diff options
Diffstat (limited to 'arch')
2189 files changed, 60441 insertions, 50449 deletions
diff --git a/arch/Kconfig b/arch/Kconfig index af2cc6eabcc7..f1cf895c040f 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -207,9 +207,6 @@ config HAVE_DMA_ATTRS config HAVE_DMA_CONTIGUOUS bool -config USE_GENERIC_SMP_HELPERS - bool - config GENERIC_SMP_IDLE_THREAD bool @@ -353,6 +350,18 @@ config HAVE_CONTEXT_TRACKING config HAVE_VIRT_CPU_ACCOUNTING bool +config HAVE_VIRT_CPU_ACCOUNTING_GEN + bool + default y if 64BIT + help + With VIRT_CPU_ACCOUNTING_GEN, cputime_t becomes 64-bit. + Before enabling this option, arch code must be audited + to ensure there are no races in concurrent read/write of + cputime_t. For example, reading/writing 64-bit cputime_t on + some 32-bit arches may require multiple accesses, so proper + locking is needed to protect against concurrent accesses. + + config HAVE_IRQ_TIME_ACCOUNTING bool help @@ -390,6 +399,16 @@ config HAVE_UNDERSCORE_SYMBOL_PREFIX Some architectures generate an _ in front of C symbols; things like module loading and assembly files need to know about this. +config HAVE_IRQ_EXIT_ON_IRQ_STACK + bool + help + Architecture doesn't only execute the irq handler on the irq stack + but also irq_exit(). This way we can process softirqs on this irq + stack instead of switching to a new one when we call __do_softirq() + in the end of an hardirq. + This spares a stack switch and improves cache usage on softirq + processing. + # # ABI hall of shame # diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index 35a300d4a9fb..135c674eaf9e 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig @@ -1,6 +1,7 @@ config ALPHA bool default y + select ARCH_MIGHT_HAVE_PC_PARPORT select HAVE_AOUT select HAVE_IDE select HAVE_OPROFILE @@ -522,7 +523,6 @@ config ARCH_MAY_HAVE_PC_FDC config SMP bool "Symmetric multi-processing support" depends on ALPHA_SABLE || ALPHA_LYNX || ALPHA_RAWHIDE || ALPHA_DP264 || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_GENERIC || ALPHA_SHARK || ALPHA_MARVEL - select USE_GENERIC_SMP_HELPERS ---help--- This enables support for systems with more than one CPU. If you have a system with only one CPU, like most personal computers, say N. If diff --git a/arch/alpha/include/asm/Kbuild b/arch/alpha/include/asm/Kbuild index a6e85f448c1c..f01fb505ad52 100644 --- a/arch/alpha/include/asm/Kbuild +++ b/arch/alpha/include/asm/Kbuild @@ -3,3 +3,4 @@ generic-y += clkdev.h generic-y += exec.h generic-y += trace_clock.h +generic-y += preempt.h diff --git a/arch/alpha/include/asm/pgalloc.h b/arch/alpha/include/asm/pgalloc.h index bc2a0daf2d92..aab14a019c20 100644 --- a/arch/alpha/include/asm/pgalloc.h +++ b/arch/alpha/include/asm/pgalloc.h @@ -72,7 +72,10 @@ pte_alloc_one(struct mm_struct *mm, unsigned long address) if (!pte) return NULL; page = virt_to_page(pte); - pgtable_page_ctor(page); + if (!pgtable_page_ctor(page)) { + __free_page(page); + return NULL; + } return page; } diff --git a/arch/alpha/include/asm/thread_info.h b/arch/alpha/include/asm/thread_info.h index 52cd2a4a3ff4..453597b91f3a 100644 --- a/arch/alpha/include/asm/thread_info.h +++ b/arch/alpha/include/asm/thread_info.h @@ -58,8 +58,6 @@ register struct thread_info *__current_thread_info __asm__("$8"); #define THREAD_SIZE_ORDER 1 #define THREAD_SIZE (2*PAGE_SIZE) -#define PREEMPT_ACTIVE 0x40000000 - /* * Thread information flags: * - these are process state flags and used from assembly diff --git a/arch/alpha/include/uapi/asm/errno.h b/arch/alpha/include/uapi/asm/errno.h index e5f29ca28180..17f92aa76b2f 100644 --- a/arch/alpha/include/uapi/asm/errno.h +++ b/arch/alpha/include/uapi/asm/errno.h @@ -43,7 +43,7 @@ #define EUSERS 68 /* Too many users */ #define EDQUOT 69 /* Quota exceeded */ -#define ESTALE 70 /* Stale NFS file handle */ +#define ESTALE 70 /* Stale file handle */ #define EREMOTE 71 /* Object is remote */ #define ENOLCK 77 /* No record locks available */ diff --git a/arch/alpha/include/uapi/asm/socket.h b/arch/alpha/include/uapi/asm/socket.h index 467de010ea7e..e3a1491d5073 100644 --- a/arch/alpha/include/uapi/asm/socket.h +++ b/arch/alpha/include/uapi/asm/socket.h @@ -81,6 +81,8 @@ #define SO_SELECT_ERR_QUEUE 45 -#define SO_BUSY_POLL 46 +#define SO_BUSY_POLL 46 + +#define SO_MAX_PACING_RATE 47 #endif /* _UAPI_ASM_SOCKET_H */ diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index 91dbb2757afd..2ee0c9bfd032 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -35,6 +35,12 @@ config ARC select PERF_USE_VMALLOC select HAVE_DEBUG_STACKOVERFLOW +config TRACE_IRQFLAGS_SUPPORT + def_bool y + +config LOCKDEP_SUPPORT + def_bool y + config SCHED_OMIT_FRAME_POINTER def_bool y @@ -119,7 +125,6 @@ config ARC_PLAT_NEEDS_CPU_TO_DMA config SMP bool "Symmetric Multi-Processing (Incomplete)" default n - select USE_GENERIC_SMP_HELPERS help This enables support for systems with more than one CPU. If you have a system with only one CPU, like most personal computers, say N. If @@ -130,17 +135,14 @@ if SMP config ARC_HAS_COH_CACHES def_bool n -config ARC_HAS_COH_RTSC - def_bool n - config ARC_HAS_REENTRANT_IRQ_LV2 def_bool n endif config NR_CPUS - int "Maximum number of CPUs (2-32)" - range 2 32 + int "Maximum number of CPUs (2-4096)" + range 2 4096 depends on SMP default "2" @@ -326,8 +328,7 @@ config ARC_HAS_RTSC bool "Insn: RTSC (64-bit r/o cycle counter)" default y depends on ARC_CPU_REL_4_10 - # if SMP, enable RTSC only if counter is coherent across cores - depends on !SMP || ARC_HAS_COH_RTSC + depends on !SMP endmenu # "ARC CPU Configuration" diff --git a/arch/arc/boot/dts/abilis_tb100.dtsi b/arch/arc/boot/dts/abilis_tb100.dtsi index d9f8249aa66e..3942634f805a 100644 --- a/arch/arc/boot/dts/abilis_tb100.dtsi +++ b/arch/arc/boot/dts/abilis_tb100.dtsi @@ -43,124 +43,124 @@ iomux: iomux@FF10601c { /* Port 1 */ pctl_tsin_s0: pctl-tsin-s0 { /* Serial TS-in 0 */ - pingrp = "mis0_pins"; + abilis,function = "mis0"; }; pctl_tsin_s1: pctl-tsin-s1 { /* Serial TS-in 1 */ - pingrp = "mis1_pins"; + abilis,function = "mis1"; }; pctl_gpio_a: pctl-gpio-a { /* GPIO bank A */ - pingrp = "gpioa_pins"; + abilis,function = "gpioa"; }; pctl_tsin_p1: pctl-tsin-p1 { /* Parallel TS-in 1 */ - pingrp = "mip1_pins"; + abilis,function = "mip1"; }; /* Port 2 */ pctl_tsin_s2: pctl-tsin-s2 { /* Serial TS-in 2 */ - pingrp = "mis2_pins"; + abilis,function = "mis2"; }; pctl_tsin_s3: pctl-tsin-s3 { /* Serial TS-in 3 */ - pingrp = "mis3_pins"; + abilis,function = "mis3"; }; pctl_gpio_c: pctl-gpio-c { /* GPIO bank C */ - pingrp = "gpioc_pins"; + abilis,function = "gpioc"; }; pctl_tsin_p3: pctl-tsin-p3 { /* Parallel TS-in 3 */ - pingrp = "mip3_pins"; + abilis,function = "mip3"; }; /* Port 3 */ pctl_tsin_s4: pctl-tsin-s4 { /* Serial TS-in 4 */ - pingrp = "mis4_pins"; + abilis,function = "mis4"; }; pctl_tsin_s5: pctl-tsin-s5 { /* Serial TS-in 5 */ - pingrp = "mis5_pins"; + abilis,function = "mis5"; }; pctl_gpio_e: pctl-gpio-e { /* GPIO bank E */ - pingrp = "gpioe_pins"; + abilis,function = "gpioe"; }; pctl_tsin_p5: pctl-tsin-p5 { /* Parallel TS-in 5 */ - pingrp = "mip5_pins"; + abilis,function = "mip5"; }; /* Port 4 */ pctl_tsin_s6: pctl-tsin-s6 { /* Serial TS-in 6 */ - pingrp = "mis6_pins"; + abilis,function = "mis6"; }; pctl_tsin_s7: pctl-tsin-s7 { /* Serial TS-in 7 */ - pingrp = "mis7_pins"; + abilis,function = "mis7"; }; pctl_gpio_g: pctl-gpio-g { /* GPIO bank G */ - pingrp = "gpiog_pins"; + abilis,function = "gpiog"; }; pctl_tsin_p7: pctl-tsin-p7 { /* Parallel TS-in 7 */ - pingrp = "mip7_pins"; + abilis,function = "mip7"; }; /* Port 5 */ pctl_gpio_j: pctl-gpio-j { /* GPIO bank J */ - pingrp = "gpioj_pins"; + abilis,function = "gpioj"; }; pctl_gpio_k: pctl-gpio-k { /* GPIO bank K */ - pingrp = "gpiok_pins"; + abilis,function = "gpiok"; }; pctl_ciplus: pctl-ciplus { /* CI+ interface */ - pingrp = "ciplus_pins"; + abilis,function = "ciplus"; }; pctl_mcard: pctl-mcard { /* M-Card interface */ - pingrp = "mcard_pins"; + abilis,function = "mcard"; }; /* Port 6 */ pctl_tsout_p: pctl-tsout-p { /* Parallel TS-out */ - pingrp = "mop_pins"; + abilis,function = "mop"; }; pctl_tsout_s0: pctl-tsout-s0 { /* Serial TS-out 0 */ - pingrp = "mos0_pins"; + abilis,function = "mos0"; }; pctl_tsout_s1: pctl-tsout-s1 { /* Serial TS-out 1 */ - pingrp = "mos1_pins"; + abilis,function = "mos1"; }; pctl_tsout_s2: pctl-tsout-s2 { /* Serial TS-out 2 */ - pingrp = "mos2_pins"; + abilis,function = "mos2"; }; pctl_tsout_s3: pctl-tsout-s3 { /* Serial TS-out 3 */ - pingrp = "mos3_pins"; + abilis,function = "mos3"; }; /* Port 7 */ pctl_uart0: pctl-uart0 { /* UART 0 */ - pingrp = "uart0_pins"; + abilis,function = "uart0"; }; pctl_uart1: pctl-uart1 { /* UART 1 */ - pingrp = "uart1_pins"; + abilis,function = "uart1"; }; pctl_gpio_l: pctl-gpio-l { /* GPIO bank L */ - pingrp = "gpiol_pins"; + abilis,function = "gpiol"; }; pctl_gpio_m: pctl-gpio-m { /* GPIO bank M */ - pingrp = "gpiom_pins"; + abilis,function = "gpiom"; }; /* Port 8 */ pctl_spi3: pctl-spi3 { - pingrp = "spi3_pins"; + abilis,function = "spi3"; }; /* Port 9 */ pctl_spi1: pctl-spi1 { - pingrp = "spi1_pins"; + abilis,function = "spi1"; }; pctl_gpio_n: pctl-gpio-n { - pingrp = "gpion_pins"; + abilis,function = "gpion"; }; /* Unmuxed GPIOs */ pctl_gpio_b: pctl-gpio-b { - pingrp = "gpiob_pins"; + abilis,function = "gpiob"; }; pctl_gpio_d: pctl-gpio-d { - pingrp = "gpiod_pins"; + abilis,function = "gpiod"; }; pctl_gpio_f: pctl-gpio-f { - pingrp = "gpiof_pins"; + abilis,function = "gpiof"; }; pctl_gpio_h: pctl-gpio-h { - pingrp = "gpioh_pins"; + abilis,function = "gpioh"; }; pctl_gpio_i: pctl-gpio-i { - pingrp = "gpioi_pins"; + abilis,function = "gpioi"; }; }; @@ -172,9 +172,10 @@ interrupts = <27 2>; reg = <0xFF140000 0x1000>; gpio-controller; - #gpio-cells = <1>; - gpio-base = <0>; - gpio-pins = <&pctl_gpio_a>; + #gpio-cells = <2>; + abilis,ngpio = <3>; + gpio-ranges = <&iomux 0 0 0>; + gpio-ranges-group-names = "gpioa"; }; gpiob: gpio@FF141000 { compatible = "abilis,tb10x-gpio"; @@ -184,9 +185,10 @@ interrupts = <27 2>; reg = <0xFF141000 0x1000>; gpio-controller; - #gpio-cells = <1>; - gpio-base = <3>; - gpio-pins = <&pctl_gpio_b>; + #gpio-cells = <2>; + abilis,ngpio = <2>; + gpio-ranges = <&iomux 0 0 0>; + gpio-ranges-group-names = "gpiob"; }; gpioc: gpio@FF142000 { compatible = "abilis,tb10x-gpio"; @@ -196,9 +198,10 @@ interrupts = <27 2>; reg = <0xFF142000 0x1000>; gpio-controller; - #gpio-cells = <1>; - gpio-base = <5>; - gpio-pins = <&pctl_gpio_c>; + #gpio-cells = <2>; + abilis,ngpio = <3>; + gpio-ranges = <&iomux 0 0 0>; + gpio-ranges-group-names = "gpioc"; }; gpiod: gpio@FF143000 { compatible = "abilis,tb10x-gpio"; @@ -208,9 +211,10 @@ interrupts = <27 2>; reg = <0xFF143000 0x1000>; gpio-controller; - #gpio-cells = <1>; - gpio-base = <8>; - gpio-pins = <&pctl_gpio_d>; + #gpio-cells = <2>; + abilis,ngpio = <2>; + gpio-ranges = <&iomux 0 0 0>; + gpio-ranges-group-names = "gpiod"; }; gpioe: gpio@FF144000 { compatible = "abilis,tb10x-gpio"; @@ -220,9 +224,10 @@ interrupts = <27 2>; reg = <0xFF144000 0x1000>; gpio-controller; - #gpio-cells = <1>; - gpio-base = <10>; - gpio-pins = <&pctl_gpio_e>; + #gpio-cells = <2>; + abilis,ngpio = <3>; + gpio-ranges = <&iomux 0 0 0>; + gpio-ranges-group-names = "gpioe"; }; gpiof: gpio@FF145000 { compatible = "abilis,tb10x-gpio"; @@ -232,9 +237,10 @@ interrupts = <27 2>; reg = <0xFF145000 0x1000>; gpio-controller; - #gpio-cells = <1>; - gpio-base = <13>; - gpio-pins = <&pctl_gpio_f>; + #gpio-cells = <2>; + abilis,ngpio = <2>; + gpio-ranges = <&iomux 0 0 0>; + gpio-ranges-group-names = "gpiof"; }; gpiog: gpio@FF146000 { compatible = "abilis,tb10x-gpio"; @@ -244,9 +250,10 @@ interrupts = <27 2>; reg = <0xFF146000 0x1000>; gpio-controller; - #gpio-cells = <1>; - gpio-base = <15>; - gpio-pins = <&pctl_gpio_g>; + #gpio-cells = <2>; + abilis,ngpio = <3>; + gpio-ranges = <&iomux 0 0 0>; + gpio-ranges-group-names = "gpiog"; }; gpioh: gpio@FF147000 { compatible = "abilis,tb10x-gpio"; @@ -256,9 +263,10 @@ interrupts = <27 2>; reg = <0xFF147000 0x1000>; gpio-controller; - #gpio-cells = <1>; - gpio-base = <18>; - gpio-pins = <&pctl_gpio_h>; + #gpio-cells = <2>; + abilis,ngpio = <2>; + gpio-ranges = <&iomux 0 0 0>; + gpio-ranges-group-names = "gpioh"; }; gpioi: gpio@FF148000 { compatible = "abilis,tb10x-gpio"; @@ -268,9 +276,10 @@ interrupts = <27 2>; reg = <0xFF148000 0x1000>; gpio-controller; - #gpio-cells = <1>; - gpio-base = <20>; - gpio-pins = <&pctl_gpio_i>; + #gpio-cells = <2>; + abilis,ngpio = <12>; + gpio-ranges = <&iomux 0 0 0>; + gpio-ranges-group-names = "gpioi"; }; gpioj: gpio@FF149000 { compatible = "abilis,tb10x-gpio"; @@ -280,9 +289,10 @@ interrupts = <27 2>; reg = <0xFF149000 0x1000>; gpio-controller; - #gpio-cells = <1>; - gpio-base = <32>; - gpio-pins = <&pctl_gpio_j>; + #gpio-cells = <2>; + abilis,ngpio = <32>; + gpio-ranges = <&iomux 0 0 0>; + gpio-ranges-group-names = "gpioj"; }; gpiok: gpio@FF14a000 { compatible = "abilis,tb10x-gpio"; @@ -292,9 +302,10 @@ interrupts = <27 2>; reg = <0xFF14A000 0x1000>; gpio-controller; - #gpio-cells = <1>; - gpio-base = <64>; - gpio-pins = <&pctl_gpio_k>; + #gpio-cells = <2>; + abilis,ngpio = <22>; + gpio-ranges = <&iomux 0 0 0>; + gpio-ranges-group-names = "gpiok"; }; gpiol: gpio@FF14b000 { compatible = "abilis,tb10x-gpio"; @@ -304,9 +315,10 @@ interrupts = <27 2>; reg = <0xFF14B000 0x1000>; gpio-controller; - #gpio-cells = <1>; - gpio-base = <86>; - gpio-pins = <&pctl_gpio_l>; + #gpio-cells = <2>; + abilis,ngpio = <4>; + gpio-ranges = <&iomux 0 0 0>; + gpio-ranges-group-names = "gpiol"; }; gpiom: gpio@FF14c000 { compatible = "abilis,tb10x-gpio"; @@ -316,9 +328,10 @@ interrupts = <27 2>; reg = <0xFF14C000 0x1000>; gpio-controller; - #gpio-cells = <1>; - gpio-base = <90>; - gpio-pins = <&pctl_gpio_m>; + #gpio-cells = <2>; + abilis,ngpio = <4>; + gpio-ranges = <&iomux 0 0 0>; + gpio-ranges-group-names = "gpiom"; }; gpion: gpio@FF14d000 { compatible = "abilis,tb10x-gpio"; @@ -328,9 +341,10 @@ interrupts = <27 2>; reg = <0xFF14D000 0x1000>; gpio-controller; - #gpio-cells = <1>; - gpio-base = <94>; - gpio-pins = <&pctl_gpio_n>; + #gpio-cells = <2>; + abilis,ngpio = <5>; + gpio-ranges = <&iomux 0 0 0>; + gpio-ranges-group-names = "gpion"; }; }; }; diff --git a/arch/arc/boot/dts/abilis_tb100_dvk.dts b/arch/arc/boot/dts/abilis_tb100_dvk.dts index ebc313a9f5b2..3dd6ed941464 100644 --- a/arch/arc/boot/dts/abilis_tb100_dvk.dts +++ b/arch/arc/boot/dts/abilis_tb100_dvk.dts @@ -64,62 +64,62 @@ compatible = "gpio-leds"; power { label = "Power"; - gpios = <&gpioi 0>; + gpios = <&gpioi 0 0>; linux,default-trigger = "default-on"; }; heartbeat { label = "Heartbeat"; - gpios = <&gpioi 1>; + gpios = <&gpioi 1 0>; linux,default-trigger = "heartbeat"; }; led2 { label = "LED2"; - gpios = <&gpioi 2>; + gpios = <&gpioi 2 0>; default-state = "off"; }; led3 { label = "LED3"; - gpios = <&gpioi 3>; + gpios = <&gpioi 3 0>; default-state = "off"; }; led4 { label = "LED4"; - gpios = <&gpioi 4>; + gpios = <&gpioi 4 0>; default-state = "off"; }; led5 { label = "LED5"; - gpios = <&gpioi 5>; + gpios = <&gpioi 5 0>; default-state = "off"; }; led6 { label = "LED6"; - gpios = <&gpioi 6>; + gpios = <&gpioi 6 0>; default-state = "off"; }; led7 { label = "LED7"; - gpios = <&gpioi 7>; + gpios = <&gpioi 7 0>; default-state = "off"; }; led8 { label = "LED8"; - gpios = <&gpioi 8>; + gpios = <&gpioi 8 0>; default-state = "off"; }; led9 { label = "LED9"; - gpios = <&gpioi 9>; + gpios = <&gpioi 9 0>; default-state = "off"; }; led10 { label = "LED10"; - gpios = <&gpioi 10>; + gpios = <&gpioi 10 0>; default-state = "off"; }; led11 { label = "LED11"; - gpios = <&gpioi 11>; + gpios = <&gpioi 11 0>; default-state = "off"; }; }; diff --git a/arch/arc/boot/dts/abilis_tb101.dtsi b/arch/arc/boot/dts/abilis_tb101.dtsi index da8ca7941e67..b0467229a5c4 100644 --- a/arch/arc/boot/dts/abilis_tb101.dtsi +++ b/arch/arc/boot/dts/abilis_tb101.dtsi @@ -43,133 +43,133 @@ iomux: iomux@FF10601c { /* Port 1 */ pctl_tsin_s0: pctl-tsin-s0 { /* Serial TS-in 0 */ - pingrp = "mis0_pins"; + abilis,function = "mis0"; }; pctl_tsin_s1: pctl-tsin-s1 { /* Serial TS-in 1 */ - pingrp = "mis1_pins"; + abilis,function = "mis1"; }; pctl_gpio_a: pctl-gpio-a { /* GPIO bank A */ - pingrp = "gpioa_pins"; + abilis,function = "gpioa"; }; pctl_tsin_p1: pctl-tsin-p1 { /* Parallel TS-in 1 */ - pingrp = "mip1_pins"; + abilis,function = "mip1"; }; /* Port 2 */ pctl_tsin_s2: pctl-tsin-s2 { /* Serial TS-in 2 */ - pingrp = "mis2_pins"; + abilis,function = "mis2"; }; pctl_tsin_s3: pctl-tsin-s3 { /* Serial TS-in 3 */ - pingrp = "mis3_pins"; + abilis,function = "mis3"; }; pctl_gpio_c: pctl-gpio-c { /* GPIO bank C */ - pingrp = "gpioc_pins"; + abilis,function = "gpioc"; }; pctl_tsin_p3: pctl-tsin-p3 { /* Parallel TS-in 3 */ - pingrp = "mip3_pins"; + abilis,function = "mip3"; }; /* Port 3 */ pctl_tsin_s4: pctl-tsin-s4 { /* Serial TS-in 4 */ - pingrp = "mis4_pins"; + abilis,function = "mis4"; }; pctl_tsin_s5: pctl-tsin-s5 { /* Serial TS-in 5 */ - pingrp = "mis5_pins"; + abilis,function = "mis5"; }; pctl_gpio_e: pctl-gpio-e { /* GPIO bank E */ - pingrp = "gpioe_pins"; + abilis,function = "gpioe"; }; pctl_tsin_p5: pctl-tsin-p5 { /* Parallel TS-in 5 */ - pingrp = "mip5_pins"; + abilis,function = "mip5"; }; /* Port 4 */ pctl_tsin_s6: pctl-tsin-s6 { /* Serial TS-in 6 */ - pingrp = "mis6_pins"; + abilis,function = "mis6"; }; pctl_tsin_s7: pctl-tsin-s7 { /* Serial TS-in 7 */ - pingrp = "mis7_pins"; + abilis,function = "mis7"; }; pctl_gpio_g: pctl-gpio-g { /* GPIO bank G */ - pingrp = "gpiog_pins"; + abilis,function = "gpiog"; }; pctl_tsin_p7: pctl-tsin-p7 { /* Parallel TS-in 7 */ - pingrp = "mip7_pins"; + abilis,function = "mip7"; }; /* Port 5 */ pctl_gpio_j: pctl-gpio-j { /* GPIO bank J */ - pingrp = "gpioj_pins"; + abilis,function = "gpioj"; }; pctl_gpio_k: pctl-gpio-k { /* GPIO bank K */ - pingrp = "gpiok_pins"; + abilis,function = "gpiok"; }; pctl_ciplus: pctl-ciplus { /* CI+ interface */ - pingrp = "ciplus_pins"; + abilis,function = "ciplus"; }; pctl_mcard: pctl-mcard { /* M-Card interface */ - pingrp = "mcard_pins"; + abilis,function = "mcard"; }; pctl_stc0: pctl-stc0 { /* Smart card I/F 0 */ - pingrp = "stc0_pins"; + abilis,function = "stc0"; }; pctl_stc1: pctl-stc1 { /* Smart card I/F 1 */ - pingrp = "stc1_pins"; + abilis,function = "stc1"; }; /* Port 6 */ pctl_tsout_p: pctl-tsout-p { /* Parallel TS-out */ - pingrp = "mop_pins"; + abilis,function = "mop"; }; pctl_tsout_s0: pctl-tsout-s0 { /* Serial TS-out 0 */ - pingrp = "mos0_pins"; + abilis,function = "mos0"; }; pctl_tsout_s1: pctl-tsout-s1 { /* Serial TS-out 1 */ - pingrp = "mos1_pins"; + abilis,function = "mos1"; }; pctl_tsout_s2: pctl-tsout-s2 { /* Serial TS-out 2 */ - pingrp = "mos2_pins"; + abilis,function = "mos2"; }; pctl_tsout_s3: pctl-tsout-s3 { /* Serial TS-out 3 */ - pingrp = "mos3_pins"; + abilis,function = "mos3"; }; /* Port 7 */ pctl_uart0: pctl-uart0 { /* UART 0 */ - pingrp = "uart0_pins"; + abilis,function = "uart0"; }; pctl_uart1: pctl-uart1 { /* UART 1 */ - pingrp = "uart1_pins"; + abilis,function = "uart1"; }; pctl_gpio_l: pctl-gpio-l { /* GPIO bank L */ - pingrp = "gpiol_pins"; + abilis,function = "gpiol"; }; pctl_gpio_m: pctl-gpio-m { /* GPIO bank M */ - pingrp = "gpiom_pins"; + abilis,function = "gpiom"; }; /* Port 8 */ pctl_spi3: pctl-spi3 { - pingrp = "spi3_pins"; + abilis,function = "spi3"; }; pctl_jtag: pctl-jtag { - pingrp = "jtag_pins"; + abilis,function = "jtag"; }; /* Port 9 */ pctl_spi1: pctl-spi1 { - pingrp = "spi1_pins"; + abilis,function = "spi1"; }; pctl_gpio_n: pctl-gpio-n { - pingrp = "gpion_pins"; + abilis,function = "gpion"; }; /* Unmuxed GPIOs */ pctl_gpio_b: pctl-gpio-b { - pingrp = "gpiob_pins"; + abilis,function = "gpiob"; }; pctl_gpio_d: pctl-gpio-d { - pingrp = "gpiod_pins"; + abilis,function = "gpiod"; }; pctl_gpio_f: pctl-gpio-f { - pingrp = "gpiof_pins"; + abilis,function = "gpiof"; }; pctl_gpio_h: pctl-gpio-h { - pingrp = "gpioh_pins"; + abilis,function = "gpioh"; }; pctl_gpio_i: pctl-gpio-i { - pingrp = "gpioi_pins"; + abilis,function = "gpioi"; }; }; @@ -181,9 +181,10 @@ interrupts = <27 2>; reg = <0xFF140000 0x1000>; gpio-controller; - #gpio-cells = <1>; - gpio-base = <0>; - gpio-pins = <&pctl_gpio_a>; + #gpio-cells = <2>; + abilis,ngpio = <3>; + gpio-ranges = <&iomux 0 0 0>; + gpio-ranges-group-names = "gpioa"; }; gpiob: gpio@FF141000 { compatible = "abilis,tb10x-gpio"; @@ -193,9 +194,10 @@ interrupts = <27 2>; reg = <0xFF141000 0x1000>; gpio-controller; - #gpio-cells = <1>; - gpio-base = <3>; - gpio-pins = <&pctl_gpio_b>; + #gpio-cells = <2>; + abilis,ngpio = <2>; + gpio-ranges = <&iomux 0 0 0>; + gpio-ranges-group-names = "gpiob"; }; gpioc: gpio@FF142000 { compatible = "abilis,tb10x-gpio"; @@ -205,9 +207,10 @@ interrupts = <27 2>; reg = <0xFF142000 0x1000>; gpio-controller; - #gpio-cells = <1>; - gpio-base = <5>; - gpio-pins = <&pctl_gpio_c>; + #gpio-cells = <2>; + abilis,ngpio = <3>; + gpio-ranges = <&iomux 0 0 0>; + gpio-ranges-group-names = "gpioc"; }; gpiod: gpio@FF143000 { compatible = "abilis,tb10x-gpio"; @@ -217,9 +220,10 @@ interrupts = <27 2>; reg = <0xFF143000 0x1000>; gpio-controller; - #gpio-cells = <1>; - gpio-base = <8>; - gpio-pins = <&pctl_gpio_d>; + #gpio-cells = <2>; + abilis,ngpio = <2>; + gpio-ranges = <&iomux 0 0 0>; + gpio-ranges-group-names = "gpiod"; }; gpioe: gpio@FF144000 { compatible = "abilis,tb10x-gpio"; @@ -229,9 +233,10 @@ interrupts = <27 2>; reg = <0xFF144000 0x1000>; gpio-controller; - #gpio-cells = <1>; - gpio-base = <10>; - gpio-pins = <&pctl_gpio_e>; + #gpio-cells = <2>; + abilis,ngpio = <3>; + gpio-ranges = <&iomux 0 0 0>; + gpio-ranges-group-names = "gpioe"; }; gpiof: gpio@FF145000 { compatible = "abilis,tb10x-gpio"; @@ -241,9 +246,10 @@ interrupts = <27 2>; reg = <0xFF145000 0x1000>; gpio-controller; - #gpio-cells = <1>; - gpio-base = <13>; - gpio-pins = <&pctl_gpio_f>; + #gpio-cells = <2>; + abilis,ngpio = <2>; + gpio-ranges = <&iomux 0 0 0>; + gpio-ranges-group-names = "gpiof"; }; gpiog: gpio@FF146000 { compatible = "abilis,tb10x-gpio"; @@ -253,9 +259,10 @@ interrupts = <27 2>; reg = <0xFF146000 0x1000>; gpio-controller; - #gpio-cells = <1>; - gpio-base = <15>; - gpio-pins = <&pctl_gpio_g>; + #gpio-cells = <2>; + abilis,ngpio = <3>; + gpio-ranges = <&iomux 0 0 0>; + gpio-ranges-group-names = "gpiog"; }; gpioh: gpio@FF147000 { compatible = "abilis,tb10x-gpio"; @@ -265,9 +272,10 @@ interrupts = <27 2>; reg = <0xFF147000 0x1000>; gpio-controller; - #gpio-cells = <1>; - gpio-base = <18>; - gpio-pins = <&pctl_gpio_h>; + #gpio-cells = <2>; + abilis,ngpio = <2>; + gpio-ranges = <&iomux 0 0 0>; + gpio-ranges-group-names = "gpioh"; }; gpioi: gpio@FF148000 { compatible = "abilis,tb10x-gpio"; @@ -277,9 +285,10 @@ interrupts = <27 2>; reg = <0xFF148000 0x1000>; gpio-controller; - #gpio-cells = <1>; - gpio-base = <20>; - gpio-pins = <&pctl_gpio_i>; + #gpio-cells = <2>; + abilis,ngpio = <12>; + gpio-ranges = <&iomux 0 0 0>; + gpio-ranges-group-names = "gpioi"; }; gpioj: gpio@FF149000 { compatible = "abilis,tb10x-gpio"; @@ -289,9 +298,10 @@ interrupts = <27 2>; reg = <0xFF149000 0x1000>; gpio-controller; - #gpio-cells = <1>; - gpio-base = <32>; - gpio-pins = <&pctl_gpio_j>; + #gpio-cells = <2>; + abilis,ngpio = <32>; + gpio-ranges = <&iomux 0 0 0>; + gpio-ranges-group-names = "gpioj"; }; gpiok: gpio@FF14a000 { compatible = "abilis,tb10x-gpio"; @@ -301,9 +311,10 @@ interrupts = <27 2>; reg = <0xFF14A000 0x1000>; gpio-controller; - #gpio-cells = <1>; - gpio-base = <64>; - gpio-pins = <&pctl_gpio_k>; + #gpio-cells = <2>; + abilis,ngpio = <22>; + gpio-ranges = <&iomux 0 0 0>; + gpio-ranges-group-names = "gpiok"; }; gpiol: gpio@FF14b000 { compatible = "abilis,tb10x-gpio"; @@ -313,9 +324,10 @@ interrupts = <27 2>; reg = <0xFF14B000 0x1000>; gpio-controller; - #gpio-cells = <1>; - gpio-base = <86>; - gpio-pins = <&pctl_gpio_l>; + #gpio-cells = <2>; + abilis,ngpio = <4>; + gpio-ranges = <&iomux 0 0 0>; + gpio-ranges-group-names = "gpiol"; }; gpiom: gpio@FF14c000 { compatible = "abilis,tb10x-gpio"; @@ -325,9 +337,10 @@ interrupts = <27 2>; reg = <0xFF14C000 0x1000>; gpio-controller; - #gpio-cells = <1>; - gpio-base = <90>; - gpio-pins = <&pctl_gpio_m>; + #gpio-cells = <2>; + abilis,ngpio = <4>; + gpio-ranges = <&iomux 0 0 0>; + gpio-ranges-group-names = "gpiom"; }; gpion: gpio@FF14d000 { compatible = "abilis,tb10x-gpio"; @@ -337,9 +350,10 @@ interrupts = <27 2>; reg = <0xFF14D000 0x1000>; gpio-controller; - #gpio-cells = <1>; - gpio-base = <94>; - gpio-pins = <&pctl_gpio_n>; + #gpio-cells = <2>; + abilis,ngpio = <5>; + gpio-ranges = <&iomux 0 0 0>; + gpio-ranges-group-names = "gpion"; }; }; }; diff --git a/arch/arc/boot/dts/abilis_tb101_dvk.dts b/arch/arc/boot/dts/abilis_tb101_dvk.dts index b204657993aa..1cf51c280f28 100644 --- a/arch/arc/boot/dts/abilis_tb101_dvk.dts +++ b/arch/arc/boot/dts/abilis_tb101_dvk.dts @@ -64,62 +64,62 @@ compatible = "gpio-leds"; power { label = "Power"; - gpios = <&gpioi 0>; + gpios = <&gpioi 0 0>; linux,default-trigger = "default-on"; }; heartbeat { label = "Heartbeat"; - gpios = <&gpioi 1>; + gpios = <&gpioi 1 0>; linux,default-trigger = "heartbeat"; }; led2 { label = "LED2"; - gpios = <&gpioi 2>; + gpios = <&gpioi 2 0>; default-state = "off"; }; led3 { label = "LED3"; - gpios = <&gpioi 3>; + gpios = <&gpioi 3 0>; default-state = "off"; }; led4 { label = "LED4"; - gpios = <&gpioi 4>; + gpios = <&gpioi 4 0>; default-state = "off"; }; led5 { label = "LED5"; - gpios = <&gpioi 5>; + gpios = <&gpioi 5 0>; default-state = "off"; }; led6 { label = "LED6"; - gpios = <&gpioi 6>; + gpios = <&gpioi 6 0>; default-state = "off"; }; led7 { label = "LED7"; - gpios = <&gpioi 7>; + gpios = <&gpioi 7 0>; default-state = "off"; }; led8 { label = "LED8"; - gpios = <&gpioi 8>; + gpios = <&gpioi 8 0>; default-state = "off"; }; led9 { label = "LED9"; - gpios = <&gpioi 9>; + gpios = <&gpioi 9 0>; default-state = "off"; }; led10 { label = "LED10"; - gpios = <&gpioi 10>; + gpios = <&gpioi 10 0>; default-state = "off"; }; led11 { label = "LED11"; - gpios = <&gpioi 11>; + gpios = <&gpioi 11 0>; default-state = "off"; }; }; diff --git a/arch/arc/boot/dts/abilis_tb10x.dtsi b/arch/arc/boot/dts/abilis_tb10x.dtsi index edf56f4749e1..a098d7c05e96 100644 --- a/arch/arc/boot/dts/abilis_tb10x.dtsi +++ b/arch/arc/boot/dts/abilis_tb10x.dtsi @@ -62,9 +62,8 @@ }; iomux: iomux@FF10601c { - #address-cells = <1>; - #size-cells = <1>; compatible = "abilis,tb10x-iomux"; + #gpio-range-cells = <3>; reg = <0xFF10601c 0x4>; }; diff --git a/arch/arc/boot/dts/angel4.dts b/arch/arc/boot/dts/angel4.dts index 4fb2d6f655bd..bcf662d21a57 100644 --- a/arch/arc/boot/dts/angel4.dts +++ b/arch/arc/boot/dts/angel4.dts @@ -67,5 +67,9 @@ reg = <1>; }; }; + + arcpmu0: pmu { + compatible = "snps,arc700-pmu"; + }; }; }; diff --git a/arch/arc/configs/fpga_defconfig b/arch/arc/configs/fpga_defconfig index 4ca50f1f8d05..e283aa586934 100644 --- a/arch/arc/configs/fpga_defconfig +++ b/arch/arc/configs/fpga_defconfig @@ -2,6 +2,8 @@ CONFIG_CROSS_COMPILE="arc-linux-uclibc-" # CONFIG_LOCALVERSION_AUTO is not set CONFIG_DEFAULT_HOSTNAME="ARCLinux" # CONFIG_SWAP is not set +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y CONFIG_HIGH_RES_TIMERS=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y @@ -62,4 +64,5 @@ CONFIG_TMPFS=y CONFIG_NFS_FS=y # CONFIG_ENABLE_WARN_DEPRECATED is not set # CONFIG_ENABLE_MUST_CHECK is not set +# CONFIG_DEBUG_PREEMPT is not set CONFIG_XZ_DEC=y diff --git a/arch/arc/configs/fpga_noramfs_defconfig b/arch/arc/configs/fpga_noramfs_defconfig new file mode 100644 index 000000000000..5276a52f6a2f --- /dev/null +++ b/arch/arc/configs/fpga_noramfs_defconfig @@ -0,0 +1,64 @@ +CONFIG_CROSS_COMPILE="arc-linux-uclibc-" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_DEFAULT_HOSTNAME="ARCLinux" +# CONFIG_SWAP is not set +CONFIG_HIGH_RES_TIMERS=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_NAMESPACES=y +# CONFIG_UTS_NS is not set +# CONFIG_PID_NS is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_KALLSYMS_ALL=y +CONFIG_EMBEDDED=y +# CONFIG_SLUB_DEBUG is not set +# CONFIG_COMPAT_BRK is not set +CONFIG_KPROBES=y +CONFIG_MODULES=y +# CONFIG_LBDAF is not set +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +CONFIG_ARC_PLAT_FPGA_LEGACY=y +CONFIG_ARC_BOARD_ML509=y +# CONFIG_ARC_HAS_RTSC is not set +CONFIG_ARC_BUILTIN_DTB_NAME="angel4" +CONFIG_PREEMPT=y +# CONFIG_COMPACTION is not set +# CONFIG_CROSS_MEMORY_ATTACH is not set +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_UNIX_DIAG=y +CONFIG_NET_KEY=y +CONFIG_INET=y +# CONFIG_IPV6 is not set +# CONFIG_STANDALONE is not set +# CONFIG_PREVENT_FIRMWARE_BUILD is not set +# CONFIG_FIRMWARE_IN_KERNEL is not set +# CONFIG_BLK_DEV is not set +CONFIG_NETDEVICES=y +CONFIG_ARC_EMAC=y +CONFIG_LXT_PHY=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_SERIO is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_DEVKMEM is not set +CONFIG_SERIAL_ARC=y +CONFIG_SERIAL_ARC_CONSOLE=y +# CONFIG_HW_RANDOM is not set +# CONFIG_HWMON is not set +# CONFIG_VGA_CONSOLE is not set +# CONFIG_HID is not set +# CONFIG_USB_SUPPORT is not set +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_TMPFS=y +# CONFIG_MISC_FILESYSTEMS is not set +CONFIG_NFS_FS=y +# CONFIG_ENABLE_WARN_DEPRECATED is not set +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_XZ_DEC=y diff --git a/arch/arc/include/asm/Kbuild b/arch/arc/include/asm/Kbuild index d8dd660898b9..5943f7f9d325 100644 --- a/arch/arc/include/asm/Kbuild +++ b/arch/arc/include/asm/Kbuild @@ -46,3 +46,4 @@ generic-y += ucontext.h generic-y += user.h generic-y += vga.h generic-y += xor.h +generic-y += preempt.h diff --git a/arch/arc/include/asm/cache.h b/arch/arc/include/asm/cache.h index e4abdaac6f9f..2fd3162ec4df 100644 --- a/arch/arc/include/asm/cache.h +++ b/arch/arc/include/asm/cache.h @@ -17,13 +17,7 @@ #endif #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) - -/* For a rare case where customers have differently config I/D */ -#define ARC_ICACHE_LINE_LEN L1_CACHE_BYTES -#define ARC_DCACHE_LINE_LEN L1_CACHE_BYTES - -#define ICACHE_LINE_MASK (~(ARC_ICACHE_LINE_LEN - 1)) -#define DCACHE_LINE_MASK (~(ARC_DCACHE_LINE_LEN - 1)) +#define CACHE_LINE_MASK (~(L1_CACHE_BYTES - 1)) /* * ARC700 doesn't cache any access in top 256M. diff --git a/arch/arc/include/asm/irq.h b/arch/arc/include/asm/irq.h index c0a72105ee0b..291a70db68b8 100644 --- a/arch/arc/include/asm/irq.h +++ b/arch/arc/include/asm/irq.h @@ -18,8 +18,8 @@ #include <asm-generic/irq.h> -extern void __init arc_init_IRQ(void); -extern int __init get_hw_config_num_irq(void); +extern void arc_init_IRQ(void); +extern int get_hw_config_num_irq(void); void arc_local_timer_setup(unsigned int cpu); diff --git a/arch/arc/include/asm/irqflags.h b/arch/arc/include/asm/irqflags.h index b68b53f458d1..cb7efc29f16f 100644 --- a/arch/arc/include/asm/irqflags.h +++ b/arch/arc/include/asm/irqflags.h @@ -151,16 +151,38 @@ static inline void arch_unmask_irq(unsigned int irq) #else +#ifdef CONFIG_TRACE_IRQFLAGS + +.macro TRACE_ASM_IRQ_DISABLE + bl trace_hardirqs_off +.endm + +.macro TRACE_ASM_IRQ_ENABLE + bl trace_hardirqs_on +.endm + +#else + +.macro TRACE_ASM_IRQ_DISABLE +.endm + +.macro TRACE_ASM_IRQ_ENABLE +.endm + +#endif + .macro IRQ_DISABLE scratch lr \scratch, [status32] bic \scratch, \scratch, (STATUS_E1_MASK | STATUS_E2_MASK) flag \scratch + TRACE_ASM_IRQ_DISABLE .endm .macro IRQ_ENABLE scratch lr \scratch, [status32] or \scratch, \scratch, (STATUS_E1_MASK | STATUS_E2_MASK) flag \scratch + TRACE_ASM_IRQ_ENABLE .endm #endif /* __ASSEMBLY__ */ diff --git a/arch/arc/include/asm/mach_desc.h b/arch/arc/include/asm/mach_desc.h index 9998dc846ebb..e8993a2be6c2 100644 --- a/arch/arc/include/asm/mach_desc.h +++ b/arch/arc/include/asm/mach_desc.h @@ -51,22 +51,12 @@ struct machine_desc { /* * Current machine - only accessible during boot. */ -extern struct machine_desc *machine_desc; +extern const struct machine_desc *machine_desc; /* * Machine type table - also only accessible during boot */ -extern struct machine_desc __arch_info_begin[], __arch_info_end[]; -#define for_each_machine_desc(p) \ - for (p = __arch_info_begin; p < __arch_info_end; p++) - -static inline struct machine_desc *default_machine_desc(void) -{ - /* the default machine is the last one linked in */ - if (__arch_info_end - 1 < __arch_info_begin) - return NULL; - return __arch_info_end - 1; -} +extern const struct machine_desc __arch_info_begin[], __arch_info_end[]; /* * Set of macros to define architecture features. @@ -81,7 +71,6 @@ __attribute__((__section__(".arch.info.init"))) = { \ #define MACHINE_END \ }; -extern struct machine_desc *setup_machine_fdt(void *dt); -extern void __init copy_devtree(void); +extern const struct machine_desc *setup_machine_fdt(void *dt); #endif diff --git a/arch/arc/include/asm/mmu.h b/arch/arc/include/asm/mmu.h index c2663b32866b..8c84ae98c337 100644 --- a/arch/arc/include/asm/mmu.h +++ b/arch/arc/include/asm/mmu.h @@ -48,7 +48,7 @@ #ifndef __ASSEMBLY__ typedef struct { - unsigned long asid; /* 8 bit MMU PID + Generation cycle */ + unsigned long asid[NR_CPUS]; /* 8 bit MMU PID + Generation cycle */ } mm_context_t; #ifdef CONFIG_ARC_DBG_TLB_PARANOIA diff --git a/arch/arc/include/asm/mmu_context.h b/arch/arc/include/asm/mmu_context.h index 43a1b51bb8cc..1fd467ef658f 100644 --- a/arch/arc/include/asm/mmu_context.h +++ b/arch/arc/include/asm/mmu_context.h @@ -30,13 +30,13 @@ * "Fast Context Switch" i.e. no TLB flush on ctxt-switch * * Linux assigns each task a unique ASID. A simple round-robin allocation - * of H/w ASID is done using software tracker @asid_cache. + * of H/w ASID is done using software tracker @asid_cpu. * When it reaches max 255, the allocation cycle starts afresh by flushing * the entire TLB and wrapping ASID back to zero. * * A new allocation cycle, post rollover, could potentially reassign an ASID * to a different task. Thus the rule is to refresh the ASID in a new cycle. - * The 32 bit @asid_cache (and mm->asid) have 8 bits MMU PID and rest 24 bits + * The 32 bit @asid_cpu (and mm->asid) have 8 bits MMU PID and rest 24 bits * serve as cycle/generation indicator and natural 32 bit unsigned math * automagically increments the generation when lower 8 bits rollover. */ @@ -47,9 +47,11 @@ #define MM_CTXT_FIRST_CYCLE (MM_CTXT_ASID_MASK + 1) #define MM_CTXT_NO_ASID 0UL -#define hw_pid(mm) (mm->context.asid & MM_CTXT_ASID_MASK) +#define asid_mm(mm, cpu) mm->context.asid[cpu] +#define hw_pid(mm, cpu) (asid_mm(mm, cpu) & MM_CTXT_ASID_MASK) -extern unsigned int asid_cache; +DECLARE_PER_CPU(unsigned int, asid_cache); +#define asid_cpu(cpu) per_cpu(asid_cache, cpu) /* * Get a new ASID if task doesn't have a valid one (unalloc or from prev cycle) @@ -57,6 +59,7 @@ extern unsigned int asid_cache; */ static inline void get_new_mmu_context(struct mm_struct *mm) { + const unsigned int cpu = smp_processor_id(); unsigned long flags; local_irq_save(flags); @@ -71,28 +74,28 @@ static inline void get_new_mmu_context(struct mm_struct *mm) * first need to destroy the context, setting it to invalid * value. */ - if (!((mm->context.asid ^ asid_cache) & MM_CTXT_CYCLE_MASK)) + if (!((asid_mm(mm, cpu) ^ asid_cpu(cpu)) & MM_CTXT_CYCLE_MASK)) goto set_hw; /* move to new ASID and handle rollover */ - if (unlikely(!(++asid_cache & MM_CTXT_ASID_MASK))) { + if (unlikely(!(++asid_cpu(cpu) & MM_CTXT_ASID_MASK))) { - flush_tlb_all(); + local_flush_tlb_all(); /* * Above checke for rollover of 8 bit ASID in 32 bit container. * If the container itself wrapped around, set it to a non zero * "generation" to distinguish from no context */ - if (!asid_cache) - asid_cache = MM_CTXT_FIRST_CYCLE; + if (!asid_cpu(cpu)) + asid_cpu(cpu) = MM_CTXT_FIRST_CYCLE; } /* Assign new ASID to tsk */ - mm->context.asid = asid_cache; + asid_mm(mm, cpu) = asid_cpu(cpu); set_hw: - write_aux_reg(ARC_REG_PID, hw_pid(mm) | MMU_ENABLE); + write_aux_reg(ARC_REG_PID, hw_pid(mm, cpu) | MMU_ENABLE); local_irq_restore(flags); } @@ -104,16 +107,45 @@ set_hw: static inline int init_new_context(struct task_struct *tsk, struct mm_struct *mm) { - mm->context.asid = MM_CTXT_NO_ASID; + int i; + + for_each_possible_cpu(i) + asid_mm(mm, i) = MM_CTXT_NO_ASID; + return 0; } +static inline void destroy_context(struct mm_struct *mm) +{ + unsigned long flags; + + /* Needed to elide CONFIG_DEBUG_PREEMPT warning */ + local_irq_save(flags); + asid_mm(mm, smp_processor_id()) = MM_CTXT_NO_ASID; + local_irq_restore(flags); +} + /* Prepare the MMU for task: setup PID reg with allocated ASID If task doesn't have an ASID (never alloc or stolen, get a new ASID) */ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk) { + const int cpu = smp_processor_id(); + + /* + * Note that the mm_cpumask is "aggregating" only, we don't clear it + * for the switched-out task, unlike some other arches. + * It is used to enlist cpus for sending TLB flush IPIs and not sending + * it to CPUs where a task once ran-on, could cause stale TLB entry + * re-use, specially for a multi-threaded task. + * e.g. T1 runs on C1, migrates to C3. T2 running on C2 munmaps. + * For a non-aggregating mm_cpumask, IPI not sent C1, and if T1 + * were to re-migrate to C1, it could access the unmapped region + * via any existing stale TLB entries. + */ + cpumask_set_cpu(cpu, mm_cpumask(next)); + #ifndef CONFIG_SMP /* PGD cached in MMU reg to avoid 3 mem lookups: task->mm->pgd */ write_aux_reg(ARC_REG_SCRATCH_DATA0, next->pgd); @@ -131,11 +163,6 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, */ #define activate_mm(prev, next) switch_mm(prev, next, NULL) -static inline void destroy_context(struct mm_struct *mm) -{ - mm->context.asid = MM_CTXT_NO_ASID; -} - /* it seemed that deactivate_mm( ) is a reasonable place to do book-keeping * for retiring-mm. However destroy_context( ) still needs to do that because * between mm_release( ) = >deactive_mm( ) and diff --git a/arch/arc/include/asm/perf_event.h b/arch/arc/include/asm/perf_event.h index 115ad96480e6..cbf755e32a03 100644 --- a/arch/arc/include/asm/perf_event.h +++ b/arch/arc/include/asm/perf_event.h @@ -1,5 +1,7 @@ /* - * Copyright (C) 2011-2012 Synopsys, Inc. (www.synopsys.com) + * Linux performance counter support for ARC + * + * Copyright (C) 2011-2013 Synopsys, Inc. (www.synopsys.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 @@ -10,4 +12,204 @@ #ifndef __ASM_PERF_EVENT_H #define __ASM_PERF_EVENT_H +/* real maximum varies per CPU, this is the maximum supported by the driver */ +#define ARC_PMU_MAX_HWEVENTS 64 + +#define ARC_REG_CC_BUILD 0xF6 +#define ARC_REG_CC_INDEX 0x240 +#define ARC_REG_CC_NAME0 0x241 +#define ARC_REG_CC_NAME1 0x242 + +#define ARC_REG_PCT_BUILD 0xF5 +#define ARC_REG_PCT_COUNTL 0x250 +#define ARC_REG_PCT_COUNTH 0x251 +#define ARC_REG_PCT_SNAPL 0x252 +#define ARC_REG_PCT_SNAPH 0x253 +#define ARC_REG_PCT_CONFIG 0x254 +#define ARC_REG_PCT_CONTROL 0x255 +#define ARC_REG_PCT_INDEX 0x256 + +#define ARC_REG_PCT_CONTROL_CC (1 << 16) /* clear counts */ +#define ARC_REG_PCT_CONTROL_SN (1 << 17) /* snapshot */ + +struct arc_reg_pct_build { +#ifdef CONFIG_CPU_BIG_ENDIAN + unsigned int m:8, c:8, r:6, s:2, v:8; +#else + unsigned int v:8, s:2, r:6, c:8, m:8; +#endif +}; + +struct arc_reg_cc_build { +#ifdef CONFIG_CPU_BIG_ENDIAN + unsigned int c:16, r:8, v:8; +#else + unsigned int v:8, r:8, c:16; +#endif +}; + +#define PERF_COUNT_ARC_DCLM (PERF_COUNT_HW_MAX + 0) +#define PERF_COUNT_ARC_DCSM (PERF_COUNT_HW_MAX + 1) +#define PERF_COUNT_ARC_ICM (PERF_COUNT_HW_MAX + 2) +#define PERF_COUNT_ARC_BPOK (PERF_COUNT_HW_MAX + 3) +#define PERF_COUNT_ARC_EDTLB (PERF_COUNT_HW_MAX + 4) +#define PERF_COUNT_ARC_EITLB (PERF_COUNT_HW_MAX + 5) +#define PERF_COUNT_ARC_HW_MAX (PERF_COUNT_HW_MAX + 6) + +/* + * The "generalized" performance events seem to really be a copy + * of the available events on x86 processors; the mapping to ARC + * events is not always possible 1-to-1. Fortunately, there doesn't + * seem to be an exact definition for these events, so we can cheat + * a bit where necessary. + * + * In particular, the following PERF events may behave a bit differently + * compared to other architectures: + * + * PERF_COUNT_HW_CPU_CYCLES + * Cycles not in halted state + * + * PERF_COUNT_HW_REF_CPU_CYCLES + * Reference cycles not in halted state, same as PERF_COUNT_HW_CPU_CYCLES + * for now as we don't do Dynamic Voltage/Frequency Scaling (yet) + * + * PERF_COUNT_HW_BUS_CYCLES + * Unclear what this means, Intel uses 0x013c, which according to + * their datasheet means "unhalted reference cycles". It sounds similar + * to PERF_COUNT_HW_REF_CPU_CYCLES, and we use the same counter for it. + * + * PERF_COUNT_HW_STALLED_CYCLES_BACKEND + * PERF_COUNT_HW_STALLED_CYCLES_FRONTEND + * The ARC 700 can either measure stalls per pipeline stage, or all stalls + * combined; for now we assign all stalls to STALLED_CYCLES_BACKEND + * and all pipeline flushes (e.g. caused by mispredicts, etc.) to + * STALLED_CYCLES_FRONTEND. + * + * We could start multiple performance counters and combine everything + * afterwards, but that makes it complicated. + * + * Note that I$ cache misses aren't counted by either of the two! + */ + +static const char * const arc_pmu_ev_hw_map[] = { + [PERF_COUNT_HW_CPU_CYCLES] = "crun", + [PERF_COUNT_HW_REF_CPU_CYCLES] = "crun", + [PERF_COUNT_HW_BUS_CYCLES] = "crun", + [PERF_COUNT_HW_INSTRUCTIONS] = "iall", + [PERF_COUNT_HW_BRANCH_MISSES] = "bpfail", + [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = "ijmp", + [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = "bflush", + [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = "bstall", + [PERF_COUNT_ARC_DCLM] = "dclm", + [PERF_COUNT_ARC_DCSM] = "dcsm", + [PERF_COUNT_ARC_ICM] = "icm", + [PERF_COUNT_ARC_BPOK] = "bpok", + [PERF_COUNT_ARC_EDTLB] = "edtlb", + [PERF_COUNT_ARC_EITLB] = "eitlb", +}; + +#define C(_x) PERF_COUNT_HW_CACHE_##_x +#define CACHE_OP_UNSUPPORTED 0xffff + +static const unsigned arc_pmu_cache_map[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = { + [C(L1D)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = PERF_COUNT_ARC_DCLM, + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = PERF_COUNT_ARC_DCSM, + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, + }, + }, + [C(L1I)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = PERF_COUNT_ARC_ICM, + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, + }, + }, + [C(LL)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, + }, + }, + [C(DTLB)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = PERF_COUNT_ARC_EDTLB, + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, + }, + }, + [C(ITLB)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = PERF_COUNT_ARC_EITLB, + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, + }, + }, + [C(BPU)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = PERF_COUNT_HW_BRANCH_INSTRUCTIONS, + [C(RESULT_MISS)] = PERF_COUNT_HW_BRANCH_MISSES, + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, + }, + }, + [C(NODE)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, + }, + }, +}; + #endif /* __ASM_PERF_EVENT_H */ diff --git a/arch/arc/include/asm/pgalloc.h b/arch/arc/include/asm/pgalloc.h index 36a9f20c21a3..81208bfd9dcb 100644 --- a/arch/arc/include/asm/pgalloc.h +++ b/arch/arc/include/asm/pgalloc.h @@ -105,11 +105,16 @@ static inline pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address) { pgtable_t pte_pg; + struct page *page; pte_pg = __get_free_pages(GFP_KERNEL | __GFP_REPEAT, __get_order_pte()); - if (pte_pg) { - memzero((void *)pte_pg, PTRS_PER_PTE * 4); - pgtable_page_ctor(virt_to_page(pte_pg)); + if (!pte_pg) + return 0; + memzero((void *)pte_pg, PTRS_PER_PTE * 4); + page = virt_to_page(pte_pg); + if (!pgtable_page_ctor(page)) { + __free_page(page); + return 0; } return pte_pg; diff --git a/arch/arc/include/asm/prom.h b/arch/arc/include/asm/prom.h deleted file mode 100644 index 692d0d0789a7..000000000000 --- a/arch/arc/include/asm/prom.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (C) 2012 Synopsys, Inc. (www.synopsys.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 - * published by the Free Software Foundation. - */ - -#ifndef _ASM_ARC_PROM_H_ -#define _ASM_ARC_PROM_H_ - -#define HAVE_ARCH_DEVTREE_FIXUPS - -#endif diff --git a/arch/arc/include/asm/setup.h b/arch/arc/include/asm/setup.h index 229e50681497..e10f8cef56a8 100644 --- a/arch/arc/include/asm/setup.h +++ b/arch/arc/include/asm/setup.h @@ -31,7 +31,7 @@ struct cpuinfo_data { extern int root_mountflags, end_mem; extern int running_on_hw; -void __init setup_processor(void); +void setup_processor(void); void __init setup_arch_memory(void); #endif /* __ASMARC_SETUP_H */ diff --git a/arch/arc/include/asm/smp.h b/arch/arc/include/asm/smp.h index c4fb211dcd25..eefc29f08cdb 100644 --- a/arch/arc/include/asm/smp.h +++ b/arch/arc/include/asm/smp.h @@ -30,7 +30,7 @@ extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); * APIs provided by arch SMP code to rest of arch code */ extern void __init smp_init_cpus(void); -extern void __init first_lines_of_secondary(void); +extern void first_lines_of_secondary(void); extern const char *arc_platform_smp_cpuinfo(void); /* diff --git a/arch/arc/include/asm/thread_info.h b/arch/arc/include/asm/thread_info.h index 2d50a4cdd7f3..45be21672011 100644 --- a/arch/arc/include/asm/thread_info.h +++ b/arch/arc/include/asm/thread_info.h @@ -80,8 +80,6 @@ static inline __attribute_const__ struct thread_info *current_thread_info(void) #endif /* !__ASSEMBLY__ */ -#define PREEMPT_ACTIVE 0x10000000 - /* * thread information flags * - these are process state flags that various assembly files may need to diff --git a/arch/arc/include/asm/tlbflush.h b/arch/arc/include/asm/tlbflush.h index b2f9bc7f68c8..71c7b2e4b874 100644 --- a/arch/arc/include/asm/tlbflush.h +++ b/arch/arc/include/asm/tlbflush.h @@ -18,11 +18,18 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end); void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end); -/* XXX: Revisit for SMP */ +#ifndef CONFIG_SMP #define flush_tlb_range(vma, s, e) local_flush_tlb_range(vma, s, e) #define flush_tlb_page(vma, page) local_flush_tlb_page(vma, page) #define flush_tlb_kernel_range(s, e) local_flush_tlb_kernel_range(s, e) #define flush_tlb_all() local_flush_tlb_all() #define flush_tlb_mm(mm) local_flush_tlb_mm(mm) - +#else +extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, + unsigned long end); +extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long page); +extern void flush_tlb_kernel_range(unsigned long start, unsigned long end); +extern void flush_tlb_all(void); +extern void flush_tlb_mm(struct mm_struct *mm); +#endif /* CONFIG_SMP */ #endif diff --git a/arch/arc/include/asm/unaligned.h b/arch/arc/include/asm/unaligned.h index 60702f3751d2..3e5f071bc00c 100644 --- a/arch/arc/include/asm/unaligned.h +++ b/arch/arc/include/asm/unaligned.h @@ -22,7 +22,8 @@ static inline int misaligned_fixup(unsigned long address, struct pt_regs *regs, struct callee_regs *cregs) { - return 0; + /* Not fixed */ + return 1; } #endif diff --git a/arch/arc/kernel/Makefile b/arch/arc/kernel/Makefile index c242ef07ba70..8004b4fa6461 100644 --- a/arch/arc/kernel/Makefile +++ b/arch/arc/kernel/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_ARC_MISALIGN_ACCESS) += unaligned.o obj-$(CONFIG_KGDB) += kgdb.o obj-$(CONFIG_ARC_METAWARE_HLINK) += arc_hostlink.o +obj-$(CONFIG_PERF_EVENTS) += perf_event.o obj-$(CONFIG_ARC_FPU_SAVE_RESTORE) += fpu.o CFLAGS_fpu.o += -mdpfp diff --git a/arch/arc/kernel/ctx_sw.c b/arch/arc/kernel/ctx_sw.c index 34410eb1a308..c14a5bea0c76 100644 --- a/arch/arc/kernel/ctx_sw.c +++ b/arch/arc/kernel/ctx_sw.c @@ -17,6 +17,8 @@ #include <asm/asm-offsets.h> #include <linux/sched.h> +#define KSP_WORD_OFF ((TASK_THREAD + THREAD_KSP) / 4) + struct task_struct *__sched __switch_to(struct task_struct *prev_task, struct task_struct *next_task) { @@ -45,7 +47,16 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task) #endif /* set ksp of outgoing task in tsk->thread.ksp */ +#if KSP_WORD_OFF <= 255 "st.as sp, [%3, %1] \n\t" +#else + /* + * Workaround for NR_CPUS=4k + * %1 is bigger than 255 (S9 offset for st.as) + */ + "add2 r24, %3, %1 \n\t" + "st sp, [r24] \n\t" +#endif "sync \n\t" @@ -97,7 +108,7 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task) /* FP/BLINK restore generated by gcc (standard func epilogue */ : "=r"(tmp) - : "n"((TASK_THREAD + THREAD_KSP) / 4), "r"(next), "r"(prev) + : "n"(KSP_WORD_OFF), "r"(next), "r"(prev) : "blink" ); diff --git a/arch/arc/kernel/ctx_sw_asm.S b/arch/arc/kernel/ctx_sw_asm.S index d8972345e4c2..65690e7fcc8c 100644 --- a/arch/arc/kernel/ctx_sw_asm.S +++ b/arch/arc/kernel/ctx_sw_asm.S @@ -14,6 +14,8 @@ #include <asm/asm-offsets.h> #include <asm/linkage.h> +#define KSP_WORD_OFF ((TASK_THREAD + THREAD_KSP) / 4) + ;################### Low Level Context Switch ########################## .section .sched.text,"ax",@progbits @@ -28,8 +30,13 @@ __switch_to: SAVE_CALLEE_SAVED_KERNEL /* Save the now KSP in task->thread.ksp */ - st.as sp, [r0, (TASK_THREAD + THREAD_KSP)/4] - +#if KSP_WORD_OFF <= 255 + st.as sp, [r0, KSP_WORD_OFF] +#else + /* Workaround for NR_CPUS=4k as ST.as can only take s9 offset */ + add2 r24, r0, KSP_WORD_OFF + st sp, [r24] +#endif /* * Return last task in r0 (return reg) * On ARC, Return reg = First Arg reg = r0. diff --git a/arch/arc/kernel/devtree.c b/arch/arc/kernel/devtree.c index 2340af0e1d6f..b6dc4e21fd32 100644 --- a/arch/arc/kernel/devtree.c +++ b/arch/arc/kernel/devtree.c @@ -14,10 +14,22 @@ #include <linux/memblock.h> #include <linux/of.h> #include <linux/of_fdt.h> -#include <asm/prom.h> #include <asm/clk.h> #include <asm/mach_desc.h> +static const void * __init arch_get_next_mach(const char *const **match) +{ + static const struct machine_desc *mdesc = __arch_info_begin; + const struct machine_desc *m = mdesc; + + if (m >= __arch_info_end) + return NULL; + + mdesc++; + *match = m->dt_compat; + return m; +} + /** * setup_machine_fdt - Machine setup when an dtb was passed to the kernel * @dt: virtual address pointer to dt blob @@ -25,93 +37,24 @@ * If a dtb was passed to the kernel, then use it to choose the correct * machine_desc and to setup the system. */ -struct machine_desc * __init setup_machine_fdt(void *dt) +const struct machine_desc * __init setup_machine_fdt(void *dt) { - struct boot_param_header *devtree = dt; - struct machine_desc *mdesc = NULL, *mdesc_best = NULL; - unsigned int score, mdesc_score = ~1; + const struct machine_desc *mdesc; unsigned long dt_root; - const char *model, *compat; void *clk; - char manufacturer[16]; unsigned long len; - /* check device tree validity */ - if (be32_to_cpu(devtree->magic) != OF_DT_HEADER) + if (!early_init_dt_scan(dt)) return NULL; - initial_boot_params = devtree; - dt_root = of_get_flat_dt_root(); - - /* - * The kernel could be multi-platform enabled, thus could have many - * "baked-in" machine descriptors. Search thru all for the best - * "compatible" string match. - */ - for_each_machine_desc(mdesc) { - score = of_flat_dt_match(dt_root, mdesc->dt_compat); - if (score > 0 && score < mdesc_score) { - mdesc_best = mdesc; - mdesc_score = score; - } - } - if (!mdesc_best) { - const char *prop; - long size; - - pr_err("\n unrecognized device tree list:\n[ "); - - prop = of_get_flat_dt_prop(dt_root, "compatible", &size); - if (prop) { - while (size > 0) { - printk("'%s' ", prop); - size -= strlen(prop) + 1; - prop += strlen(prop) + 1; - } - } - printk("]\n\n"); - + mdesc = of_flat_dt_match_machine(NULL, arch_get_next_mach); + if (!mdesc) machine_halt(); - } - - /* compat = "<manufacturer>,<model>" */ - compat = mdesc_best->dt_compat[0]; - - model = strchr(compat, ','); - if (model) - model++; - - strlcpy(manufacturer, compat, model ? model - compat : strlen(compat)); - - pr_info("Board \"%s\" from %s (Manufacturer)\n", model, manufacturer); - - /* Retrieve various information from the /chosen node */ - of_scan_flat_dt(early_init_dt_scan_chosen, boot_command_line); - - /* Initialize {size,address}-cells info */ - of_scan_flat_dt(early_init_dt_scan_root, NULL); - - /* Setup memory, calling early_init_dt_add_memory_arch */ - of_scan_flat_dt(early_init_dt_scan_memory, NULL); + dt_root = of_get_flat_dt_root(); clk = of_get_flat_dt_prop(dt_root, "clock-frequency", &len); if (clk) arc_set_core_freq(of_read_ulong(clk, len/4)); - return mdesc_best; -} - -/* - * Copy the flattened DT out of .init since unflattening doesn't copy strings - * and the normal DT APIs refs them from orig flat DT - */ -void __init copy_devtree(void) -{ - void *alloc = early_init_dt_alloc_memory_arch( - be32_to_cpu(initial_boot_params->totalsize), 64); - if (alloc) { - memcpy(alloc, initial_boot_params, - be32_to_cpu(initial_boot_params->totalsize)); - initial_boot_params = alloc; - } + return mdesc; } diff --git a/arch/arc/kernel/entry.S b/arch/arc/kernel/entry.S index b908dde8a331..47d09d07f093 100644 --- a/arch/arc/kernel/entry.S +++ b/arch/arc/kernel/entry.S @@ -250,6 +250,14 @@ ARC_ENTRY handle_interrupt_level1 lr r0, [icause1] and r0, r0, 0x1f +#ifdef CONFIG_TRACE_IRQFLAGS + ; icause1 needs to be read early, before calling tracing, which + ; can clobber scratch regs, hence use of stack to stash it + push r0 + TRACE_ASM_IRQ_DISABLE + pop r0 +#endif + bl.d @arch_do_IRQ mov r1, sp @@ -337,9 +345,9 @@ ARC_ENTRY EV_TLBProtV ; vineetg: Mar 6th: Random Seg Fault issue #1 ; ecr and efa were not saved in case an Intr sneaks in ; after fake rtie - ; + lr r2, [ecr] - lr r1, [efa] ; Faulting Data address + lr r0, [efa] ; Faulting Data address ; --------(4) Return from CPU Exception Mode --------- ; Fake a rtie, but rtie to next label @@ -348,6 +356,8 @@ ARC_ENTRY EV_TLBProtV FAKE_RET_FROM_EXCPN r9 + mov r1, sp + ;------ (5) Type of Protection Violation? ---------- ; ; ProtV Hardware Exception is triggered for Access Faults of 2 types @@ -358,16 +368,12 @@ ARC_ENTRY EV_TLBProtV bbit1 r2, ECR_C_BIT_PROTV_MISALIG_DATA, 4f ;========= (6a) Access Violation Processing ======== - mov r0, sp ; pt_regs bl do_page_fault b ret_from_exception ;========== (6b) Non aligned access ============ 4: - mov r0, r1 - mov r1, sp ; pt_regs -#ifdef CONFIG_ARC_MISALIGN_ACCESS SAVE_CALLEE_SAVED_USER mov r2, sp ; callee_regs @@ -376,9 +382,6 @@ ARC_ENTRY EV_TLBProtV ; TBD: optimize - do this only if a callee reg was involved ; either a dst of emulated LD/ST or src with address-writeback RESTORE_CALLEE_SAVED_USER -#else - bl do_misaligned_error -#endif b ret_from_exception @@ -575,6 +578,7 @@ resume_user_mode_begin: ; --- (Slow Path #2) pending signal --- mov r0, sp ; pt_regs for arg to do_signal()/do_notify_resume() + GET_CURR_THR_INFO_FLAGS r9 bbit0 r9, TIF_SIGPENDING, .Lchk_notify_resume ; Normal Trap/IRQ entry only saves Scratch (caller-saved) regs @@ -640,6 +644,8 @@ resume_kernel_mode: restore_regs : + TRACE_ASM_IRQ_ENABLE + lr r10, [status32] ; Restore REG File. In case multiple Events outstanding, diff --git a/arch/arc/kernel/head.S b/arch/arc/kernel/head.S index 0f944f024513..2c878e964a64 100644 --- a/arch/arc/kernel/head.S +++ b/arch/arc/kernel/head.S @@ -95,7 +95,7 @@ stext: ;---------------------------------------------------------------- ; First lines of code run by secondary before jumping to 'C' ;---------------------------------------------------------------- - .section .init.text, "ax",@progbits + .section .text, "ax",@progbits .type first_lines_of_secondary, @function .globl first_lines_of_secondary diff --git a/arch/arc/kernel/irq.c b/arch/arc/kernel/irq.c index 5fc92455da36..a4b141ee9a6a 100644 --- a/arch/arc/kernel/irq.c +++ b/arch/arc/kernel/irq.c @@ -39,10 +39,14 @@ void arc_init_IRQ(void) level_mask |= IS_ENABLED(CONFIG_ARC_IRQ5_LV2) << 5; level_mask |= IS_ENABLED(CONFIG_ARC_IRQ6_LV2) << 6; - if (level_mask) { + /* + * Write to register, even if no LV2 IRQs configured to reset it + * in case bootloader had mucked with it + */ + write_aux_reg(AUX_IRQ_LEV, level_mask); + + if (level_mask) pr_info("Level-2 interrupts bitset %x\n", level_mask); - write_aux_reg(AUX_IRQ_LEV, level_mask); - } } /* @@ -146,7 +150,7 @@ void arch_do_IRQ(unsigned int irq, struct pt_regs *regs) set_irq_regs(old_regs); } -int __init get_hw_config_num_irq(void) +int get_hw_config_num_irq(void) { uint32_t val = read_aux_reg(ARC_REG_VECBASE_BCR); diff --git a/arch/arc/kernel/kgdb.c b/arch/arc/kernel/kgdb.c index a7698fb14818..a2ff5c5d1450 100644 --- a/arch/arc/kernel/kgdb.c +++ b/arch/arc/kernel/kgdb.c @@ -196,6 +196,18 @@ void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long ip) instruction_pointer(regs) = ip; } +static void kgdb_call_nmi_hook(void *ignored) +{ + kgdb_nmicallback(raw_smp_processor_id(), NULL); +} + +void kgdb_roundup_cpus(unsigned long flags) +{ + local_irq_enable(); + smp_call_function(kgdb_call_nmi_hook, NULL, 0); + local_irq_disable(); +} + struct kgdb_arch arch_kgdb_ops = { /* breakpoint instruction: TRAP_S 0x3 */ #ifdef CONFIG_CPU_BIG_ENDIAN diff --git a/arch/arc/kernel/kprobes.c b/arch/arc/kernel/kprobes.c index 72f97822784a..42b05046fad9 100644 --- a/arch/arc/kernel/kprobes.c +++ b/arch/arc/kernel/kprobes.c @@ -87,13 +87,13 @@ static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb) static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb) { - __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp; + __this_cpu_write(current_kprobe, kcb->prev_kprobe.kp); kcb->kprobe_status = kcb->prev_kprobe.status; } static inline void __kprobes set_current_kprobe(struct kprobe *p) { - __get_cpu_var(current_kprobe) = p; + __this_cpu_write(current_kprobe, p); } static void __kprobes resume_execution(struct kprobe *p, unsigned long addr, @@ -237,7 +237,7 @@ int __kprobes arc_kprobe_handler(unsigned long addr, struct pt_regs *regs) return 1; } else if (kprobe_running()) { - p = __get_cpu_var(current_kprobe); + p = __this_cpu_read(current_kprobe); if (p->break_handler && p->break_handler(p, regs)) { setup_singlestep(p, regs); kcb->kprobe_status = KPROBE_HIT_SS; @@ -327,7 +327,7 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, unsigned long trapnr) */ /* We increment the nmissed count for accounting, - * we can also use npre/npostfault count for accouting + * we can also use npre/npostfault count for accounting * these specific fault cases. */ kprobes_inc_nmissed_count(cur); diff --git a/arch/arc/kernel/perf_event.c b/arch/arc/kernel/perf_event.c new file mode 100644 index 000000000000..e46d81f70979 --- /dev/null +++ b/arch/arc/kernel/perf_event.c @@ -0,0 +1,326 @@ +/* + * Linux performance counter support for ARC700 series + * + * Copyright (C) 2013 Synopsys, Inc. (www.synopsys.com) + * + * This code is inspired by the perf support of various other architectures. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ +#include <linux/errno.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/perf_event.h> +#include <linux/platform_device.h> +#include <asm/arcregs.h> + +struct arc_pmu { + struct pmu pmu; + int counter_size; /* in bits */ + int n_counters; + unsigned long used_mask[BITS_TO_LONGS(ARC_PMU_MAX_HWEVENTS)]; + int ev_hw_idx[PERF_COUNT_ARC_HW_MAX]; +}; + +/* read counter #idx; note that counter# != event# on ARC! */ +static uint64_t arc_pmu_read_counter(int idx) +{ + uint32_t tmp; + uint64_t result; + + /* + * ARC supports making 'snapshots' of the counters, so we don't + * need to care about counters wrapping to 0 underneath our feet + */ + write_aux_reg(ARC_REG_PCT_INDEX, idx); + tmp = read_aux_reg(ARC_REG_PCT_CONTROL); + write_aux_reg(ARC_REG_PCT_CONTROL, tmp | ARC_REG_PCT_CONTROL_SN); + result = (uint64_t) (read_aux_reg(ARC_REG_PCT_SNAPH)) << 32; + result |= read_aux_reg(ARC_REG_PCT_SNAPL); + + return result; +} + +static void arc_perf_event_update(struct perf_event *event, + struct hw_perf_event *hwc, int idx) +{ + struct arc_pmu *arc_pmu = container_of(event->pmu, struct arc_pmu, pmu); + uint64_t prev_raw_count, new_raw_count; + int64_t delta; + + do { + prev_raw_count = local64_read(&hwc->prev_count); + new_raw_count = arc_pmu_read_counter(idx); + } while (local64_cmpxchg(&hwc->prev_count, prev_raw_count, + new_raw_count) != prev_raw_count); + + delta = (new_raw_count - prev_raw_count) & + ((1ULL << arc_pmu->counter_size) - 1ULL); + + local64_add(delta, &event->count); + local64_sub(delta, &hwc->period_left); +} + +static void arc_pmu_read(struct perf_event *event) +{ + arc_perf_event_update(event, &event->hw, event->hw.idx); +} + +static int arc_pmu_cache_event(u64 config) +{ + unsigned int cache_type, cache_op, cache_result; + int ret; + + cache_type = (config >> 0) & 0xff; + cache_op = (config >> 8) & 0xff; + cache_result = (config >> 16) & 0xff; + if (cache_type >= PERF_COUNT_HW_CACHE_MAX) + return -EINVAL; + if (cache_type >= PERF_COUNT_HW_CACHE_OP_MAX) + return -EINVAL; + if (cache_type >= PERF_COUNT_HW_CACHE_RESULT_MAX) + return -EINVAL; + + ret = arc_pmu_cache_map[cache_type][cache_op][cache_result]; + + if (ret == CACHE_OP_UNSUPPORTED) + return -ENOENT; + + return ret; +} + +/* initializes hw_perf_event structure if event is supported */ +static int arc_pmu_event_init(struct perf_event *event) +{ + struct arc_pmu *arc_pmu = container_of(event->pmu, struct arc_pmu, pmu); + struct hw_perf_event *hwc = &event->hw; + int ret; + + /* ARC 700 PMU does not support sampling events */ + if (is_sampling_event(event)) + return -ENOENT; + + switch (event->attr.type) { + case PERF_TYPE_HARDWARE: + if (event->attr.config >= PERF_COUNT_HW_MAX) + return -ENOENT; + if (arc_pmu->ev_hw_idx[event->attr.config] < 0) + return -ENOENT; + hwc->config = arc_pmu->ev_hw_idx[event->attr.config]; + pr_debug("initializing event %d with cfg %d\n", + (int) event->attr.config, (int) hwc->config); + return 0; + case PERF_TYPE_HW_CACHE: + ret = arc_pmu_cache_event(event->attr.config); + if (ret < 0) + return ret; + hwc->config = arc_pmu->ev_hw_idx[ret]; + return 0; + default: + return -ENOENT; + } +} + +/* starts all counters */ +static void arc_pmu_enable(struct pmu *pmu) +{ + uint32_t tmp; + tmp = read_aux_reg(ARC_REG_PCT_CONTROL); + write_aux_reg(ARC_REG_PCT_CONTROL, (tmp & 0xffff0000) | 0x1); +} + +/* stops all counters */ +static void arc_pmu_disable(struct pmu *pmu) +{ + uint32_t tmp; + tmp = read_aux_reg(ARC_REG_PCT_CONTROL); + write_aux_reg(ARC_REG_PCT_CONTROL, (tmp & 0xffff0000) | 0x0); +} + +/* + * Assigns hardware counter to hardware condition. + * Note that there is no separate start/stop mechanism; + * stopping is achieved by assigning the 'never' condition + */ +static void arc_pmu_start(struct perf_event *event, int flags) +{ + struct hw_perf_event *hwc = &event->hw; + int idx = hwc->idx; + + if (WARN_ON_ONCE(idx == -1)) + return; + + if (flags & PERF_EF_RELOAD) + WARN_ON_ONCE(!(event->hw.state & PERF_HES_UPTODATE)); + + event->hw.state = 0; + + /* enable ARC pmu here */ + write_aux_reg(ARC_REG_PCT_INDEX, idx); + write_aux_reg(ARC_REG_PCT_CONFIG, hwc->config); +} + +static void arc_pmu_stop(struct perf_event *event, int flags) +{ + struct hw_perf_event *hwc = &event->hw; + int idx = hwc->idx; + + if (!(event->hw.state & PERF_HES_STOPPED)) { + /* stop ARC pmu here */ + write_aux_reg(ARC_REG_PCT_INDEX, idx); + + /* condition code #0 is always "never" */ + write_aux_reg(ARC_REG_PCT_CONFIG, 0); + + event->hw.state |= PERF_HES_STOPPED; + } + + if ((flags & PERF_EF_UPDATE) && + !(event->hw.state & PERF_HES_UPTODATE)) { + arc_perf_event_update(event, &event->hw, idx); + event->hw.state |= PERF_HES_UPTODATE; + } +} + +static void arc_pmu_del(struct perf_event *event, int flags) +{ + struct arc_pmu *arc_pmu = container_of(event->pmu, struct arc_pmu, pmu); + + arc_pmu_stop(event, PERF_EF_UPDATE); + __clear_bit(event->hw.idx, arc_pmu->used_mask); + + perf_event_update_userpage(event); +} + +/* allocate hardware counter and optionally start counting */ +static int arc_pmu_add(struct perf_event *event, int flags) +{ + struct arc_pmu *arc_pmu = container_of(event->pmu, struct arc_pmu, pmu); + struct hw_perf_event *hwc = &event->hw; + int idx = hwc->idx; + + if (__test_and_set_bit(idx, arc_pmu->used_mask)) { + idx = find_first_zero_bit(arc_pmu->used_mask, + arc_pmu->n_counters); + if (idx == arc_pmu->n_counters) + return -EAGAIN; + + __set_bit(idx, arc_pmu->used_mask); + hwc->idx = idx; + } + + write_aux_reg(ARC_REG_PCT_INDEX, idx); + write_aux_reg(ARC_REG_PCT_CONFIG, 0); + write_aux_reg(ARC_REG_PCT_COUNTL, 0); + write_aux_reg(ARC_REG_PCT_COUNTH, 0); + local64_set(&hwc->prev_count, 0); + + hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED; + if (flags & PERF_EF_START) + arc_pmu_start(event, PERF_EF_RELOAD); + + perf_event_update_userpage(event); + + return 0; +} + +static int arc_pmu_device_probe(struct platform_device *pdev) +{ + struct arc_pmu *arc_pmu; + struct arc_reg_pct_build pct_bcr; + struct arc_reg_cc_build cc_bcr; + int i, j, ret; + + union cc_name { + struct { + uint32_t word0, word1; + char sentinel; + } indiv; + char str[9]; + } cc_name; + + + READ_BCR(ARC_REG_PCT_BUILD, pct_bcr); + if (!pct_bcr.v) { + pr_err("This core does not have performance counters!\n"); + return -ENODEV; + } + + arc_pmu = devm_kzalloc(&pdev->dev, sizeof(struct arc_pmu), + GFP_KERNEL); + if (!arc_pmu) + return -ENOMEM; + + arc_pmu->n_counters = pct_bcr.c; + BUG_ON(arc_pmu->n_counters > ARC_PMU_MAX_HWEVENTS); + + arc_pmu->counter_size = 32 + (pct_bcr.s << 4); + pr_info("ARC PMU found with %d counters of size %d bits\n", + arc_pmu->n_counters, arc_pmu->counter_size); + + READ_BCR(ARC_REG_CC_BUILD, cc_bcr); + + if (!cc_bcr.v) + pr_err("Strange! Performance counters exist, but no countable conditions?\n"); + + pr_info("ARC PMU has %d countable conditions\n", cc_bcr.c); + + cc_name.str[8] = 0; + for (i = 0; i < PERF_COUNT_HW_MAX; i++) + arc_pmu->ev_hw_idx[i] = -1; + + for (j = 0; j < cc_bcr.c; j++) { + write_aux_reg(ARC_REG_CC_INDEX, j); + cc_name.indiv.word0 = read_aux_reg(ARC_REG_CC_NAME0); + cc_name.indiv.word1 = read_aux_reg(ARC_REG_CC_NAME1); + for (i = 0; i < ARRAY_SIZE(arc_pmu_ev_hw_map); i++) { + if (arc_pmu_ev_hw_map[i] && + !strcmp(arc_pmu_ev_hw_map[i], cc_name.str) && + strlen(arc_pmu_ev_hw_map[i])) { + pr_debug("mapping %d to idx %d with name %s\n", + i, j, cc_name.str); + arc_pmu->ev_hw_idx[i] = j; + } + } + } + + arc_pmu->pmu = (struct pmu) { + .pmu_enable = arc_pmu_enable, + .pmu_disable = arc_pmu_disable, + .event_init = arc_pmu_event_init, + .add = arc_pmu_add, + .del = arc_pmu_del, + .start = arc_pmu_start, + .stop = arc_pmu_stop, + .read = arc_pmu_read, + }; + + ret = perf_pmu_register(&arc_pmu->pmu, pdev->name, PERF_TYPE_RAW); + + return ret; +} + +#ifdef CONFIG_OF +static const struct of_device_id arc_pmu_match[] = { + { .compatible = "snps,arc700-pmu" }, + {}, +}; +MODULE_DEVICE_TABLE(of, arc_pmu_match); +#endif + +static struct platform_driver arc_pmu_driver = { + .driver = { + .name = "arc700-pmu", + .of_match_table = of_match_ptr(arc_pmu_match), + }, + .probe = arc_pmu_device_probe, +}; + +module_platform_driver(arc_pmu_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mischa Jonker <mjonker@synopsys.com>"); +MODULE_DESCRIPTION("ARC PMU driver"); diff --git a/arch/arc/kernel/reset.c b/arch/arc/kernel/reset.c index e227a2b1c943..2768fa1e39b9 100644 --- a/arch/arc/kernel/reset.c +++ b/arch/arc/kernel/reset.c @@ -31,3 +31,4 @@ void machine_power_off(void) } void (*pm_power_off) (void) = NULL; +EXPORT_SYMBOL(pm_power_off); diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c index 2c68bc7e6a78..643eae4436e0 100644 --- a/arch/arc/kernel/setup.c +++ b/arch/arc/kernel/setup.c @@ -21,7 +21,6 @@ #include <asm/setup.h> #include <asm/page.h> #include <asm/irq.h> -#include <asm/prom.h> #include <asm/unwind.h> #include <asm/clk.h> #include <asm/mach_desc.h> @@ -31,14 +30,13 @@ int running_on_hw = 1; /* vs. on ISS */ char __initdata command_line[COMMAND_LINE_SIZE]; -struct machine_desc *machine_desc; +const struct machine_desc *machine_desc; struct task_struct *_current_task[NR_CPUS]; /* For stack switching */ struct cpuinfo_arc cpuinfo_arc700[NR_CPUS]; - -void read_arc_build_cfg_regs(void) +static void read_arc_build_cfg_regs(void) { struct bcr_perip uncached_space; struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()]; @@ -106,7 +104,7 @@ static const struct cpuinfo_data arc_cpu_tbl[] = { { {0x00, NULL } } }; -char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len) +static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len) { int n = 0; struct cpuinfo_arc *cpu = &cpuinfo_arc700[cpu_id]; @@ -171,7 +169,7 @@ static const struct id_to_str mac_mul_nm[] = { {0x6, "Dual 16x16 and 32x16"} }; -char *arc_extn_mumbojumbo(int cpu_id, char *buf, int len) +static char *arc_extn_mumbojumbo(int cpu_id, char *buf, int len) { int n = 0; struct cpuinfo_arc *cpu = &cpuinfo_arc700[cpu_id]; @@ -234,7 +232,7 @@ char *arc_extn_mumbojumbo(int cpu_id, char *buf, int len) return buf; } -void arc_chk_ccms(void) +static void arc_chk_ccms(void) { #if defined(CONFIG_ARC_HAS_DCCM) || defined(CONFIG_ARC_HAS_ICCM) struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()]; @@ -269,7 +267,7 @@ void arc_chk_ccms(void) * hardware has dedicated regs which need to be saved/restored on ctx-sw * (Single Precision uses core regs), thus kernel is kind of oblivious to it */ -void arc_chk_fpu(void) +static void arc_chk_fpu(void) { struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()]; @@ -346,8 +344,7 @@ void __init setup_arch(char **cmdline_p) setup_arch_memory(); /* copy flat DT out of .init and then unflatten it */ - copy_devtree(); - unflatten_device_tree(); + unflatten_and_copy_device_tree(); /* Can be issue if someone passes cmd line arg "ro" * But that is unlikely so keeping it as it is diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c index bca3052c956d..c2f9ebbc38f6 100644 --- a/arch/arc/kernel/smp.c +++ b/arch/arc/kernel/smp.c @@ -95,7 +95,7 @@ void __init smp_cpus_done(unsigned int max_cpus) * If it turns out to be elaborate, it's better to code it in assembly * */ -void __attribute__((weak)) arc_platform_smp_wait_to_boot(int cpu) +void __weak arc_platform_smp_wait_to_boot(int cpu) { /* * As a hack for debugging - since debugger will single-step over the @@ -128,6 +128,7 @@ void start_kernel_secondary(void) atomic_inc(&mm->mm_users); atomic_inc(&mm->mm_count); current->active_mm = mm; + cpumask_set_cpu(cpu, mm_cpumask(mm)); notify_cpu_starting(cpu); set_cpu_online(cpu, true); @@ -210,7 +211,6 @@ enum ipi_msg_type { IPI_NOP = 0, IPI_RESCHEDULE = 1, IPI_CALL_FUNC, - IPI_CALL_FUNC_SINGLE, IPI_CPU_STOP }; @@ -254,7 +254,7 @@ void smp_send_stop(void) void arch_send_call_function_single_ipi(int cpu) { - ipi_send_msg(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE); + ipi_send_msg(cpumask_of(cpu), IPI_CALL_FUNC); } void arch_send_call_function_ipi_mask(const struct cpumask *mask) @@ -286,10 +286,6 @@ static inline void __do_IPI(unsigned long *ops, struct ipi_data *ipi, int cpu) generic_smp_call_function_interrupt(); break; - case IPI_CALL_FUNC_SINGLE: - generic_smp_call_function_single_interrupt(); - break; - case IPI_CPU_STOP: ipi_cpu_stop(cpu); break; diff --git a/arch/arc/kernel/stacktrace.c b/arch/arc/kernel/stacktrace.c index f8b7d880304d..9ce47cfe2303 100644 --- a/arch/arc/kernel/stacktrace.c +++ b/arch/arc/kernel/stacktrace.c @@ -237,11 +237,14 @@ unsigned int get_wchan(struct task_struct *tsk) */ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) { + /* Assumes @tsk is sleeping so unwinds from __switch_to */ arc_unwind_core(tsk, NULL, __collect_all_but_sched, trace); } void save_stack_trace(struct stack_trace *trace) { - arc_unwind_core(current, NULL, __collect_all, trace); + /* Pass NULL for task so it unwinds the current call frame */ + arc_unwind_core(NULL, NULL, __collect_all, trace); } +EXPORT_SYMBOL_GPL(save_stack_trace); #endif diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c index 3fde7de3ea67..e5f3a837fb35 100644 --- a/arch/arc/kernel/time.c +++ b/arch/arc/kernel/time.c @@ -63,9 +63,10 @@ int arc_counter_setup(void) { - /* RTSC insn taps into cpu clk, needs no setup */ - - /* For SMP, only allowed if cross-core-sync, hence usable as cs */ + /* + * For SMP this needs to be 0. However Kconfig glue doesn't + * enable this option for SMP configs + */ return 1; } @@ -206,7 +207,7 @@ static DEFINE_PER_CPU(struct clock_event_device, arc_clockevent_device) = { static irqreturn_t timer_irq_handler(int irq, void *dev_id) { - struct clock_event_device *clk = &__get_cpu_var(arc_clockevent_device); + struct clock_event_device *clk = this_cpu_ptr(&arc_clockevent_device); arc_timer_event_ack(clk->mode == CLOCK_EVT_MODE_PERIODIC); clk->event_handler(clk); @@ -223,7 +224,7 @@ static struct irqaction arc_timer_irq = { * Setup the local event timer for @cpu * N.B. weak so that some exotic ARC SoCs can completely override it */ -void __attribute__((weak)) arc_local_timer_setup(unsigned int cpu) +void __weak arc_local_timer_setup(unsigned int cpu) { struct clock_event_device *clk = &per_cpu(arc_clockevent_device, cpu); diff --git a/arch/arc/kernel/traps.c b/arch/arc/kernel/traps.c index e21692d2fdab..3eadfdabc322 100644 --- a/arch/arc/kernel/traps.c +++ b/arch/arc/kernel/traps.c @@ -84,19 +84,18 @@ DO_ERROR_INFO(SIGBUS, "Invalid Mem Access", do_memory_error, BUS_ADRERR) DO_ERROR_INFO(SIGTRAP, "Breakpoint Set", trap_is_brkpt, TRAP_BRKPT) DO_ERROR_INFO(SIGBUS, "Misaligned Access", do_misaligned_error, BUS_ADRALN) -#ifdef CONFIG_ARC_MISALIGN_ACCESS /* * Entry Point for Misaligned Data access Exception, for emulating in software */ int do_misaligned_access(unsigned long address, struct pt_regs *regs, struct callee_regs *cregs) { + /* If emulation not enabled, or failed, kill the task */ if (misaligned_fixup(address, regs, cregs) != 0) return do_misaligned_error(address, regs); return 0; } -#endif /* * Entry point for miscll errors such as Nested Exceptions diff --git a/arch/arc/mm/cache_arc700.c b/arch/arc/mm/cache_arc700.c index 5a1259cd948c..6b58c1de7577 100644 --- a/arch/arc/mm/cache_arc700.c +++ b/arch/arc/mm/cache_arc700.c @@ -182,7 +182,7 @@ void arc_cache_init(void) #ifdef CONFIG_ARC_HAS_ICACHE /* 1. Confirm some of I-cache params which Linux assumes */ - if (ic->line_len != ARC_ICACHE_LINE_LEN) + if (ic->line_len != L1_CACHE_BYTES) panic("Cache H/W doesn't match kernel Config"); if (ic->ver != CONFIG_ARC_MMU_VER) @@ -205,7 +205,7 @@ chk_dc: return; #ifdef CONFIG_ARC_HAS_DCACHE - if (dc->line_len != ARC_DCACHE_LINE_LEN) + if (dc->line_len != L1_CACHE_BYTES) panic("Cache H/W doesn't match kernel Config"); /* check for D-Cache aliasing */ @@ -240,6 +240,67 @@ chk_dc: #define OP_INV 0x1 #define OP_FLUSH 0x2 #define OP_FLUSH_N_INV 0x3 +#define OP_INV_IC 0x4 + +/* + * Common Helper for Line Operations on {I,D}-Cache + */ +static inline void __cache_line_loop(unsigned long paddr, unsigned long vaddr, + unsigned long sz, const int cacheop) +{ + unsigned int aux_cmd, aux_tag; + int num_lines; + const int full_page_op = __builtin_constant_p(sz) && sz == PAGE_SIZE; + + if (cacheop == OP_INV_IC) { + aux_cmd = ARC_REG_IC_IVIL; + aux_tag = ARC_REG_IC_PTAG; + } + else { + /* d$ cmd: INV (discard or wback-n-discard) OR FLUSH (wback) */ + aux_cmd = cacheop & OP_INV ? ARC_REG_DC_IVDL : ARC_REG_DC_FLDL; + aux_tag = ARC_REG_DC_PTAG; + } + + /* Ensure we properly floor/ceil the non-line aligned/sized requests + * and have @paddr - aligned to cache line and integral @num_lines. + * This however can be avoided for page sized since: + * -@paddr will be cache-line aligned already (being page aligned) + * -@sz will be integral multiple of line size (being page sized). + */ + if (!full_page_op) { + sz += paddr & ~CACHE_LINE_MASK; + paddr &= CACHE_LINE_MASK; + vaddr &= CACHE_LINE_MASK; + } + + num_lines = DIV_ROUND_UP(sz, L1_CACHE_BYTES); + +#if (CONFIG_ARC_MMU_VER <= 2) + /* MMUv2 and before: paddr contains stuffed vaddrs bits */ + paddr |= (vaddr >> PAGE_SHIFT) & 0x1F; +#else + /* if V-P const for loop, PTAG can be written once outside loop */ + if (full_page_op) + write_aux_reg(ARC_REG_DC_PTAG, paddr); +#endif + + while (num_lines-- > 0) { +#if (CONFIG_ARC_MMU_VER > 2) + /* MMUv3, cache ops require paddr seperately */ + if (!full_page_op) { + write_aux_reg(aux_tag, paddr); + paddr += L1_CACHE_BYTES; + } + + write_aux_reg(aux_cmd, vaddr); + vaddr += L1_CACHE_BYTES; +#else + write_aux_reg(aux, paddr); + paddr += L1_CACHE_BYTES; +#endif + } +} #ifdef CONFIG_ARC_HAS_DCACHE @@ -289,53 +350,6 @@ static inline void __dc_entire_op(const int cacheop) write_aux_reg(ARC_REG_DC_CTRL, tmp & ~DC_CTRL_INV_MODE_FLUSH); } -/* - * Per Line Operation on D-Cache - * Doesn't deal with type-of-op/IRQ-disabling/waiting-for-flush-to-complete - * It's sole purpose is to help gcc generate ZOL - * (aliasing VIPT dcache flushing needs both vaddr and paddr) - */ -static inline void __dc_line_loop(unsigned long paddr, unsigned long vaddr, - unsigned long sz, const int aux_reg) -{ - int num_lines; - - /* Ensure we properly floor/ceil the non-line aligned/sized requests - * and have @paddr - aligned to cache line and integral @num_lines. - * This however can be avoided for page sized since: - * -@paddr will be cache-line aligned already (being page aligned) - * -@sz will be integral multiple of line size (being page sized). - */ - if (!(__builtin_constant_p(sz) && sz == PAGE_SIZE)) { - sz += paddr & ~DCACHE_LINE_MASK; - paddr &= DCACHE_LINE_MASK; - vaddr &= DCACHE_LINE_MASK; - } - - num_lines = DIV_ROUND_UP(sz, ARC_DCACHE_LINE_LEN); - -#if (CONFIG_ARC_MMU_VER <= 2) - paddr |= (vaddr >> PAGE_SHIFT) & 0x1F; -#endif - - while (num_lines-- > 0) { -#if (CONFIG_ARC_MMU_VER > 2) - /* - * Just as for I$, in MMU v3, D$ ops also require - * "tag" bits in DC_PTAG, "index" bits in FLDL,IVDL ops - */ - write_aux_reg(ARC_REG_DC_PTAG, paddr); - - write_aux_reg(aux_reg, vaddr); - vaddr += ARC_DCACHE_LINE_LEN; -#else - /* paddr contains stuffed vaddrs bits */ - write_aux_reg(aux_reg, paddr); -#endif - paddr += ARC_DCACHE_LINE_LEN; - } -} - /* For kernel mappings cache operation: index is same as paddr */ #define __dc_line_op_k(p, sz, op) __dc_line_op(p, p, sz, op) @@ -346,7 +360,6 @@ static inline void __dc_line_op(unsigned long paddr, unsigned long vaddr, unsigned long sz, const int cacheop) { unsigned long flags, tmp = tmp; - int aux; local_irq_save(flags); @@ -361,12 +374,7 @@ static inline void __dc_line_op(unsigned long paddr, unsigned long vaddr, write_aux_reg(ARC_REG_DC_CTRL, tmp | DC_CTRL_INV_MODE_FLUSH); } - if (cacheop & OP_INV) /* Inv / flush-n-inv use same cmd reg */ - aux = ARC_REG_DC_IVDL; - else - aux = ARC_REG_DC_FLDL; - - __dc_line_loop(paddr, vaddr, sz, aux); + __cache_line_loop(paddr, vaddr, sz, cacheop); if (cacheop & OP_FLUSH) /* flush / flush-n-inv both wait */ wait_for_flush(); @@ -438,42 +446,9 @@ static void __ic_line_inv_vaddr(unsigned long paddr, unsigned long vaddr, unsigned long sz) { unsigned long flags; - int num_lines; - - /* - * Ensure we properly floor/ceil the non-line aligned/sized requests: - * However page sized flushes can be compile time optimised. - * -@paddr will be cache-line aligned already (being page aligned) - * -@sz will be integral multiple of line size (being page sized). - */ - if (!(__builtin_constant_p(sz) && sz == PAGE_SIZE)) { - sz += paddr & ~ICACHE_LINE_MASK; - paddr &= ICACHE_LINE_MASK; - vaddr &= ICACHE_LINE_MASK; - } - - num_lines = DIV_ROUND_UP(sz, ARC_ICACHE_LINE_LEN); - -#if (CONFIG_ARC_MMU_VER <= 2) - /* bits 17:13 of vaddr go as bits 4:0 of paddr */ - paddr |= (vaddr >> PAGE_SHIFT) & 0x1F; -#endif local_irq_save(flags); - while (num_lines-- > 0) { -#if (CONFIG_ARC_MMU_VER > 2) - /* tag comes from phy addr */ - write_aux_reg(ARC_REG_IC_PTAG, paddr); - - /* index bits come from vaddr */ - write_aux_reg(ARC_REG_IC_IVIL, vaddr); - vaddr += ARC_ICACHE_LINE_LEN; -#else - /* paddr contains stuffed vaddrs bits */ - write_aux_reg(ARC_REG_IC_IVIL, paddr); -#endif - paddr += ARC_ICACHE_LINE_LEN; - } + __cache_line_loop(paddr, vaddr, sz, OP_INV_IC); local_irq_restore(flags); } diff --git a/arch/arc/mm/fault.c b/arch/arc/mm/fault.c index d63f3de0cd5b..9c69552350c4 100644 --- a/arch/arc/mm/fault.c +++ b/arch/arc/mm/fault.c @@ -17,7 +17,7 @@ #include <asm/pgalloc.h> #include <asm/mmu.h> -static int handle_vmalloc_fault(struct mm_struct *mm, unsigned long address) +static int handle_vmalloc_fault(unsigned long address) { /* * Synchronize this task's top level page-table @@ -27,7 +27,7 @@ static int handle_vmalloc_fault(struct mm_struct *mm, unsigned long address) pud_t *pud, *pud_k; pmd_t *pmd, *pmd_k; - pgd = pgd_offset_fast(mm, address); + pgd = pgd_offset_fast(current->active_mm, address); pgd_k = pgd_offset_k(address); if (!pgd_present(*pgd_k)) @@ -52,7 +52,7 @@ bad_area: return 1; } -void do_page_fault(struct pt_regs *regs, unsigned long address) +void do_page_fault(unsigned long address, struct pt_regs *regs) { struct vm_area_struct *vma = NULL; struct task_struct *tsk = current; @@ -72,7 +72,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long address) * nothing more. */ if (address >= VMALLOC_START && address <= VMALLOC_END) { - ret = handle_vmalloc_fault(mm, address); + ret = handle_vmalloc_fault(address); if (unlikely(ret)) goto bad_area_nosemaphore; else diff --git a/arch/arc/mm/init.c b/arch/arc/mm/init.c index 81279ec73a6a..55e0a85bea78 100644 --- a/arch/arc/mm/init.c +++ b/arch/arc/mm/init.c @@ -125,10 +125,3 @@ void __init free_initrd_mem(unsigned long start, unsigned long end) free_reserved_area((void *)start, (void *)end, -1, "initrd"); } #endif - -#ifdef CONFIG_OF_FLATTREE -void __init early_init_dt_setup_initrd_arch(u64 start, u64 end) -{ - pr_err("%s(%llx, %llx)\n", __func__, start, end); -} -#endif /* CONFIG_OF_FLATTREE */ diff --git a/arch/arc/mm/tlb.c b/arch/arc/mm/tlb.c index 71cb26df4255..e1acf0ce5647 100644 --- a/arch/arc/mm/tlb.c +++ b/arch/arc/mm/tlb.c @@ -100,7 +100,7 @@ /* A copy of the ASID from the PID reg is kept in asid_cache */ -unsigned int asid_cache = MM_CTXT_FIRST_CYCLE; +DEFINE_PER_CPU(unsigned int, asid_cache) = MM_CTXT_FIRST_CYCLE; /* * Utility Routine to erase a J-TLB entry @@ -274,6 +274,7 @@ noinline void local_flush_tlb_mm(struct mm_struct *mm) void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) { + const unsigned int cpu = smp_processor_id(); unsigned long flags; /* If range @start to @end is more than 32 TLB entries deep, @@ -297,9 +298,9 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, local_irq_save(flags); - if (vma->vm_mm->context.asid != MM_CTXT_NO_ASID) { + if (asid_mm(vma->vm_mm, cpu) != MM_CTXT_NO_ASID) { while (start < end) { - tlb_entry_erase(start | hw_pid(vma->vm_mm)); + tlb_entry_erase(start | hw_pid(vma->vm_mm, cpu)); start += PAGE_SIZE; } } @@ -346,6 +347,7 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) { + const unsigned int cpu = smp_processor_id(); unsigned long flags; /* Note that it is critical that interrupts are DISABLED between @@ -353,14 +355,87 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) */ local_irq_save(flags); - if (vma->vm_mm->context.asid != MM_CTXT_NO_ASID) { - tlb_entry_erase((page & PAGE_MASK) | hw_pid(vma->vm_mm)); + if (asid_mm(vma->vm_mm, cpu) != MM_CTXT_NO_ASID) { + tlb_entry_erase((page & PAGE_MASK) | hw_pid(vma->vm_mm, cpu)); utlb_invalidate(); } local_irq_restore(flags); } +#ifdef CONFIG_SMP + +struct tlb_args { + struct vm_area_struct *ta_vma; + unsigned long ta_start; + unsigned long ta_end; +}; + +static inline void ipi_flush_tlb_page(void *arg) +{ + struct tlb_args *ta = arg; + + local_flush_tlb_page(ta->ta_vma, ta->ta_start); +} + +static inline void ipi_flush_tlb_range(void *arg) +{ + struct tlb_args *ta = arg; + + local_flush_tlb_range(ta->ta_vma, ta->ta_start, ta->ta_end); +} + +static inline void ipi_flush_tlb_kernel_range(void *arg) +{ + struct tlb_args *ta = (struct tlb_args *)arg; + + local_flush_tlb_kernel_range(ta->ta_start, ta->ta_end); +} + +void flush_tlb_all(void) +{ + on_each_cpu((smp_call_func_t)local_flush_tlb_all, NULL, 1); +} + +void flush_tlb_mm(struct mm_struct *mm) +{ + on_each_cpu_mask(mm_cpumask(mm), (smp_call_func_t)local_flush_tlb_mm, + mm, 1); +} + +void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) +{ + struct tlb_args ta = { + .ta_vma = vma, + .ta_start = uaddr + }; + + on_each_cpu_mask(mm_cpumask(vma->vm_mm), ipi_flush_tlb_page, &ta, 1); +} + +void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, + unsigned long end) +{ + struct tlb_args ta = { + .ta_vma = vma, + .ta_start = start, + .ta_end = end + }; + + on_each_cpu_mask(mm_cpumask(vma->vm_mm), ipi_flush_tlb_range, &ta, 1); +} + +void flush_tlb_kernel_range(unsigned long start, unsigned long end) +{ + struct tlb_args ta = { + .ta_start = start, + .ta_end = end + }; + + on_each_cpu(ipi_flush_tlb_kernel_range, &ta, 1); +} +#endif + /* * Routine to create a TLB entry */ @@ -400,7 +475,7 @@ void create_tlb(struct vm_area_struct *vma, unsigned long address, pte_t *ptep) local_irq_save(flags); - tlb_paranoid_check(vma->vm_mm->context.asid, address); + tlb_paranoid_check(asid_mm(vma->vm_mm, smp_processor_id()), address); address &= PAGE_MASK; @@ -610,9 +685,9 @@ void do_tlb_overlap_fault(unsigned long cause, unsigned long address, struct pt_regs *regs) { int set, way, n; - unsigned int pd0[4], pd1[4]; /* assume max 4 ways */ unsigned long flags, is_valid; struct cpuinfo_arc_mmu *mmu = &cpuinfo_arc700[smp_processor_id()].mmu; + unsigned int pd0[mmu->ways], pd1[mmu->ways]; local_irq_save(flags); @@ -637,7 +712,7 @@ void do_tlb_overlap_fault(unsigned long cause, unsigned long address, continue; /* Scan the set for duplicate ways: needs a nested loop */ - for (way = 0; way < mmu->ways; way++) { + for (way = 0; way < mmu->ways - 1; way++) { if (!pd0[way]) continue; diff --git a/arch/arc/mm/tlbex.S b/arch/arc/mm/tlbex.S index cf7d7d9ad695..3fcfdb38d242 100644 --- a/arch/arc/mm/tlbex.S +++ b/arch/arc/mm/tlbex.S @@ -369,8 +369,8 @@ do_slow_path_pf: EXCEPTION_PROLOGUE ; ------- setup args for Linux Page fault Hanlder --------- - mov_s r0, sp - lr r1, [efa] + mov_s r1, sp + lr r0, [efa] ; We don't want exceptions to be disabled while the fault is handled. ; Now that we have saved the context we return from exception hence diff --git a/arch/arc/plat-tb10x/Kconfig b/arch/arc/plat-tb10x/Kconfig index 1ab386bb5da8..6994c188dc88 100644 --- a/arch/arc/plat-tb10x/Kconfig +++ b/arch/arc/plat-tb10x/Kconfig @@ -20,8 +20,10 @@ menuconfig ARC_PLAT_TB10X bool "Abilis TB10x" select COMMON_CLK select PINCTRL + select PINCTRL_TB10X select PINMUX select ARCH_REQUIRE_GPIOLIB + select GPIO_TB10X select TB10X_IRQC help Support for platforms based on the TB10x home media gateway SOC by diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 1ad6fb6c094d..214b698cefea 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -5,6 +5,8 @@ config ARM select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST select ARCH_HAVE_CUSTOM_GPIO_H + select ARCH_MIGHT_HAVE_PC_PARPORT + select ARCH_USE_CMPXCHG_LOCKREF select ARCH_WANT_IPC_PARSE_VERSION select BUILDTIME_EXTABLE_SORT if MMU select CLONE_BACKWARDS @@ -51,9 +53,12 @@ config ARM select HAVE_MOD_ARCH_SPECIFIC if ARM_UNWIND select HAVE_OPROFILE if (HAVE_PERF_EVENTS) select HAVE_PERF_EVENTS + select HAVE_PERF_REGS + select HAVE_PERF_USER_STACK_DUMP select HAVE_REGS_AND_STACK_ACCESS_API select HAVE_SYSCALL_TRACEPOINTS select HAVE_UID16 + select HAVE_VIRT_CPU_ACCOUNTING_GEN select IRQ_FORCED_THREADING select KTIME_SCALAR select MODULES_USE_ELF_REL @@ -317,6 +322,7 @@ config ARCH_INTEGRATOR select NEED_MACH_MEMORY_H select PLAT_VERSATILE select SPARSE_IRQ + select USE_OF select VERSATILE_FPGA_IRQ help Support for ARM's Integrator platform. @@ -358,7 +364,6 @@ config ARCH_AT91 bool "Atmel AT91" select ARCH_REQUIRE_GPIOLIB select CLKDEV_LOOKUP - select HAVE_CLK select IRQ_DOMAIN select NEED_MACH_GPIO_H select NEED_MACH_IO_H if PCCARD @@ -372,7 +377,6 @@ config ARCH_CLPS711X bool "Cirrus Logic CLPS711x/EP721x/EP731x-based" select ARCH_REQUIRE_GPIOLIB select AUTO_ZRELADDR - select CLKDEV_LOOKUP select CLKSRC_MMIO select COMMON_CLK select CPU_ARM720T @@ -386,9 +390,9 @@ config ARCH_CLPS711X config ARCH_GEMINI bool "Cortina Systems Gemini" select ARCH_REQUIRE_GPIOLIB - select ARCH_USES_GETTIMEOFFSET + select CLKSRC_MMIO select CPU_FA526 - select NEED_MACH_GPIO_H + select GENERIC_CLOCKEVENTS help Support for the Cortina Systems Gemini family SoCs @@ -457,7 +461,7 @@ config ARCH_IOP32X depends on MMU select ARCH_REQUIRE_GPIOLIB select CPU_XSCALE - select NEED_MACH_GPIO_H + select GPIO_IOP select NEED_RET_TO_USER select PCI select PLAT_IOP @@ -470,7 +474,7 @@ config ARCH_IOP33X depends on MMU select ARCH_REQUIRE_GPIOLIB select CPU_XSCALE - select NEED_MACH_GPIO_H + select GPIO_IOP select NEED_RET_TO_USER select PCI select PLAT_IOP @@ -481,6 +485,7 @@ config ARCH_IXP4XX bool "IXP4xx-based" depends on MMU select ARCH_HAS_DMA_SET_COHERENT_MASK + select ARCH_SUPPORTS_BIG_ENDIAN select ARCH_REQUIRE_GPIOLIB select CLKSRC_MMIO select CPU_XSCALE @@ -559,7 +564,6 @@ config ARCH_MMP select GPIO_PXA select IRQ_DOMAIN select MULTI_IRQ_HANDLER - select NEED_MACH_GPIO_H select PINCTRL select PLAT_PXA select SPARSE_IRQ @@ -622,7 +626,6 @@ config ARCH_PXA select GPIO_PXA select HAVE_IDE select MULTI_IRQ_HANDLER - select NEED_MACH_GPIO_H select PLAT_PXA select SPARSE_IRQ help @@ -631,7 +634,6 @@ config ARCH_PXA config ARCH_MSM bool "Qualcomm MSM" select ARCH_REQUIRE_GPIOLIB - select CLKDEV_LOOKUP select CLKSRC_OF if OF select COMMON_CLK select GENERIC_CLOCKEVENTS @@ -649,7 +651,6 @@ config ARCH_SHMOBILE select GENERIC_CLOCKEVENTS select HAVE_ARM_SCU if SMP select HAVE_ARM_TWD if SMP - select HAVE_CLK select HAVE_MACH_CLKDEV select HAVE_SMP select MIGHT_HAVE_CACHE_L2X0 @@ -692,7 +693,6 @@ config ARCH_SA1100 select GENERIC_CLOCKEVENTS select HAVE_IDE select ISA - select NEED_MACH_GPIO_H select NEED_MACH_MEMORY_H select SPARSE_IRQ help @@ -706,7 +706,6 @@ config ARCH_S3C24XX select CLKSRC_SAMSUNG_PWM select GENERIC_CLOCKEVENTS select GPIO_SAMSUNG - select HAVE_CLK select HAVE_S3C2410_I2C if I2C select HAVE_S3C2410_WATCHDOG if WATCHDOG select HAVE_S3C_RTC if RTC_CLASS @@ -727,21 +726,22 @@ config ARCH_S3C64XX select ARM_VIC select CLKDEV_LOOKUP select CLKSRC_SAMSUNG_PWM + select COMMON_CLK select CPU_V6 select GENERIC_CLOCKEVENTS select GPIO_SAMSUNG - select HAVE_CLK select HAVE_S3C2410_I2C if I2C select HAVE_S3C2410_WATCHDOG if WATCHDOG select HAVE_TCM select NEED_MACH_GPIO_H select NO_IOPORT select PLAT_SAMSUNG + select PM_GENERIC_DOMAINS select S3C_DEV_NAND select S3C_GPIO_TRACK select SAMSUNG_ATAGS - select SAMSUNG_CLKSRC select SAMSUNG_GPIOLIB_4BIT + select SAMSUNG_WAKEMASK select SAMSUNG_WDT_RESET select USB_ARCH_HAS_OHCI help @@ -754,7 +754,6 @@ config ARCH_S5P64X0 select CPU_V6 select GENERIC_CLOCKEVENTS select GPIO_SAMSUNG - select HAVE_CLK select HAVE_S3C2410_I2C if I2C select HAVE_S3C2410_WATCHDOG if WATCHDOG select HAVE_S3C_RTC if RTC_CLASS @@ -773,7 +772,6 @@ config ARCH_S5PC100 select CPU_V7 select GENERIC_CLOCKEVENTS select GPIO_SAMSUNG - select HAVE_CLK select HAVE_S3C2410_I2C if I2C select HAVE_S3C2410_WATCHDOG if WATCHDOG select HAVE_S3C_RTC if RTC_CLASS @@ -793,7 +791,6 @@ config ARCH_S5PV210 select CPU_V7 select GENERIC_CLOCKEVENTS select GPIO_SAMSUNG - select HAVE_CLK select HAVE_S3C2410_I2C if I2C select HAVE_S3C2410_WATCHDOG if WATCHDOG select HAVE_S3C_RTC if RTC_CLASS @@ -810,11 +807,9 @@ config ARCH_EXYNOS select ARCH_REQUIRE_GPIOLIB select ARCH_SPARSEMEM_ENABLE select ARM_GIC - select CLKDEV_LOOKUP select COMMON_CLK select CPU_V7 select GENERIC_CLOCKEVENTS - select HAVE_CLK select HAVE_S3C2410_I2C if I2C select HAVE_S3C2410_WATCHDOG if WATCHDOG select HAVE_S3C_RTC if RTC_CLASS @@ -824,20 +819,6 @@ config ARCH_EXYNOS help Support for SAMSUNG's EXYNOS SoCs (EXYNOS4/5) -config ARCH_SHARK - bool "Shark" - select ARCH_USES_GETTIMEOFFSET - select CPU_SA110 - select ISA - select ISA_DMA - select NEED_MACH_MEMORY_H - select PCI - select VIRT_TO_BUS - select ZONE_DMA - help - Support for the StrongARM based Digital DNARD machine, also known - as "Shark" (<http://www.shark-linux.de/shark.html>). - config ARCH_DAVINCI bool "TI DaVinci" select ARCH_HAS_HOLES_MEMORYMODEL @@ -847,7 +828,6 @@ config ARCH_DAVINCI select GENERIC_CLOCKEVENTS select GENERIC_IRQ_CHIP select HAVE_IDE - select NEED_MACH_GPIO_H select TI_PRIV_EDMA select USE_OF select ZONE_DMA @@ -865,7 +845,6 @@ config ARCH_OMAP1 select CLKSRC_MMIO select GENERIC_CLOCKEVENTS select GENERIC_IRQ_CHIP - select HAVE_CLK select HAVE_IDE select IRQ_DOMAIN select NEED_MACH_IO_H if PCCARD @@ -1009,9 +988,7 @@ source "arch/arm/mach-sti/Kconfig" source "arch/arm/mach-s3c24xx/Kconfig" -if ARCH_S3C64XX source "arch/arm/mach-s3c64xx/Kconfig" -endif source "arch/arm/mach-s5p64x0/Kconfig" @@ -1091,11 +1068,6 @@ config IWMMXT Enable support for iWMMXt context switching at run time if running on a CPU that supports it. -config XSCALE_PMU - bool - depends on CPU_XSCALE - default y - config MULTI_IRQ_HANDLER bool help @@ -1431,12 +1403,6 @@ config PCI_NANOENGINE config PCI_SYSCALL def_bool PCI -# Select the host bridge type -config PCI_HOST_VIA82C505 - bool - depends on PCI && ARCH_SHARK - default y - config PCI_HOST_ITE8152 bool depends on PCI && MACH_ARMCORE @@ -1467,7 +1433,6 @@ config SMP depends on GENERIC_CLOCKEVENTS depends on HAVE_SMP depends on MMU || ARM_MPU - select USE_GENERIC_SMP_HELPERS help This enables support for systems with more than one CPU. If you have a system with only one CPU, like most personal computers, say N. If @@ -1549,6 +1514,32 @@ config MCPM for (multi-)cluster based systems, such as big.LITTLE based systems. +config BIG_LITTLE + bool "big.LITTLE support (Experimental)" + depends on CPU_V7 && SMP + select MCPM + help + This option enables support selections for the big.LITTLE + system architecture. + +config BL_SWITCHER + bool "big.LITTLE switcher support" + depends on BIG_LITTLE && MCPM && HOTPLUG_CPU + select CPU_PM + select ARM_CPU_SUSPEND + help + The big.LITTLE "switcher" provides the core functionality to + transparently handle transition between a cluster of A15's + and a cluster of A7's in a big.LITTLE system. + +config BL_SWITCHER_DUMMY_IF + tristate "Simple big.LITTLE switcher user interface" + depends on BL_SWITCHER && DEBUG_KERNEL + help + This is a simple and dummy char dev interface to control + the big.LITTLE switcher core code. It is meant for + debugging purposes only. + choice prompt "Memory split" default VMSPLIT_3G @@ -1872,6 +1863,12 @@ config CC_STACKPROTECTOR neutralized via a kernel panic. This feature requires gcc version 4.2 or above. +config SWIOTLB + def_bool y + +config IOMMU_HELPER + def_bool SWIOTLB + config XEN_DOM0 def_bool y depends on XEN @@ -1882,6 +1879,7 @@ config XEN depends on CPU_V7 && !CPU_V6 depends on !GENERIC_ATOMIC64 select ARM_PSCI + select SWIOTLB_XEN help Say Y if you want to run Linux in a Virtual Machine on Xen on ARM. diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 9762c84b4198..5765abf5ce84 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -318,6 +318,7 @@ choice config DEBUG_MSM_UART1 bool "Kernel low-level debugging messages via MSM UART1" depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50 + select DEBUG_MSM_UART help Say Y here if you want the debug print routines to direct their output to the first serial port on MSM devices. @@ -325,6 +326,7 @@ choice config DEBUG_MSM_UART2 bool "Kernel low-level debugging messages via MSM UART2" depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50 + select DEBUG_MSM_UART help Say Y here if you want the debug print routines to direct their output to the second serial port on MSM devices. @@ -332,6 +334,7 @@ choice config DEBUG_MSM_UART3 bool "Kernel low-level debugging messages via MSM UART3" depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50 + select DEBUG_MSM_UART help Say Y here if you want the debug print routines to direct their output to the third serial port on MSM devices. @@ -340,6 +343,7 @@ choice bool "Kernel low-level debugging messages via MSM 8660 UART" depends on ARCH_MSM8X60 select MSM_HAS_DEBUG_UART_HS + select DEBUG_MSM_UART help Say Y here if you want the debug print routines to direct their output to the serial port on MSM 8660 devices. @@ -348,10 +352,20 @@ choice bool "Kernel low-level debugging messages via MSM 8960 UART" depends on ARCH_MSM8960 select MSM_HAS_DEBUG_UART_HS + select DEBUG_MSM_UART help Say Y here if you want the debug print routines to direct their output to the serial port on MSM 8960 devices. + config DEBUG_MSM8974_UART + bool "Kernel low-level debugging messages via MSM 8974 UART" + depends on ARCH_MSM8974 + select MSM_HAS_DEBUG_UART_HS + select DEBUG_MSM_UART + help + Say Y here if you want the debug print routines to direct + their output to the serial port on MSM 8974 devices. + config DEBUG_MVEBU_UART bool "Kernel low-level debugging messages via MVEBU UART (old bootloaders)" depends on ARCH_MVEBU @@ -386,6 +400,13 @@ choice when u-boot hands over to the kernel, the system silently crashes, with no serial output at all. + config DEBUG_VF_UART + bool "Vybrid UART" + depends on SOC_VF610 + help + Say Y here if you want kernel low-level debugging support + on Vybrid based platforms. + config DEBUG_NOMADIK_UART bool "Kernel low-level debugging messages via NOMADIK UART" depends on ARCH_NOMADIK @@ -834,6 +855,20 @@ choice options; the platform specific options are deprecated and will be soon removed. + config DEBUG_LL_UART_EFM32 + bool "Kernel low-level debugging via efm32 UART" + depends on ARCH_EFM32 + help + Say Y here if you want the debug print routines to direct + their output to an UART or USART port on efm32 based + machines. Use the following addresses for DEBUG_UART_PHYS: + + 0x4000c000 | USART0 + 0x4000c400 | USART1 + 0x4000c800 | USART2 + 0x4000e000 | UART0 + 0x4000e400 | UART1 + config DEBUG_LL_UART_PL01X bool "Kernel low-level debugging via ARM Ltd PL01x Primecell UART" help @@ -880,11 +915,16 @@ config DEBUG_STI_UART bool depends on ARCH_STI +config DEBUG_MSM_UART + bool + depends on ARCH_MSM + config DEBUG_LL_INCLUDE string default "debug/8250.S" if DEBUG_LL_UART_8250 || DEBUG_UART_8250 default "debug/pl01x.S" if DEBUG_LL_UART_PL01X || DEBUG_UART_PL01X default "debug/exynos.S" if DEBUG_EXYNOS_UART + default "debug/efm32.S" if DEBUG_LL_UART_EFM32 default "debug/icedcc.S" if DEBUG_ICEDCC default "debug/imx.S" if DEBUG_IMX1_UART || \ DEBUG_IMX25_UART || \ @@ -895,17 +935,14 @@ config DEBUG_LL_INCLUDE DEBUG_IMX53_UART ||\ DEBUG_IMX6Q_UART || \ DEBUG_IMX6SL_UART - default "debug/msm.S" if DEBUG_MSM_UART1 || \ - DEBUG_MSM_UART2 || \ - DEBUG_MSM_UART3 || \ - DEBUG_MSM8660_UART || \ - DEBUG_MSM8960_UART + default "debug/msm.S" if DEBUG_MSM_UART default "debug/omap2plus.S" if DEBUG_OMAP2PLUS_UART default "debug/sirf.S" if DEBUG_SIRFPRIMA2_UART1 || DEBUG_SIRFMARCO_UART1 default "debug/sti.S" if DEBUG_STI_UART default "debug/tegra.S" if DEBUG_TEGRA_UART default "debug/ux500.S" if DEBUG_UX500_UART default "debug/vexpress.S" if DEBUG_VEXPRESS_UART0_DETECT + default "debug/vf.S" if DEBUG_VF_UART default "debug/vt8500.S" if DEBUG_VT8500_UART0 default "debug/zynq.S" if DEBUG_ZYNQ_UART0 || DEBUG_ZYNQ_UART1 default "mach/debug-macro.S" @@ -951,6 +988,7 @@ config DEBUG_UART_PHYS default 0x20064000 if DEBUG_RK29_UART1 || DEBUG_RK3X_UART2 default 0x20068000 if DEBUG_RK29_UART2 || DEBUG_RK3X_UART3 default 0x20201000 if DEBUG_BCM2835 + default 0x4000e400 if DEBUG_LL_UART_EFM32 default 0x40090000 if ARCH_LPC32XX default 0x40100000 if DEBUG_PXA_UART1 default 0x42000000 if ARCH_GEMINI @@ -981,6 +1019,7 @@ config DEBUG_UART_PHYS default 0xfff36000 if DEBUG_HIGHBANK_UART default 0xfffff700 if ARCH_IOP33X depends on DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \ + DEBUG_LL_UART_EFM32 || \ DEBUG_UART_8250 || DEBUG_UART_PL01X config DEBUG_UART_VIRT diff --git a/arch/arm/Makefile b/arch/arm/Makefile index db50b626be98..c99b1086d83d 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -16,6 +16,7 @@ LDFLAGS := LDFLAGS_vmlinux :=-p --no-undefined -X ifeq ($(CONFIG_CPU_ENDIAN_BE8),y) LDFLAGS_vmlinux += --be8 +LDFLAGS_MODULE += --be8 endif OBJCOPYFLAGS :=-O binary -R .comment -S @@ -188,7 +189,6 @@ machine-$(CONFIG_ARCH_S5P64X0) += s5p64x0 machine-$(CONFIG_ARCH_S5PC100) += s5pc100 machine-$(CONFIG_ARCH_S5PV210) += s5pv210 machine-$(CONFIG_ARCH_SA1100) += sa1100 -machine-$(CONFIG_ARCH_SHARK) += shark machine-$(CONFIG_ARCH_SHMOBILE) += shmobile machine-$(CONFIG_ARCH_SHMOBILE_MULTI) += shmobile machine-$(CONFIG_ARCH_SIRF) += prima2 diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index 7ac1610252ba..e7190bb5998e 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile @@ -44,10 +44,6 @@ ifeq ($(CONFIG_ARCH_ACORN),y) OBJS += ll_char_wr.o font.o endif -ifeq ($(CONFIG_ARCH_SHARK),y) -OBJS += head-shark.o ofw-shark.o -endif - ifeq ($(CONFIG_ARCH_SA1100),y) OBJS += head-sa1100.o endif diff --git a/arch/arm/boot/compressed/head-shark.S b/arch/arm/boot/compressed/head-shark.S deleted file mode 100644 index 92b56897ed64..000000000000 --- a/arch/arm/boot/compressed/head-shark.S +++ /dev/null @@ -1,140 +0,0 @@ -/* The head-file for the Shark - * by Alexander Schulz - * - * Does the following: - * - get the memory layout from firmware. This can only be done as long as the mmu - * is still on. - * - switch the mmu off, so we have physical addresses - * - copy the kernel to 0x08508000. This is done to have a fixed address where the - * C-parts (misc.c) are executed. This address must be known at compile-time, - * but the load-address of the kernel depends on how much memory is installed. - * - Jump to this location. - * - Set r8 with 0, r7 with the architecture ID for head.S - */ - -#include <linux/linkage.h> - -#include <asm/assembler.h> - - .section ".start", "ax" - - .arch armv4 - b __beginning - -__ofw_data: .long 0 @ the number of memory blocks - .space 128 @ (startaddr,size) ... - .space 128 @ bootargs - .align - -__beginning: mov r4, r0 @ save the entry to the firmware - - mov r0, #0xC0 @ disable irq and fiq - mov r1, r0 - mrs r3, cpsr - bic r2, r3, r0 - eor r2, r2, r1 - msr cpsr_c, r2 - - mov r0, r4 @ get the Memory layout from firmware - adr r1, __ofw_data - add r2, r1, #4 - mov lr, pc - b ofw_init - mov r1, #0 - - adr r2, __mmu_off @ calculate physical address - sub r2, r2, #0xf0000000 @ openprom maps us at f000 virt, 0e50 phys - adr r0, __ofw_data - ldr r0, [r0, #4] - add r2, r2, r0 - add r2, r2, #0x00500000 - - mrc p15, 0, r3, c1, c0 - bic r3, r3, #0xC @ Write Buffer and DCache - bic r3, r3, #0x1000 @ ICache - mcr p15, 0, r3, c1, c0 @ disabled - - mov r0, #0 - mcr p15, 0, r0, c7, c7 @ flush I,D caches on v4 - mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 - mcr p15, 0, r0, c8, c7 @ flush I,D TLBs on v4 - - bic r3, r3, #0x1 @ MMU - mcr p15, 0, r3, c1, c0 @ disabled - - mov pc, r2 - -__copy_target: .long 0x08507FFC -__copy_end: .long 0x08607FFC - - .word _start - .word __bss_start - - .align -__temp_stack: .space 128 - -__mmu_off: - adr r0, __ofw_data @ read the 1. entry of the memory map - ldr r0, [r0, #4] - orr r0, r0, #0x00600000 - sub r0, r0, #4 - - ldr r1, __copy_end - ldr r3, __copy_target - -/* r0 = 0x0e600000 (current end of kernelcode) - * r3 = 0x08508000 (where it should begin) - * r1 = 0x08608000 (end of copying area, 1MB) - * The kernel is compressed, so 1 MB should be enough. - * copy the kernel to the beginning of physical memory - * We start from the highest address, so we can copy - * from 0x08500000 to 0x08508000 if we have only 8MB - */ - -/* As we get more 2.6-kernels it gets more and more - * uncomfortable to be bound to kernel images of 1MB only. - * So we add a loop here, to be able to copy some more. - * Alexander Schulz 2005-07-17 - */ - - mov r4, #3 @ How many megabytes to copy - - -__MoveCode: sub r4, r4, #1 - -__Copy: ldr r2, [r0], #-4 - str r2, [r1], #-4 - teq r1, r3 - bne __Copy - - /* The firmware maps us in blocks of 1 MB, the next block is - _below_ the last one. So our decrementing source pointer - ist right here, but the destination pointer must be increased - by 2 MB */ - add r1, r1, #0x00200000 - add r3, r3, #0x00100000 - - teq r4, #0 - bne __MoveCode - - - /* and jump to it */ - adr r2, __go_on @ where we want to jump - adr r0, __ofw_data @ read the 1. entry of the memory map - ldr r0, [r0, #4] - sub r2, r2, r0 @ we are mapped add 0e50 now, sub that (-0e00) - sub r2, r2, #0x00500000 @ -0050 - ldr r0, __copy_target @ and add 0850 8000 instead - add r0, r0, #4 - add r2, r2, r0 - mov pc, r2 @ and jump there - -__go_on: - adr sp, __temp_stack - add sp, sp, #128 - adr r0, __ofw_data - mov lr, pc - b create_params - - mov r8, #0 - mov r7, #15 diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 75189f13cf54..066b03480b63 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -135,6 +135,7 @@ start: .word _edata @ zImage end address THUMB( .thumb ) 1: + ARM_BE8( setend be ) @ go BE8 if compiled for BE8 mrs r9, cpsr #ifdef CONFIG_ARM_VIRT_EXT bl __hyp_stub_install @ get into SVC mode, reversibly @@ -699,9 +700,7 @@ __armv4_mmu_cache_on: mrc p15, 0, r0, c1, c0, 0 @ read control reg orr r0, r0, #0x5000 @ I-cache enable, RR cache replacement orr r0, r0, #0x0030 -#ifdef CONFIG_CPU_ENDIAN_BE8 - orr r0, r0, #1 << 25 @ big-endian page tables -#endif + ARM_BE8( orr r0, r0, #1 << 25 ) @ big-endian page tables bl __common_mmu_cache_on mov r0, #0 mcr p15, 0, r0, c8, c7, 0 @ flush I,D TLBs @@ -728,9 +727,7 @@ __armv7_mmu_cache_on: 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 -#endif + ARM_BE8( orr r0, r0, #1 << 25 ) @ big-endian page tables mrcne p15, 0, r6, c2, c0, 2 @ read ttb control reg orrne r0, r0, #1 @ MMU enabled movne r1, #0xfffffffd @ domain 0 = client diff --git a/arch/arm/boot/compressed/ofw-shark.c b/arch/arm/boot/compressed/ofw-shark.c deleted file mode 100644 index 465c54b6b128..000000000000 --- a/arch/arm/boot/compressed/ofw-shark.c +++ /dev/null @@ -1,260 +0,0 @@ -/* - * linux/arch/arm/boot/compressed/ofw-shark.c - * - * by Alexander Schulz - * - * This file is used to get some basic information - * about the memory layout of the shark we are running - * on. Memory is usually divided in blocks a 8 MB. - * And bootargs are copied from OpenFirmware. - */ - - -#include <linux/kernel.h> -#include <linux/types.h> -#include <asm/setup.h> -#include <asm/page.h> - - -asmlinkage void -create_params (unsigned long *buffer) -{ - /* Is there a better address? Also change in mach-shark/core.c */ - struct tag *tag = (struct tag *) 0x08003000; - int j,i,m,k,nr_banks,size; - unsigned char *c; - - k = 0; - - /* Head of the taglist */ - tag->hdr.tag = ATAG_CORE; - tag->hdr.size = tag_size(tag_core); - tag->u.core.flags = 1; - tag->u.core.pagesize = PAGE_SIZE; - tag->u.core.rootdev = 0; - - /* Build up one tagged block for each memory region */ - size=0; - nr_banks=(unsigned int) buffer[0]; - for (j=0;j<nr_banks;j++){ - /* search the lowest address and put it into the next entry */ - /* not a fast sort algorithm, but there are at most 8 entries */ - /* and this is used only once anyway */ - m=0xffffffff; - for (i=0;i<(unsigned int) buffer[0];i++){ - if (buffer[2*i+1]<m) { - m=buffer[2*i+1]; - k=i; - } - } - - tag = tag_next(tag); - tag->hdr.tag = ATAG_MEM; - tag->hdr.size = tag_size(tag_mem32); - tag->u.mem.size = buffer[2*k+2]; - tag->u.mem.start = buffer[2*k+1]; - - size += buffer[2*k+2]; - - buffer[2*k+1]=0xffffffff; /* mark as copied */ - } - - /* The command line */ - tag = tag_next(tag); - tag->hdr.tag = ATAG_CMDLINE; - - c=(unsigned char *)(&buffer[34]); - j=0; - while (*c) tag->u.cmdline.cmdline[j++]=*c++; - - tag->u.cmdline.cmdline[j]=0; - tag->hdr.size = (j + 7 + sizeof(struct tag_header)) >> 2; - - /* Hardware revision */ - tag = tag_next(tag); - tag->hdr.tag = ATAG_REVISION; - tag->hdr.size = tag_size(tag_revision); - tag->u.revision.rev = ((unsigned char) buffer[33])-'0'; - - /* End of the taglist */ - tag = tag_next(tag); - tag->hdr.tag = 0; - tag->hdr.size = 0; -} - - -typedef int (*ofw_handle_t)(void *); - -/* Everything below is called with a wrong MMU setting. - * This means: no string constants, no initialization of - * arrays, no global variables! This is ugly but I didn't - * want to write this in assembler :-) - */ - -int -of_decode_int(const unsigned char *p) -{ - unsigned int i = *p++ << 8; - i = (i + *p++) << 8; - i = (i + *p++) << 8; - return (i + *p); -} - -int -OF_finddevice(ofw_handle_t openfirmware, char *name) -{ - unsigned int args[8]; - char service[12]; - - service[0]='f'; - service[1]='i'; - service[2]='n'; - service[3]='d'; - service[4]='d'; - service[5]='e'; - service[6]='v'; - service[7]='i'; - service[8]='c'; - service[9]='e'; - service[10]='\0'; - - args[0]=(unsigned int)service; - args[1]=1; - args[2]=1; - args[3]=(unsigned int)name; - - if (openfirmware(args) == -1) - return -1; - return args[4]; -} - -int -OF_getproplen(ofw_handle_t openfirmware, int handle, char *prop) -{ - unsigned int args[8]; - char service[12]; - - service[0]='g'; - service[1]='e'; - service[2]='t'; - service[3]='p'; - service[4]='r'; - service[5]='o'; - service[6]='p'; - service[7]='l'; - service[8]='e'; - service[9]='n'; - service[10]='\0'; - - args[0] = (unsigned int)service; - args[1] = 2; - args[2] = 1; - args[3] = (unsigned int)handle; - args[4] = (unsigned int)prop; - - if (openfirmware(args) == -1) - return -1; - return args[5]; -} - -int -OF_getprop(ofw_handle_t openfirmware, int handle, char *prop, void *buf, unsigned int buflen) -{ - unsigned int args[8]; - char service[8]; - - service[0]='g'; - service[1]='e'; - service[2]='t'; - service[3]='p'; - service[4]='r'; - service[5]='o'; - service[6]='p'; - service[7]='\0'; - - args[0] = (unsigned int)service; - args[1] = 4; - args[2] = 1; - args[3] = (unsigned int)handle; - args[4] = (unsigned int)prop; - args[5] = (unsigned int)buf; - args[6] = buflen; - - if (openfirmware(args) == -1) - return -1; - return args[7]; -} - -asmlinkage void ofw_init(ofw_handle_t o, int *nomr, int *pointer) -{ - int phandle,i,mem_len,buffer[32]; - char temp[15]; - - temp[0]='/'; - temp[1]='m'; - temp[2]='e'; - temp[3]='m'; - temp[4]='o'; - temp[5]='r'; - temp[6]='y'; - temp[7]='\0'; - - phandle=OF_finddevice(o,temp); - - temp[0]='r'; - temp[1]='e'; - temp[2]='g'; - temp[3]='\0'; - - mem_len = OF_getproplen(o,phandle, temp); - OF_getprop(o,phandle, temp, buffer, mem_len); - *nomr=mem_len >> 3; - - for (i=0; i<=mem_len/4; i++) pointer[i]=of_decode_int((const unsigned char *)&buffer[i]); - - temp[0]='/'; - temp[1]='c'; - temp[2]='h'; - temp[3]='o'; - temp[4]='s'; - temp[5]='e'; - temp[6]='n'; - temp[7]='\0'; - - phandle=OF_finddevice(o,temp); - - temp[0]='b'; - temp[1]='o'; - temp[2]='o'; - temp[3]='t'; - temp[4]='a'; - temp[5]='r'; - temp[6]='g'; - temp[7]='s'; - temp[8]='\0'; - - mem_len = OF_getproplen(o,phandle, temp); - OF_getprop(o,phandle, temp, buffer, mem_len); - if (mem_len > 128) mem_len=128; - for (i=0; i<=mem_len/4; i++) pointer[i+33]=buffer[i]; - pointer[i+33]=0; - - temp[0]='/'; - temp[1]='\0'; - phandle=OF_finddevice(o,temp); - temp[0]='b'; - temp[1]='a'; - temp[2]='n'; - temp[3]='n'; - temp[4]='e'; - temp[5]='r'; - temp[6]='-'; - temp[7]='n'; - temp[8]='a'; - temp[9]='m'; - temp[10]='e'; - temp[11]='\0'; - mem_len = OF_getproplen(o,phandle, temp); - OF_getprop(o,phandle, temp, buffer, mem_len); - * ((unsigned char *) &pointer[32]) = ((unsigned char *) buffer)[mem_len-2]; -} diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index 802720e3e8fd..d57c1a65b24f 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -40,17 +40,17 @@ dtb-$(CONFIG_ARCH_AT91) += sama5d31ek.dtb dtb-$(CONFIG_ARCH_AT91) += sama5d33ek.dtb dtb-$(CONFIG_ARCH_AT91) += sama5d34ek.dtb dtb-$(CONFIG_ARCH_AT91) += sama5d35ek.dtb - dtb-$(CONFIG_ARCH_ATLAS6) += atlas6-evb.dtb - dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-b.dtb -dtb-$(CONFIG_ARCH_BCM) += bcm11351-brt.dtb \ +dtb-$(CONFIG_ARCH_BCM_MOBILE) += bcm11351-brt.dtb \ bcm28155-ap.dtb +dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-b.dtb dtb-$(CONFIG_ARCH_DAVINCI) += da850-enbw-cmc.dtb \ da850-evm.dtb dtb-$(CONFIG_ARCH_DOVE) += dove-cm-a510.dtb \ dove-cubox.dtb \ dove-d2plug.dtb \ + dove-d3plug.dtb \ dove-dove-db.dtb dtb-$(CONFIG_ARCH_EXYNOS) += exynos4210-origen.dtb \ exynos4210-smdkv310.dtb \ @@ -96,22 +96,25 @@ dtb-$(CONFIG_ARCH_KIRKWOOD) += kirkwood-cloudbox.dtb \ kirkwood-ns2mini.dtb \ kirkwood-nsa310.dtb \ kirkwood-nsa310a.dtb \ + kirkwood-openblocks_a6.dtb \ + kirkwood-openblocks_a7.dtb \ kirkwood-sheevaplug.dtb \ kirkwood-sheevaplug-esata.dtb \ kirkwood-topkick.dtb \ kirkwood-ts219-6281.dtb \ - kirkwood-ts219-6282.dtb \ - kirkwood-openblocks_a6.dtb + kirkwood-ts219-6282.dtb dtb-$(CONFIG_ARCH_MARCO) += marco-evb.dtb -dtb-$(CONFIG_ARCH_MSM) += msm8660-surf.dtb \ - msm8960-cdp.dtb +dtb-$(CONFIG_ARCH_MSM) += qcom-msm8660-surf.dtb \ + qcom-msm8960-cdp.dtb dtb-$(CONFIG_ARCH_MVEBU) += armada-370-db.dtb \ armada-370-mirabox.dtb \ armada-370-netgear-rn102.dtb \ + armada-370-netgear-rn104.dtb \ armada-370-rd.dtb \ armada-xp-axpwifiap.dtb \ armada-xp-db.dtb \ armada-xp-gp.dtb \ + armada-xp-matrix.dtb \ armada-xp-openblocks-ax3-4.dtb dtb-$(CONFIG_ARCH_MXC) += \ imx25-karo-tx25.dtb \ @@ -142,8 +145,10 @@ dtb-$(CONFIG_ARCH_MXC) += \ imx6q-sabrelite.dtb \ imx6q-sabresd.dtb \ imx6q-sbc6x.dtb \ + imx6q-udoo.dtb \ imx6q-wandboard.dtb \ imx6sl-evk.dtb \ + vf610-cosmic.dtb \ vf610-twr.dtb dtb-$(CONFIG_ARCH_MXS) += imx23-evk.dtb \ imx23-olinuxino.dtb \ @@ -159,6 +164,7 @@ dtb-$(CONFIG_ARCH_MXS) += imx23-evk.dtb \ imx28-cfa10057.dtb \ imx28-cfa10058.dtb \ imx28-evk.dtb \ + imx28-m28cu3.dtb \ imx28-m28evk.dtb \ imx28-sps1.dtb \ imx28-tx28.dtb @@ -172,9 +178,15 @@ dtb-$(CONFIG_ARCH_OMAP2PLUS) += omap2420-h4.dtb \ omap3-devkit8000.dtb \ omap3-beagle-xm.dtb \ omap3-evm.dtb \ + omap3-evm-37xx.dtb \ + omap3-n900.dtb \ + omap3-n9.dtb \ + omap3-n950.dtb \ omap3-tobi.dtb \ + omap3-gta04.dtb \ omap3-igep0020.dtb \ omap3-igep0030.dtb \ + omap3-zoom3.dtb \ omap4-panda.dtb \ omap4-panda-a4.dtb \ omap4-panda-es.dtb \ @@ -186,25 +198,33 @@ dtb-$(CONFIG_ARCH_OMAP2PLUS) += omap2420-h4.dtb \ am335x-evmsk.dtb \ am335x-bone.dtb \ am335x-boneblack.dtb \ + am335x-nano.dtb \ + am335x-base0033.dtb \ am3517-evm.dtb \ am3517_mt_ventoux.dtb \ - am43x-epos-evm.dtb + am43x-epos-evm.dtb \ + dra7-evm.dtb dtb-$(CONFIG_ARCH_ORION5X) += orion5x-lacie-ethernet-disk-mini-v2.dtb dtb-$(CONFIG_ARCH_PRIMA2) += prima2-evb.dtb dtb-$(CONFIG_ARCH_U8500) += ste-snowball.dtb \ - ste-hrefprev60.dtb \ - ste-hrefv60plus.dtb \ + ste-hrefprev60-stuib.dtb \ + ste-hrefprev60-tvk.dtb \ + ste-hrefv60plus-stuib.dtb \ + ste-hrefv60plus-tvk.dtb \ ste-ccu8540.dtb \ ste-ccu9540.dtb dtb-$(CONFIG_ARCH_S3C24XX) += s3c2416-smdk2416.dtb +dtb-$(CONFIG_ARCH_S3C64XX) += s3c6410-mini6410.dtb \ + s3c6410-smdk6410.dtb dtb-$(CONFIG_ARCH_SHMOBILE) += emev2-kzm9d.dtb \ - emev2-kzm9d-reference.dtb \ + r7s72100-genmai.dtb \ r8a7740-armadillo800eva.dtb \ r8a7778-bockw.dtb \ r8a7778-bockw-reference.dtb \ r8a7740-armadillo800eva-reference.dtb \ r8a7779-marzen.dtb \ r8a7779-marzen-reference.dtb \ + r8a7791-koelsch.dtb \ r8a7790-lager.dtb \ r8a7790-lager-reference.dtb \ sh73a0-kzm9g.dtb \ @@ -212,8 +232,10 @@ dtb-$(CONFIG_ARCH_SHMOBILE) += emev2-kzm9d.dtb \ r8a73a4-ape6evm.dtb \ r8a73a4-ape6evm-reference.dtb \ sh7372-mackerel.dtb -dtb-$(CONFIG_ARCH_SHMOBILE_MULTI) += emev2-kzm9d-reference.dtb -dtb-$(CONFIG_ARCH_SOCFPGA) += socfpga_cyclone5.dtb \ +dtb-$(CONFIG_ARCH_SHMOBILE_MULTI) += emev2-kzm9d.dtb +dtb-$(CONFIG_ARCH_SOCFPGA) += socfpga_arria5_socdk.dtb \ + socfpga_cyclone5_socdk.dtb \ + socfpga_cyclone5_sockit.dtb \ socfpga_vt.dtb dtb-$(CONFIG_ARCH_SPEAR13XX) += spear1310-evb.dtb \ spear1340-evb.dtb @@ -235,6 +257,7 @@ dtb-$(CONFIG_ARCH_SUNXI) += \ sun5i-a13-olinuxino.dtb \ sun6i-a31-colombus.dtb \ sun7i-a20-cubieboard2.dtb \ + sun7i-a20-cubietruck.dtb \ sun7i-a20-olinuxino-micro.dtb dtb-$(CONFIG_ARCH_TEGRA) += tegra20-harmony.dtb \ tegra20-iris-512.dtb \ @@ -249,7 +272,8 @@ dtb-$(CONFIG_ARCH_TEGRA) += tegra20-harmony.dtb \ tegra30-beaver.dtb \ tegra30-cardhu-a02.dtb \ tegra30-cardhu-a04.dtb \ - tegra114-dalmore.dtb + tegra114-dalmore.dtb \ + tegra124-venice2.dtb dtb-$(CONFIG_ARCH_VERSATILE) += versatile-ab.dtb \ versatile-pb.dtb dtb-$(CONFIG_ARCH_U300) += ste-u300.dtb diff --git a/arch/arm/boot/dts/am335x-base0033.dts b/arch/arm/boot/dts/am335x-base0033.dts new file mode 100644 index 000000000000..b4f95c2bbf74 --- /dev/null +++ b/arch/arm/boot/dts/am335x-base0033.dts @@ -0,0 +1,16 @@ +/* + * am335x-base0033.dts - Device Tree file for IGEP AQUILA EXPANSION + * + * Copyright (C) 2013 ISEE 2007 SL - http://www.isee.biz + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include "am335x-igep0033.dtsi" + +/ { + model = "IGEP COM AM335x on AQUILA Expansion"; + compatible = "isee,am335x-base0033", "isee,am335x-igep0033", "ti,am33xx"; +}; diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi index 2f66deda9f5c..e3f27ec31718 100644 --- a/arch/arm/boot/dts/am335x-bone-common.dtsi +++ b/arch/arm/boot/dts/am335x-bone-common.dtsi @@ -21,177 +21,205 @@ reg = <0x80000000 0x10000000>; /* 256 MB */ }; - am33xx_pinmux: pinmux@44e10800 { + leds { pinctrl-names = "default"; - pinctrl-0 = <&clkout2_pin>; - - user_leds_s0: user_leds_s0 { - pinctrl-single,pins = < - 0x54 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a5.gpio1_21 */ - 0x58 (PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpmc_a6.gpio1_22 */ - 0x5c (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a7.gpio1_23 */ - 0x60 (PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpmc_a8.gpio1_24 */ - >; - }; + pinctrl-0 = <&user_leds_s0>; - i2c0_pins: pinmux_i2c0_pins { - pinctrl-single,pins = < - 0x188 (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_sda.i2c0_sda */ - 0x18c (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_scl.i2c0_scl */ - >; - }; + compatible = "gpio-leds"; - uart0_pins: pinmux_uart0_pins { - pinctrl-single,pins = < - 0x170 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart0_rxd.uart0_rxd */ - 0x174 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */ - >; + led@2 { + label = "beaglebone:green:heartbeat"; + gpios = <&gpio1 21 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + default-state = "off"; }; - clkout2_pin: pinmux_clkout2_pin { - pinctrl-single,pins = < - 0x1b4 (PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr1.clkout2 */ - >; + led@3 { + label = "beaglebone:green:mmc0"; + gpios = <&gpio1 22 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "mmc0"; + default-state = "off"; }; - cpsw_default: cpsw_default { - pinctrl-single,pins = < - /* Slave 1 */ - 0x110 (PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxerr.mii1_rxerr */ - 0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txen.mii1_txen */ - 0x118 (PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxdv.mii1_rxdv */ - 0x11c (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txd3.mii1_txd3 */ - 0x120 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txd2.mii1_txd2 */ - 0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txd1.mii1_txd1 */ - 0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txd0.mii1_txd0 */ - 0x12c (PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_txclk.mii1_txclk */ - 0x130 (PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxclk.mii1_rxclk */ - 0x134 (PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxd3.mii1_rxd3 */ - 0x138 (PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxd2.mii1_rxd2 */ - 0x13c (PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxd1.mii1_rxd1 */ - 0x140 (PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxd0.mii1_rxd0 */ - >; + led@4 { + label = "beaglebone:green:usr2"; + gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "cpu0"; + default-state = "off"; }; - cpsw_sleep: cpsw_sleep { - pinctrl-single,pins = < - /* Slave 1 reset value */ - 0x110 (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x118 (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x11c (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x120 (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x12c (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x130 (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x134 (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x138 (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7) - >; + led@5 { + label = "beaglebone:green:usr3"; + gpios = <&gpio1 24 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "mmc1"; + default-state = "off"; }; + }; - davinci_mdio_default: davinci_mdio_default { - pinctrl-single,pins = < - /* MDIO */ - 0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* mdio_data.mdio_data */ - 0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0) /* mdio_clk.mdio_clk */ - >; - }; + vmmcsd_fixed: fixedregulator@0 { + compatible = "regulator-fixed"; + regulator-name = "vmmcsd_fixed"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; +}; - davinci_mdio_sleep: davinci_mdio_sleep { - pinctrl-single,pins = < - /* MDIO reset value */ - 0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7) - >; - }; +&am33xx_pinmux { + pinctrl-names = "default"; + pinctrl-0 = <&clkout2_pin>; + + user_leds_s0: user_leds_s0 { + pinctrl-single,pins = < + 0x54 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a5.gpio1_21 */ + 0x58 (PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpmc_a6.gpio1_22 */ + 0x5c (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a7.gpio1_23 */ + 0x60 (PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpmc_a8.gpio1_24 */ + >; }; - ocp { - uart0: serial@44e09000 { - pinctrl-names = "default"; - pinctrl-0 = <&uart0_pins>; + i2c0_pins: pinmux_i2c0_pins { + pinctrl-single,pins = < + 0x188 (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_sda.i2c0_sda */ + 0x18c (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_scl.i2c0_scl */ + >; + }; - status = "okay"; - }; + uart0_pins: pinmux_uart0_pins { + pinctrl-single,pins = < + 0x170 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart0_rxd.uart0_rxd */ + 0x174 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */ + >; + }; - musb: usb@47400000 { - status = "okay"; + clkout2_pin: pinmux_clkout2_pin { + pinctrl-single,pins = < + 0x1b4 (PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr1.clkout2 */ + >; + }; - control@44e10000 { - status = "okay"; - }; + cpsw_default: cpsw_default { + pinctrl-single,pins = < + /* Slave 1 */ + 0x110 (PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxerr.mii1_rxerr */ + 0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txen.mii1_txen */ + 0x118 (PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxdv.mii1_rxdv */ + 0x11c (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txd3.mii1_txd3 */ + 0x120 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txd2.mii1_txd2 */ + 0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txd1.mii1_txd1 */ + 0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txd0.mii1_txd0 */ + 0x12c (PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_txclk.mii1_txclk */ + 0x130 (PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxclk.mii1_rxclk */ + 0x134 (PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxd3.mii1_rxd3 */ + 0x138 (PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxd2.mii1_rxd2 */ + 0x13c (PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxd1.mii1_rxd1 */ + 0x140 (PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxd0.mii1_rxd0 */ + >; + }; - usb-phy@47401300 { - status = "okay"; - }; + cpsw_sleep: cpsw_sleep { + pinctrl-single,pins = < + /* Slave 1 reset value */ + 0x110 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x118 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x11c (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x120 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x12c (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x130 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x134 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x138 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7) + >; + }; - usb-phy@47401b00 { - status = "okay"; - }; + davinci_mdio_default: davinci_mdio_default { + pinctrl-single,pins = < + /* MDIO */ + 0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* mdio_data.mdio_data */ + 0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0) /* mdio_clk.mdio_clk */ + >; + }; - usb@47401000 { - status = "okay"; - }; + davinci_mdio_sleep: davinci_mdio_sleep { + pinctrl-single,pins = < + /* MDIO reset value */ + 0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7) + >; + }; - usb@47401800 { - status = "okay"; - dr_mode = "host"; - }; + mmc1_pins: pinmux_mmc1_pins { + pinctrl-single,pins = < + 0x160 (PIN_INPUT | MUX_MODE7) /* GPIO0_6 */ + >; + }; - dma-controller@07402000 { - status = "okay"; - }; - }; + emmc_pins: pinmux_emmc_pins { + pinctrl-single,pins = < + 0x80 (PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn1.mmc1_clk */ + 0x84 (PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn2.mmc1_cmd */ + 0x00 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad0.mmc1_dat0 */ + 0x04 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad1.mmc1_dat1 */ + 0x08 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad2.mmc1_dat2 */ + 0x0c (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad3.mmc1_dat3 */ + 0x10 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad4.mmc1_dat4 */ + 0x14 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad5.mmc1_dat5 */ + 0x18 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad6.mmc1_dat6 */ + 0x1c (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad7.mmc1_dat7 */ + >; + }; +}; - i2c0: i2c@44e0b000 { - pinctrl-names = "default"; - pinctrl-0 = <&i2c0_pins>; +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins>; - status = "okay"; - clock-frequency = <400000>; + status = "okay"; +}; - tps: tps@24 { - reg = <0x24>; - }; +&usb { + status = "okay"; - }; + control@44e10000 { + status = "okay"; }; - leds { - pinctrl-names = "default"; - pinctrl-0 = <&user_leds_s0>; + usb-phy@47401300 { + status = "okay"; + }; - compatible = "gpio-leds"; + usb-phy@47401b00 { + status = "okay"; + }; - led@2 { - label = "beaglebone:green:heartbeat"; - gpios = <&gpio1 21 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "heartbeat"; - default-state = "off"; - }; + usb@47401000 { + status = "okay"; + }; - led@3 { - label = "beaglebone:green:mmc0"; - gpios = <&gpio1 22 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "mmc0"; - default-state = "off"; - }; + usb@47401800 { + status = "okay"; + dr_mode = "host"; + }; - led@4 { - label = "beaglebone:green:usr2"; - gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>; - default-state = "off"; - }; + dma-controller@07402000 { + status = "okay"; + }; +}; - led@5 { - label = "beaglebone:green:usr3"; - gpios = <&gpio1 24 GPIO_ACTIVE_HIGH>; - default-state = "off"; - }; +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins>; + + status = "okay"; + clock-frequency = <400000>; + + tps: tps@24 { + reg = <0x24>; }; + }; /include/ "tps65217.dtsi" @@ -260,3 +288,12 @@ pinctrl-0 = <&davinci_mdio_default>; pinctrl-1 = <&davinci_mdio_sleep>; }; + +&mmc1 { + status = "okay"; + bus-width = <0x4>; + pinctrl-names = "default"; + pinctrl-0 = <&mmc1_pins>; + cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>; + cd-inverted; +}; diff --git a/arch/arm/boot/dts/am335x-bone.dts b/arch/arm/boot/dts/am335x-bone.dts index 7993c489982c..94ee427a6db1 100644 --- a/arch/arm/boot/dts/am335x-bone.dts +++ b/arch/arm/boot/dts/am335x-bone.dts @@ -9,3 +9,21 @@ #include "am33xx.dtsi" #include "am335x-bone-common.dtsi" + +&ldo3_reg { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; +}; + +&mmc1 { + vmmc-supply = <&ldo3_reg>; +}; + +&sham { + status = "okay"; +}; + +&aes { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/am335x-boneblack.dts b/arch/arm/boot/dts/am335x-boneblack.dts index 197cadf72d2c..6b71ad95a5cf 100644 --- a/arch/arm/boot/dts/am335x-boneblack.dts +++ b/arch/arm/boot/dts/am335x-boneblack.dts @@ -15,3 +15,64 @@ regulator-max-microvolt = <1800000>; regulator-always-on; }; + +&mmc1 { + vmmc-supply = <&vmmcsd_fixed>; +}; + +&mmc2 { + vmmc-supply = <&vmmcsd_fixed>; + pinctrl-names = "default"; + pinctrl-0 = <&emmc_pins>; + bus-width = <8>; + status = "okay"; + ti,vcc-aux-disable-is-sleep; +}; + +&am33xx_pinmux { + nxp_hdmi_bonelt_pins: nxp_hdmi_bonelt_pins { + pinctrl-single,pins = < + 0x1b0 0x03 /* xdma_event_intr0, OMAP_MUX_MODE3 | AM33XX_PIN_OUTPUT */ + 0xa0 0x08 /* lcd_data0.lcd_data0, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ + 0xa4 0x08 /* lcd_data1.lcd_data1, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ + 0xa8 0x08 /* lcd_data2.lcd_data2, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ + 0xac 0x08 /* lcd_data3.lcd_data3, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ + 0xb0 0x08 /* lcd_data4.lcd_data4, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ + 0xb4 0x08 /* lcd_data5.lcd_data5, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ + 0xb8 0x08 /* lcd_data6.lcd_data6, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ + 0xbc 0x08 /* lcd_data7.lcd_data7, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ + 0xc0 0x08 /* lcd_data8.lcd_data8, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ + 0xc4 0x08 /* lcd_data9.lcd_data9, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ + 0xc8 0x08 /* lcd_data10.lcd_data10, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ + 0xcc 0x08 /* lcd_data11.lcd_data11, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ + 0xd0 0x08 /* lcd_data12.lcd_data12, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ + 0xd4 0x08 /* lcd_data13.lcd_data13, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ + 0xd8 0x08 /* lcd_data14.lcd_data14, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ + 0xdc 0x08 /* lcd_data15.lcd_data15, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ + 0xe0 0x00 /* lcd_vsync.lcd_vsync, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */ + 0xe4 0x00 /* lcd_hsync.lcd_hsync, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */ + 0xe8 0x00 /* lcd_pclk.lcd_pclk, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */ + 0xec 0x00 /* lcd_ac_bias_en.lcd_ac_bias_en, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */ + >; + }; + nxp_hdmi_bonelt_off_pins: nxp_hdmi_bonelt_off_pins { + pinctrl-single,pins = < + 0x1b0 0x03 /* xdma_event_intr0, OMAP_MUX_MODE3 | AM33XX_PIN_OUTPUT */ + >; + }; +}; + +&lcdc { + status = "okay"; +}; + +/ { + hdmi { + compatible = "ti,tilcdc,slave"; + i2c = <&i2c0>; + pinctrl-names = "default", "off"; + pinctrl-0 = <&nxp_hdmi_bonelt_pins>; + pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>; + status = "okay"; + }; +}; diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts index e8ec8756e498..7e6c64ed966d 100644 --- a/arch/arm/boot/dts/am335x-evm.dts +++ b/arch/arm/boot/dts/am335x-evm.dts @@ -24,324 +24,6 @@ reg = <0x80000000 0x10000000>; /* 256 MB */ }; - am33xx_pinmux: pinmux@44e10800 { - pinctrl-names = "default"; - pinctrl-0 = <&matrix_keypad_s0 &volume_keys_s0 &clkout2_pin>; - - matrix_keypad_s0: matrix_keypad_s0 { - pinctrl-single,pins = < - 0x54 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a5.gpio1_21 */ - 0x58 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a6.gpio1_22 */ - 0x64 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_a9.gpio1_25 */ - 0x68 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_a10.gpio1_26 */ - 0x6c (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_a11.gpio1_27 */ - >; - }; - - volume_keys_s0: volume_keys_s0 { - pinctrl-single,pins = < - 0x150 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* spi0_sclk.gpio0_2 */ - 0x154 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* spi0_d0.gpio0_3 */ - >; - }; - - i2c0_pins: pinmux_i2c0_pins { - pinctrl-single,pins = < - 0x188 (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_sda.i2c0_sda */ - 0x18c (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_scl.i2c0_scl */ - >; - }; - - i2c1_pins: pinmux_i2c1_pins { - pinctrl-single,pins = < - 0x158 (PIN_INPUT_PULLUP | MUX_MODE2) /* spi0_d1.i2c1_sda */ - 0x15c (PIN_INPUT_PULLUP | MUX_MODE2) /* spi0_cs0.i2c1_scl */ - >; - }; - - uart0_pins: pinmux_uart0_pins { - pinctrl-single,pins = < - 0x170 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart0_rxd.uart0_rxd */ - 0x174 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */ - >; - }; - - clkout2_pin: pinmux_clkout2_pin { - pinctrl-single,pins = < - 0x1b4 (PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr1.clkout2 */ - >; - }; - - nandflash_pins_s0: nandflash_pins_s0 { - pinctrl-single,pins = < - 0x0 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad0.gpmc_ad0 */ - 0x4 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad1.gpmc_ad1 */ - 0x8 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad2.gpmc_ad2 */ - 0xc (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad3.gpmc_ad3 */ - 0x10 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad4.gpmc_ad4 */ - 0x14 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad5.gpmc_ad5 */ - 0x18 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad6.gpmc_ad6 */ - 0x1c (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad7.gpmc_ad7 */ - 0x70 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_wait0.gpmc_wait0 */ - 0x74 (PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_wpn.gpio0_30 */ - 0x7c (PIN_OUTPUT | MUX_MODE0) /* gpmc_csn0.gpmc_csn0 */ - 0x90 (PIN_OUTPUT | MUX_MODE0) /* gpmc_advn_ale.gpmc_advn_ale */ - 0x94 (PIN_OUTPUT | MUX_MODE0) /* gpmc_oen_ren.gpmc_oen_ren */ - 0x98 (PIN_OUTPUT | MUX_MODE0) /* gpmc_wen.gpmc_wen */ - 0x9c (PIN_OUTPUT | MUX_MODE0) /* gpmc_be0n_cle.gpmc_be0n_cle */ - >; - }; - - ecap0_pins: backlight_pins { - pinctrl-single,pins = < - 0x164 0x0 /* eCAP0_in_PWM0_out.eCAP0_in_PWM0_out MODE0 */ - >; - }; - - cpsw_default: cpsw_default { - pinctrl-single,pins = < - /* Slave 1 */ - 0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txen.rgmii1_tctl */ - 0x118 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxdv.rgmii1_rctl */ - 0x11c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd3.rgmii1_td3 */ - 0x120 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd2.rgmii1_td2 */ - 0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd1.rgmii1_td1 */ - 0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd0.rgmii1_td0 */ - 0x12c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txclk.rgmii1_tclk */ - 0x130 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxclk.rgmii1_rclk */ - 0x134 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd3.rgmii1_rd3 */ - 0x138 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd2.rgmii1_rd2 */ - 0x13c (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd1.rgmii1_rd1 */ - 0x140 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd0.rgmii1_rd0 */ - >; - }; - - cpsw_sleep: cpsw_sleep { - pinctrl-single,pins = < - /* Slave 1 reset value */ - 0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x118 (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x11c (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x120 (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x12c (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x130 (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x134 (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x138 (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7) - >; - }; - - davinci_mdio_default: davinci_mdio_default { - pinctrl-single,pins = < - /* MDIO */ - 0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* mdio_data.mdio_data */ - 0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0) /* mdio_clk.mdio_clk */ - >; - }; - - davinci_mdio_sleep: davinci_mdio_sleep { - pinctrl-single,pins = < - /* MDIO reset value */ - 0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7) - >; - }; - }; - - ocp { - uart0: serial@44e09000 { - pinctrl-names = "default"; - pinctrl-0 = <&uart0_pins>; - - status = "okay"; - }; - - i2c0: i2c@44e0b000 { - pinctrl-names = "default"; - pinctrl-0 = <&i2c0_pins>; - - status = "okay"; - clock-frequency = <400000>; - - tps: tps@2d { - reg = <0x2d>; - }; - }; - - musb: usb@47400000 { - status = "okay"; - - control@44e10000 { - status = "okay"; - }; - - usb-phy@47401300 { - status = "okay"; - }; - - usb-phy@47401b00 { - status = "okay"; - }; - - usb@47401000 { - status = "okay"; - }; - - usb@47401800 { - status = "okay"; - dr_mode = "host"; - }; - - dma-controller@07402000 { - status = "okay"; - }; - }; - - i2c1: i2c@4802a000 { - pinctrl-names = "default"; - pinctrl-0 = <&i2c1_pins>; - - status = "okay"; - clock-frequency = <100000>; - - lis331dlh: lis331dlh@18 { - compatible = "st,lis331dlh", "st,lis3lv02d"; - reg = <0x18>; - Vdd-supply = <&lis3_reg>; - Vdd_IO-supply = <&lis3_reg>; - - st,click-single-x; - st,click-single-y; - st,click-single-z; - st,click-thresh-x = <10>; - st,click-thresh-y = <10>; - st,click-thresh-z = <10>; - st,irq1-click; - st,irq2-click; - st,wakeup-x-lo; - st,wakeup-x-hi; - st,wakeup-y-lo; - st,wakeup-y-hi; - st,wakeup-z-lo; - st,wakeup-z-hi; - st,min-limit-x = <120>; - st,min-limit-y = <120>; - st,min-limit-z = <140>; - st,max-limit-x = <550>; - st,max-limit-y = <550>; - st,max-limit-z = <750>; - }; - - tsl2550: tsl2550@39 { - compatible = "taos,tsl2550"; - reg = <0x39>; - }; - - tmp275: tmp275@48 { - compatible = "ti,tmp275"; - reg = <0x48>; - }; - }; - - elm: elm@48080000 { - status = "okay"; - }; - - epwmss0: epwmss@48300000 { - status = "okay"; - - ecap0: ecap@48300100 { - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&ecap0_pins>; - }; - }; - - gpmc: gpmc@50000000 { - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&nandflash_pins_s0>; - ranges = <0 0 0x08000000 0x10000000>; /* CS0: NAND */ - nand@0,0 { - reg = <0 0 0>; /* CS0, offset 0 */ - nand-bus-width = <8>; - ti,nand-ecc-opt = "bch8"; - gpmc,device-nand = "true"; - gpmc,device-width = <1>; - gpmc,sync-clk-ps = <0>; - gpmc,cs-on-ns = <0>; - gpmc,cs-rd-off-ns = <44>; - gpmc,cs-wr-off-ns = <44>; - gpmc,adv-on-ns = <6>; - gpmc,adv-rd-off-ns = <34>; - gpmc,adv-wr-off-ns = <44>; - gpmc,we-on-ns = <0>; - gpmc,we-off-ns = <40>; - gpmc,oe-on-ns = <0>; - gpmc,oe-off-ns = <54>; - gpmc,access-ns = <64>; - gpmc,rd-cycle-ns = <82>; - gpmc,wr-cycle-ns = <82>; - gpmc,wait-on-read = "true"; - gpmc,wait-on-write = "true"; - gpmc,bus-turnaround-ns = <0>; - gpmc,cycle2cycle-delay-ns = <0>; - gpmc,clk-activation-ns = <0>; - gpmc,wait-monitoring-ns = <0>; - gpmc,wr-access-ns = <40>; - gpmc,wr-data-mux-bus-ns = <0>; - - #address-cells = <1>; - #size-cells = <1>; - elm_id = <&elm>; - - /* MTD partition table */ - partition@0 { - label = "SPL1"; - reg = <0x00000000 0x000020000>; - }; - - partition@1 { - label = "SPL2"; - reg = <0x00020000 0x00020000>; - }; - - partition@2 { - label = "SPL3"; - reg = <0x00040000 0x00020000>; - }; - - partition@3 { - label = "SPL4"; - reg = <0x00060000 0x00020000>; - }; - - partition@4 { - label = "U-boot"; - reg = <0x00080000 0x001e0000>; - }; - - partition@5 { - label = "environment"; - reg = <0x00260000 0x00020000>; - }; - - partition@6 { - label = "Kernel"; - reg = <0x00280000 0x00500000>; - }; - - partition@7 { - label = "File-System"; - reg = <0x00780000 0x0F880000>; - }; - }; - }; - }; - vbat: fixedregulator@0 { compatible = "regulator-fixed"; regulator-name = "vbat"; @@ -403,10 +85,447 @@ brightness-levels = <0 51 53 56 62 75 101 152 255>; default-brightness-level = <8>; }; + + panel { + compatible = "ti,tilcdc,panel"; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&lcd_pins_s0>; + panel-info { + ac-bias = <255>; + ac-bias-intrpt = <0>; + dma-burst-sz = <16>; + bpp = <32>; + fdd = <0x80>; + sync-edge = <0>; + sync-ctrl = <1>; + raster-order = <0>; + fifo-th = <0>; + }; + + display-timings { + 800x480p62 { + clock-frequency = <30000000>; + hactive = <800>; + vactive = <480>; + hfront-porch = <39>; + hback-porch = <39>; + hsync-len = <47>; + vback-porch = <29>; + vfront-porch = <13>; + vsync-len = <2>; + hsync-active = <1>; + vsync-active = <1>; + }; + }; + }; + + sound { + compatible = "ti,da830-evm-audio"; + ti,model = "AM335x-EVM"; + ti,audio-codec = <&tlv320aic3106>; + ti,mcasp-controller = <&mcasp1>; + ti,codec-clock-rate = <12000000>; + ti,audio-routing = + "Headphone Jack", "HPLOUT", + "Headphone Jack", "HPROUT", + "LINE1L", "Line In", + "LINE1R", "Line In"; + }; +}; + +&am33xx_pinmux { + pinctrl-names = "default"; + pinctrl-0 = <&matrix_keypad_s0 &volume_keys_s0 &clkout2_pin>; + + matrix_keypad_s0: matrix_keypad_s0 { + pinctrl-single,pins = < + 0x54 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a5.gpio1_21 */ + 0x58 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a6.gpio1_22 */ + 0x64 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_a9.gpio1_25 */ + 0x68 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_a10.gpio1_26 */ + 0x6c (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_a11.gpio1_27 */ + >; + }; + + volume_keys_s0: volume_keys_s0 { + pinctrl-single,pins = < + 0x150 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* spi0_sclk.gpio0_2 */ + 0x154 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* spi0_d0.gpio0_3 */ + >; + }; + + i2c0_pins: pinmux_i2c0_pins { + pinctrl-single,pins = < + 0x188 (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_sda.i2c0_sda */ + 0x18c (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_scl.i2c0_scl */ + >; + }; + + i2c1_pins: pinmux_i2c1_pins { + pinctrl-single,pins = < + 0x158 (PIN_INPUT_PULLUP | MUX_MODE2) /* spi0_d1.i2c1_sda */ + 0x15c (PIN_INPUT_PULLUP | MUX_MODE2) /* spi0_cs0.i2c1_scl */ + >; + }; + + uart0_pins: pinmux_uart0_pins { + pinctrl-single,pins = < + 0x170 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart0_rxd.uart0_rxd */ + 0x174 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */ + >; + }; + + clkout2_pin: pinmux_clkout2_pin { + pinctrl-single,pins = < + 0x1b4 (PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr1.clkout2 */ + >; + }; + + nandflash_pins_s0: nandflash_pins_s0 { + pinctrl-single,pins = < + 0x0 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad0.gpmc_ad0 */ + 0x4 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad1.gpmc_ad1 */ + 0x8 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad2.gpmc_ad2 */ + 0xc (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad3.gpmc_ad3 */ + 0x10 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad4.gpmc_ad4 */ + 0x14 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad5.gpmc_ad5 */ + 0x18 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad6.gpmc_ad6 */ + 0x1c (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad7.gpmc_ad7 */ + 0x70 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_wait0.gpmc_wait0 */ + 0x74 (PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_wpn.gpio0_30 */ + 0x7c (PIN_OUTPUT | MUX_MODE0) /* gpmc_csn0.gpmc_csn0 */ + 0x90 (PIN_OUTPUT | MUX_MODE0) /* gpmc_advn_ale.gpmc_advn_ale */ + 0x94 (PIN_OUTPUT | MUX_MODE0) /* gpmc_oen_ren.gpmc_oen_ren */ + 0x98 (PIN_OUTPUT | MUX_MODE0) /* gpmc_wen.gpmc_wen */ + 0x9c (PIN_OUTPUT | MUX_MODE0) /* gpmc_be0n_cle.gpmc_be0n_cle */ + >; + }; + + ecap0_pins: backlight_pins { + pinctrl-single,pins = < + 0x164 0x0 /* eCAP0_in_PWM0_out.eCAP0_in_PWM0_out MODE0 */ + >; + }; + + cpsw_default: cpsw_default { + pinctrl-single,pins = < + /* Slave 1 */ + 0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txen.rgmii1_tctl */ + 0x118 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxdv.rgmii1_rctl */ + 0x11c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd3.rgmii1_td3 */ + 0x120 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd2.rgmii1_td2 */ + 0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd1.rgmii1_td1 */ + 0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd0.rgmii1_td0 */ + 0x12c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txclk.rgmii1_tclk */ + 0x130 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxclk.rgmii1_rclk */ + 0x134 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd3.rgmii1_rd3 */ + 0x138 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd2.rgmii1_rd2 */ + 0x13c (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd1.rgmii1_rd1 */ + 0x140 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd0.rgmii1_rd0 */ + >; + }; + + cpsw_sleep: cpsw_sleep { + pinctrl-single,pins = < + /* Slave 1 reset value */ + 0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x118 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x11c (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x120 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x12c (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x130 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x134 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x138 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7) + >; + }; + + davinci_mdio_default: davinci_mdio_default { + pinctrl-single,pins = < + /* MDIO */ + 0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* mdio_data.mdio_data */ + 0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0) /* mdio_clk.mdio_clk */ + >; + }; + + davinci_mdio_sleep: davinci_mdio_sleep { + pinctrl-single,pins = < + /* MDIO reset value */ + 0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7) + >; + }; + + lcd_pins_s0: lcd_pins_s0 { + pinctrl-single,pins = < + 0x20 0x01 /* gpmc_ad8.lcd_data16, OUTPUT | MODE1 */ + 0x24 0x01 /* gpmc_ad9.lcd_data17, OUTPUT | MODE1 */ + 0x28 0x01 /* gpmc_ad10.lcd_data18, OUTPUT | MODE1 */ + 0x2c 0x01 /* gpmc_ad11.lcd_data19, OUTPUT | MODE1 */ + 0x30 0x01 /* gpmc_ad12.lcd_data20, OUTPUT | MODE1 */ + 0x34 0x01 /* gpmc_ad13.lcd_data21, OUTPUT | MODE1 */ + 0x38 0x01 /* gpmc_ad14.lcd_data22, OUTPUT | MODE1 */ + 0x3c 0x01 /* gpmc_ad15.lcd_data23, OUTPUT | MODE1 */ + 0xa0 0x00 /* lcd_data0.lcd_data0, OUTPUT | MODE0 */ + 0xa4 0x00 /* lcd_data1.lcd_data1, OUTPUT | MODE0 */ + 0xa8 0x00 /* lcd_data2.lcd_data2, OUTPUT | MODE0 */ + 0xac 0x00 /* lcd_data3.lcd_data3, OUTPUT | MODE0 */ + 0xb0 0x00 /* lcd_data4.lcd_data4, OUTPUT | MODE0 */ + 0xb4 0x00 /* lcd_data5.lcd_data5, OUTPUT | MODE0 */ + 0xb8 0x00 /* lcd_data6.lcd_data6, OUTPUT | MODE0 */ + 0xbc 0x00 /* lcd_data7.lcd_data7, OUTPUT | MODE0 */ + 0xc0 0x00 /* lcd_data8.lcd_data8, OUTPUT | MODE0 */ + 0xc4 0x00 /* lcd_data9.lcd_data9, OUTPUT | MODE0 */ + 0xc8 0x00 /* lcd_data10.lcd_data10, OUTPUT | MODE0 */ + 0xcc 0x00 /* lcd_data11.lcd_data11, OUTPUT | MODE0 */ + 0xd0 0x00 /* lcd_data12.lcd_data12, OUTPUT | MODE0 */ + 0xd4 0x00 /* lcd_data13.lcd_data13, OUTPUT | MODE0 */ + 0xd8 0x00 /* lcd_data14.lcd_data14, OUTPUT | MODE0 */ + 0xdc 0x00 /* lcd_data15.lcd_data15, OUTPUT | MODE0 */ + 0xe0 0x00 /* lcd_vsync.lcd_vsync, OUTPUT | MODE0 */ + 0xe4 0x00 /* lcd_hsync.lcd_hsync, OUTPUT | MODE0 */ + 0xe8 0x00 /* lcd_pclk.lcd_pclk, OUTPUT | MODE0 */ + 0xec 0x00 /* lcd_ac_bias_en.lcd_ac_bias_en, OUTPUT | MODE0 */ + >; + }; + + am335x_evm_audio_pins: am335x_evm_audio_pins { + pinctrl-single,pins = < + 0x10c (PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_rx_dv.mcasp1_aclkx */ + 0x110 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_txd3.mcasp1_fsx */ + 0x108 (PIN_OUTPUT_PULLDOWN | MUX_MODE4) /* mii1_col.mcasp1_axr2 */ + 0x144 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* rmii1_ref_clk.mcasp1_axr3 */ + >; + }; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins>; + + status = "okay"; +}; + +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins>; + + status = "okay"; + clock-frequency = <400000>; + + tps: tps@2d { + reg = <0x2d>; + }; +}; + +&usb { + status = "okay"; + + control@44e10000 { + status = "okay"; + }; + + usb-phy@47401300 { + status = "okay"; + }; + + usb-phy@47401b00 { + status = "okay"; + }; + + usb@47401000 { + status = "okay"; + }; + + usb@47401800 { + status = "okay"; + dr_mode = "host"; + }; + + dma-controller@07402000 { + status = "okay"; + }; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; + + status = "okay"; + clock-frequency = <100000>; + + lis331dlh: lis331dlh@18 { + compatible = "st,lis331dlh", "st,lis3lv02d"; + reg = <0x18>; + Vdd-supply = <&lis3_reg>; + Vdd_IO-supply = <&lis3_reg>; + + st,click-single-x; + st,click-single-y; + st,click-single-z; + st,click-thresh-x = <10>; + st,click-thresh-y = <10>; + st,click-thresh-z = <10>; + st,irq1-click; + st,irq2-click; + st,wakeup-x-lo; + st,wakeup-x-hi; + st,wakeup-y-lo; + st,wakeup-y-hi; + st,wakeup-z-lo; + st,wakeup-z-hi; + st,min-limit-x = <120>; + st,min-limit-y = <120>; + st,min-limit-z = <140>; + st,max-limit-x = <550>; + st,max-limit-y = <550>; + st,max-limit-z = <750>; + }; + + tsl2550: tsl2550@39 { + compatible = "taos,tsl2550"; + reg = <0x39>; + }; + + tmp275: tmp275@48 { + compatible = "ti,tmp275"; + reg = <0x48>; + }; + + tlv320aic3106: tlv320aic3106@1b { + compatible = "ti,tlv320aic3106"; + reg = <0x1b>; + status = "okay"; + + /* Regulators */ + AVDD-supply = <&vaux2_reg>; + IOVDD-supply = <&vaux2_reg>; + DRVDD-supply = <&vaux2_reg>; + DVDD-supply = <&vbat>; + }; +}; + +&lcdc { + status = "okay"; +}; + +&elm { + status = "okay"; +}; + +&epwmss0 { + status = "okay"; + + ecap0: ecap@48300100 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&ecap0_pins>; + }; +}; + +&gpmc { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&nandflash_pins_s0>; + ranges = <0 0 0x08000000 0x10000000>; /* CS0: NAND */ + nand@0,0 { + reg = <0 0 0>; /* CS0, offset 0 */ + nand-bus-width = <8>; + ti,nand-ecc-opt = "bch8"; + gpmc,device-nand = "true"; + gpmc,device-width = <1>; + gpmc,sync-clk-ps = <0>; + gpmc,cs-on-ns = <0>; + gpmc,cs-rd-off-ns = <44>; + gpmc,cs-wr-off-ns = <44>; + gpmc,adv-on-ns = <6>; + gpmc,adv-rd-off-ns = <34>; + gpmc,adv-wr-off-ns = <44>; + gpmc,we-on-ns = <0>; + gpmc,we-off-ns = <40>; + gpmc,oe-on-ns = <0>; + gpmc,oe-off-ns = <54>; + gpmc,access-ns = <64>; + gpmc,rd-cycle-ns = <82>; + gpmc,wr-cycle-ns = <82>; + gpmc,wait-on-read = "true"; + gpmc,wait-on-write = "true"; + gpmc,bus-turnaround-ns = <0>; + gpmc,cycle2cycle-delay-ns = <0>; + gpmc,clk-activation-ns = <0>; + gpmc,wait-monitoring-ns = <0>; + gpmc,wr-access-ns = <40>; + gpmc,wr-data-mux-bus-ns = <0>; + + #address-cells = <1>; + #size-cells = <1>; + elm_id = <&elm>; + + /* MTD partition table */ + partition@0 { + label = "SPL1"; + reg = <0x00000000 0x000020000>; + }; + + partition@1 { + label = "SPL2"; + reg = <0x00020000 0x00020000>; + }; + + partition@2 { + label = "SPL3"; + reg = <0x00040000 0x00020000>; + }; + + partition@3 { + label = "SPL4"; + reg = <0x00060000 0x00020000>; + }; + + partition@4 { + label = "U-boot"; + reg = <0x00080000 0x001e0000>; + }; + + partition@5 { + label = "environment"; + reg = <0x00260000 0x00020000>; + }; + + partition@6 { + label = "Kernel"; + reg = <0x00280000 0x00500000>; + }; + + partition@7 { + label = "File-System"; + reg = <0x00780000 0x0F880000>; + }; + }; }; #include "tps65910.dtsi" +&mcasp1 { + pinctrl-names = "default"; + pinctrl-0 = <&am335x_evm_audio_pins>; + + status = "okay"; + + op-mode = <0>; /* MCASP_IIS_MODE */ + tdm-slots = <2>; + /* 4 serializers */ + serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */ + 0 0 1 2 + >; + tx-num-evt = <1>; + rx-num-evt = <1>; +}; + &tps { vcc1-supply = <&vbat>; vcc2-supply = <&vbat>; @@ -477,6 +596,8 @@ }; vmmc_reg: regulator@12 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; regulator-always-on; }; }; @@ -509,7 +630,7 @@ tsc { ti,wires = <4>; ti,x-plate-resistance = <200>; - ti,coordiante-readouts = <5>; + ti,coordinate-readouts = <5>; ti,wire-config = <0x00 0x11 0x22 0x33>; }; @@ -517,3 +638,17 @@ ti,adc-channels = <4 5 6 7>; }; }; + +&mmc1 { + status = "okay"; + vmmc-supply = <&vmmc_reg>; + bus-width = <4>; +}; + +&sham { + status = "okay"; +}; + +&aes { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/am335x-evmsk.dts b/arch/arm/boot/dts/am335x-evmsk.dts index 4f339fa91c57..4718ec4a4dbf 100644 --- a/arch/arm/boot/dts/am335x-evmsk.dts +++ b/arch/arm/boot/dts/am335x-evmsk.dts @@ -31,210 +31,6 @@ reg = <0x80000000 0x10000000>; /* 256 MB */ }; - am33xx_pinmux: pinmux@44e10800 { - pinctrl-names = "default"; - pinctrl-0 = <&gpio_keys_s0 &clkout2_pin>; - - user_leds_s0: user_leds_s0 { - pinctrl-single,pins = < - 0x10 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad4.gpio1_4 */ - 0x14 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad5.gpio1_5 */ - 0x18 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad6.gpio1_6 */ - 0x1c (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad7.gpio1_7 */ - >; - }; - - gpio_keys_s0: gpio_keys_s0 { - pinctrl-single,pins = < - 0x94 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_oen_ren.gpio2_3 */ - 0x90 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_advn_ale.gpio2_2 */ - 0x70 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_wait0.gpio0_30 */ - 0x9c (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ben0_cle.gpio2_5 */ - >; - }; - - i2c0_pins: pinmux_i2c0_pins { - pinctrl-single,pins = < - 0x188 (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_sda.i2c0_sda */ - 0x18c (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_scl.i2c0_scl */ - >; - }; - - uart0_pins: pinmux_uart0_pins { - pinctrl-single,pins = < - 0x170 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart0_rxd.uart0_rxd */ - 0x174 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */ - >; - }; - - clkout2_pin: pinmux_clkout2_pin { - pinctrl-single,pins = < - 0x1b4 (PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr1.clkout2 */ - >; - }; - - ecap2_pins: backlight_pins { - pinctrl-single,pins = < - 0x19c 0x4 /* mcasp0_ahclkr.ecap2_in_pwm2_out MODE4 */ - >; - }; - - cpsw_default: cpsw_default { - pinctrl-single,pins = < - /* Slave 1 */ - 0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txen.rgmii1_tctl */ - 0x118 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxdv.rgmii1_rctl */ - 0x11c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd3.rgmii1_td3 */ - 0x120 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd2.rgmii1_td2 */ - 0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd1.rgmii1_td1 */ - 0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd0.rgmii1_td0 */ - 0x12c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txclk.rgmii1_tclk */ - 0x130 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxclk.rgmii1_rclk */ - 0x134 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd3.rgmii1_rd3 */ - 0x138 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd2.rgmii1_rd2 */ - 0x13c (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd1.rgmii1_rd1 */ - 0x140 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd0.rgmii1_rd0 */ - - /* Slave 2 */ - 0x40 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a0.rgmii2_tctl */ - 0x44 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a1.rgmii2_rctl */ - 0x48 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a2.rgmii2_td3 */ - 0x4c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a3.rgmii2_td2 */ - 0x50 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a4.rgmii2_td1 */ - 0x54 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a5.rgmii2_td0 */ - 0x58 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a6.rgmii2_tclk */ - 0x5c (PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a7.rgmii2_rclk */ - 0x60 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a8.rgmii2_rd3 */ - 0x64 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a9.rgmii2_rd2 */ - 0x68 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a10.rgmii2_rd1 */ - 0x6c (PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a11.rgmii2_rd0 */ - >; - }; - - cpsw_sleep: cpsw_sleep { - pinctrl-single,pins = < - /* Slave 1 reset value */ - 0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x118 (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x11c (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x120 (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x12c (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x130 (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x134 (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x138 (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7) - - /* Slave 2 reset value*/ - 0x40 (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x44 (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x48 (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x4c (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x50 (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x54 (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x58 (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x5c (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x60 (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x64 (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x68 (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x6c (PIN_INPUT_PULLDOWN | MUX_MODE7) - >; - }; - - davinci_mdio_default: davinci_mdio_default { - pinctrl-single,pins = < - /* MDIO */ - 0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* mdio_data.mdio_data */ - 0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0) /* mdio_clk.mdio_clk */ - >; - }; - - davinci_mdio_sleep: davinci_mdio_sleep { - pinctrl-single,pins = < - /* MDIO reset value */ - 0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7) - 0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7) - >; - }; - }; - - ocp { - uart0: serial@44e09000 { - pinctrl-names = "default"; - pinctrl-0 = <&uart0_pins>; - - status = "okay"; - }; - - i2c0: i2c@44e0b000 { - pinctrl-names = "default"; - pinctrl-0 = <&i2c0_pins>; - - status = "okay"; - clock-frequency = <400000>; - - tps: tps@2d { - reg = <0x2d>; - }; - - lis331dlh: lis331dlh@18 { - compatible = "st,lis331dlh", "st,lis3lv02d"; - reg = <0x18>; - Vdd-supply = <&lis3_reg>; - Vdd_IO-supply = <&lis3_reg>; - - st,click-single-x; - st,click-single-y; - st,click-single-z; - st,click-thresh-x = <10>; - st,click-thresh-y = <10>; - st,click-thresh-z = <10>; - st,irq1-click; - st,irq2-click; - st,wakeup-x-lo; - st,wakeup-x-hi; - st,wakeup-y-lo; - st,wakeup-y-hi; - st,wakeup-z-lo; - st,wakeup-z-hi; - st,min-limit-x = <120>; - st,min-limit-y = <120>; - st,min-limit-z = <140>; - st,max-limit-x = <550>; - st,max-limit-y = <550>; - st,max-limit-z = <750>; - }; - }; - - musb: usb@47400000 { - status = "okay"; - - control@44e10000 { - status = "okay"; - }; - - usb-phy@47401300 { - status = "okay"; - }; - - usb@47401000 { - status = "okay"; - }; - }; - - epwmss2: epwmss@48304000 { - status = "okay"; - - ecap2: ecap@48304100 { - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&ecap2_pins>; - }; - }; - }; - vbat: fixedregulator@0 { compatible = "regulator-fixed"; regulator-name = "vbat"; @@ -319,6 +115,240 @@ brightness-levels = <0 58 61 66 75 90 125 170 255>; default-brightness-level = <8>; }; + + sound { + compatible = "ti,da830-evm-audio"; + ti,model = "AM335x-EVMSK"; + ti,audio-codec = <&tlv320aic3106>; + ti,mcasp-controller = <&mcasp1>; + ti,codec-clock-rate = <24576000>; + ti,audio-routing = + "Headphone Jack", "HPLOUT", + "Headphone Jack", "HPROUT"; + }; +}; + +&am33xx_pinmux { + pinctrl-names = "default"; + pinctrl-0 = <&gpio_keys_s0 &clkout2_pin>; + + user_leds_s0: user_leds_s0 { + pinctrl-single,pins = < + 0x10 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad4.gpio1_4 */ + 0x14 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad5.gpio1_5 */ + 0x18 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad6.gpio1_6 */ + 0x1c (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad7.gpio1_7 */ + >; + }; + + gpio_keys_s0: gpio_keys_s0 { + pinctrl-single,pins = < + 0x94 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_oen_ren.gpio2_3 */ + 0x90 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_advn_ale.gpio2_2 */ + 0x70 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_wait0.gpio0_30 */ + 0x9c (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ben0_cle.gpio2_5 */ + >; + }; + + i2c0_pins: pinmux_i2c0_pins { + pinctrl-single,pins = < + 0x188 (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_sda.i2c0_sda */ + 0x18c (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_scl.i2c0_scl */ + >; + }; + + uart0_pins: pinmux_uart0_pins { + pinctrl-single,pins = < + 0x170 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart0_rxd.uart0_rxd */ + 0x174 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */ + >; + }; + + clkout2_pin: pinmux_clkout2_pin { + pinctrl-single,pins = < + 0x1b4 (PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr1.clkout2 */ + >; + }; + + ecap2_pins: backlight_pins { + pinctrl-single,pins = < + 0x19c 0x4 /* mcasp0_ahclkr.ecap2_in_pwm2_out MODE4 */ + >; + }; + + cpsw_default: cpsw_default { + pinctrl-single,pins = < + /* Slave 1 */ + 0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txen.rgmii1_tctl */ + 0x118 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxdv.rgmii1_rctl */ + 0x11c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd3.rgmii1_td3 */ + 0x120 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd2.rgmii1_td2 */ + 0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd1.rgmii1_td1 */ + 0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd0.rgmii1_td0 */ + 0x12c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txclk.rgmii1_tclk */ + 0x130 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxclk.rgmii1_rclk */ + 0x134 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd3.rgmii1_rd3 */ + 0x138 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd2.rgmii1_rd2 */ + 0x13c (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd1.rgmii1_rd1 */ + 0x140 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd0.rgmii1_rd0 */ + + /* Slave 2 */ + 0x40 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a0.rgmii2_tctl */ + 0x44 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a1.rgmii2_rctl */ + 0x48 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a2.rgmii2_td3 */ + 0x4c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a3.rgmii2_td2 */ + 0x50 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a4.rgmii2_td1 */ + 0x54 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a5.rgmii2_td0 */ + 0x58 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a6.rgmii2_tclk */ + 0x5c (PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a7.rgmii2_rclk */ + 0x60 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a8.rgmii2_rd3 */ + 0x64 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a9.rgmii2_rd2 */ + 0x68 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a10.rgmii2_rd1 */ + 0x6c (PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a11.rgmii2_rd0 */ + >; + }; + + cpsw_sleep: cpsw_sleep { + pinctrl-single,pins = < + /* Slave 1 reset value */ + 0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x118 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x11c (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x120 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x12c (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x130 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x134 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x138 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7) + + /* Slave 2 reset value*/ + 0x40 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x44 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x48 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x4c (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x50 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x54 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x58 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x5c (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x60 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x64 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x68 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x6c (PIN_INPUT_PULLDOWN | MUX_MODE7) + >; + }; + + davinci_mdio_default: davinci_mdio_default { + pinctrl-single,pins = < + /* MDIO */ + 0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* mdio_data.mdio_data */ + 0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0) /* mdio_clk.mdio_clk */ + >; + }; + + davinci_mdio_sleep: davinci_mdio_sleep { + pinctrl-single,pins = < + /* MDIO reset value */ + 0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7) + >; + }; + + mcasp1_pins: mcasp1_pins { + pinctrl-single,pins = < + 0x10c (PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_crs.mcasp1_aclkx */ + 0x110 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_rxerr.mcasp1_fsx */ + 0x108 (PIN_OUTPUT_PULLDOWN | MUX_MODE4) /* mii1_col.mcasp1_axr2 */ + 0x144 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* rmii1_ref_clk.mcasp1_axr3 */ + >; + }; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins>; + + status = "okay"; +}; + +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins>; + + status = "okay"; + clock-frequency = <400000>; + + tps: tps@2d { + reg = <0x2d>; + }; + + lis331dlh: lis331dlh@18 { + compatible = "st,lis331dlh", "st,lis3lv02d"; + reg = <0x18>; + Vdd-supply = <&lis3_reg>; + Vdd_IO-supply = <&lis3_reg>; + + st,click-single-x; + st,click-single-y; + st,click-single-z; + st,click-thresh-x = <10>; + st,click-thresh-y = <10>; + st,click-thresh-z = <10>; + st,irq1-click; + st,irq2-click; + st,wakeup-x-lo; + st,wakeup-x-hi; + st,wakeup-y-lo; + st,wakeup-y-hi; + st,wakeup-z-lo; + st,wakeup-z-hi; + st,min-limit-x = <120>; + st,min-limit-y = <120>; + st,min-limit-z = <140>; + st,max-limit-x = <550>; + st,max-limit-y = <550>; + st,max-limit-z = <750>; + }; + + tlv320aic3106: tlv320aic3106@1b { + compatible = "ti,tlv320aic3106"; + reg = <0x1b>; + status = "okay"; + + /* Regulators */ + AVDD-supply = <&vaux2_reg>; + IOVDD-supply = <&vaux2_reg>; + DRVDD-supply = <&vaux2_reg>; + DVDD-supply = <&vbat>; + }; +}; + +&usb { + status = "okay"; + + control@44e10000 { + status = "okay"; + }; + + usb-phy@47401300 { + status = "okay"; + }; + + usb@47401000 { + status = "okay"; + }; +}; + +&epwmss2 { + status = "okay"; + + ecap2: ecap@48304100 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&ecap2_pins>; + }; }; #include "tps65910.dtsi" @@ -393,6 +423,8 @@ }; vmmc_reg: regulator@12 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; regulator-always-on; }; }; @@ -419,3 +451,47 @@ phy_id = <&davinci_mdio>, <1>; phy-mode = "rgmii-txid"; }; + +&mmc1 { + status = "okay"; + vmmc-supply = <&vmmc_reg>; + bus-width = <4>; +}; + +&sham { + status = "okay"; +}; + +&aes { + status = "okay"; +}; + +&gpio0 { + ti,no-reset-on-init; +}; + +&mcasp1 { + pinctrl-names = "default"; + pinctrl-0 = <&mcasp1_pins>; + + status = "okay"; + + op-mode = <0>; /* MCASP_IIS_MODE */ + tdm-slots = <2>; + /* 4 serializers */ + serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */ + 0 0 1 2 + >; + tx-num-evt = <1>; + rx-num-evt = <1>; +}; + +&tscadc { + status = "okay"; + tsc { + ti,wires = <4>; + ti,x-plate-resistance = <200>; + ti,coordinate-readouts = <5>; + ti,wire-config = <0x00 0x11 0x22 0x33>; + }; +}; diff --git a/arch/arm/boot/dts/am335x-igep0033.dtsi b/arch/arm/boot/dts/am335x-igep0033.dtsi new file mode 100644 index 000000000000..619624479311 --- /dev/null +++ b/arch/arm/boot/dts/am335x-igep0033.dtsi @@ -0,0 +1,278 @@ +/* + * am335x-igep0033.dtsi - Device Tree file for IGEP COM AQUILA AM335x + * + * Copyright (C) 2013 ISEE 2007 SL - http://www.isee.biz + * + * 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. + */ + +/dts-v1/; + +#include "am33xx.dtsi" + +/ { + cpus { + cpu@0 { + cpu0-supply = <&vdd1_reg>; + }; + }; + + memory { + device_type = "memory"; + reg = <0x80000000 0x10000000>; /* 256 MB */ + }; + + leds { + pinctrl-names = "default"; + pinctrl-0 = <&leds_pins>; + + compatible = "gpio-leds"; + + led@0 { + label = "com:green:user"; + gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + }; + + vbat: fixedregulator@0 { + compatible = "regulator-fixed"; + regulator-name = "vbat"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-boot-on; + }; + + vmmc: fixedregulator@0 { + compatible = "regulator-fixed"; + regulator-name = "vmmc"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; +}; + +&am33xx_pinmux { + i2c0_pins: pinmux_i2c0_pins { + pinctrl-single,pins = < + 0x188 (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_sda.i2c0_sda */ + 0x18c (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_scl.i2c0_scl */ + >; + }; + + nandflash_pins: pinmux_nandflash_pins { + pinctrl-single,pins = < + 0x0 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad0.gpmc_ad0 */ + 0x4 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad1.gpmc_ad1 */ + 0x8 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad2.gpmc_ad2 */ + 0xc (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad3.gpmc_ad3 */ + 0x10 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad4.gpmc_ad4 */ + 0x14 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad5.gpmc_ad5 */ + 0x18 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad6.gpmc_ad6 */ + 0x1c (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad7.gpmc_ad7 */ + 0x70 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_wait0.gpmc_wait0 */ + 0x74 (PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_wpn.gpio0_30 */ + 0x7c (PIN_OUTPUT | MUX_MODE0) /* gpmc_csn0.gpmc_csn0 */ + 0x90 (PIN_OUTPUT | MUX_MODE0) /* gpmc_advn_ale.gpmc_advn_ale */ + 0x94 (PIN_OUTPUT | MUX_MODE0) /* gpmc_oen_ren.gpmc_oen_ren */ + 0x98 (PIN_OUTPUT | MUX_MODE0) /* gpmc_wen.gpmc_wen */ + 0x9c (PIN_OUTPUT | MUX_MODE0) /* gpmc_be0n_cle.gpmc_be0n_cle */ + >; + }; + + uart0_pins: pinmux_uart0_pins { + pinctrl-single,pins = < + 0x170 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart0_rxd.uart0_rxd */ + 0x174 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */ + >; + }; + + leds_pins: pinmux_leds_pins { + pinctrl-single,pins = < + 0x5c (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a7.gpio1_23 */ + >; + }; +}; + +&cpsw_emac0 { + phy_id = <&davinci_mdio>, <0>; +}; + +&cpsw_emac1 { + phy_id = <&davinci_mdio>, <1>; +}; + +&elm { + status = "okay"; +}; + +&gpmc { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&nandflash_pins>; + + ranges = <0 0 0x08000000 0x10000000>; /* CS0: NAND */ + + nand@0,0 { + reg = <0 0 0>; /* CS0, offset 0 */ + nand-bus-width = <8>; + ti,nand-ecc-opt = "bch8"; + gpmc,device-nand = "true"; + gpmc,device-width = <1>; + gpmc,sync-clk-ps = <0>; + gpmc,cs-on-ns = <0>; + gpmc,cs-rd-off-ns = <44>; + gpmc,cs-wr-off-ns = <44>; + gpmc,adv-on-ns = <6>; + gpmc,adv-rd-off-ns = <34>; + gpmc,adv-wr-off-ns = <44>; + gpmc,we-on-ns = <0>; + gpmc,we-off-ns = <40>; + gpmc,oe-on-ns = <0>; + gpmc,oe-off-ns = <54>; + gpmc,access-ns = <64>; + gpmc,rd-cycle-ns = <82>; + gpmc,wr-cycle-ns = <82>; + gpmc,wait-on-read = "true"; + gpmc,wait-on-write = "true"; + gpmc,bus-turnaround-ns = <0>; + gpmc,cycle2cycle-delay-ns = <0>; + gpmc,clk-activation-ns = <0>; + gpmc,wait-monitoring-ns = <0>; + gpmc,wr-access-ns = <40>; + gpmc,wr-data-mux-bus-ns = <0>; + + #address-cells = <1>; + #size-cells = <1>; + elm_id = <&elm>; + + /* MTD partition table */ + partition@0 { + label = "SPL"; + reg = <0x00000000 0x000080000>; + }; + + partition@1 { + label = "U-boot"; + reg = <0x00080000 0x001e0000>; + }; + + partition@2 { + label = "U-Boot Env"; + reg = <0x00260000 0x00020000>; + }; + + partition@3 { + label = "Kernel"; + reg = <0x00280000 0x00500000>; + }; + + partition@4 { + label = "File System"; + reg = <0x00780000 0x007880000>; + }; + }; +}; + +&i2c0 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins>; + + clock-frequency = <400000>; + + tps: tps@2d { + reg = <0x2d>; + }; +}; + +&mmc1 { + status = "okay"; + vmmc-supply = <&vmmc>; + bus-width = <4>; +}; + +&uart0 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins>; +}; + +#include "tps65910.dtsi" + +&tps { + vcc1-supply = <&vbat>; + vcc2-supply = <&vbat>; + vcc3-supply = <&vbat>; + vcc4-supply = <&vbat>; + vcc5-supply = <&vbat>; + vcc6-supply = <&vbat>; + vcc7-supply = <&vbat>; + vccio-supply = <&vbat>; + + regulators { + vrtc_reg: regulator@0 { + regulator-always-on; + }; + + vio_reg: regulator@1 { + regulator-always-on; + }; + + vdd1_reg: regulator@2 { + /* VDD_MPU voltage limits 0.95V - 1.26V with +/-4% tolerance */ + regulator-name = "vdd_mpu"; + regulator-min-microvolt = <912500>; + regulator-max-microvolt = <1312500>; + regulator-boot-on; + regulator-always-on; + }; + + vdd2_reg: regulator@3 { + /* VDD_CORE voltage limits 0.95V - 1.1V with +/-4% tolerance */ + regulator-name = "vdd_core"; + regulator-min-microvolt = <912500>; + regulator-max-microvolt = <1150000>; + regulator-boot-on; + regulator-always-on; + }; + + vdd3_reg: regulator@4 { + regulator-always-on; + }; + + vdig1_reg: regulator@5 { + regulator-always-on; + }; + + vdig2_reg: regulator@6 { + regulator-always-on; + }; + + vpll_reg: regulator@7 { + regulator-always-on; + }; + + vdac_reg: regulator@8 { + regulator-always-on; + }; + + vaux1_reg: regulator@9 { + regulator-always-on; + }; + + vaux2_reg: regulator@10 { + regulator-always-on; + }; + + vaux33_reg: regulator@11 { + regulator-always-on; + }; + + vmmc_reg: regulator@12 { + regulator-always-on; + }; + }; +}; + diff --git a/arch/arm/boot/dts/am335x-nano.dts b/arch/arm/boot/dts/am335x-nano.dts new file mode 100644 index 000000000000..9907b494b99c --- /dev/null +++ b/arch/arm/boot/dts/am335x-nano.dts @@ -0,0 +1,431 @@ +/* + * Copyright (C) 2013 Newflow Ltd - http://www.newflow.co.uk/ + * + * 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. + */ +/dts-v1/; + +#include "am33xx.dtsi" + +/ { + model = "Newflow AM335x NanoBone"; + compatible = "ti,am33xx"; + + cpus { + cpu@0 { + cpu0-supply = <&dcdc2_reg>; + }; + }; + + memory { + device_type = "memory"; + reg = <0x80000000 0x10000000>; /* 256 MB */ + }; + + leds { + compatible = "gpio-leds"; + + led@0 { + label = "nanobone:green:usr1"; + gpios = <&gpio1 5 0>; + default-state = "off"; + }; + }; +}; + +&am33xx_pinmux { + pinctrl-names = "default"; + pinctrl-0 = <&misc_pins>; + + misc_pins: misc_pins { + pinctrl-single,pins = < + 0x15c (PIN_OUTPUT | MUX_MODE7) /* spi0_cs0.gpio0_5 */ + >; + }; + + gpmc_pins: gpmc_pins { + pinctrl-single,pins = < + 0x0 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad0.gpmc_ad0 */ + 0x4 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad1.gpmc_ad1 */ + 0x8 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad2.gpmc_ad2 */ + 0xc (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad3.gpmc_ad3 */ + 0x10 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad4.gpmc_ad4 */ + 0x14 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad5.gpmc_ad5 */ + 0x18 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad6.gpmc_ad6 */ + 0x1c (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad7.gpmc_ad7 */ + 0x20 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad8.gpmc_ad8 */ + 0x24 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad9.gpmc_ad9 */ + 0x28 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad10.gpmc_ad10 */ + 0x2c (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad11.gpmc_ad11 */ + 0x30 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad12.gpmc_ad12 */ + 0x34 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad13.gpmc_ad13 */ + 0x38 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad14.gpmc_ad14 */ + 0x3c (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad15.gpmc_ad15 */ + + 0x70 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_wait0.gpmc_wait0 */ + 0x7c (PIN_OUTPUT | MUX_MODE0) /* gpmc_csn0.gpmc_csn0 */ + 0x80 (PIN_OUTPUT | MUX_MODE0) /* gpmc_csn1.gpmc_csn1 */ + 0x84 (PIN_OUTPUT | MUX_MODE0) /* gpmc_csn2.gpmc_csn2 */ + 0x88 (PIN_OUTPUT | MUX_MODE0) /* gpmc_csn3.gpmc_csn3 */ + + 0x90 (PIN_OUTPUT | MUX_MODE0) /* gpmc_advn_ale.gpmc_advn_ale */ + 0x94 (PIN_OUTPUT | MUX_MODE0) /* gpmc_oen_ren.gpmc_oen_ren */ + 0x98 (PIN_OUTPUT | MUX_MODE0) /* gpmc_wen.gpmc_wen */ + 0x9c (PIN_OUTPUT | MUX_MODE0) /* gpmc_ben0_cle.gpmc_ben0_cle */ + + 0xa4 (PIN_OUTPUT | MUX_MODE1) /* lcd_data1.gpmc_a1 */ + 0xa8 (PIN_OUTPUT | MUX_MODE1) /* lcd_data2.gpmc_a2 */ + 0xac (PIN_OUTPUT | MUX_MODE1) /* lcd_data3.gpmc_a3 */ + 0xb0 (PIN_OUTPUT | MUX_MODE1) /* lcd_data4.gpmc_a4 */ + 0xb4 (PIN_OUTPUT | MUX_MODE1) /* lcd_data5.gpmc_a5 */ + 0xb8 (PIN_OUTPUT | MUX_MODE1) /* lcd_data6.gpmc_a6 */ + 0xbc (PIN_OUTPUT | MUX_MODE1) /* lcd_data7.gpmc_a7 */ + + 0xe0 (PIN_OUTPUT | MUX_MODE1) /* lcd_vsync.gpmc_a8 */ + 0xe4 (PIN_OUTPUT | MUX_MODE1) /* lcd_hsync.gpmc_a9 */ + 0xe8 (PIN_OUTPUT | MUX_MODE1) /* lcd_pclk.gpmc_a10 */ + >; + }; + + i2c0_pins: i2c0_pins { + pinctrl-single,pins = < + 0x188 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* i2c0_sda.i2c0_sda */ + 0x18c (PIN_INPUT_PULLDOWN | MUX_MODE0) /* i2c0_scl.i2c0_scl */ + >; + }; + + uart0_pins: uart0_pins { + pinctrl-single,pins = < + 0x170 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart0_rxd.uart0_rxd */ + 0x174 (PIN_OUTPUT | MUX_MODE0) /* uart0_txd.uart0_txd */ + >; + }; + + uart1_pins: uart1_pins { + pinctrl-single,pins = < + 0x178 (PIN_OUTPUT | MUX_MODE7) /* uart1_ctsn.uart1_ctsn */ + 0x17c (PIN_OUTPUT | MUX_MODE7) /* uart1_rtsn.uart1_rtsn */ + 0x180 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart1_rxd.uart1_rxd */ + 0x184 (PIN_OUTPUT | MUX_MODE0) /* uart1_txd.uart1_txd */ + >; + }; + + uart2_pins: uart2_pins { + pinctrl-single,pins = < + 0xc0 (PIN_INPUT_PULLUP | MUX_MODE7) /* lcd_data8.gpio2[14] */ + 0xc4 (PIN_OUTPUT | MUX_MODE7) /* lcd_data9.gpio2[15] */ + 0x150 (PIN_INPUT | MUX_MODE1) /* spi0_sclk.uart2_rxd */ + 0x154 (PIN_OUTPUT | MUX_MODE1) /* spi0_d0.uart2_txd */ + >; + }; + + uart3_pins: uart3_pins { + pinctrl-single,pins = < + 0xc8 (PIN_INPUT_PULLUP | MUX_MODE6) /* lcd_data10.uart3_ctsn */ + 0xcc (PIN_OUTPUT | MUX_MODE6) /* lcd_data11.uart3_rtsn */ + 0x160 (PIN_INPUT | MUX_MODE1) /* spi0_cs1.uart3_rxd */ + 0x164 (PIN_OUTPUT | MUX_MODE1) /* ecap0_in_pwm0_out.uart3_txd */ + >; + }; + + uart4_pins: uart4_pins { + pinctrl-single,pins = < + 0xd0 (PIN_INPUT_PULLUP | MUX_MODE6) /* lcd_data12.uart4_ctsn */ + 0xd4 (PIN_OUTPUT | MUX_MODE6) /* lcd_data13.uart4_rtsn */ + 0x168 (PIN_INPUT | MUX_MODE1) /* uart0_ctsn.uart4_rxd */ + 0x16c (PIN_OUTPUT | MUX_MODE1) /* uart0_rtsn.uart4_txd */ + >; + }; + + uart5_pins: uart5_pins { + pinctrl-single,pins = < + 0xd8 (PIN_INPUT | MUX_MODE4) /* lcd_data14.uart5_rxd */ + 0x144 (PIN_OUTPUT | MUX_MODE3) /* rmiii1_refclk.uart5_txd */ + >; + }; + + mmc1_pins: mmc1_pins { + pinctrl-single,pins = < + 0xf0 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat0.mmc0_dat0 */ + 0xf4 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat1.mmc0_dat1 */ + 0xf8 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat2.mmc0_dat2 */ + 0xfc (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat3.mmc0_dat3 */ + 0x100 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_clk.mmc0_clk */ + 0x104 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_cmd.mmc0_cmd */ + 0x1e8 (PIN_INPUT_PULLUP | MUX_MODE7) /* emu1.gpio3[8] */ + 0x1a0 (PIN_INPUT_PULLUP | MUX_MODE7) /* mcasp0_aclkr.gpio3[18] */ + >; + }; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins>; + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins>; + status = "okay"; + rts-gpio = <&gpio0 13 GPIO_ACTIVE_HIGH>; + rs485-rts-active-high; + rs485-rx-during-tx; + rs485-rts-delay = <1 1>; + linux,rs485-enabled-at-boot-time; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&uart2_pins>; + status = "okay"; + rts-gpio = <&gpio2 15 GPIO_ACTIVE_HIGH>; + rs485-rts-active-high; + rs485-rts-delay = <1 1>; + linux,rs485-enabled-at-boot-time; +}; + +&uart3 { + pinctrl-names = "default"; + pinctrl-0 = <&uart3_pins>; + status = "okay"; +}; + +&uart4 { + pinctrl-names = "default"; + pinctrl-0 = <&uart4_pins>; + status = "okay"; +}; + +&uart5 { + pinctrl-names = "default"; + pinctrl-0 = <&uart5_pins>; + status = "okay"; +}; + +&i2c0 { + status = "okay"; + pinctrl-names = "default"; + clock-frequency = <400000>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins>; + + gpio@20 { + compatible = "mcp,mcp23017"; + reg = <0x20>; + }; + + tps: tps@24 { + reg = <0x24>; + }; + + eeprom@53 { + compatible = "mcp,24c02"; + reg = <0x53>; + pagesize = <8>; + }; + + rtc@68 { + compatible = "dallas,ds1307"; + reg = <0x68>; + }; +}; + +&elm { + status = "okay"; +}; + +&gpmc { + compatible = "ti,am3352-gpmc"; + ti,hwmods = "gpmc"; + status = "okay"; + gpmc,num-waitpins = <2>; + pinctrl-names = "default"; + pinctrl-0 = <&gpmc_pins>; + + #address-cells = <2>; + #size-cells = <1>; + ranges = <0 0 0x08000000 0x08000000>; /* CS0: NOR 128M */ + + nor@0,0 { + reg = <0 0x00000000 0x08000000>; + compatible = "cfi-flash"; + linux,mtd-name = "spansion,s29gl010p11t"; + bank-width = <2>; + + gpmc,mux-add-data = <2>; + + gpmc,sync-clk-ps = <0>; + gpmc,cs-on-ns = <0>; + gpmc,cs-rd-off-ns = <160>; + gpmc,cs-wr-off-ns = <160>; + gpmc,adv-on-ns = <10>; + gpmc,adv-rd-off-ns = <30>; + gpmc,adv-wr-off-ns = <30>; + gpmc,oe-on-ns = <40>; + gpmc,oe-off-ns = <160>; + gpmc,we-on-ns = <40>; + gpmc,we-off-ns = <160>; + gpmc,rd-cycle-ns = <160>; + gpmc,wr-cycle-ns = <160>; + gpmc,access-ns = <150>; + gpmc,page-burst-access-ns = <10>; + gpmc,cycle2cycle-samecsen; + gpmc,cycle2cycle-delay-ns = <20>; + gpmc,wr-data-mux-bus-ns = <70>; + gpmc,wr-access-ns = <80>; + + #address-cells = <1>; + #size-cells = <1>; + + /* + MTD partition table + =================== + +------------+-->0x00000000-> U-Boot start + | | + | |-->0x000BFFFF-> U-Boot end + | |-->0x000C0000-> ENV1 start + | | + | |-->0x000DFFFF-> ENV1 end + | |-->0x000E0000-> ENV2 start + | | + | |-->0x000FFFFF-> ENV2 end + | |-->0x00100000-> Kernel start + | | + | |-->0x004FFFFF-> Kernel end + | |-->0x00500000-> File system start + | | + | |-->0x014FFFFF-> File system end + | |-->0x01500000-> User data start + | | + | |-->0x03FFFFFF-> User data end + | |-->0x04000000-> Data storage start + | | + +------------+-->0x08000000-> NOR end (Free end) + */ + partition@0 { + label = "boot"; + reg = <0x00000000 0x000c0000>; /* 768KB */ + }; + + partition@1 { + label = "env1"; + reg = <0x000c0000 0x00020000>; /* 128KB */ + }; + + partition@2 { + label = "env2"; + reg = <0x000e0000 0x00020000>; /* 128KB */ + }; + + partition@3 { + label = "kernel"; + reg = <0x00100000 0x00400000>; /* 4MB */ + }; + + partition@4 { + label = "rootfs"; + reg = <0x00500000 0x01000000>; /* 16MB */ + }; + + partition@5 { + label = "user"; + reg = <0x01500000 0x02b00000>; /* 43MB */ + }; + + partition@6 { + label = "data"; + reg = <0x04000000 0x04000000>; /* 64MB */ + }; + }; +}; + +&mac { + dual_emac = <1>; +}; + +&cpsw_emac0 { + phy_id = <&davinci_mdio>, <0>; + dual_emac_res_vlan = <1>; +}; + +&cpsw_emac1 { + phy_id = <&davinci_mdio>, <1>; + dual_emac_res_vlan = <2>; +}; + +&mmc1 { + status = "okay"; + vmmc-supply = <&ldo4_reg>; + pinctrl-names = "default"; + pinctrl-0 = <&mmc1_pins>; + bus-width = <4>; + cd-gpios = <&gpio3 8 0>; + wp-gpios = <&gpio3 18 0>; +}; + +#include "tps65217.dtsi" + +&tps { + regulators { + dcdc1_reg: regulator@0 { + /* +1.5V voltage with ±4% tolerance */ + regulator-min-microvolt = <1450000>; + regulator-max-microvolt = <1550000>; + regulator-boot-on; + regulator-always-on; + }; + + dcdc2_reg: regulator@1 { + /* VDD_MPU voltage limits 0.95V - 1.1V with ±4% tolerance */ + regulator-name = "vdd_mpu"; + regulator-min-microvolt = <915000>; + regulator-max-microvolt = <1140000>; + regulator-boot-on; + regulator-always-on; + }; + + dcdc3_reg: regulator@2 { + /* VDD_CORE voltage limits 0.95V - 1.1V with ±4% tolerance */ + regulator-name = "vdd_core"; + regulator-min-microvolt = <915000>; + regulator-max-microvolt = <1140000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo1_reg: regulator@3 { + /* +1.8V voltage with ±4% tolerance */ + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <1870000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo2_reg: regulator@4 { + /* +3.3V voltage with ±4% tolerance */ + regulator-min-microvolt = <3175000>; + regulator-max-microvolt = <3430000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo3_reg: regulator@5 { + /* +1.8V voltage with ±4% tolerance */ + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <1870000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo4_reg: regulator@6 { + /* +3.3V voltage with ±4% tolerance */ + regulator-min-microvolt = <3175000>; + regulator-max-microvolt = <3430000>; + regulator-boot-on; + regulator-always-on; + }; + }; +}; diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index f9c5da9c7fe1..f6d8ffe98d0b 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi @@ -18,6 +18,9 @@ interrupt-parent = <&intc>; aliases { + i2c0 = &i2c0; + i2c1 = &i2c1; + i2c2 = &i2c2; serial0 = &uart0; serial1 = &uart1; serial2 = &uart2; @@ -30,6 +33,8 @@ usb1 = &usb1; phy0 = &usb0_phy; phy1 = &usb1_phy; + ethernet0 = &cpsw_emac0; + ethernet1 = &cpsw_emac1; }; cpus { @@ -57,6 +62,11 @@ }; }; + pmu { + compatible = "arm,cortex-a8-pmu"; + interrupts = <3>; + }; + /* * The soc node represents the soc top level view. It is uses for IPs * that are not memory mapped in the MPU view or for the MPU itself. @@ -100,13 +110,25 @@ reg = <0x48200000 0x1000>; }; + edma: edma@49000000 { + compatible = "ti,edma3"; + ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2"; + reg = <0x49000000 0x10000>, + <0x44e10f90 0x10>; + interrupts = <12 13 14>; + #dma-cells = <1>; + dma-channels = <64>; + ti,edma-regions = <4>; + ti,edma-slots = <256>; + }; + gpio0: gpio@44e07000 { compatible = "ti,omap4-gpio"; ti,hwmods = "gpio1"; gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; reg = <0x44e07000 0x1000>; interrupts = <96>; }; @@ -117,7 +139,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; reg = <0x4804c000 0x1000>; interrupts = <98>; }; @@ -128,7 +150,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; reg = <0x481ac000 0x1000>; interrupts = <32>; }; @@ -139,7 +161,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; reg = <0x481ae000 0x1000>; interrupts = <62>; }; @@ -228,6 +250,50 @@ status = "disabled"; }; + mmc1: mmc@48060000 { + compatible = "ti,omap4-hsmmc"; + ti,hwmods = "mmc1"; + ti,dual-volt; + ti,needs-special-reset; + ti,needs-special-hs-handling; + dmas = <&edma 24 + &edma 25>; + dma-names = "tx", "rx"; + interrupts = <64>; + interrupt-parent = <&intc>; + reg = <0x48060000 0x1000>; + status = "disabled"; + }; + + mmc2: mmc@481d8000 { + compatible = "ti,omap4-hsmmc"; + ti,hwmods = "mmc2"; + ti,needs-special-reset; + dmas = <&edma 2 + &edma 3>; + dma-names = "tx", "rx"; + interrupts = <28>; + interrupt-parent = <&intc>; + reg = <0x481d8000 0x1000>; + status = "disabled"; + }; + + mmc3: mmc@47810000 { + compatible = "ti,omap4-hsmmc"; + ti,hwmods = "mmc3"; + ti,needs-special-reset; + interrupts = <29>; + interrupt-parent = <&intc>; + reg = <0x47810000 0x1000>; + status = "disabled"; + }; + + hwspinlock: spinlock@480ca000 { + compatible = "ti,omap4-hwspinlock"; + reg = <0x480ca000 0x1000>; + ti,hwmods = "spinlock"; + }; + wdt2: wdt@44e35000 { compatible = "ti,omap3-wdt"; ti,hwmods = "wd_timer2"; @@ -323,6 +389,11 @@ interrupts = <65>; ti,spi-num-cs = <2>; ti,hwmods = "spi0"; + dmas = <&edma 16 + &edma 17 + &edma 18 + &edma 19>; + dma-names = "tx0", "rx0", "tx1", "rx1"; status = "disabled"; }; @@ -334,6 +405,11 @@ interrupts = <125>; ti,spi-num-cs = <2>; ti,hwmods = "spi1"; + dmas = <&edma 42 + &edma 43 + &edma 44 + &edma 45>; + dma-names = "tx0", "rx0", "tx1", "rx1"; status = "disabled"; }; @@ -346,7 +422,7 @@ ti,hwmods = "usb_otg_hs"; status = "disabled"; - ctrl_mod: control@44e10000 { + usb_ctrl_mod: control@44e10000 { compatible = "ti,am335x-usb-ctrl-module"; reg = <0x44e10620 0x10 0x44e10648 0x4>; @@ -359,7 +435,7 @@ reg = <0x47401300 0x100>; reg-names = "phy"; status = "disabled"; - ti,ctrl_mod = <&ctrl_mod>; + ti,ctrl_mod = <&usb_ctrl_mod>; }; usb0: usb@47401000 { @@ -407,7 +483,7 @@ reg = <0x47401b00 0x100>; reg-names = "phy"; status = "disabled"; - ti,ctrl_mod = <&ctrl_mod>; + ti,ctrl_mod = <&usb_ctrl_mod>; }; usb1: usb@47401800 { @@ -594,6 +670,12 @@ /* Filled in by U-Boot */ mac-address = [ 00 00 00 00 00 00 ]; }; + + phy_sel: cpsw-phy-sel@44e10650 { + compatible = "ti,am3352-cpsw-phy-sel"; + reg= <0x44e10650 0x4>; + reg-names = "gmii-sel"; + }; }; ocmcram: ocmcram@40300000 { @@ -607,6 +689,7 @@ reg = <0x44d00000 0x4000 /* M3 UMEM */ 0x44d80000 0x2000>; /* M3 DMEM */ ti,hwmods = "wkup_m3"; + ti,no-reset-on-init; }; elm: elm@48080000 { @@ -617,6 +700,15 @@ status = "disabled"; }; + lcdc: lcdc@4830e000 { + compatible = "ti,am33xx-tilcdc"; + reg = <0x4830e000 0x1000>; + interrupt-parent = <&intc>; + interrupts = <36>; + ti,hwmods = "lcdc"; + status = "disabled"; + }; + tscadc: tscadc@44e0d000 { compatible = "ti,am3359-tscadc"; reg = <0x44e0d000 0x1000>; @@ -637,6 +729,7 @@ gpmc: gpmc@50000000 { compatible = "ti,am3352-gpmc"; ti,hwmods = "gpmc"; + ti,no-idle-on-init; reg = <0x50000000 0x2000>; interrupts = <100>; gpmc,num-cs = <7>; @@ -645,5 +738,59 @@ #size-cells = <1>; status = "disabled"; }; + + sham: sham@53100000 { + compatible = "ti,omap4-sham"; + ti,hwmods = "sham"; + reg = <0x53100000 0x200>; + interrupts = <109>; + dmas = <&edma 36>; + dma-names = "rx"; + }; + + aes: aes@53500000 { + compatible = "ti,omap4-aes"; + ti,hwmods = "aes"; + reg = <0x53500000 0xa0>; + interrupts = <103>; + dmas = <&edma 6>, + <&edma 5>; + dma-names = "tx", "rx"; + }; + + mcasp0: mcasp@48038000 { + compatible = "ti,am33xx-mcasp-audio"; + ti,hwmods = "mcasp0"; + reg = <0x48038000 0x2000>, + <0x46000000 0x400000>; + reg-names = "mpu", "dat"; + interrupts = <80>, <81>; + interrupts-names = "tx", "rx"; + status = "disabled"; + dmas = <&edma 8>, + <&edma 9>; + dma-names = "tx", "rx"; + }; + + mcasp1: mcasp@4803C000 { + compatible = "ti,am33xx-mcasp-audio"; + ti,hwmods = "mcasp1"; + reg = <0x4803C000 0x2000>, + <0x46400000 0x400000>; + reg-names = "mpu", "dat"; + interrupts = <82>, <83>; + interrupts-names = "tx", "rx"; + status = "disabled"; + dmas = <&edma 10>, + <&edma 11>; + dma-names = "tx", "rx"; + }; + + rng: rng@48310000 { + compatible = "ti,omap4-rng"; + ti,hwmods = "rng"; + reg = <0x48310000 0x2000>; + interrupts = <111>; + }; }; }; diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi index ddc1df77ac52..974d103ab3b1 100644 --- a/arch/arm/boot/dts/am4372.dtsi +++ b/arch/arm/boot/dts/am4372.dtsi @@ -18,12 +18,21 @@ aliases { + i2c0 = &i2c0; + i2c1 = &i2c1; + i2c2 = &i2c2; serial0 = &uart0; + ethernet0 = &cpsw_emac0; + ethernet1 = &cpsw_emac1; }; cpus { + #address-cells = <1>; + #size-cells = <0>; cpu@0 { compatible = "arm,cortex-a9"; + device_type = "cpu"; + reg = <0>; }; }; @@ -35,16 +44,100 @@ <0x48240100 0x0100>; }; + l2-cache-controller@48242000 { + compatible = "arm,pl310-cache"; + reg = <0x48242000 0x1000>; + cache-unified; + cache-level = <2>; + }; + + am43xx_pinmux: pinmux@44e10800 { + compatible = "pinctrl-single"; + reg = <0x44e10800 0x31c>; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-single,register-width = <32>; + pinctrl-single,function-mask = <0xffffffff>; + }; + ocp { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges; + ti,hwmods = "l3_main"; + + edma: edma@49000000 { + compatible = "ti,edma3"; + ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2"; + reg = <0x49000000 0x10000>, + <0x44e10f90 0x10>; + interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; + #dma-cells = <1>; + dma-channels = <64>; + ti,edma-regions = <4>; + ti,edma-slots = <256>; + }; uart0: serial@44e09000 { compatible = "ti,am4372-uart","ti,omap2-uart"; reg = <0x44e09000 0x2000>; interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "uart1"; + }; + + uart1: serial@48022000 { + compatible = "ti,am4372-uart","ti,omap2-uart"; + reg = <0x48022000 0x2000>; + interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "uart2"; + status = "disabled"; + }; + + uart2: serial@48024000 { + compatible = "ti,am4372-uart","ti,omap2-uart"; + reg = <0x48024000 0x2000>; + interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "uart3"; + status = "disabled"; + }; + + uart3: serial@481a6000 { + compatible = "ti,am4372-uart","ti,omap2-uart"; + reg = <0x481a6000 0x2000>; + interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "uart4"; + status = "disabled"; + }; + + uart4: serial@481a8000 { + compatible = "ti,am4372-uart","ti,omap2-uart"; + reg = <0x481a8000 0x2000>; + interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "uart5"; + status = "disabled"; + }; + + uart5: serial@481aa000 { + compatible = "ti,am4372-uart","ti,omap2-uart"; + reg = <0x481aa000 0x2000>; + interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "uart6"; + status = "disabled"; + }; + + mailbox: mailbox@480C8000 { + compatible = "ti,omap4-mailbox"; + reg = <0x480C8000 0x200>; + interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "mailbox"; + ti,mbox-num-users = <4>; + ti,mbox-num-fifos = <8>; + ti,mbox-names = "wkup_m3"; + ti,mbox-data = <0 0 0 0>; + status = "disabled"; }; timer1: timer@44e31000 { @@ -52,17 +145,523 @@ reg = <0x44e31000 0x400>; interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>; ti,timer-alwon; + ti,hwmods = "timer1"; }; timer2: timer@48040000 { compatible = "ti,am4372-timer","ti,am335x-timer"; reg = <0x48040000 0x400>; interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "timer2"; + }; + + timer3: timer@48042000 { + compatible = "ti,am4372-timer","ti,am335x-timer"; + reg = <0x48042000 0x400>; + interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "timer3"; + status = "disabled"; + }; + + timer4: timer@48044000 { + compatible = "ti,am4372-timer","ti,am335x-timer"; + reg = <0x48044000 0x400>; + interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>; + ti,timer-pwm; + ti,hwmods = "timer4"; + status = "disabled"; + }; + + timer5: timer@48046000 { + compatible = "ti,am4372-timer","ti,am335x-timer"; + reg = <0x48046000 0x400>; + interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>; + ti,timer-pwm; + ti,hwmods = "timer5"; + status = "disabled"; + }; + + timer6: timer@48048000 { + compatible = "ti,am4372-timer","ti,am335x-timer"; + reg = <0x48048000 0x400>; + interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>; + ti,timer-pwm; + ti,hwmods = "timer6"; + status = "disabled"; + }; + + timer7: timer@4804a000 { + compatible = "ti,am4372-timer","ti,am335x-timer"; + reg = <0x4804a000 0x400>; + interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>; + ti,timer-pwm; + ti,hwmods = "timer7"; + status = "disabled"; + }; + + timer8: timer@481c1000 { + compatible = "ti,am4372-timer","ti,am335x-timer"; + reg = <0x481c1000 0x400>; + interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "timer8"; + status = "disabled"; + }; + + timer9: timer@4833d000 { + compatible = "ti,am4372-timer","ti,am335x-timer"; + reg = <0x4833d000 0x400>; + interrupts = <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "timer9"; + status = "disabled"; + }; + + timer10: timer@4833f000 { + compatible = "ti,am4372-timer","ti,am335x-timer"; + reg = <0x4833f000 0x400>; + interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "timer10"; + status = "disabled"; + }; + + timer11: timer@48341000 { + compatible = "ti,am4372-timer","ti,am335x-timer"; + reg = <0x48341000 0x400>; + interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "timer11"; + status = "disabled"; }; counter32k: counter@44e86000 { compatible = "ti,am4372-counter32k","ti,omap-counter32k"; reg = <0x44e86000 0x40>; + ti,hwmods = "counter_32k"; + }; + + rtc@44e3e000 { + compatible = "ti,am4372-rtc","ti,da830-rtc"; + reg = <0x44e3e000 0x1000>; + interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "rtc"; + status = "disabled"; + }; + + wdt@44e35000 { + compatible = "ti,am4372-wdt","ti,omap3-wdt"; + reg = <0x44e35000 0x1000>; + interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "wd_timer2"; + }; + + gpio0: gpio@44e07000 { + compatible = "ti,am4372-gpio","ti,omap4-gpio"; + reg = <0x44e07000 0x1000>; + interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + ti,hwmods = "gpio1"; + status = "disabled"; + }; + + gpio1: gpio@4804c000 { + compatible = "ti,am4372-gpio","ti,omap4-gpio"; + reg = <0x4804c000 0x1000>; + interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + ti,hwmods = "gpio2"; + status = "disabled"; + }; + + gpio2: gpio@481ac000 { + compatible = "ti,am4372-gpio","ti,omap4-gpio"; + reg = <0x481ac000 0x1000>; + interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + ti,hwmods = "gpio3"; + status = "disabled"; + }; + + gpio3: gpio@481ae000 { + compatible = "ti,am4372-gpio","ti,omap4-gpio"; + reg = <0x481ae000 0x1000>; + interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + ti,hwmods = "gpio4"; + status = "disabled"; + }; + + gpio4: gpio@48320000 { + compatible = "ti,am4372-gpio","ti,omap4-gpio"; + reg = <0x48320000 0x1000>; + interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + ti,hwmods = "gpio5"; + status = "disabled"; + }; + + gpio5: gpio@48322000 { + compatible = "ti,am4372-gpio","ti,omap4-gpio"; + reg = <0x48322000 0x1000>; + interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + ti,hwmods = "gpio6"; + status = "disabled"; + }; + + i2c0: i2c@44e0b000 { + compatible = "ti,am4372-i2c","ti,omap4-i2c"; + reg = <0x44e0b000 0x1000>; + interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "i2c1"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c1: i2c@4802a000 { + compatible = "ti,am4372-i2c","ti,omap4-i2c"; + reg = <0x4802a000 0x1000>; + interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "i2c2"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c2: i2c@4819c000 { + compatible = "ti,am4372-i2c","ti,omap4-i2c"; + reg = <0x4819c000 0x1000>; + interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "i2c3"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + spi0: spi@48030000 { + compatible = "ti,am4372-mcspi","ti,omap4-mcspi"; + reg = <0x48030000 0x400>; + interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "spi0"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + mmc1: mmc@48060000 { + compatible = "ti,omap4-hsmmc"; + reg = <0x48060000 0x1000>; + ti,hwmods = "mmc1"; + ti,dual-volt; + ti,needs-special-reset; + dmas = <&edma 24 + &edma 25>; + dma-names = "tx", "rx"; + interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + mmc2: mmc@481d8000 { + compatible = "ti,omap4-hsmmc"; + reg = <0x481d8000 0x1000>; + ti,hwmods = "mmc2"; + ti,needs-special-reset; + dmas = <&edma 2 + &edma 3>; + dma-names = "tx", "rx"; + interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + mmc3: mmc@47810000 { + compatible = "ti,omap4-hsmmc"; + reg = <0x47810000 0x1000>; + ti,hwmods = "mmc3"; + ti,needs-special-reset; + interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + spi1: spi@481a0000 { + compatible = "ti,am4372-mcspi","ti,omap4-mcspi"; + reg = <0x481a0000 0x400>; + interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "spi1"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + spi2: spi@481a2000 { + compatible = "ti,am4372-mcspi","ti,omap4-mcspi"; + reg = <0x481a2000 0x400>; + interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "spi2"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + spi3: spi@481a4000 { + compatible = "ti,am4372-mcspi","ti,omap4-mcspi"; + reg = <0x481a4000 0x400>; + interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "spi3"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + spi4: spi@48345000 { + compatible = "ti,am4372-mcspi","ti,omap4-mcspi"; + reg = <0x48345000 0x400>; + interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "spi4"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + mac: ethernet@4a100000 { + compatible = "ti,am4372-cpsw","ti,cpsw"; + reg = <0x4a100000 0x800 + 0x4a101200 0x100>; + interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <1>; + ti,hwmods = "cpgmac0"; + status = "disabled"; + cpdma_channels = <8>; + ale_entries = <1024>; + bd_ram_size = <0x2000>; + no_bd_ram = <0>; + rx_descs = <64>; + mac_control = <0x20>; + slaves = <2>; + active_slave = <0>; + cpts_clock_mult = <0x80000000>; + cpts_clock_shift = <29>; + ranges; + + davinci_mdio: mdio@4a101000 { + compatible = "ti,am4372-mdio","ti,davinci_mdio"; + reg = <0x4a101000 0x100>; + #address-cells = <1>; + #size-cells = <0>; + ti,hwmods = "davinci_mdio"; + bus_freq = <1000000>; + status = "disabled"; + }; + + cpsw_emac0: slave@4a100200 { + /* Filled in by U-Boot */ + mac-address = [ 00 00 00 00 00 00 ]; + }; + + cpsw_emac1: slave@4a100300 { + /* Filled in by U-Boot */ + mac-address = [ 00 00 00 00 00 00 ]; + }; + }; + + epwmss0: epwmss@48300000 { + compatible = "ti,am4372-pwmss","ti,am33xx-pwmss"; + reg = <0x48300000 0x10>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + ti,hwmods = "epwmss0"; + status = "disabled"; + + ecap0: ecap@48300100 { + compatible = "ti,am4372-ecap","ti,am33xx-ecap"; + reg = <0x48300100 0x80>; + ti,hwmods = "ecap0"; + status = "disabled"; + }; + + ehrpwm0: ehrpwm@48300200 { + compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm"; + reg = <0x48300200 0x80>; + ti,hwmods = "ehrpwm0"; + status = "disabled"; + }; + }; + + epwmss1: epwmss@48302000 { + compatible = "ti,am4372-pwmss","ti,am33xx-pwmss"; + reg = <0x48302000 0x10>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + ti,hwmods = "epwmss1"; + status = "disabled"; + + ecap1: ecap@48302100 { + compatible = "ti,am4372-ecap","ti,am33xx-ecap"; + reg = <0x48302100 0x80>; + ti,hwmods = "ecap1"; + status = "disabled"; + }; + + ehrpwm1: ehrpwm@48302200 { + compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm"; + reg = <0x48302200 0x80>; + ti,hwmods = "ehrpwm1"; + status = "disabled"; + }; + }; + + epwmss2: epwmss@48304000 { + compatible = "ti,am4372-pwmss","ti,am33xx-pwmss"; + reg = <0x48304000 0x10>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + ti,hwmods = "epwmss2"; + status = "disabled"; + + ecap2: ecap@48304100 { + compatible = "ti,am4372-ecap","ti,am33xx-ecap"; + reg = <0x48304100 0x80>; + ti,hwmods = "ecap2"; + status = "disabled"; + }; + + ehrpwm2: ehrpwm@48304200 { + compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm"; + reg = <0x48304200 0x80>; + ti,hwmods = "ehrpwm2"; + status = "disabled"; + }; + }; + + epwmss3: epwmss@48306000 { + compatible = "ti,am4372-pwmss","ti,am33xx-pwmss"; + reg = <0x48306000 0x10>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + ti,hwmods = "epwmss3"; + status = "disabled"; + + ehrpwm3: ehrpwm@48306200 { + compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm"; + reg = <0x48306200 0x80>; + ti,hwmods = "ehrpwm3"; + status = "disabled"; + }; + }; + + epwmss4: epwmss@48308000 { + compatible = "ti,am4372-pwmss","ti,am33xx-pwmss"; + reg = <0x48308000 0x10>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + ti,hwmods = "epwmss4"; + status = "disabled"; + + ehrpwm4: ehrpwm@48308200 { + compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm"; + reg = <0x48308200 0x80>; + ti,hwmods = "ehrpwm4"; + status = "disabled"; + }; + }; + + epwmss5: epwmss@4830a000 { + compatible = "ti,am4372-pwmss","ti,am33xx-pwmss"; + reg = <0x4830a000 0x10>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + ti,hwmods = "epwmss5"; + status = "disabled"; + + ehrpwm5: ehrpwm@4830a200 { + compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm"; + reg = <0x4830a200 0x80>; + ti,hwmods = "ehrpwm5"; + status = "disabled"; + }; + }; + + sham: sham@53100000 { + compatible = "ti,omap5-sham"; + ti,hwmods = "sham"; + reg = <0x53100000 0x300>; + dmas = <&edma 36>; + dma-names = "rx"; + interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>; + }; + + aes: aes@53501000 { + compatible = "ti,omap4-aes"; + ti,hwmods = "aes"; + reg = <0x53501000 0xa0>; + interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&edma 6 + &edma 5>; + dma-names = "tx", "rx"; + }; + + des: des@53701000 { + compatible = "ti,omap4-des"; + ti,hwmods = "des"; + reg = <0x53701000 0xa0>; + interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&edma 34 + &edma 33>; + dma-names = "tx", "rx"; + }; + + mcasp0: mcasp@48038000 { + compatible = "ti,am33xx-mcasp-audio"; + ti,hwmods = "mcasp0"; + reg = <0x48038000 0x2000>, + <0x46000000 0x400000>; + reg-names = "mpu", "dat"; + interrupts = <80>, <81>; + interrupts-names = "tx", "rx"; + status = "disabled"; + dmas = <&edma 8>, + <&edma 9>; + dma-names = "tx", "rx"; + }; + + mcasp1: mcasp@4803C000 { + compatible = "ti,am33xx-mcasp-audio"; + ti,hwmods = "mcasp1"; + reg = <0x4803C000 0x2000>, + <0x46400000 0x400000>; + reg-names = "mpu", "dat"; + interrupts = <82>, <83>; + interrupts-names = "tx", "rx"; + status = "disabled"; + dmas = <&edma 10>, + <&edma 11>; + dma-names = "tx", "rx"; }; }; }; diff --git a/arch/arm/boot/dts/am43x-epos-evm.dts b/arch/arm/boot/dts/am43x-epos-evm.dts index 74174d48f476..fbf9c4c7a94f 100644 --- a/arch/arm/boot/dts/am43x-epos-evm.dts +++ b/arch/arm/boot/dts/am43x-epos-evm.dts @@ -11,8 +11,176 @@ /dts-v1/; #include "am4372.dtsi" +#include <dt-bindings/pinctrl/am43xx.h> +#include <dt-bindings/gpio/gpio.h> / { model = "TI AM43x EPOS EVM"; compatible = "ti,am43x-epos-evm","ti,am4372","ti,am43"; + + vmmcsd_fixed: fixedregulator-sd { + compatible = "regulator-fixed"; + regulator-name = "vmmcsd_fixed"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + enable-active-high; + }; + + am43xx_pinmux: pinmux@44e10800 { + cpsw_default: cpsw_default { + pinctrl-single,pins = < + /* Slave 1 */ + 0x10c (PIN_INPUT_PULLDOWN | MUX_MODE1) /* mii1_crs.rmii1_crs */ + 0x110 (PIN_INPUT_PULLDOWN | MUX_MODE1) /* mii1_rxerr.rmii1_rxerr */ + 0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* mii1_txen.rmii1_txen */ + 0x118 (PIN_INPUT_PULLDOWN | MUX_MODE1) /* mii1_rxdv.rmii1_rxdv */ + 0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* mii1_txd1.rmii1_txd1 */ + 0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* mii1_txd0.rmii1_txd0 */ + 0x13c (PIN_INPUT_PULLDOWN | MUX_MODE1) /* mii1_rxd1.rmii1_rxd1 */ + 0x140 (PIN_INPUT_PULLDOWN | MUX_MODE1) /* mii1_rxd0.rmii1_rxd0 */ + 0x144 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* rmii1_refclk.rmii1_refclk */ + >; + }; + + cpsw_sleep: cpsw_sleep { + pinctrl-single,pins = < + /* Slave 1 reset value */ + 0x10c (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x110 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x118 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x144 (PIN_INPUT_PULLDOWN | MUX_MODE7) + >; + }; + + davinci_mdio_default: davinci_mdio_default { + pinctrl-single,pins = < + /* MDIO */ + 0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* mdio_data.mdio_data */ + 0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0) /* mdio_clk.mdio_clk */ + >; + }; + + davinci_mdio_sleep: davinci_mdio_sleep { + pinctrl-single,pins = < + /* MDIO reset value */ + 0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7) + 0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7) + >; + }; + + i2c0_pins: pinmux_i2c0_pins { + pinctrl-single,pins = < + 0x188 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* i2c0_sda.i2c0_sda */ + 0x18c (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* i2c0_scl.i2c0_scl */ + >; + }; + }; + + matrix_keypad: matrix_keypad@0 { + compatible = "gpio-matrix-keypad"; + debounce-delay-ms = <5>; + col-scan-delay-us = <2>; + + row-gpios = <&gpio0 12 GPIO_ACTIVE_HIGH /* Bank0, pin12 */ + &gpio0 13 GPIO_ACTIVE_HIGH /* Bank0, pin13 */ + &gpio0 14 GPIO_ACTIVE_HIGH /* Bank0, pin14 */ + &gpio0 15 GPIO_ACTIVE_HIGH>; /* Bank0, pin15 */ + + col-gpios = <&gpio3 9 GPIO_ACTIVE_HIGH /* Bank3, pin9 */ + &gpio3 10 GPIO_ACTIVE_HIGH /* Bank3, pin10 */ + &gpio2 18 GPIO_ACTIVE_HIGH /* Bank2, pin18 */ + &gpio2 19 GPIO_ACTIVE_HIGH>; /* Bank2, pin19 */ + + linux,keymap = <0x00000201 /* P1 */ + 0x01000204 /* P4 */ + 0x02000207 /* P7 */ + 0x0300020a /* NUMERIC_STAR */ + 0x00010202 /* P2 */ + 0x01010205 /* P5 */ + 0x02010208 /* P8 */ + 0x03010200 /* P0 */ + 0x00020203 /* P3 */ + 0x01020206 /* P6 */ + 0x02020209 /* P9 */ + 0x0302020b /* NUMERIC_POUND */ + 0x00030067 /* UP */ + 0x0103006a /* RIGHT */ + 0x0203006c /* DOWN */ + 0x03030069>; /* LEFT */ + }; +}; + +&mmc1 { + status = "okay"; + vmmc-supply = <&vmmcsd_fixed>; + bus-width = <4>; +}; + +&mac { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&cpsw_default>; + pinctrl-1 = <&cpsw_sleep>; + status = "okay"; +}; + +&davinci_mdio { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&davinci_mdio_default>; + pinctrl-1 = <&davinci_mdio_sleep>; + status = "okay"; +}; + +&cpsw_emac0 { + phy_id = <&davinci_mdio>, <16>; + phy-mode = "rmii"; +}; + +&cpsw_emac1 { + phy_id = <&davinci_mdio>, <1>; + phy-mode = "rmii"; +}; + +&i2c0 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins>; + + at24@50 { + compatible = "at24,24c256"; + pagesize = <64>; + reg = <0x50>; + }; + + pixcir_ts@5c { + compatible = "pixcir,pixcir_ts"; + reg = <0x5c>; + interrupt-parent = <&gpio1>; + interrupts = <17 0>; + + attb-gpio = <&gpio1 17 GPIO_ACTIVE_HIGH>; + + x-size = <1024>; + y-size = <768>; + }; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&gpio2 { + status = "okay"; +}; + +&gpio3 { + status = "okay"; }; diff --git a/arch/arm/boot/dts/armada-370-netgear-rn104.dts b/arch/arm/boot/dts/armada-370-netgear-rn104.dts new file mode 100644 index 000000000000..b0b32f5fbeb4 --- /dev/null +++ b/arch/arm/boot/dts/armada-370-netgear-rn104.dts @@ -0,0 +1,193 @@ +/* + * Device Tree file for NETGEAR ReadyNAS 104 + * + * Copyright (C) 2013, Arnaud EBALARD <arno@natisbad.org> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +/dts-v1/; + +#include "armada-370.dtsi" + +/ { + model = "NETGEAR ReadyNAS 104"; + compatible = "netgear,readynas-104", "marvell,armada370", "marvell,armada-370-xp"; + + chosen { + bootargs = "console=ttyS0,115200 earlyprintk"; + }; + + memory { + device_type = "memory"; + reg = <0x00000000 0x20000000>; /* 512 MB */ + }; + + soc { + ranges = <MBUS_ID(0xf0, 0x01) 0 0xd0000000 0x100000 + MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000>; + + pcie-controller { + status = "okay"; + + /* Connected to FL1009 USB 3.0 controller */ + pcie@1,0 { + /* Port 0, Lane 0 */ + status = "okay"; + }; + + /* Connected to Marvell 88SE9215 SATA controller */ + pcie@2,0 { + /* Port 1, Lane 0 */ + status = "okay"; + }; + }; + + internal-regs { + serial@12000 { + clock-frequency = <200000000>; + status = "okay"; + }; + + pinctrl { + poweroff: poweroff { + marvell,pins = "mpp60"; + marvell,function = "gpio"; + }; + + backup_key_pin: backup-key-pin { + marvell,pins = "mpp52"; + marvell,function = "gpio"; + }; + + power_key_pin: power-key-pin { + marvell,pins = "mpp62"; + marvell,function = "gpio"; + }; + + backup_led_pin: backup-led-pin { + marvell,pins = "mpp63"; + marvell,function = "gpo"; + }; + + power_led_pin: power-led-pin { + marvell,pins = "mpp64"; + marvell,function = "gpio"; + }; + + reset_key_pin: reset-key-pin { + marvell,pins = "mpp65"; + marvell,function = "gpio"; + }; + }; + + mdio { + phy0: ethernet-phy@0 { + reg = <0>; + }; + + phy1: ethernet-phy@1 { + reg = <1>; + }; + }; + + ethernet@70000 { + status = "okay"; + phy = <&phy0>; + phy-mode = "rgmii-id"; + }; + + ethernet@74000 { + status = "okay"; + phy = <&phy1>; + phy-mode = "rgmii-id"; + }; + + usb@50000 { + status = "okay"; + }; + + i2c@11000 { + compatible = "marvell,mv64xxx-i2c"; + clock-frequency = <100000>; + status = "okay"; + + g762: g762@3e { + compatible = "gmt,g762"; + reg = <0x3e>; + clocks = <&g762_clk>; /* input clock */ + fan_gear_mode = <0>; + fan_startv = <1>; + pwm_polarity = <0>; + }; + }; + }; + }; + + clocks { + #address-cells = <1>; + #size-cells = <0>; + + g762_clk: fixedclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <8192>; + }; + }; + + gpio_leds { + compatible = "gpio-leds"; + pinctrl-0 = <&backup_led_pin &power_led_pin>; + pinctrl-names = "default"; + + blue_backup_led { + label = "rn104:blue:backup"; + gpios = <&gpio1 31 0>; /* GPIO 63 Active High */ + default-state = "off"; + }; + + blue_power_led { + label = "rn104:blue:pwr"; + gpios = <&gpio2 0 1>; /* GPIO 64 Active Low */ + linux,default-trigger = "keep"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-0 = <&backup_key_pin + &power_key_pin + &reset_key_pin>; + pinctrl-names = "default"; + + button@1 { + label = "Backup Button"; + linux,code = <133>; /* KEY_COPY */ + gpios = <&gpio1 20 1>; + }; + + button@2 { + label = "Power Button"; + linux,code = <116>; /* KEY_POWER */ + gpios = <&gpio1 30 0>; + }; + + button@3 { + label = "Reset Button"; + linux,code = <0x198>; /* KEY_RESTART */ + gpios = <&gpio2 1 1>; + }; + }; + + gpio_poweroff { + compatible = "gpio-poweroff"; + pinctrl-0 = <&poweroff>; + pinctrl-names = "default"; + gpios = <&gpio1 28 1>; + }; +}; diff --git a/arch/arm/boot/dts/armada-370-xp.dtsi b/arch/arm/boot/dts/armada-370-xp.dtsi index 1de2dae0fdae..00d6a798c705 100644 --- a/arch/arm/boot/dts/armada-370-xp.dtsi +++ b/arch/arm/boot/dts/armada-370-xp.dtsi @@ -113,6 +113,7 @@ #interrupt-cells = <1>; #size-cells = <1>; interrupt-controller; + msi-controller; }; coherency-fabric@20200 { @@ -137,6 +138,14 @@ status = "disabled"; }; + coredivclk: corediv-clock@18740 { + compatible = "marvell,armada-370-corediv-clock"; + reg = <0x18740 0xc>; + #clock-cells = <1>; + clocks = <&mainpll>; + clock-output-names = "nand"; + }; + timer@20300 { reg = <0x20300 0x30>, <0x21040 0x30>; interrupts = <37>, <38>, <39>, <40>, <5>, <6>; @@ -176,7 +185,6 @@ i2c0: i2c@11000 { compatible = "marvell,mv64xxx-i2c"; - reg = <0x11000 0x20>; #address-cells = <1>; #size-cells = <0>; interrupts = <31>; @@ -187,7 +195,6 @@ i2c1: i2c@11100 { compatible = "marvell,mv64xxx-i2c"; - reg = <0x11100 0x20>; #address-cells = <1>; #size-cells = <0>; interrupts = <32>; @@ -252,4 +259,13 @@ }; }; + + clocks { + /* 2 GHz fixed main PLL */ + mainpll: mainpll { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <2000000000>; + }; + }; }; diff --git a/arch/arm/boot/dts/armada-370.dtsi b/arch/arm/boot/dts/armada-370.dtsi index e134d7a90c9a..7a4b82e71aaf 100644 --- a/arch/arm/boot/dts/armada-370.dtsi +++ b/arch/arm/boot/dts/armada-370.dtsi @@ -44,6 +44,7 @@ #address-cells = <3>; #size-cells = <2>; + msi-parent = <&mpic>; bus-range = <0x00 0xff>; ranges = @@ -218,6 +219,14 @@ }; }; + i2c0: i2c@11000 { + reg = <0x11000 0x20>; + }; + + i2c1: i2c@11100 { + reg = <0x11100 0x20>; + }; + usb@50000 { clocks = <&coreclk 0>; }; diff --git a/arch/arm/boot/dts/armada-xp-matrix.dts b/arch/arm/boot/dts/armada-xp-matrix.dts new file mode 100644 index 000000000000..e47c49ecd55c --- /dev/null +++ b/arch/arm/boot/dts/armada-xp-matrix.dts @@ -0,0 +1,75 @@ +/* + * Device Tree file for Marvell Armada XP Matrix board + * + * Copyright (C) 2013 Marvell + * + * Lior Amsalem <alior@marvell.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. + */ + +/dts-v1/; +#include "armada-xp-mv78460.dtsi" + +/ { + model = "Marvell Armada XP Matrix Board"; + compatible = "marvell,axp-matrix", "marvell,armadaxp-mv78460", "marvell,armadaxp", "marvell,armada-370-xp"; + + chosen { + bootargs = "console=ttyS0,115200 earlyprintk"; + }; + + memory { + device_type = "memory"; + reg = <0 0x00000000 0 0x80000000>; /* 2 GB */ + }; + + soc { + ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xf1000000 0x100000 + MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000>; + + internal-regs { + serial@12000 { + clock-frequency = <250000000>; + status = "okay"; + }; + serial@12100 { + clock-frequency = <250000000>; + status = "okay"; + }; + serial@12200 { + clock-frequency = <250000000>; + status = "okay"; + }; + serial@12300 { + clock-frequency = <250000000>; + status = "okay"; + }; + + sata@a0000 { + nr-ports = <2>; + status = "okay"; + }; + + ethernet@30000 { + status = "okay"; + phy-mode = "sgmii"; + }; + + pcie-controller { + status = "okay"; + + pcie@1,0 { + /* Port 0, Lane 0 */ + status = "okay"; + }; + }; + + usb@50000 { + status = "okay"; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/armada-xp-mv78230.dtsi b/arch/arm/boot/dts/armada-xp-mv78230.dtsi index 0358a33cba48..3f5e6121c730 100644 --- a/arch/arm/boot/dts/armada-xp-mv78230.dtsi +++ b/arch/arm/boot/dts/armada-xp-mv78230.dtsi @@ -57,6 +57,7 @@ #address-cells = <3>; #size-cells = <2>; + msi-parent = <&mpic>; bus-range = <0x00 0xff>; ranges = diff --git a/arch/arm/boot/dts/armada-xp-mv78260.dtsi b/arch/arm/boot/dts/armada-xp-mv78260.dtsi index 0e82c5062243..3e9fd1353f89 100644 --- a/arch/arm/boot/dts/armada-xp-mv78260.dtsi +++ b/arch/arm/boot/dts/armada-xp-mv78260.dtsi @@ -58,6 +58,7 @@ #address-cells = <3>; #size-cells = <2>; + msi-parent = <&mpic>; bus-range = <0x00 0xff>; ranges = diff --git a/arch/arm/boot/dts/armada-xp-mv78460.dtsi b/arch/arm/boot/dts/armada-xp-mv78460.dtsi index e82c1b80af17..31ba6d8fbadf 100644 --- a/arch/arm/boot/dts/armada-xp-mv78460.dtsi +++ b/arch/arm/boot/dts/armada-xp-mv78460.dtsi @@ -74,6 +74,7 @@ #address-cells = <3>; #size-cells = <2>; + msi-parent = <&mpic>; bus-range = <0x00 0xff>; ranges = diff --git a/arch/arm/boot/dts/armada-xp.dtsi b/arch/arm/boot/dts/armada-xp.dtsi index 3058522f5aad..281c6447e872 100644 --- a/arch/arm/boot/dts/armada-xp.dtsi +++ b/arch/arm/boot/dts/armada-xp.dtsi @@ -147,6 +147,16 @@ }; }; + i2c0: i2c@11000 { + compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c"; + reg = <0x11000 0x100>; + }; + + i2c1: i2c@11100 { + compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c"; + reg = <0x11100 0x100>; + }; + usb@50000 { clocks = <&gateclk 18>; }; diff --git a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi index 137354689ad0..cb2c010e08e2 100644 --- a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi +++ b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi @@ -96,7 +96,6 @@ }; spi0: spi@fffc8000 { - status = "okay"; cs-gpios = <0>, <&pioC 11 0>, <0>, <0>; mtd_dataflash@0 { compatible = "atmel,at45", "atmel,dataflash"; diff --git a/arch/arm/boot/dts/at91sam9g25.dtsi b/arch/arm/boot/dts/at91sam9g25.dtsi index b4ec6fe53fc7..17b879990914 100644 --- a/arch/arm/boot/dts/at91sam9g25.dtsi +++ b/arch/arm/boot/dts/at91sam9g25.dtsi @@ -7,6 +7,8 @@ */ #include "at91sam9x5.dtsi" +#include "at91sam9x5_usart3.dtsi" +#include "at91sam9x5_macb0.dtsi" / { model = "Atmel AT91SAM9G25 SoC"; diff --git a/arch/arm/boot/dts/at91sam9g35.dtsi b/arch/arm/boot/dts/at91sam9g35.dtsi index bebf9f55614b..e35c2fcf8298 100644 --- a/arch/arm/boot/dts/at91sam9g35.dtsi +++ b/arch/arm/boot/dts/at91sam9g35.dtsi @@ -7,6 +7,7 @@ */ #include "at91sam9x5.dtsi" +#include "at91sam9x5_macb0.dtsi" / { model = "Atmel AT91SAM9G35 SoC"; diff --git a/arch/arm/boot/dts/at91sam9n12.dtsi b/arch/arm/boot/dts/at91sam9n12.dtsi index 9fb7ffd32af2..6224f9fe2f2b 100644 --- a/arch/arm/boot/dts/at91sam9n12.dtsi +++ b/arch/arm/boot/dts/at91sam9n12.dtsi @@ -437,6 +437,9 @@ compatible = "atmel,at91sam9g45-ssc"; reg = <0xf0010000 0x4000>; interrupts = <28 IRQ_TYPE_LEVEL_HIGH 5>; + dmas = <&dma 0 AT91_DMA_CFG_PER_ID(21)>, + <&dma 0 AT91_DMA_CFG_PER_ID(22)>; + dma-names = "tx", "rx"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ssc0_tx &pinctrl_ssc0_rx>; status = "disabled"; diff --git a/arch/arm/boot/dts/at91sam9n12ek.dts b/arch/arm/boot/dts/at91sam9n12ek.dts index 27a9352b9d7a..e9487f6f0166 100644 --- a/arch/arm/boot/dts/at91sam9n12ek.dts +++ b/arch/arm/boot/dts/at91sam9n12ek.dts @@ -38,9 +38,18 @@ status = "okay"; }; + ssc0: ssc@f0010000 { + status = "okay"; + }; + i2c0: i2c@f8010000 { status = "okay"; + wm8904: codec@1a { + compatible = "wm8904"; + reg = <0x1a>; + }; + qt1070: keyboard@1b { compatible = "qt1070"; reg = <0x1b>; @@ -82,6 +91,13 @@ <AT91_PIOA 2 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; }; }; + + sound { + pinctrl_pck0_as_audio_mck: pck0_as_audio_mck { + atmel,pins = + <AT91_PIOB 10 AT91_PERIPH_B AT91_PINCTRL_NONE>; + }; + }; }; spi0: spi@f0000000 { @@ -142,4 +158,22 @@ gpio-key,wakeup; }; }; + + sound { + compatible = "atmel,asoc-wm8904"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pck0_as_audio_mck>; + + atmel,model = "wm8904 @ AT91SAM9N12"; + atmel,audio-routing = + "Headphone Jack", "HPOUTL", + "Headphone Jack", "HPOUTR", + "IN2L", "Line In Jack", + "IN2R", "Line In Jack", + "Mic", "MICBIAS", + "IN1L", "Mic"; + + atmel,ssc-controller = <&ssc0>; + atmel,audio-codec = <&wm8904>; + }; }; diff --git a/arch/arm/boot/dts/at91sam9x25.dtsi b/arch/arm/boot/dts/at91sam9x25.dtsi index 49e94aba938f..c2554219f7a4 100644 --- a/arch/arm/boot/dts/at91sam9x25.dtsi +++ b/arch/arm/boot/dts/at91sam9x25.dtsi @@ -7,6 +7,9 @@ */ #include "at91sam9x5.dtsi" +#include "at91sam9x5_usart3.dtsi" +#include "at91sam9x5_macb0.dtsi" +#include "at91sam9x5_macb1.dtsi" / { model = "Atmel AT91SAM9X25 SoC"; @@ -22,27 +25,6 @@ 0x80000000 0xfffd0000 0xb83fffff /* pioC */ 0x003fffff 0x003f8000 0x00000000 /* pioD */ >; - - macb1 { - pinctrl_macb1_rmii: macb1_rmii-0 { - atmel,pins = - <AT91_PIOC 16 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC16 periph B */ - AT91_PIOC 18 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC18 periph B */ - AT91_PIOC 19 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC19 periph B */ - AT91_PIOC 20 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC20 periph B */ - AT91_PIOC 21 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC21 periph B */ - AT91_PIOC 27 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC27 periph B */ - AT91_PIOC 28 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC28 periph B */ - AT91_PIOC 29 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC29 periph B */ - AT91_PIOC 30 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC30 periph B */ - AT91_PIOC 31 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PC31 periph B */ - }; - }; - }; - - macb1: ethernet@f8030000 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_macb1_rmii>; }; }; }; diff --git a/arch/arm/boot/dts/at91sam9x35.dtsi b/arch/arm/boot/dts/at91sam9x35.dtsi index 1a3d525a1f5d..8eac66ce0ab7 100644 --- a/arch/arm/boot/dts/at91sam9x35.dtsi +++ b/arch/arm/boot/dts/at91sam9x35.dtsi @@ -7,6 +7,7 @@ */ #include "at91sam9x5.dtsi" +#include "at91sam9x5_macb0.dtsi" / { model = "Atmel AT91SAM9X35 SoC"; diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi index e74dc15efa9d..40267a116c3c 100644 --- a/arch/arm/boot/dts/at91sam9x5.dtsi +++ b/arch/arm/boot/dts/at91sam9x5.dtsi @@ -206,29 +206,6 @@ }; }; - usart3 { - pinctrl_usart3: usart3-0 { - atmel,pins = - <AT91_PIOC 22 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* PC22 periph B with pullup */ - AT91_PIOC 23 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PC23 periph B */ - }; - - pinctrl_usart3_rts: usart3_rts-0 { - atmel,pins = - <AT91_PIOC 24 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PC24 periph B */ - }; - - pinctrl_usart3_cts: usart3_cts-0 { - atmel,pins = - <AT91_PIOC 25 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PC25 periph B */ - }; - - pinctrl_usart3_sck: usart3_sck-0 { - atmel,pins = - <AT91_PIOC 26 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PC26 periph B */ - }; - }; - uart0 { pinctrl_uart0: uart0-0 { atmel,pins = @@ -277,34 +254,6 @@ }; }; - macb0 { - pinctrl_macb0_rmii: macb0_rmii-0 { - atmel,pins = - <AT91_PIOB 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB0 periph A */ - AT91_PIOB 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB1 periph A */ - AT91_PIOB 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB2 periph A */ - AT91_PIOB 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB3 periph A */ - AT91_PIOB 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB4 periph A */ - AT91_PIOB 5 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB5 periph A */ - AT91_PIOB 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB6 periph A */ - AT91_PIOB 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB7 periph A */ - AT91_PIOB 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB9 periph A */ - AT91_PIOB 10 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB10 periph A */ - }; - - pinctrl_macb0_rmii_mii: macb0_rmii_mii-0 { - atmel,pins = - <AT91_PIOB 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB8 periph A */ - AT91_PIOB 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB11 periph A */ - AT91_PIOB 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB12 periph A */ - AT91_PIOB 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB13 periph A */ - AT91_PIOB 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB14 periph A */ - AT91_PIOB 15 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB15 periph A */ - AT91_PIOB 16 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB16 periph A */ - AT91_PIOB 17 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB17 periph A */ - }; - }; - mmc0 { pinctrl_mmc0_slot0_clk_cmd_dat0: mmc0_slot0_clk_cmd_dat0-0 { atmel,pins = @@ -610,22 +559,6 @@ status = "disabled"; }; - macb0: ethernet@f802c000 { - compatible = "cdns,at32ap7000-macb", "cdns,macb"; - reg = <0xf802c000 0x100>; - interrupts = <24 IRQ_TYPE_LEVEL_HIGH 3>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_macb0_rmii>; - status = "disabled"; - }; - - macb1: ethernet@f8030000 { - compatible = "cdns,at32ap7000-macb", "cdns,macb"; - reg = <0xf8030000 0x100>; - interrupts = <27 IRQ_TYPE_LEVEL_HIGH 3>; - status = "disabled"; - }; - i2c0: i2c@f8010000 { compatible = "atmel,at91sam9x5-i2c"; reg = <0xf8010000 0x100>; diff --git a/arch/arm/boot/dts/at91sam9x5_macb0.dtsi b/arch/arm/boot/dts/at91sam9x5_macb0.dtsi new file mode 100644 index 000000000000..55731ffba764 --- /dev/null +++ b/arch/arm/boot/dts/at91sam9x5_macb0.dtsi @@ -0,0 +1,56 @@ +/* + * at91sam9x5_macb0.dtsi - Device Tree Include file for AT91SAM9x5 SoC with 1 + * Ethernet interface. + * + * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com> + * + * Licensed under GPLv2. + */ + +#include <dt-bindings/pinctrl/at91.h> +#include <dt-bindings/interrupt-controller/irq.h> + +/ { + ahb { + apb { + pinctrl@fffff400 { + macb0 { + pinctrl_macb0_rmii: macb0_rmii-0 { + atmel,pins = + <AT91_PIOB 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB0 periph A */ + AT91_PIOB 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB1 periph A */ + AT91_PIOB 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB2 periph A */ + AT91_PIOB 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB3 periph A */ + AT91_PIOB 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB4 periph A */ + AT91_PIOB 5 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB5 periph A */ + AT91_PIOB 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB6 periph A */ + AT91_PIOB 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB7 periph A */ + AT91_PIOB 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB9 periph A */ + AT91_PIOB 10 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB10 periph A */ + }; + + pinctrl_macb0_rmii_mii: macb0_rmii_mii-0 { + atmel,pins = + <AT91_PIOB 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB8 periph A */ + AT91_PIOB 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB11 periph A */ + AT91_PIOB 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB12 periph A */ + AT91_PIOB 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB13 periph A */ + AT91_PIOB 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB14 periph A */ + AT91_PIOB 15 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB15 periph A */ + AT91_PIOB 16 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB16 periph A */ + AT91_PIOB 17 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB17 periph A */ + }; + }; + }; + + macb0: ethernet@f802c000 { + compatible = "cdns,at32ap7000-macb", "cdns,macb"; + reg = <0xf802c000 0x100>; + interrupts = <24 IRQ_TYPE_LEVEL_HIGH 3>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_macb0_rmii>; + status = "disabled"; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/at91sam9x5_macb1.dtsi b/arch/arm/boot/dts/at91sam9x5_macb1.dtsi new file mode 100644 index 000000000000..77425a627a94 --- /dev/null +++ b/arch/arm/boot/dts/at91sam9x5_macb1.dtsi @@ -0,0 +1,44 @@ +/* + * at91sam9x5_macb1.dtsi - Device Tree Include file for AT91SAM9x5 SoC with 2 + * Ethernet interfaces. + * + * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com> + * + * Licensed under GPLv2. + */ + +#include <dt-bindings/pinctrl/at91.h> +#include <dt-bindings/interrupt-controller/irq.h> + +/ { + ahb { + apb { + pinctrl@fffff400 { + macb1 { + pinctrl_macb1_rmii: macb1_rmii-0 { + atmel,pins = + <AT91_PIOC 16 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC16 periph B */ + AT91_PIOC 18 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC18 periph B */ + AT91_PIOC 19 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC19 periph B */ + AT91_PIOC 20 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC20 periph B */ + AT91_PIOC 21 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC21 periph B */ + AT91_PIOC 27 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC27 periph B */ + AT91_PIOC 28 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC28 periph B */ + AT91_PIOC 29 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC29 periph B */ + AT91_PIOC 30 AT91_PERIPH_B AT91_PINCTRL_NONE /* PC30 periph B */ + AT91_PIOC 31 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PC31 periph B */ + }; + }; + }; + + macb1: ethernet@f8030000 { + compatible = "cdns,at32ap7000-macb", "cdns,macb"; + reg = <0xf8030000 0x100>; + interrupts = <27 IRQ_TYPE_LEVEL_HIGH 3>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_macb1_rmii>; + status = "disabled"; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/at91sam9x5_usart3.dtsi b/arch/arm/boot/dts/at91sam9x5_usart3.dtsi new file mode 100644 index 000000000000..2347e9563cef --- /dev/null +++ b/arch/arm/boot/dts/at91sam9x5_usart3.dtsi @@ -0,0 +1,51 @@ +/* + * at91sam9x5_usart3.dtsi - Device Tree Include file for AT91SAM9x5 SoC with + * 4 USART. + * + * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com> + * + * Licensed under GPLv2. + */ + +#include <dt-bindings/pinctrl/at91.h> +#include <dt-bindings/interrupt-controller/irq.h> + +/ { + ahb { + apb { + pinctrl@fffff400 { + usart3 { + pinctrl_usart3: usart3-0 { + atmel,pins = + <AT91_PIOC 22 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* PC22 periph B with pullup */ + AT91_PIOC 23 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PC23 periph B */ + }; + + pinctrl_usart3_rts: usart3_rts-0 { + atmel,pins = + <AT91_PIOC 24 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PC24 periph B */ + }; + + pinctrl_usart3_cts: usart3_cts-0 { + atmel,pins = + <AT91_PIOC 25 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PC25 periph B */ + }; + + pinctrl_usart3_sck: usart3_sck-0 { + atmel,pins = + <AT91_PIOC 26 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PC26 periph B */ + }; + }; + }; + + usart3: serial@f8028000 { + compatible = "atmel,at91sam9260-usart"; + reg = <0xf8028000 0x200>; + interrupts = <8 IRQ_TYPE_LEVEL_HIGH 5>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usart3>; + status = "disabled"; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/atlas6.dtsi b/arch/arm/boot/dts/atlas6.dtsi index 6db4f81d4795..978bab4991df 100644 --- a/arch/arm/boot/dts/atlas6.dtsi +++ b/arch/arm/boot/dts/atlas6.dtsi @@ -65,6 +65,11 @@ compatible = "sirf,prima2-rsc"; reg = <0x88020000 0x1000>; }; + + cphifbg@88030000 { + compatible = "sirf,prima2-cphifbg"; + reg = <0x88030000 0x1000>; + }; }; mem-iobg { @@ -75,10 +80,17 @@ memory-controller@90000000 { compatible = "sirf,prima2-memc"; - reg = <0x90000000 0x10000>; + reg = <0x90000000 0x2000>; interrupts = <27>; clocks = <&clks 5>; }; + + memc-monitor { + compatible = "sirf,prima2-memcmon"; + reg = <0x90002000 0x200>; + interrupts = <4>; + clocks = <&clks 32>; + }; }; disp-iobg { @@ -120,6 +132,20 @@ }; }; + graphics2d-iobg { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0xa0000000 0xa0000000 0x8000000>; + + ble@a0000000 { + compatible = "sirf,atlas6-ble"; + reg = <0xa0000000 0x2000>; + interrupts = <5>; + clocks = <&clks 33>; + }; + }; + dsp-iobg { compatible = "simple-bus"; #address-cells = <1>; @@ -271,6 +297,11 @@ compatible = "sirf,prima2-spi"; reg = <0xb0170000 0x10000>; interrupts = <16>; + sirf,spi-num-chipselects = <1>; + sirf,spi-dma-rx-channel = <12>; + sirf,spi-dma-tx-channel = <13>; + #address-cells = <1>; + #size-cells = <0>; clocks = <&clks 20>; status = "disabled"; }; @@ -527,6 +558,18 @@ sirf,function = "usb1_utmi_drvbus"; }; }; + usb1_dp_dn_pins_a: usb1_dp_dn@0 { + usb1_dp_dn { + sirf,pins = "usb1_dp_dngrp"; + sirf,function = "usb1_dp_dn"; + }; + }; + uart1_route_io_usb1_pins_a: uart1_route_io_usb1@0 { + uart1_route_io_usb1 { + sirf,pins = "uart1_route_io_usb1grp"; + sirf,function = "uart1_route_io_usb1"; + }; + }; warm_rst_pins_a: warm_rst@0 { warm_rst { sirf,pins = "warm_rstgrp"; diff --git a/arch/arm/boot/dts/bcm11351-brt.dts b/arch/arm/boot/dts/bcm11351-brt.dts index 9d36eb4e3c41..23cd16d736bf 100644 --- a/arch/arm/boot/dts/bcm11351-brt.dts +++ b/arch/arm/boot/dts/bcm11351-brt.dts @@ -40,6 +40,7 @@ sdio4: sdio@3f1b0000 { max-frequency = <48000000>; + cd-gpios = <&gpio 14 0>; status = "okay"; }; diff --git a/arch/arm/boot/dts/bcm11351.dtsi b/arch/arm/boot/dts/bcm11351.dtsi index 05a5aabe3b2c..b0c0610d1395 100644 --- a/arch/arm/boot/dts/bcm11351.dtsi +++ b/arch/arm/boot/dts/bcm11351.dtsi @@ -49,6 +49,36 @@ reg-io-width = <4>; }; + uart@3e001000 { + compatible = "brcm,bcm11351-dw-apb-uart", "snps,dw-apb-uart"; + status = "disabled"; + reg = <0x3e001000 0x1000>; + clock-frequency = <13000000>; + interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>; + reg-shift = <2>; + reg-io-width = <4>; + }; + + uart@3e002000 { + compatible = "brcm,bcm11351-dw-apb-uart", "snps,dw-apb-uart"; + status = "disabled"; + reg = <0x3e002000 0x1000>; + clock-frequency = <13000000>; + interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>; + reg-shift = <2>; + reg-io-width = <4>; + }; + + uart@3e003000 { + compatible = "brcm,bcm11351-dw-apb-uart", "snps,dw-apb-uart"; + status = "disabled"; + reg = <0x3e003000 0x1000>; + clock-frequency = <13000000>; + interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>; + reg-shift = <2>; + reg-io-width = <4>; + }; + L2: l2-cache { compatible = "brcm,bcm11351-a2-pl310-cache"; reg = <0x3ff20000 0x1000>; @@ -68,31 +98,47 @@ clock-frequency = <32768>; }; + gpio: gpio@35003000 { + compatible = "brcm,bcm11351-gpio", "brcm,kona-gpio"; + reg = <0x35003000 0x800>; + interrupts = + <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>; + #gpio-cells = <2>; + #interrupt-cells = <2>; + gpio-controller; + interrupt-controller; + }; + sdio1: sdio@3f180000 { compatible = "brcm,kona-sdhci"; reg = <0x3f180000 0x10000>; - interrupts = <0x0 77 0x4>; + interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; }; sdio2: sdio@3f190000 { compatible = "brcm,kona-sdhci"; reg = <0x3f190000 0x10000>; - interrupts = <0x0 76 0x4>; + interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; }; sdio3: sdio@3f1a0000 { compatible = "brcm,kona-sdhci"; reg = <0x3f1a0000 0x10000>; - interrupts = <0x0 74 0x4>; + interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; }; sdio4: sdio@3f1b0000 { compatible = "brcm,kona-sdhci"; reg = <0x3f1b0000 0x10000>; - interrupts = <0x0 73 0x4>; + interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/bcm28155-ap.dts b/arch/arm/boot/dts/bcm28155-ap.dts index 96ae67a2f0d3..08e47c285227 100644 --- a/arch/arm/boot/dts/bcm28155-ap.dts +++ b/arch/arm/boot/dts/bcm28155-ap.dts @@ -40,6 +40,7 @@ sdio4: sdio@3f1b0000 { max-frequency = <48000000>; + cd-gpios = <&gpio 14 0>; status = "okay"; }; }; diff --git a/arch/arm/boot/dts/dove-cm-a510.dts b/arch/arm/boot/dts/dove-cm-a510.dts index 61a8062e56de..50c0d6904497 100644 --- a/arch/arm/boot/dts/dove-cm-a510.dts +++ b/arch/arm/boot/dts/dove-cm-a510.dts @@ -1,6 +1,6 @@ /dts-v1/; -/include/ "dove.dtsi" +#include "dove.dtsi" / { model = "Compulab CM-A510"; diff --git a/arch/arm/boot/dts/dove-cubox.dts b/arch/arm/boot/dts/dove-cubox.dts index 022646ef4b38..8349a248ecea 100644 --- a/arch/arm/boot/dts/dove-cubox.dts +++ b/arch/arm/boot/dts/dove-cubox.dts @@ -1,6 +1,6 @@ /dts-v1/; -/include/ "dove.dtsi" +#include "dove.dtsi" / { model = "SolidRun CuBox"; @@ -99,18 +99,12 @@ silabs,pll-master; }; - clkout1 { - reg = <1>; - silabs,drive-strength = <8>; - silabs,multisynth-source = <1>; - silabs,clock-source = <0>; - silabs,pll-master; - }; - clkout2 { reg = <2>; + silabs,drive-strength = <8>; silabs,multisynth-source = <1>; silabs,clock-source = <0>; + silabs,pll-master; }; }; }; @@ -132,3 +126,11 @@ reg = <0>; }; }; + +&audio1 { + status = "okay"; + clocks = <&gate_clk 13>, <&si5351 2>; + clock-names = "internal", "extclk"; + pinctrl-0 = <&pmx_audio1_i2s1_spdifo &pmx_audio1_extclk>; + pinctrl-names = "default"; +}; diff --git a/arch/arm/boot/dts/dove-d2plug.dts b/arch/arm/boot/dts/dove-d2plug.dts index e2222ce94f2f..c11d3636c8e5 100644 --- a/arch/arm/boot/dts/dove-d2plug.dts +++ b/arch/arm/boot/dts/dove-d2plug.dts @@ -1,6 +1,6 @@ /dts-v1/; -/include/ "dove.dtsi" +#include "dove.dtsi" / { model = "Globalscale D2Plug"; diff --git a/arch/arm/boot/dts/dove-d3plug.dts b/arch/arm/boot/dts/dove-d3plug.dts new file mode 100644 index 000000000000..f5f59bb5a534 --- /dev/null +++ b/arch/arm/boot/dts/dove-d3plug.dts @@ -0,0 +1,103 @@ +/dts-v1/; + +#include "dove.dtsi" + +/ { + model = "Globalscale D3Plug"; + compatible = "globalscale,d3plug", "marvell,dove"; + + memory { + device_type = "memory"; + reg = <0x00000000 0x40000000>; + }; + + chosen { + bootargs = "console=ttyS0,115200n8 earlyprintk root=/dev/mmcblk0p2 rw rootwait"; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-0 = <&pmx_gpio_0 &pmx_gpio_1 &pmx_gpio_2>; + pinctrl-names = "default"; + + wlan-act { + label = "wlan-act"; + gpios = <&gpio0 0 1>; + }; + + wlan-ap { + label = "wlan-ap"; + gpios = <&gpio0 1 1>; + }; + + status { + label = "status"; + gpios = <&gpio0 2 1>; + }; + }; + + regulators { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + usb_power: regulator@1 { + compatible = "regulator-fixed"; + reg = <1>; + regulator-name = "USB Power"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + regulator-always-on; + regulator-boot-on; + gpio = <&gpio0 8 0>; + pinctrl-0 = <&pmx_gpio_8>; + pinctrl-names = "default"; + }; + }; +}; + +&uart0 { status = "okay"; }; +&sata0 { status = "okay"; }; +&i2c0 { status = "okay"; }; + +/* Samsung M8G2F eMMC */ +&sdio0 { + status = "okay"; + non-removable; + bus-width = <4>; +}; + +/* Marvell SD8787 WLAN/BT */ +&sdio1 { + status = "okay"; + non-removable; +}; + +&spi0 { + status = "okay"; + + /* spi0.0: 2M Flash Macronix MX25L1605D */ + spi-flash@0 { + compatible = "st,m25l1605d"; + spi-max-frequency = <86000000>; + reg = <0>; + }; +}; + +&pcie { + status = "okay"; + /* Fresco Logic USB3.0 xHCI controller */ + pcie-port@0 { + status = "okay"; + reset-gpios = <&gpio0 26 1>; + reset-delay-us = <20000>; + pinctrl-0 = <&pmx_camera_gpio>; + pinctrl-names = "default"; + }; + /* Mini-PCIe slot */ + pcie-port@1 { + status = "okay"; + reset-gpios = <&gpio0 25 1>; + }; +}; diff --git a/arch/arm/boot/dts/dove-dove-db.dts b/arch/arm/boot/dts/dove-dove-db.dts index e5a920beab45..bb725dca3a10 100644 --- a/arch/arm/boot/dts/dove-dove-db.dts +++ b/arch/arm/boot/dts/dove-dove-db.dts @@ -1,6 +1,6 @@ /dts-v1/; -/include/ "dove.dtsi" +#include "dove.dtsi" / { model = "Marvell DB-MV88AP510-BP Development Board"; diff --git a/arch/arm/boot/dts/dove.dtsi b/arch/arm/boot/dts/dove.dtsi index cc279166646f..113a8bc7bee7 100644 --- a/arch/arm/boot/dts/dove.dtsi +++ b/arch/arm/boot/dts/dove.dtsi @@ -1,8 +1,11 @@ /include/ "skeleton.dtsi" +#define MBUS_ID(target,attributes) (((target) << 24) | ((attributes) << 16)) + / { compatible = "marvell,dove"; model = "Marvell Armada 88AP510 SoC"; + interrupt-parent = <&intc>; aliases { gpio0 = &gpio0; @@ -27,482 +30,576 @@ marvell,tauros2-cache-features = <0>; }; - soc@f1000000 { - compatible = "simple-bus"; - #address-cells = <1>; + mbus { + compatible = "marvell,dove-mbus", "marvell,mbus", "simple-bus"; + #address-cells = <2>; #size-cells = <1>; - interrupt-parent = <&intc>; - - ranges = <0xc8000000 0xc8000000 0x0100000 /* CESA SRAM 1M */ - 0xe0000000 0xe0000000 0x8000000 /* PCIe0 Mem 128M */ - 0xe8000000 0xe8000000 0x8000000 /* PCIe1 Mem 128M */ - 0xf0000000 0xf0000000 0x0100000 /* ScratchPad 1M */ - 0x00000000 0xf1000000 0x1000000 /* SB/NB regs 16M */ - 0xf2000000 0xf2000000 0x0100000 /* PCIe0 I/O 1M */ - 0xf2100000 0xf2100000 0x0100000 /* PCIe0 I/O 1M */ - 0xf8000000 0xf8000000 0x8000000>; /* BootROM 128M */ - - timer: timer@20300 { - compatible = "marvell,orion-timer"; - reg = <0x20300 0x20>; - interrupt-parent = <&bridge_intc>; - interrupts = <1>, <2>; - clocks = <&core_clk 0>; - }; - - intc: main-interrupt-ctrl@20200 { - compatible = "marvell,orion-intc"; - interrupt-controller; - #interrupt-cells = <1>; - reg = <0x20200 0x10>, <0x20210 0x10>; - }; - - bridge_intc: bridge-interrupt-ctrl@20110 { - compatible = "marvell,orion-bridge-intc"; - interrupt-controller; - #interrupt-cells = <1>; - reg = <0x20110 0x8>; - interrupts = <0>; - marvell,#interrupts = <5>; - }; - - core_clk: core-clocks@d0214 { - compatible = "marvell,dove-core-clock"; - reg = <0xd0214 0x4>; - #clock-cells = <1>; - }; - - gate_clk: clock-gating-ctrl@d0038 { - compatible = "marvell,dove-gating-clock"; - reg = <0xd0038 0x4>; - clocks = <&core_clk 0>; - #clock-cells = <1>; - }; - - thermal: thermal-diode@d001c { - compatible = "marvell,dove-thermal"; - reg = <0xd001c 0x0c>, <0xd005c 0x08>; - }; - - uart0: serial@12000 { - compatible = "ns16550a"; - reg = <0x12000 0x100>; - reg-shift = <2>; - interrupts = <7>; - clocks = <&core_clk 0>; - status = "disabled"; - }; - - uart1: serial@12100 { - compatible = "ns16550a"; - reg = <0x12100 0x100>; - reg-shift = <2>; - interrupts = <8>; - clocks = <&core_clk 0>; - pinctrl-0 = <&pmx_uart1>; - pinctrl-names = "default"; - status = "disabled"; - }; - - uart2: serial@12200 { - compatible = "ns16550a"; - reg = <0x12000 0x100>; - reg-shift = <2>; - interrupts = <9>; - clocks = <&core_clk 0>; + controller = <&mbusc>; + pcie-mem-aperture = <0xe0000000 0x10000000>; /* 256M MEM space */ + pcie-io-aperture = <0xf2000000 0x00200000>; /* 2M I/O space */ + + ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x0100000 /* MBUS regs 1M */ + MBUS_ID(0xf0, 0x02) 0 0xf1800000 0x1000000 /* AXI regs 16M */ + MBUS_ID(0x01, 0xfd) 0 0xf8000000 0x8000000 /* BootROM 128M */ + MBUS_ID(0x03, 0x01) 0 0xc8000000 0x0100000 /* CESA SRAM 1M */ + MBUS_ID(0x0d, 0x00) 0 0xf0000000 0x0100000>; /* PMU SRAM 1M */ + + pcie: pcie-controller { + compatible = "marvell,dove-pcie"; status = "disabled"; - }; - - uart3: serial@12300 { - compatible = "ns16550a"; - reg = <0x12100 0x100>; - reg-shift = <2>; - interrupts = <10>; - clocks = <&core_clk 0>; - status = "disabled"; - }; - - gpio0: gpio-ctrl@d0400 { - compatible = "marvell,orion-gpio"; - #gpio-cells = <2>; - gpio-controller; - reg = <0xd0400 0x20>; - ngpios = <32>; - interrupt-controller; - #interrupt-cells = <2>; - interrupts = <12>, <13>, <14>, <60>; - }; - - gpio1: gpio-ctrl@d0420 { - compatible = "marvell,orion-gpio"; - #gpio-cells = <2>; - gpio-controller; - reg = <0xd0420 0x20>; - ngpios = <32>; - interrupt-controller; - #interrupt-cells = <2>; - interrupts = <61>; - }; - - gpio2: gpio-ctrl@e8400 { - compatible = "marvell,orion-gpio"; - #gpio-cells = <2>; - gpio-controller; - reg = <0xe8400 0x0c>; - ngpios = <8>; - }; - - pinctrl: pin-ctrl@d0200 { - compatible = "marvell,dove-pinctrl"; - reg = <0xd0200 0x10>; - clocks = <&gate_clk 22>; - - pmx_gpio_0: pmx-gpio-0 { - marvell,pins = "mpp0"; - marvell,function = "gpio"; - }; - - pmx_gpio_1: pmx-gpio-1 { - marvell,pins = "mpp1"; - marvell,function = "gpio"; - }; - - pmx_gpio_2: pmx-gpio-2 { - marvell,pins = "mpp2"; - marvell,function = "gpio"; - }; - - pmx_gpio_3: pmx-gpio-3 { - marvell,pins = "mpp3"; - marvell,function = "gpio"; + device_type = "pci"; + #address-cells = <3>; + #size-cells = <2>; + + msi-parent = <&intc>; + bus-range = <0x00 0xff>; + + ranges = <0x82000000 0x0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x2000 + 0x82000000 0x0 0x80000 MBUS_ID(0xf0, 0x01) 0x80000 0 0x2000 + 0x82000000 0x1 0x0 MBUS_ID(0x04, 0xe8) 0 1 0 /* Port 0.0 Mem */ + 0x81000000 0x1 0x0 MBUS_ID(0x04, 0xe0) 0 1 0 /* Port 0.0 I/O */ + 0x82000000 0x2 0x0 MBUS_ID(0x08, 0xe8) 0 1 0 /* Port 1.0 Mem */ + 0x81000000 0x2 0x0 MBUS_ID(0x08, 0xe0) 0 1 0>; /* Port 1.0 I/O */ + + pcie-port@0 { + device_type = "pci"; + status = "disabled"; + assigned-addresses = <0x82000800 0 0x40000 0 0x2000>; + reg = <0x0800 0 0 0 0>; + clocks = <&gate_clk 4>; + marvell,pcie-port = <0>; + + #address-cells = <3>; + #size-cells = <2>; + ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0 + 0x81000000 0 0 0x81000000 0x1 0 1 0>; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &intc 16>; + }; + + pcie-port@1 { + device_type = "pci"; + status = "disabled"; + assigned-addresses = <0x82002800 0 0x80000 0 0x2000>; + reg = <0x1000 0 0 0 0>; + clocks = <&gate_clk 5>; + marvell,pcie-port = <1>; + + #address-cells = <3>; + #size-cells = <2>; + ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0 + 0x81000000 0 0 0x81000000 0x2 0 1 0>; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &intc 18>; }; - - pmx_gpio_4: pmx-gpio-4 { - marvell,pins = "mpp4"; - marvell,function = "gpio"; - }; - - pmx_gpio_5: pmx-gpio-5 { - marvell,pins = "mpp5"; - marvell,function = "gpio"; - }; - - pmx_gpio_6: pmx-gpio-6 { - marvell,pins = "mpp6"; - marvell,function = "gpio"; - }; - - pmx_gpio_7: pmx-gpio-7 { - marvell,pins = "mpp7"; - marvell,function = "gpio"; - }; - - pmx_gpio_8: pmx-gpio-8 { - marvell,pins = "mpp8"; - marvell,function = "gpio"; - }; - - pmx_gpio_9: pmx-gpio-9 { - marvell,pins = "mpp9"; - marvell,function = "gpio"; - }; - - pmx_gpio_10: pmx-gpio-10 { - marvell,pins = "mpp10"; - marvell,function = "gpio"; - }; - - pmx_gpio_11: pmx-gpio-11 { - marvell,pins = "mpp11"; - marvell,function = "gpio"; - }; - - pmx_gpio_12: pmx-gpio-12 { - marvell,pins = "mpp12"; - marvell,function = "gpio"; - }; - - pmx_gpio_13: pmx-gpio-13 { - marvell,pins = "mpp13"; - marvell,function = "gpio"; - }; - - pmx_gpio_14: pmx-gpio-14 { - marvell,pins = "mpp14"; - marvell,function = "gpio"; - }; - - pmx_gpio_15: pmx-gpio-15 { - marvell,pins = "mpp15"; - marvell,function = "gpio"; - }; - - pmx_gpio_16: pmx-gpio-16 { - marvell,pins = "mpp16"; - marvell,function = "gpio"; - }; - - pmx_gpio_17: pmx-gpio-17 { - marvell,pins = "mpp17"; - marvell,function = "gpio"; - }; - - pmx_gpio_18: pmx-gpio-18 { - marvell,pins = "mpp18"; - marvell,function = "gpio"; - }; - - pmx_gpio_19: pmx-gpio-19 { - marvell,pins = "mpp19"; - marvell,function = "gpio"; - }; - - pmx_gpio_20: pmx-gpio-20 { - marvell,pins = "mpp20"; - marvell,function = "gpio"; - }; - - pmx_gpio_21: pmx-gpio-21 { - marvell,pins = "mpp21"; - marvell,function = "gpio"; - }; - - pmx_camera: pmx-camera { - marvell,pins = "mpp_camera"; - marvell,function = "camera"; - }; - - pmx_camera_gpio: pmx-camera-gpio { - marvell,pins = "mpp_camera"; - marvell,function = "gpio"; - }; - - pmx_sdio0: pmx-sdio0 { - marvell,pins = "mpp_sdio0"; - marvell,function = "sdio0"; - }; - - pmx_sdio0_gpio: pmx-sdio0-gpio { - marvell,pins = "mpp_sdio0"; - marvell,function = "gpio"; - }; - - pmx_sdio1: pmx-sdio1 { - marvell,pins = "mpp_sdio1"; - marvell,function = "sdio1"; - }; - - pmx_sdio1_gpio: pmx-sdio1-gpio { - marvell,pins = "mpp_sdio1"; - marvell,function = "gpio"; - }; - - pmx_audio1_gpio: pmx-audio1-gpio { - marvell,pins = "mpp_audio1"; - marvell,function = "gpio"; - }; - - pmx_spi0: pmx-spi0 { - marvell,pins = "mpp_spi0"; - marvell,function = "spi0"; - }; - - pmx_spi0_gpio: pmx-spi0-gpio { - marvell,pins = "mpp_spi0"; - marvell,function = "gpio"; - }; - - pmx_uart1: pmx-uart1 { - marvell,pins = "mpp_uart1"; - marvell,function = "uart1"; - }; - - pmx_uart1_gpio: pmx-uart1-gpio { - marvell,pins = "mpp_uart1"; - marvell,function = "gpio"; - }; - - pmx_nand: pmx-nand { - marvell,pins = "mpp_nand"; - marvell,function = "nand"; - }; - - pmx_nand_gpo: pmx-nand-gpo { - marvell,pins = "mpp_nand"; - marvell,function = "gpo"; - }; - }; - - spi0: spi-ctrl@10600 { - compatible = "marvell,orion-spi"; - #address-cells = <1>; - #size-cells = <0>; - cell-index = <0>; - interrupts = <6>; - reg = <0x10600 0x28>; - clocks = <&core_clk 0>; - pinctrl-0 = <&pmx_spi0>; - pinctrl-names = "default"; - status = "disabled"; - }; - - spi1: spi-ctrl@14600 { - compatible = "marvell,orion-spi"; - #address-cells = <1>; - #size-cells = <0>; - cell-index = <1>; - interrupts = <5>; - reg = <0x14600 0x28>; - clocks = <&core_clk 0>; - status = "disabled"; - }; - - i2c0: i2c-ctrl@11000 { - compatible = "marvell,mv64xxx-i2c"; - reg = <0x11000 0x20>; - #address-cells = <1>; - #size-cells = <0>; - interrupts = <11>; - clock-frequency = <400000>; - timeout-ms = <1000>; - clocks = <&core_clk 0>; - status = "disabled"; }; - ehci0: usb-host@50000 { - compatible = "marvell,orion-ehci"; - reg = <0x50000 0x1000>; - interrupts = <24>; - clocks = <&gate_clk 0>; - status = "okay"; - }; - - ehci1: usb-host@51000 { - compatible = "marvell,orion-ehci"; - reg = <0x51000 0x1000>; - interrupts = <25>; - clocks = <&gate_clk 1>; - status = "okay"; - }; - - sdio0: sdio-host@92000 { - compatible = "marvell,dove-sdhci"; - reg = <0x92000 0x100>; - interrupts = <35>, <37>; - clocks = <&gate_clk 8>; - pinctrl-0 = <&pmx_sdio0>; - pinctrl-names = "default"; - status = "disabled"; - }; - - sdio1: sdio-host@90000 { - compatible = "marvell,dove-sdhci"; - reg = <0x90000 0x100>; - interrupts = <36>, <38>; - clocks = <&gate_clk 9>; - pinctrl-0 = <&pmx_sdio1>; - pinctrl-names = "default"; - status = "disabled"; - }; - - sata0: sata-host@a0000 { - compatible = "marvell,orion-sata"; - reg = <0xa0000 0x2400>; - interrupts = <62>; - clocks = <&gate_clk 3>; - nr-ports = <1>; - status = "disabled"; - }; - - rtc: real-time-clock@d8500 { - compatible = "marvell,orion-rtc"; - reg = <0xd8500 0x20>; - }; - - crypto: crypto-engine@30000 { - compatible = "marvell,orion-crypto"; - reg = <0x30000 0x10000>, - <0xc8000000 0x800>; - reg-names = "regs", "sram"; - interrupts = <31>; - clocks = <&gate_clk 15>; - status = "okay"; - }; - - xor0: dma-engine@60800 { - compatible = "marvell,orion-xor"; - reg = <0x60800 0x100 - 0x60a00 0x100>; - clocks = <&gate_clk 23>; - status = "okay"; - - channel0 { - interrupts = <39>; - dmacap,memcpy; - dmacap,xor; - }; - - channel1 { - interrupts = <40>; - dmacap,memset; - dmacap,memcpy; - dmacap,xor; - }; - }; - - xor1: dma-engine@60900 { - compatible = "marvell,orion-xor"; - reg = <0x60900 0x100 - 0x60b00 0x100>; - clocks = <&gate_clk 24>; - status = "okay"; - - channel0 { - interrupts = <42>; - dmacap,memcpy; - dmacap,xor; - }; - - channel1 { - interrupts = <43>; - dmacap,memset; - dmacap,memcpy; - dmacap,xor; - }; - }; - - mdio: mdio-bus@72004 { - compatible = "marvell,orion-mdio"; + internal-regs { + compatible = "simple-bus"; #address-cells = <1>; - #size-cells = <0>; - reg = <0x72004 0x84>; - interrupts = <30>; - clocks = <&gate_clk 2>; - status = "disabled"; - - ethphy: ethernet-phy { - device-type = "ethernet-phy"; - /* set phy address in board file */ - }; - }; - - eth: ethernet-controller@72000 { - compatible = "marvell,orion-eth"; - #address-cells = <1>; - #size-cells = <0>; - reg = <0x72000 0x4000>; - clocks = <&gate_clk 2>; - marvell,tx-checksum-limit = <1600>; - status = "disabled"; - - ethernet-port@0 { - device_type = "network"; - compatible = "marvell,orion-eth-port"; - reg = <0>; - interrupts = <29>; - /* overwrite MAC address in bootloader */ - local-mac-address = [00 00 00 00 00 00]; - phy-handle = <ðphy>; + #size-cells = <1>; + ranges = <0x00000000 MBUS_ID(0xf0, 0x01) 0 0x0100000 /* MBUS regs 1M */ + 0x00800000 MBUS_ID(0xf0, 0x02) 0 0x1000000 /* AXI regs 16M */ + 0xffffe000 MBUS_ID(0x03, 0x01) 0 0x0000800 /* CESA SRAM 2k */ + 0xfffff000 MBUS_ID(0x0d, 0x00) 0 0x0000800>; /* PMU SRAM 2k */ + + mbusc: mbus-ctrl@20000 { + compatible = "marvell,mbus-controller"; + reg = <0x20000 0x80>, <0x800100 0x8>; + }; + + timer: timer@20300 { + compatible = "marvell,orion-timer"; + reg = <0x20300 0x20>; + interrupt-parent = <&bridge_intc>; + interrupts = <1>, <2>; + clocks = <&core_clk 0>; + }; + + intc: main-interrupt-ctrl@20200 { + compatible = "marvell,orion-intc"; + interrupt-controller; + #interrupt-cells = <1>; + reg = <0x20200 0x10>, <0x20210 0x10>; + }; + + bridge_intc: bridge-interrupt-ctrl@20110 { + compatible = "marvell,orion-bridge-intc"; + interrupt-controller; + #interrupt-cells = <1>; + reg = <0x20110 0x8>; + interrupts = <0>; + marvell,#interrupts = <5>; + }; + + core_clk: core-clocks@d0214 { + compatible = "marvell,dove-core-clock"; + reg = <0xd0214 0x4>; + #clock-cells = <1>; + }; + + gate_clk: clock-gating-ctrl@d0038 { + compatible = "marvell,dove-gating-clock"; + reg = <0xd0038 0x4>; + clocks = <&core_clk 0>; + #clock-cells = <1>; + }; + + thermal: thermal-diode@d001c { + compatible = "marvell,dove-thermal"; + reg = <0xd001c 0x0c>, <0xd005c 0x08>; + }; + + uart0: serial@12000 { + compatible = "ns16550a"; + reg = <0x12000 0x100>; + reg-shift = <2>; + interrupts = <7>; + clocks = <&core_clk 0>; + status = "disabled"; + }; + + uart1: serial@12100 { + compatible = "ns16550a"; + reg = <0x12100 0x100>; + reg-shift = <2>; + interrupts = <8>; + clocks = <&core_clk 0>; + pinctrl-0 = <&pmx_uart1>; + pinctrl-names = "default"; + status = "disabled"; + }; + + uart2: serial@12200 { + compatible = "ns16550a"; + reg = <0x12000 0x100>; + reg-shift = <2>; + interrupts = <9>; + clocks = <&core_clk 0>; + status = "disabled"; + }; + + uart3: serial@12300 { + compatible = "ns16550a"; + reg = <0x12100 0x100>; + reg-shift = <2>; + interrupts = <10>; + clocks = <&core_clk 0>; + status = "disabled"; + }; + + gpio0: gpio-ctrl@d0400 { + compatible = "marvell,orion-gpio"; + #gpio-cells = <2>; + gpio-controller; + reg = <0xd0400 0x20>; + ngpios = <32>; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = <12>, <13>, <14>, <60>; + }; + + gpio1: gpio-ctrl@d0420 { + compatible = "marvell,orion-gpio"; + #gpio-cells = <2>; + gpio-controller; + reg = <0xd0420 0x20>; + ngpios = <32>; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = <61>; + }; + + gpio2: gpio-ctrl@e8400 { + compatible = "marvell,orion-gpio"; + #gpio-cells = <2>; + gpio-controller; + reg = <0xe8400 0x0c>; + ngpios = <8>; + }; + + pinctrl: pin-ctrl@d0200 { + compatible = "marvell,dove-pinctrl"; + reg = <0xd0200 0x10>; + clocks = <&gate_clk 22>; + + pmx_gpio_0: pmx-gpio-0 { + marvell,pins = "mpp0"; + marvell,function = "gpio"; + }; + + pmx_gpio_1: pmx-gpio-1 { + marvell,pins = "mpp1"; + marvell,function = "gpio"; + }; + + pmx_gpio_2: pmx-gpio-2 { + marvell,pins = "mpp2"; + marvell,function = "gpio"; + }; + + pmx_gpio_3: pmx-gpio-3 { + marvell,pins = "mpp3"; + marvell,function = "gpio"; + }; + + pmx_gpio_4: pmx-gpio-4 { + marvell,pins = "mpp4"; + marvell,function = "gpio"; + }; + + pmx_gpio_5: pmx-gpio-5 { + marvell,pins = "mpp5"; + marvell,function = "gpio"; + }; + + pmx_gpio_6: pmx-gpio-6 { + marvell,pins = "mpp6"; + marvell,function = "gpio"; + }; + + pmx_gpio_7: pmx-gpio-7 { + marvell,pins = "mpp7"; + marvell,function = "gpio"; + }; + + pmx_gpio_8: pmx-gpio-8 { + marvell,pins = "mpp8"; + marvell,function = "gpio"; + }; + + pmx_gpio_9: pmx-gpio-9 { + marvell,pins = "mpp9"; + marvell,function = "gpio"; + }; + + pmx_gpio_10: pmx-gpio-10 { + marvell,pins = "mpp10"; + marvell,function = "gpio"; + }; + + pmx_gpio_11: pmx-gpio-11 { + marvell,pins = "mpp11"; + marvell,function = "gpio"; + }; + + pmx_gpio_12: pmx-gpio-12 { + marvell,pins = "mpp12"; + marvell,function = "gpio"; + }; + + pmx_gpio_13: pmx-gpio-13 { + marvell,pins = "mpp13"; + marvell,function = "gpio"; + }; + + pmx_audio1_extclk: pmx-audio1-extclk { + marvell,pins = "mpp13"; + marvell,function = "audio1"; + }; + + pmx_gpio_14: pmx-gpio-14 { + marvell,pins = "mpp14"; + marvell,function = "gpio"; + }; + + pmx_gpio_15: pmx-gpio-15 { + marvell,pins = "mpp15"; + marvell,function = "gpio"; + }; + + pmx_gpio_16: pmx-gpio-16 { + marvell,pins = "mpp16"; + marvell,function = "gpio"; + }; + + pmx_gpio_17: pmx-gpio-17 { + marvell,pins = "mpp17"; + marvell,function = "gpio"; + }; + + pmx_gpio_18: pmx-gpio-18 { + marvell,pins = "mpp18"; + marvell,function = "gpio"; + }; + + pmx_gpio_19: pmx-gpio-19 { + marvell,pins = "mpp19"; + marvell,function = "gpio"; + }; + + pmx_gpio_20: pmx-gpio-20 { + marvell,pins = "mpp20"; + marvell,function = "gpio"; + }; + + pmx_gpio_21: pmx-gpio-21 { + marvell,pins = "mpp21"; + marvell,function = "gpio"; + }; + + pmx_camera: pmx-camera { + marvell,pins = "mpp_camera"; + marvell,function = "camera"; + }; + + pmx_camera_gpio: pmx-camera-gpio { + marvell,pins = "mpp_camera"; + marvell,function = "gpio"; + }; + + pmx_sdio0: pmx-sdio0 { + marvell,pins = "mpp_sdio0"; + marvell,function = "sdio0"; + }; + + pmx_sdio0_gpio: pmx-sdio0-gpio { + marvell,pins = "mpp_sdio0"; + marvell,function = "gpio"; + }; + + pmx_sdio1: pmx-sdio1 { + marvell,pins = "mpp_sdio1"; + marvell,function = "sdio1"; + }; + + pmx_sdio1_gpio: pmx-sdio1-gpio { + marvell,pins = "mpp_sdio1"; + marvell,function = "gpio"; + }; + + pmx_audio1_gpio: pmx-audio1-gpio { + marvell,pins = "mpp_audio1"; + marvell,function = "gpio"; + }; + + pmx_audio1_i2s1_spdifo: pmx-audio1-i2s1-spdifo { + marvell,pins = "mpp_audio1"; + marvell,function = "i2s1/spdifo"; + }; + + pmx_spi0: pmx-spi0 { + marvell,pins = "mpp_spi0"; + marvell,function = "spi0"; + }; + + pmx_spi0_gpio: pmx-spi0-gpio { + marvell,pins = "mpp_spi0"; + marvell,function = "gpio"; + }; + + pmx_uart1: pmx-uart1 { + marvell,pins = "mpp_uart1"; + marvell,function = "uart1"; + }; + + pmx_uart1_gpio: pmx-uart1-gpio { + marvell,pins = "mpp_uart1"; + marvell,function = "gpio"; + }; + + pmx_nand: pmx-nand { + marvell,pins = "mpp_nand"; + marvell,function = "nand"; + }; + + pmx_nand_gpo: pmx-nand-gpo { + marvell,pins = "mpp_nand"; + marvell,function = "gpo"; + }; + }; + + spi0: spi-ctrl@10600 { + compatible = "marvell,orion-spi"; + #address-cells = <1>; + #size-cells = <0>; + cell-index = <0>; + interrupts = <6>; + reg = <0x10600 0x28>; + clocks = <&core_clk 0>; + pinctrl-0 = <&pmx_spi0>; + pinctrl-names = "default"; + status = "disabled"; + }; + + spi1: spi-ctrl@14600 { + compatible = "marvell,orion-spi"; + #address-cells = <1>; + #size-cells = <0>; + cell-index = <1>; + interrupts = <5>; + reg = <0x14600 0x28>; + clocks = <&core_clk 0>; + status = "disabled"; + }; + + i2c0: i2c-ctrl@11000 { + compatible = "marvell,mv64xxx-i2c"; + reg = <0x11000 0x20>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <11>; + clock-frequency = <400000>; + timeout-ms = <1000>; + clocks = <&core_clk 0>; + status = "disabled"; + }; + + ehci0: usb-host@50000 { + compatible = "marvell,orion-ehci"; + reg = <0x50000 0x1000>; + interrupts = <24>; + clocks = <&gate_clk 0>; + status = "okay"; + }; + + ehci1: usb-host@51000 { + compatible = "marvell,orion-ehci"; + reg = <0x51000 0x1000>; + interrupts = <25>; + clocks = <&gate_clk 1>; + status = "okay"; + }; + + sdio0: sdio-host@92000 { + compatible = "marvell,dove-sdhci"; + reg = <0x92000 0x100>; + interrupts = <35>, <37>; + clocks = <&gate_clk 8>; + pinctrl-0 = <&pmx_sdio0>; + pinctrl-names = "default"; + status = "disabled"; + }; + + sdio1: sdio-host@90000 { + compatible = "marvell,dove-sdhci"; + reg = <0x90000 0x100>; + interrupts = <36>, <38>; + clocks = <&gate_clk 9>; + pinctrl-0 = <&pmx_sdio1>; + pinctrl-names = "default"; + status = "disabled"; + }; + + sata0: sata-host@a0000 { + compatible = "marvell,orion-sata"; + reg = <0xa0000 0x2400>; + interrupts = <62>; + clocks = <&gate_clk 3>; + nr-ports = <1>; + status = "disabled"; + }; + + rtc: real-time-clock@d8500 { + compatible = "marvell,orion-rtc"; + reg = <0xd8500 0x20>; + }; + + crypto: crypto-engine@30000 { + compatible = "marvell,orion-crypto"; + reg = <0x30000 0x10000>, + <0xffffe000 0x800>; + reg-names = "regs", "sram"; + interrupts = <31>; + clocks = <&gate_clk 15>; + status = "okay"; + }; + + xor0: dma-engine@60800 { + compatible = "marvell,orion-xor"; + reg = <0x60800 0x100 + 0x60a00 0x100>; + clocks = <&gate_clk 23>; + status = "okay"; + + channel0 { + interrupts = <39>; + dmacap,memcpy; + dmacap,xor; + }; + + channel1 { + interrupts = <40>; + dmacap,memcpy; + dmacap,xor; + }; + }; + + xor1: dma-engine@60900 { + compatible = "marvell,orion-xor"; + reg = <0x60900 0x100 + 0x60b00 0x100>; + clocks = <&gate_clk 24>; + status = "okay"; + + channel0 { + interrupts = <42>; + dmacap,memcpy; + dmacap,xor; + }; + + channel1 { + interrupts = <43>; + dmacap,memcpy; + dmacap,xor; + }; + }; + + mdio: mdio-bus@72004 { + compatible = "marvell,orion-mdio"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x72004 0x84>; + interrupts = <30>; + clocks = <&gate_clk 2>; + status = "disabled"; + + ethphy: ethernet-phy { + device-type = "ethernet-phy"; + /* set phy address in board file */ + }; + }; + + eth: ethernet-ctrl@72000 { + compatible = "marvell,orion-eth"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x72000 0x4000>; + clocks = <&gate_clk 2>; + marvell,tx-checksum-limit = <1600>; + status = "disabled"; + + ethernet-port@0 { + device_type = "network"; + compatible = "marvell,orion-eth-port"; + reg = <0>; + interrupts = <29>; + /* overwrite MAC address in bootloader */ + local-mac-address = [00 00 00 00 00 00]; + phy-handle = <ðphy>; + }; + }; + + audio0: audio-controller@b0000 { + compatible = "marvell,dove-audio"; + reg = <0xb0000 0x2210>; + interrupts = <19>, <20>; + clocks = <&gate_clk 12>; + clock-names = "internal"; + status = "disabled"; + }; + + audio1: audio-controller@b4000 { + compatible = "marvell,dove-audio"; + reg = <0xb4000 0x2210>; + interrupts = <21>, <22>; + clocks = <&gate_clk 13>; + clock-names = "internal"; + status = "disabled"; }; }; }; diff --git a/arch/arm/boot/dts/dra7-evm.dts b/arch/arm/boot/dts/dra7-evm.dts new file mode 100644 index 000000000000..5babba0a3a75 --- /dev/null +++ b/arch/arm/boot/dts/dra7-evm.dts @@ -0,0 +1,275 @@ +/* + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.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 + * published by the Free Software Foundation. + */ +/dts-v1/; + +#include "dra7.dtsi" + +/ { + model = "TI DRA7"; + compatible = "ti,dra7-evm", "ti,dra752", "ti,dra7"; + + memory { + device_type = "memory"; + reg = <0x80000000 0x60000000>; /* 1536 MB */ + }; + + mmc2_3v3: fixedregulator-mmc2 { + compatible = "regulator-fixed"; + regulator-name = "mmc2_3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; +}; + +&dra7_pmx_core { + i2c1_pins: pinmux_i2c1_pins { + pinctrl-single,pins = < + 0x400 (PIN_INPUT | MUX_MODE0) /* i2c1_sda */ + 0x404 (PIN_INPUT | MUX_MODE0) /* i2c1_scl */ + >; + }; + + i2c2_pins: pinmux_i2c2_pins { + pinctrl-single,pins = < + 0x408 (PIN_INPUT | MUX_MODE0) /* i2c2_sda */ + 0x40c (PIN_INPUT | MUX_MODE0) /* i2c2_scl */ + >; + }; + + i2c3_pins: pinmux_i2c3_pins { + pinctrl-single,pins = < + 0x410 (PIN_INPUT | MUX_MODE0) /* i2c3_sda */ + 0x414 (PIN_INPUT | MUX_MODE0) /* i2c3_scl */ + >; + }; + + mcspi1_pins: pinmux_mcspi1_pins { + pinctrl-single,pins = < + 0x3a4 (PIN_INPUT | MUX_MODE0) /* spi2_clk */ + 0x3a8 (PIN_INPUT | MUX_MODE0) /* spi2_d1 */ + 0x3ac (PIN_INPUT | MUX_MODE0) /* spi2_d0 */ + 0x3b0 (PIN_INPUT_SLEW | MUX_MODE0) /* spi2_cs0 */ + 0x3b4 (PIN_INPUT_SLEW | MUX_MODE0) /* spi2_cs1 */ + 0x3b8 (PIN_INPUT_SLEW | MUX_MODE6) /* spi2_cs2 */ + 0x3bc (PIN_INPUT_SLEW | MUX_MODE6) /* spi2_cs3 */ + >; + }; + + mcspi2_pins: pinmux_mcspi2_pins { + pinctrl-single,pins = < + 0x3c0 (PIN_INPUT | MUX_MODE0) /* spi2_sclk */ + 0x3c4 (PIN_INPUT_SLEW | MUX_MODE0) /* spi2_d1 */ + 0x3c8 (PIN_INPUT_SLEW | MUX_MODE0) /* spi2_d1 */ + 0x3cc (PIN_INPUT_SLEW | MUX_MODE0) /* spi2_cs0 */ + >; + }; + + uart1_pins: pinmux_uart1_pins { + pinctrl-single,pins = < + 0x3e0 (PIN_INPUT_SLEW | MUX_MODE0) /* uart1_rxd */ + 0x3e4 (PIN_INPUT_SLEW | MUX_MODE0) /* uart1_txd */ + 0x3e8 (PIN_INPUT | MUX_MODE3) /* uart1_ctsn */ + 0x3ec (PIN_INPUT | MUX_MODE3) /* uart1_rtsn */ + >; + }; + + uart2_pins: pinmux_uart2_pins { + pinctrl-single,pins = < + 0x3f0 (PIN_INPUT | MUX_MODE0) /* uart2_rxd */ + 0x3f4 (PIN_INPUT | MUX_MODE0) /* uart2_txd */ + 0x3f8 (PIN_INPUT | MUX_MODE0) /* uart2_ctsn */ + 0x3fc (PIN_INPUT | MUX_MODE0) /* uart2_rtsn */ + >; + }; + + uart3_pins: pinmux_uart3_pins { + pinctrl-single,pins = < + 0x248 (PIN_INPUT_SLEW | MUX_MODE0) /* uart3_rxd */ + 0x24c (PIN_INPUT_SLEW | MUX_MODE0) /* uart3_txd */ + >; + }; +}; + +&i2c1 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; + clock-frequency = <400000>; + + tps659038: tps659038@58 { + compatible = "ti,tps659038"; + reg = <0x58>; + + tps659038_pmic { + compatible = "ti,tps659038-pmic"; + + regulators { + smps123_reg: smps123 { + /* VDD_MPU */ + regulator-name = "smps123"; + regulator-min-microvolt = < 850000>; + regulator-max-microvolt = <1250000>; + regulator-always-on; + regulator-boot-on; + }; + + smps45_reg: smps45 { + /* VDD_DSPEVE */ + regulator-name = "smps45"; + regulator-min-microvolt = < 850000>; + regulator-max-microvolt = <1150000>; + regulator-boot-on; + }; + + smps6_reg: smps6 { + /* VDD_GPU - over VDD_SMPS6 */ + regulator-name = "smps6"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <12500000>; + regulator-boot-on; + }; + + smps7_reg: smps7 { + /* CORE_VDD */ + regulator-name = "smps7"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <1030000>; + regulator-always-on; + regulator-boot-on; + }; + + smps8_reg: smps8 { + /* VDD_IVAHD */ + regulator-name = "smps8"; + regulator-min-microvolt = < 850000>; + regulator-max-microvolt = <1250000>; + regulator-boot-on; + }; + + smps9_reg: smps9 { + /* VDDS1V8 */ + regulator-name = "smps9"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + }; + + ldo1_reg: ldo1 { + /* LDO1_OUT --> SDIO */ + regulator-name = "ldo1"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + }; + + ldo2_reg: ldo2 { + /* VDD_RTCIO */ + /* LDO2 -> VDDSHV5, LDO2 also goes to CAN_PHY_3V3 */ + regulator-name = "ldo2"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + }; + + ldo3_reg: ldo3 { + /* VDDA_1V8_PHY */ + regulator-name = "ldo3"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + }; + + ldo9_reg: ldo9 { + /* VDD_RTC */ + regulator-name = "ldo9"; + regulator-min-microvolt = <1050000>; + regulator-max-microvolt = <1050000>; + regulator-boot-on; + }; + + ldoln_reg: ldoln { + /* VDDA_1V8_PLL */ + regulator-name = "ldoln"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + }; + + ldousb_reg: ldousb { + /* VDDA_3V_USB: VDDA_USBHS33 */ + regulator-name = "ldousb"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + }; + }; + }; + }; +}; + +&i2c2 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_pins>; + clock-frequency = <400000>; +}; + +&i2c3 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c3_pins>; + clock-frequency = <3400000>; +}; + +&mcspi1 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&mcspi1_pins>; +}; + +&mcspi2 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&mcspi2_pins>; +}; + +&uart1 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins>; +}; + +&uart2 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&uart2_pins>; +}; + +&uart3 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&uart3_pins>; +}; + +&mmc1 { + status = "okay"; + vmmc-supply = <&ldo1_reg>; + bus-width = <4>; +}; + +&mmc2 { + status = "okay"; + vmmc-supply = <&mmc2_3v3>; + bus-width = <8>; +}; + +&cpu0 { + cpu0-supply = <&smps123_reg>; +}; diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi new file mode 100644 index 000000000000..d0df4c4e8b0a --- /dev/null +++ b/arch/arm/boot/dts/dra7.dtsi @@ -0,0 +1,586 @@ +/* + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.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 + * published by the Free Software Foundation. + * Based on "omap4.dtsi" + */ + +#include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/pinctrl/dra.h> + +#include "skeleton.dtsi" + +/ { + #address-cells = <1>; + #size-cells = <1>; + + compatible = "ti,dra7xx"; + interrupt-parent = <&gic>; + + aliases { + i2c0 = &i2c1; + i2c1 = &i2c2; + i2c2 = &i2c3; + i2c3 = &i2c4; + i2c4 = &i2c5; + serial0 = &uart1; + serial1 = &uart2; + serial2 = &uart3; + serial3 = &uart4; + serial4 = &uart5; + serial5 = &uart6; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0>; + + operating-points = < + /* kHz uV */ + 1000000 1060000 + 1176000 1160000 + >; + }; + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <1>; + }; + }; + + timer { + compatible = "arm,armv7-timer"; + interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>; + }; + + gic: interrupt-controller@48211000 { + compatible = "arm,cortex-a15-gic"; + interrupt-controller; + #interrupt-cells = <3>; + reg = <0x48211000 0x1000>, + <0x48212000 0x1000>, + <0x48214000 0x2000>, + <0x48216000 0x2000>; + interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>; + }; + + /* + * The soc node represents the soc top level view. It is uses for IPs + * that are not memory mapped in the MPU view or for the MPU itself. + */ + soc { + compatible = "ti,omap-infra"; + mpu { + compatible = "ti,omap5-mpu"; + ti,hwmods = "mpu"; + }; + }; + + /* + * XXX: Use a flat representation of the SOC interconnect. + * The real OMAP interconnect network is quite complex. + * Since that will not bring real advantage to represent that in DT for + * the moment, just use a fake OCP bus entry to represent the whole bus + * hierarchy. + */ + ocp { + compatible = "ti,omap4-l3-noc", "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + ti,hwmods = "l3_main_1", "l3_main_2"; + reg = <0x44000000 0x2000>, + <0x44800000 0x3000>; + interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>; + + counter32k: counter@4ae04000 { + compatible = "ti,omap-counter32k"; + reg = <0x4ae04000 0x40>; + ti,hwmods = "counter_32k"; + }; + + dra7_pmx_core: pinmux@4a003400 { + compatible = "pinctrl-single"; + reg = <0x4a003400 0x0464>; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-single,register-width = <32>; + pinctrl-single,function-mask = <0x3fffffff>; + }; + + sdma: dma-controller@4a056000 { + compatible = "ti,omap4430-sdma"; + reg = <0x4a056000 0x1000>; + interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>; + #dma-cells = <1>; + #dma-channels = <32>; + #dma-requests = <127>; + }; + + gpio1: gpio@4ae10000 { + compatible = "ti,omap4-gpio"; + reg = <0x4ae10000 0x200>; + interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "gpio1"; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <1>; + }; + + gpio2: gpio@48055000 { + compatible = "ti,omap4-gpio"; + reg = <0x48055000 0x200>; + interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "gpio2"; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <1>; + }; + + gpio3: gpio@48057000 { + compatible = "ti,omap4-gpio"; + reg = <0x48057000 0x200>; + interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "gpio3"; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <1>; + }; + + gpio4: gpio@48059000 { + compatible = "ti,omap4-gpio"; + reg = <0x48059000 0x200>; + interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "gpio4"; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <1>; + }; + + gpio5: gpio@4805b000 { + compatible = "ti,omap4-gpio"; + reg = <0x4805b000 0x200>; + interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "gpio5"; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <1>; + }; + + gpio6: gpio@4805d000 { + compatible = "ti,omap4-gpio"; + reg = <0x4805d000 0x200>; + interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "gpio6"; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <1>; + }; + + gpio7: gpio@48051000 { + compatible = "ti,omap4-gpio"; + reg = <0x48051000 0x200>; + interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "gpio7"; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <1>; + }; + + gpio8: gpio@48053000 { + compatible = "ti,omap4-gpio"; + reg = <0x48053000 0x200>; + interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "gpio8"; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <1>; + }; + + uart1: serial@4806a000 { + compatible = "ti,omap4-uart"; + reg = <0x4806a000 0x100>; + interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "uart1"; + clock-frequency = <48000000>; + status = "disabled"; + }; + + uart2: serial@4806c000 { + compatible = "ti,omap4-uart"; + reg = <0x4806c000 0x100>; + interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "uart2"; + clock-frequency = <48000000>; + status = "disabled"; + }; + + uart3: serial@48020000 { + compatible = "ti,omap4-uart"; + reg = <0x48020000 0x100>; + interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "uart3"; + clock-frequency = <48000000>; + status = "disabled"; + }; + + uart4: serial@4806e000 { + compatible = "ti,omap4-uart"; + reg = <0x4806e000 0x100>; + interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "uart4"; + clock-frequency = <48000000>; + status = "disabled"; + }; + + uart5: serial@48066000 { + compatible = "ti,omap4-uart"; + reg = <0x48066000 0x100>; + interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "uart5"; + clock-frequency = <48000000>; + status = "disabled"; + }; + + uart6: serial@48068000 { + compatible = "ti,omap4-uart"; + reg = <0x48068000 0x100>; + interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "uart6"; + clock-frequency = <48000000>; + status = "disabled"; + }; + + uart7: serial@48420000 { + compatible = "ti,omap4-uart"; + reg = <0x48420000 0x100>; + ti,hwmods = "uart7"; + clock-frequency = <48000000>; + status = "disabled"; + }; + + uart8: serial@48422000 { + compatible = "ti,omap4-uart"; + reg = <0x48422000 0x100>; + ti,hwmods = "uart8"; + clock-frequency = <48000000>; + status = "disabled"; + }; + + uart9: serial@48424000 { + compatible = "ti,omap4-uart"; + reg = <0x48424000 0x100>; + ti,hwmods = "uart9"; + clock-frequency = <48000000>; + status = "disabled"; + }; + + uart10: serial@4ae2b000 { + compatible = "ti,omap4-uart"; + reg = <0x4ae2b000 0x100>; + ti,hwmods = "uart10"; + clock-frequency = <48000000>; + status = "disabled"; + }; + + timer1: timer@4ae18000 { + compatible = "ti,omap5430-timer"; + reg = <0x4ae18000 0x80>; + interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "timer1"; + ti,timer-alwon; + }; + + timer2: timer@48032000 { + compatible = "ti,omap5430-timer"; + reg = <0x48032000 0x80>; + interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "timer2"; + }; + + timer3: timer@48034000 { + compatible = "ti,omap5430-timer"; + reg = <0x48034000 0x80>; + interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "timer3"; + }; + + timer4: timer@48036000 { + compatible = "ti,omap5430-timer"; + reg = <0x48036000 0x80>; + interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "timer4"; + }; + + timer5: timer@48820000 { + compatible = "ti,omap5430-timer"; + reg = <0x48820000 0x80>; + interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "timer5"; + ti,timer-dsp; + }; + + timer6: timer@48822000 { + compatible = "ti,omap5430-timer"; + reg = <0x48822000 0x80>; + interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "timer6"; + ti,timer-dsp; + ti,timer-pwm; + }; + + timer7: timer@48824000 { + compatible = "ti,omap5430-timer"; + reg = <0x48824000 0x80>; + interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "timer7"; + ti,timer-dsp; + }; + + timer8: timer@48826000 { + compatible = "ti,omap5430-timer"; + reg = <0x48826000 0x80>; + interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "timer8"; + ti,timer-dsp; + ti,timer-pwm; + }; + + timer9: timer@4803e000 { + compatible = "ti,omap5430-timer"; + reg = <0x4803e000 0x80>; + interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "timer9"; + }; + + timer10: timer@48086000 { + compatible = "ti,omap5430-timer"; + reg = <0x48086000 0x80>; + interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "timer10"; + }; + + timer11: timer@48088000 { + compatible = "ti,omap5430-timer"; + reg = <0x48088000 0x80>; + interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "timer11"; + ti,timer-pwm; + }; + + timer13: timer@48828000 { + compatible = "ti,omap5430-timer"; + reg = <0x48828000 0x80>; + ti,hwmods = "timer13"; + status = "disabled"; + }; + + timer14: timer@4882a000 { + compatible = "ti,omap5430-timer"; + reg = <0x4882a000 0x80>; + ti,hwmods = "timer14"; + status = "disabled"; + }; + + timer15: timer@4882c000 { + compatible = "ti,omap5430-timer"; + reg = <0x4882c000 0x80>; + ti,hwmods = "timer15"; + status = "disabled"; + }; + + timer16: timer@4882e000 { + compatible = "ti,omap5430-timer"; + reg = <0x4882e000 0x80>; + ti,hwmods = "timer16"; + status = "disabled"; + }; + + wdt2: wdt@4ae14000 { + compatible = "ti,omap4-wdt"; + reg = <0x4ae14000 0x80>; + interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "wd_timer2"; + }; + + i2c1: i2c@48070000 { + compatible = "ti,omap4-i2c"; + reg = <0x48070000 0x100>; + interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + ti,hwmods = "i2c1"; + status = "disabled"; + }; + + i2c2: i2c@48072000 { + compatible = "ti,omap4-i2c"; + reg = <0x48072000 0x100>; + interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + ti,hwmods = "i2c2"; + status = "disabled"; + }; + + i2c3: i2c@48060000 { + compatible = "ti,omap4-i2c"; + reg = <0x48060000 0x100>; + interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + ti,hwmods = "i2c3"; + status = "disabled"; + }; + + i2c4: i2c@4807a000 { + compatible = "ti,omap4-i2c"; + reg = <0x4807a000 0x100>; + interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + ti,hwmods = "i2c4"; + status = "disabled"; + }; + + i2c5: i2c@4807c000 { + compatible = "ti,omap4-i2c"; + reg = <0x4807c000 0x100>; + interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + ti,hwmods = "i2c5"; + status = "disabled"; + }; + + mmc1: mmc@4809c000 { + compatible = "ti,omap4-hsmmc"; + reg = <0x4809c000 0x400>; + interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "mmc1"; + ti,dual-volt; + ti,needs-special-reset; + dmas = <&sdma 61>, <&sdma 62>; + dma-names = "tx", "rx"; + status = "disabled"; + }; + + mmc2: mmc@480b4000 { + compatible = "ti,omap4-hsmmc"; + reg = <0x480b4000 0x400>; + interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "mmc2"; + ti,needs-special-reset; + dmas = <&sdma 47>, <&sdma 48>; + dma-names = "tx", "rx"; + status = "disabled"; + }; + + mmc3: mmc@480ad000 { + compatible = "ti,omap4-hsmmc"; + reg = <0x480ad000 0x400>; + interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "mmc3"; + ti,needs-special-reset; + dmas = <&sdma 77>, <&sdma 78>; + dma-names = "tx", "rx"; + status = "disabled"; + }; + + mmc4: mmc@480d1000 { + compatible = "ti,omap4-hsmmc"; + reg = <0x480d1000 0x400>; + interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "mmc4"; + ti,needs-special-reset; + dmas = <&sdma 57>, <&sdma 58>; + dma-names = "tx", "rx"; + status = "disabled"; + }; + + mcspi1: spi@48098000 { + compatible = "ti,omap4-mcspi"; + reg = <0x48098000 0x200>; + interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + ti,hwmods = "mcspi1"; + ti,spi-num-cs = <4>; + dmas = <&sdma 35>, + <&sdma 36>, + <&sdma 37>, + <&sdma 38>, + <&sdma 39>, + <&sdma 40>, + <&sdma 41>, + <&sdma 42>; + dma-names = "tx0", "rx0", "tx1", "rx1", + "tx2", "rx2", "tx3", "rx3"; + status = "disabled"; + }; + + mcspi2: spi@4809a000 { + compatible = "ti,omap4-mcspi"; + reg = <0x4809a000 0x200>; + interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + ti,hwmods = "mcspi2"; + ti,spi-num-cs = <2>; + dmas = <&sdma 43>, + <&sdma 44>, + <&sdma 45>, + <&sdma 46>; + dma-names = "tx0", "rx0", "tx1", "rx1"; + status = "disabled"; + }; + + mcspi3: spi@480b8000 { + compatible = "ti,omap4-mcspi"; + reg = <0x480b8000 0x200>; + interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + ti,hwmods = "mcspi3"; + ti,spi-num-cs = <2>; + dmas = <&sdma 15>, <&sdma 16>; + dma-names = "tx0", "rx0"; + status = "disabled"; + }; + + mcspi4: spi@480ba000 { + compatible = "ti,omap4-mcspi"; + reg = <0x480ba000 0x200>; + interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + ti,hwmods = "mcspi4"; + ti,spi-num-cs = <1>; + dmas = <&sdma 70>, <&sdma 71>; + dma-names = "tx0", "rx0"; + status = "disabled"; + }; + }; +}; diff --git a/arch/arm/boot/dts/ecx-2000.dts b/arch/arm/boot/dts/ecx-2000.dts index 139b40cc3a23..2ccbb57fbfa8 100644 --- a/arch/arm/boot/dts/ecx-2000.dts +++ b/arch/arm/boot/dts/ecx-2000.dts @@ -85,6 +85,12 @@ <1 10 0xf08>; }; + memory-controller@fff00000 { + compatible = "calxeda,ecx-2000-ddr-ctrl"; + reg = <0xfff00000 0x1000>; + interrupts = <0 91 4>; + }; + intc: interrupt-controller@fff11000 { compatible = "arm,cortex-a15-gic"; #interrupt-cells = <3>; diff --git a/arch/arm/boot/dts/ecx-common.dtsi b/arch/arm/boot/dts/ecx-common.dtsi index e8559b753c9d..b90045a8f8e3 100644 --- a/arch/arm/boot/dts/ecx-common.dtsi +++ b/arch/arm/boot/dts/ecx-common.dtsi @@ -19,6 +19,14 @@ bootargs = "console=ttyAMA0"; }; + psci { + compatible = "arm,psci"; + method = "smc"; + cpu_suspend = <0x84000002>; + cpu_off = <0x84000004>; + cpu_on = <0x84000006>; + }; + soc { #address-cells = <1>; #size-cells = <1>; @@ -45,12 +53,6 @@ status = "disabled"; }; - memory-controller@fff00000 { - compatible = "calxeda,hb-ddr-ctrl"; - reg = <0xfff00000 0x1000>; - interrupts = <0 91 4>; - }; - ipc@fff20000 { compatible = "arm,pl320", "arm,primecell"; reg = <0xfff20000 0x1000>; diff --git a/arch/arm/boot/dts/emev2-kzm9d-reference.dts b/arch/arm/boot/dts/emev2-kzm9d-reference.dts deleted file mode 100644 index cceefda268b6..000000000000 --- a/arch/arm/boot/dts/emev2-kzm9d-reference.dts +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Device Tree Source for the KZM9D board - * - * Copyright (C) 2013 Renesas Solutions Corp. - * - * 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. - */ -/dts-v1/; - -/include/ "emev2.dtsi" - -/ { - model = "EMEV2 KZM9D Board"; - compatible = "renesas,kzm9d-reference", "renesas,emev2"; - - memory { - device_type = "memory"; - reg = <0x40000000 0x8000000>; - }; - - chosen { - bootargs = "console=ttyS1,115200n81 ignore_loglevel root=/dev/nfs ip=dhcp"; - }; - - reg_1p8v: regulator@0 { - compatible = "regulator-fixed"; - regulator-name = "fixed-1.8V"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-always-on; - regulator-boot-on; - }; - - reg_3p3v: regulator@1 { - compatible = "regulator-fixed"; - regulator-name = "fixed-3.3V"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - regulator-always-on; - regulator-boot-on; - }; - - lan9220@20000000 { - compatible = "smsc,lan9220", "smsc,lan9115"; - reg = <0x20000000 0x10000>; - phy-mode = "mii"; - interrupt-parent = <&gpio0>; - interrupts = <1 1>; /* active high */ - reg-io-width = <4>; - smsc,irq-active-high; - smsc,irq-push-pull; - vddvario-supply = <®_1p8v>; - vdd33a-supply = <®_3p3v>; - }; -}; diff --git a/arch/arm/boot/dts/emev2-kzm9d.dts b/arch/arm/boot/dts/emev2-kzm9d.dts index f92e812fdd9f..861aa7d6fc7d 100644 --- a/arch/arm/boot/dts/emev2-kzm9d.dts +++ b/arch/arm/boot/dts/emev2-kzm9d.dts @@ -1,7 +1,7 @@ /* * Device Tree Source for the KZM9D board * - * Copyright (C) 2012 Renesas Solutions Corp. + * Copyright (C) 2013 Renesas Solutions Corp. * * 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 @@ -23,4 +23,35 @@ chosen { bootargs = "console=ttyS1,115200n81 ignore_loglevel root=/dev/nfs ip=dhcp"; }; + + reg_1p8v: regulator@0 { + compatible = "regulator-fixed"; + regulator-name = "fixed-1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + }; + + reg_3p3v: regulator@1 { + compatible = "regulator-fixed"; + regulator-name = "fixed-3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + }; + + lan9220@20000000 { + compatible = "smsc,lan9220", "smsc,lan9115"; + reg = <0x20000000 0x10000>; + phy-mode = "mii"; + interrupt-parent = <&gpio0>; + interrupts = <1 1>; /* active high */ + reg-io-width = <4>; + smsc,irq-active-high; + smsc,irq-push-pull; + vddvario-supply = <®_1p8v>; + vdd33a-supply = <®_3p3v>; + }; }; diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi index caadc0257342..a73eeb5f258f 100644 --- a/arch/arm/boot/dts/exynos4.dtsi +++ b/arch/arm/boot/dts/exynos4.dtsi @@ -49,6 +49,12 @@ reg = <0x10000000 0x100>; }; + mipi_phy: video-phy@10020710 { + compatible = "samsung,s5pv210-mipi-video-phy"; + reg = <0x10020710 8>; + #phy-cells = <1>; + }; + pd_mfc: mfc-power-domain@10023C40 { compatible = "samsung,exynos4210-pd"; reg = <0x10023C40 0x20>; @@ -161,6 +167,8 @@ clock-names = "csis", "sclk_csis"; bus-width = <4>; samsung,power-domain = <&pd_cam>; + phys = <&mipi_phy 0>; + phy-names = "csis"; status = "disabled"; #address-cells = <1>; #size-cells = <0>; @@ -174,6 +182,8 @@ clock-names = "csis", "sclk_csis"; bus-width = <2>; samsung,power-domain = <&pd_cam>; + phys = <&mipi_phy 2>; + phy-names = "csis"; status = "disabled"; #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/boot/dts/exynos4210-origen.dts b/arch/arm/boot/dts/exynos4210-origen.dts index 382d8c7e2906..1a12fb23767c 100644 --- a/arch/arm/boot/dts/exynos4210-origen.dts +++ b/arch/arm/boot/dts/exynos4210-origen.dts @@ -32,13 +32,20 @@ bootargs ="root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC2,115200 init=/linuxrc"; }; - mmc_reg: voltage-regulator { - compatible = "regulator-fixed"; - regulator-name = "VMEM_VDD_2.8V"; - regulator-min-microvolt = <2800000>; - regulator-max-microvolt = <2800000>; - gpio = <&gpx1 1 0>; - enable-active-high; + regulators { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + mmc_reg: regulator@0 { + compatible = "regulator-fixed"; + reg = <0>; + regulator-name = "VMEM_VDD_2.8V"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + gpio = <&gpx1 1 0>; + enable-active-high; + }; }; tmu@100C0000 { @@ -192,7 +199,12 @@ }; buck1_reg: BUCK1 { - regulator-name = "VDD_ARM_1.2V"; + /* + * HACK: The real name is VDD_ARM_1.2V, + * but exynos-cpufreq does not support + * DT-based regulator lookup yet. + */ + regulator-name = "vdd_arm"; regulator-min-microvolt = <950000>; regulator-max-microvolt = <1350000>; regulator-always-on; diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts index 1c164f234bcc..63cc571ca307 100644 --- a/arch/arm/boot/dts/exynos4210-trats.dts +++ b/arch/arm/boot/dts/exynos4210-trats.dts @@ -290,7 +290,12 @@ }; varm_breg: BUCK1 { - regulator-name = "VARM_1.2V_C210"; + /* + * HACK: The real name is VARM_1.2V_C210, + * but exynos-cpufreq does not support + * DT-based regulator lookup yet. + */ + regulator-name = "vdd_arm"; regulator-min-microvolt = <900000>; regulator-max-microvolt = <1350000>; regulator-always-on; diff --git a/arch/arm/boot/dts/exynos4210-universal_c210.dts b/arch/arm/boot/dts/exynos4210-universal_c210.dts index 889cdada1ce9..d2e3f5f5916d 100644 --- a/arch/arm/boot/dts/exynos4210-universal_c210.dts +++ b/arch/arm/boot/dts/exynos4210-universal_c210.dts @@ -350,3 +350,7 @@ status = "okay"; }; }; + +&mdma1 { + reg = <0x12840000 0x1000>; +}; diff --git a/arch/arm/boot/dts/exynos4412-origen.dts b/arch/arm/boot/dts/exynos4412-origen.dts index 8768b03702e5..d65984c440f6 100644 --- a/arch/arm/boot/dts/exynos4412-origen.dts +++ b/arch/arm/boot/dts/exynos4412-origen.dts @@ -32,13 +32,20 @@ reg = <0x0203F000 0x1000>; }; - mmc_reg: voltage-regulator { - compatible = "regulator-fixed"; - regulator-name = "VMEM_VDD_2.8V"; - regulator-min-microvolt = <2800000>; - regulator-max-microvolt = <2800000>; - gpio = <&gpx1 1 0>; - enable-active-high; + regulators { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + mmc_reg: regulator@0 { + compatible = "regulator-fixed"; + reg = <0>; + regulator-name = "VMEM_VDD_2.8V"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + gpio = <&gpx1 1 0>; + enable-active-high; + }; }; pinctrl@11000000 { diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts index cee55fa33731..684527087aa4 100644 --- a/arch/arm/boot/dts/exynos5250-arndale.dts +++ b/arch/arm/boot/dts/exynos5250-arndale.dts @@ -324,7 +324,14 @@ }; i2c@12C80000 { - status = "disabled"; + samsung,i2c-sda-delay = <100>; + samsung,i2c-max-bus-freq = <66000>; + samsung,i2c-slave-addr = <0x50>; + + hdmiddc@50 { + compatible = "samsung,exynos4210-hdmiddc"; + reg = <0x50>; + }; }; i2c@12C90000 { @@ -362,6 +369,17 @@ status = "disabled"; }; + i2c@12CE0000 { + samsung,i2c-sda-delay = <100>; + samsung,i2c-max-bus-freq = <66000>; + samsung,i2c-slave-addr = <0x38>; + + hdmiphy@38 { + compatible = "samsung,exynos4212-hdmiphy"; + reg = <0x38>; + }; + }; + i2c@121D0000 { status = "disabled"; }; @@ -412,6 +430,10 @@ status = "disabled"; }; + i2s0: i2s@03830000 { + status = "okay"; + }; + spi_0: spi@12d20000 { status = "disabled"; }; @@ -482,13 +504,15 @@ #address-cells = <1>; #size-cells = <0>; - main_dc_reg: fixedregulator@1 { + main_dc_reg: regulator@0 { compatible = "regulator-fixed"; + reg = <0>; regulator-name = "MAIN_DC"; }; - mmc_reg: voltage-regulator { + mmc_reg: regulator@1 { compatible = "regulator-fixed"; + reg = <1>; regulator-name = "VDD_33ON_2.8V"; regulator-min-microvolt = <2800000>; regulator-max-microvolt = <2800000>; @@ -496,8 +520,9 @@ enable-active-high; }; - reg_hdmi_en: fixedregulator@0 { + reg_hdmi_en: regulator@2 { compatible = "regulator-fixed"; + reg = <2>; regulator-name = "hdmi-en"; }; }; diff --git a/arch/arm/boot/dts/exynos5250-pinctrl.dtsi b/arch/arm/boot/dts/exynos5250-pinctrl.dtsi index 724a22f9b1c8..9a49e6804ae1 100644 --- a/arch/arm/boot/dts/exynos5250-pinctrl.dtsi +++ b/arch/arm/boot/dts/exynos5250-pinctrl.dtsi @@ -210,21 +210,21 @@ samsung,pins = "gpa0-2", "gpa0-3"; samsung,pin-function = <2>; samsung,pin-pud = <0>; - samaung,pin-drv = <0>; + samsung,pin-drv = <0>; }; i2c2_bus: i2c2-bus { samsung,pins = "gpa0-6", "gpa0-7"; samsung,pin-function = <3>; samsung,pin-pud = <3>; - samaung,pin-drv = <0>; + samsung,pin-drv = <0>; }; i2c2_hs_bus: i2c2-hs-bus { samsung,pins = "gpa0-6", "gpa0-7"; samsung,pin-function = <4>; samsung,pin-pud = <3>; - samaung,pin-drv = <0>; + samsung,pin-drv = <0>; }; uart2_data: uart2-data { @@ -238,21 +238,21 @@ samsung,pins = "gpa1-2", "gpa1-3"; samsung,pin-function = <2>; samsung,pin-pud = <0>; - samaung,pin-drv = <0>; + samsung,pin-drv = <0>; }; i2c3_bus: i2c3-bus { samsung,pins = "gpa1-2", "gpa1-3"; samsung,pin-function = <3>; samsung,pin-pud = <3>; - samaung,pin-drv = <0>; + samsung,pin-drv = <0>; }; i2c3_hs_bus: i2c3-hs-bus { samsung,pins = "gpa1-2", "gpa1-3"; samsung,pin-function = <4>; samsung,pin-pud = <3>; - samaung,pin-drv = <0>; + samsung,pin-drv = <0>; }; uart3_data: uart3-data { @@ -273,14 +273,14 @@ samsung,pins = "gpa2-0", "gpa2-1"; samsung,pin-function = <3>; samsung,pin-pud = <3>; - samaung,pin-drv = <0>; + samsung,pin-drv = <0>; }; i2c5_bus: i2c5-bus { samsung,pins = "gpa2-2", "gpa2-3"; samsung,pin-function = <3>; samsung,pin-pud = <3>; - samaung,pin-drv = <0>; + samsung,pin-drv = <0>; }; spi1_bus: spi1-bus { @@ -376,14 +376,14 @@ samsung,pins = "gpb3-0", "gpb3-1"; samsung,pin-function = <4>; samsung,pin-pud = <3>; - samaung,pin-drv = <0>; + samsung,pin-drv = <0>; }; i2c1_hs_bus: i2c1-hs-bus { samsung,pins = "gpb3-2", "gpb3-3"; samsung,pin-function = <4>; samsung,pin-pud = <3>; - samaung,pin-drv = <0>; + samsung,pin-drv = <0>; }; sd0_clk: sd0-clk { @@ -551,14 +551,14 @@ samsung,pins = "gpd0-2", "gpd0-3"; samsung,pin-function = <2>; samsung,pin-pud = <0>; - samaung,pin-drv = <0>; + samsung,pin-drv = <0>; }; dp_hpd: dp_hpd { samsung,pins = "gpx0-7"; samsung,pin-function = <3>; samsung,pin-pud = <0>; - samaung,pin-drv = <0>; + samsung,pin-drv = <0>; }; }; @@ -649,42 +649,42 @@ "gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3"; samsung,pin-function = <3>; samsung,pin-pud = <0>; - samaung,pin-drv = <0>; + samsung,pin-drv = <0>; }; cam_i2c2_bus: cam-i2c2-bus { samsung,pins = "gpe0-6", "gpe1-0"; samsung,pin-function = <4>; samsung,pin-pud = <3>; - samaung,pin-drv = <0>; + samsung,pin-drv = <0>; }; cam_spi1_bus: cam-spi1-bus { samsung,pins = "gpe0-4", "gpe0-5", "gpf0-2", "gpf0-3"; samsung,pin-function = <4>; samsung,pin-pud = <0>; - samaung,pin-drv = <0>; + samsung,pin-drv = <0>; }; cam_i2c1_bus: cam-i2c1-bus { samsung,pins = "gpf0-2", "gpf0-3"; samsung,pin-function = <2>; samsung,pin-pud = <3>; - samaung,pin-drv = <0>; + samsung,pin-drv = <0>; }; cam_i2c0_bus: cam-i2c0-bus { samsung,pins = "gpf0-0", "gpf0-1"; samsung,pin-function = <2>; samsung,pin-pud = <3>; - samaung,pin-drv = <0>; + samsung,pin-drv = <0>; }; cam_spi0_bus: cam-spi0-bus { samsung,pins = "gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3"; samsung,pin-function = <2>; samsung,pin-pud = <0>; - samaung,pin-drv = <0>; + samsung,pin-drv = <0>; }; cam_bayrgb_bus: cam-bayrgb-bus { @@ -695,7 +695,7 @@ "gpg2-0", "gpg2-1"; samsung,pin-function = <2>; samsung,pin-pud = <0>; - samaung,pin-drv = <0>; + samsung,pin-drv = <0>; }; cam_port_a: cam-port-a { @@ -704,7 +704,7 @@ "gph1-4", "gph1-5", "gph1-6", "gph1-7"; samsung,pin-function = <2>; samsung,pin-pud = <0>; - samaung,pin-drv = <0>; + samsung,pin-drv = <0>; }; }; @@ -756,7 +756,7 @@ "gpv1-4", "gpv1-5", "gpv1-6", "gpv1-7"; samsung,pin-function = <2>; samsung,pin-pud = <0>; - samaung,pin-drv = <0>; + samsung,pin-drv = <0>; }; c2c_txd: c2c-txd { @@ -766,7 +766,7 @@ "gpv3-4", "gpv3-5", "gpv3-6", "gpv3-7"; samsung,pin-function = <2>; samsung,pin-pud = <0>; - samaung,pin-drv = <0>; + samsung,pin-drv = <0>; }; }; diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts index 2538b329f2ce..f86d56760a45 100644 --- a/arch/arm/boot/dts/exynos5250-smdk5250.dts +++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts @@ -231,14 +231,6 @@ status = "okay"; }; - i2s1: i2s@12D60000 { - status = "disabled"; - }; - - i2s2: i2s@12D70000 { - status = "disabled"; - }; - sound { compatible = "samsung,smdk-wm8994"; diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi index bbac42a78ce5..9db5047812f3 100644 --- a/arch/arm/boot/dts/exynos5250.dtsi +++ b/arch/arm/boot/dts/exynos5250.dtsi @@ -422,6 +422,7 @@ i2s0: i2s@03830000 { compatible = "samsung,s5pv210-i2s"; + status = "disabled"; reg = <0x03830000 0x100>; dmas = <&pdma0 10 &pdma0 9 @@ -438,6 +439,7 @@ i2s1: i2s@12D60000 { compatible = "samsung,s3c6410-i2s"; + status = "disabled"; reg = <0x12D60000 0x100>; dmas = <&pdma1 12 &pdma1 11>; @@ -450,6 +452,7 @@ i2s2: i2s@12D70000 { compatible = "samsung,s3c6410-i2s"; + status = "disabled"; reg = <0x12D70000 0x100>; dmas = <&pdma0 12 &pdma0 11>; @@ -615,16 +618,18 @@ compatible = "samsung,exynos4212-hdmi"; reg = <0x14530000 0x70000>; interrupts = <0 95 0>; - clocks = <&clock 333>, <&clock 136>, <&clock 137>, - <&clock 333>, <&clock 333>; + clocks = <&clock 344>, <&clock 136>, <&clock 137>, + <&clock 159>, <&clock 1024>; clock-names = "hdmi", "sclk_hdmi", "sclk_pixel", - "sclk_hdmiphy", "hdmiphy"; + "sclk_hdmiphy", "mout_hdmi"; }; mixer { compatible = "samsung,exynos5250-mixer"; reg = <0x14450000 0x10000>; interrupts = <0 94 0>; + clocks = <&clock 343>, <&clock 136>; + clock-names = "mixer", "sclk_hdmi"; }; dp_phy: video-phy@10040720 { diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts index bafba25ba7c2..79524c74c603 100644 --- a/arch/arm/boot/dts/exynos5420-smdk5420.dts +++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts @@ -61,4 +61,30 @@ }; }; + pinctrl@13400000 { + hdmi_hpd_irq: hdmi-hpd-irq { + samsung,pins = "gpx3-7"; + samsung,pin-function = <0>; + samsung,pin-pud = <1>; + samsung,pin-drv = <0>; + }; + }; + + hdmi@14530000 { + status = "okay"; + hpd-gpio = <&gpx3 7 0>; + pinctrl-names = "default"; + pinctrl-0 = <&hdmi_hpd_irq>; + }; + + i2c_2: i2c@12C80000 { + samsung,i2c-sda-delay = <100>; + samsung,i2c-max-bus-freq = <66000>; + status = "okay"; + + hdmiddc@50 { + compatible = "samsung,exynos4210-hdmiddc"; + reg = <0x50>; + }; + }; }; diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi index d537cd704e19..09aa06cb3d3a 100644 --- a/arch/arm/boot/dts/exynos5420.dtsi +++ b/arch/arm/boot/dts/exynos5420.dtsi @@ -27,6 +27,10 @@ pinctrl2 = &pinctrl_2; pinctrl3 = &pinctrl_3; pinctrl4 = &pinctrl_4; + i2c0 = &i2c_0; + i2c1 = &i2c_1; + i2c2 = &i2c_2; + i2c3 = &i2c_3; }; cpus { @@ -235,4 +239,75 @@ io-channel-ranges; status = "disabled"; }; + + i2c_0: i2c@12C60000 { + compatible = "samsung,s3c2440-i2c"; + reg = <0x12C60000 0x100>; + interrupts = <0 56 0>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clock 261>; + clock-names = "i2c"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_bus>; + status = "disabled"; + }; + + i2c_1: i2c@12C70000 { + compatible = "samsung,s3c2440-i2c"; + reg = <0x12C70000 0x100>; + interrupts = <0 57 0>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clock 262>; + clock-names = "i2c"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_bus>; + status = "disabled"; + }; + + i2c_2: i2c@12C80000 { + compatible = "samsung,s3c2440-i2c"; + reg = <0x12C80000 0x100>; + interrupts = <0 58 0>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clock 263>; + clock-names = "i2c"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_bus>; + status = "disabled"; + }; + + i2c_3: i2c@12C90000 { + compatible = "samsung,s3c2440-i2c"; + reg = <0x12C90000 0x100>; + interrupts = <0 59 0>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clock 264>; + clock-names = "i2c"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c3_bus>; + status = "disabled"; + }; + + hdmi@14530000 { + compatible = "samsung,exynos4212-hdmi"; + reg = <0x14530000 0x70000>; + interrupts = <0 95 0>; + clocks = <&clock 413>, <&clock 143>, <&clock 768>, + <&clock 158>, <&clock 640>; + clock-names = "hdmi", "sclk_hdmi", "sclk_pixel", + "sclk_hdmiphy", "mout_hdmi"; + status = "disabled"; + }; + + mixer@14450000 { + compatible = "samsung,exynos5420-mixer"; + reg = <0x14450000 0x10000>; + interrupts = <0 94 0>; + clocks = <&clock 431>, <&clock 143>; + clock-names = "mixer", "sclk_hdmi"; + }; }; diff --git a/arch/arm/boot/dts/exynos5440-sd5v1.dts b/arch/arm/boot/dts/exynos5440-sd5v1.dts index 5b22508050da..777fb1c2c70f 100644 --- a/arch/arm/boot/dts/exynos5440-sd5v1.dts +++ b/arch/arm/boot/dts/exynos5440-sd5v1.dts @@ -17,7 +17,7 @@ compatible = "samsung,sd5v1", "samsung,exynos5440"; chosen { - bootargs = "root=/dev/sda2 rw rootwait ignore_loglevel early_printk no_console_suspend mem=2048M@0x80000000 mem=6144M@0x100000000 console=ttySAC0,115200"; + bootargs = "root=/dev/sda2 rw rootwait ignore_loglevel earlyprintk no_console_suspend mem=2048M@0x80000000 mem=6144M@0x100000000 console=ttySAC0,115200"; }; fixed-rate-clocks { diff --git a/arch/arm/boot/dts/exynos5440-ssdk5440.dts b/arch/arm/boot/dts/exynos5440-ssdk5440.dts index ede772741f81..d58cb787061a 100644 --- a/arch/arm/boot/dts/exynos5440-ssdk5440.dts +++ b/arch/arm/boot/dts/exynos5440-ssdk5440.dts @@ -17,7 +17,7 @@ compatible = "samsung,ssdk5440", "samsung,exynos5440"; chosen { - bootargs = "root=/dev/sda2 rw rootwait ignore_loglevel early_printk no_console_suspend mem=2048M@0x80000000 mem=6144M@0x100000000 console=ttySAC0,115200"; + bootargs = "root=/dev/sda2 rw rootwait ignore_loglevel earlyprintk no_console_suspend mem=2048M@0x80000000 mem=6144M@0x100000000 console=ttySAC0,115200"; }; spi_0: spi@D0000 { @@ -68,9 +68,11 @@ pcie@290000 { reset-gpio = <&pin_ctrl 5 0>; + status = "okay"; }; pcie@2a0000 { reset-gpio = <&pin_ctrl 22 0>; + status = "okay"; }; }; diff --git a/arch/arm/boot/dts/exynos5440.dtsi b/arch/arm/boot/dts/exynos5440.dtsi index 5d6cf4965d6e..8da107088ce4 100644 --- a/arch/arm/boot/dts/exynos5440.dtsi +++ b/arch/arm/boot/dts/exynos5440.dtsi @@ -276,6 +276,7 @@ interrupt-map-mask = <0 0 0 0>; interrupt-map = <0x0 0 &gic 53>; num-lanes = <4>; + status = "disabled"; }; pcie@2a0000 { @@ -296,5 +297,6 @@ interrupt-map-mask = <0 0 0 0>; interrupt-map = <0x0 0 &gic 56>; num-lanes = <4>; + status = "disabled"; }; }; diff --git a/arch/arm/boot/dts/highbank.dts b/arch/arm/boot/dts/highbank.dts index 6aad34ad9517..ed14aeac0566 100644 --- a/arch/arm/boot/dts/highbank.dts +++ b/arch/arm/boot/dts/highbank.dts @@ -86,6 +86,12 @@ soc { ranges = <0x00000000 0x00000000 0xffffffff>; + memory-controller@fff00000 { + compatible = "calxeda,hb-ddr-ctrl"; + reg = <0xfff00000 0x1000>; + interrupts = <0 91 4>; + }; + timer@fff10600 { compatible = "arm,cortex-a9-twd-timer"; reg = <0xfff10600 0x20>; diff --git a/arch/arm/boot/dts/imx23-evk.dts b/arch/arm/boot/dts/imx23-evk.dts index 185c7c01102a..1f026adefd45 100644 --- a/arch/arm/boot/dts/imx23-evk.dts +++ b/arch/arm/boot/dts/imx23-evk.dts @@ -10,7 +10,7 @@ */ /dts-v1/; -/include/ "imx23.dtsi" +#include "imx23.dtsi" / { model = "Freescale i.MX23 Evaluation Kit"; @@ -45,14 +45,14 @@ hog_pins_a: hog@0 { reg = <0>; fsl,pinmux-ids = < - 0x1123 /* MX23_PAD_LCD_RESET__GPIO_1_18 */ - 0x11d3 /* MX23_PAD_PWM3__GPIO_1_29 */ - 0x11e3 /* MX23_PAD_PWM4__GPIO_1_30 */ - 0x2010 /* MX23_PAD_SSP1_DETECT__SSP1_DETECT */ + MX23_PAD_LCD_RESET__GPIO_1_18 + MX23_PAD_PWM3__GPIO_1_29 + MX23_PAD_PWM4__GPIO_1_30 + MX23_PAD_SSP1_DETECT__SSP1_DETECT >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; }; diff --git a/arch/arm/boot/dts/imx23-olinuxino.dts b/arch/arm/boot/dts/imx23-olinuxino.dts index fc766ae12e24..526bfdbd87f9 100644 --- a/arch/arm/boot/dts/imx23-olinuxino.dts +++ b/arch/arm/boot/dts/imx23-olinuxino.dts @@ -12,7 +12,7 @@ */ /dts-v1/; -/include/ "imx23.dtsi" +#include "imx23.dtsi" / { model = "i.MX23 Olinuxino Low Cost Board"; @@ -40,21 +40,21 @@ hog_pins_a: hog@0 { reg = <0>; fsl,pinmux-ids = < - 0x0113 /* MX23_PAD_GPMI_ALE__GPIO_0_17 */ + MX23_PAD_GPMI_ALE__GPIO_0_17 >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; led_pin_gpio2_1: led_gpio2_1@0 { reg = <0>; fsl,pinmux-ids = < - 0x2013 /* MX23_PAD_SSP1_DETECT__GPIO_2_1 */ + MX23_PAD_SSP1_DETECT__GPIO_2_1 >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; }; diff --git a/arch/arm/boot/dts/imx23-pinfunc.h b/arch/arm/boot/dts/imx23-pinfunc.h new file mode 100644 index 000000000000..5c0f32ca3a93 --- /dev/null +++ b/arch/arm/boot/dts/imx23-pinfunc.h @@ -0,0 +1,333 @@ +/* + * Header providing constants for i.MX23 pinctrl bindings. + * + * Copyright (C) 2013 Lothar Waßmann <LW@KARO-electronics.de> + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#ifndef __DT_BINDINGS_MX23_PINCTRL_H__ +#define __DT_BINDINGS_MX23_PINCTRL_H__ + +#include "mxs-pinfunc.h" + +#define MX23_PAD_GPMI_D00__GPMI_D00 0x0000 +#define MX23_PAD_GPMI_D01__GPMI_D01 0x0010 +#define MX23_PAD_GPMI_D02__GPMI_D02 0x0020 +#define MX23_PAD_GPMI_D03__GPMI_D03 0x0030 +#define MX23_PAD_GPMI_D04__GPMI_D04 0x0040 +#define MX23_PAD_GPMI_D05__GPMI_D05 0x0050 +#define MX23_PAD_GPMI_D06__GPMI_D06 0x0060 +#define MX23_PAD_GPMI_D07__GPMI_D07 0x0070 +#define MX23_PAD_GPMI_D08__GPMI_D08 0x0080 +#define MX23_PAD_GPMI_D09__GPMI_D09 0x0090 +#define MX23_PAD_GPMI_D10__GPMI_D10 0x00a0 +#define MX23_PAD_GPMI_D11__GPMI_D11 0x00b0 +#define MX23_PAD_GPMI_D12__GPMI_D12 0x00c0 +#define MX23_PAD_GPMI_D13__GPMI_D13 0x00d0 +#define MX23_PAD_GPMI_D14__GPMI_D14 0x00e0 +#define MX23_PAD_GPMI_D15__GPMI_D15 0x00f0 +#define MX23_PAD_GPMI_CLE__GPMI_CLE 0x0100 +#define MX23_PAD_GPMI_ALE__GPMI_ALE 0x0110 +#define MX23_PAD_GPMI_CE2N__GPMI_CE2N 0x0120 +#define MX23_PAD_GPMI_RDY0__GPMI_RDY0 0x0130 +#define MX23_PAD_GPMI_RDY1__GPMI_RDY1 0x0140 +#define MX23_PAD_GPMI_RDY2__GPMI_RDY2 0x0150 +#define MX23_PAD_GPMI_RDY3__GPMI_RDY3 0x0160 +#define MX23_PAD_GPMI_WPN__GPMI_WPN 0x0170 +#define MX23_PAD_GPMI_WRN__GPMI_WRN 0x0180 +#define MX23_PAD_GPMI_RDN__GPMI_RDN 0x0190 +#define MX23_PAD_AUART1_CTS__AUART1_CTS 0x01a0 +#define MX23_PAD_AUART1_RTS__AUART1_RTS 0x01b0 +#define MX23_PAD_AUART1_RX__AUART1_RX 0x01c0 +#define MX23_PAD_AUART1_TX__AUART1_TX 0x01d0 +#define MX23_PAD_I2C_SCL__I2C_SCL 0x01e0 +#define MX23_PAD_I2C_SDA__I2C_SDA 0x01f0 +#define MX23_PAD_LCD_D00__LCD_D00 0x1000 +#define MX23_PAD_LCD_D01__LCD_D01 0x1010 +#define MX23_PAD_LCD_D02__LCD_D02 0x1020 +#define MX23_PAD_LCD_D03__LCD_D03 0x1030 +#define MX23_PAD_LCD_D04__LCD_D04 0x1040 +#define MX23_PAD_LCD_D05__LCD_D05 0x1050 +#define MX23_PAD_LCD_D06__LCD_D06 0x1060 +#define MX23_PAD_LCD_D07__LCD_D07 0x1070 +#define MX23_PAD_LCD_D08__LCD_D08 0x1080 +#define MX23_PAD_LCD_D09__LCD_D09 0x1090 +#define MX23_PAD_LCD_D10__LCD_D10 0x10a0 +#define MX23_PAD_LCD_D11__LCD_D11 0x10b0 +#define MX23_PAD_LCD_D12__LCD_D12 0x10c0 +#define MX23_PAD_LCD_D13__LCD_D13 0x10d0 +#define MX23_PAD_LCD_D14__LCD_D14 0x10e0 +#define MX23_PAD_LCD_D15__LCD_D15 0x10f0 +#define MX23_PAD_LCD_D16__LCD_D16 0x1100 +#define MX23_PAD_LCD_D17__LCD_D17 0x1110 +#define MX23_PAD_LCD_RESET__LCD_RESET 0x1120 +#define MX23_PAD_LCD_RS__LCD_RS 0x1130 +#define MX23_PAD_LCD_WR__LCD_WR 0x1140 +#define MX23_PAD_LCD_CS__LCD_CS 0x1150 +#define MX23_PAD_LCD_DOTCK__LCD_DOTCK 0x1160 +#define MX23_PAD_LCD_ENABLE__LCD_ENABLE 0x1170 +#define MX23_PAD_LCD_HSYNC__LCD_HSYNC 0x1180 +#define MX23_PAD_LCD_VSYNC__LCD_VSYNC 0x1190 +#define MX23_PAD_PWM0__PWM0 0x11a0 +#define MX23_PAD_PWM1__PWM1 0x11b0 +#define MX23_PAD_PWM2__PWM2 0x11c0 +#define MX23_PAD_PWM3__PWM3 0x11d0 +#define MX23_PAD_PWM4__PWM4 0x11e0 +#define MX23_PAD_SSP1_CMD__SSP1_CMD 0x2000 +#define MX23_PAD_SSP1_DETECT__SSP1_DETECT 0x2010 +#define MX23_PAD_SSP1_DATA0__SSP1_DATA0 0x2020 +#define MX23_PAD_SSP1_DATA1__SSP1_DATA1 0x2030 +#define MX23_PAD_SSP1_DATA2__SSP1_DATA2 0x2040 +#define MX23_PAD_SSP1_DATA3__SSP1_DATA3 0x2050 +#define MX23_PAD_SSP1_SCK__SSP1_SCK 0x2060 +#define MX23_PAD_ROTARYA__ROTARYA 0x2070 +#define MX23_PAD_ROTARYB__ROTARYB 0x2080 +#define MX23_PAD_EMI_A00__EMI_A00 0x2090 +#define MX23_PAD_EMI_A01__EMI_A01 0x20a0 +#define MX23_PAD_EMI_A02__EMI_A02 0x20b0 +#define MX23_PAD_EMI_A03__EMI_A03 0x20c0 +#define MX23_PAD_EMI_A04__EMI_A04 0x20d0 +#define MX23_PAD_EMI_A05__EMI_A05 0x20e0 +#define MX23_PAD_EMI_A06__EMI_A06 0x20f0 +#define MX23_PAD_EMI_A07__EMI_A07 0x2100 +#define MX23_PAD_EMI_A08__EMI_A08 0x2110 +#define MX23_PAD_EMI_A09__EMI_A09 0x2120 +#define MX23_PAD_EMI_A10__EMI_A10 0x2130 +#define MX23_PAD_EMI_A11__EMI_A11 0x2140 +#define MX23_PAD_EMI_A12__EMI_A12 0x2150 +#define MX23_PAD_EMI_BA0__EMI_BA0 0x2160 +#define MX23_PAD_EMI_BA1__EMI_BA1 0x2170 +#define MX23_PAD_EMI_CASN__EMI_CASN 0x2180 +#define MX23_PAD_EMI_CE0N__EMI_CE0N 0x2190 +#define MX23_PAD_EMI_CE1N__EMI_CE1N 0x21a0 +#define MX23_PAD_GPMI_CE1N__GPMI_CE1N 0x21b0 +#define MX23_PAD_GPMI_CE0N__GPMI_CE0N 0x21c0 +#define MX23_PAD_EMI_CKE__EMI_CKE 0x21d0 +#define MX23_PAD_EMI_RASN__EMI_RASN 0x21e0 +#define MX23_PAD_EMI_WEN__EMI_WEN 0x21f0 +#define MX23_PAD_EMI_D00__EMI_D00 0x3000 +#define MX23_PAD_EMI_D01__EMI_D01 0x3010 +#define MX23_PAD_EMI_D02__EMI_D02 0x3020 +#define MX23_PAD_EMI_D03__EMI_D03 0x3030 +#define MX23_PAD_EMI_D04__EMI_D04 0x3040 +#define MX23_PAD_EMI_D05__EMI_D05 0x3050 +#define MX23_PAD_EMI_D06__EMI_D06 0x3060 +#define MX23_PAD_EMI_D07__EMI_D07 0x3070 +#define MX23_PAD_EMI_D08__EMI_D08 0x3080 +#define MX23_PAD_EMI_D09__EMI_D09 0x3090 +#define MX23_PAD_EMI_D10__EMI_D10 0x30a0 +#define MX23_PAD_EMI_D11__EMI_D11 0x30b0 +#define MX23_PAD_EMI_D12__EMI_D12 0x30c0 +#define MX23_PAD_EMI_D13__EMI_D13 0x30d0 +#define MX23_PAD_EMI_D14__EMI_D14 0x30e0 +#define MX23_PAD_EMI_D15__EMI_D15 0x30f0 +#define MX23_PAD_EMI_DQM0__EMI_DQM0 0x3100 +#define MX23_PAD_EMI_DQM1__EMI_DQM1 0x3110 +#define MX23_PAD_EMI_DQS0__EMI_DQS0 0x3120 +#define MX23_PAD_EMI_DQS1__EMI_DQS1 0x3130 +#define MX23_PAD_EMI_CLK__EMI_CLK 0x3140 +#define MX23_PAD_EMI_CLKN__EMI_CLKN 0x3150 +#define MX23_PAD_GPMI_D00__LCD_D8 0x0001 +#define MX23_PAD_GPMI_D01__LCD_D9 0x0011 +#define MX23_PAD_GPMI_D02__LCD_D10 0x0021 +#define MX23_PAD_GPMI_D03__LCD_D11 0x0031 +#define MX23_PAD_GPMI_D04__LCD_D12 0x0041 +#define MX23_PAD_GPMI_D05__LCD_D13 0x0051 +#define MX23_PAD_GPMI_D06__LCD_D14 0x0061 +#define MX23_PAD_GPMI_D07__LCD_D15 0x0071 +#define MX23_PAD_GPMI_D08__LCD_D18 0x0081 +#define MX23_PAD_GPMI_D09__LCD_D19 0x0091 +#define MX23_PAD_GPMI_D10__LCD_D20 0x00a1 +#define MX23_PAD_GPMI_D11__LCD_D21 0x00b1 +#define MX23_PAD_GPMI_D12__LCD_D22 0x00c1 +#define MX23_PAD_GPMI_D13__LCD_D23 0x00d1 +#define MX23_PAD_GPMI_D14__AUART2_RX 0x00e1 +#define MX23_PAD_GPMI_D15__AUART2_TX 0x00f1 +#define MX23_PAD_GPMI_CLE__LCD_D16 0x0101 +#define MX23_PAD_GPMI_ALE__LCD_D17 0x0111 +#define MX23_PAD_GPMI_CE2N__ATA_A2 0x0121 +#define MX23_PAD_AUART1_RTS__IR_CLK 0x01b1 +#define MX23_PAD_AUART1_RX__IR_RX 0x01c1 +#define MX23_PAD_AUART1_TX__IR_TX 0x01d1 +#define MX23_PAD_I2C_SCL__GPMI_RDY2 0x01e1 +#define MX23_PAD_I2C_SDA__GPMI_CE2N 0x01f1 +#define MX23_PAD_LCD_D00__ETM_DA8 0x1001 +#define MX23_PAD_LCD_D01__ETM_DA9 0x1011 +#define MX23_PAD_LCD_D02__ETM_DA10 0x1021 +#define MX23_PAD_LCD_D03__ETM_DA11 0x1031 +#define MX23_PAD_LCD_D04__ETM_DA12 0x1041 +#define MX23_PAD_LCD_D05__ETM_DA13 0x1051 +#define MX23_PAD_LCD_D06__ETM_DA14 0x1061 +#define MX23_PAD_LCD_D07__ETM_DA15 0x1071 +#define MX23_PAD_LCD_D08__ETM_DA0 0x1081 +#define MX23_PAD_LCD_D09__ETM_DA1 0x1091 +#define MX23_PAD_LCD_D10__ETM_DA2 0x10a1 +#define MX23_PAD_LCD_D11__ETM_DA3 0x10b1 +#define MX23_PAD_LCD_D12__ETM_DA4 0x10c1 +#define MX23_PAD_LCD_D13__ETM_DA5 0x10d1 +#define MX23_PAD_LCD_D14__ETM_DA6 0x10e1 +#define MX23_PAD_LCD_D15__ETM_DA7 0x10f1 +#define MX23_PAD_LCD_RESET__ETM_TCTL 0x1121 +#define MX23_PAD_LCD_RS__ETM_TCLK 0x1131 +#define MX23_PAD_LCD_DOTCK__GPMI_RDY3 0x1161 +#define MX23_PAD_LCD_ENABLE__I2C_SCL 0x1171 +#define MX23_PAD_LCD_HSYNC__I2C_SDA 0x1181 +#define MX23_PAD_LCD_VSYNC__LCD_BUSY 0x1191 +#define MX23_PAD_PWM0__ROTARYA 0x11a1 +#define MX23_PAD_PWM1__ROTARYB 0x11b1 +#define MX23_PAD_PWM2__GPMI_RDY3 0x11c1 +#define MX23_PAD_PWM3__ETM_TCTL 0x11d1 +#define MX23_PAD_PWM4__ETM_TCLK 0x11e1 +#define MX23_PAD_SSP1_DETECT__GPMI_CE3N 0x2011 +#define MX23_PAD_SSP1_DATA1__I2C_SCL 0x2031 +#define MX23_PAD_SSP1_DATA2__I2C_SDA 0x2041 +#define MX23_PAD_ROTARYA__AUART2_RTS 0x2071 +#define MX23_PAD_ROTARYB__AUART2_CTS 0x2081 +#define MX23_PAD_GPMI_D00__SSP2_DATA0 0x0002 +#define MX23_PAD_GPMI_D01__SSP2_DATA1 0x0012 +#define MX23_PAD_GPMI_D02__SSP2_DATA2 0x0022 +#define MX23_PAD_GPMI_D03__SSP2_DATA3 0x0032 +#define MX23_PAD_GPMI_D04__SSP2_DATA4 0x0042 +#define MX23_PAD_GPMI_D05__SSP2_DATA5 0x0052 +#define MX23_PAD_GPMI_D06__SSP2_DATA6 0x0062 +#define MX23_PAD_GPMI_D07__SSP2_DATA7 0x0072 +#define MX23_PAD_GPMI_D08__SSP1_DATA4 0x0082 +#define MX23_PAD_GPMI_D09__SSP1_DATA5 0x0092 +#define MX23_PAD_GPMI_D10__SSP1_DATA6 0x00a2 +#define MX23_PAD_GPMI_D11__SSP1_DATA7 0x00b2 +#define MX23_PAD_GPMI_D15__GPMI_CE3N 0x00f2 +#define MX23_PAD_GPMI_RDY0__SSP2_DETECT 0x0132 +#define MX23_PAD_GPMI_RDY1__SSP2_CMD 0x0142 +#define MX23_PAD_GPMI_WRN__SSP2_SCK 0x0182 +#define MX23_PAD_AUART1_CTS__SSP1_DATA4 0x01a2 +#define MX23_PAD_AUART1_RTS__SSP1_DATA5 0x01b2 +#define MX23_PAD_AUART1_RX__SSP1_DATA6 0x01c2 +#define MX23_PAD_AUART1_TX__SSP1_DATA7 0x01d2 +#define MX23_PAD_I2C_SCL__AUART1_TX 0x01e2 +#define MX23_PAD_I2C_SDA__AUART1_RX 0x01f2 +#define MX23_PAD_LCD_D08__SAIF2_SDATA0 0x1082 +#define MX23_PAD_LCD_D09__SAIF1_SDATA0 0x1092 +#define MX23_PAD_LCD_D10__SAIF_MCLK_BITCLK 0x10a2 +#define MX23_PAD_LCD_D11__SAIF_LRCLK 0x10b2 +#define MX23_PAD_LCD_D12__SAIF2_SDATA1 0x10c2 +#define MX23_PAD_LCD_D13__SAIF2_SDATA2 0x10d2 +#define MX23_PAD_LCD_D14__SAIF1_SDATA2 0x10e2 +#define MX23_PAD_LCD_D15__SAIF1_SDATA1 0x10f2 +#define MX23_PAD_LCD_D16__SAIF_ALT_BITCLK 0x1102 +#define MX23_PAD_LCD_RESET__GPMI_CE3N 0x1122 +#define MX23_PAD_PWM0__DUART_RX 0x11a2 +#define MX23_PAD_PWM1__DUART_TX 0x11b2 +#define MX23_PAD_PWM3__AUART1_CTS 0x11d2 +#define MX23_PAD_PWM4__AUART1_RTS 0x11e2 +#define MX23_PAD_SSP1_CMD__JTAG_TDO 0x2002 +#define MX23_PAD_SSP1_DETECT__USB_OTG_ID 0x2012 +#define MX23_PAD_SSP1_DATA0__JTAG_TDI 0x2022 +#define MX23_PAD_SSP1_DATA1__JTAG_TCLK 0x2032 +#define MX23_PAD_SSP1_DATA2__JTAG_RTCK 0x2042 +#define MX23_PAD_SSP1_DATA3__JTAG_TMS 0x2052 +#define MX23_PAD_SSP1_SCK__JTAG_TRST 0x2062 +#define MX23_PAD_ROTARYA__SPDIF 0x2072 +#define MX23_PAD_ROTARYB__GPMI_CE3N 0x2082 +#define MX23_PAD_GPMI_D00__GPIO_0_0 0x0003 +#define MX23_PAD_GPMI_D01__GPIO_0_1 0x0013 +#define MX23_PAD_GPMI_D02__GPIO_0_2 0x0023 +#define MX23_PAD_GPMI_D03__GPIO_0_3 0x0033 +#define MX23_PAD_GPMI_D04__GPIO_0_4 0x0043 +#define MX23_PAD_GPMI_D05__GPIO_0_5 0x0053 +#define MX23_PAD_GPMI_D06__GPIO_0_6 0x0063 +#define MX23_PAD_GPMI_D07__GPIO_0_7 0x0073 +#define MX23_PAD_GPMI_D08__GPIO_0_8 0x0083 +#define MX23_PAD_GPMI_D09__GPIO_0_9 0x0093 +#define MX23_PAD_GPMI_D10__GPIO_0_10 0x00a3 +#define MX23_PAD_GPMI_D11__GPIO_0_11 0x00b3 +#define MX23_PAD_GPMI_D12__GPIO_0_12 0x00c3 +#define MX23_PAD_GPMI_D13__GPIO_0_13 0x00d3 +#define MX23_PAD_GPMI_D14__GPIO_0_14 0x00e3 +#define MX23_PAD_GPMI_D15__GPIO_0_15 0x00f3 +#define MX23_PAD_GPMI_CLE__GPIO_0_16 0x0103 +#define MX23_PAD_GPMI_ALE__GPIO_0_17 0x0113 +#define MX23_PAD_GPMI_CE2N__GPIO_0_18 0x0123 +#define MX23_PAD_GPMI_RDY0__GPIO_0_19 0x0133 +#define MX23_PAD_GPMI_RDY1__GPIO_0_20 0x0143 +#define MX23_PAD_GPMI_RDY2__GPIO_0_21 0x0153 +#define MX23_PAD_GPMI_RDY3__GPIO_0_22 0x0163 +#define MX23_PAD_GPMI_WPN__GPIO_0_23 0x0173 +#define MX23_PAD_GPMI_WRN__GPIO_0_24 0x0183 +#define MX23_PAD_GPMI_RDN__GPIO_0_25 0x0193 +#define MX23_PAD_AUART1_CTS__GPIO_0_26 0x01a3 +#define MX23_PAD_AUART1_RTS__GPIO_0_27 0x01b3 +#define MX23_PAD_AUART1_RX__GPIO_0_28 0x01c3 +#define MX23_PAD_AUART1_TX__GPIO_0_29 0x01d3 +#define MX23_PAD_I2C_SCL__GPIO_0_30 0x01e3 +#define MX23_PAD_I2C_SDA__GPIO_0_31 0x01f3 +#define MX23_PAD_LCD_D00__GPIO_1_0 0x1003 +#define MX23_PAD_LCD_D01__GPIO_1_1 0x1013 +#define MX23_PAD_LCD_D02__GPIO_1_2 0x1023 +#define MX23_PAD_LCD_D03__GPIO_1_3 0x1033 +#define MX23_PAD_LCD_D04__GPIO_1_4 0x1043 +#define MX23_PAD_LCD_D05__GPIO_1_5 0x1053 +#define MX23_PAD_LCD_D06__GPIO_1_6 0x1063 +#define MX23_PAD_LCD_D07__GPIO_1_7 0x1073 +#define MX23_PAD_LCD_D08__GPIO_1_8 0x1083 +#define MX23_PAD_LCD_D09__GPIO_1_9 0x1093 +#define MX23_PAD_LCD_D10__GPIO_1_10 0x10a3 +#define MX23_PAD_LCD_D11__GPIO_1_11 0x10b3 +#define MX23_PAD_LCD_D12__GPIO_1_12 0x10c3 +#define MX23_PAD_LCD_D13__GPIO_1_13 0x10d3 +#define MX23_PAD_LCD_D14__GPIO_1_14 0x10e3 +#define MX23_PAD_LCD_D15__GPIO_1_15 0x10f3 +#define MX23_PAD_LCD_D16__GPIO_1_16 0x1103 +#define MX23_PAD_LCD_D17__GPIO_1_17 0x1113 +#define MX23_PAD_LCD_RESET__GPIO_1_18 0x1123 +#define MX23_PAD_LCD_RS__GPIO_1_19 0x1133 +#define MX23_PAD_LCD_WR__GPIO_1_20 0x1143 +#define MX23_PAD_LCD_CS__GPIO_1_21 0x1153 +#define MX23_PAD_LCD_DOTCK__GPIO_1_22 0x1163 +#define MX23_PAD_LCD_ENABLE__GPIO_1_23 0x1173 +#define MX23_PAD_LCD_HSYNC__GPIO_1_24 0x1183 +#define MX23_PAD_LCD_VSYNC__GPIO_1_25 0x1193 +#define MX23_PAD_PWM0__GPIO_1_26 0x11a3 +#define MX23_PAD_PWM1__GPIO_1_27 0x11b3 +#define MX23_PAD_PWM2__GPIO_1_28 0x11c3 +#define MX23_PAD_PWM3__GPIO_1_29 0x11d3 +#define MX23_PAD_PWM4__GPIO_1_30 0x11e3 +#define MX23_PAD_SSP1_CMD__GPIO_2_0 0x2003 +#define MX23_PAD_SSP1_DETECT__GPIO_2_1 0x2013 +#define MX23_PAD_SSP1_DATA0__GPIO_2_2 0x2023 +#define MX23_PAD_SSP1_DATA1__GPIO_2_3 0x2033 +#define MX23_PAD_SSP1_DATA2__GPIO_2_4 0x2043 +#define MX23_PAD_SSP1_DATA3__GPIO_2_5 0x2053 +#define MX23_PAD_SSP1_SCK__GPIO_2_6 0x2063 +#define MX23_PAD_ROTARYA__GPIO_2_7 0x2073 +#define MX23_PAD_ROTARYB__GPIO_2_8 0x2083 +#define MX23_PAD_EMI_A00__GPIO_2_9 0x2093 +#define MX23_PAD_EMI_A01__GPIO_2_10 0x20a3 +#define MX23_PAD_EMI_A02__GPIO_2_11 0x20b3 +#define MX23_PAD_EMI_A03__GPIO_2_12 0x20c3 +#define MX23_PAD_EMI_A04__GPIO_2_13 0x20d3 +#define MX23_PAD_EMI_A05__GPIO_2_14 0x20e3 +#define MX23_PAD_EMI_A06__GPIO_2_15 0x20f3 +#define MX23_PAD_EMI_A07__GPIO_2_16 0x2103 +#define MX23_PAD_EMI_A08__GPIO_2_17 0x2113 +#define MX23_PAD_EMI_A09__GPIO_2_18 0x2123 +#define MX23_PAD_EMI_A10__GPIO_2_19 0x2133 +#define MX23_PAD_EMI_A11__GPIO_2_20 0x2143 +#define MX23_PAD_EMI_A12__GPIO_2_21 0x2153 +#define MX23_PAD_EMI_BA0__GPIO_2_22 0x2163 +#define MX23_PAD_EMI_BA1__GPIO_2_23 0x2173 +#define MX23_PAD_EMI_CASN__GPIO_2_24 0x2183 +#define MX23_PAD_EMI_CE0N__GPIO_2_25 0x2193 +#define MX23_PAD_EMI_CE1N__GPIO_2_26 0x21a3 +#define MX23_PAD_GPMI_CE1N__GPIO_2_27 0x21b3 +#define MX23_PAD_GPMI_CE0N__GPIO_2_28 0x21c3 +#define MX23_PAD_EMI_CKE__GPIO_2_29 0x21d3 +#define MX23_PAD_EMI_RASN__GPIO_2_30 0x21e3 +#define MX23_PAD_EMI_WEN__GPIO_2_31 0x21f3 + +#endif /* __DT_BINDINGS_MX23_PINCTRL_H__ */ diff --git a/arch/arm/boot/dts/imx23-stmp378x_devb.dts b/arch/arm/boot/dts/imx23-stmp378x_devb.dts index 85c3864b6a56..cb64e2b191ea 100644 --- a/arch/arm/boot/dts/imx23-stmp378x_devb.dts +++ b/arch/arm/boot/dts/imx23-stmp378x_devb.dts @@ -10,7 +10,7 @@ */ /dts-v1/; -/include/ "imx23.dtsi" +#include "imx23.dtsi" / { model = "Freescale STMP378x Development Board"; @@ -39,12 +39,12 @@ hog_pins_a: hog@0 { reg = <0>; fsl,pinmux-ids = < - 0x11d3 /* MX23_PAD_PWM3__GPIO_1_29 */ - 0x11e3 /* MX23_PAD_PWM4__GPIO_1_30 */ + MX23_PAD_PWM3__GPIO_1_29 + MX23_PAD_PWM4__GPIO_1_30 >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; }; }; diff --git a/arch/arm/boot/dts/imx23.dtsi b/arch/arm/boot/dts/imx23.dtsi index 28b5ce289662..c96ceaef7ddf 100644 --- a/arch/arm/boot/dts/imx23.dtsi +++ b/arch/arm/boot/dts/imx23.dtsi @@ -9,7 +9,8 @@ * http://www.gnu.org/copyleft/gpl.html */ -/include/ "skeleton.dtsi" +#include "skeleton.dtsi" +#include "imx23-pinfunc.h" / { interrupt-parent = <&icoll>; @@ -137,174 +138,174 @@ duart_pins_a: duart@0 { reg = <0>; fsl,pinmux-ids = < - 0x11a2 /* MX23_PAD_PWM0__DUART_RX */ - 0x11b2 /* MX23_PAD_PWM1__DUART_TX */ + MX23_PAD_PWM0__DUART_RX + MX23_PAD_PWM1__DUART_TX >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; auart0_pins_a: auart0@0 { reg = <0>; fsl,pinmux-ids = < - 0x01c0 /* MX23_PAD_AUART1_RX__AUART1_RX */ - 0x01d0 /* MX23_PAD_AUART1_TX__AUART1_TX */ - 0x01a0 /* MX23_PAD_AUART1_CTS__AUART1_CTS */ - 0x01b0 /* MX23_PAD_AUART1_RTS__AUART1_RTS */ + MX23_PAD_AUART1_RX__AUART1_RX + MX23_PAD_AUART1_TX__AUART1_TX + MX23_PAD_AUART1_CTS__AUART1_CTS + MX23_PAD_AUART1_RTS__AUART1_RTS >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; auart0_2pins_a: auart0-2pins@0 { reg = <0>; fsl,pinmux-ids = < - 0x01e2 /* MX23_PAD_I2C_SCL__AUART1_TX */ - 0x01f2 /* MX23_PAD_I2C_SDA__AUART1_RX */ + MX23_PAD_I2C_SCL__AUART1_TX + MX23_PAD_I2C_SDA__AUART1_RX >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; gpmi_pins_a: gpmi-nand@0 { reg = <0>; fsl,pinmux-ids = < - 0x0000 /* MX23_PAD_GPMI_D00__GPMI_D00 */ - 0x0010 /* MX23_PAD_GPMI_D01__GPMI_D01 */ - 0x0020 /* MX23_PAD_GPMI_D02__GPMI_D02 */ - 0x0030 /* MX23_PAD_GPMI_D03__GPMI_D03 */ - 0x0040 /* MX23_PAD_GPMI_D04__GPMI_D04 */ - 0x0050 /* MX23_PAD_GPMI_D05__GPMI_D05 */ - 0x0060 /* MX23_PAD_GPMI_D06__GPMI_D06 */ - 0x0070 /* MX23_PAD_GPMI_D07__GPMI_D07 */ - 0x0100 /* MX23_PAD_GPMI_CLE__GPMI_CLE */ - 0x0110 /* MX23_PAD_GPMI_ALE__GPMI_ALE */ - 0x0130 /* MX23_PAD_GPMI_RDY0__GPMI_RDY0 */ - 0x0140 /* MX23_PAD_GPMI_RDY1__GPMI_RDY1 */ - 0x0170 /* MX23_PAD_GPMI_WPN__GPMI_WPN */ - 0x0180 /* MX23_PAD_GPMI_WRN__GPMI_WRN */ - 0x0190 /* MX23_PAD_GPMI_RDN__GPMI_RDN */ - 0x21b0 /* MX23_PAD_GPMI_CE1N__GPMI_CE1N */ - 0x21c0 /* MX23_PAD_GPMI_CE0N__GPMI_CE0N */ + MX23_PAD_GPMI_D00__GPMI_D00 + MX23_PAD_GPMI_D01__GPMI_D01 + MX23_PAD_GPMI_D02__GPMI_D02 + MX23_PAD_GPMI_D03__GPMI_D03 + MX23_PAD_GPMI_D04__GPMI_D04 + MX23_PAD_GPMI_D05__GPMI_D05 + MX23_PAD_GPMI_D06__GPMI_D06 + MX23_PAD_GPMI_D07__GPMI_D07 + MX23_PAD_GPMI_CLE__GPMI_CLE + MX23_PAD_GPMI_ALE__GPMI_ALE + MX23_PAD_GPMI_RDY0__GPMI_RDY0 + MX23_PAD_GPMI_RDY1__GPMI_RDY1 + MX23_PAD_GPMI_WPN__GPMI_WPN + MX23_PAD_GPMI_WRN__GPMI_WRN + MX23_PAD_GPMI_RDN__GPMI_RDN + MX23_PAD_GPMI_CE1N__GPMI_CE1N + MX23_PAD_GPMI_CE0N__GPMI_CE0N >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; gpmi_pins_fixup: gpmi-pins-fixup { fsl,pinmux-ids = < - 0x0170 /* MX23_PAD_GPMI_WPN__GPMI_WPN */ - 0x0180 /* MX23_PAD_GPMI_WRN__GPMI_WRN */ - 0x0190 /* MX23_PAD_GPMI_RDN__GPMI_RDN */ + MX23_PAD_GPMI_WPN__GPMI_WPN + MX23_PAD_GPMI_WRN__GPMI_WRN + MX23_PAD_GPMI_RDN__GPMI_RDN >; - fsl,drive-strength = <2>; + fsl,drive-strength = <MXS_DRIVE_12mA>; }; mmc0_4bit_pins_a: mmc0-4bit@0 { reg = <0>; fsl,pinmux-ids = < - 0x2020 /* MX23_PAD_SSP1_DATA0__SSP1_DATA0 */ - 0x2030 /* MX23_PAD_SSP1_DATA1__SSP1_DATA1 */ - 0x2040 /* MX23_PAD_SSP1_DATA2__SSP1_DATA2 */ - 0x2050 /* MX23_PAD_SSP1_DATA3__SSP1_DATA3 */ - 0x2000 /* MX23_PAD_SSP1_CMD__SSP1_CMD */ - 0x2060 /* MX23_PAD_SSP1_SCK__SSP1_SCK */ + MX23_PAD_SSP1_DATA0__SSP1_DATA0 + MX23_PAD_SSP1_DATA1__SSP1_DATA1 + MX23_PAD_SSP1_DATA2__SSP1_DATA2 + MX23_PAD_SSP1_DATA3__SSP1_DATA3 + MX23_PAD_SSP1_CMD__SSP1_CMD + MX23_PAD_SSP1_SCK__SSP1_SCK >; - fsl,drive-strength = <1>; - fsl,voltage = <1>; - fsl,pull-up = <1>; + fsl,drive-strength = <MXS_DRIVE_8mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_ENABLE>; }; mmc0_8bit_pins_a: mmc0-8bit@0 { reg = <0>; fsl,pinmux-ids = < - 0x2020 /* MX23_PAD_SSP1_DATA0__SSP1_DATA0 */ - 0x2030 /* MX23_PAD_SSP1_DATA1__SSP1_DATA1 */ - 0x2040 /* MX23_PAD_SSP1_DATA2__SSP1_DATA2 */ - 0x2050 /* MX23_PAD_SSP1_DATA3__SSP1_DATA3 */ - 0x0082 /* MX23_PAD_GPMI_D08__SSP1_DATA4 */ - 0x0092 /* MX23_PAD_GPMI_D09__SSP1_DATA5 */ - 0x00a2 /* MX23_PAD_GPMI_D10__SSP1_DATA6 */ - 0x00b2 /* MX23_PAD_GPMI_D11__SSP1_DATA7 */ - 0x2000 /* MX23_PAD_SSP1_CMD__SSP1_CMD */ - 0x2010 /* MX23_PAD_SSP1_DETECT__SSP1_DETECT */ - 0x2060 /* MX23_PAD_SSP1_SCK__SSP1_SCK */ + MX23_PAD_SSP1_DATA0__SSP1_DATA0 + MX23_PAD_SSP1_DATA1__SSP1_DATA1 + MX23_PAD_SSP1_DATA2__SSP1_DATA2 + MX23_PAD_SSP1_DATA3__SSP1_DATA3 + MX23_PAD_GPMI_D08__SSP1_DATA4 + MX23_PAD_GPMI_D09__SSP1_DATA5 + MX23_PAD_GPMI_D10__SSP1_DATA6 + MX23_PAD_GPMI_D11__SSP1_DATA7 + MX23_PAD_SSP1_CMD__SSP1_CMD + MX23_PAD_SSP1_DETECT__SSP1_DETECT + MX23_PAD_SSP1_SCK__SSP1_SCK >; - fsl,drive-strength = <1>; - fsl,voltage = <1>; - fsl,pull-up = <1>; + fsl,drive-strength = <MXS_DRIVE_8mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_ENABLE>; }; mmc0_pins_fixup: mmc0-pins-fixup { fsl,pinmux-ids = < - 0x2010 /* MX23_PAD_SSP1_DETECT__SSP1_DETECT */ - 0x2060 /* MX23_PAD_SSP1_SCK__SSP1_SCK */ + MX23_PAD_SSP1_DETECT__SSP1_DETECT + MX23_PAD_SSP1_SCK__SSP1_SCK >; - fsl,pull-up = <0>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; pwm2_pins_a: pwm2@0 { reg = <0>; fsl,pinmux-ids = < - 0x11c0 /* MX23_PAD_PWM2__PWM2 */ + MX23_PAD_PWM2__PWM2 >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; lcdif_24bit_pins_a: lcdif-24bit@0 { reg = <0>; fsl,pinmux-ids = < - 0x1000 /* MX23_PAD_LCD_D00__LCD_D0 */ - 0x1010 /* MX23_PAD_LCD_D01__LCD_D1 */ - 0x1020 /* MX23_PAD_LCD_D02__LCD_D2 */ - 0x1030 /* MX23_PAD_LCD_D03__LCD_D3 */ - 0x1040 /* MX23_PAD_LCD_D04__LCD_D4 */ - 0x1050 /* MX23_PAD_LCD_D05__LCD_D5 */ - 0x1060 /* MX23_PAD_LCD_D06__LCD_D6 */ - 0x1070 /* MX23_PAD_LCD_D07__LCD_D7 */ - 0x1080 /* MX23_PAD_LCD_D08__LCD_D8 */ - 0x1090 /* MX23_PAD_LCD_D09__LCD_D9 */ - 0x10a0 /* MX23_PAD_LCD_D10__LCD_D10 */ - 0x10b0 /* MX23_PAD_LCD_D11__LCD_D11 */ - 0x10c0 /* MX23_PAD_LCD_D12__LCD_D12 */ - 0x10d0 /* MX23_PAD_LCD_D13__LCD_D13 */ - 0x10e0 /* MX23_PAD_LCD_D14__LCD_D14 */ - 0x10f0 /* MX23_PAD_LCD_D15__LCD_D15 */ - 0x1100 /* MX23_PAD_LCD_D16__LCD_D16 */ - 0x1110 /* MX23_PAD_LCD_D17__LCD_D17 */ - 0x0081 /* MX23_PAD_GPMI_D08__LCD_D18 */ - 0x0091 /* MX23_PAD_GPMI_D09__LCD_D19 */ - 0x00a1 /* MX23_PAD_GPMI_D10__LCD_D20 */ - 0x00b1 /* MX23_PAD_GPMI_D11__LCD_D21 */ - 0x00c1 /* MX23_PAD_GPMI_D12__LCD_D22 */ - 0x00d1 /* MX23_PAD_GPMI_D13__LCD_D23 */ - 0x1160 /* MX23_PAD_LCD_DOTCK__LCD_DOTCK */ - 0x1170 /* MX23_PAD_LCD_ENABLE__LCD_ENABLE */ - 0x1180 /* MX23_PAD_LCD_HSYNC__LCD_HSYNC */ - 0x1190 /* MX23_PAD_LCD_VSYNC__LCD_VSYNC */ + MX23_PAD_LCD_D00__LCD_D00 + MX23_PAD_LCD_D01__LCD_D01 + MX23_PAD_LCD_D02__LCD_D02 + MX23_PAD_LCD_D03__LCD_D03 + MX23_PAD_LCD_D04__LCD_D04 + MX23_PAD_LCD_D05__LCD_D05 + MX23_PAD_LCD_D06__LCD_D06 + MX23_PAD_LCD_D07__LCD_D07 + MX23_PAD_LCD_D08__LCD_D08 + MX23_PAD_LCD_D09__LCD_D09 + MX23_PAD_LCD_D10__LCD_D10 + MX23_PAD_LCD_D11__LCD_D11 + MX23_PAD_LCD_D12__LCD_D12 + MX23_PAD_LCD_D13__LCD_D13 + MX23_PAD_LCD_D14__LCD_D14 + MX23_PAD_LCD_D15__LCD_D15 + MX23_PAD_LCD_D16__LCD_D16 + MX23_PAD_LCD_D17__LCD_D17 + MX23_PAD_GPMI_D08__LCD_D18 + MX23_PAD_GPMI_D09__LCD_D19 + MX23_PAD_GPMI_D10__LCD_D20 + MX23_PAD_GPMI_D11__LCD_D21 + MX23_PAD_GPMI_D12__LCD_D22 + MX23_PAD_GPMI_D13__LCD_D23 + MX23_PAD_LCD_DOTCK__LCD_DOTCK + MX23_PAD_LCD_ENABLE__LCD_ENABLE + MX23_PAD_LCD_HSYNC__LCD_HSYNC + MX23_PAD_LCD_VSYNC__LCD_VSYNC >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; spi2_pins_a: spi2@0 { reg = <0>; fsl,pinmux-ids = < - 0x0182 /* MX23_PAD_GPMI_WRN__SSP2_SCK */ - 0x0142 /* MX23_PAD_GPMI_RDY1__SSP2_CMD */ - 0x0002 /* MX23_PAD_GPMI_D00__SSP2_DATA0 */ - 0x0032 /* MX23_PAD_GPMI_D03__SSP2_DATA3 */ + MX23_PAD_GPMI_WRN__SSP2_SCK + MX23_PAD_GPMI_RDY1__SSP2_CMD + MX23_PAD_GPMI_D00__SSP2_DATA0 + MX23_PAD_GPMI_D03__SSP2_DATA3 >; - fsl,drive-strength = <1>; - fsl,voltage = <1>; - fsl,pull-up = <1>; + fsl,drive-strength = <MXS_DRIVE_8mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_ENABLE>; }; }; @@ -430,6 +431,7 @@ reg = <0x80050000 0x2000>; interrupts = <36 37 38 39 40 41 42 43 44>; status = "disabled"; + clocks = <&clks 26>; }; spdif@80054000 { diff --git a/arch/arm/boot/dts/imx27-apf27dev.dts b/arch/arm/boot/dts/imx27-apf27dev.dts index 2a377ca1881a..47c8c26012e4 100644 --- a/arch/arm/boot/dts/imx27-apf27dev.dts +++ b/arch/arm/boot/dts/imx27-apf27dev.dts @@ -16,6 +16,26 @@ model = "Armadeus Systems APF27Dev docking/development board"; compatible = "armadeus,imx27-apf27dev", "armadeus,imx27-apf27", "fsl,imx27"; + display: display { + model = "Chimei-LW700AT9003"; + native-mode = <&timing0>; + bits-per-pixel = <16>; /* non-standard but required */ + fsl,pcr = <0xfae80083>; /* non-standard but required */ + display-timings { + timing0: 640x480 { + clock-frequency = <33000033>; + hactive = <800>; + vactive = <640>; + hback-porch = <96>; + hfront-porch = <96>; + vback-porch = <20>; + vfront-porch = <21>; + hsync-len = <64>; + vsync-len = <4>; + }; + }; + }; + gpio-keys { compatible = "gpio-keys"; @@ -50,6 +70,12 @@ status = "okay"; }; +&fb { + display = <&display>; + fsl,dmacr = <0x00020010>; + status = "okay"; +}; + &i2c1 { clock-frequency = <400000>; status = "okay"; diff --git a/arch/arm/boot/dts/imx27.dtsi b/arch/arm/boot/dts/imx27.dtsi index b7a1c6d950b9..826231eb4446 100644 --- a/arch/arm/boot/dts/imx27.dtsi +++ b/arch/arm/boot/dts/imx27.dtsi @@ -123,6 +123,7 @@ }; pwm: pwm@10006000 { + #pwm-cells = <2>; compatible = "fsl,imx27-pwm"; reg = <0x10006000 0x1000>; interrupts = <23>; diff --git a/arch/arm/boot/dts/imx28-apf28.dts b/arch/arm/boot/dts/imx28-apf28.dts index 7eb075876c4c..7198fe3798c6 100644 --- a/arch/arm/boot/dts/imx28-apf28.dts +++ b/arch/arm/boot/dts/imx28-apf28.dts @@ -10,7 +10,7 @@ */ /dts-v1/; -/include/ "imx28.dtsi" +#include "imx28.dtsi" / { model = "Armadeus Systems APF28 module"; diff --git a/arch/arm/boot/dts/imx28-apf28dev.dts b/arch/arm/boot/dts/imx28-apf28dev.dts index b602494c152b..e2efd8d89c4f 100644 --- a/arch/arm/boot/dts/imx28-apf28dev.dts +++ b/arch/arm/boot/dts/imx28-apf28dev.dts @@ -10,7 +10,7 @@ */ /* APF28Dev is a docking board for the APF28 SOM */ -/include/ "imx28-apf28.dts" +#include "imx28-apf28.dts" / { model = "Armadeus Systems APF28Dev docking/development board"; @@ -41,30 +41,30 @@ hog_pins_apf28dev: hog@0 { reg = <0>; fsl,pinmux-ids = < - 0x1103 /* MX28_PAD_LCD_D16__GPIO_1_16 */ - 0x1113 /* MX28_PAD_LCD_D17__GPIO_1_17 */ - 0x1123 /* MX28_PAD_LCD_D18__GPIO_1_18 */ - 0x1133 /* MX28_PAD_LCD_D19__GPIO_1_19 */ - 0x1143 /* MX28_PAD_LCD_D20__GPIO_1_20 */ - 0x1153 /* MX28_PAD_LCD_D21__GPIO_1_21 */ - 0x1163 /* MX28_PAD_LCD_D22__GPIO_1_22 */ + MX28_PAD_LCD_D16__GPIO_1_16 + MX28_PAD_LCD_D17__GPIO_1_17 + MX28_PAD_LCD_D18__GPIO_1_18 + MX28_PAD_LCD_D19__GPIO_1_19 + MX28_PAD_LCD_D20__GPIO_1_20 + MX28_PAD_LCD_D21__GPIO_1_21 + MX28_PAD_LCD_D22__GPIO_1_22 >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; lcdif_pins_apf28dev: lcdif-apf28dev@0 { reg = <0>; fsl,pinmux-ids = < - 0x1181 /* MX28_PAD_LCD_RD_E__LCD_VSYNC */ - 0x1191 /* MX28_PAD_LCD_WR_RWN__LCD_HSYNC */ - 0x11a1 /* MX28_PAD_LCD_RS__LCD_DOTCLK */ - 0x11b1 /* MX28_PAD_LCD_CS__LCD_ENABLE */ + MX28_PAD_LCD_RD_E__LCD_VSYNC + MX28_PAD_LCD_WR_RWN__LCD_HSYNC + MX28_PAD_LCD_RS__LCD_DOTCLK + MX28_PAD_LCD_CS__LCD_ENABLE >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; }; diff --git a/arch/arm/boot/dts/imx28-apx4devkit.dts b/arch/arm/boot/dts/imx28-apx4devkit.dts index 0e7fed47bd8d..6f254ca816cb 100644 --- a/arch/arm/boot/dts/imx28-apx4devkit.dts +++ b/arch/arm/boot/dts/imx28-apx4devkit.dts @@ -1,5 +1,5 @@ /dts-v1/; -/include/ "imx28.dtsi" +#include "imx28.dtsi" / { model = "Bluegiga APX4 Development Kit"; @@ -40,53 +40,53 @@ hog_pins_a: hog@0 { reg = <0>; fsl,pinmux-ids = < - 0x0113 /* MX28_PAD_GPMI_CE1N__GPIO_0_17 */ - 0x0153 /* MX28_PAD_GPMI_RDY1__GPIO_0_21 */ - 0x2123 /* MX28_PAD_SSP2_MISO__GPIO_2_18 */ - 0x2131 /* MX28_PAD_SSP2_SS0__GPIO_2_19 */ - 0x31c3 /* MX28_PAD_PWM3__GPIO_3_28 */ - 0x31e3 /* MX28_PAD_LCD_RESET__GPIO_3_30 */ - 0x4143 /* MX28_PAD_JTAG_RTCK__GPIO_4_20 */ + MX28_PAD_GPMI_CE1N__GPIO_0_17 + MX28_PAD_GPMI_RDY1__GPIO_0_21 + MX28_PAD_SSP2_MISO__GPIO_2_18 + MX28_PAD_SSP2_SS0__AUART3_TX /* was: 0x2131 - MX28_PAD_SSP2_SS0__GPIO_2_19 */ + MX28_PAD_PWM3__GPIO_3_28 + MX28_PAD_LCD_RESET__GPIO_3_30 + MX28_PAD_JTAG_RTCK__GPIO_4_20 >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; lcdif_pins_apx4: lcdif-apx4@0 { reg = <0>; fsl,pinmux-ids = < - 0x1181 /* MX28_PAD_LCD_RD_E__LCD_VSYNC */ - 0x1191 /* MX28_PAD_LCD_WR_RWN__LCD_HSYNC */ - 0x11a1 /* MX28_PAD_LCD_RS__LCD_DOTCLK */ - 0x11b1 /* MX28_PAD_LCD_CS__LCD_ENABLE */ + MX28_PAD_LCD_RD_E__LCD_VSYNC + MX28_PAD_LCD_WR_RWN__LCD_HSYNC + MX28_PAD_LCD_RS__LCD_DOTCLK + MX28_PAD_LCD_CS__LCD_ENABLE >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; mmc2_4bit_pins_apx4: mmc2-4bit-apx4@0 { reg = <0>; fsl,pinmux-ids = < - 0x2041 /* MX28_PAD_SSP0_DATA4__SSP2_D0 */ - 0x2051 /* MX28_PAD_SSP0_DATA5__SSP2_D3 */ - 0x2061 /* MX28_PAD_SSP0_DATA6__SSP2_CMD */ - 0x2071 /* MX28_PAD_SSP0_DATA7__SSP2_SCK */ - 0x2141 /* MX28_PAD_SSP2_SS1__SSP2_D1 */ - 0x2151 /* MX28_PAD_SSP2_SS2__SSP2_D2 */ + MX28_PAD_SSP0_DATA4__SSP2_D0 + MX28_PAD_SSP0_DATA5__SSP2_D3 + MX28_PAD_SSP0_DATA6__SSP2_CMD + MX28_PAD_SSP0_DATA7__SSP2_SCK + MX28_PAD_SSP2_SS1__SSP2_D1 + MX28_PAD_SSP2_SS2__SSP2_D2 >; - fsl,drive-strength = <1>; - fsl,voltage = <1>; - fsl,pull-up = <1>; + fsl,drive-strength = <MXS_DRIVE_8mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_ENABLE>; }; mmc2_sck_cfg_apx4: mmc2-sck-cfg-apx4 { fsl,pinmux-ids = < - 0x2071 /* MX28_PAD_SSP0_DATA7__SSP2_SCK */ + MX28_PAD_SSP0_DATA7__SSP2_SCK >; - fsl,drive-strength = <2>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_12mA>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; }; diff --git a/arch/arm/boot/dts/imx28-cfa10036.dts b/arch/arm/boot/dts/imx28-cfa10036.dts index 1ec8c94bbac9..cabb6171a19d 100644 --- a/arch/arm/boot/dts/imx28-cfa10036.dts +++ b/arch/arm/boot/dts/imx28-cfa10036.dts @@ -10,7 +10,7 @@ */ /dts-v1/; -/include/ "imx28.dtsi" +#include "imx28.dtsi" / { model = "Crystalfontz CFA-10036 Board"; @@ -26,31 +26,31 @@ ssd1306_cfa10036: ssd1306-10036@0 { reg = <0>; fsl,pinmux-ids = < - 0x2073 /* MX28_PAD_SSP0_D7__GPIO_2_7 */ + MX28_PAD_SSP0_DATA7__GPIO_2_7 >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; led_pins_cfa10036: leds-10036@0 { reg = <0>; fsl,pinmux-ids = < - 0x3043 /* MX28_PAD_AUART1_RX__GPIO_3_4 */ + MX28_PAD_AUART1_RX__GPIO_3_4 >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; usb0_otg_cfa10036: otg-10036@0 { reg = <0>; fsl,pinmux-ids = < - 0x0142 /* MX28_PAD_GPMI_READY0__USB0_ID */ + MX28_PAD_GPMI_RDY0__USB0_ID >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; }; diff --git a/arch/arm/boot/dts/imx28-cfa10037.dts b/arch/arm/boot/dts/imx28-cfa10037.dts index 182b99fe35f3..f93e9a700e52 100644 --- a/arch/arm/boot/dts/imx28-cfa10037.dts +++ b/arch/arm/boot/dts/imx28-cfa10037.dts @@ -13,7 +13,7 @@ * The CFA-10049 is an expansion board for the CFA-10036 module, thus we * need to include the CFA-10036 DTS. */ -/include/ "imx28-cfa10036.dts" +#include "imx28-cfa10036.dts" / { model = "Crystalfontz CFA-10037 Board"; @@ -25,21 +25,21 @@ usb_pins_cfa10037: usb-10037@0 { reg = <0>; fsl,pinmux-ids = < - 0x0073 /* MX28_PAD_GPMI_D7__GPIO_0_7 */ + MX28_PAD_GPMI_D07__GPIO_0_7 >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; mac0_pins_cfa10037: mac0-10037@0 { reg = <0>; fsl,pinmux-ids = < - 0x2153 /* MX28_PAD_SSP2_D5__GPIO_2_21 */ + MX28_PAD_SSP2_SS2__GPIO_2_21 >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; }; }; diff --git a/arch/arm/boot/dts/imx28-cfa10049.dts b/arch/arm/boot/dts/imx28-cfa10049.dts index 06e4cfaf7dd2..7087b4bf6a8f 100644 --- a/arch/arm/boot/dts/imx28-cfa10049.dts +++ b/arch/arm/boot/dts/imx28-cfa10049.dts @@ -13,7 +13,7 @@ * The CFA-10049 is an expansion board for the CFA-10036 module, thus we * need to include the CFA-10036 DTS. */ -/include/ "imx28-cfa10036.dts" +#include "imx28-cfa10036.dts" / { model = "Crystalfontz CFA-10049 Board"; @@ -25,150 +25,150 @@ usb_pins_cfa10049: usb-10049@0 { reg = <0>; fsl,pinmux-ids = < - 0x0073 /* MX28_PAD_GPMI_D7__GPIO_0_7 */ + MX28_PAD_GPMI_D07__GPIO_0_7 >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; i2cmux_pins_cfa10049: i2cmux-10049@0 { reg = <0>; fsl,pinmux-ids = < - 0x1163 /* MX28_PAD_LCD_D22__GPIO_1_22 */ - 0x1173 /* MX28_PAD_LCD_D22__GPIO_1_23 */ + MX28_PAD_LCD_D22__GPIO_1_22 + MX28_PAD_LCD_D23__GPIO_1_23 >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; mac0_pins_cfa10049: mac0-10049@0 { reg = <0>; fsl,pinmux-ids = < - 0x2153 /* MX28_PAD_SSP2_D5__GPIO_2_21 */ + MX28_PAD_SSP2_SS2__GPIO_2_21 >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; pca_pins_cfa10049: pca-10049@0 { reg = <0>; fsl,pinmux-ids = < - 0x2133 /* MX28_PAD_SSP2_D3__GPIO_2_19 */ + MX28_PAD_SSP2_SS0__GPIO_2_19 >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <1>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_ENABLE>; }; rotary_pins_cfa10049: rotary-10049@0 { reg = <0>; fsl,pinmux-ids = < - 0x3183 /* MX28_PAD_I2C0_SCL__GPIO_3_24 */ - 0x3193 /* MX28_PAD_I2C0_SDA__GPIO_3_25 */ + MX28_PAD_I2C0_SCL__GPIO_3_24 + MX28_PAD_I2C0_SDA__GPIO_3_25 >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <1>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_ENABLE>; }; rotary_btn_pins_cfa10049: rotary-btn-10049@0 { reg = <0>; fsl,pinmux-ids = < - 0x31a3 /* MX28_PAD_SAIF_SDATA0__GPIO_3_26 */ + MX28_PAD_SAIF1_SDATA0__GPIO_3_26 >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <1>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_ENABLE>; }; spi2_pins_cfa10049: spi2-cfa10049@0 { reg = <0>; fsl,pinmux-ids = < - 0x2103 /* MX28_PAD_SSP2_SCK__GPIO_2_16 */ - 0x2113 /* MX28_PAD_SSP2_CMD__GPIO_2_17 */ - 0x2123 /* MX28_PAD_SSP2_D0__GPIO_2_18 */ - 0x3053 /* MX28_PAD_AUART1_TX__GPIO_3_5 */ + MX28_PAD_SSP2_SCK__GPIO_2_16 + MX28_PAD_SSP2_MOSI__GPIO_2_17 + MX28_PAD_SSP2_MISO__GPIO_2_18 + MX28_PAD_AUART1_TX__GPIO_3_5 >; - fsl,drive-strength = <1>; - fsl,voltage = <1>; - fsl,pull-up = <1>; + fsl,drive-strength = <MXS_DRIVE_8mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_ENABLE>; }; spi3_pins_cfa10049: spi3-cfa10049@0 { reg = <0>; fsl,pinmux-ids = < - 0x0183 /* MX28_PAD_GPMI_RDN__GPIO_0_24 */ - 0x01c3 /* MX28_PAD_GPMI_RESETN__GPIO_0_28 */ - 0x0113 /* MX28_PAD_GPMI_CE1N__GPIO_0_17 */ - 0x01a3 /* MX28_PAD_GPMI_ALE__GPIO_0_26 */ - 0x01b3 /* MX28_PAD_GPMI_CLE__GPIO_0_27 */ + MX28_PAD_GPMI_RDN__GPIO_0_24 + MX28_PAD_GPMI_RESETN__GPIO_0_28 + MX28_PAD_GPMI_CE1N__GPIO_0_17 + MX28_PAD_GPMI_ALE__GPIO_0_26 + MX28_PAD_GPMI_CLE__GPIO_0_27 >; - fsl,drive-strength = <1>; - fsl,voltage = <1>; - fsl,pull-up = <1>; + fsl,drive-strength = <MXS_DRIVE_8mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_ENABLE>; }; lcdif_18bit_pins_cfa10049: lcdif-18bit@0 { reg = <0>; fsl,pinmux-ids = < - 0x1000 /* MX28_PAD_LCD_D00__LCD_D0 */ - 0x1010 /* MX28_PAD_LCD_D01__LCD_D1 */ - 0x1020 /* MX28_PAD_LCD_D02__LCD_D2 */ - 0x1030 /* MX28_PAD_LCD_D03__LCD_D3 */ - 0x1040 /* MX28_PAD_LCD_D04__LCD_D4 */ - 0x1050 /* MX28_PAD_LCD_D05__LCD_D5 */ - 0x1060 /* MX28_PAD_LCD_D06__LCD_D6 */ - 0x1070 /* MX28_PAD_LCD_D07__LCD_D7 */ - 0x1080 /* MX28_PAD_LCD_D08__LCD_D8 */ - 0x1090 /* MX28_PAD_LCD_D09__LCD_D9 */ - 0x10a0 /* MX28_PAD_LCD_D10__LCD_D10 */ - 0x10b0 /* MX28_PAD_LCD_D11__LCD_D11 */ - 0x10c0 /* MX28_PAD_LCD_D12__LCD_D12 */ - 0x10d0 /* MX28_PAD_LCD_D13__LCD_D13 */ - 0x10e0 /* MX28_PAD_LCD_D14__LCD_D14 */ - 0x10f0 /* MX28_PAD_LCD_D15__LCD_D15 */ - 0x1100 /* MX28_PAD_LCD_D16__LCD_D16 */ - 0x1110 /* MX28_PAD_LCD_D17__LCD_D17 */ + MX28_PAD_LCD_D00__LCD_D0 + MX28_PAD_LCD_D01__LCD_D1 + MX28_PAD_LCD_D02__LCD_D2 + MX28_PAD_LCD_D03__LCD_D3 + MX28_PAD_LCD_D04__LCD_D4 + MX28_PAD_LCD_D05__LCD_D5 + MX28_PAD_LCD_D06__LCD_D6 + MX28_PAD_LCD_D07__LCD_D7 + MX28_PAD_LCD_D08__LCD_D8 + MX28_PAD_LCD_D09__LCD_D9 + MX28_PAD_LCD_D10__LCD_D10 + MX28_PAD_LCD_D11__LCD_D11 + MX28_PAD_LCD_D12__LCD_D12 + MX28_PAD_LCD_D13__LCD_D13 + MX28_PAD_LCD_D14__LCD_D14 + MX28_PAD_LCD_D15__LCD_D15 + MX28_PAD_LCD_D16__LCD_D16 + MX28_PAD_LCD_D17__LCD_D17 >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; lcdif_pins_cfa10049: lcdif-evk@0 { reg = <0>; fsl,pinmux-ids = < - 0x1181 /* MX28_PAD_LCD_RD_E__LCD_VSYNC */ - 0x1191 /* MX28_PAD_LCD_WR_RWN__LCD_HSYNC */ - 0x11a1 /* MX28_PAD_LCD_RS__LCD_DOTCLK */ - 0x11b1 /* MX28_PAD_LCD_CS__LCD_ENABLE */ + MX28_PAD_LCD_RD_E__LCD_VSYNC + MX28_PAD_LCD_WR_RWN__LCD_HSYNC + MX28_PAD_LCD_RS__LCD_DOTCLK + MX28_PAD_LCD_CS__LCD_ENABLE >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; lcdif_pins_cfa10049_pullup: lcdif-10049-pullup@0 { reg = <0>; fsl,pinmux-ids = < - 0x31e3 /* MX28_PAD_LCD_RESET__GPIO_3_30 */ + MX28_PAD_LCD_RESET__GPIO_3_30 >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <1>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_ENABLE>; }; w1_gpio_pins: w1-gpio@0 { reg = <0>; fsl,pinmux-ids = < - 0x1153 /* MX28_PAD_LCD_D21__GPIO_1_21 */ + MX28_PAD_LCD_D21__GPIO_1_21 >; - fsl,drive-strength = <1>; - fsl,voltage = <1>; - fsl,pull-up = <0>; /* 0 will enable the keeper */ + fsl,drive-strength = <MXS_DRIVE_8mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; /* 0 will enable the keeper */ }; }; diff --git a/arch/arm/boot/dts/imx28-cfa10055.dts b/arch/arm/boot/dts/imx28-cfa10055.dts index 171bcbe1ec4b..c3900e7ba331 100644 --- a/arch/arm/boot/dts/imx28-cfa10055.dts +++ b/arch/arm/boot/dts/imx28-cfa10055.dts @@ -14,7 +14,7 @@ * The CFA-10055 is an expansion board for the CFA-10036 module and * CFA-10037, thus we need to include the CFA-10037 DTS. */ -/include/ "imx28-cfa10037.dts" +#include "imx28-cfa10037.dts" / { model = "Crystalfontz CFA-10055 Board"; @@ -26,64 +26,64 @@ spi2_pins_cfa10055: spi2-cfa10055@0 { reg = <0>; fsl,pinmux-ids = < - 0x2103 /* MX28_PAD_SSP2_SCK__GPIO_2_16 */ - 0x2113 /* MX28_PAD_SSP2_CMD__GPIO_2_17 */ - 0x2123 /* MX28_PAD_SSP2_D0__GPIO_2_18 */ - 0x3053 /* MX28_PAD_AUART1_TX__GPIO_3_5 */ + MX28_PAD_SSP2_SCK__GPIO_2_16 + MX28_PAD_SSP2_MOSI__GPIO_2_17 + MX28_PAD_SSP2_MISO__GPIO_2_18 + MX28_PAD_AUART1_TX__GPIO_3_5 >; - fsl,drive-strength = <1>; - fsl,voltage = <1>; - fsl,pull-up = <1>; + fsl,drive-strength = <MXS_DRIVE_8mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_ENABLE>; }; lcdif_18bit_pins_cfa10055: lcdif-18bit@0 { reg = <0>; fsl,pinmux-ids = < - 0x1000 /* MX28_PAD_LCD_D00__LCD_D0 */ - 0x1010 /* MX28_PAD_LCD_D01__LCD_D1 */ - 0x1020 /* MX28_PAD_LCD_D02__LCD_D2 */ - 0x1030 /* MX28_PAD_LCD_D03__LCD_D3 */ - 0x1040 /* MX28_PAD_LCD_D04__LCD_D4 */ - 0x1050 /* MX28_PAD_LCD_D05__LCD_D5 */ - 0x1060 /* MX28_PAD_LCD_D06__LCD_D6 */ - 0x1070 /* MX28_PAD_LCD_D07__LCD_D7 */ - 0x1080 /* MX28_PAD_LCD_D08__LCD_D8 */ - 0x1090 /* MX28_PAD_LCD_D09__LCD_D9 */ - 0x10a0 /* MX28_PAD_LCD_D10__LCD_D10 */ - 0x10b0 /* MX28_PAD_LCD_D11__LCD_D11 */ - 0x10c0 /* MX28_PAD_LCD_D12__LCD_D12 */ - 0x10d0 /* MX28_PAD_LCD_D13__LCD_D13 */ - 0x10e0 /* MX28_PAD_LCD_D14__LCD_D14 */ - 0x10f0 /* MX28_PAD_LCD_D15__LCD_D15 */ - 0x1100 /* MX28_PAD_LCD_D16__LCD_D16 */ - 0x1110 /* MX28_PAD_LCD_D17__LCD_D17 */ + MX28_PAD_LCD_D00__LCD_D0 + MX28_PAD_LCD_D01__LCD_D1 + MX28_PAD_LCD_D02__LCD_D2 + MX28_PAD_LCD_D03__LCD_D3 + MX28_PAD_LCD_D04__LCD_D4 + MX28_PAD_LCD_D05__LCD_D5 + MX28_PAD_LCD_D06__LCD_D6 + MX28_PAD_LCD_D07__LCD_D7 + MX28_PAD_LCD_D08__LCD_D8 + MX28_PAD_LCD_D09__LCD_D9 + MX28_PAD_LCD_D10__LCD_D10 + MX28_PAD_LCD_D11__LCD_D11 + MX28_PAD_LCD_D12__LCD_D12 + MX28_PAD_LCD_D13__LCD_D13 + MX28_PAD_LCD_D14__LCD_D14 + MX28_PAD_LCD_D15__LCD_D15 + MX28_PAD_LCD_D16__LCD_D16 + MX28_PAD_LCD_D17__LCD_D17 >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; lcdif_pins_cfa10055: lcdif-evk@0 { reg = <0>; fsl,pinmux-ids = < - 0x1181 /* MX28_PAD_LCD_RD_E__LCD_VSYNC */ - 0x1191 /* MX28_PAD_LCD_WR_RWN__LCD_HSYNC */ - 0x11a1 /* MX28_PAD_LCD_RS__LCD_DOTCLK */ - 0x11b1 /* MX28_PAD_LCD_CS__LCD_ENABLE */ + MX28_PAD_LCD_RD_E__LCD_VSYNC + MX28_PAD_LCD_WR_RWN__LCD_HSYNC + MX28_PAD_LCD_RS__LCD_DOTCLK + MX28_PAD_LCD_CS__LCD_ENABLE >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; lcdif_pins_cfa10055_pullup: lcdif-10055-pullup@0 { reg = <0>; fsl,pinmux-ids = < - 0x31e3 /* MX28_PAD_LCD_RESET__GPIO_3_30 */ + MX28_PAD_LCD_RESET__GPIO_3_30 >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <1>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_ENABLE>; }; }; diff --git a/arch/arm/boot/dts/imx28-cfa10056.dts b/arch/arm/boot/dts/imx28-cfa10056.dts index b45dd0e4ee57..cef959a97219 100644 --- a/arch/arm/boot/dts/imx28-cfa10056.dts +++ b/arch/arm/boot/dts/imx28-cfa10056.dts @@ -13,7 +13,7 @@ * The CFA-10055 is an expansion board for the CFA-10036 module and * CFA-10037, thus we need to include the CFA-10037 DTS. */ -/include/ "imx28-cfa10037.dts" +#include "imx28-cfa10037.dts" / { model = "Crystalfontz CFA-10056 Board"; @@ -25,37 +25,37 @@ spi2_pins_cfa10056: spi2-cfa10056@0 { reg = <0>; fsl,pinmux-ids = < - 0x2103 /* MX28_PAD_SSP2_SCK__GPIO_2_16 */ - 0x2113 /* MX28_PAD_SSP2_CMD__GPIO_2_17 */ - 0x2123 /* MX28_PAD_SSP2_D0__GPIO_2_18 */ - 0x3053 /* MX28_PAD_AUART1_TX__GPIO_3_5 */ + MX28_PAD_SSP2_SCK__GPIO_2_16 + MX28_PAD_SSP2_MOSI__GPIO_2_17 + MX28_PAD_SSP2_MISO__GPIO_2_18 + MX28_PAD_AUART1_TX__GPIO_3_5 >; - fsl,drive-strength = <1>; - fsl,voltage = <1>; - fsl,pull-up = <1>; + fsl,drive-strength = <MXS_DRIVE_8mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_ENABLE>; }; lcdif_pins_cfa10056: lcdif-10056@0 { reg = <0>; fsl,pinmux-ids = < - 0x1181 /* MX28_PAD_LCD_RD_E__LCD_VSYNC */ - 0x1191 /* MX28_PAD_LCD_WR_RWN__LCD_HSYNC */ - 0x11a1 /* MX28_PAD_LCD_RS__LCD_DOTCLK */ - 0x11b1 /* MX28_PAD_LCD_CS__LCD_ENABLE */ + MX28_PAD_LCD_RD_E__LCD_VSYNC + MX28_PAD_LCD_WR_RWN__LCD_HSYNC + MX28_PAD_LCD_RS__LCD_DOTCLK + MX28_PAD_LCD_CS__LCD_ENABLE >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; lcdif_pins_cfa10056_pullup: lcdif-10056-pullup@0 { reg = <0>; fsl,pinmux-ids = < - 0x31e3 /* MX28_PAD_LCD_RESET__GPIO_3_30 */ + MX28_PAD_LCD_RESET__GPIO_3_30 >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <1>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_ENABLE>; }; }; diff --git a/arch/arm/boot/dts/imx28-cfa10057.dts b/arch/arm/boot/dts/imx28-cfa10057.dts index 0333c0532f28..3c1312885ae0 100644 --- a/arch/arm/boot/dts/imx28-cfa10057.dts +++ b/arch/arm/boot/dts/imx28-cfa10057.dts @@ -14,7 +14,7 @@ * The CFA-10057 is an expansion board for the CFA-10036 module, thus we * need to include the CFA-10036 DTS. */ -/include/ "imx28-cfa10036.dts" +#include "imx28-cfa10036.dts" / { model = "Crystalfontz CFA-10057 Board"; @@ -26,51 +26,51 @@ usb_pins_cfa10057: usb-10057@0 { reg = <0>; fsl,pinmux-ids = < - 0x0073 /* MX28_PAD_GPMI_D7__GPIO_0_7 */ + MX28_PAD_GPMI_D07__GPIO_0_7 >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; lcdif_18bit_pins_cfa10057: lcdif-18bit@0 { reg = <0>; fsl,pinmux-ids = < - 0x1000 /* MX28_PAD_LCD_D00__LCD_D0 */ - 0x1010 /* MX28_PAD_LCD_D01__LCD_D1 */ - 0x1020 /* MX28_PAD_LCD_D02__LCD_D2 */ - 0x1030 /* MX28_PAD_LCD_D03__LCD_D3 */ - 0x1040 /* MX28_PAD_LCD_D04__LCD_D4 */ - 0x1050 /* MX28_PAD_LCD_D05__LCD_D5 */ - 0x1060 /* MX28_PAD_LCD_D06__LCD_D6 */ - 0x1070 /* MX28_PAD_LCD_D07__LCD_D7 */ - 0x1080 /* MX28_PAD_LCD_D08__LCD_D8 */ - 0x1090 /* MX28_PAD_LCD_D09__LCD_D9 */ - 0x10a0 /* MX28_PAD_LCD_D10__LCD_D10 */ - 0x10b0 /* MX28_PAD_LCD_D11__LCD_D11 */ - 0x10c0 /* MX28_PAD_LCD_D12__LCD_D12 */ - 0x10d0 /* MX28_PAD_LCD_D13__LCD_D13 */ - 0x10e0 /* MX28_PAD_LCD_D14__LCD_D14 */ - 0x10f0 /* MX28_PAD_LCD_D15__LCD_D15 */ - 0x1100 /* MX28_PAD_LCD_D16__LCD_D16 */ - 0x1110 /* MX28_PAD_LCD_D17__LCD_D17 */ + MX28_PAD_LCD_D00__LCD_D0 + MX28_PAD_LCD_D01__LCD_D1 + MX28_PAD_LCD_D02__LCD_D2 + MX28_PAD_LCD_D03__LCD_D3 + MX28_PAD_LCD_D04__LCD_D4 + MX28_PAD_LCD_D05__LCD_D5 + MX28_PAD_LCD_D06__LCD_D6 + MX28_PAD_LCD_D07__LCD_D7 + MX28_PAD_LCD_D08__LCD_D8 + MX28_PAD_LCD_D09__LCD_D9 + MX28_PAD_LCD_D10__LCD_D10 + MX28_PAD_LCD_D11__LCD_D11 + MX28_PAD_LCD_D12__LCD_D12 + MX28_PAD_LCD_D13__LCD_D13 + MX28_PAD_LCD_D14__LCD_D14 + MX28_PAD_LCD_D15__LCD_D15 + MX28_PAD_LCD_D16__LCD_D16 + MX28_PAD_LCD_D17__LCD_D17 >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; lcdif_pins_cfa10057: lcdif-evk@0 { reg = <0>; fsl,pinmux-ids = < - 0x1181 /* MX28_PAD_LCD_RD_E__LCD_VSYNC */ - 0x1191 /* MX28_PAD_LCD_WR_RWN__LCD_HSYNC */ - 0x11a1 /* MX28_PAD_LCD_RS__LCD_DOTCLK */ - 0x11b1 /* MX28_PAD_LCD_CS__LCD_ENABLE */ + MX28_PAD_LCD_RD_E__LCD_VSYNC + MX28_PAD_LCD_WR_RWN__LCD_HSYNC + MX28_PAD_LCD_RS__LCD_DOTCLK + MX28_PAD_LCD_CS__LCD_ENABLE >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; }; diff --git a/arch/arm/boot/dts/imx28-cfa10058.dts b/arch/arm/boot/dts/imx28-cfa10058.dts index 64c64c55a82a..2469d34df0ae 100644 --- a/arch/arm/boot/dts/imx28-cfa10058.dts +++ b/arch/arm/boot/dts/imx28-cfa10058.dts @@ -14,7 +14,7 @@ * The CFA-10058 is an expansion board for the CFA-10036 module, thus we * need to include the CFA-10036 DTS. */ -/include/ "imx28-cfa10036.dts" +#include "imx28-cfa10036.dts" / { model = "Crystalfontz CFA-10058 Board"; @@ -26,24 +26,24 @@ usb_pins_cfa10058: usb-10058@0 { reg = <0>; fsl,pinmux-ids = < - 0x0073 /* MX28_PAD_GPMI_D7__GPIO_0_7 */ + MX28_PAD_GPMI_D07__GPIO_0_7 >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; lcdif_pins_cfa10058: lcdif-10058@0 { reg = <0>; fsl,pinmux-ids = < - 0x1181 /* MX28_PAD_LCD_RD_E__LCD_VSYNC */ - 0x1191 /* MX28_PAD_LCD_WR_RWN__LCD_HSYNC */ - 0x11a1 /* MX28_PAD_LCD_RS__LCD_DOTCLK */ - 0x11b1 /* MX28_PAD_LCD_CS__LCD_ENABLE */ + MX28_PAD_LCD_RD_E__LCD_VSYNC + MX28_PAD_LCD_WR_RWN__LCD_HSYNC + MX28_PAD_LCD_RS__LCD_DOTCLK + MX28_PAD_LCD_CS__LCD_ENABLE >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; }; diff --git a/arch/arm/boot/dts/imx28-evk.dts b/arch/arm/boot/dts/imx28-evk.dts index 15715d921d14..4267c2b05d60 100644 --- a/arch/arm/boot/dts/imx28-evk.dts +++ b/arch/arm/boot/dts/imx28-evk.dts @@ -10,7 +10,7 @@ */ /dts-v1/; -/include/ "imx28.dtsi" +#include "imx28.dtsi" / { model = "Freescale i.MX28 Evaluation Kit"; @@ -70,52 +70,52 @@ hog_pins_a: hog@0 { reg = <0>; fsl,pinmux-ids = < - 0x20d3 /* MX28_PAD_SSP1_CMD__GPIO_2_13 */ - 0x20f3 /* MX28_PAD_SSP1_DATA3__GPIO_2_15 */ - 0x40d3 /* MX28_PAD_ENET0_RX_CLK__GPIO_4_13 */ - 0x20c3 /* MX28_PAD_SSP1_SCK__GPIO_2_12 */ - 0x31c3 /* MX28_PAD_PWM3__GPIO_3_28 */ - 0x31e3 /* MX28_PAD_LCD_RESET__GPIO_3_30 */ - 0x3083 /* MX28_PAD_AUART2_RX__GPIO_3_8 */ - 0x3093 /* MX28_PAD_AUART2_TX__GPIO_3_9 */ + MX28_PAD_SSP1_CMD__GPIO_2_13 + MX28_PAD_SSP1_DATA3__GPIO_2_15 + MX28_PAD_ENET0_RX_CLK__GPIO_4_13 + MX28_PAD_SSP1_SCK__GPIO_2_12 + MX28_PAD_PWM3__GPIO_3_28 + MX28_PAD_LCD_RESET__GPIO_3_30 + MX28_PAD_AUART2_RX__GPIO_3_8 + MX28_PAD_AUART2_TX__GPIO_3_9 >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; led_pin_gpio3_5: led_gpio3_5@0 { reg = <0>; fsl,pinmux-ids = < - 0x3053 /* MX28_PAD_AUART1_TX__GPIO_3_5 */ + MX28_PAD_AUART1_TX__GPIO_3_5 >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; gpmi_pins_evk: gpmi-nand-evk@0 { reg = <0>; fsl,pinmux-ids = < - 0x0110 /* MX28_PAD_GPMI_CE1N__GPMI_CE1N */ - 0x0150 /* MX28_PAD_GPMI_RDY1__GPMI_READY1 */ + MX28_PAD_GPMI_CE1N__GPMI_CE1N + MX28_PAD_GPMI_RDY1__GPMI_READY1 >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; lcdif_pins_evk: lcdif-evk@0 { reg = <0>; fsl,pinmux-ids = < - 0x1181 /* MX28_PAD_LCD_RD_E__LCD_VSYNC */ - 0x1191 /* MX28_PAD_LCD_WR_RWN__LCD_HSYNC */ - 0x11a1 /* MX28_PAD_LCD_RS__LCD_DOTCLK */ - 0x11b1 /* MX28_PAD_LCD_CS__LCD_ENABLE */ + MX28_PAD_LCD_RD_E__LCD_VSYNC + MX28_PAD_LCD_WR_RWN__LCD_HSYNC + MX28_PAD_LCD_RS__LCD_DOTCLK + MX28_PAD_LCD_CS__LCD_ENABLE >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; }; @@ -182,7 +182,12 @@ }; lradc@80050000 { + fsl,lradc-touchscreen-wires = <4>; status = "okay"; + fsl,lradc-touchscreen-wires = <4>; + fsl,ave-ctrl = <4>; + fsl,ave-delay = <2>; + fsl,settling = <10>; }; i2c0: i2c@80058000 { @@ -242,6 +247,8 @@ ahb@80080000 { usb0: usb@80080000 { + pinctrl-names = "default"; + pinctrl-0 = <&usb0_id_pins_a>; vbus-supply = <®_usb0_vbus>; status = "okay"; }; diff --git a/arch/arm/boot/dts/imx28-m28cu3.dts b/arch/arm/boot/dts/imx28-m28cu3.dts new file mode 100644 index 000000000000..d3958da60bd7 --- /dev/null +++ b/arch/arm/boot/dts/imx28-m28cu3.dts @@ -0,0 +1,266 @@ +/* + * Copyright (C) 2013 Marek Vasut <marex@denx.de> + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/dts-v1/; +#include "imx28.dtsi" + +/ { + model = "MSR M28CU3"; + compatible = "msr,m28cu3", "fsl,imx28"; + + memory { + reg = <0x40000000 0x08000000>; + }; + + apb@80000000 { + apbh@80000000 { + gpmi-nand@8000c000 { + #address-cells = <1>; + #size-cells = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&gpmi_pins_a &gpmi_status_cfg>; + status = "okay"; + + partition@0 { + label = "gpmi-nfc-0-boot"; + reg = <0x00000000 0x01400000>; + read-only; + }; + + partition@1 { + label = "gpmi-nfc-general-use"; + reg = <0x01400000 0x0ec00000>; + }; + }; + + ssp0: ssp@80010000 { + compatible = "fsl,imx28-mmc"; + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_4bit_pins_a + &mmc0_cd_cfg + &mmc0_sck_cfg>; + bus-width = <4>; + vmmc-supply = <®_vddio_sd0>; + status = "okay"; + }; + + ssp2: ssp@80014000 { + compatible = "fsl,imx28-mmc"; + pinctrl-names = "default"; + pinctrl-0 = <&mmc2_4bit_pins_a + &mmc2_cd_cfg + &mmc2_sck_cfg>; + bus-width = <4>; + vmmc-supply = <®_vddio_sd1>; + status = "okay"; + }; + + pinctrl@80018000 { + pinctrl-names = "default"; + pinctrl-0 = <&hog_pins_a>; + + hog_pins_a: hog@0 { + reg = <0>; + fsl,pinmux-ids = < + MX28_PAD_SSP2_SS0__GPIO_2_19 + MX28_PAD_PWM4__GPIO_3_29 + MX28_PAD_AUART2_RX__GPIO_3_8 + MX28_PAD_ENET0_RX_CLK__GPIO_4_13 + >; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; + }; + + lcdif_pins_m28: lcdif-m28@0 { + reg = <0>; + fsl,pinmux-ids = < + MX28_PAD_LCD_VSYNC__LCD_VSYNC + MX28_PAD_LCD_HSYNC__LCD_HSYNC + MX28_PAD_LCD_DOTCLK__LCD_DOTCLK + MX28_PAD_LCD_RESET__LCD_RESET + MX28_PAD_LCD_CS__LCD_ENABLE + MX28_PAD_AUART1_TX__GPIO_3_5 + >; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; + }; + + led_pins_gpio: leds-m28@0 { + reg = <0>; + fsl,pinmux-ids = < + MX28_PAD_SSP3_MISO__GPIO_2_26 + MX28_PAD_SSP3_SCK__GPIO_2_24 + >; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; + }; + }; + + ocotp@8002c000 { + status = "okay"; + }; + + lcdif@80030000 { + pinctrl-names = "default"; + pinctrl-0 = <&lcdif_24bit_pins_a + &lcdif_pins_m28>; + display = <&display>; + reset-active-high; + status = "okay"; + + display: display0 { + bits-per-pixel = <32>; + bus-width = <24>; + + display-timings { + native-mode = <&timing0>; + timing0: timing0 { + clock-frequency = <6410256>; + hactive = <320>; + vactive = <240>; + hback-porch = <38>; + hfront-porch = <20>; + vback-porch = <15>; + vfront-porch = <5>; + hsync-len = <30>; + vsync-len = <3>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <1>; + pixelclk-active = <1>; + }; + }; + }; + }; + }; + + apbx@80040000 { + duart: serial@80074000 { + pinctrl-names = "default"; + pinctrl-0 = <&duart_pins_b>; + status = "okay"; + }; + + usbphy1: usbphy@8007e000 { + status = "okay"; + }; + + auart0: serial@8006a000 { + pinctrl-names = "default"; + pinctrl-0 = <&auart0_2pins_a>; + status = "okay"; + }; + + auart3: serial@80070000 { + pinctrl-names = "default"; + pinctrl-0 = <&auart3_2pins_b>; + status = "okay"; + }; + + pwm: pwm@80064000 { + pinctrl-names = "default"; + pinctrl-0 = <&pwm3_pins_a>; + status = "okay"; + }; + }; + }; + + ahb@80080000 { + usb1: usb@80090000 { + vbus-supply = <®_usb1_vbus>; + pinctrl-names = "default"; + pinctrl-0 = <&usbphy1_pins_a>; + disable-over-current; + status = "okay"; + }; + + mac0: ethernet@800f0000 { + phy-mode = "rmii"; + pinctrl-names = "default"; + pinctrl-0 = <&mac0_pins_a>; + phy-reset-gpios = <&gpio4 13 0>; + phy-reset-duration = <100>; + status = "okay"; + }; + + mac1: ethernet@800f4000 { + phy-mode = "rmii"; + pinctrl-names = "default"; + pinctrl-0 = <&mac1_pins_a>; + status = "okay"; + }; + }; + + backlight { + compatible = "pwm-backlight"; + pwms = <&pwm 3 5000000>; + brightness-levels = <0 4 8 16 32 64 128 255>; + default-brightness-level = <6>; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&led_pins_gpio>; + + user1 { + label = "sd0-led"; + gpios = <&gpio2 26 0>; + linux,default-trigger = "mmc0"; + }; + + user2 { + label = "sd1-led"; + gpios = <&gpio2 24 0>; + linux,default-trigger = "mmc2"; + }; + }; + + regulators { + compatible = "simple-bus"; + + reg_3p3v: 3p3v { + compatible = "regulator-fixed"; + regulator-name = "3P3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + reg_vddio_sd0: vddio-sd0 { + compatible = "regulator-fixed"; + regulator-name = "vddio-sd0"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio3 29 0>; + }; + + reg_vddio_sd1: vddio-sd1 { + compatible = "regulator-fixed"; + regulator-name = "vddio-sd1"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio2 19 0>; + }; + + reg_usb1_vbus: usb1_vbus { + compatible = "regulator-fixed"; + regulator-name = "usb1_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio3 8 0>; + enable-active-high; + }; + }; +}; diff --git a/arch/arm/boot/dts/imx28-m28evk.dts b/arch/arm/boot/dts/imx28-m28evk.dts index 0d322a2bebaf..8e2477fbe1d7 100644 --- a/arch/arm/boot/dts/imx28-m28evk.dts +++ b/arch/arm/boot/dts/imx28-m28evk.dts @@ -10,7 +10,7 @@ */ /dts-v1/; -/include/ "imx28.dtsi" +#include "imx28.dtsi" / { model = "DENX M28EVK"; @@ -92,26 +92,26 @@ hog_pins_a: hog@0 { reg = <0>; fsl,pinmux-ids = < - 0x31c3 /* MX28_PAD_PWM3__GPIO_3_28 */ - 0x30a3 /* MX28_PAD_AUART2_CTS__GPIO_3_10 */ - 0x30b3 /* MX28_PAD_AUART2_RTS__GPIO_3_11 */ - 0x30c3 /* MX28_PAD_AUART3_RX__GPIO_3_12 */ - 0x30d3 /* MX28_PAD_AUART3_TX__GPIO_3_13 */ + MX28_PAD_PWM3__GPIO_3_28 + MX28_PAD_AUART2_CTS__GPIO_3_10 + MX28_PAD_AUART2_RTS__GPIO_3_11 + MX28_PAD_AUART3_RX__GPIO_3_12 + MX28_PAD_AUART3_TX__GPIO_3_13 >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; lcdif_pins_m28: lcdif-m28@0 { reg = <0>; fsl,pinmux-ids = < - 0x11e0 /* MX28_PAD_LCD_DOTCLK__LCD_DOTCLK */ - 0x11f0 /* MX28_PAD_LCD_ENABLE__LCD_ENABLE */ + MX28_PAD_LCD_DOTCLK__LCD_DOTCLK + MX28_PAD_LCD_ENABLE__LCD_ENABLE >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; }; diff --git a/arch/arm/boot/dts/imx28-pinfunc.h b/arch/arm/boot/dts/imx28-pinfunc.h new file mode 100644 index 000000000000..e11f69ba0fe4 --- /dev/null +++ b/arch/arm/boot/dts/imx28-pinfunc.h @@ -0,0 +1,506 @@ +/* + * Header providing constants for i.MX28 pinctrl bindings. + * + * Copyright (C) 2013 Lothar Waßmann <LW@KARO-electronics.de> + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#ifndef __DT_BINDINGS_MX28_PINCTRL_H__ +#define __DT_BINDINGS_MX28_PINCTRL_H__ + +#include "mxs-pinfunc.h" + +#define MX28_PAD_GPMI_D00__GPMI_D0 0x0000 +#define MX28_PAD_GPMI_D01__GPMI_D1 0x0010 +#define MX28_PAD_GPMI_D02__GPMI_D2 0x0020 +#define MX28_PAD_GPMI_D03__GPMI_D3 0x0030 +#define MX28_PAD_GPMI_D04__GPMI_D4 0x0040 +#define MX28_PAD_GPMI_D05__GPMI_D5 0x0050 +#define MX28_PAD_GPMI_D06__GPMI_D6 0x0060 +#define MX28_PAD_GPMI_D07__GPMI_D7 0x0070 +#define MX28_PAD_GPMI_CE0N__GPMI_CE0N 0x0100 +#define MX28_PAD_GPMI_CE1N__GPMI_CE1N 0x0110 +#define MX28_PAD_GPMI_CE2N__GPMI_CE2N 0x0120 +#define MX28_PAD_GPMI_CE3N__GPMI_CE3N 0x0130 +#define MX28_PAD_GPMI_RDY0__GPMI_READY0 0x0140 +#define MX28_PAD_GPMI_RDY1__GPMI_READY1 0x0150 +#define MX28_PAD_GPMI_RDY2__GPMI_READY2 0x0160 +#define MX28_PAD_GPMI_RDY3__GPMI_READY3 0x0170 +#define MX28_PAD_GPMI_RDN__GPMI_RDN 0x0180 +#define MX28_PAD_GPMI_WRN__GPMI_WRN 0x0190 +#define MX28_PAD_GPMI_ALE__GPMI_ALE 0x01a0 +#define MX28_PAD_GPMI_CLE__GPMI_CLE 0x01b0 +#define MX28_PAD_GPMI_RESETN__GPMI_RESETN 0x01c0 +#define MX28_PAD_LCD_D00__LCD_D0 0x1000 +#define MX28_PAD_LCD_D01__LCD_D1 0x1010 +#define MX28_PAD_LCD_D02__LCD_D2 0x1020 +#define MX28_PAD_LCD_D03__LCD_D3 0x1030 +#define MX28_PAD_LCD_D04__LCD_D4 0x1040 +#define MX28_PAD_LCD_D05__LCD_D5 0x1050 +#define MX28_PAD_LCD_D06__LCD_D6 0x1060 +#define MX28_PAD_LCD_D07__LCD_D7 0x1070 +#define MX28_PAD_LCD_D08__LCD_D8 0x1080 +#define MX28_PAD_LCD_D09__LCD_D9 0x1090 +#define MX28_PAD_LCD_D10__LCD_D10 0x10a0 +#define MX28_PAD_LCD_D11__LCD_D11 0x10b0 +#define MX28_PAD_LCD_D12__LCD_D12 0x10c0 +#define MX28_PAD_LCD_D13__LCD_D13 0x10d0 +#define MX28_PAD_LCD_D14__LCD_D14 0x10e0 +#define MX28_PAD_LCD_D15__LCD_D15 0x10f0 +#define MX28_PAD_LCD_D16__LCD_D16 0x1100 +#define MX28_PAD_LCD_D17__LCD_D17 0x1110 +#define MX28_PAD_LCD_D18__LCD_D18 0x1120 +#define MX28_PAD_LCD_D19__LCD_D19 0x1130 +#define MX28_PAD_LCD_D20__LCD_D20 0x1140 +#define MX28_PAD_LCD_D21__LCD_D21 0x1150 +#define MX28_PAD_LCD_D22__LCD_D22 0x1160 +#define MX28_PAD_LCD_D23__LCD_D23 0x1170 +#define MX28_PAD_LCD_RD_E__LCD_RD_E 0x1180 +#define MX28_PAD_LCD_WR_RWN__LCD_WR_RWN 0x1190 +#define MX28_PAD_LCD_RS__LCD_RS 0x11a0 +#define MX28_PAD_LCD_CS__LCD_CS 0x11b0 +#define MX28_PAD_LCD_VSYNC__LCD_VSYNC 0x11c0 +#define MX28_PAD_LCD_HSYNC__LCD_HSYNC 0x11d0 +#define MX28_PAD_LCD_DOTCLK__LCD_DOTCLK 0x11e0 +#define MX28_PAD_LCD_ENABLE__LCD_ENABLE 0x11f0 +#define MX28_PAD_SSP0_DATA0__SSP0_D0 0x2000 +#define MX28_PAD_SSP0_DATA1__SSP0_D1 0x2010 +#define MX28_PAD_SSP0_DATA2__SSP0_D2 0x2020 +#define MX28_PAD_SSP0_DATA3__SSP0_D3 0x2030 +#define MX28_PAD_SSP0_DATA4__SSP0_D4 0x2040 +#define MX28_PAD_SSP0_DATA5__SSP0_D5 0x2050 +#define MX28_PAD_SSP0_DATA6__SSP0_D6 0x2060 +#define MX28_PAD_SSP0_DATA7__SSP0_D7 0x2070 +#define MX28_PAD_SSP0_CMD__SSP0_CMD 0x2080 +#define MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT 0x2090 +#define MX28_PAD_SSP0_SCK__SSP0_SCK 0x20a0 +#define MX28_PAD_SSP1_SCK__SSP1_SCK 0x20c0 +#define MX28_PAD_SSP1_CMD__SSP1_CMD 0x20d0 +#define MX28_PAD_SSP1_DATA0__SSP1_D0 0x20e0 +#define MX28_PAD_SSP1_DATA3__SSP1_D3 0x20f0 +#define MX28_PAD_SSP2_SCK__SSP2_SCK 0x2100 +#define MX28_PAD_SSP2_MOSI__SSP2_CMD 0x2110 +#define MX28_PAD_SSP2_MISO__SSP2_D0 0x2120 +#define MX28_PAD_SSP2_SS0__SSP2_D3 0x2130 +#define MX28_PAD_SSP2_SS1__SSP2_D4 0x2140 +#define MX28_PAD_SSP2_SS2__SSP2_D5 0x2150 +#define MX28_PAD_SSP3_SCK__SSP3_SCK 0x2180 +#define MX28_PAD_SSP3_MOSI__SSP3_CMD 0x2190 +#define MX28_PAD_SSP3_MISO__SSP3_D0 0x21a0 +#define MX28_PAD_SSP3_SS0__SSP3_D3 0x21b0 +#define MX28_PAD_AUART0_RX__AUART0_RX 0x3000 +#define MX28_PAD_AUART0_TX__AUART0_TX 0x3010 +#define MX28_PAD_AUART0_CTS__AUART0_CTS 0x3020 +#define MX28_PAD_AUART0_RTS__AUART0_RTS 0x3030 +#define MX28_PAD_AUART1_RX__AUART1_RX 0x3040 +#define MX28_PAD_AUART1_TX__AUART1_TX 0x3050 +#define MX28_PAD_AUART1_CTS__AUART1_CTS 0x3060 +#define MX28_PAD_AUART1_RTS__AUART1_RTS 0x3070 +#define MX28_PAD_AUART2_RX__AUART2_RX 0x3080 +#define MX28_PAD_AUART2_TX__AUART2_TX 0x3090 +#define MX28_PAD_AUART2_CTS__AUART2_CTS 0x30a0 +#define MX28_PAD_AUART2_RTS__AUART2_RTS 0x30b0 +#define MX28_PAD_AUART3_RX__AUART3_RX 0x30c0 +#define MX28_PAD_AUART3_TX__AUART3_TX 0x30d0 +#define MX28_PAD_AUART3_CTS__AUART3_CTS 0x30e0 +#define MX28_PAD_AUART3_RTS__AUART3_RTS 0x30f0 +#define MX28_PAD_PWM0__PWM_0 0x3100 +#define MX28_PAD_PWM1__PWM_1 0x3110 +#define MX28_PAD_PWM2__PWM_2 0x3120 +#define MX28_PAD_SAIF0_MCLK__SAIF0_MCLK 0x3140 +#define MX28_PAD_SAIF0_LRCLK__SAIF0_LRCLK 0x3150 +#define MX28_PAD_SAIF0_BITCLK__SAIF0_BITCLK 0x3160 +#define MX28_PAD_SAIF0_SDATA0__SAIF0_SDATA0 0x3170 +#define MX28_PAD_I2C0_SCL__I2C0_SCL 0x3180 +#define MX28_PAD_I2C0_SDA__I2C0_SDA 0x3190 +#define MX28_PAD_SAIF1_SDATA0__SAIF1_SDATA0 0x31a0 +#define MX28_PAD_SPDIF__SPDIF_TX 0x31b0 +#define MX28_PAD_PWM3__PWM_3 0x31c0 +#define MX28_PAD_PWM4__PWM_4 0x31d0 +#define MX28_PAD_LCD_RESET__LCD_RESET 0x31e0 +#define MX28_PAD_ENET0_MDC__ENET0_MDC 0x4000 +#define MX28_PAD_ENET0_MDIO__ENET0_MDIO 0x4010 +#define MX28_PAD_ENET0_RX_EN__ENET0_RX_EN 0x4020 +#define MX28_PAD_ENET0_RXD0__ENET0_RXD0 0x4030 +#define MX28_PAD_ENET0_RXD1__ENET0_RXD1 0x4040 +#define MX28_PAD_ENET0_TX_CLK__ENET0_TX_CLK 0x4050 +#define MX28_PAD_ENET0_TX_EN__ENET0_TX_EN 0x4060 +#define MX28_PAD_ENET0_TXD0__ENET0_TXD0 0x4070 +#define MX28_PAD_ENET0_TXD1__ENET0_TXD1 0x4080 +#define MX28_PAD_ENET0_RXD2__ENET0_RXD2 0x4090 +#define MX28_PAD_ENET0_RXD3__ENET0_RXD3 0x40a0 +#define MX28_PAD_ENET0_TXD2__ENET0_TXD2 0x40b0 +#define MX28_PAD_ENET0_TXD3__ENET0_TXD3 0x40c0 +#define MX28_PAD_ENET0_RX_CLK__ENET0_RX_CLK 0x40d0 +#define MX28_PAD_ENET0_COL__ENET0_COL 0x40e0 +#define MX28_PAD_ENET0_CRS__ENET0_CRS 0x40f0 +#define MX28_PAD_ENET_CLK__CLKCTRL_ENET 0x4100 +#define MX28_PAD_JTAG_RTCK__JTAG_RTCK 0x4140 +#define MX28_PAD_EMI_D00__EMI_DATA0 0x5000 +#define MX28_PAD_EMI_D01__EMI_DATA1 0x5010 +#define MX28_PAD_EMI_D02__EMI_DATA2 0x5020 +#define MX28_PAD_EMI_D03__EMI_DATA3 0x5030 +#define MX28_PAD_EMI_D04__EMI_DATA4 0x5040 +#define MX28_PAD_EMI_D05__EMI_DATA5 0x5050 +#define MX28_PAD_EMI_D06__EMI_DATA6 0x5060 +#define MX28_PAD_EMI_D07__EMI_DATA7 0x5070 +#define MX28_PAD_EMI_D08__EMI_DATA8 0x5080 +#define MX28_PAD_EMI_D09__EMI_DATA9 0x5090 +#define MX28_PAD_EMI_D10__EMI_DATA10 0x50a0 +#define MX28_PAD_EMI_D11__EMI_DATA11 0x50b0 +#define MX28_PAD_EMI_D12__EMI_DATA12 0x50c0 +#define MX28_PAD_EMI_D13__EMI_DATA13 0x50d0 +#define MX28_PAD_EMI_D14__EMI_DATA14 0x50e0 +#define MX28_PAD_EMI_D15__EMI_DATA15 0x50f0 +#define MX28_PAD_EMI_ODT0__EMI_ODT0 0x5100 +#define MX28_PAD_EMI_DQM0__EMI_DQM0 0x5110 +#define MX28_PAD_EMI_ODT1__EMI_ODT1 0x5120 +#define MX28_PAD_EMI_DQM1__EMI_DQM1 0x5130 +#define MX28_PAD_EMI_DDR_OPEN_FB__EMI_DDR_OPEN_FEEDBACK 0x5140 +#define MX28_PAD_EMI_CLK__EMI_CLK 0x5150 +#define MX28_PAD_EMI_DQS0__EMI_DQS0 0x5160 +#define MX28_PAD_EMI_DQS1__EMI_DQS1 0x5170 +#define MX28_PAD_EMI_DDR_OPEN__EMI_DDR_OPEN 0x51a0 +#define MX28_PAD_EMI_A00__EMI_ADDR0 0x6000 +#define MX28_PAD_EMI_A01__EMI_ADDR1 0x6010 +#define MX28_PAD_EMI_A02__EMI_ADDR2 0x6020 +#define MX28_PAD_EMI_A03__EMI_ADDR3 0x6030 +#define MX28_PAD_EMI_A04__EMI_ADDR4 0x6040 +#define MX28_PAD_EMI_A05__EMI_ADDR5 0x6050 +#define MX28_PAD_EMI_A06__EMI_ADDR6 0x6060 +#define MX28_PAD_EMI_A07__EMI_ADDR7 0x6070 +#define MX28_PAD_EMI_A08__EMI_ADDR8 0x6080 +#define MX28_PAD_EMI_A09__EMI_ADDR9 0x6090 +#define MX28_PAD_EMI_A10__EMI_ADDR10 0x60a0 +#define MX28_PAD_EMI_A11__EMI_ADDR11 0x60b0 +#define MX28_PAD_EMI_A12__EMI_ADDR12 0x60c0 +#define MX28_PAD_EMI_A13__EMI_ADDR13 0x60d0 +#define MX28_PAD_EMI_A14__EMI_ADDR14 0x60e0 +#define MX28_PAD_EMI_BA0__EMI_BA0 0x6100 +#define MX28_PAD_EMI_BA1__EMI_BA1 0x6110 +#define MX28_PAD_EMI_BA2__EMI_BA2 0x6120 +#define MX28_PAD_EMI_CASN__EMI_CASN 0x6130 +#define MX28_PAD_EMI_RASN__EMI_RASN 0x6140 +#define MX28_PAD_EMI_WEN__EMI_WEN 0x6150 +#define MX28_PAD_EMI_CE0N__EMI_CE0N 0x6160 +#define MX28_PAD_EMI_CE1N__EMI_CE1N 0x6170 +#define MX28_PAD_EMI_CKE__EMI_CKE 0x6180 +#define MX28_PAD_GPMI_D00__SSP1_D0 0x0001 +#define MX28_PAD_GPMI_D01__SSP1_D1 0x0011 +#define MX28_PAD_GPMI_D02__SSP1_D2 0x0021 +#define MX28_PAD_GPMI_D03__SSP1_D3 0x0031 +#define MX28_PAD_GPMI_D04__SSP1_D4 0x0041 +#define MX28_PAD_GPMI_D05__SSP1_D5 0x0051 +#define MX28_PAD_GPMI_D06__SSP1_D6 0x0061 +#define MX28_PAD_GPMI_D07__SSP1_D7 0x0071 +#define MX28_PAD_GPMI_CE0N__SSP3_D0 0x0101 +#define MX28_PAD_GPMI_CE1N__SSP3_D3 0x0111 +#define MX28_PAD_GPMI_CE2N__CAN1_TX 0x0121 +#define MX28_PAD_GPMI_CE3N__CAN1_RX 0x0131 +#define MX28_PAD_GPMI_RDY0__SSP1_CARD_DETECT 0x0141 +#define MX28_PAD_GPMI_RDY1__SSP1_CMD 0x0151 +#define MX28_PAD_GPMI_RDY2__CAN0_TX 0x0161 +#define MX28_PAD_GPMI_RDY3__CAN0_RX 0x0171 +#define MX28_PAD_GPMI_RDN__SSP3_SCK 0x0181 +#define MX28_PAD_GPMI_WRN__SSP1_SCK 0x0191 +#define MX28_PAD_GPMI_ALE__SSP3_D1 0x01a1 +#define MX28_PAD_GPMI_CLE__SSP3_D2 0x01b1 +#define MX28_PAD_GPMI_RESETN__SSP3_CMD 0x01c1 +#define MX28_PAD_LCD_D03__ETM_DA8 0x1031 +#define MX28_PAD_LCD_D04__ETM_DA9 0x1041 +#define MX28_PAD_LCD_D08__ETM_DA3 0x1081 +#define MX28_PAD_LCD_D09__ETM_DA4 0x1091 +#define MX28_PAD_LCD_D20__ENET1_1588_EVENT2_OUT 0x1141 +#define MX28_PAD_LCD_D21__ENET1_1588_EVENT2_IN 0x1151 +#define MX28_PAD_LCD_D22__ENET1_1588_EVENT3_OUT 0x1161 +#define MX28_PAD_LCD_D23__ENET1_1588_EVENT3_IN 0x1171 +#define MX28_PAD_LCD_RD_E__LCD_VSYNC 0x1181 +#define MX28_PAD_LCD_WR_RWN__LCD_HSYNC 0x1191 +#define MX28_PAD_LCD_RS__LCD_DOTCLK 0x11a1 +#define MX28_PAD_LCD_CS__LCD_ENABLE 0x11b1 +#define MX28_PAD_LCD_VSYNC__SAIF1_SDATA0 0x11c1 +#define MX28_PAD_LCD_HSYNC__SAIF1_SDATA1 0x11d1 +#define MX28_PAD_LCD_DOTCLK__SAIF1_MCLK 0x11e1 +#define MX28_PAD_SSP0_DATA4__SSP2_D0 0x2041 +#define MX28_PAD_SSP0_DATA5__SSP2_D3 0x2051 +#define MX28_PAD_SSP0_DATA6__SSP2_CMD 0x2061 +#define MX28_PAD_SSP0_DATA7__SSP2_SCK 0x2071 +#define MX28_PAD_SSP1_SCK__SSP2_D1 0x20c1 +#define MX28_PAD_SSP1_CMD__SSP2_D2 0x20d1 +#define MX28_PAD_SSP1_DATA0__SSP2_D6 0x20e1 +#define MX28_PAD_SSP1_DATA3__SSP2_D7 0x20f1 +#define MX28_PAD_SSP2_SCK__AUART2_RX 0x2101 +#define MX28_PAD_SSP2_MOSI__AUART2_TX 0x2111 +#define MX28_PAD_SSP2_MISO__AUART3_RX 0x2121 +#define MX28_PAD_SSP2_SS0__AUART3_TX 0x2131 +#define MX28_PAD_SSP2_SS1__SSP2_D1 0x2141 +#define MX28_PAD_SSP2_SS2__SSP2_D2 0x2151 +#define MX28_PAD_SSP3_SCK__AUART4_TX 0x2181 +#define MX28_PAD_SSP3_MOSI__AUART4_RX 0x2191 +#define MX28_PAD_SSP3_MISO__AUART4_RTS 0x21a1 +#define MX28_PAD_SSP3_SS0__AUART4_CTS 0x21b1 +#define MX28_PAD_AUART0_RX__I2C0_SCL 0x3001 +#define MX28_PAD_AUART0_TX__I2C0_SDA 0x3011 +#define MX28_PAD_AUART0_CTS__AUART4_RX 0x3021 +#define MX28_PAD_AUART0_RTS__AUART4_TX 0x3031 +#define MX28_PAD_AUART1_RX__SSP2_CARD_DETECT 0x3041 +#define MX28_PAD_AUART1_TX__SSP3_CARD_DETECT 0x3051 +#define MX28_PAD_AUART1_CTS__USB0_OVERCURRENT 0x3061 +#define MX28_PAD_AUART1_RTS__USB0_ID 0x3071 +#define MX28_PAD_AUART2_RX__SSP3_D1 0x3081 +#define MX28_PAD_AUART2_TX__SSP3_D2 0x3091 +#define MX28_PAD_AUART2_CTS__I2C1_SCL 0x30a1 +#define MX28_PAD_AUART2_RTS__I2C1_SDA 0x30b1 +#define MX28_PAD_AUART3_RX__CAN0_TX 0x30c1 +#define MX28_PAD_AUART3_TX__CAN0_RX 0x30d1 +#define MX28_PAD_AUART3_CTS__CAN1_TX 0x30e1 +#define MX28_PAD_AUART3_RTS__CAN1_RX 0x30f1 +#define MX28_PAD_PWM0__I2C1_SCL 0x3101 +#define MX28_PAD_PWM1__I2C1_SDA 0x3111 +#define MX28_PAD_PWM2__USB0_ID 0x3121 +#define MX28_PAD_SAIF0_MCLK__PWM_3 0x3141 +#define MX28_PAD_SAIF0_LRCLK__PWM_4 0x3151 +#define MX28_PAD_SAIF0_BITCLK__PWM_5 0x3161 +#define MX28_PAD_SAIF0_SDATA0__PWM_6 0x3171 +#define MX28_PAD_I2C0_SCL__TIMROT_ROTARYA 0x3181 +#define MX28_PAD_I2C0_SDA__TIMROT_ROTARYB 0x3191 +#define MX28_PAD_SAIF1_SDATA0__PWM_7 0x31a1 +#define MX28_PAD_LCD_RESET__LCD_VSYNC 0x31e1 +#define MX28_PAD_ENET0_MDC__GPMI_CE4N 0x4001 +#define MX28_PAD_ENET0_MDIO__GPMI_CE5N 0x4011 +#define MX28_PAD_ENET0_RX_EN__GPMI_CE6N 0x4021 +#define MX28_PAD_ENET0_RXD0__GPMI_CE7N 0x4031 +#define MX28_PAD_ENET0_RXD1__GPMI_READY4 0x4041 +#define MX28_PAD_ENET0_TX_CLK__HSADC_TRIGGER 0x4051 +#define MX28_PAD_ENET0_TX_EN__GPMI_READY5 0x4061 +#define MX28_PAD_ENET0_TXD0__GPMI_READY6 0x4071 +#define MX28_PAD_ENET0_TXD1__GPMI_READY7 0x4081 +#define MX28_PAD_ENET0_RXD2__ENET1_RXD0 0x4091 +#define MX28_PAD_ENET0_RXD3__ENET1_RXD1 0x40a1 +#define MX28_PAD_ENET0_TXD2__ENET1_TXD0 0x40b1 +#define MX28_PAD_ENET0_TXD3__ENET1_TXD1 0x40c1 +#define MX28_PAD_ENET0_RX_CLK__ENET0_RX_ER 0x40d1 +#define MX28_PAD_ENET0_COL__ENET1_TX_EN 0x40e1 +#define MX28_PAD_ENET0_CRS__ENET1_RX_EN 0x40f1 +#define MX28_PAD_GPMI_CE2N__ENET0_RX_ER 0x0122 +#define MX28_PAD_GPMI_CE3N__SAIF1_MCLK 0x0132 +#define MX28_PAD_GPMI_RDY0__USB0_ID 0x0142 +#define MX28_PAD_GPMI_RDY2__ENET0_TX_ER 0x0162 +#define MX28_PAD_GPMI_RDY3__HSADC_TRIGGER 0x0172 +#define MX28_PAD_GPMI_ALE__SSP3_D4 0x01a2 +#define MX28_PAD_GPMI_CLE__SSP3_D5 0x01b2 +#define MX28_PAD_LCD_D00__ETM_DA0 0x1002 +#define MX28_PAD_LCD_D01__ETM_DA1 0x1012 +#define MX28_PAD_LCD_D02__ETM_DA2 0x1022 +#define MX28_PAD_LCD_D03__ETM_DA3 0x1032 +#define MX28_PAD_LCD_D04__ETM_DA4 0x1042 +#define MX28_PAD_LCD_D05__ETM_DA5 0x1052 +#define MX28_PAD_LCD_D06__ETM_DA6 0x1062 +#define MX28_PAD_LCD_D07__ETM_DA7 0x1072 +#define MX28_PAD_LCD_D08__ETM_DA8 0x1082 +#define MX28_PAD_LCD_D09__ETM_DA9 0x1092 +#define MX28_PAD_LCD_D10__ETM_DA10 0x10a2 +#define MX28_PAD_LCD_D11__ETM_DA11 0x10b2 +#define MX28_PAD_LCD_D12__ETM_DA12 0x10c2 +#define MX28_PAD_LCD_D13__ETM_DA13 0x10d2 +#define MX28_PAD_LCD_D14__ETM_DA14 0x10e2 +#define MX28_PAD_LCD_D15__ETM_DA15 0x10f2 +#define MX28_PAD_LCD_D16__ETM_DA7 0x1102 +#define MX28_PAD_LCD_D17__ETM_DA6 0x1112 +#define MX28_PAD_LCD_D18__ETM_DA5 0x1122 +#define MX28_PAD_LCD_D19__ETM_DA4 0x1132 +#define MX28_PAD_LCD_D20__ETM_DA3 0x1142 +#define MX28_PAD_LCD_D21__ETM_DA2 0x1152 +#define MX28_PAD_LCD_D22__ETM_DA1 0x1162 +#define MX28_PAD_LCD_D23__ETM_DA0 0x1172 +#define MX28_PAD_LCD_RD_E__ETM_TCTL 0x1182 +#define MX28_PAD_LCD_WR_RWN__ETM_TCLK 0x1192 +#define MX28_PAD_LCD_HSYNC__ETM_TCTL 0x11d2 +#define MX28_PAD_LCD_DOTCLK__ETM_TCLK 0x11e2 +#define MX28_PAD_SSP1_SCK__ENET0_1588_EVENT2_OUT 0x20c2 +#define MX28_PAD_SSP1_CMD__ENET0_1588_EVENT2_IN 0x20d2 +#define MX28_PAD_SSP1_DATA0__ENET0_1588_EVENT3_OUT 0x20e2 +#define MX28_PAD_SSP1_DATA3__ENET0_1588_EVENT3_IN 0x20f2 +#define MX28_PAD_SSP2_SCK__SAIF0_SDATA1 0x2102 +#define MX28_PAD_SSP2_MOSI__SAIF0_SDATA2 0x2112 +#define MX28_PAD_SSP2_MISO__SAIF1_SDATA1 0x2122 +#define MX28_PAD_SSP2_SS0__SAIF1_SDATA2 0x2132 +#define MX28_PAD_SSP2_SS1__USB1_OVERCURRENT 0x2142 +#define MX28_PAD_SSP2_SS2__USB0_OVERCURRENT 0x2152 +#define MX28_PAD_SSP3_SCK__ENET1_1588_EVENT0_OUT 0x2182 +#define MX28_PAD_SSP3_MOSI__ENET1_1588_EVENT0_IN 0x2192 +#define MX28_PAD_SSP3_MISO__ENET1_1588_EVENT1_OUT 0x21a2 +#define MX28_PAD_SSP3_SS0__ENET1_1588_EVENT1_IN 0x21b2 +#define MX28_PAD_AUART0_RX__DUART_CTS 0x3002 +#define MX28_PAD_AUART0_TX__DUART_RTS 0x3012 +#define MX28_PAD_AUART0_CTS__DUART_RX 0x3022 +#define MX28_PAD_AUART0_RTS__DUART_TX 0x3032 +#define MX28_PAD_AUART1_RX__PWM_0 0x3042 +#define MX28_PAD_AUART1_TX__PWM_1 0x3052 +#define MX28_PAD_AUART1_CTS__TIMROT_ROTARYA 0x3062 +#define MX28_PAD_AUART1_RTS__TIMROT_ROTARYB 0x3072 +#define MX28_PAD_AUART2_RX__SSP3_D4 0x3082 +#define MX28_PAD_AUART2_TX__SSP3_D5 0x3092 +#define MX28_PAD_AUART2_CTS__SAIF1_BITCLK 0x30a2 +#define MX28_PAD_AUART2_RTS__SAIF1_LRCLK 0x30b2 +#define MX28_PAD_AUART3_RX__ENET0_1588_EVENT0_OUT 0x30c2 +#define MX28_PAD_AUART3_TX__ENET0_1588_EVENT0_IN 0x30d2 +#define MX28_PAD_AUART3_CTS__ENET0_1588_EVENT1_OUT 0x30e2 +#define MX28_PAD_AUART3_RTS__ENET0_1588_EVENT1_IN 0x30f2 +#define MX28_PAD_PWM0__DUART_RX 0x3102 +#define MX28_PAD_PWM1__DUART_TX 0x3112 +#define MX28_PAD_PWM2__USB1_OVERCURRENT 0x3122 +#define MX28_PAD_SAIF0_MCLK__AUART4_CTS 0x3142 +#define MX28_PAD_SAIF0_LRCLK__AUART4_RTS 0x3152 +#define MX28_PAD_SAIF0_BITCLK__AUART4_RX 0x3162 +#define MX28_PAD_SAIF0_SDATA0__AUART4_TX 0x3172 +#define MX28_PAD_I2C0_SCL__DUART_RX 0x3182 +#define MX28_PAD_I2C0_SDA__DUART_TX 0x3192 +#define MX28_PAD_SAIF1_SDATA0__SAIF0_SDATA1 0x31a2 +#define MX28_PAD_SPDIF__ENET1_RX_ER 0x31b2 +#define MX28_PAD_ENET0_MDC__SAIF0_SDATA1 0x4002 +#define MX28_PAD_ENET0_MDIO__SAIF0_SDATA2 0x4012 +#define MX28_PAD_ENET0_RX_EN__SAIF1_SDATA1 0x4022 +#define MX28_PAD_ENET0_RXD0__SAIF1_SDATA2 0x4032 +#define MX28_PAD_ENET0_TX_CLK__ENET0_1588_EVENT2_OUT 0x4052 +#define MX28_PAD_ENET0_RXD2__ENET0_1588_EVENT0_OUT 0x4092 +#define MX28_PAD_ENET0_RXD3__ENET0_1588_EVENT0_IN 0x40a2 +#define MX28_PAD_ENET0_TXD2__ENET0_1588_EVENT1_OUT 0x40b2 +#define MX28_PAD_ENET0_TXD3__ENET0_1588_EVENT1_IN 0x40c2 +#define MX28_PAD_ENET0_RX_CLK__ENET0_1588_EVENT2_IN 0x40d2 +#define MX28_PAD_ENET0_COL__ENET0_1588_EVENT3_OUT 0x40e2 +#define MX28_PAD_ENET0_CRS__ENET0_1588_EVENT3_IN 0x40f2 +#define MX28_PAD_GPMI_D00__GPIO_0_0 0x0003 +#define MX28_PAD_GPMI_D01__GPIO_0_1 0x0013 +#define MX28_PAD_GPMI_D02__GPIO_0_2 0x0023 +#define MX28_PAD_GPMI_D03__GPIO_0_3 0x0033 +#define MX28_PAD_GPMI_D04__GPIO_0_4 0x0043 +#define MX28_PAD_GPMI_D05__GPIO_0_5 0x0053 +#define MX28_PAD_GPMI_D06__GPIO_0_6 0x0063 +#define MX28_PAD_GPMI_D07__GPIO_0_7 0x0073 +#define MX28_PAD_GPMI_CE0N__GPIO_0_16 0x0103 +#define MX28_PAD_GPMI_CE1N__GPIO_0_17 0x0113 +#define MX28_PAD_GPMI_CE2N__GPIO_0_18 0x0123 +#define MX28_PAD_GPMI_CE3N__GPIO_0_19 0x0133 +#define MX28_PAD_GPMI_RDY0__GPIO_0_20 0x0143 +#define MX28_PAD_GPMI_RDY1__GPIO_0_21 0x0153 +#define MX28_PAD_GPMI_RDY2__GPIO_0_22 0x0163 +#define MX28_PAD_GPMI_RDY3__GPIO_0_23 0x0173 +#define MX28_PAD_GPMI_RDN__GPIO_0_24 0x0183 +#define MX28_PAD_GPMI_WRN__GPIO_0_25 0x0193 +#define MX28_PAD_GPMI_ALE__GPIO_0_26 0x01a3 +#define MX28_PAD_GPMI_CLE__GPIO_0_27 0x01b3 +#define MX28_PAD_GPMI_RESETN__GPIO_0_28 0x01c3 +#define MX28_PAD_LCD_D00__GPIO_1_0 0x1003 +#define MX28_PAD_LCD_D01__GPIO_1_1 0x1013 +#define MX28_PAD_LCD_D02__GPIO_1_2 0x1023 +#define MX28_PAD_LCD_D03__GPIO_1_3 0x1033 +#define MX28_PAD_LCD_D04__GPIO_1_4 0x1043 +#define MX28_PAD_LCD_D05__GPIO_1_5 0x1053 +#define MX28_PAD_LCD_D06__GPIO_1_6 0x1063 +#define MX28_PAD_LCD_D07__GPIO_1_7 0x1073 +#define MX28_PAD_LCD_D08__GPIO_1_8 0x1083 +#define MX28_PAD_LCD_D09__GPIO_1_9 0x1093 +#define MX28_PAD_LCD_D10__GPIO_1_10 0x10a3 +#define MX28_PAD_LCD_D11__GPIO_1_11 0x10b3 +#define MX28_PAD_LCD_D12__GPIO_1_12 0x10c3 +#define MX28_PAD_LCD_D13__GPIO_1_13 0x10d3 +#define MX28_PAD_LCD_D14__GPIO_1_14 0x10e3 +#define MX28_PAD_LCD_D15__GPIO_1_15 0x10f3 +#define MX28_PAD_LCD_D16__GPIO_1_16 0x1103 +#define MX28_PAD_LCD_D17__GPIO_1_17 0x1113 +#define MX28_PAD_LCD_D18__GPIO_1_18 0x1123 +#define MX28_PAD_LCD_D19__GPIO_1_19 0x1133 +#define MX28_PAD_LCD_D20__GPIO_1_20 0x1143 +#define MX28_PAD_LCD_D21__GPIO_1_21 0x1153 +#define MX28_PAD_LCD_D22__GPIO_1_22 0x1163 +#define MX28_PAD_LCD_D23__GPIO_1_23 0x1173 +#define MX28_PAD_LCD_RD_E__GPIO_1_24 0x1183 +#define MX28_PAD_LCD_WR_RWN__GPIO_1_25 0x1193 +#define MX28_PAD_LCD_RS__GPIO_1_26 0x11a3 +#define MX28_PAD_LCD_CS__GPIO_1_27 0x11b3 +#define MX28_PAD_LCD_VSYNC__GPIO_1_28 0x11c3 +#define MX28_PAD_LCD_HSYNC__GPIO_1_29 0x11d3 +#define MX28_PAD_LCD_DOTCLK__GPIO_1_30 0x11e3 +#define MX28_PAD_LCD_ENABLE__GPIO_1_31 0x11f3 +#define MX28_PAD_SSP0_DATA0__GPIO_2_0 0x2003 +#define MX28_PAD_SSP0_DATA1__GPIO_2_1 0x2013 +#define MX28_PAD_SSP0_DATA2__GPIO_2_2 0x2023 +#define MX28_PAD_SSP0_DATA3__GPIO_2_3 0x2033 +#define MX28_PAD_SSP0_DATA4__GPIO_2_4 0x2043 +#define MX28_PAD_SSP0_DATA5__GPIO_2_5 0x2053 +#define MX28_PAD_SSP0_DATA6__GPIO_2_6 0x2063 +#define MX28_PAD_SSP0_DATA7__GPIO_2_7 0x2073 +#define MX28_PAD_SSP0_CMD__GPIO_2_8 0x2083 +#define MX28_PAD_SSP0_DETECT__GPIO_2_9 0x2093 +#define MX28_PAD_SSP0_SCK__GPIO_2_10 0x20a3 +#define MX28_PAD_SSP1_SCK__GPIO_2_12 0x20c3 +#define MX28_PAD_SSP1_CMD__GPIO_2_13 0x20d3 +#define MX28_PAD_SSP1_DATA0__GPIO_2_14 0x20e3 +#define MX28_PAD_SSP1_DATA3__GPIO_2_15 0x20f3 +#define MX28_PAD_SSP2_SCK__GPIO_2_16 0x2103 +#define MX28_PAD_SSP2_MOSI__GPIO_2_17 0x2113 +#define MX28_PAD_SSP2_MISO__GPIO_2_18 0x2123 +#define MX28_PAD_SSP2_SS0__GPIO_2_19 0x2133 +#define MX28_PAD_SSP2_SS1__GPIO_2_20 0x2143 +#define MX28_PAD_SSP2_SS2__GPIO_2_21 0x2153 +#define MX28_PAD_SSP3_SCK__GPIO_2_24 0x2183 +#define MX28_PAD_SSP3_MOSI__GPIO_2_25 0x2193 +#define MX28_PAD_SSP3_MISO__GPIO_2_26 0x21a3 +#define MX28_PAD_SSP3_SS0__GPIO_2_27 0x21b3 +#define MX28_PAD_AUART0_RX__GPIO_3_0 0x3003 +#define MX28_PAD_AUART0_TX__GPIO_3_1 0x3013 +#define MX28_PAD_AUART0_CTS__GPIO_3_2 0x3023 +#define MX28_PAD_AUART0_RTS__GPIO_3_3 0x3033 +#define MX28_PAD_AUART1_RX__GPIO_3_4 0x3043 +#define MX28_PAD_AUART1_TX__GPIO_3_5 0x3053 +#define MX28_PAD_AUART1_CTS__GPIO_3_6 0x3063 +#define MX28_PAD_AUART1_RTS__GPIO_3_7 0x3073 +#define MX28_PAD_AUART2_RX__GPIO_3_8 0x3083 +#define MX28_PAD_AUART2_TX__GPIO_3_9 0x3093 +#define MX28_PAD_AUART2_CTS__GPIO_3_10 0x30a3 +#define MX28_PAD_AUART2_RTS__GPIO_3_11 0x30b3 +#define MX28_PAD_AUART3_RX__GPIO_3_12 0x30c3 +#define MX28_PAD_AUART3_TX__GPIO_3_13 0x30d3 +#define MX28_PAD_AUART3_CTS__GPIO_3_14 0x30e3 +#define MX28_PAD_AUART3_RTS__GPIO_3_15 0x30f3 +#define MX28_PAD_PWM0__GPIO_3_16 0x3103 +#define MX28_PAD_PWM1__GPIO_3_17 0x3113 +#define MX28_PAD_PWM2__GPIO_3_18 0x3123 +#define MX28_PAD_SAIF0_MCLK__GPIO_3_20 0x3143 +#define MX28_PAD_SAIF0_LRCLK__GPIO_3_21 0x3153 +#define MX28_PAD_SAIF0_BITCLK__GPIO_3_22 0x3163 +#define MX28_PAD_SAIF0_SDATA0__GPIO_3_23 0x3173 +#define MX28_PAD_I2C0_SCL__GPIO_3_24 0x3183 +#define MX28_PAD_I2C0_SDA__GPIO_3_25 0x3193 +#define MX28_PAD_SAIF1_SDATA0__GPIO_3_26 0x31a3 +#define MX28_PAD_SPDIF__GPIO_3_27 0x31b3 +#define MX28_PAD_PWM3__GPIO_3_28 0x31c3 +#define MX28_PAD_PWM4__GPIO_3_29 0x31d3 +#define MX28_PAD_LCD_RESET__GPIO_3_30 0x31e3 +#define MX28_PAD_ENET0_MDC__GPIO_4_0 0x4003 +#define MX28_PAD_ENET0_MDIO__GPIO_4_1 0x4013 +#define MX28_PAD_ENET0_RX_EN__GPIO_4_2 0x4023 +#define MX28_PAD_ENET0_RXD0__GPIO_4_3 0x4033 +#define MX28_PAD_ENET0_RXD1__GPIO_4_4 0x4043 +#define MX28_PAD_ENET0_TX_CLK__GPIO_4_5 0x4053 +#define MX28_PAD_ENET0_TX_EN__GPIO_4_6 0x4063 +#define MX28_PAD_ENET0_TXD0__GPIO_4_7 0x4073 +#define MX28_PAD_ENET0_TXD1__GPIO_4_8 0x4083 +#define MX28_PAD_ENET0_RXD2__GPIO_4_9 0x4093 +#define MX28_PAD_ENET0_RXD3__GPIO_4_10 0x40a3 +#define MX28_PAD_ENET0_TXD2__GPIO_4_11 0x40b3 +#define MX28_PAD_ENET0_TXD3__GPIO_4_12 0x40c3 +#define MX28_PAD_ENET0_RX_CLK__GPIO_4_13 0x40d3 +#define MX28_PAD_ENET0_COL__GPIO_4_14 0x40e3 +#define MX28_PAD_ENET0_CRS__GPIO_4_15 0x40f3 +#define MX28_PAD_ENET_CLK__GPIO_4_16 0x4103 +#define MX28_PAD_JTAG_RTCK__GPIO_4_20 0x4143 + +#endif /* __DT_BINDINGS_MX28_PINCTRL_H__ */ diff --git a/arch/arm/boot/dts/imx28-sps1.dts b/arch/arm/boot/dts/imx28-sps1.dts index 6c6a5442800a..4870f07bf56a 100644 --- a/arch/arm/boot/dts/imx28-sps1.dts +++ b/arch/arm/boot/dts/imx28-sps1.dts @@ -10,7 +10,7 @@ */ /dts-v1/; -/include/ "imx28.dtsi" +#include "imx28.dtsi" / { model = "SchulerControl GmbH, SC SPS 1"; @@ -29,13 +29,13 @@ hog_pins_a: hog-gpios@0 { reg = <0>; fsl,pinmux-ids = < - 0x0003 /* MX28_PAD_GPMI_D00__GPIO_0_0 */ - 0x0033 /* MX28_PAD_GPMI_D03__GPIO_0_3 */ - 0x0063 /* MX28_PAD_GPMI_D06__GPIO_0_6 */ + MX28_PAD_GPMI_D00__GPIO_0_0 + MX28_PAD_GPMI_D03__GPIO_0_3 + MX28_PAD_GPMI_D06__GPIO_0_6 >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; }; diff --git a/arch/arm/boot/dts/imx28-tx28.dts b/arch/arm/boot/dts/imx28-tx28.dts index 37be532f0055..be5a0550d58c 100644 --- a/arch/arm/boot/dts/imx28-tx28.dts +++ b/arch/arm/boot/dts/imx28-tx28.dts @@ -1,106 +1,139 @@ +/* + * Copyright 2012 Shawn Guo <shawn.guo@linaro.org> + * Copyright 2013 Lothar Waßmann <LW@KARO-electronics.de> + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + /dts-v1/; -/include/ "imx28.dtsi" +#include "imx28.dtsi" +#include <dt-bindings/gpio/gpio.h> / { model = "Ka-Ro electronics TX28 module"; compatible = "karo,tx28", "fsl,imx28"; + aliases { + can0 = &can0; + can1 = &can1; + display = &display; + ds1339 = &ds1339; + gpio5 = &gpio5; + lcdif = &lcdif; + lcdif_23bit_pins = &tx28_lcdif_23bit_pins; + lcdif_24bit_pins = &lcdif_24bit_pins_a; + stk5led = &user_led; + usbotg = &usb0; + }; + memory { - reg = <0x40000000 0x08000000>; - }; - - apb@80000000 { - apbh@80000000 { - ssp0: ssp@80010000 { - compatible = "fsl,imx28-mmc"; - pinctrl-names = "default"; - pinctrl-0 = <&mmc0_4bit_pins_a - &mmc0_cd_cfg - &mmc0_sck_cfg>; - bus-width = <4>; - status = "okay"; - }; + reg = <0 0>; /* will be filled in by U-Boot */ + }; - pinctrl@80018000 { - pinctrl-names = "default"; - pinctrl-0 = <&hog_pins_a>; - - hog_pins_a: hog@0 { - reg = <0>; - fsl,pinmux-ids = < - 0x40a3 /* MX28_PAD_ENET0_RXD3__GPIO_4_10 */ - >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; - }; - - mac0_pins_gpio: mac0-gpio-mode@0 { - reg = <0>; - fsl,pinmux-ids = < - 0x4003 /* MX28_PAD_ENET0_MDC__GPIO_4_0 */ - 0x4013 /* MX28_PAD_ENET0_MDIO__GPIO_4_1 */ - 0x4023 /* MX28_PAD_ENET0_RX_EN__GPIO_4_2 */ - 0x4033 /* MX28_PAD_ENET0_RXD0__GPIO_4_3 */ - 0x4043 /* MX28_PAD_ENET0_RXD1__GPIO_4_4 */ - 0x4063 /* MX28_PAD_ENET0_TX_EN__GPIO_4_6 */ - 0x4073 /* MX28_PAD_ENET0_TXD0__GPIO_4_7 */ - 0x4083 /* MX28_PAD_ENET0_TXD1__GPIO_4_8 */ - 0x4103 /* MX28_PAD_ENET_CLK__GPIO_4_16 */ - >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; - }; - }; + onewire { + compatible = "w1-gpio"; + gpios = <&gpio2 7 0>; + status = "disabled"; + }; + + regulators { + compatible = "simple-bus"; + + reg_usb0_vbus: usb0_vbus { + compatible = "regulator-fixed"; + regulator-name = "usb0_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio0 18 0>; + enable-active-high; }; - apbx@80040000 { - i2c0: i2c@80058000 { - pinctrl-names = "default"; - pinctrl-0 = <&i2c0_pins_a>; - status = "okay"; + reg_usb1_vbus: usb1_vbus { + compatible = "regulator-fixed"; + regulator-name = "usb1_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio3 27 0>; + enable-active-high; + }; - ds1339: rtc@68 { - compatible = "mxim,ds1339"; - reg = <0x68>; - }; - }; + reg_2p5v: 2p5v { + compatible = "regulator-fixed"; + regulator-name = "2P5V"; + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <2500000>; + regulator-always-on; + }; - pwm: pwm@80064000 { - pinctrl-names = "default"; - pinctrl-0 = <&pwm0_pins_a>; - status = "okay"; - }; + reg_3p3v: 3p3v { + compatible = "regulator-fixed"; + regulator-name = "3P3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; - duart: serial@80074000 { - pinctrl-names = "default"; - pinctrl-0 = <&duart_4pins_a>; - status = "okay"; - }; + reg_can_xcvr: can-xcvr { + compatible = "regulator-fixed"; + regulator-name = "CAN XCVR"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio1 0 0>; + enable-active-low; + pinctrl-names = "default"; + pinctrl-0 = <&tx28_flexcan_xcvr_pins>; + }; - auart1: serial@8006c000 { - pinctrl-names = "default"; - pinctrl-0 = <&auart1_pins_a>; - status = "okay"; - }; + reg_lcd: lcd-power { + compatible = "regulator-fixed"; + regulator-name = "LCD POWER"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio1 31 0>; + enable-active-high; + }; + + reg_lcd_reset: lcd-reset { + compatible = "regulator-fixed"; + regulator-name = "LCD RESET"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio3 30 0>; + startup-delay-us = <300000>; + enable-active-high; + regulator-always-on; + regulator-boot-on; }; }; - ahb@80080000 { - mac0: ethernet@800f0000 { - phy-mode = "rmii"; - pinctrl-names = "default", "gpio_mode"; - pinctrl-0 = <&mac0_pins_a>; - pinctrl-1 = <&mac0_pins_gpio>; - status = "okay"; + clocks { + #address-cells = <1>; + #size-cells = <0>; + mclk: clock@0 { + compatible = "fixed-clock"; + reg = <0>; + #clock-cells = <0>; + clock-frequency = <27000000>; }; }; + sound { + compatible = "fsl,imx28-tx28-sgtl5000", + "fsl,mxs-audio-sgtl5000"; + model = "imx28-tx28-sgtl5000"; + saif-controllers = <&saif0 &saif1>; + audio-codec = <&sgtl5000>; + }; + leds { compatible = "gpio-leds"; - user { + user_led: user { label = "Heartbeat"; gpios = <&gpio4 10 0>; linux,default-trigger = "heartbeat"; @@ -109,8 +142,512 @@ backlight { compatible = "pwm-backlight"; - pwms = <&pwm 0 5000000>; - brightness-levels = <0 4 8 16 32 64 128 255>; - default-brightness-level = <6>; + pwms = <&pwm 0 500000>; + /* + * a silly way to create a 1:1 relationship between the + * PWM value and the actual duty cycle + */ + brightness-levels = < 0 1 2 3 4 5 6 7 8 9 + 10 11 12 13 14 15 16 17 18 19 + 20 21 22 23 24 25 26 27 28 29 + 30 31 32 33 34 35 36 37 38 39 + 40 41 42 43 44 45 46 47 48 49 + 50 51 52 53 54 55 56 57 58 59 + 60 61 62 63 64 65 66 67 68 69 + 70 71 72 73 74 75 76 77 78 79 + 80 81 82 83 84 85 86 87 88 89 + 90 91 92 93 94 95 96 97 98 99 + 100>; + default-brightness-level = <50>; + }; + + matrix_keypad: matrix-keypad@0 { + compatible = "gpio-matrix-keypad"; + col-gpios = < + &gpio5 0 0 + &gpio5 1 0 + &gpio5 2 0 + &gpio5 3 0 + >; + row-gpios = < + &gpio5 4 0 + &gpio5 5 0 + &gpio5 6 0 + &gpio5 7 0 + >; + /* sample keymap */ + linux,keymap = < + 0x00000074 /* row 0, col 0, KEY_POWER */ + 0x00010052 /* row 0, col 1, KEY_KP0 */ + 0x0002004f /* row 0, col 2, KEY_KP1 */ + 0x00030050 /* row 0, col 3, KEY_KP2 */ + 0x01000051 /* row 1, col 0, KEY_KP3 */ + 0x0101004b /* row 1, col 1, KEY_KP4 */ + 0x0102004c /* row 1, col 2, KEY_KP5 */ + 0x0103004d /* row 1, col 3, KEY_KP6 */ + 0x02000047 /* row 2, col 0, KEY_KP7 */ + 0x02010048 /* row 2, col 1, KEY_KP8 */ + 0x02020049 /* row 2, col 2, KEY_KP9 */ + >; + gpio-activelow; + linux,wakeup; + debounce-delay-ms = <100>; + col-scan-delay-us = <5000>; + linux,no-autorepeat; + }; +}; + +/* 2nd TX-Std UART - (A)UART1 */ +&auart1 { + pinctrl-names = "default"; + pinctrl-0 = <&auart1_pins_a>; + status = "okay"; +}; + +/* 3rd TX-Std UART - (A)UART3 */ +&auart3 { + pinctrl-names = "default"; + pinctrl-0 = <&auart3_pins_a>; + status = "okay"; +}; + +&can0 { + pinctrl-names = "default"; + pinctrl-0 = <&can0_pins_a>; + xceiver-supply = <®_can_xcvr>; + status = "okay"; +}; + +&can1 { + pinctrl-names = "default"; + pinctrl-0 = <&can1_pins_a>; + xceiver-supply = <®_can_xcvr>; + status = "okay"; +}; + +&digctl { + status = "okay"; +}; + +/* 1st TX-Std UART - (D)UART */ +&duart { + pinctrl-names = "default"; + pinctrl-0 = <&duart_4pins_a>; + status = "okay"; +}; + +&gpmi { + pinctrl-0 = <&gpmi_pins_a &gpmi_status_cfg>; + nand-on-flash-bbt; + status = "okay"; +}; + +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins_a>; + clock-frequency = <400000>; + status = "okay"; + + sgtl5000: sgtl5000@0a { + compatible = "fsl,sgtl5000"; + reg = <0x0a>; + VDDA-supply = <®_2p5v>; + VDDIO-supply = <®_3p3v>; + clocks = <&mclk>; + }; + + gpio5: pca953x@20 { + compatible = "nxp,pca9554"; + reg = <0x20>; + pinctrl-names = "default"; + pinctrl-0 = <&tx28_pca9554_pins>; + interrupt-parent = <&gpio3>; + interrupts = <28 0>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + polytouch: edt-ft5x06@38 { + compatible = "edt,edt-ft5x06"; + reg = <0x38>; + pinctrl-names = "default"; + pinctrl-0 = <&tx28_edt_ft5x06_pins>; + interrupt-parent = <&gpio2>; + interrupts = <5 0>; + reset-gpios = <&gpio2 6 1>; + wake-gpios = <&gpio4 9 0>; + }; + + touchscreen: tsc2007@48 { + compatible = "ti,tsc2007"; + reg = <0x48>; + pinctrl-names = "default"; + pinctrl-0 = <&tx28_tsc2007_pins>; + interrupt-parent = <&gpio3>; + interrupts = <20 0>; + pendown-gpio = <&gpio3 20 1>; + ti,x-plate-ohms = /bits/ 16 <660>; + }; + + ds1339: rtc@68 { + compatible = "mxim,ds1339"; + reg = <0x68>; + }; +}; + +&lcdif { + pinctrl-names = "default"; + pinctrl-0 = <&lcdif_24bit_pins_a &lcdif_sync_pins_a &tx28_lcdif_ctrl_pins>; + lcd-supply = <®_lcd>; + display = <&display>; + status = "okay"; + + display: display@0 { + bits-per-pixel = <32>; + bus-width = <24>; + display-timings { + native-mode = <&timing5>; + timing0: timing0 { + panel-name = "VGA"; + clock-frequency = <25175000>; + hactive = <640>; + vactive = <480>; + hback-porch = <48>; + hsync-len = <96>; + hfront-porch = <16>; + vback-porch = <33>; + vsync-len = <2>; + vfront-porch = <10>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <1>; + pixelclk-active = <1>; + }; + + timing1: timing1 { + panel-name = "ETV570"; + clock-frequency = <25175000>; + hactive = <640>; + vactive = <480>; + hback-porch = <114>; + hsync-len = <30>; + hfront-porch = <16>; + vback-porch = <32>; + vsync-len = <3>; + vfront-porch = <10>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <1>; + pixelclk-active = <1>; + }; + + timing2: timing2 { + panel-name = "ET0350"; + clock-frequency = <6500000>; + hactive = <320>; + vactive = <240>; + hback-porch = <34>; + hsync-len = <34>; + hfront-porch = <20>; + vback-porch = <15>; + vsync-len = <3>; + vfront-porch = <4>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <1>; + pixelclk-active = <1>; + }; + + timing3: timing3 { + panel-name = "ET0430"; + clock-frequency = <9000000>; + hactive = <480>; + vactive = <272>; + hback-porch = <2>; + hsync-len = <41>; + hfront-porch = <2>; + vback-porch = <2>; + vsync-len = <10>; + vfront-porch = <2>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <1>; + pixelclk-active = <1>; + }; + + timing4: timing4 { + panel-name = "ET0500", "ET0700"; + clock-frequency = <33260000>; + hactive = <800>; + vactive = <480>; + hback-porch = <88>; + hsync-len = <128>; + hfront-porch = <40>; + vback-porch = <33>; + vsync-len = <2>; + vfront-porch = <10>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <1>; + pixelclk-active = <1>; + }; + + timing5: timing5 { + panel-name = "ETQ570"; + clock-frequency = <6400000>; + hactive = <320>; + vactive = <240>; + hback-porch = <38>; + hsync-len = <30>; + hfront-porch = <30>; + vback-porch = <16>; + vsync-len = <3>; + vfront-porch = <4>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <1>; + pixelclk-active = <1>; + }; + }; + }; +}; + +&lradc { + fsl,lradc-touchscreen-wires = <4>; + status = "okay"; +}; + +&mac0 { + phy-mode = "rmii"; + pinctrl-names = "default", "gpio_mode"; + pinctrl-0 = <&mac0_pins_a>; + pinctrl-1 = <&tx28_mac0_pins_gpio>; + status = "okay"; +}; + +&mac1 { + phy-mode = "rmii"; + pinctrl-names = "default"; + pinctrl-0 = <&mac1_pins_a>; + /* not enabled by default */ +}; + +&mxs_rtc { + status = "okay"; +}; + +&ocotp { + status = "okay"; +}; + +&pwm { + pinctrl-names = "default"; + pinctrl-0 = <&pwm0_pins_a>; + status = "okay"; +}; + +&pinctrl { + pinctrl-names = "default"; + pinctrl-0 = <&hog_pins_a>; + + hog_pins_a: hog@0 { + reg = <0>; + fsl,pinmux-ids = < + MX28_PAD_ENET0_RXD3__GPIO_4_10 /* module LED */ + >; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; + }; + + tx28_edt_ft5x06_pins: tx28-edt-ft5x06-pins { + fsl,pinmux-ids = < + MX28_PAD_SSP0_DATA6__GPIO_2_6 /* RESET */ + MX28_PAD_SSP0_DATA5__GPIO_2_5 /* IRQ */ + MX28_PAD_ENET0_RXD2__GPIO_4_9 /* WAKE */ + >; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; + }; + + tx28_flexcan_xcvr_pins: tx28-flexcan-xcvr-pins { + fsl,pinmux-ids = < + MX28_PAD_LCD_D00__GPIO_1_0 + >; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; + }; + + tx28_lcdif_23bit_pins: tx28-lcdif-23bit { + fsl,pinmux-ids = < + /* LCD_D00 may be used as Flexcan Transceiver Enable on STK5-V5 */ + MX28_PAD_LCD_D01__LCD_D1 + MX28_PAD_LCD_D02__LCD_D2 + MX28_PAD_LCD_D03__LCD_D3 + MX28_PAD_LCD_D04__LCD_D4 + MX28_PAD_LCD_D05__LCD_D5 + MX28_PAD_LCD_D06__LCD_D6 + MX28_PAD_LCD_D07__LCD_D7 + MX28_PAD_LCD_D08__LCD_D8 + MX28_PAD_LCD_D09__LCD_D9 + MX28_PAD_LCD_D10__LCD_D10 + MX28_PAD_LCD_D11__LCD_D11 + MX28_PAD_LCD_D12__LCD_D12 + MX28_PAD_LCD_D13__LCD_D13 + MX28_PAD_LCD_D14__LCD_D14 + MX28_PAD_LCD_D15__LCD_D15 + MX28_PAD_LCD_D16__LCD_D16 + MX28_PAD_LCD_D17__LCD_D17 + MX28_PAD_LCD_D18__LCD_D18 + MX28_PAD_LCD_D19__LCD_D19 + MX28_PAD_LCD_D20__LCD_D20 + MX28_PAD_LCD_D21__LCD_D21 + MX28_PAD_LCD_D22__LCD_D22 + MX28_PAD_LCD_D23__LCD_D23 + >; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; + }; + + tx28_lcdif_ctrl_pins: tx28-lcdif-ctrl { + fsl,pinmux-ids = < + MX28_PAD_LCD_ENABLE__GPIO_1_31 /* Enable */ + MX28_PAD_LCD_RESET__GPIO_3_30 /* Reset */ + >; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; + }; + + tx28_mac0_pins_gpio: tx28-mac0-gpio-pins { + fsl,pinmux-ids = < + MX28_PAD_ENET0_MDC__GPIO_4_0 + MX28_PAD_ENET0_MDIO__GPIO_4_1 + MX28_PAD_ENET0_RX_EN__GPIO_4_2 + MX28_PAD_ENET0_RXD0__GPIO_4_3 + MX28_PAD_ENET0_RXD1__GPIO_4_4 + MX28_PAD_ENET0_TX_EN__GPIO_4_6 + MX28_PAD_ENET0_TXD0__GPIO_4_7 + MX28_PAD_ENET0_TXD1__GPIO_4_8 + MX28_PAD_ENET_CLK__GPIO_4_16 + >; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; + }; + + tx28_pca9554_pins: tx28-pca9554-pins { + fsl,pinmux-ids = < + MX28_PAD_PWM3__GPIO_3_28 + >; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; + }; + + tx28_tsc2007_pins: tx28-tsc2007-pins { + fsl,pinmux-ids = < + MX28_PAD_SAIF0_MCLK__GPIO_3_20 /* TSC2007 IRQ */ + >; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; + }; + + + tx28_usbphy0_pins: tx28-usbphy0-pins { + fsl,pinmux-ids = < + MX28_PAD_GPMI_CE2N__GPIO_0_18 /* USBOTG_VBUSEN */ + MX28_PAD_GPMI_CE3N__GPIO_0_19 /* USBOTH_OC */ + >; + fsl,drive-strength = <MXS_DRIVE_12mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; + }; + + tx28_usbphy1_pins: tx28-usbphy1-pins { + fsl,pinmux-ids = < + MX28_PAD_SPDIF__GPIO_3_27 /* USBH_VBUSEN */ + MX28_PAD_JTAG_RTCK__GPIO_4_20 /* USBH_OC */ + >; + fsl,drive-strength = <MXS_DRIVE_12mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; + }; +}; + +&saif0 { + pinctrl-names = "default"; + pinctrl-0 = <&saif0_pins_b>; + fsl,saif-master; + status = "okay"; +}; + +&saif1 { + pinctrl-names = "default"; + pinctrl-0 = <&saif1_pins_a>; + status = "okay"; +}; + +&ssp0 { + compatible = "fsl,imx28-mmc"; + pinctrl-names = "default", "special"; + pinctrl-0 = <&mmc0_4bit_pins_a + &mmc0_cd_cfg + &mmc0_sck_cfg>; + bus-width = <4>; + status = "okay"; +}; + +&ssp3 { + compatible = "fsl,imx28-spi"; + pinctrl-names = "default"; + pinctrl-0 = <&spi3_pins_a>; + clock-frequency = <57600000>; + status = "okay"; + + spidev0: spi@0 { + compatible = "spidev"; + reg = <0>; + spi-max-frequency = <57600000>; + }; + + spidev1: spi@1 { + compatible = "spidev"; + reg = <1>; + spi-max-frequency = <57600000>; }; }; + +&usb0 { + vbus-supply = <®_usb0_vbus>; + disable-over-current; + dr_mode = "peripheral"; + status = "okay"; +}; + +&usb1 { + vbus-supply = <®_usb1_vbus>; + disable-over-current; + dr_mode = "host"; + status = "okay"; +}; + +&usbphy0 { + pinctrl-names = "default"; + pinctrl-0 = <&tx28_usbphy0_pins>; + phy_type = "utmi"; + status = "okay"; +}; + +&usbphy1 { + pinctrl-names = "default"; + pinctrl-0 = <&tx28_usbphy1_pins>; + phy_type = "utmi"; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/imx28.dtsi b/arch/arm/boot/dts/imx28.dtsi index 7363fded95ee..cda19c8b0a47 100644 --- a/arch/arm/boot/dts/imx28.dtsi +++ b/arch/arm/boot/dts/imx28.dtsi @@ -9,7 +9,8 @@ * http://www.gnu.org/copyleft/gpl.html */ -/include/ "skeleton.dtsi" +#include "skeleton.dtsi" +#include "imx28-pinfunc.h" / { interrupt-parent = <&icoll>; @@ -207,538 +208,579 @@ duart_pins_a: duart@0 { reg = <0>; fsl,pinmux-ids = < - 0x3102 /* MX28_PAD_PWM0__DUART_RX */ - 0x3112 /* MX28_PAD_PWM1__DUART_TX */ + MX28_PAD_PWM0__DUART_RX + MX28_PAD_PWM1__DUART_TX >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; duart_pins_b: duart@1 { reg = <1>; fsl,pinmux-ids = < - 0x3022 /* MX28_PAD_AUART0_CTS__DUART_RX */ - 0x3032 /* MX28_PAD_AUART0_RTS__DUART_TX */ + MX28_PAD_AUART0_CTS__DUART_RX + MX28_PAD_AUART0_RTS__DUART_TX >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; duart_4pins_a: duart-4pins@0 { reg = <0>; fsl,pinmux-ids = < - 0x3022 /* MX28_PAD_AUART0_CTS__DUART_RX */ - 0x3032 /* MX28_PAD_AUART0_RTS__DUART_TX */ - 0x3002 /* MX28_PAD_AUART0_RX__DUART_CTS */ - 0x3012 /* MX28_PAD_AUART0_TX__DUART_RTS */ + MX28_PAD_AUART0_CTS__DUART_RX + MX28_PAD_AUART0_RTS__DUART_TX + MX28_PAD_AUART0_RX__DUART_CTS + MX28_PAD_AUART0_TX__DUART_RTS >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; gpmi_pins_a: gpmi-nand@0 { reg = <0>; fsl,pinmux-ids = < - 0x0000 /* MX28_PAD_GPMI_D00__GPMI_D0 */ - 0x0010 /* MX28_PAD_GPMI_D01__GPMI_D1 */ - 0x0020 /* MX28_PAD_GPMI_D02__GPMI_D2 */ - 0x0030 /* MX28_PAD_GPMI_D03__GPMI_D3 */ - 0x0040 /* MX28_PAD_GPMI_D04__GPMI_D4 */ - 0x0050 /* MX28_PAD_GPMI_D05__GPMI_D5 */ - 0x0060 /* MX28_PAD_GPMI_D06__GPMI_D6 */ - 0x0070 /* MX28_PAD_GPMI_D07__GPMI_D7 */ - 0x0100 /* MX28_PAD_GPMI_CE0N__GPMI_CE0N */ - 0x0140 /* MX28_PAD_GPMI_RDY0__GPMI_READY0 */ - 0x0180 /* MX28_PAD_GPMI_RDN__GPMI_RDN */ - 0x0190 /* MX28_PAD_GPMI_WRN__GPMI_WRN */ - 0x01a0 /* MX28_PAD_GPMI_ALE__GPMI_ALE */ - 0x01b0 /* MX28_PAD_GPMI_CLE__GPMI_CLE */ - 0x01c0 /* MX28_PAD_GPMI_RESETN__GPMI_RESETN */ + MX28_PAD_GPMI_D00__GPMI_D0 + MX28_PAD_GPMI_D01__GPMI_D1 + MX28_PAD_GPMI_D02__GPMI_D2 + MX28_PAD_GPMI_D03__GPMI_D3 + MX28_PAD_GPMI_D04__GPMI_D4 + MX28_PAD_GPMI_D05__GPMI_D5 + MX28_PAD_GPMI_D06__GPMI_D6 + MX28_PAD_GPMI_D07__GPMI_D7 + MX28_PAD_GPMI_CE0N__GPMI_CE0N + MX28_PAD_GPMI_RDY0__GPMI_READY0 + MX28_PAD_GPMI_RDN__GPMI_RDN + MX28_PAD_GPMI_WRN__GPMI_WRN + MX28_PAD_GPMI_ALE__GPMI_ALE + MX28_PAD_GPMI_CLE__GPMI_CLE + MX28_PAD_GPMI_RESETN__GPMI_RESETN >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; gpmi_status_cfg: gpmi-status-cfg { fsl,pinmux-ids = < - 0x0180 /* MX28_PAD_GPMI_RDN__GPMI_RDN */ - 0x0190 /* MX28_PAD_GPMI_WRN__GPMI_WRN */ - 0x01c0 /* MX28_PAD_GPMI_RESETN__GPMI_RESETN */ + MX28_PAD_GPMI_RDN__GPMI_RDN + MX28_PAD_GPMI_WRN__GPMI_WRN + MX28_PAD_GPMI_RESETN__GPMI_RESETN >; - fsl,drive-strength = <2>; + fsl,drive-strength = <MXS_DRIVE_12mA>; }; auart0_pins_a: auart0@0 { reg = <0>; fsl,pinmux-ids = < - 0x3000 /* MX28_PAD_AUART0_RX__AUART0_RX */ - 0x3010 /* MX28_PAD_AUART0_TX__AUART0_TX */ - 0x3020 /* MX28_PAD_AUART0_CTS__AUART0_CTS */ - 0x3030 /* MX28_PAD_AUART0_RTS__AUART0_RTS */ + MX28_PAD_AUART0_RX__AUART0_RX + MX28_PAD_AUART0_TX__AUART0_TX + MX28_PAD_AUART0_CTS__AUART0_CTS + MX28_PAD_AUART0_RTS__AUART0_RTS >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; auart0_2pins_a: auart0-2pins@0 { reg = <0>; fsl,pinmux-ids = < - 0x3000 /* MX28_PAD_AUART0_RX__AUART0_RX */ - 0x3010 /* MX28_PAD_AUART0_TX__AUART0_TX */ + MX28_PAD_AUART0_RX__AUART0_RX + MX28_PAD_AUART0_TX__AUART0_TX >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; auart1_pins_a: auart1@0 { reg = <0>; fsl,pinmux-ids = < - 0x3040 /* MX28_PAD_AUART1_RX__AUART1_RX */ - 0x3050 /* MX28_PAD_AUART1_TX__AUART1_TX */ - 0x3060 /* MX28_PAD_AUART1_CTS__AUART1_CTS */ - 0x3070 /* MX28_PAD_AUART1_RTS__AUART1_RTS */ + MX28_PAD_AUART1_RX__AUART1_RX + MX28_PAD_AUART1_TX__AUART1_TX + MX28_PAD_AUART1_CTS__AUART1_CTS + MX28_PAD_AUART1_RTS__AUART1_RTS >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; auart1_2pins_a: auart1-2pins@0 { reg = <0>; fsl,pinmux-ids = < - 0x3040 /* MX28_PAD_AUART1_RX__AUART1_RX */ - 0x3050 /* MX28_PAD_AUART1_TX__AUART1_TX */ + MX28_PAD_AUART1_RX__AUART1_RX + MX28_PAD_AUART1_TX__AUART1_TX >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; auart2_2pins_a: auart2-2pins@0 { reg = <0>; fsl,pinmux-ids = < - 0x2101 /* MX28_PAD_SSP2_SCK__AUART2_RX */ - 0x2111 /* MX28_PAD_SSP2_MOSI__AUART2_TX */ + MX28_PAD_SSP2_SCK__AUART2_RX + MX28_PAD_SSP2_MOSI__AUART2_TX >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; auart2_2pins_b: auart2-2pins@1 { reg = <1>; fsl,pinmux-ids = < - 0x3080 /* MX28_PAD_AUART2_RX__AUART2_RX */ - 0x3090 /* MX28_PAD_AUART2_TX__AUART2_TX */ + MX28_PAD_AUART2_RX__AUART2_RX + MX28_PAD_AUART2_TX__AUART2_TX >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; auart3_pins_a: auart3@0 { reg = <0>; fsl,pinmux-ids = < - 0x30c0 /* MX28_PAD_AUART3_RX__AUART3_RX */ - 0x30d0 /* MX28_PAD_AUART3_TX__AUART3_TX */ - 0x30e0 /* MX28_PAD_AUART3_CTS__AUART3_CTS */ - 0x30f0 /* MX28_PAD_AUART3_RTS__AUART3_RTS */ + MX28_PAD_AUART3_RX__AUART3_RX + MX28_PAD_AUART3_TX__AUART3_TX + MX28_PAD_AUART3_CTS__AUART3_CTS + MX28_PAD_AUART3_RTS__AUART3_RTS >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; auart3_2pins_a: auart3-2pins@0 { reg = <0>; fsl,pinmux-ids = < - 0x2121 /* MX28_PAD_SSP2_MISO__AUART3_RX */ - 0x2131 /* MX28_PAD_SSP2_SS0__AUART3_TX */ + MX28_PAD_SSP2_MISO__AUART3_RX + MX28_PAD_SSP2_SS0__AUART3_TX >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; auart3_2pins_b: auart3-2pins@1 { reg = <1>; fsl,pinmux-ids = < - 0x30c0 /* MX28_PAD_AUART3_RX__AUART3_RX */ - 0x30d0 /* MX28_PAD_AUART3_TX__AUART3_TX */ + MX28_PAD_AUART3_RX__AUART3_RX + MX28_PAD_AUART3_TX__AUART3_TX >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; auart4_2pins_a: auart4@0 { reg = <0>; fsl,pinmux-ids = < - 0x2181 /* MX28_PAD_SSP3_SCK__AUART4_TX */ - 0x2191 /* MX28_PAD_SSP3_MOSI__AUART4_RX */ + MX28_PAD_SSP3_SCK__AUART4_TX + MX28_PAD_SSP3_MOSI__AUART4_RX >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; mac0_pins_a: mac0@0 { reg = <0>; fsl,pinmux-ids = < - 0x4000 /* MX28_PAD_ENET0_MDC__ENET0_MDC */ - 0x4010 /* MX28_PAD_ENET0_MDIO__ENET0_MDIO */ - 0x4020 /* MX28_PAD_ENET0_RX_EN__ENET0_RX_EN */ - 0x4030 /* MX28_PAD_ENET0_RXD0__ENET0_RXD0 */ - 0x4040 /* MX28_PAD_ENET0_RXD1__ENET0_RXD1 */ - 0x4060 /* MX28_PAD_ENET0_TX_EN__ENET0_TX_EN */ - 0x4070 /* MX28_PAD_ENET0_TXD0__ENET0_TXD0 */ - 0x4080 /* MX28_PAD_ENET0_TXD1__ENET0_TXD1 */ - 0x4100 /* MX28_PAD_ENET_CLK__CLKCTRL_ENET */ + MX28_PAD_ENET0_MDC__ENET0_MDC + MX28_PAD_ENET0_MDIO__ENET0_MDIO + MX28_PAD_ENET0_RX_EN__ENET0_RX_EN + MX28_PAD_ENET0_RXD0__ENET0_RXD0 + MX28_PAD_ENET0_RXD1__ENET0_RXD1 + MX28_PAD_ENET0_TX_EN__ENET0_TX_EN + MX28_PAD_ENET0_TXD0__ENET0_TXD0 + MX28_PAD_ENET0_TXD1__ENET0_TXD1 + MX28_PAD_ENET_CLK__CLKCTRL_ENET >; - fsl,drive-strength = <1>; - fsl,voltage = <1>; - fsl,pull-up = <1>; + fsl,drive-strength = <MXS_DRIVE_8mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_ENABLE>; }; mac1_pins_a: mac1@0 { reg = <0>; fsl,pinmux-ids = < - 0x40f1 /* MX28_PAD_ENET0_CRS__ENET1_RX_EN */ - 0x4091 /* MX28_PAD_ENET0_RXD2__ENET1_RXD0 */ - 0x40a1 /* MX28_PAD_ENET0_RXD3__ENET1_RXD1 */ - 0x40e1 /* MX28_PAD_ENET0_COL__ENET1_TX_EN */ - 0x40b1 /* MX28_PAD_ENET0_TXD2__ENET1_TXD0 */ - 0x40c1 /* MX28_PAD_ENET0_TXD3__ENET1_TXD1 */ + MX28_PAD_ENET0_CRS__ENET1_RX_EN + MX28_PAD_ENET0_RXD2__ENET1_RXD0 + MX28_PAD_ENET0_RXD3__ENET1_RXD1 + MX28_PAD_ENET0_COL__ENET1_TX_EN + MX28_PAD_ENET0_TXD2__ENET1_TXD0 + MX28_PAD_ENET0_TXD3__ENET1_TXD1 >; - fsl,drive-strength = <1>; - fsl,voltage = <1>; - fsl,pull-up = <1>; + fsl,drive-strength = <MXS_DRIVE_8mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_ENABLE>; }; mmc0_8bit_pins_a: mmc0-8bit@0 { reg = <0>; fsl,pinmux-ids = < - 0x2000 /* MX28_PAD_SSP0_DATA0__SSP0_D0 */ - 0x2010 /* MX28_PAD_SSP0_DATA1__SSP0_D1 */ - 0x2020 /* MX28_PAD_SSP0_DATA2__SSP0_D2 */ - 0x2030 /* MX28_PAD_SSP0_DATA3__SSP0_D3 */ - 0x2040 /* MX28_PAD_SSP0_DATA4__SSP0_D4 */ - 0x2050 /* MX28_PAD_SSP0_DATA5__SSP0_D5 */ - 0x2060 /* MX28_PAD_SSP0_DATA6__SSP0_D6 */ - 0x2070 /* MX28_PAD_SSP0_DATA7__SSP0_D7 */ - 0x2080 /* MX28_PAD_SSP0_CMD__SSP0_CMD */ - 0x2090 /* MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT */ - 0x20a0 /* MX28_PAD_SSP0_SCK__SSP0_SCK */ + MX28_PAD_SSP0_DATA0__SSP0_D0 + MX28_PAD_SSP0_DATA1__SSP0_D1 + MX28_PAD_SSP0_DATA2__SSP0_D2 + MX28_PAD_SSP0_DATA3__SSP0_D3 + MX28_PAD_SSP0_DATA4__SSP0_D4 + MX28_PAD_SSP0_DATA5__SSP0_D5 + MX28_PAD_SSP0_DATA6__SSP0_D6 + MX28_PAD_SSP0_DATA7__SSP0_D7 + MX28_PAD_SSP0_CMD__SSP0_CMD + MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT + MX28_PAD_SSP0_SCK__SSP0_SCK >; - fsl,drive-strength = <1>; - fsl,voltage = <1>; - fsl,pull-up = <1>; + fsl,drive-strength = <MXS_DRIVE_8mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_ENABLE>; }; mmc0_4bit_pins_a: mmc0-4bit@0 { reg = <0>; fsl,pinmux-ids = < - 0x2000 /* MX28_PAD_SSP0_DATA0__SSP0_D0 */ - 0x2010 /* MX28_PAD_SSP0_DATA1__SSP0_D1 */ - 0x2020 /* MX28_PAD_SSP0_DATA2__SSP0_D2 */ - 0x2030 /* MX28_PAD_SSP0_DATA3__SSP0_D3 */ - 0x2080 /* MX28_PAD_SSP0_CMD__SSP0_CMD */ - 0x2090 /* MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT */ - 0x20a0 /* MX28_PAD_SSP0_SCK__SSP0_SCK */ + MX28_PAD_SSP0_DATA0__SSP0_D0 + MX28_PAD_SSP0_DATA1__SSP0_D1 + MX28_PAD_SSP0_DATA2__SSP0_D2 + MX28_PAD_SSP0_DATA3__SSP0_D3 + MX28_PAD_SSP0_CMD__SSP0_CMD + MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT + MX28_PAD_SSP0_SCK__SSP0_SCK >; - fsl,drive-strength = <1>; - fsl,voltage = <1>; - fsl,pull-up = <1>; + fsl,drive-strength = <MXS_DRIVE_8mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_ENABLE>; }; mmc0_cd_cfg: mmc0-cd-cfg { fsl,pinmux-ids = < - 0x2090 /* MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT */ + MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT >; - fsl,pull-up = <0>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; mmc0_sck_cfg: mmc0-sck-cfg { fsl,pinmux-ids = < - 0x20a0 /* MX28_PAD_SSP0_SCK__SSP0_SCK */ + MX28_PAD_SSP0_SCK__SSP0_SCK >; - fsl,drive-strength = <2>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_12mA>; + fsl,pull-up = <MXS_PULL_DISABLE>; + }; + + mmc2_4bit_pins_a: mmc2-4bit@0 { + reg = <0>; + fsl,pinmux-ids = < + MX28_PAD_SSP0_DATA4__SSP2_D0 + MX28_PAD_SSP1_SCK__SSP2_D1 + MX28_PAD_SSP1_CMD__SSP2_D2 + MX28_PAD_SSP0_DATA5__SSP2_D3 + MX28_PAD_SSP0_DATA6__SSP2_CMD + MX28_PAD_AUART1_RX__SSP2_CARD_DETECT + MX28_PAD_SSP0_DATA7__SSP2_SCK + >; + fsl,drive-strength = <MXS_DRIVE_8mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_ENABLE>; + }; + + mmc2_cd_cfg: mmc2-cd-cfg { + fsl,pinmux-ids = < + MX28_PAD_AUART1_RX__SSP2_CARD_DETECT + >; + fsl,pull-up = <MXS_PULL_DISABLE>; + }; + + mmc2_sck_cfg: mmc2-sck-cfg { + fsl,pinmux-ids = < + MX28_PAD_SSP0_DATA7__SSP2_SCK + >; + fsl,drive-strength = <MXS_DRIVE_12mA>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; i2c0_pins_a: i2c0@0 { reg = <0>; fsl,pinmux-ids = < - 0x3180 /* MX28_PAD_I2C0_SCL__I2C0_SCL */ - 0x3190 /* MX28_PAD_I2C0_SDA__I2C0_SDA */ + MX28_PAD_I2C0_SCL__I2C0_SCL + MX28_PAD_I2C0_SDA__I2C0_SDA >; - fsl,drive-strength = <1>; - fsl,voltage = <1>; - fsl,pull-up = <1>; + fsl,drive-strength = <MXS_DRIVE_8mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_ENABLE>; }; i2c0_pins_b: i2c0@1 { reg = <1>; fsl,pinmux-ids = < - 0x3001 /* MX28_PAD_AUART0_RX__I2C0_SCL */ - 0x3011 /* MX28_PAD_AUART0_TX__I2C0_SDA */ + MX28_PAD_AUART0_RX__I2C0_SCL + MX28_PAD_AUART0_TX__I2C0_SDA >; - fsl,drive-strength = <1>; - fsl,voltage = <1>; - fsl,pull-up = <1>; + fsl,drive-strength = <MXS_DRIVE_8mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_ENABLE>; }; i2c1_pins_a: i2c1@0 { reg = <0>; fsl,pinmux-ids = < - 0x3101 /* MX28_PAD_PWM0__I2C1_SCL */ - 0x3111 /* MX28_PAD_PWM1__I2C1_SDA */ + MX28_PAD_PWM0__I2C1_SCL + MX28_PAD_PWM1__I2C1_SDA >; - fsl,drive-strength = <1>; - fsl,voltage = <1>; - fsl,pull-up = <1>; + fsl,drive-strength = <MXS_DRIVE_8mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_ENABLE>; }; saif0_pins_a: saif0@0 { reg = <0>; fsl,pinmux-ids = < - 0x3140 /* MX28_PAD_SAIF0_MCLK__SAIF0_MCLK */ - 0x3150 /* MX28_PAD_SAIF0_LRCLK__SAIF0_LRCLK */ - 0x3160 /* MX28_PAD_SAIF0_BITCLK__SAIF0_BITCLK */ - 0x3170 /* MX28_PAD_SAIF0_SDATA0__SAIF0_SDATA0 */ + MX28_PAD_SAIF0_MCLK__SAIF0_MCLK + MX28_PAD_SAIF0_LRCLK__SAIF0_LRCLK + MX28_PAD_SAIF0_BITCLK__SAIF0_BITCLK + MX28_PAD_SAIF0_SDATA0__SAIF0_SDATA0 >; - fsl,drive-strength = <2>; - fsl,voltage = <1>; - fsl,pull-up = <1>; + fsl,drive-strength = <MXS_DRIVE_12mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_ENABLE>; }; saif0_pins_b: saif0@1 { reg = <1>; fsl,pinmux-ids = < - 0x3150 /* MX28_PAD_SAIF0_LRCLK__SAIF0_LRCLK */ - 0x3160 /* MX28_PAD_SAIF0_BITCLK__SAIF0_BITCLK */ - 0x3170 /* MX28_PAD_SAIF0_SDATA0__SAIF0_SDATA0 */ + MX28_PAD_SAIF0_LRCLK__SAIF0_LRCLK + MX28_PAD_SAIF0_BITCLK__SAIF0_BITCLK + MX28_PAD_SAIF0_SDATA0__SAIF0_SDATA0 >; - fsl,drive-strength = <2>; - fsl,voltage = <1>; - fsl,pull-up = <1>; + fsl,drive-strength = <MXS_DRIVE_12mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_ENABLE>; }; saif1_pins_a: saif1@0 { reg = <0>; fsl,pinmux-ids = < - 0x31a0 /* MX28_PAD_SAIF1_SDATA0__SAIF1_SDATA0 */ + MX28_PAD_SAIF1_SDATA0__SAIF1_SDATA0 >; - fsl,drive-strength = <2>; - fsl,voltage = <1>; - fsl,pull-up = <1>; + fsl,drive-strength = <MXS_DRIVE_12mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_ENABLE>; }; pwm0_pins_a: pwm0@0 { reg = <0>; fsl,pinmux-ids = < - 0x3100 /* MX28_PAD_PWM0__PWM_0 */ + MX28_PAD_PWM0__PWM_0 >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; pwm2_pins_a: pwm2@0 { reg = <0>; fsl,pinmux-ids = < - 0x3120 /* MX28_PAD_PWM2__PWM_2 */ + MX28_PAD_PWM2__PWM_2 >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; pwm3_pins_a: pwm3@0 { reg = <0>; fsl,pinmux-ids = < - 0x31c0 /* MX28_PAD_PWM3__PWM_3 */ + MX28_PAD_PWM3__PWM_3 >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; pwm3_pins_b: pwm3@1 { reg = <1>; fsl,pinmux-ids = < - 0x3141 /* MX28_PAD_SAIF0_MCLK__PWM3 */ + MX28_PAD_SAIF0_MCLK__PWM_3 >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; pwm4_pins_a: pwm4@0 { reg = <0>; fsl,pinmux-ids = < - 0x31d0 /* MX28_PAD_PWM4__PWM_4 */ + MX28_PAD_PWM4__PWM_4 >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; lcdif_24bit_pins_a: lcdif-24bit@0 { reg = <0>; fsl,pinmux-ids = < - 0x1000 /* MX28_PAD_LCD_D00__LCD_D0 */ - 0x1010 /* MX28_PAD_LCD_D01__LCD_D1 */ - 0x1020 /* MX28_PAD_LCD_D02__LCD_D2 */ - 0x1030 /* MX28_PAD_LCD_D03__LCD_D3 */ - 0x1040 /* MX28_PAD_LCD_D04__LCD_D4 */ - 0x1050 /* MX28_PAD_LCD_D05__LCD_D5 */ - 0x1060 /* MX28_PAD_LCD_D06__LCD_D6 */ - 0x1070 /* MX28_PAD_LCD_D07__LCD_D7 */ - 0x1080 /* MX28_PAD_LCD_D08__LCD_D8 */ - 0x1090 /* MX28_PAD_LCD_D09__LCD_D9 */ - 0x10a0 /* MX28_PAD_LCD_D10__LCD_D10 */ - 0x10b0 /* MX28_PAD_LCD_D11__LCD_D11 */ - 0x10c0 /* MX28_PAD_LCD_D12__LCD_D12 */ - 0x10d0 /* MX28_PAD_LCD_D13__LCD_D13 */ - 0x10e0 /* MX28_PAD_LCD_D14__LCD_D14 */ - 0x10f0 /* MX28_PAD_LCD_D15__LCD_D15 */ - 0x1100 /* MX28_PAD_LCD_D16__LCD_D16 */ - 0x1110 /* MX28_PAD_LCD_D17__LCD_D17 */ - 0x1120 /* MX28_PAD_LCD_D18__LCD_D18 */ - 0x1130 /* MX28_PAD_LCD_D19__LCD_D19 */ - 0x1140 /* MX28_PAD_LCD_D20__LCD_D20 */ - 0x1150 /* MX28_PAD_LCD_D21__LCD_D21 */ - 0x1160 /* MX28_PAD_LCD_D22__LCD_D22 */ - 0x1170 /* MX28_PAD_LCD_D23__LCD_D23 */ + MX28_PAD_LCD_D00__LCD_D0 + MX28_PAD_LCD_D01__LCD_D1 + MX28_PAD_LCD_D02__LCD_D2 + MX28_PAD_LCD_D03__LCD_D3 + MX28_PAD_LCD_D04__LCD_D4 + MX28_PAD_LCD_D05__LCD_D5 + MX28_PAD_LCD_D06__LCD_D6 + MX28_PAD_LCD_D07__LCD_D7 + MX28_PAD_LCD_D08__LCD_D8 + MX28_PAD_LCD_D09__LCD_D9 + MX28_PAD_LCD_D10__LCD_D10 + MX28_PAD_LCD_D11__LCD_D11 + MX28_PAD_LCD_D12__LCD_D12 + MX28_PAD_LCD_D13__LCD_D13 + MX28_PAD_LCD_D14__LCD_D14 + MX28_PAD_LCD_D15__LCD_D15 + MX28_PAD_LCD_D16__LCD_D16 + MX28_PAD_LCD_D17__LCD_D17 + MX28_PAD_LCD_D18__LCD_D18 + MX28_PAD_LCD_D19__LCD_D19 + MX28_PAD_LCD_D20__LCD_D20 + MX28_PAD_LCD_D21__LCD_D21 + MX28_PAD_LCD_D22__LCD_D22 + MX28_PAD_LCD_D23__LCD_D23 >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; lcdif_16bit_pins_a: lcdif-16bit@0 { reg = <0>; fsl,pinmux-ids = < - 0x1000 /* MX28_PAD_LCD_D00__LCD_D0 */ - 0x1010 /* MX28_PAD_LCD_D01__LCD_D1 */ - 0x1020 /* MX28_PAD_LCD_D02__LCD_D2 */ - 0x1030 /* MX28_PAD_LCD_D03__LCD_D3 */ - 0x1040 /* MX28_PAD_LCD_D04__LCD_D4 */ - 0x1050 /* MX28_PAD_LCD_D05__LCD_D5 */ - 0x1060 /* MX28_PAD_LCD_D06__LCD_D6 */ - 0x1070 /* MX28_PAD_LCD_D07__LCD_D7 */ - 0x1080 /* MX28_PAD_LCD_D08__LCD_D8 */ - 0x1090 /* MX28_PAD_LCD_D09__LCD_D9 */ - 0x10a0 /* MX28_PAD_LCD_D10__LCD_D10 */ - 0x10b0 /* MX28_PAD_LCD_D11__LCD_D11 */ - 0x10c0 /* MX28_PAD_LCD_D12__LCD_D12 */ - 0x10d0 /* MX28_PAD_LCD_D13__LCD_D13 */ - 0x10e0 /* MX28_PAD_LCD_D14__LCD_D14 */ - 0x10f0 /* MX28_PAD_LCD_D15__LCD_D15 */ + MX28_PAD_LCD_D00__LCD_D0 + MX28_PAD_LCD_D01__LCD_D1 + MX28_PAD_LCD_D02__LCD_D2 + MX28_PAD_LCD_D03__LCD_D3 + MX28_PAD_LCD_D04__LCD_D4 + MX28_PAD_LCD_D05__LCD_D5 + MX28_PAD_LCD_D06__LCD_D6 + MX28_PAD_LCD_D07__LCD_D7 + MX28_PAD_LCD_D08__LCD_D8 + MX28_PAD_LCD_D09__LCD_D9 + MX28_PAD_LCD_D10__LCD_D10 + MX28_PAD_LCD_D11__LCD_D11 + MX28_PAD_LCD_D12__LCD_D12 + MX28_PAD_LCD_D13__LCD_D13 + MX28_PAD_LCD_D14__LCD_D14 + MX28_PAD_LCD_D15__LCD_D15 >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; lcdif_sync_pins_a: lcdif-sync@0 { reg = <0>; fsl,pinmux-ids = < - 0x11a1 /* MX28_PAD_LCD_RS__LCD_DOTCLK */ - 0x11b1 /* MX28_PAD_LCD_CS__LCD_ENABLE */ - 0x1181 /* MX28_PAD_LCD_RD_E__LCD_VSYNC */ - 0x1191 /* MX28_PAD_LCD_WR_RWN__LCD_HSYNC */ + MX28_PAD_LCD_RS__LCD_DOTCLK + MX28_PAD_LCD_CS__LCD_ENABLE + MX28_PAD_LCD_RD_E__LCD_VSYNC + MX28_PAD_LCD_WR_RWN__LCD_HSYNC >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; can0_pins_a: can0@0 { reg = <0>; fsl,pinmux-ids = < - 0x0161 /* MX28_PAD_GPMI_RDY2__CAN0_TX */ - 0x0171 /* MX28_PAD_GPMI_RDY3__CAN0_RX */ + MX28_PAD_GPMI_RDY2__CAN0_TX + MX28_PAD_GPMI_RDY3__CAN0_RX >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; can1_pins_a: can1@0 { reg = <0>; fsl,pinmux-ids = < - 0x0121 /* MX28_PAD_GPMI_CE2N__CAN1_TX */ - 0x0131 /* MX28_PAD_GPMI_CE3N__CAN1_RX */ + MX28_PAD_GPMI_CE2N__CAN1_TX + MX28_PAD_GPMI_CE3N__CAN1_RX >; - fsl,drive-strength = <0>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; spi2_pins_a: spi2@0 { reg = <0>; fsl,pinmux-ids = < - 0x2100 /* MX28_PAD_SSP2_SCK__SSP2_SCK */ - 0x2110 /* MX28_PAD_SSP2_MOSI__SSP2_CMD */ - 0x2120 /* MX28_PAD_SSP2_MISO__SSP2_D0 */ - 0x2130 /* MX28_PAD_SSP2_SS0__SSP2_D3 */ + MX28_PAD_SSP2_SCK__SSP2_SCK + MX28_PAD_SSP2_MOSI__SSP2_CMD + MX28_PAD_SSP2_MISO__SSP2_D0 + MX28_PAD_SSP2_SS0__SSP2_D3 >; - fsl,drive-strength = <1>; - fsl,voltage = <1>; - fsl,pull-up = <1>; + fsl,drive-strength = <MXS_DRIVE_8mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_ENABLE>; }; spi3_pins_a: spi3@0 { reg = <0>; fsl,pinmux-ids = < - 0x3082 /* MX28_PAD_AUART2_RX__SSP3_D4 */ - 0x3092 /* MX28_PAD_AUART2_TX__SSP3_D5 */ - 0x2180 /* MX28_PAD_SSP3_SCK__SSP3_SCK */ - 0x2190 /* MX28_PAD_SSP3_MOSI__SSP3_CMD */ - 0x21A0 /* MX28_PAD_SSP3_MISO__SSP3_D0 */ - 0x21B0 /* MX28_PAD_SSP3_SS0__SSP3_D3 */ + MX28_PAD_AUART2_RX__SSP3_D4 + MX28_PAD_AUART2_TX__SSP3_D5 + MX28_PAD_SSP3_SCK__SSP3_SCK + MX28_PAD_SSP3_MOSI__SSP3_CMD + MX28_PAD_SSP3_MISO__SSP3_D0 + MX28_PAD_SSP3_SS0__SSP3_D3 >; - fsl,drive-strength = <1>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_8mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; usbphy0_pins_a: usbphy0@0 { reg = <0>; fsl,pinmux-ids = < - 0x2152 /* MX28_PAD_SSP2_SS2__USB0_OVERCURRENT */ + MX28_PAD_SSP2_SS2__USB0_OVERCURRENT >; - fsl,drive-strength = <2>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_12mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; usbphy0_pins_b: usbphy0@1 { reg = <1>; fsl,pinmux-ids = < - 0x3061 /* MX28_PAD_AUART1_CTS__USB0_OVERCURRENT */ + MX28_PAD_AUART1_CTS__USB0_OVERCURRENT >; - fsl,drive-strength = <2>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_12mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; }; usbphy1_pins_a: usbphy1@0 { reg = <0>; fsl,pinmux-ids = < - 0x2142 /* MX28_PAD_SSP2_SS1__USB1_OVERCURRENT */ + MX28_PAD_SSP2_SS1__USB1_OVERCURRENT + >; + fsl,drive-strength = <MXS_DRIVE_12mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; + }; + + usb0_id_pins_a: usb0id@0 { + reg = <0>; + fsl,pinmux-ids = < + MX28_PAD_AUART1_RTS__USB0_ID >; - fsl,drive-strength = <2>; - fsl,voltage = <1>; - fsl,pull-up = <0>; + fsl,drive-strength = <MXS_DRIVE_12mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_ENABLE>; }; }; @@ -902,6 +944,7 @@ interrupts = <10 14 15 16 17 18 19 20 21 22 23 24 25>; status = "disabled"; + clocks = <&clks 41>; }; spdif: spdif@80054000 { diff --git a/arch/arm/boot/dts/imx51-apf51dev.dts b/arch/arm/boot/dts/imx51-apf51dev.dts index 123fe84e0e8c..5a7f552786a1 100644 --- a/arch/arm/boot/dts/imx51-apf51dev.dts +++ b/arch/arm/boot/dts/imx51-apf51dev.dts @@ -16,6 +16,33 @@ model = "Armadeus Systems APF51Dev docking/development board"; compatible = "armadeus,imx51-apf51dev", "armadeus,imx51-apf51", "fsl,imx51"; + display@di1 { + compatible = "fsl,imx-parallel-display"; + crtcs = <&ipu 0>; + interface-pix-fmt = "bgr666"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ipu_disp1_1>; + + display-timings { + lw700 { + native-mode; + clock-frequency = <33000033>; + hactive = <800>; + vactive = <480>; + hback-porch = <96>; + hfront-porch = <96>; + vback-porch = <20>; + vfront-porch = <21>; + hsync-len = <64>; + vsync-len = <4>; + hsync-active = <1>; + vsync-active = <1>; + de-active = <1>; + pixelclk-active = <0>; + }; + }; + }; + gpio-keys { compatible = "gpio-keys"; diff --git a/arch/arm/boot/dts/imx51-babbage.dts b/arch/arm/boot/dts/imx51-babbage.dts index 1d337d99ecd5..be1407cf5abd 100644 --- a/arch/arm/boot/dts/imx51-babbage.dts +++ b/arch/arm/boot/dts/imx51-babbage.dts @@ -27,6 +27,20 @@ interface-pix-fmt = "rgb24"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ipu_disp1_1>; + display-timings { + native-mode = <&timing0>; + timing0: dvi { + clock-frequency = <65000000>; + hactive = <1024>; + vactive = <768>; + hback-porch = <220>; + hfront-porch = <40>; + vback-porch = <21>; + vfront-porch = <7>; + hsync-len = <60>; + vsync-len = <10>; + }; + }; }; display@di1 { @@ -35,6 +49,25 @@ interface-pix-fmt = "rgb565"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ipu_disp2_1>; + status = "disabled"; + display-timings { + native-mode = <&timing1>; + timing1: claawvga { + clock-frequency = <27000000>; + hactive = <800>; + vactive = <480>; + hback-porch = <40>; + hfront-porch = <60>; + vback-porch = <10>; + vfront-porch = <10>; + hsync-len = <20>; + vsync-len = <10>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <1>; + pixelclk-active = <0>; + }; + }; }; gpio-keys { @@ -95,7 +128,7 @@ &uart3 { pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart3_1>; + pinctrl-0 = <&pinctrl_uart3_1 &pinctrl_uart3_rtscts_1>; fsl,uart-has-rtscts; status = "okay"; }; @@ -252,7 +285,7 @@ &uart1 { pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart1_1>; + pinctrl-0 = <&pinctrl_uart1_1 &pinctrl_uart1_rtscts_1>; fsl,uart-has-rtscts; status = "okay"; }; diff --git a/arch/arm/boot/dts/imx51.dtsi b/arch/arm/boot/dts/imx51.dtsi index 54cee6517902..4bcdd3ad15e5 100644 --- a/arch/arm/boot/dts/imx51.dtsi +++ b/arch/arm/boot/dts/imx51.dtsi @@ -86,6 +86,11 @@ interrupt-parent = <&tzic>; ranges; + iram: iram@1ffe0000 { + compatible = "mmio-sram"; + reg = <0x1ffe0000 0x20000>; + }; + ipu: ipu@40000000 { #crtc-cells = <1>; compatible = "fsl,imx51-ipu"; @@ -185,7 +190,7 @@ usbphy0: usbphy@0 { compatible = "usb-nop-xceiv"; - clocks = <&clks 124>; + clocks = <&clks 75>; clock-names = "main_clk"; status = "okay"; }; @@ -374,6 +379,14 @@ clocks = <&clks 107>; }; + owire: owire@83fa4000 { + compatible = "fsl,imx51-owire", "fsl,imx21-owire"; + reg = <0x83fa4000 0x4000>; + interrupts = <88>; + clocks = <&clks 159>; + status = "disabled"; + }; + ecspi2: ecspi@83fac000 { #address-cells = <1>; #size-cells = <0>; @@ -747,6 +760,11 @@ fsl,pins = < MX51_PAD_UART1_RXD__UART1_RXD 0x1c5 MX51_PAD_UART1_TXD__UART1_TXD 0x1c5 + >; + }; + + pinctrl_uart1_rtscts_1: uart1rtscts-1 { + fsl,pins = < MX51_PAD_UART1_RTS__UART1_RTS 0x1c5 MX51_PAD_UART1_CTS__UART1_CTS 0x1c5 >; @@ -767,6 +785,11 @@ fsl,pins = < MX51_PAD_EIM_D25__UART3_RXD 0x1c5 MX51_PAD_EIM_D26__UART3_TXD 0x1c5 + >; + }; + + pinctrl_uart3_rtscts_1: uart3rtscts-1 { + fsl,pins = < MX51_PAD_EIM_D27__UART3_RTS 0x1c5 MX51_PAD_EIM_D24__UART3_CTS 0x1c5 >; diff --git a/arch/arm/boot/dts/imx53-qsb.dts b/arch/arm/boot/dts/imx53-qsb.dts index e97ddae09d74..91a5935a4aac 100644 --- a/arch/arm/boot/dts/imx53-qsb.dts +++ b/arch/arm/boot/dts/imx53-qsb.dts @@ -55,19 +55,20 @@ label = "Power Button"; gpios = <&gpio1 8 0>; linux,code = <116>; /* KEY_POWER */ - gpio-key,wakeup; }; volume-up { label = "Volume Up"; gpios = <&gpio2 14 0>; linux,code = <115>; /* KEY_VOLUMEUP */ + gpio-key,wakeup; }; volume-down { label = "Volume Down"; gpios = <&gpio2 15 0>; linux,code = <114>; /* KEY_VOLUMEDOWN */ + gpio-key,wakeup; }; }; @@ -122,7 +123,6 @@ &esdhc1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_esdhc1_1>; - cd-gpios = <&gpio3 13 0>; status = "okay"; }; @@ -136,6 +136,7 @@ pinctrl-0 = <&pinctrl_esdhc3_1>; cd-gpios = <&gpio3 11 0>; wp-gpios = <&gpio3 12 0>; + bus-width = <8>; status = "okay"; }; @@ -152,7 +153,6 @@ MX53_PAD_PATA_DATA15__GPIO2_15 0x80000000 MX53_PAD_EIM_DA11__GPIO3_11 0x80000000 MX53_PAD_EIM_DA12__GPIO3_12 0x80000000 - MX53_PAD_EIM_DA13__GPIO3_13 0x80000000 MX53_PAD_PATA_DA_0__GPIO7_6 0x80000000 MX53_PAD_PATA_DA_2__GPIO7_8 0x80000000 MX53_PAD_GPIO_16__GPIO7_11 0x80000000 @@ -318,5 +318,6 @@ }; &usbotg { - status = "okay"; + dr_mode = "peripheral"; + status = "okay"; }; diff --git a/arch/arm/boot/dts/imx6q-pinfunc.h b/arch/arm/boot/dts/imx6q-pinfunc.h index 9bbe82bdee41..97ed0816a6e0 100644 --- a/arch/arm/boot/dts/imx6q-pinfunc.h +++ b/arch/arm/boot/dts/imx6q-pinfunc.h @@ -536,7 +536,7 @@ #define MX6QDL_PAD_ENET_REF_CLK__ESAI_RX_FS 0x1d4 0x4e8 0x85c 0x2 0x0 #define MX6QDL_PAD_ENET_REF_CLK__GPIO1_IO23 0x1d4 0x4e8 0x000 0x5 0x0 #define MX6QDL_PAD_ENET_REF_CLK__SPDIF_SR_CLK 0x1d4 0x4e8 0x000 0x6 0x0 -#define MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID 0x1d8 0x4ec 0x000 0x0 0x0 +#define MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID 0x1d8 0x4ec 0x004 0x0 0xff0d0100 #define MX6QDL_PAD_ENET_RX_ER__ENET_RX_ER 0x1d8 0x4ec 0x000 0x1 0x0 #define MX6QDL_PAD_ENET_RX_ER__ESAI_RX_HF_CLK 0x1d8 0x4ec 0x864 0x2 0x0 #define MX6QDL_PAD_ENET_RX_ER__SPDIF_IN 0x1d8 0x4ec 0x914 0x3 0x1 @@ -654,7 +654,7 @@ #define MX6QDL_PAD_GPIO_1__ESAI_RX_CLK 0x224 0x5f4 0x86c 0x0 0x1 #define MX6QDL_PAD_GPIO_1__WDOG2_B 0x224 0x5f4 0x000 0x1 0x0 #define MX6QDL_PAD_GPIO_1__KEY_ROW5 0x224 0x5f4 0x8f4 0x2 0x0 -#define MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x224 0x5f4 0x000 0x3 0x0 +#define MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x224 0x5f4 0x004 0x3 0xff0d0101 #define MX6QDL_PAD_GPIO_1__PWM2_OUT 0x224 0x5f4 0x000 0x4 0x0 #define MX6QDL_PAD_GPIO_1__GPIO1_IO01 0x224 0x5f4 0x000 0x5 0x0 #define MX6QDL_PAD_GPIO_1__SD1_CD_B 0x224 0x5f4 0x000 0x6 0x0 diff --git a/arch/arm/boot/dts/imx6q-sabrelite.dts b/arch/arm/boot/dts/imx6q-sabrelite.dts index 3530280f5150..f004913f7d80 100644 --- a/arch/arm/boot/dts/imx6q-sabrelite.dts +++ b/arch/arm/boot/dts/imx6q-sabrelite.dts @@ -65,8 +65,10 @@ }; }; -&sata { +&audmux { status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_audmux_1>; }; &ecspi1 { @@ -83,11 +85,29 @@ }; }; -&ssi1 { - fsl,mode = "i2s-slave"; +&fec { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_enet_1>; + phy-mode = "rgmii"; + phy-reset-gpios = <&gpio3 23 0>; status = "okay"; }; +&i2c1 { + status = "okay"; + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1_1>; + + codec: sgtl5000@0a { + compatible = "fsl,sgtl5000"; + reg = <0x0a>; + clocks = <&clks 201>; + VDDA-supply = <®_2p5v>; + VDDIO-supply = <®_3p3v>; + }; +}; + &iomuxc { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_hog>; @@ -103,28 +123,61 @@ MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x80000000 MX6QDL_PAD_SD3_DAT4__GPIO7_IO01 0x1f0b0 MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x80000000 + MX6QDL_PAD_EIM_D23__GPIO3_IO23 0x80000000 >; }; }; }; -&usbotg { - vbus-supply = <®_usb_otg_vbus>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usbotg_1>; - disable-over-current; +&ldb { + status = "okay"; + + lvds-channel@0 { + fsl,data-mapping = "spwg"; + fsl,data-width = <18>; + status = "okay"; + + display-timings { + native-mode = <&timing0>; + timing0: hsd100pxn1 { + clock-frequency = <65000000>; + hactive = <1024>; + vactive = <768>; + hback-porch = <220>; + hfront-porch = <40>; + vback-porch = <21>; + vfront-porch = <7>; + hsync-len = <60>; + vsync-len = <10>; + }; + }; + }; +}; + +&sata { + status = "okay"; +}; + +&ssi1 { + fsl,mode = "i2s-slave"; status = "okay"; }; +&uart2 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart2_1>; +}; + &usbh1 { status = "okay"; }; -&fec { +&usbotg { + vbus-supply = <®_usb_otg_vbus>; pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_enet_1>; - phy-mode = "rgmii"; - phy-reset-gpios = <&gpio3 23 0>; + pinctrl-0 = <&pinctrl_usbotg_1>; + disable-over-current; status = "okay"; }; @@ -145,30 +198,3 @@ vmmc-supply = <®_3p3v>; status = "okay"; }; - -&audmux { - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_audmux_1>; -}; - -&uart2 { - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart2_1>; -}; - -&i2c1 { - status = "okay"; - clock-frequency = <100000>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_i2c1_1>; - - codec: sgtl5000@0a { - compatible = "fsl,sgtl5000"; - reg = <0x0a>; - clocks = <&clks 201>; - VDDA-supply = <®_2p5v>; - VDDIO-supply = <®_3p3v>; - }; -}; diff --git a/arch/arm/boot/dts/imx6q-udoo.dts b/arch/arm/boot/dts/imx6q-udoo.dts new file mode 100644 index 000000000000..6e1ccdc019a7 --- /dev/null +++ b/arch/arm/boot/dts/imx6q-udoo.dts @@ -0,0 +1,39 @@ +/* + * Copyright 2013 Freescale Semiconductor, Inc. + * + * Author: Fabio Estevam <fabio.estevam@freescale.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 + * published by the Free Software Foundation. + * + */ + +/dts-v1/; +#include "imx6q.dtsi" + +/ { + model = "Udoo i.MX6 Quad Board"; + compatible = "udoo,imx6q-udoo", "fsl,imx6q"; + + memory { + reg = <0x10000000 0x40000000>; + }; +}; + +&sata { + status = "okay"; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart2_1>; + status = "okay"; +}; + +&usdhc3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc3_2>; + non-removable; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi b/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi index 1cbbc5160d27..ff6f1e8f2dd9 100644 --- a/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi +++ b/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi @@ -54,6 +54,7 @@ fsl,pins = < MX6QDL_PAD_NANDF_CS2__GPIO6_IO15 0x80000000 MX6QDL_PAD_SD2_DAT2__GPIO1_IO13 0x80000000 + MX6QDL_PAD_GPIO_18__SD3_VSELECT 0x17059 >; }; }; @@ -74,8 +75,10 @@ }; &usdhc3 { - pinctrl-names = "default"; + pinctrl-names = "default", "state_100mhz", "state_200mhz"; pinctrl-0 = <&pinctrl_usdhc3_1>; + pinctrl-1 = <&pinctrl_usdhc3_1_100mhz>; + pinctrl-2 = <&pinctrl_usdhc3_1_200mhz>; cd-gpios = <&gpio6 15 0>; wp-gpios = <&gpio1 13 0>; status = "okay"; diff --git a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi index 39eafc222a2e..e75e11b36dff 100644 --- a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi +++ b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi @@ -80,6 +80,14 @@ mux-int-port = <2>; mux-ext-port = <3>; }; + + backlight { + compatible = "pwm-backlight"; + pwms = <&pwm1 0 5000000>; + brightness-levels = <0 4 8 16 32 64 128 255>; + default-brightness-level = <7>; + status = "okay"; + }; }; &audmux { @@ -108,6 +116,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_enet_1>; phy-mode = "rgmii"; + phy-reset-gpios = <&gpio1 25 0>; status = "okay"; }; @@ -172,6 +181,7 @@ MX6QDL_PAD_NANDF_CLE__GPIO6_IO07 0x80000000 MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x80000000 MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x80000000 + MX6QDL_PAD_ENET_CRS_DV__GPIO1_IO25 0x80000000 >; }; }; @@ -202,6 +212,12 @@ }; }; +&pwm1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm0_1>; + status = "okay"; +}; + &ssi2 { fsl,mode = "i2s-slave"; status = "okay"; @@ -229,6 +245,7 @@ &usdhc2 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usdhc2_1>; + bus-width = <8>; cd-gpios = <&gpio2 2 0>; wp-gpios = <&gpio2 3 0>; status = "okay"; @@ -237,6 +254,7 @@ &usdhc3 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usdhc3_1>; + bus-width = <8>; cd-gpios = <&gpio2 0 0>; wp-gpios = <&gpio2 1 0>; status = "okay"; diff --git a/arch/arm/boot/dts/imx6qdl-wandboard.dtsi b/arch/arm/boot/dts/imx6qdl-wandboard.dtsi index a55113e65bcb..35f547929167 100644 --- a/arch/arm/boot/dts/imx6qdl-wandboard.dtsi +++ b/arch/arm/boot/dts/imx6qdl-wandboard.dtsi @@ -43,6 +43,13 @@ mux-int-port = <1>; mux-ext-port = <3>; }; + + sound-spdif { + compatible = "fsl,imx-audio-spdif"; + model = "imx-spdif"; + spdif-controller = <&spdif>; + spdif-out; + }; }; &audmux { @@ -81,6 +88,7 @@ MX6QDL_PAD_ENET_RXD1__GPIO1_IO26 0x80000000 /* WL_REG_ON */ MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x80000000 /* WL_HOST_WAKE */ MX6QDL_PAD_ENET_TXD0__GPIO1_IO30 0x80000000 /* WL_WAKE */ + MX6QDL_PAD_EIM_D29__GPIO3_IO29 0x80000000 >; }; }; @@ -90,6 +98,13 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_enet_1>; phy-mode = "rgmii"; + phy-reset-gpios = <&gpio3 29 0>; + status = "okay"; +}; + +&spdif { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spdif_3>; status = "okay"; }; @@ -115,6 +130,14 @@ status = "okay"; }; +&usbotg { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbotg_1>; + disable-over-current; + dr_mode = "peripheral"; + status = "okay"; +}; + &usdhc1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usdhc1_2>; diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi index ccd55c2fdb67..59154dc15fe4 100644 --- a/arch/arm/boot/dts/imx6qdl.dtsi +++ b/arch/arm/boot/dts/imx6qdl.dtsi @@ -116,6 +116,22 @@ arm,data-latency = <4 2 3>; }; + pcie: pcie@0x01000000 { + compatible = "fsl,imx6q-pcie", "snps,dw-pcie"; + reg = <0x01ffc000 0x4000>; /* DBI */ + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + ranges = <0x00000800 0 0x01f00000 0x01f00000 0 0x00080000 /* configuration space */ + 0x81000000 0 0 0x01f80000 0 0x00010000 /* downstream I/O */ + 0x82000000 0 0x01000000 0x01000000 0 0x00f00000>; /* non-prefetchable memory */ + num-lanes = <1>; + interrupts = <0 123 0x04>; + clocks = <&clks 189>, <&clks 187>, <&clks 206>, <&clks 144>; + clock-names = "pcie_ref_125m", "sata_ref_100m", "lvds_gate", "pcie_axi"; + status = "disabled"; + }; + pmu { compatible = "arm,cortex-a9-pmu"; interrupts = <0 94 0x04>; @@ -136,8 +152,23 @@ ranges; spdif: spdif@02004000 { + compatible = "fsl,imx35-spdif"; reg = <0x02004000 0x4000>; interrupts = <0 52 0x04>; + dmas = <&sdma 14 18 0>, + <&sdma 15 18 0>; + dma-names = "rx", "tx"; + clocks = <&clks 197>, <&clks 3>, + <&clks 197>, <&clks 107>, + <&clks 0>, <&clks 118>, + <&clks 62>, <&clks 139>, + <&clks 0>; + clock-names = "core", "rxtx0", + "rxtx1", "rxtx2", + "rxtx3", "rxtx4", + "rxtx5", "rxtx6", + "rxtx7"; + status = "disabled"; }; ecspi1: ecspi@02008000 { @@ -1010,6 +1041,12 @@ MX6QDL_PAD_GPIO_17__SPDIF_OUT 0x1b0b0 >; }; + + pinctrl_spdif_3: spdifgrp-3 { + fsl,pins = < + MX6QDL_PAD_ENET_RXD0__SPDIF_OUT 0x1b0b0 + >; + }; }; uart1 { @@ -1184,6 +1221,36 @@ >; }; + pinctrl_usdhc3_1_100mhz: usdhc3grp-1-100mhz { /* 100Mhz */ + fsl,pins = < + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x170b9 + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x100b9 + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x170b9 + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x170b9 + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x170b9 + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170b9 + MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x170b9 + MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x170b9 + MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x170b9 + MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x170b9 + >; + }; + + pinctrl_usdhc3_1_200mhz: usdhc3grp-1-200mhz { /* 200Mhz */ + fsl,pins = < + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x170f9 + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x100f9 + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x170f9 + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x170f9 + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x170f9 + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170f9 + MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x170f9 + MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x170f9 + MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x170f9 + MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x170f9 + >; + }; + pinctrl_usdhc3_2: usdhc3grp-2 { fsl,pins = < MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059 diff --git a/arch/arm/boot/dts/imx6sl-evk.dts b/arch/arm/boot/dts/imx6sl-evk.dts index 2886a590823d..cc68e19c5163 100644 --- a/arch/arm/boot/dts/imx6sl-evk.dts +++ b/arch/arm/boot/dts/imx6sl-evk.dts @@ -17,6 +17,44 @@ memory { reg = <0x80000000 0x40000000>; }; + + regulators { + compatible = "simple-bus"; + + reg_usb_otg1_vbus: usb_otg1_vbus { + compatible = "regulator-fixed"; + regulator-name = "usb_otg1_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio4 0 0>; + enable-active-high; + }; + + reg_usb_otg2_vbus: usb_otg2_vbus { + compatible = "regulator-fixed"; + regulator-name = "usb_otg2_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio4 2 0>; + enable-active-high; + }; + }; +}; + +&ecspi1 { + fsl,spi-num-chipselects = <1>; + cs-gpios = <&gpio4 11 0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ecspi1_1>; + status = "okay"; + + flash: m25p80@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "st,m25p32"; + spi-max-frequency = <20000000>; + reg = <0>; + }; }; &fec { @@ -38,6 +76,8 @@ MX6SL_PAD_SD2_DAT7__GPIO5_IO00 0x17059 MX6SL_PAD_SD2_DAT6__GPIO4_IO29 0x17059 MX6SL_PAD_REF_CLK_32K__GPIO3_IO22 0x17059 + MX6SL_PAD_KEY_COL4__GPIO4_IO00 0x80000000 + MX6SL_PAD_KEY_COL5__GPIO4_IO02 0x80000000 >; }; }; @@ -49,9 +89,26 @@ status = "okay"; }; -&usdhc1 { +&usbotg1 { + vbus-supply = <®_usb_otg1_vbus>; pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbotg1_1>; + disable-over-current; + status = "okay"; +}; + +&usbotg2 { + vbus-supply = <®_usb_otg2_vbus>; + dr_mode = "host"; + disable-over-current; + status = "okay"; +}; + +&usdhc1 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; pinctrl-0 = <&pinctrl_usdhc1_1>; + pinctrl-1 = <&pinctrl_usdhc1_1_100mhz>; + pinctrl-2 = <&pinctrl_usdhc1_1_200mhz>; bus-width = <8>; cd-gpios = <&gpio4 7 0>; wp-gpios = <&gpio4 6 0>; @@ -59,16 +116,20 @@ }; &usdhc2 { - pinctrl-names = "default"; + pinctrl-names = "default", "state_100mhz", "state_200mhz"; pinctrl-0 = <&pinctrl_usdhc2_1>; + pinctrl-1 = <&pinctrl_usdhc2_1_100mhz>; + pinctrl-2 = <&pinctrl_usdhc2_1_200mhz>; cd-gpios = <&gpio5 0 0>; wp-gpios = <&gpio4 29 0>; status = "okay"; }; &usdhc3 { - pinctrl-names = "default"; + pinctrl-names = "default", "state_100mhz", "state_200mhz"; pinctrl-0 = <&pinctrl_usdhc3_1>; + pinctrl-1 = <&pinctrl_usdhc3_1_100mhz>; + pinctrl-2 = <&pinctrl_usdhc3_1_200mhz>; cd-gpios = <&gpio3 22 0>; status = "okay"; }; diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi index c46651e4d966..28558f1aaf2d 100644 --- a/arch/arm/boot/dts/imx6sl.dtsi +++ b/arch/arm/boot/dts/imx6sl.dtsi @@ -13,16 +13,20 @@ / { aliases { - serial0 = &uart1; - serial1 = &uart2; - serial2 = &uart3; - serial3 = &uart4; - serial4 = &uart5; gpio0 = &gpio1; gpio1 = &gpio2; gpio2 = &gpio3; gpio3 = &gpio4; gpio4 = &gpio5; + serial0 = &uart1; + serial1 = &uart2; + serial2 = &uart3; + serial3 = &uart4; + serial4 = &uart5; + spi0 = &ecspi1; + spi1 = &ecspi2; + spi2 = &ecspi3; + spi3 = &ecspi4; }; cpus { @@ -380,7 +384,9 @@ }; anatop: anatop@020c8000 { - compatible = "fsl,imx6sl-anatop", "syscon", "simple-bus"; + compatible = "fsl,imx6sl-anatop", + "fsl,imx6q-anatop", + "syscon", "simple-bus"; reg = <0x020c8000 0x1000>; interrupts = <0 49 0x04 0 54 0x04 0 127 0x04>; @@ -528,10 +534,26 @@ interrupts = <0 89 0x04>; }; + gpr: iomuxc-gpr@020e0000 { + compatible = "fsl,imx6sl-iomuxc-gpr", + "fsl,imx6q-iomuxc-gpr", "syscon"; + reg = <0x020e0000 0x38>; + }; + iomuxc: iomuxc@020e0000 { compatible = "fsl,imx6sl-iomuxc"; reg = <0x020e0000 0x4000>; + ecspi1 { + pinctrl_ecspi1_1: ecspi1grp-1 { + fsl,pins = < + MX6SL_PAD_ECSPI1_MISO__ECSPI1_MISO 0x100b1 + MX6SL_PAD_ECSPI1_MOSI__ECSPI1_MOSI 0x100b1 + MX6SL_PAD_ECSPI1_SCLK__ECSPI1_SCLK 0x100b1 + >; + }; + }; + fec { pinctrl_fec_1: fecgrp-1 { fsl,pins = < @@ -557,6 +579,64 @@ }; }; + usbotg1 { + pinctrl_usbotg1_1: usbotg1grp-1 { + fsl,pins = < + MX6SL_PAD_EPDC_PWRCOM__USB_OTG1_ID 0x17059 + >; + }; + + pinctrl_usbotg1_2: usbotg1grp-2 { + fsl,pins = < + MX6SL_PAD_FEC_RXD0__USB_OTG1_ID 0x17059 + >; + }; + + pinctrl_usbotg1_3: usbotg1grp-3 { + fsl,pins = < + MX6SL_PAD_LCD_DAT1__USB_OTG1_ID 0x17059 + >; + }; + + pinctrl_usbotg1_4: usbotg1grp-4 { + fsl,pins = < + MX6SL_PAD_REF_CLK_32K__USB_OTG1_ID 0x17059 + >; + }; + + pinctrl_usbotg1_5: usbotg1grp-5 { + fsl,pins = < + MX6SL_PAD_SD3_DAT0__USB_OTG1_ID 0x17059 + >; + }; + }; + + usbotg2 { + pinctrl_usbotg2_1: usbotg2grp-1 { + fsl,pins = < + MX6SL_PAD_ECSPI1_SCLK__USB_OTG2_OC 0x17059 + >; + }; + + pinctrl_usbotg2_2: usbotg2grp-2 { + fsl,pins = < + MX6SL_PAD_ECSPI2_SCLK__USB_OTG2_OC 0x17059 + >; + }; + + pinctrl_usbotg2_3: usbotg2grp-3 { + fsl,pins = < + MX6SL_PAD_KEY_ROW5__USB_OTG2_OC 0x17059 + >; + }; + + pinctrl_usbotg2_4: usbotg2grp-4 { + fsl,pins = < + MX6SL_PAD_SD3_DAT2__USB_OTG2_OC 0x17059 + >; + }; + }; + usdhc1 { pinctrl_usdhc1_1: usdhc1grp-1 { fsl,pins = < @@ -572,6 +652,38 @@ MX6SL_PAD_SD1_DAT7__SD1_DATA7 0x17059 >; }; + + pinctrl_usdhc1_1_100mhz: usdhc1grp-1-100mhz { + fsl,pins = < + MX6SL_PAD_SD1_CMD__SD1_CMD 0x170b9 + MX6SL_PAD_SD1_CLK__SD1_CLK 0x100b9 + MX6SL_PAD_SD1_DAT0__SD1_DATA0 0x170b9 + MX6SL_PAD_SD1_DAT1__SD1_DATA1 0x170b9 + MX6SL_PAD_SD1_DAT2__SD1_DATA2 0x170b9 + MX6SL_PAD_SD1_DAT3__SD1_DATA3 0x170b9 + MX6SL_PAD_SD1_DAT4__SD1_DATA4 0x170b9 + MX6SL_PAD_SD1_DAT5__SD1_DATA5 0x170b9 + MX6SL_PAD_SD1_DAT6__SD1_DATA6 0x170b9 + MX6SL_PAD_SD1_DAT7__SD1_DATA7 0x170b9 + >; + }; + + pinctrl_usdhc1_1_200mhz: usdhc1grp-1-200mhz { + fsl,pins = < + MX6SL_PAD_SD1_CMD__SD1_CMD 0x170f9 + MX6SL_PAD_SD1_CLK__SD1_CLK 0x100f9 + MX6SL_PAD_SD1_DAT0__SD1_DATA0 0x170f9 + MX6SL_PAD_SD1_DAT1__SD1_DATA1 0x170f9 + MX6SL_PAD_SD1_DAT2__SD1_DATA2 0x170f9 + MX6SL_PAD_SD1_DAT3__SD1_DATA3 0x170f9 + MX6SL_PAD_SD1_DAT4__SD1_DATA4 0x170f9 + MX6SL_PAD_SD1_DAT5__SD1_DATA5 0x170f9 + MX6SL_PAD_SD1_DAT6__SD1_DATA6 0x170f9 + MX6SL_PAD_SD1_DAT7__SD1_DATA7 0x170f9 + >; + }; + + }; usdhc2 { @@ -585,6 +697,29 @@ MX6SL_PAD_SD2_DAT3__SD2_DATA3 0x17059 >; }; + + pinctrl_usdhc2_1_100mhz: usdhc2grp-1-100mhz { + fsl,pins = < + MX6SL_PAD_SD2_CMD__SD2_CMD 0x170b9 + MX6SL_PAD_SD2_CLK__SD2_CLK 0x100b9 + MX6SL_PAD_SD2_DAT0__SD2_DATA0 0x170b9 + MX6SL_PAD_SD2_DAT1__SD2_DATA1 0x170b9 + MX6SL_PAD_SD2_DAT2__SD2_DATA2 0x170b9 + MX6SL_PAD_SD2_DAT3__SD2_DATA3 0x170b9 + >; + }; + + pinctrl_usdhc2_1_200mhz: usdhc2grp-1-200mhz { + fsl,pins = < + MX6SL_PAD_SD2_CMD__SD2_CMD 0x170f9 + MX6SL_PAD_SD2_CLK__SD2_CLK 0x100f9 + MX6SL_PAD_SD2_DAT0__SD2_DATA0 0x170f9 + MX6SL_PAD_SD2_DAT1__SD2_DATA1 0x170f9 + MX6SL_PAD_SD2_DAT2__SD2_DATA2 0x170f9 + MX6SL_PAD_SD2_DAT3__SD2_DATA3 0x170f9 + >; + }; + }; usdhc3 { @@ -598,6 +733,28 @@ MX6SL_PAD_SD3_DAT3__SD3_DATA3 0x17059 >; }; + + pinctrl_usdhc3_1_100mhz: usdhc3grp-1-100mhz { + fsl,pins = < + MX6SL_PAD_SD3_CMD__SD3_CMD 0x170b9 + MX6SL_PAD_SD3_CLK__SD3_CLK 0x100b9 + MX6SL_PAD_SD3_DAT0__SD3_DATA0 0x170b9 + MX6SL_PAD_SD3_DAT1__SD3_DATA1 0x170b9 + MX6SL_PAD_SD3_DAT2__SD3_DATA2 0x170b9 + MX6SL_PAD_SD3_DAT3__SD3_DATA3 0x170b9 + >; + }; + + pinctrl_usdhc3_1_200mhz: usdhc3grp-1-200mhz { + fsl,pins = < + MX6SL_PAD_SD3_CMD__SD3_CMD 0x170f9 + MX6SL_PAD_SD3_CLK__SD3_CLK 0x100f9 + MX6SL_PAD_SD3_DAT0__SD3_DATA0 0x170f9 + MX6SL_PAD_SD3_DAT1__SD3_DATA1 0x170f9 + MX6SL_PAD_SD3_DAT2__SD3_DATA2 0x170f9 + MX6SL_PAD_SD3_DAT3__SD3_DATA3 0x170f9 + >; + }; }; }; @@ -619,7 +776,8 @@ <&clks IMX6SL_CLK_SDMA>; clock-names = "ipg", "ahb"; #dma-cells = <3>; - fsl,sdma-ram-script-name = "imx/sdma/sdma-imx6sl.bin"; + /* imx6sl reuses imx6q sdma firmware */ + fsl,sdma-ram-script-name = "imx/sdma/sdma-imx6q.bin"; }; pxp: pxp@020f0000 { @@ -663,7 +821,7 @@ usbotg2: usb@02184200 { compatible = "fsl,imx6sl-usb", "fsl,imx27-usb"; reg = <0x02184200 0x200>; - interrupts = <0 40 0x04>; + interrupts = <0 42 0x04>; clocks = <&clks IMX6SL_CLK_USBOH3>; fsl,usbphy = <&usbphy2>; fsl,usbmisc = <&usbmisc 1>; @@ -673,7 +831,7 @@ usbh: usb@02184400 { compatible = "fsl,imx6sl-usb", "fsl,imx27-usb"; reg = <0x02184400 0x200>; - interrupts = <0 42 0x04>; + interrupts = <0 40 0x04>; clocks = <&clks IMX6SL_CLK_USBOH3>; fsl,usbmisc = <&usbmisc 2>; status = "disabled"; diff --git a/arch/arm/boot/dts/integrator.dtsi b/arch/arm/boot/dts/integrator.dtsi index 813b91d7bea2..0f06f8687b0b 100644 --- a/arch/arm/boot/dts/integrator.dtsi +++ b/arch/arm/boot/dts/integrator.dtsi @@ -5,6 +5,11 @@ /include/ "skeleton.dtsi" / { + core-module@10000000 { + compatible = "arm,core-module-integrator"; + reg = <0x10000000 0x200>; + }; + timer@13000000 { reg = <0x13000000 0x100>; interrupt-parent = <&pic>; diff --git a/arch/arm/boot/dts/integratorap.dts b/arch/arm/boot/dts/integratorap.dts index b6b82eca8d1e..e6be9315ff0a 100644 --- a/arch/arm/boot/dts/integratorap.dts +++ b/arch/arm/boot/dts/integratorap.dts @@ -19,8 +19,11 @@ }; syscon { - /* AP system controller registers */ + compatible = "arm,integrator-ap-syscon"; reg = <0x11000000 0x100>; + interrupt-parent = <&pic>; + /* These are the logical module IRQs */ + interrupts = <9>, <10>, <11>, <12>; }; timer0: timer@13000000 { diff --git a/arch/arm/boot/dts/integratorcp.dts b/arch/arm/boot/dts/integratorcp.dts index 72693a69f830..7deb3a3182b4 100644 --- a/arch/arm/boot/dts/integratorcp.dts +++ b/arch/arm/boot/dts/integratorcp.dts @@ -13,8 +13,8 @@ bootargs = "root=/dev/ram0 console=ttyAMA0,38400n8 earlyprintk"; }; - cpcon { - /* CP controller registers */ + syscon { + compatible = "arm,integrator-cp-syscon"; reg = <0xcb000000 0x100>; }; diff --git a/arch/arm/boot/dts/keystone-clocks.dtsi b/arch/arm/boot/dts/keystone-clocks.dtsi new file mode 100644 index 000000000000..d6713b113258 --- /dev/null +++ b/arch/arm/boot/dts/keystone-clocks.dtsi @@ -0,0 +1,821 @@ +/* + * Device Tree Source for Keystone 2 clock tree + * + * Copyright (C) 2013 Texas Instruments, Inc. + * + * 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. + */ + +clocks { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + refclkmain: refclkmain { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <122880000>; + clock-output-names = "refclk-main"; + }; + + mainpllclk: mainpllclk@2310110 { + #clock-cells = <0>; + compatible = "ti,keystone,main-pll-clock"; + clocks = <&refclkmain>; + reg = <0x02620350 4>, <0x02310110 4>; + reg-names = "control", "multiplier"; + fixed-postdiv = <2>; + }; + + papllclk: papllclk@2620358 { + #clock-cells = <0>; + compatible = "ti,keystone,pll-clock"; + clocks = <&refclkmain>; + clock-output-names = "pa-pll-clk"; + reg = <0x02620358 4>; + reg-names = "control"; + fixed-postdiv = <6>; + }; + + ddr3allclk: ddr3apllclk@2620360 { + #clock-cells = <0>; + compatible = "ti,keystone,pll-clock"; + clocks = <&refclkmain>; + clock-output-names = "ddr-3a-pll-clk"; + reg = <0x02620360 4>; + reg-names = "control"; + fixed-postdiv = <6>; + }; + + ddr3bllclk: ddr3bpllclk@2620368 { + #clock-cells = <0>; + compatible = "ti,keystone,pll-clock"; + clocks = <&refclkmain>; + clock-output-names = "ddr-3b-pll-clk"; + reg = <0x02620368 4>; + reg-names = "control"; + fixed-postdiv = <6>; + }; + + armpllclk: armpllclk@2620370 { + #clock-cells = <0>; + compatible = "ti,keystone,pll-clock"; + clocks = <&refclkmain>; + clock-output-names = "arm-pll-clk"; + reg = <0x02620370 4>; + reg-names = "control"; + fixed-postdiv = <6>; + }; + + mainmuxclk: mainmuxclk@2310108 { + #clock-cells = <0>; + compatible = "ti,keystone,pll-mux-clock"; + clocks = <&mainpllclk>, <&refclkmain>; + reg = <0x02310108 4>; + bit-shift = <23>; + bit-mask = <1>; + clock-output-names = "mainmuxclk"; + }; + + chipclk1: chipclk1 { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&mainmuxclk>; + clock-div = <1>; + clock-mult = <1>; + clock-output-names = "chipclk1"; + }; + + chipclk1rstiso: chipclk1rstiso { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&mainmuxclk>; + clock-div = <1>; + clock-mult = <1>; + clock-output-names = "chipclk1rstiso"; + }; + + gemtraceclk: gemtraceclk@2310120 { + #clock-cells = <0>; + compatible = "ti,keystone,pll-divider-clock"; + clocks = <&mainmuxclk>; + reg = <0x02310120 4>; + bit-shift = <0>; + bit-mask = <8>; + clock-output-names = "gemtraceclk"; + }; + + chipstmxptclk: chipstmxptclk { + #clock-cells = <0>; + compatible = "ti,keystone,pll-divider-clock"; + clocks = <&mainmuxclk>; + reg = <0x02310164 4>; + bit-shift = <0>; + bit-mask = <8>; + clock-output-names = "chipstmxptclk"; + }; + + chipclk12: chipclk12 { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&chipclk1>; + clock-div = <2>; + clock-mult = <1>; + clock-output-names = "chipclk12"; + }; + + chipclk13: chipclk13 { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&chipclk1>; + clock-div = <3>; + clock-mult = <1>; + clock-output-names = "chipclk13"; + }; + + chipclk14: chipclk14 { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&chipclk1>; + clock-div = <4>; + clock-mult = <1>; + clock-output-names = "chipclk14"; + }; + + chipclk16: chipclk16 { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&chipclk1>; + clock-div = <6>; + clock-mult = <1>; + clock-output-names = "chipclk16"; + }; + + chipclk112: chipclk112 { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&chipclk1>; + clock-div = <12>; + clock-mult = <1>; + clock-output-names = "chipclk112"; + }; + + chipclk124: chipclk124 { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&chipclk1>; + clock-div = <24>; + clock-mult = <1>; + clock-output-names = "chipclk114"; + }; + + chipclk1rstiso13: chipclk1rstiso13 { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&chipclk1rstiso>; + clock-div = <3>; + clock-mult = <1>; + clock-output-names = "chipclk1rstiso13"; + }; + + chipclk1rstiso14: chipclk1rstiso14 { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&chipclk1rstiso>; + clock-div = <4>; + clock-mult = <1>; + clock-output-names = "chipclk1rstiso14"; + }; + + chipclk1rstiso16: chipclk1rstiso16 { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&chipclk1rstiso>; + clock-div = <6>; + clock-mult = <1>; + clock-output-names = "chipclk1rstiso16"; + }; + + chipclk1rstiso112: chipclk1rstiso112 { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&chipclk1rstiso>; + clock-div = <12>; + clock-mult = <1>; + clock-output-names = "chipclk1rstiso112"; + }; + + clkmodrst0: clkmodrst0 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk16>; + clock-output-names = "modrst0"; + reg = <0x02350000 0xb00>, <0x02350000 0x400>; + reg-names = "control", "domain"; + domain-id = <0>; + }; + + + clkusb: clkusb { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk16>; + clock-output-names = "usb"; + reg = <0x02350008 0xb00>, <0x02350000 0x400>; + reg-names = "control", "domain"; + domain-id = <0>; + }; + + clkaemifspi: clkaemifspi { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk16>; + clock-output-names = "aemif-spi"; + reg = <0x0235000c 0xb00>, <0x02350000 0x400>; + reg-names = "control", "domain"; + domain-id = <0>; + }; + + + clkdebugsstrc: clkdebugsstrc { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "debugss-trc"; + reg = <0x02350014 0xb00>, <0x02350000 0x400>; + reg-names = "control", "domain"; + domain-id = <0>; + }; + + clktetbtrc: clktetbtrc { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "tetb-trc"; + reg = <0x02350018 0xb00>, <0x02350004 0x400>; + reg-names = "control", "domain"; + domain-id = <1>; + }; + + clkpa: clkpa { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk16>; + clock-output-names = "pa"; + reg = <0x0235001c 0xb00>, <0x02350008 0x400>; + reg-names = "control", "domain"; + domain-id = <2>; + }; + + clkcpgmac: clkcpgmac { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&clkpa>; + clock-output-names = "cpgmac"; + reg = <0x02350020 0xb00>, <0x02350008 0x400>; + reg-names = "control", "domain"; + domain-id = <2>; + }; + + clksa: clksa { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&clkpa>; + clock-output-names = "sa"; + reg = <0x02350024 0xb00>, <0x02350008 0x400>; + reg-names = "control", "domain"; + domain-id = <2>; + }; + + clkpcie: clkpcie { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk12>; + clock-output-names = "pcie"; + reg = <0x02350028 0xb00>, <0x0235000c 0x400>; + reg-names = "control", "domain"; + domain-id = <3>; + }; + + clksrio: clksrio { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk1rstiso13>; + clock-output-names = "srio"; + reg = <0x0235002c 0xb00>, <0x02350010 0x400>; + reg-names = "control", "domain"; + domain-id = <4>; + }; + + clkhyperlink0: clkhyperlink0 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk12>; + clock-output-names = "hyperlink-0"; + reg = <0x02350030 0xb00>, <0x02350014 0x400>; + reg-names = "control", "domain"; + domain-id = <5>; + }; + + clksr: clksr { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk1rstiso112>; + clock-output-names = "sr"; + reg = <0x02350034 0xb00>, <0x02350018 0x400>; + reg-names = "control", "domain"; + domain-id = <6>; + }; + + clkmsmcsram: clkmsmcsram { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk1>; + clock-output-names = "msmcsram"; + reg = <0x02350038 0xb00>, <0x0235001c 0x400>; + reg-names = "control", "domain"; + domain-id = <7>; + }; + + clkgem0: clkgem0 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk1>; + clock-output-names = "gem0"; + reg = <0x0235003c 0xb00>, <0x02350020 0x400>; + reg-names = "control", "domain"; + domain-id = <8>; + }; + + clkgem1: clkgem1 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk1>; + clock-output-names = "gem1"; + reg = <0x02350040 0xb00>, <0x02350024 0x400>; + reg-names = "control", "domain"; + domain-id = <9>; + }; + + clkgem2: clkgem2 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk1>; + clock-output-names = "gem2"; + reg = <0x02350044 0xb00>, <0x02350028 0x400>; + reg-names = "control", "domain"; + domain-id = <10>; + }; + + clkgem3: clkgem3 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk1>; + clock-output-names = "gem3"; + reg = <0x02350048 0xb00>, <0x0235002c 0x400>; + reg-names = "control", "domain"; + domain-id = <11>; + }; + + clkgem4: clkgem4 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk1>; + clock-output-names = "gem4"; + reg = <0x0235004c 0xb00>, <0x02350030 0x400>; + reg-names = "control", "domain"; + domain-id = <12>; + }; + + clkgem5: clkgem5 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk1>; + clock-output-names = "gem5"; + reg = <0x02350050 0xb00>, <0x02350034 0x400>; + reg-names = "control", "domain"; + domain-id = <13>; + }; + + clkgem6: clkgem6 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk1>; + clock-output-names = "gem6"; + reg = <0x02350054 0xb00>, <0x02350038 0x400>; + reg-names = "control", "domain"; + domain-id = <14>; + }; + + clkgem7: clkgem7 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk1>; + clock-output-names = "gem7"; + reg = <0x02350058 0xb00>, <0x0235003c 0x400>; + reg-names = "control", "domain"; + domain-id = <15>; + }; + + clkddr30: clkddr30 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk12>; + clock-output-names = "ddr3-0"; + reg = <0x0235005c 0xb00>, <0x02350040 0x400>; + reg-names = "control", "domain"; + domain-id = <16>; + }; + + clkddr31: clkddr31 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "ddr3-1"; + reg = <0x02350060 0xb00>, <0x02350040 0x400>; + reg-names = "control", "domain"; + domain-id = <16>; + }; + + clktac: clktac { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "tac"; + reg = <0x02350064 0xb00>, <0x02350044 0x400>; + reg-names = "control", "domain"; + domain-id = <17>; + }; + + clkrac01: clktac01 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "rac-01"; + reg = <0x02350068 0xb00>, <0x02350044 0x400>; + reg-names = "control", "domain"; + domain-id = <17>; + }; + + clkrac23: clktac23 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "rac-23"; + reg = <0x0235006c 0xb00>, <0x02350048 0x400>; + reg-names = "control", "domain"; + domain-id = <18>; + }; + + clkfftc0: clkfftc0 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "fftc-0"; + reg = <0x02350070 0xb00>, <0x0235004c 0x400>; + reg-names = "control", "domain"; + domain-id = <19>; + }; + + clkfftc1: clkfftc1 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "fftc-1"; + reg = <0x02350074 0xb00>, <0x023504c0 0x400>; + reg-names = "control", "domain"; + domain-id = <19>; + }; + + clkfftc2: clkfftc2 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "fftc-2"; + reg = <0x02350078 0xb00>, <0x02350050 0x400>; + reg-names = "control", "domain"; + domain-id = <20>; + }; + + clkfftc3: clkfftc3 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "fftc-3"; + reg = <0x0235007c 0xb00>, <0x02350050 0x400>; + reg-names = "control", "domain"; + domain-id = <20>; + }; + + clkfftc4: clkfftc4 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "fftc-4"; + reg = <0x02350080 0xb00>, <0x02350050 0x400>; + reg-names = "control", "domain"; + domain-id = <20>; + }; + + clkfftc5: clkfftc5 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "fftc-5"; + reg = <0x02350084 0xb00>, <0x02350050 0x400>; + reg-names = "control", "domain"; + domain-id = <20>; + }; + + clkaif: clkaif { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "aif"; + reg = <0x02350088 0xb00>, <0x02350054 0x400>; + reg-names = "control", "domain"; + domain-id = <21>; + }; + + clktcp3d0: clktcp3d0 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "tcp3d-0"; + reg = <0x0235008c 0xb00>, <0x02350058 0x400>; + reg-names = "control", "domain"; + domain-id = <22>; + }; + + clktcp3d1: clktcp3d1 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "tcp3d-1"; + reg = <0x02350090 0xb00>, <0x02350058 0x400>; + reg-names = "control", "domain"; + domain-id = <22>; + }; + + clktcp3d2: clktcp3d2 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "tcp3d-2"; + reg = <0x02350094 0xb00>, <0x0235005c 0x400>; + reg-names = "control", "domain"; + domain-id = <23>; + }; + + clktcp3d3: clktcp3d3 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "tcp3d-3"; + reg = <0x02350098 0xb00>, <0x0235005c 0x400>; + reg-names = "control", "domain"; + domain-id = <23>; + }; + + clkvcp0: clkvcp0 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "vcp-0"; + reg = <0x0235009c 0xb00>, <0x02350060 0x400>; + reg-names = "control", "domain"; + domain-id = <24>; + }; + + clkvcp1: clkvcp1 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "vcp-1"; + reg = <0x023500a0 0xb00>, <0x02350060 0x400>; + reg-names = "control", "domain"; + domain-id = <24>; + }; + + clkvcp2: clkvcp2 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "vcp-2"; + reg = <0x023500a4 0xb00>, <0x02350060 0x400>; + reg-names = "control", "domain"; + domain-id = <24>; + }; + + clkvcp3: clkvcp3 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "vcp-3"; + reg = <0x0235000a8 0xb00>, <0x02350060 0x400>; + reg-names = "control", "domain"; + domain-id = <24>; + }; + + clkvcp4: clkvcp4 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "vcp-4"; + reg = <0x023500ac 0xb00>, <0x02350064 0x400>; + reg-names = "control", "domain"; + domain-id = <25>; + }; + + clkvcp5: clkvcp5 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "vcp-5"; + reg = <0x023500b0 0xb00>, <0x02350064 0x400>; + reg-names = "control", "domain"; + domain-id = <25>; + }; + + clkvcp6: clkvcp6 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "vcp-6"; + reg = <0x023500b4 0xb00>, <0x02350064 0x400>; + reg-names = "control", "domain"; + domain-id = <25>; + }; + + clkvcp7: clkvcp7 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "vcp-7"; + reg = <0x023500b8 0xb00>, <0x02350064 0x400>; + reg-names = "control", "domain"; + domain-id = <25>; + }; + + clkbcp: clkbcp { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "bcp"; + reg = <0x023500bc 0xb00>, <0x02350068 0x400>; + reg-names = "control", "domain"; + domain-id = <26>; + }; + + clkdxb: clkdxb { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "dxb"; + reg = <0x023500c0 0xb00>, <0x0235006c 0x400>; + reg-names = "control", "domain"; + domain-id = <27>; + }; + + clkhyperlink1: clkhyperlink1 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk12>; + clock-output-names = "hyperlink-1"; + reg = <0x023500c4 0xb00>, <0x02350070 0x400>; + reg-names = "control", "domain"; + domain-id = <28>; + }; + + clkxge: clkxge { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "xge"; + reg = <0x023500c8 0xb00>, <0x02350074 0x400>; + reg-names = "control", "domain"; + domain-id = <29>; + }; + + clkwdtimer0: clkwdtimer0 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&clkmodrst0>; + clock-output-names = "timer0"; + reg = <0x02350000 0xb00>, <0x02350000 0x400>; + reg-names = "control", "domain"; + domain-id = <0>; + }; + + clkwdtimer1: clkwdtimer1 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&clkmodrst0>; + clock-output-names = "timer1"; + reg = <0x02350000 0xb00>, <0x02350000 0x400>; + reg-names = "control", "domain"; + domain-id = <0>; + }; + + clkwdtimer2: clkwdtimer2 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&clkmodrst0>; + clock-output-names = "timer2"; + reg = <0x02350000 0xb00>, <0x02350000 0x400>; + reg-names = "control", "domain"; + domain-id = <0>; + }; + + clkwdtimer3: clkwdtimer3 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&clkmodrst0>; + clock-output-names = "timer3"; + reg = <0x02350000 0xb00>, <0x02350000 0x400>; + reg-names = "control", "domain"; + domain-id = <0>; + }; + + clkuart0: clkuart0 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&clkmodrst0>; + clock-output-names = "uart0"; + reg = <0x02350000 0xb00>, <0x02350000 0x400>; + reg-names = "control", "domain"; + domain-id = <0>; + }; + + clkuart1: clkuart1 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&clkmodrst0>; + clock-output-names = "uart1"; + reg = <0x02350000 0xb00>, <0x02350000 0x400>; + reg-names = "control", "domain"; + domain-id = <0>; + }; + + clkaemif: clkaemif { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&clkaemifspi>; + clock-output-names = "aemif"; + reg = <0x02350000 0xb00>, <0x02350000 0x400>; + reg-names = "control", "domain"; + domain-id = <0>; + }; + + clkusim: clkusim { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&clkmodrst0>; + clock-output-names = "usim"; + reg = <0x02350000 0xb00>, <0x02350000 0x400>; + reg-names = "control", "domain"; + domain-id = <0>; + }; + + clki2c: clki2c { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&clkmodrst0>; + clock-output-names = "i2c"; + reg = <0x02350000 0xb00>, <0x02350000 0x400>; + reg-names = "control", "domain"; + domain-id = <0>; + }; + + clkspi: clkspi { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&clkaemifspi>; + clock-output-names = "spi"; + reg = <0x02350000 0xb00>, <0x02350000 0x400>; + reg-names = "control", "domain"; + domain-id = <0>; + }; + + clkgpio: clkgpio { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&clkmodrst0>; + clock-output-names = "gpio"; + reg = <0x02350000 0xb00>, <0x02350000 0x400>; + reg-names = "control", "domain"; + domain-id = <0>; + }; + + clkkeymgr: clkkeymgr { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&clkmodrst0>; + clock-output-names = "keymgr"; + reg = <0x02350000 0xb00>, <0x02350000 0x400>; + reg-names = "control", "domain"; + domain-id = <0>; + }; +}; diff --git a/arch/arm/boot/dts/keystone.dts b/arch/arm/boot/dts/keystone.dts index a68e34bbecb2..100bdf52b847 100644 --- a/arch/arm/boot/dts/keystone.dts +++ b/arch/arm/boot/dts/keystone.dts @@ -100,13 +100,15 @@ reg = <0x023100e8 4>; /* pll reset control reg */ }; + /include/ "keystone-clocks.dtsi" + uart0: serial@02530c00 { compatible = "ns16550a"; current-speed = <115200>; reg-shift = <2>; reg-io-width = <4>; reg = <0x02530c00 0x100>; - clock-frequency = <133120000>; + clocks = <&clkuart0>; interrupts = <GIC_SPI 277 IRQ_TYPE_EDGE_RISING>; }; @@ -116,9 +118,66 @@ reg-shift = <2>; reg-io-width = <4>; reg = <0x02531000 0x100>; - clock-frequency = <133120000>; + clocks = <&clkuart1>; interrupts = <GIC_SPI 280 IRQ_TYPE_EDGE_RISING>; }; + i2c0: i2c@2530000 { + compatible = "ti,davinci-i2c"; + reg = <0x02530000 0x400>; + clock-frequency = <100000>; + clocks = <&clki2c>; + interrupts = <GIC_SPI 283 IRQ_TYPE_EDGE_RISING>; + #address-cells = <1>; + #size-cells = <0>; + + dtt@50 { + compatible = "at,24c1024"; + reg = <0x50>; + }; + }; + + i2c1: i2c@2530400 { + compatible = "ti,davinci-i2c"; + reg = <0x02530400 0x400>; + clock-frequency = <100000>; + clocks = <&clki2c>; + interrupts = <GIC_SPI 286 IRQ_TYPE_EDGE_RISING>; + }; + + i2c2: i2c@2530800 { + compatible = "ti,davinci-i2c"; + reg = <0x02530800 0x400>; + clock-frequency = <100000>; + clocks = <&clki2c>; + interrupts = <GIC_SPI 289 IRQ_TYPE_EDGE_RISING>; + }; + + spi0: spi@21000400 { + compatible = "ti,dm6441-spi"; + reg = <0x21000400 0x200>; + num-cs = <4>; + ti,davinci-spi-intr-line = <0>; + interrupts = <GIC_SPI 292 IRQ_TYPE_EDGE_RISING>; + clocks = <&clkspi>; + }; + + spi1: spi@21000600 { + compatible = "ti,dm6441-spi"; + reg = <0x21000600 0x200>; + num-cs = <4>; + ti,davinci-spi-intr-line = <0>; + interrupts = <GIC_SPI 296 IRQ_TYPE_EDGE_RISING>; + clocks = <&clkspi>; + }; + + spi2: spi@21000800 { + compatible = "ti,dm6441-spi"; + reg = <0x21000800 0x200>; + num-cs = <4>; + ti,davinci-spi-intr-line = <0>; + interrupts = <GIC_SPI 300 IRQ_TYPE_EDGE_RISING>; + clocks = <&clkspi>; + }; }; }; diff --git a/arch/arm/boot/dts/kirkwood-db-88f6281.dts b/arch/arm/boot/dts/kirkwood-db-88f6281.dts index 72c4b0a0366f..c39dd766c75a 100644 --- a/arch/arm/boot/dts/kirkwood-db-88f6281.dts +++ b/arch/arm/boot/dts/kirkwood-db-88f6281.dts @@ -19,7 +19,6 @@ compatible = "marvell,db-88f6281-bp", "marvell,kirkwood-88f6281", "marvell,kirkwood"; mbus { - ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000>; pcie-controller { status = "okay"; diff --git a/arch/arm/boot/dts/kirkwood-db-88f6282.dts b/arch/arm/boot/dts/kirkwood-db-88f6282.dts index 36c411d34926..701c6b6cdaa2 100644 --- a/arch/arm/boot/dts/kirkwood-db-88f6282.dts +++ b/arch/arm/boot/dts/kirkwood-db-88f6282.dts @@ -19,7 +19,6 @@ compatible = "marvell,db-88f6282-bp", "marvell,kirkwood-88f6282", "marvell,kirkwood"; mbus { - ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000>; pcie-controller { status = "okay"; diff --git a/arch/arm/boot/dts/kirkwood-db.dtsi b/arch/arm/boot/dts/kirkwood-db.dtsi index c0e2a5879174..053aa20fb30f 100644 --- a/arch/arm/boot/dts/kirkwood-db.dtsi +++ b/arch/arm/boot/dts/kirkwood-db.dtsi @@ -39,28 +39,6 @@ status = "ok"; }; - nand@3000000 { - pinctrl-0 = <&pmx_nand>; - pinctrl-names = "default"; - chip-delay = <25>; - status = "okay"; - - partition@0 { - label = "uboot"; - reg = <0x0 0x100000>; - }; - - partition@100000 { - label = "uImage"; - reg = <0x100000 0x400000>; - }; - - partition@500000 { - label = "root"; - reg = <0x500000 0x1fb00000>; - }; - }; - sata@80000 { nr-ports = <2>; status = "okay"; @@ -80,6 +58,28 @@ }; }; +&nand { + pinctrl-0 = <&pmx_nand>; + pinctrl-names = "default"; + chip-delay = <25>; + status = "okay"; + + partition@0 { + label = "uboot"; + reg = <0x0 0x100000>; + }; + + partition@100000 { + label = "uImage"; + reg = <0x100000 0x400000>; + }; + + partition@500000 { + label = "root"; + reg = <0x500000 0x1fb00000>; + }; +}; + &mdio { status = "okay"; diff --git a/arch/arm/boot/dts/kirkwood-dnskw.dtsi b/arch/arm/boot/dts/kirkwood-dnskw.dtsi index d544f77a4ca4..aefa375a550d 100644 --- a/arch/arm/boot/dts/kirkwood-dnskw.dtsi +++ b/arch/arm/boot/dts/kirkwood-dnskw.dtsi @@ -148,44 +148,6 @@ status = "okay"; nr-ports = <2>; }; - - nand@3000000 { - pinctrl-0 = <&pmx_nand>; - pinctrl-names = "default"; - status = "okay"; - chip-delay = <35>; - - partition@0 { - label = "u-boot"; - reg = <0x0000000 0x100000>; - read-only; - }; - - partition@100000 { - label = "uImage"; - reg = <0x0100000 0x500000>; - }; - - partition@600000 { - label = "ramdisk"; - reg = <0x0600000 0x500000>; - }; - - partition@b00000 { - label = "image"; - reg = <0x0b00000 0x6600000>; - }; - - partition@7100000 { - label = "mini firmware"; - reg = <0x7100000 0xa00000>; - }; - - partition@7b00000 { - label = "config"; - reg = <0x7b00000 0x500000>; - }; - }; }; regulators { @@ -220,6 +182,44 @@ }; }; +&nand { + pinctrl-0 = <&pmx_nand>; + pinctrl-names = "default"; + status = "okay"; + chip-delay = <35>; + + partition@0 { + label = "u-boot"; + reg = <0x0000000 0x100000>; + read-only; + }; + + partition@100000 { + label = "uImage"; + reg = <0x0100000 0x500000>; + }; + + partition@600000 { + label = "ramdisk"; + reg = <0x0600000 0x500000>; + }; + + partition@b00000 { + label = "image"; + reg = <0x0b00000 0x6600000>; + }; + + partition@7100000 { + label = "mini firmware"; + reg = <0x7100000 0xa00000>; + }; + + partition@7b00000 { + label = "config"; + reg = <0x7b00000 0x500000>; + }; +}; + &mdio { status = "okay"; diff --git a/arch/arm/boot/dts/kirkwood-dockstar.dts b/arch/arm/boot/dts/kirkwood-dockstar.dts index 59a2117c35a7..33ff368fbfa5 100644 --- a/arch/arm/boot/dts/kirkwood-dockstar.dts +++ b/arch/arm/boot/dts/kirkwood-dockstar.dts @@ -34,26 +34,6 @@ serial@12000 { status = "ok"; }; - - nand@3000000 { - status = "okay"; - - partition@0 { - label = "u-boot"; - reg = <0x0000000 0x100000>; - read-only; - }; - - partition@100000 { - label = "uImage"; - reg = <0x0100000 0x400000>; - }; - - partition@500000 { - label = "data"; - reg = <0x0500000 0xfb00000>; - }; - }; }; gpio-leds { compatible = "gpio-leds"; @@ -91,6 +71,26 @@ }; }; +&nand { + status = "okay"; + + partition@0 { + label = "u-boot"; + reg = <0x0000000 0x100000>; + read-only; + }; + + partition@100000 { + label = "uImage"; + reg = <0x0100000 0x400000>; + }; + + partition@500000 { + label = "data"; + reg = <0x0500000 0xfb00000>; + }; +}; + &mdio { status = "okay"; diff --git a/arch/arm/boot/dts/kirkwood-goflexnet.dts b/arch/arm/boot/dts/kirkwood-goflexnet.dts index 6f7c7d7ecf2a..a43bebb25110 100644 --- a/arch/arm/boot/dts/kirkwood-goflexnet.dts +++ b/arch/arm/boot/dts/kirkwood-goflexnet.dts @@ -67,31 +67,6 @@ status = "ok"; }; - nand@3000000 { - chip-delay = <40>; - status = "okay"; - - partition@0 { - label = "u-boot"; - reg = <0x0000000 0x100000>; - read-only; - }; - - partition@100000 { - label = "uImage"; - reg = <0x0100000 0x400000>; - }; - - partition@500000 { - label = "pogoplug"; - reg = <0x0500000 0x2000000>; - }; - - partition@2500000 { - label = "root"; - reg = <0x02500000 0xd800000>; - }; - }; sata@80000 { status = "okay"; nr-ports = <2>; @@ -171,6 +146,32 @@ }; }; +&nand { + chip-delay = <40>; + status = "okay"; + + partition@0 { + label = "u-boot"; + reg = <0x0000000 0x100000>; + read-only; + }; + + partition@100000 { + label = "uImage"; + reg = <0x0100000 0x400000>; + }; + + partition@500000 { + label = "pogoplug"; + reg = <0x0500000 0x2000000>; + }; + + partition@2500000 { + label = "root"; + reg = <0x02500000 0xd800000>; + }; +}; + &mdio { status = "okay"; diff --git a/arch/arm/boot/dts/kirkwood-guruplug-server-plus.dts b/arch/arm/boot/dts/kirkwood-guruplug-server-plus.dts index 6548b9dc6855..d30a91a5047d 100644 --- a/arch/arm/boot/dts/kirkwood-guruplug-server-plus.dts +++ b/arch/arm/boot/dts/kirkwood-guruplug-server-plus.dts @@ -40,26 +40,6 @@ status = "ok"; }; - nand@3000000 { - status = "okay"; - - partition@0 { - label = "u-boot"; - reg = <0x00000000 0x00100000>; - read-only; - }; - - partition@100000 { - label = "uImage"; - reg = <0x00100000 0x00400000>; - }; - - partition@500000 { - label = "data"; - reg = <0x00500000 0x1fb00000>; - }; - }; - sata@80000 { status = "okay"; nr-ports = <1>; @@ -97,6 +77,26 @@ }; }; +&nand { + status = "okay"; + + partition@0 { + label = "u-boot"; + reg = <0x00000000 0x00100000>; + read-only; + }; + + partition@100000 { + label = "uImage"; + reg = <0x00100000 0x00400000>; + }; + + partition@500000 { + label = "data"; + reg = <0x00500000 0x1fb00000>; + }; +}; + &mdio { status = "okay"; diff --git a/arch/arm/boot/dts/kirkwood-ib62x0.dts b/arch/arm/boot/dts/kirkwood-ib62x0.dts index cb711a3bd983..c5fb02f7ebc3 100644 --- a/arch/arm/boot/dts/kirkwood-ib62x0.dts +++ b/arch/arm/boot/dts/kirkwood-ib62x0.dts @@ -5,7 +5,7 @@ / { model = "RaidSonic ICY BOX IB-NAS62x0 (Rev B)"; - compatible = "raidsonic,ib-nas6210-b", "raidsonic,ib-nas6220-b", "raidsonic,ib-nas6210", "raidsonic,ib-nas6220", "raidsonic,ib-nas62x0", "marvell,kirkwood-88f6281", "marvell,kirkwood"; + compatible = "raidsonic,ib-nas6210-b", "raidsonic,ib-nas6220-b", "raidsonic,ib-nas6210", "raidsonic,ib-nas6220", "raidsonic,ib-nas62x0", "marvell,kirkwood-88f6281", "marvell,kirkwood"; memory { device_type = "memory"; @@ -43,6 +43,7 @@ marvell,function = "gpio"; }; }; + serial@12000 { status = "okay"; }; @@ -51,28 +52,6 @@ status = "okay"; nr-ports = <2>; }; - - nand@3000000 { - status = "okay"; - pinctrl-0 = <&pmx_nand>; - pinctrl-names = "default"; - - partition@0 { - label = "u-boot"; - reg = <0x0000000 0x100000>; - }; - - partition@100000 { - label = "uImage"; - reg = <0x0100000 0x600000>; - }; - - partition@700000 { - label = "root"; - reg = <0x0700000 0xf900000>; - }; - - }; }; gpio_keys { @@ -93,6 +72,7 @@ gpios = <&gpio0 28 1>; }; }; + gpio-leds { compatible = "gpio-leds"; pinctrl-0 = <&pmx_led_os_red &pmx_led_os_green @@ -113,13 +93,39 @@ gpios = <&gpio0 27 0>; }; }; + gpio_poweroff { compatible = "gpio-poweroff"; pinctrl-0 = <&pmx_power_off>; pinctrl-names = "default"; gpios = <&gpio0 24 0>; }; +}; + +&nand { + status = "okay"; + pinctrl-0 = <&pmx_nand>; + pinctrl-names = "default"; + + partition@0 { + label = "u-boot"; + reg = <0x0000000 0xe0000>; + }; + partition@e0000 { + label = "u-boot environment"; + reg = <0xe0000 0x100000>; + }; + + partition@100000 { + label = "uImage"; + reg = <0x0100000 0x600000>; + }; + + partition@700000 { + label = "root"; + reg = <0x0700000 0xf900000>; + }; }; @@ -134,6 +140,7 @@ ð0 { status = "okay"; + ethernet0-port@0 { phy-handle = <ðphy0>; }; diff --git a/arch/arm/boot/dts/kirkwood-iconnect.dts b/arch/arm/boot/dts/kirkwood-iconnect.dts index 0323f017eeed..4a62b206f680 100644 --- a/arch/arm/boot/dts/kirkwood-iconnect.dts +++ b/arch/arm/boot/dts/kirkwood-iconnect.dts @@ -19,7 +19,6 @@ }; mbus { - ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000>; pcie-controller { status = "okay"; @@ -83,35 +82,6 @@ serial@12000 { status = "ok"; }; - - nand@3000000 { - status = "okay"; - - partition@0 { - label = "uboot"; - reg = <0x0000000 0xc0000>; - }; - - partition@a0000 { - label = "env"; - reg = <0xa0000 0x20000>; - }; - - partition@100000 { - label = "zImage"; - reg = <0x100000 0x300000>; - }; - - partition@540000 { - label = "initrd"; - reg = <0x540000 0x300000>; - }; - - partition@980000 { - label = "boot"; - reg = <0x980000 0x1f400000>; - }; - }; }; gpio-leds { @@ -180,6 +150,35 @@ }; }; +&nand { + status = "okay"; + + partition@0 { + label = "uboot"; + reg = <0x0000000 0xc0000>; + }; + + partition@a0000 { + label = "env"; + reg = <0xa0000 0x20000>; + }; + + partition@100000 { + label = "zImage"; + reg = <0x100000 0x300000>; + }; + + partition@540000 { + label = "initrd"; + reg = <0x540000 0x300000>; + }; + + partition@980000 { + label = "boot"; + reg = <0x980000 0x1f400000>; + }; +}; + &mdio { status = "okay"; diff --git a/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts b/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts index df8447442b37..d15395d671ed 100644 --- a/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts +++ b/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts @@ -113,31 +113,6 @@ status = "ok"; }; - nand@3000000 { - status = "okay"; - - partition@0 { - label = "u-boot"; - reg = <0x0000000 0x100000>; - read-only; - }; - - partition@a0000 { - label = "env"; - reg = <0xa0000 0x20000>; - read-only; - }; - - partition@100000 { - label = "uImage"; - reg = <0x100000 0x300000>; - }; - - partition@400000 { - label = "uInitrd"; - reg = <0x540000 0x1000000>; - }; - }; sata@80000 { status = "okay"; nr-ports = <2>; @@ -195,6 +170,32 @@ }; }; +&nand { + status = "okay"; + + partition@0 { + label = "u-boot"; + reg = <0x0000000 0x100000>; + read-only; + }; + + partition@a0000 { + label = "env"; + reg = <0xa0000 0x20000>; + read-only; + }; + + partition@100000 { + label = "uImage"; + reg = <0x100000 0x300000>; + }; + + partition@400000 { + label = "uInitrd"; + reg = <0x540000 0x1000000>; + }; +}; + &mdio { status = "okay"; diff --git a/arch/arm/boot/dts/kirkwood-km_kirkwood.dts b/arch/arm/boot/dts/kirkwood-km_kirkwood.dts index 6899408482d2..cd44f37e54b5 100644 --- a/arch/arm/boot/dts/kirkwood-km_kirkwood.dts +++ b/arch/arm/boot/dts/kirkwood-km_kirkwood.dts @@ -34,13 +34,6 @@ serial@12000 { status = "ok"; }; - - nand@3000000 { - pinctrl-0 = <&pmx_nand>; - pinctrl-names = "default"; - status = "ok"; - chip-delay = <25>; - }; }; i2c@0 { @@ -51,6 +44,13 @@ }; }; +&nand { + pinctrl-0 = <&pmx_nand>; + pinctrl-names = "default"; + status = "ok"; + chip-delay = <25>; +}; + &mdio { status = "okay"; diff --git a/arch/arm/boot/dts/kirkwood-mplcec4.dts b/arch/arm/boot/dts/kirkwood-mplcec4.dts index ce2b94b513db..6c1ec2786e6e 100644 --- a/arch/arm/boot/dts/kirkwood-mplcec4.dts +++ b/arch/arm/boot/dts/kirkwood-mplcec4.dts @@ -17,7 +17,6 @@ }; mbus { - ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000>; pcie-controller { status = "okay"; @@ -96,37 +95,6 @@ pinctrl-names = "default"; }; - nand@3000000 { - pinctrl-0 = <&pmx_nand>; - pinctrl-names = "default"; - status = "okay"; - - partition@0 { - label = "uboot"; - reg = <0x0000000 0x100000>; - }; - - partition@100000 { - label = "env"; - reg = <0x100000 0x80000>; - }; - - partition@180000 { - label = "fdt"; - reg = <0x180000 0x80000>; - }; - - partition@200000 { - label = "kernel"; - reg = <0x200000 0x400000>; - }; - - partition@600000 { - label = "rootfs"; - reg = <0x600000 0x1fa00000>; - }; - }; - rtc@10300 { status = "disabled"; }; @@ -194,6 +162,37 @@ }; }; +&nand { + pinctrl-0 = <&pmx_nand>; + pinctrl-names = "default"; + status = "okay"; + + partition@0 { + label = "uboot"; + reg = <0x0000000 0x100000>; + }; + + partition@100000 { + label = "env"; + reg = <0x100000 0x80000>; + }; + + partition@180000 { + label = "fdt"; + reg = <0x180000 0x80000>; + }; + + partition@200000 { + label = "kernel"; + reg = <0x200000 0x400000>; + }; + + partition@600000 { + label = "rootfs"; + reg = <0x600000 0x1fa00000>; + }; +}; + &mdio { status = "okay"; diff --git a/arch/arm/boot/dts/kirkwood-netgear_readynas_duo_v2.dts b/arch/arm/boot/dts/kirkwood-netgear_readynas_duo_v2.dts index 874857ea9cb8..e6a102cf424c 100644 --- a/arch/arm/boot/dts/kirkwood-netgear_readynas_duo_v2.dts +++ b/arch/arm/boot/dts/kirkwood-netgear_readynas_duo_v2.dts @@ -17,7 +17,6 @@ }; mbus { - ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000>; pcie-controller { status = "okay"; @@ -98,36 +97,6 @@ status = "okay"; }; - nand@3000000 { - status = "okay"; - - partition@0 { - label = "u-boot"; - reg = <0x0000000 0x180000>; - read-only; - }; - - partition@180000 { - label = "u-boot-env"; - reg = <0x180000 0x20000>; - }; - - partition@200000 { - label = "uImage"; - reg = <0x0200000 0x600000>; - }; - - partition@800000 { - label = "minirootfs"; - reg = <0x0800000 0x1000000>; - }; - - partition@1800000 { - label = "jffs2"; - reg = <0x1800000 0x6800000>; - }; - }; - sata@80000 { status = "okay"; nr-ports = <2>; @@ -208,6 +177,36 @@ }; }; +&nand { + status = "okay"; + + partition@0 { + label = "u-boot"; + reg = <0x0000000 0x180000>; + read-only; + }; + + partition@180000 { + label = "u-boot-env"; + reg = <0x180000 0x20000>; + }; + + partition@200000 { + label = "uImage"; + reg = <0x0200000 0x600000>; + }; + + partition@800000 { + label = "minirootfs"; + reg = <0x0800000 0x1000000>; + }; + + partition@1800000 { + label = "jffs2"; + reg = <0x1800000 0x6800000>; + }; +}; + &mdio { status = "okay"; diff --git a/arch/arm/boot/dts/kirkwood-nsa310-common.dtsi b/arch/arm/boot/dts/kirkwood-nsa310-common.dtsi index 06267a91de38..e3f915defd3d 100644 --- a/arch/arm/boot/dts/kirkwood-nsa310-common.dtsi +++ b/arch/arm/boot/dts/kirkwood-nsa310-common.dtsi @@ -27,49 +27,6 @@ nr-ports = <2>; }; - nand@3000000 { - status = "okay"; - chip-delay = <35>; - - partition@0 { - label = "uboot"; - reg = <0x0000000 0x0100000>; - read-only; - }; - partition@100000 { - label = "uboot_env"; - reg = <0x0100000 0x0080000>; - }; - partition@180000 { - label = "key_store"; - reg = <0x0180000 0x0080000>; - }; - partition@200000 { - label = "info"; - reg = <0x0200000 0x0080000>; - }; - partition@280000 { - label = "etc"; - reg = <0x0280000 0x0a00000>; - }; - partition@c80000 { - label = "kernel_1"; - reg = <0x0c80000 0x0a00000>; - }; - partition@1680000 { - label = "rootfs1"; - reg = <0x1680000 0x2fc0000>; - }; - partition@4640000 { - label = "kernel_2"; - reg = <0x4640000 0x0a00000>; - }; - partition@5040000 { - label = "rootfs2"; - reg = <0x5040000 0x2fc0000>; - }; - }; - pcie-controller { status = "okay"; @@ -105,3 +62,46 @@ }; }; }; + +&nand { + status = "okay"; + chip-delay = <35>; + + partition@0 { + label = "uboot"; + reg = <0x0000000 0x0100000>; + read-only; + }; + partition@100000 { + label = "uboot_env"; + reg = <0x0100000 0x0080000>; + }; + partition@180000 { + label = "key_store"; + reg = <0x0180000 0x0080000>; + }; + partition@200000 { + label = "info"; + reg = <0x0200000 0x0080000>; + }; + partition@280000 { + label = "etc"; + reg = <0x0280000 0x0a00000>; + }; + partition@c80000 { + label = "kernel_1"; + reg = <0x0c80000 0x0a00000>; + }; + partition@1680000 { + label = "rootfs1"; + reg = <0x1680000 0x2fc0000>; + }; + partition@4640000 { + label = "kernel_2"; + reg = <0x4640000 0x0a00000>; + }; + partition@5040000 { + label = "rootfs2"; + reg = <0x5040000 0x2fc0000>; + }; +}; diff --git a/arch/arm/boot/dts/kirkwood-nsa310.dts b/arch/arm/boot/dts/kirkwood-nsa310.dts index 7aeae0c2c1f4..b5418bcaecce 100644 --- a/arch/arm/boot/dts/kirkwood-nsa310.dts +++ b/arch/arm/boot/dts/kirkwood-nsa310.dts @@ -15,7 +15,6 @@ }; mbus { - ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000>; pcie-controller { status = "okay"; diff --git a/arch/arm/boot/dts/kirkwood-openblocks_a6.dts b/arch/arm/boot/dts/kirkwood-openblocks_a6.dts index 85ccf8d8abb1..f0e3d213604c 100644 --- a/arch/arm/boot/dts/kirkwood-openblocks_a6.dts +++ b/arch/arm/boot/dts/kirkwood-openblocks_a6.dts @@ -29,43 +29,6 @@ pinctrl-names = "default"; }; - nand@3000000 { - chip-delay = <25>; - status = "okay"; - pinctrl-0 = <&pmx_nand>; - pinctrl-names = "default"; - - partition@0 { - label = "uboot"; - reg = <0x0 0x90000>; - }; - - partition@90000 { - label = "env"; - reg = <0x90000 0x44000>; - }; - - partition@d4000 { - label = "test"; - reg = <0xd4000 0x24000>; - }; - - partition@f4000 { - label = "conf"; - reg = <0xf4000 0x400000>; - }; - - partition@4f4000 { - label = "linux"; - reg = <0x4f4000 0x1d20000>; - }; - - partition@2214000 { - label = "user"; - reg = <0x2214000 0x1dec000>; - }; - }; - sata@80000 { nr-ports = <1>; status = "okay"; @@ -167,6 +130,43 @@ }; }; +&nand { + chip-delay = <25>; + status = "okay"; + pinctrl-0 = <&pmx_nand>; + pinctrl-names = "default"; + + partition@0 { + label = "uboot"; + reg = <0x0 0x90000>; + }; + + partition@90000 { + label = "env"; + reg = <0x90000 0x44000>; + }; + + partition@d4000 { + label = "test"; + reg = <0xd4000 0x24000>; + }; + + partition@f4000 { + label = "conf"; + reg = <0xf4000 0x400000>; + }; + + partition@4f4000 { + label = "linux"; + reg = <0x4f4000 0x1d20000>; + }; + + partition@2214000 { + label = "user"; + reg = <0x2214000 0x1dec000>; + }; +}; + &mdio { status = "okay"; diff --git a/arch/arm/boot/dts/kirkwood-openblocks_a7.dts b/arch/arm/boot/dts/kirkwood-openblocks_a7.dts new file mode 100644 index 000000000000..851fb2a60f20 --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-openblocks_a7.dts @@ -0,0 +1,223 @@ +/* + * Device Tree file for OpenBlocks A7 board + * + * Copyright (C) 2013 Free Electrons + * + * Thomas Petazzoni <thomas.petazzoni@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. + */ + +/dts-v1/; + +#include "kirkwood.dtsi" +#include "kirkwood-6282.dtsi" + +/ { + model = "Plat'Home OpenBlocksA7"; + compatible = "plathome,openblocks-a7", "marvell,kirkwood-88f6283", "marvell,kirkwood"; + + memory { + device_type = "memory"; + reg = <0x00000000 0x40000000>; /* 1 GB */ + }; + + chosen { + bootargs = "console=ttyS0,115200n8 earlyprintk"; + }; + + ocp@f1000000 { + serial@12000 { + status = "ok"; + pinctrl-0 = <&pmx_uart0>; + pinctrl-names = "default"; + }; + + serial@12100 { + status = "ok"; + pinctrl-0 = <&pmx_uart1>; + pinctrl-names = "default"; + }; + + sata@80000 { + nr-ports = <1>; + status = "okay"; + }; + + i2c@11100 { + status = "okay"; + pinctrl-0 = <&pmx_twsi1>; + pinctrl-names = "default"; + + s24c02: s24c02@50 { + compatible = "24c02"; + reg = <0x50>; + }; + }; + + pinctrl: pinctrl@10000 { + pinctrl-0 = <&pmx_dip_switches &pmx_gpio_header>; + pinctrl-names = "default"; + + pmx_uart0: pmx-uart0 { + marvell,pins = "mpp10", "mpp11", "mpp15", + "mpp16"; + marvell,function = "uart0"; + }; + + pmx_uart1: pmx-uart1 { + marvell,pins = "mpp13", "mpp14", "mpp8", + "mpp9"; + marvell,function = "uart1"; + }; + + pmx_sysrst: pmx-sysrst { + marvell,pins = "mpp6"; + marvell,function = "sysrst"; + }; + + pmx_dip_switches: pmx-dip-switches { + marvell,pins = "mpp44", "mpp45", "mpp46", "mpp47"; + marvell,function = "gpio"; + }; + + /* + * Accessible on connector J202. The MPP + * listed below are pin 1-7, pin 8 is unused, + * pin 9 is external reset input and pin 10 is + * ground. + */ + pmx_gpio_header: pmx-gpio-header { + marvell,pins = "mpp17", "mpp7", "mpp29", "mpp28", + "mpp35", "mpp34", "mpp40"; + marvell,function = "gpio"; + }; + + pmx_gpio_init: pmx-init { + marvell,pins = "mpp38"; + marvell,function = "gpio"; + }; + + pmx_usb_oc: pmx-usb-oc { + marvell,pins = "mpp39"; + marvell,function = "gpio"; + }; + + pmx_leds: pmx-leds { + marvell,pins = "mpp41", "mpp42", "mpp43"; + marvell,function = "gpio"; + }; + + pmx_ge1: pmx-ge1 { + marvell,pins = "mpp20", "mpp21", "mpp22", "mpp23", + "mpp24", "mpp25", "mpp26", "mpp27", + "mpp30", "mpp31", "mpp32", "mpp33"; + marvell,function = "ge1"; + }; + }; + }; + + gpio-leds { + compatible = "gpio-leds"; + pinctrl-0 = <&pmx_leds>; + pinctrl-names = "default"; + + led-red { + label = "obsa7:red:stat"; + gpios = <&gpio1 9 1>; + }; + + led-green { + label = "obsa7:green:stat"; + gpios = <&gpio1 10 1>; + }; + + led-yellow { + label = "obsa7:yellow:stat"; + gpios = <&gpio1 11 1>; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + pinctrl-0 = <&pmx_gpio_init>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + button@1 { + label = "Init Button"; + linux,code = <116>; + gpios = <&gpio1 6 0>; + }; + }; +}; + +&nand { + chip-delay = <25>; + status = "okay"; + pinctrl-0 = <&pmx_nand>; + pinctrl-names = "default"; + + partition@0 { + label = "uboot"; + reg = <0x0 0x1c0000>; + }; + + partition@1c0000 { + label = "env"; + reg = <0x1c0000 0x2c0000>; + }; + + partition@480000 { + label = "test"; + reg = <0x480000 0x160000>; + }; + + partition@5e0000 { + label = "conf"; + reg = <0x5e0000 0x540000>; + }; + + partition@b20000 { + label = "linux"; + reg = <0xb20000 0x3d40000>; + }; + + partition@4860000 { + label = "user"; + reg = <0x4860000 0xb7a0000>; + }; +}; + +&mdio { + status = "okay"; + + ethphy0: ethernet-phy@0 { + device_type = "ethernet-phy"; + reg = <0>; + }; + + ethphy1: ethernet-phy@1 { + device_type = "ethernet-phy"; + reg = <1>; + }; +}; + +ð0 { + status = "okay"; + ethernet0-port@0 { + phy-handle = <ðphy0>; + }; +}; + +ð1 { + status = "okay"; + pinctrl-0 = <&pmx_ge1>; + pinctrl-names = "default"; + ethernet1-port@0 { + phy-handle = <ðphy1>; + }; +}; diff --git a/arch/arm/boot/dts/kirkwood-sheevaplug-common.dtsi b/arch/arm/boot/dts/kirkwood-sheevaplug-common.dtsi index 5696b630b70b..1173d7fb31b2 100644 --- a/arch/arm/boot/dts/kirkwood-sheevaplug-common.dtsi +++ b/arch/arm/boot/dts/kirkwood-sheevaplug-common.dtsi @@ -48,27 +48,6 @@ pinctrl-names = "default"; status = "okay"; }; - - nand@3000000 { - pinctrl-0 = <&pmx_nand>; - pinctrl-names = "default"; - status = "okay"; - - partition@0 { - label = "u-boot"; - reg = <0x0000000 0x100000>; - }; - - partition@100000 { - label = "uImage"; - reg = <0x0100000 0x400000>; - }; - - partition@500000 { - label = "root"; - reg = <0x0500000 0x1fb00000>; - }; - }; }; regulators { @@ -92,6 +71,27 @@ }; }; +&nand { + pinctrl-0 = <&pmx_nand>; + pinctrl-names = "default"; + status = "okay"; + + partition@0 { + label = "u-boot"; + reg = <0x0000000 0x100000>; + }; + + partition@100000 { + label = "uImage"; + reg = <0x0100000 0x400000>; + }; + + partition@500000 { + label = "root"; + reg = <0x0500000 0x1fb00000>; + }; +}; + &mdio { status = "okay"; diff --git a/arch/arm/boot/dts/kirkwood-topkick.dts b/arch/arm/boot/dts/kirkwood-topkick.dts index 30842b4ff293..320da677b984 100644 --- a/arch/arm/boot/dts/kirkwood-topkick.dts +++ b/arch/arm/boot/dts/kirkwood-topkick.dts @@ -90,37 +90,6 @@ pinctrl-names = "default"; }; - nand@3000000 { - status = "okay"; - pinctrl-0 = <&pmx_nand>; - pinctrl-names = "default"; - - partition@0 { - label = "u-boot"; - reg = <0x0000000 0x180000>; - }; - - partition@180000 { - label = "u-boot env"; - reg = <0x0180000 0x20000>; - }; - - partition@200000 { - label = "uImage"; - reg = <0x0200000 0x600000>; - }; - - partition@800000 { - label = "uInitrd"; - reg = <0x0800000 0x1000000>; - }; - - partition@1800000 { - label = "rootfs"; - reg = <0x1800000 0xe800000>; - }; - }; - sata@80000 { status = "okay"; nr-ports = <1>; @@ -204,6 +173,37 @@ }; }; +&nand { + status = "okay"; + pinctrl-0 = <&pmx_nand>; + pinctrl-names = "default"; + + partition@0 { + label = "u-boot"; + reg = <0x0000000 0x180000>; + }; + + partition@180000 { + label = "u-boot env"; + reg = <0x0180000 0x20000>; + }; + + partition@200000 { + label = "uImage"; + reg = <0x0200000 0x600000>; + }; + + partition@800000 { + label = "uInitrd"; + reg = <0x0800000 0x1000000>; + }; + + partition@1800000 { + label = "rootfs"; + reg = <0x1800000 0xe800000>; + }; +}; + &mdio { status = "okay"; diff --git a/arch/arm/boot/dts/kirkwood-ts219-6282.dts b/arch/arm/boot/dts/kirkwood-ts219-6282.dts index 9efcd2dc79d3..345562f75891 100644 --- a/arch/arm/boot/dts/kirkwood-ts219-6282.dts +++ b/arch/arm/boot/dts/kirkwood-ts219-6282.dts @@ -6,7 +6,6 @@ / { mbus { - ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000>; pcie-controller { status = "okay"; diff --git a/arch/arm/boot/dts/kirkwood.dtsi b/arch/arm/boot/dts/kirkwood.dtsi index 1335b2e1bed4..8b73c80f1dad 100644 --- a/arch/arm/boot/dts/kirkwood.dtsi +++ b/arch/arm/boot/dts/kirkwood.dtsi @@ -28,16 +28,43 @@ compatible = "marvell,kirkwood-mbus", "simple-bus"; #address-cells = <2>; #size-cells = <1>; + /* If a board file needs to change this ranges it must replace it completely */ + ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000 /* internal-regs */ + MBUS_ID(0x01, 0x2f) 0 0xf4000000 0x10000 /* nand flash */ + MBUS_ID(0x03, 0x01) 0 0xf5000000 0x10000 /* crypto sram */ + >; controller = <&mbusc>; pcie-mem-aperture = <0xe0000000 0x10000000>; /* 256 MiB memory space */ pcie-io-aperture = <0xf2000000 0x100000>; /* 1 MiB I/O space */ + + crypto@0301 { + compatible = "marvell,orion-crypto"; + reg = <MBUS_ID(0xf0, 0x01) 0x30000 0x10000>, + <MBUS_ID(0x03, 0x01) 0 0x800>; + reg-names = "regs", "sram"; + interrupts = <22>; + clocks = <&gate_clk 17>; + status = "okay"; + }; + + nand: nand@012f { + #address-cells = <1>; + #size-cells = <1>; + cle = <0>; + ale = <1>; + bank-width = <1>; + compatible = "marvell,orion-nand"; + reg = <MBUS_ID(0x01, 0x2f) 0 0x400>; + chip-delay = <25>; + /* set partition map and/or chip-delay in board dts */ + clocks = <&gate_clk 7>; + status = "disabled"; + }; }; ocp@f1000000 { compatible = "simple-bus"; - ranges = <0x00000000 0xf1000000 0x0100000 - 0xf4000000 0xf4000000 0x0000400 - 0xf5000000 0xf5000000 0x0000400>; + ranges = <0x00000000 0xf1000000 0x0100000>; #address-cells = <1>; #size-cells = <1>; @@ -193,20 +220,6 @@ status = "okay"; }; - nand@3000000 { - #address-cells = <1>; - #size-cells = <1>; - cle = <0>; - ale = <1>; - bank-width = <1>; - compatible = "marvell,orion-nand"; - reg = <0xf4000000 0x400>; - chip-delay = <25>; - /* set partition map and/or chip-delay in board dts */ - clocks = <&gate_clk 7>; - status = "disabled"; - }; - i2c@11000 { compatible = "marvell,mv64xxx-i2c"; reg = <0x11000 0x20>; @@ -218,16 +231,6 @@ status = "disabled"; }; - crypto@30000 { - compatible = "marvell,orion-crypto"; - reg = <0x30000 0x10000>, - <0xf5000000 0x800>; - reg-names = "regs", "sram"; - interrupts = <22>; - clocks = <&gate_clk 17>; - status = "okay"; - }; - mdio: mdio-bus@72004 { compatible = "marvell,orion-mdio"; #address-cells = <1>; diff --git a/arch/arm/boot/dts/mxs-pinfunc.h b/arch/arm/boot/dts/mxs-pinfunc.h new file mode 100644 index 000000000000..c6da987b20cb --- /dev/null +++ b/arch/arm/boot/dts/mxs-pinfunc.h @@ -0,0 +1,31 @@ +/* + * Header providing constants for i.MX28 pinctrl bindings. + * + * Copyright (C) 2013 Lothar Waßmann <LW@KARO-electronics.de> + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#ifndef __DT_BINDINGS_MXS_PINCTRL_H__ +#define __DT_BINDINGS_MXS_PINCTRL_H__ + +/* fsl,drive-strength property */ +#define MXS_DRIVE_4mA 0 +#define MXS_DRIVE_8mA 1 +#define MXS_DRIVE_12mA 2 +#define MXS_DRIVE_16mA 3 + +/* fsl,voltage property */ +#define MXS_VOLTAGE_LOW 0 +#define MXS_VOLTAGE_HIGH 1 + +/* fsl,pull-up property */ +#define MXS_PULL_DISABLE 0 +#define MXS_PULL_ENABLE 1 + +#endif /* __DT_BINDINGS_MXS_PINCTRL_H__ */ diff --git a/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi b/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi new file mode 100644 index 000000000000..9c18adf788f7 --- /dev/null +++ b/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi @@ -0,0 +1,52 @@ +/* + * Common file for GPMC connected smsc911x on omaps + * + * Note that the board specifc DTS file needs to specify + * ranges, pinctrl, reg, interrupt parent and interrupts. + */ + +/ { + vddvario: regulator-vddvario { + compatible = "regulator-fixed"; + regulator-name = "vddvario"; + regulator-always-on; + }; + + vdd33a: regulator-vdd33a { + compatible = "regulator-fixed"; + regulator-name = "vdd33a"; + regulator-always-on; + }; +}; + +&gpmc { + ethernet@gpmc { + compatible = "smsc,lan9221", "smsc,lan9115"; + bank-width = <2>; + gpmc,mux-add-data; + gpmc,cs-on-ns = <0>; + gpmc,cs-rd-off-ns = <186>; + gpmc,cs-wr-off-ns = <186>; + gpmc,adv-on-ns = <12>; + gpmc,adv-rd-off-ns = <48>; + gpmc,adv-wr-off-ns = <48>; + gpmc,oe-on-ns = <54>; + gpmc,oe-off-ns = <168>; + gpmc,we-on-ns = <54>; + gpmc,we-off-ns = <168>; + gpmc,rd-cycle-ns = <186>; + gpmc,wr-cycle-ns = <186>; + gpmc,access-ns = <114>; + gpmc,page-burst-access-ns = <6>; + gpmc,bus-turnaround-ns = <12>; + gpmc,cycle2cycle-delay-ns = <18>; + gpmc,wr-data-mux-bus-ns = <90>; + gpmc,wr-access-ns = <186>; + gpmc,cycle2cycle-samecsen; + gpmc,cycle2cycle-diffcsen; + vmmc-supply = <&vddvario>; + vmmc_aux-supply = <&vdd33a>; + reg-io-width = <4>; + smsc,save-mac-address; + }; +}; diff --git a/arch/arm/boot/dts/omap-zoom-common.dtsi b/arch/arm/boot/dts/omap-zoom-common.dtsi new file mode 100644 index 000000000000..b0ee342598f0 --- /dev/null +++ b/arch/arm/boot/dts/omap-zoom-common.dtsi @@ -0,0 +1,33 @@ +/* + * Common features on the Zoom debug board + */ + +#include "omap-gpmc-smsc911x.dtsi" + +&gpmc { + ranges = <3 0 0x10000000 0x00000400>, + <7 0 0x2c000000 0x01000000>; + + /* + * Four port TL16CP754C serial port on GPMC, + * they probably share the same GPIO IRQ + * REVISIT: Add timing support from slls644g.pdf + */ + 8250@3,0 { + compatible = "ns16550a"; + reg = <3 0 0x100>; + bank-width = <2>; + reg-shift = <1>; + reg-io-width = <1>; + interrupt-parent = <&gpio4>; + interrupts = <6 IRQ_TYPE_EDGE_RISING>; /* gpio102 */ + clock-frequency = <1843200>; + current-speed = <115200>; + }; + + ethernet@gpmc { + reg = <7 0 0xff>; + interrupt-parent = <&gpio5>; + interrupts = <30 IRQ_TYPE_LEVEL_LOW>; /* gpio158 */ + }; +}; diff --git a/arch/arm/boot/dts/omap2420-h4.dts b/arch/arm/boot/dts/omap2420-h4.dts index 224c08f472f4..34cdecb4fdda 100644 --- a/arch/arm/boot/dts/omap2420-h4.dts +++ b/arch/arm/boot/dts/omap2420-h4.dts @@ -50,15 +50,15 @@ label = "bootloader"; reg = <0 0x20000>; }; - partition@0x20000 { + partition@20000 { label = "params"; reg = <0x20000 0x20000>; }; - partition@0x40000 { + partition@40000 { label = "kernel"; reg = <0x40000 0x200000>; }; - partition@0x240000 { + partition@240000 { label = "file-system"; reg = <0x240000 0x3dc0000>; }; diff --git a/arch/arm/boot/dts/omap3-beagle-xm.dts b/arch/arm/boot/dts/omap3-beagle-xm.dts index 2816bf612672..31a632f7effb 100644 --- a/arch/arm/boot/dts/omap3-beagle-xm.dts +++ b/arch/arm/boot/dts/omap3-beagle-xm.dts @@ -69,6 +69,23 @@ }; }; + + /* HS USB Port 2 Power */ + hsusb2_power: hsusb2_power_reg { + compatible = "regulator-fixed"; + regulator-name = "hsusb2_vbus"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&twl_gpio 18 0>; /* GPIO LEDA */ + startup-delay-us = <70000>; + }; + + /* HS USB Host PHY on PORT 2 */ + hsusb2_phy: hsusb2_phy { + compatible = "usb-nop-xceiv"; + reset-gpios = <&gpio5 19 GPIO_ACTIVE_LOW>; /* gpio_147 */ + vcc-supply = <&hsusb2_power>; + }; }; &omap3_pmx_wkup { @@ -79,6 +96,37 @@ }; }; +&omap3_pmx_core { + pinctrl-names = "default"; + pinctrl-0 = < + &hsusbb2_pins + >; + + uart3_pins: pinmux_uart3_pins { + pinctrl-single,pins = < + 0x16e (PIN_INPUT | PIN_OFF_WAKEUPENABLE | MUX_MODE0) /* uart3_rx_irrx.uart3_rx_irrx */ + 0x170 (PIN_OUTPUT | MUX_MODE0) /* uart3_tx_irtx.uart3_tx_irtx OUTPUT | MODE0 */ + >; + }; + + hsusbb2_pins: pinmux_hsusbb2_pins { + pinctrl-single,pins = < + 0x5c0 (PIN_OUTPUT | MUX_MODE3) /* etk_d10.hsusb2_clk */ + 0x5c2 (PIN_OUTPUT | MUX_MODE3) /* etk_d11.hsusb2_stp */ + 0x5c4 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d12.hsusb2_dir */ + 0x5c6 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d13.hsusb2_nxt */ + 0x5c8 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d14.hsusb2_data0 */ + 0x5cA (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d15.hsusb2_data1 */ + 0x1a4 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi1_cs3.hsusb2_data2 */ + 0x1a6 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_clk.hsusb2_data7 */ + 0x1a8 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_simo.hsusb2_data4 */ + 0x1aa (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_somi.hsusb2_data5 */ + 0x1ac (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_cs0.hsusb2_data6 */ + 0x1ae (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_cs1.hsusb2_data3 */ + >; + }; +}; + &i2c1 { clock-frequency = <2600000>; @@ -144,19 +192,12 @@ &usb_otg_hs { interface-type = <0>; usb-phy = <&usb2_phy>; + phys = <&usb2_phy>; + phy-names = "usb2-phy"; mode = <3>; power = <50>; }; -&omap3_pmx_core { - uart3_pins: pinmux_uart3_pins { - pinctrl-single,pins = < - 0x16e (PIN_INPUT | PIN_OFF_WAKEUPENABLE | MUX_MODE0) /* uart3_rx_irrx.uart3_rx_irrx */ - 0x170 (PIN_OUTPUT | MUX_MODE0) /* uart3_tx_irtx.uart3_tx_irtx OUTPUT | MODE0 */ - >; - }; -}; - &uart3 { pinctrl-names = "default"; pinctrl-0 = <&uart3_pins>; @@ -166,3 +207,11 @@ pinctrl-names = "default"; pinctrl-0 = <&gpio1_pins>; }; + +&usbhshost { + port2-mode = "ehci-phy"; +}; + +&usbhsehci { + phys = <0 &hsusb2_phy>; +}; diff --git a/arch/arm/boot/dts/omap3-beagle.dts b/arch/arm/boot/dts/omap3-beagle.dts index dfd83103657a..fa532aaacc68 100644 --- a/arch/arm/boot/dts/omap3-beagle.dts +++ b/arch/arm/boot/dts/omap3-beagle.dts @@ -44,17 +44,6 @@ }; }; - /* HS USB Port 2 RESET */ - hsusb2_reset: hsusb2_reset_reg { - compatible = "regulator-fixed"; - regulator-name = "hsusb2_reset"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - gpio = <&gpio5 19 0>; /* gpio_147 */ - startup-delay-us = <70000>; - enable-active-high; - }; - /* HS USB Port 2 Power */ hsusb2_power: hsusb2_power_reg { compatible = "regulator-fixed"; @@ -68,7 +57,7 @@ /* HS USB Host PHY on PORT 2 */ hsusb2_phy: hsusb2_phy { compatible = "usb-nop-xceiv"; - reset-supply = <&hsusb2_reset>; + reset-gpios = <&gpio5 19 GPIO_ACTIVE_LOW>; /* gpio_147 */ vcc-supply = <&hsusb2_power>; }; @@ -101,18 +90,18 @@ hsusbb2_pins: pinmux_hsusbb2_pins { pinctrl-single,pins = < - 0x5c0 (PIN_OUTPUT | MUX_MODE3) /* usbb2_ulpitll_clk.usbb1_ulpiphy_clk */ - 0x5c2 (PIN_OUTPUT | MUX_MODE3) /* usbb2_ulpitll_clk.usbb1_ulpiphy_stp */ - 0x5c4 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* usbb2_ulpitll_clk.usbb1_ulpiphy_dir */ - 0x5c6 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* usbb2_ulpitll_clk.usbb1_ulpiphy_nxt */ - 0x5c8 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* usbb2_ulpitll_clk.usbb1_ulpiphy_dat0 */ - 0x5cA (PIN_INPUT_PULLDOWN | MUX_MODE3) /* usbb2_ulpitll_clk.usbb1_ulpiphy_dat1 */ - 0x1a4 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* usbb2_ulpitll_clk.usbb1_ulpiphy_dat2 */ - 0x1a6 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* usbb2_ulpitll_clk.usbb1_ulpiphy_dat3 */ - 0x1a8 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* usbb2_ulpitll_clk.usbb1_ulpiphy_dat4 */ - 0x1aa (PIN_INPUT_PULLDOWN | MUX_MODE3) /* usbb2_ulpitll_clk.usbb1_ulpiphy_dat5 */ - 0x1ac (PIN_INPUT_PULLDOWN | MUX_MODE3) /* usbb2_ulpitll_clk.usbb1_ulpiphy_dat6 */ - 0x1ae (PIN_INPUT_PULLDOWN | MUX_MODE3) /* usbb2_ulpitll_clk.usbb1_ulpiphy_dat7 */ + 0x5c0 (PIN_OUTPUT | MUX_MODE3) /* etk_d10.hsusb2_clk */ + 0x5c2 (PIN_OUTPUT | MUX_MODE3) /* etk_d11.hsusb2_stp */ + 0x5c4 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d12.hsusb2_dir */ + 0x5c6 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d13.hsusb2_nxt */ + 0x5c8 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d14.hsusb2_data0 */ + 0x5cA (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d15.hsusb2_data1 */ + 0x1a4 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi1_cs3.hsusb2_data2 */ + 0x1a6 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_clk.hsusb2_data7 */ + 0x1a8 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_simo.hsusb2_data4 */ + 0x1aa (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_somi.hsusb2_data5 */ + 0x1ac (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_cs0.hsusb2_data6 */ + 0x1ae (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_cs1.hsusb2_data3 */ >; }; @@ -180,3 +169,12 @@ pinctrl-names = "default"; pinctrl-0 = <&gpio1_pins>; }; + +&usb_otg_hs { + interface-type = <0>; + usb-phy = <&usb2_phy>; + phys = <&usb2_phy>; + phy-names = "usb2-phy"; + mode = <3>; + power = <50>; +}; diff --git a/arch/arm/boot/dts/omap3-devkit8000.dts b/arch/arm/boot/dts/omap3-devkit8000.dts index 7ef282795dd4..4665421bb7bc 100644 --- a/arch/arm/boot/dts/omap3-devkit8000.dts +++ b/arch/arm/boot/dts/omap3-devkit8000.dts @@ -125,7 +125,7 @@ nand-bus-width = <16>; gpmc,device-nand; - gpmc,sync-clki-ps = <0>; + gpmc,sync-clk-ps = <0>; gpmc,cs-on-ns = <0>; gpmc,cs-rd-off-ns = <44>; gpmc,cs-wr-off-ns = <44>; diff --git a/arch/arm/boot/dts/omap3-evm-37xx.dts b/arch/arm/boot/dts/omap3-evm-37xx.dts new file mode 100644 index 000000000000..4df68ad3736a --- /dev/null +++ b/arch/arm/boot/dts/omap3-evm-37xx.dts @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.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 + * published by the Free Software Foundation. + */ +/dts-v1/; + +#include "omap36xx.dtsi" +#include "omap3-evm-common.dtsi" + + +/ { + model = "TI OMAP37XX EVM (TMDSEVM3730)"; + compatible = "ti,omap3-evm-37xx", "ti,omap36xx"; + + memory { + device_type = "memory"; + reg = <0x80000000 0x10000000>; /* 256 MB */ + }; + + wl12xx_vmmc: wl12xx_vmmc { + pinctrl-names = "default"; + pinctrl-0 = <&wl12xx_gpio>; + }; +}; + +&omap3_pmx_core { + mmc1_pins: pinmux_mmc1_pins { + pinctrl-single,pins = < + 0x114 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* sdmmc1_clk.sdmmc1_clk */ + 0x116 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_cmd.sdmmc1_cmd */ + 0x118 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat0.sdmmc1_dat0 */ + 0x11a (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat1.sdmmc1_dat1 */ + 0x11c (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat2.sdmmc1_dat2 */ + 0x11e (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat3.sdmmc1_dat3 */ + 0x120 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat4.sdmmc1_dat4 */ + 0x122 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat5.sdmmc1_dat5 */ + 0x124 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat6.sdmmc1_dat6 */ + 0x126 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat7.sdmmc1_dat7 */ + >; + }; + + /* NOTE: Clocked externally, needs INPUT also for sdmmc2_clk.sdmmc2_clk */ + mmc2_pins: pinmux_mmc2_pins { + pinctrl-single,pins = < + 0x128 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_clk.sdmmc2_clk */ + 0x12a (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_cmd.sdmmc2_cmd */ + 0x12c (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat0.sdmmc2_dat0 */ + 0x12e (WAKEUP_EN | PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat1.sdmmc2_dat1 */ + 0x130 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat2.sdmmc2_dat2 */ + 0x132 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat3.sdmmc2_dat3 */ + >; + }; + + uart3_pins: pinmux_uart3_pins { + pinctrl-single,pins = < + 0x16e (WAKEUP_EN | PIN_INPUT | MUX_MODE0) /* uart3_rx_irrx.uart3_rx_irrx */ + 0x170 (PIN_OUTPUT | MUX_MODE0) /* uart3_tx_irtx.uart3_tx_irtx */ + >; + }; + + wl12xx_gpio: pinmux_wl12xx_gpio { + pinctrl-single,pins = < + 0x150 (PIN_OUTPUT | MUX_MODE4) /* uart1_cts.gpio_150 */ + 0x14e (PIN_INPUT | MUX_MODE4) /* uart1_rts.gpio_149 */ + >; + }; + + smsc911x_pins: pinmux_smsc911x_pins { + pinctrl-single,pins = < + 0x1a2 (PIN_INPUT | MUX_MODE4) /* mcspi1_cs2.gpio_176 */ + >; + }; +}; + +&mmc1 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc1_pins>; +}; + +&mmc2 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc2_pins>; +}; + +&mmc3 { + status = "disabled"; +}; + +&uart3 { + pinctrl-names = "default"; + pinctrl-0 = <&uart3_pins>; +}; + +&gpmc { + ranges = <0 0 0x00000000 0x20000000>, + <5 0 0x2c000000 0x01000000>; + + nand@0,0 { + linux,mtd-name= "hynix,h8kds0un0mer-4em"; + reg = <0 0 0>; + nand-bus-width = <16>; + ti,nand-ecc-opt = "bch8"; + + gpmc,sync-clk-ps = <0>; + gpmc,cs-on-ns = <0>; + gpmc,cs-rd-off-ns = <44>; + gpmc,cs-wr-off-ns = <44>; + gpmc,adv-on-ns = <6>; + gpmc,adv-rd-off-ns = <34>; + gpmc,adv-wr-off-ns = <44>; + gpmc,we-off-ns = <40>; + gpmc,oe-off-ns = <54>; + gpmc,access-ns = <64>; + gpmc,rd-cycle-ns = <82>; + gpmc,wr-cycle-ns = <82>; + gpmc,wr-access-ns = <40>; + gpmc,wr-data-mux-bus-ns = <0>; + + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "X-Loader"; + reg = <0 0x80000>; + }; + partition@0x80000 { + label = "U-Boot"; + reg = <0x80000 0x1c0000>; + }; + partition@0x1c0000 { + label = "Environment"; + reg = <0x240000 0x40000>; + }; + partition@0x280000 { + label = "Kernel"; + reg = <0x280000 0x500000>; + }; + partition@0x780000 { + label = "Filesystem"; + reg = <0x780000 0x1f880000>; + }; + }; + + ethernet@gpmc { + pinctrl-names = "default"; + pinctrl-0 = <&smsc911x_pins>; + }; +}; diff --git a/arch/arm/boot/dts/omap3-evm-common.dtsi b/arch/arm/boot/dts/omap3-evm-common.dtsi new file mode 100644 index 000000000000..3007e79c9cd6 --- /dev/null +++ b/arch/arm/boot/dts/omap3-evm-common.dtsi @@ -0,0 +1,96 @@ +/* + * Common support for omap3 EVM boards + */ + +#include "omap-gpmc-smsc911x.dtsi" + +/ { + cpus { + cpu@0 { + cpu0-supply = <&vcc>; + }; + }; + + leds { + compatible = "gpio-leds"; + ledb { + label = "omap3evm::ledb"; + gpios = <&twl_gpio 19 GPIO_ACTIVE_HIGH>; /* LEDB */ + linux,default-trigger = "default-on"; + }; + }; + + wl12xx_vmmc: wl12xx_vmmc { + compatible = "regulator-fixed"; + regulator-name = "vwl1271"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + gpio = <&gpio5 22 0>; /* gpio150 */ + startup-delay-us = <70000>; + enable-active-high; + vin-supply = <&vmmc2>; + }; +}; + +&i2c1 { + clock-frequency = <2600000>; + + twl: twl@48 { + reg = <0x48>; + interrupts = <7>; /* SYS_NIRQ cascaded to intc */ + interrupt-parent = <&intc>; + }; +}; + +#include "twl4030.dtsi" +#include "twl4030_omap3.dtsi" + +&i2c2 { + clock-frequency = <400000>; +}; + +&i2c3 { + clock-frequency = <400000>; + + /* + * TVP5146 Video decoder-in for analog input support. + */ + tvp5146@5c { + compatible = "ti,tvp5146m2"; + reg = <0x5c>; + }; +}; + +&mmc1 { + vmmc-supply = <&vmmc1>; + vmmc_aux-supply = <&vsim>; + bus-width = <8>; +}; + +&mmc2 { + vmmc-supply = <&wl12xx_vmmc>; + non-removable; + bus-width = <4>; + cap-power-off-card; +}; + +&twl_gpio { + ti,use-leds; +}; + +&usb_otg_hs { + interface-type = <0>; + usb-phy = <&usb2_phy>; + phys = <&usb2_phy>; + phy-names = "usb2-phy"; + mode = <3>; + power = <50>; +}; + +&gpmc { + ethernet@gpmc { + interrupt-parent = <&gpio6>; + interrupts = <16 8>; + reg = <5 0 0xff>; + }; +}; diff --git a/arch/arm/boot/dts/omap3-evm.dts b/arch/arm/boot/dts/omap3-evm.dts index 7d4329d179c4..e10dcd0fa539 100644 --- a/arch/arm/boot/dts/omap3-evm.dts +++ b/arch/arm/boot/dts/omap3-evm.dts @@ -8,68 +8,14 @@ /dts-v1/; #include "omap34xx.dtsi" +#include "omap3-evm-common.dtsi" / { - model = "TI OMAP3 EVM (OMAP3530, AM/DM37x)"; + model = "TI OMAP35XX EVM (TMDSEVM3530)"; compatible = "ti,omap3-evm", "ti,omap3"; - cpus { - cpu@0 { - cpu0-supply = <&vcc>; - }; - }; - memory { device_type = "memory"; reg = <0x80000000 0x10000000>; /* 256 MB */ }; - - leds { - compatible = "gpio-leds"; - ledb { - label = "omap3evm::ledb"; - gpios = <&twl_gpio 19 GPIO_ACTIVE_HIGH>; /* LEDB */ - linux,default-trigger = "default-on"; - }; - }; -}; - -&i2c1 { - clock-frequency = <2600000>; - - twl: twl@48 { - reg = <0x48>; - interrupts = <7>; /* SYS_NIRQ cascaded to intc */ - interrupt-parent = <&intc>; - }; -}; - -#include "twl4030.dtsi" -#include "twl4030_omap3.dtsi" - -&i2c2 { - clock-frequency = <400000>; -}; - -&i2c3 { - clock-frequency = <400000>; - - /* - * TVP5146 Video decoder-in for analog input support. - */ - tvp5146@5c { - compatible = "ti,tvp5146m2"; - reg = <0x5c>; - }; -}; - -&twl_gpio { - ti,use-leds; -}; - -&usb_otg_hs { - interface-type = <0>; - usb-phy = <&usb2_phy>; - mode = <3>; - power = <50>; }; diff --git a/arch/arm/boot/dts/omap3-gta04.dts b/arch/arm/boot/dts/omap3-gta04.dts new file mode 100644 index 000000000000..b9b55c95a566 --- /dev/null +++ b/arch/arm/boot/dts/omap3-gta04.dts @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2013 Marek Belisko <marek@goldelico.com> + * + * Based on omap3-beagle-xm.dts + * + * 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. + */ +/dts-v1/; + +#include "omap36xx.dtsi" + +/ { + model = "OMAP3 GTA04"; + compatible = "ti,omap3-gta04", "ti,omap3"; + + cpus { + cpu@0 { + cpu0-supply = <&vcc>; + }; + }; + + memory { + device_type = "memory"; + reg = <0x80000000 0x20000000>; /* 512 MB */ + }; + + gpio-keys { + compatible = "gpio-keys"; + + aux-button { + label = "aux"; + linux,code = <169>; + gpios = <&gpio1 7 GPIO_ACTIVE_LOW>; + gpio-key,wakeup; + }; + }; +}; + +&omap3_pmx_core { + uart1_pins: pinmux_uart1_pins { + pinctrl-single,pins = < + 0x152 (PIN_INPUT | MUX_MODE0) /* uart1_rx.uart1_rx */ + 0x14c (PIN_OUTPUT |MUX_MODE0) /* uart1_tx.uart1_tx */ + >; + }; + + uart2_pins: pinmux_uart2_pins { + pinctrl-single,pins = < + 0x14a (PIN_INPUT | MUX_MODE0) /* uart2_rx.uart2_rx */ + 0x148 (PIN_OUTPUT | MUX_MODE0) /* uart2_tx.uart2_tx */ + >; + }; + + uart3_pins: pinmux_uart3_pins { + pinctrl-single,pins = < + 0x16e (PIN_INPUT | MUX_MODE0) /* uart3_rx.uart3_rx */ + 0x170 (PIN_OUTPUT | MUX_MODE0) /* uart3_tx.uart3_tx */ + >; + }; + + mmc1_pins: pinmux_mmc1_pins { + pinctrl-single,pins = < + 0x114 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_clk.sdmmc1_clk */ + 0x116 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_cmd.sdmmc1_cmd */ + 0x118 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat0.sdmmc1_dat0 */ + 0x11a (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat1.sdmmc1_dat1 */ + 0x11c (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat2.sdmmc1_dat2 */ + 0x11e (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat3.sdmmc1_dat3 */ + >; + }; +}; + +&i2c1 { + clock-frequency = <2600000>; + + twl: twl@48 { + reg = <0x48>; + interrupts = <7>; /* SYS_NIRQ cascaded to intc */ + interrupt-parent = <&intc>; + }; +}; + +#include "twl4030.dtsi" +#include "twl4030_omap3.dtsi" + +&i2c2 { + clock-frequency = <400000>; + + /* pressure sensor */ + bmp085@77 { + compatible = "bosch,bmp085"; + reg = <0x77>; + }; + + /* leds */ + tca6507@45 { + compatible = "ti,tca6507"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x45>; + + gta04_led0: red_aux@0 { + label = "gta04:red:aux"; + reg = <0x0>; + }; + + gta04_led1: green_aux@1 { + label = "gta04:green:aux"; + reg = <0x1>; + }; + + gta04_led3: red_power@3 { + label = "gta04:red:power"; + reg = <0x3>; + linux,default-trigger = "default-on"; + }; + + gta04_led4: green_power@4 { + label = "gta04:green:power"; + reg = <0x4>; + }; + }; +}; + +&i2c3 { + clock-frequency = <100000>; +}; + +&usb_otg_hs { + interface-type = <0>; + usb-phy = <&usb2_phy>; + phys = <&usb2_phy>; + phy-names = "usb2-phy"; + mode = <3>; + power = <50>; +}; + +&mmc1 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc1_pins>; + vmmc-supply = <&vmmc1>; + vmmc_aux-supply = <&vsim>; + bus-width = <4>; +}; + +&mmc2 { + status = "disabled"; +}; + +&mmc3 { + status = "disabled"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins>; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&uart2_pins>; +}; + +&uart3 { + pinctrl-names = "default"; + pinctrl-0 = <&uart3_pins>; +}; + diff --git a/arch/arm/boot/dts/omap3-igep.dtsi b/arch/arm/boot/dts/omap3-igep.dtsi index 2326d11462a5..ba1e58b7b7e3 100644 --- a/arch/arm/boot/dts/omap3-igep.dtsi +++ b/arch/arm/boot/dts/omap3-igep.dtsi @@ -77,6 +77,8 @@ 0x1a2 (PIN_INPUT | MUX_MODE4) /* mcspi1_cs2.gpio_176 */ >; }; + + leds_pins: pinmux_leds_pins { }; }; &i2c1 { @@ -141,3 +143,12 @@ &twl_gpio { ti,use-leds; }; + +&usb_otg_hs { + interface-type = <0>; + usb-phy = <&usb2_phy>; + phys = <&usb2_phy>; + phy-names = "usb2-phy"; + mode = <3>; + power = <50>; +}; diff --git a/arch/arm/boot/dts/omap3-igep0020.dts b/arch/arm/boot/dts/omap3-igep0020.dts index e8c48284587c..d5cc79267250 100644 --- a/arch/arm/boot/dts/omap3-igep0020.dts +++ b/arch/arm/boot/dts/omap3-igep0020.dts @@ -10,13 +10,17 @@ */ #include "omap3-igep.dtsi" +#include "omap-gpmc-smsc911x.dtsi" / { model = "IGEPv2"; compatible = "isee,omap3-igep0020", "ti,omap3"; leds { + pinctrl-names = "default"; + pinctrl-0 = <&leds_pins>; compatible = "gpio-leds"; + boot { label = "omap3:green:boot"; gpios = <&gpio1 26 GPIO_ACTIVE_HIGH>; @@ -41,19 +45,56 @@ }; }; - vddvario: regulator-vddvario { - compatible = "regulator-fixed"; - regulator-name = "vddvario"; - regulator-always-on; + /* HS USB Port 1 Power */ + hsusb1_power: hsusb1_power_reg { + compatible = "regulator-fixed"; + regulator-name = "hsusb1_vbus"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&twl_gpio 18 GPIO_ACTIVE_LOW>; /* GPIO LEDA */ + startup-delay-us = <70000>; + }; + + /* HS USB Host PHY on PORT 1 */ + hsusb1_phy: hsusb1_phy { + compatible = "usb-nop-xceiv"; + reset-gpios = <&gpio1 24 GPIO_ACTIVE_LOW>; /* gpio_24 */ + vcc-supply = <&hsusb1_power>; }; +}; - vdd33a: regulator-vdd33a { - compatible = "regulator-fixed"; - regulator-name = "vdd33a"; - regulator-always-on; +&omap3_pmx_core { + pinctrl-names = "default"; + pinctrl-0 = < + &hsusbb1_pins + >; + + hsusbb1_pins: pinmux_hsusbb1_pins { + pinctrl-single,pins = < + 0x5aa (PIN_OUTPUT | MUX_MODE3) /* etk_ctl.hsusb1_clk */ + 0x5a8 (PIN_OUTPUT | MUX_MODE3) /* etk_clk.hsusb1_stp */ + 0x5bc (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d8.hsusb1_dir */ + 0x5be (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d9.hsusb1_nxt */ + 0x5ac (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d0.hsusb1_data0 */ + 0x5ae (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d1.hsusb1_data1 */ + 0x5b0 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d2.hsusb1_data2 */ + 0x5b2 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d3.hsusb1_data7 */ + 0x5b4 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d4.hsusb1_data4 */ + 0x5b6 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d5.hsusb1_data5 */ + 0x5b8 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d6.hsusb1_data6 */ + 0x5ba (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d7.hsusb1_data3 */ + >; }; }; +&leds_pins { + pinctrl-single,pins = < + 0x5c4 (PIN_OUTPUT | MUX_MODE4) /* etk_d12.gpio_26 */ + 0x5c6 (PIN_OUTPUT | MUX_MODE4) /* etk_d13.gpio_27 */ + 0x5c8 (PIN_OUTPUT | MUX_MODE4) /* etk_d14.gpio_28 */ + >; +}; + &i2c3 { clock-frequency = <100000>; @@ -99,59 +140,37 @@ label = "SPL"; reg = <0 0x100000>; }; - partition@0x80000 { + partition@80000 { label = "U-Boot"; reg = <0x100000 0x180000>; }; - partition@0x1c0000 { + partition@1c0000 { label = "Environment"; reg = <0x280000 0x100000>; }; - partition@0x280000 { + partition@280000 { label = "Kernel"; reg = <0x380000 0x300000>; }; - partition@0x780000 { + partition@780000 { label = "Filesystem"; reg = <0x680000 0x1f980000>; }; }; - ethernet@5,0 { + ethernet@gpmc { pinctrl-names = "default"; pinctrl-0 = <&smsc911x_pins>; - compatible = "smsc,lan9221", "smsc,lan9115"; reg = <5 0 0xff>; - bank-width = <2>; - - gpmc,mux-add-data; - gpmc,cs-on-ns = <0>; - gpmc,cs-rd-off-ns = <186>; - gpmc,cs-wr-off-ns = <186>; - gpmc,adv-on-ns = <12>; - gpmc,adv-rd-off-ns = <48>; - gpmc,adv-wr-off-ns = <48>; - gpmc,oe-on-ns = <54>; - gpmc,oe-off-ns = <168>; - gpmc,we-on-ns = <54>; - gpmc,we-off-ns = <168>; - gpmc,rd-cycle-ns = <186>; - gpmc,wr-cycle-ns = <186>; - gpmc,access-ns = <114>; - gpmc,page-burst-access-ns = <6>; - gpmc,bus-turnaround-ns = <12>; - gpmc,cycle2cycle-delay-ns = <18>; - gpmc,wr-data-mux-bus-ns = <90>; - gpmc,wr-access-ns = <186>; - gpmc,cycle2cycle-samecsen; - gpmc,cycle2cycle-diffcsen; - interrupt-parent = <&gpio6>; - interrupts = <16 8>; - vmmc-supply = <&vddvario>; - vmmc_aux-supply = <&vdd33a>; - reg-io-width = <4>; - - smsc,save-mac-address; + interrupts = <16 IRQ_TYPE_LEVEL_LOW>; }; }; + +&usbhshost { + port1-mode = "ehci-phy"; +}; + +&usbhsehci { + phys = <&hsusb1_phy>; +}; diff --git a/arch/arm/boot/dts/omap3-igep0030.dts b/arch/arm/boot/dts/omap3-igep0030.dts index 644d05383836..525e6d9b0978 100644 --- a/arch/arm/boot/dts/omap3-igep0030.dts +++ b/arch/arm/boot/dts/omap3-igep0030.dts @@ -16,7 +16,10 @@ compatible = "isee,omap3-igep0030", "ti,omap3"; leds { + pinctrl-names = "default"; + pinctrl-0 = <&leds_pins>; compatible = "gpio-leds"; + boot { label = "omap3:green:boot"; gpios = <&twl_gpio 13 GPIO_ACTIVE_LOW>; @@ -43,6 +46,12 @@ }; }; +&leds_pins { + pinctrl-single,pins = < + 0x5b0 (PIN_OUTPUT | MUX_MODE4) /* etk_d2.gpio_16 */ + >; +}; + &gpmc { ranges = <0 0 0x00000000 0x20000000>; @@ -74,19 +83,19 @@ label = "SPL"; reg = <0 0x100000>; }; - partition@0x80000 { + partition@80000 { label = "U-Boot"; reg = <0x100000 0x180000>; }; - partition@0x1c0000 { + partition@1c0000 { label = "Environment"; reg = <0x280000 0x100000>; }; - partition@0x280000 { + partition@280000 { label = "Kernel"; reg = <0x380000 0x300000>; }; - partition@0x780000 { + partition@780000 { label = "Filesystem"; reg = <0x680000 0x1f980000>; }; diff --git a/arch/arm/boot/dts/omap3-n9.dts b/arch/arm/boot/dts/omap3-n9.dts new file mode 100644 index 000000000000..39828ce464ee --- /dev/null +++ b/arch/arm/boot/dts/omap3-n9.dts @@ -0,0 +1,18 @@ +/* + * omap3-n9.dts - Device Tree file for Nokia N9 + * + * Written by: Aaro Koskinen <aaro.koskinen@iki.fi> + * + * 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. + */ + +/dts-v1/; + +#include "omap3-n950-n9.dtsi" + +/ { + model = "Nokia N9"; + compatible = "nokia,omap3-n9", "ti,omap3"; +}; diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts new file mode 100644 index 000000000000..c4f20bfe4cce --- /dev/null +++ b/arch/arm/boot/dts/omap3-n900.dts @@ -0,0 +1,484 @@ +/* + * Copyright (C) 2013 Pavel Machek <pavel@ucw.cz> + * Copyright 2013 Aaro Koskinen <aaro.koskinen@iki.fi> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 (or later) as + * published by the Free Software Foundation. + */ + +/dts-v1/; + +#include "omap34xx.dtsi" + +/ { + model = "Nokia N900"; + compatible = "nokia,omap3-n900", "ti,omap3"; + + cpus { + cpu@0 { + cpu0-supply = <&vcc>; + }; + }; + + memory { + device_type = "memory"; + reg = <0x80000000 0x10000000>; /* 256 MB */ + }; + + gpio_keys { + compatible = "gpio-keys"; + + camera_lens_cover { + label = "Camera Lens Cover"; + gpios = <&gpio4 14 GPIO_ACTIVE_LOW>; /* 110 */ + linux,input-type = <5>; /* EV_SW */ + linux,code = <0x09>; /* SW_CAMERA_LENS_COVER */ + gpio-key,wakeup; + }; + + camera_focus { + label = "Camera Focus"; + gpios = <&gpio3 4 GPIO_ACTIVE_LOW>; /* 68 */ + linux,code = <0x210>; /* KEY_CAMERA_FOCUS */ + gpio-key,wakeup; + }; + + camera_capture { + label = "Camera Capture"; + gpios = <&gpio3 5 GPIO_ACTIVE_LOW>; /* 69 */ + linux,code = <0xd4>; /* KEY_CAMERA */ + gpio-key,wakeup; + }; + + lock_button { + label = "Lock Button"; + gpios = <&gpio4 17 GPIO_ACTIVE_LOW>; /* 113 */ + linux,code = <0x98>; /* KEY_SCREENLOCK */ + gpio-key,wakeup; + }; + + keypad_slide { + label = "Keypad Slide"; + gpios = <&gpio3 7 GPIO_ACTIVE_LOW>; /* 71 */ + linux,input-type = <5>; /* EV_SW */ + linux,code = <0x0a>; /* SW_KEYPAD_SLIDE */ + gpio-key,wakeup; + }; + + proximity_sensor { + label = "Proximity Sensor"; + gpios = <&gpio3 25 GPIO_ACTIVE_HIGH>; /* 89 */ + linux,input-type = <5>; /* EV_SW */ + linux,code = <0x0b>; /* SW_FRONT_PROXIMITY */ + }; + }; + +}; + +&omap3_pmx_core { + pinctrl-names = "default"; + + uart2_pins: pinmux_uart2_pins { + pinctrl-single,pins = < + 0x14a (PIN_INPUT | MUX_MODE0) /* uart2_rx */ + 0x148 (PIN_OUTPUT | MUX_MODE0) /* uart2_tx */ + >; + }; + + uart3_pins: pinmux_uart3_pins { + pinctrl-single,pins = < + 0x16e (PIN_INPUT | MUX_MODE0) /* uart3_rx */ + 0x170 (PIN_OUTPUT | MUX_MODE0) /* uart3_tx */ + >; + }; + + i2c1_pins: pinmux_i2c1_pins { + pinctrl-single,pins = < + 0x18a (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_scl */ + 0x18c (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_sda */ + >; + }; + + i2c2_pins: pinmux_i2c2_pins { + pinctrl-single,pins = < + 0x18e (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c2_scl */ + 0x190 (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c2_sda */ + >; + }; + + i2c3_pins: pinmux_i2c3_pins { + pinctrl-single,pins = < + 0x192 (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_scl */ + 0x194 (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_sda */ + >; + }; + + mmc1_pins: pinmux_mmc1_pins { + pinctrl-single,pins = < + 0x114 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_clk */ + 0x116 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_cmd */ + 0x118 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat0 */ + 0x11a (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat1 */ + 0x11c (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat2 */ + 0x11e (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat3 */ + >; + }; + + display_pins: pinmux_display_pins { + pinctrl-single,pins = < + 0x0d4 (PIN_OUTPUT | MUX_MODE4) /* RX51_LCD_RESET_GPIO */ + >; + }; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; + + clock-frequency = <2200000>; + + twl: twl@48 { + reg = <0x48>; + interrupts = <7>; /* SYS_NIRQ cascaded to intc */ + interrupt-parent = <&intc>; + }; +}; + +#include "twl4030.dtsi" +#include "twl4030_omap3.dtsi" + +&vaux1 { + regulator-name = "V28"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-always-on; /* due battery cover sensor */ +}; + +&vaux2 { + regulator-name = "VCSI"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; +}; + +&vaux3 { + regulator-name = "VMMC2_30"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <3000000>; +}; + +&vaux4 { + regulator-name = "VCAM_ANA_28"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; +}; + +&vmmc1 { + regulator-name = "VMMC1"; + regulator-min-microvolt = <1850000>; + regulator-max-microvolt = <3150000>; +}; + +&vmmc2 { + regulator-name = "V28_A"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <3000000>; + regulator-always-on; /* due VIO leak to AIC34 VDDs */ +}; + +&vpll1 { + regulator-name = "VPLL"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; +}; + +&vpll2 { + regulator-name = "VSDI_CSI"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; +}; + +&vsim { + regulator-name = "VMMC2_IO_18"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; +}; + +&vio { + regulator-name = "VIO"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + +}; + +&vintana1 { + regulator-name = "VINTANA1"; + /* fixed to 1500000 */ + regulator-always-on; +}; + +&vintana2 { + regulator-name = "VINTANA2"; + regulator-min-microvolt = <2750000>; + regulator-max-microvolt = <2750000>; + regulator-always-on; +}; + +&vintdig { + regulator-name = "VINTDIG"; + /* fixed to 1500000 */ + regulator-always-on; +}; + +&twl { + twl_audio: audio { + compatible = "ti,twl4030-audio"; + ti,enable-vibra = <1>; + }; +}; + +&twl_gpio { + ti,pullups = <0x0>; + ti,pulldowns = <0x03ff3f>; /* BIT(0..5) | BIT(8..17) */ +}; + +&i2c2 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_pins>; + + clock-frequency = <100000>; + + tlv320aic3x: tlv320aic3x@18 { + compatible = "ti,tlv320aic3x"; + reg = <0x18>; + gpio-reset = <&gpio2 28 GPIO_ACTIVE_HIGH>; /* 60 */ + ai3x-gpio-func = < + 0 /* AIC3X_GPIO1_FUNC_DISABLED */ + 5 /* AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT */ + >; + + AVDD-supply = <&vmmc2>; + DRVDD-supply = <&vmmc2>; + IOVDD-supply = <&vio>; + DVDD-supply = <&vio>; + }; + + tlv320aic3x_aux: tlv320aic3x@19 { + compatible = "ti,tlv320aic3x"; + reg = <0x19>; + gpio-reset = <&gpio2 28 GPIO_ACTIVE_HIGH>; /* 60 */ + + AVDD-supply = <&vmmc2>; + DRVDD-supply = <&vmmc2>; + IOVDD-supply = <&vio>; + DVDD-supply = <&vio>; + }; + + lp5523: lp5523@32 { + compatible = "national,lp5523"; + reg = <0x32>; + clock-mode = /bits/ 8 <0>; /* LP55XX_CLOCK_AUTO */ + enable-gpio = <&gpio2 9 GPIO_ACTIVE_HIGH>; /* 41 */ + + chan0 { + chan-name = "lp5523:kb1"; + led-cur = /bits/ 8 <50>; + max-cur = /bits/ 8 <100>; + }; + + chan1 { + chan-name = "lp5523:kb2"; + led-cur = /bits/ 8 <50>; + max-cur = /bits/ 8 <100>; + }; + + chan2 { + chan-name = "lp5523:kb3"; + led-cur = /bits/ 8 <50>; + max-cur = /bits/ 8 <100>; + }; + + chan3 { + chan-name = "lp5523:kb4"; + led-cur = /bits/ 8 <50>; + max-cur = /bits/ 8 <100>; + }; + + chan4 { + chan-name = "lp5523:b"; + led-cur = /bits/ 8 <50>; + max-cur = /bits/ 8 <100>; + }; + + chan5 { + chan-name = "lp5523:g"; + led-cur = /bits/ 8 <50>; + max-cur = /bits/ 8 <100>; + }; + + chan6 { + chan-name = "lp5523:r"; + led-cur = /bits/ 8 <50>; + max-cur = /bits/ 8 <100>; + }; + + chan7 { + chan-name = "lp5523:kb5"; + led-cur = /bits/ 8 <50>; + max-cur = /bits/ 8 <100>; + }; + + chan8 { + chan-name = "lp5523:kb6"; + led-cur = /bits/ 8 <50>; + max-cur = /bits/ 8 <100>; + }; + }; + + bq27200: bq27200@55 { + compatible = "ti,bq27200"; + reg = <0x55>; + }; +}; + +&i2c3 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c3_pins>; + + clock-frequency = <400000>; +}; + +&mmc1 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc1_pins>; + vmmc-supply = <&vmmc1>; + bus-width = <4>; + cd-gpios = <&gpio6 0 GPIO_ACTIVE_HIGH>; /* 160 */ +}; + +&mmc2 { + status = "disabled"; +}; + +&mmc3 { + status = "disabled"; +}; + +&gpmc { + ranges = <0 0 0x04000000 0x10000000>; /* 256MB */ + + /* gpio-irq for dma: 65 */ + + onenand@0,0 { + #address-cells = <1>; + #size-cells = <1>; + reg = <0 0 0x10000000>; + + gpmc,sync-read; + gpmc,sync-write; + gpmc,burst-length = <16>; + gpmc,burst-read; + gpmc,burst-wrap; + gpmc,burst-write; + gpmc,device-width = <2>; /* GPMC_DEVWIDTH_16BIT */ + gpmc,mux-add-data = <2>; /* GPMC_MUX_AD */ + gpmc,cs-on-ns = <0>; + gpmc,cs-rd-off-ns = <87>; + gpmc,cs-wr-off-ns = <87>; + gpmc,adv-on-ns = <0>; + gpmc,adv-rd-off-ns = <10>; + gpmc,adv-wr-off-ns = <10>; + gpmc,oe-on-ns = <15>; + gpmc,oe-off-ns = <87>; + gpmc,we-on-ns = <0>; + gpmc,we-off-ns = <87>; + gpmc,rd-cycle-ns = <112>; + gpmc,wr-cycle-ns = <112>; + gpmc,access-ns = <81>; + gpmc,page-burst-access-ns = <15>; + gpmc,bus-turnaround-ns = <0>; + gpmc,cycle2cycle-delay-ns = <0>; + gpmc,wait-monitoring-ns = <0>; + gpmc,clk-activation-ns = <5>; + gpmc,wr-data-mux-bus-ns = <30>; + gpmc,wr-access-ns = <81>; + gpmc,sync-clk-ps = <15000>; + + /* + * MTD partition table corresponding to Nokia's + * Maemo 5 (Fremantle) release. + */ + partition@0 { + label = "bootloader"; + reg = <0x00000000 0x00020000>; + read-only; + }; + partition@1 { + label = "config"; + reg = <0x00020000 0x00060000>; + }; + partition@2 { + label = "log"; + reg = <0x00080000 0x00040000>; + }; + partition@3 { + label = "kernel"; + reg = <0x000c0000 0x00200000>; + }; + partition@4 { + label = "initfs"; + reg = <0x002c0000 0x00200000>; + }; + partition@5 { + label = "rootfs"; + reg = <0x004c0000 0x0fb40000>; + }; + }; +}; + +&mcspi1 { + /* + * For some reason, touchscreen is necessary for screen to work at + * all on real hw. It works well without it on emulator. + * + * Also... order in the device tree actually matters here. + */ + tsc2005@0 { + compatible = "tsc2005"; + spi-max-frequency = <6000000>; + reg = <0>; + }; + mipid@2 { + compatible = "acx565akm"; + spi-max-frequency = <6000000>; + reg = <2>; + + pinctrl-names = "default"; + pinctrl-0 = <&display_pins>; + }; +}; + +&usb_otg_hs { + interface-type = <0>; + usb-phy = <&usb2_phy>; + phys = <&usb2_phy>; + phy-names = "usb2-phy"; + mode = <2>; + power = <50>; +}; + +&uart1 { + status = "disabled"; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&uart2_pins>; +}; + +&uart3 { + pinctrl-names = "default"; + pinctrl-0 = <&uart3_pins>; +}; diff --git a/arch/arm/boot/dts/omap3-n950-n9.dtsi b/arch/arm/boot/dts/omap3-n950-n9.dtsi new file mode 100644 index 000000000000..94eb77d3b9dd --- /dev/null +++ b/arch/arm/boot/dts/omap3-n950-n9.dtsi @@ -0,0 +1,174 @@ +/* + * omap3-n950-n9.dtsi - Device Tree file for Nokia N950 & N9 (common stuff) + * + * Written by: Aaro Koskinen <aaro.koskinen@iki.fi> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include "omap36xx.dtsi" + +/ { + cpus { + cpu@0 { + cpu0-supply = <&vcc>; + }; + }; + + memory { + device_type = "memory"; + reg = <0x80000000 0x40000000>; /* 1 GB */ + }; + + vemmc: fixedregulator@0 { + compatible = "regulator-fixed"; + regulator-name = "VEMMC"; + regulator-min-microvolt = <2900000>; + regulator-max-microvolt = <2900000>; + gpio = <&gpio5 29 0>; /* gpio line 157 */ + startup-delay-us = <150>; + enable-active-high; + }; +}; + +&omap3_pmx_core { + mmc2_pins: pinmux_mmc2_pins { + pinctrl-single,pins = < + 0x128 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_clk */ + 0x12a (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_cmd */ + 0x12c (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat0 */ + 0x12e (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat1 */ + 0x130 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat2 */ + 0x132 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat3 */ + >; + }; +}; + +&i2c1 { + clock-frequency = <2900000>; + + twl: twl@48 { + reg = <0x48>; + interrupts = <7>; /* SYS_NIRQ cascaded to intc */ + interrupt-parent = <&intc>; + }; +}; + +/include/ "twl4030.dtsi" + +&twl { + compatible = "ti,twl5031"; +}; + +&twl_gpio { + ti,pullups = <0x000001>; /* BIT(0) */ + ti,pulldowns = <0x008106>; /* BIT(1) | BIT(2) | BIT(8) | BIT(15) */ +}; + +&i2c2 { + clock-frequency = <400000>; +}; + +&i2c3 { + clock-frequency = <400000>; +}; + +&mmc1 { + status = "disabled"; +}; + +&mmc2 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc2_pins>; + vmmc-supply = <&vemmc>; + bus-width = <4>; + ti,non-removable; +}; + +&mmc3 { + status = "disabled"; +}; + +&usb_otg_hs { + interface-type = <0>; + usb-phy = <&usb2_phy>; + phys = <&usb2_phy>; + phy-names = "usb2-phy"; + mode = <3>; + power = <50>; +}; + +&gpmc { + ranges = <0 0 0x04000000 0x20000000>; + + onenand@0,0 { + #address-cells = <1>; + #size-cells = <1>; + reg = <0 0 0x20000000>; + + gpmc,sync-read; + gpmc,sync-write; + gpmc,burst-length = <16>; + gpmc,burst-read; + gpmc,burst-wrap; + gpmc,burst-write; + gpmc,device-width = <2>; + gpmc,mux-add-data = <2>; + gpmc,cs-on-ns = <0>; + gpmc,cs-rd-off-ns = <87>; + gpmc,cs-wr-off-ns = <87>; + gpmc,adv-on-ns = <0>; + gpmc,adv-rd-off-ns = <10>; + gpmc,adv-wr-off-ns = <10>; + gpmc,oe-on-ns = <15>; + gpmc,oe-off-ns = <87>; + gpmc,we-on-ns = <0>; + gpmc,we-off-ns = <87>; + gpmc,rd-cycle-ns = <112>; + gpmc,wr-cycle-ns = <112>; + gpmc,access-ns = <81>; + gpmc,page-burst-access-ns = <15>; + gpmc,bus-turnaround-ns = <0>; + gpmc,cycle2cycle-delay-ns = <0>; + gpmc,wait-monitoring-ns = <0>; + gpmc,clk-activation-ns = <5>; + gpmc,wr-data-mux-bus-ns = <30>; + gpmc,wr-access-ns = <81>; + gpmc,sync-clk-ps = <15000>; + + /* + * MTD partition table corresponding to Nokia's MeeGo 1.2 + * Harmattan release. + */ + partition@0 { + label = "bootloader"; + reg = <0x00000000 0x00100000>; + }; + partition@1 { + label = "config"; + reg = <0x00100000 0x002c0000>; + }; + partition@2 { + label = "kernel"; + reg = <0x003c0000 0x01000000>; + }; + partition@3 { + label = "log"; + reg = <0x013c0000 0x00200000>; + }; + partition@4 { + label = "var"; + reg = <0x015c0000 0x1ca40000>; + }; + partition@5 { + label = "moslo"; + reg = <0x1e000000 0x02000000>; + }; + partition@6 { + label = "omap2-onenand"; + reg = <0x00000000 0x20000000>; + }; + }; +}; diff --git a/arch/arm/boot/dts/omap3-n950.dts b/arch/arm/boot/dts/omap3-n950.dts new file mode 100644 index 000000000000..b076a526b999 --- /dev/null +++ b/arch/arm/boot/dts/omap3-n950.dts @@ -0,0 +1,18 @@ +/* + * omap3-n950.dts - Device Tree file for Nokia N950 + * + * Written by: Aaro Koskinen <aaro.koskinen@iki.fi> + * + * 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. + */ + +/dts-v1/; + +#include "omap3-n950-n9.dtsi" + +/ { + model = "Nokia N950"; + compatible = "nokia,omap3-n950", "ti,omap3"; +}; diff --git a/arch/arm/boot/dts/omap3-overo.dtsi b/arch/arm/boot/dts/omap3-overo.dtsi index 8f1abec78275..a461d2fd1fb0 100644 --- a/arch/arm/boot/dts/omap3-overo.dtsi +++ b/arch/arm/boot/dts/omap3-overo.dtsi @@ -76,6 +76,8 @@ &usb_otg_hs { interface-type = <0>; usb-phy = <&usb2_phy>; + phys = <&usb2_phy>; + phy-names = "usb2-phy"; mode = <3>; power = <50>; }; diff --git a/arch/arm/boot/dts/omap3-zoom3.dts b/arch/arm/boot/dts/omap3-zoom3.dts new file mode 100644 index 000000000000..15eb9fe5169c --- /dev/null +++ b/arch/arm/boot/dts/omap3-zoom3.dts @@ -0,0 +1,217 @@ +/* + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.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 + * published by the Free Software Foundation. + */ +/dts-v1/; + +#include "omap36xx.dtsi" +#include "omap-zoom-common.dtsi" + +/ { + model = "TI Zoom3"; + compatible = "ti,omap3-zoom3", "ti,omap36xx", "ti,omap3"; + + cpus { + cpu@0 { + cpu0-supply = <&vcc>; + }; + }; + + memory { + device_type = "memory"; + reg = <0x80000000 0x20000000>; /* 512 MB */ + }; + + vddvario: regulator-vddvario { + compatible = "regulator-fixed"; + regulator-name = "vddvario"; + regulator-always-on; + }; + + vdd33a: regulator-vdd33a { + compatible = "regulator-fixed"; + regulator-name = "vdd33a"; + regulator-always-on; + }; + + wl12xx_vmmc: wl12xx_vmmc { + pinctrl-names = "default"; + pinctrl-0 = <&wl12xx_gpio>; + compatible = "regulator-fixed"; + regulator-name = "vwl1271"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + gpio = <&gpio4 5 0>; /* gpio101 */ + startup-delay-us = <70000>; + enable-active-high; + }; +}; + +&omap3_pmx_core { + /* REVISIT: twl gpio0 is mmc0_cd */ + mmc1_pins: pinmux_mmc1_pins { + pinctrl-single,pins = < + 0x114 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* sdmmc1_clk.sdmmc1_clk */ + 0x116 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* sdmmc1_cmd.sdmmc1_cmd */ + 0x118 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat0.sdmmc1_dat0 */ + 0x11a (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat1.sdmmc1_dat1 */ + 0x11c (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat2.sdmmc1_dat2 */ + 0x11e (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat3.sdmmc1_dat3 */ + >; + }; + + mmc2_pins: pinmux_mmc2_pins { + pinctrl-single,pins = < + 0x128 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_clk.sdmmc2_clk */ + 0x12a (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_cmd.sdmmc2_cmd */ + 0x12c (PIN_INPUT | MUX_MODE0) /* sdmmc2_dat0.sdmmc2_dat0 */ + 0x12e (PIN_INPUT | MUX_MODE0) /* sdmmc2_dat1.sdmmc2_dat1 */ + 0x130 (PIN_INPUT | MUX_MODE0) /* sdmmc2_dat2.sdmmc2_dat2 */ + 0x132 (PIN_INPUT | MUX_MODE0) /* sdmmc2_dat3.sdmmc2_dat3 */ + 0x134 (PIN_INPUT | MUX_MODE0) /* sdmmc2_dat4.sdmmc2_dat4 */ + 0x136 (PIN_INPUT | MUX_MODE0) /* sdmmc2_dat5.sdmmc2_dat5 */ + 0x138 (PIN_INPUT | MUX_MODE0) /* sdmmc2_dat6.sdmmc2_dat6 */ + 0x13a (PIN_INPUT | MUX_MODE0) /* sdmmc2_dat7.sdmmc2_dat7 */ + >; + }; + + mmc3_pins: pinmux_mmc3_pins { + pinctrl-single,pins = < + 0x168 (PIN_INPUT | MUX_MODE4) /* mcbsp1_clkx.gpio_162 WLAN IRQ */ + 0x1a0 (PIN_INPUT_PULLUP | MUX_MODE3) /* mcspi1_cs1.sdmmc3_cmd */ + 0x5a8 (PIN_INPUT_PULLUP | MUX_MODE2) /* etk_clk.sdmmc3_clk */ + 0x5b4 (PIN_INPUT_PULLUP | MUX_MODE2) /* etk_d4.sdmmc3_dat0 */ + 0x5b6 (WAKEUP_EN | PIN_INPUT_PULLUP | MUX_MODE2) /* etk_d5.sdmmc3_dat1 */ + 0x5b8 (PIN_INPUT_PULLUP | MUX_MODE2) /* etk_d6.sdmmc3_dat2 */ + 0x5b2 (PIN_INPUT_PULLUP | MUX_MODE2) /* etk_d3.sdmmc3_dat3 */ + >; + }; + + uart1_pins: pinmux_uart1_pins { + pinctrl-single,pins = < + 0x150 (PIN_INPUT | MUX_MODE0) /* uart1_cts.uart1_cts */ + 0x14e (PIN_OUTPUT | MUX_MODE0) /* uart1_rts.uart1_rts */ + 0x152 (WAKEUP_EN | PIN_INPUT | MUX_MODE0) /* uart1_rx.uart1_rx */ + 0x14c (PIN_OUTPUT | MUX_MODE0) /* uart1_tx.uart1_tx */ + >; + }; + + uart2_pins: pinmux_uart2_pins { + pinctrl-single,pins = < + 0x144 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart2_cts.uart2_cts */ + 0x146 (PIN_OUTPUT | MUX_MODE0) /* uart2_rts.uart2_rts */ + 0x14a (WAKEUP_EN | PIN_INPUT | MUX_MODE0) /* uart2_rx.uart2_rx */ + 0x148 (PIN_OUTPUT | MUX_MODE0) /* uart2_tx.uart2_tx */ + >; + }; + + uart3_pins: pinmux_uart3_pins { + pinctrl-single,pins = < + 0x16a (PIN_INPUT_PULLDOWN | MUX_MODE0) /* uart3_cts_rctx.uart3_cts_rctx */ + 0x16c (PIN_OUTPUT | MUX_MODE0) /* uart3_rts_sd.uart3_rts_sd */ + 0x16e (WAKEUP_EN | PIN_INPUT | MUX_MODE0) /* uart3_rx_irrx.uart3_rx_irrx */ + 0x170 (PIN_OUTPUT | MUX_MODE0) /* uart3_tx_irtx.uart3_tx_irtx */ + >; + }; + + /* wl12xx GPIO output for WLAN_EN */ + wl12xx_gpio: pinmux_wl12xx_gpio { + pinctrl-single,pins = < + 0xea (PIN_OUTPUT| MUX_MODE4) /* cam_d2.gpio_101 */ + >; + }; +}; + +&omap3_pmx_wkup { + wlan_host_wkup: pinmux_wlan_host_wkup_pins { + pinctrl-single,pins = < + 0x1a (PIN_INPUT_PULLUP | MUX_MODE4) /* sys_clkout1.gpio_10 WLAN_HOST_WKUP */ + >; + }; +}; + +&i2c1 { + clock-frequency = <2600000>; + + twl: twl@48 { + reg = <0x48>; + interrupts = <7>; /* SYS_NIRQ cascaded to intc */ + interrupt-parent = <&intc>; + }; +}; + +#include "twl4030.dtsi" + +&i2c2 { + clock-frequency = <400000>; +}; + +&i2c3 { + clock-frequency = <400000>; + + /* + * TVP5146 Video decoder-in for analog input support. + */ + tvp5146@5c { + compatible = "ti,tvp5146m2"; + reg = <0x5c>; + }; +}; + +&twl_gpio { + ti,use-leds; +}; + +&mmc1 { + vmmc-supply = <&vmmc1>; + vmmc_aux-supply = <&vsim>; + bus-width = <4>; + pinctrl-names = "default"; + pinctrl-0 = <&mmc1_pins>; +}; +/* +&mmc2 { + vmmc-supply = <&vmmc2>; + ti,non-removable; + bus-width = <8>; + pinctrl-names = "default"; + pinctrl-0 = <&mmc2_pins>; +}; +*/ +&mmc3 { + vmmc-supply = <&wl12xx_vmmc>; + non-removable; + bus-width = <4>; + cap-power-off-card; + pinctrl-names = "default"; + pinctrl-0 = <&mmc3_pins>; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins>; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&uart2_pins>; +}; + +&uart3 { + pinctrl-names = "default"; + pinctrl-0 = <&uart3_pins>; +}; + +&uart4 { + status = "disabled"; +}; + +&usb_otg_hs { + interface-type = <0>; + usb-phy = <&usb2_phy>; + mode = <3>; + power = <50>; +}; diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi index b41bd57f4328..f3a0c26ed0c2 100644 --- a/arch/arm/boot/dts/omap3.dtsi +++ b/arch/arm/boot/dts/omap3.dtsi @@ -19,6 +19,9 @@ interrupt-parent = <&intc>; aliases { + i2c0 = &i2c1; + i2c1 = &i2c2; + i2c2 = &i2c3; serial0 = &uart1; serial1 = &uart2; serial2 = &uart3; @@ -37,6 +40,7 @@ pmu { compatible = "arm,cortex-a8-pmu"; + reg = <0x54000000 0x800000>; interrupts = <3>; ti,hwmods = "debugss"; }; @@ -71,6 +75,8 @@ */ ocp { compatible = "simple-bus"; + reg = <0x68000000 0x10000>; + interrupts = <9 10>; #address-cells = <1>; #size-cells = <1>; ranges; @@ -107,15 +113,19 @@ reg = <0x48002030 0x05cc>; #address-cells = <1>; #size-cells = <0>; + #interrupt-cells = <1>; + interrupt-controller; pinctrl-single,register-width = <16>; pinctrl-single,function-mask = <0xff1f>; }; - omap3_pmx_wkup: pinmux@0x48002a00 { + omap3_pmx_wkup: pinmux@48002a00 { compatible = "ti,omap3-padconf", "pinctrl-single"; reg = <0x48002a00 0x5c>; #address-cells = <1>; #size-cells = <0>; + #interrupt-cells = <1>; + interrupt-controller; pinctrl-single,register-width = <16>; pinctrl-single,function-mask = <0xff1f>; }; @@ -189,24 +199,40 @@ uart1: serial@4806a000 { compatible = "ti,omap3-uart"; + reg = <0x4806a000 0x2000>; + interrupts = <72>; + dmas = <&sdma 49 &sdma 50>; + dma-names = "tx", "rx"; ti,hwmods = "uart1"; clock-frequency = <48000000>; }; uart2: serial@4806c000 { compatible = "ti,omap3-uart"; + reg = <0x4806c000 0x400>; + interrupts = <73>; + dmas = <&sdma 51 &sdma 52>; + dma-names = "tx", "rx"; ti,hwmods = "uart2"; clock-frequency = <48000000>; }; uart3: serial@49020000 { compatible = "ti,omap3-uart"; + reg = <0x49020000 0x400>; + interrupts = <74>; + dmas = <&sdma 53 &sdma 54>; + dma-names = "tx", "rx"; ti,hwmods = "uart3"; clock-frequency = <48000000>; }; i2c1: i2c@48070000 { compatible = "ti,omap3-i2c"; + reg = <0x48070000 0x80>; + interrupts = <56>; + dmas = <&sdma 27 &sdma 28>; + dma-names = "tx", "rx"; #address-cells = <1>; #size-cells = <0>; ti,hwmods = "i2c1"; @@ -214,6 +240,10 @@ i2c2: i2c@48072000 { compatible = "ti,omap3-i2c"; + reg = <0x48072000 0x80>; + interrupts = <57>; + dmas = <&sdma 29 &sdma 30>; + dma-names = "tx", "rx"; #address-cells = <1>; #size-cells = <0>; ti,hwmods = "i2c2"; @@ -221,6 +251,10 @@ i2c3: i2c@48060000 { compatible = "ti,omap3-i2c"; + reg = <0x48060000 0x80>; + interrupts = <61>; + dmas = <&sdma 25 &sdma 26>; + dma-names = "tx", "rx"; #address-cells = <1>; #size-cells = <0>; ti,hwmods = "i2c3"; @@ -228,6 +262,8 @@ mcspi1: spi@48098000 { compatible = "ti,omap2-mcspi"; + reg = <0x48098000 0x100>; + interrupts = <65>; #address-cells = <1>; #size-cells = <0>; ti,hwmods = "mcspi1"; @@ -246,6 +282,8 @@ mcspi2: spi@4809a000 { compatible = "ti,omap2-mcspi"; + reg = <0x4809a000 0x100>; + interrupts = <66>; #address-cells = <1>; #size-cells = <0>; ti,hwmods = "mcspi2"; @@ -259,6 +297,8 @@ mcspi3: spi@480b8000 { compatible = "ti,omap2-mcspi"; + reg = <0x480b8000 0x100>; + interrupts = <91>; #address-cells = <1>; #size-cells = <0>; ti,hwmods = "mcspi3"; @@ -272,6 +312,8 @@ mcspi4: spi@480ba000 { compatible = "ti,omap2-mcspi"; + reg = <0x480ba000 0x100>; + interrupts = <48>; #address-cells = <1>; #size-cells = <0>; ti,hwmods = "mcspi4"; @@ -280,8 +322,17 @@ dma-names = "tx0", "rx0"; }; + hdqw1w: 1w@480b2000 { + compatible = "ti,omap3-1w"; + reg = <0x480b2000 0x1000>; + interrupts = <58>; + ti,hwmods = "hdq1w"; + }; + mmc1: mmc@4809c000 { compatible = "ti,omap3-hsmmc"; + reg = <0x4809c000 0x200>; + interrupts = <83>; ti,hwmods = "mmc1"; ti,dual-volt; dmas = <&sdma 61>, <&sdma 62>; @@ -290,6 +341,8 @@ mmc2: mmc@480b4000 { compatible = "ti,omap3-hsmmc"; + reg = <0x480b4000 0x200>; + interrupts = <86>; ti,hwmods = "mmc2"; dmas = <&sdma 47>, <&sdma 48>; dma-names = "tx", "rx"; @@ -297,6 +350,8 @@ mmc3: mmc@480ad000 { compatible = "ti,omap3-hsmmc"; + reg = <0x480ad000 0x200>; + interrupts = <94>; ti,hwmods = "mmc3"; dmas = <&sdma 77>, <&sdma 78>; dma-names = "tx", "rx"; @@ -304,6 +359,7 @@ wdt2: wdt@48314000 { compatible = "ti,omap3-wdt"; + reg = <0x48314000 0x80>; ti,hwmods = "wd_timer2"; }; diff --git a/arch/arm/boot/dts/omap3430-sdp.dts b/arch/arm/boot/dts/omap3430-sdp.dts index e2249bcc3e63..281914ed0151 100644 --- a/arch/arm/boot/dts/omap3430-sdp.dts +++ b/arch/arm/boot/dts/omap3430-sdp.dts @@ -84,15 +84,15 @@ label = "bootloader-nor"; reg = <0 0x40000>; }; - partition@0x40000 { + partition@40000 { label = "params-nor"; reg = <0x40000 0x40000>; }; - partition@0x80000 { + partition@80000 { label = "kernel-nor"; reg = <0x80000 0x200000>; }; - partition@0x280000 { + partition@280000 { label = "filesystem-nor"; reg = <0x240000 0x7d80000>; }; @@ -125,19 +125,19 @@ label = "xloader-nand"; reg = <0 0x80000>; }; - partition@0x80000 { + partition@80000 { label = "bootloader-nand"; reg = <0x80000 0x140000>; }; - partition@0x1c0000 { + partition@1c0000 { label = "params-nand"; reg = <0x1c0000 0xc0000>; }; - partition@0x280000 { + partition@280000 { label = "kernel-nand"; reg = <0x280000 0x500000>; }; - partition@0x780000 { + partition@780000 { label = "filesystem-nand"; reg = <0x780000 0x7880000>; }; @@ -170,19 +170,19 @@ label = "xloader-onenand"; reg = <0 0x80000>; }; - partition@0x80000 { + partition@80000 { label = "bootloader-onenand"; reg = <0x80000 0x40000>; }; - partition@0xc0000 { + partition@c0000 { label = "params-onenand"; reg = <0xc0000 0x20000>; }; - partition@0xe0000 { + partition@e0000 { label = "kernel-onenand"; reg = <0xe0000 0x200000>; }; - partition@0x2e0000 { + partition@2e0000 { label = "filesystem-onenand"; reg = <0x2e0000 0xfd20000>; }; diff --git a/arch/arm/boot/dts/omap36xx.dtsi b/arch/arm/boot/dts/omap36xx.dtsi index f8b3765eb9be..380c22eb468e 100644 --- a/arch/arm/boot/dts/omap36xx.dtsi +++ b/arch/arm/boot/dts/omap36xx.dtsi @@ -31,6 +31,10 @@ ocp { uart4: serial@49042000 { compatible = "ti,omap3-uart"; + reg = <0x49042000 0x400>; + interrupts = <80>; + dmas = <&sdma 81 &sdma 82>; + dma-names = "tx", "rx"; ti,hwmods = "uart4"; clock-frequency = <48000000>; }; diff --git a/arch/arm/boot/dts/omap4-panda-common.dtsi b/arch/arm/boot/dts/omap4-panda-common.dtsi index 814ab67c8c29..298e85020e1b 100644 --- a/arch/arm/boot/dts/omap4-panda-common.dtsi +++ b/arch/arm/boot/dts/omap4-panda-common.dtsi @@ -60,22 +60,6 @@ "AFMR", "Line In"; }; - /* - * Temp hack: Need to be replaced with the proper gpio-controlled - * reset driver as soon it will be merged. - * http://thread.gmane.org/gmane.linux.drivers.devicetree/36830 - */ - /* HS USB Port 1 RESET */ - hsusb1_reset: hsusb1_reset_reg { - compatible = "regulator-fixed"; - regulator-name = "hsusb1_reset"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - gpio = <&gpio2 30 0>; /* gpio_62 */ - startup-delay-us = <70000>; - enable-active-high; - }; - /* HS USB Port 1 Power */ hsusb1_power: hsusb1_power_reg { compatible = "regulator-fixed"; @@ -97,7 +81,7 @@ /* HS USB Host PHY on PORT 1 */ hsusb1_phy: hsusb1_phy { compatible = "usb-nop-xceiv"; - reset-supply = <&hsusb1_reset>; + reset-gpios = <&gpio2 30 GPIO_ACTIVE_LOW>; /* gpio_62 */ vcc-supply = <&hsusb1_power>; /** * FIXME: @@ -122,37 +106,19 @@ }; }; -&omap4_pmx_wkup { - pinctrl-names = "default"; - pinctrl-0 = < - &twl6030_wkup_pins - >; - - twl6030_wkup_pins: pinmux_twl6030_wkup_pins { - pinctrl-single,pins = < - 0x14 (PIN_OUTPUT | MUX_MODE2) /* fref_clk0_out.sys_drm_msecure */ - >; - }; -}; - &omap4_pmx_core { pinctrl-names = "default"; pinctrl-0 = < - &twl6030_pins &twl6040_pins &mcpdm_pins &mcbsp1_pins + &dss_dpi_pins + &tfp410_pins &dss_hdmi_pins &tpd12s015_pins &hsusbb1_pins >; - twl6030_pins: pinmux_twl6030_pins { - pinctrl-single,pins = < - 0x15e (WAKEUP_EN | PIN_INPUT_PULLUP | MUX_MODE0) /* sys_nirq1.sys_nirq1 */ - >; - }; - twl6040_pins: pinmux_twl6040_pins { pinctrl-single,pins = < 0xe0 (PIN_OUTPUT | MUX_MODE3) /* hdq_sio.gpio_127 */ @@ -179,6 +145,47 @@ >; }; + dss_dpi_pins: pinmux_dss_dpi_pins { + pinctrl-single,pins = < + 0x122 (PIN_OUTPUT | MUX_MODE5) /* dispc2_data23 */ + 0x124 (PIN_OUTPUT | MUX_MODE5) /* dispc2_data22 */ + 0x126 (PIN_OUTPUT | MUX_MODE5) /* dispc2_data21 */ + 0x128 (PIN_OUTPUT | MUX_MODE5) /* dispc2_data20 */ + 0x12a (PIN_OUTPUT | MUX_MODE5) /* dispc2_data19 */ + 0x12c (PIN_OUTPUT | MUX_MODE5) /* dispc2_data18 */ + 0x12e (PIN_OUTPUT | MUX_MODE5) /* dispc2_data15 */ + 0x130 (PIN_OUTPUT | MUX_MODE5) /* dispc2_data14 */ + 0x132 (PIN_OUTPUT | MUX_MODE5) /* dispc2_data13 */ + 0x134 (PIN_OUTPUT | MUX_MODE5) /* dispc2_data12 */ + 0x136 (PIN_OUTPUT | MUX_MODE5) /* dispc2_data11 */ + + 0x174 (PIN_OUTPUT | MUX_MODE5) /* dispc2_data10 */ + 0x176 (PIN_OUTPUT | MUX_MODE5) /* dispc2_data9 */ + 0x178 (PIN_OUTPUT | MUX_MODE5) /* dispc2_data16 */ + 0x17a (PIN_OUTPUT | MUX_MODE5) /* dispc2_data17 */ + 0x17c (PIN_OUTPUT | MUX_MODE5) /* dispc2_hsync */ + 0x17e (PIN_OUTPUT | MUX_MODE5) /* dispc2_pclk */ + 0x180 (PIN_OUTPUT | MUX_MODE5) /* dispc2_vsync */ + 0x182 (PIN_OUTPUT | MUX_MODE5) /* dispc2_de */ + 0x184 (PIN_OUTPUT | MUX_MODE5) /* dispc2_data8 */ + 0x186 (PIN_OUTPUT | MUX_MODE5) /* dispc2_data7 */ + 0x188 (PIN_OUTPUT | MUX_MODE5) /* dispc2_data6 */ + 0x18a (PIN_OUTPUT | MUX_MODE5) /* dispc2_data5 */ + 0x18c (PIN_OUTPUT | MUX_MODE5) /* dispc2_data4 */ + 0x18e (PIN_OUTPUT | MUX_MODE5) /* dispc2_data3 */ + + 0x190 (PIN_OUTPUT | MUX_MODE5) /* dispc2_data2 */ + 0x192 (PIN_OUTPUT | MUX_MODE5) /* dispc2_data1 */ + 0x194 (PIN_OUTPUT | MUX_MODE5) /* dispc2_data0 */ + >; + }; + + tfp410_pins: pinmux_tfp410_pins { + pinctrl-single,pins = < + 0x144 (PIN_OUTPUT | MUX_MODE3) /* gpio_0 */ + >; + }; + dss_hdmi_pins: pinmux_dss_hdmi_pins { pinctrl-single,pins = < 0x5a (PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_cec.hdmi_cec */ @@ -305,6 +312,7 @@ }; #include "twl6030.dtsi" +#include "twl6030_omap4.dtsi" &i2c2 { pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/omap4-panda-es.dts b/arch/arm/boot/dts/omap4-panda-es.dts index 56c435468e94..816d1c95b592 100644 --- a/arch/arm/boot/dts/omap4-panda-es.dts +++ b/arch/arm/boot/dts/omap4-panda-es.dts @@ -62,3 +62,7 @@ gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>; }; }; + +&gpio1 { + ti,no-reset-on-init; +}; diff --git a/arch/arm/boot/dts/omap4-sdp.dts b/arch/arm/boot/dts/omap4-sdp.dts index 4f78380ecdb8..5fc3f43c5a81 100644 --- a/arch/arm/boot/dts/omap4-sdp.dts +++ b/arch/arm/boot/dts/omap4-sdp.dts @@ -155,23 +155,9 @@ }; }; -&omap4_pmx_wkup { - pinctrl-names = "default"; - pinctrl-0 = < - &twl6030_wkup_pins - >; - - twl6030_wkup_pins: pinmux_twl6030_wkup_pins { - pinctrl-single,pins = < - 0x14 (PIN_OUTPUT | MUX_MODE2) /* fref_clk0_out.sys_drm_msecure */ - >; - }; -}; - &omap4_pmx_core { pinctrl-names = "default"; pinctrl-0 = < - &twl6030_pins &twl6040_pins &mcpdm_pins &dmic_pins @@ -206,12 +192,6 @@ >; }; - twl6030_pins: pinmux_twl6030_pins { - pinctrl-single,pins = < - 0x15e (WAKEUP_EN | PIN_INPUT_PULLUP | MUX_MODE0) /* sys_nirq1.sys_nirq1 */ - >; - }; - twl6040_pins: pinmux_twl6040_pins { pinctrl-single,pins = < 0xe0 (PIN_OUTPUT | MUX_MODE3) /* hdq_sio.gpio_127 */ @@ -370,6 +350,7 @@ }; #include "twl6030.dtsi" +#include "twl6030_omap4.dtsi" &i2c2 { pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi index 22d9f2b593d4..a1e05853afcd 100644 --- a/arch/arm/boot/dts/omap4.dtsi +++ b/arch/arm/boot/dts/omap4.dtsi @@ -17,6 +17,10 @@ interrupt-parent = <&gic>; aliases { + i2c0 = &i2c1; + i2c1 = &i2c2; + i2c2 = &i2c3; + i2c3 = &i2c4; serial0 = &uart1; serial1 = &uart2; serial2 = &uart3; @@ -56,7 +60,7 @@ cache-level = <2>; }; - local-timer@0x48240600 { + local-timer@48240600 { compatible = "arm,cortex-a9-twd-timer"; reg = <0x48240600 0x20>; interrupts = <GIC_PPI 13 (GIC_CPU_MASK_RAW(3) | IRQ_TYPE_LEVEL_HIGH)>; @@ -114,6 +118,8 @@ reg = <0x4a100040 0x0196>; #address-cells = <1>; #size-cells = <0>; + #interrupt-cells = <1>; + interrupt-controller; pinctrl-single,register-width = <16>; pinctrl-single,function-mask = <0x7fff>; }; @@ -122,6 +128,8 @@ reg = <0x4a31e040 0x0038>; #address-cells = <1>; #size-cells = <0>; + #interrupt-cells = <1>; + interrupt-controller; pinctrl-single,register-width = <16>; pinctrl-single,function-mask = <0x7fff>; }; @@ -214,6 +222,7 @@ gpmc,num-cs = <8>; gpmc,num-waitpins = <4>; ti,hwmods = "gpmc"; + ti,no-idle-on-init; }; uart1: serial@4806a000 { @@ -248,6 +257,12 @@ clock-frequency = <48000000>; }; + hwspinlock: spinlock@4a0f6000 { + compatible = "ti,omap4-hwspinlock"; + reg = <0x4a0f6000 0x1000>; + ti,hwmods = "spinlock"; + }; + i2c1: i2c@48070000 { compatible = "ti,omap4-i2c"; reg = <0x48070000 0x100>; @@ -492,6 +507,7 @@ reg = <0x4c000000 0x100>; interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>; ti,hwmods = "emif1"; + ti,no-idle-on-init; phy-type = <1>; hw-caps-read-idle-ctrl; hw-caps-ll-interface; @@ -503,6 +519,7 @@ reg = <0x4d000000 0x100>; interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>; ti,hwmods = "emif2"; + ti,no-idle-on-init; phy-type = <1>; hw-caps-read-idle-ctrl; hw-caps-ll-interface; @@ -519,7 +536,8 @@ usb2_phy: usb2phy@4a0ad080 { compatible = "ti,omap-usb2"; reg = <0x4a0ad080 0x58>; - ctrl-module = <&omap_control_usb>; + ctrl-module = <&omap_control_usb2phy>; + #phy-cells = <0>; }; }; @@ -643,12 +661,16 @@ }; }; - omap_control_usb: omap-control-usb@4a002300 { - compatible = "ti,omap-control-usb"; - reg = <0x4a002300 0x4>, - <0x4a00233c 0x4>; - reg-names = "control_dev_conf", "otghs_control"; - ti,type = <1>; + omap_control_usb2phy: control-phy@4a002300 { + compatible = "ti,control-phy-usb2"; + reg = <0x4a002300 0x4>; + reg-names = "power"; + }; + + omap_control_usbotg: control-phy@4a00233c { + compatible = "ti,control-phy-otghs"; + reg = <0x4a00233c 0x4>; + reg-names = "otghs_control"; }; usb_otg_hs: usb_otg_hs@4a0ab000 { @@ -658,10 +680,30 @@ interrupt-names = "mc", "dma"; ti,hwmods = "usb_otg_hs"; usb-phy = <&usb2_phy>; + phys = <&usb2_phy>; + phy-names = "usb2-phy"; multipoint = <1>; num-eps = <16>; ram-bits = <12>; - ti,has-mailbox; + ctrl-module = <&omap_control_usbotg>; + }; + + aes: aes@4b501000 { + compatible = "ti,omap4-aes"; + ti,hwmods = "aes"; + reg = <0x4b501000 0xa0>; + interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&sdma 111>, <&sdma 110>; + dma-names = "tx", "rx"; + }; + + des: des@480a5000 { + compatible = "ti,omap4-des"; + ti,hwmods = "des"; + reg = <0x480a5000 0xa0>; + interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&sdma 117>, <&sdma 116>; + dma-names = "tx", "rx"; }; }; }; diff --git a/arch/arm/boot/dts/omap5-uevm.dts b/arch/arm/boot/dts/omap5-uevm.dts index 65d7b601651c..002fa70180a5 100644 --- a/arch/arm/boot/dts/omap5-uevm.dts +++ b/arch/arm/boot/dts/omap5-uevm.dts @@ -27,21 +27,10 @@ regulator-max-microvolt = <3000000>; }; - /* HS USB Port 2 RESET */ - hsusb2_reset: hsusb2_reset_reg { - compatible = "regulator-fixed"; - regulator-name = "hsusb2_reset"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - gpio = <&gpio3 16 GPIO_ACTIVE_HIGH>; /* gpio3_80 HUB_NRESET */ - startup-delay-us = <70000>; - enable-active-high; - }; - /* HS USB Host PHY on PORT 2 */ hsusb2_phy: hsusb2_phy { compatible = "usb-nop-xceiv"; - reset-supply = <&hsusb2_reset>; + reset-gpios = <&gpio3 16 GPIO_ACTIVE_LOW>; /* gpio3_80 HUB_NRESET */ /** * FIXME * Put the right clock phandle here when available @@ -51,21 +40,10 @@ clock-frequency = <19200000>; }; - /* HS USB Port 3 RESET */ - hsusb3_reset: hsusb3_reset_reg { - compatible = "regulator-fixed"; - regulator-name = "hsusb3_reset"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - gpio = <&gpio3 15 GPIO_ACTIVE_HIGH>; /* gpio3_79 ETH_NRESET */ - startup-delay-us = <70000>; - enable-active-high; - }; - /* HS USB Host PHY on PORT 3 */ hsusb3_phy: hsusb3_phy { compatible = "usb-nop-xceiv"; - reset-supply = <&hsusb3_reset>; + reset-gpios = <&gpio3 15 GPIO_ACTIVE_LOW>; /* gpio3_79 ETH_NRESET */ }; leds { @@ -84,7 +62,6 @@ pinctrl-0 = < &twl6040_pins &mcpdm_pins - &dmic_pins &mcbsp1_pins &mcbsp2_pins &usbhost_pins @@ -93,7 +70,7 @@ twl6040_pins: pinmux_twl6040_pins { pinctrl-single,pins = < - 0x18a (PIN_OUTPUT | MUX_MODE6) /* perslimbus2_clock.gpio5_145 */ + 0x17e (PIN_OUTPUT | MUX_MODE6) /* mcspi1_somi.gpio5_141 */ >; }; @@ -107,15 +84,6 @@ >; }; - dmic_pins: pinmux_dmic_pins { - pinctrl-single,pins = < - 0x144 (PIN_INPUT | MUX_MODE0) /* abedmic_din1.abedmic_din1 */ - 0x146 (PIN_INPUT | MUX_MODE0) /* abedmic_din2.abedmic_din2 */ - 0x148 (PIN_INPUT | MUX_MODE0) /* abedmic_din3.abedmic_din3 */ - 0x14a (PIN_OUTPUT | MUX_MODE0) /* abedmic_clk1.abedmic_clk1 */ - >; - }; - mcbsp1_pins: pinmux_mcbsp1_pins { pinctrl-single,pins = < 0x14c (PIN_INPUT | MUX_MODE1) /* abedmic_clk2.abemcbsp1_fsx */ @@ -153,25 +121,25 @@ 0xbc (PIN_INPUT | MUX_MODE0) /* mcspi2_clk */ 0xbe (PIN_INPUT | MUX_MODE0) /* mcspi2_simo */ 0xc0 (PIN_INPUT_PULLUP | MUX_MODE0) /* mcspi2_somi */ - 0xc2 (PIN_OUTPUT | MUX_MODE0) /* mcspi2_cs */ + 0xc2 (PIN_OUTPUT | MUX_MODE0) /* mcspi2_cs0 */ >; }; mcspi3_pins: pinmux_mcspi3_pins { pinctrl-single,pins = < - 0x78 (PIN_INPUT | MUX_MODE1) /* mcspi2_somi */ - 0x7a (PIN_INPUT | MUX_MODE1) /* mcspi2_cs */ - 0x7c (PIN_INPUT | MUX_MODE1) /* mcspi2_simo */ - 0x7e (PIN_INPUT | MUX_MODE1) /* mcspi2_clk */ + 0x78 (PIN_INPUT | MUX_MODE1) /* mcspi3_somi */ + 0x7a (PIN_INPUT | MUX_MODE1) /* mcspi3_cs0 */ + 0x7c (PIN_INPUT | MUX_MODE1) /* mcspi3_simo */ + 0x7e (PIN_INPUT | MUX_MODE1) /* mcspi3_clk */ >; }; mcspi4_pins: pinmux_mcspi4_pins { pinctrl-single,pins = < - 0x164 (PIN_INPUT | MUX_MODE1) /* mcspi2_clk */ - 0x168 (PIN_INPUT | MUX_MODE1) /* mcspi2_simo */ - 0x16a (PIN_INPUT | MUX_MODE1) /* mcspi2_somi */ - 0x16c (PIN_INPUT | MUX_MODE1) /* mcspi2_cs */ + 0x164 (PIN_INPUT | MUX_MODE1) /* mcspi4_clk */ + 0x168 (PIN_INPUT | MUX_MODE1) /* mcspi4_simo */ + 0x16a (PIN_INPUT | MUX_MODE1) /* mcspi4_somi */ + 0x16c (PIN_INPUT | MUX_MODE1) /* mcspi4_cs0 */ >; }; @@ -271,6 +239,14 @@ reg = <0x48>; interrupt-controller; #interrupt-cells = <2>; + ti,system-power-controller; + + extcon_usb3: palmas_usb { + compatible = "ti,palmas-usb-vid"; + ti,enable-vbus-detection; + ti,enable-id-detection; + ti,wakeup; + }; palmas_pmic { compatible = "ti,palmas-pmic"; @@ -334,15 +310,22 @@ ti,smps-range = <0x80>; }; - smps10_reg: smps10 { + smps10_out2_reg: smps10_out2 { /* VBUS_5V_OTG */ - regulator-name = "smps10"; + regulator-name = "smps10_out2"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; regulator-always-on; regulator-boot-on; }; + smps10_out1_reg: smps10_out1 { + /* VBUS_5V_OTG */ + regulator-name = "smps10_out1"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + ldo1_reg: ldo1 { /* VDDAPHY_CAM: vdda_csiport */ regulator-name = "ldo1"; @@ -470,6 +453,11 @@ phys = <0 &hsusb2_phy &hsusb3_phy>; }; +&usb3 { + extcon = <&extcon_usb3>; + vbus-supply = <&smps10_out1_reg>; +}; + &mcspi1 { }; @@ -503,3 +491,7 @@ pinctrl-names = "default"; pinctrl-0 = <&uart5_pins>; }; + +&cpu0 { + cpu0-supply = <&smps123_reg>; +}; diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi index 7cdea1bfea09..fc3fad563861 100644 --- a/arch/arm/boot/dts/omap5.dtsi +++ b/arch/arm/boot/dts/omap5.dtsi @@ -21,6 +21,11 @@ interrupt-parent = <&gic>; aliases { + i2c0 = &i2c1; + i2c1 = &i2c2; + i2c2 = &i2c3; + i2c3 = &i2c4; + i2c4 = &i2c5; serial0 = &uart1; serial1 = &uart2; serial2 = &uart3; @@ -33,10 +38,17 @@ #address-cells = <1>; #size-cells = <0>; - cpu@0 { + cpu0: cpu@0 { device_type = "cpu"; compatible = "arm,cortex-a15"; reg = <0x0>; + + operating-points = < + /* kHz uV */ + 500000 880000 + 1000000 1060000 + 1500000 1250000 + >; }; cpu@1 { device_type = "cpu"; @@ -52,7 +64,6 @@ <GIC_PPI 14 (GIC_CPU_MASK_RAW(3) | IRQ_TYPE_LEVEL_LOW)>, <GIC_PPI 11 (GIC_CPU_MASK_RAW(3) | IRQ_TYPE_LEVEL_LOW)>, <GIC_PPI 10 (GIC_CPU_MASK_RAW(3) | IRQ_TYPE_LEVEL_LOW)>; - clock-frequency = <6144000>; }; gic: interrupt-controller@48211000 { @@ -276,6 +287,12 @@ ti,hwmods = "i2c5"; }; + hwspinlock: spinlock@4a0f6000 { + compatible = "ti,omap4-hwspinlock"; + reg = <0x4a0f6000 0x1000>; + ti,hwmods = "spinlock"; + }; + mcspi1: spi@48098000 { compatible = "ti,omap4-mcspi"; reg = <0x48098000 0x200>; @@ -604,9 +621,10 @@ ti,hwmods = "wd_timer2"; }; - emif1: emif@0x4c000000 { + emif1: emif@4c000000 { compatible = "ti,emif-4d5"; ti,hwmods = "emif1"; + ti,no-idle-on-init; phy-type = <2>; /* DDR PHY type: Intelli PHY */ reg = <0x4c000000 0x400>; interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>; @@ -615,9 +633,10 @@ hw-caps-temp-alert; }; - emif2: emif@0x4d000000 { + emif2: emif@4d000000 { compatible = "ti,emif-4d5"; ti,hwmods = "emif2"; + ti,no-idle-on-init; phy-type = <2>; /* DDR PHY type: Intelli PHY */ reg = <0x4d000000 0x400>; interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>; @@ -626,15 +645,19 @@ hw-caps-temp-alert; }; - omap_control_usb: omap-control-usb@4a002300 { - compatible = "ti,omap-control-usb"; - reg = <0x4a002300 0x4>, - <0x4a002370 0x4>; - reg-names = "control_dev_conf", "phy_power_usb"; - ti,type = <2>; + omap_control_usb2phy: control-phy@4a002300 { + compatible = "ti,control-phy-usb2"; + reg = <0x4a002300 0x4>; + reg-names = "power"; + }; + + omap_control_usb3phy: control-phy@4a002370 { + compatible = "ti,control-phy-pipe3"; + reg = <0x4a002370 0x4>; + reg-names = "power"; }; - omap_dwc3@4a020000 { + usb3: omap_dwc3@4a020000 { compatible = "ti,dwc3"; ti,hwmods = "usb_otg_ss"; reg = <0x4a020000 0x10000>; @@ -648,6 +671,7 @@ reg = <0x4a030000 0x10000>; interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>; usb-phy = <&usb2_phy>, <&usb3_phy>; + dr_mode = "peripheral"; tx-fifo-resize; }; }; @@ -662,7 +686,7 @@ usb2_phy: usb2phy@4a084000 { compatible = "ti,omap-usb2"; reg = <0x4a084000 0x7c>; - ctrl-module = <&omap_control_usb>; + ctrl-module = <&omap_control_usb2phy>; }; usb3_phy: usb3phy@4a084400 { @@ -671,7 +695,7 @@ <0x4a084800 0x64>, <0x4a084c00 0x40>; reg-names = "phy_rx", "phy_tx", "pll_ctrl"; - ctrl-module = <&omap_control_usb>; + ctrl-module = <&omap_control_usb3phy>; }; }; diff --git a/arch/arm/boot/dts/prima2.dtsi b/arch/arm/boot/dts/prima2.dtsi index 27ed9f5144bc..daee58944e15 100644 --- a/arch/arm/boot/dts/prima2.dtsi +++ b/arch/arm/boot/dts/prima2.dtsi @@ -76,6 +76,11 @@ compatible = "sirf,prima2-rsc"; reg = <0x88020000 0x1000>; }; + + cphifbg@88030000 { + compatible = "sirf,prima2-cphifbg"; + reg = <0x88030000 0x1000>; + }; }; mem-iobg { @@ -86,10 +91,17 @@ memory-controller@90000000 { compatible = "sirf,prima2-memc"; - reg = <0x90000000 0x10000>; + reg = <0x90000000 0x2000>; interrupts = <27>; clocks = <&clks 5>; }; + + memc-monitor { + compatible = "sirf,prima2-memcmon"; + reg = <0x90002000 0x200>; + interrupts = <4>; + clocks = <&clks 32>; + }; }; disp-iobg { @@ -287,7 +299,13 @@ compatible = "sirf,prima2-spi"; reg = <0xb00d0000 0x10000>; interrupts = <15>; + sirf,spi-num-chipselects = <1>; + sirf,spi-dma-rx-channel = <25>; + sirf,spi-dma-tx-channel = <20>; + #address-cells = <1>; + #size-cells = <0>; clocks = <&clks 19>; + status = "disabled"; }; spi1: spi@b0170000 { @@ -295,7 +313,13 @@ compatible = "sirf,prima2-spi"; reg = <0xb0170000 0x10000>; interrupts = <16>; + sirf,spi-num-chipselects = <1>; + sirf,spi-dma-rx-channel = <12>; + sirf,spi-dma-tx-channel = <13>; + #address-cells = <1>; + #size-cells = <0>; clocks = <&clks 20>; + status = "disabled"; }; i2c0: i2c@b00e0000 { @@ -304,6 +328,8 @@ reg = <0xb00e0000 0x10000>; interrupts = <24>; clocks = <&clks 17>; + #address-cells = <1>; + #size-cells = <0>; }; i2c1: i2c@b00f0000 { @@ -312,6 +338,8 @@ reg = <0xb00f0000 0x10000>; interrupts = <25>; clocks = <&clks 18>; + #address-cells = <1>; + #size-cells = <0>; }; tsc@b0110000 { @@ -360,6 +388,12 @@ sirf,function = "uart0"; }; }; + uart0_noflow_pins_a: uart0@1 { + uart { + sirf,pins = "uart0_nostreamctrlgrp"; + sirf,function = "uart0_nostreamctrl"; + }; + }; uart1_pins_a: uart1@0 { uart { sirf,pins = "uart1grp"; @@ -498,18 +532,42 @@ sirf,function = "usp0"; }; }; + usp0_uart_nostreamctrl_pins_a: usp0@1 { + usp0 { + sirf,pins = + "usp0_uart_nostreamctrl_grp"; + sirf,function = + "usp0_uart_nostreamctrl"; + }; + }; usp1_pins_a: usp1@0 { usp1 { sirf,pins = "usp1grp"; sirf,function = "usp1"; }; }; + usp1_uart_nostreamctrl_pins_a: usp1@1 { + usp1 { + sirf,pins = + "usp1_uart_nostreamctrl_grp"; + sirf,function = + "usp1_uart_nostreamctrl"; + }; + }; usp2_pins_a: usp2@0 { usp2 { sirf,pins = "usp2grp"; sirf,function = "usp2"; }; }; + usp2_uart_nostreamctrl_pins_a: usp2@1 { + usp2 { + sirf,pins = + "usp2_uart_nostreamctrl_grp"; + sirf,function = + "usp2_uart_nostreamctrl"; + }; + }; usb0_utmi_drvbus_pins_a: usb0_utmi_drvbus@0 { usb0_utmi_drvbus { sirf,pins = "usb0_utmi_drvbusgrp"; @@ -522,6 +580,18 @@ sirf,function = "usb1_utmi_drvbus"; }; }; + usb1_dp_dn_pins_a: usb1_dp_dn@0 { + usb1_dp_dn { + sirf,pins = "usb1_dp_dngrp"; + sirf,function = "usb1_dp_dn"; + }; + }; + uart1_route_io_usb1_pins_a: uart1_route_io_usb1@0 { + uart1_route_io_usb1 { + sirf,pins = "uart1_route_io_usb1grp"; + sirf,function = "uart1_route_io_usb1"; + }; + }; warm_rst_pins_a: warm_rst@0 { warm_rst { sirf,pins = "warm_rstgrp"; diff --git a/arch/arm/boot/dts/msm8660-surf.dts b/arch/arm/boot/dts/qcom-msm8660-surf.dts index 386d42870215..386d42870215 100644 --- a/arch/arm/boot/dts/msm8660-surf.dts +++ b/arch/arm/boot/dts/qcom-msm8660-surf.dts diff --git a/arch/arm/boot/dts/msm8960-cdp.dts b/arch/arm/boot/dts/qcom-msm8960-cdp.dts index 93e9f7e0b7ad..93e9f7e0b7ad 100644 --- a/arch/arm/boot/dts/msm8960-cdp.dts +++ b/arch/arm/boot/dts/qcom-msm8960-cdp.dts diff --git a/arch/arm/boot/dts/r7s72100-genmai.dts b/arch/arm/boot/dts/r7s72100-genmai.dts new file mode 100644 index 000000000000..1fb20f2333cc --- /dev/null +++ b/arch/arm/boot/dts/r7s72100-genmai.dts @@ -0,0 +1,31 @@ +/* + * Device Tree Source for the Genmai board + * + * Copyright (C) 2013 Renesas Solutions Corp. + * + * 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. + */ + +/dts-v1/; +/include/ "r7s72100.dtsi" + +/ { + model = "Genmai"; + compatible = "renesas,genmai", "renesas,r7s72100"; + + chosen { + bootargs = "console=ttySC2,115200 ignore_loglevel rw root=/dev/nfs ip=dhcp"; + }; + + memory { + device_type = "memory"; + reg = <0x08000000 0x08000000>; + }; + + lbsc { + #address-cells = <1>; + #size-cells = <1>; + }; +}; diff --git a/arch/arm/boot/dts/r7s72100.dtsi b/arch/arm/boot/dts/r7s72100.dtsi new file mode 100644 index 000000000000..46b82aa7dc4e --- /dev/null +++ b/arch/arm/boot/dts/r7s72100.dtsi @@ -0,0 +1,36 @@ +/* + * Device Tree Source for the r7s72100 SoC + * + * Copyright (C) 2013 Renesas Solutions Corp. + * + * 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. + */ + +/ { + compatible = "renesas,r7s72100"; + interrupt-parent = <&gic>; + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + reg = <0>; + }; + }; + + gic: interrupt-controller@e8201000 { + compatible = "arm,cortex-a9-gic"; + #interrupt-cells = <3>; + #address-cells = <0>; + interrupt-controller; + reg = <0xe8201000 0x1000>, + <0xe8202000 0x1000>; + }; +}; diff --git a/arch/arm/boot/dts/r8a73a4-ape6evm-reference.dts b/arch/arm/boot/dts/r8a73a4-ape6evm-reference.dts index f444624eb097..9443e93d3cac 100644 --- a/arch/arm/boot/dts/r8a73a4-ape6evm-reference.dts +++ b/arch/arm/boot/dts/r8a73a4-ape6evm-reference.dts @@ -10,6 +10,7 @@ /dts-v1/; /include/ "r8a73a4.dtsi" +#include <dt-bindings/gpio/gpio.h> / { model = "APE6EVM"; @@ -24,6 +25,34 @@ reg = <0 0x40000000 0 0x40000000>; }; + vcc_mmc0: regulator@0 { + compatible = "regulator-fixed"; + regulator-name = "MMC0 Vcc"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-always-on; + }; + + vcc_sdhi0: regulator@1 { + compatible = "regulator-fixed"; + + regulator-name = "SDHI0 Vcc"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&pfc 76 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + /* Common 3.3V rail, used by several devices on APE6EVM */ + ape6evm_fixed_3v3: regulator@2 { + compatible = "regulator-fixed"; + regulator-name = "3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + lbsc { compatible = "simple-bus"; #address-cells = <1>; @@ -33,6 +62,7 @@ }; &i2c5 { + status = "okay"; vdd_dvfs: max8973@1b { compatible = "maxim,max8973"; reg = <0x1b>; @@ -62,4 +92,47 @@ renesas,groups = "scifa0_data"; renesas,function = "scifa0"; }; + + mmc0_pins: mmcif { + renesas,groups = "mmc0_data8", "mmc0_ctrl"; + renesas,function = "mmc0"; + }; + + sdhi0_pins: sdhi0 { + renesas,groups = "sdhi0_data4", "sdhi0_ctrl", "sdhi0_cd"; + renesas,function = "sdhi0"; + }; + + sdhi1_pins: sdhi1 { + renesas,groups = "sdhi1_data4", "sdhi1_ctrl"; + renesas,function = "sdhi1"; + }; +}; + +&mmcif0 { + vmmc-supply = <&vcc_mmc0>; + bus-width = <8>; + non-removable; + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins>; + status = "okay"; +}; + +&sdhi0 { + vmmc-supply = <&vcc_sdhi0>; + bus-width = <4>; + toshiba,mmc-wrprotect-disable; + pinctrl-names = "default"; + pinctrl-0 = <&sdhi0_pins>; + status = "okay"; +}; + +&sdhi1 { + vmmc-supply = <&ape6evm_fixed_3v3>; + bus-width = <4>; + broken-cd; + toshiba,mmc-wrprotect-disable; + pinctrl-names = "default"; + pinctrl-0 = <&sdhi1_pins>; + status = "okay"; }; diff --git a/arch/arm/boot/dts/r8a73a4-ape6evm.dts b/arch/arm/boot/dts/r8a73a4-ape6evm.dts index 72f867e65791..91436b58016f 100644 --- a/arch/arm/boot/dts/r8a73a4-ape6evm.dts +++ b/arch/arm/boot/dts/r8a73a4-ape6evm.dts @@ -52,6 +52,7 @@ }; &i2c5 { + status = "okay"; vdd_dvfs: max8973@1b { compatible = "maxim,max8973"; reg = <0x1b>; diff --git a/arch/arm/boot/dts/r8a73a4.dtsi b/arch/arm/boot/dts/r8a73a4.dtsi index 658fcc537576..287e047592a0 100644 --- a/arch/arm/boot/dts/r8a73a4.dtsi +++ b/arch/arm/boot/dts/r8a73a4.dtsi @@ -78,6 +78,49 @@ <0 56 4>, <0 57 4>; }; + dmac: dma-multiplexer@0 { + compatible = "renesas,shdma-mux"; + #dma-cells = <1>; + dma-channels = <20>; + dma-requests = <256>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + dma0: dma-controller@e6700020 { + compatible = "renesas,shdma-r8a73a4"; + reg = <0 0xe6700020 0 0x89e0>; + interrupt-parent = <&gic>; + interrupts = <0 220 4 + 0 200 4 + 0 201 4 + 0 202 4 + 0 203 4 + 0 204 4 + 0 205 4 + 0 206 4 + 0 207 4 + 0 208 4 + 0 209 4 + 0 210 4 + 0 211 4 + 0 212 4 + 0 213 4 + 0 214 4 + 0 215 4 + 0 216 4 + 0 217 4 + 0 218 4 + 0 219 4>; + interrupt-names = "error", + "ch0", "ch1", "ch2", "ch3", + "ch4", "ch5", "ch6", "ch7", + "ch8", "ch9", "ch10", "ch11", + "ch12", "ch13", "ch14", "ch15", + "ch16", "ch17", "ch18", "ch19"; + }; + }; + thermal@e61f0000 { compatible = "renesas,rcar-thermal"; reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>, @@ -93,6 +136,7 @@ reg = <0 0xe6500000 0 0x428>; interrupt-parent = <&gic>; interrupts = <0 174 0x4>; + status = "disabled"; }; i2c1: i2c@e6510000 { @@ -102,6 +146,7 @@ reg = <0 0xe6510000 0 0x428>; interrupt-parent = <&gic>; interrupts = <0 175 0x4>; + status = "disabled"; }; i2c2: i2c@e6520000 { @@ -111,6 +156,7 @@ reg = <0 0xe6520000 0 0x428>; interrupt-parent = <&gic>; interrupts = <0 176 0x4>; + status = "disabled"; }; i2c3: i2c@e6530000 { @@ -120,6 +166,7 @@ reg = <0 0xe6530000 0 0x428>; interrupt-parent = <&gic>; interrupts = <0 177 0x4>; + status = "disabled"; }; i2c4: i2c@e6540000 { @@ -129,6 +176,7 @@ reg = <0 0xe6540000 0 0x428>; interrupt-parent = <&gic>; interrupts = <0 178 0x4>; + status = "disabled"; }; i2c5: i2c@e60b0000 { @@ -138,6 +186,7 @@ reg = <0 0xe60b0000 0 0x428>; interrupt-parent = <&gic>; interrupts = <0 179 0x4>; + status = "disabled"; }; i2c6: i2c@e6550000 { @@ -147,6 +196,7 @@ reg = <0 0xe6550000 0 0x428>; interrupt-parent = <&gic>; interrupts = <0 184 0x4>; + status = "disabled"; }; i2c7: i2c@e6560000 { @@ -156,6 +206,7 @@ reg = <0 0xe6560000 0 0x428>; interrupt-parent = <&gic>; interrupts = <0 185 0x4>; + status = "disabled"; }; i2c8: i2c@e6570000 { @@ -165,6 +216,7 @@ reg = <0 0xe6570000 0 0x428>; interrupt-parent = <&gic>; interrupts = <0 173 0x4>; + status = "disabled"; }; mmcif0: mmcif@ee200000 { diff --git a/arch/arm/boot/dts/r8a7740-armadillo800eva-reference.dts b/arch/arm/boot/dts/r8a7740-armadillo800eva-reference.dts index c638e4ab91b8..1c56c5e56950 100644 --- a/arch/arm/boot/dts/r8a7740-armadillo800eva-reference.dts +++ b/arch/arm/boot/dts/r8a7740-armadillo800eva-reference.dts @@ -11,6 +11,7 @@ /dts-v1/; /include/ "r8a7740.dtsi" #include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/pwm/pwm.h> / { model = "armadillo 800 eva reference"; @@ -34,6 +35,33 @@ regulator-boot-on; }; + vcc_sdhi0: regulator@1 { + compatible = "regulator-fixed"; + + regulator-name = "SDHI0 Vcc"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&pfc 75 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + vccq_sdhi0: regulator@2 { + compatible = "regulator-gpio"; + + regulator-name = "SDHI0 VccQ"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc_sdhi0>; + + enable-gpio = <&pfc 74 GPIO_ACTIVE_HIGH>; + gpios = <&pfc 17 GPIO_ACTIVE_HIGH>; + states = <3300000 0 + 1800000 1>; + + enable-active-high; + }; + leds { compatible = "gpio-leds"; led1 { @@ -49,9 +77,19 @@ gpios = <&pfc 177 GPIO_ACTIVE_HIGH>; }; }; + + backlight { + compatible = "pwm-backlight"; + pwms = <&tpu 2 33333 PWM_POLARITY_INVERTED>; + brightness-levels = <0 1 2 4 8 16 32 64 128 255>; + default-brightness-level = <9>; + pinctrl-0 = <&backlight_pins>; + pinctrl-names = "default"; + }; }; &i2c0 { + status = "okay"; touchscreen: st1232@55 { compatible = "sitronix,st1232"; reg = <0x55>; @@ -76,4 +114,44 @@ renesas,groups = "intc_irq10"; renesas,function = "intc"; }; + + backlight_pins: backlight { + renesas,groups = "tpu0_to2_1"; + renesas,function = "tpu0"; + }; + + mmc0_pins: mmc0 { + renesas,groups = "mmc0_data8_1", "mmc0_ctrl_1"; + renesas,function = "mmc0"; + }; + + sdhi0_pins: sdhi0 { + renesas,groups = "sdhi0_data4", "sdhi0_ctrl", "sdhi0_wp"; + renesas,function = "sdhi0"; + }; +}; + +&tpu { + status = "okay"; +}; + +&mmcif0 { + pinctrl-0 = <&mmc0_pins>; + pinctrl-names = "default"; + + vmmc-supply = <®_3p3v>; + bus-width = <8>; + non-removable; + status = "okay"; +}; + +&sdhi0 { + pinctrl-0 = <&sdhi0_pins>; + pinctrl-names = "default"; + + vmmc-supply = <&vcc_sdhi0>; + vqmmc-supply = <&vccq_sdhi0>; + bus-width = <4>; + cd-gpios = <&pfc 167 GPIO_ACTIVE_LOW>; + status = "okay"; }; diff --git a/arch/arm/boot/dts/r8a7740.dtsi b/arch/arm/boot/dts/r8a7740.dtsi index 44d3d520e01f..ae1e230f711d 100644 --- a/arch/arm/boot/dts/r8a7740.dtsi +++ b/arch/arm/boot/dts/r8a7740.dtsi @@ -131,6 +131,7 @@ 0 202 0x4 0 203 0x4 0 204 0x4>; + status = "disabled"; }; i2c1: i2c@e6c20000 { @@ -143,6 +144,7 @@ 0 71 0x4 0 72 0x4 0 73 0x4>; + status = "disabled"; }; pfc: pfc@e6050000 { @@ -159,4 +161,37 @@ status = "disabled"; #pwm-cells = <3>; }; + + mmcif0: mmcif@e6bd0000 { + compatible = "renesas,sh-mmcif"; + reg = <0xe6bd0000 0x100>; + interrupt-parent = <&gic>; + interrupts = <0 56 4 + 0 57 4>; + status = "disabled"; + }; + + sdhi0: sdhi@e6850000 { + compatible = "renesas,sdhi-r8a7740"; + reg = <0xe6850000 0x100>; + interrupt-parent = <&gic>; + interrupts = <0 117 4 + 0 118 4 + 0 119 4>; + cap-sd-highspeed; + cap-sdio-irq; + status = "disabled"; + }; + + sdhi1: sdhi@e6860000 { + compatible = "renesas,sdhi-r8a7740"; + reg = <0xe6860000 0x100>; + interrupt-parent = <&gic>; + interrupts = <0 121 4 + 0 122 4 + 0 123 4>; + cap-sd-highspeed; + cap-sdio-irq; + status = "disabled"; + }; }; diff --git a/arch/arm/boot/dts/r8a7778-bockw-reference.dts b/arch/arm/boot/dts/r8a7778-bockw-reference.dts index 9bb903a3230d..969e386e852c 100644 --- a/arch/arm/boot/dts/r8a7778-bockw-reference.dts +++ b/arch/arm/boot/dts/r8a7778-bockw-reference.dts @@ -22,11 +22,36 @@ compatible = "renesas,bockw-reference", "renesas,r8a7778"; chosen { - bootargs = "console=ttySC0,115200 ignore_loglevel rw"; + bootargs = "console=ttySC0,115200 ignore_loglevel root=/dev/nfs ip=dhcp rw"; }; memory { device_type = "memory"; reg = <0x60000000 0x10000000>; }; + + fixedregulator3v3: fixedregulator@0 { + compatible = "regulator-fixed"; + regulator-name = "fixed-3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + ethernet@18300000 { + compatible = "smsc,lan9220", "smsc,lan9115"; + reg = <0x18300000 0x1000>; + + phy-mode = "mii"; + interrupt-parent = <&irqpin>; + interrupts = <0 0>; /* IRQ0: hwirq 0 on irqpin */ + reg-io-width = <4>; + vddvario-supply = <&fixedregulator3v3>; + vdd33a-supply = <&fixedregulator3v3>; + }; +}; + +&irqpin { + status = "okay"; }; diff --git a/arch/arm/boot/dts/r8a7778.dtsi b/arch/arm/boot/dts/r8a7778.dtsi index 3577aba82583..a6308a399e2d 100644 --- a/arch/arm/boot/dts/r8a7778.dtsi +++ b/arch/arm/boot/dts/r8a7778.dtsi @@ -33,6 +33,25 @@ <0xfe430000 0x100>; }; + /* irqpin: IRQ0 - IRQ3 */ + irqpin: irqpin@fe78001c { + compatible = "renesas,intc-irqpin"; + #interrupt-cells = <2>; + interrupt-controller; + status = "disabled"; /* default off */ + reg = <0xfe78001c 4>, + <0xfe780010 4>, + <0xfe780024 4>, + <0xfe780044 4>, + <0xfe780064 4>; + interrupt-parent = <&gic>; + interrupts = <0 27 0x4 + 0 28 0x4 + 0 29 0x4 + 0 30 0x4>; + sense-bitfield-width = <2>; + }; + gpio0: gpio@ffc40000 { compatible = "renesas,gpio-r8a7778", "renesas,gpio-rcar"; reg = <0xffc40000 0x2c>; diff --git a/arch/arm/boot/dts/r8a7779-marzen-reference.dts b/arch/arm/boot/dts/r8a7779-marzen-reference.dts index 6d5508392252..ab4110aa3c3b 100644 --- a/arch/arm/boot/dts/r8a7779-marzen-reference.dts +++ b/arch/arm/boot/dts/r8a7779-marzen-reference.dts @@ -42,8 +42,8 @@ pinctrl-names = "default"; phy-mode = "mii"; - interrupt-parent = <&gic>; - interrupts = <0 28 0x4>; + interrupt-parent = <&irqpin0>; + interrupts = <1 0>; /* IRQ1: hwirq 1 on irqpin0 */ reg-io-width = <4>; vddvario-supply = <&fixedregulator3v3>; vdd33a-supply = <&fixedregulator3v3>; @@ -63,6 +63,10 @@ }; }; +&irqpin0 { + status = "okay"; +}; + &pfc { pinctrl-0 = <&scif2_pins &scif4_pins &sdhi0_pins>; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/r8a7779.dtsi b/arch/arm/boot/dts/r8a7779.dtsi index ebbe507fcbfa..19faeac3fd2e 100644 --- a/arch/arm/boot/dts/r8a7779.dtsi +++ b/arch/arm/boot/dts/r8a7779.dtsi @@ -135,6 +135,7 @@ irqpin0: irqpin@fe780010 { compatible = "renesas,intc-irqpin"; #interrupt-cells = <2>; + status = "disabled"; interrupt-controller; reg = <0xfe78001c 4>, <0xfe780010 4>, @@ -156,6 +157,7 @@ reg = <0xffc70000 0x1000>; interrupt-parent = <&gic>; interrupts = <0 79 0x4>; + status = "disabled"; }; i2c1: i2c@ffc71000 { @@ -165,6 +167,7 @@ reg = <0xffc71000 0x1000>; interrupt-parent = <&gic>; interrupts = <0 82 0x4>; + status = "disabled"; }; i2c2: i2c@ffc72000 { @@ -174,6 +177,7 @@ reg = <0xffc72000 0x1000>; interrupt-parent = <&gic>; interrupts = <0 80 0x4>; + status = "disabled"; }; i2c3: i2c@ffc73000 { @@ -183,6 +187,7 @@ reg = <0xffc73000 0x1000>; interrupt-parent = <&gic>; interrupts = <0 81 0x4>; + status = "disabled"; }; pfc: pfc@fffc0000 { diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi index 413b4c29e782..ee845fad939b 100644 --- a/arch/arm/boot/dts/r8a7790.dtsi +++ b/arch/arm/boot/dts/r8a7790.dtsi @@ -24,6 +24,55 @@ reg = <0>; clock-frequency = <1300000000>; }; + + cpu1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <1>; + clock-frequency = <1300000000>; + }; + + cpu2: cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <2>; + clock-frequency = <1300000000>; + }; + + cpu3: cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <3>; + clock-frequency = <1300000000>; + }; + + cpu4: cpu@4 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x100>; + clock-frequency = <780000000>; + }; + + cpu5: cpu@5 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x101>; + clock-frequency = <780000000>; + }; + + cpu6: cpu@6 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x102>; + clock-frequency = <780000000>; + }; + + cpu7: cpu@7 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x103>; + clock-frequency = <780000000>; + }; }; gic: interrupt-controller@f1001000 { @@ -127,6 +176,46 @@ interrupts = <0 0 4>, <0 1 4>, <0 2 4>, <0 3 4>; }; + i2c0: i2c@e6508000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a7790"; + reg = <0 0xe6508000 0 0x40>; + interrupt-parent = <&gic>; + interrupts = <0 287 0x4>; + status = "disabled"; + }; + + i2c1: i2c@e6518000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a7790"; + reg = <0 0xe6518000 0 0x40>; + interrupt-parent = <&gic>; + interrupts = <0 288 0x4>; + status = "disabled"; + }; + + i2c2: i2c@e6530000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a7790"; + reg = <0 0xe6530000 0 0x40>; + interrupt-parent = <&gic>; + interrupts = <0 286 0x4>; + status = "disabled"; + }; + + i2c3: i2c@e6540000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a7790"; + reg = <0 0xe6540000 0 0x40>; + interrupt-parent = <&gic>; + interrupts = <0 290 0x4>; + status = "disabled"; + }; + mmcif0: mmcif@ee200000 { compatible = "renesas,sh-mmcif"; reg = <0 0xee200000 0 0x80>; diff --git a/arch/arm/boot/dts/r8a7791-koelsch.dts b/arch/arm/boot/dts/r8a7791-koelsch.dts new file mode 100644 index 000000000000..1ce5250ec278 --- /dev/null +++ b/arch/arm/boot/dts/r8a7791-koelsch.dts @@ -0,0 +1,32 @@ +/* + * Device Tree Source for the Koelsch board + * + * Copyright (C) 2013 Renesas Electronics Corporation + * Copyright (C) 2013 Renesas Solutions Corp. + * + * 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. + */ + +/dts-v1/; +/include/ "r8a7791.dtsi" + +/ { + model = "Koelsch"; + compatible = "renesas,koelsch", "renesas,r8a7791"; + + chosen { + bootargs = "console=ttySC6,115200 ignore_loglevel rw root=/dev/nfs ip=dhcp"; + }; + + memory@40000000 { + device_type = "memory"; + reg = <0 0x40000000 0 0x80000000>; + }; + + lbsc { + #address-cells = <1>; + #size-cells = <1>; + }; +}; diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi new file mode 100644 index 000000000000..fea5cfef4691 --- /dev/null +++ b/arch/arm/boot/dts/r8a7791.dtsi @@ -0,0 +1,74 @@ +/* + * Device Tree Source for the r8a7791 SoC + * + * Copyright (C) 2013 Renesas Electronics Corporation + * Copyright (C) 2013 Renesas Solutions Corp. + * + * 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. + */ + +/ { + compatible = "renesas,r8a7791"; + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0>; + clock-frequency = <1300000000>; + }; + + cpu1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <1>; + clock-frequency = <1300000000>; + }; + }; + + gic: interrupt-controller@f1001000 { + compatible = "arm,cortex-a15-gic"; + #interrupt-cells = <3>; + #address-cells = <0>; + interrupt-controller; + reg = <0 0xf1001000 0 0x1000>, + <0 0xf1002000 0 0x1000>, + <0 0xf1004000 0 0x2000>, + <0 0xf1006000 0 0x2000>; + interrupts = <1 9 0xf04>; + }; + + timer { + compatible = "arm,armv7-timer"; + interrupts = <1 13 0xf08>, + <1 14 0xf08>, + <1 11 0xf08>, + <1 10 0xf08>; + }; + + irqc0: interrupt-controller@e61c0000 { + compatible = "renesas,irqc"; + #interrupt-cells = <2>; + interrupt-controller; + reg = <0 0xe61c0000 0 0x200>; + interrupt-parent = <&gic>; + interrupts = <0 0 4>, + <0 1 4>, + <0 2 4>, + <0 3 4>, + <0 12 4>, + <0 13 4>, + <0 14 4>, + <0 15 4>, + <0 16 4>, + <0 17 4>; + }; +}; diff --git a/arch/arm/boot/dts/rk3066a-bqcurie2.dts b/arch/arm/boot/dts/rk3066a-bqcurie2.dts new file mode 100644 index 000000000000..035df4053c21 --- /dev/null +++ b/arch/arm/boot/dts/rk3066a-bqcurie2.dts @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2013 MundoReader S.L. + * Author: Heiko Stuebner <heiko@sntech.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that 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. + */ + +/dts-v1/; +#include "rk3066a.dtsi" + +/ { + model = "bq Curie 2"; + + memory { + reg = <0x60000000 0x40000000>; + }; + + soc { + uart0: serial@10124000 { + status = "okay"; + }; + + uart1: serial@10126000 { + status = "okay"; + }; + + uart2: serial@20064000 { + pinctrl-names = "default"; + pinctrl-0 = <&uart2_xfer>; + status = "okay"; + }; + + uart3: serial@20068000 { + status = "okay"; + }; + + vcc_sd0: fixed-regulator { + compatible = "regulator-fixed"; + regulator-name = "sdmmc-supply"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + gpio = <&gpio3 7 GPIO_ACTIVE_LOW>; + startup-delay-us = <100000>; + }; + + dwmmc@10214000 { /* sdmmc */ + num-slots = <1>; + status = "okay"; + + pinctrl-names = "default"; + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_cd &sd0_bus4>; + vmmc-supply = <&vcc_sd0>; + + slot@0 { + reg = <0>; + bus-width = <4>; + disable-wp; + }; + }; + + dwmmc@10218000 { /* wifi */ + num-slots = <1>; + status = "okay"; + non-removable; + + pinctrl-names = "default"; + pinctrl-0 = <&sd1_clk &sd1_cmd &sd1_bus4>; + + slot@0 { + reg = <0>; + bus-width = <4>; + disable-wp; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + autorepeat; + + button@0 { + gpios = <&gpio6 2 GPIO_ACTIVE_LOW>; /* GPIO6_A2 */ + linux,code = <116>; + label = "GPIO Key Power"; + linux,input-type = <1>; + gpio-key,wakeup = <1>; + debounce-interval = <100>; + }; + button@1 { + gpios = <&gpio4 21 GPIO_ACTIVE_LOW>; /* GPIO4_C5 */ + linux,code = <104>; + label = "GPIO Key Vol-"; + linux,input-type = <1>; + gpio-key,wakeup = <0>; + debounce-interval = <100>; + }; + /* VOL+ comes somehow thru the ADC */ + }; + }; +}; diff --git a/arch/arm/boot/dts/rk3066a.dtsi b/arch/arm/boot/dts/rk3066a.dtsi index 56bfac93d3f6..be5d2b09a363 100644 --- a/arch/arm/boot/dts/rk3066a.dtsi +++ b/arch/arm/boot/dts/rk3066a.dtsi @@ -14,15 +14,12 @@ */ #include <dt-bindings/gpio/gpio.h> -#include <dt-bindings/interrupt-controller/irq.h> -#include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/pinctrl/rockchip.h> -#include "skeleton.dtsi" +#include "rk3xxx.dtsi" #include "rk3066a-clocks.dtsi" / { compatible = "rockchip,rk3066a"; - interrupt-parent = <&gic>; cpus { #address-cells = <1>; @@ -43,33 +40,6 @@ }; soc { - #address-cells = <1>; - #size-cells = <1>; - compatible = "simple-bus"; - ranges; - - gic: interrupt-controller@1013d000 { - compatible = "arm,cortex-a9-gic"; - interrupt-controller; - #interrupt-cells = <3>; - reg = <0x1013d000 0x1000>, - <0x1013c100 0x0100>; - }; - - L2: l2-cache-controller@10138000 { - compatible = "arm,pl310-cache"; - reg = <0x10138000 0x1000>; - cache-unified; - cache-level = <2>; - }; - - local-timer@1013c600 { - compatible = "arm,cortex-a9-twd-timer"; - reg = <0x1013c600 0x20>; - interrupts = <GIC_PPI 13 0x304>; - clocks = <&dummy150m>; - }; - timer@20038000 { compatible = "snps,dw-apb-timer-osc"; reg = <0x20038000 0x100>; @@ -191,17 +161,14 @@ uart0_xfer: uart0-xfer { rockchip,pins = <RK_GPIO1 0 RK_FUNC_1 &pcfg_pull_default>, <RK_GPIO1 1 RK_FUNC_1 &pcfg_pull_default>; - rockchip,config = <&pcfg_pull_default>; }; uart0_cts: uart0-cts { rockchip,pins = <RK_GPIO1 2 RK_FUNC_1 &pcfg_pull_default>; - rockchip,config = <&pcfg_pull_default>; }; uart0_rts: uart0-rts { rockchip,pins = <RK_GPIO1 3 RK_FUNC_1 &pcfg_pull_default>; - rockchip,config = <&pcfg_pull_default>; }; }; @@ -209,17 +176,14 @@ uart1_xfer: uart1-xfer { rockchip,pins = <RK_GPIO1 4 RK_FUNC_1 &pcfg_pull_default>, <RK_GPIO1 5 RK_FUNC_1 &pcfg_pull_default>; - rockchip,config = <&pcfg_pull_default>; }; uart1_cts: uart1-cts { rockchip,pins = <RK_GPIO1 6 RK_FUNC_1 &pcfg_pull_default>; - rockchip,config = <&pcfg_pull_default>; }; uart1_rts: uart1-rts { rockchip,pins = <RK_GPIO1 7 RK_FUNC_1 &pcfg_pull_default>; - rockchip,config = <&pcfg_pull_default>; }; }; @@ -227,7 +191,6 @@ uart2_xfer: uart2-xfer { rockchip,pins = <RK_GPIO1 8 RK_FUNC_1 &pcfg_pull_default>, <RK_GPIO1 9 RK_FUNC_1 &pcfg_pull_default>; - rockchip,config = <&pcfg_pull_default>; }; /* no rts / cts for uart2 */ }; @@ -236,44 +199,36 @@ uart3_xfer: uart3-xfer { rockchip,pins = <RK_GPIO3 27 RK_FUNC_1 &pcfg_pull_default>, <RK_GPIO3 28 RK_FUNC_1 &pcfg_pull_default>; - rockchip,config = <&pcfg_pull_default>; }; uart3_cts: uart3-cts { rockchip,pins = <RK_GPIO3 29 RK_FUNC_1 &pcfg_pull_default>; - rockchip,config = <&pcfg_pull_default>; }; uart3_rts: uart3-rts { rockchip,pins = <RK_GPIO3 30 RK_FUNC_1 &pcfg_pull_default>; - rockchip,config = <&pcfg_pull_default>; }; }; sd0 { sd0_clk: sd0-clk { rockchip,pins = <RK_GPIO3 8 RK_FUNC_1 &pcfg_pull_default>; - rockchip,config = <&pcfg_pull_default>; }; sd0_cmd: sd0-cmd { rockchip,pins = <RK_GPIO3 9 RK_FUNC_1 &pcfg_pull_default>; - rockchip,config = <&pcfg_pull_default>; }; sd0_cd: sd0-cd { rockchip,pins = <RK_GPIO3 14 RK_FUNC_1 &pcfg_pull_default>; - rockchip,config = <&pcfg_pull_default>; }; sd0_wp: sd0-wp { rockchip,pins = <RK_GPIO3 15 RK_FUNC_1 &pcfg_pull_default>; - rockchip,config = <&pcfg_pull_default>; }; sd0_bus1: sd0-bus-width1 { rockchip,pins = <RK_GPIO3 10 RK_FUNC_1 &pcfg_pull_default>; - rockchip,config = <&pcfg_pull_default>; }; sd0_bus4: sd0-bus-width4 { @@ -281,34 +236,28 @@ <RK_GPIO3 11 RK_FUNC_1 &pcfg_pull_default>, <RK_GPIO3 12 RK_FUNC_1 &pcfg_pull_default>, <RK_GPIO3 13 RK_FUNC_1 &pcfg_pull_default>; - rockchip,config = <&pcfg_pull_default>; }; }; sd1 { sd1_clk: sd1-clk { rockchip,pins = <RK_GPIO3 21 RK_FUNC_1 &pcfg_pull_default>; - rockchip,config = <&pcfg_pull_default>; }; sd1_cmd: sd1-cmd { rockchip,pins = <RK_GPIO3 16 RK_FUNC_1 &pcfg_pull_default>; - rockchip,config = <&pcfg_pull_default>; }; sd1_cd: sd1-cd { rockchip,pins = <RK_GPIO3 22 RK_FUNC_1 &pcfg_pull_default>; - rockchip,config = <&pcfg_pull_default>; }; sd1_wp: sd1-wp { rockchip,pins = <RK_GPIO3 23 RK_FUNC_1 &pcfg_pull_default>; - rockchip,config = <&pcfg_pull_default>; }; sd1_bus1: sd1-bus-width1 { rockchip,pins = <RK_GPIO3 17 RK_FUNC_1 &pcfg_pull_default>; - rockchip,config = <&pcfg_pull_default>; }; sd1_bus4: sd1-bus-width4 { @@ -316,75 +265,8 @@ <RK_GPIO3 18 RK_FUNC_1 &pcfg_pull_default>, <RK_GPIO3 19 RK_FUNC_1 &pcfg_pull_default>, <RK_GPIO3 20 RK_FUNC_1 &pcfg_pull_default>; - rockchip,config = <&pcfg_pull_default>; }; }; }; - - uart0: serial@10124000 { - compatible = "snps,dw-apb-uart"; - reg = <0x10124000 0x400>; - interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>; - reg-shift = <2>; - reg-io-width = <1>; - clocks = <&clk_gates1 8>; - status = "disabled"; - }; - - uart1: serial@10126000 { - compatible = "snps,dw-apb-uart"; - reg = <0x10126000 0x400>; - interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>; - reg-shift = <2>; - reg-io-width = <1>; - clocks = <&clk_gates1 10>; - status = "disabled"; - }; - - uart2: serial@20064000 { - compatible = "snps,dw-apb-uart"; - reg = <0x20064000 0x400>; - interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>; - reg-shift = <2>; - reg-io-width = <1>; - clocks = <&clk_gates1 12>; - status = "disabled"; - }; - - uart3: serial@20068000 { - compatible = "snps,dw-apb-uart"; - reg = <0x20068000 0x400>; - interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>; - reg-shift = <2>; - reg-io-width = <1>; - clocks = <&clk_gates1 14>; - status = "disabled"; - }; - - dwmmc@10214000 { - compatible = "rockchip,rk2928-dw-mshc"; - reg = <0x10214000 0x1000>; - interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>; - #address-cells = <1>; - #size-cells = <0>; - - clocks = <&clk_gates5 10>, <&clk_gates2 11>; - clock-names = "biu", "ciu"; - - status = "disabled"; - }; - - dwmmc@10218000 { - compatible = "rockchip,rk2928-dw-mshc"; - reg = <0x10218000 0x1000>; - interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>; - #address-cells = <1>; - #size-cells = <0>; - - clocks = <&clk_gates5 11>, <&clk_gates2 13>; - clock-names = "biu", "ciu"; - - status = "disabled"; - }; }; }; diff --git a/arch/arm/boot/dts/rk3188-clocks.dtsi b/arch/arm/boot/dts/rk3188-clocks.dtsi new file mode 100644 index 000000000000..b1b92dc245ce --- /dev/null +++ b/arch/arm/boot/dts/rk3188-clocks.dtsi @@ -0,0 +1,289 @@ +/* + * Copyright (c) 2013 MundoReader S.L. + * Author: Heiko Stuebner <heiko@sntech.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that 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. + */ + +/ { + clocks { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + /* + * This is a dummy clock, to be used as placeholder on + * other mux clocks when a specific parent clock is not + * yet implemented. It should be dropped when the driver + * is complete. + */ + dummy: dummy { + compatible = "fixed-clock"; + clock-frequency = <0>; + #clock-cells = <0>; + }; + + xin24m: xin24m { + compatible = "fixed-clock"; + clock-frequency = <24000000>; + #clock-cells = <0>; + }; + + dummy48m: dummy48m { + compatible = "fixed-clock"; + clock-frequency = <48000000>; + #clock-cells = <0>; + }; + + dummy150m: dummy150m { + compatible = "fixed-clock"; + clock-frequency = <150000000>; + #clock-cells = <0>; + }; + + clk_gates0: gate-clk@200000d0 { + compatible = "rockchip,rk2928-gate-clk"; + reg = <0x200000d0 0x4>; + clocks = <&dummy150m>, <&dummy>, + <&dummy>, <&dummy>, + <&dummy>, <&dummy>, + <&dummy>, <&dummy>, + <&dummy>, <&dummy>, + <&dummy>, <&dummy>, + <&dummy>, <&dummy>, + <&dummy>, <&dummy>; + + clock-output-names = + "gate_core_periph", "gate_cpu_gpll", + "gate_ddrphy", "gate_aclk_cpu", + "gate_hclk_cpu", "gate_pclk_cpu", + "gate_atclk_cpu", "gate_aclk_core", + "reserved", "gate_i2s0", + "gate_i2s0_frac", "reserved", + "reserved", "gate_spdif", + "gate_spdif_frac", "gate_testclk"; + + #clock-cells = <1>; + }; + + clk_gates1: gate-clk@200000d4 { + compatible = "rockchip,rk2928-gate-clk"; + reg = <0x200000d4 0x4>; + clocks = <&xin24m>, <&xin24m>, + <&xin24m>, <&dummy>, + <&dummy>, <&xin24m>, + <&xin24m>, <&dummy>, + <&xin24m>, <&dummy>, + <&xin24m>, <&dummy>, + <&xin24m>, <&dummy>, + <&xin24m>, <&dummy>; + + clock-output-names = + "gate_timer0", "gate_timer1", + "gate_timer3", "gate_jtag", + "gate_aclk_lcdc1_src", "gate_otgphy0", + "gate_otgphy1", "gate_ddr_gpll", + "gate_uart0", "gate_frac_uart0", + "gate_uart1", "gate_frac_uart1", + "gate_uart2", "gate_frac_uart2", + "gate_uart3", "gate_frac_uart3"; + + #clock-cells = <1>; + }; + + clk_gates2: gate-clk@200000d8 { + compatible = "rockchip,rk2928-gate-clk"; + reg = <0x200000d8 0x4>; + clocks = <&clk_gates2 1>, <&dummy>, + <&dummy>, <&dummy>, + <&dummy>, <&dummy>, + <&clk_gates2 3>, <&dummy>, + <&dummy>, <&dummy>, + <&dummy>, <&dummy48m>, + <&dummy>, <&dummy48m>, + <&dummy>, <&dummy>; + + clock-output-names = + "gate_periph_src", "gate_aclk_periph", + "gate_hclk_periph", "gate_pclk_periph", + "gate_smc", "gate_mac", + "gate_hsadc", "gate_hsadc_frac", + "gate_saradc", "gate_spi0", + "gate_spi1", "gate_mmc0", + "gate_mac_lbtest", "gate_mmc1", + "gate_emmc", "reserved"; + + #clock-cells = <1>; + }; + + clk_gates3: gate-clk@200000dc { + compatible = "rockchip,rk2928-gate-clk"; + reg = <0x200000dc 0x4>; + clocks = <&dummy>, <&dummy>, + <&dummy>, <&dummy>, + <&xin24m>, <&xin24m>, + <&dummy>, <&dummy>, + <&xin24m>, <&dummy>, + <&dummy>, <&dummy>, + <&dummy>, <&dummy>, + <&xin24m>, <&dummy>; + + clock-output-names = + "gate_aclk_lcdc0_src", "gate_dclk_lcdc0", + "gate_dclk_lcdc1", "gate_pclkin_cif0", + "gate_timer2", "gate_timer4", + "gate_hsicphy", "gate_cif0_out", + "gate_timer5", "gate_aclk_vepu", + "gate_hclk_vepu", "gate_aclk_vdpu", + "gate_hclk_vdpu", "reserved", + "gate_timer6", "gate_aclk_gpu_src"; + + #clock-cells = <1>; + }; + + clk_gates4: gate-clk@200000e0 { + compatible = "rockchip,rk2928-gate-clk"; + reg = <0x200000e0 0x4>; + clocks = <&clk_gates2 2>, <&clk_gates2 3>, + <&clk_gates2 1>, <&clk_gates2 1>, + <&clk_gates2 1>, <&clk_gates2 2>, + <&clk_gates2 2>, <&clk_gates2 2>, + <&clk_gates0 4>, <&clk_gates0 4>, + <&clk_gates0 3>, <&dummy>, + <&clk_gates0 3>, <&dummy>, + <&dummy>, <&dummy>; + + clock-output-names = + "gate_hclk_peri_axi_matrix", "gate_pclk_peri_axi_matrix", + "gate_aclk_cpu_peri", "gate_aclk_peri_axi_matrix", + "gate_aclk_pei_niu", "gate_hclk_usb_peri", + "gate_hclk_peri_ahb_arbi", "gate_hclk_emem_peri", + "gate_hclk_cpubus", "gate_hclk_ahb2apb", + "gate_aclk_strc_sys", "reserved", + "gate_aclk_intmem", "reserved", + "gate_hclk_imem1", "gate_hclk_imem0"; + + #clock-cells = <1>; + }; + + clk_gates5: gate-clk@200000e4 { + compatible = "rockchip,rk2928-gate-clk"; + reg = <0x200000e4 0x4>; + clocks = <&clk_gates0 3>, <&clk_gates2 1>, + <&clk_gates0 5>, <&clk_gates0 5>, + <&clk_gates0 5>, <&clk_gates0 5>, + <&clk_gates0 4>, <&clk_gates0 5>, + <&clk_gates2 1>, <&clk_gates2 2>, + <&clk_gates2 2>, <&clk_gates2 2>, + <&clk_gates2 2>, <&clk_gates4 5>; + + clock-output-names = + "gate_aclk_dmac1", "gate_aclk_dmac2", + "gate_pclk_efuse", "gate_pclk_tzpc", + "gate_pclk_grf", "gate_pclk_pmu", + "gate_hclk_rom", "gate_pclk_ddrupctl", + "gate_aclk_smc", "gate_hclk_nandc", + "gate_hclk_mmc0", "gate_hclk_mmc1", + "gate_hclk_emmc", "gate_hclk_otg0"; + + #clock-cells = <1>; + }; + + clk_gates6: gate-clk@200000e8 { + compatible = "rockchip,rk2928-gate-clk"; + reg = <0x200000e8 0x4>; + clocks = <&clk_gates3 0>, <&clk_gates0 4>, + <&clk_gates0 4>, <&clk_gates1 4>, + <&clk_gates0 4>, <&clk_gates3 0>, + <&dummy>, <&dummy>, + <&clk_gates3 0>, <&clk_gates0 4>, + <&clk_gates0 4>, <&clk_gates1 4>, + <&clk_gates0 4>, <&clk_gates3 0>; + + clock-output-names = + "gate_aclk_lcdc0", "gate_hclk_lcdc0", + "gate_hclk_lcdc1", "gate_aclk_lcdc1", + "gate_hclk_cif0", "gate_aclk_cif0", + "reserved", "reserved", + "gate_aclk_ipp", "gate_hclk_ipp", + "gate_hclk_rga", "gate_aclk_rga", + "gate_hclk_vio_bus", "gate_aclk_vio0"; + + #clock-cells = <1>; + }; + + clk_gates7: gate-clk@200000ec { + compatible = "rockchip,rk2928-gate-clk"; + reg = <0x200000ec 0x4>; + clocks = <&clk_gates2 2>, <&clk_gates0 4>, + <&clk_gates0 4>, <&dummy>, + <&dummy>, <&clk_gates2 2>, + <&clk_gates2 2>, <&clk_gates0 5>, + <&dummy>, <&clk_gates0 5>, + <&clk_gates0 5>, <&clk_gates2 3>, + <&clk_gates2 3>, <&clk_gates2 3>, + <&clk_gates2 3>, <&clk_gates2 3>; + + clock-output-names = + "gate_hclk_emac", "gate_hclk_spdif", + "gate_hclk_i2s0_2ch", "gate_hclk_otg1", + "gate_hclk_hsic", "gate_hclk_hsadc", + "gate_hclk_pidf", "gate_pclk_timer0", + "reserved", "gate_pclk_timer2", + "gate_pclk_pwm01", "gate_pclk_pwm23", + "gate_pclk_spi0", "gate_pclk_spi1", + "gate_pclk_saradc", "gate_pclk_wdt"; + + #clock-cells = <1>; + }; + + clk_gates8: gate-clk@200000f0 { + compatible = "rockchip,rk2928-gate-clk"; + reg = <0x200000f0 0x4>; + clocks = <&clk_gates0 5>, <&clk_gates0 5>, + <&clk_gates2 3>, <&clk_gates2 3>, + <&clk_gates0 5>, <&clk_gates0 5>, + <&clk_gates2 3>, <&clk_gates2 3>, + <&clk_gates2 3>, <&clk_gates0 5>, + <&clk_gates0 5>, <&clk_gates0 5>, + <&clk_gates2 3>, <&dummy>; + + clock-output-names = + "gate_pclk_uart0", "gate_pclk_uart1", + "gate_pclk_uart2", "gate_pclk_uart3", + "gate_pclk_i2c0", "gate_pclk_i2c1", + "gate_pclk_i2c2", "gate_pclk_i2c3", + "gate_pclk_i2c4", "gate_pclk_gpio0", + "gate_pclk_gpio1", "gate_pclk_gpio2", + "gate_pclk_gpio3", "gate_aclk_gps"; + + #clock-cells = <1>; + }; + + clk_gates9: gate-clk@200000f4 { + compatible = "rockchip,rk2928-gate-clk"; + reg = <0x200000f4 0x4>; + clocks = <&dummy>, <&dummy>, + <&dummy>, <&dummy>, + <&dummy>, <&dummy>, + <&dummy>, <&dummy>; + + clock-output-names = + "gate_clk_core_dbg", "gate_pclk_dbg", + "gate_clk_trace", "gate_atclk", + "gate_clk_l2c", "gate_aclk_vio1", + "gate_pclk_publ", "gate_aclk_gpu"; + + #clock-cells = <1>; + }; + }; + +}; diff --git a/arch/arm/boot/dts/rk3188-radxarock.dts b/arch/arm/boot/dts/rk3188-radxarock.dts new file mode 100644 index 000000000000..3ba1968a70ab --- /dev/null +++ b/arch/arm/boot/dts/rk3188-radxarock.dts @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that 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. + */ + +/dts-v1/; +#include "rk3188.dtsi" + +/ { + model = "Radxa Rock"; + + memory { + reg = <0x60000000 0x80000000>; + }; + + soc { + uart0: serial@10124000 { + status = "okay"; + }; + + uart1: serial@10126000 { + status = "okay"; + }; + + uart2: serial@20064000 { + pinctrl-names = "default"; + pinctrl-0 = <&uart2_xfer>; + status = "okay"; + }; + + uart3: serial@20068000 { + status = "okay"; + }; + + gpio-keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + autorepeat; + + button@0 { + gpios = <&gpio0 4 GPIO_ACTIVE_LOW>; + linux,code = <116>; + label = "GPIO Key Power"; + linux,input-type = <1>; + gpio-key,wakeup = <1>; + debounce-interval = <100>; + }; + }; + + gpio-leds { + compatible = "gpio-leds"; + + green { + gpios = <&gpio0 12 GPIO_ACTIVE_LOW>; + default-state = "off"; + }; + + yellow { + gpios = <&gpio0 14 GPIO_ACTIVE_LOW>; + default-state = "off"; + }; + + sleep { + gpios = <&gpio0 15 0>; + default-state = "off"; + }; + }; + + }; +}; diff --git a/arch/arm/boot/dts/rk3188.dtsi b/arch/arm/boot/dts/rk3188.dtsi new file mode 100644 index 000000000000..1a26b03b3649 --- /dev/null +++ b/arch/arm/boot/dts/rk3188.dtsi @@ -0,0 +1,253 @@ +/* + * Copyright (c) 2013 MundoReader S.L. + * Author: Heiko Stuebner <heiko@sntech.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that 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. + */ + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/pinctrl/rockchip.h> +#include "rk3xxx.dtsi" +#include "rk3188-clocks.dtsi" + +/ { + compatible = "rockchip,rk3188"; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + next-level-cache = <&L2>; + reg = <0x0>; + }; + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + next-level-cache = <&L2>; + reg = <0x1>; + }; + cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + next-level-cache = <&L2>; + reg = <0x2>; + }; + cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + next-level-cache = <&L2>; + reg = <0x3>; + }; + }; + + soc { + global-timer@1013c200 { + interrupts = <GIC_PPI 11 0xf04>; + }; + + local-timer@1013c600 { + interrupts = <GIC_PPI 13 0xf04>; + }; + + pinctrl@20008000 { + compatible = "rockchip,rk3188-pinctrl"; + reg = <0x20008000 0xa0>, + <0x20008164 0x1a0>; + reg-names = "base", "pull"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + gpio0: gpio0@0x2000a000 { + compatible = "rockchip,rk3188-gpio-bank0"; + reg = <0x2000a000 0x100>, + <0x20004064 0x8>; + interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk_gates8 9>; + + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio1: gpio1@0x2003c000 { + compatible = "rockchip,gpio-bank"; + reg = <0x2003c000 0x100>; + interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk_gates8 10>; + + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio2: gpio2@2003e000 { + compatible = "rockchip,gpio-bank"; + reg = <0x2003e000 0x100>; + interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk_gates8 11>; + + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio3: gpio3@20080000 { + compatible = "rockchip,gpio-bank"; + reg = <0x20080000 0x100>; + interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk_gates8 12>; + + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + pcfg_pull_up: pcfg_pull_up { + bias-pull-up; + }; + + pcfg_pull_down: pcfg_pull_down { + bias-pull-down; + }; + + pcfg_pull_none: pcfg_pull_none { + bias-disable; + }; + + uart0 { + uart0_xfer: uart0-xfer { + rockchip,pins = <RK_GPIO1 0 RK_FUNC_1 &pcfg_pull_none>, + <RK_GPIO1 1 RK_FUNC_1 &pcfg_pull_none>; + }; + + uart0_cts: uart0-cts { + rockchip,pins = <RK_GPIO1 2 RK_FUNC_1 &pcfg_pull_none>; + }; + + uart0_rts: uart0-rts { + rockchip,pins = <RK_GPIO1 3 RK_FUNC_1 &pcfg_pull_none>; + }; + }; + + uart1 { + uart1_xfer: uart1-xfer { + rockchip,pins = <RK_GPIO1 4 RK_FUNC_1 &pcfg_pull_none>, + <RK_GPIO1 5 RK_FUNC_1 &pcfg_pull_none>; + }; + + uart1_cts: uart1-cts { + rockchip,pins = <RK_GPIO1 6 RK_FUNC_1 &pcfg_pull_none>; + }; + + uart1_rts: uart1-rts { + rockchip,pins = <RK_GPIO1 7 RK_FUNC_1 &pcfg_pull_none>; + }; + }; + + uart2 { + uart2_xfer: uart2-xfer { + rockchip,pins = <RK_GPIO1 8 RK_FUNC_1 &pcfg_pull_none>, + <RK_GPIO1 9 RK_FUNC_1 &pcfg_pull_none>; + }; + /* no rts / cts for uart2 */ + }; + + uart3 { + uart3_xfer: uart3-xfer { + rockchip,pins = <RK_GPIO1 10 RK_FUNC_1 &pcfg_pull_none>, + <RK_GPIO1 11 RK_FUNC_1 &pcfg_pull_none>; + }; + + uart3_cts: uart3-cts { + rockchip,pins = <RK_GPIO1 12 RK_FUNC_1 &pcfg_pull_none>; + }; + + uart3_rts: uart3-rts { + rockchip,pins = <RK_GPIO1 13 RK_FUNC_1 &pcfg_pull_none>; + }; + }; + + sd0 { + sd0_clk: sd0-clk { + rockchip,pins = <RK_GPIO3 2 RK_FUNC_1 &pcfg_pull_none>; + }; + + sd0_cmd: sd0-cmd { + rockchip,pins = <RK_GPIO3 3 RK_FUNC_1 &pcfg_pull_none>; + }; + + sd0_cd: sd0-cd { + rockchip,pins = <RK_GPIO3 8 RK_FUNC_1 &pcfg_pull_none>; + }; + + sd0_wp: sd0-wp { + rockchip,pins = <RK_GPIO3 9 RK_FUNC_1 &pcfg_pull_none>; + }; + + sd0_pwr: sd0-pwr { + rockchip,pins = <RK_GPIO3 1 RK_FUNC_1 &pcfg_pull_none>; + }; + + sd0_bus1: sd0-bus-width1 { + rockchip,pins = <RK_GPIO3 4 RK_FUNC_1 &pcfg_pull_none>; + }; + + sd0_bus4: sd0-bus-width4 { + rockchip,pins = <RK_GPIO3 4 RK_FUNC_1 &pcfg_pull_none>, + <RK_GPIO3 5 RK_FUNC_1 &pcfg_pull_none>, + <RK_GPIO3 6 RK_FUNC_1 &pcfg_pull_none>, + <RK_GPIO3 7 RK_FUNC_1 &pcfg_pull_none>; + }; + }; + + sd1 { + sd1_clk: sd1-clk { + rockchip,pins = <RK_GPIO3 21 RK_FUNC_1 &pcfg_pull_none>; + }; + + sd1_cmd: sd1-cmd { + rockchip,pins = <RK_GPIO3 16 RK_FUNC_1 &pcfg_pull_none>; + }; + + sd1_cd: sd1-cd { + rockchip,pins = <RK_GPIO3 22 RK_FUNC_1 &pcfg_pull_none>; + }; + + sd1_wp: sd1-wp { + rockchip,pins = <RK_GPIO3 23 RK_FUNC_1 &pcfg_pull_none>; + }; + + sd1_bus1: sd1-bus-width1 { + rockchip,pins = <RK_GPIO3 17 RK_FUNC_1 &pcfg_pull_none>; + }; + + sd1_bus4: sd1-bus-width4 { + rockchip,pins = <RK_GPIO3 17 RK_FUNC_1 &pcfg_pull_none>, + <RK_GPIO3 18 RK_FUNC_1 &pcfg_pull_none>, + <RK_GPIO3 19 RK_FUNC_1 &pcfg_pull_none>, + <RK_GPIO3 20 RK_FUNC_1 &pcfg_pull_none>; + }; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/rk3xxx.dtsi b/arch/arm/boot/dts/rk3xxx.dtsi new file mode 100644 index 000000000000..0fcbcfd67de2 --- /dev/null +++ b/arch/arm/boot/dts/rk3xxx.dtsi @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2013 MundoReader S.L. + * Author: Heiko Stuebner <heiko@sntech.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that 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. + */ + +#include <dt-bindings/interrupt-controller/irq.h> +#include <dt-bindings/interrupt-controller/arm-gic.h> +#include "skeleton.dtsi" + +/ { + interrupt-parent = <&gic>; + + soc { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + ranges; + + gic: interrupt-controller@1013d000 { + compatible = "arm,cortex-a9-gic"; + interrupt-controller; + #interrupt-cells = <3>; + reg = <0x1013d000 0x1000>, + <0x1013c100 0x0100>; + }; + + L2: l2-cache-controller@10138000 { + compatible = "arm,pl310-cache"; + reg = <0x10138000 0x1000>; + cache-unified; + cache-level = <2>; + }; + + global-timer@1013c200 { + compatible = "arm,cortex-a9-global-timer"; + reg = <0x1013c200 0x20>; + interrupts = <GIC_PPI 11 0x304>; + clocks = <&dummy150m>; + }; + + local-timer@1013c600 { + compatible = "arm,cortex-a9-twd-timer"; + reg = <0x1013c600 0x20>; + interrupts = <GIC_PPI 13 0x304>; + clocks = <&dummy150m>; + }; + + uart0: serial@10124000 { + compatible = "snps,dw-apb-uart"; + reg = <0x10124000 0x400>; + interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>; + reg-shift = <2>; + reg-io-width = <1>; + clocks = <&clk_gates1 8>; + status = "disabled"; + }; + + uart1: serial@10126000 { + compatible = "snps,dw-apb-uart"; + reg = <0x10126000 0x400>; + interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>; + reg-shift = <2>; + reg-io-width = <1>; + clocks = <&clk_gates1 10>; + status = "disabled"; + }; + + uart2: serial@20064000 { + compatible = "snps,dw-apb-uart"; + reg = <0x20064000 0x400>; + interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>; + reg-shift = <2>; + reg-io-width = <1>; + clocks = <&clk_gates1 12>; + status = "disabled"; + }; + + uart3: serial@20068000 { + compatible = "snps,dw-apb-uart"; + reg = <0x20068000 0x400>; + interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>; + reg-shift = <2>; + reg-io-width = <1>; + clocks = <&clk_gates1 14>; + status = "disabled"; + }; + + dwmmc@10214000 { + compatible = "rockchip,rk2928-dw-mshc"; + reg = <0x10214000 0x1000>; + interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + + clocks = <&clk_gates5 10>, <&clk_gates2 11>; + clock-names = "biu", "ciu"; + + status = "disabled"; + }; + + dwmmc@10218000 { + compatible = "rockchip,rk2928-dw-mshc"; + reg = <0x10218000 0x1000>; + interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + + clocks = <&clk_gates5 11>, <&clk_gates2 13>; + clock-names = "biu", "ciu"; + + status = "disabled"; + }; + }; +}; diff --git a/arch/arm/boot/dts/s3c6400.dtsi b/arch/arm/boot/dts/s3c6400.dtsi new file mode 100644 index 000000000000..a7d1c8ec150d --- /dev/null +++ b/arch/arm/boot/dts/s3c6400.dtsi @@ -0,0 +1,41 @@ +/* + * Samsung's S3C6400 SoC device tree source + * + * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com> + * + * Samsung's S3C6400 SoC device nodes are listed in this file. S3C6400 + * based board files can include this file and provide values for board specfic + * bindings. + * + * Note: This file does not include device nodes for all the controllers in + * S3C6400 SoC. As device tree coverage for S3C6400 increases, additional + * nodes can be added to this file. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include "s3c64xx.dtsi" + +/ { + compatible = "samsung,s3c6400"; +}; + +&vic0 { + valid-mask = <0xfffffe1f>; + valid-wakeup-mask = <0x00200004>; +}; + +&vic1 { + valid-mask = <0xffffffff>; + valid-wakeup-mask = <0x53020000>; +}; + +&soc { + clocks: clock-controller@7e00f000 { + compatible = "samsung,s3c6400-clock"; + reg = <0x7e00f000 0x1000>; + #clock-cells = <1>; + }; +}; diff --git a/arch/arm/boot/dts/s3c6410-mini6410.dts b/arch/arm/boot/dts/s3c6410-mini6410.dts new file mode 100644 index 000000000000..57e00f9bce99 --- /dev/null +++ b/arch/arm/boot/dts/s3c6410-mini6410.dts @@ -0,0 +1,228 @@ +/* + * Samsung's S3C6410 based Mini6410 board device tree source + * + * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com> + * + * Device tree source file for FriendlyARM Mini6410 board which is based on + * Samsung's S3C6410 SoC. + * + * 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. +*/ + +/dts-v1/; + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/interrupt-controller/irq.h> + +#include "s3c6410.dtsi" + +/ { + model = "FriendlyARM Mini6410 board based on S3C6410"; + compatible = "friendlyarm,mini6410", "samsung,s3c6410"; + + memory { + reg = <0x50000000 0x10000000>; + }; + + chosen { + bootargs = "console=ttySAC0,115200n8 earlyprintk rootwait root=/dev/mmcblk0p1"; + }; + + clocks { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + fin_pll: oscillator@0 { + compatible = "fixed-clock"; + reg = <0>; + clock-frequency = <12000000>; + clock-output-names = "fin_pll"; + #clock-cells = <0>; + }; + + xusbxti: oscillator@1 { + compatible = "fixed-clock"; + reg = <1>; + clock-output-names = "xusbxti"; + clock-frequency = <48000000>; + #clock-cells = <0>; + }; + }; + + srom-cs1@18000000 { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x18000000 0x8000000>; + ranges; + + ethernet@18000000 { + compatible = "davicom,dm9000"; + reg = <0x18000000 0x2 0x18000004 0x2>; + interrupt-parent = <&gpn>; + interrupts = <7 IRQ_TYPE_LEVEL_HIGH>; + davicom,no-eeprom; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&gpio_keys>; + autorepeat; + + button-k1 { + label = "K1"; + gpios = <&gpn 0 GPIO_ACTIVE_LOW>; + linux,code = <2>; + debounce-interval = <20>; + }; + + button-k2 { + label = "K2"; + gpios = <&gpn 1 GPIO_ACTIVE_LOW>; + linux,code = <3>; + debounce-interval = <20>; + }; + + button-k3 { + label = "K3"; + gpios = <&gpn 2 GPIO_ACTIVE_LOW>; + linux,code = <4>; + debounce-interval = <20>; + }; + + button-k4 { + label = "K4"; + gpios = <&gpn 3 GPIO_ACTIVE_LOW>; + linux,code = <5>; + debounce-interval = <20>; + }; + + button-k5 { + label = "K5"; + gpios = <&gpn 4 GPIO_ACTIVE_LOW>; + linux,code = <6>; + debounce-interval = <20>; + }; + + button-k6 { + label = "K6"; + gpios = <&gpn 5 GPIO_ACTIVE_LOW>; + linux,code = <7>; + debounce-interval = <20>; + }; + + button-k7 { + label = "K7"; + gpios = <&gpl 11 GPIO_ACTIVE_LOW>; + linux,code = <8>; + debounce-interval = <20>; + }; + + button-k8 { + label = "K8"; + gpios = <&gpl 12 GPIO_ACTIVE_LOW>; + linux,code = <9>; + debounce-interval = <20>; + }; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&gpio_leds>; + + led-1 { + label = "LED1"; + gpios = <&gpk 4 GPIO_ACTIVE_LOW>; + linux,default-trigger = "heartbeat"; + }; + + led-2 { + label = "LED2"; + gpios = <&gpk 5 GPIO_ACTIVE_LOW>; + linux,default-trigger = "mmc0"; + }; + + led-3 { + label = "LED3"; + gpios = <&gpk 6 GPIO_ACTIVE_LOW>; + }; + + led-4 { + label = "LED4"; + gpios = <&gpk 7 GPIO_ACTIVE_LOW>; + }; + }; + + buzzer { + compatible = "pwm-beeper"; + pwms = <&pwm 0 1000000 0>; + pinctrl-names = "default"; + pinctrl-0 = <&pwm0_out>; + }; +}; + +&sdhci0 { + pinctrl-names = "default"; + pinctrl-0 = <&sd0_clk>, <&sd0_cmd>, <&sd0_cd>, <&sd0_bus4>; + bus-width = <4>; + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_data>; + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_data>, <&uart1_fctl>; + status = "okay"; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&uart2_data>; + status = "okay"; +}; + +&uart3 { + pinctrl-names = "default"; + pinctrl-0 = <&uart3_data>; + status = "okay"; +}; + +&pwm { + status = "okay"; +}; + +&pinctrl0 { + gpio_leds: gpio-leds { + samsung,pins = "gpk-4", "gpk-5", "gpk-6", "gpk-7"; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + gpio_keys: gpio-keys { + samsung,pins = "gpn-0", "gpn-1", "gpn-2", "gpn-3", + "gpn-4", "gpn-5", "gpl-11", "gpl-12"; + samsung,pin-pud = <PIN_PULL_NONE>; + }; +}; + +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_bus>; + status = "okay"; + + eeprom@50 { + compatible = "atmel,24c08"; + reg = <0x50>; + pagesize = <16>; + }; +}; diff --git a/arch/arm/boot/dts/s3c6410-smdk6410.dts b/arch/arm/boot/dts/s3c6410-smdk6410.dts new file mode 100644 index 000000000000..ecf35ec466f7 --- /dev/null +++ b/arch/arm/boot/dts/s3c6410-smdk6410.dts @@ -0,0 +1,103 @@ +/* + * Samsung S3C6410 based SMDK6410 board device tree source. + * + * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com> + * + * Device tree source file for SAMSUNG SMDK6410 board which is based on + * Samsung's S3C6410 SoC. + * + * 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. +*/ + +/dts-v1/; + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/interrupt-controller/irq.h> + +#include "s3c6410.dtsi" + +/ { + model = "SAMSUNG SMDK6410 board based on S3C6410"; + compatible = "samsung,mini6410", "samsung,s3c6410"; + + memory { + reg = <0x50000000 0x8000000>; + }; + + chosen { + bootargs = "console=ttySAC0,115200n8 earlyprintk rootwait root=/dev/mmcblk0p1"; + }; + + clocks { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + fin_pll: oscillator@0 { + compatible = "fixed-clock"; + reg = <0>; + clock-frequency = <12000000>; + clock-output-names = "fin_pll"; + #clock-cells = <0>; + }; + + xusbxti: oscillator@1 { + compatible = "fixed-clock"; + reg = <1>; + clock-output-names = "xusbxti"; + clock-frequency = <48000000>; + #clock-cells = <0>; + }; + }; + + srom-cs1@18000000 { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x18000000 0x8000000>; + ranges; + + ethernet@18000000 { + compatible = "smsc,lan9115"; + reg = <0x18000000 0x10000>; + interrupt-parent = <&gpn>; + interrupts = <10 IRQ_TYPE_LEVEL_LOW>; + phy-mode = "mii"; + reg-io-width = <4>; + smsc,force-internal-phy; + }; + }; +}; + +&sdhci0 { + pinctrl-names = "default"; + pinctrl-0 = <&sd0_clk>, <&sd0_cmd>, <&sd0_cd>, <&sd0_bus4>; + bus-width = <4>; + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_data>, <&uart0_fctl>; + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_data>; + status = "okay"; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&uart2_data>; + status = "okay"; +}; + +&uart3 { + pinctrl-names = "default"; + pinctrl-0 = <&uart3_data>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/s3c6410.dtsi b/arch/arm/boot/dts/s3c6410.dtsi new file mode 100644 index 000000000000..eb4226b3407c --- /dev/null +++ b/arch/arm/boot/dts/s3c6410.dtsi @@ -0,0 +1,57 @@ +/* + * Samsung's S3C6410 SoC device tree source + * + * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com> + * + * Samsung's S3C6410 SoC device nodes are listed in this file. S3C6410 + * based board files can include this file and provide values for board specfic + * bindings. + * + * Note: This file does not include device nodes for all the controllers in + * S3C6410 SoC. As device tree coverage for S3C6410 increases, additional + * nodes can be added to this file. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include "s3c64xx.dtsi" + +/ { + compatible = "samsung,s3c6410"; + + aliases { + i2c1 = &i2c1; + }; +}; + +&vic0 { + valid-mask = <0xffffff7f>; + valid-wakeup-mask = <0x00200004>; +}; + +&vic1 { + valid-mask = <0xffffffff>; + valid-wakeup-mask = <0x53020000>; +}; + +&soc { + clocks: clock-controller@7e00f000 { + compatible = "samsung,s3c6410-clock"; + reg = <0x7e00f000 0x1000>; + #clock-cells = <1>; + }; + + i2c1: i2c@7f00f000 { + compatible = "samsung,s3c2440-i2c"; + reg = <0x7f00f000 0x1000>; + interrupt-parent = <&vic0>; + interrupts = <5>; + clock-names = "i2c"; + clocks = <&clocks PCLK_IIC1>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; +}; diff --git a/arch/arm/boot/dts/s3c64xx-pinctrl.dtsi b/arch/arm/boot/dts/s3c64xx-pinctrl.dtsi new file mode 100644 index 000000000000..b1197d8b04de --- /dev/null +++ b/arch/arm/boot/dts/s3c64xx-pinctrl.dtsi @@ -0,0 +1,687 @@ +/* + * Samsung's S3C64xx SoC series common device tree source + * - pin control-related definitions + * + * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com> + * + * Samsung's S3C64xx SoCs pin banks, pin-mux and pin-config options are + * listed as device tree nodes in this file. + * + * 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. + */ + +#define PIN_PULL_NONE 0 +#define PIN_PULL_DOWN 1 +#define PIN_PULL_UP 2 + +&pinctrl0 { + /* + * Pin banks + */ + + gpa: gpa { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpb: gpb { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpc: gpc { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpd: gpd { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpe: gpe { + gpio-controller; + #gpio-cells = <2>; + }; + + gpf: gpf { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpg: gpg { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gph: gph { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpi: gpi { + gpio-controller; + #gpio-cells = <2>; + }; + + gpj: gpj { + gpio-controller; + #gpio-cells = <2>; + }; + + gpk: gpk { + gpio-controller; + #gpio-cells = <2>; + }; + + gpl: gpl { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpm: gpm { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpn: gpn { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpo: gpo { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpp: gpp { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpq: gpq { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + /* + * Pin groups + */ + + uart0_data: uart0-data { + samsung,pins = "gpa-0", "gpa-1"; + samsung,pin-function = <2>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + uart0_fctl: uart0-fctl { + samsung,pins = "gpa-2", "gpa-3"; + samsung,pin-function = <2>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + uart1_data: uart1-data { + samsung,pins = "gpa-4", "gpa-5"; + samsung,pin-function = <2>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + uart1_fctl: uart1-fctl { + samsung,pins = "gpa-6", "gpa-7"; + samsung,pin-function = <2>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + uart2_data: uart2-data { + samsung,pins = "gpb-0", "gpb-1"; + samsung,pin-function = <2>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + uart3_data: uart3-data { + samsung,pins = "gpb-2", "gpb-3"; + samsung,pin-function = <2>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + ext_dma_0: ext-dma-0 { + samsung,pins = "gpb-0", "gpb-1"; + samsung,pin-function = <3>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + ext_dma_1: ext-dma-1 { + samsung,pins = "gpb-2", "gpb-3"; + samsung,pin-function = <4>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + irda_data_0: irda-data-0 { + samsung,pins = "gpb-0", "gpb-1"; + samsung,pin-function = <4>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + irda_data_1: irda-data-1 { + samsung,pins = "gpb-2", "gpb-3"; + samsung,pin-function = <3>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + irda_sdbw: irda-sdbw { + samsung,pins = "gpb-4"; + samsung,pin-function = <2>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + i2c0_bus: i2c0-bus { + samsung,pins = "gpb-5", "gpb-6"; + samsung,pin-function = <2>; + samsung,pin-pud = <PIN_PULL_UP>; + }; + + i2c1_bus: i2c1-bus { + /* S3C6410-only */ + samsung,pins = "gpb-2", "gpb-3"; + samsung,pin-function = <6>; + samsung,pin-pud = <PIN_PULL_UP>; + }; + + spi0_bus: spi0-bus { + samsung,pins = "gpc-0", "gpc-1", "gpc-2"; + samsung,pin-function = <2>; + samsung,pin-pud = <PIN_PULL_UP>; + }; + + spi0_cs: spi0-cs { + samsung,pins = "gpc-3"; + samsung,pin-function = <2>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + spi1_bus: spi1-bus { + samsung,pins = "gpc-4", "gpc-5", "gpc-6"; + samsung,pin-function = <2>; + samsung,pin-pud = <PIN_PULL_UP>; + }; + + spi1_cs: spi1-cs { + samsung,pins = "gpc-7"; + samsung,pin-function = <2>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + sd0_cmd: sd0-cmd { + samsung,pins = "gpg-1"; + samsung,pin-function = <2>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + sd0_clk: sd0-clk { + samsung,pins = "gpg-0"; + samsung,pin-function = <2>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + sd0_bus1: sd0-bus1 { + samsung,pins = "gpg-2"; + samsung,pin-function = <2>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + sd0_bus4: sd0-bus4 { + samsung,pins = "gpg-2", "gpg-3", "gpg-4", "gpg-5"; + samsung,pin-function = <2>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + sd0_cd: sd0-cd { + samsung,pins = "gpg-6"; + samsung,pin-function = <2>; + samsung,pin-pud = <PIN_PULL_UP>; + }; + + sd1_cmd: sd1-cmd { + samsung,pins = "gph-1"; + samsung,pin-function = <2>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + sd1_clk: sd1-clk { + samsung,pins = "gph-0"; + samsung,pin-function = <2>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + sd1_bus1: sd1-bus1 { + samsung,pins = "gph-2"; + samsung,pin-function = <2>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + sd1_bus4: sd1-bus4 { + samsung,pins = "gph-2", "gph-3", "gph-4", "gph-5"; + samsung,pin-function = <2>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + sd1_bus8: sd1-bus8 { + samsung,pins = "gph-2", "gph-3", "gph-4", "gph-5", + "gph-6", "gph-7", "gph-8", "gph-9"; + samsung,pin-function = <2>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + sd1_cd: sd1-cd { + samsung,pins = "gpg-6"; + samsung,pin-function = <3>; + samsung,pin-pud = <PIN_PULL_UP>; + }; + + sd2_cmd: sd2-cmd { + samsung,pins = "gpc-4"; + samsung,pin-function = <3>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + sd2_clk: sd2-clk { + samsung,pins = "gpc-5"; + samsung,pin-function = <3>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + sd2_bus1: sd2-bus1 { + samsung,pins = "gph-6"; + samsung,pin-function = <3>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + sd2_bus4: sd2-bus4 { + samsung,pins = "gph-6", "gph-7", "gph-8", "gph-9"; + samsung,pin-function = <3>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + i2s0_bus: i2s0-bus { + samsung,pins = "gpd-0", "gpd-2", "gpd-3", "gpd-4"; + samsung,pin-function = <3>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + i2s0_cdclk: i2s0-cdclk { + samsung,pins = "gpd-1"; + samsung,pin-function = <3>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + i2s1_bus: i2s1-bus { + samsung,pins = "gpe-0", "gpe-2", "gpe-3", "gpe-4"; + samsung,pin-function = <3>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + i2s1_cdclk: i2s1-cdclk { + samsung,pins = "gpe-1"; + samsung,pin-function = <3>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + i2s2_bus: i2s2-bus { + /* S3C6410-only */ + samsung,pins = "gpc-4", "gpc-5", "gpc-6", "gph-6", + "gph-8", "gph-9"; + samsung,pin-function = <5>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + i2s2_cdclk: i2s2-cdclk { + /* S3C6410-only */ + samsung,pins = "gph-7"; + samsung,pin-function = <5>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + pcm0_bus: pcm0-bus { + samsung,pins = "gpd-0", "gpd-2", "gpd-3", "gpd-4"; + samsung,pin-function = <2>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + pcm0_extclk: pcm0-extclk { + samsung,pins = "gpd-1"; + samsung,pin-function = <2>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + pcm1_bus: pcm1-bus { + samsung,pins = "gpe-0", "gpe-2", "gpe-3", "gpe-4"; + samsung,pin-function = <2>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + pcm1_extclk: pcm1-extclk { + samsung,pins = "gpe-1"; + samsung,pin-function = <2>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + ac97_bus_0: ac97-bus-0 { + samsung,pins = "gpd-0", "gpd-1", "gpd-2", "gpd-3", "gpd-4"; + samsung,pin-function = <4>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + ac97_bus_1: ac97-bus-1 { + samsung,pins = "gpe-0", "gpe-1", "gpe-2", "gpe-3", "gpe-4"; + samsung,pin-function = <4>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + cam_port: cam-port { + samsung,pins = "gpf-0", "gpf-1", "gpf-2", "gpf-4", + "gpf-5", "gpf-6", "gpf-7", "gpf-8", + "gpf-9", "gpf-10", "gpf-11", "gpf-12"; + samsung,pin-function = <2>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + cam_rst: cam-rst { + samsung,pins = "gpf-3"; + samsung,pin-function = <2>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + cam_field: cam-field { + /* S3C6410-only */ + samsung,pins = "gpb-4"; + samsung,pin-function = <3>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + pwm_extclk: pwm-extclk { + samsung,pins = "gpf-13"; + samsung,pin-function = <2>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + pwm0_out: pwm0-out { + samsung,pins = "gpf-14"; + samsung,pin-function = <2>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + pwm1_out: pwm1-out { + samsung,pins = "gpf-15"; + samsung,pin-function = <2>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + clkout0: clkout-0 { + samsung,pins = "gpf-14"; + samsung,pin-function = <3>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + keypad_col0_0: keypad-col0-0 { + samsung,pins = "gph-0"; + samsung,pin-function = <4>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + keypad_col1_0: keypad-col1-0 { + samsung,pins = "gph-1"; + samsung,pin-function = <4>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + keypad_col2_0: keypad-col2-0 { + samsung,pins = "gph-2"; + samsung,pin-function = <4>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + keypad_col3_0: keypad-col3-0 { + samsung,pins = "gph-3"; + samsung,pin-function = <4>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + keypad_col4_0: keypad-col4-0 { + samsung,pins = "gph-4"; + samsung,pin-function = <4>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + keypad_col5_0: keypad-col5-0 { + samsung,pins = "gph-5"; + samsung,pin-function = <4>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + keypad_col6_0: keypad-col6-0 { + samsung,pins = "gph-6"; + samsung,pin-function = <4>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + keypad_col7_0: keypad-col7-0 { + samsung,pins = "gph-7"; + samsung,pin-function = <4>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + keypad_col0_1: keypad-col0-1 { + samsung,pins = "gpl-0"; + samsung,pin-function = <3>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + keypad_col1_1: keypad-col1-1 { + samsung,pins = "gpl-1"; + samsung,pin-function = <3>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + keypad_col2_1: keypad-col2-1 { + samsung,pins = "gpl-2"; + samsung,pin-function = <3>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + keypad_col3_1: keypad-col3-1 { + samsung,pins = "gpl-3"; + samsung,pin-function = <3>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + keypad_col4_1: keypad-col4-1 { + samsung,pins = "gpl-4"; + samsung,pin-function = <3>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + keypad_col5_1: keypad-col5-1 { + samsung,pins = "gpl-5"; + samsung,pin-function = <3>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + keypad_col6_1: keypad-col6-1 { + samsung,pins = "gpl-6"; + samsung,pin-function = <3>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + keypad_col7_1: keypad-col7-1 { + samsung,pins = "gpl-7"; + samsung,pin-function = <3>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + keypad_row0_0: keypad-row0-0 { + samsung,pins = "gpk-8"; + samsung,pin-function = <3>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + keypad_row1_0: keypad-row1-0 { + samsung,pins = "gpk-9"; + samsung,pin-function = <3>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + keypad_row2_0: keypad-row2-0 { + samsung,pins = "gpk-10"; + samsung,pin-function = <3>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + keypad_row3_0: keypad-row3-0 { + samsung,pins = "gpk-11"; + samsung,pin-function = <3>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + keypad_row4_0: keypad-row4-0 { + samsung,pins = "gpk-12"; + samsung,pin-function = <3>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + keypad_row5_0: keypad-row5-0 { + samsung,pins = "gpk-13"; + samsung,pin-function = <3>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + keypad_row6_0: keypad-row6-0 { + samsung,pins = "gpk-14"; + samsung,pin-function = <3>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + keypad_row7_0: keypad-row7-0 { + samsung,pins = "gpk-15"; + samsung,pin-function = <3>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + keypad_row0_1: keypad-row0-1 { + samsung,pins = "gpn-0"; + samsung,pin-function = <3>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + keypad_row1_1: keypad-row1-1 { + samsung,pins = "gpn-1"; + samsung,pin-function = <3>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + keypad_row2_1: keypad-row2-1 { + samsung,pins = "gpn-2"; + samsung,pin-function = <3>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + keypad_row3_1: keypad-row3-1 { + samsung,pins = "gpn-3"; + samsung,pin-function = <3>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + keypad_row4_1: keypad-row4-1 { + samsung,pins = "gpn-4"; + samsung,pin-function = <3>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + keypad_row5_1: keypad-row5-1 { + samsung,pins = "gpn-5"; + samsung,pin-function = <3>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + keypad_row6_1: keypad-row6-1 { + samsung,pins = "gpn-6"; + samsung,pin-function = <3>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + keypad_row7_1: keypad-row7-1 { + samsung,pins = "gpn-7"; + samsung,pin-function = <3>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + lcd_ctrl: lcd-ctrl { + samsung,pins = "gpj-8", "gpj-9", "gpj-10", "gpj-11"; + samsung,pin-function = <2>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + lcd_data16: lcd-data-width16 { + samsung,pins = "gpi-3", "gpi-4", "gpi-5", "gpi-6", + "gpi-7", "gpi-10", "gpi-11", "gpi-12", + "gpi-13", "gpi-14", "gpi-15", "gpj-3", + "gpj-4", "gpj-5", "gpj-6", "gpj-7"; + samsung,pin-function = <2>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + lcd_data18: lcd-data-width18 { + samsung,pins = "gpi-2", "gpi-3", "gpi-4", "gpi-5", + "gpi-6", "gpi-7", "gpi-10", "gpi-11", + "gpi-12", "gpi-13", "gpi-14", "gpi-15", + "gpj-2", "gpj-3", "gpj-4", "gpj-5", + "gpj-6", "gpj-7"; + samsung,pin-function = <2>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + lcd_data24: lcd-data-width24 { + samsung,pins = "gpi-0", "gpi-1", "gpi-2", "gpi-3", + "gpi-4", "gpi-5", "gpi-6", "gpi-7", + "gpi-8", "gpi-9", "gpi-10", "gpi-11", + "gpi-12", "gpi-13", "gpi-14", "gpi-15", + "gpj-0", "gpj-1", "gpj-2", "gpj-3", + "gpj-4", "gpj-5", "gpj-6", "gpj-7"; + samsung,pin-function = <2>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; + + hsi_bus: hsi-bus { + samsung,pins = "gpk-0", "gpk-1", "gpk-2", "gpk-3", + "gpk-4", "gpk-5", "gpk-6", "gpk-7"; + samsung,pin-function = <3>; + samsung,pin-pud = <PIN_PULL_NONE>; + }; +}; diff --git a/arch/arm/boot/dts/s3c64xx.dtsi b/arch/arm/boot/dts/s3c64xx.dtsi new file mode 100644 index 000000000000..4e3be4d3493d --- /dev/null +++ b/arch/arm/boot/dts/s3c64xx.dtsi @@ -0,0 +1,199 @@ +/* + * Samsung's S3C64xx SoC series common device tree source + * + * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com> + * + * Samsung's S3C64xx SoC series device nodes are listed in this file. + * Particular SoCs from S3C64xx series can include this file and provide + * values for SoCs specfic bindings. + * + * Note: This file does not include device nodes for all the controllers in + * S3C64xx SoCs. As device tree coverage for S3C64xx increases, additional + * nodes can be added to this file. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include "skeleton.dtsi" +#include <dt-bindings/clock/samsung,s3c64xx-clock.h> + +/ { + aliases { + i2c0 = &i2c0; + pinctrl0 = &pinctrl0; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,arm1176jzf-s", "arm,arm1176"; + reg = <0x0>; + }; + }; + + soc: soc { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + vic0: interrupt-controller@71200000 { + compatible = "arm,pl192-vic"; + interrupt-controller; + reg = <0x71200000 0x1000>; + #interrupt-cells = <1>; + }; + + vic1: interrupt-controller@71300000 { + compatible = "arm,pl192-vic"; + interrupt-controller; + reg = <0x71300000 0x1000>; + #interrupt-cells = <1>; + }; + + sdhci0: sdhci@7c200000 { + compatible = "samsung,s3c6410-sdhci"; + reg = <0x7c200000 0x100>; + interrupt-parent = <&vic1>; + interrupts = <24>; + clock-names = "hsmmc", "mmc_busclk.0", "mmc_busclk.2"; + clocks = <&clocks HCLK_HSMMC0>, <&clocks HCLK_HSMMC0>, + <&clocks SCLK_MMC0>; + status = "disabled"; + }; + + sdhci1: sdhci@7c300000 { + compatible = "samsung,s3c6410-sdhci"; + reg = <0x7c300000 0x100>; + interrupt-parent = <&vic1>; + interrupts = <25>; + clock-names = "hsmmc", "mmc_busclk.0", "mmc_busclk.2"; + clocks = <&clocks HCLK_HSMMC1>, <&clocks HCLK_HSMMC1>, + <&clocks SCLK_MMC1>; + status = "disabled"; + }; + + sdhci2: sdhci@7c400000 { + compatible = "samsung,s3c6410-sdhci"; + reg = <0x7c400000 0x100>; + interrupt-parent = <&vic1>; + interrupts = <17>; + clock-names = "hsmmc", "mmc_busclk.0", "mmc_busclk.2"; + clocks = <&clocks HCLK_HSMMC2>, <&clocks HCLK_HSMMC2>, + <&clocks SCLK_MMC2>; + status = "disabled"; + }; + + watchdog: watchdog@7e004000 { + compatible = "samsung,s3c2410-wdt"; + reg = <0x7e004000 0x1000>; + interrupt-parent = <&vic0>; + interrupts = <26>; + clock-names = "watchdog"; + clocks = <&clocks PCLK_WDT>; + status = "disabled"; + }; + + i2c0: i2c@7f004000 { + compatible = "samsung,s3c2440-i2c"; + reg = <0x7f004000 0x1000>; + interrupt-parent = <&vic1>; + interrupts = <18>; + clock-names = "i2c"; + clocks = <&clocks PCLK_IIC0>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + uart0: serial@7f005000 { + compatible = "samsung,s3c6400-uart"; + reg = <0x7f005000 0x100>; + interrupt-parent = <&vic1>; + interrupts = <5>; + clock-names = "uart", "clk_uart_baud2", + "clk_uart_baud3"; + clocks = <&clocks PCLK_UART0>, <&clocks PCLK_UART0>, + <&clocks SCLK_UART>; + status = "disabled"; + }; + + uart1: serial@7f005400 { + compatible = "samsung,s3c6400-uart"; + reg = <0x7f005400 0x100>; + interrupt-parent = <&vic1>; + interrupts = <6>; + clock-names = "uart", "clk_uart_baud2", + "clk_uart_baud3"; + clocks = <&clocks PCLK_UART1>, <&clocks PCLK_UART1>, + <&clocks SCLK_UART>; + status = "disabled"; + }; + + uart2: serial@7f005800 { + compatible = "samsung,s3c6400-uart"; + reg = <0x7f005800 0x100>; + interrupt-parent = <&vic1>; + interrupts = <7>; + clock-names = "uart", "clk_uart_baud2", + "clk_uart_baud3"; + clocks = <&clocks PCLK_UART2>, <&clocks PCLK_UART2>, + <&clocks SCLK_UART>; + status = "disabled"; + }; + + uart3: serial@7f005c00 { + compatible = "samsung,s3c6400-uart"; + reg = <0x7f005c00 0x100>; + interrupt-parent = <&vic1>; + interrupts = <8>; + clock-names = "uart", "clk_uart_baud2", + "clk_uart_baud3"; + clocks = <&clocks PCLK_UART3>, <&clocks PCLK_UART3>, + <&clocks SCLK_UART>; + status = "disabled"; + }; + + pwm: pwm@7f006000 { + compatible = "samsung,s3c6400-pwm"; + reg = <0x7f006000 0x1000>; + interrupt-parent = <&vic0>; + interrupts = <23>, <24>, <25>, <27>, <28>; + clock-names = "timers"; + clocks = <&clocks PCLK_PWM>; + samsung,pwm-outputs = <0>, <1>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pinctrl0: pinctrl@7f008000 { + compatible = "samsung,s3c64xx-pinctrl"; + reg = <0x7f008000 0x1000>; + interrupt-parent = <&vic1>; + interrupts = <21>; + + pctrl_int_map: pinctrl-interrupt-map { + interrupt-map = <0 &vic0 0>, + <1 &vic0 1>, + <2 &vic1 0>, + <3 &vic1 1>; + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <1>; + }; + + wakeup-interrupt-controller { + compatible = "samsung,s3c64xx-wakeup-eint"; + interrupts = <0>, <1>, <2>, <3>; + interrupt-parent = <&pctrl_int_map>; + }; + }; + }; +}; + +#include "s3c64xx-pinctrl.dtsi" diff --git a/arch/arm/boot/dts/sama5d3.dtsi b/arch/arm/boot/dts/sama5d3.dtsi index b7f49615120d..5cdaba4cea86 100644 --- a/arch/arm/boot/dts/sama5d3.dtsi +++ b/arch/arm/boot/dts/sama5d3.dtsi @@ -31,7 +31,6 @@ gpio3 = &pioD; gpio4 = &pioE; tcb0 = &tcb0; - tcb1 = &tcb1; i2c0 = &i2c0; i2c1 = &i2c1; i2c2 = &i2c2; @@ -105,15 +104,6 @@ status = "disabled"; }; - can0: can@f000c000 { - compatible = "atmel,at91sam9x5-can"; - reg = <0xf000c000 0x300>; - interrupts = <40 IRQ_TYPE_LEVEL_HIGH 3>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_can0_rx_tx>; - status = "disabled"; - }; - tcb0: timer@f0010000 { compatible = "atmel,at91sam9x5-tcb"; reg = <0xf0010000 0x100>; @@ -166,15 +156,6 @@ status = "disabled"; }; - macb0: ethernet@f0028000 { - compatible = "cdns,pc302-gem", "cdns,gem"; - reg = <0xf0028000 0x100>; - interrupts = <34 IRQ_TYPE_LEVEL_HIGH 3>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_macb0_data_rgmii &pinctrl_macb0_signal_rgmii>; - status = "disabled"; - }; - isi: isi@f0034000 { compatible = "atmel,at91sam9g45-isi"; reg = <0xf0034000 0x4000>; @@ -195,19 +176,6 @@ #size-cells = <0>; }; - mmc2: mmc@f8004000 { - compatible = "atmel,hsmci"; - reg = <0xf8004000 0x600>; - interrupts = <23 IRQ_TYPE_LEVEL_HIGH 0>; - dmas = <&dma1 2 AT91_DMA_CFG_PER_ID(1)>; - dma-names = "rxtx"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_mmc2_clk_cmd_dat0 &pinctrl_mmc2_dat1_3>; - status = "disabled"; - #address-cells = <1>; - #size-cells = <0>; - }; - spi1: spi@f8008000 { #address-cells = <1>; #size-cells = <0>; @@ -231,20 +199,6 @@ status = "disabled"; }; - can1: can@f8010000 { - compatible = "atmel,at91sam9x5-can"; - reg = <0xf8010000 0x300>; - interrupts = <41 IRQ_TYPE_LEVEL_HIGH 3>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_can1_rx_tx>; - }; - - tcb1: timer@f8014000 { - compatible = "atmel,at91sam9x5-tcb"; - reg = <0xf8014000 0x100>; - interrupts = <27 IRQ_TYPE_LEVEL_HIGH 0>; - }; - adc0: adc@f8018000 { compatible = "atmel,at91sam9260-adc"; reg = <0xf8018000 0x100>; @@ -341,15 +295,6 @@ status = "disabled"; }; - macb1: ethernet@f802c000 { - compatible = "cdns,at32ap7000-macb", "cdns,macb"; - reg = <0xf802c000 0x100>; - interrupts = <35 IRQ_TYPE_LEVEL_HIGH 3>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_macb1_rmii>; - status = "disabled"; - }; - sha@f8034000 { compatible = "atmel,sam9g46-sha"; reg = <0xf8034000 0x100>; @@ -474,22 +419,6 @@ }; }; - can0 { - pinctrl_can0_rx_tx: can0_rx_tx { - atmel,pins = - <AT91_PIOD 14 AT91_PERIPH_C AT91_PINCTRL_NONE /* PD14 periph C RX, conflicts with SCK0, SPI0_NPCS1 */ - AT91_PIOD 15 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* PD15 periph C TX, conflicts with CTS0, SPI0_NPCS2 */ - }; - }; - - can1 { - pinctrl_can1_rx_tx: can1_rx_tx { - atmel,pins = - <AT91_PIOB 14 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB14 periph B RX, conflicts with GCRS */ - AT91_PIOB 15 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PB15 periph B TX, conflicts with GCOL */ - }; - }; - dbgu { pinctrl_dbgu: dbgu-0 { atmel,pins = @@ -537,107 +466,6 @@ }; }; - lcd { - pinctrl_lcd: lcd-0 { - atmel,pins = - <AT91_PIOA 24 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA24 periph A LCDPWM */ - AT91_PIOA 26 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA26 periph A LCDVSYNC */ - AT91_PIOA 27 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA27 periph A LCDHSYNC */ - AT91_PIOA 25 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA25 periph A LCDDISP */ - AT91_PIOA 29 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA29 periph A LCDDEN */ - AT91_PIOA 28 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA28 periph A LCDPCK */ - AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA0 periph A LCDD0 pin */ - AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA1 periph A LCDD1 pin */ - AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA2 periph A LCDD2 pin */ - AT91_PIOA 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA3 periph A LCDD3 pin */ - AT91_PIOA 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA4 periph A LCDD4 pin */ - AT91_PIOA 5 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA5 periph A LCDD5 pin */ - AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA6 periph A LCDD6 pin */ - AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA7 periph A LCDD7 pin */ - AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA8 periph A LCDD8 pin */ - AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA9 periph A LCDD9 pin */ - AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA10 periph A LCDD10 pin */ - AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA11 periph A LCDD11 pin */ - AT91_PIOA 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA12 periph A LCDD12 pin */ - AT91_PIOA 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA13 periph A LCDD13 pin */ - AT91_PIOA 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA14 periph A LCDD14 pin */ - AT91_PIOA 15 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA15 periph A LCDD15 pin */ - AT91_PIOC 14 AT91_PERIPH_C AT91_PINCTRL_NONE /* PC14 periph C LCDD16 pin */ - AT91_PIOC 13 AT91_PERIPH_C AT91_PINCTRL_NONE /* PC13 periph C LCDD17 pin */ - AT91_PIOC 12 AT91_PERIPH_C AT91_PINCTRL_NONE /* PC12 periph C LCDD18 pin */ - AT91_PIOC 11 AT91_PERIPH_C AT91_PINCTRL_NONE /* PC11 periph C LCDD19 pin */ - AT91_PIOC 10 AT91_PERIPH_C AT91_PINCTRL_NONE /* PC10 periph C LCDD20 pin */ - AT91_PIOC 15 AT91_PERIPH_C AT91_PINCTRL_NONE /* PC15 periph C LCDD21 pin */ - AT91_PIOE 27 AT91_PERIPH_C AT91_PINCTRL_NONE /* PE27 periph C LCDD22 pin */ - AT91_PIOE 28 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* PE28 periph C LCDD23 pin */ - }; - }; - - macb0 { - pinctrl_macb0_data_rgmii: macb0_data_rgmii { - atmel,pins = - <AT91_PIOB 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB0 periph A GTX0, conflicts with PWMH0 */ - AT91_PIOB 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB1 periph A GTX1, conflicts with PWML0 */ - AT91_PIOB 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB2 periph A GTX2, conflicts with TK1 */ - AT91_PIOB 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB3 periph A GTX3, conflicts with TF1 */ - AT91_PIOB 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB4 periph A GRX0, conflicts with PWMH1 */ - AT91_PIOB 5 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB5 periph A GRX1, conflicts with PWML1 */ - AT91_PIOB 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB6 periph A GRX2, conflicts with TD1 */ - AT91_PIOB 7 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB7 periph A GRX3, conflicts with RK1 */ - }; - pinctrl_macb0_data_gmii: macb0_data_gmii { - atmel,pins = - <AT91_PIOB 19 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB19 periph B GTX4, conflicts with MCI1_CDA */ - AT91_PIOB 20 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB20 periph B GTX5, conflicts with MCI1_DA0 */ - AT91_PIOB 21 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB21 periph B GTX6, conflicts with MCI1_DA1 */ - AT91_PIOB 22 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB22 periph B GTX7, conflicts with MCI1_DA2 */ - AT91_PIOB 23 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB23 periph B GRX4, conflicts with MCI1_DA3 */ - AT91_PIOB 24 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB24 periph B GRX5, conflicts with MCI1_CK */ - AT91_PIOB 25 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB25 periph B GRX6, conflicts with SCK1 */ - AT91_PIOB 26 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PB26 periph B GRX7, conflicts with CTS1 */ - }; - pinctrl_macb0_signal_rgmii: macb0_signal_rgmii { - atmel,pins = - <AT91_PIOB 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB8 periph A GTXCK, conflicts with PWMH2 */ - AT91_PIOB 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB9 periph A GTXEN, conflicts with PWML2 */ - AT91_PIOB 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB11 periph A GRXCK, conflicts with RD1 */ - AT91_PIOB 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB13 periph A GRXER, conflicts with PWML3 */ - AT91_PIOB 16 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB16 periph A GMDC */ - AT91_PIOB 17 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB17 periph A GMDIO */ - AT91_PIOB 18 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB18 periph A G125CK */ - }; - pinctrl_macb0_signal_gmii: macb0_signal_gmii { - atmel,pins = - <AT91_PIOB 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB9 periph A GTXEN, conflicts with PWML2 */ - AT91_PIOB 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB10 periph A GTXER, conflicts with RF1 */ - AT91_PIOB 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB11 periph A GRXCK, conflicts with RD1 */ - AT91_PIOB 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB12 periph A GRXDV, conflicts with PWMH3 */ - AT91_PIOB 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB13 periph A GRXER, conflicts with PWML3 */ - AT91_PIOB 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB14 periph A GCRS, conflicts with CANRX1 */ - AT91_PIOB 15 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB15 periph A GCOL, conflicts with CANTX1 */ - AT91_PIOB 16 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB16 periph A GMDC */ - AT91_PIOB 17 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB17 periph A GMDIO */ - AT91_PIOB 27 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PB27 periph B G125CKO */ - }; - - }; - - macb1 { - pinctrl_macb1_rmii: macb1_rmii-0 { - atmel,pins = - <AT91_PIOC 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC0 periph A ETX0, conflicts with TIOA3 */ - AT91_PIOC 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC1 periph A ETX1, conflicts with TIOB3 */ - AT91_PIOC 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC2 periph A ERX0, conflicts with TCLK3 */ - AT91_PIOC 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC3 periph A ERX1, conflicts with TIOA4 */ - AT91_PIOC 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC4 periph A ETXEN, conflicts with TIOB4 */ - AT91_PIOC 5 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC5 periph A ECRSDV,conflicts with TCLK4 */ - AT91_PIOC 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC6 periph A ERXER, conflicts with TIOA5 */ - AT91_PIOC 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC7 periph A EREFCK, conflicts with TIOB5 */ - AT91_PIOC 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC8 periph A EMDC, conflicts with TCLK5 */ - AT91_PIOC 9 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PC9 periph A EMDIO */ - }; - }; - mmc0 { pinctrl_mmc0_clk_cmd_dat0: mmc0_clk_cmd_dat0 { atmel,pins = @@ -675,21 +503,6 @@ }; }; - mmc2 { - pinctrl_mmc2_clk_cmd_dat0: mmc2_clk_cmd_dat0 { - atmel,pins = - <AT91_PIOC 15 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC15 periph A MCI2_CK, conflicts with PCK2 */ - AT91_PIOC 10 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PC10 periph A MCI2_CDA with pullup */ - AT91_PIOC 11 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PC11 periph A MCI2_DA0 with pullup */ - }; - pinctrl_mmc2_dat1_3: mmc2_dat1_3 { - atmel,pins = - <AT91_PIOC 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC12 periph A MCI2_DA1 with pullup, conflicts with TIOA1 */ - AT91_PIOC 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC13 periph A MCI2_DA2 with pullup, conflicts with TIOB1 */ - AT91_PIOC 14 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PC14 periph A MCI2_DA3 with pullup, conflicts with TCLK1 */ - }; - }; - nand0 { pinctrl_nand0_ale_cle: nand0_ale_cle-0 { atmel,pins = @@ -748,22 +561,6 @@ }; }; - uart0 { - pinctrl_uart0: uart0-0 { - atmel,pins = - <AT91_PIOC 29 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC29 periph A, conflicts with PWMFI2, ISI_D8 */ - AT91_PIOC 30 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PC30 periph A with pullup, conflicts with ISI_PCK */ - }; - }; - - uart1 { - pinctrl_uart1: uart1-0 { - atmel,pins = - <AT91_PIOA 30 AT91_PERIPH_B AT91_PINCTRL_NONE /* PA30 periph B, conflicts with TWD0, ISI_VSYNC */ - AT91_PIOA 31 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>; /* PA31 periph B with pullup, conflicts with TWCK0, ISI_HSYNC */ - }; - }; - usart0 { pinctrl_usart0: usart0-0 { atmel,pins = diff --git a/arch/arm/boot/dts/sama5d31.dtsi b/arch/arm/boot/dts/sama5d31.dtsi new file mode 100644 index 000000000000..7997dc9863ed --- /dev/null +++ b/arch/arm/boot/dts/sama5d31.dtsi @@ -0,0 +1,16 @@ +/* + * sama5d31.dtsi - Device Tree Include file for SAMA5D31 SoC + * + * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com> + * + * Licensed under GPLv2 or later. + */ +#include "sama5d3.dtsi" +#include "sama5d3_lcd.dtsi" +#include "sama5d3_emac.dtsi" +#include "sama5d3_mci2.dtsi" +#include "sama5d3_uart.dtsi" + +/ { + compatible = "atmel,samad31", "atmel,sama5d3", "atmel,sama5"; +}; diff --git a/arch/arm/boot/dts/sama5d31ek.dts b/arch/arm/boot/dts/sama5d31ek.dts index 027bac7510b6..04eec0dfcf7d 100644 --- a/arch/arm/boot/dts/sama5d31ek.dts +++ b/arch/arm/boot/dts/sama5d31ek.dts @@ -7,12 +7,13 @@ * Licensed under GPLv2 or later. */ /dts-v1/; +#include "sama5d31.dtsi" #include "sama5d3xmb.dtsi" #include "sama5d3xdm.dtsi" / { model = "Atmel SAMA5D31-EK"; - compatible = "atmel,sama5d31ek", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d3", "atmel,sama5"; + compatible = "atmel,sama5d31ek", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d31", "atmel,sama5d3", "atmel,sama5"; ahb { apb { diff --git a/arch/arm/boot/dts/sama5d33.dtsi b/arch/arm/boot/dts/sama5d33.dtsi new file mode 100644 index 000000000000..39f832253caf --- /dev/null +++ b/arch/arm/boot/dts/sama5d33.dtsi @@ -0,0 +1,14 @@ +/* + * sama5d33.dtsi - Device Tree Include file for SAMA5D33 SoC + * + * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com> + * + * Licensed under GPLv2 or later. + */ +#include "sama5d3.dtsi" +#include "sama5d3_lcd.dtsi" +#include "sama5d3_gmac.dtsi" + +/ { + compatible = "atmel,samad33", "atmel,sama5d3", "atmel,sama5"; +}; diff --git a/arch/arm/boot/dts/sama5d33ek.dts b/arch/arm/boot/dts/sama5d33ek.dts index 99bd0c8e0471..cbd6a3ff1545 100644 --- a/arch/arm/boot/dts/sama5d33ek.dts +++ b/arch/arm/boot/dts/sama5d33ek.dts @@ -7,12 +7,13 @@ * Licensed under GPLv2 or later. */ /dts-v1/; +#include "sama5d33.dtsi" #include "sama5d3xmb.dtsi" #include "sama5d3xdm.dtsi" / { model = "Atmel SAMA5D33-EK"; - compatible = "atmel,sama5d33ek", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d3", "atmel,sama5"; + compatible = "atmel,sama5d33ek", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d33", "atmel,sama5d3", "atmel,sama5"; ahb { apb { diff --git a/arch/arm/boot/dts/sama5d34.dtsi b/arch/arm/boot/dts/sama5d34.dtsi new file mode 100644 index 000000000000..89cda2c0da39 --- /dev/null +++ b/arch/arm/boot/dts/sama5d34.dtsi @@ -0,0 +1,16 @@ +/* + * sama5d34.dtsi - Device Tree Include file for SAMA5D34 SoC + * + * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com> + * + * Licensed under GPLv2 or later. + */ +#include "sama5d3.dtsi" +#include "sama5d3_lcd.dtsi" +#include "sama5d3_gmac.dtsi" +#include "sama5d3_can.dtsi" +#include "sama5d3_mci2.dtsi" + +/ { + compatible = "atmel,samad34", "atmel,sama5d3", "atmel,sama5"; +}; diff --git a/arch/arm/boot/dts/sama5d34ek.dts b/arch/arm/boot/dts/sama5d34ek.dts index fb8ee11cf282..878aa164275a 100644 --- a/arch/arm/boot/dts/sama5d34ek.dts +++ b/arch/arm/boot/dts/sama5d34ek.dts @@ -7,12 +7,13 @@ * Licensed under GPLv2 or later. */ /dts-v1/; +#include "sama5d34.dtsi" #include "sama5d3xmb.dtsi" #include "sama5d3xdm.dtsi" / { model = "Atmel SAMA5D34-EK"; - compatible = "atmel,sama5d34ek", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d3", "atmel,sama5"; + compatible = "atmel,sama5d34ek", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d34", "atmel,sama5d3", "atmel,sama5"; ahb { apb { diff --git a/arch/arm/boot/dts/sama5d35.dtsi b/arch/arm/boot/dts/sama5d35.dtsi new file mode 100644 index 000000000000..d20cd71b5f0e --- /dev/null +++ b/arch/arm/boot/dts/sama5d35.dtsi @@ -0,0 +1,18 @@ +/* + * sama5d35.dtsi - Device Tree Include file for SAMA5D35 SoC + * + * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com> + * + * Licensed under GPLv2 or later. + */ +#include "sama5d3.dtsi" +#include "sama5d3_gmac.dtsi" +#include "sama5d3_emac.dtsi" +#include "sama5d3_can.dtsi" +#include "sama5d3_mci2.dtsi" +#include "sama5d3_uart.dtsi" +#include "sama5d3_tcb1.dtsi" + +/ { + compatible = "atmel,samad35", "atmel,sama5d3", "atmel,sama5"; +}; diff --git a/arch/arm/boot/dts/sama5d35ek.dts b/arch/arm/boot/dts/sama5d35ek.dts index 509a53d9cc7b..9089c7c6cea8 100644 --- a/arch/arm/boot/dts/sama5d35ek.dts +++ b/arch/arm/boot/dts/sama5d35ek.dts @@ -7,11 +7,12 @@ * Licensed under GPLv2 or later. */ /dts-v1/; +#include "sama5d35.dtsi" #include "sama5d3xmb.dtsi" / { model = "Atmel SAMA5D35-EK"; - compatible = "atmel,sama5d35ek", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d3", "atmel,sama5"; + compatible = "atmel,sama5d35ek", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d35", "atmel,sama5d3", "atmel,sama5"; ahb { apb { diff --git a/arch/arm/boot/dts/sama5d3_can.dtsi b/arch/arm/boot/dts/sama5d3_can.dtsi new file mode 100644 index 000000000000..8ed3260cef66 --- /dev/null +++ b/arch/arm/boot/dts/sama5d3_can.dtsi @@ -0,0 +1,54 @@ +/* + * at91sama5d3_can.dtsi - Device Tree Include file for AT91SAM9x5 SoC with + * CAN support + * + * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com> + * + * Licensed under GPLv2. + */ + +#include <dt-bindings/pinctrl/at91.h> +#include <dt-bindings/interrupt-controller/irq.h> + +/ { + ahb { + apb { + pinctrl@fffff200 { + can0 { + pinctrl_can0_rx_tx: can0_rx_tx { + atmel,pins = + <AT91_PIOD 14 AT91_PERIPH_C AT91_PINCTRL_NONE /* PD14 periph C RX, conflicts with SCK0, SPI0_NPCS1 */ + AT91_PIOD 15 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* PD15 periph C TX, conflicts with CTS0, SPI0_NPCS2 */ + }; + }; + + can1 { + pinctrl_can1_rx_tx: can1_rx_tx { + atmel,pins = + <AT91_PIOB 14 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB14 periph B RX, conflicts with GCRS */ + AT91_PIOB 15 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PB15 periph B TX, conflicts with GCOL */ + }; + }; + + }; + + can0: can@f000c000 { + compatible = "atmel,at91sam9x5-can"; + reg = <0xf000c000 0x300>; + interrupts = <40 IRQ_TYPE_LEVEL_HIGH 3>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_can0_rx_tx>; + status = "disabled"; + }; + + can1: can@f8010000 { + compatible = "atmel,at91sam9x5-can"; + reg = <0xf8010000 0x300>; + interrupts = <41 IRQ_TYPE_LEVEL_HIGH 3>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_can1_rx_tx>; + status = "disabled"; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/sama5d3_emac.dtsi b/arch/arm/boot/dts/sama5d3_emac.dtsi new file mode 100644 index 000000000000..4d4f351f1f9f --- /dev/null +++ b/arch/arm/boot/dts/sama5d3_emac.dtsi @@ -0,0 +1,44 @@ +/* + * at91sama5d3_emac.dtsi - Device Tree Include file for AT91SAM9x5 SoC with + * Ethernet. + * + * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com> + * + * Licensed under GPLv2. + */ + +#include <dt-bindings/pinctrl/at91.h> +#include <dt-bindings/interrupt-controller/irq.h> + +/ { + ahb { + apb { + pinctrl@fffff200 { + macb1 { + pinctrl_macb1_rmii: macb1_rmii-0 { + atmel,pins = + <AT91_PIOC 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC0 periph A ETX0, conflicts with TIOA3 */ + AT91_PIOC 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC1 periph A ETX1, conflicts with TIOB3 */ + AT91_PIOC 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC2 periph A ERX0, conflicts with TCLK3 */ + AT91_PIOC 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC3 periph A ERX1, conflicts with TIOA4 */ + AT91_PIOC 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC4 periph A ETXEN, conflicts with TIOB4 */ + AT91_PIOC 5 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC5 periph A ECRSDV,conflicts with TCLK4 */ + AT91_PIOC 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC6 periph A ERXER, conflicts with TIOA5 */ + AT91_PIOC 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC7 periph A EREFCK, conflicts with TIOB5 */ + AT91_PIOC 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC8 periph A EMDC, conflicts with TCLK5 */ + AT91_PIOC 9 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PC9 periph A EMDIO */ + }; + }; + }; + + macb1: ethernet@f802c000 { + compatible = "cdns,at32ap7000-macb", "cdns,macb"; + reg = <0xf802c000 0x100>; + interrupts = <35 IRQ_TYPE_LEVEL_HIGH 3>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_macb1_rmii>; + status = "disabled"; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/sama5d3_gmac.dtsi b/arch/arm/boot/dts/sama5d3_gmac.dtsi new file mode 100644 index 000000000000..0ba8be30ccd8 --- /dev/null +++ b/arch/arm/boot/dts/sama5d3_gmac.dtsi @@ -0,0 +1,77 @@ +/* + * at91sama5d3_gmac.dtsi - Device Tree Include file for AT91SAM9x5 SoC with + * Gigabit Ethernet. + * + * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com> + * + * Licensed under GPLv2. + */ + +#include <dt-bindings/pinctrl/at91.h> +#include <dt-bindings/interrupt-controller/irq.h> + +/ { + ahb { + apb { + pinctrl@fffff200 { + macb0 { + pinctrl_macb0_data_rgmii: macb0_data_rgmii { + atmel,pins = + <AT91_PIOB 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB0 periph A GTX0, conflicts with PWMH0 */ + AT91_PIOB 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB1 periph A GTX1, conflicts with PWML0 */ + AT91_PIOB 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB2 periph A GTX2, conflicts with TK1 */ + AT91_PIOB 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB3 periph A GTX3, conflicts with TF1 */ + AT91_PIOB 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB4 periph A GRX0, conflicts with PWMH1 */ + AT91_PIOB 5 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB5 periph A GRX1, conflicts with PWML1 */ + AT91_PIOB 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB6 periph A GRX2, conflicts with TD1 */ + AT91_PIOB 7 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB7 periph A GRX3, conflicts with RK1 */ + }; + pinctrl_macb0_data_gmii: macb0_data_gmii { + atmel,pins = + <AT91_PIOB 19 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB19 periph B GTX4, conflicts with MCI1_CDA */ + AT91_PIOB 20 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB20 periph B GTX5, conflicts with MCI1_DA0 */ + AT91_PIOB 21 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB21 periph B GTX6, conflicts with MCI1_DA1 */ + AT91_PIOB 22 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB22 periph B GTX7, conflicts with MCI1_DA2 */ + AT91_PIOB 23 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB23 periph B GRX4, conflicts with MCI1_DA3 */ + AT91_PIOB 24 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB24 periph B GRX5, conflicts with MCI1_CK */ + AT91_PIOB 25 AT91_PERIPH_B AT91_PINCTRL_NONE /* PB25 periph B GRX6, conflicts with SCK1 */ + AT91_PIOB 26 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PB26 periph B GRX7, conflicts with CTS1 */ + }; + pinctrl_macb0_signal_rgmii: macb0_signal_rgmii { + atmel,pins = + <AT91_PIOB 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB8 periph A GTXCK, conflicts with PWMH2 */ + AT91_PIOB 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB9 periph A GTXEN, conflicts with PWML2 */ + AT91_PIOB 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB11 periph A GRXCK, conflicts with RD1 */ + AT91_PIOB 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB13 periph A GRXER, conflicts with PWML3 */ + AT91_PIOB 16 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB16 periph A GMDC */ + AT91_PIOB 17 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB17 periph A GMDIO */ + AT91_PIOB 18 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB18 periph A G125CK */ + }; + pinctrl_macb0_signal_gmii: macb0_signal_gmii { + atmel,pins = + <AT91_PIOB 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB9 periph A GTXEN, conflicts with PWML2 */ + AT91_PIOB 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB10 periph A GTXER, conflicts with RF1 */ + AT91_PIOB 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB11 periph A GRXCK, conflicts with RD1 */ + AT91_PIOB 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB12 periph A GRXDV, conflicts with PWMH3 */ + AT91_PIOB 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB13 periph A GRXER, conflicts with PWML3 */ + AT91_PIOB 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB14 periph A GCRS, conflicts with CANRX1 */ + AT91_PIOB 15 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB15 periph A GCOL, conflicts with CANTX1 */ + AT91_PIOB 16 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB16 periph A GMDC */ + AT91_PIOB 17 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB17 periph A GMDIO */ + AT91_PIOB 27 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PB27 periph B G125CKO */ + }; + + }; + }; + + macb0: ethernet@f0028000 { + compatible = "cdns,pc302-gem", "cdns,gem"; + reg = <0xf0028000 0x100>; + interrupts = <34 IRQ_TYPE_LEVEL_HIGH 3>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_macb0_data_rgmii &pinctrl_macb0_signal_rgmii>; + status = "disabled"; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/sama5d3_lcd.dtsi b/arch/arm/boot/dts/sama5d3_lcd.dtsi new file mode 100644 index 000000000000..01f52a79f8ba --- /dev/null +++ b/arch/arm/boot/dts/sama5d3_lcd.dtsi @@ -0,0 +1,55 @@ +/* + * at91sama5d3_lcd.dtsi - Device Tree Include file for AT91SAM9x5 SoC with + * LCD support + * + * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com> + * + * Licensed under GPLv2. + */ + +#include <dt-bindings/pinctrl/at91.h> +#include <dt-bindings/interrupt-controller/irq.h> + +/ { + ahb { + apb { + pinctrl@fffff200 { + lcd { + pinctrl_lcd: lcd-0 { + atmel,pins = + <AT91_PIOA 24 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA24 periph A LCDPWM */ + AT91_PIOA 26 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA26 periph A LCDVSYNC */ + AT91_PIOA 27 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA27 periph A LCDHSYNC */ + AT91_PIOA 25 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA25 periph A LCDDISP */ + AT91_PIOA 29 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA29 periph A LCDDEN */ + AT91_PIOA 28 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA28 periph A LCDPCK */ + AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA0 periph A LCDD0 pin */ + AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA1 periph A LCDD1 pin */ + AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA2 periph A LCDD2 pin */ + AT91_PIOA 3 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA3 periph A LCDD3 pin */ + AT91_PIOA 4 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA4 periph A LCDD4 pin */ + AT91_PIOA 5 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA5 periph A LCDD5 pin */ + AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA6 periph A LCDD6 pin */ + AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA7 periph A LCDD7 pin */ + AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA8 periph A LCDD8 pin */ + AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA9 periph A LCDD9 pin */ + AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA10 periph A LCDD10 pin */ + AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA11 periph A LCDD11 pin */ + AT91_PIOA 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA12 periph A LCDD12 pin */ + AT91_PIOA 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA13 periph A LCDD13 pin */ + AT91_PIOA 14 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA14 periph A LCDD14 pin */ + AT91_PIOA 15 AT91_PERIPH_A AT91_PINCTRL_NONE /* PA15 periph A LCDD15 pin */ + AT91_PIOC 14 AT91_PERIPH_C AT91_PINCTRL_NONE /* PC14 periph C LCDD16 pin */ + AT91_PIOC 13 AT91_PERIPH_C AT91_PINCTRL_NONE /* PC13 periph C LCDD17 pin */ + AT91_PIOC 12 AT91_PERIPH_C AT91_PINCTRL_NONE /* PC12 periph C LCDD18 pin */ + AT91_PIOC 11 AT91_PERIPH_C AT91_PINCTRL_NONE /* PC11 periph C LCDD19 pin */ + AT91_PIOC 10 AT91_PERIPH_C AT91_PINCTRL_NONE /* PC10 periph C LCDD20 pin */ + AT91_PIOC 15 AT91_PERIPH_C AT91_PINCTRL_NONE /* PC15 periph C LCDD21 pin */ + AT91_PIOE 27 AT91_PERIPH_C AT91_PINCTRL_NONE /* PE27 periph C LCDD22 pin */ + AT91_PIOE 28 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* PE28 periph C LCDD23 pin */ + }; + }; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/sama5d3_mci2.dtsi b/arch/arm/boot/dts/sama5d3_mci2.dtsi new file mode 100644 index 000000000000..38e88e39e551 --- /dev/null +++ b/arch/arm/boot/dts/sama5d3_mci2.dtsi @@ -0,0 +1,47 @@ +/* + * at91sama5d3_mci2.dtsi - Device Tree Include file for AT91SAM9x5 SoC with + * 3 MMC ports + * + * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com> + * + * Licensed under GPLv2. + */ + +#include <dt-bindings/pinctrl/at91.h> +#include <dt-bindings/interrupt-controller/irq.h> + +/ { + ahb { + apb { + pinctrl@fffff200 { + mmc2 { + pinctrl_mmc2_clk_cmd_dat0: mmc2_clk_cmd_dat0 { + atmel,pins = + <AT91_PIOC 15 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC15 periph A MCI2_CK, conflicts with PCK2 */ + AT91_PIOC 10 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PC10 periph A MCI2_CDA with pullup */ + AT91_PIOC 11 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PC11 periph A MCI2_DA0 with pullup */ + }; + pinctrl_mmc2_dat1_3: mmc2_dat1_3 { + atmel,pins = + <AT91_PIOC 12 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC12 periph A MCI2_DA1 with pullup, conflicts with TIOA1 */ + AT91_PIOC 13 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC13 periph A MCI2_DA2 with pullup, conflicts with TIOB1 */ + AT91_PIOC 14 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PC14 periph A MCI2_DA3 with pullup, conflicts with TCLK1 */ + }; + }; + }; + + mmc2: mmc@f8004000 { + compatible = "atmel,hsmci"; + reg = <0xf8004000 0x600>; + interrupts = <23 IRQ_TYPE_LEVEL_HIGH 0>; + dmas = <&dma1 2 AT91_DMA_CFG_PER_ID(1)>; + dma-names = "rxtx"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_mmc2_clk_cmd_dat0 &pinctrl_mmc2_dat1_3>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/sama5d3_tcb1.dtsi b/arch/arm/boot/dts/sama5d3_tcb1.dtsi new file mode 100644 index 000000000000..5264bb4a6998 --- /dev/null +++ b/arch/arm/boot/dts/sama5d3_tcb1.dtsi @@ -0,0 +1,27 @@ +/* + * at91sama5d3_tcb1.dtsi - Device Tree Include file for AT91SAM9x5 SoC with + * 2 TC blocks. + * + * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com> + * + * Licensed under GPLv2. + */ + +#include <dt-bindings/pinctrl/at91.h> +#include <dt-bindings/interrupt-controller/irq.h> + +/ { + aliases { + tcb1 = &tcb1; + }; + + ahb { + apb { + tcb1: timer@f8014000 { + compatible = "atmel,at91sam9x5-tcb"; + reg = <0xf8014000 0x100>; + interrupts = <27 IRQ_TYPE_LEVEL_HIGH 0>; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/sama5d3_uart.dtsi b/arch/arm/boot/dts/sama5d3_uart.dtsi new file mode 100644 index 000000000000..98fcb2d57446 --- /dev/null +++ b/arch/arm/boot/dts/sama5d3_uart.dtsi @@ -0,0 +1,53 @@ +/* + * at91sama5d3_uart.dtsi - Device Tree Include file for AT91SAM9x5 SoC with + * UART support + * + * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com> + * + * Licensed under GPLv2. + */ + +#include <dt-bindings/pinctrl/at91.h> +#include <dt-bindings/interrupt-controller/irq.h> + +/ { + ahb { + apb { + pinctrl@fffff200 { + uart0 { + pinctrl_uart0: uart0-0 { + atmel,pins = + <AT91_PIOC 29 AT91_PERIPH_A AT91_PINCTRL_NONE /* PC29 periph A, conflicts with PWMFI2, ISI_D8 */ + AT91_PIOC 30 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PC30 periph A with pullup, conflicts with ISI_PCK */ + }; + }; + + uart1 { + pinctrl_uart1: uart1-0 { + atmel,pins = + <AT91_PIOA 30 AT91_PERIPH_B AT91_PINCTRL_NONE /* PA30 periph B, conflicts with TWD0, ISI_VSYNC */ + AT91_PIOA 31 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>; /* PA31 periph B with pullup, conflicts with TWCK0, ISI_HSYNC */ + }; + }; + }; + + uart0: serial@f0024000 { + compatible = "atmel,at91sam9260-usart"; + reg = <0xf0024000 0x200>; + interrupts = <16 IRQ_TYPE_LEVEL_HIGH 5>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart0>; + status = "disabled"; + }; + + uart1: serial@f8028000 { + compatible = "atmel,at91sam9260-usart"; + reg = <0xf8028000 0x200>; + interrupts = <17 IRQ_TYPE_LEVEL_HIGH 5>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1>; + status = "disabled"; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/sama5d3xcm.dtsi b/arch/arm/boot/dts/sama5d3xcm.dtsi index 31ed9e3bb649..726a0f35100c 100644 --- a/arch/arm/boot/dts/sama5d3xcm.dtsi +++ b/arch/arm/boot/dts/sama5d3xcm.dtsi @@ -6,7 +6,6 @@ * * Licensed under GPLv2 or later. */ -#include "sama5d3.dtsi" / { compatible = "atmel,samad3xcm", "atmel,sama5d3", "atmel,sama5"; diff --git a/arch/arm/boot/dts/sh73a0-kzm9g-reference.dts b/arch/arm/boot/dts/sh73a0-kzm9g-reference.dts index 212230629f27..8ee06dd81799 100644 --- a/arch/arm/boot/dts/sh73a0-kzm9g-reference.dts +++ b/arch/arm/boot/dts/sh73a0-kzm9g-reference.dts @@ -108,6 +108,7 @@ }; &i2c0 { + status = "okay"; as3711@40 { compatible = "ams,as3711"; reg = <0x40>; @@ -183,6 +184,7 @@ &i2c3 { pinctrl-0 = <&i2c3_pins>; pinctrl-names = "default"; + status = "okay"; }; &mmcif { diff --git a/arch/arm/boot/dts/sh73a0.dtsi b/arch/arm/boot/dts/sh73a0.dtsi index 3955c7606a6f..fcf26889a8a0 100644 --- a/arch/arm/boot/dts/sh73a0.dtsi +++ b/arch/arm/boot/dts/sh73a0.dtsi @@ -135,6 +135,7 @@ 0 168 0x4 0 169 0x4 0 170 0x4>; + status = "disabled"; }; i2c1: i2c@e6822000 { @@ -147,6 +148,7 @@ 0 52 0x4 0 53 0x4 0 54 0x4>; + status = "disabled"; }; i2c2: i2c@e6824000 { @@ -159,6 +161,7 @@ 0 172 0x4 0 173 0x4 0 174 0x4>; + status = "disabled"; }; i2c3: i2c@e6826000 { @@ -171,6 +174,7 @@ 0 184 0x4 0 185 0x4 0 186 0x4>; + status = "disabled"; }; i2c4: i2c@e6828000 { @@ -183,6 +187,7 @@ 0 188 0x4 0 189 0x4 0 190 0x4>; + status = "disabled"; }; mmcif: mmcif@e6bd0000 { diff --git a/arch/arm/boot/dts/socfpga.dtsi b/arch/arm/boot/dts/socfpga.dtsi index e273fa993b8c..6d09b8d42fdd 100644 --- a/arch/arm/boot/dts/socfpga.dtsi +++ b/arch/arm/boot/dts/socfpga.dtsi @@ -147,7 +147,7 @@ reg = <0x58>; }; - cfg_s2f_usr0_clk: cfg_s2f_usr0_clk { + cfg_h2f_usr0_clk: cfg_h2f_usr0_clk { #clock-cells = <0>; compatible = "altr,socfpga-perip-clk"; clocks = <&main_pll>; @@ -198,7 +198,7 @@ reg = <0x98>; }; - s2f_usr1_clk: s2f_usr1_clk { + h2f_usr1_clk: h2f_usr1_clk { #clock-cells = <0>; compatible = "altr,socfpga-perip-clk"; clocks = <&periph_pll>; @@ -235,7 +235,7 @@ reg = <0xD0>; }; - s2f_usr2_clk: s2f_usr2_clk { + h2f_usr2_clk: h2f_usr2_clk { #clock-cells = <0>; compatible = "altr,socfpga-perip-clk"; clocks = <&sdram_pll>; @@ -243,197 +243,197 @@ }; }; - mpu_periph_clk: mpu_periph_clk { - #clock-cells = <0>; - compatible = "altr,socfpga-gate-clk"; - clocks = <&mpuclk>; - fixed-divider = <4>; + mpu_periph_clk: mpu_periph_clk { + #clock-cells = <0>; + compatible = "altr,socfpga-gate-clk"; + clocks = <&mpuclk>; + fixed-divider = <4>; }; - mpu_l2_ram_clk: mpu_l2_ram_clk { - #clock-cells = <0>; - compatible = "altr,socfpga-gate-clk"; - clocks = <&mpuclk>; - fixed-divider = <2>; + mpu_l2_ram_clk: mpu_l2_ram_clk { + #clock-cells = <0>; + compatible = "altr,socfpga-gate-clk"; + clocks = <&mpuclk>; + fixed-divider = <2>; }; - l4_main_clk: l4_main_clk { - #clock-cells = <0>; - compatible = "altr,socfpga-gate-clk"; - clocks = <&mainclk>; - clk-gate = <0x60 0>; + l4_main_clk: l4_main_clk { + #clock-cells = <0>; + compatible = "altr,socfpga-gate-clk"; + clocks = <&mainclk>; + clk-gate = <0x60 0>; }; - l3_main_clk: l3_main_clk { - #clock-cells = <0>; - compatible = "altr,socfpga-gate-clk"; - clocks = <&mainclk>; + l3_main_clk: l3_main_clk { + #clock-cells = <0>; + compatible = "altr,socfpga-gate-clk"; + clocks = <&mainclk>; }; - l3_mp_clk: l3_mp_clk { - #clock-cells = <0>; - compatible = "altr,socfpga-gate-clk"; - clocks = <&mainclk>; - div-reg = <0x64 0 2>; - clk-gate = <0x60 1>; + l3_mp_clk: l3_mp_clk { + #clock-cells = <0>; + compatible = "altr,socfpga-gate-clk"; + clocks = <&mainclk>; + div-reg = <0x64 0 2>; + clk-gate = <0x60 1>; }; - l3_sp_clk: l3_sp_clk { - #clock-cells = <0>; - compatible = "altr,socfpga-gate-clk"; - clocks = <&mainclk>; - div-reg = <0x64 2 2>; - }; + l3_sp_clk: l3_sp_clk { + #clock-cells = <0>; + compatible = "altr,socfpga-gate-clk"; + clocks = <&mainclk>; + div-reg = <0x64 2 2>; + }; - l4_mp_clk: l4_mp_clk { - #clock-cells = <0>; - compatible = "altr,socfpga-gate-clk"; - clocks = <&mainclk>, <&per_base_clk>; - div-reg = <0x64 4 3>; - clk-gate = <0x60 2>; + l4_mp_clk: l4_mp_clk { + #clock-cells = <0>; + compatible = "altr,socfpga-gate-clk"; + clocks = <&mainclk>, <&per_base_clk>; + div-reg = <0x64 4 3>; + clk-gate = <0x60 2>; }; - l4_sp_clk: l4_sp_clk { - #clock-cells = <0>; - compatible = "altr,socfpga-gate-clk"; - clocks = <&mainclk>, <&per_base_clk>; - div-reg = <0x64 7 3>; - clk-gate = <0x60 3>; + l4_sp_clk: l4_sp_clk { + #clock-cells = <0>; + compatible = "altr,socfpga-gate-clk"; + clocks = <&mainclk>, <&per_base_clk>; + div-reg = <0x64 7 3>; + clk-gate = <0x60 3>; }; - dbg_at_clk: dbg_at_clk { - #clock-cells = <0>; - compatible = "altr,socfpga-gate-clk"; - clocks = <&dbg_base_clk>; - div-reg = <0x68 0 2>; - clk-gate = <0x60 4>; + dbg_at_clk: dbg_at_clk { + #clock-cells = <0>; + compatible = "altr,socfpga-gate-clk"; + clocks = <&dbg_base_clk>; + div-reg = <0x68 0 2>; + clk-gate = <0x60 4>; }; - dbg_clk: dbg_clk { - #clock-cells = <0>; - compatible = "altr,socfpga-gate-clk"; - clocks = <&dbg_base_clk>; - div-reg = <0x68 2 2>; - clk-gate = <0x60 5>; + dbg_clk: dbg_clk { + #clock-cells = <0>; + compatible = "altr,socfpga-gate-clk"; + clocks = <&dbg_base_clk>; + div-reg = <0x68 2 2>; + clk-gate = <0x60 5>; }; - dbg_trace_clk: dbg_trace_clk { - #clock-cells = <0>; - compatible = "altr,socfpga-gate-clk"; - clocks = <&dbg_base_clk>; - div-reg = <0x6C 0 3>; - clk-gate = <0x60 6>; + dbg_trace_clk: dbg_trace_clk { + #clock-cells = <0>; + compatible = "altr,socfpga-gate-clk"; + clocks = <&dbg_base_clk>; + div-reg = <0x6C 0 3>; + clk-gate = <0x60 6>; }; - dbg_timer_clk: dbg_timer_clk { - #clock-cells = <0>; - compatible = "altr,socfpga-gate-clk"; - clocks = <&dbg_base_clk>; - clk-gate = <0x60 7>; + dbg_timer_clk: dbg_timer_clk { + #clock-cells = <0>; + compatible = "altr,socfpga-gate-clk"; + clocks = <&dbg_base_clk>; + clk-gate = <0x60 7>; }; - cfg_clk: cfg_clk { - #clock-cells = <0>; - compatible = "altr,socfpga-gate-clk"; - clocks = <&cfg_s2f_usr0_clk>; - clk-gate = <0x60 8>; + cfg_clk: cfg_clk { + #clock-cells = <0>; + compatible = "altr,socfpga-gate-clk"; + clocks = <&cfg_h2f_usr0_clk>; + clk-gate = <0x60 8>; }; - s2f_user0_clk: s2f_user0_clk { - #clock-cells = <0>; - compatible = "altr,socfpga-gate-clk"; - clocks = <&cfg_s2f_usr0_clk>; - clk-gate = <0x60 9>; + h2f_user0_clk: h2f_user0_clk { + #clock-cells = <0>; + compatible = "altr,socfpga-gate-clk"; + clocks = <&cfg_h2f_usr0_clk>; + clk-gate = <0x60 9>; }; - emac_0_clk: emac_0_clk { - #clock-cells = <0>; - compatible = "altr,socfpga-gate-clk"; - clocks = <&emac0_clk>; - clk-gate = <0xa0 0>; + emac_0_clk: emac_0_clk { + #clock-cells = <0>; + compatible = "altr,socfpga-gate-clk"; + clocks = <&emac0_clk>; + clk-gate = <0xa0 0>; }; - emac_1_clk: emac_1_clk { - #clock-cells = <0>; - compatible = "altr,socfpga-gate-clk"; - clocks = <&emac1_clk>; - clk-gate = <0xa0 1>; + emac_1_clk: emac_1_clk { + #clock-cells = <0>; + compatible = "altr,socfpga-gate-clk"; + clocks = <&emac1_clk>; + clk-gate = <0xa0 1>; }; - usb_mp_clk: usb_mp_clk { - #clock-cells = <0>; - compatible = "altr,socfpga-gate-clk"; - clocks = <&per_base_clk>; - clk-gate = <0xa0 2>; - div-reg = <0xa4 0 3>; + usb_mp_clk: usb_mp_clk { + #clock-cells = <0>; + compatible = "altr,socfpga-gate-clk"; + clocks = <&per_base_clk>; + clk-gate = <0xa0 2>; + div-reg = <0xa4 0 3>; }; - spi_m_clk: spi_m_clk { - #clock-cells = <0>; - compatible = "altr,socfpga-gate-clk"; - clocks = <&per_base_clk>; - clk-gate = <0xa0 3>; - div-reg = <0xa4 3 3>; + spi_m_clk: spi_m_clk { + #clock-cells = <0>; + compatible = "altr,socfpga-gate-clk"; + clocks = <&per_base_clk>; + clk-gate = <0xa0 3>; + div-reg = <0xa4 3 3>; }; - can0_clk: can0_clk { - #clock-cells = <0>; - compatible = "altr,socfpga-gate-clk"; - clocks = <&per_base_clk>; - clk-gate = <0xa0 4>; - div-reg = <0xa4 6 3>; + can0_clk: can0_clk { + #clock-cells = <0>; + compatible = "altr,socfpga-gate-clk"; + clocks = <&per_base_clk>; + clk-gate = <0xa0 4>; + div-reg = <0xa4 6 3>; }; - can1_clk: can1_clk { - #clock-cells = <0>; - compatible = "altr,socfpga-gate-clk"; - clocks = <&per_base_clk>; - clk-gate = <0xa0 5>; - div-reg = <0xa4 9 3>; + can1_clk: can1_clk { + #clock-cells = <0>; + compatible = "altr,socfpga-gate-clk"; + clocks = <&per_base_clk>; + clk-gate = <0xa0 5>; + div-reg = <0xa4 9 3>; }; - gpio_db_clk: gpio_db_clk { - #clock-cells = <0>; - compatible = "altr,socfpga-gate-clk"; - clocks = <&per_base_clk>; - clk-gate = <0xa0 6>; - div-reg = <0xa8 0 24>; + gpio_db_clk: gpio_db_clk { + #clock-cells = <0>; + compatible = "altr,socfpga-gate-clk"; + clocks = <&per_base_clk>; + clk-gate = <0xa0 6>; + div-reg = <0xa8 0 24>; }; - s2f_user1_clk: s2f_user1_clk { - #clock-cells = <0>; - compatible = "altr,socfpga-gate-clk"; - clocks = <&s2f_usr1_clk>; - clk-gate = <0xa0 7>; + h2f_user1_clk: h2f_user1_clk { + #clock-cells = <0>; + compatible = "altr,socfpga-gate-clk"; + clocks = <&h2f_usr1_clk>; + clk-gate = <0xa0 7>; }; - sdmmc_clk: sdmmc_clk { - #clock-cells = <0>; - compatible = "altr,socfpga-gate-clk"; - clocks = <&f2s_periph_ref_clk>, <&main_nand_sdmmc_clk>, <&per_nand_mmc_clk>; - clk-gate = <0xa0 8>; + sdmmc_clk: sdmmc_clk { + #clock-cells = <0>; + compatible = "altr,socfpga-gate-clk"; + clocks = <&f2s_periph_ref_clk>, <&main_nand_sdmmc_clk>, <&per_nand_mmc_clk>; + clk-gate = <0xa0 8>; }; - nand_x_clk: nand_x_clk { - #clock-cells = <0>; - compatible = "altr,socfpga-gate-clk"; - clocks = <&f2s_periph_ref_clk>, <&main_nand_sdmmc_clk>, <&per_nand_mmc_clk>; - clk-gate = <0xa0 9>; + nand_x_clk: nand_x_clk { + #clock-cells = <0>; + compatible = "altr,socfpga-gate-clk"; + clocks = <&f2s_periph_ref_clk>, <&main_nand_sdmmc_clk>, <&per_nand_mmc_clk>; + clk-gate = <0xa0 9>; }; - nand_clk: nand_clk { - #clock-cells = <0>; - compatible = "altr,socfpga-gate-clk"; - clocks = <&f2s_periph_ref_clk>, <&main_nand_sdmmc_clk>, <&per_nand_mmc_clk>; - clk-gate = <0xa0 10>; - fixed-divider = <4>; + nand_clk: nand_clk { + #clock-cells = <0>; + compatible = "altr,socfpga-gate-clk"; + clocks = <&f2s_periph_ref_clk>, <&main_nand_sdmmc_clk>, <&per_nand_mmc_clk>; + clk-gate = <0xa0 10>; + fixed-divider = <4>; }; - qspi_clk: qspi_clk { - #clock-cells = <0>; - compatible = "altr,socfpga-gate-clk"; - clocks = <&f2s_periph_ref_clk>, <&main_qspi_clk>, <&per_qspi_clk>; - clk-gate = <0xa0 11>; + qspi_clk: qspi_clk { + #clock-cells = <0>; + compatible = "altr,socfpga-gate-clk"; + clocks = <&f2s_periph_ref_clk>, <&main_qspi_clk>, <&per_qspi_clk>; + clk-gate = <0xa0 11>; }; }; }; @@ -473,6 +473,7 @@ compatible = "arm,cortex-a9-twd-timer"; reg = <0xfffec600 0x100>; interrupts = <1 13 0xf04>; + clocks = <&mpu_periph_clk>; }; timer0: timer0@ffc08000 { @@ -516,9 +517,9 @@ }; rstmgr@ffd05000 { - compatible = "altr,rst-mgr"; - reg = <0xffd05000 0x1000>; - }; + compatible = "altr,rst-mgr"; + reg = <0xffd05000 0x1000>; + }; sysmgr@ffd08000 { compatible = "altr,sys-mgr"; diff --git a/arch/arm/boot/dts/socfpga_arria5.dtsi b/arch/arm/boot/dts/socfpga_arria5.dtsi new file mode 100644 index 000000000000..a85b4043f888 --- /dev/null +++ b/arch/arm/boot/dts/socfpga_arria5.dtsi @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2013 Altera Corporation <www.altera.com> + * + * 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/>. + */ + +/dts-v1/; +/include/ "socfpga.dtsi" + +/ { + soc { + clkmgr@ffd04000 { + clocks { + osc1 { + clock-frequency = <25000000>; + }; + }; + }; + + serial0@ffc02000 { + clock-frequency = <100000000>; + }; + + serial1@ffc03000 { + clock-frequency = <100000000>; + }; + + sysmgr@ffd08000 { + cpu1-start-addr = <0xffd080c4>; + }; + + timer0@ffc08000 { + clock-frequency = <100000000>; + }; + + timer1@ffc09000 { + clock-frequency = <100000000>; + }; + + timer2@ffd00000 { + clock-frequency = <25000000>; + }; + + timer3@ffd01000 { + clock-frequency = <25000000>; + }; + }; +}; diff --git a/arch/mips/include/asm/mach-powertv/powertv-clock.h b/arch/arm/boot/dts/socfpga_arria5_socdk.dts index 6f3e9a0fcf8c..5beffb2265f4 100644 --- a/arch/mips/include/asm/mach-powertv/powertv-clock.h +++ b/arch/arm/boot/dts/socfpga_arria5_socdk.dts @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Cisco Systems, Inc. + * Copyright (C) 2013 Altera Corporation <www.altera.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -12,18 +12,29 @@ * 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, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -/* - * Local definitions for the powertv PCI code + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef _POWERTV_PCI_POWERTV_PCI_H_ -#define _POWERTV_PCI_POWERTV_PCI_H_ -extern int asic_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin); -extern int asic_pcie_init(void); -extern int asic_pcie_init(void); +/include/ "socfpga_arria5.dtsi" + +/ { + model = "Altera SOCFPGA Arria V SoC Development Kit"; + compatible = "altr,socfpga-arria5", "altr,socfpga"; + + chosen { + bootargs = "console=ttyS0,115200"; + }; + + memory { + name = "memory"; + device_type = "memory"; + reg = <0x0 0x40000000>; /* 1GB */ + }; -extern int log_level; -#endif + aliases { + /* this allow the ethaddr uboot environmnet variable contents + * to be added to the gmac1 device tree blob. + */ + ethernet0 = &gmac1; + }; +}; diff --git a/arch/arm/boot/dts/socfpga_cyclone5.dts b/arch/arm/boot/dts/socfpga_cyclone5.dtsi index 973999d2c697..a8716f6dbe2e 100644 --- a/arch/arm/boot/dts/socfpga_cyclone5.dts +++ b/arch/arm/boot/dts/socfpga_cyclone5.dtsi @@ -19,26 +19,6 @@ /include/ "socfpga.dtsi" / { - model = "Altera SOCFPGA Cyclone V"; - compatible = "altr,socfpga-cyclone5", "altr,socfpga"; - - chosen { - bootargs = "console=ttyS0,57600"; - }; - - memory { - name = "memory"; - device_type = "memory"; - reg = <0x0 0x40000000>; /* 1GB */ - }; - - aliases { - /* this allow the ethaddr uboot environmnet variable contents - * to be added to the gmac1 device tree blob. - */ - ethernet0 = &gmac1; - }; - soc { clkmgr@ffd04000 { clocks { diff --git a/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts b/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts new file mode 100644 index 000000000000..2ee52ab8cabb --- /dev/null +++ b/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2012 Altera Corporation <www.altera.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that 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/>. + */ + +/include/ "socfpga_cyclone5.dtsi" + +/ { + model = "Altera SOCFPGA Cyclone V SoC Development Kit"; + compatible = "altr,socfpga-cyclone5", "altr,socfpga"; + + chosen { + bootargs = "console=ttyS0,115200"; + }; + + memory { + name = "memory"; + device_type = "memory"; + reg = <0x0 0x40000000>; /* 1GB */ + }; + + aliases { + /* this allow the ethaddr uboot environmnet variable contents + * to be added to the gmac1 device tree blob. + */ + ethernet0 = &gmac1; + }; +}; diff --git a/arch/mips/include/asm/mach-powertv/irq.h b/arch/arm/boot/dts/socfpga_cyclone5_sockit.dts index 4bd5d0c61a91..50b99a2c12ae 100644 --- a/arch/mips/include/asm/mach-powertv/irq.h +++ b/arch/arm/boot/dts/socfpga_cyclone5_sockit.dts @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Cisco Systems, Inc. + * Copyright (C) 2013 Steffen Trumtrar <s.trumtrar@pengutronix.de> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -12,14 +12,26 @@ * 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, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef _ASM_MACH_POWERTV_IRQ_H -#define _ASM_MACH_POWERTV_IRQ_H -#include <asm/mach-powertv/interrupts.h> +/include/ "socfpga_cyclone5.dtsi" -#define MIPS_CPU_IRQ_BASE ibase -#define NR_IRQS 127 -#endif +/ { + model = "Terasic SoCkit"; + compatible = "altr,socfpga-cyclone5", "altr,socfpga"; + + chosen { + bootargs = "console=ttyS0,115200"; + }; + + memory { + name = "memory"; + device_type = "memory"; + reg = <0x0 0x40000000>; /* 1GB */ + }; +}; + +&gmac1 { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/ste-dbx5x0.dtsi b/arch/arm/boot/dts/ste-dbx5x0.dtsi index 1c1091eedade..7da99fe497e1 100644 --- a/arch/arm/boot/dts/ste-dbx5x0.dtsi +++ b/arch/arm/boot/dts/ste-dbx5x0.dtsi @@ -10,6 +10,7 @@ */ #include <dt-bindings/interrupt-controller/irq.h> +#include <dt-bindings/mfd/dbx500-prcmu.h> #include "skeleton.dtsi" / { @@ -42,16 +43,56 @@ interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>; }; + + clocks { + compatible = "stericsson,u8500-clks"; + + prcmu_clk: prcmu-clock { + #clock-cells = <1>; + }; + + prcc_pclk: prcc-periph-clock { + #clock-cells = <2>; + }; + + prcc_kclk: prcc-kernel-clock { + #clock-cells = <2>; + }; + + rtc_clk: rtc32k-clock { + #clock-cells = <0>; + }; + + smp_twd_clk: smp-twd-clock { + #clock-cells = <0>; + }; + }; + + mtu@a03c6000 { + /* Nomadik System Timer */ + compatible = "st,nomadik-mtu"; + reg = <0xa03c6000 0x1000>; + interrupts = <0 4 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&prcmu_clk PRCMU_TIMCLK>, <&prcc_pclk 6 6>; + clock-names = "timclk", "apb_pclk"; + }; + timer@a0410600 { compatible = "arm,cortex-a9-twd-timer"; reg = <0xa0410600 0x20>; interrupts = <1 13 0x304>; /* IRQ level high per-CPU */ + + clocks = <&smp_twd_clk>; }; rtc@80154000 { compatible = "arm,rtc-pl031", "arm,primecell"; reg = <0x80154000 0x1000>; interrupts = <0 18 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&rtc_clk>; + clock-names = "apb_pclk"; }; gpio0: gpio@8012e000 { @@ -65,6 +106,8 @@ gpio-controller; #gpio-cells = <2>; gpio-bank = <0>; + + clocks = <&prcc_pclk 1 9>; }; gpio1: gpio@8012e080 { @@ -78,6 +121,8 @@ gpio-controller; #gpio-cells = <2>; gpio-bank = <1>; + + clocks = <&prcc_pclk 1 9>; }; gpio2: gpio@8000e000 { @@ -91,6 +136,8 @@ gpio-controller; #gpio-cells = <2>; gpio-bank = <2>; + + clocks = <&prcc_pclk 3 8>; }; gpio3: gpio@8000e080 { @@ -104,6 +151,8 @@ gpio-controller; #gpio-cells = <2>; gpio-bank = <3>; + + clocks = <&prcc_pclk 3 8>; }; gpio4: gpio@8000e100 { @@ -117,6 +166,8 @@ gpio-controller; #gpio-cells = <2>; gpio-bank = <4>; + + clocks = <&prcc_pclk 3 8>; }; gpio5: gpio@8000e180 { @@ -130,6 +181,8 @@ gpio-controller; #gpio-cells = <2>; gpio-bank = <5>; + + clocks = <&prcc_pclk 3 8>; }; gpio6: gpio@8011e000 { @@ -143,6 +196,8 @@ gpio-controller; #gpio-cells = <2>; gpio-bank = <6>; + + clocks = <&prcc_pclk 2 11>; }; gpio7: gpio@8011e080 { @@ -156,6 +211,8 @@ gpio-controller; #gpio-cells = <2>; gpio-bank = <7>; + + clocks = <&prcc_pclk 2 11>; }; gpio8: gpio@a03fe000 { @@ -169,6 +226,8 @@ gpio-controller; #gpio-cells = <2>; gpio-bank = <8>; + + clocks = <&prcc_pclk 5 1>; }; pinctrl { @@ -177,8 +236,7 @@ }; usb_per5@a03e0000 { - compatible = "stericsson,db8500-musb", - "mentor,musb"; + compatible = "stericsson,db8500-musb"; reg = <0xa03e0000 0x10000>; interrupts = <0 23 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "mc"; @@ -210,6 +268,8 @@ "iep_6_14", "oep_6_14", "iep_7_15", "oep_7_15", "iep_8", "oep_8"; + + clocks = <&prcc_pclk 5 0>; }; dma: dma-controller@801C0000 { @@ -220,6 +280,8 @@ #dma-cells = <3>; memcpy-channels = <56 57 58 59 60>; + + clocks = <&prcmu_clk PRCMU_DMACLK>; }; prcmu: prcmu@80157000 { @@ -238,6 +300,13 @@ reg = <0x80157450 0xC>; }; + cpufreq { + compatible = "stericsson,cpufreq-ux500"; + clocks = <&prcmu_clk PRCMU_ARMSS>; + clock-names = "armss"; + status = "disabled"; + }; + thermal@801573c0 { compatible = "stericsson,db8500-thermal"; reg = <0x801573c0 0x40>; @@ -559,65 +628,74 @@ compatible = "stericsson,db8500-i2c", "st,nomadik-i2c", "arm,primecell"; reg = <0x80004000 0x1000>; interrupts = <0 21 IRQ_TYPE_LEVEL_HIGH>; - arm,primecell-periphid = <0x180024>; #address-cells = <1>; #size-cells = <0>; v-i2c-supply = <&db8500_vape_reg>; clock-frequency = <400000>; + clocks = <&prcc_kclk 3 3>, <&prcc_pclk 3 3>; + clock-names = "i2cclk", "apb_pclk"; }; i2c@80122000 { compatible = "stericsson,db8500-i2c", "st,nomadik-i2c", "arm,primecell"; reg = <0x80122000 0x1000>; interrupts = <0 22 IRQ_TYPE_LEVEL_HIGH>; - arm,primecell-periphid = <0x180024>; #address-cells = <1>; #size-cells = <0>; v-i2c-supply = <&db8500_vape_reg>; clock-frequency = <400000>; + + clocks = <&prcc_kclk 1 2>, <&prcc_pclk 1 2>; + clock-names = "i2cclk", "apb_pclk"; }; i2c@80128000 { compatible = "stericsson,db8500-i2c", "st,nomadik-i2c", "arm,primecell"; reg = <0x80128000 0x1000>; interrupts = <0 55 IRQ_TYPE_LEVEL_HIGH>; - arm,primecell-periphid = <0x180024>; #address-cells = <1>; #size-cells = <0>; v-i2c-supply = <&db8500_vape_reg>; clock-frequency = <400000>; + + clocks = <&prcc_kclk 1 6>, <&prcc_pclk 1 6>; + clock-names = "i2cclk", "apb_pclk"; }; i2c@80110000 { compatible = "stericsson,db8500-i2c", "st,nomadik-i2c", "arm,primecell"; reg = <0x80110000 0x1000>; interrupts = <0 12 IRQ_TYPE_LEVEL_HIGH>; - arm,primecell-periphid = <0x180024>; #address-cells = <1>; #size-cells = <0>; v-i2c-supply = <&db8500_vape_reg>; clock-frequency = <400000>; + + clocks = <&prcc_kclk 2 0>, <&prcc_pclk 2 0>; + clock-names = "i2cclk", "apb_pclk"; }; i2c@8012a000 { compatible = "stericsson,db8500-i2c", "st,nomadik-i2c", "arm,primecell"; reg = <0x8012a000 0x1000>; interrupts = <0 51 IRQ_TYPE_LEVEL_HIGH>; - arm,primecell-periphid = <0x180024>; #address-cells = <1>; #size-cells = <0>; v-i2c-supply = <&db8500_vape_reg>; clock-frequency = <400000>; + + clocks = <&prcc_kclk 1 9>, <&prcc_pclk 1 10>; + clock-names = "i2cclk", "apb_pclk"; }; ssp@80002000 { @@ -626,7 +704,80 @@ interrupts = <0 14 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; - status = "disabled"; + clocks = <&prcc_kclk 3 1>, <&prcc_pclk 3 1>; + clock-names = "ssp0clk", "apb_pclk"; + dmas = <&dma 8 0 0x2>, /* Logical - DevToMem */ + <&dma 8 0 0x0>; /* Logical - MemToDev */ + dma-names = "rx", "tx"; + }; + + ssp@80003000 { + compatible = "arm,pl022", "arm,primecell"; + reg = <0x80003000 0x1000>; + interrupts = <0 52 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&prcc_kclk 3 2>, <&prcc_pclk 3 2>; + clock-names = "ssp1clk", "apb_pclk"; + dmas = <&dma 9 0 0x2>, /* Logical - DevToMem */ + <&dma 9 0 0x0>; /* Logical - MemToDev */ + dma-names = "rx", "tx"; + }; + + spi@8011a000 { + compatible = "arm,pl022", "arm,primecell"; + reg = <0x8011a000 0x1000>; + interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + /* Same clock wired to kernel and pclk */ + clocks = <&prcc_pclk 2 8>, <&prcc_pclk 2 8>; + clock-names = "spi0clk", "apb_pclk"; + dmas = <&dma 0 0 0x2>, /* Logical - DevToMem */ + <&dma 0 0 0x0>; /* Logical - MemToDev */ + dma-names = "rx", "tx"; + }; + + spi@80112000 { + compatible = "arm,pl022", "arm,primecell"; + reg = <0x80112000 0x1000>; + interrupts = <0 96 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + /* Same clock wired to kernel and pclk */ + clocks = <&prcc_pclk 2 2>, <&prcc_pclk 2 2>; + clock-names = "spi1clk", "apb_pclk"; + dmas = <&dma 35 0 0x2>, /* Logical - DevToMem */ + <&dma 35 0 0x0>; /* Logical - MemToDev */ + dma-names = "rx", "tx"; + }; + + spi@80111000 { + compatible = "arm,pl022", "arm,primecell"; + reg = <0x80111000 0x1000>; + interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + /* Same clock wired to kernel and pclk */ + clocks = <&prcc_pclk 2 1>, <&prcc_pclk 2 1>; + clock-names = "spi2clk", "apb_pclk"; + dmas = <&dma 33 0 0x2>, /* Logical - DevToMem */ + <&dma 33 0 0x0>; /* Logical - MemToDev */ + dma-names = "rx", "tx"; + }; + + spi@80129000 { + compatible = "arm,pl022", "arm,primecell"; + reg = <0x80129000 0x1000>; + interrupts = <0 49 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + /* Same clock wired to kernel and pclk */ + clocks = <&prcc_pclk 1 7>, <&prcc_pclk 1 7>; + clock-names = "spi3clk", "apb_pclk"; + dmas = <&dma 40 0 0x2>, /* Logical - DevToMem */ + <&dma 40 0 0x0>; /* Logical - MemToDev */ + dma-names = "rx", "tx"; }; uart@80120000 { @@ -638,6 +789,9 @@ <&dma 13 0 0x0>; /* Logical - MemToDev */ dma-names = "rx", "tx"; + clocks = <&prcc_kclk 1 0>, <&prcc_pclk 1 0>; + clock-names = "uart", "apb_pclk"; + status = "disabled"; }; @@ -650,6 +804,9 @@ <&dma 12 0 0x0>; /* Logical - MemToDev */ dma-names = "rx", "tx"; + clocks = <&prcc_kclk 1 1>, <&prcc_pclk 1 1>; + clock-names = "uart", "apb_pclk"; + status = "disabled"; }; @@ -662,6 +819,9 @@ <&dma 11 0 0x0>; /* Logical - MemToDev */ dma-names = "rx", "tx"; + clocks = <&prcc_kclk 3 6>, <&prcc_pclk 3 6>; + clock-names = "uart", "apb_pclk"; + status = "disabled"; }; @@ -674,6 +834,9 @@ <&dma 29 0 0x0>; /* Logical - MemToDev */ dma-names = "rx", "tx"; + clocks = <&prcc_kclk 1 5>, <&prcc_pclk 1 5>; + clock-names = "sdi", "apb_pclk"; + status = "disabled"; }; @@ -686,6 +849,9 @@ <&dma 32 0 0x0>; /* Logical - MemToDev */ dma-names = "rx", "tx"; + clocks = <&prcc_kclk 2 4>, <&prcc_pclk 2 6>; + clock-names = "sdi", "apb_pclk"; + status = "disabled"; }; @@ -698,6 +864,9 @@ <&dma 28 0 0x0>; /* Logical - MemToDev */ dma-names = "rx", "tx"; + clocks = <&prcc_kclk 3 4>, <&prcc_pclk 3 4>; + clock-names = "sdi", "apb_pclk"; + status = "disabled"; }; @@ -705,6 +874,10 @@ compatible = "arm,pl18x", "arm,primecell"; reg = <0x80119000 0x1000>; interrupts = <0 59 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&prcc_kclk 2 5>, <&prcc_pclk 2 7>; + clock-names = "sdi", "apb_pclk"; + status = "disabled"; }; @@ -717,6 +890,9 @@ <&dma 42 0 0x0>; /* Logical - MemToDev */ dma-names = "rx", "tx"; + clocks = <&prcc_kclk 2 2>, <&prcc_pclk 2 4>; + clock-names = "sdi", "apb_pclk"; + status = "disabled"; }; @@ -724,6 +900,10 @@ compatible = "arm,pl18x", "arm,primecell"; reg = <0x80008000 0x1000>; interrupts = <0 100 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&prcc_kclk 3 7>, <&prcc_pclk 3 7>; + clock-names = "sdi", "apb_pclk"; + status = "disabled"; }; @@ -732,6 +912,10 @@ reg = <0x80123000 0x1000>; interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>; v-ape-supply = <&db8500_vape_reg>; + + clocks = <&prcc_kclk 1 3>, <&prcc_pclk 1 3>; + clock-names = "msp", "apb_pclk"; + status = "disabled"; }; @@ -740,6 +924,10 @@ reg = <0x80124000 0x1000>; interrupts = <0 62 IRQ_TYPE_LEVEL_HIGH>; v-ape-supply = <&db8500_vape_reg>; + + clocks = <&prcc_kclk 1 4>, <&prcc_pclk 1 4>; + clock-names = "msp", "apb_pclk"; + status = "disabled"; }; @@ -749,6 +937,10 @@ reg = <0x80117000 0x1000>; interrupts = <0 98 IRQ_TYPE_LEVEL_HIGH>; v-ape-supply = <&db8500_vape_reg>; + + clocks = <&prcc_kclk 2 3>, <&prcc_pclk 2 5>; + clock-names = "msp", "apb_pclk"; + status = "disabled"; }; @@ -757,6 +949,10 @@ reg = <0x80125000 0x1000>; interrupts = <0 62 IRQ_TYPE_LEVEL_HIGH>; v-ape-supply = <&db8500_vape_reg>; + + clocks = <&prcc_kclk 1 10>, <&prcc_pclk 1 11>; + clock-names = "msp", "apb_pclk"; + status = "disabled"; }; @@ -772,7 +968,7 @@ cpufreq-cooling { compatible = "stericsson,db8500-cpufreq-cooling"; status = "disabled"; - }; + }; vmmci: regulator-gpio { compatible = "regulator-gpio"; @@ -797,6 +993,7 @@ interrupts = <0 15 IRQ_TYPE_LEVEL_HIGH>; v-ape-supply = <&db8500_vape_reg>; + clocks = <&prcc_pclk 6 1>; }; hash@a03c2000 { @@ -804,6 +1001,7 @@ reg = <0xa03c2000 0x1000>; v-ape-supply = <&db8500_vape_reg>; + clocks = <&prcc_pclk 6 2>; }; }; }; diff --git a/arch/arm/boot/dts/ste-stuib.dtsi b/arch/arm/boot/dts/ste-href-stuib.dtsi index 524e33240ad4..76704ec0ffcc 100644 --- a/arch/arm/boot/dts/ste-stuib.dtsi +++ b/arch/arm/boot/dts/ste-href-stuib.dtsi @@ -57,7 +57,6 @@ bu21013_tp@5c { compatible = "rohm,bu21013_tp"; reg = <0x5c>; - touch-gpio = <&gpio2 20 0x4>; avdd-supply = <&ab8500_ldo_aux1_reg>; rohm,touch-max-x = <384>; @@ -68,7 +67,6 @@ bu21013_tp@5d { compatible = "rohm,bu21013_tp"; reg = <0x5d>; - touch-gpio = <&gpio2 20 0x4>; avdd-supply = <&ab8500_ldo_aux1_reg>; rohm,touch-max-x = <384>; diff --git a/arch/arm/boot/dts/ste-href-tvk1281618.dtsi b/arch/arm/boot/dts/ste-href-tvk1281618.dtsi new file mode 100644 index 000000000000..76d3ef13175f --- /dev/null +++ b/arch/arm/boot/dts/ste-href-tvk1281618.dtsi @@ -0,0 +1,41 @@ +/* + * Copyright 2012 ST-Ericsson AB + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + * + * Device Tree for the TVK1281618 UIB + */ + +#include <dt-bindings/interrupt-controller/irq.h> + +/ { + soc { + /* Add Synaptics touch screen, TC35892 keypad etc here */ + i2c@80004000 { + tc3589x@44 { + compatible = "tc3589x"; + reg = <0x44>; + interrupt-parent = <&gpio6>; + interrupts = <26 IRQ_TYPE_EDGE_RISING>; + + interrupt-controller; + #interrupt-cells = <2>; + + tc3589x_gpio { + compatible = "tc3589x-gpio"; + interrupts = <0 IRQ_TYPE_EDGE_RISING>; + + interrupt-controller; + #interrupt-cells = <2>; + gpio-controller; + #gpio-cells = <2>; + }; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/ste-href.dtsi b/arch/arm/boot/dts/ste-href.dtsi index 370e03f5e7b2..aa3f02060fdd 100644 --- a/arch/arm/boot/dts/ste-href.dtsi +++ b/arch/arm/boot/dts/ste-href.dtsi @@ -41,28 +41,6 @@ status = "okay"; }; - i2c@80004000 { - tc3589x@42 { - compatible = "tc3589x"; - reg = <0x42>; - interrupt-parent = <&gpio6>; - interrupts = <25 IRQ_TYPE_EDGE_RISING>; - - interrupt-controller; - #interrupt-cells = <2>; - - tc3589x_gpio: tc3589x_gpio { - compatible = "tc3589x-gpio"; - interrupts = <0 IRQ_TYPE_EDGE_RISING>; - - interrupt-controller; - #interrupt-cells = <2>; - gpio-controller; - #gpio-cells = <2>; - }; - }; - }; - i2c@80128000 { lp5521@33 { compatible = "national,lp5521"; @@ -72,6 +50,7 @@ chan0 { led-cur = /bits/ 8 <0x2f>; max-cur = /bits/ 8 <0x5f>; + linux,default-trigger = "heartbeat"; }; chan1 { led-cur = /bits/ 8 <0x2f>; @@ -102,7 +81,7 @@ }; bh1780@29 { compatible = "rohm,bh1780gli"; - reg = <0x33>; + reg = <0x29>; }; }; @@ -167,89 +146,11 @@ }; prcmu@80157000 { - db8500-prcmu-regulators { - db8500_vape_reg: db8500_vape { - regulator-name = "db8500-vape"; - }; - - db8500_varm_reg: db8500_varm { - regulator-name = "db8500-varm"; - }; - - db8500_vmodem_reg: db8500_vmodem { - regulator-name = "db8500-vmodem"; - }; - - db8500_vpll_reg: db8500_vpll { - regulator-name = "db8500-vpll"; - }; - - db8500_vsmps1_reg: db8500_vsmps1 { - regulator-name = "db8500-vsmps1"; - }; - - db8500_vsmps2_reg: db8500_vsmps2 { - regulator-name = "db8500-vsmps2"; - }; - - db8500_vsmps3_reg: db8500_vsmps3 { - regulator-name = "db8500-vsmps3"; - }; - - db8500_vrf1_reg: db8500_vrf1 { - regulator-name = "db8500-vrf1"; - }; - - db8500_sva_mmdsp_reg: db8500_sva_mmdsp { - regulator-name = "db8500-sva-mmdsp"; - }; - - db8500_sva_mmdsp_ret_reg: db8500_sva_mmdsp_ret { - regulator-name = "db8500-sva-mmdsp-ret"; - }; - - db8500_sva_pipe_reg: db8500_sva_pipe { - regulator-name = "db8500_sva_pipe"; - }; - - db8500_sia_mmdsp_reg: db8500_sia_mmdsp { - regulator-name = "db8500_sia_mmdsp"; - }; - - db8500_sia_mmdsp_ret_reg: db8500_sia_mmdsp_ret { - regulator-name = "db8500-sia-mmdsp-ret"; - }; - - db8500_sia_pipe_reg: db8500_sia_pipe { - regulator-name = "db8500-sia-pipe"; - }; - - db8500_sga_reg: db8500_sga { - regulator-name = "db8500-sga"; - }; - - db8500_b2r2_mcde_reg: db8500_b2r2_mcde { - regulator-name = "db8500-b2r2-mcde"; - }; - - db8500_esram12_reg: db8500_esram12 { - regulator-name = "db8500-esram12"; - }; - - db8500_esram12_ret_reg: db8500_esram12_ret { - regulator-name = "db8500-esram12-ret"; - }; - - db8500_esram34_reg: db8500_esram34 { - regulator-name = "db8500-esram34"; + ab8500 { + ab8500-gpio { + compatible = "stericsson,ab8500-gpio"; }; - db8500_esram34_ret_reg: db8500_esram34_ret { - regulator-name = "db8500-esram34-ret"; - }; - }; - - ab8500 { ab8500-regulators { ab8500_ldo_aux1_reg: ab8500_ldo_aux1 { regulator-name = "V-DISPLAY"; diff --git a/arch/arm/boot/dts/ste-hrefprev60-stuib.dts b/arch/arm/boot/dts/ste-hrefprev60-stuib.dts new file mode 100644 index 000000000000..2b1cb5b584b6 --- /dev/null +++ b/arch/arm/boot/dts/ste-hrefprev60-stuib.dts @@ -0,0 +1,34 @@ +/* + * Copyright 2012 ST-Ericsson AB + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/dts-v1/; +#include "ste-hrefprev60.dtsi" +#include "ste-href-stuib.dtsi" + +/ { + model = "ST-Ericsson HREF (pre-v60) and ST UIB"; + compatible = "st-ericsson,mop500", "st-ericsson,u8500"; + + soc { + /* Reset line for the BU21013 touchscreen */ + i2c@80110000 { + /* Only one of these will be used */ + bu21013_tp@5c { + touch-gpio = <&gpio2 12 0x4>; + reset-gpio = <&tc3589x_gpio 13 0x4>; + }; + bu21013_tp@5d { + touch-gpio = <&gpio2 12 0x4>; + reset-gpio = <&tc3589x_gpio 13 0x4>; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/ste-hrefprev60-tvk.dts b/arch/arm/boot/dts/ste-hrefprev60-tvk.dts new file mode 100644 index 000000000000..59523f866812 --- /dev/null +++ b/arch/arm/boot/dts/ste-hrefprev60-tvk.dts @@ -0,0 +1,19 @@ +/* + * Copyright 2012 ST-Ericsson AB + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/dts-v1/; +#include "ste-hrefprev60.dtsi" +#include "ste-href-tvk1281618.dtsi" + +/ { + model = "ST-Ericsson HREF (pre-v60) and TVK1281618 UIB"; + compatible = "st-ericsson,mop500", "st-ericsson,u8500"; +}; diff --git a/arch/arm/boot/dts/ste-hrefprev60.dts b/arch/arm/boot/dts/ste-hrefprev60.dtsi index d8d3b99ab007..b2cd7bc2752f 100644 --- a/arch/arm/boot/dts/ste-hrefprev60.dts +++ b/arch/arm/boot/dts/ste-hrefprev60.dtsi @@ -7,17 +7,14 @@ * * http://www.opensource.org/licenses/gpl-license.html * http://www.gnu.org/copyleft/gpl.html + * + * Device Tree for the HREF+ prior to the v60 variant. */ -/dts-v1/; #include "ste-dbx5x0.dtsi" #include "ste-href.dtsi" -#include "ste-stuib.dtsi" / { - model = "ST-Ericsson HREF (pre-v60) platform with Device Tree"; - compatible = "st-ericsson,mop500", "st-ericsson,u8500"; - gpio_keys { button@1 { gpios = <&tc3589x_gpio 7 0x4>; @@ -25,24 +22,30 @@ }; soc { - prcmu@80157000 { - ab8500@5 { - ab8500-gpio { - compatible = "stericsson,ab8500-gpio"; - }; - }; - }; - i2c@80004000 { tps61052@33 { compatible = "tps61052"; reg = <0x33>; }; - }; - i2c@80110000 { - bu21013_tp@5c { - reset-gpio = <&tc3589x_gpio 13 0x4>; + tc3589x@42 { + compatible = "tc3589x"; + reg = <0x42>; + interrupt-parent = <&gpio6>; + interrupts = <25 IRQ_TYPE_EDGE_RISING>; + + interrupt-controller; + #interrupt-cells = <2>; + + tc3589x_gpio: tc3589x_gpio { + compatible = "tc3589x-gpio"; + interrupts = <0 IRQ_TYPE_EDGE_RISING>; + + interrupt-controller; + #interrupt-cells = <2>; + gpio-controller; + #gpio-cells = <2>; + }; }; }; diff --git a/arch/arm/boot/dts/ste-hrefv60plus-stuib.dts b/arch/arm/boot/dts/ste-hrefv60plus-stuib.dts new file mode 100644 index 000000000000..8c6a2de56cf1 --- /dev/null +++ b/arch/arm/boot/dts/ste-hrefv60plus-stuib.dts @@ -0,0 +1,36 @@ +/* + * Copyright 2012 ST-Ericsson AB + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + * + * Device Tree for the HREF version 60 or later with the ST UIB + */ + +/dts-v1/; +#include "ste-hrefv60plus.dtsi" +#include "ste-href-stuib.dtsi" + +/ { + model = "ST-Ericsson HREF (v60+) and ST UIB"; + compatible = "st-ericsson,hrefv60+", "st-ericsson,u8500"; + + soc { + /* Reset line for the BU21013 touchscreen */ + i2c@80110000 { + /* Only one of these will be used */ + bu21013_tp@5c { + touch-gpio = <&gpio2 20 0x4>; + reset-gpio = <&gpio4 17 0x4>; + }; + bu21013_tp@5d { + touch-gpio = <&gpio2 20 0x4>; + reset-gpio = <&gpio4 17 0x4>; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/ste-hrefv60plus-tvk.dts b/arch/arm/boot/dts/ste-hrefv60plus-tvk.dts new file mode 100644 index 000000000000..d53cccdce776 --- /dev/null +++ b/arch/arm/boot/dts/ste-hrefv60plus-tvk.dts @@ -0,0 +1,21 @@ +/* + * Copyright 2012 ST-Ericsson AB + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + * + * Device Tree for the HREF version 60 or later with the TVK1281618 UIB + */ + +/dts-v1/; +#include "ste-hrefv60plus.dtsi" +#include "ste-href-tvk1281618.dtsi" + +/ { + model = "ST-Ericsson HREF (v60+) and TVK1281618 UIB"; + compatible = "st-ericsson,hrefv60+", "st-ericsson,u8500"; +}; diff --git a/arch/arm/boot/dts/ste-hrefv60plus.dts b/arch/arm/boot/dts/ste-hrefv60plus.dts deleted file mode 100644 index 6e52ebbf113f..000000000000 --- a/arch/arm/boot/dts/ste-hrefv60plus.dts +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright 2012 ST-Ericsson AB - * - * The code contained herein is licensed under the GNU General Public - * License. You may obtain a copy of the GNU General Public License - * Version 2 or later at the following locations: - * - * http://www.opensource.org/licenses/gpl-license.html - * http://www.gnu.org/copyleft/gpl.html - */ - -/dts-v1/; -#include "ste-dbx5x0.dtsi" -#include "ste-href.dtsi" -#include "ste-stuib.dtsi" - -/ { - model = "ST-Ericsson HREF (v60+) platform with Device Tree"; - compatible = "st-ericsson,hrefv60+", "st-ericsson,u8500"; - - gpio_keys { - button@1 { - gpios = <&gpio6 25 0x4>; - }; - }; - - soc { - i2c@80110000 { - bu21013_tp@0x5c { - reset-gpio = <&gpio4 15 0x4>; - }; - }; - - // External Micro SD slot - sdi0_per1@80126000 { - arm,primecell-periphid = <0x10480180>; - max-frequency = <100000000>; - bus-width = <4>; - mmc-cap-sd-highspeed; - mmc-cap-mmc-highspeed; - vmmc-supply = <&ab8500_ldo_aux3_reg>; - - cd-gpios = <&tc3589x_gpio 3 0x4>; - - status = "okay"; - }; - - // WLAN SDIO channel - sdi1_per2@80118000 { - arm,primecell-periphid = <0x10480180>; - max-frequency = <100000000>; - bus-width = <4>; - - status = "okay"; - }; - - // PoP:ed eMMC - sdi2_per3@80005000 { - arm,primecell-periphid = <0x10480180>; - max-frequency = <100000000>; - bus-width = <8>; - mmc-cap-mmc-highspeed; - - status = "okay"; - }; - - // On-board eMMC - sdi4_per2@80114000 { - arm,primecell-periphid = <0x10480180>; - max-frequency = <100000000>; - bus-width = <8>; - mmc-cap-mmc-highspeed; - vmmc-supply = <&ab8500_ldo_aux2_reg>; - - status = "okay"; - }; - - prcmu@80157000 { - db8500-prcmu-regulators { - db8500_vape_reg: db8500_vape { - regulator-name = "db8500-vape"; - }; - - db8500_varm_reg: db8500_varm { - regulator-name = "db8500-varm"; - }; - - db8500_vmodem_reg: db8500_vmodem { - regulator-name = "db8500-vmodem"; - }; - - db8500_vpll_reg: db8500_vpll { - regulator-name = "db8500-vpll"; - }; - - db8500_vsmps1_reg: db8500_vsmps1 { - regulator-name = "db8500-vsmps1"; - }; - - db8500_vsmps2_reg: db8500_vsmps2 { - regulator-name = "db8500-vsmps2"; - }; - - db8500_vsmps3_reg: db8500_vsmps3 { - regulator-name = "db8500-vsmps3"; - }; - - db8500_vrf1_reg: db8500_vrf1 { - regulator-name = "db8500-vrf1"; - }; - - db8500_sva_mmdsp_reg: db8500_sva_mmdsp { - regulator-name = "db8500-sva-mmdsp"; - }; - - db8500_sva_mmdsp_ret_reg: db8500_sva_mmdsp_ret { - regulator-name = "db8500-sva-mmdsp-ret"; - }; - - db8500_sva_pipe_reg: db8500_sva_pipe { - regulator-name = "db8500_sva_pipe"; - }; - - db8500_sia_mmdsp_reg: db8500_sia_mmdsp { - regulator-name = "db8500_sia_mmdsp"; - }; - - db8500_sia_mmdsp_ret_reg: db8500_sia_mmdsp_ret { - regulator-name = "db8500-sia-mmdsp-ret"; - }; - - db8500_sia_pipe_reg: db8500_sia_pipe { - regulator-name = "db8500-sia-pipe"; - }; - - db8500_sga_reg: db8500_sga { - regulator-name = "db8500-sga"; - }; - - db8500_b2r2_mcde_reg: db8500_b2r2_mcde { - regulator-name = "db8500-b2r2-mcde"; - }; - - db8500_esram12_reg: db8500_esram12 { - regulator-name = "db8500-esram12"; - }; - - db8500_esram12_ret_reg: db8500_esram12_ret { - regulator-name = "db8500-esram12-ret"; - }; - - db8500_esram34_reg: db8500_esram34 { - regulator-name = "db8500-esram34"; - }; - - db8500_esram34_ret_reg: db8500_esram34_ret { - regulator-name = "db8500-esram34-ret"; - }; - }; - - ab8500 { - ab8500-regulators { - ab8500_ldo_aux1_reg: ab8500_ldo_aux1 { - regulator-name = "V-DISPLAY"; - }; - - ab8500_ldo_aux2_reg: ab8500_ldo_aux2 { - regulator-name = "V-eMMC1"; - }; - - ab8500_ldo_aux3_reg: ab8500_ldo_aux3 { - regulator-name = "V-MMC-SD"; - }; - - ab8500_ldo_intcore_reg: ab8500_ldo_intcore { - regulator-name = "V-INTCORE"; - }; - - ab8500_ldo_tvout_reg: ab8500_ldo_tvout { - regulator-name = "V-TVOUT"; - }; - - ab8500_ldo_usb_reg: ab8500_ldo_usb { - regulator-name = "dummy"; - }; - - ab8500_ldo_audio_reg: ab8500_ldo_audio { - regulator-name = "V-AUD"; - }; - - ab8500_ldo_anamic1_reg: ab8500_ldo_anamic1 { - regulator-name = "V-AMIC1"; - }; - - ab8500_ldo_anamic2_reg: ab8500_ldo_anamic2 { - regulator-name = "V-AMIC2"; - }; - - ab8500_ldo_dmic_reg: ab8500_ldo_dmic { - regulator-name = "V-DMIC"; - }; - - ab8500_ldo_ana_reg: ab8500_ldo_ana { - regulator-name = "V-CSI/DSI"; - }; - }; - }; - }; - }; -}; diff --git a/arch/arm/boot/dts/ste-hrefv60plus.dtsi b/arch/arm/boot/dts/ste-hrefv60plus.dtsi new file mode 100644 index 000000000000..aed511b47a9e --- /dev/null +++ b/arch/arm/boot/dts/ste-hrefv60plus.dtsi @@ -0,0 +1,70 @@ +/* + * Copyright 2012 ST-Ericsson AB + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include "ste-dbx5x0.dtsi" +#include "ste-href.dtsi" + +/ { + model = "ST-Ericsson HREF (v60+) platform with Device Tree"; + compatible = "st-ericsson,hrefv60+", "st-ericsson,u8500"; + + gpio_keys { + button@1 { + gpios = <&gpio5 25 0x4>; + }; + }; + + soc { + // External Micro SD slot + sdi0_per1@80126000 { + arm,primecell-periphid = <0x10480180>; + max-frequency = <100000000>; + bus-width = <4>; + mmc-cap-sd-highspeed; + mmc-cap-mmc-highspeed; + vmmc-supply = <&ab8500_ldo_aux3_reg>; + + cd-gpios = <&gpio2 31 0x4>; // 95 + + status = "okay"; + }; + + // WLAN SDIO channel + sdi1_per2@80118000 { + arm,primecell-periphid = <0x10480180>; + max-frequency = <100000000>; + bus-width = <4>; + + status = "okay"; + }; + + // PoP:ed eMMC + sdi2_per3@80005000 { + arm,primecell-periphid = <0x10480180>; + max-frequency = <100000000>; + bus-width = <8>; + mmc-cap-mmc-highspeed; + + status = "okay"; + }; + + // On-board eMMC + sdi4_per2@80114000 { + arm,primecell-periphid = <0x10480180>; + max-frequency = <100000000>; + bus-width = <8>; + mmc-cap-mmc-highspeed; + vmmc-supply = <&ab8500_ldo_aux2_reg>; + + status = "okay"; + }; + }; +}; diff --git a/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi b/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi index 9169d3025f39..79425e3836ce 100644 --- a/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi +++ b/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi @@ -653,6 +653,7 @@ reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd"; clocks = <&hclksmc>; status = "okay"; + timings = /bits/ 8 <0 0 0 0x10 0x0a 0>; partition@0 { label = "X-Loader(NAND)"; @@ -707,8 +708,14 @@ pinctrl-0 = <&i2c0_default_mux>, <&i2c0_default_mode>; stw4811@2d { - compatible = "st,stw4811"; - reg = <0x2d>; + compatible = "st,stw4811"; + reg = <0x2d>; + vmmc_regulator: vmmc { + compatible = "st,stw481x-vmmc"; + regulator-name = "VMMC"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + }; }; }; @@ -839,6 +846,7 @@ cd-inverted; pinctrl-names = "default"; pinctrl-0 = <&mmcsd_default_mux>, <&mmcsd_default_mode>; + vmmc-supply = <&vmmc_regulator>; }; }; }; diff --git a/arch/arm/boot/dts/ste-snowball.dts b/arch/arm/boot/dts/ste-snowball.dts index f1fc128e249d..f0b39f835914 100644 --- a/arch/arm/boot/dts/ste-snowball.dts +++ b/arch/arm/boot/dts/ste-snowball.dts @@ -111,12 +111,13 @@ vdd33a-supply = <&en_3v3_reg>; vddvario-supply = <&db8500_vape_reg>; - reg-shift = <1>; reg-io-width = <2>; smsc,force-internal-phy; smsc,irq-active-high; smsc,irq-push-pull; + + clocks = <&prcc_pclk 3 0>; }; }; @@ -170,86 +171,8 @@ }; prcmu@80157000 { - db8500-prcmu-regulators { - db8500_vape_reg: db8500_vape { - regulator-name = "db8500-vape"; - }; - - db8500_varm_reg: db8500_varm { - regulator-name = "db8500-varm"; - }; - - db8500_vmodem_reg: db8500_vmodem { - regulator-name = "db8500-vmodem"; - }; - - db8500_vpll_reg: db8500_vpll { - regulator-name = "db8500-vpll"; - }; - - db8500_vsmps1_reg: db8500_vsmps1 { - regulator-name = "db8500-vsmps1"; - }; - - db8500_vsmps2_reg: db8500_vsmps2 { - regulator-name = "db8500-vsmps2"; - }; - - db8500_vsmps3_reg: db8500_vsmps3 { - regulator-name = "db8500-vsmps3"; - }; - - db8500_vrf1_reg: db8500_vrf1 { - regulator-name = "db8500-vrf1"; - }; - - db8500_sva_mmdsp_reg: db8500_sva_mmdsp { - regulator-name = "db8500-sva-mmdsp"; - }; - - db8500_sva_mmdsp_ret_reg: db8500_sva_mmdsp_ret { - regulator-name = "db8500-sva-mmdsp-ret"; - }; - - db8500_sva_pipe_reg: db8500_sva_pipe { - regulator-name = "db8500_sva_pipe"; - }; - - db8500_sia_mmdsp_reg: db8500_sia_mmdsp { - regulator-name = "db8500_sia_mmdsp"; - }; - - db8500_sia_mmdsp_ret_reg: db8500_sia_mmdsp_ret { - regulator-name = "db8500-sia-mmdsp-ret"; - }; - - db8500_sia_pipe_reg: db8500_sia_pipe { - regulator-name = "db8500-sia-pipe"; - }; - - db8500_sga_reg: db8500_sga { - regulator-name = "db8500-sga"; - }; - - db8500_b2r2_mcde_reg: db8500_b2r2_mcde { - regulator-name = "db8500-b2r2-mcde"; - }; - - db8500_esram12_reg: db8500_esram12 { - regulator-name = "db8500-esram12"; - }; - - db8500_esram12_ret_reg: db8500_esram12_ret { - regulator-name = "db8500-esram12-ret"; - }; - - db8500_esram34_reg: db8500_esram34 { - regulator-name = "db8500-esram34"; - }; - - db8500_esram34_ret_reg: db8500_esram34_ret { - regulator-name = "db8500-esram34-ret"; - }; + cpufreq { + status = "okay"; }; thermal@801573c0 { diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi index c32770a28acf..319cc6b509da 100644 --- a/arch/arm/boot/dts/sun4i-a10.dtsi +++ b/arch/arm/boot/dts/sun4i-a10.dtsi @@ -266,6 +266,11 @@ reg = <0x01c20c90 0x10>; }; + sid: eeprom@01c23800 { + compatible = "allwinner,sun4i-sid"; + reg = <0x01c23800 0x10>; + }; + uart0: serial@01c28000 { compatible = "snps,dw-apb-uart"; reg = <0x01c28000 0x400>; diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi index 3b4a0574f068..52476742a104 100644 --- a/arch/arm/boot/dts/sun5i-a10s.dtsi +++ b/arch/arm/boot/dts/sun5i-a10s.dtsi @@ -255,6 +255,11 @@ reg = <0x01c20c90 0x10>; }; + sid: eeprom@01c23800 { + compatible = "allwinner,sun4i-sid"; + reg = <0x01c23800 0x10>; + }; + uart0: serial@01c28000 { compatible = "snps,dw-apb-uart"; reg = <0x01c28000 0x400>; diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi index f6091dc0936c..ce8ef2a45be0 100644 --- a/arch/arm/boot/dts/sun5i-a13.dtsi +++ b/arch/arm/boot/dts/sun5i-a13.dtsi @@ -222,6 +222,11 @@ reg = <0x01c20c90 0x10>; }; + sid: eeprom@01c23800 { + compatible = "allwinner,sun4i-sid"; + reg = <0x01c23800 0x10>; + }; + uart1: serial@01c28400 { compatible = "snps,dw-apb-uart"; reg = <0x01c28400 0x400>; diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi index f244f5f02365..c1751a64889a 100644 --- a/arch/arm/boot/dts/sun6i-a31.dtsi +++ b/arch/arm/boot/dts/sun6i-a31.dtsi @@ -175,7 +175,7 @@ apb2_gates: apb2_gates@01c2006c { #clock-cells = <1>; compatible = "allwinner,sun6i-a31-apb2-gates-clk"; - reg = <0x01c2006c 0x8>; + reg = <0x01c2006c 0x4>; clocks = <&apb2>; clock-output-names = "apb2_i2c0", "apb2_i2c1", "apb2_i2c2", "apb2_i2c3", "apb2_uart0", diff --git a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts index 15e625eca312..5c51cb8a98b0 100644 --- a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts +++ b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts @@ -48,6 +48,18 @@ pinctrl-0 = <&uart0_pins_a>; status = "okay"; }; + + i2c0: i2c@01c2ac00 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins_a>; + status = "okay"; + }; + + i2c1: i2c@01c2b000 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins_a>; + status = "okay"; + }; }; leds { diff --git a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts new file mode 100644 index 000000000000..8a1009d6c829 --- /dev/null +++ b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts @@ -0,0 +1,63 @@ +/* + * Copyright 2013 Oliver Schinagl + * + * Oliver Schinagl <oliver@schinagl.nl> + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/dts-v1/; +/include/ "sun7i-a20.dtsi" + +/ { + model = "Cubietech Cubietruck"; + compatible = "cubietech,cubietruck", "allwinner,sun7i-a20"; + + soc@01c00000 { + pinctrl@01c20800 { + led_pins_cubietruck: led_pins@0 { + allwinner,pins = "PH7", "PH11", "PH20", "PH21"; + allwinner,function = "gpio_out"; + allwinner,drive = <0>; + allwinner,pull = <0>; + }; + }; + + uart0: serial@01c28000 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins_a>; + status = "okay"; + }; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&led_pins_cubietruck>; + + blue { + label = "cubietruck:blue:usr"; + gpios = <&pio 7 21 0>; + }; + + orange { + label = "cubietruck:orange:usr"; + gpios = <&pio 7 20 0>; + }; + + white { + label = "cubietruck:white:usr"; + gpios = <&pio 7 11 0>; + }; + + green { + label = "cubietruck:green:usr"; + gpios = <&pio 7 7 0>; + }; + }; +}; diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts index 9e778557fadb..ead3013f9aca 100644 --- a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts +++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts @@ -60,6 +60,24 @@ pinctrl-0 = <&uart7_pins_a>; status = "okay"; }; + + i2c0: i2c@01c2ac00 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins_a>; + status = "okay"; + }; + + i2c1: i2c@01c2b000 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins_a>; + status = "okay"; + }; + + i2c2: i2c@01c2b400 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_pins_a>; + status = "okay"; + }; }; leds { diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi index 80559cbdbc87..e46cfedde74c 100644 --- a/arch/arm/boot/dts/sun7i-a20.dtsi +++ b/arch/arm/boot/dts/sun7i-a20.dtsi @@ -215,6 +215,27 @@ allwinner,pull = <0>; }; + i2c0_pins_a: i2c0@0 { + allwinner,pins = "PB0", "PB1"; + allwinner,function = "i2c0"; + allwinner,drive = <0>; + allwinner,pull = <0>; + }; + + i2c1_pins_a: i2c1@0 { + allwinner,pins = "PB18", "PB19"; + allwinner,function = "i2c1"; + allwinner,drive = <0>; + allwinner,pull = <0>; + }; + + i2c2_pins_a: i2c2@0 { + allwinner,pins = "PB20", "PB21"; + allwinner,function = "i2c2"; + allwinner,drive = <0>; + allwinner,pull = <0>; + }; + emac_pins_a: emac0@0 { allwinner,pins = "PA0", "PA1", "PA2", "PA3", "PA4", "PA5", "PA6", @@ -244,6 +265,11 @@ reg = <0x01c20c90 0x10>; }; + sid: eeprom@01c23800 { + compatible = "allwinner,sun7i-a20-sid"; + reg = <0x01c23800 0x200>; + }; + uart0: serial@01c28000 { compatible = "snps,dw-apb-uart"; reg = <0x01c28000 0x400>; @@ -324,6 +350,51 @@ status = "disabled"; }; + i2c0: i2c@01c2ac00 { + compatible = "allwinner,sun4i-i2c"; + reg = <0x01c2ac00 0x400>; + interrupts = <0 7 1>; + clocks = <&apb1_gates 0>; + clock-frequency = <100000>; + status = "disabled"; + }; + + i2c1: i2c@01c2b000 { + compatible = "allwinner,sun4i-i2c"; + reg = <0x01c2b000 0x400>; + interrupts = <0 8 1>; + clocks = <&apb1_gates 1>; + clock-frequency = <100000>; + status = "disabled"; + }; + + i2c2: i2c@01c2b400 { + compatible = "allwinner,sun4i-i2c"; + reg = <0x01c2b400 0x400>; + interrupts = <0 9 1>; + clocks = <&apb1_gates 2>; + clock-frequency = <100000>; + status = "disabled"; + }; + + i2c3: i2c@01c2b800 { + compatible = "allwinner,sun4i-i2c"; + reg = <0x01c2b800 0x400>; + interrupts = <0 88 1>; + clocks = <&apb1_gates 3>; + clock-frequency = <100000>; + status = "disabled"; + }; + + i2c4: i2c@01c2bc00 { + compatible = "allwinner,sun4i-i2c"; + reg = <0x01c2bc00 0x400>; + interrupts = <0 89 1>; + clocks = <&apb1_gates 15>; + clock-frequency = <100000>; + status = "disabled"; + }; + gic: interrupt-controller@01c81000 { compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic"; reg = <0x01c81000 0x1000>, diff --git a/arch/arm/boot/dts/tegra114-dalmore.dts b/arch/arm/boot/dts/tegra114-dalmore.dts index 60230288884b..cb5ec23b03a7 100644 --- a/arch/arm/boot/dts/tegra114-dalmore.dts +++ b/arch/arm/boot/dts/tegra114-dalmore.dts @@ -1,5 +1,6 @@ /dts-v1/; +#include <dt-bindings/input/input.h> #include "tegra114.dtsi" / { @@ -738,6 +739,14 @@ realtek,ldo1-en-gpios = <&gpio TEGRA_GPIO(V, 3) GPIO_ACTIVE_HIGH>; }; + + temperature-sensor@4c { + compatible = "onnn,nct1008"; + reg = <0x4c>; + vcc-supply = <&palmas_ldo6_reg>; + interrupt-parent = <&gpio>; + interrupts = <TEGRA_GPIO(O, 4) IRQ_TYPE_LEVEL_LOW>; + }; }; i2c@7000d000 { @@ -947,7 +956,7 @@ regulator-max-microvolt = <1800000>; }; - ldo6 { + palmas_ldo6_reg: ldo6 { regulator-name = "vdd-sensor-2v85"; regulator-min-microvolt = <2850000>; regulator-max-microvolt = <2850000>; @@ -1011,6 +1020,19 @@ interrupt-parent = <&palmas>; interrupts = <8 0>; }; + + pinmux { + compatible = "ti,tps65913-pinctrl"; + pinctrl-names = "default"; + pinctrl-0 = <&palmas_default>; + + palmas_default: pinmux { + pin_gpio6 { + pins = "gpio6"; + function = "gpio"; + }; + }; + }; }; }; @@ -1081,26 +1103,26 @@ home { label = "Home"; gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>; - linux,code = <102>; /* KEY_HOME */ + linux,code = <KEY_HOME>; }; power { label = "Power"; gpios = <&gpio TEGRA_GPIO(Q, 0) GPIO_ACTIVE_LOW>; - linux,code = <116>; /* KEY_POWER */ + linux,code = <KEY_POWER>; gpio-key,wakeup; }; volume_down { label = "Volume Down"; gpios = <&gpio TEGRA_GPIO(R, 1) GPIO_ACTIVE_LOW>; - linux,code = <114>; /* KEY_VOLUMEDOWN */ + linux,code = <KEY_VOLUMEDOWN>; }; volume_up { label = "Volume Up"; gpios = <&gpio TEGRA_GPIO(R, 2) GPIO_ACTIVE_LOW>; - linux,code = <115>; /* KEY_VOLUMEUP */ + linux,code = <KEY_VOLUMEUP>; }; }; diff --git a/arch/arm/boot/dts/tegra114.dtsi b/arch/arm/boot/dts/tegra114.dtsi index 2905145d8e59..8d42787c8ff1 100644 --- a/arch/arm/boot/dts/tegra114.dtsi +++ b/arch/arm/boot/dts/tegra114.dtsi @@ -318,9 +318,9 @@ iommu { compatible = "nvidia,tegra114-smmu", "nvidia,tegra30-smmu"; - reg = <0x7000f010 0x02c - 0x7000f1f0 0x010 - 0x7000f228 0x074>; + reg = <0x70019010 0x02c + 0x700191f0 0x010 + 0x70019228 0x074>; nvidia,#asids = <4>; dma-window = <0 0x40000000>; nvidia,swgroups = <0x18659fe>; diff --git a/arch/arm/boot/dts/tegra124-venice2.dts b/arch/arm/boot/dts/tegra124-venice2.dts new file mode 100644 index 000000000000..431d67a2b413 --- /dev/null +++ b/arch/arm/boot/dts/tegra124-venice2.dts @@ -0,0 +1,27 @@ +/dts-v1/; + +#include "tegra124.dtsi" + +/ { + model = "NVIDIA Tegra124 Venice2"; + compatible = "nvidia,venice2", "nvidia,tegra124"; + + memory { + reg = <0x80000000 0x80000000>; + }; + + serial@70006000 { + status = "okay"; + }; + + pmc@7000e400 { + nvidia,invert-interrupt; + nvidia,suspend-mode = <1>; + nvidia,cpu-pwr-good-time = <500>; + nvidia,cpu-pwr-off-time = <300>; + nvidia,core-pwr-good-time = <641 3845>; + nvidia,core-pwr-off-time = <61036>; + nvidia,core-power-req-active-high; + nvidia,sys-clock-req-active-high; + }; +}; diff --git a/arch/arm/boot/dts/tegra124.dtsi b/arch/arm/boot/dts/tegra124.dtsi new file mode 100644 index 000000000000..b7413004ee77 --- /dev/null +++ b/arch/arm/boot/dts/tegra124.dtsi @@ -0,0 +1,149 @@ +#include <dt-bindings/gpio/tegra-gpio.h> +#include <dt-bindings/interrupt-controller/arm-gic.h> + +#include "skeleton.dtsi" + +/ { + compatible = "nvidia,tegra124"; + interrupt-parent = <&gic>; + + gic: interrupt-controller@50041000 { + compatible = "arm,cortex-a15-gic"; + #interrupt-cells = <3>; + interrupt-controller; + reg = <0x50041000 0x1000>, + <0x50042000 0x1000>, + <0x50044000 0x2000>, + <0x50046000 0x2000>; + interrupts = <GIC_PPI 9 + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; + }; + + timer@60005000 { + compatible = "nvidia,tegra124-timer", "nvidia,tegra20-timer"; + reg = <0x60005000 0x400>; + interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>; + }; + + gpio: gpio@6000d000 { + compatible = "nvidia,tegra124-gpio", "nvidia,tegra30-gpio"; + reg = <0x6000d000 0x1000>; + interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>; + #gpio-cells = <2>; + gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; + }; + + /* + * There are two serial driver i.e. 8250 based simple serial + * driver and APB DMA based serial driver for higher baudrate + * and performace. To enable the 8250 based driver, the compatible + * is "nvidia,tegra124-uart", "nvidia,tegra20-uart" and to enable + * the APB DMA based serial driver, the comptible is + * "nvidia,tegra124-hsuart", "nvidia,tegra30-hsuart". + */ + serial@70006000 { + compatible = "nvidia,tegra124-uart", "nvidia,tegra20-uart"; + reg = <0x70006000 0x40>; + reg-shift = <2>; + interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + serial@70006040 { + compatible = "nvidia,tegra124-uart", "nvidia,tegra20-uart"; + reg = <0x70006040 0x40>; + reg-shift = <2>; + interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + serial@70006200 { + compatible = "nvidia,tegra124-uart", "nvidia,tegra20-uart"; + reg = <0x70006200 0x40>; + reg-shift = <2>; + interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + serial@70006300 { + compatible = "nvidia,tegra124-uart", "nvidia,tegra20-uart"; + reg = <0x70006300 0x40>; + reg-shift = <2>; + interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + serial@70006400 { + compatible = "nvidia,tegra124-uart", "nvidia,tegra20-uart"; + reg = <0x70006400 0x40>; + reg-shift = <2>; + interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + rtc@7000e000 { + compatible = "nvidia,tegra124-rtc", "nvidia,tegra20-rtc"; + reg = <0x7000e000 0x100>; + interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>; + }; + + pmc@7000e400 { + compatible = "nvidia,tegra124-pmc"; + reg = <0x7000e400 0x400>; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <1>; + }; + + cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <2>; + }; + + cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <3>; + }; + }; + + timer { + compatible = "arm,armv7-timer"; + interrupts = <GIC_PPI 13 + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 14 + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 11 + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 10 + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>; + }; +}; diff --git a/arch/arm/boot/dts/tegra30-cardhu.dtsi b/arch/arm/boot/dts/tegra30-cardhu.dtsi index e19dbf238e5c..5ea7dfa4d9fa 100644 --- a/arch/arm/boot/dts/tegra30-cardhu.dtsi +++ b/arch/arm/boot/dts/tegra30-cardhu.dtsi @@ -294,9 +294,10 @@ }; }; - nct1008 { + temperature-sensor@4c { compatible = "onnn,nct1008"; reg = <0x4c>; + vcc-supply = <&sys_3v3_reg>; interrupt-parent = <&gpio>; interrupts = <TEGRA_GPIO(CC, 2) IRQ_TYPE_LEVEL_LOW>; }; diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi index 0022c127e1d9..2bd55cfd88ad 100644 --- a/arch/arm/boot/dts/tegra30.dtsi +++ b/arch/arm/boot/dts/tegra30.dtsi @@ -136,12 +136,13 @@ gr3d { compatible = "nvidia,tegra30-gr3d"; reg = <0x54180000 0x00040000>; - clocks = <&tegra_car 24 &tegra_car 98>; + clocks = <&tegra_car TEGRA30_CLK_GR3D + &tegra_car TEGRA30_CLK_GR3D2>; clock-names = "3d", "3d2"; }; dc@54200000 { - compatible = "nvidia,tegra30-dc"; + compatible = "nvidia,tegra30-dc", "nvidia,tegra20-dc"; reg = <0x54200000 0x00040000>; interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; clocks = <&tegra_car TEGRA30_CLK_DISP1>, diff --git a/arch/arm/boot/dts/testcases/tests-interrupts.dtsi b/arch/arm/boot/dts/testcases/tests-interrupts.dtsi new file mode 100644 index 000000000000..c843720bd3e5 --- /dev/null +++ b/arch/arm/boot/dts/testcases/tests-interrupts.dtsi @@ -0,0 +1,58 @@ + +/ { + testcase-data { + interrupts { + #address-cells = <1>; + #size-cells = <1>; + test_intc0: intc0 { + interrupt-controller; + #interrupt-cells = <1>; + }; + + test_intc1: intc1 { + interrupt-controller; + #interrupt-cells = <3>; + }; + + test_intc2: intc2 { + interrupt-controller; + #interrupt-cells = <2>; + }; + + test_intmap0: intmap0 { + #interrupt-cells = <1>; + #address-cells = <0>; + interrupt-map = <1 &test_intc0 9>, + <2 &test_intc1 10 11 12>, + <3 &test_intc2 13 14>, + <4 &test_intc2 15 16>; + }; + + test_intmap1: intmap1 { + #interrupt-cells = <2>; + interrupt-map = <0x5000 1 2 &test_intc0 15>; + }; + + interrupts0 { + interrupt-parent = <&test_intc0>; + interrupts = <1>, <2>, <3>, <4>; + }; + + interrupts1 { + interrupt-parent = <&test_intmap0>; + interrupts = <1>, <2>, <3>, <4>; + }; + + interrupts-extended0 { + reg = <0x5000 0x100>; + interrupts-extended = <&test_intc0 1>, + <&test_intc1 2 3 4>, + <&test_intc2 5 6>, + <&test_intmap0 1>, + <&test_intmap0 2>, + <&test_intmap0 3>, + <&test_intmap1 1 2>; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/testcases/tests.dtsi b/arch/arm/boot/dts/testcases/tests.dtsi index a7c5067622e8..3f123ecc9dd7 100644 --- a/arch/arm/boot/dts/testcases/tests.dtsi +++ b/arch/arm/boot/dts/testcases/tests.dtsi @@ -1 +1,2 @@ /include/ "tests-phandle.dtsi" +/include/ "tests-interrupts.dtsi" diff --git a/arch/arm/boot/dts/twl4030.dtsi b/arch/arm/boot/dts/twl4030.dtsi index ae6a17aed9ee..4217096ee677 100644 --- a/arch/arm/boot/dts/twl4030.dtsi +++ b/arch/arm/boot/dts/twl4030.dtsi @@ -19,10 +19,32 @@ interrupts = <11>; }; + charger: bci { + compatible = "ti,twl4030-bci"; + interrupts = <9>, <2>; + bci3v1-supply = <&vusb3v1>; + }; + watchdog { compatible = "ti,twl4030-wdt"; }; + vaux1: regulator-vaux1 { + compatible = "ti,twl4030-vaux1"; + }; + + vaux2: regulator-vaux2 { + compatible = "ti,twl4030-vaux2"; + }; + + vaux3: regulator-vaux3 { + compatible = "ti,twl4030-vaux3"; + }; + + vaux4: regulator-vaux4 { + compatible = "ti,twl4030-vaux4"; + }; + vcc: regulator-vdd1 { compatible = "ti,twl4030-vdd1"; regulator-min-microvolt = <600000>; @@ -35,10 +57,20 @@ regulator-max-microvolt = <1800000>; }; - vpll2: regulator-vpll2 { - compatible = "ti,twl4030-vpll2"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; + vio: regulator-vio { + compatible = "ti,twl4030-vio"; + }; + + vintana1: regulator-vintana1 { + compatible = "ti,twl4030-vintana1"; + }; + + vintana2: regulator-vintana2 { + compatible = "ti,twl4030-vintana2"; + }; + + vintdig: regulator-vintdig { + compatible = "ti,twl4030-vintdig"; }; vmmc1: regulator-vmmc1 { @@ -65,6 +97,16 @@ compatible = "ti,twl4030-vusb3v1"; }; + vpll1: regulator-vpll1 { + compatible = "ti,twl4030-vpll1"; + }; + + vpll2: regulator-vpll2 { + compatible = "ti,twl4030-vpll2"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + vsim: regulator-vsim { compatible = "ti,twl4030-vsim"; regulator-min-microvolt = <1800000>; @@ -86,6 +128,7 @@ usb1v8-supply = <&vusb1v8>; usb3v1-supply = <&vusb3v1>; usb_mode = <1>; + #phy-cells = <0>; }; twl_pwm: pwm { @@ -97,4 +140,9 @@ compatible = "ti,twl4030-pwmled"; #pwm-cells = <2>; }; + + twl_pwrbutton: pwrbutton { + compatible = "ti,twl4030-pwrbutton"; + interrupts = <8>; + }; }; diff --git a/arch/arm/boot/dts/twl6030_omap4.dtsi b/arch/arm/boot/dts/twl6030_omap4.dtsi new file mode 100644 index 000000000000..a4fa5703c42b --- /dev/null +++ b/arch/arm/boot/dts/twl6030_omap4.dtsi @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.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 + * published by the Free Software Foundation. + */ + +&twl { + /* + * On most OMAP4 platforms, the twl6030 IRQ line is connected + * to the SYS_NIRQ1 line on OMAP and the twl6030 MSECURE line is + * connected to the fref_clk0_out.sys_drm_msecure line. + * Therefore, configure the defaults for the SYS_NIRQ1 and + * fref_clk0_out.sys_drm_msecure pins here. + */ + pinctrl-names = "default"; + pinctrl-0 = < + &twl6030_pins + &twl6030_wkup_pins + >; +}; + +&omap4_pmx_wkup { + twl6030_wkup_pins: pinmux_twl6030_wkup_pins { + pinctrl-single,pins = < + 0x14 (PIN_OUTPUT | MUX_MODE2) /* fref_clk0_out.sys_drm_msecure */ + >; + }; +}; + +&omap4_pmx_core { + twl6030_pins: pinmux_twl6030_pins { + pinctrl-single,pins = < + 0x15e (WAKEUP_EN | PIN_INPUT_PULLUP | MUX_MODE0) /* sys_nirq1.sys_nirq1 */ + >; + }; +}; diff --git a/arch/arm/boot/dts/versatile-ab.dts b/arch/arm/boot/dts/versatile-ab.dts index dde75ae8b4b1..e01e5a081def 100644 --- a/arch/arm/boot/dts/versatile-ab.dts +++ b/arch/arm/boot/dts/versatile-ab.dts @@ -185,7 +185,7 @@ mmc@5000 { compatible = "arm,primecell"; reg = < 0x5000 0x1000>; - interrupts = <22 34>; + interrupts-extended = <&vic 22 &sic 2>; }; kmi@6000 { compatible = "arm,pl050", "arm,primecell"; diff --git a/arch/arm/boot/dts/versatile-pb.dts b/arch/arm/boot/dts/versatile-pb.dts index 7e8175269064..f43907c40c93 100644 --- a/arch/arm/boot/dts/versatile-pb.dts +++ b/arch/arm/boot/dts/versatile-pb.dts @@ -41,7 +41,7 @@ mmc@b000 { compatible = "arm,primecell"; reg = <0xb000 0x1000>; - interrupts = <23 34>; + interrupts-extended = <&vic 23 &sic 2>; }; }; }; diff --git a/arch/arm/boot/dts/vf610-cosmic.dts b/arch/arm/boot/dts/vf610-cosmic.dts new file mode 100644 index 000000000000..c42e4f938dcd --- /dev/null +++ b/arch/arm/boot/dts/vf610-cosmic.dts @@ -0,0 +1,47 @@ +/* + * Copyright 2013 Freescale Semiconductor, Inc. + * Copyright 2013 Linaro Limited + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +/dts-v1/; +#include "vf610.dtsi" + +/ { + model = "PHYTEC Cosmic/Cosmic+ Board"; + compatible = "phytec,vf610-cosmic", "fsl,vf610"; + + chosen { + bootargs = "console=ttyLP1,115200"; + }; + + memory { + reg = <0x80000000 0x10000000>; + }; + + clocks { + enet_ext { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <50000000>; + }; + }; + +}; + +&fec1 { + phy-mode = "rmii"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fec1_1>; + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1_1>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/vf610-twr.dts b/arch/arm/boot/dts/vf610-twr.dts index 1a58678b93fa..c8047ca16501 100644 --- a/arch/arm/boot/dts/vf610-twr.dts +++ b/arch/arm/boot/dts/vf610-twr.dts @@ -36,6 +36,23 @@ }; +&dspi0 { + bus-num = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_dspi0_1>; + status = "okay"; + + sflash: at26df081a@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "atmel,at26df081a"; + spi-max-frequency = <16000000>; + spi-cpol; + spi-cpha; + reg = <0>; + }; +}; + &fec0 { phy-mode = "rmii"; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/vf610.dtsi b/arch/arm/boot/dts/vf610.dtsi index 67d929cf9804..d31ce1b4a7b0 100644 --- a/arch/arm/boot/dts/vf610.dtsi +++ b/arch/arm/boot/dts/vf610.dtsi @@ -123,6 +123,18 @@ status = "disabled"; }; + dspi0: dspi0@4002c000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,vf610-dspi"; + reg = <0x4002c000 0x1000>; + interrupts = <0 67 0x04>; + clocks = <&clks VF610_CLK_DSPI0>; + clock-names = "dspi"; + spi-num-chipselects = <5>; + status = "disabled"; + }; + sai2: sai@40031000 { compatible = "fsl,vf610-sai"; reg = <0x40031000 0x1000>; diff --git a/arch/arm/boot/dts/zynq-7000.dtsi b/arch/arm/boot/dts/zynq-7000.dtsi index e32b92b949d2..e7f73b2e4550 100644 --- a/arch/arm/boot/dts/zynq-7000.dtsi +++ b/arch/arm/boot/dts/zynq-7000.dtsi @@ -92,6 +92,14 @@ }; }; + global_timer: timer@f8f00200 { + compatible = "arm,cortex-a9-global-timer"; + reg = <0xf8f00200 0x20>; + interrupts = <1 11 0x301>; + interrupt-parent = <&intc>; + clocks = <&clkc 4>; + }; + ttc0: ttc0@f8001000 { interrupt-parent = <&intc>; interrupts = < 0 10 4 0 11 4 0 12 4 >; diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile index 8c60f473e976..4bdc41622c36 100644 --- a/arch/arm/common/Makefile +++ b/arch/arm/common/Makefile @@ -6,7 +6,6 @@ obj-y += firmware.o obj-$(CONFIG_ICST) += icst.o obj-$(CONFIG_SA1111) += sa1111.o -obj-$(CONFIG_PCI_HOST_VIA82C505) += via82c505.o obj-$(CONFIG_DMABOUNCE) += dmabounce.o obj-$(CONFIG_SHARP_LOCOMO) += locomo.o obj-$(CONFIG_SHARP_PARAM) += sharpsl_param.o @@ -17,3 +16,5 @@ obj-$(CONFIG_MCPM) += mcpm_head.o mcpm_entry.o mcpm_platsmp.o vlock.o AFLAGS_mcpm_head.o := -march=armv7-a AFLAGS_vlock.o := -march=armv7-a obj-$(CONFIG_TI_PRIV_EDMA) += edma.o +obj-$(CONFIG_BL_SWITCHER) += bL_switcher.o +obj-$(CONFIG_BL_SWITCHER_DUMMY_IF) += bL_switcher_dummy_if.o diff --git a/arch/arm/common/bL_switcher.c b/arch/arm/common/bL_switcher.c new file mode 100644 index 000000000000..5774b6ea7ad5 --- /dev/null +++ b/arch/arm/common/bL_switcher.c @@ -0,0 +1,822 @@ +/* + * arch/arm/common/bL_switcher.c -- big.LITTLE cluster switcher core driver + * + * Created by: Nicolas Pitre, March 2012 + * Copyright: (C) 2012-2013 Linaro Limited + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/atomic.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/cpu_pm.h> +#include <linux/cpu.h> +#include <linux/cpumask.h> +#include <linux/kthread.h> +#include <linux/wait.h> +#include <linux/time.h> +#include <linux/clockchips.h> +#include <linux/hrtimer.h> +#include <linux/tick.h> +#include <linux/notifier.h> +#include <linux/mm.h> +#include <linux/mutex.h> +#include <linux/smp.h> +#include <linux/spinlock.h> +#include <linux/string.h> +#include <linux/sysfs.h> +#include <linux/irqchip/arm-gic.h> +#include <linux/moduleparam.h> + +#include <asm/smp_plat.h> +#include <asm/cputype.h> +#include <asm/suspend.h> +#include <asm/mcpm.h> +#include <asm/bL_switcher.h> + +#define CREATE_TRACE_POINTS +#include <trace/events/power_cpu_migrate.h> + + +/* + * Use our own MPIDR accessors as the generic ones in asm/cputype.h have + * __attribute_const__ and we don't want the compiler to assume any + * constness here as the value _does_ change along some code paths. + */ + +static int read_mpidr(void) +{ + unsigned int id; + asm volatile ("mrc p15, 0, %0, c0, c0, 5" : "=r" (id)); + return id & MPIDR_HWID_BITMASK; +} + +/* + * Get a global nanosecond time stamp for tracing. + */ +static s64 get_ns(void) +{ + struct timespec ts; + getnstimeofday(&ts); + return timespec_to_ns(&ts); +} + +/* + * bL switcher core code. + */ + +static void bL_do_switch(void *_arg) +{ + unsigned ib_mpidr, ib_cpu, ib_cluster; + long volatile handshake, **handshake_ptr = _arg; + + pr_debug("%s\n", __func__); + + ib_mpidr = cpu_logical_map(smp_processor_id()); + ib_cpu = MPIDR_AFFINITY_LEVEL(ib_mpidr, 0); + ib_cluster = MPIDR_AFFINITY_LEVEL(ib_mpidr, 1); + + /* Advertise our handshake location */ + if (handshake_ptr) { + handshake = 0; + *handshake_ptr = &handshake; + } else + handshake = -1; + + /* + * Our state has been saved at this point. Let's release our + * inbound CPU. + */ + mcpm_set_entry_vector(ib_cpu, ib_cluster, cpu_resume); + sev(); + + /* + * From this point, we must assume that our counterpart CPU might + * have taken over in its parallel world already, as if execution + * just returned from cpu_suspend(). It is therefore important to + * be very careful not to make any change the other guy is not + * expecting. This is why we need stack isolation. + * + * Fancy under cover tasks could be performed here. For now + * we have none. + */ + + /* + * Let's wait until our inbound is alive. + */ + while (!handshake) { + wfe(); + smp_mb(); + } + + /* Let's put ourself down. */ + mcpm_cpu_power_down(); + + /* should never get here */ + BUG(); +} + +/* + * Stack isolation. To ensure 'current' remains valid, we just use another + * piece of our thread's stack space which should be fairly lightly used. + * The selected area starts just above the thread_info structure located + * at the very bottom of the stack, aligned to a cache line, and indexed + * with the cluster number. + */ +#define STACK_SIZE 512 +extern void call_with_stack(void (*fn)(void *), void *arg, void *sp); +static int bL_switchpoint(unsigned long _arg) +{ + unsigned int mpidr = read_mpidr(); + unsigned int clusterid = MPIDR_AFFINITY_LEVEL(mpidr, 1); + void *stack = current_thread_info() + 1; + stack = PTR_ALIGN(stack, L1_CACHE_BYTES); + stack += clusterid * STACK_SIZE + STACK_SIZE; + call_with_stack(bL_do_switch, (void *)_arg, stack); + BUG(); +} + +/* + * Generic switcher interface + */ + +static unsigned int bL_gic_id[MAX_CPUS_PER_CLUSTER][MAX_NR_CLUSTERS]; +static int bL_switcher_cpu_pairing[NR_CPUS]; + +/* + * bL_switch_to - Switch to a specific cluster for the current CPU + * @new_cluster_id: the ID of the cluster to switch to. + * + * This function must be called on the CPU to be switched. + * Returns 0 on success, else a negative status code. + */ +static int bL_switch_to(unsigned int new_cluster_id) +{ + unsigned int mpidr, this_cpu, that_cpu; + unsigned int ob_mpidr, ob_cpu, ob_cluster, ib_mpidr, ib_cpu, ib_cluster; + struct completion inbound_alive; + struct tick_device *tdev; + enum clock_event_mode tdev_mode; + long volatile *handshake_ptr; + int ipi_nr, ret; + + this_cpu = smp_processor_id(); + ob_mpidr = read_mpidr(); + ob_cpu = MPIDR_AFFINITY_LEVEL(ob_mpidr, 0); + ob_cluster = MPIDR_AFFINITY_LEVEL(ob_mpidr, 1); + BUG_ON(cpu_logical_map(this_cpu) != ob_mpidr); + + if (new_cluster_id == ob_cluster) + return 0; + + that_cpu = bL_switcher_cpu_pairing[this_cpu]; + ib_mpidr = cpu_logical_map(that_cpu); + ib_cpu = MPIDR_AFFINITY_LEVEL(ib_mpidr, 0); + ib_cluster = MPIDR_AFFINITY_LEVEL(ib_mpidr, 1); + + pr_debug("before switch: CPU %d MPIDR %#x -> %#x\n", + this_cpu, ob_mpidr, ib_mpidr); + + this_cpu = smp_processor_id(); + + /* Close the gate for our entry vectors */ + mcpm_set_entry_vector(ob_cpu, ob_cluster, NULL); + mcpm_set_entry_vector(ib_cpu, ib_cluster, NULL); + + /* Install our "inbound alive" notifier. */ + init_completion(&inbound_alive); + ipi_nr = register_ipi_completion(&inbound_alive, this_cpu); + ipi_nr |= ((1 << 16) << bL_gic_id[ob_cpu][ob_cluster]); + mcpm_set_early_poke(ib_cpu, ib_cluster, gic_get_sgir_physaddr(), ipi_nr); + + /* + * Let's wake up the inbound CPU now in case it requires some delay + * to come online, but leave it gated in our entry vector code. + */ + ret = mcpm_cpu_power_up(ib_cpu, ib_cluster); + if (ret) { + pr_err("%s: mcpm_cpu_power_up() returned %d\n", __func__, ret); + return ret; + } + + /* + * Raise a SGI on the inbound CPU to make sure it doesn't stall + * in a possible WFI, such as in bL_power_down(). + */ + gic_send_sgi(bL_gic_id[ib_cpu][ib_cluster], 0); + + /* + * Wait for the inbound to come up. This allows for other + * tasks to be scheduled in the mean time. + */ + wait_for_completion(&inbound_alive); + mcpm_set_early_poke(ib_cpu, ib_cluster, 0, 0); + + /* + * From this point we are entering the switch critical zone + * and can't take any interrupts anymore. + */ + local_irq_disable(); + local_fiq_disable(); + trace_cpu_migrate_begin(get_ns(), ob_mpidr); + + /* redirect GIC's SGIs to our counterpart */ + gic_migrate_target(bL_gic_id[ib_cpu][ib_cluster]); + + tdev = tick_get_device(this_cpu); + if (tdev && !cpumask_equal(tdev->evtdev->cpumask, cpumask_of(this_cpu))) + tdev = NULL; + if (tdev) { + tdev_mode = tdev->evtdev->mode; + clockevents_set_mode(tdev->evtdev, CLOCK_EVT_MODE_SHUTDOWN); + } + + ret = cpu_pm_enter(); + + /* we can not tolerate errors at this point */ + if (ret) + panic("%s: cpu_pm_enter() returned %d\n", __func__, ret); + + /* Swap the physical CPUs in the logical map for this logical CPU. */ + cpu_logical_map(this_cpu) = ib_mpidr; + cpu_logical_map(that_cpu) = ob_mpidr; + + /* Let's do the actual CPU switch. */ + ret = cpu_suspend((unsigned long)&handshake_ptr, bL_switchpoint); + if (ret > 0) + panic("%s: cpu_suspend() returned %d\n", __func__, ret); + + /* We are executing on the inbound CPU at this point */ + mpidr = read_mpidr(); + pr_debug("after switch: CPU %d MPIDR %#x\n", this_cpu, mpidr); + BUG_ON(mpidr != ib_mpidr); + + mcpm_cpu_powered_up(); + + ret = cpu_pm_exit(); + + if (tdev) { + clockevents_set_mode(tdev->evtdev, tdev_mode); + clockevents_program_event(tdev->evtdev, + tdev->evtdev->next_event, 1); + } + + trace_cpu_migrate_finish(get_ns(), ib_mpidr); + local_fiq_enable(); + local_irq_enable(); + + *handshake_ptr = 1; + dsb_sev(); + + if (ret) + pr_err("%s exiting with error %d\n", __func__, ret); + return ret; +} + +struct bL_thread { + spinlock_t lock; + struct task_struct *task; + wait_queue_head_t wq; + int wanted_cluster; + struct completion started; + bL_switch_completion_handler completer; + void *completer_cookie; +}; + +static struct bL_thread bL_threads[NR_CPUS]; + +static int bL_switcher_thread(void *arg) +{ + struct bL_thread *t = arg; + struct sched_param param = { .sched_priority = 1 }; + int cluster; + bL_switch_completion_handler completer; + void *completer_cookie; + + sched_setscheduler_nocheck(current, SCHED_FIFO, ¶m); + complete(&t->started); + + do { + if (signal_pending(current)) + flush_signals(current); + wait_event_interruptible(t->wq, + t->wanted_cluster != -1 || + kthread_should_stop()); + + spin_lock(&t->lock); + cluster = t->wanted_cluster; + completer = t->completer; + completer_cookie = t->completer_cookie; + t->wanted_cluster = -1; + t->completer = NULL; + spin_unlock(&t->lock); + + if (cluster != -1) { + bL_switch_to(cluster); + + if (completer) + completer(completer_cookie); + } + } while (!kthread_should_stop()); + + return 0; +} + +static struct task_struct *bL_switcher_thread_create(int cpu, void *arg) +{ + struct task_struct *task; + + task = kthread_create_on_node(bL_switcher_thread, arg, + cpu_to_node(cpu), "kswitcher_%d", cpu); + if (!IS_ERR(task)) { + kthread_bind(task, cpu); + wake_up_process(task); + } else + pr_err("%s failed for CPU %d\n", __func__, cpu); + return task; +} + +/* + * bL_switch_request_cb - Switch to a specific cluster for the given CPU, + * with completion notification via a callback + * + * @cpu: the CPU to switch + * @new_cluster_id: the ID of the cluster to switch to. + * @completer: switch completion callback. if non-NULL, + * @completer(@completer_cookie) will be called on completion of + * the switch, in non-atomic context. + * @completer_cookie: opaque context argument for @completer. + * + * This function causes a cluster switch on the given CPU by waking up + * the appropriate switcher thread. This function may or may not return + * before the switch has occurred. + * + * If a @completer callback function is supplied, it will be called when + * the switch is complete. This can be used to determine asynchronously + * when the switch is complete, regardless of when bL_switch_request() + * returns. When @completer is supplied, no new switch request is permitted + * for the affected CPU until after the switch is complete, and @completer + * has returned. + */ +int bL_switch_request_cb(unsigned int cpu, unsigned int new_cluster_id, + bL_switch_completion_handler completer, + void *completer_cookie) +{ + struct bL_thread *t; + + if (cpu >= ARRAY_SIZE(bL_threads)) { + pr_err("%s: cpu %d out of bounds\n", __func__, cpu); + return -EINVAL; + } + + t = &bL_threads[cpu]; + + if (IS_ERR(t->task)) + return PTR_ERR(t->task); + if (!t->task) + return -ESRCH; + + spin_lock(&t->lock); + if (t->completer) { + spin_unlock(&t->lock); + return -EBUSY; + } + t->completer = completer; + t->completer_cookie = completer_cookie; + t->wanted_cluster = new_cluster_id; + spin_unlock(&t->lock); + wake_up(&t->wq); + return 0; +} +EXPORT_SYMBOL_GPL(bL_switch_request_cb); + +/* + * Activation and configuration code. + */ + +static DEFINE_MUTEX(bL_switcher_activation_lock); +static BLOCKING_NOTIFIER_HEAD(bL_activation_notifier); +static unsigned int bL_switcher_active; +static unsigned int bL_switcher_cpu_original_cluster[NR_CPUS]; +static cpumask_t bL_switcher_removed_logical_cpus; + +int bL_switcher_register_notifier(struct notifier_block *nb) +{ + return blocking_notifier_chain_register(&bL_activation_notifier, nb); +} +EXPORT_SYMBOL_GPL(bL_switcher_register_notifier); + +int bL_switcher_unregister_notifier(struct notifier_block *nb) +{ + return blocking_notifier_chain_unregister(&bL_activation_notifier, nb); +} +EXPORT_SYMBOL_GPL(bL_switcher_unregister_notifier); + +static int bL_activation_notify(unsigned long val) +{ + int ret; + + ret = blocking_notifier_call_chain(&bL_activation_notifier, val, NULL); + if (ret & NOTIFY_STOP_MASK) + pr_err("%s: notifier chain failed with status 0x%x\n", + __func__, ret); + return notifier_to_errno(ret); +} + +static void bL_switcher_restore_cpus(void) +{ + int i; + + for_each_cpu(i, &bL_switcher_removed_logical_cpus) + cpu_up(i); +} + +static int bL_switcher_halve_cpus(void) +{ + int i, j, cluster_0, gic_id, ret; + unsigned int cpu, cluster, mask; + cpumask_t available_cpus; + + /* First pass to validate what we have */ + mask = 0; + for_each_online_cpu(i) { + cpu = MPIDR_AFFINITY_LEVEL(cpu_logical_map(i), 0); + cluster = MPIDR_AFFINITY_LEVEL(cpu_logical_map(i), 1); + if (cluster >= 2) { + pr_err("%s: only dual cluster systems are supported\n", __func__); + return -EINVAL; + } + if (WARN_ON(cpu >= MAX_CPUS_PER_CLUSTER)) + return -EINVAL; + mask |= (1 << cluster); + } + if (mask != 3) { + pr_err("%s: no CPU pairing possible\n", __func__); + return -EINVAL; + } + + /* + * Now let's do the pairing. We match each CPU with another CPU + * from a different cluster. To get a uniform scheduling behavior + * without fiddling with CPU topology and compute capacity data, + * we'll use logical CPUs initially belonging to the same cluster. + */ + memset(bL_switcher_cpu_pairing, -1, sizeof(bL_switcher_cpu_pairing)); + cpumask_copy(&available_cpus, cpu_online_mask); + cluster_0 = -1; + for_each_cpu(i, &available_cpus) { + int match = -1; + cluster = MPIDR_AFFINITY_LEVEL(cpu_logical_map(i), 1); + if (cluster_0 == -1) + cluster_0 = cluster; + if (cluster != cluster_0) + continue; + cpumask_clear_cpu(i, &available_cpus); + for_each_cpu(j, &available_cpus) { + cluster = MPIDR_AFFINITY_LEVEL(cpu_logical_map(j), 1); + /* + * Let's remember the last match to create "odd" + * pairings on purpose in order for other code not + * to assume any relation between physical and + * logical CPU numbers. + */ + if (cluster != cluster_0) + match = j; + } + if (match != -1) { + bL_switcher_cpu_pairing[i] = match; + cpumask_clear_cpu(match, &available_cpus); + pr_info("CPU%d paired with CPU%d\n", i, match); + } + } + + /* + * Now we disable the unwanted CPUs i.e. everything that has no + * pairing information (that includes the pairing counterparts). + */ + cpumask_clear(&bL_switcher_removed_logical_cpus); + for_each_online_cpu(i) { + cpu = MPIDR_AFFINITY_LEVEL(cpu_logical_map(i), 0); + cluster = MPIDR_AFFINITY_LEVEL(cpu_logical_map(i), 1); + + /* Let's take note of the GIC ID for this CPU */ + gic_id = gic_get_cpu_id(i); + if (gic_id < 0) { + pr_err("%s: bad GIC ID for CPU %d\n", __func__, i); + bL_switcher_restore_cpus(); + return -EINVAL; + } + bL_gic_id[cpu][cluster] = gic_id; + pr_info("GIC ID for CPU %u cluster %u is %u\n", + cpu, cluster, gic_id); + + if (bL_switcher_cpu_pairing[i] != -1) { + bL_switcher_cpu_original_cluster[i] = cluster; + continue; + } + + ret = cpu_down(i); + if (ret) { + bL_switcher_restore_cpus(); + return ret; + } + cpumask_set_cpu(i, &bL_switcher_removed_logical_cpus); + } + + return 0; +} + +/* Determine the logical CPU a given physical CPU is grouped on. */ +int bL_switcher_get_logical_index(u32 mpidr) +{ + int cpu; + + if (!bL_switcher_active) + return -EUNATCH; + + mpidr &= MPIDR_HWID_BITMASK; + for_each_online_cpu(cpu) { + int pairing = bL_switcher_cpu_pairing[cpu]; + if (pairing == -1) + continue; + if ((mpidr == cpu_logical_map(cpu)) || + (mpidr == cpu_logical_map(pairing))) + return cpu; + } + return -EINVAL; +} + +static void bL_switcher_trace_trigger_cpu(void *__always_unused info) +{ + trace_cpu_migrate_current(get_ns(), read_mpidr()); +} + +int bL_switcher_trace_trigger(void) +{ + int ret; + + preempt_disable(); + + bL_switcher_trace_trigger_cpu(NULL); + ret = smp_call_function(bL_switcher_trace_trigger_cpu, NULL, true); + + preempt_enable(); + + return ret; +} +EXPORT_SYMBOL_GPL(bL_switcher_trace_trigger); + +static int bL_switcher_enable(void) +{ + int cpu, ret; + + mutex_lock(&bL_switcher_activation_lock); + lock_device_hotplug(); + if (bL_switcher_active) { + unlock_device_hotplug(); + mutex_unlock(&bL_switcher_activation_lock); + return 0; + } + + pr_info("big.LITTLE switcher initializing\n"); + + ret = bL_activation_notify(BL_NOTIFY_PRE_ENABLE); + if (ret) + goto error; + + ret = bL_switcher_halve_cpus(); + if (ret) + goto error; + + bL_switcher_trace_trigger(); + + for_each_online_cpu(cpu) { + struct bL_thread *t = &bL_threads[cpu]; + spin_lock_init(&t->lock); + init_waitqueue_head(&t->wq); + init_completion(&t->started); + t->wanted_cluster = -1; + t->task = bL_switcher_thread_create(cpu, t); + } + + bL_switcher_active = 1; + bL_activation_notify(BL_NOTIFY_POST_ENABLE); + pr_info("big.LITTLE switcher initialized\n"); + goto out; + +error: + pr_warn("big.LITTLE switcher initialization failed\n"); + bL_activation_notify(BL_NOTIFY_POST_DISABLE); + +out: + unlock_device_hotplug(); + mutex_unlock(&bL_switcher_activation_lock); + return ret; +} + +#ifdef CONFIG_SYSFS + +static void bL_switcher_disable(void) +{ + unsigned int cpu, cluster; + struct bL_thread *t; + struct task_struct *task; + + mutex_lock(&bL_switcher_activation_lock); + lock_device_hotplug(); + + if (!bL_switcher_active) + goto out; + + if (bL_activation_notify(BL_NOTIFY_PRE_DISABLE) != 0) { + bL_activation_notify(BL_NOTIFY_POST_ENABLE); + goto out; + } + + bL_switcher_active = 0; + + /* + * To deactivate the switcher, we must shut down the switcher + * threads to prevent any other requests from being accepted. + * Then, if the final cluster for given logical CPU is not the + * same as the original one, we'll recreate a switcher thread + * just for the purpose of switching the CPU back without any + * possibility for interference from external requests. + */ + for_each_online_cpu(cpu) { + t = &bL_threads[cpu]; + task = t->task; + t->task = NULL; + if (!task || IS_ERR(task)) + continue; + kthread_stop(task); + /* no more switch may happen on this CPU at this point */ + cluster = MPIDR_AFFINITY_LEVEL(cpu_logical_map(cpu), 1); + if (cluster == bL_switcher_cpu_original_cluster[cpu]) + continue; + init_completion(&t->started); + t->wanted_cluster = bL_switcher_cpu_original_cluster[cpu]; + task = bL_switcher_thread_create(cpu, t); + if (!IS_ERR(task)) { + wait_for_completion(&t->started); + kthread_stop(task); + cluster = MPIDR_AFFINITY_LEVEL(cpu_logical_map(cpu), 1); + if (cluster == bL_switcher_cpu_original_cluster[cpu]) + continue; + } + /* If execution gets here, we're in trouble. */ + pr_crit("%s: unable to restore original cluster for CPU %d\n", + __func__, cpu); + pr_crit("%s: CPU %d can't be restored\n", + __func__, bL_switcher_cpu_pairing[cpu]); + cpumask_clear_cpu(bL_switcher_cpu_pairing[cpu], + &bL_switcher_removed_logical_cpus); + } + + bL_switcher_restore_cpus(); + bL_switcher_trace_trigger(); + + bL_activation_notify(BL_NOTIFY_POST_DISABLE); + +out: + unlock_device_hotplug(); + mutex_unlock(&bL_switcher_activation_lock); +} + +static ssize_t bL_switcher_active_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return sprintf(buf, "%u\n", bL_switcher_active); +} + +static ssize_t bL_switcher_active_store(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, size_t count) +{ + int ret; + + switch (buf[0]) { + case '0': + bL_switcher_disable(); + ret = 0; + break; + case '1': + ret = bL_switcher_enable(); + break; + default: + ret = -EINVAL; + } + + return (ret >= 0) ? count : ret; +} + +static ssize_t bL_switcher_trace_trigger_store(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, size_t count) +{ + int ret = bL_switcher_trace_trigger(); + + return ret ? ret : count; +} + +static struct kobj_attribute bL_switcher_active_attr = + __ATTR(active, 0644, bL_switcher_active_show, bL_switcher_active_store); + +static struct kobj_attribute bL_switcher_trace_trigger_attr = + __ATTR(trace_trigger, 0200, NULL, bL_switcher_trace_trigger_store); + +static struct attribute *bL_switcher_attrs[] = { + &bL_switcher_active_attr.attr, + &bL_switcher_trace_trigger_attr.attr, + NULL, +}; + +static struct attribute_group bL_switcher_attr_group = { + .attrs = bL_switcher_attrs, +}; + +static struct kobject *bL_switcher_kobj; + +static int __init bL_switcher_sysfs_init(void) +{ + int ret; + + bL_switcher_kobj = kobject_create_and_add("bL_switcher", kernel_kobj); + if (!bL_switcher_kobj) + return -ENOMEM; + ret = sysfs_create_group(bL_switcher_kobj, &bL_switcher_attr_group); + if (ret) + kobject_put(bL_switcher_kobj); + return ret; +} + +#endif /* CONFIG_SYSFS */ + +bool bL_switcher_get_enabled(void) +{ + mutex_lock(&bL_switcher_activation_lock); + + return bL_switcher_active; +} +EXPORT_SYMBOL_GPL(bL_switcher_get_enabled); + +void bL_switcher_put_enabled(void) +{ + mutex_unlock(&bL_switcher_activation_lock); +} +EXPORT_SYMBOL_GPL(bL_switcher_put_enabled); + +/* + * Veto any CPU hotplug operation on those CPUs we've removed + * while the switcher is active. + * We're just not ready to deal with that given the trickery involved. + */ +static int bL_switcher_hotplug_callback(struct notifier_block *nfb, + unsigned long action, void *hcpu) +{ + if (bL_switcher_active) { + int pairing = bL_switcher_cpu_pairing[(unsigned long)hcpu]; + switch (action & 0xf) { + case CPU_UP_PREPARE: + case CPU_DOWN_PREPARE: + if (pairing == -1) + return NOTIFY_BAD; + } + } + return NOTIFY_DONE; +} + +static bool no_bL_switcher; +core_param(no_bL_switcher, no_bL_switcher, bool, 0644); + +static int __init bL_switcher_init(void) +{ + int ret; + + if (MAX_NR_CLUSTERS != 2) { + pr_err("%s: only dual cluster systems are supported\n", __func__); + return -EINVAL; + } + + cpu_notifier(bL_switcher_hotplug_callback, 0); + + if (!no_bL_switcher) { + ret = bL_switcher_enable(); + if (ret) + return ret; + } + +#ifdef CONFIG_SYSFS + ret = bL_switcher_sysfs_init(); + if (ret) + pr_err("%s: unable to create sysfs entry\n", __func__); +#endif + + return 0; +} + +late_initcall(bL_switcher_init); diff --git a/arch/arm/common/bL_switcher_dummy_if.c b/arch/arm/common/bL_switcher_dummy_if.c new file mode 100644 index 000000000000..3f47f1203c6b --- /dev/null +++ b/arch/arm/common/bL_switcher_dummy_if.c @@ -0,0 +1,71 @@ +/* + * arch/arm/common/bL_switcher_dummy_if.c -- b.L switcher dummy interface + * + * Created by: Nicolas Pitre, November 2012 + * Copyright: (C) 2012-2013 Linaro Limited + * + * Dummy interface to user space for debugging purpose only. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/init.h> +#include <linux/module.h> +#include <linux/fs.h> +#include <linux/miscdevice.h> +#include <asm/uaccess.h> +#include <asm/bL_switcher.h> + +static ssize_t bL_switcher_write(struct file *file, const char __user *buf, + size_t len, loff_t *pos) +{ + unsigned char val[3]; + unsigned int cpu, cluster; + int ret; + + pr_debug("%s\n", __func__); + + if (len < 3) + return -EINVAL; + + if (copy_from_user(val, buf, 3)) + return -EFAULT; + + /* format: <cpu#>,<cluster#> */ + if (val[0] < '0' || val[0] > '9' || + val[1] != ',' || + val[2] < '0' || val[2] > '1') + return -EINVAL; + + cpu = val[0] - '0'; + cluster = val[2] - '0'; + ret = bL_switch_request(cpu, cluster); + + return ret ? : len; +} + +static const struct file_operations bL_switcher_fops = { + .write = bL_switcher_write, + .owner = THIS_MODULE, +}; + +static struct miscdevice bL_switcher_device = { + MISC_DYNAMIC_MINOR, + "b.L_switcher", + &bL_switcher_fops +}; + +static int __init bL_switcher_dummy_if_init(void) +{ + return misc_register(&bL_switcher_device); +} + +static void __exit bL_switcher_dummy_if_exit(void) +{ + misc_deregister(&bL_switcher_device); +} + +module_init(bL_switcher_dummy_if_init); +module_exit(bL_switcher_dummy_if_exit); diff --git a/arch/arm/common/mcpm_entry.c b/arch/arm/common/mcpm_entry.c index 990250965f2c..26020a03f659 100644 --- a/arch/arm/common/mcpm_entry.c +++ b/arch/arm/common/mcpm_entry.c @@ -27,6 +27,18 @@ void mcpm_set_entry_vector(unsigned cpu, unsigned cluster, void *ptr) sync_cache_w(&mcpm_entry_vectors[cluster][cpu]); } +extern unsigned long mcpm_entry_early_pokes[MAX_NR_CLUSTERS][MAX_CPUS_PER_CLUSTER][2]; + +void mcpm_set_early_poke(unsigned cpu, unsigned cluster, + unsigned long poke_phys_addr, unsigned long poke_val) +{ + unsigned long *poke = &mcpm_entry_early_pokes[cluster][cpu][0]; + poke[0] = poke_phys_addr; + poke[1] = poke_val; + __cpuc_flush_dcache_area((void *)poke, 8); + outer_clean_range(__pa(poke), __pa(poke + 2)); +} + static const struct mcpm_platform_ops *platform_ops; int __init mcpm_platform_register(const struct mcpm_platform_ops *ops) @@ -90,6 +102,21 @@ void mcpm_cpu_power_down(void) BUG(); } +int mcpm_cpu_power_down_finish(unsigned int cpu, unsigned int cluster) +{ + int ret; + + if (WARN_ON_ONCE(!platform_ops || !platform_ops->power_down_finish)) + return -EUNATCH; + + ret = platform_ops->power_down_finish(cpu, cluster); + if (ret) + pr_warn("%s: cpu %u, cluster %u failed to power down (%d)\n", + __func__, cpu, cluster, ret); + + return ret; +} + void mcpm_cpu_suspend(u64 expected_residency) { phys_reset_t phys_reset; diff --git a/arch/arm/common/mcpm_head.S b/arch/arm/common/mcpm_head.S index 39c96df3477a..e02db4b81a66 100644 --- a/arch/arm/common/mcpm_head.S +++ b/arch/arm/common/mcpm_head.S @@ -15,6 +15,7 @@ #include <linux/linkage.h> #include <asm/mcpm.h> +#include <asm/assembler.h> #include "vlock.h" @@ -47,6 +48,7 @@ ENTRY(mcpm_entry_point) + ARM_BE8(setend be) THUMB( adr r12, BSYM(1f) ) THUMB( bx r12 ) THUMB( .thumb ) @@ -71,12 +73,19 @@ ENTRY(mcpm_entry_point) * position independent way. */ adr r5, 3f - ldmia r5, {r6, r7, r8, r11} + ldmia r5, {r0, r6, r7, r8, r11} + add r0, r5, r0 @ r0 = mcpm_entry_early_pokes add r6, r5, r6 @ r6 = mcpm_entry_vectors ldr r7, [r5, r7] @ r7 = mcpm_power_up_setup_phys add r8, r5, r8 @ r8 = mcpm_sync add r11, r5, r11 @ r11 = first_man_locks + @ Perform an early poke, if any + add r0, r0, r4, lsl #3 + ldmia r0, {r0, r1} + teq r0, #0 + strne r1, [r0] + mov r0, #MCPM_SYNC_CLUSTER_SIZE mla r8, r0, r10, r8 @ r8 = sync cluster base @@ -195,7 +204,8 @@ mcpm_entry_gated: .align 2 -3: .word mcpm_entry_vectors - . +3: .word mcpm_entry_early_pokes - . + .word mcpm_entry_vectors - 3b .word mcpm_power_up_setup_phys - 3b .word mcpm_sync - 3b .word first_man_locks - 3b @@ -214,6 +224,10 @@ first_man_locks: ENTRY(mcpm_entry_vectors) .space 4 * MAX_NR_CLUSTERS * MAX_CPUS_PER_CLUSTER + .type mcpm_entry_early_pokes, #object +ENTRY(mcpm_entry_early_pokes) + .space 8 * MAX_NR_CLUSTERS * MAX_CPUS_PER_CLUSTER + .type mcpm_power_up_setup_phys, #object ENTRY(mcpm_power_up_setup_phys) .space 4 @ set by mcpm_sync_init() diff --git a/arch/arm/common/mcpm_platsmp.c b/arch/arm/common/mcpm_platsmp.c index 1bc34c7567fd..177251a4dd9a 100644 --- a/arch/arm/common/mcpm_platsmp.c +++ b/arch/arm/common/mcpm_platsmp.c @@ -19,14 +19,23 @@ #include <asm/smp.h> #include <asm/smp_plat.h> +static void cpu_to_pcpu(unsigned int cpu, + unsigned int *pcpu, unsigned int *pcluster) +{ + unsigned int mpidr; + + mpidr = cpu_logical_map(cpu); + *pcpu = MPIDR_AFFINITY_LEVEL(mpidr, 0); + *pcluster = MPIDR_AFFINITY_LEVEL(mpidr, 1); +} + static int mcpm_boot_secondary(unsigned int cpu, struct task_struct *idle) { - unsigned int mpidr, pcpu, pcluster, ret; + unsigned int pcpu, pcluster, ret; extern void secondary_startup(void); - mpidr = cpu_logical_map(cpu); - pcpu = MPIDR_AFFINITY_LEVEL(mpidr, 0); - pcluster = MPIDR_AFFINITY_LEVEL(mpidr, 1); + cpu_to_pcpu(cpu, &pcpu, &pcluster); + pr_debug("%s: logical CPU %d is physical CPU %d cluster %d\n", __func__, cpu, pcpu, pcluster); @@ -47,6 +56,15 @@ static void mcpm_secondary_init(unsigned int cpu) #ifdef CONFIG_HOTPLUG_CPU +static int mcpm_cpu_kill(unsigned int cpu) +{ + unsigned int pcpu, pcluster; + + cpu_to_pcpu(cpu, &pcpu, &pcluster); + + return !mcpm_cpu_power_down_finish(pcpu, pcluster); +} + static int mcpm_cpu_disable(unsigned int cpu) { /* @@ -73,6 +91,7 @@ static struct smp_operations __initdata mcpm_smp_ops = { .smp_boot_secondary = mcpm_boot_secondary, .smp_secondary_init = mcpm_secondary_init, #ifdef CONFIG_HOTPLUG_CPU + .cpu_kill = mcpm_cpu_kill, .cpu_disable = mcpm_cpu_disable, .cpu_die = mcpm_cpu_die, #endif diff --git a/arch/arm/common/timer-sp.c b/arch/arm/common/timer-sp.c index e901d0f3e0bb..ce922d0ea7aa 100644 --- a/arch/arm/common/timer-sp.c +++ b/arch/arm/common/timer-sp.c @@ -175,7 +175,7 @@ static struct clock_event_device sp804_clockevent = { static struct irqaction sp804_timer_irq = { .name = "timer", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .flags = IRQF_TIMER | IRQF_IRQPOLL, .handler = sp804_timer_interrupt, .dev_id = &sp804_clockevent, }; diff --git a/arch/arm/common/via82c505.c b/arch/arm/common/via82c505.c deleted file mode 100644 index 6cb362e56d29..000000000000 --- a/arch/arm/common/via82c505.c +++ /dev/null @@ -1,83 +0,0 @@ -#include <linux/kernel.h> -#include <linux/pci.h> -#include <linux/interrupt.h> -#include <linux/mm.h> -#include <linux/init.h> -#include <linux/ioport.h> -#include <linux/io.h> - - -#include <asm/mach/pci.h> - -#define MAX_SLOTS 7 - -#define CONFIG_CMD(bus, devfn, where) (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3)) - -static int -via82c505_read_config(struct pci_bus *bus, unsigned int devfn, int where, - int size, u32 *value) -{ - outl(CONFIG_CMD(bus,devfn,where),0xCF8); - switch (size) { - case 1: - *value=inb(0xCFC + (where&3)); - break; - case 2: - *value=inw(0xCFC + (where&2)); - break; - case 4: - *value=inl(0xCFC); - break; - } - return PCIBIOS_SUCCESSFUL; -} - -static int -via82c505_write_config(struct pci_bus *bus, unsigned int devfn, int where, - int size, u32 value) -{ - outl(CONFIG_CMD(bus,devfn,where),0xCF8); - switch (size) { - case 1: - outb(value, 0xCFC + (where&3)); - break; - case 2: - outw(value, 0xCFC + (where&2)); - break; - case 4: - outl(value, 0xCFC); - break; - } - return PCIBIOS_SUCCESSFUL; -} - -struct pci_ops via82c505_ops = { - .read = via82c505_read_config, - .write = via82c505_write_config, -}; - -void __init via82c505_preinit(void) -{ - printk(KERN_DEBUG "PCI: VIA 82c505\n"); - if (!request_region(0xA8,2,"via config")) { - printk(KERN_WARNING"VIA 82c505: Unable to request region 0xA8\n"); - return; - } - if (!request_region(0xCF8,8,"pci config")) { - printk(KERN_WARNING"VIA 82c505: Unable to request region 0xCF8\n"); - release_region(0xA8, 2); - return; - } - - /* Enable compatible Mode */ - outb(0x96,0xA8); - outb(0x18,0xA9); - outb(0x93,0xA8); - outb(0xd0,0xA9); - -} - -int __init via82c505_setup(int nr, struct pci_sys_data *sys) -{ - return (nr == 0); -} diff --git a/arch/arm/configs/bcm_defconfig b/arch/arm/configs/bcm_defconfig index 6e4931097dd4..287ac1d7aac7 100644 --- a/arch/arm/configs/bcm_defconfig +++ b/arch/arm/configs/bcm_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set # CONFIG_SWAP is not set CONFIG_SYSVIPC=y @@ -25,10 +24,9 @@ CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_BLK_DEV_BSG is not set CONFIG_PARTITION_ADVANCED=y -CONFIG_EFI_PARTITION=y CONFIG_ARCH_BCM=y +CONFIG_ARCH_BCM_MOBILE=y CONFIG_ARM_THUMBEE=y -CONFIG_ARM_ERRATA_743622=y CONFIG_PREEMPT=y CONFIG_AEABI=y # CONFIG_OABI_COMPAT is not set @@ -50,7 +48,6 @@ CONFIG_UNIX_DIAG=y CONFIG_NET_KEY=y CONFIG_INET=y CONFIG_IP_MULTICAST=y -CONFIG_ARPD=y CONFIG_SYN_COOKIES=y CONFIG_TCP_MD5SIG=y CONFIG_IPV6=y @@ -95,7 +92,6 @@ CONFIG_MMC_UNSAFE_RESUME=y CONFIG_MMC_BLOCK_MINORS=32 CONFIG_MMC_TEST=y CONFIG_MMC_SDHCI=y -CONFIG_MMC_SDHCI_PLTFM=y CONFIG_MMC_SDHCI_BCM_KONA=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y @@ -117,12 +113,12 @@ CONFIG_CONFIGFS_FS=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y CONFIG_PRINTK_TIME=y -CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_INFO=y CONFIG_DEBUG_FS=y +CONFIG_MAGIC_SYSRQ=y CONFIG_DETECT_HUNG_TASK=y CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=110 CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y -CONFIG_DEBUG_INFO=y # CONFIG_FTRACE is not set CONFIG_CRC_CCITT=y CONFIG_CRC_T10DIF=y diff --git a/arch/arm/configs/bockw_defconfig b/arch/arm/configs/bockw_defconfig index e7e94948d194..b38cd107f82d 100644 --- a/arch/arm/configs/bockw_defconfig +++ b/arch/arm/configs/bockw_defconfig @@ -91,6 +91,10 @@ CONFIG_VIDEO_RCAR_VIN=y CONFIG_VIDEO_ML86V7667=y CONFIG_SPI=y CONFIG_SPI_SH_HSPI=y +CONFIG_SOUND=y +CONFIG_SND=y +CONFIG_SND_SOC=y +CONFIG_SND_SOC_RCAR=y CONFIG_USB=y CONFIG_USB_ANNOUNCE_NEW_DEVICES=y CONFIG_USB_EHCI_HCD=y diff --git a/arch/arm/configs/ep93xx_defconfig b/arch/arm/configs/ep93xx_defconfig index 806005a4c4c1..6ac5ea73bd0a 100644 --- a/arch/arm/configs/ep93xx_defconfig +++ b/arch/arm/configs/ep93xx_defconfig @@ -1,15 +1,14 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -CONFIG_SYSFS_DEPRECATED_V2=y CONFIG_EXPERT=y CONFIG_SLAB=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y # CONFIG_BLK_DEV_BSG is not set +CONFIG_PARTITION_ADVANCED=y # CONFIG_IOSCHED_CFQ is not set CONFIG_ARCH_EP93XX=y CONFIG_CRUNCH=y @@ -47,11 +46,8 @@ CONFIG_IPV6=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_MTD=y -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_REDBOOT_PARTS=y CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_ADV_OPTIONS=y @@ -67,15 +63,14 @@ CONFIG_SCSI=y # CONFIG_SCSI_PROC_FS is not set CONFIG_BLK_DEV_SD=y CONFIG_NETDEVICES=y -CONFIG_NET_ETHERNET=y CONFIG_EP93XX_ETH=y CONFIG_USB_RTL8150=y # CONFIG_INPUT is not set # CONFIG_SERIO is not set # CONFIG_VT is not set +# CONFIG_LEGACY_PTYS is not set CONFIG_SERIAL_AMBA_PL010=y CONFIG_SERIAL_AMBA_PL010_CONSOLE=y -# CONFIG_LEGACY_PTYS is not set # CONFIG_HW_RANDOM is not set CONFIG_I2C=y CONFIG_I2C_CHARDEV=y @@ -86,9 +81,9 @@ CONFIG_WATCHDOG=y CONFIG_EP93XX_WATCHDOG=y CONFIG_USB=y CONFIG_USB_DEBUG=y -CONFIG_USB_DEVICEFS=y CONFIG_USB_DYNAMIC_MINORS=y CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_HCD_PLATFORM=y CONFIG_USB_STORAGE=y CONFIG_USB_SERIAL=y CONFIG_USB_SERIAL_CONSOLE=y @@ -100,24 +95,18 @@ CONFIG_RTC_DRV_EP93XX=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y # CONFIG_EXT3_FS_XATTR is not set -CONFIG_INOTIFY=y CONFIG_VFAT_FS=y CONFIG_TMPFS=y CONFIG_JFFS2_FS=y CONFIG_NFS_FS=y -CONFIG_NFS_V3=y CONFIG_ROOT_NFS=y -CONFIG_PARTITION_ADVANCED=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y CONFIG_MAGIC_SYSRQ=y -CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_SLAB=y CONFIG_DEBUG_SPINLOCK=y CONFIG_DEBUG_MUTEXES=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_DEBUG_USER=y -CONFIG_DEBUG_ERRORS=y CONFIG_DEBUG_LL=y # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_LIBCRC32C=y diff --git a/arch/arm/configs/h3600_defconfig b/arch/arm/configs/h3600_defconfig index 317960f12488..0142ec37e0be 100644 --- a/arch/arm/configs/h3600_defconfig +++ b/arch/arm/configs/h3600_defconfig @@ -1,5 +1,6 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y +CONFIG_NO_HZ_IDLE=y +CONFIG_HIGH_RES_TIMERS=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_BLK_DEV_INITRD=y CONFIG_MODULES=y @@ -11,11 +12,11 @@ CONFIG_ARCH_SA1100=y CONFIG_SA1100_H3600=y CONFIG_PCCARD=y CONFIG_PCMCIA_SA1100=y +CONFIG_PREEMPT=y CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 # CONFIG_CPU_FREQ_STAT is not set CONFIG_FPE_NWFPE=y -CONFIG_PM=y CONFIG_NET=y CONFIG_UNIX=y CONFIG_INET=y @@ -24,13 +25,10 @@ CONFIG_IRDA=m CONFIG_IRLAN=m CONFIG_IRNET=m CONFIG_IRCOMM=m -CONFIG_SA1100_FIR=m # CONFIG_WIRELESS is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_REDBOOT_PARTS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_ADV_OPTIONS=y @@ -41,19 +39,15 @@ CONFIG_MTD_SA1100=y CONFIG_BLK_DEV_LOOP=m CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 -# CONFIG_MISC_DEVICES is not set CONFIG_IDE=y CONFIG_BLK_DEV_IDECS=y CONFIG_NETDEVICES=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set -# CONFIG_WLAN is not set -CONFIG_NET_PCMCIA=y CONFIG_PCMCIA_PCNET=y CONFIG_PPP=m -CONFIG_PPP_ASYNC=m -CONFIG_PPP_DEFLATE=m CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_ASYNC=m +# CONFIG_WLAN is not set # CONFIG_KEYBOARD_ATKBD is not set CONFIG_KEYBOARD_GPIO=y # CONFIG_INPUT_MOUSE is not set @@ -64,8 +58,6 @@ CONFIG_SERIAL_SA1100_CONSOLE=y # CONFIG_HWMON is not set CONFIG_FB=y CONFIG_FB_SA1100=y -# CONFIG_VGA_CONSOLE is not set -# CONFIG_HID_SUPPORT is not set # CONFIG_USB_SUPPORT is not set CONFIG_EXT2_FS=y CONFIG_MSDOS_FS=m @@ -74,6 +66,4 @@ CONFIG_JFFS2_FS=y CONFIG_CRAMFS=m CONFIG_NFS_FS=y CONFIG_NFSD=m -CONFIG_SMB_FS=m CONFIG_NLS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig index 5d488c24b132..8d0c5a018ed7 100644 --- a/arch/arm/configs/imx_v6_v7_defconfig +++ b/arch/arm/configs/imx_v6_v7_defconfig @@ -132,7 +132,6 @@ CONFIG_TOUCHSCREEN_MC13783=y CONFIG_INPUT_MISC=y CONFIG_INPUT_MMA8450=y CONFIG_SERIO_SERPORT=m -CONFIG_VT_HW_CONSOLE_BINDING=y # CONFIG_LEGACY_PTYS is not set # CONFIG_DEVKMEM is not set CONFIG_SERIAL_IMX=y @@ -188,22 +187,33 @@ CONFIG_SND_SOC_PHYCORE_AC97=y CONFIG_SND_SOC_EUKREA_TLV320=y CONFIG_SND_SOC_IMX_WM8962=y CONFIG_SND_SOC_IMX_SGTL5000=y +CONFIG_SND_SOC_IMX_SPDIF=y CONFIG_SND_SOC_IMX_MC13783=y CONFIG_USB=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_MXC=y CONFIG_USB_STORAGE=y CONFIG_USB_CHIPIDEA=y +CONFIG_USB_CHIPIDEA_UDC=y CONFIG_USB_CHIPIDEA_HOST=y -CONFIG_USB_PHY=y CONFIG_NOP_USB_XCEIV=y CONFIG_USB_MXS_PHY=y +CONFIG_USB_GADGET=y +CONFIG_USB_ETH=m +CONFIG_USB_MASS_STORAGE=m CONFIG_MMC=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_PLTFM=y CONFIG_MMC_SDHCI_ESDHC_IMX=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_ONESHOT=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_BACKLIGHT=y +CONFIG_LEDS_TRIGGER_GPIO=y CONFIG_RTC_CLASS=y CONFIG_RTC_INTF_DEV_UIE_EMUL=y CONFIG_RTC_DRV_MC13XXX=y @@ -246,7 +256,6 @@ CONFIG_UDF_FS=m CONFIG_MSDOS_FS=m CONFIG_VFAT_FS=y CONFIG_TMPFS=y -CONFIG_CONFIGFS_FS=m CONFIG_JFFS2_FS=y CONFIG_UBIFS_FS=y CONFIG_NFS_FS=y @@ -261,6 +270,7 @@ CONFIG_NLS_ISO8859_15=m CONFIG_NLS_UTF8=y CONFIG_MAGIC_SYSRQ=y # CONFIG_SCHED_DEBUG is not set +CONFIG_PROVE_LOCKING=y # CONFIG_DEBUG_BUGVERBOSE is not set # CONFIG_FTRACE is not set # CONFIG_ARM_UNWIND is not set diff --git a/arch/arm/configs/integrator_defconfig b/arch/arm/configs/integrator_defconfig index a8314c3ee84d..5bae19557591 100644 --- a/arch/arm/configs/integrator_defconfig +++ b/arch/arm/configs/integrator_defconfig @@ -1,15 +1,17 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y -CONFIG_TINY_RCU=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_BLK_DEV_INITRD=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y +CONFIG_PARTITION_ADVANCED=y CONFIG_ARCH_INTEGRATOR=y CONFIG_ARCH_INTEGRATOR_AP=y CONFIG_ARCH_INTEGRATOR_CP=y +CONFIG_INTEGRATOR_IMPD1=y CONFIG_CPU_ARM720T=y CONFIG_CPU_ARM920T=y CONFIG_CPU_ARM922T=y @@ -18,12 +20,9 @@ CONFIG_CPU_ARM1020=y CONFIG_CPU_ARM1022=y CONFIG_CPU_ARM1026=y CONFIG_PCI=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y CONFIG_PREEMPT=y CONFIG_AEABI=y -CONFIG_LEDS=y -CONFIG_LEDS_CPU=y +# CONFIG_ATAGS is not set CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 CONFIG_CMDLINE="console=ttyAM0,38400n8 root=/dev/nfs ip=bootp" @@ -44,24 +43,20 @@ CONFIG_IP_PNP_BOOTP=y CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_AFS_PARTS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_ADV_OPTIONS=y CONFIG_MTD_CFI_INTELEXT=y CONFIG_MTD_PHYSMAP=y +CONFIG_PROC_DEVICETREE=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_NETDEVICES=y -CONFIG_NET_ETHERNET=y -CONFIG_NET_PCI=y CONFIG_E100=y CONFIG_SMC91X=y # CONFIG_KEYBOARD_ATKBD is not set # CONFIG_SERIO_SERPORT is not set -CONFIG_SERIAL_AMBA_PL010=y -CONFIG_SERIAL_AMBA_PL010_CONSOLE=y CONFIG_FB=y CONFIG_FB_MODE_HELPERS=y CONFIG_FB_ARMCLCD=y @@ -71,19 +66,23 @@ CONFIG_FB_MATROX_MYSTIQUE=y # CONFIG_VGA_CONSOLE is not set CONFIG_MMC=y CONFIG_MMC_ARMMMCI=y +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_CPU=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_PL030=y +CONFIG_COMMON_CLK_DEBUG=y CONFIG_EXT2_FS=y CONFIG_VFAT_FS=y CONFIG_TMPFS=y CONFIG_JFFS2_FS=y CONFIG_CRAMFS=y CONFIG_NFS_FS=y -CONFIG_NFS_V3=y CONFIG_ROOT_NFS=y CONFIG_NFSD=y CONFIG_NFSD_V3=y -CONFIG_PARTITION_ADVANCED=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y CONFIG_MAGIC_SYSRQ=y diff --git a/arch/arm/configs/keystone_defconfig b/arch/arm/configs/keystone_defconfig index 1f36b823905f..9943e5da74f1 100644 --- a/arch/arm/configs/keystone_defconfig +++ b/arch/arm/configs/keystone_defconfig @@ -123,7 +123,9 @@ CONFIG_SERIAL_OF_PLATFORM=y CONFIG_I2C=y # CONFIG_I2C_COMPAT is not set CONFIG_I2C_CHARDEV=y +CONFIG_I2C_DAVINCI=y CONFIG_SPI=y +CONFIG_SPI_DAVINCI=y CONFIG_SPI_SPIDEV=y # CONFIG_HWMON is not set CONFIG_WATCHDOG=y diff --git a/arch/arm/configs/koelsch_defconfig b/arch/arm/configs/koelsch_defconfig new file mode 100644 index 000000000000..825c16dee8a0 --- /dev/null +++ b/arch/arm/configs/koelsch_defconfig @@ -0,0 +1,54 @@ +CONFIG_SYSVIPC=y +CONFIG_NO_HZ=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=16 +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_EMBEDDED=y +CONFIG_PERF_EVENTS=y +CONFIG_SLAB=y +# CONFIG_BLOCK is not set +CONFIG_ARCH_SHMOBILE=y +CONFIG_ARCH_R8A7791=y +CONFIG_MACH_KOELSCH=y +# CONFIG_SWP_EMULATE is not set +CONFIG_CPU_BPREDICT_DISABLE=y +CONFIG_PL310_ERRATA_588369=y +CONFIG_ARM_ERRATA_754322=y +CONFIG_SMP=y +CONFIG_SCHED_MC=y +CONFIG_NR_CPUS=8 +CONFIG_AEABI=y +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_ARM_APPENDED_DTB=y +CONFIG_KEXEC=y +CONFIG_AUTO_ZRELADDR=y +CONFIG_VFP=y +CONFIG_NEON=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_PM_RUNTIME=y +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_LEGACY_PTYS is not set +CONFIG_SERIAL_SH_SCI=y +CONFIG_SERIAL_SH_SCI_NR_UARTS=20 +CONFIG_SERIAL_SH_SCI_CONSOLE=y +# CONFIG_HWMON is not set +CONFIG_THERMAL=y +CONFIG_RCAR_THERMAL=y +# CONFIG_HID is not set +# CONFIG_USB_SUPPORT is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +# CONFIG_IOMMU_SUPPORT is not set +# CONFIG_DNOTIFY is not set +# CONFIG_INOTIFY_USER is not set +CONFIG_TMPFS=y +CONFIG_CONFIGFS_FS=y +# CONFIG_MISC_FILESYSTEMS is not set +# CONFIG_ENABLE_WARN_DEPRECATED is not set +# CONFIG_ENABLE_MUST_CHECK is not set +# CONFIG_ARM_UNWIND is not set diff --git a/arch/arm/configs/lager_defconfig b/arch/arm/configs/lager_defconfig index e777ef22b801..35bff5e0d57a 100644 --- a/arch/arm/configs/lager_defconfig +++ b/arch/arm/configs/lager_defconfig @@ -89,6 +89,8 @@ CONFIG_THERMAL=y CONFIG_RCAR_THERMAL=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_DRM=y +CONFIG_DRM_RCAR_DU=y # CONFIG_USB_SUPPORT is not set CONFIG_MMC=y CONFIG_MMC_SDHI=y diff --git a/arch/arm/configs/marzen_defconfig b/arch/arm/configs/marzen_defconfig index 000e9205b2b9..5cc6360340b1 100644 --- a/arch/arm/configs/marzen_defconfig +++ b/arch/arm/configs/marzen_defconfig @@ -92,6 +92,8 @@ CONFIG_SOC_CAMERA=y CONFIG_VIDEO_RCAR_VIN=y # CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set CONFIG_VIDEO_ADV7180=y +CONFIG_DRM=y +CONFIG_DRM_RCAR_DU=y CONFIG_USB=y CONFIG_USB_RCAR_PHY=y CONFIG_MMC=y diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig index 119fc378fc52..4a5903e04827 100644 --- a/arch/arm/configs/multi_v7_defconfig +++ b/arch/arm/configs/multi_v7_defconfig @@ -6,6 +6,7 @@ CONFIG_ARCH_MVEBU=y CONFIG_MACH_ARMADA_370=y CONFIG_MACH_ARMADA_XP=y CONFIG_ARCH_BCM=y +CONFIG_ARCH_BCM_MOBILE=y CONFIG_GPIO_PCA953X=y CONFIG_ARCH_HIGHBANK=y CONFIG_ARCH_KEYSTONE=y diff --git a/arch/arm/configs/mxs_defconfig b/arch/arm/configs/mxs_defconfig index 4555c025629a..6150108e15de 100644 --- a/arch/arm/configs/mxs_defconfig +++ b/arch/arm/configs/mxs_defconfig @@ -76,7 +76,6 @@ CONFIG_INPUT_EVDEV=y CONFIG_INPUT_TOUCHSCREEN=y CONFIG_TOUCHSCREEN_TSC2007=m # CONFIG_SERIO is not set -CONFIG_VT_HW_CONSOLE_BINDING=y CONFIG_DEVPTS_MULTIPLE_INSTANCES=y # CONFIG_LEGACY_PTYS is not set # CONFIG_DEVKMEM is not set @@ -91,7 +90,6 @@ CONFIG_I2C_MXS=y CONFIG_SPI=y CONFIG_SPI_GPIO=m CONFIG_SPI_MXS=y -CONFIG_DEBUG_GPIO=y CONFIG_GPIO_SYSFS=y # CONFIG_HWMON is not set CONFIG_WATCHDOG=y @@ -115,9 +113,12 @@ CONFIG_USB=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_STORAGE=y CONFIG_USB_CHIPIDEA=y +CONFIG_USB_CHIPIDEA_UDC=y CONFIG_USB_CHIPIDEA_HOST=y -CONFIG_USB_PHY=y CONFIG_USB_MXS_PHY=y +CONFIG_USB_GADGET=y +CONFIG_USB_ETH=m +CONFIG_USB_MASS_STORAGE=m CONFIG_MMC=y CONFIG_MMC_UNSAFE_RESUME=y CONFIG_MMC_MXS=y diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig index 254cf0539439..98a50c309b90 100644 --- a/arch/arm/configs/omap2plus_defconfig +++ b/arch/arm/configs/omap2plus_defconfig @@ -1,14 +1,13 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=16 CONFIG_BLK_DEV_INITRD=y CONFIG_EXPERT=y -# CONFIG_SYSCTL_SYSCALL is not set -CONFIG_KALLSYMS_EXTRA_PASS=y CONFIG_SLAB=y CONFIG_PROFILING=y CONFIG_OPROFILE=y @@ -20,22 +19,21 @@ CONFIG_MODULE_FORCE_UNLOAD=y CONFIG_MODVERSIONS=y CONFIG_MODULE_SRCVERSION_ALL=y # CONFIG_BLK_DEV_BSG is not set +CONFIG_PARTITION_ADVANCED=y CONFIG_ARCH_MULTI_V6=y -CONFIG_ARCH_OMAP2PLUS=y +CONFIG_OMAP_RESET_CLOCKS=y +CONFIG_OMAP_MUX_DEBUG=y CONFIG_ARCH_OMAP2=y CONFIG_ARCH_OMAP3=y CONFIG_ARCH_OMAP4=y +CONFIG_SOC_OMAP5=y CONFIG_SOC_AM33XX=y -CONFIG_OMAP_RESET_CLOCKS=y -CONFIG_OMAP_MUX_DEBUG=y -CONFIG_ARCH_VEXPRESS_CA9X4=y +CONFIG_SOC_DRA7XX=y CONFIG_ARM_THUMBEE=y CONFIG_ARM_ERRATA_411920=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y CONFIG_SMP=y CONFIG_NR_CPUS=2 -CONFIG_LEDS=y +CONFIG_CMA=y CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 CONFIG_ARM_APPENDED_DTB=y @@ -61,8 +59,6 @@ CONFIG_IP_PNP_RARP=y # CONFIG_IPV6 is not set CONFIG_NETFILTER=y CONFIG_CAN=m -CONFIG_CAN_RAW=m -CONFIG_CAN_BCM=m CONFIG_CAN_C_CAN=m CONFIG_CAN_C_CAN_PLATFORM=m CONFIG_BT=m @@ -77,14 +73,13 @@ CONFIG_MAC80211=m CONFIG_MAC80211_RC_PID=y CONFIG_MAC80211_RC_DEFAULT_PID=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_CMA=y -CONFIG_DMA_CMA=y -CONFIG_CONNECTOR=y CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y +CONFIG_DMA_CMA=y +CONFIG_OMAP_OCP2SCP=y +CONFIG_CONNECTOR=y CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_OOPS=y CONFIG_MTD_CFI=y @@ -98,32 +93,40 @@ CONFIG_MTD_UBI=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=16384 -CONFIG_SENSORS_LIS3LV02D=m CONFIG_SENSORS_TSL2550=m -CONFIG_SENSORS_LIS3_I2C=m CONFIG_BMP085_I2C=m +CONFIG_SENSORS_LIS3_I2C=m CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_SCSI_MULTI_LUN=y CONFIG_SCSI_SCAN_ASYNC=y CONFIG_MD=y CONFIG_NETDEVICES=y -CONFIG_SMSC_PHY=y -CONFIG_NET_ETHERNET=y -CONFIG_SMC91X=y -CONFIG_SMSC911X=y CONFIG_KS8851=y CONFIG_KS8851_MLL=y -CONFIG_LIBERTAS=m -CONFIG_LIBERTAS_USB=m -CONFIG_LIBERTAS_SDIO=m -CONFIG_LIBERTAS_DEBUG=y +CONFIG_SMC91X=y +CONFIG_SMSC911X=y +CONFIG_TI_CPSW=y +CONFIG_AT803X_PHY=y +CONFIG_SMSC_PHY=y CONFIG_USB_USBNET=y CONFIG_USB_NET_SMSC95XX=y CONFIG_USB_ALI_M5632=y CONFIG_USB_AN2720=y CONFIG_USB_EPSON2888=y CONFIG_USB_KC2190=y +CONFIG_LIBERTAS=m +CONFIG_LIBERTAS_USB=m +CONFIG_LIBERTAS_SDIO=m +CONFIG_LIBERTAS_DEBUG=y +CONFIG_WL_TI=y +CONFIG_WL12XX=m +CONFIG_WL18XX=m +CONFIG_WLCORE_SPI=m +CONFIG_WLCORE_SDIO=m +CONFIG_MWIFIEX=m +CONFIG_MWIFIEX_SDIO=m +CONFIG_MWIFIEX_USB=m CONFIG_INPUT_JOYDEV=y CONFIG_INPUT_EVDEV=y CONFIG_KEYBOARD_GPIO=y @@ -133,7 +136,6 @@ CONFIG_INPUT_TOUCHSCREEN=y CONFIG_TOUCHSCREEN_ADS7846=y CONFIG_INPUT_MISC=y CONFIG_INPUT_TWL4030_PWRBUTTON=y -CONFIG_VT_HW_CONSOLE_BINDING=y # CONFIG_LEGACY_PTYS is not set CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y @@ -143,8 +145,7 @@ CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y CONFIG_SERIAL_8250_DETECT_IRQ=y CONFIG_SERIAL_8250_RSA=y -CONFIG_SERIAL_AMBA_PL011=y -CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +CONFIG_SERIAL_OF_PLATFORM=y CONFIG_SERIAL_OMAP=y CONFIG_SERIAL_OMAP_CONSOLE=y CONFIG_HW_RANDOM=y @@ -158,31 +159,31 @@ CONFIG_GPIO_TWL4030=y CONFIG_W1=y CONFIG_POWER_SUPPLY=y CONFIG_SENSORS_LM75=m -CONFIG_WATCHDOG=y CONFIG_THERMAL=y -CONFIG_THERMAL_HWMON=y -CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y CONFIG_THERMAL_GOV_FAIR_SHARE=y -CONFIG_THERMAL_GOV_STEP_WISE=y CONFIG_THERMAL_GOV_USER_SPACE=y -CONFIG_CPU_THERMAL=y +CONFIG_TI_SOC_THERMAL=y +CONFIG_OMAP4_THERMAL=y +CONFIG_OMAP5_THERMAL=y +CONFIG_DRA752_THERMAL=y +CONFIG_WATCHDOG=y CONFIG_OMAP_WATCHDOG=y CONFIG_TWL4030_WATCHDOG=y +CONFIG_MFD_PALMAS=y CONFIG_MFD_TPS65217=y CONFIG_MFD_TPS65910=y CONFIG_TWL6040_CORE=y -CONFIG_REGULATOR_TWL4030=y +CONFIG_REGULATOR_PALMAS=y CONFIG_REGULATOR_TPS65023=y CONFIG_REGULATOR_TPS6507X=y CONFIG_REGULATOR_TPS65217=y CONFIG_REGULATOR_TPS65910=y +CONFIG_REGULATOR_TWL4030=y CONFIG_FB=y CONFIG_FIRMWARE_EDID=y CONFIG_FB_MODE_HELPERS=y CONFIG_FB_TILEBLITTING=y -CONFIG_FB_OMAP_LCD_VGA=y CONFIG_OMAP2_DSS=m -CONFIG_OMAP2_DSS_RFBI=y CONFIG_OMAP2_DSS_SDI=y CONFIG_OMAP2_DSS_DSI=y CONFIG_FB_OMAP2=m @@ -194,12 +195,8 @@ CONFIG_DISPLAY_PANEL_DPI=m CONFIG_BACKLIGHT_LCD_SUPPORT=y CONFIG_LCD_CLASS_DEVICE=y CONFIG_LCD_PLATFORM=y -CONFIG_DISPLAY_SUPPORT=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y -CONFIG_FONTS=y -CONFIG_FONT_8x8=y -CONFIG_FONT_8x16=y CONFIG_LOGO=y CONFIG_SOUND=m CONFIG_SND=m @@ -216,14 +213,14 @@ CONFIG_SND_OMAP_SOC_OMAP3_PANDORA=m CONFIG_USB=y CONFIG_USB_DEBUG=y CONFIG_USB_ANNOUNCE_NEW_DEVICES=y -CONFIG_USB_DEVICEFS=y CONFIG_USB_MON=y CONFIG_USB_WDM=y CONFIG_USB_STORAGE=y -CONFIG_USB_LIBUSUAL=y +CONFIG_USB_DWC3=m CONFIG_USB_TEST=y -CONFIG_USB_PHY=y CONFIG_NOP_USB_XCEIV=y +CONFIG_OMAP_USB2=y +CONFIG_OMAP_USB3=y CONFIG_USB_GADGET=y CONFIG_USB_GADGET_DEBUG=y CONFIG_USB_GADGET_DEBUG_FILES=y @@ -232,7 +229,6 @@ CONFIG_USB_ZERO=m CONFIG_MMC=y CONFIG_MMC_UNSAFE_RESUME=y CONFIG_SDIO_UART=y -CONFIG_MMC_ARMMMCI=y CONFIG_MMC_OMAP=y CONFIG_MMC_OMAP_HS=y CONFIG_NEW_LEDS=y @@ -252,11 +248,8 @@ CONFIG_RTC_DRV_OMAP=y CONFIG_DMADEVICES=y CONFIG_TI_EDMA=y CONFIG_DMA_OMAP=y -CONFIG_TI_SOC_THERMAL=y -CONFIG_TI_THERMAL=y -CONFIG_OMAP4_THERMAL=y -CONFIG_OMAP5_THERMAL=y -CONFIG_DRA752_THERMAL=y +CONFIG_EXTCON=y +CONFIG_EXTCON_PALMAS=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y # CONFIG_EXT3_FS_XATTR is not set @@ -275,23 +268,18 @@ CONFIG_JFFS2_RUBIN=y CONFIG_UBIFS_FS=y CONFIG_CRAMFS=y CONFIG_NFS_FS=y -CONFIG_NFS_V3=y CONFIG_NFS_V3_ACL=y CONFIG_NFS_V4=y CONFIG_ROOT_NFS=y -CONFIG_PARTITION_ADVANCED=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y CONFIG_PRINTK_TIME=y +CONFIG_DEBUG_INFO=y CONFIG_MAGIC_SYSRQ=y -CONFIG_DEBUG_KERNEL=y CONFIG_SCHEDSTATS=y CONFIG_TIMER_STATS=y CONFIG_PROVE_LOCKING=y -CONFIG_DEBUG_SPINLOCK_SLEEP=y # CONFIG_DEBUG_BUGVERBOSE is not set -CONFIG_DEBUG_INFO=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_SECURITY=y CONFIG_CRYPTO_MICHAEL_MIC=y # CONFIG_CRYPTO_ANSI_CPRNG is not set @@ -300,9 +288,6 @@ CONFIG_CRC_T10DIF=y CONFIG_CRC_ITU_T=y CONFIG_CRC7=y CONFIG_LIBCRC32C=y -CONFIG_SOC_OMAP5=y -CONFIG_TI_DAVINCI_MDIO=y -CONFIG_TI_DAVINCI_CPDMA=y -CONFIG_TI_CPSW=y -CONFIG_AT803X_PHY=y -CONFIG_SOC_DRA7XX=y +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y diff --git a/arch/arm/configs/prima2_defconfig b/arch/arm/configs/prima2_defconfig index 002a1ceadceb..23591dba47a0 100644 --- a/arch/arm/configs/prima2_defconfig +++ b/arch/arm/configs/prima2_defconfig @@ -39,6 +39,7 @@ CONFIG_SPI=y CONFIG_SPI_SIRF=y CONFIG_SPI_SPIDEV=y # CONFIG_HWMON is not set +CONFIG_WATCHDOG=y CONFIG_USB_GADGET=y CONFIG_USB_MASS_STORAGE=m CONFIG_MMC=y diff --git a/arch/arm/configs/shark_defconfig b/arch/arm/configs/shark_defconfig deleted file mode 100644 index e319b2c56f11..000000000000 --- a/arch/arm/configs/shark_defconfig +++ /dev/null @@ -1,80 +0,0 @@ -CONFIG_EXPERIMENTAL=y -# CONFIG_LOCALVERSION_AUTO is not set -CONFIG_SYSVIPC=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_SYSFS_DEPRECATED_V2=y -CONFIG_SLAB=y -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y -# CONFIG_BLK_DEV_BSG is not set -CONFIG_ARCH_SHARK=y -CONFIG_LEDS=y -CONFIG_LEDS_TIMER=y -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_FPE_NWFPE=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_INET=y -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set -# CONFIG_INET_DIAG is not set -# CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -# CONFIG_STANDALONE is not set -# CONFIG_FIRMWARE_IN_KERNEL is not set -CONFIG_PARPORT=m -CONFIG_PARPORT_PC=m -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_RAM=y -CONFIG_IDE=y -CONFIG_BLK_DEV_IDECD=m -CONFIG_SCSI=m -CONFIG_BLK_DEV_SD=m -CONFIG_CHR_DEV_ST=m -CONFIG_BLK_DEV_SR=m -CONFIG_CHR_DEV_SG=m -CONFIG_NETDEVICES=y -CONFIG_NET_ETHERNET=y -CONFIG_NET_PCI=y -CONFIG_CS89x0=y -# CONFIG_SERIO_SERPORT is not set -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_PRINTER=m -# CONFIG_HWMON is not set -CONFIG_FB=y -CONFIG_FB_CYBER2000=y -# CONFIG_VGA_CONSOLE is not set -CONFIG_FRAMEBUFFER_CONSOLE=y -CONFIG_LOGO=y -# CONFIG_LOGO_LINUX_MONO is not set -# CONFIG_LOGO_LINUX_VGA16 is not set -CONFIG_SOUND=m -CONFIG_SOUND_PRIME=m -CONFIG_SOUND_OSS=m -CONFIG_SOUND_SB=m -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_CMOS=y -CONFIG_EXT2_FS=y -CONFIG_EXT3_FS=y -CONFIG_ISO9660_FS=m -CONFIG_JOLIET=y -CONFIG_MSDOS_FS=m -CONFIG_VFAT_FS=m -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -CONFIG_NFSD=m -CONFIG_PARTITION_ADVANCED=y -CONFIG_NLS_CODEPAGE_437=m -CONFIG_NLS_CODEPAGE_850=m -CONFIG_NLS_ISO8859_1=m -# CONFIG_ENABLE_MUST_CHECK is not set -CONFIG_DEBUG_KERNEL=y -# CONFIG_SCHED_DEBUG is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_DEBUG_USER=y diff --git a/arch/arm/configs/sunxi_defconfig b/arch/arm/configs/sunxi_defconfig new file mode 100644 index 000000000000..d57a85badb5e --- /dev/null +++ b/arch/arm/configs/sunxi_defconfig @@ -0,0 +1,61 @@ +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_ARCH_SUNXI=y +CONFIG_SMP=y +CONFIG_AEABI=y +CONFIG_HIGHMEM=y +CONFIG_HIGHPTE=y +CONFIG_VFP=y +CONFIG_NEON=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +# CONFIG_INET_DIAG is not set +# CONFIG_IPV6 is not set +# CONFIG_WIRELESS is not set +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_NETDEVICES=y +CONFIG_SUN4I_EMAC=y +# CONFIG_NET_CADENCE is not set +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_NET_VENDOR_CIRRUS is not set +# CONFIG_NET_VENDOR_FARADAY is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SMSC is not set +# CONFIG_NET_VENDOR_STMICRO is not set +# CONFIG_NET_VENDOR_WIZNET is not set +# CONFIG_WLAN is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=8 +CONFIG_SERIAL_8250_RUNTIME_UARTS=8 +CONFIG_SERIAL_8250_DW=y +CONFIG_I2C=y +# CONFIG_I2C_COMPAT is not set +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MV64XXX=y +CONFIG_GPIO_SYSFS=y +# CONFIG_HWMON is not set +CONFIG_WATCHDOG=y +CONFIG_SUNXI_WATCHDOG=y +# CONFIG_USB_SUPPORT is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y +CONFIG_COMMON_CLK_DEBUG=y +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_NLS=y diff --git a/arch/arm/configs/tegra_defconfig b/arch/arm/configs/tegra_defconfig index ea042e80e54d..4934295bb4f0 100644 --- a/arch/arm/configs/tegra_defconfig +++ b/arch/arm/configs/tegra_defconfig @@ -27,6 +27,7 @@ CONFIG_ARCH_TEGRA=y CONFIG_ARCH_TEGRA_2x_SOC=y CONFIG_ARCH_TEGRA_3x_SOC=y CONFIG_ARCH_TEGRA_114_SOC=y +CONFIG_ARCH_TEGRA_124_SOC=y CONFIG_TEGRA_EMC_SCALING_ENABLE=y CONFIG_PCI=y CONFIG_PCI_MSI=y @@ -41,9 +42,11 @@ CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 CONFIG_KEXEC=y CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_STAT_DETAILS=y CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y CONFIG_CPU_IDLE=y CONFIG_VFP=y +CONFIG_NEON=y CONFIG_PM_RUNTIME=y CONFIG_NET=y CONFIG_PACKET=y @@ -129,6 +132,7 @@ CONFIG_SPI=y CONFIG_SPI_TEGRA114=y CONFIG_SPI_TEGRA20_SFLASH=y CONFIG_SPI_TEGRA20_SLINK=y +CONFIG_PINCTRL_PALMAS=y CONFIG_GPIO_PCA953X_IRQ=y CONFIG_GPIO_PALMAS=y CONFIG_GPIO_TPS6586X=y @@ -223,6 +227,7 @@ CONFIG_KEYBOARD_NVEC=y CONFIG_SERIO_NVEC_PS2=y CONFIG_NVEC_POWER=y CONFIG_NVEC_PAZ00=y +CONFIG_COMMON_CLK_DEBUG=y CONFIG_TEGRA_IOMMU_GART=y CONFIG_TEGRA_IOMMU_SMMU=y CONFIG_MEMORY=y diff --git a/arch/arm/configs/u8500_defconfig b/arch/arm/configs/u8500_defconfig index a0025dc13021..ac632cc38f24 100644 --- a/arch/arm/configs/u8500_defconfig +++ b/arch/arm/configs/u8500_defconfig @@ -1,4 +1,3 @@ -CONFIG_HIGHMEM=y # CONFIG_SWAP is not set CONFIG_SYSVIPC=y CONFIG_NO_HZ=y @@ -16,6 +15,9 @@ CONFIG_SMP=y CONFIG_NR_CPUS=2 CONFIG_PREEMPT=y CONFIG_AEABI=y +CONFIG_HIGHMEM=y +CONFIG_ARM_APPENDED_DTB=y +CONFIG_ARM_ATAG_DTB_COMPAT=y CONFIG_CMDLINE="root=/dev/ram0 console=ttyAMA2,115200n8" CONFIG_CPU_FREQ=y CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y @@ -68,8 +70,8 @@ CONFIG_CPU_THERMAL=y CONFIG_WATCHDOG=y CONFIG_MFD_STMPE=y CONFIG_MFD_TC3589X=y -CONFIG_REGULATOR_GPIO=y CONFIG_REGULATOR_AB8500=y +CONFIG_REGULATOR_GPIO=y CONFIG_SOUND=y CONFIG_SND=y CONFIG_SND_SOC=y @@ -78,10 +80,8 @@ CONFIG_SND_SOC_UX500_MACH_MOP500=y CONFIG_USB=y CONFIG_USB_MUSB_HDRC=y CONFIG_USB_MUSB_UX500=y -CONFIG_USB_PHY=y CONFIG_AB8500_USB=y CONFIG_USB_GADGET=y -CONFIG_USB_GADGET_MUSB_HDRC=y CONFIG_USB_ETH=m CONFIG_MMC=y CONFIG_MMC_UNSAFE_RESUME=y @@ -116,12 +116,12 @@ CONFIG_NFS_FS=y CONFIG_ROOT_NFS=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y -CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_INFO=y CONFIG_DEBUG_FS=y +CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y # CONFIG_SCHED_DEBUG is not set # CONFIG_DEBUG_PREEMPT is not set -CONFIG_DEBUG_INFO=y # CONFIG_FTRACE is not set CONFIG_DEBUG_USER=y CONFIG_CRYPTO_DEV_UX500=y diff --git a/arch/arm/configs/vexpress_defconfig b/arch/arm/configs/vexpress_defconfig index f2de51f0bd18..f489fdaa19b8 100644 --- a/arch/arm/configs/vexpress_defconfig +++ b/arch/arm/configs/vexpress_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_IKCONFIG=y @@ -8,11 +7,9 @@ CONFIG_CGROUPS=y CONFIG_CPUSETS=y # CONFIG_UTS_NS is not set # CONFIG_IPC_NS is not set -# CONFIG_USER_NS is not set # CONFIG_PID_NS is not set # CONFIG_NET_NS is not set CONFIG_BLK_DEV_INITRD=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_PROFILING=y CONFIG_OPROFILE=y CONFIG_MODULES=y @@ -23,14 +20,22 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_IOSCHED_CFQ is not set CONFIG_ARCH_VEXPRESS=y CONFIG_ARCH_VEXPRESS_CA9X4=y +CONFIG_ARCH_VEXPRESS_DCSCB=y +CONFIG_ARCH_VEXPRESS_TC2_PM=y # CONFIG_SWP_EMULATE is not set CONFIG_SMP=y +CONFIG_HAVE_ARM_ARCH_TIMER=y +CONFIG_MCPM=y CONFIG_VMSPLIT_2G=y -CONFIG_HOTPLUG_CPU=y +CONFIG_NR_CPUS=8 +CONFIG_ARM_PSCI=y CONFIG_AEABI=y +CONFIG_CMA=y CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="root=/dev/nfs nfsroot=10.1.69.3:/work/nfsroot ip=dhcp console=ttyAMA0 mem=128M" +CONFIG_CMDLINE="console=ttyAMA0" +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y CONFIG_VFP=y CONFIG_NEON=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set @@ -44,37 +49,46 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set # CONFIG_WIRELESS is not set +CONFIG_NET_9P=y +CONFIG_NET_9P_VIRTIO=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y CONFIG_MTD=y -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_INTELEXT=y CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_ARM_INTEGRATOR=y -CONFIG_MISC_DEVICES=y +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_OF=y +CONFIG_MTD_PLATRAM=y +CONFIG_MTD_UBI=y +CONFIG_PROC_DEVICETREE=y +CONFIG_VIRTIO_BLK=y # CONFIG_SCSI_PROC_FS is not set CONFIG_BLK_DEV_SD=y -# CONFIG_SCSI_LOWLEVEL is not set +CONFIG_SCSI_VIRTIO=y CONFIG_ATA=y # CONFIG_SATA_PMP is not set CONFIG_NETDEVICES=y -CONFIG_NET_ETHERNET=y +CONFIG_VIRTIO_NET=y +CONFIG_SMC91X=y CONFIG_SMSC911X=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set # CONFIG_WLAN is not set CONFIG_INPUT_EVDEV=y # CONFIG_SERIO_SERPORT is not set CONFIG_SERIO_AMBAKMI=y +CONFIG_LEGACY_PTY_COUNT=16 CONFIG_SERIAL_AMBA_PL011=y CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -CONFIG_LEGACY_PTY_COUNT=16 -# CONFIG_HW_RANDOM is not set -# CONFIG_HWMON is not set +CONFIG_VIRTIO_CONSOLE=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_VIRTIO=y +CONFIG_I2C=y +CONFIG_I2C_VERSATILE=y +CONFIG_SENSORS_VEXPRESS=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_VEXPRESS=y CONFIG_FB=y CONFIG_FB_ARMCLCD=y CONFIG_FRAMEBUFFER_CONSOLE=y @@ -103,38 +117,45 @@ CONFIG_HID_THRUSTMASTER=y CONFIG_HID_ZEROPLUS=y CONFIG_USB=y CONFIG_USB_ANNOUNCE_NEW_DEVICES=y -# CONFIG_USB_DEVICE_CLASS is not set CONFIG_USB_MON=y CONFIG_USB_ISP1760_HCD=y CONFIG_USB_STORAGE=y CONFIG_MMC=y CONFIG_MMC_ARMMMCI=y +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_CPU=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_PL031=y +CONFIG_VIRTIO_BALLOON=y +CONFIG_VIRTIO_MMIO=y +CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set # CONFIG_EXT3_FS_XATTR is not set +CONFIG_EXT4_FS=y CONFIG_VFAT_FS=y CONFIG_TMPFS=y CONFIG_JFFS2_FS=y +CONFIG_UBIFS_FS=y CONFIG_CRAMFS=y +CONFIG_SQUASHFS=y +CONFIG_SQUASHFS_LZO=y CONFIG_NFS_FS=y -CONFIG_NFS_V3=y CONFIG_ROOT_NFS=y -# CONFIG_RPCSEC_GSS_KRB5 is not set +CONFIG_9P_FS=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y -CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_INFO=y CONFIG_DEBUG_FS=y +CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y CONFIG_DETECT_HUNG_TASK=y # CONFIG_SCHED_DEBUG is not set -CONFIG_DEBUG_INFO=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_DEBUG_USER=y -CONFIG_DEBUG_ERRORS=y -CONFIG_DEBUG_LL=y -CONFIG_EARLY_PRINTK=y # CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set diff --git a/arch/arm/configs/vt8500_v6_v7_defconfig b/arch/arm/configs/vt8500_v6_v7_defconfig new file mode 100644 index 000000000000..f0520176acd0 --- /dev/null +++ b/arch/arm/configs/vt8500_v6_v7_defconfig @@ -0,0 +1,90 @@ +CONFIG_IRQ_DOMAIN_DEBUG=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_ARCH_MULTI_V6=y +CONFIG_ARCH_WM8750=y +CONFIG_ARCH_WM8850=y +CONFIG_ARM_ERRATA_720789=y +CONFIG_ARM_ERRATA_754322=y +CONFIG_ARM_ERRATA_775420=y +CONFIG_HAVE_ARM_ARCH_TIMER=y +CONFIG_AEABI=y +CONFIG_HIGHMEM=y +CONFIG_HIGHPTE=y +CONFIG_ARM_APPENDED_DTB=y +CONFIG_ARM_ATAG_DTB_COMPAT=y +CONFIG_VFP=y +CONFIG_NEON=y +CONFIG_PM_RUNTIME=y +CONFIG_NET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_PROC_DEVICETREE=y +CONFIG_EEPROM_93CX6=y +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y +CONFIG_NETDEVICES=y +# CONFIG_NET_CADENCE is not set +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_NET_VENDOR_CIRRUS is not set +# CONFIG_NET_VENDOR_FARADAY is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SMSC is not set +# CONFIG_NET_VENDOR_STMICRO is not set +CONFIG_VIA_VELOCITY=y +# CONFIG_NET_VENDOR_WIZNET is not set +CONFIG_PHYLIB=y +CONFIG_INPUT_MATRIXKMAP=y +CONFIG_SERIAL_VT8500=y +CONFIG_SERIAL_VT8500_CONSOLE=y +CONFIG_I2C=y +CONFIG_I2C_WMT=y +CONFIG_PINCTRL_SINGLE=y +CONFIG_PINCTRL_WM8750=y +CONFIG_GPIO_GENERIC_PLATFORM=y +CONFIG_POWER_SUPPLY=y +CONFIG_POWER_RESET=y +CONFIG_MFD_SYSCON=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_GPIO=y +CONFIG_USB=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_HCD_PLATFORM=y +CONFIG_USB_UHCI_HCD=y +CONFIG_USB_STORAGE=y +CONFIG_NOP_USB_XCEIV=y +CONFIG_USB_GPIO_VBUS=y +CONFIG_USB_ULPI=y +CONFIG_MMC=y +CONFIG_MMC_DEBUG=y +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_TRIGGERS=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_VT8500=y +CONFIG_DMADEVICES=y +CONFIG_COMMON_CLK_DEBUG=y +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_PWM=y +CONFIG_PWM_VT8500=y +CONFIG_RESET_CONTROLLER=y +CONFIG_GENERIC_PHY=y +CONFIG_EXT4_FS=y +CONFIG_TMPFS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_ROOT_NFS=y +CONFIG_PRINTK_TIME=y +CONFIG_DEBUG_KERNEL=y +CONFIG_LOCKUP_DETECTOR=y diff --git a/arch/arm/crypto/.gitignore b/arch/arm/crypto/.gitignore new file mode 100644 index 000000000000..6231d36b3635 --- /dev/null +++ b/arch/arm/crypto/.gitignore @@ -0,0 +1 @@ +aesbs-core.S diff --git a/arch/arm/crypto/Makefile b/arch/arm/crypto/Makefile index a2c83851bc90..81cda39860c5 100644 --- a/arch/arm/crypto/Makefile +++ b/arch/arm/crypto/Makefile @@ -3,7 +3,17 @@ # obj-$(CONFIG_CRYPTO_AES_ARM) += aes-arm.o +obj-$(CONFIG_CRYPTO_AES_ARM_BS) += aes-arm-bs.o obj-$(CONFIG_CRYPTO_SHA1_ARM) += sha1-arm.o -aes-arm-y := aes-armv4.o aes_glue.o -sha1-arm-y := sha1-armv4-large.o sha1_glue.o +aes-arm-y := aes-armv4.o aes_glue.o +aes-arm-bs-y := aesbs-core.o aesbs-glue.o +sha1-arm-y := sha1-armv4-large.o sha1_glue.o + +quiet_cmd_perl = PERL $@ + cmd_perl = $(PERL) $(<) > $(@) + +$(src)/aesbs-core.S_shipped: $(src)/bsaes-armv7.pl + $(call cmd,perl) + +.PRECIOUS: $(obj)/aesbs-core.S diff --git a/arch/arm/crypto/aes_glue.c b/arch/arm/crypto/aes_glue.c index 59f7877ead6a..3003fa1f6fb4 100644 --- a/arch/arm/crypto/aes_glue.c +++ b/arch/arm/crypto/aes_glue.c @@ -6,22 +6,12 @@ #include <linux/crypto.h> #include <crypto/aes.h> -#define AES_MAXNR 14 +#include "aes_glue.h" -typedef struct { - unsigned int rd_key[4 *(AES_MAXNR + 1)]; - int rounds; -} AES_KEY; - -struct AES_CTX { - AES_KEY enc_key; - AES_KEY dec_key; -}; - -asmlinkage void AES_encrypt(const u8 *in, u8 *out, AES_KEY *ctx); -asmlinkage void AES_decrypt(const u8 *in, u8 *out, AES_KEY *ctx); -asmlinkage int private_AES_set_decrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key); -asmlinkage int private_AES_set_encrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key); +EXPORT_SYMBOL(AES_encrypt); +EXPORT_SYMBOL(AES_decrypt); +EXPORT_SYMBOL(private_AES_set_encrypt_key); +EXPORT_SYMBOL(private_AES_set_decrypt_key); static void aes_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) { @@ -81,7 +71,7 @@ static struct crypto_alg aes_alg = { .cipher = { .cia_min_keysize = AES_MIN_KEY_SIZE, .cia_max_keysize = AES_MAX_KEY_SIZE, - .cia_setkey = aes_set_key, + .cia_setkey = aes_set_key, .cia_encrypt = aes_encrypt, .cia_decrypt = aes_decrypt } diff --git a/arch/arm/crypto/aes_glue.h b/arch/arm/crypto/aes_glue.h new file mode 100644 index 000000000000..cca3e51eb606 --- /dev/null +++ b/arch/arm/crypto/aes_glue.h @@ -0,0 +1,19 @@ + +#define AES_MAXNR 14 + +struct AES_KEY { + unsigned int rd_key[4 * (AES_MAXNR + 1)]; + int rounds; +}; + +struct AES_CTX { + struct AES_KEY enc_key; + struct AES_KEY dec_key; +}; + +asmlinkage void AES_encrypt(const u8 *in, u8 *out, struct AES_KEY *ctx); +asmlinkage void AES_decrypt(const u8 *in, u8 *out, struct AES_KEY *ctx); +asmlinkage int private_AES_set_decrypt_key(const unsigned char *userKey, + const int bits, struct AES_KEY *key); +asmlinkage int private_AES_set_encrypt_key(const unsigned char *userKey, + const int bits, struct AES_KEY *key); diff --git a/arch/arm/crypto/aesbs-core.S_shipped b/arch/arm/crypto/aesbs-core.S_shipped new file mode 100644 index 000000000000..64205d453260 --- /dev/null +++ b/arch/arm/crypto/aesbs-core.S_shipped @@ -0,0 +1,2544 @@ + +@ ==================================================================== +@ Written by Andy Polyakov <appro@openssl.org> for the OpenSSL +@ project. The module is, however, dual licensed under OpenSSL and +@ CRYPTOGAMS licenses depending on where you obtain it. For further +@ details see http://www.openssl.org/~appro/cryptogams/. +@ +@ Specific modes and adaptation for Linux kernel by Ard Biesheuvel +@ <ard.biesheuvel@linaro.org>. Permission to use under GPL terms is +@ granted. +@ ==================================================================== + +@ Bit-sliced AES for ARM NEON +@ +@ February 2012. +@ +@ This implementation is direct adaptation of bsaes-x86_64 module for +@ ARM NEON. Except that this module is endian-neutral [in sense that +@ it can be compiled for either endianness] by courtesy of vld1.8's +@ neutrality. Initial version doesn't implement interface to OpenSSL, +@ only low-level primitives and unsupported entry points, just enough +@ to collect performance results, which for Cortex-A8 core are: +@ +@ encrypt 19.5 cycles per byte processed with 128-bit key +@ decrypt 22.1 cycles per byte processed with 128-bit key +@ key conv. 440 cycles per 128-bit key/0.18 of 8x block +@ +@ Snapdragon S4 encrypts byte in 17.6 cycles and decrypts in 19.7, +@ which is [much] worse than anticipated (for further details see +@ http://www.openssl.org/~appro/Snapdragon-S4.html). +@ +@ Cortex-A15 manages in 14.2/16.1 cycles [when integer-only code +@ manages in 20.0 cycles]. +@ +@ When comparing to x86_64 results keep in mind that NEON unit is +@ [mostly] single-issue and thus can't [fully] benefit from +@ instruction-level parallelism. And when comparing to aes-armv4 +@ results keep in mind key schedule conversion overhead (see +@ bsaes-x86_64.pl for further details)... +@ +@ <appro@openssl.org> + +@ April-August 2013 +@ +@ Add CBC, CTR and XTS subroutines, adapt for kernel use. +@ +@ <ard.biesheuvel@linaro.org> + +#ifndef __KERNEL__ +# include "arm_arch.h" + +# define VFP_ABI_PUSH vstmdb sp!,{d8-d15} +# define VFP_ABI_POP vldmia sp!,{d8-d15} +# define VFP_ABI_FRAME 0x40 +#else +# define VFP_ABI_PUSH +# define VFP_ABI_POP +# define VFP_ABI_FRAME 0 +# define BSAES_ASM_EXTENDED_KEY +# define XTS_CHAIN_TWEAK +# define __ARM_ARCH__ __LINUX_ARM_ARCH__ +#endif + +#ifdef __thumb__ +# define adrl adr +#endif + +#if __ARM_ARCH__>=7 +.text +.syntax unified @ ARMv7-capable assembler is expected to handle this +#ifdef __thumb2__ +.thumb +#else +.code 32 +#endif + +.fpu neon + +.type _bsaes_decrypt8,%function +.align 4 +_bsaes_decrypt8: + adr r6,_bsaes_decrypt8 + vldmia r4!, {q9} @ round 0 key + add r6,r6,#.LM0ISR-_bsaes_decrypt8 + + vldmia r6!, {q8} @ .LM0ISR + veor q10, q0, q9 @ xor with round0 key + veor q11, q1, q9 + vtbl.8 d0, {q10}, d16 + vtbl.8 d1, {q10}, d17 + veor q12, q2, q9 + vtbl.8 d2, {q11}, d16 + vtbl.8 d3, {q11}, d17 + veor q13, q3, q9 + vtbl.8 d4, {q12}, d16 + vtbl.8 d5, {q12}, d17 + veor q14, q4, q9 + vtbl.8 d6, {q13}, d16 + vtbl.8 d7, {q13}, d17 + veor q15, q5, q9 + vtbl.8 d8, {q14}, d16 + vtbl.8 d9, {q14}, d17 + veor q10, q6, q9 + vtbl.8 d10, {q15}, d16 + vtbl.8 d11, {q15}, d17 + veor q11, q7, q9 + vtbl.8 d12, {q10}, d16 + vtbl.8 d13, {q10}, d17 + vtbl.8 d14, {q11}, d16 + vtbl.8 d15, {q11}, d17 + vmov.i8 q8,#0x55 @ compose .LBS0 + vmov.i8 q9,#0x33 @ compose .LBS1 + vshr.u64 q10, q6, #1 + vshr.u64 q11, q4, #1 + veor q10, q10, q7 + veor q11, q11, q5 + vand q10, q10, q8 + vand q11, q11, q8 + veor q7, q7, q10 + vshl.u64 q10, q10, #1 + veor q5, q5, q11 + vshl.u64 q11, q11, #1 + veor q6, q6, q10 + veor q4, q4, q11 + vshr.u64 q10, q2, #1 + vshr.u64 q11, q0, #1 + veor q10, q10, q3 + veor q11, q11, q1 + vand q10, q10, q8 + vand q11, q11, q8 + veor q3, q3, q10 + vshl.u64 q10, q10, #1 + veor q1, q1, q11 + vshl.u64 q11, q11, #1 + veor q2, q2, q10 + veor q0, q0, q11 + vmov.i8 q8,#0x0f @ compose .LBS2 + vshr.u64 q10, q5, #2 + vshr.u64 q11, q4, #2 + veor q10, q10, q7 + veor q11, q11, q6 + vand q10, q10, q9 + vand q11, q11, q9 + veor q7, q7, q10 + vshl.u64 q10, q10, #2 + veor q6, q6, q11 + vshl.u64 q11, q11, #2 + veor q5, q5, q10 + veor q4, q4, q11 + vshr.u64 q10, q1, #2 + vshr.u64 q11, q0, #2 + veor q10, q10, q3 + veor q11, q11, q2 + vand q10, q10, q9 + vand q11, q11, q9 + veor q3, q3, q10 + vshl.u64 q10, q10, #2 + veor q2, q2, q11 + vshl.u64 q11, q11, #2 + veor q1, q1, q10 + veor q0, q0, q11 + vshr.u64 q10, q3, #4 + vshr.u64 q11, q2, #4 + veor q10, q10, q7 + veor q11, q11, q6 + vand q10, q10, q8 + vand q11, q11, q8 + veor q7, q7, q10 + vshl.u64 q10, q10, #4 + veor q6, q6, q11 + vshl.u64 q11, q11, #4 + veor q3, q3, q10 + veor q2, q2, q11 + vshr.u64 q10, q1, #4 + vshr.u64 q11, q0, #4 + veor q10, q10, q5 + veor q11, q11, q4 + vand q10, q10, q8 + vand q11, q11, q8 + veor q5, q5, q10 + vshl.u64 q10, q10, #4 + veor q4, q4, q11 + vshl.u64 q11, q11, #4 + veor q1, q1, q10 + veor q0, q0, q11 + sub r5,r5,#1 + b .Ldec_sbox +.align 4 +.Ldec_loop: + vldmia r4!, {q8-q11} + veor q8, q8, q0 + veor q9, q9, q1 + vtbl.8 d0, {q8}, d24 + vtbl.8 d1, {q8}, d25 + vldmia r4!, {q8} + veor q10, q10, q2 + vtbl.8 d2, {q9}, d24 + vtbl.8 d3, {q9}, d25 + vldmia r4!, {q9} + veor q11, q11, q3 + vtbl.8 d4, {q10}, d24 + vtbl.8 d5, {q10}, d25 + vldmia r4!, {q10} + vtbl.8 d6, {q11}, d24 + vtbl.8 d7, {q11}, d25 + vldmia r4!, {q11} + veor q8, q8, q4 + veor q9, q9, q5 + vtbl.8 d8, {q8}, d24 + vtbl.8 d9, {q8}, d25 + veor q10, q10, q6 + vtbl.8 d10, {q9}, d24 + vtbl.8 d11, {q9}, d25 + veor q11, q11, q7 + vtbl.8 d12, {q10}, d24 + vtbl.8 d13, {q10}, d25 + vtbl.8 d14, {q11}, d24 + vtbl.8 d15, {q11}, d25 +.Ldec_sbox: + veor q1, q1, q4 + veor q3, q3, q4 + + veor q4, q4, q7 + veor q1, q1, q6 + veor q2, q2, q7 + veor q6, q6, q4 + + veor q0, q0, q1 + veor q2, q2, q5 + veor q7, q7, q6 + veor q3, q3, q0 + veor q5, q5, q0 + veor q1, q1, q3 + veor q11, q3, q0 + veor q10, q7, q4 + veor q9, q1, q6 + veor q13, q4, q0 + vmov q8, q10 + veor q12, q5, q2 + + vorr q10, q10, q9 + veor q15, q11, q8 + vand q14, q11, q12 + vorr q11, q11, q12 + veor q12, q12, q9 + vand q8, q8, q9 + veor q9, q6, q2 + vand q15, q15, q12 + vand q13, q13, q9 + veor q9, q3, q7 + veor q12, q1, q5 + veor q11, q11, q13 + veor q10, q10, q13 + vand q13, q9, q12 + vorr q9, q9, q12 + veor q11, q11, q15 + veor q8, q8, q13 + veor q10, q10, q14 + veor q9, q9, q15 + veor q8, q8, q14 + vand q12, q4, q6 + veor q9, q9, q14 + vand q13, q0, q2 + vand q14, q7, q1 + vorr q15, q3, q5 + veor q11, q11, q12 + veor q9, q9, q14 + veor q8, q8, q15 + veor q10, q10, q13 + + @ Inv_GF16 0, 1, 2, 3, s0, s1, s2, s3 + + @ new smaller inversion + + vand q14, q11, q9 + vmov q12, q8 + + veor q13, q10, q14 + veor q15, q8, q14 + veor q14, q8, q14 @ q14=q15 + + vbsl q13, q9, q8 + vbsl q15, q11, q10 + veor q11, q11, q10 + + vbsl q12, q13, q14 + vbsl q8, q14, q13 + + vand q14, q12, q15 + veor q9, q9, q8 + + veor q14, q14, q11 + veor q12, q5, q2 + veor q8, q1, q6 + veor q10, q15, q14 + vand q10, q10, q5 + veor q5, q5, q1 + vand q11, q1, q15 + vand q5, q5, q14 + veor q1, q11, q10 + veor q5, q5, q11 + veor q15, q15, q13 + veor q14, q14, q9 + veor q11, q15, q14 + veor q10, q13, q9 + vand q11, q11, q12 + vand q10, q10, q2 + veor q12, q12, q8 + veor q2, q2, q6 + vand q8, q8, q15 + vand q6, q6, q13 + vand q12, q12, q14 + vand q2, q2, q9 + veor q8, q8, q12 + veor q2, q2, q6 + veor q12, q12, q11 + veor q6, q6, q10 + veor q5, q5, q12 + veor q2, q2, q12 + veor q1, q1, q8 + veor q6, q6, q8 + + veor q12, q3, q0 + veor q8, q7, q4 + veor q11, q15, q14 + veor q10, q13, q9 + vand q11, q11, q12 + vand q10, q10, q0 + veor q12, q12, q8 + veor q0, q0, q4 + vand q8, q8, q15 + vand q4, q4, q13 + vand q12, q12, q14 + vand q0, q0, q9 + veor q8, q8, q12 + veor q0, q0, q4 + veor q12, q12, q11 + veor q4, q4, q10 + veor q15, q15, q13 + veor q14, q14, q9 + veor q10, q15, q14 + vand q10, q10, q3 + veor q3, q3, q7 + vand q11, q7, q15 + vand q3, q3, q14 + veor q7, q11, q10 + veor q3, q3, q11 + veor q3, q3, q12 + veor q0, q0, q12 + veor q7, q7, q8 + veor q4, q4, q8 + veor q1, q1, q7 + veor q6, q6, q5 + + veor q4, q4, q1 + veor q2, q2, q7 + veor q5, q5, q7 + veor q4, q4, q2 + veor q7, q7, q0 + veor q4, q4, q5 + veor q3, q3, q6 + veor q6, q6, q1 + veor q3, q3, q4 + + veor q4, q4, q0 + veor q7, q7, q3 + subs r5,r5,#1 + bcc .Ldec_done + @ multiplication by 0x05-0x00-0x04-0x00 + vext.8 q8, q0, q0, #8 + vext.8 q14, q3, q3, #8 + vext.8 q15, q5, q5, #8 + veor q8, q8, q0 + vext.8 q9, q1, q1, #8 + veor q14, q14, q3 + vext.8 q10, q6, q6, #8 + veor q15, q15, q5 + vext.8 q11, q4, q4, #8 + veor q9, q9, q1 + vext.8 q12, q2, q2, #8 + veor q10, q10, q6 + vext.8 q13, q7, q7, #8 + veor q11, q11, q4 + veor q12, q12, q2 + veor q13, q13, q7 + + veor q0, q0, q14 + veor q1, q1, q14 + veor q6, q6, q8 + veor q2, q2, q10 + veor q4, q4, q9 + veor q1, q1, q15 + veor q6, q6, q15 + veor q2, q2, q14 + veor q7, q7, q11 + veor q4, q4, q14 + veor q3, q3, q12 + veor q2, q2, q15 + veor q7, q7, q15 + veor q5, q5, q13 + vext.8 q8, q0, q0, #12 @ x0 <<< 32 + vext.8 q9, q1, q1, #12 + veor q0, q0, q8 @ x0 ^ (x0 <<< 32) + vext.8 q10, q6, q6, #12 + veor q1, q1, q9 + vext.8 q11, q4, q4, #12 + veor q6, q6, q10 + vext.8 q12, q2, q2, #12 + veor q4, q4, q11 + vext.8 q13, q7, q7, #12 + veor q2, q2, q12 + vext.8 q14, q3, q3, #12 + veor q7, q7, q13 + vext.8 q15, q5, q5, #12 + veor q3, q3, q14 + + veor q9, q9, q0 + veor q5, q5, q15 + vext.8 q0, q0, q0, #8 @ (x0 ^ (x0 <<< 32)) <<< 64) + veor q10, q10, q1 + veor q8, q8, q5 + veor q9, q9, q5 + vext.8 q1, q1, q1, #8 + veor q13, q13, q2 + veor q0, q0, q8 + veor q14, q14, q7 + veor q1, q1, q9 + vext.8 q8, q2, q2, #8 + veor q12, q12, q4 + vext.8 q9, q7, q7, #8 + veor q15, q15, q3 + vext.8 q2, q4, q4, #8 + veor q11, q11, q6 + vext.8 q7, q5, q5, #8 + veor q12, q12, q5 + vext.8 q4, q3, q3, #8 + veor q11, q11, q5 + vext.8 q3, q6, q6, #8 + veor q5, q9, q13 + veor q11, q11, q2 + veor q7, q7, q15 + veor q6, q4, q14 + veor q4, q8, q12 + veor q2, q3, q10 + vmov q3, q11 + @ vmov q5, q9 + vldmia r6, {q12} @ .LISR + ite eq @ Thumb2 thing, sanity check in ARM + addeq r6,r6,#0x10 + bne .Ldec_loop + vldmia r6, {q12} @ .LISRM0 + b .Ldec_loop +.align 4 +.Ldec_done: + vmov.i8 q8,#0x55 @ compose .LBS0 + vmov.i8 q9,#0x33 @ compose .LBS1 + vshr.u64 q10, q3, #1 + vshr.u64 q11, q2, #1 + veor q10, q10, q5 + veor q11, q11, q7 + vand q10, q10, q8 + vand q11, q11, q8 + veor q5, q5, q10 + vshl.u64 q10, q10, #1 + veor q7, q7, q11 + vshl.u64 q11, q11, #1 + veor q3, q3, q10 + veor q2, q2, q11 + vshr.u64 q10, q6, #1 + vshr.u64 q11, q0, #1 + veor q10, q10, q4 + veor q11, q11, q1 + vand q10, q10, q8 + vand q11, q11, q8 + veor q4, q4, q10 + vshl.u64 q10, q10, #1 + veor q1, q1, q11 + vshl.u64 q11, q11, #1 + veor q6, q6, q10 + veor q0, q0, q11 + vmov.i8 q8,#0x0f @ compose .LBS2 + vshr.u64 q10, q7, #2 + vshr.u64 q11, q2, #2 + veor q10, q10, q5 + veor q11, q11, q3 + vand q10, q10, q9 + vand q11, q11, q9 + veor q5, q5, q10 + vshl.u64 q10, q10, #2 + veor q3, q3, q11 + vshl.u64 q11, q11, #2 + veor q7, q7, q10 + veor q2, q2, q11 + vshr.u64 q10, q1, #2 + vshr.u64 q11, q0, #2 + veor q10, q10, q4 + veor q11, q11, q6 + vand q10, q10, q9 + vand q11, q11, q9 + veor q4, q4, q10 + vshl.u64 q10, q10, #2 + veor q6, q6, q11 + vshl.u64 q11, q11, #2 + veor q1, q1, q10 + veor q0, q0, q11 + vshr.u64 q10, q4, #4 + vshr.u64 q11, q6, #4 + veor q10, q10, q5 + veor q11, q11, q3 + vand q10, q10, q8 + vand q11, q11, q8 + veor q5, q5, q10 + vshl.u64 q10, q10, #4 + veor q3, q3, q11 + vshl.u64 q11, q11, #4 + veor q4, q4, q10 + veor q6, q6, q11 + vshr.u64 q10, q1, #4 + vshr.u64 q11, q0, #4 + veor q10, q10, q7 + veor q11, q11, q2 + vand q10, q10, q8 + vand q11, q11, q8 + veor q7, q7, q10 + vshl.u64 q10, q10, #4 + veor q2, q2, q11 + vshl.u64 q11, q11, #4 + veor q1, q1, q10 + veor q0, q0, q11 + vldmia r4, {q8} @ last round key + veor q6, q6, q8 + veor q4, q4, q8 + veor q2, q2, q8 + veor q7, q7, q8 + veor q3, q3, q8 + veor q5, q5, q8 + veor q0, q0, q8 + veor q1, q1, q8 + bx lr +.size _bsaes_decrypt8,.-_bsaes_decrypt8 + +.type _bsaes_const,%object +.align 6 +_bsaes_const: +.LM0ISR: @ InvShiftRows constants + .quad 0x0a0e0206070b0f03, 0x0004080c0d010509 +.LISR: + .quad 0x0504070602010003, 0x0f0e0d0c080b0a09 +.LISRM0: + .quad 0x01040b0e0205080f, 0x0306090c00070a0d +.LM0SR: @ ShiftRows constants + .quad 0x0a0e02060f03070b, 0x0004080c05090d01 +.LSR: + .quad 0x0504070600030201, 0x0f0e0d0c0a09080b +.LSRM0: + .quad 0x0304090e00050a0f, 0x01060b0c0207080d +.LM0: + .quad 0x02060a0e03070b0f, 0x0004080c0105090d +.LREVM0SR: + .quad 0x090d01050c000408, 0x03070b0f060a0e02 +.asciz "Bit-sliced AES for NEON, CRYPTOGAMS by <appro@openssl.org>" +.align 6 +.size _bsaes_const,.-_bsaes_const + +.type _bsaes_encrypt8,%function +.align 4 +_bsaes_encrypt8: + adr r6,_bsaes_encrypt8 + vldmia r4!, {q9} @ round 0 key + sub r6,r6,#_bsaes_encrypt8-.LM0SR + + vldmia r6!, {q8} @ .LM0SR +_bsaes_encrypt8_alt: + veor q10, q0, q9 @ xor with round0 key + veor q11, q1, q9 + vtbl.8 d0, {q10}, d16 + vtbl.8 d1, {q10}, d17 + veor q12, q2, q9 + vtbl.8 d2, {q11}, d16 + vtbl.8 d3, {q11}, d17 + veor q13, q3, q9 + vtbl.8 d4, {q12}, d16 + vtbl.8 d5, {q12}, d17 + veor q14, q4, q9 + vtbl.8 d6, {q13}, d16 + vtbl.8 d7, {q13}, d17 + veor q15, q5, q9 + vtbl.8 d8, {q14}, d16 + vtbl.8 d9, {q14}, d17 + veor q10, q6, q9 + vtbl.8 d10, {q15}, d16 + vtbl.8 d11, {q15}, d17 + veor q11, q7, q9 + vtbl.8 d12, {q10}, d16 + vtbl.8 d13, {q10}, d17 + vtbl.8 d14, {q11}, d16 + vtbl.8 d15, {q11}, d17 +_bsaes_encrypt8_bitslice: + vmov.i8 q8,#0x55 @ compose .LBS0 + vmov.i8 q9,#0x33 @ compose .LBS1 + vshr.u64 q10, q6, #1 + vshr.u64 q11, q4, #1 + veor q10, q10, q7 + veor q11, q11, q5 + vand q10, q10, q8 + vand q11, q11, q8 + veor q7, q7, q10 + vshl.u64 q10, q10, #1 + veor q5, q5, q11 + vshl.u64 q11, q11, #1 + veor q6, q6, q10 + veor q4, q4, q11 + vshr.u64 q10, q2, #1 + vshr.u64 q11, q0, #1 + veor q10, q10, q3 + veor q11, q11, q1 + vand q10, q10, q8 + vand q11, q11, q8 + veor q3, q3, q10 + vshl.u64 q10, q10, #1 + veor q1, q1, q11 + vshl.u64 q11, q11, #1 + veor q2, q2, q10 + veor q0, q0, q11 + vmov.i8 q8,#0x0f @ compose .LBS2 + vshr.u64 q10, q5, #2 + vshr.u64 q11, q4, #2 + veor q10, q10, q7 + veor q11, q11, q6 + vand q10, q10, q9 + vand q11, q11, q9 + veor q7, q7, q10 + vshl.u64 q10, q10, #2 + veor q6, q6, q11 + vshl.u64 q11, q11, #2 + veor q5, q5, q10 + veor q4, q4, q11 + vshr.u64 q10, q1, #2 + vshr.u64 q11, q0, #2 + veor q10, q10, q3 + veor q11, q11, q2 + vand q10, q10, q9 + vand q11, q11, q9 + veor q3, q3, q10 + vshl.u64 q10, q10, #2 + veor q2, q2, q11 + vshl.u64 q11, q11, #2 + veor q1, q1, q10 + veor q0, q0, q11 + vshr.u64 q10, q3, #4 + vshr.u64 q11, q2, #4 + veor q10, q10, q7 + veor q11, q11, q6 + vand q10, q10, q8 + vand q11, q11, q8 + veor q7, q7, q10 + vshl.u64 q10, q10, #4 + veor q6, q6, q11 + vshl.u64 q11, q11, #4 + veor q3, q3, q10 + veor q2, q2, q11 + vshr.u64 q10, q1, #4 + vshr.u64 q11, q0, #4 + veor q10, q10, q5 + veor q11, q11, q4 + vand q10, q10, q8 + vand q11, q11, q8 + veor q5, q5, q10 + vshl.u64 q10, q10, #4 + veor q4, q4, q11 + vshl.u64 q11, q11, #4 + veor q1, q1, q10 + veor q0, q0, q11 + sub r5,r5,#1 + b .Lenc_sbox +.align 4 +.Lenc_loop: + vldmia r4!, {q8-q11} + veor q8, q8, q0 + veor q9, q9, q1 + vtbl.8 d0, {q8}, d24 + vtbl.8 d1, {q8}, d25 + vldmia r4!, {q8} + veor q10, q10, q2 + vtbl.8 d2, {q9}, d24 + vtbl.8 d3, {q9}, d25 + vldmia r4!, {q9} + veor q11, q11, q3 + vtbl.8 d4, {q10}, d24 + vtbl.8 d5, {q10}, d25 + vldmia r4!, {q10} + vtbl.8 d6, {q11}, d24 + vtbl.8 d7, {q11}, d25 + vldmia r4!, {q11} + veor q8, q8, q4 + veor q9, q9, q5 + vtbl.8 d8, {q8}, d24 + vtbl.8 d9, {q8}, d25 + veor q10, q10, q6 + vtbl.8 d10, {q9}, d24 + vtbl.8 d11, {q9}, d25 + veor q11, q11, q7 + vtbl.8 d12, {q10}, d24 + vtbl.8 d13, {q10}, d25 + vtbl.8 d14, {q11}, d24 + vtbl.8 d15, {q11}, d25 +.Lenc_sbox: + veor q2, q2, q1 + veor q5, q5, q6 + veor q3, q3, q0 + veor q6, q6, q2 + veor q5, q5, q0 + + veor q6, q6, q3 + veor q3, q3, q7 + veor q7, q7, q5 + veor q3, q3, q4 + veor q4, q4, q5 + + veor q2, q2, q7 + veor q3, q3, q1 + veor q1, q1, q5 + veor q11, q7, q4 + veor q10, q1, q2 + veor q9, q5, q3 + veor q13, q2, q4 + vmov q8, q10 + veor q12, q6, q0 + + vorr q10, q10, q9 + veor q15, q11, q8 + vand q14, q11, q12 + vorr q11, q11, q12 + veor q12, q12, q9 + vand q8, q8, q9 + veor q9, q3, q0 + vand q15, q15, q12 + vand q13, q13, q9 + veor q9, q7, q1 + veor q12, q5, q6 + veor q11, q11, q13 + veor q10, q10, q13 + vand q13, q9, q12 + vorr q9, q9, q12 + veor q11, q11, q15 + veor q8, q8, q13 + veor q10, q10, q14 + veor q9, q9, q15 + veor q8, q8, q14 + vand q12, q2, q3 + veor q9, q9, q14 + vand q13, q4, q0 + vand q14, q1, q5 + vorr q15, q7, q6 + veor q11, q11, q12 + veor q9, q9, q14 + veor q8, q8, q15 + veor q10, q10, q13 + + @ Inv_GF16 0, 1, 2, 3, s0, s1, s2, s3 + + @ new smaller inversion + + vand q14, q11, q9 + vmov q12, q8 + + veor q13, q10, q14 + veor q15, q8, q14 + veor q14, q8, q14 @ q14=q15 + + vbsl q13, q9, q8 + vbsl q15, q11, q10 + veor q11, q11, q10 + + vbsl q12, q13, q14 + vbsl q8, q14, q13 + + vand q14, q12, q15 + veor q9, q9, q8 + + veor q14, q14, q11 + veor q12, q6, q0 + veor q8, q5, q3 + veor q10, q15, q14 + vand q10, q10, q6 + veor q6, q6, q5 + vand q11, q5, q15 + vand q6, q6, q14 + veor q5, q11, q10 + veor q6, q6, q11 + veor q15, q15, q13 + veor q14, q14, q9 + veor q11, q15, q14 + veor q10, q13, q9 + vand q11, q11, q12 + vand q10, q10, q0 + veor q12, q12, q8 + veor q0, q0, q3 + vand q8, q8, q15 + vand q3, q3, q13 + vand q12, q12, q14 + vand q0, q0, q9 + veor q8, q8, q12 + veor q0, q0, q3 + veor q12, q12, q11 + veor q3, q3, q10 + veor q6, q6, q12 + veor q0, q0, q12 + veor q5, q5, q8 + veor q3, q3, q8 + + veor q12, q7, q4 + veor q8, q1, q2 + veor q11, q15, q14 + veor q10, q13, q9 + vand q11, q11, q12 + vand q10, q10, q4 + veor q12, q12, q8 + veor q4, q4, q2 + vand q8, q8, q15 + vand q2, q2, q13 + vand q12, q12, q14 + vand q4, q4, q9 + veor q8, q8, q12 + veor q4, q4, q2 + veor q12, q12, q11 + veor q2, q2, q10 + veor q15, q15, q13 + veor q14, q14, q9 + veor q10, q15, q14 + vand q10, q10, q7 + veor q7, q7, q1 + vand q11, q1, q15 + vand q7, q7, q14 + veor q1, q11, q10 + veor q7, q7, q11 + veor q7, q7, q12 + veor q4, q4, q12 + veor q1, q1, q8 + veor q2, q2, q8 + veor q7, q7, q0 + veor q1, q1, q6 + veor q6, q6, q0 + veor q4, q4, q7 + veor q0, q0, q1 + + veor q1, q1, q5 + veor q5, q5, q2 + veor q2, q2, q3 + veor q3, q3, q5 + veor q4, q4, q5 + + veor q6, q6, q3 + subs r5,r5,#1 + bcc .Lenc_done + vext.8 q8, q0, q0, #12 @ x0 <<< 32 + vext.8 q9, q1, q1, #12 + veor q0, q0, q8 @ x0 ^ (x0 <<< 32) + vext.8 q10, q4, q4, #12 + veor q1, q1, q9 + vext.8 q11, q6, q6, #12 + veor q4, q4, q10 + vext.8 q12, q3, q3, #12 + veor q6, q6, q11 + vext.8 q13, q7, q7, #12 + veor q3, q3, q12 + vext.8 q14, q2, q2, #12 + veor q7, q7, q13 + vext.8 q15, q5, q5, #12 + veor q2, q2, q14 + + veor q9, q9, q0 + veor q5, q5, q15 + vext.8 q0, q0, q0, #8 @ (x0 ^ (x0 <<< 32)) <<< 64) + veor q10, q10, q1 + veor q8, q8, q5 + veor q9, q9, q5 + vext.8 q1, q1, q1, #8 + veor q13, q13, q3 + veor q0, q0, q8 + veor q14, q14, q7 + veor q1, q1, q9 + vext.8 q8, q3, q3, #8 + veor q12, q12, q6 + vext.8 q9, q7, q7, #8 + veor q15, q15, q2 + vext.8 q3, q6, q6, #8 + veor q11, q11, q4 + vext.8 q7, q5, q5, #8 + veor q12, q12, q5 + vext.8 q6, q2, q2, #8 + veor q11, q11, q5 + vext.8 q2, q4, q4, #8 + veor q5, q9, q13 + veor q4, q8, q12 + veor q3, q3, q11 + veor q7, q7, q15 + veor q6, q6, q14 + @ vmov q4, q8 + veor q2, q2, q10 + @ vmov q5, q9 + vldmia r6, {q12} @ .LSR + ite eq @ Thumb2 thing, samity check in ARM + addeq r6,r6,#0x10 + bne .Lenc_loop + vldmia r6, {q12} @ .LSRM0 + b .Lenc_loop +.align 4 +.Lenc_done: + vmov.i8 q8,#0x55 @ compose .LBS0 + vmov.i8 q9,#0x33 @ compose .LBS1 + vshr.u64 q10, q2, #1 + vshr.u64 q11, q3, #1 + veor q10, q10, q5 + veor q11, q11, q7 + vand q10, q10, q8 + vand q11, q11, q8 + veor q5, q5, q10 + vshl.u64 q10, q10, #1 + veor q7, q7, q11 + vshl.u64 q11, q11, #1 + veor q2, q2, q10 + veor q3, q3, q11 + vshr.u64 q10, q4, #1 + vshr.u64 q11, q0, #1 + veor q10, q10, q6 + veor q11, q11, q1 + vand q10, q10, q8 + vand q11, q11, q8 + veor q6, q6, q10 + vshl.u64 q10, q10, #1 + veor q1, q1, q11 + vshl.u64 q11, q11, #1 + veor q4, q4, q10 + veor q0, q0, q11 + vmov.i8 q8,#0x0f @ compose .LBS2 + vshr.u64 q10, q7, #2 + vshr.u64 q11, q3, #2 + veor q10, q10, q5 + veor q11, q11, q2 + vand q10, q10, q9 + vand q11, q11, q9 + veor q5, q5, q10 + vshl.u64 q10, q10, #2 + veor q2, q2, q11 + vshl.u64 q11, q11, #2 + veor q7, q7, q10 + veor q3, q3, q11 + vshr.u64 q10, q1, #2 + vshr.u64 q11, q0, #2 + veor q10, q10, q6 + veor q11, q11, q4 + vand q10, q10, q9 + vand q11, q11, q9 + veor q6, q6, q10 + vshl.u64 q10, q10, #2 + veor q4, q4, q11 + vshl.u64 q11, q11, #2 + veor q1, q1, q10 + veor q0, q0, q11 + vshr.u64 q10, q6, #4 + vshr.u64 q11, q4, #4 + veor q10, q10, q5 + veor q11, q11, q2 + vand q10, q10, q8 + vand q11, q11, q8 + veor q5, q5, q10 + vshl.u64 q10, q10, #4 + veor q2, q2, q11 + vshl.u64 q11, q11, #4 + veor q6, q6, q10 + veor q4, q4, q11 + vshr.u64 q10, q1, #4 + vshr.u64 q11, q0, #4 + veor q10, q10, q7 + veor q11, q11, q3 + vand q10, q10, q8 + vand q11, q11, q8 + veor q7, q7, q10 + vshl.u64 q10, q10, #4 + veor q3, q3, q11 + vshl.u64 q11, q11, #4 + veor q1, q1, q10 + veor q0, q0, q11 + vldmia r4, {q8} @ last round key + veor q4, q4, q8 + veor q6, q6, q8 + veor q3, q3, q8 + veor q7, q7, q8 + veor q2, q2, q8 + veor q5, q5, q8 + veor q0, q0, q8 + veor q1, q1, q8 + bx lr +.size _bsaes_encrypt8,.-_bsaes_encrypt8 +.type _bsaes_key_convert,%function +.align 4 +_bsaes_key_convert: + adr r6,_bsaes_key_convert + vld1.8 {q7}, [r4]! @ load round 0 key + sub r6,r6,#_bsaes_key_convert-.LM0 + vld1.8 {q15}, [r4]! @ load round 1 key + + vmov.i8 q8, #0x01 @ bit masks + vmov.i8 q9, #0x02 + vmov.i8 q10, #0x04 + vmov.i8 q11, #0x08 + vmov.i8 q12, #0x10 + vmov.i8 q13, #0x20 + vldmia r6, {q14} @ .LM0 + +#ifdef __ARMEL__ + vrev32.8 q7, q7 + vrev32.8 q15, q15 +#endif + sub r5,r5,#1 + vstmia r12!, {q7} @ save round 0 key + b .Lkey_loop + +.align 4 +.Lkey_loop: + vtbl.8 d14,{q15},d28 + vtbl.8 d15,{q15},d29 + vmov.i8 q6, #0x40 + vmov.i8 q15, #0x80 + + vtst.8 q0, q7, q8 + vtst.8 q1, q7, q9 + vtst.8 q2, q7, q10 + vtst.8 q3, q7, q11 + vtst.8 q4, q7, q12 + vtst.8 q5, q7, q13 + vtst.8 q6, q7, q6 + vtst.8 q7, q7, q15 + vld1.8 {q15}, [r4]! @ load next round key + vmvn q0, q0 @ "pnot" + vmvn q1, q1 + vmvn q5, q5 + vmvn q6, q6 +#ifdef __ARMEL__ + vrev32.8 q15, q15 +#endif + subs r5,r5,#1 + vstmia r12!,{q0-q7} @ write bit-sliced round key + bne .Lkey_loop + + vmov.i8 q7,#0x63 @ compose .L63 + @ don't save last round key + bx lr +.size _bsaes_key_convert,.-_bsaes_key_convert +.extern AES_cbc_encrypt +.extern AES_decrypt + +.global bsaes_cbc_encrypt +.type bsaes_cbc_encrypt,%function +.align 5 +bsaes_cbc_encrypt: +#ifndef __KERNEL__ + cmp r2, #128 +#ifndef __thumb__ + blo AES_cbc_encrypt +#else + bhs 1f + b AES_cbc_encrypt +1: +#endif +#endif + + @ it is up to the caller to make sure we are called with enc == 0 + + mov ip, sp + stmdb sp!, {r4-r10, lr} + VFP_ABI_PUSH + ldr r8, [ip] @ IV is 1st arg on the stack + mov r2, r2, lsr#4 @ len in 16 byte blocks + sub sp, #0x10 @ scratch space to carry over the IV + mov r9, sp @ save sp + + ldr r10, [r3, #240] @ get # of rounds +#ifndef BSAES_ASM_EXTENDED_KEY + @ allocate the key schedule on the stack + sub r12, sp, r10, lsl#7 @ 128 bytes per inner round key + add r12, #96 @ sifze of bit-slices key schedule + + @ populate the key schedule + mov r4, r3 @ pass key + mov r5, r10 @ pass # of rounds + mov sp, r12 @ sp is sp + bl _bsaes_key_convert + vldmia sp, {q6} + vstmia r12, {q15} @ save last round key + veor q7, q7, q6 @ fix up round 0 key + vstmia sp, {q7} +#else + ldr r12, [r3, #244] + eors r12, #1 + beq 0f + + @ populate the key schedule + str r12, [r3, #244] + mov r4, r3 @ pass key + mov r5, r10 @ pass # of rounds + add r12, r3, #248 @ pass key schedule + bl _bsaes_key_convert + add r4, r3, #248 + vldmia r4, {q6} + vstmia r12, {q15} @ save last round key + veor q7, q7, q6 @ fix up round 0 key + vstmia r4, {q7} + +.align 2 +0: +#endif + + vld1.8 {q15}, [r8] @ load IV + b .Lcbc_dec_loop + +.align 4 +.Lcbc_dec_loop: + subs r2, r2, #0x8 + bmi .Lcbc_dec_loop_finish + + vld1.8 {q0-q1}, [r0]! @ load input + vld1.8 {q2-q3}, [r0]! +#ifndef BSAES_ASM_EXTENDED_KEY + mov r4, sp @ pass the key +#else + add r4, r3, #248 +#endif + vld1.8 {q4-q5}, [r0]! + mov r5, r10 + vld1.8 {q6-q7}, [r0] + sub r0, r0, #0x60 + vstmia r9, {q15} @ put aside IV + + bl _bsaes_decrypt8 + + vldmia r9, {q14} @ reload IV + vld1.8 {q8-q9}, [r0]! @ reload input + veor q0, q0, q14 @ ^= IV + vld1.8 {q10-q11}, [r0]! + veor q1, q1, q8 + veor q6, q6, q9 + vld1.8 {q12-q13}, [r0]! + veor q4, q4, q10 + veor q2, q2, q11 + vld1.8 {q14-q15}, [r0]! + veor q7, q7, q12 + vst1.8 {q0-q1}, [r1]! @ write output + veor q3, q3, q13 + vst1.8 {q6}, [r1]! + veor q5, q5, q14 + vst1.8 {q4}, [r1]! + vst1.8 {q2}, [r1]! + vst1.8 {q7}, [r1]! + vst1.8 {q3}, [r1]! + vst1.8 {q5}, [r1]! + + b .Lcbc_dec_loop + +.Lcbc_dec_loop_finish: + adds r2, r2, #8 + beq .Lcbc_dec_done + + vld1.8 {q0}, [r0]! @ load input + cmp r2, #2 + blo .Lcbc_dec_one + vld1.8 {q1}, [r0]! +#ifndef BSAES_ASM_EXTENDED_KEY + mov r4, sp @ pass the key +#else + add r4, r3, #248 +#endif + mov r5, r10 + vstmia r9, {q15} @ put aside IV + beq .Lcbc_dec_two + vld1.8 {q2}, [r0]! + cmp r2, #4 + blo .Lcbc_dec_three + vld1.8 {q3}, [r0]! + beq .Lcbc_dec_four + vld1.8 {q4}, [r0]! + cmp r2, #6 + blo .Lcbc_dec_five + vld1.8 {q5}, [r0]! + beq .Lcbc_dec_six + vld1.8 {q6}, [r0]! + sub r0, r0, #0x70 + + bl _bsaes_decrypt8 + + vldmia r9, {q14} @ reload IV + vld1.8 {q8-q9}, [r0]! @ reload input + veor q0, q0, q14 @ ^= IV + vld1.8 {q10-q11}, [r0]! + veor q1, q1, q8 + veor q6, q6, q9 + vld1.8 {q12-q13}, [r0]! + veor q4, q4, q10 + veor q2, q2, q11 + vld1.8 {q15}, [r0]! + veor q7, q7, q12 + vst1.8 {q0-q1}, [r1]! @ write output + veor q3, q3, q13 + vst1.8 {q6}, [r1]! + vst1.8 {q4}, [r1]! + vst1.8 {q2}, [r1]! + vst1.8 {q7}, [r1]! + vst1.8 {q3}, [r1]! + b .Lcbc_dec_done +.align 4 +.Lcbc_dec_six: + sub r0, r0, #0x60 + bl _bsaes_decrypt8 + vldmia r9,{q14} @ reload IV + vld1.8 {q8-q9}, [r0]! @ reload input + veor q0, q0, q14 @ ^= IV + vld1.8 {q10-q11}, [r0]! + veor q1, q1, q8 + veor q6, q6, q9 + vld1.8 {q12}, [r0]! + veor q4, q4, q10 + veor q2, q2, q11 + vld1.8 {q15}, [r0]! + veor q7, q7, q12 + vst1.8 {q0-q1}, [r1]! @ write output + vst1.8 {q6}, [r1]! + vst1.8 {q4}, [r1]! + vst1.8 {q2}, [r1]! + vst1.8 {q7}, [r1]! + b .Lcbc_dec_done +.align 4 +.Lcbc_dec_five: + sub r0, r0, #0x50 + bl _bsaes_decrypt8 + vldmia r9, {q14} @ reload IV + vld1.8 {q8-q9}, [r0]! @ reload input + veor q0, q0, q14 @ ^= IV + vld1.8 {q10-q11}, [r0]! + veor q1, q1, q8 + veor q6, q6, q9 + vld1.8 {q15}, [r0]! + veor q4, q4, q10 + vst1.8 {q0-q1}, [r1]! @ write output + veor q2, q2, q11 + vst1.8 {q6}, [r1]! + vst1.8 {q4}, [r1]! + vst1.8 {q2}, [r1]! + b .Lcbc_dec_done +.align 4 +.Lcbc_dec_four: + sub r0, r0, #0x40 + bl _bsaes_decrypt8 + vldmia r9, {q14} @ reload IV + vld1.8 {q8-q9}, [r0]! @ reload input + veor q0, q0, q14 @ ^= IV + vld1.8 {q10}, [r0]! + veor q1, q1, q8 + veor q6, q6, q9 + vld1.8 {q15}, [r0]! + veor q4, q4, q10 + vst1.8 {q0-q1}, [r1]! @ write output + vst1.8 {q6}, [r1]! + vst1.8 {q4}, [r1]! + b .Lcbc_dec_done +.align 4 +.Lcbc_dec_three: + sub r0, r0, #0x30 + bl _bsaes_decrypt8 + vldmia r9, {q14} @ reload IV + vld1.8 {q8-q9}, [r0]! @ reload input + veor q0, q0, q14 @ ^= IV + vld1.8 {q15}, [r0]! + veor q1, q1, q8 + veor q6, q6, q9 + vst1.8 {q0-q1}, [r1]! @ write output + vst1.8 {q6}, [r1]! + b .Lcbc_dec_done +.align 4 +.Lcbc_dec_two: + sub r0, r0, #0x20 + bl _bsaes_decrypt8 + vldmia r9, {q14} @ reload IV + vld1.8 {q8}, [r0]! @ reload input + veor q0, q0, q14 @ ^= IV + vld1.8 {q15}, [r0]! @ reload input + veor q1, q1, q8 + vst1.8 {q0-q1}, [r1]! @ write output + b .Lcbc_dec_done +.align 4 +.Lcbc_dec_one: + sub r0, r0, #0x10 + mov r10, r1 @ save original out pointer + mov r1, r9 @ use the iv scratch space as out buffer + mov r2, r3 + vmov q4,q15 @ just in case ensure that IV + vmov q5,q0 @ and input are preserved + bl AES_decrypt + vld1.8 {q0}, [r9,:64] @ load result + veor q0, q0, q4 @ ^= IV + vmov q15, q5 @ q5 holds input + vst1.8 {q0}, [r10] @ write output + +.Lcbc_dec_done: +#ifndef BSAES_ASM_EXTENDED_KEY + vmov.i32 q0, #0 + vmov.i32 q1, #0 +.Lcbc_dec_bzero: @ wipe key schedule [if any] + vstmia sp!, {q0-q1} + cmp sp, r9 + bne .Lcbc_dec_bzero +#endif + + mov sp, r9 + add sp, #0x10 @ add sp,r9,#0x10 is no good for thumb + vst1.8 {q15}, [r8] @ return IV + VFP_ABI_POP + ldmia sp!, {r4-r10, pc} +.size bsaes_cbc_encrypt,.-bsaes_cbc_encrypt +.extern AES_encrypt +.global bsaes_ctr32_encrypt_blocks +.type bsaes_ctr32_encrypt_blocks,%function +.align 5 +bsaes_ctr32_encrypt_blocks: + cmp r2, #8 @ use plain AES for + blo .Lctr_enc_short @ small sizes + + mov ip, sp + stmdb sp!, {r4-r10, lr} + VFP_ABI_PUSH + ldr r8, [ip] @ ctr is 1st arg on the stack + sub sp, sp, #0x10 @ scratch space to carry over the ctr + mov r9, sp @ save sp + + ldr r10, [r3, #240] @ get # of rounds +#ifndef BSAES_ASM_EXTENDED_KEY + @ allocate the key schedule on the stack + sub r12, sp, r10, lsl#7 @ 128 bytes per inner round key + add r12, #96 @ size of bit-sliced key schedule + + @ populate the key schedule + mov r4, r3 @ pass key + mov r5, r10 @ pass # of rounds + mov sp, r12 @ sp is sp + bl _bsaes_key_convert + veor q7,q7,q15 @ fix up last round key + vstmia r12, {q7} @ save last round key + + vld1.8 {q0}, [r8] @ load counter + add r8, r6, #.LREVM0SR-.LM0 @ borrow r8 + vldmia sp, {q4} @ load round0 key +#else + ldr r12, [r3, #244] + eors r12, #1 + beq 0f + + @ populate the key schedule + str r12, [r3, #244] + mov r4, r3 @ pass key + mov r5, r10 @ pass # of rounds + add r12, r3, #248 @ pass key schedule + bl _bsaes_key_convert + veor q7,q7,q15 @ fix up last round key + vstmia r12, {q7} @ save last round key + +.align 2 +0: add r12, r3, #248 + vld1.8 {q0}, [r8] @ load counter + adrl r8, .LREVM0SR @ borrow r8 + vldmia r12, {q4} @ load round0 key + sub sp, #0x10 @ place for adjusted round0 key +#endif + + vmov.i32 q8,#1 @ compose 1<<96 + veor q9,q9,q9 + vrev32.8 q0,q0 + vext.8 q8,q9,q8,#4 + vrev32.8 q4,q4 + vadd.u32 q9,q8,q8 @ compose 2<<96 + vstmia sp, {q4} @ save adjusted round0 key + b .Lctr_enc_loop + +.align 4 +.Lctr_enc_loop: + vadd.u32 q10, q8, q9 @ compose 3<<96 + vadd.u32 q1, q0, q8 @ +1 + vadd.u32 q2, q0, q9 @ +2 + vadd.u32 q3, q0, q10 @ +3 + vadd.u32 q4, q1, q10 + vadd.u32 q5, q2, q10 + vadd.u32 q6, q3, q10 + vadd.u32 q7, q4, q10 + vadd.u32 q10, q5, q10 @ next counter + + @ Borrow prologue from _bsaes_encrypt8 to use the opportunity + @ to flip byte order in 32-bit counter + + vldmia sp, {q9} @ load round0 key +#ifndef BSAES_ASM_EXTENDED_KEY + add r4, sp, #0x10 @ pass next round key +#else + add r4, r3, #264 +#endif + vldmia r8, {q8} @ .LREVM0SR + mov r5, r10 @ pass rounds + vstmia r9, {q10} @ save next counter + sub r6, r8, #.LREVM0SR-.LSR @ pass constants + + bl _bsaes_encrypt8_alt + + subs r2, r2, #8 + blo .Lctr_enc_loop_done + + vld1.8 {q8-q9}, [r0]! @ load input + vld1.8 {q10-q11}, [r0]! + veor q0, q8 + veor q1, q9 + vld1.8 {q12-q13}, [r0]! + veor q4, q10 + veor q6, q11 + vld1.8 {q14-q15}, [r0]! + veor q3, q12 + vst1.8 {q0-q1}, [r1]! @ write output + veor q7, q13 + veor q2, q14 + vst1.8 {q4}, [r1]! + veor q5, q15 + vst1.8 {q6}, [r1]! + vmov.i32 q8, #1 @ compose 1<<96 + vst1.8 {q3}, [r1]! + veor q9, q9, q9 + vst1.8 {q7}, [r1]! + vext.8 q8, q9, q8, #4 + vst1.8 {q2}, [r1]! + vadd.u32 q9,q8,q8 @ compose 2<<96 + vst1.8 {q5}, [r1]! + vldmia r9, {q0} @ load counter + + bne .Lctr_enc_loop + b .Lctr_enc_done + +.align 4 +.Lctr_enc_loop_done: + add r2, r2, #8 + vld1.8 {q8}, [r0]! @ load input + veor q0, q8 + vst1.8 {q0}, [r1]! @ write output + cmp r2, #2 + blo .Lctr_enc_done + vld1.8 {q9}, [r0]! + veor q1, q9 + vst1.8 {q1}, [r1]! + beq .Lctr_enc_done + vld1.8 {q10}, [r0]! + veor q4, q10 + vst1.8 {q4}, [r1]! + cmp r2, #4 + blo .Lctr_enc_done + vld1.8 {q11}, [r0]! + veor q6, q11 + vst1.8 {q6}, [r1]! + beq .Lctr_enc_done + vld1.8 {q12}, [r0]! + veor q3, q12 + vst1.8 {q3}, [r1]! + cmp r2, #6 + blo .Lctr_enc_done + vld1.8 {q13}, [r0]! + veor q7, q13 + vst1.8 {q7}, [r1]! + beq .Lctr_enc_done + vld1.8 {q14}, [r0] + veor q2, q14 + vst1.8 {q2}, [r1]! + +.Lctr_enc_done: + vmov.i32 q0, #0 + vmov.i32 q1, #0 +#ifndef BSAES_ASM_EXTENDED_KEY +.Lctr_enc_bzero: @ wipe key schedule [if any] + vstmia sp!, {q0-q1} + cmp sp, r9 + bne .Lctr_enc_bzero +#else + vstmia sp, {q0-q1} +#endif + + mov sp, r9 + add sp, #0x10 @ add sp,r9,#0x10 is no good for thumb + VFP_ABI_POP + ldmia sp!, {r4-r10, pc} @ return + +.align 4 +.Lctr_enc_short: + ldr ip, [sp] @ ctr pointer is passed on stack + stmdb sp!, {r4-r8, lr} + + mov r4, r0 @ copy arguments + mov r5, r1 + mov r6, r2 + mov r7, r3 + ldr r8, [ip, #12] @ load counter LSW + vld1.8 {q1}, [ip] @ load whole counter value +#ifdef __ARMEL__ + rev r8, r8 +#endif + sub sp, sp, #0x10 + vst1.8 {q1}, [sp,:64] @ copy counter value + sub sp, sp, #0x10 + +.Lctr_enc_short_loop: + add r0, sp, #0x10 @ input counter value + mov r1, sp @ output on the stack + mov r2, r7 @ key + + bl AES_encrypt + + vld1.8 {q0}, [r4]! @ load input + vld1.8 {q1}, [sp,:64] @ load encrypted counter + add r8, r8, #1 +#ifdef __ARMEL__ + rev r0, r8 + str r0, [sp, #0x1c] @ next counter value +#else + str r8, [sp, #0x1c] @ next counter value +#endif + veor q0,q0,q1 + vst1.8 {q0}, [r5]! @ store output + subs r6, r6, #1 + bne .Lctr_enc_short_loop + + vmov.i32 q0, #0 + vmov.i32 q1, #0 + vstmia sp!, {q0-q1} + + ldmia sp!, {r4-r8, pc} +.size bsaes_ctr32_encrypt_blocks,.-bsaes_ctr32_encrypt_blocks +.globl bsaes_xts_encrypt +.type bsaes_xts_encrypt,%function +.align 4 +bsaes_xts_encrypt: + mov ip, sp + stmdb sp!, {r4-r10, lr} @ 0x20 + VFP_ABI_PUSH + mov r6, sp @ future r3 + + mov r7, r0 + mov r8, r1 + mov r9, r2 + mov r10, r3 + + sub r0, sp, #0x10 @ 0x10 + bic r0, #0xf @ align at 16 bytes + mov sp, r0 + +#ifdef XTS_CHAIN_TWEAK + ldr r0, [ip] @ pointer to input tweak +#else + @ generate initial tweak + ldr r0, [ip, #4] @ iv[] + mov r1, sp + ldr r2, [ip, #0] @ key2 + bl AES_encrypt + mov r0,sp @ pointer to initial tweak +#endif + + ldr r1, [r10, #240] @ get # of rounds + mov r3, r6 +#ifndef BSAES_ASM_EXTENDED_KEY + @ allocate the key schedule on the stack + sub r12, sp, r1, lsl#7 @ 128 bytes per inner round key + @ add r12, #96 @ size of bit-sliced key schedule + sub r12, #48 @ place for tweak[9] + + @ populate the key schedule + mov r4, r10 @ pass key + mov r5, r1 @ pass # of rounds + mov sp, r12 + add r12, #0x90 @ pass key schedule + bl _bsaes_key_convert + veor q7, q7, q15 @ fix up last round key + vstmia r12, {q7} @ save last round key +#else + ldr r12, [r10, #244] + eors r12, #1 + beq 0f + + str r12, [r10, #244] + mov r4, r10 @ pass key + mov r5, r1 @ pass # of rounds + add r12, r10, #248 @ pass key schedule + bl _bsaes_key_convert + veor q7, q7, q15 @ fix up last round key + vstmia r12, {q7} + +.align 2 +0: sub sp, #0x90 @ place for tweak[9] +#endif + + vld1.8 {q8}, [r0] @ initial tweak + adr r2, .Lxts_magic + + subs r9, #0x80 + blo .Lxts_enc_short + b .Lxts_enc_loop + +.align 4 +.Lxts_enc_loop: + vldmia r2, {q5} @ load XTS magic + vshr.s64 q6, q8, #63 + mov r0, sp + vand q6, q6, q5 + vadd.u64 q9, q8, q8 + vst1.64 {q8}, [r0,:128]! + vswp d13,d12 + vshr.s64 q7, q9, #63 + veor q9, q9, q6 + vand q7, q7, q5 + vadd.u64 q10, q9, q9 + vst1.64 {q9}, [r0,:128]! + vswp d15,d14 + vshr.s64 q6, q10, #63 + veor q10, q10, q7 + vand q6, q6, q5 + vld1.8 {q0}, [r7]! + vadd.u64 q11, q10, q10 + vst1.64 {q10}, [r0,:128]! + vswp d13,d12 + vshr.s64 q7, q11, #63 + veor q11, q11, q6 + vand q7, q7, q5 + vld1.8 {q1}, [r7]! + veor q0, q0, q8 + vadd.u64 q12, q11, q11 + vst1.64 {q11}, [r0,:128]! + vswp d15,d14 + vshr.s64 q6, q12, #63 + veor q12, q12, q7 + vand q6, q6, q5 + vld1.8 {q2}, [r7]! + veor q1, q1, q9 + vadd.u64 q13, q12, q12 + vst1.64 {q12}, [r0,:128]! + vswp d13,d12 + vshr.s64 q7, q13, #63 + veor q13, q13, q6 + vand q7, q7, q5 + vld1.8 {q3}, [r7]! + veor q2, q2, q10 + vadd.u64 q14, q13, q13 + vst1.64 {q13}, [r0,:128]! + vswp d15,d14 + vshr.s64 q6, q14, #63 + veor q14, q14, q7 + vand q6, q6, q5 + vld1.8 {q4}, [r7]! + veor q3, q3, q11 + vadd.u64 q15, q14, q14 + vst1.64 {q14}, [r0,:128]! + vswp d13,d12 + vshr.s64 q7, q15, #63 + veor q15, q15, q6 + vand q7, q7, q5 + vld1.8 {q5}, [r7]! + veor q4, q4, q12 + vadd.u64 q8, q15, q15 + vst1.64 {q15}, [r0,:128]! + vswp d15,d14 + veor q8, q8, q7 + vst1.64 {q8}, [r0,:128] @ next round tweak + + vld1.8 {q6-q7}, [r7]! + veor q5, q5, q13 +#ifndef BSAES_ASM_EXTENDED_KEY + add r4, sp, #0x90 @ pass key schedule +#else + add r4, r10, #248 @ pass key schedule +#endif + veor q6, q6, q14 + mov r5, r1 @ pass rounds + veor q7, q7, q15 + mov r0, sp + + bl _bsaes_encrypt8 + + vld1.64 {q8-q9}, [r0,:128]! + vld1.64 {q10-q11}, [r0,:128]! + veor q0, q0, q8 + vld1.64 {q12-q13}, [r0,:128]! + veor q1, q1, q9 + veor q8, q4, q10 + vst1.8 {q0-q1}, [r8]! + veor q9, q6, q11 + vld1.64 {q14-q15}, [r0,:128]! + veor q10, q3, q12 + vst1.8 {q8-q9}, [r8]! + veor q11, q7, q13 + veor q12, q2, q14 + vst1.8 {q10-q11}, [r8]! + veor q13, q5, q15 + vst1.8 {q12-q13}, [r8]! + + vld1.64 {q8}, [r0,:128] @ next round tweak + + subs r9, #0x80 + bpl .Lxts_enc_loop + +.Lxts_enc_short: + adds r9, #0x70 + bmi .Lxts_enc_done + + vldmia r2, {q5} @ load XTS magic + vshr.s64 q7, q8, #63 + mov r0, sp + vand q7, q7, q5 + vadd.u64 q9, q8, q8 + vst1.64 {q8}, [r0,:128]! + vswp d15,d14 + vshr.s64 q6, q9, #63 + veor q9, q9, q7 + vand q6, q6, q5 + vadd.u64 q10, q9, q9 + vst1.64 {q9}, [r0,:128]! + vswp d13,d12 + vshr.s64 q7, q10, #63 + veor q10, q10, q6 + vand q7, q7, q5 + vld1.8 {q0}, [r7]! + subs r9, #0x10 + bmi .Lxts_enc_1 + vadd.u64 q11, q10, q10 + vst1.64 {q10}, [r0,:128]! + vswp d15,d14 + vshr.s64 q6, q11, #63 + veor q11, q11, q7 + vand q6, q6, q5 + vld1.8 {q1}, [r7]! + subs r9, #0x10 + bmi .Lxts_enc_2 + veor q0, q0, q8 + vadd.u64 q12, q11, q11 + vst1.64 {q11}, [r0,:128]! + vswp d13,d12 + vshr.s64 q7, q12, #63 + veor q12, q12, q6 + vand q7, q7, q5 + vld1.8 {q2}, [r7]! + subs r9, #0x10 + bmi .Lxts_enc_3 + veor q1, q1, q9 + vadd.u64 q13, q12, q12 + vst1.64 {q12}, [r0,:128]! + vswp d15,d14 + vshr.s64 q6, q13, #63 + veor q13, q13, q7 + vand q6, q6, q5 + vld1.8 {q3}, [r7]! + subs r9, #0x10 + bmi .Lxts_enc_4 + veor q2, q2, q10 + vadd.u64 q14, q13, q13 + vst1.64 {q13}, [r0,:128]! + vswp d13,d12 + vshr.s64 q7, q14, #63 + veor q14, q14, q6 + vand q7, q7, q5 + vld1.8 {q4}, [r7]! + subs r9, #0x10 + bmi .Lxts_enc_5 + veor q3, q3, q11 + vadd.u64 q15, q14, q14 + vst1.64 {q14}, [r0,:128]! + vswp d15,d14 + vshr.s64 q6, q15, #63 + veor q15, q15, q7 + vand q6, q6, q5 + vld1.8 {q5}, [r7]! + subs r9, #0x10 + bmi .Lxts_enc_6 + veor q4, q4, q12 + sub r9, #0x10 + vst1.64 {q15}, [r0,:128] @ next round tweak + + vld1.8 {q6}, [r7]! + veor q5, q5, q13 +#ifndef BSAES_ASM_EXTENDED_KEY + add r4, sp, #0x90 @ pass key schedule +#else + add r4, r10, #248 @ pass key schedule +#endif + veor q6, q6, q14 + mov r5, r1 @ pass rounds + mov r0, sp + + bl _bsaes_encrypt8 + + vld1.64 {q8-q9}, [r0,:128]! + vld1.64 {q10-q11}, [r0,:128]! + veor q0, q0, q8 + vld1.64 {q12-q13}, [r0,:128]! + veor q1, q1, q9 + veor q8, q4, q10 + vst1.8 {q0-q1}, [r8]! + veor q9, q6, q11 + vld1.64 {q14}, [r0,:128]! + veor q10, q3, q12 + vst1.8 {q8-q9}, [r8]! + veor q11, q7, q13 + veor q12, q2, q14 + vst1.8 {q10-q11}, [r8]! + vst1.8 {q12}, [r8]! + + vld1.64 {q8}, [r0,:128] @ next round tweak + b .Lxts_enc_done +.align 4 +.Lxts_enc_6: + vst1.64 {q14}, [r0,:128] @ next round tweak + + veor q4, q4, q12 +#ifndef BSAES_ASM_EXTENDED_KEY + add r4, sp, #0x90 @ pass key schedule +#else + add r4, r10, #248 @ pass key schedule +#endif + veor q5, q5, q13 + mov r5, r1 @ pass rounds + mov r0, sp + + bl _bsaes_encrypt8 + + vld1.64 {q8-q9}, [r0,:128]! + vld1.64 {q10-q11}, [r0,:128]! + veor q0, q0, q8 + vld1.64 {q12-q13}, [r0,:128]! + veor q1, q1, q9 + veor q8, q4, q10 + vst1.8 {q0-q1}, [r8]! + veor q9, q6, q11 + veor q10, q3, q12 + vst1.8 {q8-q9}, [r8]! + veor q11, q7, q13 + vst1.8 {q10-q11}, [r8]! + + vld1.64 {q8}, [r0,:128] @ next round tweak + b .Lxts_enc_done + +@ put this in range for both ARM and Thumb mode adr instructions +.align 5 +.Lxts_magic: + .quad 1, 0x87 + +.align 5 +.Lxts_enc_5: + vst1.64 {q13}, [r0,:128] @ next round tweak + + veor q3, q3, q11 +#ifndef BSAES_ASM_EXTENDED_KEY + add r4, sp, #0x90 @ pass key schedule +#else + add r4, r10, #248 @ pass key schedule +#endif + veor q4, q4, q12 + mov r5, r1 @ pass rounds + mov r0, sp + + bl _bsaes_encrypt8 + + vld1.64 {q8-q9}, [r0,:128]! + vld1.64 {q10-q11}, [r0,:128]! + veor q0, q0, q8 + vld1.64 {q12}, [r0,:128]! + veor q1, q1, q9 + veor q8, q4, q10 + vst1.8 {q0-q1}, [r8]! + veor q9, q6, q11 + veor q10, q3, q12 + vst1.8 {q8-q9}, [r8]! + vst1.8 {q10}, [r8]! + + vld1.64 {q8}, [r0,:128] @ next round tweak + b .Lxts_enc_done +.align 4 +.Lxts_enc_4: + vst1.64 {q12}, [r0,:128] @ next round tweak + + veor q2, q2, q10 +#ifndef BSAES_ASM_EXTENDED_KEY + add r4, sp, #0x90 @ pass key schedule +#else + add r4, r10, #248 @ pass key schedule +#endif + veor q3, q3, q11 + mov r5, r1 @ pass rounds + mov r0, sp + + bl _bsaes_encrypt8 + + vld1.64 {q8-q9}, [r0,:128]! + vld1.64 {q10-q11}, [r0,:128]! + veor q0, q0, q8 + veor q1, q1, q9 + veor q8, q4, q10 + vst1.8 {q0-q1}, [r8]! + veor q9, q6, q11 + vst1.8 {q8-q9}, [r8]! + + vld1.64 {q8}, [r0,:128] @ next round tweak + b .Lxts_enc_done +.align 4 +.Lxts_enc_3: + vst1.64 {q11}, [r0,:128] @ next round tweak + + veor q1, q1, q9 +#ifndef BSAES_ASM_EXTENDED_KEY + add r4, sp, #0x90 @ pass key schedule +#else + add r4, r10, #248 @ pass key schedule +#endif + veor q2, q2, q10 + mov r5, r1 @ pass rounds + mov r0, sp + + bl _bsaes_encrypt8 + + vld1.64 {q8-q9}, [r0,:128]! + vld1.64 {q10}, [r0,:128]! + veor q0, q0, q8 + veor q1, q1, q9 + veor q8, q4, q10 + vst1.8 {q0-q1}, [r8]! + vst1.8 {q8}, [r8]! + + vld1.64 {q8}, [r0,:128] @ next round tweak + b .Lxts_enc_done +.align 4 +.Lxts_enc_2: + vst1.64 {q10}, [r0,:128] @ next round tweak + + veor q0, q0, q8 +#ifndef BSAES_ASM_EXTENDED_KEY + add r4, sp, #0x90 @ pass key schedule +#else + add r4, r10, #248 @ pass key schedule +#endif + veor q1, q1, q9 + mov r5, r1 @ pass rounds + mov r0, sp + + bl _bsaes_encrypt8 + + vld1.64 {q8-q9}, [r0,:128]! + veor q0, q0, q8 + veor q1, q1, q9 + vst1.8 {q0-q1}, [r8]! + + vld1.64 {q8}, [r0,:128] @ next round tweak + b .Lxts_enc_done +.align 4 +.Lxts_enc_1: + mov r0, sp + veor q0, q8 + mov r1, sp + vst1.8 {q0}, [sp,:128] + mov r2, r10 + mov r4, r3 @ preserve fp + + bl AES_encrypt + + vld1.8 {q0}, [sp,:128] + veor q0, q0, q8 + vst1.8 {q0}, [r8]! + mov r3, r4 + + vmov q8, q9 @ next round tweak + +.Lxts_enc_done: +#ifndef XTS_CHAIN_TWEAK + adds r9, #0x10 + beq .Lxts_enc_ret + sub r6, r8, #0x10 + +.Lxts_enc_steal: + ldrb r0, [r7], #1 + ldrb r1, [r8, #-0x10] + strb r0, [r8, #-0x10] + strb r1, [r8], #1 + + subs r9, #1 + bhi .Lxts_enc_steal + + vld1.8 {q0}, [r6] + mov r0, sp + veor q0, q0, q8 + mov r1, sp + vst1.8 {q0}, [sp,:128] + mov r2, r10 + mov r4, r3 @ preserve fp + + bl AES_encrypt + + vld1.8 {q0}, [sp,:128] + veor q0, q0, q8 + vst1.8 {q0}, [r6] + mov r3, r4 +#endif + +.Lxts_enc_ret: + bic r0, r3, #0xf + vmov.i32 q0, #0 + vmov.i32 q1, #0 +#ifdef XTS_CHAIN_TWEAK + ldr r1, [r3, #0x20+VFP_ABI_FRAME] @ chain tweak +#endif +.Lxts_enc_bzero: @ wipe key schedule [if any] + vstmia sp!, {q0-q1} + cmp sp, r0 + bne .Lxts_enc_bzero + + mov sp, r3 +#ifdef XTS_CHAIN_TWEAK + vst1.8 {q8}, [r1] +#endif + VFP_ABI_POP + ldmia sp!, {r4-r10, pc} @ return + +.size bsaes_xts_encrypt,.-bsaes_xts_encrypt + +.globl bsaes_xts_decrypt +.type bsaes_xts_decrypt,%function +.align 4 +bsaes_xts_decrypt: + mov ip, sp + stmdb sp!, {r4-r10, lr} @ 0x20 + VFP_ABI_PUSH + mov r6, sp @ future r3 + + mov r7, r0 + mov r8, r1 + mov r9, r2 + mov r10, r3 + + sub r0, sp, #0x10 @ 0x10 + bic r0, #0xf @ align at 16 bytes + mov sp, r0 + +#ifdef XTS_CHAIN_TWEAK + ldr r0, [ip] @ pointer to input tweak +#else + @ generate initial tweak + ldr r0, [ip, #4] @ iv[] + mov r1, sp + ldr r2, [ip, #0] @ key2 + bl AES_encrypt + mov r0, sp @ pointer to initial tweak +#endif + + ldr r1, [r10, #240] @ get # of rounds + mov r3, r6 +#ifndef BSAES_ASM_EXTENDED_KEY + @ allocate the key schedule on the stack + sub r12, sp, r1, lsl#7 @ 128 bytes per inner round key + @ add r12, #96 @ size of bit-sliced key schedule + sub r12, #48 @ place for tweak[9] + + @ populate the key schedule + mov r4, r10 @ pass key + mov r5, r1 @ pass # of rounds + mov sp, r12 + add r12, #0x90 @ pass key schedule + bl _bsaes_key_convert + add r4, sp, #0x90 + vldmia r4, {q6} + vstmia r12, {q15} @ save last round key + veor q7, q7, q6 @ fix up round 0 key + vstmia r4, {q7} +#else + ldr r12, [r10, #244] + eors r12, #1 + beq 0f + + str r12, [r10, #244] + mov r4, r10 @ pass key + mov r5, r1 @ pass # of rounds + add r12, r10, #248 @ pass key schedule + bl _bsaes_key_convert + add r4, r10, #248 + vldmia r4, {q6} + vstmia r12, {q15} @ save last round key + veor q7, q7, q6 @ fix up round 0 key + vstmia r4, {q7} + +.align 2 +0: sub sp, #0x90 @ place for tweak[9] +#endif + vld1.8 {q8}, [r0] @ initial tweak + adr r2, .Lxts_magic + + tst r9, #0xf @ if not multiple of 16 + it ne @ Thumb2 thing, sanity check in ARM + subne r9, #0x10 @ subtract another 16 bytes + subs r9, #0x80 + + blo .Lxts_dec_short + b .Lxts_dec_loop + +.align 4 +.Lxts_dec_loop: + vldmia r2, {q5} @ load XTS magic + vshr.s64 q6, q8, #63 + mov r0, sp + vand q6, q6, q5 + vadd.u64 q9, q8, q8 + vst1.64 {q8}, [r0,:128]! + vswp d13,d12 + vshr.s64 q7, q9, #63 + veor q9, q9, q6 + vand q7, q7, q5 + vadd.u64 q10, q9, q9 + vst1.64 {q9}, [r0,:128]! + vswp d15,d14 + vshr.s64 q6, q10, #63 + veor q10, q10, q7 + vand q6, q6, q5 + vld1.8 {q0}, [r7]! + vadd.u64 q11, q10, q10 + vst1.64 {q10}, [r0,:128]! + vswp d13,d12 + vshr.s64 q7, q11, #63 + veor q11, q11, q6 + vand q7, q7, q5 + vld1.8 {q1}, [r7]! + veor q0, q0, q8 + vadd.u64 q12, q11, q11 + vst1.64 {q11}, [r0,:128]! + vswp d15,d14 + vshr.s64 q6, q12, #63 + veor q12, q12, q7 + vand q6, q6, q5 + vld1.8 {q2}, [r7]! + veor q1, q1, q9 + vadd.u64 q13, q12, q12 + vst1.64 {q12}, [r0,:128]! + vswp d13,d12 + vshr.s64 q7, q13, #63 + veor q13, q13, q6 + vand q7, q7, q5 + vld1.8 {q3}, [r7]! + veor q2, q2, q10 + vadd.u64 q14, q13, q13 + vst1.64 {q13}, [r0,:128]! + vswp d15,d14 + vshr.s64 q6, q14, #63 + veor q14, q14, q7 + vand q6, q6, q5 + vld1.8 {q4}, [r7]! + veor q3, q3, q11 + vadd.u64 q15, q14, q14 + vst1.64 {q14}, [r0,:128]! + vswp d13,d12 + vshr.s64 q7, q15, #63 + veor q15, q15, q6 + vand q7, q7, q5 + vld1.8 {q5}, [r7]! + veor q4, q4, q12 + vadd.u64 q8, q15, q15 + vst1.64 {q15}, [r0,:128]! + vswp d15,d14 + veor q8, q8, q7 + vst1.64 {q8}, [r0,:128] @ next round tweak + + vld1.8 {q6-q7}, [r7]! + veor q5, q5, q13 +#ifndef BSAES_ASM_EXTENDED_KEY + add r4, sp, #0x90 @ pass key schedule +#else + add r4, r10, #248 @ pass key schedule +#endif + veor q6, q6, q14 + mov r5, r1 @ pass rounds + veor q7, q7, q15 + mov r0, sp + + bl _bsaes_decrypt8 + + vld1.64 {q8-q9}, [r0,:128]! + vld1.64 {q10-q11}, [r0,:128]! + veor q0, q0, q8 + vld1.64 {q12-q13}, [r0,:128]! + veor q1, q1, q9 + veor q8, q6, q10 + vst1.8 {q0-q1}, [r8]! + veor q9, q4, q11 + vld1.64 {q14-q15}, [r0,:128]! + veor q10, q2, q12 + vst1.8 {q8-q9}, [r8]! + veor q11, q7, q13 + veor q12, q3, q14 + vst1.8 {q10-q11}, [r8]! + veor q13, q5, q15 + vst1.8 {q12-q13}, [r8]! + + vld1.64 {q8}, [r0,:128] @ next round tweak + + subs r9, #0x80 + bpl .Lxts_dec_loop + +.Lxts_dec_short: + adds r9, #0x70 + bmi .Lxts_dec_done + + vldmia r2, {q5} @ load XTS magic + vshr.s64 q7, q8, #63 + mov r0, sp + vand q7, q7, q5 + vadd.u64 q9, q8, q8 + vst1.64 {q8}, [r0,:128]! + vswp d15,d14 + vshr.s64 q6, q9, #63 + veor q9, q9, q7 + vand q6, q6, q5 + vadd.u64 q10, q9, q9 + vst1.64 {q9}, [r0,:128]! + vswp d13,d12 + vshr.s64 q7, q10, #63 + veor q10, q10, q6 + vand q7, q7, q5 + vld1.8 {q0}, [r7]! + subs r9, #0x10 + bmi .Lxts_dec_1 + vadd.u64 q11, q10, q10 + vst1.64 {q10}, [r0,:128]! + vswp d15,d14 + vshr.s64 q6, q11, #63 + veor q11, q11, q7 + vand q6, q6, q5 + vld1.8 {q1}, [r7]! + subs r9, #0x10 + bmi .Lxts_dec_2 + veor q0, q0, q8 + vadd.u64 q12, q11, q11 + vst1.64 {q11}, [r0,:128]! + vswp d13,d12 + vshr.s64 q7, q12, #63 + veor q12, q12, q6 + vand q7, q7, q5 + vld1.8 {q2}, [r7]! + subs r9, #0x10 + bmi .Lxts_dec_3 + veor q1, q1, q9 + vadd.u64 q13, q12, q12 + vst1.64 {q12}, [r0,:128]! + vswp d15,d14 + vshr.s64 q6, q13, #63 + veor q13, q13, q7 + vand q6, q6, q5 + vld1.8 {q3}, [r7]! + subs r9, #0x10 + bmi .Lxts_dec_4 + veor q2, q2, q10 + vadd.u64 q14, q13, q13 + vst1.64 {q13}, [r0,:128]! + vswp d13,d12 + vshr.s64 q7, q14, #63 + veor q14, q14, q6 + vand q7, q7, q5 + vld1.8 {q4}, [r7]! + subs r9, #0x10 + bmi .Lxts_dec_5 + veor q3, q3, q11 + vadd.u64 q15, q14, q14 + vst1.64 {q14}, [r0,:128]! + vswp d15,d14 + vshr.s64 q6, q15, #63 + veor q15, q15, q7 + vand q6, q6, q5 + vld1.8 {q5}, [r7]! + subs r9, #0x10 + bmi .Lxts_dec_6 + veor q4, q4, q12 + sub r9, #0x10 + vst1.64 {q15}, [r0,:128] @ next round tweak + + vld1.8 {q6}, [r7]! + veor q5, q5, q13 +#ifndef BSAES_ASM_EXTENDED_KEY + add r4, sp, #0x90 @ pass key schedule +#else + add r4, r10, #248 @ pass key schedule +#endif + veor q6, q6, q14 + mov r5, r1 @ pass rounds + mov r0, sp + + bl _bsaes_decrypt8 + + vld1.64 {q8-q9}, [r0,:128]! + vld1.64 {q10-q11}, [r0,:128]! + veor q0, q0, q8 + vld1.64 {q12-q13}, [r0,:128]! + veor q1, q1, q9 + veor q8, q6, q10 + vst1.8 {q0-q1}, [r8]! + veor q9, q4, q11 + vld1.64 {q14}, [r0,:128]! + veor q10, q2, q12 + vst1.8 {q8-q9}, [r8]! + veor q11, q7, q13 + veor q12, q3, q14 + vst1.8 {q10-q11}, [r8]! + vst1.8 {q12}, [r8]! + + vld1.64 {q8}, [r0,:128] @ next round tweak + b .Lxts_dec_done +.align 4 +.Lxts_dec_6: + vst1.64 {q14}, [r0,:128] @ next round tweak + + veor q4, q4, q12 +#ifndef BSAES_ASM_EXTENDED_KEY + add r4, sp, #0x90 @ pass key schedule +#else + add r4, r10, #248 @ pass key schedule +#endif + veor q5, q5, q13 + mov r5, r1 @ pass rounds + mov r0, sp + + bl _bsaes_decrypt8 + + vld1.64 {q8-q9}, [r0,:128]! + vld1.64 {q10-q11}, [r0,:128]! + veor q0, q0, q8 + vld1.64 {q12-q13}, [r0,:128]! + veor q1, q1, q9 + veor q8, q6, q10 + vst1.8 {q0-q1}, [r8]! + veor q9, q4, q11 + veor q10, q2, q12 + vst1.8 {q8-q9}, [r8]! + veor q11, q7, q13 + vst1.8 {q10-q11}, [r8]! + + vld1.64 {q8}, [r0,:128] @ next round tweak + b .Lxts_dec_done +.align 4 +.Lxts_dec_5: + vst1.64 {q13}, [r0,:128] @ next round tweak + + veor q3, q3, q11 +#ifndef BSAES_ASM_EXTENDED_KEY + add r4, sp, #0x90 @ pass key schedule +#else + add r4, r10, #248 @ pass key schedule +#endif + veor q4, q4, q12 + mov r5, r1 @ pass rounds + mov r0, sp + + bl _bsaes_decrypt8 + + vld1.64 {q8-q9}, [r0,:128]! + vld1.64 {q10-q11}, [r0,:128]! + veor q0, q0, q8 + vld1.64 {q12}, [r0,:128]! + veor q1, q1, q9 + veor q8, q6, q10 + vst1.8 {q0-q1}, [r8]! + veor q9, q4, q11 + veor q10, q2, q12 + vst1.8 {q8-q9}, [r8]! + vst1.8 {q10}, [r8]! + + vld1.64 {q8}, [r0,:128] @ next round tweak + b .Lxts_dec_done +.align 4 +.Lxts_dec_4: + vst1.64 {q12}, [r0,:128] @ next round tweak + + veor q2, q2, q10 +#ifndef BSAES_ASM_EXTENDED_KEY + add r4, sp, #0x90 @ pass key schedule +#else + add r4, r10, #248 @ pass key schedule +#endif + veor q3, q3, q11 + mov r5, r1 @ pass rounds + mov r0, sp + + bl _bsaes_decrypt8 + + vld1.64 {q8-q9}, [r0,:128]! + vld1.64 {q10-q11}, [r0,:128]! + veor q0, q0, q8 + veor q1, q1, q9 + veor q8, q6, q10 + vst1.8 {q0-q1}, [r8]! + veor q9, q4, q11 + vst1.8 {q8-q9}, [r8]! + + vld1.64 {q8}, [r0,:128] @ next round tweak + b .Lxts_dec_done +.align 4 +.Lxts_dec_3: + vst1.64 {q11}, [r0,:128] @ next round tweak + + veor q1, q1, q9 +#ifndef BSAES_ASM_EXTENDED_KEY + add r4, sp, #0x90 @ pass key schedule +#else + add r4, r10, #248 @ pass key schedule +#endif + veor q2, q2, q10 + mov r5, r1 @ pass rounds + mov r0, sp + + bl _bsaes_decrypt8 + + vld1.64 {q8-q9}, [r0,:128]! + vld1.64 {q10}, [r0,:128]! + veor q0, q0, q8 + veor q1, q1, q9 + veor q8, q6, q10 + vst1.8 {q0-q1}, [r8]! + vst1.8 {q8}, [r8]! + + vld1.64 {q8}, [r0,:128] @ next round tweak + b .Lxts_dec_done +.align 4 +.Lxts_dec_2: + vst1.64 {q10}, [r0,:128] @ next round tweak + + veor q0, q0, q8 +#ifndef BSAES_ASM_EXTENDED_KEY + add r4, sp, #0x90 @ pass key schedule +#else + add r4, r10, #248 @ pass key schedule +#endif + veor q1, q1, q9 + mov r5, r1 @ pass rounds + mov r0, sp + + bl _bsaes_decrypt8 + + vld1.64 {q8-q9}, [r0,:128]! + veor q0, q0, q8 + veor q1, q1, q9 + vst1.8 {q0-q1}, [r8]! + + vld1.64 {q8}, [r0,:128] @ next round tweak + b .Lxts_dec_done +.align 4 +.Lxts_dec_1: + mov r0, sp + veor q0, q8 + mov r1, sp + vst1.8 {q0}, [sp,:128] + mov r2, r10 + mov r4, r3 @ preserve fp + mov r5, r2 @ preserve magic + + bl AES_decrypt + + vld1.8 {q0}, [sp,:128] + veor q0, q0, q8 + vst1.8 {q0}, [r8]! + mov r3, r4 + mov r2, r5 + + vmov q8, q9 @ next round tweak + +.Lxts_dec_done: +#ifndef XTS_CHAIN_TWEAK + adds r9, #0x10 + beq .Lxts_dec_ret + + @ calculate one round of extra tweak for the stolen ciphertext + vldmia r2, {q5} + vshr.s64 q6, q8, #63 + vand q6, q6, q5 + vadd.u64 q9, q8, q8 + vswp d13,d12 + veor q9, q9, q6 + + @ perform the final decryption with the last tweak value + vld1.8 {q0}, [r7]! + mov r0, sp + veor q0, q0, q9 + mov r1, sp + vst1.8 {q0}, [sp,:128] + mov r2, r10 + mov r4, r3 @ preserve fp + + bl AES_decrypt + + vld1.8 {q0}, [sp,:128] + veor q0, q0, q9 + vst1.8 {q0}, [r8] + + mov r6, r8 +.Lxts_dec_steal: + ldrb r1, [r8] + ldrb r0, [r7], #1 + strb r1, [r8, #0x10] + strb r0, [r8], #1 + + subs r9, #1 + bhi .Lxts_dec_steal + + vld1.8 {q0}, [r6] + mov r0, sp + veor q0, q8 + mov r1, sp + vst1.8 {q0}, [sp,:128] + mov r2, r10 + + bl AES_decrypt + + vld1.8 {q0}, [sp,:128] + veor q0, q0, q8 + vst1.8 {q0}, [r6] + mov r3, r4 +#endif + +.Lxts_dec_ret: + bic r0, r3, #0xf + vmov.i32 q0, #0 + vmov.i32 q1, #0 +#ifdef XTS_CHAIN_TWEAK + ldr r1, [r3, #0x20+VFP_ABI_FRAME] @ chain tweak +#endif +.Lxts_dec_bzero: @ wipe key schedule [if any] + vstmia sp!, {q0-q1} + cmp sp, r0 + bne .Lxts_dec_bzero + + mov sp, r3 +#ifdef XTS_CHAIN_TWEAK + vst1.8 {q8}, [r1] +#endif + VFP_ABI_POP + ldmia sp!, {r4-r10, pc} @ return + +.size bsaes_xts_decrypt,.-bsaes_xts_decrypt +#endif diff --git a/arch/arm/crypto/aesbs-glue.c b/arch/arm/crypto/aesbs-glue.c new file mode 100644 index 000000000000..4522366da759 --- /dev/null +++ b/arch/arm/crypto/aesbs-glue.c @@ -0,0 +1,434 @@ +/* + * linux/arch/arm/crypto/aesbs-glue.c - glue code for NEON bit sliced AES + * + * Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <asm/neon.h> +#include <crypto/aes.h> +#include <crypto/ablk_helper.h> +#include <crypto/algapi.h> +#include <linux/module.h> + +#include "aes_glue.h" + +#define BIT_SLICED_KEY_MAXSIZE (128 * (AES_MAXNR - 1) + 2 * AES_BLOCK_SIZE) + +struct BS_KEY { + struct AES_KEY rk; + int converted; + u8 __aligned(8) bs[BIT_SLICED_KEY_MAXSIZE]; +} __aligned(8); + +asmlinkage void bsaes_enc_key_convert(u8 out[], struct AES_KEY const *in); +asmlinkage void bsaes_dec_key_convert(u8 out[], struct AES_KEY const *in); + +asmlinkage void bsaes_cbc_encrypt(u8 const in[], u8 out[], u32 bytes, + struct BS_KEY *key, u8 iv[]); + +asmlinkage void bsaes_ctr32_encrypt_blocks(u8 const in[], u8 out[], u32 blocks, + struct BS_KEY *key, u8 const iv[]); + +asmlinkage void bsaes_xts_encrypt(u8 const in[], u8 out[], u32 bytes, + struct BS_KEY *key, u8 tweak[]); + +asmlinkage void bsaes_xts_decrypt(u8 const in[], u8 out[], u32 bytes, + struct BS_KEY *key, u8 tweak[]); + +struct aesbs_cbc_ctx { + struct AES_KEY enc; + struct BS_KEY dec; +}; + +struct aesbs_ctr_ctx { + struct BS_KEY enc; +}; + +struct aesbs_xts_ctx { + struct BS_KEY enc; + struct BS_KEY dec; + struct AES_KEY twkey; +}; + +static int aesbs_cbc_set_key(struct crypto_tfm *tfm, const u8 *in_key, + unsigned int key_len) +{ + struct aesbs_cbc_ctx *ctx = crypto_tfm_ctx(tfm); + int bits = key_len * 8; + + if (private_AES_set_encrypt_key(in_key, bits, &ctx->enc)) { + tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; + return -EINVAL; + } + ctx->dec.rk = ctx->enc; + private_AES_set_decrypt_key(in_key, bits, &ctx->dec.rk); + ctx->dec.converted = 0; + return 0; +} + +static int aesbs_ctr_set_key(struct crypto_tfm *tfm, const u8 *in_key, + unsigned int key_len) +{ + struct aesbs_ctr_ctx *ctx = crypto_tfm_ctx(tfm); + int bits = key_len * 8; + + if (private_AES_set_encrypt_key(in_key, bits, &ctx->enc.rk)) { + tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; + return -EINVAL; + } + ctx->enc.converted = 0; + return 0; +} + +static int aesbs_xts_set_key(struct crypto_tfm *tfm, const u8 *in_key, + unsigned int key_len) +{ + struct aesbs_xts_ctx *ctx = crypto_tfm_ctx(tfm); + int bits = key_len * 4; + + if (private_AES_set_encrypt_key(in_key, bits, &ctx->enc.rk)) { + tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; + return -EINVAL; + } + ctx->dec.rk = ctx->enc.rk; + private_AES_set_decrypt_key(in_key, bits, &ctx->dec.rk); + private_AES_set_encrypt_key(in_key + key_len / 2, bits, &ctx->twkey); + ctx->enc.converted = ctx->dec.converted = 0; + return 0; +} + +static int aesbs_cbc_encrypt(struct blkcipher_desc *desc, + struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) +{ + struct aesbs_cbc_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); + struct blkcipher_walk walk; + int err; + + blkcipher_walk_init(&walk, dst, src, nbytes); + err = blkcipher_walk_virt(desc, &walk); + + while (walk.nbytes) { + u32 blocks = walk.nbytes / AES_BLOCK_SIZE; + u8 *src = walk.src.virt.addr; + + if (walk.dst.virt.addr == walk.src.virt.addr) { + u8 *iv = walk.iv; + + do { + crypto_xor(src, iv, AES_BLOCK_SIZE); + AES_encrypt(src, src, &ctx->enc); + iv = src; + src += AES_BLOCK_SIZE; + } while (--blocks); + memcpy(walk.iv, iv, AES_BLOCK_SIZE); + } else { + u8 *dst = walk.dst.virt.addr; + + do { + crypto_xor(walk.iv, src, AES_BLOCK_SIZE); + AES_encrypt(walk.iv, dst, &ctx->enc); + memcpy(walk.iv, dst, AES_BLOCK_SIZE); + src += AES_BLOCK_SIZE; + dst += AES_BLOCK_SIZE; + } while (--blocks); + } + err = blkcipher_walk_done(desc, &walk, 0); + } + return err; +} + +static int aesbs_cbc_decrypt(struct blkcipher_desc *desc, + struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) +{ + struct aesbs_cbc_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); + struct blkcipher_walk walk; + int err; + + blkcipher_walk_init(&walk, dst, src, nbytes); + err = blkcipher_walk_virt_block(desc, &walk, 8 * AES_BLOCK_SIZE); + + while ((walk.nbytes / AES_BLOCK_SIZE) >= 8) { + kernel_neon_begin(); + bsaes_cbc_encrypt(walk.src.virt.addr, walk.dst.virt.addr, + walk.nbytes, &ctx->dec, walk.iv); + kernel_neon_end(); + err = blkcipher_walk_done(desc, &walk, 0); + } + while (walk.nbytes) { + u32 blocks = walk.nbytes / AES_BLOCK_SIZE; + u8 *dst = walk.dst.virt.addr; + u8 *src = walk.src.virt.addr; + u8 bk[2][AES_BLOCK_SIZE]; + u8 *iv = walk.iv; + + do { + if (walk.dst.virt.addr == walk.src.virt.addr) + memcpy(bk[blocks & 1], src, AES_BLOCK_SIZE); + + AES_decrypt(src, dst, &ctx->dec.rk); + crypto_xor(dst, iv, AES_BLOCK_SIZE); + + if (walk.dst.virt.addr == walk.src.virt.addr) + iv = bk[blocks & 1]; + else + iv = src; + + dst += AES_BLOCK_SIZE; + src += AES_BLOCK_SIZE; + } while (--blocks); + err = blkcipher_walk_done(desc, &walk, 0); + } + return err; +} + +static void inc_be128_ctr(__be32 ctr[], u32 addend) +{ + int i; + + for (i = 3; i >= 0; i--, addend = 1) { + u32 n = be32_to_cpu(ctr[i]) + addend; + + ctr[i] = cpu_to_be32(n); + if (n >= addend) + break; + } +} + +static int aesbs_ctr_encrypt(struct blkcipher_desc *desc, + struct scatterlist *dst, struct scatterlist *src, + unsigned int nbytes) +{ + struct aesbs_ctr_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); + struct blkcipher_walk walk; + u32 blocks; + int err; + + blkcipher_walk_init(&walk, dst, src, nbytes); + err = blkcipher_walk_virt_block(desc, &walk, 8 * AES_BLOCK_SIZE); + + while ((blocks = walk.nbytes / AES_BLOCK_SIZE)) { + u32 tail = walk.nbytes % AES_BLOCK_SIZE; + __be32 *ctr = (__be32 *)walk.iv; + u32 headroom = UINT_MAX - be32_to_cpu(ctr[3]); + + /* avoid 32 bit counter overflow in the NEON code */ + if (unlikely(headroom < blocks)) { + blocks = headroom + 1; + tail = walk.nbytes - blocks * AES_BLOCK_SIZE; + } + kernel_neon_begin(); + bsaes_ctr32_encrypt_blocks(walk.src.virt.addr, + walk.dst.virt.addr, blocks, + &ctx->enc, walk.iv); + kernel_neon_end(); + inc_be128_ctr(ctr, blocks); + + nbytes -= blocks * AES_BLOCK_SIZE; + if (nbytes && nbytes == tail && nbytes <= AES_BLOCK_SIZE) + break; + + err = blkcipher_walk_done(desc, &walk, tail); + } + if (walk.nbytes) { + u8 *tdst = walk.dst.virt.addr + blocks * AES_BLOCK_SIZE; + u8 *tsrc = walk.src.virt.addr + blocks * AES_BLOCK_SIZE; + u8 ks[AES_BLOCK_SIZE]; + + AES_encrypt(walk.iv, ks, &ctx->enc.rk); + if (tdst != tsrc) + memcpy(tdst, tsrc, nbytes); + crypto_xor(tdst, ks, nbytes); + err = blkcipher_walk_done(desc, &walk, 0); + } + return err; +} + +static int aesbs_xts_encrypt(struct blkcipher_desc *desc, + struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) +{ + struct aesbs_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); + struct blkcipher_walk walk; + int err; + + blkcipher_walk_init(&walk, dst, src, nbytes); + err = blkcipher_walk_virt_block(desc, &walk, 8 * AES_BLOCK_SIZE); + + /* generate the initial tweak */ + AES_encrypt(walk.iv, walk.iv, &ctx->twkey); + + while (walk.nbytes) { + kernel_neon_begin(); + bsaes_xts_encrypt(walk.src.virt.addr, walk.dst.virt.addr, + walk.nbytes, &ctx->enc, walk.iv); + kernel_neon_end(); + err = blkcipher_walk_done(desc, &walk, 0); + } + return err; +} + +static int aesbs_xts_decrypt(struct blkcipher_desc *desc, + struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) +{ + struct aesbs_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); + struct blkcipher_walk walk; + int err; + + blkcipher_walk_init(&walk, dst, src, nbytes); + err = blkcipher_walk_virt_block(desc, &walk, 8 * AES_BLOCK_SIZE); + + /* generate the initial tweak */ + AES_encrypt(walk.iv, walk.iv, &ctx->twkey); + + while (walk.nbytes) { + kernel_neon_begin(); + bsaes_xts_decrypt(walk.src.virt.addr, walk.dst.virt.addr, + walk.nbytes, &ctx->dec, walk.iv); + kernel_neon_end(); + err = blkcipher_walk_done(desc, &walk, 0); + } + return err; +} + +static struct crypto_alg aesbs_algs[] = { { + .cra_name = "__cbc-aes-neonbs", + .cra_driver_name = "__driver-cbc-aes-neonbs", + .cra_priority = 0, + .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, + .cra_blocksize = AES_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct aesbs_cbc_ctx), + .cra_alignmask = 7, + .cra_type = &crypto_blkcipher_type, + .cra_module = THIS_MODULE, + .cra_blkcipher = { + .min_keysize = AES_MIN_KEY_SIZE, + .max_keysize = AES_MAX_KEY_SIZE, + .ivsize = AES_BLOCK_SIZE, + .setkey = aesbs_cbc_set_key, + .encrypt = aesbs_cbc_encrypt, + .decrypt = aesbs_cbc_decrypt, + }, +}, { + .cra_name = "__ctr-aes-neonbs", + .cra_driver_name = "__driver-ctr-aes-neonbs", + .cra_priority = 0, + .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, + .cra_blocksize = 1, + .cra_ctxsize = sizeof(struct aesbs_ctr_ctx), + .cra_alignmask = 7, + .cra_type = &crypto_blkcipher_type, + .cra_module = THIS_MODULE, + .cra_blkcipher = { + .min_keysize = AES_MIN_KEY_SIZE, + .max_keysize = AES_MAX_KEY_SIZE, + .ivsize = AES_BLOCK_SIZE, + .setkey = aesbs_ctr_set_key, + .encrypt = aesbs_ctr_encrypt, + .decrypt = aesbs_ctr_encrypt, + }, +}, { + .cra_name = "__xts-aes-neonbs", + .cra_driver_name = "__driver-xts-aes-neonbs", + .cra_priority = 0, + .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, + .cra_blocksize = AES_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct aesbs_xts_ctx), + .cra_alignmask = 7, + .cra_type = &crypto_blkcipher_type, + .cra_module = THIS_MODULE, + .cra_blkcipher = { + .min_keysize = 2 * AES_MIN_KEY_SIZE, + .max_keysize = 2 * AES_MAX_KEY_SIZE, + .ivsize = AES_BLOCK_SIZE, + .setkey = aesbs_xts_set_key, + .encrypt = aesbs_xts_encrypt, + .decrypt = aesbs_xts_decrypt, + }, +}, { + .cra_name = "cbc(aes)", + .cra_driver_name = "cbc-aes-neonbs", + .cra_priority = 300, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER|CRYPTO_ALG_ASYNC, + .cra_blocksize = AES_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct async_helper_ctx), + .cra_alignmask = 7, + .cra_type = &crypto_ablkcipher_type, + .cra_module = THIS_MODULE, + .cra_init = ablk_init, + .cra_exit = ablk_exit, + .cra_ablkcipher = { + .min_keysize = AES_MIN_KEY_SIZE, + .max_keysize = AES_MAX_KEY_SIZE, + .ivsize = AES_BLOCK_SIZE, + .setkey = ablk_set_key, + .encrypt = __ablk_encrypt, + .decrypt = ablk_decrypt, + } +}, { + .cra_name = "ctr(aes)", + .cra_driver_name = "ctr-aes-neonbs", + .cra_priority = 300, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER|CRYPTO_ALG_ASYNC, + .cra_blocksize = 1, + .cra_ctxsize = sizeof(struct async_helper_ctx), + .cra_alignmask = 7, + .cra_type = &crypto_ablkcipher_type, + .cra_module = THIS_MODULE, + .cra_init = ablk_init, + .cra_exit = ablk_exit, + .cra_ablkcipher = { + .min_keysize = AES_MIN_KEY_SIZE, + .max_keysize = AES_MAX_KEY_SIZE, + .ivsize = AES_BLOCK_SIZE, + .setkey = ablk_set_key, + .encrypt = ablk_encrypt, + .decrypt = ablk_decrypt, + } +}, { + .cra_name = "xts(aes)", + .cra_driver_name = "xts-aes-neonbs", + .cra_priority = 300, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER|CRYPTO_ALG_ASYNC, + .cra_blocksize = AES_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct async_helper_ctx), + .cra_alignmask = 7, + .cra_type = &crypto_ablkcipher_type, + .cra_module = THIS_MODULE, + .cra_init = ablk_init, + .cra_exit = ablk_exit, + .cra_ablkcipher = { + .min_keysize = 2 * AES_MIN_KEY_SIZE, + .max_keysize = 2 * AES_MAX_KEY_SIZE, + .ivsize = AES_BLOCK_SIZE, + .setkey = ablk_set_key, + .encrypt = ablk_encrypt, + .decrypt = ablk_decrypt, + } +} }; + +static int __init aesbs_mod_init(void) +{ + if (!cpu_has_neon()) + return -ENODEV; + + return crypto_register_algs(aesbs_algs, ARRAY_SIZE(aesbs_algs)); +} + +static void __exit aesbs_mod_exit(void) +{ + crypto_unregister_algs(aesbs_algs, ARRAY_SIZE(aesbs_algs)); +} + +module_init(aesbs_mod_init); +module_exit(aesbs_mod_exit); + +MODULE_DESCRIPTION("Bit sliced AES in CBC/CTR/XTS modes using NEON"); +MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>"); +MODULE_LICENSE("GPL"); diff --git a/arch/arm/crypto/bsaes-armv7.pl b/arch/arm/crypto/bsaes-armv7.pl new file mode 100644 index 000000000000..f3d96d932573 --- /dev/null +++ b/arch/arm/crypto/bsaes-armv7.pl @@ -0,0 +1,2467 @@ +#!/usr/bin/env perl + +# ==================================================================== +# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# +# Specific modes and adaptation for Linux kernel by Ard Biesheuvel +# <ard.biesheuvel@linaro.org>. Permission to use under GPL terms is +# granted. +# ==================================================================== + +# Bit-sliced AES for ARM NEON +# +# February 2012. +# +# This implementation is direct adaptation of bsaes-x86_64 module for +# ARM NEON. Except that this module is endian-neutral [in sense that +# it can be compiled for either endianness] by courtesy of vld1.8's +# neutrality. Initial version doesn't implement interface to OpenSSL, +# only low-level primitives and unsupported entry points, just enough +# to collect performance results, which for Cortex-A8 core are: +# +# encrypt 19.5 cycles per byte processed with 128-bit key +# decrypt 22.1 cycles per byte processed with 128-bit key +# key conv. 440 cycles per 128-bit key/0.18 of 8x block +# +# Snapdragon S4 encrypts byte in 17.6 cycles and decrypts in 19.7, +# which is [much] worse than anticipated (for further details see +# http://www.openssl.org/~appro/Snapdragon-S4.html). +# +# Cortex-A15 manages in 14.2/16.1 cycles [when integer-only code +# manages in 20.0 cycles]. +# +# When comparing to x86_64 results keep in mind that NEON unit is +# [mostly] single-issue and thus can't [fully] benefit from +# instruction-level parallelism. And when comparing to aes-armv4 +# results keep in mind key schedule conversion overhead (see +# bsaes-x86_64.pl for further details)... +# +# <appro@openssl.org> + +# April-August 2013 +# +# Add CBC, CTR and XTS subroutines, adapt for kernel use. +# +# <ard.biesheuvel@linaro.org> + +while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {} +open STDOUT,">$output"; + +my ($inp,$out,$len,$key)=("r0","r1","r2","r3"); +my @XMM=map("q$_",(0..15)); + +{ +my ($key,$rounds,$const)=("r4","r5","r6"); + +sub Dlo() { shift=~m|q([1]?[0-9])|?"d".($1*2):""; } +sub Dhi() { shift=~m|q([1]?[0-9])|?"d".($1*2+1):""; } + +sub Sbox { +# input in lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb +# output in lsb > [b0, b1, b4, b6, b3, b7, b2, b5] < msb +my @b=@_[0..7]; +my @t=@_[8..11]; +my @s=@_[12..15]; + &InBasisChange (@b); + &Inv_GF256 (@b[6,5,0,3,7,1,4,2],@t,@s); + &OutBasisChange (@b[7,1,4,2,6,5,0,3]); +} + +sub InBasisChange { +# input in lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb +# output in lsb > [b6, b5, b0, b3, b7, b1, b4, b2] < msb +my @b=@_[0..7]; +$code.=<<___; + veor @b[2], @b[2], @b[1] + veor @b[5], @b[5], @b[6] + veor @b[3], @b[3], @b[0] + veor @b[6], @b[6], @b[2] + veor @b[5], @b[5], @b[0] + + veor @b[6], @b[6], @b[3] + veor @b[3], @b[3], @b[7] + veor @b[7], @b[7], @b[5] + veor @b[3], @b[3], @b[4] + veor @b[4], @b[4], @b[5] + + veor @b[2], @b[2], @b[7] + veor @b[3], @b[3], @b[1] + veor @b[1], @b[1], @b[5] +___ +} + +sub OutBasisChange { +# input in lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb +# output in lsb > [b6, b1, b2, b4, b7, b0, b3, b5] < msb +my @b=@_[0..7]; +$code.=<<___; + veor @b[0], @b[0], @b[6] + veor @b[1], @b[1], @b[4] + veor @b[4], @b[4], @b[6] + veor @b[2], @b[2], @b[0] + veor @b[6], @b[6], @b[1] + + veor @b[1], @b[1], @b[5] + veor @b[5], @b[5], @b[3] + veor @b[3], @b[3], @b[7] + veor @b[7], @b[7], @b[5] + veor @b[2], @b[2], @b[5] + + veor @b[4], @b[4], @b[7] +___ +} + +sub InvSbox { +# input in lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb +# output in lsb > [b0, b1, b6, b4, b2, b7, b3, b5] < msb +my @b=@_[0..7]; +my @t=@_[8..11]; +my @s=@_[12..15]; + &InvInBasisChange (@b); + &Inv_GF256 (@b[5,1,2,6,3,7,0,4],@t,@s); + &InvOutBasisChange (@b[3,7,0,4,5,1,2,6]); +} + +sub InvInBasisChange { # OutBasisChange in reverse (with twist) +my @b=@_[5,1,2,6,3,7,0,4]; +$code.=<<___ + veor @b[1], @b[1], @b[7] + veor @b[4], @b[4], @b[7] + + veor @b[7], @b[7], @b[5] + veor @b[1], @b[1], @b[3] + veor @b[2], @b[2], @b[5] + veor @b[3], @b[3], @b[7] + + veor @b[6], @b[6], @b[1] + veor @b[2], @b[2], @b[0] + veor @b[5], @b[5], @b[3] + veor @b[4], @b[4], @b[6] + veor @b[0], @b[0], @b[6] + veor @b[1], @b[1], @b[4] +___ +} + +sub InvOutBasisChange { # InBasisChange in reverse +my @b=@_[2,5,7,3,6,1,0,4]; +$code.=<<___; + veor @b[1], @b[1], @b[5] + veor @b[2], @b[2], @b[7] + + veor @b[3], @b[3], @b[1] + veor @b[4], @b[4], @b[5] + veor @b[7], @b[7], @b[5] + veor @b[3], @b[3], @b[4] + veor @b[5], @b[5], @b[0] + veor @b[3], @b[3], @b[7] + veor @b[6], @b[6], @b[2] + veor @b[2], @b[2], @b[1] + veor @b[6], @b[6], @b[3] + + veor @b[3], @b[3], @b[0] + veor @b[5], @b[5], @b[6] +___ +} + +sub Mul_GF4 { +#;************************************************************* +#;* Mul_GF4: Input x0-x1,y0-y1 Output x0-x1 Temp t0 (8) * +#;************************************************************* +my ($x0,$x1,$y0,$y1,$t0,$t1)=@_; +$code.=<<___; + veor $t0, $y0, $y1 + vand $t0, $t0, $x0 + veor $x0, $x0, $x1 + vand $t1, $x1, $y0 + vand $x0, $x0, $y1 + veor $x1, $t1, $t0 + veor $x0, $x0, $t1 +___ +} + +sub Mul_GF4_N { # not used, see next subroutine +# multiply and scale by N +my ($x0,$x1,$y0,$y1,$t0)=@_; +$code.=<<___; + veor $t0, $y0, $y1 + vand $t0, $t0, $x0 + veor $x0, $x0, $x1 + vand $x1, $x1, $y0 + vand $x0, $x0, $y1 + veor $x1, $x1, $x0 + veor $x0, $x0, $t0 +___ +} + +sub Mul_GF4_N_GF4 { +# interleaved Mul_GF4_N and Mul_GF4 +my ($x0,$x1,$y0,$y1,$t0, + $x2,$x3,$y2,$y3,$t1)=@_; +$code.=<<___; + veor $t0, $y0, $y1 + veor $t1, $y2, $y3 + vand $t0, $t0, $x0 + vand $t1, $t1, $x2 + veor $x0, $x0, $x1 + veor $x2, $x2, $x3 + vand $x1, $x1, $y0 + vand $x3, $x3, $y2 + vand $x0, $x0, $y1 + vand $x2, $x2, $y3 + veor $x1, $x1, $x0 + veor $x2, $x2, $x3 + veor $x0, $x0, $t0 + veor $x3, $x3, $t1 +___ +} +sub Mul_GF16_2 { +my @x=@_[0..7]; +my @y=@_[8..11]; +my @t=@_[12..15]; +$code.=<<___; + veor @t[0], @x[0], @x[2] + veor @t[1], @x[1], @x[3] +___ + &Mul_GF4 (@x[0], @x[1], @y[0], @y[1], @t[2..3]); +$code.=<<___; + veor @y[0], @y[0], @y[2] + veor @y[1], @y[1], @y[3] +___ + Mul_GF4_N_GF4 (@t[0], @t[1], @y[0], @y[1], @t[3], + @x[2], @x[3], @y[2], @y[3], @t[2]); +$code.=<<___; + veor @x[0], @x[0], @t[0] + veor @x[2], @x[2], @t[0] + veor @x[1], @x[1], @t[1] + veor @x[3], @x[3], @t[1] + + veor @t[0], @x[4], @x[6] + veor @t[1], @x[5], @x[7] +___ + &Mul_GF4_N_GF4 (@t[0], @t[1], @y[0], @y[1], @t[3], + @x[6], @x[7], @y[2], @y[3], @t[2]); +$code.=<<___; + veor @y[0], @y[0], @y[2] + veor @y[1], @y[1], @y[3] +___ + &Mul_GF4 (@x[4], @x[5], @y[0], @y[1], @t[2..3]); +$code.=<<___; + veor @x[4], @x[4], @t[0] + veor @x[6], @x[6], @t[0] + veor @x[5], @x[5], @t[1] + veor @x[7], @x[7], @t[1] +___ +} +sub Inv_GF256 { +#;******************************************************************** +#;* Inv_GF256: Input x0-x7 Output x0-x7 Temp t0-t3,s0-s3 (144) * +#;******************************************************************** +my @x=@_[0..7]; +my @t=@_[8..11]; +my @s=@_[12..15]; +# direct optimizations from hardware +$code.=<<___; + veor @t[3], @x[4], @x[6] + veor @t[2], @x[5], @x[7] + veor @t[1], @x[1], @x[3] + veor @s[1], @x[7], @x[6] + vmov @t[0], @t[2] + veor @s[0], @x[0], @x[2] + + vorr @t[2], @t[2], @t[1] + veor @s[3], @t[3], @t[0] + vand @s[2], @t[3], @s[0] + vorr @t[3], @t[3], @s[0] + veor @s[0], @s[0], @t[1] + vand @t[0], @t[0], @t[1] + veor @t[1], @x[3], @x[2] + vand @s[3], @s[3], @s[0] + vand @s[1], @s[1], @t[1] + veor @t[1], @x[4], @x[5] + veor @s[0], @x[1], @x[0] + veor @t[3], @t[3], @s[1] + veor @t[2], @t[2], @s[1] + vand @s[1], @t[1], @s[0] + vorr @t[1], @t[1], @s[0] + veor @t[3], @t[3], @s[3] + veor @t[0], @t[0], @s[1] + veor @t[2], @t[2], @s[2] + veor @t[1], @t[1], @s[3] + veor @t[0], @t[0], @s[2] + vand @s[0], @x[7], @x[3] + veor @t[1], @t[1], @s[2] + vand @s[1], @x[6], @x[2] + vand @s[2], @x[5], @x[1] + vorr @s[3], @x[4], @x[0] + veor @t[3], @t[3], @s[0] + veor @t[1], @t[1], @s[2] + veor @t[0], @t[0], @s[3] + veor @t[2], @t[2], @s[1] + + @ Inv_GF16 \t0, \t1, \t2, \t3, \s0, \s1, \s2, \s3 + + @ new smaller inversion + + vand @s[2], @t[3], @t[1] + vmov @s[0], @t[0] + + veor @s[1], @t[2], @s[2] + veor @s[3], @t[0], @s[2] + veor @s[2], @t[0], @s[2] @ @s[2]=@s[3] + + vbsl @s[1], @t[1], @t[0] + vbsl @s[3], @t[3], @t[2] + veor @t[3], @t[3], @t[2] + + vbsl @s[0], @s[1], @s[2] + vbsl @t[0], @s[2], @s[1] + + vand @s[2], @s[0], @s[3] + veor @t[1], @t[1], @t[0] + + veor @s[2], @s[2], @t[3] +___ +# output in s3, s2, s1, t1 + +# Mul_GF16_2 \x0, \x1, \x2, \x3, \x4, \x5, \x6, \x7, \t2, \t3, \t0, \t1, \s0, \s1, \s2, \s3 + +# Mul_GF16_2 \x0, \x1, \x2, \x3, \x4, \x5, \x6, \x7, \s3, \s2, \s1, \t1, \s0, \t0, \t2, \t3 + &Mul_GF16_2(@x,@s[3,2,1],@t[1],@s[0],@t[0,2,3]); + +### output msb > [x3,x2,x1,x0,x7,x6,x5,x4] < lsb +} + +# AES linear components + +sub ShiftRows { +my @x=@_[0..7]; +my @t=@_[8..11]; +my $mask=pop; +$code.=<<___; + vldmia $key!, {@t[0]-@t[3]} + veor @t[0], @t[0], @x[0] + veor @t[1], @t[1], @x[1] + vtbl.8 `&Dlo(@x[0])`, {@t[0]}, `&Dlo($mask)` + vtbl.8 `&Dhi(@x[0])`, {@t[0]}, `&Dhi($mask)` + vldmia $key!, {@t[0]} + veor @t[2], @t[2], @x[2] + vtbl.8 `&Dlo(@x[1])`, {@t[1]}, `&Dlo($mask)` + vtbl.8 `&Dhi(@x[1])`, {@t[1]}, `&Dhi($mask)` + vldmia $key!, {@t[1]} + veor @t[3], @t[3], @x[3] + vtbl.8 `&Dlo(@x[2])`, {@t[2]}, `&Dlo($mask)` + vtbl.8 `&Dhi(@x[2])`, {@t[2]}, `&Dhi($mask)` + vldmia $key!, {@t[2]} + vtbl.8 `&Dlo(@x[3])`, {@t[3]}, `&Dlo($mask)` + vtbl.8 `&Dhi(@x[3])`, {@t[3]}, `&Dhi($mask)` + vldmia $key!, {@t[3]} + veor @t[0], @t[0], @x[4] + veor @t[1], @t[1], @x[5] + vtbl.8 `&Dlo(@x[4])`, {@t[0]}, `&Dlo($mask)` + vtbl.8 `&Dhi(@x[4])`, {@t[0]}, `&Dhi($mask)` + veor @t[2], @t[2], @x[6] + vtbl.8 `&Dlo(@x[5])`, {@t[1]}, `&Dlo($mask)` + vtbl.8 `&Dhi(@x[5])`, {@t[1]}, `&Dhi($mask)` + veor @t[3], @t[3], @x[7] + vtbl.8 `&Dlo(@x[6])`, {@t[2]}, `&Dlo($mask)` + vtbl.8 `&Dhi(@x[6])`, {@t[2]}, `&Dhi($mask)` + vtbl.8 `&Dlo(@x[7])`, {@t[3]}, `&Dlo($mask)` + vtbl.8 `&Dhi(@x[7])`, {@t[3]}, `&Dhi($mask)` +___ +} + +sub MixColumns { +# modified to emit output in order suitable for feeding back to aesenc[last] +my @x=@_[0..7]; +my @t=@_[8..15]; +my $inv=@_[16]; # optional +$code.=<<___; + vext.8 @t[0], @x[0], @x[0], #12 @ x0 <<< 32 + vext.8 @t[1], @x[1], @x[1], #12 + veor @x[0], @x[0], @t[0] @ x0 ^ (x0 <<< 32) + vext.8 @t[2], @x[2], @x[2], #12 + veor @x[1], @x[1], @t[1] + vext.8 @t[3], @x[3], @x[3], #12 + veor @x[2], @x[2], @t[2] + vext.8 @t[4], @x[4], @x[4], #12 + veor @x[3], @x[3], @t[3] + vext.8 @t[5], @x[5], @x[5], #12 + veor @x[4], @x[4], @t[4] + vext.8 @t[6], @x[6], @x[6], #12 + veor @x[5], @x[5], @t[5] + vext.8 @t[7], @x[7], @x[7], #12 + veor @x[6], @x[6], @t[6] + + veor @t[1], @t[1], @x[0] + veor @x[7], @x[7], @t[7] + vext.8 @x[0], @x[0], @x[0], #8 @ (x0 ^ (x0 <<< 32)) <<< 64) + veor @t[2], @t[2], @x[1] + veor @t[0], @t[0], @x[7] + veor @t[1], @t[1], @x[7] + vext.8 @x[1], @x[1], @x[1], #8 + veor @t[5], @t[5], @x[4] + veor @x[0], @x[0], @t[0] + veor @t[6], @t[6], @x[5] + veor @x[1], @x[1], @t[1] + vext.8 @t[0], @x[4], @x[4], #8 + veor @t[4], @t[4], @x[3] + vext.8 @t[1], @x[5], @x[5], #8 + veor @t[7], @t[7], @x[6] + vext.8 @x[4], @x[3], @x[3], #8 + veor @t[3], @t[3], @x[2] + vext.8 @x[5], @x[7], @x[7], #8 + veor @t[4], @t[4], @x[7] + vext.8 @x[3], @x[6], @x[6], #8 + veor @t[3], @t[3], @x[7] + vext.8 @x[6], @x[2], @x[2], #8 + veor @x[7], @t[1], @t[5] +___ +$code.=<<___ if (!$inv); + veor @x[2], @t[0], @t[4] + veor @x[4], @x[4], @t[3] + veor @x[5], @x[5], @t[7] + veor @x[3], @x[3], @t[6] + @ vmov @x[2], @t[0] + veor @x[6], @x[6], @t[2] + @ vmov @x[7], @t[1] +___ +$code.=<<___ if ($inv); + veor @t[3], @t[3], @x[4] + veor @x[5], @x[5], @t[7] + veor @x[2], @x[3], @t[6] + veor @x[3], @t[0], @t[4] + veor @x[4], @x[6], @t[2] + vmov @x[6], @t[3] + @ vmov @x[7], @t[1] +___ +} + +sub InvMixColumns_orig { +my @x=@_[0..7]; +my @t=@_[8..15]; + +$code.=<<___; + @ multiplication by 0x0e + vext.8 @t[7], @x[7], @x[7], #12 + vmov @t[2], @x[2] + veor @x[2], @x[2], @x[5] @ 2 5 + veor @x[7], @x[7], @x[5] @ 7 5 + vext.8 @t[0], @x[0], @x[0], #12 + vmov @t[5], @x[5] + veor @x[5], @x[5], @x[0] @ 5 0 [1] + veor @x[0], @x[0], @x[1] @ 0 1 + vext.8 @t[1], @x[1], @x[1], #12 + veor @x[1], @x[1], @x[2] @ 1 25 + veor @x[0], @x[0], @x[6] @ 01 6 [2] + vext.8 @t[3], @x[3], @x[3], #12 + veor @x[1], @x[1], @x[3] @ 125 3 [4] + veor @x[2], @x[2], @x[0] @ 25 016 [3] + veor @x[3], @x[3], @x[7] @ 3 75 + veor @x[7], @x[7], @x[6] @ 75 6 [0] + vext.8 @t[6], @x[6], @x[6], #12 + vmov @t[4], @x[4] + veor @x[6], @x[6], @x[4] @ 6 4 + veor @x[4], @x[4], @x[3] @ 4 375 [6] + veor @x[3], @x[3], @x[7] @ 375 756=36 + veor @x[6], @x[6], @t[5] @ 64 5 [7] + veor @x[3], @x[3], @t[2] @ 36 2 + vext.8 @t[5], @t[5], @t[5], #12 + veor @x[3], @x[3], @t[4] @ 362 4 [5] +___ + my @y = @x[7,5,0,2,1,3,4,6]; +$code.=<<___; + @ multiplication by 0x0b + veor @y[1], @y[1], @y[0] + veor @y[0], @y[0], @t[0] + vext.8 @t[2], @t[2], @t[2], #12 + veor @y[1], @y[1], @t[1] + veor @y[0], @y[0], @t[5] + vext.8 @t[4], @t[4], @t[4], #12 + veor @y[1], @y[1], @t[6] + veor @y[0], @y[0], @t[7] + veor @t[7], @t[7], @t[6] @ clobber t[7] + + veor @y[3], @y[3], @t[0] + veor @y[1], @y[1], @y[0] + vext.8 @t[0], @t[0], @t[0], #12 + veor @y[2], @y[2], @t[1] + veor @y[4], @y[4], @t[1] + vext.8 @t[1], @t[1], @t[1], #12 + veor @y[2], @y[2], @t[2] + veor @y[3], @y[3], @t[2] + veor @y[5], @y[5], @t[2] + veor @y[2], @y[2], @t[7] + vext.8 @t[2], @t[2], @t[2], #12 + veor @y[3], @y[3], @t[3] + veor @y[6], @y[6], @t[3] + veor @y[4], @y[4], @t[3] + veor @y[7], @y[7], @t[4] + vext.8 @t[3], @t[3], @t[3], #12 + veor @y[5], @y[5], @t[4] + veor @y[7], @y[7], @t[7] + veor @t[7], @t[7], @t[5] @ clobber t[7] even more + veor @y[3], @y[3], @t[5] + veor @y[4], @y[4], @t[4] + + veor @y[5], @y[5], @t[7] + vext.8 @t[4], @t[4], @t[4], #12 + veor @y[6], @y[6], @t[7] + veor @y[4], @y[4], @t[7] + + veor @t[7], @t[7], @t[5] + vext.8 @t[5], @t[5], @t[5], #12 + + @ multiplication by 0x0d + veor @y[4], @y[4], @y[7] + veor @t[7], @t[7], @t[6] @ restore t[7] + veor @y[7], @y[7], @t[4] + vext.8 @t[6], @t[6], @t[6], #12 + veor @y[2], @y[2], @t[0] + veor @y[7], @y[7], @t[5] + vext.8 @t[7], @t[7], @t[7], #12 + veor @y[2], @y[2], @t[2] + + veor @y[3], @y[3], @y[1] + veor @y[1], @y[1], @t[1] + veor @y[0], @y[0], @t[0] + veor @y[3], @y[3], @t[0] + veor @y[1], @y[1], @t[5] + veor @y[0], @y[0], @t[5] + vext.8 @t[0], @t[0], @t[0], #12 + veor @y[1], @y[1], @t[7] + veor @y[0], @y[0], @t[6] + veor @y[3], @y[3], @y[1] + veor @y[4], @y[4], @t[1] + vext.8 @t[1], @t[1], @t[1], #12 + + veor @y[7], @y[7], @t[7] + veor @y[4], @y[4], @t[2] + veor @y[5], @y[5], @t[2] + veor @y[2], @y[2], @t[6] + veor @t[6], @t[6], @t[3] @ clobber t[6] + vext.8 @t[2], @t[2], @t[2], #12 + veor @y[4], @y[4], @y[7] + veor @y[3], @y[3], @t[6] + + veor @y[6], @y[6], @t[6] + veor @y[5], @y[5], @t[5] + vext.8 @t[5], @t[5], @t[5], #12 + veor @y[6], @y[6], @t[4] + vext.8 @t[4], @t[4], @t[4], #12 + veor @y[5], @y[5], @t[6] + veor @y[6], @y[6], @t[7] + vext.8 @t[7], @t[7], @t[7], #12 + veor @t[6], @t[6], @t[3] @ restore t[6] + vext.8 @t[3], @t[3], @t[3], #12 + + @ multiplication by 0x09 + veor @y[4], @y[4], @y[1] + veor @t[1], @t[1], @y[1] @ t[1]=y[1] + veor @t[0], @t[0], @t[5] @ clobber t[0] + vext.8 @t[6], @t[6], @t[6], #12 + veor @t[1], @t[1], @t[5] + veor @y[3], @y[3], @t[0] + veor @t[0], @t[0], @y[0] @ t[0]=y[0] + veor @t[1], @t[1], @t[6] + veor @t[6], @t[6], @t[7] @ clobber t[6] + veor @y[4], @y[4], @t[1] + veor @y[7], @y[7], @t[4] + veor @y[6], @y[6], @t[3] + veor @y[5], @y[5], @t[2] + veor @t[4], @t[4], @y[4] @ t[4]=y[4] + veor @t[3], @t[3], @y[3] @ t[3]=y[3] + veor @t[5], @t[5], @y[5] @ t[5]=y[5] + veor @t[2], @t[2], @y[2] @ t[2]=y[2] + veor @t[3], @t[3], @t[7] + veor @XMM[5], @t[5], @t[6] + veor @XMM[6], @t[6], @y[6] @ t[6]=y[6] + veor @XMM[2], @t[2], @t[6] + veor @XMM[7], @t[7], @y[7] @ t[7]=y[7] + + vmov @XMM[0], @t[0] + vmov @XMM[1], @t[1] + @ vmov @XMM[2], @t[2] + vmov @XMM[3], @t[3] + vmov @XMM[4], @t[4] + @ vmov @XMM[5], @t[5] + @ vmov @XMM[6], @t[6] + @ vmov @XMM[7], @t[7] +___ +} + +sub InvMixColumns { +my @x=@_[0..7]; +my @t=@_[8..15]; + +# Thanks to Jussi Kivilinna for providing pointer to +# +# | 0e 0b 0d 09 | | 02 03 01 01 | | 05 00 04 00 | +# | 09 0e 0b 0d | = | 01 02 03 01 | x | 00 05 00 04 | +# | 0d 09 0e 0b | | 01 01 02 03 | | 04 00 05 00 | +# | 0b 0d 09 0e | | 03 01 01 02 | | 00 04 00 05 | + +$code.=<<___; + @ multiplication by 0x05-0x00-0x04-0x00 + vext.8 @t[0], @x[0], @x[0], #8 + vext.8 @t[6], @x[6], @x[6], #8 + vext.8 @t[7], @x[7], @x[7], #8 + veor @t[0], @t[0], @x[0] + vext.8 @t[1], @x[1], @x[1], #8 + veor @t[6], @t[6], @x[6] + vext.8 @t[2], @x[2], @x[2], #8 + veor @t[7], @t[7], @x[7] + vext.8 @t[3], @x[3], @x[3], #8 + veor @t[1], @t[1], @x[1] + vext.8 @t[4], @x[4], @x[4], #8 + veor @t[2], @t[2], @x[2] + vext.8 @t[5], @x[5], @x[5], #8 + veor @t[3], @t[3], @x[3] + veor @t[4], @t[4], @x[4] + veor @t[5], @t[5], @x[5] + + veor @x[0], @x[0], @t[6] + veor @x[1], @x[1], @t[6] + veor @x[2], @x[2], @t[0] + veor @x[4], @x[4], @t[2] + veor @x[3], @x[3], @t[1] + veor @x[1], @x[1], @t[7] + veor @x[2], @x[2], @t[7] + veor @x[4], @x[4], @t[6] + veor @x[5], @x[5], @t[3] + veor @x[3], @x[3], @t[6] + veor @x[6], @x[6], @t[4] + veor @x[4], @x[4], @t[7] + veor @x[5], @x[5], @t[7] + veor @x[7], @x[7], @t[5] +___ + &MixColumns (@x,@t,1); # flipped 2<->3 and 4<->6 +} + +sub swapmove { +my ($a,$b,$n,$mask,$t)=@_; +$code.=<<___; + vshr.u64 $t, $b, #$n + veor $t, $t, $a + vand $t, $t, $mask + veor $a, $a, $t + vshl.u64 $t, $t, #$n + veor $b, $b, $t +___ +} +sub swapmove2x { +my ($a0,$b0,$a1,$b1,$n,$mask,$t0,$t1)=@_; +$code.=<<___; + vshr.u64 $t0, $b0, #$n + vshr.u64 $t1, $b1, #$n + veor $t0, $t0, $a0 + veor $t1, $t1, $a1 + vand $t0, $t0, $mask + vand $t1, $t1, $mask + veor $a0, $a0, $t0 + vshl.u64 $t0, $t0, #$n + veor $a1, $a1, $t1 + vshl.u64 $t1, $t1, #$n + veor $b0, $b0, $t0 + veor $b1, $b1, $t1 +___ +} + +sub bitslice { +my @x=reverse(@_[0..7]); +my ($t0,$t1,$t2,$t3)=@_[8..11]; +$code.=<<___; + vmov.i8 $t0,#0x55 @ compose .LBS0 + vmov.i8 $t1,#0x33 @ compose .LBS1 +___ + &swapmove2x(@x[0,1,2,3],1,$t0,$t2,$t3); + &swapmove2x(@x[4,5,6,7],1,$t0,$t2,$t3); +$code.=<<___; + vmov.i8 $t0,#0x0f @ compose .LBS2 +___ + &swapmove2x(@x[0,2,1,3],2,$t1,$t2,$t3); + &swapmove2x(@x[4,6,5,7],2,$t1,$t2,$t3); + + &swapmove2x(@x[0,4,1,5],4,$t0,$t2,$t3); + &swapmove2x(@x[2,6,3,7],4,$t0,$t2,$t3); +} + +$code.=<<___; +#ifndef __KERNEL__ +# include "arm_arch.h" + +# define VFP_ABI_PUSH vstmdb sp!,{d8-d15} +# define VFP_ABI_POP vldmia sp!,{d8-d15} +# define VFP_ABI_FRAME 0x40 +#else +# define VFP_ABI_PUSH +# define VFP_ABI_POP +# define VFP_ABI_FRAME 0 +# define BSAES_ASM_EXTENDED_KEY +# define XTS_CHAIN_TWEAK +# define __ARM_ARCH__ __LINUX_ARM_ARCH__ +#endif + +#ifdef __thumb__ +# define adrl adr +#endif + +#if __ARM_ARCH__>=7 +.text +.syntax unified @ ARMv7-capable assembler is expected to handle this +#ifdef __thumb2__ +.thumb +#else +.code 32 +#endif + +.fpu neon + +.type _bsaes_decrypt8,%function +.align 4 +_bsaes_decrypt8: + adr $const,_bsaes_decrypt8 + vldmia $key!, {@XMM[9]} @ round 0 key + add $const,$const,#.LM0ISR-_bsaes_decrypt8 + + vldmia $const!, {@XMM[8]} @ .LM0ISR + veor @XMM[10], @XMM[0], @XMM[9] @ xor with round0 key + veor @XMM[11], @XMM[1], @XMM[9] + vtbl.8 `&Dlo(@XMM[0])`, {@XMM[10]}, `&Dlo(@XMM[8])` + vtbl.8 `&Dhi(@XMM[0])`, {@XMM[10]}, `&Dhi(@XMM[8])` + veor @XMM[12], @XMM[2], @XMM[9] + vtbl.8 `&Dlo(@XMM[1])`, {@XMM[11]}, `&Dlo(@XMM[8])` + vtbl.8 `&Dhi(@XMM[1])`, {@XMM[11]}, `&Dhi(@XMM[8])` + veor @XMM[13], @XMM[3], @XMM[9] + vtbl.8 `&Dlo(@XMM[2])`, {@XMM[12]}, `&Dlo(@XMM[8])` + vtbl.8 `&Dhi(@XMM[2])`, {@XMM[12]}, `&Dhi(@XMM[8])` + veor @XMM[14], @XMM[4], @XMM[9] + vtbl.8 `&Dlo(@XMM[3])`, {@XMM[13]}, `&Dlo(@XMM[8])` + vtbl.8 `&Dhi(@XMM[3])`, {@XMM[13]}, `&Dhi(@XMM[8])` + veor @XMM[15], @XMM[5], @XMM[9] + vtbl.8 `&Dlo(@XMM[4])`, {@XMM[14]}, `&Dlo(@XMM[8])` + vtbl.8 `&Dhi(@XMM[4])`, {@XMM[14]}, `&Dhi(@XMM[8])` + veor @XMM[10], @XMM[6], @XMM[9] + vtbl.8 `&Dlo(@XMM[5])`, {@XMM[15]}, `&Dlo(@XMM[8])` + vtbl.8 `&Dhi(@XMM[5])`, {@XMM[15]}, `&Dhi(@XMM[8])` + veor @XMM[11], @XMM[7], @XMM[9] + vtbl.8 `&Dlo(@XMM[6])`, {@XMM[10]}, `&Dlo(@XMM[8])` + vtbl.8 `&Dhi(@XMM[6])`, {@XMM[10]}, `&Dhi(@XMM[8])` + vtbl.8 `&Dlo(@XMM[7])`, {@XMM[11]}, `&Dlo(@XMM[8])` + vtbl.8 `&Dhi(@XMM[7])`, {@XMM[11]}, `&Dhi(@XMM[8])` +___ + &bitslice (@XMM[0..7, 8..11]); +$code.=<<___; + sub $rounds,$rounds,#1 + b .Ldec_sbox +.align 4 +.Ldec_loop: +___ + &ShiftRows (@XMM[0..7, 8..12]); +$code.=".Ldec_sbox:\n"; + &InvSbox (@XMM[0..7, 8..15]); +$code.=<<___; + subs $rounds,$rounds,#1 + bcc .Ldec_done +___ + &InvMixColumns (@XMM[0,1,6,4,2,7,3,5, 8..15]); +$code.=<<___; + vldmia $const, {@XMM[12]} @ .LISR + ite eq @ Thumb2 thing, sanity check in ARM + addeq $const,$const,#0x10 + bne .Ldec_loop + vldmia $const, {@XMM[12]} @ .LISRM0 + b .Ldec_loop +.align 4 +.Ldec_done: +___ + &bitslice (@XMM[0,1,6,4,2,7,3,5, 8..11]); +$code.=<<___; + vldmia $key, {@XMM[8]} @ last round key + veor @XMM[6], @XMM[6], @XMM[8] + veor @XMM[4], @XMM[4], @XMM[8] + veor @XMM[2], @XMM[2], @XMM[8] + veor @XMM[7], @XMM[7], @XMM[8] + veor @XMM[3], @XMM[3], @XMM[8] + veor @XMM[5], @XMM[5], @XMM[8] + veor @XMM[0], @XMM[0], @XMM[8] + veor @XMM[1], @XMM[1], @XMM[8] + bx lr +.size _bsaes_decrypt8,.-_bsaes_decrypt8 + +.type _bsaes_const,%object +.align 6 +_bsaes_const: +.LM0ISR: @ InvShiftRows constants + .quad 0x0a0e0206070b0f03, 0x0004080c0d010509 +.LISR: + .quad 0x0504070602010003, 0x0f0e0d0c080b0a09 +.LISRM0: + .quad 0x01040b0e0205080f, 0x0306090c00070a0d +.LM0SR: @ ShiftRows constants + .quad 0x0a0e02060f03070b, 0x0004080c05090d01 +.LSR: + .quad 0x0504070600030201, 0x0f0e0d0c0a09080b +.LSRM0: + .quad 0x0304090e00050a0f, 0x01060b0c0207080d +.LM0: + .quad 0x02060a0e03070b0f, 0x0004080c0105090d +.LREVM0SR: + .quad 0x090d01050c000408, 0x03070b0f060a0e02 +.asciz "Bit-sliced AES for NEON, CRYPTOGAMS by <appro\@openssl.org>" +.align 6 +.size _bsaes_const,.-_bsaes_const + +.type _bsaes_encrypt8,%function +.align 4 +_bsaes_encrypt8: + adr $const,_bsaes_encrypt8 + vldmia $key!, {@XMM[9]} @ round 0 key + sub $const,$const,#_bsaes_encrypt8-.LM0SR + + vldmia $const!, {@XMM[8]} @ .LM0SR +_bsaes_encrypt8_alt: + veor @XMM[10], @XMM[0], @XMM[9] @ xor with round0 key + veor @XMM[11], @XMM[1], @XMM[9] + vtbl.8 `&Dlo(@XMM[0])`, {@XMM[10]}, `&Dlo(@XMM[8])` + vtbl.8 `&Dhi(@XMM[0])`, {@XMM[10]}, `&Dhi(@XMM[8])` + veor @XMM[12], @XMM[2], @XMM[9] + vtbl.8 `&Dlo(@XMM[1])`, {@XMM[11]}, `&Dlo(@XMM[8])` + vtbl.8 `&Dhi(@XMM[1])`, {@XMM[11]}, `&Dhi(@XMM[8])` + veor @XMM[13], @XMM[3], @XMM[9] + vtbl.8 `&Dlo(@XMM[2])`, {@XMM[12]}, `&Dlo(@XMM[8])` + vtbl.8 `&Dhi(@XMM[2])`, {@XMM[12]}, `&Dhi(@XMM[8])` + veor @XMM[14], @XMM[4], @XMM[9] + vtbl.8 `&Dlo(@XMM[3])`, {@XMM[13]}, `&Dlo(@XMM[8])` + vtbl.8 `&Dhi(@XMM[3])`, {@XMM[13]}, `&Dhi(@XMM[8])` + veor @XMM[15], @XMM[5], @XMM[9] + vtbl.8 `&Dlo(@XMM[4])`, {@XMM[14]}, `&Dlo(@XMM[8])` + vtbl.8 `&Dhi(@XMM[4])`, {@XMM[14]}, `&Dhi(@XMM[8])` + veor @XMM[10], @XMM[6], @XMM[9] + vtbl.8 `&Dlo(@XMM[5])`, {@XMM[15]}, `&Dlo(@XMM[8])` + vtbl.8 `&Dhi(@XMM[5])`, {@XMM[15]}, `&Dhi(@XMM[8])` + veor @XMM[11], @XMM[7], @XMM[9] + vtbl.8 `&Dlo(@XMM[6])`, {@XMM[10]}, `&Dlo(@XMM[8])` + vtbl.8 `&Dhi(@XMM[6])`, {@XMM[10]}, `&Dhi(@XMM[8])` + vtbl.8 `&Dlo(@XMM[7])`, {@XMM[11]}, `&Dlo(@XMM[8])` + vtbl.8 `&Dhi(@XMM[7])`, {@XMM[11]}, `&Dhi(@XMM[8])` +_bsaes_encrypt8_bitslice: +___ + &bitslice (@XMM[0..7, 8..11]); +$code.=<<___; + sub $rounds,$rounds,#1 + b .Lenc_sbox +.align 4 +.Lenc_loop: +___ + &ShiftRows (@XMM[0..7, 8..12]); +$code.=".Lenc_sbox:\n"; + &Sbox (@XMM[0..7, 8..15]); +$code.=<<___; + subs $rounds,$rounds,#1 + bcc .Lenc_done +___ + &MixColumns (@XMM[0,1,4,6,3,7,2,5, 8..15]); +$code.=<<___; + vldmia $const, {@XMM[12]} @ .LSR + ite eq @ Thumb2 thing, samity check in ARM + addeq $const,$const,#0x10 + bne .Lenc_loop + vldmia $const, {@XMM[12]} @ .LSRM0 + b .Lenc_loop +.align 4 +.Lenc_done: +___ + # output in lsb > [t0, t1, t4, t6, t3, t7, t2, t5] < msb + &bitslice (@XMM[0,1,4,6,3,7,2,5, 8..11]); +$code.=<<___; + vldmia $key, {@XMM[8]} @ last round key + veor @XMM[4], @XMM[4], @XMM[8] + veor @XMM[6], @XMM[6], @XMM[8] + veor @XMM[3], @XMM[3], @XMM[8] + veor @XMM[7], @XMM[7], @XMM[8] + veor @XMM[2], @XMM[2], @XMM[8] + veor @XMM[5], @XMM[5], @XMM[8] + veor @XMM[0], @XMM[0], @XMM[8] + veor @XMM[1], @XMM[1], @XMM[8] + bx lr +.size _bsaes_encrypt8,.-_bsaes_encrypt8 +___ +} +{ +my ($out,$inp,$rounds,$const)=("r12","r4","r5","r6"); + +sub bitslice_key { +my @x=reverse(@_[0..7]); +my ($bs0,$bs1,$bs2,$t2,$t3)=@_[8..12]; + + &swapmove (@x[0,1],1,$bs0,$t2,$t3); +$code.=<<___; + @ &swapmove(@x[2,3],1,$t0,$t2,$t3); + vmov @x[2], @x[0] + vmov @x[3], @x[1] +___ + #&swapmove2x(@x[4,5,6,7],1,$t0,$t2,$t3); + + &swapmove2x (@x[0,2,1,3],2,$bs1,$t2,$t3); +$code.=<<___; + @ &swapmove2x(@x[4,6,5,7],2,$t1,$t2,$t3); + vmov @x[4], @x[0] + vmov @x[6], @x[2] + vmov @x[5], @x[1] + vmov @x[7], @x[3] +___ + &swapmove2x (@x[0,4,1,5],4,$bs2,$t2,$t3); + &swapmove2x (@x[2,6,3,7],4,$bs2,$t2,$t3); +} + +$code.=<<___; +.type _bsaes_key_convert,%function +.align 4 +_bsaes_key_convert: + adr $const,_bsaes_key_convert + vld1.8 {@XMM[7]}, [$inp]! @ load round 0 key + sub $const,$const,#_bsaes_key_convert-.LM0 + vld1.8 {@XMM[15]}, [$inp]! @ load round 1 key + + vmov.i8 @XMM[8], #0x01 @ bit masks + vmov.i8 @XMM[9], #0x02 + vmov.i8 @XMM[10], #0x04 + vmov.i8 @XMM[11], #0x08 + vmov.i8 @XMM[12], #0x10 + vmov.i8 @XMM[13], #0x20 + vldmia $const, {@XMM[14]} @ .LM0 + +#ifdef __ARMEL__ + vrev32.8 @XMM[7], @XMM[7] + vrev32.8 @XMM[15], @XMM[15] +#endif + sub $rounds,$rounds,#1 + vstmia $out!, {@XMM[7]} @ save round 0 key + b .Lkey_loop + +.align 4 +.Lkey_loop: + vtbl.8 `&Dlo(@XMM[7])`,{@XMM[15]},`&Dlo(@XMM[14])` + vtbl.8 `&Dhi(@XMM[7])`,{@XMM[15]},`&Dhi(@XMM[14])` + vmov.i8 @XMM[6], #0x40 + vmov.i8 @XMM[15], #0x80 + + vtst.8 @XMM[0], @XMM[7], @XMM[8] + vtst.8 @XMM[1], @XMM[7], @XMM[9] + vtst.8 @XMM[2], @XMM[7], @XMM[10] + vtst.8 @XMM[3], @XMM[7], @XMM[11] + vtst.8 @XMM[4], @XMM[7], @XMM[12] + vtst.8 @XMM[5], @XMM[7], @XMM[13] + vtst.8 @XMM[6], @XMM[7], @XMM[6] + vtst.8 @XMM[7], @XMM[7], @XMM[15] + vld1.8 {@XMM[15]}, [$inp]! @ load next round key + vmvn @XMM[0], @XMM[0] @ "pnot" + vmvn @XMM[1], @XMM[1] + vmvn @XMM[5], @XMM[5] + vmvn @XMM[6], @XMM[6] +#ifdef __ARMEL__ + vrev32.8 @XMM[15], @XMM[15] +#endif + subs $rounds,$rounds,#1 + vstmia $out!,{@XMM[0]-@XMM[7]} @ write bit-sliced round key + bne .Lkey_loop + + vmov.i8 @XMM[7],#0x63 @ compose .L63 + @ don't save last round key + bx lr +.size _bsaes_key_convert,.-_bsaes_key_convert +___ +} + +if (0) { # following four functions are unsupported interface + # used for benchmarking... +$code.=<<___; +.globl bsaes_enc_key_convert +.type bsaes_enc_key_convert,%function +.align 4 +bsaes_enc_key_convert: + stmdb sp!,{r4-r6,lr} + vstmdb sp!,{d8-d15} @ ABI specification says so + + ldr r5,[$inp,#240] @ pass rounds + mov r4,$inp @ pass key + mov r12,$out @ pass key schedule + bl _bsaes_key_convert + veor @XMM[7],@XMM[7],@XMM[15] @ fix up last round key + vstmia r12, {@XMM[7]} @ save last round key + + vldmia sp!,{d8-d15} + ldmia sp!,{r4-r6,pc} +.size bsaes_enc_key_convert,.-bsaes_enc_key_convert + +.globl bsaes_encrypt_128 +.type bsaes_encrypt_128,%function +.align 4 +bsaes_encrypt_128: + stmdb sp!,{r4-r6,lr} + vstmdb sp!,{d8-d15} @ ABI specification says so +.Lenc128_loop: + vld1.8 {@XMM[0]-@XMM[1]}, [$inp]! @ load input + vld1.8 {@XMM[2]-@XMM[3]}, [$inp]! + mov r4,$key @ pass the key + vld1.8 {@XMM[4]-@XMM[5]}, [$inp]! + mov r5,#10 @ pass rounds + vld1.8 {@XMM[6]-@XMM[7]}, [$inp]! + + bl _bsaes_encrypt8 + + vst1.8 {@XMM[0]-@XMM[1]}, [$out]! @ write output + vst1.8 {@XMM[4]}, [$out]! + vst1.8 {@XMM[6]}, [$out]! + vst1.8 {@XMM[3]}, [$out]! + vst1.8 {@XMM[7]}, [$out]! + vst1.8 {@XMM[2]}, [$out]! + subs $len,$len,#0x80 + vst1.8 {@XMM[5]}, [$out]! + bhi .Lenc128_loop + + vldmia sp!,{d8-d15} + ldmia sp!,{r4-r6,pc} +.size bsaes_encrypt_128,.-bsaes_encrypt_128 + +.globl bsaes_dec_key_convert +.type bsaes_dec_key_convert,%function +.align 4 +bsaes_dec_key_convert: + stmdb sp!,{r4-r6,lr} + vstmdb sp!,{d8-d15} @ ABI specification says so + + ldr r5,[$inp,#240] @ pass rounds + mov r4,$inp @ pass key + mov r12,$out @ pass key schedule + bl _bsaes_key_convert + vldmia $out, {@XMM[6]} + vstmia r12, {@XMM[15]} @ save last round key + veor @XMM[7], @XMM[7], @XMM[6] @ fix up round 0 key + vstmia $out, {@XMM[7]} + + vldmia sp!,{d8-d15} + ldmia sp!,{r4-r6,pc} +.size bsaes_dec_key_convert,.-bsaes_dec_key_convert + +.globl bsaes_decrypt_128 +.type bsaes_decrypt_128,%function +.align 4 +bsaes_decrypt_128: + stmdb sp!,{r4-r6,lr} + vstmdb sp!,{d8-d15} @ ABI specification says so +.Ldec128_loop: + vld1.8 {@XMM[0]-@XMM[1]}, [$inp]! @ load input + vld1.8 {@XMM[2]-@XMM[3]}, [$inp]! + mov r4,$key @ pass the key + vld1.8 {@XMM[4]-@XMM[5]}, [$inp]! + mov r5,#10 @ pass rounds + vld1.8 {@XMM[6]-@XMM[7]}, [$inp]! + + bl _bsaes_decrypt8 + + vst1.8 {@XMM[0]-@XMM[1]}, [$out]! @ write output + vst1.8 {@XMM[6]}, [$out]! + vst1.8 {@XMM[4]}, [$out]! + vst1.8 {@XMM[2]}, [$out]! + vst1.8 {@XMM[7]}, [$out]! + vst1.8 {@XMM[3]}, [$out]! + subs $len,$len,#0x80 + vst1.8 {@XMM[5]}, [$out]! + bhi .Ldec128_loop + + vldmia sp!,{d8-d15} + ldmia sp!,{r4-r6,pc} +.size bsaes_decrypt_128,.-bsaes_decrypt_128 +___ +} +{ +my ($inp,$out,$len,$key, $ivp,$fp,$rounds)=map("r$_",(0..3,8..10)); +my ($keysched)=("sp"); + +$code.=<<___; +.extern AES_cbc_encrypt +.extern AES_decrypt + +.global bsaes_cbc_encrypt +.type bsaes_cbc_encrypt,%function +.align 5 +bsaes_cbc_encrypt: +#ifndef __KERNEL__ + cmp $len, #128 +#ifndef __thumb__ + blo AES_cbc_encrypt +#else + bhs 1f + b AES_cbc_encrypt +1: +#endif +#endif + + @ it is up to the caller to make sure we are called with enc == 0 + + mov ip, sp + stmdb sp!, {r4-r10, lr} + VFP_ABI_PUSH + ldr $ivp, [ip] @ IV is 1st arg on the stack + mov $len, $len, lsr#4 @ len in 16 byte blocks + sub sp, #0x10 @ scratch space to carry over the IV + mov $fp, sp @ save sp + + ldr $rounds, [$key, #240] @ get # of rounds +#ifndef BSAES_ASM_EXTENDED_KEY + @ allocate the key schedule on the stack + sub r12, sp, $rounds, lsl#7 @ 128 bytes per inner round key + add r12, #`128-32` @ sifze of bit-slices key schedule + + @ populate the key schedule + mov r4, $key @ pass key + mov r5, $rounds @ pass # of rounds + mov sp, r12 @ sp is $keysched + bl _bsaes_key_convert + vldmia $keysched, {@XMM[6]} + vstmia r12, {@XMM[15]} @ save last round key + veor @XMM[7], @XMM[7], @XMM[6] @ fix up round 0 key + vstmia $keysched, {@XMM[7]} +#else + ldr r12, [$key, #244] + eors r12, #1 + beq 0f + + @ populate the key schedule + str r12, [$key, #244] + mov r4, $key @ pass key + mov r5, $rounds @ pass # of rounds + add r12, $key, #248 @ pass key schedule + bl _bsaes_key_convert + add r4, $key, #248 + vldmia r4, {@XMM[6]} + vstmia r12, {@XMM[15]} @ save last round key + veor @XMM[7], @XMM[7], @XMM[6] @ fix up round 0 key + vstmia r4, {@XMM[7]} + +.align 2 +0: +#endif + + vld1.8 {@XMM[15]}, [$ivp] @ load IV + b .Lcbc_dec_loop + +.align 4 +.Lcbc_dec_loop: + subs $len, $len, #0x8 + bmi .Lcbc_dec_loop_finish + + vld1.8 {@XMM[0]-@XMM[1]}, [$inp]! @ load input + vld1.8 {@XMM[2]-@XMM[3]}, [$inp]! +#ifndef BSAES_ASM_EXTENDED_KEY + mov r4, $keysched @ pass the key +#else + add r4, $key, #248 +#endif + vld1.8 {@XMM[4]-@XMM[5]}, [$inp]! + mov r5, $rounds + vld1.8 {@XMM[6]-@XMM[7]}, [$inp] + sub $inp, $inp, #0x60 + vstmia $fp, {@XMM[15]} @ put aside IV + + bl _bsaes_decrypt8 + + vldmia $fp, {@XMM[14]} @ reload IV + vld1.8 {@XMM[8]-@XMM[9]}, [$inp]! @ reload input + veor @XMM[0], @XMM[0], @XMM[14] @ ^= IV + vld1.8 {@XMM[10]-@XMM[11]}, [$inp]! + veor @XMM[1], @XMM[1], @XMM[8] + veor @XMM[6], @XMM[6], @XMM[9] + vld1.8 {@XMM[12]-@XMM[13]}, [$inp]! + veor @XMM[4], @XMM[4], @XMM[10] + veor @XMM[2], @XMM[2], @XMM[11] + vld1.8 {@XMM[14]-@XMM[15]}, [$inp]! + veor @XMM[7], @XMM[7], @XMM[12] + vst1.8 {@XMM[0]-@XMM[1]}, [$out]! @ write output + veor @XMM[3], @XMM[3], @XMM[13] + vst1.8 {@XMM[6]}, [$out]! + veor @XMM[5], @XMM[5], @XMM[14] + vst1.8 {@XMM[4]}, [$out]! + vst1.8 {@XMM[2]}, [$out]! + vst1.8 {@XMM[7]}, [$out]! + vst1.8 {@XMM[3]}, [$out]! + vst1.8 {@XMM[5]}, [$out]! + + b .Lcbc_dec_loop + +.Lcbc_dec_loop_finish: + adds $len, $len, #8 + beq .Lcbc_dec_done + + vld1.8 {@XMM[0]}, [$inp]! @ load input + cmp $len, #2 + blo .Lcbc_dec_one + vld1.8 {@XMM[1]}, [$inp]! +#ifndef BSAES_ASM_EXTENDED_KEY + mov r4, $keysched @ pass the key +#else + add r4, $key, #248 +#endif + mov r5, $rounds + vstmia $fp, {@XMM[15]} @ put aside IV + beq .Lcbc_dec_two + vld1.8 {@XMM[2]}, [$inp]! + cmp $len, #4 + blo .Lcbc_dec_three + vld1.8 {@XMM[3]}, [$inp]! + beq .Lcbc_dec_four + vld1.8 {@XMM[4]}, [$inp]! + cmp $len, #6 + blo .Lcbc_dec_five + vld1.8 {@XMM[5]}, [$inp]! + beq .Lcbc_dec_six + vld1.8 {@XMM[6]}, [$inp]! + sub $inp, $inp, #0x70 + + bl _bsaes_decrypt8 + + vldmia $fp, {@XMM[14]} @ reload IV + vld1.8 {@XMM[8]-@XMM[9]}, [$inp]! @ reload input + veor @XMM[0], @XMM[0], @XMM[14] @ ^= IV + vld1.8 {@XMM[10]-@XMM[11]}, [$inp]! + veor @XMM[1], @XMM[1], @XMM[8] + veor @XMM[6], @XMM[6], @XMM[9] + vld1.8 {@XMM[12]-@XMM[13]}, [$inp]! + veor @XMM[4], @XMM[4], @XMM[10] + veor @XMM[2], @XMM[2], @XMM[11] + vld1.8 {@XMM[15]}, [$inp]! + veor @XMM[7], @XMM[7], @XMM[12] + vst1.8 {@XMM[0]-@XMM[1]}, [$out]! @ write output + veor @XMM[3], @XMM[3], @XMM[13] + vst1.8 {@XMM[6]}, [$out]! + vst1.8 {@XMM[4]}, [$out]! + vst1.8 {@XMM[2]}, [$out]! + vst1.8 {@XMM[7]}, [$out]! + vst1.8 {@XMM[3]}, [$out]! + b .Lcbc_dec_done +.align 4 +.Lcbc_dec_six: + sub $inp, $inp, #0x60 + bl _bsaes_decrypt8 + vldmia $fp,{@XMM[14]} @ reload IV + vld1.8 {@XMM[8]-@XMM[9]}, [$inp]! @ reload input + veor @XMM[0], @XMM[0], @XMM[14] @ ^= IV + vld1.8 {@XMM[10]-@XMM[11]}, [$inp]! + veor @XMM[1], @XMM[1], @XMM[8] + veor @XMM[6], @XMM[6], @XMM[9] + vld1.8 {@XMM[12]}, [$inp]! + veor @XMM[4], @XMM[4], @XMM[10] + veor @XMM[2], @XMM[2], @XMM[11] + vld1.8 {@XMM[15]}, [$inp]! + veor @XMM[7], @XMM[7], @XMM[12] + vst1.8 {@XMM[0]-@XMM[1]}, [$out]! @ write output + vst1.8 {@XMM[6]}, [$out]! + vst1.8 {@XMM[4]}, [$out]! + vst1.8 {@XMM[2]}, [$out]! + vst1.8 {@XMM[7]}, [$out]! + b .Lcbc_dec_done +.align 4 +.Lcbc_dec_five: + sub $inp, $inp, #0x50 + bl _bsaes_decrypt8 + vldmia $fp, {@XMM[14]} @ reload IV + vld1.8 {@XMM[8]-@XMM[9]}, [$inp]! @ reload input + veor @XMM[0], @XMM[0], @XMM[14] @ ^= IV + vld1.8 {@XMM[10]-@XMM[11]}, [$inp]! + veor @XMM[1], @XMM[1], @XMM[8] + veor @XMM[6], @XMM[6], @XMM[9] + vld1.8 {@XMM[15]}, [$inp]! + veor @XMM[4], @XMM[4], @XMM[10] + vst1.8 {@XMM[0]-@XMM[1]}, [$out]! @ write output + veor @XMM[2], @XMM[2], @XMM[11] + vst1.8 {@XMM[6]}, [$out]! + vst1.8 {@XMM[4]}, [$out]! + vst1.8 {@XMM[2]}, [$out]! + b .Lcbc_dec_done +.align 4 +.Lcbc_dec_four: + sub $inp, $inp, #0x40 + bl _bsaes_decrypt8 + vldmia $fp, {@XMM[14]} @ reload IV + vld1.8 {@XMM[8]-@XMM[9]}, [$inp]! @ reload input + veor @XMM[0], @XMM[0], @XMM[14] @ ^= IV + vld1.8 {@XMM[10]}, [$inp]! + veor @XMM[1], @XMM[1], @XMM[8] + veor @XMM[6], @XMM[6], @XMM[9] + vld1.8 {@XMM[15]}, [$inp]! + veor @XMM[4], @XMM[4], @XMM[10] + vst1.8 {@XMM[0]-@XMM[1]}, [$out]! @ write output + vst1.8 {@XMM[6]}, [$out]! + vst1.8 {@XMM[4]}, [$out]! + b .Lcbc_dec_done +.align 4 +.Lcbc_dec_three: + sub $inp, $inp, #0x30 + bl _bsaes_decrypt8 + vldmia $fp, {@XMM[14]} @ reload IV + vld1.8 {@XMM[8]-@XMM[9]}, [$inp]! @ reload input + veor @XMM[0], @XMM[0], @XMM[14] @ ^= IV + vld1.8 {@XMM[15]}, [$inp]! + veor @XMM[1], @XMM[1], @XMM[8] + veor @XMM[6], @XMM[6], @XMM[9] + vst1.8 {@XMM[0]-@XMM[1]}, [$out]! @ write output + vst1.8 {@XMM[6]}, [$out]! + b .Lcbc_dec_done +.align 4 +.Lcbc_dec_two: + sub $inp, $inp, #0x20 + bl _bsaes_decrypt8 + vldmia $fp, {@XMM[14]} @ reload IV + vld1.8 {@XMM[8]}, [$inp]! @ reload input + veor @XMM[0], @XMM[0], @XMM[14] @ ^= IV + vld1.8 {@XMM[15]}, [$inp]! @ reload input + veor @XMM[1], @XMM[1], @XMM[8] + vst1.8 {@XMM[0]-@XMM[1]}, [$out]! @ write output + b .Lcbc_dec_done +.align 4 +.Lcbc_dec_one: + sub $inp, $inp, #0x10 + mov $rounds, $out @ save original out pointer + mov $out, $fp @ use the iv scratch space as out buffer + mov r2, $key + vmov @XMM[4],@XMM[15] @ just in case ensure that IV + vmov @XMM[5],@XMM[0] @ and input are preserved + bl AES_decrypt + vld1.8 {@XMM[0]}, [$fp,:64] @ load result + veor @XMM[0], @XMM[0], @XMM[4] @ ^= IV + vmov @XMM[15], @XMM[5] @ @XMM[5] holds input + vst1.8 {@XMM[0]}, [$rounds] @ write output + +.Lcbc_dec_done: +#ifndef BSAES_ASM_EXTENDED_KEY + vmov.i32 q0, #0 + vmov.i32 q1, #0 +.Lcbc_dec_bzero: @ wipe key schedule [if any] + vstmia $keysched!, {q0-q1} + cmp $keysched, $fp + bne .Lcbc_dec_bzero +#endif + + mov sp, $fp + add sp, #0x10 @ add sp,$fp,#0x10 is no good for thumb + vst1.8 {@XMM[15]}, [$ivp] @ return IV + VFP_ABI_POP + ldmia sp!, {r4-r10, pc} +.size bsaes_cbc_encrypt,.-bsaes_cbc_encrypt +___ +} +{ +my ($inp,$out,$len,$key, $ctr,$fp,$rounds)=(map("r$_",(0..3,8..10))); +my $const = "r6"; # shared with _bsaes_encrypt8_alt +my $keysched = "sp"; + +$code.=<<___; +.extern AES_encrypt +.global bsaes_ctr32_encrypt_blocks +.type bsaes_ctr32_encrypt_blocks,%function +.align 5 +bsaes_ctr32_encrypt_blocks: + cmp $len, #8 @ use plain AES for + blo .Lctr_enc_short @ small sizes + + mov ip, sp + stmdb sp!, {r4-r10, lr} + VFP_ABI_PUSH + ldr $ctr, [ip] @ ctr is 1st arg on the stack + sub sp, sp, #0x10 @ scratch space to carry over the ctr + mov $fp, sp @ save sp + + ldr $rounds, [$key, #240] @ get # of rounds +#ifndef BSAES_ASM_EXTENDED_KEY + @ allocate the key schedule on the stack + sub r12, sp, $rounds, lsl#7 @ 128 bytes per inner round key + add r12, #`128-32` @ size of bit-sliced key schedule + + @ populate the key schedule + mov r4, $key @ pass key + mov r5, $rounds @ pass # of rounds + mov sp, r12 @ sp is $keysched + bl _bsaes_key_convert + veor @XMM[7],@XMM[7],@XMM[15] @ fix up last round key + vstmia r12, {@XMM[7]} @ save last round key + + vld1.8 {@XMM[0]}, [$ctr] @ load counter + add $ctr, $const, #.LREVM0SR-.LM0 @ borrow $ctr + vldmia $keysched, {@XMM[4]} @ load round0 key +#else + ldr r12, [$key, #244] + eors r12, #1 + beq 0f + + @ populate the key schedule + str r12, [$key, #244] + mov r4, $key @ pass key + mov r5, $rounds @ pass # of rounds + add r12, $key, #248 @ pass key schedule + bl _bsaes_key_convert + veor @XMM[7],@XMM[7],@XMM[15] @ fix up last round key + vstmia r12, {@XMM[7]} @ save last round key + +.align 2 +0: add r12, $key, #248 + vld1.8 {@XMM[0]}, [$ctr] @ load counter + adrl $ctr, .LREVM0SR @ borrow $ctr + vldmia r12, {@XMM[4]} @ load round0 key + sub sp, #0x10 @ place for adjusted round0 key +#endif + + vmov.i32 @XMM[8],#1 @ compose 1<<96 + veor @XMM[9],@XMM[9],@XMM[9] + vrev32.8 @XMM[0],@XMM[0] + vext.8 @XMM[8],@XMM[9],@XMM[8],#4 + vrev32.8 @XMM[4],@XMM[4] + vadd.u32 @XMM[9],@XMM[8],@XMM[8] @ compose 2<<96 + vstmia $keysched, {@XMM[4]} @ save adjusted round0 key + b .Lctr_enc_loop + +.align 4 +.Lctr_enc_loop: + vadd.u32 @XMM[10], @XMM[8], @XMM[9] @ compose 3<<96 + vadd.u32 @XMM[1], @XMM[0], @XMM[8] @ +1 + vadd.u32 @XMM[2], @XMM[0], @XMM[9] @ +2 + vadd.u32 @XMM[3], @XMM[0], @XMM[10] @ +3 + vadd.u32 @XMM[4], @XMM[1], @XMM[10] + vadd.u32 @XMM[5], @XMM[2], @XMM[10] + vadd.u32 @XMM[6], @XMM[3], @XMM[10] + vadd.u32 @XMM[7], @XMM[4], @XMM[10] + vadd.u32 @XMM[10], @XMM[5], @XMM[10] @ next counter + + @ Borrow prologue from _bsaes_encrypt8 to use the opportunity + @ to flip byte order in 32-bit counter + + vldmia $keysched, {@XMM[9]} @ load round0 key +#ifndef BSAES_ASM_EXTENDED_KEY + add r4, $keysched, #0x10 @ pass next round key +#else + add r4, $key, #`248+16` +#endif + vldmia $ctr, {@XMM[8]} @ .LREVM0SR + mov r5, $rounds @ pass rounds + vstmia $fp, {@XMM[10]} @ save next counter + sub $const, $ctr, #.LREVM0SR-.LSR @ pass constants + + bl _bsaes_encrypt8_alt + + subs $len, $len, #8 + blo .Lctr_enc_loop_done + + vld1.8 {@XMM[8]-@XMM[9]}, [$inp]! @ load input + vld1.8 {@XMM[10]-@XMM[11]}, [$inp]! + veor @XMM[0], @XMM[8] + veor @XMM[1], @XMM[9] + vld1.8 {@XMM[12]-@XMM[13]}, [$inp]! + veor @XMM[4], @XMM[10] + veor @XMM[6], @XMM[11] + vld1.8 {@XMM[14]-@XMM[15]}, [$inp]! + veor @XMM[3], @XMM[12] + vst1.8 {@XMM[0]-@XMM[1]}, [$out]! @ write output + veor @XMM[7], @XMM[13] + veor @XMM[2], @XMM[14] + vst1.8 {@XMM[4]}, [$out]! + veor @XMM[5], @XMM[15] + vst1.8 {@XMM[6]}, [$out]! + vmov.i32 @XMM[8], #1 @ compose 1<<96 + vst1.8 {@XMM[3]}, [$out]! + veor @XMM[9], @XMM[9], @XMM[9] + vst1.8 {@XMM[7]}, [$out]! + vext.8 @XMM[8], @XMM[9], @XMM[8], #4 + vst1.8 {@XMM[2]}, [$out]! + vadd.u32 @XMM[9],@XMM[8],@XMM[8] @ compose 2<<96 + vst1.8 {@XMM[5]}, [$out]! + vldmia $fp, {@XMM[0]} @ load counter + + bne .Lctr_enc_loop + b .Lctr_enc_done + +.align 4 +.Lctr_enc_loop_done: + add $len, $len, #8 + vld1.8 {@XMM[8]}, [$inp]! @ load input + veor @XMM[0], @XMM[8] + vst1.8 {@XMM[0]}, [$out]! @ write output + cmp $len, #2 + blo .Lctr_enc_done + vld1.8 {@XMM[9]}, [$inp]! + veor @XMM[1], @XMM[9] + vst1.8 {@XMM[1]}, [$out]! + beq .Lctr_enc_done + vld1.8 {@XMM[10]}, [$inp]! + veor @XMM[4], @XMM[10] + vst1.8 {@XMM[4]}, [$out]! + cmp $len, #4 + blo .Lctr_enc_done + vld1.8 {@XMM[11]}, [$inp]! + veor @XMM[6], @XMM[11] + vst1.8 {@XMM[6]}, [$out]! + beq .Lctr_enc_done + vld1.8 {@XMM[12]}, [$inp]! + veor @XMM[3], @XMM[12] + vst1.8 {@XMM[3]}, [$out]! + cmp $len, #6 + blo .Lctr_enc_done + vld1.8 {@XMM[13]}, [$inp]! + veor @XMM[7], @XMM[13] + vst1.8 {@XMM[7]}, [$out]! + beq .Lctr_enc_done + vld1.8 {@XMM[14]}, [$inp] + veor @XMM[2], @XMM[14] + vst1.8 {@XMM[2]}, [$out]! + +.Lctr_enc_done: + vmov.i32 q0, #0 + vmov.i32 q1, #0 +#ifndef BSAES_ASM_EXTENDED_KEY +.Lctr_enc_bzero: @ wipe key schedule [if any] + vstmia $keysched!, {q0-q1} + cmp $keysched, $fp + bne .Lctr_enc_bzero +#else + vstmia $keysched, {q0-q1} +#endif + + mov sp, $fp + add sp, #0x10 @ add sp,$fp,#0x10 is no good for thumb + VFP_ABI_POP + ldmia sp!, {r4-r10, pc} @ return + +.align 4 +.Lctr_enc_short: + ldr ip, [sp] @ ctr pointer is passed on stack + stmdb sp!, {r4-r8, lr} + + mov r4, $inp @ copy arguments + mov r5, $out + mov r6, $len + mov r7, $key + ldr r8, [ip, #12] @ load counter LSW + vld1.8 {@XMM[1]}, [ip] @ load whole counter value +#ifdef __ARMEL__ + rev r8, r8 +#endif + sub sp, sp, #0x10 + vst1.8 {@XMM[1]}, [sp,:64] @ copy counter value + sub sp, sp, #0x10 + +.Lctr_enc_short_loop: + add r0, sp, #0x10 @ input counter value + mov r1, sp @ output on the stack + mov r2, r7 @ key + + bl AES_encrypt + + vld1.8 {@XMM[0]}, [r4]! @ load input + vld1.8 {@XMM[1]}, [sp,:64] @ load encrypted counter + add r8, r8, #1 +#ifdef __ARMEL__ + rev r0, r8 + str r0, [sp, #0x1c] @ next counter value +#else + str r8, [sp, #0x1c] @ next counter value +#endif + veor @XMM[0],@XMM[0],@XMM[1] + vst1.8 {@XMM[0]}, [r5]! @ store output + subs r6, r6, #1 + bne .Lctr_enc_short_loop + + vmov.i32 q0, #0 + vmov.i32 q1, #0 + vstmia sp!, {q0-q1} + + ldmia sp!, {r4-r8, pc} +.size bsaes_ctr32_encrypt_blocks,.-bsaes_ctr32_encrypt_blocks +___ +} +{ +###################################################################### +# void bsaes_xts_[en|de]crypt(const char *inp,char *out,size_t len, +# const AES_KEY *key1, const AES_KEY *key2, +# const unsigned char iv[16]); +# +my ($inp,$out,$len,$key,$rounds,$magic,$fp)=(map("r$_",(7..10,1..3))); +my $const="r6"; # returned by _bsaes_key_convert +my $twmask=@XMM[5]; +my @T=@XMM[6..7]; + +$code.=<<___; +.globl bsaes_xts_encrypt +.type bsaes_xts_encrypt,%function +.align 4 +bsaes_xts_encrypt: + mov ip, sp + stmdb sp!, {r4-r10, lr} @ 0x20 + VFP_ABI_PUSH + mov r6, sp @ future $fp + + mov $inp, r0 + mov $out, r1 + mov $len, r2 + mov $key, r3 + + sub r0, sp, #0x10 @ 0x10 + bic r0, #0xf @ align at 16 bytes + mov sp, r0 + +#ifdef XTS_CHAIN_TWEAK + ldr r0, [ip] @ pointer to input tweak +#else + @ generate initial tweak + ldr r0, [ip, #4] @ iv[] + mov r1, sp + ldr r2, [ip, #0] @ key2 + bl AES_encrypt + mov r0,sp @ pointer to initial tweak +#endif + + ldr $rounds, [$key, #240] @ get # of rounds + mov $fp, r6 +#ifndef BSAES_ASM_EXTENDED_KEY + @ allocate the key schedule on the stack + sub r12, sp, $rounds, lsl#7 @ 128 bytes per inner round key + @ add r12, #`128-32` @ size of bit-sliced key schedule + sub r12, #`32+16` @ place for tweak[9] + + @ populate the key schedule + mov r4, $key @ pass key + mov r5, $rounds @ pass # of rounds + mov sp, r12 + add r12, #0x90 @ pass key schedule + bl _bsaes_key_convert + veor @XMM[7], @XMM[7], @XMM[15] @ fix up last round key + vstmia r12, {@XMM[7]} @ save last round key +#else + ldr r12, [$key, #244] + eors r12, #1 + beq 0f + + str r12, [$key, #244] + mov r4, $key @ pass key + mov r5, $rounds @ pass # of rounds + add r12, $key, #248 @ pass key schedule + bl _bsaes_key_convert + veor @XMM[7], @XMM[7], @XMM[15] @ fix up last round key + vstmia r12, {@XMM[7]} + +.align 2 +0: sub sp, #0x90 @ place for tweak[9] +#endif + + vld1.8 {@XMM[8]}, [r0] @ initial tweak + adr $magic, .Lxts_magic + + subs $len, #0x80 + blo .Lxts_enc_short + b .Lxts_enc_loop + +.align 4 +.Lxts_enc_loop: + vldmia $magic, {$twmask} @ load XTS magic + vshr.s64 @T[0], @XMM[8], #63 + mov r0, sp + vand @T[0], @T[0], $twmask +___ +for($i=9;$i<16;$i++) { +$code.=<<___; + vadd.u64 @XMM[$i], @XMM[$i-1], @XMM[$i-1] + vst1.64 {@XMM[$i-1]}, [r0,:128]! + vswp `&Dhi("@T[0]")`,`&Dlo("@T[0]")` + vshr.s64 @T[1], @XMM[$i], #63 + veor @XMM[$i], @XMM[$i], @T[0] + vand @T[1], @T[1], $twmask +___ + @T=reverse(@T); + +$code.=<<___ if ($i>=10); + vld1.8 {@XMM[$i-10]}, [$inp]! +___ +$code.=<<___ if ($i>=11); + veor @XMM[$i-11], @XMM[$i-11], @XMM[$i-3] +___ +} +$code.=<<___; + vadd.u64 @XMM[8], @XMM[15], @XMM[15] + vst1.64 {@XMM[15]}, [r0,:128]! + vswp `&Dhi("@T[0]")`,`&Dlo("@T[0]")` + veor @XMM[8], @XMM[8], @T[0] + vst1.64 {@XMM[8]}, [r0,:128] @ next round tweak + + vld1.8 {@XMM[6]-@XMM[7]}, [$inp]! + veor @XMM[5], @XMM[5], @XMM[13] +#ifndef BSAES_ASM_EXTENDED_KEY + add r4, sp, #0x90 @ pass key schedule +#else + add r4, $key, #248 @ pass key schedule +#endif + veor @XMM[6], @XMM[6], @XMM[14] + mov r5, $rounds @ pass rounds + veor @XMM[7], @XMM[7], @XMM[15] + mov r0, sp + + bl _bsaes_encrypt8 + + vld1.64 {@XMM[ 8]-@XMM[ 9]}, [r0,:128]! + vld1.64 {@XMM[10]-@XMM[11]}, [r0,:128]! + veor @XMM[0], @XMM[0], @XMM[ 8] + vld1.64 {@XMM[12]-@XMM[13]}, [r0,:128]! + veor @XMM[1], @XMM[1], @XMM[ 9] + veor @XMM[8], @XMM[4], @XMM[10] + vst1.8 {@XMM[0]-@XMM[1]}, [$out]! + veor @XMM[9], @XMM[6], @XMM[11] + vld1.64 {@XMM[14]-@XMM[15]}, [r0,:128]! + veor @XMM[10], @XMM[3], @XMM[12] + vst1.8 {@XMM[8]-@XMM[9]}, [$out]! + veor @XMM[11], @XMM[7], @XMM[13] + veor @XMM[12], @XMM[2], @XMM[14] + vst1.8 {@XMM[10]-@XMM[11]}, [$out]! + veor @XMM[13], @XMM[5], @XMM[15] + vst1.8 {@XMM[12]-@XMM[13]}, [$out]! + + vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak + + subs $len, #0x80 + bpl .Lxts_enc_loop + +.Lxts_enc_short: + adds $len, #0x70 + bmi .Lxts_enc_done + + vldmia $magic, {$twmask} @ load XTS magic + vshr.s64 @T[0], @XMM[8], #63 + mov r0, sp + vand @T[0], @T[0], $twmask +___ +for($i=9;$i<16;$i++) { +$code.=<<___; + vadd.u64 @XMM[$i], @XMM[$i-1], @XMM[$i-1] + vst1.64 {@XMM[$i-1]}, [r0,:128]! + vswp `&Dhi("@T[0]")`,`&Dlo("@T[0]")` + vshr.s64 @T[1], @XMM[$i], #63 + veor @XMM[$i], @XMM[$i], @T[0] + vand @T[1], @T[1], $twmask +___ + @T=reverse(@T); + +$code.=<<___ if ($i>=10); + vld1.8 {@XMM[$i-10]}, [$inp]! + subs $len, #0x10 + bmi .Lxts_enc_`$i-9` +___ +$code.=<<___ if ($i>=11); + veor @XMM[$i-11], @XMM[$i-11], @XMM[$i-3] +___ +} +$code.=<<___; + sub $len, #0x10 + vst1.64 {@XMM[15]}, [r0,:128] @ next round tweak + + vld1.8 {@XMM[6]}, [$inp]! + veor @XMM[5], @XMM[5], @XMM[13] +#ifndef BSAES_ASM_EXTENDED_KEY + add r4, sp, #0x90 @ pass key schedule +#else + add r4, $key, #248 @ pass key schedule +#endif + veor @XMM[6], @XMM[6], @XMM[14] + mov r5, $rounds @ pass rounds + mov r0, sp + + bl _bsaes_encrypt8 + + vld1.64 {@XMM[ 8]-@XMM[ 9]}, [r0,:128]! + vld1.64 {@XMM[10]-@XMM[11]}, [r0,:128]! + veor @XMM[0], @XMM[0], @XMM[ 8] + vld1.64 {@XMM[12]-@XMM[13]}, [r0,:128]! + veor @XMM[1], @XMM[1], @XMM[ 9] + veor @XMM[8], @XMM[4], @XMM[10] + vst1.8 {@XMM[0]-@XMM[1]}, [$out]! + veor @XMM[9], @XMM[6], @XMM[11] + vld1.64 {@XMM[14]}, [r0,:128]! + veor @XMM[10], @XMM[3], @XMM[12] + vst1.8 {@XMM[8]-@XMM[9]}, [$out]! + veor @XMM[11], @XMM[7], @XMM[13] + veor @XMM[12], @XMM[2], @XMM[14] + vst1.8 {@XMM[10]-@XMM[11]}, [$out]! + vst1.8 {@XMM[12]}, [$out]! + + vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak + b .Lxts_enc_done +.align 4 +.Lxts_enc_6: + vst1.64 {@XMM[14]}, [r0,:128] @ next round tweak + + veor @XMM[4], @XMM[4], @XMM[12] +#ifndef BSAES_ASM_EXTENDED_KEY + add r4, sp, #0x90 @ pass key schedule +#else + add r4, $key, #248 @ pass key schedule +#endif + veor @XMM[5], @XMM[5], @XMM[13] + mov r5, $rounds @ pass rounds + mov r0, sp + + bl _bsaes_encrypt8 + + vld1.64 {@XMM[ 8]-@XMM[ 9]}, [r0,:128]! + vld1.64 {@XMM[10]-@XMM[11]}, [r0,:128]! + veor @XMM[0], @XMM[0], @XMM[ 8] + vld1.64 {@XMM[12]-@XMM[13]}, [r0,:128]! + veor @XMM[1], @XMM[1], @XMM[ 9] + veor @XMM[8], @XMM[4], @XMM[10] + vst1.8 {@XMM[0]-@XMM[1]}, [$out]! + veor @XMM[9], @XMM[6], @XMM[11] + veor @XMM[10], @XMM[3], @XMM[12] + vst1.8 {@XMM[8]-@XMM[9]}, [$out]! + veor @XMM[11], @XMM[7], @XMM[13] + vst1.8 {@XMM[10]-@XMM[11]}, [$out]! + + vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak + b .Lxts_enc_done + +@ put this in range for both ARM and Thumb mode adr instructions +.align 5 +.Lxts_magic: + .quad 1, 0x87 + +.align 5 +.Lxts_enc_5: + vst1.64 {@XMM[13]}, [r0,:128] @ next round tweak + + veor @XMM[3], @XMM[3], @XMM[11] +#ifndef BSAES_ASM_EXTENDED_KEY + add r4, sp, #0x90 @ pass key schedule +#else + add r4, $key, #248 @ pass key schedule +#endif + veor @XMM[4], @XMM[4], @XMM[12] + mov r5, $rounds @ pass rounds + mov r0, sp + + bl _bsaes_encrypt8 + + vld1.64 {@XMM[ 8]-@XMM[ 9]}, [r0,:128]! + vld1.64 {@XMM[10]-@XMM[11]}, [r0,:128]! + veor @XMM[0], @XMM[0], @XMM[ 8] + vld1.64 {@XMM[12]}, [r0,:128]! + veor @XMM[1], @XMM[1], @XMM[ 9] + veor @XMM[8], @XMM[4], @XMM[10] + vst1.8 {@XMM[0]-@XMM[1]}, [$out]! + veor @XMM[9], @XMM[6], @XMM[11] + veor @XMM[10], @XMM[3], @XMM[12] + vst1.8 {@XMM[8]-@XMM[9]}, [$out]! + vst1.8 {@XMM[10]}, [$out]! + + vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak + b .Lxts_enc_done +.align 4 +.Lxts_enc_4: + vst1.64 {@XMM[12]}, [r0,:128] @ next round tweak + + veor @XMM[2], @XMM[2], @XMM[10] +#ifndef BSAES_ASM_EXTENDED_KEY + add r4, sp, #0x90 @ pass key schedule +#else + add r4, $key, #248 @ pass key schedule +#endif + veor @XMM[3], @XMM[3], @XMM[11] + mov r5, $rounds @ pass rounds + mov r0, sp + + bl _bsaes_encrypt8 + + vld1.64 {@XMM[ 8]-@XMM[ 9]}, [r0,:128]! + vld1.64 {@XMM[10]-@XMM[11]}, [r0,:128]! + veor @XMM[0], @XMM[0], @XMM[ 8] + veor @XMM[1], @XMM[1], @XMM[ 9] + veor @XMM[8], @XMM[4], @XMM[10] + vst1.8 {@XMM[0]-@XMM[1]}, [$out]! + veor @XMM[9], @XMM[6], @XMM[11] + vst1.8 {@XMM[8]-@XMM[9]}, [$out]! + + vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak + b .Lxts_enc_done +.align 4 +.Lxts_enc_3: + vst1.64 {@XMM[11]}, [r0,:128] @ next round tweak + + veor @XMM[1], @XMM[1], @XMM[9] +#ifndef BSAES_ASM_EXTENDED_KEY + add r4, sp, #0x90 @ pass key schedule +#else + add r4, $key, #248 @ pass key schedule +#endif + veor @XMM[2], @XMM[2], @XMM[10] + mov r5, $rounds @ pass rounds + mov r0, sp + + bl _bsaes_encrypt8 + + vld1.64 {@XMM[8]-@XMM[9]}, [r0,:128]! + vld1.64 {@XMM[10]}, [r0,:128]! + veor @XMM[0], @XMM[0], @XMM[ 8] + veor @XMM[1], @XMM[1], @XMM[ 9] + veor @XMM[8], @XMM[4], @XMM[10] + vst1.8 {@XMM[0]-@XMM[1]}, [$out]! + vst1.8 {@XMM[8]}, [$out]! + + vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak + b .Lxts_enc_done +.align 4 +.Lxts_enc_2: + vst1.64 {@XMM[10]}, [r0,:128] @ next round tweak + + veor @XMM[0], @XMM[0], @XMM[8] +#ifndef BSAES_ASM_EXTENDED_KEY + add r4, sp, #0x90 @ pass key schedule +#else + add r4, $key, #248 @ pass key schedule +#endif + veor @XMM[1], @XMM[1], @XMM[9] + mov r5, $rounds @ pass rounds + mov r0, sp + + bl _bsaes_encrypt8 + + vld1.64 {@XMM[8]-@XMM[9]}, [r0,:128]! + veor @XMM[0], @XMM[0], @XMM[ 8] + veor @XMM[1], @XMM[1], @XMM[ 9] + vst1.8 {@XMM[0]-@XMM[1]}, [$out]! + + vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak + b .Lxts_enc_done +.align 4 +.Lxts_enc_1: + mov r0, sp + veor @XMM[0], @XMM[8] + mov r1, sp + vst1.8 {@XMM[0]}, [sp,:128] + mov r2, $key + mov r4, $fp @ preserve fp + + bl AES_encrypt + + vld1.8 {@XMM[0]}, [sp,:128] + veor @XMM[0], @XMM[0], @XMM[8] + vst1.8 {@XMM[0]}, [$out]! + mov $fp, r4 + + vmov @XMM[8], @XMM[9] @ next round tweak + +.Lxts_enc_done: +#ifndef XTS_CHAIN_TWEAK + adds $len, #0x10 + beq .Lxts_enc_ret + sub r6, $out, #0x10 + +.Lxts_enc_steal: + ldrb r0, [$inp], #1 + ldrb r1, [$out, #-0x10] + strb r0, [$out, #-0x10] + strb r1, [$out], #1 + + subs $len, #1 + bhi .Lxts_enc_steal + + vld1.8 {@XMM[0]}, [r6] + mov r0, sp + veor @XMM[0], @XMM[0], @XMM[8] + mov r1, sp + vst1.8 {@XMM[0]}, [sp,:128] + mov r2, $key + mov r4, $fp @ preserve fp + + bl AES_encrypt + + vld1.8 {@XMM[0]}, [sp,:128] + veor @XMM[0], @XMM[0], @XMM[8] + vst1.8 {@XMM[0]}, [r6] + mov $fp, r4 +#endif + +.Lxts_enc_ret: + bic r0, $fp, #0xf + vmov.i32 q0, #0 + vmov.i32 q1, #0 +#ifdef XTS_CHAIN_TWEAK + ldr r1, [$fp, #0x20+VFP_ABI_FRAME] @ chain tweak +#endif +.Lxts_enc_bzero: @ wipe key schedule [if any] + vstmia sp!, {q0-q1} + cmp sp, r0 + bne .Lxts_enc_bzero + + mov sp, $fp +#ifdef XTS_CHAIN_TWEAK + vst1.8 {@XMM[8]}, [r1] +#endif + VFP_ABI_POP + ldmia sp!, {r4-r10, pc} @ return + +.size bsaes_xts_encrypt,.-bsaes_xts_encrypt + +.globl bsaes_xts_decrypt +.type bsaes_xts_decrypt,%function +.align 4 +bsaes_xts_decrypt: + mov ip, sp + stmdb sp!, {r4-r10, lr} @ 0x20 + VFP_ABI_PUSH + mov r6, sp @ future $fp + + mov $inp, r0 + mov $out, r1 + mov $len, r2 + mov $key, r3 + + sub r0, sp, #0x10 @ 0x10 + bic r0, #0xf @ align at 16 bytes + mov sp, r0 + +#ifdef XTS_CHAIN_TWEAK + ldr r0, [ip] @ pointer to input tweak +#else + @ generate initial tweak + ldr r0, [ip, #4] @ iv[] + mov r1, sp + ldr r2, [ip, #0] @ key2 + bl AES_encrypt + mov r0, sp @ pointer to initial tweak +#endif + + ldr $rounds, [$key, #240] @ get # of rounds + mov $fp, r6 +#ifndef BSAES_ASM_EXTENDED_KEY + @ allocate the key schedule on the stack + sub r12, sp, $rounds, lsl#7 @ 128 bytes per inner round key + @ add r12, #`128-32` @ size of bit-sliced key schedule + sub r12, #`32+16` @ place for tweak[9] + + @ populate the key schedule + mov r4, $key @ pass key + mov r5, $rounds @ pass # of rounds + mov sp, r12 + add r12, #0x90 @ pass key schedule + bl _bsaes_key_convert + add r4, sp, #0x90 + vldmia r4, {@XMM[6]} + vstmia r12, {@XMM[15]} @ save last round key + veor @XMM[7], @XMM[7], @XMM[6] @ fix up round 0 key + vstmia r4, {@XMM[7]} +#else + ldr r12, [$key, #244] + eors r12, #1 + beq 0f + + str r12, [$key, #244] + mov r4, $key @ pass key + mov r5, $rounds @ pass # of rounds + add r12, $key, #248 @ pass key schedule + bl _bsaes_key_convert + add r4, $key, #248 + vldmia r4, {@XMM[6]} + vstmia r12, {@XMM[15]} @ save last round key + veor @XMM[7], @XMM[7], @XMM[6] @ fix up round 0 key + vstmia r4, {@XMM[7]} + +.align 2 +0: sub sp, #0x90 @ place for tweak[9] +#endif + vld1.8 {@XMM[8]}, [r0] @ initial tweak + adr $magic, .Lxts_magic + + tst $len, #0xf @ if not multiple of 16 + it ne @ Thumb2 thing, sanity check in ARM + subne $len, #0x10 @ subtract another 16 bytes + subs $len, #0x80 + + blo .Lxts_dec_short + b .Lxts_dec_loop + +.align 4 +.Lxts_dec_loop: + vldmia $magic, {$twmask} @ load XTS magic + vshr.s64 @T[0], @XMM[8], #63 + mov r0, sp + vand @T[0], @T[0], $twmask +___ +for($i=9;$i<16;$i++) { +$code.=<<___; + vadd.u64 @XMM[$i], @XMM[$i-1], @XMM[$i-1] + vst1.64 {@XMM[$i-1]}, [r0,:128]! + vswp `&Dhi("@T[0]")`,`&Dlo("@T[0]")` + vshr.s64 @T[1], @XMM[$i], #63 + veor @XMM[$i], @XMM[$i], @T[0] + vand @T[1], @T[1], $twmask +___ + @T=reverse(@T); + +$code.=<<___ if ($i>=10); + vld1.8 {@XMM[$i-10]}, [$inp]! +___ +$code.=<<___ if ($i>=11); + veor @XMM[$i-11], @XMM[$i-11], @XMM[$i-3] +___ +} +$code.=<<___; + vadd.u64 @XMM[8], @XMM[15], @XMM[15] + vst1.64 {@XMM[15]}, [r0,:128]! + vswp `&Dhi("@T[0]")`,`&Dlo("@T[0]")` + veor @XMM[8], @XMM[8], @T[0] + vst1.64 {@XMM[8]}, [r0,:128] @ next round tweak + + vld1.8 {@XMM[6]-@XMM[7]}, [$inp]! + veor @XMM[5], @XMM[5], @XMM[13] +#ifndef BSAES_ASM_EXTENDED_KEY + add r4, sp, #0x90 @ pass key schedule +#else + add r4, $key, #248 @ pass key schedule +#endif + veor @XMM[6], @XMM[6], @XMM[14] + mov r5, $rounds @ pass rounds + veor @XMM[7], @XMM[7], @XMM[15] + mov r0, sp + + bl _bsaes_decrypt8 + + vld1.64 {@XMM[ 8]-@XMM[ 9]}, [r0,:128]! + vld1.64 {@XMM[10]-@XMM[11]}, [r0,:128]! + veor @XMM[0], @XMM[0], @XMM[ 8] + vld1.64 {@XMM[12]-@XMM[13]}, [r0,:128]! + veor @XMM[1], @XMM[1], @XMM[ 9] + veor @XMM[8], @XMM[6], @XMM[10] + vst1.8 {@XMM[0]-@XMM[1]}, [$out]! + veor @XMM[9], @XMM[4], @XMM[11] + vld1.64 {@XMM[14]-@XMM[15]}, [r0,:128]! + veor @XMM[10], @XMM[2], @XMM[12] + vst1.8 {@XMM[8]-@XMM[9]}, [$out]! + veor @XMM[11], @XMM[7], @XMM[13] + veor @XMM[12], @XMM[3], @XMM[14] + vst1.8 {@XMM[10]-@XMM[11]}, [$out]! + veor @XMM[13], @XMM[5], @XMM[15] + vst1.8 {@XMM[12]-@XMM[13]}, [$out]! + + vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak + + subs $len, #0x80 + bpl .Lxts_dec_loop + +.Lxts_dec_short: + adds $len, #0x70 + bmi .Lxts_dec_done + + vldmia $magic, {$twmask} @ load XTS magic + vshr.s64 @T[0], @XMM[8], #63 + mov r0, sp + vand @T[0], @T[0], $twmask +___ +for($i=9;$i<16;$i++) { +$code.=<<___; + vadd.u64 @XMM[$i], @XMM[$i-1], @XMM[$i-1] + vst1.64 {@XMM[$i-1]}, [r0,:128]! + vswp `&Dhi("@T[0]")`,`&Dlo("@T[0]")` + vshr.s64 @T[1], @XMM[$i], #63 + veor @XMM[$i], @XMM[$i], @T[0] + vand @T[1], @T[1], $twmask +___ + @T=reverse(@T); + +$code.=<<___ if ($i>=10); + vld1.8 {@XMM[$i-10]}, [$inp]! + subs $len, #0x10 + bmi .Lxts_dec_`$i-9` +___ +$code.=<<___ if ($i>=11); + veor @XMM[$i-11], @XMM[$i-11], @XMM[$i-3] +___ +} +$code.=<<___; + sub $len, #0x10 + vst1.64 {@XMM[15]}, [r0,:128] @ next round tweak + + vld1.8 {@XMM[6]}, [$inp]! + veor @XMM[5], @XMM[5], @XMM[13] +#ifndef BSAES_ASM_EXTENDED_KEY + add r4, sp, #0x90 @ pass key schedule +#else + add r4, $key, #248 @ pass key schedule +#endif + veor @XMM[6], @XMM[6], @XMM[14] + mov r5, $rounds @ pass rounds + mov r0, sp + + bl _bsaes_decrypt8 + + vld1.64 {@XMM[ 8]-@XMM[ 9]}, [r0,:128]! + vld1.64 {@XMM[10]-@XMM[11]}, [r0,:128]! + veor @XMM[0], @XMM[0], @XMM[ 8] + vld1.64 {@XMM[12]-@XMM[13]}, [r0,:128]! + veor @XMM[1], @XMM[1], @XMM[ 9] + veor @XMM[8], @XMM[6], @XMM[10] + vst1.8 {@XMM[0]-@XMM[1]}, [$out]! + veor @XMM[9], @XMM[4], @XMM[11] + vld1.64 {@XMM[14]}, [r0,:128]! + veor @XMM[10], @XMM[2], @XMM[12] + vst1.8 {@XMM[8]-@XMM[9]}, [$out]! + veor @XMM[11], @XMM[7], @XMM[13] + veor @XMM[12], @XMM[3], @XMM[14] + vst1.8 {@XMM[10]-@XMM[11]}, [$out]! + vst1.8 {@XMM[12]}, [$out]! + + vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak + b .Lxts_dec_done +.align 4 +.Lxts_dec_6: + vst1.64 {@XMM[14]}, [r0,:128] @ next round tweak + + veor @XMM[4], @XMM[4], @XMM[12] +#ifndef BSAES_ASM_EXTENDED_KEY + add r4, sp, #0x90 @ pass key schedule +#else + add r4, $key, #248 @ pass key schedule +#endif + veor @XMM[5], @XMM[5], @XMM[13] + mov r5, $rounds @ pass rounds + mov r0, sp + + bl _bsaes_decrypt8 + + vld1.64 {@XMM[ 8]-@XMM[ 9]}, [r0,:128]! + vld1.64 {@XMM[10]-@XMM[11]}, [r0,:128]! + veor @XMM[0], @XMM[0], @XMM[ 8] + vld1.64 {@XMM[12]-@XMM[13]}, [r0,:128]! + veor @XMM[1], @XMM[1], @XMM[ 9] + veor @XMM[8], @XMM[6], @XMM[10] + vst1.8 {@XMM[0]-@XMM[1]}, [$out]! + veor @XMM[9], @XMM[4], @XMM[11] + veor @XMM[10], @XMM[2], @XMM[12] + vst1.8 {@XMM[8]-@XMM[9]}, [$out]! + veor @XMM[11], @XMM[7], @XMM[13] + vst1.8 {@XMM[10]-@XMM[11]}, [$out]! + + vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak + b .Lxts_dec_done +.align 4 +.Lxts_dec_5: + vst1.64 {@XMM[13]}, [r0,:128] @ next round tweak + + veor @XMM[3], @XMM[3], @XMM[11] +#ifndef BSAES_ASM_EXTENDED_KEY + add r4, sp, #0x90 @ pass key schedule +#else + add r4, $key, #248 @ pass key schedule +#endif + veor @XMM[4], @XMM[4], @XMM[12] + mov r5, $rounds @ pass rounds + mov r0, sp + + bl _bsaes_decrypt8 + + vld1.64 {@XMM[ 8]-@XMM[ 9]}, [r0,:128]! + vld1.64 {@XMM[10]-@XMM[11]}, [r0,:128]! + veor @XMM[0], @XMM[0], @XMM[ 8] + vld1.64 {@XMM[12]}, [r0,:128]! + veor @XMM[1], @XMM[1], @XMM[ 9] + veor @XMM[8], @XMM[6], @XMM[10] + vst1.8 {@XMM[0]-@XMM[1]}, [$out]! + veor @XMM[9], @XMM[4], @XMM[11] + veor @XMM[10], @XMM[2], @XMM[12] + vst1.8 {@XMM[8]-@XMM[9]}, [$out]! + vst1.8 {@XMM[10]}, [$out]! + + vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak + b .Lxts_dec_done +.align 4 +.Lxts_dec_4: + vst1.64 {@XMM[12]}, [r0,:128] @ next round tweak + + veor @XMM[2], @XMM[2], @XMM[10] +#ifndef BSAES_ASM_EXTENDED_KEY + add r4, sp, #0x90 @ pass key schedule +#else + add r4, $key, #248 @ pass key schedule +#endif + veor @XMM[3], @XMM[3], @XMM[11] + mov r5, $rounds @ pass rounds + mov r0, sp + + bl _bsaes_decrypt8 + + vld1.64 {@XMM[ 8]-@XMM[ 9]}, [r0,:128]! + vld1.64 {@XMM[10]-@XMM[11]}, [r0,:128]! + veor @XMM[0], @XMM[0], @XMM[ 8] + veor @XMM[1], @XMM[1], @XMM[ 9] + veor @XMM[8], @XMM[6], @XMM[10] + vst1.8 {@XMM[0]-@XMM[1]}, [$out]! + veor @XMM[9], @XMM[4], @XMM[11] + vst1.8 {@XMM[8]-@XMM[9]}, [$out]! + + vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak + b .Lxts_dec_done +.align 4 +.Lxts_dec_3: + vst1.64 {@XMM[11]}, [r0,:128] @ next round tweak + + veor @XMM[1], @XMM[1], @XMM[9] +#ifndef BSAES_ASM_EXTENDED_KEY + add r4, sp, #0x90 @ pass key schedule +#else + add r4, $key, #248 @ pass key schedule +#endif + veor @XMM[2], @XMM[2], @XMM[10] + mov r5, $rounds @ pass rounds + mov r0, sp + + bl _bsaes_decrypt8 + + vld1.64 {@XMM[8]-@XMM[9]}, [r0,:128]! + vld1.64 {@XMM[10]}, [r0,:128]! + veor @XMM[0], @XMM[0], @XMM[ 8] + veor @XMM[1], @XMM[1], @XMM[ 9] + veor @XMM[8], @XMM[6], @XMM[10] + vst1.8 {@XMM[0]-@XMM[1]}, [$out]! + vst1.8 {@XMM[8]}, [$out]! + + vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak + b .Lxts_dec_done +.align 4 +.Lxts_dec_2: + vst1.64 {@XMM[10]}, [r0,:128] @ next round tweak + + veor @XMM[0], @XMM[0], @XMM[8] +#ifndef BSAES_ASM_EXTENDED_KEY + add r4, sp, #0x90 @ pass key schedule +#else + add r4, $key, #248 @ pass key schedule +#endif + veor @XMM[1], @XMM[1], @XMM[9] + mov r5, $rounds @ pass rounds + mov r0, sp + + bl _bsaes_decrypt8 + + vld1.64 {@XMM[8]-@XMM[9]}, [r0,:128]! + veor @XMM[0], @XMM[0], @XMM[ 8] + veor @XMM[1], @XMM[1], @XMM[ 9] + vst1.8 {@XMM[0]-@XMM[1]}, [$out]! + + vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak + b .Lxts_dec_done +.align 4 +.Lxts_dec_1: + mov r0, sp + veor @XMM[0], @XMM[8] + mov r1, sp + vst1.8 {@XMM[0]}, [sp,:128] + mov r2, $key + mov r4, $fp @ preserve fp + mov r5, $magic @ preserve magic + + bl AES_decrypt + + vld1.8 {@XMM[0]}, [sp,:128] + veor @XMM[0], @XMM[0], @XMM[8] + vst1.8 {@XMM[0]}, [$out]! + mov $fp, r4 + mov $magic, r5 + + vmov @XMM[8], @XMM[9] @ next round tweak + +.Lxts_dec_done: +#ifndef XTS_CHAIN_TWEAK + adds $len, #0x10 + beq .Lxts_dec_ret + + @ calculate one round of extra tweak for the stolen ciphertext + vldmia $magic, {$twmask} + vshr.s64 @XMM[6], @XMM[8], #63 + vand @XMM[6], @XMM[6], $twmask + vadd.u64 @XMM[9], @XMM[8], @XMM[8] + vswp `&Dhi("@XMM[6]")`,`&Dlo("@XMM[6]")` + veor @XMM[9], @XMM[9], @XMM[6] + + @ perform the final decryption with the last tweak value + vld1.8 {@XMM[0]}, [$inp]! + mov r0, sp + veor @XMM[0], @XMM[0], @XMM[9] + mov r1, sp + vst1.8 {@XMM[0]}, [sp,:128] + mov r2, $key + mov r4, $fp @ preserve fp + + bl AES_decrypt + + vld1.8 {@XMM[0]}, [sp,:128] + veor @XMM[0], @XMM[0], @XMM[9] + vst1.8 {@XMM[0]}, [$out] + + mov r6, $out +.Lxts_dec_steal: + ldrb r1, [$out] + ldrb r0, [$inp], #1 + strb r1, [$out, #0x10] + strb r0, [$out], #1 + + subs $len, #1 + bhi .Lxts_dec_steal + + vld1.8 {@XMM[0]}, [r6] + mov r0, sp + veor @XMM[0], @XMM[8] + mov r1, sp + vst1.8 {@XMM[0]}, [sp,:128] + mov r2, $key + + bl AES_decrypt + + vld1.8 {@XMM[0]}, [sp,:128] + veor @XMM[0], @XMM[0], @XMM[8] + vst1.8 {@XMM[0]}, [r6] + mov $fp, r4 +#endif + +.Lxts_dec_ret: + bic r0, $fp, #0xf + vmov.i32 q0, #0 + vmov.i32 q1, #0 +#ifdef XTS_CHAIN_TWEAK + ldr r1, [$fp, #0x20+VFP_ABI_FRAME] @ chain tweak +#endif +.Lxts_dec_bzero: @ wipe key schedule [if any] + vstmia sp!, {q0-q1} + cmp sp, r0 + bne .Lxts_dec_bzero + + mov sp, $fp +#ifdef XTS_CHAIN_TWEAK + vst1.8 {@XMM[8]}, [r1] +#endif + VFP_ABI_POP + ldmia sp!, {r4-r10, pc} @ return + +.size bsaes_xts_decrypt,.-bsaes_xts_decrypt +___ +} +$code.=<<___; +#endif +___ + +$code =~ s/\`([^\`]*)\`/eval($1)/gem; + +open SELF,$0; +while(<SELF>) { + next if (/^#!/); + last if (!s/^#/@/ and !/^$/); + print; +} +close SELF; + +print $code; + +close STDOUT; diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild index 59ceae8f3c95..c38b58c80202 100644 --- a/arch/arm/include/asm/Kbuild +++ b/arch/arm/include/asm/Kbuild @@ -24,6 +24,7 @@ generic-y += sembuf.h generic-y += serial.h generic-y += shmbuf.h generic-y += siginfo.h +generic-y += simd.h generic-y += sizes.h generic-y += socket.h generic-y += sockios.h @@ -32,3 +33,4 @@ generic-y += termios.h generic-y += timex.h generic-y += trace_clock.h generic-y += unaligned.h +generic-y += preempt.h diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h index 5665134bfa3e..0704e0cf5571 100644 --- a/arch/arm/include/asm/arch_timer.h +++ b/arch/arm/include/asm/arch_timer.h @@ -87,17 +87,43 @@ static inline u64 arch_counter_get_cntvct(void) return cval; } -static inline void arch_counter_set_user_access(void) +static inline u32 arch_timer_get_cntkctl(void) { u32 cntkctl; - asm volatile("mrc p15, 0, %0, c14, c1, 0" : "=r" (cntkctl)); + return cntkctl; +} - /* disable user access to everything */ - cntkctl &= ~((3 << 8) | (7 << 0)); - +static inline void arch_timer_set_cntkctl(u32 cntkctl) +{ asm volatile("mcr p15, 0, %0, c14, c1, 0" : : "r" (cntkctl)); } + +static inline void arch_counter_set_user_access(void) +{ + u32 cntkctl = arch_timer_get_cntkctl(); + + /* Disable user access to both physical/virtual counters/timers */ + /* Also disable virtual event stream */ + cntkctl &= ~(ARCH_TIMER_USR_PT_ACCESS_EN + | ARCH_TIMER_USR_VT_ACCESS_EN + | ARCH_TIMER_VIRT_EVT_EN + | ARCH_TIMER_USR_VCT_ACCESS_EN + | ARCH_TIMER_USR_PCT_ACCESS_EN); + arch_timer_set_cntkctl(cntkctl); +} + +static inline void arch_timer_evtstrm_enable(int divider) +{ + u32 cntkctl = arch_timer_get_cntkctl(); + cntkctl &= ~ARCH_TIMER_EVT_TRIGGER_MASK; + /* Set the divider and enable virtual event stream */ + cntkctl |= (divider << ARCH_TIMER_EVT_TRIGGER_SHIFT) + | ARCH_TIMER_VIRT_EVT_EN; + arch_timer_set_cntkctl(cntkctl); + elf_hwcap |= HWCAP_EVTSTRM; +} + #endif #endif diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h index fcc1b5bf6979..5c2285160575 100644 --- a/arch/arm/include/asm/assembler.h +++ b/arch/arm/include/asm/assembler.h @@ -53,6 +53,13 @@ #define put_byte_3 lsl #0 #endif +/* Select code for any configuration running in BE8 mode */ +#ifdef CONFIG_CPU_ENDIAN_BE8 +#define ARM_BE8(code...) code +#else +#define ARM_BE8(code...) +#endif + /* * Data preload for architectures that support it */ diff --git a/arch/arm/include/asm/atomic.h b/arch/arm/include/asm/atomic.h index da1c77d39327..62d2cb53b069 100644 --- a/arch/arm/include/asm/atomic.h +++ b/arch/arm/include/asm/atomic.h @@ -12,6 +12,7 @@ #define __ASM_ARM_ATOMIC_H #include <linux/compiler.h> +#include <linux/prefetch.h> #include <linux/types.h> #include <linux/irqflags.h> #include <asm/barrier.h> @@ -41,6 +42,7 @@ static inline void atomic_add(int i, atomic_t *v) unsigned long tmp; int result; + prefetchw(&v->counter); __asm__ __volatile__("@ atomic_add\n" "1: ldrex %0, [%3]\n" " add %0, %0, %4\n" @@ -79,6 +81,7 @@ static inline void atomic_sub(int i, atomic_t *v) unsigned long tmp; int result; + prefetchw(&v->counter); __asm__ __volatile__("@ atomic_sub\n" "1: ldrex %0, [%3]\n" " sub %0, %0, %4\n" @@ -114,7 +117,8 @@ static inline int atomic_sub_return(int i, atomic_t *v) static inline int atomic_cmpxchg(atomic_t *ptr, int old, int new) { - unsigned long oldval, res; + int oldval; + unsigned long res; smp_mb(); @@ -134,21 +138,6 @@ static inline int atomic_cmpxchg(atomic_t *ptr, int old, int new) return oldval; } -static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr) -{ - unsigned long tmp, tmp2; - - __asm__ __volatile__("@ atomic_clear_mask\n" -"1: ldrex %0, [%3]\n" -" bic %0, %0, %4\n" -" strex %1, %0, [%3]\n" -" teq %1, #0\n" -" bne 1b" - : "=&r" (tmp), "=&r" (tmp2), "+Qo" (*addr) - : "r" (addr), "Ir" (mask) - : "cc"); -} - #else /* ARM_ARCH_6 */ #ifdef CONFIG_SMP @@ -197,15 +186,6 @@ static inline int atomic_cmpxchg(atomic_t *v, int old, int new) return ret; } -static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr) -{ - unsigned long flags; - - raw_local_irq_save(flags); - *addr &= ~mask; - raw_local_irq_restore(flags); -} - #endif /* __LINUX_ARM_ARCH__ */ #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) @@ -238,15 +218,15 @@ static inline int __atomic_add_unless(atomic_t *v, int a, int u) #ifndef CONFIG_GENERIC_ATOMIC64 typedef struct { - u64 __aligned(8) counter; + long long counter; } atomic64_t; #define ATOMIC64_INIT(i) { (i) } #ifdef CONFIG_ARM_LPAE -static inline u64 atomic64_read(const atomic64_t *v) +static inline long long atomic64_read(const atomic64_t *v) { - u64 result; + long long result; __asm__ __volatile__("@ atomic64_read\n" " ldrd %0, %H0, [%1]" @@ -257,7 +237,7 @@ static inline u64 atomic64_read(const atomic64_t *v) return result; } -static inline void atomic64_set(atomic64_t *v, u64 i) +static inline void atomic64_set(atomic64_t *v, long long i) { __asm__ __volatile__("@ atomic64_set\n" " strd %2, %H2, [%1]" @@ -266,9 +246,9 @@ static inline void atomic64_set(atomic64_t *v, u64 i) ); } #else -static inline u64 atomic64_read(const atomic64_t *v) +static inline long long atomic64_read(const atomic64_t *v) { - u64 result; + long long result; __asm__ __volatile__("@ atomic64_read\n" " ldrexd %0, %H0, [%1]" @@ -279,10 +259,11 @@ static inline u64 atomic64_read(const atomic64_t *v) return result; } -static inline void atomic64_set(atomic64_t *v, u64 i) +static inline void atomic64_set(atomic64_t *v, long long i) { - u64 tmp; + long long tmp; + prefetchw(&v->counter); __asm__ __volatile__("@ atomic64_set\n" "1: ldrexd %0, %H0, [%2]\n" " strexd %0, %3, %H3, [%2]\n" @@ -294,15 +275,16 @@ static inline void atomic64_set(atomic64_t *v, u64 i) } #endif -static inline void atomic64_add(u64 i, atomic64_t *v) +static inline void atomic64_add(long long i, atomic64_t *v) { - u64 result; + long long result; unsigned long tmp; + prefetchw(&v->counter); __asm__ __volatile__("@ atomic64_add\n" "1: ldrexd %0, %H0, [%3]\n" -" adds %0, %0, %4\n" -" adc %H0, %H0, %H4\n" +" adds %Q0, %Q0, %Q4\n" +" adc %R0, %R0, %R4\n" " strexd %1, %0, %H0, [%3]\n" " teq %1, #0\n" " bne 1b" @@ -311,17 +293,17 @@ static inline void atomic64_add(u64 i, atomic64_t *v) : "cc"); } -static inline u64 atomic64_add_return(u64 i, atomic64_t *v) +static inline long long atomic64_add_return(long long i, atomic64_t *v) { - u64 result; + long long result; unsigned long tmp; smp_mb(); __asm__ __volatile__("@ atomic64_add_return\n" "1: ldrexd %0, %H0, [%3]\n" -" adds %0, %0, %4\n" -" adc %H0, %H0, %H4\n" +" adds %Q0, %Q0, %Q4\n" +" adc %R0, %R0, %R4\n" " strexd %1, %0, %H0, [%3]\n" " teq %1, #0\n" " bne 1b" @@ -334,15 +316,16 @@ static inline u64 atomic64_add_return(u64 i, atomic64_t *v) return result; } -static inline void atomic64_sub(u64 i, atomic64_t *v) +static inline void atomic64_sub(long long i, atomic64_t *v) { - u64 result; + long long result; unsigned long tmp; + prefetchw(&v->counter); __asm__ __volatile__("@ atomic64_sub\n" "1: ldrexd %0, %H0, [%3]\n" -" subs %0, %0, %4\n" -" sbc %H0, %H0, %H4\n" +" subs %Q0, %Q0, %Q4\n" +" sbc %R0, %R0, %R4\n" " strexd %1, %0, %H0, [%3]\n" " teq %1, #0\n" " bne 1b" @@ -351,17 +334,17 @@ static inline void atomic64_sub(u64 i, atomic64_t *v) : "cc"); } -static inline u64 atomic64_sub_return(u64 i, atomic64_t *v) +static inline long long atomic64_sub_return(long long i, atomic64_t *v) { - u64 result; + long long result; unsigned long tmp; smp_mb(); __asm__ __volatile__("@ atomic64_sub_return\n" "1: ldrexd %0, %H0, [%3]\n" -" subs %0, %0, %4\n" -" sbc %H0, %H0, %H4\n" +" subs %Q0, %Q0, %Q4\n" +" sbc %R0, %R0, %R4\n" " strexd %1, %0, %H0, [%3]\n" " teq %1, #0\n" " bne 1b" @@ -374,9 +357,10 @@ static inline u64 atomic64_sub_return(u64 i, atomic64_t *v) return result; } -static inline u64 atomic64_cmpxchg(atomic64_t *ptr, u64 old, u64 new) +static inline long long atomic64_cmpxchg(atomic64_t *ptr, long long old, + long long new) { - u64 oldval; + long long oldval; unsigned long res; smp_mb(); @@ -398,9 +382,9 @@ static inline u64 atomic64_cmpxchg(atomic64_t *ptr, u64 old, u64 new) return oldval; } -static inline u64 atomic64_xchg(atomic64_t *ptr, u64 new) +static inline long long atomic64_xchg(atomic64_t *ptr, long long new) { - u64 result; + long long result; unsigned long tmp; smp_mb(); @@ -419,18 +403,18 @@ static inline u64 atomic64_xchg(atomic64_t *ptr, u64 new) return result; } -static inline u64 atomic64_dec_if_positive(atomic64_t *v) +static inline long long atomic64_dec_if_positive(atomic64_t *v) { - u64 result; + long long result; unsigned long tmp; smp_mb(); __asm__ __volatile__("@ atomic64_dec_if_positive\n" "1: ldrexd %0, %H0, [%3]\n" -" subs %0, %0, #1\n" -" sbc %H0, %H0, #0\n" -" teq %H0, #0\n" +" subs %Q0, %Q0, #1\n" +" sbc %R0, %R0, #0\n" +" teq %R0, #0\n" " bmi 2f\n" " strexd %1, %0, %H0, [%3]\n" " teq %1, #0\n" @@ -445,9 +429,9 @@ static inline u64 atomic64_dec_if_positive(atomic64_t *v) return result; } -static inline int atomic64_add_unless(atomic64_t *v, u64 a, u64 u) +static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u) { - u64 val; + long long val; unsigned long tmp; int ret = 1; @@ -459,8 +443,8 @@ static inline int atomic64_add_unless(atomic64_t *v, u64 a, u64 u) " teqeq %H0, %H5\n" " moveq %1, #0\n" " beq 2f\n" -" adds %0, %0, %6\n" -" adc %H0, %H0, %H6\n" +" adds %Q0, %Q0, %Q6\n" +" adc %R0, %R0, %R6\n" " strexd %2, %0, %H0, [%4]\n" " teq %2, #0\n" " bne 1b\n" diff --git a/arch/arm/include/asm/bL_switcher.h b/arch/arm/include/asm/bL_switcher.h new file mode 100644 index 000000000000..1714800fa113 --- /dev/null +++ b/arch/arm/include/asm/bL_switcher.h @@ -0,0 +1,77 @@ +/* + * arch/arm/include/asm/bL_switcher.h + * + * Created by: Nicolas Pitre, April 2012 + * Copyright: (C) 2012-2013 Linaro Limited + * + * 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 ASM_BL_SWITCHER_H +#define ASM_BL_SWITCHER_H + +#include <linux/compiler.h> +#include <linux/types.h> + +typedef void (*bL_switch_completion_handler)(void *cookie); + +int bL_switch_request_cb(unsigned int cpu, unsigned int new_cluster_id, + bL_switch_completion_handler completer, + void *completer_cookie); +static inline int bL_switch_request(unsigned int cpu, unsigned int new_cluster_id) +{ + return bL_switch_request_cb(cpu, new_cluster_id, NULL, NULL); +} + +/* + * Register here to be notified about runtime enabling/disabling of + * the switcher. + * + * The notifier chain is called with the switcher activation lock held: + * the switcher will not be enabled or disabled during callbacks. + * Callbacks must not call bL_switcher_{get,put}_enabled(). + */ +#define BL_NOTIFY_PRE_ENABLE 0 +#define BL_NOTIFY_POST_ENABLE 1 +#define BL_NOTIFY_PRE_DISABLE 2 +#define BL_NOTIFY_POST_DISABLE 3 + +#ifdef CONFIG_BL_SWITCHER + +int bL_switcher_register_notifier(struct notifier_block *nb); +int bL_switcher_unregister_notifier(struct notifier_block *nb); + +/* + * Use these functions to temporarily prevent enabling/disabling of + * the switcher. + * bL_switcher_get_enabled() returns true if the switcher is currently + * enabled. Each call to bL_switcher_get_enabled() must be followed + * by a call to bL_switcher_put_enabled(). These functions are not + * recursive. + */ +bool bL_switcher_get_enabled(void); +void bL_switcher_put_enabled(void); + +int bL_switcher_trace_trigger(void); +int bL_switcher_get_logical_index(u32 mpidr); + +#else +static inline int bL_switcher_register_notifier(struct notifier_block *nb) +{ + return 0; +} + +static inline int bL_switcher_unregister_notifier(struct notifier_block *nb) +{ + return 0; +} + +static inline bool bL_switcher_get_enabled(void) { return false; } +static inline void bL_switcher_put_enabled(void) { } +static inline int bL_switcher_trace_trigger(void) { return 0; } +static inline int bL_switcher_get_logical_index(u32 mpidr) { return -EUNATCH; } +#endif /* CONFIG_BL_SWITCHER */ + +#endif diff --git a/arch/arm/include/asm/bug.h b/arch/arm/include/asm/bug.h index 7af5c6c3653a..b274bde24905 100644 --- a/arch/arm/include/asm/bug.h +++ b/arch/arm/include/asm/bug.h @@ -2,6 +2,8 @@ #define _ASMARM_BUG_H #include <linux/linkage.h> +#include <linux/types.h> +#include <asm/opcodes.h> #ifdef CONFIG_BUG @@ -12,10 +14,10 @@ */ #ifdef CONFIG_THUMB2_KERNEL #define BUG_INSTR_VALUE 0xde02 -#define BUG_INSTR_TYPE ".hword " +#define BUG_INSTR(__value) __inst_thumb16(__value) #else #define BUG_INSTR_VALUE 0xe7f001f2 -#define BUG_INSTR_TYPE ".word " +#define BUG_INSTR(__value) __inst_arm(__value) #endif @@ -33,7 +35,7 @@ #define __BUG(__file, __line, __value) \ do { \ - asm volatile("1:\t" BUG_INSTR_TYPE #__value "\n" \ + asm volatile("1:\t" BUG_INSTR(__value) "\n" \ ".pushsection .rodata.str, \"aMS\", %progbits, 1\n" \ "2:\t.asciz " #__file "\n" \ ".popsection\n" \ @@ -48,7 +50,7 @@ do { \ #define __BUG(__file, __line, __value) \ do { \ - asm volatile(BUG_INSTR_TYPE #__value); \ + asm volatile(BUG_INSTR(__value) "\n"); \ unreachable(); \ } while (0) #endif /* CONFIG_DEBUG_BUGVERBOSE */ diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h index 15f2d5bf8875..ee753f1749cd 100644 --- a/arch/arm/include/asm/cacheflush.h +++ b/arch/arm/include/asm/cacheflush.h @@ -435,4 +435,50 @@ static inline void __sync_cache_range_r(volatile void *p, size_t size) #define sync_cache_w(ptr) __sync_cache_range_w(ptr, sizeof *(ptr)) #define sync_cache_r(ptr) __sync_cache_range_r(ptr, sizeof *(ptr)) +/* + * Disabling cache access for one CPU in an ARMv7 SMP system is tricky. + * To do so we must: + * + * - Clear the SCTLR.C bit to prevent further cache allocations + * - Flush the desired level of cache + * - Clear the ACTLR "SMP" bit to disable local coherency + * + * ... and so without any intervening memory access in between those steps, + * not even to the stack. + * + * WARNING -- After this has been called: + * + * - No ldrex/strex (and similar) instructions must be used. + * - The CPU is obviously no longer coherent with the other CPUs. + * - This is unlikely to work as expected if Linux is running non-secure. + * + * Note: + * + * - This is known to apply to several ARMv7 processor implementations, + * however some exceptions may exist. Caveat emptor. + * + * - The clobber list is dictated by the call to v7_flush_dcache_*. + * fp is preserved to the stack explicitly prior disabling the cache + * since adding it to the clobber list is incompatible with having + * CONFIG_FRAME_POINTER=y. ip is saved as well if ever r12-clobbering + * trampoline are inserted by the linker and to keep sp 64-bit aligned. + */ +#define v7_exit_coherency_flush(level) \ + asm volatile( \ + "stmfd sp!, {fp, ip} \n\t" \ + "mrc p15, 0, r0, c1, c0, 0 @ get SCTLR \n\t" \ + "bic r0, r0, #"__stringify(CR_C)" \n\t" \ + "mcr p15, 0, r0, c1, c0, 0 @ set SCTLR \n\t" \ + "isb \n\t" \ + "bl v7_flush_dcache_"__stringify(level)" \n\t" \ + "clrex \n\t" \ + "mrc p15, 0, r0, c1, c0, 1 @ get ACTLR \n\t" \ + "bic r0, r0, #(1 << 6) @ disable local coherency \n\t" \ + "mcr p15, 0, r0, c1, c0, 1 @ set ACTLR \n\t" \ + "isb \n\t" \ + "dsb \n\t" \ + "ldmfd sp!, {fp, ip}" \ + : : : "r0","r1","r2","r3","r4","r5","r6","r7", \ + "r9","r10","lr","memory" ) + #endif diff --git a/arch/arm/include/asm/cmpxchg.h b/arch/arm/include/asm/cmpxchg.h index 4f009c10540d..df2fbba7efc8 100644 --- a/arch/arm/include/asm/cmpxchg.h +++ b/arch/arm/include/asm/cmpxchg.h @@ -223,6 +223,42 @@ static inline unsigned long __cmpxchg_local(volatile void *ptr, return ret; } +static inline unsigned long long __cmpxchg64(unsigned long long *ptr, + unsigned long long old, + unsigned long long new) +{ + unsigned long long oldval; + unsigned long res; + + __asm__ __volatile__( +"1: ldrexd %1, %H1, [%3]\n" +" teq %1, %4\n" +" teqeq %H1, %H4\n" +" bne 2f\n" +" strexd %0, %5, %H5, [%3]\n" +" teq %0, #0\n" +" bne 1b\n" +"2:" + : "=&r" (res), "=&r" (oldval), "+Qo" (*ptr) + : "r" (ptr), "r" (old), "r" (new) + : "cc"); + + return oldval; +} + +static inline unsigned long long __cmpxchg64_mb(unsigned long long *ptr, + unsigned long long old, + unsigned long long new) +{ + unsigned long long ret; + + smp_mb(); + ret = __cmpxchg64(ptr, old, new); + smp_mb(); + + return ret; +} + #define cmpxchg_local(ptr,o,n) \ ((__typeof__(*(ptr)))__cmpxchg_local((ptr), \ (unsigned long)(o), \ @@ -230,18 +266,16 @@ static inline unsigned long __cmpxchg_local(volatile void *ptr, sizeof(*(ptr)))) #define cmpxchg64(ptr, o, n) \ - ((__typeof__(*(ptr)))atomic64_cmpxchg(container_of((ptr), \ - atomic64_t, \ - counter), \ - (unsigned long long)(o), \ - (unsigned long long)(n))) - -#define cmpxchg64_local(ptr, o, n) \ - ((__typeof__(*(ptr)))local64_cmpxchg(container_of((ptr), \ - local64_t, \ - a), \ - (unsigned long long)(o), \ - (unsigned long long)(n))) + ((__typeof__(*(ptr)))__cmpxchg64_mb((ptr), \ + (unsigned long long)(o), \ + (unsigned long long)(n))) + +#define cmpxchg64_relaxed(ptr, o, n) \ + ((__typeof__(*(ptr)))__cmpxchg64((ptr), \ + (unsigned long long)(o), \ + (unsigned long long)(n))) + +#define cmpxchg64_local(ptr, o, n) cmpxchg64_relaxed((ptr), (o), (n)) #endif /* __LINUX_ARM_ARCH__ >= 6 */ diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h index 9672e978d50d..acdde76b39bb 100644 --- a/arch/arm/include/asm/cputype.h +++ b/arch/arm/include/asm/cputype.h @@ -10,6 +10,7 @@ #define CPUID_TLBTYPE 3 #define CPUID_MPUIR 4 #define CPUID_MPIDR 5 +#define CPUID_REVIDR 6 #ifdef CONFIG_CPU_V7M #define CPUID_EXT_PFR0 0x40 diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h index 5b579b951503..e701a4d9aa59 100644 --- a/arch/arm/include/asm/dma-mapping.h +++ b/arch/arm/include/asm/dma-mapping.h @@ -11,17 +11,28 @@ #include <asm-generic/dma-coherent.h> #include <asm/memory.h> +#include <xen/xen.h> +#include <asm/xen/hypervisor.h> + #define DMA_ERROR_CODE (~0) extern struct dma_map_ops arm_dma_ops; extern struct dma_map_ops arm_coherent_dma_ops; -static inline struct dma_map_ops *get_dma_ops(struct device *dev) +static inline struct dma_map_ops *__generic_dma_ops(struct device *dev) { if (dev && dev->archdata.dma_ops) return dev->archdata.dma_ops; return &arm_dma_ops; } +static inline struct dma_map_ops *get_dma_ops(struct device *dev) +{ + if (xen_initial_domain()) + return xen_dma_ops; + else + return __generic_dma_ops(dev); +} + static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops) { BUG_ON(!dev); @@ -64,6 +75,7 @@ static inline dma_addr_t virt_to_dma(struct device *dev, void *addr) { return (dma_addr_t)__virt_to_bus((unsigned long)(addr)); } + #else static inline dma_addr_t pfn_to_dma(struct device *dev, unsigned long pfn) { @@ -86,6 +98,46 @@ static inline dma_addr_t virt_to_dma(struct device *dev, void *addr) } #endif +/* The ARM override for dma_max_pfn() */ +static inline unsigned long dma_max_pfn(struct device *dev) +{ + return PHYS_PFN_OFFSET + dma_to_pfn(dev, *dev->dma_mask); +} +#define dma_max_pfn(dev) dma_max_pfn(dev) + +static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) +{ + unsigned int offset = paddr & ~PAGE_MASK; + return pfn_to_dma(dev, __phys_to_pfn(paddr)) + offset; +} + +static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t dev_addr) +{ + unsigned int offset = dev_addr & ~PAGE_MASK; + return __pfn_to_phys(dma_to_pfn(dev, dev_addr)) + offset; +} + +static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size) +{ + u64 limit, mask; + + if (!dev->dma_mask) + return 0; + + mask = *dev->dma_mask; + + limit = (mask + 1) & ~mask; + if (limit && size > limit) + return 0; + + if ((addr | (addr + size - 1)) & ~mask) + return 0; + + return 1; +} + +static inline void dma_mark_clean(void *addr, size_t size) { } + /* * DMA errors are defined by all-bits-set in the DMA address. */ diff --git a/arch/arm/include/asm/hardirq.h b/arch/arm/include/asm/hardirq.h index 2740c2a2df63..fe3ea776dc34 100644 --- a/arch/arm/include/asm/hardirq.h +++ b/arch/arm/include/asm/hardirq.h @@ -5,7 +5,7 @@ #include <linux/threads.h> #include <asm/irq.h> -#define NR_IPI 6 +#define NR_IPI 8 typedef struct { unsigned int __softirq_pending; diff --git a/arch/arm/include/asm/hardware/coresight.h b/arch/arm/include/asm/hardware/coresight.h index 0cf7a6b842ff..ad774f37c47c 100644 --- a/arch/arm/include/asm/hardware/coresight.h +++ b/arch/arm/include/asm/hardware/coresight.h @@ -24,8 +24,8 @@ #define TRACER_TIMEOUT 10000 #define etm_writel(t, v, x) \ - (__raw_writel((v), (t)->etm_regs + (x))) -#define etm_readl(t, x) (__raw_readl((t)->etm_regs + (x))) + (writel_relaxed((v), (t)->etm_regs + (x))) +#define etm_readl(t, x) (readl_relaxed((t)->etm_regs + (x))) /* CoreSight Management Registers */ #define CSMR_LOCKACCESS 0xfb0 @@ -142,8 +142,8 @@ #define ETBFF_TRIGFL BIT(10) #define etb_writel(t, v, x) \ - (__raw_writel((v), (t)->etb_regs + (x))) -#define etb_readl(t, x) (__raw_readl((t)->etb_regs + (x))) + (writel_relaxed((v), (t)->etb_regs + (x))) +#define etb_readl(t, x) (readl_relaxed((t)->etb_regs + (x))) #define etm_lock(t) do { etm_writel((t), 0, CSMR_LOCKACCESS); } while (0) #define etm_unlock(t) \ diff --git a/arch/arm/include/asm/hardware/iop3xx-gpio.h b/arch/arm/include/asm/hardware/iop3xx-gpio.h deleted file mode 100644 index 9eda7dc92ad8..000000000000 --- a/arch/arm/include/asm/hardware/iop3xx-gpio.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * arch/arm/include/asm/hardware/iop3xx-gpio.h - * - * IOP3xx GPIO wrappers - * - * Copyright (c) 2008 Arnaud Patard <arnaud.patard@rtp-net.org> - * Based on IXP4XX gpio.h file - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __ASM_ARM_HARDWARE_IOP3XX_GPIO_H -#define __ASM_ARM_HARDWARE_IOP3XX_GPIO_H - -#include <mach/hardware.h> -#include <asm-generic/gpio.h> - -#define __ARM_GPIOLIB_COMPLEX - -#define IOP3XX_N_GPIOS 8 - -static inline int gpio_get_value(unsigned gpio) -{ - if (gpio > IOP3XX_N_GPIOS) - return __gpio_get_value(gpio); - - return gpio_line_get(gpio); -} - -static inline void gpio_set_value(unsigned gpio, int value) -{ - if (gpio > IOP3XX_N_GPIOS) { - __gpio_set_value(gpio, value); - return; - } - gpio_line_set(gpio, value); -} - -static inline int gpio_cansleep(unsigned gpio) -{ - if (gpio < IOP3XX_N_GPIOS) - return 0; - else - return __gpio_cansleep(gpio); -} - -/* - * The GPIOs are not generating any interrupt - * Note : manuals are not clear about this - */ -static inline int gpio_to_irq(int gpio) -{ - return -EINVAL; -} - -static inline int irq_to_gpio(int gpio) -{ - return -EINVAL; -} - -#endif - diff --git a/arch/arm/include/asm/hardware/iop3xx.h b/arch/arm/include/asm/hardware/iop3xx.h index 423744bf18eb..2594a95ff19a 100644 --- a/arch/arm/include/asm/hardware/iop3xx.h +++ b/arch/arm/include/asm/hardware/iop3xx.h @@ -18,16 +18,9 @@ /* * IOP3XX GPIO handling */ -#define GPIO_IN 0 -#define GPIO_OUT 1 -#define GPIO_LOW 0 -#define GPIO_HIGH 1 #define IOP3XX_GPIO_LINE(x) (x) #ifndef __ASSEMBLY__ -extern void gpio_line_config(int line, int direction); -extern int gpio_line_get(int line); -extern void gpio_line_set(int line, int value); extern int init_atu; extern int iop3xx_get_init_atu(void); #endif @@ -168,11 +161,6 @@ extern int iop3xx_get_init_atu(void); /* PERCR0 DOESN'T EXIST - index from 1! */ #define IOP3XX_PERCR0 (volatile u32 *)IOP3XX_REG_ADDR(0x0710) -/* General Purpose I/O */ -#define IOP3XX_GPOE (volatile u32 *)IOP3XX_GPIO_REG(0x0000) -#define IOP3XX_GPID (volatile u32 *)IOP3XX_GPIO_REG(0x0004) -#define IOP3XX_GPOD (volatile u32 *)IOP3XX_GPIO_REG(0x0008) - /* Timers */ #define IOP3XX_TU_TMR0 (volatile u32 *)IOP3XX_TIMER_REG(0x0000) #define IOP3XX_TU_TMR1 (volatile u32 *)IOP3XX_TIMER_REG(0x0004) diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h index d070741b2b37..3c597c222ef2 100644 --- a/arch/arm/include/asm/io.h +++ b/arch/arm/include/asm/io.h @@ -24,9 +24,11 @@ #ifdef __KERNEL__ #include <linux/types.h> +#include <linux/blk_types.h> #include <asm/byteorder.h> #include <asm/memory.h> #include <asm-generic/pci_iomap.h> +#include <xen/xen.h> /* * ISA I/O bus memory addresses are 1:1 with the physical address. @@ -372,6 +374,13 @@ extern void pci_iounmap(struct pci_dev *dev, void __iomem *addr); #define BIOVEC_MERGEABLE(vec1, vec2) \ ((bvec_to_phys((vec1)) + (vec1)->bv_len) == bvec_to_phys((vec2))) +struct bio_vec; +extern bool xen_biovec_phys_mergeable(const struct bio_vec *vec1, + const struct bio_vec *vec2); +#define BIOVEC_PHYS_MERGEABLE(vec1, vec2) \ + (__BIOVEC_PHYS_MERGEABLE(vec1, vec2) && \ + (!xen_domain() || xen_biovec_phys_mergeable(vec1, vec2))) + #ifdef CONFIG_MMU #define ARCH_HAS_VALID_PHYS_ADDR_RANGE extern int valid_phys_addr_range(phys_addr_t addr, size_t size); diff --git a/arch/arm/include/asm/kgdb.h b/arch/arm/include/asm/kgdb.h index 48066ce9ea34..0a9d5dd93294 100644 --- a/arch/arm/include/asm/kgdb.h +++ b/arch/arm/include/asm/kgdb.h @@ -11,6 +11,7 @@ #define __ARM_KGDB_H__ #include <linux/ptrace.h> +#include <asm/opcodes.h> /* * GDB assumes that we're a user process being debugged, so @@ -41,7 +42,7 @@ static inline void arch_kgdb_breakpoint(void) { - asm(".word 0xe7ffdeff"); + asm(__inst_arm(0xe7ffdeff)); } extern void kgdb_handle_bus_error(void); diff --git a/arch/arm/include/asm/kvm_arm.h b/arch/arm/include/asm/kvm_arm.h index 64e96960de29..1d3153c7eb41 100644 --- a/arch/arm/include/asm/kvm_arm.h +++ b/arch/arm/include/asm/kvm_arm.h @@ -57,6 +57,7 @@ * TSC: Trap SMC * TSW: Trap cache operations by set/way * TWI: Trap WFI + * TWE: Trap WFE * TIDCP: Trap L2CTLR/L2ECTLR * BSU_IS: Upgrade barriers to the inner shareable domain * FB: Force broadcast of all maintainance operations @@ -67,7 +68,7 @@ */ #define HCR_GUEST_MASK (HCR_TSC | HCR_TSW | HCR_TWI | HCR_VM | HCR_BSU_IS | \ HCR_FB | HCR_TAC | HCR_AMO | HCR_IMO | HCR_FMO | \ - HCR_SWIO | HCR_TIDCP) + HCR_TWE | HCR_SWIO | HCR_TIDCP) #define HCR_VIRT_EXCP_MASK (HCR_VA | HCR_VI | HCR_VF) /* System Control Register (SCTLR) bits */ @@ -95,12 +96,12 @@ #define TTBCR_IRGN1 (3 << 24) #define TTBCR_EPD1 (1 << 23) #define TTBCR_A1 (1 << 22) -#define TTBCR_T1SZ (3 << 16) +#define TTBCR_T1SZ (7 << 16) #define TTBCR_SH0 (3 << 12) #define TTBCR_ORGN0 (3 << 10) #define TTBCR_IRGN0 (3 << 8) #define TTBCR_EPD0 (1 << 7) -#define TTBCR_T0SZ 3 +#define TTBCR_T0SZ (7 << 0) #define HTCR_MASK (TTBCR_T0SZ | TTBCR_IRGN0 | TTBCR_ORGN0 | TTBCR_SH0) /* Hyp System Trap Register */ @@ -208,6 +209,8 @@ #define HSR_EC_DABT (0x24) #define HSR_EC_DABT_HYP (0x25) +#define HSR_WFI_IS_WFE (1U << 0) + #define HSR_HVC_IMM_MASK ((1UL << 16) - 1) #define HSR_DABT_S1PTW (1U << 7) diff --git a/arch/arm/include/asm/kvm_asm.h b/arch/arm/include/asm/kvm_asm.h index a2f43ddcc300..661da11f76f4 100644 --- a/arch/arm/include/asm/kvm_asm.h +++ b/arch/arm/include/asm/kvm_asm.h @@ -39,7 +39,7 @@ #define c6_IFAR 17 /* Instruction Fault Address Register */ #define c7_PAR 18 /* Physical Address Register */ #define c7_PAR_high 19 /* PAR top 32 bits */ -#define c9_L2CTLR 20 /* Cortex A15 L2 Control Register */ +#define c9_L2CTLR 20 /* Cortex A15/A7 L2 Control Register */ #define c10_PRRR 21 /* Primary Region Remap Register */ #define c10_NMRR 22 /* Normal Memory Remap Register */ #define c12_VBAR 23 /* Vector Base Address Register */ diff --git a/arch/arm/include/asm/kvm_emulate.h b/arch/arm/include/asm/kvm_emulate.h index a464e8d7b6c5..0fa90c962ac8 100644 --- a/arch/arm/include/asm/kvm_emulate.h +++ b/arch/arm/include/asm/kvm_emulate.h @@ -157,4 +157,55 @@ static inline u32 kvm_vcpu_hvc_get_imm(struct kvm_vcpu *vcpu) return kvm_vcpu_get_hsr(vcpu) & HSR_HVC_IMM_MASK; } +static inline unsigned long kvm_vcpu_get_mpidr(struct kvm_vcpu *vcpu) +{ + return vcpu->arch.cp15[c0_MPIDR]; +} + +static inline void kvm_vcpu_set_be(struct kvm_vcpu *vcpu) +{ + *vcpu_cpsr(vcpu) |= PSR_E_BIT; +} + +static inline bool kvm_vcpu_is_be(struct kvm_vcpu *vcpu) +{ + return !!(*vcpu_cpsr(vcpu) & PSR_E_BIT); +} + +static inline unsigned long vcpu_data_guest_to_host(struct kvm_vcpu *vcpu, + unsigned long data, + unsigned int len) +{ + if (kvm_vcpu_is_be(vcpu)) { + switch (len) { + case 1: + return data & 0xff; + case 2: + return be16_to_cpu(data & 0xffff); + default: + return be32_to_cpu(data); + } + } + + return data; /* Leave LE untouched */ +} + +static inline unsigned long vcpu_data_host_to_guest(struct kvm_vcpu *vcpu, + unsigned long data, + unsigned int len) +{ + if (kvm_vcpu_is_be(vcpu)) { + switch (len) { + case 1: + return data & 0xff; + case 2: + return cpu_to_be16(data & 0xffff); + default: + return cpu_to_be32(data); + } + } + + return data; /* Leave LE untouched */ +} + #endif /* __ARM_KVM_EMULATE_H__ */ diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h index 7d22517d8071..8a6f6db14ee4 100644 --- a/arch/arm/include/asm/kvm_host.h +++ b/arch/arm/include/asm/kvm_host.h @@ -38,11 +38,6 @@ #define KVM_VCPU_MAX_FEATURES 1 -/* We don't currently support large pages. */ -#define KVM_HPAGE_GFN_SHIFT(x) 0 -#define KVM_NR_PAGE_SIZES 1 -#define KVM_PAGES_PER_HPAGE(x) (1UL<<31) - #include <kvm/arm_vgic.h> struct kvm_vcpu; @@ -154,6 +149,7 @@ struct kvm_vcpu_stat { struct kvm_vcpu_init; int kvm_vcpu_set_target(struct kvm_vcpu *vcpu, const struct kvm_vcpu_init *init); +int kvm_vcpu_preferred_target(struct kvm_vcpu_init *init); unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu); int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *indices); struct kvm_one_reg; diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h index 9b28c41f4ba9..77de4a41cc50 100644 --- a/arch/arm/include/asm/kvm_mmu.h +++ b/arch/arm/include/asm/kvm_mmu.h @@ -62,6 +62,12 @@ phys_addr_t kvm_get_idmap_vector(void); int kvm_mmu_init(void); void kvm_clear_hyp_idmap(void); +static inline void kvm_set_pmd(pmd_t *pmd, pmd_t new_pmd) +{ + *pmd = new_pmd; + flush_pmd_entry(pmd); +} + static inline void kvm_set_pte(pte_t *pte, pte_t new_pte) { *pte = new_pte; @@ -103,9 +109,15 @@ static inline void kvm_set_s2pte_writable(pte_t *pte) pte_val(*pte) |= L_PTE_S2_RDWR; } +static inline void kvm_set_s2pmd_writable(pmd_t *pmd) +{ + pmd_val(*pmd) |= L_PMD_S2_RDWR; +} + struct kvm; -static inline void coherent_icache_guest_page(struct kvm *kvm, gfn_t gfn) +static inline void coherent_icache_guest_page(struct kvm *kvm, hva_t hva, + unsigned long size) { /* * If we are going to insert an instruction page and the icache is @@ -120,8 +132,7 @@ static inline void coherent_icache_guest_page(struct kvm *kvm, gfn_t gfn) * need any kind of flushing (DDI 0406C.b - Page B3-1392). */ if (icache_is_pipt()) { - unsigned long hva = gfn_to_hva(kvm, gfn); - __cpuc_coherent_user_range(hva, hva + PAGE_SIZE); + __cpuc_coherent_user_range(hva, hva + size); } else if (!icache_is_vivt_asid_tagged()) { /* any kind of VIPT cache */ __flush_icache_all(); diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h index 402a2bc6aa68..17a3fa2979e8 100644 --- a/arch/arm/include/asm/mach/arch.h +++ b/arch/arm/include/asm/mach/arch.h @@ -49,6 +49,7 @@ struct machine_desc { bool (*smp_init)(void); void (*fixup)(struct tag *, char **, struct meminfo *); + void (*init_meminfo)(void); void (*reserve)(void);/* reserve mem blocks */ void (*map_io)(void);/* IO mapping function */ void (*init_early)(void); diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h index 454d642a4070..7fc42784becb 100644 --- a/arch/arm/include/asm/mach/pci.h +++ b/arch/arm/include/asm/mach/pci.h @@ -106,8 +106,4 @@ extern int dc21285_setup(int nr, struct pci_sys_data *); extern void dc21285_preinit(void); extern void dc21285_postinit(void); -extern struct pci_ops via82c505_ops; -extern int via82c505_setup(int nr, struct pci_sys_data *); -extern void via82c505_init(void *sysdata); - #endif /* __ASM_MACH_PCI_H */ diff --git a/arch/arm/include/asm/mcpm.h b/arch/arm/include/asm/mcpm.h index fc82a88f5b69..608516ebabfe 100644 --- a/arch/arm/include/asm/mcpm.h +++ b/arch/arm/include/asm/mcpm.h @@ -42,6 +42,14 @@ extern void mcpm_entry_point(void); void mcpm_set_entry_vector(unsigned cpu, unsigned cluster, void *ptr); /* + * This sets an early poke i.e a value to be poked into some address + * from very early assembly code before the CPU is ungated. The + * address must be physical, and if 0 then nothing will happen. + */ +void mcpm_set_early_poke(unsigned cpu, unsigned cluster, + unsigned long poke_phys_addr, unsigned long poke_val); + +/* * CPU/cluster power operations API for higher subsystems to use. */ @@ -81,10 +89,40 @@ int mcpm_cpu_power_up(unsigned int cpu, unsigned int cluster); * * This will return if mcpm_platform_register() has not been called * previously in which case the caller should take appropriate action. + * + * On success, the CPU is not guaranteed to be truly halted until + * mcpm_cpu_power_down_finish() subsequently returns non-zero for the + * specified cpu. Until then, other CPUs should make sure they do not + * trash memory the target CPU might be executing/accessing. */ void mcpm_cpu_power_down(void); /** + * mcpm_cpu_power_down_finish - wait for a specified CPU to halt, and + * make sure it is powered off + * + * @cpu: CPU number within given cluster + * @cluster: cluster number for the CPU + * + * Call this function to ensure that a pending powerdown has taken + * effect and the CPU is safely parked before performing non-mcpm + * operations that may affect the CPU (such as kexec trashing the + * kernel text). + * + * It is *not* necessary to call this function if you only need to + * serialise a pending powerdown with mcpm_cpu_power_up() or a wakeup + * event. + * + * Do not call this function unless the specified CPU has already + * called mcpm_cpu_power_down() or has committed to doing so. + * + * @return: + * - zero if the CPU is in a safely parked state + * - nonzero otherwise (e.g., timeout) + */ +int mcpm_cpu_power_down_finish(unsigned int cpu, unsigned int cluster); + +/** * mcpm_cpu_suspend - bring the calling CPU in a suspended state * * @expected_residency: duration in microseconds the CPU is expected @@ -126,6 +164,7 @@ int mcpm_cpu_powered_up(void); struct mcpm_platform_ops { int (*power_up)(unsigned int cpu, unsigned int cluster); void (*power_down)(void); + int (*power_down_finish)(unsigned int cpu, unsigned int cluster); void (*suspend)(u64); void (*powered_up)(void); }; diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h index e750a938fd3c..4dd21457ef9d 100644 --- a/arch/arm/include/asm/memory.h +++ b/arch/arm/include/asm/memory.h @@ -172,8 +172,13 @@ * so that all we need to do is modify the 8-bit constant field. */ #define __PV_BITS_31_24 0x81000000 +#define __PV_BITS_7_0 0x81 + +extern u64 __pv_phys_offset; +extern u64 __pv_offset; +extern void fixup_pv_table(const void *, unsigned long); +extern const void *__pv_table_begin, *__pv_table_end; -extern unsigned long __pv_phys_offset; #define PHYS_OFFSET __pv_phys_offset #define __pv_stub(from,to,instr,type) \ @@ -185,22 +190,58 @@ extern unsigned long __pv_phys_offset; : "=r" (to) \ : "r" (from), "I" (type)) -static inline unsigned long __virt_to_phys(unsigned long x) +#define __pv_stub_mov_hi(t) \ + __asm__ volatile("@ __pv_stub_mov\n" \ + "1: mov %R0, %1\n" \ + " .pushsection .pv_table,\"a\"\n" \ + " .long 1b\n" \ + " .popsection\n" \ + : "=r" (t) \ + : "I" (__PV_BITS_7_0)) + +#define __pv_add_carry_stub(x, y) \ + __asm__ volatile("@ __pv_add_carry_stub\n" \ + "1: adds %Q0, %1, %2\n" \ + " adc %R0, %R0, #0\n" \ + " .pushsection .pv_table,\"a\"\n" \ + " .long 1b\n" \ + " .popsection\n" \ + : "+r" (y) \ + : "r" (x), "I" (__PV_BITS_31_24) \ + : "cc") + +static inline phys_addr_t __virt_to_phys(unsigned long x) { - unsigned long t; - __pv_stub(x, t, "add", __PV_BITS_31_24); + phys_addr_t t; + + if (sizeof(phys_addr_t) == 4) { + __pv_stub(x, t, "add", __PV_BITS_31_24); + } else { + __pv_stub_mov_hi(t); + __pv_add_carry_stub(x, t); + } return t; } -static inline unsigned long __phys_to_virt(unsigned long x) +static inline unsigned long __phys_to_virt(phys_addr_t x) { unsigned long t; __pv_stub(x, t, "sub", __PV_BITS_31_24); return t; } + #else -#define __virt_to_phys(x) ((x) - PAGE_OFFSET + PHYS_OFFSET) -#define __phys_to_virt(x) ((x) - PHYS_OFFSET + PAGE_OFFSET) + +static inline phys_addr_t __virt_to_phys(unsigned long x) +{ + return (phys_addr_t)x - PAGE_OFFSET + PHYS_OFFSET; +} + +static inline unsigned long __phys_to_virt(phys_addr_t x) +{ + return x - PHYS_OFFSET + PAGE_OFFSET; +} + #endif #endif #endif /* __ASSEMBLY__ */ @@ -238,16 +279,33 @@ static inline phys_addr_t virt_to_phys(const volatile void *x) static inline void *phys_to_virt(phys_addr_t x) { - return (void *)(__phys_to_virt((unsigned long)(x))); + return (void *)__phys_to_virt(x); } /* * Drivers should NOT use these either. */ #define __pa(x) __virt_to_phys((unsigned long)(x)) -#define __va(x) ((void *)__phys_to_virt((unsigned long)(x))) +#define __va(x) ((void *)__phys_to_virt((phys_addr_t)(x))) #define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) +extern phys_addr_t (*arch_virt_to_idmap)(unsigned long x); + +/* + * These are for systems that have a hardware interconnect supported alias of + * physical memory for idmap purposes. Most cases should leave these + * untouched. + */ +static inline phys_addr_t __virt_to_idmap(unsigned long x) +{ + if (arch_virt_to_idmap) + return arch_virt_to_idmap(x); + else + return __virt_to_phys(x); +} + +#define virt_to_idmap(x) __virt_to_idmap((unsigned long)(x)) + /* * Virtual <-> DMA view memory address translations * Again, these are *only* valid on the kernel direct mapped RAM diff --git a/arch/arm/include/asm/mmu.h b/arch/arm/include/asm/mmu.h index 6f18da09668b..64fd15159b7d 100644 --- a/arch/arm/include/asm/mmu.h +++ b/arch/arm/include/asm/mmu.h @@ -16,7 +16,7 @@ typedef struct { #ifdef CONFIG_CPU_HAS_ASID #define ASID_BITS 8 #define ASID_MASK ((~0ULL) << ASID_BITS) -#define ASID(mm) ((mm)->context.id.counter & ~ASID_MASK) +#define ASID(mm) ((unsigned int)((mm)->context.id.counter & ~ASID_MASK)) #else #define ASID(mm) (0) #endif diff --git a/arch/arm/include/asm/pgalloc.h b/arch/arm/include/asm/pgalloc.h index 943504f53f57..78a779361682 100644 --- a/arch/arm/include/asm/pgalloc.h +++ b/arch/arm/include/asm/pgalloc.h @@ -102,12 +102,14 @@ pte_alloc_one(struct mm_struct *mm, unsigned long addr) #else pte = alloc_pages(PGALLOC_GFP, 0); #endif - if (pte) { - if (!PageHighMem(pte)) - clean_pte_table(page_address(pte)); - pgtable_page_ctor(pte); + if (!pte) + return NULL; + if (!PageHighMem(pte)) + clean_pte_table(page_address(pte)); + if (!pgtable_page_ctor(pte)) { + __free_page(pte); + return NULL; } - return pte; } diff --git a/arch/arm/include/asm/pgtable-2level.h b/arch/arm/include/asm/pgtable-2level.h index f97ee02386ee..86a659a19526 100644 --- a/arch/arm/include/asm/pgtable-2level.h +++ b/arch/arm/include/asm/pgtable-2level.h @@ -181,6 +181,13 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr) #define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext) +/* + * We don't have huge page support for short descriptors, for the moment + * define empty stubs for use by pin_page_for_write. + */ +#define pmd_hugewillfault(pmd) (0) +#define pmd_thp_or_huge(pmd) (0) + #endif /* __ASSEMBLY__ */ #endif /* _ASM_PGTABLE_2LEVEL_H */ diff --git a/arch/arm/include/asm/pgtable-3level.h b/arch/arm/include/asm/pgtable-3level.h index 5689c18c85f5..4f9503908dca 100644 --- a/arch/arm/include/asm/pgtable-3level.h +++ b/arch/arm/include/asm/pgtable-3level.h @@ -126,6 +126,8 @@ #define L_PTE_S2_RDONLY (_AT(pteval_t, 1) << 6) /* HAP[1] */ #define L_PTE_S2_RDWR (_AT(pteval_t, 3) << 6) /* HAP[2:1] */ +#define L_PMD_S2_RDWR (_AT(pmdval_t, 3) << 6) /* HAP[2:1] */ + /* * Hyp-mode PL2 PTE definitions for LPAE. */ @@ -206,6 +208,9 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr) #define __HAVE_ARCH_PMD_WRITE #define pmd_write(pmd) (!(pmd_val(pmd) & PMD_SECT_RDONLY)) +#define pmd_hugewillfault(pmd) (!pmd_young(pmd) || !pmd_write(pmd)) +#define pmd_thp_or_huge(pmd) (pmd_huge(pmd) || pmd_trans_huge(pmd)) + #ifdef CONFIG_TRANSPARENT_HUGEPAGE #define pmd_trans_huge(pmd) (pmd_val(pmd) && !(pmd_val(pmd) & PMD_TABLE_BIT)) #define pmd_trans_splitting(pmd) (pmd_val(pmd) & PMD_SECT_SPLITTING) diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h index 413f3876341c..c3d5fc124a05 100644 --- a/arch/arm/include/asm/processor.h +++ b/arch/arm/include/asm/processor.h @@ -22,6 +22,7 @@ #include <asm/hw_breakpoint.h> #include <asm/ptrace.h> #include <asm/types.h> +#include <asm/unified.h> #ifdef __KERNEL__ #define STACK_TOP ((current->personality & ADDR_LIMIT_32BIT) ? \ @@ -87,6 +88,17 @@ unsigned long get_wchan(struct task_struct *p); #define KSTK_EIP(tsk) task_pt_regs(tsk)->ARM_pc #define KSTK_ESP(tsk) task_pt_regs(tsk)->ARM_sp +#ifdef CONFIG_SMP +#define __ALT_SMP_ASM(smp, up) \ + "9998: " smp "\n" \ + " .pushsection \".alt.smp.init\", \"a\"\n" \ + " .long 9998b\n" \ + " " up "\n" \ + " .popsection\n" +#else +#define __ALT_SMP_ASM(smp, up) up +#endif + /* * Prefetching support - only ARMv5. */ @@ -97,17 +109,22 @@ static inline void prefetch(const void *ptr) { __asm__ __volatile__( "pld\t%a0" - : - : "p" (ptr) - : "cc"); + :: "p" (ptr)); } +#if __LINUX_ARM_ARCH__ >= 7 && defined(CONFIG_SMP) #define ARCH_HAS_PREFETCHW -#define prefetchw(ptr) prefetch(ptr) - -#define ARCH_HAS_SPINLOCK_PREFETCH -#define spin_lock_prefetch(x) do { } while (0) - +static inline void prefetchw(const void *ptr) +{ + __asm__ __volatile__( + ".arch_extension mp\n" + __ALT_SMP_ASM( + WASM(pldw) "\t%a0", + WASM(pld) "\t%a0" + ) + :: "p" (ptr)); +} +#endif #endif #define HAVE_ARCH_PICK_MMAP_LAYOUT diff --git a/arch/arm/include/asm/prom.h b/arch/arm/include/asm/prom.h index 4a2985e21969..b681575ad3de 100644 --- a/arch/arm/include/asm/prom.h +++ b/arch/arm/include/asm/prom.h @@ -11,8 +11,6 @@ #ifndef __ASMARM_PROM_H #define __ASMARM_PROM_H -#define HAVE_ARCH_DEVTREE_FIXUPS - #ifdef CONFIG_OF extern const struct machine_desc *setup_machine_fdt(unsigned int dt_phys); diff --git a/arch/arm/include/asm/sched_clock.h b/arch/arm/include/asm/sched_clock.h deleted file mode 100644 index 2389b71a8e7c..000000000000 --- a/arch/arm/include/asm/sched_clock.h +++ /dev/null @@ -1,4 +0,0 @@ -/* You shouldn't include this file. Use linux/sched_clock.h instead. - * Temporary file until all asm/sched_clock.h users are gone - */ -#include <linux/sched_clock.h> diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h index c50f05609501..8d6a089dfb76 100644 --- a/arch/arm/include/asm/setup.h +++ b/arch/arm/include/asm/setup.h @@ -49,7 +49,7 @@ extern struct meminfo meminfo; #define bank_phys_end(bank) ((bank)->start + (bank)->size) #define bank_phys_size(bank) (bank)->size -extern int arm_add_memory(phys_addr_t start, phys_addr_t size); +extern int arm_add_memory(u64 start, u64 size); extern void early_print(const char *str, ...); extern void dump_machine_table(void); diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h index a8cae71caceb..22a3b9b5d4a1 100644 --- a/arch/arm/include/asm/smp.h +++ b/arch/arm/include/asm/smp.h @@ -84,6 +84,8 @@ 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); +extern int register_ipi_completion(struct completion *completion, int cpu); + struct smp_operations { #ifdef CONFIG_SMP /* diff --git a/arch/arm/include/asm/spinlock.h b/arch/arm/include/asm/spinlock.h index 4f2c28060c9a..ef3c6072aa45 100644 --- a/arch/arm/include/asm/spinlock.h +++ b/arch/arm/include/asm/spinlock.h @@ -5,21 +5,13 @@ #error SMP not supported on pre-ARMv6 CPUs #endif -#include <asm/processor.h> +#include <linux/prefetch.h> /* * sev and wfe are ARMv6K extensions. Uniprocessor ARMv6 may not have the K * extensions, so when running on UP, we have to patch these instructions away. */ -#define ALT_SMP(smp, up) \ - "9998: " smp "\n" \ - " .pushsection \".alt.smp.init\", \"a\"\n" \ - " .long 9998b\n" \ - " " up "\n" \ - " .popsection\n" - #ifdef CONFIG_THUMB2_KERNEL -#define SEV ALT_SMP("sev.w", "nop.w") /* * For Thumb-2, special care is needed to ensure that the conditional WFE * instruction really does assemble to exactly 4 bytes (as required by @@ -31,17 +23,18 @@ * the assembler won't change IT instructions which are explicitly present * in the input. */ -#define WFE(cond) ALT_SMP( \ +#define WFE(cond) __ALT_SMP_ASM( \ "it " cond "\n\t" \ "wfe" cond ".n", \ \ "nop.w" \ ) #else -#define SEV ALT_SMP("sev", "nop") -#define WFE(cond) ALT_SMP("wfe" cond, "nop") +#define WFE(cond) __ALT_SMP_ASM("wfe" cond, "nop") #endif +#define SEV __ALT_SMP_ASM(WASM(sev), WASM(nop)) + static inline void dsb_sev(void) { #if __LINUX_ARM_ARCH__ >= 7 @@ -77,6 +70,7 @@ static inline void arch_spin_lock(arch_spinlock_t *lock) u32 newval; arch_spinlock_t lockval; + prefetchw(&lock->slock); __asm__ __volatile__( "1: ldrex %0, [%3]\n" " add %1, %0, %4\n" @@ -100,6 +94,7 @@ static inline int arch_spin_trylock(arch_spinlock_t *lock) unsigned long contended, res; u32 slock; + prefetchw(&lock->slock); do { __asm__ __volatile__( " ldrex %0, [%3]\n" @@ -127,10 +122,14 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock) dsb_sev(); } +static inline int arch_spin_value_unlocked(arch_spinlock_t lock) +{ + return lock.tickets.owner == lock.tickets.next; +} + static inline int arch_spin_is_locked(arch_spinlock_t *lock) { - struct __raw_tickets tickets = ACCESS_ONCE(lock->tickets); - return tickets.owner != tickets.next; + return !arch_spin_value_unlocked(ACCESS_ONCE(*lock)); } static inline int arch_spin_is_contended(arch_spinlock_t *lock) @@ -152,6 +151,7 @@ static inline void arch_write_lock(arch_rwlock_t *rw) { unsigned long tmp; + prefetchw(&rw->lock); __asm__ __volatile__( "1: ldrex %0, [%1]\n" " teq %0, #0\n" @@ -170,6 +170,7 @@ static inline int arch_write_trylock(arch_rwlock_t *rw) { unsigned long contended, res; + prefetchw(&rw->lock); do { __asm__ __volatile__( " ldrex %0, [%2]\n" @@ -203,7 +204,7 @@ static inline void arch_write_unlock(arch_rwlock_t *rw) } /* write_can_lock - would write_trylock() succeed? */ -#define arch_write_can_lock(x) ((x)->lock == 0) +#define arch_write_can_lock(x) (ACCESS_ONCE((x)->lock) == 0) /* * Read locks are a bit more hairy: @@ -221,6 +222,7 @@ static inline void arch_read_lock(arch_rwlock_t *rw) { unsigned long tmp, tmp2; + prefetchw(&rw->lock); __asm__ __volatile__( "1: ldrex %0, [%2]\n" " adds %0, %0, #1\n" @@ -241,6 +243,7 @@ static inline void arch_read_unlock(arch_rwlock_t *rw) smp_mb(); + prefetchw(&rw->lock); __asm__ __volatile__( "1: ldrex %0, [%2]\n" " sub %0, %0, #1\n" @@ -259,6 +262,7 @@ static inline int arch_read_trylock(arch_rwlock_t *rw) { unsigned long contended, res; + prefetchw(&rw->lock); do { __asm__ __volatile__( " ldrex %0, [%2]\n" @@ -280,7 +284,7 @@ static inline int arch_read_trylock(arch_rwlock_t *rw) } /* read_can_lock - would read_trylock() succeed? */ -#define arch_read_can_lock(x) ((x)->lock < 0x80000000) +#define arch_read_can_lock(x) (ACCESS_ONCE((x)->lock) < 0x80000000) #define arch_read_lock_flags(lock, flags) arch_read_lock(lock) #define arch_write_lock_flags(lock, flags) arch_write_lock(lock) diff --git a/arch/arm/include/asm/spinlock_types.h b/arch/arm/include/asm/spinlock_types.h index b262d2f8b478..47663fcb10ad 100644 --- a/arch/arm/include/asm/spinlock_types.h +++ b/arch/arm/include/asm/spinlock_types.h @@ -25,7 +25,7 @@ typedef struct { #define __ARCH_SPIN_LOCK_UNLOCKED { { 0 } } typedef struct { - volatile unsigned int lock; + u32 lock; } arch_rwlock_t; #define __ARCH_RW_LOCK_UNLOCKED { 0 } diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h index df5e13d64f2c..71a06b293489 100644 --- a/arch/arm/include/asm/thread_info.h +++ b/arch/arm/include/asm/thread_info.h @@ -141,12 +141,6 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *, #endif /* - * We use bit 30 of the preempt_count to indicate that kernel - * preemption is occurring. See <asm/hardirq.h>. - */ -#define PREEMPT_ACTIVE 0x40000000 - -/* * thread information flags: * TIF_SYSCALL_TRACE - syscall trace active * TIF_SYSCAL_AUDIT - syscall auditing active diff --git a/arch/arm/include/asm/tlbflush.h b/arch/arm/include/asm/tlbflush.h index 38960264040c..def9e570199f 100644 --- a/arch/arm/include/asm/tlbflush.h +++ b/arch/arm/include/asm/tlbflush.h @@ -560,37 +560,6 @@ static inline void __flush_bp_all(void) asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero)); } -#include <asm/cputype.h> -#ifdef CONFIG_ARM_ERRATA_798181 -static inline int erratum_a15_798181(void) -{ - unsigned int midr = read_cpuid_id(); - - /* Cortex-A15 r0p0..r3p2 affected */ - if ((midr & 0xff0ffff0) != 0x410fc0f0 || midr > 0x413fc0f2) - return 0; - return 1; -} - -static inline void dummy_flush_tlb_a15_erratum(void) -{ - /* - * Dummy TLBIMVAIS. Using the unmapped address 0 and ASID 0. - */ - asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (0)); - dsb(ish); -} -#else -static inline int erratum_a15_798181(void) -{ - return 0; -} - -static inline void dummy_flush_tlb_a15_erratum(void) -{ -} -#endif - /* * flush_pmd_entry * @@ -697,4 +666,21 @@ extern void flush_bp_all(void); #endif +#ifndef __ASSEMBLY__ +#ifdef CONFIG_ARM_ERRATA_798181 +extern void erratum_a15_798181_init(void); +#else +static inline void erratum_a15_798181_init(void) {} +#endif +extern bool (*erratum_a15_798181_handler)(void); + +static inline bool erratum_a15_798181(void) +{ + if (unlikely(IS_ENABLED(CONFIG_ARM_ERRATA_798181) && + erratum_a15_798181_handler)) + return erratum_a15_798181_handler(); + return false; +} +#endif + #endif diff --git a/arch/arm/include/asm/unified.h b/arch/arm/include/asm/unified.h index f5989f46b4d2..b88beaba6b4a 100644 --- a/arch/arm/include/asm/unified.h +++ b/arch/arm/include/asm/unified.h @@ -38,6 +38,8 @@ #ifdef __ASSEMBLY__ #define W(instr) instr.w #define BSYM(sym) sym + 1 +#else +#define WASM(instr) #instr ".w" #endif #else /* !CONFIG_THUMB2_KERNEL */ @@ -50,6 +52,8 @@ #ifdef __ASSEMBLY__ #define W(instr) instr #define BSYM(sym) sym +#else +#define WASM(instr) #instr #endif #endif /* CONFIG_THUMB2_KERNEL */ diff --git a/arch/arm/include/asm/xen/hypervisor.h b/arch/arm/include/asm/xen/hypervisor.h index d7ab99a0c9eb..1317ee40f4df 100644 --- a/arch/arm/include/asm/xen/hypervisor.h +++ b/arch/arm/include/asm/xen/hypervisor.h @@ -16,4 +16,6 @@ static inline enum paravirt_lazy_mode paravirt_get_lazy_mode(void) return PARAVIRT_LAZY_NONE; } +extern struct dma_map_ops *xen_dma_ops; + #endif /* _ASM_ARM_XEN_HYPERVISOR_H */ diff --git a/arch/arm/include/asm/xen/page-coherent.h b/arch/arm/include/asm/xen/page-coherent.h new file mode 100644 index 000000000000..1109017499e5 --- /dev/null +++ b/arch/arm/include/asm/xen/page-coherent.h @@ -0,0 +1,50 @@ +#ifndef _ASM_ARM_XEN_PAGE_COHERENT_H +#define _ASM_ARM_XEN_PAGE_COHERENT_H + +#include <asm/page.h> +#include <linux/dma-attrs.h> +#include <linux/dma-mapping.h> + +static inline void *xen_alloc_coherent_pages(struct device *hwdev, size_t size, + dma_addr_t *dma_handle, gfp_t flags, + struct dma_attrs *attrs) +{ + return __generic_dma_ops(hwdev)->alloc(hwdev, size, dma_handle, flags, attrs); +} + +static inline void xen_free_coherent_pages(struct device *hwdev, size_t size, + void *cpu_addr, dma_addr_t dma_handle, + struct dma_attrs *attrs) +{ + __generic_dma_ops(hwdev)->free(hwdev, size, cpu_addr, dma_handle, attrs); +} + +static inline void xen_dma_map_page(struct device *hwdev, struct page *page, + unsigned long offset, size_t size, enum dma_data_direction dir, + struct dma_attrs *attrs) +{ + __generic_dma_ops(hwdev)->map_page(hwdev, page, offset, size, dir, attrs); +} + +static inline void xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle, + size_t size, enum dma_data_direction dir, + struct dma_attrs *attrs) +{ + if (__generic_dma_ops(hwdev)->unmap_page) + __generic_dma_ops(hwdev)->unmap_page(hwdev, handle, size, dir, attrs); +} + +static inline void xen_dma_sync_single_for_cpu(struct device *hwdev, + dma_addr_t handle, size_t size, enum dma_data_direction dir) +{ + if (__generic_dma_ops(hwdev)->sync_single_for_cpu) + __generic_dma_ops(hwdev)->sync_single_for_cpu(hwdev, handle, size, dir); +} + +static inline void xen_dma_sync_single_for_device(struct device *hwdev, + dma_addr_t handle, size_t size, enum dma_data_direction dir) +{ + if (__generic_dma_ops(hwdev)->sync_single_for_device) + __generic_dma_ops(hwdev)->sync_single_for_device(hwdev, handle, size, dir); +} +#endif /* _ASM_ARM_XEN_PAGE_COHERENT_H */ diff --git a/arch/arm/include/asm/xen/page.h b/arch/arm/include/asm/xen/page.h index 359a7b50b158..75579a9d6f76 100644 --- a/arch/arm/include/asm/xen/page.h +++ b/arch/arm/include/asm/xen/page.h @@ -6,12 +6,12 @@ #include <linux/pfn.h> #include <linux/types.h> +#include <linux/dma-mapping.h> +#include <xen/xen.h> #include <xen/interface/grant_table.h> -#define pfn_to_mfn(pfn) (pfn) #define phys_to_machine_mapping_valid(pfn) (1) -#define mfn_to_pfn(mfn) (mfn) #define mfn_to_virt(m) (__va(mfn_to_pfn(m) << PAGE_SHIFT)) #define pte_mfn pte_pfn @@ -32,6 +32,38 @@ typedef struct xpaddr { #define INVALID_P2M_ENTRY (~0UL) +unsigned long __pfn_to_mfn(unsigned long pfn); +unsigned long __mfn_to_pfn(unsigned long mfn); +extern struct rb_root phys_to_mach; + +static inline unsigned long pfn_to_mfn(unsigned long pfn) +{ + unsigned long mfn; + + if (phys_to_mach.rb_node != NULL) { + mfn = __pfn_to_mfn(pfn); + if (mfn != INVALID_P2M_ENTRY) + return mfn; + } + + return pfn; +} + +static inline unsigned long mfn_to_pfn(unsigned long mfn) +{ + unsigned long pfn; + + if (phys_to_mach.rb_node != NULL) { + pfn = __mfn_to_pfn(mfn); + if (pfn != INVALID_P2M_ENTRY) + return pfn; + } + + return mfn; +} + +#define mfn_to_local_pfn(mfn) mfn_to_pfn(mfn) + static inline xmaddr_t phys_to_machine(xpaddr_t phys) { unsigned offset = phys.paddr & ~PAGE_MASK; @@ -76,11 +108,9 @@ static inline int m2p_remove_override(struct page *page, bool clear_pte) return 0; } -static inline bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn) -{ - BUG_ON(pfn != mfn && mfn != INVALID_P2M_ENTRY); - return true; -} +bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn); +bool __set_phys_to_machine_multi(unsigned long pfn, unsigned long mfn, + unsigned long nr_pages); static inline bool set_phys_to_machine(unsigned long pfn, unsigned long mfn) { diff --git a/arch/arm/include/debug/efm32.S b/arch/arm/include/debug/efm32.S new file mode 100644 index 000000000000..2265a199280c --- /dev/null +++ b/arch/arm/include/debug/efm32.S @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2013 Pengutronix + * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> + * + * 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. + */ + +#define UARTn_CMD 0x000c +#define UARTn_CMD_TXEN 0x0004 + +#define UARTn_STATUS 0x0010 +#define UARTn_STATUS_TXC 0x0020 +#define UARTn_STATUS_TXBL 0x0040 + +#define UARTn_TXDATA 0x0034 + + .macro addruart, rx, tmp + ldr \rx, =(CONFIG_DEBUG_UART_PHYS) + + /* + * enable TX. The driver might disable it to save energy. We + * don't care about disabling at the end as during debug power + * consumption isn't that important. + */ + ldr \tmp, =(UARTn_CMD_TXEN) + str \tmp, [\rx, #UARTn_CMD] + .endm + + .macro senduart,rd,rx + strb \rd, [\rx, #UARTn_TXDATA] + .endm + + .macro waituart,rd,rx +1001: ldr \rd, [\rx, #UARTn_STATUS] + tst \rd, #UARTn_STATUS_TXBL + beq 1001b + .endm + + .macro busyuart,rd,rx +1001: ldr \rd, [\rx, UARTn_STATUS] + tst \rd, #UARTn_STATUS_TXC + bne 1001b + .endm diff --git a/arch/arm/include/debug/msm.S b/arch/arm/include/debug/msm.S index 9166e1bc470e..9d653d475903 100644 --- a/arch/arm/include/debug/msm.S +++ b/arch/arm/include/debug/msm.S @@ -46,6 +46,11 @@ #define MSM_DEBUG_UART_PHYS 0x16440000 #endif +#ifdef CONFIG_DEBUG_MSM8974_UART +#define MSM_DEBUG_UART_BASE 0xFA71E000 +#define MSM_DEBUG_UART_PHYS 0xF991E000 +#endif + .macro addruart, rp, rv, tmp #ifdef MSM_DEBUG_UART_PHYS ldr \rp, =MSM_DEBUG_UART_PHYS diff --git a/arch/arm/include/debug/pl01x.S b/arch/arm/include/debug/pl01x.S index 37c6895b87e6..92ef808a2337 100644 --- a/arch/arm/include/debug/pl01x.S +++ b/arch/arm/include/debug/pl01x.S @@ -25,12 +25,14 @@ .macro waituart,rd,rx 1001: ldr \rd, [\rx, #UART01x_FR] + ARM_BE8( rev \rd, \rd ) tst \rd, #UART01x_FR_TXFF bne 1001b .endm .macro busyuart,rd,rx 1001: ldr \rd, [\rx, #UART01x_FR] + ARM_BE8( rev \rd, \rd ) tst \rd, #UART01x_FR_BUSY bne 1001b .endm diff --git a/arch/arm/include/debug/vf.S b/arch/arm/include/debug/vf.S new file mode 100644 index 000000000000..ba12cc44b2cb --- /dev/null +++ b/arch/arm/include/debug/vf.S @@ -0,0 +1,26 @@ +/* + * Copyright 2013 Freescale Semiconductor, Inc. + * + * 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. + * + */ + + .macro addruart, rp, rv, tmp + ldr \rp, =0x40028000 @ physical + ldr \rv, =0xfe028000 @ virtual + .endm + + .macro senduart, rd, rx + strb \rd, [\rx, #0x7] @ Data Register + .endm + + .macro busyuart, rd, rx +1001: ldrb \rd, [\rx, #0x4] @ Status Register 1 + tst \rd, #1 << 6 @ TC + beq 1001b @ wait until transmit done + .endm + + .macro waituart,rd,rx + .endm diff --git a/arch/arm/include/uapi/asm/Kbuild b/arch/arm/include/uapi/asm/Kbuild index 18d76fd5a2af..70a1c9da30ca 100644 --- a/arch/arm/include/uapi/asm/Kbuild +++ b/arch/arm/include/uapi/asm/Kbuild @@ -7,6 +7,7 @@ header-y += hwcap.h header-y += ioctls.h header-y += kvm_para.h header-y += mman.h +header-y += perf_regs.h header-y += posix_types.h header-y += ptrace.h header-y += setup.h diff --git a/arch/arm/include/uapi/asm/hwcap.h b/arch/arm/include/uapi/asm/hwcap.h index 6d34d080372a..7dcc10d67253 100644 --- a/arch/arm/include/uapi/asm/hwcap.h +++ b/arch/arm/include/uapi/asm/hwcap.h @@ -26,5 +26,6 @@ #define HWCAP_VFPD32 (1 << 19) /* set if VFP has 32 regs (not 16) */ #define HWCAP_IDIV (HWCAP_IDIVA | HWCAP_IDIVT) #define HWCAP_LPAE (1 << 20) +#define HWCAP_EVTSTRM (1 << 21) #endif /* _UAPI__ASMARM_HWCAP_H */ diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h index c1ee007523d7..c498b60c0505 100644 --- a/arch/arm/include/uapi/asm/kvm.h +++ b/arch/arm/include/uapi/asm/kvm.h @@ -63,7 +63,8 @@ struct kvm_regs { /* Supported Processor Types */ #define KVM_ARM_TARGET_CORTEX_A15 0 -#define KVM_ARM_NUM_TARGETS 1 +#define KVM_ARM_TARGET_CORTEX_A7 1 +#define KVM_ARM_NUM_TARGETS 2 /* KVM_ARM_SET_DEVICE_ADDR ioctl id encoding */ #define KVM_ARM_DEVICE_TYPE_SHIFT 0 diff --git a/arch/arm/include/uapi/asm/perf_regs.h b/arch/arm/include/uapi/asm/perf_regs.h new file mode 100644 index 000000000000..ce59448458b2 --- /dev/null +++ b/arch/arm/include/uapi/asm/perf_regs.h @@ -0,0 +1,23 @@ +#ifndef _ASM_ARM_PERF_REGS_H +#define _ASM_ARM_PERF_REGS_H + +enum perf_event_arm_regs { + PERF_REG_ARM_R0, + PERF_REG_ARM_R1, + PERF_REG_ARM_R2, + PERF_REG_ARM_R3, + PERF_REG_ARM_R4, + PERF_REG_ARM_R5, + PERF_REG_ARM_R6, + PERF_REG_ARM_R7, + PERF_REG_ARM_R8, + PERF_REG_ARM_R9, + PERF_REG_ARM_R10, + PERF_REG_ARM_FP, + PERF_REG_ARM_IP, + PERF_REG_ARM_SP, + PERF_REG_ARM_LR, + PERF_REG_ARM_PC, + PERF_REG_ARM_MAX, +}; +#endif /* _ASM_ARM_PERF_REGS_H */ diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 5140df5f23aa..a30fc9be9e9e 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -17,7 +17,8 @@ CFLAGS_REMOVE_return_address.o = -pg obj-y := elf.o entry-common.o irq.o opcodes.o \ process.o ptrace.o return_address.o \ - setup.o signal.o stacktrace.o sys_arm.o time.o traps.o + setup.o signal.o sigreturn_codes.o \ + stacktrace.o sys_arm.o time.o traps.o obj-$(CONFIG_ATAGS) += atags_parse.o obj-$(CONFIG_ATAGS_PROC) += atags_proc.o @@ -78,6 +79,7 @@ obj-$(CONFIG_CPU_XSC3) += xscale-cp0.o obj-$(CONFIG_CPU_MOHAWK) += xscale-cp0.o obj-$(CONFIG_CPU_PJ4) += pj4-cp0.o obj-$(CONFIG_IWMMXT) += iwmmxt.o +obj-$(CONFIG_PERF_EVENTS) += perf_regs.o obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o perf_event_cpu.o AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt obj-$(CONFIG_ARM_CPU_TOPOLOGY) += topology.o diff --git a/arch/arm/kernel/arch_timer.c b/arch/arm/kernel/arch_timer.c index 221f07b11ccb..1791f12c180b 100644 --- a/arch/arm/kernel/arch_timer.c +++ b/arch/arm/kernel/arch_timer.c @@ -11,7 +11,6 @@ #include <linux/init.h> #include <linux/types.h> #include <linux/errno.h> -#include <linux/sched_clock.h> #include <asm/delay.h> @@ -22,13 +21,6 @@ static unsigned long arch_timer_read_counter_long(void) return arch_timer_read_counter(); } -static u32 sched_clock_mult __read_mostly; - -static unsigned long long notrace arch_timer_sched_clock(void) -{ - return arch_timer_read_counter() * sched_clock_mult; -} - static struct delay_timer arch_delay_timer; static void __init arch_timer_delay_timer_register(void) @@ -48,11 +40,5 @@ int __init arch_timer_arch_init(void) arch_timer_delay_timer_register(); - /* Cache the sched_clock multiplier to save a divide in the hot path. */ - sched_clock_mult = NSEC_PER_SEC / arch_timer_rate; - sched_clock_func = arch_timer_sched_clock; - pr_info("sched_clock: ARM arch timer >56 bits at %ukHz, resolution %uns\n", - arch_timer_rate / 1000, sched_clock_mult); - return 0; } diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c index 60d3b738d420..1f031ddd0667 100644 --- a/arch/arm/kernel/armksyms.c +++ b/arch/arm/kernel/armksyms.c @@ -155,4 +155,5 @@ EXPORT_SYMBOL(__gnu_mcount_nc); #ifdef CONFIG_ARM_PATCH_PHYS_VIRT EXPORT_SYMBOL(__pv_phys_offset); +EXPORT_SYMBOL(__pv_offset); #endif diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c index f35906b3d8c9..739c3dfc1da2 100644 --- a/arch/arm/kernel/devtree.c +++ b/arch/arm/kernel/devtree.c @@ -174,6 +174,19 @@ bool arch_match_cpu_phys_id(int cpu, u64 phys_id) return (phys_id & MPIDR_HWID_BITMASK) == cpu_logical_map(cpu); } +static const void * __init arch_get_next_mach(const char *const **match) +{ + static const struct machine_desc *mdesc = __arch_info_begin; + const struct machine_desc *m = mdesc; + + if (m >= __arch_info_end) + return NULL; + + mdesc++; + *match = m->dt_compat; + return m; +} + /** * setup_machine_fdt - Machine setup when an dtb was passed to the kernel * @dt_phys: physical address of dt blob @@ -183,11 +196,7 @@ bool arch_match_cpu_phys_id(int cpu, u64 phys_id) */ const struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys) { - struct boot_param_header *devtree; const struct machine_desc *mdesc, *mdesc_best = NULL; - unsigned int score, mdesc_score = ~1; - unsigned long dt_root; - const char *model; #ifdef CONFIG_ARCH_MULTIPLATFORM DT_MACHINE_START(GENERIC_DT, "Generic DT based system") @@ -196,32 +205,20 @@ const struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys) mdesc_best = &__mach_desc_GENERIC_DT; #endif - if (!dt_phys) + if (!dt_phys || !early_init_dt_scan(phys_to_virt(dt_phys))) return NULL; - devtree = phys_to_virt(dt_phys); + mdesc = of_flat_dt_match_machine(mdesc_best, arch_get_next_mach); - /* check device tree validity */ - if (be32_to_cpu(devtree->magic) != OF_DT_HEADER) - return NULL; - - /* Search the mdescs for the 'best' compatible value match */ - initial_boot_params = devtree; - dt_root = of_get_flat_dt_root(); - for_each_machine_desc(mdesc) { - score = of_flat_dt_match(dt_root, mdesc->dt_compat); - if (score > 0 && score < mdesc_score) { - mdesc_best = mdesc; - mdesc_score = score; - } - } - if (!mdesc_best) { + if (!mdesc) { const char *prop; long size; + unsigned long dt_root; early_print("\nError: unrecognized/unsupported " "device tree compatible list:\n[ "); + dt_root = of_get_flat_dt_root(); prop = of_get_flat_dt_prop(dt_root, "compatible", &size); while (size > 0) { early_print("'%s' ", prop); @@ -233,22 +230,8 @@ const struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys) dump_machine_table(); /* does not return */ } - model = of_get_flat_dt_prop(dt_root, "model", NULL); - if (!model) - model = of_get_flat_dt_prop(dt_root, "compatible", NULL); - if (!model) - model = "<unknown>"; - pr_info("Machine: %s, model: %s\n", mdesc_best->name, model); - - /* Retrieve various information from the /chosen node */ - of_scan_flat_dt(early_init_dt_scan_chosen, boot_command_line); - /* Initialize {size,address}-cells info */ - of_scan_flat_dt(early_init_dt_scan_root, NULL); - /* Setup memory, calling early_init_dt_add_memory_arch */ - of_scan_flat_dt(early_init_dt_scan_memory, NULL); - /* Change machine number to match the mdesc we're using */ - __machine_arch_type = mdesc_best->nr; + __machine_arch_type = mdesc->nr; - return mdesc_best; + return mdesc; } diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 9cbe70c8b0ef..b3fb8c9e1ff2 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -192,6 +192,7 @@ __dabt_svc: svc_entry mov r2, sp dabt_helper + THUMB( ldr r5, [sp, #S_PSR] ) @ potentially updated CPSR svc_exit r5 @ return from exception UNWIND(.fnend ) ENDPROC(__dabt_svc) @@ -416,9 +417,8 @@ __und_usr: bne __und_usr_thumb sub r4, r2, #4 @ ARM instr at LR - 4 1: ldrt r0, [r4] -#ifdef CONFIG_CPU_ENDIAN_BE8 - rev r0, r0 @ little endian instruction -#endif + ARM_BE8(rev r0, r0) @ little endian instruction + @ r0 = 32-bit ARM instruction which caused the exception @ r2 = PC value for the following instruction (:= regs->ARM_pc) @ r4 = PC value for the faulting instruction diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index bc6bd9683ba4..a2dcafdf1bc8 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S @@ -393,9 +393,7 @@ ENTRY(vector_swi) #else USER( ldr r10, [lr, #-4] ) @ get SWI instruction #endif -#ifdef CONFIG_CPU_ENDIAN_BE8 - rev r10, r10 @ little endian instruction -#endif + ARM_BE8(rev r10, r10) @ little endian instruction #elif defined(CONFIG_AEABI) diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index 476de57dcef2..7801866e626a 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S @@ -77,6 +77,7 @@ __HEAD ENTRY(stext) + ARM_BE8(setend be ) @ ensure we are in BE8 mode THUMB( adr r9, BSYM(1f) ) @ Kernel is always entered in ARM. THUMB( bx r9 ) @ If this is a Thumb-2 kernel, @@ -352,6 +353,9 @@ ENTRY(secondary_startup) * the processor type - there is no need to check the machine type * as it has already been validated by the primary processor. */ + + ARM_BE8(setend be) @ ensure we are in BE8 mode + #ifdef CONFIG_ARM_VIRT_EXT bl __hyp_stub_install_secondary #endif @@ -555,6 +559,14 @@ ENTRY(fixup_smp) ldmfd sp!, {r4 - r6, pc} ENDPROC(fixup_smp) +#ifdef __ARMEB__ +#define LOW_OFFSET 0x4 +#define HIGH_OFFSET 0x0 +#else +#define LOW_OFFSET 0x0 +#define HIGH_OFFSET 0x4 +#endif + #ifdef CONFIG_ARM_PATCH_PHYS_VIRT /* __fixup_pv_table - patch the stub instructions with the delta between @@ -565,17 +577,20 @@ ENDPROC(fixup_smp) __HEAD __fixup_pv_table: adr r0, 1f - ldmia r0, {r3-r5, r7} - sub r3, r0, r3 @ PHYS_OFFSET - PAGE_OFFSET + ldmia r0, {r3-r7} + mvn ip, #0 + subs r3, r0, r3 @ PHYS_OFFSET - PAGE_OFFSET add r4, r4, r3 @ adjust table start address add r5, r5, r3 @ adjust table end address - add r7, r7, r3 @ adjust __pv_phys_offset address - str r8, [r7] @ save computed PHYS_OFFSET to __pv_phys_offset + add r6, r6, r3 @ adjust __pv_phys_offset address + add r7, r7, r3 @ adjust __pv_offset address + str r8, [r6, #LOW_OFFSET] @ save computed PHYS_OFFSET to __pv_phys_offset + strcc ip, [r7, #HIGH_OFFSET] @ save to __pv_offset high bits mov r6, r3, lsr #24 @ constant for add/sub instructions teq r3, r6, lsl #24 @ must be 16MiB aligned THUMB( it ne @ cross section branch ) bne __error - str r6, [r7, #4] @ save to __pv_offset + str r3, [r7, #LOW_OFFSET] @ save to __pv_offset low bits b __fixup_a_pv_table ENDPROC(__fixup_pv_table) @@ -584,10 +599,19 @@ ENDPROC(__fixup_pv_table) .long __pv_table_begin .long __pv_table_end 2: .long __pv_phys_offset + .long __pv_offset .text __fixup_a_pv_table: + adr r0, 3f + ldr r6, [r0] + add r6, r6, r3 + ldr r0, [r6, #HIGH_OFFSET] @ pv_offset high word + ldr r6, [r6, #LOW_OFFSET] @ pv_offset low word + mov r6, r6, lsr #24 + cmn r0, #1 #ifdef CONFIG_THUMB2_KERNEL + moveq r0, #0x200000 @ set bit 21, mov to mvn instruction lsls r6, #24 beq 2f clz r7, r6 @@ -601,18 +625,42 @@ __fixup_a_pv_table: b 2f 1: add r7, r3 ldrh ip, [r7, #2] - and ip, 0x8f00 - orr ip, r6 @ mask in offset bits 31-24 +ARM_BE8(rev16 ip, ip) + tst ip, #0x4000 + and ip, #0x8f00 + orrne ip, r6 @ mask in offset bits 31-24 + orreq ip, r0 @ mask in offset bits 7-0 +ARM_BE8(rev16 ip, ip) strh ip, [r7, #2] + bne 2f + ldrh ip, [r7] +ARM_BE8(rev16 ip, ip) + bic ip, #0x20 + orr ip, ip, r0, lsr #16 +ARM_BE8(rev16 ip, ip) + strh ip, [r7] 2: cmp r4, r5 ldrcc r7, [r4], #4 @ use branch for delay slot bcc 1b bx lr #else + moveq r0, #0x400000 @ set bit 22, mov to mvn instruction b 2f 1: ldr ip, [r7, r3] +#ifdef CONFIG_CPU_ENDIAN_BE8 + @ in BE8, we load data in BE, but instructions still in LE + bic ip, ip, #0xff000000 + tst ip, #0x000f0000 @ check the rotation field + orrne ip, ip, r6, lsl #24 @ mask in offset bits 31-24 + biceq ip, ip, #0x00004000 @ clear bit 22 + orreq ip, ip, r0, lsl #24 @ mask in offset bits 7-0 +#else bic ip, ip, #0x000000ff - orr ip, ip, r6 @ mask in offset bits 31-24 + tst ip, #0xf00 @ check the rotation field + orrne ip, ip, r6 @ mask in offset bits 31-24 + biceq ip, ip, #0x400000 @ clear bit 22 + orreq ip, ip, r0 @ mask in offset bits 7-0 +#endif str ip, [r7, r3] 2: cmp r4, r5 ldrcc r7, [r4], #4 @ use branch for delay slot @@ -621,28 +669,30 @@ __fixup_a_pv_table: #endif ENDPROC(__fixup_a_pv_table) + .align +3: .long __pv_offset + ENTRY(fixup_pv_table) stmfd sp!, {r4 - r7, lr} - ldr r2, 2f @ get address of __pv_phys_offset mov r3, #0 @ no offset mov r4, r0 @ r0 = table start add r5, r0, r1 @ r1 = table size - ldr r6, [r2, #4] @ get __pv_offset bl __fixup_a_pv_table ldmfd sp!, {r4 - r7, pc} ENDPROC(fixup_pv_table) - .align -2: .long __pv_phys_offset - .data .globl __pv_phys_offset .type __pv_phys_offset, %object __pv_phys_offset: - .long 0 - .size __pv_phys_offset, . - __pv_phys_offset + .quad 0 + .size __pv_phys_offset, . -__pv_phys_offset + + .globl __pv_offset + .type __pv_offset, %object __pv_offset: - .long 0 + .quad 0 + .size __pv_offset, . -__pv_offset #endif #include "head-common.S" diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index 7b95de601357..3d446605cbf8 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c @@ -344,13 +344,13 @@ int arch_install_hw_breakpoint(struct perf_event *bp) /* Breakpoint */ ctrl_base = ARM_BASE_BCR; val_base = ARM_BASE_BVR; - slots = (struct perf_event **)__get_cpu_var(bp_on_reg); + slots = this_cpu_ptr(bp_on_reg); max_slots = core_num_brps; } else { /* Watchpoint */ ctrl_base = ARM_BASE_WCR; val_base = ARM_BASE_WVR; - slots = (struct perf_event **)__get_cpu_var(wp_on_reg); + slots = this_cpu_ptr(wp_on_reg); max_slots = core_num_wrps; } @@ -396,12 +396,12 @@ void arch_uninstall_hw_breakpoint(struct perf_event *bp) if (info->ctrl.type == ARM_BREAKPOINT_EXECUTE) { /* Breakpoint */ base = ARM_BASE_BCR; - slots = (struct perf_event **)__get_cpu_var(bp_on_reg); + slots = this_cpu_ptr(bp_on_reg); max_slots = core_num_brps; } else { /* Watchpoint */ base = ARM_BASE_WCR; - slots = (struct perf_event **)__get_cpu_var(wp_on_reg); + slots = this_cpu_ptr(wp_on_reg); max_slots = core_num_wrps; } @@ -697,7 +697,7 @@ static void watchpoint_handler(unsigned long addr, unsigned int fsr, struct arch_hw_breakpoint *info; struct arch_hw_breakpoint_ctrl ctrl; - slots = (struct perf_event **)__get_cpu_var(wp_on_reg); + slots = this_cpu_ptr(wp_on_reg); for (i = 0; i < core_num_wrps; ++i) { rcu_read_lock(); @@ -768,7 +768,7 @@ static void watchpoint_single_step_handler(unsigned long pc) struct perf_event *wp, **slots; struct arch_hw_breakpoint *info; - slots = (struct perf_event **)__get_cpu_var(wp_on_reg); + slots = this_cpu_ptr(wp_on_reg); for (i = 0; i < core_num_wrps; ++i) { rcu_read_lock(); @@ -802,7 +802,7 @@ static void breakpoint_handler(unsigned long unknown, struct pt_regs *regs) struct arch_hw_breakpoint *info; struct arch_hw_breakpoint_ctrl ctrl; - slots = (struct perf_event **)__get_cpu_var(bp_on_reg); + slots = this_cpu_ptr(bp_on_reg); /* The exception entry code places the amended lr in the PC. */ addr = regs->ARM_pc; diff --git a/arch/arm/kernel/kprobes.c b/arch/arm/kernel/kprobes.c index 170e9f34003f..a7b621ece23d 100644 --- a/arch/arm/kernel/kprobes.c +++ b/arch/arm/kernel/kprobes.c @@ -171,13 +171,13 @@ static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb) static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb) { - __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp; + __this_cpu_write(current_kprobe, kcb->prev_kprobe.kp); kcb->kprobe_status = kcb->prev_kprobe.status; } static void __kprobes set_current_kprobe(struct kprobe *p) { - __get_cpu_var(current_kprobe) = p; + __this_cpu_write(current_kprobe, p); } static void __kprobes @@ -421,10 +421,10 @@ static __used __kprobes void *trampoline_handler(struct pt_regs *regs) continue; if (ri->rp && ri->rp->handler) { - __get_cpu_var(current_kprobe) = &ri->rp->kp; + __this_cpu_write(current_kprobe, &ri->rp->kp); get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE; ri->rp->handler(ri, regs); - __get_cpu_var(current_kprobe) = NULL; + __this_cpu_write(current_kprobe, NULL); } orig_ret_address = (unsigned long)ri->ret_addr; diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c index 084dc8896986..45e478157278 100644 --- a/arch/arm/kernel/module.c +++ b/arch/arm/kernel/module.c @@ -24,6 +24,7 @@ #include <asm/sections.h> #include <asm/smp_plat.h> #include <asm/unwind.h> +#include <asm/opcodes.h> #ifdef CONFIG_XIP_KERNEL /* @@ -40,7 +41,7 @@ void *module_alloc(unsigned long size) { return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END, - GFP_KERNEL, PAGE_KERNEL_EXEC, -1, + GFP_KERNEL, PAGE_KERNEL_EXEC, NUMA_NO_NODE, __builtin_return_address(0)); } #endif @@ -60,6 +61,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, Elf32_Sym *sym; const char *symname; s32 offset; + u32 tmp; #ifdef CONFIG_THUMB2_KERNEL u32 upper, lower, sign, j1, j2; #endif @@ -95,7 +97,8 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, case R_ARM_PC24: case R_ARM_CALL: case R_ARM_JUMP24: - offset = (*(u32 *)loc & 0x00ffffff) << 2; + offset = __mem_to_opcode_arm(*(u32 *)loc); + offset = (offset & 0x00ffffff) << 2; if (offset & 0x02000000) offset -= 0x04000000; @@ -111,9 +114,10 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, } offset >>= 2; + offset &= 0x00ffffff; - *(u32 *)loc &= 0xff000000; - *(u32 *)loc |= offset & 0x00ffffff; + *(u32 *)loc &= __opcode_to_mem_arm(0xff000000); + *(u32 *)loc |= __opcode_to_mem_arm(offset); break; case R_ARM_V4BX: @@ -121,8 +125,8 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, * other bits to re-code instruction as * MOV PC,Rm. */ - *(u32 *)loc &= 0xf000000f; - *(u32 *)loc |= 0x01a0f000; + *(u32 *)loc &= __opcode_to_mem_arm(0xf000000f); + *(u32 *)loc |= __opcode_to_mem_arm(0x01a0f000); break; case R_ARM_PREL31: @@ -132,7 +136,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, case R_ARM_MOVW_ABS_NC: case R_ARM_MOVT_ABS: - offset = *(u32 *)loc; + offset = tmp = __mem_to_opcode_arm(*(u32 *)loc); offset = ((offset & 0xf0000) >> 4) | (offset & 0xfff); offset = (offset ^ 0x8000) - 0x8000; @@ -140,16 +144,18 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, if (ELF32_R_TYPE(rel->r_info) == R_ARM_MOVT_ABS) offset >>= 16; - *(u32 *)loc &= 0xfff0f000; - *(u32 *)loc |= ((offset & 0xf000) << 4) | - (offset & 0x0fff); + tmp &= 0xfff0f000; + tmp |= ((offset & 0xf000) << 4) | + (offset & 0x0fff); + + *(u32 *)loc = __opcode_to_mem_arm(tmp); break; #ifdef CONFIG_THUMB2_KERNEL case R_ARM_THM_CALL: case R_ARM_THM_JUMP24: - upper = *(u16 *)loc; - lower = *(u16 *)(loc + 2); + upper = __mem_to_opcode_thumb16(*(u16 *)loc); + lower = __mem_to_opcode_thumb16(*(u16 *)(loc + 2)); /* * 25 bit signed address range (Thumb-2 BL and B.W @@ -198,17 +204,20 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, sign = (offset >> 24) & 1; j1 = sign ^ (~(offset >> 23) & 1); j2 = sign ^ (~(offset >> 22) & 1); - *(u16 *)loc = (u16)((upper & 0xf800) | (sign << 10) | + upper = (u16)((upper & 0xf800) | (sign << 10) | ((offset >> 12) & 0x03ff)); - *(u16 *)(loc + 2) = (u16)((lower & 0xd000) | - (j1 << 13) | (j2 << 11) | - ((offset >> 1) & 0x07ff)); + lower = (u16)((lower & 0xd000) | + (j1 << 13) | (j2 << 11) | + ((offset >> 1) & 0x07ff)); + + *(u16 *)loc = __opcode_to_mem_thumb16(upper); + *(u16 *)(loc + 2) = __opcode_to_mem_thumb16(lower); break; case R_ARM_THM_MOVW_ABS_NC: case R_ARM_THM_MOVT_ABS: - upper = *(u16 *)loc; - lower = *(u16 *)(loc + 2); + upper = __mem_to_opcode_thumb16(*(u16 *)loc); + lower = __mem_to_opcode_thumb16(*(u16 *)(loc + 2)); /* * MOVT/MOVW instructions encoding in Thumb-2: @@ -229,12 +238,14 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, if (ELF32_R_TYPE(rel->r_info) == R_ARM_THM_MOVT_ABS) offset >>= 16; - *(u16 *)loc = (u16)((upper & 0xfbf0) | - ((offset & 0xf000) >> 12) | - ((offset & 0x0800) >> 1)); - *(u16 *)(loc + 2) = (u16)((lower & 0x8f00) | - ((offset & 0x0700) << 4) | - (offset & 0x00ff)); + upper = (u16)((upper & 0xfbf0) | + ((offset & 0xf000) >> 12) | + ((offset & 0x0800) >> 1)); + lower = (u16)((lower & 0x8f00) | + ((offset & 0x0700) << 4) | + (offset & 0x00ff)); + *(u16 *)loc = __opcode_to_mem_thumb16(upper); + *(u16 *)(loc + 2) = __opcode_to_mem_thumb16(lower); break; #endif diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index e186ee1e63f6..bc3f2efa0d86 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c @@ -256,12 +256,11 @@ validate_event(struct pmu_hw_events *hw_events, struct perf_event *event) { struct arm_pmu *armpmu = to_arm_pmu(event->pmu); - struct pmu *leader_pmu = event->group_leader->pmu; if (is_software_event(event)) return 1; - if (event->pmu != leader_pmu || event->state < PERF_EVENT_STATE_OFF) + if (event->state < PERF_EVENT_STATE_OFF) return 1; if (event->state == PERF_EVENT_STATE_OFF && !event->attr.enable_on_exec) diff --git a/arch/arm/kernel/perf_event_cpu.c b/arch/arm/kernel/perf_event_cpu.c index 8d6147b2001f..d85055cd24ba 100644 --- a/arch/arm/kernel/perf_event_cpu.c +++ b/arch/arm/kernel/perf_event_cpu.c @@ -68,7 +68,7 @@ EXPORT_SYMBOL_GPL(perf_num_counters); static struct pmu_hw_events *cpu_pmu_get_cpu_events(void) { - return &__get_cpu_var(cpu_hw_events); + return this_cpu_ptr(&cpu_hw_events); } static void cpu_pmu_free_irq(struct arm_pmu *cpu_pmu) diff --git a/arch/arm/kernel/perf_regs.c b/arch/arm/kernel/perf_regs.c new file mode 100644 index 000000000000..6e4379c67cbc --- /dev/null +++ b/arch/arm/kernel/perf_regs.c @@ -0,0 +1,30 @@ + +#include <linux/errno.h> +#include <linux/kernel.h> +#include <linux/perf_event.h> +#include <linux/bug.h> +#include <asm/perf_regs.h> +#include <asm/ptrace.h> + +u64 perf_reg_value(struct pt_regs *regs, int idx) +{ + if (WARN_ON_ONCE((u32)idx >= PERF_REG_ARM_MAX)) + return 0; + + return regs->uregs[idx]; +} + +#define REG_RESERVED (~((1ULL << PERF_REG_ARM_MAX) - 1)) + +int perf_reg_validate(u64 mask) +{ + if (!mask || mask & REG_RESERVED) + return -EINVAL; + + return 0; +} + +u64 perf_reg_abi(struct task_struct *task) +{ + return PERF_SAMPLE_REGS_ABI_32; +} diff --git a/arch/arm/kernel/psci_smp.c b/arch/arm/kernel/psci_smp.c index 70ded3fb42d9..570a48cc3d64 100644 --- a/arch/arm/kernel/psci_smp.c +++ b/arch/arm/kernel/psci_smp.c @@ -14,7 +14,6 @@ */ #include <linux/init.h> -#include <linux/irqchip/arm-gic.h> #include <linux/smp.h> #include <linux/of.h> diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 0e1e2b3afa45..6a1b8a81b1ae 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -73,6 +73,8 @@ __setup("fpe=", fpe_setup); #endif extern void paging_init(const struct machine_desc *desc); +extern void early_paging_init(const struct machine_desc *, + struct proc_info_list *); extern void sanity_check_meminfo(void); extern enum reboot_mode reboot_mode; extern void setup_dma_zone(const struct machine_desc *desc); @@ -599,6 +601,8 @@ static void __init setup_processor(void) elf_hwcap &= ~(HWCAP_THUMB | HWCAP_IDIVT); #endif + erratum_a15_798181_init(); + feat_v6_fixup(); cacheid_init(); @@ -619,9 +623,10 @@ void __init dump_machine_table(void) /* can't use cpu_relax() here as it may require MMU setup */; } -int __init arm_add_memory(phys_addr_t start, phys_addr_t size) +int __init arm_add_memory(u64 start, u64 size) { struct membank *bank = &meminfo.bank[meminfo.nr_banks]; + u64 aligned_start; if (meminfo.nr_banks >= NR_BANKS) { printk(KERN_CRIT "NR_BANKS too low, " @@ -634,10 +639,16 @@ int __init arm_add_memory(phys_addr_t start, phys_addr_t size) * Size is appropriately rounded down, start is rounded up. */ size -= start & ~PAGE_MASK; - bank->start = PAGE_ALIGN(start); + aligned_start = PAGE_ALIGN(start); -#ifndef CONFIG_ARM_LPAE - if (bank->start + size < bank->start) { +#ifndef CONFIG_ARCH_PHYS_ADDR_T_64BIT + if (aligned_start > ULONG_MAX) { + printk(KERN_CRIT "Ignoring memory at 0x%08llx outside " + "32-bit physical address space\n", (long long)start); + return -EINVAL; + } + + if (aligned_start + size > ULONG_MAX) { printk(KERN_CRIT "Truncating memory at 0x%08llx to fit in " "32-bit physical address space\n", (long long)start); /* @@ -645,10 +656,11 @@ int __init arm_add_memory(phys_addr_t start, phys_addr_t size) * 32 bits, we use ULONG_MAX as the upper limit rather than 4GB. * This means we lose a page after masking. */ - size = ULONG_MAX - bank->start; + size = ULONG_MAX - aligned_start; } #endif + bank->start = aligned_start; bank->size = size & ~(phys_addr_t)(PAGE_SIZE - 1); /* @@ -669,8 +681,8 @@ int __init arm_add_memory(phys_addr_t start, phys_addr_t size) static int __init early_mem(char *p) { static int usermem __initdata = 0; - phys_addr_t size; - phys_addr_t start; + u64 size; + u64 start; char *endp; /* @@ -878,6 +890,8 @@ void __init setup_arch(char **cmdline_p) parse_early_param(); sort(&meminfo.bank, meminfo.nr_banks, sizeof(meminfo.bank[0]), meminfo_cmp, NULL); + + early_paging_init(mdesc, lookup_processor_type(read_cpuid_id())); sanity_check_meminfo(); arm_memblock_init(&meminfo, mdesc); @@ -975,6 +989,7 @@ static const char *hwcap_str[] = { "idivt", "vfpd32", "lpae", + "evtstrm", NULL }; diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index ab3304225272..04d63880037f 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c @@ -21,29 +21,7 @@ #include <asm/unistd.h> #include <asm/vfp.h> -/* - * For ARM syscalls, we encode the syscall number into the instruction. - */ -#define SWI_SYS_SIGRETURN (0xef000000|(__NR_sigreturn)|(__NR_OABI_SYSCALL_BASE)) -#define SWI_SYS_RT_SIGRETURN (0xef000000|(__NR_rt_sigreturn)|(__NR_OABI_SYSCALL_BASE)) - -/* - * With EABI, the syscall number has to be loaded into r7. - */ -#define MOV_R7_NR_SIGRETURN (0xe3a07000 | (__NR_sigreturn - __NR_SYSCALL_BASE)) -#define MOV_R7_NR_RT_SIGRETURN (0xe3a07000 | (__NR_rt_sigreturn - __NR_SYSCALL_BASE)) - -/* - * For Thumb syscalls, we pass the syscall number via r7. We therefore - * need two 16-bit instructions. - */ -#define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (__NR_sigreturn - __NR_SYSCALL_BASE)) -#define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (__NR_rt_sigreturn - __NR_SYSCALL_BASE)) - -static const unsigned long sigreturn_codes[7] = { - MOV_R7_NR_SIGRETURN, SWI_SYS_SIGRETURN, SWI_THUMB_SIGRETURN, - MOV_R7_NR_RT_SIGRETURN, SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN, -}; +extern const unsigned long sigreturn_codes[7]; static unsigned long signal_return_offset; @@ -375,12 +353,18 @@ setup_return(struct pt_regs *regs, struct ksignal *ksig, */ thumb = handler & 1; - if (thumb) { - cpsr |= PSR_T_BIT; #if __LINUX_ARM_ARCH__ >= 7 - /* clear the If-Then Thumb-2 execution state */ - cpsr &= ~PSR_IT_MASK; + /* + * Clear the If-Then Thumb-2 execution state + * ARM spec requires this to be all 000s in ARM mode + * Snapdragon S4/Krait misbehaves on a Thumb=>ARM + * signal transition without this. + */ + cpsr &= ~PSR_IT_MASK; #endif + + if (thumb) { + cpsr |= PSR_T_BIT; } else cpsr &= ~PSR_T_BIT; } diff --git a/arch/arm/kernel/sigreturn_codes.S b/arch/arm/kernel/sigreturn_codes.S new file mode 100644 index 000000000000..3c5d0f2170fd --- /dev/null +++ b/arch/arm/kernel/sigreturn_codes.S @@ -0,0 +1,80 @@ +/* + * sigreturn_codes.S - code sinpets for sigreturn syscalls + * + * Created by: Victor Kamensky, 2013-08-13 + * Copyright: (C) 2013 Linaro Limited + * + * 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. + * + * This program is distributed in the hope that 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. + */ + +#include <asm/unistd.h> + +/* + * For ARM syscalls, we encode the syscall number into the instruction. + * With EABI, the syscall number has to be loaded into r7. As result + * ARM syscall sequence snippet will have move and svc in .arm encoding + * + * For Thumb syscalls, we pass the syscall number via r7. We therefore + * need two 16-bit instructions in .thumb encoding + * + * Please note sigreturn_codes code are not executed in place. Instead + * they just copied by kernel into appropriate places. Code inside of + * arch/arm/kernel/signal.c is very sensitive to layout of these code + * snippets. + */ + +#if __LINUX_ARM_ARCH__ <= 4 + /* + * Note we manually set minimally required arch that supports + * required thumb opcodes for early arch versions. It is OK + * for this file to be used in combination with other + * lower arch variants, since these code snippets are only + * used as input data. + */ + .arch armv4t +#endif + + .section .rodata + .global sigreturn_codes + .type sigreturn_codes, #object + + .arm + +sigreturn_codes: + + /* ARM sigreturn syscall code snippet */ + mov r7, #(__NR_sigreturn - __NR_SYSCALL_BASE) + swi #(__NR_sigreturn)|(__NR_OABI_SYSCALL_BASE) + + /* Thumb sigreturn syscall code snippet */ + .thumb + movs r7, #(__NR_sigreturn - __NR_SYSCALL_BASE) + swi #0 + + /* ARM sigreturn_rt syscall code snippet */ + .arm + mov r7, #(__NR_rt_sigreturn - __NR_SYSCALL_BASE) + swi #(__NR_rt_sigreturn)|(__NR_OABI_SYSCALL_BASE) + + /* Thumb sigreturn_rt syscall code snippet */ + .thumb + movs r7, #(__NR_rt_sigreturn - __NR_SYSCALL_BASE) + swi #0 + + /* + * Note on addtional space: setup_return in signal.c + * algorithm uses two words copy regardless whether + * it is thumb case or not, so we need additional + * word after real last entry. + */ + .arm + .space 4 + + .size sigreturn_codes, . - sigreturn_codes diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S index db1536b8b30b..b907d9b790ab 100644 --- a/arch/arm/kernel/sleep.S +++ b/arch/arm/kernel/sleep.S @@ -55,6 +55,7 @@ * specific registers and some other data for resume. * r0 = suspend function arg0 * r1 = suspend function + * r2 = MPIDR value the resuming CPU will use */ ENTRY(__cpu_suspend) stmfd sp!, {r4 - r11, lr} @@ -67,23 +68,18 @@ ENTRY(__cpu_suspend) mov r5, sp @ current virtual SP add r4, r4, #12 @ Space for pgd, virt sp, phys resume fn sub sp, sp, r4 @ allocate CPU state on stack - stmfd sp!, {r0, r1} @ save suspend func arg and pointer - add r0, sp, #8 @ save pointer to save block - mov r1, r4 @ size of save block - mov r2, r5 @ virtual SP ldr r3, =sleep_save_sp + stmfd sp!, {r0, r1} @ save suspend func arg and pointer ldr r3, [r3, #SLEEP_SAVE_SP_VIRT] - ALT_SMP(mrc p15, 0, r9, c0, c0, 5) - ALT_UP_B(1f) - ldr r8, =mpidr_hash - /* - * This ldmia relies on the memory layout of the mpidr_hash - * struct mpidr_hash. - */ - ldmia r8, {r4-r7} @ r4 = mpidr mask (r5,r6,r7) = l[0,1,2] shifts - compute_mpidr_hash lr, r5, r6, r7, r9, r4 - add r3, r3, lr, lsl #2 -1: + ALT_SMP(ldr r0, =mpidr_hash) + ALT_UP_B(1f) + /* This ldmia relies on the memory layout of the mpidr_hash struct */ + ldmia r0, {r1, r6-r8} @ r1 = mpidr mask (r6,r7,r8) = l[0,1,2] shifts + compute_mpidr_hash r0, r6, r7, r8, r2, r1 + add r3, r3, r0, lsl #2 +1: mov r2, r5 @ virtual SP + mov r1, r4 @ size of save block + add r0, sp, #8 @ pointer to save block bl __cpu_suspend_save adr lr, BSYM(cpu_suspend_abort) ldmfd sp!, {r0, pc} @ call suspend fn @@ -130,6 +126,7 @@ ENDPROC(cpu_resume_after_mmu) .data .align ENTRY(cpu_resume) +ARM_BE8(setend be) @ ensure we are in BE mode mov r1, #0 ALT_SMP(mrc p15, 0, r0, c0, c0, 5) ALT_UP_B(1f) diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 72024ea8a3a6..dc894ab3622b 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -25,6 +25,7 @@ #include <linux/clockchips.h> #include <linux/completion.h> #include <linux/cpufreq.h> +#include <linux/irq_work.h> #include <linux/atomic.h> #include <asm/smp.h> @@ -66,6 +67,8 @@ enum ipi_msg_type { IPI_CALL_FUNC, IPI_CALL_FUNC_SINGLE, IPI_CPU_STOP, + IPI_IRQ_WORK, + IPI_COMPLETION, }; static DECLARE_COMPLETION(cpu_running); @@ -80,7 +83,7 @@ void __init smp_set_ops(struct smp_operations *ops) static unsigned long get_arch_pgd(pgd_t *pgd) { - phys_addr_t pgdir = virt_to_phys(pgd); + phys_addr_t pgdir = virt_to_idmap(pgd); BUG_ON(pgdir & ARCH_PGD_MASK); return pgdir >> ARCH_PGD_SHIFT; } @@ -448,6 +451,14 @@ void arch_send_call_function_single_ipi(int cpu) smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE); } +#ifdef CONFIG_IRQ_WORK +void arch_irq_work_raise(void) +{ + if (is_smp()) + smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK); +} +#endif + static const char *ipi_types[NR_IPI] = { #define S(x,s) [x] = s S(IPI_WAKEUP, "CPU wakeup interrupts"), @@ -456,6 +467,8 @@ static const char *ipi_types[NR_IPI] = { S(IPI_CALL_FUNC, "Function call interrupts"), S(IPI_CALL_FUNC_SINGLE, "Single function call interrupts"), S(IPI_CPU_STOP, "CPU stop interrupts"), + S(IPI_IRQ_WORK, "IRQ work interrupts"), + S(IPI_COMPLETION, "completion interrupts"), }; void show_ipi_list(struct seq_file *p, int prec) @@ -515,6 +528,19 @@ static void ipi_cpu_stop(unsigned int cpu) cpu_relax(); } +static DEFINE_PER_CPU(struct completion *, cpu_completion); + +int register_ipi_completion(struct completion *completion, int cpu) +{ + per_cpu(cpu_completion, cpu) = completion; + return IPI_COMPLETION; +} + +static void ipi_complete(unsigned int cpu) +{ + complete(per_cpu(cpu_completion, cpu)); +} + /* * Main handler for inter-processor interrupts */ @@ -565,6 +591,20 @@ void handle_IPI(int ipinr, struct pt_regs *regs) irq_exit(); break; +#ifdef CONFIG_IRQ_WORK + case IPI_IRQ_WORK: + irq_enter(); + irq_work_run(); + irq_exit(); + break; +#endif + + case IPI_COMPLETION: + irq_enter(); + ipi_complete(cpu); + irq_exit(); + break; + default: printk(KERN_CRIT "CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr); diff --git a/arch/arm/kernel/smp_scu.c b/arch/arm/kernel/smp_scu.c index 5bc1a63284e3..1aafa0d785eb 100644 --- a/arch/arm/kernel/smp_scu.c +++ b/arch/arm/kernel/smp_scu.c @@ -28,7 +28,7 @@ */ unsigned int __init scu_get_core_count(void __iomem *scu_base) { - unsigned int ncores = __raw_readl(scu_base + SCU_CONFIG); + unsigned int ncores = readl_relaxed(scu_base + SCU_CONFIG); return (ncores & 0x03) + 1; } @@ -42,19 +42,19 @@ void scu_enable(void __iomem *scu_base) #ifdef CONFIG_ARM_ERRATA_764369 /* Cortex-A9 only */ if ((read_cpuid_id() & 0xff0ffff0) == 0x410fc090) { - scu_ctrl = __raw_readl(scu_base + 0x30); + scu_ctrl = readl_relaxed(scu_base + 0x30); if (!(scu_ctrl & 1)) - __raw_writel(scu_ctrl | 0x1, scu_base + 0x30); + writel_relaxed(scu_ctrl | 0x1, scu_base + 0x30); } #endif - scu_ctrl = __raw_readl(scu_base + SCU_CTRL); + scu_ctrl = readl_relaxed(scu_base + SCU_CTRL); /* already enabled? */ if (scu_ctrl & 1) return; scu_ctrl |= 1; - __raw_writel(scu_ctrl, scu_base + SCU_CTRL); + writel_relaxed(scu_ctrl, scu_base + SCU_CTRL); /* * Ensure that the data accessed by CPU0 before the SCU was @@ -80,9 +80,9 @@ int scu_power_mode(void __iomem *scu_base, unsigned int mode) if (mode > 3 || mode == 1 || cpu > 3) return -EINVAL; - val = __raw_readb(scu_base + SCU_CPU_STATUS + cpu) & ~0x03; + val = readb_relaxed(scu_base + SCU_CPU_STATUS + cpu) & ~0x03; val |= mode; - __raw_writeb(val, scu_base + SCU_CPU_STATUS + cpu); + writeb_relaxed(val, scu_base + SCU_CPU_STATUS + cpu); return 0; } diff --git a/arch/arm/kernel/smp_tlb.c b/arch/arm/kernel/smp_tlb.c index 83ccca303df8..95d063620b76 100644 --- a/arch/arm/kernel/smp_tlb.c +++ b/arch/arm/kernel/smp_tlb.c @@ -70,6 +70,40 @@ static inline void ipi_flush_bp_all(void *ignored) local_flush_bp_all(); } +#ifdef CONFIG_ARM_ERRATA_798181 +bool (*erratum_a15_798181_handler)(void); + +static bool erratum_a15_798181_partial(void) +{ + asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (0)); + dsb(ish); + return false; +} + +static bool erratum_a15_798181_broadcast(void) +{ + asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (0)); + dsb(ish); + return true; +} + +void erratum_a15_798181_init(void) +{ + unsigned int midr = read_cpuid_id(); + unsigned int revidr = read_cpuid(CPUID_REVIDR); + + /* Cortex-A15 r0p0..r3p2 w/o ECO fix affected */ + if ((midr & 0xff0ffff0) != 0x410fc0f0 || midr > 0x413fc0f2 || + (revidr & 0x210) == 0x210) { + return; + } + if (revidr & 0x10) + erratum_a15_798181_handler = erratum_a15_798181_partial; + else + erratum_a15_798181_handler = erratum_a15_798181_broadcast; +} +#endif + static void ipi_flush_tlb_a15_erratum(void *arg) { dmb(); @@ -80,7 +114,6 @@ static void broadcast_tlb_a15_erratum(void) if (!erratum_a15_798181()) return; - dummy_flush_tlb_a15_erratum(); smp_call_function(ipi_flush_tlb_a15_erratum, NULL, 1); } @@ -92,7 +125,6 @@ static void broadcast_tlb_mm_a15_erratum(struct mm_struct *mm) if (!erratum_a15_798181()) return; - dummy_flush_tlb_a15_erratum(); this_cpu = get_cpu(); a15_erratum_get_cpumask(this_cpu, mm, &mask); smp_call_function_many(&mask, ipi_flush_tlb_a15_erratum, NULL, 1); diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c index 2985c9f0905d..6591e26fc13f 100644 --- a/arch/arm/kernel/smp_twd.c +++ b/arch/arm/kernel/smp_twd.c @@ -45,7 +45,7 @@ static void twd_set_mode(enum clock_event_mode mode, case CLOCK_EVT_MODE_PERIODIC: ctrl = TWD_TIMER_CONTROL_ENABLE | TWD_TIMER_CONTROL_IT_ENABLE | TWD_TIMER_CONTROL_PERIODIC; - __raw_writel(DIV_ROUND_CLOSEST(twd_timer_rate, HZ), + writel_relaxed(DIV_ROUND_CLOSEST(twd_timer_rate, HZ), twd_base + TWD_TIMER_LOAD); break; case CLOCK_EVT_MODE_ONESHOT: @@ -58,18 +58,18 @@ static void twd_set_mode(enum clock_event_mode mode, ctrl = 0; } - __raw_writel(ctrl, twd_base + TWD_TIMER_CONTROL); + writel_relaxed(ctrl, twd_base + TWD_TIMER_CONTROL); } static int twd_set_next_event(unsigned long evt, struct clock_event_device *unused) { - unsigned long ctrl = __raw_readl(twd_base + TWD_TIMER_CONTROL); + unsigned long ctrl = readl_relaxed(twd_base + TWD_TIMER_CONTROL); ctrl |= TWD_TIMER_CONTROL_ENABLE; - __raw_writel(evt, twd_base + TWD_TIMER_COUNTER); - __raw_writel(ctrl, twd_base + TWD_TIMER_CONTROL); + writel_relaxed(evt, twd_base + TWD_TIMER_COUNTER); + writel_relaxed(ctrl, twd_base + TWD_TIMER_CONTROL); return 0; } @@ -82,8 +82,8 @@ static int twd_set_next_event(unsigned long evt, */ static int twd_timer_ack(void) { - if (__raw_readl(twd_base + TWD_TIMER_INTSTAT)) { - __raw_writel(1, twd_base + TWD_TIMER_INTSTAT); + if (readl_relaxed(twd_base + TWD_TIMER_INTSTAT)) { + writel_relaxed(1, twd_base + TWD_TIMER_INTSTAT); return 1; } @@ -211,15 +211,15 @@ static void twd_calibrate_rate(void) waitjiffies += 5; /* enable, no interrupt or reload */ - __raw_writel(0x1, twd_base + TWD_TIMER_CONTROL); + writel_relaxed(0x1, twd_base + TWD_TIMER_CONTROL); /* maximum value */ - __raw_writel(0xFFFFFFFFU, twd_base + TWD_TIMER_COUNTER); + writel_relaxed(0xFFFFFFFFU, twd_base + TWD_TIMER_COUNTER); while (get_jiffies_64() < waitjiffies) udelay(10); - count = __raw_readl(twd_base + TWD_TIMER_COUNTER); + count = readl_relaxed(twd_base + TWD_TIMER_COUNTER); twd_timer_rate = (0xFFFFFFFFU - count) * (HZ / 5); @@ -277,7 +277,7 @@ static void twd_timer_setup(void) * bother with the below. */ if (per_cpu(percpu_setup_called, cpu)) { - __raw_writel(0, twd_base + TWD_TIMER_CONTROL); + writel_relaxed(0, twd_base + TWD_TIMER_CONTROL); clockevents_register_device(clk); enable_percpu_irq(clk->irq, 0); return; @@ -290,7 +290,7 @@ static void twd_timer_setup(void) * The following is done once per CPU the first time .setup() is * called. */ - __raw_writel(0, twd_base + TWD_TIMER_CONTROL); + writel_relaxed(0, twd_base + TWD_TIMER_CONTROL); clk->name = "local_timer"; clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT | diff --git a/arch/arm/kernel/suspend.c b/arch/arm/kernel/suspend.c index 41cf3cbf756d..2835d35234ca 100644 --- a/arch/arm/kernel/suspend.c +++ b/arch/arm/kernel/suspend.c @@ -10,7 +10,7 @@ #include <asm/suspend.h> #include <asm/tlbflush.h> -extern int __cpu_suspend(unsigned long, int (*)(unsigned long)); +extern int __cpu_suspend(unsigned long, int (*)(unsigned long), u32 cpuid); extern void cpu_resume_mmu(void); #ifdef CONFIG_MMU @@ -21,6 +21,7 @@ extern void cpu_resume_mmu(void); int cpu_suspend(unsigned long arg, int (*fn)(unsigned long)) { struct mm_struct *mm = current->active_mm; + u32 __mpidr = cpu_logical_map(smp_processor_id()); int ret; if (!idmap_pgd) @@ -32,7 +33,7 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long)) * resume (indicated by a zero return code), we need to switch * back to the correct page tables. */ - ret = __cpu_suspend(arg, fn); + ret = __cpu_suspend(arg, fn, __mpidr); if (ret == 0) { cpu_switch_mm(mm->pgd, mm); local_flush_bp_all(); @@ -44,7 +45,8 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long)) #else int cpu_suspend(unsigned long arg, int (*fn)(unsigned long)) { - return __cpu_suspend(arg, fn); + u32 __mpidr = cpu_logical_map(smp_processor_id()); + return __cpu_suspend(arg, fn, __mpidr); } #define idmap_pgd NULL #endif diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c index 98aee3258398..829a96d4a179 100644 --- a/arch/arm/kernel/time.c +++ b/arch/arm/kernel/time.c @@ -11,25 +11,26 @@ * This file contains the ARM-specific time handling details: * reading the RTC at bootup, etc... */ +#include <linux/clk-provider.h> +#include <linux/clocksource.h> +#include <linux/errno.h> #include <linux/export.h> -#include <linux/kernel.h> -#include <linux/interrupt.h> -#include <linux/time.h> #include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/kernel.h> +#include <linux/profile.h> #include <linux/sched.h> +#include <linux/sched_clock.h> #include <linux/smp.h> +#include <linux/time.h> #include <linux/timex.h> -#include <linux/errno.h> -#include <linux/profile.h> #include <linux/timer.h> -#include <linux/clocksource.h> -#include <linux/irq.h> -#include <linux/sched_clock.h> -#include <asm/thread_info.h> -#include <asm/stacktrace.h> #include <asm/mach/arch.h> #include <asm/mach/time.h> +#include <asm/stacktrace.h> +#include <asm/thread_info.h> #if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) || \ defined(CONFIG_NVRAM) || defined(CONFIG_NVRAM_MODULE) @@ -116,8 +117,12 @@ int __init register_persistent_clock(clock_access_fn read_boot, void __init time_init(void) { - if (machine_desc->init_time) + if (machine_desc->init_time) { machine_desc->init_time(); - else + } else { +#ifdef CONFIG_COMMON_CLK + of_clk_init(NULL); +#endif clocksource_of_init(); + } } diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 8fcda140358d..6125f259b7b5 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -34,6 +34,7 @@ #include <asm/unwind.h> #include <asm/tls.h> #include <asm/system_misc.h> +#include <asm/opcodes.h> static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" }; @@ -341,15 +342,17 @@ void arm_notify_die(const char *str, struct pt_regs *regs, int is_valid_bugaddr(unsigned long pc) { #ifdef CONFIG_THUMB2_KERNEL - unsigned short bkpt; + u16 bkpt; + u16 insn = __opcode_to_mem_thumb16(BUG_INSTR_VALUE); #else - unsigned long bkpt; + u32 bkpt; + u32 insn = __opcode_to_mem_arm(BUG_INSTR_VALUE); #endif if (probe_kernel_address((unsigned *)pc, bkpt)) return 0; - return bkpt == BUG_INSTR_VALUE; + return bkpt == insn; } #endif @@ -402,25 +405,28 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs) if (processor_mode(regs) == SVC_MODE) { #ifdef CONFIG_THUMB2_KERNEL if (thumb_mode(regs)) { - instr = ((u16 *)pc)[0]; + instr = __mem_to_opcode_thumb16(((u16 *)pc)[0]); if (is_wide_instruction(instr)) { - instr <<= 16; - instr |= ((u16 *)pc)[1]; + u16 inst2; + inst2 = __mem_to_opcode_thumb16(((u16 *)pc)[1]); + instr = __opcode_thumb32_compose(instr, inst2); } } else #endif - instr = *(u32 *) pc; + instr = __mem_to_opcode_arm(*(u32 *) pc); } else if (thumb_mode(regs)) { if (get_user(instr, (u16 __user *)pc)) goto die_sig; + instr = __mem_to_opcode_thumb16(instr); if (is_wide_instruction(instr)) { unsigned int instr2; if (get_user(instr2, (u16 __user *)pc+1)) goto die_sig; - instr <<= 16; - instr |= instr2; + instr2 = __mem_to_opcode_thumb16(instr2); + instr = __opcode_thumb32_compose(instr, instr2); } } else if (get_user(instr, (u32 __user *)pc)) { + instr = __mem_to_opcode_arm(instr); goto die_sig; } diff --git a/arch/arm/kvm/Kconfig b/arch/arm/kvm/Kconfig index ebf5015508b5..466bd299b1a8 100644 --- a/arch/arm/kvm/Kconfig +++ b/arch/arm/kvm/Kconfig @@ -20,6 +20,7 @@ config KVM bool "Kernel-based Virtual Machine (KVM) support" select PREEMPT_NOTIFIERS select ANON_INODES + select HAVE_KVM_CPU_RELAX_INTERCEPT select KVM_MMIO select KVM_ARM_HOST depends on ARM_VIRT_EXT && ARM_LPAE diff --git a/arch/arm/kvm/Makefile b/arch/arm/kvm/Makefile index d99bee4950e5..789bca9e64a7 100644 --- a/arch/arm/kvm/Makefile +++ b/arch/arm/kvm/Makefile @@ -19,6 +19,6 @@ kvm-arm-y = $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o obj-y += kvm-arm.o init.o interrupts.o obj-y += arm.o handle_exit.o guest.o mmu.o emulate.o reset.o -obj-y += coproc.o coproc_a15.o mmio.o psci.o perf.o +obj-y += coproc.o coproc_a15.o coproc_a7.o mmio.o psci.o perf.o obj-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic.o obj-$(CONFIG_KVM_ARM_TIMER) += $(KVM)/arm/arch_timer.o diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index 9c697db2787e..2a700e00528d 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c @@ -65,7 +65,7 @@ static bool vgic_present; static void kvm_arm_set_running_vcpu(struct kvm_vcpu *vcpu) { BUG_ON(preemptible()); - __get_cpu_var(kvm_arm_running_vcpu) = vcpu; + __this_cpu_write(kvm_arm_running_vcpu, vcpu); } /** @@ -75,7 +75,7 @@ static void kvm_arm_set_running_vcpu(struct kvm_vcpu *vcpu) struct kvm_vcpu *kvm_arm_get_running_vcpu(void) { BUG_ON(preemptible()); - return __get_cpu_var(kvm_arm_running_vcpu); + return __this_cpu_read(kvm_arm_running_vcpu); } /** @@ -152,12 +152,13 @@ int kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf) return VM_FAULT_SIGBUS; } -void kvm_arch_free_memslot(struct kvm_memory_slot *free, +void kvm_arch_free_memslot(struct kvm *kvm, struct kvm_memory_slot *free, struct kvm_memory_slot *dont) { } -int kvm_arch_create_memslot(struct kvm_memory_slot *slot, unsigned long npages) +int kvm_arch_create_memslot(struct kvm *kvm, struct kvm_memory_slot *slot, + unsigned long npages) { return 0; } @@ -797,6 +798,19 @@ long kvm_arch_vm_ioctl(struct file *filp, return -EFAULT; return kvm_vm_ioctl_set_device_addr(kvm, &dev_addr); } + case KVM_ARM_PREFERRED_TARGET: { + int err; + struct kvm_vcpu_init init; + + err = kvm_vcpu_preferred_target(&init); + if (err) + return err; + + if (copy_to_user(argp, &init, sizeof(init))) + return -EFAULT; + + return 0; + } default: return -EINVAL; } @@ -815,7 +829,7 @@ static void cpu_init_hyp_mode(void *dummy) boot_pgd_ptr = kvm_mmu_get_boot_httbr(); pgd_ptr = kvm_mmu_get_httbr(); - stack_page = __get_cpu_var(kvm_arm_hyp_stack_page); + stack_page = __this_cpu_read(kvm_arm_hyp_stack_page); hyp_stack_ptr = stack_page + PAGE_SIZE; vector_ptr = (unsigned long)__kvm_hyp_vector; diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c index db9cf692d4dd..78c0885d6501 100644 --- a/arch/arm/kvm/coproc.c +++ b/arch/arm/kvm/coproc.c @@ -71,6 +71,98 @@ int kvm_handle_cp14_access(struct kvm_vcpu *vcpu, struct kvm_run *run) return 1; } +static void reset_mpidr(struct kvm_vcpu *vcpu, const struct coproc_reg *r) +{ + /* + * Compute guest MPIDR. We build a virtual cluster out of the + * vcpu_id, but we read the 'U' bit from the underlying + * hardware directly. + */ + vcpu->arch.cp15[c0_MPIDR] = ((read_cpuid_mpidr() & MPIDR_SMP_BITMASK) | + ((vcpu->vcpu_id >> 2) << MPIDR_LEVEL_BITS) | + (vcpu->vcpu_id & 3)); +} + +/* TRM entries A7:4.3.31 A15:4.3.28 - RO WI */ +static bool access_actlr(struct kvm_vcpu *vcpu, + const struct coproc_params *p, + const struct coproc_reg *r) +{ + if (p->is_write) + return ignore_write(vcpu, p); + + *vcpu_reg(vcpu, p->Rt1) = vcpu->arch.cp15[c1_ACTLR]; + return true; +} + +/* TRM entries A7:4.3.56, A15:4.3.60 - R/O. */ +static bool access_cbar(struct kvm_vcpu *vcpu, + const struct coproc_params *p, + const struct coproc_reg *r) +{ + if (p->is_write) + return write_to_read_only(vcpu, p); + return read_zero(vcpu, p); +} + +/* TRM entries A7:4.3.49, A15:4.3.48 - R/O WI */ +static bool access_l2ctlr(struct kvm_vcpu *vcpu, + const struct coproc_params *p, + const struct coproc_reg *r) +{ + if (p->is_write) + return ignore_write(vcpu, p); + + *vcpu_reg(vcpu, p->Rt1) = vcpu->arch.cp15[c9_L2CTLR]; + return true; +} + +static void reset_l2ctlr(struct kvm_vcpu *vcpu, const struct coproc_reg *r) +{ + u32 l2ctlr, ncores; + + asm volatile("mrc p15, 1, %0, c9, c0, 2\n" : "=r" (l2ctlr)); + l2ctlr &= ~(3 << 24); + ncores = atomic_read(&vcpu->kvm->online_vcpus) - 1; + /* How many cores in the current cluster and the next ones */ + ncores -= (vcpu->vcpu_id & ~3); + /* Cap it to the maximum number of cores in a single cluster */ + ncores = min(ncores, 3U); + l2ctlr |= (ncores & 3) << 24; + + vcpu->arch.cp15[c9_L2CTLR] = l2ctlr; +} + +static void reset_actlr(struct kvm_vcpu *vcpu, const struct coproc_reg *r) +{ + u32 actlr; + + /* ACTLR contains SMP bit: make sure you create all cpus first! */ + asm volatile("mrc p15, 0, %0, c1, c0, 1\n" : "=r" (actlr)); + /* Make the SMP bit consistent with the guest configuration */ + if (atomic_read(&vcpu->kvm->online_vcpus) > 1) + actlr |= 1U << 6; + else + actlr &= ~(1U << 6); + + vcpu->arch.cp15[c1_ACTLR] = actlr; +} + +/* + * TRM entries: A7:4.3.50, A15:4.3.49 + * R/O WI (even if NSACR.NS_L2ERR, a write of 1 is ignored). + */ +static bool access_l2ectlr(struct kvm_vcpu *vcpu, + const struct coproc_params *p, + const struct coproc_reg *r) +{ + if (p->is_write) + return ignore_write(vcpu, p); + + *vcpu_reg(vcpu, p->Rt1) = 0; + return true; +} + /* See note at ARM ARM B1.14.4 */ static bool access_dcsw(struct kvm_vcpu *vcpu, const struct coproc_params *p, @@ -153,10 +245,22 @@ static bool pm_fake(struct kvm_vcpu *vcpu, * registers preceding 32-bit ones. */ static const struct coproc_reg cp15_regs[] = { + /* MPIDR: we use VMPIDR for guest access. */ + { CRn( 0), CRm( 0), Op1( 0), Op2( 5), is32, + NULL, reset_mpidr, c0_MPIDR }, + /* CSSELR: swapped by interrupt.S. */ { CRn( 0), CRm( 0), Op1( 2), Op2( 0), is32, NULL, reset_unknown, c0_CSSELR }, + /* ACTLR: trapped by HCR.TAC bit. */ + { CRn( 1), CRm( 0), Op1( 0), Op2( 1), is32, + access_actlr, reset_actlr, c1_ACTLR }, + + /* CPACR: swapped by interrupt.S. */ + { CRn( 1), CRm( 0), Op1( 0), Op2( 2), is32, + NULL, reset_val, c1_CPACR, 0x00000000 }, + /* TTBR0/TTBR1: swapped by interrupt.S. */ { CRm64( 2), Op1( 0), is64, NULL, reset_unknown64, c2_TTBR0 }, { CRm64( 2), Op1( 1), is64, NULL, reset_unknown64, c2_TTBR1 }, @@ -195,6 +299,13 @@ static const struct coproc_reg cp15_regs[] = { { CRn( 7), CRm(10), Op1( 0), Op2( 2), is32, access_dcsw}, { CRn( 7), CRm(14), Op1( 0), Op2( 2), is32, access_dcsw}, /* + * L2CTLR access (guest wants to know #CPUs). + */ + { CRn( 9), CRm( 0), Op1( 1), Op2( 2), is32, + access_l2ctlr, reset_l2ctlr, c9_L2CTLR }, + { CRn( 9), CRm( 0), Op1( 1), Op2( 3), is32, access_l2ectlr}, + + /* * Dummy performance monitor implementation. */ { CRn( 9), CRm(12), Op1( 0), Op2( 0), is32, access_pmcr}, @@ -234,6 +345,9 @@ static const struct coproc_reg cp15_regs[] = { /* CNTKCTL: swapped by interrupt.S. */ { CRn(14), CRm( 1), Op1( 0), Op2( 0), is32, NULL, reset_val, c14_CNTKCTL, 0x00000000 }, + + /* The Configuration Base Address Register. */ + { CRn(15), CRm( 0), Op1( 4), Op2( 0), is32, access_cbar}, }; /* Target specific emulation tables */ @@ -241,6 +355,12 @@ static struct kvm_coproc_target_table *target_tables[KVM_ARM_NUM_TARGETS]; void kvm_register_target_coproc_table(struct kvm_coproc_target_table *table) { + unsigned int i; + + for (i = 1; i < table->num; i++) + BUG_ON(cmp_reg(&table->table[i-1], + &table->table[i]) >= 0); + target_tables[table->target] = table; } diff --git a/arch/arm/kvm/coproc_a15.c b/arch/arm/kvm/coproc_a15.c index cf93472b9dd6..bb0cac1410cc 100644 --- a/arch/arm/kvm/coproc_a15.c +++ b/arch/arm/kvm/coproc_a15.c @@ -17,101 +17,12 @@ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include <linux/kvm_host.h> -#include <asm/cputype.h> -#include <asm/kvm_arm.h> -#include <asm/kvm_host.h> -#include <asm/kvm_emulate.h> #include <asm/kvm_coproc.h> +#include <asm/kvm_emulate.h> #include <linux/init.h> -static void reset_mpidr(struct kvm_vcpu *vcpu, const struct coproc_reg *r) -{ - /* - * Compute guest MPIDR: - * (Even if we present only one VCPU to the guest on an SMP - * host we don't set the U bit in the MPIDR, or vice versa, as - * revealing the underlying hardware properties is likely to - * be the best choice). - */ - vcpu->arch.cp15[c0_MPIDR] = (read_cpuid_mpidr() & ~MPIDR_LEVEL_MASK) - | (vcpu->vcpu_id & MPIDR_LEVEL_MASK); -} - #include "coproc.h" -/* A15 TRM 4.3.28: RO WI */ -static bool access_actlr(struct kvm_vcpu *vcpu, - const struct coproc_params *p, - const struct coproc_reg *r) -{ - if (p->is_write) - return ignore_write(vcpu, p); - - *vcpu_reg(vcpu, p->Rt1) = vcpu->arch.cp15[c1_ACTLR]; - return true; -} - -/* A15 TRM 4.3.60: R/O. */ -static bool access_cbar(struct kvm_vcpu *vcpu, - const struct coproc_params *p, - const struct coproc_reg *r) -{ - if (p->is_write) - return write_to_read_only(vcpu, p); - return read_zero(vcpu, p); -} - -/* A15 TRM 4.3.48: R/O WI. */ -static bool access_l2ctlr(struct kvm_vcpu *vcpu, - const struct coproc_params *p, - const struct coproc_reg *r) -{ - if (p->is_write) - return ignore_write(vcpu, p); - - *vcpu_reg(vcpu, p->Rt1) = vcpu->arch.cp15[c9_L2CTLR]; - return true; -} - -static void reset_l2ctlr(struct kvm_vcpu *vcpu, const struct coproc_reg *r) -{ - u32 l2ctlr, ncores; - - asm volatile("mrc p15, 1, %0, c9, c0, 2\n" : "=r" (l2ctlr)); - l2ctlr &= ~(3 << 24); - ncores = atomic_read(&vcpu->kvm->online_vcpus) - 1; - l2ctlr |= (ncores & 3) << 24; - - vcpu->arch.cp15[c9_L2CTLR] = l2ctlr; -} - -static void reset_actlr(struct kvm_vcpu *vcpu, const struct coproc_reg *r) -{ - u32 actlr; - - /* ACTLR contains SMP bit: make sure you create all cpus first! */ - asm volatile("mrc p15, 0, %0, c1, c0, 1\n" : "=r" (actlr)); - /* Make the SMP bit consistent with the guest configuration */ - if (atomic_read(&vcpu->kvm->online_vcpus) > 1) - actlr |= 1U << 6; - else - actlr &= ~(1U << 6); - - vcpu->arch.cp15[c1_ACTLR] = actlr; -} - -/* A15 TRM 4.3.49: R/O WI (even if NSACR.NS_L2ERR, a write of 1 is ignored). */ -static bool access_l2ectlr(struct kvm_vcpu *vcpu, - const struct coproc_params *p, - const struct coproc_reg *r) -{ - if (p->is_write) - return ignore_write(vcpu, p); - - *vcpu_reg(vcpu, p->Rt1) = 0; - return true; -} - /* * A15-specific CP15 registers. * CRn denotes the primary register number, but is copied to the CRm in the @@ -121,29 +32,9 @@ static bool access_l2ectlr(struct kvm_vcpu *vcpu, * registers preceding 32-bit ones. */ static const struct coproc_reg a15_regs[] = { - /* MPIDR: we use VMPIDR for guest access. */ - { CRn( 0), CRm( 0), Op1( 0), Op2( 5), is32, - NULL, reset_mpidr, c0_MPIDR }, - /* SCTLR: swapped by interrupt.S. */ { CRn( 1), CRm( 0), Op1( 0), Op2( 0), is32, NULL, reset_val, c1_SCTLR, 0x00C50078 }, - /* ACTLR: trapped by HCR.TAC bit. */ - { CRn( 1), CRm( 0), Op1( 0), Op2( 1), is32, - access_actlr, reset_actlr, c1_ACTLR }, - /* CPACR: swapped by interrupt.S. */ - { CRn( 1), CRm( 0), Op1( 0), Op2( 2), is32, - NULL, reset_val, c1_CPACR, 0x00000000 }, - - /* - * L2CTLR access (guest wants to know #CPUs). - */ - { CRn( 9), CRm( 0), Op1( 1), Op2( 2), is32, - access_l2ctlr, reset_l2ctlr, c9_L2CTLR }, - { CRn( 9), CRm( 0), Op1( 1), Op2( 3), is32, access_l2ectlr}, - - /* The Configuration Base Address Register. */ - { CRn(15), CRm( 0), Op1( 4), Op2( 0), is32, access_cbar}, }; static struct kvm_coproc_target_table a15_target_table = { @@ -154,12 +45,6 @@ static struct kvm_coproc_target_table a15_target_table = { static int __init coproc_a15_init(void) { - unsigned int i; - - for (i = 1; i < ARRAY_SIZE(a15_regs); i++) - BUG_ON(cmp_reg(&a15_regs[i-1], - &a15_regs[i]) >= 0); - kvm_register_target_coproc_table(&a15_target_table); return 0; } diff --git a/arch/arm/kvm/coproc_a7.c b/arch/arm/kvm/coproc_a7.c new file mode 100644 index 000000000000..1df767331588 --- /dev/null +++ b/arch/arm/kvm/coproc_a7.c @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2012 - Virtual Open Systems and Columbia University + * Copyright (C) 2013 - ARM Ltd + * + * Authors: Rusty Russell <rusty@rustcorp.au> + * Christoffer Dall <c.dall@virtualopensystems.com> + * Jonathan Austin <jonathan.austin@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 + * published by the Free Software Foundation. + * + * This program is distributed in the hope that 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, write to the Free Software + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include <linux/kvm_host.h> +#include <asm/kvm_coproc.h> +#include <asm/kvm_emulate.h> +#include <linux/init.h> + +#include "coproc.h" + +/* + * Cortex-A7 specific CP15 registers. + * CRn denotes the primary register number, but is copied to the CRm in the + * user space API for 64-bit register access in line with the terminology used + * in the ARM ARM. + * Important: Must be sorted ascending by CRn, CRM, Op1, Op2 and with 64-bit + * registers preceding 32-bit ones. + */ +static const struct coproc_reg a7_regs[] = { + /* SCTLR: swapped by interrupt.S. */ + { CRn( 1), CRm( 0), Op1( 0), Op2( 0), is32, + NULL, reset_val, c1_SCTLR, 0x00C50878 }, +}; + +static struct kvm_coproc_target_table a7_target_table = { + .target = KVM_ARM_TARGET_CORTEX_A7, + .table = a7_regs, + .num = ARRAY_SIZE(a7_regs), +}; + +static int __init coproc_a7_init(void) +{ + kvm_register_target_coproc_table(&a7_target_table); + return 0; +} +late_initcall(coproc_a7_init); diff --git a/arch/arm/kvm/emulate.c b/arch/arm/kvm/emulate.c index bdede9e7da51..d6c005283678 100644 --- a/arch/arm/kvm/emulate.c +++ b/arch/arm/kvm/emulate.c @@ -354,7 +354,7 @@ static void inject_abt(struct kvm_vcpu *vcpu, bool is_pabt, unsigned long addr) *vcpu_pc(vcpu) = exc_vector_base(vcpu) + vect_offset; if (is_pabt) { - /* Set DFAR and DFSR */ + /* Set IFAR and IFSR */ vcpu->arch.cp15[c6_IFAR] = addr; is_lpae = (vcpu->arch.cp15[c2_TTBCR] >> 31); /* Always give debug fault for now - should give guest a clue */ diff --git a/arch/arm/kvm/guest.c b/arch/arm/kvm/guest.c index 152d03612181..20f8d97904af 100644 --- a/arch/arm/kvm/guest.c +++ b/arch/arm/kvm/guest.c @@ -190,6 +190,8 @@ int __attribute_const__ kvm_target_cpu(void) return -EINVAL; switch (part_number) { + case ARM_CPU_PART_CORTEX_A7: + return KVM_ARM_TARGET_CORTEX_A7; case ARM_CPU_PART_CORTEX_A15: return KVM_ARM_TARGET_CORTEX_A15; default: @@ -202,7 +204,7 @@ int kvm_vcpu_set_target(struct kvm_vcpu *vcpu, { unsigned int i; - /* We can only do a cortex A15 for now. */ + /* We can only cope with guest==host and only on A15/A7 (for now). */ if (init->target != kvm_target_cpu()) return -EINVAL; @@ -222,6 +224,26 @@ int kvm_vcpu_set_target(struct kvm_vcpu *vcpu, return kvm_reset_vcpu(vcpu); } +int kvm_vcpu_preferred_target(struct kvm_vcpu_init *init) +{ + int target = kvm_target_cpu(); + + if (target < 0) + return -ENODEV; + + memset(init, 0, sizeof(*init)); + + /* + * For now, we don't return any features. + * In future, we might use features to return target + * specific features available for the preferred + * target type. + */ + init->target = (__u32)target; + + return 0; +} + int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) { return -EINVAL; diff --git a/arch/arm/kvm/handle_exit.c b/arch/arm/kvm/handle_exit.c index df4c82d47ad7..a92079011a83 100644 --- a/arch/arm/kvm/handle_exit.c +++ b/arch/arm/kvm/handle_exit.c @@ -73,23 +73,29 @@ static int handle_dabt_hyp(struct kvm_vcpu *vcpu, struct kvm_run *run) } /** - * kvm_handle_wfi - handle a wait-for-interrupts instruction executed by a guest + * kvm_handle_wfx - handle a WFI or WFE instructions trapped in guests * @vcpu: the vcpu pointer * @run: the kvm_run structure pointer * - * Simply sets the wait_for_interrupts flag on the vcpu structure, which will - * halt execution of world-switches and schedule other host processes until - * there is an incoming IRQ or FIQ to the VM. + * WFE: Yield the CPU and come back to this vcpu when the scheduler + * decides to. + * WFI: Simply call kvm_vcpu_block(), which will halt execution of + * world-switches and schedule other host processes until there is an + * incoming IRQ or FIQ to the VM. */ -static int kvm_handle_wfi(struct kvm_vcpu *vcpu, struct kvm_run *run) +static int kvm_handle_wfx(struct kvm_vcpu *vcpu, struct kvm_run *run) { trace_kvm_wfi(*vcpu_pc(vcpu)); - kvm_vcpu_block(vcpu); + if (kvm_vcpu_get_hsr(vcpu) & HSR_WFI_IS_WFE) + kvm_vcpu_on_spin(vcpu); + else + kvm_vcpu_block(vcpu); + return 1; } static exit_handle_fn arm_exit_handlers[] = { - [HSR_EC_WFI] = kvm_handle_wfi, + [HSR_EC_WFI] = kvm_handle_wfx, [HSR_EC_CP15_32] = kvm_handle_cp15_32, [HSR_EC_CP15_64] = kvm_handle_cp15_64, [HSR_EC_CP14_MR] = kvm_handle_cp14_access, diff --git a/arch/arm/kvm/mmio.c b/arch/arm/kvm/mmio.c index 0c25d9487d53..4cb5a93182e9 100644 --- a/arch/arm/kvm/mmio.c +++ b/arch/arm/kvm/mmio.c @@ -23,6 +23,68 @@ #include "trace.h" +static void mmio_write_buf(char *buf, unsigned int len, unsigned long data) +{ + void *datap = NULL; + union { + u8 byte; + u16 hword; + u32 word; + u64 dword; + } tmp; + + switch (len) { + case 1: + tmp.byte = data; + datap = &tmp.byte; + break; + case 2: + tmp.hword = data; + datap = &tmp.hword; + break; + case 4: + tmp.word = data; + datap = &tmp.word; + break; + case 8: + tmp.dword = data; + datap = &tmp.dword; + break; + } + + memcpy(buf, datap, len); +} + +static unsigned long mmio_read_buf(char *buf, unsigned int len) +{ + unsigned long data = 0; + union { + u16 hword; + u32 word; + u64 dword; + } tmp; + + switch (len) { + case 1: + data = buf[0]; + break; + case 2: + memcpy(&tmp.hword, buf, len); + data = tmp.hword; + break; + case 4: + memcpy(&tmp.word, buf, len); + data = tmp.word; + break; + case 8: + memcpy(&tmp.dword, buf, len); + data = tmp.dword; + break; + } + + return data; +} + /** * kvm_handle_mmio_return -- Handle MMIO loads after user space emulation * @vcpu: The VCPU pointer @@ -33,28 +95,27 @@ */ int kvm_handle_mmio_return(struct kvm_vcpu *vcpu, struct kvm_run *run) { - unsigned long *dest; + unsigned long data; unsigned int len; int mask; if (!run->mmio.is_write) { - dest = vcpu_reg(vcpu, vcpu->arch.mmio_decode.rt); - *dest = 0; - len = run->mmio.len; if (len > sizeof(unsigned long)) return -EINVAL; - memcpy(dest, run->mmio.data, len); - - trace_kvm_mmio(KVM_TRACE_MMIO_READ, len, run->mmio.phys_addr, - *((u64 *)run->mmio.data)); + data = mmio_read_buf(run->mmio.data, len); if (vcpu->arch.mmio_decode.sign_extend && len < sizeof(unsigned long)) { mask = 1U << ((len * 8) - 1); - *dest = (*dest ^ mask) - mask; + data = (data ^ mask) - mask; } + + trace_kvm_mmio(KVM_TRACE_MMIO_READ, len, run->mmio.phys_addr, + data); + data = vcpu_data_host_to_guest(vcpu, data, len); + *vcpu_reg(vcpu, vcpu->arch.mmio_decode.rt) = data; } return 0; @@ -105,6 +166,7 @@ int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run *run, phys_addr_t fault_ipa) { struct kvm_exit_mmio mmio; + unsigned long data; unsigned long rt; int ret; @@ -125,13 +187,15 @@ int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run *run, } rt = vcpu->arch.mmio_decode.rt; + data = vcpu_data_guest_to_host(vcpu, *vcpu_reg(vcpu, rt), mmio.len); + trace_kvm_mmio((mmio.is_write) ? KVM_TRACE_MMIO_WRITE : KVM_TRACE_MMIO_READ_UNSATISFIED, mmio.len, fault_ipa, - (mmio.is_write) ? *vcpu_reg(vcpu, rt) : 0); + (mmio.is_write) ? data : 0); if (mmio.is_write) - memcpy(mmio.data, vcpu_reg(vcpu, rt), mmio.len); + mmio_write_buf(mmio.data, mmio.len, data); if (vgic_handle_mmio(vcpu, run, &mmio)) return 1; diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c index b0de86b56c13..371958370de4 100644 --- a/arch/arm/kvm/mmu.c +++ b/arch/arm/kvm/mmu.c @@ -19,6 +19,7 @@ #include <linux/mman.h> #include <linux/kvm_host.h> #include <linux/io.h> +#include <linux/hugetlb.h> #include <trace/events/kvm.h> #include <asm/pgalloc.h> #include <asm/cacheflush.h> @@ -41,6 +42,8 @@ static unsigned long hyp_idmap_start; static unsigned long hyp_idmap_end; static phys_addr_t hyp_idmap_vector; +#define kvm_pmd_huge(_x) (pmd_huge(_x) || pmd_trans_huge(_x)) + static void kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa) { /* @@ -93,19 +96,29 @@ static bool page_empty(void *ptr) static void clear_pud_entry(struct kvm *kvm, pud_t *pud, phys_addr_t addr) { - pmd_t *pmd_table = pmd_offset(pud, 0); - pud_clear(pud); - kvm_tlb_flush_vmid_ipa(kvm, addr); - pmd_free(NULL, pmd_table); + if (pud_huge(*pud)) { + pud_clear(pud); + kvm_tlb_flush_vmid_ipa(kvm, addr); + } else { + pmd_t *pmd_table = pmd_offset(pud, 0); + pud_clear(pud); + kvm_tlb_flush_vmid_ipa(kvm, addr); + pmd_free(NULL, pmd_table); + } put_page(virt_to_page(pud)); } static void clear_pmd_entry(struct kvm *kvm, pmd_t *pmd, phys_addr_t addr) { - pte_t *pte_table = pte_offset_kernel(pmd, 0); - pmd_clear(pmd); - kvm_tlb_flush_vmid_ipa(kvm, addr); - pte_free_kernel(NULL, pte_table); + if (kvm_pmd_huge(*pmd)) { + pmd_clear(pmd); + kvm_tlb_flush_vmid_ipa(kvm, addr); + } else { + pte_t *pte_table = pte_offset_kernel(pmd, 0); + pmd_clear(pmd); + kvm_tlb_flush_vmid_ipa(kvm, addr); + pte_free_kernel(NULL, pte_table); + } put_page(virt_to_page(pmd)); } @@ -136,18 +149,32 @@ static void unmap_range(struct kvm *kvm, pgd_t *pgdp, continue; } + if (pud_huge(*pud)) { + /* + * If we are dealing with a huge pud, just clear it and + * move on. + */ + clear_pud_entry(kvm, pud, addr); + addr = pud_addr_end(addr, end); + continue; + } + pmd = pmd_offset(pud, addr); if (pmd_none(*pmd)) { addr = pmd_addr_end(addr, end); continue; } - pte = pte_offset_kernel(pmd, addr); - clear_pte_entry(kvm, pte, addr); - next = addr + PAGE_SIZE; + if (!kvm_pmd_huge(*pmd)) { + pte = pte_offset_kernel(pmd, addr); + clear_pte_entry(kvm, pte, addr); + next = addr + PAGE_SIZE; + } - /* If we emptied the pte, walk back up the ladder */ - if (page_empty(pte)) { + /* + * If the pmd entry is to be cleared, walk back up the ladder + */ + if (kvm_pmd_huge(*pmd) || page_empty(pte)) { clear_pmd_entry(kvm, pmd, addr); next = pmd_addr_end(addr, end); if (page_empty(pmd) && !page_empty(pud)) { @@ -420,29 +447,71 @@ void kvm_free_stage2_pgd(struct kvm *kvm) kvm->arch.pgd = NULL; } - -static int stage2_set_pte(struct kvm *kvm, struct kvm_mmu_memory_cache *cache, - phys_addr_t addr, const pte_t *new_pte, bool iomap) +static pmd_t *stage2_get_pmd(struct kvm *kvm, struct kvm_mmu_memory_cache *cache, + phys_addr_t addr) { pgd_t *pgd; pud_t *pud; pmd_t *pmd; - pte_t *pte, old_pte; - /* Create 2nd stage page table mapping - Level 1 */ pgd = kvm->arch.pgd + pgd_index(addr); pud = pud_offset(pgd, addr); if (pud_none(*pud)) { if (!cache) - return 0; /* ignore calls from kvm_set_spte_hva */ + return NULL; pmd = mmu_memory_cache_alloc(cache); pud_populate(NULL, pud, pmd); get_page(virt_to_page(pud)); } - pmd = pmd_offset(pud, addr); + return pmd_offset(pud, addr); +} + +static int stage2_set_pmd_huge(struct kvm *kvm, struct kvm_mmu_memory_cache + *cache, phys_addr_t addr, const pmd_t *new_pmd) +{ + pmd_t *pmd, old_pmd; + + pmd = stage2_get_pmd(kvm, cache, addr); + VM_BUG_ON(!pmd); + + /* + * Mapping in huge pages should only happen through a fault. If a + * page is merged into a transparent huge page, the individual + * subpages of that huge page should be unmapped through MMU + * notifiers before we get here. + * + * Merging of CompoundPages is not supported; they should become + * splitting first, unmapped, merged, and mapped back in on-demand. + */ + VM_BUG_ON(pmd_present(*pmd) && pmd_pfn(*pmd) != pmd_pfn(*new_pmd)); + + old_pmd = *pmd; + kvm_set_pmd(pmd, *new_pmd); + if (pmd_present(old_pmd)) + kvm_tlb_flush_vmid_ipa(kvm, addr); + else + get_page(virt_to_page(pmd)); + return 0; +} + +static int stage2_set_pte(struct kvm *kvm, struct kvm_mmu_memory_cache *cache, + phys_addr_t addr, const pte_t *new_pte, bool iomap) +{ + pmd_t *pmd; + pte_t *pte, old_pte; - /* Create 2nd stage page table mapping - Level 2 */ + /* Create stage-2 page table mapping - Level 1 */ + pmd = stage2_get_pmd(kvm, cache, addr); + if (!pmd) { + /* + * Ignore calls from kvm_set_spte_hva for unallocated + * address ranges. + */ + return 0; + } + + /* Create stage-2 page mappings - Level 2 */ if (pmd_none(*pmd)) { if (!cache) return 0; /* ignore calls from kvm_set_spte_hva */ @@ -507,16 +576,60 @@ out: return ret; } +static bool transparent_hugepage_adjust(pfn_t *pfnp, phys_addr_t *ipap) +{ + pfn_t pfn = *pfnp; + gfn_t gfn = *ipap >> PAGE_SHIFT; + + if (PageTransCompound(pfn_to_page(pfn))) { + unsigned long mask; + /* + * The address we faulted on is backed by a transparent huge + * page. However, because we map the compound huge page and + * not the individual tail page, we need to transfer the + * refcount to the head page. We have to be careful that the + * THP doesn't start to split while we are adjusting the + * refcounts. + * + * We are sure this doesn't happen, because mmu_notifier_retry + * was successful and we are holding the mmu_lock, so if this + * THP is trying to split, it will be blocked in the mmu + * notifier before touching any of the pages, specifically + * before being able to call __split_huge_page_refcount(). + * + * We can therefore safely transfer the refcount from PG_tail + * to PG_head and switch the pfn from a tail page to the head + * page accordingly. + */ + mask = PTRS_PER_PMD - 1; + VM_BUG_ON((gfn & mask) != (pfn & mask)); + if (pfn & mask) { + *ipap &= PMD_MASK; + kvm_release_pfn_clean(pfn); + pfn &= ~mask; + kvm_get_pfn(pfn); + *pfnp = pfn; + } + + return true; + } + + return false; +} + static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, - gfn_t gfn, struct kvm_memory_slot *memslot, + struct kvm_memory_slot *memslot, unsigned long fault_status) { - pte_t new_pte; - pfn_t pfn; int ret; - bool write_fault, writable; + bool write_fault, writable, hugetlb = false, force_pte = false; unsigned long mmu_seq; + gfn_t gfn = fault_ipa >> PAGE_SHIFT; + unsigned long hva = gfn_to_hva(vcpu->kvm, gfn); + struct kvm *kvm = vcpu->kvm; struct kvm_mmu_memory_cache *memcache = &vcpu->arch.mmu_page_cache; + struct vm_area_struct *vma; + pfn_t pfn; write_fault = kvm_is_write_fault(kvm_vcpu_get_hsr(vcpu)); if (fault_status == FSC_PERM && !write_fault) { @@ -524,6 +637,26 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, return -EFAULT; } + /* Let's check if we will get back a huge page backed by hugetlbfs */ + down_read(¤t->mm->mmap_sem); + vma = find_vma_intersection(current->mm, hva, hva + 1); + if (is_vm_hugetlb_page(vma)) { + hugetlb = true; + gfn = (fault_ipa & PMD_MASK) >> PAGE_SHIFT; + } else { + /* + * Pages belonging to VMAs not aligned to the PMD mapping + * granularity cannot be mapped using block descriptors even + * if the pages belong to a THP for the process, because the + * stage-2 block descriptor will cover more than a single THP + * and we loose atomicity for unmapping, updates, and splits + * of the THP or other pages in the stage-2 block range. + */ + if (vma->vm_start & ~PMD_MASK) + force_pte = true; + } + up_read(¤t->mm->mmap_sem); + /* We need minimum second+third level pages */ ret = mmu_topup_memory_cache(memcache, 2, KVM_NR_MEM_OBJS); if (ret) @@ -541,26 +674,40 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, */ smp_rmb(); - pfn = gfn_to_pfn_prot(vcpu->kvm, gfn, write_fault, &writable); + pfn = gfn_to_pfn_prot(kvm, gfn, write_fault, &writable); if (is_error_pfn(pfn)) return -EFAULT; - new_pte = pfn_pte(pfn, PAGE_S2); - coherent_icache_guest_page(vcpu->kvm, gfn); - - spin_lock(&vcpu->kvm->mmu_lock); - if (mmu_notifier_retry(vcpu->kvm, mmu_seq)) + spin_lock(&kvm->mmu_lock); + if (mmu_notifier_retry(kvm, mmu_seq)) goto out_unlock; - if (writable) { - kvm_set_s2pte_writable(&new_pte); - kvm_set_pfn_dirty(pfn); + if (!hugetlb && !force_pte) + hugetlb = transparent_hugepage_adjust(&pfn, &fault_ipa); + + if (hugetlb) { + pmd_t new_pmd = pfn_pmd(pfn, PAGE_S2); + new_pmd = pmd_mkhuge(new_pmd); + if (writable) { + kvm_set_s2pmd_writable(&new_pmd); + kvm_set_pfn_dirty(pfn); + } + coherent_icache_guest_page(kvm, hva & PMD_MASK, PMD_SIZE); + ret = stage2_set_pmd_huge(kvm, memcache, fault_ipa, &new_pmd); + } else { + pte_t new_pte = pfn_pte(pfn, PAGE_S2); + if (writable) { + kvm_set_s2pte_writable(&new_pte); + kvm_set_pfn_dirty(pfn); + } + coherent_icache_guest_page(kvm, hva, PAGE_SIZE); + ret = stage2_set_pte(kvm, memcache, fault_ipa, &new_pte, false); } - stage2_set_pte(vcpu->kvm, memcache, fault_ipa, &new_pte, false); + out_unlock: - spin_unlock(&vcpu->kvm->mmu_lock); + spin_unlock(&kvm->mmu_lock); kvm_release_pfn_clean(pfn); - return 0; + return ret; } /** @@ -629,7 +776,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run) memslot = gfn_to_memslot(vcpu->kvm, gfn); - ret = user_mem_abort(vcpu, fault_ipa, gfn, memslot, fault_status); + ret = user_mem_abort(vcpu, fault_ipa, memslot, fault_status); if (ret == 0) ret = 1; out_unlock: diff --git a/arch/arm/kvm/psci.c b/arch/arm/kvm/psci.c index 86a693a02ba3..0881bf169fbc 100644 --- a/arch/arm/kvm/psci.c +++ b/arch/arm/kvm/psci.c @@ -18,6 +18,7 @@ #include <linux/kvm_host.h> #include <linux/wait.h> +#include <asm/cputype.h> #include <asm/kvm_emulate.h> #include <asm/kvm_psci.h> @@ -34,22 +35,30 @@ static void kvm_psci_vcpu_off(struct kvm_vcpu *vcpu) static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu) { struct kvm *kvm = source_vcpu->kvm; - struct kvm_vcpu *vcpu; + struct kvm_vcpu *vcpu = NULL, *tmp; wait_queue_head_t *wq; unsigned long cpu_id; + unsigned long mpidr; phys_addr_t target_pc; + int i; cpu_id = *vcpu_reg(source_vcpu, 1); if (vcpu_mode_is_32bit(source_vcpu)) cpu_id &= ~((u32) 0); - if (cpu_id >= atomic_read(&kvm->online_vcpus)) + kvm_for_each_vcpu(i, tmp, kvm) { + mpidr = kvm_vcpu_get_mpidr(tmp); + if ((mpidr & MPIDR_HWID_BITMASK) == (cpu_id & MPIDR_HWID_BITMASK)) { + vcpu = tmp; + break; + } + } + + if (!vcpu) return KVM_PSCI_RET_INVAL; target_pc = *vcpu_reg(source_vcpu, 2); - vcpu = kvm_get_vcpu(kvm, cpu_id); - wq = kvm_arch_vcpu_wq(vcpu); if (!waitqueue_active(wq)) return KVM_PSCI_RET_INVAL; @@ -62,6 +71,10 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu) vcpu_set_thumb(vcpu); } + /* Propagate caller endianness */ + if (kvm_vcpu_is_be(source_vcpu)) + kvm_vcpu_set_be(vcpu); + *vcpu_pc(vcpu) = target_pc; vcpu->arch.pause = false; smp_mb(); /* Make sure the above is visible */ diff --git a/arch/arm/kvm/reset.c b/arch/arm/kvm/reset.c index c02ba4af599f..f558c073c023 100644 --- a/arch/arm/kvm/reset.c +++ b/arch/arm/kvm/reset.c @@ -30,16 +30,14 @@ #include <kvm/arm_arch_timer.h> /****************************************************************************** - * Cortex-A15 Reset Values + * Cortex-A15 and Cortex-A7 Reset Values */ -static const int a15_max_cpu_idx = 3; - -static struct kvm_regs a15_regs_reset = { +static struct kvm_regs cortexa_regs_reset = { .usr_regs.ARM_cpsr = SVC_MODE | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT, }; -static const struct kvm_irq_level a15_vtimer_irq = { +static const struct kvm_irq_level cortexa_vtimer_irq = { { .irq = 27 }, .level = 1, }; @@ -62,12 +60,11 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu) const struct kvm_irq_level *cpu_vtimer_irq; switch (vcpu->arch.target) { + case KVM_ARM_TARGET_CORTEX_A7: case KVM_ARM_TARGET_CORTEX_A15: - if (vcpu->vcpu_id > a15_max_cpu_idx) - return -EINVAL; - reset_regs = &a15_regs_reset; + reset_regs = &cortexa_regs_reset; vcpu->arch.midr = read_cpuid_id(); - cpu_vtimer_irq = &a15_vtimer_irq; + cpu_vtimer_irq = &cortexa_vtimer_irq; break; default: return -ENODEV; diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index bd454b09133e..47d7338561de 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -41,7 +41,6 @@ else endif lib-$(CONFIG_ARCH_RPC) += ecard.o io-acorn.o floppydma.o -lib-$(CONFIG_ARCH_SHARK) += io-shark.o $(obj)/csumpartialcopy.o: $(obj)/csumpartialcopygeneric.S $(obj)/csumpartialcopyuser.o: $(obj)/csumpartialcopygeneric.S diff --git a/arch/arm/lib/bitops.h b/arch/arm/lib/bitops.h index d6408d1ee543..e0c68d5bb7dc 100644 --- a/arch/arm/lib/bitops.h +++ b/arch/arm/lib/bitops.h @@ -10,6 +10,11 @@ UNWIND( .fnstart ) and r3, r0, #31 @ Get bit offset mov r0, r0, lsr #5 add r1, r1, r0, lsl #2 @ Get word offset +#if __LINUX_ARM_ARCH__ >= 7 + .arch_extension mp + ALT_SMP(W(pldw) [r1]) + ALT_UP(W(nop)) +#endif mov r3, r2, lsl r3 1: ldrex r2, [r1] \instr r2, r2, r3 diff --git a/arch/arm/lib/io-shark.c b/arch/arm/lib/io-shark.c deleted file mode 100644 index 824253948f51..000000000000 --- a/arch/arm/lib/io-shark.c +++ /dev/null @@ -1,13 +0,0 @@ -/* - * linux/arch/arm/lib/io-shark.c - * - * by Alexander Schulz - * - * derived from: - * linux/arch/arm/lib/io-ebsa.S - * Copyright (C) 1995, 1996 Russell King - * - * 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. - */ diff --git a/arch/arm/lib/uaccess_with_memcpy.c b/arch/arm/lib/uaccess_with_memcpy.c index 025f742dd4df..3e58d710013c 100644 --- a/arch/arm/lib/uaccess_with_memcpy.c +++ b/arch/arm/lib/uaccess_with_memcpy.c @@ -18,6 +18,7 @@ #include <linux/hardirq.h> /* for in_atomic() */ #include <linux/gfp.h> #include <linux/highmem.h> +#include <linux/hugetlb.h> #include <asm/current.h> #include <asm/page.h> @@ -40,7 +41,35 @@ pin_page_for_write(const void __user *_addr, pte_t **ptep, spinlock_t **ptlp) return 0; pmd = pmd_offset(pud, addr); - if (unlikely(pmd_none(*pmd) || pmd_bad(*pmd))) + if (unlikely(pmd_none(*pmd))) + return 0; + + /* + * A pmd can be bad if it refers to a HugeTLB or THP page. + * + * Both THP and HugeTLB pages have the same pmd layout + * and should not be manipulated by the pte functions. + * + * Lock the page table for the destination and check + * to see that it's still huge and whether or not we will + * need to fault on write, or if we have a splitting THP. + */ + if (unlikely(pmd_thp_or_huge(*pmd))) { + ptl = ¤t->mm->page_table_lock; + spin_lock(ptl); + if (unlikely(!pmd_thp_or_huge(*pmd) + || pmd_hugewillfault(*pmd) + || pmd_trans_splitting(*pmd))) { + spin_unlock(ptl); + return 0; + } + + *ptep = NULL; + *ptlp = ptl; + return 1; + } + + if (unlikely(pmd_bad(*pmd))) return 0; pte = pte_offset_map_lock(current->mm, pmd, addr, &ptl); @@ -94,7 +123,10 @@ __copy_to_user_memcpy(void __user *to, const void *from, unsigned long n) from += tocopy; n -= tocopy; - pte_unmap_unlock(pte, ptl); + if (pte) + pte_unmap_unlock(pte, ptl); + else + spin_unlock(ptl); } if (!atomic) up_read(¤t->mm->mmap_sem); @@ -147,7 +179,10 @@ __clear_user_memset(void __user *addr, unsigned long n) addr += tocopy; n -= tocopy; - pte_unmap_unlock(pte, ptl); + if (pte) + pte_unmap_unlock(pte, ptl); + else + spin_unlock(ptl); } up_read(¤t->mm->mmap_sem); diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index 3b0a9538093c..90aab2d5a07f 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile @@ -2,7 +2,7 @@ # Makefile for the linux kernel. # -obj-y := irq.o gpio.o setup.o +obj-y := irq.o gpio.o setup.o sysirq_mask.o obj-m := obj-n := obj- := @@ -98,7 +98,6 @@ obj-y += leds.o # Power Management obj-$(CONFIG_PM) += pm.o obj-$(CONFIG_AT91_SLOW_CLOCK) += pm_slowclock.o -obj-$(CONFIG_CPU_IDLE) += cpuidle.o ifeq ($(CONFIG_PM_DEBUG),y) CFLAGS_pm.o += -DDEBUG diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c index 4aad93d54d6f..25805f2f6010 100644 --- a/arch/arm/mach-at91/at91rm9200.c +++ b/arch/arm/mach-at91/at91rm9200.c @@ -27,6 +27,7 @@ #include "generic.h" #include "clock.h" #include "sam9_smc.h" +#include "pm.h" /* -------------------------------------------------------------------- * Clocks @@ -327,6 +328,7 @@ static void __init at91rm9200_ioremap_registers(void) { at91rm9200_ioremap_st(AT91RM9200_BASE_ST); at91_ioremap_ramc(0, AT91RM9200_BASE_MC, 256); + at91_pm_set_standby(at91rm9200_standby); } static void __init at91rm9200_initialize(void) diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c index 5de6074b4f4f..d6a1fa85371d 100644 --- a/arch/arm/mach-at91/at91sam9260.c +++ b/arch/arm/mach-at91/at91sam9260.c @@ -28,6 +28,7 @@ #include "generic.h" #include "clock.h" #include "sam9_smc.h" +#include "pm.h" /* -------------------------------------------------------------------- * Clocks @@ -342,6 +343,7 @@ static void __init at91sam9260_ioremap_registers(void) at91sam926x_ioremap_pit(AT91SAM9260_BASE_PIT); at91sam9_ioremap_smc(0, AT91SAM9260_BASE_SMC); at91_ioremap_matrix(AT91SAM9260_BASE_MATRIX); + at91_pm_set_standby(at91sam9_sdram_standby); } static void __init at91sam9260_initialize(void) @@ -349,6 +351,8 @@ static void __init at91sam9260_initialize(void) arm_pm_idle = at91sam9_idle; arm_pm_restart = at91sam9_alt_restart; + at91_sysirq_mask_rtt(AT91SAM9260_BASE_RTT); + /* Register GPIO subsystem */ at91_gpio_init(at91sam9260_gpio, 3); } diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c index 0e0793241ab7..23ba1d8a1531 100644 --- a/arch/arm/mach-at91/at91sam9261.c +++ b/arch/arm/mach-at91/at91sam9261.c @@ -27,6 +27,7 @@ #include "generic.h" #include "clock.h" #include "sam9_smc.h" +#include "pm.h" /* -------------------------------------------------------------------- * Clocks @@ -284,6 +285,7 @@ static void __init at91sam9261_ioremap_registers(void) at91sam926x_ioremap_pit(AT91SAM9261_BASE_PIT); at91sam9_ioremap_smc(0, AT91SAM9261_BASE_SMC); at91_ioremap_matrix(AT91SAM9261_BASE_MATRIX); + at91_pm_set_standby(at91sam9_sdram_standby); } static void __init at91sam9261_initialize(void) @@ -291,6 +293,8 @@ static void __init at91sam9261_initialize(void) arm_pm_idle = at91sam9_idle; arm_pm_restart = at91sam9_alt_restart; + at91_sysirq_mask_rtt(AT91SAM9261_BASE_RTT); + /* Register GPIO subsystem */ at91_gpio_init(at91sam9261_gpio, 3); } diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c index 629ea5fc95cf..b2a34740146a 100644 --- a/arch/arm/mach-at91/at91sam9261_devices.c +++ b/arch/arm/mach-at91/at91sam9261_devices.c @@ -465,7 +465,7 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) #if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) static u64 lcdc_dmamask = DMA_BIT_MASK(32); -static struct atmel_lcdfb_info lcdc_data; +static struct atmel_lcdfb_pdata lcdc_data; static struct resource lcdc_resources[] = { [0] = { @@ -498,7 +498,7 @@ static struct platform_device at91_lcdc_device = { .num_resources = ARRAY_SIZE(lcdc_resources), }; -void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) +void __init at91_add_device_lcdc(struct atmel_lcdfb_pdata *data) { if (!data) { return; @@ -559,7 +559,7 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) platform_device_register(&at91_lcdc_device); } #else -void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {} +void __init at91_add_device_lcdc(struct atmel_lcdfb_pdata *data) {} #endif diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c index 6ce7d1850893..7eccb0fc57bc 100644 --- a/arch/arm/mach-at91/at91sam9263.c +++ b/arch/arm/mach-at91/at91sam9263.c @@ -26,6 +26,7 @@ #include "generic.h" #include "clock.h" #include "sam9_smc.h" +#include "pm.h" /* -------------------------------------------------------------------- * Clocks @@ -321,6 +322,7 @@ static void __init at91sam9263_ioremap_registers(void) at91sam9_ioremap_smc(0, AT91SAM9263_BASE_SMC0); at91sam9_ioremap_smc(1, AT91SAM9263_BASE_SMC1); at91_ioremap_matrix(AT91SAM9263_BASE_MATRIX); + at91_pm_set_standby(at91sam9_sdram_standby); } static void __init at91sam9263_initialize(void) @@ -328,6 +330,9 @@ static void __init at91sam9263_initialize(void) arm_pm_idle = at91sam9_idle; arm_pm_restart = at91sam9_alt_restart; + at91_sysirq_mask_rtt(AT91SAM9263_BASE_RTT0); + at91_sysirq_mask_rtt(AT91SAM9263_BASE_RTT1); + /* Register GPIO subsystem */ at91_gpio_init(at91sam9263_gpio, 5); } diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c index 858c8aac2daf..4aeadddbc181 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c @@ -832,7 +832,7 @@ void __init at91_add_device_can(struct at91_can_data *data) {} #if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) static u64 lcdc_dmamask = DMA_BIT_MASK(32); -static struct atmel_lcdfb_info lcdc_data; +static struct atmel_lcdfb_pdata lcdc_data; static struct resource lcdc_resources[] = { [0] = { @@ -859,7 +859,7 @@ static struct platform_device at91_lcdc_device = { .num_resources = ARRAY_SIZE(lcdc_resources), }; -void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) +void __init at91_add_device_lcdc(struct atmel_lcdfb_pdata *data) { if (!data) return; @@ -891,7 +891,7 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) platform_device_register(&at91_lcdc_device); } #else -void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {} +void __init at91_add_device_lcdc(struct atmel_lcdfb_pdata *data) {} #endif diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index 474ee04d24b9..9405aa08b104 100644 --- a/arch/arm/mach-at91/at91sam9g45.c +++ b/arch/arm/mach-at91/at91sam9g45.c @@ -26,6 +26,7 @@ #include "generic.h" #include "clock.h" #include "sam9_smc.h" +#include "pm.h" /* -------------------------------------------------------------------- * Clocks @@ -370,6 +371,7 @@ static void __init at91sam9g45_ioremap_registers(void) at91sam926x_ioremap_pit(AT91SAM9G45_BASE_PIT); at91sam9_ioremap_smc(0, AT91SAM9G45_BASE_SMC); at91_ioremap_matrix(AT91SAM9G45_BASE_MATRIX); + at91_pm_set_standby(at91_ddr_standby); } static void __init at91sam9g45_initialize(void) @@ -377,6 +379,9 @@ static void __init at91sam9g45_initialize(void) arm_pm_idle = at91sam9_idle; arm_pm_restart = at91sam9g45_restart; + at91_sysirq_mask_rtc(AT91SAM9G45_BASE_RTC); + at91_sysirq_mask_rtt(AT91SAM9G45_BASE_RTT); + /* Register GPIO subsystem */ at91_gpio_init(at91sam9g45_gpio, 5); } diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index acb703e13331..cb36fa872d30 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c @@ -965,7 +965,7 @@ void __init at91_add_device_isi(struct isi_platform_data *data, #if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) static u64 lcdc_dmamask = DMA_BIT_MASK(32); -static struct atmel_lcdfb_info lcdc_data; +static struct atmel_lcdfb_pdata lcdc_data; static struct resource lcdc_resources[] = { [0] = { @@ -991,7 +991,7 @@ static struct platform_device at91_lcdc_device = { .num_resources = ARRAY_SIZE(lcdc_resources), }; -void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) +void __init at91_add_device_lcdc(struct atmel_lcdfb_pdata *data) { if (!data) return; @@ -1037,7 +1037,7 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) platform_device_register(&at91_lcdc_device); } #else -void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {} +void __init at91_add_device_lcdc(struct atmel_lcdfb_pdata *data) {} #endif diff --git a/arch/arm/mach-at91/at91sam9n12.c b/arch/arm/mach-at91/at91sam9n12.c index c7d670d11802..388ec3aec4b9 100644 --- a/arch/arm/mach-at91/at91sam9n12.c +++ b/arch/arm/mach-at91/at91sam9n12.c @@ -169,6 +169,7 @@ static struct clk_lookup periph_clocks_lookups[] = { 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(NULL, "f0010000.ssc", &ssc_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), @@ -223,7 +224,13 @@ static void __init at91sam9n12_map_io(void) at91_init_sram(0, AT91SAM9N12_SRAM_BASE, AT91SAM9N12_SRAM_SIZE); } +static void __init at91sam9n12_initialize(void) +{ + at91_sysirq_mask_rtc(AT91SAM9N12_BASE_RTC); +} + AT91_SOC_START(at91sam9n12) .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 d4ec0d9a9872..0750ffb7e6b1 100644 --- a/arch/arm/mach-at91/at91sam9rl.c +++ b/arch/arm/mach-at91/at91sam9rl.c @@ -27,6 +27,7 @@ #include "generic.h" #include "clock.h" #include "sam9_smc.h" +#include "pm.h" /* -------------------------------------------------------------------- * Clocks @@ -287,6 +288,7 @@ static void __init at91sam9rl_ioremap_registers(void) at91sam926x_ioremap_pit(AT91SAM9RL_BASE_PIT); at91sam9_ioremap_smc(0, AT91SAM9RL_BASE_SMC); at91_ioremap_matrix(AT91SAM9RL_BASE_MATRIX); + at91_pm_set_standby(at91sam9_sdram_standby); } static void __init at91sam9rl_initialize(void) @@ -294,6 +296,9 @@ static void __init at91sam9rl_initialize(void) arm_pm_idle = at91sam9_idle; arm_pm_restart = at91sam9_alt_restart; + at91_sysirq_mask_rtc(AT91SAM9RL_BASE_RTC); + at91_sysirq_mask_rtt(AT91SAM9RL_BASE_RTT); + /* Register GPIO subsystem */ at91_gpio_init(at91sam9rl_gpio, 4); } diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c index 352468f265a9..a698bdab2cce 100644 --- a/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/arch/arm/mach-at91/at91sam9rl_devices.c @@ -498,7 +498,7 @@ void __init at91_add_device_ac97(struct ac97c_platform_data *data) {} #if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) static u64 lcdc_dmamask = DMA_BIT_MASK(32); -static struct atmel_lcdfb_info lcdc_data; +static struct atmel_lcdfb_pdata lcdc_data; static struct resource lcdc_resources[] = { [0] = { @@ -525,7 +525,7 @@ static struct platform_device at91_lcdc_device = { .num_resources = ARRAY_SIZE(lcdc_resources), }; -void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) +void __init at91_add_device_lcdc(struct atmel_lcdfb_pdata *data) { if (!data) { return; @@ -557,7 +557,7 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) platform_device_register(&at91_lcdc_device); } #else -void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {} +void __init at91_add_device_lcdc(struct atmel_lcdfb_pdata *data) {} #endif diff --git a/arch/arm/mach-at91/at91sam9x5.c b/arch/arm/mach-at91/at91sam9x5.c index 916e5a142917..e8a2e075a1b8 100644 --- a/arch/arm/mach-at91/at91sam9x5.c +++ b/arch/arm/mach-at91/at91sam9x5.c @@ -322,6 +322,11 @@ static void __init at91sam9x5_map_io(void) at91_init_sram(0, AT91SAM9X5_SRAM_BASE, AT91SAM9X5_SRAM_SIZE); } +static void __init at91sam9x5_initialize(void) +{ + at91_sysirq_mask_rtc(AT91SAM9X5_BASE_RTC); +} + /* -------------------------------------------------------------------- * Interrupt initialization * -------------------------------------------------------------------- */ @@ -329,4 +334,5 @@ static void __init at91sam9x5_map_io(void) AT91_SOC_START(at91sam9x5) .map_io = at91sam9x5_map_io, .register_clocks = at91sam9x5_register_clocks, + .init = at91sam9x5_initialize, AT91_SOC_END diff --git a/arch/arm/mach-at91/board-cam60.c b/arch/arm/mach-at91/board-cam60.c index ade948b82662..112e867c4abe 100644 --- a/arch/arm/mach-at91/board-cam60.c +++ b/arch/arm/mach-at91/board-cam60.c @@ -112,7 +112,7 @@ static struct spi_board_info cam60_spi_devices[] __initdata = { /* * MACB Ethernet device */ -static struct __initdata macb_platform_data cam60_macb_data = { +static struct macb_platform_data cam60_macb_data __initdata = { .phy_irq_pin = AT91_PIN_PB5, .is_rmii = 0, }; diff --git a/arch/arm/mach-at91/board-dt-rm9200.c b/arch/arm/mach-at91/board-dt-rm9200.c index 3fcb6623a33e..3a185faee795 100644 --- a/arch/arm/mach-at91/board-dt-rm9200.c +++ b/arch/arm/mach-at91/board-dt-rm9200.c @@ -14,7 +14,6 @@ #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> @@ -36,11 +35,6 @@ 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 @@ -52,6 +46,5 @@ DT_MACHINE_START(at91rm9200_dt, "Atmel AT91RM9200 (Device Tree)") .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/board-dt-sam9.c b/arch/arm/mach-at91/board-dt-sam9.c index 8db30132abed..3dab868b02fa 100644 --- a/arch/arm/mach-at91/board-dt-sam9.c +++ b/arch/arm/mach-at91/board-dt-sam9.c @@ -13,7 +13,6 @@ #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> @@ -37,11 +36,6 @@ static void __init at91_dt_init_irq(void) of_irq_init(irq_of_match); } -static void __init at91_dt_device_init(void) -{ - of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); -} - static const char *at91_dt_board_compat[] __initdata = { "atmel,at91sam9", NULL @@ -54,6 +48,5 @@ DT_MACHINE_START(at91sam_dt, "Atmel AT91SAM (Device Tree)") .handle_irq = at91_aic_handle_irq, .init_early = at91_dt_initialize, .init_irq = at91_dt_init_irq, - .init_machine = at91_dt_device_init, .dt_compat = at91_dt_board_compat, MACHINE_END diff --git a/arch/arm/mach-at91/board-sam9260ek.c b/arch/arm/mach-at91/board-sam9260ek.c index 0b153c87521d..f4f8735315da 100644 --- a/arch/arm/mach-at91/board-sam9260ek.c +++ b/arch/arm/mach-at91/board-sam9260ek.c @@ -28,7 +28,7 @@ #include <linux/spi/spi.h> #include <linux/spi/at73c213.h> #include <linux/clk.h> -#include <linux/i2c/at24.h> +#include <linux/platform_data/at24.h> #include <linux/gpio_keys.h> #include <linux/input.h> diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c index d3437624ca4e..473546b9408b 100644 --- a/arch/arm/mach-at91/board-sam9261ek.c +++ b/arch/arm/mach-at91/board-sam9261ek.c @@ -389,7 +389,7 @@ static struct fb_monspecs at91fb_default_stn_monspecs = { | ATMEL_LCDC_IFWIDTH_4 \ | ATMEL_LCDC_SCANMOD_SINGLE) -static void at91_lcdc_stn_power_control(int on) +static void at91_lcdc_stn_power_control(struct atmel_lcdfb_pdata *pdata, int on) { /* backlight */ if (on) { /* power up */ @@ -401,7 +401,7 @@ static void at91_lcdc_stn_power_control(int on) } } -static struct atmel_lcdfb_info __initdata ek_lcdc_data = { +static struct atmel_lcdfb_pdata __initdata ek_lcdc_data = { .default_bpp = 1, .default_dmacon = ATMEL_LCDC_DMAEN, .default_lcdcon2 = AT91SAM9261_DEFAULT_STN_LCDCON2, @@ -445,7 +445,7 @@ static struct fb_monspecs at91fb_default_tft_monspecs = { | ATMEL_LCDC_DISTYPE_TFT \ | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE) -static void at91_lcdc_tft_power_control(int on) +static void at91_lcdc_tft_power_control(struct atmel_lcdfb_pdata *pdata, int on) { if (on) at91_set_gpio_value(AT91_PIN_PA12, 0); /* power up */ @@ -453,7 +453,7 @@ static void at91_lcdc_tft_power_control(int on) at91_set_gpio_value(AT91_PIN_PA12, 1); /* power down */ } -static struct atmel_lcdfb_info __initdata ek_lcdc_data = { +static struct atmel_lcdfb_pdata __initdata ek_lcdc_data = { .lcdcon_is_backlight = true, .default_bpp = 16, .default_dmacon = ATMEL_LCDC_DMAEN, @@ -465,7 +465,7 @@ static struct atmel_lcdfb_info __initdata ek_lcdc_data = { #endif #else -static struct atmel_lcdfb_info __initdata ek_lcdc_data; +static struct atmel_lcdfb_pdata __initdata ek_lcdc_data; #endif diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c index 3284df05df14..2f931915c80c 100644 --- a/arch/arm/mach-at91/board-sam9263ek.c +++ b/arch/arm/mach-at91/board-sam9263ek.c @@ -27,7 +27,7 @@ #include <linux/platform_device.h> #include <linux/spi/spi.h> #include <linux/spi/ads7846.h> -#include <linux/i2c/at24.h> +#include <linux/platform_data/at24.h> #include <linux/fb.h> #include <linux/gpio_keys.h> #include <linux/input.h> @@ -275,13 +275,13 @@ static struct fb_monspecs at91fb_default_monspecs = { | ATMEL_LCDC_DISTYPE_TFT \ | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE) -static void at91_lcdc_power_control(int on) +static void at91_lcdc_power_control(struct atmel_lcdfb_pdata *pdata, int on) { at91_set_gpio_value(AT91_PIN_PA30, on); } /* Driver datas */ -static struct atmel_lcdfb_info __initdata ek_lcdc_data = { +static struct atmel_lcdfb_pdata __initdata ek_lcdc_data = { .lcdcon_is_backlight = true, .default_bpp = 16, .default_dmacon = ATMEL_LCDC_DMAEN, @@ -292,7 +292,7 @@ static struct atmel_lcdfb_info __initdata ek_lcdc_data = { }; #else -static struct atmel_lcdfb_info __initdata ek_lcdc_data; +static struct atmel_lcdfb_pdata __initdata ek_lcdc_data; #endif diff --git a/arch/arm/mach-at91/board-sam9m10g45ek.c b/arch/arm/mach-at91/board-sam9m10g45ek.c index 2a94896a1375..ef39078c8ce2 100644 --- a/arch/arm/mach-at91/board-sam9m10g45ek.c +++ b/arch/arm/mach-at91/board-sam9m10g45ek.c @@ -284,7 +284,7 @@ static struct fb_monspecs at91fb_default_monspecs = { | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE) /* Driver datas */ -static struct atmel_lcdfb_info __initdata ek_lcdc_data = { +static struct atmel_lcdfb_pdata __initdata ek_lcdc_data = { .lcdcon_is_backlight = true, .default_bpp = 32, .default_dmacon = ATMEL_LCDC_DMAEN, @@ -295,7 +295,7 @@ static struct atmel_lcdfb_info __initdata ek_lcdc_data = { }; #else -static struct atmel_lcdfb_info __initdata ek_lcdc_data; +static struct atmel_lcdfb_pdata __initdata ek_lcdc_data; #endif diff --git a/arch/arm/mach-at91/board-sam9rlek.c b/arch/arm/mach-at91/board-sam9rlek.c index aa265dcf2128..604eecf6cd70 100644 --- a/arch/arm/mach-at91/board-sam9rlek.c +++ b/arch/arm/mach-at91/board-sam9rlek.c @@ -170,7 +170,7 @@ static struct fb_monspecs at91fb_default_monspecs = { | ATMEL_LCDC_DISTYPE_TFT \ | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE) -static void at91_lcdc_power_control(int on) +static void at91_lcdc_power_control(struct atmel_lcdfb_pdata *pdata, int on) { if (on) at91_set_gpio_value(AT91_PIN_PC1, 0); /* power up */ @@ -179,7 +179,7 @@ static void at91_lcdc_power_control(int on) } /* Driver datas */ -static struct atmel_lcdfb_info __initdata ek_lcdc_data = { +static struct atmel_lcdfb_pdata __initdata ek_lcdc_data = { .lcdcon_is_backlight = true, .default_bpp = 16, .default_dmacon = ATMEL_LCDC_DMAEN, @@ -191,7 +191,7 @@ static struct atmel_lcdfb_info __initdata ek_lcdc_data = { }; #else -static struct atmel_lcdfb_info __initdata ek_lcdc_data; +static struct atmel_lcdfb_pdata __initdata ek_lcdc_data; #endif diff --git a/arch/arm/mach-at91/board.h b/arch/arm/mach-at91/board.h index 4a234fb2ab3b..6c08b341167d 100644 --- a/arch/arm/mach-at91/board.h +++ b/arch/arm/mach-at91/board.h @@ -107,8 +107,8 @@ extern void __init at91_add_device_pwm(u32 mask); extern void __init at91_add_device_ssc(unsigned id, unsigned pins); /* LCD Controller */ -struct atmel_lcdfb_info; -extern void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data); +struct atmel_lcdfb_pdata; +extern void __init at91_add_device_lcdc(struct atmel_lcdfb_pdata *data); /* AC97 */ extern void __init at91_add_device_ac97(struct ac97c_platform_data *data); diff --git a/arch/arm/mach-at91/cpuidle.c b/arch/arm/mach-at91/cpuidle.c deleted file mode 100644 index 4ec6a6d9b9be..000000000000 --- a/arch/arm/mach-at91/cpuidle.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * based on arch/arm/mach-kirkwood/cpuidle.c - * - * CPU idle support for AT91 SoC - * - * 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. - * - * The cpu idle uses wait-for-interrupt and RAM self refresh in order - * to implement two idle states - - * #1 wait-for-interrupt - * #2 wait-for-interrupt and RAM self refresh - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/platform_device.h> -#include <linux/cpuidle.h> -#include <linux/io.h> -#include <linux/export.h> -#include <asm/proc-fns.h> -#include <asm/cpuidle.h> -#include <mach/cpu.h> - -#include "pm.h" - -#define AT91_MAX_STATES 2 - -/* Actual code that puts the SoC in different idle states */ -static int at91_enter_idle(struct cpuidle_device *dev, - struct cpuidle_driver *drv, - int index) -{ - if (cpu_is_at91rm9200()) - at91rm9200_standby(); - else if (cpu_is_at91sam9g45()) - at91sam9g45_standby(); - else if (cpu_is_at91sam9263()) - at91sam9263_standby(); - else - at91sam9_standby(); - - return index; -} - -static struct cpuidle_driver at91_idle_driver = { - .name = "at91_idle", - .owner = THIS_MODULE, - .states[0] = ARM_CPUIDLE_WFI_STATE, - .states[1] = { - .enter = at91_enter_idle, - .exit_latency = 10, - .target_residency = 10000, - .flags = CPUIDLE_FLAG_TIME_VALID, - .name = "RAM_SR", - .desc = "WFI and DDR Self Refresh", - }, - .state_count = AT91_MAX_STATES, -}; - -/* Initialize CPU idle by registering the idle states */ -static int __init at91_init_cpuidle(void) -{ - return cpuidle_register(&at91_idle_driver, NULL); -} - -device_initcall(at91_init_cpuidle); diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h index dc6e2f5f804d..26dee3ce9397 100644 --- a/arch/arm/mach-at91/generic.h +++ b/arch/arm/mach-at91/generic.h @@ -34,6 +34,8 @@ extern int __init at91_aic_of_init(struct device_node *node, struct device_node *parent); extern int __init at91_aic5_of_init(struct device_node *node, struct device_node *parent); +extern void __init at91_sysirq_mask_rtc(u32 rtc_base); +extern void __init at91_sysirq_mask_rtt(u32 rtt_base); /* Timer */ diff --git a/arch/arm/mach-at91/include/mach/at91_adc.h b/arch/arm/mach-at91/include/mach/at91_adc.h index 048a57f76bd3..c287307b9a3b 100644 --- a/arch/arm/mach-at91/include/mach/at91_adc.h +++ b/arch/arm/mach-at91/include/mach/at91_adc.h @@ -60,14 +60,48 @@ #define AT91_ADC_IER 0x24 /* Interrupt Enable Register */ #define AT91_ADC_IDR 0x28 /* Interrupt Disable Register */ #define AT91_ADC_IMR 0x2C /* Interrupt Mask Register */ +#define AT91_ADC_IER_PEN (1 << 29) +#define AT91_ADC_IER_NOPEN (1 << 30) +#define AT91_ADC_IER_XRDY (1 << 20) +#define AT91_ADC_IER_YRDY (1 << 21) +#define AT91_ADC_IER_PRDY (1 << 22) +#define AT91_ADC_ISR_PENS (1 << 31) #define AT91_ADC_CHR(n) (0x30 + ((n) * 4)) /* Channel Data Register N */ #define AT91_ADC_DATA (0x3ff) #define AT91_ADC_CDR0_9X5 (0x50) /* Channel Data Register 0 for 9X5 */ +#define AT91_ADC_ACR 0x94 /* Analog Control Register */ +#define AT91_ADC_ACR_PENDETSENS (0x3 << 0) /* pull-up resistor */ + +#define AT91_ADC_TSMR 0xB0 +#define AT91_ADC_TSMR_TSMODE (3 << 0) /* Touch Screen Mode */ +#define AT91_ADC_TSMR_TSMODE_NONE (0 << 0) +#define AT91_ADC_TSMR_TSMODE_4WIRE_NO_PRESS (1 << 0) +#define AT91_ADC_TSMR_TSMODE_4WIRE_PRESS (2 << 0) +#define AT91_ADC_TSMR_TSMODE_5WIRE (3 << 0) +#define AT91_ADC_TSMR_TSAV (3 << 4) /* Averages samples */ +#define AT91_ADC_TSMR_TSAV_(x) ((x) << 4) +#define AT91_ADC_TSMR_SCTIM (0x0f << 16) /* Switch closure time */ +#define AT91_ADC_TSMR_PENDBC (0x0f << 28) /* Pen Debounce time */ +#define AT91_ADC_TSMR_PENDBC_(x) ((x) << 28) +#define AT91_ADC_TSMR_NOTSDMA (1 << 22) /* No Touchscreen DMA */ +#define AT91_ADC_TSMR_PENDET_DIS (0 << 24) /* Pen contact detection disable */ +#define AT91_ADC_TSMR_PENDET_ENA (1 << 24) /* Pen contact detection enable */ + +#define AT91_ADC_TSXPOSR 0xB4 +#define AT91_ADC_TSYPOSR 0xB8 +#define AT91_ADC_TSPRESSR 0xBC + #define AT91_ADC_TRGR_9260 AT91_ADC_MR #define AT91_ADC_TRGR_9G45 0x08 #define AT91_ADC_TRGR_9X5 0xC0 +/* Trigger Register bit field */ +#define AT91_ADC_TRGR_TRGPER (0xffff << 16) +#define AT91_ADC_TRGR_TRGPER_(x) ((x) << 16) +#define AT91_ADC_TRGR_TRGMOD (0x7 << 0) +#define AT91_ADC_TRGR_MOD_PERIOD_TRIG (5 << 0) + #endif diff --git a/arch/arm/mach-at91/include/mach/at91sam9n12.h b/arch/arm/mach-at91/include/mach/at91sam9n12.h index d374b87c0459..0151bcf6163c 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9n12.h +++ b/arch/arm/mach-at91/include/mach/at91sam9n12.h @@ -49,6 +49,11 @@ #define AT91SAM9N12_BASE_USART3 0xf8028000 /* + * System Peripherals + */ +#define AT91SAM9N12_BASE_RTC 0xfffffeb0 + +/* * Internal Memory. */ #define AT91SAM9N12_SRAM_BASE 0x00300000 /* Internal SRAM base address */ diff --git a/arch/arm/mach-at91/include/mach/at91sam9x5.h b/arch/arm/mach-at91/include/mach/at91sam9x5.h index c75ee19b58d3..2fc76c49e97c 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9x5.h +++ b/arch/arm/mach-at91/include/mach/at91sam9x5.h @@ -55,6 +55,11 @@ #define AT91SAM9X5_BASE_USART2 0xf8024000 /* + * System Peripherals + */ +#define AT91SAM9X5_BASE_RTC 0xfffffeb0 + +/* * Internal Memory. */ #define AT91SAM9X5_SRAM_BASE 0x00300000 /* Internal SRAM base address */ diff --git a/arch/arm/mach-at91/include/mach/sama5d3.h b/arch/arm/mach-at91/include/mach/sama5d3.h index 31096a8aaf1d..25613d8c6dcd 100644 --- a/arch/arm/mach-at91/include/mach/sama5d3.h +++ b/arch/arm/mach-at91/include/mach/sama5d3.h @@ -73,6 +73,11 @@ #define SAMA5D3_BASE_USART3 0xf8024000 /* + * System Peripherals + */ +#define SAMA5D3_BASE_RTC 0xfffffeb0 + +/* * Internal Memory */ #define SAMA5D3_SRAM_BASE 0x00300000 /* Internal SRAM base address */ diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index 15afb5d9271f..9986542e8060 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -39,6 +39,8 @@ #include "at91_rstc.h" #include "at91_shdwc.h" +static void (*at91_pm_standby)(void); + static void __init show_reset_status(void) { static char reset[] __initdata = "reset"; @@ -266,14 +268,8 @@ static int at91_pm_enter(suspend_state_t state) * For ARM 926 based chips, this requirement is weaker * as at91sam9 can access a RAM in self-refresh mode. */ - if (cpu_is_at91rm9200()) - at91rm9200_standby(); - else if (cpu_is_at91sam9g45()) - at91sam9g45_standby(); - else if (cpu_is_at91sam9263()) - at91sam9263_standby(); - else - at91sam9_standby(); + if (at91_pm_standby) + at91_pm_standby(); break; case PM_SUSPEND_ON: @@ -314,6 +310,18 @@ static const struct platform_suspend_ops at91_pm_ops = { .end = at91_pm_end, }; +static struct platform_device at91_cpuidle_device = { + .name = "cpuidle-at91", +}; + +void at91_pm_set_standby(void (*at91_standby)(void)) +{ + if (at91_standby) { + at91_cpuidle_device.dev.platform_data = at91_standby; + at91_pm_standby = at91_standby; + } +} + static int __init at91_pm_init(void) { #ifdef CONFIG_AT91_SLOW_CLOCK @@ -325,6 +333,9 @@ static int __init at91_pm_init(void) /* AT91RM9200 SDRAM low-power mode cannot be used with self-refresh. */ if (cpu_is_at91rm9200()) at91_ramc_write(0, AT91RM9200_SDRAMC_LPR, 0); + + if (at91_cpuidle_device.dev.platform_data) + platform_device_register(&at91_cpuidle_device); suspend_set_ops(&at91_pm_ops); diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h index 2f5908f0b8c5..3ed190ce062b 100644 --- a/arch/arm/mach-at91/pm.h +++ b/arch/arm/mach-at91/pm.h @@ -11,9 +11,13 @@ #ifndef __ARCH_ARM_MACH_AT91_PM #define __ARCH_ARM_MACH_AT91_PM +#include <asm/proc-fns.h> + #include <mach/at91_ramc.h> #include <mach/at91rm9200_sdramc.h> +extern void at91_pm_set_standby(void (*at91_standby)(void)); + /* * The AT91RM9200 goes into self-refresh mode with this command, and will * terminate self-refresh automatically on the next SDRAM access. @@ -45,16 +49,18 @@ static inline void at91rm9200_standby(void) /* We manage both DDRAM/SDRAM controllers, we need more than one value to * remember. */ -static inline void at91sam9g45_standby(void) +static inline void at91_ddr_standby(void) { /* Those two values allow us to delay self-refresh activation * to the maximum. */ - u32 lpr0, lpr1; - u32 saved_lpr0, saved_lpr1; + u32 lpr0, lpr1 = 0; + u32 saved_lpr0, saved_lpr1 = 0; - saved_lpr1 = at91_ramc_read(1, AT91_DDRSDRC_LPR); - lpr1 = saved_lpr1 & ~AT91_DDRSDRC_LPCB; - lpr1 |= AT91_DDRSDRC_LPCB_SELF_REFRESH; + if (at91_ramc_base[1]) { + saved_lpr1 = at91_ramc_read(1, AT91_DDRSDRC_LPR); + lpr1 = saved_lpr1 & ~AT91_DDRSDRC_LPCB; + lpr1 |= AT91_DDRSDRC_LPCB_SELF_REFRESH; + } saved_lpr0 = at91_ramc_read(0, AT91_DDRSDRC_LPR); lpr0 = saved_lpr0 & ~AT91_DDRSDRC_LPCB; @@ -62,25 +68,29 @@ static inline void at91sam9g45_standby(void) /* self-refresh mode now */ at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr0); - at91_ramc_write(1, AT91_DDRSDRC_LPR, lpr1); + if (at91_ramc_base[1]) + at91_ramc_write(1, AT91_DDRSDRC_LPR, lpr1); cpu_do_idle(); at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0); - at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1); + if (at91_ramc_base[1]) + at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1); } /* We manage both DDRAM/SDRAM controllers, we need more than one value to * remember. */ -static inline void at91sam9263_standby(void) +static inline void at91sam9_sdram_standby(void) { - u32 lpr0, lpr1; - u32 saved_lpr0, saved_lpr1; + u32 lpr0, lpr1 = 0; + u32 saved_lpr0, saved_lpr1 = 0; - saved_lpr1 = at91_ramc_read(1, AT91_SDRAMC_LPR); - lpr1 = saved_lpr1 & ~AT91_SDRAMC_LPCB; - lpr1 |= AT91_SDRAMC_LPCB_SELF_REFRESH; + if (at91_ramc_base[1]) { + saved_lpr1 = at91_ramc_read(1, AT91_SDRAMC_LPR); + lpr1 = saved_lpr1 & ~AT91_SDRAMC_LPCB; + lpr1 |= AT91_SDRAMC_LPCB_SELF_REFRESH; + } saved_lpr0 = at91_ramc_read(0, AT91_SDRAMC_LPR); lpr0 = saved_lpr0 & ~AT91_SDRAMC_LPCB; @@ -88,27 +98,14 @@ static inline void at91sam9263_standby(void) /* self-refresh mode now */ at91_ramc_write(0, AT91_SDRAMC_LPR, lpr0); - at91_ramc_write(1, AT91_SDRAMC_LPR, lpr1); + if (at91_ramc_base[1]) + at91_ramc_write(1, AT91_SDRAMC_LPR, lpr1); cpu_do_idle(); at91_ramc_write(0, AT91_SDRAMC_LPR, saved_lpr0); - at91_ramc_write(1, AT91_SDRAMC_LPR, saved_lpr1); -} - -static inline void at91sam9_standby(void) -{ - u32 saved_lpr, lpr; - - saved_lpr = at91_ramc_read(0, AT91_SDRAMC_LPR); - - lpr = saved_lpr & ~AT91_SDRAMC_LPCB; - at91_ramc_write(0, AT91_SDRAMC_LPR, lpr | - AT91_SDRAMC_LPCB_SELF_REFRESH); - - cpu_do_idle(); - - at91_ramc_write(0, AT91_SDRAMC_LPR, saved_lpr); + if (at91_ramc_base[1]) + at91_ramc_write(1, AT91_SDRAMC_LPR, saved_lpr1); } #endif diff --git a/arch/arm/mach-at91/sama5d3.c b/arch/arm/mach-at91/sama5d3.c index 401279715ab1..3ea86428ee09 100644 --- a/arch/arm/mach-at91/sama5d3.c +++ b/arch/arm/mach-at91/sama5d3.c @@ -371,7 +371,13 @@ static void __init sama5d3_map_io(void) at91_init_sram(0, SAMA5D3_SRAM_BASE, SAMA5D3_SRAM_SIZE); } +static void __init sama5d3_initialize(void) +{ + at91_sysirq_mask_rtc(SAMA5D3_BASE_RTC); +} + AT91_SOC_START(sama5d3) .map_io = sama5d3_map_io, .register_clocks = sama5d3_register_clocks, + .init = sama5d3_initialize, AT91_SOC_END diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c index b17fbcf4d9e8..094b3459c288 100644 --- a/arch/arm/mach-at91/setup.c +++ b/arch/arm/mach-at91/setup.c @@ -23,6 +23,7 @@ #include "at91_shdwc.h" #include "soc.h" #include "generic.h" +#include "pm.h" struct at91_init_soc __initdata at91_boot_soc; @@ -376,15 +377,16 @@ 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" }, + { .compatible = "atmel,at91rm9200-sdramc", .data = at91rm9200_standby }, + { .compatible = "atmel,at91sam9260-sdramc", .data = at91sam9_sdram_standby }, + { .compatible = "atmel,at91sam9g45-ddramc", .data = at91_ddr_standby }, { /*sentinel*/ } }; static void at91_dt_ramc(void) { struct device_node *np; + const struct of_device_id *of_id; np = of_find_matching_node(NULL, ramc_ids); if (!np) @@ -396,6 +398,12 @@ static void at91_dt_ramc(void) /* the controller may have 2 banks */ at91_ramc_base[1] = of_iomap(np, 1); + of_id = of_match_node(ramc_ids, np); + if (!of_id) + pr_warn("AT91: ramc no standby function available\n"); + else + at91_pm_set_standby(of_id->data); + of_node_put(np); } diff --git a/arch/arm/mach-at91/sysirq_mask.c b/arch/arm/mach-at91/sysirq_mask.c new file mode 100644 index 000000000000..2ba694f9626b --- /dev/null +++ b/arch/arm/mach-at91/sysirq_mask.c @@ -0,0 +1,71 @@ +/* + * sysirq_mask.c - System-interrupt masking + * + * Copyright (C) 2013 Johan Hovold <jhovold@gmail.com> + * + * Functions to disable system interrupts from backup-powered peripherals. + * + * The RTC and RTT-peripherals are generally powered by backup power (VDDBU) + * and are not reset on wake-up, user, watchdog or software reset. This means + * that their interrupts may be enabled during early boot (e.g. after a user + * reset). + * + * As the RTC and RTT share the system-interrupt line with the PIT, an + * interrupt occurring before a handler has been installed would lead to the + * system interrupt being disabled and prevent the system from booting. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include <linux/io.h> +#include <mach/at91_rtt.h> + +#include "generic.h" + +#define AT91_RTC_IDR 0x24 /* Interrupt Disable Register */ +#define AT91_RTC_IMR 0x28 /* Interrupt Mask Register */ + +void __init at91_sysirq_mask_rtc(u32 rtc_base) +{ + void __iomem *base; + u32 mask; + + base = ioremap(rtc_base, 64); + if (!base) + return; + + mask = readl_relaxed(base + AT91_RTC_IMR); + if (mask) { + pr_info("AT91: Disabling rtc irq\n"); + writel_relaxed(mask, base + AT91_RTC_IDR); + (void)readl_relaxed(base + AT91_RTC_IMR); /* flush */ + } + + iounmap(base); +} + +void __init at91_sysirq_mask_rtt(u32 rtt_base) +{ + void __iomem *base; + void __iomem *reg; + u32 mode; + + base = ioremap(rtt_base, 16); + if (!base) + return; + + reg = base + AT91_RTT_MR; + + mode = readl_relaxed(reg); + if (mode & (AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN)) { + pr_info("AT91: Disabling rtt irq\n"); + mode &= ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN); + writel_relaxed(mode, reg); + (void)readl_relaxed(reg); /* flush */ + } + + iounmap(base); +} diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig index 69d67f714a2f..9fe6d88737ed 100644 --- a/arch/arm/mach-bcm/Kconfig +++ b/arch/arm/mach-bcm/Kconfig @@ -1,5 +1,16 @@ config ARCH_BCM - bool "Broadcom SoC" if ARCH_MULTI_V7 + bool "Broadcom SoC Support" + depends on ARCH_MULTIPLATFORM + help + This enables support for Broadcom ARM based SoC + chips + +if ARCH_BCM + +menu "Broadcom SoC Selection" + +config ARCH_BCM_MOBILE + bool "Broadcom Mobile SoC" if ARCH_MULTI_V7 depends on MMU select ARCH_REQUIRE_GPIOLIB select ARM_ERRATA_754322 @@ -9,12 +20,17 @@ config ARCH_BCM select CLKSRC_OF select GENERIC_CLOCKEVENTS select GENERIC_TIME - select GPIO_BCM + select GPIO_BCM_KONA select SPARSE_IRQ select TICK_ONESHOT select CACHE_L2X0 + select HAVE_ARM_ARCH_TIMER help - This enables support for system based on Broadcom SoCs. + This enables support for systems based on Broadcom mobile SoCs. It currently supports the 'BCM281XX' family, which includes BCM11130, BCM11140, BCM11351, BCM28145 and BCM28155 variants. + +endmenu + +endif diff --git a/arch/arm/mach-bcm/Makefile b/arch/arm/mach-bcm/Makefile index e3d03033a7e2..c2ccd5a0f772 100644 --- a/arch/arm/mach-bcm/Makefile +++ b/arch/arm/mach-bcm/Makefile @@ -10,6 +10,6 @@ # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -obj-$(CONFIG_ARCH_BCM) := board_bcm281xx.o bcm_kona_smc.o bcm_kona_smc_asm.o kona.o +obj-$(CONFIG_ARCH_BCM_MOBILE) := board_bcm281xx.o bcm_kona_smc.o bcm_kona_smc_asm.o kona.o plus_sec := $(call as-instr,.arch_extension sec,+sec) AFLAGS_bcm_kona_smc_asm.o :=-Wa,-march=armv7-a$(plus_sec) diff --git a/arch/arm/mach-bcm/board_bcm281xx.c b/arch/arm/mach-bcm/board_bcm281xx.c index 8d9f931164bb..cb3dc364405c 100644 --- a/arch/arm/mach-bcm/board_bcm281xx.c +++ b/arch/arm/mach-bcm/board_bcm281xx.c @@ -67,8 +67,7 @@ static void __init board_init(void) static const char * const bcm11351_dt_compat[] = { "brcm,bcm11351", NULL, }; -DT_MACHINE_START(BCM11351_DT, "Broadcom Application Processor") - .init_time = clocksource_of_init, +DT_MACHINE_START(BCM11351_DT, "BCM281xx Broadcom Application Processor") .init_machine = board_init, .restart = bcm_kona_restart, .dt_compat = bcm11351_dt_compat, diff --git a/arch/arm/mach-bcm2835/bcm2835.c b/arch/arm/mach-bcm2835/bcm2835.c index 40686d7ef500..70f2f3925f0e 100644 --- a/arch/arm/mach-bcm2835/bcm2835.c +++ b/arch/arm/mach-bcm2835/bcm2835.c @@ -14,11 +14,10 @@ #include <linux/delay.h> #include <linux/init.h> -#include <linux/irqchip/bcm2835.h> +#include <linux/irqchip.h> #include <linux/of_address.h> #include <linux/of_platform.h> #include <linux/clk/bcm2835.h> -#include <linux/clocksource.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> @@ -131,10 +130,8 @@ static const char * const bcm2835_compat[] = { DT_MACHINE_START(BCM2835, "BCM2835") .map_io = bcm2835_map_io, - .init_irq = bcm2835_init_irq, - .handle_irq = bcm2835_handle_irq, + .init_irq = irqchip_init, .init_machine = bcm2835_init, - .init_time = clocksource_of_init, .restart = bcm2835_restart, .dt_compat = bcm2835_compat MACHINE_END diff --git a/arch/arm/mach-clps711x/common.c b/arch/arm/mach-clps711x/common.c index 4ca2f3ca2de4..134641d688bb 100644 --- a/arch/arm/mach-clps711x/common.c +++ b/arch/arm/mach-clps711x/common.c @@ -29,12 +29,12 @@ #include <linux/clockchips.h> #include <linux/clocksource.h> #include <linux/clk-provider.h> +#include <linux/sched_clock.h> #include <asm/exception.h> #include <asm/mach/irq.h> #include <asm/mach/map.h> #include <asm/mach/time.h> -#include <asm/sched_clock.h> #include <asm/system_misc.h> #include <mach/hardware.h> diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig index e026b19b23ea..a075b3e0c5c7 100644 --- a/arch/arm/mach-davinci/Kconfig +++ b/arch/arm/mach-davinci/Kconfig @@ -40,7 +40,6 @@ config ARCH_DAVINCI_DA850 bool "DA850/OMAP-L138/AM18x based system" select ARCH_DAVINCI_DA8XX select ARCH_HAS_CPUFREQ - select CPU_FREQ_TABLE select CP_INTC config ARCH_DAVINCI_DA8XX diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c index c4bdc0a1c36e..d1f45af7a530 100644 --- a/arch/arm/mach-davinci/board-da830-evm.c +++ b/arch/arm/mach-davinci/board-da830-evm.c @@ -17,22 +17,24 @@ #include <linux/platform_device.h> #include <linux/i2c.h> #include <linux/i2c/pcf857x.h> -#include <linux/i2c/at24.h> +#include <linux/platform_data/at24.h> #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> #include <linux/spi/spi.h> #include <linux/spi/flash.h> +#include <linux/platform_data/gpio-davinci.h> +#include <linux/platform_data/mtd-davinci.h> +#include <linux/platform_data/mtd-davinci-aemif.h> +#include <linux/platform_data/spi-davinci.h> +#include <linux/platform_data/usb-davinci.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> +#include <mach/common.h> #include <mach/cp_intc.h> #include <mach/mux.h> -#include <linux/platform_data/mtd-davinci.h> #include <mach/da8xx.h> -#include <linux/platform_data/usb-davinci.h> -#include <linux/platform_data/mtd-davinci-aemif.h> -#include <linux/platform_data/spi-davinci.h> #define DA830_EVM_PHY_ID "" /* @@ -74,7 +76,7 @@ static int da830_evm_usb_ocic_notify(da8xx_ocic_handler_t handler) if (handler != NULL) { da830_evm_usb_ocic_handler = handler; - error = request_irq(irq, da830_evm_usb_ocic_irq, IRQF_DISABLED | + error = request_irq(irq, da830_evm_usb_ocic_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "OHCI over-current indicator", NULL); if (error) @@ -591,6 +593,10 @@ static __init void da830_evm_init(void) struct davinci_soc_info *soc_info = &davinci_soc_info; int ret; + ret = da830_register_gpio(); + if (ret) + pr_warn("da830_evm_init: GPIO init failed: %d\n", ret); + ret = da830_register_edma(da830_edma_rsv); if (ret) pr_warning("da830_evm_init: edma registration failed: %d\n", diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c index dd1fb24521aa..e0af0eccde8f 100644 --- a/arch/arm/mach-davinci/board-da850-evm.c +++ b/arch/arm/mach-davinci/board-da850-evm.c @@ -18,7 +18,7 @@ #include <linux/init.h> #include <linux/kernel.h> #include <linux/i2c.h> -#include <linux/i2c/at24.h> +#include <linux/platform_data/at24.h> #include <linux/platform_data/pca953x.h> #include <linux/input.h> #include <linux/input/tps6507x-ts.h> @@ -28,6 +28,7 @@ #include <linux/mtd/partitions.h> #include <linux/mtd/physmap.h> #include <linux/platform_device.h> +#include <linux/platform_data/gpio-davinci.h> #include <linux/platform_data/mtd-davinci.h> #include <linux/platform_data/mtd-davinci-aemif.h> #include <linux/platform_data/spi-davinci.h> @@ -38,6 +39,7 @@ #include <linux/spi/flash.h> #include <linux/wl12xx.h> +#include <mach/common.h> #include <mach/cp_intc.h> #include <mach/da8xx.h> #include <mach/mux.h> @@ -1437,6 +1439,10 @@ static __init void da850_evm_init(void) { int ret; + ret = da850_register_gpio(); + if (ret) + pr_warn("%s: GPIO init failed: %d\n", __func__, ret); + ret = pmic_tps65070_init(); if (ret) pr_warn("%s: TPS65070 PMIC init failed: %d\n", __func__, ret); diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c index 42b23a3194a0..ecdc7d44fa70 100644 --- a/arch/arm/mach-davinci/board-dm355-evm.c +++ b/arch/arm/mach-davinci/board-dm355-evm.c @@ -22,15 +22,17 @@ #include <media/tvp514x.h> #include <linux/spi/spi.h> #include <linux/spi/eeprom.h> +#include <linux/platform_data/gpio-davinci.h> +#include <linux/platform_data/i2c-davinci.h> +#include <linux/platform_data/mtd-davinci.h> +#include <linux/platform_data/mmc-davinci.h> +#include <linux/platform_data/usb-davinci.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> -#include <linux/platform_data/i2c-davinci.h> #include <mach/serial.h> -#include <linux/platform_data/mtd-davinci.h> -#include <linux/platform_data/mmc-davinci.h> -#include <linux/platform_data/usb-davinci.h> +#include <mach/common.h> #include "davinci.h" @@ -375,6 +377,11 @@ static struct spi_board_info dm355_evm_spi_info[] __initconst = { static __init void dm355_evm_init(void) { struct clk *aemif; + int ret; + + ret = dm355_gpio_register(); + if (ret) + pr_warn("%s: GPIO init failed: %d\n", __func__, ret); gpio_request(1, "dm9000"); gpio_direction_input(1); diff --git a/arch/arm/mach-davinci/board-dm355-leopard.c b/arch/arm/mach-davinci/board-dm355-leopard.c index 65a984c52df6..43bacbf15314 100644 --- a/arch/arm/mach-davinci/board-dm355-leopard.c +++ b/arch/arm/mach-davinci/board-dm355-leopard.c @@ -19,15 +19,16 @@ #include <linux/clk.h> #include <linux/spi/spi.h> #include <linux/spi/eeprom.h> +#include <linux/platform_data/i2c-davinci.h> +#include <linux/platform_data/mmc-davinci.h> +#include <linux/platform_data/mtd-davinci.h> +#include <linux/platform_data/usb-davinci.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> -#include <linux/platform_data/i2c-davinci.h> +#include <mach/common.h> #include <mach/serial.h> -#include <linux/platform_data/mtd-davinci.h> -#include <linux/platform_data/mmc-davinci.h> -#include <linux/platform_data/usb-davinci.h> #include "davinci.h" @@ -234,6 +235,11 @@ static struct spi_board_info dm355_leopard_spi_info[] __initconst = { static __init void dm355_leopard_init(void) { struct clk *aemif; + int ret; + + ret = dm355_gpio_register(); + if (ret) + pr_warn("%s: GPIO init failed: %d\n", __func__, ret); gpio_request(9, "dm9000"); gpio_direction_input(9); diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c index 4078ba93776b..e08a8684ead2 100644 --- a/arch/arm/mach-davinci/board-dm365-evm.c +++ b/arch/arm/mach-davinci/board-dm365-evm.c @@ -18,7 +18,7 @@ #include <linux/i2c.h> #include <linux/io.h> #include <linux/clk.h> -#include <linux/i2c/at24.h> +#include <linux/platform_data/at24.h> #include <linux/leds.h> #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> @@ -743,6 +743,12 @@ static struct spi_board_info dm365_evm_spi_info[] __initconst = { static __init void dm365_evm_init(void) { + int ret; + + ret = dm365_gpio_register(); + if (ret) + pr_warn("%s: GPIO init failed: %d\n", __func__, ret); + evm_init_i2c(); davinci_serial_init(dm365_serial_device); diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c index 40bb9b5b87e8..987605b78556 100644 --- a/arch/arm/mach-davinci/board-dm644x-evm.c +++ b/arch/arm/mach-davinci/board-dm644x-evm.c @@ -15,7 +15,7 @@ #include <linux/gpio.h> #include <linux/i2c.h> #include <linux/i2c/pcf857x.h> -#include <linux/i2c/at24.h> +#include <linux/platform_data/at24.h> #include <linux/mtd/mtd.h> #include <linux/mtd/nand.h> #include <linux/mtd/partitions.h> @@ -754,9 +754,14 @@ static int davinci_phy_fixup(struct phy_device *phydev) static __init void davinci_evm_init(void) { + int ret; struct clk *aemif_clk; struct davinci_soc_info *soc_info = &davinci_soc_info; + ret = dm644x_gpio_register(); + if (ret) + pr_warn("%s: GPIO init failed: %d\n", __func__, ret); + aemif_clk = clk_get(NULL, "aemif"); clk_prepare_enable(aemif_clk); diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c index 2bc3651d56cc..13d0801fd6b1 100644 --- a/arch/arm/mach-davinci/board-dm646x-evm.c +++ b/arch/arm/mach-davinci/board-dm646x-evm.c @@ -22,7 +22,7 @@ #include <linux/gpio.h> #include <linux/platform_device.h> #include <linux/i2c.h> -#include <linux/i2c/at24.h> +#include <linux/platform_data/at24.h> #include <linux/i2c/pcf857x.h> #include <media/tvp514x.h> @@ -33,17 +33,19 @@ #include <linux/mtd/partitions.h> #include <linux/clk.h> #include <linux/export.h> +#include <linux/platform_data/gpio-davinci.h> +#include <linux/platform_data/i2c-davinci.h> +#include <linux/platform_data/mtd-davinci.h> +#include <linux/platform_data/mtd-davinci-aemif.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <mach/common.h> +#include <mach/irqs.h> #include <mach/serial.h> -#include <linux/platform_data/i2c-davinci.h> -#include <linux/platform_data/mtd-davinci.h> #include <mach/clock.h> #include <mach/cdce949.h> -#include <linux/platform_data/mtd-davinci-aemif.h> #include "davinci.h" #include "clock.h" @@ -786,8 +788,13 @@ static struct edma_rsv_info dm646x_edma_rsv[] = { static __init void evm_init(void) { + int ret; struct davinci_soc_info *soc_info = &davinci_soc_info; + ret = dm646x_gpio_register(); + if (ret) + pr_warn("%s: GPIO init failed: %d\n", __func__, ret); + evm_init_i2c(); davinci_serial_init(dm646x_serial_device); dm646x_init_mcasp0(&dm646x_evm_snd_data[0]); diff --git a/arch/arm/mach-davinci/board-mityomapl138.c b/arch/arm/mach-davinci/board-mityomapl138.c index cd0f58730c2b..7aa105b1fd0f 100644 --- a/arch/arm/mach-davinci/board-mityomapl138.c +++ b/arch/arm/mach-davinci/board-mityomapl138.c @@ -15,7 +15,7 @@ #include <linux/mtd/partitions.h> #include <linux/regulator/machine.h> #include <linux/i2c.h> -#include <linux/i2c/at24.h> +#include <linux/platform_data/at24.h> #include <linux/etherdevice.h> #include <linux/spi/spi.h> #include <linux/spi/flash.h> diff --git a/arch/arm/mach-davinci/board-neuros-osd2.c b/arch/arm/mach-davinci/board-neuros-osd2.c index 46f336fca803..bb680af98374 100644 --- a/arch/arm/mach-davinci/board-neuros-osd2.c +++ b/arch/arm/mach-davinci/board-neuros-osd2.c @@ -26,17 +26,18 @@ #include <linux/platform_device.h> #include <linux/gpio.h> #include <linux/mtd/partitions.h> +#include <linux/platform_data/gpio-davinci.h> +#include <linux/platform_data/i2c-davinci.h> +#include <linux/platform_data/mmc-davinci.h> +#include <linux/platform_data/mtd-davinci.h> +#include <linux/platform_data/usb-davinci.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <mach/common.h> -#include <linux/platform_data/i2c-davinci.h> #include <mach/serial.h> #include <mach/mux.h> -#include <linux/platform_data/mtd-davinci.h> -#include <linux/platform_data/mmc-davinci.h> -#include <linux/platform_data/usb-davinci.h> #include "davinci.h" @@ -169,9 +170,14 @@ static struct davinci_mmc_config davinci_ntosd2_mmc_config = { static __init void davinci_ntosd2_init(void) { + int ret; struct clk *aemif_clk; struct davinci_soc_info *soc_info = &davinci_soc_info; + ret = dm644x_gpio_register(); + if (ret) + pr_warn("%s: GPIO init failed: %d\n", __func__, ret); + aemif_clk = clk_get(NULL, "aemif"); clk_prepare_enable(aemif_clk); diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index ab98c75cabb4..2aac51d0e853 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -13,10 +13,12 @@ #include <linux/init.h> #include <linux/console.h> #include <linux/gpio.h> +#include <linux/platform_data/gpio-davinci.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> +#include <mach/common.h> #include <mach/cp_intc.h> #include <mach/da8xx.h> #include <mach/mux.h> @@ -211,7 +213,7 @@ static int hawk_usb_ocic_notify(da8xx_ocic_handler_t handler) hawk_usb_ocic_handler = handler; error = request_irq(irq, omapl138_hawk_usb_ocic_irq, - IRQF_DISABLED | IRQF_TRIGGER_RISING | + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "OHCI over-current indicator", NULL); if (error) @@ -290,6 +292,10 @@ static __init void omapl138_hawk_init(void) { int ret; + ret = da850_register_gpio(); + if (ret) + pr_warn("%s: GPIO init failed: %d\n", __func__, ret); + davinci_serial_init(da8xx_serial_device); omapl138_hawk_config_emac(); diff --git a/arch/arm/mach-davinci/board-sffsdr.c b/arch/arm/mach-davinci/board-sffsdr.c index d84360148100..41c7c9615791 100644 --- a/arch/arm/mach-davinci/board-sffsdr.c +++ b/arch/arm/mach-davinci/board-sffsdr.c @@ -26,7 +26,7 @@ #include <linux/init.h> #include <linux/platform_device.h> #include <linux/i2c.h> -#include <linux/i2c/at24.h> +#include <linux/platform_data/at24.h> #include <linux/mtd/mtd.h> #include <linux/mtd/nand.h> #include <linux/mtd/partitions.h> diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c index d6c746e35ad9..0813b5167e05 100644 --- a/arch/arm/mach-davinci/da830.c +++ b/arch/arm/mach-davinci/da830.c @@ -11,6 +11,7 @@ #include <linux/gpio.h> #include <linux/init.h> #include <linux/clk.h> +#include <linux/platform_data/gpio-davinci.h> #include <asm/mach/map.h> @@ -20,7 +21,6 @@ #include <mach/common.h> #include <mach/time.h> #include <mach/da8xx.h> -#include <mach/gpio-davinci.h> #include "clock.h" #include "mux.h" @@ -1151,6 +1151,16 @@ static struct davinci_id da830_ids[] = { }, }; +static struct davinci_gpio_platform_data da830_gpio_platform_data = { + .ngpio = 128, + .intc_irq_num = DA830_N_CP_INTC_IRQ, +}; + +int __init da830_register_gpio(void) +{ + return da8xx_register_gpio(&da830_gpio_platform_data); +} + static struct davinci_timer_instance da830_timer_instance[2] = { { .base = DA8XX_TIMER64P0_BASE, @@ -1196,10 +1206,6 @@ static struct davinci_soc_info davinci_soc_info_da830 = { .intc_irq_prios = da830_default_priorities, .intc_irq_num = DA830_N_CP_INTC_IRQ, .timer_info = &da830_timer_info, - .gpio_type = GPIO_TYPE_DAVINCI, - .gpio_base = DA8XX_GPIO_BASE, - .gpio_num = 128, - .gpio_irq = IRQ_DA8XX_GPIO0, .emac_pdata = &da8xx_emac_pdata, }; diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index f56e5fbfa2fd..352984e1528a 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -17,6 +17,7 @@ #include <linux/platform_device.h> #include <linux/cpufreq.h> #include <linux/regulator/consumer.h> +#include <linux/platform_data/gpio-davinci.h> #include <asm/mach/map.h> @@ -28,7 +29,6 @@ #include <mach/da8xx.h> #include <mach/cpufreq.h> #include <mach/pm.h> -#include <mach/gpio-davinci.h> #include "clock.h" #include "mux.h" @@ -1281,6 +1281,16 @@ int __init da850_register_vpif_capture(struct vpif_capture_config return platform_device_register(&da850_vpif_capture_dev); } +static struct davinci_gpio_platform_data da850_gpio_platform_data = { + .ngpio = 144, + .intc_irq_num = DA850_N_CP_INTC_IRQ, +}; + +int __init da850_register_gpio(void) +{ + return da8xx_register_gpio(&da850_gpio_platform_data); +} + static struct davinci_soc_info davinci_soc_info_da850 = { .io_desc = da850_io_desc, .io_desc_num = ARRAY_SIZE(da850_io_desc), @@ -1298,10 +1308,6 @@ static struct davinci_soc_info davinci_soc_info_da850 = { .intc_irq_prios = da850_default_priorities, .intc_irq_num = DA850_N_CP_INTC_IRQ, .timer_info = &da850_timer_info, - .gpio_type = GPIO_TYPE_DAVINCI, - .gpio_base = DA8XX_GPIO_BASE, - .gpio_num = 144, - .gpio_irq = IRQ_DA8XX_GPIO0, .emac_pdata = &da8xx_emac_pdata, .sram_dma = DA8XX_SHARED_RAM_BASE, .sram_len = SZ_128K, diff --git a/arch/arm/mach-davinci/davinci.h b/arch/arm/mach-davinci/davinci.h index 2ab5d577186f..2eebc4338802 100644 --- a/arch/arm/mach-davinci/davinci.h +++ b/arch/arm/mach-davinci/davinci.h @@ -53,6 +53,9 @@ extern void __iomem *davinci_sysmod_base; #define DAVINCI_SYSMOD_VIRT(x) (davinci_sysmod_base + (x)) void davinci_map_sysmod(void); +#define DAVINCI_GPIO_BASE 0x01C67000 +int davinci_gpio_register(struct resource *res, int size, void *pdata); + /* DM355 base addresses */ #define DM355_ASYNC_EMIF_CONTROL_BASE 0x01e10000 #define DM355_ASYNC_EMIF_DATA_CE0_BASE 0x02000000 @@ -82,6 +85,7 @@ void dm355_init_spi0(unsigned chipselect_mask, const struct spi_board_info *info, unsigned len); void dm355_init_asp1(u32 evt_enable, struct snd_platform_data *pdata); int dm355_init_video(struct vpfe_config *, struct vpbe_config *); +int dm355_gpio_register(void); /* DM365 function declarations */ void dm365_init(void); @@ -92,11 +96,13 @@ void dm365_init_rtc(void); void dm365_init_spi0(unsigned chipselect_mask, const struct spi_board_info *info, unsigned len); int dm365_init_video(struct vpfe_config *, struct vpbe_config *); +int dm365_gpio_register(void); /* DM644x function declarations */ void dm644x_init(void); void dm644x_init_asp(struct snd_platform_data *pdata); int dm644x_init_video(struct vpfe_config *, struct vpbe_config *); +int dm644x_gpio_register(void); /* DM646x function declarations */ void dm646x_init(void); @@ -106,6 +112,7 @@ int dm646x_init_edma(struct edma_rsv_info *rsv); void dm646x_video_init(void); void dm646x_setup_vpif(struct vpif_display_config *, struct vpif_capture_config *); +int dm646x_gpio_register(void); extern struct platform_device dm365_serial_device[]; extern struct platform_device dm355_serial_device[]; diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c index 2e473fefd71e..c46eccbbd512 100644 --- a/arch/arm/mach-davinci/devices-da8xx.c +++ b/arch/arm/mach-davinci/devices-da8xx.c @@ -665,6 +665,32 @@ int __init da8xx_register_lcdc(struct da8xx_lcdc_platform_data *pdata) return platform_device_register(&da8xx_lcdc_device); } +static struct resource da8xx_gpio_resources[] = { + { /* registers */ + .start = DA8XX_GPIO_BASE, + .end = DA8XX_GPIO_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + { /* interrupt */ + .start = IRQ_DA8XX_GPIO0, + .end = IRQ_DA8XX_GPIO8, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device da8xx_gpio_device = { + .name = "davinci_gpio", + .id = -1, + .num_resources = ARRAY_SIZE(da8xx_gpio_resources), + .resource = da8xx_gpio_resources, +}; + +int __init da8xx_register_gpio(void *pdata) +{ + da8xx_gpio_device.dev.platform_data = pdata; + return platform_device_register(&da8xx_gpio_device); +} + static struct resource da8xx_mmcsd0_resources[] = { { /* registers */ .start = DA8XX_MMCSD0_BASE, diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c index 111573c0aad1..3996e98f52fb 100644 --- a/arch/arm/mach-davinci/devices.c +++ b/arch/arm/mach-davinci/devices.c @@ -318,6 +318,19 @@ static void davinci_init_wdt(void) platform_device_register(&davinci_wdt_device); } +static struct platform_device davinci_gpio_device = { + .name = "davinci_gpio", + .id = -1, +}; + +int davinci_gpio_register(struct resource *res, int size, void *pdata) +{ + davinci_gpio_device.resource = res; + davinci_gpio_device.num_resources = size; + davinci_gpio_device.dev.platform_data = pdata; + return platform_device_register(&davinci_gpio_device); +} + /*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/ diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c index 3eaa5f6b2160..ef9ff1fb6f52 100644 --- a/arch/arm/mach-davinci/dm355.c +++ b/arch/arm/mach-davinci/dm355.c @@ -13,8 +13,10 @@ #include <linux/serial_8250.h> #include <linux/platform_device.h> #include <linux/dma-mapping.h> - #include <linux/spi/spi.h> +#include <linux/platform_data/edma.h> +#include <linux/platform_data/gpio-davinci.h> +#include <linux/platform_data/spi-davinci.h> #include <asm/mach/map.h> @@ -25,9 +27,6 @@ #include <mach/time.h> #include <mach/serial.h> #include <mach/common.h> -#include <linux/platform_data/spi-davinci.h> -#include <mach/gpio-davinci.h> -#include <linux/platform_data/edma.h> #include "davinci.h" #include "clock.h" @@ -886,6 +885,30 @@ static struct platform_device dm355_vpbe_dev = { }, }; +static struct resource dm355_gpio_resources[] = { + { /* registers */ + .start = DAVINCI_GPIO_BASE, + .end = DAVINCI_GPIO_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + { /* interrupt */ + .start = IRQ_DM355_GPIOBNK0, + .end = IRQ_DM355_GPIOBNK6, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct davinci_gpio_platform_data dm355_gpio_platform_data = { + .ngpio = 104, + .intc_irq_num = DAVINCI_N_AINTC_IRQ, +}; + +int __init dm355_gpio_register(void) +{ + return davinci_gpio_register(dm355_gpio_resources, + sizeof(dm355_gpio_resources), + &dm355_gpio_platform_data); +} /*----------------------------------------------------------------------*/ static struct map_desc dm355_io_desc[] = { @@ -1005,10 +1028,6 @@ static struct davinci_soc_info davinci_soc_info_dm355 = { .intc_irq_prios = dm355_default_priorities, .intc_irq_num = DAVINCI_N_AINTC_IRQ, .timer_info = &dm355_timer_info, - .gpio_type = GPIO_TYPE_DAVINCI, - .gpio_base = DAVINCI_GPIO_BASE, - .gpio_num = 104, - .gpio_irq = IRQ_DM355_GPIOBNK0, .sram_dma = 0x00010000, .sram_len = SZ_32K, }; diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c index c29e324eb0bb..1511a0680f9a 100644 --- a/arch/arm/mach-davinci/dm365.c +++ b/arch/arm/mach-davinci/dm365.c @@ -19,6 +19,9 @@ #include <linux/dma-mapping.h> #include <linux/spi/spi.h> #include <linux/platform_data/edma.h> +#include <linux/platform_data/gpio-davinci.h> +#include <linux/platform_data/keyscan-davinci.h> +#include <linux/platform_data/spi-davinci.h> #include <asm/mach/map.h> @@ -29,9 +32,6 @@ #include <mach/time.h> #include <mach/serial.h> #include <mach/common.h> -#include <linux/platform_data/keyscan-davinci.h> -#include <linux/platform_data/spi-davinci.h> -#include <mach/gpio-davinci.h> #include "davinci.h" #include "clock.h" @@ -698,6 +698,32 @@ void __init dm365_init_spi0(unsigned chipselect_mask, platform_device_register(&dm365_spi0_device); } +static struct resource dm365_gpio_resources[] = { + { /* registers */ + .start = DAVINCI_GPIO_BASE, + .end = DAVINCI_GPIO_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + { /* interrupt */ + .start = IRQ_DM365_GPIO0, + .end = IRQ_DM365_GPIO7, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct davinci_gpio_platform_data dm365_gpio_platform_data = { + .ngpio = 104, + .intc_irq_num = DAVINCI_N_AINTC_IRQ, + .gpio_unbanked = 8, +}; + +int __init dm365_gpio_register(void) +{ + return davinci_gpio_register(dm365_gpio_resources, + sizeof(dm365_gpio_resources), + &dm365_gpio_platform_data); +} + static struct emac_platform_data dm365_emac_pdata = { .ctrl_reg_offset = DM365_EMAC_CNTRL_OFFSET, .ctrl_mod_reg_offset = DM365_EMAC_CNTRL_MOD_OFFSET, @@ -1105,11 +1131,6 @@ static struct davinci_soc_info davinci_soc_info_dm365 = { .intc_irq_prios = dm365_default_priorities, .intc_irq_num = DAVINCI_N_AINTC_IRQ, .timer_info = &dm365_timer_info, - .gpio_type = GPIO_TYPE_DAVINCI, - .gpio_base = DAVINCI_GPIO_BASE, - .gpio_num = 104, - .gpio_irq = IRQ_DM365_GPIO0, - .gpio_unbanked = 8, /* really 16 ... skip muxed GPIOs */ .emac_pdata = &dm365_emac_pdata, .sram_dma = 0x00010000, .sram_len = SZ_32K, diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index 4f74682293d6..143a3217e8ef 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -13,6 +13,7 @@ #include <linux/serial_8250.h> #include <linux/platform_device.h> #include <linux/platform_data/edma.h> +#include <linux/platform_data/gpio-davinci.h> #include <asm/mach/map.h> @@ -23,7 +24,6 @@ #include <mach/time.h> #include <mach/serial.h> #include <mach/common.h> -#include <mach/gpio-davinci.h> #include "davinci.h" #include "clock.h" @@ -771,6 +771,30 @@ static struct platform_device dm644x_vpbe_dev = { }, }; +static struct resource dm644_gpio_resources[] = { + { /* registers */ + .start = DAVINCI_GPIO_BASE, + .end = DAVINCI_GPIO_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + { /* interrupt */ + .start = IRQ_GPIOBNK0, + .end = IRQ_GPIOBNK4, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct davinci_gpio_platform_data dm644_gpio_platform_data = { + .ngpio = 71, + .intc_irq_num = DAVINCI_N_AINTC_IRQ, +}; + +int __init dm644x_gpio_register(void) +{ + return davinci_gpio_register(dm644_gpio_resources, + sizeof(dm644_gpio_resources), + &dm644_gpio_platform_data); +} /*----------------------------------------------------------------------*/ static struct map_desc dm644x_io_desc[] = { @@ -897,10 +921,6 @@ static struct davinci_soc_info davinci_soc_info_dm644x = { .intc_irq_prios = dm644x_default_priorities, .intc_irq_num = DAVINCI_N_AINTC_IRQ, .timer_info = &dm644x_timer_info, - .gpio_type = GPIO_TYPE_DAVINCI, - .gpio_base = DAVINCI_GPIO_BASE, - .gpio_num = 71, - .gpio_irq = IRQ_GPIOBNK0, .emac_pdata = &dm644x_emac_pdata, .sram_dma = 0x00008000, .sram_len = SZ_16K, diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index 68f8d1f1aca1..2a73f299c1d0 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -14,6 +14,7 @@ #include <linux/serial_8250.h> #include <linux/platform_device.h> #include <linux/platform_data/edma.h> +#include <linux/platform_data/gpio-davinci.h> #include <asm/mach/map.h> @@ -24,7 +25,6 @@ #include <mach/time.h> #include <mach/serial.h> #include <mach/common.h> -#include <mach/gpio-davinci.h> #include "davinci.h" #include "clock.h" @@ -748,6 +748,30 @@ static struct platform_device vpif_capture_dev = { .num_resources = ARRAY_SIZE(vpif_capture_resource), }; +static struct resource dm646x_gpio_resources[] = { + { /* registers */ + .start = DAVINCI_GPIO_BASE, + .end = DAVINCI_GPIO_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + { /* interrupt */ + .start = IRQ_DM646X_GPIOBNK0, + .end = IRQ_DM646X_GPIOBNK2, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct davinci_gpio_platform_data dm646x_gpio_platform_data = { + .ngpio = 43, + .intc_irq_num = DAVINCI_N_AINTC_IRQ, +}; + +int __init dm646x_gpio_register(void) +{ + return davinci_gpio_register(dm646x_gpio_resources, + sizeof(dm646x_gpio_resources), + &dm646x_gpio_platform_data); +} /*----------------------------------------------------------------------*/ static struct map_desc dm646x_io_desc[] = { @@ -874,10 +898,6 @@ static struct davinci_soc_info davinci_soc_info_dm646x = { .intc_irq_prios = dm646x_default_priorities, .intc_irq_num = DAVINCI_N_AINTC_IRQ, .timer_info = &dm646x_timer_info, - .gpio_type = GPIO_TYPE_DAVINCI, - .gpio_base = DAVINCI_GPIO_BASE, - .gpio_num = 43, /* Only 33 usable */ - .gpio_irq = IRQ_DM646X_GPIOBNK0, .emac_pdata = &dm646x_emac_pdata, .sram_dma = 0x10010000, .sram_len = SZ_32K, diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h index aae53072c0eb..39e58b48e826 100644 --- a/arch/arm/mach-davinci/include/mach/da8xx.h +++ b/arch/arm/mach-davinci/include/mach/da8xx.h @@ -97,6 +97,7 @@ int da8xx_register_mmcsd0(struct davinci_mmc_config *config); int da850_register_mmcsd1(struct davinci_mmc_config *config); void da8xx_register_mcasp(int id, struct snd_platform_data *pdata); int da8xx_register_rtc(void); +int da8xx_register_gpio(void *pdata); int da850_register_cpufreq(char *async_clk); int da8xx_register_cpuidle(void); void __iomem *da8xx_get_mem_ctlr(void); @@ -110,6 +111,8 @@ int da850_register_vpif_capture void da8xx_restart(enum reboot_mode mode, const char *cmd); void da8xx_rproc_reserve_cma(void); int da8xx_register_rproc(void); +int da850_register_gpio(void); +int da830_register_gpio(void); extern struct platform_device da8xx_serial_device[]; extern struct emac_platform_data da8xx_emac_pdata; diff --git a/arch/arm/mach-davinci/include/mach/gpio-davinci.h b/arch/arm/mach-davinci/include/mach/gpio-davinci.h deleted file mode 100644 index 1fdd1fd35448..000000000000 --- a/arch/arm/mach-davinci/include/mach/gpio-davinci.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * TI DaVinci GPIO Support - * - * Copyright (c) 2006 David Brownell - * Copyright (c) 2007, MontaVista Software, Inc. <source@mvista.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#ifndef __DAVINCI_DAVINCI_GPIO_H -#define __DAVINCI_DAVINCI_GPIO_H - -#include <linux/io.h> -#include <linux/spinlock.h> - -#include <asm-generic/gpio.h> - -#include <mach/irqs.h> -#include <mach/common.h> - -#define DAVINCI_GPIO_BASE 0x01C67000 - -enum davinci_gpio_type { - GPIO_TYPE_DAVINCI = 0, - GPIO_TYPE_TNETV107X, -}; - -/* - * basic gpio routines - * - * board-specific init should be done by arch/.../.../board-XXX.c (maybe - * initializing banks together) rather than boot loaders; kexec() won't - * go through boot loaders. - * - * the gpio clock will be turned on when gpios are used, and you may also - * need to pay attention to PINMUX registers to be sure those pins are - * used as gpios, not with other peripherals. - * - * On-chip GPIOs are numbered 0..(DAVINCI_N_GPIO-1). For documentation, - * and maybe for later updates, code may write GPIO(N). These may be - * all 1.8V signals, all 3.3V ones, or a mix of the two. A given chip - * may not support all the GPIOs in that range. - * - * GPIOs can also be on external chips, numbered after the ones built-in - * to the DaVinci chip. For now, they won't be usable as IRQ sources. - */ -#define GPIO(X) (X) /* 0 <= X <= (DAVINCI_N_GPIO - 1) */ - -/* Convert GPIO signal to GPIO pin number */ -#define GPIO_TO_PIN(bank, gpio) (16 * (bank) + (gpio)) - -struct davinci_gpio_controller { - struct gpio_chip chip; - int irq_base; - spinlock_t lock; - void __iomem *regs; - void __iomem *set_data; - void __iomem *clr_data; - void __iomem *in_data; -}; - -/* The __gpio_to_controller() and __gpio_mask() functions inline to constants - * with constant parameters; or in outlined code they execute at runtime. - * - * You'd access the controller directly when reading or writing more than - * one gpio value at a time, and to support wired logic where the value - * being driven by the cpu need not match the value read back. - * - * These are NOT part of the cross-platform GPIO interface - */ -static inline struct davinci_gpio_controller * -__gpio_to_controller(unsigned gpio) -{ - struct davinci_gpio_controller *ctlrs = davinci_soc_info.gpio_ctlrs; - int index = gpio / 32; - - if (!ctlrs || index >= davinci_soc_info.gpio_ctlrs_num) - return NULL; - - return ctlrs + index; -} - -static inline u32 __gpio_mask(unsigned gpio) -{ - return 1 << (gpio % 32); -} - -#endif /* __DAVINCI_DAVINCI_GPIO_H */ diff --git a/arch/arm/mach-davinci/include/mach/gpio.h b/arch/arm/mach-davinci/include/mach/gpio.h deleted file mode 100644 index 960e9de47e1e..000000000000 --- a/arch/arm/mach-davinci/include/mach/gpio.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * TI DaVinci GPIO Support - * - * Copyright (c) 2006 David Brownell - * Copyright (c) 2007, MontaVista Software, Inc. <source@mvista.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#ifndef __DAVINCI_GPIO_H -#define __DAVINCI_GPIO_H - -#include <asm-generic/gpio.h> - -#define __ARM_GPIOLIB_COMPLEX - -/* The inline versions use the static inlines in the driver header */ -#include "gpio-davinci.h" - -/* - * The get/set/clear functions will inline when called with constant - * parameters referencing built-in GPIOs, for low-overhead bitbanging. - * - * gpio_set_value() will inline only on traditional Davinci style controllers - * with distinct set/clear registers. - * - * Otherwise, calls with variable parameters or referencing external - * GPIOs (e.g. on GPIO expander chips) use outlined functions. - */ -static inline void gpio_set_value(unsigned gpio, int value) -{ - if (__builtin_constant_p(value) && gpio < davinci_soc_info.gpio_num) { - struct davinci_gpio_controller *ctlr; - u32 mask; - - ctlr = __gpio_to_controller(gpio); - - if (ctlr->set_data != ctlr->clr_data) { - mask = __gpio_mask(gpio); - if (value) - __raw_writel(mask, ctlr->set_data); - else - __raw_writel(mask, ctlr->clr_data); - return; - } - } - - __gpio_set_value(gpio, value); -} - -/* Returns zero or nonzero; works for gpios configured as inputs OR - * as outputs, at least for built-in GPIOs. - * - * NOTE: for built-in GPIOs, changes in reported values are synchronized - * to the GPIO clock. This is easily seen after calling gpio_set_value() - * and then immediately gpio_get_value(), where the gpio_get_value() will - * return the old value until the GPIO clock ticks and the new value gets - * latched. - */ -static inline int gpio_get_value(unsigned gpio) -{ - struct davinci_gpio_controller *ctlr; - - if (!__builtin_constant_p(gpio) || gpio >= davinci_soc_info.gpio_num) - return __gpio_get_value(gpio); - - ctlr = __gpio_to_controller(gpio); - return __gpio_mask(gpio) & __raw_readl(ctlr->in_data); -} - -static inline int gpio_cansleep(unsigned gpio) -{ - if (__builtin_constant_p(gpio) && gpio < davinci_soc_info.gpio_num) - return 0; - else - return __gpio_cansleep(gpio); -} - -static inline int irq_to_gpio(unsigned irq) -{ - /* don't support the reverse mapping */ - return -ENOSYS; -} - -#endif /* __DAVINCI_GPIO_H */ diff --git a/arch/arm/mach-davinci/sram.c b/arch/arm/mach-davinci/sram.c index f18928b073f5..8540dddf1fbd 100644 --- a/arch/arm/mach-davinci/sram.c +++ b/arch/arm/mach-davinci/sram.c @@ -25,7 +25,6 @@ struct gen_pool *sram_get_gen_pool(void) void *sram_alloc(size_t len, dma_addr_t *dma) { - unsigned long vaddr; dma_addr_t dma_base = davinci_soc_info.sram_dma; if (dma) @@ -33,13 +32,7 @@ void *sram_alloc(size_t len, dma_addr_t *dma) if (!sram_pool || (dma && !dma_base)) return NULL; - vaddr = gen_pool_alloc(sram_pool, len); - if (!vaddr) - return NULL; - - if (dma) - *dma = gen_pool_virt_to_phys(sram_pool, vaddr); - return (void *)vaddr; + return gen_pool_dma_alloc(sram_pool, len, dma); } EXPORT_SYMBOL(sram_alloc); diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c index 7a55b5c95971..56c6eb5266ad 100644 --- a/arch/arm/mach-davinci/time.c +++ b/arch/arm/mach-davinci/time.c @@ -181,7 +181,7 @@ static struct timer_s timers[] = { .name = "clockevent", .opts = TIMER_OPTS_DISABLED, .irqaction = { - .flags = IRQF_DISABLED | IRQF_TIMER, + .flags = IRQF_TIMER, .handler = timer_interrupt, } }, @@ -190,7 +190,7 @@ static struct timer_s timers[] = { .period = ~0, .opts = TIMER_OPTS_PERIODIC, .irqaction = { - .flags = IRQF_DISABLED | IRQF_TIMER, + .flags = IRQF_TIMER, .handler = freerun_interrupt, } }, @@ -331,7 +331,6 @@ static void davinci_set_mode(enum clock_event_mode mode, static struct clock_event_device clockevent_davinci = { .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, - .shift = 32, .set_next_event = davinci_set_next_event, .set_mode = davinci_set_mode, }; @@ -397,14 +396,10 @@ void __init davinci_timer_init(void) /* setup clockevent */ clockevent_davinci.name = id_to_name[timers[TID_CLOCKEVENT].id]; - clockevent_davinci.mult = div_sc(davinci_clock_tick_rate, NSEC_PER_SEC, - clockevent_davinci.shift); - clockevent_davinci.max_delta_ns = - clockevent_delta2ns(0xfffffffe, &clockevent_davinci); - clockevent_davinci.min_delta_ns = 50000; /* 50 usec */ clockevent_davinci.cpumask = cpumask_of(0); - clockevents_register_device(&clockevent_davinci); + clockevents_config_and_register(&clockevent_davinci, + davinci_clock_tick_rate, 1, 0xfffffffe); for (i=0; i< ARRAY_SIZE(timers); i++) timer32_config(&timers[i]); diff --git a/arch/arm/mach-dove/board-dt.c b/arch/arm/mach-dove/board-dt.c index 49f72a848423..49fa9abd09da 100644 --- a/arch/arm/mach-dove/board-dt.c +++ b/arch/arm/mach-dove/board-dt.c @@ -10,54 +10,15 @@ #include <linux/init.h> #include <linux/clk-provider.h> -#include <linux/clocksource.h> -#include <linux/irqchip.h> #include <linux/of.h> #include <linux/of_platform.h> -#include <linux/platform_data/usb-ehci-orion.h> #include <asm/hardware/cache-tauros2.h> #include <asm/mach/arch.h> #include <mach/dove.h> #include <mach/pm.h> #include <plat/common.h> -#include <plat/irq.h> #include "common.h" -/* - * There are still devices that doesn't even know about DT, - * get clock gates here and add a clock lookup. - */ -static void __init dove_legacy_clk_init(void) -{ - struct device_node *np = of_find_compatible_node(NULL, NULL, - "marvell,dove-gating-clock"); - struct of_phandle_args clkspec; - - clkspec.np = np; - clkspec.args_count = 1; - - clkspec.args[0] = CLOCK_GATING_BIT_PCIE0; - orion_clkdev_add("0", "pcie", - of_clk_get_from_provider(&clkspec)); - - clkspec.args[0] = CLOCK_GATING_BIT_PCIE1; - orion_clkdev_add("1", "pcie", - of_clk_get_from_provider(&clkspec)); -} - -static void __init dove_dt_time_init(void) -{ - of_clk_init(NULL); - clocksource_of_init(); -} - -static void __init dove_dt_init_early(void) -{ - mvebu_mbus_init("marvell,dove-mbus", - BRIDGE_WINS_BASE, BRIDGE_WINS_SZ, - DOVE_MC_WINS_BASE, DOVE_MC_WINS_SZ); -} - static void __init dove_dt_init(void) { pr_info("Dove 88AP510 SoC\n"); @@ -65,14 +26,7 @@ static void __init dove_dt_init(void) #ifdef CONFIG_CACHE_TAUROS2 tauros2_init(0); #endif - dove_setup_cpu_wins(); - - /* Setup clocks for legacy devices */ - dove_legacy_clk_init(); - - /* Internal devices not ported to DT yet */ - dove_pcie_init(1, 1); - + BUG_ON(mvebu_mbus_dt_init()); of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); } @@ -83,8 +37,6 @@ static const char * const dove_dt_board_compat[] = { DT_MACHINE_START(DOVE_DT, "Marvell Dove (Flattened Device Tree)") .map_io = dove_map_io, - .init_early = dove_dt_init_early, - .init_time = dove_dt_time_init, .init_machine = dove_dt_init, .restart = dove_restart, .dt_compat = dove_dt_board_compat, diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c index c95dbce2468e..39ef3b613912 100644 --- a/arch/arm/mach-ep93xx/clock.c +++ b/arch/arm/mach-ep93xx/clock.c @@ -212,7 +212,7 @@ static struct clk_lookup clocks[] = { INIT_CK(NULL, "hclk", &clk_h), INIT_CK(NULL, "apb_pclk", &clk_p), INIT_CK(NULL, "pll2", &clk_pll2), - INIT_CK("ep93xx-ohci", NULL, &clk_usb_host), + INIT_CK("ohci-platform", NULL, &clk_usb_host), INIT_CK("ep93xx-keypad", NULL, &clk_keypad), INIT_CK("ep93xx-fb", NULL, &clk_video), INIT_CK("ep93xx-spi.0", NULL, &clk_spi), diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c index 3f12b885c083..d95ee28a616a 100644 --- a/arch/arm/mach-ep93xx/core.c +++ b/arch/arm/mach-ep93xx/core.c @@ -36,6 +36,7 @@ #include <linux/export.h> #include <linux/irqchip/arm-vic.h> #include <linux/reboot.h> +#include <linux/usb/ohci_pdriver.h> #include <mach/hardware.h> #include <linux/platform_data/video-ep93xx.h> @@ -297,25 +298,53 @@ static struct platform_device ep93xx_rtc_device = { .resource = ep93xx_rtc_resource, }; +/************************************************************************* + * EP93xx OHCI USB Host + *************************************************************************/ + +static struct clk *ep93xx_ohci_host_clock; + +static int ep93xx_ohci_power_on(struct platform_device *pdev) +{ + if (!ep93xx_ohci_host_clock) { + ep93xx_ohci_host_clock = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(ep93xx_ohci_host_clock)) + return PTR_ERR(ep93xx_ohci_host_clock); + } + + return clk_enable(ep93xx_ohci_host_clock); +} + +static void ep93xx_ohci_power_off(struct platform_device *pdev) +{ + clk_disable(ep93xx_ohci_host_clock); +} + +static struct usb_ohci_pdata ep93xx_ohci_pdata = { + .power_on = ep93xx_ohci_power_on, + .power_off = ep93xx_ohci_power_off, + .power_suspend = ep93xx_ohci_power_off, +}; static struct resource ep93xx_ohci_resources[] = { DEFINE_RES_MEM(EP93XX_USB_PHYS_BASE, 0x1000), DEFINE_RES_IRQ(IRQ_EP93XX_USB), }; +static u64 ep93xx_ohci_dma_mask = DMA_BIT_MASK(32); static struct platform_device ep93xx_ohci_device = { - .name = "ep93xx-ohci", + .name = "ohci-platform", .id = -1, + .num_resources = ARRAY_SIZE(ep93xx_ohci_resources), + .resource = ep93xx_ohci_resources, .dev = { - .dma_mask = &ep93xx_ohci_device.dev.coherent_dma_mask, + .dma_mask = &ep93xx_ohci_dma_mask, .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &ep93xx_ohci_pdata, }, - .num_resources = ARRAY_SIZE(ep93xx_ohci_resources), - .resource = ep93xx_ohci_resources, }; - /************************************************************************* * EP93xx physmap'ed flash *************************************************************************/ diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig index 56fe819ee10b..f9d67a0acb2a 100644 --- a/arch/arm/mach-exynos/Kconfig +++ b/arch/arm/mach-exynos/Kconfig @@ -14,19 +14,28 @@ menu "SAMSUNG EXYNOS SoCs Support" config ARCH_EXYNOS4 bool "SAMSUNG EXYNOS4" default y + select ARM_AMBA + select CLKSRC_OF + select CLKSRC_SAMSUNG_PWM if CPU_EXYNOS4210 + select CPU_EXYNOS4210 select GIC_NON_BANKED + select KEYBOARD_SAMSUNG if INPUT_KEYBOARD select HAVE_ARM_SCU if SMP select HAVE_SMP select MIGHT_HAVE_CACHE_L2X0 select PINCTRL + select S5P_DEV_MFC help Samsung EXYNOS4 SoCs based systems config ARCH_EXYNOS5 bool "SAMSUNG EXYNOS5" + select ARM_AMBA + select CLKSRC_OF select HAVE_ARM_SCU if SMP select HAVE_SMP select PINCTRL + select USB_ARCH_HAS_XHCI help Samsung EXYNOS5 (Cortex-A15) SoC based systems @@ -110,35 +119,6 @@ config SOC_EXYNOS5440 help Enable EXYNOS5440 SoC support -comment "Flattened Device Tree based board for EXYNOS SoCs" - -config MACH_EXYNOS4_DT - bool "Samsung Exynos4 Machine using device tree" - default y - depends on ARCH_EXYNOS4 - select ARM_AMBA - select CLKSRC_OF - select CLKSRC_SAMSUNG_PWM if CPU_EXYNOS4210 - select CPU_EXYNOS4210 - select KEYBOARD_SAMSUNG if INPUT_KEYBOARD - select S5P_DEV_MFC - help - Machine support for Samsung Exynos4 machine with device tree enabled. - Select this if a fdt blob is available for the Exynos4 SoC based board. - Note: This is under development and not all peripherals can be supported - with this machine file. - -config MACH_EXYNOS5_DT - bool "SAMSUNG EXYNOS5 Machine using device tree" - default y - depends on ARCH_EXYNOS5 - select ARM_AMBA - select CLKSRC_OF - select USB_ARCH_HAS_XHCI - help - Machine support for Samsung EXYNOS5 machine with device tree enabled. - Select this if a fdt blob is available for the EXYNOS5 SoC based board. - endmenu endif diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile index 53696154aead..8930b66b4abd 100644 --- a/arch/arm/mach-exynos/Makefile +++ b/arch/arm/mach-exynos/Makefile @@ -32,5 +32,5 @@ AFLAGS_exynos-smc.o :=-Wa,-march=armv7-a$(plus_sec) # machine support -obj-$(CONFIG_MACH_EXYNOS4_DT) += mach-exynos4-dt.o -obj-$(CONFIG_MACH_EXYNOS5_DT) += mach-exynos5-dt.o +obj-$(CONFIG_ARCH_EXYNOS4) += mach-exynos4-dt.o +obj-$(CONFIG_ARCH_EXYNOS5) += mach-exynos5-dt.o diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c index ba95e5db2501..61d2906ccefb 100644 --- a/arch/arm/mach-exynos/common.c +++ b/arch/arm/mach-exynos/common.c @@ -26,10 +26,9 @@ #include <linux/export.h> #include <linux/irqdomain.h> #include <linux/of_address.h> -#include <linux/clocksource.h> -#include <linux/clk-provider.h> #include <linux/irqchip/arm-gic.h> #include <linux/irqchip/chained_irq.h> +#include <linux/platform_device.h> #include <asm/proc-fns.h> #include <asm/exception.h> @@ -294,6 +293,16 @@ void exynos5_restart(enum reboot_mode mode, const char *cmd) __raw_writel(val, addr); } +static struct platform_device exynos_cpuidle = { + .name = "exynos_cpuidle", + .id = -1, +}; + +void __init exynos_cpuidle_init(void) +{ + platform_device_register(&exynos_cpuidle); +} + void __init exynos_init_late(void) { if (of_machine_is_compatible("samsung,exynos5440")) @@ -367,12 +376,6 @@ static void __init exynos5_map_io(void) iotable_init(exynos5250_iodesc, ARRAY_SIZE(exynos5250_iodesc)); } -void __init exynos_init_time(void) -{ - of_clk_init(NULL); - clocksource_of_init(); -} - struct bus_type exynos_subsys = { .name = "exynos-core", .dev_name = "exynos-core", diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h index 8646a141ae46..ff9b6a9419b0 100644 --- a/arch/arm/mach-exynos/common.h +++ b/arch/arm/mach-exynos/common.h @@ -16,12 +16,12 @@ #include <linux/of.h> void mct_init(void __iomem *base, int irq_g0, int irq_l0, int irq_l1); -void exynos_init_time(void); struct map_desc; void exynos_init_io(void); void exynos4_restart(enum reboot_mode mode, const char *cmd); void exynos5_restart(enum reboot_mode mode, const char *cmd); +void exynos_cpuidle_init(void); void exynos_init_late(void); void exynos_firmware_init(void); diff --git a/arch/arm/mach-exynos/cpuidle.c b/arch/arm/mach-exynos/cpuidle.c index ac139226d63c..ddbfe8709fe7 100644 --- a/arch/arm/mach-exynos/cpuidle.c +++ b/arch/arm/mach-exynos/cpuidle.c @@ -15,6 +15,7 @@ #include <linux/io.h> #include <linux/export.h> #include <linux/time.h> +#include <linux/platform_device.h> #include <asm/proc-fns.h> #include <asm/smp_scu.h> @@ -192,7 +193,7 @@ static void __init exynos5_core_down_clk(void) __raw_writel(tmp, EXYNOS5_PWR_CTRL2); } -static int __init exynos4_init_cpuidle(void) +static int exynos_cpuidle_probe(struct platform_device *pdev) { int cpu_id, ret; struct cpuidle_device *device; @@ -205,7 +206,7 @@ static int __init exynos4_init_cpuidle(void) ret = cpuidle_register_driver(&exynos4_idle_driver); if (ret) { - printk(KERN_ERR "CPUidle failed to register driver\n"); + dev_err(&pdev->dev, "failed to register cpuidle driver\n"); return ret; } @@ -219,11 +220,20 @@ static int __init exynos4_init_cpuidle(void) ret = cpuidle_register_device(device); if (ret) { - printk(KERN_ERR "CPUidle register device failed\n"); + dev_err(&pdev->dev, "failed to register cpuidle device\n"); return ret; } } return 0; } -device_initcall(exynos4_init_cpuidle); + +static struct platform_driver exynos_cpuidle_driver = { + .probe = exynos_cpuidle_probe, + .driver = { + .name = "exynos_cpuidle", + .owner = THIS_MODULE, + }, +}; + +module_platform_driver(exynos_cpuidle_driver); diff --git a/arch/arm/mach-exynos/include/mach/regs-pmu.h b/arch/arm/mach-exynos/include/mach/regs-pmu.h index 57344b7e98ce..2cdb63e8ce5c 100644 --- a/arch/arm/mach-exynos/include/mach/regs-pmu.h +++ b/arch/arm/mach-exynos/include/mach/regs-pmu.h @@ -44,11 +44,6 @@ #define S5P_DAC_PHY_CONTROL S5P_PMUREG(0x070C) #define S5P_DAC_PHY_ENABLE (1 << 0) -#define S5P_MIPI_DPHY_CONTROL(n) S5P_PMUREG(0x0710 + (n) * 4) -#define S5P_MIPI_DPHY_ENABLE (1 << 0) -#define S5P_MIPI_DPHY_SRESETN (1 << 1) -#define S5P_MIPI_DPHY_MRESETN (1 << 2) - #define S5P_INFORM0 S5P_PMUREG(0x0800) #define S5P_INFORM1 S5P_PMUREG(0x0804) #define S5P_INFORM2 S5P_PMUREG(0x0808) diff --git a/arch/arm/mach-exynos/mach-exynos4-dt.c b/arch/arm/mach-exynos/mach-exynos4-dt.c index 0099c6c13bba..4603e6bd424b 100644 --- a/arch/arm/mach-exynos/mach-exynos4-dt.c +++ b/arch/arm/mach-exynos/mach-exynos4-dt.c @@ -11,12 +11,8 @@ * published by the Free Software Foundation. */ -#include <linux/kernel.h> #include <linux/of_platform.h> #include <linux/of_fdt.h> -#include <linux/serial_core.h> -#include <linux/memblock.h> -#include <linux/clocksource.h> #include <asm/mach/arch.h> #include <plat/mfc.h> @@ -25,6 +21,8 @@ static void __init exynos4_dt_machine_init(void) { + exynos_cpuidle_init(); + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); } @@ -54,7 +52,6 @@ DT_MACHINE_START(EXYNOS4210_DT, "Samsung Exynos4 (Flattened Device Tree)") .init_early = exynos_firmware_init, .init_machine = exynos4_dt_machine_init, .init_late = exynos_init_late, - .init_time = exynos_init_time, .dt_compat = exynos4_dt_compat, .restart = exynos4_restart, .reserve = exynos4_reserve, diff --git a/arch/arm/mach-exynos/mach-exynos5-dt.c b/arch/arm/mach-exynos/mach-exynos5-dt.c index f874b773ca13..1fe075a70c1e 100644 --- a/arch/arm/mach-exynos/mach-exynos5-dt.c +++ b/arch/arm/mach-exynos/mach-exynos5-dt.c @@ -11,14 +11,10 @@ #include <linux/of_platform.h> #include <linux/of_fdt.h> -#include <linux/memblock.h> #include <linux/io.h> -#include <linux/clocksource.h> #include <asm/mach/arch.h> #include <mach/regs-pmu.h> - -#include <plat/cpu.h> #include <plat/mfc.h> #include "common.h" @@ -47,6 +43,8 @@ static void __init exynos5_dt_machine_init(void) } } + exynos_cpuidle_init(); + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); } @@ -76,7 +74,6 @@ DT_MACHINE_START(EXYNOS5_DT, "SAMSUNG EXYNOS5 (Flattened Device Tree)") .map_io = exynos_init_io, .init_machine = exynos5_dt_machine_init, .init_late = exynos_init_late, - .init_time = exynos_init_time, .dt_compat = exynos5_dt_compat, .restart = exynos5_restart, .reserve = exynos5_reserve, diff --git a/arch/arm/mach-footbridge/netwinder-hw.c b/arch/arm/mach-footbridge/netwinder-hw.c index 1fd2cf097e30..eb1fa5c84723 100644 --- a/arch/arm/mach-footbridge/netwinder-hw.c +++ b/arch/arm/mach-footbridge/netwinder-hw.c @@ -692,14 +692,14 @@ static void netwinder_led_set(struct led_classdev *cdev, unsigned long flags; u32 reg; - spin_lock_irqsave(&nw_gpio_lock, flags); + raw_spin_lock_irqsave(&nw_gpio_lock, flags); reg = nw_gpio_read(); if (b != LED_OFF) reg &= ~led->mask; else reg |= led->mask; nw_gpio_modify_op(led->mask, reg); - spin_unlock_irqrestore(&nw_gpio_lock, flags); + raw_spin_unlock_irqrestore(&nw_gpio_lock, flags); } static enum led_brightness netwinder_led_get(struct led_classdev *cdev) @@ -709,9 +709,9 @@ static enum led_brightness netwinder_led_get(struct led_classdev *cdev) unsigned long flags; u32 reg; - spin_lock_irqsave(&nw_gpio_lock, flags); + raw_spin_lock_irqsave(&nw_gpio_lock, flags); reg = nw_gpio_read(); - spin_unlock_irqrestore(&nw_gpio_lock, flags); + raw_spin_unlock_irqrestore(&nw_gpio_lock, flags); return (reg & led->mask) ? LED_OFF : LED_FULL; } diff --git a/arch/arm/mach-gemini/gpio.c b/arch/arm/mach-gemini/gpio.c index 70bfa571b24b..f8cb5710d6ee 100644 --- a/arch/arm/mach-gemini/gpio.c +++ b/arch/arm/mach-gemini/gpio.c @@ -21,9 +21,9 @@ #include <mach/hardware.h> #include <mach/irqs.h> -#include <mach/gpio.h> #define GPIO_BASE(x) IO_ADDRESS(GEMINI_GPIO_BASE(x)) +#define irq_to_gpio(x) ((x) - GPIO_IRQ_BASE) /* GPIO registers definition */ #define GPIO_DATA_OUT 0x0 diff --git a/arch/arm/mach-gemini/include/mach/gpio.h b/arch/arm/mach-gemini/include/mach/gpio.h deleted file mode 100644 index 40a0527bada7..000000000000 --- a/arch/arm/mach-gemini/include/mach/gpio.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Gemini gpiolib specific defines - * - * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#ifndef __MACH_GPIO_H__ -#define __MACH_GPIO_H__ - -#include <mach/irqs.h> - -#define gpio_to_irq(x) ((x) + GPIO_IRQ_BASE) -#define irq_to_gpio(x) ((x) - GPIO_IRQ_BASE) - -#endif /* __MACH_GPIO_H__ */ diff --git a/arch/arm/mach-gemini/time.c b/arch/arm/mach-gemini/time.c index 21dc5a89d1c4..0a63c4d25b64 100644 --- a/arch/arm/mach-gemini/time.c +++ b/arch/arm/mach-gemini/time.c @@ -13,6 +13,8 @@ #include <mach/hardware.h> #include <mach/global_reg.h> #include <asm/mach/time.h> +#include <linux/clockchips.h> +#include <linux/clocksource.h> /* * Register definitions for the timers @@ -33,19 +35,89 @@ #define TIMER_3_CR_CLOCK (1 << 7) #define TIMER_3_CR_INT (1 << 8) +static unsigned int tick_rate; + +static int gemini_timer_set_next_event(unsigned long cycles, + struct clock_event_device *evt) +{ + u32 cr; + + cr = readl(TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE))); + + /* This may be overdoing it, feel free to test without this */ + cr &= ~TIMER_2_CR_ENABLE; + cr &= ~TIMER_2_CR_INT; + writel(cr, TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE))); + + /* Set next event */ + writel(cycles, TIMER_COUNT(IO_ADDRESS(GEMINI_TIMER2_BASE))); + writel(cycles, TIMER_LOAD(IO_ADDRESS(GEMINI_TIMER2_BASE))); + cr |= TIMER_2_CR_ENABLE; + cr |= TIMER_2_CR_INT; + writel(cr, TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE))); + + return 0; +} + +static void gemini_timer_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + u32 period = DIV_ROUND_CLOSEST(tick_rate, HZ); + u32 cr; + + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + /* Start the timer */ + writel(period, + TIMER_COUNT(IO_ADDRESS(GEMINI_TIMER2_BASE))); + writel(period, + TIMER_LOAD(IO_ADDRESS(GEMINI_TIMER2_BASE))); + cr = readl(TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE))); + cr |= TIMER_2_CR_ENABLE; + cr |= TIMER_2_CR_INT; + writel(cr, TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE))); + break; + case CLOCK_EVT_MODE_ONESHOT: + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_SHUTDOWN: + case CLOCK_EVT_MODE_RESUME: + /* + * Disable also for oneshot: the set_next() call will + * arm the timer instead. + */ + cr = readl(TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE))); + cr &= ~TIMER_2_CR_ENABLE; + cr &= ~TIMER_2_CR_INT; + writel(cr, TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE))); + break; + default: + break; + } +} + +/* Use TIMER2 as clock event */ +static struct clock_event_device gemini_clockevent = { + .name = "TIMER2", + .rating = 300, /* Reasonably fast and accurate clock event */ + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, + .set_next_event = gemini_timer_set_next_event, + .set_mode = gemini_timer_set_mode, +}; + /* * IRQ handler for the timer */ static irqreturn_t gemini_timer_interrupt(int irq, void *dev_id) { - timer_tick(); + struct clock_event_device *evt = &gemini_clockevent; + evt->event_handler(evt); return IRQ_HANDLED; } static struct irqaction gemini_timer_irq = { .name = "Gemini Timer Tick", - .flags = IRQF_DISABLED | IRQF_TIMER, + .flags = IRQF_TIMER, .handler = gemini_timer_interrupt, }; @@ -54,9 +126,9 @@ static struct irqaction gemini_timer_irq = { */ void __init gemini_timer_init(void) { - unsigned int tick_rate, reg_v; + u32 reg_v; - reg_v = __raw_readl(IO_ADDRESS(GEMINI_GLOBAL_BASE + GLOBAL_STATUS)); + reg_v = readl(IO_ADDRESS(GEMINI_GLOBAL_BASE + GLOBAL_STATUS)); tick_rate = REG_TO_AHB_SPEED(reg_v) * 1000000; printk(KERN_INFO "Bus: %dMHz", tick_rate / 1000000); @@ -82,8 +154,17 @@ void __init gemini_timer_init(void) * Make irqs happen for the system timer */ setup_irq(IRQ_TIMER2, &gemini_timer_irq); - /* Start the timer */ - __raw_writel(tick_rate / HZ, TIMER_COUNT(IO_ADDRESS(GEMINI_TIMER2_BASE))); - __raw_writel(tick_rate / HZ, TIMER_LOAD(IO_ADDRESS(GEMINI_TIMER2_BASE))); - __raw_writel(TIMER_2_CR_ENABLE | TIMER_2_CR_INT, TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE))); + + /* Enable and use TIMER1 as clock source */ + writel(0xffffffff, TIMER_COUNT(IO_ADDRESS(GEMINI_TIMER1_BASE))); + writel(0xffffffff, TIMER_LOAD(IO_ADDRESS(GEMINI_TIMER1_BASE))); + writel(TIMER_1_CR_ENABLE, TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE))); + if (clocksource_mmio_init(TIMER_COUNT(IO_ADDRESS(GEMINI_TIMER1_BASE)), + "TIMER1", tick_rate, 300, 32, + clocksource_mmio_readl_up)) + pr_err("timer: failed to initialize gemini clock source\n"); + + /* Configure and register the clockevent */ + clockevents_config_and_register(&gemini_clockevent, tick_rate, + 1, 0xffffffff); } diff --git a/arch/arm/mach-highbank/Kconfig b/arch/arm/mach-highbank/Kconfig index 8e8437dea3ce..0aded64a9ebc 100644 --- a/arch/arm/mach-highbank/Kconfig +++ b/arch/arm/mach-highbank/Kconfig @@ -4,15 +4,16 @@ config ARCH_HIGHBANK select ARCH_HAS_CPUFREQ select ARCH_HAS_HOLES_MEMORYMODEL select ARCH_HAS_OPP + select ARCH_SUPPORTS_BIG_ENDIAN select ARCH_WANT_OPTIONAL_GPIOLIB select ARM_AMBA - select ARM_ERRATA_764369 + select ARM_ERRATA_764369 if SMP select ARM_ERRATA_775420 - select ARM_ERRATA_798181 + select ARM_ERRATA_798181 if SMP select ARM_GIC + select ARM_PSCI select ARM_TIMER_SP804 select CACHE_L2X0 - select CLKDEV_LOOKUP select COMMON_CLK select CPU_V7 select GENERIC_CLOCKEVENTS diff --git a/arch/arm/mach-highbank/Makefile b/arch/arm/mach-highbank/Makefile index 8a1ef576d79f..55840f414d3e 100644 --- a/arch/arm/mach-highbank/Makefile +++ b/arch/arm/mach-highbank/Makefile @@ -3,6 +3,4 @@ obj-y := highbank.o system.o smc.o plus_sec := $(call as-instr,.arch_extension sec,+sec) AFLAGS_smc.o :=-Wa,-march=armv7-a$(plus_sec) -obj-$(CONFIG_SMP) += platsmp.o -obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o obj-$(CONFIG_PM_SLEEP) += pm.o diff --git a/arch/arm/mach-highbank/core.h b/arch/arm/mach-highbank/core.h index aea1ec5ab6f8..7ec5edcd1336 100644 --- a/arch/arm/mach-highbank/core.h +++ b/arch/arm/mach-highbank/core.h @@ -3,7 +3,6 @@ #include <linux/reboot.h> -extern void highbank_set_cpu_jump(int cpu, void *jump_addr); extern void highbank_restart(enum reboot_mode, const char *); extern void __iomem *scu_base_addr; @@ -14,8 +13,5 @@ static inline void highbank_pm_init(void) {} #endif extern void highbank_smc1(int fn, int arg); -extern void highbank_cpu_die(unsigned int cpu); - -extern struct smp_operations highbank_smp_ops; #endif diff --git a/arch/arm/mach-highbank/highbank.c b/arch/arm/mach-highbank/highbank.c index 8e63ccdb0de3..b3d7e5634b83 100644 --- a/arch/arm/mach-highbank/highbank.c +++ b/arch/arm/mach-highbank/highbank.c @@ -24,11 +24,9 @@ #include <linux/of_platform.h> #include <linux/of_address.h> #include <linux/amba/bus.h> -#include <linux/clk-provider.h> +#include <linux/platform_device.h> -#include <asm/cacheflush.h> -#include <asm/cputype.h> -#include <asm/smp_plat.h> +#include <asm/psci.h> #include <asm/hardware/cache-l2x0.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> @@ -49,17 +47,6 @@ static void __init highbank_scu_map_io(void) scu_base_addr = ioremap(base, SZ_4K); } -#define HB_JUMP_TABLE_PHYS(cpu) (0x40 + (0x10 * (cpu))) -#define HB_JUMP_TABLE_VIRT(cpu) phys_to_virt(HB_JUMP_TABLE_PHYS(cpu)) - -void highbank_set_cpu_jump(int cpu, void *jump_addr) -{ - cpu = MPIDR_AFFINITY_LEVEL(cpu_logical_map(cpu), 0); - writel(virt_to_phys(jump_addr), HB_JUMP_TABLE_VIRT(cpu)); - __cpuc_flush_dcache_area(HB_JUMP_TABLE_VIRT(cpu), 16); - outer_clean_range(HB_JUMP_TABLE_PHYS(cpu), - HB_JUMP_TABLE_PHYS(cpu) + 15); -} static void highbank_l2x0_disable(void) { @@ -83,20 +70,6 @@ static void __init highbank_init_irq(void) } } -static void __init highbank_timer_init(void) -{ - struct device_node *np; - - /* Map system registers */ - np = of_find_compatible_node(NULL, NULL, "calxeda,hb-sregs"); - sregs_base = of_iomap(np, 0); - WARN_ON(!sregs_base); - - of_clk_init(NULL); - - clocksource_of_init(); -} - static void highbank_power_off(void) { highbank_set_pwr_shutdown(); @@ -153,8 +126,19 @@ static struct notifier_block highbank_platform_nb = { .notifier_call = highbank_platform_notifier, }; +static struct platform_device highbank_cpuidle_device = { + .name = "cpuidle-calxeda", +}; + static void __init highbank_init(void) { + struct device_node *np; + + /* Map system registers */ + np = of_find_compatible_node(NULL, NULL, "calxeda,hb-sregs"); + sregs_base = of_iomap(np, 0); + WARN_ON(!sregs_base); + pm_power_off = highbank_power_off; highbank_pm_init(); @@ -162,6 +146,9 @@ static void __init highbank_init(void) bus_register_notifier(&amba_bustype, &highbank_amba_nb); of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); + + if (psci_ops.cpu_suspend) + platform_device_register(&highbank_cpuidle_device); } static const char *highbank_match[] __initconst = { @@ -174,9 +161,7 @@ DT_MACHINE_START(HIGHBANK, "Highbank") #if defined(CONFIG_ZONE_DMA) && defined(CONFIG_ARM_LPAE) .dma_zone_size = (4ULL * SZ_1G), #endif - .smp = smp_ops(highbank_smp_ops), .init_irq = highbank_init_irq, - .init_time = highbank_timer_init, .init_machine = highbank_init, .dt_compat = highbank_match, .restart = highbank_restart, diff --git a/arch/arm/mach-highbank/hotplug.c b/arch/arm/mach-highbank/hotplug.c deleted file mode 100644 index a019e4e86e51..000000000000 --- a/arch/arm/mach-highbank/hotplug.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2011 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/>. - */ -#include <linux/kernel.h> -#include <asm/cacheflush.h> - -#include "core.h" -#include "sysregs.h" - -extern void secondary_startup(void); - -/* - * platform-specific code to shutdown a CPU - * - */ -void __ref highbank_cpu_die(unsigned int cpu) -{ - highbank_set_cpu_jump(cpu, phys_to_virt(0)); - - flush_cache_louis(); - highbank_set_core_pwr(); - - while (1) - cpu_do_idle(); -} diff --git a/arch/arm/mach-highbank/platsmp.c b/arch/arm/mach-highbank/platsmp.c deleted file mode 100644 index 32d75cf55cbc..000000000000 --- a/arch/arm/mach-highbank/platsmp.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2010-2011 Calxeda, Inc. - * Based on platsmp.c, Copyright (C) 2002 ARM Ltd. - * - * 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/>. - */ -#include <linux/init.h> -#include <linux/smp.h> -#include <linux/io.h> - -#include <asm/smp_scu.h> - -#include "core.h" - -extern void secondary_startup(void); - -static int highbank_boot_secondary(unsigned int cpu, struct task_struct *idle) -{ - highbank_set_cpu_jump(cpu, secondary_startup); - arch_send_wakeup_ipi_mask(cpumask_of(cpu)); - return 0; -} - -/* - * Initialise the CPU possible map early - this describes the CPUs - * which may be present or become present in the system. - */ -static void __init highbank_smp_init_cpus(void) -{ - unsigned int i, ncores = 4; - - /* sanity check */ - if (ncores > NR_CPUS) { - printk(KERN_WARNING - "highbank: no. of cores (%d) greater than configured " - "maximum of %d - clipping\n", - ncores, NR_CPUS); - ncores = NR_CPUS; - } - - for (i = 0; i < ncores; i++) - set_cpu_possible(i, true); -} - -static void __init highbank_smp_prepare_cpus(unsigned int max_cpus) -{ - if (scu_base_addr) - scu_enable(scu_base_addr); -} - -struct smp_operations highbank_smp_ops __initdata = { - .smp_init_cpus = highbank_smp_init_cpus, - .smp_prepare_cpus = highbank_smp_prepare_cpus, - .smp_boot_secondary = highbank_boot_secondary, -#ifdef CONFIG_HOTPLUG_CPU - .cpu_die = highbank_cpu_die, -#endif -}; diff --git a/arch/arm/mach-highbank/pm.c b/arch/arm/mach-highbank/pm.c index 04eddb4f4380..7f2bd85eb935 100644 --- a/arch/arm/mach-highbank/pm.c +++ b/arch/arm/mach-highbank/pm.c @@ -16,27 +16,19 @@ #include <linux/cpu_pm.h> #include <linux/init.h> -#include <linux/io.h> #include <linux/suspend.h> -#include <asm/cacheflush.h> -#include <asm/proc-fns.h> #include <asm/suspend.h> - -#include "core.h" -#include "sysregs.h" +#include <asm/psci.h> static int highbank_suspend_finish(unsigned long val) { - outer_flush_all(); - outer_disable(); - - highbank_set_pwr_suspend(); - - cpu_do_idle(); + const struct psci_power_state ps = { + .type = PSCI_POWER_STATE_TYPE_POWER_DOWN, + .affinity_level = 1, + }; - highbank_clear_pwr_request(); - return 0; + return psci_ops.cpu_suspend(ps, __pa(cpu_resume)); } static int highbank_pm_enter(suspend_state_t state) @@ -44,15 +36,11 @@ static int highbank_pm_enter(suspend_state_t state) cpu_pm_enter(); cpu_cluster_pm_enter(); - highbank_set_cpu_jump(0, cpu_resume); cpu_suspend(0, highbank_suspend_finish); cpu_cluster_pm_exit(); cpu_pm_exit(); - highbank_smc1(0x102, 0x1); - if (scu_base_addr) - scu_enable(scu_base_addr); return 0; } @@ -63,5 +51,8 @@ static const struct platform_suspend_ops highbank_pm_ops = { void __init highbank_pm_init(void) { + if (!psci_ops.cpu_suspend) + return; + suspend_set_ops(&highbank_pm_ops); } diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 29a8af6922a8..7a6e6f710068 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -4,13 +4,14 @@ config ARCH_MXC select ARM_CPU_SUSPEND if PM select ARM_PATCH_PHYS_VIRT select AUTO_ZRELADDR if !ZBOOT_ROM - select CLKDEV_LOOKUP select CLKSRC_MMIO + select COMMON_CLK select GENERIC_ALLOCATOR select GENERIC_CLOCKEVENTS select GENERIC_IRQ_CHIP select MIGHT_HAVE_CACHE_L2X0 if ARCH_MULTI_V6_V7 select MULTI_IRQ_HANDLER + select SOC_BUS select SPARSE_IRQ select USE_OF help @@ -24,7 +25,7 @@ config MXC_IRQ_PRIOR help Select this if you want to use prioritized IRQ handling. This feature prevents higher priority ISR to be interrupted - by lower priority IRQ even IRQF_DISABLED flag is not set. + by lower priority IRQ. This may be useful in embedded applications, where are strong requirements for timing. Say N here, unless you have a specialized requirement. @@ -92,14 +93,12 @@ config MACH_MX27 config SOC_IMX1 bool select ARCH_MX1 - select COMMON_CLK select CPU_ARM920T select IMX_HAVE_IOMUX_V1 select MXC_AVIC config SOC_IMX21 bool - select COMMON_CLK select CPU_ARM926T select IMX_HAVE_IOMUX_V1 select MXC_AVIC @@ -108,7 +107,6 @@ config SOC_IMX25 bool select ARCH_MX25 select ARCH_MXC_IOMUX_V3 - select COMMON_CLK select CPU_ARM926T select MXC_AVIC @@ -116,7 +114,6 @@ config SOC_IMX27 bool select ARCH_HAS_CPUFREQ select ARCH_HAS_OPP - select COMMON_CLK select CPU_ARM926T select IMX_HAVE_IOMUX_V1 select MACH_MX27 @@ -124,7 +121,6 @@ config SOC_IMX27 config SOC_IMX31 bool - select COMMON_CLK select CPU_V6 select IMX_HAVE_PLATFORM_MXC_RNGA select MXC_AVIC @@ -133,7 +129,6 @@ config SOC_IMX31 config SOC_IMX35 bool select ARCH_MXC_IOMUX_V3 - select COMMON_CLK select CPU_V6K select HAVE_EPIT select MXC_AVIC @@ -144,7 +139,6 @@ config SOC_IMX5 select ARCH_HAS_CPUFREQ select ARCH_HAS_OPP select ARCH_MXC_IOMUX_V3 - select COMMON_CLK select CPU_V7 select MXC_TZIC @@ -791,7 +785,6 @@ config SOC_IMX6Q select ARM_ERRATA_764369 if SMP select ARM_ERRATA_775420 select ARM_GIC - select COMMON_CLK select CPU_V7 select HAVE_ARM_SCU if SMP select HAVE_ARM_TWD if SMP @@ -801,6 +794,8 @@ config SOC_IMX6Q select HAVE_IMX_SRC select HAVE_SMP select MFD_SYSCON + select MIGHT_HAVE_PCI + select PCI_DOMAINS if PCI select PINCTRL select PINCTRL_IMX6Q select PL310_ERRATA_588369 if CACHE_PL310 diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 5383c589ad71..1789e2b31903 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -102,6 +102,8 @@ obj-$(CONFIG_SOC_IMX6SL) += clk-imx6sl.o mach-imx6sl.o ifeq ($(CONFIG_PM),y) obj-$(CONFIG_SOC_IMX6Q) += pm-imx6q.o headsmp.o +# i.MX6SL reuses i.MX6Q code +obj-$(CONFIG_SOC_IMX6SL) += pm-imx6q.o headsmp.o endif # i.MX5 based machines diff --git a/arch/arm/mach-imx/anatop.c b/arch/arm/mach-imx/anatop.c index ad3b755abb78..4a40bbb46183 100644 --- a/arch/arm/mach-imx/anatop.c +++ b/arch/arm/mach-imx/anatop.c @@ -16,6 +16,7 @@ #include <linux/mfd/syscon.h> #include <linux/regmap.h> #include "common.h" +#include "hardware.h" #define REG_SET 0x4 #define REG_CLR 0x8 @@ -26,6 +27,7 @@ #define ANADIG_USB1_CHRG_DETECT 0x1b0 #define ANADIG_USB2_CHRG_DETECT 0x210 #define ANADIG_DIGPROG 0x260 +#define ANADIG_DIGPROG_IMX6SL 0x280 #define BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG 0x40000 #define BM_ANADIG_REG_CORE_FET_ODRIVE 0x20000000 @@ -76,21 +78,38 @@ static void imx_anatop_usb_chrg_detect_disable(void) BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B); } -u32 imx_anatop_get_digprog(void) +void __init imx_init_revision_from_anatop(void) { struct device_node *np; void __iomem *anatop_base; - static u32 digprog; - - if (digprog) - return digprog; + unsigned int revision; + u32 digprog; + u16 offset = ANADIG_DIGPROG; np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop"); anatop_base = of_iomap(np, 0); WARN_ON(!anatop_base); - digprog = readl_relaxed(anatop_base + ANADIG_DIGPROG); + if (of_device_is_compatible(np, "fsl,imx6sl-anatop")) + offset = ANADIG_DIGPROG_IMX6SL; + digprog = readl_relaxed(anatop_base + offset); + iounmap(anatop_base); + + switch (digprog & 0xff) { + case 0: + revision = IMX_CHIP_REVISION_1_0; + break; + case 1: + revision = IMX_CHIP_REVISION_1_1; + break; + case 2: + revision = IMX_CHIP_REVISION_1_2; + break; + default: + revision = IMX_CHIP_REVISION_UNKNOWN; + } - return digprog; + mxc_set_cpu_type(digprog >> 16 & 0xff); + imx_set_soc_revision(revision); } void __init imx_anatop_init(void) diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c index 7c0dc4540aa4..ce37af26ff8c 100644 --- a/arch/arm/mach-imx/clk-imx51-imx53.c +++ b/arch/arm/mach-imx/clk-imx51-imx53.c @@ -11,8 +11,12 @@ #include <linux/clk.h> #include <linux/io.h> #include <linux/clkdev.h> +#include <linux/clk-provider.h> #include <linux/of.h> #include <linux/err.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> #include "crm-regs-imx5.h" #include "clk.h" @@ -131,8 +135,6 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil, { int i; - of_clk_init(NULL); - clk[dummy] = imx_clk_fixed("dummy", 0); clk[ckil] = imx_obtain_fixed_clock("ckil", rate_ckil); clk[osc] = imx_obtain_fixed_clock("osc", rate_osc); @@ -465,12 +467,17 @@ int __init mx51_clocks_init(unsigned long rate_ckil, unsigned long rate_osc, return 0; } -int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc, - unsigned long rate_ckih1, unsigned long rate_ckih2) +static void __init mx51_clocks_init_dt(struct device_node *np) { - int i; + mx51_clocks_init(0, 0, 0, 0); +} +CLK_OF_DECLARE(imx51_ccm, "fsl,imx51-ccm", mx51_clocks_init_dt); + +static void __init mx53_clocks_init(struct device_node *np) +{ + int i, irq; unsigned long r; - struct device_node *np; + void __iomem *base; clk[pll1_sw] = imx_clk_pllv2("pll1_sw", "osc", MX53_DPLL1_BASE); clk[pll2_sw] = imx_clk_pllv2("pll2_sw", "osc", MX53_DPLL2_BASE); @@ -529,12 +536,11 @@ int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc, pr_err("i.MX53 clk %d: register failed with %ld\n", i, PTR_ERR(clk[i])); - np = of_find_compatible_node(NULL, NULL, "fsl,imx53-ccm"); clk_data.clks = clk; clk_data.clk_num = ARRAY_SIZE(clk); of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); - mx5_clocks_common_init(rate_ckil, rate_osc, rate_ckih1, rate_ckih2); + mx5_clocks_common_init(0, 0, 0, 0); clk_register_clkdev(clk[vpu_gate], NULL, "imx53-vpu.0"); clk_register_clkdev(clk[i2c3_gate], NULL, "imx21-i2c.2"); @@ -557,9 +563,6 @@ int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc, clk_set_rate(clk[esdhc_a_podf], 200000000); clk_set_rate(clk[esdhc_b_podf], 200000000); - /* System timer */ - mxc_timer_init(MX53_IO_ADDRESS(MX53_GPT1_BASE_ADDR), MX53_INT_GPT); - clk_prepare_enable(clk[iim_gate]); imx_print_silicon_rev("i.MX53", mx53_revision()); clk_disable_unprepare(clk[iim_gate]); @@ -567,15 +570,10 @@ int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc, r = clk_round_rate(clk[usboh3_per_gate], 54000000); clk_set_rate(clk[usboh3_per_gate], r); - return 0; -} - -int __init mx51_clocks_init_dt(void) -{ - return mx51_clocks_init(0, 0, 0, 0); -} - -int __init mx53_clocks_init_dt(void) -{ - return mx53_clocks_init(0, 0, 0, 0); + np = of_find_compatible_node(NULL, NULL, "fsl,imx53-gpt"); + base = of_iomap(np, 0); + WARN_ON(!base); + irq = irq_of_parse_and_map(np, 0); + mxc_timer_init(base, irq); } +CLK_OF_DECLARE(imx53_ccm, "fsl,imx53-ccm", mx53_clocks_init); diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 9181a241d3a8..04cfd0fcb0e5 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -14,7 +14,6 @@ #include <linux/types.h> #include <linux/clk.h> #include <linux/clkdev.h> -#include <linux/delay.h> #include <linux/err.h> #include <linux/io.h> #include <linux/of.h> @@ -25,155 +24,6 @@ #include "common.h" #include "hardware.h" -#define CCR 0x0 -#define BM_CCR_WB_COUNT (0x7 << 16) -#define BM_CCR_RBC_BYPASS_COUNT (0x3f << 21) -#define BM_CCR_RBC_EN (0x1 << 27) - -#define CCGR0 0x68 -#define CCGR1 0x6c -#define CCGR2 0x70 -#define CCGR3 0x74 -#define CCGR4 0x78 -#define CCGR5 0x7c -#define CCGR6 0x80 -#define CCGR7 0x84 - -#define CLPCR 0x54 -#define BP_CLPCR_LPM 0 -#define BM_CLPCR_LPM (0x3 << 0) -#define BM_CLPCR_BYPASS_PMIC_READY (0x1 << 2) -#define BM_CLPCR_ARM_CLK_DIS_ON_LPM (0x1 << 5) -#define BM_CLPCR_SBYOS (0x1 << 6) -#define BM_CLPCR_DIS_REF_OSC (0x1 << 7) -#define BM_CLPCR_VSTBY (0x1 << 8) -#define BP_CLPCR_STBY_COUNT 9 -#define BM_CLPCR_STBY_COUNT (0x3 << 9) -#define BM_CLPCR_COSC_PWRDOWN (0x1 << 11) -#define BM_CLPCR_WB_PER_AT_LPM (0x1 << 16) -#define BM_CLPCR_WB_CORE_AT_LPM (0x1 << 17) -#define BM_CLPCR_BYP_MMDC_CH0_LPM_HS (0x1 << 19) -#define BM_CLPCR_BYP_MMDC_CH1_LPM_HS (0x1 << 21) -#define BM_CLPCR_MASK_CORE0_WFI (0x1 << 22) -#define BM_CLPCR_MASK_CORE1_WFI (0x1 << 23) -#define BM_CLPCR_MASK_CORE2_WFI (0x1 << 24) -#define BM_CLPCR_MASK_CORE3_WFI (0x1 << 25) -#define BM_CLPCR_MASK_SCU_IDLE (0x1 << 26) -#define BM_CLPCR_MASK_L2CC_IDLE (0x1 << 27) - -#define CGPR 0x64 -#define BM_CGPR_CHICKEN_BIT (0x1 << 17) - -static void __iomem *ccm_base; - -void imx6q_set_chicken_bit(void) -{ - u32 val = readl_relaxed(ccm_base + CGPR); - - val |= BM_CGPR_CHICKEN_BIT; - writel_relaxed(val, ccm_base + CGPR); -} - -static void imx6q_enable_rbc(bool enable) -{ - u32 val; - static bool last_rbc_mode; - - if (last_rbc_mode == enable) - return; - /* - * need to mask all interrupts in GPC before - * operating RBC configurations - */ - imx_gpc_mask_all(); - - /* configure RBC enable bit */ - val = readl_relaxed(ccm_base + CCR); - val &= ~BM_CCR_RBC_EN; - val |= enable ? BM_CCR_RBC_EN : 0; - writel_relaxed(val, ccm_base + CCR); - - /* configure RBC count */ - val = readl_relaxed(ccm_base + CCR); - val &= ~BM_CCR_RBC_BYPASS_COUNT; - val |= enable ? BM_CCR_RBC_BYPASS_COUNT : 0; - writel(val, ccm_base + CCR); - - /* - * need to delay at least 2 cycles of CKIL(32K) - * due to hardware design requirement, which is - * ~61us, here we use 65us for safe - */ - udelay(65); - - /* restore GPC interrupt mask settings */ - imx_gpc_restore_all(); - - last_rbc_mode = enable; -} - -static void imx6q_enable_wb(bool enable) -{ - u32 val; - static bool last_wb_mode; - - if (last_wb_mode == enable) - return; - - /* configure well bias enable bit */ - val = readl_relaxed(ccm_base + CLPCR); - val &= ~BM_CLPCR_WB_PER_AT_LPM; - val |= enable ? BM_CLPCR_WB_PER_AT_LPM : 0; - writel_relaxed(val, ccm_base + CLPCR); - - /* configure well bias count */ - val = readl_relaxed(ccm_base + CCR); - val &= ~BM_CCR_WB_COUNT; - val |= enable ? BM_CCR_WB_COUNT : 0; - writel_relaxed(val, ccm_base + CCR); - - last_wb_mode = enable; -} - -int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) -{ - u32 val = readl_relaxed(ccm_base + CLPCR); - - val &= ~BM_CLPCR_LPM; - switch (mode) { - case WAIT_CLOCKED: - imx6q_enable_wb(false); - imx6q_enable_rbc(false); - break; - case WAIT_UNCLOCKED: - val |= 0x1 << BP_CLPCR_LPM; - val |= BM_CLPCR_ARM_CLK_DIS_ON_LPM; - break; - case STOP_POWER_ON: - val |= 0x2 << BP_CLPCR_LPM; - break; - case WAIT_UNCLOCKED_POWER_OFF: - val |= 0x1 << BP_CLPCR_LPM; - val &= ~BM_CLPCR_VSTBY; - val &= ~BM_CLPCR_SBYOS; - break; - case STOP_POWER_OFF: - val |= 0x2 << BP_CLPCR_LPM; - val |= 0x3 << BP_CLPCR_STBY_COUNT; - val |= BM_CLPCR_VSTBY; - val |= BM_CLPCR_SBYOS; - imx6q_enable_wb(true); - imx6q_enable_rbc(true); - break; - default: - return -EINVAL; - } - - writel_relaxed(val, ccm_base + CLPCR); - - return 0; -} - static const char *step_sels[] = { "osc", "pll2_pfd2_396m", }; static const char *pll1_sw_sels[] = { "pll1_sys", "step", }; static const char *periph_pre_sels[] = { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll2_198m", }; @@ -182,7 +32,7 @@ static const char *periph2_clk2_sels[] = { "pll3_usb_otg", "pll2_bus", }; static const char *periph_sels[] = { "periph_pre", "periph_clk2", }; static const char *periph2_sels[] = { "periph2_pre", "periph2_clk2", }; static const char *axi_sels[] = { "periph", "pll2_pfd2_396m", "periph", "pll3_pfd1_540m", }; -static const char *audio_sels[] = { "pll4_post_div", "pll3_pfd2_508m", "pll3_pfd3_454m", "pll3_usb_otg", }; +static const char *audio_sels[] = { "pll4_audio_div", "pll3_pfd2_508m", "pll3_pfd3_454m", "pll3_usb_otg", }; static const char *gpu_axi_sels[] = { "axi", "ahb", }; static const char *gpu2d_core_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", }; static const char *gpu3d_core_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd2_396m", }; @@ -196,7 +46,7 @@ static const char *ipu2_di0_sels[] = { "ipu2_di0_pre", "dummy", "dummy", "ldb_di static const char *ipu2_di1_sels[] = { "ipu2_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; static const char *hsi_tx_sels[] = { "pll3_120m", "pll2_pfd2_396m", }; static const char *pcie_axi_sels[] = { "axi", "ahb", }; -static const char *ssi_sels[] = { "pll3_pfd2_508m", "pll3_pfd3_454m", "pll4_post_div", }; +static const char *ssi_sels[] = { "pll3_pfd2_508m", "pll3_pfd3_454m", "pll4_audio_div", }; static const char *usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", }; static const char *enfc_sels[] = { "pll2_pfd0_352m", "pll2_bus", "pll3_usb_otg", "pll2_pfd2_396m", }; static const char *emi_sels[] = { "pll2_pfd2_396m", "pll3_usb_otg", "axi", "pll2_pfd0_352m", }; @@ -205,7 +55,7 @@ static const char *vdo_axi_sels[] = { "axi", "ahb", }; static const char *vpu_axi_sels[] = { "axi", "pll2_pfd2_396m", "pll2_pfd0_352m", }; static const char *cko1_sels[] = { "pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5_video_div", "dummy", "axi", "enfc", "ipu1_di0", "ipu1_di1", "ipu2_di0", - "ipu2_di1", "ahb", "ipg", "ipg_per", "ckil", "pll4_post_div", }; + "ipu2_di1", "ahb", "ipg", "ipg_per", "ckil", "pll4_audio_div", }; static const char *cko2_sels[] = { "mmdc_ch0_axi", "mmdc_ch1_axi", "usdhc4", "usdhc1", "gpu2d_axi", "dummy", "ecspi_root", "gpu3d_axi", @@ -217,6 +67,11 @@ static const char *cko2_sels[] = { "uart_serial", "spdif", "asrc", "hsi_tx", }; static const char *cko_sels[] = { "cko1", "cko2", }; +static const char *lvds_sels[] = { + "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", + "pll4_audio", "pll5_video", "pll8_mlb", "enet_ref", + "pcie_ref", "sata_ref", +}; enum mx6q_clks { dummy, ckil, ckih, osc, pll2_pfd0_352m, pll2_pfd1_594m, pll2_pfd2_396m, @@ -251,7 +106,8 @@ enum mx6q_clks { ssi2_ipg, ssi3_ipg, rom, usbphy1, usbphy2, ldb_di0_div_3_5, ldb_di1_div_3_5, sata_ref, sata_ref_100m, pcie_ref, pcie_ref_125m, enet_ref, usbphy1_gate, usbphy2_gate, pll4_post_div, pll5_post_div, pll5_video_div, eim_slow, - spdif, cko2_sel, cko2_podf, cko2, cko, vdoa, clk_max + spdif, cko2_sel, cko2_podf, cko2, cko, vdoa, pll4_audio_div, + lvds1_sel, lvds2_sel, lvds1_gate, lvds2_gate, clk_max }; static struct clk *clk[clk_max]; @@ -266,13 +122,14 @@ static struct clk_div_table clk_enet_ref_table[] = { { .val = 1, .div = 10, }, { .val = 2, .div = 5, }, { .val = 3, .div = 4, }, + { /* sentinel */ } }; static struct clk_div_table post_div_table[] = { { .val = 2, .div = 1, }, { .val = 1, .div = 2, }, { .val = 0, .div = 4, }, - { } + { /* sentinel */ } }; static struct clk_div_table video_div_table[] = { @@ -280,7 +137,7 @@ static struct clk_div_table video_div_table[] = { { .val = 1, .div = 2, }, { .val = 2, .div = 1, }, { .val = 3, .div = 4, }, - { } + { /* sentinel */ } }; static void __init imx6q_clocks_init(struct device_node *ccm_node) @@ -300,7 +157,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) WARN_ON(!base); /* Audio/video PLL post dividers do not work on i.MX6q revision 1.0 */ - if (cpu_is_imx6q() && imx6q_revision() == IMX_CHIP_REVISION_1_0) { + if (cpu_is_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_1_0) { post_div_table[1].div = 1; post_div_table[2].div = 1; video_div_table[1].div = 1; @@ -342,6 +199,18 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) base + 0xe0, 0, 2, 0, clk_enet_ref_table, &imx_ccm_lock); + clk[lvds1_sel] = imx_clk_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels)); + clk[lvds2_sel] = imx_clk_mux("lvds2_sel", base + 0x160, 5, 5, lvds_sels, ARRAY_SIZE(lvds_sels)); + + /* + * lvds1_gate and lvds2_gate are pseudo-gates. Both can be + * independently configured as clock inputs or outputs. We treat + * the "output_enable" bit as a gate, even though it's really just + * enabling clock output. + */ + clk[lvds1_gate] = imx_clk_gate("lvds1_gate", "dummy", base + 0x160, 10); + clk[lvds2_gate] = imx_clk_gate("lvds2_gate", "dummy", base + 0x160, 11); + /* name parent_name reg idx */ clk[pll2_pfd0_352m] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus", base + 0x100, 0); clk[pll2_pfd1_594m] = imx_clk_pfd("pll2_pfd1_594m", "pll2_bus", base + 0x100, 1); @@ -359,13 +228,15 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk[twd] = imx_clk_fixed_factor("twd", "arm", 1, 2); clk[pll4_post_div] = clk_register_divider_table(NULL, "pll4_post_div", "pll4_audio", CLK_SET_RATE_PARENT, base + 0x70, 19, 2, 0, post_div_table, &imx_ccm_lock); + clk[pll4_audio_div] = clk_register_divider(NULL, "pll4_audio_div", "pll4_post_div", CLK_SET_RATE_PARENT, base + 0x170, 15, 1, 0, &imx_ccm_lock); clk[pll5_post_div] = clk_register_divider_table(NULL, "pll5_post_div", "pll5_video", CLK_SET_RATE_PARENT, base + 0xa0, 19, 2, 0, post_div_table, &imx_ccm_lock); clk[pll5_video_div] = clk_register_divider_table(NULL, "pll5_video_div", "pll5_post_div", CLK_SET_RATE_PARENT, base + 0x170, 30, 2, 0, video_div_table, &imx_ccm_lock); np = ccm_node; base = of_iomap(np, 0); WARN_ON(!base); - ccm_base = base; + + imx6q_pm_set_ccm_base(base); /* name reg shift width parent_names num_parents */ clk[step] = imx_clk_mux("step", base + 0xc, 8, 1, step_sels, ARRAY_SIZE(step_sels)); @@ -428,7 +299,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk[asrc_podf] = imx_clk_divider("asrc_podf", "asrc_pred", base + 0x30, 9, 3); clk[spdif_pred] = imx_clk_divider("spdif_pred", "spdif_sel", base + 0x30, 25, 3); clk[spdif_podf] = imx_clk_divider("spdif_podf", "spdif_pred", base + 0x30, 22, 3); - clk[can_root] = imx_clk_divider("can_root", "pll3_usb_otg", base + 0x20, 2, 6); + clk[can_root] = imx_clk_divider("can_root", "pll3_60m", base + 0x20, 2, 6); clk[ecspi_root] = imx_clk_divider("ecspi_root", "pll3_60m", base + 0x38, 19, 6); clk[gpu2d_core_podf] = imx_clk_divider("gpu2d_core_podf", "gpu2d_core_sel", base + 0x18, 23, 3); clk[gpu3d_core_podf] = imx_clk_divider("gpu3d_core_podf", "gpu3d_core_sel", base + 0x18, 26, 3); @@ -573,7 +444,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk_register_clkdev(clk[pll4_post_div], "pll4_post_div", NULL); clk_register_clkdev(clk[pll4_audio], "pll4_audio", NULL); - if ((imx6q_revision() != IMX_CHIP_REVISION_1_0) || cpu_is_imx6dl()) { + if ((imx_get_soc_revision() != IMX_CHIP_REVISION_1_0) || + cpu_is_imx6dl()) { clk_set_parent(clk[ldb_di0_sel], clk[pll5_video_div]); clk_set_parent(clk[ldb_di1_sel], clk[pll5_video_div]); } @@ -603,8 +475,9 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) if (ret) pr_warn("failed to set up CLKO: %d\n", ret); - /* Set initial power mode */ - imx6q_set_lpm(WAIT_CLOCKED); + /* All existing boards with PCIe use LVDS1 */ + if (IS_ENABLED(CONFIG_PCI_IMX6)) + clk_set_parent(clk[lvds1_sel], clk[sata_ref]); np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpt"); base = of_iomap(np, 0); diff --git a/arch/arm/mach-imx/clk-imx6sl.c b/arch/arm/mach-imx/clk-imx6sl.c index a5c3c5d21aee..c0c4ef55e35b 100644 --- a/arch/arm/mach-imx/clk-imx6sl.c +++ b/arch/arm/mach-imx/clk-imx6sl.c @@ -127,6 +127,9 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node) base = of_iomap(np, 0); WARN_ON(!base); + /* Reuse imx6q pm code */ + imx6q_pm_set_ccm_base(base); + /* name reg shift width parent_names num_parents */ clks[IMX6SL_CLK_STEP] = imx_clk_mux("step", base + 0xc, 8, 1, step_sels, ARRAY_SIZE(step_sels)); clks[IMX6SL_CLK_PLL1_SW] = imx_clk_mux("pll1_sw", base + 0xc, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels)); diff --git a/arch/arm/mach-imx/clk-pllv3.c b/arch/arm/mach-imx/clk-pllv3.c index f6640b6a7b31..61364050fccd 100644 --- a/arch/arm/mach-imx/clk-pllv3.c +++ b/arch/arm/mach-imx/clk-pllv3.c @@ -12,6 +12,7 @@ #include <linux/clk.h> #include <linux/clk-provider.h> +#include <linux/delay.h> #include <linux/io.h> #include <linux/slab.h> #include <linux/jiffies.h> @@ -45,33 +46,49 @@ struct clk_pllv3 { #define to_clk_pllv3(_hw) container_of(_hw, struct clk_pllv3, hw) +static int clk_pllv3_wait_lock(struct clk_pllv3 *pll) +{ + unsigned long timeout = jiffies + msecs_to_jiffies(10); + u32 val = readl_relaxed(pll->base) & BM_PLL_POWER; + + /* No need to wait for lock when pll is not powered up */ + if ((pll->powerup_set && !val) || (!pll->powerup_set && val)) + return 0; + + /* Wait for PLL to lock */ + do { + if (readl_relaxed(pll->base) & BM_PLL_LOCK) + break; + if (time_after(jiffies, timeout)) + break; + usleep_range(50, 500); + } while (1); + + return readl_relaxed(pll->base) & BM_PLL_LOCK ? 0 : -ETIMEDOUT; +} + static int clk_pllv3_prepare(struct clk_hw *hw) { struct clk_pllv3 *pll = to_clk_pllv3(hw); - unsigned long timeout; u32 val; + int ret; val = readl_relaxed(pll->base); - val &= ~BM_PLL_BYPASS; if (pll->powerup_set) val |= BM_PLL_POWER; else val &= ~BM_PLL_POWER; writel_relaxed(val, pll->base); - timeout = jiffies + msecs_to_jiffies(10); - /* Wait for PLL to lock */ - do { - if (readl_relaxed(pll->base) & BM_PLL_LOCK) - break; - if (time_after(jiffies, timeout)) - break; - } while (1); + ret = clk_pllv3_wait_lock(pll); + if (ret) + return ret; - if (readl_relaxed(pll->base) & BM_PLL_LOCK) - return 0; - else - return -ETIMEDOUT; + val = readl_relaxed(pll->base); + val &= ~BM_PLL_BYPASS; + writel_relaxed(val, pll->base); + + return 0; } static void clk_pllv3_unprepare(struct clk_hw *hw) @@ -146,7 +163,7 @@ static int clk_pllv3_set_rate(struct clk_hw *hw, unsigned long rate, val |= div; writel_relaxed(val, pll->base); - return 0; + return clk_pllv3_wait_lock(pll); } static const struct clk_ops clk_pllv3_ops = { @@ -202,7 +219,7 @@ static int clk_pllv3_sys_set_rate(struct clk_hw *hw, unsigned long rate, val |= div; writel_relaxed(val, pll->base); - return 0; + return clk_pllv3_wait_lock(pll); } static const struct clk_ops clk_pllv3_sys_ops = { @@ -276,7 +293,7 @@ static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate, writel_relaxed(mfn, pll->base + PLL_NUM_OFFSET); writel_relaxed(mfd, pll->base + PLL_DENOM_OFFSET); - return 0; + return clk_pllv3_wait_lock(pll); } static const struct clk_ops clk_pllv3_av_ops = { diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index 4517fd760bfc..24a7899e36a8 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h @@ -13,74 +13,73 @@ #include <linux/reboot.h> +struct irq_data; struct platform_device; struct pt_regs; struct clk; enum mxc_cpu_pwr_mode; -extern void mx1_map_io(void); -extern void mx21_map_io(void); -extern void mx25_map_io(void); -extern void mx27_map_io(void); -extern void mx31_map_io(void); -extern void mx35_map_io(void); -extern void mx51_map_io(void); -extern void mx53_map_io(void); -extern void imx1_init_early(void); -extern void imx21_init_early(void); -extern void imx25_init_early(void); -extern void imx27_init_early(void); -extern void imx31_init_early(void); -extern void imx35_init_early(void); -extern void imx51_init_early(void); -extern void imx53_init_early(void); -extern void mxc_init_irq(void __iomem *); -extern void tzic_init_irq(void __iomem *); -extern void mx1_init_irq(void); -extern void mx21_init_irq(void); -extern void mx25_init_irq(void); -extern void mx27_init_irq(void); -extern void mx31_init_irq(void); -extern void mx35_init_irq(void); -extern void mx51_init_irq(void); -extern void mx53_init_irq(void); -extern void imx1_soc_init(void); -extern void imx21_soc_init(void); -extern void imx25_soc_init(void); -extern void imx27_soc_init(void); -extern void imx31_soc_init(void); -extern void imx35_soc_init(void); -extern void imx51_soc_init(void); -extern void imx51_init_late(void); -extern void imx53_init_late(void); -extern void epit_timer_init(void __iomem *base, int irq); -extern void mxc_timer_init(void __iomem *, int); -extern int mx1_clocks_init(unsigned long fref); -extern int mx21_clocks_init(unsigned long lref, unsigned long fref); -extern int mx25_clocks_init(void); -extern int mx27_clocks_init(unsigned long fref); -extern int mx31_clocks_init(unsigned long fref); -extern int mx35_clocks_init(void); -extern int mx51_clocks_init(unsigned long ckil, unsigned long osc, +void mx1_map_io(void); +void mx21_map_io(void); +void mx25_map_io(void); +void mx27_map_io(void); +void mx31_map_io(void); +void mx35_map_io(void); +void mx51_map_io(void); +void mx53_map_io(void); +void imx1_init_early(void); +void imx21_init_early(void); +void imx25_init_early(void); +void imx27_init_early(void); +void imx31_init_early(void); +void imx35_init_early(void); +void imx51_init_early(void); +void imx53_init_early(void); +void mxc_init_irq(void __iomem *); +void tzic_init_irq(void __iomem *); +void mx1_init_irq(void); +void mx21_init_irq(void); +void mx25_init_irq(void); +void mx27_init_irq(void); +void mx31_init_irq(void); +void mx35_init_irq(void); +void mx51_init_irq(void); +void mx53_init_irq(void); +void imx1_soc_init(void); +void imx21_soc_init(void); +void imx25_soc_init(void); +void imx27_soc_init(void); +void imx31_soc_init(void); +void imx35_soc_init(void); +void imx51_soc_init(void); +void imx51_init_late(void); +void imx53_init_late(void); +void epit_timer_init(void __iomem *base, int irq); +void mxc_timer_init(void __iomem *, int); +int mx1_clocks_init(unsigned long fref); +int mx21_clocks_init(unsigned long lref, unsigned long fref); +int mx25_clocks_init(void); +int mx27_clocks_init(unsigned long fref); +int mx31_clocks_init(unsigned long fref); +int mx35_clocks_init(void); +int mx51_clocks_init(unsigned long ckil, unsigned long osc, unsigned long ckih1, unsigned long ckih2); -extern int mx53_clocks_init(unsigned long ckil, unsigned long osc, - unsigned long ckih1, unsigned long ckih2); -extern int mx25_clocks_init_dt(void); -extern int mx27_clocks_init_dt(void); -extern int mx31_clocks_init_dt(void); -extern int mx51_clocks_init_dt(void); -extern int mx53_clocks_init_dt(void); -extern struct platform_device *mxc_register_gpio(char *name, int id, +int mx25_clocks_init_dt(void); +int mx27_clocks_init_dt(void); +int mx31_clocks_init_dt(void); +struct platform_device *mxc_register_gpio(char *name, int id, resource_size_t iobase, resource_size_t iosize, int irq, int irq_high); -extern void mxc_set_cpu_type(unsigned int type); -extern void mxc_restart(enum reboot_mode, const char *); -extern void mxc_arch_reset_init(void __iomem *); -extern void mxc_arch_reset_init_dt(void); -extern int mx53_revision(void); -extern int imx6q_revision(void); -extern int mx53_display_revision(void); -extern void imx_set_aips(void __iomem *); -extern int mxc_device_init(void); +void mxc_set_cpu_type(unsigned int type); +void mxc_restart(enum reboot_mode, const char *); +void mxc_arch_reset_init(void __iomem *); +void mxc_arch_reset_init_dt(void); +int mx53_revision(void); +void imx_set_aips(void __iomem *); +int mxc_device_init(void); +void imx_set_soc_revision(unsigned int rev); +unsigned int imx_get_soc_revision(void); +void imx_init_revision_from_anatop(void); +struct device *imx_soc_device_init(void); enum mxc_cpu_pwr_mode { WAIT_CLOCKED, /* wfi only */ @@ -97,8 +96,8 @@ enum mx3_cpu_pwr_mode { MX3_SLEEP, }; -extern void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode); -extern void imx_print_silicon_rev(const char *cpu, int srev); +void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode); +void imx_print_silicon_rev(const char *cpu, int srev); void avic_handle_irq(struct pt_regs *); void tzic_handle_irq(struct pt_regs *); @@ -112,54 +111,56 @@ void tzic_handle_irq(struct pt_regs *); #define imx51_handle_irq tzic_handle_irq #define imx53_handle_irq tzic_handle_irq -extern void imx_enable_cpu(int cpu, bool enable); -extern void imx_set_cpu_jump(int cpu, void *jump_addr); -extern u32 imx_get_cpu_arg(int cpu); -extern void imx_set_cpu_arg(int cpu, u32 arg); -extern void v7_cpu_resume(void); +void imx_enable_cpu(int cpu, bool enable); +void imx_set_cpu_jump(int cpu, void *jump_addr); +u32 imx_get_cpu_arg(int cpu); +void imx_set_cpu_arg(int cpu, u32 arg); +void v7_cpu_resume(void); #ifdef CONFIG_SMP -extern void v7_secondary_startup(void); -extern void imx_scu_map_io(void); -extern void imx_smp_prepare(void); -extern void imx_scu_standby_enable(void); +void v7_secondary_startup(void); +void imx_scu_map_io(void); +void imx_smp_prepare(void); +void imx_scu_standby_enable(void); #else static inline void imx_scu_map_io(void) {} static inline void imx_smp_prepare(void) {} static inline void imx_scu_standby_enable(void) {} #endif -extern void imx_src_init(void); -extern void imx_src_prepare_restart(void); -extern void imx_gpc_init(void); -extern void imx_gpc_pre_suspend(void); -extern void imx_gpc_post_resume(void); -extern void imx_gpc_mask_all(void); -extern void imx_gpc_restore_all(void); -extern void imx_anatop_init(void); -extern void imx_anatop_pre_suspend(void); -extern void imx_anatop_post_resume(void); -extern u32 imx_anatop_get_digprog(void); -extern int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode); -extern void imx6q_set_chicken_bit(void); - -extern void imx_cpu_die(unsigned int cpu); -extern int imx_cpu_kill(unsigned int cpu); +void imx_src_init(void); +void imx_gpc_init(void); +void imx_gpc_pre_suspend(void); +void imx_gpc_post_resume(void); +void imx_gpc_mask_all(void); +void imx_gpc_restore_all(void); +void imx_gpc_irq_mask(struct irq_data *d); +void imx_gpc_irq_unmask(struct irq_data *d); +void imx_anatop_init(void); +void imx_anatop_pre_suspend(void); +void imx_anatop_post_resume(void); +int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode); +void imx6q_set_chicken_bit(void); + +void imx_cpu_die(unsigned int cpu); +int imx_cpu_kill(unsigned int cpu); #ifdef CONFIG_PM -extern void imx6q_pm_init(void); -extern void imx5_pm_init(void); +void imx6q_pm_init(void); +void imx6q_pm_set_ccm_base(void __iomem *base); +void imx5_pm_init(void); #else static inline void imx6q_pm_init(void) {} +static inline void imx6q_pm_set_ccm_base(void __iomem *base) {} static inline void imx5_pm_init(void) {} #endif #ifdef CONFIG_NEON -extern int mx51_neon_fixup(void); +int mx51_neon_fixup(void); #else static inline int mx51_neon_fixup(void) { return 0; } #endif #ifdef CONFIG_CACHE_L2X0 -extern void imx_init_l2cache(void); +void imx_init_l2cache(void); #else static inline void imx_init_l2cache(void) {} #endif diff --git a/arch/arm/mach-imx/cpu.c b/arch/arm/mach-imx/cpu.c index e70e3acbf9bd..ba3b498a67ec 100644 --- a/arch/arm/mach-imx/cpu.c +++ b/arch/arm/mach-imx/cpu.c @@ -1,6 +1,9 @@ - +#include <linux/err.h> #include <linux/module.h> #include <linux/io.h> +#include <linux/of.h> +#include <linux/slab.h> +#include <linux/sys_soc.h> #include "hardware.h" #include "common.h" @@ -8,11 +11,23 @@ unsigned int __mxc_cpu_type; EXPORT_SYMBOL(__mxc_cpu_type); +static unsigned int imx_soc_revision; + void mxc_set_cpu_type(unsigned int type) { __mxc_cpu_type = type; } +void imx_set_soc_revision(unsigned int rev) +{ + imx_soc_revision = rev; +} + +unsigned int imx_get_soc_revision(void) +{ + return imx_soc_revision; +} + void imx_print_silicon_rev(const char *cpu, int srev) { if (srev == IMX_CHIP_REVISION_UNKNOWN) @@ -44,3 +59,81 @@ void __init imx_set_aips(void __iomem *base) reg = __raw_readl(base + 0x50) & 0x00FFFFFF; __raw_writel(reg, base + 0x50); } + +struct device * __init imx_soc_device_init(void) +{ + struct soc_device_attribute *soc_dev_attr; + struct soc_device *soc_dev; + struct device_node *root; + const char *soc_id; + int ret; + + soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); + if (!soc_dev_attr) + return NULL; + + soc_dev_attr->family = "Freescale i.MX"; + + root = of_find_node_by_path("/"); + ret = of_property_read_string(root, "model", &soc_dev_attr->machine); + of_node_put(root); + if (ret) + goto free_soc; + + switch (__mxc_cpu_type) { + case MXC_CPU_MX1: + soc_id = "i.MX1"; + break; + case MXC_CPU_MX21: + soc_id = "i.MX21"; + break; + case MXC_CPU_MX25: + soc_id = "i.MX25"; + break; + case MXC_CPU_MX27: + soc_id = "i.MX27"; + break; + case MXC_CPU_MX31: + soc_id = "i.MX31"; + break; + case MXC_CPU_MX35: + soc_id = "i.MX35"; + break; + case MXC_CPU_MX51: + soc_id = "i.MX51"; + break; + case MXC_CPU_MX53: + soc_id = "i.MX53"; + break; + case MXC_CPU_IMX6SL: + soc_id = "i.MX6SL"; + break; + case MXC_CPU_IMX6DL: + soc_id = "i.MX6DL"; + break; + case MXC_CPU_IMX6Q: + soc_id = "i.MX6Q"; + break; + default: + soc_id = "Unknown"; + } + soc_dev_attr->soc_id = soc_id; + + soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%d.%d", + (imx_soc_revision >> 4) & 0xf, + imx_soc_revision & 0xf); + if (!soc_dev_attr->revision) + goto free_soc; + + soc_dev = soc_device_register(soc_dev_attr); + if (IS_ERR(soc_dev)) + goto free_rev; + + return soc_device_to_device(soc_dev); + +free_rev: + kfree(soc_dev_attr->revision); +free_soc: + kfree(soc_dev_attr); + return NULL; +} diff --git a/arch/arm/mach-imx/epit.c b/arch/arm/mach-imx/epit.c index e02de188ae83..074b1a81ba76 100644 --- a/arch/arm/mach-imx/epit.c +++ b/arch/arm/mach-imx/epit.c @@ -171,7 +171,7 @@ static irqreturn_t epit_timer_interrupt(int irq, void *dev_id) static struct irqaction epit_timer_irq = { .name = "i.MX EPIT Timer Tick", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .flags = IRQF_TIMER | IRQF_IRQPOLL, .handler = epit_timer_interrupt, }; diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c index 44a65e9ff1fc..586e0171a652 100644 --- a/arch/arm/mach-imx/gpc.c +++ b/arch/arm/mach-imx/gpc.c @@ -90,7 +90,7 @@ void imx_gpc_restore_all(void) writel_relaxed(gpc_saved_imrs[i], reg_imr1 + i * 4); } -static void imx_gpc_irq_unmask(struct irq_data *d) +void imx_gpc_irq_unmask(struct irq_data *d) { void __iomem *reg; u32 val; @@ -105,7 +105,7 @@ static void imx_gpc_irq_unmask(struct irq_data *d) writel_relaxed(val, reg); } -static void imx_gpc_irq_mask(struct irq_data *d) +void imx_gpc_irq_mask(struct irq_data *d) { void __iomem *reg; u32 val; diff --git a/arch/arm/mach-imx/hotplug.c b/arch/arm/mach-imx/hotplug.c index 3daf1ed90579..b35e99cc5e5b 100644 --- a/arch/arm/mach-imx/hotplug.c +++ b/arch/arm/mach-imx/hotplug.c @@ -52,7 +52,9 @@ void imx_cpu_die(unsigned int cpu) * the register being cleared to kill the cpu. */ imx_set_cpu_arg(cpu, ~0); - cpu_do_idle(); + + while (1) + cpu_do_idle(); } int imx_cpu_kill(unsigned int cpu) diff --git a/arch/arm/mach-imx/imx51-dt.c b/arch/arm/mach-imx/imx51-dt.c index 53e43e579dd7..bece8a65e6f0 100644 --- a/arch/arm/mach-imx/imx51-dt.c +++ b/arch/arm/mach-imx/imx51-dt.c @@ -34,17 +34,11 @@ static const char *imx51_dt_board_compat[] __initdata = { NULL }; -static void __init imx51_timer_init(void) -{ - mx51_clocks_init_dt(); -} - DT_MACHINE_START(IMX51_DT, "Freescale i.MX51 (Device Tree Support)") .map_io = mx51_map_io, .init_early = imx51_init_early, .init_irq = mx51_init_irq, .handle_irq = imx51_handle_irq, - .init_time = imx51_timer_init, .init_machine = imx51_dt_init, .init_late = imx51_init_late, .dt_compat = imx51_dt_board_compat, diff --git a/arch/arm/mach-imx/mach-armadillo5x0.c b/arch/arm/mach-imx/mach-armadillo5x0.c index 368a6e3f5926..58b864a3fc20 100644 --- a/arch/arm/mach-imx/mach-armadillo5x0.c +++ b/arch/arm/mach-imx/mach-armadillo5x0.c @@ -404,8 +404,7 @@ static int armadillo5x0_sdhc1_init(struct device *dev, /* When supported the trigger type have to be BOTH */ ret = request_irq(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_ATA_DMACK)), - detect_irq, - IRQF_DISABLED | IRQF_TRIGGER_FALLING, + detect_irq, IRQF_TRIGGER_FALLING, "sdhc-detect", data); if (ret) diff --git a/arch/arm/mach-imx/mach-imx53.c b/arch/arm/mach-imx/mach-imx53.c index 98c58944015a..c9c4d8d96931 100644 --- a/arch/arm/mach-imx/mach-imx53.c +++ b/arch/arm/mach-imx/mach-imx53.c @@ -36,17 +36,11 @@ static const char *imx53_dt_board_compat[] __initdata = { NULL }; -static void __init imx53_timer_init(void) -{ - mx53_clocks_init_dt(); -} - DT_MACHINE_START(IMX53_DT, "Freescale i.MX53 (Device Tree Support)") .map_io = mx53_map_io, .init_early = imx53_init_early, .init_irq = mx53_init_irq, .handle_irq = imx53_handle_irq, - .init_time = imx53_timer_init, .init_machine = imx53_dt_init, .init_late = imx53_init_late, .dt_compat = imx53_dt_board_compat, diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 90372a21087f..d0cfb225ec9a 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c @@ -11,11 +11,8 @@ */ #include <linux/clk.h> -#include <linux/clk-provider.h> #include <linux/clkdev.h> -#include <linux/clocksource.h> #include <linux/cpu.h> -#include <linux/delay.h> #include <linux/export.h> #include <linux/init.h> #include <linux/io.h> @@ -25,7 +22,7 @@ #include <linux/of_address.h> #include <linux/of_irq.h> #include <linux/of_platform.h> -#include <linux/opp.h> +#include <linux/pm_opp.h> #include <linux/phy.h> #include <linux/reboot.h> #include <linux/regmap.h> @@ -40,64 +37,6 @@ #include "cpuidle.h" #include "hardware.h" -static u32 chip_revision; - -int imx6q_revision(void) -{ - return chip_revision; -} - -static void __init imx6q_init_revision(void) -{ - u32 rev = imx_anatop_get_digprog(); - - switch (rev & 0xff) { - case 0: - chip_revision = IMX_CHIP_REVISION_1_0; - break; - case 1: - chip_revision = IMX_CHIP_REVISION_1_1; - break; - case 2: - chip_revision = IMX_CHIP_REVISION_1_2; - break; - default: - chip_revision = IMX_CHIP_REVISION_UNKNOWN; - } - - mxc_set_cpu_type(rev >> 16 & 0xff); -} - -static void imx6q_restart(enum reboot_mode mode, const char *cmd) -{ - struct device_node *np; - void __iomem *wdog_base; - - np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-wdt"); - wdog_base = of_iomap(np, 0); - if (!wdog_base) - goto soft; - - imx_src_prepare_restart(); - - /* enable wdog */ - writew_relaxed(1 << 2, wdog_base); - /* write twice to ensure the request will not get ignored */ - writew_relaxed(1 << 2, wdog_base); - - /* wait for reset to assert ... */ - mdelay(500); - - pr_err("Watchdog reset failed to assert reset\n"); - - /* delay to allow the serial port to show the message */ - mdelay(50); - -soft: - /* we'll take a jump through zero as a poor second */ - soft_restart(0); -} - /* For imx6q sabrelite board: set KSZ9021RN RGMII pad skew */ static int ksz9021rn_phy_fixup(struct phy_device *phydev) { @@ -192,9 +131,20 @@ static void __init imx6q_1588_init(void) static void __init imx6q_init_machine(void) { + struct device *parent; + + imx_print_silicon_rev(cpu_is_imx6dl() ? "i.MX6DL" : "i.MX6Q", + imx_get_soc_revision()); + + mxc_arch_reset_init_dt(); + + parent = imx_soc_device_init(); + if (parent == NULL) + pr_warn("failed to initialize soc device\n"); + imx6q_enet_phy_init(); - of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); + of_platform_populate(NULL, of_default_bus_match_table, NULL, parent); imx_anatop_init(); imx6q_pm_init(); @@ -226,7 +176,7 @@ static void __init imx6q_opp_check_1p2ghz(struct device *cpu_dev) val = readl_relaxed(base + OCOTP_CFG3); val >>= OCOTP_CFG3_SPEED_SHIFT; if ((val & 0x3) != OCOTP_CFG3_SPEED_1P2GHZ) - if (opp_disable(cpu_dev, 1200000000)) + if (dev_pm_opp_disable(cpu_dev, 1200000000)) pr_warn("failed to disable 1.2 GHz OPP\n"); put_node: @@ -269,7 +219,7 @@ static void __init imx6q_init_late(void) * WAIT mode is broken on TO 1.0 and 1.1, so there is no point * to run cpuidle on them. */ - if (imx6q_revision() > IMX_CHIP_REVISION_1_1) + if (imx_get_soc_revision() > IMX_CHIP_REVISION_1_1) imx6q_cpuidle_init(); if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ)) { @@ -286,21 +236,13 @@ static void __init imx6q_map_io(void) static void __init imx6q_init_irq(void) { - imx6q_init_revision(); + imx_init_revision_from_anatop(); imx_init_l2cache(); imx_src_init(); imx_gpc_init(); irqchip_init(); } -static void __init imx6q_timer_init(void) -{ - of_clk_init(NULL); - clocksource_of_init(); - imx_print_silicon_rev(cpu_is_imx6dl() ? "i.MX6DL" : "i.MX6Q", - imx6q_revision()); -} - static const char *imx6q_dt_compat[] __initdata = { "fsl,imx6dl", "fsl,imx6q", @@ -311,9 +253,8 @@ DT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad/DualLite (Device Tree)") .smp = smp_ops(imx_smp_ops), .map_io = imx6q_map_io, .init_irq = imx6q_init_irq, - .init_time = imx6q_timer_init, .init_machine = imx6q_init_machine, .init_late = imx6q_init_late, .dt_compat = imx6q_dt_compat, - .restart = imx6q_restart, + .restart = mxc_restart, MACHINE_END diff --git a/arch/arm/mach-imx/mach-imx6sl.c b/arch/arm/mach-imx/mach-imx6sl.c index 0d75dc54f715..2f952e3fcf89 100644 --- a/arch/arm/mach-imx/mach-imx6sl.c +++ b/arch/arm/mach-imx/mach-imx6sl.c @@ -7,35 +7,60 @@ * */ -#include <linux/clk-provider.h> #include <linux/irqchip.h> #include <linux/of.h> #include <linux/of_platform.h> +#include <linux/mfd/syscon.h> +#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h> +#include <linux/regmap.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> #include "common.h" +static void __init imx6sl_fec_init(void) +{ + struct regmap *gpr; + + /* set FEC clock from internal PLL clock source */ + gpr = syscon_regmap_lookup_by_compatible("fsl,imx6sl-iomuxc-gpr"); + if (!IS_ERR(gpr)) { + regmap_update_bits(gpr, IOMUXC_GPR1, + IMX6SL_GPR1_FEC_CLOCK_MUX2_SEL_MASK, 0); + regmap_update_bits(gpr, IOMUXC_GPR1, + IMX6SL_GPR1_FEC_CLOCK_MUX1_SEL_MASK, 0); + } else { + pr_err("failed to find fsl,imx6sl-iomux-gpr regmap\n"); + } +} + static void __init imx6sl_init_machine(void) { + struct device *parent; + mxc_arch_reset_init_dt(); - of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); + parent = imx_soc_device_init(); + if (parent == NULL) + pr_warn("failed to initialize soc device\n"); + + of_platform_populate(NULL, of_default_bus_match_table, NULL, parent); + + imx6sl_fec_init(); + imx_anatop_init(); + /* Reuse imx6q pm code */ + imx6q_pm_init(); } static void __init imx6sl_init_irq(void) { + imx_init_revision_from_anatop(); imx_init_l2cache(); imx_src_init(); imx_gpc_init(); irqchip_init(); } -static void __init imx6sl_timer_init(void) -{ - of_clk_init(NULL); -} - static const char *imx6sl_dt_compat[] __initdata = { "fsl,imx6sl", NULL, @@ -44,7 +69,6 @@ static const char *imx6sl_dt_compat[] __initdata = { DT_MACHINE_START(IMX6SL, "Freescale i.MX6 SoloLite (Device Tree)") .map_io = debug_ll_io_init, .init_irq = imx6sl_init_irq, - .init_time = imx6sl_timer_init, .init_machine = imx6sl_init_machine, .dt_compat = imx6sl_dt_compat, .restart = mxc_restart, diff --git a/arch/arm/mach-imx/mach-mx31_3ds.c b/arch/arm/mach-imx/mach-mx31_3ds.c index 1ed916175d41..50044a21b388 100644 --- a/arch/arm/mach-imx/mach-mx31_3ds.c +++ b/arch/arm/mach-imx/mach-mx31_3ds.c @@ -311,7 +311,7 @@ static int mx31_3ds_sdhc1_init(struct device *dev, } ret = request_irq(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO3_1)), - detect_irq, IRQF_DISABLED | + detect_irq, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "sdhc1-detect", data); if (ret) { diff --git a/arch/arm/mach-imx/mach-pca100.c b/arch/arm/mach-imx/mach-pca100.c index 19bb6441a7d4..c5f95674e9b7 100644 --- a/arch/arm/mach-imx/mach-pca100.c +++ b/arch/arm/mach-imx/mach-pca100.c @@ -20,7 +20,7 @@ #include <linux/platform_device.h> #include <linux/io.h> #include <linux/i2c.h> -#include <linux/i2c/at24.h> +#include <linux/platform_data/at24.h> #include <linux/dma-mapping.h> #include <linux/spi/spi.h> #include <linux/spi/eeprom.h> diff --git a/arch/arm/mach-imx/mach-pcm037.c b/arch/arm/mach-imx/mach-pcm037.c index bc0261e99d39..639a3dfb0092 100644 --- a/arch/arm/mach-imx/mach-pcm037.c +++ b/arch/arm/mach-imx/mach-pcm037.c @@ -23,7 +23,7 @@ #include <linux/smsc911x.h> #include <linux/interrupt.h> #include <linux/i2c.h> -#include <linux/i2c/at24.h> +#include <linux/platform_data/at24.h> #include <linux/delay.h> #include <linux/spi/spi.h> #include <linux/irq.h> @@ -371,8 +371,7 @@ static int pcm970_sdhc1_init(struct device *dev, irq_handler_t detect_irq, #endif ret = request_irq(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_SCK6)), detect_irq, - IRQF_DISABLED | IRQF_TRIGGER_FALLING, - "sdhc-detect", data); + IRQF_TRIGGER_FALLING, "sdhc-detect", data); if (ret) goto err_gpio_free_2; diff --git a/arch/arm/mach-imx/mach-pcm038.c b/arch/arm/mach-imx/mach-pcm038.c index e805ac273e9c..592ddbe031ac 100644 --- a/arch/arm/mach-imx/mach-pcm038.c +++ b/arch/arm/mach-imx/mach-pcm038.c @@ -18,7 +18,7 @@ */ #include <linux/i2c.h> -#include <linux/i2c/at24.h> +#include <linux/platform_data/at24.h> #include <linux/io.h> #include <linux/mtd/plat-ram.h> #include <linux/mtd/physmap.h> diff --git a/arch/arm/mach-imx/mach-pcm043.c b/arch/arm/mach-imx/mach-pcm043.c index b726cb1c5fdd..ac504b67326b 100644 --- a/arch/arm/mach-imx/mach-pcm043.c +++ b/arch/arm/mach-imx/mach-pcm043.c @@ -24,7 +24,7 @@ #include <linux/interrupt.h> #include <linux/delay.h> #include <linux/i2c.h> -#include <linux/i2c/at24.h> +#include <linux/platform_data/at24.h> #include <linux/usb/otg.h> #include <linux/usb/ulpi.h> diff --git a/arch/arm/mach-imx/mach-vf610.c b/arch/arm/mach-imx/mach-vf610.c index 816991deb9b8..af0cb8a9dc48 100644 --- a/arch/arm/mach-imx/mach-vf610.c +++ b/arch/arm/mach-imx/mach-vf610.c @@ -8,9 +8,7 @@ */ #include <linux/of_platform.h> -#include <linux/clocksource.h> #include <linux/irqchip.h> -#include <linux/clk-provider.h> #include <asm/mach/arch.h> #include <asm/hardware/cache-l2x0.h> @@ -28,12 +26,6 @@ static void __init vf610_init_irq(void) irqchip_init(); } -static void __init vf610_init_time(void) -{ - of_clk_init(NULL); - clocksource_of_init(); -} - static const char *vf610_dt_compat[] __initdata = { "fsl,vf610", NULL, @@ -41,7 +33,6 @@ static const char *vf610_dt_compat[] __initdata = { DT_MACHINE_START(VYBRID_VF610, "Freescale Vybrid VF610 (Device Tree)") .init_irq = vf610_init_irq, - .init_time = vf610_init_time, .init_machine = vf610_init_machine, .dt_compat = vf610_dt_compat, .restart = mxc_restart, diff --git a/arch/arm/mach-imx/mach-vpr200.c b/arch/arm/mach-imx/mach-vpr200.c index 0910761e8280..8825d1217d18 100644 --- a/arch/arm/mach-imx/mach-vpr200.c +++ b/arch/arm/mach-imx/mach-vpr200.c @@ -29,7 +29,7 @@ #include <asm/mach/time.h> #include <linux/i2c.h> -#include <linux/i2c/at24.h> +#include <linux/platform_data/at24.h> #include <linux/mfd/mc13xxx.h> #include "common.h" diff --git a/arch/arm/mach-imx/mm-imx5.c b/arch/arm/mach-imx/mm-imx5.c index eb3cce38c70d..d1d52600f458 100644 --- a/arch/arm/mach-imx/mm-imx5.c +++ b/arch/arm/mach-imx/mm-imx5.c @@ -15,6 +15,7 @@ #include <linux/init.h> #include <linux/clk.h> #include <linux/pinctrl/machine.h> +#include <linux/of_address.h> #include <asm/mach/map.h> @@ -88,8 +89,15 @@ void __init imx51_init_early(void) void __init imx53_init_early(void) { + struct device_node *np; + void __iomem *base; + mxc_set_cpu_type(MXC_CPU_MX53); - mxc_iomux_v3_init(MX53_IO_ADDRESS(MX53_IOMUXC_BASE_ADDR)); + + np = of_find_compatible_node(NULL, NULL, "fsl,imx53-iomuxc"); + base = of_iomap(np, 0); + WARN_ON(!base); + mxc_iomux_v3_init(base); imx_src_init(); } @@ -100,7 +108,14 @@ void __init mx51_init_irq(void) void __init mx53_init_irq(void) { - tzic_init_irq(MX53_IO_ADDRESS(MX53_TZIC_BASE_ADDR)); + struct device_node *np; + void __iomem *base; + + np = of_find_compatible_node(NULL, NULL, "fsl,imx53-tzic"); + base = of_iomap(np, 0); + WARN_ON(!base); + + tzic_init_irq(base); } static struct sdma_platform_data imx51_sdma_pdata __initdata = { diff --git a/arch/arm/mach-imx/mx31lilly-db.c b/arch/arm/mach-imx/mx31lilly-db.c index d4361b80c5fb..649fe49ce85e 100644 --- a/arch/arm/mach-imx/mx31lilly-db.c +++ b/arch/arm/mach-imx/mx31lilly-db.c @@ -130,8 +130,7 @@ static int mxc_mmc1_init(struct device *dev, gpio_direction_input(gpio_wp); ret = request_irq(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1)), - detect_irq, - IRQF_DISABLED | IRQF_TRIGGER_FALLING, + detect_irq, IRQF_TRIGGER_FALLING, "MMC detect", data); if (ret) goto exit_free_wp; diff --git a/arch/arm/mach-imx/mxc.h b/arch/arm/mach-imx/mxc.h index 8629e5be7ecd..b08ab3ad4a6d 100644 --- a/arch/arm/mach-imx/mxc.h +++ b/arch/arm/mach-imx/mxc.h @@ -34,6 +34,7 @@ #define MXC_CPU_MX35 35 #define MXC_CPU_MX51 51 #define MXC_CPU_MX53 53 +#define MXC_CPU_IMX6SL 0x60 #define MXC_CPU_IMX6DL 0x61 #define MXC_CPU_IMX6Q 0x63 @@ -152,6 +153,11 @@ extern unsigned int __mxc_cpu_type; #endif #ifndef __ASSEMBLY__ +static inline bool cpu_is_imx6sl(void) +{ + return __mxc_cpu_type == MXC_CPU_IMX6SL; +} + static inline bool cpu_is_imx6dl(void) { return __mxc_cpu_type == MXC_CPU_IMX6DL; diff --git a/arch/arm/mach-imx/pm-imx6q.c b/arch/arm/mach-imx/pm-imx6q.c index 204942749e21..aecd9f8037e0 100644 --- a/arch/arm/mach-imx/pm-imx6q.c +++ b/arch/arm/mach-imx/pm-imx6q.c @@ -10,9 +10,15 @@ * http://www.gnu.org/copyleft/gpl.html */ +#include <linux/delay.h> #include <linux/init.h> #include <linux/io.h> +#include <linux/irq.h> +#include <linux/mfd/syscon.h> +#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h> #include <linux/of.h> +#include <linux/of_address.h> +#include <linux/regmap.h> #include <linux/suspend.h> #include <asm/cacheflush.h> #include <asm/proc-fns.h> @@ -22,6 +28,147 @@ #include "common.h" #include "hardware.h" +#define CCR 0x0 +#define BM_CCR_WB_COUNT (0x7 << 16) +#define BM_CCR_RBC_BYPASS_COUNT (0x3f << 21) +#define BM_CCR_RBC_EN (0x1 << 27) + +#define CLPCR 0x54 +#define BP_CLPCR_LPM 0 +#define BM_CLPCR_LPM (0x3 << 0) +#define BM_CLPCR_BYPASS_PMIC_READY (0x1 << 2) +#define BM_CLPCR_ARM_CLK_DIS_ON_LPM (0x1 << 5) +#define BM_CLPCR_SBYOS (0x1 << 6) +#define BM_CLPCR_DIS_REF_OSC (0x1 << 7) +#define BM_CLPCR_VSTBY (0x1 << 8) +#define BP_CLPCR_STBY_COUNT 9 +#define BM_CLPCR_STBY_COUNT (0x3 << 9) +#define BM_CLPCR_COSC_PWRDOWN (0x1 << 11) +#define BM_CLPCR_WB_PER_AT_LPM (0x1 << 16) +#define BM_CLPCR_WB_CORE_AT_LPM (0x1 << 17) +#define BM_CLPCR_BYP_MMDC_CH0_LPM_HS (0x1 << 19) +#define BM_CLPCR_BYP_MMDC_CH1_LPM_HS (0x1 << 21) +#define BM_CLPCR_MASK_CORE0_WFI (0x1 << 22) +#define BM_CLPCR_MASK_CORE1_WFI (0x1 << 23) +#define BM_CLPCR_MASK_CORE2_WFI (0x1 << 24) +#define BM_CLPCR_MASK_CORE3_WFI (0x1 << 25) +#define BM_CLPCR_MASK_SCU_IDLE (0x1 << 26) +#define BM_CLPCR_MASK_L2CC_IDLE (0x1 << 27) + +#define CGPR 0x64 +#define BM_CGPR_CHICKEN_BIT (0x1 << 17) + +static void __iomem *ccm_base; + +void imx6q_set_chicken_bit(void) +{ + u32 val = readl_relaxed(ccm_base + CGPR); + + val |= BM_CGPR_CHICKEN_BIT; + writel_relaxed(val, ccm_base + CGPR); +} + +static void imx6q_enable_rbc(bool enable) +{ + u32 val; + + /* + * need to mask all interrupts in GPC before + * operating RBC configurations + */ + imx_gpc_mask_all(); + + /* configure RBC enable bit */ + val = readl_relaxed(ccm_base + CCR); + val &= ~BM_CCR_RBC_EN; + val |= enable ? BM_CCR_RBC_EN : 0; + writel_relaxed(val, ccm_base + CCR); + + /* configure RBC count */ + val = readl_relaxed(ccm_base + CCR); + val &= ~BM_CCR_RBC_BYPASS_COUNT; + val |= enable ? BM_CCR_RBC_BYPASS_COUNT : 0; + writel(val, ccm_base + CCR); + + /* + * need to delay at least 2 cycles of CKIL(32K) + * due to hardware design requirement, which is + * ~61us, here we use 65us for safe + */ + udelay(65); + + /* restore GPC interrupt mask settings */ + imx_gpc_restore_all(); +} + +static void imx6q_enable_wb(bool enable) +{ + u32 val; + + /* configure well bias enable bit */ + val = readl_relaxed(ccm_base + CLPCR); + val &= ~BM_CLPCR_WB_PER_AT_LPM; + val |= enable ? BM_CLPCR_WB_PER_AT_LPM : 0; + writel_relaxed(val, ccm_base + CLPCR); + + /* configure well bias count */ + val = readl_relaxed(ccm_base + CCR); + val &= ~BM_CCR_WB_COUNT; + val |= enable ? BM_CCR_WB_COUNT : 0; + writel_relaxed(val, ccm_base + CCR); +} + +int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) +{ + struct irq_desc *iomuxc_irq_desc; + u32 val = readl_relaxed(ccm_base + CLPCR); + + val &= ~BM_CLPCR_LPM; + switch (mode) { + case WAIT_CLOCKED: + break; + case WAIT_UNCLOCKED: + val |= 0x1 << BP_CLPCR_LPM; + val |= BM_CLPCR_ARM_CLK_DIS_ON_LPM; + break; + case STOP_POWER_ON: + val |= 0x2 << BP_CLPCR_LPM; + break; + case WAIT_UNCLOCKED_POWER_OFF: + val |= 0x1 << BP_CLPCR_LPM; + val &= ~BM_CLPCR_VSTBY; + val &= ~BM_CLPCR_SBYOS; + break; + case STOP_POWER_OFF: + val |= 0x2 << BP_CLPCR_LPM; + val |= 0x3 << BP_CLPCR_STBY_COUNT; + val |= BM_CLPCR_VSTBY; + val |= BM_CLPCR_SBYOS; + if (cpu_is_imx6sl()) { + val |= BM_CLPCR_BYPASS_PMIC_READY; + val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS; + } else { + val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS; + } + break; + default: + return -EINVAL; + } + + /* + * Unmask the always pending IOMUXC interrupt #32 as wakeup source to + * deassert dsm_request signal, so that we can ensure dsm_request + * is not asserted when we're going to write CLPCR register to set LPM. + * After setting up LPM bits, we need to mask this wakeup source. + */ + iomuxc_irq_desc = irq_to_desc(32); + imx_gpc_irq_unmask(&iomuxc_irq_desc->irq_data); + writel_relaxed(val, ccm_base + CLPCR); + imx_gpc_irq_mask(&iomuxc_irq_desc->irq_data); + + return 0; +} + static int imx6q_suspend_finish(unsigned long val) { cpu_do_idle(); @@ -33,14 +180,19 @@ static int imx6q_pm_enter(suspend_state_t state) switch (state) { case PM_SUSPEND_MEM: imx6q_set_lpm(STOP_POWER_OFF); + imx6q_enable_wb(true); + imx6q_enable_rbc(true); imx_gpc_pre_suspend(); imx_anatop_pre_suspend(); imx_set_cpu_jump(0, v7_cpu_resume); /* Zzz ... */ cpu_suspend(0, imx6q_suspend_finish); - imx_smp_prepare(); + if (cpu_is_imx6q() || cpu_is_imx6dl()) + imx_smp_prepare(); imx_anatop_post_resume(); imx_gpc_post_resume(); + imx6q_enable_rbc(false); + imx6q_enable_wb(false); imx6q_set_lpm(WAIT_CLOCKED); break; default: @@ -55,7 +207,29 @@ static const struct platform_suspend_ops imx6q_pm_ops = { .valid = suspend_valid_only_mem, }; +void __init imx6q_pm_set_ccm_base(void __iomem *base) +{ + ccm_base = base; +} + void __init imx6q_pm_init(void) { + struct regmap *gpr; + + WARN_ON(!ccm_base); + + /* + * Force IOMUXC irq pending, so that the interrupt to GPC can be + * used to deassert dsm_request signal when the signal gets + * asserted unexpectedly. + */ + gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr"); + if (!IS_ERR(gpr)) + regmap_update_bits(gpr, IOMUXC_GPR1, IMX6Q_GPR1_GINT, + IMX6Q_GPR1_GINT); + + /* Set initial power mode */ + imx6q_set_lpm(WAIT_CLOCKED); + suspend_set_ops(&imx6q_pm_ops); } diff --git a/arch/arm/mach-imx/src.c b/arch/arm/mach-imx/src.c index 10a6b1a8c5ac..45f7f4e0a447 100644 --- a/arch/arm/mach-imx/src.c +++ b/arch/arm/mach-imx/src.c @@ -91,6 +91,7 @@ void imx_enable_cpu(int cpu, bool enable) spin_lock(&scr_lock); val = readl_relaxed(src_base + SRC_SCR); val = enable ? val | mask : val & ~mask; + val |= 1 << (BP_SRC_SCR_CORE1_RST + cpu - 1); writel_relaxed(val, src_base + SRC_SCR); spin_unlock(&scr_lock); } @@ -114,21 +115,6 @@ void imx_set_cpu_arg(int cpu, u32 arg) writel_relaxed(arg, src_base + SRC_GPR1 + cpu * 8 + 4); } -void imx_src_prepare_restart(void) -{ - u32 val; - - /* clear enable bits of secondary cores */ - spin_lock(&scr_lock); - val = readl_relaxed(src_base + SRC_SCR); - val &= ~(0x7 << BP_SRC_SCR_CORE1_ENABLE); - writel_relaxed(val, src_base + SRC_SCR); - spin_unlock(&scr_lock); - - /* clear persistent entry register of primary core */ - writel_relaxed(0, src_base + SRC_GPR1); -} - void __init imx_src_init(void) { struct device_node *np; diff --git a/arch/arm/mach-imx/system.c b/arch/arm/mach-imx/system.c index 80c177c36c5f..5e3027d3692f 100644 --- a/arch/arm/mach-imx/system.c +++ b/arch/arm/mach-imx/system.c @@ -52,6 +52,15 @@ void mxc_restart(enum reboot_mode mode, const char *cmd) /* Assert SRS signal */ __raw_writew(wcr_enable, wdog_base); + /* + * Due to imx6q errata ERR004346 (WDOG: WDOG SRS bit requires to be + * written twice), we add another two writes to ensure there must be at + * least two writes happen in the same one 32kHz clock period. We save + * the target check here, since the writes shouldn't be a huge burden + * for other platforms. + */ + __raw_writew(wcr_enable, wdog_base); + __raw_writew(wcr_enable, wdog_base); /* wait for reset to assert... */ mdelay(500); diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c index cd46529e9eaa..9b6638aadeaa 100644 --- a/arch/arm/mach-imx/time.c +++ b/arch/arm/mach-imx/time.c @@ -250,7 +250,7 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id) static struct irqaction mxc_timer_irq = { .name = "i.MX Timer Tick", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .flags = IRQF_TIMER | IRQF_IRQPOLL, .handler = mxc_timer_interrupt, }; diff --git a/arch/arm/mach-integrator/include/mach/cm.h b/arch/arm/mach-integrator/cm.h index 202e6a57f100..4ecff7bff482 100644 --- a/arch/arm/mach-integrator/include/mach/cm.h +++ b/arch/arm/mach-integrator/cm.h @@ -1,9 +1,12 @@ /* - * update the core module control register. + * access the core module control register. */ +u32 cm_get(void); void cm_control(u32, u32); -#define CM_CTRL __io_address(INTEGRATOR_HDR_CTRL) +struct device_node; +void cm_init(void); +void cm_clear_irqs(void); #define CM_CTRL_LED (1 << 0) #define CM_CTRL_nMBDET (1 << 1) diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index 4cdfd7365925..00ddf20ed91b 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c @@ -22,77 +22,30 @@ #include <linux/amba/serial.h> #include <linux/io.h> #include <linux/stat.h> +#include <linux/of.h> +#include <linux/of_address.h> #include <mach/hardware.h> #include <mach/platform.h> -#include <mach/cm.h> -#include <mach/irqs.h> #include <asm/mach-types.h> #include <asm/mach/time.h> #include <asm/pgtable.h> +#include "cm.h" #include "common.h" -#ifdef CONFIG_ATAGS - -#define INTEGRATOR_RTC_IRQ { IRQ_RTCINT } -#define INTEGRATOR_UART0_IRQ { IRQ_UARTINT0 } -#define INTEGRATOR_UART1_IRQ { IRQ_UARTINT1 } -#define KMI0_IRQ { IRQ_KMIINT0 } -#define KMI1_IRQ { IRQ_KMIINT1 } - -static AMBA_APB_DEVICE(rtc, "rtc", 0, - INTEGRATOR_RTC_BASE, INTEGRATOR_RTC_IRQ, NULL); - -static AMBA_APB_DEVICE(uart0, "uart0", 0, - INTEGRATOR_UART0_BASE, INTEGRATOR_UART0_IRQ, NULL); - -static AMBA_APB_DEVICE(uart1, "uart1", 0, - INTEGRATOR_UART1_BASE, INTEGRATOR_UART1_IRQ, NULL); - -static AMBA_APB_DEVICE(kmi0, "kmi0", 0, KMI0_BASE, KMI0_IRQ, NULL); -static AMBA_APB_DEVICE(kmi1, "kmi1", 0, KMI1_BASE, KMI1_IRQ, NULL); - -static struct amba_device *amba_devs[] __initdata = { - &rtc_device, - &uart0_device, - &uart1_device, - &kmi0_device, - &kmi1_device, -}; +static DEFINE_RAW_SPINLOCK(cm_lock); +static void __iomem *cm_base; -int __init integrator_init(bool is_cp) +/** + * cm_get - get the value from the CM_CTRL register + */ +u32 cm_get(void) { - int i; - - /* - * The Integrator/AP lacks necessary AMBA PrimeCell IDs, so we need to - * hard-code them. The Integator/CP and forward have proper cell IDs. - * Else we leave them undefined to the bus driver can autoprobe them. - */ - if (!is_cp && IS_ENABLED(CONFIG_ARCH_INTEGRATOR_AP)) { - rtc_device.periphid = 0x00041030; - uart0_device.periphid = 0x00041010; - uart1_device.periphid = 0x00041010; - kmi0_device.periphid = 0x00041050; - kmi1_device.periphid = 0x00041050; - uart0_device.dev.platform_data = &ap_uart_data; - uart1_device.dev.platform_data = &ap_uart_data; - } - - for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { - struct amba_device *d = amba_devs[i]; - amba_device_register(d, &iomem_resource); - } - - return 0; + return readl(cm_base + INTEGRATOR_HDR_CTRL_OFFSET); } -#endif - -static DEFINE_RAW_SPINLOCK(cm_lock); - /** * cm_control - update the CM_CTRL register. * @mask: bits to change @@ -104,12 +57,80 @@ void cm_control(u32 mask, u32 set) u32 val; raw_spin_lock_irqsave(&cm_lock, flags); - val = readl(CM_CTRL) & ~mask; - writel(val | set, CM_CTRL); + val = readl(cm_base + INTEGRATOR_HDR_CTRL_OFFSET) & ~mask; + writel(val | set, cm_base + INTEGRATOR_HDR_CTRL_OFFSET); raw_spin_unlock_irqrestore(&cm_lock, flags); } -EXPORT_SYMBOL(cm_control); +static const char *integrator_arch_str(u32 id) +{ + switch ((id >> 16) & 0xff) { + case 0x00: + return "ASB little-endian"; + case 0x01: + return "AHB little-endian"; + case 0x03: + return "AHB-Lite system bus, bi-endian"; + case 0x04: + return "AHB"; + case 0x08: + return "AHB system bus, ASB processor bus"; + default: + return "Unknown"; + } +} + +static const char *integrator_fpga_str(u32 id) +{ + switch ((id >> 12) & 0xf) { + case 0x01: + return "XC4062"; + case 0x02: + return "XC4085"; + case 0x03: + return "XVC600"; + case 0x04: + return "EPM7256AE (Altera PLD)"; + default: + return "Unknown"; + } +} + +void cm_clear_irqs(void) +{ + /* disable core module IRQs */ + writel(0xffffffffU, cm_base + INTEGRATOR_HDR_IC_OFFSET + + IRQ_ENABLE_CLEAR); +} + +static const struct of_device_id cm_match[] = { + { .compatible = "arm,core-module-integrator"}, + { }, +}; + +void cm_init(void) +{ + struct device_node *cm = of_find_matching_node(NULL, cm_match); + u32 val; + + if (!cm) { + pr_crit("no core module node found in device tree\n"); + return; + } + cm_base = of_iomap(cm, 0); + if (!cm_base) { + pr_crit("could not remap core module\n"); + return; + } + cm_clear_irqs(); + val = readl(cm_base + INTEGRATOR_HDR_ID_OFFSET); + pr_info("Detected ARM core module:\n"); + pr_info(" Manufacturer: %02x\n", (val >> 24)); + pr_info(" Architecture: %s\n", integrator_arch_str(val)); + pr_info(" FPGA: %s\n", integrator_fpga_str(val)); + pr_info(" Build: %02x\n", (val >> 4) & 0xFF); + pr_info(" Rev: %c\n", ('A' + (val & 0x03))); +} /* * We need to stop things allocating the low memory; ideally we need a @@ -145,27 +166,7 @@ static ssize_t intcp_get_arch(struct device *dev, struct device_attribute *attr, char *buf) { - const char *arch; - - switch ((integrator_id >> 16) & 0xff) { - case 0x00: - arch = "ASB little-endian"; - break; - case 0x01: - arch = "AHB little-endian"; - break; - case 0x03: - arch = "AHB-Lite system bus, bi-endian"; - break; - case 0x04: - arch = "AHB"; - break; - default: - arch = "Unknown"; - break; - } - - return sprintf(buf, "%s\n", arch); + return sprintf(buf, "%s\n", integrator_arch_str(integrator_id)); } static struct device_attribute intcp_arch_attr = @@ -175,24 +176,7 @@ static ssize_t intcp_get_fpga(struct device *dev, struct device_attribute *attr, char *buf) { - const char *fpga; - - switch ((integrator_id >> 12) & 0xf) { - case 0x01: - fpga = "XC4062"; - break; - case 0x02: - fpga = "XC4085"; - break; - case 0x04: - fpga = "EPM7256AE (Altera PLD)"; - break; - default: - fpga = "Unknown"; - break; - } - - return sprintf(buf, "%s\n", fpga); + return sprintf(buf, "%s\n", integrator_fpga_str(integrator_id)); } static struct device_attribute intcp_fpga_attr = diff --git a/arch/arm/mach-integrator/include/mach/irqs.h b/arch/arm/mach-integrator/include/mach/irqs.h deleted file mode 100644 index eff0adad9ae3..000000000000 --- a/arch/arm/mach-integrator/include/mach/irqs.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * arch/arm/mach-integrator/include/mach/irqs.h - * - * Copyright (C) 1999 ARM Limited - * Copyright (C) 2000 Deep Blue Solutions Ltd. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * Interrupt numbers, all of the above are just static reservations - * used so they can be encoded into device resources. They will finally - * be done away with when switching to device tree. - */ -#define IRQ_PIC_START 64 -#define IRQ_SOFTINT (IRQ_PIC_START+0) -#define IRQ_UARTINT0 (IRQ_PIC_START+1) -#define IRQ_UARTINT1 (IRQ_PIC_START+2) -#define IRQ_KMIINT0 (IRQ_PIC_START+3) -#define IRQ_KMIINT1 (IRQ_PIC_START+4) -#define IRQ_TIMERINT0 (IRQ_PIC_START+5) -#define IRQ_TIMERINT1 (IRQ_PIC_START+6) -#define IRQ_TIMERINT2 (IRQ_PIC_START+7) -#define IRQ_RTCINT (IRQ_PIC_START+8) -#define IRQ_AP_EXPINT0 (IRQ_PIC_START+9) -#define IRQ_AP_EXPINT1 (IRQ_PIC_START+10) -#define IRQ_AP_EXPINT2 (IRQ_PIC_START+11) -#define IRQ_AP_EXPINT3 (IRQ_PIC_START+12) -#define IRQ_AP_PCIINT0 (IRQ_PIC_START+13) -#define IRQ_AP_PCIINT1 (IRQ_PIC_START+14) -#define IRQ_AP_PCIINT2 (IRQ_PIC_START+15) -#define IRQ_AP_PCIINT3 (IRQ_PIC_START+16) -#define IRQ_AP_V3INT (IRQ_PIC_START+17) -#define IRQ_AP_CPINT0 (IRQ_PIC_START+18) -#define IRQ_AP_CPINT1 (IRQ_PIC_START+19) -#define IRQ_AP_LBUSTIMEOUT (IRQ_PIC_START+20) -#define IRQ_AP_APCINT (IRQ_PIC_START+21) -#define IRQ_CP_CLCDCINT (IRQ_PIC_START+22) -#define IRQ_CP_MMCIINT0 (IRQ_PIC_START+23) -#define IRQ_CP_MMCIINT1 (IRQ_PIC_START+24) -#define IRQ_CP_AACIINT (IRQ_PIC_START+25) -#define IRQ_CP_CPPLDINT (IRQ_PIC_START+26) -#define IRQ_CP_ETHINT (IRQ_PIC_START+27) -#define IRQ_CP_TSPENINT (IRQ_PIC_START+28) -#define IRQ_PIC_END (IRQ_PIC_START+28) - -#define IRQ_CIC_START (IRQ_PIC_END+1) -#define IRQ_CM_SOFTINT (IRQ_CIC_START+0) -#define IRQ_CM_COMMRX (IRQ_CIC_START+1) -#define IRQ_CM_COMMTX (IRQ_CIC_START+2) -#define IRQ_CIC_END (IRQ_CIC_START+2) - -/* - * IntegratorCP only - */ -#define IRQ_SIC_START (IRQ_CIC_END+1) -#define IRQ_SIC_CP_SOFTINT (IRQ_SIC_START+0) -#define IRQ_SIC_CP_RI0 (IRQ_SIC_START+1) -#define IRQ_SIC_CP_RI1 (IRQ_SIC_START+2) -#define IRQ_SIC_CP_CARDIN (IRQ_SIC_START+3) -#define IRQ_SIC_CP_LMINT0 (IRQ_SIC_START+4) -#define IRQ_SIC_CP_LMINT1 (IRQ_SIC_START+5) -#define IRQ_SIC_CP_LMINT2 (IRQ_SIC_START+6) -#define IRQ_SIC_CP_LMINT3 (IRQ_SIC_START+7) -#define IRQ_SIC_CP_LMINT4 (IRQ_SIC_START+8) -#define IRQ_SIC_CP_LMINT5 (IRQ_SIC_START+9) -#define IRQ_SIC_CP_LMINT6 (IRQ_SIC_START+10) -#define IRQ_SIC_CP_LMINT7 (IRQ_SIC_START+11) -#define IRQ_SIC_END (IRQ_SIC_START+11) diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index d9e95e612fcb..d50dc2dbfd89 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c @@ -51,13 +51,13 @@ #include <asm/mach-types.h> #include <mach/lm.h> -#include <mach/irqs.h> #include <asm/mach/arch.h> #include <asm/mach/irq.h> #include <asm/mach/map.h> #include <asm/mach/time.h> +#include "cm.h" #include "common.h" #include "pci_v3.h" @@ -146,7 +146,7 @@ static int irq_suspend(void) static void irq_resume(void) { /* disable all irq sources */ - writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR); + cm_clear_irqs(); writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR); writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR); @@ -402,8 +402,6 @@ void __init ap_init_early(void) { } -#ifdef CONFIG_OF - static void __init ap_of_timer_init(void) { struct device_node *node; @@ -450,8 +448,7 @@ static const struct of_device_id fpga_irq_of_match[] __initconst = { static void __init ap_init_irq_of(void) { - /* disable core module IRQs */ - writel(0xffffffffU, VA_CMIC_BASE + IRQ_ENABLE_CLEAR); + cm_init(); of_irq_init(fpga_irq_of_match); integrator_clk_init(false); } @@ -473,6 +470,11 @@ static struct of_dev_auxdata ap_auxdata_lookup[] __initdata = { { /* sentinel */ }, }; +static const struct of_device_id ap_syscon_match[] = { + { .compatible = "arm,integrator-ap-syscon"}, + { }, +}; + static void __init ap_init_of(void) { unsigned long sc_dec; @@ -489,7 +491,8 @@ static void __init ap_init_of(void) root = of_find_node_by_path("/"); if (!root) return; - syscon = of_find_node_by_path("/syscon"); + + syscon = of_find_matching_node(root, ap_syscon_match); if (!syscon) return; @@ -541,7 +544,7 @@ static void __init ap_init_of(void) lmdev->resource.start = 0xc0000000 + 0x10000000 * i; lmdev->resource.end = lmdev->resource.start + 0x0fffffff; lmdev->resource.flags = IORESOURCE_MEM; - lmdev->irq = IRQ_AP_EXPINT0 + i; + lmdev->irq = irq_of_parse_and_map(syscon, i); lmdev->id = i; lm_device_register(lmdev); @@ -564,136 +567,3 @@ DT_MACHINE_START(INTEGRATOR_AP_DT, "ARM Integrator/AP (Device Tree)") .restart = integrator_restart, .dt_compat = ap_dt_board_compat, MACHINE_END - -#endif - -#ifdef CONFIG_ATAGS - -/* - * For the ATAG boot some static mappings are needed. This will - * go away with the ATAG support down the road. - */ - -static struct map_desc ap_io_desc_atag[] __initdata = { - { - .virtual = IO_ADDRESS(INTEGRATOR_SC_BASE), - .pfn = __phys_to_pfn(INTEGRATOR_SC_BASE), - .length = SZ_4K, - .type = MT_DEVICE - }, -}; - -static void __init ap_map_io_atag(void) -{ - iotable_init(ap_io_desc_atag, ARRAY_SIZE(ap_io_desc_atag)); - ap_map_io(); -} - -/* - * This is where non-devicetree initialization code is collected and stashed - * for eventual deletion. - */ - -static struct platform_device pci_v3_device = { - .name = "pci-v3", - .id = 0, -}; - -static struct resource cfi_flash_resource = { - .start = INTEGRATOR_FLASH_BASE, - .end = INTEGRATOR_FLASH_BASE + INTEGRATOR_FLASH_SIZE - 1, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device cfi_flash_device = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &ap_flash_data, - }, - .num_resources = 1, - .resource = &cfi_flash_resource, -}; - -static void __init ap_timer_init(void) -{ - struct clk *clk; - unsigned long rate; - - clk = clk_get_sys("ap_timer", NULL); - BUG_ON(IS_ERR(clk)); - clk_prepare_enable(clk); - rate = clk_get_rate(clk); - - writel(0, TIMER0_VA_BASE + TIMER_CTRL); - writel(0, TIMER1_VA_BASE + TIMER_CTRL); - writel(0, TIMER2_VA_BASE + TIMER_CTRL); - - integrator_clocksource_init(rate, (void __iomem *)TIMER2_VA_BASE); - integrator_clockevent_init(rate, (void __iomem *)TIMER1_VA_BASE, - IRQ_TIMERINT1); -} - -#define INTEGRATOR_SC_VALID_INT 0x003fffff - -static void __init ap_init_irq(void) -{ - /* Disable all interrupts initially. */ - /* Do the core module ones */ - writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR); - - /* do the header card stuff next */ - writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR); - writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR); - - fpga_irq_init(VA_IC_BASE, "SC", IRQ_PIC_START, - -1, INTEGRATOR_SC_VALID_INT, NULL); - integrator_clk_init(false); -} - -static void __init ap_init(void) -{ - unsigned long sc_dec; - int i; - - platform_device_register(&pci_v3_device); - platform_device_register(&cfi_flash_device); - - ap_syscon_base = __io_address(INTEGRATOR_SC_BASE); - sc_dec = readl(ap_syscon_base + INTEGRATOR_SC_DEC_OFFSET); - for (i = 0; i < 4; i++) { - struct lm_device *lmdev; - - if ((sc_dec & (16 << i)) == 0) - continue; - - lmdev = kzalloc(sizeof(struct lm_device), GFP_KERNEL); - if (!lmdev) - continue; - - lmdev->resource.start = 0xc0000000 + 0x10000000 * i; - lmdev->resource.end = lmdev->resource.start + 0x0fffffff; - lmdev->resource.flags = IORESOURCE_MEM; - lmdev->irq = IRQ_AP_EXPINT0 + i; - lmdev->id = i; - - lm_device_register(lmdev); - } - - integrator_init(false); -} - -MACHINE_START(INTEGRATOR, "ARM-Integrator") - /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ - .atag_offset = 0x100, - .reserve = integrator_reserve, - .map_io = ap_map_io_atag, - .init_early = ap_init_early, - .init_irq = ap_init_irq, - .handle_irq = fpga_handle_irq, - .init_time = ap_timer_init, - .init_machine = ap_init, - .restart = integrator_restart, -MACHINE_END - -#endif diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index 8c60fcb08a98..4fc0a195de01 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -36,9 +36,7 @@ #include <asm/hardware/arm_timer.h> #include <asm/hardware/icst.h> -#include <mach/cm.h> #include <mach/lm.h> -#include <mach/irqs.h> #include <asm/mach/arch.h> #include <asm/mach/irq.h> @@ -50,6 +48,7 @@ #include <plat/clcd.h> #include <plat/sched_clock.h> +#include "cm.h" #include "common.h" /* Base address to the CP controller */ @@ -199,7 +198,8 @@ static struct mmci_platform_data mmc_data = { static void cp_clcd_enable(struct clcd_fb *fb) { struct fb_var_screeninfo *var = &fb->fb.var; - u32 val = CM_CTRL_STATIC1 | CM_CTRL_STATIC2; + u32 val = CM_CTRL_STATIC1 | CM_CTRL_STATIC2 + | CM_CTRL_LCDEN0 | CM_CTRL_LCDEN1; if (var->bits_per_pixel <= 8 || (var->bits_per_pixel == 16 && var->green.length == 5)) @@ -249,7 +249,6 @@ static void __init intcp_init_early(void) #endif } -#ifdef CONFIG_OF static const struct of_device_id fpga_irq_of_match[] __initconst = { { .compatible = "arm,versatile-fpga-irq", .data = fpga_irq_of_init, }, { /* Sentinel */ } @@ -257,6 +256,7 @@ static const struct of_device_id fpga_irq_of_match[] __initconst = { static void __init intcp_init_irq_of(void) { + cm_init(); of_irq_init(fpga_irq_of_match); integrator_clk_init(true); } @@ -287,6 +287,11 @@ static struct of_dev_auxdata intcp_auxdata_lookup[] __initdata = { { /* sentinel */ }, }; +static const struct of_device_id intcp_syscon_match[] = { + { .compatible = "arm,integrator-cp-syscon"}, + { }, +}; + static void __init intcp_init_of(void) { struct device_node *root; @@ -301,7 +306,8 @@ static void __init intcp_init_of(void) root = of_find_node_by_path("/"); if (!root) return; - cpcon = of_find_node_by_path("/cpcon"); + + cpcon = of_find_matching_node(root, intcp_syscon_match); if (!cpcon) return; @@ -354,175 +360,3 @@ DT_MACHINE_START(INTEGRATOR_CP_DT, "ARM Integrator/CP (Device Tree)") .restart = integrator_restart, .dt_compat = intcp_dt_board_compat, MACHINE_END - -#endif - -#ifdef CONFIG_ATAGS - -/* - * For the ATAG boot some static mappings are needed. This will - * go away with the ATAG support down the road. - */ - -static struct map_desc intcp_io_desc_atag[] __initdata = { - { - .virtual = IO_ADDRESS(INTEGRATOR_CP_CTL_BASE), - .pfn = __phys_to_pfn(INTEGRATOR_CP_CTL_BASE), - .length = SZ_4K, - .type = MT_DEVICE - }, -}; - -static void __init intcp_map_io_atag(void) -{ - iotable_init(intcp_io_desc_atag, ARRAY_SIZE(intcp_io_desc_atag)); - intcp_con_base = __io_address(INTEGRATOR_CP_CTL_BASE); - intcp_map_io(); -} - - -/* - * This is where non-devicetree initialization code is collected and stashed - * for eventual deletion. - */ - -#define INTCP_FLASH_SIZE SZ_32M - -static struct resource intcp_flash_resource = { - .start = INTCP_PA_FLASH_BASE, - .end = INTCP_PA_FLASH_BASE + INTCP_FLASH_SIZE - 1, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device intcp_flash_device = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &intcp_flash_data, - }, - .num_resources = 1, - .resource = &intcp_flash_resource, -}; - -#define INTCP_ETH_SIZE 0x10 - -static struct resource smc91x_resources[] = { - [0] = { - .start = INTEGRATOR_CP_ETH_BASE, - .end = INTEGRATOR_CP_ETH_BASE + INTCP_ETH_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_CP_ETHINT, - .end = IRQ_CP_ETHINT, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device smc91x_device = { - .name = "smc91x", - .id = 0, - .num_resources = ARRAY_SIZE(smc91x_resources), - .resource = smc91x_resources, -}; - -static struct platform_device *intcp_devs[] __initdata = { - &intcp_flash_device, - &smc91x_device, -}; - -#define INTCP_VA_CIC_BASE __io_address(INTEGRATOR_HDR_BASE + 0x40) -#define INTCP_VA_PIC_BASE __io_address(INTEGRATOR_IC_BASE) -#define INTCP_VA_SIC_BASE __io_address(INTEGRATOR_CP_SIC_BASE) - -static void __init intcp_init_irq(void) -{ - u32 pic_mask, cic_mask, sic_mask; - - /* These masks are for the HW IRQ registers */ - pic_mask = ~((~0u) << (11 - 0)); - pic_mask |= (~((~0u) << (29 - 22))) << 22; - cic_mask = ~((~0u) << (1 + IRQ_CIC_END - IRQ_CIC_START)); - sic_mask = ~((~0u) << (1 + IRQ_SIC_END - IRQ_SIC_START)); - - /* - * Disable all interrupt sources - */ - writel(0xffffffff, INTCP_VA_PIC_BASE + IRQ_ENABLE_CLEAR); - writel(0xffffffff, INTCP_VA_PIC_BASE + FIQ_ENABLE_CLEAR); - writel(0xffffffff, INTCP_VA_CIC_BASE + IRQ_ENABLE_CLEAR); - writel(0xffffffff, INTCP_VA_CIC_BASE + FIQ_ENABLE_CLEAR); - writel(sic_mask, INTCP_VA_SIC_BASE + IRQ_ENABLE_CLEAR); - writel(sic_mask, INTCP_VA_SIC_BASE + FIQ_ENABLE_CLEAR); - - fpga_irq_init(INTCP_VA_PIC_BASE, "PIC", IRQ_PIC_START, - -1, pic_mask, NULL); - - fpga_irq_init(INTCP_VA_CIC_BASE, "CIC", IRQ_CIC_START, - -1, cic_mask, NULL); - - fpga_irq_init(INTCP_VA_SIC_BASE, "SIC", IRQ_SIC_START, - IRQ_CP_CPPLDINT, sic_mask, NULL); - - integrator_clk_init(true); -} - -#define TIMER0_VA_BASE __io_address(INTEGRATOR_TIMER0_BASE) -#define TIMER1_VA_BASE __io_address(INTEGRATOR_TIMER1_BASE) -#define TIMER2_VA_BASE __io_address(INTEGRATOR_TIMER2_BASE) - -static void __init cp_timer_init(void) -{ - writel(0, TIMER0_VA_BASE + TIMER_CTRL); - writel(0, TIMER1_VA_BASE + TIMER_CTRL); - writel(0, TIMER2_VA_BASE + TIMER_CTRL); - - sp804_clocksource_init(TIMER2_VA_BASE, "timer2"); - sp804_clockevents_init(TIMER1_VA_BASE, IRQ_TIMERINT1, "timer1"); -} - -#define INTEGRATOR_CP_MMC_IRQS { IRQ_CP_MMCIINT0, IRQ_CP_MMCIINT1 } -#define INTEGRATOR_CP_AACI_IRQS { IRQ_CP_AACIINT } - -static AMBA_APB_DEVICE(mmc, "mmci", 0, INTEGRATOR_CP_MMC_BASE, - INTEGRATOR_CP_MMC_IRQS, &mmc_data); - -static AMBA_APB_DEVICE(aaci, "aaci", 0, INTEGRATOR_CP_AACI_BASE, - INTEGRATOR_CP_AACI_IRQS, NULL); - -static AMBA_AHB_DEVICE(clcd, "clcd", 0, INTCP_PA_CLCD_BASE, - { IRQ_CP_CLCDCINT }, &clcd_data); - -static struct amba_device *amba_devs[] __initdata = { - &mmc_device, - &aaci_device, - &clcd_device, -}; - -static void __init intcp_init(void) -{ - int i; - - platform_add_devices(intcp_devs, ARRAY_SIZE(intcp_devs)); - - for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { - struct amba_device *d = amba_devs[i]; - amba_device_register(d, &iomem_resource); - } - integrator_init(true); -} - -MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP") - /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ - .atag_offset = 0x100, - .reserve = integrator_reserve, - .map_io = intcp_map_io_atag, - .init_early = intcp_init_early, - .init_irq = intcp_init_irq, - .handle_irq = fpga_handle_irq, - .init_time = cp_timer_init, - .init_machine = intcp_init, - .restart = integrator_restart, -MACHINE_END - -#endif diff --git a/arch/arm/mach-integrator/leds.c b/arch/arm/mach-integrator/leds.c index 7a7f6d3273bf..cb6ac58f5e07 100644 --- a/arch/arm/mach-integrator/leds.c +++ b/arch/arm/mach-integrator/leds.c @@ -11,10 +11,11 @@ #include <linux/slab.h> #include <linux/leds.h> -#include <mach/cm.h> #include <mach/hardware.h> #include <mach/platform.h> +#include "cm.h" + #if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS) #define ALPHA_REG __io_address(INTEGRATOR_DBG_BASE) @@ -78,7 +79,7 @@ static void cm_led_set(struct led_classdev *cdev, static enum led_brightness cm_led_get(struct led_classdev *cdev) { - u32 reg = readl(CM_CTRL); + u32 reg = cm_get(); return (reg & CM_CTRL_LED) ? LED_FULL : LED_OFF; } diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c index bef100527c42..c5e01b24d9fb 100644 --- a/arch/arm/mach-integrator/pci_v3.c +++ b/arch/arm/mach-integrator/pci_v3.c @@ -36,7 +36,6 @@ #include <mach/hardware.h> #include <mach/platform.h> -#include <mach/irqs.h> #include <asm/mach/map.h> #include <asm/signal.h> @@ -605,7 +604,7 @@ v3_pci_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) return 1; } -static irqreturn_t v3_irq(int dummy, void *devid) +static irqreturn_t v3_irq(int irq, void *devid) { #ifdef CONFIG_DEBUG_LL struct pt_regs *regs = get_irq_regs(); @@ -615,7 +614,7 @@ static irqreturn_t v3_irq(int dummy, void *devid) extern void printascii(const char *); sprintf(buf, "V3 int %d: pc=0x%08lx [%08lx] LBFADDR=%08x LBFCODE=%02x " - "ISTAT=%02x\n", IRQ_AP_V3INT, pc, instr, + "ISTAT=%02x\n", irq, pc, instr, __raw_readl(ap_syscon_base + INTEGRATOR_SC_LBFADDR_OFFSET), __raw_readl(ap_syscon_base + INTEGRATOR_SC_LBFCODE_OFFSET) & 255, v3_readb(V3_LB_ISTAT)); @@ -809,21 +808,6 @@ static u8 __init pci_v3_swizzle(struct pci_dev *dev, u8 *pinp) return pci_common_swizzle(dev, pinp); } -static int irq_tab[4] __initdata = { - IRQ_AP_PCIINT0, IRQ_AP_PCIINT1, IRQ_AP_PCIINT2, IRQ_AP_PCIINT3 -}; - -/* - * map the specified device/slot/pin to an IRQ. This works out such - * that slot 9 pin 1 is INT0, pin 2 is INT1, and slot 10 pin 1 is INT1. - */ -static int __init pci_v3_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) -{ - int intnr = ((slot - 9) + (pin - 1)) & 3; - - return irq_tab[intnr]; -} - static struct hw_pci pci_v3 __initdata = { .swizzle = pci_v3_swizzle, .setup = pci_v3_setup, @@ -833,32 +817,27 @@ static struct hw_pci pci_v3 __initdata = { .postinit = pci_v3_postinit, }; -#ifdef CONFIG_OF - -static int __init pci_v3_map_irq_dt(const struct pci_dev *dev, u8 slot, u8 pin) -{ - struct of_irq oirq; - int ret; - - ret = of_irq_map_pci(dev, &oirq); - if (ret) { - dev_err(&dev->dev, "of_irq_map_pci() %d\n", ret); - /* Proper return code 0 == NO_IRQ */ - return 0; - } - - return irq_create_of_mapping(oirq.controller, oirq.specifier, - oirq.size); -} - -static int __init pci_v3_dtprobe(struct platform_device *pdev, - struct device_node *np) +static int __init pci_v3_probe(struct platform_device *pdev) { + struct device_node *np = pdev->dev.of_node; struct of_pci_range_parser parser; struct of_pci_range range; struct resource *res; int irq, ret; + /* Remap the Integrator system controller */ + ap_syscon_base = devm_ioremap(&pdev->dev, INTEGRATOR_SC_BASE, 0x100); + if (!ap_syscon_base) { + dev_err(&pdev->dev, "unable to remap the AP syscon for PCIv3\n"); + return -ENODEV; + } + + /* Device tree probe path */ + if (!np) { + dev_err(&pdev->dev, "no device tree node for PCIv3\n"); + return -ENODEV; + } + if (of_pci_range_parser_init(&parser, np)) return -EINVAL; @@ -919,77 +898,7 @@ static int __init pci_v3_dtprobe(struct platform_device *pdev, return -EINVAL; } - pci_v3.map_irq = pci_v3_map_irq_dt; - pci_common_init_dev(&pdev->dev, &pci_v3); - - return 0; -} - -#else - -static inline int pci_v3_dtprobe(struct platform_device *pdev, - struct device_node *np) -{ - return -EINVAL; -} - -#endif - -static int __init pci_v3_probe(struct platform_device *pdev) -{ - struct device_node *np = pdev->dev.of_node; - int ret; - - /* Remap the Integrator system controller */ - ap_syscon_base = ioremap(INTEGRATOR_SC_BASE, 0x100); - if (!ap_syscon_base) { - dev_err(&pdev->dev, "unable to remap the AP syscon for PCIv3\n"); - return -ENODEV; - } - - /* Device tree probe path */ - if (np) - return pci_v3_dtprobe(pdev, np); - - pci_v3_base = devm_ioremap(&pdev->dev, PHYS_PCI_V3_BASE, SZ_64K); - if (!pci_v3_base) { - dev_err(&pdev->dev, "unable to remap PCIv3 base\n"); - return -ENODEV; - } - - ret = devm_request_irq(&pdev->dev, IRQ_AP_V3INT, v3_irq, 0, "V3", NULL); - if (ret) { - dev_err(&pdev->dev, "unable to grab PCI error interrupt: %d\n", - ret); - return -ENODEV; - } - - conf_mem.name = "PCIv3 config"; - conf_mem.start = PHYS_PCI_CONFIG_BASE; - conf_mem.end = PHYS_PCI_CONFIG_BASE + SZ_16M - 1; - conf_mem.flags = IORESOURCE_MEM; - - io_mem.name = "PCIv3 I/O"; - io_mem.start = PHYS_PCI_IO_BASE; - io_mem.end = PHYS_PCI_IO_BASE + SZ_16M - 1; - io_mem.flags = IORESOURCE_MEM; - - non_mem_pci = 0x00000000; - non_mem_pci_sz = SZ_256M; - non_mem.name = "PCIv3 non-prefetched mem"; - non_mem.start = PHYS_PCI_MEM_BASE; - non_mem.end = PHYS_PCI_MEM_BASE + SZ_256M - 1; - non_mem.flags = IORESOURCE_MEM; - - pre_mem_pci = 0x10000000; - pre_mem_pci_sz = SZ_256M; - pre_mem.name = "PCIv3 prefetched mem"; - pre_mem.start = PHYS_PCI_PRE_BASE + SZ_256M; - pre_mem.end = PHYS_PCI_PRE_BASE + SZ_256M - 1; - pre_mem.flags = IORESOURCE_MEM | IORESOURCE_PREFETCH; - - pci_v3.map_irq = pci_v3_map_irq; - + pci_v3.map_irq = of_irq_parse_and_map_pci; pci_common_init_dev(&pdev->dev, &pci_v3); return 0; diff --git a/arch/arm/mach-iop32x/em7210.c b/arch/arm/mach-iop32x/em7210.c index 31fbb6c61b25..177cd073a83b 100644 --- a/arch/arm/mach-iop32x/em7210.c +++ b/arch/arm/mach-iop32x/em7210.c @@ -32,6 +32,7 @@ #include <asm/mach/time.h> #include <asm/mach-types.h> #include <mach/time.h> +#include "gpio-iop32x.h" static void __init em7210_timer_init(void) { @@ -183,6 +184,7 @@ void em7210_power_off(void) static void __init em7210_init_machine(void) { + register_iop32x_gpio(); platform_device_register(&em7210_serial_device); platform_device_register(&iop3xx_i2c0_device); platform_device_register(&iop3xx_i2c1_device); diff --git a/arch/arm/mach-iop32x/glantank.c b/arch/arm/mach-iop32x/glantank.c index ac304705fe68..547b2342d61a 100644 --- a/arch/arm/mach-iop32x/glantank.c +++ b/arch/arm/mach-iop32x/glantank.c @@ -34,6 +34,7 @@ #include <asm/mach-types.h> #include <asm/page.h> #include <mach/time.h> +#include "gpio-iop32x.h" /* * GLAN Tank timer tick configuration. @@ -187,6 +188,7 @@ static void glantank_power_off(void) static void __init glantank_init_machine(void) { + register_iop32x_gpio(); platform_device_register(&iop3xx_i2c0_device); platform_device_register(&iop3xx_i2c1_device); platform_device_register(&glantank_flash_device); diff --git a/arch/arm/mach-iop32x/gpio-iop32x.h b/arch/arm/mach-iop32x/gpio-iop32x.h new file mode 100644 index 000000000000..3c7309c02029 --- /dev/null +++ b/arch/arm/mach-iop32x/gpio-iop32x.h @@ -0,0 +1,10 @@ +static struct resource iop32x_gpio_res[] = { + DEFINE_RES_MEM((IOP3XX_PERIPHERAL_PHYS_BASE + 0x07c4), 0x10), +}; + +static inline void register_iop32x_gpio(void) +{ + platform_device_register_simple("gpio-iop", 0, + iop32x_gpio_res, + ARRAY_SIZE(iop32x_gpio_res)); +} diff --git a/arch/arm/mach-iop32x/include/mach/gpio.h b/arch/arm/mach-iop32x/include/mach/gpio.h deleted file mode 100644 index 708f4ec9db1d..000000000000 --- a/arch/arm/mach-iop32x/include/mach/gpio.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ASM_ARCH_IOP32X_GPIO_H -#define __ASM_ARCH_IOP32X_GPIO_H - -#include <asm/hardware/iop3xx-gpio.h> - -#endif diff --git a/arch/arm/mach-iop32x/include/mach/iop32x.h b/arch/arm/mach-iop32x/include/mach/iop32x.h index 941f363aca56..56ec864ec313 100644 --- a/arch/arm/mach-iop32x/include/mach/iop32x.h +++ b/arch/arm/mach-iop32x/include/mach/iop32x.h @@ -19,7 +19,6 @@ * Peripherals that are shared between the iop32x and iop33x but * located at different addresses. */ -#define IOP3XX_GPIO_REG(reg) (IOP3XX_PERIPHERAL_VIRT_BASE + 0x07c4 + (reg)) #define IOP3XX_TIMER_REG(reg) (IOP3XX_PERIPHERAL_VIRT_BASE + 0x07e0 + (reg)) #include <asm/hardware/iop3xx.h> diff --git a/arch/arm/mach-iop32x/iq31244.c b/arch/arm/mach-iop32x/iq31244.c index f2cd2966212d..0e1392b20d18 100644 --- a/arch/arm/mach-iop32x/iq31244.c +++ b/arch/arm/mach-iop32x/iq31244.c @@ -37,6 +37,7 @@ #include <asm/page.h> #include <asm/pgtable.h> #include <mach/time.h> +#include "gpio-iop32x.h" /* * Until March of 2007 iq31244 platforms and ep80219 platforms shared the @@ -283,6 +284,7 @@ void ep80219_power_off(void) static void __init iq31244_init_machine(void) { + register_iop32x_gpio(); platform_device_register(&iop3xx_i2c0_device); platform_device_register(&iop3xx_i2c1_device); platform_device_register(&iq31244_flash_device); diff --git a/arch/arm/mach-iop32x/iq80321.c b/arch/arm/mach-iop32x/iq80321.c index 015435de90dd..66782ff1f46a 100644 --- a/arch/arm/mach-iop32x/iq80321.c +++ b/arch/arm/mach-iop32x/iq80321.c @@ -33,6 +33,7 @@ #include <asm/page.h> #include <asm/pgtable.h> #include <mach/time.h> +#include "gpio-iop32x.h" /* * IQ80321 timer tick configuration. @@ -170,6 +171,7 @@ static struct platform_device iq80321_serial_device = { static void __init iq80321_init_machine(void) { + register_iop32x_gpio(); platform_device_register(&iop3xx_i2c0_device); platform_device_register(&iop3xx_i2c1_device); platform_device_register(&iq80321_flash_device); diff --git a/arch/arm/mach-iop32x/n2100.c b/arch/arm/mach-iop32x/n2100.c index 069144300b77..c1cd80ecc219 100644 --- a/arch/arm/mach-iop32x/n2100.c +++ b/arch/arm/mach-iop32x/n2100.c @@ -30,6 +30,7 @@ #include <linux/platform_device.h> #include <linux/reboot.h> #include <linux/io.h> +#include <linux/gpio.h> #include <mach/hardware.h> #include <asm/irq.h> #include <asm/mach/arch.h> @@ -40,6 +41,7 @@ #include <asm/page.h> #include <asm/pgtable.h> #include <mach/time.h> +#include "gpio-iop32x.h" /* * N2100 timer tick configuration. @@ -288,8 +290,14 @@ static void n2100_power_off(void) static void n2100_restart(enum reboot_mode mode, const char *cmd) { - gpio_line_set(N2100_HARDWARE_RESET, GPIO_LOW); - gpio_line_config(N2100_HARDWARE_RESET, GPIO_OUT); + int ret; + + ret = gpio_direction_output(N2100_HARDWARE_RESET, 0); + if (ret) { + pr_crit("could not drive reset GPIO low\n"); + return; + } + /* Wait for reset to happen */ while (1) ; } @@ -299,7 +307,7 @@ static struct timer_list power_button_poll_timer; static void power_button_poll(unsigned long dummy) { - if (gpio_line_get(N2100_POWER_BUTTON) == 0) { + if (gpio_get_value(N2100_POWER_BUTTON) == 0) { ctrl_alt_del(); return; } @@ -308,9 +316,37 @@ static void power_button_poll(unsigned long dummy) add_timer(&power_button_poll_timer); } +static int __init n2100_request_gpios(void) +{ + int ret; + + if (!machine_is_n2100()) + return 0; + + ret = gpio_request(N2100_HARDWARE_RESET, "reset"); + if (ret) + pr_err("could not request reset GPIO\n"); + + ret = gpio_request(N2100_POWER_BUTTON, "power"); + if (ret) + pr_err("could not request power GPIO\n"); + else { + ret = gpio_direction_input(N2100_POWER_BUTTON); + if (ret) + pr_err("could not set power GPIO as input\n"); + } + /* Set up power button poll timer */ + init_timer(&power_button_poll_timer); + power_button_poll_timer.function = power_button_poll; + power_button_poll_timer.expires = jiffies + (HZ / 10); + add_timer(&power_button_poll_timer); + return 0; +} +device_initcall(n2100_request_gpios); static void __init n2100_init_machine(void) { + register_iop32x_gpio(); platform_device_register(&iop3xx_i2c0_device); platform_device_register(&n2100_flash_device); platform_device_register(&n2100_serial_device); @@ -321,11 +357,6 @@ static void __init n2100_init_machine(void) ARRAY_SIZE(n2100_i2c_devices)); pm_power_off = n2100_power_off; - - init_timer(&power_button_poll_timer); - power_button_poll_timer.function = power_button_poll; - power_button_poll_timer.expires = jiffies + (HZ / 10); - add_timer(&power_button_poll_timer); } MACHINE_START(N2100, "Thecus N2100") diff --git a/arch/arm/mach-iop33x/include/mach/gpio.h b/arch/arm/mach-iop33x/include/mach/gpio.h deleted file mode 100644 index ddd55bba9bb9..000000000000 --- a/arch/arm/mach-iop33x/include/mach/gpio.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ASM_ARCH_IOP33X_GPIO_H -#define __ASM_ARCH_IOP33X_GPIO_H - -#include <asm/hardware/iop3xx-gpio.h> - -#endif diff --git a/arch/arm/mach-iop33x/include/mach/iop33x.h b/arch/arm/mach-iop33x/include/mach/iop33x.h index a89c0a234bff..c95122653094 100644 --- a/arch/arm/mach-iop33x/include/mach/iop33x.h +++ b/arch/arm/mach-iop33x/include/mach/iop33x.h @@ -18,7 +18,6 @@ * Peripherals that are shared between the iop32x and iop33x but * located at different addresses. */ -#define IOP3XX_GPIO_REG(reg) (IOP3XX_PERIPHERAL_VIRT_BASE + 0x1780 + (reg)) #define IOP3XX_TIMER_REG(reg) (IOP3XX_PERIPHERAL_VIRT_BASE + 0x07d0 + (reg)) #include <asm/hardware/iop3xx.h> diff --git a/arch/arm/mach-iop33x/iq80331.c b/arch/arm/mach-iop33x/iq80331.c index c43304a10fa7..e2cb65cfbe23 100644 --- a/arch/arm/mach-iop33x/iq80331.c +++ b/arch/arm/mach-iop33x/iq80331.c @@ -122,8 +122,15 @@ static struct platform_device iq80331_flash_device = { .resource = &iq80331_flash_resource, }; +static struct resource iq80331_gpio_res[] = { + DEFINE_RES_MEM((IOP3XX_PERIPHERAL_PHYS_BASE + 0x1780), 0x10), +}; + static void __init iq80331_init_machine(void) { + platform_device_register_simple("gpio-iop", 0, + iq80331_gpio_res, + ARRAY_SIZE(iq80331_gpio_res)); platform_device_register(&iop3xx_i2c0_device); platform_device_register(&iop3xx_i2c1_device); platform_device_register(&iop33x_uart0_device); diff --git a/arch/arm/mach-iop33x/iq80332.c b/arch/arm/mach-iop33x/iq80332.c index 8192987e78e5..0b6269d94f89 100644 --- a/arch/arm/mach-iop33x/iq80332.c +++ b/arch/arm/mach-iop33x/iq80332.c @@ -122,8 +122,15 @@ static struct platform_device iq80332_flash_device = { .resource = &iq80332_flash_resource, }; +static struct resource iq80332_gpio_res[] = { + DEFINE_RES_MEM((IOP3XX_PERIPHERAL_PHYS_BASE + 0x1780), 0x10), +}; + static void __init iq80332_init_machine(void) { + platform_device_register_simple("gpio-iop", 0, + iq80332_gpio_res, + ARRAY_SIZE(iq80332_gpio_res)); platform_device_register(&iop3xx_i2c0_device); platform_device_register(&iop3xx_i2c1_device); platform_device_register(&iop33x_uart0_device); diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig index 30e1ebe3a891..c342dc4e8a45 100644 --- a/arch/arm/mach-ixp4xx/Kconfig +++ b/arch/arm/mach-ixp4xx/Kconfig @@ -1,9 +1,5 @@ if ARCH_IXP4XX -config ARCH_SUPPORTS_BIG_ENDIAN - bool - default y - menu "Intel IXP4xx Implementation Options" comment "IXP4xx Platforms" diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index 5327decde5a0..9edaf4734fa8 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c @@ -81,6 +81,44 @@ void __init ixp4xx_map_io(void) iotable_init(ixp4xx_io_desc, ARRAY_SIZE(ixp4xx_io_desc)); } +/* + * GPIO-functions + */ +/* + * The following converted to the real HW bits the gpio_line_config + */ +/* GPIO pin types */ +#define IXP4XX_GPIO_OUT 0x1 +#define IXP4XX_GPIO_IN 0x2 + +/* GPIO signal types */ +#define IXP4XX_GPIO_LOW 0 +#define IXP4XX_GPIO_HIGH 1 + +/* GPIO Clocks */ +#define IXP4XX_GPIO_CLK_0 14 +#define IXP4XX_GPIO_CLK_1 15 + +static void gpio_line_config(u8 line, u32 direction) +{ + if (direction == IXP4XX_GPIO_IN) + *IXP4XX_GPIO_GPOER |= (1 << line); + else + *IXP4XX_GPIO_GPOER &= ~(1 << line); +} + +static void gpio_line_get(u8 line, int *value) +{ + *value = (*IXP4XX_GPIO_GPINR >> line) & 0x1; +} + +static void gpio_line_set(u8 line, int value) +{ + if (value == IXP4XX_GPIO_HIGH) + *IXP4XX_GPIO_GPOUTR |= (1 << line); + else if (value == IXP4XX_GPIO_LOW) + *IXP4XX_GPIO_GPOUTR &= ~(1 << line); +} /************************************************************************* * IXP4xx chipset IRQ handling @@ -117,17 +155,6 @@ static int ixp4xx_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) return -EINVAL; } -int irq_to_gpio(unsigned int irq) -{ - int gpio = (irq < 32) ? irq2gpio[irq] : -EINVAL; - - if (gpio == -1) - return -EINVAL; - - return gpio; -} -EXPORT_SYMBOL(irq_to_gpio); - static int ixp4xx_set_irq_type(struct irq_data *d, unsigned int type) { int line = irq2gpio[d->irq]; diff --git a/arch/arm/mach-ixp4xx/dsmg600-setup.c b/arch/arm/mach-ixp4xx/dsmg600-setup.c index 63de1b3fd06b..736dc692d540 100644 --- a/arch/arm/mach-ixp4xx/dsmg600-setup.c +++ b/arch/arm/mach-ixp4xx/dsmg600-setup.c @@ -26,6 +26,7 @@ #include <linux/reboot.h> #include <linux/i2c.h> #include <linux/i2c-gpio.h> +#include <linux/gpio.h> #include <mach/hardware.h> @@ -161,11 +162,8 @@ static struct platform_device *dsmg600_devices[] __initdata = { static void dsmg600_power_off(void) { - /* enable the pwr cntl gpio */ - gpio_line_config(DSMG600_PO_GPIO, IXP4XX_GPIO_OUT); - - /* poweroff */ - gpio_line_set(DSMG600_PO_GPIO, IXP4XX_GPIO_HIGH); + /* enable the pwr cntl and drive it high */ + gpio_direction_output(DSMG600_PO_GPIO, 1); } /* This is used to make sure the power-button pusher is serious. The button @@ -202,7 +200,7 @@ static void dsmg600_power_handler(unsigned long data) ctrl_alt_del(); /* Change the state of the power LED to "blink" */ - gpio_line_set(DSMG600_LED_PWR_GPIO, IXP4XX_GPIO_LOW); + gpio_set_value(DSMG600_LED_PWR_GPIO, 0); } else { power_button_countdown = PBUTTON_HOLDDOWN_COUNT; } @@ -228,6 +226,40 @@ static void __init dsmg600_timer_init(void) ixp4xx_timer_init(); } +static int __init dsmg600_gpio_init(void) +{ + if (!machine_is_dsmg600()) + return 0; + + gpio_request(DSMG600_RB_GPIO, "reset button"); + if (request_irq(gpio_to_irq(DSMG600_RB_GPIO), &dsmg600_reset_handler, + IRQF_DISABLED | IRQF_TRIGGER_LOW, + "DSM-G600 reset button", NULL) < 0) { + + printk(KERN_DEBUG "Reset Button IRQ %d not available\n", + gpio_to_irq(DSMG600_RB_GPIO)); + } + + /* + * The power button on the D-Link DSM-G600 is on GPIO 15, but + * it cannot handle interrupts on that GPIO line. So we'll + * have to poll it with a kernel timer. + */ + + /* Make sure that the power button GPIO is set up as an input */ + gpio_request(DSMG600_PB_GPIO, "power button"); + gpio_direction_input(DSMG600_PB_GPIO); + /* Request poweroff GPIO line */ + gpio_request(DSMG600_PO_GPIO, "power off button"); + + /* Set the initial value for the power button IRQ handler */ + power_button_countdown = PBUTTON_HOLDDOWN_COUNT; + + mod_timer(&dsmg600_power_timer, jiffies + msecs_to_jiffies(500)); + return 0; +} +device_initcall(dsmg600_gpio_init); + static void __init dsmg600_init(void) { ixp4xx_sys_init(); @@ -251,27 +283,6 @@ static void __init dsmg600_init(void) platform_add_devices(dsmg600_devices, ARRAY_SIZE(dsmg600_devices)); pm_power_off = dsmg600_power_off; - - if (request_irq(gpio_to_irq(DSMG600_RB_GPIO), &dsmg600_reset_handler, - IRQF_DISABLED | IRQF_TRIGGER_LOW, - "DSM-G600 reset button", NULL) < 0) { - - printk(KERN_DEBUG "Reset Button IRQ %d not available\n", - gpio_to_irq(DSMG600_RB_GPIO)); - } - - /* The power button on the D-Link DSM-G600 is on GPIO 15, but - * it cannot handle interrupts on that GPIO line. So we'll - * have to poll it with a kernel timer. - */ - - /* Make sure that the power button GPIO is set up as an input */ - gpio_line_config(DSMG600_PB_GPIO, IXP4XX_GPIO_IN); - - /* Set the initial value for the power button IRQ handler */ - power_button_countdown = PBUTTON_HOLDDOWN_COUNT; - - mod_timer(&dsmg600_power_timer, jiffies + msecs_to_jiffies(500)); } MACHINE_START(DSMG600, "D-Link DSM-G600 RevA") diff --git a/arch/arm/mach-ixp4xx/include/mach/platform.h b/arch/arm/mach-ixp4xx/include/mach/platform.h index 4c4c6a6f4526..75c4c6572ad0 100644 --- a/arch/arm/mach-ixp4xx/include/mach/platform.h +++ b/arch/arm/mach-ixp4xx/include/mach/platform.h @@ -131,44 +131,5 @@ struct pci_sys_data; extern int ixp4xx_setup(int nr, struct pci_sys_data *sys); extern struct pci_ops ixp4xx_ops; -/* - * GPIO-functions - */ -/* - * The following converted to the real HW bits the gpio_line_config - */ -/* GPIO pin types */ -#define IXP4XX_GPIO_OUT 0x1 -#define IXP4XX_GPIO_IN 0x2 - -/* GPIO signal types */ -#define IXP4XX_GPIO_LOW 0 -#define IXP4XX_GPIO_HIGH 1 - -/* GPIO Clocks */ -#define IXP4XX_GPIO_CLK_0 14 -#define IXP4XX_GPIO_CLK_1 15 - -static inline void gpio_line_config(u8 line, u32 direction) -{ - if (direction == IXP4XX_GPIO_IN) - *IXP4XX_GPIO_GPOER |= (1 << line); - else - *IXP4XX_GPIO_GPOER &= ~(1 << line); -} - -static inline void gpio_line_get(u8 line, int *value) -{ - *value = (*IXP4XX_GPIO_GPINR >> line) & 0x1; -} - -static inline void gpio_line_set(u8 line, int value) -{ - if (value == IXP4XX_GPIO_HIGH) - *IXP4XX_GPIO_GPOUTR |= (1 << line); - else if (value == IXP4XX_GPIO_LOW) - *IXP4XX_GPIO_GPOUTR &= ~(1 << line); -} - #endif // __ASSEMBLY__ diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c index 22d688b7d513..e7b8befa8729 100644 --- a/arch/arm/mach-ixp4xx/ixdp425-setup.c +++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c @@ -20,6 +20,7 @@ #include <linux/mtd/nand.h> #include <linux/mtd/partitions.h> #include <linux/delay.h> +#include <linux/gpio.h> #include <asm/types.h> #include <asm/setup.h> #include <asm/memory.h> @@ -80,10 +81,10 @@ ixdp425_flash_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) if (ctrl & NAND_CTRL_CHANGE) { if (ctrl & NAND_NCE) { - gpio_line_set(IXDP425_NAND_NCE_PIN, IXP4XX_GPIO_LOW); + gpio_set_value(IXDP425_NAND_NCE_PIN, 0); udelay(5); } else - gpio_line_set(IXDP425_NAND_NCE_PIN, IXP4XX_GPIO_HIGH); + gpio_set_value(IXDP425_NAND_NCE_PIN, 1); offset = (ctrl & NAND_CLE) ? IXDP425_NAND_CMD_BYTE : 0; offset |= (ctrl & NAND_ALE) ? IXDP425_NAND_ADDR_BYTE : 0; @@ -227,7 +228,8 @@ static void __init ixdp425_init(void) ixdp425_flash_nand_resource.start = IXP4XX_EXP_BUS_BASE(3), ixdp425_flash_nand_resource.end = IXP4XX_EXP_BUS_BASE(3) + 0x10 - 1; - gpio_line_config(IXDP425_NAND_NCE_PIN, IXP4XX_GPIO_OUT); + gpio_request(IXDP425_NAND_NCE_PIN, "NAND NCE pin"); + gpio_direction_output(IXDP425_NAND_NCE_PIN, 0); /* Configure expansion bus for NAND Flash */ *IXP4XX_EXP_CS3 = IXP4XX_EXP_BUS_CS_EN | diff --git a/arch/arm/mach-ixp4xx/nas100d-setup.c b/arch/arm/mach-ixp4xx/nas100d-setup.c index ed667ce9f576..507cb5233537 100644 --- a/arch/arm/mach-ixp4xx/nas100d-setup.c +++ b/arch/arm/mach-ixp4xx/nas100d-setup.c @@ -184,11 +184,8 @@ static void nas100d_power_off(void) { /* This causes the box to drop the power and go dead. */ - /* enable the pwr cntl gpio */ - gpio_line_config(NAS100D_PO_GPIO, IXP4XX_GPIO_OUT); - - /* do the deed */ - gpio_line_set(NAS100D_PO_GPIO, IXP4XX_GPIO_HIGH); + /* enable the pwr cntl gpio and assert power off */ + gpio_direction_output(NAS100D_PO_GPIO, 1); } /* This is used to make sure the power-button pusher is serious. The button @@ -225,7 +222,7 @@ static void nas100d_power_handler(unsigned long data) ctrl_alt_del(); /* Change the state of the power LED to "blink" */ - gpio_line_set(NAS100D_LED_PWR_GPIO, IXP4XX_GPIO_LOW); + gpio_set_value(NAS100D_LED_PWR_GPIO, 0); } else { power_button_countdown = PBUTTON_HOLDDOWN_COUNT; } @@ -242,6 +239,33 @@ static irqreturn_t nas100d_reset_handler(int irq, void *dev_id) return IRQ_HANDLED; } +static int __init nas100d_gpio_init(void) +{ + if (!machine_is_nas100d()) + return 0; + + /* + * The power button on the Iomega NAS100d is on GPIO 14, but + * it cannot handle interrupts on that GPIO line. So we'll + * have to poll it with a kernel timer. + */ + + /* Request the power off GPIO */ + gpio_request(NAS100D_PO_GPIO, "power off"); + + /* Make sure that the power button GPIO is set up as an input */ + gpio_request(NAS100D_PB_GPIO, "power button"); + gpio_direction_input(NAS100D_PB_GPIO); + + /* Set the initial value for the power button IRQ handler */ + power_button_countdown = PBUTTON_HOLDDOWN_COUNT; + + mod_timer(&nas100d_power_timer, jiffies + msecs_to_jiffies(500)); + + return 0; +} +device_initcall(nas100d_gpio_init); + static void __init nas100d_init(void) { uint8_t __iomem *f; @@ -278,19 +302,6 @@ static void __init nas100d_init(void) gpio_to_irq(NAS100D_RB_GPIO)); } - /* The power button on the Iomega NAS100d is on GPIO 14, but - * it cannot handle interrupts on that GPIO line. So we'll - * have to poll it with a kernel timer. - */ - - /* Make sure that the power button GPIO is set up as an input */ - gpio_line_config(NAS100D_PB_GPIO, IXP4XX_GPIO_IN); - - /* Set the initial value for the power button IRQ handler */ - power_button_countdown = PBUTTON_HOLDDOWN_COUNT; - - mod_timer(&nas100d_power_timer, jiffies + msecs_to_jiffies(500)); - /* * Map in a portion of the flash and read the MAC address. * Since it is stored in BE in the flash itself, we need to diff --git a/arch/arm/mach-ixp4xx/nslu2-setup.c b/arch/arm/mach-ixp4xx/nslu2-setup.c index 7e55236c26ea..ba5f1cda2a9d 100644 --- a/arch/arm/mach-ixp4xx/nslu2-setup.c +++ b/arch/arm/mach-ixp4xx/nslu2-setup.c @@ -197,11 +197,8 @@ static void nslu2_power_off(void) { /* This causes the box to drop the power and go dead. */ - /* enable the pwr cntl gpio */ - gpio_line_config(NSLU2_PO_GPIO, IXP4XX_GPIO_OUT); - - /* do the deed */ - gpio_line_set(NSLU2_PO_GPIO, IXP4XX_GPIO_HIGH); + /* enable the pwr cntl gpio and assert power off */ + gpio_direction_output(NSLU2_PO_GPIO, 1); } static irqreturn_t nslu2_power_handler(int irq, void *dev_id) @@ -223,6 +220,16 @@ static irqreturn_t nslu2_reset_handler(int irq, void *dev_id) return IRQ_HANDLED; } +static int __init nslu2_gpio_init(void) +{ + if (!machine_is_nslu2()) + return 0; + + /* Request the power off GPIO */ + return gpio_request(NSLU2_PO_GPIO, "power off"); +} +device_initcall(nslu2_gpio_init); + static void __init nslu2_timer_init(void) { /* The xtal on this machine is non-standard. */ diff --git a/arch/arm/mach-keystone/Kconfig b/arch/arm/mach-keystone/Kconfig index 366d1a3b418d..f20c53e75ed9 100644 --- a/arch/arm/mach-keystone/Kconfig +++ b/arch/arm/mach-keystone/Kconfig @@ -9,6 +9,8 @@ config ARCH_KEYSTONE select GENERIC_CLOCKEVENTS select ARCH_WANT_OPTIONAL_GPIOLIB select ARM_ERRATA_798181 if SMP + select COMMON_CLK_KEYSTONE + select TI_EDMA help Support for boards based on the Texas Instruments Keystone family of SoCs. diff --git a/arch/arm/mach-keystone/Makefile b/arch/arm/mach-keystone/Makefile index ddc52b05dc84..25d92396fbfa 100644 --- a/arch/arm/mach-keystone/Makefile +++ b/arch/arm/mach-keystone/Makefile @@ -4,3 +4,6 @@ plus_sec := $(call as-instr,.arch_extension sec,+sec) AFLAGS_smc.o :=-Wa,-march=armv7-a$(plus_sec) obj-$(CONFIG_SMP) += platsmp.o + +# PM domain driver for Keystone SOCs +obj-$(CONFIG_ARCH_KEYSTONE) += pm_domain.o diff --git a/arch/arm/mach-keystone/platsmp.c b/arch/arm/mach-keystone/platsmp.c index c12296157d4a..5cf0683577ea 100644 --- a/arch/arm/mach-keystone/platsmp.c +++ b/arch/arm/mach-keystone/platsmp.c @@ -17,7 +17,6 @@ #include <linux/io.h> #include <asm/smp_plat.h> -#include <asm/prom.h> #include "keystone.h" diff --git a/arch/arm/mach-keystone/pm_domain.c b/arch/arm/mach-keystone/pm_domain.c new file mode 100644 index 000000000000..29625232e954 --- /dev/null +++ b/arch/arm/mach-keystone/pm_domain.c @@ -0,0 +1,82 @@ +/* + * PM domain driver for Keystone2 devices + * + * Copyright 2013 Texas Instruments, Inc. + * Santosh Shilimkar <santosh.shillimkar@ti.com> + * + * Based on Kevins work on DAVINCI SOCs + * Kevin Hilman <khilman@linaro.org> + * + * 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. + */ + +#include <linux/init.h> +#include <linux/pm_runtime.h> +#include <linux/pm_clock.h> +#include <linux/platform_device.h> +#include <linux/clk-provider.h> +#include <linux/of.h> + +#ifdef CONFIG_PM_RUNTIME +static int keystone_pm_runtime_suspend(struct device *dev) +{ + int ret; + + dev_dbg(dev, "%s\n", __func__); + + ret = pm_generic_runtime_suspend(dev); + if (ret) + return ret; + + ret = pm_clk_suspend(dev); + if (ret) { + pm_generic_runtime_resume(dev); + return ret; + } + + return 0; +} + +static int keystone_pm_runtime_resume(struct device *dev) +{ + dev_dbg(dev, "%s\n", __func__); + + pm_clk_resume(dev); + + return pm_generic_runtime_resume(dev); +} +#endif + +static struct dev_pm_domain keystone_pm_domain = { + .ops = { + SET_RUNTIME_PM_OPS(keystone_pm_runtime_suspend, + keystone_pm_runtime_resume, NULL) + USE_PLATFORM_PM_SLEEP_OPS + }, +}; + +static struct pm_clk_notifier_block platform_domain_notifier = { + .pm_domain = &keystone_pm_domain, +}; + +static struct of_device_id of_keystone_table[] = { + {.compatible = "ti,keystone"}, + { /* end of list */ }, +}; + +int __init keystone_pm_runtime_init(void) +{ + struct device_node *np; + + np = of_find_matching_node(NULL, of_keystone_table); + if (!np) + return 0; + + of_clk_init(NULL); + pm_clk_add_notifier(&platform_bus_type, &platform_domain_notifier); + + return 0; +} +subsys_initcall(keystone_pm_runtime_init); diff --git a/arch/arm/mach-kirkwood/Makefile b/arch/arm/mach-kirkwood/Makefile index d1f8e3d0793b..144b51102939 100644 --- a/arch/arm/mach-kirkwood/Makefile +++ b/arch/arm/mach-kirkwood/Makefile @@ -1,5 +1,7 @@ obj-y += common.o pcie.o obj-$(CONFIG_KIRKWOOD_LEGACY) += irq.o mpp.o +obj-$(CONFIG_PM) += pm.o + obj-$(CONFIG_MACH_D2NET_V2) += d2net_v2-setup.o lacie_v2-common.o obj-$(CONFIG_MACH_NET2BIG_V2) += netxbig_v2-setup.o lacie_v2-common.o obj-$(CONFIG_MACH_NET5BIG_V2) += netxbig_v2-setup.o lacie_v2-common.o diff --git a/arch/arm/mach-kirkwood/board-dt.c b/arch/arm/mach-kirkwood/board-dt.c index 82d3ad8e87cf..9caa4fe95913 100644 --- a/arch/arm/mach-kirkwood/board-dt.c +++ b/arch/arm/mach-kirkwood/board-dt.c @@ -13,9 +13,10 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_net.h> #include <linux/of_platform.h> #include <linux/clk-provider.h> -#include <linux/clocksource.h> #include <linux/dma-mapping.h> #include <linux/irqchip.h> #include <linux/kexec.h> @@ -44,14 +45,6 @@ static void __init kirkwood_legacy_clk_init(void) clkspec.np = np; clkspec.args_count = 1; - clkspec.args[0] = CGC_BIT_PEX0; - orion_clkdev_add("0", "pcie", - of_clk_get_from_provider(&clkspec)); - - clkspec.args[0] = CGC_BIT_PEX1; - orion_clkdev_add("1", "pcie", - of_clk_get_from_provider(&clkspec)); - /* * The ethernet interfaces forget the MAC address assigned by * u-boot if the clocks are turned off. Until proper DT support @@ -66,17 +59,83 @@ static void __init kirkwood_legacy_clk_init(void) clk_prepare_enable(clk); } -static void __init kirkwood_dt_time_init(void) -{ - of_clk_init(NULL); - clocksource_of_init(); -} +#define MV643XX_ETH_MAC_ADDR_LOW 0x0414 +#define MV643XX_ETH_MAC_ADDR_HIGH 0x0418 -static void __init kirkwood_dt_init_early(void) +static void __init kirkwood_dt_eth_fixup(void) { - mvebu_mbus_init("marvell,kirkwood-mbus", - BRIDGE_WINS_BASE, BRIDGE_WINS_SZ, - DDR_WINDOW_CPU_BASE, DDR_WINDOW_CPU_SZ); + struct device_node *np; + + /* + * The ethernet interfaces forget the MAC address assigned by u-boot + * if the clocks are turned off. Usually, u-boot on kirkwood boards + * has no DT support to properly set local-mac-address property. + * As a workaround, we get the MAC address from mv643xx_eth registers + * and update the port device node if no valid MAC address is set. + */ + for_each_compatible_node(np, NULL, "marvell,kirkwood-eth-port") { + struct device_node *pnp = of_get_parent(np); + struct clk *clk; + struct property *pmac; + void __iomem *io; + u8 *macaddr; + u32 reg; + + if (!pnp) + continue; + + /* skip disabled nodes or nodes with valid MAC address*/ + if (!of_device_is_available(pnp) || of_get_mac_address(np)) + goto eth_fixup_skip; + + clk = of_clk_get(pnp, 0); + if (IS_ERR(clk)) + goto eth_fixup_skip; + + io = of_iomap(pnp, 0); + if (!io) + goto eth_fixup_no_map; + + /* ensure port clock is not gated to not hang CPU */ + clk_prepare_enable(clk); + + /* store MAC address register contents in local-mac-address */ + pr_err(FW_INFO "%s: local-mac-address is not set\n", + np->full_name); + + pmac = kzalloc(sizeof(*pmac) + 6, GFP_KERNEL); + if (!pmac) + goto eth_fixup_no_mem; + + pmac->value = pmac + 1; + pmac->length = 6; + pmac->name = kstrdup("local-mac-address", GFP_KERNEL); + if (!pmac->name) { + kfree(pmac); + goto eth_fixup_no_mem; + } + + macaddr = pmac->value; + reg = readl(io + MV643XX_ETH_MAC_ADDR_HIGH); + macaddr[0] = (reg >> 24) & 0xff; + macaddr[1] = (reg >> 16) & 0xff; + macaddr[2] = (reg >> 8) & 0xff; + macaddr[3] = reg & 0xff; + + reg = readl(io + MV643XX_ETH_MAC_ADDR_LOW); + macaddr[4] = (reg >> 8) & 0xff; + macaddr[5] = reg & 0xff; + + of_update_property(np, pmac); + +eth_fixup_no_mem: + iounmap(io); + clk_disable_unprepare(clk); +eth_fixup_no_map: + clk_put(clk); +eth_fixup_skip: + of_node_put(pnp); + } } static void __init kirkwood_dt_init(void) @@ -92,16 +151,16 @@ static void __init kirkwood_dt_init(void) writel(readl(CPU_CONFIG) & ~CPU_CONFIG_ERROR_PROP, CPU_CONFIG); BUG_ON(mvebu_mbus_dt_init()); - kirkwood_setup_wins(); kirkwood_l2_init(); kirkwood_cpufreq_init(); - + kirkwood_cpuidle_init(); /* Setup clocks for legacy devices */ kirkwood_legacy_clk_init(); - kirkwood_cpuidle_init(); + kirkwood_pm_init(); + kirkwood_dt_eth_fixup(); #ifdef CONFIG_KEXEC kexec_reinit = kirkwood_enable_pcie; @@ -121,8 +180,6 @@ static const char * const kirkwood_dt_board_compat[] = { DT_MACHINE_START(KIRKWOOD_DT, "Marvell Kirkwood (Flattened Device Tree)") /* Maintainer: Jason Cooper <jason@lakedaemon.net> */ .map_io = kirkwood_map_io, - .init_early = kirkwood_dt_init_early, - .init_time = kirkwood_dt_time_init, .init_machine = kirkwood_dt_init, .restart = kirkwood_restart, .dt_compat = kirkwood_dt_board_compat, diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index 176761134a66..f3407a5db216 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c @@ -721,6 +721,7 @@ void __init kirkwood_init(void) kirkwood_xor1_init(); kirkwood_crypto_init(); + kirkwood_pm_init(); kirkwood_cpuidle_init(); #ifdef CONFIG_KEXEC kexec_reinit = kirkwood_enable_pcie; diff --git a/arch/arm/mach-kirkwood/common.h b/arch/arm/mach-kirkwood/common.h index 1296de94febf..05fd648df543 100644 --- a/arch/arm/mach-kirkwood/common.h +++ b/arch/arm/mach-kirkwood/common.h @@ -58,6 +58,12 @@ void kirkwood_cpufreq_init(void); void kirkwood_restart(enum reboot_mode, const char *); void kirkwood_clk_init(void); +#ifdef CONFIG_PM +void kirkwood_pm_init(void); +#else +static inline void kirkwood_pm_init(void) {}; +#endif + /* board init functions for boards not fully converted to fdt */ #ifdef CONFIG_MACH_MV88F6281GTW_GE_DT void mv88f6281gtw_ge_init(void); diff --git a/arch/arm/mach-kirkwood/include/mach/bridge-regs.h b/arch/arm/mach-kirkwood/include/mach/bridge-regs.h index 91242c944d7a..8b9d1c9ff199 100644 --- a/arch/arm/mach-kirkwood/include/mach/bridge-regs.h +++ b/arch/arm/mach-kirkwood/include/mach/bridge-regs.h @@ -78,4 +78,6 @@ #define CGC_TDM (1 << 20) #define CGC_RESERVED (0x6 << 21) +#define MEMORY_PM_CTRL (BRIDGE_VIRT_BASE + 0x118) + #endif diff --git a/arch/arm/mach-kirkwood/lacie_v2-common.c b/arch/arm/mach-kirkwood/lacie_v2-common.c index 489495976fcd..8e3e4331c380 100644 --- a/arch/arm/mach-kirkwood/lacie_v2-common.c +++ b/arch/arm/mach-kirkwood/lacie_v2-common.c @@ -12,7 +12,7 @@ #include <linux/spi/flash.h> #include <linux/spi/spi.h> #include <linux/i2c.h> -#include <linux/i2c/at24.h> +#include <linux/platform_data/at24.h> #include <linux/gpio.h> #include <asm/mach/time.h> #include <mach/kirkwood.h> diff --git a/arch/arm/mach-kirkwood/pm.c b/arch/arm/mach-kirkwood/pm.c new file mode 100644 index 000000000000..8783a7184e73 --- /dev/null +++ b/arch/arm/mach-kirkwood/pm.c @@ -0,0 +1,73 @@ +/* + * Power Management driver for Marvell Kirkwood SoCs + * + * Copyright (C) 2013 Ezequiel Garcia <ezequiel@free-electrons.com> + * Copyright (C) 2010 Simon Guinot <sguinot@lacie.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 of the License. + * + * This program is distributed in the hope that 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. + */ + +#include <linux/kernel.h> +#include <linux/suspend.h> +#include <linux/io.h> +#include <mach/bridge-regs.h> + +static void __iomem *ddr_operation_base; + +static void kirkwood_low_power(void) +{ + u32 mem_pm_ctrl; + + mem_pm_ctrl = readl(MEMORY_PM_CTRL); + + /* Set peripherals to low-power mode */ + writel_relaxed(~0, MEMORY_PM_CTRL); + + /* Set DDR in self-refresh */ + writel_relaxed(0x7, ddr_operation_base); + + /* + * Set CPU in wait-for-interrupt state. + * This disables the CPU core clocks, + * the array clocks, and also the L2 controller. + */ + cpu_do_idle(); + + writel_relaxed(mem_pm_ctrl, MEMORY_PM_CTRL); +} + +static int kirkwood_suspend_enter(suspend_state_t state) +{ + switch (state) { + case PM_SUSPEND_STANDBY: + kirkwood_low_power(); + break; + default: + return -EINVAL; + } + return 0; +} + +static int kirkwood_pm_valid_standby(suspend_state_t state) +{ + return state == PM_SUSPEND_STANDBY; +} + +static const struct platform_suspend_ops kirkwood_suspend_ops = { + .enter = kirkwood_suspend_enter, + .valid = kirkwood_pm_valid_standby, +}; + +int __init kirkwood_pm_init(void) +{ + ddr_operation_base = ioremap(DDR_OPERATION_BASE, 4); + suspend_set_ops(&kirkwood_suspend_ops); + return 0; +} diff --git a/arch/arm/mach-mmp/include/mach/gpio.h b/arch/arm/mach-mmp/include/mach/gpio.h deleted file mode 100644 index 13219ebf5128..000000000000 --- a/arch/arm/mach-mmp/include/mach/gpio.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __ASM_MACH_GPIO_H -#define __ASM_MACH_GPIO_H - -#include <asm-generic/gpio.h> - -#include <mach/cputype.h> - -#endif /* __ASM_MACH_GPIO_H */ diff --git a/arch/arm/mach-mmp/ttc_dkb.c b/arch/arm/mach-mmp/ttc_dkb.c index 702232996c8c..cfadd974f5ce 100644 --- a/arch/arm/mach-mmp/ttc_dkb.c +++ b/arch/arm/mach-mmp/ttc_dkb.c @@ -191,7 +191,6 @@ static struct pxa3xx_nand_platform_data dkb_nand_info = { #define SCLK_SOURCE_SELECT(x) (x << 30) /* 0x0 ~ 0x3 */ /* link config */ #define CFG_DUMBMODE(mode) (mode << 28) /* 0x0 ~ 0x6*/ -#define CFG_GRA_SWAPRB(x) (x << 0) /* 1: rbswap enabled */ static struct mmp_mach_path_config dkb_disp_config[] = { [0] = { .name = "mmp-parallel", @@ -199,8 +198,7 @@ static struct mmp_mach_path_config dkb_disp_config[] = { .output_type = PATH_OUT_PARALLEL, .path_config = CFG_IOPADMODE(0x1) | SCLK_SOURCE_SELECT(0x1), - .link_config = CFG_DUMBMODE(0x2) - | CFG_GRA_SWAPRB(0x1), + .link_config = CFG_DUMBMODE(0x2), }, }; diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig index 905efc8cac79..2586c2865874 100644 --- a/arch/arm/mach-msm/Kconfig +++ b/arch/arm/mach-msm/Kconfig @@ -1,12 +1,12 @@ if ARCH_MSM comment "Qualcomm MSM SoC Type" - depends on (ARCH_MSM8X60 || ARCH_MSM8960) + depends on ARCH_MSM_DT choice prompt "Qualcomm MSM SoC Type" default ARCH_MSM7X00A - depends on !(ARCH_MSM8X60 || ARCH_MSM8960) + depends on !ARCH_MSM_DT config ARCH_MSM7X00A bool "MSM7x00A / MSM7x01A" @@ -49,7 +49,6 @@ config ARCH_MSM8X60 select GPIO_MSM_V2 select HAVE_SMP select MSM_SCM if SMP - select USE_OF config ARCH_MSM8960 bool "MSM8960" @@ -58,6 +57,11 @@ config ARCH_MSM8960 select HAVE_SMP select GPIO_MSM_V2 select MSM_SCM if SMP + +config ARCH_MSM_DT + def_bool y + depends on (ARCH_MSM8X60 || ARCH_MSM8960) + select SPARSE_IRQ select USE_OF config MSM_HAS_DEBUG_UART_HS @@ -68,6 +72,7 @@ config MSM_SOC_REV_A config ARCH_MSM_ARM11 bool + config ARCH_MSM_SCORPION bool @@ -75,6 +80,7 @@ config MSM_VIC bool menu "Qualcomm MSM Board Type" + depends on !ARCH_MSM_DT config MACH_HALIBUT depends on ARCH_MSM @@ -122,6 +128,7 @@ config MSM_SMD config MSM_GPIOMUX bool + depends on !ARCH_MSM_DT help Support for MSM V1 TLMM GPIOMUX architecture. diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile index d872634c2f85..7ed4c1b2bdd2 100644 --- a/arch/arm/mach-msm/Makefile +++ b/arch/arm/mach-msm/Makefile @@ -26,7 +26,6 @@ obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o b obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o devices-msm7x00.o obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o obj-$(CONFIG_ARCH_QSD8X50) += board-qsd8x50.o devices-qsd8x50.o -obj-$(CONFIG_ARCH_MSM8X60) += board-dt-8660.o -obj-$(CONFIG_ARCH_MSM8960) += board-dt-8960.o +obj-$(CONFIG_ARCH_MSM_DT) += board-dt.o obj-$(CONFIG_MSM_GPIOMUX) += gpiomux.o obj-$(CONFIG_ARCH_QSD8X50) += gpiomux-8x50.o diff --git a/arch/arm/mach-msm/board-dt-8660.c b/arch/arm/mach-msm/board-dt-8660.c deleted file mode 100644 index c2946892f5e3..000000000000 --- a/arch/arm/mach-msm/board-dt-8660.c +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that 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. - */ - -#include <linux/init.h> -#include <linux/of.h> -#include <linux/of_platform.h> - -#include <asm/mach/arch.h> -#include <asm/mach/map.h> - -#include "common.h" - -static void __init msm8x60_init_late(void) -{ - smd_debugfs_init(); -} - -static struct of_dev_auxdata msm_auxdata_lookup[] __initdata = { - {} -}; - -static void __init msm8x60_dt_init(void) -{ - of_platform_populate(NULL, of_default_bus_match_table, - msm_auxdata_lookup, NULL); -} - -static const char *msm8x60_fluid_match[] __initdata = { - "qcom,msm8660-fluid", - "qcom,msm8660-surf", - NULL -}; - -DT_MACHINE_START(MSM_DT, "Qualcomm MSM (Flattened Device Tree)") - .smp = smp_ops(msm_smp_ops), - .init_machine = msm8x60_dt_init, - .init_late = msm8x60_init_late, - .dt_compat = msm8x60_fluid_match, -MACHINE_END diff --git a/arch/arm/mach-msm/board-dt-8960.c b/arch/arm/mach-msm/board-dt.c index d4ca52c45111..16e6183ac9f1 100644 --- a/arch/arm/mach-msm/board-dt-8960.c +++ b/arch/arm/mach-msm/board-dt.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2012,2013 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -11,6 +11,7 @@ */ #include <linux/init.h> +#include <linux/of.h> #include <linux/of_platform.h> #include <asm/mach/arch.h> @@ -18,18 +19,14 @@ #include "common.h" -static void __init msm_dt_init(void) -{ - of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); -} - -static const char * const msm8960_dt_match[] __initconst = { +static const char * const msm_dt_match[] __initconst = { + "qcom,msm8660-fluid", + "qcom,msm8660-surf", "qcom,msm8960-cdp", NULL }; -DT_MACHINE_START(MSM8960_DT, "Qualcomm MSM (Flattened Device Tree)") +DT_MACHINE_START(MSM_DT, "Qualcomm MSM (Flattened Device Tree)") .smp = smp_ops(msm_smp_ops), - .init_machine = msm_dt_init, - .dt_compat = msm8960_dt_match, + .dt_compat = msm_dt_match, MACHINE_END diff --git a/arch/arm/mach-msm/include/mach/irqs-8960.h b/arch/arm/mach-msm/include/mach/irqs-8960.h deleted file mode 100644 index 81ab2a6792bd..000000000000 --- a/arch/arm/mach-msm/include/mach/irqs-8960.h +++ /dev/null @@ -1,277 +0,0 @@ -/* Copyright (c) 2011 Code Aurora Forum. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that 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. - */ - -#ifndef __ASM_ARCH_MSM_IRQS_8960_H -#define __ASM_ARCH_MSM_IRQS_8960_H - -/* MSM ACPU Interrupt Numbers */ - -/* 0-15: STI/SGI (software triggered/generated interrupts) - 16-31: PPI (private peripheral interrupts) - 32+: SPI (shared peripheral interrupts) */ - -#define GIC_PPI_START 16 -#define GIC_SPI_START 32 - -#define INT_VGIC (GIC_PPI_START + 0) -#define INT_DEBUG_TIMER_EXP (GIC_PPI_START + 1) -#define INT_GP_TIMER_EXP (GIC_PPI_START + 2) -#define INT_GP_TIMER2_EXP (GIC_PPI_START + 3) -#define WDT0_ACCSCSSNBARK_INT (GIC_PPI_START + 4) -#define WDT1_ACCSCSSNBARK_INT (GIC_PPI_START + 5) -#define AVS_SVICINT (GIC_PPI_START + 6) -#define AVS_SVICINTSWDONE (GIC_PPI_START + 7) -#define CPU_DBGCPUXCOMMRXFULL (GIC_PPI_START + 8) -#define CPU_DBGCPUXCOMMTXEMPTY (GIC_PPI_START + 9) -#define CPU_SICCPUXPERFMONIRPTREQ (GIC_PPI_START + 10) -#define SC_AVSCPUXDOWN (GIC_PPI_START + 11) -#define SC_AVSCPUXUP (GIC_PPI_START + 12) -#define SC_SICCPUXACGIRPTREQ (GIC_PPI_START + 13) -#define SC_SICCPUXEXTFAULTIRPTREQ (GIC_PPI_START + 14) -/* PPI 15 is unused */ - -#define SC_SICMPUIRPTREQ (GIC_SPI_START + 0) -#define SC_SICL2IRPTREQ (GIC_SPI_START + 1) -#define SC_SICL2PERFMONIRPTREQ (GIC_SPI_START + 2) -#define SC_SICAGCIRPTREQ (GIC_SPI_START + 3) -#define TLMM_APCC_DIR_CONN_IRQ_0 (GIC_SPI_START + 4) -#define TLMM_APCC_DIR_CONN_IRQ_1 (GIC_SPI_START + 5) -#define TLMM_APCC_DIR_CONN_IRQ_2 (GIC_SPI_START + 6) -#define TLMM_APCC_DIR_CONN_IRQ_3 (GIC_SPI_START + 7) -#define TLMM_APCC_DIR_CONN_IRQ_4 (GIC_SPI_START + 8) -#define TLMM_APCC_DIR_CONN_IRQ_5 (GIC_SPI_START + 9) -#define TLMM_APCC_DIR_CONN_IRQ_6 (GIC_SPI_START + 10) -#define TLMM_APCC_DIR_CONN_IRQ_7 (GIC_SPI_START + 11) -#define TLMM_APCC_DIR_CONN_IRQ_8 (GIC_SPI_START + 12) -#define TLMM_APCC_DIR_CONN_IRQ_9 (GIC_SPI_START + 13) -#define PM8921_SEC_IRQ_103 (GIC_SPI_START + 14) -#define PM8018_SEC_IRQ_106 (GIC_SPI_START + 15) -#define TLMM_APCC_SUMMARY_IRQ (GIC_SPI_START + 16) -#define SPDM_RT_1_IRQ (GIC_SPI_START + 17) -#define SPDM_DIAG_IRQ (GIC_SPI_START + 18) -#define RPM_APCC_CPU0_GP_HIGH_IRQ (GIC_SPI_START + 19) -#define RPM_APCC_CPU0_GP_MEDIUM_IRQ (GIC_SPI_START + 20) -#define RPM_APCC_CPU0_GP_LOW_IRQ (GIC_SPI_START + 21) -#define RPM_APCC_CPU0_WAKE_UP_IRQ (GIC_SPI_START + 22) -#define RPM_APCC_CPU1_GP_HIGH_IRQ (GIC_SPI_START + 23) -#define RPM_APCC_CPU1_GP_MEDIUM_IRQ (GIC_SPI_START + 24) -#define RPM_APCC_CPU1_GP_LOW_IRQ (GIC_SPI_START + 25) -#define RPM_APCC_CPU1_WAKE_UP_IRQ (GIC_SPI_START + 26) -#define SSBI2_2_SC_CPU0_SECURE_IRQ (GIC_SPI_START + 27) -#define SSBI2_2_SC_CPU0_NON_SECURE_IRQ (GIC_SPI_START + 28) -#define SSBI2_1_SC_CPU0_SECURE_IRQ (GIC_SPI_START + 29) -#define SSBI2_1_SC_CPU0_NON_SECURE_IRQ (GIC_SPI_START + 30) -#define MSMC_SC_SEC_CE_IRQ (GIC_SPI_START + 31) -#define MSMC_SC_PRI_CE_IRQ (GIC_SPI_START + 32) -#define SLIMBUS0_CORE_EE1_IRQ (GIC_SPI_START + 33) -#define SLIMBUS0_BAM_EE1_IRQ (GIC_SPI_START + 34) -#define Q6FW_WDOG_EXPIRED_IRQ (GIC_SPI_START + 35) -#define Q6SW_WDOG_EXPIRED_IRQ (GIC_SPI_START + 36) -#define MSS_TO_APPS_IRQ_0 (GIC_SPI_START + 37) -#define MSS_TO_APPS_IRQ_1 (GIC_SPI_START + 38) -#define MSS_TO_APPS_IRQ_2 (GIC_SPI_START + 39) -#define MSS_TO_APPS_IRQ_3 (GIC_SPI_START + 40) -#define MSS_TO_APPS_IRQ_4 (GIC_SPI_START + 41) -#define MSS_TO_APPS_IRQ_5 (GIC_SPI_START + 42) -#define MSS_TO_APPS_IRQ_6 (GIC_SPI_START + 43) -#define MSS_TO_APPS_IRQ_7 (GIC_SPI_START + 44) -#define MSS_TO_APPS_IRQ_8 (GIC_SPI_START + 45) -#define MSS_TO_APPS_IRQ_9 (GIC_SPI_START + 46) -#define VPE_IRQ (GIC_SPI_START + 47) -#define VFE_IRQ (GIC_SPI_START + 48) -#define VCODEC_IRQ (GIC_SPI_START + 49) -#define TV_ENC_IRQ (GIC_SPI_START + 50) -#define SMMU_VPE_CB_SC_SECURE_IRQ (GIC_SPI_START + 51) -#define SMMU_VPE_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 52) -#define SMMU_VFE_CB_SC_SECURE_IRQ (GIC_SPI_START + 53) -#define SMMU_VFE_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 54) -#define SMMU_VCODEC_B_CB_SC_SECURE_IRQ (GIC_SPI_START + 55) -#define SMMU_VCODEC_B_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 56) -#define SMMU_VCODEC_A_CB_SC_SECURE_IRQ (GIC_SPI_START + 57) -#define SMMU_VCODEC_A_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 58) -#define SMMU_ROT_CB_SC_SECURE_IRQ (GIC_SPI_START + 59) -#define SMMU_ROT_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 60) -#define SMMU_MDP1_CB_SC_SECURE_IRQ (GIC_SPI_START + 61) -#define SMMU_MDP1_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 62) -#define SMMU_MDP0_CB_SC_SECURE_IRQ (GIC_SPI_START + 63) -#define SMMU_MDP0_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 64) -#define SMMU_JPEGD_CB_SC_SECURE_IRQ (GIC_SPI_START + 65) -#define SMMU_JPEGD_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 66) -#define SMMU_IJPEG_CB_SC_SECURE_IRQ (GIC_SPI_START + 67) -#define SMMU_IJPEG_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 68) -#define SMMU_GFX3D_CB_SC_SECURE_IRQ (GIC_SPI_START + 69) -#define SMMU_GFX3D_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 70) -#define SMMU_GFX2D0_CB_SC_SECURE_IRQ (GIC_SPI_START + 71) -#define SMMU_GFX2D0_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 72) -#define ROT_IRQ (GIC_SPI_START + 73) -#define MMSS_FABRIC_IRQ (GIC_SPI_START + 74) -#define MDP_IRQ (GIC_SPI_START + 75) -#define JPEGD_IRQ (GIC_SPI_START + 76) -#define JPEG_IRQ (GIC_SPI_START + 77) -#define MMSS_IMEM_IRQ (GIC_SPI_START + 78) -#define HDMI_IRQ (GIC_SPI_START + 79) -#define GFX3D_IRQ (GIC_SPI_START + 80) -#define GFX2D0_IRQ (GIC_SPI_START + 81) -#define DSI1_IRQ (GIC_SPI_START + 82) -#define CSI_1_IRQ (GIC_SPI_START + 83) -#define CSI_0_IRQ (GIC_SPI_START + 84) -#define LPASS_SCSS_AUDIO_IF_OUT0_IRQ (GIC_SPI_START + 85) -#define LPASS_SCSS_MIDI_IRQ (GIC_SPI_START + 86) -#define LPASS_Q6SS_WDOG_EXPIRED (GIC_SPI_START + 87) -#define LPASS_SCSS_GP_LOW_IRQ (GIC_SPI_START + 88) -#define LPASS_SCSS_GP_MEDIUM_IRQ (GIC_SPI_START + 89) -#define LPASS_SCSS_GP_HIGH_IRQ (GIC_SPI_START + 90) -#define TOP_IMEM_IRQ (GIC_SPI_START + 91) -#define FABRIC_SYS_IRQ (GIC_SPI_START + 92) -#define FABRIC_APPS_IRQ (GIC_SPI_START + 93) -#define USB1_HS_BAM_IRQ (GIC_SPI_START + 94) -#define SDC4_BAM_IRQ (GIC_SPI_START + 95) -#define SDC3_BAM_IRQ (GIC_SPI_START + 96) -#define SDC2_BAM_IRQ (GIC_SPI_START + 97) -#define SDC1_BAM_IRQ (GIC_SPI_START + 98) -#define FABRIC_SPS_IRQ (GIC_SPI_START + 99) -#define USB1_HS_IRQ (GIC_SPI_START + 100) -#define SDC4_IRQ_0 (GIC_SPI_START + 101) -#define SDC3_IRQ_0 (GIC_SPI_START + 102) -#define SDC2_IRQ_0 (GIC_SPI_START + 103) -#define SDC1_IRQ_0 (GIC_SPI_START + 104) -#define SPS_BAM_DMA_IRQ (GIC_SPI_START + 105) -#define SPS_SEC_VIOL_IRQ (GIC_SPI_START + 106) -#define SPS_MTI_0 (GIC_SPI_START + 107) -#define SPS_MTI_1 (GIC_SPI_START + 108) -#define SPS_MTI_2 (GIC_SPI_START + 109) -#define SPS_MTI_3 (GIC_SPI_START + 110) -#define SPS_MTI_4 (GIC_SPI_START + 111) -#define SPS_MTI_5 (GIC_SPI_START + 112) -#define SPS_MTI_6 (GIC_SPI_START + 113) -#define SPS_MTI_7 (GIC_SPI_START + 114) -#define SPS_MTI_8 (GIC_SPI_START + 115) -#define SPS_MTI_9 (GIC_SPI_START + 116) -#define SPS_MTI_10 (GIC_SPI_START + 117) -#define SPS_MTI_11 (GIC_SPI_START + 118) -#define SPS_MTI_12 (GIC_SPI_START + 119) -#define SPS_MTI_13 (GIC_SPI_START + 120) -#define SPS_MTI_14 (GIC_SPI_START + 121) -#define SPS_MTI_15 (GIC_SPI_START + 122) -#define SPS_MTI_16 (GIC_SPI_START + 123) -#define SPS_MTI_17 (GIC_SPI_START + 124) -#define SPS_MTI_18 (GIC_SPI_START + 125) -#define SPS_MTI_19 (GIC_SPI_START + 126) -#define SPS_MTI_20 (GIC_SPI_START + 127) -#define SPS_MTI_21 (GIC_SPI_START + 128) -#define SPS_MTI_22 (GIC_SPI_START + 129) -#define SPS_MTI_23 (GIC_SPI_START + 130) -#define SPS_MTI_24 (GIC_SPI_START + 131) -#define SPS_MTI_25 (GIC_SPI_START + 132) -#define SPS_MTI_26 (GIC_SPI_START + 133) -#define SPS_MTI_27 (GIC_SPI_START + 134) -#define SPS_MTI_28 (GIC_SPI_START + 135) -#define SPS_MTI_29 (GIC_SPI_START + 136) -#define SPS_MTI_30 (GIC_SPI_START + 137) -#define SPS_MTI_31 (GIC_SPI_START + 138) -#define CSIPHY_4LN_IRQ (GIC_SPI_START + 139) -#define CSIPHY_2LN_IRQ (GIC_SPI_START + 140) -#define USB2_IRQ (GIC_SPI_START + 141) -#define USB1_IRQ (GIC_SPI_START + 142) -#define TSSC_SSBI_IRQ (GIC_SPI_START + 143) -#define TSSC_SAMPLE_IRQ (GIC_SPI_START + 144) -#define TSSC_PENUP_IRQ (GIC_SPI_START + 145) -#define GSBI1_UARTDM_IRQ (GIC_SPI_START + 146) -#define GSBI1_QUP_IRQ (GIC_SPI_START + 147) -#define GSBI2_UARTDM_IRQ (GIC_SPI_START + 148) -#define GSBI2_QUP_IRQ (GIC_SPI_START + 149) -#define GSBI3_UARTDM_IRQ (GIC_SPI_START + 150) -#define GSBI3_QUP_IRQ (GIC_SPI_START + 151) -#define GSBI4_UARTDM_IRQ (GIC_SPI_START + 152) -#define GSBI4_QUP_IRQ (GIC_SPI_START + 153) -#define GSBI5_UARTDM_IRQ (GIC_SPI_START + 154) -#define GSBI5_QUP_IRQ (GIC_SPI_START + 155) -#define GSBI6_UARTDM_IRQ (GIC_SPI_START + 156) -#define GSBI6_QUP_IRQ (GIC_SPI_START + 157) -#define GSBI7_UARTDM_IRQ (GIC_SPI_START + 158) -#define GSBI7_QUP_IRQ (GIC_SPI_START + 159) -#define GSBI8_UARTDM_IRQ (GIC_SPI_START + 160) -#define GSBI8_QUP_IRQ (GIC_SPI_START + 161) -#define TSIF_TSPP_IRQ (GIC_SPI_START + 162) -#define TSIF_BAM_IRQ (GIC_SPI_START + 163) -#define TSIF2_IRQ (GIC_SPI_START + 164) -#define TSIF1_IRQ (GIC_SPI_START + 165) -#define DSI2_IRQ (GIC_SPI_START + 166) -#define ISPIF_IRQ (GIC_SPI_START + 167) -#define MSMC_SC_SEC_TMR_IRQ (GIC_SPI_START + 168) -#define MSMC_SC_SEC_WDOG_BARK_IRQ (GIC_SPI_START + 169) -#define INT_ADM0_SCSS_0_IRQ (GIC_SPI_START + 170) -#define INT_ADM0_SCSS_1_IRQ (GIC_SPI_START + 171) -#define INT_ADM0_SCSS_2_IRQ (GIC_SPI_START + 172) -#define INT_ADM0_SCSS_3_IRQ (GIC_SPI_START + 173) -#define CC_SCSS_WDT1CPU1BITEEXPIRED (GIC_SPI_START + 174) -#define CC_SCSS_WDT1CPU0BITEEXPIRED (GIC_SPI_START + 175) -#define CC_SCSS_WDT0CPU1BITEEXPIRED (GIC_SPI_START + 176) -#define CC_SCSS_WDT0CPU0BITEEXPIRED (GIC_SPI_START + 177) -#define TSENS_UPPER_LOWER_INT (GIC_SPI_START + 178) -#define SSBI2_2_SC_CPU1_SECURE_INT (GIC_SPI_START + 179) -#define SSBI2_2_SC_CPU1_NON_SECURE_INT (GIC_SPI_START + 180) -#define SSBI2_1_SC_CPU1_SECURE_INT (GIC_SPI_START + 181) -#define SSBI2_1_SC_CPU1_NON_SECURE_INT (GIC_SPI_START + 182) -#define XPU_SUMMARY_IRQ (GIC_SPI_START + 183) -#define BUS_EXCEPTION_SUMMARY_IRQ (GIC_SPI_START + 184) -#define HSDDRX_EBI1CH0_IRQ (GIC_SPI_START + 185) -#define HSDDRX_EBI1CH1_IRQ (GIC_SPI_START + 186) -#define SDC5_BAM_IRQ (GIC_SPI_START + 187) -#define SDC5_IRQ_0 (GIC_SPI_START + 188) -#define GSBI9_UARTDM_IRQ (GIC_SPI_START + 189) -#define GSBI9_QUP_IRQ (GIC_SPI_START + 190) -#define GSBI10_UARTDM_IRQ (GIC_SPI_START + 191) -#define GSBI10_QUP_IRQ (GIC_SPI_START + 192) -#define GSBI11_UARTDM_IRQ (GIC_SPI_START + 193) -#define GSBI11_QUP_IRQ (GIC_SPI_START + 194) -#define GSBI12_UARTDM_IRQ (GIC_SPI_START + 195) -#define GSBI12_QUP_IRQ (GIC_SPI_START + 196) -#define RIVA_APSS_LTECOEX_IRQ (GIC_SPI_START + 197) -#define RIVA_APSS_SPARE_IRQ (GIC_SPI_START + 198) -#define RIVA_APSS_WDOG_BITE_RESET_RDY_IRQ (GIC_SPI_START + 199) -#define RIVA_ASS_RESET_DONE_IRQ (GIC_SPI_START + 200) -#define RIVA_APSS_ASIC_IRQ (GIC_SPI_START + 201) -#define RIVA_APPS_WLAN_RX_DATA_AVAIL_IRQ (GIC_SPI_START + 202) -#define RIVA_APPS_WLAN_DATA_XFER_DONE_IRQ (GIC_SPI_START + 203) -#define RIVA_APPS_WLAM_SMSM_IRQ (GIC_SPI_START + 204) -#define RIVA_APPS_LOG_CTRL_IRQ (GIC_SPI_START + 205) -#define RIVA_APPS_FM_CTRL_IRQ (GIC_SPI_START + 206) -#define RIVA_APPS_HCI_IRQ (GIC_SPI_START + 207) -#define RIVA_APPS_WLAN_CTRL_IRQ (GIC_SPI_START + 208) -#define A2_BAM_IRQ (GIC_SPI_START + 209) -#define SMMU_GFX2D1_CB_SC_SECURE_IRQ (GIC_SPI_START + 210) -#define SMMU_GFX2D1_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 211) -#define GFX2D1_IRQ (GIC_SPI_START + 212) -#define PPSS_WDOG_TIMER_IRQ (GIC_SPI_START + 213) -#define SPS_SLIMBUS_CORE_EE0_IRQ (GIC_SPI_START + 214) -#define SPS_SLIMBUS_BAM_EE0_IRQ (GIC_SPI_START + 215) -#define QDSS_ETB_IRQ (GIC_SPI_START + 216) -#define QDSS_CTI2KPSS_CPU1_IRQ (GIC_SPI_START + 217) -#define QDSS_CTI2KPSS_CPU0_IRQ (GIC_SPI_START + 218) -#define TLMM_APCC_DIR_CONN_IRQ_16 (GIC_SPI_START + 219) -#define TLMM_APCC_DIR_CONN_IRQ_17 (GIC_SPI_START + 220) -#define TLMM_APCC_DIR_CONN_IRQ_18 (GIC_SPI_START + 221) -#define TLMM_APCC_DIR_CONN_IRQ_19 (GIC_SPI_START + 222) -#define TLMM_APCC_DIR_CONN_IRQ_20 (GIC_SPI_START + 223) -#define TLMM_APCC_DIR_CONN_IRQ_21 (GIC_SPI_START + 224) -#define PM8921_SEC_IRQ_104 (GIC_SPI_START + 225) -#define PM8018_SEC_IRQ_107 (GIC_SPI_START + 226) - -/* For now, use the maximum number of interrupts until a pending GIC issue - * is sorted out */ -#define NR_MSM_IRQS 1020 -#define NR_BOARD_IRQS 0 -#define NR_GPIO_IRQS 0 - -#endif - diff --git a/arch/arm/mach-msm/include/mach/irqs-8x60.h b/arch/arm/mach-msm/include/mach/irqs-8x60.h deleted file mode 100644 index f65841c74c0b..000000000000 --- a/arch/arm/mach-msm/include/mach/irqs-8x60.h +++ /dev/null @@ -1,258 +0,0 @@ -/* Copyright (c) 2010 Code Aurora Forum. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that 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. - * - */ - -#ifndef __ASM_ARCH_MSM_IRQS_8X60_H -#define __ASM_ARCH_MSM_IRQS_8X60_H - -/* MSM ACPU Interrupt Numbers */ - -/* 0-15: STI/SGI (software triggered/generated interrupts) - * 16-31: PPI (private peripheral interrupts) - * 32+: SPI (shared peripheral interrupts) - */ - -#define GIC_PPI_START 16 -#define GIC_SPI_START 32 - -#define INT_DEBUG_TIMER_EXP (GIC_PPI_START + 0) -#define INT_GP_TIMER_EXP (GIC_PPI_START + 1) -#define INT_GP_TIMER2_EXP (GIC_PPI_START + 2) -#define WDT0_ACCSCSSNBARK_INT (GIC_PPI_START + 3) -#define WDT1_ACCSCSSNBARK_INT (GIC_PPI_START + 4) -#define AVS_SVICINT (GIC_PPI_START + 5) -#define AVS_SVICINTSWDONE (GIC_PPI_START + 6) -#define CPU_DBGCPUXCOMMRXFULL (GIC_PPI_START + 7) -#define CPU_DBGCPUXCOMMTXEMPTY (GIC_PPI_START + 8) -#define CPU_SICCPUXPERFMONIRPTREQ (GIC_PPI_START + 9) -#define SC_AVSCPUXDOWN (GIC_PPI_START + 10) -#define SC_AVSCPUXUP (GIC_PPI_START + 11) -#define SC_SICCPUXACGIRPTREQ (GIC_PPI_START + 12) -/* PPI 13 to 15 are unused */ - - -#define SC_SICMPUIRPTREQ (GIC_SPI_START + 0) -#define SC_SICL2IRPTREQ (GIC_SPI_START + 1) -#define SC_SICL2ACGIRPTREQ (GIC_SPI_START + 2) -#define NC (GIC_SPI_START + 3) -#define TLMM_SCSS_DIR_CONN_IRQ_0 (GIC_SPI_START + 4) -#define TLMM_SCSS_DIR_CONN_IRQ_1 (GIC_SPI_START + 5) -#define TLMM_SCSS_DIR_CONN_IRQ_2 (GIC_SPI_START + 6) -#define TLMM_SCSS_DIR_CONN_IRQ_3 (GIC_SPI_START + 7) -#define TLMM_SCSS_DIR_CONN_IRQ_4 (GIC_SPI_START + 8) -#define TLMM_SCSS_DIR_CONN_IRQ_5 (GIC_SPI_START + 9) -#define TLMM_SCSS_DIR_CONN_IRQ_6 (GIC_SPI_START + 10) -#define TLMM_SCSS_DIR_CONN_IRQ_7 (GIC_SPI_START + 11) -#define TLMM_SCSS_DIR_CONN_IRQ_8 (GIC_SPI_START + 12) -#define TLMM_SCSS_DIR_CONN_IRQ_9 (GIC_SPI_START + 13) -#define PM8058_SEC_IRQ_N (GIC_SPI_START + 14) -#define PM8901_SEC_IRQ_N (GIC_SPI_START + 15) -#define TLMM_SCSS_SUMMARY_IRQ (GIC_SPI_START + 16) -#define SPDM_RT_1_IRQ (GIC_SPI_START + 17) -#define SPDM_DIAG_IRQ (GIC_SPI_START + 18) -#define RPM_SCSS_CPU0_GP_HIGH_IRQ (GIC_SPI_START + 19) -#define RPM_SCSS_CPU0_GP_MEDIUM_IRQ (GIC_SPI_START + 20) -#define RPM_SCSS_CPU0_GP_LOW_IRQ (GIC_SPI_START + 21) -#define RPM_SCSS_CPU0_WAKE_UP_IRQ (GIC_SPI_START + 22) -#define RPM_SCSS_CPU1_GP_HIGH_IRQ (GIC_SPI_START + 23) -#define RPM_SCSS_CPU1_GP_MEDIUM_IRQ (GIC_SPI_START + 24) -#define RPM_SCSS_CPU1_GP_LOW_IRQ (GIC_SPI_START + 25) -#define RPM_SCSS_CPU1_WAKE_UP_IRQ (GIC_SPI_START + 26) -#define SSBI2_2_SC_CPU0_SECURE_INT (GIC_SPI_START + 27) -#define SSBI2_2_SC_CPU0_NON_SECURE_INT (GIC_SPI_START + 28) -#define SSBI2_1_SC_CPU0_SECURE_INT (GIC_SPI_START + 29) -#define SSBI2_1_SC_CPU0_NON_SECURE_INT (GIC_SPI_START + 30) -#define MSMC_SC_SEC_CE_IRQ (GIC_SPI_START + 31) -#define MSMC_SC_PRI_CE_IRQ (GIC_SPI_START + 32) -#define MARM_FIQ (GIC_SPI_START + 33) -#define MARM_IRQ (GIC_SPI_START + 34) -#define MARM_L2CC_IRQ (GIC_SPI_START + 35) -#define MARM_WDOG_EXPIRED (GIC_SPI_START + 36) -#define MARM_SCSS_GP_IRQ_0 (GIC_SPI_START + 37) -#define MARM_SCSS_GP_IRQ_1 (GIC_SPI_START + 38) -#define MARM_SCSS_GP_IRQ_2 (GIC_SPI_START + 39) -#define MARM_SCSS_GP_IRQ_3 (GIC_SPI_START + 40) -#define MARM_SCSS_GP_IRQ_4 (GIC_SPI_START + 41) -#define MARM_SCSS_GP_IRQ_5 (GIC_SPI_START + 42) -#define MARM_SCSS_GP_IRQ_6 (GIC_SPI_START + 43) -#define MARM_SCSS_GP_IRQ_7 (GIC_SPI_START + 44) -#define MARM_SCSS_GP_IRQ_8 (GIC_SPI_START + 45) -#define MARM_SCSS_GP_IRQ_9 (GIC_SPI_START + 46) -#define VPE_IRQ (GIC_SPI_START + 47) -#define VFE_IRQ (GIC_SPI_START + 48) -#define VCODEC_IRQ (GIC_SPI_START + 49) -#define TV_ENC_IRQ (GIC_SPI_START + 50) -#define SMMU_VPE_CB_SC_SECURE_IRQ (GIC_SPI_START + 51) -#define SMMU_VPE_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 52) -#define SMMU_VFE_CB_SC_SECURE_IRQ (GIC_SPI_START + 53) -#define SMMU_VFE_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 54) -#define SMMU_VCODEC_B_CB_SC_SECURE_IRQ (GIC_SPI_START + 55) -#define SMMU_VCODEC_B_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 56) -#define SMMU_VCODEC_A_CB_SC_SECURE_IRQ (GIC_SPI_START + 57) -#define SMMU_VCODEC_A_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 58) -#define SMMU_ROT_CB_SC_SECURE_IRQ (GIC_SPI_START + 59) -#define SMMU_ROT_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 60) -#define SMMU_MDP1_CB_SC_SECURE_IRQ (GIC_SPI_START + 61) -#define SMMU_MDP1_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 62) -#define SMMU_MDP0_CB_SC_SECURE_IRQ (GIC_SPI_START + 63) -#define SMMU_MDP0_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 64) -#define SMMU_JPEGD_CB_SC_SECURE_IRQ (GIC_SPI_START + 65) -#define SMMU_JPEGD_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 66) -#define SMMU_IJPEG_CB_SC_SECURE_IRQ (GIC_SPI_START + 67) -#define SMMU_IJPEG_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 68) -#define SMMU_GFX3D_CB_SC_SECURE_IRQ (GIC_SPI_START + 69) -#define SMMU_GFX3D_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 70) -#define SMMU_GFX2D0_CB_SC_SECURE_IRQ (GIC_SPI_START + 71) -#define SMMU_GFX2D0_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 72) -#define ROT_IRQ (GIC_SPI_START + 73) -#define MMSS_FABRIC_IRQ (GIC_SPI_START + 74) -#define MDP_IRQ (GIC_SPI_START + 75) -#define JPEGD_IRQ (GIC_SPI_START + 76) -#define JPEG_IRQ (GIC_SPI_START + 77) -#define MMSS_IMEM_IRQ (GIC_SPI_START + 78) -#define HDMI_IRQ (GIC_SPI_START + 79) -#define GFX3D_IRQ (GIC_SPI_START + 80) -#define GFX2D0_IRQ (GIC_SPI_START + 81) -#define DSI_IRQ (GIC_SPI_START + 82) -#define CSI_1_IRQ (GIC_SPI_START + 83) -#define CSI_0_IRQ (GIC_SPI_START + 84) -#define LPASS_SCSS_AUDIO_IF_OUT0_IRQ (GIC_SPI_START + 85) -#define LPASS_SCSS_MIDI_IRQ (GIC_SPI_START + 86) -#define LPASS_Q6SS_WDOG_EXPIRED (GIC_SPI_START + 87) -#define LPASS_SCSS_GP_LOW_IRQ (GIC_SPI_START + 88) -#define LPASS_SCSS_GP_MEDIUM_IRQ (GIC_SPI_START + 89) -#define LPASS_SCSS_GP_HIGH_IRQ (GIC_SPI_START + 90) -#define TOP_IMEM_IRQ (GIC_SPI_START + 91) -#define FABRIC_SYS_IRQ (GIC_SPI_START + 92) -#define FABRIC_APPS_IRQ (GIC_SPI_START + 93) -#define USB1_HS_BAM_IRQ (GIC_SPI_START + 94) -#define SDC4_BAM_IRQ (GIC_SPI_START + 95) -#define SDC3_BAM_IRQ (GIC_SPI_START + 96) -#define SDC2_BAM_IRQ (GIC_SPI_START + 97) -#define SDC1_BAM_IRQ (GIC_SPI_START + 98) -#define FABRIC_SPS_IRQ (GIC_SPI_START + 99) -#define USB1_HS_IRQ (GIC_SPI_START + 100) -#define SDC4_IRQ_0 (GIC_SPI_START + 101) -#define SDC3_IRQ_0 (GIC_SPI_START + 102) -#define SDC2_IRQ_0 (GIC_SPI_START + 103) -#define SDC1_IRQ_0 (GIC_SPI_START + 104) -#define SPS_BAM_DMA_IRQ (GIC_SPI_START + 105) -#define SPS_SEC_VIOL_IRQ (GIC_SPI_START + 106) -#define SPS_MTI_0 (GIC_SPI_START + 107) -#define SPS_MTI_1 (GIC_SPI_START + 108) -#define SPS_MTI_2 (GIC_SPI_START + 109) -#define SPS_MTI_3 (GIC_SPI_START + 110) -#define SPS_MTI_4 (GIC_SPI_START + 111) -#define SPS_MTI_5 (GIC_SPI_START + 112) -#define SPS_MTI_6 (GIC_SPI_START + 113) -#define SPS_MTI_7 (GIC_SPI_START + 114) -#define SPS_MTI_8 (GIC_SPI_START + 115) -#define SPS_MTI_9 (GIC_SPI_START + 116) -#define SPS_MTI_10 (GIC_SPI_START + 117) -#define SPS_MTI_11 (GIC_SPI_START + 118) -#define SPS_MTI_12 (GIC_SPI_START + 119) -#define SPS_MTI_13 (GIC_SPI_START + 120) -#define SPS_MTI_14 (GIC_SPI_START + 121) -#define SPS_MTI_15 (GIC_SPI_START + 122) -#define SPS_MTI_16 (GIC_SPI_START + 123) -#define SPS_MTI_17 (GIC_SPI_START + 124) -#define SPS_MTI_18 (GIC_SPI_START + 125) -#define SPS_MTI_19 (GIC_SPI_START + 126) -#define SPS_MTI_20 (GIC_SPI_START + 127) -#define SPS_MTI_21 (GIC_SPI_START + 128) -#define SPS_MTI_22 (GIC_SPI_START + 129) -#define SPS_MTI_23 (GIC_SPI_START + 130) -#define SPS_MTI_24 (GIC_SPI_START + 131) -#define SPS_MTI_25 (GIC_SPI_START + 132) -#define SPS_MTI_26 (GIC_SPI_START + 133) -#define SPS_MTI_27 (GIC_SPI_START + 134) -#define SPS_MTI_28 (GIC_SPI_START + 135) -#define SPS_MTI_29 (GIC_SPI_START + 136) -#define SPS_MTI_30 (GIC_SPI_START + 137) -#define SPS_MTI_31 (GIC_SPI_START + 138) -#define UXMC_EBI2_WR_ER_DONE_IRQ (GIC_SPI_START + 139) -#define UXMC_EBI2_OP_DONE_IRQ (GIC_SPI_START + 140) -#define USB2_IRQ (GIC_SPI_START + 141) -#define USB1_IRQ (GIC_SPI_START + 142) -#define TSSC_SSBI_IRQ (GIC_SPI_START + 143) -#define TSSC_SAMPLE_IRQ (GIC_SPI_START + 144) -#define TSSC_PENUP_IRQ (GIC_SPI_START + 145) -#define INT_UART1DM_IRQ (GIC_SPI_START + 146) -#define GSBI1_QUP_IRQ (GIC_SPI_START + 147) -#define INT_UART2DM_IRQ (GIC_SPI_START + 148) -#define GSBI2_QUP_IRQ (GIC_SPI_START + 149) -#define INT_UART3DM_IRQ (GIC_SPI_START + 150) -#define GSBI3_QUP_IRQ (GIC_SPI_START + 151) -#define INT_UART4DM_IRQ (GIC_SPI_START + 152) -#define GSBI4_QUP_IRQ (GIC_SPI_START + 153) -#define INT_UART5DM_IRQ (GIC_SPI_START + 154) -#define GSBI5_QUP_IRQ (GIC_SPI_START + 155) -#define INT_UART6DM_IRQ (GIC_SPI_START + 156) -#define GSBI6_QUP_IRQ (GIC_SPI_START + 157) -#define INT_UART7DM_IRQ (GIC_SPI_START + 158) -#define GSBI7_QUP_IRQ (GIC_SPI_START + 159) -#define INT_UART8DM_IRQ (GIC_SPI_START + 160) -#define GSBI8_QUP_IRQ (GIC_SPI_START + 161) -#define TSIF_TSPP_IRQ (GIC_SPI_START + 162) -#define TSIF_BAM_IRQ (GIC_SPI_START + 163) -#define TSIF2_IRQ (GIC_SPI_START + 164) -#define TSIF1_IRQ (GIC_SPI_START + 165) -#define INT_ADM1_MASTER (GIC_SPI_START + 166) -#define INT_ADM1_AARM (GIC_SPI_START + 167) -#define INT_ADM1_SD2 (GIC_SPI_START + 168) -#define INT_ADM1_SD3 (GIC_SPI_START + 169) -#define INT_ADM0_MASTER (GIC_SPI_START + 170) -#define INT_ADM0_AARM (GIC_SPI_START + 171) -#define INT_ADM0_SD2 (GIC_SPI_START + 172) -#define INT_ADM0_SD3 (GIC_SPI_START + 173) -#define CC_SCSS_WDT1CPU1BITEEXPIRED (GIC_SPI_START + 174) -#define CC_SCSS_WDT1CPU0BITEEXPIRED (GIC_SPI_START + 175) -#define CC_SCSS_WDT0CPU1BITEEXPIRED (GIC_SPI_START + 176) -#define CC_SCSS_WDT0CPU0BITEEXPIRED (GIC_SPI_START + 177) -#define TSENS_UPPER_LOWER_INT (GIC_SPI_START + 178) -#define SSBI2_2_SC_CPU1_SECURE_INT (GIC_SPI_START + 179) -#define SSBI2_2_SC_CPU1_NON_SECURE_INT (GIC_SPI_START + 180) -#define SSBI2_1_SC_CPU1_SECURE_INT (GIC_SPI_START + 181) -#define SSBI2_1_SC_CPU1_NON_SECURE_INT (GIC_SPI_START + 182) -#define XPU_SUMMARY_IRQ (GIC_SPI_START + 183) -#define BUS_EXCEPTION_SUMMARY_IRQ (GIC_SPI_START + 184) -#define HSDDRX_SMICH0_IRQ (GIC_SPI_START + 185) -#define HSDDRX_EBI1_IRQ (GIC_SPI_START + 186) -#define SDC5_BAM_IRQ (GIC_SPI_START + 187) -#define SDC5_IRQ_0 (GIC_SPI_START + 188) -#define INT_UART9DM_IRQ (GIC_SPI_START + 189) -#define GSBI9_QUP_IRQ (GIC_SPI_START + 190) -#define INT_UART10DM_IRQ (GIC_SPI_START + 191) -#define GSBI10_QUP_IRQ (GIC_SPI_START + 192) -#define INT_UART11DM_IRQ (GIC_SPI_START + 193) -#define GSBI11_QUP_IRQ (GIC_SPI_START + 194) -#define INT_UART12DM_IRQ (GIC_SPI_START + 195) -#define GSBI12_QUP_IRQ (GIC_SPI_START + 196) - -/*SPI 197 to 209 arent used in 8x60*/ -#define SMMU_GFX2D1_CB_SC_SECURE_IRQ (GIC_SPI_START + 210) -#define SMMU_GFX2D1_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 211) - -/*SPI 212 to 216 arent used in 8x60*/ -#define SMPSS_SPARE_1 (GIC_SPI_START + 217) -#define SMPSS_SPARE_2 (GIC_SPI_START + 218) -#define SMPSS_SPARE_3 (GIC_SPI_START + 219) -#define SMPSS_SPARE_4 (GIC_SPI_START + 220) -#define SMPSS_SPARE_5 (GIC_SPI_START + 221) -#define SMPSS_SPARE_6 (GIC_SPI_START + 222) -#define SMPSS_SPARE_7 (GIC_SPI_START + 223) - -#define NR_GPIO_IRQS 173 -#define NR_MSM_IRQS 256 -#define NR_BOARD_IRQS 0 - -#endif diff --git a/arch/arm/mach-msm/include/mach/irqs.h b/arch/arm/mach-msm/include/mach/irqs.h index 3cd78b165abb..164d355c96ea 100644 --- a/arch/arm/mach-msm/include/mach/irqs.h +++ b/arch/arm/mach-msm/include/mach/irqs.h @@ -24,11 +24,6 @@ #elif defined(CONFIG_ARCH_QSD8X50) #include "irqs-8x50.h" #include "sirc.h" -#elif defined(CONFIG_ARCH_MSM8X60) -#include "irqs-8x60.h" -#elif defined(CONFIG_ARCH_MSM8960) -/* TODO: Make these not generic. */ -#include "irqs-8960.h" #elif defined(CONFIG_ARCH_MSM_ARM11) #include "irqs-7x00.h" #else diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c index 696fb73296d0..1e9c3383daba 100644 --- a/arch/arm/mach-msm/timer.c +++ b/arch/arm/mach-msm/timer.c @@ -274,7 +274,6 @@ static void __init msm_dt_timer_init(struct device_node *np) pr_err("Unknown frequency\n"); return; } - of_node_put(np); event_base = base + 0x4; sts_base = base + 0x88; diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig index 9eb63d724602..5e269d7263ce 100644 --- a/arch/arm/mach-mvebu/Kconfig +++ b/arch/arm/mach-mvebu/Kconfig @@ -1,5 +1,6 @@ config ARCH_MVEBU bool "Marvell SOCs with Device Tree support" if ARCH_MULTI_V7 + select ARCH_SUPPORTS_BIG_ENDIAN select CLKSRC_MMIO select COMMON_CLK select GENERIC_CLOCKEVENTS diff --git a/arch/arm/mach-mvebu/coherency_ll.S b/arch/arm/mach-mvebu/coherency_ll.S index 5476669ba905..ee7598fe75db 100644 --- a/arch/arm/mach-mvebu/coherency_ll.S +++ b/arch/arm/mach-mvebu/coherency_ll.S @@ -20,6 +20,8 @@ #define ARMADA_XP_CFB_CTL_REG_OFFSET 0x0 #define ARMADA_XP_CFB_CFG_REG_OFFSET 0x4 +#include <asm/assembler.h> + .text /* * r0: Coherency fabric base register address @@ -29,6 +31,7 @@ ENTRY(ll_set_cpu_coherent) /* Create bit by cpu index */ mov r3, #(1 << 24) lsl r1, r3, r1 +ARM_BE8(rev r1, r1) /* Add CPU to SMP group - Atomic */ add r3, r0, #ARMADA_XP_CFB_CTL_REG_OFFSET diff --git a/arch/arm/mach-mvebu/headsmp.S b/arch/arm/mach-mvebu/headsmp.S index 8a1b0c96e9ec..3dd80df428f7 100644 --- a/arch/arm/mach-mvebu/headsmp.S +++ b/arch/arm/mach-mvebu/headsmp.S @@ -21,12 +21,16 @@ #include <linux/linkage.h> #include <linux/init.h> +#include <asm/assembler.h> + /* * Armada XP specific entry point for secondary CPUs. * We add the CPU to the coherency fabric and then jump to secondary * startup */ ENTRY(armada_xp_secondary_startup) + ARM_BE8(setend be ) @ go BE8 if entered LE + /* Get coherency fabric base physical address */ adr r0, 1f ldr r1, [r0] diff --git a/arch/arm/mach-mxs/mach-mxs.c b/arch/arm/mach-mxs/mach-mxs.c index 98f6e2adb53e..1dc5acd4fc99 100644 --- a/arch/arm/mach-mxs/mach-mxs.c +++ b/arch/arm/mach-mxs/mach-mxs.c @@ -13,8 +13,6 @@ #include <linux/clk.h> #include <linux/clk/mxs.h> #include <linux/clkdev.h> -#include <linux/clocksource.h> -#include <linux/clk-provider.h> #include <linux/delay.h> #include <linux/err.h> #include <linux/gpio.h> @@ -332,6 +330,11 @@ static void __init crystalfontz_init(void) update_fec_mac_prop(OUI_CRYSTALFONTZ); } +static void __init m28cu3_init(void) +{ + update_fec_mac_prop(OUI_DENX); +} + static const char __init *mxs_get_soc_id(void) { struct device_node *np; @@ -459,6 +462,8 @@ static void __init mxs_machine_init(void) apx4devkit_init(); else if (of_machine_is_compatible("crystalfontz,cfa10036")) crystalfontz_init(); + else if (of_machine_is_compatible("msr,m28cu3")) + m28cu3_init(); of_platform_populate(NULL, of_default_bus_match_table, NULL, parent); @@ -490,16 +495,6 @@ static void mxs_restart(enum reboot_mode mode, const char *cmd) soft_restart(0); } -static void __init mxs_timer_init(void) -{ - if (of_machine_is_compatible("fsl,imx23")) - mx23_clocks_init(); - else - mx28_clocks_init(); - of_clk_init(NULL); - clocksource_of_init(); -} - static const char *mxs_dt_compat[] __initdata = { "fsl,imx28", "fsl,imx23", @@ -508,7 +503,6 @@ static const char *mxs_dt_compat[] __initdata = { DT_MACHINE_START(MXS, "Freescale MXS (Device Tree)") .handle_irq = icoll_handle_irq, - .init_time = mxs_timer_init, .init_machine = mxs_machine_init, .init_late = mxs_pm_init, .dt_compat = mxs_dt_compat, diff --git a/arch/arm/mach-nomadik/cpu-8815.c b/arch/arm/mach-nomadik/cpu-8815.c index 13e0df9c11ce..cce2c9dfb5d1 100644 --- a/arch/arm/mach-nomadik/cpu-8815.c +++ b/arch/arm/mach-nomadik/cpu-8815.c @@ -25,15 +25,11 @@ #include <linux/slab.h> #include <linux/irq.h> #include <linux/dma-mapping.h> -#include <linux/platform_data/clk-nomadik.h> -#include <linux/clocksource.h> #include <linux/of_irq.h> #include <linux/of_gpio.h> #include <linux/of_address.h> #include <linux/of_platform.h> -#include <linux/mtd/fsmc.h> #include <linux/gpio.h> -#include <linux/amba/mmci.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> @@ -113,50 +109,6 @@ static void cpu8815_restart(enum reboot_mode mode, const char *cmd) writel(1, srcbase + 0x18); } -/* Initial value for SRC control register: all timers use MXTAL/8 source */ -#define SRC_CR_INIT_MASK 0x00007fff -#define SRC_CR_INIT_VAL 0x2aaa8000 - -static void __init cpu8815_timer_init_of(void) -{ - struct device_node *mtu; - void __iomem *base; - int irq; - u32 src_cr; - - /* We need this to be up now */ - nomadik_clk_init(); - - mtu = of_find_node_by_path("/mtu@101e2000"); - if (!mtu) - return; - base = of_iomap(mtu, 0); - if (WARN_ON(!base)) - return; - irq = irq_of_parse_and_map(mtu, 0); - - pr_info("Remapped MTU @ %p, irq: %d\n", base, irq); - - /* Configure timer sources in "system reset controller" ctrl reg */ - src_cr = readl(base); - src_cr &= SRC_CR_INIT_MASK; - src_cr |= SRC_CR_INIT_VAL; - writel(src_cr, base); - - clocksource_of_init(); -} - -static struct fsmc_nand_timings cpu8815_nand_timings = { - .thiz = 0, - .thold = 0x10, - .twait = 0x0A, - .tset = 0, -}; - -static struct fsmc_nand_platform_data cpu8815_nand_data = { - .nand_timings = &cpu8815_nand_timings, -}; - /* * The SMSC911x IRQ is connected to a GPIO pin, but the driver expects * to simply request an IRQ passed as a resource. So the GPIO pin needs @@ -190,15 +142,6 @@ static int __init cpu8815_eth_init(void) device_initcall(cpu8815_eth_init); /* - * TODO: - * cannot be set from device tree, convert to a proper DT - * binding. - */ -static struct mmci_platform_data mmcsd_plat_data = { - .ocr_mask = MMC_VDD_29_30, -}; - -/* * This GPIO pin turns on a line that is used to detect card insertion * on this board. */ @@ -232,24 +175,13 @@ static int __init cpu8815_mmcsd_init(void) } device_initcall(cpu8815_mmcsd_init); - -/* These are mostly to get the right device names for the clock lookups */ -static struct of_dev_auxdata cpu8815_auxdata_lookup[] __initdata = { - OF_DEV_AUXDATA("stericsson,fsmc-nand", NOMADIK_FSMC_BASE, - NULL, &cpu8815_nand_data), - OF_DEV_AUXDATA("arm,primecell", NOMADIK_SDI_BASE, - NULL, &mmcsd_plat_data), - { /* sentinel */ }, -}; - static void __init cpu8815_init_of(void) { #ifdef CONFIG_CACHE_L2X0 /* At full speed latency must be >=2, so 0x249 in low bits */ l2x0_of_init(0x00730249, 0xfe000fff); #endif - of_platform_populate(NULL, of_default_bus_match_table, - cpu8815_auxdata_lookup, NULL); + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); } static const char * cpu8815_board_compat[] = { @@ -259,7 +191,6 @@ static const char * cpu8815_board_compat[] = { DT_MACHINE_START(NOMADIK_DT, "Nomadik STn8815") .map_io = cpu8815_map_io, - .init_time = cpu8815_timer_init_of, .init_machine = cpu8815_init_of, .restart = cpu8815_restart, .dt_compat = cpu8815_board_compat, diff --git a/arch/arm/mach-nspire/nspire.c b/arch/arm/mach-nspire/nspire.c index 99e26092a9f7..4b2ed2e8352f 100644 --- a/arch/arm/mach-nspire/nspire.c +++ b/arch/arm/mach-nspire/nspire.c @@ -14,11 +14,9 @@ #include <linux/of_platform.h> #include <linux/irqchip.h> #include <linux/irqchip/arm-vic.h> -#include <linux/clk-provider.h> #include <linux/clkdev.h> #include <linux/amba/bus.h> #include <linux/amba/clcd.h> -#include <linux/clocksource.h> #include <asm/mach/arch.h> #include <asm/mach-types.h> @@ -65,12 +63,6 @@ static void __init nspire_init(void) nspire_auxdata, NULL); } -static void __init nspire_init_time(void) -{ - of_clk_init(NULL); - clocksource_of_init(); -} - static void nspire_restart(char mode, const char *cmd) { void __iomem *base = ioremap(NSPIRE_MISC_PHYS_BASE, SZ_4K); @@ -83,7 +75,6 @@ static void nspire_restart(char mode, const char *cmd) DT_MACHINE_START(NSPIRE, "TI-NSPIRE") .dt_compat = nspire_dt_match, .map_io = nspire_map_io, - .init_time = nspire_init_time, .init_machine = nspire_init, .restart = nspire_restart, MACHINE_END diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c index a7ce69286688..d68909b095f1 100644 --- a/arch/arm/mach-omap1/board-osk.c +++ b/arch/arm/mach-omap1/board-osk.c @@ -300,7 +300,7 @@ static struct omap_lcd_config osk_lcd_config __initdata = { #ifdef CONFIG_OMAP_OSK_MISTRAL #include <linux/input.h> -#include <linux/i2c/at24.h> +#include <linux/platform_data/at24.h> #include <linux/spi/spi.h> #include <linux/spi/ads7846.h> diff --git a/arch/arm/mach-omap1/common.h b/arch/arm/mach-omap1/common.h index abec019a5281..732f8ee2fcd2 100644 --- a/arch/arm/mach-omap1/common.h +++ b/arch/arm/mach-omap1/common.h @@ -46,6 +46,9 @@ static inline void omap7xx_map_io(void) void omap1510_fpga_init_irq(void); void omap15xx_map_io(void); #else +static inline void omap1510_fpga_init_irq(void) +{ +} static inline void omap15xx_map_io(void) { } diff --git a/arch/arm/mach-omap1/fpga.c b/arch/arm/mach-omap1/fpga.c index 8bd71b2d0967..3c0e42219200 100644 --- a/arch/arm/mach-omap1/fpga.c +++ b/arch/arm/mach-omap1/fpga.c @@ -135,8 +135,7 @@ static struct irq_chip omap_fpga_irq = { * mask_ack routine for all of the FPGA interrupts has been changed from * fpga_mask_ack_irq() to fpga_ack_irq() so that the specific FPGA interrupt * being serviced is left unmasked. We can do this because the FPGA cascade - * interrupt is installed with the IRQF_DISABLED flag, which leaves all - * interrupts masked at the CPU while an FPGA interrupt handler executes. + * interrupt is run with all interrupts masked. * * Limited testing indicates that this workaround appears to be effective * for the smc9194 Ethernet driver used on the Innovator. It should work diff --git a/arch/arm/mach-omap1/gpio15xx.c b/arch/arm/mach-omap1/gpio15xx.c index 02b3eb2e201c..312a0924d786 100644 --- a/arch/arm/mach-omap1/gpio15xx.c +++ b/arch/arm/mach-omap1/gpio15xx.c @@ -25,7 +25,7 @@ #define OMAP1510_GPIO_BASE 0xFFFCE000 /* gpio1 */ -static struct __initdata resource omap15xx_mpu_gpio_resources[] = { +static struct resource omap15xx_mpu_gpio_resources[] = { { .start = OMAP1_MPUIO_VBASE, .end = OMAP1_MPUIO_VBASE + SZ_2K - 1, @@ -48,7 +48,7 @@ static struct omap_gpio_reg_offs omap15xx_mpuio_regs = { .irqctrl = OMAP_MPUIO_GPIO_INT_EDGE, }; -static struct __initdata omap_gpio_platform_data omap15xx_mpu_gpio_config = { +static struct omap_gpio_platform_data omap15xx_mpu_gpio_config = { .is_mpuio = true, .bank_width = 16, .bank_stride = 1, @@ -66,7 +66,7 @@ static struct platform_device omap15xx_mpu_gpio = { }; /* gpio2 */ -static struct __initdata resource omap15xx_gpio_resources[] = { +static struct resource omap15xx_gpio_resources[] = { { .start = OMAP1510_GPIO_BASE, .end = OMAP1510_GPIO_BASE + SZ_2K - 1, @@ -90,7 +90,7 @@ static struct omap_gpio_reg_offs omap15xx_gpio_regs = { .pinctrl = OMAP1510_GPIO_PIN_CONTROL, }; -static struct __initdata omap_gpio_platform_data omap15xx_gpio_config = { +static struct omap_gpio_platform_data omap15xx_gpio_config = { .bank_width = 16, .regs = &omap15xx_gpio_regs, }; diff --git a/arch/arm/mach-omap1/gpio16xx.c b/arch/arm/mach-omap1/gpio16xx.c index b9952a258d82..6e6ec93dcbb3 100644 --- a/arch/arm/mach-omap1/gpio16xx.c +++ b/arch/arm/mach-omap1/gpio16xx.c @@ -31,7 +31,7 @@ #define SYSCONFIG_WORD 0x14 /* mpu gpio */ -static struct __initdata resource omap16xx_mpu_gpio_resources[] = { +static struct resource omap16xx_mpu_gpio_resources[] = { { .start = OMAP1_MPUIO_VBASE, .end = OMAP1_MPUIO_VBASE + SZ_2K - 1, @@ -54,7 +54,7 @@ static struct omap_gpio_reg_offs omap16xx_mpuio_regs = { .irqctrl = OMAP_MPUIO_GPIO_INT_EDGE, }; -static struct __initdata omap_gpio_platform_data omap16xx_mpu_gpio_config = { +static struct omap_gpio_platform_data omap16xx_mpu_gpio_config = { .is_mpuio = true, .bank_width = 16, .bank_stride = 1, @@ -72,7 +72,7 @@ static struct platform_device omap16xx_mpu_gpio = { }; /* gpio1 */ -static struct __initdata resource omap16xx_gpio1_resources[] = { +static struct resource omap16xx_gpio1_resources[] = { { .start = OMAP1610_GPIO1_BASE, .end = OMAP1610_GPIO1_BASE + SZ_2K - 1, @@ -100,7 +100,7 @@ static struct omap_gpio_reg_offs omap16xx_gpio_regs = { .edgectrl2 = OMAP1610_GPIO_EDGE_CTRL2, }; -static struct __initdata omap_gpio_platform_data omap16xx_gpio1_config = { +static struct omap_gpio_platform_data omap16xx_gpio1_config = { .bank_width = 16, .regs = &omap16xx_gpio_regs, }; @@ -116,7 +116,7 @@ static struct platform_device omap16xx_gpio1 = { }; /* gpio2 */ -static struct __initdata resource omap16xx_gpio2_resources[] = { +static struct resource omap16xx_gpio2_resources[] = { { .start = OMAP1610_GPIO2_BASE, .end = OMAP1610_GPIO2_BASE + SZ_2K - 1, @@ -128,7 +128,7 @@ static struct __initdata resource omap16xx_gpio2_resources[] = { }, }; -static struct __initdata omap_gpio_platform_data omap16xx_gpio2_config = { +static struct omap_gpio_platform_data omap16xx_gpio2_config = { .bank_width = 16, .regs = &omap16xx_gpio_regs, }; @@ -144,7 +144,7 @@ static struct platform_device omap16xx_gpio2 = { }; /* gpio3 */ -static struct __initdata resource omap16xx_gpio3_resources[] = { +static struct resource omap16xx_gpio3_resources[] = { { .start = OMAP1610_GPIO3_BASE, .end = OMAP1610_GPIO3_BASE + SZ_2K - 1, @@ -156,7 +156,7 @@ static struct __initdata resource omap16xx_gpio3_resources[] = { }, }; -static struct __initdata omap_gpio_platform_data omap16xx_gpio3_config = { +static struct omap_gpio_platform_data omap16xx_gpio3_config = { .bank_width = 16, .regs = &omap16xx_gpio_regs, }; @@ -172,7 +172,7 @@ static struct platform_device omap16xx_gpio3 = { }; /* gpio4 */ -static struct __initdata resource omap16xx_gpio4_resources[] = { +static struct resource omap16xx_gpio4_resources[] = { { .start = OMAP1610_GPIO4_BASE, .end = OMAP1610_GPIO4_BASE + SZ_2K - 1, @@ -184,7 +184,7 @@ static struct __initdata resource omap16xx_gpio4_resources[] = { }, }; -static struct __initdata omap_gpio_platform_data omap16xx_gpio4_config = { +static struct omap_gpio_platform_data omap16xx_gpio4_config = { .bank_width = 16, .regs = &omap16xx_gpio_regs, }; @@ -199,7 +199,7 @@ static struct platform_device omap16xx_gpio4 = { .resource = omap16xx_gpio4_resources, }; -static struct __initdata platform_device * omap16xx_gpio_dev[] = { +static struct platform_device *omap16xx_gpio_dev[] __initdata = { &omap16xx_mpu_gpio, &omap16xx_gpio1, &omap16xx_gpio2, diff --git a/arch/arm/mach-omap1/gpio7xx.c b/arch/arm/mach-omap1/gpio7xx.c index f5819b2b7cbe..4612d2506a2d 100644 --- a/arch/arm/mach-omap1/gpio7xx.c +++ b/arch/arm/mach-omap1/gpio7xx.c @@ -30,7 +30,7 @@ #define OMAP1_MPUIO_VBASE OMAP1_MPUIO_BASE /* mpu gpio */ -static struct __initdata resource omap7xx_mpu_gpio_resources[] = { +static struct resource omap7xx_mpu_gpio_resources[] = { { .start = OMAP1_MPUIO_VBASE, .end = OMAP1_MPUIO_VBASE + SZ_2K - 1, @@ -53,7 +53,7 @@ static struct omap_gpio_reg_offs omap7xx_mpuio_regs = { .irqctrl = OMAP_MPUIO_GPIO_INT_EDGE >> 1, }; -static struct __initdata omap_gpio_platform_data omap7xx_mpu_gpio_config = { +static struct omap_gpio_platform_data omap7xx_mpu_gpio_config = { .is_mpuio = true, .bank_width = 16, .bank_stride = 2, @@ -71,7 +71,7 @@ static struct platform_device omap7xx_mpu_gpio = { }; /* gpio1 */ -static struct __initdata resource omap7xx_gpio1_resources[] = { +static struct resource omap7xx_gpio1_resources[] = { { .start = OMAP7XX_GPIO1_BASE, .end = OMAP7XX_GPIO1_BASE + SZ_2K - 1, @@ -94,7 +94,7 @@ static struct omap_gpio_reg_offs omap7xx_gpio_regs = { .irqctrl = OMAP7XX_GPIO_INT_CONTROL, }; -static struct __initdata omap_gpio_platform_data omap7xx_gpio1_config = { +static struct omap_gpio_platform_data omap7xx_gpio1_config = { .bank_width = 32, .regs = &omap7xx_gpio_regs, }; @@ -110,7 +110,7 @@ static struct platform_device omap7xx_gpio1 = { }; /* gpio2 */ -static struct __initdata resource omap7xx_gpio2_resources[] = { +static struct resource omap7xx_gpio2_resources[] = { { .start = OMAP7XX_GPIO2_BASE, .end = OMAP7XX_GPIO2_BASE + SZ_2K - 1, @@ -122,7 +122,7 @@ static struct __initdata resource omap7xx_gpio2_resources[] = { }, }; -static struct __initdata omap_gpio_platform_data omap7xx_gpio2_config = { +static struct omap_gpio_platform_data omap7xx_gpio2_config = { .bank_width = 32, .regs = &omap7xx_gpio_regs, }; @@ -138,7 +138,7 @@ static struct platform_device omap7xx_gpio2 = { }; /* gpio3 */ -static struct __initdata resource omap7xx_gpio3_resources[] = { +static struct resource omap7xx_gpio3_resources[] = { { .start = OMAP7XX_GPIO3_BASE, .end = OMAP7XX_GPIO3_BASE + SZ_2K - 1, @@ -150,7 +150,7 @@ static struct __initdata resource omap7xx_gpio3_resources[] = { }, }; -static struct __initdata omap_gpio_platform_data omap7xx_gpio3_config = { +static struct omap_gpio_platform_data omap7xx_gpio3_config = { .bank_width = 32, .regs = &omap7xx_gpio_regs, }; @@ -166,7 +166,7 @@ static struct platform_device omap7xx_gpio3 = { }; /* gpio4 */ -static struct __initdata resource omap7xx_gpio4_resources[] = { +static struct resource omap7xx_gpio4_resources[] = { { .start = OMAP7XX_GPIO4_BASE, .end = OMAP7XX_GPIO4_BASE + SZ_2K - 1, @@ -178,7 +178,7 @@ static struct __initdata resource omap7xx_gpio4_resources[] = { }, }; -static struct __initdata omap_gpio_platform_data omap7xx_gpio4_config = { +static struct omap_gpio_platform_data omap7xx_gpio4_config = { .bank_width = 32, .regs = &omap7xx_gpio_regs, }; @@ -194,7 +194,7 @@ static struct platform_device omap7xx_gpio4 = { }; /* gpio5 */ -static struct __initdata resource omap7xx_gpio5_resources[] = { +static struct resource omap7xx_gpio5_resources[] = { { .start = OMAP7XX_GPIO5_BASE, .end = OMAP7XX_GPIO5_BASE + SZ_2K - 1, @@ -206,7 +206,7 @@ static struct __initdata resource omap7xx_gpio5_resources[] = { }, }; -static struct __initdata omap_gpio_platform_data omap7xx_gpio5_config = { +static struct omap_gpio_platform_data omap7xx_gpio5_config = { .bank_width = 32, .regs = &omap7xx_gpio_regs, }; @@ -222,7 +222,7 @@ static struct platform_device omap7xx_gpio5 = { }; /* gpio6 */ -static struct __initdata resource omap7xx_gpio6_resources[] = { +static struct resource omap7xx_gpio6_resources[] = { { .start = OMAP7XX_GPIO6_BASE, .end = OMAP7XX_GPIO6_BASE + SZ_2K - 1, @@ -234,7 +234,7 @@ static struct __initdata resource omap7xx_gpio6_resources[] = { }, }; -static struct __initdata omap_gpio_platform_data omap7xx_gpio6_config = { +static struct omap_gpio_platform_data omap7xx_gpio6_config = { .bank_width = 32, .regs = &omap7xx_gpio_regs, }; @@ -249,7 +249,7 @@ static struct platform_device omap7xx_gpio6 = { .resource = omap7xx_gpio6_resources, }; -static struct __initdata platform_device * omap7xx_gpio_dev[] = { +static struct platform_device *omap7xx_gpio_dev[] __initdata = { &omap7xx_mpu_gpio, &omap7xx_gpio1, &omap7xx_gpio2, diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c index 358b82cb9f78..40a1ae319610 100644 --- a/arch/arm/mach-omap1/pm.c +++ b/arch/arm/mach-omap1/pm.c @@ -628,7 +628,6 @@ static irqreturn_t omap_wakeup_interrupt(int irq, void *dev) static struct irqaction omap_wakeup_irq = { .name = "peripheral wakeup", - .flags = IRQF_DISABLED, .handler = omap_wakeup_interrupt }; diff --git a/arch/arm/mach-omap1/time.c b/arch/arm/mach-omap1/time.c index 80603d2fef77..6b5f298d6638 100644 --- a/arch/arm/mach-omap1/time.c +++ b/arch/arm/mach-omap1/time.c @@ -160,7 +160,7 @@ static irqreturn_t omap_mpu_timer1_interrupt(int irq, void *dev_id) static struct irqaction omap_mpu_timer1_irq = { .name = "mpu_timer1", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .flags = IRQF_TIMER | IRQF_IRQPOLL, .handler = omap_mpu_timer1_interrupt, }; diff --git a/arch/arm/mach-omap1/timer32k.c b/arch/arm/mach-omap1/timer32k.c index 0b74246ba62c..107e7ab3edba 100644 --- a/arch/arm/mach-omap1/timer32k.c +++ b/arch/arm/mach-omap1/timer32k.c @@ -156,7 +156,7 @@ static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id) static struct irqaction omap_32k_timer_irq = { .name = "32KHz timer", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .flags = IRQF_TIMER | IRQF_IRQPOLL, .handler = omap_32k_timer_interrupt, }; diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index b5fb5f7992df..dc21df166161 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -8,7 +8,6 @@ config ARCH_OMAP2 select CPU_V6 select MULTI_IRQ_HANDLER select SOC_HAS_OMAP2_SDRC - select COMMON_CLK config ARCH_OMAP3 bool "TI OMAP3" @@ -22,7 +21,6 @@ config ARCH_OMAP3 select PM_OPP if PM select PM_RUNTIME if CPU_IDLE select SOC_HAS_OMAP2_SDRC - select COMMON_CLK select USB_ARCH_HAS_EHCI if USB_SUPPORT config ARCH_OMAP4 @@ -45,7 +43,6 @@ config ARCH_OMAP4 select PM_OPP if PM select PM_RUNTIME if CPU_IDLE select USB_ARCH_HAS_EHCI if USB_SUPPORT - select COMMON_CLK select ARM_ERRATA_754322 select ARM_ERRATA_775420 @@ -59,7 +56,6 @@ config SOC_OMAP5 select HAVE_ARM_SCU if SMP select HAVE_ARM_TWD if LOCAL_TIMERS select HAVE_SMP - select COMMON_CLK select HAVE_ARM_ARCH_TIMER select ARM_ERRATA_798181 if SMP @@ -70,7 +66,6 @@ config SOC_AM33XX select ARM_CPU_SUSPEND if PM select CPU_V7 select MULTI_IRQ_HANDLER - select COMMON_CLK config SOC_AM43XX bool "TI AM43x" @@ -79,7 +74,6 @@ config SOC_AM43XX select ARCH_OMAP2PLUS select MULTI_IRQ_HANDLER select ARM_GIC - select COMMON_CLK select MACH_OMAP_GENERIC config ARCH_OMAP2PLUS @@ -89,11 +83,11 @@ config ARCH_OMAP2PLUS select ARCH_HAS_HOLES_MEMORYMODEL select ARCH_OMAP select ARCH_REQUIRE_GPIOLIB - select CLKDEV_LOOKUP select CLKSRC_MMIO + select COMMON_CLK select GENERIC_CLOCKEVENTS select GENERIC_IRQ_CHIP - select HAVE_CLK + select MACH_OMAP_GENERIC select OMAP_DM_TIMER select PINCTRL select PROC_DEVICETREE if PROC_FS @@ -187,16 +181,11 @@ config OMAP_PACKAGE_CUS config OMAP_PACKAGE_CBP bool -comment "OMAP Board Type" +comment "OMAP Legacy Platform Data Board Type" depends on ARCH_OMAP2PLUS config MACH_OMAP_GENERIC - bool "Generic OMAP2+ board" - depends on ARCH_OMAP2PLUS - default y - help - Support for generic TI OMAP2+ boards using Flattened Device Tree. - More information at Documentation/devicetree + bool config MACH_OMAP2_TUSB6010 bool @@ -260,12 +249,6 @@ config MACH_OVERO default y select OMAP_PACKAGE_CBB -config MACH_OMAP3EVM - bool "OMAP 3530 EVM board" - depends on ARCH_OMAP3 - default y - select OMAP_PACKAGE_CBB - config MACH_OMAP3517EVM bool "OMAP3517/ AM3517 EVM board" depends on ARCH_OMAP3 @@ -314,33 +297,12 @@ config MACH_NOKIA_N8X0 select MACH_NOKIA_N810_WIMAX select OMAP_PACKAGE_ZAC -config MACH_NOKIA_RM680 - bool "Nokia N950 (RM-680) / N9 (RM-696) phones" - depends on ARCH_OMAP3 - default y - select MACH_NOKIA_RM696 - select OMAP_PACKAGE_CBB - config MACH_NOKIA_RX51 bool "Nokia N900 (RX-51) phone" depends on ARCH_OMAP3 default y select OMAP_PACKAGE_CBB -config MACH_OMAP_ZOOM2 - bool "OMAP3 Zoom2 board" - depends on ARCH_OMAP3 - default y - select OMAP_PACKAGE_CBB - select REGULATOR_FIXED_VOLTAGE if REGULATOR - -config MACH_OMAP_ZOOM3 - bool "OMAP3630 Zoom3 board" - depends on ARCH_OMAP3 - default y - select OMAP_PACKAGE_CBP - select REGULATOR_FIXED_VOLTAGE if REGULATOR - config MACH_CM_T35 bool "CompuLab CM-T35/CM-T3730 modules" depends on ARCH_OMAP3 @@ -357,31 +319,12 @@ config MACH_CM_T3517 config MACH_CM_T3730 bool -config MACH_IGEP0020 - bool "IGEP v2 board" - depends on ARCH_OMAP3 - default y - select OMAP_PACKAGE_CBB - -config MACH_IGEP0030 - bool "IGEP OMAP3 module" - depends on ARCH_OMAP3 - default y - select MACH_IGEP0020 - select OMAP_PACKAGE_CBB - config MACH_SBC3530 bool "OMAP3 SBC STALKER board" depends on ARCH_OMAP3 default y select OMAP_PACKAGE_CUS -config MACH_OMAP_3630SDP - bool "OMAP3630 SDP board" - depends on ARCH_OMAP3 - default y - select OMAP_PACKAGE_CBP - config MACH_TI8168EVM bool "TI8168 Evaluation Module" depends on SOC_TI81XX diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index afb457c3135b..1f25f3e99c05 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -8,7 +8,7 @@ ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include \ # Common support obj-y := id.o io.o control.o mux.o devices.o fb.o serial.o gpmc.o timer.o pm.o \ common.o gpio.o dma.o wd_timer.o display.o i2c.o hdq1w.o omap_hwmod.o \ - omap_device.o sram.o + omap_device.o sram.o drm.o omap-2-3-common = irq.o hwmod-common = omap_hwmod.o omap_hwmod_reset.o \ @@ -40,7 +40,7 @@ omap-4-5-common = omap4-common.o omap-wakeupgen.o obj-$(CONFIG_ARCH_OMAP4) += $(omap-4-5-common) $(smp-y) sleep44xx.o obj-$(CONFIG_SOC_OMAP5) += $(omap-4-5-common) $(smp-y) sleep44xx.o obj-$(CONFIG_SOC_AM43XX) += $(omap-4-5-common) -obj-$(CONFIG_SOC_DRA7XX) += $(omap-4-5-common) $(smp-y) +obj-$(CONFIG_SOC_DRA7XX) += $(omap-4-5-common) $(smp-y) sleep44xx.o plus_sec := $(call as-instr,.arch_extension sec,+sec) AFLAGS_omap-headsmp.o :=-Wa,-march=armv7-a$(plus_sec) @@ -112,13 +112,13 @@ obj-$(CONFIG_ARCH_OMAP2) += prm2xxx_3xxx.o prm2xxx.o cm2xxx.o obj-$(CONFIG_ARCH_OMAP3) += prm2xxx_3xxx.o prm3xxx.o cm3xxx.o obj-$(CONFIG_ARCH_OMAP3) += vc3xxx_data.o vp3xxx_data.o obj-$(CONFIG_SOC_AM33XX) += prm33xx.o cm33xx.o -obj-$(CONFIG_SOC_AM43XX) += prm33xx.o cm33xx.o omap-prcm-4-5-common = cminst44xx.o cm44xx.o prm44xx.o \ prcm_mpu44xx.o prminst44xx.o \ vc44xx_data.o vp44xx_data.o obj-$(CONFIG_ARCH_OMAP4) += $(omap-prcm-4-5-common) obj-$(CONFIG_SOC_OMAP5) += $(omap-prcm-4-5-common) obj-$(CONFIG_SOC_DRA7XX) += $(omap-prcm-4-5-common) +obj-$(CONFIG_SOC_AM43XX) += $(omap-prcm-4-5-common) # OMAP voltage domains voltagedomain-common := voltage.o vc.o vp.o @@ -146,6 +146,7 @@ obj-$(CONFIG_ARCH_OMAP4) += powerdomains44xx_data.o obj-$(CONFIG_SOC_AM33XX) += $(powerdomain-common) obj-$(CONFIG_SOC_AM33XX) += powerdomains33xx_data.o obj-$(CONFIG_SOC_AM43XX) += $(powerdomain-common) +obj-$(CONFIG_SOC_AM43XX) += powerdomains43xx_data.o obj-$(CONFIG_SOC_OMAP5) += $(powerdomain-common) obj-$(CONFIG_SOC_OMAP5) += powerdomains54xx_data.o obj-$(CONFIG_SOC_DRA7XX) += $(powerdomain-common) @@ -165,6 +166,7 @@ obj-$(CONFIG_ARCH_OMAP4) += clockdomains44xx_data.o obj-$(CONFIG_SOC_AM33XX) += $(clockdomain-common) obj-$(CONFIG_SOC_AM33XX) += clockdomains33xx_data.o obj-$(CONFIG_SOC_AM43XX) += $(clockdomain-common) +obj-$(CONFIG_SOC_AM43XX) += clockdomains43xx_data.o obj-$(CONFIG_SOC_OMAP5) += $(clockdomain-common) obj-$(CONFIG_SOC_OMAP5) += clockdomains54xx_data.o obj-$(CONFIG_SOC_DRA7XX) += $(clockdomain-common) @@ -210,6 +212,11 @@ obj-$(CONFIG_ARCH_OMAP3) += omap_hwmod_2xxx_3xxx_ipblock_data.o obj-$(CONFIG_ARCH_OMAP3) += omap_hwmod_2xxx_3xxx_interconnect_data.o obj-$(CONFIG_ARCH_OMAP3) += omap_hwmod_3xxx_data.o obj-$(CONFIG_SOC_AM33XX) += omap_hwmod_33xx_data.o +obj-$(CONFIG_SOC_AM33XX) += omap_hwmod_33xx_43xx_interconnect_data.o +obj-$(CONFIG_SOC_AM33XX) += omap_hwmod_33xx_43xx_ipblock_data.o +obj-$(CONFIG_SOC_AM43XX) += omap_hwmod_43xx_data.o +obj-$(CONFIG_SOC_AM43XX) += omap_hwmod_33xx_43xx_interconnect_data.o +obj-$(CONFIG_SOC_AM43XX) += omap_hwmod_33xx_43xx_ipblock_data.o obj-$(CONFIG_ARCH_OMAP4) += omap_hwmod_44xx_data.o obj-$(CONFIG_SOC_OMAP5) += omap_hwmod_54xx_data.o obj-$(CONFIG_SOC_DRA7XX) += omap_hwmod_7xx_data.o @@ -228,12 +235,8 @@ endif # OMAP2420 MSDI controller integration support ("MMC") obj-$(CONFIG_SOC_OMAP2420) += msdi.o -ifneq ($(CONFIG_DRM_OMAP),) -obj-y += drm.o -endif - # Specific board support -obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o +obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o pdata-quirks.o obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o obj-$(CONFIG_MACH_OMAP_2430SDP) += board-2430sdp.o obj-$(CONFIG_MACH_OMAP3_BEAGLE) += board-omap3beagle.o @@ -242,26 +245,14 @@ obj-$(CONFIG_MACH_OMAP_LDP) += board-ldp.o obj-$(CONFIG_MACH_OMAP3530_LV_SOM) += board-omap3logic.o obj-$(CONFIG_MACH_OMAP3_TORPEDO) += board-omap3logic.o obj-$(CONFIG_MACH_OVERO) += board-overo.o -obj-$(CONFIG_MACH_OMAP3EVM) += board-omap3evm.o obj-$(CONFIG_MACH_OMAP3_PANDORA) += board-omap3pandora.o obj-$(CONFIG_MACH_OMAP_3430SDP) += board-3430sdp.o obj-$(CONFIG_MACH_NOKIA_N8X0) += board-n8x0.o -obj-$(CONFIG_MACH_NOKIA_RM680) += board-rm680.o sdram-nokia.o obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51.o sdram-nokia.o obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51-peripherals.o obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51-video.o -obj-$(CONFIG_MACH_OMAP_ZOOM2) += board-zoom.o board-zoom-peripherals.o -obj-$(CONFIG_MACH_OMAP_ZOOM2) += board-zoom-display.o -obj-$(CONFIG_MACH_OMAP_ZOOM2) += board-zoom-debugboard.o -obj-$(CONFIG_MACH_OMAP_ZOOM3) += board-zoom.o board-zoom-peripherals.o -obj-$(CONFIG_MACH_OMAP_ZOOM3) += board-zoom-display.o -obj-$(CONFIG_MACH_OMAP_ZOOM3) += board-zoom-debugboard.o -obj-$(CONFIG_MACH_OMAP_3630SDP) += board-3630sdp.o -obj-$(CONFIG_MACH_OMAP_3630SDP) += board-zoom-peripherals.o -obj-$(CONFIG_MACH_OMAP_3630SDP) += board-zoom-display.o obj-$(CONFIG_MACH_CM_T35) += board-cm-t35.o obj-$(CONFIG_MACH_CM_T3517) += board-cm-t3517.o -obj-$(CONFIG_MACH_IGEP0020) += board-igep0020.o obj-$(CONFIG_MACH_TOUCHBOOK) += board-omap3touchbook.o obj-$(CONFIG_MACH_OMAP3517EVM) += board-am3517evm.o diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c deleted file mode 100644 index 20d6d8189240..000000000000 --- a/arch/arm/mach-omap2/board-3630sdp.c +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright (C) 2009 Texas Instruments Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/platform_device.h> -#include <linux/input.h> -#include <linux/gpio.h> -#include <linux/mtd/nand.h> - -#include <asm/mach-types.h> -#include <asm/mach/arch.h> - -#include "common.h" -#include "gpmc-smc91x.h" - -#include "board-zoom.h" - -#include "board-flash.h" -#include "mux.h" -#include "sdram-hynix-h8mbx00u0mer-0em.h" - -#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) - -static struct omap_smc91x_platform_data board_smc91x_data = { - .cs = 3, - .flags = GPMC_MUX_ADD_DATA | IORESOURCE_IRQ_LOWLEVEL, -}; - -static void __init board_smc91x_init(void) -{ - board_smc91x_data.gpio_irq = 158; - gpmc_smc91x_init(&board_smc91x_data); -} - -#else - -static inline void board_smc91x_init(void) -{ -} - -#endif /* defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) */ - -static void enable_board_wakeup_source(void) -{ - /* T2 interrupt line (keypad) */ - omap_mux_init_signal("sys_nirq", - OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP); -} - -static struct usbhs_phy_data phy_data[] __initdata = { - { - .port = 1, - .reset_gpio = 126, - .vcc_gpio = -EINVAL, - }, - { - .port = 2, - .reset_gpio = 61, - .vcc_gpio = -EINVAL, - }, -}; - -static struct usbhs_omap_platform_data usbhs_bdata __initdata = { - - .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, - .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, -}; - -#ifdef CONFIG_OMAP_MUX -static struct omap_board_mux board_mux[] __initdata = { - { .reg_offset = OMAP_MUX_TERMINATOR }, -}; -#endif - -/* - * SDP3630 CS organization - * See also the Switch S8 settings in the comments. - */ -static char chip_sel_sdp[][GPMC_CS_NUM] = { - {PDC_NOR, PDC_NAND, PDC_ONENAND, DBG_MPDB, 0, 0, 0, 0}, /* S8:1111 */ - {PDC_ONENAND, PDC_NAND, PDC_NOR, DBG_MPDB, 0, 0, 0, 0}, /* S8:1110 */ - {PDC_NAND, PDC_ONENAND, PDC_NOR, DBG_MPDB, 0, 0, 0, 0}, /* S8:1101 */ -}; - -static struct mtd_partition sdp_nor_partitions[] = { - /* bootloader (U-Boot, etc) in first sector */ - { - .name = "Bootloader-NOR", - .offset = 0, - .size = SZ_256K, - .mask_flags = MTD_WRITEABLE, /* force read-only */ - }, - /* bootloader params in the next sector */ - { - .name = "Params-NOR", - .offset = MTDPART_OFS_APPEND, - .size = SZ_256K, - .mask_flags = 0, - }, - /* kernel */ - { - .name = "Kernel-NOR", - .offset = MTDPART_OFS_APPEND, - .size = SZ_2M, - .mask_flags = 0 - }, - /* file system */ - { - .name = "Filesystem-NOR", - .offset = MTDPART_OFS_APPEND, - .size = MTDPART_SIZ_FULL, - .mask_flags = 0 - } -}; - -static struct mtd_partition sdp_onenand_partitions[] = { - { - .name = "X-Loader-OneNAND", - .offset = 0, - .size = 4 * (64 * 2048), - .mask_flags = MTD_WRITEABLE /* force read-only */ - }, - { - .name = "U-Boot-OneNAND", - .offset = MTDPART_OFS_APPEND, - .size = 2 * (64 * 2048), - .mask_flags = MTD_WRITEABLE /* force read-only */ - }, - { - .name = "U-Boot Environment-OneNAND", - .offset = MTDPART_OFS_APPEND, - .size = 1 * (64 * 2048), - }, - { - .name = "Kernel-OneNAND", - .offset = MTDPART_OFS_APPEND, - .size = 16 * (64 * 2048), - }, - { - .name = "File System-OneNAND", - .offset = MTDPART_OFS_APPEND, - .size = MTDPART_SIZ_FULL, - }, -}; - -static struct mtd_partition sdp_nand_partitions[] = { - /* All the partition sizes are listed in terms of NAND block size */ - { - .name = "X-Loader-NAND", - .offset = 0, - .size = 4 * (64 * 2048), - .mask_flags = MTD_WRITEABLE, /* force read-only */ - }, - { - .name = "U-Boot-NAND", - .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */ - .size = 10 * (64 * 2048), - .mask_flags = MTD_WRITEABLE, /* force read-only */ - }, - { - .name = "Boot Env-NAND", - - .offset = MTDPART_OFS_APPEND, /* Offset = 0x1c0000 */ - .size = 6 * (64 * 2048), - }, - { - .name = "Kernel-NAND", - .offset = MTDPART_OFS_APPEND, /* Offset = 0x280000 */ - .size = 40 * (64 * 2048), - }, - { - .name = "File System - NAND", - .size = MTDPART_SIZ_FULL, - .offset = MTDPART_OFS_APPEND, /* Offset = 0x780000 */ - }, -}; - -static struct flash_partitions sdp_flash_partitions[] = { - { - .parts = sdp_nor_partitions, - .nr_parts = ARRAY_SIZE(sdp_nor_partitions), - }, - { - .parts = sdp_onenand_partitions, - .nr_parts = ARRAY_SIZE(sdp_onenand_partitions), - }, - { - .parts = sdp_nand_partitions, - .nr_parts = ARRAY_SIZE(sdp_nand_partitions), - }, -}; - -static void __init omap_sdp_init(void) -{ - omap3_mux_init(board_mux, OMAP_PACKAGE_CBP); - zoom_peripherals_init(); - omap_sdrc_init(h8mbx00u0mer0em_sdrc_params, - h8mbx00u0mer0em_sdrc_params); - zoom_display_init(); - board_smc91x_init(); - board_flash_init(sdp_flash_partitions, chip_sel_sdp, NAND_BUSWIDTH_16); - enable_board_wakeup_source(); - - usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); - usbhs_init(&usbhs_bdata); -} - -MACHINE_START(OMAP_3630SDP, "OMAP 3630SDP board") - .atag_offset = 0x100, - .reserve = omap_reserve, - .map_io = omap3_map_io, - .init_early = omap3630_init_early, - .init_irq = omap3_init_irq, - .handle_irq = omap3_intc_handle_irq, - .init_machine = omap_sdp_init, - .init_late = omap3630_init_late, - .init_time = omap3_sync32k_timer_init, - .restart = omap3xxx_restart, -MACHINE_END diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c index 33d159e2386e..8dd0ec858cf1 100644 --- a/arch/arm/mach-omap2/board-cm-t35.c +++ b/arch/arm/mach-omap2/board-cm-t35.c @@ -25,7 +25,7 @@ #include <linux/gpio.h> #include <linux/platform_data/gpio-omap.h> -#include <linux/i2c/at24.h> +#include <linux/platform_data/at24.h> #include <linux/i2c/twl.h> #include <linux/regulator/fixed.h> #include <linux/regulator/machine.h> diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c index fc20a61f6b2a..ac82512b9c8c 100644 --- a/arch/arm/mach-omap2/board-flash.c +++ b/arch/arm/mach-omap2/board-flash.c @@ -142,7 +142,7 @@ __init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs, board_nand_data.nr_parts = nr_parts; board_nand_data.devsize = nand_type; - board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DEFAULT; + board_nand_data.ecc_opt = OMAP_ECC_BCH8_CODE_HW; gpmc_nand_init(&board_nand_data, gpmc_t); } #endif /* CONFIG_MTD_NAND_OMAP2 || CONFIG_MTD_NAND_OMAP2_MODULE */ diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c index 87162e1b94a5..19f1652e94cf 100644 --- a/arch/arm/mach-omap2/board-generic.c +++ b/arch/arm/mach-omap2/board-generic.c @@ -15,13 +15,10 @@ #include <linux/of_irq.h> #include <linux/of_platform.h> #include <linux/irqdomain.h> -#include <linux/clk.h> #include <asm/mach/arch.h> #include "common.h" -#include "common-board-devices.h" -#include "dss-common.h" #if !(defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)) #define intc_of_init NULL @@ -36,40 +33,9 @@ static struct of_device_id omap_dt_match_table[] __initdata = { { } }; -/* - * Create alias for USB host PHY clock. - * Remove this when clock phandle can be provided via DT - */ -static void __init legacy_init_ehci_clk(char *clkname) -{ - int ret; - - ret = clk_add_alias("main_clk", NULL, clkname, NULL); - if (ret) { - pr_err("%s:Failed to add main_clk alias to %s :%d\n", - __func__, clkname, ret); - } -} - static void __init omap_generic_init(void) { - omap_sdrc_init(NULL, NULL); - - of_platform_populate(NULL, omap_dt_match_table, NULL, NULL); - - /* - * HACK: call display setup code for selected boards to enable omapdss. - * This will be removed when omapdss supports DT. - */ - if (of_machine_is_compatible("ti,omap4-panda")) { - omap4_panda_display_init_of(); - legacy_init_ehci_clk("auxclk3_ck"); - - } - else if (of_machine_is_compatible("ti,omap4-sdp")) - omap_4430sdp_display_init_of(); - else if (of_machine_is_compatible("ti,omap5-uevm")) - legacy_init_ehci_clk("auxclk1_ck"); + pdata_quirks_init(omap_dt_match_table); } #ifdef CONFIG_SOC_OMAP2420 @@ -180,6 +146,7 @@ DT_MACHINE_START(AM33XX_DT, "Generic AM33XX (Flattened Device Tree)") .init_irq = omap_intc_of_init, .handle_irq = omap3_intc_handle_irq, .init_machine = omap_generic_init, + .init_late = am33xx_init_late, .init_time = omap3_gptimer_timer_init, .dt_compat = am33xx_boards_compat, .restart = am33xx_restart, @@ -219,6 +186,7 @@ DT_MACHINE_START(OMAP5_DT, "Generic OMAP5 (Flattened Device Tree)") .init_early = omap5_init_early, .init_irq = omap_gic_of_init, .init_machine = omap_generic_init, + .init_late = omap5_init_late, .init_time = omap5_realtime_timer_init, .dt_compat = omap5_boards_compat, .restart = omap44xx_restart, @@ -234,6 +202,7 @@ static const char *am43_boards_compat[] __initdata = { DT_MACHINE_START(AM43_DT, "Generic AM43 (Flattened Device Tree)") .map_io = am33xx_map_io, .init_early = am43xx_init_early, + .init_late = am43xx_init_late, .init_irq = omap_gic_of_init, .init_machine = omap_generic_init, .init_time = omap3_sync32k_timer_init, @@ -252,6 +221,7 @@ DT_MACHINE_START(DRA7XX_DT, "Generic DRA7XX (Flattened Device Tree)") .smp = smp_ops(omap4_smp_ops), .map_io = omap5_map_io, .init_early = dra7xx_init_early, + .init_late = dra7xx_init_late, .init_irq = omap_gic_of_init, .init_machine = omap_generic_init, .init_time = omap5_realtime_timer_init, diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c index 87e41a8b8d46..f7808349a734 100644 --- a/arch/arm/mach-omap2/board-h4.c +++ b/arch/arm/mach-omap2/board-h4.c @@ -20,7 +20,7 @@ #include <linux/delay.h> #include <linux/workqueue.h> #include <linux/i2c.h> -#include <linux/i2c/at24.h> +#include <linux/platform_data/at24.h> #include <linux/input.h> #include <linux/err.h> #include <linux/clk.h> diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c deleted file mode 100644 index 06dbb2d3d38b..000000000000 --- a/arch/arm/mach-omap2/board-igep0020.c +++ /dev/null @@ -1,718 +0,0 @@ -/* - * Copyright (C) 2009 Integration Software and Electronic Engineering. - * - * Modified from mach-omap2/board-generic.c - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/platform_device.h> -#include <linux/delay.h> -#include <linux/err.h> -#include <linux/clk.h> -#include <linux/io.h> -#include <linux/gpio.h> -#include <linux/interrupt.h> -#include <linux/input.h> -#include <linux/usb/phy.h> - -#include <linux/regulator/machine.h> -#include <linux/regulator/fixed.h> -#include <linux/i2c/twl.h> -#include <linux/mmc/host.h> - -#include <linux/mtd/nand.h> - -#include <asm/mach-types.h> -#include <asm/mach/arch.h> - -#include <video/omapdss.h> -#include <video/omap-panel-data.h> -#include <linux/platform_data/mtd-onenand-omap2.h> - -#include "common.h" -#include "gpmc.h" -#include "mux.h" -#include "hsmmc.h" -#include "sdram-numonyx-m65kxxxxam.h" -#include "common-board-devices.h" -#include "board-flash.h" -#include "control.h" -#include "gpmc-onenand.h" - -#define IGEP2_SMSC911X_CS 5 -#define IGEP2_SMSC911X_GPIO 176 -#define IGEP2_GPIO_USBH_NRESET 24 -#define IGEP2_GPIO_LED0_GREEN 26 -#define IGEP2_GPIO_LED0_RED 27 -#define IGEP2_GPIO_LED1_RED 28 -#define IGEP2_GPIO_DVI_PUP 170 - -#define IGEP2_RB_GPIO_WIFI_NPD 94 -#define IGEP2_RB_GPIO_WIFI_NRESET 95 -#define IGEP2_RB_GPIO_BT_NRESET 137 -#define IGEP2_RC_GPIO_WIFI_NPD 138 -#define IGEP2_RC_GPIO_WIFI_NRESET 139 -#define IGEP2_RC_GPIO_BT_NRESET 137 - -#define IGEP3_GPIO_LED0_GREEN 54 -#define IGEP3_GPIO_LED0_RED 53 -#define IGEP3_GPIO_LED1_RED 16 -#define IGEP3_GPIO_USBH_NRESET 183 - -#define IGEP_SYSBOOT_MASK 0x1f -#define IGEP_SYSBOOT_NAND 0x0f -#define IGEP_SYSBOOT_ONENAND 0x10 - -/* - * IGEP2 Hardware Revision Table - * - * -------------------------------------------------------------------------- - * | Id. | Hw Rev. | HW0 (28) | WIFI_NPD | WIFI_NRESET | BT_NRESET | - * -------------------------------------------------------------------------- - * | 0 | B | high | gpio94 | gpio95 | - | - * | 0 | B/C (B-compatible) | high | gpio94 | gpio95 | gpio137 | - * | 1 | C | low | gpio138 | gpio139 | gpio137 | - * -------------------------------------------------------------------------- - */ - -#define IGEP2_BOARD_HWREV_B 0 -#define IGEP2_BOARD_HWREV_C 1 -#define IGEP3_BOARD_HWREV 2 - -static u8 hwrev; - -static void __init igep2_get_revision(void) -{ - u8 ret; - - if (machine_is_igep0030()) { - hwrev = IGEP3_BOARD_HWREV; - return; - } - - omap_mux_init_gpio(IGEP2_GPIO_LED1_RED, OMAP_PIN_INPUT); - - if (gpio_request_one(IGEP2_GPIO_LED1_RED, GPIOF_IN, "GPIO_HW0_REV")) { - pr_warning("IGEP2: Could not obtain gpio GPIO_HW0_REV\n"); - pr_err("IGEP2: Unknown Hardware Revision\n"); - return; - } - - ret = gpio_get_value(IGEP2_GPIO_LED1_RED); - if (ret == 0) { - pr_info("IGEP2: Hardware Revision C (B-NON compatible)\n"); - hwrev = IGEP2_BOARD_HWREV_C; - } else if (ret == 1) { - pr_info("IGEP2: Hardware Revision B/C (B compatible)\n"); - hwrev = IGEP2_BOARD_HWREV_B; - } else { - pr_err("IGEP2: Unknown Hardware Revision\n"); - hwrev = -1; - } - - gpio_free(IGEP2_GPIO_LED1_RED); -} - -#if defined(CONFIG_MTD_ONENAND_OMAP2) || \ - defined(CONFIG_MTD_ONENAND_OMAP2_MODULE) || \ - defined(CONFIG_MTD_NAND_OMAP2) || \ - defined(CONFIG_MTD_NAND_OMAP2_MODULE) - -#define ONENAND_MAP 0x20000000 - -/* NAND04GR4E1A ( x2 Flash built-in COMBO POP MEMORY ) - * Since the device is equipped with two DataRAMs, and two-plane NAND - * Flash memory array, these two component enables simultaneous program - * of 4KiB. Plane1 has only even blocks such as block0, block2, block4 - * while Plane2 has only odd blocks such as block1, block3, block5. - * So MTD regards it as 4KiB page size and 256KiB block size 64*(2*2048) - */ - -static struct mtd_partition igep_flash_partitions[] = { - { - .name = "X-Loader", - .offset = 0, - .size = 2 * (64*(2*2048)) - }, - { - .name = "U-Boot", - .offset = MTDPART_OFS_APPEND, - .size = 6 * (64*(2*2048)), - }, - { - .name = "Environment", - .offset = MTDPART_OFS_APPEND, - .size = 2 * (64*(2*2048)), - }, - { - .name = "Kernel", - .offset = MTDPART_OFS_APPEND, - .size = 12 * (64*(2*2048)), - }, - { - .name = "File System", - .offset = MTDPART_OFS_APPEND, - .size = MTDPART_SIZ_FULL, - }, -}; - -static inline u32 igep_get_sysboot_value(void) -{ - return omap_ctrl_readl(OMAP343X_CONTROL_STATUS) & IGEP_SYSBOOT_MASK; -} - -static void __init igep_flash_init(void) -{ - u32 mux; - mux = igep_get_sysboot_value(); - - if (mux == IGEP_SYSBOOT_NAND) { - pr_info("IGEP: initializing NAND memory device\n"); - board_nand_init(igep_flash_partitions, - ARRAY_SIZE(igep_flash_partitions), - 0, NAND_BUSWIDTH_16, nand_default_timings); - } else if (mux == IGEP_SYSBOOT_ONENAND) { - pr_info("IGEP: initializing OneNAND memory device\n"); - board_onenand_init(igep_flash_partitions, - ARRAY_SIZE(igep_flash_partitions), 0); - } else { - pr_err("IGEP: Flash: unsupported sysboot sequence found\n"); - } -} - -#else -static void __init igep_flash_init(void) {} -#endif - -#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE) - -#include <linux/smsc911x.h> -#include "gpmc-smsc911x.h" - -static struct omap_smsc911x_platform_data smsc911x_cfg = { - .cs = IGEP2_SMSC911X_CS, - .gpio_irq = IGEP2_SMSC911X_GPIO, - .gpio_reset = -EINVAL, - .flags = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS, -}; - -static inline void __init igep2_init_smsc911x(void) -{ - gpmc_smsc911x_init(&smsc911x_cfg); -} - -#else -static inline void __init igep2_init_smsc911x(void) { } -#endif - -static struct regulator_consumer_supply igep_vmmc1_supply[] = { - REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"), -}; - -/* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */ -static struct regulator_init_data igep_vmmc1 = { - .constraints = { - .min_uV = 1850000, - .max_uV = 3150000, - .valid_modes_mask = REGULATOR_MODE_NORMAL - | REGULATOR_MODE_STANDBY, - .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE - | REGULATOR_CHANGE_MODE - | REGULATOR_CHANGE_STATUS, - }, - .num_consumer_supplies = ARRAY_SIZE(igep_vmmc1_supply), - .consumer_supplies = igep_vmmc1_supply, -}; - -static struct regulator_consumer_supply igep_vio_supply[] = { - REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.1"), -}; - -static struct regulator_init_data igep_vio = { - .constraints = { - .min_uV = 1800000, - .max_uV = 1800000, - .apply_uV = 1, - .valid_modes_mask = REGULATOR_MODE_NORMAL - | REGULATOR_MODE_STANDBY, - .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE - | REGULATOR_CHANGE_MODE - | REGULATOR_CHANGE_STATUS, - }, - .num_consumer_supplies = ARRAY_SIZE(igep_vio_supply), - .consumer_supplies = igep_vio_supply, -}; - -static struct regulator_consumer_supply igep_vmmc2_supply[] = { - REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"), -}; - -static struct regulator_init_data igep_vmmc2 = { - .constraints = { - .valid_modes_mask = REGULATOR_MODE_NORMAL, - .always_on = 1, - }, - .num_consumer_supplies = ARRAY_SIZE(igep_vmmc2_supply), - .consumer_supplies = igep_vmmc2_supply, -}; - -static struct fixed_voltage_config igep_vwlan = { - .supply_name = "vwlan", - .microvolts = 3300000, - .gpio = -EINVAL, - .enabled_at_boot = 1, - .init_data = &igep_vmmc2, -}; - -static struct platform_device igep_vwlan_device = { - .name = "reg-fixed-voltage", - .id = 0, - .dev = { - .platform_data = &igep_vwlan, - }, -}; - -static struct omap2_hsmmc_info mmc[] = { - { - .mmc = 1, - .caps = MMC_CAP_4_BIT_DATA, - .gpio_cd = -EINVAL, - .gpio_wp = -EINVAL, - .deferred = true, - }, -#if defined(CONFIG_LIBERTAS_SDIO) || defined(CONFIG_LIBERTAS_SDIO_MODULE) - { - .mmc = 2, - .caps = MMC_CAP_4_BIT_DATA, - .gpio_cd = -EINVAL, - .gpio_wp = -EINVAL, - }, -#endif - {} /* Terminator */ -}; - -#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) -#include <linux/leds.h> - -static struct gpio_led igep_gpio_leds[] = { - [0] = { - .name = "omap3:red:user0", - .default_state = 0, - }, - [1] = { - .name = "omap3:green:boot", - .default_state = 1, - }, - [2] = { - .name = "omap3:red:user1", - .default_state = 0, - }, - [3] = { - .name = "omap3:green:user1", - .default_state = 0, - .gpio = -EINVAL, /* gets replaced */ - .active_low = 1, - }, -}; - -static struct gpio_led_platform_data igep_led_pdata = { - .leds = igep_gpio_leds, - .num_leds = ARRAY_SIZE(igep_gpio_leds), -}; - -static struct platform_device igep_led_device = { - .name = "leds-gpio", - .id = -1, - .dev = { - .platform_data = &igep_led_pdata, - }, -}; - -static void __init igep_leds_init(void) -{ - if (machine_is_igep0020()) { - igep_gpio_leds[0].gpio = IGEP2_GPIO_LED0_RED; - igep_gpio_leds[1].gpio = IGEP2_GPIO_LED0_GREEN; - igep_gpio_leds[2].gpio = IGEP2_GPIO_LED1_RED; - } else { - igep_gpio_leds[0].gpio = IGEP3_GPIO_LED0_RED; - igep_gpio_leds[1].gpio = IGEP3_GPIO_LED0_GREEN; - igep_gpio_leds[2].gpio = IGEP3_GPIO_LED1_RED; - } - - platform_device_register(&igep_led_device); -} - -#else -static struct gpio igep_gpio_leds[] __initdata = { - { -EINVAL, GPIOF_OUT_INIT_LOW, "gpio-led:red:d0" }, - { -EINVAL, GPIOF_OUT_INIT_LOW, "gpio-led:green:d0" }, - { -EINVAL, GPIOF_OUT_INIT_LOW, "gpio-led:red:d1" }, -}; - -static inline void igep_leds_init(void) -{ - int i; - - if (machine_is_igep0020()) { - igep_gpio_leds[0].gpio = IGEP2_GPIO_LED0_RED; - igep_gpio_leds[1].gpio = IGEP2_GPIO_LED0_GREEN; - igep_gpio_leds[2].gpio = IGEP2_GPIO_LED1_RED; - } else { - igep_gpio_leds[0].gpio = IGEP3_GPIO_LED0_RED; - igep_gpio_leds[1].gpio = IGEP3_GPIO_LED0_GREEN; - igep_gpio_leds[2].gpio = IGEP3_GPIO_LED1_RED; - } - - if (gpio_request_array(igep_gpio_leds, ARRAY_SIZE(igep_gpio_leds))) { - pr_warning("IGEP v2: Could not obtain leds gpios\n"); - return; - } - - for (i = 0; i < ARRAY_SIZE(igep_gpio_leds); i++) - gpio_export(igep_gpio_leds[i].gpio, 0); -} -#endif - -static struct gpio igep2_twl_gpios[] = { - { -EINVAL, GPIOF_IN, "GPIO_EHCI_NOC" }, - { -EINVAL, GPIOF_OUT_INIT_LOW, "GPIO_USBH_CPEN" }, -}; - -static int igep_twl_gpio_setup(struct device *dev, - unsigned gpio, unsigned ngpio) -{ - int ret; - - /* gpio + 0 is "mmc0_cd" (input/IRQ) */ - mmc[0].gpio_cd = gpio + 0; - omap_hsmmc_late_init(mmc); - - /* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */ -#if !defined(CONFIG_LEDS_GPIO) && !defined(CONFIG_LEDS_GPIO_MODULE) - ret = gpio_request_one(gpio + TWL4030_GPIO_MAX + 1, GPIOF_OUT_INIT_HIGH, - "gpio-led:green:d1"); - if (ret == 0) - gpio_export(gpio + TWL4030_GPIO_MAX + 1, 0); - else - pr_warning("IGEP: Could not obtain gpio GPIO_LED1_GREEN\n"); -#else - igep_gpio_leds[3].gpio = gpio + TWL4030_GPIO_MAX + 1; -#endif - - if (machine_is_igep0030()) - return 0; - - /* - * REVISIT: need ehci-omap hooks for external VBUS - * power switch and overcurrent detect - */ - igep2_twl_gpios[0].gpio = gpio + 1; - - /* TWL4030_GPIO_MAX + 0 == ledA, GPIO_USBH_CPEN (out, active low) */ - igep2_twl_gpios[1].gpio = gpio + TWL4030_GPIO_MAX; - - ret = gpio_request_array(igep2_twl_gpios, ARRAY_SIZE(igep2_twl_gpios)); - if (ret < 0) - pr_err("IGEP2: Could not obtain gpio for USBH_CPEN"); - - return 0; -}; - -static struct twl4030_gpio_platform_data igep_twl4030_gpio_pdata = { - .use_leds = true, - .setup = igep_twl_gpio_setup, -}; - -static struct connector_dvi_platform_data omap3stalker_dvi_connector_pdata = { - .name = "dvi", - .source = "tfp410.0", - .i2c_bus_num = 3, -}; - -static struct platform_device omap3stalker_dvi_connector_device = { - .name = "connector-dvi", - .id = 0, - .dev.platform_data = &omap3stalker_dvi_connector_pdata, -}; - -static struct encoder_tfp410_platform_data omap3stalker_tfp410_pdata = { - .name = "tfp410.0", - .source = "dpi.0", - .data_lines = 24, - .power_down_gpio = IGEP2_GPIO_DVI_PUP, -}; - -static struct platform_device omap3stalker_tfp410_device = { - .name = "tfp410", - .id = 0, - .dev.platform_data = &omap3stalker_tfp410_pdata, -}; - -static struct omap_dss_board_info igep2_dss_data = { - .default_display_name = "dvi", -}; - -static struct platform_device *igep_devices[] __initdata = { - &igep_vwlan_device, - &omap3stalker_tfp410_device, - &omap3stalker_dvi_connector_device, -}; - -static int igep2_keymap[] = { - KEY(0, 0, KEY_LEFT), - KEY(0, 1, KEY_RIGHT), - KEY(0, 2, KEY_A), - KEY(0, 3, KEY_B), - KEY(1, 0, KEY_DOWN), - KEY(1, 1, KEY_UP), - KEY(1, 2, KEY_E), - KEY(1, 3, KEY_F), - KEY(2, 0, KEY_ENTER), - KEY(2, 1, KEY_I), - KEY(2, 2, KEY_J), - KEY(2, 3, KEY_K), - KEY(3, 0, KEY_M), - KEY(3, 1, KEY_N), - KEY(3, 2, KEY_O), - KEY(3, 3, KEY_P) -}; - -static struct matrix_keymap_data igep2_keymap_data = { - .keymap = igep2_keymap, - .keymap_size = ARRAY_SIZE(igep2_keymap), -}; - -static struct twl4030_keypad_data igep2_keypad_pdata = { - .keymap_data = &igep2_keymap_data, - .rows = 4, - .cols = 4, - .rep = 1, -}; - -static struct twl4030_platform_data igep_twldata = { - /* platform_data for children goes here */ - .gpio = &igep_twl4030_gpio_pdata, - .vmmc1 = &igep_vmmc1, - .vio = &igep_vio, -}; - -static struct i2c_board_info __initdata igep2_i2c3_boardinfo[] = { - { - I2C_BOARD_INFO("eeprom", 0x50), - }, -}; - -static void __init igep_i2c_init(void) -{ - int ret; - - omap3_pmic_get_config(&igep_twldata, TWL_COMMON_PDATA_USB, - TWL_COMMON_REGULATOR_VPLL2); - igep_twldata.vpll2->constraints.apply_uV = true; - igep_twldata.vpll2->constraints.name = "VDVI"; - - if (machine_is_igep0020()) { - /* - * Bus 3 is attached to the DVI port where devices like the - * pico DLP projector don't work reliably with 400kHz - */ - ret = omap_register_i2c_bus(3, 100, igep2_i2c3_boardinfo, - ARRAY_SIZE(igep2_i2c3_boardinfo)); - if (ret) - pr_warning("IGEP2: Could not register I2C3 bus (%d)\n", ret); - - igep_twldata.keypad = &igep2_keypad_pdata; - /* Get common pmic data */ - omap3_pmic_get_config(&igep_twldata, TWL_COMMON_PDATA_AUDIO, 0); - } - - omap3_pmic_init("twl4030", &igep_twldata); -} - -static struct usbhs_phy_data igep2_phy_data[] __initdata = { - { - .port = 1, - .reset_gpio = IGEP2_GPIO_USBH_NRESET, - .vcc_gpio = -EINVAL, - }, -}; - -static struct usbhs_phy_data igep3_phy_data[] __initdata = { - { - .port = 2, - .reset_gpio = IGEP3_GPIO_USBH_NRESET, - .vcc_gpio = -EINVAL, - }, -}; - -static struct usbhs_omap_platform_data igep2_usbhs_bdata __initdata = { - .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, -}; - -static struct usbhs_omap_platform_data igep3_usbhs_bdata __initdata = { - .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, -}; - -#ifdef CONFIG_OMAP_MUX -static struct omap_board_mux board_mux[] __initdata = { - /* Display Sub System */ - OMAP3_MUX(DSS_PCLK, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), - OMAP3_MUX(DSS_HSYNC, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), - OMAP3_MUX(DSS_VSYNC, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), - OMAP3_MUX(DSS_ACBIAS, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), - OMAP3_MUX(DSS_DATA0, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), - OMAP3_MUX(DSS_DATA1, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), - OMAP3_MUX(DSS_DATA2, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), - OMAP3_MUX(DSS_DATA3, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), - OMAP3_MUX(DSS_DATA4, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), - OMAP3_MUX(DSS_DATA5, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), - OMAP3_MUX(DSS_DATA6, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), - OMAP3_MUX(DSS_DATA7, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), - OMAP3_MUX(DSS_DATA8, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), - OMAP3_MUX(DSS_DATA9, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), - OMAP3_MUX(DSS_DATA10, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), - OMAP3_MUX(DSS_DATA11, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), - OMAP3_MUX(DSS_DATA12, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), - OMAP3_MUX(DSS_DATA13, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), - OMAP3_MUX(DSS_DATA14, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), - OMAP3_MUX(DSS_DATA15, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), - OMAP3_MUX(DSS_DATA16, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), - OMAP3_MUX(DSS_DATA17, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), - OMAP3_MUX(DSS_DATA18, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), - OMAP3_MUX(DSS_DATA19, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), - OMAP3_MUX(DSS_DATA20, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), - OMAP3_MUX(DSS_DATA21, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), - OMAP3_MUX(DSS_DATA22, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), - OMAP3_MUX(DSS_DATA23, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), - /* TFP410 PanelBus DVI Transmitte (GPIO_170) */ - OMAP3_MUX(HDQ_SIO, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT), - /* SMSC9221 LAN Controller ETH IRQ (GPIO_176) */ - OMAP3_MUX(MCSPI1_CS2, OMAP_MUX_MODE4 | OMAP_PIN_INPUT), - { .reg_offset = OMAP_MUX_TERMINATOR }, -}; -#endif - -#if defined(CONFIG_LIBERTAS_SDIO) || defined(CONFIG_LIBERTAS_SDIO_MODULE) -static struct gpio igep_wlan_bt_gpios[] __initdata = { - { -EINVAL, GPIOF_OUT_INIT_HIGH, "GPIO_WIFI_NPD" }, - { -EINVAL, GPIOF_OUT_INIT_HIGH, "GPIO_WIFI_NRESET" }, - { -EINVAL, GPIOF_OUT_INIT_HIGH, "GPIO_BT_NRESET" }, -}; - -static void __init igep_wlan_bt_init(void) -{ - int err; - - /* GPIO's for WLAN-BT combo depends on hardware revision */ - if (hwrev == IGEP2_BOARD_HWREV_B) { - igep_wlan_bt_gpios[0].gpio = IGEP2_RB_GPIO_WIFI_NPD; - igep_wlan_bt_gpios[1].gpio = IGEP2_RB_GPIO_WIFI_NRESET; - igep_wlan_bt_gpios[2].gpio = IGEP2_RB_GPIO_BT_NRESET; - } else if (hwrev == IGEP2_BOARD_HWREV_C || machine_is_igep0030()) { - igep_wlan_bt_gpios[0].gpio = IGEP2_RC_GPIO_WIFI_NPD; - igep_wlan_bt_gpios[1].gpio = IGEP2_RC_GPIO_WIFI_NRESET; - igep_wlan_bt_gpios[2].gpio = IGEP2_RC_GPIO_BT_NRESET; - } 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) { - pr_warning("IGEP2: Could not obtain WIFI/BT gpios\n"); - return; - } - - gpio_export(igep_wlan_bt_gpios[0].gpio, 0); - gpio_export(igep_wlan_bt_gpios[1].gpio, 0); - gpio_export(igep_wlan_bt_gpios[2].gpio, 0); - - gpio_set_value(igep_wlan_bt_gpios[1].gpio, 0); - udelay(10); - gpio_set_value(igep_wlan_bt_gpios[1].gpio, 1); - -} -#else -static inline void __init igep_wlan_bt_init(void) { } -#endif - -static struct regulator_consumer_supply dummy_supplies[] = { - REGULATOR_SUPPLY("vddvario", "smsc911x.0"), - REGULATOR_SUPPLY("vdd33a", "smsc911x.0"), -}; - -static void __init igep_init(void) -{ - regulator_register_fixed(1, dummy_supplies, ARRAY_SIZE(dummy_supplies)); - omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); - - /* Get IGEP2 hardware revision */ - igep2_get_revision(); - - omap_hsmmc_init(mmc); - - /* Register I2C busses and drivers */ - igep_i2c_init(); - platform_add_devices(igep_devices, ARRAY_SIZE(igep_devices)); - omap_serial_init(); - omap_sdrc_init(m65kxxxxam_sdrc_params, - m65kxxxxam_sdrc_params); - usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); - usb_musb_init(NULL); - - igep_flash_init(); - igep_leds_init(); - omap_twl4030_audio_init("igep2", NULL); - - /* - * WLAN-BT combo module from MuRata which has a Marvell WLAN - * (88W8686) + CSR Bluetooth chipset. Uses SDIO interface. - */ - igep_wlan_bt_init(); - - if (machine_is_igep0020()) { - omap_display_init(&igep2_dss_data); - igep2_init_smsc911x(); - usbhs_init_phys(igep2_phy_data, ARRAY_SIZE(igep2_phy_data)); - usbhs_init(&igep2_usbhs_bdata); - } else { - usbhs_init_phys(igep3_phy_data, ARRAY_SIZE(igep3_phy_data)); - usbhs_init(&igep3_usbhs_bdata); - } -} - -MACHINE_START(IGEP0020, "IGEP v2 board") - .atag_offset = 0x100, - .reserve = omap_reserve, - .map_io = omap3_map_io, - .init_early = omap35xx_init_early, - .init_irq = omap3_init_irq, - .handle_irq = omap3_intc_handle_irq, - .init_machine = igep_init, - .init_late = omap35xx_init_late, - .init_time = omap3_sync32k_timer_init, - .restart = omap3xxx_restart, -MACHINE_END - -MACHINE_START(IGEP0030, "IGEP OMAP3 module") - .atag_offset = 0x100, - .reserve = omap_reserve, - .map_io = omap3_map_io, - .init_early = omap35xx_init_early, - .init_irq = omap3_init_irq, - .handle_irq = omap3_intc_handle_irq, - .init_machine = igep_init, - .init_late = omap35xx_init_late, - .init_time = omap3_sync32k_timer_init, - .restart = omap3xxx_restart, -MACHINE_END diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c index dd8da2c5399f..4ec8d82b0492 100644 --- a/arch/arm/mach-omap2/board-ldp.c +++ b/arch/arm/mach-omap2/board-ldp.c @@ -36,7 +36,6 @@ #include <asm/mach/map.h> #include "common.h" -#include "board-zoom.h" #include "gpmc.h" #include "gpmc-smsc911x.h" @@ -406,7 +405,7 @@ static void __init omap_ldp_init(void) usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); usb_musb_init(NULL); board_nand_init(ldp_nand_partitions, ARRAY_SIZE(ldp_nand_partitions), - ZOOM_NAND_CS, 0, nand_default_timings); + 0, 0, nand_default_timings); omap_hsmmc_init(mmc); ldp_display_init(); diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index f26918467efc..d6ed819ff15c 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c @@ -25,7 +25,7 @@ #include <linux/gpio.h> #include <linux/input.h> #include <linux/gpio_keys.h> -#include <linux/opp.h> +#include <linux/pm_opp.h> #include <linux/cpu.h> #include <linux/mtd/mtd.h> @@ -289,18 +289,12 @@ static struct regulator_consumer_supply beagle_vsim_supply[] = { static struct gpio_led gpio_leds[]; -/* PHY's VCC regulator might be added later, so flag that we need it */ -static struct usb_phy_gen_xceiv_platform_data hsusb2_phy_data = { - .needs_vcc = true, -}; - static struct usbhs_phy_data phy_data[] = { { .port = 2, .reset_gpio = 147, .vcc_gpio = -1, /* updated in beagle_twl_gpio_setup */ .vcc_polarity = 1, /* updated in beagle_twl_gpio_setup */ - .platform_data = &hsusb2_phy_data, }, }; @@ -516,17 +510,17 @@ static int __init beagle_opp_init(void) mpu_dev = get_cpu_device(0); iva_dev = omap_device_get_by_hwmod_name("iva"); - if (IS_ERR(mpu_dev) || IS_ERR(iva_dev)) { + if (!mpu_dev || IS_ERR(iva_dev)) { pr_err("%s: Aiee.. no mpu/dsp devices? %p %p\n", __func__, mpu_dev, iva_dev); return -ENODEV; } /* Enable MPU 1GHz and lower opps */ - r = opp_enable(mpu_dev, 800000000); + r = dev_pm_opp_enable(mpu_dev, 800000000); /* TODO: MPU 1GHz needs SR and ABB */ /* Enable IVA 800MHz and lower opps */ - r |= opp_enable(iva_dev, 660000000); + r |= dev_pm_opp_enable(iva_dev, 660000000); /* TODO: DSP 800MHz needs SR and ABB */ if (r) { pr_err("%s: failed to enable higher opp %d\n", @@ -535,8 +529,8 @@ static int __init beagle_opp_init(void) * Cleanup - disable the higher freqs - we dont care * about the results */ - opp_disable(mpu_dev, 800000000); - opp_disable(iva_dev, 660000000); + dev_pm_opp_disable(mpu_dev, 800000000); + dev_pm_opp_disable(iva_dev, 660000000); } } return 0; diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c deleted file mode 100644 index 18143873346c..000000000000 --- a/arch/arm/mach-omap2/board-omap3evm.c +++ /dev/null @@ -1,756 +0,0 @@ -/* - * linux/arch/arm/mach-omap2/board-omap3evm.c - * - * Copyright (C) 2008 Texas Instruments - * - * Modified from mach-omap2/board-3430sdp.c - * - * Initial code: Syed Mohammed Khasim - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/platform_device.h> -#include <linux/delay.h> -#include <linux/err.h> -#include <linux/clk.h> -#include <linux/gpio.h> -#include <linux/input.h> -#include <linux/input/matrix_keypad.h> -#include <linux/leds.h> -#include <linux/interrupt.h> - -#include <linux/mtd/mtd.h> -#include <linux/mtd/partitions.h> -#include <linux/mtd/nand.h> - -#include <linux/spi/spi.h> -#include <linux/spi/ads7846.h> -#include <linux/i2c/twl.h> -#include <linux/usb/otg.h> -#include <linux/usb/musb.h> -#include <linux/usb/usb_phy_gen_xceiv.h> -#include <linux/smsc911x.h> - -#include <linux/wl12xx.h> -#include <linux/regulator/fixed.h> -#include <linux/regulator/machine.h> -#include <linux/mmc/host.h> -#include <linux/export.h> -#include <linux/usb/phy.h> - -#include <asm/mach-types.h> -#include <asm/mach/arch.h> -#include <asm/mach/map.h> - -#include <linux/platform_data/mtd-nand-omap2.h> -#include "common.h" -#include <linux/platform_data/spi-omap2-mcspi.h> -#include <video/omapdss.h> -#include <video/omap-panel-data.h> - -#include "soc.h" -#include "mux.h" -#include "sdram-micron-mt46h32m32lf-6.h" -#include "hsmmc.h" -#include "common-board-devices.h" -#include "board-flash.h" - -#define NAND_CS 0 - -#define OMAP3_EVM_TS_GPIO 175 -#define OMAP3_EVM_EHCI_VBUS 22 -#define OMAP3_EVM_EHCI_SELECT 61 - -#define OMAP3EVM_ETHR_START 0x2c000000 -#define OMAP3EVM_ETHR_SIZE 1024 -#define OMAP3EVM_ETHR_ID_REV 0x50 -#define OMAP3EVM_ETHR_GPIO_IRQ 176 -#define OMAP3EVM_SMSC911X_CS 5 -/* - * Eth Reset signal - * 64 = Generation 1 (<=RevD) - * 7 = Generation 2 (>=RevE) - */ -#define OMAP3EVM_GEN1_ETHR_GPIO_RST 64 -#define OMAP3EVM_GEN2_ETHR_GPIO_RST 7 - -/* - * OMAP35x EVM revision - * Run time detection of EVM revision is done by reading Ethernet - * PHY ID - - * GEN_1 = 0x01150000 - * GEN_2 = 0x92200000 - */ -enum { - OMAP3EVM_BOARD_GEN_1 = 0, /* EVM Rev between A - D */ - OMAP3EVM_BOARD_GEN_2, /* EVM Rev >= Rev E */ -}; - -static u8 omap3_evm_version; - -static u8 get_omap3_evm_rev(void) -{ - return omap3_evm_version; -} - -static void __init omap3_evm_get_revision(void) -{ - void __iomem *ioaddr; - unsigned int smsc_id; - - /* Ethernet PHY ID is stored at ID_REV register */ - ioaddr = ioremap_nocache(OMAP3EVM_ETHR_START, SZ_1K); - if (!ioaddr) - return; - smsc_id = readl(ioaddr + OMAP3EVM_ETHR_ID_REV) & 0xFFFF0000; - iounmap(ioaddr); - - switch (smsc_id) { - /*SMSC9115 chipset*/ - case 0x01150000: - omap3_evm_version = OMAP3EVM_BOARD_GEN_1; - break; - /*SMSC 9220 chipset*/ - case 0x92200000: - default: - omap3_evm_version = OMAP3EVM_BOARD_GEN_2; - } -} - -#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE) -#include "gpmc-smsc911x.h" - -static struct omap_smsc911x_platform_data smsc911x_cfg = { - .cs = OMAP3EVM_SMSC911X_CS, - .gpio_irq = OMAP3EVM_ETHR_GPIO_IRQ, - .gpio_reset = -EINVAL, - .flags = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS, -}; - -static inline void __init omap3evm_init_smsc911x(void) -{ - /* Configure ethernet controller reset gpio */ - if (cpu_is_omap3430()) { - if (get_omap3_evm_rev() == OMAP3EVM_BOARD_GEN_1) - smsc911x_cfg.gpio_reset = OMAP3EVM_GEN1_ETHR_GPIO_RST; - else - smsc911x_cfg.gpio_reset = OMAP3EVM_GEN2_ETHR_GPIO_RST; - } - - gpmc_smsc911x_init(&smsc911x_cfg); -} - -#else -static inline void __init omap3evm_init_smsc911x(void) { return; } -#endif - -/* - * OMAP3EVM LCD Panel control signals - */ -#define OMAP3EVM_LCD_PANEL_LR 2 -#define OMAP3EVM_LCD_PANEL_UD 3 -#define OMAP3EVM_LCD_PANEL_INI 152 -#define OMAP3EVM_LCD_PANEL_QVGA 154 -#define OMAP3EVM_LCD_PANEL_RESB 155 - -#define OMAP3EVM_LCD_PANEL_ENVDD 153 -#define OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO 210 - -/* - * OMAP3EVM DVI control signals - */ -#define OMAP3EVM_DVI_PANEL_EN_GPIO 199 - -#ifdef CONFIG_BROKEN -static void __init omap3_evm_display_init(void) -{ - int r; - - r = gpio_request_one(OMAP3EVM_LCD_PANEL_ENVDD, GPIOF_OUT_INIT_LOW, - "lcd_panel_envdd"); - if (r) - pr_err("failed to get lcd_panel_envdd GPIO\n"); - - r = gpio_request_one(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, - GPIOF_OUT_INIT_LOW, "lcd_panel_bklight"); - if (r) - pr_err("failed to get lcd_panel_bklight GPIO\n"); - - if (get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2) - gpio_set_value_cansleep(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 0); - else - gpio_set_value_cansleep(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 1); -} -#endif - -static struct panel_sharp_ls037v7dw01_platform_data omap3_evm_lcd_pdata = { - .name = "lcd", - .source = "dpi.0", - - .data_lines = 18, - - .resb_gpio = OMAP3EVM_LCD_PANEL_RESB, - .ini_gpio = OMAP3EVM_LCD_PANEL_INI, - .mo_gpio = OMAP3EVM_LCD_PANEL_QVGA, - .lr_gpio = OMAP3EVM_LCD_PANEL_LR, - .ud_gpio = OMAP3EVM_LCD_PANEL_UD, -}; - -static struct platform_device omap3_evm_lcd_device = { - .name = "panel-sharp-ls037v7dw01", - .id = 0, - .dev.platform_data = &omap3_evm_lcd_pdata, -}; - -static struct connector_dvi_platform_data omap3_evm_dvi_connector_pdata = { - .name = "dvi", - .source = "tfp410.0", - .i2c_bus_num = -1, -}; - -static struct platform_device omap3_evm_dvi_connector_device = { - .name = "connector-dvi", - .id = 0, - .dev.platform_data = &omap3_evm_dvi_connector_pdata, -}; - -static struct encoder_tfp410_platform_data omap3_evm_tfp410_pdata = { - .name = "tfp410.0", - .source = "dpi.0", - .data_lines = 24, - .power_down_gpio = OMAP3EVM_DVI_PANEL_EN_GPIO, -}; - -static struct platform_device omap3_evm_tfp410_device = { - .name = "tfp410", - .id = 0, - .dev.platform_data = &omap3_evm_tfp410_pdata, -}; - -static struct connector_atv_platform_data omap3_evm_tv_pdata = { - .name = "tv", - .source = "venc.0", - .connector_type = OMAP_DSS_VENC_TYPE_SVIDEO, - .invert_polarity = false, -}; - -static struct platform_device omap3_evm_tv_connector_device = { - .name = "connector-analog-tv", - .id = 0, - .dev.platform_data = &omap3_evm_tv_pdata, -}; - -static struct omap_dss_board_info omap3_evm_dss_data = { - .default_display_name = "lcd", -}; - -static struct regulator_consumer_supply omap3evm_vmmc1_supply[] = { - REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"), -}; - -static struct regulator_consumer_supply omap3evm_vsim_supply[] = { - REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.0"), -}; - -/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */ -static struct regulator_init_data omap3evm_vmmc1 = { - .constraints = { - .min_uV = 1850000, - .max_uV = 3150000, - .valid_modes_mask = REGULATOR_MODE_NORMAL - | REGULATOR_MODE_STANDBY, - .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE - | REGULATOR_CHANGE_MODE - | REGULATOR_CHANGE_STATUS, - }, - .num_consumer_supplies = ARRAY_SIZE(omap3evm_vmmc1_supply), - .consumer_supplies = omap3evm_vmmc1_supply, -}; - -/* VSIM for MMC1 pins DAT4..DAT7 (2 mA, plus card == max 50 mA) */ -static struct regulator_init_data omap3evm_vsim = { - .constraints = { - .min_uV = 1800000, - .max_uV = 3000000, - .valid_modes_mask = REGULATOR_MODE_NORMAL - | REGULATOR_MODE_STANDBY, - .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE - | REGULATOR_CHANGE_MODE - | REGULATOR_CHANGE_STATUS, - }, - .num_consumer_supplies = ARRAY_SIZE(omap3evm_vsim_supply), - .consumer_supplies = omap3evm_vsim_supply, -}; - -static struct omap2_hsmmc_info mmc[] = { - { - .mmc = 1, - .caps = MMC_CAP_4_BIT_DATA, - .gpio_cd = -EINVAL, - .gpio_wp = 63, - .deferred = true, - }, -#ifdef CONFIG_WILINK_PLATFORM_DATA - { - .name = "wl1271", - .mmc = 2, - .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD, - .gpio_wp = -EINVAL, - .gpio_cd = -EINVAL, - .nonremovable = true, - }, -#endif - {} /* Terminator */ -}; - -static struct gpio_led gpio_leds[] = { - { - .name = "omap3evm::ledb", - /* normally not visible (board underside) */ - .default_trigger = "default-on", - .gpio = -EINVAL, /* gets replaced */ - .active_low = true, - }, -}; - -static struct gpio_led_platform_data gpio_led_info = { - .leds = gpio_leds, - .num_leds = ARRAY_SIZE(gpio_leds), -}; - -static struct platform_device leds_gpio = { - .name = "leds-gpio", - .id = -1, - .dev = { - .platform_data = &gpio_led_info, - }, -}; - - -static int omap3evm_twl_gpio_setup(struct device *dev, - unsigned gpio, unsigned ngpio) -{ - int r, lcd_bl_en; - - /* gpio + 0 is "mmc0_cd" (input/IRQ) */ - mmc[0].gpio_cd = gpio + 0; - omap_hsmmc_late_init(mmc); - - /* - * Most GPIOs are for USB OTG. Some are mostly sent to - * the P2 connector; notably LEDA for the LCD backlight. - */ - - /* TWL4030_GPIO_MAX + 0 == ledA, LCD Backlight control */ - lcd_bl_en = get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2 ? - GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW; - r = gpio_request_one(gpio + TWL4030_GPIO_MAX, lcd_bl_en, "EN_LCD_BKL"); - if (r) - printk(KERN_ERR "failed to get/set lcd_bkl gpio\n"); - - /* gpio + 7 == DVI Enable */ - gpio_request_one(gpio + 7, GPIOF_OUT_INIT_LOW, "EN_DVI"); - - /* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */ - gpio_leds[0].gpio = gpio + TWL4030_GPIO_MAX + 1; - - platform_device_register(&leds_gpio); - - /* Enable VBUS switch by setting TWL4030.GPIO2DIR as output - * for starting USB tranceiver - */ -#ifdef CONFIG_TWL4030_CORE - if (get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2) { - u8 val; - - twl_i2c_read_u8(TWL4030_MODULE_GPIO, &val, REG_GPIODATADIR1); - val |= 0x04; /* TWL4030.GPIO2DIR BIT at GPIODATADIR1(0x9B) */ - twl_i2c_write_u8(TWL4030_MODULE_GPIO, val, REG_GPIODATADIR1); - } -#endif - - return 0; -} - -static struct twl4030_gpio_platform_data omap3evm_gpio_data = { - .use_leds = true, - .setup = omap3evm_twl_gpio_setup, -}; - -static uint32_t board_keymap[] = { - KEY(0, 0, KEY_LEFT), - KEY(0, 1, KEY_DOWN), - KEY(0, 2, KEY_ENTER), - KEY(0, 3, KEY_M), - - KEY(1, 0, KEY_RIGHT), - KEY(1, 1, KEY_UP), - KEY(1, 2, KEY_I), - KEY(1, 3, KEY_N), - - KEY(2, 0, KEY_A), - KEY(2, 1, KEY_E), - KEY(2, 2, KEY_J), - KEY(2, 3, KEY_O), - - KEY(3, 0, KEY_B), - KEY(3, 1, KEY_F), - KEY(3, 2, KEY_K), - KEY(3, 3, KEY_P) -}; - -static struct matrix_keymap_data board_map_data = { - .keymap = board_keymap, - .keymap_size = ARRAY_SIZE(board_keymap), -}; - -static struct twl4030_keypad_data omap3evm_kp_data = { - .keymap_data = &board_map_data, - .rows = 4, - .cols = 4, - .rep = 1, -}; - -/* ads7846 on SPI */ -static struct regulator_consumer_supply omap3evm_vio_supply[] = { - REGULATOR_SUPPLY("vcc", "spi1.0"), -}; - -/* VIO for ads7846 */ -static struct regulator_init_data omap3evm_vio = { - .constraints = { - .min_uV = 1800000, - .max_uV = 1800000, - .apply_uV = true, - .valid_modes_mask = REGULATOR_MODE_NORMAL - | REGULATOR_MODE_STANDBY, - .valid_ops_mask = REGULATOR_CHANGE_MODE - | REGULATOR_CHANGE_STATUS, - }, - .num_consumer_supplies = ARRAY_SIZE(omap3evm_vio_supply), - .consumer_supplies = omap3evm_vio_supply, -}; - -#ifdef CONFIG_WILINK_PLATFORM_DATA - -#define OMAP3EVM_WLAN_PMENA_GPIO (150) -#define OMAP3EVM_WLAN_IRQ_GPIO (149) - -static struct regulator_consumer_supply omap3evm_vmmc2_supply[] = { - REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"), -}; - -/* VMMC2 for driving the WL12xx module */ -static struct regulator_init_data omap3evm_vmmc2 = { - .constraints = { - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - }, - .num_consumer_supplies = ARRAY_SIZE(omap3evm_vmmc2_supply), - .consumer_supplies = omap3evm_vmmc2_supply, -}; - -static struct fixed_voltage_config omap3evm_vwlan = { - .supply_name = "vwl1271", - .microvolts = 1800000, /* 1.80V */ - .gpio = OMAP3EVM_WLAN_PMENA_GPIO, - .startup_delay = 70000, /* 70ms */ - .enable_high = 1, - .enabled_at_boot = 0, - .init_data = &omap3evm_vmmc2, -}; - -static struct platform_device omap3evm_wlan_regulator = { - .name = "reg-fixed-voltage", - .id = 1, - .dev = { - .platform_data = &omap3evm_vwlan, - }, -}; - -struct wl12xx_platform_data omap3evm_wlan_data __initdata = { - .board_ref_clock = WL12XX_REFCLOCK_38, /* 38.4 MHz */ -}; -#endif - -/* VAUX2 for USB */ -static struct regulator_consumer_supply omap3evm_vaux2_supplies[] = { - REGULATOR_SUPPLY("VDD_CSIPHY1", "omap3isp"), /* OMAP ISP */ - REGULATOR_SUPPLY("VDD_CSIPHY2", "omap3isp"), /* OMAP ISP */ - REGULATOR_SUPPLY("vcc", "usb_phy_gen_xceiv.2"), /* hsusb port 2 */ - REGULATOR_SUPPLY("vaux2", NULL), -}; - -static struct regulator_init_data omap3evm_vaux2 = { - .constraints = { - .min_uV = 2800000, - .max_uV = 2800000, - .apply_uV = true, - .valid_modes_mask = REGULATOR_MODE_NORMAL - | REGULATOR_MODE_STANDBY, - .valid_ops_mask = REGULATOR_CHANGE_MODE - | REGULATOR_CHANGE_STATUS, - }, - .num_consumer_supplies = ARRAY_SIZE(omap3evm_vaux2_supplies), - .consumer_supplies = omap3evm_vaux2_supplies, -}; - -static struct twl4030_platform_data omap3evm_twldata = { - /* platform_data for children goes here */ - .keypad = &omap3evm_kp_data, - .gpio = &omap3evm_gpio_data, - .vio = &omap3evm_vio, - .vmmc1 = &omap3evm_vmmc1, - .vsim = &omap3evm_vsim, -}; - -static int __init omap3_evm_i2c_init(void) -{ - omap3_pmic_get_config(&omap3evm_twldata, - TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_MADC | - TWL_COMMON_PDATA_AUDIO, - TWL_COMMON_REGULATOR_VDAC | TWL_COMMON_REGULATOR_VPLL2); - - omap3evm_twldata.vdac->constraints.apply_uV = true; - omap3evm_twldata.vpll2->constraints.apply_uV = true; - - omap3_pmic_init("twl4030", &omap3evm_twldata); - omap_register_i2c_bus(2, 400, NULL, 0); - omap_register_i2c_bus(3, 400, NULL, 0); - return 0; -} - -static struct usbhs_phy_data phy_data[] __initdata = { - { - .port = 2, - .reset_gpio = -1, /* set at runtime */ - .vcc_gpio = -EINVAL, - }, -}; - -static struct usbhs_omap_platform_data usbhs_bdata __initdata = { - .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, -}; - -#ifdef CONFIG_OMAP_MUX -static struct omap_board_mux omap35x_board_mux[] __initdata = { - OMAP3_MUX(SYS_NIRQ, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP | - OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_OUTPUT_LOW | - OMAP_PIN_OFF_WAKEUPENABLE), - OMAP3_MUX(MCSPI1_CS1, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP | - OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_OUTPUT_LOW | - OMAP_PIN_OFF_WAKEUPENABLE), - OMAP3_MUX(SYS_BOOT5, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP | - OMAP_PIN_OFF_NONE), - OMAP3_MUX(GPMC_WAIT2, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP | - OMAP_PIN_OFF_NONE), -#ifdef CONFIG_WILINK_PLATFORM_DATA - /* WLAN IRQ - GPIO 149 */ - OMAP3_MUX(UART1_RTS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT), - - /* WLAN POWER ENABLE - GPIO 150 */ - OMAP3_MUX(UART1_CTS, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT), - - /* MMC2 SDIO pin muxes for WL12xx */ - OMAP3_MUX(SDMMC2_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), - OMAP3_MUX(SDMMC2_CMD, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), - OMAP3_MUX(SDMMC2_DAT0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), - OMAP3_MUX(SDMMC2_DAT1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), - OMAP3_MUX(SDMMC2_DAT2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), - OMAP3_MUX(SDMMC2_DAT3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), -#endif - { .reg_offset = OMAP_MUX_TERMINATOR }, -}; - -static struct omap_board_mux omap36x_board_mux[] __initdata = { - OMAP3_MUX(SYS_NIRQ, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP | - OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_OUTPUT_LOW | - OMAP_PIN_OFF_WAKEUPENABLE), - OMAP3_MUX(MCSPI1_CS1, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP | - OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_OUTPUT_LOW | - OMAP_PIN_OFF_WAKEUPENABLE), - /* AM/DM37x EVM: DSS data bus muxed with sys_boot */ - OMAP3_MUX(DSS_DATA18, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), - OMAP3_MUX(DSS_DATA19, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), - OMAP3_MUX(DSS_DATA22, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), - OMAP3_MUX(DSS_DATA21, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), - OMAP3_MUX(DSS_DATA22, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), - OMAP3_MUX(DSS_DATA23, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), - OMAP3_MUX(SYS_BOOT0, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), - OMAP3_MUX(SYS_BOOT1, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), - OMAP3_MUX(SYS_BOOT3, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), - OMAP3_MUX(SYS_BOOT4, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), - OMAP3_MUX(SYS_BOOT5, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), - OMAP3_MUX(SYS_BOOT6, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), -#ifdef CONFIG_WILINK_PLATFORM_DATA - /* WLAN IRQ - GPIO 149 */ - OMAP3_MUX(UART1_RTS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT), - - /* WLAN POWER ENABLE - GPIO 150 */ - OMAP3_MUX(UART1_CTS, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT), - - /* MMC2 SDIO pin muxes for WL12xx */ - OMAP3_MUX(SDMMC2_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), - OMAP3_MUX(SDMMC2_CMD, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), - OMAP3_MUX(SDMMC2_DAT0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), - OMAP3_MUX(SDMMC2_DAT1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), - OMAP3_MUX(SDMMC2_DAT2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), - OMAP3_MUX(SDMMC2_DAT3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), -#endif - - { .reg_offset = OMAP_MUX_TERMINATOR }, -}; -#else -#define omap35x_board_mux NULL -#define omap36x_board_mux NULL -#endif - -static struct omap_musb_board_data musb_board_data = { - .interface_type = MUSB_INTERFACE_ULPI, - .mode = MUSB_OTG, - .power = 100, -}; - -static struct gpio omap3_evm_ehci_gpios[] __initdata = { - { OMAP3_EVM_EHCI_VBUS, GPIOF_OUT_INIT_HIGH, "enable EHCI VBUS" }, - { OMAP3_EVM_EHCI_SELECT, GPIOF_OUT_INIT_LOW, "select EHCI port" }, -}; - -static void __init omap3_evm_wl12xx_init(void) -{ -#ifdef CONFIG_WILINK_PLATFORM_DATA - int ret; - - /* WL12xx WLAN Init */ - omap3evm_wlan_data.irq = gpio_to_irq(OMAP3EVM_WLAN_IRQ_GPIO); - ret = wl12xx_set_platform_data(&omap3evm_wlan_data); - if (ret) - pr_err("error setting wl12xx data: %d\n", ret); - ret = platform_device_register(&omap3evm_wlan_regulator); - if (ret) - pr_err("error registering wl12xx device: %d\n", ret); -#endif -} - -static struct regulator_consumer_supply dummy_supplies[] = { - REGULATOR_SUPPLY("vddvario", "smsc911x.0"), - REGULATOR_SUPPLY("vdd33a", "smsc911x.0"), -}; - -static struct mtd_partition omap3evm_nand_partitions[] = { - /* All the partition sizes are listed in terms of NAND block size */ - { - .name = "X-Loader", - .offset = 0, - .size = 4*(SZ_128K), - .mask_flags = MTD_WRITEABLE - }, - { - .name = "U-Boot", - .offset = MTDPART_OFS_APPEND, - .size = 14*(SZ_128K), - .mask_flags = MTD_WRITEABLE - }, - { - .name = "U-Boot Env", - .offset = MTDPART_OFS_APPEND, - .size = 2*(SZ_128K) - }, - { - .name = "Kernel", - .offset = MTDPART_OFS_APPEND, - .size = 40*(SZ_128K) - }, - { - .name = "File system", - .size = MTDPART_SIZ_FULL, - .offset = MTDPART_OFS_APPEND, - }, -}; - -static void __init omap3_evm_init(void) -{ - struct omap_board_mux *obm; - - omap3_evm_get_revision(); - regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); - - obm = (cpu_is_omap3630()) ? omap36x_board_mux : omap35x_board_mux; - omap3_mux_init(obm, OMAP_PACKAGE_CBB); - - omap_mux_init_gpio(63, OMAP_PIN_INPUT); - omap_hsmmc_init(mmc); - - if (get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2) - omap3evm_twldata.vaux2 = &omap3evm_vaux2; - - omap3_evm_i2c_init(); - - omap_display_init(&omap3_evm_dss_data); - platform_device_register(&omap3_evm_lcd_device); - platform_device_register(&omap3_evm_tfp410_device); - platform_device_register(&omap3_evm_dvi_connector_device); - platform_device_register(&omap3_evm_tv_connector_device); - - omap_serial_init(); - omap_sdrc_init(mt46h32m32lf6_sdrc_params, NULL); - - /* OMAP3EVM uses ISP1504 phy and so register nop transceiver */ - usb_nop_xceiv_register(); - - if (get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2) { - /* enable EHCI VBUS using GPIO22 */ - omap_mux_init_gpio(OMAP3_EVM_EHCI_VBUS, OMAP_PIN_INPUT_PULLUP); - /* Select EHCI port on main board */ - omap_mux_init_gpio(OMAP3_EVM_EHCI_SELECT, - OMAP_PIN_INPUT_PULLUP); - gpio_request_array(omap3_evm_ehci_gpios, - ARRAY_SIZE(omap3_evm_ehci_gpios)); - - /* setup EHCI phy reset config */ - omap_mux_init_gpio(21, OMAP_PIN_INPUT_PULLUP); - phy_data[0].reset_gpio = 21; - - /* EVM REV >= E can supply 500mA with EXTVBUS programming */ - musb_board_data.power = 500; - musb_board_data.extvbus = 1; - } else { - /* setup EHCI phy reset on MDC */ - omap_mux_init_gpio(135, OMAP_PIN_OUTPUT); - phy_data[0].reset_gpio = 135; - } - usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); - usb_musb_init(&musb_board_data); - - usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); - usbhs_init(&usbhs_bdata); - board_nand_init(omap3evm_nand_partitions, - ARRAY_SIZE(omap3evm_nand_partitions), NAND_CS, - NAND_BUSWIDTH_16, NULL); - - omap_ads7846_init(1, OMAP3_EVM_TS_GPIO, 310, NULL); - omap3evm_init_smsc911x(); -#ifdef CONFIG_BROKEN - omap3_evm_display_init(); -#endif - omap3_evm_wl12xx_init(); - omap_twl4030_audio_init("omap3evm", NULL); -} - -MACHINE_START(OMAP3EVM, "OMAP3 EVM") - /* Maintainer: Syed Mohammed Khasim - Texas Instruments */ - .atag_offset = 0x100, - .reserve = omap_reserve, - .map_io = omap3_map_io, - .init_early = omap35xx_init_early, - .init_irq = omap3_init_irq, - .handle_irq = omap3_intc_handle_irq, - .init_machine = omap3_evm_init, - .init_late = omap35xx_init_late, - .init_time = omap3_sync32k_timer_init, - .restart = omap3xxx_restart, -MACHINE_END diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c index ba8342fef799..119efaf5808a 100644 --- a/arch/arm/mach-omap2/board-omap3stalker.c +++ b/arch/arm/mach-omap2/board-omap3stalker.c @@ -32,7 +32,7 @@ #include <linux/spi/spi.h> #include <linux/interrupt.h> #include <linux/smsc911x.h> -#include <linux/i2c/at24.h> +#include <linux/platform_data/at24.h> #include <linux/usb/phy.h> #include <asm/mach-types.h> diff --git a/arch/arm/mach-omap2/board-rm680.c b/arch/arm/mach-omap2/board-rm680.c deleted file mode 100644 index 345e8c4b8731..000000000000 --- a/arch/arm/mach-omap2/board-rm680.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Board support file for Nokia N950 (RM-680) / N9 (RM-696). - * - * Copyright (C) 2010 Nokia - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/io.h> -#include <linux/i2c.h> -#include <linux/gpio.h> -#include <linux/init.h> -#include <linux/i2c/twl.h> -#include <linux/platform_device.h> -#include <linux/regulator/fixed.h> -#include <linux/regulator/machine.h> -#include <linux/regulator/consumer.h> -#include <linux/platform_data/mtd-onenand-omap2.h> -#include <linux/usb/phy.h> - -#include <asm/mach/arch.h> -#include <asm/mach-types.h> - -#include "common.h" -#include "mux.h" -#include "gpmc.h" -#include "mmc.h" -#include "hsmmc.h" -#include "sdram-nokia.h" -#include "common-board-devices.h" -#include "gpmc-onenand.h" - -static struct regulator_consumer_supply rm680_vemmc_consumers[] = { - REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"), -}; - -/* Fixed regulator for internal eMMC */ -static struct regulator_init_data rm680_vemmc = { - .constraints = { - .name = "rm680_vemmc", - .valid_modes_mask = REGULATOR_MODE_NORMAL - | REGULATOR_MODE_STANDBY, - .valid_ops_mask = REGULATOR_CHANGE_STATUS - | REGULATOR_CHANGE_MODE, - }, - .num_consumer_supplies = ARRAY_SIZE(rm680_vemmc_consumers), - .consumer_supplies = rm680_vemmc_consumers, -}; - -static struct fixed_voltage_config rm680_vemmc_config = { - .supply_name = "VEMMC", - .microvolts = 2900000, - .gpio = 157, - .startup_delay = 150, - .enable_high = 1, - .init_data = &rm680_vemmc, -}; - -static struct platform_device rm680_vemmc_device = { - .name = "reg-fixed-voltage", - .dev = { - .platform_data = &rm680_vemmc_config, - }, -}; - -static struct platform_device *rm680_peripherals_devices[] __initdata = { - &rm680_vemmc_device, -}; - -/* TWL */ -static struct twl4030_gpio_platform_data rm680_gpio_data = { - .pullups = BIT(0), - .pulldowns = BIT(1) | BIT(2) | BIT(8) | BIT(15), -}; - -static struct twl4030_platform_data rm680_twl_data = { - .gpio = &rm680_gpio_data, - /* add rest of the children here */ -}; - -static void __init rm680_i2c_init(void) -{ - omap3_pmic_get_config(&rm680_twl_data, TWL_COMMON_PDATA_USB, 0); - omap_pmic_init(1, 2900, "twl5031", 7 + OMAP_INTC_START, &rm680_twl_data); - omap_register_i2c_bus(2, 400, NULL, 0); - omap_register_i2c_bus(3, 400, NULL, 0); -} - -#if defined(CONFIG_MTD_ONENAND_OMAP2) || \ - defined(CONFIG_MTD_ONENAND_OMAP2_MODULE) -static struct omap_onenand_platform_data board_onenand_data[] = { - { - .gpio_irq = 65, - .flags = ONENAND_SYNC_READWRITE, - } -}; -#endif - -/* eMMC */ -static struct omap2_hsmmc_info mmc[] __initdata = { - { - .name = "internal", - .mmc = 2, - .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MMC_HIGHSPEED, - .gpio_cd = -EINVAL, - .gpio_wp = -EINVAL, - }, - { /* Terminator */ } -}; - -static void __init rm680_peripherals_init(void) -{ - platform_add_devices(rm680_peripherals_devices, - ARRAY_SIZE(rm680_peripherals_devices)); - rm680_i2c_init(); - gpmc_onenand_init(board_onenand_data); - omap_hsmmc_init(mmc); -} - -#ifdef CONFIG_OMAP_MUX -static struct omap_board_mux board_mux[] __initdata = { - { .reg_offset = OMAP_MUX_TERMINATOR }, -}; -#endif - -static void __init rm680_init(void) -{ - struct omap_sdrc_params *sdrc_params; - - omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); - omap_serial_init(); - - sdrc_params = nokia_get_sdram_timings(); - omap_sdrc_init(sdrc_params, sdrc_params); - - usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); - usb_musb_init(NULL); - rm680_peripherals_init(); -} - -MACHINE_START(NOKIA_RM680, "Nokia RM-680 board") - .atag_offset = 0x100, - .reserve = omap_reserve, - .map_io = omap3_map_io, - .init_early = omap3630_init_early, - .init_irq = omap3_init_irq, - .handle_irq = omap3_intc_handle_irq, - .init_machine = rm680_init, - .init_late = omap3630_init_late, - .init_time = omap3_sync32k_timer_init, - .restart = omap3xxx_restart, -MACHINE_END - -MACHINE_START(NOKIA_RM696, "Nokia RM-696 board") - .atag_offset = 0x100, - .reserve = omap_reserve, - .map_io = omap3_map_io, - .init_early = omap3630_init_early, - .init_irq = omap3_init_irq, - .handle_irq = omap3_intc_handle_irq, - .init_machine = rm680_init, - .init_late = omap3630_init_late, - .init_time = omap3_sync32k_timer_init, - .restart = omap3xxx_restart, -MACHINE_END diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c index f6fe388af989..f093af17f5e6 100644 --- a/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c @@ -57,6 +57,8 @@ #include "common-board-devices.h" #include "gpmc.h" #include "gpmc-onenand.h" +#include "soc.h" +#include "omap-secure.h" #define SYSTEM_REV_B_USES_VAUX3 0x1699 #define SYSTEM_REV_S_USES_VAUX3 0x8 @@ -211,29 +213,11 @@ static struct lp55xx_led_config rx51_lp5523_led_config[] = { } }; -static int rx51_lp5523_setup(void) -{ - return gpio_request_one(RX51_LP5523_CHIP_EN_GPIO, GPIOF_DIR_OUT, - "lp5523_enable"); -} - -static void rx51_lp5523_release(void) -{ - gpio_free(RX51_LP5523_CHIP_EN_GPIO); -} - -static void rx51_lp5523_enable(bool state) -{ - gpio_set_value(RX51_LP5523_CHIP_EN_GPIO, !!state); -} - static struct lp55xx_platform_data rx51_lp5523_platform_data = { .led_config = rx51_lp5523_led_config, .num_channels = ARRAY_SIZE(rx51_lp5523_led_config), .clock_mode = LP55XX_CLOCK_AUTO, - .setup_resources = rx51_lp5523_setup, - .release_resources = rx51_lp5523_release, - .enable = rx51_lp5523_enable, + .enable_gpio = RX51_LP5523_CHIP_EN_GPIO, }; #endif @@ -1298,6 +1282,22 @@ static void __init rx51_init_twl4030_hwmon(void) platform_device_register(&madc_hwmon); } +static struct platform_device omap3_rom_rng_device = { + .name = "omap3-rom-rng", + .id = -1, + .dev = { + .platform_data = rx51_secure_rng_call, + }, +}; + +static void __init rx51_init_omap3_rom_rng(void) +{ + if (omap_type() == OMAP2_DEVICE_TYPE_SEC) { + pr_info("RX-51: Registring OMAP3 HWRNG device\n"); + platform_device_register(&omap3_rom_rng_device); + } +} + void __init rx51_peripherals_init(void) { rx51_i2c_init(); @@ -1318,5 +1318,6 @@ void __init rx51_peripherals_init(void) rx51_charger_init(); rx51_init_twl4030_hwmon(); + rx51_init_omap3_rom_rng(); } diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c index 7735105561d8..db168c9627a1 100644 --- a/arch/arm/mach-omap2/board-rx51.c +++ b/arch/arm/mach-omap2/board-rx51.c @@ -2,6 +2,8 @@ * Board support file for Nokia N900 (aka RX-51). * * Copyright (C) 2007, 2008 Nokia + * Copyright (C) 2012 Ivaylo Dimitrov <freemangordon@abv.bg> + * Copyright (C) 2013 Pali Rohár <pali.rohar@gmail.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 @@ -31,7 +33,9 @@ #include "mux.h" #include "gpmc.h" #include "pm.h" +#include "soc.h" #include "sdram-nokia.h" +#include "omap-secure.h" #define RX51_GPIO_SLEEP_IND 162 @@ -103,6 +107,14 @@ static void __init rx51_init(void) usb_musb_init(&musb_board_data); rx51_peripherals_init(); + if (omap_type() == OMAP2_DEVICE_TYPE_SEC) { +#ifdef CONFIG_ARM_ERRATA_430973 + pr_info("RX-51: Enabling ARM errata 430973 workaround\n"); + /* set IBE to 1 */ + rx51_secure_update_aux_cr(BIT(6), 0); +#endif + } + /* Ensure SDRC pins are mux'd for self-refresh */ omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT); omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT); diff --git a/arch/arm/mach-omap2/board-zoom-debugboard.c b/arch/arm/mach-omap2/board-zoom-debugboard.c deleted file mode 100644 index 42e5f231a799..000000000000 --- a/arch/arm/mach-omap2/board-zoom-debugboard.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (C) 2009 Texas Instruments Inc. - * Mikkel Christensen <mlc@ti.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 - * published by the Free Software Foundation. - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/gpio.h> -#include <linux/serial_8250.h> -#include <linux/smsc911x.h> -#include <linux/interrupt.h> - -#include <linux/regulator/fixed.h> -#include <linux/regulator/machine.h> - -#include "gpmc.h" -#include "gpmc-smsc911x.h" - -#include "board-zoom.h" - -#include "soc.h" -#include "common.h" - -#define ZOOM_SMSC911X_CS 7 -#define ZOOM_SMSC911X_GPIO 158 -#define ZOOM_QUADUART_CS 3 -#define ZOOM_QUADUART_GPIO 102 -#define ZOOM_QUADUART_RST_GPIO 152 -#define QUART_CLK 1843200 -#define DEBUG_BASE 0x08000000 -#define ZOOM_ETHR_START DEBUG_BASE - -static struct omap_smsc911x_platform_data zoom_smsc911x_cfg = { - .cs = ZOOM_SMSC911X_CS, - .gpio_irq = ZOOM_SMSC911X_GPIO, - .gpio_reset = -EINVAL, - .flags = SMSC911X_USE_32BIT, -}; - -static inline void __init zoom_init_smsc911x(void) -{ - gpmc_smsc911x_init(&zoom_smsc911x_cfg); -} - -static struct plat_serial8250_port serial_platform_data[] = { - { - .mapbase = ZOOM_UART_BASE, - .flags = UPF_BOOT_AUTOCONF|UPF_IOREMAP|UPF_SHARE_IRQ, - .irqflags = IRQF_SHARED | IRQF_TRIGGER_RISING, - .iotype = UPIO_MEM, - .regshift = 1, - .uartclk = QUART_CLK, - }, { - .flags = 0 - } -}; - -static struct platform_device zoom_debugboard_serial_device = { - .name = "serial8250", - .id = PLAT8250_DEV_PLATFORM, - .dev = { - .platform_data = serial_platform_data, - }, -}; - -static inline void __init zoom_init_quaduart(void) -{ - int quart_cs; - unsigned long cs_mem_base; - int quart_gpio = 0; - - if (gpio_request_one(ZOOM_QUADUART_RST_GPIO, - GPIOF_OUT_INIT_LOW, - "TL16CP754C GPIO") < 0) { - pr_err("Failed to request GPIO%d for TL16CP754C\n", - ZOOM_QUADUART_RST_GPIO); - return; - } - - quart_cs = ZOOM_QUADUART_CS; - - if (gpmc_cs_request(quart_cs, SZ_1M, &cs_mem_base) < 0) { - pr_err("Failed to request GPMC mem for Quad UART(TL16CP754C)\n"); - return; - } - - quart_gpio = ZOOM_QUADUART_GPIO; - - if (gpio_request_one(quart_gpio, GPIOF_IN, "TL16CP754C GPIO") < 0) - printk(KERN_ERR "Failed to request GPIO%d for TL16CP754C\n", - quart_gpio); - - serial_platform_data[0].irq = gpio_to_irq(102); -} - -static inline int omap_zoom_debugboard_detect(void) -{ - int debug_board_detect = 0; - int ret = 1; - - debug_board_detect = ZOOM_SMSC911X_GPIO; - - if (gpio_request_one(debug_board_detect, GPIOF_IN, - "Zoom debug board detect") < 0) { - pr_err("Failed to request GPIO%d for Zoom debug board detect\n", - debug_board_detect); - return 0; - } - - if (!gpio_get_value(debug_board_detect)) { - ret = 0; - } - gpio_free(debug_board_detect); - return ret; -} - -static struct platform_device *zoom_devices[] __initdata = { - &zoom_debugboard_serial_device, -}; - -static struct regulator_consumer_supply dummy_supplies[] = { - REGULATOR_SUPPLY("vddvario", "smsc911x.0"), - REGULATOR_SUPPLY("vdd33a", "smsc911x.0"), -}; - -int __init zoom_debugboard_init(void) -{ - if (!omap_zoom_debugboard_detect()) - return 0; - - regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); - zoom_init_smsc911x(); - zoom_init_quaduart(); - return platform_add_devices(zoom_devices, ARRAY_SIZE(zoom_devices)); -} diff --git a/arch/arm/mach-omap2/board-zoom-display.c b/arch/arm/mach-omap2/board-zoom-display.c deleted file mode 100644 index 3d8ecc1e05bd..000000000000 --- a/arch/arm/mach-omap2/board-zoom-display.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2010 Texas Instruments Inc. - * - * Modified from mach-omap2/board-zoom-peripherals.c - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/platform_device.h> -#include <linux/gpio.h> -#include <linux/spi/spi.h> -#include <linux/platform_data/spi-omap2-mcspi.h> -#include <video/omapdss.h> -#include <video/omap-panel-data.h> - -#include "board-zoom.h" -#include "soc.h" -#include "common.h" - -#define LCD_PANEL_RESET_GPIO_PROD 96 -#define LCD_PANEL_RESET_GPIO_PILOT 55 -#define LCD_PANEL_QVGA_GPIO 56 - -static struct panel_nec_nl8048hl11_platform_data zoom_lcd_pdata = { - .name = "lcd", - .source = "dpi.0", - - .data_lines = 24, - - .res_gpio = -1, /* filled in code */ - .qvga_gpio = LCD_PANEL_QVGA_GPIO, -}; - -static struct omap_dss_board_info zoom_dss_data = { - .default_display_name = "lcd", -}; - -static void __init zoom_lcd_panel_init(void) -{ - zoom_lcd_pdata.res_gpio = (omap_rev() > OMAP3430_REV_ES3_0) ? - LCD_PANEL_RESET_GPIO_PROD : - LCD_PANEL_RESET_GPIO_PILOT; -} - -static struct omap2_mcspi_device_config dss_lcd_mcspi_config = { - .turbo_mode = 1, -}; - -static struct spi_board_info nec_8048_spi_board_info[] __initdata = { - [0] = { - .modalias = "panel-nec-nl8048hl11", - .bus_num = 1, - .chip_select = 2, - .max_speed_hz = 375000, - .controller_data = &dss_lcd_mcspi_config, - .platform_data = &zoom_lcd_pdata, - }, -}; - -void __init zoom_display_init(void) -{ - omap_display_init(&zoom_dss_data); - zoom_lcd_panel_init(); - spi_register_board_info(nec_8048_spi_board_info, - ARRAY_SIZE(nec_8048_spi_board_info)); -} - diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c deleted file mode 100644 index a90375d5b2b6..000000000000 --- a/arch/arm/mach-omap2/board-zoom-peripherals.c +++ /dev/null @@ -1,360 +0,0 @@ -/* - * Copyright (C) 2009 Texas Instruments Inc. - * - * Modified from mach-omap2/board-zoom2.c - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/platform_device.h> -#include <linux/input.h> -#include <linux/input/matrix_keypad.h> -#include <linux/gpio.h> -#include <linux/i2c/twl.h> -#include <linux/regulator/machine.h> -#include <linux/regulator/fixed.h> -#include <linux/wl12xx.h> -#include <linux/mmc/host.h> -#include <linux/platform_data/gpio-omap.h> -#include <linux/platform_data/omap-twl4030.h> -#include <linux/usb/phy.h> -#include <linux/pwm.h> -#include <linux/leds_pwm.h> -#include <linux/pwm_backlight.h> - -#include <asm/mach-types.h> -#include <asm/mach/arch.h> -#include <asm/mach/map.h> - -#include "common.h" - -#include "board-zoom.h" - -#include "mux.h" -#include "hsmmc.h" -#include "common-board-devices.h" - -#define OMAP_ZOOM_WLAN_PMENA_GPIO (101) -#define OMAP_ZOOM_TSC2004_IRQ_GPIO (153) -#define OMAP_ZOOM_WLAN_IRQ_GPIO (162) - -/* Zoom2 has Qwerty keyboard*/ -static uint32_t board_keymap[] = { - KEY(0, 0, KEY_E), - KEY(0, 1, KEY_R), - KEY(0, 2, KEY_T), - KEY(0, 3, KEY_HOME), - KEY(0, 6, KEY_I), - KEY(0, 7, KEY_LEFTSHIFT), - KEY(1, 0, KEY_D), - KEY(1, 1, KEY_F), - KEY(1, 2, KEY_G), - KEY(1, 3, KEY_SEND), - KEY(1, 6, KEY_K), - KEY(1, 7, KEY_ENTER), - KEY(2, 0, KEY_X), - KEY(2, 1, KEY_C), - KEY(2, 2, KEY_V), - KEY(2, 3, KEY_END), - KEY(2, 6, KEY_DOT), - KEY(2, 7, KEY_CAPSLOCK), - KEY(3, 0, KEY_Z), - KEY(3, 1, KEY_KPPLUS), - KEY(3, 2, KEY_B), - KEY(3, 3, KEY_F1), - KEY(3, 6, KEY_O), - KEY(3, 7, KEY_SPACE), - KEY(4, 0, KEY_W), - KEY(4, 1, KEY_Y), - KEY(4, 2, KEY_U), - KEY(4, 3, KEY_F2), - KEY(4, 4, KEY_VOLUMEUP), - KEY(4, 6, KEY_L), - KEY(4, 7, KEY_LEFT), - KEY(5, 0, KEY_S), - KEY(5, 1, KEY_H), - KEY(5, 2, KEY_J), - KEY(5, 3, KEY_F3), - KEY(5, 4, KEY_UNKNOWN), - KEY(5, 5, KEY_VOLUMEDOWN), - KEY(5, 6, KEY_M), - KEY(5, 7, KEY_RIGHT), - KEY(6, 0, KEY_Q), - KEY(6, 1, KEY_A), - KEY(6, 2, KEY_N), - KEY(6, 3, KEY_BACKSPACE), - KEY(6, 6, KEY_P), - KEY(6, 7, KEY_UP), - KEY(7, 0, KEY_PROG1), /*MACRO 1 <User defined> */ - KEY(7, 1, KEY_PROG2), /*MACRO 2 <User defined> */ - KEY(7, 2, KEY_PROG3), /*MACRO 3 <User defined> */ - KEY(7, 3, KEY_PROG4), /*MACRO 4 <User defined> */ - KEY(7, 6, KEY_SELECT), - KEY(7, 7, KEY_DOWN) -}; - -static struct matrix_keymap_data board_map_data = { - .keymap = board_keymap, - .keymap_size = ARRAY_SIZE(board_keymap), -}; - -static struct twl4030_keypad_data zoom_kp_twl4030_data = { - .keymap_data = &board_map_data, - .rows = 8, - .cols = 8, - .rep = 1, -}; - -static struct regulator_consumer_supply zoom_vmmc1_supply[] = { - REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"), -}; - -static struct regulator_consumer_supply zoom_vsim_supply[] = { - REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.0"), -}; - -static struct regulator_consumer_supply zoom_vmmc2_supply[] = { - REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"), -}; - -static struct regulator_consumer_supply zoom_vmmc3_supply[] = { - REGULATOR_SUPPLY("vmmc", "omap_hsmmc.2"), -}; - -/* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */ -static struct regulator_init_data zoom_vmmc1 = { - .constraints = { - .min_uV = 1850000, - .max_uV = 3150000, - .valid_modes_mask = REGULATOR_MODE_NORMAL - | REGULATOR_MODE_STANDBY, - .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE - | REGULATOR_CHANGE_MODE - | REGULATOR_CHANGE_STATUS, - }, - .num_consumer_supplies = ARRAY_SIZE(zoom_vmmc1_supply), - .consumer_supplies = zoom_vmmc1_supply, -}; - -/* VMMC2 for MMC2 card */ -static struct regulator_init_data zoom_vmmc2 = { - .constraints = { - .min_uV = 1850000, - .max_uV = 1850000, - .apply_uV = true, - .valid_modes_mask = REGULATOR_MODE_NORMAL - | REGULATOR_MODE_STANDBY, - .valid_ops_mask = REGULATOR_CHANGE_MODE - | REGULATOR_CHANGE_STATUS, - }, - .num_consumer_supplies = ARRAY_SIZE(zoom_vmmc2_supply), - .consumer_supplies = zoom_vmmc2_supply, -}; - -/* VSIM for OMAP VDD_MMC1A (i/o for DAT4..DAT7) */ -static struct regulator_init_data zoom_vsim = { - .constraints = { - .min_uV = 1800000, - .max_uV = 3000000, - .valid_modes_mask = REGULATOR_MODE_NORMAL - | REGULATOR_MODE_STANDBY, - .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE - | REGULATOR_CHANGE_MODE - | REGULATOR_CHANGE_STATUS, - }, - .num_consumer_supplies = ARRAY_SIZE(zoom_vsim_supply), - .consumer_supplies = zoom_vsim_supply, -}; - -static struct regulator_init_data zoom_vmmc3 = { - .constraints = { - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - }, - .num_consumer_supplies = ARRAY_SIZE(zoom_vmmc3_supply), - .consumer_supplies = zoom_vmmc3_supply, -}; - -static struct fixed_voltage_config zoom_vwlan = { - .supply_name = "vwl1271", - .microvolts = 1800000, /* 1.8V */ - .gpio = OMAP_ZOOM_WLAN_PMENA_GPIO, - .startup_delay = 70000, /* 70msec */ - .enable_high = 1, - .enabled_at_boot = 0, - .init_data = &zoom_vmmc3, -}; - -static struct platform_device omap_vwlan_device = { - .name = "reg-fixed-voltage", - .id = 1, - .dev = { - .platform_data = &zoom_vwlan, - }, -}; - -static struct pwm_lookup zoom_pwm_lookup[] = { - PWM_LOOKUP("twl-pwm", 0, "leds_pwm", "zoom::keypad"), - PWM_LOOKUP("twl-pwm", 1, "pwm-backlight", "backlight"), -}; - -static struct led_pwm zoom_pwm_leds[] = { - { - .name = "zoom::keypad", - .max_brightness = 127, - .pwm_period_ns = 7812500, - }, -}; - -static struct led_pwm_platform_data zoom_pwm_data = { - .num_leds = ARRAY_SIZE(zoom_pwm_leds), - .leds = zoom_pwm_leds, -}; - -static struct platform_device zoom_leds_pwm = { - .name = "leds_pwm", - .id = -1, - .dev = { - .platform_data = &zoom_pwm_data, - }, -}; - -static struct platform_pwm_backlight_data zoom_backlight_data = { - .pwm_id = 1, - .max_brightness = 127, - .dft_brightness = 127, - .pwm_period_ns = 7812500, -}; - -static struct platform_device zoom_backlight_pwm = { - .name = "pwm-backlight", - .id = -1, - .dev = { - .platform_data = &zoom_backlight_data, - }, -}; - -static struct platform_device *zoom_devices[] __initdata = { - &omap_vwlan_device, - &zoom_leds_pwm, - &zoom_backlight_pwm, -}; - -static struct wl12xx_platform_data omap_zoom_wlan_data __initdata = { - .board_ref_clock = WL12XX_REFCLOCK_26, /* 26 MHz */ -}; - -static struct omap2_hsmmc_info mmc[] = { - { - .name = "external", - .mmc = 1, - .caps = MMC_CAP_4_BIT_DATA, - .gpio_wp = -EINVAL, - .power_saving = true, - .deferred = true, - }, - { - .name = "internal", - .mmc = 2, - .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, - .gpio_cd = -EINVAL, - .gpio_wp = -EINVAL, - .nonremovable = true, - .power_saving = true, - }, - { - .name = "wl1271", - .mmc = 3, - .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD, - .gpio_wp = -EINVAL, - .gpio_cd = -EINVAL, - .nonremovable = true, - }, - {} /* Terminator */ -}; - -static struct omap_tw4030_pdata omap_twl4030_audio_data = { - .voice_connected = true, - .custom_routing = true, - - .has_hs = OMAP_TWL4030_LEFT | OMAP_TWL4030_RIGHT, - .has_hf = OMAP_TWL4030_LEFT | OMAP_TWL4030_RIGHT, - - .has_mainmic = true, - .has_submic = true, - .has_hsmic = true, - .has_linein = OMAP_TWL4030_LEFT | OMAP_TWL4030_RIGHT, -}; - -static int zoom_twl_gpio_setup(struct device *dev, - unsigned gpio, unsigned ngpio) -{ - /* gpio + 0 is "mmc0_cd" (input/IRQ) */ - mmc[0].gpio_cd = gpio + 0; - omap_hsmmc_late_init(mmc); - - /* Audio setup */ - omap_twl4030_audio_data.jack_detect = gpio + 2; - omap_twl4030_audio_init("Zoom2", &omap_twl4030_audio_data); - - return 0; -} - -static struct twl4030_gpio_platform_data zoom_gpio_data = { - .setup = zoom_twl_gpio_setup, -}; - -static struct twl4030_platform_data zoom_twldata = { - /* platform_data for children goes here */ - .gpio = &zoom_gpio_data, - .keypad = &zoom_kp_twl4030_data, - .vmmc1 = &zoom_vmmc1, - .vmmc2 = &zoom_vmmc2, - .vsim = &zoom_vsim, -}; - -static int __init omap_i2c_init(void) -{ - omap3_pmic_get_config(&zoom_twldata, - TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_BCI | - TWL_COMMON_PDATA_MADC | TWL_COMMON_PDATA_AUDIO, - TWL_COMMON_REGULATOR_VDAC | TWL_COMMON_REGULATOR_VPLL2); - - if (machine_is_omap_zoom2()) - zoom_twldata.audio->codec->ramp_delay_value = 3; /* 161 ms */ - - omap_pmic_init(1, 2400, "twl5030", 7 + OMAP_INTC_START, &zoom_twldata); - omap_register_i2c_bus(2, 400, NULL, 0); - omap_register_i2c_bus(3, 400, NULL, 0); - return 0; -} - -static void enable_board_wakeup_source(void) -{ - /* T2 interrupt line (keypad) */ - omap_mux_init_signal("sys_nirq", - OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP); -} - -void __init zoom_peripherals_init(void) -{ - int ret; - - omap_zoom_wlan_data.irq = gpio_to_irq(OMAP_ZOOM_WLAN_IRQ_GPIO); - ret = wl12xx_set_platform_data(&omap_zoom_wlan_data); - - if (ret) - pr_err("error setting wl12xx data: %d\n", ret); - - omap_hsmmc_init(mmc); - omap_i2c_init(); - pwm_add_table(zoom_pwm_lookup, ARRAY_SIZE(zoom_pwm_lookup)); - platform_add_devices(zoom_devices, ARRAY_SIZE(zoom_devices)); - usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); - usb_musb_init(NULL); - enable_board_wakeup_source(); - omap_serial_init(); -} diff --git a/arch/arm/mach-omap2/board-zoom.c b/arch/arm/mach-omap2/board-zoom.c deleted file mode 100644 index 1a3dd865d8eb..000000000000 --- a/arch/arm/mach-omap2/board-zoom.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (C) 2009-2010 Texas Instruments Inc. - * Mikkel Christensen <mlc@ti.com> - * Felipe Balbi <balbi@ti.com> - * - * Modified from mach-omap2/board-ldp.c - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/platform_device.h> -#include <linux/input.h> -#include <linux/gpio.h> -#include <linux/i2c/twl.h> -#include <linux/mtd/nand.h> - -#include <asm/mach-types.h> -#include <asm/mach/arch.h> - -#include "common.h" - -#include "board-zoom.h" - -#include "board-flash.h" -#include "mux.h" -#include "sdram-micron-mt46h32m32lf-6.h" -#include "sdram-hynix-h8mbx00u0mer-0em.h" - -#define ZOOM3_EHCI_RESET_GPIO 64 - -#ifdef CONFIG_OMAP_MUX -static struct omap_board_mux board_mux[] __initdata = { - /* WLAN IRQ - GPIO 162 */ - OMAP3_MUX(MCBSP1_CLKX, OMAP_MUX_MODE4 | OMAP_PIN_INPUT), - /* WLAN POWER ENABLE - GPIO 101 */ - OMAP3_MUX(CAM_D2, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT), - /* WLAN SDIO: MMC3 CMD */ - OMAP3_MUX(MCSPI1_CS1, OMAP_MUX_MODE3 | OMAP_PIN_INPUT_PULLUP), - /* WLAN SDIO: MMC3 CLK */ - OMAP3_MUX(ETK_CLK, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP), - /* WLAN SDIO: MMC3 DAT[0-3] */ - OMAP3_MUX(ETK_D3, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP), - OMAP3_MUX(ETK_D4, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP), - OMAP3_MUX(ETK_D5, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP), - OMAP3_MUX(ETK_D6, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP), - { .reg_offset = OMAP_MUX_TERMINATOR }, -}; -#endif - -static struct mtd_partition zoom_nand_partitions[] = { - /* All the partition sizes are listed in terms of NAND block size */ - { - .name = "X-Loader-NAND", - .offset = 0, - .size = 4 * (64 * 2048), /* 512KB, 0x80000 */ - .mask_flags = MTD_WRITEABLE, /* force read-only */ - }, - { - .name = "U-Boot-NAND", - .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */ - .size = 10 * (64 * 2048), /* 1.25MB, 0x140000 */ - .mask_flags = MTD_WRITEABLE, /* force read-only */ - }, - { - .name = "Boot Env-NAND", - .offset = MTDPART_OFS_APPEND, /* Offset = 0x1c0000 */ - .size = 2 * (64 * 2048), /* 256KB, 0x40000 */ - }, - { - .name = "Kernel-NAND", - .offset = MTDPART_OFS_APPEND, /* Offset = 0x0200000*/ - .size = 240 * (64 * 2048), /* 30M, 0x1E00000 */ - }, - { - .name = "system", - .offset = MTDPART_OFS_APPEND, /* Offset = 0x2000000 */ - .size = 3328 * (64 * 2048), /* 416M, 0x1A000000 */ - }, - { - .name = "userdata", - .offset = MTDPART_OFS_APPEND, /* Offset = 0x1C000000*/ - .size = 256 * (64 * 2048), /* 32M, 0x2000000 */ - }, - { - .name = "cache", - .offset = MTDPART_OFS_APPEND, /* Offset = 0x1E000000*/ - .size = 256 * (64 * 2048), /* 32M, 0x2000000 */ - }, -}; - -static struct usbhs_phy_data phy_data[] __initdata = { - { - .port = 2, - .reset_gpio = ZOOM3_EHCI_RESET_GPIO, - .vcc_gpio = -EINVAL, - }, -}; - -static struct usbhs_omap_platform_data usbhs_bdata __initdata = { - .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, -}; - -static void __init omap_zoom_init(void) -{ - if (machine_is_omap_zoom2()) { - omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); - } else if (machine_is_omap_zoom3()) { - omap3_mux_init(board_mux, OMAP_PACKAGE_CBP); - omap_mux_init_gpio(ZOOM3_EHCI_RESET_GPIO, OMAP_PIN_OUTPUT); - - usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); - usbhs_init(&usbhs_bdata); - } - - board_nand_init(zoom_nand_partitions, - ARRAY_SIZE(zoom_nand_partitions), ZOOM_NAND_CS, - NAND_BUSWIDTH_16, nand_default_timings); - zoom_debugboard_init(); - zoom_peripherals_init(); - - if (machine_is_omap_zoom2()) - omap_sdrc_init(mt46h32m32lf6_sdrc_params, - mt46h32m32lf6_sdrc_params); - else if (machine_is_omap_zoom3()) - omap_sdrc_init(h8mbx00u0mer0em_sdrc_params, - h8mbx00u0mer0em_sdrc_params); - - zoom_display_init(); -} - -MACHINE_START(OMAP_ZOOM2, "OMAP Zoom2 board") - .atag_offset = 0x100, - .reserve = omap_reserve, - .map_io = omap3_map_io, - .init_early = omap3430_init_early, - .init_irq = omap3_init_irq, - .handle_irq = omap3_intc_handle_irq, - .init_machine = omap_zoom_init, - .init_late = omap3430_init_late, - .init_time = omap3_sync32k_timer_init, - .restart = omap3xxx_restart, -MACHINE_END - -MACHINE_START(OMAP_ZOOM3, "OMAP Zoom3 board") - .atag_offset = 0x100, - .reserve = omap_reserve, - .map_io = omap3_map_io, - .init_early = omap3630_init_early, - .init_irq = omap3_init_irq, - .handle_irq = omap3_intc_handle_irq, - .init_machine = omap_zoom_init, - .init_late = omap3630_init_late, - .init_time = omap3_sync32k_timer_init, - .restart = omap3xxx_restart, -MACHINE_END diff --git a/arch/arm/mach-omap2/board-zoom.h b/arch/arm/mach-omap2/board-zoom.h deleted file mode 100644 index 2e9486940ead..000000000000 --- a/arch/arm/mach-omap2/board-zoom.h +++ /dev/null @@ -1,10 +0,0 @@ -/* - * Defines for zoom boards - */ -#include <video/omapdss.h> - -#define ZOOM_NAND_CS 0 - -extern int __init zoom_debugboard_init(void); -extern void __init zoom_peripherals_init(void); -extern void __init zoom_display_init(void); diff --git a/arch/arm/mach-omap2/cclock3xxx_data.c b/arch/arm/mach-omap2/cclock3xxx_data.c index 334b76745900..3b05aea56d1f 100644 --- a/arch/arm/mach-omap2/cclock3xxx_data.c +++ b/arch/arm/mach-omap2/cclock3xxx_data.c @@ -381,6 +381,42 @@ static struct clk_hw_omap dpll4_ck_hw = { DEFINE_STRUCT_CLK(dpll4_ck, dpll3_ck_parent_names, dpll4_ck_ops); +static const struct clk_div_table dpll4_mx_ck_div_table[] = { + { .div = 1, .val = 1 }, + { .div = 2, .val = 2 }, + { .div = 3, .val = 3 }, + { .div = 4, .val = 4 }, + { .div = 5, .val = 5 }, + { .div = 6, .val = 6 }, + { .div = 7, .val = 7 }, + { .div = 8, .val = 8 }, + { .div = 9, .val = 9 }, + { .div = 10, .val = 10 }, + { .div = 11, .val = 11 }, + { .div = 12, .val = 12 }, + { .div = 13, .val = 13 }, + { .div = 14, .val = 14 }, + { .div = 15, .val = 15 }, + { .div = 16, .val = 16 }, + { .div = 17, .val = 17 }, + { .div = 18, .val = 18 }, + { .div = 19, .val = 19 }, + { .div = 20, .val = 20 }, + { .div = 21, .val = 21 }, + { .div = 22, .val = 22 }, + { .div = 23, .val = 23 }, + { .div = 24, .val = 24 }, + { .div = 25, .val = 25 }, + { .div = 26, .val = 26 }, + { .div = 27, .val = 27 }, + { .div = 28, .val = 28 }, + { .div = 29, .val = 29 }, + { .div = 30, .val = 30 }, + { .div = 31, .val = 31 }, + { .div = 32, .val = 32 }, + { .div = 0 }, +}; + DEFINE_CLK_DIVIDER(dpll4_m5_ck, "dpll4_ck", &dpll4_ck, 0x0, OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_CLKSEL), OMAP3430_CLKSEL_CAM_SHIFT, OMAP3630_CLKSEL_CAM_WIDTH, @@ -524,10 +560,10 @@ static const struct clksel_rate clkout2_src_54m_rates[] = { { .div = 0 } }; -DEFINE_CLK_DIVIDER(dpll4_m3_ck, "dpll4_ck", &dpll4_ck, 0x0, +DEFINE_CLK_DIVIDER_TABLE(dpll4_m3_ck, "dpll4_ck", &dpll4_ck, 0x0, OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_CLKSEL), OMAP3430_CLKSEL_TV_SHIFT, OMAP3630_CLKSEL_TV_WIDTH, - CLK_DIVIDER_ONE_BASED, NULL); + 0, dpll4_mx_ck_div_table, NULL); static struct clk dpll4_m3x2_ck; @@ -847,10 +883,10 @@ static struct clk dpll3_m3x2_ck_3630 = { DEFINE_CLK_FIXED_FACTOR(dpll3_x2_ck, "dpll3_ck", &dpll3_ck, 0x0, 2, 1); -DEFINE_CLK_DIVIDER(dpll4_m4_ck, "dpll4_ck", &dpll4_ck, 0x0, +DEFINE_CLK_DIVIDER_TABLE(dpll4_m4_ck, "dpll4_ck", &dpll4_ck, 0x0, OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_CLKSEL), OMAP3430_CLKSEL_DSS1_SHIFT, OMAP3630_CLKSEL_DSS1_WIDTH, - CLK_DIVIDER_ONE_BASED, NULL); + 0, dpll4_mx_ck_div_table, NULL); static struct clk dpll4_m4x2_ck; @@ -869,7 +905,8 @@ static struct clk_hw_omap dpll4_m4x2_ck_hw = { .clkdm_name = "dpll4_clkdm", }; -DEFINE_STRUCT_CLK(dpll4_m4x2_ck, dpll4_m4x2_ck_parent_names, dpll4_m5x2_ck_ops); +DEFINE_STRUCT_CLK_FLAGS(dpll4_m4x2_ck, dpll4_m4x2_ck_parent_names, + dpll4_m5x2_ck_ops, CLK_SET_RATE_PARENT); static struct clk dpll4_m4x2_ck_3630 = { .name = "dpll4_m4x2_ck", @@ -877,6 +914,7 @@ static struct clk dpll4_m4x2_ck_3630 = { .parent_names = dpll4_m4x2_ck_parent_names, .num_parents = ARRAY_SIZE(dpll4_m4x2_ck_parent_names), .ops = &dpll4_m5x2_ck_3630_ops, + .flags = CLK_SET_RATE_PARENT, }; DEFINE_CLK_DIVIDER(dpll4_m6_ck, "dpll4_ck", &dpll4_ck, 0x0, @@ -968,8 +1006,9 @@ static struct clk_hw_omap dss1_alwon_fck_3430es1_hw = { .clkdm_name = "dss_clkdm", }; -DEFINE_STRUCT_CLK(dss1_alwon_fck_3430es1, dss1_alwon_fck_3430es1_parent_names, - aes2_ick_ops); +DEFINE_STRUCT_CLK_FLAGS(dss1_alwon_fck_3430es1, + dss1_alwon_fck_3430es1_parent_names, aes2_ick_ops, + CLK_SET_RATE_PARENT); static struct clk dss1_alwon_fck_3430es2; @@ -983,8 +1022,9 @@ static struct clk_hw_omap dss1_alwon_fck_3430es2_hw = { .clkdm_name = "dss_clkdm", }; -DEFINE_STRUCT_CLK(dss1_alwon_fck_3430es2, dss1_alwon_fck_3430es1_parent_names, - aes2_ick_ops); +DEFINE_STRUCT_CLK_FLAGS(dss1_alwon_fck_3430es2, + dss1_alwon_fck_3430es1_parent_names, aes2_ick_ops, + CLK_SET_RATE_PARENT); static struct clk dss2_alwon_fck; @@ -3275,6 +3315,7 @@ static struct omap_clk omap36xx_clks[] = { static struct omap_clk omap34xx_omap36xx_clks[] = { CLK(NULL, "aes1_ick", &aes1_ick), CLK("omap_rng", "ick", &rng_ick), + CLK("omap3-rom-rng", "ick", &rng_ick), CLK(NULL, "sha11_ick", &sha11_ick), CLK(NULL, "des1_ick", &des1_ick), CLK(NULL, "cam_mclk", &cam_mclk), diff --git a/arch/arm/mach-omap2/cclock44xx_data.c b/arch/arm/mach-omap2/cclock44xx_data.c index b237950eb8a3..ec0dc0b1755e 100644 --- a/arch/arm/mach-omap2/cclock44xx_data.c +++ b/arch/arm/mach-omap2/cclock44xx_data.c @@ -830,7 +830,8 @@ DEFINE_CLK_GATE(dss_tv_clk, "extalt_clkin_ck", &extalt_clkin_ck, 0x0, OMAP4430_CM_DSS_DSS_CLKCTRL, OMAP4430_OPTFCLKEN_TV_CLK_SHIFT, 0x0, NULL); -DEFINE_CLK_GATE(dss_dss_clk, "dpll_per_m5x2_ck", &dpll_per_m5x2_ck, 0x0, +DEFINE_CLK_GATE(dss_dss_clk, "dpll_per_m5x2_ck", &dpll_per_m5x2_ck, + CLK_SET_RATE_PARENT, OMAP4430_CM_DSS_DSS_CLKCTRL, OMAP4430_OPTFCLKEN_DSSCLK_SHIFT, 0x0, NULL); diff --git a/arch/arm/mach-omap2/clkt2xxx_apll.c b/arch/arm/mach-omap2/clkt2xxx_apll.c index 25b1feed480d..c78e893eba7d 100644 --- a/arch/arm/mach-omap2/clkt2xxx_apll.c +++ b/arch/arm/mach-omap2/clkt2xxx_apll.c @@ -52,7 +52,7 @@ static bool omap2xxx_clk_apll_locked(struct clk_hw *hw) apll_mask = EN_APLL_LOCKED << clk->enable_bit; - r = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN); + r = omap2xxx_cm_get_pll_status(); return ((r & apll_mask) == apll_mask) ? true : false; } @@ -126,7 +126,7 @@ u32 omap2xxx_get_apll_clkin(void) { u32 aplls, srate = 0; - aplls = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL1); + aplls = omap2xxx_cm_get_pll_config(); aplls &= OMAP24XX_APLLS_CLKIN_MASK; aplls >>= OMAP24XX_APLLS_CLKIN_SHIFT; diff --git a/arch/arm/mach-omap2/clkt2xxx_dpllcore.c b/arch/arm/mach-omap2/clkt2xxx_dpllcore.c index d8620105c42a..3ff32543493c 100644 --- a/arch/arm/mach-omap2/clkt2xxx_dpllcore.c +++ b/arch/arm/mach-omap2/clkt2xxx_dpllcore.c @@ -60,8 +60,7 @@ unsigned long omap2xxx_clk_get_core_rate(void) core_clk = omap2_get_dpll_rate(dpll_core_ck); - v = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2); - v &= OMAP24XX_CORE_CLK_SRC_MASK; + v = omap2xxx_cm_get_core_clk_src(); if (v == CORE_CLK_SRC_32K) core_clk = 32768; @@ -79,8 +78,7 @@ static long omap2_dpllcore_round_rate(unsigned long target_rate) { u32 high, low, core_clk_src; - core_clk_src = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2); - core_clk_src &= OMAP24XX_CORE_CLK_SRC_MASK; + core_clk_src = omap2xxx_cm_get_core_clk_src(); if (core_clk_src == CORE_CLK_SRC_DPLL) { /* DPLL clockout */ high = curr_prcm_set->dpll_speed * 2; @@ -120,8 +118,7 @@ int omap2_reprogram_dpllcore(struct clk_hw *hw, unsigned long rate, const struct dpll_data *dd; cur_rate = omap2xxx_clk_get_core_rate(); - mult = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2); - mult &= OMAP24XX_CORE_CLK_SRC_MASK; + mult = omap2xxx_cm_get_core_clk_src(); if ((rate == (cur_rate / 2)) && (mult == 2)) { omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1); @@ -145,7 +142,7 @@ int omap2_reprogram_dpllcore(struct clk_hw *hw, unsigned long rate, tmpset.cm_clksel1_pll &= ~(dd->mult_mask | dd->div1_mask); div = ((curr_prcm_set->xtal_speed / 1000000) - 1); - tmpset.cm_clksel2_pll = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2); + tmpset.cm_clksel2_pll = omap2xxx_cm_get_core_pll_config(); tmpset.cm_clksel2_pll &= ~OMAP24XX_CORE_CLK_SRC_MASK; if (rate > low) { tmpset.cm_clksel2_pll |= CORE_CLK_SRC_DPLL_X2; diff --git a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c index ae2b35e76dc8..b935ed2922d8 100644 --- a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c +++ b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c @@ -98,7 +98,7 @@ long omap2_round_to_table_rate(struct clk_hw *hw, unsigned long rate, int omap2_select_table_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { - u32 cur_rate, done_rate, bypass = 0, tmp; + u32 cur_rate, done_rate, bypass = 0; const struct prcm_config *prcm; unsigned long found_speed = 0; unsigned long flags; @@ -141,23 +141,11 @@ int omap2_select_table_rate(struct clk_hw *hw, unsigned long rate, else done_rate = CORE_CLK_SRC_DPLL; - /* MPU divider */ - omap2_cm_write_mod_reg(prcm->cm_clksel_mpu, MPU_MOD, CM_CLKSEL); - - /* dsp + iva1 div(2420), iva2.1(2430) */ - omap2_cm_write_mod_reg(prcm->cm_clksel_dsp, - OMAP24XX_DSP_MOD, CM_CLKSEL); - - omap2_cm_write_mod_reg(prcm->cm_clksel_gfx, GFX_MOD, CM_CLKSEL); - - /* Major subsystem dividers */ - tmp = omap2_cm_read_mod_reg(CORE_MOD, CM_CLKSEL1) & OMAP24XX_CLKSEL_DSS2_MASK; - omap2_cm_write_mod_reg(prcm->cm_clksel1_core | tmp, CORE_MOD, - CM_CLKSEL1); - - if (cpu_is_omap2430()) - omap2_cm_write_mod_reg(prcm->cm_clksel_mdm, - OMAP2430_MDM_MOD, CM_CLKSEL); + omap2xxx_cm_set_mod_dividers(prcm->cm_clksel_mpu, + prcm->cm_clksel_dsp, + prcm->cm_clksel_gfx, + prcm->cm_clksel1_core, + prcm->cm_clksel_mdm); /* x2 to enter omap2xxx_sdrc_init_params() */ omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1); diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c index 0c38ca96c840..c7c5d31e9082 100644 --- a/arch/arm/mach-omap2/clock.c +++ b/arch/arm/mach-omap2/clock.c @@ -543,6 +543,44 @@ int omap2_clk_disable_autoidle_all(void) } /** + * omap2_clk_deny_idle - disable autoidle on an OMAP clock + * @clk: struct clk * to disable autoidle for + * + * Disable autoidle on an OMAP clock. + */ +int omap2_clk_deny_idle(struct clk *clk) +{ + struct clk_hw_omap *c; + + if (__clk_get_flags(clk) & CLK_IS_BASIC) + return -EINVAL; + + c = to_clk_hw_omap(__clk_get_hw(clk)); + if (c->ops && c->ops->deny_idle) + c->ops->deny_idle(c); + return 0; +} + +/** + * omap2_clk_allow_idle - enable autoidle on an OMAP clock + * @clk: struct clk * to enable autoidle for + * + * Enable autoidle on an OMAP clock. + */ +int omap2_clk_allow_idle(struct clk *clk) +{ + struct clk_hw_omap *c; + + if (__clk_get_flags(clk) & CLK_IS_BASIC) + return -EINVAL; + + c = to_clk_hw_omap(__clk_get_hw(clk)); + if (c->ops && c->ops->allow_idle) + c->ops->allow_idle(c); + return 0; +} + +/** * omap2_clk_enable_init_clocks - prepare & enable a list of clocks * @clk_names: ptr to an array of strings of clock names to enable * @num_clocks: number of clock names in @clk_names diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h index 7aa32cd292f9..82916cc82c92 100644 --- a/arch/arm/mach-omap2/clock.h +++ b/arch/arm/mach-omap2/clock.h @@ -411,6 +411,8 @@ void omap2_clk_dflt_find_idlest(struct clk_hw_omap *clk, void omap2_init_clk_hw_omap_clocks(struct clk *clk); int omap2_clk_enable_autoidle_all(void); int omap2_clk_disable_autoidle_all(void); +int omap2_clk_allow_idle(struct clk *clk); +int omap2_clk_deny_idle(struct clk *clk); void omap2_clk_enable_init_clocks(const char **clk_names, u8 num_clocks); int omap2_clk_switch_mpurate_at_boot(const char *mpurate_ck_name); void omap2_clk_print_new_rates(const char *hfclkin_ck_name, diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h index 4b03394fa0c5..f17f00697cc0 100644 --- a/arch/arm/mach-omap2/clockdomain.h +++ b/arch/arm/mach-omap2/clockdomain.h @@ -132,7 +132,7 @@ struct clockdomain { u8 _flags; const u8 dep_bit; const u8 prcm_partition; - const s16 cm_inst; + const u16 cm_inst; const u16 clkdm_offs; struct clkdm_dep *wkdep_srcs; struct clkdm_dep *sleepdep_srcs; @@ -218,6 +218,7 @@ extern void __init am33xx_clockdomains_init(void); extern void __init omap44xx_clockdomains_init(void); extern void __init omap54xx_clockdomains_init(void); extern void __init dra7xx_clockdomains_init(void); +void am43xx_clockdomains_init(void); extern void clkdm_add_autodeps(struct clockdomain *clkdm); extern void clkdm_del_autodeps(struct clockdomain *clkdm); @@ -226,6 +227,7 @@ extern struct clkdm_ops omap2_clkdm_operations; extern struct clkdm_ops omap3_clkdm_operations; extern struct clkdm_ops omap4_clkdm_operations; extern struct clkdm_ops am33xx_clkdm_operations; +extern struct clkdm_ops am43xx_clkdm_operations; extern struct clkdm_dep gfx_24xx_wkdeps[]; extern struct clkdm_dep dsp_24xx_wkdeps[]; diff --git a/arch/arm/mach-omap2/clockdomains43xx_data.c b/arch/arm/mach-omap2/clockdomains43xx_data.c new file mode 100644 index 000000000000..6d71c6082a24 --- /dev/null +++ b/arch/arm/mach-omap2/clockdomains43xx_data.c @@ -0,0 +1,196 @@ +/* + * AM43xx Clock domains framework + * + * Copyright (C) 2013 Texas Instruments, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/io.h> + +#include "clockdomain.h" +#include "prcm44xx.h" +#include "prcm43xx.h" + +static struct clockdomain l4_cefuse_43xx_clkdm = { + .name = "l4_cefuse_clkdm", + .pwrdm = { .name = "cefuse_pwrdm" }, + .prcm_partition = AM43XX_CM_PARTITION, + .cm_inst = AM43XX_CM_CEFUSE_INST, + .clkdm_offs = AM43XX_CM_CEFUSE_CEFUSE_CDOFFS, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain mpu_43xx_clkdm = { + .name = "mpu_clkdm", + .pwrdm = { .name = "mpu_pwrdm" }, + .prcm_partition = AM43XX_CM_PARTITION, + .cm_inst = AM43XX_CM_MPU_INST, + .clkdm_offs = AM43XX_CM_MPU_MPU_CDOFFS, + .flags = CLKDM_CAN_HWSUP_SWSUP, +}; + +static struct clockdomain l4ls_43xx_clkdm = { + .name = "l4ls_clkdm", + .pwrdm = { .name = "per_pwrdm" }, + .prcm_partition = AM43XX_CM_PARTITION, + .cm_inst = AM43XX_CM_PER_INST, + .clkdm_offs = AM43XX_CM_PER_L4LS_CDOFFS, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain tamper_43xx_clkdm = { + .name = "tamper_clkdm", + .pwrdm = { .name = "tamper_pwrdm" }, + .prcm_partition = AM43XX_CM_PARTITION, + .cm_inst = AM43XX_CM_TAMPER_INST, + .clkdm_offs = AM43XX_CM_TAMPER_TAMPER_CDOFFS, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain l4_rtc_43xx_clkdm = { + .name = "l4_rtc_clkdm", + .pwrdm = { .name = "rtc_pwrdm" }, + .prcm_partition = AM43XX_CM_PARTITION, + .cm_inst = AM43XX_CM_RTC_INST, + .clkdm_offs = AM43XX_CM_RTC_RTC_CDOFFS, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain pruss_ocp_43xx_clkdm = { + .name = "pruss_ocp_clkdm", + .pwrdm = { .name = "per_pwrdm" }, + .prcm_partition = AM43XX_CM_PARTITION, + .cm_inst = AM43XX_CM_PER_INST, + .clkdm_offs = AM43XX_CM_PER_ICSS_CDOFFS, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain ocpwp_l3_43xx_clkdm = { + .name = "ocpwp_l3_clkdm", + .pwrdm = { .name = "per_pwrdm" }, + .prcm_partition = AM43XX_CM_PARTITION, + .cm_inst = AM43XX_CM_PER_INST, + .clkdm_offs = AM43XX_CM_PER_OCPWP_L3_CDOFFS, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain l3s_tsc_43xx_clkdm = { + .name = "l3s_tsc_clkdm", + .pwrdm = { .name = "wkup_pwrdm" }, + .prcm_partition = AM43XX_CM_PARTITION, + .cm_inst = AM43XX_CM_WKUP_INST, + .clkdm_offs = AM43XX_CM_WKUP_L3S_TSC_CDOFFS, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain dss_43xx_clkdm = { + .name = "dss_clkdm", + .pwrdm = { .name = "per_pwrdm" }, + .prcm_partition = AM43XX_CM_PARTITION, + .cm_inst = AM43XX_CM_PER_INST, + .clkdm_offs = AM43XX_CM_PER_DSS_CDOFFS, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain l3_aon_43xx_clkdm = { + .name = "l3_aon_clkdm", + .pwrdm = { .name = "wkup_pwrdm" }, + .prcm_partition = AM43XX_CM_PARTITION, + .cm_inst = AM43XX_CM_WKUP_INST, + .clkdm_offs = AM43XX_CM_WKUP_L3_AON_CDOFFS, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain emif_43xx_clkdm = { + .name = "emif_clkdm", + .pwrdm = { .name = "per_pwrdm" }, + .prcm_partition = AM43XX_CM_PARTITION, + .cm_inst = AM43XX_CM_PER_INST, + .clkdm_offs = AM43XX_CM_PER_EMIF_CDOFFS, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain l4_wkup_aon_43xx_clkdm = { + .name = "l4_wkup_aon_clkdm", + .pwrdm = { .name = "wkup_pwrdm" }, + .prcm_partition = AM43XX_CM_PARTITION, + .cm_inst = AM43XX_CM_WKUP_INST, + .clkdm_offs = AM43XX_CM_WKUP_L4_WKUP_AON_CDOFFS, +}; + +static struct clockdomain l3_43xx_clkdm = { + .name = "l3_clkdm", + .pwrdm = { .name = "per_pwrdm" }, + .prcm_partition = AM43XX_CM_PARTITION, + .cm_inst = AM43XX_CM_PER_INST, + .clkdm_offs = AM43XX_CM_PER_L3_CDOFFS, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain l4_wkup_43xx_clkdm = { + .name = "l4_wkup_clkdm", + .pwrdm = { .name = "wkup_pwrdm" }, + .prcm_partition = AM43XX_CM_PARTITION, + .cm_inst = AM43XX_CM_WKUP_INST, + .clkdm_offs = AM43XX_CM_WKUP_WKUP_CDOFFS, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain cpsw_125mhz_43xx_clkdm = { + .name = "cpsw_125mhz_clkdm", + .pwrdm = { .name = "per_pwrdm" }, + .prcm_partition = AM43XX_CM_PARTITION, + .cm_inst = AM43XX_CM_PER_INST, + .clkdm_offs = AM43XX_CM_PER_CPSW_CDOFFS, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain gfx_l3_43xx_clkdm = { + .name = "gfx_l3_clkdm", + .pwrdm = { .name = "gfx_pwrdm" }, + .prcm_partition = AM43XX_CM_PARTITION, + .cm_inst = AM43XX_CM_GFX_INST, + .clkdm_offs = AM43XX_CM_GFX_GFX_L3_CDOFFS, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain l3s_43xx_clkdm = { + .name = "l3s_clkdm", + .pwrdm = { .name = "per_pwrdm" }, + .prcm_partition = AM43XX_CM_PARTITION, + .cm_inst = AM43XX_CM_PER_INST, + .clkdm_offs = AM43XX_CM_PER_L3S_CDOFFS, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain *clockdomains_am43xx[] __initdata = { + &l4_cefuse_43xx_clkdm, + &mpu_43xx_clkdm, + &l4ls_43xx_clkdm, + &tamper_43xx_clkdm, + &l4_rtc_43xx_clkdm, + &pruss_ocp_43xx_clkdm, + &ocpwp_l3_43xx_clkdm, + &l3s_tsc_43xx_clkdm, + &dss_43xx_clkdm, + &l3_aon_43xx_clkdm, + &emif_43xx_clkdm, + &l4_wkup_aon_43xx_clkdm, + &l3_43xx_clkdm, + &l4_wkup_43xx_clkdm, + &cpsw_125mhz_43xx_clkdm, + &gfx_l3_43xx_clkdm, + &l3s_43xx_clkdm, + NULL +}; + +void __init am43xx_clockdomains_init(void) +{ + clkdm_register_platform_funcs(&am43xx_clkdm_operations); + clkdm_register_clkdms(clockdomains_am43xx); + clkdm_complete_init(); +} diff --git a/arch/arm/mach-omap2/cm2xxx.c b/arch/arm/mach-omap2/cm2xxx.c index 6774a53a3874..ce25abbcffae 100644 --- a/arch/arm/mach-omap2/cm2xxx.c +++ b/arch/arm/mach-omap2/cm2xxx.c @@ -327,6 +327,73 @@ struct clkdm_ops omap2_clkdm_operations = { .clkdm_clk_disable = omap2xxx_clkdm_clk_disable, }; +int omap2xxx_cm_fclks_active(void) +{ + u32 f1, f2; + + f1 = omap2_cm_read_mod_reg(CORE_MOD, CM_FCLKEN1); + f2 = omap2_cm_read_mod_reg(CORE_MOD, OMAP24XX_CM_FCLKEN2); + + return (f1 | f2) ? 1 : 0; +} + +int omap2xxx_cm_mpu_retention_allowed(void) +{ + u32 l; + + /* Check for MMC, UART2, UART1, McSPI2, McSPI1 and DSS1. */ + l = omap2_cm_read_mod_reg(CORE_MOD, CM_FCLKEN1); + if (l & (OMAP2420_EN_MMC_MASK | OMAP24XX_EN_UART2_MASK | + OMAP24XX_EN_UART1_MASK | OMAP24XX_EN_MCSPI2_MASK | + OMAP24XX_EN_MCSPI1_MASK | OMAP24XX_EN_DSS1_MASK)) + return 0; + /* Check for UART3. */ + l = omap2_cm_read_mod_reg(CORE_MOD, OMAP24XX_CM_FCLKEN2); + if (l & OMAP24XX_EN_UART3_MASK) + return 0; + + return 1; +} + +u32 omap2xxx_cm_get_core_clk_src(void) +{ + u32 v; + + v = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2); + v &= OMAP24XX_CORE_CLK_SRC_MASK; + + return v; +} + +u32 omap2xxx_cm_get_core_pll_config(void) +{ + return omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2); +} + +u32 omap2xxx_cm_get_pll_config(void) +{ + return omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL1); +} + +u32 omap2xxx_cm_get_pll_status(void) +{ + return omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN); +} + +void omap2xxx_cm_set_mod_dividers(u32 mpu, u32 dsp, u32 gfx, u32 core, u32 mdm) +{ + u32 tmp; + + omap2_cm_write_mod_reg(mpu, MPU_MOD, CM_CLKSEL); + omap2_cm_write_mod_reg(dsp, OMAP24XX_DSP_MOD, CM_CLKSEL); + omap2_cm_write_mod_reg(gfx, GFX_MOD, CM_CLKSEL); + tmp = omap2_cm_read_mod_reg(CORE_MOD, CM_CLKSEL1) & + OMAP24XX_CLKSEL_DSS2_MASK; + omap2_cm_write_mod_reg(core | tmp, CORE_MOD, CM_CLKSEL1); + if (cpu_is_omap2430()) + omap2_cm_write_mod_reg(mdm, OMAP2430_MDM_MOD, CM_CLKSEL); +} + /* * */ diff --git a/arch/arm/mach-omap2/cm2xxx.h b/arch/arm/mach-omap2/cm2xxx.h index 4cbb39b051d2..891d81c3c8f4 100644 --- a/arch/arm/mach-omap2/cm2xxx.h +++ b/arch/arm/mach-omap2/cm2xxx.h @@ -62,6 +62,14 @@ extern int omap2xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift); extern int omap2xxx_cm_split_idlest_reg(void __iomem *idlest_reg, s16 *prcm_inst, u8 *idlest_reg_id); +extern int omap2xxx_cm_fclks_active(void); +extern int omap2xxx_cm_mpu_retention_allowed(void); +extern u32 omap2xxx_cm_get_core_clk_src(void); +extern u32 omap2xxx_cm_get_core_pll_config(void); +extern u32 omap2xxx_cm_get_pll_config(void); +extern u32 omap2xxx_cm_get_pll_status(void); +extern void omap2xxx_cm_set_mod_dividers(u32 mpu, u32 dsp, u32 gfx, u32 core, + u32 mdm); extern int __init omap2xxx_cm_init(void); diff --git a/arch/arm/mach-omap2/cm33xx.c b/arch/arm/mach-omap2/cm33xx.c index 325a51576576..40a22e5649ae 100644 --- a/arch/arm/mach-omap2/cm33xx.c +++ b/arch/arm/mach-omap2/cm33xx.c @@ -48,13 +48,13 @@ /* Private functions */ /* Read a register in a CM instance */ -static inline u32 am33xx_cm_read_reg(s16 inst, u16 idx) +static inline u32 am33xx_cm_read_reg(u16 inst, u16 idx) { return __raw_readl(cm_base + inst + idx); } /* Write into a register in a CM */ -static inline void am33xx_cm_write_reg(u32 val, s16 inst, u16 idx) +static inline void am33xx_cm_write_reg(u32 val, u16 inst, u16 idx) { __raw_writel(val, cm_base + inst + idx); } @@ -138,7 +138,7 @@ static bool _is_module_ready(u16 inst, s16 cdoffs, u16 clkctrl_offs) * @c must be the unshifted value for CLKTRCTRL - i.e., this function * will handle the shift itself. */ -static void _clktrctrl_write(u8 c, s16 inst, u16 cdoffs) +static void _clktrctrl_write(u8 c, u16 inst, u16 cdoffs) { u32 v; @@ -158,7 +158,7 @@ static void _clktrctrl_write(u8 c, s16 inst, u16 cdoffs) * Returns true if the clockdomain referred to by (@inst, @cdoffs) * is in hardware-supervised idle mode, or 0 otherwise. */ -bool am33xx_cm_is_clkdm_in_hwsup(s16 inst, u16 cdoffs) +bool am33xx_cm_is_clkdm_in_hwsup(u16 inst, u16 cdoffs) { u32 v; @@ -177,7 +177,7 @@ bool am33xx_cm_is_clkdm_in_hwsup(s16 inst, u16 cdoffs) * Put a clockdomain referred to by (@inst, @cdoffs) into * hardware-supervised idle mode. No return value. */ -void am33xx_cm_clkdm_enable_hwsup(s16 inst, u16 cdoffs) +void am33xx_cm_clkdm_enable_hwsup(u16 inst, u16 cdoffs) { _clktrctrl_write(OMAP34XX_CLKSTCTRL_ENABLE_AUTO, inst, cdoffs); } @@ -191,7 +191,7 @@ void am33xx_cm_clkdm_enable_hwsup(s16 inst, u16 cdoffs) * software-supervised idle mode, i.e., controlled manually by the * Linux OMAP clockdomain code. No return value. */ -void am33xx_cm_clkdm_disable_hwsup(s16 inst, u16 cdoffs) +void am33xx_cm_clkdm_disable_hwsup(u16 inst, u16 cdoffs) { _clktrctrl_write(OMAP34XX_CLKSTCTRL_DISABLE_AUTO, inst, cdoffs); } @@ -204,7 +204,7 @@ void am33xx_cm_clkdm_disable_hwsup(s16 inst, u16 cdoffs) * Put a clockdomain referred to by (@inst, @cdoffs) into idle * No return value. */ -void am33xx_cm_clkdm_force_sleep(s16 inst, u16 cdoffs) +void am33xx_cm_clkdm_force_sleep(u16 inst, u16 cdoffs) { _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_SLEEP, inst, cdoffs); } @@ -217,7 +217,7 @@ void am33xx_cm_clkdm_force_sleep(s16 inst, u16 cdoffs) * Take a clockdomain referred to by (@inst, @cdoffs) out of idle, * waking it up. No return value. */ -void am33xx_cm_clkdm_force_wakeup(s16 inst, u16 cdoffs) +void am33xx_cm_clkdm_force_wakeup(u16 inst, u16 cdoffs) { _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP, inst, cdoffs); } diff --git a/arch/arm/mach-omap2/cm33xx.h b/arch/arm/mach-omap2/cm33xx.h index 9d1f4fcdebbb..cfb8891b0c0e 100644 --- a/arch/arm/mach-omap2/cm33xx.h +++ b/arch/arm/mach-omap2/cm33xx.h @@ -377,13 +377,13 @@ #ifndef __ASSEMBLER__ -extern bool am33xx_cm_is_clkdm_in_hwsup(s16 inst, u16 cdoffs); -extern void am33xx_cm_clkdm_enable_hwsup(s16 inst, u16 cdoffs); -extern void am33xx_cm_clkdm_disable_hwsup(s16 inst, u16 cdoffs); -extern void am33xx_cm_clkdm_force_sleep(s16 inst, u16 cdoffs); -extern void am33xx_cm_clkdm_force_wakeup(s16 inst, u16 cdoffs); +bool am33xx_cm_is_clkdm_in_hwsup(u16 inst, u16 cdoffs); +void am33xx_cm_clkdm_enable_hwsup(u16 inst, u16 cdoffs); +void am33xx_cm_clkdm_disable_hwsup(u16 inst, u16 cdoffs); +void am33xx_cm_clkdm_force_sleep(u16 inst, u16 cdoffs); +void am33xx_cm_clkdm_force_wakeup(u16 inst, u16 cdoffs); -#if defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX) +#ifdef CONFIG_SOC_AM33XX extern int am33xx_cm_wait_module_idle(u16 inst, s16 cdoffs, u16 clkctrl_offs); extern void am33xx_cm_module_enable(u8 mode, u16 inst, s16 cdoffs, diff --git a/arch/arm/mach-omap2/cm3xxx.c b/arch/arm/mach-omap2/cm3xxx.c index 9061c307d915..f6f028867bfe 100644 --- a/arch/arm/mach-omap2/cm3xxx.c +++ b/arch/arm/mach-omap2/cm3xxx.c @@ -636,6 +636,28 @@ void omap3_cm_restore_context(void) OMAP3_CM_CLKOUT_CTRL_OFFSET); } +void omap3_cm_save_scratchpad_contents(u32 *ptr) +{ + *ptr++ = omap2_cm_read_mod_reg(CORE_MOD, CM_CLKSEL); + *ptr++ = omap2_cm_read_mod_reg(WKUP_MOD, CM_CLKSEL); + *ptr++ = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN); + + /* + * As per erratum i671, ROM code does not respect the PER DPLL + * programming scheme if CM_AUTOIDLE_PLL..AUTO_PERIPH_DPLL == 1. + * Then, in anycase, clear these bits to avoid extra latencies. + */ + *ptr++ = omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE) & + ~OMAP3430_AUTO_PERIPH_DPLL_MASK; + *ptr++ = omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL1_PLL); + *ptr++ = omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL2_PLL); + *ptr++ = omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL3); + *ptr++ = omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKEN_PLL); + *ptr++ = omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_AUTOIDLE_PLL); + *ptr++ = omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL); + *ptr++ = omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKSEL2_PLL); +} + /* * */ diff --git a/arch/arm/mach-omap2/cm3xxx.h b/arch/arm/mach-omap2/cm3xxx.h index e8e146f4a43f..8224c91b4d7a 100644 --- a/arch/arm/mach-omap2/cm3xxx.h +++ b/arch/arm/mach-omap2/cm3xxx.h @@ -83,6 +83,7 @@ extern int omap3xxx_cm_split_idlest_reg(void __iomem *idlest_reg, extern void omap3_cm_save_context(void); extern void omap3_cm_restore_context(void); +extern void omap3_cm_save_scratchpad_contents(u32 *ptr); extern int __init omap3xxx_cm_init(void); diff --git a/arch/arm/mach-omap2/cminst44xx.c b/arch/arm/mach-omap2/cminst44xx.c index f0290f5566fe..731ca134348c 100644 --- a/arch/arm/mach-omap2/cminst44xx.c +++ b/arch/arm/mach-omap2/cminst44xx.c @@ -111,7 +111,7 @@ static bool _is_module_ready(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs) /* Public functions */ /* Read a register in a CM instance */ -u32 omap4_cminst_read_inst_reg(u8 part, s16 inst, u16 idx) +u32 omap4_cminst_read_inst_reg(u8 part, u16 inst, u16 idx) { BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS || part == OMAP4430_INVALID_PRCM_PARTITION || @@ -120,7 +120,7 @@ u32 omap4_cminst_read_inst_reg(u8 part, s16 inst, u16 idx) } /* Write into a register in a CM instance */ -void omap4_cminst_write_inst_reg(u32 val, u8 part, s16 inst, u16 idx) +void omap4_cminst_write_inst_reg(u32 val, u8 part, u16 inst, u16 idx) { BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS || part == OMAP4430_INVALID_PRCM_PARTITION || @@ -129,7 +129,7 @@ void omap4_cminst_write_inst_reg(u32 val, u8 part, s16 inst, u16 idx) } /* Read-modify-write a register in CM1. Caller must lock */ -u32 omap4_cminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, s16 inst, +u32 omap4_cminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, u16 inst, s16 idx) { u32 v; @@ -142,12 +142,12 @@ u32 omap4_cminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, s16 inst, return v; } -u32 omap4_cminst_set_inst_reg_bits(u32 bits, u8 part, s16 inst, s16 idx) +u32 omap4_cminst_set_inst_reg_bits(u32 bits, u8 part, u16 inst, s16 idx) { return omap4_cminst_rmw_inst_reg_bits(bits, bits, part, inst, idx); } -u32 omap4_cminst_clear_inst_reg_bits(u32 bits, u8 part, s16 inst, s16 idx) +u32 omap4_cminst_clear_inst_reg_bits(u32 bits, u8 part, u16 inst, s16 idx) { return omap4_cminst_rmw_inst_reg_bits(bits, 0x0, part, inst, idx); } @@ -177,7 +177,7 @@ u32 omap4_cminst_read_inst_reg_bits(u8 part, u16 inst, s16 idx, u32 mask) * @c must be the unshifted value for CLKTRCTRL - i.e., this function * will handle the shift itself. */ -static void _clktrctrl_write(u8 c, u8 part, s16 inst, u16 cdoffs) +static void _clktrctrl_write(u8 c, u8 part, u16 inst, u16 cdoffs) { u32 v; @@ -196,7 +196,7 @@ static void _clktrctrl_write(u8 c, u8 part, s16 inst, u16 cdoffs) * Returns true if the clockdomain referred to by (@part, @inst, @cdoffs) * is in hardware-supervised idle mode, or 0 otherwise. */ -bool omap4_cminst_is_clkdm_in_hwsup(u8 part, s16 inst, u16 cdoffs) +bool omap4_cminst_is_clkdm_in_hwsup(u8 part, u16 inst, u16 cdoffs) { u32 v; @@ -216,7 +216,7 @@ bool omap4_cminst_is_clkdm_in_hwsup(u8 part, s16 inst, u16 cdoffs) * Put a clockdomain referred to by (@part, @inst, @cdoffs) into * hardware-supervised idle mode. No return value. */ -void omap4_cminst_clkdm_enable_hwsup(u8 part, s16 inst, u16 cdoffs) +void omap4_cminst_clkdm_enable_hwsup(u8 part, u16 inst, u16 cdoffs) { _clktrctrl_write(OMAP34XX_CLKSTCTRL_ENABLE_AUTO, part, inst, cdoffs); } @@ -231,7 +231,7 @@ void omap4_cminst_clkdm_enable_hwsup(u8 part, s16 inst, u16 cdoffs) * software-supervised idle mode, i.e., controlled manually by the * Linux OMAP clockdomain code. No return value. */ -void omap4_cminst_clkdm_disable_hwsup(u8 part, s16 inst, u16 cdoffs) +void omap4_cminst_clkdm_disable_hwsup(u8 part, u16 inst, u16 cdoffs) { _clktrctrl_write(OMAP34XX_CLKSTCTRL_DISABLE_AUTO, part, inst, cdoffs); } @@ -245,7 +245,7 @@ void omap4_cminst_clkdm_disable_hwsup(u8 part, s16 inst, u16 cdoffs) * Take a clockdomain referred to by (@part, @inst, @cdoffs) out of idle, * waking it up. No return value. */ -void omap4_cminst_clkdm_force_wakeup(u8 part, s16 inst, u16 cdoffs) +void omap4_cminst_clkdm_force_wakeup(u8 part, u16 inst, u16 cdoffs) { _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP, part, inst, cdoffs); } @@ -483,3 +483,12 @@ struct clkdm_ops omap4_clkdm_operations = { .clkdm_clk_enable = omap4_clkdm_clk_enable, .clkdm_clk_disable = omap4_clkdm_clk_disable, }; + +struct clkdm_ops am43xx_clkdm_operations = { + .clkdm_sleep = omap4_clkdm_sleep, + .clkdm_wakeup = omap4_clkdm_wakeup, + .clkdm_allow_idle = omap4_clkdm_allow_idle, + .clkdm_deny_idle = omap4_clkdm_deny_idle, + .clkdm_clk_enable = omap4_clkdm_clk_enable, + .clkdm_clk_disable = omap4_clkdm_clk_disable, +}; diff --git a/arch/arm/mach-omap2/cminst44xx.h b/arch/arm/mach-omap2/cminst44xx.h index bd7bab889745..7f56ea444bc4 100644 --- a/arch/arm/mach-omap2/cminst44xx.h +++ b/arch/arm/mach-omap2/cminst44xx.h @@ -11,11 +11,11 @@ #ifndef __ARCH_ASM_MACH_OMAP2_CMINST44XX_H #define __ARCH_ASM_MACH_OMAP2_CMINST44XX_H -extern bool omap4_cminst_is_clkdm_in_hwsup(u8 part, s16 inst, u16 cdoffs); -extern void omap4_cminst_clkdm_enable_hwsup(u8 part, s16 inst, u16 cdoffs); -extern void omap4_cminst_clkdm_disable_hwsup(u8 part, s16 inst, u16 cdoffs); -extern void omap4_cminst_clkdm_force_sleep(u8 part, s16 inst, u16 cdoffs); -extern void omap4_cminst_clkdm_force_wakeup(u8 part, s16 inst, u16 cdoffs); +bool omap4_cminst_is_clkdm_in_hwsup(u8 part, u16 inst, u16 cdoffs); +void omap4_cminst_clkdm_enable_hwsup(u8 part, u16 inst, u16 cdoffs); +void omap4_cminst_clkdm_disable_hwsup(u8 part, u16 inst, u16 cdoffs); +void omap4_cminst_clkdm_force_sleep(u8 part, u16 inst, u16 cdoffs); +void omap4_cminst_clkdm_force_wakeup(u8 part, u16 inst, u16 cdoffs); extern int omap4_cminst_wait_module_ready(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs); extern int omap4_cminst_wait_module_idle(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs); @@ -27,14 +27,14 @@ extern void omap4_cminst_module_disable(u8 part, u16 inst, s16 cdoffs, * In an ideal world, we would not export these low-level functions, * but this will probably take some time to fix properly */ -extern u32 omap4_cminst_read_inst_reg(u8 part, s16 inst, u16 idx); -extern void omap4_cminst_write_inst_reg(u32 val, u8 part, s16 inst, u16 idx); -extern u32 omap4_cminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, - s16 inst, s16 idx); -extern u32 omap4_cminst_set_inst_reg_bits(u32 bits, u8 part, s16 inst, - s16 idx); -extern u32 omap4_cminst_clear_inst_reg_bits(u32 bits, u8 part, s16 inst, - s16 idx); +u32 omap4_cminst_read_inst_reg(u8 part, u16 inst, u16 idx); +void omap4_cminst_write_inst_reg(u32 val, u8 part, u16 inst, u16 idx); +u32 omap4_cminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, + u16 inst, s16 idx); +u32 omap4_cminst_set_inst_reg_bits(u32 bits, u8 part, u16 inst, + s16 idx); +u32 omap4_cminst_clear_inst_reg_bits(u32 bits, u8 part, u16 inst, + s16 idx); extern u32 omap4_cminst_read_inst_reg_bits(u8 part, u16 inst, s16 idx, u32 mask); diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index 4a5684b96492..f7644febee81 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -98,6 +98,7 @@ void am35xx_init_early(void); void ti81xx_init_early(void); void am33xx_init_early(void); void am43xx_init_early(void); +void am43xx_init_late(void); void omap4430_init_early(void); void omap5_init_early(void); void omap3_init_late(void); /* Do not use this one */ @@ -109,8 +110,11 @@ void omap35xx_init_late(void); void omap3630_init_late(void); void am35xx_init_late(void); void ti81xx_init_late(void); +void am33xx_init_late(void); +void omap5_init_late(void); int omap2_common_pm_late_init(void); void dra7xx_init_early(void); +void dra7xx_init_late(void); #ifdef CONFIG_SOC_BUS void omap_soc_device_init(void); @@ -288,6 +292,9 @@ static inline void omap4_cpu_resume(void) #endif +void pdata_quirks_init(struct of_device_id *); +void omap_pcs_legacy_init(int irq, void (*rearm)(void)); + struct omap_sdrc_params; extern void omap_sdrc_init(struct omap_sdrc_params *sdrc_cs0, struct omap_sdrc_params *sdrc_cs1); diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c index 31e0dfe4a4ea..44bb4d544dcf 100644 --- a/arch/arm/mach-omap2/control.c +++ b/arch/arm/mach-omap2/control.c @@ -46,17 +46,7 @@ struct omap3_scratchpad { struct omap3_scratchpad_prcm_block { u32 prm_clksrc_ctrl; u32 prm_clksel; - u32 cm_clksel_core; - u32 cm_clksel_wkup; - u32 cm_clken_pll; - u32 cm_autoidle_pll; - u32 cm_clksel1_pll; - u32 cm_clksel2_pll; - u32 cm_clksel3_pll; - u32 cm_clken_pll_mpu; - u32 cm_autoidle_pll_mpu; - u32 cm_clksel1_pll_mpu; - u32 cm_clksel2_pll_mpu; + u32 cm_contents[11]; u32 prcm_block_size; }; @@ -347,34 +337,9 @@ void omap3_save_scratchpad_contents(void) prcm_block_contents.prm_clksel = omap2_prm_read_mod_reg(OMAP3430_CCR_MOD, OMAP3_PRM_CLKSEL_OFFSET); - prcm_block_contents.cm_clksel_core = - omap2_cm_read_mod_reg(CORE_MOD, CM_CLKSEL); - prcm_block_contents.cm_clksel_wkup = - omap2_cm_read_mod_reg(WKUP_MOD, CM_CLKSEL); - prcm_block_contents.cm_clken_pll = - omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN); - /* - * As per erratum i671, ROM code does not respect the PER DPLL - * programming scheme if CM_AUTOIDLE_PLL..AUTO_PERIPH_DPLL == 1. - * Then, in anycase, clear these bits to avoid extra latencies. - */ - prcm_block_contents.cm_autoidle_pll = - omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE) & - ~OMAP3430_AUTO_PERIPH_DPLL_MASK; - prcm_block_contents.cm_clksel1_pll = - omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL1_PLL); - prcm_block_contents.cm_clksel2_pll = - omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL2_PLL); - prcm_block_contents.cm_clksel3_pll = - omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL3); - prcm_block_contents.cm_clken_pll_mpu = - omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKEN_PLL); - prcm_block_contents.cm_autoidle_pll_mpu = - omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_AUTOIDLE_PLL); - prcm_block_contents.cm_clksel1_pll_mpu = - omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL); - prcm_block_contents.cm_clksel2_pll_mpu = - omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKSEL2_PLL); + + omap3_cm_save_scratchpad_contents(prcm_block_contents.cm_contents); + prcm_block_contents.prcm_block_size = 0x0; /* Populate the SDRC block contents */ @@ -604,4 +569,15 @@ int omap3_ctrl_save_padconf(void) return 0; } +/** + * omap3_ctrl_set_iva_bootmode_idle - sets the IVA2 bootmode to idle + * + * Sets the bootmode for IVA2 to idle. This is needed by the PM code to + * force disable IVA2 so that it does not prevent any low-power states. + */ +void omap3_ctrl_set_iva_bootmode_idle(void) +{ + omap_ctrl_writel(OMAP3_IVA2_BOOTMOD_IDLE, + OMAP343X_CONTROL_IVA2_BOOTMOD); +} #endif /* CONFIG_ARCH_OMAP3 && CONFIG_PM */ diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h index f7d7c2ef1b40..da054801b114 100644 --- a/arch/arm/mach-omap2/control.h +++ b/arch/arm/mach-omap2/control.h @@ -427,6 +427,7 @@ extern void omap_ctrl_write_dsp_boot_addr(u32 bootaddr); extern void omap_ctrl_write_dsp_boot_mode(u8 bootmode); extern void omap3630_ctrl_disable_rta(void); extern int omap3_ctrl_save_padconf(void); +extern void omap3_ctrl_set_iva_bootmode_idle(void); extern void omap2_set_globals_control(void __iomem *ctrl, void __iomem *ctrl_pad); #else diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 5c5315ba129b..0dd6398bade4 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -19,7 +19,6 @@ #include <linux/of.h> #include <linux/pinctrl/machine.h> #include <linux/platform_data/omap4-keypad.h> -#include <linux/wl12xx.h> #include <linux/platform_data/mailbox-omap.h> #include <asm/mach-types.h> @@ -37,6 +36,7 @@ #include "mux.h" #include "control.h" #include "devices.h" +#include "display.h" #define L3_MODULES_MAX_LEN 12 #define L3_MODULES 3 @@ -466,47 +466,13 @@ static struct platform_device omap_vout_device = { .resource = &omap_vout_resource[0], .id = -1, }; -static void omap_init_vout(void) -{ - if (platform_device_register(&omap_vout_device) < 0) - printk(KERN_ERR "Unable to register OMAP-VOUT device\n"); -} -#else -static inline void omap_init_vout(void) {} -#endif - -#if IS_ENABLED(CONFIG_WL12XX) -static struct wl12xx_platform_data wl12xx __initdata; - -void __init omap_init_wl12xx_of(void) +int __init omap_init_vout(void) { - int ret; - - if (!of_have_populated_dt()) - return; - - if (of_machine_is_compatible("ti,omap4-sdp")) { - wl12xx.board_ref_clock = WL12XX_REFCLOCK_26; - wl12xx.board_tcxo_clock = WL12XX_TCXOCLOCK_26; - wl12xx.irq = gpio_to_irq(53); - } else if (of_machine_is_compatible("ti,omap4-panda")) { - wl12xx.board_ref_clock = WL12XX_REFCLOCK_38; - wl12xx.irq = gpio_to_irq(53); - } else { - return; - } - - ret = wl12xx_set_platform_data(&wl12xx); - if (ret) { - pr_err("error setting wl12xx data: %d\n", ret); - return; - } + return platform_device_register(&omap_vout_device); } #else -static inline void omap_init_wl12xx_of(void) -{ -} +int __init omap_init_vout(void) { return 0; } #endif /*-------------------------------------------------------------------------*/ @@ -531,12 +497,8 @@ static int __init omap2_init_devices(void) omap_init_sham(); omap_init_aes(); omap_init_rng(); - } else { - /* These can be removed when bindings are done */ - omap_init_wl12xx_of(); } omap_init_sti(); - omap_init_vout(); return 0; } diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c index 03a0516c7f67..a4e536b11ec9 100644 --- a/arch/arm/mach-omap2/display.c +++ b/arch/arm/mach-omap2/display.c @@ -416,6 +416,34 @@ int __init omap_display_init(struct omap_dss_board_info *board_data) } } + /* create DRM device */ + r = omap_init_drm(); + if (r < 0) { + pr_err("Unable to register omapdrm device\n"); + return r; + } + + /* create vrfb device */ + r = omap_init_vrfb(); + if (r < 0) { + pr_err("Unable to register omapvrfb device\n"); + return r; + } + + /* create FB device */ + r = omap_init_fb(); + if (r < 0) { + pr_err("Unable to register omapfb device\n"); + return r; + } + + /* create V4L2 display device */ + r = omap_init_vout(); + if (r < 0) { + pr_err("Unable to register omap_vout device\n"); + return r; + } + return 0; } diff --git a/arch/arm/mach-omap2/display.h b/arch/arm/mach-omap2/display.h index b871b017b352..f3d2ce4bc262 100644 --- a/arch/arm/mach-omap2/display.h +++ b/arch/arm/mach-omap2/display.h @@ -26,4 +26,8 @@ struct omap_dss_dispc_dev_attr { bool has_framedonetv_irq; }; +int omap_init_drm(void); +int omap_init_vrfb(void); +int omap_init_fb(void); +int omap_init_vout(void); #endif diff --git a/arch/arm/mach-omap2/drm.c b/arch/arm/mach-omap2/drm.c index 59a4af779f42..facd7406a03d 100644 --- a/arch/arm/mach-omap2/drm.c +++ b/arch/arm/mach-omap2/drm.c @@ -26,10 +26,9 @@ #include <linux/platform_data/omap_drm.h> #include "soc.h" -#include "omap_device.h" -#include "omap_hwmod.h" +#include "display.h" -#if defined(CONFIG_DRM_OMAP) || (CONFIG_DRM_OMAP_MODULE) +#if defined(CONFIG_DRM_OMAP) || defined(CONFIG_DRM_OMAP_MODULE) static struct omap_drm_platform_data platform_data; @@ -42,26 +41,13 @@ static struct platform_device omap_drm_device = { .id = 0, }; -static int __init omap_init_drm(void) +int __init omap_init_drm(void) { - struct omap_hwmod *oh = NULL; - struct platform_device *pdev; - - /* lookup and populate the DMM information, if present - OMAP4+ */ - oh = omap_hwmod_lookup("dmm"); - - if (oh) { - pdev = omap_device_build(oh->name, -1, oh, NULL, 0); - WARN(IS_ERR(pdev), "Could not build omap_device for %s\n", - oh->name); - } - platform_data.omaprev = GET_OMAP_TYPE; return platform_device_register(&omap_drm_device); } - -omap_arch_initcall(omap_init_drm); - +#else +int __init omap_init_drm(void) { return 0; } #endif diff --git a/arch/arm/mach-omap2/dss-common.c b/arch/arm/mach-omap2/dss-common.c index bf89effa4c99..365bfd3d9c68 100644 --- a/arch/arm/mach-omap2/dss-common.c +++ b/arch/arm/mach-omap2/dss-common.c @@ -213,3 +213,47 @@ void __init omap_4430sdp_display_init_of(void) platform_device_register(&sdp4430_tpd_device); platform_device_register(&sdp4430_hdmi_connector_device); } + + +/* OMAP3 IGEPv2 data */ + +#define IGEP2_DVI_TFP410_POWER_DOWN_GPIO 170 + +/* DVI Connector */ +static struct connector_dvi_platform_data omap3_igep2_dvi_connector_pdata = { + .name = "dvi", + .source = "tfp410.0", + .i2c_bus_num = 3, +}; + +static struct platform_device omap3_igep2_dvi_connector_device = { + .name = "connector-dvi", + .id = 0, + .dev.platform_data = &omap3_igep2_dvi_connector_pdata, +}; + +/* TFP410 DPI-to-DVI chip */ +static struct encoder_tfp410_platform_data omap3_igep2_tfp410_pdata = { + .name = "tfp410.0", + .source = "dpi.0", + .data_lines = 24, + .power_down_gpio = IGEP2_DVI_TFP410_POWER_DOWN_GPIO, +}; + +static struct platform_device omap3_igep2_tfp410_device = { + .name = "tfp410", + .id = 0, + .dev.platform_data = &omap3_igep2_tfp410_pdata, +}; + +static struct omap_dss_board_info igep2_dss_data = { + .default_display_name = "dvi", +}; + +void __init omap3_igep2_display_init_of(void) +{ + omap_display_init(&igep2_dss_data); + + platform_device_register(&omap3_igep2_tfp410_device); + platform_device_register(&omap3_igep2_dvi_connector_device); +} diff --git a/arch/arm/mach-omap2/dss-common.h b/arch/arm/mach-omap2/dss-common.h index c28fe3c03588..a9becf0d5be8 100644 --- a/arch/arm/mach-omap2/dss-common.h +++ b/arch/arm/mach-omap2/dss-common.h @@ -8,5 +8,6 @@ void __init omap4_panda_display_init_of(void); void __init omap_4430sdp_display_init_of(void); +void __init omap3_igep2_display_init_of(void); #endif diff --git a/arch/arm/mach-omap2/fb.c b/arch/arm/mach-omap2/fb.c index 2ca33cc0c484..26e28e94f625 100644 --- a/arch/arm/mach-omap2/fb.c +++ b/arch/arm/mach-omap2/fb.c @@ -32,6 +32,7 @@ #include <asm/mach/map.h> #include "soc.h" +#include "display.h" #ifdef CONFIG_OMAP2_VRFB @@ -64,7 +65,7 @@ static const struct resource omap3_vrfb_resources[] = { DEFINE_RES_MEM_NAMED(0xfc000000u, 0x4000000, "vrfb-area-11"), }; -static int __init omap_init_vrfb(void) +int __init omap_init_vrfb(void) { struct platform_device *pdev; const struct resource *res; @@ -85,8 +86,8 @@ static int __init omap_init_vrfb(void) return PTR_RET(pdev); } - -omap_arch_initcall(omap_init_vrfb); +#else +int __init omap_init_vrfb(void) { return 0; } #endif #if defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE) @@ -105,11 +106,10 @@ static struct platform_device omap_fb_device = { .num_resources = 0, }; -static int __init omap_init_fb(void) +int __init omap_init_fb(void) { return platform_device_register(&omap_fb_device); } - -omap_arch_initcall(omap_init_fb); - +#else +int __init omap_init_fb(void) { return 0; } #endif diff --git a/arch/arm/mach-omap2/gpmc-smsc911x.c b/arch/arm/mach-omap2/gpmc-smsc911x.c index ef990118d32b..2757504a13c4 100644 --- a/arch/arm/mach-omap2/gpmc-smsc911x.c +++ b/arch/arm/mach-omap2/gpmc-smsc911x.c @@ -83,7 +83,7 @@ void __init gpmc_smsc911x_init(struct omap_smsc911x_platform_data *gpmc_cfg) pdev = platform_device_register_resndata(NULL, "smsc911x", gpmc_cfg->id, gpmc_smsc911x_resources, ARRAY_SIZE(gpmc_smsc911x_resources), &gpmc_smsc911x_config, sizeof(gpmc_smsc911x_config)); - if (!pdev) { + if (IS_ERR(pdev)) { pr_err("Unable to register platform device\n"); gpio_free(gpmc_cfg->gpio_reset); goto free2; diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 579697adaae7..81de56251955 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -1341,14 +1341,6 @@ static void __maybe_unused gpmc_read_timings_dt(struct device_node *np, #ifdef CONFIG_MTD_NAND -static const char * const nand_ecc_opts[] = { - [OMAP_ECC_HAMMING_CODE_DEFAULT] = "sw", - [OMAP_ECC_HAMMING_CODE_HW] = "hw", - [OMAP_ECC_HAMMING_CODE_HW_ROMCODE] = "hw-romcode", - [OMAP_ECC_BCH4_CODE_HW] = "bch4", - [OMAP_ECC_BCH8_CODE_HW] = "bch8", -}; - static const char * const nand_xfer_types[] = { [NAND_OMAP_PREFETCH_POLLED] = "prefetch-polled", [NAND_OMAP_POLLED] = "polled", @@ -1378,13 +1370,41 @@ static int gpmc_probe_nand_child(struct platform_device *pdev, gpmc_nand_data->cs = val; gpmc_nand_data->of_node = child; - if (!of_property_read_string(child, "ti,nand-ecc-opt", &s)) - for (val = 0; val < ARRAY_SIZE(nand_ecc_opts); val++) - if (!strcasecmp(s, nand_ecc_opts[val])) { - gpmc_nand_data->ecc_opt = val; - break; - } + /* Detect availability of ELM module */ + gpmc_nand_data->elm_of_node = of_parse_phandle(child, "ti,elm-id", 0); + if (gpmc_nand_data->elm_of_node == NULL) + gpmc_nand_data->elm_of_node = + of_parse_phandle(child, "elm_id", 0); + if (gpmc_nand_data->elm_of_node == NULL) + pr_warn("%s: ti,elm-id property not found\n", __func__); + + /* select ecc-scheme for NAND */ + if (of_property_read_string(child, "ti,nand-ecc-opt", &s)) { + pr_err("%s: ti,nand-ecc-opt not found\n", __func__); + return -ENODEV; + } + if (!strcmp(s, "ham1") || !strcmp(s, "sw") || + !strcmp(s, "hw") || !strcmp(s, "hw-romcode")) + gpmc_nand_data->ecc_opt = + OMAP_ECC_HAM1_CODE_HW; + else if (!strcmp(s, "bch4")) + if (gpmc_nand_data->elm_of_node) + gpmc_nand_data->ecc_opt = + OMAP_ECC_BCH4_CODE_HW; + else + gpmc_nand_data->ecc_opt = + OMAP_ECC_BCH4_CODE_HW_DETECTION_SW; + else if (!strcmp(s, "bch8")) + if (gpmc_nand_data->elm_of_node) + gpmc_nand_data->ecc_opt = + OMAP_ECC_BCH8_CODE_HW; + else + gpmc_nand_data->ecc_opt = + OMAP_ECC_BCH8_CODE_HW_DETECTION_SW; + else + pr_err("%s: ti,nand-ecc-opt invalid value\n", __func__); + /* select data transfer mode for NAND controller */ if (!of_property_read_string(child, "ti,nand-xfer-type", &s)) for (val = 0; val < ARRAY_SIZE(nand_xfer_types); val++) if (!strcasecmp(s, nand_xfer_types[val])) { @@ -1521,6 +1541,42 @@ err: return ret; } +/* + * REVISIT: Add timing support from slls644g.pdf + */ +static int gpmc_probe_8250(struct platform_device *pdev, + struct device_node *child) +{ + struct resource res; + unsigned long base; + int ret, cs; + + if (of_property_read_u32(child, "reg", &cs) < 0) { + dev_err(&pdev->dev, "%s has no 'reg' property\n", + child->full_name); + return -ENODEV; + } + + if (of_address_to_resource(child, 0, &res) < 0) { + dev_err(&pdev->dev, "%s has malformed 'reg' property\n", + child->full_name); + return -ENODEV; + } + + ret = gpmc_cs_request(cs, resource_size(&res), &base); + if (ret < 0) { + dev_err(&pdev->dev, "cannot request GPMC CS %d\n", cs); + return ret; + } + + if (of_platform_device_create(child, NULL, &pdev->dev)) + return 0; + + dev_err(&pdev->dev, "failed to create gpmc child %s\n", child->name); + + return -ENODEV; +} + static int gpmc_probe_dt(struct platform_device *pdev) { int ret; @@ -1564,6 +1620,8 @@ static int gpmc_probe_dt(struct platform_device *pdev) else if (of_node_cmp(child->name, "ethernet") == 0 || of_node_cmp(child->name, "nor") == 0) ret = gpmc_probe_generic_child(pdev, child); + else if (of_node_cmp(child->name, "8250") == 0) + ret = gpmc_probe_8250(pdev, child); if (WARN(ret < 0, "%s: probing gpmc child %s failed\n", __func__, child->full_name)) diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index 0289adcb6efb..9428c5f9d4f2 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -18,6 +18,7 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/io.h> +#include <linux/random.h> #include <linux/slab.h> #ifdef CONFIG_SOC_BUS @@ -130,6 +131,17 @@ void omap_get_die_id(struct omap_die_id *odi) odi->id_3 = read_tap_reg(OMAP_TAP_DIE_ID_3); } +static int __init omap_feed_randpool(void) +{ + struct omap_die_id odi; + + /* Throw the die ID into the entropy pool at boot */ + omap_get_die_id(&odi); + add_device_randomness(&odi, sizeof(odi)); + return 0; +} +omap_device_initcall(omap_feed_randpool); + void __init omap2xxx_check_revision(void) { int i, j; @@ -576,8 +588,8 @@ void __init omap5xxx_check_revision(void) case 0xb942: switch (rev) { case 0: - omap_revision = OMAP5430_REV_ES1_0; - break; + /* No support for ES1.0 Test chip */ + BUG(); case 1: default: omap_revision = OMAP5430_REV_ES2_0; @@ -587,8 +599,8 @@ void __init omap5xxx_check_revision(void) case 0xb998: switch (rev) { case 0: - omap_revision = OMAP5432_REV_ES1_0; - break; + /* No support for ES1.0 Test chip */ + BUG(); case 1: default: omap_revision = OMAP5432_REV_ES2_0; diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index ff2113ce4014..cd22262a2cc0 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -583,6 +583,11 @@ void __init am33xx_init_early(void) omap_hwmod_init_postsetup(); omap_clk_init = am33xx_clk_init; } + +void __init am33xx_init_late(void) +{ + omap_common_late_init(); +} #endif #ifdef CONFIG_SOC_AM43XX @@ -594,7 +599,18 @@ void __init am43xx_init_early(void) NULL); omap2_set_globals_prm(AM33XX_L4_WK_IO_ADDRESS(AM43XX_PRCM_BASE)); omap2_set_globals_cm(AM33XX_L4_WK_IO_ADDRESS(AM43XX_PRCM_BASE), NULL); + omap_prm_base_init(); + omap_cm_base_init(); omap3xxx_check_revision(); + am43xx_powerdomains_init(); + am43xx_clockdomains_init(); + am43xx_hwmod_init(); + omap_hwmod_init_postsetup(); +} + +void __init am43xx_init_late(void) +{ + omap_common_late_init(); } #endif @@ -651,6 +667,11 @@ void __init omap5_init_early(void) omap54xx_hwmod_init(); omap_hwmod_init_postsetup(); } + +void __init omap5_init_late(void) +{ + omap_common_late_init(); +} #endif #ifdef CONFIG_SOC_DRA7XX @@ -671,6 +692,11 @@ void __init dra7xx_init_early(void) dra7xx_hwmod_init(); omap_hwmod_init_postsetup(); } + +void __init dra7xx_init_late(void) +{ + omap_common_late_init(); +} #endif diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c index 3926f370448f..e022a869bff2 100644 --- a/arch/arm/mach-omap2/irq.c +++ b/arch/arm/mach-omap2/irq.c @@ -233,7 +233,7 @@ static inline void omap_intc_handle_irq(void __iomem *base_addr, struct pt_regs goto out; irqnr = readl_relaxed(base_addr + 0xd8); -#ifdef CONFIG_SOC_TI81XX +#if IS_ENABLED(CONFIG_SOC_TI81XX) || IS_ENABLED(CONFIG_SOC_AM33XX) if (irqnr) goto out; irqnr = readl_relaxed(base_addr + 0xf8); diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c index 5d8768075dd9..b4ac3af1160c 100644 --- a/arch/arm/mach-omap2/mcbsp.c +++ b/arch/arm/mach-omap2/mcbsp.c @@ -25,6 +25,7 @@ #include "soc.h" #include "omap_device.h" +#include "clock.h" /* * FIXME: Find a mechanism to enable/disable runtime the McBSP ICLK autoidle. @@ -33,22 +34,18 @@ #include "cm3xxx.h" #include "cm-regbits-34xx.h" +static struct clk *mcbsp_iclks[5]; + static int omap3_enable_st_clock(unsigned int id, bool enable) { - unsigned int w; - /* * Sidetone uses McBSP ICLK - which must not idle when sidetones * are enabled or sidetones start sounding ugly. */ - w = omap2_cm_read_mod_reg(OMAP3430_PER_MOD, CM_AUTOIDLE); if (enable) - w &= ~(1 << (id - 2)); + return omap2_clk_deny_idle(mcbsp_iclks[id]); else - w |= 1 << (id - 2); - omap2_cm_write_mod_reg(w, OMAP3430_PER_MOD, CM_AUTOIDLE); - - return 0; + return omap2_clk_allow_idle(mcbsp_iclks[id]); } static int __init omap_init_mcbsp(struct omap_hwmod *oh, void *unused) @@ -58,6 +55,7 @@ static int __init omap_init_mcbsp(struct omap_hwmod *oh, void *unused) struct omap_hwmod *oh_device[2]; struct omap_mcbsp_platform_data *pdata = NULL; struct platform_device *pdev; + char clk_name[11]; sscanf(oh->name, "mcbsp%d", &id); @@ -99,6 +97,8 @@ static int __init omap_init_mcbsp(struct omap_hwmod *oh, void *unused) oh_device[1] = omap_hwmod_lookup(( (struct omap_mcbsp_dev_attr *)(oh->dev_attr))->sidetone); pdata->enable_st_clock = omap3_enable_st_clock; + sprintf(clk_name, "mcbsp%d_ick", id); + mcbsp_iclks[id] = clk_get(NULL, clk_name); count++; } pdev = omap_device_build_ss(name, id, oh_device, count, pdata, diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c index f82cf878d6af..48094b58c88f 100644 --- a/arch/arm/mach-omap2/mux.c +++ b/arch/arm/mach-omap2/mux.c @@ -811,6 +811,12 @@ int __init omap_mux_late_init(void) } } + omap_mux_dbg_init(); + + /* see pinctrl-single-omap for the wake-up interrupt handling */ + if (of_have_populated_dt()) + return 0; + ret = request_irq(omap_prcm_event_to_irq("io"), omap_hwmod_mux_handle_irq, IRQF_SHARED | IRQF_NO_SUSPEND, "hwmod_io", omap_mux_late_init); @@ -818,8 +824,6 @@ int __init omap_mux_late_init(void) if (ret) pr_warning("mux: Failed to setup hwmod io irq %d\n", ret); - omap_mux_dbg_init(); - return 0; } diff --git a/arch/arm/mach-omap2/omap-pm.h b/arch/arm/mach-omap2/omap-pm.h index 67faa7b8fe92..1d777e63e05c 100644 --- a/arch/arm/mach-omap2/omap-pm.h +++ b/arch/arm/mach-omap2/omap-pm.h @@ -17,7 +17,7 @@ #include <linux/device.h> #include <linux/cpufreq.h> #include <linux/clk.h> -#include <linux/opp.h> +#include <linux/pm_opp.h> /* * agent_id values for use with omap_pm_set_min_bus_tput(): diff --git a/arch/arm/mach-omap2/omap-secure.c b/arch/arm/mach-omap2/omap-secure.c index b970440cffca..5ac122e88f67 100644 --- a/arch/arm/mach-omap2/omap-secure.c +++ b/arch/arm/mach-omap2/omap-secure.c @@ -3,6 +3,8 @@ * * Copyright (C) 2011 Texas Instruments, Inc. * Santosh Shilimkar <santosh.shilimkar@ti.com> + * Copyright (C) 2012 Ivaylo Dimitrov <freemangordon@abv.bg> + * Copyright (C) 2013 Pali Rohár <pali.rohar@gmail.com> * * * This program is free software,you can redistribute it and/or modify @@ -70,3 +72,77 @@ phys_addr_t omap_secure_ram_mempool_base(void) { return omap_secure_memblock_base; } + +/** + * rx51_secure_dispatcher: Routine to dispatch secure PPA API calls + * @idx: The PPA API index + * @process: Process ID + * @flag: The flag indicating criticality of operation + * @nargs: Number of valid arguments out of four. + * @arg1, arg2, arg3 args4: Parameters passed to secure API + * + * Return the non-zero error value on failure. + * + * NOTE: rx51_secure_dispatcher differs from omap_secure_dispatcher because + * it calling omap_smc3() instead omap_smc2() and param[0] is nargs+1 + */ +u32 rx51_secure_dispatcher(u32 idx, u32 process, u32 flag, u32 nargs, + u32 arg1, u32 arg2, u32 arg3, u32 arg4) +{ + u32 ret; + u32 param[5]; + + param[0] = nargs+1; /* RX-51 needs number of arguments + 1 */ + param[1] = arg1; + param[2] = arg2; + param[3] = arg3; + param[4] = arg4; + + /* + * Secure API needs physical address + * pointer for the parameters + */ + local_irq_disable(); + local_fiq_disable(); + flush_cache_all(); + outer_clean_range(__pa(param), __pa(param + 5)); + ret = omap_smc3(idx, process, flag, __pa(param)); + flush_cache_all(); + local_fiq_enable(); + local_irq_enable(); + + return ret; +} + +/** + * rx51_secure_update_aux_cr: Routine to modify the contents of Auxiliary Control Register + * @set_bits: bits to set in ACR + * @clr_bits: bits to clear in ACR + * + * Return the non-zero error value on failure. +*/ +u32 rx51_secure_update_aux_cr(u32 set_bits, u32 clear_bits) +{ + u32 acr; + + /* Read ACR */ + asm volatile ("mrc p15, 0, %0, c1, c0, 1" : "=r" (acr)); + acr &= ~clear_bits; + acr |= set_bits; + + return rx51_secure_dispatcher(RX51_PPA_WRITE_ACR, + 0, + FLAG_START_CRITICAL, + 1, acr, 0, 0, 0); +} + +/** + * rx51_secure_rng_call: Routine for HW random generator + */ +u32 rx51_secure_rng_call(u32 ptr, u32 count, u32 flag) +{ + return rx51_secure_dispatcher(RX51_PPA_HWRNG, + 0, + NO_FLAG, + 3, ptr, count, flag, 0); +} diff --git a/arch/arm/mach-omap2/omap-secure.h b/arch/arm/mach-omap2/omap-secure.h index 0e729170c46b..8cc7d331437d 100644 --- a/arch/arm/mach-omap2/omap-secure.h +++ b/arch/arm/mach-omap2/omap-secure.h @@ -3,6 +3,8 @@ * * Copyright (C) 2011 Texas Instruments, Inc. * Santosh Shilimkar <santosh.shilimkar@ti.com> + * Copyright (C) 2012 Ivaylo Dimitrov <freemangordon@abv.bg> + * Copyright (C) 2013 Pali Rohár <pali.rohar@gmail.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 @@ -42,23 +44,38 @@ #define OMAP4_MON_L2X0_AUXCTRL_INDEX 0x109 #define OMAP4_MON_L2X0_PREFETCH_INDEX 0x113 +#define OMAP5_DRA7_MON_SET_CNTFRQ_INDEX 0x109 + /* Secure PPA(Primary Protected Application) APIs */ #define OMAP4_PPA_L2_POR_INDEX 0x23 #define OMAP4_PPA_CPU_ACTRL_SMP_INDEX 0x25 +/* Secure RX-51 PPA (Primary Protected Application) APIs */ +#define RX51_PPA_HWRNG 29 +#define RX51_PPA_L2_INVAL 40 +#define RX51_PPA_WRITE_ACR 42 + #ifndef __ASSEMBLER__ extern u32 omap_secure_dispatcher(u32 idx, u32 flag, u32 nargs, u32 arg1, u32 arg2, u32 arg3, u32 arg4); extern u32 omap_smc2(u32 id, u32 falg, u32 pargs); +extern u32 omap_smc3(u32 id, u32 process, u32 flag, u32 pargs); extern phys_addr_t omap_secure_ram_mempool_base(void); extern int omap_secure_ram_reserve_memblock(void); +extern u32 rx51_secure_dispatcher(u32 idx, u32 process, u32 flag, u32 nargs, + u32 arg1, u32 arg2, u32 arg3, u32 arg4); +extern u32 rx51_secure_update_aux_cr(u32 set_bits, u32 clear_bits); +extern u32 rx51_secure_rng_call(u32 ptr, u32 count, u32 flag); + #ifdef CONFIG_OMAP4_ERRATA_I688 extern int omap_barrier_reserve_memblock(void); #else static inline void omap_barrier_reserve_memblock(void) { } #endif + +void set_cntfreq(void); #endif /* __ASSEMBLER__ */ #endif /* OMAP_ARCH_OMAP_SECURE_H */ diff --git a/arch/arm/mach-omap2/omap-smc.S b/arch/arm/mach-omap2/omap-smc.S index f6441c13cd8c..fd90125bffc7 100644 --- a/arch/arm/mach-omap2/omap-smc.S +++ b/arch/arm/mach-omap2/omap-smc.S @@ -1,9 +1,11 @@ /* - * OMAP44xx secure APIs file. + * OMAP34xx and OMAP44xx secure APIs file. * * Copyright (C) 2010 Texas Instruments, Inc. * Written by Santosh Shilimkar <santosh.shilimkar@ti.com> * + * Copyright (C) 2012 Ivaylo Dimitrov <freemangordon@abv.bg> + * Copyright (C) 2013 Pali Rohár <pali.rohar@gmail.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 @@ -54,6 +56,23 @@ ENTRY(omap_smc2) ldmfd sp!, {r4-r12, pc} ENDPROC(omap_smc2) +/** + * u32 omap_smc3(u32 service_id, u32 process_id, u32 flag, u32 pargs) + * Low level common routine for secure HAL and PPA APIs via smc #1 + * r0 - @service_id: Secure Service ID + * r1 - @process_id: Process ID + * r2 - @flag: Flag to indicate the criticality of operation + * r3 - @pargs: Physical address of parameter list + */ +ENTRY(omap_smc3) + stmfd sp!, {r4-r11, lr} + mov r12, r0 @ Copy the secure service ID + mov r6, #0xff @ Indicate new Task call + dsb @ Memory Barrier (not sure if needed, copied from omap_smc2) + smc #1 @ Call PPA service + ldmfd sp!, {r4-r11, pc} +ENDPROC(omap_smc3) + ENTRY(omap_modify_auxcoreboot0) stmfd sp!, {r1-r12, lr} ldr r12, =0x104 diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index 891211093295..75e95d4fb448 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c @@ -66,6 +66,13 @@ static void omap4_secondary_init(unsigned int cpu) 4, 0, 0, 0, 0, 0); /* + * Configure the CNTFRQ register for the secondary cpu's which + * indicates the frequency of the cpu local timers. + */ + if (soc_is_omap54xx() || soc_is_dra7xx()) + set_cntfreq(); + + /* * Synchronise with the boot thread. */ spin_lock(&boot_lock); diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c index 813c61558a5f..3664562f9148 100644 --- a/arch/arm/mach-omap2/omap-wakeupgen.c +++ b/arch/arm/mach-omap2/omap-wakeupgen.c @@ -33,8 +33,12 @@ #include "omap4-sar-layout.h" #include "common.h" -#define MAX_NR_REG_BANKS 5 -#define MAX_IRQS 160 +#define AM43XX_NR_REG_BANKS 7 +#define AM43XX_IRQS 224 +#define MAX_NR_REG_BANKS AM43XX_NR_REG_BANKS +#define MAX_IRQS AM43XX_IRQS +#define DEFAULT_NR_REG_BANKS 5 +#define DEFAULT_IRQS 160 #define WKG_MASK_ALL 0x00000000 #define WKG_UNMASK_ALL 0xffffffff #define CPU_ENA_OFFSET 0x400 @@ -47,8 +51,8 @@ static void __iomem *wakeupgen_base; static void __iomem *sar_base; static DEFINE_RAW_SPINLOCK(wakeupgen_lock); static unsigned int irq_target_cpu[MAX_IRQS]; -static unsigned int irq_banks = MAX_NR_REG_BANKS; -static unsigned int max_irqs = MAX_IRQS; +static unsigned int irq_banks = DEFAULT_NR_REG_BANKS; +static unsigned int max_irqs = DEFAULT_IRQS; static unsigned int omap_secure_apis; /* @@ -418,12 +422,16 @@ int __init omap_wakeupgen_init(void) irq_banks = OMAP4_NR_BANKS; max_irqs = OMAP4_NR_IRQS; omap_secure_apis = 1; + } else if (soc_is_am43xx()) { + irq_banks = AM43XX_NR_REG_BANKS; + max_irqs = AM43XX_IRQS; } /* Clear all IRQ bitmasks at wakeupGen level */ for (i = 0; i < irq_banks; i++) { wakeupgen_writel(0, i, CPU0_ID); - wakeupgen_writel(0, i, CPU1_ID); + if (!soc_is_am43xx()) + wakeupgen_writel(0, i, CPU1_ID); } /* diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c index b69dd9abb50a..53f0735817bb 100644 --- a/arch/arm/mach-omap2/omap_device.c +++ b/arch/arm/mach-omap2/omap_device.c @@ -621,6 +621,7 @@ static int _od_suspend_noirq(struct device *dev) if (!ret && !pm_runtime_status_suspended(dev)) { if (pm_generic_runtime_suspend(dev) == 0) { + pm_runtime_set_suspended(dev); omap_device_idle(pdev); od->flags |= OMAP_DEVICE_SUSPENDED; } @@ -634,10 +635,18 @@ static int _od_resume_noirq(struct device *dev) struct platform_device *pdev = to_platform_device(dev); struct omap_device *od = to_omap_device(pdev); - if ((od->flags & OMAP_DEVICE_SUSPENDED) && - !pm_runtime_status_suspended(dev)) { + if (od->flags & OMAP_DEVICE_SUSPENDED) { od->flags &= ~OMAP_DEVICE_SUSPENDED; omap_device_enable(pdev); + /* + * XXX: we run before core runtime pm has resumed itself. At + * this point in time, we just restore the runtime pm state and + * considering symmetric operations in resume, we donot expect + * to fail. If we failed, something changed in core runtime_pm + * framework OR some device driver messed things up, hence, WARN + */ + WARN(pm_runtime_set_active(dev), + "Could not set %s runtime state active\n", dev_name(dev)); pm_generic_runtime_resume(dev); } diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index d9ee0ff094d4..e3f0ecaf87dd 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -2357,25 +2357,29 @@ static struct device_node *of_dev_hwmod_lookup(struct device_node *np, /** * _init_mpu_rt_base - populate the virtual address for a hwmod * @oh: struct omap_hwmod * to locate the virtual address + * @data: (unused, caller should pass NULL) + * @np: struct device_node * of the IP block's device node in the DT data * * Cache the virtual address used by the MPU to access this IP block's * registers. This address is needed early so the OCP registers that * are part of the device's address space can be ioremapped properly. - * No return value. + * + * Returns 0 on success, -EINVAL if an invalid hwmod is passed, and + * -ENXIO on absent or invalid register target address space. */ -static void __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data) +static int __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data, + struct device_node *np) { struct omap_hwmod_addr_space *mem; void __iomem *va_start = NULL; - struct device_node *np; if (!oh) - return; + return -EINVAL; _save_mpu_port_index(oh); if (oh->_int_flags & _HWMOD_NO_MPU_PORT) - return; + return -ENXIO; mem = _find_mpu_rt_addr_space(oh); if (!mem) { @@ -2383,25 +2387,24 @@ static void __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data) oh->name); /* Extract the IO space from device tree blob */ - if (!of_have_populated_dt()) - return; + if (!np) + return -ENXIO; - np = of_dev_hwmod_lookup(of_find_node_by_name(NULL, "ocp"), oh); - if (np) - va_start = of_iomap(np, oh->mpu_rt_idx); + va_start = of_iomap(np, oh->mpu_rt_idx); } else { va_start = ioremap(mem->pa_start, mem->pa_end - mem->pa_start); } if (!va_start) { pr_err("omap_hwmod: %s: Could not ioremap\n", oh->name); - return; + return -ENXIO; } pr_debug("omap_hwmod: %s: MPU register target at va %p\n", oh->name, va_start); oh->_mpu_rt_va = va_start; + return 0; } /** @@ -2414,18 +2417,28 @@ static void __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data) * registered at this point. This is the first of two phases for * hwmod initialization. Code called here does not touch any hardware * registers, it simply prepares internal data structures. Returns 0 - * upon success or if the hwmod isn't registered, or -EINVAL upon - * failure. + * upon success or if the hwmod isn't registered or if the hwmod's + * address space is not defined, or -EINVAL upon failure. */ static int __init _init(struct omap_hwmod *oh, void *data) { int r; + struct device_node *np = NULL; if (oh->_state != _HWMOD_STATE_REGISTERED) return 0; - if (oh->class->sysc) - _init_mpu_rt_base(oh, NULL); + if (of_have_populated_dt()) + np = of_dev_hwmod_lookup(of_find_node_by_name(NULL, "ocp"), oh); + + if (oh->class->sysc) { + r = _init_mpu_rt_base(oh, NULL, np); + if (r < 0) { + WARN(1, "omap_hwmod: %s: doesn't have mpu register target base\n", + oh->name); + return 0; + } + } r = _init_clocks(oh, NULL); if (r < 0) { @@ -2433,6 +2446,12 @@ static int __init _init(struct omap_hwmod *oh, void *data) return -EINVAL; } + if (np) + if (of_find_property(np, "ti,no-reset-on-init", NULL)) + oh->flags |= HWMOD_INIT_NO_RESET; + if (of_find_property(np, "ti,no-idle-on-init", NULL)) + oh->flags |= HWMOD_INIT_NO_IDLE; + oh->_state = _HWMOD_STATE_INITIALIZED; return 0; @@ -4125,6 +4144,14 @@ void __init omap_hwmod_init(void) soc_ops.init_clkdm = _init_clkdm; soc_ops.update_context_lost = _omap4_update_context_lost; soc_ops.get_context_lost = _omap4_get_context_lost; + } else if (soc_is_am43xx()) { + soc_ops.enable_module = _omap4_enable_module; + soc_ops.disable_module = _omap4_disable_module; + soc_ops.wait_target_ready = _omap4_wait_target_ready; + soc_ops.assert_hardreset = _omap4_assert_hardreset; + soc_ops.deassert_hardreset = _omap4_deassert_hardreset; + soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted; + soc_ops.init_clkdm = _init_clkdm; } else if (soc_is_am33xx()) { soc_ops.enable_module = _am33xx_enable_module; soc_ops.disable_module = _am33xx_disable_module; diff --git a/arch/arm/mach-omap2/omap_hwmod.h b/arch/arm/mach-omap2/omap_hwmod.h index d02acf9308d3..0f97d635ff90 100644 --- a/arch/arm/mach-omap2/omap_hwmod.h +++ b/arch/arm/mach-omap2/omap_hwmod.h @@ -752,6 +752,7 @@ extern int omap44xx_hwmod_init(void); extern int omap54xx_hwmod_init(void); extern int am33xx_hwmod_init(void); extern int dra7xx_hwmod_init(void); +int am43xx_hwmod_init(void); extern int __init omap_hwmod_register_links(struct omap_hwmod_ocp_if **ois); diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h new file mode 100644 index 000000000000..130332c0534d --- /dev/null +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h @@ -0,0 +1,163 @@ +/* + * + * Copyright (C) 2013 Texas Instruments Incorporated + * + * Data common for AM335x and AM43x + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_OMAP_HWMOD_33XX_43XX_COMMON_DATA_H +#define __ARCH_ARM_MACH_OMAP2_OMAP_HWMOD_33XX_43XX_COMMON_DATA_H + +extern struct omap_hwmod_ocp_if am33xx_mpu__l3_main; +extern struct omap_hwmod_ocp_if am33xx_l3_main__l3_s; +extern struct omap_hwmod_ocp_if am33xx_l3_s__l4_ls; +extern struct omap_hwmod_ocp_if am33xx_l3_s__l4_wkup; +extern struct omap_hwmod_ocp_if am33xx_l3_main__l3_instr; +extern struct omap_hwmod_ocp_if am33xx_mpu__prcm; +extern struct omap_hwmod_ocp_if am33xx_l3_s__l3_main; +extern struct omap_hwmod_ocp_if am33xx_pruss__l3_main; +extern struct omap_hwmod_ocp_if am33xx_gfx__l3_main; +extern struct omap_hwmod_ocp_if am33xx_l3_main__gfx; +extern struct omap_hwmod_ocp_if am33xx_l4_wkup__rtc; +extern struct omap_hwmod_ocp_if am33xx_l4_per__dcan0; +extern struct omap_hwmod_ocp_if am33xx_l4_per__dcan1; +extern struct omap_hwmod_ocp_if am33xx_l4_per__gpio1; +extern struct omap_hwmod_ocp_if am33xx_l4_per__gpio2; +extern struct omap_hwmod_ocp_if am33xx_l4_per__gpio3; +extern struct omap_hwmod_ocp_if am33xx_cpgmac0__mdio; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__elm; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss0; +extern struct omap_hwmod_ocp_if am33xx_epwmss0__ecap0; +extern struct omap_hwmod_ocp_if am33xx_epwmss0__eqep0; +extern struct omap_hwmod_ocp_if am33xx_epwmss0__ehrpwm0; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss1; +extern struct omap_hwmod_ocp_if am33xx_epwmss1__ecap1; +extern struct omap_hwmod_ocp_if am33xx_epwmss1__eqep1; +extern struct omap_hwmod_ocp_if am33xx_epwmss1__ehrpwm1; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss2; +extern struct omap_hwmod_ocp_if am33xx_epwmss2__ecap2; +extern struct omap_hwmod_ocp_if am33xx_epwmss2__eqep2; +extern struct omap_hwmod_ocp_if am33xx_epwmss2__ehrpwm2; +extern struct omap_hwmod_ocp_if am33xx_l3_s__gpmc; +extern struct omap_hwmod_ocp_if am33xx_l4_per__i2c2; +extern struct omap_hwmod_ocp_if am33xx_l4_per__i2c3; +extern struct omap_hwmod_ocp_if am33xx_l4_per__mailbox; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__spinlock; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__mcasp0; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__mcasp1; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__mmc0; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__mmc1; +extern struct omap_hwmod_ocp_if am33xx_l3_s__mmc2; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__mcspi0; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__mcspi1; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__timer2; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__timer3; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__timer4; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__timer5; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__timer6; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__timer7; +extern struct omap_hwmod_ocp_if am33xx_l3_main__tpcc; +extern struct omap_hwmod_ocp_if am33xx_l3_main__tptc0; +extern struct omap_hwmod_ocp_if am33xx_l3_main__tptc1; +extern struct omap_hwmod_ocp_if am33xx_l3_main__tptc2; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__uart2; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__uart3; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__uart4; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__uart5; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__uart6; +extern struct omap_hwmod_ocp_if am33xx_l3_main__ocmc; +extern struct omap_hwmod_ocp_if am33xx_l3_main__sha0; +extern struct omap_hwmod_ocp_if am33xx_l3_main__aes0; + +extern struct omap_hwmod am33xx_l3_main_hwmod; +extern struct omap_hwmod am33xx_l3_s_hwmod; +extern struct omap_hwmod am33xx_l3_instr_hwmod; +extern struct omap_hwmod am33xx_l4_ls_hwmod; +extern struct omap_hwmod am33xx_l4_wkup_hwmod; +extern struct omap_hwmod am33xx_mpu_hwmod; +extern struct omap_hwmod am33xx_pruss_hwmod; +extern struct omap_hwmod am33xx_gfx_hwmod; +extern struct omap_hwmod am33xx_prcm_hwmod; +extern struct omap_hwmod am33xx_aes0_hwmod; +extern struct omap_hwmod am33xx_sha0_hwmod; +extern struct omap_hwmod am33xx_ocmcram_hwmod; +extern struct omap_hwmod am33xx_smartreflex0_hwmod; +extern struct omap_hwmod am33xx_smartreflex1_hwmod; +extern struct omap_hwmod am33xx_cpgmac0_hwmod; +extern struct omap_hwmod am33xx_mdio_hwmod; +extern struct omap_hwmod am33xx_dcan0_hwmod; +extern struct omap_hwmod am33xx_dcan1_hwmod; +extern struct omap_hwmod am33xx_elm_hwmod; +extern struct omap_hwmod am33xx_epwmss0_hwmod; +extern struct omap_hwmod am33xx_ecap0_hwmod; +extern struct omap_hwmod am33xx_eqep0_hwmod; +extern struct omap_hwmod am33xx_ehrpwm0_hwmod; +extern struct omap_hwmod am33xx_epwmss1_hwmod; +extern struct omap_hwmod am33xx_ecap1_hwmod; +extern struct omap_hwmod am33xx_eqep1_hwmod; +extern struct omap_hwmod am33xx_ehrpwm1_hwmod; +extern struct omap_hwmod am33xx_epwmss2_hwmod; +extern struct omap_hwmod am33xx_ecap2_hwmod; +extern struct omap_hwmod am33xx_eqep2_hwmod; +extern struct omap_hwmod am33xx_ehrpwm2_hwmod; +extern struct omap_hwmod am33xx_gpio1_hwmod; +extern struct omap_hwmod am33xx_gpio2_hwmod; +extern struct omap_hwmod am33xx_gpio3_hwmod; +extern struct omap_hwmod am33xx_gpmc_hwmod; +extern struct omap_hwmod am33xx_i2c1_hwmod; +extern struct omap_hwmod am33xx_i2c2_hwmod; +extern struct omap_hwmod am33xx_i2c3_hwmod; +extern struct omap_hwmod am33xx_mailbox_hwmod; +extern struct omap_hwmod am33xx_mcasp0_hwmod; +extern struct omap_hwmod am33xx_mcasp1_hwmod; +extern struct omap_hwmod am33xx_mmc0_hwmod; +extern struct omap_hwmod am33xx_mmc1_hwmod; +extern struct omap_hwmod am33xx_mmc2_hwmod; +extern struct omap_hwmod am33xx_rtc_hwmod; +extern struct omap_hwmod am33xx_spi0_hwmod; +extern struct omap_hwmod am33xx_spi1_hwmod; +extern struct omap_hwmod am33xx_spinlock_hwmod; +extern struct omap_hwmod am33xx_timer1_hwmod; +extern struct omap_hwmod am33xx_timer2_hwmod; +extern struct omap_hwmod am33xx_timer3_hwmod; +extern struct omap_hwmod am33xx_timer4_hwmod; +extern struct omap_hwmod am33xx_timer5_hwmod; +extern struct omap_hwmod am33xx_timer6_hwmod; +extern struct omap_hwmod am33xx_timer7_hwmod; +extern struct omap_hwmod am33xx_tpcc_hwmod; +extern struct omap_hwmod am33xx_tptc0_hwmod; +extern struct omap_hwmod am33xx_tptc1_hwmod; +extern struct omap_hwmod am33xx_tptc2_hwmod; +extern struct omap_hwmod am33xx_uart1_hwmod; +extern struct omap_hwmod am33xx_uart2_hwmod; +extern struct omap_hwmod am33xx_uart3_hwmod; +extern struct omap_hwmod am33xx_uart4_hwmod; +extern struct omap_hwmod am33xx_uart5_hwmod; +extern struct omap_hwmod am33xx_uart6_hwmod; +extern struct omap_hwmod am33xx_wd_timer1_hwmod; + +extern struct omap_hwmod_class am33xx_l4_hwmod_class; +extern struct omap_hwmod_class am33xx_wkup_m3_hwmod_class; +extern struct omap_hwmod_class am33xx_control_hwmod_class; +extern struct omap_hwmod_class am33xx_gpio_hwmod_class; +extern struct omap_hwmod_class am33xx_timer_hwmod_class; +extern struct omap_hwmod_class am33xx_epwmss_hwmod_class; +extern struct omap_hwmod_class am33xx_ehrpwm_hwmod_class; +extern struct omap_hwmod_class am33xx_spi_hwmod_class; + +extern struct omap_gpio_dev_attr gpio_dev_attr; +extern struct omap2_mcspi_dev_attr mcspi_attrib; + +void omap_hwmod_am33xx_reg(void); +void omap_hwmod_am43xx_reg(void); + +#endif diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_interconnect_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_interconnect_data.c new file mode 100644 index 000000000000..e2db378b849e --- /dev/null +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_interconnect_data.c @@ -0,0 +1,643 @@ +/* + * + * Copyright (C) 2013 Texas Instruments Incorporated + * + * Interconnects common for AM335x and AM43x + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/sizes.h> +#include "omap_hwmod.h" +#include "omap_hwmod_33xx_43xx_common_data.h" + +/* mpu -> l3 main */ +struct omap_hwmod_ocp_if am33xx_mpu__l3_main = { + .master = &am33xx_mpu_hwmod, + .slave = &am33xx_l3_main_hwmod, + .clk = "dpll_mpu_m2_ck", + .user = OCP_USER_MPU, +}; + +/* l3 main -> l3 s */ +struct omap_hwmod_ocp_if am33xx_l3_main__l3_s = { + .master = &am33xx_l3_main_hwmod, + .slave = &am33xx_l3_s_hwmod, + .clk = "l3s_gclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3 s -> l4 per/ls */ +struct omap_hwmod_ocp_if am33xx_l3_s__l4_ls = { + .master = &am33xx_l3_s_hwmod, + .slave = &am33xx_l4_ls_hwmod, + .clk = "l3s_gclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3 s -> l4 wkup */ +struct omap_hwmod_ocp_if am33xx_l3_s__l4_wkup = { + .master = &am33xx_l3_s_hwmod, + .slave = &am33xx_l4_wkup_hwmod, + .clk = "l3s_gclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3 main -> l3 instr */ +struct omap_hwmod_ocp_if am33xx_l3_main__l3_instr = { + .master = &am33xx_l3_main_hwmod, + .slave = &am33xx_l3_instr_hwmod, + .clk = "l3s_gclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* mpu -> prcm */ +struct omap_hwmod_ocp_if am33xx_mpu__prcm = { + .master = &am33xx_mpu_hwmod, + .slave = &am33xx_prcm_hwmod, + .clk = "dpll_mpu_m2_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3 s -> l3 main*/ +struct omap_hwmod_ocp_if am33xx_l3_s__l3_main = { + .master = &am33xx_l3_s_hwmod, + .slave = &am33xx_l3_main_hwmod, + .clk = "l3s_gclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* pru-icss -> l3 main */ +struct omap_hwmod_ocp_if am33xx_pruss__l3_main = { + .master = &am33xx_pruss_hwmod, + .slave = &am33xx_l3_main_hwmod, + .clk = "l3_gclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* gfx -> l3 main */ +struct omap_hwmod_ocp_if am33xx_gfx__l3_main = { + .master = &am33xx_gfx_hwmod, + .slave = &am33xx_l3_main_hwmod, + .clk = "dpll_core_m4_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3 main -> gfx */ +struct omap_hwmod_ocp_if am33xx_l3_main__gfx = { + .master = &am33xx_l3_main_hwmod, + .slave = &am33xx_gfx_hwmod, + .clk = "dpll_core_m4_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4 wkup -> rtc */ +struct omap_hwmod_ocp_if am33xx_l4_wkup__rtc = { + .master = &am33xx_l4_wkup_hwmod, + .slave = &am33xx_rtc_hwmod, + .clk = "clkdiv32k_ick", + .user = OCP_USER_MPU, +}; + +/* l4 per/ls -> DCAN0 */ +struct omap_hwmod_ocp_if am33xx_l4_per__dcan0 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_dcan0_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4 per/ls -> DCAN1 */ +struct omap_hwmod_ocp_if am33xx_l4_per__dcan1 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_dcan1_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4 per/ls -> GPIO2 */ +struct omap_hwmod_ocp_if am33xx_l4_per__gpio1 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_gpio1_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4 per/ls -> gpio3 */ +struct omap_hwmod_ocp_if am33xx_l4_per__gpio2 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_gpio2_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4 per/ls -> gpio4 */ +struct omap_hwmod_ocp_if am33xx_l4_per__gpio3 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_gpio3_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +struct omap_hwmod_ocp_if am33xx_cpgmac0__mdio = { + .master = &am33xx_cpgmac0_hwmod, + .slave = &am33xx_mdio_hwmod, + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_addr_space am33xx_elm_addr_space[] = { + { + .pa_start = 0x48080000, + .pa_end = 0x48080000 + SZ_8K - 1, + .flags = ADDR_TYPE_RT + }, + { } +}; + +struct omap_hwmod_ocp_if am33xx_l4_ls__elm = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_elm_hwmod, + .clk = "l4ls_gclk", + .addr = am33xx_elm_addr_space, + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_addr_space am33xx_epwmss0_addr_space[] = { + { + .pa_start = 0x48300000, + .pa_end = 0x48300000 + SZ_16 - 1, + .flags = ADDR_TYPE_RT + }, + { } +}; + +struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss0 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_epwmss0_hwmod, + .clk = "l4ls_gclk", + .addr = am33xx_epwmss0_addr_space, + .user = OCP_USER_MPU, +}; + +struct omap_hwmod_ocp_if am33xx_epwmss0__ecap0 = { + .master = &am33xx_epwmss0_hwmod, + .slave = &am33xx_ecap0_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +struct omap_hwmod_ocp_if am33xx_epwmss0__eqep0 = { + .master = &am33xx_epwmss0_hwmod, + .slave = &am33xx_eqep0_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +struct omap_hwmod_ocp_if am33xx_epwmss0__ehrpwm0 = { + .master = &am33xx_epwmss0_hwmod, + .slave = &am33xx_ehrpwm0_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + + +static struct omap_hwmod_addr_space am33xx_epwmss1_addr_space[] = { + { + .pa_start = 0x48302000, + .pa_end = 0x48302000 + SZ_16 - 1, + .flags = ADDR_TYPE_RT + }, + { } +}; + +struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss1 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_epwmss1_hwmod, + .clk = "l4ls_gclk", + .addr = am33xx_epwmss1_addr_space, + .user = OCP_USER_MPU, +}; + +struct omap_hwmod_ocp_if am33xx_epwmss1__ecap1 = { + .master = &am33xx_epwmss1_hwmod, + .slave = &am33xx_ecap1_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +struct omap_hwmod_ocp_if am33xx_epwmss1__eqep1 = { + .master = &am33xx_epwmss1_hwmod, + .slave = &am33xx_eqep1_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +struct omap_hwmod_ocp_if am33xx_epwmss1__ehrpwm1 = { + .master = &am33xx_epwmss1_hwmod, + .slave = &am33xx_ehrpwm1_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_addr_space am33xx_epwmss2_addr_space[] = { + { + .pa_start = 0x48304000, + .pa_end = 0x48304000 + SZ_16 - 1, + .flags = ADDR_TYPE_RT + }, + { } +}; + +struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss2 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_epwmss2_hwmod, + .clk = "l4ls_gclk", + .addr = am33xx_epwmss2_addr_space, + .user = OCP_USER_MPU, +}; + +struct omap_hwmod_ocp_if am33xx_epwmss2__ecap2 = { + .master = &am33xx_epwmss2_hwmod, + .slave = &am33xx_ecap2_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +struct omap_hwmod_ocp_if am33xx_epwmss2__eqep2 = { + .master = &am33xx_epwmss2_hwmod, + .slave = &am33xx_eqep2_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +struct omap_hwmod_ocp_if am33xx_epwmss2__ehrpwm2 = { + .master = &am33xx_epwmss2_hwmod, + .slave = &am33xx_ehrpwm2_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +/* l3s cfg -> gpmc */ +static struct omap_hwmod_addr_space am33xx_gpmc_addr_space[] = { + { + .pa_start = 0x50000000, + .pa_end = 0x50000000 + SZ_8K - 1, + .flags = ADDR_TYPE_RT, + }, + { } +}; + +struct omap_hwmod_ocp_if am33xx_l3_s__gpmc = { + .master = &am33xx_l3_s_hwmod, + .slave = &am33xx_gpmc_hwmod, + .clk = "l3s_gclk", + .addr = am33xx_gpmc_addr_space, + .user = OCP_USER_MPU, +}; + +/* i2c2 */ +struct omap_hwmod_ocp_if am33xx_l4_per__i2c2 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_i2c2_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +struct omap_hwmod_ocp_if am33xx_l4_per__i2c3 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_i2c3_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_addr_space am33xx_mailbox_addrs[] = { + { + .pa_start = 0x480C8000, + .pa_end = 0x480C8000 + (SZ_4K - 1), + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4 ls -> mailbox */ +struct omap_hwmod_ocp_if am33xx_l4_per__mailbox = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_mailbox_hwmod, + .clk = "l4ls_gclk", + .addr = am33xx_mailbox_addrs, + .user = OCP_USER_MPU, +}; + +/* l4 ls -> spinlock */ +struct omap_hwmod_ocp_if am33xx_l4_ls__spinlock = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_spinlock_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +/* l4 ls -> mcasp0 */ +static struct omap_hwmod_addr_space am33xx_mcasp0_addr_space[] = { + { + .pa_start = 0x48038000, + .pa_end = 0x48038000 + SZ_8K - 1, + .flags = ADDR_TYPE_RT + }, + { } +}; + +struct omap_hwmod_ocp_if am33xx_l4_ls__mcasp0 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_mcasp0_hwmod, + .clk = "l4ls_gclk", + .addr = am33xx_mcasp0_addr_space, + .user = OCP_USER_MPU, +}; + +/* l4 ls -> mcasp1 */ +static struct omap_hwmod_addr_space am33xx_mcasp1_addr_space[] = { + { + .pa_start = 0x4803C000, + .pa_end = 0x4803C000 + SZ_8K - 1, + .flags = ADDR_TYPE_RT + }, + { } +}; + +struct omap_hwmod_ocp_if am33xx_l4_ls__mcasp1 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_mcasp1_hwmod, + .clk = "l4ls_gclk", + .addr = am33xx_mcasp1_addr_space, + .user = OCP_USER_MPU, +}; + +/* l4 ls -> mmc0 */ +static struct omap_hwmod_addr_space am33xx_mmc0_addr_space[] = { + { + .pa_start = 0x48060100, + .pa_end = 0x48060100 + SZ_4K - 1, + .flags = ADDR_TYPE_RT, + }, + { } +}; + +struct omap_hwmod_ocp_if am33xx_l4_ls__mmc0 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_mmc0_hwmod, + .clk = "l4ls_gclk", + .addr = am33xx_mmc0_addr_space, + .user = OCP_USER_MPU, +}; + +/* l4 ls -> mmc1 */ +static struct omap_hwmod_addr_space am33xx_mmc1_addr_space[] = { + { + .pa_start = 0x481d8100, + .pa_end = 0x481d8100 + SZ_4K - 1, + .flags = ADDR_TYPE_RT, + }, + { } +}; + +struct omap_hwmod_ocp_if am33xx_l4_ls__mmc1 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_mmc1_hwmod, + .clk = "l4ls_gclk", + .addr = am33xx_mmc1_addr_space, + .user = OCP_USER_MPU, +}; + +/* l3 s -> mmc2 */ +static struct omap_hwmod_addr_space am33xx_mmc2_addr_space[] = { + { + .pa_start = 0x47810100, + .pa_end = 0x47810100 + SZ_64K - 1, + .flags = ADDR_TYPE_RT, + }, + { } +}; + +struct omap_hwmod_ocp_if am33xx_l3_s__mmc2 = { + .master = &am33xx_l3_s_hwmod, + .slave = &am33xx_mmc2_hwmod, + .clk = "l3s_gclk", + .addr = am33xx_mmc2_addr_space, + .user = OCP_USER_MPU, +}; + +/* l4 ls -> mcspi0 */ +struct omap_hwmod_ocp_if am33xx_l4_ls__mcspi0 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_spi0_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +/* l4 ls -> mcspi1 */ +struct omap_hwmod_ocp_if am33xx_l4_ls__mcspi1 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_spi1_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +/* l4 per -> timer2 */ +struct omap_hwmod_ocp_if am33xx_l4_ls__timer2 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_timer2_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +/* l4 per -> timer3 */ +struct omap_hwmod_ocp_if am33xx_l4_ls__timer3 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_timer3_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +/* l4 per -> timer4 */ +struct omap_hwmod_ocp_if am33xx_l4_ls__timer4 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_timer4_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +/* l4 per -> timer5 */ +struct omap_hwmod_ocp_if am33xx_l4_ls__timer5 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_timer5_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +/* l4 per -> timer6 */ +struct omap_hwmod_ocp_if am33xx_l4_ls__timer6 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_timer6_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +/* l4 per -> timer7 */ +struct omap_hwmod_ocp_if am33xx_l4_ls__timer7 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_timer7_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +/* l3 main -> tpcc */ +struct omap_hwmod_ocp_if am33xx_l3_main__tpcc = { + .master = &am33xx_l3_main_hwmod, + .slave = &am33xx_tpcc_hwmod, + .clk = "l3_gclk", + .user = OCP_USER_MPU, +}; + +/* l3 main -> tpcc0 */ +static struct omap_hwmod_addr_space am33xx_tptc0_addr_space[] = { + { + .pa_start = 0x49800000, + .pa_end = 0x49800000 + SZ_8K - 1, + .flags = ADDR_TYPE_RT, + }, + { } +}; + +struct omap_hwmod_ocp_if am33xx_l3_main__tptc0 = { + .master = &am33xx_l3_main_hwmod, + .slave = &am33xx_tptc0_hwmod, + .clk = "l3_gclk", + .addr = am33xx_tptc0_addr_space, + .user = OCP_USER_MPU, +}; + +/* l3 main -> tpcc1 */ +static struct omap_hwmod_addr_space am33xx_tptc1_addr_space[] = { + { + .pa_start = 0x49900000, + .pa_end = 0x49900000 + SZ_8K - 1, + .flags = ADDR_TYPE_RT, + }, + { } +}; + +struct omap_hwmod_ocp_if am33xx_l3_main__tptc1 = { + .master = &am33xx_l3_main_hwmod, + .slave = &am33xx_tptc1_hwmod, + .clk = "l3_gclk", + .addr = am33xx_tptc1_addr_space, + .user = OCP_USER_MPU, +}; + +/* l3 main -> tpcc2 */ +static struct omap_hwmod_addr_space am33xx_tptc2_addr_space[] = { + { + .pa_start = 0x49a00000, + .pa_end = 0x49a00000 + SZ_8K - 1, + .flags = ADDR_TYPE_RT, + }, + { } +}; + +struct omap_hwmod_ocp_if am33xx_l3_main__tptc2 = { + .master = &am33xx_l3_main_hwmod, + .slave = &am33xx_tptc2_hwmod, + .clk = "l3_gclk", + .addr = am33xx_tptc2_addr_space, + .user = OCP_USER_MPU, +}; + +/* l4 ls -> uart2 */ +struct omap_hwmod_ocp_if am33xx_l4_ls__uart2 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_uart2_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +/* l4 ls -> uart3 */ +struct omap_hwmod_ocp_if am33xx_l4_ls__uart3 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_uart3_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +/* l4 ls -> uart4 */ +struct omap_hwmod_ocp_if am33xx_l4_ls__uart4 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_uart4_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +/* l4 ls -> uart5 */ +struct omap_hwmod_ocp_if am33xx_l4_ls__uart5 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_uart5_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +/* l4 ls -> uart6 */ +struct omap_hwmod_ocp_if am33xx_l4_ls__uart6 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_uart6_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +/* l3 main -> ocmc */ +struct omap_hwmod_ocp_if am33xx_l3_main__ocmc = { + .master = &am33xx_l3_main_hwmod, + .slave = &am33xx_ocmcram_hwmod, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3 main -> sha0 HIB2 */ +static struct omap_hwmod_addr_space am33xx_sha0_addrs[] = { + { + .pa_start = 0x53100000, + .pa_end = 0x53100000 + SZ_512 - 1, + .flags = ADDR_TYPE_RT + }, + { } +}; + +struct omap_hwmod_ocp_if am33xx_l3_main__sha0 = { + .master = &am33xx_l3_main_hwmod, + .slave = &am33xx_sha0_hwmod, + .clk = "sha0_fck", + .addr = am33xx_sha0_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3 main -> AES0 HIB2 */ +static struct omap_hwmod_addr_space am33xx_aes0_addrs[] = { + { + .pa_start = 0x53500000, + .pa_end = 0x53500000 + SZ_1M - 1, + .flags = ADDR_TYPE_RT + }, + { } +}; + +struct omap_hwmod_ocp_if am33xx_l3_main__aes0 = { + .master = &am33xx_l3_main_hwmod, + .slave = &am33xx_aes0_hwmod, + .clk = "aes0_fck", + .addr = am33xx_aes0_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c new file mode 100644 index 000000000000..0f178623e7da --- /dev/null +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c @@ -0,0 +1,1469 @@ +/* + * + * Copyright (C) 2013 Texas Instruments Incorporated + * + * Hwmod common for AM335x and AM43x + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/platform_data/gpio-omap.h> +#include <linux/platform_data/spi-omap2-mcspi.h> +#include "omap_hwmod.h" +#include "i2c.h" +#include "mmc.h" +#include "wd_timer.h" +#include "cm33xx.h" +#include "prm33xx.h" +#include "omap_hwmod_33xx_43xx_common_data.h" +#include "prcm43xx.h" + +#define CLKCTRL(oh, clkctrl) ((oh).prcm.omap4.clkctrl_offs = (clkctrl)) +#define RSTCTRL(oh, rstctrl) ((oh).prcm.omap4.rstctrl_offs = (rstctrl)) +#define RSTST(oh, rstst) ((oh).prcm.omap4.rstst_offs = (rstst)) + +/* + * 'l3' class + * instance(s): l3_main, l3_s, l3_instr + */ +static struct omap_hwmod_class am33xx_l3_hwmod_class = { + .name = "l3", +}; + +struct omap_hwmod am33xx_l3_main_hwmod = { + .name = "l3_main", + .class = &am33xx_l3_hwmod_class, + .clkdm_name = "l3_clkdm", + .flags = HWMOD_INIT_NO_IDLE, + .main_clk = "l3_gclk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* l3_s */ +struct omap_hwmod am33xx_l3_s_hwmod = { + .name = "l3_s", + .class = &am33xx_l3_hwmod_class, + .clkdm_name = "l3s_clkdm", +}; + +/* l3_instr */ +struct omap_hwmod am33xx_l3_instr_hwmod = { + .name = "l3_instr", + .class = &am33xx_l3_hwmod_class, + .clkdm_name = "l3_clkdm", + .flags = HWMOD_INIT_NO_IDLE, + .main_clk = "l3_gclk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * 'l4' class + * instance(s): l4_ls, l4_hs, l4_wkup, l4_fw + */ +struct omap_hwmod_class am33xx_l4_hwmod_class = { + .name = "l4", +}; + +/* l4_ls */ +struct omap_hwmod am33xx_l4_ls_hwmod = { + .name = "l4_ls", + .class = &am33xx_l4_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .flags = HWMOD_INIT_NO_IDLE, + .main_clk = "l4ls_gclk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* l4_wkup */ +struct omap_hwmod am33xx_l4_wkup_hwmod = { + .name = "l4_wkup", + .class = &am33xx_l4_hwmod_class, + .clkdm_name = "l4_wkup_clkdm", + .flags = HWMOD_INIT_NO_IDLE, + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * 'mpu' class + */ +static struct omap_hwmod_class am33xx_mpu_hwmod_class = { + .name = "mpu", +}; + +struct omap_hwmod am33xx_mpu_hwmod = { + .name = "mpu", + .class = &am33xx_mpu_hwmod_class, + .clkdm_name = "mpu_clkdm", + .flags = HWMOD_INIT_NO_IDLE, + .main_clk = "dpll_mpu_m2_ck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * 'wakeup m3' class + * Wakeup controller sub-system under wakeup domain + */ +struct omap_hwmod_class am33xx_wkup_m3_hwmod_class = { + .name = "wkup_m3", +}; + +/* + * 'pru-icss' class + * Programmable Real-Time Unit and Industrial Communication Subsystem + */ +static struct omap_hwmod_class am33xx_pruss_hwmod_class = { + .name = "pruss", +}; + +static struct omap_hwmod_rst_info am33xx_pruss_resets[] = { + { .name = "pruss", .rst_shift = 1 }, +}; + +/* pru-icss */ +/* Pseudo hwmod for reset control purpose only */ +struct omap_hwmod am33xx_pruss_hwmod = { + .name = "pruss", + .class = &am33xx_pruss_hwmod_class, + .clkdm_name = "pruss_ocp_clkdm", + .main_clk = "pruss_ocp_gclk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .rst_lines = am33xx_pruss_resets, + .rst_lines_cnt = ARRAY_SIZE(am33xx_pruss_resets), +}; + +/* gfx */ +/* Pseudo hwmod for reset control purpose only */ +static struct omap_hwmod_class am33xx_gfx_hwmod_class = { + .name = "gfx", +}; + +static struct omap_hwmod_rst_info am33xx_gfx_resets[] = { + { .name = "gfx", .rst_shift = 0, .st_shift = 0}, +}; + +struct omap_hwmod am33xx_gfx_hwmod = { + .name = "gfx", + .class = &am33xx_gfx_hwmod_class, + .clkdm_name = "gfx_l3_clkdm", + .main_clk = "gfx_fck_div_ck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .rst_lines = am33xx_gfx_resets, + .rst_lines_cnt = ARRAY_SIZE(am33xx_gfx_resets), +}; + +/* + * 'prcm' class + * power and reset manager (whole prcm infrastructure) + */ +static struct omap_hwmod_class am33xx_prcm_hwmod_class = { + .name = "prcm", +}; + +/* prcm */ +struct omap_hwmod am33xx_prcm_hwmod = { + .name = "prcm", + .class = &am33xx_prcm_hwmod_class, + .clkdm_name = "l4_wkup_clkdm", +}; + +/* + * 'aes0' class + */ +static struct omap_hwmod_class_sysconfig am33xx_aes0_sysc = { + .rev_offs = 0x80, + .sysc_offs = 0x84, + .syss_offs = 0x88, + .sysc_flags = SYSS_HAS_RESET_STATUS, +}; + +static struct omap_hwmod_class am33xx_aes0_hwmod_class = { + .name = "aes0", + .sysc = &am33xx_aes0_sysc, +}; + +struct omap_hwmod am33xx_aes0_hwmod = { + .name = "aes", + .class = &am33xx_aes0_hwmod_class, + .clkdm_name = "l3_clkdm", + .main_clk = "aes0_fck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* sha0 HIB2 (the 'P' (public) device) */ +static struct omap_hwmod_class_sysconfig am33xx_sha0_sysc = { + .rev_offs = 0x100, + .sysc_offs = 0x110, + .syss_offs = 0x114, + .sysc_flags = SYSS_HAS_RESET_STATUS, +}; + +static struct omap_hwmod_class am33xx_sha0_hwmod_class = { + .name = "sha0", + .sysc = &am33xx_sha0_sysc, +}; + +struct omap_hwmod am33xx_sha0_hwmod = { + .name = "sham", + .class = &am33xx_sha0_hwmod_class, + .clkdm_name = "l3_clkdm", + .main_clk = "l3_gclk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* ocmcram */ +static struct omap_hwmod_class am33xx_ocmcram_hwmod_class = { + .name = "ocmcram", +}; + +struct omap_hwmod am33xx_ocmcram_hwmod = { + .name = "ocmcram", + .class = &am33xx_ocmcram_hwmod_class, + .clkdm_name = "l3_clkdm", + .flags = HWMOD_INIT_NO_IDLE, + .main_clk = "l3_gclk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* 'smartreflex' class */ +static struct omap_hwmod_class am33xx_smartreflex_hwmod_class = { + .name = "smartreflex", +}; + +/* smartreflex0 */ +struct omap_hwmod am33xx_smartreflex0_hwmod = { + .name = "smartreflex0", + .class = &am33xx_smartreflex_hwmod_class, + .clkdm_name = "l4_wkup_clkdm", + .main_clk = "smartreflex0_fck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* smartreflex1 */ +struct omap_hwmod am33xx_smartreflex1_hwmod = { + .name = "smartreflex1", + .class = &am33xx_smartreflex_hwmod_class, + .clkdm_name = "l4_wkup_clkdm", + .main_clk = "smartreflex1_fck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * 'control' module class + */ +struct omap_hwmod_class am33xx_control_hwmod_class = { + .name = "control", +}; + +/* + * 'cpgmac' class + * cpsw/cpgmac sub system + */ +static struct omap_hwmod_class_sysconfig am33xx_cpgmac_sysc = { + .rev_offs = 0x0, + .sysc_offs = 0x8, + .syss_offs = 0x4, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE | + SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | MSTANDBY_FORCE | + MSTANDBY_NO), + .sysc_fields = &omap_hwmod_sysc_type3, +}; + +static struct omap_hwmod_class am33xx_cpgmac0_hwmod_class = { + .name = "cpgmac0", + .sysc = &am33xx_cpgmac_sysc, +}; + +struct omap_hwmod am33xx_cpgmac0_hwmod = { + .name = "cpgmac0", + .class = &am33xx_cpgmac0_hwmod_class, + .clkdm_name = "cpsw_125mhz_clkdm", + .flags = (HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY), + .main_clk = "cpsw_125mhz_gclk", + .mpu_rt_idx = 1, + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * mdio class + */ +static struct omap_hwmod_class am33xx_mdio_hwmod_class = { + .name = "davinci_mdio", +}; + +struct omap_hwmod am33xx_mdio_hwmod = { + .name = "davinci_mdio", + .class = &am33xx_mdio_hwmod_class, + .clkdm_name = "cpsw_125mhz_clkdm", + .main_clk = "cpsw_125mhz_gclk", +}; + +/* + * dcan class + */ +static struct omap_hwmod_class am33xx_dcan_hwmod_class = { + .name = "d_can", +}; + +/* dcan0 */ +struct omap_hwmod am33xx_dcan0_hwmod = { + .name = "d_can0", + .class = &am33xx_dcan_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "dcan0_fck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* dcan1 */ +struct omap_hwmod am33xx_dcan1_hwmod = { + .name = "d_can1", + .class = &am33xx_dcan_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "dcan1_fck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* elm */ +static struct omap_hwmod_class_sysconfig am33xx_elm_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE | + SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class am33xx_elm_hwmod_class = { + .name = "elm", + .sysc = &am33xx_elm_sysc, +}; + +struct omap_hwmod am33xx_elm_hwmod = { + .name = "elm", + .class = &am33xx_elm_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* pwmss */ +static struct omap_hwmod_class_sysconfig am33xx_epwmss_sysc = { + .rev_offs = 0x0, + .sysc_offs = 0x4, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO | + MSTANDBY_SMART | MSTANDBY_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +struct omap_hwmod_class am33xx_epwmss_hwmod_class = { + .name = "epwmss", + .sysc = &am33xx_epwmss_sysc, +}; + +static struct omap_hwmod_class am33xx_ecap_hwmod_class = { + .name = "ecap", +}; + +static struct omap_hwmod_class am33xx_eqep_hwmod_class = { + .name = "eqep", +}; + +struct omap_hwmod_class am33xx_ehrpwm_hwmod_class = { + .name = "ehrpwm", +}; + +/* epwmss0 */ +struct omap_hwmod am33xx_epwmss0_hwmod = { + .name = "epwmss0", + .class = &am33xx_epwmss_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* ecap0 */ +struct omap_hwmod am33xx_ecap0_hwmod = { + .name = "ecap0", + .class = &am33xx_ecap_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", +}; + +/* eqep0 */ +struct omap_hwmod am33xx_eqep0_hwmod = { + .name = "eqep0", + .class = &am33xx_eqep_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", +}; + +/* ehrpwm0 */ +struct omap_hwmod am33xx_ehrpwm0_hwmod = { + .name = "ehrpwm0", + .class = &am33xx_ehrpwm_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", +}; + +/* epwmss1 */ +struct omap_hwmod am33xx_epwmss1_hwmod = { + .name = "epwmss1", + .class = &am33xx_epwmss_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* ecap1 */ +struct omap_hwmod am33xx_ecap1_hwmod = { + .name = "ecap1", + .class = &am33xx_ecap_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", +}; + +/* eqep1 */ +struct omap_hwmod am33xx_eqep1_hwmod = { + .name = "eqep1", + .class = &am33xx_eqep_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", +}; + +/* ehrpwm1 */ +struct omap_hwmod am33xx_ehrpwm1_hwmod = { + .name = "ehrpwm1", + .class = &am33xx_ehrpwm_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", +}; + +/* epwmss2 */ +struct omap_hwmod am33xx_epwmss2_hwmod = { + .name = "epwmss2", + .class = &am33xx_epwmss_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* ecap2 */ +struct omap_hwmod am33xx_ecap2_hwmod = { + .name = "ecap2", + .class = &am33xx_ecap_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", +}; + +/* eqep2 */ +struct omap_hwmod am33xx_eqep2_hwmod = { + .name = "eqep2", + .class = &am33xx_eqep_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", +}; + +/* ehrpwm2 */ +struct omap_hwmod am33xx_ehrpwm2_hwmod = { + .name = "ehrpwm2", + .class = &am33xx_ehrpwm_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", +}; + +/* + * 'gpio' class: for gpio 0,1,2,3 + */ +static struct omap_hwmod_class_sysconfig am33xx_gpio_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0114, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_ENAWAKEUP | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | + SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +struct omap_hwmod_class am33xx_gpio_hwmod_class = { + .name = "gpio", + .sysc = &am33xx_gpio_sysc, + .rev = 2, +}; + +struct omap_gpio_dev_attr gpio_dev_attr = { + .bank_width = 32, + .dbck_flag = true, +}; + +/* gpio1 */ +static struct omap_hwmod_opt_clk gpio1_opt_clks[] = { + { .role = "dbclk", .clk = "gpio1_dbclk" }, +}; + +struct omap_hwmod am33xx_gpio1_hwmod = { + .name = "gpio2", + .class = &am33xx_gpio_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .main_clk = "l4ls_gclk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .opt_clks = gpio1_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(gpio1_opt_clks), + .dev_attr = &gpio_dev_attr, +}; + +/* gpio2 */ +static struct omap_hwmod_opt_clk gpio2_opt_clks[] = { + { .role = "dbclk", .clk = "gpio2_dbclk" }, +}; + +struct omap_hwmod am33xx_gpio2_hwmod = { + .name = "gpio3", + .class = &am33xx_gpio_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .main_clk = "l4ls_gclk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .opt_clks = gpio2_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(gpio2_opt_clks), + .dev_attr = &gpio_dev_attr, +}; + +/* gpio3 */ +static struct omap_hwmod_opt_clk gpio3_opt_clks[] = { + { .role = "dbclk", .clk = "gpio3_dbclk" }, +}; + +struct omap_hwmod am33xx_gpio3_hwmod = { + .name = "gpio4", + .class = &am33xx_gpio_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .main_clk = "l4ls_gclk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .opt_clks = gpio3_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(gpio3_opt_clks), + .dev_attr = &gpio_dev_attr, +}; + +/* gpmc */ +static struct omap_hwmod_class_sysconfig gpmc_sysc = { + .rev_offs = 0x0, + .sysc_offs = 0x10, + .syss_offs = 0x14, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class am33xx_gpmc_hwmod_class = { + .name = "gpmc", + .sysc = &gpmc_sysc, +}; + +struct omap_hwmod am33xx_gpmc_hwmod = { + .name = "gpmc", + .class = &am33xx_gpmc_hwmod_class, + .clkdm_name = "l3s_clkdm", + .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), + .main_clk = "l3s_gclk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* 'i2c' class */ +static struct omap_hwmod_class_sysconfig am33xx_i2c_sysc = { + .sysc_offs = 0x0010, + .syss_offs = 0x0090, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | + SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class i2c_class = { + .name = "i2c", + .sysc = &am33xx_i2c_sysc, + .rev = OMAP_I2C_IP_VERSION_2, + .reset = &omap_i2c_reset, +}; + +static struct omap_i2c_dev_attr i2c_dev_attr = { + .flags = OMAP_I2C_FLAG_BUS_SHIFT_NONE, +}; + +/* i2c1 */ +struct omap_hwmod am33xx_i2c1_hwmod = { + .name = "i2c1", + .class = &i2c_class, + .clkdm_name = "l4_wkup_clkdm", + .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, + .main_clk = "dpll_per_m2_div4_wkupdm_ck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &i2c_dev_attr, +}; + +/* i2c1 */ +struct omap_hwmod am33xx_i2c2_hwmod = { + .name = "i2c2", + .class = &i2c_class, + .clkdm_name = "l4ls_clkdm", + .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, + .main_clk = "dpll_per_m2_div4_ck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &i2c_dev_attr, +}; + +/* i2c3 */ +struct omap_hwmod am33xx_i2c3_hwmod = { + .name = "i2c3", + .class = &i2c_class, + .clkdm_name = "l4ls_clkdm", + .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, + .main_clk = "dpll_per_m2_div4_ck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &i2c_dev_attr, +}; + +/* + * 'mailbox' class + * mailbox module allowing communication between the on-chip processors using a + * queued mailbox-interrupt mechanism. + */ +static struct omap_hwmod_class_sysconfig am33xx_mailbox_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_RESET_STATUS | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class am33xx_mailbox_hwmod_class = { + .name = "mailbox", + .sysc = &am33xx_mailbox_sysc, +}; + +struct omap_hwmod am33xx_mailbox_hwmod = { + .name = "mailbox", + .class = &am33xx_mailbox_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * 'mcasp' class + */ +static struct omap_hwmod_class_sysconfig am33xx_mcasp_sysc = { + .rev_offs = 0x0, + .sysc_offs = 0x4, + .sysc_flags = SYSC_HAS_SIDLEMODE, + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type3, +}; + +static struct omap_hwmod_class am33xx_mcasp_hwmod_class = { + .name = "mcasp", + .sysc = &am33xx_mcasp_sysc, +}; + +/* mcasp0 */ +struct omap_hwmod am33xx_mcasp0_hwmod = { + .name = "mcasp0", + .class = &am33xx_mcasp_hwmod_class, + .clkdm_name = "l3s_clkdm", + .main_clk = "mcasp0_fck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* mcasp1 */ +struct omap_hwmod am33xx_mcasp1_hwmod = { + .name = "mcasp1", + .class = &am33xx_mcasp_hwmod_class, + .clkdm_name = "l3s_clkdm", + .main_clk = "mcasp1_fck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* 'mmc' class */ +static struct omap_hwmod_class_sysconfig am33xx_mmc_sysc = { + .rev_offs = 0x1fc, + .sysc_offs = 0x10, + .syss_offs = 0x14, + .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE | + SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | + SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class am33xx_mmc_hwmod_class = { + .name = "mmc", + .sysc = &am33xx_mmc_sysc, +}; + +/* mmc0 */ +static struct omap_mmc_dev_attr am33xx_mmc0_dev_attr = { + .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT, +}; + +struct omap_hwmod am33xx_mmc0_hwmod = { + .name = "mmc1", + .class = &am33xx_mmc_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "mmc_clk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &am33xx_mmc0_dev_attr, +}; + +/* mmc1 */ +static struct omap_mmc_dev_attr am33xx_mmc1_dev_attr = { + .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT, +}; + +struct omap_hwmod am33xx_mmc1_hwmod = { + .name = "mmc2", + .class = &am33xx_mmc_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "mmc_clk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &am33xx_mmc1_dev_attr, +}; + +/* mmc2 */ +static struct omap_mmc_dev_attr am33xx_mmc2_dev_attr = { + .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT, +}; +struct omap_hwmod am33xx_mmc2_hwmod = { + .name = "mmc3", + .class = &am33xx_mmc_hwmod_class, + .clkdm_name = "l3s_clkdm", + .main_clk = "mmc_clk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &am33xx_mmc2_dev_attr, +}; + +/* + * 'rtc' class + * rtc subsystem + */ +static struct omap_hwmod_class_sysconfig am33xx_rtc_sysc = { + .rev_offs = 0x0074, + .sysc_offs = 0x0078, + .sysc_flags = SYSC_HAS_SIDLEMODE, + .idlemodes = (SIDLE_FORCE | SIDLE_NO | + SIDLE_SMART | SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type3, +}; + +static struct omap_hwmod_class am33xx_rtc_hwmod_class = { + .name = "rtc", + .sysc = &am33xx_rtc_sysc, +}; + +struct omap_hwmod am33xx_rtc_hwmod = { + .name = "rtc", + .class = &am33xx_rtc_hwmod_class, + .clkdm_name = "l4_rtc_clkdm", + .main_clk = "clk_32768_ck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* 'spi' class */ +static struct omap_hwmod_class_sysconfig am33xx_mcspi_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0110, + .syss_offs = 0x0114, + .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE | + SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +struct omap_hwmod_class am33xx_spi_hwmod_class = { + .name = "mcspi", + .sysc = &am33xx_mcspi_sysc, + .rev = OMAP4_MCSPI_REV, +}; + +/* spi0 */ +struct omap2_mcspi_dev_attr mcspi_attrib = { + .num_chipselect = 2, +}; +struct omap_hwmod am33xx_spi0_hwmod = { + .name = "spi0", + .class = &am33xx_spi_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "dpll_per_m2_div4_ck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &mcspi_attrib, +}; + +/* spi1 */ +struct omap_hwmod am33xx_spi1_hwmod = { + .name = "spi1", + .class = &am33xx_spi_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "dpll_per_m2_div4_ck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &mcspi_attrib, +}; + +/* + * 'spinlock' class + * spinlock provides hardware assistance for synchronizing the + * processes running on multiple processors + */ + +static struct omap_hwmod_class_sysconfig am33xx_spinlock_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | + SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class am33xx_spinlock_hwmod_class = { + .name = "spinlock", + .sysc = &am33xx_spinlock_sysc, +}; + +struct omap_hwmod am33xx_spinlock_hwmod = { + .name = "spinlock", + .class = &am33xx_spinlock_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* 'timer 2-7' class */ +static struct omap_hwmod_class_sysconfig am33xx_timer_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +struct omap_hwmod_class am33xx_timer_hwmod_class = { + .name = "timer", + .sysc = &am33xx_timer_sysc, +}; + +/* timer1 1ms */ +static struct omap_hwmod_class_sysconfig am33xx_timer1ms_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE | + SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class am33xx_timer1ms_hwmod_class = { + .name = "timer", + .sysc = &am33xx_timer1ms_sysc, +}; + +struct omap_hwmod am33xx_timer1_hwmod = { + .name = "timer1", + .class = &am33xx_timer1ms_hwmod_class, + .clkdm_name = "l4_wkup_clkdm", + .main_clk = "timer1_fck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +struct omap_hwmod am33xx_timer2_hwmod = { + .name = "timer2", + .class = &am33xx_timer_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "timer2_fck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +struct omap_hwmod am33xx_timer3_hwmod = { + .name = "timer3", + .class = &am33xx_timer_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "timer3_fck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +struct omap_hwmod am33xx_timer4_hwmod = { + .name = "timer4", + .class = &am33xx_timer_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "timer4_fck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +struct omap_hwmod am33xx_timer5_hwmod = { + .name = "timer5", + .class = &am33xx_timer_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "timer5_fck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +struct omap_hwmod am33xx_timer6_hwmod = { + .name = "timer6", + .class = &am33xx_timer_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "timer6_fck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +struct omap_hwmod am33xx_timer7_hwmod = { + .name = "timer7", + .class = &am33xx_timer_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "timer7_fck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* tpcc */ +static struct omap_hwmod_class am33xx_tpcc_hwmod_class = { + .name = "tpcc", +}; + +struct omap_hwmod am33xx_tpcc_hwmod = { + .name = "tpcc", + .class = &am33xx_tpcc_hwmod_class, + .clkdm_name = "l3_clkdm", + .main_clk = "l3_gclk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +static struct omap_hwmod_class_sysconfig am33xx_tptc_sysc = { + .rev_offs = 0x0, + .sysc_offs = 0x10, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | + SYSC_HAS_MIDLEMODE), + .idlemodes = (SIDLE_FORCE | SIDLE_SMART | MSTANDBY_FORCE), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +/* 'tptc' class */ +static struct omap_hwmod_class am33xx_tptc_hwmod_class = { + .name = "tptc", + .sysc = &am33xx_tptc_sysc, +}; + +/* tptc0 */ +struct omap_hwmod am33xx_tptc0_hwmod = { + .name = "tptc0", + .class = &am33xx_tptc_hwmod_class, + .clkdm_name = "l3_clkdm", + .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY, + .main_clk = "l3_gclk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* tptc1 */ +struct omap_hwmod am33xx_tptc1_hwmod = { + .name = "tptc1", + .class = &am33xx_tptc_hwmod_class, + .clkdm_name = "l3_clkdm", + .flags = (HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY), + .main_clk = "l3_gclk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* tptc2 */ +struct omap_hwmod am33xx_tptc2_hwmod = { + .name = "tptc2", + .class = &am33xx_tptc_hwmod_class, + .clkdm_name = "l3_clkdm", + .flags = (HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY), + .main_clk = "l3_gclk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* 'uart' class */ +static struct omap_hwmod_class_sysconfig uart_sysc = { + .rev_offs = 0x50, + .sysc_offs = 0x54, + .syss_offs = 0x58, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_ENAWAKEUP | + SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class uart_class = { + .name = "uart", + .sysc = &uart_sysc, +}; + +struct omap_hwmod am33xx_uart1_hwmod = { + .name = "uart1", + .class = &uart_class, + .clkdm_name = "l4_wkup_clkdm", + .flags = DEBUG_AM33XXUART1_FLAGS | HWMOD_SWSUP_SIDLE_ACT, + .main_clk = "dpll_per_m2_div4_wkupdm_ck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +struct omap_hwmod am33xx_uart2_hwmod = { + .name = "uart2", + .class = &uart_class, + .clkdm_name = "l4ls_clkdm", + .flags = HWMOD_SWSUP_SIDLE_ACT, + .main_clk = "dpll_per_m2_div4_ck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* uart3 */ +struct omap_hwmod am33xx_uart3_hwmod = { + .name = "uart3", + .class = &uart_class, + .clkdm_name = "l4ls_clkdm", + .flags = HWMOD_SWSUP_SIDLE_ACT, + .main_clk = "dpll_per_m2_div4_ck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +struct omap_hwmod am33xx_uart4_hwmod = { + .name = "uart4", + .class = &uart_class, + .clkdm_name = "l4ls_clkdm", + .flags = HWMOD_SWSUP_SIDLE_ACT, + .main_clk = "dpll_per_m2_div4_ck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +struct omap_hwmod am33xx_uart5_hwmod = { + .name = "uart5", + .class = &uart_class, + .clkdm_name = "l4ls_clkdm", + .flags = HWMOD_SWSUP_SIDLE_ACT, + .main_clk = "dpll_per_m2_div4_ck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +struct omap_hwmod am33xx_uart6_hwmod = { + .name = "uart6", + .class = &uart_class, + .clkdm_name = "l4ls_clkdm", + .flags = HWMOD_SWSUP_SIDLE_ACT, + .main_clk = "dpll_per_m2_div4_ck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* 'wd_timer' class */ +static struct omap_hwmod_class_sysconfig wdt_sysc = { + .rev_offs = 0x0, + .sysc_offs = 0x10, + .syss_offs = 0x14, + .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class am33xx_wd_timer_hwmod_class = { + .name = "wd_timer", + .sysc = &wdt_sysc, + .pre_shutdown = &omap2_wd_timer_disable, +}; + +/* + * XXX: device.c file uses hardcoded name for watchdog timer + * driver "wd_timer2, so we are also using same name as of now... + */ +struct omap_hwmod am33xx_wd_timer1_hwmod = { + .name = "wd_timer2", + .class = &am33xx_wd_timer_hwmod_class, + .clkdm_name = "l4_wkup_clkdm", + .flags = HWMOD_SWSUP_SIDLE, + .main_clk = "wdt1_fck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +static void omap_hwmod_am33xx_clkctrl(void) +{ + CLKCTRL(am33xx_uart2_hwmod, AM33XX_CM_PER_UART1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_uart3_hwmod, AM33XX_CM_PER_UART2_CLKCTRL_OFFSET); + CLKCTRL(am33xx_uart4_hwmod, AM33XX_CM_PER_UART3_CLKCTRL_OFFSET); + CLKCTRL(am33xx_uart5_hwmod, AM33XX_CM_PER_UART4_CLKCTRL_OFFSET); + CLKCTRL(am33xx_uart6_hwmod, AM33XX_CM_PER_UART5_CLKCTRL_OFFSET); + CLKCTRL(am33xx_dcan0_hwmod, AM33XX_CM_PER_DCAN0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_dcan1_hwmod, AM33XX_CM_PER_DCAN1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_elm_hwmod, AM33XX_CM_PER_ELM_CLKCTRL_OFFSET); + CLKCTRL(am33xx_epwmss0_hwmod, AM33XX_CM_PER_EPWMSS0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_epwmss1_hwmod, AM33XX_CM_PER_EPWMSS1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_epwmss2_hwmod, AM33XX_CM_PER_EPWMSS2_CLKCTRL_OFFSET); + CLKCTRL(am33xx_gpio1_hwmod, AM33XX_CM_PER_GPIO1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_gpio2_hwmod, AM33XX_CM_PER_GPIO2_CLKCTRL_OFFSET); + CLKCTRL(am33xx_gpio3_hwmod, AM33XX_CM_PER_GPIO3_CLKCTRL_OFFSET); + CLKCTRL(am33xx_i2c2_hwmod, AM33XX_CM_PER_I2C1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_i2c3_hwmod, AM33XX_CM_PER_I2C2_CLKCTRL_OFFSET); + CLKCTRL(am33xx_mailbox_hwmod, AM33XX_CM_PER_MAILBOX0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_mcasp0_hwmod, AM33XX_CM_PER_MCASP0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_mcasp1_hwmod, AM33XX_CM_PER_MCASP1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_mmc0_hwmod, AM33XX_CM_PER_MMC0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_mmc1_hwmod, AM33XX_CM_PER_MMC1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_spi0_hwmod, AM33XX_CM_PER_SPI0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_spi1_hwmod, AM33XX_CM_PER_SPI1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_spinlock_hwmod, AM33XX_CM_PER_SPINLOCK_CLKCTRL_OFFSET); + CLKCTRL(am33xx_timer2_hwmod, AM33XX_CM_PER_TIMER2_CLKCTRL_OFFSET); + CLKCTRL(am33xx_timer3_hwmod, AM33XX_CM_PER_TIMER3_CLKCTRL_OFFSET); + CLKCTRL(am33xx_timer4_hwmod, AM33XX_CM_PER_TIMER4_CLKCTRL_OFFSET); + CLKCTRL(am33xx_timer5_hwmod, AM33XX_CM_PER_TIMER5_CLKCTRL_OFFSET); + CLKCTRL(am33xx_timer6_hwmod, AM33XX_CM_PER_TIMER6_CLKCTRL_OFFSET); + CLKCTRL(am33xx_timer7_hwmod, AM33XX_CM_PER_TIMER7_CLKCTRL_OFFSET); + CLKCTRL(am33xx_smartreflex0_hwmod, + AM33XX_CM_WKUP_SMARTREFLEX0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_smartreflex1_hwmod, + AM33XX_CM_WKUP_SMARTREFLEX1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_uart1_hwmod, AM33XX_CM_WKUP_UART0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_timer1_hwmod, AM33XX_CM_WKUP_TIMER1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_i2c1_hwmod, AM33XX_CM_WKUP_I2C0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_wd_timer1_hwmod, AM33XX_CM_WKUP_WDT1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_rtc_hwmod, AM33XX_CM_RTC_RTC_CLKCTRL_OFFSET); + CLKCTRL(am33xx_mmc2_hwmod, AM33XX_CM_PER_MMC2_CLKCTRL_OFFSET); + CLKCTRL(am33xx_gpmc_hwmod, AM33XX_CM_PER_GPMC_CLKCTRL_OFFSET); + CLKCTRL(am33xx_l4_ls_hwmod, AM33XX_CM_PER_L4LS_CLKCTRL_OFFSET); + CLKCTRL(am33xx_l4_wkup_hwmod, AM33XX_CM_WKUP_L4WKUP_CLKCTRL_OFFSET); + CLKCTRL(am33xx_l3_main_hwmod, AM33XX_CM_PER_L3_CLKCTRL_OFFSET); + CLKCTRL(am33xx_tpcc_hwmod, AM33XX_CM_PER_TPCC_CLKCTRL_OFFSET); + CLKCTRL(am33xx_tptc0_hwmod, AM33XX_CM_PER_TPTC0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_tptc1_hwmod, AM33XX_CM_PER_TPTC1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_tptc2_hwmod, AM33XX_CM_PER_TPTC2_CLKCTRL_OFFSET); + CLKCTRL(am33xx_gfx_hwmod, AM33XX_CM_GFX_GFX_CLKCTRL_OFFSET); + CLKCTRL(am33xx_cpgmac0_hwmod, AM33XX_CM_PER_CPGMAC0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_pruss_hwmod, AM33XX_CM_PER_PRUSS_CLKCTRL_OFFSET); + CLKCTRL(am33xx_mpu_hwmod , AM33XX_CM_MPU_MPU_CLKCTRL_OFFSET); + CLKCTRL(am33xx_l3_instr_hwmod , AM33XX_CM_PER_L3_INSTR_CLKCTRL_OFFSET); + CLKCTRL(am33xx_ocmcram_hwmod , AM33XX_CM_PER_OCMCRAM_CLKCTRL_OFFSET); + CLKCTRL(am33xx_sha0_hwmod , AM33XX_CM_PER_SHA0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_aes0_hwmod , AM33XX_CM_PER_AES0_CLKCTRL_OFFSET); +} + +static void omap_hwmod_am33xx_rst(void) +{ + RSTCTRL(am33xx_pruss_hwmod, AM33XX_RM_PER_RSTCTRL_OFFSET); + RSTCTRL(am33xx_gfx_hwmod, AM33XX_RM_GFX_RSTCTRL_OFFSET); + RSTST(am33xx_gfx_hwmod, AM33XX_RM_GFX_RSTST_OFFSET); +} + +void omap_hwmod_am33xx_reg(void) +{ + omap_hwmod_am33xx_clkctrl(); + omap_hwmod_am33xx_rst(); +} + +static void omap_hwmod_am43xx_clkctrl(void) +{ + CLKCTRL(am33xx_uart2_hwmod, AM43XX_CM_PER_UART1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_uart3_hwmod, AM43XX_CM_PER_UART2_CLKCTRL_OFFSET); + CLKCTRL(am33xx_uart4_hwmod, AM43XX_CM_PER_UART3_CLKCTRL_OFFSET); + CLKCTRL(am33xx_uart5_hwmod, AM43XX_CM_PER_UART4_CLKCTRL_OFFSET); + CLKCTRL(am33xx_uart6_hwmod, AM43XX_CM_PER_UART5_CLKCTRL_OFFSET); + CLKCTRL(am33xx_dcan0_hwmod, AM43XX_CM_PER_DCAN0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_dcan1_hwmod, AM43XX_CM_PER_DCAN1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_elm_hwmod, AM43XX_CM_PER_ELM_CLKCTRL_OFFSET); + CLKCTRL(am33xx_epwmss0_hwmod, AM43XX_CM_PER_EPWMSS0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_epwmss1_hwmod, AM43XX_CM_PER_EPWMSS1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_epwmss2_hwmod, AM43XX_CM_PER_EPWMSS2_CLKCTRL_OFFSET); + CLKCTRL(am33xx_gpio1_hwmod, AM43XX_CM_PER_GPIO1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_gpio2_hwmod, AM43XX_CM_PER_GPIO2_CLKCTRL_OFFSET); + CLKCTRL(am33xx_gpio3_hwmod, AM43XX_CM_PER_GPIO3_CLKCTRL_OFFSET); + CLKCTRL(am33xx_i2c2_hwmod, AM43XX_CM_PER_I2C1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_i2c3_hwmod, AM43XX_CM_PER_I2C2_CLKCTRL_OFFSET); + CLKCTRL(am33xx_mailbox_hwmod, AM43XX_CM_PER_MAILBOX0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_mcasp0_hwmod, AM43XX_CM_PER_MCASP0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_mcasp1_hwmod, AM43XX_CM_PER_MCASP1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_mmc0_hwmod, AM43XX_CM_PER_MMC0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_mmc1_hwmod, AM43XX_CM_PER_MMC1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_spi0_hwmod, AM43XX_CM_PER_SPI0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_spi1_hwmod, AM43XX_CM_PER_SPI1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_spinlock_hwmod, AM43XX_CM_PER_SPINLOCK_CLKCTRL_OFFSET); + CLKCTRL(am33xx_timer2_hwmod, AM43XX_CM_PER_TIMER2_CLKCTRL_OFFSET); + CLKCTRL(am33xx_timer3_hwmod, AM43XX_CM_PER_TIMER3_CLKCTRL_OFFSET); + CLKCTRL(am33xx_timer4_hwmod, AM43XX_CM_PER_TIMER4_CLKCTRL_OFFSET); + CLKCTRL(am33xx_timer5_hwmod, AM43XX_CM_PER_TIMER5_CLKCTRL_OFFSET); + CLKCTRL(am33xx_timer6_hwmod, AM43XX_CM_PER_TIMER6_CLKCTRL_OFFSET); + CLKCTRL(am33xx_timer7_hwmod, AM43XX_CM_PER_TIMER7_CLKCTRL_OFFSET); + CLKCTRL(am33xx_smartreflex0_hwmod, + AM43XX_CM_WKUP_SMARTREFLEX0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_smartreflex1_hwmod, + AM43XX_CM_WKUP_SMARTREFLEX1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_uart1_hwmod, AM43XX_CM_WKUP_UART0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_timer1_hwmod, AM43XX_CM_WKUP_TIMER1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_i2c1_hwmod, AM43XX_CM_WKUP_I2C0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_wd_timer1_hwmod, AM43XX_CM_WKUP_WDT1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_rtc_hwmod, AM43XX_CM_RTC_RTC_CLKCTRL_OFFSET); + CLKCTRL(am33xx_mmc2_hwmod, AM43XX_CM_PER_MMC2_CLKCTRL_OFFSET); + CLKCTRL(am33xx_gpmc_hwmod, AM43XX_CM_PER_GPMC_CLKCTRL_OFFSET); + CLKCTRL(am33xx_l4_ls_hwmod, AM43XX_CM_PER_L4LS_CLKCTRL_OFFSET); + CLKCTRL(am33xx_l4_wkup_hwmod, AM43XX_CM_WKUP_L4WKUP_CLKCTRL_OFFSET); + CLKCTRL(am33xx_l3_main_hwmod, AM43XX_CM_PER_L3_CLKCTRL_OFFSET); + CLKCTRL(am33xx_tpcc_hwmod, AM43XX_CM_PER_TPCC_CLKCTRL_OFFSET); + CLKCTRL(am33xx_tptc0_hwmod, AM43XX_CM_PER_TPTC0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_tptc1_hwmod, AM43XX_CM_PER_TPTC1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_tptc2_hwmod, AM43XX_CM_PER_TPTC2_CLKCTRL_OFFSET); + CLKCTRL(am33xx_gfx_hwmod, AM43XX_CM_GFX_GFX_CLKCTRL_OFFSET); + CLKCTRL(am33xx_cpgmac0_hwmod, AM43XX_CM_PER_CPGMAC0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_pruss_hwmod, AM43XX_CM_PER_PRUSS_CLKCTRL_OFFSET); + CLKCTRL(am33xx_mpu_hwmod , AM43XX_CM_MPU_MPU_CLKCTRL_OFFSET); + CLKCTRL(am33xx_l3_instr_hwmod , AM43XX_CM_PER_L3_INSTR_CLKCTRL_OFFSET); + CLKCTRL(am33xx_ocmcram_hwmod , AM43XX_CM_PER_OCMCRAM_CLKCTRL_OFFSET); + CLKCTRL(am33xx_sha0_hwmod , AM43XX_CM_PER_SHA0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_aes0_hwmod , AM43XX_CM_PER_AES0_CLKCTRL_OFFSET); +} + +static void omap_hwmod_am43xx_rst(void) +{ + RSTCTRL(am33xx_pruss_hwmod, AM43XX_RM_PER_RSTCTRL_OFFSET); + RSTCTRL(am33xx_gfx_hwmod, AM43XX_RM_GFX_RSTCTRL_OFFSET); + RSTST(am33xx_gfx_hwmod, AM43XX_RM_GFX_RSTST_OFFSET); +} + +void omap_hwmod_am43xx_reg(void) +{ + omap_hwmod_am43xx_clkctrl(); + omap_hwmod_am43xx_rst(); +} diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c index 215894f8910d..6b406ca4bd3b 100644 --- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c @@ -29,6 +29,7 @@ #include "i2c.h" #include "mmc.h" #include "wd_timer.h" +#include "omap_hwmod_33xx_43xx_common_data.h" /* * IP blocks @@ -52,7 +53,7 @@ static struct omap_hwmod am33xx_emif_hwmod = { .name = "emif", .class = &am33xx_emif_hwmod_class, .clkdm_name = "l3_clkdm", - .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), + .flags = HWMOD_INIT_NO_IDLE, .main_clk = "dpll_ddr_m2_div2_ck", .prcm = { .omap4 = { @@ -62,79 +63,12 @@ static struct omap_hwmod am33xx_emif_hwmod = { }, }; -/* - * 'l3' class - * instance(s): l3_main, l3_s, l3_instr - */ -static struct omap_hwmod_class am33xx_l3_hwmod_class = { - .name = "l3", -}; - -static struct omap_hwmod am33xx_l3_main_hwmod = { - .name = "l3_main", - .class = &am33xx_l3_hwmod_class, - .clkdm_name = "l3_clkdm", - .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), - .main_clk = "l3_gclk", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_L3_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* l3_s */ -static struct omap_hwmod am33xx_l3_s_hwmod = { - .name = "l3_s", - .class = &am33xx_l3_hwmod_class, - .clkdm_name = "l3s_clkdm", -}; - -/* l3_instr */ -static struct omap_hwmod am33xx_l3_instr_hwmod = { - .name = "l3_instr", - .class = &am33xx_l3_hwmod_class, - .clkdm_name = "l3_clkdm", - .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), - .main_clk = "l3_gclk", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_L3_INSTR_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* - * 'l4' class - * instance(s): l4_ls, l4_hs, l4_wkup, l4_fw - */ -static struct omap_hwmod_class am33xx_l4_hwmod_class = { - .name = "l4", -}; - -/* l4_ls */ -static struct omap_hwmod am33xx_l4_ls_hwmod = { - .name = "l4_ls", - .class = &am33xx_l4_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), - .main_clk = "l4ls_gclk", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_L4LS_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - /* l4_hs */ static struct omap_hwmod am33xx_l4_hs_hwmod = { .name = "l4_hs", .class = &am33xx_l4_hwmod_class, .clkdm_name = "l4hs_clkdm", - .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), + .flags = HWMOD_INIT_NO_IDLE, .main_clk = "l4hs_gclk", .prcm = { .omap4 = { @@ -144,50 +78,6 @@ static struct omap_hwmod am33xx_l4_hs_hwmod = { }, }; - -/* l4_wkup */ -static struct omap_hwmod am33xx_l4_wkup_hwmod = { - .name = "l4_wkup", - .class = &am33xx_l4_hwmod_class, - .clkdm_name = "l4_wkup_clkdm", - .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_WKUP_L4WKUP_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* - * 'mpu' class - */ -static struct omap_hwmod_class am33xx_mpu_hwmod_class = { - .name = "mpu", -}; - -static struct omap_hwmod am33xx_mpu_hwmod = { - .name = "mpu", - .class = &am33xx_mpu_hwmod_class, - .clkdm_name = "mpu_clkdm", - .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), - .main_clk = "dpll_mpu_m2_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_MPU_MPU_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* - * 'wakeup m3' class - * Wakeup controller sub-system under wakeup domain - */ -static struct omap_hwmod_class am33xx_wkup_m3_hwmod_class = { - .name = "wkup_m3", -}; - static struct omap_hwmod_rst_info am33xx_wkup_m3_resets[] = { { .name = "wkup_m3", .rst_shift = 3, .st_shift = 5 }, }; @@ -213,78 +103,6 @@ static struct omap_hwmod am33xx_wkup_m3_hwmod = { }; /* - * 'pru-icss' class - * Programmable Real-Time Unit and Industrial Communication Subsystem - */ -static struct omap_hwmod_class am33xx_pruss_hwmod_class = { - .name = "pruss", -}; - -static struct omap_hwmod_rst_info am33xx_pruss_resets[] = { - { .name = "pruss", .rst_shift = 1 }, -}; - -/* pru-icss */ -/* Pseudo hwmod for reset control purpose only */ -static struct omap_hwmod am33xx_pruss_hwmod = { - .name = "pruss", - .class = &am33xx_pruss_hwmod_class, - .clkdm_name = "pruss_ocp_clkdm", - .main_clk = "pruss_ocp_gclk", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_PRUSS_CLKCTRL_OFFSET, - .rstctrl_offs = AM33XX_RM_PER_RSTCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, - .rst_lines = am33xx_pruss_resets, - .rst_lines_cnt = ARRAY_SIZE(am33xx_pruss_resets), -}; - -/* gfx */ -/* Pseudo hwmod for reset control purpose only */ -static struct omap_hwmod_class am33xx_gfx_hwmod_class = { - .name = "gfx", -}; - -static struct omap_hwmod_rst_info am33xx_gfx_resets[] = { - { .name = "gfx", .rst_shift = 0, .st_shift = 0}, -}; - -static struct omap_hwmod am33xx_gfx_hwmod = { - .name = "gfx", - .class = &am33xx_gfx_hwmod_class, - .clkdm_name = "gfx_l3_clkdm", - .main_clk = "gfx_fck_div_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_GFX_GFX_CLKCTRL_OFFSET, - .rstctrl_offs = AM33XX_RM_GFX_RSTCTRL_OFFSET, - .rstst_offs = AM33XX_RM_GFX_RSTST_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, - .rst_lines = am33xx_gfx_resets, - .rst_lines_cnt = ARRAY_SIZE(am33xx_gfx_resets), -}; - -/* - * 'prcm' class - * power and reset manager (whole prcm infrastructure) - */ -static struct omap_hwmod_class am33xx_prcm_hwmod_class = { - .name = "prcm", -}; - -/* prcm */ -static struct omap_hwmod am33xx_prcm_hwmod = { - .name = "prcm", - .class = &am33xx_prcm_hwmod_class, - .clkdm_name = "l4_wkup_clkdm", -}; - -/* * 'adc/tsc' class * TouchScreen Controller (Anolog-To-Digital Converter) */ @@ -388,79 +206,6 @@ static struct omap_hwmod am33xx_ocpwp_hwmod = { #endif /* - * 'aes0' class - */ -static struct omap_hwmod_class_sysconfig am33xx_aes0_sysc = { - .rev_offs = 0x80, - .sysc_offs = 0x84, - .syss_offs = 0x88, - .sysc_flags = SYSS_HAS_RESET_STATUS, -}; - -static struct omap_hwmod_class am33xx_aes0_hwmod_class = { - .name = "aes0", - .sysc = &am33xx_aes0_sysc, -}; - -static struct omap_hwmod am33xx_aes0_hwmod = { - .name = "aes", - .class = &am33xx_aes0_hwmod_class, - .clkdm_name = "l3_clkdm", - .main_clk = "aes0_fck", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_AES0_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* sha0 HIB2 (the 'P' (public) device) */ -static struct omap_hwmod_class_sysconfig am33xx_sha0_sysc = { - .rev_offs = 0x100, - .sysc_offs = 0x110, - .syss_offs = 0x114, - .sysc_flags = SYSS_HAS_RESET_STATUS, -}; - -static struct omap_hwmod_class am33xx_sha0_hwmod_class = { - .name = "sha0", - .sysc = &am33xx_sha0_sysc, -}; - -static struct omap_hwmod am33xx_sha0_hwmod = { - .name = "sham", - .class = &am33xx_sha0_hwmod_class, - .clkdm_name = "l3_clkdm", - .main_clk = "l3_gclk", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_SHA0_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* ocmcram */ -static struct omap_hwmod_class am33xx_ocmcram_hwmod_class = { - .name = "ocmcram", -}; - -static struct omap_hwmod am33xx_ocmcram_hwmod = { - .name = "ocmcram", - .class = &am33xx_ocmcram_hwmod_class, - .clkdm_name = "l3_clkdm", - .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), - .main_clk = "l3_gclk", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_OCMCRAM_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* * 'debugss' class * debug sub system */ @@ -488,51 +233,11 @@ static struct omap_hwmod am33xx_debugss_hwmod = { .opt_clks_cnt = ARRAY_SIZE(debugss_opt_clks), }; -/* 'smartreflex' class */ -static struct omap_hwmod_class am33xx_smartreflex_hwmod_class = { - .name = "smartreflex", -}; - -/* smartreflex0 */ -static struct omap_hwmod am33xx_smartreflex0_hwmod = { - .name = "smartreflex0", - .class = &am33xx_smartreflex_hwmod_class, - .clkdm_name = "l4_wkup_clkdm", - .main_clk = "smartreflex0_fck", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_WKUP_SMARTREFLEX0_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* smartreflex1 */ -static struct omap_hwmod am33xx_smartreflex1_hwmod = { - .name = "smartreflex1", - .class = &am33xx_smartreflex_hwmod_class, - .clkdm_name = "l4_wkup_clkdm", - .main_clk = "smartreflex1_fck", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_WKUP_SMARTREFLEX1_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* - * 'control' module class - */ -static struct omap_hwmod_class am33xx_control_hwmod_class = { - .name = "control", -}; - static struct omap_hwmod am33xx_control_hwmod = { .name = "control", .class = &am33xx_control_hwmod_class, .clkdm_name = "l4_wkup_clkdm", - .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), + .flags = HWMOD_INIT_NO_IDLE, .main_clk = "dpll_core_m4_div2_ck", .prcm = { .omap4 = { @@ -542,288 +247,6 @@ static struct omap_hwmod am33xx_control_hwmod = { }, }; -/* - * 'cpgmac' class - * cpsw/cpgmac sub system - */ -static struct omap_hwmod_class_sysconfig am33xx_cpgmac_sysc = { - .rev_offs = 0x0, - .sysc_offs = 0x8, - .syss_offs = 0x4, - .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE | - SYSS_HAS_RESET_STATUS), - .idlemodes = (SIDLE_FORCE | SIDLE_NO | MSTANDBY_FORCE | - MSTANDBY_NO), - .sysc_fields = &omap_hwmod_sysc_type3, -}; - -static struct omap_hwmod_class am33xx_cpgmac0_hwmod_class = { - .name = "cpgmac0", - .sysc = &am33xx_cpgmac_sysc, -}; - -static struct omap_hwmod am33xx_cpgmac0_hwmod = { - .name = "cpgmac0", - .class = &am33xx_cpgmac0_hwmod_class, - .clkdm_name = "cpsw_125mhz_clkdm", - .flags = (HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY), - .main_clk = "cpsw_125mhz_gclk", - .mpu_rt_idx = 1, - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_CPGMAC0_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* - * mdio class - */ -static struct omap_hwmod_class am33xx_mdio_hwmod_class = { - .name = "davinci_mdio", -}; - -static struct omap_hwmod am33xx_mdio_hwmod = { - .name = "davinci_mdio", - .class = &am33xx_mdio_hwmod_class, - .clkdm_name = "cpsw_125mhz_clkdm", - .main_clk = "cpsw_125mhz_gclk", -}; - -/* - * dcan class - */ -static struct omap_hwmod_class am33xx_dcan_hwmod_class = { - .name = "d_can", -}; - -/* dcan0 */ -static struct omap_hwmod am33xx_dcan0_hwmod = { - .name = "d_can0", - .class = &am33xx_dcan_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .main_clk = "dcan0_fck", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_DCAN0_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* dcan1 */ -static struct omap_hwmod am33xx_dcan1_hwmod = { - .name = "d_can1", - .class = &am33xx_dcan_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .main_clk = "dcan1_fck", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_DCAN1_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* elm */ -static struct omap_hwmod_class_sysconfig am33xx_elm_sysc = { - .rev_offs = 0x0000, - .sysc_offs = 0x0010, - .syss_offs = 0x0014, - .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE | - SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE | - SYSS_HAS_RESET_STATUS), - .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), - .sysc_fields = &omap_hwmod_sysc_type1, -}; - -static struct omap_hwmod_class am33xx_elm_hwmod_class = { - .name = "elm", - .sysc = &am33xx_elm_sysc, -}; - -static struct omap_hwmod am33xx_elm_hwmod = { - .name = "elm", - .class = &am33xx_elm_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .main_clk = "l4ls_gclk", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_ELM_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* pwmss */ -static struct omap_hwmod_class_sysconfig am33xx_epwmss_sysc = { - .rev_offs = 0x0, - .sysc_offs = 0x4, - .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE), - .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | - SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO | - MSTANDBY_SMART | MSTANDBY_SMART_WKUP), - .sysc_fields = &omap_hwmod_sysc_type2, -}; - -static struct omap_hwmod_class am33xx_epwmss_hwmod_class = { - .name = "epwmss", - .sysc = &am33xx_epwmss_sysc, -}; - -static struct omap_hwmod_class am33xx_ecap_hwmod_class = { - .name = "ecap", -}; - -static struct omap_hwmod_class am33xx_eqep_hwmod_class = { - .name = "eqep", -}; - -static struct omap_hwmod_class am33xx_ehrpwm_hwmod_class = { - .name = "ehrpwm", -}; - -/* epwmss0 */ -static struct omap_hwmod am33xx_epwmss0_hwmod = { - .name = "epwmss0", - .class = &am33xx_epwmss_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .main_clk = "l4ls_gclk", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_EPWMSS0_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* ecap0 */ -static struct omap_hwmod am33xx_ecap0_hwmod = { - .name = "ecap0", - .class = &am33xx_ecap_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .main_clk = "l4ls_gclk", -}; - -/* eqep0 */ -static struct omap_hwmod am33xx_eqep0_hwmod = { - .name = "eqep0", - .class = &am33xx_eqep_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .main_clk = "l4ls_gclk", -}; - -/* ehrpwm0 */ -static struct omap_hwmod am33xx_ehrpwm0_hwmod = { - .name = "ehrpwm0", - .class = &am33xx_ehrpwm_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .main_clk = "l4ls_gclk", -}; - -/* epwmss1 */ -static struct omap_hwmod am33xx_epwmss1_hwmod = { - .name = "epwmss1", - .class = &am33xx_epwmss_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .main_clk = "l4ls_gclk", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_EPWMSS1_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* ecap1 */ -static struct omap_hwmod am33xx_ecap1_hwmod = { - .name = "ecap1", - .class = &am33xx_ecap_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .main_clk = "l4ls_gclk", -}; - -/* eqep1 */ -static struct omap_hwmod am33xx_eqep1_hwmod = { - .name = "eqep1", - .class = &am33xx_eqep_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .main_clk = "l4ls_gclk", -}; - -/* ehrpwm1 */ -static struct omap_hwmod am33xx_ehrpwm1_hwmod = { - .name = "ehrpwm1", - .class = &am33xx_ehrpwm_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .main_clk = "l4ls_gclk", -}; - -/* epwmss2 */ -static struct omap_hwmod am33xx_epwmss2_hwmod = { - .name = "epwmss2", - .class = &am33xx_epwmss_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .main_clk = "l4ls_gclk", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_EPWMSS2_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* ecap2 */ -static struct omap_hwmod am33xx_ecap2_hwmod = { - .name = "ecap2", - .class = &am33xx_ecap_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .main_clk = "l4ls_gclk", -}; - -/* eqep2 */ -static struct omap_hwmod am33xx_eqep2_hwmod = { - .name = "eqep2", - .class = &am33xx_eqep_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .main_clk = "l4ls_gclk", -}; - -/* ehrpwm2 */ -static struct omap_hwmod am33xx_ehrpwm2_hwmod = { - .name = "ehrpwm2", - .class = &am33xx_ehrpwm_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .main_clk = "l4ls_gclk", -}; - -/* - * 'gpio' class: for gpio 0,1,2,3 - */ -static struct omap_hwmod_class_sysconfig am33xx_gpio_sysc = { - .rev_offs = 0x0000, - .sysc_offs = 0x0010, - .syss_offs = 0x0114, - .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_ENAWAKEUP | - SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | - SYSS_HAS_RESET_STATUS), - .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | - SIDLE_SMART_WKUP), - .sysc_fields = &omap_hwmod_sysc_type1, -}; - -static struct omap_hwmod_class am33xx_gpio_hwmod_class = { - .name = "gpio", - .sysc = &am33xx_gpio_sysc, - .rev = 2, -}; - -static struct omap_gpio_dev_attr gpio_dev_attr = { - .bank_width = 32, - .dbck_flag = true, -}; - /* gpio0 */ static struct omap_hwmod_opt_clk gpio0_opt_clks[] = { { .role = "dbclk", .clk = "gpio0_dbclk" }, @@ -846,174 +269,6 @@ static struct omap_hwmod am33xx_gpio0_hwmod = { .dev_attr = &gpio_dev_attr, }; -/* gpio1 */ -static struct omap_hwmod_opt_clk gpio1_opt_clks[] = { - { .role = "dbclk", .clk = "gpio1_dbclk" }, -}; - -static struct omap_hwmod am33xx_gpio1_hwmod = { - .name = "gpio2", - .class = &am33xx_gpio_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, - .main_clk = "l4ls_gclk", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_GPIO1_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, - .opt_clks = gpio1_opt_clks, - .opt_clks_cnt = ARRAY_SIZE(gpio1_opt_clks), - .dev_attr = &gpio_dev_attr, -}; - -/* gpio2 */ -static struct omap_hwmod_opt_clk gpio2_opt_clks[] = { - { .role = "dbclk", .clk = "gpio2_dbclk" }, -}; - -static struct omap_hwmod am33xx_gpio2_hwmod = { - .name = "gpio3", - .class = &am33xx_gpio_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, - .main_clk = "l4ls_gclk", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_GPIO2_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, - .opt_clks = gpio2_opt_clks, - .opt_clks_cnt = ARRAY_SIZE(gpio2_opt_clks), - .dev_attr = &gpio_dev_attr, -}; - -/* gpio3 */ -static struct omap_hwmod_opt_clk gpio3_opt_clks[] = { - { .role = "dbclk", .clk = "gpio3_dbclk" }, -}; - -static struct omap_hwmod am33xx_gpio3_hwmod = { - .name = "gpio4", - .class = &am33xx_gpio_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, - .main_clk = "l4ls_gclk", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_GPIO3_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, - .opt_clks = gpio3_opt_clks, - .opt_clks_cnt = ARRAY_SIZE(gpio3_opt_clks), - .dev_attr = &gpio_dev_attr, -}; - -/* gpmc */ -static struct omap_hwmod_class_sysconfig gpmc_sysc = { - .rev_offs = 0x0, - .sysc_offs = 0x10, - .syss_offs = 0x14, - .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE | - SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), - .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), - .sysc_fields = &omap_hwmod_sysc_type1, -}; - -static struct omap_hwmod_class am33xx_gpmc_hwmod_class = { - .name = "gpmc", - .sysc = &gpmc_sysc, -}; - -static struct omap_hwmod am33xx_gpmc_hwmod = { - .name = "gpmc", - .class = &am33xx_gpmc_hwmod_class, - .clkdm_name = "l3s_clkdm", - .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), - .main_clk = "l3s_gclk", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_GPMC_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* 'i2c' class */ -static struct omap_hwmod_class_sysconfig am33xx_i2c_sysc = { - .sysc_offs = 0x0010, - .syss_offs = 0x0090, - .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | - SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | - SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), - .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | - SIDLE_SMART_WKUP), - .sysc_fields = &omap_hwmod_sysc_type1, -}; - -static struct omap_hwmod_class i2c_class = { - .name = "i2c", - .sysc = &am33xx_i2c_sysc, - .rev = OMAP_I2C_IP_VERSION_2, - .reset = &omap_i2c_reset, -}; - -static struct omap_i2c_dev_attr i2c_dev_attr = { - .flags = OMAP_I2C_FLAG_BUS_SHIFT_NONE, -}; - -/* i2c1 */ -static struct omap_hwmod am33xx_i2c1_hwmod = { - .name = "i2c1", - .class = &i2c_class, - .clkdm_name = "l4_wkup_clkdm", - .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, - .main_clk = "dpll_per_m2_div4_wkupdm_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_WKUP_I2C0_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, - .dev_attr = &i2c_dev_attr, -}; - -/* i2c1 */ -static struct omap_hwmod am33xx_i2c2_hwmod = { - .name = "i2c2", - .class = &i2c_class, - .clkdm_name = "l4ls_clkdm", - .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, - .main_clk = "dpll_per_m2_div4_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_I2C1_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, - .dev_attr = &i2c_dev_attr, -}; - -/* i2c3 */ -static struct omap_hwmod am33xx_i2c3_hwmod = { - .name = "i2c3", - .class = &i2c_class, - .clkdm_name = "l4ls_clkdm", - .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, - .main_clk = "dpll_per_m2_div4_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_I2C2_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, - .dev_attr = &i2c_dev_attr, -}; - - /* lcdc */ static struct omap_hwmod_class_sysconfig lcdc_sysc = { .rev_offs = 0x0, @@ -1043,600 +298,6 @@ static struct omap_hwmod am33xx_lcdc_hwmod = { }; /* - * 'mailbox' class - * mailbox module allowing communication between the on-chip processors using a - * queued mailbox-interrupt mechanism. - */ -static struct omap_hwmod_class_sysconfig am33xx_mailbox_sysc = { - .rev_offs = 0x0000, - .sysc_offs = 0x0010, - .sysc_flags = (SYSC_HAS_RESET_STATUS | SYSC_HAS_SIDLEMODE | - SYSC_HAS_SOFTRESET), - .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), - .sysc_fields = &omap_hwmod_sysc_type2, -}; - -static struct omap_hwmod_class am33xx_mailbox_hwmod_class = { - .name = "mailbox", - .sysc = &am33xx_mailbox_sysc, -}; - -static struct omap_hwmod am33xx_mailbox_hwmod = { - .name = "mailbox", - .class = &am33xx_mailbox_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .main_clk = "l4ls_gclk", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_MAILBOX0_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* - * 'mcasp' class - */ -static struct omap_hwmod_class_sysconfig am33xx_mcasp_sysc = { - .rev_offs = 0x0, - .sysc_offs = 0x4, - .sysc_flags = SYSC_HAS_SIDLEMODE, - .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), - .sysc_fields = &omap_hwmod_sysc_type3, -}; - -static struct omap_hwmod_class am33xx_mcasp_hwmod_class = { - .name = "mcasp", - .sysc = &am33xx_mcasp_sysc, -}; - -/* mcasp0 */ -static struct omap_hwmod am33xx_mcasp0_hwmod = { - .name = "mcasp0", - .class = &am33xx_mcasp_hwmod_class, - .clkdm_name = "l3s_clkdm", - .main_clk = "mcasp0_fck", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_MCASP0_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* mcasp1 */ -static struct omap_hwmod am33xx_mcasp1_hwmod = { - .name = "mcasp1", - .class = &am33xx_mcasp_hwmod_class, - .clkdm_name = "l3s_clkdm", - .main_clk = "mcasp1_fck", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_MCASP1_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* 'mmc' class */ -static struct omap_hwmod_class_sysconfig am33xx_mmc_sysc = { - .rev_offs = 0x1fc, - .sysc_offs = 0x10, - .syss_offs = 0x14, - .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE | - SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | - SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS), - .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), - .sysc_fields = &omap_hwmod_sysc_type1, -}; - -static struct omap_hwmod_class am33xx_mmc_hwmod_class = { - .name = "mmc", - .sysc = &am33xx_mmc_sysc, -}; - -/* mmc0 */ -static struct omap_mmc_dev_attr am33xx_mmc0_dev_attr = { - .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT, -}; - -static struct omap_hwmod am33xx_mmc0_hwmod = { - .name = "mmc1", - .class = &am33xx_mmc_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .main_clk = "mmc_clk", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_MMC0_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, - .dev_attr = &am33xx_mmc0_dev_attr, -}; - -/* mmc1 */ -static struct omap_mmc_dev_attr am33xx_mmc1_dev_attr = { - .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT, -}; - -static struct omap_hwmod am33xx_mmc1_hwmod = { - .name = "mmc2", - .class = &am33xx_mmc_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .main_clk = "mmc_clk", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_MMC1_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, - .dev_attr = &am33xx_mmc1_dev_attr, -}; - -/* mmc2 */ -static struct omap_mmc_dev_attr am33xx_mmc2_dev_attr = { - .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT, -}; -static struct omap_hwmod am33xx_mmc2_hwmod = { - .name = "mmc3", - .class = &am33xx_mmc_hwmod_class, - .clkdm_name = "l3s_clkdm", - .main_clk = "mmc_clk", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_MMC2_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, - .dev_attr = &am33xx_mmc2_dev_attr, -}; - -/* - * 'rtc' class - * rtc subsystem - */ -static struct omap_hwmod_class_sysconfig am33xx_rtc_sysc = { - .rev_offs = 0x0074, - .sysc_offs = 0x0078, - .sysc_flags = SYSC_HAS_SIDLEMODE, - .idlemodes = (SIDLE_FORCE | SIDLE_NO | - SIDLE_SMART | SIDLE_SMART_WKUP), - .sysc_fields = &omap_hwmod_sysc_type3, -}; - -static struct omap_hwmod_class am33xx_rtc_hwmod_class = { - .name = "rtc", - .sysc = &am33xx_rtc_sysc, -}; - -static struct omap_hwmod am33xx_rtc_hwmod = { - .name = "rtc", - .class = &am33xx_rtc_hwmod_class, - .clkdm_name = "l4_rtc_clkdm", - .main_clk = "clk_32768_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_RTC_RTC_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* 'spi' class */ -static struct omap_hwmod_class_sysconfig am33xx_mcspi_sysc = { - .rev_offs = 0x0000, - .sysc_offs = 0x0110, - .syss_offs = 0x0114, - .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE | - SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE | - SYSS_HAS_RESET_STATUS), - .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), - .sysc_fields = &omap_hwmod_sysc_type1, -}; - -static struct omap_hwmod_class am33xx_spi_hwmod_class = { - .name = "mcspi", - .sysc = &am33xx_mcspi_sysc, - .rev = OMAP4_MCSPI_REV, -}; - -/* spi0 */ -static struct omap2_mcspi_dev_attr mcspi_attrib = { - .num_chipselect = 2, -}; -static struct omap_hwmod am33xx_spi0_hwmod = { - .name = "spi0", - .class = &am33xx_spi_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .main_clk = "dpll_per_m2_div4_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_SPI0_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, - .dev_attr = &mcspi_attrib, -}; - -/* spi1 */ -static struct omap_hwmod am33xx_spi1_hwmod = { - .name = "spi1", - .class = &am33xx_spi_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .main_clk = "dpll_per_m2_div4_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_SPI1_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, - .dev_attr = &mcspi_attrib, -}; - -/* - * 'spinlock' class - * spinlock provides hardware assistance for synchronizing the - * processes running on multiple processors - */ -static struct omap_hwmod_class am33xx_spinlock_hwmod_class = { - .name = "spinlock", -}; - -static struct omap_hwmod am33xx_spinlock_hwmod = { - .name = "spinlock", - .class = &am33xx_spinlock_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .main_clk = "l4ls_gclk", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_SPINLOCK_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* 'timer 2-7' class */ -static struct omap_hwmod_class_sysconfig am33xx_timer_sysc = { - .rev_offs = 0x0000, - .sysc_offs = 0x0010, - .syss_offs = 0x0014, - .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET), - .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | - SIDLE_SMART_WKUP), - .sysc_fields = &omap_hwmod_sysc_type2, -}; - -static struct omap_hwmod_class am33xx_timer_hwmod_class = { - .name = "timer", - .sysc = &am33xx_timer_sysc, -}; - -/* timer1 1ms */ -static struct omap_hwmod_class_sysconfig am33xx_timer1ms_sysc = { - .rev_offs = 0x0000, - .sysc_offs = 0x0010, - .syss_offs = 0x0014, - .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE | - SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE | - SYSS_HAS_RESET_STATUS), - .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), - .sysc_fields = &omap_hwmod_sysc_type1, -}; - -static struct omap_hwmod_class am33xx_timer1ms_hwmod_class = { - .name = "timer", - .sysc = &am33xx_timer1ms_sysc, -}; - -static struct omap_hwmod am33xx_timer1_hwmod = { - .name = "timer1", - .class = &am33xx_timer1ms_hwmod_class, - .clkdm_name = "l4_wkup_clkdm", - .main_clk = "timer1_fck", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_WKUP_TIMER1_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -static struct omap_hwmod am33xx_timer2_hwmod = { - .name = "timer2", - .class = &am33xx_timer_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .main_clk = "timer2_fck", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_TIMER2_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -static struct omap_hwmod am33xx_timer3_hwmod = { - .name = "timer3", - .class = &am33xx_timer_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .main_clk = "timer3_fck", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_TIMER3_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -static struct omap_hwmod am33xx_timer4_hwmod = { - .name = "timer4", - .class = &am33xx_timer_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .main_clk = "timer4_fck", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_TIMER4_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -static struct omap_hwmod am33xx_timer5_hwmod = { - .name = "timer5", - .class = &am33xx_timer_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .main_clk = "timer5_fck", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_TIMER5_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -static struct omap_hwmod am33xx_timer6_hwmod = { - .name = "timer6", - .class = &am33xx_timer_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .main_clk = "timer6_fck", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_TIMER6_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -static struct omap_hwmod am33xx_timer7_hwmod = { - .name = "timer7", - .class = &am33xx_timer_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .main_clk = "timer7_fck", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_TIMER7_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* tpcc */ -static struct omap_hwmod_class am33xx_tpcc_hwmod_class = { - .name = "tpcc", -}; - -static struct omap_hwmod am33xx_tpcc_hwmod = { - .name = "tpcc", - .class = &am33xx_tpcc_hwmod_class, - .clkdm_name = "l3_clkdm", - .main_clk = "l3_gclk", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_TPCC_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -static struct omap_hwmod_class_sysconfig am33xx_tptc_sysc = { - .rev_offs = 0x0, - .sysc_offs = 0x10, - .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | - SYSC_HAS_MIDLEMODE), - .idlemodes = (SIDLE_FORCE | SIDLE_SMART | MSTANDBY_FORCE), - .sysc_fields = &omap_hwmod_sysc_type2, -}; - -/* 'tptc' class */ -static struct omap_hwmod_class am33xx_tptc_hwmod_class = { - .name = "tptc", - .sysc = &am33xx_tptc_sysc, -}; - -/* tptc0 */ -static struct omap_hwmod am33xx_tptc0_hwmod = { - .name = "tptc0", - .class = &am33xx_tptc_hwmod_class, - .clkdm_name = "l3_clkdm", - .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY, - .main_clk = "l3_gclk", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_TPTC0_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* tptc1 */ -static struct omap_hwmod am33xx_tptc1_hwmod = { - .name = "tptc1", - .class = &am33xx_tptc_hwmod_class, - .clkdm_name = "l3_clkdm", - .flags = (HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY), - .main_clk = "l3_gclk", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_TPTC1_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* tptc2 */ -static struct omap_hwmod am33xx_tptc2_hwmod = { - .name = "tptc2", - .class = &am33xx_tptc_hwmod_class, - .clkdm_name = "l3_clkdm", - .flags = (HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY), - .main_clk = "l3_gclk", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_TPTC2_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* 'uart' class */ -static struct omap_hwmod_class_sysconfig uart_sysc = { - .rev_offs = 0x50, - .sysc_offs = 0x54, - .syss_offs = 0x58, - .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_ENAWAKEUP | - SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), - .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | - SIDLE_SMART_WKUP), - .sysc_fields = &omap_hwmod_sysc_type1, -}; - -static struct omap_hwmod_class uart_class = { - .name = "uart", - .sysc = &uart_sysc, -}; - -/* uart1 */ -static struct omap_hwmod am33xx_uart1_hwmod = { - .name = "uart1", - .class = &uart_class, - .clkdm_name = "l4_wkup_clkdm", - .flags = DEBUG_AM33XXUART1_FLAGS | HWMOD_SWSUP_SIDLE_ACT, - .main_clk = "dpll_per_m2_div4_wkupdm_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_WKUP_UART0_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -static struct omap_hwmod am33xx_uart2_hwmod = { - .name = "uart2", - .class = &uart_class, - .clkdm_name = "l4ls_clkdm", - .flags = HWMOD_SWSUP_SIDLE_ACT, - .main_clk = "dpll_per_m2_div4_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_UART1_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* uart3 */ -static struct omap_hwmod am33xx_uart3_hwmod = { - .name = "uart3", - .class = &uart_class, - .clkdm_name = "l4ls_clkdm", - .flags = HWMOD_SWSUP_SIDLE_ACT, - .main_clk = "dpll_per_m2_div4_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_UART2_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -static struct omap_hwmod am33xx_uart4_hwmod = { - .name = "uart4", - .class = &uart_class, - .clkdm_name = "l4ls_clkdm", - .flags = HWMOD_SWSUP_SIDLE_ACT, - .main_clk = "dpll_per_m2_div4_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_UART3_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -static struct omap_hwmod am33xx_uart5_hwmod = { - .name = "uart5", - .class = &uart_class, - .clkdm_name = "l4ls_clkdm", - .flags = HWMOD_SWSUP_SIDLE_ACT, - .main_clk = "dpll_per_m2_div4_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_UART4_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -static struct omap_hwmod am33xx_uart6_hwmod = { - .name = "uart6", - .class = &uart_class, - .clkdm_name = "l4ls_clkdm", - .flags = HWMOD_SWSUP_SIDLE_ACT, - .main_clk = "dpll_per_m2_div4_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_UART5_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* 'wd_timer' class */ -static struct omap_hwmod_class_sysconfig wdt_sysc = { - .rev_offs = 0x0, - .sysc_offs = 0x10, - .syss_offs = 0x14, - .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_SIDLEMODE | - SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), - .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | - SIDLE_SMART_WKUP), - .sysc_fields = &omap_hwmod_sysc_type1, -}; - -static struct omap_hwmod_class am33xx_wd_timer_hwmod_class = { - .name = "wd_timer", - .sysc = &wdt_sysc, - .pre_shutdown = &omap2_wd_timer_disable, -}; - -/* - * XXX: device.c file uses hardcoded name for watchdog timer - * driver "wd_timer2, so we are also using same name as of now... - */ -static struct omap_hwmod am33xx_wd_timer1_hwmod = { - .name = "wd_timer2", - .class = &am33xx_wd_timer_hwmod_class, - .clkdm_name = "l4_wkup_clkdm", - .flags = HWMOD_SWSUP_SIDLE, - .main_clk = "wdt1_fck", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_WKUP_WDT1_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* * 'usb_otg' class * high-speed on-the-go universal serial bus (usb_otg) controller */ @@ -1690,14 +351,6 @@ static struct omap_hwmod_ocp_if am33xx_l3_main__emif = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; -/* mpu -> l3 main */ -static struct omap_hwmod_ocp_if am33xx_mpu__l3_main = { - .master = &am33xx_mpu_hwmod, - .slave = &am33xx_l3_main_hwmod, - .clk = "dpll_mpu_m2_ck", - .user = OCP_USER_MPU, -}; - /* l3 main -> l4 hs */ static struct omap_hwmod_ocp_if am33xx_l3_main__l4_hs = { .master = &am33xx_l3_main_hwmod, @@ -1706,62 +359,6 @@ static struct omap_hwmod_ocp_if am33xx_l3_main__l4_hs = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; -/* l3 main -> l3 s */ -static struct omap_hwmod_ocp_if am33xx_l3_main__l3_s = { - .master = &am33xx_l3_main_hwmod, - .slave = &am33xx_l3_s_hwmod, - .clk = "l3s_gclk", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* l3 s -> l4 per/ls */ -static struct omap_hwmod_ocp_if am33xx_l3_s__l4_ls = { - .master = &am33xx_l3_s_hwmod, - .slave = &am33xx_l4_ls_hwmod, - .clk = "l3s_gclk", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* l3 s -> l4 wkup */ -static struct omap_hwmod_ocp_if am33xx_l3_s__l4_wkup = { - .master = &am33xx_l3_s_hwmod, - .slave = &am33xx_l4_wkup_hwmod, - .clk = "l3s_gclk", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* l3 main -> l3 instr */ -static struct omap_hwmod_ocp_if am33xx_l3_main__l3_instr = { - .master = &am33xx_l3_main_hwmod, - .slave = &am33xx_l3_instr_hwmod, - .clk = "l3s_gclk", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* mpu -> prcm */ -static struct omap_hwmod_ocp_if am33xx_mpu__prcm = { - .master = &am33xx_mpu_hwmod, - .slave = &am33xx_prcm_hwmod, - .clk = "dpll_mpu_m2_ck", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* l3 s -> l3 main*/ -static struct omap_hwmod_ocp_if am33xx_l3_s__l3_main = { - .master = &am33xx_l3_s_hwmod, - .slave = &am33xx_l3_main_hwmod, - .clk = "l3s_gclk", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* pru-icss -> l3 main */ -static struct omap_hwmod_ocp_if am33xx_pruss__l3_main = { - .master = &am33xx_pruss_hwmod, - .slave = &am33xx_l3_main_hwmod, - .clk = "l3_gclk", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - /* wkup m3 -> l4 wkup */ static struct omap_hwmod_ocp_if am33xx_wkup_m3__l4_wkup = { .master = &am33xx_wkup_m3_hwmod, @@ -1770,14 +367,6 @@ static struct omap_hwmod_ocp_if am33xx_wkup_m3__l4_wkup = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; -/* gfx -> l3 main */ -static struct omap_hwmod_ocp_if am33xx_gfx__l3_main = { - .master = &am33xx_gfx_hwmod, - .slave = &am33xx_l3_main_hwmod, - .clk = "dpll_core_m4_ck", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - /* l4 wkup -> wkup m3 */ static struct omap_hwmod_ocp_if am33xx_l4_wkup__wkup_m3 = { .master = &am33xx_l4_wkup_hwmod, @@ -1794,14 +383,6 @@ static struct omap_hwmod_ocp_if am33xx_l4_hs__pruss = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; -/* l3 main -> gfx */ -static struct omap_hwmod_ocp_if am33xx_l3_main__gfx = { - .master = &am33xx_l3_main_hwmod, - .slave = &am33xx_gfx_hwmod, - .clk = "dpll_core_m4_ck", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - /* l3_main -> debugss */ static struct omap_hwmod_addr_space am33xx_debugss_addrs[] = { { @@ -1844,54 +425,6 @@ static struct omap_hwmod_ocp_if am33xx_l4_wkup__control = { .user = OCP_USER_MPU, }; -/* l4 wkup -> rtc */ -static struct omap_hwmod_ocp_if am33xx_l4_wkup__rtc = { - .master = &am33xx_l4_wkup_hwmod, - .slave = &am33xx_rtc_hwmod, - .clk = "clkdiv32k_ick", - .user = OCP_USER_MPU, -}; - -/* l4 per/ls -> DCAN0 */ -static struct omap_hwmod_ocp_if am33xx_l4_per__dcan0 = { - .master = &am33xx_l4_ls_hwmod, - .slave = &am33xx_dcan0_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* l4 per/ls -> DCAN1 */ -static struct omap_hwmod_ocp_if am33xx_l4_per__dcan1 = { - .master = &am33xx_l4_ls_hwmod, - .slave = &am33xx_dcan1_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* l4 per/ls -> GPIO2 */ -static struct omap_hwmod_ocp_if am33xx_l4_per__gpio1 = { - .master = &am33xx_l4_ls_hwmod, - .slave = &am33xx_gpio1_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* l4 per/ls -> gpio3 */ -static struct omap_hwmod_ocp_if am33xx_l4_per__gpio2 = { - .master = &am33xx_l4_ls_hwmod, - .slave = &am33xx_gpio2_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* l4 per/ls -> gpio4 */ -static struct omap_hwmod_ocp_if am33xx_l4_per__gpio3 = { - .master = &am33xx_l4_ls_hwmod, - .slave = &am33xx_gpio3_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - /* L4 WKUP -> I2C1 */ static struct omap_hwmod_ocp_if am33xx_l4_wkup__i2c1 = { .master = &am33xx_l4_wkup_hwmod, @@ -1933,177 +466,6 @@ static struct omap_hwmod_ocp_if am33xx_l4_hs__cpgmac0 = { .user = OCP_USER_MPU, }; -static struct omap_hwmod_ocp_if am33xx_cpgmac0__mdio = { - .master = &am33xx_cpgmac0_hwmod, - .slave = &am33xx_mdio_hwmod, - .user = OCP_USER_MPU, -}; - -static struct omap_hwmod_addr_space am33xx_elm_addr_space[] = { - { - .pa_start = 0x48080000, - .pa_end = 0x48080000 + SZ_8K - 1, - .flags = ADDR_TYPE_RT - }, - { } -}; - -static struct omap_hwmod_ocp_if am33xx_l4_ls__elm = { - .master = &am33xx_l4_ls_hwmod, - .slave = &am33xx_elm_hwmod, - .clk = "l4ls_gclk", - .addr = am33xx_elm_addr_space, - .user = OCP_USER_MPU, -}; - -static struct omap_hwmod_addr_space am33xx_epwmss0_addr_space[] = { - { - .pa_start = 0x48300000, - .pa_end = 0x48300000 + SZ_16 - 1, - .flags = ADDR_TYPE_RT - }, - { } -}; - -static struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss0 = { - .master = &am33xx_l4_ls_hwmod, - .slave = &am33xx_epwmss0_hwmod, - .clk = "l4ls_gclk", - .addr = am33xx_epwmss0_addr_space, - .user = OCP_USER_MPU, -}; - -static struct omap_hwmod_ocp_if am33xx_epwmss0__ecap0 = { - .master = &am33xx_epwmss0_hwmod, - .slave = &am33xx_ecap0_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU, -}; - -static struct omap_hwmod_ocp_if am33xx_epwmss0__eqep0 = { - .master = &am33xx_epwmss0_hwmod, - .slave = &am33xx_eqep0_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU, -}; - -static struct omap_hwmod_ocp_if am33xx_epwmss0__ehrpwm0 = { - .master = &am33xx_epwmss0_hwmod, - .slave = &am33xx_ehrpwm0_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU, -}; - - -static struct omap_hwmod_addr_space am33xx_epwmss1_addr_space[] = { - { - .pa_start = 0x48302000, - .pa_end = 0x48302000 + SZ_16 - 1, - .flags = ADDR_TYPE_RT - }, - { } -}; - -static struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss1 = { - .master = &am33xx_l4_ls_hwmod, - .slave = &am33xx_epwmss1_hwmod, - .clk = "l4ls_gclk", - .addr = am33xx_epwmss1_addr_space, - .user = OCP_USER_MPU, -}; - -static struct omap_hwmod_ocp_if am33xx_epwmss1__ecap1 = { - .master = &am33xx_epwmss1_hwmod, - .slave = &am33xx_ecap1_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU, -}; - -static struct omap_hwmod_ocp_if am33xx_epwmss1__eqep1 = { - .master = &am33xx_epwmss1_hwmod, - .slave = &am33xx_eqep1_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU, -}; - -static struct omap_hwmod_ocp_if am33xx_epwmss1__ehrpwm1 = { - .master = &am33xx_epwmss1_hwmod, - .slave = &am33xx_ehrpwm1_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU, -}; - -static struct omap_hwmod_addr_space am33xx_epwmss2_addr_space[] = { - { - .pa_start = 0x48304000, - .pa_end = 0x48304000 + SZ_16 - 1, - .flags = ADDR_TYPE_RT - }, - { } -}; - -static struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss2 = { - .master = &am33xx_l4_ls_hwmod, - .slave = &am33xx_epwmss2_hwmod, - .clk = "l4ls_gclk", - .addr = am33xx_epwmss2_addr_space, - .user = OCP_USER_MPU, -}; - -static struct omap_hwmod_ocp_if am33xx_epwmss2__ecap2 = { - .master = &am33xx_epwmss2_hwmod, - .slave = &am33xx_ecap2_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU, -}; - -static struct omap_hwmod_ocp_if am33xx_epwmss2__eqep2 = { - .master = &am33xx_epwmss2_hwmod, - .slave = &am33xx_eqep2_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU, -}; - -static struct omap_hwmod_ocp_if am33xx_epwmss2__ehrpwm2 = { - .master = &am33xx_epwmss2_hwmod, - .slave = &am33xx_ehrpwm2_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU, -}; - -/* l3s cfg -> gpmc */ -static struct omap_hwmod_addr_space am33xx_gpmc_addr_space[] = { - { - .pa_start = 0x50000000, - .pa_end = 0x50000000 + SZ_8K - 1, - .flags = ADDR_TYPE_RT, - }, - { } -}; - -static struct omap_hwmod_ocp_if am33xx_l3_s__gpmc = { - .master = &am33xx_l3_s_hwmod, - .slave = &am33xx_gpmc_hwmod, - .clk = "l3s_gclk", - .addr = am33xx_gpmc_addr_space, - .user = OCP_USER_MPU, -}; - -/* i2c2 */ -static struct omap_hwmod_ocp_if am33xx_l4_per__i2c2 = { - .master = &am33xx_l4_ls_hwmod, - .slave = &am33xx_i2c2_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU, -}; - -static struct omap_hwmod_ocp_if am33xx_l4_per__i2c3 = { - .master = &am33xx_l4_ls_hwmod, - .slave = &am33xx_i2c3_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU, -}; - static struct omap_hwmod_addr_space am33xx_lcdc_addr_space[] = { { .pa_start = 0x4830E000, @@ -2121,138 +483,6 @@ static struct omap_hwmod_ocp_if am33xx_l3_main__lcdc = { .user = OCP_USER_MPU, }; -static struct omap_hwmod_addr_space am33xx_mailbox_addrs[] = { - { - .pa_start = 0x480C8000, - .pa_end = 0x480C8000 + (SZ_4K - 1), - .flags = ADDR_TYPE_RT - }, - { } -}; - -/* l4 ls -> mailbox */ -static struct omap_hwmod_ocp_if am33xx_l4_per__mailbox = { - .master = &am33xx_l4_ls_hwmod, - .slave = &am33xx_mailbox_hwmod, - .clk = "l4ls_gclk", - .addr = am33xx_mailbox_addrs, - .user = OCP_USER_MPU, -}; - -/* l4 ls -> spinlock */ -static struct omap_hwmod_ocp_if am33xx_l4_ls__spinlock = { - .master = &am33xx_l4_ls_hwmod, - .slave = &am33xx_spinlock_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU, -}; - -/* l4 ls -> mcasp0 */ -static struct omap_hwmod_addr_space am33xx_mcasp0_addr_space[] = { - { - .pa_start = 0x48038000, - .pa_end = 0x48038000 + SZ_8K - 1, - .flags = ADDR_TYPE_RT - }, - { } -}; - -static struct omap_hwmod_ocp_if am33xx_l4_ls__mcasp0 = { - .master = &am33xx_l4_ls_hwmod, - .slave = &am33xx_mcasp0_hwmod, - .clk = "l4ls_gclk", - .addr = am33xx_mcasp0_addr_space, - .user = OCP_USER_MPU, -}; - -/* l4 ls -> mcasp1 */ -static struct omap_hwmod_addr_space am33xx_mcasp1_addr_space[] = { - { - .pa_start = 0x4803C000, - .pa_end = 0x4803C000 + SZ_8K - 1, - .flags = ADDR_TYPE_RT - }, - { } -}; - -static struct omap_hwmod_ocp_if am33xx_l4_ls__mcasp1 = { - .master = &am33xx_l4_ls_hwmod, - .slave = &am33xx_mcasp1_hwmod, - .clk = "l4ls_gclk", - .addr = am33xx_mcasp1_addr_space, - .user = OCP_USER_MPU, -}; - -/* l4 ls -> mmc0 */ -static struct omap_hwmod_addr_space am33xx_mmc0_addr_space[] = { - { - .pa_start = 0x48060100, - .pa_end = 0x48060100 + SZ_4K - 1, - .flags = ADDR_TYPE_RT, - }, - { } -}; - -static struct omap_hwmod_ocp_if am33xx_l4_ls__mmc0 = { - .master = &am33xx_l4_ls_hwmod, - .slave = &am33xx_mmc0_hwmod, - .clk = "l4ls_gclk", - .addr = am33xx_mmc0_addr_space, - .user = OCP_USER_MPU, -}; - -/* l4 ls -> mmc1 */ -static struct omap_hwmod_addr_space am33xx_mmc1_addr_space[] = { - { - .pa_start = 0x481d8100, - .pa_end = 0x481d8100 + SZ_4K - 1, - .flags = ADDR_TYPE_RT, - }, - { } -}; - -static struct omap_hwmod_ocp_if am33xx_l4_ls__mmc1 = { - .master = &am33xx_l4_ls_hwmod, - .slave = &am33xx_mmc1_hwmod, - .clk = "l4ls_gclk", - .addr = am33xx_mmc1_addr_space, - .user = OCP_USER_MPU, -}; - -/* l3 s -> mmc2 */ -static struct omap_hwmod_addr_space am33xx_mmc2_addr_space[] = { - { - .pa_start = 0x47810100, - .pa_end = 0x47810100 + SZ_64K - 1, - .flags = ADDR_TYPE_RT, - }, - { } -}; - -static struct omap_hwmod_ocp_if am33xx_l3_s__mmc2 = { - .master = &am33xx_l3_s_hwmod, - .slave = &am33xx_mmc2_hwmod, - .clk = "l3s_gclk", - .addr = am33xx_mmc2_addr_space, - .user = OCP_USER_MPU, -}; - -/* l4 ls -> mcspi0 */ -static struct omap_hwmod_ocp_if am33xx_l4_ls__mcspi0 = { - .master = &am33xx_l4_ls_hwmod, - .slave = &am33xx_spi0_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU, -}; - -/* l4 ls -> mcspi1 */ -static struct omap_hwmod_ocp_if am33xx_l4_ls__mcspi1 = { - .master = &am33xx_l4_ls_hwmod, - .slave = &am33xx_spi1_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU, -}; - /* l4 wkup -> timer1 */ static struct omap_hwmod_ocp_if am33xx_l4_wkup__timer1 = { .master = &am33xx_l4_wkup_hwmod, @@ -2261,116 +491,6 @@ static struct omap_hwmod_ocp_if am33xx_l4_wkup__timer1 = { .user = OCP_USER_MPU, }; -/* l4 per -> timer2 */ -static struct omap_hwmod_ocp_if am33xx_l4_ls__timer2 = { - .master = &am33xx_l4_ls_hwmod, - .slave = &am33xx_timer2_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU, -}; - -/* l4 per -> timer3 */ -static struct omap_hwmod_ocp_if am33xx_l4_ls__timer3 = { - .master = &am33xx_l4_ls_hwmod, - .slave = &am33xx_timer3_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU, -}; - -/* l4 per -> timer4 */ -static struct omap_hwmod_ocp_if am33xx_l4_ls__timer4 = { - .master = &am33xx_l4_ls_hwmod, - .slave = &am33xx_timer4_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU, -}; - -/* l4 per -> timer5 */ -static struct omap_hwmod_ocp_if am33xx_l4_ls__timer5 = { - .master = &am33xx_l4_ls_hwmod, - .slave = &am33xx_timer5_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU, -}; - -/* l4 per -> timer6 */ -static struct omap_hwmod_ocp_if am33xx_l4_ls__timer6 = { - .master = &am33xx_l4_ls_hwmod, - .slave = &am33xx_timer6_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU, -}; - -/* l4 per -> timer7 */ -static struct omap_hwmod_ocp_if am33xx_l4_ls__timer7 = { - .master = &am33xx_l4_ls_hwmod, - .slave = &am33xx_timer7_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU, -}; - -/* l3 main -> tpcc */ -static struct omap_hwmod_ocp_if am33xx_l3_main__tpcc = { - .master = &am33xx_l3_main_hwmod, - .slave = &am33xx_tpcc_hwmod, - .clk = "l3_gclk", - .user = OCP_USER_MPU, -}; - -/* l3 main -> tpcc0 */ -static struct omap_hwmod_addr_space am33xx_tptc0_addr_space[] = { - { - .pa_start = 0x49800000, - .pa_end = 0x49800000 + SZ_8K - 1, - .flags = ADDR_TYPE_RT, - }, - { } -}; - -static struct omap_hwmod_ocp_if am33xx_l3_main__tptc0 = { - .master = &am33xx_l3_main_hwmod, - .slave = &am33xx_tptc0_hwmod, - .clk = "l3_gclk", - .addr = am33xx_tptc0_addr_space, - .user = OCP_USER_MPU, -}; - -/* l3 main -> tpcc1 */ -static struct omap_hwmod_addr_space am33xx_tptc1_addr_space[] = { - { - .pa_start = 0x49900000, - .pa_end = 0x49900000 + SZ_8K - 1, - .flags = ADDR_TYPE_RT, - }, - { } -}; - -static struct omap_hwmod_ocp_if am33xx_l3_main__tptc1 = { - .master = &am33xx_l3_main_hwmod, - .slave = &am33xx_tptc1_hwmod, - .clk = "l3_gclk", - .addr = am33xx_tptc1_addr_space, - .user = OCP_USER_MPU, -}; - -/* l3 main -> tpcc2 */ -static struct omap_hwmod_addr_space am33xx_tptc2_addr_space[] = { - { - .pa_start = 0x49a00000, - .pa_end = 0x49a00000 + SZ_8K - 1, - .flags = ADDR_TYPE_RT, - }, - { } -}; - -static struct omap_hwmod_ocp_if am33xx_l3_main__tptc2 = { - .master = &am33xx_l3_main_hwmod, - .slave = &am33xx_tptc2_hwmod, - .clk = "l3_gclk", - .addr = am33xx_tptc2_addr_space, - .user = OCP_USER_MPU, -}; - /* l4 wkup -> uart1 */ static struct omap_hwmod_ocp_if am33xx_l4_wkup__uart1 = { .master = &am33xx_l4_wkup_hwmod, @@ -2379,46 +499,6 @@ static struct omap_hwmod_ocp_if am33xx_l4_wkup__uart1 = { .user = OCP_USER_MPU, }; -/* l4 ls -> uart2 */ -static struct omap_hwmod_ocp_if am33xx_l4_ls__uart2 = { - .master = &am33xx_l4_ls_hwmod, - .slave = &am33xx_uart2_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU, -}; - -/* l4 ls -> uart3 */ -static struct omap_hwmod_ocp_if am33xx_l4_ls__uart3 = { - .master = &am33xx_l4_ls_hwmod, - .slave = &am33xx_uart3_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU, -}; - -/* l4 ls -> uart4 */ -static struct omap_hwmod_ocp_if am33xx_l4_ls__uart4 = { - .master = &am33xx_l4_ls_hwmod, - .slave = &am33xx_uart4_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU, -}; - -/* l4 ls -> uart5 */ -static struct omap_hwmod_ocp_if am33xx_l4_ls__uart5 = { - .master = &am33xx_l4_ls_hwmod, - .slave = &am33xx_uart5_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU, -}; - -/* l4 ls -> uart6 */ -static struct omap_hwmod_ocp_if am33xx_l4_ls__uart6 = { - .master = &am33xx_l4_ls_hwmod, - .slave = &am33xx_uart6_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU, -}; - /* l4 wkup -> wd_timer1 */ static struct omap_hwmod_ocp_if am33xx_l4_wkup__wd_timer1 = { .master = &am33xx_l4_wkup_hwmod, @@ -2437,47 +517,39 @@ static struct omap_hwmod_ocp_if am33xx_l3_s__usbss = { .flags = OCPIF_SWSUP_IDLE, }; -/* l3 main -> ocmc */ -static struct omap_hwmod_ocp_if am33xx_l3_main__ocmc = { - .master = &am33xx_l3_main_hwmod, - .slave = &am33xx_ocmcram_hwmod, - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* l3 main -> sha0 HIB2 */ -static struct omap_hwmod_addr_space am33xx_sha0_addrs[] = { - { - .pa_start = 0x53100000, - .pa_end = 0x53100000 + SZ_512 - 1, - .flags = ADDR_TYPE_RT - }, - { } +/* rng */ +static struct omap_hwmod_class_sysconfig am33xx_rng_sysc = { + .rev_offs = 0x1fe0, + .sysc_offs = 0x1fe4, + .sysc_flags = SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE, + .idlemodes = SIDLE_FORCE | SIDLE_NO, + .sysc_fields = &omap_hwmod_sysc_type1, }; -static struct omap_hwmod_ocp_if am33xx_l3_main__sha0 = { - .master = &am33xx_l3_main_hwmod, - .slave = &am33xx_sha0_hwmod, - .clk = "sha0_fck", - .addr = am33xx_sha0_addrs, - .user = OCP_USER_MPU | OCP_USER_SDMA, +static struct omap_hwmod_class am33xx_rng_hwmod_class = { + .name = "rng", + .sysc = &am33xx_rng_sysc, }; -/* l3 main -> AES0 HIB2 */ -static struct omap_hwmod_addr_space am33xx_aes0_addrs[] = { - { - .pa_start = 0x53500000, - .pa_end = 0x53500000 + SZ_1M - 1, - .flags = ADDR_TYPE_RT +static struct omap_hwmod am33xx_rng_hwmod = { + .name = "rng", + .class = &am33xx_rng_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .flags = HWMOD_SWSUP_SIDLE, + .main_clk = "rng_fck", + .prcm = { + .omap4 = { + .clkctrl_offs = AM33XX_CM_PER_RNG_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, }, - { } }; -static struct omap_hwmod_ocp_if am33xx_l3_main__aes0 = { - .master = &am33xx_l3_main_hwmod, - .slave = &am33xx_aes0_hwmod, - .clk = "aes0_fck", - .addr = am33xx_aes0_addrs, - .user = OCP_USER_MPU | OCP_USER_SDMA, +static struct omap_hwmod_ocp_if am33xx_l4_per__rng = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_rng_hwmod, + .clk = "rng_fck", + .user = OCP_USER_MPU, }; static struct omap_hwmod_ocp_if *am33xx_hwmod_ocp_ifs[] __initdata = { @@ -2559,11 +631,13 @@ static struct omap_hwmod_ocp_if *am33xx_hwmod_ocp_ifs[] __initdata = { &am33xx_cpgmac0__mdio, &am33xx_l3_main__sha0, &am33xx_l3_main__aes0, + &am33xx_l4_per__rng, NULL, }; int __init am33xx_hwmod_init(void) { + omap_hwmod_am33xx_reg(); omap_hwmod_init(); return omap_hwmod_register_links(am33xx_hwmod_ocp_ifs); } diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 0c3a427da544..9e56fabd7fa3 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -3693,6 +3693,53 @@ static struct omap_hwmod_ocp_if omap3xxx_l4_core__aes = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; +/* + * 'ssi' class + * synchronous serial interface (multichannel and full-duplex serial if) + */ + +static struct omap_hwmod_class_sysconfig omap34xx_ssi_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_EMUFREE | + SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO | + MSTANDBY_SMART | MSTANDBY_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap34xx_ssi_hwmod_class = { + .name = "ssi", + .sysc = &omap34xx_ssi_sysc, +}; + +static struct omap_hwmod omap34xx_ssi_hwmod = { + .name = "ssi", + .class = &omap34xx_ssi_hwmod_class, + .clkdm_name = "core_l4_clkdm", + .main_clk = "ssi_ssr_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_SSI_SHIFT, + .module_offs = CORE_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430ES2_ST_SSI_IDLE_SHIFT, + }, + }, +}; + +/* L4 CORE -> SSI */ +static struct omap_hwmod_ocp_if omap34xx_l4_core__ssi = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap34xx_ssi_hwmod, + .clk = "ssi_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + static struct omap_hwmod_ocp_if *omap3xxx_hwmod_ocp_ifs[] __initdata = { &omap3xxx_l3_main__l4_core, &omap3xxx_l3_main__l4_per, @@ -3818,6 +3865,7 @@ static struct omap_hwmod_ocp_if *omap34xx_hwmod_ocp_ifs[] __initdata = { #ifdef CONFIG_OMAP_IOMMU_IVA2 &omap3xxx_l3_main__mmu_iva, #endif + &omap34xx_l4_core__ssi, NULL }; diff --git a/arch/arm/mach-omap2/omap_hwmod_43xx_data.c b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c new file mode 100644 index 000000000000..9002fca76699 --- /dev/null +++ b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c @@ -0,0 +1,758 @@ +/* + * Copyright (C) 2013 Texas Instruments Incorporated + * + * Hwmod present only in AM43x and those that differ other than register + * offsets as compared to AM335x. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/platform_data/gpio-omap.h> +#include <linux/platform_data/spi-omap2-mcspi.h> +#include "omap_hwmod.h" +#include "omap_hwmod_33xx_43xx_common_data.h" +#include "prcm43xx.h" + +/* IP blocks */ +static struct omap_hwmod am43xx_l4_hs_hwmod = { + .name = "l4_hs", + .class = &am33xx_l4_hwmod_class, + .clkdm_name = "l3_clkdm", + .flags = HWMOD_INIT_NO_IDLE, + .main_clk = "l4hs_gclk", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_PER_L4HS_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +static struct omap_hwmod_rst_info am33xx_wkup_m3_resets[] = { + { .name = "wkup_m3", .rst_shift = 3, .st_shift = 5 }, +}; + +static struct omap_hwmod am43xx_wkup_m3_hwmod = { + .name = "wkup_m3", + .class = &am33xx_wkup_m3_hwmod_class, + .clkdm_name = "l4_wkup_aon_clkdm", + /* Keep hardreset asserted */ + .flags = HWMOD_INIT_NO_RESET | HWMOD_NO_IDLEST, + .main_clk = "sys_clkin_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_WKUP_WKUP_M3_CLKCTRL_OFFSET, + .rstctrl_offs = AM43XX_RM_WKUP_RSTCTRL_OFFSET, + .rstst_offs = AM43XX_RM_WKUP_RSTST_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .rst_lines = am33xx_wkup_m3_resets, + .rst_lines_cnt = ARRAY_SIZE(am33xx_wkup_m3_resets), +}; + +static struct omap_hwmod am43xx_control_hwmod = { + .name = "control", + .class = &am33xx_control_hwmod_class, + .clkdm_name = "l4_wkup_clkdm", + .flags = HWMOD_INIT_NO_IDLE, + .main_clk = "sys_clkin_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_WKUP_CONTROL_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +static struct omap_hwmod_opt_clk gpio0_opt_clks[] = { + { .role = "dbclk", .clk = "gpio0_dbclk" }, +}; + +static struct omap_hwmod am43xx_gpio0_hwmod = { + .name = "gpio1", + .class = &am33xx_gpio_hwmod_class, + .clkdm_name = "l4_wkup_clkdm", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .main_clk = "sys_clkin_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_WKUP_GPIO0_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .opt_clks = gpio0_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(gpio0_opt_clks), + .dev_attr = &gpio_dev_attr, +}; + +static struct omap_hwmod_class_sysconfig am43xx_synctimer_sysc = { + .rev_offs = 0x0, + .sysc_offs = 0x4, + .sysc_flags = SYSC_HAS_SIDLEMODE, + .idlemodes = (SIDLE_FORCE | SIDLE_NO), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class am43xx_synctimer_hwmod_class = { + .name = "synctimer", + .sysc = &am43xx_synctimer_sysc, +}; + +static struct omap_hwmod am43xx_synctimer_hwmod = { + .name = "counter_32k", + .class = &am43xx_synctimer_hwmod_class, + .clkdm_name = "l4_wkup_aon_clkdm", + .flags = HWMOD_SWSUP_SIDLE, + .main_clk = "synctimer_32kclk", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_WKUP_SYNCTIMER_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +static struct omap_hwmod am43xx_timer8_hwmod = { + .name = "timer8", + .class = &am33xx_timer_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "timer8_fck", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_PER_TIMER8_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +static struct omap_hwmod am43xx_timer9_hwmod = { + .name = "timer9", + .class = &am33xx_timer_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "timer9_fck", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_PER_TIMER9_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +static struct omap_hwmod am43xx_timer10_hwmod = { + .name = "timer10", + .class = &am33xx_timer_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "timer10_fck", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_PER_TIMER10_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +static struct omap_hwmod am43xx_timer11_hwmod = { + .name = "timer11", + .class = &am33xx_timer_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "timer11_fck", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_PER_TIMER11_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +static struct omap_hwmod am43xx_epwmss3_hwmod = { + .name = "epwmss3", + .class = &am33xx_epwmss_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_PER_EPWMSS3_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +static struct omap_hwmod am43xx_ehrpwm3_hwmod = { + .name = "ehrpwm3", + .class = &am33xx_ehrpwm_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", +}; + +static struct omap_hwmod am43xx_epwmss4_hwmod = { + .name = "epwmss4", + .class = &am33xx_epwmss_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_PER_EPWMSS4_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +static struct omap_hwmod am43xx_ehrpwm4_hwmod = { + .name = "ehrpwm4", + .class = &am33xx_ehrpwm_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", +}; + +static struct omap_hwmod am43xx_epwmss5_hwmod = { + .name = "epwmss5", + .class = &am33xx_epwmss_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_PER_EPWMSS5_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +static struct omap_hwmod am43xx_ehrpwm5_hwmod = { + .name = "ehrpwm5", + .class = &am33xx_ehrpwm_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", +}; + +static struct omap_hwmod am43xx_spi2_hwmod = { + .name = "spi2", + .class = &am33xx_spi_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "dpll_per_m2_div4_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_PER_SPI2_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &mcspi_attrib, +}; + +static struct omap_hwmod am43xx_spi3_hwmod = { + .name = "spi3", + .class = &am33xx_spi_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "dpll_per_m2_div4_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_PER_SPI3_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &mcspi_attrib, +}; + +static struct omap_hwmod am43xx_spi4_hwmod = { + .name = "spi4", + .class = &am33xx_spi_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "dpll_per_m2_div4_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_PER_SPI4_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &mcspi_attrib, +}; + +static struct omap_hwmod_opt_clk gpio4_opt_clks[] = { + { .role = "dbclk", .clk = "gpio4_dbclk" }, +}; + +static struct omap_hwmod am43xx_gpio4_hwmod = { + .name = "gpio5", + .class = &am33xx_gpio_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .main_clk = "l4ls_gclk", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_PER_GPIO4_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .opt_clks = gpio4_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(gpio4_opt_clks), + .dev_attr = &gpio_dev_attr, +}; + +static struct omap_hwmod_opt_clk gpio5_opt_clks[] = { + { .role = "dbclk", .clk = "gpio5_dbclk" }, +}; + +static struct omap_hwmod am43xx_gpio5_hwmod = { + .name = "gpio6", + .class = &am33xx_gpio_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .main_clk = "l4ls_gclk", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_PER_GPIO5_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .opt_clks = gpio5_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(gpio5_opt_clks), + .dev_attr = &gpio_dev_attr, +}; + +static struct omap_hwmod_class am43xx_ocp2scp_hwmod_class = { + .name = "ocp2scp", +}; + +static struct omap_hwmod am43xx_ocp2scp0_hwmod = { + .name = "ocp2scp0", + .class = &am43xx_ocp2scp_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_PER_USBPHYOCP2SCP0_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +static struct omap_hwmod am43xx_ocp2scp1_hwmod = { + .name = "ocp2scp1", + .class = &am43xx_ocp2scp_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_PER_USBPHYOCP2SCP1_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +static struct omap_hwmod_class_sysconfig am43xx_usb_otg_ss_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_DMADISABLE | SYSC_HAS_MIDLEMODE | + SYSC_HAS_SIDLEMODE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP | MSTANDBY_FORCE | + MSTANDBY_NO | MSTANDBY_SMART | + MSTANDBY_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class am43xx_usb_otg_ss_hwmod_class = { + .name = "usb_otg_ss", + .sysc = &am43xx_usb_otg_ss_sysc, +}; + +static struct omap_hwmod am43xx_usb_otg_ss0_hwmod = { + .name = "usb_otg_ss0", + .class = &am43xx_usb_otg_ss_hwmod_class, + .clkdm_name = "l3s_clkdm", + .main_clk = "l3s_gclk", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_PER_USB_OTG_SS0_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +static struct omap_hwmod am43xx_usb_otg_ss1_hwmod = { + .name = "usb_otg_ss1", + .class = &am43xx_usb_otg_ss_hwmod_class, + .clkdm_name = "l3s_clkdm", + .main_clk = "l3s_gclk", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_PER_USB_OTG_SS1_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +static struct omap_hwmod_class_sysconfig am43xx_qspi_sysc = { + .sysc_offs = 0x0010, + .sysc_flags = SYSC_HAS_SIDLEMODE, + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class am43xx_qspi_hwmod_class = { + .name = "qspi", + .sysc = &am43xx_qspi_sysc, +}; + +static struct omap_hwmod am43xx_qspi_hwmod = { + .name = "qspi", + .class = &am43xx_qspi_hwmod_class, + .clkdm_name = "l3s_clkdm", + .main_clk = "l3s_gclk", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_PER_QSPI_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* Interfaces */ +static struct omap_hwmod_ocp_if am43xx_l3_main__l4_hs = { + .master = &am33xx_l3_main_hwmod, + .slave = &am43xx_l4_hs_hwmod, + .clk = "l3s_gclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_ocp_if am43xx_wkup_m3__l4_wkup = { + .master = &am43xx_wkup_m3_hwmod, + .slave = &am33xx_l4_wkup_hwmod, + .clk = "sys_clkin_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_wkup__wkup_m3 = { + .master = &am33xx_l4_wkup_hwmod, + .slave = &am43xx_wkup_m3_hwmod, + .clk = "sys_clkin_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_ocp_if am43xx_l3_main__pruss = { + .master = &am33xx_l3_main_hwmod, + .slave = &am33xx_pruss_hwmod, + .clk = "dpll_core_m4_ck", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_wkup__smartreflex0 = { + .master = &am33xx_l4_wkup_hwmod, + .slave = &am33xx_smartreflex0_hwmod, + .clk = "sys_clkin_ck", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_wkup__smartreflex1 = { + .master = &am33xx_l4_wkup_hwmod, + .slave = &am33xx_smartreflex1_hwmod, + .clk = "sys_clkin_ck", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_wkup__control = { + .master = &am33xx_l4_wkup_hwmod, + .slave = &am43xx_control_hwmod, + .clk = "sys_clkin_ck", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_wkup__i2c1 = { + .master = &am33xx_l4_wkup_hwmod, + .slave = &am33xx_i2c1_hwmod, + .clk = "sys_clkin_ck", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_wkup__gpio0 = { + .master = &am33xx_l4_wkup_hwmod, + .slave = &am43xx_gpio0_hwmod, + .clk = "sys_clkin_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_hs__cpgmac0 = { + .master = &am43xx_l4_hs_hwmod, + .slave = &am33xx_cpgmac0_hwmod, + .clk = "cpsw_125mhz_gclk", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_wkup__timer1 = { + .master = &am33xx_l4_wkup_hwmod, + .slave = &am33xx_timer1_hwmod, + .clk = "sys_clkin_ck", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_wkup__uart1 = { + .master = &am33xx_l4_wkup_hwmod, + .slave = &am33xx_uart1_hwmod, + .clk = "sys_clkin_ck", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_wkup__wd_timer1 = { + .master = &am33xx_l4_wkup_hwmod, + .slave = &am33xx_wd_timer1_hwmod, + .clk = "sys_clkin_ck", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am33xx_l4_wkup__synctimer = { + .master = &am33xx_l4_wkup_hwmod, + .slave = &am43xx_synctimer_hwmod, + .clk = "sys_clkin_ck", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_ls__timer8 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am43xx_timer8_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_ls__timer9 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am43xx_timer9_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_ls__timer10 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am43xx_timer10_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_ls__timer11 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am43xx_timer11_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_ls__epwmss3 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am43xx_epwmss3_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_epwmss3__ehrpwm3 = { + .master = &am43xx_epwmss3_hwmod, + .slave = &am43xx_ehrpwm3_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_ls__epwmss4 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am43xx_epwmss4_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_epwmss4__ehrpwm4 = { + .master = &am43xx_epwmss4_hwmod, + .slave = &am43xx_ehrpwm4_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_ls__epwmss5 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am43xx_epwmss5_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_epwmss5__ehrpwm5 = { + .master = &am43xx_epwmss5_hwmod, + .slave = &am43xx_ehrpwm5_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_ls__mcspi2 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am43xx_spi2_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_ls__mcspi3 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am43xx_spi3_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_ls__mcspi4 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am43xx_spi4_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_ls__gpio4 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am43xx_gpio4_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_ls__gpio5 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am43xx_gpio5_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_ls__ocp2scp0 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am43xx_ocp2scp0_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_ls__ocp2scp1 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am43xx_ocp2scp1_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_l3_s__usbotgss0 = { + .master = &am33xx_l3_s_hwmod, + .slave = &am43xx_usb_otg_ss0_hwmod, + .clk = "l3s_gclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_ocp_if am43xx_l3_s__usbotgss1 = { + .master = &am33xx_l3_s_hwmod, + .slave = &am43xx_usb_otg_ss1_hwmod, + .clk = "l3s_gclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_ocp_if am43xx_l3_s__qspi = { + .master = &am33xx_l3_s_hwmod, + .slave = &am43xx_qspi_hwmod, + .clk = "l3s_gclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_ocp_if *am43xx_hwmod_ocp_ifs[] __initdata = { + &am33xx_l4_wkup__synctimer, + &am43xx_l4_ls__timer8, + &am43xx_l4_ls__timer9, + &am43xx_l4_ls__timer10, + &am43xx_l4_ls__timer11, + &am43xx_l4_ls__epwmss3, + &am43xx_epwmss3__ehrpwm3, + &am43xx_l4_ls__epwmss4, + &am43xx_epwmss4__ehrpwm4, + &am43xx_l4_ls__epwmss5, + &am43xx_epwmss5__ehrpwm5, + &am43xx_l4_ls__mcspi2, + &am43xx_l4_ls__mcspi3, + &am43xx_l4_ls__mcspi4, + &am43xx_l4_ls__gpio4, + &am43xx_l4_ls__gpio5, + &am43xx_l3_main__pruss, + &am33xx_mpu__l3_main, + &am33xx_mpu__prcm, + &am33xx_l3_s__l4_ls, + &am33xx_l3_s__l4_wkup, + &am43xx_l3_main__l4_hs, + &am33xx_l3_main__l3_s, + &am33xx_l3_main__l3_instr, + &am33xx_l3_main__gfx, + &am33xx_l3_s__l3_main, + &am33xx_pruss__l3_main, + &am43xx_wkup_m3__l4_wkup, + &am33xx_gfx__l3_main, + &am43xx_l4_wkup__wkup_m3, + &am43xx_l4_wkup__control, + &am43xx_l4_wkup__smartreflex0, + &am43xx_l4_wkup__smartreflex1, + &am43xx_l4_wkup__uart1, + &am43xx_l4_wkup__timer1, + &am43xx_l4_wkup__i2c1, + &am43xx_l4_wkup__gpio0, + &am43xx_l4_wkup__wd_timer1, + &am43xx_l3_s__qspi, + &am33xx_l4_per__dcan0, + &am33xx_l4_per__dcan1, + &am33xx_l4_per__gpio1, + &am33xx_l4_per__gpio2, + &am33xx_l4_per__gpio3, + &am33xx_l4_per__i2c2, + &am33xx_l4_per__i2c3, + &am33xx_l4_per__mailbox, + &am33xx_l4_ls__mcasp0, + &am33xx_l4_ls__mcasp1, + &am33xx_l4_ls__mmc0, + &am33xx_l4_ls__mmc1, + &am33xx_l3_s__mmc2, + &am33xx_l4_ls__timer2, + &am33xx_l4_ls__timer3, + &am33xx_l4_ls__timer4, + &am33xx_l4_ls__timer5, + &am33xx_l4_ls__timer6, + &am33xx_l4_ls__timer7, + &am33xx_l3_main__tpcc, + &am33xx_l4_ls__uart2, + &am33xx_l4_ls__uart3, + &am33xx_l4_ls__uart4, + &am33xx_l4_ls__uart5, + &am33xx_l4_ls__uart6, + &am33xx_l4_ls__elm, + &am33xx_l4_ls__epwmss0, + &am33xx_epwmss0__ecap0, + &am33xx_epwmss0__eqep0, + &am33xx_epwmss0__ehrpwm0, + &am33xx_l4_ls__epwmss1, + &am33xx_epwmss1__ecap1, + &am33xx_epwmss1__eqep1, + &am33xx_epwmss1__ehrpwm1, + &am33xx_l4_ls__epwmss2, + &am33xx_epwmss2__ecap2, + &am33xx_epwmss2__eqep2, + &am33xx_epwmss2__ehrpwm2, + &am33xx_l3_s__gpmc, + &am33xx_l4_ls__mcspi0, + &am33xx_l4_ls__mcspi1, + &am33xx_l3_main__tptc0, + &am33xx_l3_main__tptc1, + &am33xx_l3_main__tptc2, + &am33xx_l3_main__ocmc, + &am43xx_l4_hs__cpgmac0, + &am33xx_cpgmac0__mdio, + &am33xx_l3_main__sha0, + &am33xx_l3_main__aes0, + &am43xx_l4_ls__ocp2scp0, + &am43xx_l4_ls__ocp2scp1, + &am43xx_l3_s__usbotgss0, + &am43xx_l3_s__usbotgss1, + NULL, +}; + +int __init am43xx_hwmod_init(void) +{ + omap_hwmod_am43xx_reg(); + omap_hwmod_init(); + return omap_hwmod_register_links(am43xx_hwmod_ocp_ifs); +} diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 9c3b504477d7..1e5b12cb8246 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -914,7 +914,7 @@ static struct omap_hwmod omap44xx_emif1_hwmod = { .name = "emif1", .class = &omap44xx_emif_hwmod_class, .clkdm_name = "l3_emif_clkdm", - .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, + .flags = HWMOD_INIT_NO_IDLE, .main_clk = "ddrphy_ck", .prcm = { .omap4 = { @@ -930,7 +930,7 @@ static struct omap_hwmod omap44xx_emif2_hwmod = { .name = "emif2", .class = &omap44xx_emif_hwmod_class, .clkdm_name = "l3_emif_clkdm", - .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, + .flags = HWMOD_INIT_NO_IDLE, .main_clk = "ddrphy_ck", .prcm = { .omap4 = { @@ -2193,7 +2193,7 @@ static struct omap_hwmod omap44xx_mpu_hwmod = { .name = "mpu", .class = &omap44xx_mpu_hwmod_class, .clkdm_name = "mpuss_clkdm", - .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, + .flags = HWMOD_INIT_NO_IDLE, .main_clk = "dpll_mpu_m2_ck", .prcm = { .omap4 = { diff --git a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c index cde415570e04..9e08d6994a0b 100644 --- a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c @@ -352,7 +352,7 @@ static struct omap_hwmod omap54xx_emif1_hwmod = { .name = "emif1", .class = &omap54xx_emif_hwmod_class, .clkdm_name = "emif_clkdm", - .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, + .flags = HWMOD_INIT_NO_IDLE, .main_clk = "dpll_core_h11x2_ck", .prcm = { .omap4 = { @@ -368,7 +368,7 @@ static struct omap_hwmod omap54xx_emif2_hwmod = { .name = "emif2", .class = &omap54xx_emif_hwmod_class, .clkdm_name = "emif_clkdm", - .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, + .flags = HWMOD_INIT_NO_IDLE, .main_clk = "dpll_core_h11x2_ck", .prcm = { .omap4 = { @@ -1135,7 +1135,7 @@ static struct omap_hwmod omap54xx_mpu_hwmod = { .name = "mpu", .class = &omap54xx_mpu_hwmod_class, .clkdm_name = "mpu_clkdm", - .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, + .flags = HWMOD_INIT_NO_IDLE, .main_clk = "dpll_mpu_m2_ck", .prcm = { .omap4 = { @@ -1146,6 +1146,77 @@ static struct omap_hwmod omap54xx_mpu_hwmod = { }; /* + * 'spinlock' class + * spinlock provides hardware assistance for synchronizing the processes + * running on multiple processors + */ + +static struct omap_hwmod_class_sysconfig omap54xx_spinlock_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | + SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap54xx_spinlock_hwmod_class = { + .name = "spinlock", + .sysc = &omap54xx_spinlock_sysc, +}; + +/* spinlock */ +static struct omap_hwmod omap54xx_spinlock_hwmod = { + .name = "spinlock", + .class = &omap54xx_spinlock_hwmod_class, + .clkdm_name = "l4cfg_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L4CFG_SPINLOCK_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L4CFG_SPINLOCK_CONTEXT_OFFSET, + }, + }, +}; + +/* + * 'ocp2scp' class + * bridge to transform ocp interface protocol to scp (serial control port) + * protocol + */ + +static struct omap_hwmod_class_sysconfig omap54xx_ocp2scp_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap54xx_ocp2scp_hwmod_class = { + .name = "ocp2scp", + .sysc = &omap54xx_ocp2scp_sysc, +}; + +/* ocp2scp1 */ +static struct omap_hwmod omap54xx_ocp2scp1_hwmod = { + .name = "ocp2scp1", + .class = &omap54xx_ocp2scp_hwmod_class, + .clkdm_name = "l3init_clkdm", + .main_clk = "l4_root_clk_div", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L3INIT_OCP2SCP1_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L3INIT_OCP2SCP1_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + +/* * 'timer' class * general purpose timer module with accurate 1ms tick * This class contains several variants: ['timer_1ms', 'timer'] @@ -1465,6 +1536,123 @@ static struct omap_hwmod omap54xx_uart6_hwmod = { }; /* + * 'usb_host_hs' class + * high-speed multi-port usb host controller + */ + +static struct omap_hwmod_class_sysconfig omap54xx_usb_host_hs_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_RESET_STATUS | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO | + MSTANDBY_SMART | MSTANDBY_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class omap54xx_usb_host_hs_hwmod_class = { + .name = "usb_host_hs", + .sysc = &omap54xx_usb_host_hs_sysc, +}; + +static struct omap_hwmod omap54xx_usb_host_hs_hwmod = { + .name = "usb_host_hs", + .class = &omap54xx_usb_host_hs_hwmod_class, + .clkdm_name = "l3init_clkdm", + /* + * Errata: USBHOST Configured In Smart-Idle Can Lead To a Deadlock + * id: i660 + * + * Description: + * In the following configuration : + * - USBHOST module is set to smart-idle mode + * - PRCM asserts idle_req to the USBHOST module ( This typically + * happens when the system is going to a low power mode : all ports + * have been suspended, the master part of the USBHOST module has + * entered the standby state, and SW has cut the functional clocks) + * - an USBHOST interrupt occurs before the module is able to answer + * idle_ack, typically a remote wakeup IRQ. + * Then the USB HOST module will enter a deadlock situation where it + * is no more accessible nor functional. + * + * Workaround: + * Don't use smart idle; use only force idle, hence HWMOD_SWSUP_SIDLE + */ + + /* + * Errata: USB host EHCI may stall when entering smart-standby mode + * Id: i571 + * + * Description: + * When the USBHOST module is set to smart-standby mode, and when it is + * ready to enter the standby state (i.e. all ports are suspended and + * all attached devices are in suspend mode), then it can wrongly assert + * the Mstandby signal too early while there are still some residual OCP + * transactions ongoing. If this condition occurs, the internal state + * machine may go to an undefined state and the USB link may be stuck + * upon the next resume. + * + * Workaround: + * Don't use smart standby; use only force standby, + * hence HWMOD_SWSUP_MSTANDBY + */ + + /* + * During system boot; If the hwmod framework resets the module + * the module will have smart idle settings; which can lead to deadlock + * (above Errata Id:i660); so, dont reset the module during boot; + * Use HWMOD_INIT_NO_RESET. + */ + + .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY | + HWMOD_INIT_NO_RESET, + .main_clk = "l3init_60m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L3INIT_USB_HOST_HS_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L3INIT_USB_HOST_HS_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * 'usb_tll_hs' class + * usb_tll_hs module is the adapter on the usb_host_hs ports + */ + +static struct omap_hwmod_class_sysconfig omap54xx_usb_tll_hs_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | + SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap54xx_usb_tll_hs_hwmod_class = { + .name = "usb_tll_hs", + .sysc = &omap54xx_usb_tll_hs_sysc, +}; + +static struct omap_hwmod omap54xx_usb_tll_hs_hwmod = { + .name = "usb_tll_hs", + .class = &omap54xx_usb_tll_hs_hwmod_class, + .clkdm_name = "l3init_clkdm", + .main_clk = "l4_root_clk_div", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L3INIT_USB_TLL_HS_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L3INIT_USB_TLL_HS_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + +/* * 'usb_otg_ss' class * 2.0 super speed (usb_otg_ss) controller */ @@ -1960,6 +2148,22 @@ static struct omap_hwmod_ocp_if omap54xx_l4_cfg__mpu = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; +/* l4_cfg -> spinlock */ +static struct omap_hwmod_ocp_if omap54xx_l4_cfg__spinlock = { + .master = &omap54xx_l4_cfg_hwmod, + .slave = &omap54xx_spinlock_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_cfg -> ocp2scp1 */ +static struct omap_hwmod_ocp_if omap54xx_l4_cfg__ocp2scp1 = { + .master = &omap54xx_l4_cfg_hwmod, + .slave = &omap54xx_ocp2scp1_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + /* l4_wkup -> timer1 */ static struct omap_hwmod_ocp_if omap54xx_l4_wkup__timer1 = { .master = &omap54xx_l4_wkup_hwmod, @@ -2096,6 +2300,22 @@ static struct omap_hwmod_ocp_if omap54xx_l4_per__uart6 = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; +/* l4_cfg -> usb_host_hs */ +static struct omap_hwmod_ocp_if omap54xx_l4_cfg__usb_host_hs = { + .master = &omap54xx_l4_cfg_hwmod, + .slave = &omap54xx_usb_host_hs_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_cfg -> usb_tll_hs */ +static struct omap_hwmod_ocp_if omap54xx_l4_cfg__usb_tll_hs = { + .master = &omap54xx_l4_cfg_hwmod, + .slave = &omap54xx_usb_tll_hs_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + /* l4_cfg -> usb_otg_ss */ static struct omap_hwmod_ocp_if omap54xx_l4_cfg__usb_otg_ss = { .master = &omap54xx_l4_cfg_hwmod, @@ -2163,6 +2383,8 @@ static struct omap_hwmod_ocp_if *omap54xx_hwmod_ocp_ifs[] __initdata = { &omap54xx_l4_per__mmc4, &omap54xx_l4_per__mmc5, &omap54xx_l4_cfg__mpu, + &omap54xx_l4_cfg__spinlock, + &omap54xx_l4_cfg__ocp2scp1, &omap54xx_l4_wkup__timer1, &omap54xx_l4_per__timer2, &omap54xx_l4_per__timer3, @@ -2180,6 +2402,8 @@ static struct omap_hwmod_ocp_if *omap54xx_hwmod_ocp_ifs[] __initdata = { &omap54xx_l4_per__uart4, &omap54xx_l4_per__uart5, &omap54xx_l4_per__uart6, + &omap54xx_l4_cfg__usb_host_hs, + &omap54xx_l4_cfg__usb_tll_hs, &omap54xx_l4_cfg__usb_otg_ss, &omap54xx_l4_wkup__wd_timer2, NULL, diff --git a/arch/arm/mach-omap2/opp.c b/arch/arm/mach-omap2/opp.c index bd41d59a7cab..a358a07e18f2 100644 --- a/arch/arm/mach-omap2/opp.c +++ b/arch/arm/mach-omap2/opp.c @@ -17,7 +17,8 @@ * GNU General Public License for more details. */ #include <linux/module.h> -#include <linux/opp.h> +#include <linux/of.h> +#include <linux/pm_opp.h> #include <linux/cpu.h> #include "omap_device.h" @@ -40,6 +41,9 @@ int __init omap_init_opp_table(struct omap_opp_def *opp_def, { int i, r; + if (of_have_populated_dt()) + return -EINVAL; + if (!opp_def || !opp_def_size) { pr_err("%s: invalid params!\n", __func__); return -EINVAL; @@ -81,14 +85,14 @@ int __init omap_init_opp_table(struct omap_opp_def *opp_def, dev = &oh->od->pdev->dev; } - r = opp_add(dev, opp_def->freq, opp_def->u_volt); + r = dev_pm_opp_add(dev, opp_def->freq, opp_def->u_volt); if (r) { dev_err(dev, "%s: add OPP %ld failed for %s [%d] result=%d\n", __func__, opp_def->freq, opp_def->hwmod_name, i, r); } else { if (!opp_def->default_available) - r = opp_disable(dev, opp_def->freq); + r = dev_pm_opp_disable(dev, opp_def->freq); if (r) dev_err(dev, "%s: disable %ld failed for %s [%d] result=%d\n", __func__, opp_def->freq, diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c new file mode 100644 index 000000000000..10c71450cf63 --- /dev/null +++ b/arch/arm/mach-omap2/pdata-quirks.c @@ -0,0 +1,174 @@ +/* + * Legacy platform_data quirks + * + * Copyright (C) 2013 Texas Instruments + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/clk.h> +#include <linux/gpio.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/of_platform.h> +#include <linux/wl12xx.h> + +#include <linux/platform_data/pinctrl-single.h> + +#include "common.h" +#include "common-board-devices.h" +#include "dss-common.h" +#include "control.h" + +struct pdata_init { + const char *compatible; + void (*fn)(void); +}; + +/* + * Create alias for USB host PHY clock. + * Remove this when clock phandle can be provided via DT + */ +static void __init __used legacy_init_ehci_clk(char *clkname) +{ + int ret; + + ret = clk_add_alias("main_clk", NULL, clkname, NULL); + if (ret) + pr_err("%s:Failed to add main_clk alias to %s :%d\n", + __func__, clkname, ret); +} + +#if IS_ENABLED(CONFIG_WL12XX) + +static struct wl12xx_platform_data wl12xx __initdata; + +static void __init __used legacy_init_wl12xx(unsigned ref_clock, + unsigned tcxo_clock, + int gpio) +{ + int res; + + wl12xx.board_ref_clock = ref_clock; + wl12xx.board_tcxo_clock = tcxo_clock; + wl12xx.irq = gpio_to_irq(gpio); + + res = wl12xx_set_platform_data(&wl12xx); + if (res) { + pr_err("error setting wl12xx data: %d\n", res); + return; + } +} +#else +static inline void legacy_init_wl12xx(unsigned ref_clock, + unsigned tcxo_clock, + int gpio) +{ +} +#endif + +#ifdef CONFIG_ARCH_OMAP3 +static void __init hsmmc2_internal_input_clk(void) +{ + u32 reg; + + reg = omap_ctrl_readl(OMAP343X_CONTROL_DEVCONF1); + reg |= OMAP2_MMCSDIO2ADPCLKISEL; + omap_ctrl_writel(reg, OMAP343X_CONTROL_DEVCONF1); +} + +static void __init omap3_igep0020_legacy_init(void) +{ + omap3_igep2_display_init_of(); +} + +static void __init omap3_evm_legacy_init(void) +{ + legacy_init_wl12xx(WL12XX_REFCLOCK_38, 0, 149); +} + +static void __init omap3_zoom_legacy_init(void) +{ + legacy_init_wl12xx(WL12XX_REFCLOCK_26, 0, 162); +} +#endif /* CONFIG_ARCH_OMAP3 */ + +#ifdef CONFIG_ARCH_OMAP4 +static void __init omap4_sdp_legacy_init(void) +{ + omap_4430sdp_display_init_of(); + legacy_init_wl12xx(WL12XX_REFCLOCK_26, + WL12XX_TCXOCLOCK_26, 53); +} + +static void __init omap4_panda_legacy_init(void) +{ + omap4_panda_display_init_of(); + legacy_init_ehci_clk("auxclk3_ck"); + legacy_init_wl12xx(WL12XX_REFCLOCK_38, 0, 53); +} +#endif + +#ifdef CONFIG_SOC_OMAP5 +static void __init omap5_uevm_legacy_init(void) +{ + legacy_init_ehci_clk("auxclk1_ck"); +} +#endif + +static struct pcs_pdata pcs_pdata; + +void omap_pcs_legacy_init(int irq, void (*rearm)(void)) +{ + pcs_pdata.irq = irq; + pcs_pdata.rearm = rearm; +} + +struct of_dev_auxdata omap_auxdata_lookup[] __initdata = { +#ifdef CONFIG_ARCH_OMAP3 + OF_DEV_AUXDATA("ti,omap3-padconf", 0x48002030, "48002030.pinmux", &pcs_pdata), + OF_DEV_AUXDATA("ti,omap3-padconf", 0x48002a00, "48002a00.pinmux", &pcs_pdata), +#endif +#ifdef CONFIG_ARCH_OMAP4 + OF_DEV_AUXDATA("ti,omap4-padconf", 0x4a100040, "4a100040.pinmux", &pcs_pdata), + OF_DEV_AUXDATA("ti,omap4-padconf", 0x4a31e040, "4a31e040.pinmux", &pcs_pdata), +#endif + { /* sentinel */ }, +}; + +static struct pdata_init pdata_quirks[] __initdata = { +#ifdef CONFIG_ARCH_OMAP3 + { "nokia,omap3-n9", hsmmc2_internal_input_clk, }, + { "nokia,omap3-n950", hsmmc2_internal_input_clk, }, + { "isee,omap3-igep0020", omap3_igep0020_legacy_init, }, + { "ti,omap3-evm-37xx", omap3_evm_legacy_init, }, + { "ti,omap3-zoom3", omap3_zoom_legacy_init, }, +#endif +#ifdef CONFIG_ARCH_OMAP4 + { "ti,omap4-sdp", omap4_sdp_legacy_init, }, + { "ti,omap4-panda", omap4_panda_legacy_init, }, +#endif +#ifdef CONFIG_SOC_OMAP5 + { "ti,omap5-uevm", omap5_uevm_legacy_init, }, +#endif + { /* sentinel */ }, +}; + +void __init pdata_quirks_init(struct of_device_id *omap_dt_match_table) +{ + struct pdata_init *quirks = pdata_quirks; + + omap_sdrc_init(NULL, NULL); + of_platform_populate(NULL, omap_dt_match_table, + omap_auxdata_lookup, NULL); + + while (quirks->compatible) { + if (of_machine_is_compatible(quirks->compatible)) { + if (quirks->fn) + quirks->fn(); + break; + } + quirks++; + } +} diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index e742118fcfd2..e1b41416fbf1 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c @@ -13,7 +13,7 @@ #include <linux/init.h> #include <linux/io.h> #include <linux/err.h> -#include <linux/opp.h> +#include <linux/pm_opp.h> #include <linux/export.h> #include <linux/suspend.h> #include <linux/cpu.h> @@ -131,7 +131,7 @@ static int __init omap2_set_init_voltage(char *vdd_name, char *clk_name, { struct voltagedomain *voltdm; struct clk *clk; - struct opp *opp; + struct dev_pm_opp *opp; unsigned long freq, bootup_volt; struct device *dev; @@ -172,7 +172,7 @@ static int __init omap2_set_init_voltage(char *vdd_name, char *clk_name, clk_put(clk); rcu_read_lock(); - opp = opp_find_freq_ceil(dev, &freq); + opp = dev_pm_opp_find_freq_ceil(dev, &freq); if (IS_ERR(opp)) { rcu_read_unlock(); pr_err("%s: unable to find boot up OPP for vdd_%s\n", @@ -180,7 +180,7 @@ static int __init omap2_set_init_voltage(char *vdd_name, char *clk_name, goto exit; } - bootup_volt = opp_get_voltage(opp); + bootup_volt = dev_pm_opp_get_voltage(opp); rcu_read_unlock(); if (!bootup_volt) { pr_err("%s: unable to find voltage corresponding to the bootup OPP for vdd_%s\n", @@ -266,7 +266,12 @@ static void __init omap4_init_voltages(void) static inline void omap_init_cpufreq(void) { - struct platform_device_info devinfo = { .name = "omap-cpufreq", }; + struct platform_device_info devinfo = { }; + + if (!of_have_populated_dt()) + devinfo.name = "omap-cpufreq"; + else + devinfo.name = "cpufreq-cpu0"; platform_device_register_full(&devinfo); } @@ -300,10 +305,11 @@ int __init omap2_common_pm_late_init(void) /* Smartreflex device init */ omap_devinit_smartreflex(); - /* cpufreq dummy device instantiation */ - omap_init_cpufreq(); } + /* cpufreq dummy device instantiation */ + omap_init_cpufreq(); + #ifdef CONFIG_SUSPEND suspend_set_ops(&omap_pm_ops); #endif diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c index ce956b0a7ba4..8c0759496c8d 100644 --- a/arch/arm/mach-omap2/pm24xx.c +++ b/arch/arm/mach-omap2/pm24xx.c @@ -62,16 +62,6 @@ static struct clockdomain *dsp_clkdm, *mpu_clkdm, *wkup_clkdm, *gfx_clkdm; static struct clk *osc_ck, *emul_ck; -static int omap2_fclks_active(void) -{ - u32 f1, f2; - - f1 = omap2_cm_read_mod_reg(CORE_MOD, CM_FCLKEN1); - f2 = omap2_cm_read_mod_reg(CORE_MOD, OMAP24XX_CM_FCLKEN2); - - return (f1 | f2) ? 1 : 0; -} - static int omap2_enter_full_retention(void) { u32 l; @@ -142,17 +132,7 @@ static int sti_console_enabled; static int omap2_allow_mpu_retention(void) { - u32 l; - - /* Check for MMC, UART2, UART1, McSPI2, McSPI1 and DSS1. */ - l = omap2_cm_read_mod_reg(CORE_MOD, CM_FCLKEN1); - if (l & (OMAP2420_EN_MMC_MASK | OMAP24XX_EN_UART2_MASK | - OMAP24XX_EN_UART1_MASK | OMAP24XX_EN_MCSPI2_MASK | - OMAP24XX_EN_MCSPI1_MASK | OMAP24XX_EN_DSS1_MASK)) - return 0; - /* Check for UART3. */ - l = omap2_cm_read_mod_reg(CORE_MOD, OMAP24XX_CM_FCLKEN2); - if (l & OMAP24XX_EN_UART3_MASK) + if (!omap2xxx_cm_mpu_retention_allowed()) return 0; if (sti_console_enabled) return 0; @@ -188,7 +168,7 @@ static void omap2_enter_mpu_retention(void) static int omap2_can_sleep(void) { - if (omap2_fclks_active()) + if (omap2xxx_cm_fclks_active()) return 0; if (__clk_is_enabled(osc_ck)) return 0; diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 5a2d8034c8de..93b80e5da8d4 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -430,8 +430,7 @@ static void __init omap3_iva_idle(void) OMAP3430_IVA2_MOD, CM_FCLKEN); /* Set IVA2 boot mode to 'idle' */ - omap_ctrl_writel(OMAP3_IVA2_BOOTMOD_IDLE, - OMAP343X_CONTROL_IVA2_BOOTMOD); + omap3_ctrl_set_iva_bootmode_idle(); /* Un-reset IVA2 */ omap2_prm_write_mod_reg(0, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL); diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h index baf3d8bf6bea..da5a59ae77b6 100644 --- a/arch/arm/mach-omap2/powerdomain.h +++ b/arch/arm/mach-omap2/powerdomain.h @@ -257,6 +257,7 @@ extern void am33xx_powerdomains_init(void); extern void omap44xx_powerdomains_init(void); extern void omap54xx_powerdomains_init(void); extern void dra7xx_powerdomains_init(void); +void am43xx_powerdomains_init(void); extern struct pwrdm_ops omap2_pwrdm_operations; extern struct pwrdm_ops omap3_pwrdm_operations; diff --git a/arch/arm/mach-omap2/powerdomains43xx_data.c b/arch/arm/mach-omap2/powerdomains43xx_data.c new file mode 100644 index 000000000000..95fee54c38ab --- /dev/null +++ b/arch/arm/mach-omap2/powerdomains43xx_data.c @@ -0,0 +1,136 @@ +/* + * AM43xx Power domains framework + * + * Copyright (C) 2013 Texas Instruments, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/init.h> + +#include "powerdomain.h" + +#include "prcm-common.h" +#include "prcm44xx.h" +#include "prcm43xx.h" + +static struct powerdomain gfx_43xx_pwrdm = { + .name = "gfx_pwrdm", + .voltdm = { .name = "core" }, + .prcm_offs = AM43XX_PRM_GFX_INST, + .prcm_partition = AM43XX_PRM_PARTITION, + .pwrsts = PWRSTS_OFF_ON, + .banks = 1, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* gfx_mem */ + }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, +}; + +static struct powerdomain mpu_43xx_pwrdm = { + .name = "mpu_pwrdm", + .voltdm = { .name = "mpu" }, + .prcm_offs = AM43XX_PRM_MPU_INST, + .prcm_partition = AM43XX_PRM_PARTITION, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF_RET, + .banks = 3, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* mpu_l1 */ + [1] = PWRSTS_OFF_RET, /* mpu_l2 */ + [2] = PWRSTS_OFF_RET, /* mpu_ram */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* mpu_l1 */ + [1] = PWRSTS_ON, /* mpu_l2 */ + [2] = PWRSTS_ON, /* mpu_ram */ + }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, +}; + +static struct powerdomain rtc_43xx_pwrdm = { + .name = "rtc_pwrdm", + .voltdm = { .name = "rtc" }, + .prcm_offs = AM43XX_PRM_RTC_INST, + .prcm_partition = AM43XX_PRM_PARTITION, + .pwrsts = PWRSTS_ON, +}; + +static struct powerdomain wkup_43xx_pwrdm = { + .name = "wkup_pwrdm", + .voltdm = { .name = "core" }, + .prcm_offs = AM43XX_PRM_WKUP_INST, + .prcm_partition = AM43XX_PRM_PARTITION, + .pwrsts = PWRSTS_ON, + .banks = 1, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* debugss_mem */ + }, +}; + +static struct powerdomain tamper_43xx_pwrdm = { + .name = "tamper_pwrdm", + .voltdm = { .name = "tamper" }, + .prcm_offs = AM43XX_PRM_TAMPER_INST, + .prcm_partition = AM43XX_PRM_PARTITION, + .pwrsts = PWRSTS_ON, +}; + +static struct powerdomain cefuse_43xx_pwrdm = { + .name = "cefuse_pwrdm", + .voltdm = { .name = "core" }, + .prcm_offs = AM43XX_PRM_CEFUSE_INST, + .prcm_partition = AM43XX_PRM_PARTITION, + .pwrsts = PWRSTS_OFF_ON, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, +}; + +static struct powerdomain per_43xx_pwrdm = { + .name = "per_pwrdm", + .voltdm = { .name = "core" }, + .prcm_offs = AM43XX_PRM_PER_INST, + .prcm_partition = AM43XX_PRM_PARTITION, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF_RET, + .banks = 4, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* icss_mem */ + [1] = PWRSTS_OFF_RET, /* per_mem */ + [2] = PWRSTS_OFF_RET, /* ram1_mem */ + [3] = PWRSTS_OFF_RET, /* ram2_mem */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* icss_mem */ + [1] = PWRSTS_ON, /* per_mem */ + [2] = PWRSTS_ON, /* ram1_mem */ + [3] = PWRSTS_ON, /* ram2_mem */ + }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, +}; + +static struct powerdomain *powerdomains_am43xx[] __initdata = { + &gfx_43xx_pwrdm, + &mpu_43xx_pwrdm, + &rtc_43xx_pwrdm, + &wkup_43xx_pwrdm, + &tamper_43xx_pwrdm, + &cefuse_43xx_pwrdm, + &per_43xx_pwrdm, + NULL +}; + +static int am43xx_check_vcvp(void) +{ + return 0; +} + +void __init am43xx_powerdomains_init(void) +{ + omap4_pwrdm_operations.pwrdm_has_voltdm = am43xx_check_vcvp; + pwrdm_register_platform_funcs(&omap4_pwrdm_operations); + pwrdm_register_pwrdms(powerdomains_am43xx); + pwrdm_complete_init(); +} diff --git a/arch/arm/mach-omap2/prcm43xx.h b/arch/arm/mach-omap2/prcm43xx.h new file mode 100644 index 000000000000..7785be984edd --- /dev/null +++ b/arch/arm/mach-omap2/prcm43xx.h @@ -0,0 +1,146 @@ +/* + * AM43x PRCM defines + * + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.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 __ARCH_ARM_MACH_OMAP2_PRCM_43XX_H +#define __ARCH_ARM_MACH_OMAP2_PRCM_43XX_H + +#define AM43XX_PRM_PARTITION 1 +#define AM43XX_CM_PARTITION 1 + +/* PRM instances */ +#define AM43XX_PRM_OCP_SOCKET_INST 0x0000 +#define AM43XX_PRM_MPU_INST 0x0300 +#define AM43XX_PRM_GFX_INST 0x0400 +#define AM43XX_PRM_RTC_INST 0x0500 +#define AM43XX_PRM_TAMPER_INST 0x0600 +#define AM43XX_PRM_CEFUSE_INST 0x0700 +#define AM43XX_PRM_PER_INST 0x0800 +#define AM43XX_PRM_WKUP_INST 0x2000 +#define AM43XX_PRM_DEVICE_INST 0x4000 + +/* RM RSTCTRL offsets */ +#define AM43XX_RM_PER_RSTCTRL_OFFSET 0x0010 +#define AM43XX_RM_GFX_RSTCTRL_OFFSET 0x0010 +#define AM43XX_RM_WKUP_RSTCTRL_OFFSET 0x0010 + +/* RM RSTST offsets */ +#define AM43XX_RM_GFX_RSTST_OFFSET 0x0014 +#define AM43XX_RM_WKUP_RSTST_OFFSET 0x0014 + +/* CM instances */ +#define AM43XX_CM_WKUP_INST 0x2800 +#define AM43XX_CM_DEVICE_INST 0x4100 +#define AM43XX_CM_DPLL_INST 0x4200 +#define AM43XX_CM_MPU_INST 0x8300 +#define AM43XX_CM_GFX_INST 0x8400 +#define AM43XX_CM_RTC_INST 0x8500 +#define AM43XX_CM_TAMPER_INST 0x8600 +#define AM43XX_CM_CEFUSE_INST 0x8700 +#define AM43XX_CM_PER_INST 0x8800 + +/* CD offsets */ +#define AM43XX_CM_WKUP_L3_AON_CDOFFS 0x0000 +#define AM43XX_CM_WKUP_L3S_TSC_CDOFFS 0x0100 +#define AM43XX_CM_WKUP_L4_WKUP_AON_CDOFFS 0x0200 +#define AM43XX_CM_WKUP_WKUP_CDOFFS 0x0300 +#define AM43XX_CM_MPU_MPU_CDOFFS 0x0000 +#define AM43XX_CM_GFX_GFX_L3_CDOFFS 0x0000 +#define AM43XX_CM_RTC_RTC_CDOFFS 0x0000 +#define AM43XX_CM_TAMPER_TAMPER_CDOFFS 0x0000 +#define AM43XX_CM_CEFUSE_CEFUSE_CDOFFS 0x0000 +#define AM43XX_CM_PER_L3_CDOFFS 0x0000 +#define AM43XX_CM_PER_L3S_CDOFFS 0x0200 +#define AM43XX_CM_PER_ICSS_CDOFFS 0x0300 +#define AM43XX_CM_PER_L4LS_CDOFFS 0x0400 +#define AM43XX_CM_PER_EMIF_CDOFFS 0x0700 +#define AM43XX_CM_PER_DSS_CDOFFS 0x0a00 +#define AM43XX_CM_PER_CPSW_CDOFFS 0x0b00 +#define AM43XX_CM_PER_OCPWP_L3_CDOFFS 0x0c00 + +/* CLK CTRL offsets */ +#define AM43XX_CM_PER_UART1_CLKCTRL_OFFSET 0x0580 +#define AM43XX_CM_PER_UART2_CLKCTRL_OFFSET 0x0588 +#define AM43XX_CM_PER_UART3_CLKCTRL_OFFSET 0x0590 +#define AM43XX_CM_PER_UART4_CLKCTRL_OFFSET 0x0598 +#define AM43XX_CM_PER_UART5_CLKCTRL_OFFSET 0x05a0 +#define AM43XX_CM_PER_DCAN0_CLKCTRL_OFFSET 0x0428 +#define AM43XX_CM_PER_DCAN1_CLKCTRL_OFFSET 0x0430 +#define AM43XX_CM_PER_ELM_CLKCTRL_OFFSET 0x0468 +#define AM43XX_CM_PER_EPWMSS0_CLKCTRL_OFFSET 0x0438 +#define AM43XX_CM_PER_EPWMSS1_CLKCTRL_OFFSET 0x0440 +#define AM43XX_CM_PER_EPWMSS2_CLKCTRL_OFFSET 0x0448 +#define AM43XX_CM_PER_GPIO1_CLKCTRL_OFFSET 0x0478 +#define AM43XX_CM_PER_GPIO2_CLKCTRL_OFFSET 0x0480 +#define AM43XX_CM_PER_GPIO3_CLKCTRL_OFFSET 0x0488 +#define AM43XX_CM_PER_I2C1_CLKCTRL_OFFSET 0x04a8 +#define AM43XX_CM_PER_I2C2_CLKCTRL_OFFSET 0x04b0 +#define AM43XX_CM_PER_MAILBOX0_CLKCTRL_OFFSET 0x04b8 +#define AM43XX_CM_PER_MMC0_CLKCTRL_OFFSET 0x04c0 +#define AM43XX_CM_PER_MMC1_CLKCTRL_OFFSET 0x04c8 +#define AM43XX_CM_PER_SPI0_CLKCTRL_OFFSET 0x0500 +#define AM43XX_CM_PER_SPI1_CLKCTRL_OFFSET 0x0508 +#define AM43XX_CM_PER_SPINLOCK_CLKCTRL_OFFSET 0x0528 +#define AM43XX_CM_PER_TIMER2_CLKCTRL_OFFSET 0x0530 +#define AM43XX_CM_PER_TIMER3_CLKCTRL_OFFSET 0x0538 +#define AM43XX_CM_PER_TIMER4_CLKCTRL_OFFSET 0x0540 +#define AM43XX_CM_PER_TIMER5_CLKCTRL_OFFSET 0x0548 +#define AM43XX_CM_PER_TIMER6_CLKCTRL_OFFSET 0x0550 +#define AM43XX_CM_PER_TIMER7_CLKCTRL_OFFSET 0x0558 +#define AM43XX_CM_WKUP_WKUP_M3_CLKCTRL_OFFSET 0x0228 +#define AM43XX_CM_WKUP_CONTROL_CLKCTRL_OFFSET 0x0360 +#define AM43XX_CM_WKUP_SMARTREFLEX0_CLKCTRL_OFFSET 0x0350 +#define AM43XX_CM_WKUP_SMARTREFLEX1_CLKCTRL_OFFSET 0x0358 +#define AM43XX_CM_WKUP_UART0_CLKCTRL_OFFSET 0x0348 +#define AM43XX_CM_WKUP_TIMER1_CLKCTRL_OFFSET 0x0328 +#define AM43XX_CM_WKUP_I2C0_CLKCTRL_OFFSET 0x0340 +#define AM43XX_CM_WKUP_GPIO0_CLKCTRL_OFFSET 0x0368 +#define AM43XX_CM_WKUP_ADC_TSC_CLKCTRL_OFFSET 0x0120 +#define AM43XX_CM_WKUP_WDT1_CLKCTRL_OFFSET 0x0338 +#define AM43XX_CM_WKUP_L4WKUP_CLKCTRL_OFFSET 0x0220 +#define AM43XX_CM_RTC_RTC_CLKCTRL_OFFSET 0x0020 +#define AM43XX_CM_PER_MMC2_CLKCTRL_OFFSET 0x0248 +#define AM43XX_CM_PER_QSPI_CLKCTRL_OFFSET 0x0258 +#define AM43XX_CM_PER_GPMC_CLKCTRL_OFFSET 0x0220 +#define AM43XX_CM_PER_MCASP0_CLKCTRL_OFFSET 0x0238 +#define AM43XX_CM_PER_MCASP1_CLKCTRL_OFFSET 0x0240 +#define AM43XX_CM_PER_L4LS_CLKCTRL_OFFSET 0x0420 +#define AM43XX_CM_PER_L3_CLKCTRL_OFFSET 0x0020 +#define AM43XX_CM_PER_TPCC_CLKCTRL_OFFSET 0x0078 +#define AM43XX_CM_PER_TPTC0_CLKCTRL_OFFSET 0x0080 +#define AM43XX_CM_PER_TPTC1_CLKCTRL_OFFSET 0x0088 +#define AM43XX_CM_PER_TPTC2_CLKCTRL_OFFSET 0x0090 +#define AM43XX_CM_PER_CPGMAC0_CLKCTRL_OFFSET 0x0b20 +#define AM43XX_CM_PER_PRUSS_CLKCTRL_OFFSET 0x0320 +#define AM43XX_CM_GFX_GFX_CLKCTRL_OFFSET 0x0020 +#define AM43XX_CM_PER_L4HS_CLKCTRL_OFFSET 0x00a0 +#define AM43XX_CM_MPU_MPU_CLKCTRL_OFFSET 0x0020 +#define AM43XX_CM_PER_L3_INSTR_CLKCTRL_OFFSET 0x0040 +#define AM43XX_CM_PER_OCMCRAM_CLKCTRL_OFFSET 0x0050 +#define AM43XX_CM_PER_SHA0_CLKCTRL_OFFSET 0x0058 +#define AM43XX_CM_PER_AES0_CLKCTRL_OFFSET 0x0028 +#define AM43XX_CM_PER_TIMER8_CLKCTRL_OFFSET 0x0560 +#define AM43XX_CM_PER_TIMER9_CLKCTRL_OFFSET 0x0568 +#define AM43XX_CM_PER_TIMER10_CLKCTRL_OFFSET 0x0570 +#define AM43XX_CM_PER_TIMER11_CLKCTRL_OFFSET 0x0578 +#define AM43XX_CM_WKUP_SYNCTIMER_CLKCTRL_OFFSET 0x0230 +#define AM43XX_CM_PER_EPWMSS3_CLKCTRL_OFFSET 0x0450 +#define AM43XX_CM_PER_EPWMSS4_CLKCTRL_OFFSET 0x0458 +#define AM43XX_CM_PER_EPWMSS5_CLKCTRL_OFFSET 0x0460 +#define AM43XX_CM_PER_SPI2_CLKCTRL_OFFSET 0x0510 +#define AM43XX_CM_PER_SPI3_CLKCTRL_OFFSET 0x0518 +#define AM43XX_CM_PER_SPI4_CLKCTRL_OFFSET 0x0520 +#define AM43XX_CM_PER_GPIO4_CLKCTRL_OFFSET 0x0490 +#define AM43XX_CM_PER_GPIO5_CLKCTRL_OFFSET 0x0498 +#define AM43XX_CM_PER_USB_OTG_SS0_CLKCTRL_OFFSET 0x0260 +#define AM43XX_CM_PER_USBPHYOCP2SCP0_CLKCTRL_OFFSET 0x05B8 +#define AM43XX_CM_PER_USB_OTG_SS1_CLKCTRL_OFFSET 0x0268 +#define AM43XX_CM_PER_USBPHYOCP2SCP1_CLKCTRL_OFFSET 0x05C0 + +#endif diff --git a/arch/arm/mach-omap2/prm3xxx.h b/arch/arm/mach-omap2/prm3xxx.h index 277f71794e61..f8eb83323b1a 100644 --- a/arch/arm/mach-omap2/prm3xxx.h +++ b/arch/arm/mach-omap2/prm3xxx.h @@ -144,7 +144,13 @@ extern u32 omap3_prm_vcvp_read(u8 offset); extern void omap3_prm_vcvp_write(u32 val, u8 offset); extern u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset); -extern void omap3xxx_prm_reconfigure_io_chain(void); +#ifdef CONFIG_ARCH_OMAP3 +void omap3xxx_prm_reconfigure_io_chain(void); +#else +static inline void omap3xxx_prm_reconfigure_io_chain(void) +{ +} +#endif /* PRM interrupt-related functions */ extern void omap3xxx_prm_read_pending_irqs(unsigned long *events); diff --git a/arch/arm/mach-omap2/prm44xx_54xx.h b/arch/arm/mach-omap2/prm44xx_54xx.h index 7cd22abb8f15..7a976065e138 100644 --- a/arch/arm/mach-omap2/prm44xx_54xx.h +++ b/arch/arm/mach-omap2/prm44xx_54xx.h @@ -42,7 +42,14 @@ extern u32 omap4_prm_vcvp_read(u8 offset); extern void omap4_prm_vcvp_write(u32 val, u8 offset); extern u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset); -extern void omap44xx_prm_reconfigure_io_chain(void); +#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \ + defined(CONFIG_SOC_DRA7XX) +void omap44xx_prm_reconfigure_io_chain(void); +#else +static inline void omap44xx_prm_reconfigure_io_chain(void) +{ +} +#endif /* PRM interrupt-related functions */ extern void omap44xx_prm_read_pending_irqs(unsigned long *events); diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c index 228b850e632f..a2e1174ad1b6 100644 --- a/arch/arm/mach-omap2/prm_common.c +++ b/arch/arm/mach-omap2/prm_common.c @@ -24,6 +24,7 @@ #include <linux/interrupt.h> #include <linux/slab.h> +#include "soc.h" #include "prm2xxx_3xxx.h" #include "prm2xxx.h" #include "prm3xxx.h" @@ -322,6 +323,16 @@ int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup) prcm_irq_chips[i] = gc; } + if (of_have_populated_dt()) { + int irq = omap_prcm_event_to_irq("io"); + if (cpu_is_omap34xx()) + omap_pcs_legacy_init(irq, + omap3xxx_prm_reconfigure_io_chain); + else + omap_pcs_legacy_init(irq, + omap44xx_prm_reconfigure_io_chain); + } + return 0; err: diff --git a/arch/arm/mach-omap2/soc.h b/arch/arm/mach-omap2/soc.h index 4588df1447ed..076bd90a6ce0 100644 --- a/arch/arm/mach-omap2/soc.h +++ b/arch/arm/mach-omap2/soc.h @@ -455,9 +455,7 @@ IS_OMAP_TYPE(3430, 0x3430) #define OMAP4470_REV_ES1_0 (OMAP447X_CLASS | (0x10 << 8)) #define OMAP54XX_CLASS 0x54000054 -#define OMAP5430_REV_ES1_0 (OMAP54XX_CLASS | (0x30 << 16) | (0x10 << 8)) #define OMAP5430_REV_ES2_0 (OMAP54XX_CLASS | (0x30 << 16) | (0x20 << 8)) -#define OMAP5432_REV_ES1_0 (OMAP54XX_CLASS | (0x32 << 16) | (0x10 << 8)) #define OMAP5432_REV_ES2_0 (OMAP54XX_CLASS | (0x32 << 16) | (0x20 << 8)) void omap2xxx_check_revision(void); diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index ead48fa5715e..3ca81e0ada5e 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -55,6 +55,7 @@ #include "soc.h" #include "common.h" #include "powerdomain.h" +#include "omap-secure.h" #define REALTIME_COUNTER_BASE 0x48243200 #define INCREMENTER_NUMERATOR_OFFSET 0x10 @@ -66,6 +67,15 @@ static struct omap_dm_timer clkev; static struct clock_event_device clockevent_gpt; +#ifdef CONFIG_SOC_HAS_REALTIME_COUNTER +static unsigned long arch_timer_freq; + +void set_cntfreq(void) +{ + omap_smc1(OMAP5_DRA7_MON_SET_CNTFRQ_INDEX, arch_timer_freq); +} +#endif + static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id) { struct clock_event_device *evt = &clockevent_gpt; @@ -78,7 +88,7 @@ static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id) static struct irqaction omap2_gp_timer_irq = { .name = "gp_timer", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .flags = IRQF_TIMER | IRQF_IRQPOLL, .handler = omap2_gp_timer_interrupt, }; @@ -515,6 +525,10 @@ static void __init realtime_counter_init(void) num = 8; den = 25; break; + case 20000000: + num = 192; + den = 625; + break; case 2600000: num = 384; den = 1625; @@ -542,6 +556,9 @@ static void __init realtime_counter_init(void) reg |= den; __raw_writel(reg, base + INCREMENTER_DENUMERATOR_RELOAD_OFFSET); + arch_timer_freq = (rate / den) * num; + set_cntfreq(); + iounmap(base); } #else diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c index c05898fbd634..b0d54dae1bcb 100644 --- a/arch/arm/mach-omap2/twl-common.c +++ b/arch/arm/mach-omap2/twl-common.c @@ -24,6 +24,7 @@ #include <linux/i2c/twl.h> #include <linux/gpio.h> #include <linux/string.h> +#include <linux/phy/phy.h> #include <linux/regulator/machine.h> #include <linux/regulator/fixed.h> @@ -90,8 +91,18 @@ void __init omap_pmic_late_init(void) } #if defined(CONFIG_ARCH_OMAP3) +struct phy_consumer consumers[] = { + PHY_CONSUMER("musb-hdrc.0", "usb"), +}; + +struct phy_init_data init_data = { + .consumers = consumers, + .num_consumers = ARRAY_SIZE(consumers), +}; + static struct twl4030_usb_data omap3_usb_pdata = { .usb_mode = T2_USB_MODE_ULPI, + .init_data = &init_data, }; static int omap3_batt_table[] = { diff --git a/arch/arm/mach-omap2/usb-host.c b/arch/arm/mach-omap2/usb-host.c index e83a6a4b184a..10855eb4ccc1 100644 --- a/arch/arm/mach-omap2/usb-host.c +++ b/arch/arm/mach-omap2/usb-host.c @@ -435,6 +435,7 @@ int usbhs_init_phys(struct usbhs_phy_data *phy, int num_phys) struct platform_device *pdev; char *phy_id; struct platform_device_info pdevinfo; + struct usb_phy_gen_xceiv_platform_data nop_pdata; for (i = 0; i < num_phys; i++) { @@ -455,11 +456,18 @@ int usbhs_init_phys(struct usbhs_phy_data *phy, int num_phys) return -ENOMEM; } + /* set platform data */ + memset(&nop_pdata, 0, sizeof(nop_pdata)); + if (gpio_is_valid(phy->vcc_gpio)) + nop_pdata.needs_vcc = true; + nop_pdata.gpio_reset = phy->reset_gpio; + nop_pdata.type = USB_PHY_TYPE_USB2; + /* create a NOP PHY device */ memset(&pdevinfo, 0, sizeof(pdevinfo)); pdevinfo.name = nop_name; pdevinfo.id = phy->port; - pdevinfo.data = phy->platform_data; + pdevinfo.data = &nop_pdata; pdevinfo.size_data = sizeof(struct usb_phy_gen_xceiv_platform_data); scnprintf(phy_id, MAX_STR, "usb_phy_gen_xceiv.%d", @@ -474,14 +482,6 @@ int usbhs_init_phys(struct usbhs_phy_data *phy, int num_phys) usb_bind_phy("ehci-omap.0", phy->port - 1, phy_id); - /* Do we need RESET regulator ? */ - if (gpio_is_valid(phy->reset_gpio)) { - scnprintf(rail_name, MAX_STR, - "hsusb%d_reset", phy->port); - usbhs_add_regulator(rail_name, phy_id, "reset", - phy->reset_gpio, 1); - } - /* Do we need VCC regulator ? */ if (gpio_is_valid(phy->vcc_gpio)) { scnprintf(rail_name, MAX_STR, "hsusb%d_vcc", phy->port); diff --git a/arch/arm/mach-omap2/usb.h b/arch/arm/mach-omap2/usb.h index e7261ebcf7b0..4ba2ae759895 100644 --- a/arch/arm/mach-omap2/usb.h +++ b/arch/arm/mach-omap2/usb.h @@ -58,7 +58,6 @@ struct usbhs_phy_data { int reset_gpio; int vcc_gpio; bool vcc_polarity; /* 1 active high, 0 active low */ - void *platform_data; }; extern void usb_musb_init(struct omap_musb_board_data *board_data); diff --git a/arch/arm/mach-prima2/common.c b/arch/arm/mach-prima2/common.c index e110b6d4ae8c..d49aff74de98 100644 --- a/arch/arm/mach-prima2/common.c +++ b/arch/arm/mach-prima2/common.c @@ -6,7 +6,6 @@ * Licensed under GPLv2 or later. */ -#include <linux/clocksource.h> #include <linux/init.h> #include <linux/kernel.h> #include <asm/sizes.h> @@ -21,13 +20,6 @@ void __init sirfsoc_init_late(void) sirfsoc_pm_init(); } -static __init void sirfsoc_init_time(void) -{ - /* initialize clocking early, we want to set the OS timer */ - sirfsoc_of_clk_init(); - clocksource_of_init(); -} - static __init void sirfsoc_map_io(void) { sirfsoc_map_lluart(); @@ -43,7 +35,6 @@ static const char *atlas6_dt_match[] __initdata = { DT_MACHINE_START(ATLAS6_DT, "Generic ATLAS6 (Flattened Device Tree)") /* Maintainer: Barry Song <baohua.song@csr.com> */ .map_io = sirfsoc_map_io, - .init_time = sirfsoc_init_time, .init_late = sirfsoc_init_late, .dt_compat = atlas6_dt_match, .restart = sirfsoc_restart, @@ -59,7 +50,6 @@ static const char *prima2_dt_match[] __initdata = { DT_MACHINE_START(PRIMA2_DT, "Generic PRIMA2 (Flattened Device Tree)") /* Maintainer: Barry Song <baohua.song@csr.com> */ .map_io = sirfsoc_map_io, - .init_time = sirfsoc_init_time, .dma_zone_size = SZ_256M, .init_late = sirfsoc_init_late, .dt_compat = prima2_dt_match, @@ -77,7 +67,6 @@ DT_MACHINE_START(MARCO_DT, "Generic MARCO (Flattened Device Tree)") /* Maintainer: Barry Song <baohua.song@csr.com> */ .smp = smp_ops(sirfsoc_smp_ops), .map_io = sirfsoc_map_io, - .init_time = sirfsoc_init_time, .init_late = sirfsoc_init_late, .dt_compat = marco_dt_match, .restart = sirfsoc_restart, diff --git a/arch/arm/mach-prima2/common.h b/arch/arm/mach-prima2/common.h index a6304858474a..4b768060a858 100644 --- a/arch/arm/mach-prima2/common.h +++ b/arch/arm/mach-prima2/common.h @@ -23,7 +23,6 @@ extern void sirfsoc_secondary_startup(void); extern void sirfsoc_cpu_die(unsigned int cpu); extern void __init sirfsoc_of_irq_init(void); -extern void __init sirfsoc_of_clk_init(void); extern void sirfsoc_restart(enum reboot_mode, const char *); extern asmlinkage void __exception_irq_entry sirfsoc_handle_irq(struct pt_regs *regs); diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index a8427115ee07..96100dbf5a2e 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -615,14 +615,12 @@ endmenu config PXA25x bool select CPU_XSCALE - select CPU_FREQ_TABLE if CPU_FREQ help Select code specific to PXA21x/25x/26x variants config PXA27x bool select CPU_XSCALE - select CPU_FREQ_TABLE if CPU_FREQ help Select code specific to PXA27x variants @@ -635,7 +633,6 @@ config CPU_PXA26x config PXA3xx bool select CPU_XSC3 - select CPU_FREQ_TABLE if CPU_FREQ help Select code specific to PXA3xx variants diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c index f9423493ed36..584439bfa59f 100644 --- a/arch/arm/mach-pxa/cm-x300.c +++ b/arch/arm/mach-pxa/cm-x300.c @@ -310,6 +310,7 @@ static struct platform_pwm_backlight_data cm_x300_backlight_data = { .max_brightness = 100, .dft_brightness = 100, .pwm_period_ns = 10000, + .enable_gpio = -1, }; static struct platform_device cm_x300_backlight_device = { diff --git a/arch/arm/mach-pxa/colibri-pxa270-income.c b/arch/arm/mach-pxa/colibri-pxa270-income.c index 2d4a7b4d5d78..3aa264640c9d 100644 --- a/arch/arm/mach-pxa/colibri-pxa270-income.c +++ b/arch/arm/mach-pxa/colibri-pxa270-income.c @@ -189,6 +189,7 @@ static struct platform_pwm_backlight_data income_backlight_data = { .max_brightness = 0x3ff, .dft_brightness = 0x1ff, .pwm_period_ns = 1000000, + .enable_gpio = -1, }; static struct platform_device income_backlight = { diff --git a/arch/arm/mach-pxa/ezx.c b/arch/arm/mach-pxa/ezx.c index fe2eb8394dff..ab93441e596e 100644 --- a/arch/arm/mach-pxa/ezx.c +++ b/arch/arm/mach-pxa/ezx.c @@ -54,6 +54,7 @@ static struct platform_pwm_backlight_data ezx_backlight_data = { .max_brightness = 1023, .dft_brightness = 1023, .pwm_period_ns = 78770, + .enable_gpio = -1, }; static struct platform_device ezx_backlight_device = { diff --git a/arch/arm/mach-pxa/hx4700.c b/arch/arm/mach-pxa/hx4700.c index 133109ec7332..a7c30eb0c8db 100644 --- a/arch/arm/mach-pxa/hx4700.c +++ b/arch/arm/mach-pxa/hx4700.c @@ -561,6 +561,7 @@ static struct platform_pwm_backlight_data backlight_data = { .max_brightness = 200, .dft_brightness = 100, .pwm_period_ns = 30923, + .enable_gpio = -1, }; static struct platform_device backlight = { diff --git a/arch/arm/mach-pxa/include/mach/gpio.h b/arch/arm/mach-pxa/include/mach/gpio.h deleted file mode 100644 index 0248e433bc98..000000000000 --- a/arch/arm/mach-pxa/include/mach/gpio.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * arch/arm/mach-pxa/include/mach/gpio.h - * - * PXA GPIO wrappers for arch-neutral GPIO calls - * - * Written by Philipp Zabel <philipp.zabel@gmail.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __ASM_ARCH_PXA_GPIO_H -#define __ASM_ARCH_PXA_GPIO_H - -#include <asm-generic/gpio.h> - -#include <mach/irqs.h> -#include <mach/hardware.h> - -#endif diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c index 1255ee00f3d1..9f6ec167902a 100644 --- a/arch/arm/mach-pxa/lpd270.c +++ b/arch/arm/mach-pxa/lpd270.c @@ -269,6 +269,7 @@ static struct platform_pwm_backlight_data lpd270_backlight_data = { .max_brightness = 1, .dft_brightness = 1, .pwm_period_ns = 78770, + .enable_gpio = -1, }; static struct platform_device lpd270_backlight_device = { diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c index f44532fc648b..fab30d666cc7 100644 --- a/arch/arm/mach-pxa/magician.c +++ b/arch/arm/mach-pxa/magician.c @@ -378,6 +378,7 @@ static struct platform_pwm_backlight_data backlight_data = { .max_brightness = 272, .dft_brightness = 100, .pwm_period_ns = 30923, + .enable_gpio = -1, .init = magician_backlight_init, .notify = magician_backlight_notify, .exit = magician_backlight_exit, diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index dd70343c8708..08ccc0718f31 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c @@ -338,6 +338,7 @@ static struct platform_pwm_backlight_data mainstone_backlight_data = { .max_brightness = 1023, .dft_brightness = 1023, .pwm_period_ns = 78770, + .enable_gpio = -1, }; static struct platform_device mainstone_backlight_device = { diff --git a/arch/arm/mach-pxa/mioa701.c b/arch/arm/mach-pxa/mioa701.c index acc9d3cc0762..f70583fee59f 100644 --- a/arch/arm/mach-pxa/mioa701.c +++ b/arch/arm/mach-pxa/mioa701.c @@ -186,6 +186,7 @@ static struct platform_pwm_backlight_data mioa701_backlight_data = { .max_brightness = 100, .dft_brightness = 50, .pwm_period_ns = 4000 * 1024, /* Fl = 250kHz */ + .enable_gpio = -1, }; /* diff --git a/arch/arm/mach-pxa/palm27x.c b/arch/arm/mach-pxa/palm27x.c index 17d4c53017ca..e54a296fb81f 100644 --- a/arch/arm/mach-pxa/palm27x.c +++ b/arch/arm/mach-pxa/palm27x.c @@ -322,6 +322,7 @@ static struct platform_pwm_backlight_data palm27x_backlight_data = { .max_brightness = 0xfe, .dft_brightness = 0x7e, .pwm_period_ns = 3500 * 1024, + .enable_gpio = -1, .init = palm27x_backlight_init, .notify = palm27x_backlight_notify, .exit = palm27x_backlight_exit, diff --git a/arch/arm/mach-pxa/palmtc.c b/arch/arm/mach-pxa/palmtc.c index 100b176f7e88..7691c974ca4b 100644 --- a/arch/arm/mach-pxa/palmtc.c +++ b/arch/arm/mach-pxa/palmtc.c @@ -166,45 +166,12 @@ static inline void palmtc_keys_init(void) {} * Backlight ******************************************************************************/ #if defined(CONFIG_BACKLIGHT_PWM) || defined(CONFIG_BACKLIGHT_PWM_MODULE) -static int palmtc_backlight_init(struct device *dev) -{ - int ret; - - ret = gpio_request(GPIO_NR_PALMTC_BL_POWER, "BL POWER"); - if (ret) - goto err; - ret = gpio_direction_output(GPIO_NR_PALMTC_BL_POWER, 1); - if (ret) - goto err2; - - return 0; - -err2: - gpio_free(GPIO_NR_PALMTC_BL_POWER); -err: - return ret; -} - -static int palmtc_backlight_notify(struct device *dev, int brightness) -{ - /* backlight is on when GPIO16 AF0 is high */ - gpio_set_value(GPIO_NR_PALMTC_BL_POWER, brightness); - return brightness; -} - -static void palmtc_backlight_exit(struct device *dev) -{ - gpio_free(GPIO_NR_PALMTC_BL_POWER); -} - static struct platform_pwm_backlight_data palmtc_backlight_data = { .pwm_id = 1, .max_brightness = PALMTC_MAX_INTENSITY, .dft_brightness = PALMTC_MAX_INTENSITY, .pwm_period_ns = PALMTC_PERIOD_NS, - .init = palmtc_backlight_init, - .notify = palmtc_backlight_notify, - .exit = palmtc_backlight_exit, + .enable_gpio = GPIO_NR_PALMTC_BL_POWER, }; static struct platform_device palmtc_backlight = { diff --git a/arch/arm/mach-pxa/palmte2.c b/arch/arm/mach-pxa/palmte2.c index 0742721ced2d..956fd24ee6fd 100644 --- a/arch/arm/mach-pxa/palmte2.c +++ b/arch/arm/mach-pxa/palmte2.c @@ -165,6 +165,7 @@ static struct platform_pwm_backlight_data palmte2_backlight_data = { .max_brightness = PALMTE2_MAX_INTENSITY, .dft_brightness = PALMTE2_MAX_INTENSITY, .pwm_period_ns = PALMTE2_PERIOD_NS, + .enable_gpio = -1, .init = palmte2_backlight_init, .notify = palmte2_backlight_notify, .exit = palmte2_backlight_exit, diff --git a/arch/arm/mach-pxa/pcm990-baseboard.c b/arch/arm/mach-pxa/pcm990-baseboard.c index 3133ba82c508..9a4e470f162b 100644 --- a/arch/arm/mach-pxa/pcm990-baseboard.c +++ b/arch/arm/mach-pxa/pcm990-baseboard.c @@ -153,6 +153,7 @@ static struct platform_pwm_backlight_data pcm990_backlight_data = { .max_brightness = 1023, .dft_brightness = 1023, .pwm_period_ns = 78770, + .enable_gpio = -1, }; static struct platform_device pcm990_backlight_device = { diff --git a/arch/arm/mach-pxa/raumfeld.c b/arch/arm/mach-pxa/raumfeld.c index 969b0ba7fa70..8386dc30b3e4 100644 --- a/arch/arm/mach-pxa/raumfeld.c +++ b/arch/arm/mach-pxa/raumfeld.c @@ -539,6 +539,7 @@ static struct platform_pwm_backlight_data raumfeld_pwm_backlight_data = { .dft_brightness = 100, /* 10000 ns = 10 ms ^= 100 kHz */ .pwm_period_ns = 10000, + .enable_gpio = -1, }; static struct platform_device raumfeld_pwm_backlight_device = { diff --git a/arch/arm/mach-pxa/stargate2.c b/arch/arm/mach-pxa/stargate2.c index 62aea3e835f3..01de542432a6 100644 --- a/arch/arm/mach-pxa/stargate2.c +++ b/arch/arm/mach-pxa/stargate2.c @@ -27,7 +27,7 @@ #include <linux/i2c/pxa-i2c.h> #include <linux/i2c/pcf857x.h> -#include <linux/i2c/at24.h> +#include <linux/platform_data/at24.h> #include <linux/smc91x.h> #include <linux/gpio.h> #include <linux/leds.h> diff --git a/arch/arm/mach-pxa/tavorevb.c b/arch/arm/mach-pxa/tavorevb.c index 4680efe55345..a71da84e784b 100644 --- a/arch/arm/mach-pxa/tavorevb.c +++ b/arch/arm/mach-pxa/tavorevb.c @@ -175,6 +175,7 @@ static struct platform_pwm_backlight_data tavorevb_backlight_data[] = { .max_brightness = 100, .dft_brightness = 100, .pwm_period_ns = 100000, + .enable_gpio = -1, }, [1] = { /* secondary backlight */ @@ -182,6 +183,7 @@ static struct platform_pwm_backlight_data tavorevb_backlight_data[] = { .max_brightness = 100, .dft_brightness = 100, .pwm_period_ns = 100000, + .enable_gpio = -1, }, }; diff --git a/arch/arm/mach-pxa/viper.c b/arch/arm/mach-pxa/viper.c index 9c363c081d3f..29905b127ad9 100644 --- a/arch/arm/mach-pxa/viper.c +++ b/arch/arm/mach-pxa/viper.c @@ -401,6 +401,7 @@ static struct platform_pwm_backlight_data viper_backlight_data = { .max_brightness = 100, .dft_brightness = 100, .pwm_period_ns = 1000000, + .enable_gpio = -1, .init = viper_backlight_init, .notify = viper_backlight_notify, .exit = viper_backlight_exit, diff --git a/arch/arm/mach-pxa/z2.c b/arch/arm/mach-pxa/z2.c index 2513d8f4931f..e1a121b36cfa 100644 --- a/arch/arm/mach-pxa/z2.c +++ b/arch/arm/mach-pxa/z2.c @@ -206,6 +206,7 @@ static struct platform_pwm_backlight_data z2_backlight_data[] = { .max_brightness = 1023, .dft_brightness = 0, .pwm_period_ns = 1260320, + .enable_gpio = -1, }, [1] = { /* LCD Backlight */ @@ -213,6 +214,7 @@ static struct platform_pwm_backlight_data z2_backlight_data[] = { .max_brightness = 1023, .dft_brightness = 512, .pwm_period_ns = 1260320, + .enable_gpio = -1, }, }; diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c index 36cf7cf95ec1..77daea478e88 100644 --- a/arch/arm/mach-pxa/zylonite.c +++ b/arch/arm/mach-pxa/zylonite.c @@ -125,6 +125,7 @@ static struct platform_pwm_backlight_data zylonite_backlight_data = { .max_brightness = 100, .dft_brightness = 100, .pwm_period_ns = 10000, + .enable_gpio = -1, }; static struct platform_device zylonite_backlight_device = { diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig index 25ee12b21f01..cf073dea5784 100644 --- a/arch/arm/mach-rockchip/Kconfig +++ b/arch/arm/mach-rockchip/Kconfig @@ -5,12 +5,13 @@ config ARCH_ROCKCHIP select ARCH_REQUIRE_GPIOLIB select ARM_GIC select CACHE_L2X0 - select HAVE_ARM_TWD if LOCAL_TIMERS + select HAVE_ARM_TWD if SMP select HAVE_SMP - select LOCAL_TIMERS if SMP select COMMON_CLK select GENERIC_CLOCKEVENTS select DW_APB_TIMER_OF + select ARM_GLOBAL_TIMER + select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK help Support for Rockchip's Cortex-A9 Single-to-Quad-Core-SoCs containing the RK2928, RK30xx and RK31xx series. diff --git a/arch/arm/mach-rockchip/rockchip.c b/arch/arm/mach-rockchip/rockchip.c index 724d2d81f976..82c0b0709712 100644 --- a/arch/arm/mach-rockchip/rockchip.c +++ b/arch/arm/mach-rockchip/rockchip.c @@ -19,18 +19,10 @@ #include <linux/init.h> #include <linux/of_platform.h> #include <linux/irqchip.h> -#include <linux/dw_apb_timer.h> -#include <linux/clk-provider.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> #include <asm/hardware/cache-l2x0.h> -static void __init rockchip_timer_init(void) -{ - of_clk_init(NULL); - clocksource_of_init(); -} - static void __init rockchip_dt_init(void) { l2x0_of_init(0, ~0UL); @@ -47,6 +39,5 @@ static const char * const rockchip_board_dt_compat[] = { DT_MACHINE_START(ROCKCHIP_DT, "Rockchip Cortex-A9 (Device Tree)") .init_machine = rockchip_dt_init, - .init_time = rockchip_timer_init, .dt_compat = rockchip_board_dt_compat, MACHINE_END diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig index dba2173e70f3..8f1d327e0cd1 100644 --- a/arch/arm/mach-s3c24xx/Kconfig +++ b/arch/arm/mach-s3c24xx/Kconfig @@ -28,6 +28,7 @@ config CPU_S3C2410 select CPU_ARM920T select CPU_LLSERIAL_S3C2410 select S3C2410_CLOCK + select S3C2410_DMA if S3C24XX_DMA select ARM_S3C2410_CPUFREQ if ARM_S3C24XX_CPUFREQ select S3C2410_PM if PM select SAMSUNG_WDT_RESET @@ -70,6 +71,7 @@ config CPU_S3C2442 select CPU_ARM920T select CPU_LLSERIAL_S3C2440 select S3C2410_CLOCK + select S3C2410_DMA if S3C24XX_DMA select S3C2410_PM if PM help Support for S3C2442 Samsung Mobile CPU based systems. @@ -148,7 +150,6 @@ config S3C2410_DMA_DEBUG config S3C2410_DMA bool depends on S3C24XX_DMA && (CPU_S3C2410 || CPU_S3C2442) - default y if CPU_S3C2410 || CPU_S3C2442 help DMA device selection for S3C2410 and compatible CPUs diff --git a/arch/arm/mach-s3c24xx/clock-s3c2412.c b/arch/arm/mach-s3c24xx/clock-s3c2412.c index d8f253f2b486..11b3b28457bb 100644 --- a/arch/arm/mach-s3c24xx/clock-s3c2412.c +++ b/arch/arm/mach-s3c24xx/clock-s3c2412.c @@ -484,22 +484,22 @@ static struct clk init_clocks_disable[] = { static struct clk init_clocks[] = { { - .name = "dma", + .name = "dma.0", .parent = &clk_h, .enable = s3c2412_clkcon_enable, .ctrlbit = S3C2412_CLKCON_DMA0, }, { - .name = "dma", + .name = "dma.1", .parent = &clk_h, .enable = s3c2412_clkcon_enable, .ctrlbit = S3C2412_CLKCON_DMA1, }, { - .name = "dma", + .name = "dma.2", .parent = &clk_h, .enable = s3c2412_clkcon_enable, .ctrlbit = S3C2412_CLKCON_DMA2, }, { - .name = "dma", + .name = "dma.3", .parent = &clk_h, .enable = s3c2412_clkcon_enable, .ctrlbit = S3C2412_CLKCON_DMA3, diff --git a/arch/arm/mach-s3c24xx/common-s3c2443.c b/arch/arm/mach-s3c24xx/common-s3c2443.c index f6b9f2ef01bd..65d3eef73090 100644 --- a/arch/arm/mach-s3c24xx/common-s3c2443.c +++ b/arch/arm/mach-s3c24xx/common-s3c2443.c @@ -438,32 +438,32 @@ static struct clk init_clocks_off[] = { static struct clk init_clocks[] = { { - .name = "dma", + .name = "dma.0", .parent = &clk_h, .enable = s3c2443_clkcon_enable_h, .ctrlbit = S3C2443_HCLKCON_DMA0, }, { - .name = "dma", + .name = "dma.1", .parent = &clk_h, .enable = s3c2443_clkcon_enable_h, .ctrlbit = S3C2443_HCLKCON_DMA1, }, { - .name = "dma", + .name = "dma.2", .parent = &clk_h, .enable = s3c2443_clkcon_enable_h, .ctrlbit = S3C2443_HCLKCON_DMA2, }, { - .name = "dma", + .name = "dma.3", .parent = &clk_h, .enable = s3c2443_clkcon_enable_h, .ctrlbit = S3C2443_HCLKCON_DMA3, }, { - .name = "dma", + .name = "dma.4", .parent = &clk_h, .enable = s3c2443_clkcon_enable_h, .ctrlbit = S3C2443_HCLKCON_DMA4, }, { - .name = "dma", + .name = "dma.5", .parent = &clk_h, .enable = s3c2443_clkcon_enable_h, .ctrlbit = S3C2443_HCLKCON_DMA5, diff --git a/arch/arm/mach-s3c24xx/common.c b/arch/arm/mach-s3c24xx/common.c index 457261c98433..4adaa4b43ffe 100644 --- a/arch/arm/mach-s3c24xx/common.c +++ b/arch/arm/mach-s3c24xx/common.c @@ -31,6 +31,7 @@ #include <linux/platform_device.h> #include <linux/delay.h> #include <linux/io.h> +#include <linux/platform_data/dma-s3c24xx.h> #include <mach/hardware.h> #include <mach/regs-clock.h> @@ -44,6 +45,7 @@ #include <mach/regs-gpio.h> #include <plat/regs-serial.h> +#include <mach/dma.h> #include <plat/cpu.h> #include <plat/devs.h> @@ -329,3 +331,207 @@ void __init_or_cpufreq s3c24xx_setup_clocks(unsigned long fclk, clk_p.rate = pclk; clk_f.rate = fclk; } + +#if defined(CONFIG_CPU_S3C2410) || defined(CONFIG_CPU_S3C2412) || \ + defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2442) +static struct resource s3c2410_dma_resource[] = { + [0] = DEFINE_RES_MEM(S3C24XX_PA_DMA, S3C24XX_SZ_DMA), + [1] = DEFINE_RES_IRQ(IRQ_DMA0), + [2] = DEFINE_RES_IRQ(IRQ_DMA1), + [3] = DEFINE_RES_IRQ(IRQ_DMA2), + [4] = DEFINE_RES_IRQ(IRQ_DMA3), +}; +#endif + +#if defined(CONFIG_CPU_S3C2410) || defined(CONFIG_CPU_S3C2442) +static struct s3c24xx_dma_channel s3c2410_dma_channels[DMACH_MAX] = { + [DMACH_XD0] = { S3C24XX_DMA_AHB, true, S3C24XX_DMA_CHANREQ(0, 0), }, + [DMACH_XD1] = { S3C24XX_DMA_AHB, true, S3C24XX_DMA_CHANREQ(0, 1), }, + [DMACH_SDI] = { S3C24XX_DMA_APB, false, S3C24XX_DMA_CHANREQ(2, 0) | + S3C24XX_DMA_CHANREQ(2, 2) | + S3C24XX_DMA_CHANREQ(1, 3), + }, + [DMACH_SPI0] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(3, 1), }, + [DMACH_SPI1] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(2, 3), }, + [DMACH_UART0] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(1, 0), }, + [DMACH_UART1] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(1, 1), }, + [DMACH_UART2] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(0, 3), }, + [DMACH_TIMER] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(3, 0) | + S3C24XX_DMA_CHANREQ(3, 2) | + S3C24XX_DMA_CHANREQ(3, 3), + }, + [DMACH_I2S_IN] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(2, 1) | + S3C24XX_DMA_CHANREQ(1, 2), + }, + [DMACH_I2S_OUT] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(0, 2), }, + [DMACH_USB_EP1] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(4, 0), }, + [DMACH_USB_EP2] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(4, 1), }, + [DMACH_USB_EP3] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(4, 2), }, + [DMACH_USB_EP4] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(4, 3), }, +}; + +static struct s3c24xx_dma_platdata s3c2410_dma_platdata = { + .num_phy_channels = 4, + .channels = s3c2410_dma_channels, + .num_channels = DMACH_MAX, +}; + +struct platform_device s3c2410_device_dma = { + .name = "s3c2410-dma", + .id = 0, + .num_resources = ARRAY_SIZE(s3c2410_dma_resource), + .resource = s3c2410_dma_resource, + .dev = { + .platform_data = &s3c2410_dma_platdata, + }, +}; +#endif + +#ifdef CONFIG_CPU_S3C2412 +static struct s3c24xx_dma_channel s3c2412_dma_channels[DMACH_MAX] = { + [DMACH_XD0] = { S3C24XX_DMA_AHB, true, 17 }, + [DMACH_XD1] = { S3C24XX_DMA_AHB, true, 18 }, + [DMACH_SDI] = { S3C24XX_DMA_APB, false, 10 }, + [DMACH_SPI0_RX] = { S3C24XX_DMA_APB, true, 1 }, + [DMACH_SPI0_TX] = { S3C24XX_DMA_APB, true, 0 }, + [DMACH_SPI1_RX] = { S3C24XX_DMA_APB, true, 3 }, + [DMACH_SPI1_TX] = { S3C24XX_DMA_APB, true, 2 }, + [DMACH_UART0] = { S3C24XX_DMA_APB, true, 19 }, + [DMACH_UART1] = { S3C24XX_DMA_APB, true, 21 }, + [DMACH_UART2] = { S3C24XX_DMA_APB, true, 23 }, + [DMACH_UART0_SRC2] = { S3C24XX_DMA_APB, true, 20 }, + [DMACH_UART1_SRC2] = { S3C24XX_DMA_APB, true, 22 }, + [DMACH_UART2_SRC2] = { S3C24XX_DMA_APB, true, 24 }, + [DMACH_TIMER] = { S3C24XX_DMA_APB, true, 9 }, + [DMACH_I2S_IN] = { S3C24XX_DMA_APB, true, 5 }, + [DMACH_I2S_OUT] = { S3C24XX_DMA_APB, true, 4 }, + [DMACH_USB_EP1] = { S3C24XX_DMA_APB, true, 13 }, + [DMACH_USB_EP2] = { S3C24XX_DMA_APB, true, 14 }, + [DMACH_USB_EP3] = { S3C24XX_DMA_APB, true, 15 }, + [DMACH_USB_EP4] = { S3C24XX_DMA_APB, true, 16 }, +}; + +static struct s3c24xx_dma_platdata s3c2412_dma_platdata = { + .num_phy_channels = 4, + .channels = s3c2412_dma_channels, + .num_channels = DMACH_MAX, +}; + +struct platform_device s3c2412_device_dma = { + .name = "s3c2412-dma", + .id = 0, + .num_resources = ARRAY_SIZE(s3c2410_dma_resource), + .resource = s3c2410_dma_resource, + .dev = { + .platform_data = &s3c2412_dma_platdata, + }, +}; +#endif + +#if defined(CONFIG_CPU_S3C2440) +static struct s3c24xx_dma_channel s3c2440_dma_channels[DMACH_MAX] = { + [DMACH_XD0] = { S3C24XX_DMA_AHB, true, S3C24XX_DMA_CHANREQ(0, 0), }, + [DMACH_XD1] = { S3C24XX_DMA_AHB, true, S3C24XX_DMA_CHANREQ(0, 1), }, + [DMACH_SDI] = { S3C24XX_DMA_APB, false, S3C24XX_DMA_CHANREQ(2, 0) | + S3C24XX_DMA_CHANREQ(6, 1) | + S3C24XX_DMA_CHANREQ(2, 2) | + S3C24XX_DMA_CHANREQ(1, 3), + }, + [DMACH_SPI0] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(3, 1), }, + [DMACH_SPI1] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(2, 3), }, + [DMACH_UART0] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(1, 0), }, + [DMACH_UART1] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(1, 1), }, + [DMACH_UART2] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(0, 3), }, + [DMACH_TIMER] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(3, 0) | + S3C24XX_DMA_CHANREQ(3, 2) | + S3C24XX_DMA_CHANREQ(3, 3), + }, + [DMACH_I2S_IN] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(2, 1) | + S3C24XX_DMA_CHANREQ(1, 2), + }, + [DMACH_I2S_OUT] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(5, 0) | + S3C24XX_DMA_CHANREQ(0, 2), + }, + [DMACH_PCM_IN] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(6, 0) | + S3C24XX_DMA_CHANREQ(5, 2), + }, + [DMACH_PCM_OUT] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(5, 1) | + S3C24XX_DMA_CHANREQ(6, 3), + }, + [DMACH_MIC_IN] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(6, 2) | + S3C24XX_DMA_CHANREQ(5, 3), + }, + [DMACH_USB_EP1] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(4, 0), }, + [DMACH_USB_EP2] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(4, 1), }, + [DMACH_USB_EP3] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(4, 2), }, + [DMACH_USB_EP4] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(4, 3), }, +}; + +static struct s3c24xx_dma_platdata s3c2440_dma_platdata = { + .num_phy_channels = 4, + .channels = s3c2440_dma_channels, + .num_channels = DMACH_MAX, +}; + +struct platform_device s3c2440_device_dma = { + .name = "s3c2410-dma", + .id = 0, + .num_resources = ARRAY_SIZE(s3c2410_dma_resource), + .resource = s3c2410_dma_resource, + .dev = { + .platform_data = &s3c2440_dma_platdata, + }, +}; +#endif + +#if defined(CONFIG_CPUS_3C2443) || defined(CONFIG_CPU_S3C2416) +static struct resource s3c2443_dma_resource[] = { + [0] = DEFINE_RES_MEM(S3C24XX_PA_DMA, S3C24XX_SZ_DMA), + [1] = DEFINE_RES_IRQ(IRQ_S3C2443_DMA0), + [2] = DEFINE_RES_IRQ(IRQ_S3C2443_DMA1), + [3] = DEFINE_RES_IRQ(IRQ_S3C2443_DMA2), + [4] = DEFINE_RES_IRQ(IRQ_S3C2443_DMA3), + [5] = DEFINE_RES_IRQ(IRQ_S3C2443_DMA4), + [6] = DEFINE_RES_IRQ(IRQ_S3C2443_DMA5), +}; + +static struct s3c24xx_dma_channel s3c2443_dma_channels[DMACH_MAX] = { + [DMACH_XD0] = { S3C24XX_DMA_AHB, true, 17 }, + [DMACH_XD1] = { S3C24XX_DMA_AHB, true, 18 }, + [DMACH_SDI] = { S3C24XX_DMA_APB, false, 10 }, + [DMACH_SPI0_RX] = { S3C24XX_DMA_APB, true, 1 }, + [DMACH_SPI0_TX] = { S3C24XX_DMA_APB, true, 0 }, + [DMACH_SPI1_RX] = { S3C24XX_DMA_APB, true, 3 }, + [DMACH_SPI1_TX] = { S3C24XX_DMA_APB, true, 2 }, + [DMACH_UART0] = { S3C24XX_DMA_APB, true, 19 }, + [DMACH_UART1] = { S3C24XX_DMA_APB, true, 21 }, + [DMACH_UART2] = { S3C24XX_DMA_APB, true, 23 }, + [DMACH_UART3] = { S3C24XX_DMA_APB, true, 25 }, + [DMACH_UART0_SRC2] = { S3C24XX_DMA_APB, true, 20 }, + [DMACH_UART1_SRC2] = { S3C24XX_DMA_APB, true, 22 }, + [DMACH_UART2_SRC2] = { S3C24XX_DMA_APB, true, 24 }, + [DMACH_UART3_SRC2] = { S3C24XX_DMA_APB, true, 26 }, + [DMACH_TIMER] = { S3C24XX_DMA_APB, true, 9 }, + [DMACH_I2S_IN] = { S3C24XX_DMA_APB, true, 5 }, + [DMACH_I2S_OUT] = { S3C24XX_DMA_APB, true, 4 }, + [DMACH_PCM_IN] = { S3C24XX_DMA_APB, true, 28 }, + [DMACH_PCM_OUT] = { S3C24XX_DMA_APB, true, 27 }, + [DMACH_MIC_IN] = { S3C24XX_DMA_APB, true, 29 }, +}; + +static struct s3c24xx_dma_platdata s3c2443_dma_platdata = { + .num_phy_channels = 6, + .channels = s3c2443_dma_channels, + .num_channels = DMACH_MAX, +}; + +struct platform_device s3c2443_device_dma = { + .name = "s3c2443-dma", + .id = 0, + .num_resources = ARRAY_SIZE(s3c2443_dma_resource), + .resource = s3c2443_dma_resource, + .dev = { + .platform_data = &s3c2443_dma_platdata, + }, +}; +#endif diff --git a/arch/arm/mach-s3c24xx/common.h b/arch/arm/mach-s3c24xx/common.h index 84b280654f4c..e46c10417216 100644 --- a/arch/arm/mach-s3c24xx/common.h +++ b/arch/arm/mach-s3c24xx/common.h @@ -109,4 +109,9 @@ extern void s3c2443_init_irq(void); extern struct syscore_ops s3c24xx_irq_syscore_ops; +extern struct platform_device s3c2410_device_dma; +extern struct platform_device s3c2412_device_dma; +extern struct platform_device s3c2440_device_dma; +extern struct platform_device s3c2443_device_dma; + #endif /* __ARCH_ARM_MACH_S3C24XX_COMMON_H */ diff --git a/arch/arm/mach-s3c24xx/mach-h1940.c b/arch/arm/mach-s3c24xx/mach-h1940.c index 74dd47988b41..952b6a040d1f 100644 --- a/arch/arm/mach-s3c24xx/mach-h1940.c +++ b/arch/arm/mach-s3c24xx/mach-h1940.c @@ -504,6 +504,7 @@ static struct platform_pwm_backlight_data backlight_data = { .dft_brightness = 50, /* tcnt = 0x31 */ .pwm_period_ns = 36296, + .enable_gpio = -1, .init = h1940_backlight_init, .notify = h1940_backlight_notify, .exit = h1940_backlight_exit, diff --git a/arch/arm/mach-s3c24xx/mach-jive.c b/arch/arm/mach-s3c24xx/mach-jive.c index a45fcd8ccf79..43c23e220f5b 100644 --- a/arch/arm/mach-s3c24xx/mach-jive.c +++ b/arch/arm/mach-s3c24xx/mach-jive.c @@ -466,6 +466,7 @@ static struct platform_device *jive_devices[] __initdata = { &jive_device_wm8750, &s3c_device_nand, &s3c_device_usbgadget, + &s3c2412_device_dma, }; static struct s3c2410_udc_mach_info jive_udc_cfg __initdata = { diff --git a/arch/arm/mach-s3c24xx/mach-mini2440.c b/arch/arm/mach-s3c24xx/mach-mini2440.c index a83db46320bc..4a18d49a63e0 100644 --- a/arch/arm/mach-s3c24xx/mach-mini2440.c +++ b/arch/arm/mach-s3c24xx/mach-mini2440.c @@ -24,7 +24,7 @@ #include <linux/io.h> #include <linux/serial_core.h> #include <linux/dm9000.h> -#include <linux/i2c/at24.h> +#include <linux/platform_data/at24.h> #include <linux/platform_device.h> #include <linux/gpio_keys.h> #include <linux/i2c.h> diff --git a/arch/arm/mach-s3c24xx/mach-rx1950.c b/arch/arm/mach-s3c24xx/mach-rx1950.c index 206b1f7546d1..034b7fe45c49 100644 --- a/arch/arm/mach-s3c24xx/mach-rx1950.c +++ b/arch/arm/mach-s3c24xx/mach-rx1950.c @@ -522,6 +522,7 @@ static struct platform_pwm_backlight_data rx1950_backlight_data = { .max_brightness = 24, .dft_brightness = 4, .pwm_period_ns = 48000, + .enable_gpio = -1, .init = rx1950_backlight_init, .notify = rx1950_backlight_notify, .exit = rx1950_backlight_exit, diff --git a/arch/arm/mach-s3c24xx/mach-smdk2413.c b/arch/arm/mach-s3c24xx/mach-smdk2413.c index 8146e920f10d..c9d31ef28dd1 100644 --- a/arch/arm/mach-s3c24xx/mach-smdk2413.c +++ b/arch/arm/mach-s3c24xx/mach-smdk2413.c @@ -89,6 +89,7 @@ static struct platform_device *smdk2413_devices[] __initdata = { &s3c_device_i2c0, &s3c_device_iis, &s3c_device_usbgadget, + &s3c2412_device_dma, }; static void __init smdk2413_fixup(struct tag *tags, char **cmdline, diff --git a/arch/arm/mach-s3c24xx/mach-smdk2416.c b/arch/arm/mach-s3c24xx/mach-smdk2416.c index cb46847c66b4..f88e672ad1e4 100644 --- a/arch/arm/mach-s3c24xx/mach-smdk2416.c +++ b/arch/arm/mach-s3c24xx/mach-smdk2416.c @@ -215,6 +215,7 @@ static struct platform_device *smdk2416_devices[] __initdata = { &s3c_device_hsmmc0, &s3c_device_hsmmc1, &s3c_device_usb_hsudc, + &s3c2443_device_dma, }; static void __init smdk2416_map_io(void) diff --git a/arch/arm/mach-s3c24xx/mach-smdk2443.c b/arch/arm/mach-s3c24xx/mach-smdk2443.c index 9435c3bef18a..d9933fcc6cc8 100644 --- a/arch/arm/mach-s3c24xx/mach-smdk2443.c +++ b/arch/arm/mach-s3c24xx/mach-smdk2443.c @@ -115,6 +115,7 @@ static struct platform_device *smdk2443_devices[] __initdata = { #ifdef CONFIG_SND_SOC_SMDK2443_WM9710 &s3c_device_ac97, #endif + &s3c2443_device_dma, }; static void __init smdk2443_map_io(void) diff --git a/arch/arm/mach-s3c24xx/mach-vstms.c b/arch/arm/mach-s3c24xx/mach-vstms.c index b66588428ec9..f7ec9c550787 100644 --- a/arch/arm/mach-s3c24xx/mach-vstms.c +++ b/arch/arm/mach-s3c24xx/mach-vstms.c @@ -126,6 +126,7 @@ static struct platform_device *vstms_devices[] __initdata = { &s3c_device_iis, &s3c_device_rtc, &s3c_device_nand, + &s3c2412_device_dma, }; static void __init vstms_fixup(struct tag *tags, char **cmdline, diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig index 041da5172423..2cb8dc55b50e 100644 --- a/arch/arm/mach-s3c64xx/Kconfig +++ b/arch/arm/mach-s3c64xx/Kconfig @@ -3,16 +3,7 @@ # # Licensed under GPLv2 -# temporary until we can eliminate all drivers using it. -config PLAT_S3C64XX - bool - depends on ARCH_S3C64XX - default y - select PM_GENERIC_DOMAINS - select SAMSUNG_WAKEMASK - help - Base platform code for any Samsung S3C64XX device - +if ARCH_S3C64XX # Configuration options for the S3C6410 CPU @@ -306,3 +297,21 @@ config MACH_WLF_CRAGG_6410 select SAMSUNG_GPIO_EXTRA128 help Machine support for the Wolfson Cragganmore S3C6410 variant. + +config MACH_S3C64XX_DT + bool "Samsung S3C6400/S3C6410 machine using Device Tree" + select CLKSRC_OF + select CPU_S3C6400 + select CPU_S3C6410 + select PINCTRL + select PINCTRL_S3C64XX + select USE_OF + help + Machine support for Samsung S3C6400/S3C6410 machines with Device Tree + enabled. + Select this if a fdt blob is available for your S3C64XX SoC based + board. + Note: This is under development and not all peripherals can be + supported with this machine file. + +endif diff --git a/arch/arm/mach-s3c64xx/Makefile b/arch/arm/mach-s3c64xx/Makefile index 31d0c9101272..6faedcffce04 100644 --- a/arch/arm/mach-s3c64xx/Makefile +++ b/arch/arm/mach-s3c64xx/Makefile @@ -12,7 +12,7 @@ obj- := # Core -obj-y += common.o clock.o +obj-y += common.o # Core support @@ -57,3 +57,4 @@ obj-$(CONFIG_MACH_SMARTQ7) += mach-smartq7.o obj-$(CONFIG_MACH_SMDK6400) += mach-smdk6400.o obj-$(CONFIG_MACH_SMDK6410) += mach-smdk6410.o obj-$(CONFIG_MACH_WLF_CRAGG_6410) += mach-crag6410.o mach-crag6410-module.o +obj-$(CONFIG_MACH_S3C64XX_DT) += mach-s3c64xx-dt.o diff --git a/arch/arm/mach-s3c64xx/clock.c b/arch/arm/mach-s3c64xx/clock.c deleted file mode 100644 index c1bcc4a6d3a8..000000000000 --- a/arch/arm/mach-s3c64xx/clock.c +++ /dev/null @@ -1,1007 +0,0 @@ -/* linux/arch/arm/plat-s3c64xx/clock.c - * - * Copyright 2008 Openmoko, Inc. - * Copyright 2008 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * http://armlinux.simtec.co.uk/ - * - * S3C64XX Base clock support - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include <linux/init.h> -#include <linux/module.h> -#include <linux/interrupt.h> -#include <linux/ioport.h> -#include <linux/clk.h> -#include <linux/err.h> -#include <linux/io.h> - -#include <mach/hardware.h> -#include <mach/map.h> - -#include <mach/regs-clock.h> - -#include <plat/cpu.h> -#include <plat/devs.h> -#include <plat/cpu-freq.h> -#include <plat/clock.h> -#include <plat/clock-clksrc.h> -#include <plat/pll.h> - -#include "regs-sys.h" - -/* fin_apll, fin_mpll and fin_epll are all the same clock, which we call - * ext_xtal_mux for want of an actual name from the manual. -*/ - -static struct clk clk_ext_xtal_mux = { - .name = "ext_xtal", -}; - -#define clk_fin_apll clk_ext_xtal_mux -#define clk_fin_mpll clk_ext_xtal_mux -#define clk_fin_epll clk_ext_xtal_mux - -#define clk_fout_mpll clk_mpll -#define clk_fout_epll clk_epll - -struct clk clk_h2 = { - .name = "hclk2", - .rate = 0, -}; - -struct clk clk_27m = { - .name = "clk_27m", - .rate = 27000000, -}; - -static int clk_48m_ctrl(struct clk *clk, int enable) -{ - unsigned long flags; - u32 val; - - /* can't rely on clock lock, this register has other usages */ - local_irq_save(flags); - - val = __raw_readl(S3C64XX_OTHERS); - if (enable) - val |= S3C64XX_OTHERS_USBMASK; - else - val &= ~S3C64XX_OTHERS_USBMASK; - - __raw_writel(val, S3C64XX_OTHERS); - local_irq_restore(flags); - - return 0; -} - -struct clk clk_48m = { - .name = "clk_48m", - .rate = 48000000, - .enable = clk_48m_ctrl, -}; - -struct clk clk_xusbxti = { - .name = "xusbxti", - .rate = 48000000, -}; - -static int inline s3c64xx_gate(void __iomem *reg, - struct clk *clk, - int enable) -{ - unsigned int ctrlbit = clk->ctrlbit; - u32 con; - - con = __raw_readl(reg); - - if (enable) - con |= ctrlbit; - else - con &= ~ctrlbit; - - __raw_writel(con, reg); - return 0; -} - -static int s3c64xx_pclk_ctrl(struct clk *clk, int enable) -{ - return s3c64xx_gate(S3C_PCLK_GATE, clk, enable); -} - -static int s3c64xx_hclk_ctrl(struct clk *clk, int enable) -{ - return s3c64xx_gate(S3C_HCLK_GATE, clk, enable); -} - -int s3c64xx_sclk_ctrl(struct clk *clk, int enable) -{ - return s3c64xx_gate(S3C_SCLK_GATE, clk, enable); -} - -static struct clk init_clocks_off[] = { - { - .name = "nand", - .parent = &clk_h, - }, { - .name = "rtc", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_RTC, - }, { - .name = "adc", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_TSADC, - }, { - .name = "i2c", - .devname = "s3c2440-i2c.0", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_IIC, - }, { - .name = "i2c", - .devname = "s3c2440-i2c.1", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C6410_CLKCON_PCLK_I2C1, - }, { - .name = "keypad", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_KEYPAD, - }, { - .name = "spi", - .devname = "s3c6410-spi.0", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_SPI0, - }, { - .name = "spi", - .devname = "s3c6410-spi.1", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_SPI1, - }, { - .name = "48m", - .devname = "s3c-sdhci.0", - .parent = &clk_48m, - .enable = s3c64xx_sclk_ctrl, - .ctrlbit = S3C_CLKCON_SCLK_MMC0_48, - }, { - .name = "48m", - .devname = "s3c-sdhci.1", - .parent = &clk_48m, - .enable = s3c64xx_sclk_ctrl, - .ctrlbit = S3C_CLKCON_SCLK_MMC1_48, - }, { - .name = "48m", - .devname = "s3c-sdhci.2", - .parent = &clk_48m, - .enable = s3c64xx_sclk_ctrl, - .ctrlbit = S3C_CLKCON_SCLK_MMC2_48, - }, { - .name = "ac97", - .parent = &clk_p, - .ctrlbit = S3C_CLKCON_PCLK_AC97, - }, { - .name = "cfcon", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_IHOST, - }, { - .name = "dma0", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_DMA0, - }, { - .name = "dma1", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_DMA1, - }, { - .name = "3dse", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_3DSE, - }, { - .name = "hclk_secur", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_SECUR, - }, { - .name = "sdma1", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_SDMA1, - }, { - .name = "sdma0", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_SDMA0, - }, { - .name = "hclk_jpeg", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_JPEG, - }, { - .name = "camif", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_CAMIF, - }, { - .name = "hclk_scaler", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_SCALER, - }, { - .name = "2d", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_2D, - }, { - .name = "tv", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_TV, - }, { - .name = "post0", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_POST0, - }, { - .name = "rot", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_ROT, - }, { - .name = "hclk_mfc", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_MFC, - }, { - .name = "pclk_mfc", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_MFC, - }, { - .name = "dac27", - .enable = s3c64xx_sclk_ctrl, - .ctrlbit = S3C_CLKCON_SCLK_DAC27, - }, { - .name = "tv27", - .enable = s3c64xx_sclk_ctrl, - .ctrlbit = S3C_CLKCON_SCLK_TV27, - }, { - .name = "scaler27", - .enable = s3c64xx_sclk_ctrl, - .ctrlbit = S3C_CLKCON_SCLK_SCALER27, - }, { - .name = "sclk_scaler", - .enable = s3c64xx_sclk_ctrl, - .ctrlbit = S3C_CLKCON_SCLK_SCALER, - }, { - .name = "post0_27", - .enable = s3c64xx_sclk_ctrl, - .ctrlbit = S3C_CLKCON_SCLK_POST0_27, - }, { - .name = "secur", - .enable = s3c64xx_sclk_ctrl, - .ctrlbit = S3C_CLKCON_SCLK_SECUR, - }, { - .name = "sclk_mfc", - .enable = s3c64xx_sclk_ctrl, - .ctrlbit = S3C_CLKCON_SCLK_MFC, - }, { - .name = "sclk_jpeg", - .enable = s3c64xx_sclk_ctrl, - .ctrlbit = S3C_CLKCON_SCLK_JPEG, - }, -}; - -static struct clk clk_48m_spi0 = { - .name = "spi_48m", - .devname = "s3c6410-spi.0", - .parent = &clk_48m, - .enable = s3c64xx_sclk_ctrl, - .ctrlbit = S3C_CLKCON_SCLK_SPI0_48, -}; - -static struct clk clk_48m_spi1 = { - .name = "spi_48m", - .devname = "s3c6410-spi.1", - .parent = &clk_48m, - .enable = s3c64xx_sclk_ctrl, - .ctrlbit = S3C_CLKCON_SCLK_SPI1_48, -}; - -static struct clk clk_i2s0 = { - .name = "iis", - .devname = "samsung-i2s.0", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_IIS0, -}; - -static struct clk clk_i2s1 = { - .name = "iis", - .devname = "samsung-i2s.1", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_IIS1, -}; - -#ifdef CONFIG_CPU_S3C6410 -static struct clk clk_i2s2 = { - .name = "iis", - .devname = "samsung-i2s.2", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C6410_CLKCON_PCLK_IIS2, -}; -#endif - -static struct clk init_clocks[] = { - { - .name = "lcd", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_LCD, - }, { - .name = "gpio", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_GPIO, - }, { - .name = "usb-host", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_UHOST, - }, { - .name = "otg", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_USB, - }, { - .name = "timers", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_PWM, - }, { - .name = "uart", - .devname = "s3c6400-uart.0", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_UART0, - }, { - .name = "uart", - .devname = "s3c6400-uart.1", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_UART1, - }, { - .name = "uart", - .devname = "s3c6400-uart.2", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_UART2, - }, { - .name = "uart", - .devname = "s3c6400-uart.3", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_UART3, - }, { - .name = "watchdog", - .parent = &clk_p, - .ctrlbit = S3C_CLKCON_PCLK_WDT, - }, -}; - -static struct clk clk_hsmmc0 = { - .name = "hsmmc", - .devname = "s3c-sdhci.0", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_HSMMC0, -}; - -static struct clk clk_hsmmc1 = { - .name = "hsmmc", - .devname = "s3c-sdhci.1", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_HSMMC1, -}; - -static struct clk clk_hsmmc2 = { - .name = "hsmmc", - .devname = "s3c-sdhci.2", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_HSMMC2, -}; - -static struct clk clk_fout_apll = { - .name = "fout_apll", -}; - -static struct clk *clk_src_apll_list[] = { - [0] = &clk_fin_apll, - [1] = &clk_fout_apll, -}; - -static struct clksrc_sources clk_src_apll = { - .sources = clk_src_apll_list, - .nr_sources = ARRAY_SIZE(clk_src_apll_list), -}; - -static struct clksrc_clk clk_mout_apll = { - .clk = { - .name = "mout_apll", - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 0, .size = 1 }, - .sources = &clk_src_apll, -}; - -static struct clk *clk_src_epll_list[] = { - [0] = &clk_fin_epll, - [1] = &clk_fout_epll, -}; - -static struct clksrc_sources clk_src_epll = { - .sources = clk_src_epll_list, - .nr_sources = ARRAY_SIZE(clk_src_epll_list), -}; - -static struct clksrc_clk clk_mout_epll = { - .clk = { - .name = "mout_epll", - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 2, .size = 1 }, - .sources = &clk_src_epll, -}; - -static struct clk *clk_src_mpll_list[] = { - [0] = &clk_fin_mpll, - [1] = &clk_fout_mpll, -}; - -static struct clksrc_sources clk_src_mpll = { - .sources = clk_src_mpll_list, - .nr_sources = ARRAY_SIZE(clk_src_mpll_list), -}; - -static struct clksrc_clk clk_mout_mpll = { - .clk = { - .name = "mout_mpll", - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 1, .size = 1 }, - .sources = &clk_src_mpll, -}; - -static unsigned int armclk_mask; - -static unsigned long s3c64xx_clk_arm_get_rate(struct clk *clk) -{ - unsigned long rate = clk_get_rate(clk->parent); - u32 clkdiv; - - /* divisor mask starts at bit0, so no need to shift */ - clkdiv = __raw_readl(S3C_CLK_DIV0) & armclk_mask; - - return rate / (clkdiv + 1); -} - -static unsigned long s3c64xx_clk_arm_round_rate(struct clk *clk, - unsigned long rate) -{ - unsigned long parent = clk_get_rate(clk->parent); - u32 div; - - if (parent < rate) - return parent; - - div = (parent / rate) - 1; - if (div > armclk_mask) - div = armclk_mask; - - return parent / (div + 1); -} - -static int s3c64xx_clk_arm_set_rate(struct clk *clk, unsigned long rate) -{ - unsigned long parent = clk_get_rate(clk->parent); - u32 div; - u32 val; - - if (rate < parent / (armclk_mask + 1)) - return -EINVAL; - - rate = clk_round_rate(clk, rate); - div = clk_get_rate(clk->parent) / rate; - - val = __raw_readl(S3C_CLK_DIV0); - val &= ~armclk_mask; - val |= (div - 1); - __raw_writel(val, S3C_CLK_DIV0); - - return 0; - -} - -static struct clk clk_arm = { - .name = "armclk", - .parent = &clk_mout_apll.clk, - .ops = &(struct clk_ops) { - .get_rate = s3c64xx_clk_arm_get_rate, - .set_rate = s3c64xx_clk_arm_set_rate, - .round_rate = s3c64xx_clk_arm_round_rate, - }, -}; - -static unsigned long s3c64xx_clk_doutmpll_get_rate(struct clk *clk) -{ - unsigned long rate = clk_get_rate(clk->parent); - - printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate); - - if (__raw_readl(S3C_CLK_DIV0) & S3C6400_CLKDIV0_MPLL_MASK) - rate /= 2; - - return rate; -} - -static struct clk_ops clk_dout_ops = { - .get_rate = s3c64xx_clk_doutmpll_get_rate, -}; - -static struct clk clk_dout_mpll = { - .name = "dout_mpll", - .parent = &clk_mout_mpll.clk, - .ops = &clk_dout_ops, -}; - -static struct clk *clkset_spi_mmc_list[] = { - &clk_mout_epll.clk, - &clk_dout_mpll, - &clk_fin_epll, - &clk_27m, -}; - -static struct clksrc_sources clkset_spi_mmc = { - .sources = clkset_spi_mmc_list, - .nr_sources = ARRAY_SIZE(clkset_spi_mmc_list), -}; - -static struct clk *clkset_irda_list[] = { - &clk_mout_epll.clk, - &clk_dout_mpll, - NULL, - &clk_27m, -}; - -static struct clksrc_sources clkset_irda = { - .sources = clkset_irda_list, - .nr_sources = ARRAY_SIZE(clkset_irda_list), -}; - -static struct clk *clkset_uart_list[] = { - &clk_mout_epll.clk, - &clk_dout_mpll, - NULL, - NULL -}; - -static struct clksrc_sources clkset_uart = { - .sources = clkset_uart_list, - .nr_sources = ARRAY_SIZE(clkset_uart_list), -}; - -static struct clk *clkset_uhost_list[] = { - &clk_48m, - &clk_mout_epll.clk, - &clk_dout_mpll, - &clk_fin_epll, -}; - -static struct clksrc_sources clkset_uhost = { - .sources = clkset_uhost_list, - .nr_sources = ARRAY_SIZE(clkset_uhost_list), -}; - -/* The peripheral clocks are all controlled via clocksource followed - * by an optional divider and gate stage. We currently roll this into - * one clock which hides the intermediate clock from the mux. - * - * Note, the JPEG clock can only be an even divider... - * - * The scaler and LCD clocks depend on the S3C64XX version, and also - * have a common parent divisor so are not included here. - */ - -/* clocks that feed other parts of the clock source tree */ - -static struct clk clk_iis_cd0 = { - .name = "iis_cdclk0", -}; - -static struct clk clk_iis_cd1 = { - .name = "iis_cdclk1", -}; - -static struct clk clk_iisv4_cd = { - .name = "iis_cdclk_v4", -}; - -static struct clk clk_pcm_cd = { - .name = "pcm_cdclk", -}; - -static struct clk *clkset_audio0_list[] = { - [0] = &clk_mout_epll.clk, - [1] = &clk_dout_mpll, - [2] = &clk_fin_epll, - [3] = &clk_iis_cd0, - [4] = &clk_pcm_cd, -}; - -static struct clksrc_sources clkset_audio0 = { - .sources = clkset_audio0_list, - .nr_sources = ARRAY_SIZE(clkset_audio0_list), -}; - -static struct clk *clkset_audio1_list[] = { - [0] = &clk_mout_epll.clk, - [1] = &clk_dout_mpll, - [2] = &clk_fin_epll, - [3] = &clk_iis_cd1, - [4] = &clk_pcm_cd, -}; - -static struct clksrc_sources clkset_audio1 = { - .sources = clkset_audio1_list, - .nr_sources = ARRAY_SIZE(clkset_audio1_list), -}; - -#ifdef CONFIG_CPU_S3C6410 -static struct clk *clkset_audio2_list[] = { - [0] = &clk_mout_epll.clk, - [1] = &clk_dout_mpll, - [2] = &clk_fin_epll, - [3] = &clk_iisv4_cd, - [4] = &clk_pcm_cd, -}; - -static struct clksrc_sources clkset_audio2 = { - .sources = clkset_audio2_list, - .nr_sources = ARRAY_SIZE(clkset_audio2_list), -}; -#endif - -static struct clksrc_clk clksrcs[] = { - { - .clk = { - .name = "usb-bus-host", - .ctrlbit = S3C_CLKCON_SCLK_UHOST, - .enable = s3c64xx_sclk_ctrl, - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 5, .size = 2 }, - .reg_div = { .reg = S3C_CLK_DIV1, .shift = 20, .size = 4 }, - .sources = &clkset_uhost, - }, { - .clk = { - .name = "irda-bus", - .ctrlbit = S3C_CLKCON_SCLK_IRDA, - .enable = s3c64xx_sclk_ctrl, - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 24, .size = 2 }, - .reg_div = { .reg = S3C_CLK_DIV2, .shift = 20, .size = 4 }, - .sources = &clkset_irda, - }, { - .clk = { - .name = "camera", - .ctrlbit = S3C_CLKCON_SCLK_CAM, - .enable = s3c64xx_sclk_ctrl, - .parent = &clk_h2, - }, - .reg_div = { .reg = S3C_CLK_DIV0, .shift = 20, .size = 4 }, - }, -}; - -/* Where does UCLK0 come from? */ -static struct clksrc_clk clk_sclk_uclk = { - .clk = { - .name = "uclk1", - .ctrlbit = S3C_CLKCON_SCLK_UART, - .enable = s3c64xx_sclk_ctrl, - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 13, .size = 1 }, - .reg_div = { .reg = S3C_CLK_DIV2, .shift = 16, .size = 4 }, - .sources = &clkset_uart, -}; - -static struct clksrc_clk clk_sclk_mmc0 = { - .clk = { - .name = "mmc_bus", - .devname = "s3c-sdhci.0", - .ctrlbit = S3C_CLKCON_SCLK_MMC0, - .enable = s3c64xx_sclk_ctrl, - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 18, .size = 2 }, - .reg_div = { .reg = S3C_CLK_DIV1, .shift = 0, .size = 4 }, - .sources = &clkset_spi_mmc, -}; - -static struct clksrc_clk clk_sclk_mmc1 = { - .clk = { - .name = "mmc_bus", - .devname = "s3c-sdhci.1", - .ctrlbit = S3C_CLKCON_SCLK_MMC1, - .enable = s3c64xx_sclk_ctrl, - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 20, .size = 2 }, - .reg_div = { .reg = S3C_CLK_DIV1, .shift = 4, .size = 4 }, - .sources = &clkset_spi_mmc, -}; - -static struct clksrc_clk clk_sclk_mmc2 = { - .clk = { - .name = "mmc_bus", - .devname = "s3c-sdhci.2", - .ctrlbit = S3C_CLKCON_SCLK_MMC2, - .enable = s3c64xx_sclk_ctrl, - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 22, .size = 2 }, - .reg_div = { .reg = S3C_CLK_DIV1, .shift = 8, .size = 4 }, - .sources = &clkset_spi_mmc, -}; - -static struct clksrc_clk clk_sclk_spi0 = { - .clk = { - .name = "spi-bus", - .devname = "s3c6410-spi.0", - .ctrlbit = S3C_CLKCON_SCLK_SPI0, - .enable = s3c64xx_sclk_ctrl, - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 14, .size = 2 }, - .reg_div = { .reg = S3C_CLK_DIV2, .shift = 0, .size = 4 }, - .sources = &clkset_spi_mmc, -}; - -static struct clksrc_clk clk_sclk_spi1 = { - .clk = { - .name = "spi-bus", - .devname = "s3c6410-spi.1", - .ctrlbit = S3C_CLKCON_SCLK_SPI1, - .enable = s3c64xx_sclk_ctrl, - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 16, .size = 2 }, - .reg_div = { .reg = S3C_CLK_DIV2, .shift = 4, .size = 4 }, - .sources = &clkset_spi_mmc, -}; - -static struct clksrc_clk clk_audio_bus0 = { - .clk = { - .name = "audio-bus", - .devname = "samsung-i2s.0", - .ctrlbit = S3C_CLKCON_SCLK_AUDIO0, - .enable = s3c64xx_sclk_ctrl, - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 7, .size = 3 }, - .reg_div = { .reg = S3C_CLK_DIV2, .shift = 8, .size = 4 }, - .sources = &clkset_audio0, -}; - -static struct clksrc_clk clk_audio_bus1 = { - .clk = { - .name = "audio-bus", - .devname = "samsung-i2s.1", - .ctrlbit = S3C_CLKCON_SCLK_AUDIO1, - .enable = s3c64xx_sclk_ctrl, - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 10, .size = 3 }, - .reg_div = { .reg = S3C_CLK_DIV2, .shift = 12, .size = 4 }, - .sources = &clkset_audio1, -}; - -#ifdef CONFIG_CPU_S3C6410 -static struct clksrc_clk clk_audio_bus2 = { - .clk = { - .name = "audio-bus", - .devname = "samsung-i2s.2", - .ctrlbit = S3C6410_CLKCON_SCLK_AUDIO2, - .enable = s3c64xx_sclk_ctrl, - }, - .reg_src = { .reg = S3C6410_CLK_SRC2, .shift = 0, .size = 3 }, - .reg_div = { .reg = S3C_CLK_DIV2, .shift = 24, .size = 4 }, - .sources = &clkset_audio2, -}; -#endif -/* Clock initialisation code */ - -static struct clksrc_clk *init_parents[] = { - &clk_mout_apll, - &clk_mout_epll, - &clk_mout_mpll, -}; - -static struct clksrc_clk *clksrc_cdev[] = { - &clk_sclk_uclk, - &clk_sclk_mmc0, - &clk_sclk_mmc1, - &clk_sclk_mmc2, - &clk_sclk_spi0, - &clk_sclk_spi1, - &clk_audio_bus0, - &clk_audio_bus1, -}; - -static struct clk *clk_cdev[] = { - &clk_hsmmc0, - &clk_hsmmc1, - &clk_hsmmc2, - &clk_48m_spi0, - &clk_48m_spi1, - &clk_i2s0, - &clk_i2s1, -}; - -static struct clk_lookup s3c64xx_clk_lookup[] = { - CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p), - CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uclk.clk), - CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.0", &clk_hsmmc0), - CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.0", &clk_hsmmc1), - CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.0", &clk_hsmmc2), - CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &clk_sclk_mmc0.clk), - CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_sclk_mmc1.clk), - CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk), - CLKDEV_INIT(NULL, "spi_busclk0", &clk_p), - CLKDEV_INIT("s3c6410-spi.0", "spi_busclk1", &clk_sclk_spi0.clk), - CLKDEV_INIT("s3c6410-spi.0", "spi_busclk2", &clk_48m_spi0), - CLKDEV_INIT("s3c6410-spi.1", "spi_busclk1", &clk_sclk_spi1.clk), - CLKDEV_INIT("s3c6410-spi.1", "spi_busclk2", &clk_48m_spi1), - CLKDEV_INIT("samsung-i2s.0", "i2s_opclk0", &clk_i2s0), - CLKDEV_INIT("samsung-i2s.0", "i2s_opclk1", &clk_audio_bus0.clk), - CLKDEV_INIT("samsung-i2s.1", "i2s_opclk0", &clk_i2s1), - CLKDEV_INIT("samsung-i2s.1", "i2s_opclk1", &clk_audio_bus1.clk), -#ifdef CONFIG_CPU_S3C6410 - CLKDEV_INIT("samsung-i2s.2", "i2s_opclk0", &clk_i2s2), - CLKDEV_INIT("samsung-i2s.2", "i2s_opclk1", &clk_audio_bus2.clk), -#endif -}; - -#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1) - -void __init_or_cpufreq s3c64xx_setup_clocks(void) -{ - struct clk *xtal_clk; - unsigned long xtal; - unsigned long fclk; - unsigned long hclk; - unsigned long hclk2; - unsigned long pclk; - unsigned long epll; - unsigned long apll; - unsigned long mpll; - unsigned int ptr; - u32 clkdiv0; - - printk(KERN_DEBUG "%s: registering clocks\n", __func__); - - clkdiv0 = __raw_readl(S3C_CLK_DIV0); - printk(KERN_DEBUG "%s: clkdiv0 = %08x\n", __func__, clkdiv0); - - xtal_clk = clk_get(NULL, "xtal"); - BUG_ON(IS_ERR(xtal_clk)); - - xtal = clk_get_rate(xtal_clk); - clk_put(xtal_clk); - - printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal); - - /* For now assume the mux always selects the crystal */ - clk_ext_xtal_mux.parent = xtal_clk; - - epll = s3c_get_pll6553x(xtal, __raw_readl(S3C_EPLL_CON0), - __raw_readl(S3C_EPLL_CON1)); - mpll = s3c6400_get_pll(xtal, __raw_readl(S3C_MPLL_CON)); - apll = s3c6400_get_pll(xtal, __raw_readl(S3C_APLL_CON)); - - fclk = mpll; - - printk(KERN_INFO "S3C64XX: PLL settings, A=%ld, M=%ld, E=%ld\n", - apll, mpll, epll); - - if(__raw_readl(S3C64XX_OTHERS) & S3C64XX_OTHERS_SYNCMUXSEL) - /* Synchronous mode */ - hclk2 = apll / GET_DIV(clkdiv0, S3C6400_CLKDIV0_HCLK2); - else - /* Asynchronous mode */ - hclk2 = mpll / GET_DIV(clkdiv0, S3C6400_CLKDIV0_HCLK2); - - hclk = hclk2 / GET_DIV(clkdiv0, S3C6400_CLKDIV0_HCLK); - pclk = hclk2 / GET_DIV(clkdiv0, S3C6400_CLKDIV0_PCLK); - - printk(KERN_INFO "S3C64XX: HCLK2=%ld, HCLK=%ld, PCLK=%ld\n", - hclk2, hclk, pclk); - - clk_fout_mpll.rate = mpll; - clk_fout_epll.rate = epll; - clk_fout_apll.rate = apll; - - clk_h2.rate = hclk2; - clk_h.rate = hclk; - clk_p.rate = pclk; - clk_f.rate = fclk; - - for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++) - s3c_set_clksrc(init_parents[ptr], true); - - for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) - s3c_set_clksrc(&clksrcs[ptr], true); -} - -static struct clk *clks1[] __initdata = { - &clk_ext_xtal_mux, - &clk_iis_cd0, - &clk_iis_cd1, - &clk_iisv4_cd, - &clk_pcm_cd, - &clk_mout_epll.clk, - &clk_mout_mpll.clk, - &clk_dout_mpll, - &clk_arm, -}; - -static struct clk *clks[] __initdata = { - &clk_ext, - &clk_epll, - &clk_27m, - &clk_48m, - &clk_h2, - &clk_xusbxti, -}; - -/** - * s3c64xx_register_clocks - register clocks for s3c6400 and s3c6410 - * @xtal: The rate for the clock crystal feeding the PLLs. - * @armclk_divlimit: Divisor mask for ARMCLK. - * - * Register the clocks for the S3C6400 and S3C6410 SoC range, such - * as ARMCLK as well as the necessary parent clocks. - * - * This call does not setup the clocks, which is left to the - * s3c64xx_setup_clocks() call which may be needed by the cpufreq - * or resume code to re-set the clocks if the bootloader has changed - * them. - */ -void __init s3c64xx_register_clocks(unsigned long xtal, - unsigned armclk_divlimit) -{ - unsigned int cnt; - - armclk_mask = armclk_divlimit; - - s3c24xx_register_baseclocks(xtal); - s3c24xx_register_clocks(clks, ARRAY_SIZE(clks)); - - s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); - - s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); - s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); - - s3c24xx_register_clocks(clk_cdev, ARRAY_SIZE(clk_cdev)); - for (cnt = 0; cnt < ARRAY_SIZE(clk_cdev); cnt++) - s3c_disable_clocks(clk_cdev[cnt], 1); - - s3c24xx_register_clocks(clks1, ARRAY_SIZE(clks1)); - s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); - for (cnt = 0; cnt < ARRAY_SIZE(clksrc_cdev); cnt++) - s3c_register_clksrc(clksrc_cdev[cnt], 1); - clkdev_add_table(s3c64xx_clk_lookup, ARRAY_SIZE(s3c64xx_clk_lookup)); -} diff --git a/arch/arm/mach-s3c64xx/common.c b/arch/arm/mach-s3c64xx/common.c index 73d79cf5e141..7a3ce4c39e5f 100644 --- a/arch/arm/mach-s3c64xx/common.c +++ b/arch/arm/mach-s3c64xx/common.c @@ -14,9 +14,14 @@ * published by the Free Software Foundation. */ +/* + * NOTE: Code in this file is not used when booting with Device Tree support. + */ + #include <linux/kernel.h> #include <linux/init.h> #include <linux/module.h> +#include <linux/clk-provider.h> #include <linux/interrupt.h> #include <linux/ioport.h> #include <linux/serial_core.h> @@ -38,7 +43,6 @@ #include <mach/regs-gpio.h> #include <plat/cpu.h> -#include <plat/clock.h> #include <plat/devs.h> #include <plat/pm.h> #include <plat/gpio-cfg.h> @@ -50,6 +54,19 @@ #include "common.h" +/* External clock frequency */ +static unsigned long xtal_f = 12000000, xusbxti_f = 48000000; + +void __init s3c64xx_set_xtal_freq(unsigned long freq) +{ + xtal_f = freq; +} + +void __init s3c64xx_set_xusbxti_freq(unsigned long freq) +{ + xusbxti_f = freq; +} + /* uart registration process */ static void __init s3c64xx_init_uarts(struct s3c2410_uartcfg *cfg, int no) @@ -67,7 +84,6 @@ static struct cpu_table cpu_ids[] __initdata = { .idcode = S3C6400_CPU_ID, .idmask = S3C64XX_CPU_MASK, .map_io = s3c6400_map_io, - .init_clocks = s3c6400_init_clocks, .init_uarts = s3c64xx_init_uarts, .init = s3c6400_init, .name = name_s3c6400, @@ -75,7 +91,6 @@ static struct cpu_table cpu_ids[] __initdata = { .idcode = S3C6410_CPU_ID, .idmask = S3C64XX_CPU_MASK, .map_io = s3c6410_map_io, - .init_clocks = s3c6410_init_clocks, .init_uarts = s3c64xx_init_uarts, .init = s3c6410_init, .name = name_s3c6410, @@ -192,6 +207,10 @@ void __init s3c64xx_init_io(struct map_desc *mach_desc, int size) static __init int s3c64xx_dev_init(void) { + /* Not applicable when using DT. */ + if (of_have_populated_dt()) + return 0; + subsys_system_register(&s3c64xx_subsys, NULL); return device_register(&s3c64xx_dev); } @@ -213,8 +232,10 @@ void __init s3c64xx_init_irq(u32 vic0_valid, u32 vic1_valid) { /* * FIXME: there is no better place to put this at the moment - * (samsung_wdt_reset_init needs clocks) + * (s3c64xx_clk_init needs ioremap and must happen before init_time + * samsung_wdt_reset_init needs clocks) */ + s3c64xx_clk_init(NULL, xtal_f, xusbxti_f, soc_is_s3c6400(), S3C_VA_SYS); samsung_wdt_reset_init(S3C_VA_WATCHDOG); printk(KERN_DEBUG "%s: initialising interrupts\n", __func__); @@ -391,6 +412,10 @@ static int __init s3c64xx_init_irq_eint(void) { int irq; + /* On DT-enabled systems EINTs are handled by pinctrl-s3c64xx driver. */ + if (of_have_populated_dt()) + return -ENODEV; + for (irq = IRQ_EINT(0); irq <= IRQ_EINT(27); irq++) { irq_set_chip_and_handler(irq, &s3c_irq_eint, handle_level_irq); irq_set_chip_data(irq, (void *)eint_irq_to_bit(irq)); diff --git a/arch/arm/mach-s3c64xx/common.h b/arch/arm/mach-s3c64xx/common.h index e8f990b37665..bd3bd562011e 100644 --- a/arch/arm/mach-s3c64xx/common.h +++ b/arch/arm/mach-s3c64xx/common.h @@ -22,21 +22,21 @@ void s3c64xx_init_irq(u32 vic0, u32 vic1); void s3c64xx_init_io(struct map_desc *mach_desc, int size); -void s3c64xx_register_clocks(unsigned long xtal, unsigned armclk_limit); -void s3c64xx_setup_clocks(void); - void s3c64xx_restart(enum reboot_mode mode, const char *cmd); void s3c64xx_init_late(void); +void s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f, + unsigned long xusbxti_f, bool is_s3c6400, void __iomem *reg_base); +void s3c64xx_set_xtal_freq(unsigned long freq); +void s3c64xx_set_xusbxti_freq(unsigned long freq); + #ifdef CONFIG_CPU_S3C6400 extern int s3c6400_init(void); extern void s3c6400_init_irq(void); extern void s3c6400_map_io(void); -extern void s3c6400_init_clocks(int xtal); #else -#define s3c6400_init_clocks NULL #define s3c6400_map_io NULL #define s3c6400_init NULL #endif @@ -46,10 +46,8 @@ extern void s3c6400_init_clocks(int xtal); extern int s3c6410_init(void); extern void s3c6410_init_irq(void); extern void s3c6410_map_io(void); -extern void s3c6410_init_clocks(int xtal); #else -#define s3c6410_init_clocks NULL #define s3c6410_map_io NULL #define s3c6410_init NULL #endif diff --git a/arch/arm/mach-s3c64xx/dma.c b/arch/arm/mach-s3c64xx/dma.c index 759846c28d12..7e22c2113816 100644 --- a/arch/arm/mach-s3c64xx/dma.c +++ b/arch/arm/mach-s3c64xx/dma.c @@ -12,6 +12,10 @@ * published by the Free Software Foundation. */ +/* + * NOTE: Code in this file is not used when booting with Device Tree support. + */ + #include <linux/kernel.h> #include <linux/module.h> #include <linux/interrupt.h> @@ -24,6 +28,7 @@ #include <linux/err.h> #include <linux/io.h> #include <linux/amba/pl080.h> +#include <linux/of.h> #include <mach/dma.h> #include <mach/map.h> @@ -677,7 +682,7 @@ static int s3c64xx_dma_init1(int chno, enum dma_ch chbase, goto err_map; } - clk_enable(dmac->clk); + clk_prepare_enable(dmac->clk); dmac->regs = regs; dmac->chanbase = chbase; @@ -711,7 +716,7 @@ static int s3c64xx_dma_init1(int chno, enum dma_ch chbase, return 0; err_clk: - clk_disable(dmac->clk); + clk_disable_unprepare(dmac->clk); clk_put(dmac->clk); err_map: iounmap(regs); @@ -726,6 +731,10 @@ static int __init s3c64xx_dma_init(void) { int ret; + /* This driver is not supported when booting with device tree. */ + if (of_have_populated_dt()) + return -ENODEV; + printk(KERN_INFO "%s: Registering DMA channels\n", __func__); dma_pool = dma_pool_create("DMA-LLI", NULL, sizeof(struct pl080s_lli), 16, 0); diff --git a/arch/arm/mach-s3c64xx/include/mach/regs-clock.h b/arch/arm/mach-s3c64xx/include/mach/regs-clock.h index 05332b998ec0..4f44aac77092 100644 --- a/arch/arm/mach-s3c64xx/include/mach/regs-clock.h +++ b/arch/arm/mach-s3c64xx/include/mach/regs-clock.h @@ -15,145 +15,21 @@ #ifndef __PLAT_REGS_CLOCK_H #define __PLAT_REGS_CLOCK_H __FILE__ +/* + * FIXME: Remove remaining definitions + */ + #define S3C_CLKREG(x) (S3C_VA_SYS + (x)) -#define S3C_APLL_LOCK S3C_CLKREG(0x00) -#define S3C_MPLL_LOCK S3C_CLKREG(0x04) -#define S3C_EPLL_LOCK S3C_CLKREG(0x08) -#define S3C_APLL_CON S3C_CLKREG(0x0C) -#define S3C_MPLL_CON S3C_CLKREG(0x10) -#define S3C_EPLL_CON0 S3C_CLKREG(0x14) -#define S3C_EPLL_CON1 S3C_CLKREG(0x18) -#define S3C_CLK_SRC S3C_CLKREG(0x1C) -#define S3C_CLK_DIV0 S3C_CLKREG(0x20) -#define S3C_CLK_DIV1 S3C_CLKREG(0x24) -#define S3C_CLK_DIV2 S3C_CLKREG(0x28) -#define S3C_CLK_OUT S3C_CLKREG(0x2C) -#define S3C_HCLK_GATE S3C_CLKREG(0x30) #define S3C_PCLK_GATE S3C_CLKREG(0x34) -#define S3C_SCLK_GATE S3C_CLKREG(0x38) -#define S3C_MEM0_GATE S3C_CLKREG(0x3C) #define S3C6410_CLK_SRC2 S3C_CLKREG(0x10C) #define S3C_MEM_SYS_CFG S3C_CLKREG(0x120) -/* CLKDIV0 */ -#define S3C6400_CLKDIV0_PCLK_MASK (0xf << 12) -#define S3C6400_CLKDIV0_PCLK_SHIFT (12) -#define S3C6400_CLKDIV0_HCLK2_MASK (0x7 << 9) -#define S3C6400_CLKDIV0_HCLK2_SHIFT (9) -#define S3C6400_CLKDIV0_HCLK_MASK (0x1 << 8) -#define S3C6400_CLKDIV0_HCLK_SHIFT (8) -#define S3C6400_CLKDIV0_MPLL_MASK (0x1 << 4) -#define S3C6400_CLKDIV0_MPLL_SHIFT (4) - -#define S3C6400_CLKDIV0_ARM_MASK (0x7 << 0) -#define S3C6410_CLKDIV0_ARM_MASK (0xf << 0) -#define S3C6400_CLKDIV0_ARM_SHIFT (0) - -/* HCLK GATE Registers */ -#define S3C_CLKCON_HCLK_3DSE (1<<31) -#define S3C_CLKCON_HCLK_UHOST (1<<29) -#define S3C_CLKCON_HCLK_SECUR (1<<28) -#define S3C_CLKCON_HCLK_SDMA1 (1<<27) -#define S3C_CLKCON_HCLK_SDMA0 (1<<26) -#define S3C_CLKCON_HCLK_IROM (1<<25) -#define S3C_CLKCON_HCLK_DDR1 (1<<24) -#define S3C_CLKCON_HCLK_DDR0 (1<<23) -#define S3C_CLKCON_HCLK_MEM1 (1<<22) -#define S3C_CLKCON_HCLK_MEM0 (1<<21) -#define S3C_CLKCON_HCLK_USB (1<<20) -#define S3C_CLKCON_HCLK_HSMMC2 (1<<19) -#define S3C_CLKCON_HCLK_HSMMC1 (1<<18) -#define S3C_CLKCON_HCLK_HSMMC0 (1<<17) -#define S3C_CLKCON_HCLK_MDP (1<<16) -#define S3C_CLKCON_HCLK_DHOST (1<<15) -#define S3C_CLKCON_HCLK_IHOST (1<<14) -#define S3C_CLKCON_HCLK_DMA1 (1<<13) -#define S3C_CLKCON_HCLK_DMA0 (1<<12) -#define S3C_CLKCON_HCLK_JPEG (1<<11) -#define S3C_CLKCON_HCLK_CAMIF (1<<10) -#define S3C_CLKCON_HCLK_SCALER (1<<9) -#define S3C_CLKCON_HCLK_2D (1<<8) -#define S3C_CLKCON_HCLK_TV (1<<7) -#define S3C_CLKCON_HCLK_POST0 (1<<5) -#define S3C_CLKCON_HCLK_ROT (1<<4) -#define S3C_CLKCON_HCLK_LCD (1<<3) -#define S3C_CLKCON_HCLK_TZIC (1<<2) -#define S3C_CLKCON_HCLK_INTC (1<<1) -#define S3C_CLKCON_HCLK_MFC (1<<0) - /* PCLK GATE Registers */ -#define S3C6410_CLKCON_PCLK_I2C1 (1<<27) -#define S3C6410_CLKCON_PCLK_IIS2 (1<<26) -#define S3C_CLKCON_PCLK_SKEY (1<<24) -#define S3C_CLKCON_PCLK_CHIPID (1<<23) -#define S3C_CLKCON_PCLK_SPI1 (1<<22) -#define S3C_CLKCON_PCLK_SPI0 (1<<21) -#define S3C_CLKCON_PCLK_HSIRX (1<<20) -#define S3C_CLKCON_PCLK_HSITX (1<<19) -#define S3C_CLKCON_PCLK_GPIO (1<<18) -#define S3C_CLKCON_PCLK_IIC (1<<17) -#define S3C_CLKCON_PCLK_IIS1 (1<<16) -#define S3C_CLKCON_PCLK_IIS0 (1<<15) -#define S3C_CLKCON_PCLK_AC97 (1<<14) -#define S3C_CLKCON_PCLK_TZPC (1<<13) -#define S3C_CLKCON_PCLK_TSADC (1<<12) -#define S3C_CLKCON_PCLK_KEYPAD (1<<11) -#define S3C_CLKCON_PCLK_IRDA (1<<10) -#define S3C_CLKCON_PCLK_PCM1 (1<<9) -#define S3C_CLKCON_PCLK_PCM0 (1<<8) -#define S3C_CLKCON_PCLK_PWM (1<<7) -#define S3C_CLKCON_PCLK_RTC (1<<6) -#define S3C_CLKCON_PCLK_WDT (1<<5) #define S3C_CLKCON_PCLK_UART3 (1<<4) #define S3C_CLKCON_PCLK_UART2 (1<<3) #define S3C_CLKCON_PCLK_UART1 (1<<2) #define S3C_CLKCON_PCLK_UART0 (1<<1) -#define S3C_CLKCON_PCLK_MFC (1<<0) - -/* SCLK GATE Registers */ -#define S3C_CLKCON_SCLK_UHOST (1<<30) -#define S3C_CLKCON_SCLK_MMC2_48 (1<<29) -#define S3C_CLKCON_SCLK_MMC1_48 (1<<28) -#define S3C_CLKCON_SCLK_MMC0_48 (1<<27) -#define S3C_CLKCON_SCLK_MMC2 (1<<26) -#define S3C_CLKCON_SCLK_MMC1 (1<<25) -#define S3C_CLKCON_SCLK_MMC0 (1<<24) -#define S3C_CLKCON_SCLK_SPI1_48 (1<<23) -#define S3C_CLKCON_SCLK_SPI0_48 (1<<22) -#define S3C_CLKCON_SCLK_SPI1 (1<<21) -#define S3C_CLKCON_SCLK_SPI0 (1<<20) -#define S3C_CLKCON_SCLK_DAC27 (1<<19) -#define S3C_CLKCON_SCLK_TV27 (1<<18) -#define S3C_CLKCON_SCLK_SCALER27 (1<<17) -#define S3C_CLKCON_SCLK_SCALER (1<<16) -#define S3C_CLKCON_SCLK_LCD27 (1<<15) -#define S3C_CLKCON_SCLK_LCD (1<<14) -#define S3C6400_CLKCON_SCLK_POST1_27 (1<<13) -#define S3C6410_CLKCON_FIMC (1<<13) -#define S3C_CLKCON_SCLK_POST0_27 (1<<12) -#define S3C6400_CLKCON_SCLK_POST1 (1<<11) -#define S3C6410_CLKCON_SCLK_AUDIO2 (1<<11) -#define S3C_CLKCON_SCLK_POST0 (1<<10) -#define S3C_CLKCON_SCLK_AUDIO1 (1<<9) -#define S3C_CLKCON_SCLK_AUDIO0 (1<<8) -#define S3C_CLKCON_SCLK_SECUR (1<<7) -#define S3C_CLKCON_SCLK_IRDA (1<<6) -#define S3C_CLKCON_SCLK_UART (1<<5) -#define S3C_CLKCON_SCLK_ONENAND (1<<4) -#define S3C_CLKCON_SCLK_MFC (1<<3) -#define S3C_CLKCON_SCLK_CAM (1<<2) -#define S3C_CLKCON_SCLK_JPEG (1<<1) - -/* CLKSRC */ - -#define S3C6400_CLKSRC_APLL_MOUT (1 << 0) -#define S3C6400_CLKSRC_MPLL_MOUT (1 << 1) -#define S3C6400_CLKSRC_EPLL_MOUT (1 << 2) -#define S3C6400_CLKSRC_APLL_MOUT_SHIFT (0) -#define S3C6400_CLKSRC_MPLL_MOUT_SHIFT (1) -#define S3C6400_CLKSRC_EPLL_MOUT_SHIFT (2) -#define S3C6400_CLKSRC_MFC (1 << 4) /* MEM_SYS_CFG */ #define MEM_SYS_CFG_INDEP_CF 0x4000 diff --git a/arch/arm/mach-s3c64xx/irq-pm.c b/arch/arm/mach-s3c64xx/irq-pm.c index c3da1b68d03e..1649c0d1c1b8 100644 --- a/arch/arm/mach-s3c64xx/irq-pm.c +++ b/arch/arm/mach-s3c64xx/irq-pm.c @@ -12,12 +12,17 @@ * published by the Free Software Foundation. */ +/* + * NOTE: Code in this file is not used when booting with Device Tree support. + */ + #include <linux/kernel.h> #include <linux/syscore_ops.h> #include <linux/interrupt.h> #include <linux/serial_core.h> #include <linux/irq.h> #include <linux/io.h> +#include <linux/of.h> #include <mach/map.h> @@ -101,6 +106,10 @@ static struct syscore_ops s3c64xx_irq_syscore_ops = { static __init int s3c64xx_syscore_init(void) { + /* Appropriate drivers (pinctrl, uart) handle this when using DT. */ + if (of_have_populated_dt()) + return 0; + register_syscore_ops(&s3c64xx_irq_syscore_ops); return 0; diff --git a/arch/arm/mach-s3c64xx/mach-anw6410.c b/arch/arm/mach-s3c64xx/mach-anw6410.c index 35e3f54574ef..d266dd5f7060 100644 --- a/arch/arm/mach-s3c64xx/mach-anw6410.c +++ b/arch/arm/mach-s3c64xx/mach-anw6410.c @@ -207,7 +207,7 @@ static struct platform_device *anw6410_devices[] __initdata = { static void __init anw6410_map_io(void) { s3c64xx_init_io(anw6410_iodesc, ARRAY_SIZE(anw6410_iodesc)); - s3c24xx_init_clocks(12000000); + s3c64xx_set_xtal_freq(12000000); s3c24xx_init_uarts(anw6410_uartcfgs, ARRAY_SIZE(anw6410_uartcfgs)); samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c index eb8e5a1aca42..758e31b26550 100644 --- a/arch/arm/mach-s3c64xx/mach-crag6410.c +++ b/arch/arm/mach-s3c64xx/mach-crag6410.c @@ -114,6 +114,7 @@ static struct platform_pwm_backlight_data crag6410_backlight_data = { .max_brightness = 1000, .dft_brightness = 600, .pwm_period_ns = 100000, /* about 1kHz */ + .enable_gpio = -1, }; static struct platform_device crag6410_backlight_device = { @@ -310,10 +311,6 @@ static struct regulator_consumer_supply wallvdd_consumers[] = { REGULATOR_SUPPLY("SPKVDDL", "spi0.1"), REGULATOR_SUPPLY("SPKVDDR", "spi0.1"), - REGULATOR_SUPPLY("SPKVDDL", "wm5102-codec"), - REGULATOR_SUPPLY("SPKVDDR", "wm5102-codec"), - REGULATOR_SUPPLY("SPKVDDL", "wm5110-codec"), - REGULATOR_SUPPLY("SPKVDDR", "wm5110-codec"), REGULATOR_SUPPLY("DC1VDD", "0-0034"), REGULATOR_SUPPLY("DC2VDD", "0-0034"), @@ -653,14 +650,6 @@ static struct regulator_consumer_supply pvdd_1v8_consumers[] = { REGULATOR_SUPPLY("DBVDD3", "spi0.1"), REGULATOR_SUPPLY("LDOVDD", "spi0.1"), REGULATOR_SUPPLY("CPVDD", "spi0.1"), - - REGULATOR_SUPPLY("DBVDD2", "wm5102-codec"), - REGULATOR_SUPPLY("DBVDD3", "wm5102-codec"), - REGULATOR_SUPPLY("CPVDD", "wm5102-codec"), - - REGULATOR_SUPPLY("DBVDD2", "wm5110-codec"), - REGULATOR_SUPPLY("DBVDD3", "wm5110-codec"), - REGULATOR_SUPPLY("CPVDD", "wm5110-codec"), }; static struct regulator_init_data pvdd_1v8 = { @@ -743,7 +732,7 @@ static struct s3c2410_platform_i2c i2c1_pdata = { static void __init crag6410_map_io(void) { s3c64xx_init_io(NULL, 0); - s3c24xx_init_clocks(12000000); + s3c64xx_set_xtal_freq(12000000); s3c24xx_init_uarts(crag6410_uartcfgs, ARRAY_SIZE(crag6410_uartcfgs)); samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); diff --git a/arch/arm/mach-s3c64xx/mach-hmt.c b/arch/arm/mach-s3c64xx/mach-hmt.c index f39569e0f2e6..614a03a92cf7 100644 --- a/arch/arm/mach-s3c64xx/mach-hmt.c +++ b/arch/arm/mach-s3c64xx/mach-hmt.c @@ -114,6 +114,7 @@ static struct platform_pwm_backlight_data hmt_backlight_data = { .max_brightness = 100 * 256, .dft_brightness = 40 * 256, .pwm_period_ns = 1000000000 / (100 * 256 * 20), + .enable_gpio = -1, .init = hmt_bl_init, .notify = hmt_bl_notify, .exit = hmt_bl_exit, @@ -247,7 +248,7 @@ static struct platform_device *hmt_devices[] __initdata = { static void __init hmt_map_io(void) { s3c64xx_init_io(hmt_iodesc, ARRAY_SIZE(hmt_iodesc)); - s3c24xx_init_clocks(12000000); + s3c64xx_set_xtal_freq(12000000); s3c24xx_init_uarts(hmt_uartcfgs, ARRAY_SIZE(hmt_uartcfgs)); samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); } diff --git a/arch/arm/mach-s3c64xx/mach-mini6410.c b/arch/arm/mach-s3c64xx/mach-mini6410.c index fc043e3ecdf8..58d46a3d7b78 100644 --- a/arch/arm/mach-s3c64xx/mach-mini6410.c +++ b/arch/arm/mach-s3c64xx/mach-mini6410.c @@ -231,7 +231,7 @@ static void __init mini6410_map_io(void) u32 tmp; s3c64xx_init_io(NULL, 0); - s3c24xx_init_clocks(12000000); + s3c64xx_set_xtal_freq(12000000); s3c24xx_init_uarts(mini6410_uartcfgs, ARRAY_SIZE(mini6410_uartcfgs)); samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); diff --git a/arch/arm/mach-s3c64xx/mach-ncp.c b/arch/arm/mach-s3c64xx/mach-ncp.c index 7e2c3908f1f8..2067b0bf55b4 100644 --- a/arch/arm/mach-s3c64xx/mach-ncp.c +++ b/arch/arm/mach-s3c64xx/mach-ncp.c @@ -86,7 +86,7 @@ static struct map_desc ncp_iodesc[] __initdata = {}; static void __init ncp_map_io(void) { s3c64xx_init_io(ncp_iodesc, ARRAY_SIZE(ncp_iodesc)); - s3c24xx_init_clocks(12000000); + s3c64xx_set_xtal_freq(12000000); s3c24xx_init_uarts(ncp_uartcfgs, ARRAY_SIZE(ncp_uartcfgs)); samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); } diff --git a/arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c b/arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c new file mode 100644 index 000000000000..7eb9a10fc1af --- /dev/null +++ b/arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c @@ -0,0 +1,85 @@ +/* + * Samsung's S3C64XX flattened device tree enabled machine + * + * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.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 + * published by the Free Software Foundation. +*/ + +#include <linux/clk-provider.h> +#include <linux/irqchip.h> +#include <linux/of_platform.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/system_misc.h> + +#include <plat/cpu.h> +#include <plat/watchdog-reset.h> + +#include <mach/map.h> + +#include "common.h" + +/* + * IO mapping for shared system controller IP. + * + * FIXME: Make remaining drivers use dynamic mapping. + */ +static struct map_desc s3c64xx_dt_iodesc[] __initdata = { + { + .virtual = (unsigned long)S3C_VA_SYS, + .pfn = __phys_to_pfn(S3C64XX_PA_SYSCON), + .length = SZ_4K, + .type = MT_DEVICE, + }, +}; + +static void __init s3c64xx_dt_map_io(void) +{ + debug_ll_io_init(); + iotable_init(s3c64xx_dt_iodesc, ARRAY_SIZE(s3c64xx_dt_iodesc)); + + s3c64xx_init_cpu(); + + if (!soc_is_s3c64xx()) + panic("SoC is not S3C64xx!"); +} + +static void __init s3c64xx_dt_init_irq(void) +{ + of_clk_init(NULL); + samsung_wdt_reset_of_init(); + irqchip_init(); +}; + +static void __init s3c64xx_dt_init_machine(void) +{ + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); +} + +static void s3c64xx_dt_restart(enum reboot_mode mode, const char *cmd) +{ + if (mode != REBOOT_SOFT) + samsung_wdt_reset(); + + /* if all else fails, or mode was for soft, jump to 0 */ + soft_restart(0); +} + +static char const *s3c64xx_dt_compat[] __initdata = { + "samsung,s3c6400", + "samsung,s3c6410", + NULL +}; + +DT_MACHINE_START(S3C6400_DT, "Samsung S3C64xx (Flattened Device Tree)") + /* Maintainer: Tomasz Figa <tomasz.figa@gmail.com> */ + .dt_compat = s3c64xx_dt_compat, + .map_io = s3c64xx_dt_map_io, + .init_irq = s3c64xx_dt_init_irq, + .init_machine = s3c64xx_dt_init_machine, + .restart = s3c64xx_dt_restart, +MACHINE_END diff --git a/arch/arm/mach-s3c64xx/mach-smartq.c b/arch/arm/mach-s3c64xx/mach-smartq.c index 86d980b448fd..a6b338fd0470 100644 --- a/arch/arm/mach-s3c64xx/mach-smartq.c +++ b/arch/arm/mach-s3c64xx/mach-smartq.c @@ -151,6 +151,7 @@ static struct platform_pwm_backlight_data smartq_backlight_data = { .max_brightness = 1000, .dft_brightness = 600, .pwm_period_ns = 1000000000 / (1000 * 20), + .enable_gpio = -1, .init = smartq_bl_init, }; @@ -337,13 +338,6 @@ err: return ret; } -static int __init smartq_usb_otg_init(void) -{ - clk_xusbxti.rate = 12000000; - - return 0; -} - static int __init smartq_wifi_init(void) { int ret; @@ -377,7 +371,8 @@ static struct map_desc smartq_iodesc[] __initdata = {}; void __init smartq_map_io(void) { s3c64xx_init_io(smartq_iodesc, ARRAY_SIZE(smartq_iodesc)); - s3c24xx_init_clocks(12000000); + s3c64xx_set_xtal_freq(12000000); + s3c64xx_set_xusbxti_freq(12000000); s3c24xx_init_uarts(smartq_uartcfgs, ARRAY_SIZE(smartq_uartcfgs)); samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); @@ -399,7 +394,6 @@ void __init smartq_machine_init(void) WARN_ON(smartq_lcd_setup_gpio()); WARN_ON(smartq_power_off_init()); WARN_ON(smartq_usb_host_init()); - WARN_ON(smartq_usb_otg_init()); WARN_ON(smartq_wifi_init()); platform_add_devices(smartq_devices, ARRAY_SIZE(smartq_devices)); diff --git a/arch/arm/mach-s3c64xx/mach-smdk6400.c b/arch/arm/mach-s3c64xx/mach-smdk6400.c index d70c0843aea2..27381cfcabbe 100644 --- a/arch/arm/mach-s3c64xx/mach-smdk6400.c +++ b/arch/arm/mach-s3c64xx/mach-smdk6400.c @@ -65,7 +65,7 @@ static struct map_desc smdk6400_iodesc[] = {}; static void __init smdk6400_map_io(void) { s3c64xx_init_io(smdk6400_iodesc, ARRAY_SIZE(smdk6400_iodesc)); - s3c24xx_init_clocks(12000000); + s3c64xx_set_xtal_freq(12000000); s3c24xx_init_uarts(smdk6400_uartcfgs, ARRAY_SIZE(smdk6400_uartcfgs)); samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); } diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c index d90b450c5645..d5ea938cc9a1 100644 --- a/arch/arm/mach-s3c64xx/mach-smdk6410.c +++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c @@ -625,6 +625,7 @@ static struct samsung_bl_gpio_info smdk6410_bl_gpio_info = { static struct platform_pwm_backlight_data smdk6410_bl_data = { .pwm_id = 1, + .enable_gpio = -1, }; static struct s3c_hsotg_plat smdk6410_hsotg_pdata; @@ -634,7 +635,7 @@ static void __init smdk6410_map_io(void) u32 tmp; s3c64xx_init_io(smdk6410_iodesc, ARRAY_SIZE(smdk6410_iodesc)); - s3c24xx_init_clocks(12000000); + s3c64xx_set_xtal_freq(12000000); s3c24xx_init_uarts(smdk6410_uartcfgs, ARRAY_SIZE(smdk6410_uartcfgs)); samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); diff --git a/arch/arm/mach-s3c64xx/pm.c b/arch/arm/mach-s3c64xx/pm.c index 6a1f91fea678..8cdb824a3b43 100644 --- a/arch/arm/mach-s3c64xx/pm.c +++ b/arch/arm/mach-s3c64xx/pm.c @@ -194,29 +194,8 @@ void s3c_pm_debug_smdkled(u32 set, u32 clear) #endif static struct sleep_save core_save[] = { - SAVE_ITEM(S3C_APLL_LOCK), - SAVE_ITEM(S3C_MPLL_LOCK), - SAVE_ITEM(S3C_EPLL_LOCK), - SAVE_ITEM(S3C_CLK_SRC), - SAVE_ITEM(S3C_CLK_DIV0), - SAVE_ITEM(S3C_CLK_DIV1), - SAVE_ITEM(S3C_CLK_DIV2), - SAVE_ITEM(S3C_CLK_OUT), - SAVE_ITEM(S3C_HCLK_GATE), - SAVE_ITEM(S3C_PCLK_GATE), - SAVE_ITEM(S3C_SCLK_GATE), - SAVE_ITEM(S3C_MEM0_GATE), - - SAVE_ITEM(S3C_EPLL_CON1), - SAVE_ITEM(S3C_EPLL_CON0), - SAVE_ITEM(S3C64XX_MEM0DRVCON), SAVE_ITEM(S3C64XX_MEM1DRVCON), - -#ifndef CONFIG_CPU_FREQ - SAVE_ITEM(S3C_APLL_CON), - SAVE_ITEM(S3C_MPLL_CON), -#endif }; static struct sleep_save misc_save[] = { diff --git a/arch/arm/mach-s3c64xx/s3c6400.c b/arch/arm/mach-s3c64xx/s3c6400.c index 4869714c6f1b..3db0c98222f7 100644 --- a/arch/arm/mach-s3c64xx/s3c6400.c +++ b/arch/arm/mach-s3c64xx/s3c6400.c @@ -9,6 +9,10 @@ * published by the Free Software Foundation. */ +/* + * NOTE: Code in this file is not used when booting with Device Tree support. + */ + #include <linux/kernel.h> #include <linux/types.h> #include <linux/interrupt.h> @@ -20,6 +24,7 @@ #include <linux/device.h> #include <linux/serial_core.h> #include <linux/platform_device.h> +#include <linux/of.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> @@ -58,12 +63,6 @@ void __init s3c6400_map_io(void) s3c64xx_onenand1_setname("s3c6400-onenand"); } -void __init s3c6400_init_clocks(int xtal) -{ - s3c64xx_register_clocks(xtal, S3C6400_CLKDIV0_ARM_MASK); - s3c64xx_setup_clocks(); -} - void __init s3c6400_init_irq(void) { /* VIC0 does not have IRQS 5..7, @@ -82,6 +81,10 @@ static struct device s3c6400_dev = { static int __init s3c6400_core_init(void) { + /* Not applicable when using DT. */ + if (of_have_populated_dt()) + return 0; + return subsys_system_register(&s3c6400_subsys, NULL); } diff --git a/arch/arm/mach-s3c64xx/s3c6410.c b/arch/arm/mach-s3c64xx/s3c6410.c index 31c29fdf1800..72b2278953a8 100644 --- a/arch/arm/mach-s3c64xx/s3c6410.c +++ b/arch/arm/mach-s3c64xx/s3c6410.c @@ -10,6 +10,10 @@ * published by the Free Software Foundation. */ +/* + * NOTE: Code in this file is not used when booting with Device Tree support. + */ + #include <linux/kernel.h> #include <linux/types.h> #include <linux/interrupt.h> @@ -21,6 +25,7 @@ #include <linux/device.h> #include <linux/serial_core.h> #include <linux/platform_device.h> +#include <linux/of.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> @@ -62,13 +67,6 @@ void __init s3c6410_map_io(void) s3c_cfcon_setname("s3c64xx-pata"); } -void __init s3c6410_init_clocks(int xtal) -{ - printk(KERN_DEBUG "%s: initialising clocks\n", __func__); - s3c64xx_register_clocks(xtal, S3C6410_CLKDIV0_ARM_MASK); - s3c64xx_setup_clocks(); -} - void __init s3c6410_init_irq(void) { /* VIC0 is missing IRQ7, VIC1 is fully populated. */ @@ -86,6 +84,10 @@ static struct device s3c6410_dev = { static int __init s3c6410_core_init(void) { + /* Not applicable when using DT. */ + if (of_have_populated_dt()) + return 0; + return subsys_system_register(&s3c6410_subsys, NULL); } diff --git a/arch/arm/mach-s5p64x0/mach-smdk6440.c b/arch/arm/mach-s5p64x0/mach-smdk6440.c index 0b00304c1e91..9efdcc03df3b 100644 --- a/arch/arm/mach-s5p64x0/mach-smdk6440.c +++ b/arch/arm/mach-s5p64x0/mach-smdk6440.c @@ -223,6 +223,7 @@ static struct samsung_bl_gpio_info smdk6440_bl_gpio_info = { static struct platform_pwm_backlight_data smdk6440_bl_data = { .pwm_id = 1, + .enable_gpio = -1, }; static void __init smdk6440_map_io(void) diff --git a/arch/arm/mach-s5p64x0/mach-smdk6450.c b/arch/arm/mach-s5p64x0/mach-smdk6450.c index 5949296e88fd..c3cacc067efe 100644 --- a/arch/arm/mach-s5p64x0/mach-smdk6450.c +++ b/arch/arm/mach-s5p64x0/mach-smdk6450.c @@ -242,6 +242,7 @@ static struct samsung_bl_gpio_info smdk6450_bl_gpio_info = { static struct platform_pwm_backlight_data smdk6450_bl_data = { .pwm_id = 1, + .enable_gpio = -1, }; static void __init smdk6450_map_io(void) diff --git a/arch/arm/mach-s5pc100/mach-smdkc100.c b/arch/arm/mach-s5pc100/mach-smdkc100.c index 7c57a221785e..9e256b9fc930 100644 --- a/arch/arm/mach-s5pc100/mach-smdkc100.c +++ b/arch/arm/mach-s5pc100/mach-smdkc100.c @@ -216,6 +216,7 @@ static struct samsung_bl_gpio_info smdkc100_bl_gpio_info = { static struct platform_pwm_backlight_data smdkc100_bl_data = { .pwm_id = 0, + .enable_gpio = -1, }; static void __init smdkc100_map_io(void) diff --git a/arch/arm/mach-s5pv210/include/mach/regs-clock.h b/arch/arm/mach-s5pv210/include/mach/regs-clock.h index 032de66fb8be..e345584d4c34 100644 --- a/arch/arm/mach-s5pv210/include/mach/regs-clock.h +++ b/arch/arm/mach-s5pv210/include/mach/regs-clock.h @@ -147,10 +147,6 @@ #define S5P_HDMI_PHY_CONTROL S5P_CLKREG(0xE804) #define S5P_USB_PHY_CONTROL S5P_CLKREG(0xE80C) #define S5P_DAC_PHY_CONTROL S5P_CLKREG(0xE810) -#define S5P_MIPI_DPHY_CONTROL(x) S5P_CLKREG(0xE814) -#define S5P_MIPI_DPHY_ENABLE (1 << 0) -#define S5P_MIPI_DPHY_SRESETN (1 << 1) -#define S5P_MIPI_DPHY_MRESETN (1 << 2) #define S5P_INFORM0 S5P_CLKREG(0xF000) #define S5P_INFORM1 S5P_CLKREG(0xF004) diff --git a/arch/arm/mach-s5pv210/mach-smdkv210.c b/arch/arm/mach-s5pv210/mach-smdkv210.c index 6d72bb992e38..f52cc15c2d85 100644 --- a/arch/arm/mach-s5pv210/mach-smdkv210.c +++ b/arch/arm/mach-s5pv210/mach-smdkv210.c @@ -279,6 +279,7 @@ static struct samsung_bl_gpio_info smdkv210_bl_gpio_info = { static struct platform_pwm_backlight_data smdkv210_bl_data = { .pwm_id = 3, .pwm_period_ns = 1000, + .enable_gpio = -1, }; static void __init smdkv210_map_io(void) diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c index e838ba27e443..c9808c684152 100644 --- a/arch/arm/mach-sa1100/assabet.c +++ b/arch/arm/mach-sa1100/assabet.c @@ -512,6 +512,9 @@ static void __init assabet_map_io(void) * Its called GPCLKR0 in my SA1110 manual. */ Ser1SDCR0 |= SDCR0_SUS; + MSC1 = (MSC1 & ~0xffff) | + MSC_NonBrst | MSC_32BitStMem | + MSC_RdAcc(2) | MSC_WrAcc(2) | MSC_Rec(0); if (!machine_has_neponset()) sa1100_register_uart_fns(&assabet_port_fns); diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c index f25b6119e028..d4ea142c4edd 100644 --- a/arch/arm/mach-sa1100/generic.c +++ b/arch/arm/mach-sa1100/generic.c @@ -42,74 +42,31 @@ EXPORT_SYMBOL(reset_status); /* * This table is setup for a 3.6864MHz Crystal. */ -static const unsigned short cclk_frequency_100khz[NR_FREQS] = { - 590, /* 59.0 MHz */ - 737, /* 73.7 MHz */ - 885, /* 88.5 MHz */ - 1032, /* 103.2 MHz */ - 1180, /* 118.0 MHz */ - 1327, /* 132.7 MHz */ - 1475, /* 147.5 MHz */ - 1622, /* 162.2 MHz */ - 1769, /* 176.9 MHz */ - 1917, /* 191.7 MHz */ - 2064, /* 206.4 MHz */ - 2212, /* 221.2 MHz */ - 2359, /* 235.9 MHz */ - 2507, /* 250.7 MHz */ - 2654, /* 265.4 MHz */ - 2802 /* 280.2 MHz */ +struct cpufreq_frequency_table sa11x0_freq_table[NR_FREQS+1] = { + { .frequency = 59000, /* 59.0 MHz */}, + { .frequency = 73700, /* 73.7 MHz */}, + { .frequency = 88500, /* 88.5 MHz */}, + { .frequency = 103200, /* 103.2 MHz */}, + { .frequency = 118000, /* 118.0 MHz */}, + { .frequency = 132700, /* 132.7 MHz */}, + { .frequency = 147500, /* 147.5 MHz */}, + { .frequency = 162200, /* 162.2 MHz */}, + { .frequency = 176900, /* 176.9 MHz */}, + { .frequency = 191700, /* 191.7 MHz */}, + { .frequency = 206400, /* 206.4 MHz */}, + { .frequency = 221200, /* 221.2 MHz */}, + { .frequency = 235900, /* 235.9 MHz */}, + { .frequency = 250700, /* 250.7 MHz */}, + { .frequency = 265400, /* 265.4 MHz */}, + { .frequency = 280200, /* 280.2 MHz */}, + { .frequency = CPUFREQ_TABLE_END, }, }; -/* rounds up(!) */ -unsigned int sa11x0_freq_to_ppcr(unsigned int khz) -{ - int i; - - khz /= 100; - - for (i = 0; i < NR_FREQS; i++) - if (cclk_frequency_100khz[i] >= khz) - break; - - return i; -} - -unsigned int sa11x0_ppcr_to_freq(unsigned int idx) -{ - unsigned int freq = 0; - if (idx < NR_FREQS) - freq = cclk_frequency_100khz[idx] * 100; - return freq; -} - - -/* make sure that only the "userspace" governor is run -- anything else wouldn't make sense on - * this platform, anyway. - */ -int sa11x0_verify_speed(struct cpufreq_policy *policy) -{ - unsigned int tmp; - if (policy->cpu) - return -EINVAL; - - cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, policy->cpuinfo.max_freq); - - /* make sure that at least one frequency is within the policy */ - tmp = cclk_frequency_100khz[sa11x0_freq_to_ppcr(policy->min)] * 100; - if (tmp > policy->max) - policy->max = tmp; - - cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, policy->cpuinfo.max_freq); - - return 0; -} - unsigned int sa11x0_getspeed(unsigned int cpu) { if (cpu) return 0; - return cclk_frequency_100khz[PPCR & 0xf] * 100; + return sa11x0_freq_table[PPCR & 0xf].frequency; } /* diff --git a/arch/arm/mach-sa1100/generic.h b/arch/arm/mach-sa1100/generic.h index 9a33695c9492..0d92e119b36b 100644 --- a/arch/arm/mach-sa1100/generic.h +++ b/arch/arm/mach-sa1100/generic.h @@ -3,6 +3,7 @@ * * Author: Nicolas Pitre */ +#include <linux/cpufreq.h> #include <linux/reboot.h> extern void sa1100_timer_init(void); @@ -19,12 +20,8 @@ extern void sa11x0_init_late(void); extern void sa1110_mb_enable(void); extern void sa1110_mb_disable(void); -struct cpufreq_policy; - -extern unsigned int sa11x0_freq_to_ppcr(unsigned int khz); -extern int sa11x0_verify_speed(struct cpufreq_policy *policy); +extern struct cpufreq_frequency_table sa11x0_freq_table[]; extern unsigned int sa11x0_getspeed(unsigned int cpu); -extern unsigned int sa11x0_ppcr_to_freq(unsigned int idx); struct flash_platform_data; struct resource; diff --git a/arch/arm/mach-sa1100/include/mach/gpio.h b/arch/arm/mach-sa1100/include/mach/gpio.h deleted file mode 100644 index 6a9eecf3137e..000000000000 --- a/arch/arm/mach-sa1100/include/mach/gpio.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * arch/arm/mach-sa1100/include/mach/gpio.h - * - * SA1100 GPIO wrappers for arch-neutral GPIO calls - * - * Written by Philipp Zabel <philipp.zabel@gmail.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __ASM_ARCH_SA1100_GPIO_H -#define __ASM_ARCH_SA1100_GPIO_H - -#include <linux/io.h> -#include <mach/hardware.h> -#include <asm/irq.h> -#include <asm-generic/gpio.h> - -#define __ARM_GPIOLIB_COMPLEX - -static inline int gpio_get_value(unsigned gpio) -{ - if (__builtin_constant_p(gpio) && (gpio <= GPIO_MAX)) - return GPLR & GPIO_GPIO(gpio); - else - return __gpio_get_value(gpio); -} - -static inline void gpio_set_value(unsigned gpio, int value) -{ - if (__builtin_constant_p(gpio) && (gpio <= GPIO_MAX)) - if (value) - GPSR = GPIO_GPIO(gpio); - else - GPCR = GPIO_GPIO(gpio); - else - __gpio_set_value(gpio, value); -} - -#define gpio_cansleep __gpio_cansleep - -#endif diff --git a/arch/arm/mach-sa1100/include/mach/h3xxx.h b/arch/arm/mach-sa1100/include/mach/h3xxx.h index 7d9df16f04a2..c810620db53d 100644 --- a/arch/arm/mach-sa1100/include/mach/h3xxx.h +++ b/arch/arm/mach-sa1100/include/mach/h3xxx.h @@ -13,6 +13,8 @@ #ifndef _INCLUDE_H3XXX_H_ #define _INCLUDE_H3XXX_H_ +#include "hardware.h" /* Gives GPIO_MAX */ + /* Physical memory regions corresponding to chip selects */ #define H3600_EGPIO_PHYS (SA1100_CS5_PHYS + 0x01000000) #define H3600_BANK_2_PHYS SA1100_CS2_PHYS diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c index bcbc94540e45..41e476e571d7 100644 --- a/arch/arm/mach-sa1100/simpad.c +++ b/arch/arm/mach-sa1100/simpad.c @@ -19,6 +19,7 @@ #include <mach/hardware.h> #include <asm/setup.h> +#include <asm/irq.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> diff --git a/arch/arm/mach-shark/Makefile b/arch/arm/mach-shark/Makefile deleted file mode 100644 index 29657183c452..000000000000 --- a/arch/arm/mach-shark/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# -# Makefile for the linux kernel. -# - -# Object file lists. - -obj-y := core.o dma.o irq.o pci.o leds.o -obj-m := -obj-n := -obj- := diff --git a/arch/arm/mach-shark/Makefile.boot b/arch/arm/mach-shark/Makefile.boot deleted file mode 100644 index e40e24e4ca34..000000000000 --- a/arch/arm/mach-shark/Makefile.boot +++ /dev/null @@ -1,2 +0,0 @@ - zreladdr-y += 0x08008000 - diff --git a/arch/arm/mach-shark/core.c b/arch/arm/mach-shark/core.c deleted file mode 100644 index 1d32c5e8eab6..000000000000 --- a/arch/arm/mach-shark/core.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * linux/arch/arm/mach-shark/arch.c - * - * Architecture specific stuff. - */ -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/sched.h> -#include <linux/serial_8250.h> -#include <linux/io.h> -#include <linux/cpu.h> -#include <linux/reboot.h> - -#include <asm/setup.h> -#include <asm/mach-types.h> -#include <asm/param.h> -#include <asm/system_misc.h> - -#include <asm/mach/map.h> -#include <asm/mach/arch.h> -#include <asm/mach/time.h> - -#define ROMCARD_SIZE 0x08000000 -#define ROMCARD_START 0x10000000 - -static void shark_restart(enum reboot_mode mode, const char *cmd) -{ - short temp; - /* Reset the Machine via pc[3] of the sequoia chipset */ - outw(0x09,0x24); - temp=inw(0x26); - temp = temp | (1<<3) | (1<<10); - outw(0x09,0x24); - outw(temp,0x26); -} - -static struct plat_serial8250_port serial_platform_data[] = { - { - .iobase = 0x3f8, - .irq = 4, - .uartclk = 1843200, - .regshift = 0, - .iotype = UPIO_PORT, - .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, - }, - { - .iobase = 0x2f8, - .irq = 3, - .uartclk = 1843200, - .regshift = 0, - .iotype = UPIO_PORT, - .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, - }, - { }, -}; - -static struct platform_device serial_device = { - .name = "serial8250", - .id = PLAT8250_DEV_PLATFORM, - .dev = { - .platform_data = serial_platform_data, - }, -}; - -static struct resource rtc_resources[] = { - [0] = { - .start = 0x70, - .end = 0x73, - .flags = IORESOURCE_IO, - }, - [1] = { - .start = IRQ_ISA_RTC_ALARM, - .end = IRQ_ISA_RTC_ALARM, - .flags = IORESOURCE_IRQ, - } -}; - -static struct platform_device rtc_device = { - .name = "rtc_cmos", - .id = -1, - .resource = rtc_resources, - .num_resources = ARRAY_SIZE(rtc_resources), -}; - -static int __init shark_init(void) -{ - int ret; - - if (machine_is_shark()) - { - ret = platform_device_register(&rtc_device); - if (ret) printk(KERN_ERR "Unable to register RTC device: %d\n", ret); - ret = platform_device_register(&serial_device); - if (ret) printk(KERN_ERR "Unable to register Serial device: %d\n", ret); - } - return 0; -} - -arch_initcall(shark_init); - -extern void shark_init_irq(void); - -#define IRQ_TIMER 0 -#define HZ_TIME ((1193180 + HZ/2) / HZ) - -static irqreturn_t -shark_timer_interrupt(int irq, void *dev_id) -{ - timer_tick(); - return IRQ_HANDLED; -} - -static struct irqaction shark_timer_irq = { - .name = "Shark Timer Tick", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, - .handler = shark_timer_interrupt, -}; - -/* - * Set up timer interrupt, and return the current time in seconds. - */ -static void __init shark_timer_init(void) -{ - outb(0x34, 0x43); /* binary, mode 0, LSB/MSB, Ch 0 */ - outb(HZ_TIME & 0xff, 0x40); /* LSB of count */ - outb(HZ_TIME >> 8, 0x40); - - setup_irq(IRQ_TIMER, &shark_timer_irq); -} - -static void shark_init_early(void) -{ - cpu_idle_poll_ctrl(true); -} - -MACHINE_START(SHARK, "Shark") - /* Maintainer: Alexander Schulz */ - .atag_offset = 0x3000, - .init_early = shark_init_early, - .init_irq = shark_init_irq, - .init_time = shark_timer_init, - .dma_zone_size = SZ_4M, - .restart = shark_restart, -MACHINE_END diff --git a/arch/arm/mach-shark/dma.c b/arch/arm/mach-shark/dma.c deleted file mode 100644 index 10b5b8b3272a..000000000000 --- a/arch/arm/mach-shark/dma.c +++ /dev/null @@ -1,23 +0,0 @@ -/* - * linux/arch/arm/mach-shark/dma.c - * - * by Alexander Schulz - * - * derived from: - * arch/arm/kernel/dma-ebsa285.c - * Copyright (C) 1998 Phil Blundell - */ - -#include <linux/init.h> - -#include <asm/dma.h> -#include <asm/mach/dma.h> - -static int __init shark_dma_init(void) -{ -#ifdef CONFIG_ISA_DMA - isa_init_dma(); -#endif - return 0; -} -core_initcall(shark_dma_init); diff --git a/arch/arm/mach-shark/include/mach/debug-macro.S b/arch/arm/mach-shark/include/mach/debug-macro.S deleted file mode 100644 index d129119a3f69..000000000000 --- a/arch/arm/mach-shark/include/mach/debug-macro.S +++ /dev/null @@ -1,34 +0,0 @@ -/* arch/arm/mach-shark/include/mach/debug-macro.S - * - * Debugging macro include header - * - * Copyright (C) 1994-1999 Russell King - * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks - * - * 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. - * -*/ - - .macro addruart, rp, rv, tmp - mov \rp, #0x3f8 - orr \rv, \rp, #0xfe000000 - orr \rv, \rv, #0x00e00000 - orr \rp, \rp, #0x40000000 - .endm - - .macro senduart,rd,rx - strb \rd, [\rx] - .endm - - .macro waituart,rd,rx - .endm - - .macro busyuart,rd,rx - mov \rd, #0 -1001: add \rd, \rd, #1 - teq \rd, #0x10000 - bne 1001b - .endm - diff --git a/arch/arm/mach-shark/include/mach/entry-macro.S b/arch/arm/mach-shark/include/mach/entry-macro.S deleted file mode 100644 index c9e49f049532..000000000000 --- a/arch/arm/mach-shark/include/mach/entry-macro.S +++ /dev/null @@ -1,36 +0,0 @@ -/* - * arch/arm/mach-shark/include/mach/entry-macro.S - * - * Low-level IRQ helper macros for Shark platform - * - * 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. - */ - .macro get_irqnr_preamble, base, tmp - mov \base, #0xfe000000 - orr \base, \base, #0x00e00000 - .endm - - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp - - mov \irqstat, #0x0C - strb \irqstat, [\base, #0x20] @outb(0x0C, 0x20) /* Poll command */ - ldrb \irqnr, [\base, #0x20] @irq = inb(0x20) & 7 - and \irqstat, \irqnr, #0x80 - teq \irqstat, #0 - beq 43f - and \irqnr, \irqnr, #7 - teq \irqnr, #2 - bne 44f -43: mov \irqstat, #0x0C - strb \irqstat, [\base, #0xa0] @outb(0x0C, 0xA0) /* Poll command */ - ldrb \irqnr, [\base, #0xa0] @irq = (inb(0xA0) & 7) + 8 - and \irqstat, \irqnr, #0x80 - teq \irqstat, #0 - beq 44f - and \irqnr, \irqnr, #7 - add \irqnr, \irqnr, #8 -44: teq \irqstat, #0 - .endm - diff --git a/arch/arm/mach-shark/include/mach/framebuffer.h b/arch/arm/mach-shark/include/mach/framebuffer.h deleted file mode 100644 index 84a5bf6e5ba3..000000000000 --- a/arch/arm/mach-shark/include/mach/framebuffer.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * arch/arm/mach-shark/include/mach/framebuffer.h - * - * by Alexander Schulz - * - */ - -#ifndef __ASM_ARCH_FRAMEBUFFER_H -#define __ASM_ARCH_FRAMEBUFFER_H - -/* defines for the Framebuffer */ -#define FB_START 0x06000000 -#define FB_SIZE 0x01000000 - -#endif - diff --git a/arch/arm/mach-shark/include/mach/hardware.h b/arch/arm/mach-shark/include/mach/hardware.h deleted file mode 100644 index 663f952a8ab3..000000000000 --- a/arch/arm/mach-shark/include/mach/hardware.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * arch/arm/mach-shark/include/mach/hardware.h - * - * by Alexander Schulz - * - * derived from: - * arch/arm/mach-ebsa110/include/mach/hardware.h - * Copyright (C) 1996-1999 Russell King. - */ -#ifndef __ASM_ARCH_HARDWARE_H -#define __ASM_ARCH_HARDWARE_H - -#define UNCACHEABLE_ADDR 0xdf010000 - -#endif - diff --git a/arch/arm/mach-shark/include/mach/irqs.h b/arch/arm/mach-shark/include/mach/irqs.h deleted file mode 100644 index c8e8a4e1f61a..000000000000 --- a/arch/arm/mach-shark/include/mach/irqs.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/arm/mach-shark/include/mach/irqs.h - * - * by Alexander Schulz - */ - -#define NR_IRQS 16 - -#define IRQ_ISA_KEYBOARD 1 -#define IRQ_ISA_RTC_ALARM 8 -#define I8042_KBD_IRQ 1 -#define I8042_AUX_IRQ 12 -#define IRQ_HARDDISK 14 diff --git a/arch/arm/mach-shark/include/mach/isa-dma.h b/arch/arm/mach-shark/include/mach/isa-dma.h deleted file mode 100644 index 96c43b8f8dda..000000000000 --- a/arch/arm/mach-shark/include/mach/isa-dma.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/arm/mach-shark/include/mach/isa-dma.h - * - * by Alexander Schulz - */ -#ifndef __ASM_ARCH_DMA_H -#define __ASM_ARCH_DMA_H - -#define MAX_DMA_CHANNELS 8 -#define DMA_ISA_CASCADE 4 - -#endif /* _ASM_ARCH_DMA_H */ - diff --git a/arch/arm/mach-shark/include/mach/memory.h b/arch/arm/mach-shark/include/mach/memory.h deleted file mode 100644 index 1cf8d6962617..000000000000 --- a/arch/arm/mach-shark/include/mach/memory.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * arch/arm/mach-shark/include/mach/memory.h - * - * by Alexander Schulz - * - * derived from: - * arch/arm/mach-ebsa110/include/mach/memory.h - * Copyright (c) 1996-1999 Russell King. - */ -#ifndef __ASM_ARCH_MEMORY_H -#define __ASM_ARCH_MEMORY_H - -#include <asm/sizes.h> - -/* - * Physical DRAM offset. - */ -#define PLAT_PHYS_OFFSET UL(0x08000000) - -/* - * Cache flushing area - */ -#define FLUSH_BASE_PHYS 0x80000000 -#define FLUSH_BASE 0xdf000000 - -#endif diff --git a/arch/arm/mach-shark/include/mach/timex.h b/arch/arm/mach-shark/include/mach/timex.h deleted file mode 100644 index bb6eeaebed86..000000000000 --- a/arch/arm/mach-shark/include/mach/timex.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * arch/arm/mach-shark/include/mach/timex.h - * - * by Alexander Schulz - */ - -#define CLOCK_TICK_RATE 1193180 diff --git a/arch/arm/mach-shark/include/mach/uncompress.h b/arch/arm/mach-shark/include/mach/uncompress.h deleted file mode 100644 index a168435aecc9..000000000000 --- a/arch/arm/mach-shark/include/mach/uncompress.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * arch/arm/mach-shark/include/mach/uncompress.h - * by Alexander Schulz - * - * derived from: - * arch/arm/mach-footbridge/include/mach/uncompress.h - * Copyright (C) 1996,1997,1998 Russell King - */ - -#define SERIAL_BASE ((volatile unsigned char *)0x400003f8) - -static inline void putc(int c) -{ - volatile int t; - - SERIAL_BASE[0] = c; - t=0x10000; - while (t--); -} - -static inline void flush(void) -{ -} - -#ifdef DEBUG -static void putn(unsigned long z) -{ - int i; - char x; - - putc('0'); - putc('x'); - for (i=0;i<8;i++) { - x='0'+((z>>((7-i)*4))&0xf); - if (x>'9') x=x-'0'+'A'-10; - putc(x); - } -} - -static void putr() -{ - putc('\n'); - putc('\r'); -} -#endif - -/* - * nothing to do - */ -#define arch_decomp_setup() diff --git a/arch/arm/mach-shark/irq.c b/arch/arm/mach-shark/irq.c deleted file mode 100644 index 5dce13e429f3..000000000000 --- a/arch/arm/mach-shark/irq.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * linux/arch/arm/mach-shark/irq.c - * - * by Alexander Schulz - * - * derived from linux/arch/ppc/kernel/i8259.c and: - * arch/arm/mach-ebsa110/include/mach/irq.h - * Copyright (C) 1996-1998 Russell King - */ - -#include <linux/init.h> -#include <linux/fs.h> -#include <linux/interrupt.h> -#include <linux/io.h> - -#include <asm/irq.h> -#include <asm/mach/irq.h> - -/* - * 8259A PIC functions to handle ISA devices: - */ - -/* - * This contains the irq mask for both 8259A irq controllers, - * Let through the cascade-interrupt no. 2 (ff-(1<<2)==fb) - */ -static unsigned char cached_irq_mask[2] = { 0xfb, 0xff }; - -/* - * These have to be protected by the irq controller spinlock - * before being called. - */ -static void shark_disable_8259A_irq(struct irq_data *d) -{ - unsigned int mask; - if (d->irq<8) { - mask = 1 << d->irq; - cached_irq_mask[0] |= mask; - outb(cached_irq_mask[1],0xA1); - } else { - mask = 1 << (d->irq-8); - cached_irq_mask[1] |= mask; - outb(cached_irq_mask[0],0x21); - } -} - -static void shark_enable_8259A_irq(struct irq_data *d) -{ - unsigned int mask; - if (d->irq<8) { - mask = ~(1 << d->irq); - cached_irq_mask[0] &= mask; - outb(cached_irq_mask[0],0x21); - } else { - mask = ~(1 << (d->irq-8)); - cached_irq_mask[1] &= mask; - outb(cached_irq_mask[1],0xA1); - } -} - -static void shark_ack_8259A_irq(struct irq_data *d){} - -static irqreturn_t bogus_int(int irq, void *dev_id) -{ - printk("Got interrupt %i!\n",irq); - return IRQ_NONE; -} - -static struct irqaction cascade; - -static struct irq_chip fb_chip = { - .name = "XT-PIC", - .irq_ack = shark_ack_8259A_irq, - .irq_mask = shark_disable_8259A_irq, - .irq_unmask = shark_enable_8259A_irq, -}; - -void __init shark_init_irq(void) -{ - int irq; - - for (irq = 0; irq < NR_IRQS; irq++) { - irq_set_chip_and_handler(irq, &fb_chip, handle_edge_irq); - set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); - } - - /* init master interrupt controller */ - outb(0x11, 0x20); /* Start init sequence, edge triggered (level: 0x19)*/ - outb(0x00, 0x21); /* Vector base */ - outb(0x04, 0x21); /* Cascade (slave) on IRQ2 */ - outb(0x03, 0x21); /* Select 8086 mode , auto eoi*/ - outb(0x0A, 0x20); - /* init slave interrupt controller */ - outb(0x11, 0xA0); /* Start init sequence, edge triggered */ - outb(0x08, 0xA1); /* Vector base */ - outb(0x02, 0xA1); /* Cascade (slave) on IRQ2 */ - outb(0x03, 0xA1); /* Select 8086 mode, auto eoi */ - outb(0x0A, 0xA0); - outb(cached_irq_mask[1],0xA1); - outb(cached_irq_mask[0],0x21); - //request_region(0x20,0x2,"pic1"); - //request_region(0xA0,0x2,"pic2"); - - cascade.handler = bogus_int; - cascade.name = "cascade"; - setup_irq(2,&cascade); -} - diff --git a/arch/arm/mach-shark/leds.c b/arch/arm/mach-shark/leds.c deleted file mode 100644 index 081c778a10ac..000000000000 --- a/arch/arm/mach-shark/leds.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * DIGITAL Shark LED control routines. - * - * Driver for the 3 user LEDs found on the Shark - * Based on Versatile and RealView machine LED code - * - * License terms: GNU General Public License (GPL) version 2 - * Author: Bryan Wu <bryan.wu@canonical.com> - */ -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/io.h> -#include <linux/ioport.h> -#include <linux/slab.h> -#include <linux/leds.h> - -#include <asm/mach-types.h> - -#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS) -struct shark_led { - struct led_classdev cdev; - u8 mask; -}; - -/* - * The triggers lines up below will only be used if the - * LED triggers are compiled in. - */ -static const struct { - const char *name; - const char *trigger; -} shark_leds[] = { - { "shark:amber0", "default-on", }, /* Bit 5 */ - { "shark:green", "heartbeat", }, /* Bit 6 */ - { "shark:amber1", "cpu0" }, /* Bit 7 */ -}; - -static u16 led_reg_read(void) -{ - outw(0x09, 0x24); - return inw(0x26); -} - -static void led_reg_write(u16 value) -{ - outw(0x09, 0x24); - outw(value, 0x26); -} - -static void shark_led_set(struct led_classdev *cdev, - enum led_brightness b) -{ - struct shark_led *led = container_of(cdev, - struct shark_led, cdev); - u16 reg = led_reg_read(); - - if (b != LED_OFF) - reg |= led->mask; - else - reg &= ~led->mask; - - led_reg_write(reg); -} - -static enum led_brightness shark_led_get(struct led_classdev *cdev) -{ - struct shark_led *led = container_of(cdev, - struct shark_led, cdev); - u16 reg = led_reg_read(); - - return (reg & led->mask) ? LED_FULL : LED_OFF; -} - -static int __init shark_leds_init(void) -{ - int i; - u16 reg; - - if (!machine_is_shark()) - return -ENODEV; - - for (i = 0; i < ARRAY_SIZE(shark_leds); i++) { - struct shark_led *led; - - led = kzalloc(sizeof(*led), GFP_KERNEL); - if (!led) - break; - - led->cdev.name = shark_leds[i].name; - led->cdev.brightness_set = shark_led_set; - led->cdev.brightness_get = shark_led_get; - led->cdev.default_trigger = shark_leds[i].trigger; - - /* Count in 5 bits offset */ - led->mask = BIT(i + 5); - - if (led_classdev_register(NULL, &led->cdev) < 0) { - kfree(led); - break; - } - } - - /* Make LEDs independent of power-state */ - request_region(0x24, 4, "led_reg"); - reg = led_reg_read(); - reg |= 1 << 10; - led_reg_write(reg); - - return 0; -} - -/* - * Since we may have triggers on any subsystem, defer registration - * until after subsystem_init. - */ -fs_initcall(shark_leds_init); -#endif diff --git a/arch/arm/mach-shark/pci.c b/arch/arm/mach-shark/pci.c deleted file mode 100644 index 6d91a914c1dd..000000000000 --- a/arch/arm/mach-shark/pci.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * linux/arch/arm/mach-shark/pci.c - * - * PCI bios-type initialisation for PCI machines - * - * Bits taken from various places. - */ -#include <linux/kernel.h> -#include <linux/pci.h> -#include <linux/init.h> -#include <linux/io.h> -#include <video/vga.h> - -#include <asm/irq.h> -#include <asm/mach/pci.h> -#include <asm/mach-types.h> - -#define IO_START 0x40000000 - -static int __init shark_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) -{ - if (dev->bus->number == 0) - if (dev->devfn == 0) - return 255; - else - return 11; - else - return 255; -} - -extern void __init via82c505_preinit(void); - -static struct hw_pci shark_pci __initdata = { - .setup = via82c505_setup, - .map_irq = shark_map_irq, - .nr_controllers = 1, - .ops = &via82c505_ops, - .preinit = via82c505_preinit, -}; - -static int __init shark_pci_init(void) -{ - if (!machine_is_shark()) - return -ENODEV; - - pcibios_min_io = 0x6000; - pcibios_min_mem = 0x50000000; - vga_base = 0xe8000000; - - pci_ioremap_io(0, IO_START); - - pci_common_init(&shark_pci); - - return 0; -} - -subsys_initcall(shark_pci_init); diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig index 1f94c310c477..a4a4b75109b2 100644 --- a/arch/arm/mach-shmobile/Kconfig +++ b/arch/arm/mach-shmobile/Kconfig @@ -22,16 +22,10 @@ config ARCH_EMEV2 comment "SH-Mobile Board Type" -config MACH_KZM9D_REFERENCE - bool "KZM9D board - Reference Device Tree Implementation" +config MACH_KZM9D + bool "KZM9D board" depends on ARCH_EMEV2 select REGULATOR_FIXED_VOLTAGE if REGULATOR - ---help--- - Use reference implementation of KZM9D board support - which makes a greater use of device tree at the expense - of not supporting a number of devices. - - This is intended to aid developers comment "SH-Mobile System Configuration" endif @@ -101,12 +95,24 @@ config ARCH_R8A7790 select SH_CLK_CPG select RENESAS_IRQC +config ARCH_R8A7791 + bool "R-Car M2 (R8A77910)" + select ARM_GIC + select CPU_V7 + select SH_CLK_CPG + config ARCH_EMEV2 bool "Emma Mobile EV2" select ARCH_WANT_OPTIONAL_GPIOLIB select ARM_GIC select CPU_V7 +config ARCH_R7S72100 + bool "RZ/A1H (R7S72100)" + select ARM_GIC + select CPU_V7 + select SH_CLK_CPG + comment "SH-Mobile Board Type" config MACH_APE6EVM @@ -162,6 +168,8 @@ config MACH_BOCKW select RENESAS_INTC_IRQPIN select REGULATOR_FIXED_VOLTAGE if REGULATOR select USE_OF + select SND_SOC_AK4554 if SND_SIMPLE_CARD + select SND_SOC_AK4642 if SND_SIMPLE_CARD config MACH_BOCKW_REFERENCE bool "BOCK-W - Reference Device Tree Implementation" @@ -177,6 +185,11 @@ config MACH_BOCKW_REFERENCE This is intended to aid developers +config MACH_GENMAI + bool "Genmai board" + depends on ARCH_R7S72100 + select USE_OF + config MACH_MARZEN bool "MARZEN board" depends on ARCH_R8A7779 @@ -213,23 +226,16 @@ config MACH_LAGER_REFERENCE This is intended to aid developers -config MACH_KZM9D - bool "KZM9D board" - depends on ARCH_EMEV2 - select REGULATOR_FIXED_VOLTAGE if REGULATOR +config MACH_KOELSCH + bool "Koelsch board" + depends on ARCH_R8A7791 select USE_OF -config MACH_KZM9D_REFERENCE - bool "KZM9D board - Reference Device Tree Implementation" +config MACH_KZM9D + bool "KZM9D board" depends on ARCH_EMEV2 select REGULATOR_FIXED_VOLTAGE if REGULATOR select USE_OF - ---help--- - Use reference implementation of KZM9D board support - which makes a greater use of device tree at the expense - of not supporting a number of devices. - - This is intended to aid developers config MACH_KZM9G bool "KZM-A9-GT board" diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile index 2705bfa8c113..51db2bcafabf 100644 --- a/arch/arm/mach-shmobile/Makefile +++ b/arch/arm/mach-shmobile/Makefile @@ -15,7 +15,10 @@ obj-$(CONFIG_ARCH_R8A7740) += setup-r8a7740.o obj-$(CONFIG_ARCH_R8A7778) += setup-r8a7778.o obj-$(CONFIG_ARCH_R8A7779) += setup-r8a7779.o obj-$(CONFIG_ARCH_R8A7790) += setup-r8a7790.o +obj-$(CONFIG_ARCH_R8A7790) += setup-r8a7790.o setup-rcar-gen2.o +obj-$(CONFIG_ARCH_R8A7791) += setup-r8a7791.o setup-rcar-gen2.o obj-$(CONFIG_ARCH_EMEV2) += setup-emev2.o +obj-$(CONFIG_ARCH_R7S72100) += setup-r7s72100.o # Clock objects ifndef CONFIG_COMMON_CLK @@ -27,13 +30,17 @@ obj-$(CONFIG_ARCH_R8A7740) += clock-r8a7740.o obj-$(CONFIG_ARCH_R8A7778) += clock-r8a7778.o obj-$(CONFIG_ARCH_R8A7779) += clock-r8a7779.o obj-$(CONFIG_ARCH_R8A7790) += clock-r8a7790.o +obj-$(CONFIG_ARCH_R8A7791) += clock-r8a7791.o obj-$(CONFIG_ARCH_EMEV2) += clock-emev2.o +obj-$(CONFIG_ARCH_R7S72100) += clock-r7s72100.o endif # SMP objects smp-y := platsmp.o headsmp.o smp-$(CONFIG_ARCH_SH73A0) += smp-sh73a0.o headsmp-scu.o platsmp-scu.o smp-$(CONFIG_ARCH_R8A7779) += smp-r8a7779.o headsmp-scu.o platsmp-scu.o +smp-$(CONFIG_ARCH_R8A7790) += smp-r8a7790.o platsmp-apmu.o +smp-$(CONFIG_ARCH_R8A7791) += smp-r8a7791.o platsmp-apmu.o smp-$(CONFIG_ARCH_EMEV2) += smp-emev2.o headsmp-scu.o platsmp-scu.o # IRQ objects @@ -48,21 +55,26 @@ obj-$(CONFIG_ARCH_R8A7740) += pm-r8a7740.o pm-rmobile.o obj-$(CONFIG_ARCH_R8A7779) += pm-r8a7779.o # Board objects +ifdef CONFIG_ARCH_SHMOBILE_MULTI +obj-$(CONFIG_MACH_KZM9D) += board-kzm9d-reference.o +else obj-$(CONFIG_MACH_APE6EVM) += board-ape6evm.o obj-$(CONFIG_MACH_APE6EVM_REFERENCE) += board-ape6evm-reference.o obj-$(CONFIG_MACH_MACKEREL) += board-mackerel.o obj-$(CONFIG_MACH_BOCKW) += board-bockw.o obj-$(CONFIG_MACH_BOCKW_REFERENCE) += board-bockw-reference.o +obj-$(CONFIG_MACH_GENMAI) += board-genmai.o obj-$(CONFIG_MACH_MARZEN) += board-marzen.o obj-$(CONFIG_MACH_MARZEN_REFERENCE) += board-marzen-reference.o obj-$(CONFIG_MACH_LAGER) += board-lager.o obj-$(CONFIG_MACH_LAGER_REFERENCE) += board-lager-reference.o obj-$(CONFIG_MACH_ARMADILLO800EVA) += board-armadillo800eva.o obj-$(CONFIG_MACH_ARMADILLO800EVA_REFERENCE) += board-armadillo800eva-reference.o +obj-$(CONFIG_MACH_KOELSCH) += board-koelsch.o obj-$(CONFIG_MACH_KZM9D) += board-kzm9d.o -obj-$(CONFIG_MACH_KZM9D_REFERENCE) += board-kzm9d-reference.o obj-$(CONFIG_MACH_KZM9G) += board-kzm9g.o obj-$(CONFIG_MACH_KZM9G_REFERENCE) += board-kzm9g-reference.o +endif # Framework support obj-$(CONFIG_SMP) += $(smp-y) diff --git a/arch/arm/mach-shmobile/Makefile.boot b/arch/arm/mach-shmobile/Makefile.boot index 6a504fe7d86c..391d72a5536c 100644 --- a/arch/arm/mach-shmobile/Makefile.boot +++ b/arch/arm/mach-shmobile/Makefile.boot @@ -6,8 +6,9 @@ loadaddr-$(CONFIG_MACH_ARMADILLO800EVA) += 0x40008000 loadaddr-$(CONFIG_MACH_ARMADILLO800EVA_REFERENCE) += 0x40008000 loadaddr-$(CONFIG_MACH_BOCKW) += 0x60008000 loadaddr-$(CONFIG_MACH_BOCKW_REFERENCE) += 0x60008000 +loadaddr-$(CONFIG_MACH_GENMAI) += 0x8008000 +loadaddr-$(CONFIG_MACH_KOELSCH) += 0x40008000 loadaddr-$(CONFIG_MACH_KZM9D) += 0x40008000 -loadaddr-$(CONFIG_MACH_KZM9D_REFERENCE) += 0x40008000 loadaddr-$(CONFIG_MACH_KZM9G) += 0x41008000 loadaddr-$(CONFIG_MACH_KZM9G_REFERENCE) += 0x41008000 loadaddr-$(CONFIG_MACH_LAGER) += 0x40008000 diff --git a/arch/arm/mach-shmobile/board-ape6evm-reference.c b/arch/arm/mach-shmobile/board-ape6evm-reference.c index a23fa714f7ac..3276afcf3cc9 100644 --- a/arch/arm/mach-shmobile/board-ape6evm-reference.c +++ b/arch/arm/mach-shmobile/board-ape6evm-reference.c @@ -57,7 +57,7 @@ static const char *ape6evm_boards_compat_dt[] __initdata = { }; DT_MACHINE_START(APE6EVM_DT, "ape6evm") - .init_early = r8a73a4_init_delay, + .init_early = r8a73a4_init_early, .init_machine = ape6evm_add_standard_devices, .dt_compat = ape6evm_boards_compat_dt, MACHINE_END diff --git a/arch/arm/mach-shmobile/board-ape6evm.c b/arch/arm/mach-shmobile/board-ape6evm.c index 24b87eea9da3..0fa068e30a30 100644 --- a/arch/arm/mach-shmobile/board-ape6evm.c +++ b/arch/arm/mach-shmobile/board-ape6evm.c @@ -86,7 +86,7 @@ static struct gpio_keys_button gpio_buttons[] = { GPIO_KEY(KEY_VOLUMEDOWN, 329, "S21"), }; -static struct __initdata gpio_keys_platform_data ape6evm_keys_pdata = { +static struct gpio_keys_platform_data ape6evm_keys_pdata __initdata = { .buttons = gpio_buttons, .nbuttons = ARRAY_SIZE(gpio_buttons), }; @@ -113,22 +113,58 @@ static const struct smsc911x_platform_config lan9220_data __initconst = { }; /* - * On APE6EVM power is supplied to MMCIF by a tps80032 regulator. For now we - * model a VDD supply to MMCIF, using a fixed 3.3V regulator. Also use the - * static power supply for SDHI0 and SDHI1, whereas SDHI0's VccQ is also - * supplied by the same tps80032 regulator and thus can also be adjusted - * dynamically. + * MMC0 power supplies: + * Both Vcc and VccQ to eMMC on APE6EVM are supplied by a tps80032 voltage + * regulator. Until support for it is added to this file we simulate the + * Vcc supply by a fixed always-on regulator */ -static struct regulator_consumer_supply fixed3v3_power_consumers[] = +static struct regulator_consumer_supply vcc_mmc0_consumers[] = { REGULATOR_SUPPLY("vmmc", "sh_mmcif.0"), +}; + +/* + * SDHI0 power supplies: + * Vcc to SDHI0 on APE6EVM is supplied by a GPIO-switchable regulator. VccQ is + * provided by the same tps80032 regulator as both MMC0 voltages - see comment + * above + */ +static struct regulator_consumer_supply vcc_sdhi0_consumers[] = +{ REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"), +}; + +static struct regulator_init_data vcc_sdhi0_init_data = { + .constraints = { + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(vcc_sdhi0_consumers), + .consumer_supplies = vcc_sdhi0_consumers, +}; + +static const struct fixed_voltage_config vcc_sdhi0_info __initconst = { + .supply_name = "SDHI0 Vcc", + .microvolts = 3300000, + .gpio = 76, + .enable_high = 1, + .init_data = &vcc_sdhi0_init_data, +}; + +/* + * SDHI1 power supplies: + * Vcc and VccQ to SDHI1 on APE6EVM are both fixed at 3.3V + */ +static struct regulator_consumer_supply vcc_sdhi1_consumers[] = +{ REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"), }; /* MMCIF */ static const struct sh_mmcif_plat_data mmcif0_pdata __initconst = { .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE, + .slave_id_tx = SHDMA_SLAVE_MMCIF0_TX, + .slave_id_rx = SHDMA_SLAVE_MMCIF0_RX, + .ccs_unsupported = true, }; static const struct resource mmcif0_resources[] __initconst = { @@ -215,14 +251,19 @@ static void __init ape6evm_add_standard_devices(void) platform_device_register_resndata(&platform_bus, "smsc911x", -1, lan9220_res, ARRAY_SIZE(lan9220_res), &lan9220_data, sizeof(lan9220_data)); - regulator_register_always_on(1, "fixed-3.3V", fixed3v3_power_consumers, - ARRAY_SIZE(fixed3v3_power_consumers), 3300000); + + regulator_register_always_on(1, "MMC0 Vcc", vcc_mmc0_consumers, + ARRAY_SIZE(vcc_mmc0_consumers), 2800000); platform_device_register_resndata(&platform_bus, "sh_mmcif", 0, mmcif0_resources, ARRAY_SIZE(mmcif0_resources), &mmcif0_pdata, sizeof(mmcif0_pdata)); + platform_device_register_data(&platform_bus, "reg-fixed-voltage", 2, + &vcc_sdhi0_info, sizeof(vcc_sdhi0_info)); platform_device_register_resndata(&platform_bus, "sh_mobile_sdhi", 0, sdhi0_resources, ARRAY_SIZE(sdhi0_resources), &sdhi0_pdata, sizeof(sdhi0_pdata)); + regulator_register_always_on(3, "SDHI1 Vcc", vcc_sdhi1_consumers, + ARRAY_SIZE(vcc_sdhi1_consumers), 3300000); platform_device_register_resndata(&platform_bus, "sh_mobile_sdhi", 1, sdhi1_resources, ARRAY_SIZE(sdhi1_resources), &sdhi1_pdata, sizeof(sdhi1_pdata)); @@ -240,7 +281,7 @@ static const char *ape6evm_boards_compat_dt[] __initdata = { }; DT_MACHINE_START(APE6EVM_DT, "ape6evm") - .init_early = r8a73a4_init_delay, + .init_early = r8a73a4_init_early, .init_machine = ape6evm_add_standard_devices, .dt_compat = ape6evm_boards_compat_dt, MACHINE_END diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c index 7f8f6076d360..958e3cbf0ac2 100644 --- a/arch/arm/mach-shmobile/board-armadillo800eva.c +++ b/arch/arm/mach-shmobile/board-armadillo800eva.c @@ -423,6 +423,7 @@ static struct platform_pwm_backlight_data pwm_backlight_data = { .max_brightness = 255, .dft_brightness = 255, .pwm_period_ns = 33333, /* 30kHz */ + .enable_gpio = -1, }; static struct platform_device pwm_backlight_device = { @@ -823,6 +824,7 @@ static struct sh_mmcif_plat_data sh_mmcif_plat = { .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE, + .ccs_unsupported = true, .slave_id_tx = SHDMA_SLAVE_MMCIF_TX, .slave_id_rx = SHDMA_SLAVE_MMCIF_RX, }; diff --git a/arch/arm/mach-shmobile/board-bockw-reference.c b/arch/arm/mach-shmobile/board-bockw-reference.c index 1a7c893e1a52..ae88fdad4b3a 100644 --- a/arch/arm/mach-shmobile/board-bockw-reference.c +++ b/arch/arm/mach-shmobile/board-bockw-reference.c @@ -36,15 +36,35 @@ static const struct pinctrl_map bockw_pinctrl_map[] = { "scif0_ctrl", "scif0"), }; +#define FPGA 0x18200000 +#define IRQ0MR 0x30 +#define COMCTLR 0x101c static void __init bockw_init(void) { + static void __iomem *fpga; + r8a7778_clock_init(); + r8a7778_init_irq_extpin_dt(1); pinctrl_register_mappings(bockw_pinctrl_map, ARRAY_SIZE(bockw_pinctrl_map)); r8a7778_pinmux_init(); r8a7778_add_dt_devices(); + fpga = ioremap_nocache(FPGA, SZ_1M); + if (fpga) { + /* + * CAUTION + * + * IRQ0/1 is cascaded interrupt from FPGA. + * it should be cared in the future + * Now, it is assuming IRQ0 was used only from SMSC. + */ + u16 val = ioread16(fpga + IRQ0MR); + val &= ~(1 << 4); /* enable SMSC911x */ + iowrite16(val, fpga + IRQ0MR); + } + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); } diff --git a/arch/arm/mach-shmobile/board-bockw.c b/arch/arm/mach-shmobile/board-bockw.c index 6b9faf3908f7..38611526fe9a 100644 --- a/arch/arm/mach-shmobile/board-bockw.c +++ b/arch/arm/mach-shmobile/board-bockw.c @@ -32,11 +32,19 @@ #include <linux/smsc911x.h> #include <linux/spi/spi.h> #include <linux/spi/flash.h> +#include <linux/usb/renesas_usbhs.h> #include <media/soc_camera.h> #include <mach/common.h> #include <mach/irqs.h> #include <mach/r8a7778.h> #include <asm/mach/arch.h> +#include <sound/rcar_snd.h> +#include <sound/simple_card.h> + +#define FPGA 0x18200000 +#define IRQ0MR 0x30 +#define COMCTLR 0x101c +static void __iomem *fpga; /* * CN9(Upper side) SCIF/RCAN selection @@ -63,6 +71,45 @@ * SW19 (MMC) 1 pin */ +/* + * SSI settings + * + * SW45: 1-4 side (SSI5 out, ROUT/LOUT CN19 Mid) + * SW46: 1101 (SSI6 Recorde) + * SW47: 1110 (SSI5 Playback) + * SW48: 11 (Recorde power) + * SW49: 1 (SSI slave mode) + * SW50: 1111 (SSI7, SSI8) + * SW51: 1111 (SSI3, SSI4) + * SW54: 1pin (ak4554 FPGA control) + * SW55: 1 (CLKB is 24.5760MHz) + * SW60: 1pin (ak4554 FPGA control) + * SW61: 3pin (use X11 clock) + * SW78: 3-6 (ak4642 connects I2C0) + * + * You can use sound as + * + * hw0: CN19: SSI56-AK4643 + * hw1: CN21: SSI3-AK4554(playback) + * hw2: CN21: SSI4-AK4554(capture) + * hw3: CN20: SSI7-AK4554(playback) + * hw4: CN20: SSI8-AK4554(capture) + * + * this command is required when playback on hw0. + * + * # amixer set "LINEOUT Mixer DACL" on + */ + +/* + * USB + * + * USB1 (CN29) can be Host/Function + * + * Host Func + * SW98 1 2 + * SW99 1 3 + */ + /* Dummy supplies, where voltage doesn't matter */ static struct regulator_consumer_supply dummy_supplies[] = { REGULATOR_SUPPLY("vddvario", "smsc911x"), @@ -81,16 +128,76 @@ static struct resource smsc911x_resources[] __initdata = { DEFINE_RES_IRQ(irq_pin(0)), /* IRQ 0 */ }; +#if IS_ENABLED(CONFIG_USB_RENESAS_USBHS_UDC) +/* + * When USB1 is Func + */ +static int usbhsf_get_id(struct platform_device *pdev) +{ + return USBHS_GADGET; +} + +#define SUSPMODE 0x102 +static int usbhsf_power_ctrl(struct platform_device *pdev, + void __iomem *base, int enable) +{ + enable = !!enable; + + r8a7778_usb_phy_power(enable); + + iowrite16(enable << 14, base + SUSPMODE); + + return 0; +} + +static struct resource usbhsf_resources[] __initdata = { + DEFINE_RES_MEM(0xffe60000, 0x110), + DEFINE_RES_IRQ(gic_iid(0x4f)), +}; + +static struct renesas_usbhs_platform_info usbhs_info __initdata = { + .platform_callback = { + .get_id = usbhsf_get_id, + .power_ctrl = usbhsf_power_ctrl, + }, + .driver_param = { + .buswait_bwait = 4, + }, +}; + +#define USB_PHY_SETTING {.port1_func = 1, .ovc_pin[1].active_high = 1,} +#define USB1_DEVICE "renesas_usbhs" +#define ADD_USB_FUNC_DEVICE_IF_POSSIBLE() \ + platform_device_register_resndata( \ + &platform_bus, "renesas_usbhs", -1, \ + usbhsf_resources, \ + ARRAY_SIZE(usbhsf_resources), \ + &usbhs_info, sizeof(struct renesas_usbhs_platform_info)) + +#else +/* + * When USB1 is Host + */ +#define USB_PHY_SETTING { } +#define USB1_DEVICE "ehci-platform" +#define ADD_USB_FUNC_DEVICE_IF_POSSIBLE() + +#endif + /* USB */ static struct resource usb_phy_resources[] __initdata = { DEFINE_RES_MEM(0xffe70800, 0x100), DEFINE_RES_MEM(0xffe76000, 0x100), }; -static struct rcar_phy_platform_data usb_phy_platform_data __initdata; +static struct rcar_phy_platform_data usb_phy_platform_data __initdata = + USB_PHY_SETTING; + /* SDHI */ static struct sh_mobile_sdhi_info sdhi0_info __initdata = { + .dma_slave_tx = HPBDMA_SLAVE_SDHI0_TX, + .dma_slave_rx = HPBDMA_SLAVE_SDHI0_RX, .tmio_caps = MMC_CAP_SD_HIGHSPEED, .tmio_ocr_mask = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34, .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT, @@ -101,6 +208,12 @@ static struct resource sdhi0_resources[] __initdata = { DEFINE_RES_IRQ(gic_iid(0x77)), }; +/* Ether */ +static struct resource ether_resources[] __initdata = { + DEFINE_RES_MEM(0xfde00000, 0x400), + DEFINE_RES_IRQ(gic_iid(0x89)), +}; + static struct sh_eth_plat_data ether_platform_data __initdata = { .phy = 0x01, .edmac_endian = EDMAC_LITTLE_ENDIAN, @@ -118,7 +231,9 @@ static struct sh_eth_plat_data ether_platform_data __initdata = { static struct i2c_board_info i2c0_devices[] = { { I2C_BOARD_INFO("rx8581", 0x51), - }, + }, { + I2C_BOARD_INFO("ak4643", 0x12), + } }; /* HSPI*/ @@ -162,10 +277,6 @@ static struct sh_mmcif_plat_data sh_mmcif_plat __initdata = { MMC_CAP_NEEDS_POLL, }; -static struct rcar_vin_platform_data vin_platform_data __initdata = { - .flags = RCAR_VIN_BT656, -}; - /* In the default configuration both decoders reside on I2C bus 0 */ #define BOCKW_CAMERA(idx) \ static struct i2c_board_info camera##idx##_info = { \ @@ -181,7 +292,237 @@ static struct soc_camera_link iclink##idx##_ml86v7667 __initdata = { \ BOCKW_CAMERA(0); BOCKW_CAMERA(1); +/* VIN */ +static struct rcar_vin_platform_data vin_platform_data __initdata = { + .flags = RCAR_VIN_BT656, +}; + +#define R8A7778_VIN(idx) \ +static struct resource vin##idx##_resources[] __initdata = { \ + DEFINE_RES_MEM(0xffc50000 + 0x1000 * (idx), 0x1000), \ + DEFINE_RES_IRQ(gic_iid(0x5a)), \ +}; \ + \ +static struct platform_device_info vin##idx##_info __initdata = { \ + .parent = &platform_bus, \ + .name = "r8a7778-vin", \ + .id = idx, \ + .res = vin##idx##_resources, \ + .num_res = ARRAY_SIZE(vin##idx##_resources), \ + .dma_mask = DMA_BIT_MASK(32), \ + .data = &vin_platform_data, \ + .size_data = sizeof(vin_platform_data), \ +} +R8A7778_VIN(0); +R8A7778_VIN(1); + +/* Sound */ +static struct resource rsnd_resources[] __initdata = { + [RSND_GEN1_SRU] = DEFINE_RES_MEM(0xffd90000, 0x1000), + [RSND_GEN1_SSI] = DEFINE_RES_MEM(0xffd91000, 0x1240), + [RSND_GEN1_ADG] = DEFINE_RES_MEM(0xfffe0000, 0x24), +}; + +static struct rsnd_ssi_platform_info rsnd_ssi[] = { + RSND_SSI_UNUSED, /* SSI 0 */ + RSND_SSI_UNUSED, /* SSI 1 */ + RSND_SSI_UNUSED, /* SSI 2 */ + RSND_SSI_SET(1, 0, gic_iid(0x85), RSND_SSI_PLAY), + RSND_SSI_SET(2, 0, gic_iid(0x85), RSND_SSI_CLK_PIN_SHARE | RSND_SSI_CLK_FROM_ADG), + RSND_SSI_SET(0, 0, gic_iid(0x86), RSND_SSI_PLAY), + RSND_SSI_SET(0, 0, gic_iid(0x86), 0), + RSND_SSI_SET(3, 0, gic_iid(0x86), RSND_SSI_PLAY), + RSND_SSI_SET(4, 0, gic_iid(0x86), RSND_SSI_CLK_PIN_SHARE | RSND_SSI_CLK_FROM_ADG), +}; + +static struct rsnd_scu_platform_info rsnd_scu[9] = { + /* no member at this point */ +}; + +enum { + AK4554_34 = 0, + AK4643_56, + AK4554_78, + SOUND_MAX, +}; + +static int rsnd_codec_power(int id, int enable) +{ + static int sound_user[SOUND_MAX] = {0, 0, 0}; + int *usr = NULL; + u32 bit; + + switch (id) { + case 3: + case 4: + usr = sound_user + AK4554_34; + bit = (1 << 10); + break; + case 5: + case 6: + usr = sound_user + AK4643_56; + bit = (1 << 6); + break; + case 7: + case 8: + usr = sound_user + AK4554_78; + bit = (1 << 7); + break; + } + + if (!usr) + return -EIO; + + if (enable) { + if (*usr == 0) { + u32 val = ioread16(fpga + COMCTLR); + val &= ~bit; + iowrite16(val, fpga + COMCTLR); + } + + (*usr)++; + } else { + if (*usr == 0) + return 0; + + (*usr)--; + + if (*usr == 0) { + u32 val = ioread16(fpga + COMCTLR); + val |= bit; + iowrite16(val, fpga + COMCTLR); + } + } + + return 0; +} + +static int rsnd_start(int id) +{ + return rsnd_codec_power(id, 1); +} + +static int rsnd_stop(int id) +{ + return rsnd_codec_power(id, 0); +} + +static struct rcar_snd_info rsnd_info = { + .flags = RSND_GEN1, + .ssi_info = rsnd_ssi, + .ssi_info_nr = ARRAY_SIZE(rsnd_ssi), + .scu_info = rsnd_scu, + .scu_info_nr = ARRAY_SIZE(rsnd_scu), + .start = rsnd_start, + .stop = rsnd_stop, +}; + +static struct asoc_simple_card_info rsnd_card_info[] = { + /* SSI5, SSI6 */ + { + .name = "AK4643", + .card = "SSI56-AK4643", + .codec = "ak4642-codec.0-0012", + .platform = "rcar_sound", + .daifmt = SND_SOC_DAIFMT_LEFT_J, + .cpu_dai = { + .name = "rsnd-dai.0", + .fmt = SND_SOC_DAIFMT_CBS_CFS, + }, + .codec_dai = { + .name = "ak4642-hifi", + .fmt = SND_SOC_DAIFMT_CBM_CFM, + .sysclk = 11289600, + }, + }, + /* SSI3 */ + { + .name = "AK4554", + .card = "SSI3-AK4554(playback)", + .codec = "ak4554-adc-dac.0", + .platform = "rcar_sound", + .cpu_dai = { + .name = "rsnd-dai.1", + .fmt = SND_SOC_DAIFMT_CBM_CFM | + SND_SOC_DAIFMT_RIGHT_J, + }, + .codec_dai = { + .name = "ak4554-hifi", + }, + }, + /* SSI4 */ + { + .name = "AK4554", + .card = "SSI4-AK4554(capture)", + .codec = "ak4554-adc-dac.0", + .platform = "rcar_sound", + .cpu_dai = { + .name = "rsnd-dai.2", + .fmt = SND_SOC_DAIFMT_CBM_CFM | + SND_SOC_DAIFMT_LEFT_J, + }, + .codec_dai = { + .name = "ak4554-hifi", + }, + }, + /* SSI7 */ + { + .name = "AK4554", + .card = "SSI7-AK4554(playback)", + .codec = "ak4554-adc-dac.1", + .platform = "rcar_sound", + .cpu_dai = { + .name = "rsnd-dai.3", + .fmt = SND_SOC_DAIFMT_CBM_CFM | + SND_SOC_DAIFMT_RIGHT_J, + }, + .codec_dai = { + .name = "ak4554-hifi", + }, + }, + /* SSI8 */ + { + .name = "AK4554", + .card = "SSI8-AK4554(capture)", + .codec = "ak4554-adc-dac.1", + .platform = "rcar_sound", + .cpu_dai = { + .name = "rsnd-dai.4", + .fmt = SND_SOC_DAIFMT_CBM_CFM | + SND_SOC_DAIFMT_LEFT_J, + }, + .codec_dai = { + .name = "ak4554-hifi", + }, + } +}; + static const struct pinctrl_map bockw_pinctrl_map[] = { + /* AUDIO */ + PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", + "audio_clk_a", "audio_clk"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", + "audio_clk_b", "audio_clk"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", + "ssi34_ctrl", "ssi"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", + "ssi3_data", "ssi"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", + "ssi4_data", "ssi"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", + "ssi5_ctrl", "ssi"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", + "ssi5_data", "ssi"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", + "ssi6_ctrl", "ssi"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", + "ssi6_data", "ssi"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", + "ssi78_ctrl", "ssi"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", + "ssi7_data", "ssi"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", + "ssi8_data", "ssi"), /* Ether */ PIN_MAP_MUX_GROUP_DEFAULT("r8a777x-ether", "pfc-r8a7778", "ether_rmii", "ether"), @@ -201,7 +542,7 @@ static const struct pinctrl_map bockw_pinctrl_map[] = { /* USB */ PIN_MAP_MUX_GROUP_DEFAULT("ehci-platform", "pfc-r8a7778", "usb0", "usb0"), - PIN_MAP_MUX_GROUP_DEFAULT("ehci-platform", "pfc-r8a7778", + PIN_MAP_MUX_GROUP_DEFAULT(USB1_DEVICE, "pfc-r8a7778", "usb1", "usb1"), /* SDHI0 */ PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7778", @@ -224,22 +565,28 @@ static const struct pinctrl_map bockw_pinctrl_map[] = { "vin1_data8", "vin1"), }; -#define FPGA 0x18200000 -#define IRQ0MR 0x30 #define PFC 0xfffc0000 #define PUPR4 0x110 static void __init bockw_init(void) { void __iomem *base; + struct clk *clk; + int i; r8a7778_clock_init(); r8a7778_init_irq_extpin(1); r8a7778_add_standard_devices(); - r8a7778_add_ether_device(ðer_platform_data); - r8a7778_add_vin_device(0, &vin_platform_data); + + platform_device_register_resndata(&platform_bus, "r8a777x-ether", -1, + ether_resources, + ARRAY_SIZE(ether_resources), + ðer_platform_data, + sizeof(ether_platform_data)); + + platform_device_register_full(&vin0_info); /* VIN1 has a pin conflict with Ether */ if (!IS_ENABLED(CONFIG_SH_ETH)) - r8a7778_add_vin_device(1, &vin_platform_data); + platform_device_register_full(&vin1_info); platform_device_register_data(&platform_bus, "soc-camera-pdrv", 0, &iclink0_ml86v7667, sizeof(iclink0_ml86v7667)); @@ -269,8 +616,8 @@ static void __init bockw_init(void) /* for SMSC */ - base = ioremap_nocache(FPGA, SZ_1M); - if (base) { + fpga = ioremap_nocache(FPGA, SZ_1M); + if (fpga) { /* * CAUTION * @@ -278,10 +625,9 @@ static void __init bockw_init(void) * it should be cared in the future * Now, it is assuming IRQ0 was used only from SMSC. */ - u16 val = ioread16(base + IRQ0MR); + u16 val = ioread16(fpga + IRQ0MR); val &= ~(1 << 4); /* enable SMSC911x */ - iowrite16(val, base + IRQ0MR); - iounmap(base); + iowrite16(val, fpga + IRQ0MR); regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); @@ -308,6 +654,42 @@ static void __init bockw_init(void) sdhi0_resources, ARRAY_SIZE(sdhi0_resources), &sdhi0_info, sizeof(struct sh_mobile_sdhi_info)); } + + /* for Audio */ + clk = clk_get(NULL, "audio_clk_b"); + clk_set_rate(clk, 24576000); + clk_put(clk); + rsnd_codec_power(5, 1); /* enable ak4642 */ + + platform_device_register_simple( + "ak4554-adc-dac", 0, NULL, 0); + + platform_device_register_simple( + "ak4554-adc-dac", 1, NULL, 0); + + platform_device_register_resndata( + &platform_bus, "rcar_sound", -1, + rsnd_resources, ARRAY_SIZE(rsnd_resources), + &rsnd_info, sizeof(rsnd_info)); + + for (i = 0; i < ARRAY_SIZE(rsnd_card_info); i++) { + struct platform_device_info cardinfo = { + .parent = &platform_bus, + .name = "asoc-simple-card", + .id = i, + .data = &rsnd_card_info[i], + .size_data = sizeof(struct asoc_simple_card_info), + .dma_mask = ~0, + }; + + platform_device_register_full(&cardinfo); + } +} + +static void __init bockw_init_late(void) +{ + r8a7778_init_late(); + ADD_USB_FUNC_DEVICE_IF_POSSIBLE(); } static const char *bockw_boards_compat_dt[] __initdata = { @@ -320,5 +702,5 @@ DT_MACHINE_START(BOCKW_DT, "bockw") .init_irq = r8a7778_init_irq_dt, .init_machine = bockw_init, .dt_compat = bockw_boards_compat_dt, - .init_late = r8a7778_init_late, + .init_late = bockw_init_late, MACHINE_END diff --git a/arch/arm/mach-shmobile/board-genmai.c b/arch/arm/mach-shmobile/board-genmai.c new file mode 100644 index 000000000000..3e92e3c62d4c --- /dev/null +++ b/arch/arm/mach-shmobile/board-genmai.c @@ -0,0 +1,43 @@ +/* + * Genmai board support + * + * Copyright (C) 2013 Renesas Solutions Corp. + * Copyright (C) 2013 Magnus Damm + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that 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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <linux/kernel.h> +#include <linux/platform_device.h> +#include <mach/common.h> +#include <mach/r7s72100.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +static void __init genmai_add_standard_devices(void) +{ + r7s72100_clock_init(); + r7s72100_add_dt_devices(); +} + +static const char * const genmai_boards_compat_dt[] __initconst = { + "renesas,genmai", + NULL, +}; + +DT_MACHINE_START(GENMAI_DT, "genmai") + .init_early = r7s72100_init_early, + .init_machine = genmai_add_standard_devices, + .dt_compat = genmai_boards_compat_dt, +MACHINE_END diff --git a/arch/arm/mach-shmobile/board-koelsch.c b/arch/arm/mach-shmobile/board-koelsch.c new file mode 100644 index 000000000000..ace1711a6cd8 --- /dev/null +++ b/arch/arm/mach-shmobile/board-koelsch.c @@ -0,0 +1,47 @@ +/* + * Koelsch board support + * + * Copyright (C) 2013 Renesas Electronics Corporation + * Copyright (C) 2013 Renesas Solutions Corp. + * Copyright (C) 2013 Magnus Damm + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that 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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <linux/kernel.h> +#include <linux/platform_device.h> +#include <mach/common.h> +#include <mach/r8a7791.h> +#include <mach/rcar-gen2.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +static void __init koelsch_add_standard_devices(void) +{ + r8a7791_clock_init(); + r8a7791_add_standard_devices(); +} + +static const char * const koelsch_boards_compat_dt[] __initconst = { + "renesas,koelsch", + NULL, +}; + +DT_MACHINE_START(KOELSCH_DT, "koelsch") + .smp = smp_ops(r8a7791_smp_ops), + .init_early = r8a7791_init_early, + .init_machine = koelsch_add_standard_devices, + .init_time = rcar_gen2_timer_init, + .dt_compat = koelsch_boards_compat_dt, +MACHINE_END diff --git a/arch/arm/mach-shmobile/board-kzm9d-reference.c b/arch/arm/mach-shmobile/board-kzm9d-reference.c index 8f8bb2fab076..054d8d5c8fc1 100644 --- a/arch/arm/mach-shmobile/board-kzm9d-reference.c +++ b/arch/arm/mach-shmobile/board-kzm9d-reference.c @@ -33,6 +33,7 @@ static void __init kzm9d_add_standard_devices(void) } static const char *kzm9d_boards_compat_dt[] __initdata = { + "renesas,kzm9d", "renesas,kzm9d-reference", NULL, }; diff --git a/arch/arm/mach-shmobile/board-kzm9g.c b/arch/arm/mach-shmobile/board-kzm9g.c index f1994968d303..fe689b7fdc9e 100644 --- a/arch/arm/mach-shmobile/board-kzm9g.c +++ b/arch/arm/mach-shmobile/board-kzm9g.c @@ -366,6 +366,7 @@ static struct resource sh_mmcif_resources[] = { static struct sh_mmcif_plat_data sh_mmcif_platdata = { .ocr = MMC_VDD_165_195, .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE, + .ccs_unsupported = true, .slave_id_tx = SHDMA_SLAVE_MMCIF_TX, .slave_id_rx = SHDMA_SLAVE_MMCIF_RX, }; diff --git a/arch/arm/mach-shmobile/board-lager-reference.c b/arch/arm/mach-shmobile/board-lager-reference.c index 9c316a1b2e32..1a1a4a888632 100644 --- a/arch/arm/mach-shmobile/board-lager-reference.c +++ b/arch/arm/mach-shmobile/board-lager-reference.c @@ -38,8 +38,9 @@ static const char *lager_boards_compat_dt[] __initdata = { }; DT_MACHINE_START(LAGER_DT, "lager") - .init_early = r8a7790_init_delay, + .smp = smp_ops(r8a7790_smp_ops), + .init_early = r8a7790_init_early, + .init_time = rcar_gen2_timer_init, .init_machine = lager_add_standard_devices, - .init_time = r8a7790_timer_init, .dt_compat = lager_boards_compat_dt, MACHINE_END diff --git a/arch/arm/mach-shmobile/board-lager.c b/arch/arm/mach-shmobile/board-lager.c index 5930af8d434f..a8d3ce646fb9 100644 --- a/arch/arm/mach-shmobile/board-lager.c +++ b/arch/arm/mach-shmobile/board-lager.c @@ -28,6 +28,7 @@ #include <linux/mmc/sh_mmcif.h> #include <linux/pinctrl/machine.h> #include <linux/platform_data/gpio-rcar.h> +#include <linux/platform_data/rcar-du.h> #include <linux/platform_device.h> #include <linux/phy.h> #include <linux/regulator/fixed.h> @@ -39,6 +40,62 @@ #include <asm/mach-types.h> #include <asm/mach/arch.h> +/* DU */ +static struct rcar_du_encoder_data lager_du_encoders[] = { + { + .type = RCAR_DU_ENCODER_VGA, + .output = RCAR_DU_OUTPUT_DPAD0, + }, { + .type = RCAR_DU_ENCODER_NONE, + .output = RCAR_DU_OUTPUT_LVDS1, + .connector.lvds.panel = { + .width_mm = 210, + .height_mm = 158, + .mode = { + .clock = 65000, + .hdisplay = 1024, + .hsync_start = 1048, + .hsync_end = 1184, + .htotal = 1344, + .vdisplay = 768, + .vsync_start = 771, + .vsync_end = 777, + .vtotal = 806, + .flags = 0, + }, + }, + }, +}; + +static const struct rcar_du_platform_data lager_du_pdata __initconst = { + .encoders = lager_du_encoders, + .num_encoders = ARRAY_SIZE(lager_du_encoders), +}; + +static const struct resource du_resources[] __initconst = { + DEFINE_RES_MEM(0xfeb00000, 0x70000), + DEFINE_RES_MEM_NAMED(0xfeb90000, 0x1c, "lvds.0"), + DEFINE_RES_MEM_NAMED(0xfeb94000, 0x1c, "lvds.1"), + DEFINE_RES_IRQ(gic_spi(256)), + DEFINE_RES_IRQ(gic_spi(268)), + DEFINE_RES_IRQ(gic_spi(269)), +}; + +static void __init lager_add_du_device(void) +{ + struct platform_device_info info = { + .name = "rcar-du-r8a7790", + .id = -1, + .res = du_resources, + .num_res = ARRAY_SIZE(du_resources), + .data = &lager_du_pdata, + .size_data = sizeof(lager_du_pdata), + .dma_mask = DMA_BIT_MASK(32), + }; + + platform_device_register_full(&info); +} + /* LEDS */ static struct gpio_led lager_leds[] = { { @@ -56,7 +113,7 @@ static struct gpio_led lager_leds[] = { }, }; -static __initdata struct gpio_led_platform_data lager_leds_pdata = { +static const struct gpio_led_platform_data lager_leds_pdata __initconst = { .leds = lager_leds, .num_leds = ARRAY_SIZE(lager_leds), }; @@ -72,7 +129,7 @@ static struct gpio_keys_button gpio_buttons[] = { GPIO_KEY(KEY_1, RCAR_GP_PIN(1, 14), "SW2-pin1"), }; -static __initdata struct gpio_keys_platform_data lager_keys_pdata = { +static const struct gpio_keys_platform_data lager_keys_pdata __initconst = { .buttons = gpio_buttons, .nbuttons = ARRAY_SIZE(gpio_buttons), }; @@ -84,29 +141,38 @@ static struct regulator_consumer_supply fixed3v3_power_consumers[] = }; /* MMCIF */ -static struct sh_mmcif_plat_data mmcif1_pdata __initdata = { +static const struct sh_mmcif_plat_data mmcif1_pdata __initconst = { .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE, + .clk_ctrl2_present = true, + .ccs_unsupported = true, }; -static struct resource mmcif1_resources[] __initdata = { +static const struct resource mmcif1_resources[] __initconst = { DEFINE_RES_MEM_NAMED(0xee220000, 0x80, "MMCIF1"), DEFINE_RES_IRQ(gic_spi(170)), }; /* Ether */ -static struct sh_eth_plat_data ether_pdata __initdata = { +static const struct sh_eth_plat_data ether_pdata __initconst = { .phy = 0x1, .edmac_endian = EDMAC_LITTLE_ENDIAN, .phy_interface = PHY_INTERFACE_MODE_RMII, .ether_link_active_low = 1, }; -static struct resource ether_resources[] __initdata = { +static const struct resource ether_resources[] __initconst = { DEFINE_RES_MEM(0xee700000, 0x400), DEFINE_RES_IRQ(gic_spi(162)), }; static const struct pinctrl_map lager_pinctrl_map[] = { + /* DU (CN10: ARGB0, CN13: LVDS) */ + PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7790", "pfc-r8a7790", + "du_rgb666", "du"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7790", "pfc-r8a7790", + "du_sync_1", "du"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7790", "pfc-r8a7790", + "du_clk_out_0", "du"), /* SCIF0 (CN19: DEBUG SERIAL0) */ PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.6", "pfc-r8a7790", "scif0_data", "scif0"), @@ -154,6 +220,8 @@ static void __init lager_add_standard_devices(void) ether_resources, ARRAY_SIZE(ether_resources), ðer_pdata, sizeof(ether_pdata)); + + lager_add_du_device(); } /* @@ -180,14 +248,15 @@ static void __init lager_init(void) phy_register_fixup_for_id("r8a7790-ether-ff:01", lager_ksz8041_fixup); } -static const char *lager_boards_compat_dt[] __initdata = { +static const char * const lager_boards_compat_dt[] __initconst = { "renesas,lager", NULL, }; DT_MACHINE_START(LAGER_DT, "lager") - .init_early = r8a7790_init_delay, - .init_time = r8a7790_timer_init, + .smp = smp_ops(r8a7790_smp_ops), + .init_early = r8a7790_init_early, + .init_time = rcar_gen2_timer_init, .init_machine = lager_init, .dt_compat = lager_boards_compat_dt, MACHINE_END diff --git a/arch/arm/mach-shmobile/board-marzen-reference.c b/arch/arm/mach-shmobile/board-marzen-reference.c index 3f4250a2d4eb..2773936bf7dc 100644 --- a/arch/arm/mach-shmobile/board-marzen-reference.c +++ b/arch/arm/mach-shmobile/board-marzen-reference.c @@ -28,6 +28,7 @@ static void __init marzen_init(void) { r8a7779_add_standard_devices_dt(); + r8a7779_init_irq_extpin_dt(1); /* IRQ1 as individual interrupt */ } static const char *marzen_boards_compat_dt[] __initdata = { diff --git a/arch/arm/mach-shmobile/board-marzen.c b/arch/arm/mach-shmobile/board-marzen.c index 3f5044fda4e3..da1352f5f71b 100644 --- a/arch/arm/mach-shmobile/board-marzen.c +++ b/arch/arm/mach-shmobile/board-marzen.c @@ -30,6 +30,7 @@ #include <linux/dma-mapping.h> #include <linux/pinctrl/machine.h> #include <linux/platform_data/gpio-rcar.h> +#include <linux/platform_data/rcar-du.h> #include <linux/platform_data/usb-rcar-phy.h> #include <linux/regulator/fixed.h> #include <linux/regulator/machine.h> @@ -124,6 +125,8 @@ static struct resource sdhi0_resources[] = { }; static struct sh_mobile_sdhi_info sdhi0_platform_data = { + .dma_slave_tx = HPBDMA_SLAVE_SDHI0_TX, + .dma_slave_rx = HPBDMA_SLAVE_SDHI0_RX, .tmio_flags = TMIO_MMC_WRPROTECT_DISABLE | TMIO_MMC_HAS_IDLE_WAIT, .tmio_caps = MMC_CAP_SD_HIGHSPEED, }; @@ -169,6 +172,63 @@ static struct platform_device hspi_device = { .num_resources = ARRAY_SIZE(hspi_resources), }; +/* + * DU + * + * The panel only specifies the [hv]display and [hv]total values. The position + * and width of the sync pulses don't matter, they're copied from VESA timings. + */ +static struct rcar_du_encoder_data du_encoders[] = { + { + .type = RCAR_DU_ENCODER_VGA, + .output = RCAR_DU_OUTPUT_DPAD0, + }, { + .type = RCAR_DU_ENCODER_LVDS, + .output = RCAR_DU_OUTPUT_DPAD1, + .connector.lvds.panel = { + .width_mm = 210, + .height_mm = 158, + .mode = { + .clock = 65000, + .hdisplay = 1024, + .hsync_start = 1048, + .hsync_end = 1184, + .htotal = 1344, + .vdisplay = 768, + .vsync_start = 771, + .vsync_end = 777, + .vtotal = 806, + .flags = 0, + }, + }, + }, +}; + +static const struct rcar_du_platform_data du_pdata __initconst = { + .encoders = du_encoders, + .num_encoders = ARRAY_SIZE(du_encoders), +}; + +static const struct resource du_resources[] __initconst = { + DEFINE_RES_MEM(0xfff80000, 0x40000), + DEFINE_RES_IRQ(gic_iid(0x3f)), +}; + +static void __init marzen_add_du_device(void) +{ + struct platform_device_info info = { + .name = "rcar-du-r8a7779", + .id = -1, + .res = du_resources, + .num_res = ARRAY_SIZE(du_resources), + .data = &du_pdata, + .size_data = sizeof(du_pdata), + .dma_mask = DMA_BIT_MASK(32), + }; + + platform_device_register_full(&info); +} + /* LEDS */ static struct gpio_led marzen_leds[] = { { @@ -237,6 +297,19 @@ static struct platform_device *marzen_devices[] __initdata = { }; static const struct pinctrl_map marzen_pinctrl_map[] = { + /* DU (CN10: ARGB0, CN13: LVDS) */ + PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7779", "pfc-r8a7779", + "du0_rgb888", "du0"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7779", "pfc-r8a7779", + "du0_sync_1", "du0"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7779", "pfc-r8a7779", + "du0_clk_out_0", "du0"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7779", "pfc-r8a7779", + "du1_rgb666", "du1"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7779", "pfc-r8a7779", + "du1_sync_1", "du1"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7779", "pfc-r8a7779", + "du1_clk_out", "du1"), /* HSPI0 */ PIN_MAP_MUX_GROUP_DEFAULT("sh-hspi.0", "pfc-r8a7779", "hspi0", "hspi0"), @@ -297,6 +370,7 @@ static void __init marzen_init(void) r8a7779_add_vin_device(1, &vin_platform_data); r8a7779_add_vin_device(3, &vin_platform_data); platform_add_devices(marzen_devices, ARRAY_SIZE(marzen_devices)); + marzen_add_du_device(); } static const char *marzen_boards_compat_dt[] __initdata = { diff --git a/arch/arm/mach-shmobile/clock-r7s72100.c b/arch/arm/mach-shmobile/clock-r7s72100.c new file mode 100644 index 000000000000..4aba20ca127e --- /dev/null +++ b/arch/arm/mach-shmobile/clock-r7s72100.c @@ -0,0 +1,202 @@ +/* + * r7a72100 clock framework support + * + * Copyright (C) 2013 Renesas Solutions Corp. + * Copyright (C) 2012 Phil Edworthy + * Copyright (C) 2011 Magnus Damm + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that 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. + */ +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/io.h> +#include <linux/sh_clk.h> +#include <linux/clkdev.h> +#include <mach/common.h> +#include <mach/r7s72100.h> + +/* registers */ +#define FRQCR 0xfcfe0010 +#define FRQCR2 0xfcfe0014 +#define STBCR3 0xfcfe0420 +#define STBCR4 0xfcfe0424 + +#define PLL_RATE 30 + +static struct clk_mapping cpg_mapping = { + .phys = 0xfcfe0000, + .len = 0x1000, +}; + +/* Fixed 32 KHz root clock for RTC */ +static struct clk r_clk = { + .rate = 32768, +}; + +/* + * Default rate for the root input clock, reset this with clk_set_rate() + * from the platform code. + */ +static struct clk extal_clk = { + .rate = 13330000, + .mapping = &cpg_mapping, +}; + +static unsigned long pll_recalc(struct clk *clk) +{ + return clk->parent->rate * PLL_RATE; +} + +static struct sh_clk_ops pll_clk_ops = { + .recalc = pll_recalc, +}; + +static struct clk pll_clk = { + .ops = &pll_clk_ops, + .parent = &extal_clk, + .flags = CLK_ENABLE_ON_INIT, +}; + +static unsigned long bus_recalc(struct clk *clk) +{ + return clk->parent->rate * 2 / 3; +} + +static struct sh_clk_ops bus_clk_ops = { + .recalc = bus_recalc, +}; + +static struct clk bus_clk = { + .ops = &bus_clk_ops, + .parent = &pll_clk, + .flags = CLK_ENABLE_ON_INIT, +}; + +static unsigned long peripheral0_recalc(struct clk *clk) +{ + return clk->parent->rate / 12; +} + +static struct sh_clk_ops peripheral0_clk_ops = { + .recalc = peripheral0_recalc, +}; + +static struct clk peripheral0_clk = { + .ops = &peripheral0_clk_ops, + .parent = &pll_clk, + .flags = CLK_ENABLE_ON_INIT, +}; + +static unsigned long peripheral1_recalc(struct clk *clk) +{ + return clk->parent->rate / 6; +} + +static struct sh_clk_ops peripheral1_clk_ops = { + .recalc = peripheral1_recalc, +}; + +static struct clk peripheral1_clk = { + .ops = &peripheral1_clk_ops, + .parent = &pll_clk, + .flags = CLK_ENABLE_ON_INIT, +}; + +struct clk *main_clks[] = { + &r_clk, + &extal_clk, + &pll_clk, + &bus_clk, + &peripheral0_clk, + &peripheral1_clk, +}; + +static int div2[] = { 1, 3, 0, 3 }; /* 1, 2/3, reserve, 1/3 */ +static int multipliers[] = { 1, 2, 1, 1 }; + +static struct clk_div_mult_table div4_div_mult_table = { + .divisors = div2, + .nr_divisors = ARRAY_SIZE(div2), + .multipliers = multipliers, + .nr_multipliers = ARRAY_SIZE(multipliers), +}; + +static struct clk_div4_table div4_table = { + .div_mult_table = &div4_div_mult_table, +}; + +enum { DIV4_I, + DIV4_NR }; + +#define DIV4(_reg, _bit, _mask, _flags) \ + SH_CLK_DIV4(&pll_clk, _reg, _bit, _mask, _flags) + +/* The mask field specifies the div2 entries that are valid */ +struct clk div4_clks[DIV4_NR] = { + [DIV4_I] = DIV4(FRQCR, 8, 0xB, CLK_ENABLE_REG_16BIT + | CLK_ENABLE_ON_INIT), +}; + +enum { MSTP47, MSTP46, MSTP45, MSTP44, MSTP43, MSTP42, MSTP41, MSTP40, + MSTP33, MSTP_NR }; + +static struct clk mstp_clks[MSTP_NR] = { + [MSTP47] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 7, 0), /* SCIF0 */ + [MSTP46] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 6, 0), /* SCIF1 */ + [MSTP45] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 5, 0), /* SCIF2 */ + [MSTP44] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 4, 0), /* SCIF3 */ + [MSTP43] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 3, 0), /* SCIF4 */ + [MSTP42] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 2, 0), /* SCIF5 */ + [MSTP41] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 1, 0), /* SCIF6 */ + [MSTP40] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 0, 0), /* SCIF7 */ + [MSTP33] = SH_CLK_MSTP8(&peripheral0_clk, STBCR3, 3, 0), /* MTU2 */ +}; + +static struct clk_lookup lookups[] = { + /* main clocks */ + CLKDEV_CON_ID("rclk", &r_clk), + CLKDEV_CON_ID("extal", &extal_clk), + CLKDEV_CON_ID("pll_clk", &pll_clk), + CLKDEV_CON_ID("peripheral_clk", &peripheral1_clk), + + /* DIV4 clocks */ + CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]), + + /* MSTP clocks */ + CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP47]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[MSTP46]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[MSTP45]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.3", &mstp_clks[MSTP44]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.4", &mstp_clks[MSTP43]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.5", &mstp_clks[MSTP42]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.6", &mstp_clks[MSTP41]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.7", &mstp_clks[MSTP40]), +}; + +void __init r7s72100_clock_init(void) +{ + int k, ret = 0; + + for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++) + ret = clk_register(main_clks[k]); + + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); + + if (!ret) + ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table); + + if (!ret) + ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); + + if (!ret) + shmobile_clk_init(); + else + panic("failed to setup rza1 clocks\n"); +} diff --git a/arch/arm/mach-shmobile/clock-r8a73a4.c b/arch/arm/mach-shmobile/clock-r8a73a4.c index 5bd2e851e3c7..571409b611d3 100644 --- a/arch/arm/mach-shmobile/clock-r8a73a4.c +++ b/arch/arm/mach-shmobile/clock-r8a73a4.c @@ -504,7 +504,7 @@ static struct clk div6_clks[DIV6_NR] = { /* MSTP */ enum { - MSTP217, MSTP216, MSTP207, MSTP206, MSTP204, MSTP203, + MSTP218, MSTP217, MSTP216, MSTP207, MSTP206, MSTP204, MSTP203, MSTP329, MSTP323, MSTP318, MSTP317, MSTP316, MSTP315, MSTP314, MSTP313, MSTP312, MSTP305, MSTP300, MSTP411, MSTP410, MSTP409, @@ -519,6 +519,7 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP207] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 7, 0), /* SCIFB1 */ [MSTP216] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 16, 0), /* SCIFB2 */ [MSTP217] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 17, 0), /* SCIFB3 */ + [MSTP218] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* DMAC */ [MSTP300] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 0, 0), /* IIC2 */ [MSTP305] = SH_CLK_MSTP32(&div6_clks[DIV6_MMC1],SMSTPCR3, 5, 0), /* MMCIF1 */ [MSTP312] = SH_CLK_MSTP32(&div6_clks[DIV6_SDHI2],SMSTPCR3, 12, 0), /* SDHI2 */ @@ -578,6 +579,8 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP207]), CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP216]), CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP217]), + CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), + CLKDEV_DEV_ID("e6700020.dma-controller", &mstp_clks[MSTP218]), CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]), CLKDEV_DEV_ID("e6520000.i2c", &mstp_clks[MSTP300]), CLKDEV_DEV_ID("sh_mmcif.1", &mstp_clks[MSTP305]), diff --git a/arch/arm/mach-shmobile/clock-r8a7778.c b/arch/arm/mach-shmobile/clock-r8a7778.c index c4bf2d8fb111..fb6af83858e3 100644 --- a/arch/arm/mach-shmobile/clock-r8a7778.c +++ b/arch/arm/mach-shmobile/clock-r8a7778.c @@ -69,6 +69,15 @@ static struct clk extal_clk = { .mapping = &cpg_mapping, }; +static struct clk audio_clk_a = { +}; + +static struct clk audio_clk_b = { +}; + +static struct clk audio_clk_c = { +}; + /* * clock ratio of these clock will be updated * on r8a7778_clock_init() @@ -100,18 +109,23 @@ static struct clk *main_clks[] = { &p_clk, &g_clk, &z_clk, + &audio_clk_a, + &audio_clk_b, + &audio_clk_c, }; enum { MSTP331, MSTP323, MSTP322, MSTP321, + MSTP311, MSTP310, + MSTP309, MSTP308, MSTP307, MSTP114, MSTP110, MSTP109, MSTP100, MSTP030, MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021, - MSTP016, MSTP015, - MSTP007, + MSTP016, MSTP015, MSTP012, MSTP011, MSTP010, + MSTP009, MSTP008, MSTP007, MSTP_NR }; static struct clk mstp_clks[MSTP_NR] = { @@ -119,6 +133,11 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP323] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 23, 0), /* SDHI0 */ [MSTP322] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 22, 0), /* SDHI1 */ [MSTP321] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 21, 0), /* SDHI2 */ + [MSTP311] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 11, 0), /* SSI4 */ + [MSTP310] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 10, 0), /* SSI5 */ + [MSTP309] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 9, 0), /* SSI6 */ + [MSTP308] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 8, 0), /* SSI7 */ + [MSTP307] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 7, 0), /* SSI8 */ [MSTP114] = SH_CLK_MSTP32(&p_clk, MSTPCR1, 14, 0), /* Ether */ [MSTP110] = SH_CLK_MSTP32(&s_clk, MSTPCR1, 10, 0), /* VIN0 */ [MSTP109] = SH_CLK_MSTP32(&s_clk, MSTPCR1, 9, 0), /* VIN1 */ @@ -135,11 +154,20 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP021] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 21, 0), /* SCIF5 */ [MSTP016] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 16, 0), /* TMU0 */ [MSTP015] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 15, 0), /* TMU1 */ + [MSTP012] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 12, 0), /* SSI0 */ + [MSTP011] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 11, 0), /* SSI1 */ + [MSTP010] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 10, 0), /* SSI2 */ + [MSTP009] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 9, 0), /* SSI3 */ + [MSTP008] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 8, 0), /* SRU */ [MSTP007] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 7, 0), /* HSPI */ }; static struct clk_lookup lookups[] = { /* main */ + CLKDEV_CON_ID("audio_clk_a", &audio_clk_a), + CLKDEV_CON_ID("audio_clk_b", &audio_clk_b), + CLKDEV_CON_ID("audio_clk_c", &audio_clk_c), + CLKDEV_CON_ID("audio_clk_internal", &s1_clk), CLKDEV_CON_ID("shyway_clk", &s_clk), CLKDEV_CON_ID("peripheral_clk", &p_clk), @@ -153,6 +181,7 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("r8a7778-vin.1", &mstp_clks[MSTP109]), /* VIN1 */ CLKDEV_DEV_ID("ehci-platform", &mstp_clks[MSTP100]), /* USB EHCI port0/1 */ CLKDEV_DEV_ID("ohci-platform", &mstp_clks[MSTP100]), /* USB OHCI port0/1 */ + CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP100]), /* USB FUNC */ CLKDEV_DEV_ID("i2c-rcar.0", &mstp_clks[MSTP030]), /* I2C0 */ CLKDEV_DEV_ID("i2c-rcar.1", &mstp_clks[MSTP029]), /* I2C1 */ CLKDEV_DEV_ID("i2c-rcar.2", &mstp_clks[MSTP028]), /* I2C2 */ @@ -168,6 +197,17 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("sh-hspi.0", &mstp_clks[MSTP007]), /* HSPI0 */ CLKDEV_DEV_ID("sh-hspi.1", &mstp_clks[MSTP007]), /* HSPI1 */ CLKDEV_DEV_ID("sh-hspi.2", &mstp_clks[MSTP007]), /* HSPI2 */ + CLKDEV_DEV_ID("rcar_sound", &mstp_clks[MSTP008]), /* SRU */ + + CLKDEV_ICK_ID("ssi.0", "rcar_sound", &mstp_clks[MSTP012]), + CLKDEV_ICK_ID("ssi.1", "rcar_sound", &mstp_clks[MSTP011]), + CLKDEV_ICK_ID("ssi.2", "rcar_sound", &mstp_clks[MSTP010]), + CLKDEV_ICK_ID("ssi.3", "rcar_sound", &mstp_clks[MSTP009]), + CLKDEV_ICK_ID("ssi.4", "rcar_sound", &mstp_clks[MSTP311]), + CLKDEV_ICK_ID("ssi.5", "rcar_sound", &mstp_clks[MSTP310]), + CLKDEV_ICK_ID("ssi.6", "rcar_sound", &mstp_clks[MSTP309]), + CLKDEV_ICK_ID("ssi.7", "rcar_sound", &mstp_clks[MSTP308]), + CLKDEV_ICK_ID("ssi.8", "rcar_sound", &mstp_clks[MSTP307]), }; void __init r8a7778_clock_init(void) diff --git a/arch/arm/mach-shmobile/clock-r8a7779.c b/arch/arm/mach-shmobile/clock-r8a7779.c index bd6ad922eb7e..1f7080fab0a5 100644 --- a/arch/arm/mach-shmobile/clock-r8a7779.c +++ b/arch/arm/mach-shmobile/clock-r8a7779.c @@ -200,7 +200,7 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP322]), /* SDHI1 */ CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP321]), /* SDHI2 */ CLKDEV_DEV_ID("sh_mobile_sdhi.3", &mstp_clks[MSTP320]), /* SDHI3 */ - CLKDEV_DEV_ID("rcar-du.0", &mstp_clks[MSTP103]), /* DU */ + CLKDEV_DEV_ID("rcar-du-r8a7779", &mstp_clks[MSTP103]), /* DU */ }; void __init r8a7779_clock_init(void) diff --git a/arch/arm/mach-shmobile/clock-r8a7790.c b/arch/arm/mach-shmobile/clock-r8a7790.c index fc36d3db0b4d..a64f965c7da1 100644 --- a/arch/arm/mach-shmobile/clock-r8a7790.c +++ b/arch/arm/mach-shmobile/clock-r8a7790.c @@ -52,6 +52,7 @@ #define SMSTPCR5 0xe6150144 #define SMSTPCR7 0xe615014c #define SMSTPCR8 0xe6150990 +#define SMSTPCR9 0xe6150994 #define SDCKCR 0xE6150074 #define SD2CKCR 0xE6150078 @@ -181,8 +182,9 @@ static struct clk div6_clks[DIV6_NR] = { /* MSTP */ enum { + MSTP931, MSTP930, MSTP929, MSTP928, MSTP813, - MSTP721, MSTP720, + MSTP726, MSTP725, MSTP724, MSTP723, MSTP722, MSTP721, MSTP720, MSTP717, MSTP716, MSTP522, MSTP315, MSTP314, MSTP313, MSTP312, MSTP311, MSTP305, MSTP304, @@ -192,7 +194,16 @@ enum { }; static struct clk mstp_clks[MSTP_NR] = { + [MSTP931] = SH_CLK_MSTP32(&hp_clk, SMSTPCR9, 31, 0), /* I2C0 */ + [MSTP930] = SH_CLK_MSTP32(&hp_clk, SMSTPCR9, 30, 0), /* I2C1 */ + [MSTP929] = SH_CLK_MSTP32(&hp_clk, SMSTPCR9, 29, 0), /* I2C2 */ + [MSTP928] = SH_CLK_MSTP32(&hp_clk, SMSTPCR9, 28, 0), /* I2C3 */ [MSTP813] = SH_CLK_MSTP32(&p_clk, SMSTPCR8, 13, 0), /* Ether */ + [MSTP726] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 26, 0), /* LVDS0 */ + [MSTP725] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 25, 0), /* LVDS1 */ + [MSTP724] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 24, 0), /* DU0 */ + [MSTP723] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 23, 0), /* DU1 */ + [MSTP722] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 22, 0), /* DU2 */ [MSTP721] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 21, 0), /* SCIF0 */ [MSTP720] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 20, 0), /* SCIF1 */ [MSTP717] = SH_CLK_MSTP32(&zs_clk, SMSTPCR7, 17, 0), /* HSCIF0 */ @@ -251,6 +262,11 @@ static struct clk_lookup lookups[] = { CLKDEV_CON_ID("ssprs", &div6_clks[DIV6_SSPRS]), /* MSTP */ + CLKDEV_ICK_ID("lvds.0", "rcar-du-r8a7790", &mstp_clks[MSTP726]), + CLKDEV_ICK_ID("lvds.1", "rcar-du-r8a7790", &mstp_clks[MSTP725]), + CLKDEV_ICK_ID("du.0", "rcar-du-r8a7790", &mstp_clks[MSTP724]), + CLKDEV_ICK_ID("du.1", "rcar-du-r8a7790", &mstp_clks[MSTP723]), + CLKDEV_ICK_ID("du.2", "rcar-du-r8a7790", &mstp_clks[MSTP722]), CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP206]), @@ -261,6 +277,10 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP720]), CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP717]), CLKDEV_DEV_ID("sh-sci.9", &mstp_clks[MSTP716]), + CLKDEV_DEV_ID("e6508000.i2c", &mstp_clks[MSTP931]), + CLKDEV_DEV_ID("e6518000.i2c", &mstp_clks[MSTP930]), + CLKDEV_DEV_ID("e6530000.i2c", &mstp_clks[MSTP929]), + CLKDEV_DEV_ID("e6540000.i2c", &mstp_clks[MSTP928]), CLKDEV_DEV_ID("r8a7790-ether", &mstp_clks[MSTP813]), CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]), CLKDEV_DEV_ID("ee200000.mmcif", &mstp_clks[MSTP315]), @@ -290,7 +310,7 @@ static struct clk_lookup lookups[] = { void __init r8a7790_clock_init(void) { - u32 mode = r8a7790_read_mode_pins(); + u32 mode = rcar_gen2_read_mode_pins(); int k, ret = 0; switch (mode & (MD(14) | MD(13))) { diff --git a/arch/arm/mach-shmobile/clock-r8a7791.c b/arch/arm/mach-shmobile/clock-r8a7791.c new file mode 100644 index 000000000000..c9a26f16ce5b --- /dev/null +++ b/arch/arm/mach-shmobile/clock-r8a7791.c @@ -0,0 +1,237 @@ +/* + * r8a7791 clock framework support + * + * Copyright (C) 2013 Renesas Electronics Corporation + * Copyright (C) 2013 Renesas Solutions Corp. + * Copyright (C) 2013 Magnus Damm + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that 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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include <linux/init.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/sh_clk.h> +#include <linux/clkdev.h> +#include <mach/clock.h> +#include <mach/common.h> + +/* + * MD EXTAL PLL0 PLL1 PLL3 + * 14 13 19 (MHz) *1 *1 + *--------------------------------------------------- + * 0 0 0 15 x 1 x172/2 x208/2 x106 + * 0 0 1 15 x 1 x172/2 x208/2 x88 + * 0 1 0 20 x 1 x130/2 x156/2 x80 + * 0 1 1 20 x 1 x130/2 x156/2 x66 + * 1 0 0 26 / 2 x200/2 x240/2 x122 + * 1 0 1 26 / 2 x200/2 x240/2 x102 + * 1 1 0 30 / 2 x172/2 x208/2 x106 + * 1 1 1 30 / 2 x172/2 x208/2 x88 + * + * *1 : Table 7.6 indicates VCO ouput (PLLx = VCO/2) + * see "p1 / 2" on R8A7791_CLOCK_ROOT() below + */ + +#define MD(nr) (1 << nr) + +#define CPG_BASE 0xe6150000 +#define CPG_LEN 0x1000 + +#define SMSTPCR0 0xE6150130 +#define SMSTPCR1 0xE6150134 +#define SMSTPCR2 0xe6150138 +#define SMSTPCR3 0xE615013C +#define SMSTPCR5 0xE6150144 +#define SMSTPCR7 0xe615014c +#define SMSTPCR8 0xE6150990 +#define SMSTPCR9 0xE6150994 +#define SMSTPCR10 0xE6150998 +#define SMSTPCR11 0xE615099C + +#define MODEMR 0xE6160060 +#define SDCKCR 0xE6150074 +#define SD2CKCR 0xE6150078 +#define SD3CKCR 0xE615007C +#define MMC0CKCR 0xE6150240 +#define MMC1CKCR 0xE6150244 +#define SSPCKCR 0xE6150248 +#define SSPRSCKCR 0xE615024C + +static struct clk_mapping cpg_mapping = { + .phys = CPG_BASE, + .len = CPG_LEN, +}; + +static struct clk extal_clk = { + /* .rate will be updated on r8a7791_clock_init() */ + .mapping = &cpg_mapping, +}; + +static struct sh_clk_ops followparent_clk_ops = { + .recalc = followparent_recalc, +}; + +static struct clk main_clk = { + /* .parent will be set r8a73a4_clock_init */ + .ops = &followparent_clk_ops, +}; + +/* + * clock ratio of these clock will be updated + * on r8a7791_clock_init() + */ +SH_FIXED_RATIO_CLK_SET(pll1_clk, main_clk, 1, 1); +SH_FIXED_RATIO_CLK_SET(pll3_clk, main_clk, 1, 1); + +/* fixed ratio clock */ +SH_FIXED_RATIO_CLK_SET(extal_div2_clk, extal_clk, 1, 2); +SH_FIXED_RATIO_CLK_SET(cp_clk, extal_clk, 1, 2); + +SH_FIXED_RATIO_CLK_SET(pll1_div2_clk, pll1_clk, 1, 2); +SH_FIXED_RATIO_CLK_SET(hp_clk, pll1_clk, 1, 12); +SH_FIXED_RATIO_CLK_SET(p_clk, pll1_clk, 1, 24); +SH_FIXED_RATIO_CLK_SET(rclk_clk, pll1_clk, 1, (48 * 1024)); +SH_FIXED_RATIO_CLK_SET(mp_clk, pll1_div2_clk, 1, 15); + +static struct clk *main_clks[] = { + &extal_clk, + &extal_div2_clk, + &main_clk, + &pll1_clk, + &pll1_div2_clk, + &pll3_clk, + &hp_clk, + &p_clk, + &rclk_clk, + &mp_clk, + &cp_clk, +}; + +/* MSTP */ +enum { + MSTP721, MSTP720, + MSTP719, MSTP718, MSTP715, MSTP714, + MSTP216, MSTP207, MSTP206, + MSTP204, MSTP203, MSTP202, MSTP1105, MSTP1106, MSTP1107, + MSTP124, + MSTP_NR +}; + +static struct clk mstp_clks[MSTP_NR] = { + [MSTP721] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 21, 0), /* SCIF0 */ + [MSTP720] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 20, 0), /* SCIF1 */ + [MSTP719] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 19, 0), /* SCIF2 */ + [MSTP718] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 18, 0), /* SCIF3 */ + [MSTP715] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 15, 0), /* SCIF4 */ + [MSTP714] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 14, 0), /* SCIF5 */ + [MSTP216] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 16, 0), /* SCIFB2 */ + [MSTP207] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 7, 0), /* SCIFB1 */ + [MSTP206] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 6, 0), /* SCIFB0 */ + [MSTP204] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 4, 0), /* SCIFA0 */ + [MSTP203] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 3, 0), /* SCIFA1 */ + [MSTP202] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 2, 0), /* SCIFA2 */ + [MSTP1105] = SH_CLK_MSTP32(&mp_clk, SMSTPCR11, 5, 0), /* SCIFA3 */ + [MSTP1106] = SH_CLK_MSTP32(&mp_clk, SMSTPCR11, 6, 0), /* SCIFA4 */ + [MSTP1107] = SH_CLK_MSTP32(&mp_clk, SMSTPCR11, 7, 0), /* SCIFA5 */ + [MSTP124] = SH_CLK_MSTP32(&rclk_clk, SMSTPCR1, 24, 0), /* CMT0 */ +}; + +static struct clk_lookup lookups[] = { + + /* main clocks */ + CLKDEV_CON_ID("extal", &extal_clk), + CLKDEV_CON_ID("extal_div2", &extal_div2_clk), + CLKDEV_CON_ID("main", &main_clk), + CLKDEV_CON_ID("pll1", &pll1_clk), + CLKDEV_CON_ID("pll1_div2", &pll1_div2_clk), + CLKDEV_CON_ID("pll3", &pll3_clk), + CLKDEV_CON_ID("hp", &hp_clk), + CLKDEV_CON_ID("p", &p_clk), + CLKDEV_CON_ID("rclk", &rclk_clk), + CLKDEV_CON_ID("mp", &mp_clk), + CLKDEV_CON_ID("cp", &cp_clk), + CLKDEV_CON_ID("peripheral_clk", &hp_clk), + + /* MSTP */ + CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */ + CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */ + CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP206]), /* SCIFB0 */ + CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP207]), /* SCIFB1 */ + CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP216]), /* SCIFB2 */ + CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP202]), /* SCIFA2 */ + CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP721]), /* SCIF0 */ + CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP720]), /* SCIF1 */ + CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP719]), /* SCIF2 */ + CLKDEV_DEV_ID("sh-sci.9", &mstp_clks[MSTP718]), /* SCIF3 */ + CLKDEV_DEV_ID("sh-sci.10", &mstp_clks[MSTP715]), /* SCIF4 */ + CLKDEV_DEV_ID("sh-sci.11", &mstp_clks[MSTP714]), /* SCIF5 */ + CLKDEV_DEV_ID("sh-sci.12", &mstp_clks[MSTP1105]), /* SCIFA3 */ + CLKDEV_DEV_ID("sh-sci.13", &mstp_clks[MSTP1106]), /* SCIFA4 */ + CLKDEV_DEV_ID("sh-sci.14", &mstp_clks[MSTP1107]), /* SCIFA5 */ + CLKDEV_DEV_ID("sh_cmt.0", &mstp_clks[MSTP124]), +}; + +#define R8A7791_CLOCK_ROOT(e, m, p0, p1, p30, p31) \ + extal_clk.rate = e * 1000 * 1000; \ + main_clk.parent = m; \ + SH_CLK_SET_RATIO(&pll1_clk_ratio, p1 / 2, 1); \ + if (mode & MD(19)) \ + SH_CLK_SET_RATIO(&pll3_clk_ratio, p31, 1); \ + else \ + SH_CLK_SET_RATIO(&pll3_clk_ratio, p30, 1) + + +void __init r8a7791_clock_init(void) +{ + void __iomem *modemr = ioremap_nocache(MODEMR, PAGE_SIZE); + u32 mode; + int k, ret = 0; + + BUG_ON(!modemr); + mode = ioread32(modemr); + iounmap(modemr); + + switch (mode & (MD(14) | MD(13))) { + case 0: + R8A7791_CLOCK_ROOT(15, &extal_clk, 172, 208, 106, 88); + break; + case MD(13): + R8A7791_CLOCK_ROOT(20, &extal_clk, 130, 156, 80, 66); + break; + case MD(14): + R8A7791_CLOCK_ROOT(26, &extal_div2_clk, 200, 240, 122, 102); + break; + case MD(13) | MD(14): + R8A7791_CLOCK_ROOT(30, &extal_div2_clk, 172, 208, 106, 88); + break; + } + + for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++) + ret = clk_register(main_clks[k]); + + if (!ret) + ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); + + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); + + if (!ret) + shmobile_clk_init(); + else + goto epanic; + + return; + +epanic: + panic("failed to setup r8a7791 clocks\n"); +} diff --git a/arch/arm/mach-shmobile/headsmp.S b/arch/arm/mach-shmobile/headsmp.S index f93751caf5cb..e5be5c88644b 100644 --- a/arch/arm/mach-shmobile/headsmp.S +++ b/arch/arm/mach-shmobile/headsmp.S @@ -40,6 +40,9 @@ shmobile_boot_fn: .globl shmobile_boot_arg shmobile_boot_arg: 2: .space 4 + .globl shmobile_boot_size +shmobile_boot_size: + .long . - shmobile_boot_vector /* * Per-CPU SMP boot function/argument selection code based on MPIDR diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h index 7b938681e756..e31980590eb4 100644 --- a/arch/arm/mach-shmobile/include/mach/common.h +++ b/arch/arm/mach-shmobile/include/mach/common.h @@ -9,16 +9,23 @@ extern void shmobile_setup_console(void); extern void shmobile_boot_vector(void); extern unsigned long shmobile_boot_fn; extern unsigned long shmobile_boot_arg; +extern unsigned long shmobile_boot_size; extern void shmobile_smp_boot(void); extern void shmobile_smp_sleep(void); extern void shmobile_smp_hook(unsigned int cpu, unsigned long fn, unsigned long arg); +extern int shmobile_smp_cpu_disable(unsigned int cpu); +extern void shmobile_invalidate_start(void); extern void shmobile_boot_scu(void); extern void shmobile_smp_scu_prepare_cpus(unsigned int max_cpus); -extern int shmobile_smp_scu_boot_secondary(unsigned int cpu, - struct task_struct *idle); extern void shmobile_smp_scu_cpu_die(unsigned int cpu); extern int shmobile_smp_scu_cpu_kill(unsigned int cpu); +extern void shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus); +extern int shmobile_smp_apmu_boot_secondary(unsigned int cpu, + struct task_struct *idle); +extern void shmobile_smp_apmu_cpu_die(unsigned int cpu); +extern int shmobile_smp_apmu_cpu_kill(unsigned int cpu); +extern void shmobile_invalidate_start(void); struct clk; extern int shmobile_clk_init(void); extern void shmobile_handle_irq_intc(struct pt_regs *); @@ -39,7 +46,6 @@ static inline int shmobile_cpuidle_init(void) { return 0; } #endif extern void __iomem *shmobile_scu_base; -extern void shmobile_smp_init_cpus(unsigned int ncores); static inline void __init shmobile_init_late(void) { diff --git a/arch/arm/mach-shmobile/include/mach/r7s72100.h b/arch/arm/mach-shmobile/include/mach/r7s72100.h new file mode 100644 index 000000000000..5f34b20ecd4a --- /dev/null +++ b/arch/arm/mach-shmobile/include/mach/r7s72100.h @@ -0,0 +1,8 @@ +#ifndef __ASM_R7S72100_H__ +#define __ASM_R7S72100_H__ + +void r7s72100_add_dt_devices(void); +void r7s72100_clock_init(void); +void r7s72100_init_early(void); + +#endif /* __ASM_R7S72100_H__ */ diff --git a/arch/arm/mach-shmobile/include/mach/r8a73a4.h b/arch/arm/mach-shmobile/include/mach/r8a73a4.h index f3a9b702da56..ce8bdd1d8a8a 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a73a4.h +++ b/arch/arm/mach-shmobile/include/mach/r8a73a4.h @@ -1,10 +1,19 @@ #ifndef __ASM_R8A73A4_H__ #define __ASM_R8A73A4_H__ +/* DMA slave IDs */ +enum { + SHDMA_SLAVE_INVALID, + SHDMA_SLAVE_MMCIF0_TX, + SHDMA_SLAVE_MMCIF0_RX, + SHDMA_SLAVE_MMCIF1_TX, + SHDMA_SLAVE_MMCIF1_RX, +}; + void r8a73a4_add_standard_devices(void); void r8a73a4_add_dt_devices(void); void r8a73a4_clock_init(void); void r8a73a4_pinmux_init(void); -void r8a73a4_init_delay(void); +void r8a73a4_init_early(void); #endif /* __ASM_R8A73A4_H__ */ diff --git a/arch/arm/mach-shmobile/include/mach/r8a7778.h b/arch/arm/mach-shmobile/include/mach/r8a7778.h index adfcf51b163d..441886c9714b 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7778.h +++ b/arch/arm/mach-shmobile/include/mach/r8a7778.h @@ -1,6 +1,7 @@ /* * Copyright (C) 2013 Renesas Solutions Corp. * Copyright (C) 2013 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> + * Copyright (C) 2013 Cogent Embedded, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,11 +22,15 @@ #include <linux/sh_eth.h> #include <linux/platform_data/camera-rcar.h> +/* HPB-DMA slave IDs */ +enum { + HPBDMA_SLAVE_DUMMY, + HPBDMA_SLAVE_SDHI0_TX, + HPBDMA_SLAVE_SDHI0_RX, +}; + extern void r8a7778_add_standard_devices(void); extern void r8a7778_add_standard_devices_dt(void); -extern void r8a7778_add_ether_device(struct sh_eth_plat_data *pdata); -extern void r8a7778_add_vin_device(int id, - struct rcar_vin_platform_data *pdata); extern void r8a7778_add_dt_devices(void); extern void r8a7778_init_late(void); @@ -33,6 +38,9 @@ extern void r8a7778_init_delay(void); extern void r8a7778_init_irq_dt(void); extern void r8a7778_clock_init(void); extern void r8a7778_init_irq_extpin(int irlm); +extern void r8a7778_init_irq_extpin_dt(int irlm); extern void r8a7778_pinmux_init(void); +extern int r8a7778_usb_phy_power(bool enable); + #endif /* __ASM_R8A7778_H__ */ diff --git a/arch/arm/mach-shmobile/include/mach/r8a7779.h b/arch/arm/mach-shmobile/include/mach/r8a7779.h index 11c740047e14..17af34ed89c8 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7779.h +++ b/arch/arm/mach-shmobile/include/mach/r8a7779.h @@ -6,6 +6,13 @@ #include <linux/sh_eth.h> #include <linux/platform_data/camera-rcar.h> +/* HPB-DMA slave IDs */ +enum { + HPBDMA_SLAVE_DUMMY, + HPBDMA_SLAVE_SDHI0_TX, + HPBDMA_SLAVE_SDHI0_RX, +}; + struct platform_device; struct r8a7779_pm_ch { @@ -26,6 +33,7 @@ static inline struct r8a7779_pm_ch *to_r8a7779_ch(struct generic_pm_domain *d) extern void r8a7779_init_delay(void); extern void r8a7779_init_irq_extpin(int irlm); +extern void r8a7779_init_irq_extpin_dt(int irlm); extern void r8a7779_init_irq_dt(void); extern void r8a7779_map_io(void); extern void r8a7779_earlytimer_init(void); diff --git a/arch/arm/mach-shmobile/include/mach/r8a7790.h b/arch/arm/mach-shmobile/include/mach/r8a7790.h index 788d55952091..5fbfa28b40b6 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7790.h +++ b/arch/arm/mach-shmobile/include/mach/r8a7790.h @@ -1,14 +1,13 @@ #ifndef __ASM_R8A7790_H__ #define __ASM_R8A7790_H__ +#include <mach/rcar-gen2.h> + void r8a7790_add_standard_devices(void); void r8a7790_add_dt_devices(void); void r8a7790_clock_init(void); void r8a7790_pinmux_init(void); -void r8a7790_init_delay(void); -void r8a7790_timer_init(void); - -#define MD(nr) BIT(nr) -u32 r8a7790_read_mode_pins(void); +void r8a7790_init_early(void); +extern struct smp_operations r8a7790_smp_ops; #endif /* __ASM_R8A7790_H__ */ diff --git a/arch/arm/mach-shmobile/include/mach/r8a7791.h b/arch/arm/mach-shmobile/include/mach/r8a7791.h new file mode 100644 index 000000000000..051ead3c286e --- /dev/null +++ b/arch/arm/mach-shmobile/include/mach/r8a7791.h @@ -0,0 +1,10 @@ +#ifndef __ASM_R8A7791_H__ +#define __ASM_R8A7791_H__ + +void r8a7791_add_standard_devices(void); +void r8a7791_add_dt_devices(void); +void r8a7791_clock_init(void); +void r8a7791_init_early(void); +extern struct smp_operations r8a7791_smp_ops; + +#endif /* __ASM_R8A7791_H__ */ diff --git a/arch/arm/mach-shmobile/include/mach/rcar-gen2.h b/arch/arm/mach-shmobile/include/mach/rcar-gen2.h new file mode 100644 index 000000000000..43f606eb2d82 --- /dev/null +++ b/arch/arm/mach-shmobile/include/mach/rcar-gen2.h @@ -0,0 +1,8 @@ +#ifndef __ASM_RCAR_GEN2_H__ +#define __ASM_RCAR_GEN2_H__ + +void rcar_gen2_timer_init(void); +#define MD(nr) BIT(nr) +u32 rcar_gen2_read_mode_pins(void); + +#endif /* __ASM_RCAR_GEN2_H__ */ diff --git a/arch/arm/mach-shmobile/platsmp-apmu.c b/arch/arm/mach-shmobile/platsmp-apmu.c new file mode 100644 index 000000000000..1da5a72d9642 --- /dev/null +++ b/arch/arm/mach-shmobile/platsmp-apmu.c @@ -0,0 +1,195 @@ +/* + * SMP support for SoCs with APMU + * + * Copyright (C) 2013 Magnus Damm + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/delay.h> +#include <linux/init.h> +#include <linux/io.h> +#include <linux/ioport.h> +#include <linux/of_address.h> +#include <linux/smp.h> +#include <asm/cacheflush.h> +#include <asm/cp15.h> +#include <asm/smp_plat.h> +#include <mach/common.h> + +static struct { + void __iomem *iomem; + int bit; +} apmu_cpus[CONFIG_NR_CPUS]; + +#define WUPCR_OFFS 0x10 +#define PSTR_OFFS 0x40 +#define CPUNCR_OFFS(n) (0x100 + (0x10 * (n))) + +static int apmu_power_on(void __iomem *p, int bit) +{ + /* request power on */ + writel_relaxed(BIT(bit), p + WUPCR_OFFS); + + /* wait for APMU to finish */ + while (readl_relaxed(p + WUPCR_OFFS) != 0) + ; + + return 0; +} + +static int apmu_power_off(void __iomem *p, int bit) +{ + /* request Core Standby for next WFI */ + writel_relaxed(3, p + CPUNCR_OFFS(bit)); + return 0; +} + +static int apmu_power_off_poll(void __iomem *p, int bit) +{ + int k; + + for (k = 0; k < 1000; k++) { + if (((readl_relaxed(p + PSTR_OFFS) >> (bit * 4)) & 0x03) == 3) + return 1; + + mdelay(1); + } + + return 0; +} + +static int apmu_wrap(int cpu, int (*fn)(void __iomem *p, int cpu)) +{ + void __iomem *p = apmu_cpus[cpu].iomem; + + return p ? fn(p, apmu_cpus[cpu].bit) : -EINVAL; +} + +static void apmu_init_cpu(struct resource *res, int cpu, int bit) +{ + if (apmu_cpus[cpu].iomem) + return; + + apmu_cpus[cpu].iomem = ioremap_nocache(res->start, resource_size(res)); + apmu_cpus[cpu].bit = bit; + + pr_debug("apmu ioremap %d %d 0x%08x 0x%08x\n", cpu, bit, + res->start, resource_size(res)); +} + +static struct { + struct resource iomem; + int cpus[4]; +} apmu_config[] = { + { + .iomem = DEFINE_RES_MEM(0xe6152000, 0x88), + .cpus = { 0, 1, 2, 3 }, + }, + { + .iomem = DEFINE_RES_MEM(0xe6151000, 0x88), + .cpus = { 0x100, 0x101, 0x102, 0x103 }, + } +}; + +static void apmu_parse_cfg(void (*fn)(struct resource *res, int cpu, int bit)) +{ + u32 id; + int k; + int bit, index; + bool is_allowed; + + for (k = 0; k < ARRAY_SIZE(apmu_config); k++) { + /* only enable the cluster that includes the boot CPU */ + is_allowed = false; + for (bit = 0; bit < ARRAY_SIZE(apmu_config[k].cpus); bit++) { + id = apmu_config[k].cpus[bit]; + if (id >= 0) { + if (id == cpu_logical_map(0)) + is_allowed = true; + } + } + if (!is_allowed) + continue; + + for (bit = 0; bit < ARRAY_SIZE(apmu_config[k].cpus); bit++) { + id = apmu_config[k].cpus[bit]; + if (id >= 0) { + index = get_logical_index(id); + if (index >= 0) + fn(&apmu_config[k].iomem, index, bit); + } + } + } +} + +void __init shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus) +{ + /* install boot code shared by all CPUs */ + shmobile_boot_fn = virt_to_phys(shmobile_smp_boot); + shmobile_boot_arg = MPIDR_HWID_BITMASK; + + /* perform per-cpu setup */ + apmu_parse_cfg(apmu_init_cpu); +} + +int shmobile_smp_apmu_boot_secondary(unsigned int cpu, struct task_struct *idle) +{ + /* For this particular CPU register boot vector */ + shmobile_smp_hook(cpu, virt_to_phys(shmobile_invalidate_start), 0); + + return apmu_wrap(cpu, apmu_power_on); +} + +#ifdef CONFIG_HOTPLUG_CPU +/* nicked from arch/arm/mach-exynos/hotplug.c */ +static inline void cpu_enter_lowpower_a15(void) +{ + unsigned int v; + + asm volatile( + " mrc p15, 0, %0, c1, c0, 0\n" + " bic %0, %0, %1\n" + " mcr p15, 0, %0, c1, c0, 0\n" + : "=&r" (v) + : "Ir" (CR_C) + : "cc"); + + flush_cache_louis(); + + asm volatile( + /* + * Turn off coherency + */ + " mrc p15, 0, %0, c1, c0, 1\n" + " bic %0, %0, %1\n" + " mcr p15, 0, %0, c1, c0, 1\n" + : "=&r" (v) + : "Ir" (0x40) + : "cc"); + + isb(); + dsb(); +} + +void shmobile_smp_apmu_cpu_die(unsigned int cpu) +{ + /* For this particular CPU deregister boot vector */ + shmobile_smp_hook(cpu, 0, 0); + + /* Select next sleep mode using the APMU */ + apmu_wrap(cpu, apmu_power_off); + + /* Do ARM specific CPU shutdown */ + cpu_enter_lowpower_a15(); + + /* jump to shared mach-shmobile sleep / reset code */ + shmobile_smp_sleep(); +} + +int shmobile_smp_apmu_cpu_kill(unsigned int cpu) +{ + return apmu_wrap(cpu, apmu_power_off_poll); +} +#endif diff --git a/arch/arm/mach-shmobile/platsmp-scu.c b/arch/arm/mach-shmobile/platsmp-scu.c index c96f50160be6..673ad6e80869 100644 --- a/arch/arm/mach-shmobile/platsmp-scu.c +++ b/arch/arm/mach-shmobile/platsmp-scu.c @@ -7,6 +7,7 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#include <linux/cpu.h> #include <linux/delay.h> #include <linux/init.h> #include <linux/io.h> @@ -16,6 +17,26 @@ #include <asm/smp_scu.h> #include <mach/common.h> +static int shmobile_smp_scu_notifier_call(struct notifier_block *nfb, + unsigned long action, void *hcpu) +{ + unsigned int cpu = (long)hcpu; + + switch (action) { + case CPU_UP_PREPARE: + /* For this particular CPU register SCU SMP boot vector */ + shmobile_smp_hook(cpu, virt_to_phys(shmobile_boot_scu), + (unsigned long)shmobile_scu_base); + break; + }; + + return NOTIFY_OK; +} + +static struct notifier_block shmobile_smp_scu_notifier = { + .notifier_call = shmobile_smp_scu_notifier_call, +}; + void __init shmobile_smp_scu_prepare_cpus(unsigned int max_cpus) { /* install boot code shared by all CPUs */ @@ -25,14 +46,9 @@ void __init shmobile_smp_scu_prepare_cpus(unsigned int max_cpus) /* enable SCU and cache coherency on booting CPU */ scu_enable(shmobile_scu_base); scu_power_mode(shmobile_scu_base, SCU_PM_NORMAL); -} -int shmobile_smp_scu_boot_secondary(unsigned int cpu, struct task_struct *idle) -{ - /* For this particular CPU register SCU boot vector */ - shmobile_smp_hook(cpu, virt_to_phys(shmobile_boot_scu), - (unsigned long)shmobile_scu_base); - return 0; + /* Use CPU notifier for reset vector control */ + register_cpu_notifier(&shmobile_smp_scu_notifier); } #ifdef CONFIG_HOTPLUG_CPU diff --git a/arch/arm/mach-shmobile/platsmp.c b/arch/arm/mach-shmobile/platsmp.c index d4ae616bcedb..9ebc246b8d7d 100644 --- a/arch/arm/mach-shmobile/platsmp.c +++ b/arch/arm/mach-shmobile/platsmp.c @@ -11,25 +11,10 @@ * published by the Free Software Foundation. */ #include <linux/init.h> -#include <linux/smp.h> #include <asm/cacheflush.h> #include <asm/smp_plat.h> #include <mach/common.h> -void __init shmobile_smp_init_cpus(unsigned int ncores) -{ - unsigned int i; - - if (ncores > nr_cpu_ids) { - pr_warn("SMP: %u cores greater than maximum (%u), clipping\n", - ncores, nr_cpu_ids); - ncores = nr_cpu_ids; - } - - for (i = 0; i < ncores; i++) - set_cpu_possible(i, true); -} - extern unsigned long shmobile_smp_fn[]; extern unsigned long shmobile_smp_arg[]; extern unsigned long shmobile_smp_mpidr[]; @@ -44,3 +29,10 @@ void shmobile_smp_hook(unsigned int cpu, unsigned long fn, unsigned long arg) shmobile_smp_arg[cpu] = arg; flush_cache_all(); } + +#ifdef CONFIG_HOTPLUG_CPU +int shmobile_smp_cpu_disable(unsigned int cpu) +{ + return 0; /* Hotplug of any CPU is supported */ +} +#endif diff --git a/arch/arm/mach-shmobile/setup-r7s72100.c b/arch/arm/mach-shmobile/setup-r7s72100.c new file mode 100644 index 000000000000..d4eb509a1c87 --- /dev/null +++ b/arch/arm/mach-shmobile/setup-r7s72100.c @@ -0,0 +1,88 @@ +/* + * r7s72100 processor support + * + * Copyright (C) 2013 Renesas Solutions Corp. + * Copyright (C) 2013 Magnus Damm + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that 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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <linux/irq.h> +#include <linux/kernel.h> +#include <linux/of_platform.h> +#include <linux/serial_sci.h> +#include <mach/common.h> +#include <mach/irqs.h> +#include <mach/r7s72100.h> +#include <asm/mach/arch.h> + +#define SCIF_DATA(index, baseaddr, irq) \ +[index] = { \ + .type = PORT_SCIF, \ + .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, \ + .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, \ + .scbrr_algo_id = SCBRR_ALGO_2, \ + .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE | \ + SCSCR_REIE, \ + .mapbase = baseaddr, \ + .irqs = { irq + 1, irq + 2, irq + 3, irq }, \ +} + +enum { SCIF0, SCIF1, SCIF2, SCIF3, SCIF4, SCIF5, SCIF6, SCIF7 }; + +static const struct plat_sci_port scif[] __initconst = { + SCIF_DATA(SCIF0, 0xe8007000, gic_iid(221)), /* SCIF0 */ + SCIF_DATA(SCIF1, 0xe8007800, gic_iid(225)), /* SCIF1 */ + SCIF_DATA(SCIF2, 0xe8008000, gic_iid(229)), /* SCIF2 */ + SCIF_DATA(SCIF3, 0xe8008800, gic_iid(233)), /* SCIF3 */ + SCIF_DATA(SCIF4, 0xe8009000, gic_iid(237)), /* SCIF4 */ + SCIF_DATA(SCIF5, 0xe8009800, gic_iid(241)), /* SCIF5 */ + SCIF_DATA(SCIF6, 0xe800a000, gic_iid(245)), /* SCIF6 */ + SCIF_DATA(SCIF7, 0xe800a800, gic_iid(249)), /* SCIF7 */ +}; + +static inline void r7s72100_register_scif(int idx) +{ + platform_device_register_data(&platform_bus, "sh-sci", idx, &scif[idx], + sizeof(struct plat_sci_port)); +} + +void __init r7s72100_add_dt_devices(void) +{ + r7s72100_register_scif(SCIF0); + r7s72100_register_scif(SCIF1); + r7s72100_register_scif(SCIF2); + r7s72100_register_scif(SCIF3); + r7s72100_register_scif(SCIF4); + r7s72100_register_scif(SCIF5); + r7s72100_register_scif(SCIF6); + r7s72100_register_scif(SCIF7); +} + +void __init r7s72100_init_early(void) +{ + shmobile_setup_delay(400, 1, 3); /* Cortex-A9 @ 400MHz */ +} + +#ifdef CONFIG_USE_OF +static const char *r7s72100_boards_compat_dt[] __initdata = { + "renesas,r7s72100", + NULL, +}; + +DT_MACHINE_START(R7S72100_DT, "Generic R7S72100 (Flattened Device Tree)") + .init_early = r7s72100_init_early, + .dt_compat = r7s72100_boards_compat_dt, +MACHINE_END +#endif /* CONFIG_USE_OF */ diff --git a/arch/arm/mach-shmobile/setup-r8a73a4.c b/arch/arm/mach-shmobile/setup-r8a73a4.c index 89491700afb7..b0f2749071be 100644 --- a/arch/arm/mach-shmobile/setup-r8a73a4.c +++ b/arch/arm/mach-shmobile/setup-r8a73a4.c @@ -22,8 +22,10 @@ #include <linux/of_platform.h> #include <linux/platform_data/irq-renesas-irqc.h> #include <linux/serial_sci.h> +#include <linux/sh_dma.h> #include <linux/sh_timer.h> #include <mach/common.h> +#include <mach/dma-register.h> #include <mach/irqs.h> #include <mach/r8a73a4.h> #include <asm/mach/arch.h> @@ -199,15 +201,104 @@ void __init r8a73a4_add_dt_devices(void) r8a7790_register_cmt(10); } +/* DMA */ +static const struct sh_dmae_slave_config dma_slaves[] = { + { + .slave_id = SHDMA_SLAVE_MMCIF0_TX, + .addr = 0xee200034, + .chcr = CHCR_TX(XMIT_SZ_32BIT), + .mid_rid = 0xd1, + }, { + .slave_id = SHDMA_SLAVE_MMCIF0_RX, + .addr = 0xee200034, + .chcr = CHCR_RX(XMIT_SZ_32BIT), + .mid_rid = 0xd2, + }, { + .slave_id = SHDMA_SLAVE_MMCIF1_TX, + .addr = 0xee220034, + .chcr = CHCR_TX(XMIT_SZ_32BIT), + .mid_rid = 0xe1, + }, { + .slave_id = SHDMA_SLAVE_MMCIF1_RX, + .addr = 0xee220034, + .chcr = CHCR_RX(XMIT_SZ_32BIT), + .mid_rid = 0xe2, + }, +}; + +#define DMAE_CHANNEL(a, b) \ + { \ + .offset = (a) - 0x20, \ + .dmars = (a) - 0x20 + 0x40, \ + .chclr_bit = (b), \ + .chclr_offset = 0x80 - 0x20, \ + } + +static const struct sh_dmae_channel dma_channels[] = { + DMAE_CHANNEL(0x8000, 0), + DMAE_CHANNEL(0x8080, 1), + DMAE_CHANNEL(0x8100, 2), + DMAE_CHANNEL(0x8180, 3), + DMAE_CHANNEL(0x8200, 4), + DMAE_CHANNEL(0x8280, 5), + DMAE_CHANNEL(0x8300, 6), + DMAE_CHANNEL(0x8380, 7), + DMAE_CHANNEL(0x8400, 8), + DMAE_CHANNEL(0x8480, 9), + DMAE_CHANNEL(0x8500, 10), + DMAE_CHANNEL(0x8580, 11), + DMAE_CHANNEL(0x8600, 12), + DMAE_CHANNEL(0x8680, 13), + DMAE_CHANNEL(0x8700, 14), + DMAE_CHANNEL(0x8780, 15), + DMAE_CHANNEL(0x8800, 16), + DMAE_CHANNEL(0x8880, 17), + DMAE_CHANNEL(0x8900, 18), + DMAE_CHANNEL(0x8980, 19), +}; + +static const struct sh_dmae_pdata dma_pdata = { + .slave = dma_slaves, + .slave_num = ARRAY_SIZE(dma_slaves), + .channel = dma_channels, + .channel_num = ARRAY_SIZE(dma_channels), + .ts_low_shift = TS_LOW_SHIFT, + .ts_low_mask = TS_LOW_BIT << TS_LOW_SHIFT, + .ts_high_shift = TS_HI_SHIFT, + .ts_high_mask = TS_HI_BIT << TS_HI_SHIFT, + .ts_shift = dma_ts_shift, + .ts_shift_num = ARRAY_SIZE(dma_ts_shift), + .dmaor_init = DMAOR_DME, + .chclr_present = 1, + .chclr_bitwise = 1, +}; + +static struct resource dma_resources[] = { + DEFINE_RES_MEM(0xe6700020, 0x89e0), + DEFINE_RES_IRQ_NAMED(gic_spi(220), "error_irq"), + { + /* IRQ for channels 0-19 */ + .start = gic_spi(200), + .end = gic_spi(219), + .flags = IORESOURCE_IRQ, + }, +}; + +#define r8a73a4_register_dmac() \ + platform_device_register_resndata(&platform_bus, "sh-dma-engine", 0, \ + dma_resources, ARRAY_SIZE(dma_resources), \ + &dma_pdata, sizeof(dma_pdata)) + void __init r8a73a4_add_standard_devices(void) { r8a73a4_add_dt_devices(); r8a73a4_register_irqc(0); r8a73a4_register_irqc(1); r8a73a4_register_thermal(); + r8a73a4_register_dmac(); } -void __init r8a73a4_init_delay(void) +void __init r8a73a4_init_early(void) { #ifndef CONFIG_ARM_ARCH_TIMER shmobile_setup_delay(1500, 2, 4); /* Cortex-A15 @ 1500MHz */ @@ -222,7 +313,7 @@ static const char *r8a73a4_boards_compat_dt[] __initdata = { }; DT_MACHINE_START(R8A73A4_DT, "Generic R8A73A4 (Flattened Device Tree)") - .init_early = r8a73a4_init_delay, + .init_early = r8a73a4_init_early, .dt_compat = r8a73a4_boards_compat_dt, MACHINE_END #endif /* CONFIG_USE_OF */ diff --git a/arch/arm/mach-shmobile/setup-r8a7778.c b/arch/arm/mach-shmobile/setup-r8a7778.c index 6a2657ebd197..03fcc5974ef9 100644 --- a/arch/arm/mach-shmobile/setup-r8a7778.c +++ b/arch/arm/mach-shmobile/setup-r8a7778.c @@ -24,6 +24,7 @@ #include <linux/irqchip/arm-gic.h> #include <linux/of.h> #include <linux/of_platform.h> +#include <linux/platform_data/dma-rcar-hpbdma.h> #include <linux/platform_data/gpio-rcar.h> #include <linux/platform_data/irq-renesas-intc-irqpin.h> #include <linux/platform_device.h> @@ -95,29 +96,46 @@ static struct sh_timer_config sh_tmu1_platform_data __initdata = { &sh_tmu##idx##_platform_data, \ sizeof(sh_tmu##idx##_platform_data)) -/* USB */ -static struct usb_phy *phy; +int r8a7778_usb_phy_power(bool enable) +{ + static struct usb_phy *phy = NULL; + int ret = 0; + if (!phy) + phy = usb_get_phy(USB_PHY_TYPE_USB2); + + if (IS_ERR(phy)) { + pr_err("kernel doesn't have usb phy driver\n"); + return PTR_ERR(phy); + } + + if (enable) + ret = usb_phy_init(phy); + else + usb_phy_shutdown(phy); + + return ret; +} + +/* USB */ static int usb_power_on(struct platform_device *pdev) { - if (IS_ERR(phy)) - return PTR_ERR(phy); + int ret = r8a7778_usb_phy_power(true); + + if (ret) + return ret; pm_runtime_enable(&pdev->dev); pm_runtime_get_sync(&pdev->dev); - usb_phy_init(phy); - return 0; } static void usb_power_off(struct platform_device *pdev) { - if (IS_ERR(phy)) + if (r8a7778_usb_phy_power(false)) return; - usb_phy_shutdown(phy); - pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); } @@ -174,20 +192,6 @@ static struct platform_device_info hci##_info __initdata = { \ USB_PLATFORM_INFO(ehci); USB_PLATFORM_INFO(ohci); -/* Ether */ -static struct resource ether_resources[] __initdata = { - DEFINE_RES_MEM(0xfde00000, 0x400), - DEFINE_RES_IRQ(gic_iid(0x89)), -}; - -void __init r8a7778_add_ether_device(struct sh_eth_plat_data *pdata) -{ - platform_device_register_resndata(&platform_bus, "r8a777x-ether", -1, - ether_resources, - ARRAY_SIZE(ether_resources), - pdata, sizeof(*pdata)); -} - /* PFC/GPIO */ static struct resource pfc_resources[] __initdata = { DEFINE_RES_MEM(0xfffc0000, 0x118), @@ -272,7 +276,7 @@ static struct resource hspi_resources[] __initdata = { DEFINE_RES_IRQ(gic_iid(0x75)), }; -void __init r8a7778_register_hspi(int id) +static void __init r8a7778_register_hspi(int id) { BUG_ON(id < 0 || id > 2); @@ -281,40 +285,6 @@ void __init r8a7778_register_hspi(int id) hspi_resources + (2 * id), 2); } -/* VIN */ -#define R8A7778_VIN(idx) \ -static struct resource vin##idx##_resources[] __initdata = { \ - DEFINE_RES_MEM(0xffc50000 + 0x1000 * (idx), 0x1000), \ - DEFINE_RES_IRQ(gic_iid(0x5a)), \ -}; \ - \ -static struct platform_device_info vin##idx##_info __initdata = { \ - .parent = &platform_bus, \ - .name = "r8a7778-vin", \ - .id = idx, \ - .res = vin##idx##_resources, \ - .num_res = ARRAY_SIZE(vin##idx##_resources), \ - .dma_mask = DMA_BIT_MASK(32), \ -} - -R8A7778_VIN(0); -R8A7778_VIN(1); - -static struct platform_device_info *vin_info_table[] __initdata = { - &vin0_info, - &vin1_info, -}; - -void __init r8a7778_add_vin_device(int id, struct rcar_vin_platform_data *pdata) -{ - BUG_ON(id < 0 || id > 1); - - vin_info_table[id]->data = pdata; - vin_info_table[id]->size_data = sizeof(*pdata); - - platform_device_register_full(vin_info_table[id]); -} - void __init r8a7778_add_dt_devices(void) { int i; @@ -339,6 +309,88 @@ void __init r8a7778_add_dt_devices(void) r8a7778_register_tmu(1); } +/* HPB-DMA */ + +/* Asynchronous mode register (ASYNCMDR) bits */ +#define HPB_DMAE_ASYNCMDR_ASMD22_MASK BIT(2) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD22_SINGLE BIT(2) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD22_MULTI 0 /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD21_MASK BIT(1) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD21_SINGLE BIT(1) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD21_MULTI 0 /* SDHI0 */ + +static const struct hpb_dmae_slave_config hpb_dmae_slaves[] = { + { + .id = HPBDMA_SLAVE_SDHI0_TX, + .addr = 0xffe4c000 + 0x30, + .dcr = HPB_DMAE_DCR_SPDS_16BIT | + HPB_DMAE_DCR_DMDL | + HPB_DMAE_DCR_DPDS_16BIT, + .rstr = HPB_DMAE_ASYNCRSTR_ASRST21 | + HPB_DMAE_ASYNCRSTR_ASRST22 | + HPB_DMAE_ASYNCRSTR_ASRST23, + .mdr = HPB_DMAE_ASYNCMDR_ASMD21_MULTI, + .mdm = HPB_DMAE_ASYNCMDR_ASMD21_MASK, + .port = 0x0D0C, + .flags = HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE, + .dma_ch = 21, + }, { + .id = HPBDMA_SLAVE_SDHI0_RX, + .addr = 0xffe4c000 + 0x30, + .dcr = HPB_DMAE_DCR_SMDL | + HPB_DMAE_DCR_SPDS_16BIT | + HPB_DMAE_DCR_DPDS_16BIT, + .rstr = HPB_DMAE_ASYNCRSTR_ASRST21 | + HPB_DMAE_ASYNCRSTR_ASRST22 | + HPB_DMAE_ASYNCRSTR_ASRST23, + .mdr = HPB_DMAE_ASYNCMDR_ASMD22_MULTI, + .mdm = HPB_DMAE_ASYNCMDR_ASMD22_MASK, + .port = 0x0D0C, + .flags = HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE, + .dma_ch = 22, + }, +}; + +static const struct hpb_dmae_channel hpb_dmae_channels[] = { + HPB_DMAE_CHANNEL(0x7e, HPBDMA_SLAVE_SDHI0_TX), /* ch. 21 */ + HPB_DMAE_CHANNEL(0x7e, HPBDMA_SLAVE_SDHI0_RX), /* ch. 22 */ +}; + +static struct hpb_dmae_pdata dma_platform_data __initdata = { + .slaves = hpb_dmae_slaves, + .num_slaves = ARRAY_SIZE(hpb_dmae_slaves), + .channels = hpb_dmae_channels, + .num_channels = ARRAY_SIZE(hpb_dmae_channels), + .ts_shift = { + [XMIT_SZ_8BIT] = 0, + [XMIT_SZ_16BIT] = 1, + [XMIT_SZ_32BIT] = 2, + }, + .num_hw_channels = 39, +}; + +static struct resource hpb_dmae_resources[] __initdata = { + /* Channel registers */ + DEFINE_RES_MEM(0xffc08000, 0x1000), + /* Common registers */ + DEFINE_RES_MEM(0xffc09000, 0x170), + /* Asynchronous reset registers */ + DEFINE_RES_MEM(0xffc00300, 4), + /* Asynchronous mode registers */ + DEFINE_RES_MEM(0xffc00400, 4), + /* IRQ for DMA channels */ + DEFINE_RES_NAMED(gic_iid(0x7b), 5, NULL, IORESOURCE_IRQ), +}; + +static void __init r8a7778_register_hpb_dmae(void) +{ + platform_device_register_resndata(&platform_bus, "hpb-dma-engine", -1, + hpb_dmae_resources, + ARRAY_SIZE(hpb_dmae_resources), + &dma_platform_data, + sizeof(dma_platform_data)); +} + void __init r8a7778_add_standard_devices(void) { r8a7778_add_dt_devices(); @@ -349,12 +401,12 @@ void __init r8a7778_add_standard_devices(void) r8a7778_register_hspi(0); r8a7778_register_hspi(1); r8a7778_register_hspi(2); + + r8a7778_register_hpb_dmae(); } void __init r8a7778_init_late(void) { - phy = usb_get_phy(USB_PHY_TYPE_USB2); - platform_device_register_full(&ehci_info); platform_device_register_full(&ohci_info); } @@ -376,7 +428,7 @@ static struct resource irqpin_resources[] __initdata = { DEFINE_RES_IRQ(gic_iid(0x3e)), /* IRQ3 */ }; -void __init r8a7778_init_irq_extpin(int irlm) +void __init r8a7778_init_irq_extpin_dt(int irlm) { void __iomem *icr0 = ioremap_nocache(0xfe780000, PAGE_SIZE); unsigned long tmp; @@ -394,7 +446,11 @@ void __init r8a7778_init_irq_extpin(int irlm) tmp |= (1 << 21); /* LVLMODE = 1 */ iowrite32(tmp, icr0); iounmap(icr0); +} +void __init r8a7778_init_irq_extpin(int irlm) +{ + r8a7778_init_irq_extpin_dt(irlm); if (irlm) platform_device_register_resndata( &platform_bus, "renesas_intc_irqpin", -1, diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c index ecd0148ee1e1..13049e9d691c 100644 --- a/arch/arm/mach-shmobile/setup-r8a7779.c +++ b/arch/arm/mach-shmobile/setup-r8a7779.c @@ -25,6 +25,7 @@ #include <linux/irqchip.h> #include <linux/irqchip/arm-gic.h> #include <linux/of_platform.h> +#include <linux/platform_data/dma-rcar-hpbdma.h> #include <linux/platform_data/gpio-rcar.h> #include <linux/platform_data/irq-renesas-intc-irqpin.h> #include <linux/platform_device.h> @@ -97,7 +98,7 @@ static struct resource irqpin0_resources[] __initdata = { DEFINE_RES_IRQ(gic_spi(30)), /* IRQ3 */ }; -void __init r8a7779_init_irq_extpin(int irlm) +void __init r8a7779_init_irq_extpin_dt(int irlm) { void __iomem *icr0 = ioremap_nocache(0xfe780000, PAGE_SIZE); u32 tmp; @@ -115,7 +116,11 @@ void __init r8a7779_init_irq_extpin(int irlm) tmp |= (1 << 21); /* LVLMODE = 1 */ iowrite32(tmp, icr0); iounmap(icr0); +} +void __init r8a7779_init_irq_extpin(int irlm) +{ + r8a7779_init_irq_extpin_dt(irlm); if (irlm) platform_device_register_resndata( &platform_bus, "renesas_intc_irqpin", -1, @@ -632,6 +637,158 @@ static struct platform_device_info *vin_info_table[] __initdata = { &vin3_info, }; +/* HPB-DMA */ + +/* Asynchronous mode register bits */ +#define HPB_DMAE_ASYNCMDR_ASMD43_MASK BIT(23) /* MMC1 */ +#define HPB_DMAE_ASYNCMDR_ASMD43_SINGLE BIT(23) /* MMC1 */ +#define HPB_DMAE_ASYNCMDR_ASMD43_MULTI 0 /* MMC1 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD43_MASK BIT(22) /* MMC1 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD43_BURST BIT(22) /* MMC1 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD43_NBURST 0 /* MMC1 */ +#define HPB_DMAE_ASYNCMDR_ASMD24_MASK BIT(21) /* MMC0 */ +#define HPB_DMAE_ASYNCMDR_ASMD24_SINGLE BIT(21) /* MMC0 */ +#define HPB_DMAE_ASYNCMDR_ASMD24_MULTI 0 /* MMC0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD24_MASK BIT(20) /* MMC0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD24_BURST BIT(20) /* MMC0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD24_NBURST 0 /* MMC0 */ +#define HPB_DMAE_ASYNCMDR_ASMD41_MASK BIT(19) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASMD41_SINGLE BIT(19) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASMD41_MULTI 0 /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD41_MASK BIT(18) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD41_BURST BIT(18) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD41_NBURST 0 /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASMD40_MASK BIT(17) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASMD40_SINGLE BIT(17) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASMD40_MULTI 0 /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD40_MASK BIT(16) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD40_BURST BIT(16) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD40_NBURST 0 /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASMD39_MASK BIT(15) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASMD39_SINGLE BIT(15) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASMD39_MULTI 0 /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD39_MASK BIT(14) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD39_BURST BIT(14) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD39_NBURST 0 /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASMD27_MASK BIT(13) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASMD27_SINGLE BIT(13) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASMD27_MULTI 0 /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD27_MASK BIT(12) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD27_BURST BIT(12) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD27_NBURST 0 /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASMD26_MASK BIT(11) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASMD26_SINGLE BIT(11) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASMD26_MULTI 0 /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD26_MASK BIT(10) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD26_BURST BIT(10) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD26_NBURST 0 /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASMD25_MASK BIT(9) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASMD25_SINGLE BIT(9) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASMD25_MULTI 0 /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD25_MASK BIT(8) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD25_BURST BIT(8) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD25_NBURST 0 /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASMD23_MASK BIT(7) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD23_SINGLE BIT(7) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD23_MULTI 0 /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD23_MASK BIT(6) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD23_BURST BIT(6) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD23_NBURST 0 /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD22_MASK BIT(5) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD22_SINGLE BIT(5) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD22_MULTI 0 /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD22_MASK BIT(4) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD22_BURST BIT(4) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD22_NBURST 0 /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD21_MASK BIT(3) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD21_SINGLE BIT(3) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD21_MULTI 0 /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD21_MASK BIT(2) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD21_BURST BIT(2) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD21_NBURST 0 /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD20_MASK BIT(1) /* SDHI1 */ +#define HPB_DMAE_ASYNCMDR_ASMD20_SINGLE BIT(1) /* SDHI1 */ +#define HPB_DMAE_ASYNCMDR_ASMD20_MULTI 0 /* SDHI1 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD20_MASK BIT(0) /* SDHI1 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD20_BURST BIT(0) /* SDHI1 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD20_NBURST 0 /* SDHI1 */ + +static const struct hpb_dmae_slave_config hpb_dmae_slaves[] = { + { + .id = HPBDMA_SLAVE_SDHI0_TX, + .addr = 0xffe4c000 + 0x30, + .dcr = HPB_DMAE_DCR_SPDS_16BIT | + HPB_DMAE_DCR_DMDL | + HPB_DMAE_DCR_DPDS_16BIT, + .rstr = HPB_DMAE_ASYNCRSTR_ASRST21 | + HPB_DMAE_ASYNCRSTR_ASRST22 | + HPB_DMAE_ASYNCRSTR_ASRST23, + .mdr = HPB_DMAE_ASYNCMDR_ASMD21_SINGLE | + HPB_DMAE_ASYNCMDR_ASBTMD21_NBURST, + .mdm = HPB_DMAE_ASYNCMDR_ASMD21_MASK | + HPB_DMAE_ASYNCMDR_ASBTMD21_MASK, + .port = 0x0D0C, + .flags = HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE, + .dma_ch = 21, + }, { + .id = HPBDMA_SLAVE_SDHI0_RX, + .addr = 0xffe4c000 + 0x30, + .dcr = HPB_DMAE_DCR_SMDL | + HPB_DMAE_DCR_SPDS_16BIT | + HPB_DMAE_DCR_DPDS_16BIT, + .rstr = HPB_DMAE_ASYNCRSTR_ASRST21 | + HPB_DMAE_ASYNCRSTR_ASRST22 | + HPB_DMAE_ASYNCRSTR_ASRST23, + .mdr = HPB_DMAE_ASYNCMDR_ASMD22_SINGLE | + HPB_DMAE_ASYNCMDR_ASBTMD22_NBURST, + .mdm = HPB_DMAE_ASYNCMDR_ASMD22_MASK | + HPB_DMAE_ASYNCMDR_ASBTMD22_MASK, + .port = 0x0D0C, + .flags = HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE, + .dma_ch = 22, + }, +}; + +static const struct hpb_dmae_channel hpb_dmae_channels[] = { + HPB_DMAE_CHANNEL(0x93, HPBDMA_SLAVE_SDHI0_TX), /* ch. 21 */ + HPB_DMAE_CHANNEL(0x93, HPBDMA_SLAVE_SDHI0_RX), /* ch. 22 */ +}; + +static struct hpb_dmae_pdata dma_platform_data __initdata = { + .slaves = hpb_dmae_slaves, + .num_slaves = ARRAY_SIZE(hpb_dmae_slaves), + .channels = hpb_dmae_channels, + .num_channels = ARRAY_SIZE(hpb_dmae_channels), + .ts_shift = { + [XMIT_SZ_8BIT] = 0, + [XMIT_SZ_16BIT] = 1, + [XMIT_SZ_32BIT] = 2, + }, + .num_hw_channels = 44, +}; + +static struct resource hpb_dmae_resources[] __initdata = { + /* Channel registers */ + DEFINE_RES_MEM(0xffc08000, 0x1000), + /* Common registers */ + DEFINE_RES_MEM(0xffc09000, 0x170), + /* Asynchronous reset registers */ + DEFINE_RES_MEM(0xffc00300, 4), + /* Asynchronous mode registers */ + DEFINE_RES_MEM(0xffc00400, 4), + /* IRQ for DMA channels */ + DEFINE_RES_NAMED(gic_iid(0x8e), 12, NULL, IORESOURCE_IRQ), +}; + +static void __init r8a7779_register_hpb_dmae(void) +{ + platform_device_register_resndata(&platform_bus, "hpb-dma-engine", -1, + hpb_dmae_resources, + ARRAY_SIZE(hpb_dmae_resources), + &dma_platform_data, + sizeof(dma_platform_data)); +} + static struct platform_device *r8a7779_devices_dt[] __initdata = { &scif0_device, &scif1_device, @@ -665,6 +822,7 @@ void __init r8a7779_add_standard_devices(void) ARRAY_SIZE(r8a7779_devices_dt)); platform_add_devices(r8a7779_standard_devices, ARRAY_SIZE(r8a7779_standard_devices)); + r8a7779_register_hpb_dmae(); } void __init r8a7779_add_ether_device(struct sh_eth_plat_data *pdata) diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c b/arch/arm/mach-shmobile/setup-r8a7790.c index d0f5c9f9349a..c47bcebbcb00 100644 --- a/arch/arm/mach-shmobile/setup-r8a7790.c +++ b/arch/arm/mach-shmobile/setup-r8a7790.c @@ -18,7 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include <linux/clocksource.h> #include <linux/irq.h> #include <linux/kernel.h> #include <linux/of_platform.h> @@ -31,17 +30,18 @@ #include <mach/r8a7790.h> #include <asm/mach/arch.h> -static struct resource pfc_resources[] __initdata = { +static const struct resource pfc_resources[] __initconst = { DEFINE_RES_MEM(0xe6060000, 0x250), }; #define R8A7790_GPIO(idx) \ -static struct resource r8a7790_gpio##idx##_resources[] __initdata = { \ +static const struct resource r8a7790_gpio##idx##_resources[] __initconst = { \ DEFINE_RES_MEM(0xe6050000 + 0x1000 * (idx), 0x50), \ DEFINE_RES_IRQ(gic_spi(4 + (idx))), \ }; \ \ -static struct gpio_rcar_config r8a7790_gpio##idx##_platform_data __initdata = { \ +static const struct gpio_rcar_config \ +r8a7790_gpio##idx##_platform_data __initconst = { \ .gpio_base = 32 * (idx), \ .irq_base = 0, \ .number_of_pins = 32, \ @@ -112,7 +112,7 @@ void __init r8a7790_pinmux_init(void) enum { SCIFA0, SCIFA1, SCIFB0, SCIFB1, SCIFB2, SCIFA2, SCIF0, SCIF1, HSCIF0, HSCIF1 }; -static struct plat_sci_port scif[] __initdata = { +static const struct plat_sci_port scif[] __initconst = { SCIFA_DATA(SCIFA0, 0xe6c40000, gic_spi(144)), /* SCIFA0 */ SCIFA_DATA(SCIFA1, 0xe6c50000, gic_spi(145)), /* SCIFA1 */ SCIFB_DATA(SCIFB0, 0xe6c20000, gic_spi(148)), /* SCIFB0 */ @@ -131,11 +131,11 @@ static inline void r8a7790_register_scif(int idx) sizeof(struct plat_sci_port)); } -static struct renesas_irqc_config irqc0_data __initdata = { +static const struct renesas_irqc_config irqc0_data __initconst = { .irq_base = irq_pin(0), /* IRQ0 -> IRQ3 */ }; -static struct resource irqc0_resources[] __initdata = { +static const struct resource irqc0_resources[] __initconst = { DEFINE_RES_MEM(0xe61c0000, 0x200), /* IRQC Event Detector Block_0 */ DEFINE_RES_IRQ(gic_spi(0)), /* IRQ0 */ DEFINE_RES_IRQ(gic_spi(1)), /* IRQ1 */ @@ -150,7 +150,7 @@ static struct resource irqc0_resources[] __initdata = { &irqc##idx##_data, \ sizeof(struct renesas_irqc_config)) -static struct resource thermal_resources[] __initdata = { +static const struct resource thermal_resources[] __initconst = { DEFINE_RES_MEM(0xe61f0000, 0x14), DEFINE_RES_MEM(0xe61f0100, 0x38), DEFINE_RES_IRQ(gic_spi(69)), @@ -161,13 +161,13 @@ static struct resource thermal_resources[] __initdata = { thermal_resources, \ ARRAY_SIZE(thermal_resources)) -static struct sh_timer_config cmt00_platform_data __initdata = { +static const struct sh_timer_config cmt00_platform_data __initconst = { .name = "CMT00", .timer_bit = 0, .clockevent_rating = 80, }; -static struct resource cmt00_resources[] __initdata = { +static const struct resource cmt00_resources[] __initconst = { DEFINE_RES_MEM(0xffca0510, 0x0c), DEFINE_RES_MEM(0xffca0500, 0x04), DEFINE_RES_IRQ(gic_spi(142)), /* CMT0_0 */ @@ -202,72 +202,7 @@ void __init r8a7790_add_standard_devices(void) r8a7790_register_thermal(); } -#define MODEMR 0xe6160060 - -u32 __init r8a7790_read_mode_pins(void) -{ - void __iomem *modemr = ioremap_nocache(MODEMR, 4); - u32 mode; - - BUG_ON(!modemr); - mode = ioread32(modemr); - iounmap(modemr); - - return mode; -} - -#define CNTCR 0 -#define CNTFID0 0x20 - -void __init r8a7790_timer_init(void) -{ -#ifdef CONFIG_ARM_ARCH_TIMER - u32 mode = r8a7790_read_mode_pins(); - void __iomem *base; - int extal_mhz = 0; - u32 freq; - - /* At Linux boot time the r8a7790 arch timer comes up - * with the counter disabled. Moreover, it may also report - * a potentially incorrect fixed 13 MHz frequency. To be - * correct these registers need to be updated to use the - * frequency EXTAL / 2 which can be determined by the MD pins. - */ - - switch (mode & (MD(14) | MD(13))) { - case 0: - extal_mhz = 15; - break; - case MD(13): - extal_mhz = 20; - break; - case MD(14): - extal_mhz = 26; - break; - case MD(13) | MD(14): - extal_mhz = 30; - break; - } - - /* The arch timer frequency equals EXTAL / 2 */ - freq = extal_mhz * (1000000 / 2); - - /* Remap "armgcnt address map" space */ - base = ioremap(0xe6080000, PAGE_SIZE); - - /* Update registers with correct frequency */ - iowrite32(freq, base + CNTFID0); - asm volatile("mcr p15, 0, %0, c14, c0, 0" : : "r" (freq)); - - /* make sure arch timer is started by setting bit 0 of CNTCR */ - iowrite32(1, base + CNTCR); - iounmap(base); -#endif /* CONFIG_ARM_ARCH_TIMER */ - - clocksource_of_init(); -} - -void __init r8a7790_init_delay(void) +void __init r8a7790_init_early(void) { #ifndef CONFIG_ARM_ARCH_TIMER shmobile_setup_delay(1300, 2, 4); /* Cortex-A15 @ 1300MHz */ @@ -276,14 +211,15 @@ void __init r8a7790_init_delay(void) #ifdef CONFIG_USE_OF -static const char *r8a7790_boards_compat_dt[] __initdata = { +static const char * const r8a7790_boards_compat_dt[] __initconst = { "renesas,r8a7790", NULL, }; DT_MACHINE_START(R8A7790_DT, "Generic R8A7790 (Flattened Device Tree)") - .init_early = r8a7790_init_delay, - .init_time = r8a7790_timer_init, + .smp = smp_ops(r8a7790_smp_ops), + .init_early = r8a7790_init_early, + .init_time = rcar_gen2_timer_init, .dt_compat = r8a7790_boards_compat_dt, MACHINE_END #endif /* CONFIG_USE_OF */ diff --git a/arch/arm/mach-shmobile/setup-r8a7791.c b/arch/arm/mach-shmobile/setup-r8a7791.c new file mode 100644 index 000000000000..d9393d61ee27 --- /dev/null +++ b/arch/arm/mach-shmobile/setup-r8a7791.c @@ -0,0 +1,184 @@ +/* + * r8a7791 processor support + * + * Copyright (C) 2013 Renesas Electronics Corporation + * Copyright (C) 2013 Renesas Solutions Corp. + * Copyright (C) 2013 Magnus Damm + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that 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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <linux/irq.h> +#include <linux/kernel.h> +#include <linux/of_platform.h> +#include <linux/platform_data/irq-renesas-irqc.h> +#include <linux/serial_sci.h> +#include <linux/sh_timer.h> +#include <mach/common.h> +#include <mach/irqs.h> +#include <mach/r8a7791.h> +#include <mach/rcar-gen2.h> +#include <asm/mach/arch.h> + +#define SCIF_COMMON(scif_type, baseaddr, irq) \ + .type = scif_type, \ + .mapbase = baseaddr, \ + .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, \ + .irqs = SCIx_IRQ_MUXED(irq) + +#define SCIFA_DATA(index, baseaddr, irq) \ +[index] = { \ + SCIF_COMMON(PORT_SCIFA, baseaddr, irq), \ + .scbrr_algo_id = SCBRR_ALGO_4, \ + .scscr = SCSCR_RE | SCSCR_TE, \ +} + +#define SCIFB_DATA(index, baseaddr, irq) \ +[index] = { \ + SCIF_COMMON(PORT_SCIFB, baseaddr, irq), \ + .scbrr_algo_id = SCBRR_ALGO_4, \ + .scscr = SCSCR_RE | SCSCR_TE, \ +} + +#define SCIF_DATA(index, baseaddr, irq) \ +[index] = { \ + SCIF_COMMON(PORT_SCIF, baseaddr, irq), \ + .scbrr_algo_id = SCBRR_ALGO_2, \ + .scscr = SCSCR_RE | SCSCR_TE, \ +} + +#define HSCIF_DATA(index, baseaddr, irq) \ +[index] = { \ + SCIF_COMMON(PORT_HSCIF, baseaddr, irq), \ + .scbrr_algo_id = SCBRR_ALGO_6, \ + .scscr = SCSCR_RE | SCSCR_TE, \ +} + +enum { SCIFA0, SCIFA1, SCIFB0, SCIFB1, SCIFB2, SCIFA2, SCIF0, SCIF1, + SCIF2, SCIF3, SCIF4, SCIF5, SCIFA3, SCIFA4, SCIFA5 }; + +static const struct plat_sci_port scif[] __initconst = { + SCIFA_DATA(SCIFA0, 0xe6c40000, gic_spi(144)), /* SCIFA0 */ + SCIFA_DATA(SCIFA1, 0xe6c50000, gic_spi(145)), /* SCIFA1 */ + SCIFB_DATA(SCIFB0, 0xe6c20000, gic_spi(148)), /* SCIFB0 */ + SCIFB_DATA(SCIFB1, 0xe6c30000, gic_spi(149)), /* SCIFB1 */ + SCIFB_DATA(SCIFB2, 0xe6ce0000, gic_spi(150)), /* SCIFB2 */ + SCIFA_DATA(SCIFA2, 0xe6c60000, gic_spi(151)), /* SCIFA2 */ + SCIF_DATA(SCIF0, 0xe6e60000, gic_spi(152)), /* SCIF0 */ + SCIF_DATA(SCIF1, 0xe6e68000, gic_spi(153)), /* SCIF1 */ + SCIF_DATA(SCIF2, 0xe6e58000, gic_spi(22)), /* SCIF2 */ + SCIF_DATA(SCIF3, 0xe6ea8000, gic_spi(23)), /* SCIF3 */ + SCIF_DATA(SCIF4, 0xe6ee0000, gic_spi(24)), /* SCIF4 */ + SCIF_DATA(SCIF5, 0xe6ee8000, gic_spi(25)), /* SCIF5 */ + SCIFA_DATA(SCIFA3, 0xe6c70000, gic_spi(29)), /* SCIFA3 */ + SCIFA_DATA(SCIFA4, 0xe6c78000, gic_spi(30)), /* SCIFA4 */ + SCIFA_DATA(SCIFA5, 0xe6c80000, gic_spi(31)), /* SCIFA5 */ +}; + +static inline void r8a7791_register_scif(int idx) +{ + platform_device_register_data(&platform_bus, "sh-sci", idx, &scif[idx], + sizeof(struct plat_sci_port)); +} + +static const struct sh_timer_config cmt00_platform_data __initconst = { + .name = "CMT00", + .timer_bit = 0, + .clockevent_rating = 80, +}; + +static const struct resource cmt00_resources[] __initconst = { + DEFINE_RES_MEM(0xffca0510, 0x0c), + DEFINE_RES_MEM(0xffca0500, 0x04), + DEFINE_RES_IRQ(gic_spi(142)), /* CMT0_0 */ +}; + +#define r8a7791_register_cmt(idx) \ + platform_device_register_resndata(&platform_bus, "sh_cmt", \ + idx, cmt##idx##_resources, \ + ARRAY_SIZE(cmt##idx##_resources), \ + &cmt##idx##_platform_data, \ + sizeof(struct sh_timer_config)) + +static struct renesas_irqc_config irqc0_data = { + .irq_base = irq_pin(0), /* IRQ0 -> IRQ9 */ +}; + +static struct resource irqc0_resources[] = { + DEFINE_RES_MEM(0xe61c0000, 0x200), /* IRQC Event Detector Block_0 */ + DEFINE_RES_IRQ(gic_spi(0)), /* IRQ0 */ + DEFINE_RES_IRQ(gic_spi(1)), /* IRQ1 */ + DEFINE_RES_IRQ(gic_spi(2)), /* IRQ2 */ + DEFINE_RES_IRQ(gic_spi(3)), /* IRQ3 */ + DEFINE_RES_IRQ(gic_spi(12)), /* IRQ4 */ + DEFINE_RES_IRQ(gic_spi(13)), /* IRQ5 */ + DEFINE_RES_IRQ(gic_spi(14)), /* IRQ6 */ + DEFINE_RES_IRQ(gic_spi(15)), /* IRQ7 */ + DEFINE_RES_IRQ(gic_spi(16)), /* IRQ8 */ + DEFINE_RES_IRQ(gic_spi(17)), /* IRQ9 */ +}; + +#define r8a7791_register_irqc(idx) \ + platform_device_register_resndata(&platform_bus, "renesas_irqc", \ + idx, irqc##idx##_resources, \ + ARRAY_SIZE(irqc##idx##_resources), \ + &irqc##idx##_data, \ + sizeof(struct renesas_irqc_config)) + +void __init r8a7791_add_dt_devices(void) +{ + r8a7791_register_scif(SCIFA0); + r8a7791_register_scif(SCIFA1); + r8a7791_register_scif(SCIFB0); + r8a7791_register_scif(SCIFB1); + r8a7791_register_scif(SCIFB2); + r8a7791_register_scif(SCIFA2); + r8a7791_register_scif(SCIF0); + r8a7791_register_scif(SCIF1); + r8a7791_register_scif(SCIF2); + r8a7791_register_scif(SCIF3); + r8a7791_register_scif(SCIF4); + r8a7791_register_scif(SCIF5); + r8a7791_register_scif(SCIFA3); + r8a7791_register_scif(SCIFA4); + r8a7791_register_scif(SCIFA5); + r8a7791_register_cmt(00); +} + +void __init r8a7791_add_standard_devices(void) +{ + r8a7791_add_dt_devices(); + r8a7791_register_irqc(0); +} + +void __init r8a7791_init_early(void) +{ +#ifndef CONFIG_ARM_ARCH_TIMER + shmobile_setup_delay(1300, 2, 4); /* Cortex-A15 @ 1300MHz */ +#endif +} + +#ifdef CONFIG_USE_OF +static const char *r8a7791_boards_compat_dt[] __initdata = { + "renesas,r8a7791", + NULL, +}; + +DT_MACHINE_START(R8A7791_DT, "Generic R8A7791 (Flattened Device Tree)") + .smp = smp_ops(r8a7791_smp_ops), + .init_early = r8a7791_init_early, + .init_time = rcar_gen2_timer_init, + .dt_compat = r8a7791_boards_compat_dt, +MACHINE_END +#endif /* CONFIG_USE_OF */ diff --git a/arch/arm/mach-shmobile/setup-rcar-gen2.c b/arch/arm/mach-shmobile/setup-rcar-gen2.c new file mode 100644 index 000000000000..5734c24bf6c7 --- /dev/null +++ b/arch/arm/mach-shmobile/setup-rcar-gen2.c @@ -0,0 +1,91 @@ +/* + * R-Car Generation 2 support + * + * Copyright (C) 2013 Renesas Solutions Corp. + * Copyright (C) 2013 Magnus Damm + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that 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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <linux/clocksource.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <mach/common.h> +#include <mach/rcar-gen2.h> +#include <asm/mach/arch.h> + +#define MODEMR 0xe6160060 + +u32 __init rcar_gen2_read_mode_pins(void) +{ + void __iomem *modemr = ioremap_nocache(MODEMR, 4); + u32 mode; + + BUG_ON(!modemr); + mode = ioread32(modemr); + iounmap(modemr); + + return mode; +} + +#define CNTCR 0 +#define CNTFID0 0x20 + +void __init rcar_gen2_timer_init(void) +{ +#ifdef CONFIG_ARM_ARCH_TIMER + u32 mode = rcar_gen2_read_mode_pins(); + void __iomem *base; + int extal_mhz = 0; + u32 freq; + + /* At Linux boot time the r8a7790 arch timer comes up + * with the counter disabled. Moreover, it may also report + * a potentially incorrect fixed 13 MHz frequency. To be + * correct these registers need to be updated to use the + * frequency EXTAL / 2 which can be determined by the MD pins. + */ + + switch (mode & (MD(14) | MD(13))) { + case 0: + extal_mhz = 15; + break; + case MD(13): + extal_mhz = 20; + break; + case MD(14): + extal_mhz = 26; + break; + case MD(13) | MD(14): + extal_mhz = 30; + break; + } + + /* The arch timer frequency equals EXTAL / 2 */ + freq = extal_mhz * (1000000 / 2); + + /* Remap "armgcnt address map" space */ + base = ioremap(0xe6080000, PAGE_SIZE); + + /* Update registers with correct frequency */ + iowrite32(freq, base + CNTFID0); + asm volatile("mcr p15, 0, %0, c14, c0, 0" : : "r" (freq)); + + /* make sure arch timer is started by setting bit 0 of CNTCR */ + iowrite32(1, base + CNTCR); + iounmap(base); +#endif /* CONFIG_ARM_ARCH_TIMER */ + + clocksource_of_init(); +} diff --git a/arch/arm/mach-shmobile/smp-emev2.c b/arch/arm/mach-shmobile/smp-emev2.c index 522de5ebb55f..f2ca92308f75 100644 --- a/arch/arm/mach-shmobile/smp-emev2.c +++ b/arch/arm/mach-shmobile/smp-emev2.c @@ -34,12 +34,6 @@ static int emev2_boot_secondary(unsigned int cpu, struct task_struct *idle) { - int ret; - - ret = shmobile_smp_scu_boot_secondary(cpu, idle); - if (ret) - return ret; - arch_send_wakeup_ipi_mask(cpumask_of(cpu_logical_map(cpu))); return 0; } diff --git a/arch/arm/mach-shmobile/smp-r8a7779.c b/arch/arm/mach-shmobile/smp-r8a7779.c index 0f05e9fb722f..627c1f0d9478 100644 --- a/arch/arm/mach-shmobile/smp-r8a7779.c +++ b/arch/arm/mach-shmobile/smp-r8a7779.c @@ -87,10 +87,6 @@ static int r8a7779_boot_secondary(unsigned int cpu, struct task_struct *idle) unsigned int lcpu = cpu_logical_map(cpu); int ret; - ret = shmobile_smp_scu_boot_secondary(cpu, idle); - if (ret) - return ret; - if (lcpu < ARRAY_SIZE(r8a7779_ch_cpu)) ch = r8a7779_ch_cpu[lcpu]; diff --git a/arch/arm/mach-shmobile/smp-r8a7790.c b/arch/arm/mach-shmobile/smp-r8a7790.c new file mode 100644 index 000000000000..015e2753de1f --- /dev/null +++ b/arch/arm/mach-shmobile/smp-r8a7790.c @@ -0,0 +1,67 @@ +/* + * SMP support for r8a7790 + * + * Copyright (C) 2012-2013 Renesas Solutions Corp. + * Copyright (C) 2012 Takashi Yoshii <takashi.yoshii.ze@renesas.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that 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. + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/smp.h> +#include <linux/io.h> +#include <asm/smp_plat.h> +#include <mach/common.h> + +#define RST 0xe6160000 +#define CA15BAR 0x0020 +#define CA7BAR 0x0030 +#define CA15RESCNT 0x0040 +#define CA7RESCNT 0x0044 +#define MERAM 0xe8080000 + +static void __init r8a7790_smp_prepare_cpus(unsigned int max_cpus) +{ + void __iomem *p; + u32 bar; + + /* let APMU code install data related to shmobile_boot_vector */ + shmobile_smp_apmu_prepare_cpus(max_cpus); + + /* MERAM for jump stub, because BAR requires 256KB aligned address */ + p = ioremap_nocache(MERAM, shmobile_boot_size); + memcpy_toio(p, shmobile_boot_vector, shmobile_boot_size); + iounmap(p); + + /* setup reset vectors */ + p = ioremap_nocache(RST, 0x63); + bar = (MERAM >> 8) & 0xfffffc00; + writel_relaxed(bar, p + CA15BAR); + writel_relaxed(bar, p + CA7BAR); + writel_relaxed(bar | 0x10, p + CA15BAR); + writel_relaxed(bar | 0x10, p + CA7BAR); + + /* enable clocks to all CPUs */ + writel_relaxed((readl_relaxed(p + CA15RESCNT) & ~0x0f) | 0xa5a50000, + p + CA15RESCNT); + writel_relaxed((readl_relaxed(p + CA7RESCNT) & ~0x0f) | 0x5a5a0000, + p + CA7RESCNT); + iounmap(p); +} + +struct smp_operations r8a7790_smp_ops __initdata = { + .smp_prepare_cpus = r8a7790_smp_prepare_cpus, + .smp_boot_secondary = shmobile_smp_apmu_boot_secondary, +#ifdef CONFIG_HOTPLUG_CPU + .cpu_disable = shmobile_smp_cpu_disable, + .cpu_die = shmobile_smp_apmu_cpu_die, + .cpu_kill = shmobile_smp_apmu_cpu_kill, +#endif +}; diff --git a/arch/arm/mach-shmobile/smp-r8a7791.c b/arch/arm/mach-shmobile/smp-r8a7791.c new file mode 100644 index 000000000000..2df5bd190fe4 --- /dev/null +++ b/arch/arm/mach-shmobile/smp-r8a7791.c @@ -0,0 +1,62 @@ +/* + * SMP support for r8a7791 + * + * Copyright (C) 2013 Renesas Solutions Corp. + * Copyright (C) 2013 Magnus Damm + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that 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. + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/smp.h> +#include <linux/io.h> +#include <asm/smp_plat.h> +#include <mach/common.h> +#include <mach/r8a7791.h> + +#define RST 0xe6160000 +#define CA15BAR 0x0020 +#define CA15RESCNT 0x0040 +#define RAM 0xe6300000 + +static void __init r8a7791_smp_prepare_cpus(unsigned int max_cpus) +{ + void __iomem *p; + u32 bar; + + /* let APMU code install data related to shmobile_boot_vector */ + shmobile_smp_apmu_prepare_cpus(max_cpus); + + /* RAM for jump stub, because BAR requires 256KB aligned address */ + p = ioremap_nocache(RAM, shmobile_boot_size); + memcpy_toio(p, shmobile_boot_vector, shmobile_boot_size); + iounmap(p); + + /* setup reset vectors */ + p = ioremap_nocache(RST, 0x63); + bar = (RAM >> 8) & 0xfffffc00; + writel_relaxed(bar, p + CA15BAR); + writel_relaxed(bar | 0x10, p + CA15BAR); + + /* enable clocks to all CPUs */ + writel_relaxed((readl_relaxed(p + CA15RESCNT) & ~0x0f) | 0xa5a50000, + p + CA15RESCNT); + iounmap(p); +} + +struct smp_operations r8a7791_smp_ops __initdata = { + .smp_prepare_cpus = r8a7791_smp_prepare_cpus, + .smp_boot_secondary = shmobile_smp_apmu_boot_secondary, +#ifdef CONFIG_HOTPLUG_CPU + .cpu_disable = shmobile_smp_cpu_disable, + .cpu_die = shmobile_smp_apmu_cpu_die, + .cpu_kill = shmobile_smp_apmu_cpu_kill, +#endif +}; diff --git a/arch/arm/mach-shmobile/smp-sh73a0.c b/arch/arm/mach-shmobile/smp-sh73a0.c index 0baa24443793..13ba36a6831f 100644 --- a/arch/arm/mach-shmobile/smp-sh73a0.c +++ b/arch/arm/mach-shmobile/smp-sh73a0.c @@ -46,11 +46,6 @@ void __init sh73a0_register_twd(void) static int sh73a0_boot_secondary(unsigned int cpu, struct task_struct *idle) { unsigned int lcpu = cpu_logical_map(cpu); - int ret; - - ret = shmobile_smp_scu_boot_secondary(cpu, idle); - if (ret) - return ret; if (((__raw_readl(PSTR) >> (4 * lcpu)) & 3) == 3) __raw_writel(1 << lcpu, WUPCR); /* wake up */ @@ -71,18 +66,11 @@ static void __init sh73a0_smp_prepare_cpus(unsigned int max_cpus) shmobile_smp_scu_prepare_cpus(max_cpus); } -#ifdef CONFIG_HOTPLUG_CPU -static int sh73a0_cpu_disable(unsigned int cpu) -{ - return 0; /* CPU0 and CPU1 supported */ -} -#endif /* CONFIG_HOTPLUG_CPU */ - struct smp_operations sh73a0_smp_ops __initdata = { .smp_prepare_cpus = sh73a0_smp_prepare_cpus, .smp_boot_secondary = sh73a0_boot_secondary, #ifdef CONFIG_HOTPLUG_CPU - .cpu_disable = sh73a0_cpu_disable, + .cpu_disable = shmobile_smp_cpu_disable, .cpu_die = shmobile_smp_scu_cpu_die, .cpu_kill = shmobile_smp_scu_cpu_kill, #endif diff --git a/arch/arm/mach-socfpga/Kconfig b/arch/arm/mach-socfpga/Kconfig index dd86db467521..037100a1563a 100644 --- a/arch/arm/mach-socfpga/Kconfig +++ b/arch/arm/mach-socfpga/Kconfig @@ -4,7 +4,6 @@ config ARCH_SOCFPGA select ARM_AMBA select ARM_GIC select CACHE_L2X0 - select CLKDEV_LOOKUP select COMMON_CLK select CPU_V7 select DW_APB_TIMER_OF diff --git a/arch/arm/mach-socfpga/socfpga.c b/arch/arm/mach-socfpga/socfpga.c index bfce9641e32f..dd0d49cdbe09 100644 --- a/arch/arm/mach-socfpga/socfpga.c +++ b/arch/arm/mach-socfpga/socfpga.c @@ -14,7 +14,6 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include <linux/clk-provider.h> #include <linux/irqchip.h> #include <linux/of_address.h> #include <linux/of_irq.h> @@ -107,7 +106,6 @@ static void __init socfpga_cyclone5_init(void) { l2x0_of_init(0, ~0UL); of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); - of_clk_init(NULL); socfpga_init_clocks(); } diff --git a/arch/arm/mach-spear/Kconfig b/arch/arm/mach-spear/Kconfig index df0d59afeb40..ac1710e64d9a 100644 --- a/arch/arm/mach-spear/Kconfig +++ b/arch/arm/mach-spear/Kconfig @@ -7,11 +7,9 @@ menuconfig PLAT_SPEAR default PLAT_SPEAR_SINGLE select ARCH_REQUIRE_GPIOLIB select ARM_AMBA - select CLKDEV_LOOKUP select CLKSRC_MMIO select COMMON_CLK select GENERIC_CLOCKEVENTS - select HAVE_CLK if PLAT_SPEAR diff --git a/arch/arm/mach-sti/Kconfig b/arch/arm/mach-sti/Kconfig index 835833e3c4f8..d71654bc8d54 100644 --- a/arch/arm/mach-sti/Kconfig +++ b/arch/arm/mach-sti/Kconfig @@ -12,7 +12,7 @@ menuconfig ARCH_STI select HAVE_ARM_SCU if SMP select ARCH_REQUIRE_GPIOLIB select ARM_ERRATA_754322 - select ARM_ERRATA_764369 + select ARM_ERRATA_764369 if SMP select ARM_ERRATA_775420 select PL310_ERRATA_753970 if CACHE_PL310 select PL310_ERRATA_769419 if CACHE_PL310 @@ -30,7 +30,7 @@ config SOC_STIH415 default y help This enables support for STMicroelectronics Digital Consumer - Electronics family StiH415 parts, primarily targetted at set-top-box + Electronics family StiH415 parts, primarily targeted at set-top-box and other digital audio/video applications using Flattned Device Trees. @@ -39,7 +39,7 @@ config SOC_STIH416 default y help This enables support for STMicroelectronics Digital Consumer - Electronics family StiH416 parts, primarily targetted at set-top-box + Electronics family StiH416 parts, primarily targeted at set-top-box and other digital audio/video applications using Flattened Device Trees. diff --git a/arch/arm/mach-sti/board-dt.c b/arch/arm/mach-sti/board-dt.c index 8fe6f0c46480..1217fb598cfd 100644 --- a/arch/arm/mach-sti/board-dt.c +++ b/arch/arm/mach-sti/board-dt.c @@ -7,9 +7,8 @@ * published by the Free Software Foundation. */ -#include <linux/clk-provider.h> -#include <linux/clocksource.h> #include <linux/irq.h> +#include <linux/of_platform.h> #include <asm/hardware/cache-l2x0.h> #include <asm/mach/arch.h> @@ -28,11 +27,10 @@ void __init stih41x_l2x0_init(void) l2x0_of_init(aux_ctrl, L2X0_AUX_CTRL_MASK); } -static void __init stih41x_timer_init(void) +static void __init stih41x_machine_init(void) { - of_clk_init(NULL); - clocksource_of_init(); stih41x_l2x0_init(); + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); } static const char *stih41x_dt_match[] __initdata = { @@ -42,7 +40,7 @@ static const char *stih41x_dt_match[] __initdata = { }; DT_MACHINE_START(STM, "STiH415/416 SoC with Flattened Device Tree") - .init_time = stih41x_timer_init, + .init_machine = stih41x_machine_init, .smp = smp_ops(sti_smp_ops), .dt_compat = stih41x_dt_match, MACHINE_END diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig index 3ab2f65f8a50..c9e72c89066a 100644 --- a/arch/arm/mach-sunxi/Kconfig +++ b/arch/arm/mach-sunxi/Kconfig @@ -1,14 +1,14 @@ config ARCH_SUNXI bool "Allwinner A1X SOCs" if ARCH_MULTI_V7 select ARCH_REQUIRE_GPIOLIB + select ARM_GIC select CLKSRC_MMIO select CLKSRC_OF select COMMON_CLK select GENERIC_CLOCKEVENTS select GENERIC_IRQ_CHIP + select HAVE_SMP select PINCTRL + select PINCTRL_SUNXI select SPARSE_IRQ select SUN4I_TIMER - select PINCTRL_SUNXI - select ARM_GIC - select HAVE_SMP diff --git a/arch/arm/mach-sunxi/sunxi.c b/arch/arm/mach-sunxi/sunxi.c index e79fb3469341..61d3a387f01c 100644 --- a/arch/arm/mach-sunxi/sunxi.c +++ b/arch/arm/mach-sunxi/sunxi.c @@ -10,7 +10,6 @@ * warranty of any kind, whether express or implied. */ -#include <linux/clocksource.h> #include <linux/delay.h> #include <linux/kernel.h> #include <linux/init.h> @@ -20,8 +19,6 @@ #include <linux/io.h> #include <linux/reboot.h> -#include <linux/clk/sunxi.h> - #include <asm/mach/arch.h> #include <asm/mach/map.h> #include <asm/system_misc.h> @@ -93,14 +90,13 @@ static void sun6i_restart(enum reboot_mode mode, const char *cmd) } static struct of_device_id sunxi_restart_ids[] = { - { .compatible = "allwinner,sun4i-wdt", .data = sun4i_restart }, - { .compatible = "allwinner,sun6i-wdt", .data = sun6i_restart }, + { .compatible = "allwinner,sun4i-wdt" }, + { .compatible = "allwinner,sun6i-wdt" }, { /*sentinel*/ } }; static void sunxi_setup_restart(void) { - const struct of_device_id *of_id; struct device_node *np; np = of_find_matching_node(NULL, sunxi_restart_ids); @@ -109,17 +105,6 @@ static void sunxi_setup_restart(void) wdt_base = of_iomap(np, 0); WARN(!wdt_base, "failed to map watchdog base address"); - - of_id = of_match_node(sunxi_restart_ids, np); - WARN(!of_id, "restart function not available"); - - arm_pm_restart = of_id->data; -} - -static void __init sunxi_timer_init(void) -{ - sunxi_init_clocks(); - clocksource_of_init(); } static void __init sunxi_dt_init(void) @@ -133,13 +118,33 @@ static const char * const sunxi_board_dt_compat[] = { "allwinner,sun4i-a10", "allwinner,sun5i-a10s", "allwinner,sun5i-a13", - "allwinner,sun6i-a31", - "allwinner,sun7i-a20", NULL, }; DT_MACHINE_START(SUNXI_DT, "Allwinner A1X (Device Tree)") .init_machine = sunxi_dt_init, - .init_time = sunxi_timer_init, .dt_compat = sunxi_board_dt_compat, + .restart = sun4i_restart, +MACHINE_END + +static const char * const sun6i_board_dt_compat[] = { + "allwinner,sun6i-a31", + NULL, +}; + +DT_MACHINE_START(SUN6I_DT, "Allwinner sun6i (A31) Family") + .init_machine = sunxi_dt_init, + .dt_compat = sun6i_board_dt_compat, + .restart = sun6i_restart, +MACHINE_END + +static const char * const sun7i_board_dt_compat[] = { + "allwinner,sun7i-a20", + NULL, +}; + +DT_MACHINE_START(SUN7I_DT, "Allwinner sun7i (A20) Family") + .init_machine = sunxi_dt_init, + .dt_compat = sun7i_board_dt_compat, + .restart = sun4i_restart, MACHINE_END diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index 67a76f2dfb9f..09e740f58b27 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig @@ -3,7 +3,6 @@ config ARCH_TEGRA select ARCH_HAS_CPUFREQ select ARCH_REQUIRE_GPIOLIB select ARM_GIC - select CLKDEV_LOOKUP select CLKSRC_MMIO select CLKSRC_OF select COMMON_CLK @@ -11,7 +10,6 @@ config ARCH_TEGRA select GENERIC_CLOCKEVENTS select HAVE_ARM_SCU if SMP select HAVE_ARM_TWD if SMP - select HAVE_CLK select HAVE_SMP select MIGHT_HAVE_CACHE_L2X0 select MIGHT_HAVE_PCI @@ -53,14 +51,22 @@ config ARCH_TEGRA_3x_SOC config ARCH_TEGRA_114_SOC bool "Enable support for Tegra114 family" - select HAVE_ARM_ARCH_TIMER - select ARM_ERRATA_798181 + select ARM_ERRATA_798181 if SMP select ARM_L1_CACHE_SHIFT_6 + select HAVE_ARM_ARCH_TIMER select PINCTRL_TEGRA114 help Support for NVIDIA Tegra T114 processor family, based on the ARM CortexA15MP CPU +config ARCH_TEGRA_124_SOC + bool "Enable support for Tegra124 family" + select ARM_L1_CACHE_SHIFT_6 + select HAVE_ARM_ARCH_TIMER + help + Support for NVIDIA Tegra T124 processor family, based on the + ARM CortexA15MP CPU + config TEGRA_AHB bool "Enable AHB driver for NVIDIA Tegra SoCs" default y diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index e7e5f45c6558..019bb1758662 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile @@ -1,6 +1,5 @@ asflags-y += -march=armv7-a -obj-y += common.o obj-y += io.o obj-y += irq.o obj-y += fuse.o @@ -36,5 +35,10 @@ obj-$(CONFIG_ARCH_TEGRA_114_SOC) += pm-tegra30.o ifeq ($(CONFIG_CPU_IDLE),y) obj-$(CONFIG_ARCH_TEGRA_114_SOC) += cpuidle-tegra114.o endif +obj-$(CONFIG_ARCH_TEGRA_124_SOC) += sleep-tegra30.o +obj-$(CONFIG_ARCH_TEGRA_124_SOC) += pm-tegra30.o +ifeq ($(CONFIG_CPU_IDLE),y) +obj-$(CONFIG_ARCH_TEGRA_124_SOC) += cpuidle-tegra114.o +endif obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += board-paz00.o diff --git a/arch/arm/mach-tegra/apbio.c b/arch/arm/mach-tegra/apbio.c index d7aa52ea6cfc..bc471973cf04 100644 --- a/arch/arm/mach-tegra/apbio.c +++ b/arch/arm/mach-tegra/apbio.c @@ -114,7 +114,7 @@ static int do_dma_transfer(unsigned long apb_add, dma_desc->callback = apb_dma_complete; dma_desc->callback_param = NULL; - INIT_COMPLETION(tegra_apb_wait); + reinit_completion(&tegra_apb_wait); dmaengine_submit(dma_desc); dma_async_issue_pending(tegra_apb_dma_chan); diff --git a/arch/arm/mach-tegra/board-paz00.c b/arch/arm/mach-tegra/board-paz00.c index 740e16f64728..06f024070dab 100644 --- a/arch/arm/mach-tegra/board-paz00.c +++ b/arch/arm/mach-tegra/board-paz00.c @@ -20,12 +20,11 @@ #include <linux/platform_device.h> #include <linux/rfkill-gpio.h> #include "board.h" -#include "board-paz00.h" static struct rfkill_gpio_platform_data wifi_rfkill_platform_data = { .name = "wifi_rfkill", - .reset_gpio = TEGRA_WIFI_RST, - .shutdown_gpio = TEGRA_WIFI_PWRN, + .reset_gpio = 25, /* PD1 */ + .shutdown_gpio = 85, /* PK5 */ .type = RFKILL_TYPE_WLAN, }; diff --git a/arch/arm/mach-tegra/board-paz00.h b/arch/arm/mach-tegra/board-paz00.h deleted file mode 100644 index 25c08ecef52f..000000000000 --- a/arch/arm/mach-tegra/board-paz00.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * arch/arm/mach-tegra/board-paz00.h - * - * Copyright (C) 2010 Marc Dietrich <marvin24@gmx.de> - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that 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. - * - */ - -#ifndef _MACH_TEGRA_BOARD_PAZ00_H -#define _MACH_TEGRA_BOARD_PAZ00_H - -#include "gpio-names.h" - -#define TEGRA_WIFI_PWRN TEGRA_GPIO_PK5 -#define TEGRA_WIFI_RST TEGRA_GPIO_PD1 - -#endif diff --git a/arch/arm/mach-tegra/board.h b/arch/arm/mach-tegra/board.h index db6810dc0b3d..bcf5dbf69d58 100644 --- a/arch/arm/mach-tegra/board.h +++ b/arch/arm/mach-tegra/board.h @@ -25,20 +25,8 @@ #include <linux/types.h> #include <linux/reboot.h> -void tegra_assert_system_reset(enum reboot_mode mode, const char *cmd); - -void __init tegra_init_early(void); void __init tegra_map_common_io(void); void __init tegra_init_irq(void); -void __init tegra_dt_init_irq(void); - -void tegra_init_late(void); - -#ifdef CONFIG_DEBUG_FS -int tegra_clk_debugfs_init(void); -#else -static inline int tegra_clk_debugfs_init(void) { return 0; } -#endif int __init tegra_powergate_init(void); #if defined(CONFIG_ARCH_TEGRA_2x_SOC) && defined(CONFIG_DEBUG_FS) diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c deleted file mode 100644 index 94a119a35af8..000000000000 --- a/arch/arm/mach-tegra/common.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * arch/arm/mach-tegra/common.c - * - * Copyright (c) 2013 NVIDIA Corporation. All rights reserved. - * Copyright (C) 2010 Google, Inc. - * - * Author: - * Colin Cross <ccross@android.com> - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that 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. - * - */ - -#include <linux/init.h> -#include <linux/io.h> -#include <linux/clk.h> -#include <linux/delay.h> -#include <linux/reboot.h> -#include <linux/irqchip.h> -#include <linux/clk-provider.h> - -#include <asm/hardware/cache-l2x0.h> - -#include "board.h" -#include "common.h" -#include "cpuidle.h" -#include "fuse.h" -#include "iomap.h" -#include "irq.h" -#include "pmc.h" -#include "apbio.h" -#include "sleep.h" -#include "pm.h" -#include "reset.h" - -/* - * Storage for debug-macro.S's state. - * - * This must be in .data not .bss so that it gets initialized each time the - * kernel is loaded. The data is declared here rather than debug-macro.S so - * that multiple inclusions of debug-macro.S point at the same data. - */ -u32 tegra_uart_config[4] = { - /* Debug UART initialization required */ - 1, - /* Debug UART physical address */ - 0, - /* Debug UART virtual address */ - 0, - /* Scratch space for debug macro */ - 0, -}; - -#ifdef CONFIG_OF -void __init tegra_dt_init_irq(void) -{ - of_clk_init(NULL); - tegra_pmc_init(); - tegra_init_irq(); - irqchip_init(); - tegra_legacy_irq_syscore_init(); -} -#endif - -void tegra_assert_system_reset(enum reboot_mode mode, const char *cmd) -{ - void __iomem *reset = IO_ADDRESS(TEGRA_PMC_BASE + 0); - u32 reg; - - reg = readl_relaxed(reset); - reg |= 0x10; - writel_relaxed(reg, reset); -} - -static void __init tegra_init_cache(void) -{ -#ifdef CONFIG_CACHE_L2X0 - int ret; - void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000; - u32 aux_ctrl, cache_type; - - cache_type = readl(p + L2X0_CACHE_TYPE); - aux_ctrl = (cache_type & 0x700) << (17-8); - aux_ctrl |= 0x7C400001; - - ret = l2x0_of_init(aux_ctrl, 0x8200c3fe); - if (!ret) - l2x0_saved_regs_addr = virt_to_phys(&l2x0_saved_regs); -#endif - -} - -void __init tegra_init_early(void) -{ - tegra_cpu_reset_handler_init(); - tegra_apb_io_init(); - tegra_init_fuse(); - tegra_init_cache(); - tegra_powergate_init(); - tegra_hotplug_init(); -} - -void __init tegra_init_late(void) -{ - tegra_init_suspend(); - tegra_cpuidle_init(); - tegra_powergate_debugfs_init(); -} diff --git a/arch/arm/mach-tegra/cpuidle.c b/arch/arm/mach-tegra/cpuidle.c index 0961dfcf83a4..7bc5d8d667fe 100644 --- a/arch/arm/mach-tegra/cpuidle.c +++ b/arch/arm/mach-tegra/cpuidle.c @@ -39,7 +39,9 @@ void __init tegra_cpuidle_init(void) tegra30_cpuidle_init(); break; case TEGRA114: - if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC)) + case TEGRA124: + if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) || + IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC)) tegra114_cpuidle_init(); break; } diff --git a/arch/arm/mach-tegra/flowctrl.c b/arch/arm/mach-tegra/flowctrl.c index 5348543382bf..ce8ab8abf061 100644 --- a/arch/arm/mach-tegra/flowctrl.c +++ b/arch/arm/mach-tegra/flowctrl.c @@ -87,6 +87,7 @@ void flowctrl_cpu_suspend_enter(unsigned int cpuid) break; case TEGRA30: case TEGRA114: + case TEGRA124: /* clear wfe bitmap */ reg &= ~TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP; /* clear wfi bitmap */ @@ -125,6 +126,7 @@ void flowctrl_cpu_suspend_exit(unsigned int cpuid) break; case TEGRA30: case TEGRA114: + case TEGRA124: /* clear wfe bitmap */ reg &= ~TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP; /* clear wfi bitmap */ diff --git a/arch/arm/mach-tegra/fuse.c b/arch/arm/mach-tegra/fuse.c index e035cd284a6e..d4639c506622 100644 --- a/arch/arm/mach-tegra/fuse.c +++ b/arch/arm/mach-tegra/fuse.c @@ -21,14 +21,26 @@ #include <linux/kernel.h> #include <linux/io.h> #include <linux/export.h> +#include <linux/random.h> #include <linux/tegra-soc.h> #include "fuse.h" #include "iomap.h" #include "apbio.h" +/* Tegra20 only */ #define FUSE_UID_LOW 0x108 #define FUSE_UID_HIGH 0x10c + +/* Tegra30 and later */ +#define FUSE_VENDOR_CODE 0x200 +#define FUSE_FAB_CODE 0x204 +#define FUSE_LOT_CODE_0 0x208 +#define FUSE_LOT_CODE_1 0x20c +#define FUSE_WAFER_ID 0x210 +#define FUSE_X_COORDINATE 0x214 +#define FUSE_Y_COORDINATE 0x218 + #define FUSE_SKU_INFO 0x110 #define TEGRA20_FUSE_SPARE_BIT 0x200 @@ -112,21 +124,51 @@ u32 tegra_read_chipid(void) return readl_relaxed(IO_ADDRESS(TEGRA_APB_MISC_BASE) + 0x804); } -void tegra_init_fuse(void) +static void __init tegra20_fuse_init_randomness(void) +{ + u32 randomness[2]; + + randomness[0] = tegra_fuse_readl(FUSE_UID_LOW); + randomness[1] = tegra_fuse_readl(FUSE_UID_HIGH); + + add_device_randomness(randomness, sizeof(randomness)); +} + +/* Applies to Tegra30 or later */ +static void __init tegra30_fuse_init_randomness(void) +{ + u32 randomness[7]; + + randomness[0] = tegra_fuse_readl(FUSE_VENDOR_CODE); + randomness[1] = tegra_fuse_readl(FUSE_FAB_CODE); + randomness[2] = tegra_fuse_readl(FUSE_LOT_CODE_0); + randomness[3] = tegra_fuse_readl(FUSE_LOT_CODE_1); + randomness[4] = tegra_fuse_readl(FUSE_WAFER_ID); + randomness[5] = tegra_fuse_readl(FUSE_X_COORDINATE); + randomness[6] = tegra_fuse_readl(FUSE_Y_COORDINATE); + + add_device_randomness(randomness, sizeof(randomness)); +} + +void __init tegra_init_fuse(void) { u32 id; + u32 randomness[5]; u32 reg = readl(IO_ADDRESS(TEGRA_CLK_RESET_BASE + 0x48)); reg |= 1 << 28; writel(reg, IO_ADDRESS(TEGRA_CLK_RESET_BASE + 0x48)); reg = tegra_fuse_readl(FUSE_SKU_INFO); + randomness[0] = reg; tegra_sku_id = reg & 0xFF; reg = tegra_apb_readl(TEGRA_APB_MISC_BASE + STRAP_OPT); + randomness[1] = reg; tegra_bct_strapping = (reg & RAM_ID_MASK) >> RAM_CODE_SHIFT; id = tegra_read_chipid(); + randomness[2] = id; tegra_chip_id = (id >> 8) & 0xff; switch (tegra_chip_id) { @@ -149,6 +191,18 @@ void tegra_init_fuse(void) tegra_revision = tegra_get_revision(id); tegra_init_speedo_data(); + randomness[3] = (tegra_cpu_process_id << 16) | tegra_core_process_id; + randomness[4] = (tegra_cpu_speedo_id << 16) | tegra_soc_speedo_id; + + add_device_randomness(randomness, sizeof(randomness)); + switch (tegra_chip_id) { + case TEGRA20: + tegra20_fuse_init_randomness(); + case TEGRA30: + case TEGRA114: + default: + tegra30_fuse_init_randomness(); + } pr_info("Tegra Revision: %s SKU: %d CPU Process: %d Core Process: %d\n", tegra_revision_name[tegra_revision], diff --git a/arch/arm/mach-tegra/fuse.h b/arch/arm/mach-tegra/fuse.h index def79683bef6..c01d04785d67 100644 --- a/arch/arm/mach-tegra/fuse.h +++ b/arch/arm/mach-tegra/fuse.h @@ -29,6 +29,7 @@ #define TEGRA20 0x20 #define TEGRA30 0x30 #define TEGRA114 0x35 +#define TEGRA124 0x40 #ifndef __ASSEMBLY__ enum tegra_revision { diff --git a/arch/arm/mach-tegra/gpio-names.h b/arch/arm/mach-tegra/gpio-names.h deleted file mode 100644 index f28220a641b2..000000000000 --- a/arch/arm/mach-tegra/gpio-names.h +++ /dev/null @@ -1,247 +0,0 @@ -/* - * arch/arm/mach-tegra/include/mach/gpio-names.h - * - * Copyright (c) 2010 Google, Inc - * - * Author: - * Erik Gilling <konkers@google.com> - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that 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. - */ - -#ifndef __MACH_TEGRA_GPIO_NAMES_H -#define __MACH_TEGRA_GPIO_NAMES_H - -#define TEGRA_GPIO_PA0 0 -#define TEGRA_GPIO_PA1 1 -#define TEGRA_GPIO_PA2 2 -#define TEGRA_GPIO_PA3 3 -#define TEGRA_GPIO_PA4 4 -#define TEGRA_GPIO_PA5 5 -#define TEGRA_GPIO_PA6 6 -#define TEGRA_GPIO_PA7 7 -#define TEGRA_GPIO_PB0 8 -#define TEGRA_GPIO_PB1 9 -#define TEGRA_GPIO_PB2 10 -#define TEGRA_GPIO_PB3 11 -#define TEGRA_GPIO_PB4 12 -#define TEGRA_GPIO_PB5 13 -#define TEGRA_GPIO_PB6 14 -#define TEGRA_GPIO_PB7 15 -#define TEGRA_GPIO_PC0 16 -#define TEGRA_GPIO_PC1 17 -#define TEGRA_GPIO_PC2 18 -#define TEGRA_GPIO_PC3 19 -#define TEGRA_GPIO_PC4 20 -#define TEGRA_GPIO_PC5 21 -#define TEGRA_GPIO_PC6 22 -#define TEGRA_GPIO_PC7 23 -#define TEGRA_GPIO_PD0 24 -#define TEGRA_GPIO_PD1 25 -#define TEGRA_GPIO_PD2 26 -#define TEGRA_GPIO_PD3 27 -#define TEGRA_GPIO_PD4 28 -#define TEGRA_GPIO_PD5 29 -#define TEGRA_GPIO_PD6 30 -#define TEGRA_GPIO_PD7 31 -#define TEGRA_GPIO_PE0 32 -#define TEGRA_GPIO_PE1 33 -#define TEGRA_GPIO_PE2 34 -#define TEGRA_GPIO_PE3 35 -#define TEGRA_GPIO_PE4 36 -#define TEGRA_GPIO_PE5 37 -#define TEGRA_GPIO_PE6 38 -#define TEGRA_GPIO_PE7 39 -#define TEGRA_GPIO_PF0 40 -#define TEGRA_GPIO_PF1 41 -#define TEGRA_GPIO_PF2 42 -#define TEGRA_GPIO_PF3 43 -#define TEGRA_GPIO_PF4 44 -#define TEGRA_GPIO_PF5 45 -#define TEGRA_GPIO_PF6 46 -#define TEGRA_GPIO_PF7 47 -#define TEGRA_GPIO_PG0 48 -#define TEGRA_GPIO_PG1 49 -#define TEGRA_GPIO_PG2 50 -#define TEGRA_GPIO_PG3 51 -#define TEGRA_GPIO_PG4 52 -#define TEGRA_GPIO_PG5 53 -#define TEGRA_GPIO_PG6 54 -#define TEGRA_GPIO_PG7 55 -#define TEGRA_GPIO_PH0 56 -#define TEGRA_GPIO_PH1 57 -#define TEGRA_GPIO_PH2 58 -#define TEGRA_GPIO_PH3 59 -#define TEGRA_GPIO_PH4 60 -#define TEGRA_GPIO_PH5 61 -#define TEGRA_GPIO_PH6 62 -#define TEGRA_GPIO_PH7 63 -#define TEGRA_GPIO_PI0 64 -#define TEGRA_GPIO_PI1 65 -#define TEGRA_GPIO_PI2 66 -#define TEGRA_GPIO_PI3 67 -#define TEGRA_GPIO_PI4 68 -#define TEGRA_GPIO_PI5 69 -#define TEGRA_GPIO_PI6 70 -#define TEGRA_GPIO_PI7 71 -#define TEGRA_GPIO_PJ0 72 -#define TEGRA_GPIO_PJ1 73 -#define TEGRA_GPIO_PJ2 74 -#define TEGRA_GPIO_PJ3 75 -#define TEGRA_GPIO_PJ4 76 -#define TEGRA_GPIO_PJ5 77 -#define TEGRA_GPIO_PJ6 78 -#define TEGRA_GPIO_PJ7 79 -#define TEGRA_GPIO_PK0 80 -#define TEGRA_GPIO_PK1 81 -#define TEGRA_GPIO_PK2 82 -#define TEGRA_GPIO_PK3 83 -#define TEGRA_GPIO_PK4 84 -#define TEGRA_GPIO_PK5 85 -#define TEGRA_GPIO_PK6 86 -#define TEGRA_GPIO_PK7 87 -#define TEGRA_GPIO_PL0 88 -#define TEGRA_GPIO_PL1 89 -#define TEGRA_GPIO_PL2 90 -#define TEGRA_GPIO_PL3 91 -#define TEGRA_GPIO_PL4 92 -#define TEGRA_GPIO_PL5 93 -#define TEGRA_GPIO_PL6 94 -#define TEGRA_GPIO_PL7 95 -#define TEGRA_GPIO_PM0 96 -#define TEGRA_GPIO_PM1 97 -#define TEGRA_GPIO_PM2 98 -#define TEGRA_GPIO_PM3 99 -#define TEGRA_GPIO_PM4 100 -#define TEGRA_GPIO_PM5 101 -#define TEGRA_GPIO_PM6 102 -#define TEGRA_GPIO_PM7 103 -#define TEGRA_GPIO_PN0 104 -#define TEGRA_GPIO_PN1 105 -#define TEGRA_GPIO_PN2 106 -#define TEGRA_GPIO_PN3 107 -#define TEGRA_GPIO_PN4 108 -#define TEGRA_GPIO_PN5 109 -#define TEGRA_GPIO_PN6 110 -#define TEGRA_GPIO_PN7 111 -#define TEGRA_GPIO_PO0 112 -#define TEGRA_GPIO_PO1 113 -#define TEGRA_GPIO_PO2 114 -#define TEGRA_GPIO_PO3 115 -#define TEGRA_GPIO_PO4 116 -#define TEGRA_GPIO_PO5 117 -#define TEGRA_GPIO_PO6 118 -#define TEGRA_GPIO_PO7 119 -#define TEGRA_GPIO_PP0 120 -#define TEGRA_GPIO_PP1 121 -#define TEGRA_GPIO_PP2 122 -#define TEGRA_GPIO_PP3 123 -#define TEGRA_GPIO_PP4 124 -#define TEGRA_GPIO_PP5 125 -#define TEGRA_GPIO_PP6 126 -#define TEGRA_GPIO_PP7 127 -#define TEGRA_GPIO_PQ0 128 -#define TEGRA_GPIO_PQ1 129 -#define TEGRA_GPIO_PQ2 130 -#define TEGRA_GPIO_PQ3 131 -#define TEGRA_GPIO_PQ4 132 -#define TEGRA_GPIO_PQ5 133 -#define TEGRA_GPIO_PQ6 134 -#define TEGRA_GPIO_PQ7 135 -#define TEGRA_GPIO_PR0 136 -#define TEGRA_GPIO_PR1 137 -#define TEGRA_GPIO_PR2 138 -#define TEGRA_GPIO_PR3 139 -#define TEGRA_GPIO_PR4 140 -#define TEGRA_GPIO_PR5 141 -#define TEGRA_GPIO_PR6 142 -#define TEGRA_GPIO_PR7 143 -#define TEGRA_GPIO_PS0 144 -#define TEGRA_GPIO_PS1 145 -#define TEGRA_GPIO_PS2 146 -#define TEGRA_GPIO_PS3 147 -#define TEGRA_GPIO_PS4 148 -#define TEGRA_GPIO_PS5 149 -#define TEGRA_GPIO_PS6 150 -#define TEGRA_GPIO_PS7 151 -#define TEGRA_GPIO_PT0 152 -#define TEGRA_GPIO_PT1 153 -#define TEGRA_GPIO_PT2 154 -#define TEGRA_GPIO_PT3 155 -#define TEGRA_GPIO_PT4 156 -#define TEGRA_GPIO_PT5 157 -#define TEGRA_GPIO_PT6 158 -#define TEGRA_GPIO_PT7 159 -#define TEGRA_GPIO_PU0 160 -#define TEGRA_GPIO_PU1 161 -#define TEGRA_GPIO_PU2 162 -#define TEGRA_GPIO_PU3 163 -#define TEGRA_GPIO_PU4 164 -#define TEGRA_GPIO_PU5 165 -#define TEGRA_GPIO_PU6 166 -#define TEGRA_GPIO_PU7 167 -#define TEGRA_GPIO_PV0 168 -#define TEGRA_GPIO_PV1 169 -#define TEGRA_GPIO_PV2 170 -#define TEGRA_GPIO_PV3 171 -#define TEGRA_GPIO_PV4 172 -#define TEGRA_GPIO_PV5 173 -#define TEGRA_GPIO_PV6 174 -#define TEGRA_GPIO_PV7 175 -#define TEGRA_GPIO_PW0 176 -#define TEGRA_GPIO_PW1 177 -#define TEGRA_GPIO_PW2 178 -#define TEGRA_GPIO_PW3 179 -#define TEGRA_GPIO_PW4 180 -#define TEGRA_GPIO_PW5 181 -#define TEGRA_GPIO_PW6 182 -#define TEGRA_GPIO_PW7 183 -#define TEGRA_GPIO_PX0 184 -#define TEGRA_GPIO_PX1 185 -#define TEGRA_GPIO_PX2 186 -#define TEGRA_GPIO_PX3 187 -#define TEGRA_GPIO_PX4 188 -#define TEGRA_GPIO_PX5 189 -#define TEGRA_GPIO_PX6 190 -#define TEGRA_GPIO_PX7 191 -#define TEGRA_GPIO_PY0 192 -#define TEGRA_GPIO_PY1 193 -#define TEGRA_GPIO_PY2 194 -#define TEGRA_GPIO_PY3 195 -#define TEGRA_GPIO_PY4 196 -#define TEGRA_GPIO_PY5 197 -#define TEGRA_GPIO_PY6 198 -#define TEGRA_GPIO_PY7 199 -#define TEGRA_GPIO_PZ0 200 -#define TEGRA_GPIO_PZ1 201 -#define TEGRA_GPIO_PZ2 202 -#define TEGRA_GPIO_PZ3 203 -#define TEGRA_GPIO_PZ4 204 -#define TEGRA_GPIO_PZ5 205 -#define TEGRA_GPIO_PZ6 206 -#define TEGRA_GPIO_PZ7 207 -#define TEGRA_GPIO_PAA0 208 -#define TEGRA_GPIO_PAA1 209 -#define TEGRA_GPIO_PAA2 210 -#define TEGRA_GPIO_PAA3 211 -#define TEGRA_GPIO_PAA4 212 -#define TEGRA_GPIO_PAA5 213 -#define TEGRA_GPIO_PAA6 214 -#define TEGRA_GPIO_PAA7 215 -#define TEGRA_GPIO_PBB0 216 -#define TEGRA_GPIO_PBB1 217 -#define TEGRA_GPIO_PBB2 218 -#define TEGRA_GPIO_PBB3 219 -#define TEGRA_GPIO_PBB4 220 -#define TEGRA_GPIO_PBB5 221 -#define TEGRA_GPIO_PBB6 222 -#define TEGRA_GPIO_PBB7 223 - -#endif diff --git a/arch/arm/mach-tegra/hotplug.c b/arch/arm/mach-tegra/hotplug.c index 04de2e860923..ff26af26bd0c 100644 --- a/arch/arm/mach-tegra/hotplug.c +++ b/arch/arm/mach-tegra/hotplug.c @@ -57,4 +57,6 @@ void __init tegra_hotplug_init(void) tegra_hotplug_shutdown = tegra30_hotplug_shutdown; if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) && tegra_chip_id == TEGRA114) tegra_hotplug_shutdown = tegra30_hotplug_shutdown; + if (IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC) && tegra_chip_id == TEGRA124) + tegra_hotplug_shutdown = tegra30_hotplug_shutdown; } diff --git a/arch/arm/mach-tegra/iomap.h b/arch/arm/mach-tegra/iomap.h index 3f5fa0749bde..26b1c2ad0ceb 100644 --- a/arch/arm/mach-tegra/iomap.h +++ b/arch/arm/mach-tegra/iomap.h @@ -24,44 +24,12 @@ #define TEGRA_IRAM_BASE 0x40000000 #define TEGRA_IRAM_SIZE SZ_256K -#define TEGRA_IRAM_CODE_AREA (TEGRA_IRAM_BASE + SZ_4K) - -#define TEGRA_HOST1X_BASE 0x50000000 -#define TEGRA_HOST1X_SIZE 0x24000 - #define TEGRA_ARM_PERIF_BASE 0x50040000 #define TEGRA_ARM_PERIF_SIZE SZ_8K -#define TEGRA_ARM_PL310_BASE 0x50043000 -#define TEGRA_ARM_PL310_SIZE SZ_4K - #define TEGRA_ARM_INT_DIST_BASE 0x50041000 #define TEGRA_ARM_INT_DIST_SIZE SZ_4K -#define TEGRA_MPE_BASE 0x54040000 -#define TEGRA_MPE_SIZE SZ_256K - -#define TEGRA_VI_BASE 0x54080000 -#define TEGRA_VI_SIZE SZ_256K - -#define TEGRA_ISP_BASE 0x54100000 -#define TEGRA_ISP_SIZE SZ_256K - -#define TEGRA_DISPLAY_BASE 0x54200000 -#define TEGRA_DISPLAY_SIZE SZ_256K - -#define TEGRA_DISPLAY2_BASE 0x54240000 -#define TEGRA_DISPLAY2_SIZE SZ_256K - -#define TEGRA_HDMI_BASE 0x54280000 -#define TEGRA_HDMI_SIZE SZ_256K - -#define TEGRA_GART_BASE 0x58000000 -#define TEGRA_GART_SIZE SZ_32M - -#define TEGRA_RES_SEMA_BASE 0x60001000 -#define TEGRA_RES_SEMA_SIZE SZ_4K - #define TEGRA_PRIMARY_ICTLR_BASE 0x60004000 #define TEGRA_PRIMARY_ICTLR_SIZE SZ_64 @@ -98,51 +66,15 @@ #define TEGRA_FLOW_CTRL_BASE 0x60007000 #define TEGRA_FLOW_CTRL_SIZE 20 -#define TEGRA_AHB_DMA_BASE 0x60008000 -#define TEGRA_AHB_DMA_SIZE SZ_4K - -#define TEGRA_AHB_DMA_CH0_BASE 0x60009000 -#define TEGRA_AHB_DMA_CH0_SIZE 32 - -#define TEGRA_APB_DMA_BASE 0x6000A000 -#define TEGRA_APB_DMA_SIZE SZ_4K - -#define TEGRA_APB_DMA_CH0_BASE 0x6000B000 -#define TEGRA_APB_DMA_CH0_SIZE 32 - -#define TEGRA_AHB_GIZMO_BASE 0x6000C004 -#define TEGRA_AHB_GIZMO_SIZE 0x10C - #define TEGRA_SB_BASE 0x6000C200 #define TEGRA_SB_SIZE 256 -#define TEGRA_STATMON_BASE 0x6000C400 -#define TEGRA_STATMON_SIZE SZ_1K - -#define TEGRA_GPIO_BASE 0x6000D000 -#define TEGRA_GPIO_SIZE SZ_4K - #define TEGRA_EXCEPTION_VECTORS_BASE 0x6000F000 #define TEGRA_EXCEPTION_VECTORS_SIZE SZ_4K #define TEGRA_APB_MISC_BASE 0x70000000 #define TEGRA_APB_MISC_SIZE SZ_4K -#define TEGRA_APB_MISC_DAS_BASE 0x70000c00 -#define TEGRA_APB_MISC_DAS_SIZE SZ_128 - -#define TEGRA_AC97_BASE 0x70002000 -#define TEGRA_AC97_SIZE SZ_512 - -#define TEGRA_SPDIF_BASE 0x70002400 -#define TEGRA_SPDIF_SIZE SZ_512 - -#define TEGRA_I2S1_BASE 0x70002800 -#define TEGRA_I2S1_SIZE SZ_256 - -#define TEGRA_I2S2_BASE 0x70002A00 -#define TEGRA_I2S2_SIZE SZ_256 - #define TEGRA_UARTA_BASE 0x70006000 #define TEGRA_UARTA_SIZE SZ_64 @@ -158,108 +90,27 @@ #define TEGRA_UARTE_BASE 0x70006400 #define TEGRA_UARTE_SIZE SZ_256 -#define TEGRA_NAND_BASE 0x70008000 -#define TEGRA_NAND_SIZE SZ_256 - -#define TEGRA_HSMMC_BASE 0x70008500 -#define TEGRA_HSMMC_SIZE SZ_256 - -#define TEGRA_SNOR_BASE 0x70009000 -#define TEGRA_SNOR_SIZE SZ_4K - -#define TEGRA_PWFM_BASE 0x7000A000 -#define TEGRA_PWFM_SIZE SZ_256 - -#define TEGRA_PWFM0_BASE 0x7000A000 -#define TEGRA_PWFM0_SIZE 4 - -#define TEGRA_PWFM1_BASE 0x7000A010 -#define TEGRA_PWFM1_SIZE 4 - -#define TEGRA_PWFM2_BASE 0x7000A020 -#define TEGRA_PWFM2_SIZE 4 - -#define TEGRA_PWFM3_BASE 0x7000A030 -#define TEGRA_PWFM3_SIZE 4 - -#define TEGRA_MIPI_BASE 0x7000B000 -#define TEGRA_MIPI_SIZE SZ_256 - -#define TEGRA_I2C_BASE 0x7000C000 -#define TEGRA_I2C_SIZE SZ_256 - -#define TEGRA_TWC_BASE 0x7000C100 -#define TEGRA_TWC_SIZE SZ_256 - -#define TEGRA_SPI_BASE 0x7000C380 -#define TEGRA_SPI_SIZE 48 - -#define TEGRA_I2C2_BASE 0x7000C400 -#define TEGRA_I2C2_SIZE SZ_256 - -#define TEGRA_I2C3_BASE 0x7000C500 -#define TEGRA_I2C3_SIZE SZ_256 - -#define TEGRA_OWR_BASE 0x7000C600 -#define TEGRA_OWR_SIZE 80 - -#define TEGRA_DVC_BASE 0x7000D000 -#define TEGRA_DVC_SIZE SZ_512 - -#define TEGRA_SPI1_BASE 0x7000D400 -#define TEGRA_SPI1_SIZE SZ_512 - -#define TEGRA_SPI2_BASE 0x7000D600 -#define TEGRA_SPI2_SIZE SZ_512 - -#define TEGRA_SPI3_BASE 0x7000D800 -#define TEGRA_SPI3_SIZE SZ_512 - -#define TEGRA_SPI4_BASE 0x7000DA00 -#define TEGRA_SPI4_SIZE SZ_512 - -#define TEGRA_RTC_BASE 0x7000E000 -#define TEGRA_RTC_SIZE SZ_256 - -#define TEGRA_KBC_BASE 0x7000E200 -#define TEGRA_KBC_SIZE SZ_256 - #define TEGRA_PMC_BASE 0x7000E400 #define TEGRA_PMC_SIZE SZ_256 -#define TEGRA_MC_BASE 0x7000F000 -#define TEGRA_MC_SIZE SZ_1K - #define TEGRA_EMC_BASE 0x7000F400 #define TEGRA_EMC_SIZE SZ_1K #define TEGRA_FUSE_BASE 0x7000F800 #define TEGRA_FUSE_SIZE SZ_1K -#define TEGRA_KFUSE_BASE 0x7000FC00 -#define TEGRA_KFUSE_SIZE SZ_1K - #define TEGRA_EMC0_BASE 0x7001A000 #define TEGRA_EMC0_SIZE SZ_2K #define TEGRA_EMC1_BASE 0x7001A800 #define TEGRA_EMC1_SIZE SZ_2K +#define TEGRA124_EMC_BASE 0x7001B000 +#define TEGRA124_EMC_SIZE SZ_2K + #define TEGRA_CSITE_BASE 0x70040000 #define TEGRA_CSITE_SIZE SZ_256K -#define TEGRA_SDMMC1_BASE 0xC8000000 -#define TEGRA_SDMMC1_SIZE SZ_512 - -#define TEGRA_SDMMC2_BASE 0xC8000200 -#define TEGRA_SDMMC2_SIZE SZ_512 - -#define TEGRA_SDMMC3_BASE 0xC8000400 -#define TEGRA_SDMMC3_SIZE SZ_512 - -#define TEGRA_SDMMC4_BASE 0xC8000600 -#define TEGRA_SDMMC4_SIZE SZ_512 - /* On TEGRA, many peripherals are very closely packed in * two 256MB io windows (that actually only use about 64KB * at the start of each). diff --git a/arch/arm/mach-tegra/irammap.h b/arch/arm/mach-tegra/irammap.h index 501952a84344..e32e1742c9a1 100644 --- a/arch/arm/mach-tegra/irammap.h +++ b/arch/arm/mach-tegra/irammap.h @@ -23,4 +23,10 @@ #define TEGRA_IRAM_RESET_HANDLER_OFFSET 0 #define TEGRA_IRAM_RESET_HANDLER_SIZE SZ_1K +/* + * This area is used for LPx resume vector, only while LPx power state is + * active. At other times, the AVP may use this area for arbitrary purposes + */ +#define TEGRA_IRAM_LPx_RESUME_AREA (TEGRA_IRAM_BASE + SZ_4K) + #endif diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c index 2d0203627fbb..eb72ae709124 100644 --- a/arch/arm/mach-tegra/platsmp.c +++ b/arch/arm/mach-tegra/platsmp.c @@ -176,6 +176,8 @@ static int tegra_boot_secondary(unsigned int cpu, return tegra30_boot_secondary(cpu, idle); if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) && tegra_chip_id == TEGRA114) return tegra114_boot_secondary(cpu, idle); + if (IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC) && tegra_chip_id == TEGRA124) + return tegra114_boot_secondary(cpu, idle); return -EINVAL; } diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c index ed294a04e1d3..4ae0286b468d 100644 --- a/arch/arm/mach-tegra/pm.c +++ b/arch/arm/mach-tegra/pm.c @@ -59,8 +59,10 @@ static void tegra_tear_down_cpu_init(void) break; case TEGRA30: case TEGRA114: + case TEGRA124: if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) || - IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC)) + IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) || + IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC)) tegra_tear_down_cpu = tegra30_tear_down_cpu; break; } @@ -216,8 +218,10 @@ static bool tegra_lp1_iram_hook(void) break; case TEGRA30: case TEGRA114: + case TEGRA124: if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) || - IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC)) + IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) || + IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC)) tegra30_lp1_iram_hook(); break; default: @@ -244,8 +248,10 @@ static bool tegra_sleep_core_init(void) break; case TEGRA30: case TEGRA114: + case TEGRA124: if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) || - IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC)) + IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) || + IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC)) tegra30_sleep_core_init(); break; default: @@ -263,10 +269,10 @@ static void tegra_suspend_enter_lp1(void) tegra_pmc_suspend(); /* copy the reset vector & SDRAM shutdown code into IRAM */ - memcpy(iram_save_addr, IO_ADDRESS(TEGRA_IRAM_CODE_AREA), - iram_save_size); - memcpy(IO_ADDRESS(TEGRA_IRAM_CODE_AREA), tegra_lp1_iram.start_addr, + memcpy(iram_save_addr, IO_ADDRESS(TEGRA_IRAM_LPx_RESUME_AREA), iram_save_size); + memcpy(IO_ADDRESS(TEGRA_IRAM_LPx_RESUME_AREA), + tegra_lp1_iram.start_addr, iram_save_size); *((u32 *)tegra_cpu_lp1_mask) = 1; } @@ -276,7 +282,7 @@ static void tegra_suspend_exit_lp1(void) tegra_pmc_resume(); /* restore IRAM */ - memcpy(IO_ADDRESS(TEGRA_IRAM_CODE_AREA), iram_save_addr, + memcpy(IO_ADDRESS(TEGRA_IRAM_LPx_RESUME_AREA), iram_save_addr, iram_save_size); *(u32 *)tegra_cpu_lp1_mask = 0; diff --git a/arch/arm/mach-tegra/pm.h b/arch/arm/mach-tegra/pm.h index fe204e5256e7..6e92a7c2ecbd 100644 --- a/arch/arm/mach-tegra/pm.h +++ b/arch/arm/mach-tegra/pm.h @@ -37,9 +37,6 @@ void tegra30_sleep_core_init(void); extern unsigned long l2x0_saved_regs_addr; -void save_cpu_arch_register(void); -void restore_cpu_arch_register(void); - void tegra_clear_cpu_in_lp2(void); bool tegra_set_cpu_in_lp2(void); diff --git a/arch/arm/mach-tegra/pmc.c b/arch/arm/mach-tegra/pmc.c index 8acb881f7cfe..fb7920201ab4 100644 --- a/arch/arm/mach-tegra/pmc.c +++ b/arch/arm/mach-tegra/pmc.c @@ -20,6 +20,7 @@ #include <linux/io.h> #include <linux/of.h> #include <linux/of_address.h> +#include <linux/tegra-powergate.h> #include "flowctrl.h" #include "fuse.h" @@ -43,12 +44,6 @@ #define PMC_CPUPWRGOOD_TIMER 0xc8 #define PMC_CPUPWROFF_TIMER 0xcc -#define TEGRA_POWERGATE_PCIE 3 -#define TEGRA_POWERGATE_VDEC 4 -#define TEGRA_POWERGATE_CPU1 9 -#define TEGRA_POWERGATE_CPU2 10 -#define TEGRA_POWERGATE_CPU3 11 - static u8 tegra_cpu_domains[] = { 0xFF, /* not available for CPU0 */ TEGRA_POWERGATE_CPU1, @@ -166,6 +161,15 @@ int tegra_pmc_cpu_remove_clamping(int cpuid) return tegra_pmc_powergate_remove_clamping(id); } +void tegra_pmc_restart(enum reboot_mode mode, const char *cmd) +{ + u32 val; + + val = tegra_pmc_readl(0); + val |= 0x10; + tegra_pmc_writel(val, 0); +} + #ifdef CONFIG_PM_SLEEP static void set_power_timers(u32 us_on, u32 us_off, unsigned long rate) { @@ -279,19 +283,17 @@ void tegra_pmc_suspend_init(void) #endif static const struct of_device_id matches[] __initconst = { + { .compatible = "nvidia,tegra124-pmc" }, { .compatible = "nvidia,tegra114-pmc" }, { .compatible = "nvidia,tegra30-pmc" }, { .compatible = "nvidia,tegra20-pmc" }, { } }; -static void __init tegra_pmc_parse_dt(void) +void __init tegra_pmc_init_irq(void) { struct device_node *np; - u32 prop; - enum tegra_suspend_mode suspend_mode; - u32 core_good_time[2] = {0, 0}; - u32 lp0_vec[2] = {0, 0}; + u32 val; np = of_find_matching_node(NULL, matches); BUG_ON(!np); @@ -300,6 +302,26 @@ static void __init tegra_pmc_parse_dt(void) tegra_pmc_invert_interrupt = of_property_read_bool(np, "nvidia,invert-interrupt"); + + val = tegra_pmc_readl(PMC_CTRL); + if (tegra_pmc_invert_interrupt) + val |= PMC_CTRL_INTR_LOW; + else + val &= ~PMC_CTRL_INTR_LOW; + tegra_pmc_writel(val, PMC_CTRL); +} + +void __init tegra_pmc_init(void) +{ + struct device_node *np; + u32 prop; + enum tegra_suspend_mode suspend_mode; + u32 core_good_time[2] = {0, 0}; + u32 lp0_vec[2] = {0, 0}; + + np = of_find_matching_node(NULL, matches); + BUG_ON(!np); + tegra_pclk = of_clk_get_by_name(np, "pclk"); WARN_ON(IS_ERR(tegra_pclk)); @@ -365,17 +387,3 @@ static void __init tegra_pmc_parse_dt(void) pmc_pm_data.suspend_mode = suspend_mode; } - -void __init tegra_pmc_init(void) -{ - u32 val; - - tegra_pmc_parse_dt(); - - val = tegra_pmc_readl(PMC_CTRL); - if (tegra_pmc_invert_interrupt) - val |= PMC_CTRL_INTR_LOW; - else - val &= ~PMC_CTRL_INTR_LOW; - tegra_pmc_writel(val, PMC_CTRL); -} diff --git a/arch/arm/mach-tegra/pmc.h b/arch/arm/mach-tegra/pmc.h index 549f8c7b762c..59e19c344298 100644 --- a/arch/arm/mach-tegra/pmc.h +++ b/arch/arm/mach-tegra/pmc.h @@ -18,6 +18,8 @@ #ifndef __MACH_TEGRA_PMC_H #define __MACH_TEGRA_PMC_H +#include <linux/reboot.h> + enum tegra_suspend_mode { TEGRA_SUSPEND_NONE = 0, TEGRA_SUSPEND_LP2, /* CPU voltage off */ @@ -39,6 +41,9 @@ bool tegra_pmc_cpu_is_powered(int cpuid); int tegra_pmc_cpu_power_on(int cpuid); int tegra_pmc_cpu_remove_clamping(int cpuid); +void tegra_pmc_restart(enum reboot_mode mode, const char *cmd); + +void tegra_pmc_init_irq(void); void tegra_pmc_init(void); #endif diff --git a/arch/arm/mach-tegra/powergate.c b/arch/arm/mach-tegra/powergate.c index f076f0f80fcd..85d28e756bb7 100644 --- a/arch/arm/mach-tegra/powergate.c +++ b/arch/arm/mach-tegra/powergate.c @@ -42,8 +42,16 @@ static int tegra_num_powerdomains; static int tegra_num_cpu_domains; -static u8 *tegra_cpu_domains; -static u8 tegra30_cpu_domains[] = { +static const u8 *tegra_cpu_domains; + +static const u8 tegra30_cpu_domains[] = { + TEGRA_POWERGATE_CPU, + TEGRA_POWERGATE_CPU1, + TEGRA_POWERGATE_CPU2, + TEGRA_POWERGATE_CPU3, +}; + +static const u8 tegra114_cpu_domains[] = { TEGRA_POWERGATE_CPU0, TEGRA_POWERGATE_CPU1, TEGRA_POWERGATE_CPU2, @@ -189,6 +197,11 @@ int __init tegra_powergate_init(void) tegra_num_cpu_domains = 4; tegra_cpu_domains = tegra30_cpu_domains; break; + case TEGRA114: + tegra_num_powerdomains = 23; + tegra_num_cpu_domains = 4; + tegra_cpu_domains = tegra114_cpu_domains; + break; default: /* Unknown Tegra variant. Disable powergating */ tegra_num_powerdomains = 0; @@ -229,6 +242,27 @@ static const char * const powergate_name_t30[] = { [TEGRA_POWERGATE_3D1] = "3d1", }; +static const char * const powergate_name_t114[] = { + [TEGRA_POWERGATE_CPU] = "cpu0", + [TEGRA_POWERGATE_3D] = "3d", + [TEGRA_POWERGATE_VENC] = "venc", + [TEGRA_POWERGATE_VDEC] = "vdec", + [TEGRA_POWERGATE_MPE] = "mpe", + [TEGRA_POWERGATE_HEG] = "heg", + [TEGRA_POWERGATE_CPU1] = "cpu1", + [TEGRA_POWERGATE_CPU2] = "cpu2", + [TEGRA_POWERGATE_CPU3] = "cpu3", + [TEGRA_POWERGATE_CELP] = "celp", + [TEGRA_POWERGATE_CPU0] = "cpu0", + [TEGRA_POWERGATE_C0NC] = "c0nc", + [TEGRA_POWERGATE_C1NC] = "c1nc", + [TEGRA_POWERGATE_DIS] = "dis", + [TEGRA_POWERGATE_DISB] = "disb", + [TEGRA_POWERGATE_XUSBA] = "xusba", + [TEGRA_POWERGATE_XUSBB] = "xusbb", + [TEGRA_POWERGATE_XUSBC] = "xusbc", +}; + static int powergate_show(struct seq_file *s, void *data) { int i; @@ -236,9 +270,14 @@ static int powergate_show(struct seq_file *s, void *data) seq_printf(s, " powergate powered\n"); seq_printf(s, "------------------\n"); - for (i = 0; i < tegra_num_powerdomains; i++) + for (i = 0; i < tegra_num_powerdomains; i++) { + if (!powergate_name[i]) + continue; + seq_printf(s, " %9s %7s\n", powergate_name[i], tegra_powergate_is_powered(i) ? "yes" : "no"); + } + return 0; } @@ -265,6 +304,9 @@ int __init tegra_powergate_debugfs_init(void) case TEGRA30: powergate_name = powergate_name_t30; break; + case TEGRA114: + powergate_name = powergate_name_t114; + break; } if (powergate_name) { diff --git a/arch/arm/mach-tegra/reset-handler.S b/arch/arm/mach-tegra/reset-handler.S index f527b2c2dea7..8c1ba4fea384 100644 --- a/arch/arm/mach-tegra/reset-handler.S +++ b/arch/arm/mach-tegra/reset-handler.S @@ -45,17 +45,11 @@ ENTRY(tegra_resume) check_cpu_part_num 0xc09, r8, r9 bleq v7_invalidate_l1 - blne tegra_init_l2_for_a15 cpu_id r0 - tegra_get_soc_id TEGRA_APB_MISC_BASE, r6 - cmp r6, #TEGRA114 - beq no_cpu0_chk - cmp r0, #0 @ CPU0? THUMB( it ne ) bne cpu_resume @ no -no_cpu0_chk: /* Are we on Tegra20? */ cmp r6, #TEGRA20 @@ -75,7 +69,7 @@ no_cpu0_chk: mov32 r9, 0xc09 cmp r8, r9 - bne not_ca9 + bne end_ca9_scu_l2_resume #ifdef CONFIG_HAVE_ARM_SCU /* enable SCU */ mov32 r0, TEGRA_ARM_PERIF_BASE @@ -86,7 +80,10 @@ no_cpu0_chk: /* L2 cache resume & re-enable */ l2_cache_resume r0, r1, r2, l2x0_saved_regs_addr -not_ca9: +end_ca9_scu_l2_resume: + mov32 r9, 0xc0f + cmp r8, r9 + bleq tegra_init_l2_for_a15 b cpu_resume ENDPROC(tegra_resume) diff --git a/arch/arm/mach-tegra/reset.c b/arch/arm/mach-tegra/reset.c index fd0bbf8a6c94..568f5bbf979d 100644 --- a/arch/arm/mach-tegra/reset.c +++ b/arch/arm/mach-tegra/reset.c @@ -82,7 +82,7 @@ void __init tegra_cpu_reset_handler_init(void) #ifdef CONFIG_PM_SLEEP __tegra_cpu_reset_handler_data[TEGRA_RESET_STARTUP_LP1] = - TEGRA_IRAM_CODE_AREA; + TEGRA_IRAM_LPx_RESUME_AREA; __tegra_cpu_reset_handler_data[TEGRA_RESET_STARTUP_LP2] = virt_to_phys((void *)tegra_resume); #endif diff --git a/arch/arm/mach-tegra/sleep-tegra20.S b/arch/arm/mach-tegra/sleep-tegra20.S index 5c3bd11c9838..aaaf3abd2688 100644 --- a/arch/arm/mach-tegra/sleep-tegra20.S +++ b/arch/arm/mach-tegra/sleep-tegra20.S @@ -25,6 +25,7 @@ #include <asm/cp15.h> #include <asm/cache.h> +#include "irammap.h" #include "sleep.h" #include "flowctrl.h" @@ -235,7 +236,7 @@ ENTRY(tegra20_sleep_core_finish) mov32 r0, tegra20_tear_down_core mov32 r1, tegra20_iram_start sub r0, r0, r1 - mov32 r1, TEGRA_IRAM_CODE_AREA + mov32 r1, TEGRA_IRAM_LPx_RESUME_AREA add r0, r0, r1 mov pc, r3 @@ -328,7 +329,7 @@ tegra20_iram_start: * The physical address of tegra_resume expected to be stored in * PMC_SCRATCH41. * - * NOTE: THIS *MUST* BE RELOCATED TO TEGRA_IRAM_CODE_AREA. + * NOTE: THIS *MUST* BE RELOCATED TO TEGRA_IRAM_LPx_RESUME_AREA. */ ENTRY(tegra20_lp1_reset) /* diff --git a/arch/arm/mach-tegra/sleep-tegra30.S b/arch/arm/mach-tegra/sleep-tegra30.S index 63fa91b5fafb..b16d4a57fa59 100644 --- a/arch/arm/mach-tegra/sleep-tegra30.S +++ b/arch/arm/mach-tegra/sleep-tegra30.S @@ -20,6 +20,7 @@ #include <asm/asm-offsets.h> #include <asm/cache.h> +#include "irammap.h" #include "fuse.h" #include "sleep.h" #include "flowctrl.h" @@ -262,7 +263,7 @@ ENTRY(tegra30_sleep_core_finish) mov32 r0, tegra30_tear_down_core mov32 r1, tegra30_iram_start sub r0, r0, r1 - mov32 r1, TEGRA_IRAM_CODE_AREA + mov32 r1, TEGRA_IRAM_LPx_RESUME_AREA add r0, r0, r1 mov pc, r3 @@ -314,7 +315,7 @@ tegra30_iram_start: * The physical address of tegra_resume expected to be stored in * PMC_SCRATCH41. * - * NOTE: THIS *MUST* BE RELOCATED TO TEGRA_IRAM_CODE_AREA. + * NOTE: THIS *MUST* BE RELOCATED TO TEGRA_IRAM_LPx_RESUME_AREA. */ ENTRY(tegra30_lp1_reset) /* @@ -382,7 +383,7 @@ _pll_m_c_x_done: add r1, r1, #LOCK_DELAY wait_until r1, r7, r3 - adr r5, tegra30_sdram_pad_save + adr r5, tegra_sdram_pad_save ldr r4, [r5, #0x18] @ restore CLK_SOURCE_MSELECT str r4, [r0, #CLK_RESET_CLK_SOURCE_MSELECT] @@ -407,8 +408,12 @@ _pll_m_c_x_done: cmp r10, #TEGRA30 movweq r0, #:lower16:TEGRA_EMC_BASE @ r0 reserved for emc base movteq r0, #:upper16:TEGRA_EMC_BASE - movwne r0, #:lower16:TEGRA_EMC0_BASE - movtne r0, #:upper16:TEGRA_EMC0_BASE + cmp r10, #TEGRA114 + movweq r0, #:lower16:TEGRA_EMC0_BASE + movteq r0, #:upper16:TEGRA_EMC0_BASE + cmp r10, #TEGRA124 + movweq r0, #:lower16:TEGRA124_EMC_BASE + movteq r0, #:upper16:TEGRA124_EMC_BASE exit_self_refresh: ldr r1, [r5, #0xC] @ restore EMC_XM2VTTGENPADCTRL @@ -537,6 +542,7 @@ tegra30_sdram_pad_address: .word TEGRA_PMC_BASE + PMC_IO_DPD_STATUS @0x14 .word TEGRA_CLK_RESET_BASE + CLK_RESET_CLK_SOURCE_MSELECT @0x18 .word TEGRA_CLK_RESET_BASE + CLK_RESET_SCLK_BURST @0x1c +tegra30_sdram_pad_address_end: tegra114_sdram_pad_address: .word TEGRA_EMC0_BASE + EMC_CFG @0x0 @@ -552,16 +558,28 @@ tegra114_sdram_pad_address: .word TEGRA_EMC1_BASE + EMC_AUTO_CAL_INTERVAL @0x28 .word TEGRA_EMC1_BASE + EMC_XM2VTTGENPADCTRL @0x2c .word TEGRA_EMC1_BASE + EMC_XM2VTTGENPADCTRL2 @0x30 +tegra114_sdram_pad_adress_end: + +tegra124_sdram_pad_address: + .word TEGRA124_EMC_BASE + EMC_CFG @0x0 + .word TEGRA124_EMC_BASE + EMC_ZCAL_INTERVAL @0x4 + .word TEGRA124_EMC_BASE + EMC_AUTO_CAL_INTERVAL @0x8 + .word TEGRA124_EMC_BASE + EMC_XM2VTTGENPADCTRL @0xc + .word TEGRA124_EMC_BASE + EMC_XM2VTTGENPADCTRL2 @0x10 + .word TEGRA_PMC_BASE + PMC_IO_DPD_STATUS @0x14 + .word TEGRA_CLK_RESET_BASE + CLK_RESET_CLK_SOURCE_MSELECT @0x18 + .word TEGRA_CLK_RESET_BASE + CLK_RESET_SCLK_BURST @0x1c +tegra124_sdram_pad_address_end: tegra30_sdram_pad_size: - .word tegra114_sdram_pad_address - tegra30_sdram_pad_address + .word tegra30_sdram_pad_address_end - tegra30_sdram_pad_address tegra114_sdram_pad_size: - .word tegra30_sdram_pad_size - tegra114_sdram_pad_address + .word tegra114_sdram_pad_adress_end - tegra114_sdram_pad_address - .type tegra30_sdram_pad_save, %object -tegra30_sdram_pad_save: - .rept (tegra30_sdram_pad_size - tegra114_sdram_pad_address) / 4 + .type tegra_sdram_pad_save, %object +tegra_sdram_pad_save: + .rept (tegra114_sdram_pad_adress_end - tegra114_sdram_pad_address) / 4 .long 0 .endr @@ -692,13 +710,18 @@ halted: */ tegra30_sdram_self_refresh: - adr r8, tegra30_sdram_pad_save + adr r8, tegra_sdram_pad_save tegra_get_soc_id TEGRA_APB_MISC_BASE, r10 cmp r10, #TEGRA30 adreq r2, tegra30_sdram_pad_address ldreq r3, tegra30_sdram_pad_size - adrne r2, tegra114_sdram_pad_address - ldrne r3, tegra114_sdram_pad_size + cmp r10, #TEGRA114 + adreq r2, tegra114_sdram_pad_address + ldreq r3, tegra114_sdram_pad_size + cmp r10, #TEGRA124 + adreq r2, tegra124_sdram_pad_address + ldreq r3, tegra30_sdram_pad_size + mov r9, #0 padsave: @@ -716,7 +739,10 @@ padsave_done: cmp r10, #TEGRA30 ldreq r0, =TEGRA_EMC_BASE @ r0 reserved for emc base addr - ldrne r0, =TEGRA_EMC0_BASE + cmp r10, #TEGRA114 + ldreq r0, =TEGRA_EMC0_BASE + cmp r10, #TEGRA124 + ldreq r0, =TEGRA124_EMC_BASE enter_self_refresh: cmp r10, #TEGRA30 diff --git a/arch/arm/mach-tegra/tegra.c b/arch/arm/mach-tegra/tegra.c index 5b8605547a09..73368176c6e8 100644 --- a/arch/arm/mach-tegra/tegra.c +++ b/arch/arm/mach-tegra/tegra.c @@ -16,7 +16,6 @@ * */ -#include <linux/clocksource.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/platform_device.h> @@ -34,16 +33,78 @@ #include <linux/sys_soc.h> #include <linux/usb/tegra_usb_phy.h> #include <linux/clk/tegra.h> +#include <linux/irqchip.h> +#include <asm/hardware/cache-l2x0.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/time.h> #include <asm/setup.h> +#include "apbio.h" #include "board.h" #include "common.h" +#include "cpuidle.h" #include "fuse.h" #include "iomap.h" +#include "irq.h" +#include "pmc.h" +#include "pm.h" +#include "reset.h" +#include "sleep.h" + +/* + * Storage for debug-macro.S's state. + * + * This must be in .data not .bss so that it gets initialized each time the + * kernel is loaded. The data is declared here rather than debug-macro.S so + * that multiple inclusions of debug-macro.S point at the same data. + */ +u32 tegra_uart_config[4] = { + /* Debug UART initialization required */ + 1, + /* Debug UART physical address */ + 0, + /* Debug UART virtual address */ + 0, + /* Scratch space for debug macro */ + 0, +}; + +static void __init tegra_init_cache(void) +{ +#ifdef CONFIG_CACHE_L2X0 + int ret; + void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000; + u32 aux_ctrl, cache_type; + + cache_type = readl(p + L2X0_CACHE_TYPE); + aux_ctrl = (cache_type & 0x700) << (17-8); + aux_ctrl |= 0x7C400001; + + ret = l2x0_of_init(aux_ctrl, 0x8200c3fe); + if (!ret) + l2x0_saved_regs_addr = virt_to_phys(&l2x0_saved_regs); +#endif +} + +static void __init tegra_init_early(void) +{ + tegra_apb_io_init(); + tegra_init_fuse(); + tegra_cpu_reset_handler_init(); + tegra_init_cache(); + tegra_powergate_init(); + tegra_hotplug_init(); +} + +static void __init tegra_dt_init_irq(void) +{ + tegra_pmc_init_irq(); + tegra_init_irq(); + irqchip_init(); + tegra_legacy_irq_syscore_init(); +} static void __init tegra_dt_init(void) { @@ -51,6 +112,8 @@ static void __init tegra_dt_init(void) struct soc_device *soc_dev; struct device *parent = NULL; + tegra_pmc_init(); + tegra_clocks_apply_init_table(); soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); @@ -97,7 +160,9 @@ static void __init tegra_dt_init_late(void) { int i; - tegra_init_late(); + tegra_init_suspend(); + tegra_cpuidle_init(); + tegra_powergate_debugfs_init(); for (i = 0; i < ARRAY_SIZE(board_init_funcs); i++) { if (of_machine_is_compatible(board_init_funcs[i].machine)) { @@ -108,6 +173,7 @@ static void __init tegra_dt_init_late(void) } static const char * const tegra_dt_board_compat[] = { + "nvidia,tegra124", "nvidia,tegra114", "nvidia,tegra30", "nvidia,tegra20", @@ -119,9 +185,8 @@ DT_MACHINE_START(TEGRA_DT, "NVIDIA Tegra SoC (Flattened Device Tree)") .smp = smp_ops(tegra_smp_ops), .init_early = tegra_init_early, .init_irq = tegra_dt_init_irq, - .init_time = clocksource_of_init, .init_machine = tegra_dt_init, .init_late = tegra_dt_init_late, - .restart = tegra_assert_system_reset, + .restart = tegra_pmc_restart, .dt_compat = tegra_dt_board_compat, MACHINE_END diff --git a/arch/arm/mach-u300/Kconfig b/arch/arm/mach-u300/Kconfig index a1659863bfd5..8e23071bd1b3 100644 --- a/arch/arm/mach-u300/Kconfig +++ b/arch/arm/mach-u300/Kconfig @@ -5,7 +5,6 @@ config ARCH_U300 select ARM_AMBA select ARM_PATCH_PHYS_VIRT select ARM_VIC - select CLKDEV_LOOKUP select CLKSRC_MMIO select CLKSRC_OF select COMMON_CLK diff --git a/arch/arm/mach-u300/timer.c b/arch/arm/mach-u300/timer.c index b5db207dfd1e..9a5f9fb352ce 100644 --- a/arch/arm/mach-u300/timer.c +++ b/arch/arm/mach-u300/timer.c @@ -358,8 +358,7 @@ static struct delay_timer u300_delay_timer; */ static void __init u300_timer_init_of(struct device_node *np) { - struct resource irq_res; - int irq; + unsigned int irq; struct clk *clk; unsigned long rate; @@ -368,11 +367,11 @@ static void __init u300_timer_init_of(struct device_node *np) panic("could not ioremap system timer\n"); /* Get the IRQ for the GP1 timer */ - irq = of_irq_to_resource(np, 2, &irq_res); - if (irq <= 0) + irq = irq_of_parse_and_map(np, 2); + if (!irq) panic("no IRQ for system timer\n"); - pr_info("U300 GP1 timer @ base: %p, IRQ: %d\n", u300_timer_base, irq); + pr_info("U300 GP1 timer @ base: %p, IRQ: %u\n", u300_timer_base, irq); /* Clock the interrupt controller */ clk = of_clk_get(np, 0); diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig index 99a28d628297..0034d2cd6973 100644 --- a/arch/arm/mach-ux500/Kconfig +++ b/arch/arm/mach-ux500/Kconfig @@ -1,40 +1,34 @@ config ARCH_U8500 bool "ST-Ericsson U8500 Series" if ARCH_MULTI_V7 depends on MMU + select AB8500_CORE + select ABX500_CORE select ARCH_HAS_CPUFREQ select ARCH_REQUIRE_GPIOLIB select ARM_AMBA - select CLKDEV_LOOKUP + select ARM_ERRATA_754322 + select ARM_ERRATA_764369 if SMP + select ARM_GIC + select CACHE_L2X0 + select CLKSRC_NOMADIK_MTU + select COMMON_CLK select CPU_V7 select GENERIC_CLOCKEVENTS select HAVE_ARM_SCU if SMP select HAVE_ARM_TWD if SMP select HAVE_SMP select MIGHT_HAVE_CACHE_L2X0 + select PINCTRL + select PINCTRL_ABX500 + select PINCTRL_NOMADIK + select PL310_ERRATA_753970 if CACHE_PL310 help Support for ST-Ericsson's Ux500 architecture if ARCH_U8500 -config UX500_SOC_COMMON - bool - default y - select ABX500_CORE - select AB8500_CORE - select ARM_ERRATA_754322 - select ARM_ERRATA_764369 if SMP - select ARM_GIC - select CACHE_L2X0 - select CLKSRC_NOMADIK_MTU - select COMMON_CLK - select PINCTRL - select PINCTRL_NOMADIK - select PINCTRL_ABX500 - select PL310_ERRATA_753970 if CACHE_PL310 - config UX500_SOC_DB8500 bool - select CPU_FREQ_TABLE if CPU_FREQ select MFD_DB8500_PRCMU select PINCTRL_DB8500 select PINCTRL_DB8540 diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile index fe1f3e26b88b..616b96e86ad4 100644 --- a/arch/arm/mach-ux500/Makefile +++ b/arch/arm/mach-ux500/Makefile @@ -2,14 +2,11 @@ # Makefile for the linux kernel, U8500 machine. # -obj-y := cpu.o devices.o devices-common.o \ - id.o usb.o timer.o pm.o +obj-y := cpu.o devices.o id.o timer.o pm.o obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o obj-$(CONFIG_MACH_MOP500) += board-mop500.o board-mop500-sdi.o \ board-mop500-regulators.o \ - board-mop500-uib.o board-mop500-stuib.o \ - board-mop500-u8500uib.o \ board-mop500-pins.o \ board-mop500-audio.o obj-$(CONFIG_SMP) += platsmp.o headsmp.o diff --git a/arch/arm/mach-ux500/board-mop500-audio.c b/arch/arm/mach-ux500/board-mop500-audio.c index ec0807247e60..154e15f59702 100644 --- a/arch/arm/mach-ux500/board-mop500-audio.c +++ b/arch/arm/mach-ux500/board-mop500-audio.c @@ -68,40 +68,6 @@ static struct stedma40_chan_cfg msp2_dma_tx = { .phy_channel = 1, }; -static struct platform_device *db8500_add_msp_i2s(struct device *parent, - int id, - resource_size_t base, int irq, - struct msp_i2s_platform_data *pdata) -{ - struct platform_device *pdev; - struct resource res[] = { - DEFINE_RES_MEM(base, SZ_4K), - DEFINE_RES_IRQ(irq), - }; - - pr_info("Register platform-device 'ux500-msp-i2s', id %d, irq %d\n", - id, irq); - pdev = platform_device_register_resndata(parent, "ux500-msp-i2s", id, - res, ARRAY_SIZE(res), - pdata, sizeof(*pdata)); - if (!pdev) { - pr_err("Failed to register platform-device 'ux500-msp-i2s.%d'!\n", - id); - return NULL; - } - - return pdev; -} - -/* Platform device for ASoC MOP500 machine */ -static struct platform_device snd_soc_mop500 = { - .name = "snd-soc-mop500", - .id = 0, - .dev = { - .platform_data = NULL, - }, -}; - struct msp_i2s_platform_data msp2_platform_data = { .id = MSP_I2S_2, .msp_i2s_dma_rx = &msp2_dma_rx, @@ -113,19 +79,3 @@ struct msp_i2s_platform_data msp3_platform_data = { .msp_i2s_dma_rx = &msp1_dma_rx, .msp_i2s_dma_tx = NULL, }; - -void mop500_audio_init(struct device *parent) -{ - pr_info("%s: Register platform-device 'snd-soc-mop500'.\n", __func__); - platform_device_register(&snd_soc_mop500); - - pr_info("Initialize MSP I2S-devices.\n"); - db8500_add_msp_i2s(parent, 0, U8500_MSP0_BASE, IRQ_DB8500_MSP0, - &msp0_platform_data); - db8500_add_msp_i2s(parent, 1, U8500_MSP1_BASE, IRQ_DB8500_MSP1, - &msp1_platform_data); - db8500_add_msp_i2s(parent, 2, U8500_MSP2_BASE, IRQ_DB8500_MSP2, - &msp2_platform_data); - db8500_add_msp_i2s(parent, 3, U8500_MSP3_BASE, IRQ_DB8500_MSP1, - &msp3_platform_data); -} diff --git a/arch/arm/mach-ux500/board-mop500-sdi.c b/arch/arm/mach-ux500/board-mop500-sdi.c index b3e61a38e5c8..26600a1c5319 100644 --- a/arch/arm/mach-ux500/board-mop500-sdi.c +++ b/arch/arm/mach-ux500/board-mop500-sdi.c @@ -65,18 +65,6 @@ struct mmci_platform_data mop500_sdi0_data = { #endif }; -static void sdi0_configure(struct device *parent) -{ - /* Add the device, force v2 to subrevision 1 */ - db8500_add_sdi0(parent, &mop500_sdi0_data, U8500_SDI_V2_PERIPHID); -} - -void mop500_sdi_tc35892_init(struct device *parent) -{ - mop500_sdi0_data.gpio_cd = GPIO_SDMMC_CD; - sdi0_configure(parent); -} - /* * SDI1 (SDIO WLAN) */ @@ -178,42 +166,3 @@ struct mmci_platform_data mop500_sdi4_data = { .dma_tx_param = &mop500_sdi4_dma_cfg_tx, #endif }; - -void __init mop500_sdi_init(struct device *parent) -{ - /* PoP:ed eMMC */ - db8500_add_sdi2(parent, &mop500_sdi2_data, U8500_SDI_V2_PERIPHID); - /* On-board eMMC */ - db8500_add_sdi4(parent, &mop500_sdi4_data, U8500_SDI_V2_PERIPHID); - - /* - * On boards with the TC35892 GPIO expander, sdi0 will finally - * be added when the TC35892 initializes and calls - * mop500_sdi_tc35892_init() above. - */ -} - -void __init snowball_sdi_init(struct device *parent) -{ - /* On Snowball MMC_CAP_SD_HIGHSPEED isn't supported (Hardware issue?) */ - mop500_sdi0_data.capabilities &= ~MMC_CAP_SD_HIGHSPEED; - /* On-board eMMC */ - db8500_add_sdi4(parent, &mop500_sdi4_data, U8500_SDI_V2_PERIPHID); - /* External Micro SD slot */ - mop500_sdi0_data.gpio_cd = SNOWBALL_SDMMC_CD_GPIO; - mop500_sdi0_data.cd_invert = true; - sdi0_configure(parent); -} - -void __init hrefv60_sdi_init(struct device *parent) -{ - /* PoP:ed eMMC */ - db8500_add_sdi2(parent, &mop500_sdi2_data, U8500_SDI_V2_PERIPHID); - /* On-board eMMC */ - db8500_add_sdi4(parent, &mop500_sdi4_data, U8500_SDI_V2_PERIPHID); - /* External Micro SD slot */ - mop500_sdi0_data.gpio_cd = HREFV60_SDMMC_CD_GPIO; - sdi0_configure(parent); - /* WLAN SDIO channel */ - db8500_add_sdi1(parent, &mop500_sdi1_data, U8500_SDI_V2_PERIPHID); -} diff --git a/arch/arm/mach-ux500/board-mop500-stuib.c b/arch/arm/mach-ux500/board-mop500-stuib.c deleted file mode 100644 index 7e1f294f0434..000000000000 --- a/arch/arm/mach-ux500/board-mop500-stuib.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) ST-Ericsson SA 2010 - * - * License terms: GNU General Public License (GPL), version 2 - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/mfd/stmpe.h> -#include <linux/input/bu21013.h> -#include <linux/gpio.h> -#include <linux/interrupt.h> -#include <linux/i2c.h> -#include <linux/input/matrix_keypad.h> -#include <asm/mach-types.h> - -#include "board-mop500.h" - -/* STMPE/SKE keypad use this key layout */ -static const unsigned int mop500_keymap[] = { - KEY(2, 5, KEY_END), - KEY(4, 1, KEY_POWER), - KEY(3, 5, KEY_VOLUMEDOWN), - KEY(1, 3, KEY_3), - KEY(5, 2, KEY_RIGHT), - KEY(5, 0, KEY_9), - - KEY(0, 5, KEY_MENU), - KEY(7, 6, KEY_ENTER), - KEY(4, 5, KEY_0), - KEY(6, 7, KEY_2), - KEY(3, 4, KEY_UP), - KEY(3, 3, KEY_DOWN), - - KEY(6, 4, KEY_SEND), - KEY(6, 2, KEY_BACK), - KEY(4, 2, KEY_VOLUMEUP), - KEY(5, 5, KEY_1), - KEY(4, 3, KEY_LEFT), - KEY(3, 2, KEY_7), -}; - -static const struct matrix_keymap_data mop500_keymap_data = { - .keymap = mop500_keymap, - .keymap_size = ARRAY_SIZE(mop500_keymap), -}; -/* - * STMPE1601 - */ -static struct stmpe_keypad_platform_data stmpe1601_keypad_data = { - .debounce_ms = 64, - .scan_count = 8, - .no_autorepeat = true, - .keymap_data = &mop500_keymap_data, -}; - -static struct stmpe_platform_data stmpe1601_data = { - .id = 1, - .blocks = STMPE_BLOCK_KEYPAD, - .irq_trigger = IRQF_TRIGGER_FALLING, - .irq_base = MOP500_STMPE1601_IRQ(0), - .keypad = &stmpe1601_keypad_data, - .autosleep = true, - .autosleep_timeout = 1024, -}; - -static struct i2c_board_info __initdata mop500_i2c0_devices_stuib[] = { - { - I2C_BOARD_INFO("stmpe1601", 0x40), - .irq = NOMADIK_GPIO_TO_IRQ(218), - .platform_data = &stmpe1601_data, - .flags = I2C_CLIENT_WAKE, - }, -}; - -/* - * BU21013 ROHM touchscreen interface on the STUIBs - */ - -#define TOUCH_GPIO_PIN 84 - -#define TOUCH_XMAX 384 -#define TOUCH_YMAX 704 - -#define PRCMU_CLOCK_OCR 0x1CC -#define TSC_EXT_CLOCK_9_6MHZ 0x840000 - -static struct bu21013_platform_device tsc_plat_device = { - .touch_pin = TOUCH_GPIO_PIN, - .touch_x_max = TOUCH_XMAX, - .touch_y_max = TOUCH_YMAX, - .ext_clk = false, - .x_flip = false, - .y_flip = true, -}; - -static struct i2c_board_info __initdata u8500_i2c3_devices_stuib[] = { - { - I2C_BOARD_INFO("bu21013_tp", 0x5C), - .platform_data = &tsc_plat_device, - }, - { - I2C_BOARD_INFO("bu21013_tp", 0x5D), - .platform_data = &tsc_plat_device, - }, -}; - -void __init mop500_stuib_init(void) -{ - if (machine_is_hrefv60()) - tsc_plat_device.cs_pin = HREFV60_TOUCH_RST_GPIO; - else - tsc_plat_device.cs_pin = GPIO_BU21013_CS; - - mop500_uib_i2c_add(0, mop500_i2c0_devices_stuib, - ARRAY_SIZE(mop500_i2c0_devices_stuib)); - - mop500_uib_i2c_add(3, u8500_i2c3_devices_stuib, - ARRAY_SIZE(u8500_i2c3_devices_stuib)); -} diff --git a/arch/arm/mach-ux500/board-mop500-u8500uib.c b/arch/arm/mach-ux500/board-mop500-u8500uib.c deleted file mode 100644 index d397c19570af..000000000000 --- a/arch/arm/mach-ux500/board-mop500-u8500uib.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) ST-Ericsson SA 2010 - * - * Board data for the U8500 UIB, also known as the New UIB - * License terms: GNU General Public License (GPL), version 2 - */ -#include <linux/gpio.h> -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/i2c.h> -#include <linux/interrupt.h> -#include <linux/mfd/tc3589x.h> -#include <linux/input/matrix_keypad.h> - -#include "irqs.h" - -#include "board-mop500.h" - -static struct i2c_board_info __initdata mop500_i2c3_devices_u8500[] = { - { - I2C_BOARD_INFO("synaptics_rmi4_i2c", 0x4B), - .irq = NOMADIK_GPIO_TO_IRQ(84), - }, -}; - -/* - * TC35893 - */ -static const unsigned int u8500_keymap[] = { - KEY(3, 1, KEY_END), - KEY(4, 1, KEY_POWER), - KEY(6, 4, KEY_VOLUMEDOWN), - KEY(4, 2, KEY_EMAIL), - KEY(3, 3, KEY_RIGHT), - KEY(2, 5, KEY_BACKSPACE), - - KEY(6, 7, KEY_MENU), - KEY(5, 0, KEY_ENTER), - KEY(4, 3, KEY_0), - KEY(3, 4, KEY_DOT), - KEY(5, 2, KEY_UP), - KEY(3, 5, KEY_DOWN), - - KEY(4, 5, KEY_SEND), - KEY(0, 5, KEY_BACK), - KEY(6, 2, KEY_VOLUMEUP), - KEY(1, 3, KEY_SPACE), - KEY(7, 6, KEY_LEFT), - KEY(5, 5, KEY_SEARCH), -}; - -static struct matrix_keymap_data u8500_keymap_data = { - .keymap = u8500_keymap, - .keymap_size = ARRAY_SIZE(u8500_keymap), -}; - -static struct tc3589x_keypad_platform_data tc35893_data = { - .krow = TC_KPD_ROWS, - .kcol = TC_KPD_COLUMNS, - .debounce_period = TC_KPD_DEBOUNCE_PERIOD, - .settle_time = TC_KPD_SETTLE_TIME, - .irqtype = IRQF_TRIGGER_FALLING, - .enable_wakeup = true, - .keymap_data = &u8500_keymap_data, - .no_autorepeat = true, -}; - -static struct tc3589x_platform_data tc3589x_keypad_data = { - .block = TC3589x_BLOCK_KEYPAD, - .keypad = &tc35893_data, - .irq_base = MOP500_EGPIO_IRQ_BASE, -}; - -static struct i2c_board_info __initdata mop500_i2c0_devices_u8500[] = { - { - I2C_BOARD_INFO("tc3589x", 0x44), - .platform_data = &tc3589x_keypad_data, - .irq = NOMADIK_GPIO_TO_IRQ(218), - .flags = I2C_CLIENT_WAKE, - }, -}; - - -void __init mop500_u8500uib_init(void) -{ - mop500_uib_i2c_add(3, mop500_i2c3_devices_u8500, - ARRAY_SIZE(mop500_i2c3_devices_u8500)); - - mop500_uib_i2c_add(0, mop500_i2c0_devices_u8500, - ARRAY_SIZE(mop500_i2c0_devices_u8500)); - -} diff --git a/arch/arm/mach-ux500/board-mop500-uib.c b/arch/arm/mach-ux500/board-mop500-uib.c deleted file mode 100644 index bdaa422da028..000000000000 --- a/arch/arm/mach-ux500/board-mop500-uib.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (C) ST-Ericsson SA 2010 - * - * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson - * License terms: GNU General Public License (GPL), version 2 - */ - -#define pr_fmt(fmt) "mop500-uib: " fmt - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/i2c.h> - -#include "board-mop500.h" -#include "id.h" - -enum mop500_uib { - STUIB, - U8500UIB, -}; - -struct uib { - const char *name; - const char *option; - void (*init)(void); -}; - -static struct uib __initdata mop500_uibs[] = { - [STUIB] = { - .name = "ST-UIB", - .option = "stuib", - .init = mop500_stuib_init, - }, - [U8500UIB] = { - .name = "U8500-UIB", - .option = "u8500uib", - .init = mop500_u8500uib_init, - }, -}; - -static struct uib *mop500_uib; - -static int __init mop500_uib_setup(char *str) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(mop500_uibs); i++) { - struct uib *uib = &mop500_uibs[i]; - - if (!strcmp(str, uib->option)) { - mop500_uib = uib; - break; - } - } - - if (i == ARRAY_SIZE(mop500_uibs)) - pr_err("invalid uib= option (%s)\n", str); - - return 1; -} -__setup("uib=", mop500_uib_setup); - -/* - * The UIBs are detected after the I2C host controllers are registered, so - * i2c_register_board_info() can't be used. - */ -void mop500_uib_i2c_add(int busnum, struct i2c_board_info *info, - unsigned n) -{ - struct i2c_adapter *adap; - struct i2c_client *client; - int i; - - adap = i2c_get_adapter(busnum); - if (!adap) { - pr_err("failed to get adapter i2c%d\n", busnum); - return; - } - - for (i = 0; i < n; i++) { - client = i2c_new_device(adap, &info[i]); - if (!client) - pr_err("failed to register %s to i2c%d\n", - info[i].type, busnum); - } - - i2c_put_adapter(adap); -} - -static void __init __mop500_uib_init(struct uib *uib, const char *why) -{ - pr_info("%s (%s)\n", uib->name, why); - uib->init(); -} - -/* - * Detect the UIB attached based on the presence or absence of i2c devices. - */ -int __init mop500_uib_init(void) -{ - struct uib *uib = mop500_uib; - struct i2c_adapter *i2c0; - int ret; - - if (!cpu_is_u8500_family()) - return -ENODEV; - - if (uib) { - __mop500_uib_init(uib, "from uib= boot argument"); - return 0; - } - - i2c0 = i2c_get_adapter(0); - if (!i2c0) { - __mop500_uib_init(&mop500_uibs[STUIB], - "fallback, could not get i2c0"); - return -ENODEV; - } - - /* U8500-UIB has the TC35893 at 0x44 on I2C0, the ST-UIB doesn't. */ - ret = i2c_smbus_xfer(i2c0, 0x44, 0, I2C_SMBUS_WRITE, 0, - I2C_SMBUS_QUICK, NULL); - i2c_put_adapter(i2c0); - - if (ret == 0) - uib = &mop500_uibs[U8500UIB]; - else - uib = &mop500_uibs[STUIB]; - - __mop500_uib_init(uib, "detected"); - - return 0; -} diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index ad0806eff762..514d40b625a4 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -14,27 +14,16 @@ #include <linux/platform_device.h> #include <linux/clk.h> #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> -#include <linux/amba/serial.h> -#include <linux/spi/spi.h> #include <linux/mfd/abx500/ab8500.h> #include <linux/regulator/ab8500.h> #include <linux/regulator/fixed.h> #include <linux/regulator/driver.h> -#include <linux/regulator/gpio-regulator.h> -#include <linux/mfd/tc3589x.h> #include <linux/mfd/tps6105x.h> -#include <linux/mfd/abx500/ab8500-gpio.h> -#include <linux/mfd/abx500/ab8500-codec.h> #include <linux/platform_data/leds-lp55xx.h> #include <linux/input.h> -#include <linux/smsc911x.h> -#include <linux/gpio_keys.h> #include <linux/delay.h> #include <linux/leds.h> #include <linux/pinctrl/consumer.h> @@ -46,7 +35,6 @@ #include "setup.h" #include "devices.h" #include "irqs.h" -#include <linux/platform_data/crypto-ux500.h> #include "ste-dma40-db8500.h" #include "db8500-regs.h" @@ -54,401 +42,9 @@ #include "board-mop500.h" #include "board-mop500-regulators.h" -static struct gpio_led snowball_led_array[] = { - { - .name = "user_led", - .default_trigger = "heartbeat", - .gpio = 142, - }, -}; - -static struct gpio_led_platform_data snowball_led_data = { - .leds = snowball_led_array, - .num_leds = ARRAY_SIZE(snowball_led_array), -}; - -static struct platform_device snowball_led_dev = { - .name = "leds-gpio", - .dev = { - .platform_data = &snowball_led_data, - }, -}; - -static struct fixed_voltage_config snowball_gpio_en_3v3_data = { - .supply_name = "EN-3V3", - .gpio = SNOWBALL_EN_3V3_ETH_GPIO, - .microvolts = 3300000, - .enable_high = 1, - .init_data = &gpio_en_3v3_regulator, - .startup_delay = 5000, /* 1200us */ -}; - -static struct platform_device snowball_gpio_en_3v3_regulator_dev = { - .name = "reg-fixed-voltage", - .id = 1, - .dev = { - .platform_data = &snowball_gpio_en_3v3_data, - }, -}; - -/* Dynamically populated. */ -static struct gpio sdi0_reg_gpios[] = { - { 0, GPIOF_OUT_INIT_LOW, "mmci_vsel" }, -}; - -static struct gpio_regulator_state sdi0_reg_states[] = { - { .value = 2900000, .gpios = (0 << 0) }, - { .value = 1800000, .gpios = (1 << 0) }, -}; - -static struct gpio_regulator_config sdi0_reg_info = { - .supply_name = "ext-mmc-level-shifter", - .gpios = sdi0_reg_gpios, - .nr_gpios = ARRAY_SIZE(sdi0_reg_gpios), - .states = sdi0_reg_states, - .nr_states = ARRAY_SIZE(sdi0_reg_states), - .type = REGULATOR_VOLTAGE, - .enable_high = 1, - .enabled_at_boot = 0, - .init_data = &sdi0_reg_init_data, - .startup_delay = 100, -}; - -static struct platform_device sdi0_regulator = { - .name = "gpio-regulator", - .id = -1, - .dev = { - .platform_data = &sdi0_reg_info, - }, -}; - -static struct abx500_gpio_platform_data ab8500_gpio_pdata = { - .gpio_base = MOP500_AB8500_PIN_GPIO(1), -}; - -/* ab8500-codec */ -static struct ab8500_codec_platform_data ab8500_codec_pdata = { - .amics = { - .mic1_type = AMIC_TYPE_DIFFERENTIAL, - .mic2_type = AMIC_TYPE_DIFFERENTIAL, - .mic1a_micbias = AMIC_MICBIAS_VAMIC1, - .mic1b_micbias = AMIC_MICBIAS_VAMIC1, - .mic2_micbias = AMIC_MICBIAS_VAMIC2 - }, - .ear_cmv = EAR_CMV_0_95V -}; - -static struct gpio_keys_button snowball_key_array[] = { - { - .gpio = 32, - .type = EV_KEY, - .code = KEY_1, - .desc = "userpb", - .active_low = 1, - .debounce_interval = 50, - .wakeup = 1, - }, - { - .gpio = 151, - .type = EV_KEY, - .code = KEY_2, - .desc = "extkb1", - .active_low = 1, - .debounce_interval = 50, - .wakeup = 1, - }, - { - .gpio = 152, - .type = EV_KEY, - .code = KEY_3, - .desc = "extkb2", - .active_low = 1, - .debounce_interval = 50, - .wakeup = 1, - }, - { - .gpio = 161, - .type = EV_KEY, - .code = KEY_4, - .desc = "extkb3", - .active_low = 1, - .debounce_interval = 50, - .wakeup = 1, - }, - { - .gpio = 162, - .type = EV_KEY, - .code = KEY_5, - .desc = "extkb4", - .active_low = 1, - .debounce_interval = 50, - .wakeup = 1, - }, -}; - -static struct gpio_keys_platform_data snowball_key_data = { - .buttons = snowball_key_array, - .nbuttons = ARRAY_SIZE(snowball_key_array), -}; - -static struct platform_device snowball_key_dev = { - .name = "gpio-keys", - .id = -1, - .dev = { - .platform_data = &snowball_key_data, - } -}; - -static struct smsc911x_platform_config snowball_sbnet_cfg = { - .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH, - .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, - .flags = SMSC911X_USE_16BIT | SMSC911X_FORCE_INTERNAL_PHY, - .shift = 1, -}; - -static struct resource sbnet_res[] = { - { - .name = "smsc911x-memory", - .start = (0x5000 << 16), - .end = (0x5000 << 16) + 0xffff, - .flags = IORESOURCE_MEM, - }, - { - .start = NOMADIK_GPIO_TO_IRQ(140), - .end = NOMADIK_GPIO_TO_IRQ(140), - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, - }, -}; - -static struct platform_device snowball_sbnet_dev = { - .name = "smsc911x", - .num_resources = ARRAY_SIZE(sbnet_res), - .resource = sbnet_res, - .dev = { - .platform_data = &snowball_sbnet_cfg, - }, -}; - struct ab8500_platform_data ab8500_platdata = { .irq_base = MOP500_AB8500_IRQ_BASE, .regulator = &ab8500_regulator_plat_data, - .gpio = &ab8500_gpio_pdata, - .codec = &ab8500_codec_pdata, -}; - -static struct platform_device u8500_cpufreq_cooling_device = { - .name = "db8500-cpufreq-cooling", -}; - -/* - * TPS61052 - */ - -static struct tps6105x_platform_data mop500_tps61052_data = { - .mode = TPS6105X_MODE_VOLTAGE, - .regulator_data = &tps61052_regulator, -}; - -/* - * TC35892 - */ - -static void mop500_tc35892_init(struct tc3589x *tc3589x, unsigned int base) -{ - struct device *parent = NULL; -#if 0 - /* FIXME: Is the sdi actually part of tc3589x? */ - parent = tc3589x->dev; -#endif - mop500_sdi_tc35892_init(parent); -} - -static struct tc3589x_gpio_platform_data mop500_tc35892_gpio_data = { - .gpio_base = MOP500_EGPIO(0), - .setup = mop500_tc35892_init, -}; - -static struct tc3589x_platform_data mop500_tc35892_data = { - .block = TC3589x_BLOCK_GPIO, - .gpio = &mop500_tc35892_gpio_data, - .irq_base = MOP500_EGPIO_IRQ_BASE, -}; - -static struct lp55xx_led_config lp5521_pri_led[] = { - [0] = { - .chan_nr = 0, - .led_current = 0x2f, - .max_current = 0x5f, - }, - [1] = { - .chan_nr = 1, - .led_current = 0x2f, - .max_current = 0x5f, - }, - [2] = { - .chan_nr = 2, - .led_current = 0x2f, - .max_current = 0x5f, - }, -}; - -static struct lp55xx_platform_data __initdata lp5521_pri_data = { - .label = "lp5521_pri", - .led_config = &lp5521_pri_led[0], - .num_channels = 3, - .clock_mode = LP55XX_CLOCK_EXT, -}; - -static struct lp55xx_led_config lp5521_sec_led[] = { - [0] = { - .chan_nr = 0, - .led_current = 0x2f, - .max_current = 0x5f, - }, - [1] = { - .chan_nr = 1, - .led_current = 0x2f, - .max_current = 0x5f, - }, - [2] = { - .chan_nr = 2, - .led_current = 0x2f, - .max_current = 0x5f, - }, -}; - -static struct lp55xx_platform_data __initdata lp5521_sec_data = { - .label = "lp5521_sec", - .led_config = &lp5521_sec_led[0], - .num_channels = 3, - .clock_mode = LP55XX_CLOCK_EXT, -}; - -/* I2C0 devices only available on the first HREF/MOP500 */ -static struct i2c_board_info __initdata mop500_i2c0_devices[] = { - { - I2C_BOARD_INFO("tc3589x", 0x42), - .irq = NOMADIK_GPIO_TO_IRQ(217), - .platform_data = &mop500_tc35892_data, - }, - { - I2C_BOARD_INFO("tps61052", 0x33), - .platform_data = &mop500_tps61052_data, - }, -}; - -static struct i2c_board_info __initdata mop500_i2c2_devices[] = { - { - /* lp5521 LED driver, 1st device */ - I2C_BOARD_INFO("lp5521", 0x33), - .platform_data = &lp5521_pri_data, - }, - { - /* lp5521 LED driver, 2st device */ - I2C_BOARD_INFO("lp5521", 0x34), - .platform_data = &lp5521_sec_data, - }, - { - /* Light sensor Rohm BH1780GLI */ - I2C_BOARD_INFO("bh1780", 0x29), - }, -}; - -static int __init mop500_i2c_board_init(void) -{ - if (machine_is_u8500()) - mop500_uib_i2c_add(0, mop500_i2c0_devices, - ARRAY_SIZE(mop500_i2c0_devices)); - mop500_uib_i2c_add(2, mop500_i2c2_devices, - ARRAY_SIZE(mop500_i2c2_devices)); - return 0; -} -device_initcall(mop500_i2c_board_init); - -static void __init mop500_i2c_init(struct device *parent) -{ - db8500_add_i2c0(parent, NULL); - db8500_add_i2c1(parent, NULL); - db8500_add_i2c2(parent, NULL); - db8500_add_i2c3(parent, NULL); -} - -static struct gpio_keys_button mop500_gpio_keys[] = { - { - .desc = "SFH7741 Proximity Sensor", - .type = EV_SW, - .code = SW_FRONT_PROXIMITY, - .active_low = 0, - .can_disable = 1, - } -}; - -static struct regulator *prox_regulator; -static int mop500_prox_activate(struct device *dev); -static void mop500_prox_deactivate(struct device *dev); - -static struct gpio_keys_platform_data mop500_gpio_keys_data = { - .buttons = mop500_gpio_keys, - .nbuttons = ARRAY_SIZE(mop500_gpio_keys), - .enable = mop500_prox_activate, - .disable = mop500_prox_deactivate, -}; - -static struct platform_device mop500_gpio_keys_device = { - .name = "gpio-keys", - .id = 0, - .dev = { - .platform_data = &mop500_gpio_keys_data, - }, -}; - -static int mop500_prox_activate(struct device *dev) -{ - prox_regulator = regulator_get(&mop500_gpio_keys_device.dev, - "vcc"); - if (IS_ERR(prox_regulator)) { - dev_err(&mop500_gpio_keys_device.dev, - "no regulator\n"); - return PTR_ERR(prox_regulator); - } - - return regulator_enable(prox_regulator); -} - -static void mop500_prox_deactivate(struct device *dev) -{ - regulator_disable(prox_regulator); - regulator_put(prox_regulator); -} - -static struct cryp_platform_data u8500_cryp1_platform_data = { - .mem_to_engine = { - .dir = DMA_MEM_TO_DEV, - .dev_type = DB8500_DMA_DEV48_CAC1, - .mode = STEDMA40_MODE_LOGICAL, - }, - .engine_to_mem = { - .dir = DMA_DEV_TO_MEM, - .dev_type = DB8500_DMA_DEV48_CAC1, - .mode = STEDMA40_MODE_LOGICAL, - } -}; - -static struct stedma40_chan_cfg u8500_hash_dma_cfg_tx = { - .dir = DMA_MEM_TO_DEV, - .dev_type = DB8500_DMA_DEV50_HAC1_TX, - .mode = STEDMA40_MODE_LOGICAL, -}; - -static struct hash_platform_data u8500_hash1_platform_data = { - .mem_to_engine = &u8500_hash_dma_cfg_tx, - .dma_filter = stedma40_filter, -}; - -/* add any platform devices here - TODO */ -static struct platform_device *mop500_platform_devs[] __initdata = { - &mop500_gpio_keys_device, - &sdi0_regulator, }; #ifdef CONFIG_STE_DMA40 @@ -480,236 +76,3 @@ struct pl022_ssp_controller ssp0_plat = { */ .num_chipselect = 5, }; - -static void __init mop500_spi_init(struct device *parent) -{ - db8500_add_ssp0(parent, &ssp0_plat); -} - -#ifdef CONFIG_STE_DMA40 -static struct stedma40_chan_cfg uart0_dma_cfg_rx = { - .mode = STEDMA40_MODE_LOGICAL, - .dir = DMA_DEV_TO_MEM, - .dev_type = DB8500_DMA_DEV13_UART0, -}; - -static struct stedma40_chan_cfg uart0_dma_cfg_tx = { - .mode = STEDMA40_MODE_LOGICAL, - .dir = DMA_MEM_TO_DEV, - .dev_type = DB8500_DMA_DEV13_UART0, -}; - -static struct stedma40_chan_cfg uart1_dma_cfg_rx = { - .mode = STEDMA40_MODE_LOGICAL, - .dir = DMA_DEV_TO_MEM, - .dev_type = DB8500_DMA_DEV12_UART1, -}; - -static struct stedma40_chan_cfg uart1_dma_cfg_tx = { - .mode = STEDMA40_MODE_LOGICAL, - .dir = DMA_MEM_TO_DEV, - .dev_type = DB8500_DMA_DEV12_UART1, -}; - -static struct stedma40_chan_cfg uart2_dma_cfg_rx = { - .mode = STEDMA40_MODE_LOGICAL, - .dir = DMA_DEV_TO_MEM, - .dev_type = DB8500_DMA_DEV11_UART2, -}; - -static struct stedma40_chan_cfg uart2_dma_cfg_tx = { - .mode = STEDMA40_MODE_LOGICAL, - .dir = DMA_MEM_TO_DEV, - .dev_type = DB8500_DMA_DEV11_UART2, -}; -#endif - -struct amba_pl011_data uart0_plat = { -#ifdef CONFIG_STE_DMA40 - .dma_filter = stedma40_filter, - .dma_rx_param = &uart0_dma_cfg_rx, - .dma_tx_param = &uart0_dma_cfg_tx, -#endif -}; - -struct amba_pl011_data uart1_plat = { -#ifdef CONFIG_STE_DMA40 - .dma_filter = stedma40_filter, - .dma_rx_param = &uart1_dma_cfg_rx, - .dma_tx_param = &uart1_dma_cfg_tx, -#endif -}; - -struct amba_pl011_data uart2_plat = { -#ifdef CONFIG_STE_DMA40 - .dma_filter = stedma40_filter, - .dma_rx_param = &uart2_dma_cfg_rx, - .dma_tx_param = &uart2_dma_cfg_tx, -#endif -}; - -static void __init mop500_uart_init(struct device *parent) -{ - db8500_add_uart0(parent, &uart0_plat); - db8500_add_uart1(parent, &uart1_plat); - db8500_add_uart2(parent, &uart2_plat); -} - -static void __init u8500_cryp1_hash1_init(struct device *parent) -{ - db8500_add_cryp1(parent, &u8500_cryp1_platform_data); - db8500_add_hash1(parent, &u8500_hash1_platform_data); -} - -static struct platform_device *snowball_platform_devs[] __initdata = { - &snowball_led_dev, - &snowball_key_dev, - &snowball_sbnet_dev, - &snowball_gpio_en_3v3_regulator_dev, - &u8500_cpufreq_cooling_device, - &sdi0_regulator, -}; - -static void __init mop500_init_machine(void) -{ - struct device *parent = NULL; - int i; - - platform_device_register(&db8500_prcmu_device); - mop500_gpio_keys[0].gpio = GPIO_PROX_SENSOR; - - sdi0_reg_info.enable_gpio = GPIO_SDMMC_EN; - sdi0_reg_info.gpios[0].gpio = GPIO_SDMMC_1V8_3V_SEL; - - mop500_pinmaps_init(); - parent = u8500_init_devices(); - - for (i = 0; i < ARRAY_SIZE(mop500_platform_devs); i++) - mop500_platform_devs[i]->dev.parent = parent; - - platform_add_devices(mop500_platform_devs, - ARRAY_SIZE(mop500_platform_devs)); - - mop500_i2c_init(parent); - mop500_sdi_init(parent); - mop500_spi_init(parent); - mop500_audio_init(parent); - mop500_uart_init(parent); - u8500_cryp1_hash1_init(parent); - - /* This board has full regulator constraints */ - regulator_has_full_constraints(); -} - - -static void __init snowball_init_machine(void) -{ - struct device *parent = NULL; - int i; - - platform_device_register(&db8500_prcmu_device); - - sdi0_reg_info.enable_gpio = SNOWBALL_SDMMC_EN_GPIO; - sdi0_reg_info.gpios[0].gpio = SNOWBALL_SDMMC_1V8_3V_GPIO; - - snowball_pinmaps_init(); - parent = u8500_init_devices(); - - for (i = 0; i < ARRAY_SIZE(snowball_platform_devs); i++) - snowball_platform_devs[i]->dev.parent = parent; - - platform_add_devices(snowball_platform_devs, - ARRAY_SIZE(snowball_platform_devs)); - - mop500_i2c_init(parent); - snowball_sdi_init(parent); - mop500_spi_init(parent); - mop500_audio_init(parent); - mop500_uart_init(parent); - - u8500_cryp1_hash1_init(parent); - - /* This board has full regulator constraints */ - regulator_has_full_constraints(); -} - -static void __init hrefv60_init_machine(void) -{ - struct device *parent = NULL; - int i; - - platform_device_register(&db8500_prcmu_device); - /* - * The HREFv60 board removed a GPIO expander and routed - * all these GPIO pins to the internal GPIO controller - * instead. - */ - mop500_gpio_keys[0].gpio = HREFV60_PROX_SENSE_GPIO; - - sdi0_reg_info.enable_gpio = HREFV60_SDMMC_EN_GPIO; - sdi0_reg_info.gpios[0].gpio = HREFV60_SDMMC_1V8_3V_GPIO; - - hrefv60_pinmaps_init(); - parent = u8500_init_devices(); - - for (i = 0; i < ARRAY_SIZE(mop500_platform_devs); i++) - mop500_platform_devs[i]->dev.parent = parent; - - platform_add_devices(mop500_platform_devs, - ARRAY_SIZE(mop500_platform_devs)); - - mop500_i2c_init(parent); - hrefv60_sdi_init(parent); - mop500_spi_init(parent); - mop500_audio_init(parent); - mop500_uart_init(parent); - - /* This board has full regulator constraints */ - regulator_has_full_constraints(); -} - -MACHINE_START(U8500, "ST-Ericsson MOP500 platform") - /* Maintainer: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> */ - .atag_offset = 0x100, - .smp = smp_ops(ux500_smp_ops), - .map_io = u8500_map_io, - .init_irq = ux500_init_irq, - /* we re-use nomadik timer here */ - .init_time = ux500_timer_init, - .init_machine = mop500_init_machine, - .init_late = ux500_init_late, - .restart = ux500_restart, -MACHINE_END - -MACHINE_START(U8520, "ST-Ericsson U8520 Platform HREFP520") - .atag_offset = 0x100, - .map_io = u8500_map_io, - .init_irq = ux500_init_irq, - .init_time = ux500_timer_init, - .init_machine = mop500_init_machine, - .init_late = ux500_init_late, - .restart = ux500_restart, -MACHINE_END - -MACHINE_START(HREFV60, "ST-Ericsson U8500 Platform HREFv60+") - .atag_offset = 0x100, - .smp = smp_ops(ux500_smp_ops), - .map_io = u8500_map_io, - .init_irq = ux500_init_irq, - .init_time = ux500_timer_init, - .init_machine = hrefv60_init_machine, - .init_late = ux500_init_late, - .restart = ux500_restart, -MACHINE_END - -MACHINE_START(SNOWBALL, "Calao Systems Snowball platform") - .atag_offset = 0x100, - .smp = smp_ops(ux500_smp_ops), - .map_io = u8500_map_io, - .init_irq = ux500_init_irq, - /* we re-use nomadik timer here */ - .init_time = ux500_timer_init, - .init_machine = snowball_init_machine, - .init_late = NULL, - .restart = ux500_restart, -MACHINE_END diff --git a/arch/arm/mach-ux500/board-mop500.h b/arch/arm/mach-ux500/board-mop500.h index d6fab166cbf1..511d6febbe99 100644 --- a/arch/arm/mach-ux500/board-mop500.h +++ b/arch/arm/mach-ux500/board-mop500.h @@ -79,7 +79,6 @@ #define SNOWBALL_EN_3V3_ETH_GPIO MOP500_AB8500_PIN_GPIO(26) /* GPIO26 */ struct device; -struct i2c_board_info; extern struct mmci_platform_data mop500_sdi0_data; extern struct mmci_platform_data mop500_sdi1_data; extern struct mmci_platform_data mop500_sdi2_data; @@ -88,25 +87,10 @@ extern struct msp_i2s_platform_data msp0_platform_data; extern struct msp_i2s_platform_data msp1_platform_data; extern struct msp_i2s_platform_data msp2_platform_data; extern struct msp_i2s_platform_data msp3_platform_data; -extern struct arm_pmu_platdata db8500_pmu_platdata; -extern struct amba_pl011_data uart0_plat; -extern struct amba_pl011_data uart1_plat; -extern struct amba_pl011_data uart2_plat; extern struct pl022_ssp_controller ssp0_plat; -extern struct stedma40_platform_data dma40_plat_data; -extern void mop500_sdi_init(struct device *parent); -extern void snowball_sdi_init(struct device *parent); -extern void hrefv60_sdi_init(struct device *parent); -extern void mop500_sdi_tc35892_init(struct device *parent); -void __init mop500_u8500uib_init(void); -void __init mop500_stuib_init(void); void __init mop500_pinmaps_init(void); void __init snowball_pinmaps_init(void); void __init hrefv60_pinmaps_init(void); -void mop500_audio_init(struct device *parent); -int __init mop500_uib_init(void); -void mop500_uib_i2c_add(int busnum, struct i2c_board_info *info, - unsigned n); #endif diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index 301c3460d96a..2e85c1e72535 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c @@ -32,7 +32,6 @@ #include "irqs.h" #include "devices-db8500.h" -#include "ste-dma40-db8500.h" #include "db8500-regs.h" #include "board-mop500.h" #include "id.h" @@ -93,14 +92,6 @@ void __init u8500_map_io(void) iotable_init(u8500_io_desc, ARRAY_SIZE(u8500_io_desc)); } -static struct resource db8500_pmu_resources[] = { - [0] = { - .start = IRQ_DB8500_PMU, - .end = IRQ_DB8500_PMU, - .flags = IORESOURCE_IRQ, - }, -}; - /* * The PMU IRQ lines of two cores are wired together into a single interrupt. * Bounce the interrupt to the other core if it's not ours. @@ -125,54 +116,6 @@ struct arm_pmu_platdata db8500_pmu_platdata = { .handle_irq = db8500_pmu_handler, }; -static struct platform_device db8500_pmu_device = { - .name = "arm-pmu", - .id = -1, - .num_resources = ARRAY_SIZE(db8500_pmu_resources), - .resource = db8500_pmu_resources, - .dev.platform_data = &db8500_pmu_platdata, -}; - -static struct platform_device *platform_devs[] __initdata = { - &u8500_dma40_device, - &db8500_pmu_device, -}; - -static resource_size_t __initdata db8500_gpio_base[] = { - U8500_GPIOBANK0_BASE, - U8500_GPIOBANK1_BASE, - U8500_GPIOBANK2_BASE, - U8500_GPIOBANK3_BASE, - U8500_GPIOBANK4_BASE, - U8500_GPIOBANK5_BASE, - U8500_GPIOBANK6_BASE, - U8500_GPIOBANK7_BASE, - U8500_GPIOBANK8_BASE, -}; - -static void __init db8500_add_gpios(struct device *parent) -{ - struct nmk_gpio_platform_data pdata = { - .supports_sleepmode = true, - }; - - dbx500_add_gpios(parent, db8500_gpio_base, - ARRAY_SIZE(db8500_gpio_base), - IRQ_DB8500_GPIO0, &pdata); - dbx500_add_pinctrl(parent, "pinctrl-db8500", U8500_PRCMU_BASE); -} - -static int usb_db8500_dma_cfg[] = { - DB8500_DMA_DEV38_USB_OTG_IEP_AND_OEP_1_9, - DB8500_DMA_DEV37_USB_OTG_IEP_AND_OEP_2_10, - DB8500_DMA_DEV36_USB_OTG_IEP_AND_OEP_3_11, - DB8500_DMA_DEV19_USB_OTG_IEP_AND_OEP_4_12, - DB8500_DMA_DEV18_USB_OTG_IEP_AND_OEP_5_13, - DB8500_DMA_DEV17_USB_OTG_IEP_AND_OEP_6_14, - DB8500_DMA_DEV16_USB_OTG_IEP_AND_OEP_7_15, - DB8500_DMA_DEV39_USB_OTG_IEP_AND_OEP_8 -}; - static const char *db8500_read_soc_id(void) { void __iomem *uid = __io_address(U8500_BB_UID_BASE); @@ -192,60 +135,22 @@ static struct device * __init db8500_soc_device_init(void) return ux500_soc_device_init(soc_id); } -/* - * This function is called from the board init - */ -struct device * __init u8500_init_devices(void) -{ - struct device *parent; - int i; - - parent = db8500_soc_device_init(); - - db8500_add_rtc(parent); - db8500_add_gpios(parent); - db8500_add_usb(parent, usb_db8500_dma_cfg, usb_db8500_dma_cfg); - - for (i = 0; i < ARRAY_SIZE(platform_devs); i++) - platform_devs[i]->dev.parent = parent; - - platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); - - return parent; -} - #ifdef CONFIG_MACH_UX500_DT static struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = { /* Requires call-back bindings. */ OF_DEV_AUXDATA("arm,cortex-a9-pmu", 0, "arm-pmu", &db8500_pmu_platdata), /* Requires DMA bindings. */ - OF_DEV_AUXDATA("arm,pl011", 0x80120000, "uart0", NULL), - OF_DEV_AUXDATA("arm,pl011", 0x80121000, "uart1", NULL), - OF_DEV_AUXDATA("arm,pl011", 0x80007000, "uart2", NULL), - OF_DEV_AUXDATA("arm,pl022", 0x80002000, "ssp0", &ssp0_plat), - OF_DEV_AUXDATA("arm,pl18x", 0x80126000, "sdi0", NULL), - OF_DEV_AUXDATA("arm,pl18x", 0x80118000, "sdi1", NULL), - OF_DEV_AUXDATA("arm,pl18x", 0x80005000, "sdi2", NULL), - OF_DEV_AUXDATA("arm,pl18x", 0x80114000, "sdi4", NULL), - /* Requires clock name bindings. */ - OF_DEV_AUXDATA("st,nomadik-gpio", 0x8012e000, "gpio.0", NULL), - OF_DEV_AUXDATA("st,nomadik-gpio", 0x8012e080, "gpio.1", NULL), - OF_DEV_AUXDATA("st,nomadik-gpio", 0x8000e000, "gpio.2", NULL), - OF_DEV_AUXDATA("st,nomadik-gpio", 0x8000e080, "gpio.3", NULL), - OF_DEV_AUXDATA("st,nomadik-gpio", 0x8000e100, "gpio.4", NULL), - OF_DEV_AUXDATA("st,nomadik-gpio", 0x8000e180, "gpio.5", NULL), - OF_DEV_AUXDATA("st,nomadik-gpio", 0x8011e000, "gpio.6", NULL), - OF_DEV_AUXDATA("st,nomadik-gpio", 0x8011e080, "gpio.7", NULL), - OF_DEV_AUXDATA("st,nomadik-gpio", 0xa03fe000, "gpio.8", NULL), - OF_DEV_AUXDATA("st,nomadik-i2c", 0x80004000, "nmk-i2c.0", NULL), - OF_DEV_AUXDATA("st,nomadik-i2c", 0x80122000, "nmk-i2c.1", NULL), - OF_DEV_AUXDATA("st,nomadik-i2c", 0x80128000, "nmk-i2c.2", NULL), - OF_DEV_AUXDATA("st,nomadik-i2c", 0x80110000, "nmk-i2c.3", NULL), - OF_DEV_AUXDATA("st,nomadik-i2c", 0x8012a000, "nmk-i2c.4", NULL), - OF_DEV_AUXDATA("stericsson,db8500-musb", 0xa03e0000, "musb-ux500.0", NULL), + OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80123000, + "ux500-msp-i2s.0", &msp0_platform_data), + OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80124000, + "ux500-msp-i2s.1", &msp1_platform_data), + OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80117000, + "ux500-msp-i2s.2", &msp2_platform_data), + OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80125000, + "ux500-msp-i2s.3", &msp3_platform_data), + /* Requires non-DT:able platform data. */ OF_DEV_AUXDATA("stericsson,db8500-prcmu", 0x80157000, "db8500-prcmu", &db8500_prcmu_pdata), - OF_DEV_AUXDATA("smsc,lan9115", 0x50000000, "smsc911x.0", NULL), OF_DEV_AUXDATA("stericsson,ux500-cryp", 0xa03cb000, "cryp1", NULL), OF_DEV_AUXDATA("stericsson,ux500-hash", 0xa03c2000, "hash1", NULL), OF_DEV_AUXDATA("stericsson,snd-soc-mop500", 0, "snd-soc-mop500.0", @@ -253,17 +158,6 @@ static struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = { /* Requires device name bindings. */ OF_DEV_AUXDATA("stericsson,db8500-pinctrl", U8500_PRCMU_BASE, "pinctrl-db8500", NULL), - /* Requires clock name and DMA bindings. */ - OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80123000, - "ux500-msp-i2s.0", &msp0_platform_data), - OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80124000, - "ux500-msp-i2s.1", &msp1_platform_data), - OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80117000, - "ux500-msp-i2s.2", &msp2_platform_data), - OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80125000, - "ux500-msp-i2s.3", &msp3_platform_data), - /* Requires clock name bindings and channel address lookup table. */ - OF_DEV_AUXDATA("stericsson,db8500-dma40", 0x801C0000, "dma40.0", NULL), {}, }; diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c index 5d7eebcabc63..f84d4397896b 100644 --- a/arch/arm/mach-ux500/cpu.c +++ b/arch/arm/mach-ux500/cpu.c @@ -78,9 +78,17 @@ void __init ux500_init_irq(void) if (cpu_is_u8500_family()) { prcmu_early_init(U8500_PRCMU_BASE, SZ_8K - 1); ux500_pm_init(U8500_PRCMU_BASE, SZ_8K - 1); - u8500_clk_init(U8500_CLKRST1_BASE, U8500_CLKRST2_BASE, - U8500_CLKRST3_BASE, U8500_CLKRST5_BASE, - U8500_CLKRST6_BASE); + + if (of_have_populated_dt()) + u8500_of_clk_init(U8500_CLKRST1_BASE, + U8500_CLKRST2_BASE, + U8500_CLKRST3_BASE, + U8500_CLKRST5_BASE, + U8500_CLKRST6_BASE); + else + u8500_clk_init(U8500_CLKRST1_BASE, U8500_CLKRST2_BASE, + U8500_CLKRST3_BASE, U8500_CLKRST5_BASE, + U8500_CLKRST6_BASE); } else if (cpu_is_u9540()) { prcmu_early_init(U8500_PRCMU_BASE, SZ_8K - 1); ux500_pm_init(U8500_PRCMU_BASE, SZ_8K - 1); @@ -96,11 +104,6 @@ void __init ux500_init_irq(void) } } -void __init ux500_init_late(void) -{ - mop500_uib_init(); -} - static const char * __init ux500_get_machine(void) { return kasprintf(GFP_KERNEL, "DB%4x", dbx500_partnumber()); diff --git a/arch/arm/mach-ux500/devices-common.c b/arch/arm/mach-ux500/devices-common.c deleted file mode 100644 index f71b3d7bd4fb..000000000000 --- a/arch/arm/mach-ux500/devices-common.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) ST-Ericsson SA 2010 - * - * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson - * License terms: GNU General Public License (GPL), version 2. - */ - -#include <linux/kernel.h> -#include <linux/dma-mapping.h> -#include <linux/err.h> -#include <linux/irq.h> -#include <linux/slab.h> -#include <linux/platform_device.h> -#include <linux/platform_data/pinctrl-nomadik.h> - -#include "irqs.h" - -#include "devices-common.h" - -static struct platform_device * -dbx500_add_gpio(struct device *parent, int id, resource_size_t addr, int irq, - struct nmk_gpio_platform_data *pdata) -{ - struct resource resources[] = { - { - .start = addr, - .end = addr + 127, - .flags = IORESOURCE_MEM, - }, - { - .start = irq, - .end = irq, - .flags = IORESOURCE_IRQ, - } - }; - - return platform_device_register_resndata( - parent, - "gpio", - id, - resources, - ARRAY_SIZE(resources), - pdata, - sizeof(*pdata)); -} - -void dbx500_add_gpios(struct device *parent, resource_size_t *base, int num, - int irq, struct nmk_gpio_platform_data *pdata) -{ - int first = 0; - int i; - - for (i = 0; i < num; i++, first += 32, irq++) { - pdata->first_gpio = first; - pdata->first_irq = NOMADIK_GPIO_TO_IRQ(first); - pdata->num_gpio = 32; - - dbx500_add_gpio(parent, i, base[i], irq, pdata); - } -} diff --git a/arch/arm/mach-ux500/devices-common.h b/arch/arm/mach-ux500/devices-common.h deleted file mode 100644 index 96fa4ac89e2e..000000000000 --- a/arch/arm/mach-ux500/devices-common.h +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (C) ST-Ericsson SA 2010 - * - * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson - * License terms: GNU General Public License (GPL), version 2. - */ - -#ifndef __DEVICES_COMMON_H -#define __DEVICES_COMMON_H - -#include <linux/platform_device.h> -#include <linux/dma-mapping.h> -#include <linux/sys_soc.h> -#include <linux/amba/bus.h> -#include <linux/platform_data/i2c-nomadik.h> -#include <linux/platform_data/crypto-ux500.h> - -struct spi_master_cntlr; - -static inline struct amba_device * -dbx500_add_msp_spi(struct device *parent, const char *name, - resource_size_t base, int irq, - struct spi_master_cntlr *pdata) -{ - return amba_ahb_device_add(parent, name, base, SZ_4K, irq, 0, - pdata, 0); -} - -static inline struct amba_device * -dbx500_add_spi(struct device *parent, const char *name, resource_size_t base, - int irq, struct spi_master_cntlr *pdata, - u32 periphid) -{ - return amba_ahb_device_add(parent, name, base, SZ_4K, irq, 0, - pdata, periphid); -} - -struct mmci_platform_data; - -static inline struct amba_device * -dbx500_add_sdi(struct device *parent, const char *name, resource_size_t base, - int irq, struct mmci_platform_data *pdata, u32 periphid) -{ - return amba_ahb_device_add(parent, name, base, SZ_4K, irq, 0, - pdata, periphid); -} - -struct amba_pl011_data; - -static inline struct amba_device * -dbx500_add_uart(struct device *parent, const char *name, resource_size_t base, - int irq, struct amba_pl011_data *pdata) -{ - return amba_ahb_device_add(parent, name, base, SZ_4K, irq, 0, pdata, 0); -} - -struct nmk_i2c_controller; - -static inline struct amba_device * -dbx500_add_i2c(struct device *parent, int id, resource_size_t base, int irq, - struct nmk_i2c_controller *data) -{ - /* Conjure a name similar to what the platform device used to have */ - char name[16]; - - snprintf(name, sizeof(name), "nmk-i2c.%d", id); - return amba_apb_device_add(parent, name, base, SZ_4K, irq, 0, data, 0); -} - -static inline struct amba_device * -dbx500_add_rtc(struct device *parent, resource_size_t base, int irq) -{ - return amba_apb_device_add(parent, "rtc-pl031", base, SZ_4K, irq, - 0, NULL, 0); -} - -struct cryp_platform_data; - -static inline struct platform_device * -dbx500_add_cryp1(struct device *parent, int id, resource_size_t base, int irq, - struct cryp_platform_data *pdata) -{ - struct resource res[] = { - DEFINE_RES_MEM(base, SZ_4K), - DEFINE_RES_IRQ(irq), - }; - - struct platform_device_info pdevinfo = { - .parent = parent, - .name = "cryp1", - .id = id, - .res = res, - .num_res = ARRAY_SIZE(res), - .data = pdata, - .size_data = sizeof(*pdata), - .dma_mask = DMA_BIT_MASK(32), - }; - - return platform_device_register_full(&pdevinfo); -} - -struct hash_platform_data; - -static inline struct platform_device * -dbx500_add_hash1(struct device *parent, int id, resource_size_t base, - struct hash_platform_data *pdata) -{ - struct resource res[] = { - DEFINE_RES_MEM(base, SZ_4K), - }; - - struct platform_device_info pdevinfo = { - .parent = parent, - .name = "hash1", - .id = id, - .res = res, - .num_res = ARRAY_SIZE(res), - .data = pdata, - .size_data = sizeof(*pdata), - .dma_mask = DMA_BIT_MASK(32), - }; - - return platform_device_register_full(&pdevinfo); -} - -struct nmk_gpio_platform_data; - -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, - 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); -} - -#endif diff --git a/arch/arm/mach-ux500/devices-db8500.c b/arch/arm/mach-ux500/devices-db8500.c index bc316062e0c2..c59f89d058ff 100644 --- a/arch/arm/mach-ux500/devices-db8500.c +++ b/arch/arm/mach-ux500/devices-db8500.c @@ -9,10 +9,8 @@ #include <linux/platform_device.h> #include <linux/interrupt.h> #include <linux/io.h> -#include <linux/gpio.h> #include <linux/amba/bus.h> #include <linux/amba/pl022.h> -#include <linux/platform_data/dma-ste-dma40.h> #include <linux/mfd/dbx500-prcmu.h> #include "setup.h" @@ -20,62 +18,6 @@ #include "db8500-regs.h" #include "devices-db8500.h" -#include "ste-dma40-db8500.h" - -static struct resource dma40_resources[] = { - [0] = { - .start = U8500_DMA_BASE, - .end = U8500_DMA_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - .name = "base", - }, - [1] = { - .start = U8500_DMA_LCPA_BASE, - .end = U8500_DMA_LCPA_BASE + 2 * SZ_1K - 1, - .flags = IORESOURCE_MEM, - .name = "lcpa", - }, - [2] = { - .start = IRQ_DB8500_DMA, - .end = IRQ_DB8500_DMA, - .flags = IORESOURCE_IRQ, - } -}; - -struct stedma40_platform_data dma40_plat_data = { - .disabled_channels = {-1}, -}; - -struct platform_device u8500_dma40_device = { - .dev = { - .platform_data = &dma40_plat_data, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .name = "dma40", - .id = 0, - .num_resources = ARRAY_SIZE(dma40_resources), - .resource = dma40_resources -}; - -struct resource keypad_resources[] = { - [0] = { - .start = U8500_SKE_BASE, - .end = U8500_SKE_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_DB8500_KB, - .end = IRQ_DB8500_KB, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device u8500_ske_keypad_device = { - .name = "nmk-ske-keypad", - .id = -1, - .num_resources = ARRAY_SIZE(keypad_resources), - .resource = keypad_resources, -}; struct prcmu_pdata db8500_prcmu_pdata = { .ab_platdata = &ab8500_platdata, @@ -84,39 +26,3 @@ struct prcmu_pdata db8500_prcmu_pdata = { .version_offset = DB8500_PRCMU_FW_VERSION_OFFSET, .legacy_offset = DB8500_PRCMU_LEGACY_OFFSET, }; - -static struct resource db8500_prcmu_res[] = { - { - .name = "prcmu", - .start = U8500_PRCMU_BASE, - .end = U8500_PRCMU_BASE + SZ_8K - 1, - .flags = IORESOURCE_MEM, - }, - { - .name = "prcmu-tcdm", - .start = U8500_PRCMU_TCDM_BASE, - .end = U8500_PRCMU_TCDM_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - { - .name = "irq", - .start = IRQ_DB8500_PRCMU1, - .end = IRQ_DB8500_PRCMU1, - .flags = IORESOURCE_IRQ, - }, - { - .name = "prcmu-tcpm", - .start = U8500_PRCMU_TCPM_BASE, - .end = U8500_PRCMU_TCPM_BASE + SZ_32K - 1, - .flags = IORESOURCE_MEM, - }, -}; - -struct platform_device db8500_prcmu_device = { - .name = "db8500-prcmu", - .resource = db8500_prcmu_res, - .num_resources = ARRAY_SIZE(db8500_prcmu_res), - .dev = { - .platform_data = &db8500_prcmu_pdata, - }, -}; diff --git a/arch/arm/mach-ux500/devices-db8500.h b/arch/arm/mach-ux500/devices-db8500.h index 321998320f98..b8ffc9979bb2 100644 --- a/arch/arm/mach-ux500/devices-db8500.h +++ b/arch/arm/mach-ux500/devices-db8500.h @@ -8,122 +8,12 @@ #ifndef __DEVICES_DB8500_H #define __DEVICES_DB8500_H -#include <linux/platform_data/usb-musb-ux500.h> #include "irqs.h" #include "db8500-regs.h" -#include "devices-common.h" -struct ske_keypad_platform_data; -struct pl022_ssp_controller; struct platform_device; extern struct ab8500_platform_data ab8500_platdata; extern struct prcmu_pdata db8500_prcmu_pdata; -extern struct platform_device db8500_prcmu_device; -static inline struct platform_device * -db8500_add_ske_keypad(struct device *parent, - struct ske_keypad_platform_data *pdata, - size_t size) -{ - struct resource resources[] = { - DEFINE_RES_MEM(U8500_SKE_BASE, SZ_4K), - DEFINE_RES_IRQ(IRQ_DB8500_KB), - }; - - return platform_device_register_resndata(parent, "nmk-ske-keypad", -1, - resources, 2, pdata, size); -} - -static inline struct amba_device * -db8500_add_ssp(struct device *parent, const char *name, resource_size_t base, - int irq, struct pl022_ssp_controller *pdata) -{ - return amba_ahb_device_add(parent, name, base, SZ_4K, irq, 0, pdata, 0); -} - -#define db8500_add_i2c0(parent, pdata) \ - dbx500_add_i2c(parent, 0, U8500_I2C0_BASE, IRQ_DB8500_I2C0, pdata) -#define db8500_add_i2c1(parent, pdata) \ - dbx500_add_i2c(parent, 1, U8500_I2C1_BASE, IRQ_DB8500_I2C1, pdata) -#define db8500_add_i2c2(parent, pdata) \ - dbx500_add_i2c(parent, 2, U8500_I2C2_BASE, IRQ_DB8500_I2C2, pdata) -#define db8500_add_i2c3(parent, pdata) \ - dbx500_add_i2c(parent, 3, U8500_I2C3_BASE, IRQ_DB8500_I2C3, pdata) -#define db8500_add_i2c4(parent, pdata) \ - dbx500_add_i2c(parent, 4, U8500_I2C4_BASE, IRQ_DB8500_I2C4, pdata) - -#define db8500_add_msp0_spi(parent, pdata) \ - dbx500_add_msp_spi(parent, "msp0", U8500_MSP0_BASE, \ - IRQ_DB8500_MSP0, pdata) -#define db8500_add_msp1_spi(parent, pdata) \ - dbx500_add_msp_spi(parent, "msp1", U8500_MSP1_BASE, \ - IRQ_DB8500_MSP1, pdata) -#define db8500_add_msp2_spi(parent, pdata) \ - dbx500_add_msp_spi(parent, "msp2", U8500_MSP2_BASE, \ - IRQ_DB8500_MSP2, pdata) -#define db8500_add_msp3_spi(parent, pdata) \ - dbx500_add_msp_spi(parent, "msp3", U8500_MSP3_BASE, \ - IRQ_DB8500_MSP1, pdata) - -#define db8500_add_rtc(parent) \ - dbx500_add_rtc(parent, U8500_RTC_BASE, IRQ_DB8500_RTC); - -#define db8500_add_usb(parent, rx_cfg, tx_cfg) \ - ux500_add_usb(parent, U8500_USBOTG_BASE, \ - IRQ_DB8500_USBOTG, rx_cfg, tx_cfg) - -#define db8500_add_sdi0(parent, pdata, pid) \ - dbx500_add_sdi(parent, "sdi0", U8500_SDI0_BASE, \ - IRQ_DB8500_SDMMC0, pdata, pid) -#define db8500_add_sdi1(parent, pdata, pid) \ - dbx500_add_sdi(parent, "sdi1", U8500_SDI1_BASE, \ - IRQ_DB8500_SDMMC1, pdata, pid) -#define db8500_add_sdi2(parent, pdata, pid) \ - dbx500_add_sdi(parent, "sdi2", U8500_SDI2_BASE, \ - IRQ_DB8500_SDMMC2, pdata, pid) -#define db8500_add_sdi3(parent, pdata, pid) \ - dbx500_add_sdi(parent, "sdi3", U8500_SDI3_BASE, \ - IRQ_DB8500_SDMMC3, pdata, pid) -#define db8500_add_sdi4(parent, pdata, pid) \ - dbx500_add_sdi(parent, "sdi4", U8500_SDI4_BASE, \ - IRQ_DB8500_SDMMC4, pdata, pid) -#define db8500_add_sdi5(parent, pdata, pid) \ - dbx500_add_sdi(parent, "sdi5", U8500_SDI5_BASE, \ - IRQ_DB8500_SDMMC5, pdata, pid) - -#define db8500_add_ssp0(parent, pdata) \ - db8500_add_ssp(parent, "ssp0", U8500_SSP0_BASE, \ - IRQ_DB8500_SSP0, pdata) -#define db8500_add_ssp1(parent, pdata) \ - db8500_add_ssp(parent, "ssp1", U8500_SSP1_BASE, \ - IRQ_DB8500_SSP1, pdata) - -#define db8500_add_spi0(parent, pdata) \ - dbx500_add_spi(parent, "spi0", U8500_SPI0_BASE, \ - IRQ_DB8500_SPI0, pdata, 0) -#define db8500_add_spi1(parent, pdata) \ - dbx500_add_spi(parent, "spi1", U8500_SPI1_BASE, \ - IRQ_DB8500_SPI1, pdata, 0) -#define db8500_add_spi2(parent, pdata) \ - dbx500_add_spi(parent, "spi2", U8500_SPI2_BASE, \ - IRQ_DB8500_SPI2, pdata, 0) -#define db8500_add_spi3(parent, pdata) \ - dbx500_add_spi(parent, "spi3", U8500_SPI3_BASE, \ - IRQ_DB8500_SPI3, pdata, 0) - -#define db8500_add_uart0(parent, pdata) \ - dbx500_add_uart(parent, "uart0", U8500_UART0_BASE, \ - IRQ_DB8500_UART0, pdata) -#define db8500_add_uart1(parent, pdata) \ - dbx500_add_uart(parent, "uart1", U8500_UART1_BASE, \ - IRQ_DB8500_UART1, pdata) -#define db8500_add_uart2(parent, pdata) \ - dbx500_add_uart(parent, "uart2", U8500_UART2_BASE, \ - IRQ_DB8500_UART2, pdata) - -#define db8500_add_cryp1(parent, pdata) \ - dbx500_add_cryp1(parent, -1, U8500_CRYP1_BASE, IRQ_DB8500_CRYP1, pdata) -#define db8500_add_hash1(parent, pdata) \ - dbx500_add_hash1(parent, -1, U8500_HASH1_BASE, pdata) #endif diff --git a/arch/arm/mach-ux500/devices.h b/arch/arm/mach-ux500/devices.h index cbc6f1e4104d..5bca7c605cd6 100644 --- a/arch/arm/mach-ux500/devices.h +++ b/arch/arm/mach-ux500/devices.h @@ -10,14 +10,6 @@ struct platform_device; struct amba_device; -extern struct platform_device u8500_gpio_devs[]; - extern struct amba_device ux500_pl031_device; -extern struct platform_device ux500_hash1_device; -extern struct platform_device ux500_cryp1_device; - -extern struct platform_device u8500_dma40_device; -extern struct platform_device ux500_ske_keypad_device; - #endif diff --git a/arch/arm/mach-ux500/setup.h b/arch/arm/mach-ux500/setup.h index 656324aad18e..bdb356498a74 100644 --- a/arch/arm/mach-ux500/setup.h +++ b/arch/arm/mach-ux500/setup.h @@ -24,7 +24,6 @@ extern void __init u8500_map_io(void); extern struct device * __init u8500_init_devices(void); extern void __init ux500_init_irq(void); -extern void __init ux500_init_late(void); extern struct device *ux500_soc_device_init(const char *soc_id); diff --git a/arch/arm/mach-ux500/timer.c b/arch/arm/mach-ux500/timer.c index b6bd0efcbe64..05a4ff78b3bd 100644 --- a/arch/arm/mach-ux500/timer.c +++ b/arch/arm/mach-ux500/timer.c @@ -97,8 +97,8 @@ dt_fail: * sched_clock with higher rating then MTU since is always-on. * */ - - nmdk_timer_init(mtu_timer_base, IRQ_MTU0); + if (!of_have_populated_dt()) + nmdk_timer_init(mtu_timer_base, IRQ_MTU0); clksrc_dbx500_prcmu_init(prcmu_timer_base); ux500_twd_init(); } diff --git a/arch/arm/mach-ux500/usb.c b/arch/arm/mach-ux500/usb.c deleted file mode 100644 index b7bd8d3a5507..000000000000 --- a/arch/arm/mach-ux500/usb.c +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (C) ST-Ericsson SA 2011 - * - * Author: Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com> - * License terms: GNU General Public License (GPL) version 2 - */ -#include <linux/platform_device.h> -#include <linux/usb/musb.h> -#include <linux/dma-mapping.h> -#include <linux/platform_data/usb-musb-ux500.h> -#include <linux/platform_data/dma-ste-dma40.h> - -#include "db8500-regs.h" - -#define MUSB_DMA40_RX_CH { \ - .mode = STEDMA40_MODE_LOGICAL, \ - .dir = DMA_DEV_TO_MEM, \ - } - -#define MUSB_DMA40_TX_CH { \ - .mode = STEDMA40_MODE_LOGICAL, \ - .dir = DMA_MEM_TO_DEV, \ - } - -static struct stedma40_chan_cfg musb_dma_rx_ch[UX500_MUSB_DMA_NUM_RX_TX_CHANNELS] - = { - MUSB_DMA40_RX_CH, - MUSB_DMA40_RX_CH, - MUSB_DMA40_RX_CH, - MUSB_DMA40_RX_CH, - MUSB_DMA40_RX_CH, - MUSB_DMA40_RX_CH, - MUSB_DMA40_RX_CH, - MUSB_DMA40_RX_CH -}; - -static struct stedma40_chan_cfg musb_dma_tx_ch[UX500_MUSB_DMA_NUM_RX_TX_CHANNELS] - = { - MUSB_DMA40_TX_CH, - MUSB_DMA40_TX_CH, - MUSB_DMA40_TX_CH, - MUSB_DMA40_TX_CH, - MUSB_DMA40_TX_CH, - MUSB_DMA40_TX_CH, - MUSB_DMA40_TX_CH, - MUSB_DMA40_TX_CH, -}; - -static void *ux500_dma_rx_param_array[UX500_MUSB_DMA_NUM_RX_TX_CHANNELS] = { - &musb_dma_rx_ch[0], - &musb_dma_rx_ch[1], - &musb_dma_rx_ch[2], - &musb_dma_rx_ch[3], - &musb_dma_rx_ch[4], - &musb_dma_rx_ch[5], - &musb_dma_rx_ch[6], - &musb_dma_rx_ch[7] -}; - -static void *ux500_dma_tx_param_array[UX500_MUSB_DMA_NUM_RX_TX_CHANNELS] = { - &musb_dma_tx_ch[0], - &musb_dma_tx_ch[1], - &musb_dma_tx_ch[2], - &musb_dma_tx_ch[3], - &musb_dma_tx_ch[4], - &musb_dma_tx_ch[5], - &musb_dma_tx_ch[6], - &musb_dma_tx_ch[7] -}; - -static struct ux500_musb_board_data musb_board_data = { - .dma_rx_param_array = ux500_dma_rx_param_array, - .dma_tx_param_array = ux500_dma_tx_param_array, - .dma_filter = stedma40_filter, -}; - -static struct musb_hdrc_platform_data musb_platform_data = { - .mode = MUSB_OTG, - .board_data = &musb_board_data, -}; - -static struct resource usb_resources[] = { - [0] = { - .name = "usb-mem", - .flags = IORESOURCE_MEM, - }, - - [1] = { - .name = "mc", /* hard-coded in musb */ - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device ux500_musb_device = { - .name = "musb-ux500", - .id = 0, - .dev = { - .platform_data = &musb_platform_data, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .num_resources = ARRAY_SIZE(usb_resources), - .resource = usb_resources, -}; - -static inline void ux500_usb_dma_update_rx_ch_config(int *dev_type) -{ - u32 idx; - - for (idx = 0; idx < UX500_MUSB_DMA_NUM_RX_TX_CHANNELS; idx++) - musb_dma_rx_ch[idx].dev_type = dev_type[idx]; -} - -static inline void ux500_usb_dma_update_tx_ch_config(int *dev_type) -{ - u32 idx; - - for (idx = 0; idx < UX500_MUSB_DMA_NUM_RX_TX_CHANNELS; idx++) - musb_dma_tx_ch[idx].dev_type = dev_type[idx]; -} - -void ux500_add_usb(struct device *parent, resource_size_t base, int irq, - int *dma_rx_cfg, int *dma_tx_cfg) -{ - ux500_musb_device.resource[0].start = base; - ux500_musb_device.resource[0].end = base + SZ_64K - 1; - ux500_musb_device.resource[1].start = irq; - ux500_musb_device.resource[1].end = irq; - - ux500_usb_dma_update_rx_ch_config(dma_rx_cfg); - ux500_usb_dma_update_tx_ch_config(dma_tx_cfg); - - ux500_musb_device.dev.parent = parent; - - platform_device_register(&ux500_musb_device); -} diff --git a/arch/arm/mach-vexpress/Kconfig b/arch/arm/mach-vexpress/Kconfig index 365795447804..4a70be485ff8 100644 --- a/arch/arm/mach-vexpress/Kconfig +++ b/arch/arm/mach-vexpress/Kconfig @@ -1,17 +1,16 @@ config ARCH_VEXPRESS bool "ARM Ltd. Versatile Express family" if ARCH_MULTI_V7 select ARCH_REQUIRE_GPIOLIB + select ARCH_SUPPORTS_BIG_ENDIAN select ARM_AMBA select ARM_GIC select ARM_TIMER_SP804 - select CLKDEV_LOOKUP select COMMON_CLK select COMMON_CLK_VERSATILE select CPU_V7 select GENERIC_CLOCKEVENTS select HAVE_ARM_SCU if SMP select HAVE_ARM_TWD if SMP - select HAVE_CLK select HAVE_PATA_PLATFORM select HAVE_SMP select ICST @@ -66,10 +65,22 @@ config ARCH_VEXPRESS_DCSCB This is needed to provide CPU and cluster power management on RTSM implementing big.LITTLE. +config ARCH_VEXPRESS_SPC + bool "Versatile Express Serial Power Controller (SPC)" + select ARCH_HAS_CPUFREQ + select ARCH_HAS_OPP + select PM_OPP + help + The TC2 (A15x2 A7x3) versatile express core tile integrates a logic + block called Serial Power Controller (SPC) that provides the interface + between the dual cluster test-chip and the M3 microcontroller that + carries out power management. + config ARCH_VEXPRESS_TC2_PM bool "Versatile Express TC2 power management" depends on MCPM select ARM_CCI + select ARCH_VEXPRESS_SPC help Support for CPU and cluster power management on Versatile Express with a TC2 (A15x2 A7x3) big.LITTLE core tile. diff --git a/arch/arm/mach-vexpress/Makefile b/arch/arm/mach-vexpress/Makefile index 505e64ab3eae..0997e0b7494c 100644 --- a/arch/arm/mach-vexpress/Makefile +++ b/arch/arm/mach-vexpress/Makefile @@ -8,7 +8,8 @@ obj-y := v2m.o obj-$(CONFIG_ARCH_VEXPRESS_CA9X4) += ct-ca9x4.o obj-$(CONFIG_ARCH_VEXPRESS_DCSCB) += dcscb.o dcscb_setup.o CFLAGS_dcscb.o += -march=armv7-a -obj-$(CONFIG_ARCH_VEXPRESS_TC2_PM) += tc2_pm.o spc.o +obj-$(CONFIG_ARCH_VEXPRESS_SPC) += spc.o +obj-$(CONFIG_ARCH_VEXPRESS_TC2_PM) += tc2_pm.o CFLAGS_tc2_pm.o += -march=armv7-a obj-$(CONFIG_SMP) += platsmp.o obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o diff --git a/arch/arm/mach-vexpress/dcscb.c b/arch/arm/mach-vexpress/dcscb.c index 3a6384c6c435..14d499688736 100644 --- a/arch/arm/mach-vexpress/dcscb.c +++ b/arch/arm/mach-vexpress/dcscb.c @@ -133,38 +133,8 @@ static void dcscb_power_down(void) if (last_man && __mcpm_outbound_enter_critical(cpu, cluster)) { arch_spin_unlock(&dcscb_lock); - /* - * Flush all cache levels for this cluster. - * - * To do so we do: - * - Clear the SCTLR.C bit to prevent further cache allocations - * - Flush the whole cache - * - Clear the ACTLR "SMP" bit to disable local coherency - * - * Let's do it in the safest possible way i.e. with - * no memory access within the following sequence - * including to the stack. - * - * Note: fp is preserved to the stack explicitly prior doing - * this since adding it to the clobber list is incompatible - * with having CONFIG_FRAME_POINTER=y. - */ - asm volatile( - "str fp, [sp, #-4]! \n\t" - "mrc p15, 0, r0, c1, c0, 0 @ get CR \n\t" - "bic r0, r0, #"__stringify(CR_C)" \n\t" - "mcr p15, 0, r0, c1, c0, 0 @ set CR \n\t" - "isb \n\t" - "bl v7_flush_dcache_all \n\t" - "clrex \n\t" - "mrc p15, 0, r0, c1, c0, 1 @ get AUXCR \n\t" - "bic r0, r0, #(1 << 6) @ disable local coherency \n\t" - "mcr p15, 0, r0, c1, c0, 1 @ set AUXCR \n\t" - "isb \n\t" - "dsb \n\t" - "ldr fp, [sp], #4" - : : : "r0","r1","r2","r3","r4","r5","r6","r7", - "r9","r10","lr","memory"); + /* Flush all cache levels for this cluster. */ + v7_exit_coherency_flush(all); /* * This is a harmless no-op. On platforms with a real @@ -183,26 +153,8 @@ static void dcscb_power_down(void) } else { arch_spin_unlock(&dcscb_lock); - /* - * Flush the local CPU cache. - * Let's do it in the safest possible way as above. - */ - asm volatile( - "str fp, [sp, #-4]! \n\t" - "mrc p15, 0, r0, c1, c0, 0 @ get CR \n\t" - "bic r0, r0, #"__stringify(CR_C)" \n\t" - "mcr p15, 0, r0, c1, c0, 0 @ set CR \n\t" - "isb \n\t" - "bl v7_flush_dcache_louis \n\t" - "clrex \n\t" - "mrc p15, 0, r0, c1, c0, 1 @ get AUXCR \n\t" - "bic r0, r0, #(1 << 6) @ disable local coherency \n\t" - "mcr p15, 0, r0, c1, c0, 1 @ set AUXCR \n\t" - "isb \n\t" - "dsb \n\t" - "ldr fp, [sp], #4" - : : : "r0","r1","r2","r3","r4","r5","r6","r7", - "r9","r10","lr","memory"); + /* Disable and flush the local CPU cache. */ + v7_exit_coherency_flush(louis); } __mcpm_cpu_down(cpu, cluster); diff --git a/arch/arm/mach-vexpress/spc.c b/arch/arm/mach-vexpress/spc.c index eefb029197ca..033d34dcbd3f 100644 --- a/arch/arm/mach-vexpress/spc.c +++ b/arch/arm/mach-vexpress/spc.c @@ -17,14 +17,31 @@ * GNU General Public License for more details. */ +#include <linux/clk-provider.h> +#include <linux/clkdev.h> +#include <linux/cpu.h> +#include <linux/delay.h> #include <linux/err.h> +#include <linux/interrupt.h> #include <linux/io.h> +#include <linux/platform_device.h> +#include <linux/pm_opp.h> #include <linux/slab.h> +#include <linux/semaphore.h> #include <asm/cacheflush.h> #define SPCLOG "vexpress-spc: " +#define PERF_LVL_A15 0x00 +#define PERF_REQ_A15 0x04 +#define PERF_LVL_A7 0x08 +#define PERF_REQ_A7 0x0c +#define COMMS 0x10 +#define COMMS_REQ 0x14 +#define PWC_STATUS 0x18 +#define PWC_FLAG 0x1c + /* SPC wake-up IRQs status and mask */ #define WAKE_INT_MASK 0x24 #define WAKE_INT_RAW 0x28 @@ -36,12 +53,45 @@ #define A15_BX_ADDR0 0x68 #define A7_BX_ADDR0 0x78 +/* SPC system config interface registers */ +#define SYSCFG_WDATA 0x70 +#define SYSCFG_RDATA 0x74 + +/* A15/A7 OPP virtual register base */ +#define A15_PERFVAL_BASE 0xC10 +#define A7_PERFVAL_BASE 0xC30 + +/* Config interface control bits */ +#define SYSCFG_START (1 << 31) +#define SYSCFG_SCC (6 << 20) +#define SYSCFG_STAT (14 << 20) + /* wake-up interrupt masks */ #define GBL_WAKEUP_INT_MSK (0x3 << 10) /* TC2 static dual-cluster configuration */ #define MAX_CLUSTERS 2 +/* + * Even though the SPC takes max 3-5 ms to complete any OPP/COMMS + * operation, the operation could start just before jiffie is about + * to be incremented. So setting timeout value of 20ms = 2jiffies@100Hz + */ +#define TIMEOUT_US 20000 + +#define MAX_OPPS 8 +#define CA15_DVFS 0 +#define CA7_DVFS 1 +#define SPC_SYS_CFG 2 +#define STAT_COMPLETE(type) ((1 << 0) << (type << 2)) +#define STAT_ERR(type) ((1 << 1) << (type << 2)) +#define RESPONSE_MASK(type) (STAT_COMPLETE(type) | STAT_ERR(type)) + +struct ve_spc_opp { + unsigned long freq; + unsigned long u_volt; +}; + struct ve_spc_drvdata { void __iomem *baseaddr; /* @@ -49,6 +99,12 @@ struct ve_spc_drvdata { * It corresponds to A15 processors MPIDR[15:8] bitfield */ u32 a15_clusid; + uint32_t cur_rsp_mask; + uint32_t cur_rsp_stat; + struct semaphore sem; + struct completion done; + struct ve_spc_opp *opps[MAX_CLUSTERS]; + int num_opps[MAX_CLUSTERS]; }; static struct ve_spc_drvdata *info; @@ -157,8 +213,197 @@ void ve_spc_powerdown(u32 cluster, bool enable) writel_relaxed(enable, info->baseaddr + pwdrn_reg); } -int __init ve_spc_init(void __iomem *baseaddr, u32 a15_clusid) +static int ve_spc_get_performance(int cluster, u32 *freq) +{ + struct ve_spc_opp *opps = info->opps[cluster]; + u32 perf_cfg_reg = 0; + u32 perf; + + perf_cfg_reg = cluster_is_a15(cluster) ? PERF_LVL_A15 : PERF_LVL_A7; + + perf = readl_relaxed(info->baseaddr + perf_cfg_reg); + if (perf >= info->num_opps[cluster]) + return -EINVAL; + + opps += perf; + *freq = opps->freq; + + return 0; +} + +/* find closest match to given frequency in OPP table */ +static int ve_spc_round_performance(int cluster, u32 freq) +{ + int idx, max_opp = info->num_opps[cluster]; + struct ve_spc_opp *opps = info->opps[cluster]; + u32 fmin = 0, fmax = ~0, ftmp; + + freq /= 1000; /* OPP entries in kHz */ + for (idx = 0; idx < max_opp; idx++, opps++) { + ftmp = opps->freq; + if (ftmp >= freq) { + if (ftmp <= fmax) + fmax = ftmp; + } else { + if (ftmp >= fmin) + fmin = ftmp; + } + } + if (fmax != ~0) + return fmax * 1000; + else + return fmin * 1000; +} + +static int ve_spc_find_performance_index(int cluster, u32 freq) +{ + int idx, max_opp = info->num_opps[cluster]; + struct ve_spc_opp *opps = info->opps[cluster]; + + for (idx = 0; idx < max_opp; idx++, opps++) + if (opps->freq == freq) + break; + return (idx == max_opp) ? -EINVAL : idx; +} + +static int ve_spc_waitforcompletion(int req_type) +{ + int ret = wait_for_completion_interruptible_timeout( + &info->done, usecs_to_jiffies(TIMEOUT_US)); + if (ret == 0) + ret = -ETIMEDOUT; + else if (ret > 0) + ret = info->cur_rsp_stat & STAT_COMPLETE(req_type) ? 0 : -EIO; + return ret; +} + +static int ve_spc_set_performance(int cluster, u32 freq) +{ + u32 perf_cfg_reg, perf_stat_reg; + int ret, perf, req_type; + + if (cluster_is_a15(cluster)) { + req_type = CA15_DVFS; + perf_cfg_reg = PERF_LVL_A15; + perf_stat_reg = PERF_REQ_A15; + } else { + req_type = CA7_DVFS; + perf_cfg_reg = PERF_LVL_A7; + perf_stat_reg = PERF_REQ_A7; + } + + perf = ve_spc_find_performance_index(cluster, freq); + + if (perf < 0) + return perf; + + if (down_timeout(&info->sem, usecs_to_jiffies(TIMEOUT_US))) + return -ETIME; + + init_completion(&info->done); + info->cur_rsp_mask = RESPONSE_MASK(req_type); + + writel(perf, info->baseaddr + perf_cfg_reg); + ret = ve_spc_waitforcompletion(req_type); + + info->cur_rsp_mask = 0; + up(&info->sem); + + return ret; +} + +static int ve_spc_read_sys_cfg(int func, int offset, uint32_t *data) +{ + int ret; + + if (down_timeout(&info->sem, usecs_to_jiffies(TIMEOUT_US))) + return -ETIME; + + init_completion(&info->done); + info->cur_rsp_mask = RESPONSE_MASK(SPC_SYS_CFG); + + /* Set the control value */ + writel(SYSCFG_START | func | offset >> 2, info->baseaddr + COMMS); + ret = ve_spc_waitforcompletion(SPC_SYS_CFG); + + if (ret == 0) + *data = readl(info->baseaddr + SYSCFG_RDATA); + + info->cur_rsp_mask = 0; + up(&info->sem); + + return ret; +} + +static irqreturn_t ve_spc_irq_handler(int irq, void *data) +{ + struct ve_spc_drvdata *drv_data = data; + uint32_t status = readl_relaxed(drv_data->baseaddr + PWC_STATUS); + + if (info->cur_rsp_mask & status) { + info->cur_rsp_stat = status; + complete(&drv_data->done); + } + + return IRQ_HANDLED; +} + +/* + * +--------------------------+ + * | 31 20 | 19 0 | + * +--------------------------+ + * | u_volt | freq(kHz) | + * +--------------------------+ + */ +#define MULT_FACTOR 20 +#define VOLT_SHIFT 20 +#define FREQ_MASK (0xFFFFF) +static int ve_spc_populate_opps(uint32_t cluster) { + uint32_t data = 0, off, ret, idx; + struct ve_spc_opp *opps; + + opps = kzalloc(sizeof(*opps) * MAX_OPPS, GFP_KERNEL); + if (!opps) + return -ENOMEM; + + info->opps[cluster] = opps; + + off = cluster_is_a15(cluster) ? A15_PERFVAL_BASE : A7_PERFVAL_BASE; + for (idx = 0; idx < MAX_OPPS; idx++, off += 4, opps++) { + ret = ve_spc_read_sys_cfg(SYSCFG_SCC, off, &data); + if (!ret) { + opps->freq = (data & FREQ_MASK) * MULT_FACTOR; + opps->u_volt = data >> VOLT_SHIFT; + } else { + break; + } + } + info->num_opps[cluster] = idx; + + return ret; +} + +static int ve_init_opp_table(struct device *cpu_dev) +{ + int cluster = topology_physical_package_id(cpu_dev->id); + int idx, ret = 0, max_opp = info->num_opps[cluster]; + struct ve_spc_opp *opps = info->opps[cluster]; + + for (idx = 0; idx < max_opp; idx++, opps++) { + ret = dev_pm_opp_add(cpu_dev, opps->freq * 1000, opps->u_volt); + if (ret) { + dev_warn(cpu_dev, "failed to add opp %lu %lu\n", + opps->freq, opps->u_volt); + return ret; + } + } + return ret; +} + +int __init ve_spc_init(void __iomem *baseaddr, u32 a15_clusid, int irq) +{ + int ret; info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) { pr_err(SPCLOG "unable to allocate mem\n"); @@ -168,6 +413,25 @@ int __init ve_spc_init(void __iomem *baseaddr, u32 a15_clusid) info->baseaddr = baseaddr; info->a15_clusid = a15_clusid; + if (irq <= 0) { + pr_err(SPCLOG "Invalid IRQ %d\n", irq); + kfree(info); + return -EINVAL; + } + + init_completion(&info->done); + + readl_relaxed(info->baseaddr + PWC_STATUS); + + ret = request_irq(irq, ve_spc_irq_handler, IRQF_TRIGGER_HIGH + | IRQF_ONESHOT, "vexpress-spc", info); + if (ret) { + pr_err(SPCLOG "IRQ %d request failed\n", irq); + kfree(info); + return -ENODEV; + } + + sema_init(&info->sem, 1); /* * Multi-cluster systems may need this data when non-coherent, during * cluster power-up/power-down. Make sure driver info reaches main @@ -178,3 +442,103 @@ int __init ve_spc_init(void __iomem *baseaddr, u32 a15_clusid) return 0; } + +struct clk_spc { + struct clk_hw hw; + int cluster; +}; + +#define to_clk_spc(spc) container_of(spc, struct clk_spc, hw) +static unsigned long spc_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_spc *spc = to_clk_spc(hw); + u32 freq; + + if (ve_spc_get_performance(spc->cluster, &freq)) + return -EIO; + + return freq * 1000; +} + +static long spc_round_rate(struct clk_hw *hw, unsigned long drate, + unsigned long *parent_rate) +{ + struct clk_spc *spc = to_clk_spc(hw); + + return ve_spc_round_performance(spc->cluster, drate); +} + +static int spc_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_spc *spc = to_clk_spc(hw); + + return ve_spc_set_performance(spc->cluster, rate / 1000); +} + +static struct clk_ops clk_spc_ops = { + .recalc_rate = spc_recalc_rate, + .round_rate = spc_round_rate, + .set_rate = spc_set_rate, +}; + +static struct clk *ve_spc_clk_register(struct device *cpu_dev) +{ + struct clk_init_data init; + struct clk_spc *spc; + + spc = kzalloc(sizeof(*spc), GFP_KERNEL); + if (!spc) { + pr_err("could not allocate spc clk\n"); + return ERR_PTR(-ENOMEM); + } + + spc->hw.init = &init; + spc->cluster = topology_physical_package_id(cpu_dev->id); + + init.name = dev_name(cpu_dev); + init.ops = &clk_spc_ops; + init.flags = CLK_IS_ROOT | CLK_GET_RATE_NOCACHE; + init.num_parents = 0; + + return devm_clk_register(cpu_dev, &spc->hw); +} + +static int __init ve_spc_clk_init(void) +{ + int cpu; + struct clk *clk; + + if (!info) + return 0; /* Continue only if SPC is initialised */ + + if (ve_spc_populate_opps(0) || ve_spc_populate_opps(1)) { + pr_err("failed to build OPP table\n"); + return -ENODEV; + } + + for_each_possible_cpu(cpu) { + struct device *cpu_dev = get_cpu_device(cpu); + if (!cpu_dev) { + pr_warn("failed to get cpu%d device\n", cpu); + continue; + } + clk = ve_spc_clk_register(cpu_dev); + if (IS_ERR(clk)) { + pr_warn("failed to register cpu%d clock\n", cpu); + continue; + } + if (clk_register_clkdev(clk, NULL, dev_name(cpu_dev))) { + pr_warn("failed to register cpu%d clock lookup\n", cpu); + continue; + } + + if (ve_init_opp_table(cpu_dev)) + pr_warn("failed to initialise cpu%d opp table\n", cpu); + } + + platform_device_register_simple("vexpress-spc-cpufreq", -1, NULL, 0); + return 0; +} +module_init(ve_spc_clk_init); diff --git a/arch/arm/mach-vexpress/spc.h b/arch/arm/mach-vexpress/spc.h index 5f7e4a446a17..dbd44c3720f9 100644 --- a/arch/arm/mach-vexpress/spc.h +++ b/arch/arm/mach-vexpress/spc.h @@ -15,7 +15,7 @@ #ifndef __SPC_H_ #define __SPC_H_ -int __init ve_spc_init(void __iomem *base, u32 a15_clusid); +int __init ve_spc_init(void __iomem *base, u32 a15_clusid, int irq); void ve_spc_global_wakeup_irq(bool set); void ve_spc_cpu_wakeup_irq(u32 cluster, u32 cpu, bool set); void ve_spc_set_resume_addr(u32 cluster, u32 cpu, u32 addr); diff --git a/arch/arm/mach-vexpress/tc2_pm.c b/arch/arm/mach-vexpress/tc2_pm.c index e6eb48192912..05a364c5077a 100644 --- a/arch/arm/mach-vexpress/tc2_pm.c +++ b/arch/arm/mach-vexpress/tc2_pm.c @@ -16,6 +16,7 @@ #include <linux/io.h> #include <linux/kernel.h> #include <linux/of_address.h> +#include <linux/of_irq.h> #include <linux/spinlock.h> #include <linux/errno.h> #include <linux/irqchip/arm-gic.h> @@ -156,32 +157,7 @@ static void tc2_pm_down(u64 residency) : : "r" (0x400) ); } - /* - * We need to disable and flush the whole (L1 and L2) cache. - * Let's do it in the safest possible way i.e. with - * no memory access within the following sequence - * including the stack. - * - * Note: fp is preserved to the stack explicitly prior doing - * this since adding it to the clobber list is incompatible - * with having CONFIG_FRAME_POINTER=y. - */ - asm volatile( - "str fp, [sp, #-4]! \n\t" - "mrc p15, 0, r0, c1, c0, 0 @ get CR \n\t" - "bic r0, r0, #"__stringify(CR_C)" \n\t" - "mcr p15, 0, r0, c1, c0, 0 @ set CR \n\t" - "isb \n\t" - "bl v7_flush_dcache_all \n\t" - "clrex \n\t" - "mrc p15, 0, r0, c1, c0, 1 @ get AUXCR \n\t" - "bic r0, r0, #(1 << 6) @ disable local coherency \n\t" - "mcr p15, 0, r0, c1, c0, 1 @ set AUXCR \n\t" - "isb \n\t" - "dsb \n\t" - "ldr fp, [sp], #4" - : : : "r0","r1","r2","r3","r4","r5","r6","r7", - "r9","r10","lr","memory"); + v7_exit_coherency_flush(all); cci_disable_port_by_cpu(mpidr); @@ -197,26 +173,7 @@ static void tc2_pm_down(u64 residency) arch_spin_unlock(&tc2_pm_lock); - /* - * We need to disable and flush only the L1 cache. - * Let's do it in the safest possible way as above. - */ - asm volatile( - "str fp, [sp, #-4]! \n\t" - "mrc p15, 0, r0, c1, c0, 0 @ get CR \n\t" - "bic r0, r0, #"__stringify(CR_C)" \n\t" - "mcr p15, 0, r0, c1, c0, 0 @ set CR \n\t" - "isb \n\t" - "bl v7_flush_dcache_louis \n\t" - "clrex \n\t" - "mrc p15, 0, r0, c1, c0, 1 @ get AUXCR \n\t" - "bic r0, r0, #(1 << 6) @ disable local coherency \n\t" - "mcr p15, 0, r0, c1, c0, 1 @ set AUXCR \n\t" - "isb \n\t" - "dsb \n\t" - "ldr fp, [sp], #4" - : : : "r0","r1","r2","r3","r4","r5","r6","r7", - "r9","r10","lr","memory"); + v7_exit_coherency_flush(louis); } __mcpm_cpu_down(cpu, cluster); @@ -311,7 +268,7 @@ static void __naked tc2_pm_power_up_setup(unsigned int affinity_level) static int __init tc2_pm_init(void) { - int ret; + int ret, irq; void __iomem *scc; u32 a15_cluster_id, a7_cluster_id, sys_info; struct device_node *np; @@ -336,13 +293,15 @@ static int __init tc2_pm_init(void) tc2_nr_cpus[a15_cluster_id] = (sys_info >> 16) & 0xf; tc2_nr_cpus[a7_cluster_id] = (sys_info >> 20) & 0xf; + irq = irq_of_parse_and_map(np, 0); + /* * A subset of the SCC registers is also used to communicate * with the SPC (power controller). We need to be able to * drive it very early in the boot process to power up * processors, so we initialize the SPC driver here. */ - ret = ve_spc_init(scc + SPC_BASE, a15_cluster_id); + ret = ve_spc_init(scc + SPC_BASE, a15_cluster_id, irq); if (ret) return ret; diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c index 95a469e23e37..4f8b8cb17ff5 100644 --- a/arch/arm/mach-vexpress/v2m.c +++ b/arch/arm/mach-vexpress/v2m.c @@ -1,12 +1,10 @@ /* * Versatile Express V2M Motherboard Support */ -#include <linux/clocksource.h> #include <linux/device.h> #include <linux/amba/bus.h> #include <linux/amba/mmci.h> #include <linux/io.h> -#include <linux/clocksource.h> #include <linux/smp.h> #include <linux/init.h> #include <linux/of_address.h> @@ -22,7 +20,6 @@ #include <linux/regulator/fixed.h> #include <linux/regulator/machine.h> #include <linux/vexpress.h> -#include <linux/clk-provider.h> #include <linux/clkdev.h> #include <asm/mach-types.h> @@ -422,16 +419,8 @@ void __init v2m_dt_init_early(void) pr_warning("vexpress: DT HBI (%x) is not matching " "hardware (%x)!\n", dt_hbi, hbi); } -} - -static void __init v2m_dt_timer_init(void) -{ - of_clk_init(NULL); - clocksource_of_init(); - - versatile_sched_clock_init(vexpress_get_24mhz_clock_base(), - 24000000); + versatile_sched_clock_init(vexpress_get_24mhz_clock_base(), 24000000); } static const struct of_device_id v2m_dt_bus_match[] __initconst = { @@ -458,6 +447,5 @@ DT_MACHINE_START(VEXPRESS_DT, "ARM-Versatile Express") .smp_init = smp_init_ops(vexpress_smp_init_ops), .map_io = v2m_dt_map_io, .init_early = v2m_dt_init_early, - .init_time = v2m_dt_timer_init, .init_machine = v2m_dt_init, MACHINE_END diff --git a/arch/arm/mach-vt8500/Kconfig b/arch/arm/mach-vt8500/Kconfig index 9b252934b206..927be93b692e 100644 --- a/arch/arm/mach-vt8500/Kconfig +++ b/arch/arm/mach-vt8500/Kconfig @@ -5,7 +5,6 @@ config ARCH_VT8500 select CLKDEV_LOOKUP select CLKSRC_OF select GENERIC_CLOCKEVENTS - select HAVE_CLK select VT8500_TIMER select PINCTRL help diff --git a/arch/arm/mach-vt8500/common.h b/arch/arm/mach-vt8500/common.h deleted file mode 100644 index 087787af62f1..000000000000 --- a/arch/arm/mach-vt8500/common.h +++ /dev/null @@ -1,24 +0,0 @@ -/* linux/arch/arm/mach-vt8500/dt_common.h - * - * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz> - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that 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. - * - */ - -#ifndef __ARCH_ARM_MACH_VT8500_DT_COMMON_H -#define __ARCH_ARM_MACH_VT8500_DT_COMMON_H - -#include <linux/of.h> - -/* defined in drivers/clk/clk-vt8500.c */ -void __init vtwm_clk_init(void __iomem *pmc_base); - -#endif diff --git a/arch/arm/mach-vt8500/vt8500.c b/arch/arm/mach-vt8500/vt8500.c index eefaa60d6614..4a73464cb11b 100644 --- a/arch/arm/mach-vt8500/vt8500.c +++ b/arch/arm/mach-vt8500/vt8500.c @@ -18,7 +18,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <linux/clocksource.h> #include <linux/io.h> #include <linux/pm.h> #include <linux/reboot.h> @@ -33,8 +32,6 @@ #include <linux/of_irq.h> #include <linux/of_platform.h> -#include "common.h" - #define LEGACY_GPIO_BASE 0xD8110000 #define LEGACY_PMC_BASE 0xD8130000 @@ -162,8 +159,6 @@ void __init vt8500_init(void) else pr_err("%s: PMC Hibernation register could not be remapped, not enabling power off!\n", __func__); - vtwm_clk_init(pmc_base); - of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); } @@ -180,7 +175,6 @@ DT_MACHINE_START(WMT_DT, "VIA/Wondermedia SoC (Device Tree Support)") .dt_compat = vt8500_dt_compat, .map_io = vt8500_map_io, .init_machine = vt8500_init, - .init_time = clocksource_of_init, .restart = vt8500_restart, MACHINE_END diff --git a/arch/arm/mach-w90x900/include/mach/gpio.h b/arch/arm/mach-w90x900/include/mach/gpio.h deleted file mode 100644 index 5385a4203277..000000000000 --- a/arch/arm/mach-w90x900/include/mach/gpio.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * linux/arch/arm/mach-w90p910/include/mach/gpio.h - * - * Generic w90p910 GPIO handling - * - * Wan ZongShun <mcuos.com@gmail.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 - * published by the Free Software Foundation. - */ - -#ifndef __ASM_ARCH_W90P910_GPIO_H -#define __ASM_ARCH_W90P910_GPIO_H - -#include <mach/hardware.h> -#include <asm/irq.h> - -static inline int gpio_to_irq(unsigned gpio) -{ - return gpio; -} -#define gpio_to_irq gpio_to_irq - -static inline int irq_to_gpio(unsigned irq) -{ - return irq; -} - -#endif diff --git a/arch/arm/mach-zynq/Kconfig b/arch/arm/mach-zynq/Kconfig index 04f8a4a6e755..6b04260aa142 100644 --- a/arch/arm/mach-zynq/Kconfig +++ b/arch/arm/mach-zynq/Kconfig @@ -13,5 +13,6 @@ config ARCH_ZYNQ select HAVE_SMP select SPARSE_IRQ select CADENCE_TTC_TIMER + select ARM_GLOBAL_TIMER help Support for Xilinx Zynq ARM Cortex A9 Platform diff --git a/arch/arm/mach-zynq/common.c b/arch/arm/mach-zynq/common.c index 5f252569c689..9a7bd137c8fd 100644 --- a/arch/arm/mach-zynq/common.c +++ b/arch/arm/mach-zynq/common.c @@ -44,6 +44,10 @@ static struct of_device_id zynq_of_bus_ids[] __initdata = { {} }; +static struct platform_device zynq_cpuidle_device = { + .name = "cpuidle-zynq", +}; + /** * zynq_init_machine - System specific initialization, intended to be * called from board specific initialization. @@ -56,6 +60,8 @@ static void __init zynq_init_machine(void) l2x0_of_init(0x02060000, 0xF0F0FFFF); of_platform_bus_probe(NULL, zynq_of_bus_ids, NULL); + + platform_device_register(&zynq_cpuidle_device); } static void __init zynq_timer_init(void) diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index cd2c88e7a8f7..1f8fed94c2a4 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -952,3 +952,9 @@ config ARCH_HAS_BARRIERS help This option allows the use of custom mandatory barriers included via the mach/barriers.h file. + +config ARCH_SUPPORTS_BIG_ENDIAN + bool + help + This option specifies the architecture can support big endian + operation. diff --git a/arch/arm/mm/abort-ev6.S b/arch/arm/mm/abort-ev6.S index 80741992a9fc..3815a8262af0 100644 --- a/arch/arm/mm/abort-ev6.S +++ b/arch/arm/mm/abort-ev6.S @@ -38,9 +38,8 @@ ENTRY(v6_early_abort) bne do_DataAbort bic r1, r1, #1 << 11 @ clear bit 11 of FSR ldr r3, [r4] @ read aborted ARM instruction -#ifdef CONFIG_CPU_ENDIAN_BE8 - rev r3, r3 -#endif + ARM_BE8(rev r3, r3) + do_ldrd_abort tmp=ip, insn=r3 tst r3, #1 << 20 @ L = 0 -> write orreq r1, r1, #1 << 11 @ yes. diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c index 6f4585b89078..924036473b16 100644 --- a/arch/arm/mm/alignment.c +++ b/arch/arm/mm/alignment.c @@ -25,6 +25,7 @@ #include <asm/cp15.h> #include <asm/system_info.h> #include <asm/unaligned.h> +#include <asm/opcodes.h> #include "fault.h" @@ -762,21 +763,25 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) if (thumb_mode(regs)) { u16 *ptr = (u16 *)(instrptr & ~1); fault = probe_kernel_address(ptr, tinstr); + tinstr = __mem_to_opcode_thumb16(tinstr); if (!fault) { if (cpu_architecture() >= CPU_ARCH_ARMv7 && IS_T32(tinstr)) { /* Thumb-2 32-bit */ u16 tinst2 = 0; fault = probe_kernel_address(ptr + 1, tinst2); - instr = (tinstr << 16) | tinst2; + tinst2 = __mem_to_opcode_thumb16(tinst2); + instr = __opcode_thumb32_compose(tinstr, tinst2); thumb2_32b = 1; } else { isize = 2; instr = thumb2arm(tinstr); } } - } else + } else { fault = probe_kernel_address(instrptr, instr); + instr = __mem_to_opcode_arm(instr); + } if (fault) { type = TYPE_FAULT; diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 1272ed202dde..79f8b39801a8 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -159,7 +159,7 @@ EXPORT_SYMBOL(arm_coherent_dma_ops); static u64 get_coherent_dma_mask(struct device *dev) { - u64 mask = (u64)arm_dma_limit; + u64 mask = (u64)DMA_BIT_MASK(32); if (dev) { mask = dev->coherent_dma_mask; @@ -173,10 +173,30 @@ static u64 get_coherent_dma_mask(struct device *dev) return 0; } - if ((~mask) & (u64)arm_dma_limit) { - dev_warn(dev, "coherent DMA mask %#llx is smaller " - "than system GFP_DMA mask %#llx\n", - mask, (u64)arm_dma_limit); + /* + * If the mask allows for more memory than we can address, + * and we actually have that much memory, then fail the + * allocation. + */ + if (sizeof(mask) != sizeof(dma_addr_t) && + mask > (dma_addr_t)~0 && + dma_to_pfn(dev, ~0) > arm_dma_pfn_limit) { + dev_warn(dev, "Coherent DMA mask %#llx is larger than dma_addr_t allows\n", + mask); + dev_warn(dev, "Driver did not use or check the return value from dma_set_coherent_mask()?\n"); + return 0; + } + + /* + * Now check that the mask, when translated to a PFN, + * fits within the allowable addresses which we can + * allocate. + */ + if (dma_to_pfn(dev, mask) < arm_dma_pfn_limit) { + dev_warn(dev, "Coherent DMA mask %#llx (pfn %#lx-%#lx) covers a smaller range of system memory than the DMA zone pfn 0x0-%#lx\n", + mask, + dma_to_pfn(dev, 0), dma_to_pfn(dev, mask) + 1, + arm_dma_pfn_limit + 1); return 0; } } @@ -687,7 +707,7 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs) { - pgprot_t prot = __get_dma_pgprot(attrs, pgprot_kernel); + pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL); void *memory; if (dma_alloc_from_coherent(dev, size, handle, &memory)) @@ -700,7 +720,7 @@ void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, static void *arm_coherent_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs) { - pgprot_t prot = __get_dma_pgprot(attrs, pgprot_kernel); + pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL); void *memory; if (dma_alloc_from_coherent(dev, size, handle, &memory)) @@ -1007,8 +1027,27 @@ void arm_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, */ int dma_supported(struct device *dev, u64 mask) { - if (mask < (u64)arm_dma_limit) + unsigned long limit; + + /* + * If the mask allows for more memory than we can address, + * and we actually have that much memory, then we must + * indicate that DMA to this device is not supported. + */ + if (sizeof(mask) != sizeof(dma_addr_t) && + mask > (dma_addr_t)~0 && + dma_to_pfn(dev, ~0) > arm_dma_pfn_limit) return 0; + + /* + * Translate the device's DMA mask to a PFN limit. This + * PFN number includes the page which we can DMA to. + */ + limit = dma_to_pfn(dev, mask); + + if (limit < arm_dma_pfn_limit) + return 0; + return 1; } EXPORT_SYMBOL(dma_supported); diff --git a/arch/arm/mm/extable.c b/arch/arm/mm/extable.c index 9d285626bc7d..312e15e6d00b 100644 --- a/arch/arm/mm/extable.c +++ b/arch/arm/mm/extable.c @@ -9,8 +9,13 @@ int fixup_exception(struct pt_regs *regs) const struct exception_table_entry *fixup; fixup = search_exception_tables(instruction_pointer(regs)); - if (fixup) + if (fixup) { regs->ARM_pc = fixup->fixup; +#ifdef CONFIG_THUMB2_KERNEL + /* Clear the IT state to avoid nasty surprises in the fixup */ + regs->ARM_cpsr &= ~PSR_IT_MASK; +#endif + } return fixup != NULL; } diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c index 2a5907b5c8d2..ff379ac115df 100644 --- a/arch/arm/mm/fault-armv.c +++ b/arch/arm/mm/fault-armv.c @@ -65,7 +65,7 @@ static int do_adjust_pte(struct vm_area_struct *vma, unsigned long address, return ret; } -#if USE_SPLIT_PTLOCKS +#if USE_SPLIT_PTE_PTLOCKS /* * If we are using split PTE locks, then we need to take the page * lock here. Otherwise we are using shared mm->page_table_lock @@ -84,10 +84,10 @@ static inline void do_pte_unlock(spinlock_t *ptl) { spin_unlock(ptl); } -#else /* !USE_SPLIT_PTLOCKS */ +#else /* !USE_SPLIT_PTE_PTLOCKS */ static inline void do_pte_lock(spinlock_t *ptl) {} static inline void do_pte_unlock(spinlock_t *ptl) {} -#endif /* USE_SPLIT_PTLOCKS */ +#endif /* USE_SPLIT_PTE_PTLOCKS */ static int adjust_pte(struct vm_area_struct *vma, unsigned long address, unsigned long pfn) diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c index 83cb3ac27095..8e0e52eb76b5 100644 --- a/arch/arm/mm/idmap.c +++ b/arch/arm/mm/idmap.c @@ -10,6 +10,7 @@ #include <asm/system_info.h> pgd_t *idmap_pgd; +phys_addr_t (*arch_virt_to_idmap) (unsigned long x); #ifdef CONFIG_ARM_LPAE static void idmap_add_pmd(pud_t *pud, unsigned long addr, unsigned long end, @@ -67,8 +68,9 @@ static void identity_mapping_add(pgd_t *pgd, const char *text_start, unsigned long addr, end; unsigned long next; - addr = virt_to_phys(text_start); - end = virt_to_phys(text_end); + addr = virt_to_idmap(text_start); + end = virt_to_idmap(text_end); + pr_info("Setting up static identity map for 0x%lx - 0x%lx\n", addr, end); prot |= PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AF; @@ -90,8 +92,6 @@ static int __init init_static_idmap(void) if (!idmap_pgd) return -ENOMEM; - pr_info("Setting up static identity map for 0x%p - 0x%p\n", - __idmap_text_start, __idmap_text_end); identity_mapping_add(idmap_pgd, __idmap_text_start, __idmap_text_end, 0); diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 18ec4c504abf..3e8f106ee5fe 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -76,14 +76,6 @@ static int __init parse_tag_initrd2(const struct tag *tag) __tagtable(ATAG_INITRD2, parse_tag_initrd2); -#ifdef CONFIG_OF_FLATTREE -void __init early_init_dt_setup_initrd_arch(u64 start, u64 end) -{ - phys_initrd_start = start; - phys_initrd_size = end - start; -} -#endif /* CONFIG_OF_FLATTREE */ - /* * This keeps memory configuration data used by a couple memory * initialization functions, as well as show_mem() for the skipping @@ -217,6 +209,7 @@ EXPORT_SYMBOL(arm_dma_zone_size); * so a successful GFP_DMA allocation will always satisfy this. */ phys_addr_t arm_dma_limit; +unsigned long arm_dma_pfn_limit; static void __init arm_adjust_dma_zone(unsigned long *size, unsigned long *hole, unsigned long dma_size) @@ -239,6 +232,7 @@ void __init setup_dma_zone(const struct machine_desc *mdesc) arm_dma_limit = PHYS_OFFSET + arm_dma_zone_size - 1; } else arm_dma_limit = 0xffffffff; + arm_dma_pfn_limit = arm_dma_limit >> PAGE_SHIFT; #endif } @@ -350,6 +344,11 @@ void __init arm_memblock_init(struct meminfo *mi, memblock_reserve(__pa(_stext), _end - _stext); #endif #ifdef CONFIG_BLK_DEV_INITRD + /* FDT scan will populate initrd_start */ + if (initrd_start) { + phys_initrd_start = __virt_to_phys(initrd_start); + phys_initrd_size = initrd_end - initrd_start; + } if (phys_initrd_size && !memblock_is_region_memory(phys_initrd_start, phys_initrd_size)) { pr_err("INITRD: 0x%08llx+0x%08lx is not a memory region - disabling initrd\n", @@ -421,12 +420,10 @@ void __init bootmem_init(void) * This doesn't seem to be used by the Linux memory manager any * more, but is used by ll_rw_block. If we can get rid of it, we * also get rid of some of the stuff above as well. - * - * Note: max_low_pfn and max_pfn reflect the number of _pages_ in - * the system, not the maximum PFN. */ - max_low_pfn = max_low - PHYS_PFN_OFFSET; - max_pfn = max_high - PHYS_PFN_OFFSET; + min_low_pfn = min; + max_low_pfn = max_low; + max_pfn = max_high; } /* @@ -532,7 +529,7 @@ static inline void free_area_high(unsigned long pfn, unsigned long end) static void __init free_highpages(void) { #ifdef CONFIG_HIGHMEM - unsigned long max_low = max_low_pfn + PHYS_PFN_OFFSET; + unsigned long max_low = max_low_pfn; struct memblock_region *mem, *res; /* set highmem page free */ diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h index d5a4e9ad8f0f..d5a982d15a88 100644 --- a/arch/arm/mm/mm.h +++ b/arch/arm/mm/mm.h @@ -81,8 +81,10 @@ extern __init void add_static_vm_early(struct static_vm *svm); #ifdef CONFIG_ZONE_DMA extern phys_addr_t arm_dma_limit; +extern unsigned long arm_dma_pfn_limit; #else #define arm_dma_limit ((phys_addr_t)~0) +#define arm_dma_pfn_limit (~0ul >> PAGE_SHIFT) #endif extern phys_addr_t arm_lowmem_limit; diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c index 0c6356255fe3..d27158c38eb0 100644 --- a/arch/arm/mm/mmap.c +++ b/arch/arm/mm/mmap.c @@ -202,13 +202,11 @@ int valid_phys_addr_range(phys_addr_t addr, size_t size) } /* - * We don't use supersection mappings for mmap() on /dev/mem, which - * means that we can't map the memory area above the 4G barrier into - * userspace. + * Do not allow /dev/mem mappings beyond the supported physical range. */ int valid_mmap_phys_addr_range(unsigned long pfn, size_t size) { - return !(pfn + (size >> PAGE_SHIFT) > 0x00100000); + return (pfn + (size >> PAGE_SHIFT)) <= (1 + (PHYS_MASK >> PAGE_SHIFT)); } #ifdef CONFIG_STRICT_DEVMEM diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index b1d17eeb59b8..78eeeca78f5a 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -28,6 +28,8 @@ #include <asm/highmem.h> #include <asm/system_info.h> #include <asm/traps.h> +#include <asm/procinfo.h> +#include <asm/memory.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> @@ -1315,6 +1317,86 @@ static void __init map_lowmem(void) } } +#ifdef CONFIG_ARM_LPAE +/* + * early_paging_init() recreates boot time page table setup, allowing machines + * to switch over to a high (>4G) address space on LPAE systems + */ +void __init early_paging_init(const struct machine_desc *mdesc, + struct proc_info_list *procinfo) +{ + pmdval_t pmdprot = procinfo->__cpu_mm_mmu_flags; + unsigned long map_start, map_end; + pgd_t *pgd0, *pgdk; + pud_t *pud0, *pudk, *pud_start; + pmd_t *pmd0, *pmdk; + phys_addr_t phys; + int i; + + if (!(mdesc->init_meminfo)) + return; + + /* remap kernel code and data */ + map_start = init_mm.start_code; + map_end = init_mm.brk; + + /* get a handle on things... */ + pgd0 = pgd_offset_k(0); + pud_start = pud0 = pud_offset(pgd0, 0); + pmd0 = pmd_offset(pud0, 0); + + pgdk = pgd_offset_k(map_start); + pudk = pud_offset(pgdk, map_start); + pmdk = pmd_offset(pudk, map_start); + + mdesc->init_meminfo(); + + /* Run the patch stub to update the constants */ + fixup_pv_table(&__pv_table_begin, + (&__pv_table_end - &__pv_table_begin) << 2); + + /* + * Cache cleaning operations for self-modifying code + * We should clean the entries by MVA but running a + * for loop over every pv_table entry pointer would + * just complicate the code. + */ + flush_cache_louis(); + dsb(); + isb(); + + /* remap level 1 table */ + for (i = 0; i < PTRS_PER_PGD; pud0++, i++) { + set_pud(pud0, + __pud(__pa(pmd0) | PMD_TYPE_TABLE | L_PGD_SWAPPER)); + pmd0 += PTRS_PER_PMD; + } + + /* remap pmds for kernel mapping */ + phys = __pa(map_start) & PMD_MASK; + do { + *pmdk++ = __pmd(phys | pmdprot); + phys += PMD_SIZE; + } while (phys < map_end); + + flush_cache_all(); + cpu_switch_mm(pgd0, &init_mm); + cpu_set_ttbr(1, __pa(pgd0) + TTBR1_OFFSET); + local_flush_bp_all(); + local_flush_tlb_all(); +} + +#else + +void __init early_paging_init(const struct machine_desc *mdesc, + struct proc_info_list *procinfo) +{ + if (mdesc->init_meminfo) + mdesc->init_meminfo(); +} + +#endif + /* * paging_init() sets up the page tables, initialises the zone memory * maps, and sets up the zero page, bad page and bad page tables. diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c index 34d4ab217bab..5c668b7a31f9 100644 --- a/arch/arm/mm/nommu.c +++ b/arch/arm/mm/nommu.c @@ -296,6 +296,15 @@ void __init sanity_check_meminfo(void) } /* + * early_paging_init() recreates boot time page table setup, allowing machines + * to switch over to a high (>4G) address space on LPAE systems + */ +void __init early_paging_init(const struct machine_desc *mdesc, + struct proc_info_list *procinfo) +{ +} + +/* * paging_init() sets up the page tables, initialises the zone memory * maps, and sets up the zero page, bad page and bad page tables. */ diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S index 1128064fddcb..45dc29f85d56 100644 --- a/arch/arm/mm/proc-v6.S +++ b/arch/arm/mm/proc-v6.S @@ -220,9 +220,7 @@ __v6_setup: #endif /* CONFIG_MMU */ adr r5, v6_crval ldmia r5, {r5, r6} -#ifdef CONFIG_CPU_ENDIAN_BE8 - orr r6, r6, #1 << 25 @ big-endian page tables -#endif + ARM_BE8(orr r6, r6, #1 << 25) @ big-endian page tables mrc p15, 0, r0, c1, c0, 0 @ read control register bic r0, r0, r5 @ clear bits them orr r0, r0, r6 @ set them diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index c63d9bdee51e..60920f62fdf5 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S @@ -367,9 +367,7 @@ __v7_setup: #endif adr r5, v7_crval ldmia r5, {r5, r6} -#ifdef CONFIG_CPU_ENDIAN_BE8 - orr r6, r6, #1 << 25 @ big-endian page tables -#endif + ARM_BE8(orr r6, r6, #1 << 25) @ big-endian page tables #ifdef CONFIG_SWP_EMULATE orr r5, r5, #(1 << 10) @ set SW bit in "clear" bic r6, r6, #(1 << 10) @ clear it in "mmuset" diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c index 99b44e0e8d86..9ed155ad0f97 100644 --- a/arch/arm/net/bpf_jit_32.c +++ b/arch/arm/net/bpf_jit_32.c @@ -19,6 +19,7 @@ #include <linux/if_vlan.h> #include <asm/cacheflush.h> #include <asm/hwcap.h> +#include <asm/opcodes.h> #include "bpf_jit_32.h" @@ -113,8 +114,11 @@ static u32 jit_udiv(u32 dividend, u32 divisor) static inline void _emit(int cond, u32 inst, struct jit_ctx *ctx) { + inst |= (cond << 28); + inst = __opcode_to_mem_arm(inst); + if (ctx->target != NULL) - ctx->target[ctx->idx] = inst | (cond << 28); + ctx->target[ctx->idx] = inst; ctx->idx++; } diff --git a/arch/arm/plat-iop/Makefile b/arch/arm/plat-iop/Makefile index a99dc15a70f7..224e56c6049b 100644 --- a/arch/arm/plat-iop/Makefile +++ b/arch/arm/plat-iop/Makefile @@ -5,7 +5,6 @@ obj-y := # IOP32X -obj-$(CONFIG_ARCH_IOP32X) += gpio.o obj-$(CONFIG_ARCH_IOP32X) += i2c.o obj-$(CONFIG_ARCH_IOP32X) += pci.o obj-$(CONFIG_ARCH_IOP32X) += setup.o @@ -16,7 +15,6 @@ obj-$(CONFIG_ARCH_IOP32X) += pmu.o obj-$(CONFIG_ARCH_IOP32X) += restart.o # IOP33X -obj-$(CONFIG_ARCH_IOP33X) += gpio.o obj-$(CONFIG_ARCH_IOP33X) += i2c.o obj-$(CONFIG_ARCH_IOP33X) += pci.o obj-$(CONFIG_ARCH_IOP33X) += setup.o diff --git a/arch/arm/plat-iop/gpio.c b/arch/arm/plat-iop/gpio.c deleted file mode 100644 index 697de6dc4936..000000000000 --- a/arch/arm/plat-iop/gpio.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * arch/arm/plat-iop/gpio.c - * GPIO handling for Intel IOP3xx processors. - * - * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - */ - -#include <linux/device.h> -#include <linux/init.h> -#include <linux/types.h> -#include <linux/errno.h> -#include <linux/gpio.h> -#include <linux/export.h> -#include <asm/hardware/iop3xx.h> -#include <mach/gpio.h> - -void gpio_line_config(int line, int direction) -{ - unsigned long flags; - - local_irq_save(flags); - if (direction == GPIO_IN) { - *IOP3XX_GPOE |= 1 << line; - } else if (direction == GPIO_OUT) { - *IOP3XX_GPOE &= ~(1 << line); - } - local_irq_restore(flags); -} -EXPORT_SYMBOL(gpio_line_config); - -int gpio_line_get(int line) -{ - return !!(*IOP3XX_GPID & (1 << line)); -} -EXPORT_SYMBOL(gpio_line_get); - -void gpio_line_set(int line, int value) -{ - unsigned long flags; - - local_irq_save(flags); - if (value == GPIO_LOW) { - *IOP3XX_GPOD &= ~(1 << line); - } else if (value == GPIO_HIGH) { - *IOP3XX_GPOD |= 1 << line; - } - local_irq_restore(flags); -} -EXPORT_SYMBOL(gpio_line_set); - -static int iop3xx_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) -{ - gpio_line_config(gpio, GPIO_IN); - return 0; -} - -static int iop3xx_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, int level) -{ - gpio_line_set(gpio, level); - gpio_line_config(gpio, GPIO_OUT); - return 0; -} - -static int iop3xx_gpio_get_value(struct gpio_chip *chip, unsigned gpio) -{ - return gpio_line_get(gpio); -} - -static void iop3xx_gpio_set_value(struct gpio_chip *chip, unsigned gpio, int value) -{ - gpio_line_set(gpio, value); -} - -static struct gpio_chip iop3xx_chip = { - .label = "iop3xx", - .direction_input = iop3xx_gpio_direction_input, - .get = iop3xx_gpio_get_value, - .direction_output = iop3xx_gpio_direction_output, - .set = iop3xx_gpio_set_value, - .base = 0, - .ngpio = IOP3XX_N_GPIOS, -}; - -static int __init iop3xx_gpio_setup(void) -{ - return gpiochip_add(&iop3xx_chip); -} -arch_initcall(iop3xx_gpio_setup); diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index 037660633fa4..01619c2910e3 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c @@ -1965,7 +1965,6 @@ static irqreturn_t omap2_dma_irq_handler(int irq, void *dev_id) static struct irqaction omap24xx_dma_irq = { .name = "DMA", .handler = omap2_dma_irq_handler, - .flags = IRQF_DISABLED }; #else diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig index 7dfba937d8fc..6d95d60276d6 100644 --- a/arch/arm/plat-samsung/Kconfig +++ b/arch/arm/plat-samsung/Kconfig @@ -382,11 +382,6 @@ config S5P_DEV_TV help Compile in platform device definition for TV interface -config S5P_DEV_USB_EHCI - bool - help - Compile in platform device definition for USB EHCI - config S3C24XX_PWM bool "PWM device support" select PWM @@ -395,11 +390,6 @@ config S3C24XX_PWM Support for exporting the PWM timer blocks via the pwm device system -config S5P_SETUP_MIPIPHY - bool - help - Compile in common setup code for MIPI-CSIS and MIPI-DSIM devices - config S3C_SETUP_CAMIF bool help diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile index 498c7c23e9f4..9267d29549b4 100644 --- a/arch/arm/plat-samsung/Makefile +++ b/arch/arm/plat-samsung/Makefile @@ -38,7 +38,6 @@ obj-$(CONFIG_S5P_DEV_UART) += s5p-dev-uart.o obj-$(CONFIG_SAMSUNG_DEV_BACKLIGHT) += dev-backlight.o obj-$(CONFIG_S3C_SETUP_CAMIF) += setup-camif.o -obj-$(CONFIG_S5P_SETUP_MIPIPHY) += setup-mipiphy.o # DMA support diff --git a/arch/arm/plat-samsung/dev-backlight.c b/arch/arm/plat-samsung/dev-backlight.c index d51f9565567c..be4ad0b21c08 100644 --- a/arch/arm/plat-samsung/dev-backlight.c +++ b/arch/arm/plat-samsung/dev-backlight.c @@ -70,6 +70,7 @@ static struct samsung_bl_drvdata samsung_dfl_bl_data __initdata = { .max_brightness = 255, .dft_brightness = 255, .pwm_period_ns = 78770, + .enable_gpio = -1, .init = samsung_bl_init, .exit = samsung_bl_exit, }, @@ -121,6 +122,10 @@ void __init samsung_bl_set(struct samsung_bl_gpio_info *gpio_info, samsung_bl_data->lth_brightness = bl_data->lth_brightness; if (bl_data->pwm_period_ns) samsung_bl_data->pwm_period_ns = bl_data->pwm_period_ns; + if (bl_data->enable_gpio >= 0) + samsung_bl_data->enable_gpio = bl_data->enable_gpio; + if (bl_data->enable_gpio_flags) + samsung_bl_data->enable_gpio_flags = bl_data->enable_gpio_flags; if (bl_data->init) samsung_bl_data->init = bl_data->init; if (bl_data->notify) diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c index 8ce0ac007eb9..99a3590f0349 100644 --- a/arch/arm/plat-samsung/devs.c +++ b/arch/arm/plat-samsung/devs.c @@ -32,6 +32,7 @@ #include <linux/ioport.h> #include <linux/platform_data/s3c-hsudc.h> #include <linux/platform_data/s3c-hsotg.h> +#include <linux/platform_data/dma-s3c24xx.h> #include <media/s5p_hdmi.h> @@ -49,7 +50,6 @@ #include <plat/devs.h> #include <plat/adc.h> #include <linux/platform_data/ata-samsung_cf.h> -#include <linux/platform_data/usb-ehci-s5p.h> #include <plat/fb.h> #include <plat/fb-s3c2410.h> #include <plat/hdmi.h> @@ -1359,39 +1359,6 @@ void __init s3c24xx_udc_set_platdata(struct s3c2410_udc_mach_info *pd) } #endif /* CONFIG_PLAT_S3C24XX */ -/* USB EHCI Host Controller */ - -#ifdef CONFIG_S5P_DEV_USB_EHCI -static struct resource s5p_ehci_resource[] = { - [0] = DEFINE_RES_MEM(S5P_PA_EHCI, SZ_256), - [1] = DEFINE_RES_IRQ(IRQ_USB_HOST), -}; - -struct platform_device s5p_device_ehci = { - .name = "s5p-ehci", - .id = -1, - .num_resources = ARRAY_SIZE(s5p_ehci_resource), - .resource = s5p_ehci_resource, - .dev = { - .dma_mask = &samsung_device_dma_mask, - .coherent_dma_mask = DMA_BIT_MASK(32), - } -}; - -void __init s5p_ehci_set_platdata(struct s5p_ehci_platdata *pd) -{ - struct s5p_ehci_platdata *npd; - - npd = s3c_set_platdata(pd, sizeof(struct s5p_ehci_platdata), - &s5p_device_ehci); - - if (!npd->phy_init) - npd->phy_init = s5p_usb_phy_init; - if (!npd->phy_exit) - npd->phy_exit = s5p_usb_phy_exit; -} -#endif /* CONFIG_S5P_DEV_USB_EHCI */ - /* USB HSOTG */ #ifdef CONFIG_S3C_DEV_USB_HSOTG @@ -1499,8 +1466,10 @@ void __init s3c64xx_spi0_set_platdata(int (*cfg_gpio)(void), int src_clk_nr, pd.num_cs = num_cs; pd.src_clk_nr = src_clk_nr; pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi0_cfg_gpio; -#ifdef CONFIG_PL330_DMA +#if defined(CONFIG_PL330_DMA) pd.filter = pl330_filter; +#elif defined(CONFIG_S3C24XX_DMAC) + pd.filter = s3c24xx_dma_filter; #endif s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi0); diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h index 4fb1f03a10d1..335beb341355 100644 --- a/arch/arm/plat-samsung/include/plat/cpu.h +++ b/arch/arm/plat-samsung/include/plat/cpu.h @@ -87,8 +87,12 @@ IS_SAMSUNG_CPU(exynos5440, EXYNOS5440_SOC_ID, EXYNOS5_SOC_MASK) #endif #if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410) +# define soc_is_s3c6400() is_samsung_s3c6400() +# define soc_is_s3c6410() is_samsung_s3c6410() # define soc_is_s3c64xx() (is_samsung_s3c6400() || is_samsung_s3c6410()) #else +# define soc_is_s3c6400() 0 +# define soc_is_s3c6410() 0 # define soc_is_s3c64xx() 0 #endif diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h index 0dc4ac4909b0..eece188ed188 100644 --- a/arch/arm/plat-samsung/include/plat/devs.h +++ b/arch/arm/plat-samsung/include/plat/devs.h @@ -75,7 +75,6 @@ extern struct platform_device s3c_device_usb_hsotg; extern struct platform_device s3c_device_usb_hsudc; extern struct platform_device s3c_device_wdt; -extern struct platform_device s5p_device_ehci; extern struct platform_device s5p_device_fimc0; extern struct platform_device s5p_device_fimc1; extern struct platform_device s5p_device_fimc2; diff --git a/arch/arm/plat-samsung/init.c b/arch/arm/plat-samsung/init.c index 50a3ea0037db..aa9511b6914a 100644 --- a/arch/arm/plat-samsung/init.c +++ b/arch/arm/plat-samsung/init.c @@ -11,12 +11,18 @@ * published by the Free Software Foundation. */ +/* + * NOTE: Code in this file is not used on S3C64xx when booting with + * Device Tree support. + */ + #include <linux/init.h> #include <linux/module.h> #include <linux/interrupt.h> #include <linux/ioport.h> #include <linux/serial_core.h> #include <linux/platform_device.h> +#include <linux/of.h> #include <mach/hardware.h> @@ -148,8 +154,12 @@ static int __init s3c_arch_init(void) // do the correct init for cpu - if (cpu == NULL) + if (cpu == NULL) { + /* Not needed when booting with device tree. */ + if (of_have_populated_dt()) + return 0; panic("s3c_arch_init: NULL cpu\n"); + } ret = (cpu->init)(); if (ret != 0) diff --git a/arch/arm/plat-samsung/setup-mipiphy.c b/arch/arm/plat-samsung/setup-mipiphy.c deleted file mode 100644 index 66df315990a7..000000000000 --- a/arch/arm/plat-samsung/setup-mipiphy.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2011 Samsung Electronics Co., Ltd. - * - * S5P - Helper functions for MIPI-CSIS and MIPI-DSIM D-PHY control - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/export.h> -#include <linux/kernel.h> -#include <linux/platform_device.h> -#include <linux/io.h> -#include <linux/spinlock.h> -#include <mach/regs-clock.h> - -static int __s5p_mipi_phy_control(int id, bool on, u32 reset) -{ - static DEFINE_SPINLOCK(lock); - void __iomem *addr; - unsigned long flags; - u32 cfg; - - id = max(0, id); - if (id > 1) - return -EINVAL; - - addr = S5P_MIPI_DPHY_CONTROL(id); - - spin_lock_irqsave(&lock, flags); - - cfg = __raw_readl(addr); - cfg = on ? (cfg | reset) : (cfg & ~reset); - __raw_writel(cfg, addr); - - if (on) { - cfg |= S5P_MIPI_DPHY_ENABLE; - } else if (!(cfg & (S5P_MIPI_DPHY_SRESETN | - S5P_MIPI_DPHY_MRESETN) & ~reset)) { - cfg &= ~S5P_MIPI_DPHY_ENABLE; - } - - __raw_writel(cfg, addr); - spin_unlock_irqrestore(&lock, flags); - - return 0; -} - -int s5p_csis_phy_enable(int id, bool on) -{ - return __s5p_mipi_phy_control(id, on, S5P_MIPI_DPHY_SRESETN); -} -EXPORT_SYMBOL(s5p_csis_phy_enable); - -int s5p_dsim_phy_enable(struct platform_device *pdev, bool on) -{ - return __s5p_mipi_phy_control(pdev->id, on, S5P_MIPI_DPHY_MRESETN); -} -EXPORT_SYMBOL(s5p_dsim_phy_enable); diff --git a/arch/arm/plat-versatile/headsmp.S b/arch/arm/plat-versatile/headsmp.S index 2677bc3762d7..40f27e52de75 100644 --- a/arch/arm/plat-versatile/headsmp.S +++ b/arch/arm/plat-versatile/headsmp.S @@ -10,6 +10,7 @@ */ #include <linux/linkage.h> #include <linux/init.h> +#include <asm/assembler.h> /* * Realview/Versatile Express specific entry point for secondary CPUs. @@ -17,6 +18,7 @@ * until we're ready for them to initialise. */ ENTRY(versatile_secondary_startup) + ARM_BE8(setend be) mrc p15, 0, r0, c0, c0, 5 bic r0, #0xff000000 adr r4, 1f diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index 52b8f40b1c73..2f37e1d6cb45 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c @@ -642,9 +642,9 @@ int vfp_restore_user_hwstate(struct user_vfp __user *ufp, static int vfp_hotplug(struct notifier_block *b, unsigned long action, void *hcpu) { - if (action == CPU_DYING || action == CPU_DYING_FROZEN) { - vfp_force_reload((long)hcpu, current_thread_info()); - } else if (action == CPU_STARTING || action == CPU_STARTING_FROZEN) + if (action == CPU_DYING || action == CPU_DYING_FROZEN) + vfp_current_hw_state[(long)hcpu] = NULL; + else if (action == CPU_STARTING || action == CPU_STARTING_FROZEN) vfp_enable(NULL); return NOTIFY_OK; } diff --git a/arch/arm/xen/Makefile b/arch/arm/xen/Makefile index 43841033afd3..12969523414c 100644 --- a/arch/arm/xen/Makefile +++ b/arch/arm/xen/Makefile @@ -1 +1 @@ -obj-y := enlighten.o hypercall.o grant-table.o +obj-y := enlighten.o hypercall.o grant-table.o p2m.o mm.o diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c new file mode 100644 index 000000000000..b0e77de99148 --- /dev/null +++ b/arch/arm/xen/mm.c @@ -0,0 +1,65 @@ +#include <linux/bootmem.h> +#include <linux/gfp.h> +#include <linux/export.h> +#include <linux/slab.h> +#include <linux/types.h> +#include <linux/dma-mapping.h> +#include <linux/vmalloc.h> +#include <linux/swiotlb.h> + +#include <xen/xen.h> +#include <xen/interface/memory.h> +#include <xen/swiotlb-xen.h> + +#include <asm/cacheflush.h> +#include <asm/xen/page.h> +#include <asm/xen/hypercall.h> +#include <asm/xen/interface.h> + +int xen_create_contiguous_region(phys_addr_t pstart, unsigned int order, + unsigned int address_bits, + dma_addr_t *dma_handle) +{ + if (!xen_initial_domain()) + return -EINVAL; + + /* we assume that dom0 is mapped 1:1 for now */ + *dma_handle = pstart; + return 0; +} +EXPORT_SYMBOL_GPL(xen_create_contiguous_region); + +void xen_destroy_contiguous_region(phys_addr_t pstart, unsigned int order) +{ + return; +} +EXPORT_SYMBOL_GPL(xen_destroy_contiguous_region); + +struct dma_map_ops *xen_dma_ops; +EXPORT_SYMBOL_GPL(xen_dma_ops); + +static struct dma_map_ops xen_swiotlb_dma_ops = { + .mapping_error = xen_swiotlb_dma_mapping_error, + .alloc = xen_swiotlb_alloc_coherent, + .free = xen_swiotlb_free_coherent, + .sync_single_for_cpu = xen_swiotlb_sync_single_for_cpu, + .sync_single_for_device = xen_swiotlb_sync_single_for_device, + .sync_sg_for_cpu = xen_swiotlb_sync_sg_for_cpu, + .sync_sg_for_device = xen_swiotlb_sync_sg_for_device, + .map_sg = xen_swiotlb_map_sg_attrs, + .unmap_sg = xen_swiotlb_unmap_sg_attrs, + .map_page = xen_swiotlb_map_page, + .unmap_page = xen_swiotlb_unmap_page, + .dma_supported = xen_swiotlb_dma_supported, + .set_dma_mask = xen_swiotlb_set_dma_mask, +}; + +int __init xen_mm_init(void) +{ + if (!xen_initial_domain()) + return 0; + xen_swiotlb_init(1, false); + xen_dma_ops = &xen_swiotlb_dma_ops; + return 0; +} +arch_initcall(xen_mm_init); diff --git a/arch/arm/xen/p2m.c b/arch/arm/xen/p2m.c new file mode 100644 index 000000000000..23732cdff551 --- /dev/null +++ b/arch/arm/xen/p2m.c @@ -0,0 +1,208 @@ +#include <linux/bootmem.h> +#include <linux/gfp.h> +#include <linux/export.h> +#include <linux/rwlock.h> +#include <linux/slab.h> +#include <linux/types.h> +#include <linux/dma-mapping.h> +#include <linux/vmalloc.h> +#include <linux/swiotlb.h> + +#include <xen/xen.h> +#include <xen/interface/memory.h> +#include <xen/swiotlb-xen.h> + +#include <asm/cacheflush.h> +#include <asm/xen/page.h> +#include <asm/xen/hypercall.h> +#include <asm/xen/interface.h> + +struct xen_p2m_entry { + unsigned long pfn; + unsigned long mfn; + unsigned long nr_pages; + struct rb_node rbnode_mach; + struct rb_node rbnode_phys; +}; + +rwlock_t p2m_lock; +struct rb_root phys_to_mach = RB_ROOT; +static struct rb_root mach_to_phys = RB_ROOT; + +static int xen_add_phys_to_mach_entry(struct xen_p2m_entry *new) +{ + struct rb_node **link = &phys_to_mach.rb_node; + struct rb_node *parent = NULL; + struct xen_p2m_entry *entry; + int rc = 0; + + while (*link) { + parent = *link; + entry = rb_entry(parent, struct xen_p2m_entry, rbnode_phys); + + if (new->mfn == entry->mfn) + goto err_out; + if (new->pfn == entry->pfn) + goto err_out; + + if (new->pfn < entry->pfn) + link = &(*link)->rb_left; + else + link = &(*link)->rb_right; + } + rb_link_node(&new->rbnode_phys, parent, link); + rb_insert_color(&new->rbnode_phys, &phys_to_mach); + goto out; + +err_out: + rc = -EINVAL; + pr_warn("%s: cannot add pfn=%pa -> mfn=%pa: pfn=%pa -> mfn=%pa already exists\n", + __func__, &new->pfn, &new->mfn, &entry->pfn, &entry->mfn); +out: + return rc; +} + +unsigned long __pfn_to_mfn(unsigned long pfn) +{ + struct rb_node *n = phys_to_mach.rb_node; + struct xen_p2m_entry *entry; + unsigned long irqflags; + + read_lock_irqsave(&p2m_lock, irqflags); + while (n) { + entry = rb_entry(n, struct xen_p2m_entry, rbnode_phys); + if (entry->pfn <= pfn && + entry->pfn + entry->nr_pages > pfn) { + read_unlock_irqrestore(&p2m_lock, irqflags); + return entry->mfn + (pfn - entry->pfn); + } + if (pfn < entry->pfn) + n = n->rb_left; + else + n = n->rb_right; + } + read_unlock_irqrestore(&p2m_lock, irqflags); + + return INVALID_P2M_ENTRY; +} +EXPORT_SYMBOL_GPL(__pfn_to_mfn); + +static int xen_add_mach_to_phys_entry(struct xen_p2m_entry *new) +{ + struct rb_node **link = &mach_to_phys.rb_node; + struct rb_node *parent = NULL; + struct xen_p2m_entry *entry; + int rc = 0; + + while (*link) { + parent = *link; + entry = rb_entry(parent, struct xen_p2m_entry, rbnode_mach); + + if (new->mfn == entry->mfn) + goto err_out; + if (new->pfn == entry->pfn) + goto err_out; + + if (new->mfn < entry->mfn) + link = &(*link)->rb_left; + else + link = &(*link)->rb_right; + } + rb_link_node(&new->rbnode_mach, parent, link); + rb_insert_color(&new->rbnode_mach, &mach_to_phys); + goto out; + +err_out: + rc = -EINVAL; + pr_warn("%s: cannot add pfn=%pa -> mfn=%pa: pfn=%pa -> mfn=%pa already exists\n", + __func__, &new->pfn, &new->mfn, &entry->pfn, &entry->mfn); +out: + return rc; +} + +unsigned long __mfn_to_pfn(unsigned long mfn) +{ + struct rb_node *n = mach_to_phys.rb_node; + struct xen_p2m_entry *entry; + unsigned long irqflags; + + read_lock_irqsave(&p2m_lock, irqflags); + while (n) { + entry = rb_entry(n, struct xen_p2m_entry, rbnode_mach); + if (entry->mfn <= mfn && + entry->mfn + entry->nr_pages > mfn) { + read_unlock_irqrestore(&p2m_lock, irqflags); + return entry->pfn + (mfn - entry->mfn); + } + if (mfn < entry->mfn) + n = n->rb_left; + else + n = n->rb_right; + } + read_unlock_irqrestore(&p2m_lock, irqflags); + + return INVALID_P2M_ENTRY; +} +EXPORT_SYMBOL_GPL(__mfn_to_pfn); + +bool __set_phys_to_machine_multi(unsigned long pfn, + unsigned long mfn, unsigned long nr_pages) +{ + int rc; + unsigned long irqflags; + struct xen_p2m_entry *p2m_entry; + struct rb_node *n = phys_to_mach.rb_node; + + if (mfn == INVALID_P2M_ENTRY) { + write_lock_irqsave(&p2m_lock, irqflags); + while (n) { + p2m_entry = rb_entry(n, struct xen_p2m_entry, rbnode_phys); + if (p2m_entry->pfn <= pfn && + p2m_entry->pfn + p2m_entry->nr_pages > pfn) { + rb_erase(&p2m_entry->rbnode_mach, &mach_to_phys); + rb_erase(&p2m_entry->rbnode_phys, &phys_to_mach); + write_unlock_irqrestore(&p2m_lock, irqflags); + kfree(p2m_entry); + return true; + } + if (pfn < p2m_entry->pfn) + n = n->rb_left; + else + n = n->rb_right; + } + write_unlock_irqrestore(&p2m_lock, irqflags); + return true; + } + + p2m_entry = kzalloc(sizeof(struct xen_p2m_entry), GFP_NOWAIT); + if (!p2m_entry) { + pr_warn("cannot allocate xen_p2m_entry\n"); + return false; + } + p2m_entry->pfn = pfn; + p2m_entry->nr_pages = nr_pages; + p2m_entry->mfn = mfn; + + write_lock_irqsave(&p2m_lock, irqflags); + if ((rc = xen_add_phys_to_mach_entry(p2m_entry) < 0) || + (rc = xen_add_mach_to_phys_entry(p2m_entry) < 0)) { + write_unlock_irqrestore(&p2m_lock, irqflags); + return false; + } + write_unlock_irqrestore(&p2m_lock, irqflags); + return true; +} +EXPORT_SYMBOL_GPL(__set_phys_to_machine_multi); + +bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn) +{ + return __set_phys_to_machine_multi(pfn, mfn, 1); +} +EXPORT_SYMBOL_GPL(__set_phys_to_machine); + +int p2m_init(void) +{ + rwlock_init(&p2m_lock); + return 0; +} +arch_initcall(p2m_init); diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index c04454876bcb..88c8b6c1341a 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -1,6 +1,7 @@ config ARM64 def_bool y select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE + select ARCH_USE_CMPXCHG_LOCKREF select ARCH_WANT_OPTIONAL_GPIOLIB select ARCH_WANT_COMPAT_IPC_PARSE_VERSION select ARCH_WANT_FRAME_POINTERS @@ -14,6 +15,7 @@ config ARM64 select GENERIC_IOMAP select GENERIC_IRQ_PROBE select GENERIC_IRQ_SHOW + select GENERIC_SCHED_CLOCK select GENERIC_SMP_IDLE_THREAD select GENERIC_TIME_VSYSCALL select HARDIRQS_SW_RESEND @@ -61,10 +63,6 @@ config LOCKDEP_SUPPORT config TRACE_IRQFLAGS_SUPPORT def_bool y -config GENERIC_LOCKBREAK - def_bool y - depends on SMP && PREEMPT - config RWSEM_GENERIC_SPINLOCK def_bool y @@ -138,9 +136,13 @@ config ARM64_64K_PAGES look-up. AArch32 emulation is not available when this feature is enabled. +config CPU_BIG_ENDIAN + bool "Build big-endian kernel" + help + Say Y if you plan on running a kernel in big-endian mode. + config SMP bool "Symmetric Multi-Processing" - select USE_GENERIC_SMP_HELPERS help This enables support for systems with more than one CPU. If you say N here, the kernel will run on single and @@ -160,6 +162,13 @@ config NR_CPUS default "8" if ARCH_XGENE default "4" +config HOTPLUG_CPU + bool "Support for hot-pluggable CPUs" + depends on SMP + help + Say Y here to experiment with turning CPUs off and on. CPUs + can be controlled through /sys/devices/system/cpu. + source kernel/Kconfig.preempt config HZ @@ -211,6 +220,7 @@ config XEN_DOM0 config XEN bool "Xen guest support on ARM64 (EXPERIMENTAL)" depends on ARM64 && OF + select SWIOTLB_XEN help Say Y if you want to run Linux in a Virtual Machine on Xen on ARM64. diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile index d90cf79f233a..2fceb71ac3b7 100644 --- a/arch/arm64/Makefile +++ b/arch/arm64/Makefile @@ -20,9 +20,15 @@ LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name) KBUILD_DEFCONFIG := defconfig KBUILD_CFLAGS += -mgeneral-regs-only +ifeq ($(CONFIG_CPU_BIG_ENDIAN), y) +KBUILD_CPPFLAGS += -mbig-endian +AS += -EB +LD += -EB +else KBUILD_CPPFLAGS += -mlittle-endian AS += -EL LD += -EL +endif comma = , diff --git a/arch/arm64/boot/dts/apm-storm.dtsi b/arch/arm64/boot/dts/apm-storm.dtsi index bfdc57834929..d37d7369e260 100644 --- a/arch/arm64/boot/dts/apm-storm.dtsi +++ b/arch/arm64/boot/dts/apm-storm.dtsi @@ -103,6 +103,81 @@ #size-cells = <2>; ranges; + clocks { + #address-cells = <2>; + #size-cells = <2>; + ranges; + refclk: refclk { + compatible = "fixed-clock"; + #clock-cells = <1>; + clock-frequency = <100000000>; + clock-output-names = "refclk"; + }; + + pcppll: pcppll@17000100 { + compatible = "apm,xgene-pcppll-clock"; + #clock-cells = <1>; + clocks = <&refclk 0>; + clock-names = "pcppll"; + reg = <0x0 0x17000100 0x0 0x1000>; + clock-output-names = "pcppll"; + type = <0>; + }; + + socpll: socpll@17000120 { + compatible = "apm,xgene-socpll-clock"; + #clock-cells = <1>; + clocks = <&refclk 0>; + clock-names = "socpll"; + reg = <0x0 0x17000120 0x0 0x1000>; + clock-output-names = "socpll"; + type = <1>; + }; + + socplldiv2: socplldiv2 { + compatible = "fixed-factor-clock"; + #clock-cells = <1>; + clocks = <&socpll 0>; + clock-names = "socplldiv2"; + clock-mult = <1>; + clock-div = <2>; + clock-output-names = "socplldiv2"; + }; + + qmlclk: qmlclk { + compatible = "apm,xgene-device-clock"; + #clock-cells = <1>; + clocks = <&socplldiv2 0>; + clock-names = "qmlclk"; + reg = <0x0 0x1703C000 0x0 0x1000>; + reg-names = "csr-reg"; + clock-output-names = "qmlclk"; + }; + + ethclk: ethclk { + compatible = "apm,xgene-device-clock"; + #clock-cells = <1>; + clocks = <&socplldiv2 0>; + clock-names = "ethclk"; + reg = <0x0 0x17000000 0x0 0x1000>; + reg-names = "div-reg"; + divider-offset = <0x238>; + divider-width = <0x9>; + divider-shift = <0x0>; + clock-output-names = "ethclk"; + }; + + eth8clk: eth8clk { + compatible = "apm,xgene-device-clock"; + #clock-cells = <1>; + clocks = <ðclk 0>; + clock-names = "eth8clk"; + reg = <0x0 0x1702C000 0x0 0x1000>; + reg-names = "csr-reg"; + clock-output-names = "eth8clk"; + }; + }; + serial0: serial@1c020000 { device_type = "serial"; compatible = "ns16550"; diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 31c81e9b792e..84139be62ae6 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -26,7 +26,7 @@ CONFIG_MODULE_UNLOAD=y CONFIG_ARCH_VEXPRESS=y CONFIG_ARCH_XGENE=y CONFIG_SMP=y -CONFIG_PREEMPT_VOLUNTARY=y +CONFIG_PREEMPT=y CONFIG_CMDLINE="console=ttyAMA0" # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_COMPAT=y diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild index 79a642d199f2..519f89f5b6a3 100644 --- a/arch/arm64/include/asm/Kbuild +++ b/arch/arm64/include/asm/Kbuild @@ -50,3 +50,4 @@ generic-y += unaligned.h generic-y += user.h generic-y += vga.h generic-y += xor.h +generic-y += preempt.h diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h index c9f1d2816c2b..9400596a0f39 100644 --- a/arch/arm64/include/asm/arch_timer.h +++ b/arch/arm64/include/asm/arch_timer.h @@ -92,19 +92,49 @@ static inline u32 arch_timer_get_cntfrq(void) return val; } -static inline void arch_counter_set_user_access(void) +static inline u32 arch_timer_get_cntkctl(void) { u32 cntkctl; - - /* Disable user access to the timers and the physical counter. */ asm volatile("mrs %0, cntkctl_el1" : "=r" (cntkctl)); - cntkctl &= ~((3 << 8) | (1 << 0)); + return cntkctl; +} - /* Enable user access to the virtual counter and frequency. */ - cntkctl |= (1 << 1); +static inline void arch_timer_set_cntkctl(u32 cntkctl) +{ asm volatile("msr cntkctl_el1, %0" : : "r" (cntkctl)); } +static inline void arch_counter_set_user_access(void) +{ + u32 cntkctl = arch_timer_get_cntkctl(); + + /* Disable user access to the timers and the physical counter */ + /* Also disable virtual event stream */ + cntkctl &= ~(ARCH_TIMER_USR_PT_ACCESS_EN + | ARCH_TIMER_USR_VT_ACCESS_EN + | ARCH_TIMER_VIRT_EVT_EN + | ARCH_TIMER_USR_PCT_ACCESS_EN); + + /* Enable user access to the virtual counter */ + cntkctl |= ARCH_TIMER_USR_VCT_ACCESS_EN; + + arch_timer_set_cntkctl(cntkctl); +} + +static inline void arch_timer_evtstrm_enable(int divider) +{ + u32 cntkctl = arch_timer_get_cntkctl(); + cntkctl &= ~ARCH_TIMER_EVT_TRIGGER_MASK; + /* Set the divider and enable virtual event stream */ + cntkctl |= (divider << ARCH_TIMER_EVT_TRIGGER_SHIFT) + | ARCH_TIMER_VIRT_EVT_EN; + arch_timer_set_cntkctl(cntkctl); + elf_hwcap |= HWCAP_EVTSTRM; +#ifdef CONFIG_COMPAT + compat_elf_hwcap |= COMPAT_HWCAP_EVTSTRM; +#endif +} + static inline u64 arch_counter_get_cntvct(void) { u64 cval; diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h index 5aceb83b3f5c..fd3e3924041b 100644 --- a/arch/arm64/include/asm/assembler.h +++ b/arch/arm64/include/asm/assembler.h @@ -115,3 +115,34 @@ lr .req x30 // link register .align 7 b \label .endm + +/* + * Select code when configured for BE. + */ +#ifdef CONFIG_CPU_BIG_ENDIAN +#define CPU_BE(code...) code +#else +#define CPU_BE(code...) +#endif + +/* + * Select code when configured for LE. + */ +#ifdef CONFIG_CPU_BIG_ENDIAN +#define CPU_LE(code...) +#else +#define CPU_LE(code...) code +#endif + +/* + * Define a macro that constructs a 64-bit value by concatenating two + * 32-bit registers. Note that on big endian systems the order of the + * registers is swapped. + */ +#ifndef CONFIG_CPU_BIG_ENDIAN + .macro regs_to_64, rd, lbits, hbits +#else + .macro regs_to_64, rd, hbits, lbits +#endif + orr \rd, \lbits, \hbits, lsl #32 + .endm diff --git a/arch/arm64/include/asm/atomic.h b/arch/arm64/include/asm/atomic.h index 836364468571..01de5aaa3edc 100644 --- a/arch/arm64/include/asm/atomic.h +++ b/arch/arm64/include/asm/atomic.h @@ -126,20 +126,6 @@ static inline int atomic_cmpxchg(atomic_t *ptr, int old, int new) return oldval; } -static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr) -{ - unsigned long tmp, tmp2; - - asm volatile("// atomic_clear_mask\n" -"1: ldxr %0, %2\n" -" bic %0, %0, %3\n" -" stxr %w1, %0, %2\n" -" cbnz %w1, 1b" - : "=&r" (tmp), "=&r" (tmp2), "+Q" (*addr) - : "Ir" (mask) - : "cc"); -} - #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) static inline int __atomic_add_unless(atomic_t *v, int a, int u) diff --git a/arch/arm64/include/asm/cmpxchg.h b/arch/arm64/include/asm/cmpxchg.h index 8a8ce0e73a38..3914c0dcd09c 100644 --- a/arch/arm64/include/asm/cmpxchg.h +++ b/arch/arm64/include/asm/cmpxchg.h @@ -173,4 +173,6 @@ static inline unsigned long __cmpxchg_mb(volatile void *ptr, unsigned long old, #define cmpxchg64(ptr,o,n) cmpxchg((ptr),(o),(n)) #define cmpxchg64_local(ptr,o,n) cmpxchg_local((ptr),(o),(n)) +#define cmpxchg64_relaxed(ptr,o,n) cmpxchg_local((ptr),(o),(n)) + #endif /* __ASM_CMPXCHG_H */ diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h index 899af807ef0f..fda2704b3f9f 100644 --- a/arch/arm64/include/asm/compat.h +++ b/arch/arm64/include/asm/compat.h @@ -26,7 +26,11 @@ #include <linux/ptrace.h> #define COMPAT_USER_HZ 100 +#ifdef __AARCH64EB__ +#define COMPAT_UTS_MACHINE "armv8b\0\0" +#else #define COMPAT_UTS_MACHINE "armv8l\0\0" +#endif typedef u32 compat_size_t; typedef s32 compat_ssize_t; @@ -73,13 +77,23 @@ struct compat_timeval { }; struct compat_stat { +#ifdef __AARCH64EB__ + short st_dev; + short __pad1; +#else compat_dev_t st_dev; +#endif compat_ino_t st_ino; compat_mode_t st_mode; compat_ushort_t st_nlink; __compat_uid16_t st_uid; __compat_gid16_t st_gid; +#ifdef __AARCH64EB__ + short st_rdev; + short __pad2; +#else compat_dev_t st_rdev; +#endif compat_off_t st_size; compat_off_t st_blksize; compat_off_t st_blocks; diff --git a/arch/arm64/include/asm/cpu_ops.h b/arch/arm64/include/asm/cpu_ops.h new file mode 100644 index 000000000000..c4cdb5e5b73d --- /dev/null +++ b/arch/arm64/include/asm/cpu_ops.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2013 ARM Ltd. + * + * 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. + * + * This program is distributed in the hope that 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_CPU_OPS_H +#define __ASM_CPU_OPS_H + +#include <linux/init.h> +#include <linux/threads.h> + +struct device_node; + +/** + * struct cpu_operations - Callback operations for hotplugging CPUs. + * + * @name: Name of the property as appears in a devicetree cpu node's + * enable-method property. + * @cpu_init: Reads any data necessary for a specific enable-method from the + * devicetree, for a given cpu node and proposed logical id. + * @cpu_prepare: Early one-time preparation step for a cpu. If there is a + * mechanism for doing so, tests whether it is possible to boot + * the given CPU. + * @cpu_boot: Boots a cpu into the kernel. + * @cpu_postboot: Optionally, perform any post-boot cleanup or necesary + * synchronisation. Called from the cpu being booted. + * @cpu_disable: Prepares a cpu to die. May fail for some mechanism-specific + * reason, which will cause the hot unplug to be aborted. Called + * from the cpu to be killed. + * @cpu_die: Makes a cpu leave the kernel. Must not fail. Called from the + * cpu being killed. + */ +struct cpu_operations { + const char *name; + int (*cpu_init)(struct device_node *, unsigned int); + int (*cpu_prepare)(unsigned int); + int (*cpu_boot)(unsigned int); + void (*cpu_postboot)(void); +#ifdef CONFIG_HOTPLUG_CPU + int (*cpu_disable)(unsigned int cpu); + void (*cpu_die)(unsigned int cpu); +#endif +}; + +extern const struct cpu_operations *cpu_ops[NR_CPUS]; +extern int __init cpu_read_ops(struct device_node *dn, int cpu); +extern void __init cpu_read_bootcpu_ops(void); + +#endif /* ifndef __ASM_CPU_OPS_H */ diff --git a/arch/arm64/include/asm/dma-mapping.h b/arch/arm64/include/asm/dma-mapping.h index 8d1810001aef..fd0c0c0e447a 100644 --- a/arch/arm64/include/asm/dma-mapping.h +++ b/arch/arm64/include/asm/dma-mapping.h @@ -23,11 +23,15 @@ #include <asm-generic/dma-coherent.h> +#include <xen/xen.h> +#include <asm/xen/hypervisor.h> + #define ARCH_HAS_DMA_GET_REQUIRED_MASK +#define DMA_ERROR_CODE (~(dma_addr_t)0) extern struct dma_map_ops *dma_ops; -static inline struct dma_map_ops *get_dma_ops(struct device *dev) +static inline struct dma_map_ops *__generic_dma_ops(struct device *dev) { if (unlikely(!dev) || !dev->archdata.dma_ops) return dma_ops; @@ -35,6 +39,14 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev) return dev->archdata.dma_ops; } +static inline struct dma_map_ops *get_dma_ops(struct device *dev) +{ + if (xen_initial_domain()) + return xen_dma_ops; + else + return __generic_dma_ops(dev); +} + #include <asm-generic/dma-mapping-common.h> static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h index e7fa87f9201b..01d3aab64b79 100644 --- a/arch/arm64/include/asm/elf.h +++ b/arch/arm64/include/asm/elf.h @@ -90,11 +90,24 @@ typedef struct user_fpsimd_state elf_fpregset_t; * These are used to set parameters in the core dumps. */ #define ELF_CLASS ELFCLASS64 +#ifdef __AARCH64EB__ +#define ELF_DATA ELFDATA2MSB +#else #define ELF_DATA ELFDATA2LSB +#endif #define ELF_ARCH EM_AARCH64 +/* + * This yields a string that ld.so will use to load implementation + * specific libraries for optimization. This is more specific in + * intent than poking at uname or /proc/cpuinfo. + */ #define ELF_PLATFORM_SIZE 16 +#ifdef __AARCH64EB__ +#define ELF_PLATFORM ("aarch64_be") +#else #define ELF_PLATFORM ("aarch64") +#endif /* * This is used to ensure we don't load something for the wrong architecture. @@ -149,7 +162,12 @@ extern unsigned long arch_randomize_brk(struct mm_struct *mm); #define arch_randomize_brk arch_randomize_brk #ifdef CONFIG_COMPAT + +#ifdef __AARCH64EB__ +#define COMPAT_ELF_PLATFORM ("v8b") +#else #define COMPAT_ELF_PLATFORM ("v8l") +#endif #define COMPAT_ELF_ET_DYN_BASE (randomize_et_dyn(2 * TASK_SIZE_32 / 3)) diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h index e2950b098e76..6cddbb0c9f54 100644 --- a/arch/arm64/include/asm/hwcap.h +++ b/arch/arm64/include/asm/hwcap.h @@ -30,6 +30,7 @@ #define COMPAT_HWCAP_IDIVA (1 << 17) #define COMPAT_HWCAP_IDIVT (1 << 18) #define COMPAT_HWCAP_IDIV (COMPAT_HWCAP_IDIVA|COMPAT_HWCAP_IDIVT) +#define COMPAT_HWCAP_EVTSTRM (1 << 21) #ifndef __ASSEMBLY__ /* @@ -37,11 +38,11 @@ * instruction set this cpu supports. */ #define ELF_HWCAP (elf_hwcap) -#define COMPAT_ELF_HWCAP (COMPAT_HWCAP_HALF|COMPAT_HWCAP_THUMB|\ - COMPAT_HWCAP_FAST_MULT|COMPAT_HWCAP_EDSP|\ - COMPAT_HWCAP_TLS|COMPAT_HWCAP_VFP|\ - COMPAT_HWCAP_VFPv3|COMPAT_HWCAP_VFPv4|\ - COMPAT_HWCAP_NEON|COMPAT_HWCAP_IDIV) + +#ifdef CONFIG_COMPAT +#define COMPAT_ELF_HWCAP (compat_elf_hwcap) +extern unsigned int compat_elf_hwcap; +#endif extern unsigned long elf_hwcap; #endif diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h index 1d12f89140ba..4cc813eddacb 100644 --- a/arch/arm64/include/asm/io.h +++ b/arch/arm64/include/asm/io.h @@ -22,11 +22,14 @@ #ifdef __KERNEL__ #include <linux/types.h> +#include <linux/blk_types.h> #include <asm/byteorder.h> #include <asm/barrier.h> #include <asm/pgtable.h> +#include <xen/xen.h> + /* * Generic IO read/write. These perform native-endian accesses. */ @@ -224,6 +227,7 @@ extern void __memset_io(volatile void __iomem *, int, size_t); */ extern void __iomem *__ioremap(phys_addr_t phys_addr, size_t size, pgprot_t prot); extern void __iounmap(volatile void __iomem *addr); +extern void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size); #define PROT_DEFAULT (PTE_TYPE_PAGE | PTE_AF | PTE_DIRTY) #define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_DEVICE_nGnRE)) @@ -233,7 +237,6 @@ extern void __iounmap(volatile void __iomem *addr); #define ioremap(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE)) #define ioremap_nocache(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE)) #define ioremap_wc(addr, size) __ioremap((addr), (size), __pgprot(PROT_NORMAL_NC)) -#define ioremap_cached(addr, size) __ioremap((addr), (size), __pgprot(PROT_NORMAL)) #define iounmap __iounmap #define PROT_SECT_DEFAULT (PMD_TYPE_SECT | PMD_SECT_AF) @@ -263,5 +266,12 @@ extern int devmem_is_allowed(unsigned long pfn); */ #define xlate_dev_kmem_ptr(p) p +struct bio_vec; +extern bool xen_biovec_phys_mergeable(const struct bio_vec *vec1, + const struct bio_vec *vec2); +#define BIOVEC_PHYS_MERGEABLE(vec1, vec2) \ + (__BIOVEC_PHYS_MERGEABLE(vec1, vec2) && \ + (!xen_domain() || xen_biovec_phys_mergeable(vec1, vec2))) + #endif /* __KERNEL__ */ #endif /* __ASM_IO_H */ diff --git a/arch/arm64/include/asm/irq.h b/arch/arm64/include/asm/irq.h index 0332fc077f6e..e1f7ecdde11f 100644 --- a/arch/arm64/include/asm/irq.h +++ b/arch/arm64/include/asm/irq.h @@ -4,6 +4,7 @@ #include <asm-generic/irq.h> extern void (*handle_arch_irq)(struct pt_regs *); +extern void migrate_irqs(void); extern void set_handle_irq(void (*handle_irq)(struct pt_regs *)); #endif diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h index a5f28e2720c7..c98ef4771c73 100644 --- a/arch/arm64/include/asm/kvm_arm.h +++ b/arch/arm64/include/asm/kvm_arm.h @@ -63,6 +63,7 @@ * TAC: Trap ACTLR * TSC: Trap SMC * TSW: Trap cache operations by set/way + * TWE: Trap WFE * TWI: Trap WFI * TIDCP: Trap L2CTLR/L2ECTLR * BSU_IS: Upgrade barriers to the inner shareable domain @@ -72,8 +73,9 @@ * FMO: Override CPSR.F and enable signaling with VF * SWIO: Turn set/way invalidates into set/way clean+invalidate */ -#define HCR_GUEST_FLAGS (HCR_TSC | HCR_TSW | HCR_TWI | HCR_VM | HCR_BSU_IS | \ - HCR_FB | HCR_TAC | HCR_AMO | HCR_IMO | HCR_FMO | \ +#define HCR_GUEST_FLAGS (HCR_TSC | HCR_TSW | HCR_TWE | HCR_TWI | HCR_VM | \ + HCR_BSU_IS | HCR_FB | HCR_TAC | \ + HCR_AMO | HCR_IMO | HCR_FMO | \ HCR_SWIO | HCR_TIDCP | HCR_RW) #define HCR_VIRT_EXCP_MASK (HCR_VA | HCR_VI | HCR_VF) @@ -242,4 +244,6 @@ #define ESR_EL2_EC_xABT_xFSR_EXTABT 0x10 +#define ESR_EL2_EC_WFI_ISS_WFE (1 << 0) + #endif /* __ARM64_KVM_ARM_H__ */ diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h index eec073875218..dd8ecfc3f995 100644 --- a/arch/arm64/include/asm/kvm_emulate.h +++ b/arch/arm64/include/asm/kvm_emulate.h @@ -177,4 +177,65 @@ static inline u8 kvm_vcpu_trap_get_fault(const struct kvm_vcpu *vcpu) return kvm_vcpu_get_hsr(vcpu) & ESR_EL2_FSC_TYPE; } +static inline unsigned long kvm_vcpu_get_mpidr(struct kvm_vcpu *vcpu) +{ + return vcpu_sys_reg(vcpu, MPIDR_EL1); +} + +static inline void kvm_vcpu_set_be(struct kvm_vcpu *vcpu) +{ + if (vcpu_mode_is_32bit(vcpu)) + *vcpu_cpsr(vcpu) |= COMPAT_PSR_E_BIT; + else + vcpu_sys_reg(vcpu, SCTLR_EL1) |= (1 << 25); +} + +static inline bool kvm_vcpu_is_be(struct kvm_vcpu *vcpu) +{ + if (vcpu_mode_is_32bit(vcpu)) + return !!(*vcpu_cpsr(vcpu) & COMPAT_PSR_E_BIT); + + return !!(vcpu_sys_reg(vcpu, SCTLR_EL1) & (1 << 25)); +} + +static inline unsigned long vcpu_data_guest_to_host(struct kvm_vcpu *vcpu, + unsigned long data, + unsigned int len) +{ + if (kvm_vcpu_is_be(vcpu)) { + switch (len) { + case 1: + return data & 0xff; + case 2: + return be16_to_cpu(data & 0xffff); + case 4: + return be32_to_cpu(data & 0xffffffff); + default: + return be64_to_cpu(data); + } + } + + return data; /* Leave LE untouched */ +} + +static inline unsigned long vcpu_data_host_to_guest(struct kvm_vcpu *vcpu, + unsigned long data, + unsigned int len) +{ + if (kvm_vcpu_is_be(vcpu)) { + switch (len) { + case 1: + return data & 0xff; + case 2: + return cpu_to_be16(data & 0xffff); + case 4: + return cpu_to_be32(data & 0xffffffff); + default: + return cpu_to_be64(data); + } + } + + return data; /* Leave LE untouched */ +} + #endif /* __ARM64_KVM_EMULATE_H__ */ diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 0859a4ddd1e7..5d85a02d1231 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -36,11 +36,6 @@ #define KVM_VCPU_MAX_FEATURES 2 -/* We don't currently support large pages. */ -#define KVM_HPAGE_GFN_SHIFT(x) 0 -#define KVM_NR_PAGE_SIZES 1 -#define KVM_PAGES_PER_HPAGE(x) (1UL<<31) - struct kvm_vcpu; int kvm_target_cpu(void); int kvm_reset_vcpu(struct kvm_vcpu *vcpu); @@ -151,6 +146,7 @@ struct kvm_vcpu_stat { struct kvm_vcpu_init; int kvm_vcpu_set_target(struct kvm_vcpu *vcpu, const struct kvm_vcpu_init *init); +int kvm_vcpu_preferred_target(struct kvm_vcpu_init *init); unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu); int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *indices); struct kvm_one_reg; diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h index efe609c6a3c9..680f74e67497 100644 --- a/arch/arm64/include/asm/kvm_mmu.h +++ b/arch/arm64/include/asm/kvm_mmu.h @@ -91,6 +91,7 @@ int kvm_mmu_init(void); void kvm_clear_hyp_idmap(void); #define kvm_set_pte(ptep, pte) set_pte(ptep, pte) +#define kvm_set_pmd(pmdp, pmd) set_pmd(pmdp, pmd) static inline bool kvm_is_write_fault(unsigned long esr) { @@ -116,13 +117,18 @@ static inline void kvm_set_s2pte_writable(pte_t *pte) pte_val(*pte) |= PTE_S2_RDWR; } +static inline void kvm_set_s2pmd_writable(pmd_t *pmd) +{ + pmd_val(*pmd) |= PMD_S2_RDWR; +} + struct kvm; -static inline void coherent_icache_guest_page(struct kvm *kvm, gfn_t gfn) +static inline void coherent_icache_guest_page(struct kvm *kvm, hva_t hva, + unsigned long size) { if (!icache_is_aliasing()) { /* PIPT */ - unsigned long hva = gfn_to_hva(kvm, gfn); - flush_icache_range(hva, hva + PAGE_SIZE); + flush_icache_range(hva, hva + size); } else if (!icache_is_aivivt()) { /* non ASID-tagged VIVT */ /* any kind of VIPT cache */ __flush_icache_all(); diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h index 20925bcf4e2a..37762175896f 100644 --- a/arch/arm64/include/asm/memory.h +++ b/arch/arm64/include/asm/memory.h @@ -33,18 +33,23 @@ #define UL(x) _AC(x, UL) /* - * PAGE_OFFSET - the virtual address of the start of the kernel image. + * PAGE_OFFSET - the virtual address of the start of the kernel image (top + * (VA_BITS - 1)) * VA_BITS - the maximum number of bits for virtual addresses. * TASK_SIZE - the maximum size of a user space task. * TASK_UNMAPPED_BASE - the lower boundary of the mmap VM area. * The module space lives between the addresses given by TASK_SIZE * and PAGE_OFFSET - it must be within 128MB of the kernel text. */ -#define PAGE_OFFSET UL(0xffffffc000000000) +#ifdef CONFIG_ARM64_64K_PAGES +#define VA_BITS (42) +#else +#define VA_BITS (39) +#endif +#define PAGE_OFFSET (UL(0xffffffffffffffff) << (VA_BITS - 1)) #define MODULES_END (PAGE_OFFSET) #define MODULES_VADDR (MODULES_END - SZ_64M) #define EARLYCON_IOBASE (MODULES_VADDR - SZ_4M) -#define VA_BITS (39) #define TASK_SIZE_64 (UL(1) << VA_BITS) #ifdef CONFIG_COMPAT diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h index f214069ec5d5..9bea6e74a001 100644 --- a/arch/arm64/include/asm/pgalloc.h +++ b/arch/arm64/include/asm/pgalloc.h @@ -63,9 +63,12 @@ pte_alloc_one(struct mm_struct *mm, unsigned long addr) struct page *pte; pte = alloc_pages(PGALLOC_GFP, 0); - if (pte) - pgtable_page_ctor(pte); - + if (!pte) + return NULL; + if (!pgtable_page_ctor(pte)) { + __free_page(pte); + return NULL; + } return pte; } diff --git a/arch/arm64/include/asm/pgtable-2level-hwdef.h b/arch/arm64/include/asm/pgtable-2level-hwdef.h index 0a8ed3f94e93..2593b490c56a 100644 --- a/arch/arm64/include/asm/pgtable-2level-hwdef.h +++ b/arch/arm64/include/asm/pgtable-2level-hwdef.h @@ -21,10 +21,10 @@ * 8192 entries of 8 bytes each, occupying a 64KB page. Levels 0 and 1 are not * used. The 2nd level table (PGD for Linux) can cover a range of 4TB, each * entry representing 512MB. The user and kernel address spaces are limited to - * 512GB and therefore we only use 1024 entries in the PGD. + * 4TB in the 64KB page configuration. */ #define PTRS_PER_PTE 8192 -#define PTRS_PER_PGD 1024 +#define PTRS_PER_PGD 8192 /* * PGDIR_SHIFT determines the size a top-level page table entry can map. diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h index d57e66845c86..755f86143320 100644 --- a/arch/arm64/include/asm/pgtable-hwdef.h +++ b/arch/arm64/include/asm/pgtable-hwdef.h @@ -85,6 +85,8 @@ #define PTE_S2_RDONLY (_AT(pteval_t, 1) << 6) /* HAP[2:1] */ #define PTE_S2_RDWR (_AT(pteval_t, 3) << 6) /* HAP[2:1] */ +#define PMD_S2_RDWR (_AT(pmdval_t, 3) << 6) /* HAP[2:1] */ + /* * Memory Attribute override for Stage-2 (MemAttr[3:0]) */ diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index f0bebc5e22cd..17bd3af0a117 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -33,7 +33,7 @@ /* * VMALLOC and SPARSEMEM_VMEMMAP ranges. */ -#define VMALLOC_START UL(0xffffff8000000000) +#define VMALLOC_START (UL(0xffffffffffffffff) << VA_BITS) #define VMALLOC_END (PAGE_OFFSET - UL(0x400000000) - SZ_64K) #define vmemmap ((struct page *)(VMALLOC_END + SZ_64K)) diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h index ab239b2c456f..45b20cd6cbca 100644 --- a/arch/arm64/include/asm/processor.h +++ b/arch/arm64/include/asm/processor.h @@ -107,6 +107,11 @@ static inline void compat_start_thread(struct pt_regs *regs, unsigned long pc, regs->pstate = COMPAT_PSR_MODE_USR; if (pc & 1) regs->pstate |= COMPAT_PSR_T_BIT; + +#ifdef __AARCH64EB__ + regs->pstate |= COMPAT_PSR_E_BIT; +#endif + regs->compat_sp = sp; } #endif diff --git a/arch/arm64/include/asm/prom.h b/arch/arm64/include/asm/prom.h deleted file mode 100644 index 68b90e682957..000000000000 --- a/arch/arm64/include/asm/prom.h +++ /dev/null @@ -1 +0,0 @@ -/* Empty for now */ diff --git a/arch/arm64/include/asm/psci.h b/arch/arm64/include/asm/psci.h index 0604237ecd99..e5312ea0ec1a 100644 --- a/arch/arm64/include/asm/psci.h +++ b/arch/arm64/include/asm/psci.h @@ -14,25 +14,6 @@ #ifndef __ASM_PSCI_H #define __ASM_PSCI_H -#define PSCI_POWER_STATE_TYPE_STANDBY 0 -#define PSCI_POWER_STATE_TYPE_POWER_DOWN 1 - -struct psci_power_state { - u16 id; - u8 type; - u8 affinity_level; -}; - -struct psci_operations { - int (*cpu_suspend)(struct psci_power_state state, - unsigned long entry_point); - int (*cpu_off)(struct psci_power_state state); - int (*cpu_on)(unsigned long cpuid, unsigned long entry_point); - int (*migrate)(unsigned long cpuid); -}; - -extern struct psci_operations psci_ops; - int psci_init(void); #endif /* __ASM_PSCI_H */ diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h index 0dacbbf9458b..0e7fa4963735 100644 --- a/arch/arm64/include/asm/ptrace.h +++ b/arch/arm64/include/asm/ptrace.h @@ -42,6 +42,7 @@ #define COMPAT_PSR_MODE_UND 0x0000001b #define COMPAT_PSR_MODE_SYS 0x0000001f #define COMPAT_PSR_T_BIT 0x00000020 +#define COMPAT_PSR_E_BIT 0x00000200 #define COMPAT_PSR_F_BIT 0x00000040 #define COMPAT_PSR_I_BIT 0x00000080 #define COMPAT_PSR_A_BIT 0x00000100 diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h index 4b8023c5d146..a498f2cd2c2a 100644 --- a/arch/arm64/include/asm/smp.h +++ b/arch/arm64/include/asm/smp.h @@ -60,21 +60,14 @@ struct secondary_data { void *stack; }; extern struct secondary_data secondary_data; -extern void secondary_holding_pen(void); -extern volatile unsigned long secondary_holding_pen_release; +extern void secondary_entry(void); extern void arch_send_call_function_single_ipi(int cpu); extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); -struct device_node; +extern int __cpu_disable(void); -struct smp_enable_ops { - const char *name; - int (*init_cpu)(struct device_node *, int); - int (*prepare_cpu)(int); -}; - -extern const struct smp_enable_ops smp_spin_table_ops; -extern const struct smp_enable_ops smp_psci_ops; +extern void __cpu_die(unsigned int cpu); +extern void cpu_die(void); #endif /* ifndef __ASM_SMP_H */ diff --git a/arch/arm64/include/asm/spinlock.h b/arch/arm64/include/asm/spinlock.h index 0defa0728a9b..3d5cf064d7a1 100644 --- a/arch/arm64/include/asm/spinlock.h +++ b/arch/arm64/include/asm/spinlock.h @@ -22,17 +22,10 @@ /* * Spinlock implementation. * - * The old value is read exclusively and the new one, if unlocked, is written - * exclusively. In case of failure, the loop is restarted. - * * The memory barriers are implicit with the load-acquire and store-release * instructions. - * - * Unlocked value: 0 - * Locked value: 1 */ -#define arch_spin_is_locked(x) ((x)->lock != 0) #define arch_spin_unlock_wait(lock) \ do { while (arch_spin_is_locked(lock)) cpu_relax(); } while (0) @@ -41,32 +34,51 @@ static inline void arch_spin_lock(arch_spinlock_t *lock) { unsigned int tmp; + arch_spinlock_t lockval, newval; asm volatile( - " sevl\n" - "1: wfe\n" - "2: ldaxr %w0, %1\n" - " cbnz %w0, 1b\n" - " stxr %w0, %w2, %1\n" - " cbnz %w0, 2b\n" - : "=&r" (tmp), "+Q" (lock->lock) - : "r" (1) - : "cc", "memory"); + /* Atomically increment the next ticket. */ +" prfm pstl1strm, %3\n" +"1: ldaxr %w0, %3\n" +" add %w1, %w0, %w5\n" +" stxr %w2, %w1, %3\n" +" cbnz %w2, 1b\n" + /* Did we get the lock? */ +" eor %w1, %w0, %w0, ror #16\n" +" cbz %w1, 3f\n" + /* + * No: spin on the owner. Send a local event to avoid missing an + * unlock before the exclusive load. + */ +" sevl\n" +"2: wfe\n" +" ldaxrh %w2, %4\n" +" eor %w1, %w2, %w0, lsr #16\n" +" cbnz %w1, 2b\n" + /* We got the lock. Critical section starts here. */ +"3:" + : "=&r" (lockval), "=&r" (newval), "=&r" (tmp), "+Q" (*lock) + : "Q" (lock->owner), "I" (1 << TICKET_SHIFT) + : "memory"); } static inline int arch_spin_trylock(arch_spinlock_t *lock) { unsigned int tmp; + arch_spinlock_t lockval; asm volatile( - "2: ldaxr %w0, %1\n" - " cbnz %w0, 1f\n" - " stxr %w0, %w2, %1\n" - " cbnz %w0, 2b\n" - "1:\n" - : "=&r" (tmp), "+Q" (lock->lock) - : "r" (1) - : "cc", "memory"); +" prfm pstl1strm, %2\n" +"1: ldaxr %w0, %2\n" +" eor %w1, %w0, %w0, ror #16\n" +" cbnz %w1, 2f\n" +" add %w0, %w0, %3\n" +" stxr %w1, %w0, %2\n" +" cbnz %w1, 1b\n" +"2:" + : "=&r" (lockval), "=&r" (tmp), "+Q" (*lock) + : "I" (1 << TICKET_SHIFT) + : "memory"); return !tmp; } @@ -74,9 +86,28 @@ static inline int arch_spin_trylock(arch_spinlock_t *lock) static inline void arch_spin_unlock(arch_spinlock_t *lock) { asm volatile( - " stlr %w1, %0\n" - : "=Q" (lock->lock) : "r" (0) : "memory"); +" stlrh %w1, %0\n" + : "=Q" (lock->owner) + : "r" (lock->owner + 1) + : "memory"); +} + +static inline int arch_spin_value_unlocked(arch_spinlock_t lock) +{ + return lock.owner == lock.next; +} + +static inline int arch_spin_is_locked(arch_spinlock_t *lock) +{ + return !arch_spin_value_unlocked(ACCESS_ONCE(*lock)); +} + +static inline int arch_spin_is_contended(arch_spinlock_t *lock) +{ + arch_spinlock_t lockval = ACCESS_ONCE(*lock); + return (lockval.next - lockval.owner) > 1; } +#define arch_spin_is_contended arch_spin_is_contended /* * Write lock implementation. diff --git a/arch/arm64/include/asm/spinlock_types.h b/arch/arm64/include/asm/spinlock_types.h index 9a494346efed..b8d383665f56 100644 --- a/arch/arm64/include/asm/spinlock_types.h +++ b/arch/arm64/include/asm/spinlock_types.h @@ -20,14 +20,19 @@ # error "please don't include this file directly" #endif -/* We only require natural alignment for exclusive accesses. */ -#define __lock_aligned +#define TICKET_SHIFT 16 typedef struct { - volatile unsigned int lock; -} arch_spinlock_t; +#ifdef __AARCH64EB__ + u16 next; + u16 owner; +#else + u16 owner; + u16 next; +#endif +} __aligned(4) arch_spinlock_t; -#define __ARCH_SPIN_LOCK_UNLOCKED { 0 } +#define __ARCH_SPIN_LOCK_UNLOCKED { 0 , 0 } typedef struct { volatile unsigned int lock; diff --git a/arch/arm64/include/asm/syscall.h b/arch/arm64/include/asm/syscall.h index 89c047f9a971..70ba9d4ee978 100644 --- a/arch/arm64/include/asm/syscall.h +++ b/arch/arm64/include/asm/syscall.h @@ -59,6 +59,9 @@ static inline void syscall_get_arguments(struct task_struct *task, unsigned int i, unsigned int n, unsigned long *args) { + if (n == 0) + return; + if (i + n > SYSCALL_MAX_ARGS) { unsigned long *args_bad = args + SYSCALL_MAX_ARGS - i; unsigned int n_bad = n + i - SYSCALL_MAX_ARGS; @@ -82,6 +85,9 @@ static inline void syscall_set_arguments(struct task_struct *task, unsigned int i, unsigned int n, const unsigned long *args) { + if (n == 0) + return; + if (i + n > SYSCALL_MAX_ARGS) { pr_warning("%s called with max args %d, handling only %d\n", __func__, i + n, SYSCALL_MAX_ARGS); diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h index 23a3c4791d86..720e70b66ffd 100644 --- a/arch/arm64/include/asm/thread_info.h +++ b/arch/arm64/include/asm/thread_info.h @@ -89,12 +89,6 @@ static inline struct thread_info *current_thread_info(void) #endif /* - * We use bit 30 of the preempt_count to indicate that kernel - * preemption is occurring. See <asm/hardirq.h>. - */ -#define PREEMPT_ACTIVE 0x40000000 - -/* * thread information flags: * TIF_SYSCALL_TRACE - syscall trace active * TIF_SIGPENDING - signal pending diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h index 26e310c54344..130e2be952cf 100644 --- a/arch/arm64/include/asm/virt.h +++ b/arch/arm64/include/asm/virt.h @@ -18,7 +18,8 @@ #ifndef __ASM__VIRT_H #define __ASM__VIRT_H -#define BOOT_CPU_MODE_EL2 (0x0e12b007) +#define BOOT_CPU_MODE_EL1 (0xe11) +#define BOOT_CPU_MODE_EL2 (0xe12) #ifndef __ASSEMBLY__ #include <asm/cacheflush.h> diff --git a/arch/arm64/include/asm/xen/page-coherent.h b/arch/arm64/include/asm/xen/page-coherent.h new file mode 100644 index 000000000000..2820f1a6eebe --- /dev/null +++ b/arch/arm64/include/asm/xen/page-coherent.h @@ -0,0 +1,47 @@ +#ifndef _ASM_ARM64_XEN_PAGE_COHERENT_H +#define _ASM_ARM64_XEN_PAGE_COHERENT_H + +#include <asm/page.h> +#include <linux/dma-attrs.h> +#include <linux/dma-mapping.h> + +static inline void *xen_alloc_coherent_pages(struct device *hwdev, size_t size, + dma_addr_t *dma_handle, gfp_t flags, + struct dma_attrs *attrs) +{ + return __generic_dma_ops(hwdev)->alloc(hwdev, size, dma_handle, flags, attrs); +} + +static inline void xen_free_coherent_pages(struct device *hwdev, size_t size, + void *cpu_addr, dma_addr_t dma_handle, + struct dma_attrs *attrs) +{ + __generic_dma_ops(hwdev)->free(hwdev, size, cpu_addr, dma_handle, attrs); +} + +static inline void xen_dma_map_page(struct device *hwdev, struct page *page, + unsigned long offset, size_t size, enum dma_data_direction dir, + struct dma_attrs *attrs) +{ + __generic_dma_ops(hwdev)->map_page(hwdev, page, offset, size, dir, attrs); +} + +static inline void xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle, + size_t size, enum dma_data_direction dir, + struct dma_attrs *attrs) +{ + __generic_dma_ops(hwdev)->unmap_page(hwdev, handle, size, dir, attrs); +} + +static inline void xen_dma_sync_single_for_cpu(struct device *hwdev, + dma_addr_t handle, size_t size, enum dma_data_direction dir) +{ + __generic_dma_ops(hwdev)->sync_single_for_cpu(hwdev, handle, size, dir); +} + +static inline void xen_dma_sync_single_for_device(struct device *hwdev, + dma_addr_t handle, size_t size, enum dma_data_direction dir) +{ + __generic_dma_ops(hwdev)->sync_single_for_device(hwdev, handle, size, dir); +} +#endif /* _ASM_ARM64_XEN_PAGE_COHERENT_H */ diff --git a/arch/arm64/include/uapi/asm/byteorder.h b/arch/arm64/include/uapi/asm/byteorder.h index 2b92046aafc5..dc19e9537f0d 100644 --- a/arch/arm64/include/uapi/asm/byteorder.h +++ b/arch/arm64/include/uapi/asm/byteorder.h @@ -16,6 +16,10 @@ #ifndef __ASM_BYTEORDER_H #define __ASM_BYTEORDER_H +#ifdef __AARCH64EB__ +#include <linux/byteorder/big_endian.h> +#else #include <linux/byteorder/little_endian.h> +#endif #endif /* __ASM_BYTEORDER_H */ diff --git a/arch/arm64/include/uapi/asm/hwcap.h b/arch/arm64/include/uapi/asm/hwcap.h index eea497578b87..9b12476e9c85 100644 --- a/arch/arm64/include/uapi/asm/hwcap.h +++ b/arch/arm64/include/uapi/asm/hwcap.h @@ -21,6 +21,7 @@ */ #define HWCAP_FP (1 << 0) #define HWCAP_ASIMD (1 << 1) +#define HWCAP_EVTSTRM (1 << 2) #endif /* _UAPI__ASM_HWCAP_H */ diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index 7b4b564961d4..5ba2fd43a75b 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile @@ -9,12 +9,12 @@ AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET) arm64-obj-y := cputable.o debug-monitors.o entry.o irq.o fpsimd.o \ entry-fpsimd.o process.o ptrace.o setup.o signal.o \ sys.o stacktrace.o time.o traps.o io.o vdso.o \ - hyp-stub.o psci.o + hyp-stub.o psci.o cpu_ops.o arm64-obj-$(CONFIG_COMPAT) += sys32.o kuser32.o signal32.o \ sys_compat.o arm64-obj-$(CONFIG_MODULES) += arm64ksyms.o module.o -arm64-obj-$(CONFIG_SMP) += smp.o smp_spin_table.o smp_psci.o +arm64-obj-$(CONFIG_SMP) += smp.o smp_spin_table.o arm64-obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT)+= hw_breakpoint.o arm64-obj-$(CONFIG_EARLY_PRINTK) += early_printk.o diff --git a/arch/arm64/kernel/arm64ksyms.c b/arch/arm64/kernel/arm64ksyms.c index 41b4f626d554..e7ee770c0697 100644 --- a/arch/arm64/kernel/arm64ksyms.c +++ b/arch/arm64/kernel/arm64ksyms.c @@ -39,6 +39,7 @@ EXPORT_SYMBOL(clear_page); EXPORT_SYMBOL(__copy_from_user); EXPORT_SYMBOL(__copy_to_user); EXPORT_SYMBOL(__clear_user); +EXPORT_SYMBOL(__copy_in_user); /* physical memory */ EXPORT_SYMBOL(memstart_addr); diff --git a/arch/arm64/kernel/cpu_ops.c b/arch/arm64/kernel/cpu_ops.c new file mode 100644 index 000000000000..d62d12fb36c8 --- /dev/null +++ b/arch/arm64/kernel/cpu_ops.c @@ -0,0 +1,87 @@ +/* + * CPU kernel entry/exit control + * + * Copyright (C) 2013 ARM Ltd. + * + * 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. + * + * This program is distributed in the hope that 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/>. + */ + +#include <asm/cpu_ops.h> +#include <asm/smp_plat.h> +#include <linux/errno.h> +#include <linux/of.h> +#include <linux/string.h> + +extern const struct cpu_operations smp_spin_table_ops; +extern const struct cpu_operations cpu_psci_ops; + +const struct cpu_operations *cpu_ops[NR_CPUS]; + +static const struct cpu_operations *supported_cpu_ops[] __initconst = { +#ifdef CONFIG_SMP + &smp_spin_table_ops, + &cpu_psci_ops, +#endif + NULL, +}; + +static const struct cpu_operations * __init cpu_get_ops(const char *name) +{ + const struct cpu_operations **ops = supported_cpu_ops; + + while (*ops) { + if (!strcmp(name, (*ops)->name)) + return *ops; + + ops++; + } + + return NULL; +} + +/* + * Read a cpu's enable method from the device tree and record it in cpu_ops. + */ +int __init cpu_read_ops(struct device_node *dn, int cpu) +{ + const char *enable_method = of_get_property(dn, "enable-method", NULL); + if (!enable_method) { + /* + * The boot CPU may not have an enable method (e.g. when + * spin-table is used for secondaries). Don't warn spuriously. + */ + if (cpu != 0) + pr_err("%s: missing enable-method property\n", + dn->full_name); + return -ENOENT; + } + + cpu_ops[cpu] = cpu_get_ops(enable_method); + if (!cpu_ops[cpu]) { + pr_warn("%s: unsupported enable-method property: %s\n", + dn->full_name, enable_method); + return -EOPNOTSUPP; + } + + return 0; +} + +void __init cpu_read_bootcpu_ops(void) +{ + struct device_node *dn = of_get_cpu_node(0, NULL); + if (!dn) { + pr_err("Failed to find device node for boot cpu\n"); + return; + } + cpu_read_ops(dn, 0); +} diff --git a/arch/arm64/kernel/cputable.c b/arch/arm64/kernel/cputable.c index 63cfc4a43f4e..fd3993cb060f 100644 --- a/arch/arm64/kernel/cputable.c +++ b/arch/arm64/kernel/cputable.c @@ -22,7 +22,7 @@ extern unsigned long __cpu_setup(void); -struct cpu_info __initdata cpu_table[] = { +struct cpu_info cpu_table[] = { { .cpu_id_val = 0x000f0000, .cpu_id_mask = 0x000f0000, diff --git a/arch/arm64/kernel/debug-monitors.c b/arch/arm64/kernel/debug-monitors.c index cbfacf7fb438..6a0a9b132d7a 100644 --- a/arch/arm64/kernel/debug-monitors.c +++ b/arch/arm64/kernel/debug-monitors.c @@ -27,7 +27,6 @@ #include <linux/uaccess.h> #include <asm/debug-monitors.h> -#include <asm/local.h> #include <asm/cputype.h> #include <asm/system_misc.h> @@ -89,8 +88,8 @@ early_param("nodebugmon", early_debug_disable); * Keep track of debug users on each core. * The ref counts are per-cpu so we use a local_t type. */ -static DEFINE_PER_CPU(local_t, mde_ref_count); -static DEFINE_PER_CPU(local_t, kde_ref_count); +static DEFINE_PER_CPU(int, mde_ref_count); +static DEFINE_PER_CPU(int, kde_ref_count); void enable_debug_monitors(enum debug_el el) { @@ -98,11 +97,11 @@ void enable_debug_monitors(enum debug_el el) WARN_ON(preemptible()); - if (local_inc_return(&__get_cpu_var(mde_ref_count)) == 1) + if (this_cpu_inc_return(mde_ref_count) == 1) enable = DBG_MDSCR_MDE; if (el == DBG_ACTIVE_EL1 && - local_inc_return(&__get_cpu_var(kde_ref_count)) == 1) + this_cpu_inc_return(kde_ref_count) == 1) enable |= DBG_MDSCR_KDE; if (enable && debug_enabled) { @@ -118,11 +117,11 @@ void disable_debug_monitors(enum debug_el el) WARN_ON(preemptible()); - if (local_dec_and_test(&__get_cpu_var(mde_ref_count))) + if (this_cpu_dec_return(mde_ref_count) == 0) disable = ~DBG_MDSCR_MDE; if (el == DBG_ACTIVE_EL1 && - local_dec_and_test(&__get_cpu_var(kde_ref_count))) + this_cpu_dec_return(kde_ref_count) == 0) disable &= ~DBG_MDSCR_KDE; if (disable) { diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index 3881fd115ebb..e1166145ca29 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S @@ -311,14 +311,14 @@ el1_irq: #endif #ifdef CONFIG_PREEMPT get_thread_info tsk - ldr x24, [tsk, #TI_PREEMPT] // get preempt count - add x0, x24, #1 // increment it - str x0, [tsk, #TI_PREEMPT] + ldr w24, [tsk, #TI_PREEMPT] // get preempt count + add w0, w24, #1 // increment it + str w0, [tsk, #TI_PREEMPT] #endif irq_handler #ifdef CONFIG_PREEMPT - str x24, [tsk, #TI_PREEMPT] // restore preempt count - cbnz x24, 1f // preempt count != 0 + str w24, [tsk, #TI_PREEMPT] // restore preempt count + cbnz w24, 1f // preempt count != 0 ldr x0, [tsk, #TI_FLAGS] // get flags tbz x0, #TIF_NEED_RESCHED, 1f // needs rescheduling? bl el1_preempt @@ -509,15 +509,15 @@ el0_irq_naked: #endif get_thread_info tsk #ifdef CONFIG_PREEMPT - ldr x24, [tsk, #TI_PREEMPT] // get preempt count - add x23, x24, #1 // increment it - str x23, [tsk, #TI_PREEMPT] + ldr w24, [tsk, #TI_PREEMPT] // get preempt count + add w23, w24, #1 // increment it + str w23, [tsk, #TI_PREEMPT] #endif irq_handler #ifdef CONFIG_PREEMPT - ldr x0, [tsk, #TI_PREEMPT] - str x24, [tsk, #TI_PREEMPT] - cmp x0, x23 + ldr w0, [tsk, #TI_PREEMPT] + str w24, [tsk, #TI_PREEMPT] + cmp w0, w23 b.eq 1f mov x1, #0 str x1, [x1] // BUG diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index 7090c126797c..7009387348b7 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S @@ -123,8 +123,9 @@ ENTRY(stext) mov x21, x0 // x21=FDT + bl el2_setup // Drop to EL1, w20=cpu_boot_mode bl __calc_phys_offset // x24=PHYS_OFFSET, x28=PHYS_OFFSET-PAGE_OFFSET - bl el2_setup // Drop to EL1 + bl set_cpu_boot_mode_flag mrs x22, midr_el1 // x22=cpuid mov x0, x22 bl lookup_processor_type @@ -150,21 +151,30 @@ ENDPROC(stext) /* * If we're fortunate enough to boot at EL2, ensure that the world is * sane before dropping to EL1. + * + * Returns either BOOT_CPU_MODE_EL1 or BOOT_CPU_MODE_EL2 in x20 if + * booted in EL1 or EL2 respectively. */ ENTRY(el2_setup) mrs x0, CurrentEL cmp x0, #PSR_MODE_EL2t ccmp x0, #PSR_MODE_EL2h, #0x4, ne - ldr x0, =__boot_cpu_mode // Compute __boot_cpu_mode - add x0, x0, x28 - b.eq 1f - str wzr, [x0] // Remember we don't have EL2... + b.ne 1f + mrs x0, sctlr_el2 +CPU_BE( orr x0, x0, #(1 << 25) ) // Set the EE bit for EL2 +CPU_LE( bic x0, x0, #(1 << 25) ) // Clear the EE bit for EL2 + msr sctlr_el2, x0 + b 2f +1: mrs x0, sctlr_el1 +CPU_BE( orr x0, x0, #(3 << 24) ) // Set the EE and E0E bits for EL1 +CPU_LE( bic x0, x0, #(3 << 24) ) // Clear the EE and E0E bits for EL1 + msr sctlr_el1, x0 + mov w20, #BOOT_CPU_MODE_EL1 // This cpu booted in EL1 + isb ret /* Hyp configuration. */ -1: ldr w1, =BOOT_CPU_MODE_EL2 - str w1, [x0, #4] // This CPU has EL2 - mov x0, #(1 << 31) // 64-bit EL1 +2: mov x0, #(1 << 31) // 64-bit EL1 msr hcr_el2, x0 /* Generic timers. */ @@ -181,7 +191,8 @@ ENTRY(el2_setup) /* sctlr_el1 */ mov x0, #0x0800 // Set/clear RES{1,0} bits - movk x0, #0x30d0, lsl #16 +CPU_BE( movk x0, #0x33d0, lsl #16 ) // Set EE and E0E on BE systems +CPU_LE( movk x0, #0x30d0, lsl #16 ) // Clear EE and E0E on LE systems msr sctlr_el1, x0 /* Coprocessor traps. */ @@ -204,10 +215,25 @@ ENTRY(el2_setup) PSR_MODE_EL1h) msr spsr_el2, x0 msr elr_el2, lr + mov w20, #BOOT_CPU_MODE_EL2 // This CPU booted in EL2 eret ENDPROC(el2_setup) /* + * Sets the __boot_cpu_mode flag depending on the CPU boot mode passed + * in x20. See arch/arm64/include/asm/virt.h for more info. + */ +ENTRY(set_cpu_boot_mode_flag) + ldr x1, =__boot_cpu_mode // Compute __boot_cpu_mode + add x1, x1, x28 + cmp w20, #BOOT_CPU_MODE_EL2 + b.ne 1f + add x1, x1, #4 +1: str w20, [x1] // This CPU has booted in EL1 + ret +ENDPROC(set_cpu_boot_mode_flag) + +/* * We need to find out the CPU boot mode long after boot, so we need to * store it in a writable variable. * @@ -225,7 +251,6 @@ ENTRY(__boot_cpu_mode) .quad PAGE_OFFSET #ifdef CONFIG_SMP - .pushsection .smp.pen.text, "ax" .align 3 1: .quad . .quad secondary_holding_pen_release @@ -235,8 +260,9 @@ ENTRY(__boot_cpu_mode) * cores are held until we're ready for them to initialise. */ ENTRY(secondary_holding_pen) - bl __calc_phys_offset // x24=phys offset - bl el2_setup // Drop to EL1 + bl el2_setup // Drop to EL1, w20=cpu_boot_mode + bl __calc_phys_offset // x24=PHYS_OFFSET, x28=PHYS_OFFSET-PAGE_OFFSET + bl set_cpu_boot_mode_flag mrs x0, mpidr_el1 ldr x1, =MPIDR_HWID_BITMASK and x0, x0, x1 @@ -250,7 +276,16 @@ pen: ldr x4, [x3] wfe b pen ENDPROC(secondary_holding_pen) - .popsection + + /* + * Secondary entry point that jumps straight into the kernel. Only to + * be used where CPUs are brought online dynamically by the kernel. + */ +ENTRY(secondary_entry) + bl __calc_phys_offset // x2=phys offset + bl el2_setup // Drop to EL1 + b secondary_startup +ENDPROC(secondary_entry) ENTRY(secondary_startup) /* diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c index 329218ca9ffb..ff516f6691e4 100644 --- a/arch/arm64/kernel/hw_breakpoint.c +++ b/arch/arm64/kernel/hw_breakpoint.c @@ -184,14 +184,14 @@ int arch_install_hw_breakpoint(struct perf_event *bp) /* Breakpoint */ ctrl_reg = AARCH64_DBG_REG_BCR; val_reg = AARCH64_DBG_REG_BVR; - slots = __get_cpu_var(bp_on_reg); + slots = this_cpu_ptr(bp_on_reg); max_slots = core_num_brps; reg_enable = !debug_info->bps_disabled; } else { /* Watchpoint */ ctrl_reg = AARCH64_DBG_REG_WCR; val_reg = AARCH64_DBG_REG_WVR; - slots = __get_cpu_var(wp_on_reg); + slots = this_cpu_ptr(wp_on_reg); max_slots = core_num_wrps; reg_enable = !debug_info->wps_disabled; } @@ -230,12 +230,12 @@ void arch_uninstall_hw_breakpoint(struct perf_event *bp) if (info->ctrl.type == ARM_BREAKPOINT_EXECUTE) { /* Breakpoint */ base = AARCH64_DBG_REG_BCR; - slots = __get_cpu_var(bp_on_reg); + slots = this_cpu_ptr(bp_on_reg); max_slots = core_num_brps; } else { /* Watchpoint */ base = AARCH64_DBG_REG_WCR; - slots = __get_cpu_var(wp_on_reg); + slots = this_cpu_ptr(wp_on_reg); max_slots = core_num_wrps; } @@ -505,11 +505,11 @@ static void toggle_bp_registers(int reg, enum debug_el el, int enable) switch (reg) { case AARCH64_DBG_REG_BCR: - slots = __get_cpu_var(bp_on_reg); + slots = this_cpu_ptr(bp_on_reg); max_slots = core_num_brps; break; case AARCH64_DBG_REG_WCR: - slots = __get_cpu_var(wp_on_reg); + slots = this_cpu_ptr(wp_on_reg); max_slots = core_num_wrps; break; default: @@ -546,7 +546,7 @@ static int breakpoint_handler(unsigned long unused, unsigned int esr, struct debug_info *debug_info; struct arch_hw_breakpoint_ctrl ctrl; - slots = (struct perf_event **)__get_cpu_var(bp_on_reg); + slots = this_cpu_ptr(bp_on_reg); addr = instruction_pointer(regs); debug_info = ¤t->thread.debug; @@ -596,7 +596,7 @@ unlock: user_enable_single_step(current); } else { toggle_bp_registers(AARCH64_DBG_REG_BCR, DBG_ACTIVE_EL1, 0); - kernel_step = &__get_cpu_var(stepping_kernel_bp); + kernel_step = this_cpu_ptr(&stepping_kernel_bp); if (*kernel_step != ARM_KERNEL_STEP_NONE) return 0; @@ -623,7 +623,7 @@ static int watchpoint_handler(unsigned long addr, unsigned int esr, struct arch_hw_breakpoint *info; struct arch_hw_breakpoint_ctrl ctrl; - slots = (struct perf_event **)__get_cpu_var(wp_on_reg); + slots = this_cpu_ptr(wp_on_reg); debug_info = ¤t->thread.debug; for (i = 0; i < core_num_wrps; ++i) { @@ -698,7 +698,7 @@ unlock: user_enable_single_step(current); } else { toggle_bp_registers(AARCH64_DBG_REG_WCR, DBG_ACTIVE_EL1, 0); - kernel_step = &__get_cpu_var(stepping_kernel_bp); + kernel_step = this_cpu_ptr(&stepping_kernel_bp); if (*kernel_step != ARM_KERNEL_STEP_NONE) return 0; @@ -722,7 +722,7 @@ int reinstall_suspended_bps(struct pt_regs *regs) struct debug_info *debug_info = ¤t->thread.debug; int handled_exception = 0, *kernel_step; - kernel_step = &__get_cpu_var(stepping_kernel_bp); + kernel_step = this_cpu_ptr(&stepping_kernel_bp); /* * Called from single-step exception handler. diff --git a/arch/arm64/kernel/irq.c b/arch/arm64/kernel/irq.c index ecb3354292ed..473e5dbf8f39 100644 --- a/arch/arm64/kernel/irq.c +++ b/arch/arm64/kernel/irq.c @@ -81,3 +81,64 @@ void __init init_IRQ(void) if (!handle_arch_irq) panic("No interrupt controller found."); } + +#ifdef CONFIG_HOTPLUG_CPU +static bool migrate_one_irq(struct irq_desc *desc) +{ + struct irq_data *d = irq_desc_get_irq_data(desc); + const struct cpumask *affinity = d->affinity; + struct irq_chip *c; + bool ret = false; + + /* + * If this is a per-CPU interrupt, or the affinity does not + * include this CPU, then we have nothing to do. + */ + if (irqd_is_per_cpu(d) || !cpumask_test_cpu(smp_processor_id(), affinity)) + return false; + + if (cpumask_any_and(affinity, cpu_online_mask) >= nr_cpu_ids) { + affinity = cpu_online_mask; + ret = true; + } + + c = irq_data_get_irq_chip(d); + if (!c->irq_set_affinity) + pr_debug("IRQ%u: unable to set affinity\n", d->irq); + else if (c->irq_set_affinity(d, affinity, true) == IRQ_SET_MASK_OK && ret) + cpumask_copy(d->affinity, affinity); + + return ret; +} + +/* + * The current CPU has been marked offline. Migrate IRQs off this CPU. + * If the affinity settings do not allow other CPUs, force them onto any + * available CPU. + * + * Note: we must iterate over all IRQs, whether they have an attached + * action structure or not, as we need to get chained interrupts too. + */ +void migrate_irqs(void) +{ + unsigned int i; + struct irq_desc *desc; + unsigned long flags; + + local_irq_save(flags); + + for_each_irq_desc(i, desc) { + bool affinity_broken; + + raw_spin_lock(&desc->lock); + affinity_broken = migrate_one_irq(desc); + raw_spin_unlock(&desc->lock); + + if (affinity_broken) + pr_warn_ratelimited("IRQ%u no longer affine to CPU%u\n", + i, smp_processor_id()); + } + + local_irq_restore(flags); +} +#endif /* CONFIG_HOTPLUG_CPU */ diff --git a/arch/arm64/kernel/kuser32.S b/arch/arm64/kernel/kuser32.S index 8b69ecb1d8bc..63c48ffdf230 100644 --- a/arch/arm64/kernel/kuser32.S +++ b/arch/arm64/kernel/kuser32.S @@ -27,6 +27,9 @@ * * See Documentation/arm/kernel_user_helpers.txt for formal definitions. */ + +#include <asm/unistd32.h> + .align 5 .globl __kuser_helper_start __kuser_helper_start: @@ -35,33 +38,30 @@ __kuser_cmpxchg64: // 0xffff0f60 .inst 0xe92d00f0 // push {r4, r5, r6, r7} .inst 0xe1c040d0 // ldrd r4, r5, [r0] .inst 0xe1c160d0 // ldrd r6, r7, [r1] - .inst 0xf57ff05f // dmb sy - .inst 0xe1b20f9f // 1: ldrexd r0, r1, [r2] + .inst 0xe1b20e9f // 1: ldaexd r0, r1, [r2] .inst 0xe0303004 // eors r3, r0, r4 .inst 0x00313005 // eoreqs r3, r1, r5 - .inst 0x01a23f96 // strexdeq r3, r6, [r2] + .inst 0x01a23e96 // stlexdeq r3, r6, [r2] .inst 0x03330001 // teqeq r3, #1 .inst 0x0afffff9 // beq 1b - .inst 0xf57ff05f // dmb sy .inst 0xe2730000 // rsbs r0, r3, #0 .inst 0xe8bd00f0 // pop {r4, r5, r6, r7} .inst 0xe12fff1e // bx lr .align 5 __kuser_memory_barrier: // 0xffff0fa0 - .inst 0xf57ff05f // dmb sy + .inst 0xf57ff05b // dmb ish .inst 0xe12fff1e // bx lr .align 5 __kuser_cmpxchg: // 0xffff0fc0 - .inst 0xf57ff05f // dmb sy - .inst 0xe1923f9f // 1: ldrex r3, [r2] + .inst 0xe1923e9f // 1: ldaex r3, [r2] .inst 0xe0533000 // subs r3, r3, r0 - .inst 0x01823f91 // strexeq r3, r1, [r2] + .inst 0x01823e91 // stlexeq r3, r1, [r2] .inst 0x03330001 // teqeq r3, #1 .inst 0x0afffffa // beq 1b .inst 0xe2730000 // rsbs r0, r3, #0 - .inst 0xeaffffef // b <__kuser_memory_barrier> + .inst 0xe12fff1e // bx lr .align 5 __kuser_get_tls: // 0xffff0fe0 @@ -75,3 +75,42 @@ __kuser_helper_version: // 0xffff0ffc .word ((__kuser_helper_end - __kuser_helper_start) >> 5) .globl __kuser_helper_end __kuser_helper_end: + +/* + * AArch32 sigreturn code + * + * For ARM syscalls, the syscall number has to be loaded into r7. + * We do not support an OABI userspace. + * + * For Thumb syscalls, we also pass the syscall number via r7. We therefore + * need two 16-bit instructions. + */ + .globl __aarch32_sigret_code_start +__aarch32_sigret_code_start: + + /* + * ARM Code + */ + .byte __NR_compat_sigreturn, 0x70, 0xa0, 0xe3 // mov r7, #__NR_compat_sigreturn + .byte __NR_compat_sigreturn, 0x00, 0x00, 0xef // svc #__NR_compat_sigreturn + + /* + * Thumb code + */ + .byte __NR_compat_sigreturn, 0x27 // svc #__NR_compat_sigreturn + .byte __NR_compat_sigreturn, 0xdf // mov r7, #__NR_compat_sigreturn + + /* + * ARM code + */ + .byte __NR_compat_rt_sigreturn, 0x70, 0xa0, 0xe3 // mov r7, #__NR_compat_rt_sigreturn + .byte __NR_compat_rt_sigreturn, 0x00, 0x00, 0xef // svc #__NR_compat_rt_sigreturn + + /* + * Thumb code + */ + .byte __NR_compat_rt_sigreturn, 0x27 // svc #__NR_compat_rt_sigreturn + .byte __NR_compat_rt_sigreturn, 0xdf // mov r7, #__NR_compat_rt_sigreturn + + .globl __aarch32_sigret_code_end +__aarch32_sigret_code_end: diff --git a/arch/arm64/kernel/module.c b/arch/arm64/kernel/module.c index ca0e3d55da99..e2ad0d87721f 100644 --- a/arch/arm64/kernel/module.c +++ b/arch/arm64/kernel/module.c @@ -29,7 +29,7 @@ void *module_alloc(unsigned long size) { return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END, - GFP_KERNEL, PAGE_KERNEL_EXEC, -1, + GFP_KERNEL, PAGE_KERNEL_EXEC, NUMA_NO_NODE, __builtin_return_address(0)); } @@ -111,6 +111,9 @@ static u32 encode_insn_immediate(enum aarch64_imm_type type, u32 insn, u64 imm) u32 immlo, immhi, lomask, himask, mask; int shift; + /* The instruction stream is always little endian. */ + insn = le32_to_cpu(insn); + switch (type) { case INSN_IMM_MOVNZ: /* @@ -179,7 +182,7 @@ static u32 encode_insn_immediate(enum aarch64_imm_type type, u32 insn, u64 imm) insn &= ~(mask << shift); insn |= (imm & mask) << shift; - return insn; + return cpu_to_le32(insn); } static int reloc_insn_movw(enum aarch64_reloc_op op, void *place, u64 val, diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c index cea1594ff933..0e63c98d224c 100644 --- a/arch/arm64/kernel/perf_event.c +++ b/arch/arm64/kernel/perf_event.c @@ -784,8 +784,8 @@ static const unsigned armv8_pmuv3_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] /* * PMXEVTYPER: Event selection reg */ -#define ARMV8_EVTYPE_MASK 0xc80000ff /* Mask for writable bits */ -#define ARMV8_EVTYPE_EVENT 0xff /* Mask for EVENT bits */ +#define ARMV8_EVTYPE_MASK 0xc80003ff /* Mask for writable bits */ +#define ARMV8_EVTYPE_EVENT 0x3ff /* Mask for EVENT bits */ /* * Event filters for PMUv3 @@ -1044,7 +1044,7 @@ static irqreturn_t armv8pmu_handle_irq(int irq_num, void *dev) */ regs = get_irq_regs(); - cpuc = &__get_cpu_var(cpu_hw_events); + cpuc = this_cpu_ptr(&cpu_hw_events); for (idx = 0; idx < cpu_pmu->num_events; ++idx) { struct perf_event *event = cpuc->events[idx]; struct hw_perf_event *hwc; @@ -1175,7 +1175,8 @@ static void armv8pmu_reset(void *info) static int armv8_pmuv3_map_event(struct perf_event *event) { return map_cpu_event(event, &armv8_pmuv3_perf_map, - &armv8_pmuv3_perf_cache_map, 0xFF); + &armv8_pmuv3_perf_cache_map, + ARMV8_EVTYPE_EVENT); } static struct arm_pmu armv8pmu = { @@ -1257,7 +1258,7 @@ device_initcall(register_pmu_driver); static struct pmu_hw_events *armpmu_get_cpu_events(void) { - return &__get_cpu_var(cpu_hw_events); + return this_cpu_ptr(&cpu_hw_events); } static void __init cpu_pmu_init(struct arm_pmu *armpmu) diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index 7ae8a1f00c3c..de17c89985db 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c @@ -102,6 +102,13 @@ void arch_cpu_idle(void) local_irq_enable(); } +#ifdef CONFIG_HOTPLUG_CPU +void arch_cpu_idle_dead(void) +{ + cpu_die(); +} +#endif + void machine_shutdown(void) { #ifdef CONFIG_SMP diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c index 14f73c445ff5..4f97db3d7363 100644 --- a/arch/arm64/kernel/psci.c +++ b/arch/arm64/kernel/psci.c @@ -17,12 +17,32 @@ #include <linux/init.h> #include <linux/of.h> +#include <linux/smp.h> #include <asm/compiler.h> +#include <asm/cpu_ops.h> #include <asm/errno.h> #include <asm/psci.h> +#include <asm/smp_plat.h> -struct psci_operations psci_ops; +#define PSCI_POWER_STATE_TYPE_STANDBY 0 +#define PSCI_POWER_STATE_TYPE_POWER_DOWN 1 + +struct psci_power_state { + u16 id; + u8 type; + u8 affinity_level; +}; + +struct psci_operations { + int (*cpu_suspend)(struct psci_power_state state, + unsigned long entry_point); + int (*cpu_off)(struct psci_power_state state); + int (*cpu_on)(unsigned long cpuid, unsigned long entry_point); + int (*migrate)(unsigned long cpuid); +}; + +static struct psci_operations psci_ops; static int (*invoke_psci_fn)(u64, u64, u64, u64); @@ -209,3 +229,68 @@ out_put_node: of_node_put(np); return err; } + +#ifdef CONFIG_SMP + +static int __init cpu_psci_cpu_init(struct device_node *dn, unsigned int cpu) +{ + return 0; +} + +static int __init cpu_psci_cpu_prepare(unsigned int cpu) +{ + if (!psci_ops.cpu_on) { + pr_err("no cpu_on method, not booting CPU%d\n", cpu); + return -ENODEV; + } + + return 0; +} + +static int cpu_psci_cpu_boot(unsigned int cpu) +{ + int err = psci_ops.cpu_on(cpu_logical_map(cpu), __pa(secondary_entry)); + if (err) + pr_err("psci: failed to boot CPU%d (%d)\n", cpu, err); + + return err; +} + +#ifdef CONFIG_HOTPLUG_CPU +static int cpu_psci_cpu_disable(unsigned int cpu) +{ + /* Fail early if we don't have CPU_OFF support */ + if (!psci_ops.cpu_off) + return -EOPNOTSUPP; + return 0; +} + +static void cpu_psci_cpu_die(unsigned int cpu) +{ + int ret; + /* + * There are no known implementations of PSCI actually using the + * power state field, pass a sensible default for now. + */ + struct psci_power_state state = { + .type = PSCI_POWER_STATE_TYPE_POWER_DOWN, + }; + + ret = psci_ops.cpu_off(state); + + pr_crit("psci: unable to power off CPU%u (%d)\n", cpu, ret); +} +#endif + +const struct cpu_operations cpu_psci_ops = { + .name = "psci", + .cpu_init = cpu_psci_cpu_init, + .cpu_prepare = cpu_psci_cpu_prepare, + .cpu_boot = cpu_psci_cpu_boot, +#ifdef CONFIG_HOTPLUG_CPU + .cpu_disable = cpu_psci_cpu_disable, + .cpu_die = cpu_psci_cpu_die, +#endif +}; + +#endif diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c index 055cfb80e05c..0bc5e4cbc017 100644 --- a/arch/arm64/kernel/setup.c +++ b/arch/arm64/kernel/setup.c @@ -45,6 +45,7 @@ #include <asm/cputype.h> #include <asm/elf.h> #include <asm/cputable.h> +#include <asm/cpu_ops.h> #include <asm/sections.h> #include <asm/setup.h> #include <asm/smp_plat.h> @@ -60,6 +61,16 @@ EXPORT_SYMBOL(processor_id); unsigned long elf_hwcap __read_mostly; EXPORT_SYMBOL_GPL(elf_hwcap); +#ifdef CONFIG_COMPAT +#define COMPAT_ELF_HWCAP_DEFAULT \ + (COMPAT_HWCAP_HALF|COMPAT_HWCAP_THUMB|\ + COMPAT_HWCAP_FAST_MULT|COMPAT_HWCAP_EDSP|\ + COMPAT_HWCAP_TLS|COMPAT_HWCAP_VFP|\ + COMPAT_HWCAP_VFPv3|COMPAT_HWCAP_VFPv4|\ + COMPAT_HWCAP_NEON|COMPAT_HWCAP_IDIV) +unsigned int compat_elf_hwcap __read_mostly = COMPAT_ELF_HWCAP_DEFAULT; +#endif + static const char *cpu_name; static const char *machine_name; phys_addr_t __fdt_pointer __initdata; @@ -97,6 +108,11 @@ void __init early_print(const char *str, ...) printk("%s", buf); } +bool arch_match_cpu_phys_id(int cpu, u64 phys_id) +{ + return phys_id == cpu_logical_map(cpu); +} + static void __init setup_processor(void) { struct cpu_info *cpu_info; @@ -118,76 +134,24 @@ static void __init setup_processor(void) printk("CPU: %s [%08x] revision %d\n", cpu_name, read_cpuid_id(), read_cpuid_id() & 15); - sprintf(init_utsname()->machine, "aarch64"); + sprintf(init_utsname()->machine, ELF_PLATFORM); elf_hwcap = 0; } static void __init setup_machine_fdt(phys_addr_t dt_phys) { - struct boot_param_header *devtree; - unsigned long dt_root; - - /* Check we have a non-NULL DT pointer */ - if (!dt_phys) { - early_print("\n" - "Error: NULL or invalid device tree blob\n" - "The dtb must be 8-byte aligned and passed in the first 512MB of memory\n" - "\nPlease check your bootloader.\n"); - - while (true) - cpu_relax(); - - } - - devtree = phys_to_virt(dt_phys); - - /* Check device tree validity */ - if (be32_to_cpu(devtree->magic) != OF_DT_HEADER) { + if (!dt_phys || !early_init_dt_scan(phys_to_virt(dt_phys))) { early_print("\n" "Error: invalid device tree blob at physical address 0x%p (virtual address 0x%p)\n" - "Expected 0x%x, found 0x%x\n" + "The dtb must be 8-byte aligned and passed in the first 512MB of memory\n" "\nPlease check your bootloader.\n", - dt_phys, devtree, OF_DT_HEADER, - be32_to_cpu(devtree->magic)); + dt_phys, phys_to_virt(dt_phys)); while (true) cpu_relax(); } - initial_boot_params = devtree; - dt_root = of_get_flat_dt_root(); - - machine_name = of_get_flat_dt_prop(dt_root, "model", NULL); - if (!machine_name) - machine_name = of_get_flat_dt_prop(dt_root, "compatible", NULL); - if (!machine_name) - machine_name = "<unknown>"; - pr_info("Machine: %s\n", machine_name); - - /* Retrieve various information from the /chosen node */ - of_scan_flat_dt(early_init_dt_scan_chosen, boot_command_line); - /* Initialize {size,address}-cells info */ - of_scan_flat_dt(early_init_dt_scan_root, NULL); - /* Setup memory, calling early_init_dt_add_memory_arch */ - of_scan_flat_dt(early_init_dt_scan_memory, NULL); -} - -void __init early_init_dt_add_memory_arch(u64 base, u64 size) -{ - base &= PAGE_MASK; - size &= PAGE_MASK; - if (base + size < PHYS_OFFSET) { - pr_warning("Ignoring memory block 0x%llx - 0x%llx\n", - base, base + size); - return; - } - if (base < PHYS_OFFSET) { - pr_warning("Ignoring memory range 0x%llx - 0x%llx\n", - base, PHYS_OFFSET); - size -= PHYS_OFFSET - base; - base = PHYS_OFFSET; - } - memblock_add(base, size); + machine_name = of_flat_dt_get_machine_name(); } /* @@ -264,6 +228,7 @@ void __init setup_arch(char **cmdline_p) psci_init(); cpu_logical_map(0) = read_cpuid_mpidr() & MPIDR_HWID_BITMASK; + cpu_read_bootcpu_ops(); #ifdef CONFIG_SMP smp_init_cpus(); #endif @@ -304,6 +269,7 @@ subsys_initcall(topology_init); static const char *hwcap_str[] = { "fp", "asimd", + "evtstrm", NULL }; diff --git a/arch/arm64/kernel/signal32.c b/arch/arm64/kernel/signal32.c index e393174fe859..b3fc9f5ec6d3 100644 --- a/arch/arm64/kernel/signal32.c +++ b/arch/arm64/kernel/signal32.c @@ -100,34 +100,6 @@ struct compat_rt_sigframe { #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) -/* - * For ARM syscalls, the syscall number has to be loaded into r7. - * We do not support an OABI userspace. - */ -#define MOV_R7_NR_SIGRETURN (0xe3a07000 | __NR_compat_sigreturn) -#define SVC_SYS_SIGRETURN (0xef000000 | __NR_compat_sigreturn) -#define MOV_R7_NR_RT_SIGRETURN (0xe3a07000 | __NR_compat_rt_sigreturn) -#define SVC_SYS_RT_SIGRETURN (0xef000000 | __NR_compat_rt_sigreturn) - -/* - * For Thumb syscalls, we also pass the syscall number via r7. We therefore - * need two 16-bit instructions. - */ -#define SVC_THUMB_SIGRETURN (((0xdf00 | __NR_compat_sigreturn) << 16) | \ - 0x2700 | __NR_compat_sigreturn) -#define SVC_THUMB_RT_SIGRETURN (((0xdf00 | __NR_compat_rt_sigreturn) << 16) | \ - 0x2700 | __NR_compat_rt_sigreturn) - -const compat_ulong_t aarch32_sigret_code[6] = { - /* - * AArch32 sigreturn code. - * We don't construct an OABI SWI - instead we just set the imm24 field - * to the EABI syscall number so that we create a sane disassembly. - */ - MOV_R7_NR_SIGRETURN, SVC_SYS_SIGRETURN, SVC_THUMB_SIGRETURN, - MOV_R7_NR_RT_SIGRETURN, SVC_SYS_RT_SIGRETURN, SVC_THUMB_RT_SIGRETURN, -}; - static inline int put_sigset_t(compat_sigset_t __user *uset, sigset_t *set) { compat_sigset_t cset; @@ -150,7 +122,7 @@ static inline int get_sigset_t(sigset_t *set, return 0; } -int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from) +int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from) { int err; @@ -474,12 +446,13 @@ static void compat_setup_return(struct pt_regs *regs, struct k_sigaction *ka, /* Check if the handler is written for ARM or Thumb */ thumb = handler & 1; - if (thumb) { + if (thumb) spsr |= COMPAT_PSR_T_BIT; - spsr &= ~COMPAT_PSR_IT_MASK; - } else { + else spsr &= ~COMPAT_PSR_T_BIT; - } + + /* The IT state must be cleared for both ARM and Thumb-2 */ + spsr &= ~COMPAT_PSR_IT_MASK; if (ka->sa.sa_flags & SA_RESTORER) { retcode = ptr_to_compat(ka->sa.sa_restorer); diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index 78db90dcc910..a5aeefab03c3 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -39,6 +39,7 @@ #include <asm/atomic.h> #include <asm/cacheflush.h> #include <asm/cputype.h> +#include <asm/cpu_ops.h> #include <asm/mmu_context.h> #include <asm/pgtable.h> #include <asm/pgalloc.h> @@ -54,7 +55,6 @@ * where to place its SVC stack */ struct secondary_data secondary_data; -volatile unsigned long secondary_holding_pen_release = INVALID_HWID; enum ipi_msg_type { IPI_RESCHEDULE, @@ -63,61 +63,16 @@ enum ipi_msg_type { IPI_CPU_STOP, }; -static DEFINE_RAW_SPINLOCK(boot_lock); - -/* - * Write secondary_holding_pen_release in a way that is guaranteed to be - * visible to all observers, irrespective of whether they're taking part - * in coherency or not. This is necessary for the hotplug code to work - * reliably. - */ -static void write_pen_release(u64 val) -{ - void *start = (void *)&secondary_holding_pen_release; - unsigned long size = sizeof(secondary_holding_pen_release); - - secondary_holding_pen_release = val; - __flush_dcache_area(start, size); -} - /* * Boot a secondary CPU, and assign it the specified idle task. * This also gives us the initial stack to use for this CPU. */ static int boot_secondary(unsigned int cpu, struct task_struct *idle) { - unsigned long timeout; - - /* - * Set synchronisation state between this boot processor - * and the secondary one - */ - raw_spin_lock(&boot_lock); - - /* - * Update the pen release flag. - */ - write_pen_release(cpu_logical_map(cpu)); - - /* - * Send an event, causing the secondaries to read pen_release. - */ - sev(); - - timeout = jiffies + (1 * HZ); - while (time_before(jiffies, timeout)) { - if (secondary_holding_pen_release == INVALID_HWID) - break; - udelay(10); - } - - /* - * Now the secondary core is starting up let it run its - * calibrations, then wait for it to finish - */ - raw_spin_unlock(&boot_lock); + if (cpu_ops[cpu]->cpu_boot) + return cpu_ops[cpu]->cpu_boot(cpu); - return secondary_holding_pen_release != INVALID_HWID ? -ENOSYS : 0; + return -EOPNOTSUPP; } static DECLARE_COMPLETION(cpu_running); @@ -187,17 +142,13 @@ asmlinkage void secondary_start_kernel(void) preempt_disable(); trace_hardirqs_off(); - /* - * Let the primary processor know we're out of the - * pen, then head off into the C entry point - */ - write_pen_release(INVALID_HWID); + if (cpu_ops[cpu]->cpu_postboot) + cpu_ops[cpu]->cpu_postboot(); /* - * Synchronise with the boot thread. + * Enable GIC and timers. */ - raw_spin_lock(&boot_lock); - raw_spin_unlock(&boot_lock); + notify_cpu_starting(cpu); /* * OK, now it's safe to let the boot CPU continue. Wait for @@ -207,11 +158,6 @@ asmlinkage void secondary_start_kernel(void) set_cpu_online(cpu, true); complete(&cpu_running); - /* - * Enable GIC and timers. - */ - notify_cpu_starting(cpu); - local_irq_enable(); local_fiq_enable(); @@ -221,39 +167,113 @@ asmlinkage void secondary_start_kernel(void) cpu_startup_entry(CPUHP_ONLINE); } -void __init smp_cpus_done(unsigned int max_cpus) +#ifdef CONFIG_HOTPLUG_CPU +static int op_cpu_disable(unsigned int cpu) { - pr_info("SMP: Total of %d processors activated.\n", num_online_cpus()); + /* + * If we don't have a cpu_die method, abort before we reach the point + * of no return. CPU0 may not have an cpu_ops, so test for it. + */ + if (!cpu_ops[cpu] || !cpu_ops[cpu]->cpu_die) + return -EOPNOTSUPP; + + /* + * We may need to abort a hot unplug for some other mechanism-specific + * reason. + */ + if (cpu_ops[cpu]->cpu_disable) + return cpu_ops[cpu]->cpu_disable(cpu); + + return 0; } -void __init smp_prepare_boot_cpu(void) +/* + * __cpu_disable runs on the processor to be shutdown. + */ +int __cpu_disable(void) { -} + unsigned int cpu = smp_processor_id(); + int ret; -static void (*smp_cross_call)(const struct cpumask *, unsigned int); + ret = op_cpu_disable(cpu); + if (ret) + return ret; -static const struct smp_enable_ops *enable_ops[] __initconst = { - &smp_spin_table_ops, - &smp_psci_ops, - NULL, -}; + /* + * Take this CPU offline. Once we clear this, we can't return, + * and we must not schedule until we're ready to give up the cpu. + */ + set_cpu_online(cpu, false); + + /* + * OK - migrate IRQs away from this CPU + */ + migrate_irqs(); -static const struct smp_enable_ops *smp_enable_ops[NR_CPUS]; + /* + * Remove this CPU from the vm mask set of all processes. + */ + clear_tasks_mm_cpumask(cpu); -static const struct smp_enable_ops * __init smp_get_enable_ops(const char *name) -{ - const struct smp_enable_ops **ops = enable_ops; + return 0; +} - while (*ops) { - if (!strcmp(name, (*ops)->name)) - return *ops; +static DECLARE_COMPLETION(cpu_died); - ops++; +/* + * called on the thread which is asking for a CPU to be shutdown - + * waits until shutdown has completed, or it is timed out. + */ +void __cpu_die(unsigned int cpu) +{ + if (!wait_for_completion_timeout(&cpu_died, msecs_to_jiffies(5000))) { + pr_crit("CPU%u: cpu didn't die\n", cpu); + return; } + pr_notice("CPU%u: shutdown\n", cpu); +} + +/* + * Called from the idle thread for the CPU which has been shutdown. + * + * Note that we disable IRQs here, but do not re-enable them + * before returning to the caller. This is also the behaviour + * of the other hotplug-cpu capable cores, so presumably coming + * out of idle fixes this. + */ +void cpu_die(void) +{ + unsigned int cpu = smp_processor_id(); + + idle_task_exit(); - return NULL; + local_irq_disable(); + + /* Tell __cpu_die() that this CPU is now safe to dispose of */ + complete(&cpu_died); + + /* + * Actually shutdown the CPU. This must never fail. The specific hotplug + * mechanism must perform all required cache maintenance to ensure that + * no dirty lines are lost in the process of shutting down the CPU. + */ + cpu_ops[cpu]->cpu_die(cpu); + + BUG(); +} +#endif + +void __init smp_cpus_done(unsigned int max_cpus) +{ + pr_info("SMP: Total of %d processors activated.\n", num_online_cpus()); } +void __init smp_prepare_boot_cpu(void) +{ +} + +static void (*smp_cross_call)(const struct cpumask *, unsigned int); + /* * Enumerate the possible CPU set from the device tree and build the * cpu logical map array containing MPIDR values related to logical @@ -261,9 +281,8 @@ static const struct smp_enable_ops * __init smp_get_enable_ops(const char *name) */ void __init smp_init_cpus(void) { - const char *enable_method; struct device_node *dn = NULL; - int i, cpu = 1; + unsigned int i, cpu = 1; bool bootcpu_valid = false; while ((dn = of_find_node_by_type(dn, "cpu"))) { @@ -332,25 +351,10 @@ void __init smp_init_cpus(void) if (cpu >= NR_CPUS) goto next; - /* - * We currently support only the "spin-table" enable-method. - */ - enable_method = of_get_property(dn, "enable-method", NULL); - if (!enable_method) { - pr_err("%s: missing enable-method property\n", - dn->full_name); + if (cpu_read_ops(dn, cpu) != 0) goto next; - } - - smp_enable_ops[cpu] = smp_get_enable_ops(enable_method); - - if (!smp_enable_ops[cpu]) { - pr_err("%s: invalid enable-method property: %s\n", - dn->full_name, enable_method); - goto next; - } - if (smp_enable_ops[cpu]->init_cpu(dn, cpu)) + if (cpu_ops[cpu]->cpu_init(dn, cpu)) goto next; pr_debug("cpu logical map 0x%llx\n", hwid); @@ -380,8 +384,8 @@ next: void __init smp_prepare_cpus(unsigned int max_cpus) { - int cpu, err; - unsigned int ncores = num_possible_cpus(); + int err; + unsigned int cpu, ncores = num_possible_cpus(); /* * are we trying to boot more cores than exist? @@ -408,10 +412,10 @@ void __init smp_prepare_cpus(unsigned int max_cpus) if (cpu == smp_processor_id()) continue; - if (!smp_enable_ops[cpu]) + if (!cpu_ops[cpu]) continue; - err = smp_enable_ops[cpu]->prepare_cpu(cpu); + err = cpu_ops[cpu]->cpu_prepare(cpu); if (err) continue; @@ -451,7 +455,7 @@ void show_ipi_list(struct seq_file *p, int prec) for (i = 0; i < NR_IPI; i++) { seq_printf(p, "%*s%u:%s", prec - 1, "IPI", i + IPI_RESCHEDULE, prec >= 4 ? " " : ""); - for_each_present_cpu(cpu) + for_each_online_cpu(cpu) seq_printf(p, "%10u ", __get_irq_stat(cpu, ipi_irqs[i])); seq_printf(p, " %s\n", ipi_types[i]); diff --git a/arch/arm64/kernel/smp_psci.c b/arch/arm64/kernel/smp_psci.c deleted file mode 100644 index 0c533301be77..000000000000 --- a/arch/arm64/kernel/smp_psci.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * PSCI SMP initialisation - * - * Copyright (C) 2013 ARM Ltd. - * - * 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. - * - * This program is distributed in the hope that 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/>. - */ - -#include <linux/init.h> -#include <linux/of.h> -#include <linux/smp.h> - -#include <asm/psci.h> -#include <asm/smp_plat.h> - -static int __init smp_psci_init_cpu(struct device_node *dn, int cpu) -{ - return 0; -} - -static int __init smp_psci_prepare_cpu(int cpu) -{ - int err; - - if (!psci_ops.cpu_on) { - pr_err("psci: no cpu_on method, not booting CPU%d\n", cpu); - return -ENODEV; - } - - err = psci_ops.cpu_on(cpu_logical_map(cpu), __pa(secondary_holding_pen)); - if (err) { - pr_err("psci: failed to boot CPU%d (%d)\n", cpu, err); - return err; - } - - return 0; -} - -const struct smp_enable_ops smp_psci_ops __initconst = { - .name = "psci", - .init_cpu = smp_psci_init_cpu, - .prepare_cpu = smp_psci_prepare_cpu, -}; diff --git a/arch/arm64/kernel/smp_spin_table.c b/arch/arm64/kernel/smp_spin_table.c index 7c35fa682f76..44c22805d2e2 100644 --- a/arch/arm64/kernel/smp_spin_table.c +++ b/arch/arm64/kernel/smp_spin_table.c @@ -16,15 +16,39 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <linux/delay.h> #include <linux/init.h> #include <linux/of.h> #include <linux/smp.h> #include <asm/cacheflush.h> +#include <asm/cpu_ops.h> +#include <asm/cputype.h> +#include <asm/smp_plat.h> + +extern void secondary_holding_pen(void); +volatile unsigned long secondary_holding_pen_release = INVALID_HWID; static phys_addr_t cpu_release_addr[NR_CPUS]; +static DEFINE_RAW_SPINLOCK(boot_lock); + +/* + * Write secondary_holding_pen_release in a way that is guaranteed to be + * visible to all observers, irrespective of whether they're taking part + * in coherency or not. This is necessary for the hotplug code to work + * reliably. + */ +static void write_pen_release(u64 val) +{ + void *start = (void *)&secondary_holding_pen_release; + unsigned long size = sizeof(secondary_holding_pen_release); -static int __init smp_spin_table_init_cpu(struct device_node *dn, int cpu) + secondary_holding_pen_release = val; + __flush_dcache_area(start, size); +} + + +static int smp_spin_table_cpu_init(struct device_node *dn, unsigned int cpu) { /* * Determine the address from which the CPU is polling. @@ -40,7 +64,7 @@ static int __init smp_spin_table_init_cpu(struct device_node *dn, int cpu) return 0; } -static int __init smp_spin_table_prepare_cpu(int cpu) +static int smp_spin_table_cpu_prepare(unsigned int cpu) { void **release_addr; @@ -48,7 +72,16 @@ static int __init smp_spin_table_prepare_cpu(int cpu) return -ENODEV; release_addr = __va(cpu_release_addr[cpu]); - release_addr[0] = (void *)__pa(secondary_holding_pen); + + /* + * We write the release address as LE regardless of the native + * endianess of the kernel. Therefore, any boot-loaders that + * read this address need to convert this address to the + * boot-loader's endianess before jumping. This is mandated by + * the boot protocol. + */ + release_addr[0] = (void *) cpu_to_le64(__pa(secondary_holding_pen)); + __flush_dcache_area(release_addr, sizeof(release_addr[0])); /* @@ -59,8 +92,60 @@ static int __init smp_spin_table_prepare_cpu(int cpu) return 0; } -const struct smp_enable_ops smp_spin_table_ops __initconst = { +static int smp_spin_table_cpu_boot(unsigned int cpu) +{ + unsigned long timeout; + + /* + * Set synchronisation state between this boot processor + * and the secondary one + */ + raw_spin_lock(&boot_lock); + + /* + * Update the pen release flag. + */ + write_pen_release(cpu_logical_map(cpu)); + + /* + * Send an event, causing the secondaries to read pen_release. + */ + sev(); + + timeout = jiffies + (1 * HZ); + while (time_before(jiffies, timeout)) { + if (secondary_holding_pen_release == INVALID_HWID) + break; + udelay(10); + } + + /* + * Now the secondary core is starting up let it run its + * calibrations, then wait for it to finish + */ + raw_spin_unlock(&boot_lock); + + return secondary_holding_pen_release != INVALID_HWID ? -ENOSYS : 0; +} + +void smp_spin_table_cpu_postboot(void) +{ + /* + * Let the primary processor know we're out of the pen. + */ + write_pen_release(INVALID_HWID); + + /* + * Synchronise with the boot thread. + */ + raw_spin_lock(&boot_lock); + raw_spin_unlock(&boot_lock); +} + +const struct cpu_operations smp_spin_table_ops = { .name = "spin-table", - .init_cpu = smp_spin_table_init_cpu, - .prepare_cpu = smp_spin_table_prepare_cpu, + .cpu_init = smp_spin_table_cpu_init, + .cpu_prepare = smp_spin_table_cpu_prepare, + .cpu_boot = smp_spin_table_cpu_boot, + .cpu_postboot = smp_spin_table_cpu_postboot, }; diff --git a/arch/arm64/kernel/sys32.S b/arch/arm64/kernel/sys32.S index a1b19ed7467c..423a5b3fc2be 100644 --- a/arch/arm64/kernel/sys32.S +++ b/arch/arm64/kernel/sys32.S @@ -59,48 +59,48 @@ ENDPROC(compat_sys_fstatfs64_wrapper) * extension. */ compat_sys_pread64_wrapper: - orr x3, x4, x5, lsl #32 + regs_to_64 x3, x4, x5 b sys_pread64 ENDPROC(compat_sys_pread64_wrapper) compat_sys_pwrite64_wrapper: - orr x3, x4, x5, lsl #32 + regs_to_64 x3, x4, x5 b sys_pwrite64 ENDPROC(compat_sys_pwrite64_wrapper) compat_sys_truncate64_wrapper: - orr x1, x2, x3, lsl #32 + regs_to_64 x1, x2, x3 b sys_truncate ENDPROC(compat_sys_truncate64_wrapper) compat_sys_ftruncate64_wrapper: - orr x1, x2, x3, lsl #32 + regs_to_64 x1, x2, x3 b sys_ftruncate ENDPROC(compat_sys_ftruncate64_wrapper) compat_sys_readahead_wrapper: - orr x1, x2, x3, lsl #32 + regs_to_64 x1, x2, x3 mov w2, w4 b sys_readahead ENDPROC(compat_sys_readahead_wrapper) compat_sys_fadvise64_64_wrapper: mov w6, w1 - orr x1, x2, x3, lsl #32 - orr x2, x4, x5, lsl #32 + regs_to_64 x1, x2, x3 + regs_to_64 x2, x4, x5 mov w3, w6 b sys_fadvise64_64 ENDPROC(compat_sys_fadvise64_64_wrapper) compat_sys_sync_file_range2_wrapper: - orr x2, x2, x3, lsl #32 - orr x3, x4, x5, lsl #32 + regs_to_64 x2, x2, x3 + regs_to_64 x3, x4, x5 b sys_sync_file_range2 ENDPROC(compat_sys_sync_file_range2_wrapper) compat_sys_fallocate_wrapper: - orr x2, x2, x3, lsl #32 - orr x3, x4, x5, lsl #32 + regs_to_64 x2, x2, x3 + regs_to_64 x3, x4, x5 b sys_fallocate ENDPROC(compat_sys_fallocate_wrapper) diff --git a/arch/arm64/kernel/time.c b/arch/arm64/kernel/time.c index 03dc3718eb13..29c39d5d77e3 100644 --- a/arch/arm64/kernel/time.c +++ b/arch/arm64/kernel/time.c @@ -61,13 +61,6 @@ unsigned long profile_pc(struct pt_regs *regs) EXPORT_SYMBOL(profile_pc); #endif -static u64 sched_clock_mult __read_mostly; - -unsigned long long notrace sched_clock(void) -{ - return arch_timer_read_counter() * sched_clock_mult; -} - void __init time_init(void) { u32 arch_timer_rate; @@ -78,9 +71,6 @@ void __init time_init(void) if (!arch_timer_rate) panic("Unable to initialise architected timer.\n"); - /* Cache the sched_clock multiplier to save a divide in the hot path. */ - sched_clock_mult = NSEC_PER_SEC / arch_timer_rate; - /* Calibrate the delay loop directly */ lpj_fine = arch_timer_rate / HZ; } diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c index 6a389dc1bd49..65d40cf6945a 100644 --- a/arch/arm64/kernel/vdso.c +++ b/arch/arm64/kernel/vdso.c @@ -58,7 +58,10 @@ static struct page *vectors_page[1]; static int alloc_vectors_page(void) { extern char __kuser_helper_start[], __kuser_helper_end[]; + extern char __aarch32_sigret_code_start[], __aarch32_sigret_code_end[]; + int kuser_sz = __kuser_helper_end - __kuser_helper_start; + int sigret_sz = __aarch32_sigret_code_end - __aarch32_sigret_code_start; unsigned long vpage; vpage = get_zeroed_page(GFP_ATOMIC); @@ -72,7 +75,7 @@ static int alloc_vectors_page(void) /* sigreturn code */ memcpy((void *)vpage + AARCH32_KERN_SIGRET_CODE_OFFSET, - aarch32_sigret_code, sizeof(aarch32_sigret_code)); + __aarch32_sigret_code_start, sigret_sz); flush_icache_range(vpage, vpage + PAGE_SIZE); vectors_page[0] = virt_to_page(vpage); diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S index f8ab9d8e2ea3..5161ad992091 100644 --- a/arch/arm64/kernel/vmlinux.lds.S +++ b/arch/arm64/kernel/vmlinux.lds.S @@ -54,7 +54,6 @@ SECTIONS } .text : { /* Real text segment */ _stext = .; /* Text and read-only data */ - *(.smp.pen.text) __exception_text_start = .; *(.exception.text) __exception_text_end = .; @@ -97,30 +96,13 @@ SECTIONS PERCPU_SECTION(64) __init_end = .; - . = ALIGN(THREAD_SIZE); - __data_loc = .; - - .data : AT(__data_loc) { - _data = .; /* address in memory */ - _sdata = .; - - /* - * first, the init task union, aligned - * to an 8192 byte boundary. - */ - INIT_TASK_DATA(THREAD_SIZE) - NOSAVE_DATA - CACHELINE_ALIGNED_DATA(64) - READ_MOSTLY_DATA(64) - - /* - * and the usual data section - */ - DATA_DATA - CONSTRUCTORS - - _edata = .; - } + + . = ALIGN(PAGE_SIZE); + _data = .; + __data_loc = _data - LOAD_OFFSET; + _sdata = .; + RW_DATA_SECTION(64, PAGE_SIZE, THREAD_SIZE) + _edata = .; _edata_loc = __data_loc + SIZEOF(.data); BSS_SECTION(0, 0, 0) diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig index 21e90820bd23..4480ab339a00 100644 --- a/arch/arm64/kvm/Kconfig +++ b/arch/arm64/kvm/Kconfig @@ -21,6 +21,7 @@ config KVM select MMU_NOTIFIER select PREEMPT_NOTIFIERS select ANON_INODES + select HAVE_KVM_CPU_RELAX_INTERCEPT select KVM_MMIO select KVM_ARM_HOST select KVM_ARM_VGIC diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c index 2c3ff67a8ecb..3f0731e53274 100644 --- a/arch/arm64/kvm/guest.c +++ b/arch/arm64/kvm/guest.c @@ -248,6 +248,26 @@ int kvm_vcpu_set_target(struct kvm_vcpu *vcpu, return kvm_reset_vcpu(vcpu); } +int kvm_vcpu_preferred_target(struct kvm_vcpu_init *init) +{ + int target = kvm_target_cpu(); + + if (target < 0) + return -ENODEV; + + memset(init, 0, sizeof(*init)); + + /* + * For now, we don't return any features. + * In future, we might use features to return target + * specific features available for the preferred + * target type. + */ + init->target = (__u32)target; + + return 0; +} + int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) { return -EINVAL; diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c index 9beaca033437..8da56067c304 100644 --- a/arch/arm64/kvm/handle_exit.c +++ b/arch/arm64/kvm/handle_exit.c @@ -47,21 +47,29 @@ static int handle_smc(struct kvm_vcpu *vcpu, struct kvm_run *run) } /** - * kvm_handle_wfi - handle a wait-for-interrupts instruction executed by a guest + * kvm_handle_wfx - handle a wait-for-interrupts or wait-for-event + * instruction executed by a guest + * * @vcpu: the vcpu pointer * - * Simply call kvm_vcpu_block(), which will halt execution of + * WFE: Yield the CPU and come back to this vcpu when the scheduler + * decides to. + * WFI: Simply call kvm_vcpu_block(), which will halt execution of * world-switches and schedule other host processes until there is an * incoming IRQ or FIQ to the VM. */ -static int kvm_handle_wfi(struct kvm_vcpu *vcpu, struct kvm_run *run) +static int kvm_handle_wfx(struct kvm_vcpu *vcpu, struct kvm_run *run) { - kvm_vcpu_block(vcpu); + if (kvm_vcpu_get_hsr(vcpu) & ESR_EL2_EC_WFI_ISS_WFE) + kvm_vcpu_on_spin(vcpu); + else + kvm_vcpu_block(vcpu); + return 1; } static exit_handle_fn arm_exit_handlers[] = { - [ESR_EL2_EC_WFI] = kvm_handle_wfi, + [ESR_EL2_EC_WFI] = kvm_handle_wfx, [ESR_EL2_EC_CP15_32] = kvm_handle_cp15_32, [ESR_EL2_EC_CP15_64] = kvm_handle_cp15_64, [ESR_EL2_EC_CP14_MR] = kvm_handle_cp14_access, diff --git a/arch/arm64/kvm/hyp-init.S b/arch/arm64/kvm/hyp-init.S index ba84e6705e20..2b0244d65c16 100644 --- a/arch/arm64/kvm/hyp-init.S +++ b/arch/arm64/kvm/hyp-init.S @@ -74,7 +74,10 @@ __do_hyp_init: msr mair_el2, x4 isb - mov x4, #SCTLR_EL2_FLAGS + mrs x4, sctlr_el2 + and x4, x4, #SCTLR_EL2_EE // preserve endianness of EL2 + ldr x5, =SCTLR_EL2_FLAGS + orr x4, x4, x5 msr sctlr_el2, x4 isb diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S index 1ac0bbbdddb2..3b47c36e10ff 100644 --- a/arch/arm64/kvm/hyp.S +++ b/arch/arm64/kvm/hyp.S @@ -403,6 +403,14 @@ __kvm_hyp_code_start: ldr w9, [x2, #GICH_ELRSR0] ldr w10, [x2, #GICH_ELRSR1] ldr w11, [x2, #GICH_APR] +CPU_BE( rev w4, w4 ) +CPU_BE( rev w5, w5 ) +CPU_BE( rev w6, w6 ) +CPU_BE( rev w7, w7 ) +CPU_BE( rev w8, w8 ) +CPU_BE( rev w9, w9 ) +CPU_BE( rev w10, w10 ) +CPU_BE( rev w11, w11 ) str w4, [x3, #VGIC_CPU_HCR] str w5, [x3, #VGIC_CPU_VMCR] @@ -421,6 +429,7 @@ __kvm_hyp_code_start: ldr w4, [x3, #VGIC_CPU_NR_LR] add x3, x3, #VGIC_CPU_LR 1: ldr w5, [x2], #4 +CPU_BE( rev w5, w5 ) str w5, [x3], #4 sub w4, w4, #1 cbnz w4, 1b @@ -446,6 +455,9 @@ __kvm_hyp_code_start: ldr w4, [x3, #VGIC_CPU_HCR] ldr w5, [x3, #VGIC_CPU_VMCR] ldr w6, [x3, #VGIC_CPU_APR] +CPU_BE( rev w4, w4 ) +CPU_BE( rev w5, w5 ) +CPU_BE( rev w6, w6 ) str w4, [x2, #GICH_HCR] str w5, [x2, #GICH_VMCR] @@ -456,6 +468,7 @@ __kvm_hyp_code_start: ldr w4, [x3, #VGIC_CPU_NR_LR] add x3, x3, #VGIC_CPU_LR 1: ldr w5, [x3], #4 +CPU_BE( rev w5, w5 ) str w5, [x2], #4 sub w4, w4, #1 cbnz w4, 1b diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index de2de5db628d..0cb8742de4f2 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c @@ -31,7 +31,6 @@ #include <linux/sort.h> #include <linux/of_fdt.h> -#include <asm/prom.h> #include <asm/sections.h> #include <asm/setup.h> #include <asm/sizes.h> @@ -39,17 +38,9 @@ #include "mm.h" -static unsigned long phys_initrd_start __initdata = 0; -static unsigned long phys_initrd_size __initdata = 0; - phys_addr_t memstart_addr __read_mostly = 0; -void __init early_init_dt_setup_initrd_arch(u64 start, u64 end) -{ - phys_initrd_start = start; - phys_initrd_size = end - start; -} - +#ifdef CONFIG_BLK_DEV_INITRD static int __init early_initrd(char *p) { unsigned long start, size; @@ -59,12 +50,13 @@ static int __init early_initrd(char *p) if (*endp == ',') { size = memparse(endp + 1, NULL); - phys_initrd_start = start; - phys_initrd_size = size; + initrd_start = (unsigned long)__va(start); + initrd_end = (unsigned long)__va(start + size); } return 0; } early_param("initrd", early_initrd); +#endif #define MAX_DMA32_PFN ((4UL * 1024 * 1024 * 1024) >> PAGE_SHIFT) @@ -137,13 +129,8 @@ void __init arm64_memblock_init(void) /* Register the kernel text, kernel data and initrd with memblock */ memblock_reserve(__pa(_text), _end - _text); #ifdef CONFIG_BLK_DEV_INITRD - if (phys_initrd_size) { - memblock_reserve(phys_initrd_start, phys_initrd_size); - - /* Now convert initrd to virtual addresses */ - initrd_start = __phys_to_virt(phys_initrd_start); - initrd_end = initrd_start + phys_initrd_size; - } + if (initrd_start) + memblock_reserve(__virt_to_phys(initrd_start), initrd_end - initrd_start); #endif /* diff --git a/arch/arm64/mm/ioremap.c b/arch/arm64/mm/ioremap.c index 1725cd6db37a..2bb1d586664c 100644 --- a/arch/arm64/mm/ioremap.c +++ b/arch/arm64/mm/ioremap.c @@ -77,8 +77,24 @@ EXPORT_SYMBOL(__ioremap); void __iounmap(volatile void __iomem *io_addr) { - void *addr = (void *)(PAGE_MASK & (unsigned long)io_addr); + unsigned long addr = (unsigned long)io_addr & PAGE_MASK; - vunmap(addr); + /* + * We could get an address outside vmalloc range in case + * of ioremap_cache() reusing a RAM mapping. + */ + if (VMALLOC_START <= addr && addr < VMALLOC_END) + vunmap((void *)addr); } EXPORT_SYMBOL(__iounmap); + +void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size) +{ + /* For normal memory we already have a cacheable mapping. */ + if (pfn_valid(__phys_to_pfn(phys_addr))) + return (void __iomem *)__phys_to_virt(phys_addr); + + return __ioremap_caller(phys_addr, size, __pgprot(PROT_NORMAL), + __builtin_return_address(0)); +} +EXPORT_SYMBOL(ioremap_cache); diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S index b1b31bbc967b..421b99fd635d 100644 --- a/arch/arm64/mm/proc.S +++ b/arch/arm64/mm/proc.S @@ -162,9 +162,9 @@ ENDPROC(__cpu_setup) * CE0 XWHW CZ ME TEEA S * .... .IEE .... NEAI TE.I ..AD DEN0 ACAM * 0011 0... 1101 ..0. ..0. 10.. .... .... < hardware reserved - * .... .100 .... 01.1 11.1 ..01 0001 1101 < software settings + * .... .1.. .... 01.1 11.1 ..01 0001 1101 < software settings */ .type crval, #object crval: - .word 0x030802e2 // clear + .word 0x000802e2 // clear .word 0x0405d11d // set diff --git a/arch/arm64/xen/Makefile b/arch/arm64/xen/Makefile index be240404ba96..74a8d87e542b 100644 --- a/arch/arm64/xen/Makefile +++ b/arch/arm64/xen/Makefile @@ -1,2 +1,2 @@ -xen-arm-y += $(addprefix ../../arm/xen/, enlighten.o grant-table.o) +xen-arm-y += $(addprefix ../../arm/xen/, enlighten.o grant-table.o p2m.o mm.o) obj-y := xen-arm.o hypercall.o diff --git a/arch/avr32/boards/atngw100/evklcd10x.c b/arch/avr32/boards/atngw100/evklcd10x.c index 20388750d564..64919b0da7aa 100644 --- a/arch/avr32/boards/atngw100/evklcd10x.c +++ b/arch/avr32/boards/atngw100/evklcd10x.c @@ -58,7 +58,7 @@ static struct fb_monspecs __initdata atevklcd10x_default_monspecs = { .dclkmax = 28330000, }; -static struct atmel_lcdfb_info __initdata atevklcd10x_lcdc_data = { +static struct atmel_lcdfb_pdata __initdata atevklcd10x_lcdc_data = { .default_bpp = 16, .default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN, .default_lcdcon2 = (ATMEL_LCDC_DISTYPE_TFT @@ -96,7 +96,7 @@ static struct fb_monspecs __initdata atevklcd10x_default_monspecs = { .dclkmax = 7000000, }; -static struct atmel_lcdfb_info __initdata atevklcd10x_lcdc_data = { +static struct atmel_lcdfb_pdata __initdata atevklcd10x_lcdc_data = { .default_bpp = 16, .default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN, .default_lcdcon2 = (ATMEL_LCDC_DISTYPE_TFT @@ -134,7 +134,7 @@ static struct fb_monspecs __initdata atevklcd10x_default_monspecs = { .dclkmax = 6400000, }; -static struct atmel_lcdfb_info __initdata atevklcd10x_lcdc_data = { +static struct atmel_lcdfb_pdata __initdata atevklcd10x_lcdc_data = { .default_bpp = 16, .default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN, .default_lcdcon2 = (ATMEL_LCDC_DISTYPE_TFT @@ -145,7 +145,7 @@ static struct atmel_lcdfb_info __initdata atevklcd10x_lcdc_data = { }; #endif -static void atevklcd10x_lcdc_power_control(int on) +static void atevklcd10x_lcdc_power_control(struct atmel_lcdfb_pdata *pdata, int on) { gpio_set_value(GPIO_PIN_PB(15), on); } diff --git a/arch/avr32/boards/atngw100/mrmt.c b/arch/avr32/boards/atngw100/mrmt.c index 7de083d19b7e..1ba09e4c02b1 100644 --- a/arch/avr32/boards/atngw100/mrmt.c +++ b/arch/avr32/boards/atngw100/mrmt.c @@ -83,7 +83,7 @@ static struct fb_monspecs __initdata lcd_fb_default_monspecs = { .dclkmax = 9260000, }; -static struct atmel_lcdfb_info __initdata rmt_lcdc_data = { +static struct atmel_lcdfb_pdata __initdata rmt_lcdc_data = { .default_bpp = 24, .default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN, .default_lcdcon2 = (ATMEL_LCDC_DISTYPE_TFT @@ -126,7 +126,7 @@ static struct fb_monspecs __initdata lcd_fb_default_monspecs = { .dclkmax = 9260000, }; -static struct atmel_lcdfb_info __initdata rmt_lcdc_data = { +static struct atmel_lcdfb_pdata __initdata rmt_lcdc_data = { .default_bpp = 24, .default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN, .default_lcdcon2 = (ATMEL_LCDC_DISTYPE_TFT diff --git a/arch/avr32/boards/atstk1000/atstk1000.h b/arch/avr32/boards/atstk1000/atstk1000.h index 9392d3252865..653cc09e536c 100644 --- a/arch/avr32/boards/atstk1000/atstk1000.h +++ b/arch/avr32/boards/atstk1000/atstk1000.h @@ -10,7 +10,7 @@ #ifndef __ARCH_AVR32_BOARDS_ATSTK1000_ATSTK1000_H #define __ARCH_AVR32_BOARDS_ATSTK1000_ATSTK1000_H -extern struct atmel_lcdfb_info atstk1000_lcdc_data; +extern struct atmel_lcdfb_pdata atstk1000_lcdc_data; void atstk1000_setup_j2_leds(void); diff --git a/arch/avr32/boards/atstk1000/setup.c b/arch/avr32/boards/atstk1000/setup.c index 2d6b560115d9..b6b88f5e0b43 100644 --- a/arch/avr32/boards/atstk1000/setup.c +++ b/arch/avr32/boards/atstk1000/setup.c @@ -55,7 +55,7 @@ static struct fb_monspecs __initdata atstk1000_default_monspecs = { .dclkmax = 30000000, }; -struct atmel_lcdfb_info __initdata atstk1000_lcdc_data = { +struct atmel_lcdfb_pdata __initdata atstk1000_lcdc_data = { .default_bpp = 24, .default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN, .default_lcdcon2 = (ATMEL_LCDC_DISTYPE_TFT diff --git a/arch/avr32/boards/favr-32/setup.c b/arch/avr32/boards/favr-32/setup.c index 27bd6fbe21cb..7b1f2cd85400 100644 --- a/arch/avr32/boards/favr-32/setup.c +++ b/arch/avr32/boards/favr-32/setup.c @@ -125,7 +125,7 @@ static struct fb_monspecs __initdata favr32_default_monspecs = { .dclkmax = 28000000, }; -struct atmel_lcdfb_info __initdata favr32_lcdc_data = { +struct atmel_lcdfb_pdata __initdata favr32_lcdc_data = { .default_bpp = 16, .default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN, .default_lcdcon2 = (ATMEL_LCDC_DISTYPE_TFT diff --git a/arch/avr32/boards/hammerhead/setup.c b/arch/avr32/boards/hammerhead/setup.c index 9d1efd1cd425..dc0e317f2ecd 100644 --- a/arch/avr32/boards/hammerhead/setup.c +++ b/arch/avr32/boards/hammerhead/setup.c @@ -77,7 +77,7 @@ static struct fb_monspecs __initdata hammerhead_hda350t_monspecs = { .dclkmax = 10000000, }; -struct atmel_lcdfb_info __initdata hammerhead_lcdc_data = { +struct atmel_lcdfb_pdata __initdata hammerhead_lcdc_data = { .default_bpp = 24, .default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN, .default_lcdcon2 = (ATMEL_LCDC_DISTYPE_TFT diff --git a/arch/avr32/boards/merisc/display.c b/arch/avr32/boards/merisc/display.c index 85a543cd4abc..e7683ee7ed40 100644 --- a/arch/avr32/boards/merisc/display.c +++ b/arch/avr32/boards/merisc/display.c @@ -45,7 +45,7 @@ static struct fb_monspecs merisc_fb_monspecs = { .dclkmax = 30000000, }; -struct atmel_lcdfb_info merisc_lcdc_data = { +struct atmel_lcdfb_pdata merisc_lcdc_data = { .default_bpp = 24, .default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN, .default_lcdcon2 = (ATMEL_LCDC_DISTYPE_TFT diff --git a/arch/avr32/boards/mimc200/setup.c b/arch/avr32/boards/mimc200/setup.c index 05358aa5ef7d..1cb8e9cc5cfa 100644 --- a/arch/avr32/boards/mimc200/setup.c +++ b/arch/avr32/boards/mimc200/setup.c @@ -8,7 +8,7 @@ * published by the Free Software Foundation. */ -extern struct atmel_lcdfb_info mimc200_lcdc_data; +extern struct atmel_lcdfb_pdata mimc200_lcdc_data; #include <linux/clk.h> #include <linux/etherdevice.h> @@ -71,7 +71,7 @@ static struct fb_monspecs __initdata mimc200_default_monspecs = { .dclkmax = 25200000, }; -struct atmel_lcdfb_info __initdata mimc200_lcdc_data = { +struct atmel_lcdfb_pdata __initdata mimc200_lcdc_data = { .default_bpp = 16, .default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN, .default_lcdcon2 = (ATMEL_LCDC_DISTYPE_TFT diff --git a/arch/avr32/include/asm/Kbuild b/arch/avr32/include/asm/Kbuild index fd7980743890..658001b52400 100644 --- a/arch/avr32/include/asm/Kbuild +++ b/arch/avr32/include/asm/Kbuild @@ -7,6 +7,7 @@ generic-y += div64.h generic-y += emergency-restart.h generic-y += exec.h generic-y += futex.h +generic-y += preempt.h generic-y += irq_regs.h generic-y += param.h generic-y += local.h diff --git a/arch/avr32/include/asm/pgalloc.h b/arch/avr32/include/asm/pgalloc.h index bc7e8ae479ee..1aba19d68c5e 100644 --- a/arch/avr32/include/asm/pgalloc.h +++ b/arch/avr32/include/asm/pgalloc.h @@ -68,7 +68,10 @@ static inline pgtable_t pte_alloc_one(struct mm_struct *mm, return NULL; page = virt_to_page(pg); - pgtable_page_ctor(page); + if (!pgtable_page_ctor(page)) { + quicklist_free(QUICK_PT, NULL, pg); + return NULL; + } return page; } diff --git a/arch/avr32/include/asm/thread_info.h b/arch/avr32/include/asm/thread_info.h index 6dc62e1f94c7..a978f3fe7c25 100644 --- a/arch/avr32/include/asm/thread_info.h +++ b/arch/avr32/include/asm/thread_info.h @@ -66,8 +66,6 @@ static inline struct thread_info *current_thread_info(void) #endif /* !__ASSEMBLY__ */ -#define PREEMPT_ACTIVE 0x40000000 - /* * Thread information flags * - these are process state flags that various assembly files may need to access diff --git a/arch/avr32/include/uapi/asm/socket.h b/arch/avr32/include/uapi/asm/socket.h index 11c4259c62fb..439936421434 100644 --- a/arch/avr32/include/uapi/asm/socket.h +++ b/arch/avr32/include/uapi/asm/socket.h @@ -76,4 +76,6 @@ #define SO_BUSY_POLL 46 +#define SO_MAX_PACING_RATE 47 + #endif /* __ASM_AVR32_SOCKET_H */ diff --git a/arch/avr32/mach-at32ap/at32ap700x.c b/arch/avr32/mach-at32ap/at32ap700x.c index a68f3cf7c3c1..a1f4d1e91b52 100644 --- a/arch/avr32/mach-at32ap/at32ap700x.c +++ b/arch/avr32/mach-at32ap/at32ap700x.c @@ -1439,7 +1439,7 @@ fail: * LCDC * -------------------------------------------------------------------- */ #if defined(CONFIG_CPU_AT32AP7000) || defined(CONFIG_CPU_AT32AP7002) -static struct atmel_lcdfb_info atmel_lcdfb0_data; +static struct atmel_lcdfb_pdata atmel_lcdfb0_data; static struct resource atmel_lcdfb0_resource[] = { { .start = 0xff000000, @@ -1467,12 +1467,12 @@ static struct clk atmel_lcdfb0_pixclk = { }; struct platform_device *__init -at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data, +at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_pdata *data, unsigned long fbmem_start, unsigned long fbmem_len, u64 pin_mask) { struct platform_device *pdev; - struct atmel_lcdfb_info *info; + struct atmel_lcdfb_pdata *info; struct fb_monspecs *monspecs; struct fb_videomode *modedb; unsigned int modedb_size; @@ -1529,7 +1529,7 @@ at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data, } info = pdev->dev.platform_data; - memcpy(info, data, sizeof(struct atmel_lcdfb_info)); + memcpy(info, data, sizeof(struct atmel_lcdfb_pdata)); info->default_monspecs = monspecs; pdev->name = "at32ap-lcdfb"; diff --git a/arch/avr32/mach-at32ap/include/mach/board.h b/arch/avr32/mach-at32ap/include/mach/board.h index d485b0391357..f1a316d52c73 100644 --- a/arch/avr32/mach-at32ap/include/mach/board.h +++ b/arch/avr32/mach-at32ap/include/mach/board.h @@ -44,9 +44,9 @@ struct platform_device * at32_add_device_spi(unsigned int id, struct spi_board_info *b, unsigned int n); void at32_spi_setup_slaves(unsigned int bus_num, struct spi_board_info *b, unsigned int n); -struct atmel_lcdfb_info; +struct atmel_lcdfb_pdata; struct platform_device * -at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data, +at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_pdata *data, unsigned long fbmem_start, unsigned long fbmem_len, u64 pin_mask); diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index f78c9a2c7e28..9ceccef9c649 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -34,7 +34,6 @@ config BLACKFIN select ARCH_WANT_IPC_PARSE_VERSION select GENERIC_ATOMIC64 select GENERIC_IRQ_PROBE - select USE_GENERIC_SMP_HELPERS if SMP select HAVE_NMI_WATCHDOG if NMI_WATCHDOG select GENERIC_SMP_IDLE_THREAD select ARCH_USES_GETTIMEOFFSET if !GENERIC_CLOCKEVENTS @@ -52,6 +51,9 @@ config GENERIC_BUG config ZONE_DMA def_bool y +config GENERIC_GPIO + def_bool y + config FORCE_MAX_ZONEORDER int default "14" @@ -317,6 +319,14 @@ config BF53x depends on (BF531 || BF532 || BF533 || BF534 || BF536 || BF537) default y +config GPIO_ADI + def_bool y + depends on (BF51x || BF52x || BF53x || BF538 || BF539 || BF561) + +config PINCTRL + def_bool y + depends on BF54x || BF60x + config MEM_MT48LC64M4A2FB_7E bool depends on (BFIN533_STAMP) @@ -1429,7 +1439,6 @@ source "drivers/cpufreq/Kconfig" config BFIN_CPU_FREQ bool depends on CPU_FREQ - select CPU_FREQ_TABLE default y config CPU_VOLTAGE diff --git a/arch/blackfin/configs/BF609-EZKIT_defconfig b/arch/blackfin/configs/BF609-EZKIT_defconfig index 13eb73231a9a..4ca39ab6b2bf 100644 --- a/arch/blackfin/configs/BF609-EZKIT_defconfig +++ b/arch/blackfin/configs/BF609-EZKIT_defconfig @@ -102,7 +102,7 @@ CONFIG_I2C_CHARDEV=y CONFIG_I2C_BLACKFIN_TWI=y CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100 CONFIG_SPI=y -CONFIG_SPI_BFIN6XX=y +CONFIG_SPI_BFIN_V3=y CONFIG_GPIOLIB=y CONFIG_GPIO_SYSFS=y # CONFIG_HWMON is not set diff --git a/arch/blackfin/include/asm/Kbuild b/arch/blackfin/include/asm/Kbuild index 127826f8a375..f2b43474b0e2 100644 --- a/arch/blackfin/include/asm/Kbuild +++ b/arch/blackfin/include/asm/Kbuild @@ -44,3 +44,4 @@ generic-y += ucontext.h generic-y += unaligned.h generic-y += user.h generic-y += xor.h +generic-y += preempt.h diff --git a/arch/blackfin/include/asm/gpio.h b/arch/blackfin/include/asm/gpio.h index 98d0133346b5..99d338ca2ea4 100644 --- a/arch/blackfin/include/asm/gpio.h +++ b/arch/blackfin/include/asm/gpio.h @@ -25,8 +25,12 @@ #ifndef __ASSEMBLY__ +#ifndef CONFIG_PINCTRL + #include <linux/compiler.h> -#include <linux/gpio.h> +#include <asm/blackfin.h> +#include <asm/portmux.h> +#include <asm/irq_handler.h> /*********************************************************** * @@ -45,7 +49,6 @@ * MODIFICATION HISTORY : **************************************************************/ -#if !BFIN_GPIO_PINT void set_gpio_dir(unsigned, unsigned short); void set_gpio_inen(unsigned, unsigned short); void set_gpio_polar(unsigned, unsigned short); @@ -115,7 +118,6 @@ struct gpio_port_t { unsigned short dummy16; unsigned short inen; }; -#endif #ifdef BFIN_SPECIAL_GPIO_BANKS void bfin_special_gpio_free(unsigned gpio); @@ -127,25 +129,21 @@ void bfin_special_gpio_pm_hibernate_suspend(void); #endif #ifdef CONFIG_PM -int bfin_pm_standby_ctrl(unsigned ctrl); +void bfin_gpio_pm_hibernate_restore(void); +void bfin_gpio_pm_hibernate_suspend(void); +int bfin_gpio_pm_wakeup_ctrl(unsigned gpio, unsigned ctrl); +int bfin_gpio_pm_standby_ctrl(unsigned ctrl); static inline int bfin_pm_standby_setup(void) { - return bfin_pm_standby_ctrl(1); + return bfin_gpio_pm_standby_ctrl(1); } static inline void bfin_pm_standby_restore(void) { - bfin_pm_standby_ctrl(0); + bfin_gpio_pm_standby_ctrl(0); } -void bfin_gpio_pm_hibernate_restore(void); -void bfin_gpio_pm_hibernate_suspend(void); -void bfin_pint_suspend(void); -void bfin_pint_resume(void); - -# if !BFIN_GPIO_PINT -int gpio_pm_wakeup_ctrl(unsigned gpio, unsigned ctrl); struct gpio_port_s { unsigned short data; @@ -161,7 +159,6 @@ struct gpio_port_s { unsigned short reserved; unsigned short mux; }; -# endif #endif /*CONFIG_PM*/ /*********************************************************** @@ -178,36 +175,29 @@ struct gpio_port_s { ************************************************************* * MODIFICATION HISTORY : **************************************************************/ - -int bfin_gpio_request(unsigned gpio, const char *label); -void bfin_gpio_free(unsigned gpio); int bfin_gpio_irq_request(unsigned gpio, const char *label); void bfin_gpio_irq_free(unsigned gpio); -int bfin_gpio_direction_input(unsigned gpio); -int bfin_gpio_direction_output(unsigned gpio, int value); -int bfin_gpio_get_value(unsigned gpio); -void bfin_gpio_set_value(unsigned gpio, int value); +void bfin_gpio_irq_prepare(unsigned gpio); + +static inline int irq_to_gpio(unsigned irq) +{ + return irq - GPIO_IRQ_BASE; +} +#endif /* CONFIG_PINCTRL */ #include <asm/irq.h> #include <asm/errno.h> -#ifdef CONFIG_GPIOLIB #include <asm-generic/gpio.h> /* cansleep wrappers */ static inline int gpio_get_value(unsigned int gpio) { - if (gpio < MAX_BLACKFIN_GPIOS) - return bfin_gpio_get_value(gpio); - else - return __gpio_get_value(gpio); + return __gpio_get_value(gpio); } static inline void gpio_set_value(unsigned int gpio, int value) { - if (gpio < MAX_BLACKFIN_GPIOS) - bfin_gpio_set_value(gpio, value); - else - __gpio_set_value(gpio, value); + __gpio_set_value(gpio, value); } static inline int gpio_cansleep(unsigned int gpio) @@ -219,113 +209,6 @@ static inline int gpio_to_irq(unsigned gpio) { return __gpio_to_irq(gpio); } - -#else /* !CONFIG_GPIOLIB */ - -static inline int gpio_request(unsigned gpio, const char *label) -{ - return bfin_gpio_request(gpio, label); -} - -static inline void gpio_free(unsigned gpio) -{ - return bfin_gpio_free(gpio); -} - -static inline int gpio_direction_input(unsigned gpio) -{ - return bfin_gpio_direction_input(gpio); -} - -static inline int gpio_direction_output(unsigned gpio, int value) -{ - return bfin_gpio_direction_output(gpio, value); -} - -static inline int gpio_set_debounce(unsigned gpio, unsigned debounce) -{ - return -EINVAL; -} - -static inline int gpio_request_one(unsigned gpio, unsigned long flags, const char *label) -{ - int err; - - err = bfin_gpio_request(gpio, label); - if (err) - return err; - - if (flags & GPIOF_DIR_IN) - err = bfin_gpio_direction_input(gpio); - else - err = bfin_gpio_direction_output(gpio, - (flags & GPIOF_INIT_HIGH) ? 1 : 0); - - if (err) - bfin_gpio_free(gpio); - - return err; -} - -static inline int gpio_request_array(const struct gpio *array, size_t num) -{ - int i, err; - - for (i = 0; i < num; i++, array++) { - err = gpio_request_one(array->gpio, array->flags, array->label); - if (err) - goto err_free; - } - return 0; - -err_free: - while (i--) - bfin_gpio_free((--array)->gpio); - return err; -} - -static inline void gpio_free_array(const struct gpio *array, size_t num) -{ - while (num--) - bfin_gpio_free((array++)->gpio); -} - -static inline int __gpio_get_value(unsigned gpio) -{ - return bfin_gpio_get_value(gpio); -} - -static inline void __gpio_set_value(unsigned gpio, int value) -{ - return bfin_gpio_set_value(gpio, value); -} - -static inline int gpio_get_value(unsigned gpio) -{ - return __gpio_get_value(gpio); -} - -static inline void gpio_set_value(unsigned gpio, int value) -{ - return __gpio_set_value(gpio, value); -} - -static inline int gpio_to_irq(unsigned gpio) -{ - if (likely(gpio < MAX_BLACKFIN_GPIOS)) - return gpio + GPIO_IRQ_BASE; - - return -EINVAL; -} - -#include <asm-generic/gpio.h> /* cansleep wrappers */ -#endif /* !CONFIG_GPIOLIB */ - -static inline int irq_to_gpio(unsigned irq) -{ - return (irq - GPIO_IRQ_BASE); -} - #endif /* __ASSEMBLY__ */ #endif /* __ARCH_BLACKFIN_GPIO_H__ */ diff --git a/arch/blackfin/include/asm/hardirq.h b/arch/blackfin/include/asm/hardirq.h index c078dd78d998..58b54a6d5a16 100644 --- a/arch/blackfin/include/asm/hardirq.h +++ b/arch/blackfin/include/asm/hardirq.h @@ -12,9 +12,6 @@ extern void ack_bad_irq(unsigned int irq); #define ack_bad_irq ack_bad_irq -/* Define until common code gets sane defaults */ -#define HARDIRQ_BITS 9 - #include <asm-generic/hardirq.h> #endif diff --git a/arch/blackfin/include/asm/irq.h b/arch/blackfin/include/asm/irq.h index 4ae1144a4578..2fd04f10cc26 100644 --- a/arch/blackfin/include/asm/irq.h +++ b/arch/blackfin/include/asm/irq.h @@ -23,8 +23,7 @@ /* * pm save bfin pint registers */ -struct bfin_pm_pint_save { - u32 mask_set; +struct adi_pm_pint_save { u32 assign; u32 edge_set; u32 invert_set; diff --git a/arch/blackfin/include/asm/irq_handler.h b/arch/blackfin/include/asm/irq_handler.h index 4fbf83575db1..4b2a992794d7 100644 --- a/arch/blackfin/include/asm/irq_handler.h +++ b/arch/blackfin/include/asm/irq_handler.h @@ -12,11 +12,11 @@ #include <mach/irq.h> /* init functions only */ -extern int __init init_arch_irq(void); +extern int init_arch_irq(void); extern void init_exception_vectors(void); -extern void __init program_IAR(void); +extern void program_IAR(void); #ifdef init_mach_irq -extern void __init init_mach_irq(void); +extern void init_mach_irq(void); #else # define init_mach_irq() #endif diff --git a/arch/blackfin/include/asm/portmux.h b/arch/blackfin/include/asm/portmux.h index 9b1e2c37b324..7aa20436e799 100644 --- a/arch/blackfin/include/asm/portmux.h +++ b/arch/blackfin/include/asm/portmux.h @@ -17,14 +17,29 @@ #define P_MAYSHARE 0x2000 #define P_DONTCARE 0x1000 - +#ifdef CONFIG_PINCTRL +#include <asm/irq_handler.h> + +#define gpio_pint_regs bfin_pint_regs +#define adi_internal_set_wake bfin_internal_set_wake + +#define peripheral_request(per, label) 0 +#define peripheral_free(per) +#define peripheral_request_list(per, label) \ + (pdev ? (IS_ERR(devm_pinctrl_get_select_default(&pdev->dev)) \ + ? -EINVAL : 0) : 0) +#define peripheral_free_list(per) +#else int peripheral_request(unsigned short per, const char *label); void peripheral_free(unsigned short per); int peripheral_request_list(const unsigned short per[], const char *label); void peripheral_free_list(const unsigned short per[]); +#endif -#include <asm/gpio.h> +#include <linux/err.h> +#include <linux/pinctrl/pinctrl.h> #include <mach/portmux.h> +#include <linux/gpio.h> #ifndef P_SPORT2_TFS #define P_SPORT2_TFS P_UNDEF diff --git a/arch/blackfin/include/asm/thread_info.h b/arch/blackfin/include/asm/thread_info.h index 3894005337ba..55f473bdad36 100644 --- a/arch/blackfin/include/asm/thread_info.h +++ b/arch/blackfin/include/asm/thread_info.h @@ -88,8 +88,6 @@ static inline struct thread_info *current_thread_info(void) #define TI_CPU 12 #define TI_PREEMPT 16 -#define PREEMPT_ACTIVE 0x4000000 - /* * thread information flag bit numbers */ diff --git a/arch/blackfin/kernel/Makefile b/arch/blackfin/kernel/Makefile index 735f24e07425..703dc7cf2ecc 100644 --- a/arch/blackfin/kernel/Makefile +++ b/arch/blackfin/kernel/Makefile @@ -7,7 +7,7 @@ extra-y := vmlinux.lds obj-y := \ entry.o process.o bfin_ksyms.o ptrace.o setup.o signal.o \ sys_bfin.o traps.o irqchip.o dma-mapping.o flat.o \ - fixed_code.o reboot.o bfin_gpio.o bfin_dma.o \ + fixed_code.o reboot.o bfin_dma.o \ exception.o dumpstack.o ifeq ($(CONFIG_GENERIC_CLOCKEVENTS),y) @@ -16,6 +16,7 @@ else obj-y += time.o endif +obj-$(CONFIG_GPIO_ADI) += bfin_gpio.o obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o obj-$(CONFIG_FUNCTION_TRACER) += ftrace-entry.o obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c index ed978f1c5cb9..a017359c1826 100644 --- a/arch/blackfin/kernel/bfin_gpio.c +++ b/arch/blackfin/kernel/bfin_gpio.c @@ -11,11 +11,8 @@ #include <linux/err.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> -#include <asm/blackfin.h> -#include <asm/gpio.h> -#include <asm/portmux.h> +#include <linux/gpio.h> #include <linux/irq.h> -#include <asm/irq_handler.h> #if ANOMALY_05000311 || ANOMALY_05000323 enum { @@ -58,19 +55,6 @@ static struct gpio_port_t * const gpio_array[] = { (struct gpio_port_t *) FIO0_FLAG_D, (struct gpio_port_t *) FIO1_FLAG_D, (struct gpio_port_t *) FIO2_FLAG_D, -#elif defined(CONFIG_BF54x) || defined(CONFIG_BF60x) - (struct gpio_port_t *)PORTA_FER, - (struct gpio_port_t *)PORTB_FER, - (struct gpio_port_t *)PORTC_FER, - (struct gpio_port_t *)PORTD_FER, - (struct gpio_port_t *)PORTE_FER, - (struct gpio_port_t *)PORTF_FER, - (struct gpio_port_t *)PORTG_FER, -# if defined(CONFIG_BF54x) - (struct gpio_port_t *)PORTH_FER, - (struct gpio_port_t *)PORTI_FER, - (struct gpio_port_t *)PORTJ_FER, -# endif #else # error no gpio arrays defined #endif @@ -169,12 +153,6 @@ DECLARE_RESERVED_MAP(gpio_irq, GPIO_BANK_NUM); inline int check_gpio(unsigned gpio) { -#if defined(CONFIG_BF54x) - if (gpio == GPIO_PB15 || gpio == GPIO_PC14 || gpio == GPIO_PC15 - || gpio == GPIO_PH14 || gpio == GPIO_PH15 - || gpio == GPIO_PJ14 || gpio == GPIO_PJ15) - return -EINVAL; -#endif if (gpio >= MAX_BLACKFIN_GPIOS) return -EINVAL; return 0; @@ -212,12 +190,6 @@ static void port_setup(unsigned gpio, unsigned short usage) else *port_fer[gpio_bank(gpio)] |= gpio_bit(gpio); SSYNC(); -#elif defined(CONFIG_BF54x) || defined(CONFIG_BF60x) - if (usage == GPIO_USAGE) - gpio_array[gpio_bank(gpio)]->port_fer &= ~gpio_bit(gpio); - else - gpio_array[gpio_bank(gpio)]->port_fer |= gpio_bit(gpio); - SSYNC(); #endif } @@ -255,7 +227,7 @@ static int portmux_group_check(unsigned short per) u16 ident = P_IDENT(per); u16 function = P_FUNCT2MUX(per); s8 offset = port_mux[ident]; - u16 m, pmux, pfunc; + u16 m, pmux, pfunc, mask; if (offset < 0) return 0; @@ -270,10 +242,12 @@ static int portmux_group_check(unsigned short per) continue; if (offset == 1) - pfunc = (pmux >> offset) & 3; + mask = 3; else - pfunc = (pmux >> offset) & 1; - if (pfunc != function) { + mask = 1; + + pfunc = (pmux >> offset) & mask; + if (pfunc != (function & mask)) { pr_err("pin group conflict! request pin %d func %d conflict with pin %d func %d\n", ident, function, m, pfunc); return -EINVAL; @@ -288,43 +262,21 @@ static void portmux_setup(unsigned short per) u16 ident = P_IDENT(per); u16 function = P_FUNCT2MUX(per); s8 offset = port_mux[ident]; - u16 pmux; + u16 pmux, mask; if (offset == -1) return; pmux = bfin_read_PORT_MUX(); - if (offset != 1) - pmux &= ~(1 << offset); + if (offset == 1) + mask = 3; else - pmux &= ~(3 << 1); - pmux |= (function << offset); - bfin_write_PORT_MUX(pmux); -} -#elif defined(CONFIG_BF54x) || defined(CONFIG_BF60x) -inline void portmux_setup(unsigned short per) -{ - u16 ident = P_IDENT(per); - u16 function = P_FUNCT2MUX(per); - u32 pmux; + mask = 1; - pmux = gpio_array[gpio_bank(ident)]->port_mux; + pmux &= ~(mask << offset); + pmux |= ((function & mask) << offset); - pmux &= ~(0x3 << (2 * gpio_sub_n(ident))); - pmux |= (function & 0x3) << (2 * gpio_sub_n(ident)); - - gpio_array[gpio_bank(ident)]->port_mux = pmux; -} - -inline u16 get_portmux(unsigned short per) -{ - u16 ident = P_IDENT(per); - u32 pmux = gpio_array[gpio_bank(ident)]->port_mux; - return (pmux >> (2 * gpio_sub_n(ident)) & 0x3); -} -static int portmux_group_check(unsigned short per) -{ - return 0; + bfin_write_PORT_MUX(pmux); } #elif defined(CONFIG_BF52x) || defined(CONFIG_BF51x) static int portmux_group_check(unsigned short per) @@ -379,7 +331,6 @@ static int portmux_group_check(unsigned short per) } #endif -#if !(defined(CONFIG_BF54x) || defined(CONFIG_BF60x)) /*********************************************************** * * FUNCTIONS: Blackfin General Purpose Ports Access Functions @@ -572,7 +523,7 @@ static const unsigned int sic_iwr_irqs[] = { ************************************************************* * MODIFICATION HISTORY : **************************************************************/ -int gpio_pm_wakeup_ctrl(unsigned gpio, unsigned ctrl) +int bfin_gpio_pm_wakeup_ctrl(unsigned gpio, unsigned ctrl) { unsigned long flags; @@ -591,7 +542,7 @@ int gpio_pm_wakeup_ctrl(unsigned gpio, unsigned ctrl) return 0; } -int bfin_pm_standby_ctrl(unsigned ctrl) +int bfin_gpio_pm_standby_ctrl(unsigned ctrl) { u16 bank, mask, i; @@ -682,53 +633,6 @@ void bfin_gpio_pm_hibernate_restore(void) #endif -#else /* CONFIG_BF54x || CONFIG_BF60x */ -#ifdef CONFIG_PM - -int bfin_pm_standby_ctrl(unsigned ctrl) -{ - return 0; -} - -void bfin_gpio_pm_hibernate_suspend(void) -{ - int i, bank; - - for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { - bank = gpio_bank(i); - - gpio_bank_saved[bank].fer = gpio_array[bank]->port_fer; - gpio_bank_saved[bank].mux = gpio_array[bank]->port_mux; - gpio_bank_saved[bank].data = gpio_array[bank]->data; - gpio_bank_saved[bank].inen = gpio_array[bank]->inen; - gpio_bank_saved[bank].dir = gpio_array[bank]->dir_set; - } -} - -void bfin_gpio_pm_hibernate_restore(void) -{ - int i, bank; - - for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { - bank = gpio_bank(i); - - gpio_array[bank]->port_mux = gpio_bank_saved[bank].mux; - gpio_array[bank]->port_fer = gpio_bank_saved[bank].fer; - gpio_array[bank]->inen = gpio_bank_saved[bank].inen; - gpio_array[bank]->data_set = gpio_bank_saved[bank].data - & gpio_bank_saved[bank].dir; - gpio_array[bank]->dir_set = gpio_bank_saved[bank].dir; - } -} -#endif - -unsigned short get_gpio_dir(unsigned gpio) -{ - return (0x01 & (gpio_array[gpio_bank(gpio)]->dir_clear >> gpio_sub_n(gpio))); -} -EXPORT_SYMBOL(get_gpio_dir); - -#endif /* CONFIG_BF54x || CONFIG_BF60x */ /*********************************************************** * @@ -785,11 +689,7 @@ int peripheral_request(unsigned short per, const char *label) * be requested and used by several drivers */ -#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x) - if (!((per & P_MAYSHARE) && get_portmux(per) == P_FUNCT2MUX(per))) { -#else if (!(per & P_MAYSHARE)) { -#endif /* * Allow that the identical pin function can * be requested from the same driver twice @@ -938,12 +838,9 @@ int bfin_gpio_request(unsigned gpio, const char *label) if (unlikely(is_reserved(gpio_irq, gpio, 1))) { printk(KERN_NOTICE "bfin-gpio: GPIO %d is already reserved as gpio-irq!" " (Documentation/blackfin/bfin-gpio-notes.txt)\n", gpio); - } -#if !(defined(CONFIG_BF54x) || defined(CONFIG_BF60x)) - else { /* Reset POLAR setting when acquiring a gpio for the first time */ + } else { /* Reset POLAR setting when acquiring a gpio for the first time */ set_gpio_polar(gpio, 0); } -#endif reserve(gpio, gpio); set_label(gpio, label); @@ -1112,11 +1009,7 @@ void bfin_gpio_irq_free(unsigned gpio) static inline void __bfin_gpio_direction_input(unsigned gpio) { -#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x) - gpio_array[gpio_bank(gpio)]->dir_clear = gpio_bit(gpio); -#else gpio_array[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio); -#endif gpio_array[gpio_bank(gpio)]->inen |= gpio_bit(gpio); } @@ -1140,17 +1033,7 @@ EXPORT_SYMBOL(bfin_gpio_direction_input); void bfin_gpio_irq_prepare(unsigned gpio) { -#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x) - unsigned long flags; -#endif - port_setup(gpio, GPIO_USAGE); - -#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x) - flags = hard_local_irq_save(); - __bfin_gpio_direction_input(gpio); - hard_local_irq_restore(flags); -#endif } void bfin_gpio_set_value(unsigned gpio, int arg) @@ -1175,11 +1058,7 @@ int bfin_gpio_direction_output(unsigned gpio, int value) gpio_array[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio); gpio_set_value(gpio, value); -#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x) - gpio_array[gpio_bank(gpio)]->dir_set = gpio_bit(gpio); -#else gpio_array[gpio_bank(gpio)]->dir |= gpio_bit(gpio); -#endif AWA_DUMMY_READ(dir); hard_local_irq_restore(flags); @@ -1190,9 +1069,6 @@ EXPORT_SYMBOL(bfin_gpio_direction_output); int bfin_gpio_get_value(unsigned gpio) { -#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x) - return (1 & (gpio_array[gpio_bank(gpio)]->data >> gpio_sub_n(gpio))); -#else unsigned long flags; if (unlikely(get_gpio_edge(gpio))) { @@ -1205,7 +1081,6 @@ int bfin_gpio_get_value(unsigned gpio) return ret; } else return get_gpio_data(gpio); -#endif } EXPORT_SYMBOL(bfin_gpio_get_value); diff --git a/arch/blackfin/mach-bf548/Kconfig b/arch/blackfin/mach-bf548/Kconfig index 94acb586832e..334ec7b12188 100644 --- a/arch/blackfin/mach-bf548/Kconfig +++ b/arch/blackfin/mach-bf548/Kconfig @@ -377,40 +377,6 @@ config IRQ_PINT3 endmenu -comment "Pin Interrupt to Port Assignment" -menu "Assignment" - -config PINTx_REASSIGN - bool "Reprogram PINT Assignment" - default y - help - The interrupt assignment registers controls the pin-to-interrupt - assignment in a byte-wide manner. Each option allows you to select - a set of pins (High/Low Byte) of an specific Port being mapped - to one of the four PIN Interrupts IRQ_PINTx. - - You shouldn't change any of these unless you know exactly what you're doing. - Please consult the Blackfin BF54x Processor Hardware Reference Manual. - -config PINT0_ASSIGN - hex "PINT0_ASSIGN" - depends on PINTx_REASSIGN - default 0x00000101 -config PINT1_ASSIGN - hex "PINT1_ASSIGN" - depends on PINTx_REASSIGN - default 0x01010000 -config PINT2_ASSIGN - hex "PINT2_ASSIGN" - depends on PINTx_REASSIGN - default 0x07000101 -config PINT3_ASSIGN - hex "PINT3_ASSIGN" - depends on PINTx_REASSIGN - default 0x02020303 - -endmenu - endmenu endif diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c index 372eb54944ef..d495000b81a0 100644 --- a/arch/blackfin/mach-bf548/boards/ezkit.c +++ b/arch/blackfin/mach-bf548/boards/ezkit.c @@ -17,6 +17,9 @@ #include <linux/i2c.h> #include <linux/interrupt.h> #include <linux/usb/musb.h> +#include <linux/pinctrl/machine.h> +#include <linux/pinctrl/pinconf-generic.h> +#include <linux/platform_data/pinctrl-adi2.h> #include <asm/bfin5xx_spi.h> #include <asm/dma.h> #include <asm/gpio.h> @@ -241,6 +244,13 @@ static struct resource bfin_uart0_resources[] = { .end = UART0_RBR+2, .flags = IORESOURCE_MEM, }, +#ifdef CONFIG_EARLY_PRINTK + { + .start = PORTE_FER, + .end = PORTE_FER+2, + .flags = IORESOURCE_REG, + }, +#endif { .start = IRQ_UART0_TX, .end = IRQ_UART0_TX, @@ -289,6 +299,13 @@ static struct resource bfin_uart1_resources[] = { .end = UART1_RBR+2, .flags = IORESOURCE_MEM, }, +#ifdef CONFIG_EARLY_PRINTK + { + .start = PORTH_FER, + .end = PORTH_FER+2, + .flags = IORESOURCE_REG, + }, +#endif { .start = IRQ_UART1_TX, .end = IRQ_UART1_TX, @@ -353,6 +370,13 @@ static struct resource bfin_uart2_resources[] = { .end = UART2_RBR+2, .flags = IORESOURCE_MEM, }, +#ifdef CONFIG_EARLY_PRINTK + { + .start = PORTB_FER, + .end = PORTB_FER+2, + .flags = IORESOURCE_REG, + }, +#endif { .start = IRQ_UART2_TX, .end = IRQ_UART2_TX, @@ -401,6 +425,13 @@ static struct resource bfin_uart3_resources[] = { .end = UART3_RBR+2, .flags = IORESOURCE_MEM, }, +#ifdef CONFIG_EARLY_PRINTK + { + .start = PORTB_FER, + .end = PORTB_FER+2, + .flags = IORESOURCE_REG, + }, +#endif { .start = IRQ_UART3_TX, .end = IRQ_UART3_TX, @@ -1058,6 +1089,411 @@ static const struct ad7877_platform_data bfin_ad7877_ts_info = { }; #endif +#ifdef CONFIG_PINCTRL_ADI2 + +# define ADI_PINT_DEVNAME "adi-gpio-pint" +# define ADI_GPIO_DEVNAME "adi-gpio" +# define ADI_PINCTRL_DEVNAME "pinctrl-adi2" + +static struct platform_device bfin_pinctrl_device = { + .name = ADI_PINCTRL_DEVNAME, + .id = 0, +}; + +static struct resource bfin_pint0_resources[] = { + { + .start = PINT0_MASK_SET, + .end = PINT0_LATCH + 3, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_PINT0, + .end = IRQ_PINT0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device bfin_pint0_device = { + .name = ADI_PINT_DEVNAME, + .id = 0, + .num_resources = ARRAY_SIZE(bfin_pint0_resources), + .resource = bfin_pint0_resources, +}; + +static struct resource bfin_pint1_resources[] = { + { + .start = PINT1_MASK_SET, + .end = PINT1_LATCH + 3, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_PINT1, + .end = IRQ_PINT1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device bfin_pint1_device = { + .name = ADI_PINT_DEVNAME, + .id = 1, + .num_resources = ARRAY_SIZE(bfin_pint1_resources), + .resource = bfin_pint1_resources, +}; + +static struct resource bfin_pint2_resources[] = { + { + .start = PINT2_MASK_SET, + .end = PINT2_LATCH + 3, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_PINT2, + .end = IRQ_PINT2, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device bfin_pint2_device = { + .name = ADI_PINT_DEVNAME, + .id = 2, + .num_resources = ARRAY_SIZE(bfin_pint2_resources), + .resource = bfin_pint2_resources, +}; + +static struct resource bfin_pint3_resources[] = { + { + .start = PINT3_MASK_SET, + .end = PINT3_LATCH + 3, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_PINT3, + .end = IRQ_PINT3, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device bfin_pint3_device = { + .name = ADI_PINT_DEVNAME, + .id = 3, + .num_resources = ARRAY_SIZE(bfin_pint3_resources), + .resource = bfin_pint3_resources, +}; + +static struct resource bfin_gpa_resources[] = { + { + .start = PORTA_FER, + .end = PORTA_MUX + 3, + .flags = IORESOURCE_MEM, + }, + { /* optional */ + .start = IRQ_PA0, + .end = IRQ_PA0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct adi_pinctrl_gpio_platform_data bfin_gpa_pdata = { + .port_gpio_base = GPIO_PA0, /* Optional */ + .port_pin_base = GPIO_PA0, + .port_width = GPIO_BANKSIZE, + .pint_id = 0, /* PINT0 */ + .pint_assign = true, /* PINT upper 16 bit */ + .pint_map = 0, /* mapping mask in PINT */ +}; + +static struct platform_device bfin_gpa_device = { + .name = ADI_GPIO_DEVNAME, + .id = 0, + .num_resources = ARRAY_SIZE(bfin_gpa_resources), + .resource = bfin_gpa_resources, + .dev = { + .platform_data = &bfin_gpa_pdata, /* Passed to driver */ + }, +}; + +static struct resource bfin_gpb_resources[] = { + { + .start = PORTB_FER, + .end = PORTB_MUX + 3, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_PB0, + .end = IRQ_PB0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct adi_pinctrl_gpio_platform_data bfin_gpb_pdata = { + .port_gpio_base = GPIO_PB0, + .port_pin_base = GPIO_PB0, + .port_width = 15, + .pint_id = 0, + .pint_assign = true, + .pint_map = 1, +}; + +static struct platform_device bfin_gpb_device = { + .name = ADI_GPIO_DEVNAME, + .id = 1, + .num_resources = ARRAY_SIZE(bfin_gpb_resources), + .resource = bfin_gpb_resources, + .dev = { + .platform_data = &bfin_gpb_pdata, /* Passed to driver */ + }, +}; + +static struct resource bfin_gpc_resources[] = { + { + .start = PORTC_FER, + .end = PORTC_MUX + 3, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_PC0, + .end = IRQ_PC0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct adi_pinctrl_gpio_platform_data bfin_gpc_pdata = { + .port_gpio_base = GPIO_PC0, + .port_pin_base = GPIO_PC0, + .port_width = 14, + .pint_id = 2, + .pint_assign = true, + .pint_map = 0, +}; + +static struct platform_device bfin_gpc_device = { + .name = ADI_GPIO_DEVNAME, + .id = 2, + .num_resources = ARRAY_SIZE(bfin_gpc_resources), + .resource = bfin_gpc_resources, + .dev = { + .platform_data = &bfin_gpc_pdata, /* Passed to driver */ + }, +}; + +static struct resource bfin_gpd_resources[] = { + { + .start = PORTD_FER, + .end = PORTD_MUX + 3, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_PD0, + .end = IRQ_PD0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct adi_pinctrl_gpio_platform_data bfin_gpd_pdata = { + .port_gpio_base = GPIO_PD0, + .port_pin_base = GPIO_PD0, + .port_width = GPIO_BANKSIZE, + .pint_id = 2, + .pint_assign = false, + .pint_map = 1, +}; + +static struct platform_device bfin_gpd_device = { + .name = ADI_GPIO_DEVNAME, + .id = 3, + .num_resources = ARRAY_SIZE(bfin_gpd_resources), + .resource = bfin_gpd_resources, + .dev = { + .platform_data = &bfin_gpd_pdata, /* Passed to driver */ + }, +}; + +static struct resource bfin_gpe_resources[] = { + { + .start = PORTE_FER, + .end = PORTE_MUX + 3, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_PE0, + .end = IRQ_PE0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct adi_pinctrl_gpio_platform_data bfin_gpe_pdata = { + .port_gpio_base = GPIO_PE0, + .port_pin_base = GPIO_PE0, + .port_width = GPIO_BANKSIZE, + .pint_id = 3, + .pint_assign = true, + .pint_map = 2, +}; + +static struct platform_device bfin_gpe_device = { + .name = ADI_GPIO_DEVNAME, + .id = 4, + .num_resources = ARRAY_SIZE(bfin_gpe_resources), + .resource = bfin_gpe_resources, + .dev = { + .platform_data = &bfin_gpe_pdata, /* Passed to driver */ + }, +}; + +static struct resource bfin_gpf_resources[] = { + { + .start = PORTF_FER, + .end = PORTF_MUX + 3, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_PF0, + .end = IRQ_PF0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct adi_pinctrl_gpio_platform_data bfin_gpf_pdata = { + .port_gpio_base = GPIO_PF0, + .port_pin_base = GPIO_PF0, + .port_width = GPIO_BANKSIZE, + .pint_id = 3, + .pint_assign = false, + .pint_map = 3, +}; + +static struct platform_device bfin_gpf_device = { + .name = ADI_GPIO_DEVNAME, + .id = 5, + .num_resources = ARRAY_SIZE(bfin_gpf_resources), + .resource = bfin_gpf_resources, + .dev = { + .platform_data = &bfin_gpf_pdata, /* Passed to driver */ + }, +}; + +static struct resource bfin_gpg_resources[] = { + { + .start = PORTG_FER, + .end = PORTG_MUX + 3, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_PG0, + .end = IRQ_PG0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct adi_pinctrl_gpio_platform_data bfin_gpg_pdata = { + .port_gpio_base = GPIO_PG0, + .port_pin_base = GPIO_PG0, + .port_width = GPIO_BANKSIZE, + .pint_id = -1, +}; + +static struct platform_device bfin_gpg_device = { + .name = ADI_GPIO_DEVNAME, + .id = 6, + .num_resources = ARRAY_SIZE(bfin_gpg_resources), + .resource = bfin_gpg_resources, + .dev = { + .platform_data = &bfin_gpg_pdata, /* Passed to driver */ + }, +}; + +static struct resource bfin_gph_resources[] = { + { + .start = PORTH_FER, + .end = PORTH_MUX + 3, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_PH0, + .end = IRQ_PH0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct adi_pinctrl_gpio_platform_data bfin_gph_pdata = { + .port_gpio_base = GPIO_PH0, + .port_pin_base = GPIO_PH0, + .port_width = 14, + .pint_id = -1, +}; + +static struct platform_device bfin_gph_device = { + .name = ADI_GPIO_DEVNAME, + .id = 7, + .num_resources = ARRAY_SIZE(bfin_gph_resources), + .resource = bfin_gph_resources, + .dev = { + .platform_data = &bfin_gph_pdata, /* Passed to driver */ + }, +}; + +static struct resource bfin_gpi_resources[] = { + { + .start = PORTI_FER, + .end = PORTI_MUX + 3, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_PI0, + .end = IRQ_PI0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct adi_pinctrl_gpio_platform_data bfin_gpi_pdata = { + .port_gpio_base = GPIO_PI0, + .port_pin_base = GPIO_PI0, + .port_width = GPIO_BANKSIZE, + .pint_id = -1, +}; + +static struct platform_device bfin_gpi_device = { + .name = ADI_GPIO_DEVNAME, + .id = 8, + .num_resources = ARRAY_SIZE(bfin_gpi_resources), + .resource = bfin_gpi_resources, + .dev = { + .platform_data = &bfin_gpi_pdata, /* Passed to driver */ + }, +}; + +static struct resource bfin_gpj_resources[] = { + { + .start = PORTJ_FER, + .end = PORTJ_MUX + 3, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_PJ0, + .end = IRQ_PJ0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct adi_pinctrl_gpio_platform_data bfin_gpj_pdata = { + .port_gpio_base = GPIO_PJ0, + .port_pin_base = GPIO_PJ0, + .port_width = 14, + .pint_id = -1, +}; + +static struct platform_device bfin_gpj_device = { + .name = ADI_GPIO_DEVNAME, + .id = 9, + .num_resources = ARRAY_SIZE(bfin_gpj_resources), + .resource = bfin_gpj_resources, + .dev = { + .platform_data = &bfin_gpj_pdata, /* Passed to driver */ + }, +}; + +#endif + static struct spi_board_info bfin_spi_board_info[] __initdata = { #if defined(CONFIG_MTD_M25P80) \ || defined(CONFIG_MTD_M25P80_MODULE) @@ -1066,7 +1502,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { .modalias = "m25p80", /* Name of spi_driver for this device */ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ .bus_num = 0, /* Framework bus number */ - .chip_select = 1, /* SPI_SSEL1*/ + .chip_select = MAX_CTRL_CS + GPIO_PE4, /* SPI_SSEL1*/ .platform_data = &bfin_spi_flash_data, .controller_data = &spi_flash_chip_info, .mode = SPI_MODE_3, @@ -1078,7 +1514,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { .modalias = "ad183x", .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ .bus_num = 1, - .chip_select = 4, + .chip_select = MAX_CTRL_CS + GPIO_PG6, /* SPI_SSEL2 */ }, #endif #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) @@ -1088,7 +1524,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { .irq = IRQ_PB4, /* old boards (<=Rev 1.3) use IRQ_PJ11 */ .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ .bus_num = 0, - .chip_select = 2, + .chip_select = MAX_CTRL_CS + GPIO_PE5, /* SPI_SSEL2 */ }, #endif #if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE) @@ -1096,7 +1532,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { .modalias = "spidev", .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ .bus_num = 0, - .chip_select = 1, + .chip_select = MAX_CTRL_CS + GPIO_PE4, /* SPI_SSEL1 */ }, #endif #if defined(CONFIG_INPUT_ADXL34X_SPI) || defined(CONFIG_INPUT_ADXL34X_SPI_MODULE) @@ -1106,7 +1542,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { .irq = IRQ_PC5, .max_speed_hz = 5000000, /* max spi clock (SCK) speed in HZ */ .bus_num = 1, - .chip_select = 2, + .chip_select = MAX_CTRL_CS + GPIO_PG6, /* SPI_SSEL2 */ .mode = SPI_MODE_3, }, #endif @@ -1152,7 +1588,7 @@ static struct resource bfin_spi1_resource[] = { /* SPI controller data */ static struct bfin5xx_spi_master bf54x_spi_master_info0 = { - .num_chipselect = 4, + .num_chipselect = MAX_CTRL_CS + MAX_BLACKFIN_GPIOS, .enable_dma = 1, /* master has the ability to do dma transfer */ .pin_req = {P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0}, }; @@ -1168,7 +1604,7 @@ static struct platform_device bf54x_spi_master0 = { }; static struct bfin5xx_spi_master bf54x_spi_master_info1 = { - .num_chipselect = 4, + .num_chipselect = MAX_CTRL_CS + MAX_BLACKFIN_GPIOS, .enable_dma = 1, /* master has the ability to do dma transfer */ .pin_req = {P_SPI1_SCK, P_SPI1_MISO, P_SPI1_MOSI, 0}, }; @@ -1508,6 +1944,23 @@ static struct platform_device bfin_ac97 = { static struct platform_device *ezkit_devices[] __initdata = { &bfin_dpmc, +#if defined(CONFIG_PINCTRL_ADI2) + &bfin_pinctrl_device, + &bfin_pint0_device, + &bfin_pint1_device, + &bfin_pint2_device, + &bfin_pint3_device, + &bfin_gpa_device, + &bfin_gpb_device, + &bfin_gpc_device, + &bfin_gpd_device, + &bfin_gpe_device, + &bfin_gpf_device, + &bfin_gpg_device, + &bfin_gph_device, + &bfin_gpi_device, + &bfin_gpj_device, +#endif #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) &rtc_device, @@ -1644,10 +2097,66 @@ static struct platform_device *ezkit_devices[] __initdata = { #endif }; +/* Pin control settings */ +static struct pinctrl_map __initdata bfin_pinmux_map[] = { + /* per-device maps */ + PIN_MAP_MUX_GROUP_DEFAULT("bfin-uart.0", "pinctrl-adi2.0", NULL, "uart0"), + PIN_MAP_MUX_GROUP_DEFAULT("bfin-uart.1", "pinctrl-adi2.0", NULL, "uart1"), +#ifdef CONFIG_BFIN_UART1_CTSRTS + PIN_MAP_MUX_GROUP_DEFAULT("bfin-uart.1", "pinctrl-adi2.0", NULL, "uart1_ctsrts"), +#endif + PIN_MAP_MUX_GROUP_DEFAULT("bfin-uart.2", "pinctrl-adi2.0", NULL, "uart2"), + PIN_MAP_MUX_GROUP_DEFAULT("bfin-uart.3", "pinctrl-adi2.0", NULL, "uart3"), +#ifdef CONFIG_BFIN_UART3_CTSRTS + PIN_MAP_MUX_GROUP_DEFAULT("bfin-uart.3", "pinctrl-adi2.0", NULL, "uart3_ctsrts"), +#endif + PIN_MAP_MUX_GROUP_DEFAULT("bfin_sir.0", "pinctrl-adi2.0", NULL, "uart0"), + PIN_MAP_MUX_GROUP_DEFAULT("bfin_sir.1", "pinctrl-adi2.0", NULL, "uart1"), + PIN_MAP_MUX_GROUP_DEFAULT("bfin_sir.2", "pinctrl-adi2.0", NULL, "uart2"), + PIN_MAP_MUX_GROUP_DEFAULT("bfin_sir.3", "pinctrl-adi2.0", NULL, "uart3"), + PIN_MAP_MUX_GROUP_DEFAULT("bfin-sdh.0", "pinctrl-adi2.0", NULL, "rsi0"), + PIN_MAP_MUX_GROUP_DEFAULT("bfin-spi.0", "pinctrl-adi2.0", NULL, "spi0"), + PIN_MAP_MUX_GROUP_DEFAULT("bfin-spi.1", "pinctrl-adi2.0", NULL, "spi1"), + PIN_MAP_MUX_GROUP_DEFAULT("i2c-bfin-twi.0", "pinctrl-adi2.0", NULL, "twi0"), +#if !defined(CONFIG_BF542) /* The BF542 only has 1 TWI */ + PIN_MAP_MUX_GROUP_DEFAULT("i2c-bfin-twi.1", "pinctrl-adi2.0", NULL, "twi1"), +#endif + PIN_MAP_MUX_GROUP_DEFAULT("bfin-rotary", "pinctrl-adi2.0", NULL, "rotary"), + PIN_MAP_MUX_GROUP_DEFAULT("bfin_can.0", "pinctrl-adi2.0", NULL, "can0"), + PIN_MAP_MUX_GROUP_DEFAULT("bfin_can.1", "pinctrl-adi2.0", NULL, "can1"), + PIN_MAP_MUX_GROUP_DEFAULT("bf54x-lq043", "pinctrl-adi2.0", NULL, "ppi0_24b"), + PIN_MAP_MUX_GROUP_DEFAULT("bfin-i2s.0", "pinctrl-adi2.0", NULL, "sport0"), + PIN_MAP_MUX_GROUP_DEFAULT("bfin-tdm.0", "pinctrl-adi2.0", NULL, "sport0"), + PIN_MAP_MUX_GROUP_DEFAULT("bfin-ac97.0", "pinctrl-adi2.0", NULL, "sport0"), + PIN_MAP_MUX_GROUP_DEFAULT("bfin-i2s.1", "pinctrl-adi2.0", NULL, "sport1"), + PIN_MAP_MUX_GROUP_DEFAULT("bfin-tdm.1", "pinctrl-adi2.0", NULL, "sport1"), + PIN_MAP_MUX_GROUP_DEFAULT("bfin-ac97.1", "pinctrl-adi2.0", NULL, "sport1"), + PIN_MAP_MUX_GROUP_DEFAULT("bfin-i2s.2", "pinctrl-adi2.0", NULL, "sport2"), + PIN_MAP_MUX_GROUP_DEFAULT("bfin-tdm.2", "pinctrl-adi2.0", NULL, "sport2"), + PIN_MAP_MUX_GROUP_DEFAULT("bfin-ac97.2", "pinctrl-adi2.0", NULL, "sport2"), + PIN_MAP_MUX_GROUP_DEFAULT("bfin-i2s.3", "pinctrl-adi2.0", NULL, "sport3"), + PIN_MAP_MUX_GROUP_DEFAULT("bfin-tdm.3", "pinctrl-adi2.0", NULL, "sport3"), + PIN_MAP_MUX_GROUP_DEFAULT("bfin-ac97.3", "pinctrl-adi2.0", NULL, "sport3"), + PIN_MAP_MUX_GROUP_DEFAULT("bfin-sport-uart.0", "pinctrl-adi2.0", NULL, "sport0"), + PIN_MAP_MUX_GROUP_DEFAULT("bfin-sport-uart.1", "pinctrl-adi2.0", NULL, "sport1"), + PIN_MAP_MUX_GROUP_DEFAULT("bfin-sport-uart.2", "pinctrl-adi2.0", NULL, "sport2"), + PIN_MAP_MUX_GROUP_DEFAULT("bfin-sport-uart.3", "pinctrl-adi2.0", NULL, "sport3"), + PIN_MAP_MUX_GROUP_DEFAULT("pata-bf54x", "pinctrl-adi2.0", NULL, "atapi"), +#ifdef CONFIG_BF548_ATAPI_ALTERNATIVE_PORT + PIN_MAP_MUX_GROUP_DEFAULT("pata-bf54x", "pinctrl-adi2.0", NULL, "atapi_alter"), +#endif + PIN_MAP_MUX_GROUP_DEFAULT("bf5xx-nand.0", "pinctrl-adi2.0", NULL, "nfc0"), + PIN_MAP_MUX_GROUP_DEFAULT("bf54x-keys", "pinctrl-adi2.0", NULL, "keys_4x4"), +}; + static int __init ezkit_init(void) { printk(KERN_INFO "%s(): registering device resources\n", __func__); + /* Initialize pinmuxing */ + pinctrl_register_mappings(bfin_pinmux_map, + ARRAY_SIZE(bfin_pinmux_map)); + i2c_register_board_info(0, bfin_i2c_board_info0, ARRAY_SIZE(bfin_i2c_board_info0)); #if !defined(CONFIG_BF542) /* The BF542 only has 1 TWI */ @@ -1679,21 +2188,6 @@ static struct platform_device *ezkit_early_devices[] __initdata = { &bfin_uart3_device, #endif #endif - -#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE) -#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART - &bfin_sport0_uart_device, -#endif -#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART - &bfin_sport1_uart_device, -#endif -#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART - &bfin_sport2_uart_device, -#endif -#ifdef CONFIG_SERIAL_BFIN_SPORT3_UART - &bfin_sport3_uart_device, -#endif -#endif }; void __init native_machine_early_platform_add_devices(void) diff --git a/arch/blackfin/mach-bf548/include/mach/gpio.h b/arch/blackfin/mach-bf548/include/mach/gpio.h index be9edb28f96b..006da1edcf84 100644 --- a/arch/blackfin/mach-bf548/include/mach/gpio.h +++ b/arch/blackfin/mach-bf548/include/mach/gpio.h @@ -194,14 +194,6 @@ struct gpio_port_t { unsigned int port_mux; }; -struct gpio_port_s { - unsigned short fer; - unsigned short data; - unsigned short dir; - unsigned short inen; - unsigned int mux; -}; - #endif #include <mach-common/ports-a.h> diff --git a/arch/blackfin/mach-bf548/include/mach/irq.h b/arch/blackfin/mach-bf548/include/mach/irq.h index 10dc142c518d..cf7cb725cfa2 100644 --- a/arch/blackfin/mach-bf548/include/mach/irq.h +++ b/arch/blackfin/mach-bf548/include/mach/irq.h @@ -433,7 +433,7 @@ #include <linux/types.h> /* - * bfin pint registers layout + * gpio pint registers layout */ struct bfin_pint_regs { u32 mask_set; diff --git a/arch/blackfin/mach-bf548/include/mach/portmux.h b/arch/blackfin/mach-bf548/include/mach/portmux.h index e22246202730..d9f8632d7d09 100644 --- a/arch/blackfin/mach-bf548/include/mach/portmux.h +++ b/arch/blackfin/mach-bf548/include/mach/portmux.h @@ -7,8 +7,6 @@ #ifndef _MACH_PORTMUX_H_ #define _MACH_PORTMUX_H_ -#define MAX_RESOURCES MAX_BLACKFIN_GPIOS - #define P_SPORT2_TFS (P_DEFINED | P_IDENT(GPIO_PA0) | P_FUNCT(0)) #define P_SPORT2_DTSEC (P_DEFINED | P_IDENT(GPIO_PA1) | P_FUNCT(0)) #define P_SPORT2_DTPRI (P_DEFINED | P_IDENT(GPIO_PA2) | P_FUNCT(0)) diff --git a/arch/blackfin/mach-bf609/Kconfig b/arch/blackfin/mach-bf609/Kconfig index 2bcbf94b1edf..b0fca44110b0 100644 --- a/arch/blackfin/mach-bf609/Kconfig +++ b/arch/blackfin/mach-bf609/Kconfig @@ -9,48 +9,6 @@ source "arch/blackfin/mach-bf609/boards/Kconfig" menu "BF609 Specific Configuration" -comment "Pin Interrupt to Port Assignment" -menu "Assignment" - -config PINTx_REASSIGN - bool "Reprogram PINT Assignment" - default y - help - The interrupt assignment registers controls the pin-to-interrupt - assignment in a byte-wide manner. Each option allows you to select - a set of pins (High/Low Byte) of an specific Port being mapped - to one of the four PIN Interrupts IRQ_PINTx. - - You shouldn't change any of these unless you know exactly what you're doing. - Please consult the Blackfin BF60x Processor Hardware Reference Manual. - -config PINT0_ASSIGN - hex "PINT0_ASSIGN" - depends on PINTx_REASSIGN - default 0x00000101 -config PINT1_ASSIGN - hex "PINT1_ASSIGN" - depends on PINTx_REASSIGN - default 0x00000101 -config PINT2_ASSIGN - hex "PINT2_ASSIGN" - depends on PINTx_REASSIGN - default 0x00000101 -config PINT3_ASSIGN - hex "PINT3_ASSIGN" - depends on PINTx_REASSIGN - default 0x00000101 -config PINT4_ASSIGN - hex "PINT3_ASSIGN" - depends on PINTx_REASSIGN - default 0x00000101 -config PINT5_ASSIGN - hex "PINT3_ASSIGN" - depends on PINTx_REASSIGN - default 0x00000101 - -endmenu - config SEC_IRQ_PRIORITY_LEVELS int "SEC interrupt priority levels" default 7 diff --git a/arch/blackfin/mach-bf609/boards/ezkit.c b/arch/blackfin/mach-bf609/boards/ezkit.c index d56a55ad83a7..82beedd953f6 100644 --- a/arch/blackfin/mach-bf609/boards/ezkit.c +++ b/arch/blackfin/mach-bf609/boards/ezkit.c @@ -17,6 +17,9 @@ #include <linux/i2c.h> #include <linux/interrupt.h> #include <linux/usb/musb.h> +#include <linux/pinctrl/machine.h> +#include <linux/pinctrl/pinconf-generic.h> +#include <linux/platform_data/pinctrl-adi2.h> #include <asm/bfin_spi3.h> #include <asm/dma.h> #include <asm/gpio.h> @@ -106,8 +109,6 @@ static struct platform_device bfin_rotary_device = { #include <linux/stmmac.h> #include <linux/phy.h> -static unsigned short pins[] = P_RMII0; - static struct stmmac_mdio_bus_data phy_private_data = { .phy_mask = 1, }; @@ -212,6 +213,18 @@ static struct resource bfin_uart0_resources[] = { .end = UART0_RXDIV+4, .flags = IORESOURCE_MEM, }, +#ifdef CONFIG_EARLY_PRINTK + { + .start = PORTD_FER, + .end = PORTD_FER+2, + .flags = IORESOURCE_REG, + }, + { + .start = PORTD_MUX, + .end = PORTD_MUX+3, + .flags = IORESOURCE_REG, + }, +#endif { .start = IRQ_UART0_TX, .end = IRQ_UART0_TX, @@ -276,6 +289,13 @@ static struct resource bfin_uart1_resources[] = { .end = UART1_RXDIV+4, .flags = IORESOURCE_MEM, }, +#ifdef CONFIG_EARLY_PRINTK + { + .start = PORTG_FER_SET, + .end = PORTG_FER_SET+2, + .flags = IORESOURCE_REG, + }, +#endif { .start = IRQ_UART1_TX, .end = IRQ_UART1_TX, @@ -674,17 +694,12 @@ static struct mtd_partition ezkit_partitions[] = { }, }; -int bf609_nor_flash_init(struct platform_device *dev) +int bf609_nor_flash_init(struct platform_device *pdev) { #define CONFIG_SMC_GCTL_VAL 0x00000010 - const unsigned short pins[] = { - P_A3, P_A4, P_A5, P_A6, P_A7, P_A8, P_A9, P_A10, P_A11, P_A12, - P_A13, P_A14, P_A15, P_A16, P_A17, P_A18, P_A19, P_A20, P_A21, - P_A22, P_A23, P_A24, P_A25, P_NORCK, 0, - }; - - peripheral_request_list(pins, "smc0"); + if (!devm_pinctrl_get_select_default(&pdev->dev)) + return -EBUSY; bfin_write32(SMC_GCTL, CONFIG_SMC_GCTL_VAL); bfin_write32(SMC_B0CTL, 0x01002011); bfin_write32(SMC_B0TIM, 0x08170977); @@ -692,16 +707,9 @@ int bf609_nor_flash_init(struct platform_device *dev) return 0; } -void bf609_nor_flash_exit(struct platform_device *dev) +void bf609_nor_flash_exit(struct platform_device *pdev) { - const unsigned short pins[] = { - P_A3, P_A4, P_A5, P_A6, P_A7, P_A8, P_A9, P_A10, P_A11, P_A12, - P_A13, P_A14, P_A15, P_A16, P_A17, P_A18, P_A19, P_A20, P_A21, - P_A22, P_A23, P_A24, P_A25, P_NORCK, 0, - }; - - peripheral_free_list(pins); - + devm_pinctrl_put(pdev->dev.pins->p); bfin_write32(SMC_GCTL, 0); } @@ -1319,6 +1327,356 @@ static const struct ad7877_platform_data bfin_ad7877_ts_info = { }; #endif +#ifdef CONFIG_PINCTRL_ADI2 + +# define ADI_PINT_DEVNAME "adi-gpio-pint" +# define ADI_GPIO_DEVNAME "adi-gpio" +# define ADI_PINCTRL_DEVNAME "pinctrl-adi2" + +static struct platform_device bfin_pinctrl_device = { + .name = ADI_PINCTRL_DEVNAME, + .id = 0, +}; + +static struct resource bfin_pint0_resources[] = { + { + .start = PINT0_MASK_SET, + .end = PINT0_LATCH + 3, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_PINT0, + .end = IRQ_PINT0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device bfin_pint0_device = { + .name = ADI_PINT_DEVNAME, + .id = 0, + .num_resources = ARRAY_SIZE(bfin_pint0_resources), + .resource = bfin_pint0_resources, +}; + +static struct resource bfin_pint1_resources[] = { + { + .start = PINT1_MASK_SET, + .end = PINT1_LATCH + 3, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_PINT1, + .end = IRQ_PINT1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device bfin_pint1_device = { + .name = ADI_PINT_DEVNAME, + .id = 1, + .num_resources = ARRAY_SIZE(bfin_pint1_resources), + .resource = bfin_pint1_resources, +}; + +static struct resource bfin_pint2_resources[] = { + { + .start = PINT2_MASK_SET, + .end = PINT2_LATCH + 3, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_PINT2, + .end = IRQ_PINT2, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device bfin_pint2_device = { + .name = ADI_PINT_DEVNAME, + .id = 2, + .num_resources = ARRAY_SIZE(bfin_pint2_resources), + .resource = bfin_pint2_resources, +}; + +static struct resource bfin_pint3_resources[] = { + { + .start = PINT3_MASK_SET, + .end = PINT3_LATCH + 3, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_PINT3, + .end = IRQ_PINT3, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device bfin_pint3_device = { + .name = ADI_PINT_DEVNAME, + .id = 3, + .num_resources = ARRAY_SIZE(bfin_pint3_resources), + .resource = bfin_pint3_resources, +}; + +static struct resource bfin_pint4_resources[] = { + { + .start = PINT4_MASK_SET, + .end = PINT4_LATCH + 3, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_PINT4, + .end = IRQ_PINT4, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device bfin_pint4_device = { + .name = ADI_PINT_DEVNAME, + .id = 4, + .num_resources = ARRAY_SIZE(bfin_pint4_resources), + .resource = bfin_pint4_resources, +}; + +static struct resource bfin_pint5_resources[] = { + { + .start = PINT5_MASK_SET, + .end = PINT5_LATCH + 3, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_PINT5, + .end = IRQ_PINT5, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device bfin_pint5_device = { + .name = ADI_PINT_DEVNAME, + .id = 5, + .num_resources = ARRAY_SIZE(bfin_pint5_resources), + .resource = bfin_pint5_resources, +}; + +static struct resource bfin_gpa_resources[] = { + { + .start = PORTA_FER, + .end = PORTA_MUX + 3, + .flags = IORESOURCE_MEM, + }, + { /* optional */ + .start = IRQ_PA0, + .end = IRQ_PA0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct adi_pinctrl_gpio_platform_data bfin_gpa_pdata = { + .port_pin_base = GPIO_PA0, + .port_width = GPIO_BANKSIZE, + .pint_id = 0, /* PINT0 */ + .pint_assign = true, /* PINT upper 16 bit */ + .pint_map = 0, /* mapping mask in PINT */ +}; + +static struct platform_device bfin_gpa_device = { + .name = ADI_GPIO_DEVNAME, + .id = 0, + .num_resources = ARRAY_SIZE(bfin_gpa_resources), + .resource = bfin_gpa_resources, + .dev = { + .platform_data = &bfin_gpa_pdata, /* Passed to driver */ + }, +}; + +static struct resource bfin_gpb_resources[] = { + { + .start = PORTB_FER, + .end = PORTB_MUX + 3, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_PB0, + .end = IRQ_PB0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct adi_pinctrl_gpio_platform_data bfin_gpb_pdata = { + .port_pin_base = GPIO_PB0, + .port_width = GPIO_BANKSIZE, + .pint_id = 0, + .pint_assign = false, + .pint_map = 1, +}; + +static struct platform_device bfin_gpb_device = { + .name = ADI_GPIO_DEVNAME, + .id = 1, + .num_resources = ARRAY_SIZE(bfin_gpb_resources), + .resource = bfin_gpb_resources, + .dev = { + .platform_data = &bfin_gpb_pdata, /* Passed to driver */ + }, +}; + +static struct resource bfin_gpc_resources[] = { + { + .start = PORTC_FER, + .end = PORTC_MUX + 3, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_PC0, + .end = IRQ_PC0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct adi_pinctrl_gpio_platform_data bfin_gpc_pdata = { + .port_pin_base = GPIO_PC0, + .port_width = GPIO_BANKSIZE, + .pint_id = 1, + .pint_assign = false, + .pint_map = 1, +}; + +static struct platform_device bfin_gpc_device = { + .name = ADI_GPIO_DEVNAME, + .id = 2, + .num_resources = ARRAY_SIZE(bfin_gpc_resources), + .resource = bfin_gpc_resources, + .dev = { + .platform_data = &bfin_gpc_pdata, /* Passed to driver */ + }, +}; + +static struct resource bfin_gpd_resources[] = { + { + .start = PORTD_FER, + .end = PORTD_MUX + 3, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_PD0, + .end = IRQ_PD0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct adi_pinctrl_gpio_platform_data bfin_gpd_pdata = { + .port_pin_base = GPIO_PD0, + .port_width = GPIO_BANKSIZE, + .pint_id = 2, + .pint_assign = false, + .pint_map = 1, +}; + +static struct platform_device bfin_gpd_device = { + .name = ADI_GPIO_DEVNAME, + .id = 3, + .num_resources = ARRAY_SIZE(bfin_gpd_resources), + .resource = bfin_gpd_resources, + .dev = { + .platform_data = &bfin_gpd_pdata, /* Passed to driver */ + }, +}; + +static struct resource bfin_gpe_resources[] = { + { + .start = PORTE_FER, + .end = PORTE_MUX + 3, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_PE0, + .end = IRQ_PE0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct adi_pinctrl_gpio_platform_data bfin_gpe_pdata = { + .port_pin_base = GPIO_PE0, + .port_width = GPIO_BANKSIZE, + .pint_id = 3, + .pint_assign = false, + .pint_map = 1, +}; + +static struct platform_device bfin_gpe_device = { + .name = ADI_GPIO_DEVNAME, + .id = 4, + .num_resources = ARRAY_SIZE(bfin_gpe_resources), + .resource = bfin_gpe_resources, + .dev = { + .platform_data = &bfin_gpe_pdata, /* Passed to driver */ + }, +}; + +static struct resource bfin_gpf_resources[] = { + { + .start = PORTF_FER, + .end = PORTF_MUX + 3, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_PF0, + .end = IRQ_PF0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct adi_pinctrl_gpio_platform_data bfin_gpf_pdata = { + .port_pin_base = GPIO_PF0, + .port_width = GPIO_BANKSIZE, + .pint_id = 4, + .pint_assign = false, + .pint_map = 1, +}; + +static struct platform_device bfin_gpf_device = { + .name = ADI_GPIO_DEVNAME, + .id = 5, + .num_resources = ARRAY_SIZE(bfin_gpf_resources), + .resource = bfin_gpf_resources, + .dev = { + .platform_data = &bfin_gpf_pdata, /* Passed to driver */ + }, +}; + +static struct resource bfin_gpg_resources[] = { + { + .start = PORTG_FER, + .end = PORTG_MUX + 3, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_PG0, + .end = IRQ_PG0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct adi_pinctrl_gpio_platform_data bfin_gpg_pdata = { + .port_pin_base = GPIO_PG0, + .port_width = GPIO_BANKSIZE, + .pint_id = 5, + .pint_assign = false, + .pint_map = 1, +}; + +static struct platform_device bfin_gpg_device = { + .name = ADI_GPIO_DEVNAME, + .id = 6, + .num_resources = ARRAY_SIZE(bfin_gpg_resources), + .resource = bfin_gpg_resources, + .dev = { + .platform_data = &bfin_gpg_pdata, /* Passed to driver */ + }, +}; + +#endif + #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) #include <linux/input.h> #include <linux/gpio_keys.h> @@ -1349,7 +1707,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { .modalias = "m25p80", /* Name of spi_driver for this device */ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ .bus_num = 0, /* Framework bus number */ - .chip_select = 1, /* SPI_SSEL1*/ + .chip_select = MAX_CTRL_CS + GPIO_PD11, /* SPI_SSEL1*/ .platform_data = &bfin_spi_flash_data, .controller_data = &spi_flash_chip_info, .mode = SPI_MODE_3, @@ -1362,7 +1720,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { .irq = IRQ_PD9, .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ .bus_num = 0, - .chip_select = 4, + .chip_select = MAX_CTRL_CS + GPIO_PC15, /* SPI_SSEL4 */ }, #endif #if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE) @@ -1370,7 +1728,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { .modalias = "spidev", .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ .bus_num = 0, - .chip_select = 1, + .chip_select = MAX_CTRL_CS + GPIO_PD11, /* SPI_SSEL1*/ .controller_data = &spidev_chip_info, }, #endif @@ -1565,6 +1923,22 @@ static struct platform_device bfin_dpmc = { static struct platform_device *ezkit_devices[] __initdata = { &bfin_dpmc, +#if defined(CONFIG_PINCTRL_ADI2) + &bfin_pinctrl_device, + &bfin_pint0_device, + &bfin_pint1_device, + &bfin_pint2_device, + &bfin_pint3_device, + &bfin_pint4_device, + &bfin_pint5_device, + &bfin_gpa_device, + &bfin_gpb_device, + &bfin_gpc_device, + &bfin_gpd_device, + &bfin_gpe_device, + &bfin_gpf_device, + &bfin_gpg_device, +#endif #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) &rtc_device, @@ -1681,20 +2055,52 @@ static struct platform_device *ezkit_devices[] __initdata = { }; +/* Pin control settings */ +static struct pinctrl_map __initdata bfin_pinmux_map[] = { + /* per-device maps */ + PIN_MAP_MUX_GROUP_DEFAULT("bfin-uart.0", "pinctrl-adi2.0", NULL, "uart0"), + PIN_MAP_MUX_GROUP_DEFAULT("bfin-uart.1", "pinctrl-adi2.0", NULL, "uart1"), + PIN_MAP_MUX_GROUP_DEFAULT("bfin_sir.0", "pinctrl-adi2.0", NULL, "uart0"), + PIN_MAP_MUX_GROUP_DEFAULT("bfin_sir.1", "pinctrl-adi2.0", NULL, "uart1"), + PIN_MAP_MUX_GROUP_DEFAULT("bfin-sdh.0", "pinctrl-adi2.0", NULL, "rsi0"), + PIN_MAP_MUX_GROUP_DEFAULT("stmmaceth.0", "pinctrl-adi2.0", NULL, "eth0"), + PIN_MAP_MUX_GROUP_DEFAULT("bfin-spi3.0", "pinctrl-adi2.0", NULL, "spi0"), + PIN_MAP_MUX_GROUP_DEFAULT("bfin-spi3.1", "pinctrl-adi2.0", NULL, "spi1"), + PIN_MAP_MUX_GROUP_DEFAULT("i2c-bfin-twi.0", "pinctrl-adi2.0", NULL, "twi0"), + PIN_MAP_MUX_GROUP_DEFAULT("i2c-bfin-twi.1", "pinctrl-adi2.0", NULL, "twi1"), + PIN_MAP_MUX_GROUP_DEFAULT("bfin-rotary", "pinctrl-adi2.0", NULL, "rotary"), + PIN_MAP_MUX_GROUP_DEFAULT("bfin_can.0", "pinctrl-adi2.0", NULL, "can0"), + PIN_MAP_MUX_GROUP_DEFAULT("physmap-flash.0", "pinctrl-adi2.0", NULL, "smc0"), + PIN_MAP_MUX_GROUP_DEFAULT("bf609_nl8048.2", "pinctrl-adi2.0", NULL, "ppi2_16b"), + PIN_MAP_MUX_GROUP_DEFAULT("bfin_display.0", "pinctrl-adi2.0", NULL, "ppi0_16b"), +#if defined(CONFIG_VIDEO_MT9M114) || defined(CONFIG_VIDEO_MT9M114_MODULE) + PIN_MAP_MUX_GROUP_DEFAULT("bfin_capture.0", "pinctrl-adi2.0", NULL, "ppi0_8b"), +#elif defined(CONFIG_VIDEO_VS6624) || defined(CONFIG_VIDEO_VS6624_MODULE) + PIN_MAP_MUX_GROUP_DEFAULT("bfin_capture.0", "pinctrl-adi2.0", NULL, "ppi0_16b"), +#else + PIN_MAP_MUX_GROUP_DEFAULT("bfin_capture.0", "pinctrl-adi2.0", NULL, "ppi0_24b"), +#endif + PIN_MAP_MUX_GROUP_DEFAULT("bfin-i2s.0", "pinctrl-adi2.0", NULL, "sport0"), + PIN_MAP_MUX_GROUP_DEFAULT("bfin-tdm.0", "pinctrl-adi2.0", NULL, "sport0"), + PIN_MAP_MUX_GROUP_DEFAULT("bfin-i2s.1", "pinctrl-adi2.0", NULL, "sport1"), + PIN_MAP_MUX_GROUP_DEFAULT("bfin-tdm.1", "pinctrl-adi2.0", NULL, "sport1"), + PIN_MAP_MUX_GROUP_DEFAULT("bfin-i2s.2", "pinctrl-adi2.0", NULL, "sport2"), + PIN_MAP_MUX_GROUP_DEFAULT("bfin-tdm.2", "pinctrl-adi2.0", NULL, "sport2"), +}; + static int __init ezkit_init(void) { printk(KERN_INFO "%s(): registering device resources\n", __func__); + /* Initialize pinmuxing */ + pinctrl_register_mappings(bfin_pinmux_map, + ARRAY_SIZE(bfin_pinmux_map)); + i2c_register_board_info(0, bfin_i2c_board_info0, ARRAY_SIZE(bfin_i2c_board_info0)); i2c_register_board_info(1, bfin_i2c_board_info1, ARRAY_SIZE(bfin_i2c_board_info1)); -#if defined(CONFIG_STMMAC_ETH) || defined(CONFIG_STMMAC_ETH_MODULE) - if (!peripheral_request_list(pins, "emac0")) - printk(KERN_ERR "%s(): request emac pins failed\n", __func__); -#endif - platform_add_devices(ezkit_devices, ARRAY_SIZE(ezkit_devices)); spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); @@ -1713,18 +2119,6 @@ static struct platform_device *ezkit_early_devices[] __initdata = { &bfin_uart1_device, #endif #endif - -#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE) -#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART - &bfin_sport0_uart_device, -#endif -#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART - &bfin_sport1_uart_device, -#endif -#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART - &bfin_sport2_uart_device, -#endif -#endif }; void __init native_machine_early_platform_add_devices(void) diff --git a/arch/blackfin/mach-bf609/include/mach/gpio.h b/arch/blackfin/mach-bf609/include/mach/gpio.h index c32c8cc8db2e..07182513e794 100644 --- a/arch/blackfin/mach-bf609/include/mach/gpio.h +++ b/arch/blackfin/mach-bf609/include/mach/gpio.h @@ -152,14 +152,6 @@ struct gpio_port_t { unsigned long revid; }; -struct gpio_port_s { - unsigned short fer; - unsigned short data; - unsigned short dir; - unsigned short inen; - unsigned int mux; -}; - #endif #include <mach-common/ports-a.h> diff --git a/arch/blackfin/mach-bf609/include/mach/irq.h b/arch/blackfin/mach-bf609/include/mach/irq.h index fa0843d5d77a..d1cb6a86f80a 100644 --- a/arch/blackfin/mach-bf609/include/mach/irq.h +++ b/arch/blackfin/mach-bf609/include/mach/irq.h @@ -298,7 +298,7 @@ extern u8 sec_int_priority[]; /* - * bfin pint registers layout + * gpio pint registers layout */ struct bfin_pint_regs { u32 mask_set; diff --git a/arch/blackfin/mach-bf609/include/mach/portmux.h b/arch/blackfin/mach-bf609/include/mach/portmux.h index 2e1a51c25098..c48bb71a55ce 100644 --- a/arch/blackfin/mach-bf609/include/mach/portmux.h +++ b/arch/blackfin/mach-bf609/include/mach/portmux.h @@ -7,8 +7,6 @@ #ifndef _MACH_PORTMUX_H_ #define _MACH_PORTMUX_H_ -#define MAX_RESOURCES MAX_BLACKFIN_GPIOS - /* EMAC RMII Port Mux */ #define P_MII0_MDC (P_DEFINED | P_IDENT(GPIO_PC6) | P_FUNCT(0)) #define P_MII0_MDIO (P_DEFINED | P_IDENT(GPIO_PC7) | P_FUNCT(0)) @@ -21,6 +19,7 @@ #define P_MII0_CRS (P_DEFINED | P_IDENT(GPIO_PC5) | P_FUNCT(0)) #define P_MII0_ERxER (P_DEFINED | P_IDENT(GPIO_PC4) | P_FUNCT(0)) #define P_MII0_TxCLK (P_DEFINED | P_IDENT(GPIO_PB14) | P_FUNCT(0)) +#define P_MII0_PTPPPS (P_DEFINED | P_IDENT(GPIO_PB15) | P_FUNCT(0)) #define P_RMII0 {\ P_MII0_ETxD0, \ @@ -32,6 +31,7 @@ P_MII0_TxCLK, \ P_MII0_PHYINT, \ P_MII0_CRS, \ + P_MII0_PTPPPS, \ P_MII0_MDC, \ P_MII0_MDIO, 0} @@ -46,6 +46,7 @@ #define P_MII1_CRS (P_DEFINED | P_IDENT(GPIO_PE13) | P_FUNCT(0)) #define P_MII1_ERxER (P_DEFINED | P_IDENT(GPIO_PE14) | P_FUNCT(0)) #define P_MII1_TxCLK (P_DEFINED | P_IDENT(GPIO_PG6) | P_FUNCT(0)) +#define P_MII1_PTPPPS (P_DEFINED | P_IDENT(GPIO_PC9) | P_FUNCT(0)) #define P_RMII1 {\ P_MII1_ETxD0, \ @@ -57,6 +58,7 @@ P_MII1_TxCLK, \ P_MII1_PHYINT, \ P_MII1_CRS, \ + P_MII1_PTPPPS, \ P_MII1_MDC, \ P_MII1_MDIO, 0} diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c index d143fd8d2bc5..ca75613231c8 100644 --- a/arch/blackfin/mach-common/ints-priority.c +++ b/arch/blackfin/mach-common/ints-priority.c @@ -704,10 +704,9 @@ static inline void bfin_set_irq_handler(unsigned irq, irq_flow_handler_t handle) __irq_set_handler_locked(irq, handle); } -static DECLARE_BITMAP(gpio_enabled, MAX_BLACKFIN_GPIOS); -extern void bfin_gpio_irq_prepare(unsigned gpio); +#ifdef CONFIG_GPIO_ADI -#if !BFIN_GPIO_PINT +static DECLARE_BITMAP(gpio_enabled, MAX_BLACKFIN_GPIOS); static void bfin_gpio_ack_irq(struct irq_data *d) { @@ -821,15 +820,6 @@ static int bfin_gpio_irq_type(struct irq_data *d, unsigned int type) return 0; } -#ifdef CONFIG_PM -static int bfin_gpio_set_wake(struct irq_data *d, unsigned int state) -{ - return gpio_pm_wakeup_ctrl(irq_to_gpio(d->irq), state); -} -#else -# define bfin_gpio_set_wake NULL -#endif - static void bfin_demux_gpio_block(unsigned int irq) { unsigned int gpio, mask; @@ -896,279 +886,40 @@ void bfin_demux_gpio_irq(unsigned int inta_irq, bfin_demux_gpio_block(irq); } -#else - -#define NR_PINT_BITS 32 -#define IRQ_NOT_AVAIL 0xFF - -#define PINT_2_BANK(x) ((x) >> 5) -#define PINT_2_BIT(x) ((x) & 0x1F) -#define PINT_BIT(x) (1 << (PINT_2_BIT(x))) - -static unsigned char irq2pint_lut[NR_PINTS]; -static unsigned char pint2irq_lut[NR_PINT_SYS_IRQS * NR_PINT_BITS]; - -static struct bfin_pint_regs * const pint[NR_PINT_SYS_IRQS] = { - (struct bfin_pint_regs *)PINT0_MASK_SET, - (struct bfin_pint_regs *)PINT1_MASK_SET, - (struct bfin_pint_regs *)PINT2_MASK_SET, - (struct bfin_pint_regs *)PINT3_MASK_SET, -#ifdef CONFIG_BF60x - (struct bfin_pint_regs *)PINT4_MASK_SET, - (struct bfin_pint_regs *)PINT5_MASK_SET, -#endif -}; - -inline unsigned int get_irq_base(u32 bank, u8 bmap) -{ - unsigned int irq_base; - -#ifndef CONFIG_BF60x - if (bank < 2) { /*PA-PB */ - irq_base = IRQ_PA0 + bmap * 16; - } else { /*PC-PJ */ - irq_base = IRQ_PC0 + bmap * 16; - } -#else - irq_base = IRQ_PA0 + bank * 16 + bmap * 16; -#endif - return irq_base; -} - - /* Whenever PINTx_ASSIGN is altered init_pint_lut() must be executed! */ -void init_pint_lut(void) -{ - u16 bank, bit, irq_base, bit_pos; - u32 pint_assign; - u8 bmap; - - memset(irq2pint_lut, IRQ_NOT_AVAIL, sizeof(irq2pint_lut)); - - for (bank = 0; bank < NR_PINT_SYS_IRQS; bank++) { - - pint_assign = pint[bank]->assign; - - for (bit = 0; bit < NR_PINT_BITS; bit++) { - - bmap = (pint_assign >> ((bit / 8) * 8)) & 0xFF; - - irq_base = get_irq_base(bank, bmap); - - irq_base += (bit % 8) + ((bit / 8) & 1 ? 8 : 0); - bit_pos = bit + bank * NR_PINT_BITS; - - pint2irq_lut[bit_pos] = irq_base - SYS_IRQS; - irq2pint_lut[irq_base - SYS_IRQS] = bit_pos; - } - } -} - -static void bfin_gpio_ack_irq(struct irq_data *d) -{ - u32 pint_val = irq2pint_lut[d->irq - SYS_IRQS]; - u32 pintbit = PINT_BIT(pint_val); - u32 bank = PINT_2_BANK(pint_val); - - if (irqd_get_trigger_type(d) == IRQ_TYPE_EDGE_BOTH) { - if (pint[bank]->invert_set & pintbit) - pint[bank]->invert_clear = pintbit; - else - pint[bank]->invert_set = pintbit; - } - pint[bank]->request = pintbit; - -} - -static void bfin_gpio_mask_ack_irq(struct irq_data *d) -{ - u32 pint_val = irq2pint_lut[d->irq - SYS_IRQS]; - u32 pintbit = PINT_BIT(pint_val); - u32 bank = PINT_2_BANK(pint_val); - - if (irqd_get_trigger_type(d) == IRQ_TYPE_EDGE_BOTH) { - if (pint[bank]->invert_set & pintbit) - pint[bank]->invert_clear = pintbit; - else - pint[bank]->invert_set = pintbit; - } - - pint[bank]->request = pintbit; - pint[bank]->mask_clear = pintbit; -} - -static void bfin_gpio_mask_irq(struct irq_data *d) -{ - u32 pint_val = irq2pint_lut[d->irq - SYS_IRQS]; - - pint[PINT_2_BANK(pint_val)]->mask_clear = PINT_BIT(pint_val); -} - -static void bfin_gpio_unmask_irq(struct irq_data *d) -{ - u32 pint_val = irq2pint_lut[d->irq - SYS_IRQS]; - u32 pintbit = PINT_BIT(pint_val); - u32 bank = PINT_2_BANK(pint_val); - - pint[bank]->mask_set = pintbit; -} - -static unsigned int bfin_gpio_irq_startup(struct irq_data *d) -{ - unsigned int irq = d->irq; - u32 gpionr = irq_to_gpio(irq); - u32 pint_val = irq2pint_lut[irq - SYS_IRQS]; - - if (pint_val == IRQ_NOT_AVAIL) { - printk(KERN_ERR - "GPIO IRQ %d :Not in PINT Assign table " - "Reconfigure Interrupt to Port Assignemt\n", irq); - return -ENODEV; - } - - if (__test_and_set_bit(gpionr, gpio_enabled)) - bfin_gpio_irq_prepare(gpionr); - - bfin_gpio_unmask_irq(d); - - return 0; -} - -static void bfin_gpio_irq_shutdown(struct irq_data *d) -{ - u32 gpionr = irq_to_gpio(d->irq); - - bfin_gpio_mask_irq(d); - __clear_bit(gpionr, gpio_enabled); - bfin_gpio_irq_free(gpionr); -} - -static int bfin_gpio_irq_type(struct irq_data *d, unsigned int type) -{ - unsigned int irq = d->irq; - int ret; - char buf[16]; - u32 gpionr = irq_to_gpio(irq); - u32 pint_val = irq2pint_lut[irq - SYS_IRQS]; - u32 pintbit = PINT_BIT(pint_val); - u32 bank = PINT_2_BANK(pint_val); - - if (pint_val == IRQ_NOT_AVAIL) - return -ENODEV; - - if (type == IRQ_TYPE_PROBE) { - /* only probe unenabled GPIO interrupt lines */ - if (test_bit(gpionr, gpio_enabled)) - return 0; - type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; - } - - if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING | - IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { - - snprintf(buf, 16, "gpio-irq%d", irq); - ret = bfin_gpio_irq_request(gpionr, buf); - if (ret) - return ret; - - if (__test_and_set_bit(gpionr, gpio_enabled)) - bfin_gpio_irq_prepare(gpionr); - - } else { - __clear_bit(gpionr, gpio_enabled); - return 0; - } - - if ((type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW))) - pint[bank]->invert_set = pintbit; /* low or falling edge denoted by one */ - else - pint[bank]->invert_clear = pintbit; /* high or rising edge denoted by zero */ - - if ((type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) - == (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) { - if (gpio_get_value(gpionr)) - pint[bank]->invert_set = pintbit; - else - pint[bank]->invert_clear = pintbit; - } - - if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) { - pint[bank]->edge_set = pintbit; - bfin_set_irq_handler(irq, handle_edge_irq); - } else { - pint[bank]->edge_clear = pintbit; - bfin_set_irq_handler(irq, handle_level_irq); - } - - return 0; -} - #ifdef CONFIG_PM -static struct bfin_pm_pint_save save_pint_reg[NR_PINT_SYS_IRQS]; -static u32 save_pint_sec_ctl[NR_PINT_SYS_IRQS]; static int bfin_gpio_set_wake(struct irq_data *d, unsigned int state) { - u32 pint_irq; - u32 pint_val = irq2pint_lut[d->irq - SYS_IRQS]; - u32 bank = PINT_2_BANK(pint_val); - - switch (bank) { - case 0: - pint_irq = IRQ_PINT0; - break; - case 2: - pint_irq = IRQ_PINT2; - break; - case 3: - pint_irq = IRQ_PINT3; - break; - case 1: - pint_irq = IRQ_PINT1; - break; -#ifdef CONFIG_BF60x - case 4: - pint_irq = IRQ_PINT4; - break; - case 5: - pint_irq = IRQ_PINT5; - break; -#endif - default: - return -EINVAL; - } + return bfin_gpio_pm_wakeup_ctrl(irq_to_gpio(d->irq), state); +} -#ifndef SEC_GCTL - bfin_internal_set_wake(pint_irq, state); -#endif +#else - return 0; -} +# define bfin_gpio_set_wake NULL -void bfin_pint_suspend(void) -{ - u32 bank; +#endif - for (bank = 0; bank < NR_PINT_SYS_IRQS; bank++) { - save_pint_reg[bank].mask_set = pint[bank]->mask_set; - save_pint_reg[bank].assign = pint[bank]->assign; - save_pint_reg[bank].edge_set = pint[bank]->edge_set; - save_pint_reg[bank].invert_set = pint[bank]->invert_set; - } -} +static struct irq_chip bfin_gpio_irqchip = { + .name = "GPIO", + .irq_ack = bfin_gpio_ack_irq, + .irq_mask = bfin_gpio_mask_irq, + .irq_mask_ack = bfin_gpio_mask_ack_irq, + .irq_unmask = bfin_gpio_unmask_irq, + .irq_disable = bfin_gpio_mask_irq, + .irq_enable = bfin_gpio_unmask_irq, + .irq_set_type = bfin_gpio_irq_type, + .irq_startup = bfin_gpio_irq_startup, + .irq_shutdown = bfin_gpio_irq_shutdown, + .irq_set_wake = bfin_gpio_set_wake, +}; -void bfin_pint_resume(void) -{ - u32 bank; +#endif - for (bank = 0; bank < NR_PINT_SYS_IRQS; bank++) { - pint[bank]->mask_set = save_pint_reg[bank].mask_set; - pint[bank]->assign = save_pint_reg[bank].assign; - pint[bank]->edge_set = save_pint_reg[bank].edge_set; - pint[bank]->invert_set = save_pint_reg[bank].invert_set; - } -} +#ifdef CONFIG_PM #ifdef SEC_GCTL +static u32 save_pint_sec_ctl[NR_PINT_SYS_IRQS]; + static int sec_suspend(void) { u32 bank; @@ -1195,92 +946,10 @@ static struct syscore_ops sec_pm_syscore_ops = { .suspend = sec_suspend, .resume = sec_resume, }; - -#endif -#else -# define bfin_gpio_set_wake NULL -#endif - -void bfin_demux_gpio_irq(unsigned int inta_irq, - struct irq_desc *desc) -{ - u32 bank, pint_val; - u32 request, irq; - u32 level_mask; - int umask = 0; - struct irq_chip *chip = irq_desc_get_chip(desc); - - if (chip->irq_mask_ack) { - chip->irq_mask_ack(&desc->irq_data); - } else { - chip->irq_mask(&desc->irq_data); - if (chip->irq_ack) - chip->irq_ack(&desc->irq_data); - } - - switch (inta_irq) { - case IRQ_PINT0: - bank = 0; - break; - case IRQ_PINT2: - bank = 2; - break; - case IRQ_PINT3: - bank = 3; - break; - case IRQ_PINT1: - bank = 1; - break; -#ifdef CONFIG_BF60x - case IRQ_PINT4: - bank = 4; - break; - case IRQ_PINT5: - bank = 5; - break; #endif - default: - return; - } - - pint_val = bank * NR_PINT_BITS; - - request = pint[bank]->request; - - level_mask = pint[bank]->edge_set & request; - - while (request) { - if (request & 1) { - irq = pint2irq_lut[pint_val] + SYS_IRQS; - if (level_mask & PINT_BIT(pint_val)) { - umask = 1; - chip->irq_unmask(&desc->irq_data); - } - bfin_handle_irq(irq); - } - pint_val++; - request >>= 1; - } - if (!umask) - chip->irq_unmask(&desc->irq_data); -} #endif -static struct irq_chip bfin_gpio_irqchip = { - .name = "GPIO", - .irq_ack = bfin_gpio_ack_irq, - .irq_mask = bfin_gpio_mask_irq, - .irq_mask_ack = bfin_gpio_mask_ack_irq, - .irq_unmask = bfin_gpio_unmask_irq, - .irq_disable = bfin_gpio_mask_irq, - .irq_enable = bfin_gpio_unmask_irq, - .irq_set_type = bfin_gpio_irq_type, - .irq_startup = bfin_gpio_irq_startup, - .irq_shutdown = bfin_gpio_irq_shutdown, - .irq_set_wake = bfin_gpio_set_wake, -}; - void init_exception_vectors(void) { /* cannot program in software: @@ -1331,17 +1000,6 @@ int __init init_arch_irq(void) local_irq_disable(); -#if BFIN_GPIO_PINT -# ifdef CONFIG_PINTx_REASSIGN - pint[0]->assign = CONFIG_PINT0_ASSIGN; - pint[1]->assign = CONFIG_PINT1_ASSIGN; - pint[2]->assign = CONFIG_PINT2_ASSIGN; - pint[3]->assign = CONFIG_PINT3_ASSIGN; -# endif - /* Whenever PINTx_ASSIGN is altered init_pint_lut() must be executed! */ - init_pint_lut(); -#endif - for (irq = 0; irq <= SYS_IRQS; irq++) { if (irq <= IRQ_CORETMR) irq_set_chip(irq, &bfin_core_irqchip); @@ -1349,12 +1007,8 @@ int __init init_arch_irq(void) irq_set_chip(irq, &bfin_internal_irqchip); switch (irq) { -#if BFIN_GPIO_PINT - case IRQ_PINT0: - case IRQ_PINT1: - case IRQ_PINT2: - case IRQ_PINT3: -#elif defined(BF537_FAMILY) +#if !BFIN_GPIO_PINT +#if defined(BF537_FAMILY) case IRQ_PH_INTA_MAC_RX: case IRQ_PF_INTA_PG_INTA: #elif defined(BF533_FAMILY) @@ -1372,6 +1026,7 @@ int __init init_arch_irq(void) #endif irq_set_chained_handler(irq, bfin_demux_gpio_irq); break; +#endif #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) case IRQ_MAC_ERROR: irq_set_chained_handler(irq, @@ -1419,10 +1074,12 @@ int __init init_arch_irq(void) handle_level_irq); #endif /* if configured as edge, then will be changed to do_edge_IRQ */ +#ifdef CONFIG_GPIO_ADI for (irq = GPIO_IRQ_BASE; irq < (GPIO_IRQ_BASE + MAX_BLACKFIN_GPIOS); irq++) irq_set_chip_and_handler(irq, &bfin_gpio_irqchip, handle_level_irq); +#endif bfin_write_IMASK(0); CSYNC(); ilat = bfin_read_ILAT(); @@ -1525,19 +1182,6 @@ int __init init_arch_irq(void) local_irq_disable(); -#if BFIN_GPIO_PINT -# ifdef CONFIG_PINTx_REASSIGN - pint[0]->assign = CONFIG_PINT0_ASSIGN; - pint[1]->assign = CONFIG_PINT1_ASSIGN; - pint[2]->assign = CONFIG_PINT2_ASSIGN; - pint[3]->assign = CONFIG_PINT3_ASSIGN; - pint[4]->assign = CONFIG_PINT4_ASSIGN; - pint[5]->assign = CONFIG_PINT5_ASSIGN; -# endif - /* Whenever PINTx_ASSIGN is altered init_pint_lut() must be executed! */ - init_pint_lut(); -#endif - for (irq = 0; irq <= SYS_IRQS; irq++) { if (irq <= IRQ_CORETMR) { irq_set_chip_and_handler(irq, &bfin_core_irqchip, @@ -1546,9 +1190,6 @@ int __init init_arch_irq(void) if (irq == IRQ_CORETMR) irq_set_handler(irq, handle_percpu_irq); #endif - } else if (irq >= BFIN_IRQ(21) && irq <= BFIN_IRQ(26)) { - irq_set_chip(irq, &bfin_sec_irqchip); - irq_set_chained_handler(irq, bfin_demux_gpio_irq); } else if (irq >= BFIN_IRQ(34) && irq <= BFIN_IRQ(37)) { irq_set_chip_and_handler(irq, &bfin_sec_irqchip, handle_percpu_irq); @@ -1563,10 +1204,6 @@ int __init init_arch_irq(void) __irq_set_preflow_handler(irq, bfin_sec_preflow_handler); } } - for (irq = GPIO_IRQ_BASE; - irq < (GPIO_IRQ_BASE + MAX_BLACKFIN_GPIOS); irq++) - irq_set_chip_and_handler(irq, &bfin_gpio_irqchip, - handle_level_irq); bfin_write_IMASK(0); CSYNC(); diff --git a/arch/blackfin/mach-common/pm.c b/arch/blackfin/mach-common/pm.c index 87bfe549ad3f..1387a94bcfd5 100644 --- a/arch/blackfin/mach-common/pm.c +++ b/arch/blackfin/mach-common/pm.c @@ -27,7 +27,7 @@ struct bfin_cpu_pm_fns *bfin_cpu_pm; void bfin_pm_suspend_standby_enter(void) { -#ifndef CONFIG_BF60x +#if !BFIN_GPIO_PINT bfin_pm_standby_setup(); #endif @@ -41,7 +41,7 @@ void bfin_pm_suspend_standby_enter(void) # endif #endif -#ifndef CONFIG_BF60x +#if !BFIN_GPIO_PINT bfin_pm_standby_restore(); #endif @@ -128,6 +128,7 @@ static void flushinv_all_dcache(void) if ((status & 0x3) != 0x3) continue; + /* construct the address using the tag */ addr = (status & 0xFFFFC800) | (subbank << 12) | (set << 5); @@ -140,11 +141,14 @@ static void flushinv_all_dcache(void) int bfin_pm_suspend_mem_enter(void) { - int wakeup, ret; + int ret; +#ifndef CONFIG_BF60x + int wakeup; +#endif unsigned char *memptr = kmalloc(L1_CODE_LENGTH + L1_DATA_A_LENGTH + L1_DATA_B_LENGTH + L1_SCRATCH_LENGTH, - GFP_KERNEL); + GFP_ATOMIC); if (memptr == NULL) { panic("bf53x_suspend_l1_mem malloc failed"); @@ -170,10 +174,8 @@ int bfin_pm_suspend_mem_enter(void) return ret; } +#ifdef CONFIG_GPIO_ADI bfin_gpio_pm_hibernate_suspend(); - -#if BFIN_GPIO_PINT - bfin_pint_suspend(); #endif #if defined(CONFIG_BFIN_EXTMEM_WRITEBACK) || defined(CONFIG_BFIN_L2_WRITEBACK) @@ -194,11 +196,9 @@ int bfin_pm_suspend_mem_enter(void) _enable_icplb(); _enable_dcplb(); -#if BFIN_GPIO_PINT - bfin_pint_resume(); -#endif - +#ifdef CONFIG_GPIO_ADI bfin_gpio_pm_hibernate_restore(); +#endif blackfin_dma_resume(); kfree(memptr); diff --git a/arch/blackfin/mach-common/smp.c b/arch/blackfin/mach-common/smp.c index 82f301c117a5..2bbae0783819 100644 --- a/arch/blackfin/mach-common/smp.c +++ b/arch/blackfin/mach-common/smp.c @@ -146,6 +146,7 @@ static irqreturn_t ipi_handler_int1(int irq, void *dev_instance) platform_clear_ipi(cpu, IRQ_SUPPLE_1); + smp_rmb(); bfin_ipi_data = &__get_cpu_var(bfin_ipi); while ((pending = atomic_xchg(&bfin_ipi_data->bits, 0)) != 0) { msg = 0; @@ -161,18 +162,20 @@ static irqreturn_t ipi_handler_int1(int irq, void *dev_instance) case BFIN_IPI_CALL_FUNC: generic_smp_call_function_interrupt(); break; - case BFIN_IPI_CALL_FUNC_SINGLE: generic_smp_call_function_single_interrupt(); break; - case BFIN_IPI_CPU_STOP: ipi_cpu_stop(cpu); break; + default: + goto out; } atomic_dec(&bfin_ipi_data->count); } while (msg < BITS_PER_LONG); + } +out: return IRQ_HANDLED; } @@ -198,10 +201,11 @@ void send_ipi(const struct cpumask *cpumask, enum ipi_message_type msg) bfin_ipi_data = &per_cpu(bfin_ipi, cpu); atomic_set_mask((1 << msg), &bfin_ipi_data->bits); atomic_inc(&bfin_ipi_data->count); - platform_send_ipi_cpu(cpu, IRQ_SUPPLE_1); } - local_irq_restore(flags); + smp_wmb(); + for_each_cpu(cpu, cpumask) + platform_send_ipi_cpu(cpu, IRQ_SUPPLE_1); } void arch_send_call_function_single_ipi(int cpu) diff --git a/arch/c6x/Kconfig b/arch/c6x/Kconfig index 957dd00ea561..77ea09b8bce1 100644 --- a/arch/c6x/Kconfig +++ b/arch/c6x/Kconfig @@ -36,9 +36,6 @@ config GENERIC_HWEIGHT config GENERIC_BUG def_bool y -config COMMON_CLKDEV - def_bool y - config C6X_BIG_KERNEL bool "Build a big kernel" help @@ -105,10 +102,6 @@ menu "Processor type and features" source "arch/c6x/platforms/Kconfig" -config TMS320C6X_CACHES_ON - bool "L2 cache support" - default y - config KERNEL_RAM_BASE_ADDRESS hex "Virtual address of memory base" default 0xe0000000 if SOC_TMS320C6455 diff --git a/arch/c6x/include/asm/Kbuild b/arch/c6x/include/asm/Kbuild index e49f918531ad..fc0b3c356027 100644 --- a/arch/c6x/include/asm/Kbuild +++ b/arch/c6x/include/asm/Kbuild @@ -56,3 +56,4 @@ generic-y += ucontext.h generic-y += user.h generic-y += vga.h generic-y += xor.h +generic-y += preempt.h diff --git a/arch/c6x/include/asm/prom.h b/arch/c6x/include/asm/prom.h deleted file mode 100644 index b4ec95f07518..000000000000 --- a/arch/c6x/include/asm/prom.h +++ /dev/null @@ -1 +0,0 @@ -/* dummy prom.h; here to make linux/of.h's #includes happy */ diff --git a/arch/c6x/include/asm/setup.h b/arch/c6x/include/asm/setup.h index ecead15872a6..696804475f55 100644 --- a/arch/c6x/include/asm/setup.h +++ b/arch/c6x/include/asm/setup.h @@ -14,8 +14,6 @@ #include <uapi/asm/setup.h> #ifndef __ASSEMBLY__ -extern char c6x_command_line[COMMAND_LINE_SIZE]; - extern int c6x_add_memory(phys_addr_t start, unsigned long size); extern unsigned long ram_start; diff --git a/arch/c6x/include/asm/thread_info.h b/arch/c6x/include/asm/thread_info.h index 4c8dc562bd90..d4e9ef87076d 100644 --- a/arch/c6x/include/asm/thread_info.h +++ b/arch/c6x/include/asm/thread_info.h @@ -84,8 +84,6 @@ struct thread_info *current_thread_info(void) #define put_thread_info(ti) put_task_struct((ti)->task) #endif /* __ASSEMBLY__ */ -#define PREEMPT_ACTIVE 0x10000000 - /* * thread information flag bit numbers * - pending work-to-be-done flags are in LSW diff --git a/arch/c6x/kernel/devicetree.c b/arch/c6x/kernel/devicetree.c index 9e15ab9199b2..fa3e5741514e 100644 --- a/arch/c6x/kernel/devicetree.c +++ b/arch/c6x/kernel/devicetree.c @@ -10,37 +10,8 @@ * */ #include <linux/init.h> -#include <linux/of.h> -#include <linux/of_fdt.h> -#include <linux/initrd.h> #include <linux/memblock.h> -void __init early_init_devtree(void *params) -{ - /* Setup flat device-tree pointer */ - initial_boot_params = params; - - /* Retrieve various informations from the /chosen node of the - * device-tree, including the platform type, initrd location and - * size and more ... - */ - of_scan_flat_dt(early_init_dt_scan_chosen, c6x_command_line); - - /* Scan memory nodes and rebuild MEMBLOCKs */ - of_scan_flat_dt(early_init_dt_scan_root, NULL); - of_scan_flat_dt(early_init_dt_scan_memory, NULL); -} - - -#ifdef CONFIG_BLK_DEV_INITRD -void __init early_init_dt_setup_initrd_arch(u64 start, u64 end) -{ - initrd_start = (unsigned long)__va(start); - initrd_end = (unsigned long)__va(end); - initrd_below_start_ok = 1; -} -#endif - void __init early_init_dt_add_memory_arch(u64 base, u64 size) { c6x_add_memory(base, size); diff --git a/arch/c6x/kernel/setup.c b/arch/c6x/kernel/setup.c index f4e72bd8c103..731db4b9014d 100644 --- a/arch/c6x/kernel/setup.c +++ b/arch/c6x/kernel/setup.c @@ -68,13 +68,6 @@ unsigned long ram_end; static unsigned long dma_start __initdata; static unsigned long dma_size __initdata; -char c6x_command_line[COMMAND_LINE_SIZE]; - -#if defined(CONFIG_CMDLINE_BOOL) -static const char default_command_line[COMMAND_LINE_SIZE] __section(.cmdline) = - CONFIG_CMDLINE; -#endif - struct cpuinfo_c6x { const char *cpu_name; const char *cpu_voltage; @@ -294,10 +287,8 @@ notrace void __init machine_init(unsigned long dt_ptr) fdt = dtb; /* Do some early initialization based on the flat device tree */ - early_init_devtree(fdt); + early_init_dt_scan(fdt); - /* parse_early_param needs a boot_command_line */ - strlcpy(boot_command_line, c6x_command_line, COMMAND_LINE_SIZE); parse_early_param(); } @@ -309,7 +300,7 @@ void __init setup_arch(char **cmdline_p) printk(KERN_INFO "Initializing kernel\n"); /* Initialize command line */ - *cmdline_p = c6x_command_line; + *cmdline_p = boot_command_line; memory_end = ram_end; memory_end &= ~(PAGE_SIZE - 1); diff --git a/arch/c6x/kernel/vmlinux.lds.S b/arch/c6x/kernel/vmlinux.lds.S index 279d80725128..5a6e141d1641 100644 --- a/arch/c6x/kernel/vmlinux.lds.S +++ b/arch/c6x/kernel/vmlinux.lds.S @@ -37,12 +37,6 @@ SECTIONS _vectors_end = .; } - . = ALIGN(0x1000); - .cmdline : - { - *(.cmdline) - } - /* * This section contains data which may be shared with other * cores. It needs to be a fixed offset from PAGE_OFFSET diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig index 02380bed189c..9c957c81c688 100644 --- a/arch/cris/Kconfig +++ b/arch/cris/Kconfig @@ -130,13 +130,11 @@ config SVINTO_SIM config ETRAXFS bool "ETRAX-FS-V32" - select CPU_FREQ_TABLE if CPU_FREQ help Support CRIS V32. config CRIS_MACH_ARTPEC3 bool "ARTPEC-3" - select CPU_FREQ_TABLE if CPU_FREQ help Support Axis ARTPEC-3. diff --git a/arch/cris/include/asm/Kbuild b/arch/cris/include/asm/Kbuild index c8325455520e..b06caf649a95 100644 --- a/arch/cris/include/asm/Kbuild +++ b/arch/cris/include/asm/Kbuild @@ -11,3 +11,4 @@ generic-y += module.h generic-y += trace_clock.h generic-y += vga.h generic-y += xor.h +generic-y += preempt.h diff --git a/arch/cris/include/asm/hardirq.h b/arch/cris/include/asm/hardirq.h index 17bb12d760b2..04126f7bfab2 100644 --- a/arch/cris/include/asm/hardirq.h +++ b/arch/cris/include/asm/hardirq.h @@ -2,18 +2,6 @@ #define __ASM_HARDIRQ_H #include <asm/irq.h> - -#define HARDIRQ_BITS 8 - -/* - * The hardirq mask has to be large enough to have - * space for potentially all IRQ sources in the system - * nesting on a single CPU: - */ -#if (1 << HARDIRQ_BITS) < NR_IRQS -# error HARDIRQ_BITS is too low! -#endif - #include <asm-generic/hardirq.h> #endif /* __ASM_HARDIRQ_H */ diff --git a/arch/cris/include/asm/io.h b/arch/cris/include/asm/io.h index 5d3047e5563b..4353cf239a13 100644 --- a/arch/cris/include/asm/io.h +++ b/arch/cris/include/asm/io.h @@ -3,6 +3,7 @@ #include <asm/page.h> /* for __va, __pa */ #include <arch/io.h> +#include <asm-generic/iomap.h> #include <linux/kernel.h> struct cris_io_operations diff --git a/arch/cris/include/asm/pci.h b/arch/cris/include/asm/pci.h index 146da904cdd8..f666734926d5 100644 --- a/arch/cris/include/asm/pci.h +++ b/arch/cris/include/asm/pci.h @@ -11,7 +11,6 @@ #define pcibios_assign_all_busses(void) 1 -extern unsigned long pci_mem_start; #define PCIBIOS_MIN_IO 0x1000 #define PCIBIOS_MIN_MEM 0x10000000 diff --git a/arch/cris/include/asm/pgalloc.h b/arch/cris/include/asm/pgalloc.h index 6da975db112f..235ece437ddd 100644 --- a/arch/cris/include/asm/pgalloc.h +++ b/arch/cris/include/asm/pgalloc.h @@ -32,7 +32,12 @@ static inline pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long addres { struct page *pte; pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0); - pgtable_page_ctor(pte); + if (!pte) + return NULL; + if (!pgtable_page_ctor(pte)) { + __free_page(pte); + return NULL; + } return pte; } diff --git a/arch/cris/include/asm/thread_info.h b/arch/cris/include/asm/thread_info.h index 07c8c40c52b3..55dede18c032 100644 --- a/arch/cris/include/asm/thread_info.h +++ b/arch/cris/include/asm/thread_info.h @@ -44,8 +44,6 @@ struct thread_info { #endif -#define PREEMPT_ACTIVE 0x10000000 - /* * macros/functions for gaining access to the thread information structure */ diff --git a/arch/cris/include/uapi/asm/socket.h b/arch/cris/include/uapi/asm/socket.h index eb723e51554e..13829aaaeec5 100644 --- a/arch/cris/include/uapi/asm/socket.h +++ b/arch/cris/include/uapi/asm/socket.h @@ -78,6 +78,8 @@ #define SO_BUSY_POLL 46 +#define SO_MAX_PACING_RATE 47 + #endif /* _ASM_SOCKET_H */ diff --git a/arch/frv/include/asm/Kbuild b/arch/frv/include/asm/Kbuild index c5d767028306..74742dc6a3da 100644 --- a/arch/frv/include/asm/Kbuild +++ b/arch/frv/include/asm/Kbuild @@ -2,3 +2,4 @@ generic-y += clkdev.h generic-y += exec.h generic-y += trace_clock.h +generic-y += preempt.h diff --git a/arch/frv/include/asm/thread_info.h b/arch/frv/include/asm/thread_info.h index bebd7eadc772..af29e17c0181 100644 --- a/arch/frv/include/asm/thread_info.h +++ b/arch/frv/include/asm/thread_info.h @@ -52,8 +52,6 @@ struct thread_info { #endif -#define PREEMPT_ACTIVE 0x10000000 - /* * macros/functions for gaining access to the thread information structure */ diff --git a/arch/frv/include/uapi/asm/socket.h b/arch/frv/include/uapi/asm/socket.h index f0cb1c341163..5d4299762426 100644 --- a/arch/frv/include/uapi/asm/socket.h +++ b/arch/frv/include/uapi/asm/socket.h @@ -76,5 +76,7 @@ #define SO_BUSY_POLL 46 +#define SO_MAX_PACING_RATE 47 + #endif /* _ASM_SOCKET_H */ diff --git a/arch/frv/mb93090-mb00/pci-frv.h b/arch/frv/mb93090-mb00/pci-frv.h index 76c4e73d643d..a7e487fe76ed 100644 --- a/arch/frv/mb93090-mb00/pci-frv.h +++ b/arch/frv/mb93090-mb00/pci-frv.h @@ -30,7 +30,6 @@ void pcibios_resource_survey(void); /* pci-vdk.c */ -extern int __nongpreldata pcibios_last_bus; extern struct pci_ops *__nongpreldata pci_root_ops; /* pci-irq.c */ diff --git a/arch/frv/mb93090-mb00/pci-vdk.c b/arch/frv/mb93090-mb00/pci-vdk.c index deb67843693c..efa5d65b0007 100644 --- a/arch/frv/mb93090-mb00/pci-vdk.c +++ b/arch/frv/mb93090-mb00/pci-vdk.c @@ -25,7 +25,6 @@ unsigned int __nongpreldata pci_probe = 1; -int __nongpreldata pcibios_last_bus = -1; struct pci_ops *__nongpreldata pci_root_ops; /* @@ -220,37 +219,6 @@ static struct pci_ops * __init pci_check_direct(void) } /* - * Discover remaining PCI buses in case there are peer host bridges. - * We use the number of last PCI bus provided by the PCI BIOS. - */ -static void __init pcibios_fixup_peer_bridges(void) -{ - struct pci_bus bus; - struct pci_dev dev; - int n; - u16 l; - - if (pcibios_last_bus <= 0 || pcibios_last_bus >= 0xff) - return; - printk("PCI: Peer bridge fixup\n"); - for (n=0; n <= pcibios_last_bus; n++) { - if (pci_find_bus(0, n)) - continue; - bus.number = n; - bus.ops = pci_root_ops; - dev.bus = &bus; - for(dev.devfn=0; dev.devfn<256; dev.devfn += 8) - if (!pci_read_config_word(&dev, PCI_VENDOR_ID, &l) && - l != 0x0000 && l != 0xffff) { - printk("Found device at %02x:%02x [%04x]\n", n, dev.devfn, l); - printk("PCI: Discovered peer bus %02x\n", n); - pci_scan_bus(n, pci_root_ops, NULL); - break; - } - } -} - -/* * Exceptions for specific devices. Usually work-arounds for fatal design flaws. */ @@ -418,7 +386,6 @@ int __init pcibios_init(void) pci_scan_root_bus(NULL, 0, pci_root_ops, NULL, &resources); pcibios_irq_init(); - pcibios_fixup_peer_bridges(); pcibios_fixup_irqs(); pcibios_resource_survey(); @@ -432,9 +399,6 @@ char * __init pcibios_setup(char *str) if (!strcmp(str, "off")) { pci_probe = 0; return NULL; - } else if (!strncmp(str, "lastbus=", 8)) { - pcibios_last_bus = simple_strtol(str+8, NULL, 0); - return NULL; } return str; } diff --git a/arch/frv/mm/pgalloc.c b/arch/frv/mm/pgalloc.c index f6084bc524e8..41907d25ed38 100644 --- a/arch/frv/mm/pgalloc.c +++ b/arch/frv/mm/pgalloc.c @@ -37,11 +37,15 @@ pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address) #else page = alloc_pages(GFP_KERNEL|__GFP_REPEAT, 0); #endif - if (page) { - clear_highpage(page); - pgtable_page_ctor(page); - flush_dcache_page(page); + if (!page) + return NULL; + + clear_highpage(page); + if (!pgtable_page_ctor(page)) { + __free_page(page); + return NULL; } + flush_dcache_page(page); return page; } diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig deleted file mode 100644 index 24b1dc2564f1..000000000000 --- a/arch/h8300/Kconfig +++ /dev/null @@ -1,108 +0,0 @@ -config H8300 - bool - default y - select HAVE_IDE - select GENERIC_ATOMIC64 - select HAVE_UID16 - select VIRT_TO_BUS - select ARCH_WANT_IPC_PARSE_VERSION - select GENERIC_IRQ_SHOW - select GENERIC_CPU_DEVICES - select MODULES_USE_ELF_RELA - select OLD_SIGSUSPEND3 - select OLD_SIGACTION - select HAVE_UNDERSCORE_SYMBOL_PREFIX - -config MMU - bool - default n - -config SWAP - bool - default n - -config ZONE_DMA - bool - default y - -config FPU - bool - default n - -config RWSEM_GENERIC_SPINLOCK - bool - default y - -config RWSEM_XCHGADD_ALGORITHM - bool - default n - -config ARCH_HAS_ILOG2_U32 - bool - default n - -config ARCH_HAS_ILOG2_U64 - bool - default n - -config GENERIC_HWEIGHT - bool - default y - -config GENERIC_CALIBRATE_DELAY - bool - default y - -config GENERIC_BUG - bool - depends on BUG - -config TIME_LOW_RES - bool - default y - -config NO_IOPORT - def_bool y - -config NO_DMA - def_bool y - -config ISA - bool - default y - -config PCI - bool - default n - -config HZ - int - default 100 - -source "init/Kconfig" - -source "kernel/Kconfig.freezer" - -source "arch/h8300/Kconfig.cpu" - -menu "Executable file formats" - -source "fs/Kconfig.binfmt" - -endmenu - -source "net/Kconfig" - -source "drivers/Kconfig" - -source "arch/h8300/Kconfig.ide" - -source "fs/Kconfig" - -source "arch/h8300/Kconfig.debug" - -source "security/Kconfig" - -source "crypto/Kconfig" - -source "lib/Kconfig" diff --git a/arch/h8300/Kconfig.cpu b/arch/h8300/Kconfig.cpu deleted file mode 100644 index cdee771460ed..000000000000 --- a/arch/h8300/Kconfig.cpu +++ /dev/null @@ -1,171 +0,0 @@ -menu "Processor type and features" - -choice - prompt "H8/300 platform" - default H8300H_GENERIC - -config H8300H_GENERIC - bool "H8/300H Generic" - help - H8/300H CPU Generic Hardware Support - -config H8300H_AKI3068NET - bool "AE-3068/69" - select H83068 - help - AKI-H8/3068F / AKI-H8/3069F Flashmicom LAN Board Support - More Information. (Japanese Only) - <http://akizukidenshi.com/catalog/default.aspx> - AE-3068/69 Evaluation Board Support - More Information. - <http://www.microtronique.com/ae3069lan.htm> - -config H8300H_H8MAX - bool "H8MAX" - select H83068 - help - H8MAX Evaluation Board Support - More Information. (Japanese Only) - <http://strawberry-linux.com/h8/index.html> - -config H8300H_SIM - bool "H8/300H Simulator" - select H83007 - help - GDB Simulator Support - More Information. - <http://sourceware.org/sid/> - -config H8S_GENERIC - bool "H8S Generic" - help - H8S CPU Generic Hardware Support - -config H8S_EDOSK2674 - bool "EDOSK-2674" - select H8S2678 - help - Renesas EDOSK-2674 Evaluation Board Support - More Information. - <http://www.azpower.com/H8-uClinux/index.html> - <http://www.renesas.eu/products/tools/introductory_evaluation_tools/evaluation_development_os_kits/edosk2674r/edosk2674r_software_tools_root.jsp> - -config H8S_SIM - bool "H8S Simulator" - help - GDB Simulator Support - More Information. - <http://sourceware.org/sid/> - -endchoice - -choice - prompt "CPU Selection" - -config H83002 - bool "H8/3001,3002,3003" - depends on BROKEN - select CPU_H8300H - -config H83007 - bool "H8/3006,3007" - select CPU_H8300H - -config H83048 - bool "H8/3044,3045,3046,3047,3048,3052" - depends on BROKEN - select CPU_H8300H - -config H83068 - bool "H8/3065,3066,3067,3068,3069" - select CPU_H8300H - -config H8S2678 - bool "H8S/2670,2673,2674R,2675,2676" - select CPU_H8S - -endchoice - -config CPU_CLOCK - int "CPU Clock Frequency (/1KHz)" - default "20000" - help - CPU Clock Frequency divide to 1000 - -choice - prompt "Kernel executes from" - ---help--- - Choose the memory type that the kernel will be running in. - -config RAMKERNEL - bool "RAM" - help - The kernel will be resident in RAM when running. - -config ROMKERNEL - bool "ROM" - help - The kernel will be resident in FLASH/ROM when running. -endchoice - - -config CPU_H8300H - bool - depends on (H83002 || H83007 || H83048 || H83068) - default y - -config CPU_H8S - bool - depends on H8S2678 - default y - -choice - prompt "Timer" -config H8300_TIMER8 - bool "8bit timer (2ch cascade)" - depends on (H83007 || H83068 || H8S2678) - -config H8300_TIMER16 - bool "16bit timer" - depends on (H83007 || H83068) - -config H8300_ITU - bool "ITU" - depends on (H83002 || H83048) - -config H8300_TPU - bool "TPU" - depends on H8S2678 -endchoice - -if H8300_TIMER8 -choice - prompt "Timer Channel" -config H8300_TIMER8_CH0 - bool "Channel 0" -config H8300_TIMER8_CH2 - bool "Channel 2" - depends on CPU_H8300H -endchoice -endif - -config H8300_TIMER16_CH - int "16bit timer channel (0 - 2)" - depends on H8300_TIMER16 - range 0 2 - -config H8300_ITU_CH - int "ITU channel" - depends on H8300_ITU - range 0 4 - -config H8300_TPU_CH - int "TPU channel" - depends on H8300_TPU - range 0 4 - -source "kernel/Kconfig.preempt" - -source "mm/Kconfig" - -endmenu diff --git a/arch/h8300/Kconfig.debug b/arch/h8300/Kconfig.debug deleted file mode 100644 index e8d1b236ad8c..000000000000 --- a/arch/h8300/Kconfig.debug +++ /dev/null @@ -1,68 +0,0 @@ -menu "Kernel hacking" - -source "lib/Kconfig.debug" - -config FULLDEBUG - bool "Full Symbolic/Source Debugging support" - help - Enable debugging symbols on kernel build. - -config HIGHPROFILE - bool "Use fast second timer for profiling" - help - Use a fast secondary clock to produce profiling information. - -config NO_KERNEL_MSG - bool "Suppress Kernel BUG Messages" - help - Do not output any debug BUG messages within the kernel. - -config GDB_MAGICPRINT - bool "Message Output for GDB MagicPrint service" - depends on (H8300H_SIM || H8S_SIM) - help - kernel messages output using MagicPrint service from GDB - -config SYSCALL_PRINT - bool "SystemCall trace print" - help - output history of systemcall - -config GDB_DEBUG - bool "Use gdb stub" - depends on (!H8300H_SIM && !H8S_SIM) - help - gdb stub exception support - -config SH_STANDARD_BIOS - bool "Use gdb protocol serial console" - depends on (!H8300H_SIM && !H8S_SIM) - help - serial console output using GDB protocol. - Require eCos/RedBoot - -config DEFAULT_CMDLINE - bool "Use builtin commandline" - default n - help - builtin kernel commandline enabled. - -config KERNEL_COMMAND - string "Buildin command string" - depends on DEFAULT_CMDLINE - help - builtin kernel commandline strings. - -config BLKDEV_RESERVE - bool "BLKDEV Reserved Memory" - default n - help - Reserved BLKDEV area. - -config BLKDEV_RESERVE_ADDRESS - hex 'start address' - depends on BLKDEV_RESERVE - help - BLKDEV start address. - -endmenu diff --git a/arch/h8300/Kconfig.ide b/arch/h8300/Kconfig.ide deleted file mode 100644 index a38a63054ac2..000000000000 --- a/arch/h8300/Kconfig.ide +++ /dev/null @@ -1,44 +0,0 @@ -# uClinux H8/300 Target Board Selection Menu (IDE) - -if (H8300H_AKI3068NET) -menu "IDE Extra configuration" - -config H8300_IDE_BASE - hex "IDE register base address" - depends on IDE - default 0 - help - IDE registers base address - -config H8300_IDE_ALT - hex "IDE register alternate address" - depends on IDE - default 0 - help - IDE alternate registers address - -config H8300_IDE_IRQ - int "IDE IRQ no" - depends on IDE - default 0 - help - IDE use IRQ no -endmenu -endif - -if (H8300H_H8MAX) -config H8300_IDE_BASE - hex - depends on IDE - default 0x200000 - -config H8300_IDE_ALT - hex - depends on IDE - default 0x60000c - -config H8300_IDE_IRQ - int - depends on IDE - default 5 -endif diff --git a/arch/h8300/Makefile b/arch/h8300/Makefile deleted file mode 100644 index a556447877b4..000000000000 --- a/arch/h8300/Makefile +++ /dev/null @@ -1,71 +0,0 @@ -# -# arch/h8300/Makefile -# -# This file is subject to the terms and conditions of the GNU General Public -# License. See the file "COPYING" in the main directory of this archive -# for more details. -# -# (C) Copyright 2002,2003 Yoshinori Sato <ysato@users.sourceforge.jp> -# - -platform-$(CONFIG_CPU_H8300H) := h8300h -platform-$(CONFIG_CPU_H8S) := h8s -PLATFORM := $(platform-y) - -board-$(CONFIG_H8300H_GENERIC) := generic -board-$(CONFIG_H8300H_AKI3068NET) := aki3068net -board-$(CONFIG_H8300H_H8MAX) := h8max -board-$(CONFIG_H8300H_SIM) := generic -board-$(CONFIG_H8S_GENERIC) := generic -board-$(CONFIG_H8S_EDOSK2674) := edosk2674 -board-$(CONFIG_H8S_SIM) := generic -BOARD := $(board-y) - -model-$(CONFIG_RAMKERNEL) := ram -model-$(CONFIG_ROMKERNEL) := rom -MODEL := $(model-y) - -cflags-$(CONFIG_CPU_H8300H) := -mh -ldflags-$(CONFIG_CPU_H8300H) := -mh8300helf -cflags-$(CONFIG_CPU_H8S) := -ms -ldflags-$(CONFIG_CPU_H8S) := -mh8300self - -KBUILD_CFLAGS += $(cflags-y) -KBUILD_CFLAGS += -mint32 -fno-builtin -KBUILD_CFLAGS += -g -KBUILD_CFLAGS += -D__linux__ -KBUILD_CFLAGS += -DUTS_SYSNAME=\"uClinux\" -KBUILD_AFLAGS += -DPLATFORM=$(PLATFORM) -DMODEL=$(MODEL) $(cflags-y) -LDFLAGS += $(ldflags-y) - -CROSS_COMPILE = h8300-elf- -LIBGCC := $(shell $(CROSS-COMPILE)$(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name) - -head-y := arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/crt0_$(MODEL).o - -core-y += arch/$(ARCH)/kernel/ \ - arch/$(ARCH)/mm/ -ifdef PLATFORM -core-y += arch/$(ARCH)/platform/$(PLATFORM)/ \ - arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/ -endif - -libs-y += arch/$(ARCH)/lib/ $(LIBGCC) - -boot := arch/h8300/boot - -export MODEL PLATFORM BOARD - -archmrproper: - -archclean: - $(Q)$(MAKE) $(clean)=$(boot) - -vmlinux.srec vmlinux.bin zImage: vmlinux - $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ - -define archhelp - @echo 'vmlinux.bin - Create raw binary' - @echo 'vmlinux.srec - Create srec binary' - @echo 'zImage - Compressed kernel image' -endef diff --git a/arch/h8300/README b/arch/h8300/README deleted file mode 100644 index efa805fda19b..000000000000 --- a/arch/h8300/README +++ /dev/null @@ -1,38 +0,0 @@ -linux-2.6 for H8/300 README -Yoshinori Sato <ysato@users.sourceforge.jp> - -* Supported CPU -H8/300H and H8S - -* Supported Target -1.simulator of GDB - require patches. - -2.AE 3068/AE 3069 - more information - MICROTRONIQUE <http://www.microtronique.com/> - Akizuki Denshi Tsusho Ltd. <http://akizukidenshi.com/> (Japanese Only) - -3.H8MAX - see http://ip-sol.jp/h8max/ (Japanese Only) - -4.EDOSK2674 - see http://www.eu.renesas.com/products/mpumcu/tool/edk/support/edosk2674.html - http://www.uclinux.org/pub/uClinux/ports/h8/HITACHI-EDOSK2674-HOWTO - http://www.azpower.com/H8-uClinux/ - -* Toolchain Version -gcc-3.1 or higher and patch -see arch/h8300/tools_patch/README -binutils-2.12 or higher -gdb-5.2 or higher -The environment that can compile a h8300-elf binary is necessary. - -* Userland Develop environment -used h8300-elf toolchains. -see http://www.uclinux.org/pub/uClinux/ports/h8/ - -* A few words of thanks -Porting to H8/300 serieses is support of Information-technology Promotion Agency, Japan. -I thank support. -and All developer/user. diff --git a/arch/h8300/boot/Makefile b/arch/h8300/boot/Makefile deleted file mode 100644 index 0bb62e064eea..000000000000 --- a/arch/h8300/boot/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -# arch/h8300/boot/Makefile - -targets := vmlinux.srec vmlinux.bin zImage -subdir- := compressed - -OBJCOPYFLAGS_vmlinux.srec := -Osrec -OBJCOPYFLAGS_vmlinux.bin := -Obinary -OBJCOPYFLAGS_zImage := -O binary -R .note -R .comment -R .stab -R .stabstr -S - -$(obj)/vmlinux.srec $(obj)/vmlinux.bin: vmlinux FORCE - $(call if_changed,objcopy) - @echo ' Kernel: $@ is ready' - -$(obj)/zImage: $(obj)/compressed/vmlinux FORCE - $(call if_changed,objcopy) - @echo 'Kernel: $@ is ready' - -$(obj)/compressed/vmlinux: FORCE - $(Q)$(MAKE) $(build)=$(obj)/compressed $@ - -CLEAN_FILES += arch/$(ARCH)/vmlinux.bin arch/$(ARCH)/vmlinux.srec - diff --git a/arch/h8300/boot/compressed/Makefile b/arch/h8300/boot/compressed/Makefile deleted file mode 100644 index a6c98fe3bbc3..000000000000 --- a/arch/h8300/boot/compressed/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -# -# linux/arch/sh/boot/compressed/Makefile -# -# create a compressed vmlinux image from the original vmlinux -# - -targets := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o -asflags-y := -traditional - -OBJECTS = $(obj)/head.o $(obj)/misc.o - -# -# IMAGE_OFFSET is the load offset of the compression loader -# Assign dummy values if these 2 variables are not defined, -# in order to suppress error message. -# -CONFIG_MEMORY_START ?= 0x00400000 -CONFIG_BOOT_LINK_OFFSET ?= 0x00140000 -IMAGE_OFFSET := $(shell printf "0x%08x" $$(($(CONFIG_MEMORY_START)+$(CONFIG_BOOT_LINK_OFFSET)))) - -LDFLAGS_vmlinux := -Ttext $(IMAGE_OFFSET) -estartup $(obj)/vmlinux.lds - -$(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o FORCE - $(call if_changed,ld) - @: - -$(obj)/vmlinux.bin: vmlinux FORCE - $(call if_changed,objcopy) - -$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE - $(call if_changed,gzip) - -LDFLAGS_piggy.o := -r --format binary --oformat elf32-h8300 -T -OBJCOPYFLAGS := -O binary - -$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.gz FORCE - $(call if_changed,ld) diff --git a/arch/h8300/boot/compressed/head.S b/arch/h8300/boot/compressed/head.S deleted file mode 100644 index 10e9a2d1cc6c..000000000000 --- a/arch/h8300/boot/compressed/head.S +++ /dev/null @@ -1,47 +0,0 @@ -/* - * linux/arch/h8300/boot/compressed/head.S - * - * Copyright (C) 2006 Yoshinori Sato - */ - - .h8300h -#include <linux/linkage.h> - -#define SRAM_START 0xff4000 - - .section .text..startup - .global startup -startup: - mov.l #SRAM_START+0x8000, sp - mov.l #__sbss, er0 - mov.l #__ebss, er1 - sub.l er0, er1 - shlr er1 - shlr er1 - sub.l er2, er2 -1: - mov.l er2, @er0 - adds #4, er0 - dec.l #1, er1 - bne 1b - jsr @_decompress_kernel - jmp @0x400000 - - .align 9 -fake_headers_as_bzImage: - .word 0 - .ascii "HdrS" ; header signature - .word 0x0202 ; header version number (>= 0x0105) - ; or else old loadlin-1.5 will fail) - .word 0 ; default_switch - .word 0 ; SETUPSEG - .word 0x1000 - .word 0 ; pointing to kernel version string - .byte 0 ; = 0, old one (LILO, Loadlin, - ; 0xTV: T=0 for LILO - ; V = version - .byte 1 ; Load flags bzImage=1 - .word 0x8000 ; size to move, when setup is not - .long 0x100000 ; 0x100000 = default for big kernel - .long 0 ; address of loaded ramdisk image - .long 0 ; its size in bytes diff --git a/arch/h8300/boot/compressed/misc.c b/arch/h8300/boot/compressed/misc.c deleted file mode 100644 index 4a1e3dd43948..000000000000 --- a/arch/h8300/boot/compressed/misc.c +++ /dev/null @@ -1,180 +0,0 @@ -/* - * arch/h8300/boot/compressed/misc.c - * - * This is a collection of several routines from gzip-1.0.3 - * adapted for Linux. - * - * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994 - * - * Adapted for h8300 by Yoshinori Sato 2006 - */ - -#include <asm/uaccess.h> - -/* - * gzip declarations - */ - -#define OF(args) args -#define STATIC static - -#undef memset -#undef memcpy -#define memzero(s, n) memset ((s), 0, (n)) - -typedef unsigned char uch; -typedef unsigned short ush; -typedef unsigned long ulg; - -#define WSIZE 0x8000 /* Window size must be at least 32k, */ - /* and a power of two */ - -static uch *inbuf; /* input buffer */ -static uch window[WSIZE]; /* Sliding window buffer */ - -static unsigned insize = 0; /* valid bytes in inbuf */ -static unsigned inptr = 0; /* index of next byte to be processed in inbuf */ -static unsigned outcnt = 0; /* bytes in output buffer */ - -/* gzip flag byte */ -#define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */ -#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ -#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ -#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ -#define COMMENT 0x10 /* bit 4 set: file comment present */ -#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ -#define RESERVED 0xC0 /* bit 6,7: reserved */ - -#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) - -/* Diagnostic functions */ -#ifdef DEBUG -# define Assert(cond,msg) {if(!(cond)) error(msg);} -# define Trace(x) fprintf x -# define Tracev(x) {if (verbose) fprintf x ;} -# define Tracevv(x) {if (verbose>1) fprintf x ;} -# define Tracec(c,x) {if (verbose && (c)) fprintf x ;} -# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;} -#else -# define Assert(cond,msg) -# define Trace(x) -# define Tracev(x) -# define Tracevv(x) -# define Tracec(c,x) -# define Tracecv(c,x) -#endif - -static int fill_inbuf(void); -static void flush_window(void); -static void error(char *m); - -extern char input_data[]; -extern int input_len; - -static long bytes_out = 0; -static uch *output_data; -static unsigned long output_ptr = 0; - -static void error(char *m); - -int puts(const char *); - -extern int _end; -static unsigned long free_mem_ptr; -static unsigned long free_mem_end_ptr; - -#define HEAP_SIZE 0x10000 - -#include "../../../../lib/inflate.c" - -#define SCR *((volatile unsigned char *)0xffff8a) -#define TDR *((volatile unsigned char *)0xffff8b) -#define SSR *((volatile unsigned char *)0xffff8c) - -int puts(const char *s) -{ - return 0; -} - -void* memset(void* s, int c, size_t n) -{ - int i; - char *ss = (char*)s; - - for (i=0;i<n;i++) ss[i] = c; - return s; -} - -void* memcpy(void* __dest, __const void* __src, - size_t __n) -{ - int i; - char *d = (char *)__dest, *s = (char *)__src; - - for (i=0;i<__n;i++) d[i] = s[i]; - return __dest; -} - -/* =========================================================================== - * Fill the input buffer. This is called only when the buffer is empty - * and at least one byte is really needed. - */ -static int fill_inbuf(void) -{ - if (insize != 0) { - error("ran out of input data"); - } - - inbuf = input_data; - insize = input_len; - inptr = 1; - return inbuf[0]; -} - -/* =========================================================================== - * Write the output window window[0..outcnt-1] and update crc and bytes_out. - * (Used for the decompressed data only.) - */ -static void flush_window(void) -{ - ulg c = crc; /* temporary variable */ - unsigned n; - uch *in, *out, ch; - - in = window; - out = &output_data[output_ptr]; - for (n = 0; n < outcnt; n++) { - ch = *out++ = *in++; - c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); - } - crc = c; - bytes_out += (ulg)outcnt; - output_ptr += (ulg)outcnt; - outcnt = 0; -} - -static void error(char *x) -{ - puts("\n\n"); - puts(x); - puts("\n\n -- System halted"); - - while(1); /* Halt */ -} - -#define STACK_SIZE (4096) -long user_stack [STACK_SIZE]; -long* stack_start = &user_stack[STACK_SIZE]; - -void decompress_kernel(void) -{ - output_data = 0; - output_ptr = (unsigned long)0x400000; - free_mem_ptr = (unsigned long)&_end; - free_mem_end_ptr = free_mem_ptr + HEAP_SIZE; - - makecrc(); - puts("Uncompressing Linux... "); - gunzip(); - puts("Ok, booting the kernel.\n"); -} diff --git a/arch/h8300/boot/compressed/vmlinux.lds b/arch/h8300/boot/compressed/vmlinux.lds deleted file mode 100644 index a0a3a0ed54ef..000000000000 --- a/arch/h8300/boot/compressed/vmlinux.lds +++ /dev/null @@ -1,32 +0,0 @@ -SECTIONS -{ - .text : - { - __stext = . ; - __text = .; - *(.text..startup) - *(.text) - __etext = . ; - } - - .rodata : - { - *(.rodata) - } - .data : - - { - __sdata = . ; - ___data_start = . ; - *(.data.*) - } - .bss : - { - . = ALIGN(0x4) ; - __sbss = . ; - *(.bss*) - . = ALIGN(0x4) ; - __ebss = . ; - __end = . ; - } -} diff --git a/arch/h8300/boot/compressed/vmlinux.scr b/arch/h8300/boot/compressed/vmlinux.scr deleted file mode 100644 index a0f6962736e9..000000000000 --- a/arch/h8300/boot/compressed/vmlinux.scr +++ /dev/null @@ -1,9 +0,0 @@ -SECTIONS -{ - .data : { - _input_len = .; - LONG(_input_data_end - _input_data) _input_data = .; - *(.data) - _input_data_end = .; - } -} diff --git a/arch/h8300/defconfig b/arch/h8300/defconfig deleted file mode 100644 index 042425a02645..000000000000 --- a/arch/h8300/defconfig +++ /dev/null @@ -1,42 +0,0 @@ -CONFIG_EXPERIMENTAL=y -# CONFIG_LOCALVERSION_AUTO is not set -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_EXPERT=y -# CONFIG_UID16 is not set -# CONFIG_SYSCTL_SYSCALL is not set -# CONFIG_KALLSYMS is not set -# CONFIG_HOTPLUG is not set -# CONFIG_BASE_FULL is not set -# CONFIG_FUTEX is not set -# CONFIG_EPOLL is not set -# CONFIG_SIGNALFD is not set -# CONFIG_TIMERFD is not set -# CONFIG_EVENTFD is not set -# CONFIG_VM_EVENT_COUNTERS is not set -# CONFIG_COMPAT_BRK is not set -CONFIG_SLOB=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_IOSCHED_CFQ is not set -CONFIG_H83007=y -CONFIG_BINFMT_FLAT=y -CONFIG_BINFMT_ZFLAT=y -CONFIG_BINFMT_MISC=y -# CONFIG_PREVENT_FIRMWARE_BUILD is not set -CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_REDBOOT_PARTS=y -CONFIG_MTD_CHAR=y -CONFIG_MTD_RAM=y -CONFIG_MTD_ROM=y -CONFIG_MTD_UCLINUX=y -# CONFIG_BLK_DEV is not set -# CONFIG_INPUT is not set -# CONFIG_SERIO is not set -# CONFIG_HWMON is not set -# CONFIG_USB_SUPPORT is not set -# CONFIG_DNOTIFY is not set -CONFIG_ROMFS_FS=y -# CONFIG_ENABLE_WARN_DEPRECATED is not set -# CONFIG_ENABLE_MUST_CHECK is not set -# CONFIG_CRC32 is not set diff --git a/arch/h8300/include/asm/Kbuild b/arch/h8300/include/asm/Kbuild deleted file mode 100644 index 8ada3cf0c98d..000000000000 --- a/arch/h8300/include/asm/Kbuild +++ /dev/null @@ -1,8 +0,0 @@ - -generic-y += clkdev.h -generic-y += exec.h -generic-y += linkage.h -generic-y += mmu.h -generic-y += module.h -generic-y += trace_clock.h -generic-y += xor.h diff --git a/arch/h8300/include/asm/asm-offsets.h b/arch/h8300/include/asm/asm-offsets.h deleted file mode 100644 index d370ee36a182..000000000000 --- a/arch/h8300/include/asm/asm-offsets.h +++ /dev/null @@ -1 +0,0 @@ -#include <generated/asm-offsets.h> diff --git a/arch/h8300/include/asm/atomic.h b/arch/h8300/include/asm/atomic.h deleted file mode 100644 index 40901e353c21..000000000000 --- a/arch/h8300/include/asm/atomic.h +++ /dev/null @@ -1,146 +0,0 @@ -#ifndef __ARCH_H8300_ATOMIC__ -#define __ARCH_H8300_ATOMIC__ - -#include <linux/types.h> -#include <asm/cmpxchg.h> - -/* - * Atomic operations that C can't guarantee us. Useful for - * resource counting etc.. - */ - -#define ATOMIC_INIT(i) { (i) } - -#define atomic_read(v) (*(volatile int *)&(v)->counter) -#define atomic_set(v, i) (((v)->counter) = i) - -#include <linux/kernel.h> - -static __inline__ int atomic_add_return(int i, atomic_t *v) -{ - unsigned long flags; - int ret; - local_irq_save(flags); - ret = v->counter += i; - local_irq_restore(flags); - return ret; -} - -#define atomic_add(i, v) atomic_add_return(i, v) -#define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0) - -static __inline__ int atomic_sub_return(int i, atomic_t *v) -{ - unsigned long flags; - int ret; - local_irq_save(flags); - ret = v->counter -= i; - local_irq_restore(flags); - return ret; -} - -#define atomic_sub(i, v) atomic_sub_return(i, v) -#define atomic_sub_and_test(i,v) (atomic_sub_return(i, v) == 0) - -static __inline__ int atomic_inc_return(atomic_t *v) -{ - unsigned long flags; - int ret; - local_irq_save(flags); - v->counter++; - ret = v->counter; - local_irq_restore(flags); - return ret; -} - -#define atomic_inc(v) atomic_inc_return(v) - -/* - * atomic_inc_and_test - increment and test - * @v: pointer of type atomic_t - * - * Atomically increments @v by 1 - * and returns true if the result is zero, or false for all - * other cases. - */ -#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0) - -static __inline__ int atomic_dec_return(atomic_t *v) -{ - unsigned long flags; - int ret; - local_irq_save(flags); - --v->counter; - ret = v->counter; - local_irq_restore(flags); - return ret; -} - -#define atomic_dec(v) atomic_dec_return(v) - -static __inline__ int atomic_dec_and_test(atomic_t *v) -{ - unsigned long flags; - int ret; - local_irq_save(flags); - --v->counter; - ret = v->counter; - local_irq_restore(flags); - return ret == 0; -} - -static inline int atomic_cmpxchg(atomic_t *v, int old, int new) -{ - int ret; - unsigned long flags; - - local_irq_save(flags); - ret = v->counter; - if (likely(ret == old)) - v->counter = new; - local_irq_restore(flags); - return ret; -} - -static inline int __atomic_add_unless(atomic_t *v, int a, int u) -{ - int ret; - unsigned long flags; - - local_irq_save(flags); - ret = v->counter; - if (ret != u) - v->counter += a; - local_irq_restore(flags); - return ret; -} - -static __inline__ void atomic_clear_mask(unsigned long mask, unsigned long *v) -{ - __asm__ __volatile__("stc ccr,r1l\n\t" - "orc #0x80,ccr\n\t" - "mov.l %0,er0\n\t" - "and.l %1,er0\n\t" - "mov.l er0,%0\n\t" - "ldc r1l,ccr" - : "=m" (*v) : "g" (~(mask)) :"er0","er1"); -} - -static __inline__ void atomic_set_mask(unsigned long mask, unsigned long *v) -{ - __asm__ __volatile__("stc ccr,r1l\n\t" - "orc #0x80,ccr\n\t" - "mov.l %0,er0\n\t" - "or.l %1,er0\n\t" - "mov.l er0,%0\n\t" - "ldc r1l,ccr" - : "=m" (*v) : "g" (mask) :"er0","er1"); -} - -/* Atomic operations are already serializing */ -#define smp_mb__before_atomic_dec() barrier() -#define smp_mb__after_atomic_dec() barrier() -#define smp_mb__before_atomic_inc() barrier() -#define smp_mb__after_atomic_inc() barrier() - -#endif /* __ARCH_H8300_ATOMIC __ */ diff --git a/arch/h8300/include/asm/barrier.h b/arch/h8300/include/asm/barrier.h deleted file mode 100644 index 9e0aa9fc195d..000000000000 --- a/arch/h8300/include/asm/barrier.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef _H8300_BARRIER_H -#define _H8300_BARRIER_H - -#define nop() asm volatile ("nop"::) - -/* - * Force strict CPU ordering. - * Not really required on H8... - */ -#define mb() asm volatile ("" : : :"memory") -#define rmb() asm volatile ("" : : :"memory") -#define wmb() asm volatile ("" : : :"memory") -#define set_mb(var, value) do { xchg(&var, value); } while (0) - -#define read_barrier_depends() do { } while (0) - -#ifdef CONFIG_SMP -#define smp_mb() mb() -#define smp_rmb() rmb() -#define smp_wmb() wmb() -#define smp_read_barrier_depends() read_barrier_depends() -#else -#define smp_mb() barrier() -#define smp_rmb() barrier() -#define smp_wmb() barrier() -#define smp_read_barrier_depends() do { } while(0) -#endif - -#endif /* _H8300_BARRIER_H */ diff --git a/arch/h8300/include/asm/bitops.h b/arch/h8300/include/asm/bitops.h deleted file mode 100644 index eb34e0cd33d5..000000000000 --- a/arch/h8300/include/asm/bitops.h +++ /dev/null @@ -1,211 +0,0 @@ -#ifndef _H8300_BITOPS_H -#define _H8300_BITOPS_H - -/* - * Copyright 1992, Linus Torvalds. - * Copyright 2002, Yoshinori Sato - */ - -#include <linux/compiler.h> - -#ifdef __KERNEL__ - -#ifndef _LINUX_BITOPS_H -#error only <linux/bitops.h> can be included directly -#endif - -/* - * Function prototypes to keep gcc -Wall happy - */ - -/* - * ffz = Find First Zero in word. Undefined if no zero exists, - * so code should check against ~0UL first.. - */ -static __inline__ unsigned long ffz(unsigned long word) -{ - unsigned long result; - - result = -1; - __asm__("1:\n\t" - "shlr.l %2\n\t" - "adds #1,%0\n\t" - "bcs 1b" - : "=r" (result) - : "0" (result),"r" (word)); - return result; -} - -#define H8300_GEN_BITOP_CONST(OP,BIT) \ - case BIT: \ - __asm__(OP " #" #BIT ",@%0"::"r"(b_addr):"memory"); \ - break; - -#define H8300_GEN_BITOP(FNAME,OP) \ -static __inline__ void FNAME(int nr, volatile unsigned long* addr) \ -{ \ - volatile unsigned char *b_addr; \ - b_addr = (volatile unsigned char *)addr + ((nr >> 3) ^ 3); \ - if (__builtin_constant_p(nr)) { \ - switch(nr & 7) { \ - H8300_GEN_BITOP_CONST(OP,0) \ - H8300_GEN_BITOP_CONST(OP,1) \ - H8300_GEN_BITOP_CONST(OP,2) \ - H8300_GEN_BITOP_CONST(OP,3) \ - H8300_GEN_BITOP_CONST(OP,4) \ - H8300_GEN_BITOP_CONST(OP,5) \ - H8300_GEN_BITOP_CONST(OP,6) \ - H8300_GEN_BITOP_CONST(OP,7) \ - } \ - } else { \ - __asm__(OP " %w0,@%1"::"r"(nr),"r"(b_addr):"memory"); \ - } \ -} - -/* - * clear_bit() doesn't provide any barrier for the compiler. - */ -#define smp_mb__before_clear_bit() barrier() -#define smp_mb__after_clear_bit() barrier() - -H8300_GEN_BITOP(set_bit ,"bset") -H8300_GEN_BITOP(clear_bit ,"bclr") -H8300_GEN_BITOP(change_bit,"bnot") -#define __set_bit(nr,addr) set_bit((nr),(addr)) -#define __clear_bit(nr,addr) clear_bit((nr),(addr)) -#define __change_bit(nr,addr) change_bit((nr),(addr)) - -#undef H8300_GEN_BITOP -#undef H8300_GEN_BITOP_CONST - -static __inline__ int test_bit(int nr, const unsigned long* addr) -{ - return (*((volatile unsigned char *)addr + - ((nr >> 3) ^ 3)) & (1UL << (nr & 7))) != 0; -} - -#define __test_bit(nr, addr) test_bit(nr, addr) - -#define H8300_GEN_TEST_BITOP_CONST_INT(OP,BIT) \ - case BIT: \ - __asm__("stc ccr,%w1\n\t" \ - "orc #0x80,ccr\n\t" \ - "bld #" #BIT ",@%4\n\t" \ - OP " #" #BIT ",@%4\n\t" \ - "rotxl.l %0\n\t" \ - "ldc %w1,ccr" \ - : "=r"(retval),"=&r"(ccrsave),"=m"(*b_addr) \ - : "0" (retval),"r" (b_addr) \ - : "memory"); \ - break; - -#define H8300_GEN_TEST_BITOP_CONST(OP,BIT) \ - case BIT: \ - __asm__("bld #" #BIT ",@%3\n\t" \ - OP " #" #BIT ",@%3\n\t" \ - "rotxl.l %0\n\t" \ - : "=r"(retval),"=m"(*b_addr) \ - : "0" (retval),"r" (b_addr) \ - : "memory"); \ - break; - -#define H8300_GEN_TEST_BITOP(FNNAME,OP) \ -static __inline__ int FNNAME(int nr, volatile void * addr) \ -{ \ - int retval = 0; \ - char ccrsave; \ - volatile unsigned char *b_addr; \ - b_addr = (volatile unsigned char *)addr + ((nr >> 3) ^ 3); \ - if (__builtin_constant_p(nr)) { \ - switch(nr & 7) { \ - H8300_GEN_TEST_BITOP_CONST_INT(OP,0) \ - H8300_GEN_TEST_BITOP_CONST_INT(OP,1) \ - H8300_GEN_TEST_BITOP_CONST_INT(OP,2) \ - H8300_GEN_TEST_BITOP_CONST_INT(OP,3) \ - H8300_GEN_TEST_BITOP_CONST_INT(OP,4) \ - H8300_GEN_TEST_BITOP_CONST_INT(OP,5) \ - H8300_GEN_TEST_BITOP_CONST_INT(OP,6) \ - H8300_GEN_TEST_BITOP_CONST_INT(OP,7) \ - } \ - } else { \ - __asm__("stc ccr,%w1\n\t" \ - "orc #0x80,ccr\n\t" \ - "btst %w5,@%4\n\t" \ - OP " %w5,@%4\n\t" \ - "beq 1f\n\t" \ - "inc.l #1,%0\n" \ - "1:\n\t" \ - "ldc %w1,ccr" \ - : "=r"(retval),"=&r"(ccrsave),"=m"(*b_addr) \ - : "0" (retval),"r" (b_addr),"r"(nr) \ - : "memory"); \ - } \ - return retval; \ -} \ - \ -static __inline__ int __ ## FNNAME(int nr, volatile void * addr) \ -{ \ - int retval = 0; \ - volatile unsigned char *b_addr; \ - b_addr = (volatile unsigned char *)addr + ((nr >> 3) ^ 3); \ - if (__builtin_constant_p(nr)) { \ - switch(nr & 7) { \ - H8300_GEN_TEST_BITOP_CONST(OP,0) \ - H8300_GEN_TEST_BITOP_CONST(OP,1) \ - H8300_GEN_TEST_BITOP_CONST(OP,2) \ - H8300_GEN_TEST_BITOP_CONST(OP,3) \ - H8300_GEN_TEST_BITOP_CONST(OP,4) \ - H8300_GEN_TEST_BITOP_CONST(OP,5) \ - H8300_GEN_TEST_BITOP_CONST(OP,6) \ - H8300_GEN_TEST_BITOP_CONST(OP,7) \ - } \ - } else { \ - __asm__("btst %w4,@%3\n\t" \ - OP " %w4,@%3\n\t" \ - "beq 1f\n\t" \ - "inc.l #1,%0\n" \ - "1:" \ - : "=r"(retval),"=m"(*b_addr) \ - : "0" (retval),"r" (b_addr),"r"(nr) \ - : "memory"); \ - } \ - return retval; \ -} - -H8300_GEN_TEST_BITOP(test_and_set_bit, "bset") -H8300_GEN_TEST_BITOP(test_and_clear_bit, "bclr") -H8300_GEN_TEST_BITOP(test_and_change_bit,"bnot") -#undef H8300_GEN_TEST_BITOP_CONST -#undef H8300_GEN_TEST_BITOP_CONST_INT -#undef H8300_GEN_TEST_BITOP - -#include <asm-generic/bitops/ffs.h> - -static __inline__ unsigned long __ffs(unsigned long word) -{ - unsigned long result; - - result = -1; - __asm__("1:\n\t" - "shlr.l %2\n\t" - "adds #1,%0\n\t" - "bcc 1b" - : "=r" (result) - : "0"(result),"r"(word)); - return result; -} - -#include <asm-generic/bitops/find.h> -#include <asm-generic/bitops/sched.h> -#include <asm-generic/bitops/hweight.h> -#include <asm-generic/bitops/lock.h> -#include <asm-generic/bitops/le.h> -#include <asm-generic/bitops/ext2-atomic.h> - -#endif /* __KERNEL__ */ - -#include <asm-generic/bitops/fls.h> -#include <asm-generic/bitops/__fls.h> -#include <asm-generic/bitops/fls64.h> - -#endif /* _H8300_BITOPS_H */ diff --git a/arch/h8300/include/asm/bootinfo.h b/arch/h8300/include/asm/bootinfo.h deleted file mode 100644 index 5bed7e7aac0a..000000000000 --- a/arch/h8300/include/asm/bootinfo.h +++ /dev/null @@ -1,2 +0,0 @@ - -/* Nothing for h8300 */ diff --git a/arch/h8300/include/asm/bug.h b/arch/h8300/include/asm/bug.h deleted file mode 100644 index 1e1be8119935..000000000000 --- a/arch/h8300/include/asm/bug.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef _H8300_BUG_H -#define _H8300_BUG_H - -/* always true */ -#define is_valid_bugaddr(addr) (1) - -#include <asm-generic/bug.h> - -struct pt_regs; -extern void die(const char *str, struct pt_regs *fp, unsigned long err); - -#endif diff --git a/arch/h8300/include/asm/bugs.h b/arch/h8300/include/asm/bugs.h deleted file mode 100644 index 1cb4afba6eb1..000000000000 --- a/arch/h8300/include/asm/bugs.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * include/asm-h8300/bugs.h - * - * Copyright (C) 1994 Linus Torvalds - */ - -/* - * This is included by init/main.c to check for architecture-dependent bugs. - * - * Needs: - * void check_bugs(void); - */ - -static void check_bugs(void) -{ -} diff --git a/arch/h8300/include/asm/cache.h b/arch/h8300/include/asm/cache.h deleted file mode 100644 index 05887a1d80e5..000000000000 --- a/arch/h8300/include/asm/cache.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef __ARCH_H8300_CACHE_H -#define __ARCH_H8300_CACHE_H - -/* bytes per L1 cache line */ -#define L1_CACHE_SHIFT 2 -#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) - -/* m68k-elf-gcc 2.95.2 doesn't like these */ - -#define __cacheline_aligned -#define ____cacheline_aligned - -#endif diff --git a/arch/h8300/include/asm/cachectl.h b/arch/h8300/include/asm/cachectl.h deleted file mode 100644 index c464022d8e26..000000000000 --- a/arch/h8300/include/asm/cachectl.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _H8300_CACHECTL_H -#define _H8300_CACHECTL_H - -/* Definitions for the cacheflush system call. */ - -#define FLUSH_SCOPE_LINE 0 /* Flush a cache line */ -#define FLUSH_SCOPE_PAGE 0 /* Flush a page */ -#define FLUSH_SCOPE_ALL 0 /* Flush the whole cache -- superuser only */ - -#define FLUSH_CACHE_DATA 0 /* Writeback and flush data cache */ -#define FLUSH_CACHE_INSN 0 /* Flush instruction cache */ -#define FLUSH_CACHE_BOTH 0 /* Flush both caches */ - -#endif /* _H8300_CACHECTL_H */ diff --git a/arch/h8300/include/asm/cacheflush.h b/arch/h8300/include/asm/cacheflush.h deleted file mode 100644 index 4cf2df20c1ce..000000000000 --- a/arch/h8300/include/asm/cacheflush.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * (C) Copyright 2002, Yoshinori Sato <ysato@users.sourceforge.jp> - */ - -#ifndef _ASM_H8300_CACHEFLUSH_H -#define _ASM_H8300_CACHEFLUSH_H - -/* - * Cache handling functions - * No Cache memory all dummy functions - */ - -#define flush_cache_all() -#define flush_cache_mm(mm) -#define flush_cache_dup_mm(mm) do { } while (0) -#define flush_cache_range(vma,a,b) -#define flush_cache_page(vma,p,pfn) -#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0 -#define flush_dcache_page(page) -#define flush_dcache_mmap_lock(mapping) -#define flush_dcache_mmap_unlock(mapping) -#define flush_icache() -#define flush_icache_page(vma,page) -#define flush_icache_range(start,len) -#define flush_cache_vmap(start, end) -#define flush_cache_vunmap(start, end) -#define cache_push_v(vaddr,len) -#define cache_push(paddr,len) -#define cache_clear(paddr,len) - -#define flush_dcache_range(a,b) - -#define flush_icache_user_range(vma,page,addr,len) - -#define copy_to_user_page(vma, page, vaddr, dst, src, len) \ - memcpy(dst, src, len) -#define copy_from_user_page(vma, page, vaddr, dst, src, len) \ - memcpy(dst, src, len) - -#endif /* _ASM_H8300_CACHEFLUSH_H */ diff --git a/arch/h8300/include/asm/checksum.h b/arch/h8300/include/asm/checksum.h deleted file mode 100644 index 98724e12508c..000000000000 --- a/arch/h8300/include/asm/checksum.h +++ /dev/null @@ -1,102 +0,0 @@ -#ifndef _H8300_CHECKSUM_H -#define _H8300_CHECKSUM_H - -/* - * computes the checksum of a memory block at buff, length len, - * and adds in "sum" (32-bit) - * - * returns a 32-bit number suitable for feeding into itself - * or csum_tcpudp_magic - * - * this function must be called with even lengths, except - * for the last fragment, which may be odd - * - * it's best to have buff aligned on a 32-bit boundary - */ -__wsum csum_partial(const void *buff, int len, __wsum sum); - -/* - * the same as csum_partial, but copies from src while it - * checksums - * - * here even more important to align src and dst on a 32-bit (or even - * better 64-bit) boundary - */ - -__wsum csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum); - - -/* - * the same as csum_partial_copy, but copies from user space. - * - * here even more important to align src and dst on a 32-bit (or even - * better 64-bit) boundary - */ - -extern __wsum csum_partial_copy_from_user(const void __user *src, void *dst, - int len, __wsum sum, int *csum_err); - -__sum16 ip_fast_csum(const void *iph, unsigned int ihl); - - -/* - * Fold a partial checksum - */ - -static inline __sum16 csum_fold(__wsum sum) -{ - __asm__("mov.l %0,er0\n\t" - "add.w e0,r0\n\t" - "xor.w e0,e0\n\t" - "rotxl.w e0\n\t" - "add.w e0,r0\n\t" - "sub.w e0,e0\n\t" - "mov.l er0,%0" - : "=r"(sum) - : "0"(sum) - : "er0"); - return (__force __sum16)~sum; -} - - -/* - * computes the checksum of the TCP/UDP pseudo-header - * returns a 16-bit checksum, already complemented - */ - -static inline __wsum -csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, - unsigned short proto, __wsum sum) -{ - __asm__ ("sub.l er0,er0\n\t" - "add.l %2,%0\n\t" - "addx #0,r0l\n\t" - "add.l %3,%0\n\t" - "addx #0,r0l\n\t" - "add.l %4,%0\n\t" - "addx #0,r0l\n\t" - "add.l er0,%0\n\t" - "bcc 1f\n\t" - "inc.l #1,%0\n" - "1:" - : "=&r" (sum) - : "0" (sum), "r" (daddr), "r" (saddr), "r" (len + proto) - :"er0"); - return sum; -} - -static inline __sum16 -csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len, - unsigned short proto, __wsum sum) -{ - return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); -} - -/* - * this routine is used for miscellaneous IP-like checksums, mainly - * in icmp.c - */ - -extern __sum16 ip_compute_csum(const void *buff, int len); - -#endif /* _H8300_CHECKSUM_H */ diff --git a/arch/h8300/include/asm/cmpxchg.h b/arch/h8300/include/asm/cmpxchg.h deleted file mode 100644 index cdb203ef681f..000000000000 --- a/arch/h8300/include/asm/cmpxchg.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef __ARCH_H8300_CMPXCHG__ -#define __ARCH_H8300_CMPXCHG__ - -#include <linux/irqflags.h> - -#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) - -struct __xchg_dummy { unsigned long a[100]; }; -#define __xg(x) ((volatile struct __xchg_dummy *)(x)) - -static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size) -{ - unsigned long tmp, flags; - - local_irq_save(flags); - - switch (size) { - case 1: - __asm__ __volatile__ - ("mov.b %2,%0\n\t" - "mov.b %1,%2" - : "=&r" (tmp) : "r" (x), "m" (*__xg(ptr)) : "memory"); - break; - case 2: - __asm__ __volatile__ - ("mov.w %2,%0\n\t" - "mov.w %1,%2" - : "=&r" (tmp) : "r" (x), "m" (*__xg(ptr)) : "memory"); - break; - case 4: - __asm__ __volatile__ - ("mov.l %2,%0\n\t" - "mov.l %1,%2" - : "=&r" (tmp) : "r" (x), "m" (*__xg(ptr)) : "memory"); - break; - default: - tmp = 0; - } - local_irq_restore(flags); - return tmp; -} - -#include <asm-generic/cmpxchg-local.h> - -/* - * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make - * them available. - */ -#define cmpxchg_local(ptr, o, n) \ - ((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), (unsigned long)(o),\ - (unsigned long)(n), sizeof(*(ptr)))) -#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) - -#ifndef CONFIG_SMP -#include <asm-generic/cmpxchg.h> -#endif - -#define atomic_xchg(v, new) (xchg(&((v)->counter), new)) - -#endif /* __ARCH_H8300_CMPXCHG__ */ diff --git a/arch/h8300/include/asm/cputime.h b/arch/h8300/include/asm/cputime.h deleted file mode 100644 index 092e187c7b08..000000000000 --- a/arch/h8300/include/asm/cputime.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __H8300_CPUTIME_H -#define __H8300_CPUTIME_H - -#include <asm-generic/cputime.h> - -#endif /* __H8300_CPUTIME_H */ diff --git a/arch/h8300/include/asm/current.h b/arch/h8300/include/asm/current.h deleted file mode 100644 index 57d74ee55a14..000000000000 --- a/arch/h8300/include/asm/current.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef _H8300_CURRENT_H -#define _H8300_CURRENT_H -/* - * current.h - * (C) Copyright 2000, Lineo, David McCullough <davidm@lineo.com> - * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com) - * - * rather than dedicate a register (as the m68k source does), we - * just keep a global, we should probably just change it all to be - * current and lose _current_task. - */ - -#include <linux/thread_info.h> -#include <asm/thread_info.h> - -struct task_struct; - -static inline struct task_struct *get_current(void) -{ - return(current_thread_info()->task); -} - -#define current get_current() - -#endif /* _H8300_CURRENT_H */ diff --git a/arch/h8300/include/asm/dbg.h b/arch/h8300/include/asm/dbg.h deleted file mode 100644 index 2c6d1cbcf736..000000000000 --- a/arch/h8300/include/asm/dbg.h +++ /dev/null @@ -1,2 +0,0 @@ -#define DEBUG 1 -#define BREAK asm volatile ("trap #3") diff --git a/arch/h8300/include/asm/delay.h b/arch/h8300/include/asm/delay.h deleted file mode 100644 index 743beba70f82..000000000000 --- a/arch/h8300/include/asm/delay.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef _H8300_DELAY_H -#define _H8300_DELAY_H - -#include <asm/param.h> - -/* - * Copyright (C) 2002 Yoshinori Sato <ysato@sourceforge.jp> - * - * Delay routines, using a pre-computed "loops_per_second" value. - */ - -static inline void __delay(unsigned long loops) -{ - __asm__ __volatile__ ("1:\n\t" - "dec.l #1,%0\n\t" - "bne 1b" - :"=r" (loops):"0"(loops)); -} - -/* - * Use only for very small delays ( < 1 msec). Should probably use a - * lookup table, really, as the multiplications take much too long with - * short delays. This is a "reasonable" implementation, though (and the - * first constant multiplications gets optimized away if the delay is - * a constant) - */ - -extern unsigned long loops_per_jiffy; - -static inline void udelay(unsigned long usecs) -{ - usecs *= 4295; /* 2**32 / 1000000 */ - usecs /= (loops_per_jiffy*HZ); - if (usecs) - __delay(usecs); -} - -#endif /* _H8300_DELAY_H */ diff --git a/arch/h8300/include/asm/device.h b/arch/h8300/include/asm/device.h deleted file mode 100644 index d8f9872b0e2d..000000000000 --- a/arch/h8300/include/asm/device.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Arch specific extensions to struct device - * - * This file is released under the GPLv2 - */ -#include <asm-generic/device.h> - diff --git a/arch/h8300/include/asm/div64.h b/arch/h8300/include/asm/div64.h deleted file mode 100644 index 6cd978cefb28..000000000000 --- a/arch/h8300/include/asm/div64.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/div64.h> diff --git a/arch/h8300/include/asm/dma.h b/arch/h8300/include/asm/dma.h deleted file mode 100644 index 3edbaaaedf5b..000000000000 --- a/arch/h8300/include/asm/dma.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef _H8300_DMA_H -#define _H8300_DMA_H - - -/* - * Set number of channels of DMA on ColdFire for different implementations. - */ -#define MAX_DMA_CHANNELS 0 -#define MAX_DMA_ADDRESS PAGE_OFFSET - -/* These are in kernel/dma.c: */ -extern int request_dma(unsigned int dmanr, const char *device_id); /* reserve a DMA channel */ -extern void free_dma(unsigned int dmanr); /* release it again */ - -#endif /* _H8300_DMA_H */ diff --git a/arch/h8300/include/asm/elf.h b/arch/h8300/include/asm/elf.h deleted file mode 100644 index 6db71248a82f..000000000000 --- a/arch/h8300/include/asm/elf.h +++ /dev/null @@ -1,101 +0,0 @@ -#ifndef __ASMH8300_ELF_H -#define __ASMH8300_ELF_H - -/* - * ELF register definitions.. - */ - -#include <asm/ptrace.h> -#include <asm/user.h> - -typedef unsigned long elf_greg_t; - -#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t)) -typedef elf_greg_t elf_gregset_t[ELF_NGREG]; -typedef unsigned long elf_fpregset_t; - -/* - * This is used to ensure we don't load something for the wrong architecture. - */ -#define elf_check_arch(x) ((x)->e_machine == EM_H8_300) - -/* - * These are used to set parameters in the core dumps. - */ -#define ELF_CLASS ELFCLASS32 -#define ELF_DATA ELFDATA2MSB -#define ELF_ARCH EM_H8_300 -#if defined(__H8300H__) -#define ELF_CORE_EFLAGS 0x810000 -#endif -#if defined(__H8300S__) -#define ELF_CORE_EFLAGS 0x820000 -#endif - -#define ELF_PLAT_INIT(_r) _r->er1 = 0 - -#define ELF_EXEC_PAGESIZE 4096 - -/* This is the location that an ET_DYN program is loaded if exec'ed. Typical - use of this is to invoke "./ld.so someprog" to test out a new version of - the loader. We need to make sure that it is out of the way of the program - that it will "exec", and that there is sufficient room for the brk. */ - -#define ELF_ET_DYN_BASE 0xD0000000UL - -/* This yields a mask that user programs can use to figure out what - instruction set this cpu supports. */ - -#define ELF_HWCAP (0) - -/* This yields a string that ld.so will use to load implementation - specific libraries for optimization. This is more specific in - intent than poking at uname or /proc/cpuinfo. */ - -#define ELF_PLATFORM (NULL) - -#define R_H8_NONE 0 -#define R_H8_DIR32 1 -#define R_H8_DIR32_28 2 -#define R_H8_DIR32_24 3 -#define R_H8_DIR32_16 4 -#define R_H8_DIR32U 6 -#define R_H8_DIR32U_28 7 -#define R_H8_DIR32U_24 8 -#define R_H8_DIR32U_20 9 -#define R_H8_DIR32U_16 10 -#define R_H8_DIR24 11 -#define R_H8_DIR24_20 12 -#define R_H8_DIR24_16 13 -#define R_H8_DIR24U 14 -#define R_H8_DIR24U_20 15 -#define R_H8_DIR24U_16 16 -#define R_H8_DIR16 17 -#define R_H8_DIR16U 18 -#define R_H8_DIR16S_32 19 -#define R_H8_DIR16S_28 20 -#define R_H8_DIR16S_24 21 -#define R_H8_DIR16S_20 22 -#define R_H8_DIR16S 23 -#define R_H8_DIR8 24 -#define R_H8_DIR8U 25 -#define R_H8_DIR8Z_32 26 -#define R_H8_DIR8Z_28 27 -#define R_H8_DIR8Z_24 28 -#define R_H8_DIR8Z_20 29 -#define R_H8_DIR8Z_16 30 -#define R_H8_PCREL16 31 -#define R_H8_PCREL8 32 -#define R_H8_BPOS 33 -#define R_H8_PCREL32 34 -#define R_H8_GOT32O 35 -#define R_H8_GOT16O 36 -#define R_H8_DIR16A8 59 -#define R_H8_DIR16R8 60 -#define R_H8_DIR24A8 61 -#define R_H8_DIR24R8 62 -#define R_H8_DIR32A16 63 -#define R_H8_ABS32 65 -#define R_H8_ABS32A16 127 - -#endif diff --git a/arch/h8300/include/asm/emergency-restart.h b/arch/h8300/include/asm/emergency-restart.h deleted file mode 100644 index 108d8c48e42e..000000000000 --- a/arch/h8300/include/asm/emergency-restart.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_EMERGENCY_RESTART_H -#define _ASM_EMERGENCY_RESTART_H - -#include <asm-generic/emergency-restart.h> - -#endif /* _ASM_EMERGENCY_RESTART_H */ diff --git a/arch/h8300/include/asm/fb.h b/arch/h8300/include/asm/fb.h deleted file mode 100644 index c7df38030992..000000000000 --- a/arch/h8300/include/asm/fb.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef _ASM_FB_H_ -#define _ASM_FB_H_ -#include <linux/fb.h> - -#define fb_pgprotect(...) do {} while (0) - -static inline int fb_is_primary_device(struct fb_info *info) -{ - return 0; -} - -#endif /* _ASM_FB_H_ */ diff --git a/arch/h8300/include/asm/flat.h b/arch/h8300/include/asm/flat.h deleted file mode 100644 index bd12b31b90e6..000000000000 --- a/arch/h8300/include/asm/flat.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * include/asm-h8300/flat.h -- uClinux flat-format executables - */ - -#ifndef __H8300_FLAT_H__ -#define __H8300_FLAT_H__ - -#define flat_argvp_envp_on_stack() 1 -#define flat_old_ram_flag(flags) 1 -#define flat_reloc_valid(reloc, size) ((reloc) <= (size)) -#define flat_set_persistent(relval, p) 0 - -/* - * on the H8 a couple of the relocations have an instruction in the - * top byte. As there can only be 24bits of address space, we just - * always preserve that 8bits at the top, when it isn't an instruction - * is is 0 (davidm@snapgear.com) - */ - -#define flat_get_relocate_addr(rel) (rel) -#define flat_get_addr_from_rp(rp, relval, flags, persistent) \ - (get_unaligned(rp) & ((flags & FLAT_FLAG_GOTPIC) ? 0xffffffff: 0x00ffffff)) -#define flat_put_addr_at_rp(rp, addr, rel) \ - put_unaligned (((*(char *)(rp)) << 24) | ((addr) & 0x00ffffff), rp) - -#endif /* __H8300_FLAT_H__ */ diff --git a/arch/h8300/include/asm/fpu.h b/arch/h8300/include/asm/fpu.h deleted file mode 100644 index 4fc416e80bef..000000000000 --- a/arch/h8300/include/asm/fpu.h +++ /dev/null @@ -1 +0,0 @@ -/* Nothing do */ diff --git a/arch/h8300/include/asm/ftrace.h b/arch/h8300/include/asm/ftrace.h deleted file mode 100644 index 40a8c178f10d..000000000000 --- a/arch/h8300/include/asm/ftrace.h +++ /dev/null @@ -1 +0,0 @@ -/* empty */ diff --git a/arch/h8300/include/asm/futex.h b/arch/h8300/include/asm/futex.h deleted file mode 100644 index 6a332a9f099c..000000000000 --- a/arch/h8300/include/asm/futex.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_FUTEX_H -#define _ASM_FUTEX_H - -#include <asm-generic/futex.h> - -#endif diff --git a/arch/h8300/include/asm/gpio-internal.h b/arch/h8300/include/asm/gpio-internal.h deleted file mode 100644 index a714f0c0efbc..000000000000 --- a/arch/h8300/include/asm/gpio-internal.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef _H8300_GPIO_H -#define _H8300_GPIO_H - -#define H8300_GPIO_P1 0 -#define H8300_GPIO_P2 1 -#define H8300_GPIO_P3 2 -#define H8300_GPIO_P4 3 -#define H8300_GPIO_P5 4 -#define H8300_GPIO_P6 5 -#define H8300_GPIO_P7 6 -#define H8300_GPIO_P8 7 -#define H8300_GPIO_P9 8 -#define H8300_GPIO_PA 9 -#define H8300_GPIO_PB 10 -#define H8300_GPIO_PC 11 -#define H8300_GPIO_PD 12 -#define H8300_GPIO_PE 13 -#define H8300_GPIO_PF 14 -#define H8300_GPIO_PG 15 -#define H8300_GPIO_PH 16 - -#define H8300_GPIO_B7 0x80 -#define H8300_GPIO_B6 0x40 -#define H8300_GPIO_B5 0x20 -#define H8300_GPIO_B4 0x10 -#define H8300_GPIO_B3 0x08 -#define H8300_GPIO_B2 0x04 -#define H8300_GPIO_B1 0x02 -#define H8300_GPIO_B0 0x01 - -#define H8300_GPIO_INPUT 0 -#define H8300_GPIO_OUTPUT 1 - -#define H8300_GPIO_RESERVE(port, bits) \ - h8300_reserved_gpio(port, bits) - -#define H8300_GPIO_FREE(port, bits) \ - h8300_free_gpio(port, bits) - -#define H8300_GPIO_DDR(port, bit, dir) \ - h8300_set_gpio_dir(((port) << 8) | (bit), dir) - -#define H8300_GPIO_GETDIR(port, bit) \ - h8300_get_gpio_dir(((port) << 8) | (bit)) - -extern int h8300_reserved_gpio(int port, int bits); -extern int h8300_free_gpio(int port, int bits); -extern int h8300_set_gpio_dir(int port_bit, int dir); -extern int h8300_get_gpio_dir(int port_bit); -extern int h8300_init_gpio(void); - -#endif diff --git a/arch/h8300/include/asm/hardirq.h b/arch/h8300/include/asm/hardirq.h deleted file mode 100644 index c2e1aa0f0d14..000000000000 --- a/arch/h8300/include/asm/hardirq.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef __H8300_HARDIRQ_H -#define __H8300_HARDIRQ_H - -#include <asm/irq.h> - -#define HARDIRQ_BITS 8 - -/* - * The hardirq mask has to be large enough to have - * space for potentially all IRQ sources in the system - * nesting on a single CPU: - */ -#if (1 << HARDIRQ_BITS) < NR_IRQS -# error HARDIRQ_BITS is too low! -#endif - -#include <asm-generic/hardirq.h> - -#endif diff --git a/arch/h8300/include/asm/hw_irq.h b/arch/h8300/include/asm/hw_irq.h deleted file mode 100644 index d75a5a1119e8..000000000000 --- a/arch/h8300/include/asm/hw_irq.h +++ /dev/null @@ -1 +0,0 @@ -/* Do Nothing */ diff --git a/arch/h8300/include/asm/io.h b/arch/h8300/include/asm/io.h deleted file mode 100644 index c1a8df22080f..000000000000 --- a/arch/h8300/include/asm/io.h +++ /dev/null @@ -1,358 +0,0 @@ -#ifndef _H8300_IO_H -#define _H8300_IO_H - -#ifdef __KERNEL__ - -#include <asm/virtconvert.h> - -#if defined(CONFIG_H83007) || defined(CONFIG_H83068) -#include <asm/regs306x.h> -#elif defined(CONFIG_H8S2678) -#include <asm/regs267x.h> -#else -#error UNKNOWN CPU TYPE -#endif - - -/* - * These are for ISA/PCI shared memory _only_ and should never be used - * on any other type of memory, including Zorro memory. They are meant to - * access the bus in the bus byte order which is little-endian!. - * - * readX/writeX() are used to access memory mapped devices. On some - * architectures the memory mapped IO stuff needs to be accessed - * differently. On the m68k architecture, we just read/write the - * memory location directly. - */ -/* ++roman: The assignments to temp. vars avoid that gcc sometimes generates - * two accesses to memory, which may be undesirable for some devices. - */ - -/* - * swap functions are sometimes needed to interface little-endian hardware - */ - -static inline unsigned short _swapw(volatile unsigned short v) -{ -#ifndef H8300_IO_NOSWAP - unsigned short r; - __asm__("xor.b %w0,%x0\n\t" - "xor.b %x0,%w0\n\t" - "xor.b %w0,%x0" - :"=r"(r) - :"0"(v)); - return r; -#else - return v; -#endif -} - -static inline unsigned long _swapl(volatile unsigned long v) -{ -#ifndef H8300_IO_NOSWAP - unsigned long r; - __asm__("xor.b %w0,%x0\n\t" - "xor.b %x0,%w0\n\t" - "xor.b %w0,%x0\n\t" - "xor.w %e0,%f0\n\t" - "xor.w %f0,%e0\n\t" - "xor.w %e0,%f0\n\t" - "xor.b %w0,%x0\n\t" - "xor.b %x0,%w0\n\t" - "xor.b %w0,%x0" - :"=r"(r) - :"0"(v)); - return r; -#else - return v; -#endif -} - -#define readb(addr) \ - ({ unsigned char __v = \ - *(volatile unsigned char *)((unsigned long)(addr) & 0x00ffffff); \ - __v; }) -#define readw(addr) \ - ({ unsigned short __v = \ - *(volatile unsigned short *)((unsigned long)(addr) & 0x00ffffff); \ - __v; }) -#define readl(addr) \ - ({ unsigned long __v = \ - *(volatile unsigned long *)((unsigned long)(addr) & 0x00ffffff); \ - __v; }) - -#define writeb(b,addr) (void)((*(volatile unsigned char *) \ - ((unsigned long)(addr) & 0x00ffffff)) = (b)) -#define writew(b,addr) (void)((*(volatile unsigned short *) \ - ((unsigned long)(addr) & 0x00ffffff)) = (b)) -#define writel(b,addr) (void)((*(volatile unsigned long *) \ - ((unsigned long)(addr) & 0x00ffffff)) = (b)) -#define readb_relaxed(addr) readb(addr) -#define readw_relaxed(addr) readw(addr) -#define readl_relaxed(addr) readl(addr) - -#define __raw_readb readb -#define __raw_readw readw -#define __raw_readl readl -#define __raw_writeb writeb -#define __raw_writew writew -#define __raw_writel writel - -static inline int h8300_buswidth(unsigned int addr) -{ - return (*(volatile unsigned char *)ABWCR & (1 << ((addr >> 21) & 7))) == 0; -} - -static inline void io_outsb(unsigned int addr, const void *buf, int len) -{ - volatile unsigned char *ap_b = (volatile unsigned char *) addr; - volatile unsigned short *ap_w = (volatile unsigned short *) addr; - unsigned char *bp = (unsigned char *) buf; - - if(h8300_buswidth(addr) && (addr & 1)) { - while (len--) - *ap_w = *bp++; - } else { - while (len--) - *ap_b = *bp++; - } -} - -static inline void io_outsw(unsigned int addr, const void *buf, int len) -{ - volatile unsigned short *ap = (volatile unsigned short *) addr; - unsigned short *bp = (unsigned short *) buf; - while (len--) - *ap = _swapw(*bp++); -} - -static inline void io_outsl(unsigned int addr, const void *buf, int len) -{ - volatile unsigned long *ap = (volatile unsigned long *) addr; - unsigned long *bp = (unsigned long *) buf; - while (len--) - *ap = _swapl(*bp++); -} - -static inline void io_outsw_noswap(unsigned int addr, const void *buf, int len) -{ - volatile unsigned short *ap = (volatile unsigned short *) addr; - unsigned short *bp = (unsigned short *) buf; - while (len--) - *ap = *bp++; -} - -static inline void io_outsl_noswap(unsigned int addr, const void *buf, int len) -{ - volatile unsigned long *ap = (volatile unsigned long *) addr; - unsigned long *bp = (unsigned long *) buf; - while (len--) - *ap = *bp++; -} - -static inline void io_insb(unsigned int addr, void *buf, int len) -{ - volatile unsigned char *ap_b; - volatile unsigned short *ap_w; - unsigned char *bp = (unsigned char *) buf; - - if(h8300_buswidth(addr)) { - ap_w = (volatile unsigned short *)(addr & ~1); - while (len--) - *bp++ = *ap_w & 0xff; - } else { - ap_b = (volatile unsigned char *)addr; - while (len--) - *bp++ = *ap_b; - } -} - -static inline void io_insw(unsigned int addr, void *buf, int len) -{ - volatile unsigned short *ap = (volatile unsigned short *) addr; - unsigned short *bp = (unsigned short *) buf; - while (len--) - *bp++ = _swapw(*ap); -} - -static inline void io_insl(unsigned int addr, void *buf, int len) -{ - volatile unsigned long *ap = (volatile unsigned long *) addr; - unsigned long *bp = (unsigned long *) buf; - while (len--) - *bp++ = _swapl(*ap); -} - -static inline void io_insw_noswap(unsigned int addr, void *buf, int len) -{ - volatile unsigned short *ap = (volatile unsigned short *) addr; - unsigned short *bp = (unsigned short *) buf; - while (len--) - *bp++ = *ap; -} - -static inline void io_insl_noswap(unsigned int addr, void *buf, int len) -{ - volatile unsigned long *ap = (volatile unsigned long *) addr; - unsigned long *bp = (unsigned long *) buf; - while (len--) - *bp++ = *ap; -} - -/* - * make the short names macros so specific devices - * can override them as required - */ - -#define memset_io(a,b,c) memset((void *)(a),(b),(c)) -#define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c)) -#define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c)) - -#define mmiowb() - -#define inb(addr) ((h8300_buswidth(addr))?readw((addr) & ~1) & 0xff:readb(addr)) -#define inw(addr) _swapw(readw(addr)) -#define inl(addr) _swapl(readl(addr)) -#define outb(x,addr) ((void)((h8300_buswidth(addr) && \ - ((addr) & 1))?writew(x,(addr) & ~1):writeb(x,addr))) -#define outw(x,addr) ((void) writew(_swapw(x),addr)) -#define outl(x,addr) ((void) writel(_swapl(x),addr)) - -#define inb_p(addr) inb(addr) -#define inw_p(addr) inw(addr) -#define inl_p(addr) inl(addr) -#define outb_p(x,addr) outb(x,addr) -#define outw_p(x,addr) outw(x,addr) -#define outl_p(x,addr) outl(x,addr) - -#define outsb(a,b,l) io_outsb(a,b,l) -#define outsw(a,b,l) io_outsw(a,b,l) -#define outsl(a,b,l) io_outsl(a,b,l) - -#define insb(a,b,l) io_insb(a,b,l) -#define insw(a,b,l) io_insw(a,b,l) -#define insl(a,b,l) io_insl(a,b,l) - -#define IO_SPACE_LIMIT 0xffffff - - -/* Values for nocacheflag and cmode */ -#define IOMAP_FULL_CACHING 0 -#define IOMAP_NOCACHE_SER 1 -#define IOMAP_NOCACHE_NONSER 2 -#define IOMAP_WRITETHROUGH 3 - -extern void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag); -extern void __iounmap(void *addr, unsigned long size); - -static inline void *ioremap(unsigned long physaddr, unsigned long size) -{ - return __ioremap(physaddr, size, IOMAP_NOCACHE_SER); -} -static inline void *ioremap_nocache(unsigned long physaddr, unsigned long size) -{ - return __ioremap(physaddr, size, IOMAP_NOCACHE_SER); -} -static inline void *ioremap_writethrough(unsigned long physaddr, unsigned long size) -{ - return __ioremap(physaddr, size, IOMAP_WRITETHROUGH); -} -static inline void *ioremap_fullcache(unsigned long physaddr, unsigned long size) -{ - return __ioremap(physaddr, size, IOMAP_FULL_CACHING); -} - -extern void iounmap(void *addr); - -/* H8/300 internal I/O functions */ -static __inline__ unsigned char ctrl_inb(unsigned long addr) -{ - return *(volatile unsigned char*)addr; -} - -static __inline__ unsigned short ctrl_inw(unsigned long addr) -{ - return *(volatile unsigned short*)addr; -} - -static __inline__ unsigned long ctrl_inl(unsigned long addr) -{ - return *(volatile unsigned long*)addr; -} - -static __inline__ void ctrl_outb(unsigned char b, unsigned long addr) -{ - *(volatile unsigned char*)addr = b; -} - -static __inline__ void ctrl_outw(unsigned short b, unsigned long addr) -{ - *(volatile unsigned short*)addr = b; -} - -static __inline__ void ctrl_outl(unsigned long b, unsigned long addr) -{ - *(volatile unsigned long*)addr = b; -} - -static __inline__ void ctrl_bclr(int b, unsigned long addr) -{ - if (__builtin_constant_p(b)) - switch (b) { - case 0: __asm__("bclr #0,@%0"::"r"(addr)); break; - case 1: __asm__("bclr #1,@%0"::"r"(addr)); break; - case 2: __asm__("bclr #2,@%0"::"r"(addr)); break; - case 3: __asm__("bclr #3,@%0"::"r"(addr)); break; - case 4: __asm__("bclr #4,@%0"::"r"(addr)); break; - case 5: __asm__("bclr #5,@%0"::"r"(addr)); break; - case 6: __asm__("bclr #6,@%0"::"r"(addr)); break; - case 7: __asm__("bclr #7,@%0"::"r"(addr)); break; - } - else - __asm__("bclr %w0,@%1"::"r"(b), "r"(addr)); -} - -static __inline__ void ctrl_bset(int b, unsigned long addr) -{ - if (__builtin_constant_p(b)) - switch (b) { - case 0: __asm__("bset #0,@%0"::"r"(addr)); break; - case 1: __asm__("bset #1,@%0"::"r"(addr)); break; - case 2: __asm__("bset #2,@%0"::"r"(addr)); break; - case 3: __asm__("bset #3,@%0"::"r"(addr)); break; - case 4: __asm__("bset #4,@%0"::"r"(addr)); break; - case 5: __asm__("bset #5,@%0"::"r"(addr)); break; - case 6: __asm__("bset #6,@%0"::"r"(addr)); break; - case 7: __asm__("bset #7,@%0"::"r"(addr)); break; - } - else - __asm__("bset %w0,@%1"::"r"(b), "r"(addr)); -} - -/* Pages to physical address... */ -#define page_to_phys(page) ((page - mem_map) << PAGE_SHIFT) -#define page_to_bus(page) ((page - mem_map) << PAGE_SHIFT) - -/* - * Macros used for converting between virtual and physical mappings. - */ -#define phys_to_virt(vaddr) ((void *) (vaddr)) -#define virt_to_phys(vaddr) ((unsigned long) (vaddr)) - -#define virt_to_bus virt_to_phys -#define bus_to_virt phys_to_virt - -/* - * Convert a physical pointer to a virtual kernel pointer for /dev/mem - * access - */ -#define xlate_dev_mem_ptr(p) __va(p) - -/* - * Convert a virtual cached pointer to an uncached pointer - */ -#define xlate_dev_kmem_ptr(p) p - -#endif /* __KERNEL__ */ - -#endif /* _H8300_IO_H */ diff --git a/arch/h8300/include/asm/irq.h b/arch/h8300/include/asm/irq.h deleted file mode 100644 index 13d7c601cd0a..000000000000 --- a/arch/h8300/include/asm/irq.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef _H8300_IRQ_H_ -#define _H8300_IRQ_H_ - -#include <asm/ptrace.h> - -#if defined(CONFIG_CPU_H8300H) -#define NR_IRQS 64 -#define EXT_IRQ0 12 -#define EXT_IRQ1 13 -#define EXT_IRQ2 14 -#define EXT_IRQ3 15 -#define EXT_IRQ4 16 -#define EXT_IRQ5 17 -#define EXT_IRQ6 18 -#define EXT_IRQ7 19 -#define EXT_IRQS 5 -#define IER_REGS *(volatile unsigned char *)IER -#endif -#if defined(CONFIG_CPU_H8S) -#define NR_IRQS 128 -#define EXT_IRQ0 16 -#define EXT_IRQ1 17 -#define EXT_IRQ2 18 -#define EXT_IRQ3 19 -#define EXT_IRQ4 20 -#define EXT_IRQ5 21 -#define EXT_IRQ6 22 -#define EXT_IRQ7 23 -#define EXT_IRQ8 24 -#define EXT_IRQ9 25 -#define EXT_IRQ10 26 -#define EXT_IRQ11 27 -#define EXT_IRQ12 28 -#define EXT_IRQ13 29 -#define EXT_IRQ14 30 -#define EXT_IRQ15 31 -#define EXT_IRQS 15 - -#define IER_REGS *(volatile unsigned short *)IER -#endif - -static __inline__ int irq_canonicalize(int irq) -{ - return irq; -} - -typedef void (*h8300_vector)(void); - -#endif /* _H8300_IRQ_H_ */ diff --git a/arch/h8300/include/asm/irq_regs.h b/arch/h8300/include/asm/irq_regs.h deleted file mode 100644 index 3dd9c0b70270..000000000000 --- a/arch/h8300/include/asm/irq_regs.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/irq_regs.h> diff --git a/arch/h8300/include/asm/irqflags.h b/arch/h8300/include/asm/irqflags.h deleted file mode 100644 index 9617cd57aebd..000000000000 --- a/arch/h8300/include/asm/irqflags.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef _H8300_IRQFLAGS_H -#define _H8300_IRQFLAGS_H - -static inline unsigned long arch_local_save_flags(void) -{ - unsigned long flags; - asm volatile ("stc ccr,%w0" : "=r" (flags)); - return flags; -} - -static inline void arch_local_irq_disable(void) -{ - asm volatile ("orc #0x80,ccr" : : : "memory"); -} - -static inline void arch_local_irq_enable(void) -{ - asm volatile ("andc #0x7f,ccr" : : : "memory"); -} - -static inline unsigned long arch_local_irq_save(void) -{ - unsigned long flags = arch_local_save_flags(); - arch_local_irq_disable(); - return flags; -} - -static inline void arch_local_irq_restore(unsigned long flags) -{ - asm volatile ("ldc %w0,ccr" : : "r" (flags) : "memory"); -} - -static inline bool arch_irqs_disabled_flags(unsigned long flags) -{ - return (flags & 0x80) == 0x80; -} - -static inline bool arch_irqs_disabled(void) -{ - return arch_irqs_disabled_flags(arch_local_save_flags()); -} - -#endif /* _H8300_IRQFLAGS_H */ diff --git a/arch/h8300/include/asm/kdebug.h b/arch/h8300/include/asm/kdebug.h deleted file mode 100644 index 6ece1b037665..000000000000 --- a/arch/h8300/include/asm/kdebug.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/kdebug.h> diff --git a/arch/h8300/include/asm/kmap_types.h b/arch/h8300/include/asm/kmap_types.h deleted file mode 100644 index be12a7160116..000000000000 --- a/arch/h8300/include/asm/kmap_types.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_H8300_KMAP_TYPES_H -#define _ASM_H8300_KMAP_TYPES_H - -#include <asm-generic/kmap_types.h> - -#endif diff --git a/arch/h8300/include/asm/local.h b/arch/h8300/include/asm/local.h deleted file mode 100644 index fdd4efe437cd..000000000000 --- a/arch/h8300/include/asm/local.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _H8300_LOCAL_H_ -#define _H8300_LOCAL_H_ - -#include <asm-generic/local.h> - -#endif diff --git a/arch/h8300/include/asm/local64.h b/arch/h8300/include/asm/local64.h deleted file mode 100644 index 36c93b5cc239..000000000000 --- a/arch/h8300/include/asm/local64.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/local64.h> diff --git a/arch/h8300/include/asm/mc146818rtc.h b/arch/h8300/include/asm/mc146818rtc.h deleted file mode 100644 index ab9d9646d241..000000000000 --- a/arch/h8300/include/asm/mc146818rtc.h +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Machine dependent access functions for RTC registers. - */ -#ifndef _H8300_MC146818RTC_H -#define _H8300_MC146818RTC_H - -/* empty include file to satisfy the include in genrtc.c/ide-geometry.c */ - -#endif /* _H8300_MC146818RTC_H */ diff --git a/arch/h8300/include/asm/mmu_context.h b/arch/h8300/include/asm/mmu_context.h deleted file mode 100644 index f44b730da54d..000000000000 --- a/arch/h8300/include/asm/mmu_context.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef __H8300_MMU_CONTEXT_H -#define __H8300_MMU_CONTEXT_H - -#include <asm/setup.h> -#include <asm/page.h> -#include <asm/pgalloc.h> -#include <asm-generic/mm_hooks.h> - -static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) -{ -} - -static inline int -init_new_context(struct task_struct *tsk, struct mm_struct *mm) -{ - // mm->context = virt_to_phys(mm->pgd); - return(0); -} - -#define destroy_context(mm) do { } while(0) -#define deactivate_mm(tsk,mm) do { } while(0) - -static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk) -{ -} - -static inline void activate_mm(struct mm_struct *prev_mm, - struct mm_struct *next_mm) -{ -} - -#endif diff --git a/arch/h8300/include/asm/mutex.h b/arch/h8300/include/asm/mutex.h deleted file mode 100644 index 458c1f7fbc18..000000000000 --- a/arch/h8300/include/asm/mutex.h +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Pull in the generic implementation for the mutex fastpath. - * - * TODO: implement optimized primitives instead, or leave the generic - * implementation in place, or pick the atomic_xchg() based generic - * implementation. (see asm-generic/mutex-xchg.h for details) - */ - -#include <asm-generic/mutex-dec.h> diff --git a/arch/h8300/include/asm/page.h b/arch/h8300/include/asm/page.h deleted file mode 100644 index 837381a2df46..000000000000 --- a/arch/h8300/include/asm/page.h +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef _H8300_PAGE_H -#define _H8300_PAGE_H - -/* PAGE_SHIFT determines the page size */ - -#define PAGE_SHIFT (12) -#define PAGE_SIZE (1UL << PAGE_SHIFT) -#define PAGE_MASK (~(PAGE_SIZE-1)) - -#include <asm/setup.h> - -#ifndef __ASSEMBLY__ - -#define get_user_page(vaddr) __get_free_page(GFP_KERNEL) -#define free_user_page(page, addr) free_page(addr) - -#define clear_page(page) memset((page), 0, PAGE_SIZE) -#define copy_page(to,from) memcpy((to), (from), PAGE_SIZE) - -#define clear_user_page(page, vaddr, pg) clear_page(page) -#define copy_user_page(to, from, vaddr, pg) copy_page(to, from) - -#define __alloc_zeroed_user_highpage(movableflags, vma, vaddr) \ - alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO | movableflags, vma, vaddr) -#define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE - -/* - * These are used to make use of C type-checking.. - */ -typedef struct { unsigned long pte; } pte_t; -typedef struct { unsigned long pmd[16]; } pmd_t; -typedef struct { unsigned long pgd; } pgd_t; -typedef struct { unsigned long pgprot; } pgprot_t; -typedef struct page *pgtable_t; - -#define pte_val(x) ((x).pte) -#define pmd_val(x) ((&x)->pmd[0]) -#define pgd_val(x) ((x).pgd) -#define pgprot_val(x) ((x).pgprot) - -#define __pte(x) ((pte_t) { (x) } ) -#define __pmd(x) ((pmd_t) { (x) } ) -#define __pgd(x) ((pgd_t) { (x) } ) -#define __pgprot(x) ((pgprot_t) { (x) } ) - -extern unsigned long memory_start; -extern unsigned long memory_end; - -#endif /* !__ASSEMBLY__ */ - -#include <asm/page_offset.h> - -#define PAGE_OFFSET (PAGE_OFFSET_RAW) - -#ifndef __ASSEMBLY__ - -#define __pa(vaddr) virt_to_phys(vaddr) -#define __va(paddr) phys_to_virt((unsigned long)paddr) - -#define virt_to_pfn(kaddr) (__pa(kaddr) >> PAGE_SHIFT) -#define pfn_to_virt(pfn) __va((pfn) << PAGE_SHIFT) - -#define MAP_NR(addr) (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT) -#define virt_to_page(addr) (mem_map + (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT)) -#define page_to_virt(page) ((((page) - mem_map) << PAGE_SHIFT) + PAGE_OFFSET) -#define pfn_valid(page) (page < max_mapnr) - -#define ARCH_PFN_OFFSET (PAGE_OFFSET >> PAGE_SHIFT) - -#define virt_addr_valid(kaddr) (((void *)(kaddr) >= (void *)PAGE_OFFSET) && \ - ((void *)(kaddr) < (void *)memory_end)) - -#endif /* __ASSEMBLY__ */ - -#include <asm-generic/memory_model.h> -#include <asm-generic/getorder.h> - -#endif /* _H8300_PAGE_H */ diff --git a/arch/h8300/include/asm/page_offset.h b/arch/h8300/include/asm/page_offset.h deleted file mode 100644 index f8706463008c..000000000000 --- a/arch/h8300/include/asm/page_offset.h +++ /dev/null @@ -1,3 +0,0 @@ - -#define PAGE_OFFSET_RAW 0x00000000 - diff --git a/arch/h8300/include/asm/param.h b/arch/h8300/include/asm/param.h deleted file mode 100644 index c3909e7ff178..000000000000 --- a/arch/h8300/include/asm/param.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef _H8300_PARAM_H -#define _H8300_PARAM_H - -#include <uapi/asm/param.h> - -#define HZ CONFIG_HZ -#define USER_HZ HZ -#define CLOCKS_PER_SEC (USER_HZ) -#endif /* _H8300_PARAM_H */ diff --git a/arch/h8300/include/asm/pci.h b/arch/h8300/include/asm/pci.h deleted file mode 100644 index 0b2acaa3dd84..000000000000 --- a/arch/h8300/include/asm/pci.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef _ASM_H8300_PCI_H -#define _ASM_H8300_PCI_H - -/* - * asm-h8300/pci.h - H8/300 specific PCI declarations. - * - * Yoshinori Sato <ysato@users.sourceforge.jp> - */ - -#define pcibios_assign_all_busses() 0 - -static inline void pcibios_penalize_isa_irq(int irq, int active) -{ - /* We don't do dynamic PCI IRQ allocation */ -} - -#define PCI_DMA_BUS_IS_PHYS (1) - -#endif /* _ASM_H8300_PCI_H */ diff --git a/arch/h8300/include/asm/percpu.h b/arch/h8300/include/asm/percpu.h deleted file mode 100644 index 72c03e3666d8..000000000000 --- a/arch/h8300/include/asm/percpu.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ARCH_H8300_PERCPU__ -#define __ARCH_H8300_PERCPU__ - -#include <asm-generic/percpu.h> - -#endif /* __ARCH_H8300_PERCPU__ */ diff --git a/arch/h8300/include/asm/pgalloc.h b/arch/h8300/include/asm/pgalloc.h deleted file mode 100644 index c2e89a286d23..000000000000 --- a/arch/h8300/include/asm/pgalloc.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef _H8300_PGALLOC_H -#define _H8300_PGALLOC_H - -#include <asm/setup.h> - -#define check_pgt_cache() do { } while (0) - -#endif /* _H8300_PGALLOC_H */ diff --git a/arch/h8300/include/asm/pgtable.h b/arch/h8300/include/asm/pgtable.h deleted file mode 100644 index 7ca20f894dd7..000000000000 --- a/arch/h8300/include/asm/pgtable.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef _H8300_PGTABLE_H -#define _H8300_PGTABLE_H - -#include <asm-generic/4level-fixup.h> - -#include <linux/slab.h> -#include <asm/processor.h> -#include <asm/page.h> -#include <asm/io.h> - -#define pgd_present(pgd) (1) /* pages are always present on NO_MM */ -#define pgd_none(pgd) (0) -#define pgd_bad(pgd) (0) -#define pgd_clear(pgdp) -#define kern_addr_valid(addr) (1) -#define pmd_offset(a, b) ((void *)0) -#define pmd_none(pmd) (1) -#define pgd_offset_k(adrdress) ((pgd_t *)0) -#define pte_offset_kernel(dir, address) ((pte_t *)0) - -#define PAGE_NONE __pgprot(0) /* these mean nothing to NO_MM */ -#define PAGE_SHARED __pgprot(0) /* these mean nothing to NO_MM */ -#define PAGE_COPY __pgprot(0) /* these mean nothing to NO_MM */ -#define PAGE_READONLY __pgprot(0) /* these mean nothing to NO_MM */ -#define PAGE_KERNEL __pgprot(0) /* these mean nothing to NO_MM */ - -extern void paging_init(void); -#define swapper_pg_dir ((pgd_t *) 0) - -#define __swp_type(x) (0) -#define __swp_offset(x) (0) -#define __swp_entry(typ,off) ((swp_entry_t) { ((typ) | ((off) << 7)) }) -#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) -#define __swp_entry_to_pte(x) ((pte_t) { (x).val }) - -static inline int pte_file(pte_t pte) { return 0; } - -/* - * ZERO_PAGE is a global shared page that is always zero: used - * for zero-mapped memory areas etc.. - */ -#define ZERO_PAGE(vaddr) (virt_to_page(0)) - -/* - * These would be in other places but having them here reduces the diffs. - */ -extern unsigned int kobjsize(const void *objp); -extern int is_in_rom(unsigned long); - -/* - * No page table caches to initialise - */ -#define pgtable_cache_init() do { } while (0) - -/* - * All 32bit addresses are effectively valid for vmalloc... - * Sort of meaningless for non-VM targets. - */ -#define VMALLOC_START 0 -#define VMALLOC_END 0xffffffff - -/* - * All 32bit addresses are effectively valid for vmalloc... - * Sort of meaningless for non-VM targets. - */ -#define VMALLOC_START 0 -#define VMALLOC_END 0xffffffff - -#define arch_enter_lazy_cpu_mode() do {} while (0) - -#include <asm-generic/pgtable.h> - -#endif /* _H8300_PGTABLE_H */ diff --git a/arch/h8300/include/asm/processor.h b/arch/h8300/include/asm/processor.h deleted file mode 100644 index 4b0ca49bb463..000000000000 --- a/arch/h8300/include/asm/processor.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - * include/asm-h8300/processor.h - * - * Copyright (C) 2002 Yoshinori Sato - * - * Based on: linux/asm-m68nommu/processor.h - * - * Copyright (C) 1995 Hamish Macdonald - */ - -#ifndef __ASM_H8300_PROCESSOR_H -#define __ASM_H8300_PROCESSOR_H - -/* - * Default implementation of macro that returns current - * instruction pointer ("program counter"). - */ -#define current_text_addr() ({ __label__ _l; _l: &&_l;}) - -#include <linux/compiler.h> -#include <asm/segment.h> -#include <asm/fpu.h> -#include <asm/ptrace.h> -#include <asm/current.h> - -static inline unsigned long rdusp(void) { - extern unsigned int sw_usp; - return(sw_usp); -} - -static inline void wrusp(unsigned long usp) { - extern unsigned int sw_usp; - sw_usp = usp; -} - -/* - * User space process size: 3.75GB. This is hardcoded into a few places, - * so don't change it unless you know what you are doing. - */ -#define TASK_SIZE (0xFFFFFFFFUL) - -#ifdef __KERNEL__ -#define STACK_TOP TASK_SIZE -#define STACK_TOP_MAX STACK_TOP -#endif - -/* - * This decides where the kernel will search for a free chunk of vm - * space during mmap's. We won't be using it - */ -#define TASK_UNMAPPED_BASE 0 - -struct thread_struct { - unsigned long ksp; /* kernel stack pointer */ - unsigned long usp; /* user stack pointer */ - unsigned long ccr; /* saved status register */ - unsigned long esp0; /* points to SR of stack frame */ - struct { - unsigned short *addr; - unsigned short inst; - } breakinfo; -}; - -#define INIT_THREAD { \ - .ksp = sizeof(init_stack) + (unsigned long)init_stack, \ - .usp = 0, \ - .ccr = PS_S, \ - .esp0 = 0, \ - .breakinfo = { \ - .addr = (unsigned short *)-1, \ - .inst = 0 \ - } \ -} - -/* - * Do necessary setup to start up a newly executed thread. - * - * pass the data segment into user programs if it exists, - * it can't hurt anything as far as I can tell - */ -#if defined(__H8300H__) -#define start_thread(_regs, _pc, _usp) \ -do { \ - (_regs)->pc = (_pc); \ - (_regs)->ccr = 0x00; /* clear all flags */ \ - (_regs)->er5 = current->mm->start_data; /* GOT base */ \ - wrusp((unsigned long)(_usp) - sizeof(unsigned long)*3); \ -} while(0) -#endif -#if defined(__H8300S__) -#define start_thread(_regs, _pc, _usp) \ -do { \ - (_regs)->pc = (_pc); \ - (_regs)->ccr = 0x00; /* clear kernel flag */ \ - (_regs)->exr = 0x78; /* enable all interrupts */ \ - (_regs)->er5 = current->mm->start_data; /* GOT base */ \ - /* 14 = space for retaddr(4), vector(4), er0(4) and ext(2) on stack */ \ - wrusp(((unsigned long)(_usp)) - 14); \ -} while(0) -#endif - -/* Forward declaration, a strange C thing */ -struct task_struct; - -/* Free all resources held by a thread. */ -static inline void release_thread(struct task_struct *dead_task) -{ -} - -/* - * Free current thread data structures etc.. - */ -static inline void exit_thread(void) -{ -} - -/* - * Return saved PC of a blocked thread. - */ -unsigned long thread_saved_pc(struct task_struct *tsk); -unsigned long get_wchan(struct task_struct *p); - -#define KSTK_EIP(tsk) \ - ({ \ - unsigned long eip = 0; \ - if ((tsk)->thread.esp0 > PAGE_SIZE && \ - MAP_NR((tsk)->thread.esp0) < max_mapnr) \ - eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \ - eip; }) -#define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->thread.usp) - -#define cpu_relax() barrier() - -#define HARD_RESET_NOW() ({ \ - local_irq_disable(); \ - asm("jmp @@0"); \ -}) - -#endif diff --git a/arch/h8300/include/asm/ptrace.h b/arch/h8300/include/asm/ptrace.h deleted file mode 100644 index c1826b95c5ca..000000000000 --- a/arch/h8300/include/asm/ptrace.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef _H8300_PTRACE_H -#define _H8300_PTRACE_H - -#include <uapi/asm/ptrace.h> - -#ifndef __ASSEMBLY__ -#if defined(CONFIG_CPU_H8S) -#endif -#ifndef PS_S -#define PS_S (0x10) -#endif - -#if defined(__H8300H__) -#define H8300_REGS_NO 11 -#endif -#if defined(__H8300S__) -#define H8300_REGS_NO 12 -#endif - -/* Find the stack offset for a register, relative to thread.esp0. */ -#define PT_REG(reg) ((long)&((struct pt_regs *)0)->reg) - -#define arch_has_single_step() (1) - -#define user_mode(regs) (!((regs)->ccr & PS_S)) -#define instruction_pointer(regs) ((regs)->pc) -#define profile_pc(regs) instruction_pointer(regs) -#define current_pt_regs() ((struct pt_regs *) \ - (THREAD_SIZE + (unsigned long)current_thread_info()) - 1) -#define signal_pt_regs() ((struct pt_regs *)current->thread.esp0) -#define current_user_stack_pointer() rdusp() -#endif /* __ASSEMBLY__ */ -#endif /* _H8300_PTRACE_H */ diff --git a/arch/h8300/include/asm/regs267x.h b/arch/h8300/include/asm/regs267x.h deleted file mode 100644 index 1bff731a9f77..000000000000 --- a/arch/h8300/include/asm/regs267x.h +++ /dev/null @@ -1,336 +0,0 @@ -/* internal Peripherals Register address define */ -/* CPU: H8/306x */ - -#if !defined(__REGS_H8S267x__) -#define __REGS_H8S267x__ - -#if defined(__KERNEL__) - -#define DASTCR 0xFEE01A -#define DADR0 0xFFFFA4 -#define DADR1 0xFFFFA5 -#define DACR01 0xFFFFA6 -#define DADR2 0xFFFFA8 -#define DADR3 0xFFFFA9 -#define DACR23 0xFFFFAA - -#define ADDRA 0xFFFF90 -#define ADDRAH 0xFFFF90 -#define ADDRAL 0xFFFF91 -#define ADDRB 0xFFFF92 -#define ADDRBH 0xFFFF92 -#define ADDRBL 0xFFFF93 -#define ADDRC 0xFFFF94 -#define ADDRCH 0xFFFF94 -#define ADDRCL 0xFFFF95 -#define ADDRD 0xFFFF96 -#define ADDRDH 0xFFFF96 -#define ADDRDL 0xFFFF97 -#define ADDRE 0xFFFF98 -#define ADDREH 0xFFFF98 -#define ADDREL 0xFFFF99 -#define ADDRF 0xFFFF9A -#define ADDRFH 0xFFFF9A -#define ADDRFL 0xFFFF9B -#define ADDRG 0xFFFF9C -#define ADDRGH 0xFFFF9C -#define ADDRGL 0xFFFF9D -#define ADDRH 0xFFFF9E -#define ADDRHH 0xFFFF9E -#define ADDRHL 0xFFFF9F - -#define ADCSR 0xFFFFA0 -#define ADCR 0xFFFFA1 - -#define ABWCR 0xFFFEC0 -#define ASTCR 0xFFFEC1 -#define WTCRAH 0xFFFEC2 -#define WTCRAL 0xFFFEC3 -#define WTCRBH 0xFFFEC4 -#define WTCRBL 0xFFFEC5 -#define RDNCR 0xFFFEC6 -#define CSACRH 0xFFFEC8 -#define CSACRL 0xFFFEC9 -#define BROMCRH 0xFFFECA -#define BROMCRL 0xFFFECB -#define BCR 0xFFFECC -#define DRAMCR 0xFFFED0 -#define DRACCR 0xFFFED2 -#define REFCR 0xFFFED4 -#define RTCNT 0xFFFED6 -#define RTCOR 0xFFFED7 - -#define MAR0AH 0xFFFEE0 -#define MAR0AL 0xFFFEE2 -#define IOAR0A 0xFFFEE4 -#define ETCR0A 0xFFFEE6 -#define MAR0BH 0xFFFEE8 -#define MAR0BL 0xFFFEEA -#define IOAR0B 0xFFFEEC -#define ETCR0B 0xFFFEEE -#define MAR1AH 0xFFFEF0 -#define MAR1AL 0xFFFEF2 -#define IOAR1A 0xFFFEF4 -#define ETCR1A 0xFFFEF6 -#define MAR1BH 0xFFFEF8 -#define MAR1BL 0xFFFEFA -#define IOAR1B 0xFFFEFC -#define ETCR1B 0xFFFEFE -#define DMAWER 0xFFFF20 -#define DMATCR 0xFFFF21 -#define DMACR0A 0xFFFF22 -#define DMACR0B 0xFFFF23 -#define DMACR1A 0xFFFF24 -#define DMACR1B 0xFFFF25 -#define DMABCRH 0xFFFF26 -#define DMABCRL 0xFFFF27 - -#define EDSAR0 0xFFFDC0 -#define EDDAR0 0xFFFDC4 -#define EDTCR0 0xFFFDC8 -#define EDMDR0 0xFFFDCC -#define EDMDR0H 0xFFFDCC -#define EDMDR0L 0xFFFDCD -#define EDACR0 0xFFFDCE -#define EDSAR1 0xFFFDD0 -#define EDDAR1 0xFFFDD4 -#define EDTCR1 0xFFFDD8 -#define EDMDR1 0xFFFDDC -#define EDMDR1H 0xFFFDDC -#define EDMDR1L 0xFFFDDD -#define EDACR1 0xFFFDDE -#define EDSAR2 0xFFFDE0 -#define EDDAR2 0xFFFDE4 -#define EDTCR2 0xFFFDE8 -#define EDMDR2 0xFFFDEC -#define EDMDR2H 0xFFFDEC -#define EDMDR2L 0xFFFDED -#define EDACR2 0xFFFDEE -#define EDSAR3 0xFFFDF0 -#define EDDAR3 0xFFFDF4 -#define EDTCR3 0xFFFDF8 -#define EDMDR3 0xFFFDFC -#define EDMDR3H 0xFFFDFC -#define EDMDR3L 0xFFFDFD -#define EDACR3 0xFFFDFE - -#define IPRA 0xFFFE00 -#define IPRB 0xFFFE02 -#define IPRC 0xFFFE04 -#define IPRD 0xFFFE06 -#define IPRE 0xFFFE08 -#define IPRF 0xFFFE0A -#define IPRG 0xFFFE0C -#define IPRH 0xFFFE0E -#define IPRI 0xFFFE10 -#define IPRJ 0xFFFE12 -#define IPRK 0xFFFE14 -#define ITSR 0xFFFE16 -#define SSIER 0xFFFE18 -#define ISCRH 0xFFFE1A -#define ISCRL 0xFFFE1C - -#define INTCR 0xFFFF31 -#define IER 0xFFFF32 -#define IERH 0xFFFF32 -#define IERL 0xFFFF33 -#define ISR 0xFFFF34 -#define ISRH 0xFFFF34 -#define ISRL 0xFFFF35 - -#define P1DDR 0xFFFE20 -#define P2DDR 0xFFFE21 -#define P3DDR 0xFFFE22 -#define P4DDR 0xFFFE23 -#define P5DDR 0xFFFE24 -#define P6DDR 0xFFFE25 -#define P7DDR 0xFFFE26 -#define P8DDR 0xFFFE27 -#define P9DDR 0xFFFE28 -#define PADDR 0xFFFE29 -#define PBDDR 0xFFFE2A -#define PCDDR 0xFFFE2B -#define PDDDR 0xFFFE2C -#define PEDDR 0xFFFE2D -#define PFDDR 0xFFFE2E -#define PGDDR 0xFFFE2F -#define PHDDR 0xFFFF74 - -#define PFCR0 0xFFFE32 -#define PFCR1 0xFFFE33 -#define PFCR2 0xFFFE34 - -#define PAPCR 0xFFFE36 -#define PBPCR 0xFFFE37 -#define PCPCR 0xFFFE38 -#define PDPCR 0xFFFE39 -#define PEPCR 0xFFFE3A - -#define P3ODR 0xFFFE3C -#define PAODR 0xFFFE3D - -#define P1DR 0xFFFF60 -#define P2DR 0xFFFF61 -#define P3DR 0xFFFF62 -#define P4DR 0xFFFF63 -#define P5DR 0xFFFF64 -#define P6DR 0xFFFF65 -#define P7DR 0xFFFF66 -#define P8DR 0xFFFF67 -#define P9DR 0xFFFF68 -#define PADR 0xFFFF69 -#define PBDR 0xFFFF6A -#define PCDR 0xFFFF6B -#define PDDR 0xFFFF6C -#define PEDR 0xFFFF6D -#define PFDR 0xFFFF6E -#define PGDR 0xFFFF6F -#define PHDR 0xFFFF72 - -#define PORT1 0xFFFF50 -#define PORT2 0xFFFF51 -#define PORT3 0xFFFF52 -#define PORT4 0xFFFF53 -#define PORT5 0xFFFF54 -#define PORT6 0xFFFF55 -#define PORT7 0xFFFF56 -#define PORT8 0xFFFF57 -#define PORT9 0xFFFF58 -#define PORTA 0xFFFF59 -#define PORTB 0xFFFF5A -#define PORTC 0xFFFF5B -#define PORTD 0xFFFF5C -#define PORTE 0xFFFF5D -#define PORTF 0xFFFF5E -#define PORTG 0xFFFF5F -#define PORTH 0xFFFF70 - -#define PCR 0xFFFF46 -#define PMR 0xFFFF47 -#define NDERH 0xFFFF48 -#define NDERL 0xFFFF49 -#define PODRH 0xFFFF4A -#define PODRL 0xFFFF4B -#define NDRH1 0xFFFF4C -#define NDRL1 0xFFFF4D -#define NDRH2 0xFFFF4E -#define NDRL2 0xFFFF4F - -#define SMR0 0xFFFF78 -#define BRR0 0xFFFF79 -#define SCR0 0xFFFF7A -#define TDR0 0xFFFF7B -#define SSR0 0xFFFF7C -#define RDR0 0xFFFF7D -#define SCMR0 0xFFFF7E -#define SMR1 0xFFFF80 -#define BRR1 0xFFFF81 -#define SCR1 0xFFFF82 -#define TDR1 0xFFFF83 -#define SSR1 0xFFFF84 -#define RDR1 0xFFFF85 -#define SCMR1 0xFFFF86 -#define SMR2 0xFFFF88 -#define BRR2 0xFFFF89 -#define SCR2 0xFFFF8A -#define TDR2 0xFFFF8B -#define SSR2 0xFFFF8C -#define RDR2 0xFFFF8D -#define SCMR2 0xFFFF8E - -#define IRCR0 0xFFFE1E -#define SEMR 0xFFFDA8 - -#define MDCR 0xFFFF3E -#define SYSCR 0xFFFF3D -#define MSTPCRH 0xFFFF40 -#define MSTPCRL 0xFFFF41 -#define FLMCR1 0xFFFFC8 -#define FLMCR2 0xFFFFC9 -#define EBR1 0xFFFFCA -#define EBR2 0xFFFFCB -#define CTGARC_RAMCR 0xFFFECE -#define SBYCR 0xFFFF3A -#define SCKCR 0xFFFF3B -#define PLLCR 0xFFFF45 - -#define TSTR 0xFFFFC0 -#define TSNC 0XFFFFC1 - -#define TCR0 0xFFFFD0 -#define TMDR0 0xFFFFD1 -#define TIORH0 0xFFFFD2 -#define TIORL0 0xFFFFD3 -#define TIER0 0xFFFFD4 -#define TSR0 0xFFFFD5 -#define TCNT0 0xFFFFD6 -#define GRA0 0xFFFFD8 -#define GRB0 0xFFFFDA -#define GRC0 0xFFFFDC -#define GRD0 0xFFFFDE -#define TCR1 0xFFFFE0 -#define TMDR1 0xFFFFE1 -#define TIORH1 0xFFFFE2 -#define TIORL1 0xFFFFE3 -#define TIER1 0xFFFFE4 -#define TSR1 0xFFFFE5 -#define TCNT1 0xFFFFE6 -#define GRA1 0xFFFFE8 -#define GRB1 0xFFFFEA -#define TCR2 0xFFFFF0 -#define TMDR2 0xFFFFF1 -#define TIORH2 0xFFFFF2 -#define TIORL2 0xFFFFF3 -#define TIER2 0xFFFFF4 -#define TSR2 0xFFFFF5 -#define TCNT2 0xFFFFF6 -#define GRA2 0xFFFFF8 -#define GRB2 0xFFFFFA -#define TCR3 0xFFFE80 -#define TMDR3 0xFFFE81 -#define TIORH3 0xFFFE82 -#define TIORL3 0xFFFE83 -#define TIER3 0xFFFE84 -#define TSR3 0xFFFE85 -#define TCNT3 0xFFFE86 -#define GRA3 0xFFFE88 -#define GRB3 0xFFFE8A -#define GRC3 0xFFFE8C -#define GRD3 0xFFFE8E -#define TCR4 0xFFFE90 -#define TMDR4 0xFFFE91 -#define TIORH4 0xFFFE92 -#define TIORL4 0xFFFE93 -#define TIER4 0xFFFE94 -#define TSR4 0xFFFE95 -#define TCNT4 0xFFFE96 -#define GRA4 0xFFFE98 -#define GRB4 0xFFFE9A -#define TCR5 0xFFFEA0 -#define TMDR5 0xFFFEA1 -#define TIORH5 0xFFFEA2 -#define TIORL5 0xFFFEA3 -#define TIER5 0xFFFEA4 -#define TSR5 0xFFFEA5 -#define TCNT5 0xFFFEA6 -#define GRA5 0xFFFEA8 -#define GRB5 0xFFFEAA - -#define _8TCR0 0xFFFFB0 -#define _8TCR1 0xFFFFB1 -#define _8TCSR0 0xFFFFB2 -#define _8TCSR1 0xFFFFB3 -#define _8TCORA0 0xFFFFB4 -#define _8TCORA1 0xFFFFB5 -#define _8TCORB0 0xFFFFB6 -#define _8TCORB1 0xFFFFB7 -#define _8TCNT0 0xFFFFB8 -#define _8TCNT1 0xFFFFB9 - -#define TCSR 0xFFFFBC -#define TCNT 0xFFFFBD -#define RSTCSRW 0xFFFFBE -#define RSTCSRR 0xFFFFBF - -#endif /* __KERNEL__ */ -#endif /* __REGS_H8S267x__ */ diff --git a/arch/h8300/include/asm/regs306x.h b/arch/h8300/include/asm/regs306x.h deleted file mode 100644 index 027dd633fa25..000000000000 --- a/arch/h8300/include/asm/regs306x.h +++ /dev/null @@ -1,212 +0,0 @@ -/* internal Peripherals Register address define */ -/* CPU: H8/306x */ - -#if !defined(__REGS_H8306x__) -#define __REGS_H8306x__ - -#if defined(__KERNEL__) - -#define DASTCR 0xFEE01A -#define DADR0 0xFEE09C -#define DADR1 0xFEE09D -#define DACR 0xFEE09E - -#define ADDRAH 0xFFFFE0 -#define ADDRAL 0xFFFFE1 -#define ADDRBH 0xFFFFE2 -#define ADDRBL 0xFFFFE3 -#define ADDRCH 0xFFFFE4 -#define ADDRCL 0xFFFFE5 -#define ADDRDH 0xFFFFE6 -#define ADDRDL 0xFFFFE7 -#define ADCSR 0xFFFFE8 -#define ADCR 0xFFFFE9 - -#define BRCR 0xFEE013 -#define ADRCR 0xFEE01E -#define CSCR 0xFEE01F -#define ABWCR 0xFEE020 -#define ASTCR 0xFEE021 -#define WCRH 0xFEE022 -#define WCRL 0xFEE023 -#define BCR 0xFEE024 -#define DRCRA 0xFEE026 -#define DRCRB 0xFEE027 -#define RTMCSR 0xFEE028 -#define RTCNT 0xFEE029 -#define RTCOR 0xFEE02A - -#define MAR0AR 0xFFFF20 -#define MAR0AE 0xFFFF21 -#define MAR0AH 0xFFFF22 -#define MAR0AL 0xFFFF23 -#define ETCR0AL 0xFFFF24 -#define ETCR0AH 0xFFFF25 -#define IOAR0A 0xFFFF26 -#define DTCR0A 0xFFFF27 -#define MAR0BR 0xFFFF28 -#define MAR0BE 0xFFFF29 -#define MAR0BH 0xFFFF2A -#define MAR0BL 0xFFFF2B -#define ETCR0BL 0xFFFF2C -#define ETCR0BH 0xFFFF2D -#define IOAR0B 0xFFFF2E -#define DTCR0B 0xFFFF2F -#define MAR1AR 0xFFFF30 -#define MAR1AE 0xFFFF31 -#define MAR1AH 0xFFFF32 -#define MAR1AL 0xFFFF33 -#define ETCR1AL 0xFFFF34 -#define ETCR1AH 0xFFFF35 -#define IOAR1A 0xFFFF36 -#define DTCR1A 0xFFFF37 -#define MAR1BR 0xFFFF38 -#define MAR1BE 0xFFFF39 -#define MAR1BH 0xFFFF3A -#define MAR1BL 0xFFFF3B -#define ETCR1BL 0xFFFF3C -#define ETCR1BH 0xFFFF3D -#define IOAR1B 0xFFFF3E -#define DTCR1B 0xFFFF3F - -#define ISCR 0xFEE014 -#define IER 0xFEE015 -#define ISR 0xFEE016 -#define IPRA 0xFEE018 -#define IPRB 0xFEE019 - -#define P1DDR 0xFEE000 -#define P2DDR 0xFEE001 -#define P3DDR 0xFEE002 -#define P4DDR 0xFEE003 -#define P5DDR 0xFEE004 -#define P6DDR 0xFEE005 -/*#define P7DDR 0xFEE006*/ -#define P8DDR 0xFEE007 -#define P9DDR 0xFEE008 -#define PADDR 0xFEE009 -#define PBDDR 0xFEE00A - -#define P1DR 0xFFFFD0 -#define P2DR 0xFFFFD1 -#define P3DR 0xFFFFD2 -#define P4DR 0xFFFFD3 -#define P5DR 0xFFFFD4 -#define P6DR 0xFFFFD5 -/*#define P7DR 0xFFFFD6*/ -#define P8DR 0xFFFFD7 -#define P9DR 0xFFFFD8 -#define PADR 0xFFFFD9 -#define PBDR 0xFFFFDA - -#define P2CR 0xFEE03C -#define P4CR 0xFEE03E -#define P5CR 0xFEE03F - -#define SMR0 0xFFFFB0 -#define BRR0 0xFFFFB1 -#define SCR0 0xFFFFB2 -#define TDR0 0xFFFFB3 -#define SSR0 0xFFFFB4 -#define RDR0 0xFFFFB5 -#define SCMR0 0xFFFFB6 -#define SMR1 0xFFFFB8 -#define BRR1 0xFFFFB9 -#define SCR1 0xFFFFBA -#define TDR1 0xFFFFBB -#define SSR1 0xFFFFBC -#define RDR1 0xFFFFBD -#define SCMR1 0xFFFFBE -#define SMR2 0xFFFFC0 -#define BRR2 0xFFFFC1 -#define SCR2 0xFFFFC2 -#define TDR2 0xFFFFC3 -#define SSR2 0xFFFFC4 -#define RDR2 0xFFFFC5 -#define SCMR2 0xFFFFC6 - -#define MDCR 0xFEE011 -#define SYSCR 0xFEE012 -#define DIVCR 0xFEE01B -#define MSTCRH 0xFEE01C -#define MSTCRL 0xFEE01D -#define FLMCR1 0xFEE030 -#define FLMCR2 0xFEE031 -#define EBR1 0xFEE032 -#define EBR2 0xFEE033 -#define RAMCR 0xFEE077 - -#define TSTR 0xFFFF60 -#define TSNC 0XFFFF61 -#define TMDR 0xFFFF62 -#define TOLR 0xFFFF63 -#define TISRA 0xFFFF64 -#define TISRB 0xFFFF65 -#define TISRC 0xFFFF66 -#define TCR0 0xFFFF68 -#define TIOR0 0xFFFF69 -#define TCNT0H 0xFFFF6A -#define TCNT0L 0xFFFF6B -#define GRA0H 0xFFFF6C -#define GRA0L 0xFFFF6D -#define GRB0H 0xFFFF6E -#define GRB0L 0xFFFF6F -#define TCR1 0xFFFF70 -#define TIOR1 0xFFFF71 -#define TCNT1H 0xFFFF72 -#define TCNT1L 0xFFFF73 -#define GRA1H 0xFFFF74 -#define GRA1L 0xFFFF75 -#define GRB1H 0xFFFF76 -#define GRB1L 0xFFFF77 -#define TCR3 0xFFFF78 -#define TIOR3 0xFFFF79 -#define TCNT3H 0xFFFF7A -#define TCNT3L 0xFFFF7B -#define GRA3H 0xFFFF7C -#define GRA3L 0xFFFF7D -#define GRB3H 0xFFFF7E -#define GRB3L 0xFFFF7F - -#define _8TCR0 0xFFFF80 -#define _8TCR1 0xFFFF81 -#define _8TCSR0 0xFFFF82 -#define _8TCSR1 0xFFFF83 -#define TCORA0 0xFFFF84 -#define TCORA1 0xFFFF85 -#define TCORB0 0xFFFF86 -#define TCORB1 0xFFFF87 -#define _8TCNT0 0xFFFF88 -#define _8TCNT1 0xFFFF89 - -#define _8TCR2 0xFFFF90 -#define _8TCR3 0xFFFF91 -#define _8TCSR2 0xFFFF92 -#define _8TCSR3 0xFFFF93 -#define TCORA2 0xFFFF94 -#define TCORA3 0xFFFF95 -#define TCORB2 0xFFFF96 -#define TCORB3 0xFFFF97 -#define _8TCNT2 0xFFFF98 -#define _8TCNT3 0xFFFF99 - -#define TCSR 0xFFFF8C -#define TCNT 0xFFFF8D -#define RSTCSR 0xFFFF8F - -#define TPMR 0xFFFFA0 -#define TPCR 0xFFFFA1 -#define NDERB 0xFFFFA2 -#define NDERA 0xFFFFA3 -#define NDRB1 0xFFFFA4 -#define NDRA1 0xFFFFA5 -#define NDRB2 0xFFFFA6 -#define NDRA2 0xFFFFA7 - -#define TCSR 0xFFFF8C -#define TCNT 0xFFFF8D -#define RSTCSRW 0xFFFF8E -#define RSTCSRR 0xFFFF8F - -#endif /* __KERNEL__ */ -#endif /* __REGS_H8306x__ */ diff --git a/arch/h8300/include/asm/scatterlist.h b/arch/h8300/include/asm/scatterlist.h deleted file mode 100644 index 82130eda0e5f..000000000000 --- a/arch/h8300/include/asm/scatterlist.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _H8300_SCATTERLIST_H -#define _H8300_SCATTERLIST_H - -#include <asm-generic/scatterlist.h> - -#endif /* !(_H8300_SCATTERLIST_H) */ diff --git a/arch/h8300/include/asm/sections.h b/arch/h8300/include/asm/sections.h deleted file mode 100644 index a81743e8b743..000000000000 --- a/arch/h8300/include/asm/sections.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _H8300_SECTIONS_H_ -#define _H8300_SECTIONS_H_ - -#include <asm-generic/sections.h> - -#endif diff --git a/arch/h8300/include/asm/segment.h b/arch/h8300/include/asm/segment.h deleted file mode 100644 index b79a82d0f99d..000000000000 --- a/arch/h8300/include/asm/segment.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef _H8300_SEGMENT_H -#define _H8300_SEGMENT_H - -/* define constants */ -#define USER_DATA (1) -#ifndef __USER_DS -#define __USER_DS (USER_DATA) -#endif -#define USER_PROGRAM (2) -#define SUPER_DATA (3) -#ifndef __KERNEL_DS -#define __KERNEL_DS (SUPER_DATA) -#endif -#define SUPER_PROGRAM (4) - -#ifndef __ASSEMBLY__ - -typedef struct { - unsigned long seg; -} mm_segment_t; - -#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) -#define USER_DS MAKE_MM_SEG(__USER_DS) -#define KERNEL_DS MAKE_MM_SEG(__KERNEL_DS) - -/* - * Get/set the SFC/DFC registers for MOVES instructions - */ - -static inline mm_segment_t get_fs(void) -{ - return USER_DS; -} - -static inline mm_segment_t get_ds(void) -{ - /* return the supervisor data space code */ - return KERNEL_DS; -} - -static inline void set_fs(mm_segment_t val) -{ -} - -#define segment_eq(a,b) ((a).seg == (b).seg) - -#endif /* __ASSEMBLY__ */ - -#endif /* _H8300_SEGMENT_H */ diff --git a/arch/h8300/include/asm/sh_bios.h b/arch/h8300/include/asm/sh_bios.h deleted file mode 100644 index b6bb6e58295c..000000000000 --- a/arch/h8300/include/asm/sh_bios.h +++ /dev/null @@ -1,29 +0,0 @@ -/* eCos HAL interface header */ - -#ifndef SH_BIOS_H -#define SH_BIOS_H - -#define HAL_IF_VECTOR_TABLE 0xfffe20 -#define CALL_IF_SET_CONSOLE_COMM 13 -#define QUERY_CURRENT -1 -#define MANGLER -3 - -/* Checking for GDB stub active */ -/* suggestion Jonathan Larmour */ -static int sh_bios_in_gdb_mode(void) -{ - static int gdb_active = -1; - if (gdb_active == -1) { - int (*set_console_comm)(int); - set_console_comm = ((void **)HAL_IF_VECTOR_TABLE)[CALL_IF_SET_CONSOLE_COMM]; - gdb_active = (set_console_comm(QUERY_CURRENT) == MANGLER); - } - return gdb_active; -} - -static void sh_bios_gdb_detach(void) -{ - -} - -#endif diff --git a/arch/h8300/include/asm/shm.h b/arch/h8300/include/asm/shm.h deleted file mode 100644 index ed6623c0545d..000000000000 --- a/arch/h8300/include/asm/shm.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef _H8300_SHM_H -#define _H8300_SHM_H - - -/* format of page table entries that correspond to shared memory pages - currently out in swap space (see also mm/swap.c): - bits 0-1 (PAGE_PRESENT) is = 0 - bits 8..2 (SWP_TYPE) are = SHM_SWP_TYPE - bits 31..9 are used like this: - bits 15..9 (SHM_ID) the id of the shared memory segment - bits 30..16 (SHM_IDX) the index of the page within the shared memory segment - (actually only bits 25..16 get used since SHMMAX is so low) - bit 31 (SHM_READ_ONLY) flag whether the page belongs to a read-only attach -*/ -/* on the m68k both bits 0 and 1 must be zero */ -/* format on the sun3 is similar, but bits 30, 31 are set to zero and all - others are reduced by 2. --m */ - -#ifndef CONFIG_SUN3 -#define SHM_ID_SHIFT 9 -#else -#define SHM_ID_SHIFT 7 -#endif -#define _SHM_ID_BITS 7 -#define SHM_ID_MASK ((1<<_SHM_ID_BITS)-1) - -#define SHM_IDX_SHIFT (SHM_ID_SHIFT+_SHM_ID_BITS) -#define _SHM_IDX_BITS 15 -#define SHM_IDX_MASK ((1<<_SHM_IDX_BITS)-1) - -#endif /* _H8300_SHM_H */ diff --git a/arch/h8300/include/asm/shmparam.h b/arch/h8300/include/asm/shmparam.h deleted file mode 100644 index d1863953ec64..000000000000 --- a/arch/h8300/include/asm/shmparam.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _H8300_SHMPARAM_H -#define _H8300_SHMPARAM_H - -#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */ - -#endif /* _H8300_SHMPARAM_H */ diff --git a/arch/h8300/include/asm/signal.h b/arch/h8300/include/asm/signal.h deleted file mode 100644 index 6341e36386f8..000000000000 --- a/arch/h8300/include/asm/signal.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef _H8300_SIGNAL_H -#define _H8300_SIGNAL_H - -#include <uapi/asm/signal.h> - -/* Most things should be clean enough to redefine this at will, if care - is taken to make libc match. */ - -#define _NSIG 64 -#define _NSIG_BPW 32 -#define _NSIG_WORDS (_NSIG / _NSIG_BPW) - -typedef unsigned long old_sigset_t; /* at least 32 bits */ - -typedef struct { - unsigned long sig[_NSIG_WORDS]; -} sigset_t; - -#define __ARCH_HAS_SA_RESTORER - -#include <asm/sigcontext.h> -#undef __HAVE_ARCH_SIG_BITOPS - -#endif /* _H8300_SIGNAL_H */ diff --git a/arch/h8300/include/asm/smp.h b/arch/h8300/include/asm/smp.h deleted file mode 100644 index 9e9bd7e58922..000000000000 --- a/arch/h8300/include/asm/smp.h +++ /dev/null @@ -1 +0,0 @@ -/* nothing required here yet */ diff --git a/arch/h8300/include/asm/spinlock.h b/arch/h8300/include/asm/spinlock.h deleted file mode 100644 index d5407fa173e4..000000000000 --- a/arch/h8300/include/asm/spinlock.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __H8300_SPINLOCK_H -#define __H8300_SPINLOCK_H - -#error "H8/300 doesn't do SMP yet" - -#endif diff --git a/arch/h8300/include/asm/string.h b/arch/h8300/include/asm/string.h deleted file mode 100644 index ca5034897d87..000000000000 --- a/arch/h8300/include/asm/string.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef _H8300_STRING_H_ -#define _H8300_STRING_H_ - -#ifdef __KERNEL__ /* only set these up for kernel code */ - -#include <asm/setup.h> -#include <asm/page.h> - -#define __HAVE_ARCH_MEMSET -extern void * memset(void * s, int c, size_t count); - -#define __HAVE_ARCH_MEMCPY -extern void * memcpy(void *d, const void *s, size_t count); - -#else /* KERNEL */ - -/* - * let user libraries deal with these, - * IMHO the kernel has no place defining these functions for user apps - */ - -#define __HAVE_ARCH_STRCPY 1 -#define __HAVE_ARCH_STRNCPY 1 -#define __HAVE_ARCH_STRCAT 1 -#define __HAVE_ARCH_STRNCAT 1 -#define __HAVE_ARCH_STRCMP 1 -#define __HAVE_ARCH_STRNCMP 1 -#define __HAVE_ARCH_STRNICMP 1 -#define __HAVE_ARCH_STRCHR 1 -#define __HAVE_ARCH_STRRCHR 1 -#define __HAVE_ARCH_STRSTR 1 -#define __HAVE_ARCH_STRLEN 1 -#define __HAVE_ARCH_STRNLEN 1 -#define __HAVE_ARCH_MEMSET 1 -#define __HAVE_ARCH_MEMCPY 1 -#define __HAVE_ARCH_MEMMOVE 1 -#define __HAVE_ARCH_MEMSCAN 1 -#define __HAVE_ARCH_MEMCMP 1 -#define __HAVE_ARCH_MEMCHR 1 -#define __HAVE_ARCH_STRTOK 1 - -#endif /* KERNEL */ - -#endif /* _M68K_STRING_H_ */ diff --git a/arch/h8300/include/asm/switch_to.h b/arch/h8300/include/asm/switch_to.h deleted file mode 100644 index cdd8731ce487..000000000000 --- a/arch/h8300/include/asm/switch_to.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef _H8300_SWITCH_TO_H -#define _H8300_SWITCH_TO_H - -/* - * switch_to(n) should switch tasks to task ptr, first checking that - * ptr isn't the current task, in which case it does nothing. This - * also clears the TS-flag if the task we switched to has used the - * math co-processor latest. - */ -/* - * switch_to() saves the extra registers, that are not saved - * automatically by SAVE_SWITCH_STACK in resume(), ie. d0-d5 and - * a0-a1. Some of these are used by schedule() and its predecessors - * and so we might get see unexpected behaviors when a task returns - * with unexpected register values. - * - * syscall stores these registers itself and none of them are used - * by syscall after the function in the syscall has been called. - * - * Beware that resume now expects *next to be in d1 and the offset of - * tss to be in a1. This saves a few instructions as we no longer have - * to push them onto the stack and read them back right after. - * - * 02/17/96 - Jes Sorensen (jds@kom.auc.dk) - * - * Changed 96/09/19 by Andreas Schwab - * pass prev in a0, next in a1, offset of tss in d1, and whether - * the mm structures are shared in d2 (to avoid atc flushing). - * - * H8/300 Porting 2002/09/04 Yoshinori Sato - */ - -asmlinkage void resume(void); -#define switch_to(prev,next,last) { \ - void *_last; \ - __asm__ __volatile__( \ - "mov.l %1, er0\n\t" \ - "mov.l %2, er1\n\t" \ - "mov.l %3, er2\n\t" \ - "jsr @_resume\n\t" \ - "mov.l er2,%0\n\t" \ - : "=r" (_last) \ - : "r" (&(prev->thread)), \ - "r" (&(next->thread)), \ - "g" (prev) \ - : "cc", "er0", "er1", "er2", "er3"); \ - (last) = _last; \ -} - -#endif /* _H8300_SWITCH_TO_H */ diff --git a/arch/h8300/include/asm/target_time.h b/arch/h8300/include/asm/target_time.h deleted file mode 100644 index 9f2a9aa1fe6f..000000000000 --- a/arch/h8300/include/asm/target_time.h +++ /dev/null @@ -1,4 +0,0 @@ -extern int platform_timer_setup(void (*timer_int)(int, void *, struct pt_regs *)); -extern void platform_timer_eoi(void); -extern void platform_gettod(unsigned int *year, unsigned int *mon, unsigned int *day, - unsigned int *hour, unsigned int *min, unsigned int *sec); diff --git a/arch/h8300/include/asm/termios.h b/arch/h8300/include/asm/termios.h deleted file mode 100644 index 93a63df56247..000000000000 --- a/arch/h8300/include/asm/termios.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef _H8300_TERMIOS_H -#define _H8300_TERMIOS_H - -#include <uapi/asm/termios.h> - -/* intr=^C quit=^| erase=del kill=^U - eof=^D vtime=\0 vmin=\1 sxtc=\0 - start=^Q stop=^S susp=^Z eol=\0 - reprint=^R discard=^U werase=^W lnext=^V - eol2=\0 -*/ -#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0" - -/* - * Translate a "termio" structure into a "termios". Ugh. - */ -#define user_termio_to_kernel_termios(termios, termio) \ -({ \ - unsigned short tmp; \ - get_user(tmp, &(termio)->c_iflag); \ - (termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \ - get_user(tmp, &(termio)->c_oflag); \ - (termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \ - get_user(tmp, &(termio)->c_cflag); \ - (termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \ - get_user(tmp, &(termio)->c_lflag); \ - (termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \ - get_user((termios)->c_line, &(termio)->c_line); \ - copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \ -}) - -/* - * Translate a "termios" structure into a "termio". Ugh. - */ -#define kernel_termios_to_user_termio(termio, termios) \ -({ \ - put_user((termios)->c_iflag, &(termio)->c_iflag); \ - put_user((termios)->c_oflag, &(termio)->c_oflag); \ - put_user((termios)->c_cflag, &(termio)->c_cflag); \ - put_user((termios)->c_lflag, &(termio)->c_lflag); \ - put_user((termios)->c_line, &(termio)->c_line); \ - copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \ -}) - -#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios2)) -#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios2)) -#define user_termios_to_kernel_termios_1(k, u) copy_from_user(k, u, sizeof(struct termios)) -#define kernel_termios_to_user_termios_1(u, k) copy_to_user(u, k, sizeof(struct termios)) - -#endif /* _H8300_TERMIOS_H */ diff --git a/arch/h8300/include/asm/thread_info.h b/arch/h8300/include/asm/thread_info.h deleted file mode 100644 index ec2f7777c65a..000000000000 --- a/arch/h8300/include/asm/thread_info.h +++ /dev/null @@ -1,103 +0,0 @@ -/* thread_info.h: h8300 low-level thread information - * adapted from the i386 and PPC versions by Yoshinori Sato <ysato@users.sourceforge.jp> - * - * Copyright (C) 2002 David Howells (dhowells@redhat.com) - * - Incorporating suggestions made by Linus Torvalds and Dave Miller - */ - -#ifndef _ASM_THREAD_INFO_H -#define _ASM_THREAD_INFO_H - -#include <asm/page.h> - -#ifdef __KERNEL__ - -#ifndef __ASSEMBLY__ - -/* - * low level task data. - * If you change this, change the TI_* offsets below to match. - */ -struct thread_info { - struct task_struct *task; /* main task structure */ - struct exec_domain *exec_domain; /* execution domain */ - unsigned long flags; /* low level flags */ - int cpu; /* cpu we're on */ - int preempt_count; /* 0 => preemptable, <0 => BUG */ - struct restart_block restart_block; -}; - -/* - * macros/functions for gaining access to the thread information structure - */ -#define INIT_THREAD_INFO(tsk) \ -{ \ - .task = &tsk, \ - .exec_domain = &default_exec_domain, \ - .flags = 0, \ - .cpu = 0, \ - .preempt_count = INIT_PREEMPT_COUNT, \ - .restart_block = { \ - .fn = do_no_restart_syscall, \ - }, \ -} - -#define init_thread_info (init_thread_union.thread_info) -#define init_stack (init_thread_union.stack) - - -/* - * Size of kernel stack for each process. This must be a power of 2... - */ -#define THREAD_SIZE_ORDER 1 -#define THREAD_SIZE 8192 /* 2 pages */ - - -/* how to get the thread information struct from C */ -static inline struct thread_info *current_thread_info(void) -{ - struct thread_info *ti; - __asm__( - "mov.l sp, %0 \n\t" - "and.l %1, %0" - : "=&r"(ti) - : "i" (~(THREAD_SIZE-1)) - ); - return ti; -} - -#endif /* __ASSEMBLY__ */ - -/* - * Offsets in thread_info structure, used in assembly code - */ -#define TI_TASK 0 -#define TI_EXECDOMAIN 4 -#define TI_FLAGS 8 -#define TI_CPU 12 -#define TI_PRE_COUNT 16 - -#define PREEMPT_ACTIVE 0x4000000 - -/* - * thread information flag bit numbers - */ -#define TIF_SYSCALL_TRACE 0 /* syscall trace active */ -#define TIF_SIGPENDING 1 /* signal pending */ -#define TIF_NEED_RESCHED 2 /* rescheduling necessary */ -#define TIF_MEMDIE 4 /* is terminating due to OOM killer */ -#define TIF_RESTORE_SIGMASK 5 /* restore signal mask in do_signal() */ -#define TIF_NOTIFY_RESUME 6 /* callback before returning to user */ - -/* as above, but as bit values */ -#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) -#define _TIF_SIGPENDING (1<<TIF_SIGPENDING) -#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) -#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) - -#define _TIF_WORK_MASK (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \ - _TIF_NOTIFY_RESUME) - -#endif /* __KERNEL__ */ - -#endif /* _ASM_THREAD_INFO_H */ diff --git a/arch/h8300/include/asm/timer.h b/arch/h8300/include/asm/timer.h deleted file mode 100644 index def80464d38f..000000000000 --- a/arch/h8300/include/asm/timer.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef __H8300_TIMER_H -#define __H8300_TIMER_H - -void h8300_timer_tick(void); -void h8300_timer_setup(void); -void h8300_gettod(unsigned int *year, unsigned int *mon, unsigned int *day, - unsigned int *hour, unsigned int *min, unsigned int *sec); - -#define TIMER_FREQ (CONFIG_CPU_CLOCK*10000) /* Timer input freq. */ - -#define calc_param(cnt, div, rate, limit) \ -do { \ - cnt = TIMER_FREQ / HZ; \ - for (div = 0; div < ARRAY_SIZE(divide_rate); div++) { \ - if (rate[div] == 0) \ - continue; \ - if ((cnt / rate[div]) > limit) \ - break; \ - } \ - if (div == ARRAY_SIZE(divide_rate)) \ - panic("Timer counter overflow"); \ - cnt /= divide_rate[div]; \ -} while(0) - -#endif diff --git a/arch/h8300/include/asm/timex.h b/arch/h8300/include/asm/timex.h deleted file mode 100644 index 23e67013439f..000000000000 --- a/arch/h8300/include/asm/timex.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * linux/include/asm-h8300/timex.h - * - * H8/300 architecture timex specifications - */ -#ifndef _ASM_H8300_TIMEX_H -#define _ASM_H8300_TIMEX_H - -#define CLOCK_TICK_RATE (CONFIG_CPU_CLOCK*1000/8192) /* Timer input freq. */ - -typedef unsigned long cycles_t; -extern short h8300_timer_count; - -static inline cycles_t get_cycles(void) -{ - return 0; -} - -#endif diff --git a/arch/h8300/include/asm/tlb.h b/arch/h8300/include/asm/tlb.h deleted file mode 100644 index 7f0743051ad5..000000000000 --- a/arch/h8300/include/asm/tlb.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __H8300_TLB_H__ -#define __H8300_TLB_H__ - -#define tlb_flush(tlb) do { } while(0) - -#include <asm-generic/tlb.h> - -#endif diff --git a/arch/h8300/include/asm/tlbflush.h b/arch/h8300/include/asm/tlbflush.h deleted file mode 100644 index 41c148a9208e..000000000000 --- a/arch/h8300/include/asm/tlbflush.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef _H8300_TLBFLUSH_H -#define _H8300_TLBFLUSH_H - -/* - * Copyright (C) 2000 Lineo, David McCullough <davidm@uclinux.org> - * Copyright (C) 2000-2002, Greg Ungerer <gerg@snapgear.com> - */ - -#include <asm/setup.h> - -/* - * flush all user-space atc entries. - */ -static inline void __flush_tlb(void) -{ - BUG(); -} - -static inline void __flush_tlb_one(unsigned long addr) -{ - BUG(); -} - -#define flush_tlb() __flush_tlb() - -/* - * flush all atc entries (both kernel and user-space entries). - */ -static inline void flush_tlb_all(void) -{ - BUG(); -} - -static inline void flush_tlb_mm(struct mm_struct *mm) -{ - BUG(); -} - -static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr) -{ - BUG(); -} - -static inline void flush_tlb_range(struct mm_struct *mm, - unsigned long start, unsigned long end) -{ - BUG(); -} - -static inline void flush_tlb_kernel_page(unsigned long addr) -{ - BUG(); -} - -#endif /* _H8300_TLBFLUSH_H */ diff --git a/arch/h8300/include/asm/topology.h b/arch/h8300/include/asm/topology.h deleted file mode 100644 index fdc121924d4c..000000000000 --- a/arch/h8300/include/asm/topology.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_H8300_TOPOLOGY_H -#define _ASM_H8300_TOPOLOGY_H - -#include <asm-generic/topology.h> - -#endif /* _ASM_H8300_TOPOLOGY_H */ diff --git a/arch/h8300/include/asm/traps.h b/arch/h8300/include/asm/traps.h deleted file mode 100644 index 41cf6be02f68..000000000000 --- a/arch/h8300/include/asm/traps.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * linux/include/asm-h8300/traps.h - * - * Copyright (C) 2003 Yoshinori Sato <ysato@users.sourceforge.jp> - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - */ - -#ifndef _H8300_TRAPS_H -#define _H8300_TRAPS_H - -extern void system_call(void); -extern void interrupt_entry(void); -extern void trace_break(void); - -#define JMP_OP 0x5a000000 -#define JSR_OP 0x5e000000 -#define VECTOR(address) ((JMP_OP)|((unsigned long)address)) -#define REDIRECT(address) ((JSR_OP)|((unsigned long)address)) - -#define TRACE_VEC 5 - -#define TRAP0_VEC 8 -#define TRAP1_VEC 9 -#define TRAP2_VEC 10 -#define TRAP3_VEC 11 - -#if defined(__H8300H__) -#define NR_TRAPS 12 -#endif -#if defined(__H8300S__) -#define NR_TRAPS 16 -#endif - -#endif /* _H8300_TRAPS_H */ diff --git a/arch/h8300/include/asm/types.h b/arch/h8300/include/asm/types.h deleted file mode 100644 index c012707f6037..000000000000 --- a/arch/h8300/include/asm/types.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef _H8300_TYPES_H -#define _H8300_TYPES_H - -#include <uapi/asm/types.h> - - -#define BITS_PER_LONG 32 - -#endif /* _H8300_TYPES_H */ diff --git a/arch/h8300/include/asm/uaccess.h b/arch/h8300/include/asm/uaccess.h deleted file mode 100644 index 8725d1ad4272..000000000000 --- a/arch/h8300/include/asm/uaccess.h +++ /dev/null @@ -1,163 +0,0 @@ -#ifndef __H8300_UACCESS_H -#define __H8300_UACCESS_H - -/* - * User space memory access functions - */ -#include <linux/sched.h> -#include <linux/mm.h> -#include <linux/string.h> - -#include <asm/segment.h> - -#define VERIFY_READ 0 -#define VERIFY_WRITE 1 - -/* We let the MMU do all checking */ -#define access_ok(type, addr, size) __access_ok((unsigned long)addr,size) -static inline int __access_ok(unsigned long addr, unsigned long size) -{ -#define RANGE_CHECK_OK(addr, size, lower, upper) \ - (((addr) >= (lower)) && (((addr) + (size)) < (upper))) - - extern unsigned long _ramend; - return(RANGE_CHECK_OK(addr, size, 0L, (unsigned long)&_ramend)); -} - -/* - * The exception table consists of pairs of addresses: the first is the - * address of an instruction that is allowed to fault, and the second is - * the address at which the program should continue. No registers are - * modified, so it is entirely up to the continuation code to figure out - * what to do. - * - * All the routines below use bits of fixup code that are out of line - * with the main instruction path. This means when everything is well, - * we don't even have to jump over them. Further, they do not intrude - * on our cache or tlb entries. - */ - -struct exception_table_entry -{ - unsigned long insn, fixup; -}; - -/* Returns 0 if exception not found and fixup otherwise. */ -extern unsigned long search_exception_table(unsigned long); - - -/* - * These are the main single-value transfer routines. They automatically - * use the right size if we just have the right pointer type. - */ - -#define put_user(x, ptr) \ -({ \ - int __pu_err = 0; \ - typeof(*(ptr)) __pu_val = (x); \ - switch (sizeof (*(ptr))) { \ - case 1: \ - case 2: \ - case 4: \ - *(ptr) = (__pu_val); \ - break; \ - case 8: \ - memcpy(ptr, &__pu_val, sizeof (*(ptr))); \ - break; \ - default: \ - __pu_err = __put_user_bad(); \ - break; \ - } \ - __pu_err; \ -}) -#define __put_user(x, ptr) put_user(x, ptr) - -extern int __put_user_bad(void); - -/* - * Tell gcc we read from memory instead of writing: this is because - * we do not write to any memory gcc knows about, so there are no - * aliasing issues. - */ - -#define __ptr(x) ((unsigned long *)(x)) - -/* - * Tell gcc we read from memory instead of writing: this is because - * we do not write to any memory gcc knows about, so there are no - * aliasing issues. - */ - -#define get_user(x, ptr) \ -({ \ - int __gu_err = 0; \ - typeof(*(ptr)) __gu_val = *ptr; \ - switch (sizeof(*(ptr))) { \ - case 1: \ - case 2: \ - case 4: \ - case 8: \ - break; \ - default: \ - __gu_err = __get_user_bad(); \ - break; \ - } \ - (x) = __gu_val; \ - __gu_err; \ -}) -#define __get_user(x, ptr) get_user(x, ptr) - -extern int __get_user_bad(void); - -#define copy_from_user(to, from, n) (memcpy(to, from, n), 0) -#define copy_to_user(to, from, n) (memcpy(to, from, n), 0) - -#define __copy_from_user(to, from, n) copy_from_user(to, from, n) -#define __copy_to_user(to, from, n) copy_to_user(to, from, n) -#define __copy_to_user_inatomic __copy_to_user -#define __copy_from_user_inatomic __copy_from_user - -#define copy_to_user_ret(to,from,n,retval) ({ if (copy_to_user(to,from,n)) return retval; }) - -#define copy_from_user_ret(to,from,n,retval) ({ if (copy_from_user(to,from,n)) return retval; }) - -/* - * Copy a null terminated string from userspace. - */ - -static inline long -strncpy_from_user(char *dst, const char *src, long count) -{ - char *tmp; - strncpy(dst, src, count); - for (tmp = dst; *tmp && count > 0; tmp++, count--) - ; - return(tmp - dst); /* DAVIDM should we count a NUL ? check getname */ -} - -/* - * Return the size of a string (including the ending 0) - * - * Return 0 on exception, a value greater than N if too long - */ -static inline long strnlen_user(const char *src, long n) -{ - return(strlen(src) + 1); /* DAVIDM make safer */ -} - -#define strlen_user(str) strnlen_user(str, 32767) - -/* - * Zero Userspace - */ - -static inline unsigned long -clear_user(void *to, unsigned long n) -{ - memset(to, 0, n); - return 0; -} - -#define __clear_user clear_user - -#endif /* _H8300_UACCESS_H */ diff --git a/arch/h8300/include/asm/ucontext.h b/arch/h8300/include/asm/ucontext.h deleted file mode 100644 index 0bcf8f85fab9..000000000000 --- a/arch/h8300/include/asm/ucontext.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef _H8300_UCONTEXT_H -#define _H8300_UCONTEXT_H - -struct ucontext { - unsigned long uc_flags; - struct ucontext *uc_link; - stack_t uc_stack; - struct sigcontext uc_mcontext; - sigset_t uc_sigmask; /* mask last for extensibility */ -}; - -#endif diff --git a/arch/h8300/include/asm/unaligned.h b/arch/h8300/include/asm/unaligned.h deleted file mode 100644 index b8d06c70c2da..000000000000 --- a/arch/h8300/include/asm/unaligned.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef _ASM_H8300_UNALIGNED_H -#define _ASM_H8300_UNALIGNED_H - -#include <linux/unaligned/be_memmove.h> -#include <linux/unaligned/le_byteshift.h> -#include <linux/unaligned/generic.h> - -#define get_unaligned __get_unaligned_be -#define put_unaligned __put_unaligned_be - -#endif /* _ASM_H8300_UNALIGNED_H */ diff --git a/arch/h8300/include/asm/unistd.h b/arch/h8300/include/asm/unistd.h deleted file mode 100644 index ab671ecf5196..000000000000 --- a/arch/h8300/include/asm/unistd.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef _ASM_H8300_UNISTD_H_ -#define _ASM_H8300_UNISTD_H_ - -#include <uapi/asm/unistd.h> - - -#define NR_syscalls 321 - -#define __ARCH_WANT_OLD_READDIR -#define __ARCH_WANT_OLD_STAT -#define __ARCH_WANT_STAT64 -#define __ARCH_WANT_SYS_ALARM -#define __ARCH_WANT_SYS_GETHOSTNAME -#define __ARCH_WANT_SYS_IPC -#define __ARCH_WANT_SYS_PAUSE -#define __ARCH_WANT_SYS_SGETMASK -#define __ARCH_WANT_SYS_SIGNAL -#define __ARCH_WANT_SYS_TIME -#define __ARCH_WANT_SYS_UTIME -#define __ARCH_WANT_SYS_WAITPID -#define __ARCH_WANT_SYS_SOCKETCALL -#define __ARCH_WANT_SYS_FADVISE64 -#define __ARCH_WANT_SYS_GETPGRP -#define __ARCH_WANT_SYS_LLSEEK -#define __ARCH_WANT_SYS_NICE -#define __ARCH_WANT_SYS_OLD_GETRLIMIT -#define __ARCH_WANT_SYS_OLD_MMAP -#define __ARCH_WANT_SYS_OLD_SELECT -#define __ARCH_WANT_SYS_OLDUMOUNT -#define __ARCH_WANT_SYS_SIGPENDING -#define __ARCH_WANT_SYS_SIGPROCMASK -#define __ARCH_WANT_SYS_FORK -#define __ARCH_WANT_SYS_VFORK -#define __ARCH_WANT_SYS_CLONE - -#endif /* _ASM_H8300_UNISTD_H_ */ diff --git a/arch/h8300/include/asm/user.h b/arch/h8300/include/asm/user.h deleted file mode 100644 index 14a9e18950f1..000000000000 --- a/arch/h8300/include/asm/user.h +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef _H8300_USER_H -#define _H8300_USER_H - -#include <asm/page.h> - -/* Core file format: The core file is written in such a way that gdb - can understand it and provide useful information to the user (under - linux we use the 'trad-core' bfd). There are quite a number of - obstacles to being able to view the contents of the floating point - registers, and until these are solved you will not be able to view the - contents of them. Actually, you can read in the core file and look at - the contents of the user struct to find out what the floating point - registers contain. - The actual file contents are as follows: - UPAGE: 1 page consisting of a user struct that tells gdb what is present - in the file. Directly after this is a copy of the task_struct, which - is currently not used by gdb, but it may come in useful at some point. - All of the registers are stored as part of the upage. The upage should - always be only one page. - DATA: The data area is stored. We use current->end_text to - current->brk to pick up all of the user variables, plus any memory - that may have been malloced. No attempt is made to determine if a page - is demand-zero or if a page is totally unused, we just cover the entire - range. All of the addresses are rounded in such a way that an integral - number of pages is written. - STACK: We need the stack information in order to get a meaningful - backtrace. We need to write the data from (esp) to - current->start_stack, so we round each of these off in order to be able - to write an integer number of pages. - The minimum core file size is 3 pages, or 12288 bytes. -*/ - -/* This is the old layout of "struct pt_regs" as of Linux 1.x, and - is still the layout used by user (the new pt_regs doesn't have - all registers). */ -struct user_regs_struct { - long er1,er2,er3,er4,er5,er6; - long er0; - long usp; - long orig_er0; - short ccr; - long pc; -}; - - -/* When the kernel dumps core, it starts by dumping the user struct - - this will be used by gdb to figure out where the data and stack segments - are within the file, and what virtual addresses to use. */ -struct user{ -/* We start with the registers, to mimic the way that "memory" is returned - from the ptrace(3,...) function. */ - struct user_regs_struct regs; /* Where the registers are actually stored */ -/* ptrace does not yet supply these. Someday.... */ -/* The rest of this junk is to help gdb figure out what goes where */ - unsigned long int u_tsize; /* Text segment size (pages). */ - unsigned long int u_dsize; /* Data segment size (pages). */ - unsigned long int u_ssize; /* Stack segment size (pages). */ - unsigned long start_code; /* Starting virtual address of text. */ - unsigned long start_stack; /* Starting virtual address of stack area. - This is actually the bottom of the stack, - the top of the stack is always found in the - esp register. */ - long int signal; /* Signal that caused the core dump. */ - int reserved; /* No longer used */ - unsigned long u_ar0; /* Used by gdb to help find the values for */ - /* the registers. */ - unsigned long magic; /* To uniquely identify a core file */ - char u_comm[32]; /* User command that was responsible */ -}; -#define NBPG PAGE_SIZE -#define UPAGES 1 -#define HOST_TEXT_START_ADDR (u.start_code) -#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) - -#endif diff --git a/arch/h8300/include/asm/virtconvert.h b/arch/h8300/include/asm/virtconvert.h deleted file mode 100644 index 19cfd62b11c3..000000000000 --- a/arch/h8300/include/asm/virtconvert.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef __H8300_VIRT_CONVERT__ -#define __H8300_VIRT_CONVERT__ - -/* - * Macros used for converting between virtual and physical mappings. - */ - -#ifdef __KERNEL__ - -#include <asm/setup.h> -#include <asm/page.h> - -#define phys_to_virt(vaddr) ((void *) (vaddr)) -#define virt_to_phys(vaddr) ((unsigned long) (vaddr)) - -#define virt_to_bus virt_to_phys -#define bus_to_virt phys_to_virt - -#endif -#endif diff --git a/arch/h8300/include/uapi/asm/Kbuild b/arch/h8300/include/uapi/asm/Kbuild deleted file mode 100644 index 040178cdb3eb..000000000000 --- a/arch/h8300/include/uapi/asm/Kbuild +++ /dev/null @@ -1,34 +0,0 @@ -# UAPI Header export list -include include/uapi/asm-generic/Kbuild.asm - -header-y += auxvec.h -header-y += bitsperlong.h -header-y += byteorder.h -header-y += errno.h -header-y += fcntl.h -header-y += ioctl.h -header-y += ioctls.h -header-y += ipcbuf.h -header-y += kvm_para.h -header-y += mman.h -header-y += msgbuf.h -header-y += param.h -header-y += poll.h -header-y += posix_types.h -header-y += ptrace.h -header-y += resource.h -header-y += sembuf.h -header-y += setup.h -header-y += shmbuf.h -header-y += sigcontext.h -header-y += siginfo.h -header-y += signal.h -header-y += socket.h -header-y += sockios.h -header-y += stat.h -header-y += statfs.h -header-y += swab.h -header-y += termbits.h -header-y += termios.h -header-y += types.h -header-y += unistd.h diff --git a/arch/h8300/include/uapi/asm/auxvec.h b/arch/h8300/include/uapi/asm/auxvec.h deleted file mode 100644 index 1d36fe38b088..000000000000 --- a/arch/h8300/include/uapi/asm/auxvec.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifndef __ASMH8300_AUXVEC_H -#define __ASMH8300_AUXVEC_H - -#endif diff --git a/arch/h8300/include/uapi/asm/bitsperlong.h b/arch/h8300/include/uapi/asm/bitsperlong.h deleted file mode 100644 index 6dc0bb0c13b2..000000000000 --- a/arch/h8300/include/uapi/asm/bitsperlong.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/bitsperlong.h> diff --git a/arch/h8300/include/uapi/asm/byteorder.h b/arch/h8300/include/uapi/asm/byteorder.h deleted file mode 100644 index 13539da99efd..000000000000 --- a/arch/h8300/include/uapi/asm/byteorder.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _H8300_BYTEORDER_H -#define _H8300_BYTEORDER_H - -#include <linux/byteorder/big_endian.h> - -#endif /* _H8300_BYTEORDER_H */ diff --git a/arch/h8300/include/uapi/asm/errno.h b/arch/h8300/include/uapi/asm/errno.h deleted file mode 100644 index 0c2f5641fdcc..000000000000 --- a/arch/h8300/include/uapi/asm/errno.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _H8300_ERRNO_H -#define _H8300_ERRNO_H - -#include <asm-generic/errno.h> - -#endif /* _H8300_ERRNO_H */ diff --git a/arch/h8300/include/uapi/asm/fcntl.h b/arch/h8300/include/uapi/asm/fcntl.h deleted file mode 100644 index 1952cb2e3b06..000000000000 --- a/arch/h8300/include/uapi/asm/fcntl.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef _H8300_FCNTL_H -#define _H8300_FCNTL_H - -#define O_DIRECTORY 040000 /* must be a directory */ -#define O_NOFOLLOW 0100000 /* don't follow links */ -#define O_DIRECT 0200000 /* direct disk access hint - currently ignored */ -#define O_LARGEFILE 0400000 - -#include <asm-generic/fcntl.h> - -#endif /* _H8300_FCNTL_H */ diff --git a/arch/h8300/include/uapi/asm/ioctl.h b/arch/h8300/include/uapi/asm/ioctl.h deleted file mode 100644 index b279fe06dfe5..000000000000 --- a/arch/h8300/include/uapi/asm/ioctl.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/ioctl.h> diff --git a/arch/h8300/include/uapi/asm/ioctls.h b/arch/h8300/include/uapi/asm/ioctls.h deleted file mode 100644 index 30eaed2facdb..000000000000 --- a/arch/h8300/include/uapi/asm/ioctls.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __ARCH_H8300_IOCTLS_H__ -#define __ARCH_H8300_IOCTLS_H__ - -#define FIOQSIZE 0x545E - -#include <asm-generic/ioctls.h> - -#endif /* __ARCH_H8300_IOCTLS_H__ */ diff --git a/arch/h8300/include/uapi/asm/ipcbuf.h b/arch/h8300/include/uapi/asm/ipcbuf.h deleted file mode 100644 index 84c7e51cb6d0..000000000000 --- a/arch/h8300/include/uapi/asm/ipcbuf.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/ipcbuf.h> diff --git a/arch/h8300/include/uapi/asm/kvm_para.h b/arch/h8300/include/uapi/asm/kvm_para.h deleted file mode 100644 index 14fab8f0b957..000000000000 --- a/arch/h8300/include/uapi/asm/kvm_para.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/kvm_para.h> diff --git a/arch/h8300/include/uapi/asm/mman.h b/arch/h8300/include/uapi/asm/mman.h deleted file mode 100644 index 8eebf89f5ab1..000000000000 --- a/arch/h8300/include/uapi/asm/mman.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/mman.h> diff --git a/arch/h8300/include/uapi/asm/msgbuf.h b/arch/h8300/include/uapi/asm/msgbuf.h deleted file mode 100644 index 6b148cd09aa5..000000000000 --- a/arch/h8300/include/uapi/asm/msgbuf.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef _H8300_MSGBUF_H -#define _H8300_MSGBUF_H - -/* - * The msqid64_ds structure for H8/300 architecture. - * Note extra padding because this structure is passed back and forth - * between kernel and user space. - * - * Pad space is left for: - * - 64-bit time_t to solve y2038 problem - * - 2 miscellaneous 32-bit values - */ - -struct msqid64_ds { - struct ipc64_perm msg_perm; - __kernel_time_t msg_stime; /* last msgsnd time */ - unsigned long __unused1; - __kernel_time_t msg_rtime; /* last msgrcv time */ - unsigned long __unused2; - __kernel_time_t msg_ctime; /* last change time */ - unsigned long __unused3; - unsigned long msg_cbytes; /* current number of bytes on queue */ - unsigned long msg_qnum; /* number of messages in queue */ - unsigned long msg_qbytes; /* max number of bytes on queue */ - __kernel_pid_t msg_lspid; /* pid of last msgsnd */ - __kernel_pid_t msg_lrpid; /* last receive pid */ - unsigned long __unused4; - unsigned long __unused5; -}; - -#endif /* _H8300_MSGBUF_H */ diff --git a/arch/h8300/include/uapi/asm/param.h b/arch/h8300/include/uapi/asm/param.h deleted file mode 100644 index 3dd18ae15f03..000000000000 --- a/arch/h8300/include/uapi/asm/param.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef _UAPI_H8300_PARAM_H -#define _UAPI_H8300_PARAM_H - -#ifndef __KERNEL__ -#define HZ 100 -#endif - -#define EXEC_PAGESIZE 4096 - -#ifndef NOGROUP -#define NOGROUP (-1) -#endif - -#define MAXHOSTNAMELEN 64 /* max length of hostname */ - -#endif /* _UAPI_H8300_PARAM_H */ diff --git a/arch/h8300/include/uapi/asm/poll.h b/arch/h8300/include/uapi/asm/poll.h deleted file mode 100644 index f61540c22d94..000000000000 --- a/arch/h8300/include/uapi/asm/poll.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef __H8300_POLL_H -#define __H8300_POLL_H - -#define POLLWRNORM POLLOUT -#define POLLWRBAND 256 - -#include <asm-generic/poll.h> - -#undef POLLREMOVE - -#endif diff --git a/arch/h8300/include/uapi/asm/posix_types.h b/arch/h8300/include/uapi/asm/posix_types.h deleted file mode 100644 index 91e62ba4c7b0..000000000000 --- a/arch/h8300/include/uapi/asm/posix_types.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef __ARCH_H8300_POSIX_TYPES_H -#define __ARCH_H8300_POSIX_TYPES_H - -/* - * This file is generally used by user-level software, so you need to - * be a little careful about namespace pollution etc. Also, we cannot - * assume GCC is being used. - */ - -typedef unsigned short __kernel_mode_t; -#define __kernel_mode_t __kernel_mode_t - -typedef unsigned short __kernel_ipc_pid_t; -#define __kernel_ipc_pid_t __kernel_ipc_pid_t - -typedef unsigned short __kernel_uid_t; -typedef unsigned short __kernel_gid_t; -#define __kernel_uid_t __kernel_uid_t - -typedef unsigned short __kernel_old_uid_t; -typedef unsigned short __kernel_old_gid_t; -#define __kernel_old_uid_t __kernel_old_uid_t - -#include <asm-generic/posix_types.h> - -#endif diff --git a/arch/h8300/include/uapi/asm/ptrace.h b/arch/h8300/include/uapi/asm/ptrace.h deleted file mode 100644 index ef39ec5977b6..000000000000 --- a/arch/h8300/include/uapi/asm/ptrace.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef _UAPI_H8300_PTRACE_H -#define _UAPI_H8300_PTRACE_H - -#ifndef __ASSEMBLY__ - -#define PT_ER1 0 -#define PT_ER2 1 -#define PT_ER3 2 -#define PT_ER4 3 -#define PT_ER5 4 -#define PT_ER6 5 -#define PT_ER0 6 -#define PT_ORIG_ER0 7 -#define PT_CCR 8 -#define PT_PC 9 -#define PT_USP 10 -#define PT_EXR 12 - -/* this struct defines the way the registers are stored on the - stack during a system call. */ - -struct pt_regs { - long retpc; - long er4; - long er5; - long er6; - long er3; - long er2; - long er1; - long orig_er0; - unsigned short ccr; - long er0; - long vector; -#if defined(CONFIG_CPU_H8S) - unsigned short exr; -#endif - unsigned long pc; -} __attribute__((aligned(2),packed)); - -#define PTRACE_GETREGS 12 -#define PTRACE_SETREGS 13 - -#endif /* __ASSEMBLY__ */ -#endif /* _UAPI_H8300_PTRACE_H */ diff --git a/arch/h8300/include/uapi/asm/resource.h b/arch/h8300/include/uapi/asm/resource.h deleted file mode 100644 index 46c5f4391607..000000000000 --- a/arch/h8300/include/uapi/asm/resource.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _H8300_RESOURCE_H -#define _H8300_RESOURCE_H - -#include <asm-generic/resource.h> - -#endif /* _H8300_RESOURCE_H */ diff --git a/arch/h8300/include/uapi/asm/sembuf.h b/arch/h8300/include/uapi/asm/sembuf.h deleted file mode 100644 index e04a3ec0cb92..000000000000 --- a/arch/h8300/include/uapi/asm/sembuf.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef _H8300_SEMBUF_H -#define _H8300_SEMBUF_H - -/* - * The semid64_ds structure for m68k architecture. - * Note extra padding because this structure is passed back and forth - * between kernel and user space. - * - * Pad space is left for: - * - 64-bit time_t to solve y2038 problem - * - 2 miscellaneous 32-bit values - */ - -struct semid64_ds { - struct ipc64_perm sem_perm; /* permissions .. see ipc.h */ - __kernel_time_t sem_otime; /* last semop time */ - unsigned long __unused1; - __kernel_time_t sem_ctime; /* last change time */ - unsigned long __unused2; - unsigned long sem_nsems; /* no. of semaphores in array */ - unsigned long __unused3; - unsigned long __unused4; -}; - -#endif /* _H8300_SEMBUF_H */ diff --git a/arch/h8300/include/uapi/asm/setup.h b/arch/h8300/include/uapi/asm/setup.h deleted file mode 100644 index e2c600e96733..000000000000 --- a/arch/h8300/include/uapi/asm/setup.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __H8300_SETUP_H -#define __H8300_SETUP_H - -#define COMMAND_LINE_SIZE 512 - -#endif diff --git a/arch/h8300/include/uapi/asm/shmbuf.h b/arch/h8300/include/uapi/asm/shmbuf.h deleted file mode 100644 index 64e77993a7a9..000000000000 --- a/arch/h8300/include/uapi/asm/shmbuf.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef _H8300_SHMBUF_H -#define _H8300_SHMBUF_H - -/* - * The shmid64_ds structure for m68k architecture. - * Note extra padding because this structure is passed back and forth - * between kernel and user space. - * - * Pad space is left for: - * - 64-bit time_t to solve y2038 problem - * - 2 miscellaneous 32-bit values - */ - -struct shmid64_ds { - struct ipc64_perm shm_perm; /* operation perms */ - size_t shm_segsz; /* size of segment (bytes) */ - __kernel_time_t shm_atime; /* last attach time */ - unsigned long __unused1; - __kernel_time_t shm_dtime; /* last detach time */ - unsigned long __unused2; - __kernel_time_t shm_ctime; /* last change time */ - unsigned long __unused3; - __kernel_pid_t shm_cpid; /* pid of creator */ - __kernel_pid_t shm_lpid; /* pid of last operator */ - unsigned long shm_nattch; /* no. of current attaches */ - unsigned long __unused4; - unsigned long __unused5; -}; - -struct shminfo64 { - unsigned long shmmax; - unsigned long shmmin; - unsigned long shmmni; - unsigned long shmseg; - unsigned long shmall; - unsigned long __unused1; - unsigned long __unused2; - unsigned long __unused3; - unsigned long __unused4; -}; - -#endif /* _H8300_SHMBUF_H */ diff --git a/arch/h8300/include/uapi/asm/sigcontext.h b/arch/h8300/include/uapi/asm/sigcontext.h deleted file mode 100644 index e4b81505f8f8..000000000000 --- a/arch/h8300/include/uapi/asm/sigcontext.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef _ASM_H8300_SIGCONTEXT_H -#define _ASM_H8300_SIGCONTEXT_H - -struct sigcontext { - unsigned long sc_mask; /* old sigmask */ - unsigned long sc_usp; /* old user stack pointer */ - unsigned long sc_er0; - unsigned long sc_er1; - unsigned long sc_er2; - unsigned long sc_er3; - unsigned long sc_er4; - unsigned long sc_er5; - unsigned long sc_er6; - unsigned short sc_ccr; - unsigned long sc_pc; -}; - -#endif diff --git a/arch/h8300/include/uapi/asm/siginfo.h b/arch/h8300/include/uapi/asm/siginfo.h deleted file mode 100644 index bc8fbea931a5..000000000000 --- a/arch/h8300/include/uapi/asm/siginfo.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _H8300_SIGINFO_H -#define _H8300_SIGINFO_H - -#include <asm-generic/siginfo.h> - -#endif diff --git a/arch/h8300/include/uapi/asm/signal.h b/arch/h8300/include/uapi/asm/signal.h deleted file mode 100644 index af3a6c37fee6..000000000000 --- a/arch/h8300/include/uapi/asm/signal.h +++ /dev/null @@ -1,115 +0,0 @@ -#ifndef _UAPI_H8300_SIGNAL_H -#define _UAPI_H8300_SIGNAL_H - -#include <linux/types.h> - -/* Avoid too many header ordering problems. */ -struct siginfo; - -#ifndef __KERNEL__ -/* Here we must cater to libcs that poke about in kernel headers. */ - -#define NSIG 32 -typedef unsigned long sigset_t; - -#endif /* __KERNEL__ */ - -#define SIGHUP 1 -#define SIGINT 2 -#define SIGQUIT 3 -#define SIGILL 4 -#define SIGTRAP 5 -#define SIGABRT 6 -#define SIGIOT 6 -#define SIGBUS 7 -#define SIGFPE 8 -#define SIGKILL 9 -#define SIGUSR1 10 -#define SIGSEGV 11 -#define SIGUSR2 12 -#define SIGPIPE 13 -#define SIGALRM 14 -#define SIGTERM 15 -#define SIGSTKFLT 16 -#define SIGCHLD 17 -#define SIGCONT 18 -#define SIGSTOP 19 -#define SIGTSTP 20 -#define SIGTTIN 21 -#define SIGTTOU 22 -#define SIGURG 23 -#define SIGXCPU 24 -#define SIGXFSZ 25 -#define SIGVTALRM 26 -#define SIGPROF 27 -#define SIGWINCH 28 -#define SIGIO 29 -#define SIGPOLL SIGIO -/* -#define SIGLOST 29 -*/ -#define SIGPWR 30 -#define SIGSYS 31 -#define SIGUNUSED 31 - -/* These should not be considered constants from userland. */ -#define SIGRTMIN 32 -#define SIGRTMAX _NSIG - -/* - * SA_FLAGS values: - * - * SA_ONSTACK indicates that a registered stack_t will be used. - * SA_RESTART flag to get restarting signals (which were the default long ago) - * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop. - * SA_RESETHAND clears the handler when the signal is delivered. - * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies. - * SA_NODEFER prevents the current signal from being masked in the handler. - * - * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single - * Unix names RESETHAND and NODEFER respectively. - */ -#define SA_NOCLDSTOP 0x00000001 -#define SA_NOCLDWAIT 0x00000002 /* not supported yet */ -#define SA_SIGINFO 0x00000004 -#define SA_ONSTACK 0x08000000 -#define SA_RESTART 0x10000000 -#define SA_NODEFER 0x40000000 -#define SA_RESETHAND 0x80000000 - -#define SA_NOMASK SA_NODEFER -#define SA_ONESHOT SA_RESETHAND - -#define SA_RESTORER 0x04000000 - -#define MINSIGSTKSZ 2048 -#define SIGSTKSZ 8192 - -#include <asm-generic/signal-defs.h> - -#ifndef __KERNEL__ -/* Here we must cater to libcs that poke about in kernel headers. */ - -struct sigaction { - union { - __sighandler_t _sa_handler; - void (*_sa_sigaction)(int, struct siginfo *, void *); - } _u; - sigset_t sa_mask; - unsigned long sa_flags; - void (*sa_restorer)(void); -}; - -#define sa_handler _u._sa_handler -#define sa_sigaction _u._sa_sigaction - -#endif /* __KERNEL__ */ - -typedef struct sigaltstack { - void *ss_sp; - int ss_flags; - size_t ss_size; -} stack_t; - - -#endif /* _UAPI_H8300_SIGNAL_H */ diff --git a/arch/h8300/include/uapi/asm/socket.h b/arch/h8300/include/uapi/asm/socket.h deleted file mode 100644 index 9490758c5e2b..000000000000 --- a/arch/h8300/include/uapi/asm/socket.h +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef _ASM_SOCKET_H -#define _ASM_SOCKET_H - -#include <asm/sockios.h> - -/* For setsockoptions(2) */ -#define SOL_SOCKET 1 - -#define SO_DEBUG 1 -#define SO_REUSEADDR 2 -#define SO_TYPE 3 -#define SO_ERROR 4 -#define SO_DONTROUTE 5 -#define SO_BROADCAST 6 -#define SO_SNDBUF 7 -#define SO_RCVBUF 8 -#define SO_SNDBUFFORCE 32 -#define SO_RCVBUFFORCE 33 -#define SO_KEEPALIVE 9 -#define SO_OOBINLINE 10 -#define SO_NO_CHECK 11 -#define SO_PRIORITY 12 -#define SO_LINGER 13 -#define SO_BSDCOMPAT 14 -#define SO_REUSEPORT 15 -#define SO_PASSCRED 16 -#define SO_PEERCRED 17 -#define SO_RCVLOWAT 18 -#define SO_SNDLOWAT 19 -#define SO_RCVTIMEO 20 -#define SO_SNDTIMEO 21 - -/* Security levels - as per NRL IPv6 - don't actually do anything */ -#define SO_SECURITY_AUTHENTICATION 22 -#define SO_SECURITY_ENCRYPTION_TRANSPORT 23 -#define SO_SECURITY_ENCRYPTION_NETWORK 24 - -#define SO_BINDTODEVICE 25 - -/* Socket filtering */ -#define SO_ATTACH_FILTER 26 -#define SO_DETACH_FILTER 27 -#define SO_GET_FILTER SO_ATTACH_FILTER - -#define SO_PEERNAME 28 -#define SO_TIMESTAMP 29 -#define SCM_TIMESTAMP SO_TIMESTAMP - -#define SO_ACCEPTCONN 30 - -#define SO_PEERSEC 31 -#define SO_PASSSEC 34 -#define SO_TIMESTAMPNS 35 -#define SCM_TIMESTAMPNS SO_TIMESTAMPNS - -#define SO_MARK 36 - -#define SO_TIMESTAMPING 37 -#define SCM_TIMESTAMPING SO_TIMESTAMPING - -#define SO_PROTOCOL 38 -#define SO_DOMAIN 39 - -#define SO_RXQ_OVFL 40 - -#define SO_WIFI_STATUS 41 -#define SCM_WIFI_STATUS SO_WIFI_STATUS -#define SO_PEEK_OFF 42 - -/* Instruct lower device to use last 4-bytes of skb data as FCS */ -#define SO_NOFCS 43 - -#define SO_LOCK_FILTER 44 - -#define SO_SELECT_ERR_QUEUE 45 - -#define SO_BUSY_POLL 46 - -#endif /* _ASM_SOCKET_H */ diff --git a/arch/h8300/include/uapi/asm/sockios.h b/arch/h8300/include/uapi/asm/sockios.h deleted file mode 100644 index e9c7ec810c23..000000000000 --- a/arch/h8300/include/uapi/asm/sockios.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef __ARCH_H8300_SOCKIOS__ -#define __ARCH_H8300_SOCKIOS__ - -/* Socket-level I/O control calls. */ -#define FIOSETOWN 0x8901 -#define SIOCSPGRP 0x8902 -#define FIOGETOWN 0x8903 -#define SIOCGPGRP 0x8904 -#define SIOCATMARK 0x8905 -#define SIOCGSTAMP 0x8906 /* Get stamp (timeval) */ -#define SIOCGSTAMPNS 0x8907 /* Get stamp (timespec) */ - -#endif /* __ARCH_H8300_SOCKIOS__ */ diff --git a/arch/h8300/include/uapi/asm/stat.h b/arch/h8300/include/uapi/asm/stat.h deleted file mode 100644 index 62c3cc24dfe6..000000000000 --- a/arch/h8300/include/uapi/asm/stat.h +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef _H8300_STAT_H -#define _H8300_STAT_H - -struct __old_kernel_stat { - unsigned short st_dev; - unsigned short st_ino; - unsigned short st_mode; - unsigned short st_nlink; - unsigned short st_uid; - unsigned short st_gid; - unsigned short st_rdev; - unsigned long st_size; - unsigned long st_atime; - unsigned long st_mtime; - unsigned long st_ctime; -}; - -struct stat { - unsigned short st_dev; - unsigned short __pad1; - unsigned long st_ino; - unsigned short st_mode; - unsigned short st_nlink; - unsigned short st_uid; - unsigned short st_gid; - unsigned short st_rdev; - unsigned short __pad2; - unsigned long st_size; - unsigned long st_blksize; - unsigned long st_blocks; - unsigned long st_atime; - unsigned long __unused1; - unsigned long st_mtime; - unsigned long __unused2; - unsigned long st_ctime; - unsigned long __unused3; - unsigned long __unused4; - unsigned long __unused5; -}; - -/* This matches struct stat64 in glibc2.1, hence the absolutely - * insane amounts of padding around dev_t's. - */ -struct stat64 { - unsigned long long st_dev; - unsigned char __pad1[2]; - -#define STAT64_HAS_BROKEN_ST_INO 1 - unsigned long __st_ino; - - unsigned int st_mode; - unsigned int st_nlink; - - unsigned long st_uid; - unsigned long st_gid; - - unsigned long long st_rdev; - unsigned char __pad3[2]; - - long long st_size; - unsigned long st_blksize; - - unsigned long __pad4; /* future possible st_blocks high bits */ - unsigned long st_blocks; /* Number 512-byte blocks allocated. */ - - unsigned long st_atime; - unsigned long st_atime_nsec; - - unsigned long st_mtime; - unsigned long st_mtime_nsec; - - unsigned long st_ctime; - unsigned long st_ctime_nsec; - - unsigned long long st_ino; -}; - -#endif /* _H8300_STAT_H */ diff --git a/arch/h8300/include/uapi/asm/statfs.h b/arch/h8300/include/uapi/asm/statfs.h deleted file mode 100644 index b96efa712aac..000000000000 --- a/arch/h8300/include/uapi/asm/statfs.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _H8300_STATFS_H -#define _H8300_STATFS_H - -#include <asm-generic/statfs.h> - -#endif /* _H8300_STATFS_H */ diff --git a/arch/h8300/include/uapi/asm/swab.h b/arch/h8300/include/uapi/asm/swab.h deleted file mode 100644 index 39abbf52807d..000000000000 --- a/arch/h8300/include/uapi/asm/swab.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _H8300_SWAB_H -#define _H8300_SWAB_H - -#include <linux/types.h> - -#if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__) -# define __SWAB_64_THRU_32__ -#endif - -#endif /* _H8300_SWAB_H */ diff --git a/arch/h8300/include/uapi/asm/termbits.h b/arch/h8300/include/uapi/asm/termbits.h deleted file mode 100644 index 3287a6244d74..000000000000 --- a/arch/h8300/include/uapi/asm/termbits.h +++ /dev/null @@ -1,201 +0,0 @@ -#ifndef __ARCH_H8300_TERMBITS_H__ -#define __ARCH_H8300_TERMBITS_H__ - -#include <linux/posix_types.h> - -typedef unsigned char cc_t; -typedef unsigned int speed_t; -typedef unsigned int tcflag_t; - -#define NCCS 19 -struct termios { - tcflag_t c_iflag; /* input mode flags */ - tcflag_t c_oflag; /* output mode flags */ - tcflag_t c_cflag; /* control mode flags */ - tcflag_t c_lflag; /* local mode flags */ - cc_t c_line; /* line discipline */ - cc_t c_cc[NCCS]; /* control characters */ -}; - -struct termios2 { - tcflag_t c_iflag; /* input mode flags */ - tcflag_t c_oflag; /* output mode flags */ - tcflag_t c_cflag; /* control mode flags */ - tcflag_t c_lflag; /* local mode flags */ - cc_t c_line; /* line discipline */ - cc_t c_cc[NCCS]; /* control characters */ - speed_t c_ispeed; /* input speed */ - speed_t c_ospeed; /* output speed */ -}; - -struct ktermios { - tcflag_t c_iflag; /* input mode flags */ - tcflag_t c_oflag; /* output mode flags */ - tcflag_t c_cflag; /* control mode flags */ - tcflag_t c_lflag; /* local mode flags */ - cc_t c_line; /* line discipline */ - cc_t c_cc[NCCS]; /* control characters */ - speed_t c_ispeed; /* input speed */ - speed_t c_ospeed; /* output speed */ -}; - -/* c_cc characters */ -#define VINTR 0 -#define VQUIT 1 -#define VERASE 2 -#define VKILL 3 -#define VEOF 4 -#define VTIME 5 -#define VMIN 6 -#define VSWTC 7 -#define VSTART 8 -#define VSTOP 9 -#define VSUSP 10 -#define VEOL 11 -#define VREPRINT 12 -#define VDISCARD 13 -#define VWERASE 14 -#define VLNEXT 15 -#define VEOL2 16 - - -/* c_iflag bits */ -#define IGNBRK 0000001 -#define BRKINT 0000002 -#define IGNPAR 0000004 -#define PARMRK 0000010 -#define INPCK 0000020 -#define ISTRIP 0000040 -#define INLCR 0000100 -#define IGNCR 0000200 -#define ICRNL 0000400 -#define IUCLC 0001000 -#define IXON 0002000 -#define IXANY 0004000 -#define IXOFF 0010000 -#define IMAXBEL 0020000 -#define IUTF8 0040000 - -/* c_oflag bits */ -#define OPOST 0000001 -#define OLCUC 0000002 -#define ONLCR 0000004 -#define OCRNL 0000010 -#define ONOCR 0000020 -#define ONLRET 0000040 -#define OFILL 0000100 -#define OFDEL 0000200 -#define NLDLY 0000400 -#define NL0 0000000 -#define NL1 0000400 -#define CRDLY 0003000 -#define CR0 0000000 -#define CR1 0001000 -#define CR2 0002000 -#define CR3 0003000 -#define TABDLY 0014000 -#define TAB0 0000000 -#define TAB1 0004000 -#define TAB2 0010000 -#define TAB3 0014000 -#define XTABS 0014000 -#define BSDLY 0020000 -#define BS0 0000000 -#define BS1 0020000 -#define VTDLY 0040000 -#define VT0 0000000 -#define VT1 0040000 -#define FFDLY 0100000 -#define FF0 0000000 -#define FF1 0100000 - -/* c_cflag bit meaning */ -#define CBAUD 0010017 -#define B0 0000000 /* hang up */ -#define B50 0000001 -#define B75 0000002 -#define B110 0000003 -#define B134 0000004 -#define B150 0000005 -#define B200 0000006 -#define B300 0000007 -#define B600 0000010 -#define B1200 0000011 -#define B1800 0000012 -#define B2400 0000013 -#define B4800 0000014 -#define B9600 0000015 -#define B19200 0000016 -#define B38400 0000017 -#define EXTA B19200 -#define EXTB B38400 -#define CSIZE 0000060 -#define CS5 0000000 -#define CS6 0000020 -#define CS7 0000040 -#define CS8 0000060 -#define CSTOPB 0000100 -#define CREAD 0000200 -#define PARENB 0000400 -#define PARODD 0001000 -#define HUPCL 0002000 -#define CLOCAL 0004000 -#define CBAUDEX 0010000 -#define BOTHER 0010000 -#define B57600 0010001 -#define B115200 0010002 -#define B230400 0010003 -#define B460800 0010004 -#define B500000 0010005 -#define B576000 0010006 -#define B921600 0010007 -#define B1000000 0010010 -#define B1152000 0010011 -#define B1500000 0010012 -#define B2000000 0010013 -#define B2500000 0010014 -#define B3000000 0010015 -#define B3500000 0010016 -#define B4000000 0010017 -#define CIBAUD 002003600000 /* input baud rate */ -#define CMSPAR 010000000000 /* mark or space (stick) parity */ -#define CRTSCTS 020000000000 /* flow control */ - -#define IBSHIFT 16 /* shift from CBAUD to CIBAUD */ - -/* c_lflag bits */ -#define ISIG 0000001 -#define ICANON 0000002 -#define XCASE 0000004 -#define ECHO 0000010 -#define ECHOE 0000020 -#define ECHOK 0000040 -#define ECHONL 0000100 -#define NOFLSH 0000200 -#define TOSTOP 0000400 -#define ECHOCTL 0001000 -#define ECHOPRT 0002000 -#define ECHOKE 0004000 -#define FLUSHO 0010000 -#define PENDIN 0040000 -#define IEXTEN 0100000 -#define EXTPROC 0200000 - - -/* tcflow() and TCXONC use these */ -#define TCOOFF 0 -#define TCOON 1 -#define TCIOFF 2 -#define TCION 3 - -/* tcflush() and TCFLSH use these */ -#define TCIFLUSH 0 -#define TCOFLUSH 1 -#define TCIOFLUSH 2 - -/* tcsetattr uses these */ -#define TCSANOW 0 -#define TCSADRAIN 1 -#define TCSAFLUSH 2 - -#endif /* __ARCH_H8300_TERMBITS_H__ */ diff --git a/arch/h8300/include/uapi/asm/termios.h b/arch/h8300/include/uapi/asm/termios.h deleted file mode 100644 index 5a67d7e38843..000000000000 --- a/arch/h8300/include/uapi/asm/termios.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef _UAPI_H8300_TERMIOS_H -#define _UAPI_H8300_TERMIOS_H - -#include <asm/termbits.h> -#include <asm/ioctls.h> - -struct winsize { - unsigned short ws_row; - unsigned short ws_col; - unsigned short ws_xpixel; - unsigned short ws_ypixel; -}; - -#define NCC 8 -struct termio { - unsigned short c_iflag; /* input mode flags */ - unsigned short c_oflag; /* output mode flags */ - unsigned short c_cflag; /* control mode flags */ - unsigned short c_lflag; /* local mode flags */ - unsigned char c_line; /* line discipline */ - unsigned char c_cc[NCC]; /* control characters */ -}; - - -/* modem lines */ -#define TIOCM_LE 0x001 -#define TIOCM_DTR 0x002 -#define TIOCM_RTS 0x004 -#define TIOCM_ST 0x008 -#define TIOCM_SR 0x010 -#define TIOCM_CTS 0x020 -#define TIOCM_CAR 0x040 -#define TIOCM_RNG 0x080 -#define TIOCM_DSR 0x100 -#define TIOCM_CD TIOCM_CAR -#define TIOCM_RI TIOCM_RNG -#define TIOCM_OUT1 0x2000 -#define TIOCM_OUT2 0x4000 -#define TIOCM_LOOP 0x8000 - -/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ - - -#endif /* _UAPI_H8300_TERMIOS_H */ diff --git a/arch/h8300/include/uapi/asm/types.h b/arch/h8300/include/uapi/asm/types.h deleted file mode 100644 index 9ec9d4c5ac4d..000000000000 --- a/arch/h8300/include/uapi/asm/types.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/int-ll64.h> diff --git a/arch/h8300/include/uapi/asm/unistd.h b/arch/h8300/include/uapi/asm/unistd.h deleted file mode 100644 index 8cb5d429f840..000000000000 --- a/arch/h8300/include/uapi/asm/unistd.h +++ /dev/null @@ -1,330 +0,0 @@ -#ifndef _UAPI_ASM_H8300_UNISTD_H_ -#define _UAPI_ASM_H8300_UNISTD_H_ - -/* - * This file contains the system call numbers. - */ - -#define __NR_restart_syscall 0 -#define __NR_exit 1 -#define __NR_fork 2 -#define __NR_read 3 -#define __NR_write 4 -#define __NR_open 5 -#define __NR_close 6 -#define __NR_waitpid 7 -#define __NR_creat 8 -#define __NR_link 9 -#define __NR_unlink 10 -#define __NR_execve 11 -#define __NR_chdir 12 -#define __NR_time 13 -#define __NR_mknod 14 -#define __NR_chmod 15 -#define __NR_lchown 16 -#define __NR_break 17 -#define __NR_oldstat 18 -#define __NR_lseek 19 -#define __NR_getpid 20 -#define __NR_mount 21 -#define __NR_umount 22 -#define __NR_setuid 23 -#define __NR_getuid 24 -#define __NR_stime 25 -#define __NR_ptrace 26 -#define __NR_alarm 27 -#define __NR_oldfstat 28 -#define __NR_pause 29 -#define __NR_utime 30 -#define __NR_stty 31 -#define __NR_gtty 32 -#define __NR_access 33 -#define __NR_nice 34 -#define __NR_ftime 35 -#define __NR_sync 36 -#define __NR_kill 37 -#define __NR_rename 38 -#define __NR_mkdir 39 -#define __NR_rmdir 40 -#define __NR_dup 41 -#define __NR_pipe 42 -#define __NR_times 43 -#define __NR_prof 44 -#define __NR_brk 45 -#define __NR_setgid 46 -#define __NR_getgid 47 -#define __NR_signal 48 -#define __NR_geteuid 49 -#define __NR_getegid 50 -#define __NR_acct 51 -#define __NR_umount2 52 -#define __NR_lock 53 -#define __NR_ioctl 54 -#define __NR_fcntl 55 -#define __NR_mpx 56 -#define __NR_setpgid 57 -#define __NR_ulimit 58 -#define __NR_oldolduname 59 -#define __NR_umask 60 -#define __NR_chroot 61 -#define __NR_ustat 62 -#define __NR_dup2 63 -#define __NR_getppid 64 -#define __NR_getpgrp 65 -#define __NR_setsid 66 -#define __NR_sigaction 67 -#define __NR_sgetmask 68 -#define __NR_ssetmask 69 -#define __NR_setreuid 70 -#define __NR_setregid 71 -#define __NR_sigsuspend 72 -#define __NR_sigpending 73 -#define __NR_sethostname 74 -#define __NR_setrlimit 75 -#define __NR_getrlimit 76 -#define __NR_getrusage 77 -#define __NR_gettimeofday 78 -#define __NR_settimeofday 79 -#define __NR_getgroups 80 -#define __NR_setgroups 81 -#define __NR_select 82 -#define __NR_symlink 83 -#define __NR_oldlstat 84 -#define __NR_readlink 85 -#define __NR_uselib 86 -#define __NR_swapon 87 -#define __NR_reboot 88 -#define __NR_readdir 89 -#define __NR_mmap 90 -#define __NR_munmap 91 -#define __NR_truncate 92 -#define __NR_ftruncate 93 -#define __NR_fchmod 94 -#define __NR_fchown 95 -#define __NR_getpriority 96 -#define __NR_setpriority 97 -#define __NR_profil 98 -#define __NR_statfs 99 -#define __NR_fstatfs 100 -#define __NR_ioperm 101 -#define __NR_socketcall 102 -#define __NR_syslog 103 -#define __NR_setitimer 104 -#define __NR_getitimer 105 -#define __NR_stat 106 -#define __NR_lstat 107 -#define __NR_fstat 108 -#define __NR_olduname 109 -#define __NR_iopl 110 -#define __NR_vhangup 111 -#define __NR_idle 112 -#define __NR_vm86old 113 -#define __NR_wait4 114 -#define __NR_swapoff 115 -#define __NR_sysinfo 116 -#define __NR_ipc 117 -#define __NR_fsync 118 -#define __NR_sigreturn 119 -#define __NR_clone 120 -#define __NR_setdomainname 121 -#define __NR_uname 122 -#define __NR_modify_ldt 123 -#define __NR_adjtimex 124 -#define __NR_mprotect 125 -#define __NR_sigprocmask 126 -#define __NR_create_module 127 -#define __NR_init_module 128 -#define __NR_delete_module 129 -#define __NR_get_kernel_syms 130 -#define __NR_quotactl 131 -#define __NR_getpgid 132 -#define __NR_fchdir 133 -#define __NR_bdflush 134 -#define __NR_sysfs 135 -#define __NR_personality 136 -#define __NR_afs_syscall 137 /* Syscall for Andrew File System */ -#define __NR_setfsuid 138 -#define __NR_setfsgid 139 -#define __NR__llseek 140 -#define __NR_getdents 141 -#define __NR__newselect 142 -#define __NR_flock 143 -#define __NR_msync 144 -#define __NR_readv 145 -#define __NR_writev 146 -#define __NR_getsid 147 -#define __NR_fdatasync 148 -#define __NR__sysctl 149 -#define __NR_mlock 150 -#define __NR_munlock 151 -#define __NR_mlockall 152 -#define __NR_munlockall 153 -#define __NR_sched_setparam 154 -#define __NR_sched_getparam 155 -#define __NR_sched_setscheduler 156 -#define __NR_sched_getscheduler 157 -#define __NR_sched_yield 158 -#define __NR_sched_get_priority_max 159 -#define __NR_sched_get_priority_min 160 -#define __NR_sched_rr_get_interval 161 -#define __NR_nanosleep 162 -#define __NR_mremap 163 -#define __NR_setresuid 164 -#define __NR_getresuid 165 -#define __NR_vm86 166 -#define __NR_query_module 167 -#define __NR_poll 168 -#define __NR_nfsservctl 169 -#define __NR_setresgid 170 -#define __NR_getresgid 171 -#define __NR_prctl 172 -#define __NR_rt_sigreturn 173 -#define __NR_rt_sigaction 174 -#define __NR_rt_sigprocmask 175 -#define __NR_rt_sigpending 176 -#define __NR_rt_sigtimedwait 177 -#define __NR_rt_sigqueueinfo 178 -#define __NR_rt_sigsuspend 179 -#define __NR_pread64 180 -#define __NR_pwrite64 181 -#define __NR_chown 182 -#define __NR_getcwd 183 -#define __NR_capget 184 -#define __NR_capset 185 -#define __NR_sigaltstack 186 -#define __NR_sendfile 187 -#define __NR_getpmsg 188 /* some people actually want streams */ -#define __NR_putpmsg 189 /* some people actually want streams */ -#define __NR_vfork 190 -#define __NR_ugetrlimit 191 -#define __NR_mmap2 192 -#define __NR_truncate64 193 -#define __NR_ftruncate64 194 -#define __NR_stat64 195 -#define __NR_lstat64 196 -#define __NR_fstat64 197 -#define __NR_lchown32 198 -#define __NR_getuid32 199 -#define __NR_getgid32 200 -#define __NR_geteuid32 201 -#define __NR_getegid32 202 -#define __NR_setreuid32 203 -#define __NR_setregid32 204 -#define __NR_getgroups32 205 -#define __NR_setgroups32 206 -#define __NR_fchown32 207 -#define __NR_setresuid32 208 -#define __NR_getresuid32 209 -#define __NR_setresgid32 210 -#define __NR_getresgid32 211 -#define __NR_chown32 212 -#define __NR_setuid32 213 -#define __NR_setgid32 214 -#define __NR_setfsuid32 215 -#define __NR_setfsgid32 216 -#define __NR_pivot_root 217 -#define __NR_mincore 218 -#define __NR_madvise 219 -#define __NR_madvise1 219 -#define __NR_getdents64 220 -#define __NR_fcntl64 221 -/* 223 is unused */ -#define __NR_gettid 224 -#define __NR_readahead 225 -#define __NR_setxattr 226 -#define __NR_lsetxattr 227 -#define __NR_fsetxattr 228 -#define __NR_getxattr 229 -#define __NR_lgetxattr 230 -#define __NR_fgetxattr 231 -#define __NR_listxattr 232 -#define __NR_llistxattr 233 -#define __NR_flistxattr 234 -#define __NR_removexattr 235 -#define __NR_lremovexattr 236 -#define __NR_fremovexattr 237 -#define __NR_tkill 238 -#define __NR_sendfile64 239 -#define __NR_futex 240 -#define __NR_sched_setaffinity 241 -#define __NR_sched_getaffinity 242 -#define __NR_set_thread_area 243 -#define __NR_get_thread_area 244 -#define __NR_io_setup 245 -#define __NR_io_destroy 246 -#define __NR_io_getevents 247 -#define __NR_io_submit 248 -#define __NR_io_cancel 249 -#define __NR_fadvise64 250 -/* 251 is available for reuse (was briefly sys_set_zone_reclaim) */ -#define __NR_exit_group 252 -#define __NR_lookup_dcookie 253 -#define __NR_epoll_create 254 -#define __NR_epoll_ctl 255 -#define __NR_epoll_wait 256 -#define __NR_remap_file_pages 257 -#define __NR_set_tid_address 258 -#define __NR_timer_create 259 -#define __NR_timer_settime (__NR_timer_create+1) -#define __NR_timer_gettime (__NR_timer_create+2) -#define __NR_timer_getoverrun (__NR_timer_create+3) -#define __NR_timer_delete (__NR_timer_create+4) -#define __NR_clock_settime (__NR_timer_create+5) -#define __NR_clock_gettime (__NR_timer_create+6) -#define __NR_clock_getres (__NR_timer_create+7) -#define __NR_clock_nanosleep (__NR_timer_create+8) -#define __NR_statfs64 268 -#define __NR_fstatfs64 269 -#define __NR_tgkill 270 -#define __NR_utimes 271 -#define __NR_fadvise64_64 272 -#define __NR_vserver 273 -#define __NR_mbind 274 -#define __NR_get_mempolicy 275 -#define __NR_set_mempolicy 276 -#define __NR_mq_open 277 -#define __NR_mq_unlink (__NR_mq_open+1) -#define __NR_mq_timedsend (__NR_mq_open+2) -#define __NR_mq_timedreceive (__NR_mq_open+3) -#define __NR_mq_notify (__NR_mq_open+4) -#define __NR_mq_getsetattr (__NR_mq_open+5) -#define __NR_kexec_load 283 -#define __NR_waitid 284 -/* #define __NR_sys_setaltroot 285 */ -#define __NR_add_key 286 -#define __NR_request_key 287 -#define __NR_keyctl 288 -#define __NR_ioprio_set 289 -#define __NR_ioprio_get 290 -#define __NR_inotify_init 291 -#define __NR_inotify_add_watch 292 -#define __NR_inotify_rm_watch 293 -#define __NR_migrate_pages 294 -#define __NR_openat 295 -#define __NR_mkdirat 296 -#define __NR_mknodat 297 -#define __NR_fchownat 298 -#define __NR_futimesat 299 -#define __NR_fstatat64 300 -#define __NR_unlinkat 301 -#define __NR_renameat 302 -#define __NR_linkat 303 -#define __NR_symlinkat 304 -#define __NR_readlinkat 305 -#define __NR_fchmodat 306 -#define __NR_faccessat 307 -#define __NR_pselect6 308 -#define __NR_ppoll 309 -#define __NR_unshare 310 -#define __NR_set_robust_list 311 -#define __NR_get_robust_list 312 -#define __NR_splice 313 -#define __NR_sync_file_range 314 -#define __NR_tee 315 -#define __NR_vmsplice 316 -#define __NR_move_pages 317 -#define __NR_getcpu 318 -#define __NR_epoll_pwait 319 -#define __NR_setns 320 - -#endif /* _UAPI_ASM_H8300_UNISTD_H_ */ diff --git a/arch/h8300/kernel/Makefile b/arch/h8300/kernel/Makefile deleted file mode 100644 index 1cc57f872d34..000000000000 --- a/arch/h8300/kernel/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# -# Makefile for the linux kernel. -# - -extra-y := vmlinux.lds - -obj-y := process.o traps.o ptrace.o irq.o \ - sys_h8300.o time.o signal.o \ - setup.o gpio.o syscalls.o \ - entry.o timer/ - -obj-$(CONFIG_MODULES) += module.o h8300_ksyms.o diff --git a/arch/h8300/kernel/asm-offsets.c b/arch/h8300/kernel/asm-offsets.c deleted file mode 100644 index fd961e0bd741..000000000000 --- a/arch/h8300/kernel/asm-offsets.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This program is used to generate definitions needed by - * assembly language modules. - * - * We use the technique used in the OSF Mach kernel code: - * generate asm statements containing #defines, - * compile this file to assembler, and then extract the - * #defines from the assembly-language output. - */ - -#include <linux/stddef.h> -#include <linux/sched.h> -#include <linux/kernel_stat.h> -#include <linux/ptrace.h> -#include <linux/hardirq.h> -#include <linux/kbuild.h> -#include <asm/bootinfo.h> -#include <asm/irq.h> -#include <asm/ptrace.h> - -int main(void) -{ - /* offsets into the task struct */ - DEFINE(TASK_STATE, offsetof(struct task_struct, state)); - DEFINE(TASK_FLAGS, offsetof(struct task_struct, flags)); - DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace)); - DEFINE(TASK_BLOCKED, offsetof(struct task_struct, blocked)); - DEFINE(TASK_THREAD, offsetof(struct task_struct, thread)); - DEFINE(TASK_THREAD_INFO, offsetof(struct task_struct, stack)); - DEFINE(TASK_MM, offsetof(struct task_struct, mm)); - DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm)); - - /* offsets into the irq_cpustat_t struct */ - DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t, __softirq_pending)); - - /* offsets into the thread struct */ - DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp)); - DEFINE(THREAD_USP, offsetof(struct thread_struct, usp)); - DEFINE(THREAD_CCR, offsetof(struct thread_struct, ccr)); - - /* offsets into the pt_regs struct */ - DEFINE(LER0, offsetof(struct pt_regs, er0) - sizeof(long)); - DEFINE(LER1, offsetof(struct pt_regs, er1) - sizeof(long)); - DEFINE(LER2, offsetof(struct pt_regs, er2) - sizeof(long)); - DEFINE(LER3, offsetof(struct pt_regs, er3) - sizeof(long)); - DEFINE(LER4, offsetof(struct pt_regs, er4) - sizeof(long)); - DEFINE(LER5, offsetof(struct pt_regs, er5) - sizeof(long)); - DEFINE(LER6, offsetof(struct pt_regs, er6) - sizeof(long)); - DEFINE(LORIG, offsetof(struct pt_regs, orig_er0) - sizeof(long)); - DEFINE(LCCR, offsetof(struct pt_regs, ccr) - sizeof(long)); - DEFINE(LVEC, offsetof(struct pt_regs, vector) - sizeof(long)); -#if defined(__H8300S__) - DEFINE(LEXR, offsetof(struct pt_regs, exr) - sizeof(long)); -#endif - DEFINE(LRET, offsetof(struct pt_regs, pc) - sizeof(long)); - - DEFINE(PT_PTRACED, PT_PTRACED); - - return 0; -} diff --git a/arch/h8300/kernel/entry.S b/arch/h8300/kernel/entry.S deleted file mode 100644 index 94bd30f11df6..000000000000 --- a/arch/h8300/kernel/entry.S +++ /dev/null @@ -1,402 +0,0 @@ -/* -*- mode: asm -*- - * - * linux/arch/h8300/platform/h8300h/entry.S - * - * Yoshinori Sato <ysato@users.sourceforge.jp> - * David McCullough <davidm@snapgear.com> - * - */ - -/* - * entry.S - * include exception/interrupt gateway - * system call entry - */ - -#include <linux/sys.h> -#include <asm/unistd.h> -#include <asm/setup.h> -#include <asm/segment.h> -#include <asm/linkage.h> -#include <asm/asm-offsets.h> -#include <asm/thread_info.h> -#include <asm/errno.h> - -#if defined(CONFIG_CPU_H8300H) -#define USERRET 8 -INTERRUPTS = 64 - .h8300h - .macro SHLL2 reg - shll.l \reg - shll.l \reg - .endm - .macro SHLR2 reg - shlr.l \reg - shlr.l \reg - .endm - .macro SAVEREGS - mov.l er0,@-sp - mov.l er1,@-sp - mov.l er2,@-sp - mov.l er3,@-sp - .endm - .macro RESTOREREGS - mov.l @sp+,er3 - mov.l @sp+,er2 - .endm - .macro SAVEEXR - .endm - .macro RESTOREEXR - .endm -#endif -#if defined(CONFIG_CPU_H8S) -#define USERRET 10 -#define USEREXR 8 -INTERRUPTS = 128 - .h8300s - .macro SHLL2 reg - shll.l #2,\reg - .endm - .macro SHLR2 reg - shlr.l #2,\reg - .endm - .macro SAVEREGS - stm.l er0-er3,@-sp - .endm - .macro RESTOREREGS - ldm.l @sp+,er2-er3 - .endm - .macro SAVEEXR - mov.w @(USEREXR:16,er0),r1 - mov.w r1,@(LEXR-LER3:16,sp) /* copy EXR */ - .endm - .macro RESTOREEXR - mov.w @(LEXR-LER1:16,sp),r1 /* restore EXR */ - mov.b r1l,r1h - mov.w r1,@(USEREXR:16,er0) - .endm -#endif - - -/* CPU context save/restore macros. */ - - .macro SAVE_ALL - mov.l er0,@-sp - stc ccr,r0l /* check kernel mode */ - btst #4,r0l - bne 5f - - /* user mode */ - mov.l sp,@_sw_usp - mov.l @sp,er0 /* restore saved er0 */ - orc #0x10,ccr /* switch kernel stack */ - mov.l @_sw_ksp,sp - sub.l #(LRET-LORIG),sp /* allocate LORIG - LRET */ - SAVEREGS - mov.l @_sw_usp,er0 - mov.l @(USERRET:16,er0),er1 /* copy the RET addr */ - mov.l er1,@(LRET-LER3:16,sp) - SAVEEXR - - mov.l @(LORIG-LER3:16,sp),er0 - mov.l er0,@(LER0-LER3:16,sp) /* copy ER0 */ - mov.w e1,r1 /* e1 highbyte = ccr */ - and #0xef,r1h /* mask mode? flag */ - bra 6f -5: - /* kernel mode */ - mov.l @sp,er0 /* restore saved er0 */ - subs #2,sp /* set dummy ccr */ - SAVEREGS - mov.w @(LRET-LER3:16,sp),r1 /* copy old ccr */ -6: - mov.b r1h,r1l - mov.b #0,r1h - mov.w r1,@(LCCR-LER3:16,sp) /* set ccr */ - mov.l er6,@-sp /* syscall arg #6 */ - mov.l er5,@-sp /* syscall arg #5 */ - mov.l er4,@-sp /* syscall arg #4 */ - .endm /* r1 = ccr */ - - .macro RESTORE_ALL - mov.l @sp+,er4 - mov.l @sp+,er5 - mov.l @sp+,er6 - RESTOREREGS - mov.w @(LCCR-LER1:16,sp),r0 /* check kernel mode */ - btst #4,r0l - bne 7f - - orc #0x80,ccr - mov.l @_sw_usp,er0 - mov.l @(LER0-LER1:16,sp),er1 /* restore ER0 */ - mov.l er1,@er0 - RESTOREEXR - mov.w @(LCCR-LER1:16,sp),r1 /* restore the RET addr */ - mov.b r1l,r1h - mov.b @(LRET+1-LER1:16,sp),r1l - mov.w r1,e1 - mov.w @(LRET+2-LER1:16,sp),r1 - mov.l er1,@(USERRET:16,er0) - - mov.l @sp+,er1 - add.l #(LRET-LER1),sp /* remove LORIG - LRET */ - mov.l sp,@_sw_ksp - andc #0xef,ccr /* switch to user mode */ - mov.l er0,sp - bra 8f -7: - mov.l @sp+,er1 - adds #4,sp - adds #2,sp -8: - mov.l @sp+,er0 - adds #4,sp /* remove the sw created LVEC */ - rte - .endm - -.globl _system_call -.globl _ret_from_exception -.globl _ret_from_fork -.globl _ret_from_kernel_thread -.globl _ret_from_interrupt -.globl _interrupt_redirect_table -.globl _sw_ksp,_sw_usp -.globl _resume -.globl _interrupt_entry -.globl _trace_break - -#if defined(CONFIG_ROMKERNEL) - .section .int_redirect,"ax" -_interrupt_redirect_table: -#if defined(CONFIG_CPU_H8300H) - .rept 7 - .long 0 - .endr -#endif -#if defined(CONFIG_CPU_H8S) - .rept 5 - .long 0 - .endr - jmp @_trace_break - .long 0 -#endif - - jsr @_interrupt_entry /* NMI */ - jmp @_system_call /* TRAPA #0 (System call) */ - .long 0 - .long 0 - jmp @_trace_break /* TRAPA #3 (breakpoint) */ - .rept INTERRUPTS-12 - jsr @_interrupt_entry - .endr -#endif -#if defined(CONFIG_RAMKERNEL) -.globl _interrupt_redirect_table - .section .bss -_interrupt_redirect_table: - .space 4 -#endif - - .section .text - .align 2 -_interrupt_entry: - SAVE_ALL - mov.l sp,er0 - add.l #LVEC,er0 - btst #4,r1l - bne 1f - /* user LVEC */ - mov.l @_sw_usp,er0 - adds #4,er0 -1: - mov.l @er0,er0 /* LVEC address */ -#if defined(CONFIG_ROMKERNEL) - sub.l #_interrupt_redirect_table,er0 -#endif -#if defined(CONFIG_RAMKERNEL) - mov.l @_interrupt_redirect_table,er1 - sub.l er1,er0 -#endif - SHLR2 er0 - dec.l #1,er0 - mov.l sp,er1 - subs #4,er1 /* adjust ret_pc */ - jsr @_do_IRQ - jmp @_ret_from_interrupt - -_system_call: - subs #4,sp /* dummy LVEC */ - SAVE_ALL - andc #0x7f,ccr - mov.l er0,er4 - - /* save top of frame */ - mov.l sp,er0 - jsr @_set_esp0 - mov.l sp,er2 - and.w #0xe000,r2 - mov.b @((TI_FLAGS+3-(TIF_SYSCALL_TRACE >> 3)):16,er2),r2l - btst #(TIF_SYSCALL_TRACE & 7),r2l - beq 1f - jsr @_do_syscall_trace -1: - cmp.l #NR_syscalls,er4 - bcc badsys - SHLL2 er4 - mov.l #_sys_call_table,er0 - add.l er4,er0 - mov.l @er0,er4 - beq _ret_from_exception:16 - mov.l @(LER1:16,sp),er0 - mov.l @(LER2:16,sp),er1 - mov.l @(LER3:16,sp),er2 - jsr @er4 - mov.l er0,@(LER0:16,sp) /* save the return value */ - mov.l sp,er2 - and.w #0xe000,r2 - mov.b @((TI_FLAGS+3-(TIF_SYSCALL_TRACE >> 3)):16,er2),r2l - btst #(TIF_SYSCALL_TRACE & 7),r2l - beq 2f - jsr @_do_syscall_trace -2: -#if defined(CONFIG_SYSCALL_PRINT) - jsr @_syscall_print -#endif - orc #0x80,ccr - bra resume_userspace - -badsys: - mov.l #-ENOSYS,er0 - mov.l er0,@(LER0:16,sp) - bra resume_userspace - -#if !defined(CONFIG_PREEMPT) -#define resume_kernel restore_all -#endif - -_ret_from_exception: -#if defined(CONFIG_PREEMPT) - orc #0x80,ccr -#endif -_ret_from_interrupt: - mov.b @(LCCR+1:16,sp),r0l - btst #4,r0l - bne resume_kernel:8 /* return from kernel */ -resume_userspace: - andc #0x7f,ccr - mov.l sp,er4 - and.w #0xe000,r4 /* er4 <- current thread info */ - mov.l @(TI_FLAGS:16,er4),er1 - and.l #_TIF_WORK_MASK,er1 - beq restore_all:8 -work_pending: - btst #TIF_NEED_RESCHED,r1l - bne work_resched:8 - /* work notifysig */ - mov.l sp,er0 - subs #4,er0 /* er0: pt_regs */ - jsr @_do_notify_resume - bra restore_all:8 -work_resched: - mov.l sp,er0 - jsr @_set_esp0 - jsr @_schedule - bra resume_userspace:8 -restore_all: - RESTORE_ALL /* Does RTE */ - -#if defined(CONFIG_PREEMPT) -resume_kernel: - mov.l @(TI_PRE_COUNT:16,er4),er0 - bne restore_all:8 -need_resched: - mov.l @(TI_FLAGS:16,er4),er0 - btst #TIF_NEED_RESCHED,r0l - beq restore_all:8 - mov.b @(LCCR+1:16,sp),r0l /* Interrupt Enabled? */ - bmi restore_all:8 - mov.l #PREEMPT_ACTIVE,er0 - mov.l er0,@(TI_PRE_COUNT:16,er4) - andc #0x7f,ccr - mov.l sp,er0 - jsr @_set_esp0 - jsr @_schedule - orc #0x80,ccr - bra need_resched:8 -#endif - -_ret_from_fork: - mov.l er2,er0 - jsr @_schedule_tail - jmp @_ret_from_exception - -_ret_from_kernel_thread: - mov.l er2,er0 - jsr @_schedule_tail - mov.l @(LER4:16,sp),er0 - mov.l @(LER5:16,sp),er1 - jsr @er1 - jmp @_ret_from_exception - -_resume: - /* - * Beware - when entering resume, offset of tss is in d1, - * prev (the current task) is in a0, next (the new task) - * is in a1 and d2.b is non-zero if the mm structure is - * shared between the tasks, so don't change these - * registers until their contents are no longer needed. - */ - - /* save sr */ - sub.w r3,r3 - stc ccr,r3l - mov.w r3,@(THREAD_CCR+2:16,er0) - - /* disable interrupts */ - orc #0x80,ccr - mov.l @_sw_usp,er3 - mov.l er3,@(THREAD_USP:16,er0) - mov.l sp,@(THREAD_KSP:16,er0) - - /* Skip address space switching if they are the same. */ - /* FIXME: what did we hack out of here, this does nothing! */ - - mov.l @(THREAD_USP:16,er1),er0 - mov.l er0,@_sw_usp - mov.l @(THREAD_KSP:16,er1),sp - - /* restore status register */ - mov.w @(THREAD_CCR+2:16,er1),r3 - - ldc r3l,ccr - rts - -_trace_break: - subs #4,sp - SAVE_ALL - sub.l er1,er1 - dec.l #1,er1 - mov.l er1,@(LORIG,sp) - mov.l sp,er0 - jsr @_set_esp0 - mov.l @_sw_usp,er0 - mov.l @er0,er1 - mov.w @(-2:16,er1),r2 - cmp.w #0x5730,r2 - beq 1f - subs #2,er1 - mov.l er1,@er0 -1: - and.w #0xff,e1 - mov.l er1,er0 - jsr @_trace_trap - jmp @_ret_from_exception - - .section .bss -_sw_ksp: - .space 4 -_sw_usp: - .space 4 - - .end diff --git a/arch/h8300/kernel/gpio.c b/arch/h8300/kernel/gpio.c deleted file mode 100644 index 084bfd0c107e..000000000000 --- a/arch/h8300/kernel/gpio.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * linux/arch/h8300/kernel/gpio.c - * - * Yoshinori Sato <ysato@users.sourceforge.jp> - * - */ - -/* - * Internal I/O Port Management - */ - -#include <linux/stddef.h> -#include <linux/proc_fs.h> -#include <linux/seq_file.h> -#include <linux/kernel.h> -#include <linux/string.h> -#include <linux/fs.h> -#include <linux/init.h> - -#define _(addr) (volatile unsigned char *)(addr) -#if defined(CONFIG_H83007) || defined(CONFIG_H83068) -#include <asm/regs306x.h> -static volatile unsigned char *ddrs[] = { - _(P1DDR),_(P2DDR),_(P3DDR),_(P4DDR),_(P5DDR),_(P6DDR), - NULL, _(P8DDR),_(P9DDR),_(PADDR),_(PBDDR), -}; -#define MAX_PORT 11 -#endif - - #if defined(CONFIG_H83002) || defined(CONFIG_H8048) -/* Fix me!! */ -#include <asm/regs306x.h> -static volatile unsigned char *ddrs[] = { - _(P1DDR),_(P2DDR),_(P3DDR),_(P4DDR),_(P5DDR),_(P6DDR), - NULL, _(P8DDR),_(P9DDR),_(PADDR),_(PBDDR), -}; -#define MAX_PORT 11 -#endif - -#if defined(CONFIG_H8S2678) -#include <asm/regs267x.h> -static volatile unsigned char *ddrs[] = { - _(P1DDR),_(P2DDR),_(P3DDR),NULL ,_(P5DDR),_(P6DDR), - _(P7DDR),_(P8DDR),NULL, _(PADDR),_(PBDDR),_(PCDDR), - _(PDDDR),_(PEDDR),_(PFDDR),_(PGDDR),_(PHDDR), - _(PADDR),_(PBDDR),_(PCDDR),_(PDDDR),_(PEDDR),_(PFDDR), - _(PGDDR),_(PHDDR) -}; -#define MAX_PORT 17 -#endif -#undef _ - -#if !defined(P1DDR) -#error Unsuppoted CPU Selection -#endif - -static struct { - unsigned char used; - unsigned char ddr; -} gpio_regs[MAX_PORT]; - -extern char *_platform_gpio_table(int length); - -int h8300_reserved_gpio(int port, unsigned int bits) -{ - unsigned char *used; - - if (port < 0 || port >= MAX_PORT) - return -1; - used = &(gpio_regs[port].used); - if ((*used & bits) != 0) - return 0; - *used |= bits; - return 1; -} - -int h8300_free_gpio(int port, unsigned int bits) -{ - unsigned char *used; - - if (port < 0 || port >= MAX_PORT) - return -1; - used = &(gpio_regs[port].used); - if ((*used & bits) != bits) - return 0; - *used &= (~bits); - return 1; -} - -int h8300_set_gpio_dir(int port_bit,int dir) -{ - int port = (port_bit >> 8) & 0xff; - int bit = port_bit & 0xff; - - if (ddrs[port] == NULL) - return 0; - if (gpio_regs[port].used & bit) { - if (dir) - gpio_regs[port].ddr |= bit; - else - gpio_regs[port].ddr &= ~bit; - *ddrs[port] = gpio_regs[port].ddr; - return 1; - } else - return 0; -} - -int h8300_get_gpio_dir(int port_bit) -{ - int port = (port_bit >> 8) & 0xff; - int bit = port_bit & 0xff; - - if (ddrs[port] == NULL) - return 0; - if (gpio_regs[port].used & bit) { - return (gpio_regs[port].ddr & bit) != 0; - } else - return -1; -} - -#if defined(CONFIG_PROC_FS) -static char *port_status(int portno) -{ - static char result[10]; - static const char io[2]={'I','O'}; - char *rp; - int c; - unsigned char used,ddr; - - used = gpio_regs[portno].used; - ddr = gpio_regs[portno].ddr; - result[8]='\0'; - rp = result + 7; - for (c = 8; c > 0; c--,rp--,used >>= 1, ddr >>= 1) - if (used & 0x01) - *rp = io[ ddr & 0x01]; - else - *rp = '-'; - return result; -} - -static int gpio_proc_show(struct seq_file *m, void *v) -{ - static const char port_name[]="123456789ABCDEFGH"; - int c; - - for (c = 0; c < MAX_PORT; c++) { - if (ddrs[c] == NULL) - continue; - seq_printf(m, "P%c: %s\n", port_name[c], port_status(c)); - } - return 0; -} - -static int gpio_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, gpio_proc_show, PDE_DATA(inode)); -} - -static const struct file_operations gpio_proc_fops = { - .open = gpio_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static __init int register_proc(void) -{ - return proc_create("gpio", S_IRUGO, NULL, &gpio_proc_fops) != NULL; -} - -__initcall(register_proc); -#endif - -void __init h8300_gpio_init(void) -{ - memcpy(gpio_regs,_platform_gpio_table(sizeof(gpio_regs)),sizeof(gpio_regs)); -} diff --git a/arch/h8300/kernel/h8300_ksyms.c b/arch/h8300/kernel/h8300_ksyms.c deleted file mode 100644 index 53d7c0e4bd83..000000000000 --- a/arch/h8300/kernel/h8300_ksyms.c +++ /dev/null @@ -1,100 +0,0 @@ -#include <linux/module.h> -#include <linux/linkage.h> -#include <linux/sched.h> -#include <linux/string.h> -#include <linux/mm.h> -#include <linux/user.h> -#include <linux/elfcore.h> -#include <linux/in6.h> -#include <linux/interrupt.h> - -#include <asm/setup.h> -#include <asm/pgalloc.h> -#include <asm/irq.h> -#include <asm/io.h> -#include <asm/checksum.h> -#include <asm/current.h> -#include <asm/gpio.h> - -//asmlinkage long long __ashrdi3 (long long, int); -//asmlinkage long long __lshrdi3 (long long, int); -extern char h8300_debug_device[]; - -/* platform dependent support */ - -EXPORT_SYMBOL(strnlen); -EXPORT_SYMBOL(strrchr); -EXPORT_SYMBOL(strstr); -EXPORT_SYMBOL(strchr); -EXPORT_SYMBOL(strcat); -EXPORT_SYMBOL(strlen); -EXPORT_SYMBOL(strcmp); -EXPORT_SYMBOL(strncmp); - -EXPORT_SYMBOL(ip_fast_csum); - -EXPORT_SYMBOL(enable_irq); -EXPORT_SYMBOL(disable_irq); - -/* Networking helper routines. */ -EXPORT_SYMBOL(csum_partial_copy_nocheck); - -/* The following are special because they're not called - explicitly (the C compiler generates them). Fortunately, - their interface isn't gonna change any time soon now, so - it's OK to leave it out of version control. */ -//EXPORT_SYMBOL(__ashrdi3); -//EXPORT_SYMBOL(__lshrdi3); -EXPORT_SYMBOL(memcpy); -EXPORT_SYMBOL(memset); -EXPORT_SYMBOL(memcmp); -EXPORT_SYMBOL(memscan); -EXPORT_SYMBOL(memmove); - -/* - * libgcc functions - functions that are used internally by the - * compiler... (prototypes are not correct though, but that - * doesn't really matter since they're not versioned). - */ -extern void __gcc_bcmp(void); -extern void __ashldi3(void); -extern void __ashrdi3(void); -extern void __cmpdi2(void); -extern void __divdi3(void); -extern void __divsi3(void); -extern void __lshrdi3(void); -extern void __moddi3(void); -extern void __modsi3(void); -extern void __muldi3(void); -extern void __mulsi3(void); -extern void __negdi2(void); -extern void __ucmpdi2(void); -extern void __udivdi3(void); -extern void __udivmoddi4(void); -extern void __udivsi3(void); -extern void __umoddi3(void); -extern void __umodsi3(void); - - /* gcc lib functions */ -EXPORT_SYMBOL(__gcc_bcmp); -EXPORT_SYMBOL(__ashldi3); -EXPORT_SYMBOL(__ashrdi3); -EXPORT_SYMBOL(__cmpdi2); -EXPORT_SYMBOL(__divdi3); -EXPORT_SYMBOL(__divsi3); -EXPORT_SYMBOL(__lshrdi3); -EXPORT_SYMBOL(__moddi3); -EXPORT_SYMBOL(__modsi3); -EXPORT_SYMBOL(__muldi3); -EXPORT_SYMBOL(__mulsi3); -EXPORT_SYMBOL(__negdi2); -EXPORT_SYMBOL(__ucmpdi2); -EXPORT_SYMBOL(__udivdi3); -EXPORT_SYMBOL(__udivmoddi4); -EXPORT_SYMBOL(__udivsi3); -EXPORT_SYMBOL(__umoddi3); -EXPORT_SYMBOL(__umodsi3); - -EXPORT_SYMBOL(h8300_reserved_gpio); -EXPORT_SYMBOL(h8300_free_gpio); -EXPORT_SYMBOL(h8300_set_gpio_dir); diff --git a/arch/h8300/kernel/irq.c b/arch/h8300/kernel/irq.c deleted file mode 100644 index 2fa8ac7b79b5..000000000000 --- a/arch/h8300/kernel/irq.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - * linux/arch/h8300/kernel/irq.c - * - * Copyright 2007 Yoshinori Sato <ysato@users.sourceforge.jp> - */ - -#include <linux/module.h> -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/kernel_stat.h> -#include <linux/seq_file.h> -#include <linux/init.h> -#include <linux/random.h> -#include <linux/bootmem.h> -#include <linux/irq.h> -#include <linux/interrupt.h> - -#include <asm/traps.h> -#include <asm/io.h> -#include <asm/setup.h> -#include <asm/errno.h> - -/*#define DEBUG*/ - -extern unsigned long *interrupt_redirect_table; -extern const int h8300_saved_vectors[]; -extern const h8300_vector h8300_trap_table[]; -int h8300_enable_irq_pin(unsigned int irq); -void h8300_disable_irq_pin(unsigned int irq); - -#define CPU_VECTOR ((unsigned long *)0x000000) -#define ADDR_MASK (0xffffff) - -static inline int is_ext_irq(unsigned int irq) -{ - return (irq >= EXT_IRQ0 && irq <= (EXT_IRQ0 + EXT_IRQS)); -} - -static void h8300_enable_irq(struct irq_data *data) -{ - if (is_ext_irq(data->irq)) - IER_REGS |= 1 << (data->irq - EXT_IRQ0); -} - -static void h8300_disable_irq(struct irq_data *data) -{ - if (is_ext_irq(data->irq)) - IER_REGS &= ~(1 << (data->irq - EXT_IRQ0)); -} - -static unsigned int h8300_startup_irq(struct irq_data *data) -{ - if (is_ext_irq(data->irq)) - return h8300_enable_irq_pin(data->irq); - else - return 0; -} - -static void h8300_shutdown_irq(struct irq_data *data) -{ - if (is_ext_irq(data->irq)) - h8300_disable_irq_pin(data->irq); -} - -/* - * h8300 interrupt controller implementation - */ -struct irq_chip h8300irq_chip = { - .name = "H8300-INTC", - .irq_startup = h8300_startup_irq, - .irq_shutdown = h8300_shutdown_irq, - .irq_enable = h8300_enable_irq, - .irq_disable = h8300_disable_irq, -}; - -#if defined(CONFIG_RAMKERNEL) -static unsigned long __init *get_vector_address(void) -{ - unsigned long *rom_vector = CPU_VECTOR; - unsigned long base,tmp; - int vec_no; - - base = rom_vector[EXT_IRQ0] & ADDR_MASK; - - /* check romvector format */ - for (vec_no = EXT_IRQ1; vec_no <= EXT_IRQ0+EXT_IRQS; vec_no++) { - if ((base+(vec_no - EXT_IRQ0)*4) != (rom_vector[vec_no] & ADDR_MASK)) - return NULL; - } - - /* ramvector base address */ - base -= EXT_IRQ0*4; - - /* writerble check */ - tmp = ~(*(volatile unsigned long *)base); - (*(volatile unsigned long *)base) = tmp; - if ((*(volatile unsigned long *)base) != tmp) - return NULL; - return (unsigned long *)base; -} - -static void __init setup_vector(void) -{ - int i; - unsigned long *ramvec,*ramvec_p; - const h8300_vector *trap_entry; - const int *saved_vector; - - ramvec = get_vector_address(); - if (ramvec == NULL) - panic("interrupt vector serup failed."); - else - printk(KERN_INFO "virtual vector at 0x%08lx\n",(unsigned long)ramvec); - - /* create redirect table */ - ramvec_p = ramvec; - trap_entry = h8300_trap_table; - saved_vector = h8300_saved_vectors; - for ( i = 0; i < NR_IRQS; i++) { - if (i == *saved_vector) { - ramvec_p++; - saved_vector++; - } else { - if ( i < NR_TRAPS ) { - if (*trap_entry) - *ramvec_p = VECTOR(*trap_entry); - ramvec_p++; - trap_entry++; - } else - *ramvec_p++ = REDIRECT(interrupt_entry); - } - } - interrupt_redirect_table = ramvec; -#ifdef DEBUG - ramvec_p = ramvec; - for (i = 0; i < NR_IRQS; i++) { - if ((i % 8) == 0) - printk(KERN_DEBUG "\n%p: ",ramvec_p); - printk(KERN_DEBUG "%p ",*ramvec_p); - ramvec_p++; - } - printk(KERN_DEBUG "\n"); -#endif -} -#else -#define setup_vector() do { } while(0) -#endif - -void __init init_IRQ(void) -{ - int c; - - setup_vector(); - - for (c = 0; c < NR_IRQS; c++) - irq_set_chip_and_handler(c, &h8300irq_chip, handle_simple_irq); -} - -asmlinkage void do_IRQ(int irq) -{ - irq_enter(); - generic_handle_irq(irq); - irq_exit(); -} diff --git a/arch/h8300/kernel/module.c b/arch/h8300/kernel/module.c deleted file mode 100644 index 1d526e05db19..000000000000 --- a/arch/h8300/kernel/module.c +++ /dev/null @@ -1,75 +0,0 @@ -#include <linux/moduleloader.h> -#include <linux/elf.h> -#include <linux/vmalloc.h> -#include <linux/fs.h> -#include <linux/string.h> -#include <linux/kernel.h> - -#if 0 -#define DEBUGP printk -#else -#define DEBUGP(fmt...) -#endif - -int apply_relocate_add(Elf32_Shdr *sechdrs, - const char *strtab, - unsigned int symindex, - unsigned int relsec, - struct module *me) -{ - unsigned int i; - Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr; - - DEBUGP("Applying relocate section %u to %u\n", relsec, - sechdrs[relsec].sh_info); - for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rela); i++) { - /* This is where to make the change */ - uint32_t *loc = (uint32_t *)(sechdrs[sechdrs[relsec].sh_info].sh_addr - + rela[i].r_offset); - /* This is the symbol it is referring to. Note that all - undefined symbols have been resolved. */ - Elf32_Sym *sym = (Elf32_Sym *)sechdrs[symindex].sh_addr - + ELF32_R_SYM(rela[i].r_info); - uint32_t v = sym->st_value + rela[i].r_addend; - - switch (ELF32_R_TYPE(rela[i].r_info)) { - case R_H8_DIR24R8: - loc = (uint32_t *)((uint32_t)loc - 1); - *loc = (*loc & 0xff000000) | ((*loc & 0xffffff) + v); - break; - case R_H8_DIR24A8: - if (ELF32_R_SYM(rela[i].r_info)) - *loc += v; - break; - case R_H8_DIR32: - case R_H8_DIR32A16: - *loc += v; - break; - case R_H8_PCREL16: - v -= (unsigned long)loc + 2; - if ((Elf32_Sword)v > 0x7fff || - (Elf32_Sword)v < -(Elf32_Sword)0x8000) - goto overflow; - else - *(unsigned short *)loc = v; - break; - case R_H8_PCREL8: - v -= (unsigned long)loc + 1; - if ((Elf32_Sword)v > 0x7f || - (Elf32_Sword)v < -(Elf32_Sword)0x80) - goto overflow; - else - *(unsigned char *)loc = v; - break; - default: - printk(KERN_ERR "module %s: Unknown relocation: %u\n", - me->name, ELF32_R_TYPE(rela[i].r_info)); - return -ENOEXEC; - } - } - return 0; - overflow: - printk(KERN_ERR "module %s: relocation offset overflow: %08x\n", - me->name, rela[i].r_offset); - return -ENOEXEC; -} diff --git a/arch/h8300/kernel/process.c b/arch/h8300/kernel/process.c deleted file mode 100644 index 1a744ab7e7e5..000000000000 --- a/arch/h8300/kernel/process.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - * linux/arch/h8300/kernel/process.c - * - * Yoshinori Sato <ysato@users.sourceforge.jp> - * - * Based on: - * - * linux/arch/m68knommu/kernel/process.c - * - * Copyright (C) 1998 D. Jeff Dionne <jeff@ryeham.ee.ryerson.ca>, - * Kenneth Albanowski <kjahds@kjahds.com>, - * The Silver Hammer Group, Ltd. - * - * linux/arch/m68k/kernel/process.c - * - * Copyright (C) 1995 Hamish Macdonald - * - * 68060 fixes by Jesper Skov - */ - -/* - * This file handles the architecture-dependent parts of process handling.. - */ - -#include <linux/errno.h> -#include <linux/module.h> -#include <linux/sched.h> -#include <linux/kernel.h> -#include <linux/mm.h> -#include <linux/smp.h> -#include <linux/stddef.h> -#include <linux/unistd.h> -#include <linux/ptrace.h> -#include <linux/user.h> -#include <linux/interrupt.h> -#include <linux/reboot.h> -#include <linux/fs.h> -#include <linux/slab.h> -#include <linux/rcupdate.h> - -#include <asm/uaccess.h> -#include <asm/traps.h> -#include <asm/setup.h> -#include <asm/pgtable.h> - -void (*pm_power_off)(void) = NULL; -EXPORT_SYMBOL(pm_power_off); - -asmlinkage void ret_from_fork(void); -asmlinkage void ret_from_kernel_thread(void); - -/* - * The idle loop on an H8/300.. - */ -#if !defined(CONFIG_H8300H_SIM) && !defined(CONFIG_H8S_SIM) -void arch_cpu_idle(void) -{ - local_irq_enable(); - /* XXX: race here! What if need_resched() gets set now? */ - __asm__("sleep"); -} -#endif - -void machine_restart(char * __unused) -{ - local_irq_disable(); - __asm__("jmp @@0"); -} - -void machine_halt(void) -{ - local_irq_disable(); - __asm__("sleep"); - for (;;); -} - -void machine_power_off(void) -{ - local_irq_disable(); - __asm__("sleep"); - for (;;); -} - -void show_regs(struct pt_regs * regs) -{ - show_regs_print_info(KERN_DEFAULT); - - printk("\nPC: %08lx Status: %02x", - regs->pc, regs->ccr); - printk("\nORIG_ER0: %08lx ER0: %08lx ER1: %08lx", - regs->orig_er0, regs->er0, regs->er1); - printk("\nER2: %08lx ER3: %08lx ER4: %08lx ER5: %08lx", - regs->er2, regs->er3, regs->er4, regs->er5); - printk("\nER6' %08lx ",regs->er6); - if (user_mode(regs)) - printk("USP: %08lx\n", rdusp()); - else - printk("\n"); -} - -void flush_thread(void) -{ -} - -int copy_thread(unsigned long clone_flags, - unsigned long usp, unsigned long topstk, - struct task_struct * p) -{ - struct pt_regs * childregs; - - childregs = (struct pt_regs *) (THREAD_SIZE + task_stack_page(p)) - 1; - - if (unlikely(p->flags & PF_KTHREAD)) { - memset(childregs, 0, sizeof(struct pt_regs)); - childregs->retpc = (unsigned long) ret_from_kernel_thread; - childregs->er4 = topstk; /* arg */ - childregs->er5 = usp; /* fn */ - p->thread.ksp = (unsigned long)childregs; - } - *childregs = *current_pt_regs(); - childregs->retpc = (unsigned long) ret_from_fork; - childregs->er0 = 0; - p->thread.usp = usp ?: rdusp(); - p->thread.ksp = (unsigned long)childregs; - - return 0; -} - -unsigned long thread_saved_pc(struct task_struct *tsk) -{ - return ((struct pt_regs *)tsk->thread.esp0)->pc; -} - -unsigned long get_wchan(struct task_struct *p) -{ - unsigned long fp, pc; - unsigned long stack_page; - int count = 0; - if (!p || p == current || p->state == TASK_RUNNING) - return 0; - - stack_page = (unsigned long)p; - fp = ((struct pt_regs *)p->thread.ksp)->er6; - do { - if (fp < stack_page+sizeof(struct thread_info) || - fp >= 8184+stack_page) - return 0; - pc = ((unsigned long *)fp)[1]; - if (!in_sched_functions(pc)) - return pc; - fp = *(unsigned long *) fp; - } while (count++ < 16); - return 0; -} diff --git a/arch/h8300/kernel/ptrace.c b/arch/h8300/kernel/ptrace.c deleted file mode 100644 index 748cf6585aa4..000000000000 --- a/arch/h8300/kernel/ptrace.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * linux/arch/h8300/kernel/ptrace.c - * - * Yoshinori Sato <ysato@users.sourceforge.jp> - * - * Based on: - * linux/arch/m68k/kernel/ptrace.c - * - * Copyright (C) 1994 by Hamish Macdonald - * Taken from linux/kernel/ptrace.c and modified for M680x0. - * linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds - * - * This file is subject to the terms and conditions of the GNU General - * Public License. See the file COPYING in the main directory of - * this archive for more details. - */ - -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/mm.h> -#include <linux/smp.h> -#include <linux/errno.h> -#include <linux/ptrace.h> -#include <linux/user.h> -#include <linux/signal.h> - -#include <asm/uaccess.h> -#include <asm/page.h> -#include <asm/pgtable.h> -#include <asm/processor.h> -#include <asm/signal.h> - -/* cpu depend functions */ -extern long h8300_get_reg(struct task_struct *task, int regno); -extern int h8300_put_reg(struct task_struct *task, int regno, unsigned long data); - - -void user_disable_single_step(struct task_struct *child) -{ -} - -/* - * does not yet catch signals sent when the child dies. - * in exit.c or in signal.c. - */ - -void ptrace_disable(struct task_struct *child) -{ - user_disable_single_step(child); -} - -long arch_ptrace(struct task_struct *child, long request, - unsigned long addr, unsigned long data) -{ - int ret; - int regno = addr >> 2; - unsigned long __user *datap = (unsigned long __user *) data; - - switch (request) { - /* read the word at location addr in the USER area. */ - case PTRACE_PEEKUSR: { - unsigned long tmp = 0; - - if ((addr & 3) || addr >= sizeof(struct user)) { - ret = -EIO; - break ; - } - - ret = 0; /* Default return condition */ - - if (regno < H8300_REGS_NO) - tmp = h8300_get_reg(child, regno); - else { - switch (regno) { - case 49: - tmp = child->mm->start_code; - break ; - case 50: - tmp = child->mm->start_data; - break ; - case 51: - tmp = child->mm->end_code; - break ; - case 52: - tmp = child->mm->end_data; - break ; - default: - ret = -EIO; - } - } - if (!ret) - ret = put_user(tmp, datap); - break ; - } - - /* when I and D space are separate, this will have to be fixed. */ - case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ - if ((addr & 3) || addr >= sizeof(struct user)) { - ret = -EIO; - break ; - } - - if (regno == PT_ORIG_ER0) { - ret = -EIO; - break ; - } - if (regno < H8300_REGS_NO) { - ret = h8300_put_reg(child, regno, data); - break ; - } - ret = -EIO; - break ; - - case PTRACE_GETREGS: { /* Get all gp regs from the child. */ - int i; - unsigned long tmp; - for (i = 0; i < H8300_REGS_NO; i++) { - tmp = h8300_get_reg(child, i); - if (put_user(tmp, datap)) { - ret = -EFAULT; - break; - } - datap++; - } - ret = 0; - break; - } - - case PTRACE_SETREGS: { /* Set all gp regs in the child. */ - int i; - unsigned long tmp; - for (i = 0; i < H8300_REGS_NO; i++) { - if (get_user(tmp, datap)) { - ret = -EFAULT; - break; - } - h8300_put_reg(child, i, tmp); - datap++; - } - ret = 0; - break; - } - - default: - ret = ptrace_request(child, request, addr, data); - break; - } - return ret; -} - -asmlinkage void do_syscall_trace(void) -{ - if (!test_thread_flag(TIF_SYSCALL_TRACE)) - return; - if (!(current->ptrace & PT_PTRACED)) - return; - ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) - ? 0x80 : 0)); - /* - * this isn't the same as continuing with a signal, but it will do - * for normal use. strace only continues with a signal if the - * stopping signal is not SIGTRAP. -brl - */ - if (current->exit_code) { - send_sig(current->exit_code, current, 1); - current->exit_code = 0; - } -} diff --git a/arch/h8300/kernel/setup.c b/arch/h8300/kernel/setup.c deleted file mode 100644 index d0b1607f2711..000000000000 --- a/arch/h8300/kernel/setup.c +++ /dev/null @@ -1,242 +0,0 @@ -/* - * linux/arch/h8300/kernel/setup.c - * - * Copyleft ()) 2000 James D. Schettine {james@telos-systems.com} - * Copyright (C) 1999,2000 Greg Ungerer (gerg@snapgear.com) - * Copyright (C) 1998,1999 D. Jeff Dionne <jeff@lineo.ca> - * Copyright (C) 1998 Kenneth Albanowski <kjahds@kjahds.com> - * Copyright (C) 1995 Hamish Macdonald - * Copyright (C) 2000 Lineo Inc. (www.lineo.com) - * Copyright (C) 2001 Lineo, Inc. <www.lineo.com> - * - * H8/300 porting Yoshinori Sato <ysato@users.sourceforge.jp> - */ - -/* - * This file handles the architecture-dependent parts of system setup - */ - -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/delay.h> -#include <linux/interrupt.h> -#include <linux/mm.h> -#include <linux/fs.h> -#include <linux/fb.h> -#include <linux/console.h> -#include <linux/genhd.h> -#include <linux/errno.h> -#include <linux/string.h> -#include <linux/major.h> -#include <linux/bootmem.h> -#include <linux/seq_file.h> -#include <linux/init.h> - -#include <asm/setup.h> -#include <asm/irq.h> -#include <asm/pgtable.h> -#include <asm/sections.h> - -#if defined(__H8300H__) -#define CPU "H8/300H" -#include <asm/regs306x.h> -#endif - -#if defined(__H8300S__) -#define CPU "H8S" -#include <asm/regs267x.h> -#endif - -#define STUBSIZE 0xc000 - -unsigned long rom_length; -unsigned long memory_start; -unsigned long memory_end; - -char __initdata command_line[COMMAND_LINE_SIZE]; - -extern int _ramstart, _ramend; -extern char _target_name[]; -extern void h8300_gpio_init(void); - -#if (defined(CONFIG_H8300H_SIM) || defined(CONFIG_H8S_SIM)) \ - && defined(CONFIG_GDB_MAGICPRINT) -/* printk with gdb service */ -static void gdb_console_output(struct console *c, const char *msg, unsigned len) -{ - for (; len > 0; len--) { - asm("mov.w %0,r2\n\t" - "jsr @0xc4"::"r"(*msg++):"er2"); - } -} - -/* - * Setup initial baud/bits/parity. We do two things here: - * - construct a cflag setting for the first rs_open() - * - initialize the serial port - * Return non-zero if we didn't find a serial port. - */ -static int __init gdb_console_setup(struct console *co, char *options) -{ - return 0; -} - -static const struct console gdb_console = { - .name = "gdb_con", - .write = gdb_console_output, - .device = NULL, - .setup = gdb_console_setup, - .flags = CON_PRINTBUFFER, - .index = -1, -}; -#endif - -void __init setup_arch(char **cmdline_p) -{ - int bootmap_size; - - memory_start = (unsigned long) &_ramstart; - - /* allow for ROMFS on the end of the kernel */ - if (memcmp((void *)memory_start, "-rom1fs-", 8) == 0) { -#if defined(CONFIG_BLK_DEV_INITRD) - initrd_start = memory_start; - initrd_end = memory_start += be32_to_cpu(((unsigned long *) (memory_start))[2]); -#else - memory_start += be32_to_cpu(((unsigned long *) memory_start)[2]); -#endif - } - memory_start = PAGE_ALIGN(memory_start); -#if !defined(CONFIG_BLKDEV_RESERVE) - memory_end = (unsigned long) &_ramend; /* by now the stack is part of the init task */ -#if defined(CONFIG_GDB_DEBUG) - memory_end -= STUBSIZE; -#endif -#else - if ((memory_end < CONFIG_BLKDEV_RESERVE_ADDRESS) && - (memory_end > CONFIG_BLKDEV_RESERVE_ADDRESS)) - /* overlap userarea */ - memory_end = CONFIG_BLKDEV_RESERVE_ADDRESS; -#endif - - init_mm.start_code = (unsigned long) _stext; - init_mm.end_code = (unsigned long) _etext; - init_mm.end_data = (unsigned long) _edata; - init_mm.brk = (unsigned long) 0; - -#if (defined(CONFIG_H8300H_SIM) || defined(CONFIG_H8S_SIM)) && defined(CONFIG_GDB_MAGICPRINT) - register_console((struct console *)&gdb_console); -#endif - - printk(KERN_INFO "\r\n\nuClinux " CPU "\n"); - printk(KERN_INFO "Target Hardware: %s\n",_target_name); - printk(KERN_INFO "Flat model support (C) 1998,1999 Kenneth Albanowski, D. Jeff Dionne\n"); - printk(KERN_INFO "H8/300 series support by Yoshinori Sato <ysato@users.sourceforge.jp>\n"); - -#ifdef DEBUG - printk(KERN_DEBUG "KERNEL -> TEXT=0x%p-0x%p DATA=0x%p-0x%p " - "BSS=0x%p-0x%p\n", _stext, _etext, _sdata, _edata, __bss_start, - __bss_stop); - printk(KERN_DEBUG "KERNEL -> ROMFS=0x%p-0x%06lx MEM=0x%06lx-0x%06lx " - "STACK=0x%06lx-0x%p\n", __bss_stop, memory_start, memory_start, - memory_end, memory_end, &_ramend); -#endif - -#ifdef CONFIG_DEFAULT_CMDLINE - /* set from default command line */ - if (*command_line == '\0') - strcpy(command_line,CONFIG_KERNEL_COMMAND); -#endif - /* Keep a copy of command line */ - *cmdline_p = &command_line[0]; - memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); - boot_command_line[COMMAND_LINE_SIZE-1] = 0; - -#ifdef DEBUG - if (strlen(*cmdline_p)) - printk(KERN_DEBUG "Command line: '%s'\n", *cmdline_p); -#endif - - /* - * give all the memory to the bootmap allocator, tell it to put the - * boot mem_map at the start of memory - */ - bootmap_size = init_bootmem_node( - NODE_DATA(0), - memory_start >> PAGE_SHIFT, /* map goes here */ - PAGE_OFFSET >> PAGE_SHIFT, /* 0 on coldfire */ - memory_end >> PAGE_SHIFT); - /* - * free the usable memory, we have to make sure we do not free - * the bootmem bitmap so we then reserve it after freeing it :-) - */ - free_bootmem(memory_start, memory_end - memory_start); - reserve_bootmem(memory_start, bootmap_size, BOOTMEM_DEFAULT); - /* - * get kmalloc into gear - */ - paging_init(); - h8300_gpio_init(); -#if defined(CONFIG_H8300_AKI3068NET) && defined(CONFIG_IDE) - { -#define AREABIT(addr) (1 << (((addr) >> 21) & 7)) - /* setup BSC */ - volatile unsigned char *abwcr = (volatile unsigned char *)ABWCR; - volatile unsigned char *cscr = (volatile unsigned char *)CSCR; - *abwcr &= ~(AREABIT(CONFIG_H8300_IDE_BASE) | AREABIT(CONFIG_H8300_IDE_ALT)); - *cscr |= (AREABIT(CONFIG_H8300_IDE_BASE) | AREABIT(CONFIG_H8300_IDE_ALT)) | 0x0f; - } -#endif -#ifdef DEBUG - printk(KERN_DEBUG "Done setup_arch\n"); -#endif -} - -/* - * Get CPU information for use by the procfs. - */ - -static int show_cpuinfo(struct seq_file *m, void *v) -{ - char *cpu; - int mode; - u_long clockfreq; - - cpu = CPU; - mode = *(volatile unsigned char *)MDCR & 0x07; - - clockfreq = CONFIG_CPU_CLOCK; - - seq_printf(m, "CPU:\t\t%s (mode:%d)\n" - "Clock:\t\t%lu.%1luMHz\n" - "BogoMips:\t%lu.%02lu\n" - "Calibration:\t%lu loops\n", - cpu,mode, - clockfreq/1000,clockfreq%1000, - (loops_per_jiffy*HZ)/500000,((loops_per_jiffy*HZ)/5000)%100, - (loops_per_jiffy*HZ)); - - return 0; -} - -static void *c_start(struct seq_file *m, loff_t *pos) -{ - return *pos < NR_CPUS ? ((void *) 0x12345678) : NULL; -} - -static void *c_next(struct seq_file *m, void *v, loff_t *pos) -{ - ++*pos; - return c_start(m, pos); -} - -static void c_stop(struct seq_file *m, void *v) -{ -} - -const struct seq_operations cpuinfo_op = { - .start = c_start, - .next = c_next, - .stop = c_stop, - .show = show_cpuinfo, -}; diff --git a/arch/h8300/kernel/signal.c b/arch/h8300/kernel/signal.c deleted file mode 100644 index a65ff3b76326..000000000000 --- a/arch/h8300/kernel/signal.c +++ /dev/null @@ -1,444 +0,0 @@ -/* - * linux/arch/h8300/kernel/signal.c - * - * Copyright (C) 1991, 1992 Linus Torvalds - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - */ - -/* - * uClinux H8/300 support by Yoshinori Sato <ysato@users.sourceforge.jp> - * and David McCullough <davidm@snapgear.com> - * - * Based on - * Linux/m68k by Hamish Macdonald - */ - -/* - * ++roman (07/09/96): implemented signal stacks (specially for tosemu on - * Atari :-) Current limitation: Only one sigstack can be active at one time. - * If a second signal with SA_ONSTACK set arrives while working on a sigstack, - * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested - * signal handlers! - */ - -#include <linux/sched.h> -#include <linux/mm.h> -#include <linux/kernel.h> -#include <linux/signal.h> -#include <linux/syscalls.h> -#include <linux/errno.h> -#include <linux/wait.h> -#include <linux/ptrace.h> -#include <linux/unistd.h> -#include <linux/stddef.h> -#include <linux/highuid.h> -#include <linux/personality.h> -#include <linux/tty.h> -#include <linux/binfmts.h> -#include <linux/tracehook.h> - -#include <asm/setup.h> -#include <asm/uaccess.h> -#include <asm/pgtable.h> -#include <asm/traps.h> -#include <asm/ucontext.h> - -/* - * Do a signal return; undo the signal stack. - * - * Keep the return code on the stack quadword aligned! - * That makes the cache flush below easier. - */ - -struct sigframe -{ - long dummy_er0; - long dummy_vector; -#if defined(CONFIG_CPU_H8S) - short dummy_exr; -#endif - long dummy_pc; - char *pretcode; - unsigned char retcode[8]; - unsigned long extramask[_NSIG_WORDS-1]; - struct sigcontext sc; - int sig; -} __attribute__((aligned(2),packed)); - -struct rt_sigframe -{ - long dummy_er0; - long dummy_vector; -#if defined(CONFIG_CPU_H8S) - short dummy_exr; -#endif - long dummy_pc; - char *pretcode; - struct siginfo *pinfo; - void *puc; - unsigned char retcode[8]; - struct siginfo info; - struct ucontext uc; - int sig; -} __attribute__((aligned(2),packed)); - -static inline int -restore_sigcontext(struct sigcontext *usc, int *pd0) -{ - struct pt_regs *regs = current_pt_regs(); - int err = 0; - unsigned int ccr; - unsigned int usp; - unsigned int er0; - - /* Always make any pending restarted system calls return -EINTR */ - current_thread_info()->restart_block.fn = do_no_restart_syscall; - -#define COPY(r) err |= __get_user(regs->r, &usc->sc_##r) /* restore passed registers */ - COPY(er1); - COPY(er2); - COPY(er3); - COPY(er5); - COPY(pc); - ccr = regs->ccr & 0x10; - COPY(ccr); -#undef COPY - regs->ccr &= 0xef; - regs->ccr |= ccr; - regs->orig_er0 = -1; /* disable syscall checks */ - err |= __get_user(usp, &usc->sc_usp); - wrusp(usp); - - err |= __get_user(er0, &usc->sc_er0); - *pd0 = er0; - return err; -} - -asmlinkage int sys_sigreturn(void) -{ - unsigned long usp = rdusp(); - struct sigframe *frame = (struct sigframe *)(usp - 4); - sigset_t set; - int er0; - - if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) - goto badframe; - if (__get_user(set.sig[0], &frame->sc.sc_mask) || - (_NSIG_WORDS > 1 && - __copy_from_user(&set.sig[1], &frame->extramask, - sizeof(frame->extramask)))) - goto badframe; - - set_current_blocked(&set); - - if (restore_sigcontext(&frame->sc, &er0)) - goto badframe; - return er0; - -badframe: - force_sig(SIGSEGV, current); - return 0; -} - -asmlinkage int sys_rt_sigreturn(void) -{ - unsigned long usp = rdusp(); - struct rt_sigframe *frame = (struct rt_sigframe *)(usp - 4); - sigset_t set; - int er0; - - if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) - goto badframe; - if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) - goto badframe; - - set_current_blocked(&set); - - if (restore_sigcontext(&frame->uc.uc_mcontext, &er0)) - goto badframe; - - if (restore_altstack(&frame->uc.uc_stack)) - goto badframe; - - return er0; - -badframe: - force_sig(SIGSEGV, current); - return 0; -} - -static int setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, - unsigned long mask) -{ - int err = 0; - - err |= __put_user(regs->er0, &sc->sc_er0); - err |= __put_user(regs->er1, &sc->sc_er1); - err |= __put_user(regs->er2, &sc->sc_er2); - err |= __put_user(regs->er3, &sc->sc_er3); - err |= __put_user(regs->er4, &sc->sc_er4); - err |= __put_user(regs->er5, &sc->sc_er5); - err |= __put_user(regs->er6, &sc->sc_er6); - err |= __put_user(rdusp(), &sc->sc_usp); - err |= __put_user(regs->pc, &sc->sc_pc); - err |= __put_user(regs->ccr, &sc->sc_ccr); - err |= __put_user(mask, &sc->sc_mask); - - return err; -} - -static inline void * -get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) -{ - unsigned long usp; - - /* Default to using normal stack. */ - usp = rdusp(); - - /* This is the X/Open sanctioned signal stack switching. */ - if (ka->sa.sa_flags & SA_ONSTACK) { - if (!sas_ss_flags(usp)) - usp = current->sas_ss_sp + current->sas_ss_size; - } - return (void *)((usp - frame_size) & -8UL); -} - -static int setup_frame (int sig, struct k_sigaction *ka, - sigset_t *set, struct pt_regs *regs) -{ - struct sigframe *frame; - int err = 0; - int usig; - unsigned char *ret; - - frame = get_sigframe(ka, regs, sizeof(*frame)); - - if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) - goto give_sigsegv; - - usig = current_thread_info()->exec_domain - && current_thread_info()->exec_domain->signal_invmap - && sig < 32 - ? current_thread_info()->exec_domain->signal_invmap[sig] - : sig; - - err |= __put_user(usig, &frame->sig); - if (err) - goto give_sigsegv; - - err |= setup_sigcontext(&frame->sc, regs, set->sig[0]); - if (err) - goto give_sigsegv; - - if (_NSIG_WORDS > 1) { - err |= copy_to_user(frame->extramask, &set->sig[1], - sizeof(frame->extramask)); - if (err) - goto give_sigsegv; - } - - ret = frame->retcode; - if (ka->sa.sa_flags & SA_RESTORER) - ret = (unsigned char *)(ka->sa.sa_restorer); - else { - /* sub.l er0,er0; mov.b #__NR_sigreturn,r0l; trapa #0 */ - err |= __put_user(0x1a80f800 + (__NR_sigreturn & 0xff), - (unsigned long *)(frame->retcode + 0)); - err |= __put_user(0x5700, (unsigned short *)(frame->retcode + 4)); - } - - /* Set up to return from userspace. */ - err |= __put_user(ret, &frame->pretcode); - - if (err) - goto give_sigsegv; - - /* Set up registers for signal handler */ - wrusp ((unsigned long) frame); - regs->pc = (unsigned long) ka->sa.sa_handler; - regs->er0 = (current_thread_info()->exec_domain - && current_thread_info()->exec_domain->signal_invmap - && sig < 32 - ? current_thread_info()->exec_domain->signal_invmap[sig] - : sig); - regs->er1 = (unsigned long)&(frame->sc); - regs->er5 = current->mm->start_data; /* GOT base */ - - return 0; - -give_sigsegv: - force_sigsegv(sig, current); - return -EFAULT; -} - -static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, - sigset_t *set, struct pt_regs *regs) -{ - struct rt_sigframe *frame; - int err = 0; - int usig; - unsigned char *ret; - - frame = get_sigframe(ka, regs, sizeof(*frame)); - - if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) - goto give_sigsegv; - - usig = current_thread_info()->exec_domain - && current_thread_info()->exec_domain->signal_invmap - && sig < 32 - ? current_thread_info()->exec_domain->signal_invmap[sig] - : sig; - - err |= __put_user(usig, &frame->sig); - if (err) - goto give_sigsegv; - - err |= __put_user(&frame->info, &frame->pinfo); - err |= __put_user(&frame->uc, &frame->puc); - err |= copy_siginfo_to_user(&frame->info, info); - if (err) - goto give_sigsegv; - - /* Create the ucontext. */ - err |= __put_user(0, &frame->uc.uc_flags); - err |= __put_user(0, &frame->uc.uc_link); - err |= __save_altstack(&frame->uc.uc_stack, rdusp()); - err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0]); - err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set)); - if (err) - goto give_sigsegv; - - /* Set up to return from userspace. */ - ret = frame->retcode; - if (ka->sa.sa_flags & SA_RESTORER) - ret = (unsigned char *)(ka->sa.sa_restorer); - else { - /* sub.l er0,er0; mov.b #__NR_sigreturn,r0l; trapa #0 */ - err |= __put_user(0x1a80f800 + (__NR_sigreturn & 0xff), - (unsigned long *)(frame->retcode + 0)); - err |= __put_user(0x5700, (unsigned short *)(frame->retcode + 4)); - } - err |= __put_user(ret, &frame->pretcode); - - if (err) - goto give_sigsegv; - - /* Set up registers for signal handler */ - wrusp ((unsigned long) frame); - regs->pc = (unsigned long) ka->sa.sa_handler; - regs->er0 = (current_thread_info()->exec_domain - && current_thread_info()->exec_domain->signal_invmap - && sig < 32 - ? current_thread_info()->exec_domain->signal_invmap[sig] - : sig); - regs->er1 = (unsigned long)&(frame->info); - regs->er2 = (unsigned long)&frame->uc; - regs->er5 = current->mm->start_data; /* GOT base */ - - return 0; - -give_sigsegv: - force_sigsegv(sig, current); - return -EFAULT; -} - -/* - * OK, we're invoking a handler - */ -static void -handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, - struct pt_regs * regs) -{ - sigset_t *oldset = sigmask_to_save(); - int ret; - /* are we from a system call? */ - if (regs->orig_er0 >= 0) { - switch (regs->er0) { - case -ERESTART_RESTARTBLOCK: - case -ERESTARTNOHAND: - regs->er0 = -EINTR; - break; - - case -ERESTARTSYS: - if (!(ka->sa.sa_flags & SA_RESTART)) { - regs->er0 = -EINTR; - break; - } - /* fallthrough */ - case -ERESTARTNOINTR: - regs->er0 = regs->orig_er0; - regs->pc -= 2; - } - } - - /* set up the stack frame */ - if (ka->sa.sa_flags & SA_SIGINFO) - ret = setup_rt_frame(sig, ka, info, oldset, regs); - else - ret = setup_frame(sig, ka, oldset, regs); - - if (!ret) - signal_delivered(sig, info, ka, regs, 0); -} - -/* - * Note that 'init' is a special process: it doesn't get signals it doesn't - * want to handle. Thus you cannot kill init even with a SIGKILL even by - * mistake. - */ -static void do_signal(struct pt_regs *regs) -{ - siginfo_t info; - int signr; - struct k_sigaction ka; - - /* - * We want the common case to go fast, which - * is why we may in certain cases get here from - * kernel mode. Just return without doing anything - * if so. - */ - if ((regs->ccr & 0x10)) - return; - - current->thread.esp0 = (unsigned long) regs; - - signr = get_signal_to_deliver(&info, &ka, regs, NULL); - if (signr > 0) { - /* Whee! Actually deliver the signal. */ - handle_signal(signr, &info, &ka, regs); - return; - } - /* Did we come from a system call? */ - if (regs->orig_er0 >= 0) { - /* Restart the system call - no handlers present */ - if (regs->er0 == -ERESTARTNOHAND || - regs->er0 == -ERESTARTSYS || - regs->er0 == -ERESTARTNOINTR) { - regs->er0 = regs->orig_er0; - regs->pc -= 2; - } - if (regs->er0 == -ERESTART_RESTARTBLOCK){ - regs->er0 = __NR_restart_syscall; - regs->pc -= 2; - } - } - - /* If there's no signal to deliver, we just restore the saved mask. */ - restore_saved_sigmask(); -} - -asmlinkage void do_notify_resume(struct pt_regs *regs, u32 thread_info_flags) -{ - if (thread_info_flags & _TIF_SIGPENDING) - do_signal(regs); - - if (thread_info_flags & _TIF_NOTIFY_RESUME) { - clear_thread_flag(TIF_NOTIFY_RESUME); - tracehook_notify_resume(regs); - } -} diff --git a/arch/h8300/kernel/sys_h8300.c b/arch/h8300/kernel/sys_h8300.c deleted file mode 100644 index bf350cb7f597..000000000000 --- a/arch/h8300/kernel/sys_h8300.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * linux/arch/h8300/kernel/sys_h8300.c - * - * This file contains various random system calls that - * have a non-standard calling sequence on the H8/300 - * platform. - */ - -#include <linux/errno.h> -#include <linux/sched.h> -#include <linux/mm.h> -#include <linux/smp.h> -#include <linux/sem.h> -#include <linux/msg.h> -#include <linux/shm.h> -#include <linux/stat.h> -#include <linux/syscalls.h> -#include <linux/mman.h> -#include <linux/file.h> -#include <linux/fs.h> -#include <linux/ipc.h> - -#include <asm/setup.h> -#include <asm/uaccess.h> -#include <asm/cachectl.h> -#include <asm/traps.h> -#include <asm/unistd.h> - -/* sys_cacheflush -- no support. */ -asmlinkage int -sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len) -{ - return -EINVAL; -} - -asmlinkage int sys_getpagesize(void) -{ - return PAGE_SIZE; -} - -#if defined(CONFIG_SYSCALL_PRINT) -asmlinkage void syscall_print(void *dummy,...) -{ - struct pt_regs *regs = (struct pt_regs *) ((unsigned char *)&dummy-4); - printk("call %06lx:%ld 1:%08lx,2:%08lx,3:%08lx,ret:%08lx\n", - ((regs->pc)&0xffffff)-2,regs->orig_er0,regs->er1,regs->er2,regs->er3,regs->er0); -} -#endif diff --git a/arch/h8300/kernel/syscalls.S b/arch/h8300/kernel/syscalls.S deleted file mode 100644 index c55e0ed270d5..000000000000 --- a/arch/h8300/kernel/syscalls.S +++ /dev/null @@ -1,338 +0,0 @@ -/* Systemcall Entry Table */ -#include <linux/sys.h> -#include <asm/linkage.h> -#include <asm/unistd.h> - -#define CALL(x) .long _ ## x - -.globl _sys_call_table - -#if defined(CONFIG_CPU_H8300H) - .h8300h -#endif -#if defined(CONFIG_CPU_H8S) - .h8300s -#endif - .section .text - .align 2 -_sys_call_table: - CALL(sys_ni_syscall) /* 0 - old "setup()" system call*/ - CALL(sys_exit) - CALL(sys_fork) - CALL(sys_read) - CALL(sys_write) - CALL(sys_open) /* 5 */ - CALL(sys_close) - CALL(sys_waitpid) - CALL(sys_creat) - CALL(sys_link) - CALL(sys_unlink) /* 10 */ - CALL(sys_execve) - CALL(sys_chdir) - CALL(sys_time) - CALL(sys_mknod) - CALL(sys_chmod) /* 15 */ - CALL(sys_chown16) - CALL(sys_ni_syscall) /* old break syscall holder */ - CALL(sys_stat) - CALL(sys_lseek) - CALL(sys_getpid) /* 20 */ - CALL(sys_mount) - CALL(sys_oldumount) - CALL(sys_setuid16) - CALL(sys_getuid16) - CALL(sys_stime) /* 25 */ - CALL(sys_ptrace) - CALL(sys_alarm) - CALL(sys_fstat) - CALL(sys_pause) - CALL(sys_utime) /* 30 */ - CALL(sys_ni_syscall) /* old stty syscall holder */ - CALL(sys_ni_syscall) /* old gtty syscall holder */ - CALL(sys_access) - CALL(sys_nice) - CALL(sys_ni_syscall) /* 35 old ftime syscall holder */ - CALL(sys_sync) - CALL(sys_kill) - CALL(sys_rename) - CALL(sys_mkdir) - CALL(sys_rmdir) /* 40 */ - CALL(sys_dup) - CALL(sys_pipe) - CALL(sys_times) - CALL(sys_ni_syscall) /* old prof syscall holder */ - CALL(sys_brk) /* 45 */ - CALL(sys_setgid16) - CALL(sys_getgid16) - CALL(sys_signal) - CALL(sys_geteuid16) - CALL(sys_getegid16) /* 50 */ - CALL(sys_acct) - CALL(sys_umount) /* recycled never used phys() */ - CALL(sys_ni_syscall) /* old lock syscall holder */ - CALL(sys_ioctl) - CALL(sys_fcntl) /* 55 */ - CALL(sys_ni_syscall) /* old mpx syscall holder */ - CALL(sys_setpgid) - CALL(sys_ni_syscall) /* old ulimit syscall holder */ - CALL(sys_ni_syscall) - CALL(sys_umask) /* 60 */ - CALL(sys_chroot) - CALL(sys_ustat) - CALL(sys_dup2) - CALL(sys_getppid) - CALL(sys_getpgrp) /* 65 */ - CALL(sys_setsid) - CALL(sys_sigaction) - CALL(sys_sgetmask) - CALL(sys_ssetmask) - CALL(sys_setreuid16) /* 70 */ - CALL(sys_setregid16) - CALL(sys_sigsuspend) - CALL(sys_sigpending) - CALL(sys_sethostname) - CALL(sys_setrlimit) /* 75 */ - CALL(sys_old_getrlimit) - CALL(sys_getrusage) - CALL(sys_gettimeofday) - CALL(sys_settimeofday) - CALL(sys_getgroups16) /* 80 */ - CALL(sys_setgroups16) - CALL(sys_old_select) - CALL(sys_symlink) - CALL(sys_lstat) - CALL(sys_readlink) /* 85 */ - CALL(sys_uselib) - CALL(sys_swapon) - CALL(sys_reboot) - CALL(sys_old_readdir) - CALL(sys_old_mmap) /* 90 */ - CALL(sys_munmap) - CALL(sys_truncate) - CALL(sys_ftruncate) - CALL(sys_fchmod) - CALL(sys_fchown16) /* 95 */ - CALL(sys_getpriority) - CALL(sys_setpriority) - CALL(sys_ni_syscall) /* old profil syscall holder */ - CALL(sys_statfs) - CALL(sys_fstatfs) /* 100 */ - CALL(sys_ni_syscall) /* ioperm for i386 */ - CALL(sys_socketcall) - CALL(sys_syslog) - CALL(sys_setitimer) - CALL(sys_getitimer) /* 105 */ - CALL(sys_newstat) - CALL(sys_newlstat) - CALL(sys_newfstat) - CALL(sys_ni_syscall) - CALL(sys_ni_syscall) /* iopl for i386 */ /* 110 */ - CALL(sys_vhangup) - CALL(sys_ni_syscall) /* obsolete idle() syscall */ - CALL(sys_ni_syscall) /* vm86old for i386 */ - CALL(sys_wait4) - CALL(sys_swapoff) /* 115 */ - CALL(sys_sysinfo) - CALL(sys_ipc) - CALL(sys_fsync) - CALL(sys_sigreturn) - CALL(sys_clone) /* 120 */ - CALL(sys_setdomainname) - CALL(sys_newuname) - CALL(sys_cacheflush) /* modify_ldt for i386 */ - CALL(sys_adjtimex) - CALL(sys_ni_syscall) /* 125 sys_mprotect */ - CALL(sys_sigprocmask) - CALL(sys_ni_syscall) /* sys_create_module */ - CALL(sys_init_module) - CALL(sys_delete_module) - CALL(sys_ni_syscall) /* 130 sys_get_kernel_syms */ - CALL(sys_quotactl) - CALL(sys_getpgid) - CALL(sys_fchdir) - CALL(sys_bdflush) - CALL(sys_sysfs) /* 135 */ - CALL(sys_personality) - CALL(sys_ni_syscall) /* for afs_syscall */ - CALL(sys_setfsuid16) - CALL(sys_setfsgid16) - CALL(sys_llseek) /* 140 */ - CALL(sys_getdents) - CALL(sys_select) - CALL(sys_flock) - CALL(sys_ni_syscall) /* sys_msync */ - CALL(sys_readv) /* 145 */ - CALL(sys_writev) - CALL(sys_getsid) - CALL(sys_fdatasync) - CALL(sys_sysctl) - CALL(sys_ni_syscall) /* 150 sys_mlock */ - CALL(sys_ni_syscall) /* sys_munlock */ - CALL(sys_ni_syscall) /* sys_mlockall */ - CALL(sys_ni_syscall) /* sys_munlockall */ - CALL(sys_sched_setparam) - CALL(sys_sched_getparam) /* 155 */ - CALL(sys_sched_setscheduler) - CALL(sys_sched_getscheduler) - CALL(sys_sched_yield) - CALL(sys_sched_get_priority_max) - CALL(sys_sched_get_priority_min) /* 160 */ - CALL(sys_sched_rr_get_interval) - CALL(sys_nanosleep) - CALL(sys_ni_syscall) /* sys_mremap */ - CALL(sys_setresuid16) - CALL(sys_getresuid16) /* 165 */ - CALL(sys_ni_syscall) /* for vm86 */ - CALL(sys_ni_syscall) /* sys_query_module */ - CALL(sys_poll) - CALL(sys_ni_syscall) /* old nfsservctl */ - CALL(sys_setresgid16) /* 170 */ - CALL(sys_getresgid16) - CALL(sys_prctl) - CALL(sys_rt_sigreturn) - CALL(sys_rt_sigaction) - CALL(sys_rt_sigprocmask) /* 175 */ - CALL(sys_rt_sigpending) - CALL(sys_rt_sigtimedwait) - CALL(sys_rt_sigqueueinfo) - CALL(sys_rt_sigsuspend) - CALL(sys_pread64) /* 180 */ - CALL(sys_pwrite64) - CALL(sys_lchown16); - CALL(sys_getcwd) - CALL(sys_capget) - CALL(sys_capset) /* 185 */ - CALL(sys_sigaltstack) - CALL(sys_sendfile) - CALL(sys_ni_syscall) /* streams1 */ - CALL(sys_ni_syscall) /* streams2 */ - CALL(sys_vfork) /* 190 */ - CALL(sys_getrlimit) - CALL(sys_mmap_pgoff) - CALL(sys_truncate64) - CALL(sys_ftruncate64) - CALL(sys_stat64) /* 195 */ - CALL(sys_lstat64) - CALL(sys_fstat64) - CALL(sys_chown) - CALL(sys_getuid) - CALL(sys_getgid) /* 200 */ - CALL(sys_geteuid) - CALL(sys_getegid) - CALL(sys_setreuid) - CALL(sys_setregid) - CALL(sys_getgroups) /* 205 */ - CALL(sys_setgroups) - CALL(sys_fchown) - CALL(sys_setresuid) - CALL(sys_getresuid) - CALL(sys_setresgid) /* 210 */ - CALL(sys_getresgid) - CALL(sys_lchown) - CALL(sys_setuid) - CALL(sys_setgid) - CALL(sys_setfsuid) /* 215 */ - CALL(sys_setfsgid) - CALL(sys_pivot_root) - CALL(sys_ni_syscall) - CALL(sys_ni_syscall) - CALL(sys_getdents64) /* 220 */ - CALL(sys_fcntl64) - CALL(sys_ni_syscall) /* reserved TUX */ - CALL(sys_ni_syscall) /* reserved Security */ - CALL(sys_gettid) - CALL(sys_readahead) /* 225 */ - CALL(sys_setxattr) - CALL(sys_lsetxattr) - CALL(sys_fsetxattr) - CALL(sys_getxattr) - CALL(sys_lgetxattr) /* 230 */ - CALL(sys_fgetxattr) - CALL(sys_listxattr) - CALL(sys_llistxattr) - CALL(sys_flistxattr) - CALL(sys_removexattr) /* 235 */ - CALL(sys_lremovexattr) - CALL(sys_fremovexattr) - CALL(sys_tkill) - CALL(sys_sendfile64) - CALL(sys_futex) /* 240 */ - CALL(sys_sched_setaffinity) - CALL(sys_sched_getaffinity) - CALL(sys_ni_syscall) - CALL(sys_ni_syscall) - CALL(sys_io_setup) /* 245 */ - CALL(sys_io_destroy) - CALL(sys_io_getevents) - CALL(sys_io_submit) - CALL(sys_io_cancel) - CALL(sys_fadvise64) /* 250 */ - CALL(sys_ni_syscall) - CALL(sys_exit_group) - CALL(sys_lookup_dcookie) - CALL(sys_epoll_create) - CALL(sys_epoll_ctl) /* 255 */ - CALL(sys_epoll_wait) - CALL(sys_ni_syscall) /* sys_remap_file_pages */ - CALL(sys_set_tid_address) - CALL(sys_timer_create) - CALL(sys_timer_settime) /* 260 */ - CALL(sys_timer_gettime) - CALL(sys_timer_getoverrun) - CALL(sys_timer_delete) - CALL(sys_clock_settime) - CALL(sys_clock_gettime) /* 265 */ - CALL(sys_clock_getres) - CALL(sys_clock_nanosleep) - CALL(sys_statfs64) - CALL(sys_fstatfs64) - CALL(sys_tgkill) /* 270 */ - CALL(sys_utimes) - CALL(sys_fadvise64_64) - CALL(sys_ni_syscall) /* sys_vserver */ - CALL(sys_ni_syscall) - CALL(sys_get_mempolicy) /* 275 */ - CALL(sys_set_mempolicy) - CALL(sys_mq_open) - CALL(sys_mq_unlink) - CALL(sys_mq_timedsend) - CALL(sys_mq_timedreceive) /* 280 */ - CALL(sys_mq_notify) - CALL(sys_mq_getsetattr) - CALL(sys_waitid) - CALL(sys_ni_syscall) /* sys_kexec_load */ - CALL(sys_add_key) /* 285 */ - CALL(sys_request_key) - CALL(sys_keyctl) - CALL(sys_ioprio_set) - CALL(sys_ioprio_get) /* 290 */ - CALL(sys_inotify_init) - CALL(sys_inotify_add_watch) - CALL(sys_inotify_rm_watch) - CALL(sys_migrate_pages) - CALL(sys_openat) /* 295 */ - CALL(sys_mkdirat) - CALL(sys_mknodat) - CALL(sys_fchownat) - CALL(sys_futimesat) - CALL(sys_fstatat64) /* 300 */ - CALL(sys_unlinkat) - CALL(sys_renameat) - CALL(sys_linkat) - CALL(sys_symlinkat) - CALL(sys_readlinkat) /* 305 */ - CALL(sys_fchmodat) - CALL(sys_faccessat) - CALL(sys_ni_syscall) /* sys_pselect6 */ - CALL(sys_ni_syscall) /* sys_ppoll */ - CALL(sys_unshare) /* 310 */ - CALL(sys_set_robust_list) - CALL(sys_get_robust_list) - CALL(sys_splice) - CALL(sys_sync_file_range) - CALL(sys_tee) /* 315 */ - CALL(sys_vmsplice) - CALL(sys_ni_syscall) /* sys_move_pages */ - CALL(sys_getcpu) - CALL(sys_ni_syscall) /* sys_epoll_pwait */ - CALL(sys_setns) /* 320 */ diff --git a/arch/h8300/kernel/time.c b/arch/h8300/kernel/time.c deleted file mode 100644 index e0f74191d553..000000000000 --- a/arch/h8300/kernel/time.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * linux/arch/h8300/kernel/time.c - * - * Yoshinori Sato <ysato@users.sourceforge.jp> - * - * Copied/hacked from: - * - * linux/arch/m68k/kernel/time.c - * - * Copyright (C) 1991, 1992, 1995 Linus Torvalds - * - * This file contains the m68k-specific time handling details. - * Most of the stuff is located in the machine specific files. - * - * 1997-09-10 Updated NTP code according to technical memorandum Jan '96 - * "A Kernel Model for Precision Timekeeping" by Dave Mills - */ - -#include <linux/errno.h> -#include <linux/module.h> -#include <linux/sched.h> -#include <linux/kernel.h> -#include <linux/param.h> -#include <linux/string.h> -#include <linux/mm.h> -#include <linux/timex.h> -#include <linux/profile.h> - -#include <asm/io.h> -#include <asm/irq_regs.h> -#include <asm/timer.h> - -#define TICK_SIZE (tick_nsec / 1000) - -void h8300_timer_tick(void) -{ - if (current->pid) - profile_tick(CPU_PROFILING); - xtime_update(1); - update_process_times(user_mode(get_irq_regs())); -} - -void read_persistent_clock(struct timespec *ts) -{ - unsigned int year, mon, day, hour, min, sec; - - /* FIX by dqg : Set to zero for platforms that don't have tod */ - /* without this time is undefined and can overflow time_t, causing */ - /* very strange errors */ - year = 1980; - mon = day = 1; - hour = min = sec = 0; -#ifdef CONFIG_H8300_GETTOD - h8300_gettod (&year, &mon, &day, &hour, &min, &sec); -#endif - if ((year += 1900) < 1970) - year += 100; - ts->tv_sec = mktime(year, mon, day, hour, min, sec); - ts->tv_nsec = 0; -} - -void __init time_init(void) -{ - - h8300_timer_setup(); -} diff --git a/arch/h8300/kernel/timer/Makefile b/arch/h8300/kernel/timer/Makefile deleted file mode 100644 index bef0510ea6ad..000000000000 --- a/arch/h8300/kernel/timer/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# h8300 internal timer handler - -obj-$(CONFIG_H8300_TIMER8) := timer8.o -obj-$(CONFIG_H8300_TIMER16) := timer16.o -obj-$(CONFIG_H8300_ITU) := itu.o -obj-$(CONFIG_H8300_TPU) := tpu.o diff --git a/arch/h8300/kernel/timer/itu.c b/arch/h8300/kernel/timer/itu.c deleted file mode 100644 index 0a8b5cd5bf38..000000000000 --- a/arch/h8300/kernel/timer/itu.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * linux/arch/h8300/kernel/timer/itu.c - * - * Yoshinori Sato <ysato@users.sourcefoge.jp> - * - * ITU Timer Handler - * - */ - -#include <linux/errno.h> -#include <linux/sched.h> -#include <linux/kernel.h> -#include <linux/param.h> -#include <linux/string.h> -#include <linux/mm.h> -#include <linux/interrupt.h> -#include <linux/init.h> -#include <linux/timex.h> - -#include <asm/segment.h> -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/regs306x.h> - -#if CONFIG_H8300_ITU_CH == 0 -#define ITUBASE 0xffff64 -#define ITUIRQ 24 -#elif CONFIG_H8300_ITU_CH == 1 -#define ITUBASE 0xffff6e -#define ITUIRQ 28 -#elif CONFIG_H8300_ITU_CH == 2 -#define ITUBASE 0xffff78 -#define ITUIRQ 32 -#elif CONFIG_H8300_ITU_CH == 3 -#define ITUBASE 0xffff82 -#define ITUIRQ 36 -#elif CONFIG_H8300_ITU_CH == 4 -#define ITUBASE 0xffff92 -#define ITUIRQ 40 -#else -#error Unknown timer channel. -#endif - -#define TCR 0 -#define TIOR 1 -#define TIER 2 -#define TSR 3 -#define TCNT 4 -#define GRA 6 -#define GRB 8 - -static irqreturn_t timer_interrupt(int irq, void *dev_id) -{ - h8300_timer_tick(); - ctrl_bclr(IMFA, ITUBASE + TSR); - return IRQ_HANDLED; -} - -static struct irqaction itu_irq = { - .name = "itu", - .handler = timer_interrupt, - .flags = IRQF_DISABLED | IRQF_TIMER, -}; - -static const int __initconst divide_rate[] = {1, 2, 4, 8}; - -void __init h8300_timer_setup(void) -{ - unsigned int div; - unsigned int cnt; - - calc_param(cnt, div, divide_rate, 0x10000); - - setup_irq(ITUIRQ, &itu_irq); - - /* initialize timer */ - ctrl_outb(0, TSTR); - ctrl_outb(CCLR0 | div, ITUBASE + TCR); - ctrl_outb(0x01, ITUBASE + TIER); - ctrl_outw(cnt, ITUBASE + GRA); - ctrl_bset(CONFIG_H8300_ITU_CH, TSTR); -} diff --git a/arch/h8300/kernel/timer/timer16.c b/arch/h8300/kernel/timer/timer16.c deleted file mode 100644 index 462d9f581719..000000000000 --- a/arch/h8300/kernel/timer/timer16.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * linux/arch/h8300/kernel/timer/timer16.c - * - * Yoshinori Sato <ysato@users.sourcefoge.jp> - * - * 16bit Timer Handler - * - */ - -#include <linux/errno.h> -#include <linux/sched.h> -#include <linux/kernel.h> -#include <linux/param.h> -#include <linux/string.h> -#include <linux/mm.h> -#include <linux/interrupt.h> -#include <linux/init.h> -#include <linux/timex.h> - -#include <asm/segment.h> -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/regs306x.h> - -/* 16bit timer */ -#if CONFIG_H8300_TIMER16_CH == 0 -#define _16BASE 0xffff78 -#define _16IRQ 24 -#elif CONFIG_H8300_TIMER16_CH == 1 -#define _16BASE 0xffff80 -#define _16IRQ 28 -#elif CONFIG_H8300_TIMER16_CH == 2 -#define _16BASE 0xffff88 -#define _16IRQ 32 -#else -#error Unknown timer channel. -#endif - -#define TCR 0 -#define TIOR 1 -#define TCNT 2 -#define GRA 4 -#define GRB 6 - -#define H8300_TIMER_FREQ CONFIG_CPU_CLOCK*10000 /* Timer input freq. */ - -static irqreturn_t timer_interrupt(int irq, void *dev_id) -{ - h8300_timer_tick(); - ctrl_bclr(CONFIG_H8300_TIMER16_CH, TISRA); - return IRQ_HANDLED; -} - -static struct irqaction timer16_irq = { - .name = "timer-16", - .handler = timer_interrupt, - .flags = IRQF_DISABLED | IRQF_TIMER, -}; - -static const int __initconst divide_rate[] = {1, 2, 4, 8}; - -void __init h8300_timer_setup(void) -{ - unsigned int div; - unsigned int cnt; - - calc_param(cnt, div, divide_rate, 0x10000); - - setup_irq(_16IRQ, &timer16_irq); - - /* initialize timer */ - ctrl_outb(0, TSTR); - ctrl_outb(CCLR0 | div, _16BASE + TCR); - ctrl_outw(cnt, _16BASE + GRA); - ctrl_bset(4 + CONFIG_H8300_TIMER16_CH, TISRA); - ctrl_bset(CONFIG_H8300_TIMER16_CH, TSTR); -} diff --git a/arch/h8300/kernel/timer/timer8.c b/arch/h8300/kernel/timer/timer8.c deleted file mode 100644 index 505f3415b40f..000000000000 --- a/arch/h8300/kernel/timer/timer8.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * linux/arch/h8300/kernel/cpu/timer/timer8.c - * - * Yoshinori Sato <ysato@users.sourcefoge.jp> - * - * 8bit Timer Handler - * - */ - -#include <linux/errno.h> -#include <linux/sched.h> -#include <linux/kernel.h> -#include <linux/param.h> -#include <linux/string.h> -#include <linux/mm.h> -#include <linux/interrupt.h> -#include <linux/init.h> -#include <linux/profile.h> - -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/timer.h> -#if defined(CONFIG_CPU_H8300H) -#include <asm/regs306x.h> -#endif -#if defined(CONFIG_CPU_H8S) -#include <asm/regs267x.h> -#endif - -/* 8bit timer x2 */ -#define CMFA 6 - -#if defined(CONFIG_H8300_TIMER8_CH0) -#define _8BASE _8TCR0 -#ifdef CONFIG_CPU_H8300H -#define _8IRQ 36 -#endif -#ifdef CONFIG_CPU_H8S -#define _8IRQ 72 -#endif -#elif defined(CONFIG_H8300_TIMER8_CH2) -#ifdef CONFIG_CPU_H8300H -#define _8BASE _8TCR2 -#define _8IRQ 40 -#endif -#endif - -#ifndef _8BASE -#error Unknown timer channel. -#endif - -#define _8TCR 0 -#define _8TCSR 2 -#define TCORA 4 -#define TCORB 6 -#define _8TCNT 8 - -#define CMIEA 0x40 -#define CCLR_CMA 0x08 -#define CKS2 0x04 - -/* - * timer_interrupt() needs to keep up the real-time clock, - * as well as call the "xtime_update()" routine every clocktick - */ - -static irqreturn_t timer_interrupt(int irq, void *dev_id) -{ - h8300_timer_tick(); - ctrl_bclr(CMFA, _8BASE + _8TCSR); - return IRQ_HANDLED; -} - -static struct irqaction timer8_irq = { - .name = "timer-8", - .handler = timer_interrupt, - .flags = IRQF_DISABLED | IRQF_TIMER, -}; - -static const int __initconst divide_rate[] = {8, 64, 8192}; - -void __init h8300_timer_setup(void) -{ - unsigned int div; - unsigned int cnt; - - calc_param(cnt, div, divide_rate, 0x10000); - div++; - - setup_irq(_8IRQ, &timer8_irq); - -#if defined(CONFIG_CPU_H8S) - /* Timer module enable */ - ctrl_bclr(0, MSTPCRL) -#endif - - /* initialize timer */ - ctrl_outw(cnt, _8BASE + TCORA); - ctrl_outw(0x0000, _8BASE + _8TCSR); - ctrl_outw((CMIEA|CCLR_CMA|CKS2) << 8 | div, - _8BASE + _8TCR); -} diff --git a/arch/h8300/kernel/timer/tpu.c b/arch/h8300/kernel/timer/tpu.c deleted file mode 100644 index 0350f6204ecf..000000000000 --- a/arch/h8300/kernel/timer/tpu.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * linux/arch/h8300/kernel/timer/tpu.c - * - * Yoshinori Sato <ysato@users.sourceforge.jp> - * - * TPU Timer Handler - * - */ - -#include <linux/errno.h> -#include <linux/sched.h> -#include <linux/kernel.h> -#include <linux/param.h> -#include <linux/string.h> -#include <linux/mm.h> -#include <linux/interrupt.h> -#include <linux/init.h> -#include <linux/timex.h> - -#include <asm/segment.h> -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/regs267x.h> - -/* TPU */ -#if CONFIG_H8300_TPU_CH == 0 -#define TPUBASE 0xffffd0 -#define TPUIRQ 40 -#elif CONFIG_H8300_TPU_CH == 1 -#define TPUBASE 0xffffe0 -#define TPUIRQ 48 -#elif CONFIG_H8300_TPU_CH == 2 -#define TPUBASE 0xfffff0 -#define TPUIRQ 52 -#elif CONFIG_H8300_TPU_CH == 3 -#define TPUBASE 0xfffe80 -#define TPUIRQ 56 -#elif CONFIG_H8300_TPU_CH == 4 -#define TPUBASE 0xfffe90 -#define TPUIRQ 64 -#else -#error Unknown timer channel. -#endif - -#define _TCR 0 -#define _TMDR 1 -#define _TIOR 2 -#define _TIER 4 -#define _TSR 5 -#define _TCNT 6 -#define _GRA 8 -#define _GRB 10 - -#define CCLR0 0x20 - -static irqreturn_t timer_interrupt(int irq, void *dev_id) -{ - h8300_timer_tick(); - ctrl_bclr(0, TPUBASE + _TSR); - return IRQ_HANDLED; -} - -static struct irqaction tpu_irq = { - .name = "tpu", - .handler = timer_interrupt, - .flags = IRQF_DISABLED | IRQF_TIMER, -}; - -static const int __initconst divide_rate[] = { -#if CONFIG_H8300_TPU_CH == 0 - 1,4,16,64,0,0,0,0, -#elif (CONFIG_H8300_TPU_CH == 1) || (CONFIG_H8300_TPU_CH == 5) - 1,4,16,64,0,0,256,0, -#elif (CONFIG_H8300_TPU_CH == 2) || (CONFIG_H8300_TPU_CH == 4) - 1,4,16,64,0,0,0,1024, -#elif CONFIG_H8300_TPU_CH == 3 - 1,4,16,64,0,1024,256,4096, -#endif -}; - -void __init h8300_timer_setup(void) -{ - unsigned int cnt; - unsigned int div; - - calc_param(cnt, div, divide_rate, 0x10000); - - setup_irq(TPUIRQ, &tpu_irq); - - /* TPU module enabled */ - ctrl_bclr(3, MSTPCRH); - - ctrl_outb(0, TSTR); - ctrl_outb(CCLR0 | div, TPUBASE + _TCR); - ctrl_outb(0, TPUBASE + _TMDR); - ctrl_outw(0, TPUBASE + _TIOR); - ctrl_outb(0x01, TPUBASE + _TIER); - ctrl_outw(cnt, TPUBASE + _GRA); - ctrl_bset(CONFIG_H8300_TPU_CH, TSTR); -} diff --git a/arch/h8300/kernel/traps.c b/arch/h8300/kernel/traps.c deleted file mode 100644 index cfe494dbe3da..000000000000 --- a/arch/h8300/kernel/traps.c +++ /dev/null @@ -1,166 +0,0 @@ -/* - * linux/arch/h8300/boot/traps.c -- general exception handling code - * H8/300 support Yoshinori Sato <ysato@users.sourceforge.jp> - * - * Cloned from Linux/m68k. - * - * No original Copyright holder listed, - * Probable original (C) Roman Zippel (assigned DJD, 1999) - * - * Copyright 1999-2000 D. Jeff Dionne, <jeff@rt-control.com> - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - */ - -#include <linux/types.h> -#include <linux/sched.h> -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/bug.h> - -#include <asm/irq.h> -#include <asm/traps.h> -#include <asm/page.h> - -static DEFINE_SPINLOCK(die_lock); - -/* - * this must be called very early as the kernel might - * use some instruction that are emulated on the 060 - */ - -void __init base_trap_init(void) -{ -} - -void __init trap_init (void) -{ -} - -asmlinkage void set_esp0 (unsigned long ssp) -{ - current->thread.esp0 = ssp; -} - -/* - * Generic dumping code. Used for panic and debug. - */ - -static void dump(struct pt_regs *fp) -{ - unsigned long *sp; - unsigned char *tp; - int i; - - printk("\nCURRENT PROCESS:\n\n"); - printk("COMM=%s PID=%d\n", current->comm, current->pid); - if (current->mm) { - printk("TEXT=%08x-%08x DATA=%08x-%08x BSS=%08x-%08x\n", - (int) current->mm->start_code, - (int) current->mm->end_code, - (int) current->mm->start_data, - (int) current->mm->end_data, - (int) current->mm->end_data, - (int) current->mm->brk); - printk("USER-STACK=%08x KERNEL-STACK=%08lx\n\n", - (int) current->mm->start_stack, - (int) PAGE_SIZE+(unsigned long)current); - } - - show_regs(fp); - printk("\nCODE:"); - tp = ((unsigned char *) fp->pc) - 0x20; - for (sp = (unsigned long *) tp, i = 0; (i < 0x40); i += 4) { - if ((i % 0x10) == 0) - printk("\n%08x: ", (int) (tp + i)); - printk("%08x ", (int) *sp++); - } - printk("\n"); - - printk("\nKERNEL STACK:"); - tp = ((unsigned char *) fp) - 0x40; - for (sp = (unsigned long *) tp, i = 0; (i < 0xc0); i += 4) { - if ((i % 0x10) == 0) - printk("\n%08x: ", (int) (tp + i)); - printk("%08x ", (int) *sp++); - } - printk("\n"); - if (STACK_MAGIC != *(unsigned long *)((unsigned long)current+PAGE_SIZE)) - printk("(Possibly corrupted stack page??)\n"); - - printk("\n\n"); -} - -void die(const char *str, struct pt_regs *fp, unsigned long err) -{ - static int diecount; - - oops_enter(); - - console_verbose(); - spin_lock_irq(&die_lock); - report_bug(fp->pc, fp); - printk(KERN_EMERG "%s: %04lx [#%d] ", str, err & 0xffff, ++diecount); - dump(fp); - - spin_unlock_irq(&die_lock); - do_exit(SIGSEGV); -} - -extern char _start, _etext; -#define check_kernel_text(addr) \ - ((addr >= (unsigned long)(&_start)) && \ - (addr < (unsigned long)(&_etext))) - -static int kstack_depth_to_print = 24; - -void show_stack(struct task_struct *task, unsigned long *esp) -{ - unsigned long *stack, addr; - int i; - - if (esp == NULL) - esp = (unsigned long *) &esp; - - stack = esp; - - printk("Stack from %08lx:", (unsigned long)stack); - for (i = 0; i < kstack_depth_to_print; i++) { - if (((unsigned long)stack & (THREAD_SIZE - 1)) == 0) - break; - if (i % 8 == 0) - printk("\n "); - printk(" %08lx", *stack++); - } - - printk("\nCall Trace:"); - i = 0; - stack = esp; - while (((unsigned long)stack & (THREAD_SIZE - 1)) != 0) { - addr = *stack++; - /* - * If the address is either in the text segment of the - * kernel, or in the region which contains vmalloc'ed - * memory, it *may* be the address of a calling - * routine; if so, print it so that someone tracing - * down the cause of the crash will be able to figure - * out the call path that was taken. - */ - if (check_kernel_text(addr)) { - if (i % 4 == 0) - printk("\n "); - printk(" [<%08lx>]", addr); - i++; - } - } - printk("\n"); -} - -void show_trace_task(struct task_struct *tsk) -{ - show_stack(tsk,(unsigned long *)tsk->thread.esp0); -} diff --git a/arch/h8300/kernel/vmlinux.lds.S b/arch/h8300/kernel/vmlinux.lds.S deleted file mode 100644 index 3253fed42ac1..000000000000 --- a/arch/h8300/kernel/vmlinux.lds.S +++ /dev/null @@ -1,157 +0,0 @@ -#include <asm-generic/vmlinux.lds.h> -#include <asm/page.h> - -/* target memory map */ -#ifdef CONFIG_H8300H_GENERIC -#define ROMTOP 0x000000 -#define ROMSIZE 0x400000 -#define RAMTOP 0x400000 -#define RAMSIZE 0x400000 -#endif - -#ifdef CONFIG_H8300H_AKI3068NET -#define ROMTOP 0x000000 -#define ROMSIZE 0x080000 -#define RAMTOP 0x400000 -#define RAMSIZE 0x200000 -#endif - -#ifdef CONFIG_H8300H_H8MAX -#define ROMTOP 0x000000 -#define ROMSIZE 0x080000 -#define RAMTOP 0x400000 -#define RAMSIZE 0x200000 -#endif - -#ifdef CONFIG_H8300H_SIM -#define ROMTOP 0x000000 -#define ROMSIZE 0x400000 -#define RAMTOP 0x400000 -#define RAMSIZE 0x400000 -#endif - -#ifdef CONFIG_H8S_SIM -#define ROMTOP 0x000000 -#define ROMSIZE 0x400000 -#define RAMTOP 0x400000 -#define RAMSIZE 0x800000 -#endif - -#ifdef CONFIG_H8S_EDOSK2674 -#define ROMTOP 0x000000 -#define ROMSIZE 0x400000 -#define RAMTOP 0x400000 -#define RAMSIZE 0x800000 -#endif - -#if defined(CONFIG_H8300H_SIM) || defined(CONFIG_H8S_SIM) -INPUT(romfs.o) -#endif - -_jiffies = _jiffies_64 + 4; - -ENTRY(__start) - -SECTIONS -{ -#if defined(CONFIG_ROMKERNEL) - . = ROMTOP; - .vectors : - { - __vector = . ; - *(.vectors*) - } -#else - . = RAMTOP; - .bootvec : - { - *(.bootvec) - } -#endif - .text : - { - _text = .; -#if defined(CONFIG_ROMKERNEL) - *(.int_redirect) -#endif - __stext = . ; - TEXT_TEXT - SCHED_TEXT - LOCK_TEXT - __etext = . ; - } - EXCEPTION_TABLE(16) - - RODATA -#if defined(CONFIG_ROMKERNEL) - SECURITY_INIT -#endif - ROEND = .; -#if defined(CONFIG_ROMKERNEL) - . = RAMTOP; - .data : AT(ROEND) -#else - .data : -#endif - { - __sdata = . ; - ___data_start = . ; - - INIT_TASK_DATA(0x2000) - . = ALIGN(0x4) ; - DATA_DATA - . = ALIGN(0x4) ; - *(.data.*) - - . = ALIGN(0x4) ; - ___init_begin = .; - __sinittext = .; - INIT_TEXT - __einittext = .; - INIT_DATA - . = ALIGN(0x4) ; - INIT_SETUP(0x4) - ___setup_start = .; - *(.init.setup) - . = ALIGN(0x4) ; - ___setup_end = .; - INIT_CALLS - CON_INITCALL - EXIT_TEXT - EXIT_DATA - INIT_RAM_FS - . = ALIGN(0x4) ; - ___init_end = .; - __edata = . ; - } -#if defined(CONFIG_RAMKERNEL) - SECURITY_INIT -#endif - __begin_data = LOADADDR(.data); - .bss : - { - . = ALIGN(0x4) ; - __sbss = . ; - ___bss_start = . ; - *(.bss*) - . = ALIGN(0x4) ; - *(COMMON) - . = ALIGN(0x4) ; - ___bss_stop = . ; - __ebss = . ; - __end = . ; - __ramstart = .; - } - .romfs : - { - *(.romfs*) - } - . = RAMTOP+RAMSIZE; - .dummy : - { - COMMAND_START = . - 0x200 ; - __ramend = . ; - } - - DISCARDS -} diff --git a/arch/h8300/lib/Makefile b/arch/h8300/lib/Makefile deleted file mode 100644 index 1577f5075b10..000000000000 --- a/arch/h8300/lib/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# -# Makefile for H8/300-specific library files.. -# - -lib-y = ashrdi3.o checksum.o memcpy.o memset.o abs.o romfs.o diff --git a/arch/h8300/lib/abs.S b/arch/h8300/lib/abs.S deleted file mode 100644 index ddd1fb3d01ad..000000000000 --- a/arch/h8300/lib/abs.S +++ /dev/null @@ -1,21 +0,0 @@ -;;; abs.S - -#include <asm/linkage.h> - -#if defined(__H8300H__) - .h8300h -#endif -#if defined(__H8300S__) - .h8300s -#endif - .text -.global _abs - -;;; int abs(int n) -_abs: - mov.l er0,er0 - bpl 1f - neg.l er0 -1: - rts - diff --git a/arch/h8300/lib/ashrdi3.c b/arch/h8300/lib/ashrdi3.c deleted file mode 100644 index 78efb65e315a..000000000000 --- a/arch/h8300/lib/ashrdi3.c +++ /dev/null @@ -1,63 +0,0 @@ -/* ashrdi3.c extracted from gcc-2.7.2/libgcc2.c which is: */ -/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that 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 GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#define BITS_PER_UNIT 8 - -typedef int SItype __attribute__ ((mode (SI))); -typedef unsigned int USItype __attribute__ ((mode (SI))); -typedef int DItype __attribute__ ((mode (DI))); -typedef int word_type __attribute__ ((mode (__word__))); - -struct DIstruct {SItype high, low;}; - -typedef union -{ - struct DIstruct s; - DItype ll; -} DIunion; - -DItype -__ashrdi3 (DItype u, word_type b) -{ - DIunion w; - word_type bm; - DIunion uu; - - if (b == 0) - return u; - - uu.ll = u; - - bm = (sizeof (SItype) * BITS_PER_UNIT) - b; - if (bm <= 0) - { - /* w.s.high = 1..1 or 0..0 */ - w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1); - w.s.low = uu.s.high >> -bm; - } - else - { - USItype carries = (USItype)uu.s.high << bm; - w.s.high = uu.s.high >> b; - w.s.low = ((USItype)uu.s.low >> b) | carries; - } - - return w.ll; -} diff --git a/arch/h8300/lib/checksum.c b/arch/h8300/lib/checksum.c deleted file mode 100644 index bdc5b032acd6..000000000000 --- a/arch/h8300/lib/checksum.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * INET An implementation of the TCP/IP protocol suite for the LINUX - * operating system. INET is implemented using the BSD Socket - * interface as the means of communication with the user level. - * - * IP/TCP/UDP checksumming routines - * - * Authors: Jorge Cwik, <jorge@laser.satlink.net> - * Arnt Gulbrandsen, <agulbra@nvg.unit.no> - * Tom May, <ftom@netcom.com> - * Andreas Schwab, <schwab@issan.informatik.uni-dortmund.de> - * Lots of code moved from tcp.c and ip.c; see those files - * for more names. - * - * 03/02/96 Jes Sorensen, Andreas Schwab, Roman Hodek: - * Fixed some nasty bugs, causing some horrible crashes. - * A: At some points, the sum (%0) was used as - * length-counter instead of the length counter - * (%1). Thanks to Roman Hodek for pointing this out. - * B: GCC seems to mess up if one uses too many - * data-registers to hold input values and one tries to - * specify d0 and d1 as scratch registers. Letting gcc choose these - * registers itself solves the problem. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -/* Revised by Kenneth Albanowski for m68knommu. Basic problem: unaligned access kills, so most - of the assembly has to go. */ - -#include <net/checksum.h> -#include <linux/module.h> - -static inline unsigned short from32to16(unsigned long x) -{ - /* add up 16-bit and 16-bit for 16+c bit */ - x = (x & 0xffff) + (x >> 16); - /* add up carry.. */ - x = (x & 0xffff) + (x >> 16); - return x; -} - -static unsigned long do_csum(const unsigned char * buff, int len) -{ - int odd, count; - unsigned long result = 0; - - if (len <= 0) - goto out; - odd = 1 & (unsigned long) buff; - if (odd) { - result = *buff; - len--; - buff++; - } - count = len >> 1; /* nr of 16-bit words.. */ - if (count) { - if (2 & (unsigned long) buff) { - result += *(unsigned short *) buff; - count--; - len -= 2; - buff += 2; - } - count >>= 1; /* nr of 32-bit words.. */ - if (count) { - unsigned long carry = 0; - do { - unsigned long w = *(unsigned long *) buff; - count--; - buff += 4; - result += carry; - result += w; - carry = (w > result); - } while (count); - result += carry; - result = (result & 0xffff) + (result >> 16); - } - if (len & 2) { - result += *(unsigned short *) buff; - buff += 2; - } - } - if (len & 1) - result += (*buff << 8); - result = from32to16(result); - if (odd) - result = ((result >> 8) & 0xff) | ((result & 0xff) << 8); -out: - return result; -} - -/* - * This is a version of ip_compute_csum() optimized for IP headers, - * which always checksum on 4 octet boundaries. - */ -__sum16 ip_fast_csum(const void *iph, unsigned int ihl) -{ - return (__force __sum16)~do_csum(iph,ihl*4); -} - -/* - * computes the checksum of a memory block at buff, length len, - * and adds in "sum" (32-bit) - * - * returns a 32-bit number suitable for feeding into itself - * or csum_tcpudp_magic - * - * this function must be called with even lengths, except - * for the last fragment, which may be odd - * - * it's best to have buff aligned on a 32-bit boundary - */ -/* - * Egads... That thing apparently assumes that *all* checksums it ever sees will - * be folded. Very likely a bug. - */ -__wsum csum_partial(const void *buff, int len, __wsum sum) -{ - unsigned int result = do_csum(buff, len); - - /* add in old sum, and carry.. */ - result += (__force u32)sum; - /* 16+c bits -> 16 bits */ - result = (result & 0xffff) + (result >> 16); - return (__force __wsum)result; -} - -EXPORT_SYMBOL(csum_partial); - -/* - * this routine is used for miscellaneous IP-like checksums, mainly - * in icmp.c - */ -__sum16 ip_compute_csum(const void *buff, int len) -{ - return (__force __sum16)~do_csum(buff,len); -} - -/* - * copy from fs while checksumming, otherwise like csum_partial - */ - -__wsum -csum_partial_copy_from_user(const void __user *src, void *dst, int len, - __wsum sum, int *csum_err) -{ - if (csum_err) *csum_err = 0; - memcpy(dst, (__force const void *)src, len); - return csum_partial(dst, len, sum); -} - -/* - * copy from ds while checksumming, otherwise like csum_partial - */ - -__wsum -csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum) -{ - memcpy(dst, src, len); - return csum_partial(dst, len, sum); -} diff --git a/arch/h8300/lib/memcpy.S b/arch/h8300/lib/memcpy.S deleted file mode 100644 index cad325e2c0e8..000000000000 --- a/arch/h8300/lib/memcpy.S +++ /dev/null @@ -1,84 +0,0 @@ -;;; memcpy.S - -#include <asm/linkage.h> - -#if defined(__H8300H__) - .h8300h -#endif -#if defined(__H8300S__) - .h8300s -#endif - - .text -.global _memcpy - -;;; void *memcpy(void *to, void *from, size_t n) -_memcpy: - mov.l er2,er2 - bne 1f - rts -1: - ;; address check - bld #0,r0l - bxor #0,r1l - bcs 4f - mov.l er4,@-sp - mov.l er0,@-sp - btst #0,r0l - beq 1f - ;; (aligned even) odd address - mov.b @er1,r3l - mov.b r3l,@er0 - adds #1,er1 - adds #1,er0 - dec.l #1,er2 - beq 3f -1: - ;; n < sizeof(unsigned long) check - sub.l er4,er4 - adds #4,er4 ; loop count check value - cmp.l er4,er2 - blo 2f - ;; unsigned long copy -1: - mov.l @er1,er3 - mov.l er3,@er0 - adds #4,er0 - adds #4,er1 - subs #4,er2 - cmp.l er4,er2 - bcc 1b - ;; rest -2: - mov.l er2,er2 - beq 3f -1: - mov.b @er1,r3l - mov.b r3l,@er0 - adds #1,er1 - adds #1,er0 - dec.l #1,er2 - bne 1b -3: - mov.l @sp+,er0 - mov.l @sp+,er4 - rts - - ;; odd <- even / even <- odd -4: - mov.l er4,er3 - mov.l er2,er4 - mov.l er5,er2 - mov.l er1,er5 - mov.l er6,er1 - mov.l er0,er6 -1: - eepmov.w - mov.w r4,r4 - bne 1b - dec.w #1,e4 - bpl 1b - mov.l er1,er6 - mov.l er2,er5 - mov.l er3,er4 - rts diff --git a/arch/h8300/lib/memset.S b/arch/h8300/lib/memset.S deleted file mode 100644 index 4549a64c5b79..000000000000 --- a/arch/h8300/lib/memset.S +++ /dev/null @@ -1,61 +0,0 @@ -/* memset.S */ - -#include <asm/linkage.h> - -#if defined(__H8300H__) - .h8300h -#endif -#if defined(__H8300S__) - .h8300s -#endif - .text - -.global _memset - -;;void *memset(*ptr, int c, size_t count) -;; ptr = er0 -;; c = er1(r1l) -;; count = er2 -_memset: - btst #0,r0l - beq 2f - - ;; odd address -1: - mov.b r1l,@er0 - adds #1,er0 - dec.l #1,er2 - beq 6f - - ;; even address -2: - mov.l er2,er3 - cmp.l #4,er2 - blo 4f - ;; count>=4 -> count/4 -#if defined(__H8300H__) - shlr.l er2 - shlr.l er2 -#endif -#if defined(__H8300S__) - shlr.l #2,er2 -#endif - ;; byte -> long - mov.b r1l,r1h - mov.w r1,e1 -3: - mov.l er1,@er0 - adds #4,er0 - dec.l #1,er2 - bne 3b -4: - ;; count % 4 - and.b #3,r3l - beq 6f -5: - mov.b r1l,@er0 - adds #1,er0 - dec.b r3l - bne 5b -6: - rts diff --git a/arch/h8300/lib/romfs.S b/arch/h8300/lib/romfs.S deleted file mode 100644 index 68910d8e1ff4..000000000000 --- a/arch/h8300/lib/romfs.S +++ /dev/null @@ -1,57 +0,0 @@ -/* romfs move to __ebss */ - -#include <asm/linkage.h> - -#if defined(__H8300H__) - .h8300h -#endif -#if defined(__H8300S__) - .h8300s -#endif - -#define BLKOFFSET 512 - - .text -.globl __move_romfs -_romfs_sig_len = 8 - -__move_romfs: - mov.l #__sbss,er0 - mov.l #_romfs_sig,er1 - mov.b #_romfs_sig_len,r3l -1: /* check romfs image */ - mov.b @er0+,r2l - mov.b @er1+,r2h - cmp.b r2l,r2h - bne 2f - dec.b r3l - bne 1b - - /* find romfs image */ - mov.l @__sbss+8,er0 /* romfs length(be) */ - mov.l #__sbss,er1 - add.l er0,er1 /* romfs image end */ - mov.l #__ebss,er2 - add.l er0,er2 /* distination address */ -#if defined(CONFIG_INTELFLASH) - add.l #BLKOFFSET,er2 -#endif - adds #2,er0 - adds #1,er0 - shlr er0 - shlr er0 /* transfer length */ -1: - mov.l @er1,er3 /* copy image */ - mov.l er3,@er2 - subs #4,er1 - subs #4,er2 - dec.l #1,er0 - bpl 1b -2: - rts - - .section .rodata -_romfs_sig: - .ascii "-rom1fs-" - - .end diff --git a/arch/h8300/mm/Makefile b/arch/h8300/mm/Makefile deleted file mode 100644 index 5f4bc42b6453..000000000000 --- a/arch/h8300/mm/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# -# Makefile for the linux m68k-specific parts of the memory manager. -# - -obj-y := init.o fault.o memory.o kmap.o diff --git a/arch/h8300/mm/fault.c b/arch/h8300/mm/fault.c deleted file mode 100644 index 472535977006..000000000000 --- a/arch/h8300/mm/fault.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * linux/arch/h8300/mm/fault.c - * - * Copyright (C) 1998 D. Jeff Dionne <jeff@lineo.ca>, - * Copyright (C) 2000 Lineo, Inc. (www.lineo.com) - * - * Based on: - * - * linux/arch/m68knommu/mm/fault.c - * linux/arch/m68k/mm/fault.c - * - * Copyright (C) 1995 Hamish Macdonald - */ - -#include <linux/mman.h> -#include <linux/mm.h> -#include <linux/kernel.h> -#include <linux/ptrace.h> - -#include <asm/pgtable.h> - -/* - * This routine handles page faults. It determines the problem, and - * then passes it off to one of the appropriate routines. - * - * error_code: - * bit 0 == 0 means no page found, 1 means protection fault - * bit 1 == 0 means read, 1 means write - * - * If this routine detects a bad access, it returns 1, otherwise it - * returns 0. - */ -asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address, - unsigned long error_code) -{ -#ifdef DEBUG - printk ("regs->sr=%#x, regs->pc=%#lx, address=%#lx, %ld\n", - regs->sr, regs->pc, address, error_code); -#endif - -/* - * Oops. The kernel tried to access some bad page. We'll have to - * terminate things with extreme prejudice. - */ - if ((unsigned long) address < PAGE_SIZE) { - printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference"); - } else - printk(KERN_ALERT "Unable to handle kernel access"); - printk(" at virtual address %08lx\n",address); - if (!user_mode(regs)) - die("Oops", regs, error_code); - do_exit(SIGKILL); - - return 1; -} - diff --git a/arch/h8300/mm/init.c b/arch/h8300/mm/init.c deleted file mode 100644 index 6c1251e491af..000000000000 --- a/arch/h8300/mm/init.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - * linux/arch/h8300/mm/init.c - * - * Copyright (C) 1998 D. Jeff Dionne <jeff@lineo.ca>, - * Kenneth Albanowski <kjahds@kjahds.com>, - * Copyright (C) 2000 Lineo, Inc. (www.lineo.com) - * - * Based on: - * - * linux/arch/m68knommu/mm/init.c - * linux/arch/m68k/mm/init.c - * - * Copyright (C) 1995 Hamish Macdonald - * - * JAN/1999 -- hacked to support ColdFire (gerg@snapgear.com) - * DEC/2000 -- linux 2.4 support <davidm@snapgear.com> - */ - -#include <linux/signal.h> -#include <linux/sched.h> -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/string.h> -#include <linux/types.h> -#include <linux/ptrace.h> -#include <linux/mman.h> -#include <linux/mm.h> -#include <linux/swap.h> -#include <linux/init.h> -#include <linux/highmem.h> -#include <linux/pagemap.h> -#include <linux/bootmem.h> -#include <linux/gfp.h> - -#include <asm/setup.h> -#include <asm/segment.h> -#include <asm/page.h> -#include <asm/pgtable.h> -#include <asm/sections.h> - -#undef DEBUG - -/* - * BAD_PAGE is the page that is used for page faults when linux - * is out-of-memory. Older versions of linux just did a - * do_exit(), but using this instead means there is less risk - * for a process dying in kernel mode, possibly leaving a inode - * unused etc.. - * - * BAD_PAGETABLE is the accompanying page-table: it is initialized - * to point to BAD_PAGE entries. - * - * ZERO_PAGE is a special page that is used for zero-initialized - * data and COW. - */ -static unsigned long empty_bad_page_table; - -static unsigned long empty_bad_page; - -unsigned long empty_zero_page; - -extern unsigned long rom_length; - -extern unsigned long memory_start; -extern unsigned long memory_end; - -/* - * paging_init() continues the virtual memory environment setup which - * was begun by the code in arch/head.S. - * The parameters are pointers to where to stick the starting and ending - * addresses of available kernel virtual memory. - */ -void __init paging_init(void) -{ - /* - * Make sure start_mem is page aligned, otherwise bootmem and - * page_alloc get different views og the world. - */ -#ifdef DEBUG - unsigned long start_mem = PAGE_ALIGN(memory_start); -#endif - unsigned long end_mem = memory_end & PAGE_MASK; - -#ifdef DEBUG - printk ("start_mem is %#lx\nvirtual_end is %#lx\n", - start_mem, end_mem); -#endif - - /* - * Initialize the bad page table and bad page to point - * to a couple of allocated pages. - */ - empty_bad_page_table = (unsigned long)alloc_bootmem_pages(PAGE_SIZE); - empty_bad_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE); - empty_zero_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE); - memset((void *)empty_zero_page, 0, PAGE_SIZE); - - /* - * Set up SFC/DFC registers (user data space). - */ - set_fs (USER_DS); - -#ifdef DEBUG - printk ("before free_area_init\n"); - - printk ("free_area_init -> start_mem is %#lx\nvirtual_end is %#lx\n", - start_mem, end_mem); -#endif - - { - unsigned long zones_size[MAX_NR_ZONES] = {0, }; - - zones_size[ZONE_DMA] = 0 >> PAGE_SHIFT; - zones_size[ZONE_NORMAL] = (end_mem - PAGE_OFFSET) >> PAGE_SHIFT; -#ifdef CONFIG_HIGHMEM - zones_size[ZONE_HIGHMEM] = 0; -#endif - free_area_init(zones_size); - } -} - -void __init mem_init(void) -{ - unsigned long codesize = _etext - _stext; - - pr_devel("Mem_init: start=%lx, end=%lx\n", memory_start, memory_end); - - high_memory = (void *) (memory_end & PAGE_MASK); - max_mapnr = MAP_NR(high_memory); - - /* this will put all low memory onto the freelists */ - free_all_bootmem(); - - mem_init_print_info(NULL); - if (rom_length > 0 && rom_length > codesize) - pr_info("Memory available: %luK/%luK ROM\n", - (rom_length - codesize) >> 10, rom_length >> 10); -} - - -#ifdef CONFIG_BLK_DEV_INITRD -void free_initrd_mem(unsigned long start, unsigned long end) -{ - free_reserved_area((void *)start, (void *)end, -1, "initrd"); -} -#endif - -void -free_initmem(void) -{ -#ifdef CONFIG_RAMKERNEL - free_initmem_default(-1); -#endif -} - diff --git a/arch/h8300/mm/kmap.c b/arch/h8300/mm/kmap.c deleted file mode 100644 index f79edcdadf39..000000000000 --- a/arch/h8300/mm/kmap.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * linux/arch/h8300/mm/kmap.c - * - * Based on - * linux/arch/m68knommu/mm/kmap.c - * - * Copyright (C) 2000 Lineo, <davidm@snapgear.com> - * Copyright (C) 2000-2002 David McCullough <davidm@snapgear.com> - */ - -#include <linux/mm.h> -#include <linux/kernel.h> -#include <linux/string.h> -#include <linux/types.h> -#include <linux/vmalloc.h> - -#include <asm/setup.h> -#include <asm/segment.h> -#include <asm/page.h> -#include <asm/pgalloc.h> -#include <asm/io.h> - -#undef DEBUG - -#define VIRT_OFFSET (0x01000000) - -/* - * Map some physical address range into the kernel address space. - */ -void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag) -{ - return (void *)(physaddr + VIRT_OFFSET); -} - -/* - * Unmap a ioremap()ed region again. - */ -void iounmap(void *addr) -{ -} - -/* - * __iounmap unmaps nearly everything, so be careful - * it doesn't free currently pointer/page tables anymore but it - * wans't used anyway and might be added later. - */ -void __iounmap(void *addr, unsigned long size) -{ -} - -/* - * Set new cache mode for some kernel address space. - * The caller must push data for that range itself, if such data may already - * be in the cache. - */ -void kernel_set_cachemode(void *addr, unsigned long size, int cmode) -{ -} diff --git a/arch/h8300/mm/memory.c b/arch/h8300/mm/memory.c deleted file mode 100644 index 06e364641392..000000000000 --- a/arch/h8300/mm/memory.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * linux/arch/h8300/mm/memory.c - * - * Copyright (C) 2002 Yoshinori Sato <ysato@users.sourceforge.jp>, - * - * Based on: - * - * linux/arch/m68knommu/mm/memory.c - * - * Copyright (C) 1998 Kenneth Albanowski <kjahds@kjahds.com>, - * Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com) - * - * Based on: - * - * linux/arch/m68k/mm/memory.c - * - * Copyright (C) 1995 Hamish Macdonald - */ - -#include <linux/mm.h> -#include <linux/kernel.h> -#include <linux/string.h> -#include <linux/types.h> - -#include <asm/setup.h> -#include <asm/segment.h> -#include <asm/page.h> -#include <asm/pgtable.h> -#include <asm/traps.h> -#include <asm/io.h> - -void cache_clear (unsigned long paddr, int len) -{ -} - - -void cache_push (unsigned long paddr, int len) -{ -} - -void cache_push_v (unsigned long vaddr, int len) -{ -} - -/* - * Map some physical address range into the kernel address space. - */ - -unsigned long kernel_map(unsigned long paddr, unsigned long size, - int nocacheflag, unsigned long *memavailp ) -{ - return paddr; -} - diff --git a/arch/h8300/platform/h8300h/Makefile b/arch/h8300/platform/h8300h/Makefile deleted file mode 100644 index 420f73b0d962..000000000000 --- a/arch/h8300/platform/h8300h/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# -# Makefile for the linux kernel. -# -# Reuse any files we can from the H8/300H -# - -obj-y := irq.o ptrace_h8300h.o diff --git a/arch/h8300/platform/h8300h/aki3068net/Makefile b/arch/h8300/platform/h8300h/aki3068net/Makefile deleted file mode 100644 index b7ff78050b7f..000000000000 --- a/arch/h8300/platform/h8300h/aki3068net/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# -# Makefile for the linux kernel. -# - -extra-y := crt0_ram.o diff --git a/arch/h8300/platform/h8300h/aki3068net/crt0_ram.S b/arch/h8300/platform/h8300h/aki3068net/crt0_ram.S deleted file mode 100644 index b2ad0f2d0417..000000000000 --- a/arch/h8300/platform/h8300h/aki3068net/crt0_ram.S +++ /dev/null @@ -1,110 +0,0 @@ -/* - * linux/arch/h8300/platform/h8300h/aki3068net/crt0_ram.S - * - * Yoshinori Sato <ysato@users.sourceforge.jp> - * - * Platform depend startup - * Target Archtecture: AE-3068 (aka. aki3068net) - * Memory Layout : RAM - */ - -#define ASSEMBLY - -#include <asm/linkage.h> - -#if !defined(CONFIG_BLKDEV_RESERVE) -#if defined(CONFIG_GDB_DEBUG) -#define RAMEND (__ramend - 0xc000) -#else -#define RAMEND __ramend -#endif -#else -#define RAMEND CONFIG_BLKDEV_RESERVE_ADDRESS -#endif - - .global __start - .global _command_line - .global __platform_gpio_table - .global __target_name - - .h8300h - - .section .text - .file "crt0_ram.S" - - /* CPU Reset entry */ -__start: - mov.l #RAMEND,sp - ldc #0x80,ccr - - /* Peripheral Setup */ - -#if defined(CONFIG_MTD_UCLINUX) - /* move romfs image */ - jsr @__move_romfs -#endif - - /* .bss clear */ - mov.l #__sbss,er5 - mov.l #__ebss,er4 - sub.l er5,er4 - shlr er4 - shlr er4 - sub.l er0,er0 -1: - mov.l er0,@er5 - adds #4,er5 - dec.l #1,er4 - bne 1b - - /* copy kernel commandline */ - mov.l #COMMAND_START,er5 - mov.l #_command_line,er6 - mov.w #512,r4 - eepmov.w - - /* uClinux kernel start */ - ldc #0x90,ccr /* running kernel */ - mov.l #_init_thread_union,sp - add.l #0x2000,sp - jsr @_start_kernel -_exit: - - jmp _exit - - rts - - /* I/O port assign information */ -__platform_gpio_table: - mov.l #gpio_table,er0 - rts - -gpio_table: - ;; P1DDR - .byte 0xff,0xff - ;; P2DDR - .byte 0xff,0xff - ;; P3DDR - .byte 0xff,0x00 - ;; P4DDR - .byte 0x00,0x00 - ;; P5DDR - .byte 0x01,0x01 - ;; P6DDR - .byte 0x00,0x00 - ;; dummy - .byte 0x00,0x00 - ;; P8DDR - .byte 0x0c,0x0c - ;; P9DDR - .byte 0x00,0x00 - ;; PADDR - .byte 0x00,0x00 - ;; PBDDR - .byte 0x30,0x30 - -__target_name: - .asciz "AE-3068" - - .section .bootvec,"ax" - jmp @__start diff --git a/arch/h8300/platform/h8300h/generic/Makefile b/arch/h8300/platform/h8300h/generic/Makefile deleted file mode 100644 index 2b12a170209e..000000000000 --- a/arch/h8300/platform/h8300h/generic/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# -# Makefile for the linux kernel. -# - -extra-y := crt0_$(MODEL).o diff --git a/arch/h8300/platform/h8300h/generic/crt0_ram.S b/arch/h8300/platform/h8300h/generic/crt0_ram.S deleted file mode 100644 index 5ab7d9c12910..000000000000 --- a/arch/h8300/platform/h8300h/generic/crt0_ram.S +++ /dev/null @@ -1,107 +0,0 @@ -/* - * linux/arch/h8300/platform/h8300h/generic/crt0_ram.S - * - * Yoshinori Sato <ysato@users.sourceforge.jp> - * - * Platform depend startup - * Target Archtecture: AE-3068 (aka. aki3068net) - * Memory Layout : RAM - */ - -#define ASSEMBLY - -#include <asm/linkage.h> - -#if !defined(CONFIG_BLKDEV_RESERVE) -#if defined(CONFIG_GDB_DEBUG) -#define RAMEND (__ramend - 0xc000) -#else -#define RAMEND __ramend -#endif -#else -#define RAMEND CONFIG_BLKDEV_RESERVE_ADDRESS -#endif - - .global __start - .global _command_line - .global __platform_gpio_table - .global __target_name - - .h8300h - - .section .text - .file "crt0_ram.S" - - /* CPU Reset entry */ -__start: - mov.l #RAMEND,sp - ldc #0x80,ccr - - /* Peripheral Setup */ - -#if defined(CONFIG_BLK_DEV_BLKMEM) - /* move romfs image */ - jsr @__move_romfs -#endif - - /* .bss clear */ - mov.l #__sbss,er5 - mov.l #__ebss,er4 - sub.l er5,er4 - shlr er4 - shlr er4 - sub.l er0,er0 -1: - mov.l er0,@er5 - adds #4,er5 - dec.l #1,er4 - bne 1b - - /* copy kernel commandline */ - mov.l #COMMAND_START,er5 - mov.l #_command_line,er6 - mov.w #512,r4 - eepmov.w - - /* uClinux kernel start */ - ldc #0x90,ccr /* running kernel */ - mov.l #_init_thread_union,sp - add.l #0x2000,sp - jsr @_start_kernel -_exit: - - jmp _exit - - rts - - /* I/O port assign information */ -__platform_gpio_table: - mov.l #gpio_table,er0 - rts - -gpio_table: - ;; P1DDR - .byte 0x00,0x00 - ;; P2DDR - .byte 0x00,0x00 - ;; P3DDR - .byte 0x00,0x00 - ;; P4DDR - .byte 0x00,0x00 - ;; P5DDR - .byte 0x00,0x00 - ;; P6DDR - .byte 0x00,0x00 - ;; dummy - .byte 0x00,0x00 - ;; P8DDR - .byte 0x00,0x00 - ;; P9DDR - .byte 0x00,0x00 - ;; PADDR - .byte 0x00,0x00 - ;; PBDDR - .byte 0x00,0x00 - -__target_name: - .asciz "generic" diff --git a/arch/h8300/platform/h8300h/generic/crt0_rom.S b/arch/h8300/platform/h8300h/generic/crt0_rom.S deleted file mode 100644 index dda1dfa15a5e..000000000000 --- a/arch/h8300/platform/h8300h/generic/crt0_rom.S +++ /dev/null @@ -1,122 +0,0 @@ -/* - * linux/arch/h8300/platform/h8300h/generic/crt0_rom.S - * - * Yoshinori Sato <ysato@users.sourceforge.jp> - * - * Platform depend startup - * Target Archtecture: generic - * Memory Layout : ROM - */ - -#define ASSEMBLY - -#include <asm/linkage.h> - - .global __start - .global __command_line - .global __platform_gpio_table - .global __target_name - - .h8300h - .section .text - .file "crt0_rom.S" - - /* CPU Reset entry */ -__start: - mov.l #__ramend,sp - ldc #0x80,ccr - - /* Peripheral Setup */ - - /* .bss clear */ - mov.l #__sbss,er5 - mov.l #__ebss,er4 - sub.l er5,er4 - shlr er4 - shlr er4 - sub.l er0,er0 -1: - mov.l er0,@er5 - adds #4,er5 - dec.l #1,er4 - bne 1b - - /* copy .data */ -#if !defined(CONFIG_H8300H_SIM) - /* copy .data */ - mov.l #__begin_data,er5 - mov.l #__sdata,er6 - mov.l #__edata,er4 - sub.l er6,er4 - shlr.l er4 - shlr.l er4 -1: - mov.l @er5+,er0 - mov.l er0,@er6 - adds #4,er6 - dec.l #1,er4 - bne 1b -#endif - - /* copy kernel commandline */ - mov.l #COMMAND_START,er5 - mov.l #__command_line,er6 - mov.w #512,r4 - eepmov.w - - /* linux kernel start */ - ldc #0x90,ccr /* running kernel */ - mov.l #_init_thread_union,sp - add.l #0x2000,sp - jsr @_start_kernel -_exit: - - jmp _exit - - rts - - /* I/O port assign information */ -__platform_gpio_table: - mov.l #gpio_table,er0 - rts - -gpio_table: - ;; P1DDR - .byte 0x00,0x00 - ;; P2DDR - .byte 0x00,0x00 - ;; P3DDR - .byte 0x00,0x00 - ;; P4DDR - .byte 0x00,0x00 - ;; P5DDR - .byte 0x00,0x00 - ;; P6DDR - .byte 0x00,0x00 - ;; dummy - .byte 0x00,0x00 - ;; P8DDR - .byte 0x00,0x00 - ;; P9DDR - .byte 0x00,0x00 - ;; PADDR - .byte 0x00,0x00 - ;; PBDDR - .byte 0x00,0x00 - - .section .rodata -__target_name: - .asciz "generic" - - .section .bss -__command_line: - .space 512 - - /* interrupt vector */ - .section .vectors,"ax" - .long __start -vector = 1 - .rept 64-1 - .long _interrupt_redirect_table+vector*4 -vector = vector + 1 - .endr diff --git a/arch/h8300/platform/h8300h/h8max/Makefile b/arch/h8300/platform/h8300h/h8max/Makefile deleted file mode 100644 index b7ff78050b7f..000000000000 --- a/arch/h8300/platform/h8300h/h8max/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# -# Makefile for the linux kernel. -# - -extra-y := crt0_ram.o diff --git a/arch/h8300/platform/h8300h/h8max/crt0_ram.S b/arch/h8300/platform/h8300h/h8max/crt0_ram.S deleted file mode 100644 index 6a0d4e2d9ec6..000000000000 --- a/arch/h8300/platform/h8300h/h8max/crt0_ram.S +++ /dev/null @@ -1,110 +0,0 @@ -/* - * linux/arch/h8300/platform/h8300h/h8max/crt0_ram.S - * - * Yoshinori Sato <ysato@users.sourceforge.jp> - * - * Platform depend startup - * Target Archtecture: H8MAX - * Memory Layout : RAM - */ - -#define ASSEMBLY - -#include <asm/linkage.h> - -#if !defined(CONFIG_BLKDEV_RESERVE) -#if defined(CONFIG_GDB_DEBUG) -#define RAMEND (__ramend - 0xc000) -#else -#define RAMEND __ramend -#endif -#else -#define RAMEND CONFIG_BLKDEV_RESERVE_ADDRESS -#endif - - .global __start - .global _command_line - .global __platform_gpio_table - .global __target_name - - .h8300h - - .section .text - .file "crt0_ram.S" - - /* CPU Reset entry */ -__start: - mov.l #RAMEND,sp - ldc #0x80,ccr - - /* Peripheral Setup */ - -#if defined(CONFIG_MTD_UCLINUX) - /* move romfs image */ - jsr @__move_romfs -#endif - - /* .bss clear */ - mov.l #__sbss,er5 - mov.l #__ebss,er4 - sub.l er5,er4 - shlr er4 - shlr er4 - sub.l er0,er0 -1: - mov.l er0,@er5 - adds #4,er5 - dec.l #1,er4 - bne 1b - - /* copy kernel commandline */ - mov.l #COMMAND_START,er5 - mov.l #_command_line,er6 - mov.w #512,r4 - eepmov.w - - /* uClinux kernel start */ - ldc #0x90,ccr /* running kernel */ - mov.l #_init_thread_union,sp - add.l #0x2000,sp - jsr @_start_kernel -_exit: - - jmp _exit - - rts - - /* I/O port assign information */ -__platform_gpio_table: - mov.l #gpio_table,er0 - rts - -gpio_table: - ;; P1DDR - .byte 0xff,0xff - ;; P2DDR - .byte 0xff,0xff - ;; P3DDR - .byte 0x00,0x00 - ;; P4DDR - .byte 0x00,0x00 - ;; P5DDR - .byte 0x01,0x01 - ;; P6DDR - .byte 0xf6,0xf6 - ;; dummy - .byte 0x00,0x00 - ;; P8DDR - .byte 0xee,0xee - ;; P9DDR - .byte 0x00,0x00 - ;; PADDR - .byte 0x00,0x00 - ;; PBDDR - .byte 0x30,0x30 - -__target_name: - .asciz "H8MAX" - - .section .bootvec,"ax" - jmp @__start diff --git a/arch/h8300/platform/h8300h/irq.c b/arch/h8300/platform/h8300h/irq.c deleted file mode 100644 index 0a50353e09d5..000000000000 --- a/arch/h8300/platform/h8300h/irq.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Interrupt handling H8/300H depend. - * Yoshinori Sato <ysato@users.sourceforge.jp> - * - */ - -#include <linux/init.h> -#include <linux/errno.h> - -#include <asm/ptrace.h> -#include <asm/traps.h> -#include <asm/irq.h> -#include <asm/io.h> -#include <asm/gpio-internal.h> -#include <asm/regs306x.h> - -const int __initconst h8300_saved_vectors[] = { -#if defined(CONFIG_GDB_DEBUG) - TRAP3_VEC, /* TRAPA #3 is GDB breakpoint */ -#endif - -1, -}; - -const h8300_vector __initconst h8300_trap_table[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - system_call, - 0, - 0, - trace_break, -}; - -int h8300_enable_irq_pin(unsigned int irq) -{ - int bitmask; - if (irq < EXT_IRQ0 || irq > EXT_IRQ5) - return 0; - - /* initialize IRQ pin */ - bitmask = 1 << (irq - EXT_IRQ0); - switch(irq) { - case EXT_IRQ0: - case EXT_IRQ1: - case EXT_IRQ2: - case EXT_IRQ3: - if (H8300_GPIO_RESERVE(H8300_GPIO_P8, bitmask) == 0) - return -EBUSY; - H8300_GPIO_DDR(H8300_GPIO_P8, bitmask, H8300_GPIO_INPUT); - break; - case EXT_IRQ4: - case EXT_IRQ5: - if (H8300_GPIO_RESERVE(H8300_GPIO_P9, bitmask) == 0) - return -EBUSY; - H8300_GPIO_DDR(H8300_GPIO_P9, bitmask, H8300_GPIO_INPUT); - break; - } - - return 0; -} - -void h8300_disable_irq_pin(unsigned int irq) -{ - int bitmask; - if (irq < EXT_IRQ0 || irq > EXT_IRQ5) - return; - - /* disable interrupt & release IRQ pin */ - bitmask = 1 << (irq - EXT_IRQ0); - switch(irq) { - case EXT_IRQ0: - case EXT_IRQ1: - case EXT_IRQ2: - case EXT_IRQ3: - *(volatile unsigned char *)IER &= ~bitmask; - H8300_GPIO_FREE(H8300_GPIO_P8, bitmask); - break ; - case EXT_IRQ4: - case EXT_IRQ5: - *(volatile unsigned char *)IER &= ~bitmask; - H8300_GPIO_FREE(H8300_GPIO_P9, bitmask); - break; - } -} diff --git a/arch/h8300/platform/h8300h/ptrace_h8300h.c b/arch/h8300/platform/h8300h/ptrace_h8300h.c deleted file mode 100644 index 4f1ed0279633..000000000000 --- a/arch/h8300/platform/h8300h/ptrace_h8300h.c +++ /dev/null @@ -1,284 +0,0 @@ -/* - * linux/arch/h8300/platform/h8300h/ptrace_h8300h.c - * ptrace cpu depend helper functions - * - * Yoshinori Sato <ysato@users.sourceforge.jp> - * - * This file is subject to the terms and conditions of the GNU General - * Public License. See the file COPYING in the main directory of - * this archive for more details. - */ - -#include <linux/linkage.h> -#include <linux/sched.h> -#include <asm/ptrace.h> - -#define CCR_MASK 0x6f /* mode/imask not set */ -#define BREAKINST 0x5730 /* trapa #3 */ - -/* Mapping from PT_xxx to the stack offset at which the register is - saved. Notice that usp has no stack-slot and needs to be treated - specially (see get_reg/put_reg below). */ -static const int h8300_register_offset[] = { - PT_REG(er1), PT_REG(er2), PT_REG(er3), PT_REG(er4), - PT_REG(er5), PT_REG(er6), PT_REG(er0), PT_REG(orig_er0), - PT_REG(ccr), PT_REG(pc) -}; - -/* read register */ -long h8300_get_reg(struct task_struct *task, int regno) -{ - switch (regno) { - case PT_USP: - return task->thread.usp + sizeof(long)*2; - case PT_CCR: - return *(unsigned short *)(task->thread.esp0 + h8300_register_offset[regno]); - default: - return *(unsigned long *)(task->thread.esp0 + h8300_register_offset[regno]); - } -} - -/* write register */ -int h8300_put_reg(struct task_struct *task, int regno, unsigned long data) -{ - unsigned short oldccr; - switch (regno) { - case PT_USP: - task->thread.usp = data - sizeof(long)*2; - case PT_CCR: - oldccr = *(unsigned short *)(task->thread.esp0 + h8300_register_offset[regno]); - oldccr &= ~CCR_MASK; - data &= CCR_MASK; - data |= oldccr; - *(unsigned short *)(task->thread.esp0 + h8300_register_offset[regno]) = data; - break; - default: - *(unsigned long *)(task->thread.esp0 + h8300_register_offset[regno]) = data; - break; - } - return 0; -} - -/* disable singlestep */ -void user_disable_single_step(struct task_struct *child) -{ - if((long)child->thread.breakinfo.addr != -1L) { - *child->thread.breakinfo.addr = child->thread.breakinfo.inst; - child->thread.breakinfo.addr = (unsigned short *)-1L; - } -} - -/* calculate next pc */ -enum jump_type {none, /* normal instruction */ - jabs, /* absolute address jump */ - ind, /* indirect address jump */ - ret, /* return to subrutine */ - reg, /* register indexed jump */ - relb, /* pc relative jump (byte offset) */ - relw, /* pc relative jump (word offset) */ - }; - -/* opcode decode table define - ptn: opcode pattern - msk: opcode bitmask - len: instruction length (<0 next table index) - jmp: jump operation mode */ -struct optable { - unsigned char bitpattern; - unsigned char bitmask; - signed char length; - signed char type; -} __attribute__((aligned(1),packed)); - -#define OPTABLE(ptn,msk,len,jmp) \ - { \ - .bitpattern = ptn, \ - .bitmask = msk, \ - .length = len, \ - .type = jmp, \ - } - -static const struct optable optable_0[] = { - OPTABLE(0x00,0xff, 1,none), /* 0x00 */ - OPTABLE(0x01,0xff,-1,none), /* 0x01 */ - OPTABLE(0x02,0xfe, 1,none), /* 0x02-0x03 */ - OPTABLE(0x04,0xee, 1,none), /* 0x04-0x05/0x14-0x15 */ - OPTABLE(0x06,0xfe, 1,none), /* 0x06-0x07 */ - OPTABLE(0x08,0xea, 1,none), /* 0x08-0x09/0x0c-0x0d/0x18-0x19/0x1c-0x1d */ - OPTABLE(0x0a,0xee, 1,none), /* 0x0a-0x0b/0x1a-0x1b */ - OPTABLE(0x0e,0xee, 1,none), /* 0x0e-0x0f/0x1e-0x1f */ - OPTABLE(0x10,0xfc, 1,none), /* 0x10-0x13 */ - OPTABLE(0x16,0xfe, 1,none), /* 0x16-0x17 */ - OPTABLE(0x20,0xe0, 1,none), /* 0x20-0x3f */ - OPTABLE(0x40,0xf0, 1,relb), /* 0x40-0x4f */ - OPTABLE(0x50,0xfc, 1,none), /* 0x50-0x53 */ - OPTABLE(0x54,0xfd, 1,ret ), /* 0x54/0x56 */ - OPTABLE(0x55,0xff, 1,relb), /* 0x55 */ - OPTABLE(0x57,0xff, 1,none), /* 0x57 */ - OPTABLE(0x58,0xfb, 2,relw), /* 0x58/0x5c */ - OPTABLE(0x59,0xfb, 1,reg ), /* 0x59/0x5b */ - OPTABLE(0x5a,0xfb, 2,jabs), /* 0x5a/0x5e */ - OPTABLE(0x5b,0xfb, 2,ind ), /* 0x5b/0x5f */ - OPTABLE(0x60,0xe8, 1,none), /* 0x60-0x67/0x70-0x77 */ - OPTABLE(0x68,0xfa, 1,none), /* 0x68-0x69/0x6c-0x6d */ - OPTABLE(0x6a,0xfe,-2,none), /* 0x6a-0x6b */ - OPTABLE(0x6e,0xfe, 2,none), /* 0x6e-0x6f */ - OPTABLE(0x78,0xff, 4,none), /* 0x78 */ - OPTABLE(0x79,0xff, 2,none), /* 0x79 */ - OPTABLE(0x7a,0xff, 3,none), /* 0x7a */ - OPTABLE(0x7b,0xff, 2,none), /* 0x7b */ - OPTABLE(0x7c,0xfc, 2,none), /* 0x7c-0x7f */ - OPTABLE(0x80,0x80, 1,none), /* 0x80-0xff */ -}; - -static const struct optable optable_1[] = { - OPTABLE(0x00,0xff,-3,none), /* 0x0100 */ - OPTABLE(0x40,0xf0,-3,none), /* 0x0140-0x14f */ - OPTABLE(0x80,0xf0, 1,none), /* 0x0180-0x018f */ - OPTABLE(0xc0,0xc0, 2,none), /* 0x01c0-0x01ff */ -}; - -static const struct optable optable_2[] = { - OPTABLE(0x00,0x20, 2,none), /* 0x6a0?/0x6a8?/0x6b0?/0x6b8? */ - OPTABLE(0x20,0x20, 3,none), /* 0x6a2?/0x6aa?/0x6b2?/0x6ba? */ -}; - -static const struct optable optable_3[] = { - OPTABLE(0x69,0xfb, 2,none), /* 0x010069/0x01006d/014069/0x01406d */ - OPTABLE(0x6b,0xff,-4,none), /* 0x01006b/0x01406b */ - OPTABLE(0x6f,0xff, 3,none), /* 0x01006f/0x01406f */ - OPTABLE(0x78,0xff, 5,none), /* 0x010078/0x014078 */ -}; - -static const struct optable optable_4[] = { - OPTABLE(0x00,0x78, 3,none), /* 0x0100690?/0x01006d0?/0140690/0x01406d0?/0x0100698?/0x01006d8?/0140698?/0x01406d8? */ - OPTABLE(0x20,0x78, 4,none), /* 0x0100692?/0x01006d2?/0140692/0x01406d2?/0x010069a?/0x01006da?/014069a?/0x01406da? */ -}; - -static const struct optables_list { - const struct optable *ptr; - int size; -} optables[] = { -#define OPTABLES(no) \ - { \ - .ptr = optable_##no, \ - .size = sizeof(optable_##no) / sizeof(struct optable), \ - } - OPTABLES(0), - OPTABLES(1), - OPTABLES(2), - OPTABLES(3), - OPTABLES(4), - -}; - -const unsigned char condmask[] = { - 0x00,0x40,0x01,0x04,0x02,0x08,0x10,0x20 -}; - -static int isbranch(struct task_struct *task,int reson) -{ - unsigned char cond = h8300_get_reg(task, PT_CCR); - /* encode complex conditions */ - /* B4: N^V - B5: Z|(N^V) - B6: C|Z */ - __asm__("bld #3,%w0\n\t" - "bxor #1,%w0\n\t" - "bst #4,%w0\n\t" - "bor #2,%w0\n\t" - "bst #5,%w0\n\t" - "bld #2,%w0\n\t" - "bor #0,%w0\n\t" - "bst #6,%w0\n\t" - :"=&r"(cond)::"cc"); - cond &= condmask[reson >> 1]; - if (!(reson & 1)) - return cond == 0; - else - return cond != 0; -} - -static unsigned short *getnextpc(struct task_struct *child, unsigned short *pc) -{ - const struct optable *op; - unsigned char *fetch_p; - unsigned char inst; - unsigned long addr; - unsigned long *sp; - int op_len,regno; - op = optables[0].ptr; - op_len = optables[0].size; - fetch_p = (unsigned char *)pc; - inst = *fetch_p++; - do { - if ((inst & op->bitmask) == op->bitpattern) { - if (op->length < 0) { - op = optables[-op->length].ptr; - op_len = optables[-op->length].size + 1; - inst = *fetch_p++; - } else { - switch (op->type) { - case none: - return pc + op->length; - case jabs: - addr = *(unsigned long *)pc; - return (unsigned short *)(addr & 0x00ffffff); - case ind: - addr = *pc & 0xff; - return (unsigned short *)(*(unsigned long *)addr); - case ret: - sp = (unsigned long *)h8300_get_reg(child, PT_USP); - /* user stack frames - | er0 | temporary saved - +--------+ - | exp | exception stack frames - +--------+ - | ret pc | userspace return address - */ - return (unsigned short *)(*(sp+2) & 0x00ffffff); - case reg: - regno = (*pc >> 4) & 0x07; - if (regno == 0) - addr = h8300_get_reg(child, PT_ER0); - else - addr = h8300_get_reg(child, regno-1+PT_ER1); - return (unsigned short *)addr; - case relb: - if (inst == 0x55 || isbranch(child,inst & 0x0f)) - pc = (unsigned short *)((unsigned long)pc + - ((signed char)(*fetch_p))); - return pc+1; /* skip myself */ - case relw: - if (inst == 0x5c || isbranch(child,(*fetch_p & 0xf0) >> 4)) - pc = (unsigned short *)((unsigned long)pc + - ((signed short)(*(pc+1)))); - return pc+2; /* skip myself */ - } - } - } else - op++; - } while(--op_len > 0); - return NULL; -} - -/* Set breakpoint(s) to simulate a single step from the current PC. */ - -void user_enable_single_step(struct task_struct *child) -{ - unsigned short *nextpc; - nextpc = getnextpc(child,(unsigned short *)h8300_get_reg(child, PT_PC)); - child->thread.breakinfo.addr = nextpc; - child->thread.breakinfo.inst = *nextpc; - *nextpc = BREAKINST; -} - -asmlinkage void trace_trap(unsigned long bp) -{ - if ((unsigned long)current->thread.breakinfo.addr == bp) { - user_disable_single_step(current); - force_sig(SIGTRAP,current); - } else - force_sig(SIGILL,current); -} - diff --git a/arch/h8300/platform/h8s/Makefile b/arch/h8300/platform/h8s/Makefile deleted file mode 100644 index bf1241883766..000000000000 --- a/arch/h8300/platform/h8s/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# -# Makefile for the linux kernel. -# -# Reuse any files we can from the H8S -# - -obj-y := ints_h8s.o ptrace_h8s.o diff --git a/arch/h8300/platform/h8s/edosk2674/Makefile b/arch/h8300/platform/h8s/edosk2674/Makefile deleted file mode 100644 index 8e349723bb4f..000000000000 --- a/arch/h8300/platform/h8s/edosk2674/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# -# Makefile for the linux kernel. -# - -extra-y := crt0_$(MODEL).o diff --git a/arch/h8300/platform/h8s/edosk2674/crt0_ram.S b/arch/h8300/platform/h8s/edosk2674/crt0_ram.S deleted file mode 100644 index 5ed191b37cde..000000000000 --- a/arch/h8300/platform/h8s/edosk2674/crt0_ram.S +++ /dev/null @@ -1,130 +0,0 @@ -/* - * linux/arch/h8300/platform/h8s/edosk2674/crt0_ram.S - * - * Yoshinori Sato <ysato@users.sourceforge.jp> - * - * Platform depend startup - * Target Archtecture: EDOSK-2674 - * Memory Layout : RAM - */ - -#define ASSEMBLY - -#include <asm/linkage.h> -#include <asm/regs267x.h> - -#if !defined(CONFIG_BLKDEV_RESERVE) -#if defined(CONFIG_GDB_DEBUG) -#define RAMEND (__ramend - 0xc000) -#else -#define RAMEND __ramend -#endif -#else -#define RAMEND CONFIG_BLKDEV_RESERVE_ADDRESS -#endif - - .global __start - .global __command_line - .global __platform_gpio_table - .global __target_name - - .h8300s - - .section .text - .file "crt0_ram.S" - - /* CPU Reset entry */ -__start: - mov.l #RAMEND,sp - ldc #0x80,ccr - ldc #0x00,exr - - /* Peripheral Setup */ - bclr #4,@INTCR:8 /* interrupt mode 2 */ - bset #5,@INTCR:8 - bclr #0,@IER+1:16 - bset #1,@ISCRL+1:16 /* IRQ0 Positive Edge */ - bclr #0,@ISCRL+1:16 - -#if defined(CONFIG_MTD_UCLINUX) - /* move romfs image */ - jsr @__move_romfs -#endif - - /* .bss clear */ - mov.l #__sbss,er5 - mov.l er5,er6 - mov.l #__ebss,er4 - sub.l er5,er4 - shlr #2,er4 - sub.l er0,er0 -1: - mov.l er0,@er5 - adds #4,er5 - dec.l #1,er4 - bne 1b - - /* copy kernel commandline */ - mov.l #COMMAND_START,er5 - mov.l #_command_line,er6 - mov.w #512,r4 - eepmov.w - - /* uClinux kernel start */ - ldc #0x90,ccr /* running kernel */ - mov.l #_init_thread_union,sp - add.l #0x2000,sp - jsr @_start_kernel -_exit: - - jmp _exit - - rts - - /* I/O port assign information */ -__platform_gpio_table: - mov.l #gpio_table,er0 - rts - -gpio_table: - ;; P1DDR - ;; used,ddr - .byte 0x00,0x00 - ;; P2DDR - .byte 0x00,0x00 - ;; P3DDR - .byte 0x3f,0x3a - ;; dummy - .byte 0x00,0x00 - ;; P5DDR - .byte 0x00,0x00 - ;; P6DDR - .byte 0x00,0x00 - ;; P7DDR - .byte 0x00,0x00 - ;; P8DDR - .byte 0x00,0x00 - ;; dummy - .byte 0x00,0x00 - ;; PADDR - .byte 0xff,0xff - ;; PBDDR - .byte 0xff,0x00 - ;; PCDDR - .byte 0xff,0x00 - ;; PDDDR - .byte 0xff,0x00 - ;; PEDDR - .byte 0xff,0x00 - ;; PFDDR - .byte 0xff,0xff - ;; PGDDR - .byte 0x0f,0x0f - ;; PHDDR - .byte 0x0f,0x0f - -__target_name: - .asciz "EDOSK-2674" - - .section .bootvec,"ax" - jmp @__start diff --git a/arch/h8300/platform/h8s/edosk2674/crt0_rom.S b/arch/h8300/platform/h8s/edosk2674/crt0_rom.S deleted file mode 100644 index 06d1d7f324ca..000000000000 --- a/arch/h8300/platform/h8s/edosk2674/crt0_rom.S +++ /dev/null @@ -1,186 +0,0 @@ -/* - * linux/arch/h8300/platform/h8s/edosk2674/crt0_rom.S - * - * Yoshinori Sato <ysato@users.sourceforge.jp> - * - * Platform depend startup - * Target Archtecture: EDOSK-2674 - * Memory Layout : ROM - */ - -#define ASSEMBLY - -#include <asm/linkage.h> -#include <asm/regs267x.h> - - .global __start - .global __command_line - .global __platform_gpio_table - .global __target_name - - .h8300s - .section .text - .file "crt0_rom.S" - - /* CPU Reset entry */ -__start: - mov.l #__ramend,sp - ldc #0x80,ccr - ldc #0,exr - - /* Peripheral Setup */ -;BSC/GPIO setup - mov.l #init_regs,er0 - mov.w #0xffff,e2 -1: - mov.w @er0+,r2 - beq 2f - mov.w @er0+,r1 - mov.b r1l,@er2 - bra 1b - -2: -;SDRAM setup -#define SDRAM_SMR 0x400040 - - mov.b #0,r0l - mov.b r0l,@DRACCR:16 - mov.w #0x188,r0 - mov.w r0,@REFCR:16 - mov.w #0x85b4,r0 - mov.w r0,@DRAMCR:16 - mov.b #0,r1l - mov.b r1l,@SDRAM_SMR - mov.w #0x84b4,r0 - mov.w r0,@DRAMCR:16 -;special thanks to Arizona Cooperative Power - - /* copy .data */ - mov.l #__begin_data,er5 - mov.l #__sdata,er6 - mov.l #__edata,er4 - sub.l er6,er4 - shlr.l #2,er4 -1: - mov.l @er5+,er0 - mov.l er0,@er6 - adds #4,er6 - dec.l #1,er4 - bne 1b - - /* .bss clear */ - mov.l #__sbss,er5 - mov.l #__ebss,er4 - sub.l er5,er4 - shlr.l #2,er4 - sub.l er0,er0 -1: - mov.l er0,@er5 - adds #4,er5 - dec.l #1,er4 - bne 1b - - /* copy kernel commandline */ - mov.l #COMMAND_START,er5 - mov.l #__command_line,er6 - mov.w #512,r4 - eepmov.w - - /* linux kernel start */ - ldc #0x90,ccr /* running kernel */ - mov.l #_init_thread_union,sp - add.l #0x2000,sp - jsr @_start_kernel -_exit: - - jmp _exit - - rts - - /* I/O port assign information */ -__platform_gpio_table: - mov.l #gpio_table,er0 - rts - -#define INIT_REGS_DATA(REGS,DATA) \ - .word ((REGS) & 0xffff),DATA - -init_regs: -INIT_REGS_DATA(ASTCR,0xff) -INIT_REGS_DATA(RDNCR,0x00) -INIT_REGS_DATA(ABWCR,0x80) -INIT_REGS_DATA(WTCRAH,0x27) -INIT_REGS_DATA(WTCRAL,0x77) -INIT_REGS_DATA(WTCRBH,0x71) -INIT_REGS_DATA(WTCRBL,0x22) -INIT_REGS_DATA(CSACRH,0x80) -INIT_REGS_DATA(CSACRL,0x80) -INIT_REGS_DATA(BROMCRH,0xa0) -INIT_REGS_DATA(BROMCRL,0xa0) -INIT_REGS_DATA(P3DDR,0x3a) -INIT_REGS_DATA(P3ODR,0x06) -INIT_REGS_DATA(PADDR,0xff) -INIT_REGS_DATA(PFDDR,0xfe) -INIT_REGS_DATA(PGDDR,0x0f) -INIT_REGS_DATA(PHDDR,0x0f) -INIT_REGS_DATA(PFCR0,0xff) -INIT_REGS_DATA(PFCR2,0x0d) -INIT_REGS_DATA(ITSR, 0x00) -INIT_REGS_DATA(ITSR+1,0x3f) -INIT_REGS_DATA(INTCR,0x20) - - .word 0 - -gpio_table: - ;; P1DDR - .byte 0x00,0x00 - ;; P2DDR - .byte 0x00,0x00 - ;; P3DDR - .byte 0x00,0x00 - ;; dummy - .byte 0x00,0x00 - ;; P5DDR - .byte 0x00,0x00 - ;; P6DDR - .byte 0x00,0x00 - ;; P7DDR - .byte 0x00,0x00 - ;; P8DDR - .byte 0x00,0x00 - ;; dummy - .byte 0x00,0x00 - ;; PADDR - .byte 0x00,0x00 - ;; PBDDR - .byte 0x00,0x00 - ;; PCDDR - .byte 0x00,0x00 - ;; PDDDR - .byte 0x00,0x00 - ;; PEDDR - .byte 0x00,0x00 - ;; PFDDR - .byte 0x00,0x00 - ;; PGDDR - .byte 0x00,0x00 - ;; PHDDR - .byte 0x00,0x00 - - .section .rodata -__target_name: - .asciz "EDOSK-2674" - - .section .bss -__command_line: - .space 512 - - /* interrupt vector */ - .section .vectors,"ax" - .long __start - .long __start -vector = 2 - .rept 126 - .long _interrupt_redirect_table+vector*4 -vector = vector + 1 - .endr diff --git a/arch/h8300/platform/h8s/generic/Makefile b/arch/h8300/platform/h8s/generic/Makefile deleted file mode 100644 index 44b4685c664c..000000000000 --- a/arch/h8300/platform/h8s/generic/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# -# Makefile for the linux kernel. -# - -extra-y = crt0_$(MODEL).o diff --git a/arch/h8300/platform/h8s/generic/crt0_ram.S b/arch/h8300/platform/h8s/generic/crt0_ram.S deleted file mode 100644 index 7018915de74f..000000000000 --- a/arch/h8300/platform/h8s/generic/crt0_ram.S +++ /dev/null @@ -1,127 +0,0 @@ -/* - * linux/arch/h8300/platform/h8s/edosk2674/crt0_ram.S - * - * Yoshinori Sato <ysato@users.sourceforge.jp> - * - * Platform depend startup - * Target Archtecture: generic - * Memory Layout : RAM - */ - -#define ASSEMBLY - -#include <asm/linkage.h> -#include <asm/regs267x.h> - -#if !defined(CONFIG_BLKDEV_RESERVE) -#if defined(CONFIG_GDB_DEBUG) -#define RAMEND (__ramend - 0xc000) -#else -#define RAMEND __ramend -#endif -#else -#define RAMEND CONFIG_BLKDEV_RESERVE_ADDRESS -#endif - - .global __start - .global __command_line - .global __platform_gpio_table - .global __target_name - - .h8300s - - .section .text - .file "crt0_ram.S" - - /* CPU Reset entry */ -__start: - mov.l #RAMEND,sp - ldc #0x80,ccr - ldc #0x00,exr - - /* Peripheral Setup */ - bclr #4,@INTCR:8 /* interrupt mode 2 */ - bset #5,@INTCR:8 - -#if defined(CONFIG_MTD_UCLINUX) - /* move romfs image */ - jsr @__move_romfs -#endif - - /* .bss clear */ - mov.l #__sbss,er5 - mov.l er5,er6 - mov.l #__ebss,er4 - sub.l er5,er4 - shlr #2,er4 - sub.l er0,er0 -1: - mov.l er0,@er5 - adds #4,er5 - dec.l #1,er4 - bne 1b - - /* copy kernel commandline */ - mov.l #COMMAND_START,er5 - mov.l #_command_line,er6 - mov.w #512,r4 - eepmov.w - - /* uClinux kernel start */ - ldc #0x90,ccr /* running kernel */ - mov.l #_init_thread_union,sp - add.l #0x2000,sp - jsr @_start_kernel -_exit: - - jmp _exit - - rts - - /* I/O port assign information */ -__platform_gpio_table: - mov.l #gpio_table,er0 - rts - -gpio_table: - ;; P1DDR - ;; used,ddr - .byte 0x00,0x00 - ;; P2DDR - .byte 0x00,0x00 - ;; P3DDR - .byte 0x00,0x00 - ;; dummy - .byte 0x00,0x00 - ;; P5DDR - .byte 0x00,0x00 - ;; P6DDR - .byte 0x00,0x00 - ;; P7DDR - .byte 0x00,0x00 - ;; P8DDR - .byte 0x00,0x00 - ;; dummy - .byte 0x00,0x00 - ;; PADDR - .byte 0x00,0x00 - ;; PBDDR - .byte 0x00,0x00 - ;; PCDDR - .byte 0x00,0x00 - ;; PDDDR - .byte 0x00,0x00 - ;; PEDDR - .byte 0x00,0x00 - ;; PFDDR - .byte 0x00,0x00 - ;; PGDDR - .byte 0x00,0x00 - ;; PHDDR - .byte 0x00,0x00 - -__target_name: - .asciz "generic" - - .section .bootvec,"ax" - jmp @__start diff --git a/arch/h8300/platform/h8s/generic/crt0_rom.S b/arch/h8300/platform/h8s/generic/crt0_rom.S deleted file mode 100644 index 623ba7828193..000000000000 --- a/arch/h8300/platform/h8s/generic/crt0_rom.S +++ /dev/null @@ -1,128 +0,0 @@ -/* - * linux/arch/h8300/platform/h8s/generic/crt0_rom.S - * - * Yoshinori Sato <ysato@users.sourceforge.jp> - * - * Platform depend startup - * Target Archtecture: generic - * Memory Layout : ROM - */ - -#define ASSEMBLY - -#include <asm/linkage.h> -#include <asm/regs267x.h> - - .global __start - .global __command_line - .global __platform_gpio_table - .global __target_name - - .h8300s - .section .text - .file "crt0_rom.S" - - /* CPU Reset entry */ -__start: - mov.l #__ramend,sp - ldc #0x80,ccr - ldc #0,exr - bclr #4,@INTCR:8 - bset #5,@INTCR:8 /* Interrupt mode 2 */ - - /* Peripheral Setup */ - - /* copy .data */ -#if !defined(CONFIG_H8S_SIM) - mov.l #__begin_data,er5 - mov.l #__sdata,er6 - mov.l #__edata,er4 - sub.l er6,er4 - shlr.l #2,er4 -1: - mov.l @er5+,er0 - mov.l er0,@er6 - adds #4,er6 - dec.l #1,er4 - bne 1b -#endif - - /* .bss clear */ - mov.l #__sbss,er5 - mov.l #__ebss,er4 - sub.l er5,er4 - shlr.l #2,er4 - sub.l er0,er0 -1: - mov.l er0,@er5 - adds #4,er5 - dec.l #1,er4 - bne 1b - - /* linux kernel start */ - ldc #0x90,ccr /* running kernel */ - mov.l #_init_thread_union,sp - add.l #0x2000,sp - jsr @_start_kernel -_exit: - - jmp _exit - - rts - - /* I/O port assign information */ -__platform_gpio_table: - mov.l #gpio_table,er0 - rts - -gpio_table: - ;; P1DDR - .byte 0x00,0x00 - ;; P2DDR - .byte 0x00,0x00 - ;; P3DDR - .byte 0x00,0x00 - ;; P4DDR - .byte 0x00,0x00 - ;; P5DDR - .byte 0x00,0x00 - ;; P6DDR - .byte 0x00,0x00 - ;; dummy - .byte 0x00,0x00 - ;; P8DDR - .byte 0x00,0x00 - ;; PADDR - .byte 0x00,0x00 - ;; PBDDR - .byte 0x00,0x00 - ;; PCDDR - .byte 0x00,0x00 - ;; PDDDR - .byte 0x00,0x00 - ;; PEDDR - .byte 0x00,0x00 - ;; PFDDR - .byte 0x00,0x00 - ;; PGDDR - .byte 0x00,0x00 - ;; PHDDR - .byte 0x00,0x00 - - .section .rodata -__target_name: - .asciz "generic" - - .section .bss -__command_line: - .space 512 - - /* interrupt vector */ - .section .vectors,"ax" - .long __start - .long __start -vector = 2 - .rept 126-1 - .long _interrupt_redirect_table+vector*4 -vector = vector + 1 - .endr diff --git a/arch/h8300/platform/h8s/irq.c b/arch/h8300/platform/h8s/irq.c deleted file mode 100644 index f3a5511c16b1..000000000000 --- a/arch/h8300/platform/h8s/irq.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * linux/arch/h8300/platform/h8s/ints_h8s.c - * Interrupt handling CPU variants - * - * Yoshinori Sato <ysato@users.sourceforge.jp> - * - */ - -#include <linux/init.h> -#include <linux/errno.h> -#include <linux/kernel.h> - -#include <asm/ptrace.h> -#include <asm/traps.h> -#include <asm/irq.h> -#include <asm/io.h> -#include <asm/gpio-internal.h> -#include <asm/regs267x.h> - -/* saved vector list */ -const int __initconst h8300_saved_vectors[] = { -#if defined(CONFIG_GDB_DEBUG) - TRACE_VEC, - TRAP3_VEC, -#endif - -1 -}; - -/* trap entry table */ -const H8300_VECTOR __initconst h8300_trap_table[] = { - 0,0,0,0,0, - trace_break, /* TRACE */ - 0,0, - system_call, /* TRAPA #0 */ - 0,0,0,0,0,0,0 -}; - -/* IRQ pin assignment */ -struct irq_pins { - unsigned char port_no; - unsigned char bit_no; -} __attribute__((aligned(1),packed)); -/* ISTR = 0 */ -static const struct irq_pins irq_assign_table0[16]={ - {H8300_GPIO_P5,H8300_GPIO_B0},{H8300_GPIO_P5,H8300_GPIO_B1}, - {H8300_GPIO_P5,H8300_GPIO_B2},{H8300_GPIO_P5,H8300_GPIO_B3}, - {H8300_GPIO_P5,H8300_GPIO_B4},{H8300_GPIO_P5,H8300_GPIO_B5}, - {H8300_GPIO_P5,H8300_GPIO_B6},{H8300_GPIO_P5,H8300_GPIO_B7}, - {H8300_GPIO_P6,H8300_GPIO_B0},{H8300_GPIO_P6,H8300_GPIO_B1}, - {H8300_GPIO_P6,H8300_GPIO_B2},{H8300_GPIO_P6,H8300_GPIO_B3}, - {H8300_GPIO_P6,H8300_GPIO_B4},{H8300_GPIO_P6,H8300_GPIO_B5}, - {H8300_GPIO_PF,H8300_GPIO_B1},{H8300_GPIO_PF,H8300_GPIO_B2}, -}; -/* ISTR = 1 */ -static const struct irq_pins irq_assign_table1[16]={ - {H8300_GPIO_P8,H8300_GPIO_B0},{H8300_GPIO_P8,H8300_GPIO_B1}, - {H8300_GPIO_P8,H8300_GPIO_B2},{H8300_GPIO_P8,H8300_GPIO_B3}, - {H8300_GPIO_P8,H8300_GPIO_B4},{H8300_GPIO_P8,H8300_GPIO_B5}, - {H8300_GPIO_PH,H8300_GPIO_B2},{H8300_GPIO_PH,H8300_GPIO_B3}, - {H8300_GPIO_P2,H8300_GPIO_B0},{H8300_GPIO_P2,H8300_GPIO_B1}, - {H8300_GPIO_P2,H8300_GPIO_B2},{H8300_GPIO_P2,H8300_GPIO_B3}, - {H8300_GPIO_P2,H8300_GPIO_B4},{H8300_GPIO_P2,H8300_GPIO_B5}, - {H8300_GPIO_P2,H8300_GPIO_B6},{H8300_GPIO_P2,H8300_GPIO_B7}, -}; - -/* IRQ to GPIO pin translation */ -#define IRQ_GPIO_MAP(irqbit,irq,port,bit) \ -do { \ - if (*(volatile unsigned short *)ITSR & irqbit) { \ - port = irq_assign_table1[irq - EXT_IRQ0].port_no; \ - bit = irq_assign_table1[irq - EXT_IRQ0].bit_no; \ - } else { \ - port = irq_assign_table0[irq - EXT_IRQ0].port_no; \ - bit = irq_assign_table0[irq - EXT_IRQ0].bit_no; \ - } \ -} while(0) - -int h8300_enable_irq_pin(unsigned int irq) -{ - if (irq >= EXT_IRQ0 && irq <= EXT_IRQ15) { - unsigned short ptn = 1 << (irq - EXT_IRQ0); - unsigned int port_no,bit_no; - IRQ_GPIO_MAP(ptn, irq, port_no, bit_no); - if (H8300_GPIO_RESERVE(port_no, bit_no) == 0) - return -EBUSY; /* pin already use */ - H8300_GPIO_DDR(port_no, bit_no, H8300_GPIO_INPUT); - *(volatile unsigned short *)ISR &= ~ptn; /* ISR clear */ - } - - return 0; -} - -void h8300_disable_irq_pin(unsigned int irq) -{ - if (irq >= EXT_IRQ0 && irq <= EXT_IRQ15) { - /* disable interrupt & release IRQ pin */ - unsigned short ptn = 1 << (irq - EXT_IRQ0); - unsigned short port_no,bit_no; - *(volatile unsigned short *)ISR &= ~ptn; - *(volatile unsigned short *)IER &= ~ptn; - IRQ_GPIO_MAP(ptn, irq, port_no, bit_no); - H8300_GPIO_FREE(port_no, bit_no); - } -} diff --git a/arch/h8300/platform/h8s/ptrace_h8s.c b/arch/h8300/platform/h8s/ptrace_h8s.c deleted file mode 100644 index c058ab1a8495..000000000000 --- a/arch/h8300/platform/h8s/ptrace_h8s.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * linux/arch/h8300/platform/h8s/ptrace_h8s.c - * ptrace cpu depend helper functions - * - * Yoshinori Sato <ysato@users.sourceforge.jp> - * - * This file is subject to the terms and conditions of the GNU General - * Public License. See the file COPYING in the main directory of - * this archive for more details. - */ - -#include <linux/linkage.h> -#include <linux/sched.h> -#include <linux/errno.h> -#include <asm/ptrace.h> - -#define CCR_MASK 0x6f -#define EXR_TRACE 0x80 - -/* Mapping from PT_xxx to the stack offset at which the register is - saved. Notice that usp has no stack-slot and needs to be treated - specially (see get_reg/put_reg below). */ -static const int h8300_register_offset[] = { - PT_REG(er1), PT_REG(er2), PT_REG(er3), PT_REG(er4), - PT_REG(er5), PT_REG(er6), PT_REG(er0), PT_REG(orig_er0), - PT_REG(ccr), PT_REG(pc), 0, PT_REG(exr) -}; - -/* read register */ -long h8300_get_reg(struct task_struct *task, int regno) -{ - switch (regno) { - case PT_USP: - return task->thread.usp + sizeof(long)*2 + 2; - case PT_CCR: - case PT_EXR: - return *(unsigned short *)(task->thread.esp0 + h8300_register_offset[regno]); - default: - return *(unsigned long *)(task->thread.esp0 + h8300_register_offset[regno]); - } -} - -/* write register */ -int h8300_put_reg(struct task_struct *task, int regno, unsigned long data) -{ - unsigned short oldccr; - switch (regno) { - case PT_USP: - task->thread.usp = data - sizeof(long)*2 - 2; - case PT_CCR: - oldccr = *(unsigned short *)(task->thread.esp0 + h8300_register_offset[regno]); - oldccr &= ~CCR_MASK; - data &= CCR_MASK; - data |= oldccr; - *(unsigned short *)(task->thread.esp0 + h8300_register_offset[regno]) = data; - break; - case PT_EXR: - /* exr modify not support */ - return -EIO; - default: - *(unsigned long *)(task->thread.esp0 + h8300_register_offset[regno]) = data; - break; - } - return 0; -} - -/* disable singlestep */ -void user_disable_single_step(struct task_struct *child) -{ - *(unsigned short *)(child->thread.esp0 + h8300_register_offset[PT_EXR]) &= ~EXR_TRACE; -} - -/* enable singlestep */ -void user_enable_single_step(struct task_struct *child) -{ - *(unsigned short *)(child->thread.esp0 + h8300_register_offset[PT_EXR]) |= EXR_TRACE; -} - -asmlinkage void trace_trap(unsigned long bp) -{ - (void)bp; - force_sig(SIGTRAP,current); -} - diff --git a/arch/hexagon/Kconfig b/arch/hexagon/Kconfig index 99041b07e610..09df2608f40a 100644 --- a/arch/hexagon/Kconfig +++ b/arch/hexagon/Kconfig @@ -4,7 +4,6 @@ comment "Linux Kernel Configuration for Hexagon" config HEXAGON def_bool y select HAVE_OPROFILE - select USE_GENERIC_SMP_HELPERS if SMP # Other pending projects/to-do items. # select HAVE_REGS_AND_STACK_ACCESS_API # select HAVE_HW_BREAKPOINT if PERF_EVENTS diff --git a/arch/hexagon/include/asm/Kbuild b/arch/hexagon/include/asm/Kbuild index 1da17caac23c..67c3450309b7 100644 --- a/arch/hexagon/include/asm/Kbuild +++ b/arch/hexagon/include/asm/Kbuild @@ -53,3 +53,4 @@ generic-y += types.h generic-y += ucontext.h generic-y += unaligned.h generic-y += xor.h +generic-y += preempt.h diff --git a/arch/hexagon/include/asm/pgalloc.h b/arch/hexagon/include/asm/pgalloc.h index 679bf6d66487..4c9d382d7798 100644 --- a/arch/hexagon/include/asm/pgalloc.h +++ b/arch/hexagon/include/asm/pgalloc.h @@ -65,10 +65,12 @@ static inline struct page *pte_alloc_one(struct mm_struct *mm, struct page *pte; pte = alloc_page(GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO); - - if (pte) - pgtable_page_ctor(pte); - + if (!pte) + return NULL; + if (!pgtable_page_ctor(pte)) { + __free_page(pte); + return NULL; + } return pte; } diff --git a/arch/hexagon/include/asm/thread_info.h b/arch/hexagon/include/asm/thread_info.h index f7c32406a711..a59dad3b3695 100644 --- a/arch/hexagon/include/asm/thread_info.h +++ b/arch/hexagon/include/asm/thread_info.h @@ -73,10 +73,6 @@ struct thread_info { #endif /* __ASSEMBLY__ */ -/* looks like "linux/hardirq.h" uses this. */ - -#define PREEMPT_ACTIVE 0x10000000 - #ifndef __ASSEMBLY__ #define INIT_THREAD_INFO(tsk) \ diff --git a/arch/hexagon/kernel/setup.c b/arch/hexagon/kernel/setup.c index 29d1f1b00016..0e7c1dbb37b2 100644 --- a/arch/hexagon/kernel/setup.c +++ b/arch/hexagon/kernel/setup.c @@ -32,9 +32,6 @@ #include <asm/hexagon_vm.h> #include <asm/vm_mmu.h> #include <asm/time.h> -#ifdef CONFIG_OF -#include <asm/prom.h> -#endif char cmd_line[COMMAND_LINE_SIZE]; static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE; diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 7740ab10a171..4e4119b0e691 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -6,6 +6,7 @@ menu "Processor type and features" config IA64 bool + select ARCH_MIGHT_HAVE_PC_PARPORT select PCI if (!IA64_HP_SIM) select ACPI if (!IA64_HP_SIM) select PM if (!IA64_HP_SIM) @@ -343,7 +344,6 @@ config FORCE_MAX_ZONEORDER config SMP bool "Symmetric multi-processing support" - select USE_GENERIC_SMP_HELPERS help This enables support for systems with more than one CPU. If you have a system with only one CPU, say N. If you have a system with more diff --git a/arch/ia64/include/asm/Kbuild b/arch/ia64/include/asm/Kbuild index a3456f34f672..f93ee087e8fe 100644 --- a/arch/ia64/include/asm/Kbuild +++ b/arch/ia64/include/asm/Kbuild @@ -3,4 +3,5 @@ generic-y += clkdev.h generic-y += exec.h generic-y += kvm_para.h generic-y += trace_clock.h +generic-y += preempt.h generic-y += vtime.h
\ No newline at end of file diff --git a/arch/ia64/include/asm/io.h b/arch/ia64/include/asm/io.h index 74a7cc3293bc..0d2bcb37ec35 100644 --- a/arch/ia64/include/asm/io.h +++ b/arch/ia64/include/asm/io.h @@ -424,6 +424,7 @@ extern void __iomem * ioremap(unsigned long offset, unsigned long size); extern void __iomem * ioremap_nocache (unsigned long offset, unsigned long size); extern void iounmap (volatile void __iomem *addr); extern void __iomem * early_ioremap (unsigned long phys_addr, unsigned long size); +#define early_memremap(phys_addr, size) early_ioremap(phys_addr, size) extern void early_iounmap (volatile void __iomem *addr, unsigned long size); static inline void __iomem * ioremap_cache (unsigned long phys_addr, unsigned long size) { diff --git a/arch/ia64/include/asm/kvm_host.h b/arch/ia64/include/asm/kvm_host.h index 989dd3fe8de1..db95f570705f 100644 --- a/arch/ia64/include/asm/kvm_host.h +++ b/arch/ia64/include/asm/kvm_host.h @@ -234,10 +234,6 @@ struct kvm_vm_data { #define KVM_REQ_PTC_G 32 #define KVM_REQ_RESUME 33 -#define KVM_HPAGE_GFN_SHIFT(x) 0 -#define KVM_NR_PAGE_SIZES 1 -#define KVM_PAGES_PER_HPAGE(x) 1 - struct kvm; struct kvm_vcpu; @@ -480,7 +476,7 @@ struct kvm_arch { struct list_head assigned_dev_head; struct iommu_domain *iommu_domain; - int iommu_flags; + bool iommu_noncoherent; unsigned long irq_sources_bitmap; unsigned long irq_states[KVM_IOAPIC_NUM_PINS]; diff --git a/arch/ia64/include/asm/pgalloc.h b/arch/ia64/include/asm/pgalloc.h index 96a8d927db28..5767cdfc08db 100644 --- a/arch/ia64/include/asm/pgalloc.h +++ b/arch/ia64/include/asm/pgalloc.h @@ -91,7 +91,10 @@ static inline pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long addr) if (!pg) return NULL; page = virt_to_page(pg); - pgtable_page_ctor(page); + if (!pgtable_page_ctor(page)) { + quicklist_free(0, NULL, pg); + return NULL; + } return page; } diff --git a/arch/ia64/include/asm/processor.h b/arch/ia64/include/asm/processor.h index e0a899a1a8a6..5a84b3a50741 100644 --- a/arch/ia64/include/asm/processor.h +++ b/arch/ia64/include/asm/processor.h @@ -319,7 +319,7 @@ struct thread_struct { regs->loadrs = 0; \ regs->r8 = get_dumpable(current->mm); /* set "don't zap registers" flag */ \ regs->r12 = new_sp - 16; /* allocate 16 byte scratch area */ \ - if (unlikely(!get_dumpable(current->mm))) { \ + if (unlikely(get_dumpable(current->mm) != SUID_DUMP_USER)) { \ /* \ * Zap scratch regs to avoid leaking bits between processes with different \ * uid/privileges. \ diff --git a/arch/ia64/include/asm/thread_info.h b/arch/ia64/include/asm/thread_info.h index cade13dd0299..5957cf61f898 100644 --- a/arch/ia64/include/asm/thread_info.h +++ b/arch/ia64/include/asm/thread_info.h @@ -11,9 +11,6 @@ #include <asm/processor.h> #include <asm/ptrace.h> -#define PREEMPT_ACTIVE_BIT 30 -#define PREEMPT_ACTIVE (1 << PREEMPT_ACTIVE_BIT) - #ifndef __ASSEMBLY__ /* diff --git a/arch/ia64/include/asm/xen/page-coherent.h b/arch/ia64/include/asm/xen/page-coherent.h new file mode 100644 index 000000000000..96e42f97fa1f --- /dev/null +++ b/arch/ia64/include/asm/xen/page-coherent.h @@ -0,0 +1,38 @@ +#ifndef _ASM_IA64_XEN_PAGE_COHERENT_H +#define _ASM_IA64_XEN_PAGE_COHERENT_H + +#include <asm/page.h> +#include <linux/dma-attrs.h> +#include <linux/dma-mapping.h> + +static inline void *xen_alloc_coherent_pages(struct device *hwdev, size_t size, + dma_addr_t *dma_handle, gfp_t flags, + struct dma_attrs *attrs) +{ + void *vstart = (void*)__get_free_pages(flags, get_order(size)); + *dma_handle = virt_to_phys(vstart); + return vstart; +} + +static inline void xen_free_coherent_pages(struct device *hwdev, size_t size, + void *cpu_addr, dma_addr_t dma_handle, + struct dma_attrs *attrs) +{ + free_pages((unsigned long) cpu_addr, get_order(size)); +} + +static inline void xen_dma_map_page(struct device *hwdev, struct page *page, + unsigned long offset, size_t size, enum dma_data_direction dir, + struct dma_attrs *attrs) { } + +static inline void xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle, + size_t size, enum dma_data_direction dir, + struct dma_attrs *attrs) { } + +static inline void xen_dma_sync_single_for_cpu(struct device *hwdev, + dma_addr_t handle, size_t size, enum dma_data_direction dir) { } + +static inline void xen_dma_sync_single_for_device(struct device *hwdev, + dma_addr_t handle, size_t size, enum dma_data_direction dir) { } + +#endif /* _ASM_IA64_XEN_PAGE_COHERENT_H */ diff --git a/arch/ia64/include/uapi/asm/socket.h b/arch/ia64/include/uapi/asm/socket.h index 556d0701a155..c25302fb48d9 100644 --- a/arch/ia64/include/uapi/asm/socket.h +++ b/arch/ia64/include/uapi/asm/socket.h @@ -85,4 +85,6 @@ #define SO_BUSY_POLL 46 +#define SO_MAX_PACING_RATE 47 + #endif /* _ASM_IA64_SOCKET_H */ diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 5eb71d22c3d5..59d52e3aef12 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c @@ -882,40 +882,10 @@ __init void prefill_possible_map(void) set_cpu_possible(i, true); } -static int _acpi_map_lsapic(acpi_handle handle, int *pcpu) +static int _acpi_map_lsapic(acpi_handle handle, int physid, int *pcpu) { - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; - union acpi_object *obj; - struct acpi_madt_local_sapic *lsapic; cpumask_t tmp_map; - int cpu, physid; - - if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer))) - return -EINVAL; - - if (!buffer.length || !buffer.pointer) - return -EINVAL; - - obj = buffer.pointer; - if (obj->type != ACPI_TYPE_BUFFER) - { - kfree(buffer.pointer); - return -EINVAL; - } - - lsapic = (struct acpi_madt_local_sapic *)obj->buffer.pointer; - - if ((lsapic->header.type != ACPI_MADT_TYPE_LOCAL_SAPIC) || - (!(lsapic->lapic_flags & ACPI_MADT_ENABLED))) { - kfree(buffer.pointer); - return -EINVAL; - } - - physid = ((lsapic->id << 8) | (lsapic->eid)); - - kfree(buffer.pointer); - buffer.length = ACPI_ALLOCATE_BUFFER; - buffer.pointer = NULL; + int cpu; cpumask_complement(&tmp_map, cpu_present_mask); cpu = cpumask_first(&tmp_map); @@ -934,9 +904,9 @@ static int _acpi_map_lsapic(acpi_handle handle, int *pcpu) } /* wrapper to silence section mismatch warning */ -int __ref acpi_map_lsapic(acpi_handle handle, int *pcpu) +int __ref acpi_map_lsapic(acpi_handle handle, int physid, int *pcpu) { - return _acpi_map_lsapic(handle, pcpu); + return _acpi_map_lsapic(handle, physid, pcpu); } EXPORT_SYMBOL(acpi_map_lsapic); diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c index 51bce594eb83..da5b462e6de6 100644 --- a/arch/ia64/kernel/efi.c +++ b/arch/ia64/kernel/efi.c @@ -44,10 +44,15 @@ #define EFI_DEBUG 0 +static __initdata unsigned long palo_phys; + +static __initdata efi_config_table_type_t arch_tables[] = { + {PROCESSOR_ABSTRACTION_LAYER_OVERWRITE_GUID, "PALO", &palo_phys}, + {NULL_GUID, NULL, 0}, +}; + extern efi_status_t efi_call_phys (void *, ...); -struct efi efi; -EXPORT_SYMBOL(efi); static efi_runtime_services_t *runtime; static u64 mem_limit = ~0UL, max_addr = ~0UL, min_addr = 0UL; @@ -423,9 +428,9 @@ static u8 __init palo_checksum(u8 *buffer, u32 length) * Parse and handle PALO table which is published at: * http://www.dig64.org/home/DIG64_PALO_R1_0.pdf */ -static void __init handle_palo(unsigned long palo_phys) +static void __init handle_palo(unsigned long phys_addr) { - struct palo_table *palo = __va(palo_phys); + struct palo_table *palo = __va(phys_addr); u8 checksum; if (strncmp(palo->signature, PALO_SIG, sizeof(PALO_SIG) - 1)) { @@ -467,12 +472,10 @@ void __init efi_init (void) { void *efi_map_start, *efi_map_end; - efi_config_table_t *config_tables; efi_char16_t *c16; u64 efi_desc_size; char *cp, vendor[100] = "unknown"; int i; - unsigned long palo_phys; /* * It's too early to be able to use the standard kernel command line @@ -514,8 +517,6 @@ efi_init (void) efi.systab->hdr.revision >> 16, efi.systab->hdr.revision & 0xffff); - config_tables = __va(efi.systab->tables); - /* Show what we know for posterity */ c16 = __va(efi.systab->fw_vendor); if (c16) { @@ -528,43 +529,10 @@ efi_init (void) efi.systab->hdr.revision >> 16, efi.systab->hdr.revision & 0xffff, vendor); - efi.mps = EFI_INVALID_TABLE_ADDR; - efi.acpi = EFI_INVALID_TABLE_ADDR; - efi.acpi20 = EFI_INVALID_TABLE_ADDR; - efi.smbios = EFI_INVALID_TABLE_ADDR; - efi.sal_systab = EFI_INVALID_TABLE_ADDR; - efi.boot_info = EFI_INVALID_TABLE_ADDR; - efi.hcdp = EFI_INVALID_TABLE_ADDR; - efi.uga = EFI_INVALID_TABLE_ADDR; - palo_phys = EFI_INVALID_TABLE_ADDR; - for (i = 0; i < (int) efi.systab->nr_tables; i++) { - if (efi_guidcmp(config_tables[i].guid, MPS_TABLE_GUID) == 0) { - efi.mps = config_tables[i].table; - printk(" MPS=0x%lx", config_tables[i].table); - } else if (efi_guidcmp(config_tables[i].guid, ACPI_20_TABLE_GUID) == 0) { - efi.acpi20 = config_tables[i].table; - printk(" ACPI 2.0=0x%lx", config_tables[i].table); - } else if (efi_guidcmp(config_tables[i].guid, ACPI_TABLE_GUID) == 0) { - efi.acpi = config_tables[i].table; - printk(" ACPI=0x%lx", config_tables[i].table); - } else if (efi_guidcmp(config_tables[i].guid, SMBIOS_TABLE_GUID) == 0) { - efi.smbios = config_tables[i].table; - printk(" SMBIOS=0x%lx", config_tables[i].table); - } else if (efi_guidcmp(config_tables[i].guid, SAL_SYSTEM_TABLE_GUID) == 0) { - efi.sal_systab = config_tables[i].table; - printk(" SALsystab=0x%lx", config_tables[i].table); - } else if (efi_guidcmp(config_tables[i].guid, HCDP_TABLE_GUID) == 0) { - efi.hcdp = config_tables[i].table; - printk(" HCDP=0x%lx", config_tables[i].table); - } else if (efi_guidcmp(config_tables[i].guid, - PROCESSOR_ABSTRACTION_LAYER_OVERWRITE_GUID) == 0) { - palo_phys = config_tables[i].table; - printk(" PALO=0x%lx", config_tables[i].table); - } - } - printk("\n"); + if (efi_config_init(arch_tables) != 0) + return; if (palo_phys != EFI_INVALID_TABLE_ADDR) handle_palo(palo_phys); diff --git a/arch/ia64/kernel/elfcore.c b/arch/ia64/kernel/elfcore.c index bac1639bc320..04bc8fd5f893 100644 --- a/arch/ia64/kernel/elfcore.c +++ b/arch/ia64/kernel/elfcore.c @@ -11,8 +11,7 @@ Elf64_Half elf_core_extra_phdrs(void) return GATE_EHDR->e_phnum; } -int elf_core_write_extra_phdrs(struct file *file, loff_t offset, size_t *size, - unsigned long limit) +int elf_core_write_extra_phdrs(struct coredump_params *cprm, loff_t offset) { const struct elf_phdr *const gate_phdrs = (const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff); @@ -35,15 +34,13 @@ int elf_core_write_extra_phdrs(struct file *file, loff_t offset, size_t *size, phdr.p_offset += ofs; } phdr.p_paddr = 0; /* match other core phdrs */ - *size += sizeof(phdr); - if (*size > limit || !dump_write(file, &phdr, sizeof(phdr))) + if (!dump_emit(cprm, &phdr, sizeof(phdr))) return 0; } return 1; } -int elf_core_write_extra_data(struct file *file, size_t *size, - unsigned long limit) +int elf_core_write_extra_data(struct coredump_params *cprm) { const struct elf_phdr *const gate_phdrs = (const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff); @@ -54,8 +51,7 @@ int elf_core_write_extra_data(struct file *file, size_t *size, void *addr = (void *)gate_phdrs[i].p_vaddr; size_t memsz = PAGE_ALIGN(gate_phdrs[i].p_memsz); - *size += memsz; - if (*size > limit || !dump_write(file, addr, memsz)) + if (!dump_emit(cprm, addr, memsz)) return 0; break; } diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index 7a53530f22c2..ddea607f948a 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -1169,21 +1169,8 @@ skip_rbs_switch: .work_pending: tbit.z p6,p0=r31,TIF_NEED_RESCHED // is resched not needed? (p6) br.cond.sptk.few .notify -#ifdef CONFIG_PREEMPT -(pKStk) dep r21=-1,r0,PREEMPT_ACTIVE_BIT,1 - ;; -(pKStk) st4 [r20]=r21 -#endif - SSM_PSR_I(p0, p6, r2) // enable interrupts - br.call.spnt.many rp=schedule + br.call.spnt.many rp=preempt_schedule_irq .ret9: cmp.eq p6,p0=r0,r0 // p6 <- 1 (re-check) - RSM_PSR_I(p0, r2, r20) // disable interrupts - ;; -#ifdef CONFIG_PREEMPT -(pKStk) adds r20=TI_PRE_COUNT+IA64_TASK_SIZE,r13 - ;; -(pKStk) st4 [r20]=r0 // preempt_count() <- 0 -#endif (pLvSys)br.cond.sptk.few __paravirt_pending_syscall_end br.cond.sptk.many .work_processed_kernel diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c index f8280a766a78..074fde49c9e6 100644 --- a/arch/ia64/kernel/kprobes.c +++ b/arch/ia64/kernel/kprobes.c @@ -947,7 +947,7 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) case KPROBE_HIT_SSDONE: /* * We increment the nmissed count for accounting, - * we can also use npre/npostfault count for accouting + * we can also use npre/npostfault count for accounting * these specific fault cases. */ kprobes_inc_nmissed_count(cur); diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index 4fc2e9569bb2..d86669bcdfb2 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -1063,6 +1063,7 @@ check_bugs (void) static int __init run_dmi_scan(void) { dmi_scan_machine(); + dmi_memdev_walk(); dmi_set_dump_stack_arch_desc(); return 0; } diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c index 3637e03d2282..33cab9a8adff 100644 --- a/arch/ia64/kernel/signal.c +++ b/arch/ia64/kernel/signal.c @@ -105,7 +105,7 @@ restore_sigcontext (struct sigcontext __user *sc, struct sigscratch *scr) } int -copy_siginfo_to_user (siginfo_t __user *to, siginfo_t *from) +copy_siginfo_to_user (siginfo_t __user *to, const siginfo_t *from) { if (!access_ok(VERIFY_WRITE, to, sizeof(siginfo_t))) return -EFAULT; diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index bdfd8789b376..985bf80c622e 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c @@ -1550,12 +1550,13 @@ int kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf) return VM_FAULT_SIGBUS; } -void kvm_arch_free_memslot(struct kvm_memory_slot *free, +void kvm_arch_free_memslot(struct kvm *kvm, struct kvm_memory_slot *free, struct kvm_memory_slot *dont) { } -int kvm_arch_create_memslot(struct kvm_memory_slot *slot, unsigned long npages) +int kvm_arch_create_memslot(struct kvm *kvm, struct kvm_memory_slot *slot, + unsigned long npages) { return 0; } diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index b6f7f43424ec..88504abf5704 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c @@ -357,9 +357,7 @@ int vmemmap_find_next_valid_pfn(int node, int i) end_address = (unsigned long) &vmem_map[pgdat->node_start_pfn + i]; end_address = PAGE_ALIGN(end_address); - - stop_address = (unsigned long) &vmem_map[ - pgdat->node_start_pfn + pgdat->node_spanned_pages]; + stop_address = (unsigned long) &vmem_map[pgdat_end_pfn(pgdat)]; do { pgd_t *pgd; diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig index 75661fbf4529..09ef94a8a7c3 100644 --- a/arch/m32r/Kconfig +++ b/arch/m32r/Kconfig @@ -275,7 +275,6 @@ source "kernel/Kconfig.preempt" config SMP bool "Symmetric multi-processing support" - select USE_GENERIC_SMP_HELPERS ---help--- This enables support for systems with more than one CPU. If you have a system with only one CPU, like most personal computers, say N. If diff --git a/arch/m32r/include/asm/Kbuild b/arch/m32r/include/asm/Kbuild index bebdc36ebb0a..2b58c5f0bc38 100644 --- a/arch/m32r/include/asm/Kbuild +++ b/arch/m32r/include/asm/Kbuild @@ -3,3 +3,4 @@ generic-y += clkdev.h generic-y += exec.h generic-y += module.h generic-y += trace_clock.h +generic-y += preempt.h diff --git a/arch/m32r/include/asm/hardirq.h b/arch/m32r/include/asm/hardirq.h index 4c31c0ae215e..5f2ac4f64ddf 100644 --- a/arch/m32r/include/asm/hardirq.h +++ b/arch/m32r/include/asm/hardirq.h @@ -3,22 +3,6 @@ #define __ASM_HARDIRQ_H #include <asm/irq.h> - -#if NR_IRQS > 256 -#define HARDIRQ_BITS 9 -#else -#define HARDIRQ_BITS 8 -#endif - -/* - * The hardirq mask has to be large enough to have - * space for potentially all IRQ sources in the system - * nesting on a single CPU: - */ -#if (1 << HARDIRQ_BITS) < NR_IRQS -# error HARDIRQ_BITS is too low! -#endif - #include <asm-generic/hardirq.h> #endif /* __ASM_HARDIRQ_H */ diff --git a/arch/m32r/include/asm/mmu_context.h b/arch/m32r/include/asm/mmu_context.h index a979a4198168..9fc78fc44445 100644 --- a/arch/m32r/include/asm/mmu_context.h +++ b/arch/m32r/include/asm/mmu_context.h @@ -45,7 +45,7 @@ static inline void get_new_mmu_context(struct mm_struct *mm) Flush all TLB and start new cycle. */ local_flush_tlb_all(); /* Fix version if needed. - Note that we avoid version #0 to distingush NO_CONTEXT. */ + Note that we avoid version #0 to distinguish NO_CONTEXT. */ if (!mc) mmu_context_cache = mc = MMU_CONTEXT_FIRST_VERSION; } diff --git a/arch/m32r/include/asm/pgalloc.h b/arch/m32r/include/asm/pgalloc.h index 0fc736198979..2d55a064ccac 100644 --- a/arch/m32r/include/asm/pgalloc.h +++ b/arch/m32r/include/asm/pgalloc.h @@ -43,7 +43,12 @@ static __inline__ pgtable_t pte_alloc_one(struct mm_struct *mm, { struct page *pte = alloc_page(GFP_KERNEL|__GFP_ZERO); - pgtable_page_ctor(pte); + if (!pte) + return NULL; + if (!pgtable_page_ctor(pte)) { + __free_page(pte); + return NULL; + } return pte; } diff --git a/arch/m32r/include/asm/thread_info.h b/arch/m32r/include/asm/thread_info.h index c074f4c2e858..00171703402f 100644 --- a/arch/m32r/include/asm/thread_info.h +++ b/arch/m32r/include/asm/thread_info.h @@ -53,8 +53,6 @@ struct thread_info { #endif -#define PREEMPT_ACTIVE 0x10000000 - #define THREAD_SIZE (PAGE_SIZE << 1) #define THREAD_SIZE_ORDER 1 /* diff --git a/arch/m32r/include/uapi/asm/socket.h b/arch/m32r/include/uapi/asm/socket.h index 24be7c8da86a..52966650114f 100644 --- a/arch/m32r/include/uapi/asm/socket.h +++ b/arch/m32r/include/uapi/asm/socket.h @@ -76,4 +76,6 @@ #define SO_BUSY_POLL 46 +#define SO_MAX_PACING_RATE 47 + #endif /* _ASM_M32R_SOCKET_H */ diff --git a/arch/m32r/kernel/entry.S b/arch/m32r/kernel/entry.S index 0c01543f10cd..7c3db9940ce1 100644 --- a/arch/m32r/kernel/entry.S +++ b/arch/m32r/kernel/entry.S @@ -182,13 +182,7 @@ need_resched: ld r4, PSW(sp) ; interrupts off (exception path) ? and3 r4, r4, #0x4000 beqz r4, restore_all - LDIMM (r4, PREEMPT_ACTIVE) - st r4, @(TI_PRE_COUNT, r8) - ENABLE_INTERRUPTS(r4) - bl schedule - ldi r4, #0 - st r4, @(TI_PRE_COUNT, r8) - DISABLE_INTERRUPTS(r4) + bl preempt_schedule_irq bra need_resched #endif diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index 311a300d48cc..75f25a8e3001 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -1,6 +1,7 @@ config M68K bool default y + select ARCH_MIGHT_HAVE_PC_PARPORT if ISA select HAVE_IDE select HAVE_AOUT if MMU select HAVE_DEBUG_BUGVERBOSE diff --git a/arch/m68k/include/asm/Kbuild b/arch/m68k/include/asm/Kbuild index 09d77a862da3..a5d27f272a59 100644 --- a/arch/m68k/include/asm/Kbuild +++ b/arch/m68k/include/asm/Kbuild @@ -31,3 +31,4 @@ generic-y += trace_clock.h generic-y += types.h generic-y += word-at-a-time.h generic-y += xor.h +generic-y += preempt.h diff --git a/arch/m68k/include/asm/floppy.h b/arch/m68k/include/asm/floppy.h index 697d50393dd0..47365b1ccbec 100644 --- a/arch/m68k/include/asm/floppy.h +++ b/arch/m68k/include/asm/floppy.h @@ -85,7 +85,7 @@ static int fd_request_irq(void) { if(MACH_IS_Q40) return request_irq(FLOPPY_IRQ, floppy_hardint, - IRQF_DISABLED, "floppy", floppy_hardint); + 0, "floppy", floppy_hardint); else if(MACH_IS_SUN3X) return sun3xflop_request_irq(); return -ENXIO; diff --git a/arch/m68k/include/asm/hardirq.h b/arch/m68k/include/asm/hardirq.h index db30ed276878..6c618529d9b9 100644 --- a/arch/m68k/include/asm/hardirq.h +++ b/arch/m68k/include/asm/hardirq.h @@ -5,17 +5,6 @@ #include <linux/cache.h> #include <asm/irq.h> -#define HARDIRQ_BITS 8 - -/* - * The hardirq mask has to be large enough to have - * space for potentially all IRQ sources in the system - * nesting on a single CPU: - */ -#if (1 << HARDIRQ_BITS) < NR_IRQS -# error HARDIRQ_BITS is too low! -#endif - #ifdef CONFIG_MMU static inline void ack_bad_irq(unsigned int irq) diff --git a/arch/m68k/include/asm/mcf_pgalloc.h b/arch/m68k/include/asm/mcf_pgalloc.h index 313f3dd23cdc..f9924fbcfe42 100644 --- a/arch/m68k/include/asm/mcf_pgalloc.h +++ b/arch/m68k/include/asm/mcf_pgalloc.h @@ -56,6 +56,10 @@ static inline struct page *pte_alloc_one(struct mm_struct *mm, if (!page) return NULL; + if (!pgtable_page_ctor(page)) { + __free_page(page); + return NULL; + } pte = kmap(page); if (pte) { diff --git a/arch/m68k/include/asm/motorola_pgalloc.h b/arch/m68k/include/asm/motorola_pgalloc.h index 2f02f264e694..24bcba496c75 100644 --- a/arch/m68k/include/asm/motorola_pgalloc.h +++ b/arch/m68k/include/asm/motorola_pgalloc.h @@ -29,18 +29,22 @@ static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) static inline pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address) { - struct page *page = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0); + struct page *page; pte_t *pte; + page = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0); if(!page) return NULL; + if (!pgtable_page_ctor(page)) { + __free_page(page); + return NULL; + } pte = kmap(page); __flush_page_to_ram(pte); flush_tlb_kernel_page(pte); nocache_page(pte); kunmap(page); - pgtable_page_ctor(page); return page; } diff --git a/arch/m68k/include/asm/sun3_pgalloc.h b/arch/m68k/include/asm/sun3_pgalloc.h index 48d80d5a666f..f868506e3350 100644 --- a/arch/m68k/include/asm/sun3_pgalloc.h +++ b/arch/m68k/include/asm/sun3_pgalloc.h @@ -59,7 +59,10 @@ static inline pgtable_t pte_alloc_one(struct mm_struct *mm, return NULL; clear_highpage(page); - pgtable_page_ctor(page); + if (!pgtable_page_ctor(page)) { + __free_page(page); + return NULL; + } return page; } diff --git a/arch/m68k/include/asm/sun3xflop.h b/arch/m68k/include/asm/sun3xflop.h index 95231e2f9d64..a02ea3a7bb20 100644 --- a/arch/m68k/include/asm/sun3xflop.h +++ b/arch/m68k/include/asm/sun3xflop.h @@ -207,7 +207,7 @@ static int sun3xflop_request_irq(void) if(!once) { once = 1; error = request_irq(FLOPPY_IRQ, sun3xflop_hardint, - IRQF_DISABLED, "floppy", NULL); + 0, "floppy", NULL); return ((error == 0) ? 0 : -1); } else return 0; } diff --git a/arch/m68k/include/asm/thread_info.h b/arch/m68k/include/asm/thread_info.h index 126131f94a2c..21a4784ca5a1 100644 --- a/arch/m68k/include/asm/thread_info.h +++ b/arch/m68k/include/asm/thread_info.h @@ -35,8 +35,6 @@ struct thread_info { }; #endif /* __ASSEMBLY__ */ -#define PREEMPT_ACTIVE 0x4000000 - #define INIT_THREAD_INFO(tsk) \ { \ .task = &tsk, \ diff --git a/arch/m68k/include/asm/uaccess.h b/arch/m68k/include/asm/uaccess.h index 639c731568b0..3fadc4a93d97 100644 --- a/arch/m68k/include/asm/uaccess.h +++ b/arch/m68k/include/asm/uaccess.h @@ -3,3 +3,10 @@ #else #include <asm/uaccess_mm.h> #endif + +#ifdef CONFIG_CPU_HAS_NO_UNALIGNED +#include <asm-generic/uaccess-unaligned.h> +#else +#define __get_user_unaligned(x, ptr) __get_user((x), (ptr)) +#define __put_user_unaligned(x, ptr) __put_user((x), (ptr)) +#endif diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S index a78f5649e8de..b54ac7aba850 100644 --- a/arch/m68k/kernel/entry.S +++ b/arch/m68k/kernel/entry.S @@ -45,7 +45,7 @@ .globl system_call, buserr, trap, resume .globl sys_call_table .globl __sys_fork, __sys_clone, __sys_vfork -.globl ret_from_interrupt, bad_interrupt +.globl bad_interrupt .globl auto_irqhandler_fixup .globl user_irqvec_fixup @@ -275,8 +275,6 @@ do_delayed_trace: ENTRY(auto_inthandler) SAVE_ALL_INT GET_CURRENT(%d0) - movel %d0,%a1 - addqb #1,%a1@(TINFO_PREEMPT+1) | put exception # in d0 bfextu %sp@(PT_OFF_FORMATVEC){#4,#10},%d0 subw #VEC_SPUR,%d0 @@ -286,32 +284,13 @@ ENTRY(auto_inthandler) auto_irqhandler_fixup = . + 2 jsr do_IRQ | process the IRQ addql #8,%sp | pop parameters off stack - -ret_from_interrupt: - movel %curptr@(TASK_STACK),%a1 - subqb #1,%a1@(TINFO_PREEMPT+1) - jeq ret_from_last_interrupt -2: RESTORE_ALL - - ALIGN -ret_from_last_interrupt: - moveq #(~ALLOWINT>>8)&0xff,%d0 - andb %sp@(PT_OFF_SR),%d0 - jne 2b - - /* check if we need to do software interrupts */ - tstl irq_stat+CPUSTAT_SOFTIRQ_PENDING - jeq .Lret_from_exception - pea ret_from_exception - jra do_softirq + jra ret_from_exception /* Handler for user defined interrupt vectors */ ENTRY(user_inthandler) SAVE_ALL_INT GET_CURRENT(%d0) - movel %d0,%a1 - addqb #1,%a1@(TINFO_PREEMPT+1) | put exception # in d0 bfextu %sp@(PT_OFF_FORMATVEC){#4,#10},%d0 user_irqvec_fixup = . + 2 @@ -321,29 +300,18 @@ user_irqvec_fixup = . + 2 movel %d0,%sp@- | put vector # on stack jsr do_IRQ | process the IRQ addql #8,%sp | pop parameters off stack - - movel %curptr@(TASK_STACK),%a1 - subqb #1,%a1@(TINFO_PREEMPT+1) - jeq ret_from_last_interrupt - RESTORE_ALL + jra ret_from_exception /* Handler for uninitialized and spurious interrupts */ ENTRY(bad_inthandler) SAVE_ALL_INT GET_CURRENT(%d0) - movel %d0,%a1 - addqb #1,%a1@(TINFO_PREEMPT+1) movel %sp,%sp@- jsr handle_badint addql #4,%sp - - movel %curptr@(TASK_STACK),%a1 - subqb #1,%a1@(TINFO_PREEMPT+1) - jeq ret_from_last_interrupt - RESTORE_ALL - + jra ret_from_exception resume: /* diff --git a/arch/m68k/kernel/ints.c b/arch/m68k/kernel/ints.c index 4d7da384eea0..077d3a70fed1 100644 --- a/arch/m68k/kernel/ints.c +++ b/arch/m68k/kernel/ints.c @@ -58,12 +58,6 @@ void __init init_IRQ(void) { int i; - /* assembly irq entry code relies on this... */ - if (HARDIRQ_MASK != 0x00ff0000) { - extern void hardirq_mask_is_broken(void); - hardirq_mask_is_broken(); - } - for (i = IRQ_AUTO_1; i <= IRQ_AUTO_7; i++) irq_set_chip_and_handler(i, &auto_irq_chip, handle_simple_irq); diff --git a/arch/m68k/platform/68000/entry.S b/arch/m68k/platform/68000/entry.S index 7f91c2fde509..23ac054c6e1a 100644 --- a/arch/m68k/platform/68000/entry.S +++ b/arch/m68k/platform/68000/entry.S @@ -27,7 +27,6 @@ .globl ret_from_exception .globl ret_from_signal .globl sys_call_table -.globl ret_from_interrupt .globl bad_interrupt .globl inthandler1 .globl inthandler2 @@ -137,7 +136,7 @@ inthandler1: movel #65,%sp@- /* put vector # on stack*/ jbsr process_int /* process the IRQ*/ 3: addql #8,%sp /* pop parameters off stack*/ - bra ret_from_interrupt + bra ret_from_exception inthandler2: SAVE_ALL_INT @@ -148,7 +147,7 @@ inthandler2: movel #66,%sp@- /* put vector # on stack*/ jbsr process_int /* process the IRQ*/ 3: addql #8,%sp /* pop parameters off stack*/ - bra ret_from_interrupt + bra ret_from_exception inthandler3: SAVE_ALL_INT @@ -159,7 +158,7 @@ inthandler3: movel #67,%sp@- /* put vector # on stack*/ jbsr process_int /* process the IRQ*/ 3: addql #8,%sp /* pop parameters off stack*/ - bra ret_from_interrupt + bra ret_from_exception inthandler4: SAVE_ALL_INT @@ -170,7 +169,7 @@ inthandler4: movel #68,%sp@- /* put vector # on stack*/ jbsr process_int /* process the IRQ*/ 3: addql #8,%sp /* pop parameters off stack*/ - bra ret_from_interrupt + bra ret_from_exception inthandler5: SAVE_ALL_INT @@ -181,7 +180,7 @@ inthandler5: movel #69,%sp@- /* put vector # on stack*/ jbsr process_int /* process the IRQ*/ 3: addql #8,%sp /* pop parameters off stack*/ - bra ret_from_interrupt + bra ret_from_exception inthandler6: SAVE_ALL_INT @@ -192,7 +191,7 @@ inthandler6: movel #70,%sp@- /* put vector # on stack*/ jbsr process_int /* process the IRQ*/ 3: addql #8,%sp /* pop parameters off stack*/ - bra ret_from_interrupt + bra ret_from_exception inthandler7: SAVE_ALL_INT @@ -203,7 +202,7 @@ inthandler7: movel #71,%sp@- /* put vector # on stack*/ jbsr process_int /* process the IRQ*/ 3: addql #8,%sp /* pop parameters off stack*/ - bra ret_from_interrupt + bra ret_from_exception inthandler: SAVE_ALL_INT @@ -214,23 +213,7 @@ inthandler: movel %d0,%sp@- /* put vector # on stack*/ jbsr process_int /* process the IRQ*/ 3: addql #8,%sp /* pop parameters off stack*/ - bra ret_from_interrupt - -ret_from_interrupt: - jeq 1f -2: - RESTORE_ALL -1: - moveb %sp@(PT_OFF_SR), %d0 - and #7, %d0 - jhi 2b - - /* check if we need to do software interrupts */ - jeq ret_from_exception - - pea ret_from_exception - jra do_softirq - + bra ret_from_exception /* * Handler for uninitialized and spurious interrupts. diff --git a/arch/m68k/platform/68000/timers.c b/arch/m68k/platform/68000/timers.c index ec30acbfe6db..99a98698bc95 100644 --- a/arch/m68k/platform/68000/timers.c +++ b/arch/m68k/platform/68000/timers.c @@ -70,7 +70,7 @@ static irqreturn_t hw_tick(int irq, void *dummy) static struct irqaction m68328_timer_irq = { .name = "timer", - .flags = IRQF_DISABLED | IRQF_TIMER, + .flags = IRQF_TIMER, .handler = hw_tick, }; diff --git a/arch/m68k/platform/68360/config.c b/arch/m68k/platform/68360/config.c index 0570741e5500..d493ac43fe3f 100644 --- a/arch/m68k/platform/68360/config.c +++ b/arch/m68k/platform/68360/config.c @@ -59,7 +59,7 @@ static irqreturn_t hw_tick(int irq, void *dummy) static struct irqaction m68360_timer_irq = { .name = "timer", - .flags = IRQF_DISABLED | IRQF_TIMER, + .flags = IRQF_TIMER, .handler = hw_tick, }; diff --git a/arch/m68k/platform/68360/entry.S b/arch/m68k/platform/68360/entry.S index 904fd9a4af4e..447c33ef37fd 100644 --- a/arch/m68k/platform/68360/entry.S +++ b/arch/m68k/platform/68360/entry.S @@ -29,7 +29,6 @@ .globl ret_from_exception .globl ret_from_signal .globl sys_call_table -.globl ret_from_interrupt .globl bad_interrupt .globl inthandler @@ -132,26 +131,9 @@ inthandler: movel %sp,%sp@- movel %d0,%sp@- /* put vector # on stack*/ - jbsr do_IRQ /* process the IRQ*/ -3: addql #8,%sp /* pop parameters off stack*/ - bra ret_from_interrupt - -ret_from_interrupt: - jeq 1f -2: - RESTORE_ALL -1: - moveb %sp@(PT_OFF_SR), %d0 - and #7, %d0 - jhi 2b - /* check if we need to do software interrupts */ - - movel irq_stat+CPUSTAT_SOFTIRQ_PENDING,%d0 - jeq ret_from_exception - - pea ret_from_exception - jra do_softirq - + jbsr do_IRQ /* process the IRQ */ + addql #8,%sp /* pop parameters off stack*/ + jra ret_from_exception /* * Handler for uninitialized and spurious interrupts. diff --git a/arch/m68k/platform/coldfire/pit.c b/arch/m68k/platform/coldfire/pit.c index e8f3b97b0f77..493b3111d4c1 100644 --- a/arch/m68k/platform/coldfire/pit.c +++ b/arch/m68k/platform/coldfire/pit.c @@ -118,7 +118,7 @@ static irqreturn_t pit_tick(int irq, void *dummy) static struct irqaction pit_irq = { .name = "timer", - .flags = IRQF_DISABLED | IRQF_TIMER, + .flags = IRQF_TIMER, .handler = pit_tick, }; diff --git a/arch/m68k/platform/coldfire/sltimers.c b/arch/m68k/platform/coldfire/sltimers.c index bb5a25ada848..831a08cf6f40 100644 --- a/arch/m68k/platform/coldfire/sltimers.c +++ b/arch/m68k/platform/coldfire/sltimers.c @@ -51,7 +51,7 @@ irqreturn_t mcfslt_profile_tick(int irq, void *dummy) static struct irqaction mcfslt_profile_irq = { .name = "profile timer", - .flags = IRQF_DISABLED | IRQF_TIMER, + .flags = IRQF_TIMER, .handler = mcfslt_profile_tick, }; @@ -93,7 +93,7 @@ static irqreturn_t mcfslt_tick(int irq, void *dummy) static struct irqaction mcfslt_timer_irq = { .name = "timer", - .flags = IRQF_DISABLED | IRQF_TIMER, + .flags = IRQF_TIMER, .handler = mcfslt_tick, }; diff --git a/arch/m68k/platform/coldfire/timers.c b/arch/m68k/platform/coldfire/timers.c index d06068e45764..cd496a20fcc7 100644 --- a/arch/m68k/platform/coldfire/timers.c +++ b/arch/m68k/platform/coldfire/timers.c @@ -83,7 +83,7 @@ static irqreturn_t mcftmr_tick(int irq, void *dummy) static struct irqaction mcftmr_timer_irq = { .name = "timer", - .flags = IRQF_DISABLED | IRQF_TIMER, + .flags = IRQF_TIMER, .handler = mcftmr_tick, }; @@ -171,7 +171,7 @@ irqreturn_t coldfire_profile_tick(int irq, void *dummy) static struct irqaction coldfire_profile_irq = { .name = "profile timer", - .flags = IRQF_DISABLED | IRQF_TIMER, + .flags = IRQF_TIMER, .handler = coldfire_profile_tick, }; diff --git a/arch/metag/Kconfig b/arch/metag/Kconfig index 36368eb07e13..e56abd2c1b4f 100644 --- a/arch/metag/Kconfig +++ b/arch/metag/Kconfig @@ -111,7 +111,6 @@ config METAG_META21 config SMP bool "Symmetric multi-processing support" depends on METAG_META21 && METAG_META21_MMU - select USE_GENERIC_SMP_HELPERS help This enables support for systems with more than one thread running Linux. If you have a system with only one thread running Linux, diff --git a/arch/metag/include/asm/Kbuild b/arch/metag/include/asm/Kbuild index 6ae0ccb632cb..84d0c1d6b9b3 100644 --- a/arch/metag/include/asm/Kbuild +++ b/arch/metag/include/asm/Kbuild @@ -52,3 +52,4 @@ generic-y += unaligned.h generic-y += user.h generic-y += vga.h generic-y += xor.h +generic-y += preempt.h diff --git a/arch/metag/include/asm/mach/arch.h b/arch/metag/include/asm/mach/arch.h index 12c5664fea6e..433f94624fa2 100644 --- a/arch/metag/include/asm/mach/arch.h +++ b/arch/metag/include/asm/mach/arch.h @@ -53,7 +53,7 @@ struct machine_desc { /* * Current machine - only accessible during boot. */ -extern struct machine_desc *machine_desc; +extern const struct machine_desc *machine_desc; /* * Machine type table - also only accessible during boot diff --git a/arch/metag/include/asm/pgalloc.h b/arch/metag/include/asm/pgalloc.h index 275d9285141c..3104df0a4822 100644 --- a/arch/metag/include/asm/pgalloc.h +++ b/arch/metag/include/asm/pgalloc.h @@ -52,8 +52,12 @@ static inline pgtable_t pte_alloc_one(struct mm_struct *mm, { struct page *pte; pte = alloc_pages(GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO, 0); - if (pte) - pgtable_page_ctor(pte); + if (!pte) + return NULL; + if (!pgtable_page_ctor(pte)) { + __free_page(pte); + return NULL; + } return pte; } diff --git a/arch/metag/include/asm/prom.h b/arch/metag/include/asm/prom.h deleted file mode 100644 index d2aa35d2228e..000000000000 --- a/arch/metag/include/asm/prom.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * arch/metag/include/asm/prom.h - * - * Copyright (C) 2012 Imagination Technologies Ltd. - * - * Based on ARM version: - * Copyright (C) 2009 Canonical Ltd. <jeremy.kerr@canonical.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 - * published by the Free Software Foundation. - * - */ -#ifndef __ASM_METAG_PROM_H -#define __ASM_METAG_PROM_H - -#include <asm/setup.h> -#define HAVE_ARCH_DEVTREE_FIXUPS - -extern struct machine_desc *setup_machine_fdt(void *dt); -extern void copy_fdt(void); - -#endif /* __ASM_METAG_PROM_H */ diff --git a/arch/metag/include/asm/setup.h b/arch/metag/include/asm/setup.h index e13083b15dd0..e9fdee9452b1 100644 --- a/arch/metag/include/asm/setup.h +++ b/arch/metag/include/asm/setup.h @@ -3,6 +3,7 @@ #include <uapi/asm/setup.h> +extern const struct machine_desc *setup_machine_fdt(void *dt); void per_cpu_trap_init(unsigned long); extern void __init dump_machine_table(void); #endif /* _ASM_METAG_SETUP_H */ diff --git a/arch/metag/include/asm/tbx.h b/arch/metag/include/asm/tbx.h index 287b36ff8ad1..703b9cb0ac5c 100644 --- a/arch/metag/include/asm/tbx.h +++ b/arch/metag/include/asm/tbx.h @@ -150,11 +150,9 @@ #else /* Reserved 0x04-0x09 */ #endif -#define TBID_SIGNUM_SWS 0x0A /* KICK received with SigMask != 0 */ -#define TBID_SIGNUM_SWK 0x0B /* KICK received with SigMask == 0 */ -/* Reserved 0x0C-0x0F */ +/* Reserved 0x0A-0x0F */ #define TBID_SIGNUM_TRT 0x10 /* Timer trigger */ -#define TBID_SIGNUM_LWK 0x11 /* Low level kick (handler provided by TBI) */ +#define TBID_SIGNUM_LWK 0x11 /* Low level kick */ #define TBID_SIGNUM_XXF 0x12 /* Fault handler - receives ALL _xxF sigs */ #ifdef TBI_1_4 #define TBID_SIGNUM_DFR 0x13 /* Deferred Exception handler */ @@ -183,8 +181,7 @@ each hardware signal, sometimes this is a many-to-one relationship. */ #define TBI_TRIG_BIT(SigNum) (\ ((SigNum) >= TBID_SIGNUM_TRT) ? 1<<((SigNum)-TBID_SIGNUM_TRT) :\ - ( ((SigNum) == TBID_SIGNUM_SWS) || \ - ((SigNum) == TBID_SIGNUM_SWK) ) ? \ + ((SigNum) == TBID_SIGNUM_LWK) ? \ TXSTAT_KICK_BIT : TXSTATI_BGNDHALT_BIT ) /* Return the hardware trigger vector number for entries in the @@ -687,10 +684,8 @@ typedef union _tbires_tag_ { Triggers will indicate the status of TXSTAT or TXSTATI sampled by the code that called the handler. - InstOrSWSId is defined firstly as 'Inst' if the SigNum is TBID_SIGNUM_SWx - and hold the actual SWITCH instruction detected, secondly if SigNum - is TBID_SIGNUM_SWS the 'SWSId' is defined to hold the Id of the - software signal detected, in other cases the value of this + Inst is defined as 'Inst' if the SigNum is TBID_SIGNUM_SWx and holds the + actual SWITCH instruction detected, in other cases the value of this parameter is undefined. pTBI points at the PTBI structure related to the thread and processing @@ -709,7 +704,7 @@ typedef union _tbires_tag_ { */ typedef TBIRES (*PTBIAPIFN)( TBIRES State, int SigNum, - int Triggers, int InstOrSWSId, + int Triggers, int Inst, volatile struct _tbi_tag_ *pTBI ); #endif /* ifndef __ASSEMBLY__ */ @@ -757,7 +752,7 @@ typedef volatile struct _tbi_tag_ { #ifndef __ASSEMBLY__ /* This handler should be used for TBID_SIGNUM_DFR */ extern TBIRES __TBIHandleDFR ( TBIRES State, int SigNum, - int Triggers, int InstOrSWSId, + int Triggers, int Inst, volatile struct _tbi_tag_ *pTBI ); #endif #endif diff --git a/arch/metag/include/asm/thread_info.h b/arch/metag/include/asm/thread_info.h index 7c4a33006142..b19e9c588a16 100644 --- a/arch/metag/include/asm/thread_info.h +++ b/arch/metag/include/asm/thread_info.h @@ -46,8 +46,6 @@ struct thread_info { #endif -#define PREEMPT_ACTIVE 0x10000000 - #ifdef CONFIG_4KSTACKS #define THREAD_SHIFT 12 #else diff --git a/arch/metag/include/asm/topology.h b/arch/metag/include/asm/topology.h index 23f5118f58db..8e9c0b3b9691 100644 --- a/arch/metag/include/asm/topology.h +++ b/arch/metag/include/asm/topology.h @@ -26,6 +26,8 @@ .last_balance = jiffies, \ .balance_interval = 1, \ .nr_balance_failed = 0, \ + .max_newidle_lb_cost = 0, \ + .next_decay_max_lb_cost = jiffies, \ } #define cpu_to_node(cpu) ((void)(cpu), 0) diff --git a/arch/metag/kernel/devtree.c b/arch/metag/kernel/devtree.c index 7cd02529636e..18dd7aea9fdc 100644 --- a/arch/metag/kernel/devtree.c +++ b/arch/metag/kernel/devtree.c @@ -34,6 +34,19 @@ void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) return alloc_bootmem_align(size, align); } +static const void * __init arch_get_next_mach(const char *const **match) +{ + static const struct machine_desc *mdesc = __arch_info_begin; + const struct machine_desc *m = mdesc; + + if (m >= __arch_info_end) + return NULL; + + mdesc++; + *match = m->dt_compat; + return m; +} + /** * setup_machine_fdt - Machine setup when an dtb was passed to the kernel * @dt: virtual address pointer to dt blob @@ -41,74 +54,18 @@ void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) * If a dtb was passed to the kernel, then use it to choose the correct * machine_desc and to setup the system. */ -struct machine_desc * __init setup_machine_fdt(void *dt) +const struct machine_desc * __init setup_machine_fdt(void *dt) { - struct boot_param_header *devtree = dt; - struct machine_desc *mdesc, *mdesc_best = NULL; - unsigned int score, mdesc_score = ~1; - unsigned long dt_root; - const char *model; + const struct machine_desc *mdesc; /* check device tree validity */ - if (be32_to_cpu(devtree->magic) != OF_DT_HEADER) + if (!early_init_dt_scan(dt)) return NULL; - /* Search the mdescs for the 'best' compatible value match */ - initial_boot_params = devtree; - dt_root = of_get_flat_dt_root(); - - for_each_machine_desc(mdesc) { - score = of_flat_dt_match(dt_root, mdesc->dt_compat); - if (score > 0 && score < mdesc_score) { - mdesc_best = mdesc; - mdesc_score = score; - } - } - if (!mdesc_best) { - const char *prop; - long size; - - pr_err("\nError: unrecognized/unsupported device tree compatible list:\n[ "); - - prop = of_get_flat_dt_prop(dt_root, "compatible", &size); - if (prop) { - while (size > 0) { - printk("'%s' ", prop); - size -= strlen(prop) + 1; - prop += strlen(prop) + 1; - } - } - printk("]\n\n"); - + mdesc = of_flat_dt_match_machine(NULL, arch_get_next_mach); + if (!mdesc) dump_machine_table(); /* does not return */ - } - - model = of_get_flat_dt_prop(dt_root, "model", NULL); - if (!model) - model = of_get_flat_dt_prop(dt_root, "compatible", NULL); - if (!model) - model = "<unknown>"; - pr_info("Machine: %s, model: %s\n", mdesc_best->name, model); - - /* Retrieve various information from the /chosen node */ - of_scan_flat_dt(early_init_dt_scan_chosen, boot_command_line); - - return mdesc_best; -} + pr_info("Machine name: %s\n", mdesc->name); -/** - * copy_fdt - Copy device tree into non-init memory. - * - * We must copy the flattened device tree blob into non-init memory because the - * unflattened device tree will reference the strings in it directly. - */ -void __init copy_fdt(void) -{ - void *alloc = early_init_dt_alloc_memory_arch( - be32_to_cpu(initial_boot_params->totalsize), 0x40); - if (alloc) { - memcpy(alloc, initial_boot_params, - be32_to_cpu(initial_boot_params->totalsize)); - initial_boot_params = alloc; - } + return mdesc; } diff --git a/arch/metag/kernel/dma.c b/arch/metag/kernel/dma.c index 8c00dedadc54..db589ad5dbc4 100644 --- a/arch/metag/kernel/dma.c +++ b/arch/metag/kernel/dma.c @@ -305,9 +305,7 @@ void dma_free_coherent(struct device *dev, size_t size, if (pfn_valid(pfn)) { struct page *page = pfn_to_page(pfn); - ClearPageReserved(page); - - __free_page(page); + __free_reserved_page(page); continue; } } diff --git a/arch/metag/kernel/irq.c b/arch/metag/kernel/irq.c index 2a2c9d55187e..3b4b7f6c0950 100644 --- a/arch/metag/kernel/irq.c +++ b/arch/metag/kernel/irq.c @@ -159,44 +159,30 @@ void irq_ctx_exit(int cpu) extern asmlinkage void __do_softirq(void); -asmlinkage void do_softirq(void) +void do_softirq_own_stack(void) { - unsigned long flags; struct thread_info *curctx; union irq_ctx *irqctx; u32 *isp; - if (in_interrupt()) - return; - - local_irq_save(flags); - - if (local_softirq_pending()) { - curctx = current_thread_info(); - irqctx = softirq_ctx[smp_processor_id()]; - irqctx->tinfo.task = curctx->task; - - /* build the stack frame on the softirq stack */ - isp = (u32 *) ((char *)irqctx + sizeof(struct thread_info)); - - asm volatile ( - "MOV D0.5,%0\n" - "SWAP A0StP,D0.5\n" - "CALLR D1RtP,___do_softirq\n" - "MOV A0StP,D0.5\n" - : - : "r" (isp) - : "memory", "cc", "D1Ar1", "D0Ar2", "D1Ar3", "D0Ar4", - "D1Ar5", "D0Ar6", "D0Re0", "D1Re0", "D0.4", "D1RtP", - "D0.5" - ); - /* - * Shouldn't happen, we returned above if in_interrupt(): - */ - WARN_ON_ONCE(softirq_count()); - } - - local_irq_restore(flags); + curctx = current_thread_info(); + irqctx = softirq_ctx[smp_processor_id()]; + irqctx->tinfo.task = curctx->task; + + /* build the stack frame on the softirq stack */ + isp = (u32 *) ((char *)irqctx + sizeof(struct thread_info)); + + asm volatile ( + "MOV D0.5,%0\n" + "SWAP A0StP,D0.5\n" + "CALLR D1RtP,___do_softirq\n" + "MOV A0StP,D0.5\n" + : + : "r" (isp) + : "memory", "cc", "D1Ar1", "D0Ar2", "D1Ar3", "D0Ar4", + "D1Ar5", "D0Ar6", "D0Re0", "D1Re0", "D0.4", "D1RtP", + "D0.5" + ); } #endif diff --git a/arch/metag/kernel/setup.c b/arch/metag/kernel/setup.c index c396cd0b425f..129c7cdda1ce 100644 --- a/arch/metag/kernel/setup.c +++ b/arch/metag/kernel/setup.c @@ -42,7 +42,6 @@ #include <asm/mmu.h> #include <asm/mmzone.h> #include <asm/processor.h> -#include <asm/prom.h> #include <asm/sections.h> #include <asm/setup.h> #include <asm/traps.h> @@ -115,7 +114,7 @@ extern u32 __dtb_start[]; extern struct console dash_console; #endif -struct machine_desc *machine_desc __initdata; +const struct machine_desc *machine_desc __initdata; /* * Map a Linux CPU number to a hardware thread ID @@ -302,13 +301,9 @@ void __init setup_arch(char **cmdline_p) * rather than the version from the bootloader. This makes call * stacks easier to understand and may allow us to unmap the * bootloader at some point. - * - * We need to keep the LWK handler that TBI installed in order to - * be able to do inter-thread comms. */ for (i = 0; i <= TBID_SIGNUM_MAX; i++) - if (i != TBID_SIGNUM_LWK) - _pTBI->fnSigs[i] = __TBIUnExpXXX; + _pTBI->fnSigs[i] = __TBIUnExpXXX; /* A Meta requirement is that the kernel is loaded (virtually) * at the PAGE_OFFSET. @@ -408,9 +403,7 @@ void __init setup_arch(char **cmdline_p) cpu_2_hwthread_id[smp_processor_id()] = hard_processor_id(); hwthread_id_2_cpu[hard_processor_id()] = smp_processor_id(); - /* Copy device tree blob into non-init memory before unflattening */ - copy_fdt(); - unflatten_device_tree(); + unflatten_and_copy_device_tree(); #ifdef CONFIG_SMP smp_init_cpus(); diff --git a/arch/metag/kernel/traps.c b/arch/metag/kernel/traps.c index 25f9d1c2ffec..17b2e2e38d5a 100644 --- a/arch/metag/kernel/traps.c +++ b/arch/metag/kernel/traps.c @@ -819,8 +819,7 @@ void per_cpu_trap_init(unsigned long cpu) set_trigger_mask(TBI_INTS_INIT(thread) | /* interrupts */ TBI_TRIG_BIT(TBID_SIGNUM_LWK) | /* low level kick */ - TBI_TRIG_BIT(TBID_SIGNUM_SW1) | - TBI_TRIG_BIT(TBID_SIGNUM_SWS)); + TBI_TRIG_BIT(TBID_SIGNUM_SW1)); /* non-priv - use current stack */ int_context.Sig.pCtx = NULL; @@ -842,7 +841,7 @@ void __init trap_init(void) _pTBI->fnSigs[TBID_SIGNUM_SW1] = switch1_handler; _pTBI->fnSigs[TBID_SIGNUM_SW2] = switchx_handler; _pTBI->fnSigs[TBID_SIGNUM_SW3] = switchx_handler; - _pTBI->fnSigs[TBID_SIGNUM_SWK] = kick_handler; + _pTBI->fnSigs[TBID_SIGNUM_LWK] = kick_handler; #ifdef CONFIG_METAG_META21 _pTBI->fnSigs[TBID_SIGNUM_DFR] = __TBIHandleDFR; diff --git a/arch/metag/mm/init.c b/arch/metag/mm/init.c index 123919534b80..3cd6288f65c2 100644 --- a/arch/metag/mm/init.c +++ b/arch/metag/mm/init.c @@ -12,7 +12,6 @@ #include <linux/percpu.h> #include <linux/memblock.h> #include <linux/initrd.h> -#include <linux/of_fdt.h> #include <asm/setup.h> #include <asm/page.h> @@ -149,7 +148,7 @@ static void __init bootmem_init_one_node(unsigned int nid) if (!p->node_spanned_pages) return; - end_pfn = p->node_start_pfn + p->node_spanned_pages; + end_pfn = pgdat_end_pfn(p); #ifdef CONFIG_HIGHMEM if (end_pfn > max_low_pfn) end_pfn = max_low_pfn; @@ -405,11 +404,3 @@ void free_initrd_mem(unsigned long start, unsigned long end) "initrd"); } #endif - -#ifdef CONFIG_OF_FLATTREE -void __init early_init_dt_setup_initrd_arch(u64 start, u64 end) -{ - pr_err("%s(%llx, %llx)\n", - __func__, start, end); -} -#endif /* CONFIG_OF_FLATTREE */ diff --git a/arch/metag/mm/numa.c b/arch/metag/mm/numa.c index 9ae578c9b620..b172aa45fcf8 100644 --- a/arch/metag/mm/numa.c +++ b/arch/metag/mm/numa.c @@ -34,7 +34,7 @@ void __init setup_bootmem_node(int nid, unsigned long start, unsigned long end) unsigned long pgdat_paddr; /* Don't allow bogus node assignment */ - BUG_ON(nid > MAX_NUMNODES || nid <= 0); + BUG_ON(nid >= MAX_NUMNODES || nid <= 0); start_pfn = start >> PAGE_SHIFT; end_pfn = end >> PAGE_SHIFT; diff --git a/arch/metag/tbx/tbidefr.S b/arch/metag/tbx/tbidefr.S index 3eb165ebf540..8f0902b22f70 100644 --- a/arch/metag/tbx/tbidefr.S +++ b/arch/metag/tbx/tbidefr.S @@ -20,7 +20,7 @@ /* D1Ar1:D0Ar2 -- State * D0Ar3 -- SigNum * D0Ar4 -- Triggers - * D1Ar5 -- InstOrSWSId + * D1Ar5 -- Inst * D0Ar6 -- pTBI (volatile) */ ___TBIHandleDFR: diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index b82f82b74319..e23cccde9c27 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -1,5 +1,6 @@ config MICROBLAZE def_bool y + select ARCH_MIGHT_HAVE_PC_PARPORT select HAVE_MEMBLOCK select HAVE_MEMBLOCK_NODE_MAP select HAVE_FUNCTION_TRACER @@ -82,11 +83,6 @@ config MMU bool "MMU support" default n -config NO_MMU - bool - depends on !MMU - default y - comment "Boot options" config CMDLINE_BOOL @@ -250,10 +246,6 @@ config MICROBLAZE_64K_PAGES endchoice -config KERNEL_PAD - hex "Kernel PAD for unpacking" if ADVANCED_OPTIONS - default "0x80000" if MMU - endmenu source "mm/Kconfig" diff --git a/arch/microblaze/boot/dts/Makefile b/arch/microblaze/boot/dts/Makefile index c3b3a5d67b89..c4982d16e555 100644 --- a/arch/microblaze/boot/dts/Makefile +++ b/arch/microblaze/boot/dts/Makefile @@ -1,6 +1,4 @@ # -# arch/microblaze/boot/Makefile -# obj-y += linked_dtb.o diff --git a/arch/microblaze/include/asm/Kbuild b/arch/microblaze/include/asm/Kbuild index d3c51a6a601d..ce0bbf8f5640 100644 --- a/arch/microblaze/include/asm/Kbuild +++ b/arch/microblaze/include/asm/Kbuild @@ -3,3 +3,4 @@ generic-y += clkdev.h generic-y += exec.h generic-y += trace_clock.h generic-y += syscalls.h +generic-y += preempt.h diff --git a/arch/microblaze/include/asm/pci.h b/arch/microblaze/include/asm/pci.h index d52abb6812fa..935f9bec414a 100644 --- a/arch/microblaze/include/asm/pci.h +++ b/arch/microblaze/include/asm/pci.h @@ -127,8 +127,6 @@ extern void of_scan_pci_bridge(struct device_node *node, extern void of_scan_bus(struct device_node *node, struct pci_bus *bus); extern void of_rescan_bus(struct device_node *node, struct pci_bus *bus); -extern int pci_read_irq_line(struct pci_dev *dev); - extern int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap); diff --git a/arch/microblaze/include/asm/pgalloc.h b/arch/microblaze/include/asm/pgalloc.h index ebd35792482c..7fdf7fabc7d7 100644 --- a/arch/microblaze/include/asm/pgalloc.h +++ b/arch/microblaze/include/asm/pgalloc.h @@ -122,8 +122,13 @@ static inline struct page *pte_alloc_one(struct mm_struct *mm, #endif ptepage = alloc_pages(flags, 0); - if (ptepage) - clear_highpage(ptepage); + if (!ptepage) + return NULL; + clear_highpage(ptepage); + if (!pgtable_page_ctor(ptepage)) { + __free_page(ptepage); + return NULL; + } return ptepage; } @@ -158,8 +163,9 @@ extern inline void pte_free_slow(struct page *ptepage) __free_page(ptepage); } -extern inline void pte_free(struct mm_struct *mm, struct page *ptepage) +static inline void pte_free(struct mm_struct *mm, struct page *ptepage) { + pgtable_page_dtor(ptepage); __free_page(ptepage); } diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h index 9977816c5ad3..2f03ac815851 100644 --- a/arch/microblaze/include/asm/prom.h +++ b/arch/microblaze/include/asm/prom.h @@ -11,19 +11,10 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ - -#include <linux/of.h> /* linux/of.h gets to determine #include ordering */ - #ifndef _ASM_MICROBLAZE_PROM_H #define _ASM_MICROBLAZE_PROM_H -#ifdef __KERNEL__ -#ifndef __ASSEMBLY__ - -#include <linux/types.h> -#include <asm/irq.h> -#include <linux/atomic.h> -#define HAVE_ARCH_DEVTREE_FIXUPS +#include <linux/of.h> /* Other Prototypes */ enum early_consoles { @@ -33,32 +24,4 @@ enum early_consoles { extern int of_early_console(void *version); -/* - * OF address retreival & translation - */ - -#ifdef CONFIG_PCI -extern unsigned long pci_address_to_pio(phys_addr_t address); -#define pci_address_to_pio pci_address_to_pio -#endif /* CONFIG_PCI */ - -/* Parse the ibm,dma-window property of an OF node into the busno, phys and - * size parameters. - */ -void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, - unsigned long *busno, unsigned long *phys, unsigned long *size); - -extern void kdump_move_device_tree(void); - -#endif /* __ASSEMBLY__ */ -#endif /* __KERNEL__ */ - -/* These includes are put at the bottom because they may contain things - * that are overridden by this file. Ideally they shouldn't be included - * by this file, but there are a bunch of .c files that currently depend - * on it. Eventually they will be cleaned up. */ -#include <linux/of_fdt.h> -#include <linux/of_irq.h> -#include <linux/platform_device.h> - #endif /* _ASM_MICROBLAZE_PROM_H */ diff --git a/arch/microblaze/include/asm/thread_info.h b/arch/microblaze/include/asm/thread_info.h index de26ea6373de..8c9d36591a03 100644 --- a/arch/microblaze/include/asm/thread_info.h +++ b/arch/microblaze/include/asm/thread_info.h @@ -106,8 +106,6 @@ static inline struct thread_info *current_thread_info(void) /* thread information allocation */ #endif /* __ASSEMBLY__ */ -#define PREEMPT_ACTIVE 0x10000000 - /* * thread information flags * - these are process state flags that various assembly files may diff --git a/arch/microblaze/kernel/head.S b/arch/microblaze/kernel/head.S index fcc797feb9db..817b7eec95b6 100644 --- a/arch/microblaze/kernel/head.S +++ b/arch/microblaze/kernel/head.S @@ -176,7 +176,7 @@ _invalidate: /* start to do TLB calculation */ addik r12, r0, _end rsub r12, r3, r12 - addik r12, r12, CONFIG_KERNEL_PAD /* that's the pad */ + addik r12, r12, CONFIG_LOWMEM_SIZE >> PTE_SHIFT /* that's the pad */ or r9, r0, r0 /* TLB0 = 0 */ or r10, r0, r0 /* TLB1 = 0 */ diff --git a/arch/microblaze/kernel/hw_exception_handler.S b/arch/microblaze/kernel/hw_exception_handler.S index 61b3a1fed46f..fc6b89f4dd31 100644 --- a/arch/microblaze/kernel/hw_exception_handler.S +++ b/arch/microblaze/kernel/hw_exception_handler.S @@ -193,8 +193,8 @@ * - W S REG EXC * * - * STACK FRAME STRUCTURE (for NO_MMU) - * --------------------------------- + * STACK FRAME STRUCTURE (for CONFIG_MMU=n) + * ---------------------------------------- * * +-------------+ + 0 * | MSR | diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c index 0c4453f134cb..abdfb10e7eca 100644 --- a/arch/microblaze/kernel/prom.c +++ b/arch/microblaze/kernel/prom.c @@ -30,6 +30,7 @@ #include <linux/debugfs.h> #include <linux/irq.h> #include <linux/memblock.h> +#include <linux/of_fdt.h> #include <asm/prom.h> #include <asm/page.h> @@ -41,11 +42,6 @@ #include <asm/sections.h> #include <asm/pci-bridge.h> -void __init early_init_dt_add_memory_arch(u64 base, u64 size) -{ - memblock_add(base, size); -} - #ifdef CONFIG_EARLY_PRINTK static char *stdout; @@ -106,21 +102,10 @@ void __init early_init_devtree(void *params) { pr_debug(" -> early_init_devtree(%p)\n", params); - /* Setup flat device-tree pointer */ - initial_boot_params = params; - - /* Retrieve various informations from the /chosen node of the - * device-tree, including the platform type, initrd location and - * size, TCE reserve, and more ... - */ - of_scan_flat_dt(early_init_dt_scan_chosen, cmd_line); - - /* Scan memory nodes and rebuild MEMBLOCKs */ - of_scan_flat_dt(early_init_dt_scan_root, NULL); - of_scan_flat_dt(early_init_dt_scan_memory, NULL); + early_init_dt_scan(params); + if (!strlen(boot_command_line)) + strlcpy(boot_command_line, cmd_line, COMMAND_LINE_SIZE); - /* Save command line for /proc/cmdline and then parse parameters */ - strlcpy(boot_command_line, cmd_line, COMMAND_LINE_SIZE); parse_early_param(); memblock_allow_resize(); @@ -130,15 +115,6 @@ void __init early_init_devtree(void *params) pr_debug(" <- early_init_devtree()\n"); } -#ifdef CONFIG_BLK_DEV_INITRD -void __init early_init_dt_setup_initrd_arch(u64 start, u64 end) -{ - initrd_start = (unsigned long)__va(start); - initrd_end = (unsigned long)__va(end); - initrd_below_start_ok = 1; -} -#endif - /******* * * New implementation of the OF "find" APIs, return a refcounted diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c index 0775e036c526..8de8ebc309f1 100644 --- a/arch/microblaze/kernel/setup.c +++ b/arch/microblaze/kernel/setup.c @@ -16,6 +16,7 @@ #include <linux/initrd.h> #include <linux/console.h> #include <linux/debugfs.h> +#include <linux/of_fdt.h> #include <asm/setup.h> #include <asm/sections.h> @@ -50,7 +51,7 @@ char cmd_line[COMMAND_LINE_SIZE] __attribute__ ((section(".data"))); void __init setup_arch(char **cmdline_p) { - *cmdline_p = cmd_line; + *cmdline_p = boot_command_line; console_verbose(); diff --git a/arch/microblaze/kernel/sys_microblaze.c b/arch/microblaze/kernel/sys_microblaze.c index f905b3ae68c7..f1e1f666ddde 100644 --- a/arch/microblaze/kernel/sys_microblaze.c +++ b/arch/microblaze/kernel/sys_microblaze.c @@ -33,12 +33,23 @@ #include <linux/slab.h> #include <asm/syscalls.h> -asmlinkage long sys_mmap(unsigned long addr, unsigned long len, - unsigned long prot, unsigned long flags, - unsigned long fd, off_t pgoff) +SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len, + unsigned long, prot, unsigned long, flags, unsigned long, fd, + off_t, pgoff) { if (pgoff & ~PAGE_MASK) return -EINVAL; return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff >> PAGE_SHIFT); } + +SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len, + unsigned long, prot, unsigned long, flags, unsigned long, fd, + unsigned long, pgoff) +{ + if (pgoff & (~PAGE_MASK >> 12)) + return -EINVAL; + + return sys_mmap_pgoff(addr, len, prot, flags, fd, + pgoff >> (PAGE_SHIFT - 12)); +} diff --git a/arch/microblaze/kernel/syscall_table.S b/arch/microblaze/kernel/syscall_table.S index 4fca56cf02f6..b882ad50535b 100644 --- a/arch/microblaze/kernel/syscall_table.S +++ b/arch/microblaze/kernel/syscall_table.S @@ -192,7 +192,7 @@ ENTRY(sys_call_table) .long sys_ni_syscall /* reserved for streams2 */ .long sys_vfork /* 190 */ .long sys_getrlimit - .long sys_mmap_pgoff /* mmap2 */ + .long sys_mmap2 .long sys_truncate64 .long sys_ftruncate64 .long sys_stat64 /* 195 */ diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c index e4b3f33ef34c..3e39b1082fdf 100644 --- a/arch/microblaze/kernel/timer.c +++ b/arch/microblaze/kernel/timer.c @@ -15,6 +15,7 @@ #include <linux/clk.h> #include <linux/clockchips.h> #include <linux/of_address.h> +#include <linux/of_irq.h> #include <asm/cpuinfo.h> #include <linux/cnt32_to_63.h> @@ -148,7 +149,7 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id) static struct irqaction timer_irqaction = { .handler = timer_interrupt, - .flags = IRQF_DISABLED | IRQF_TIMER, + .flags = IRQF_TIMER, .name = "timer", .dev_id = &clockevent_xilinx_timer, }; diff --git a/arch/microblaze/mm/consistent.c b/arch/microblaze/mm/consistent.c index 5226b09cbbb2..dbbf2246a260 100644 --- a/arch/microblaze/mm/consistent.c +++ b/arch/microblaze/mm/consistent.c @@ -176,8 +176,7 @@ void consistent_free(size_t size, void *vaddr) page = virt_to_page(vaddr); do { - ClearPageReserved(page); - __free_page(page); + __free_reserved_page(page); page++; } while (size -= PAGE_SIZE); #else @@ -194,9 +193,7 @@ void consistent_free(size_t size, void *vaddr) pte_clear(&init_mm, (unsigned int)vaddr, ptep); if (pfn_valid(pfn)) { page = pfn_to_page(pfn); - - ClearPageReserved(page); - __free_page(page); + __free_reserved_page(page); } } vaddr += PAGE_SIZE; diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c index 1b93bf0892a0..66804adcacf0 100644 --- a/arch/microblaze/pci/pci-common.c +++ b/arch/microblaze/pci/pci-common.c @@ -29,6 +29,7 @@ #include <linux/slab.h> #include <linux/of.h> #include <linux/of_address.h> +#include <linux/of_irq.h> #include <linux/of_pci.h> #include <linux/export.h> @@ -193,76 +194,6 @@ void pcibios_set_master(struct pci_dev *dev) } /* - * Reads the interrupt pin to determine if interrupt is use by card. - * If the interrupt is used, then gets the interrupt line from the - * openfirmware and sets it in the pci_dev and pci_config line. - */ -int pci_read_irq_line(struct pci_dev *pci_dev) -{ - struct of_irq oirq; - unsigned int virq; - - /* The current device-tree that iSeries generates from the HV - * PCI informations doesn't contain proper interrupt routing, - * and all the fallback would do is print out crap, so we - * don't attempt to resolve the interrupts here at all, some - * iSeries specific fixup does it. - * - * In the long run, we will hopefully fix the generated device-tree - * instead. - */ - pr_debug("PCI: Try to map irq for %s...\n", pci_name(pci_dev)); - -#ifdef DEBUG - memset(&oirq, 0xff, sizeof(oirq)); -#endif - /* Try to get a mapping from the device-tree */ - if (of_irq_map_pci(pci_dev, &oirq)) { - u8 line, pin; - - /* If that fails, lets fallback to what is in the config - * space and map that through the default controller. We - * also set the type to level low since that's what PCI - * interrupts are. If your platform does differently, then - * either provide a proper interrupt tree or don't use this - * function. - */ - if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_PIN, &pin)) - return -1; - if (pin == 0) - return -1; - if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_LINE, &line) || - line == 0xff || line == 0) { - return -1; - } - pr_debug(" No map ! Using line %d (pin %d) from PCI config\n", - line, pin); - - virq = irq_create_mapping(NULL, line); - if (virq) - irq_set_irq_type(virq, IRQ_TYPE_LEVEL_LOW); - } else { - pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %s\n", - oirq.size, oirq.specifier[0], oirq.specifier[1], - of_node_full_name(oirq.controller)); - - virq = irq_create_of_mapping(oirq.controller, oirq.specifier, - oirq.size); - } - if (!virq) { - pr_debug(" Failed to map !\n"); - return -1; - } - - pr_debug(" Mapped to linux irq %d\n", virq); - - pci_dev->irq = virq; - - return 0; -} -EXPORT_SYMBOL(pci_read_irq_line); - -/* * Platform support for /proc/bus/pci/X/Y mmap()s, * modelled on the sparc64 implementation by Dave Miller. * -- paulus. @@ -960,7 +891,7 @@ void pcibios_setup_bus_devices(struct pci_bus *bus) dev->dev.archdata.dma_data = (void *)PCI_DRAM_OFFSET; /* Read default IRQs and fixup if necessary */ - pci_read_irq_line(dev); + dev->irq = of_irq_parse_and_map_pci(dev, 0, 0); } } diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms index d9d81c219253..6e239123d6fe 100644 --- a/arch/mips/Kbuild.platforms +++ b/arch/mips/Kbuild.platforms @@ -20,7 +20,6 @@ platforms += mti-sead3 platforms += netlogic platforms += pmcs-msp71xx platforms += pnx833x -platforms += powertv platforms += ralink platforms += rb532 platforms += sgi-ip22 diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index f75ab4a2f246..650de3976e7a 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1,6 +1,7 @@ config MIPS bool default y + select ARCH_MIGHT_HAVE_PC_PARPORT select HAVE_CONTEXT_TRACKING select HAVE_GENERIC_DMA_COHERENT select HAVE_IDE @@ -8,6 +9,7 @@ config MIPS select HAVE_PERF_EVENTS select PERF_USE_VMALLOC select HAVE_ARCH_KGDB + select HAVE_ARCH_TRACEHOOK select ARCH_HAVE_CUSTOM_GPIO_H select HAVE_FUNCTION_TRACER select HAVE_FUNCTION_TRACE_MCOUNT_TEST @@ -18,6 +20,7 @@ config MIPS select HAVE_KPROBES select HAVE_KRETPROBES select HAVE_DEBUG_KMEMLEAK + select HAVE_SYSCALL_TRACEPOINTS select ARCH_BINFMT_ELF_RANDOMIZE_PIE select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES && 64BIT select RTC_LIB if !MACH_LOONGSON @@ -146,6 +149,7 @@ config MIPS_COBALT select CSRC_R4K select CEVT_GT641XX select DMA_NONCOHERENT + select EARLY_PRINTK_8250 if EARLY_PRINTK select HW_HAS_PCI select I8253 select I8259 @@ -412,23 +416,6 @@ config PMC_MSP of integrated peripherals, interfaces and DSPs in addition to a variety of MIPS cores. -config POWERTV - bool "Cisco PowerTV" - select BOOT_ELF32 - select CEVT_R4K - select CPU_MIPSR2_IRQ_VI - select CPU_MIPSR2_IRQ_EI - select CSRC_POWERTV - select DMA_NONCOHERENT - select HW_HAS_PCI - select SYS_HAS_CPU_MIPS32_R2 - select SYS_SUPPORTS_32BIT_KERNEL - select SYS_SUPPORTS_BIG_ENDIAN - select SYS_SUPPORTS_HIGHMEM - select USB_OHCI_LITTLE_ENDIAN - help - This enables support for the Cisco PowerTV Platform. - config RALINK bool "Ralink based machines" select CEVT_R4K @@ -811,7 +798,6 @@ source "arch/mips/jz4740/Kconfig" source "arch/mips/lantiq/Kconfig" source "arch/mips/lasat/Kconfig" source "arch/mips/pmcs-msp71xx/Kconfig" -source "arch/mips/powertv/Kconfig" source "arch/mips/ralink/Kconfig" source "arch/mips/sgi-ip27/Kconfig" source "arch/mips/sibyte/Kconfig" @@ -890,9 +876,6 @@ config CSRC_BCM1480 config CSRC_IOASIC bool -config CSRC_POWERTV - bool - config CSRC_R4K bool @@ -1489,8 +1472,10 @@ config SYS_SUPPORTS_ZBOOT bool select HAVE_KERNEL_GZIP select HAVE_KERNEL_BZIP2 + select HAVE_KERNEL_LZ4 select HAVE_KERNEL_LZMA select HAVE_KERNEL_LZO + select HAVE_KERNEL_XZ config SYS_SUPPORTS_ZBOOT_UART16550 bool @@ -1977,6 +1962,7 @@ config MIPS_VPE_APSP_API config MIPS_CMP bool "MIPS CMP framework support" depends on SYS_SUPPORTS_MIPS_CMP + select SMP select SYNC_R4K select SYS_SUPPORTS_SMP select SYS_SUPPORTS_SCHED_SMT if SMP @@ -2140,7 +2126,6 @@ source "mm/Kconfig" config SMP bool "Multi-Processing support" depends on SYS_SUPPORTS_SMP - select USE_GENERIC_SMP_HELPERS help This enables support for systems with more than one CPU. If you have a system with only one CPU, like most personal computers, say N. If diff --git a/arch/mips/Kconfig.debug b/arch/mips/Kconfig.debug index 37871f0de15e..b147e7038ff0 100644 --- a/arch/mips/Kconfig.debug +++ b/arch/mips/Kconfig.debug @@ -20,6 +20,14 @@ config EARLY_PRINTK doesn't cooperate with an X server. You should normally say N here, unless you want to debug such a crash. +config EARLY_PRINTK_8250 + bool "8250/16550 and compatible serial early printk driver" + depends on EARLY_PRINTK + default n + help + If you say Y here, it will be possible to use a 8250/16550 serial + port as the boot console. + config CMDLINE_BOOL bool "Built-in kernel command line" default n diff --git a/arch/mips/Makefile b/arch/mips/Makefile index ca8f8340d75f..de300b993607 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -285,15 +285,19 @@ endif # Other need ECOFF, so we build a 32-bit ELF binary for them which we then # convert to ECOFF using elf2ecoff. # +quiet_cmd_32 = OBJCOPY $@ + cmd_32 = $(OBJCOPY) -O $(32bit-bfd) $(OBJCOPYFLAGS) $< $@ vmlinux.32: vmlinux - $(OBJCOPY) -O $(32bit-bfd) $(OBJCOPYFLAGS) $< $@ + $(call cmd,32) # # The 64-bit ELF tools are pretty broken so at this time we generate 64-bit # ELF files from 32-bit files by conversion. # +quiet_cmd_64 = OBJCOPY $@ + cmd_64 = $(OBJCOPY) -O $(64bit-bfd) $(OBJCOPYFLAGS) $< $@ vmlinux.64: vmlinux - $(OBJCOPY) -O $(64bit-bfd) $(OBJCOPYFLAGS) $< $@ + $(call cmd,64) all: $(all-y) @@ -302,10 +306,16 @@ $(boot-y): $(vmlinux-32) FORCE $(Q)$(MAKE) $(build)=arch/mips/boot VMLINUX=$(vmlinux-32) \ $(bootvars-y) arch/mips/boot/$@ +ifdef CONFIG_SYS_SUPPORTS_ZBOOT # boot/compressed $(bootz-y): $(vmlinux-32) FORCE $(Q)$(MAKE) $(build)=arch/mips/boot/compressed \ $(bootvars-y) 32bit-bfd=$(32bit-bfd) $@ +else +vmlinuz: FORCE + @echo ' CONFIG_SYS_SUPPORTS_ZBOOT is not enabled' + /bin/false +endif CLEAN_FILES += vmlinux.32 vmlinux.64 diff --git a/arch/mips/alchemy/devboards/db1235.c b/arch/mips/alchemy/devboards/db1235.c index c76a90f78664..bac19dc43d1d 100644 --- a/arch/mips/alchemy/devboards/db1235.c +++ b/arch/mips/alchemy/devboards/db1235.c @@ -59,7 +59,7 @@ void __init board_setup(void) ret = -ENODEV; } if (ret) - panic("cannot initialize board support\n"); + panic("cannot initialize board support"); } int __init db1235_arch_init(void) diff --git a/arch/mips/ath79/dev-common.c b/arch/mips/ath79/dev-common.c index c3b04c929f29..516225d207ee 100644 --- a/arch/mips/ath79/dev-common.c +++ b/arch/mips/ath79/dev-common.c @@ -20,7 +20,6 @@ #include <asm/mach-ath79/ath79.h> #include <asm/mach-ath79/ar71xx_regs.h> -#include <asm/mach-ath79/ar933x_uart_platform.h> #include "common.h" #include "dev-common.h" @@ -68,15 +67,11 @@ static struct resource ar933x_uart_resources[] = { }, }; -static struct ar933x_uart_platform_data ar933x_uart_data; static struct platform_device ar933x_uart_device = { .name = "ar933x-uart", .id = -1, .resource = ar933x_uart_resources, .num_resources = ARRAY_SIZE(ar933x_uart_resources), - .dev = { - .platform_data = &ar933x_uart_data, - }, }; void __init ath79_register_uart(void) @@ -93,7 +88,6 @@ void __init ath79_register_uart(void) ath79_uart_data[0].uartclk = uart_clk_rate; platform_device_register(&ath79_uart_device); } else if (soc_is_ar933x()) { - ar933x_uart_data.uartclk = uart_clk_rate; platform_device_register(&ar933x_uart_device); } else { BUG(); diff --git a/arch/mips/bcm47xx/Makefile b/arch/mips/bcm47xx/Makefile index f3bf6d5bfb9d..c52daf9b05c6 100644 --- a/arch/mips/bcm47xx/Makefile +++ b/arch/mips/bcm47xx/Makefile @@ -4,4 +4,5 @@ # obj-y += irq.o nvram.o prom.o serial.o setup.o time.o sprom.o +obj-y += board.o obj-$(CONFIG_BCM47XX_SSB) += wgt634u.o diff --git a/arch/mips/bcm47xx/board.c b/arch/mips/bcm47xx/board.c new file mode 100644 index 000000000000..f3f6bfe68a2a --- /dev/null +++ b/arch/mips/bcm47xx/board.c @@ -0,0 +1,309 @@ +#include <linux/export.h> +#include <linux/string.h> +#include <bcm47xx_board.h> +#include <bcm47xx_nvram.h> + +struct bcm47xx_board_type { + const enum bcm47xx_board board; + const char *name; +}; + +struct bcm47xx_board_type_list1 { + struct bcm47xx_board_type board; + const char *value1; +}; + +struct bcm47xx_board_type_list2 { + struct bcm47xx_board_type board; + const char *value1; + const char *value2; +}; + +struct bcm47xx_board_type_list3 { + struct bcm47xx_board_type board; + const char *value1; + const char *value2; + const char *value3; +}; + +struct bcm47xx_board_store { + enum bcm47xx_board board; + char name[BCM47XX_BOARD_MAX_NAME]; +}; + +/* model_name */ +static const +struct bcm47xx_board_type_list1 bcm47xx_board_list_model_name[] __initconst = { + {{BCM47XX_BOARD_DLINK_DIR130, "D-Link DIR-130"}, "DIR-130"}, + {{BCM47XX_BOARD_DLINK_DIR330, "D-Link DIR-330"}, "DIR-330"}, + { {0}, 0}, +}; + +/* model_no */ +static const +struct bcm47xx_board_type_list1 bcm47xx_board_list_model_no[] __initconst = { + {{BCM47XX_BOARD_ASUS_WL700GE, "Asus WL700"}, "WL700"}, + { {0}, 0}, +}; + +/* machine_name */ +static const +struct bcm47xx_board_type_list1 bcm47xx_board_list_machine_name[] __initconst = { + {{BCM47XX_BOARD_LINKSYS_WRTSL54GS, "Linksys WRTSL54GS"}, "WRTSL54GS"}, + { {0}, 0}, +}; + +/* hardware_version */ +static const +struct bcm47xx_board_type_list1 bcm47xx_board_list_hardware_version[] __initconst = { + {{BCM47XX_BOARD_ASUS_RTN16, "Asus RT-N16"}, "RT-N16-"}, + {{BCM47XX_BOARD_ASUS_WL320GE, "Asus WL320GE"}, "WL320G-"}, + {{BCM47XX_BOARD_ASUS_WL330GE, "Asus WL330GE"}, "WL330GE-"}, + {{BCM47XX_BOARD_ASUS_WL500GD, "Asus WL500GD"}, "WL500gd-"}, + {{BCM47XX_BOARD_ASUS_WL500GPV1, "Asus WL500GP V1"}, "WL500gp-"}, + {{BCM47XX_BOARD_ASUS_WL500GPV2, "Asus WL500GP V2"}, "WL500GPV2-"}, + {{BCM47XX_BOARD_ASUS_WL500W, "Asus WL500W"}, "WL500gW-"}, + {{BCM47XX_BOARD_ASUS_WL520GC, "Asus WL520GC"}, "WL520GC-"}, + {{BCM47XX_BOARD_ASUS_WL520GU, "Asus WL520GU"}, "WL520GU-"}, + {{BCM47XX_BOARD_BELKIN_F7D4301, "Belkin F7D4301"}, "F7D4301"}, + { {0}, 0}, +}; + +/* productid */ +static const +struct bcm47xx_board_type_list1 bcm47xx_board_list_productid[] __initconst = { + {{BCM47XX_BOARD_ASUS_RTAC66U, "Asus RT-AC66U"}, "RT-AC66U"}, + {{BCM47XX_BOARD_ASUS_RTN10, "Asus RT-N10"}, "RT-N10"}, + {{BCM47XX_BOARD_ASUS_RTN10D, "Asus RT-N10D"}, "RT-N10D"}, + {{BCM47XX_BOARD_ASUS_RTN10U, "Asus RT-N10U"}, "RT-N10U"}, + {{BCM47XX_BOARD_ASUS_RTN12, "Asus RT-N12"}, "RT-N12"}, + {{BCM47XX_BOARD_ASUS_RTN12B1, "Asus RT-N12B1"}, "RT-N12B1"}, + {{BCM47XX_BOARD_ASUS_RTN12C1, "Asus RT-N12C1"}, "RT-N12C1"}, + {{BCM47XX_BOARD_ASUS_RTN12D1, "Asus RT-N12D1"}, "RT-N12D1"}, + {{BCM47XX_BOARD_ASUS_RTN12HP, "Asus RT-N12HP"}, "RT-N12HP"}, + {{BCM47XX_BOARD_ASUS_RTN15U, "Asus RT-N15U"}, "RT-N15U"}, + {{BCM47XX_BOARD_ASUS_RTN16, "Asus RT-N16"}, "RT-N16"}, + {{BCM47XX_BOARD_ASUS_RTN53, "Asus RT-N53"}, "RT-N53"}, + {{BCM47XX_BOARD_ASUS_RTN66U, "Asus RT-N66U"}, "RT-N66U"}, + {{BCM47XX_BOARD_ASUS_WL300G, "Asus WL300G"}, "WL300g"}, + {{BCM47XX_BOARD_ASUS_WLHDD, "Asus WLHDD"}, "WLHDD"}, + { {0}, 0}, +}; + +/* ModelId */ +static const +struct bcm47xx_board_type_list1 bcm47xx_board_list_ModelId[] __initconst = { + {{BCM47XX_BOARD_DELL_TM2300, "Dell WX-5565"}, "WX-5565"}, + {{BCM47XX_BOARD_MOTOROLA_WE800G, "Motorola WE800G"}, "WE800G"}, + {{BCM47XX_BOARD_MOTOROLA_WR850GP, "Motorola WR850GP"}, "WR850GP"}, + {{BCM47XX_BOARD_MOTOROLA_WR850GV2V3, "Motorola WR850G"}, "WR850G"}, + { {0}, 0}, +}; + +/* melco_id or buf1falo_id */ +static const +struct bcm47xx_board_type_list1 bcm47xx_board_list_melco_id[] __initconst = { + {{BCM47XX_BOARD_BUFFALO_WBR2_G54, "Buffalo WBR2-G54"}, "29bb0332"}, + {{BCM47XX_BOARD_BUFFALO_WHR2_A54G54, "Buffalo WHR2-A54G54"}, "290441dd"}, + {{BCM47XX_BOARD_BUFFALO_WHR_G125, "Buffalo WHR-G125"}, "32093"}, + {{BCM47XX_BOARD_BUFFALO_WHR_G54S, "Buffalo WHR-G54S"}, "30182"}, + {{BCM47XX_BOARD_BUFFALO_WHR_HP_G54, "Buffalo WHR-HP-G54"}, "30189"}, + {{BCM47XX_BOARD_BUFFALO_WLA2_G54L, "Buffalo WLA2-G54L"}, "29129"}, + {{BCM47XX_BOARD_BUFFALO_WZR_G300N, "Buffalo WZR-G300N"}, "31120"}, + {{BCM47XX_BOARD_BUFFALO_WZR_RS_G54, "Buffalo WZR-RS-G54"}, "30083"}, + {{BCM47XX_BOARD_BUFFALO_WZR_RS_G54HP, "Buffalo WZR-RS-G54HP"}, "30103"}, + { {0}, 0}, +}; + +/* boot_hw_model, boot_hw_ver */ +static const +struct bcm47xx_board_type_list2 bcm47xx_board_list_boot_hw[] __initconst = { + /* like WRT160N v3.0 */ + {{BCM47XX_BOARD_CISCO_M10V1, "Cisco M10"}, "M10", "1.0"}, + /* like WRT310N v2.0 */ + {{BCM47XX_BOARD_CISCO_M20V1, "Cisco M20"}, "M20", "1.0"}, + {{BCM47XX_BOARD_LINKSYS_E900V1, "Linksys E900 V1"}, "E900", "1.0"}, + /* like WRT160N v3.0 */ + {{BCM47XX_BOARD_LINKSYS_E1000V1, "Linksys E1000 V1"}, "E100", "1.0"}, + {{BCM47XX_BOARD_LINKSYS_E1000V2, "Linksys E1000 V2"}, "E1000", "2.0"}, + {{BCM47XX_BOARD_LINKSYS_E1000V21, "Linksys E1000 V2.1"}, "E1000", "2.1"}, + {{BCM47XX_BOARD_LINKSYS_E1200V2, "Linksys E1200 V2"}, "E1200", "2.0"}, + {{BCM47XX_BOARD_LINKSYS_E2000V1, "Linksys E2000 V1"}, "Linksys E2000", "1.0"}, + /* like WRT610N v2.0 */ + {{BCM47XX_BOARD_LINKSYS_E3000V1, "Linksys E3000 V1"}, "E300", "1.0"}, + {{BCM47XX_BOARD_LINKSYS_E3200V1, "Linksys E3200 V1"}, "E3200", "1.0"}, + {{BCM47XX_BOARD_LINKSYS_E4200V1, "Linksys E4200 V1"}, "E4200", "1.0"}, + {{BCM47XX_BOARD_LINKSYS_WRT150NV11, "Linksys WRT150N V1.1"}, "WRT150N", "1.1"}, + {{BCM47XX_BOARD_LINKSYS_WRT150NV1, "Linksys WRT150N V1"}, "WRT150N", "1"}, + {{BCM47XX_BOARD_LINKSYS_WRT160NV1, "Linksys WRT160N V1"}, "WRT160N", "1.0"}, + {{BCM47XX_BOARD_LINKSYS_WRT160NV3, "Linksys WRT160N V3"}, "WRT160N", "3.0"}, + {{BCM47XX_BOARD_LINKSYS_WRT300NV11, "Linksys WRT300N V1.1"}, "WRT300N", "1.1"}, + {{BCM47XX_BOARD_LINKSYS_WRT310NV1, "Linksys WRT310N V1"}, "WRT310N", "1.0"}, + {{BCM47XX_BOARD_LINKSYS_WRT310NV2, "Linksys WRT310N V2"}, "WRT310N", "2.0"}, + {{BCM47XX_BOARD_LINKSYS_WRT54G3GV2, "Linksys WRT54G3GV2-VF"}, "WRT54G3GV2-VF", "1.0"}, + {{BCM47XX_BOARD_LINKSYS_WRT610NV1, "Linksys WRT610N V1"}, "WRT610N", "1.0"}, + {{BCM47XX_BOARD_LINKSYS_WRT610NV2, "Linksys WRT610N V2"}, "WRT610N", "2.0"}, + { {0}, 0}, +}; + +/* board_id */ +static const +struct bcm47xx_board_type_list1 bcm47xx_board_list_board_id[] __initconst = { + {{BCM47XX_BOARD_NETGEAR_WGR614V8, "Netgear WGR614 V8"}, "U12H072T00_NETGEAR"}, + {{BCM47XX_BOARD_NETGEAR_WGR614V9, "Netgear WGR614 V9"}, "U12H094T00_NETGEAR"}, + {{BCM47XX_BOARD_NETGEAR_WNDR3300, "Netgear WNDR3300"}, "U12H093T00_NETGEAR"}, + {{BCM47XX_BOARD_NETGEAR_WNDR3400V1, "Netgear WNDR3400 V1"}, "U12H155T00_NETGEAR"}, + {{BCM47XX_BOARD_NETGEAR_WNDR3400V2, "Netgear WNDR3400 V2"}, "U12H187T00_NETGEAR"}, + {{BCM47XX_BOARD_NETGEAR_WNDR3400VCNA, "Netgear WNDR3400 Vcna"}, "U12H155T01_NETGEAR"}, + {{BCM47XX_BOARD_NETGEAR_WNDR3700V3, "Netgear WNDR3700 V3"}, "U12H194T00_NETGEAR"}, + {{BCM47XX_BOARD_NETGEAR_WNDR4000, "Netgear WNDR4000"}, "U12H181T00_NETGEAR"}, + {{BCM47XX_BOARD_NETGEAR_WNDR4500V1, "Netgear WNDR4500 V1"}, "U12H189T00_NETGEAR"}, + {{BCM47XX_BOARD_NETGEAR_WNDR4500V2, "Netgear WNDR4500 V2"}, "U12H224T00_NETGEAR"}, + {{BCM47XX_BOARD_NETGEAR_WNR2000, "Netgear WNR2000"}, "U12H114T00_NETGEAR"}, + {{BCM47XX_BOARD_NETGEAR_WNR3500L, "Netgear WNR3500L"}, "U12H136T99_NETGEAR"}, + {{BCM47XX_BOARD_NETGEAR_WNR3500U, "Netgear WNR3500U"}, "U12H136T00_NETGEAR"}, + {{BCM47XX_BOARD_NETGEAR_WNR3500V2, "Netgear WNR3500 V2"}, "U12H127T00_NETGEAR"}, + {{BCM47XX_BOARD_NETGEAR_WNR3500V2VC, "Netgear WNR3500 V2vc"}, "U12H127T70_NETGEAR"}, + {{BCM47XX_BOARD_NETGEAR_WNR834BV2, "Netgear WNR834B V2"}, "U12H081T00_NETGEAR"}, + { {0}, 0}, +}; + +/* boardtype, boardnum, boardrev */ +static const +struct bcm47xx_board_type_list3 bcm47xx_board_list_board[] __initconst = { + {{BCM47XX_BOARD_HUAWEI_E970, "Huawei E970"}, "0x048e", "0x5347", "0x11"}, + {{BCM47XX_BOARD_PHICOMM_M1, "Phicomm M1"}, "0x0590", "80", "0x1104"}, + {{BCM47XX_BOARD_ZTE_H218N, "ZTE H218N"}, "0x053d", "1234", "0x1305"}, + { {0}, 0}, +}; + +static const +struct bcm47xx_board_type bcm47xx_board_unknown[] __initconst = { + {BCM47XX_BOARD_UNKNOWN, "Unknown Board"}, +}; + +static struct bcm47xx_board_store bcm47xx_board = {BCM47XX_BOARD_NO, "Unknown Board"}; + +static __init const struct bcm47xx_board_type *bcm47xx_board_get_nvram(void) +{ + char buf1[30]; + char buf2[30]; + char buf3[30]; + const struct bcm47xx_board_type_list1 *e1; + const struct bcm47xx_board_type_list2 *e2; + const struct bcm47xx_board_type_list3 *e3; + + if (bcm47xx_nvram_getenv("model_name", buf1, sizeof(buf1)) >= 0) { + for (e1 = bcm47xx_board_list_model_name; e1->value1; e1++) { + if (!strcmp(buf1, e1->value1)) + return &e1->board; + } + } + + if (bcm47xx_nvram_getenv("model_no", buf1, sizeof(buf1)) >= 0) { + for (e1 = bcm47xx_board_list_model_no; e1->value1; e1++) { + if (strstarts(buf1, e1->value1)) + return &e1->board; + } + } + + if (bcm47xx_nvram_getenv("machine_name", buf1, sizeof(buf1)) >= 0) { + for (e1 = bcm47xx_board_list_machine_name; e1->value1; e1++) { + if (strstarts(buf1, e1->value1)) + return &e1->board; + } + } + + if (bcm47xx_nvram_getenv("hardware_version", buf1, sizeof(buf1)) >= 0) { + for (e1 = bcm47xx_board_list_hardware_version; e1->value1; e1++) { + if (strstarts(buf1, e1->value1)) + return &e1->board; + } + } + + if (bcm47xx_nvram_getenv("productid", buf1, sizeof(buf1)) >= 0) { + for (e1 = bcm47xx_board_list_productid; e1->value1; e1++) { + if (!strcmp(buf1, e1->value1)) + return &e1->board; + } + } + + if (bcm47xx_nvram_getenv("ModelId", buf1, sizeof(buf1)) >= 0) { + for (e1 = bcm47xx_board_list_ModelId; e1->value1; e1++) { + if (!strcmp(buf1, e1->value1)) + return &e1->board; + } + } + + if (bcm47xx_nvram_getenv("melco_id", buf1, sizeof(buf1)) >= 0 || + bcm47xx_nvram_getenv("buf1falo_id", buf1, sizeof(buf1)) >= 0) { + /* buffalo hardware, check id for specific hardware matches */ + for (e1 = bcm47xx_board_list_melco_id; e1->value1; e1++) { + if (!strcmp(buf1, e1->value1)) + return &e1->board; + } + } + + if (bcm47xx_nvram_getenv("boot_hw_model", buf1, sizeof(buf1)) >= 0 && + bcm47xx_nvram_getenv("boot_hw_ver", buf2, sizeof(buf2)) >= 0) { + for (e2 = bcm47xx_board_list_boot_hw; e2->value1; e2++) { + if (!strcmp(buf1, e2->value1) && + !strcmp(buf2, e2->value2)) + return &e2->board; + } + } + + if (bcm47xx_nvram_getenv("board_id", buf1, sizeof(buf1)) >= 0) { + for (e1 = bcm47xx_board_list_board_id; e1->value1; e1++) { + if (!strcmp(buf1, e1->value1)) + return &e1->board; + } + } + + if (bcm47xx_nvram_getenv("boardtype", buf1, sizeof(buf1)) >= 0 && + bcm47xx_nvram_getenv("boardnum", buf2, sizeof(buf2)) >= 0 && + bcm47xx_nvram_getenv("boardrev", buf3, sizeof(buf3)) >= 0) { + for (e3 = bcm47xx_board_list_board; e3->value1; e3++) { + if (!strcmp(buf1, e3->value1) && + !strcmp(buf2, e3->value2) && + !strcmp(buf3, e3->value3)) + return &e3->board; + } + } + return bcm47xx_board_unknown; +} + +void __init bcm47xx_board_detect(void) +{ + int err; + char buf[10]; + const struct bcm47xx_board_type *board_detected; + + if (bcm47xx_board.board != BCM47XX_BOARD_NO) + return; + + /* check if the nvram is available */ + err = bcm47xx_nvram_getenv("boardtype", buf, sizeof(buf)); + + /* init of nvram failed, probably too early now */ + if (err == -ENXIO) { + return; + } + + board_detected = bcm47xx_board_get_nvram(); + bcm47xx_board.board = board_detected->board; + strlcpy(bcm47xx_board.name, board_detected->name, + BCM47XX_BOARD_MAX_NAME); +} + +enum bcm47xx_board bcm47xx_board_get(void) +{ + return bcm47xx_board.board; +} +EXPORT_SYMBOL(bcm47xx_board_get); + +const char *bcm47xx_board_get_name(void) +{ + return bcm47xx_board.name; +} +EXPORT_SYMBOL(bcm47xx_board_get_name); diff --git a/arch/mips/bcm47xx/nvram.c b/arch/mips/bcm47xx/nvram.c index cc40b74940f5..b4c585b1c62e 100644 --- a/arch/mips/bcm47xx/nvram.c +++ b/arch/mips/bcm47xx/nvram.c @@ -190,3 +190,23 @@ int bcm47xx_nvram_getenv(char *name, char *val, size_t val_len) return -ENOENT; } EXPORT_SYMBOL(bcm47xx_nvram_getenv); + +int bcm47xx_nvram_gpio_pin(const char *name) +{ + int i, err; + char nvram_var[10]; + char buf[30]; + + for (i = 0; i < 16; i++) { + err = snprintf(nvram_var, sizeof(nvram_var), "gpio%i", i); + if (err <= 0) + continue; + err = bcm47xx_nvram_getenv(nvram_var, buf, sizeof(buf)); + if (err <= 0) + continue; + if (!strcmp(name, buf)) + return i; + } + return -ENOENT; +} +EXPORT_SYMBOL(bcm47xx_nvram_gpio_pin); diff --git a/arch/mips/bcm47xx/prom.c b/arch/mips/bcm47xx/prom.c index 8c155afb1299..5cba318bc1cd 100644 --- a/arch/mips/bcm47xx/prom.c +++ b/arch/mips/bcm47xx/prom.c @@ -32,12 +32,37 @@ #include <asm/bootinfo.h> #include <asm/fw/cfe/cfe_api.h> #include <asm/fw/cfe/cfe_error.h> +#include <bcm47xx.h> +#include <bcm47xx_board.h> static int cfe_cons_handle; +static u16 get_chip_id(void) +{ + switch (bcm47xx_bus_type) { +#ifdef CONFIG_BCM47XX_SSB + case BCM47XX_BUS_TYPE_SSB: + return bcm47xx_bus.ssb.chip_id; +#endif +#ifdef CONFIG_BCM47XX_BCMA + case BCM47XX_BUS_TYPE_BCMA: + return bcm47xx_bus.bcma.bus.chipinfo.id; +#endif + } + return 0; +} + const char *get_system_type(void) { - return "Broadcom BCM47XX"; + static char buf[50]; + u16 chip_id = get_chip_id(); + + snprintf(buf, sizeof(buf), + (chip_id > 0x9999) ? "Broadcom BCM%d (%s)" : + "Broadcom BCM%04X (%s)", + chip_id, bcm47xx_board_get_name()); + + return buf; } void prom_putchar(char c) diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c index b2246cd9ca12..1f30571968e7 100644 --- a/arch/mips/bcm47xx/setup.c +++ b/arch/mips/bcm47xx/setup.c @@ -36,6 +36,7 @@ #include <asm/time.h> #include <bcm47xx.h> #include <bcm47xx_nvram.h> +#include <bcm47xx_board.h> union bcm47xx_bus bcm47xx_bus; EXPORT_SYMBOL(bcm47xx_bus); @@ -221,6 +222,7 @@ void __init plat_mem_setup(void) _machine_restart = bcm47xx_machine_restart; _machine_halt = bcm47xx_machine_halt; pm_power_off = bcm47xx_machine_halt; + bcm47xx_board_detect(); } static int __init bcm47xx_register_bus_complete(void) diff --git a/arch/mips/bcm47xx/time.c b/arch/mips/bcm47xx/time.c index 536374dcba78..2c85d9254b5e 100644 --- a/arch/mips/bcm47xx/time.c +++ b/arch/mips/bcm47xx/time.c @@ -27,10 +27,16 @@ #include <linux/ssb/ssb.h> #include <asm/time.h> #include <bcm47xx.h> +#include <bcm47xx_nvram.h> +#include <bcm47xx_board.h> void __init plat_time_init(void) { unsigned long hz = 0; + u16 chip_id = 0; + char buf[10]; + int len; + enum bcm47xx_board board = bcm47xx_board_get(); /* * Use deterministic values for initial counter interrupt @@ -43,15 +49,32 @@ void __init plat_time_init(void) #ifdef CONFIG_BCM47XX_SSB case BCM47XX_BUS_TYPE_SSB: hz = ssb_cpu_clock(&bcm47xx_bus.ssb.mipscore) / 2; + chip_id = bcm47xx_bus.ssb.chip_id; break; #endif #ifdef CONFIG_BCM47XX_BCMA case BCM47XX_BUS_TYPE_BCMA: hz = bcma_cpu_clock(&bcm47xx_bus.bcma.bus.drv_mips) / 2; + chip_id = bcm47xx_bus.bcma.bus.chipinfo.id; break; #endif } + if (chip_id == 0x5354) { + len = bcm47xx_nvram_getenv("clkfreq", buf, sizeof(buf)); + if (len >= 0 && !strncmp(buf, "200", 4)) + hz = 100000000; + } + + switch (board) { + case BCM47XX_BOARD_ASUS_WL520GC: + case BCM47XX_BOARD_ASUS_WL520GU: + hz = 100000000; + break; + default: + break; + } + if (!hz) hz = 100000000; diff --git a/arch/mips/boot/compressed/Makefile b/arch/mips/boot/compressed/Makefile index 0048c0897896..ca0c343c9ea5 100644 --- a/arch/mips/boot/compressed/Makefile +++ b/arch/mips/boot/compressed/Makefile @@ -37,6 +37,10 @@ vmlinuzobjs-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART16550) += $(obj)/uart-16550.o vmlinuzobjs-$(CONFIG_MIPS_ALCHEMY) += $(obj)/uart-alchemy.o endif +ifdef CONFIG_KERNEL_XZ +vmlinuzobjs-y += $(obj)/../../lib/ashldi3.o +endif + targets += vmlinux.bin OBJCOPYFLAGS_vmlinux.bin := $(OBJCOPYFLAGS) -O binary -R .comment -S $(obj)/vmlinux.bin: $(KBUILD_IMAGE) FORCE @@ -44,8 +48,10 @@ $(obj)/vmlinux.bin: $(KBUILD_IMAGE) FORCE tool_$(CONFIG_KERNEL_GZIP) = gzip tool_$(CONFIG_KERNEL_BZIP2) = bzip2 +tool_$(CONFIG_KERNEL_LZ4) = lz4 tool_$(CONFIG_KERNEL_LZMA) = lzma tool_$(CONFIG_KERNEL_LZO) = lzo +tool_$(CONFIG_KERNEL_XZ) = xzkern targets += vmlinux.bin.z $(obj)/vmlinux.bin.z: $(obj)/vmlinux.bin FORCE diff --git a/arch/mips/boot/compressed/decompress.c b/arch/mips/boot/compressed/decompress.c index 2c9573098c0d..a8c6fd6a4406 100644 --- a/arch/mips/boot/compressed/decompress.c +++ b/arch/mips/boot/compressed/decompress.c @@ -43,7 +43,8 @@ void error(char *x) /* activate the code for pre-boot environment */ #define STATIC static -#ifdef CONFIG_KERNEL_GZIP +#if defined(CONFIG_KERNEL_GZIP) || defined(CONFIG_KERNEL_XZ) || \ + defined(CONFIG_KERNEL_LZ4) void *memcpy(void *dest, const void *src, size_t n) { int i; @@ -54,6 +55,8 @@ void *memcpy(void *dest, const void *src, size_t n) d[i] = s[i]; return dest; } +#endif +#ifdef CONFIG_KERNEL_GZIP #include "../../../../lib/decompress_inflate.c" #endif @@ -70,6 +73,10 @@ void *memset(void *s, int c, size_t n) #include "../../../../lib/decompress_bunzip2.c" #endif +#ifdef CONFIG_KERNEL_LZ4 +#include "../../../../lib/decompress_unlz4.c" +#endif + #ifdef CONFIG_KERNEL_LZMA #include "../../../../lib/decompress_unlzma.c" #endif @@ -78,6 +85,10 @@ void *memset(void *s, int c, size_t n) #include "../../../../lib/decompress_unlzo.c" #endif +#ifdef CONFIG_KERNEL_XZ +#include "../../../../lib/decompress_unxz.c" +#endif + void decompress_kernel(unsigned long boot_heap_start) { unsigned long zimage_start, zimage_size; diff --git a/arch/mips/boot/compressed/ld.script b/arch/mips/boot/compressed/ld.script index 8e6b07ca2f5e..5a33409c7f63 100644 --- a/arch/mips/boot/compressed/ld.script +++ b/arch/mips/boot/compressed/ld.script @@ -8,6 +8,9 @@ OUTPUT_ARCH(mips) ENTRY(start) +PHDRS { + text PT_LOAD FLAGS(7); /* RWX */ +} SECTIONS { /* Text and read-only data */ @@ -15,7 +18,7 @@ SECTIONS .text : { *(.text) *(.rodata) - } + }: text /* End of text section */ /* Writable data */ diff --git a/arch/mips/boot/ecoff.h b/arch/mips/boot/ecoff.h index 83e5c3813d67..7a75ce2c1bcd 100644 --- a/arch/mips/boot/ecoff.h +++ b/arch/mips/boot/ecoff.h @@ -12,7 +12,6 @@ typedef struct filehdr { } FILHDR; #define FILHSZ sizeof(FILHDR) -#define OMAGIC 0407 #define MIPSEBMAGIC 0x160 #define MIPSELMAGIC 0x162 diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c index b212ae12e5ac..331b837cec57 100644 --- a/arch/mips/cavium-octeon/setup.c +++ b/arch/mips/cavium-octeon/setup.c @@ -999,7 +999,7 @@ void __init plat_mem_setup(void) if (total == 0) panic("Unable to allocate memory from " - "cvmx_bootmem_phy_alloc\n"); + "cvmx_bootmem_phy_alloc"); } /* @@ -1081,7 +1081,7 @@ void __init device_tree_init(void) /* Copy the default tree from init memory. */ initial_boot_params = early_init_dt_alloc_memory_arch(dt_size, 8); if (initial_boot_params == NULL) - panic("Could not allocate initial_boot_params\n"); + panic("Could not allocate initial_boot_params"); memcpy(initial_boot_params, fdt, dt_size); if (do_prune) { diff --git a/arch/mips/cobalt/Makefile b/arch/mips/cobalt/Makefile index 61a334ac43ac..558e94977942 100644 --- a/arch/mips/cobalt/Makefile +++ b/arch/mips/cobalt/Makefile @@ -5,5 +5,4 @@ obj-y := buttons.o irq.o lcd.o led.o reset.o rtc.o serial.o setup.o time.o obj-$(CONFIG_PCI) += pci.o -obj-$(CONFIG_EARLY_PRINTK) += console.o obj-$(CONFIG_MTD_PHYSMAP) += mtd.o diff --git a/arch/mips/cobalt/console.c b/arch/mips/cobalt/console.c deleted file mode 100644 index d1ba701c9dd1..000000000000 --- a/arch/mips/cobalt/console.c +++ /dev/null @@ -1,20 +0,0 @@ -/* - * (C) P. Horton 2006 - */ -#include <linux/io.h> -#include <linux/serial_reg.h> - -#include <cobalt.h> - -#define UART_BASE ((void __iomem *)CKSEG1ADDR(0x1c800000)) - -void prom_putchar(char c) -{ - if (cobalt_board_id <= COBALT_BRD_ID_QUBE1) - return; - - while (!(readb(UART_BASE + UART_LSR) & UART_LSR_THRE)) - ; - - writeb(c, UART_BASE + UART_TX); -} diff --git a/arch/mips/cobalt/setup.c b/arch/mips/cobalt/setup.c index ec3b2c417f7c..9a8c2fe8d334 100644 --- a/arch/mips/cobalt/setup.c +++ b/arch/mips/cobalt/setup.c @@ -17,6 +17,7 @@ #include <asm/bootinfo.h> #include <asm/reboot.h> +#include <asm/setup.h> #include <asm/gt64120.h> #include <cobalt.h> @@ -112,6 +113,8 @@ void __init prom_init(void) } add_memory_region(0x0, memsz, BOOT_MEM_RAM); + + setup_8250_early_printk_port(CKSEG1ADDR(0x1c800000), 0, 0); } void __init prom_free_prom_memory(void) diff --git a/arch/mips/configs/db1235_defconfig b/arch/mips/configs/db1235_defconfig index e2b4ad55462f..28e49f226dc0 100644 --- a/arch/mips/configs/db1235_defconfig +++ b/arch/mips/configs/db1235_defconfig @@ -351,7 +351,6 @@ CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_HCD_PLATFORM=y CONFIG_USB_STORAGE=y CONFIG_MMC=y -CONFIG_MMC_CLKGATE=y CONFIG_MMC_AU1X=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y diff --git a/arch/mips/configs/powertv_defconfig b/arch/mips/configs/powertv_defconfig deleted file mode 100644 index 7fda0ce5f692..000000000000 --- a/arch/mips/configs/powertv_defconfig +++ /dev/null @@ -1,136 +0,0 @@ -CONFIG_POWERTV=y -CONFIG_BOOTLOADER_FAMILY="R2" -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_HZ_1000=y -CONFIG_PREEMPT=y -# CONFIG_SECCOMP is not set -CONFIG_EXPERIMENTAL=y -CONFIG_CROSS_COMPILE="" -# CONFIG_SWAP is not set -CONFIG_SYSVIPC=y -CONFIG_LOG_BUF_SHIFT=16 -CONFIG_RELAY=y -CONFIG_BLK_DEV_INITRD=y -# CONFIG_RD_GZIP is not set -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_EXPERT=y -# CONFIG_SYSCTL_SYSCALL is not set -CONFIG_KALLSYMS_ALL=y -# CONFIG_PCSPKR_PLATFORM is not set -# CONFIG_EPOLL is not set -# CONFIG_SIGNALFD is not set -# CONFIG_EVENTFD is not set -# CONFIG_VM_EVENT_COUNTERS is not set -# CONFIG_SLUB_DEBUG is not set -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -CONFIG_MODVERSIONS=y -CONFIG_MODULE_SRCVERSION_ALL=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_IOSCHED_CFQ is not set -CONFIG_PCI=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_PNP=y -CONFIG_SYN_COOKIES=y -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set -# CONFIG_INET_DIAG is not set -CONFIG_IPV6=y -CONFIG_IPV6_PRIVACY=y -CONFIG_INET6_AH=y -CONFIG_INET6_ESP=y -CONFIG_INET6_IPCOMP=y -# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET6_XFRM_MODE_TUNNEL is not set -# CONFIG_INET6_XFRM_MODE_BEET is not set -# CONFIG_IPV6_SIT is not set -CONFIG_IPV6_TUNNEL=y -CONFIG_NETFILTER=y -# CONFIG_BRIDGE_NETFILTER is not set -CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y -CONFIG_IP_NF_IPTABLES=y -CONFIG_IP_NF_FILTER=y -CONFIG_IP_NF_ARPTABLES=y -CONFIG_IP_NF_ARPFILTER=y -CONFIG_IP6_NF_IPTABLES=y -CONFIG_IP6_NF_FILTER=y -CONFIG_BRIDGE=y -CONFIG_NET_SCHED=y -CONFIG_NET_SCH_TBF=y -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_NAND=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=32768 -# CONFIG_MISC_DEVICES is not set -# CONFIG_SCSI_PROC_FS is not set -CONFIG_BLK_DEV_SD=y -# CONFIG_SCSI_LOWLEVEL is not set -CONFIG_ATA=y -CONFIG_NETDEVICES=y -CONFIG_NET_ETHERNET=y -# CONFIG_WLAN is not set -CONFIG_USB_RTL8150=y -# CONFIG_INPUT_MOUSEDEV is not set -CONFIG_INPUT_EVDEV=y -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_SERIO is not set -# CONFIG_VT is not set -# CONFIG_DEVKMEM is not set -# CONFIG_LEGACY_PTYS is not set -# CONFIG_HW_RANDOM is not set -# CONFIG_HWMON is not set -# CONFIG_MFD_SUPPORT is not set -# CONFIG_VGA_ARB is not set -CONFIG_USB_HIDDEV=y -CONFIG_USB=y -CONFIG_USB_ANNOUNCE_NEW_DEVICES=y -CONFIG_USB_DEVICEFS=y -# CONFIG_USB_DEVICE_CLASS is not set -CONFIG_USB_EHCI_HCD=y -# CONFIG_USB_EHCI_TT_NEWSCHED is not set -CONFIG_USB_OHCI_HCD=y -CONFIG_USB_STORAGE=y -CONFIG_USB_SERIAL=y -CONFIG_USB_SERIAL_CONSOLE=y -CONFIG_USB_SERIAL_CP210X=y -CONFIG_EXT2_FS=y -CONFIG_EXT3_FS=y -# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -# CONFIG_EXT3_FS_XATTR is not set -# CONFIG_DNOTIFY is not set -CONFIG_FUSE_FS=y -CONFIG_PROC_KCORE=y -CONFIG_TMPFS=y -CONFIG_JFFS2_FS=y -CONFIG_CRAMFS=y -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -CONFIG_ROOT_NFS=y -CONFIG_PRINTK_TIME=y -CONFIG_DEBUG_FS=y -CONFIG_DEBUG_KERNEL=y -CONFIG_DETECT_HUNG_TASK=y -# CONFIG_SCHED_DEBUG is not set -# CONFIG_DEBUG_PREEMPT is not set -CONFIG_DEBUG_INFO=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -# CONFIG_EARLY_PRINTK is not set -CONFIG_CMDLINE_BOOL=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set -# CONFIG_CRYPTO_HW is not set diff --git a/arch/mips/dec/int-handler.S b/arch/mips/dec/int-handler.S index 22afed16ccde..41a2fa1fa12e 100644 --- a/arch/mips/dec/int-handler.S +++ b/arch/mips/dec/int-handler.S @@ -118,7 +118,7 @@ * 7 FPU/R4k timer * * We handle the IRQ according to _our_ priority (see setup.c), - * then we just return. If multiple IRQs are pending then we will + * then we just return. If multiple IRQs are pending then we will * just take another exception, big deal. */ .align 5 @@ -146,7 +146,7 @@ /* * Find irq with highest priority */ - PTR_LA t1,cpu_mask_nr_tbl + PTR_LA t1,cpu_mask_nr_tbl 1: lw t2,(t1) nop and t2,t0 @@ -195,7 +195,7 @@ /* * Find irq with highest priority */ - PTR_LA t1,asic_mask_nr_tbl + PTR_LA t1,asic_mask_nr_tbl 2: lw t2,(t1) nop and t2,t0 @@ -221,7 +221,7 @@ FEXPORT(cpu_all_int) # HALT, timers, software junk li a0,DEC_CPU_IRQ_BASE srl t0,CAUSEB_IP - li t1,CAUSEF_IP>>CAUSEB_IP # mask + li t1,CAUSEF_IP>>CAUSEB_IP # mask b 1f li t2,4 # nr of bits / 2 diff --git a/arch/mips/dec/ioasic-irq.c b/arch/mips/dec/ioasic-irq.c index 4b3e3a4375a6..e04d973ce5aa 100644 --- a/arch/mips/dec/ioasic-irq.c +++ b/arch/mips/dec/ioasic-irq.c @@ -1,7 +1,7 @@ /* * DEC I/O ASIC interrupts. * - * Copyright (c) 2002, 2003 Maciej W. Rozycki + * Copyright (c) 2002, 2003, 2013 Maciej W. Rozycki * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -51,22 +51,51 @@ static struct irq_chip ioasic_irq_type = { .irq_unmask = unmask_ioasic_irq, }; -void clear_ioasic_dma_irq(unsigned int irq) +static void clear_ioasic_dma_irq(struct irq_data *d) { u32 sir; - sir = ~(1 << (irq - ioasic_irq_base)); + sir = ~(1 << (d->irq - ioasic_irq_base)); ioasic_write(IO_REG_SIR, sir); + fast_iob(); } static struct irq_chip ioasic_dma_irq_type = { .name = "IO-ASIC-DMA", - .irq_ack = ack_ioasic_irq, + .irq_ack = clear_ioasic_dma_irq, .irq_mask = mask_ioasic_irq, - .irq_mask_ack = ack_ioasic_irq, .irq_unmask = unmask_ioasic_irq, + .irq_eoi = clear_ioasic_dma_irq, }; +/* + * I/O ASIC implements two kinds of DMA interrupts, informational and + * error interrupts. + * + * The formers do not stop DMA and should be cleared as soon as possible + * so that if they retrigger before the handler has completed, usually as + * a side effect of actions taken by the handler, then they are reissued. + * These use the `handle_edge_irq' handler that clears the request right + * away. + * + * The latters stop DMA and do not resume it until the interrupt has been + * cleared. This cannot be done until after a corrective action has been + * taken and this also means they will not retrigger. Therefore they use + * the `handle_fasteoi_irq' handler that only clears the request on the + * way out. Because MIPS processor interrupt inputs, one of which the I/O + * ASIC is cascaded to, are level-triggered it is recommended that error + * DMA interrupt action handlers are registered with the IRQF_ONESHOT flag + * set so that they are run with the interrupt line masked. + * + * This mask has `1' bits in the positions of informational interrupts. + */ +#define IO_IRQ_DMA_INFO \ + (IO_IRQ_MASK(IO_INR_SCC0A_RXDMA) | \ + IO_IRQ_MASK(IO_INR_SCC1A_RXDMA) | \ + IO_IRQ_MASK(IO_INR_ISDN_TXDMA) | \ + IO_IRQ_MASK(IO_INR_ISDN_RXDMA) | \ + IO_IRQ_MASK(IO_INR_ASC_DMA)) + void __init init_ioasic_irqs(int base) { int i; @@ -79,7 +108,9 @@ void __init init_ioasic_irqs(int base) irq_set_chip_and_handler(i, &ioasic_irq_type, handle_level_irq); for (; i < base + IO_IRQ_LINES; i++) - irq_set_chip(i, &ioasic_dma_irq_type); + irq_set_chip_and_handler(i, &ioasic_dma_irq_type, + 1 << (i - base) & IO_IRQ_DMA_INFO ? + handle_edge_irq : handle_fasteoi_irq); ioasic_irq_base = base; } diff --git a/arch/mips/dec/prom/call_o32.S b/arch/mips/dec/prom/call_o32.S index c0d1522d448f..8c8498159e43 100644 --- a/arch/mips/dec/prom/call_o32.S +++ b/arch/mips/dec/prom/call_o32.S @@ -14,7 +14,7 @@ /* Maximum number of arguments supported. Must be even! */ #define O32_ARGC 32 -/* Number of static registers we save. */ +/* Number of static registers we save. */ #define O32_STATC 11 /* Frame size for both of the above. */ #define O32_FRAMESZ (4 * O32_ARGC + SZREG * O32_STATC) diff --git a/arch/mips/dec/prom/init.c b/arch/mips/dec/prom/init.c index 468f665de7bb..4e1761e0a09a 100644 --- a/arch/mips/dec/prom/init.c +++ b/arch/mips/dec/prom/init.c @@ -104,7 +104,7 @@ void __init prom_init(void) if (prom_is_rex(magic)) rex_clear_cache(); - /* Register the early console. */ + /* Register the early console. */ register_prom_console(); /* Were we compiled with the right CPU option? */ diff --git a/arch/mips/dec/prom/memory.c b/arch/mips/dec/prom/memory.c index 0aadac742900..8c62316f22f4 100644 --- a/arch/mips/dec/prom/memory.c +++ b/arch/mips/dec/prom/memory.c @@ -22,7 +22,7 @@ volatile unsigned long mem_err; /* So we know an error occurred */ /* * Probe memory in 4MB chunks, waiting for an error to tell us we've fallen - * off the end of real memory. Only suitable for the 2100/3100's (PMAX). + * off the end of real memory. Only suitable for the 2100/3100's (PMAX). */ #define CHUNK_SIZE 0x400000 diff --git a/arch/mips/dec/setup.c b/arch/mips/dec/setup.c index 741cb4235bde..56e6e2c23683 100644 --- a/arch/mips/dec/setup.c +++ b/arch/mips/dec/setup.c @@ -65,7 +65,7 @@ EXPORT_SYMBOL(ioasic_base); /* * IRQ routing and priority tables. Priorites are set as follows: * - * KN01 KN230 KN02 KN02-BA KN02-CA KN03 + * KN01 KN230 KN02 KN02-BA KN02-CA KN03 * * MEMORY CPU CPU CPU ASIC CPU CPU * RTC CPU CPU CPU ASIC CPU CPU @@ -413,7 +413,7 @@ static void __init dec_init_kn02(void) /* * Machine-specific initialisation for KN02-BA, aka DS5000/1xx - * (xx = 20, 25, 33), aka 3min. Also applies to KN04(-BA), aka + * (xx = 20, 25, 33), aka 3min. Also applies to KN04(-BA), aka * DS5000/150, aka 4min. */ static int kn02ba_interrupt[DEC_NR_INTS] __initdata = { diff --git a/arch/mips/include/asm/Kbuild b/arch/mips/include/asm/Kbuild index 454ddf9bb76f..1acbb8b77a71 100644 --- a/arch/mips/include/asm/Kbuild +++ b/arch/mips/include/asm/Kbuild @@ -11,5 +11,6 @@ generic-y += sections.h generic-y += segment.h generic-y += serial.h generic-y += trace_clock.h +generic-y += preempt.h generic-y += ucontext.h generic-y += xor.h diff --git a/arch/mips/include/asm/addrspace.h b/arch/mips/include/asm/addrspace.h index 13d61c002e4f..3f745459fdb5 100644 --- a/arch/mips/include/asm/addrspace.h +++ b/arch/mips/include/asm/addrspace.h @@ -58,7 +58,7 @@ /* * Memory segments (64bit kernel mode addresses) - * The compatibility segments use the full 64-bit sign extended value. Note + * The compatibility segments use the full 64-bit sign extended value. Note * the R8000 doesn't have them so don't reference these in generic MIPS code. */ #define XKUSEG _CONST64_(0x0000000000000000) @@ -131,7 +131,7 @@ /* * The ultimate limited of the 64-bit MIPS architecture: 2 bits for selecting - * the region, 3 bits for the CCA mode. This leaves 59 bits of which the + * the region, 3 bits for the CCA mode. This leaves 59 bits of which the * R8000 implements most with its 48-bit physical address space. */ #define TO_PHYS_MASK _CONST64_(0x07ffffffffffffff) /* 2^^59 - 1 */ diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h index 08b607969a16..7eed2f261710 100644 --- a/arch/mips/include/asm/atomic.h +++ b/arch/mips/include/asm/atomic.h @@ -1,5 +1,5 @@ /* - * Atomic operations that C can't guarantee us. Useful for + * Atomic operations that C can't guarantee us. Useful for * resource counting etc.. * * But use these as seldom as possible since they are much more slower diff --git a/arch/mips/include/asm/barrier.h b/arch/mips/include/asm/barrier.h index 314ab5532019..f26d8e1bf3c3 100644 --- a/arch/mips/include/asm/barrier.h +++ b/arch/mips/include/asm/barrier.h @@ -18,7 +18,7 @@ * over this barrier. All reads preceding this primitive are guaranteed * to access memory (but not necessarily other CPUs' caches) before any * reads following this primitive that depend on the data return by - * any of the preceding reads. This primitive is much lighter weight than + * any of the preceding reads. This primitive is much lighter weight than * rmb() on most CPUs, and is never heavier weight than is * rmb(). * @@ -43,7 +43,7 @@ * </programlisting> * * because the read of "*q" depends on the read of "p" and these - * two reads are separated by a read_barrier_depends(). However, + * two reads are separated by a read_barrier_depends(). However, * the following code, with the same initial values for "a" and "b": * * <programlisting> @@ -57,7 +57,7 @@ * </programlisting> * * does not enforce ordering, since there is no data dependency between - * the read of "a" and the read of "b". Therefore, on some CPUs, such + * the read of "a" and the read of "b". Therefore, on some CPUs, such * as Alpha, "y" could be set to 3 and "x" to 0. Use rmb() * in cases like this where there are no data dependencies. */ diff --git a/arch/mips/include/asm/cacheops.h b/arch/mips/include/asm/cacheops.h index 68f37e3eccc7..c75025f27c20 100644 --- a/arch/mips/include/asm/cacheops.h +++ b/arch/mips/include/asm/cacheops.h @@ -14,56 +14,52 @@ /* * Cache Operations available on all MIPS processors with R4000-style caches */ -#define Index_Invalidate_I 0x00 -#define Index_Writeback_Inv_D 0x01 -#define Index_Load_Tag_I 0x04 -#define Index_Load_Tag_D 0x05 -#define Index_Store_Tag_I 0x08 -#define Index_Store_Tag_D 0x09 -#if defined(CONFIG_CPU_LOONGSON2) -#define Hit_Invalidate_I 0x00 -#else -#define Hit_Invalidate_I 0x10 -#endif -#define Hit_Invalidate_D 0x11 -#define Hit_Writeback_Inv_D 0x15 +#define Index_Invalidate_I 0x00 +#define Index_Writeback_Inv_D 0x01 +#define Index_Load_Tag_I 0x04 +#define Index_Load_Tag_D 0x05 +#define Index_Store_Tag_I 0x08 +#define Index_Store_Tag_D 0x09 +#define Hit_Invalidate_I 0x10 +#define Hit_Invalidate_D 0x11 +#define Hit_Writeback_Inv_D 0x15 /* * R4000-specific cacheops */ -#define Create_Dirty_Excl_D 0x0d -#define Fill 0x14 -#define Hit_Writeback_I 0x18 -#define Hit_Writeback_D 0x19 +#define Create_Dirty_Excl_D 0x0d +#define Fill 0x14 +#define Hit_Writeback_I 0x18 +#define Hit_Writeback_D 0x19 /* * R4000SC and R4400SC-specific cacheops */ -#define Index_Invalidate_SI 0x02 -#define Index_Writeback_Inv_SD 0x03 -#define Index_Load_Tag_SI 0x06 -#define Index_Load_Tag_SD 0x07 -#define Index_Store_Tag_SI 0x0A -#define Index_Store_Tag_SD 0x0B -#define Create_Dirty_Excl_SD 0x0f -#define Hit_Invalidate_SI 0x12 -#define Hit_Invalidate_SD 0x13 -#define Hit_Writeback_Inv_SD 0x17 -#define Hit_Writeback_SD 0x1b -#define Hit_Set_Virtual_SI 0x1e -#define Hit_Set_Virtual_SD 0x1f +#define Index_Invalidate_SI 0x02 +#define Index_Writeback_Inv_SD 0x03 +#define Index_Load_Tag_SI 0x06 +#define Index_Load_Tag_SD 0x07 +#define Index_Store_Tag_SI 0x0A +#define Index_Store_Tag_SD 0x0B +#define Create_Dirty_Excl_SD 0x0f +#define Hit_Invalidate_SI 0x12 +#define Hit_Invalidate_SD 0x13 +#define Hit_Writeback_Inv_SD 0x17 +#define Hit_Writeback_SD 0x1b +#define Hit_Set_Virtual_SI 0x1e +#define Hit_Set_Virtual_SD 0x1f /* * R5000-specific cacheops */ -#define R5K_Page_Invalidate_S 0x17 +#define R5K_Page_Invalidate_S 0x17 /* * RM7000-specific cacheops */ -#define Page_Invalidate_T 0x16 -#define Index_Store_Tag_T 0x0a -#define Index_Load_Tag_T 0x06 +#define Page_Invalidate_T 0x16 +#define Index_Store_Tag_T 0x0a +#define Index_Load_Tag_T 0x06 /* * R10000-specific cacheops @@ -71,17 +67,22 @@ * Cacheops 0x02, 0x06, 0x0a, 0x0c-0x0e, 0x16, 0x1a and 0x1e are unused. * Most of the _S cacheops are identical to the R4000SC _SD cacheops. */ -#define Index_Writeback_Inv_S 0x03 -#define Index_Load_Tag_S 0x07 -#define Index_Store_Tag_S 0x0B -#define Hit_Invalidate_S 0x13 -#define Cache_Barrier 0x14 -#define Hit_Writeback_Inv_S 0x17 -#define Index_Load_Data_I 0x18 -#define Index_Load_Data_D 0x19 -#define Index_Load_Data_S 0x1b -#define Index_Store_Data_I 0x1c -#define Index_Store_Data_D 0x1d -#define Index_Store_Data_S 0x1f +#define Index_Writeback_Inv_S 0x03 +#define Index_Load_Tag_S 0x07 +#define Index_Store_Tag_S 0x0B +#define Hit_Invalidate_S 0x13 +#define Cache_Barrier 0x14 +#define Hit_Writeback_Inv_S 0x17 +#define Index_Load_Data_I 0x18 +#define Index_Load_Data_D 0x19 +#define Index_Load_Data_S 0x1b +#define Index_Store_Data_I 0x1c +#define Index_Store_Data_D 0x1d +#define Index_Store_Data_S 0x1f + +/* + * Loongson2-specific cacheops + */ +#define Hit_Invalidate_I_Loongson23 0x00 #endif /* __ASM_CACHEOPS_H */ diff --git a/arch/mips/include/asm/dec/ioasic.h b/arch/mips/include/asm/dec/ioasic.h index a6e505a0e44b..be4d62a5a10e 100644 --- a/arch/mips/include/asm/dec/ioasic.h +++ b/arch/mips/include/asm/dec/ioasic.h @@ -31,8 +31,6 @@ static inline u32 ioasic_read(unsigned int reg) return ioasic_base[reg / 4]; } -extern void clear_ioasic_dma_irq(unsigned int irq); - extern void init_ioasic_irqs(int base); extern int dec_ioasic_clocksource_init(void); diff --git a/arch/mips/include/asm/dec/ioasic_addrs.h b/arch/mips/include/asm/dec/ioasic_addrs.h index a8665a7611c2..8bd95971fe2d 100644 --- a/arch/mips/include/asm/dec/ioasic_addrs.h +++ b/arch/mips/include/asm/dec/ioasic_addrs.h @@ -40,7 +40,7 @@ #define IOASIC_FLOPPY (11*IOASIC_SLOT_SIZE) /* FDC (maxine) */ #define IOASIC_SCSI (12*IOASIC_SLOT_SIZE) /* ASC SCSI */ #define IOASIC_FDC_DMA (13*IOASIC_SLOT_SIZE) /* FDC DMA (maxine) */ -#define IOASIC_SCSI_DMA (14*IOASIC_SLOT_SIZE) /* ??? */ +#define IOASIC_SCSI_DMA (14*IOASIC_SLOT_SIZE) /* ??? */ #define IOASIC_RES_15 (15*IOASIC_SLOT_SIZE) /* unused? */ diff --git a/arch/mips/include/asm/dec/kn01.h b/arch/mips/include/asm/dec/kn01.h index 0eb3241de706..88d9ffd74258 100644 --- a/arch/mips/include/asm/dec/kn01.h +++ b/arch/mips/include/asm/dec/kn01.h @@ -57,12 +57,12 @@ /* * System Control & Status Register bits. */ -#define KN01_CSR_MNFMOD (1<<15) /* MNFMOD manufacturing jumper */ -#define KN01_CSR_STATUS (1<<14) /* self-test result status output */ -#define KN01_CSR_PARDIS (1<<13) /* parity error disable */ -#define KN01_CSR_CRSRTST (1<<12) /* PCC test output */ -#define KN01_CSR_MONO (1<<11) /* mono/color fb SIMM installed */ -#define KN01_CSR_MEMERR (1<<10) /* write timeout error status & ack*/ +#define KN01_CSR_MNFMOD (1<<15) /* MNFMOD manufacturing jumper */ +#define KN01_CSR_STATUS (1<<14) /* self-test result status output */ +#define KN01_CSR_PARDIS (1<<13) /* parity error disable */ +#define KN01_CSR_CRSRTST (1<<12) /* PCC test output */ +#define KN01_CSR_MONO (1<<11) /* mono/color fb SIMM installed */ +#define KN01_CSR_MEMERR (1<<10) /* write timeout error status & ack*/ #define KN01_CSR_VINT (1<<9) /* PCC area detect #2 status & ack */ #define KN01_CSR_TXDIS (1<<8) /* DZ11 transmit disable */ #define KN01_CSR_VBGTRG (1<<2) /* blue DAC voltage over green (r/o) */ diff --git a/arch/mips/include/asm/dec/kn02ca.h b/arch/mips/include/asm/dec/kn02ca.h index 69dc2a9a2d0f..92c0fe256099 100644 --- a/arch/mips/include/asm/dec/kn02ca.h +++ b/arch/mips/include/asm/dec/kn02ca.h @@ -68,7 +68,7 @@ #define KN03CA_IO_SSR_ISDN_RST (1<<12) /* ~ISDN (Am79C30A) reset */ #define KN03CA_IO_SSR_FLOPPY_RST (1<<7) /* ~FDC (82077) reset */ -#define KN03CA_IO_SSR_VIDEO_RST (1<<6) /* ~framebuffer reset */ +#define KN03CA_IO_SSR_VIDEO_RST (1<<6) /* ~framebuffer reset */ #define KN03CA_IO_SSR_AB_RST (1<<5) /* ACCESS.bus reset */ #define KN03CA_IO_SSR_RES_4 (1<<4) /* unused */ #define KN03CA_IO_SSR_RES_3 (1<<4) /* unused */ diff --git a/arch/mips/include/asm/dec/prom.h b/arch/mips/include/asm/dec/prom.h index 446577712bee..c0ead6313845 100644 --- a/arch/mips/include/asm/dec/prom.h +++ b/arch/mips/include/asm/dec/prom.h @@ -49,7 +49,7 @@ #ifdef CONFIG_64BIT -#define prom_is_rex(magic) 1 /* KN04 and KN05 are REX PROMs. */ +#define prom_is_rex(magic) 1 /* KN04 and KN05 are REX PROMs. */ #else /* !CONFIG_64BIT */ diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h index cf3ae2480b1d..a66359ef4ece 100644 --- a/arch/mips/include/asm/elf.h +++ b/arch/mips/include/asm/elf.h @@ -331,6 +331,7 @@ extern int dump_task_fpu(struct task_struct *, elf_fpregset_t *); #define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) \ dump_task_fpu(tsk, elf_fpregs) +#define CORE_DUMP_USE_REGSET #define ELF_EXEC_PAGESIZE PAGE_SIZE /* This yields a mask that user programs can use to figure out what diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h index 4d6fa0bf1305..32966969f2f9 100644 --- a/arch/mips/include/asm/kvm_host.h +++ b/arch/mips/include/asm/kvm_host.h @@ -27,13 +27,6 @@ #define KVM_COALESCED_MMIO_PAGE_OFFSET 1 -/* Don't support huge pages */ -#define KVM_HPAGE_GFN_SHIFT(x) 0 - -/* We don't currently support large pages. */ -#define KVM_NR_PAGE_SIZES 1 -#define KVM_PAGES_PER_HPAGE(x) 1 - /* Special address that contains the comm page, used for reducing # of traps */ diff --git a/arch/mips/include/asm/mach-ath79/ar933x_uart_platform.h b/arch/mips/include/asm/mach-ath79/ar933x_uart_platform.h deleted file mode 100644 index 6cb30f2b7198..000000000000 --- a/arch/mips/include/asm/mach-ath79/ar933x_uart_platform.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Platform data definition for Atheros AR933X UART - * - * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> - * - * 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 _AR933X_UART_PLATFORM_H -#define _AR933X_UART_PLATFORM_H - -struct ar933x_uart_platform_data { - unsigned uartclk; -}; - -#endif /* _AR933X_UART_PLATFORM_H */ diff --git a/arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h b/arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h new file mode 100644 index 000000000000..00867dd05a69 --- /dev/null +++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h @@ -0,0 +1,110 @@ +#ifndef __BCM47XX_BOARD_H +#define __BCM47XX_BOARD_H + +enum bcm47xx_board { + BCM47XX_BOARD_ASUS_RTAC66U, + BCM47XX_BOARD_ASUS_RTN10, + BCM47XX_BOARD_ASUS_RTN10D, + BCM47XX_BOARD_ASUS_RTN10U, + BCM47XX_BOARD_ASUS_RTN12, + BCM47XX_BOARD_ASUS_RTN12B1, + BCM47XX_BOARD_ASUS_RTN12C1, + BCM47XX_BOARD_ASUS_RTN12D1, + BCM47XX_BOARD_ASUS_RTN12HP, + BCM47XX_BOARD_ASUS_RTN15U, + BCM47XX_BOARD_ASUS_RTN16, + BCM47XX_BOARD_ASUS_RTN53, + BCM47XX_BOARD_ASUS_RTN66U, + BCM47XX_BOARD_ASUS_WL300G, + BCM47XX_BOARD_ASUS_WL320GE, + BCM47XX_BOARD_ASUS_WL330GE, + BCM47XX_BOARD_ASUS_WL500GD, + BCM47XX_BOARD_ASUS_WL500GPV1, + BCM47XX_BOARD_ASUS_WL500GPV2, + BCM47XX_BOARD_ASUS_WL500W, + BCM47XX_BOARD_ASUS_WL520GC, + BCM47XX_BOARD_ASUS_WL520GU, + BCM47XX_BOARD_ASUS_WL700GE, + BCM47XX_BOARD_ASUS_WLHDD, + + BCM47XX_BOARD_BELKIN_F7D4301, + + BCM47XX_BOARD_BUFFALO_WBR2_G54, + BCM47XX_BOARD_BUFFALO_WHR2_A54G54, + BCM47XX_BOARD_BUFFALO_WHR_G125, + BCM47XX_BOARD_BUFFALO_WHR_G54S, + BCM47XX_BOARD_BUFFALO_WHR_HP_G54, + BCM47XX_BOARD_BUFFALO_WLA2_G54L, + BCM47XX_BOARD_BUFFALO_WZR_G300N, + BCM47XX_BOARD_BUFFALO_WZR_RS_G54, + BCM47XX_BOARD_BUFFALO_WZR_RS_G54HP, + + BCM47XX_BOARD_CISCO_M10V1, + BCM47XX_BOARD_CISCO_M20V1, + + BCM47XX_BOARD_DELL_TM2300, + + BCM47XX_BOARD_DLINK_DIR130, + BCM47XX_BOARD_DLINK_DIR330, + + BCM47XX_BOARD_HUAWEI_E970, + + BCM47XX_BOARD_LINKSYS_E900V1, + BCM47XX_BOARD_LINKSYS_E1000V1, + BCM47XX_BOARD_LINKSYS_E1000V2, + BCM47XX_BOARD_LINKSYS_E1000V21, + BCM47XX_BOARD_LINKSYS_E1200V2, + BCM47XX_BOARD_LINKSYS_E2000V1, + BCM47XX_BOARD_LINKSYS_E3000V1, + BCM47XX_BOARD_LINKSYS_E3200V1, + BCM47XX_BOARD_LINKSYS_E4200V1, + BCM47XX_BOARD_LINKSYS_WRT150NV1, + BCM47XX_BOARD_LINKSYS_WRT150NV11, + BCM47XX_BOARD_LINKSYS_WRT160NV1, + BCM47XX_BOARD_LINKSYS_WRT160NV3, + BCM47XX_BOARD_LINKSYS_WRT300NV11, + BCM47XX_BOARD_LINKSYS_WRT310NV1, + BCM47XX_BOARD_LINKSYS_WRT310NV2, + BCM47XX_BOARD_LINKSYS_WRT54G3GV2, + BCM47XX_BOARD_LINKSYS_WRT610NV1, + BCM47XX_BOARD_LINKSYS_WRT610NV2, + BCM47XX_BOARD_LINKSYS_WRTSL54GS, + + BCM47XX_BOARD_MOTOROLA_WE800G, + BCM47XX_BOARD_MOTOROLA_WR850GP, + BCM47XX_BOARD_MOTOROLA_WR850GV2V3, + + BCM47XX_BOARD_NETGEAR_WGR614V8, + BCM47XX_BOARD_NETGEAR_WGR614V9, + BCM47XX_BOARD_NETGEAR_WNDR3300, + BCM47XX_BOARD_NETGEAR_WNDR3400V1, + BCM47XX_BOARD_NETGEAR_WNDR3400V2, + BCM47XX_BOARD_NETGEAR_WNDR3400VCNA, + BCM47XX_BOARD_NETGEAR_WNDR3700V3, + BCM47XX_BOARD_NETGEAR_WNDR4000, + BCM47XX_BOARD_NETGEAR_WNDR4500V1, + BCM47XX_BOARD_NETGEAR_WNDR4500V2, + BCM47XX_BOARD_NETGEAR_WNR2000, + BCM47XX_BOARD_NETGEAR_WNR3500L, + BCM47XX_BOARD_NETGEAR_WNR3500U, + BCM47XX_BOARD_NETGEAR_WNR3500V2, + BCM47XX_BOARD_NETGEAR_WNR3500V2VC, + BCM47XX_BOARD_NETGEAR_WNR834BV2, + + BCM47XX_BOARD_PHICOMM_M1, + + BCM47XX_BOARD_SIMPLETECH_SIMPLESHARE, + + BCM47XX_BOARD_ZTE_H218N, + + BCM47XX_BOARD_UNKNOWN, + BCM47XX_BOARD_NO, +}; + +#define BCM47XX_BOARD_MAX_NAME 30 + +void bcm47xx_board_detect(void); +enum bcm47xx_board bcm47xx_board_get(void); +const char *bcm47xx_board_get_name(void); + +#endif /* __BCM47XX_BOARD_H */ diff --git a/arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h b/arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h index b8e7be8f34dd..36a3fc1aa3ae 100644 --- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h +++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h @@ -48,4 +48,6 @@ static inline void bcm47xx_nvram_parse_macaddr(char *buf, u8 macaddr[6]) printk(KERN_WARNING "Can not parse mac address: %s\n", buf); } +int bcm47xx_nvram_gpio_pin(const char *name); + #endif /* __BCM47XX_NVRAM_H */ diff --git a/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h b/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h index 47fb247f9663..f9f448650505 100644 --- a/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h +++ b/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h @@ -52,23 +52,11 @@ static inline int plat_dma_supported(struct device *dev, u64 mask) return 0; } -static inline void plat_extra_sync_for_device(struct device *dev) -{ - BUG(); -} - static inline int plat_device_is_coherent(struct device *dev) { return 1; } -static inline int plat_dma_mapping_error(struct device *dev, - dma_addr_t dma_addr) -{ - BUG(); - return 0; -} - dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr); phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr); diff --git a/arch/mips/include/asm/mach-dec/cpu-feature-overrides.h b/arch/mips/include/asm/mach-dec/cpu-feature-overrides.h new file mode 100644 index 000000000000..acce27fd2bb8 --- /dev/null +++ b/arch/mips/include/asm/mach-dec/cpu-feature-overrides.h @@ -0,0 +1,87 @@ +/* + * CPU feature overrides for DECstation systems. Two variations + * are generally applicable. + * + * Copyright (C) 2013 Maciej W. Rozycki + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#ifndef __ASM_MACH_DEC_CPU_FEATURE_OVERRIDES_H +#define __ASM_MACH_DEC_CPU_FEATURE_OVERRIDES_H + +/* Generic ones first. */ +#define cpu_has_tlb 1 +#define cpu_has_tx39_cache 0 +#define cpu_has_fpu 1 +#define cpu_has_divec 0 +#define cpu_has_prefetch 0 +#define cpu_has_mcheck 0 +#define cpu_has_ejtag 0 +#define cpu_has_mips16 0 +#define cpu_has_mdmx 0 +#define cpu_has_mips3d 0 +#define cpu_has_smartmips 0 +#define cpu_has_rixi 0 +#define cpu_has_vtag_icache 0 +#define cpu_has_ic_fills_f_dc 0 +#define cpu_has_pindexed_dcache 0 +#define cpu_has_local_ebase 0 +#define cpu_icache_snoops_remote_store 1 +#define cpu_has_mips_4 0 +#define cpu_has_mips_5 0 +#define cpu_has_mips32r1 0 +#define cpu_has_mips32r2 0 +#define cpu_has_mips64r1 0 +#define cpu_has_mips64r2 0 +#define cpu_has_dsp 0 +#define cpu_has_mipsmt 0 +#define cpu_has_userlocal 0 + +/* R3k-specific ones. */ +#ifdef CONFIG_CPU_R3000 +#define cpu_has_4kex 0 +#define cpu_has_3k_cache 1 +#define cpu_has_4k_cache 0 +#define cpu_has_32fpr 0 +#define cpu_has_counter 0 +#define cpu_has_watch 0 +#define cpu_has_vce 0 +#define cpu_has_cache_cdex_p 0 +#define cpu_has_cache_cdex_s 0 +#define cpu_has_llsc 0 +#define cpu_has_dc_aliases 0 +#define cpu_has_mips_2 0 +#define cpu_has_mips_3 0 +#define cpu_has_nofpuex 1 +#define cpu_has_inclusive_pcaches 0 +#define cpu_dcache_line_size() 4 +#define cpu_icache_line_size() 4 +#define cpu_scache_line_size() 0 +#endif /* CONFIG_CPU_R3000 */ + +/* R4k-specific ones. */ +#ifdef CONFIG_CPU_R4X00 +#define cpu_has_4kex 1 +#define cpu_has_3k_cache 0 +#define cpu_has_4k_cache 1 +#define cpu_has_32fpr 1 +#define cpu_has_counter 1 +#define cpu_has_watch 1 +#define cpu_has_vce 1 +#define cpu_has_cache_cdex_p 1 +#define cpu_has_cache_cdex_s 1 +#define cpu_has_llsc 1 +#define cpu_has_dc_aliases (PAGE_SIZE < 0x4000) +#define cpu_has_mips_2 1 +#define cpu_has_mips_3 1 +#define cpu_has_nofpuex 0 +#define cpu_has_inclusive_pcaches 1 +#define cpu_dcache_line_size() 16 +#define cpu_icache_line_size() 16 +#define cpu_scache_line_size() 32 +#endif /* CONFIG_CPU_R4X00 */ + +#endif /* __ASM_MACH_DEC_CPU_FEATURE_OVERRIDES_H */ diff --git a/arch/mips/include/asm/mach-generic/dma-coherence.h b/arch/mips/include/asm/mach-generic/dma-coherence.h index 74cb99257d5b..a9e8f6b62b0b 100644 --- a/arch/mips/include/asm/mach-generic/dma-coherence.h +++ b/arch/mips/include/asm/mach-generic/dma-coherence.h @@ -47,16 +47,6 @@ static inline int plat_dma_supported(struct device *dev, u64 mask) return 1; } -static inline void plat_extra_sync_for_device(struct device *dev) -{ -} - -static inline int plat_dma_mapping_error(struct device *dev, - dma_addr_t dma_addr) -{ - return 0; -} - static inline int plat_device_is_coherent(struct device *dev) { #ifdef CONFIG_DMA_COHERENT diff --git a/arch/mips/include/asm/mach-ip27/dma-coherence.h b/arch/mips/include/asm/mach-ip27/dma-coherence.h index 06c441968e6e..4ffddfdb5062 100644 --- a/arch/mips/include/asm/mach-ip27/dma-coherence.h +++ b/arch/mips/include/asm/mach-ip27/dma-coherence.h @@ -58,16 +58,6 @@ static inline int plat_dma_supported(struct device *dev, u64 mask) return 1; } -static inline void plat_extra_sync_for_device(struct device *dev) -{ -} - -static inline int plat_dma_mapping_error(struct device *dev, - dma_addr_t dma_addr) -{ - return 0; -} - static inline int plat_device_is_coherent(struct device *dev) { return 1; /* IP27 non-cohernet mode is unsupported */ diff --git a/arch/mips/include/asm/mach-ip32/dma-coherence.h b/arch/mips/include/asm/mach-ip32/dma-coherence.h index 073f0c4760ba..104cfbc3ed63 100644 --- a/arch/mips/include/asm/mach-ip32/dma-coherence.h +++ b/arch/mips/include/asm/mach-ip32/dma-coherence.h @@ -80,17 +80,6 @@ static inline int plat_dma_supported(struct device *dev, u64 mask) return 1; } -static inline void plat_extra_sync_for_device(struct device *dev) -{ - return; -} - -static inline int plat_dma_mapping_error(struct device *dev, - dma_addr_t dma_addr) -{ - return 0; -} - static inline int plat_device_is_coherent(struct device *dev) { return 0; /* IP32 is non-cohernet */ diff --git a/arch/mips/include/asm/mach-jazz/dma-coherence.h b/arch/mips/include/asm/mach-jazz/dma-coherence.h index 9fc1e9ad7038..949003ef97b3 100644 --- a/arch/mips/include/asm/mach-jazz/dma-coherence.h +++ b/arch/mips/include/asm/mach-jazz/dma-coherence.h @@ -48,16 +48,6 @@ static inline int plat_dma_supported(struct device *dev, u64 mask) return 1; } -static inline void plat_extra_sync_for_device(struct device *dev) -{ -} - -static inline int plat_dma_mapping_error(struct device *dev, - dma_addr_t dma_addr) -{ - return 0; -} - static inline int plat_device_is_coherent(struct device *dev) { return 0; diff --git a/arch/mips/include/asm/mach-loongson/dma-coherence.h b/arch/mips/include/asm/mach-loongson/dma-coherence.h index e1433055fe98..aeb2c05d6145 100644 --- a/arch/mips/include/asm/mach-loongson/dma-coherence.h +++ b/arch/mips/include/asm/mach-loongson/dma-coherence.h @@ -53,16 +53,6 @@ static inline int plat_dma_supported(struct device *dev, u64 mask) return 1; } -static inline void plat_extra_sync_for_device(struct device *dev) -{ -} - -static inline int plat_dma_mapping_error(struct device *dev, - dma_addr_t dma_addr) -{ - return 0; -} - static inline int plat_device_is_coherent(struct device *dev) { return 0; diff --git a/arch/mips/include/asm/mach-powertv/asic.h b/arch/mips/include/asm/mach-powertv/asic.h deleted file mode 100644 index b341108d12f1..000000000000 --- a/arch/mips/include/asm/mach-powertv/asic.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2009 Cisco Systems, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that 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, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef _ASM_MACH_POWERTV_ASIC_H -#define _ASM_MACH_POWERTV_ASIC_H - -#include <linux/ioport.h> -#include <linux/platform_device.h> -#include <asm/mach-powertv/asic_regs.h> - -#define DVR_CAPABLE (1<<0) -#define PCIE_CAPABLE (1<<1) -#define FFS_CAPABLE (1<<2) -#define DISPLAY_CAPABLE (1<<3) - -/* Platform Family types - * For compitability, the new value must be added in the end */ -enum family_type { - FAMILY_8500, - FAMILY_8500RNG, - FAMILY_4500, - FAMILY_1500, - FAMILY_8600, - FAMILY_4600, - FAMILY_4600VZA, - FAMILY_8600VZB, - FAMILY_1500VZE, - FAMILY_1500VZF, - FAMILY_8700, - FAMILIES -}; - -/* Register maps for each ASIC */ -extern const struct register_map calliope_register_map; -extern const struct register_map cronus_register_map; -extern const struct register_map gaia_register_map; -extern const struct register_map zeus_register_map; - -extern struct resource dvr_cronus_resources[]; -extern struct resource dvr_gaia_resources[]; -extern struct resource dvr_zeus_resources[]; -extern struct resource non_dvr_calliope_resources[]; -extern struct resource non_dvr_cronus_resources[]; -extern struct resource non_dvr_cronuslite_resources[]; -extern struct resource non_dvr_gaia_resources[]; -extern struct resource non_dvr_vz_calliope_resources[]; -extern struct resource non_dvr_vze_calliope_resources[]; -extern struct resource non_dvr_vzf_calliope_resources[]; -extern struct resource non_dvr_zeus_resources[]; - -extern void powertv_platform_init(void); -extern void platform_alloc_bootmem(void); -extern enum asic_type platform_get_asic(void); -extern enum family_type platform_get_family(void); -extern int platform_supports_dvr(void); -extern int platform_supports_ffs(void); -extern int platform_supports_pcie(void); -extern int platform_supports_display(void); -extern void configure_platform(void); - -/* Platform Resources */ -#define ASIC_RESOURCE_GET_EXISTS 1 -extern struct resource *asic_resource_get(const char *name); -extern void platform_release_memory(void *baddr, int size); - -/* USB configuration */ -struct usb_hcd; /* Forward reference */ -extern void platform_configure_usb_ehci(void); -extern void platform_unconfigure_usb_ehci(void); -extern void platform_configure_usb_ohci(void); -extern void platform_unconfigure_usb_ohci(void); - -/* Resource for ASIC registers */ -extern struct resource asic_resource; -extern int platform_usb_devices_init(struct platform_device **echi_dev, - struct platform_device **ohci_dev); - -/* Reboot Cause */ -extern void set_reboot_cause(char code, unsigned int data, unsigned int data2); -extern void set_locked_reboot_cause(char code, unsigned int data, - unsigned int data2); - -enum sys_reboot_type { - sys_unknown_reboot = 0x00, /* Unknown reboot cause */ - sys_davic_change = 0x01, /* Reboot due to change in DAVIC - * mode */ - sys_user_reboot = 0x02, /* Reboot initiated by user */ - sys_system_reboot = 0x03, /* Reboot initiated by OS */ - sys_trap_reboot = 0x04, /* Reboot due to a CPU trap */ - sys_silent_reboot = 0x05, /* Silent reboot */ - sys_boot_ldr_reboot = 0x06, /* Bootloader reboot */ - sys_power_up_reboot = 0x07, /* Power on bootup. Older - * drivers may report as - * userReboot. */ - sys_code_change = 0x08, /* Reboot to take code change. - * Older drivers may report as - * userReboot. */ - sys_hardware_reset = 0x09, /* HW watchdog or front-panel - * reset button reset. Older - * drivers may report as - * userReboot. */ - sys_watchdogInterrupt = 0x0A /* Pre-watchdog interrupt */ -}; - -#endif /* _ASM_MACH_POWERTV_ASIC_H */ diff --git a/arch/mips/include/asm/mach-powertv/asic_reg_map.h b/arch/mips/include/asm/mach-powertv/asic_reg_map.h deleted file mode 100644 index 20348e817b09..000000000000 --- a/arch/mips/include/asm/mach-powertv/asic_reg_map.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * asic_reg_map.h - * - * A macro-enclosed list of the elements for the register_map structure for - * use in defining and manipulating the structure. - * - * Copyright (C) 2009 Cisco Systems, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that 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, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -REGISTER_MAP_ELEMENT(eic_slow0_strt_add) -REGISTER_MAP_ELEMENT(eic_cfg_bits) -REGISTER_MAP_ELEMENT(eic_ready_status) -REGISTER_MAP_ELEMENT(chipver3) -REGISTER_MAP_ELEMENT(chipver2) -REGISTER_MAP_ELEMENT(chipver1) -REGISTER_MAP_ELEMENT(chipver0) -REGISTER_MAP_ELEMENT(uart1_intstat) -REGISTER_MAP_ELEMENT(uart1_inten) -REGISTER_MAP_ELEMENT(uart1_config1) -REGISTER_MAP_ELEMENT(uart1_config2) -REGISTER_MAP_ELEMENT(uart1_divisorhi) -REGISTER_MAP_ELEMENT(uart1_divisorlo) -REGISTER_MAP_ELEMENT(uart1_data) -REGISTER_MAP_ELEMENT(uart1_status) -REGISTER_MAP_ELEMENT(int_stat_3) -REGISTER_MAP_ELEMENT(int_stat_2) -REGISTER_MAP_ELEMENT(int_stat_1) -REGISTER_MAP_ELEMENT(int_stat_0) -REGISTER_MAP_ELEMENT(int_config) -REGISTER_MAP_ELEMENT(int_int_scan) -REGISTER_MAP_ELEMENT(ien_int_3) -REGISTER_MAP_ELEMENT(ien_int_2) -REGISTER_MAP_ELEMENT(ien_int_1) -REGISTER_MAP_ELEMENT(ien_int_0) -REGISTER_MAP_ELEMENT(int_level_3_3) -REGISTER_MAP_ELEMENT(int_level_3_2) -REGISTER_MAP_ELEMENT(int_level_3_1) -REGISTER_MAP_ELEMENT(int_level_3_0) -REGISTER_MAP_ELEMENT(int_level_2_3) -REGISTER_MAP_ELEMENT(int_level_2_2) -REGISTER_MAP_ELEMENT(int_level_2_1) -REGISTER_MAP_ELEMENT(int_level_2_0) -REGISTER_MAP_ELEMENT(int_level_1_3) -REGISTER_MAP_ELEMENT(int_level_1_2) -REGISTER_MAP_ELEMENT(int_level_1_1) -REGISTER_MAP_ELEMENT(int_level_1_0) -REGISTER_MAP_ELEMENT(int_level_0_3) -REGISTER_MAP_ELEMENT(int_level_0_2) -REGISTER_MAP_ELEMENT(int_level_0_1) -REGISTER_MAP_ELEMENT(int_level_0_0) -REGISTER_MAP_ELEMENT(int_docsis_en) -REGISTER_MAP_ELEMENT(mips_pll_setup) -REGISTER_MAP_ELEMENT(fs432x4b4_usb_ctl) -REGISTER_MAP_ELEMENT(test_bus) -REGISTER_MAP_ELEMENT(crt_spare) -REGISTER_MAP_ELEMENT(usb2_ohci_int_mask) -REGISTER_MAP_ELEMENT(usb2_strap) -REGISTER_MAP_ELEMENT(ehci_hcapbase) -REGISTER_MAP_ELEMENT(ohci_hc_revision) -REGISTER_MAP_ELEMENT(bcm1_bs_lmi_steer) -REGISTER_MAP_ELEMENT(usb2_control) -REGISTER_MAP_ELEMENT(usb2_stbus_obc) -REGISTER_MAP_ELEMENT(usb2_stbus_mess_size) -REGISTER_MAP_ELEMENT(usb2_stbus_chunk_size) -REGISTER_MAP_ELEMENT(pcie_regs) -REGISTER_MAP_ELEMENT(tim_ch) -REGISTER_MAP_ELEMENT(tim_cl) -REGISTER_MAP_ELEMENT(gpio_dout) -REGISTER_MAP_ELEMENT(gpio_din) -REGISTER_MAP_ELEMENT(gpio_dir) -REGISTER_MAP_ELEMENT(watchdog) -REGISTER_MAP_ELEMENT(front_panel) -REGISTER_MAP_ELEMENT(misc_clk_ctl1) -REGISTER_MAP_ELEMENT(misc_clk_ctl2) -REGISTER_MAP_ELEMENT(crt_ext_ctl) -REGISTER_MAP_ELEMENT(register_maps) diff --git a/arch/mips/include/asm/mach-powertv/asic_regs.h b/arch/mips/include/asm/mach-powertv/asic_regs.h deleted file mode 100644 index 06712abb3e55..000000000000 --- a/arch/mips/include/asm/mach-powertv/asic_regs.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (C) 2009 Cisco Systems, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that 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, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef __ASM_MACH_POWERTV_ASIC_H_ -#define __ASM_MACH_POWERTV_ASIC_H_ -#include <linux/io.h> - -/* ASIC types */ -enum asic_type { - ASIC_UNKNOWN, - ASIC_ZEUS, - ASIC_CALLIOPE, - ASIC_CRONUS, - ASIC_CRONUSLITE, - ASIC_GAIA, - ASICS /* Number of supported ASICs */ -}; - -/* hardcoded values read from Chip Version registers */ -#define CRONUS_10 0x0B4C1C20 -#define CRONUS_11 0x0B4C1C21 -#define CRONUSLITE_10 0x0B4C1C40 - -#define NAND_FLASH_BASE 0x03000000 -#define CALLIOPE_IO_BASE 0x08000000 -#define GAIA_IO_BASE 0x09000000 -#define CRONUS_IO_BASE 0x09000000 -#define ZEUS_IO_BASE 0x09000000 - -#define ASIC_IO_SIZE 0x01000000 - -/* Definitions for backward compatibility */ -#define UART1_INTSTAT uart1_intstat -#define UART1_INTEN uart1_inten -#define UART1_CONFIG1 uart1_config1 -#define UART1_CONFIG2 uart1_config2 -#define UART1_DIVISORHI uart1_divisorhi -#define UART1_DIVISORLO uart1_divisorlo -#define UART1_DATA uart1_data -#define UART1_STATUS uart1_status - -/* ASIC register enumeration */ -union register_map_entry { - unsigned long phys; - u32 *virt; -}; - -#define REGISTER_MAP_ELEMENT(x) union register_map_entry x; -struct register_map { -#include <asm/mach-powertv/asic_reg_map.h> -}; -#undef REGISTER_MAP_ELEMENT - -/** - * register_map_offset_phys - add an offset to the physical address - * @map: Pointer to the &struct register_map - * @offset: Value to add - * - * Only adds the base to non-zero physical addresses - */ -static inline void register_map_offset_phys(struct register_map *map, - unsigned long offset) -{ -#define REGISTER_MAP_ELEMENT(x) do { \ - if (map->x.phys != 0) \ - map->x.phys += offset; \ - } while (false); - -#include <asm/mach-powertv/asic_reg_map.h> -#undef REGISTER_MAP_ELEMENT -} - -/** - * register_map_virtualize - Convert ®ister_map to virtual addresses - * @map: Pointer to ®ister_map to virtualize - */ -static inline void register_map_virtualize(struct register_map *map) -{ -#define REGISTER_MAP_ELEMENT(x) do { \ - map->x.virt = (!map->x.phys) ? NULL : \ - UNCAC_ADDR(phys_to_virt(map->x.phys)); \ - } while (false); - -#include <asm/mach-powertv/asic_reg_map.h> -#undef REGISTER_MAP_ELEMENT -} - -extern struct register_map _asic_register_map; -extern unsigned long asic_phy_base; - -/* - * Macros to interface to registers through their ioremapped address - * asic_reg_phys_addr Returns the physical address of the given register - * asic_reg_addr Returns the iomapped virtual address of the given - * register. - */ -#define asic_reg_addr(x) (_asic_register_map.x.virt) -#define asic_reg_phys_addr(x) (virt_to_phys((void *) CAC_ADDR( \ - (unsigned long) asic_reg_addr(x)))) - -/* - * The asic_reg macro is gone. It should be replaced by either asic_read or - * asic_write, as appropriate. - */ - -#define asic_read(x) readl(asic_reg_addr(x)) -#define asic_write(v, x) writel(v, asic_reg_addr(x)) - -extern void asic_irq_init(void); -#endif diff --git a/arch/mips/include/asm/mach-powertv/cpu-feature-overrides.h b/arch/mips/include/asm/mach-powertv/cpu-feature-overrides.h deleted file mode 100644 index 58c76ec32a19..000000000000 --- a/arch/mips/include/asm/mach-powertv/cpu-feature-overrides.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2010 Cisco Systems, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that 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, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef _ASM_MACH_POWERTV_CPU_FEATURE_OVERRIDES_H_ -#define _ASM_MACH_POWERTV_CPU_FEATURE_OVERRIDES_H_ -#define cpu_has_tlb 1 -#define cpu_has_4kex 1 -#define cpu_has_3k_cache 0 -#define cpu_has_4k_cache 1 -#define cpu_has_tx39_cache 0 -#define cpu_has_fpu 0 -#define cpu_has_counter 1 -#define cpu_has_watch 1 -#define cpu_has_divec 1 -#define cpu_has_vce 0 -#define cpu_has_cache_cdex_p 0 -#define cpu_has_cache_cdex_s 0 -#define cpu_has_mcheck 1 -#define cpu_has_ejtag 1 -#define cpu_has_llsc 1 -#define cpu_has_mips16 0 -#define cpu_has_mdmx 0 -#define cpu_has_mips3d 0 -#define cpu_has_smartmips 0 -#define cpu_has_vtag_icache 0 -#define cpu_has_dc_aliases 0 -#define cpu_has_ic_fills_f_dc 0 -#define cpu_has_mips32r1 0 -#define cpu_has_mips32r2 1 -#define cpu_has_mips64r1 0 -#define cpu_has_mips64r2 0 -#define cpu_has_dsp 0 -#define cpu_has_dsp2 0 -#define cpu_has_mipsmt 0 -#define cpu_has_userlocal 0 -#define cpu_has_nofpuex 0 -#define cpu_has_64bits 0 -#define cpu_has_64bit_zero_reg 0 -#define cpu_has_vint 1 -#define cpu_has_veic 1 -#define cpu_has_inclusive_pcaches 0 - -#define cpu_dcache_line_size() 32 -#define cpu_icache_line_size() 32 -#endif diff --git a/arch/mips/include/asm/mach-powertv/dma-coherence.h b/arch/mips/include/asm/mach-powertv/dma-coherence.h deleted file mode 100644 index f8316720a218..000000000000 --- a/arch/mips/include/asm/mach-powertv/dma-coherence.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Version from mach-generic modified to support PowerTV port - * Portions Copyright (C) 2009 Cisco Systems, Inc. - * Copyright (C) 2006 Ralf Baechle <ralf@linux-mips.org> - * - */ - -#ifndef __ASM_MACH_POWERTV_DMA_COHERENCE_H -#define __ASM_MACH_POWERTV_DMA_COHERENCE_H - -#include <linux/sched.h> -#include <linux/device.h> -#include <asm/mach-powertv/asic.h> - -static inline bool is_kseg2(void *addr) -{ - return (unsigned long)addr >= KSEG2; -} - -static inline unsigned long virt_to_phys_from_pte(void *addr) -{ - pgd_t *pgd; - pud_t *pud; - pmd_t *pmd; - pte_t *ptep, pte; - - unsigned long virt_addr = (unsigned long)addr; - unsigned long phys_addr = 0UL; - - /* get the page global directory. */ - pgd = pgd_offset_k(virt_addr); - - if (!pgd_none(*pgd)) { - /* get the page upper directory */ - pud = pud_offset(pgd, virt_addr); - if (!pud_none(*pud)) { - /* get the page middle directory */ - pmd = pmd_offset(pud, virt_addr); - if (!pmd_none(*pmd)) { - /* get a pointer to the page table entry */ - ptep = pte_offset(pmd, virt_addr); - pte = *ptep; - /* check for a valid page */ - if (pte_present(pte)) { - /* get the physical address the page is - * referring to */ - phys_addr = (unsigned long) - page_to_phys(pte_page(pte)); - /* add the offset within the page */ - phys_addr |= (virt_addr & ~PAGE_MASK); - } - } - } - } - - return phys_addr; -} - -static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, - size_t size) -{ - if (is_kseg2(addr)) - return phys_to_dma(virt_to_phys_from_pte(addr)); - else - return phys_to_dma(virt_to_phys(addr)); -} - -static inline dma_addr_t plat_map_dma_mem_page(struct device *dev, - struct page *page) -{ - return phys_to_dma(page_to_phys(page)); -} - -static inline unsigned long plat_dma_addr_to_phys(struct device *dev, - dma_addr_t dma_addr) -{ - return dma_to_phys(dma_addr); -} - -static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr, - size_t size, enum dma_data_direction direction) -{ -} - -static inline int plat_dma_supported(struct device *dev, u64 mask) -{ - /* - * we fall back to GFP_DMA when the mask isn't all 1s, - * so we can't guarantee allocations that must be - * within a tighter range than GFP_DMA.. - */ - if (mask < DMA_BIT_MASK(24)) - return 0; - - return 1; -} - -static inline void plat_extra_sync_for_device(struct device *dev) -{ -} - -static inline int plat_dma_mapping_error(struct device *dev, - dma_addr_t dma_addr) -{ - return 0; -} - -static inline int plat_device_is_coherent(struct device *dev) -{ - return 0; -} - -#endif /* __ASM_MACH_POWERTV_DMA_COHERENCE_H */ diff --git a/arch/mips/include/asm/mach-powertv/interrupts.h b/arch/mips/include/asm/mach-powertv/interrupts.h deleted file mode 100644 index 6c463be62156..000000000000 --- a/arch/mips/include/asm/mach-powertv/interrupts.h +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright (C) 2009 Cisco Systems, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that 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, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef _ASM_MACH_POWERTV_INTERRUPTS_H_ -#define _ASM_MACH_POWERTV_INTERRUPTS_H_ - -/* - * Defines for all of the interrupt lines - */ - -/* Definitions for backward compatibility */ -#define kIrq_Uart1 irq_uart1 - -#define ibase 0 - -/*------------- Register: int_stat_3 */ -/* 126 unused (bit 31) */ -#define irq_asc2video (ibase+126) /* ASC 2 Video Interrupt */ -#define irq_asc1video (ibase+125) /* ASC 1 Video Interrupt */ -#define irq_comms_block_wd (ibase+124) /* ASC 1 Video Interrupt */ -#define irq_fdma_mailbox (ibase+123) /* FDMA Mailbox Output */ -#define irq_fdma_gp (ibase+122) /* FDMA GP Output */ -#define irq_mips_pic (ibase+121) /* MIPS Performance Counter - * Interrupt */ -#define irq_mips_timer (ibase+120) /* MIPS Timer Interrupt */ -#define irq_memory_protect (ibase+119) /* Memory Protection Interrupt - * -- Ored by glue logic inside - * SPARC ILC (see - * INT_MEM_PROT_STAT, below, - * for individual interrupts) - */ -/* 118 unused (bit 22) */ -#define irq_sbag (ibase+117) /* SBAG Interrupt -- Ored by - * glue logic inside SPARC ILC - * (see INT_SBAG_STAT, below, - * for individual interrupts) */ -#define irq_qam_b_fec (ibase+116) /* QAM B FEC Interrupt */ -#define irq_qam_a_fec (ibase+115) /* QAM A FEC Interrupt */ -/* 114 unused (bit 18) */ -#define irq_mailbox (ibase+113) /* Mailbox Debug Interrupt -- - * Ored by glue logic inside - * SPARC ILC (see - * INT_MAILBOX_STAT, below, for - * individual interrupts) */ -#define irq_fuse_stat1 (ibase+112) /* Fuse Status 1 */ -#define irq_fuse_stat2 (ibase+111) /* Fuse Status 2 */ -#define irq_fuse_stat3 (ibase+110) /* Blitter Interrupt / Fuse - * Status 3 */ -#define irq_blitter (ibase+110) /* Blitter Interrupt / Fuse - * Status 3 */ -#define irq_avc1_pp0 (ibase+109) /* AVC Decoder #1 PP0 - * Interrupt */ -#define irq_avc1_pp1 (ibase+108) /* AVC Decoder #1 PP1 - * Interrupt */ -#define irq_avc1_mbe (ibase+107) /* AVC Decoder #1 MBE - * Interrupt */ -#define irq_avc2_pp0 (ibase+106) /* AVC Decoder #2 PP0 - * Interrupt */ -#define irq_avc2_pp1 (ibase+105) /* AVC Decoder #2 PP1 - * Interrupt */ -#define irq_avc2_mbe (ibase+104) /* AVC Decoder #2 MBE - * Interrupt */ -#define irq_zbug_spi (ibase+103) /* Zbug SPI Slave Interrupt */ -#define irq_qam_mod2 (ibase+102) /* QAM Modulator 2 DMA - * Interrupt */ -#define irq_ir_rx (ibase+101) /* IR RX 2 Interrupt */ -#define irq_aud_dsp2 (ibase+100) /* Audio DSP #2 Interrupt */ -#define irq_aud_dsp1 (ibase+99) /* Audio DSP #1 Interrupt */ -#define irq_docsis (ibase+98) /* DOCSIS Debug Interrupt */ -#define irq_sd_dvp1 (ibase+97) /* SD DVP #1 Interrupt */ -#define irq_sd_dvp2 (ibase+96) /* SD DVP #2 Interrupt */ -/*------------- Register: int_stat_2 */ -#define irq_hd_dvp (ibase+95) /* HD DVP Interrupt */ -#define kIrq_Prewatchdog (ibase+94) /* watchdog Pre-Interrupt */ -#define irq_timer2 (ibase+93) /* Programmable Timer - * Interrupt 2 */ -#define irq_1394 (ibase+92) /* 1394 Firewire Interrupt */ -#define irq_usbohci (ibase+91) /* USB 2.0 OHCI Interrupt */ -#define irq_usbehci (ibase+90) /* USB 2.0 EHCI Interrupt */ -#define irq_pciexp (ibase+89) /* PCI Express 0 Interrupt */ -#define irq_pciexp0 (ibase+89) /* PCI Express 0 Interrupt */ -#define irq_afe1 (ibase+88) /* AFE 1 Interrupt */ -#define irq_sata (ibase+87) /* SATA 1 Interrupt */ -#define irq_sata1 (ibase+87) /* SATA 1 Interrupt */ -#define irq_dtcp (ibase+86) /* DTCP Interrupt */ -#define irq_pciexp1 (ibase+85) /* PCI Express 1 Interrupt */ -/* 84 unused (bit 20) */ -/* 83 unused (bit 19) */ -/* 82 unused (bit 18) */ -#define irq_sata2 (ibase+81) /* SATA2 Interrupt */ -#define irq_uart2 (ibase+80) /* UART2 Interrupt */ -#define irq_legacy_usb (ibase+79) /* Legacy USB Host ISR (1.1 - * Host module) */ -#define irq_pod (ibase+78) /* POD Interrupt */ -#define irq_slave_usb (ibase+77) /* Slave USB */ -#define irq_denc1 (ibase+76) /* DENC #1 VTG Interrupt */ -#define irq_vbi_vtg (ibase+75) /* VBI VTG Interrupt */ -#define irq_afe2 (ibase+74) /* AFE 2 Interrupt */ -#define irq_denc2 (ibase+73) /* DENC #2 VTG Interrupt */ -#define irq_asc2 (ibase+72) /* ASC #2 Interrupt */ -#define irq_asc1 (ibase+71) /* ASC #1 Interrupt */ -#define irq_mod_dma (ibase+70) /* Modulator DMA Interrupt */ -#define irq_byte_eng1 (ibase+69) /* Byte Engine Interrupt [1] */ -#define irq_byte_eng0 (ibase+68) /* Byte Engine Interrupt [0] */ -/* 67 unused (bit 03) */ -/* 66 unused (bit 02) */ -/* 65 unused (bit 01) */ -/* 64 unused (bit 00) */ -/*------------- Register: int_stat_1 */ -/* 63 unused (bit 31) */ -/* 62 unused (bit 30) */ -/* 61 unused (bit 29) */ -/* 60 unused (bit 28) */ -/* 59 unused (bit 27) */ -/* 58 unused (bit 26) */ -/* 57 unused (bit 25) */ -/* 56 unused (bit 24) */ -#define irq_buf_dma_mem2mem (ibase+55) /* BufDMA Memory to Memory - * Interrupt */ -#define irq_buf_dma_usbtransmit (ibase+54) /* BufDMA USB Transmit - * Interrupt */ -#define irq_buf_dma_qpskpodtransmit (ibase+53) /* BufDMA QPSK/POD Tramsit - * Interrupt */ -#define irq_buf_dma_transmit_error (ibase+52) /* BufDMA Transmit Error - * Interrupt */ -#define irq_buf_dma_usbrecv (ibase+51) /* BufDMA USB Receive - * Interrupt */ -#define irq_buf_dma_qpskpodrecv (ibase+50) /* BufDMA QPSK/POD Receive - * Interrupt */ -#define irq_buf_dma_recv_error (ibase+49) /* BufDMA Receive Error - * Interrupt */ -#define irq_qamdma_transmit_play (ibase+48) /* QAMDMA Transmit/Play - * Interrupt */ -#define irq_qamdma_transmit_error (ibase+47) /* QAMDMA Transmit Error - * Interrupt */ -#define irq_qamdma_recv2high (ibase+46) /* QAMDMA Receive 2 High - * (Chans 63-32) */ -#define irq_qamdma_recv2low (ibase+45) /* QAMDMA Receive 2 Low - * (Chans 31-0) */ -#define irq_qamdma_recv1high (ibase+44) /* QAMDMA Receive 1 High - * (Chans 63-32) */ -#define irq_qamdma_recv1low (ibase+43) /* QAMDMA Receive 1 Low - * (Chans 31-0) */ -#define irq_qamdma_recv_error (ibase+42) /* QAMDMA Receive Error - * Interrupt */ -#define irq_mpegsplice (ibase+41) /* MPEG Splice Interrupt */ -#define irq_deinterlace_rdy (ibase+40) /* Deinterlacer Frame Ready - * Interrupt */ -#define irq_ext_in0 (ibase+39) /* External Interrupt irq_in0 */ -#define irq_gpio3 (ibase+38) /* GP I/O IRQ 3 - From GP I/O - * Module */ -#define irq_gpio2 (ibase+37) /* GP I/O IRQ 2 - From GP I/O - * Module (ABE_intN) */ -#define irq_pcrcmplt1 (ibase+36) /* PCR Capture Complete or - * Discontinuity 1 */ -#define irq_pcrcmplt2 (ibase+35) /* PCR Capture Complete or - * Discontinuity 2 */ -#define irq_parse_peierr (ibase+34) /* PID Parser Error Detect - * (PEI) */ -#define irq_parse_cont_err (ibase+33) /* PID Parser continuity error - * detect */ -#define irq_ds1framer (ibase+32) /* DS1 Framer Interrupt */ -/*------------- Register: int_stat_0 */ -#define irq_gpio1 (ibase+31) /* GP I/O IRQ 1 - From GP I/O - * Module */ -#define irq_gpio0 (ibase+30) /* GP I/O IRQ 0 - From GP I/O - * Module */ -#define irq_qpsk_out_aloha (ibase+29) /* QPSK Output Slotted Aloha - * (chan 3) Transmission - * Completed OK */ -#define irq_qpsk_out_tdma (ibase+28) /* QPSK Output TDMA (chan 2) - * Transmission Completed OK */ -#define irq_qpsk_out_reserve (ibase+27) /* QPSK Output Reservation - * (chan 1) Transmission - * Completed OK */ -#define irq_qpsk_out_aloha_err (ibase+26) /* QPSK Output Slotted Aloha - * (chan 3)Transmission - * completed with Errors. */ -#define irq_qpsk_out_tdma_err (ibase+25) /* QPSK Output TDMA (chan 2) - * Transmission completed with - * Errors. */ -#define irq_qpsk_out_rsrv_err (ibase+24) /* QPSK Output Reservation - * (chan 1) Transmission - * completed with Errors */ -#define irq_aloha_fail (ibase+23) /* Unsuccessful Resend of Aloha - * for N times. Aloha retry - * timeout for channel 3. */ -#define irq_timer1 (ibase+22) /* Programmable Timer - * Interrupt */ -#define irq_keyboard (ibase+21) /* Keyboard Module Interrupt */ -#define irq_i2c (ibase+20) /* I2C Module Interrupt */ -#define irq_spi (ibase+19) /* SPI Module Interrupt */ -#define irq_irblaster (ibase+18) /* IR Blaster Interrupt */ -#define irq_splice_detect (ibase+17) /* PID Key Change Interrupt or - * Splice Detect Interrupt */ -#define irq_se_micro (ibase+16) /* Secure Micro I/F Module - * Interrupt */ -#define irq_uart1 (ibase+15) /* UART Interrupt */ -#define irq_irrecv (ibase+14) /* IR Receiver Interrupt */ -#define irq_host_int1 (ibase+13) /* Host-to-Host Interrupt 1 */ -#define irq_host_int0 (ibase+12) /* Host-to-Host Interrupt 0 */ -#define irq_qpsk_hecerr (ibase+11) /* QPSK HEC Error Interrupt */ -#define irq_qpsk_crcerr (ibase+10) /* QPSK AAL-5 CRC Error - * Interrupt */ -/* 9 unused (bit 09) */ -/* 8 unused (bit 08) */ -#define irq_psicrcerr (ibase+7) /* QAM PSI CRC Error - * Interrupt */ -#define irq_psilength_err (ibase+6) /* QAM PSI Length Error - * Interrupt */ -#define irq_esfforward (ibase+5) /* ESF Interrupt Mark From - * Forward Path Reference - - * every 3ms when forward Mbits - * and forward slot control - * bytes are updated. */ -#define irq_esfreverse (ibase+4) /* ESF Interrupt Mark from - * Reverse Path Reference - - * delayed from forward mark by - * the ranging delay plus a - * fixed amount. When reverse - * Mbits and reverse slot - * control bytes are updated. - * Occurs every 3ms for 3.0M and - * 1.554 M upstream rates and - * every 6 ms for 256K upstream - * rate. */ -#define irq_aloha_timeout (ibase+3) /* Slotted-Aloha timeout on - * Channel 1. */ -#define irq_reservation (ibase+2) /* Partial (or Incremental) - * Reservation Message Completed - * or Slotted aloha verify for - * channel 1. */ -#define irq_aloha3 (ibase+1) /* Slotted-Aloha Message Verify - * Interrupt or Reservation - * increment completed for - * channel 3. */ -#define irq_mpeg_d (ibase+0) /* MPEG Decoder Interrupt */ -#endif /* _ASM_MACH_POWERTV_INTERRUPTS_H_ */ diff --git a/arch/mips/include/asm/mach-powertv/ioremap.h b/arch/mips/include/asm/mach-powertv/ioremap.h deleted file mode 100644 index c86ef094ec37..000000000000 --- a/arch/mips/include/asm/mach-powertv/ioremap.h +++ /dev/null @@ -1,167 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Portions Copyright (C) Cisco Systems, Inc. - */ -#ifndef __ASM_MACH_POWERTV_IOREMAP_H -#define __ASM_MACH_POWERTV_IOREMAP_H - -#include <linux/types.h> -#include <linux/log2.h> -#include <linux/compiler.h> - -#include <asm/pgtable-bits.h> -#include <asm/addrspace.h> - -/* We're going to mess with bits, so get sizes */ -#define IOR_BPC 8 /* Bits per char */ -#define IOR_PHYS_BITS (IOR_BPC * sizeof(phys_addr_t)) -#define IOR_DMA_BITS (IOR_BPC * sizeof(dma_addr_t)) - -/* - * Define the granularity of physical/DMA mapping in terms of the number - * of bits that defines the offset within a grain. These will be the - * least significant bits of the address. The rest of a physical or DMA - * address will be used to index into an appropriate table to find the - * offset to add to the address to yield the corresponding DMA or physical - * address, respectively. - */ -#define IOR_LSBITS 22 /* Bits in a grain */ - -/* - * Compute the number of most significant address bits after removing those - * used for the offset within a grain and then compute the number of table - * entries for the conversion. - */ -#define IOR_PHYS_MSBITS (IOR_PHYS_BITS - IOR_LSBITS) -#define IOR_NUM_PHYS_TO_DMA ((phys_addr_t) 1 << IOR_PHYS_MSBITS) - -#define IOR_DMA_MSBITS (IOR_DMA_BITS - IOR_LSBITS) -#define IOR_NUM_DMA_TO_PHYS ((dma_addr_t) 1 << IOR_DMA_MSBITS) - -/* - * Define data structures used as elements in the arrays for the conversion - * between physical and DMA addresses. We do some slightly fancy math to - * compute the width of the offset element of the conversion tables so - * that we can have the smallest conversion tables. Next, round up the - * sizes to the next higher power of two, i.e. the offset element will have - * 8, 16, 32, 64, etc. bits. This eliminates the need to mask off any - * bits. Finally, we compute a shift value that puts the most significant - * bits of the offset into the most significant bits of the offset element. - * This makes it more efficient on processors without barrel shifters and - * easier to see the values if the conversion table is dumped in binary. - */ -#define _IOR_OFFSET_WIDTH(n) (1 << order_base_2(n)) -#define IOR_OFFSET_WIDTH(n) \ - (_IOR_OFFSET_WIDTH(n) < 8 ? 8 : _IOR_OFFSET_WIDTH(n)) - -#define IOR_PHYS_OFFSET_BITS IOR_OFFSET_WIDTH(IOR_PHYS_MSBITS) -#define IOR_PHYS_SHIFT (IOR_PHYS_BITS - IOR_PHYS_OFFSET_BITS) - -#define IOR_DMA_OFFSET_BITS IOR_OFFSET_WIDTH(IOR_DMA_MSBITS) -#define IOR_DMA_SHIFT (IOR_DMA_BITS - IOR_DMA_OFFSET_BITS) - -struct ior_phys_to_dma { - dma_addr_t offset:IOR_DMA_OFFSET_BITS __packed - __aligned((IOR_DMA_OFFSET_BITS / IOR_BPC)); -}; - -struct ior_dma_to_phys { - dma_addr_t offset:IOR_PHYS_OFFSET_BITS __packed - __aligned((IOR_PHYS_OFFSET_BITS / IOR_BPC)); -}; - -extern struct ior_phys_to_dma _ior_phys_to_dma[IOR_NUM_PHYS_TO_DMA]; -extern struct ior_dma_to_phys _ior_dma_to_phys[IOR_NUM_DMA_TO_PHYS]; - -static inline dma_addr_t _phys_to_dma_offset_raw(phys_addr_t phys) -{ - return (dma_addr_t)_ior_phys_to_dma[phys >> IOR_LSBITS].offset; -} - -static inline dma_addr_t _dma_to_phys_offset_raw(dma_addr_t dma) -{ - return (dma_addr_t)_ior_dma_to_phys[dma >> IOR_LSBITS].offset; -} - -/* These are not portable and should not be used in drivers. Drivers should - * be using ioremap() and friends to map physical addresses to virtual - * addresses and dma_map*() and friends to map virtual addresses into DMA - * addresses and back. - */ -static inline dma_addr_t phys_to_dma(phys_addr_t phys) -{ - return phys + (_phys_to_dma_offset_raw(phys) << IOR_PHYS_SHIFT); -} - -static inline phys_addr_t dma_to_phys(dma_addr_t dma) -{ - return dma + (_dma_to_phys_offset_raw(dma) << IOR_DMA_SHIFT); -} - -extern void ioremap_add_map(dma_addr_t phys, phys_addr_t alias, - dma_addr_t size); - -/* - * Allow physical addresses to be fixed up to help peripherals located - * outside the low 32-bit range -- generic pass-through version. - */ -static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) -{ - return phys_addr; -} - -/* - * Handle the special case of addresses the area aliased into the first - * 512 MiB of the processor's physical address space. These turn into either - * kseg0 or kseg1 addresses, depending on flags. - */ -static inline void __iomem *plat_ioremap(phys_t start, unsigned long size, - unsigned long flags) -{ - phys_addr_t start_offset; - void __iomem *result = NULL; - - /* Start by checking to see whether this is an aliased address */ - start_offset = _dma_to_phys_offset_raw(start); - - /* - * If: - * o the memory is aliased into the first 512 MiB, and - * o the start and end are in the same RAM bank, and - * o we don't have a zero size or wrap around, and - * o we are supposed to create an uncached mapping, - * handle this is a kseg0 or kseg1 address - */ - if (start_offset != 0) { - phys_addr_t last; - dma_addr_t dma_to_phys_offset; - - last = start + size - 1; - dma_to_phys_offset = - _dma_to_phys_offset_raw(last) << IOR_DMA_SHIFT; - - if (dma_to_phys_offset == start_offset && - size != 0 && start <= last) { - phys_t adjusted_start; - adjusted_start = start + start_offset; - if (flags == _CACHE_UNCACHED) - result = (void __iomem *) (unsigned long) - CKSEG1ADDR(adjusted_start); - else - result = (void __iomem *) (unsigned long) - CKSEG0ADDR(adjusted_start); - } - } - - return result; -} - -static inline int plat_iounmap(const volatile void __iomem *addr) -{ - return 0; -} -#endif /* __ASM_MACH_POWERTV_IOREMAP_H */ diff --git a/arch/mips/include/asm/mach-powertv/war.h b/arch/mips/include/asm/mach-powertv/war.h deleted file mode 100644 index c5651c8e58d1..000000000000 --- a/arch/mips/include/asm/mach-powertv/war.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * This version for the PowerTV platform copied from the Malta version. - * - * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org> - * Portions copyright (C) 2009 Cisco Systems, Inc. - */ -#ifndef __ASM_MACH_POWERTV_WAR_H -#define __ASM_MACH_POWERTV_WAR_H - -#define R4600_V1_INDEX_ICACHEOP_WAR 0 -#define R4600_V1_HIT_CACHEOP_WAR 0 -#define R4600_V2_HIT_CACHEOP_WAR 0 -#define R5432_CP0_INTERRUPT_WAR 0 -#define BCM1250_M3_WAR 0 -#define SIBYTE_1956_WAR 0 -#define MIPS4K_ICACHE_REFILL_WAR 1 -#define MIPS_CACHE_SYNC_WAR 1 -#define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define ICACHE_REFILLS_WORKAROUND_WAR 1 -#define R10000_LLSC_WAR 0 -#define MIPS34K_MISSED_ITLB_WAR 0 - -#endif /* __ASM_MACH_POWERTV_WAR_H */ diff --git a/arch/mips/include/asm/mips-boards/piix4.h b/arch/mips/include/asm/mips-boards/piix4.h index a02596cf1abd..e33227998713 100644 --- a/arch/mips/include/asm/mips-boards/piix4.h +++ b/arch/mips/include/asm/mips-boards/piix4.h @@ -1,6 +1,7 @@ /* * Carsten Langgaard, carstenl@mips.com * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. + * Copyright (C) 2013 Imagination Technologies Ltd. * * This program is free software; you can distribute it and/or modify it * under the terms of the GNU General Public License (Version 2) as @@ -20,61 +21,26 @@ #ifndef __ASM_MIPS_BOARDS_PIIX4_H #define __ASM_MIPS_BOARDS_PIIX4_H -/************************************************************************ - * IO register offsets - ************************************************************************/ -#define PIIX4_ICTLR1_ICW1 0x20 -#define PIIX4_ICTLR1_ICW2 0x21 -#define PIIX4_ICTLR1_ICW3 0x21 -#define PIIX4_ICTLR1_ICW4 0x21 -#define PIIX4_ICTLR2_ICW1 0xa0 -#define PIIX4_ICTLR2_ICW2 0xa1 -#define PIIX4_ICTLR2_ICW3 0xa1 -#define PIIX4_ICTLR2_ICW4 0xa1 -#define PIIX4_ICTLR1_OCW1 0x21 -#define PIIX4_ICTLR1_OCW2 0x20 -#define PIIX4_ICTLR1_OCW3 0x20 -#define PIIX4_ICTLR1_OCW4 0x20 -#define PIIX4_ICTLR2_OCW1 0xa1 -#define PIIX4_ICTLR2_OCW2 0xa0 -#define PIIX4_ICTLR2_OCW3 0xa0 -#define PIIX4_ICTLR2_OCW4 0xa0 - - -/************************************************************************ - * Register encodings. - ************************************************************************/ -#define PIIX4_OCW2_NSEOI (0x1 << 5) -#define PIIX4_OCW2_SEOI (0x3 << 5) -#define PIIX4_OCW2_RNSEOI (0x5 << 5) -#define PIIX4_OCW2_RAEOIS (0x4 << 5) -#define PIIX4_OCW2_RAEOIC (0x0 << 5) -#define PIIX4_OCW2_RSEOI (0x7 << 5) -#define PIIX4_OCW2_SP (0x6 << 5) -#define PIIX4_OCW2_NOP (0x2 << 5) - -#define PIIX4_OCW2_SEL (0x0 << 3) - -#define PIIX4_OCW2_ILS_0 0 -#define PIIX4_OCW2_ILS_1 1 -#define PIIX4_OCW2_ILS_2 2 -#define PIIX4_OCW2_ILS_3 3 -#define PIIX4_OCW2_ILS_4 4 -#define PIIX4_OCW2_ILS_5 5 -#define PIIX4_OCW2_ILS_6 6 -#define PIIX4_OCW2_ILS_7 7 -#define PIIX4_OCW2_ILS_8 0 -#define PIIX4_OCW2_ILS_9 1 -#define PIIX4_OCW2_ILS_10 2 -#define PIIX4_OCW2_ILS_11 3 -#define PIIX4_OCW2_ILS_12 4 -#define PIIX4_OCW2_ILS_13 5 -#define PIIX4_OCW2_ILS_14 6 -#define PIIX4_OCW2_ILS_15 7 - -#define PIIX4_OCW3_SEL (0x1 << 3) - -#define PIIX4_OCW3_IRR 0x2 -#define PIIX4_OCW3_ISR 0x3 +/* PIRQX Route Control */ +#define PIIX4_FUNC0_PIRQRC 0x60 +#define PIIX4_FUNC0_PIRQRC_IRQ_ROUTING_DISABLE (1 << 7) +#define PIIX4_FUNC0_PIRQRC_IRQ_ROUTING_MASK 0xf +#define PIIX4_FUNC0_PIRQRC_IRQ_ROUTING_MAX 16 +/* Top Of Memory */ +#define PIIX4_FUNC0_TOM 0x69 +#define PIIX4_FUNC0_TOM_TOP_OF_MEMORY_MASK 0xf0 +/* Deterministic Latency Control */ +#define PIIX4_FUNC0_DLC 0x82 +#define PIIX4_FUNC0_DLC_USBPR_EN (1 << 2) +#define PIIX4_FUNC0_DLC_PASSIVE_RELEASE_EN (1 << 1) +#define PIIX4_FUNC0_DLC_DELAYED_TRANSACTION_EN (1 << 0) + +/* IDE Timing */ +#define PIIX4_FUNC1_IDETIM_PRIMARY_LO 0x40 +#define PIIX4_FUNC1_IDETIM_PRIMARY_HI 0x41 +#define PIIX4_FUNC1_IDETIM_PRIMARY_HI_IDE_DECODE_EN (1 << 7) +#define PIIX4_FUNC1_IDETIM_SECONDARY_LO 0x42 +#define PIIX4_FUNC1_IDETIM_SECONDARY_HI 0x43 +#define PIIX4_FUNC1_IDETIM_SECONDARY_HI_IDE_DECODE_EN (1 << 7) #endif /* __ASM_MIPS_BOARDS_PIIX4_H */ diff --git a/arch/mips/include/asm/mmu_context.h b/arch/mips/include/asm/mmu_context.h index 3b29079b5424..e277bbad2871 100644 --- a/arch/mips/include/asm/mmu_context.h +++ b/arch/mips/include/asm/mmu_context.h @@ -24,21 +24,21 @@ #endif /* SMTC */ #include <asm-generic/mm_hooks.h> -#ifdef CONFIG_MIPS_PGD_C0_CONTEXT - #define TLBMISS_HANDLER_SETUP_PGD(pgd) \ do { \ extern void tlbmiss_handler_setup_pgd(unsigned long); \ tlbmiss_handler_setup_pgd((unsigned long)(pgd)); \ } while (0) +#ifdef CONFIG_MIPS_PGD_C0_CONTEXT #define TLBMISS_HANDLER_SETUP() \ do { \ TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir); \ - write_c0_xcontext((unsigned long) smp_processor_id() << 51); \ + write_c0_xcontext((unsigned long) smp_processor_id() << \ + SMP_CPUID_REGSHIFT); \ } while (0) -#else /* CONFIG_MIPS_PGD_C0_CONTEXT: using pgd_current*/ +#else /* !CONFIG_MIPS_PGD_C0_CONTEXT: using pgd_current*/ /* * For the fast tlb miss handlers, we keep a per cpu array of pointers @@ -47,21 +47,11 @@ do { \ */ extern unsigned long pgd_current[]; -#define TLBMISS_HANDLER_SETUP_PGD(pgd) \ - pgd_current[smp_processor_id()] = (unsigned long)(pgd) - -#ifdef CONFIG_32BIT #define TLBMISS_HANDLER_SETUP() \ - write_c0_context((unsigned long) smp_processor_id() << 25); \ + write_c0_context((unsigned long) smp_processor_id() << \ + SMP_CPUID_REGSHIFT); \ back_to_back_c0_hazard(); \ TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir) -#endif -#ifdef CONFIG_64BIT -#define TLBMISS_HANDLER_SETUP() \ - write_c0_context((unsigned long) smp_processor_id() << 26); \ - back_to_back_c0_hazard(); \ - TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir) -#endif #endif /* CONFIG_MIPS_PGD_C0_CONTEXT*/ #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) diff --git a/arch/mips/include/asm/netlogic/xlp-hal/xlp.h b/arch/mips/include/asm/netlogic/xlp-hal/xlp.h index 17daffb280a3..470f2095b346 100644 --- a/arch/mips/include/asm/netlogic/xlp-hal/xlp.h +++ b/arch/mips/include/asm/netlogic/xlp-hal/xlp.h @@ -69,6 +69,7 @@ void nlm_hal_init(void); int xlp_get_dram_map(int n, uint64_t *dram_map); /* Device tree related */ +void xlp_early_init_devtree(void); void *xlp_dt_init(void *fdtp); static inline int cpu_is_xlpii(void) diff --git a/arch/mips/include/asm/octeon/cvmx-pip.h b/arch/mips/include/asm/octeon/cvmx-pip.h index a76fe5a57a9f..df69bfd2b006 100644 --- a/arch/mips/include/asm/octeon/cvmx-pip.h +++ b/arch/mips/include/asm/octeon/cvmx-pip.h @@ -192,13 +192,13 @@ typedef struct { /* Number of packets processed by PIP */ uint32_t packets; /* - * Number of indentified L2 multicast packets. Does not + * Number of identified L2 multicast packets. Does not * include broadcast packets. Only includes packets whose * parse mode is SKIP_TO_L2 */ uint32_t multicast_packets; /* - * Number of indentified L2 broadcast packets. Does not + * Number of identified L2 broadcast packets. Does not * include multicast packets. Only includes packets whose * parse mode is SKIP_TO_L2 */ diff --git a/arch/mips/include/asm/pgalloc.h b/arch/mips/include/asm/pgalloc.h index 881d18b4e298..b336037e8768 100644 --- a/arch/mips/include/asm/pgalloc.h +++ b/arch/mips/include/asm/pgalloc.h @@ -80,9 +80,12 @@ static inline struct page *pte_alloc_one(struct mm_struct *mm, struct page *pte; pte = alloc_pages(GFP_KERNEL | __GFP_REPEAT, PTE_ORDER); - if (pte) { - clear_highpage(pte); - pgtable_page_ctor(pte); + if (!pte) + return NULL; + clear_highpage(pte); + if (!pgtable_page_ctor(pte)) { + __free_page(pte); + return NULL; } return pte; } diff --git a/arch/mips/include/asm/prom.h b/arch/mips/include/asm/prom.h index 1e7e0961064b..ccd2b75f152c 100644 --- a/arch/mips/include/asm/prom.h +++ b/arch/mips/include/asm/prom.h @@ -17,22 +17,8 @@ #include <linux/types.h> #include <asm/bootinfo.h> -extern int early_init_dt_scan_memory_arch(unsigned long node, - const char *uname, int depth, void *data); - extern void device_tree_init(void); -static inline unsigned long pci_address_to_pio(phys_addr_t address) -{ - /* - * The ioport address can be directly used by inX() / outX() - */ - BUG_ON(address > IO_SPACE_LIMIT); - - return (unsigned long) address; -} -#define pci_address_to_pio pci_address_to_pio - struct boot_param_header; extern void __dt_setup_arch(struct boot_param_header *bph); diff --git a/arch/mips/include/asm/ptrace.h b/arch/mips/include/asm/ptrace.h index 5e6cd0947393..7bba9da110af 100644 --- a/arch/mips/include/asm/ptrace.h +++ b/arch/mips/include/asm/ptrace.h @@ -81,7 +81,6 @@ static inline long regs_return_value(struct pt_regs *regs) #define instruction_pointer(regs) ((regs)->cp0_epc) #define profile_pc(regs) instruction_pointer(regs) -#define user_stack_pointer(r) ((r)->regs[29]) extern asmlinkage void syscall_trace_enter(struct pt_regs *regs); extern asmlinkage void syscall_trace_leave(struct pt_regs *regs); @@ -100,4 +99,17 @@ static inline void die_if_kernel(const char *str, struct pt_regs *regs) (struct pt_regs *)((sp | (THREAD_SIZE - 1)) + 1 - 32) - 1; \ }) +/* Helpers for working with the user stack pointer */ + +static inline unsigned long user_stack_pointer(struct pt_regs *regs) +{ + return regs->regs[29]; +} + +static inline void user_stack_pointer_set(struct pt_regs *regs, + unsigned long val) +{ + regs->regs[29] = val; +} + #endif /* _ASM_PTRACE_H */ diff --git a/arch/mips/include/asm/r4kcache.h b/arch/mips/include/asm/r4kcache.h index a0b2650516ac..34d1a1917125 100644 --- a/arch/mips/include/asm/r4kcache.h +++ b/arch/mips/include/asm/r4kcache.h @@ -15,6 +15,7 @@ #include <asm/asm.h> #include <asm/cacheops.h> #include <asm/cpu-features.h> +#include <asm/cpu-type.h> #include <asm/mipsmtregs.h> /* @@ -162,7 +163,15 @@ static inline void flush_scache_line_indexed(unsigned long addr) static inline void flush_icache_line(unsigned long addr) { __iflush_prologue - cache_op(Hit_Invalidate_I, addr); + switch (boot_cpu_type()) { + case CPU_LOONGSON2: + cache_op(Hit_Invalidate_I_Loongson23, addr); + break; + + default: + cache_op(Hit_Invalidate_I, addr); + break; + } __iflush_epilogue } @@ -208,7 +217,15 @@ static inline void flush_scache_line(unsigned long addr) */ static inline void protected_flush_icache_line(unsigned long addr) { - protected_cache_op(Hit_Invalidate_I, addr); + switch (boot_cpu_type()) { + case CPU_LOONGSON2: + protected_cache_op(Hit_Invalidate_I_Loongson23, addr); + break; + + default: + protected_cache_op(Hit_Invalidate_I, addr); + break; + } } /* @@ -412,8 +429,8 @@ __BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 64 __BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 128) /* build blast_xxx_range, protected_blast_xxx_range */ -#define __BUILD_BLAST_CACHE_RANGE(pfx, desc, hitop, prot) \ -static inline void prot##blast_##pfx##cache##_range(unsigned long start, \ +#define __BUILD_BLAST_CACHE_RANGE(pfx, desc, hitop, prot, extra) \ +static inline void prot##extra##blast_##pfx##cache##_range(unsigned long start, \ unsigned long end) \ { \ unsigned long lsize = cpu_##desc##_line_size(); \ @@ -432,13 +449,15 @@ static inline void prot##blast_##pfx##cache##_range(unsigned long start, \ __##pfx##flush_epilogue \ } -__BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, protected_) -__BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, protected_) -__BUILD_BLAST_CACHE_RANGE(i, icache, Hit_Invalidate_I, protected_) -__BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, ) -__BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, ) +__BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, protected_, ) +__BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, protected_, ) +__BUILD_BLAST_CACHE_RANGE(i, icache, Hit_Invalidate_I, protected_, ) +__BUILD_BLAST_CACHE_RANGE(i, icache, Hit_Invalidate_I_Loongson23, \ + protected_, loongson23_) +__BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, , ) +__BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, , ) /* blast_inv_dcache_range */ -__BUILD_BLAST_CACHE_RANGE(inv_d, dcache, Hit_Invalidate_D, ) -__BUILD_BLAST_CACHE_RANGE(inv_s, scache, Hit_Invalidate_SD, ) +__BUILD_BLAST_CACHE_RANGE(inv_d, dcache, Hit_Invalidate_D, , ) +__BUILD_BLAST_CACHE_RANGE(inv_s, scache, Hit_Invalidate_SD, , ) #endif /* _ASM_R4KCACHE_H */ diff --git a/arch/mips/include/asm/setup.h b/arch/mips/include/asm/setup.h index e26589ef36ee..d7bfdeba9e84 100644 --- a/arch/mips/include/asm/setup.h +++ b/arch/mips/include/asm/setup.h @@ -5,6 +5,14 @@ extern void setup_early_printk(void); +#ifdef CONFIG_EARLY_PRINTK_8250 +extern void setup_8250_early_printk_port(unsigned long base, + unsigned int reg_shift, unsigned int timeout); +#else +static inline void setup_8250_early_printk_port(unsigned long base, + unsigned int reg_shift, unsigned int timeout) {} +#endif + extern void set_handler(unsigned long offset, void *addr, unsigned long len); extern void set_uncached_handler(unsigned long offset, void *addr, unsigned long len); diff --git a/arch/mips/include/asm/stackframe.h b/arch/mips/include/asm/stackframe.h index 23fc95e65673..4857e2c8df5a 100644 --- a/arch/mips/include/asm/stackframe.h +++ b/arch/mips/include/asm/stackframe.h @@ -17,6 +17,7 @@ #include <asm/asmmacro.h> #include <asm/mipsregs.h> #include <asm/asm-offsets.h> +#include <asm/thread_info.h> /* * For SMTC kernel, global IE should be left set, and interrupts @@ -93,21 +94,8 @@ .endm #ifdef CONFIG_SMP -#ifdef CONFIG_MIPS_MT_SMTC -#define PTEBASE_SHIFT 19 /* TCBIND */ -#define CPU_ID_REG CP0_TCBIND -#define CPU_ID_MFC0 mfc0 -#elif defined(CONFIG_MIPS_PGD_C0_CONTEXT) -#define PTEBASE_SHIFT 48 /* XCONTEXT */ -#define CPU_ID_REG CP0_XCONTEXT -#define CPU_ID_MFC0 MFC0 -#else -#define PTEBASE_SHIFT 23 /* CONTEXT */ -#define CPU_ID_REG CP0_CONTEXT -#define CPU_ID_MFC0 MFC0 -#endif .macro get_saved_sp /* SMP variation */ - CPU_ID_MFC0 k0, CPU_ID_REG + ASM_CPUID_MFC0 k0, ASM_SMP_CPUID_REG #if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32) lui k1, %hi(kernelsp) #else @@ -117,17 +105,17 @@ daddiu k1, %hi(kernelsp) dsll k1, 16 #endif - LONG_SRL k0, PTEBASE_SHIFT + LONG_SRL k0, SMP_CPUID_PTRSHIFT LONG_ADDU k1, k0 LONG_L k1, %lo(kernelsp)(k1) .endm .macro set_saved_sp stackp temp temp2 - CPU_ID_MFC0 \temp, CPU_ID_REG - LONG_SRL \temp, PTEBASE_SHIFT + ASM_CPUID_MFC0 \temp, ASM_SMP_CPUID_REG + LONG_SRL \temp, SMP_CPUID_PTRSHIFT LONG_S \stackp, kernelsp(\temp) .endm -#else +#else /* !CONFIG_SMP */ .macro get_saved_sp /* Uniprocessor variation */ #ifdef CONFIG_CPU_JUMP_WORKAROUNDS /* diff --git a/arch/mips/include/asm/syscall.h b/arch/mips/include/asm/syscall.h new file mode 100644 index 000000000000..81c89132c59d --- /dev/null +++ b/arch/mips/include/asm/syscall.h @@ -0,0 +1,116 @@ +/* + * Access to user system call parameters and results + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * See asm-generic/syscall.h for descriptions of what we must do here. + * + * Copyright (C) 2012 Ralf Baechle <ralf@linux-mips.org> + */ + +#ifndef __ASM_MIPS_SYSCALL_H +#define __ASM_MIPS_SYSCALL_H + +#include <linux/audit.h> +#include <linux/elf-em.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/uaccess.h> +#include <asm/ptrace.h> + +static inline long syscall_get_nr(struct task_struct *task, + struct pt_regs *regs) +{ + return regs->regs[2]; +} + +static inline unsigned long mips_get_syscall_arg(unsigned long *arg, + struct task_struct *task, struct pt_regs *regs, unsigned int n) +{ + unsigned long usp = regs->regs[29]; + + switch (n) { + case 0: case 1: case 2: case 3: + *arg = regs->regs[4 + n]; + + return 0; + +#ifdef CONFIG_32BIT + case 4: case 5: case 6: case 7: + return get_user(*arg, (int *)usp + 4 * n); +#endif + +#ifdef CONFIG_64BIT + case 4: case 5: case 6: case 7: +#ifdef CONFIG_MIPS32_O32 + if (test_thread_flag(TIF_32BIT_REGS)) + return get_user(*arg, (int *)usp + 4 * n); + else +#endif + *arg = regs->regs[4 + n]; + + return 0; +#endif + + default: + BUG(); + } +} + +static inline long syscall_get_return_value(struct task_struct *task, + struct pt_regs *regs) +{ + return regs->regs[2]; +} + +static inline void syscall_set_return_value(struct task_struct *task, + struct pt_regs *regs, + int error, long val) +{ + if (error) { + regs->regs[2] = -error; + regs->regs[7] = -1; + } else { + regs->regs[2] = val; + regs->regs[7] = 0; + } +} + +static inline void syscall_get_arguments(struct task_struct *task, + struct pt_regs *regs, + unsigned int i, unsigned int n, + unsigned long *args) +{ + unsigned long arg; + int ret; + + while (n--) + ret |= mips_get_syscall_arg(&arg, task, regs, i++); + + /* + * No way to communicate an error because this is a void function. + */ +#if 0 + return ret; +#endif +} + +extern const unsigned long sys_call_table[]; +extern const unsigned long sys32_call_table[]; +extern const unsigned long sysn32_call_table[]; + +static inline int __syscall_get_arch(void) +{ + int arch = EM_MIPS; +#ifdef CONFIG_64BIT + arch |= __AUDIT_ARCH_64BIT; +#endif +#if defined(__LITTLE_ENDIAN) + arch |= __AUDIT_ARCH_LE; +#endif + return arch; +} + +#endif /* __ASM_MIPS_SYSCALL_H */ diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h index 61215a34acc6..4f58ef6d0eed 100644 --- a/arch/mips/include/asm/thread_info.h +++ b/arch/mips/include/asm/thread_info.h @@ -92,8 +92,6 @@ static inline struct thread_info *current_thread_info(void) #define STACK_WARN (THREAD_SIZE / 8) -#define PREEMPT_ACTIVE 0x10000000 - /* * thread information flags * - these are process state flags that various assembly files may need to @@ -116,6 +114,7 @@ static inline struct thread_info *current_thread_info(void) #define TIF_32BIT_ADDR 23 /* 32-bit address space (o32/n32) */ #define TIF_FPUBOUND 24 /* thread bound to FPU-full CPU set */ #define TIF_LOAD_WATCH 25 /* If set, load watch registers */ +#define TIF_SYSCALL_TRACEPOINT 26 /* syscall tracepoint instrumentation */ #define TIF_SYSCALL_TRACE 31 /* syscall trace active */ #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) @@ -132,21 +131,54 @@ static inline struct thread_info *current_thread_info(void) #define _TIF_32BIT_ADDR (1<<TIF_32BIT_ADDR) #define _TIF_FPUBOUND (1<<TIF_FPUBOUND) #define _TIF_LOAD_WATCH (1<<TIF_LOAD_WATCH) +#define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT) #define _TIF_WORK_SYSCALL_ENTRY (_TIF_NOHZ | _TIF_SYSCALL_TRACE | \ - _TIF_SYSCALL_AUDIT) + _TIF_SYSCALL_AUDIT | _TIF_SYSCALL_TRACEPOINT) /* work to do in syscall_trace_leave() */ #define _TIF_WORK_SYSCALL_EXIT (_TIF_NOHZ | _TIF_SYSCALL_TRACE | \ - _TIF_SYSCALL_AUDIT) + _TIF_SYSCALL_AUDIT | _TIF_SYSCALL_TRACEPOINT) /* work to do on interrupt/exception return */ #define _TIF_WORK_MASK \ (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_NOTIFY_RESUME) /* work to do on any return to u-space */ #define _TIF_ALLWORK_MASK (_TIF_NOHZ | _TIF_WORK_MASK | \ - _TIF_WORK_SYSCALL_EXIT) + _TIF_WORK_SYSCALL_EXIT | \ + _TIF_SYSCALL_TRACEPOINT) -#endif /* __KERNEL__ */ +/* + * We stash processor id into a COP0 register to retrieve it fast + * at kernel exception entry. + */ +#if defined(CONFIG_MIPS_MT_SMTC) +#define SMP_CPUID_REG 2, 2 /* TCBIND */ +#define ASM_SMP_CPUID_REG $2, 2 +#define SMP_CPUID_PTRSHIFT 19 +#elif defined(CONFIG_MIPS_PGD_C0_CONTEXT) +#define SMP_CPUID_REG 20, 0 /* XCONTEXT */ +#define ASM_SMP_CPUID_REG $20 +#define SMP_CPUID_PTRSHIFT 48 +#else +#define SMP_CPUID_REG 4, 0 /* CONTEXT */ +#define ASM_SMP_CPUID_REG $4 +#define SMP_CPUID_PTRSHIFT 23 +#endif +#ifdef CONFIG_64BIT +#define SMP_CPUID_REGSHIFT (SMP_CPUID_PTRSHIFT + 3) +#else +#define SMP_CPUID_REGSHIFT (SMP_CPUID_PTRSHIFT + 2) +#endif + +#ifdef CONFIG_MIPS_MT_SMTC +#define ASM_CPUID_MFC0 mfc0 +#define UASM_i_CPUID_MFC0 uasm_i_mfc0 +#else +#define ASM_CPUID_MFC0 MFC0 +#define UASM_i_CPUID_MFC0 UASM_i_MFC0 +#endif + +#endif /* __KERNEL__ */ #endif /* _ASM_THREAD_INFO_H */ diff --git a/arch/mips/include/asm/time.h b/arch/mips/include/asm/time.h index 2d7b9df4542d..24f534a7fbc3 100644 --- a/arch/mips/include/asm/time.h +++ b/arch/mips/include/asm/time.h @@ -75,7 +75,7 @@ extern int init_r4k_clocksource(void); static inline int init_mips_clocksource(void) { -#if defined(CONFIG_CSRC_R4K) && !defined(CONFIG_CSRC_GIC) +#ifdef CONFIG_CSRC_R4K return init_r4k_clocksource(); #else return 0; diff --git a/arch/mips/include/asm/unistd.h b/arch/mips/include/asm/unistd.h index 63c9c886173a..4d3b92886665 100644 --- a/arch/mips/include/asm/unistd.h +++ b/arch/mips/include/asm/unistd.h @@ -14,6 +14,13 @@ #include <uapi/asm/unistd.h> +#ifdef CONFIG_MIPS32_N32 +#define NR_syscalls (__NR_N32_Linux + __NR_N32_Linux_syscalls) +#elif defined(CONFIG_64BIT) +#define NR_syscalls (__NR_64_Linux + __NR_64_Linux_syscalls) +#else +#define NR_syscalls (__NR_O32_Linux + __NR_O32_Linux_syscalls) +#endif #ifndef __ASSEMBLY__ diff --git a/arch/mips/include/uapi/asm/errno.h b/arch/mips/include/uapi/asm/errno.h index 31575e2fd1bd..02d645d7aa9a 100644 --- a/arch/mips/include/uapi/asm/errno.h +++ b/arch/mips/include/uapi/asm/errno.h @@ -102,7 +102,7 @@ #define EWOULDBLOCK EAGAIN /* Operation would block */ #define EALREADY 149 /* Operation already in progress */ #define EINPROGRESS 150 /* Operation now in progress */ -#define ESTALE 151 /* Stale NFS file handle */ +#define ESTALE 151 /* Stale file handle */ #define ECANCELED 158 /* AIO operation canceled */ /* diff --git a/arch/mips/include/uapi/asm/siginfo.h b/arch/mips/include/uapi/asm/siginfo.h index 88e292b7719e..e81174432bab 100644 --- a/arch/mips/include/uapi/asm/siginfo.h +++ b/arch/mips/include/uapi/asm/siginfo.h @@ -33,6 +33,8 @@ struct siginfo; #error _MIPS_SZLONG neither 32 nor 64 #endif +#define __ARCH_SIGSYS + #include <asm-generic/siginfo.h> typedef struct siginfo { @@ -97,6 +99,13 @@ typedef struct siginfo { __ARCH_SI_BAND_T _band; /* POLL_IN, POLL_OUT, POLL_MSG */ int _fd; } _sigpoll; + + /* SIGSYS */ + struct { + void __user *_call_addr; /* calling user insn */ + int _syscall; /* triggering system call number */ + unsigned int _arch; /* AUDIT_ARCH_* of syscall */ + } _sigsys; } _sifields; } siginfo_t; diff --git a/arch/mips/include/uapi/asm/socket.h b/arch/mips/include/uapi/asm/socket.h index 61c01f054d1b..0df9787cd84d 100644 --- a/arch/mips/include/uapi/asm/socket.h +++ b/arch/mips/include/uapi/asm/socket.h @@ -94,4 +94,6 @@ #define SO_BUSY_POLL 46 +#define SO_MAX_PACING_RATE 47 + #endif /* _UAPI_ASM_SOCKET_H */ diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 423d871a946b..1c1b71752c84 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -26,7 +26,6 @@ obj-$(CONFIG_CEVT_TXX9) += cevt-txx9.o obj-$(CONFIG_CSRC_BCM1480) += csrc-bcm1480.o obj-$(CONFIG_CSRC_GIC) += csrc-gic.o obj-$(CONFIG_CSRC_IOASIC) += csrc-ioasic.o -obj-$(CONFIG_CSRC_POWERTV) += csrc-powertv.o obj-$(CONFIG_CSRC_R4K) += csrc-r4k.o obj-$(CONFIG_CSRC_SB1250) += csrc-sb1250.o obj-$(CONFIG_SYNC_R4K) += sync-r4k.o @@ -35,6 +34,7 @@ obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_MODULES) += mips_ksyms.o module.o obj-$(CONFIG_MODULES_USE_ELF_RELA) += module-rela.o +obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o obj-$(CONFIG_FUNCTION_TRACER) += mcount.o ftrace.o obj-$(CONFIG_CPU_R4K_FPU) += r4k_fpu.o r4k_switch.o @@ -84,6 +84,7 @@ obj-$(CONFIG_GPIO_TXX9) += gpio_txx9.o obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o crash.o obj-$(CONFIG_CRASH_DUMP) += crash_dump.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o +obj-$(CONFIG_EARLY_PRINTK_8250) += early_printk_8250.o obj-$(CONFIG_SPINLOCK_TEST) += spinlock_test.o obj-$(CONFIG_MIPS_MACHINE) += mips_machine.o diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index 5465dc183e5a..c814287bdf5d 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -376,13 +376,33 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) __cpu_name[cpu] = "R4000PC"; } } else { + int cca = read_c0_config() & CONF_CM_CMASK; + int mc; + + /* + * SC and MC versions can't be reliably told apart, + * but only the latter support coherent caching + * modes so assume the firmware has set the KSEG0 + * coherency attribute reasonably (if uncached, we + * assume SC). + */ + switch (cca) { + case CONF_CM_CACHABLE_CE: + case CONF_CM_CACHABLE_COW: + case CONF_CM_CACHABLE_CUW: + mc = 1; + break; + default: + mc = 0; + break; + } if ((c->processor_id & PRID_REV_MASK) >= PRID_REV_R4400) { - c->cputype = CPU_R4400SC; - __cpu_name[cpu] = "R4400SC"; + c->cputype = mc ? CPU_R4400MC : CPU_R4400SC; + __cpu_name[cpu] = mc ? "R4400MC" : "R4400SC"; } else { - c->cputype = CPU_R4000SC; - __cpu_name[cpu] = "R4000SC"; + c->cputype = mc ? CPU_R4000MC : CPU_R4000SC; + __cpu_name[cpu] = mc ? "R4000MC" : "R4000SC"; } } @@ -1079,8 +1099,8 @@ void cpu_report(void) { struct cpuinfo_mips *c = ¤t_cpu_data; - printk(KERN_INFO "CPU revision is: %08x (%s)\n", - c->processor_id, cpu_name_string()); + pr_info("CPU%d revision is: %08x (%s)\n", + smp_processor_id(), c->processor_id, cpu_name_string()); if (c->options & MIPS_CPU_FPU) printk(KERN_INFO "FPU revision is: %08x\n", c->fpu_id); } diff --git a/arch/mips/kernel/csrc-powertv.c b/arch/mips/kernel/csrc-powertv.c deleted file mode 100644 index abd99ea911ae..000000000000 --- a/arch/mips/kernel/csrc-powertv.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (C) 2008 Scientific-Atlanta, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that 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, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ -/* - * The file comes from kernel/csrc-r4k.c - */ -#include <linux/clocksource.h> -#include <linux/init.h> - -#include <asm/time.h> /* Not included in linux/time.h */ - -#include <asm/mach-powertv/asic_regs.h> -#include "powertv-clock.h" - -/* MIPS PLL Register Definitions */ -#define PLL_GET_M(x) (((x) >> 8) & 0x000000FF) -#define PLL_GET_N(x) (((x) >> 16) & 0x000000FF) -#define PLL_GET_P(x) (((x) >> 24) & 0x00000007) - -/* - * returns: Clock frequency in kHz - */ -unsigned int __init mips_get_pll_freq(void) -{ - unsigned int pll_reg, m, n, p; - unsigned int fin = 54000; /* Base frequency in kHz */ - unsigned int fout; - - /* Read PLL register setting */ - pll_reg = asic_read(mips_pll_setup); - m = PLL_GET_M(pll_reg); - n = PLL_GET_N(pll_reg); - p = PLL_GET_P(pll_reg); - pr_info("MIPS PLL Register:0x%x M=%d N=%d P=%d\n", pll_reg, m, n, p); - - /* Calculate clock frequency = (2 * N * 54MHz) / (M * (2**P)) */ - fout = ((2 * n * fin) / (m * (0x01 << p))); - - pr_info("MIPS Clock Freq=%d kHz\n", fout); - - return fout; -} - -static cycle_t c0_hpt_read(struct clocksource *cs) -{ - return read_c0_count(); -} - -static struct clocksource clocksource_mips = { - .name = "powertv-counter", - .read = c0_hpt_read, - .mask = CLOCKSOURCE_MASK(32), - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - -static void __init powertv_c0_hpt_clocksource_init(void) -{ - unsigned int pll_freq = mips_get_pll_freq(); - - pr_info("CPU frequency %d.%02d MHz\n", pll_freq / 1000, - (pll_freq % 1000) * 100 / 1000); - - mips_hpt_frequency = pll_freq / 2 * 1000; - - clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000; - - clocksource_register_hz(&clocksource_mips, mips_hpt_frequency); -} - -/** - * struct tim_c - free running counter - * @hi: High 16 bits of the counter - * @lo: Low 32 bits of the counter - * - * Lays out the structure of the free running counter in memory. This counter - * increments at a rate of 27 MHz/8 on all platforms. - */ -struct tim_c { - unsigned int hi; - unsigned int lo; -}; - -static struct tim_c *tim_c; - -static cycle_t tim_c_read(struct clocksource *cs) -{ - unsigned int hi; - unsigned int next_hi; - unsigned int lo; - - hi = readl(&tim_c->hi); - - for (;;) { - lo = readl(&tim_c->lo); - next_hi = readl(&tim_c->hi); - if (next_hi == hi) - break; - hi = next_hi; - } - -pr_crit("%s: read %llx\n", __func__, ((u64) hi << 32) | lo); - return ((u64) hi << 32) | lo; -} - -#define TIM_C_SIZE 48 /* # bits in the timer */ - -static struct clocksource clocksource_tim_c = { - .name = "powertv-tim_c", - .read = tim_c_read, - .mask = CLOCKSOURCE_MASK(TIM_C_SIZE), - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - -/** - * powertv_tim_c_clocksource_init - set up a clock source for the TIM_C clock - * - * We know that TIM_C counts at 27 MHz/8, so each cycle corresponds to - * 1 / (27,000,000/8) seconds. - */ -static void __init powertv_tim_c_clocksource_init(void) -{ - const unsigned long counts_per_second = 27000000 / 8; - - clocksource_tim_c.rating = 200; - - clocksource_register_hz(&clocksource_tim_c, counts_per_second); - tim_c = (struct tim_c *) asic_reg_addr(tim_ch); -} - -/** - powertv_clocksource_init - initialize all clocksources - */ -void __init powertv_clocksource_init(void) -{ - powertv_c0_hpt_clocksource_init(); - powertv_tim_c_clocksource_init(); -} diff --git a/arch/mips/kernel/early_printk_8250.c b/arch/mips/kernel/early_printk_8250.c new file mode 100644 index 000000000000..83cea3767556 --- /dev/null +++ b/arch/mips/kernel/early_printk_8250.c @@ -0,0 +1,66 @@ +/* + * 8250/16550-type serial ports prom_putchar() + * + * Copyright (C) 2010 Yoichi Yuasa <yuasa@linux-mips.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include <linux/io.h> +#include <linux/serial_core.h> +#include <linux/serial_reg.h> + +static void __iomem *serial8250_base; +static unsigned int serial8250_reg_shift; +static unsigned int serial8250_tx_timeout; + +void setup_8250_early_printk_port(unsigned long base, unsigned int reg_shift, + unsigned int timeout) +{ + serial8250_base = (void __iomem *)base; + serial8250_reg_shift = reg_shift; + serial8250_tx_timeout = timeout; +} + +static inline u8 serial_in(int offset) +{ + return readb(serial8250_base + (offset << serial8250_reg_shift)); +} + +static inline void serial_out(int offset, char value) +{ + writeb(value, serial8250_base + (offset << serial8250_reg_shift)); +} + +void prom_putchar(char c) +{ + unsigned int timeout; + int status, bits; + + if (!serial8250_base) + return; + + timeout = serial8250_tx_timeout; + bits = UART_LSR_TEMT | UART_LSR_THRE; + + do { + status = serial_in(UART_LSR); + + if (--timeout == 0) + break; + } while ((status & bits) != bits); + + if (timeout) + serial_out(UART_TX, c); +} diff --git a/arch/mips/kernel/ftrace.c b/arch/mips/kernel/ftrace.c index dba90ec0dc38..185ba258361b 100644 --- a/arch/mips/kernel/ftrace.c +++ b/arch/mips/kernel/ftrace.c @@ -11,11 +11,14 @@ #include <linux/uaccess.h> #include <linux/init.h> #include <linux/ftrace.h> +#include <linux/syscalls.h> #include <asm/asm.h> #include <asm/asm-offsets.h> #include <asm/cacheflush.h> +#include <asm/syscall.h> #include <asm/uasm.h> +#include <asm/unistd.h> #include <asm-generic/sections.h> @@ -364,3 +367,33 @@ out: WARN_ON(1); } #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ + +#ifdef CONFIG_FTRACE_SYSCALLS + +#ifdef CONFIG_32BIT +unsigned long __init arch_syscall_addr(int nr) +{ + return (unsigned long)sys_call_table[nr - __NR_O32_Linux]; +} +#endif + +#ifdef CONFIG_64BIT + +unsigned long __init arch_syscall_addr(int nr) +{ +#ifdef CONFIG_MIPS32_N32 + if (nr >= __NR_N32_Linux && nr <= __NR_N32_Linux + __NR_N32_Linux_syscalls) + return (unsigned long)sysn32_call_table[nr - __NR_N32_Linux]; +#endif + if (nr >= __NR_64_Linux && nr <= __NR_64_Linux + __NR_64_Linux_syscalls) + return (unsigned long)sys_call_table[nr - __NR_64_Linux]; +#ifdef CONFIG_MIPS32_O32 + if (nr >= __NR_O32_Linux && nr <= __NR_O32_Linux + __NR_O32_Linux_syscalls) + return (unsigned long)sys32_call_table[nr - __NR_O32_Linux]; +#endif + + return (unsigned long) &sys_ni_syscall; +} +#endif + +#endif /* CONFIG_FTRACE_SYSCALLS */ diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S index 31fa856829cb..47d7583cd67f 100644 --- a/arch/mips/kernel/genex.S +++ b/arch/mips/kernel/genex.S @@ -374,12 +374,20 @@ NESTED(except_vec_nmi, 0, sp) NESTED(nmi_handler, PT_SIZE, sp) .set push .set noat + /* + * Clear ERL - restore segment mapping + * Clear BEV - required for page fault exception handler to work + */ + mfc0 k0, CP0_STATUS + ori k0, k0, ST0_EXL + li k1, ~(ST0_BEV | ST0_ERL) + and k0, k0, k1 + mtc0 k0, CP0_STATUS + _ehb SAVE_ALL move a0, sp jal nmi_exception_handler - RESTORE_ALL - .set mips3 - eret + /* nmi_exception_handler never returns */ .set pop END(nmi_handler) diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c index 72ef2d25cbf2..e498f2b3646a 100644 --- a/arch/mips/kernel/irq_cpu.c +++ b/arch/mips/kernel/irq_cpu.c @@ -150,7 +150,7 @@ int __init mips_cpu_intc_init(struct device_node *of_node, domain = irq_domain_add_legacy(of_node, 8, MIPS_CPU_IRQ_BASE, 0, &mips_cpu_intc_irq_domain_ops, NULL); if (!domain) - panic("Failed to add irqdomain for MIPS CPU\n"); + panic("Failed to add irqdomain for MIPS CPU"); return 0; } diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c index 977a623d9253..2a52568dbcd6 100644 --- a/arch/mips/kernel/module.c +++ b/arch/mips/kernel/module.c @@ -23,6 +23,7 @@ #include <linux/moduleloader.h> #include <linux/elf.h> #include <linux/mm.h> +#include <linux/numa.h> #include <linux/vmalloc.h> #include <linux/slab.h> #include <linux/fs.h> @@ -46,7 +47,7 @@ static DEFINE_SPINLOCK(dbe_lock); void *module_alloc(unsigned long size) { return __vmalloc_node_range(size, 1, MODULE_START, MODULE_END, - GFP_KERNEL, PAGE_KERNEL, -1, + GFP_KERNEL, PAGE_KERNEL, NUMA_NO_NODE, __builtin_return_address(0)); } #endif diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c index 45f1ffcf1a4b..24cdf64789c3 100644 --- a/arch/mips/kernel/perf_event_mipsxx.c +++ b/arch/mips/kernel/perf_event_mipsxx.c @@ -971,11 +971,11 @@ static const struct mips_perf_event mipsxx74Kcore_cache_map [C(LL)] = { [C(OP_READ)] = { [C(RESULT_ACCESS)] = { 0x1c, CNTR_ODD, P }, - [C(RESULT_MISS)] = { 0x1d, CNTR_EVEN | CNTR_ODD, P }, + [C(RESULT_MISS)] = { 0x1d, CNTR_EVEN, P }, }, [C(OP_WRITE)] = { [C(RESULT_ACCESS)] = { 0x1c, CNTR_ODD, P }, - [C(RESULT_MISS)] = { 0x1d, CNTR_EVEN | CNTR_ODD, P }, + [C(RESULT_MISS)] = { 0x1d, CNTR_EVEN, P }, }, }, [C(ITLB)] = { diff --git a/arch/mips/kernel/prom.c b/arch/mips/kernel/prom.c index 0fa0b69cdd53..3c3b0df8f48d 100644 --- a/arch/mips/kernel/prom.c +++ b/arch/mips/kernel/prom.c @@ -13,12 +13,9 @@ #include <linux/errno.h> #include <linux/types.h> #include <linux/bootmem.h> -#include <linux/initrd.h> #include <linux/debugfs.h> #include <linux/of.h> #include <linux/of_fdt.h> -#include <linux/of_irq.h> -#include <linux/of_platform.h> #include <asm/page.h> #include <asm/prom.h> @@ -40,13 +37,6 @@ char *mips_get_machine_name(void) } #ifdef CONFIG_OF -int __init early_init_dt_scan_memory_arch(unsigned long node, - const char *uname, int depth, - void *data) -{ - return early_init_dt_scan_memory(node, uname, depth, data); -} - void __init early_init_dt_add_memory_arch(u64 base, u64 size) { return add_memory_region(base, size, BOOT_MEM_RAM); @@ -57,57 +47,11 @@ void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) return __alloc_bootmem(size, align, __pa(MAX_DMA_ADDRESS)); } -#ifdef CONFIG_BLK_DEV_INITRD -void __init early_init_dt_setup_initrd_arch(u64 start, u64 end) -{ - initrd_start = (unsigned long)__va(start); - initrd_end = (unsigned long)__va(end); - initrd_below_start_ok = 1; -} -#endif - -int __init early_init_dt_scan_model(unsigned long node, const char *uname, - int depth, void *data) -{ - if (!depth) { - char *model = of_get_flat_dt_prop(node, "model", NULL); - - if (model) - mips_set_machine_name(model); - } - return 0; -} - -void __init early_init_devtree(void *params) -{ - /* Setup flat device-tree pointer */ - initial_boot_params = params; - - /* Retrieve various informations from the /chosen node of the - * device-tree, including the platform type, initrd location and - * size, and more ... - */ - of_scan_flat_dt(early_init_dt_scan_chosen, arcs_cmdline); - - - /* Scan memory nodes */ - of_scan_flat_dt(early_init_dt_scan_root, NULL); - of_scan_flat_dt(early_init_dt_scan_memory_arch, NULL); - - /* try to load the mips machine name */ - of_scan_flat_dt(early_init_dt_scan_model, NULL); -} - void __init __dt_setup_arch(struct boot_param_header *bph) { - if (be32_to_cpu(bph->magic) != OF_DT_HEADER) { - pr_err("DTB has bad magic, ignoring builtin OF DTB\n"); - + if (!early_init_dt_scan(bph)) return; - } - - initial_boot_params = bph; - early_init_devtree(initial_boot_params); + mips_set_machine_name(of_flat_dt_get_machine_name()); } #endif diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c index 8ae1ebef8b71..b52e1d2b33e0 100644 --- a/arch/mips/kernel/ptrace.c +++ b/arch/mips/kernel/ptrace.c @@ -16,16 +16,20 @@ */ #include <linux/compiler.h> #include <linux/context_tracking.h> +#include <linux/elf.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/mm.h> #include <linux/errno.h> #include <linux/ptrace.h> +#include <linux/regset.h> #include <linux/smp.h> #include <linux/user.h> #include <linux/security.h> +#include <linux/tracehook.h> #include <linux/audit.h> #include <linux/seccomp.h> +#include <linux/ftrace.h> #include <asm/byteorder.h> #include <asm/cpu.h> @@ -35,10 +39,14 @@ #include <asm/mipsmtregs.h> #include <asm/pgtable.h> #include <asm/page.h> +#include <asm/syscall.h> #include <asm/uaccess.h> #include <asm/bootinfo.h> #include <asm/reg.h> +#define CREATE_TRACE_POINTS +#include <trace/events/syscalls.h> + /* * Called by kernel/ptrace.c when detaching.. * @@ -255,6 +263,133 @@ int ptrace_set_watch_regs(struct task_struct *child, return 0; } +/* regset get/set implementations */ + +static int gpr_get(struct task_struct *target, + const struct user_regset *regset, + unsigned int pos, unsigned int count, + void *kbuf, void __user *ubuf) +{ + struct pt_regs *regs = task_pt_regs(target); + + return user_regset_copyout(&pos, &count, &kbuf, &ubuf, + regs, 0, sizeof(*regs)); +} + +static int gpr_set(struct task_struct *target, + const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf) +{ + struct pt_regs newregs; + int ret; + + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + &newregs, + 0, sizeof(newregs)); + if (ret) + return ret; + + *task_pt_regs(target) = newregs; + + return 0; +} + +static int fpr_get(struct task_struct *target, + const struct user_regset *regset, + unsigned int pos, unsigned int count, + void *kbuf, void __user *ubuf) +{ + return user_regset_copyout(&pos, &count, &kbuf, &ubuf, + &target->thread.fpu, + 0, sizeof(elf_fpregset_t)); + /* XXX fcr31 */ +} + +static int fpr_set(struct task_struct *target, + const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf) +{ + return user_regset_copyin(&pos, &count, &kbuf, &ubuf, + &target->thread.fpu, + 0, sizeof(elf_fpregset_t)); + /* XXX fcr31 */ +} + +enum mips_regset { + REGSET_GPR, + REGSET_FPR, +}; + +static const struct user_regset mips_regsets[] = { + [REGSET_GPR] = { + .core_note_type = NT_PRSTATUS, + .n = ELF_NGREG, + .size = sizeof(unsigned int), + .align = sizeof(unsigned int), + .get = gpr_get, + .set = gpr_set, + }, + [REGSET_FPR] = { + .core_note_type = NT_PRFPREG, + .n = ELF_NFPREG, + .size = sizeof(elf_fpreg_t), + .align = sizeof(elf_fpreg_t), + .get = fpr_get, + .set = fpr_set, + }, +}; + +static const struct user_regset_view user_mips_view = { + .name = "mips", + .e_machine = ELF_ARCH, + .ei_osabi = ELF_OSABI, + .regsets = mips_regsets, + .n = ARRAY_SIZE(mips_regsets), +}; + +static const struct user_regset mips64_regsets[] = { + [REGSET_GPR] = { + .core_note_type = NT_PRSTATUS, + .n = ELF_NGREG, + .size = sizeof(unsigned long), + .align = sizeof(unsigned long), + .get = gpr_get, + .set = gpr_set, + }, + [REGSET_FPR] = { + .core_note_type = NT_PRFPREG, + .n = ELF_NFPREG, + .size = sizeof(elf_fpreg_t), + .align = sizeof(elf_fpreg_t), + .get = fpr_get, + .set = fpr_set, + }, +}; + +static const struct user_regset_view user_mips64_view = { + .name = "mips", + .e_machine = ELF_ARCH, + .ei_osabi = ELF_OSABI, + .regsets = mips64_regsets, + .n = ARRAY_SIZE(mips_regsets), +}; + +const struct user_regset_view *task_user_regset_view(struct task_struct *task) +{ +#ifdef CONFIG_32BIT + return &user_mips_view; +#endif + +#ifdef CONFIG_MIPS32_O32 + if (test_thread_flag(TIF_32BIT_REGS)) + return &user_mips_view; +#endif + + return &user_mips64_view; +} + long arch_ptrace(struct task_struct *child, long request, unsigned long addr, unsigned long data) { @@ -517,52 +652,27 @@ long arch_ptrace(struct task_struct *child, long request, return ret; } -static inline int audit_arch(void) -{ - int arch = EM_MIPS; -#ifdef CONFIG_64BIT - arch |= __AUDIT_ARCH_64BIT; -#endif -#if defined(__LITTLE_ENDIAN) - arch |= __AUDIT_ARCH_LE; -#endif - return arch; -} - /* * Notification of system call entry/exit * - triggered by current->work.syscall_trace */ asmlinkage void syscall_trace_enter(struct pt_regs *regs) { + long ret = 0; user_exit(); /* do the secure computing check first */ secure_computing_strict(regs->regs[2]); - if (!(current->ptrace & PT_PTRACED)) - goto out; - - if (!test_thread_flag(TIF_SYSCALL_TRACE)) - goto out; + if (test_thread_flag(TIF_SYSCALL_TRACE) && + tracehook_report_syscall_entry(regs)) + ret = -1; - /* The 0x80 provides a way for the tracing parent to distinguish - between a syscall stop and SIGTRAP delivery */ - ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ? - 0x80 : 0)); - - /* - * this isn't the same as continuing with a signal, but it will do - * for normal use. strace only continues with a signal if the - * stopping signal is not SIGTRAP. -brl - */ - if (current->exit_code) { - send_sig(current->exit_code, current, 1); - current->exit_code = 0; - } + if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) + trace_sys_enter(regs, regs->regs[2]); -out: - audit_syscall_entry(audit_arch(), regs->regs[2], + audit_syscall_entry(__syscall_get_arch(), + regs->regs[2], regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]); } @@ -582,26 +692,11 @@ asmlinkage void syscall_trace_leave(struct pt_regs *regs) audit_syscall_exit(regs); - if (!(current->ptrace & PT_PTRACED)) - return; - - if (!test_thread_flag(TIF_SYSCALL_TRACE)) - return; - - /* The 0x80 provides a way for the tracing parent to distinguish - between a syscall stop and SIGTRAP delivery */ - ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ? - 0x80 : 0)); + if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) + trace_sys_exit(regs, regs->regs[2]); - /* - * this isn't the same as continuing with a signal, but it will do - * for normal use. strace only continues with a signal if the - * stopping signal is not SIGTRAP. -brl - */ - if (current->exit_code) { - send_sig(current->exit_code, current, 1); - current->exit_code = 0; - } + if (test_thread_flag(TIF_SYSCALL_TRACE)) + tracehook_report_syscall_exit(regs, 0); user_enter(); } diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c index d763f11e35e2..2c12ea1668d1 100644 --- a/arch/mips/kernel/rtlx.c +++ b/arch/mips/kernel/rtlx.c @@ -172,8 +172,9 @@ int rtlx_open(int index, int can_sleep) if (rtlx == NULL) { if( (p = vpe_get_shared(tclimit)) == NULL) { if (can_sleep) { - __wait_event_interruptible(channel_wqs[index].lx_queue, - (p = vpe_get_shared(tclimit)), ret); + ret = __wait_event_interruptible( + channel_wqs[index].lx_queue, + (p = vpe_get_shared(tclimit))); if (ret) goto out_fail; } else { @@ -263,11 +264,10 @@ unsigned int rtlx_read_poll(int index, int can_sleep) /* data available to read? */ if (chan->lx_read == chan->lx_write) { if (can_sleep) { - int ret = 0; - - __wait_event_interruptible(channel_wqs[index].lx_queue, + int ret = __wait_event_interruptible( + channel_wqs[index].lx_queue, (chan->lx_read != chan->lx_write) || - sp_stopping, ret); + sp_stopping); if (ret) return ret; @@ -440,14 +440,13 @@ static ssize_t file_write(struct file *file, const char __user * buffer, /* any space left... */ if (!rtlx_write_poll(minor)) { - int ret = 0; + int ret; if (file->f_flags & O_NONBLOCK) return -EAGAIN; - __wait_event_interruptible(channel_wqs[minor].rt_queue, - rtlx_write_poll(minor), - ret); + ret = __wait_event_interruptible(channel_wqs[minor].rt_queue, + rtlx_write_poll(minor)); if (ret) return ret; } diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index e774bb1088b5..e8e541b40d86 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S @@ -40,17 +40,58 @@ NESTED(handle_sys, PT_SIZE, sp) sw t1, PT_EPC(sp) beqz t0, illegal_syscall - sll t0, v0, 3 + sll t0, v0, 2 la t1, sys_call_table addu t1, t0 lw t2, (t1) # syscall routine - lw t3, 4(t1) # >= 0 if we need stack arguments beqz t2, illegal_syscall sw a3, PT_R26(sp) # save a3 for syscall restarting - bgez t3, stackargs -stack_done: + /* + * More than four arguments. Try to deal with it by copying the + * stack arguments from the user stack to the kernel stack. + * This Sucks (TM). + */ + lw t0, PT_R29(sp) # get old user stack pointer + + /* + * We intentionally keep the kernel stack a little below the top of + * userspace so we don't have to do a slower byte accurate check here. + */ + lw t5, TI_ADDR_LIMIT($28) + addu t4, t0, 32 + and t5, t4 + bltz t5, bad_stack # -> sp is bad + + /* + * Ok, copy the args from the luser stack to the kernel stack. + * t3 is the precomputed number of instruction bytes needed to + * load or store arguments 6-8. + */ + + .set push + .set noreorder + .set nomacro + +1: lw t5, 16(t0) # argument #5 from usp +4: lw t6, 20(t0) # argument #6 from usp +3: lw t7, 24(t0) # argument #7 from usp +2: lw t8, 28(t0) # argument #8 from usp + + sw t5, 16(sp) # argument #5 to ksp + sw t6, 20(sp) # argument #6 to ksp + sw t7, 24(sp) # argument #7 to ksp + sw t8, 28(sp) # argument #8 to ksp + .set pop + + .section __ex_table,"a" + PTR 1b,bad_stack + PTR 2b,bad_stack + PTR 3b,bad_stack + PTR 4b,bad_stack + .previous + lw t0, TI_FLAGS($28) # syscall tracing enabled? li t1, _TIF_WORK_SYSCALL_ENTRY and t0, t1 @@ -102,66 +143,6 @@ syscall_trace_entry: /* ------------------------------------------------------------------------ */ /* - * More than four arguments. Try to deal with it by copying the - * stack arguments from the user stack to the kernel stack. - * This Sucks (TM). - */ -stackargs: - lw t0, PT_R29(sp) # get old user stack pointer - - /* - * We intentionally keep the kernel stack a little below the top of - * userspace so we don't have to do a slower byte accurate check here. - */ - lw t5, TI_ADDR_LIMIT($28) - addu t4, t0, 32 - and t5, t4 - bltz t5, bad_stack # -> sp is bad - - /* Ok, copy the args from the luser stack to the kernel stack. - * t3 is the precomputed number of instruction bytes needed to - * load or store arguments 6-8. - */ - - la t1, 5f # load up to 3 arguments - subu t1, t3 -1: lw t5, 16(t0) # argument #5 from usp - .set push - .set noreorder - .set nomacro - jr t1 - addiu t1, 6f - 5f - -2: lw t8, 28(t0) # argument #8 from usp -3: lw t7, 24(t0) # argument #7 from usp -4: lw t6, 20(t0) # argument #6 from usp -5: jr t1 - sw t5, 16(sp) # argument #5 to ksp - -#ifdef CONFIG_CPU_MICROMIPS - sw t8, 28(sp) # argument #8 to ksp - nop - sw t7, 24(sp) # argument #7 to ksp - nop - sw t6, 20(sp) # argument #6 to ksp - nop -#else - sw t8, 28(sp) # argument #8 to ksp - sw t7, 24(sp) # argument #7 to ksp - sw t6, 20(sp) # argument #6 to ksp -#endif -6: j stack_done # go back - nop - .set pop - - .section __ex_table,"a" - PTR 1b,bad_stack - PTR 2b,bad_stack - PTR 3b,bad_stack - PTR 4b,bad_stack - .previous - - /* * The stackpointer for a call with more than 4 arguments is bad. * We probably should handle this case a bit more drastic. */ @@ -187,7 +168,7 @@ illegal_syscall: subu t0, a0, __NR_O32_Linux # check syscall number sltiu v0, t0, __NR_O32_Linux_syscalls + 1 beqz t0, einval # do not recurse - sll t1, t0, 3 + sll t1, t0, 2 beqz v0, einval lw t2, sys_call_table(t1) # syscall routine @@ -218,260 +199,248 @@ einval: li v0, -ENOSYS jr ra END(sys_syscall) - .macro fifty ptr, nargs, from=1, to=50 - sys \ptr \nargs - .if \to-\from - fifty \ptr,\nargs,"(\from+1)",\to - .endif - .endm - - .macro mille ptr, nargs, from=1, to=20 - fifty \ptr,\nargs - .if \to-\from - mille \ptr,\nargs,"(\from+1)",\to - .endif - .endm - - .macro syscalltable - sys sys_syscall 8 /* 4000 */ - sys sys_exit 1 - sys __sys_fork 0 - sys sys_read 3 - sys sys_write 3 - sys sys_open 3 /* 4005 */ - sys sys_close 1 - sys sys_waitpid 3 - sys sys_creat 2 - sys sys_link 2 - sys sys_unlink 1 /* 4010 */ - sys sys_execve 0 - sys sys_chdir 1 - sys sys_time 1 - sys sys_mknod 3 - sys sys_chmod 2 /* 4015 */ - sys sys_lchown 3 - sys sys_ni_syscall 0 - sys sys_ni_syscall 0 /* was sys_stat */ - sys sys_lseek 3 - sys sys_getpid 0 /* 4020 */ - sys sys_mount 5 - sys sys_oldumount 1 - sys sys_setuid 1 - sys sys_getuid 0 - sys sys_stime 1 /* 4025 */ - sys sys_ptrace 4 - sys sys_alarm 1 - sys sys_ni_syscall 0 /* was sys_fstat */ - sys sys_pause 0 - sys sys_utime 2 /* 4030 */ - sys sys_ni_syscall 0 - sys sys_ni_syscall 0 - sys sys_access 2 - sys sys_nice 1 - sys sys_ni_syscall 0 /* 4035 */ - sys sys_sync 0 - sys sys_kill 2 - sys sys_rename 2 - sys sys_mkdir 2 - sys sys_rmdir 1 /* 4040 */ - sys sys_dup 1 - sys sysm_pipe 0 - sys sys_times 1 - sys sys_ni_syscall 0 - sys sys_brk 1 /* 4045 */ - sys sys_setgid 1 - sys sys_getgid 0 - sys sys_ni_syscall 0 /* was signal(2) */ - sys sys_geteuid 0 - sys sys_getegid 0 /* 4050 */ - sys sys_acct 1 - sys sys_umount 2 - sys sys_ni_syscall 0 - sys sys_ioctl 3 - sys sys_fcntl 3 /* 4055 */ - sys sys_ni_syscall 2 - sys sys_setpgid 2 - sys sys_ni_syscall 0 - sys sys_olduname 1 - sys sys_umask 1 /* 4060 */ - sys sys_chroot 1 - sys sys_ustat 2 - sys sys_dup2 2 - sys sys_getppid 0 - sys sys_getpgrp 0 /* 4065 */ - sys sys_setsid 0 - sys sys_sigaction 3 - sys sys_sgetmask 0 - sys sys_ssetmask 1 - sys sys_setreuid 2 /* 4070 */ - sys sys_setregid 2 - sys sys_sigsuspend 0 - sys sys_sigpending 1 - sys sys_sethostname 2 - sys sys_setrlimit 2 /* 4075 */ - sys sys_getrlimit 2 - sys sys_getrusage 2 - sys sys_gettimeofday 2 - sys sys_settimeofday 2 - sys sys_getgroups 2 /* 4080 */ - sys sys_setgroups 2 - sys sys_ni_syscall 0 /* old_select */ - sys sys_symlink 2 - sys sys_ni_syscall 0 /* was sys_lstat */ - sys sys_readlink 3 /* 4085 */ - sys sys_uselib 1 - sys sys_swapon 2 - sys sys_reboot 3 - sys sys_old_readdir 3 - sys sys_mips_mmap 6 /* 4090 */ - sys sys_munmap 2 - sys sys_truncate 2 - sys sys_ftruncate 2 - sys sys_fchmod 2 - sys sys_fchown 3 /* 4095 */ - sys sys_getpriority 2 - sys sys_setpriority 3 - sys sys_ni_syscall 0 - sys sys_statfs 2 - sys sys_fstatfs 2 /* 4100 */ - sys sys_ni_syscall 0 /* was ioperm(2) */ - sys sys_socketcall 2 - sys sys_syslog 3 - sys sys_setitimer 3 - sys sys_getitimer 2 /* 4105 */ - sys sys_newstat 2 - sys sys_newlstat 2 - sys sys_newfstat 2 - sys sys_uname 1 - sys sys_ni_syscall 0 /* 4110 was iopl(2) */ - sys sys_vhangup 0 - sys sys_ni_syscall 0 /* was sys_idle() */ - sys sys_ni_syscall 0 /* was sys_vm86 */ - sys sys_wait4 4 - sys sys_swapoff 1 /* 4115 */ - sys sys_sysinfo 1 - sys sys_ipc 6 - sys sys_fsync 1 - sys sys_sigreturn 0 - sys __sys_clone 6 /* 4120 */ - sys sys_setdomainname 2 - sys sys_newuname 1 - sys sys_ni_syscall 0 /* sys_modify_ldt */ - sys sys_adjtimex 1 - sys sys_mprotect 3 /* 4125 */ - sys sys_sigprocmask 3 - sys sys_ni_syscall 0 /* was create_module */ - sys sys_init_module 5 - sys sys_delete_module 1 - sys sys_ni_syscall 0 /* 4130 was get_kernel_syms */ - sys sys_quotactl 4 - sys sys_getpgid 1 - sys sys_fchdir 1 - sys sys_bdflush 2 - sys sys_sysfs 3 /* 4135 */ - sys sys_personality 1 - sys sys_ni_syscall 0 /* for afs_syscall */ - sys sys_setfsuid 1 - sys sys_setfsgid 1 - sys sys_llseek 5 /* 4140 */ - sys sys_getdents 3 - sys sys_select 5 - sys sys_flock 2 - sys sys_msync 3 - sys sys_readv 3 /* 4145 */ - sys sys_writev 3 - sys sys_cacheflush 3 - sys sys_cachectl 3 - sys sys_sysmips 4 - sys sys_ni_syscall 0 /* 4150 */ - sys sys_getsid 1 - sys sys_fdatasync 1 - sys sys_sysctl 1 - sys sys_mlock 2 - sys sys_munlock 2 /* 4155 */ - sys sys_mlockall 1 - sys sys_munlockall 0 - sys sys_sched_setparam 2 - sys sys_sched_getparam 2 - sys sys_sched_setscheduler 3 /* 4160 */ - sys sys_sched_getscheduler 1 - sys sys_sched_yield 0 - sys sys_sched_get_priority_max 1 - sys sys_sched_get_priority_min 1 - sys sys_sched_rr_get_interval 2 /* 4165 */ - sys sys_nanosleep, 2 - sys sys_mremap, 5 - sys sys_accept 3 - sys sys_bind 3 - sys sys_connect 3 /* 4170 */ - sys sys_getpeername 3 - sys sys_getsockname 3 - sys sys_getsockopt 5 - sys sys_listen 2 - sys sys_recv 4 /* 4175 */ - sys sys_recvfrom 6 - sys sys_recvmsg 3 - sys sys_send 4 - sys sys_sendmsg 3 - sys sys_sendto 6 /* 4180 */ - sys sys_setsockopt 5 - sys sys_shutdown 2 - sys sys_socket 3 - sys sys_socketpair 4 - sys sys_setresuid 3 /* 4185 */ - sys sys_getresuid 3 - sys sys_ni_syscall 0 /* was sys_query_module */ - sys sys_poll 3 - sys sys_ni_syscall 0 /* was nfsservctl */ - sys sys_setresgid 3 /* 4190 */ - sys sys_getresgid 3 - sys sys_prctl 5 - sys sys_rt_sigreturn 0 - sys sys_rt_sigaction 4 - sys sys_rt_sigprocmask 4 /* 4195 */ - sys sys_rt_sigpending 2 - sys sys_rt_sigtimedwait 4 - sys sys_rt_sigqueueinfo 3 - sys sys_rt_sigsuspend 0 - sys sys_pread64 6 /* 4200 */ - sys sys_pwrite64 6 - sys sys_chown 3 - sys sys_getcwd 2 - sys sys_capget 2 - sys sys_capset 2 /* 4205 */ - sys sys_sigaltstack 0 - sys sys_sendfile 4 - sys sys_ni_syscall 0 - sys sys_ni_syscall 0 - sys sys_mips_mmap2 6 /* 4210 */ - sys sys_truncate64 4 - sys sys_ftruncate64 4 - sys sys_stat64 2 - sys sys_lstat64 2 - sys sys_fstat64 2 /* 4215 */ - sys sys_pivot_root 2 - sys sys_mincore 3 - sys sys_madvise 3 - sys sys_getdents64 3 - sys sys_fcntl64 3 /* 4220 */ - sys sys_ni_syscall 0 - sys sys_gettid 0 - sys sys_readahead 5 - sys sys_setxattr 5 - sys sys_lsetxattr 5 /* 4225 */ - sys sys_fsetxattr 5 - sys sys_getxattr 4 - sys sys_lgetxattr 4 - sys sys_fgetxattr 4 - sys sys_listxattr 3 /* 4230 */ - sys sys_llistxattr 3 - sys sys_flistxattr 3 - sys sys_removexattr 2 - sys sys_lremovexattr 2 - sys sys_fremovexattr 2 /* 4235 */ - sys sys_tkill 2 - sys sys_sendfile64 5 - sys sys_futex 6 + .align 2 + .type sys_call_table, @object +EXPORT(sys_call_table) + PTR sys_syscall /* 4000 */ + PTR sys_exit + PTR __sys_fork + PTR sys_read + PTR sys_write + PTR sys_open /* 4005 */ + PTR sys_close + PTR sys_waitpid + PTR sys_creat + PTR sys_link + PTR sys_unlink /* 4010 */ + PTR sys_execve + PTR sys_chdir + PTR sys_time + PTR sys_mknod + PTR sys_chmod /* 4015 */ + PTR sys_lchown + PTR sys_ni_syscall + PTR sys_ni_syscall /* was sys_stat */ + PTR sys_lseek + PTR sys_getpid /* 4020 */ + PTR sys_mount + PTR sys_oldumount + PTR sys_setuid + PTR sys_getuid + PTR sys_stime /* 4025 */ + PTR sys_ptrace + PTR sys_alarm + PTR sys_ni_syscall /* was sys_fstat */ + PTR sys_pause + PTR sys_utime /* 4030 */ + PTR sys_ni_syscall + PTR sys_ni_syscall + PTR sys_access + PTR sys_nice + PTR sys_ni_syscall /* 4035 */ + PTR sys_sync + PTR sys_kill + PTR sys_rename + PTR sys_mkdir + PTR sys_rmdir /* 4040 */ + PTR sys_dup + PTR sysm_pipe + PTR sys_times + PTR sys_ni_syscall + PTR sys_brk /* 4045 */ + PTR sys_setgid + PTR sys_getgid + PTR sys_ni_syscall /* was signal(2) */ + PTR sys_geteuid + PTR sys_getegid /* 4050 */ + PTR sys_acct + PTR sys_umount + PTR sys_ni_syscall + PTR sys_ioctl + PTR sys_fcntl /* 4055 */ + PTR sys_ni_syscall + PTR sys_setpgid + PTR sys_ni_syscall + PTR sys_olduname + PTR sys_umask /* 4060 */ + PTR sys_chroot + PTR sys_ustat + PTR sys_dup2 + PTR sys_getppid + PTR sys_getpgrp /* 4065 */ + PTR sys_setsid + PTR sys_sigaction + PTR sys_sgetmask + PTR sys_ssetmask + PTR sys_setreuid /* 4070 */ + PTR sys_setregid + PTR sys_sigsuspend + PTR sys_sigpending + PTR sys_sethostname + PTR sys_setrlimit /* 4075 */ + PTR sys_getrlimit + PTR sys_getrusage + PTR sys_gettimeofday + PTR sys_settimeofday + PTR sys_getgroups /* 4080 */ + PTR sys_setgroups + PTR sys_ni_syscall /* old_select */ + PTR sys_symlink + PTR sys_ni_syscall /* was sys_lstat */ + PTR sys_readlink /* 4085 */ + PTR sys_uselib + PTR sys_swapon + PTR sys_reboot + PTR sys_old_readdir + PTR sys_mips_mmap /* 4090 */ + PTR sys_munmap + PTR sys_truncate + PTR sys_ftruncate + PTR sys_fchmod + PTR sys_fchown /* 4095 */ + PTR sys_getpriority + PTR sys_setpriority + PTR sys_ni_syscall + PTR sys_statfs + PTR sys_fstatfs /* 4100 */ + PTR sys_ni_syscall /* was ioperm(2) */ + PTR sys_socketcall + PTR sys_syslog + PTR sys_setitimer + PTR sys_getitimer /* 4105 */ + PTR sys_newstat + PTR sys_newlstat + PTR sys_newfstat + PTR sys_uname + PTR sys_ni_syscall /* 4110 was iopl(2) */ + PTR sys_vhangup + PTR sys_ni_syscall /* was sys_idle() */ + PTR sys_ni_syscall /* was sys_vm86 */ + PTR sys_wait4 + PTR sys_swapoff /* 4115 */ + PTR sys_sysinfo + PTR sys_ipc + PTR sys_fsync + PTR sys_sigreturn + PTR __sys_clone /* 4120 */ + PTR sys_setdomainname + PTR sys_newuname + PTR sys_ni_syscall /* sys_modify_ldt */ + PTR sys_adjtimex + PTR sys_mprotect /* 4125 */ + PTR sys_sigprocmask + PTR sys_ni_syscall /* was create_module */ + PTR sys_init_module + PTR sys_delete_module + PTR sys_ni_syscall /* 4130 was get_kernel_syms */ + PTR sys_quotactl + PTR sys_getpgid + PTR sys_fchdir + PTR sys_bdflush + PTR sys_sysfs /* 4135 */ + PTR sys_personality + PTR sys_ni_syscall /* for afs_syscall */ + PTR sys_setfsuid + PTR sys_setfsgid + PTR sys_llseek /* 4140 */ + PTR sys_getdents + PTR sys_select + PTR sys_flock + PTR sys_msync + PTR sys_readv /* 4145 */ + PTR sys_writev + PTR sys_cacheflush + PTR sys_cachectl + PTR sys_sysmips + PTR sys_ni_syscall /* 4150 */ + PTR sys_getsid + PTR sys_fdatasync + PTR sys_sysctl + PTR sys_mlock + PTR sys_munlock /* 4155 */ + PTR sys_mlockall + PTR sys_munlockall + PTR sys_sched_setparam + PTR sys_sched_getparam + PTR sys_sched_setscheduler /* 4160 */ + PTR sys_sched_getscheduler + PTR sys_sched_yield + PTR sys_sched_get_priority_max + PTR sys_sched_get_priority_min + PTR sys_sched_rr_get_interval /* 4165 */ + PTR sys_nanosleep + PTR sys_mremap + PTR sys_accept + PTR sys_bind + PTR sys_connect /* 4170 */ + PTR sys_getpeername + PTR sys_getsockname + PTR sys_getsockopt + PTR sys_listen + PTR sys_recv /* 4175 */ + PTR sys_recvfrom + PTR sys_recvmsg + PTR sys_send + PTR sys_sendmsg + PTR sys_sendto /* 4180 */ + PTR sys_setsockopt + PTR sys_shutdown + PTR sys_socket + PTR sys_socketpair + PTR sys_setresuid /* 4185 */ + PTR sys_getresuid + PTR sys_ni_syscall /* was sys_query_module */ + PTR sys_poll + PTR sys_ni_syscall /* was nfsservctl */ + PTR sys_setresgid /* 4190 */ + PTR sys_getresgid + PTR sys_prctl + PTR sys_rt_sigreturn + PTR sys_rt_sigaction + PTR sys_rt_sigprocmask /* 4195 */ + PTR sys_rt_sigpending + PTR sys_rt_sigtimedwait + PTR sys_rt_sigqueueinfo + PTR sys_rt_sigsuspend + PTR sys_pread64 /* 4200 */ + PTR sys_pwrite64 + PTR sys_chown + PTR sys_getcwd + PTR sys_capget + PTR sys_capset /* 4205 */ + PTR sys_sigaltstack + PTR sys_sendfile + PTR sys_ni_syscall + PTR sys_ni_syscall + PTR sys_mips_mmap2 /* 4210 */ + PTR sys_truncate64 + PTR sys_ftruncate64 + PTR sys_stat64 + PTR sys_lstat64 + PTR sys_fstat64 /* 4215 */ + PTR sys_pivot_root + PTR sys_mincore + PTR sys_madvise + PTR sys_getdents64 + PTR sys_fcntl64 /* 4220 */ + PTR sys_ni_syscall + PTR sys_gettid + PTR sys_readahead + PTR sys_setxattr + PTR sys_lsetxattr /* 4225 */ + PTR sys_fsetxattr + PTR sys_getxattr + PTR sys_lgetxattr + PTR sys_fgetxattr + PTR sys_listxattr /* 4230 */ + PTR sys_llistxattr + PTR sys_flistxattr + PTR sys_removexattr + PTR sys_lremovexattr + PTR sys_fremovexattr /* 4235 */ + PTR sys_tkill + PTR sys_sendfile64 + PTR sys_futex #ifdef CONFIG_MIPS_MT_FPAFF /* * For FPU affinity scheduling on MIPS MT processors, we need to @@ -480,132 +449,117 @@ einval: li v0, -ENOSYS * these hooks for the 32-bit kernel - there is no MIPS64 MT processor * atm. */ - sys mipsmt_sys_sched_setaffinity 3 - sys mipsmt_sys_sched_getaffinity 3 + PTR mipsmt_sys_sched_setaffinity + PTR mipsmt_sys_sched_getaffinity #else - sys sys_sched_setaffinity 3 - sys sys_sched_getaffinity 3 /* 4240 */ + PTR sys_sched_setaffinity + PTR sys_sched_getaffinity /* 4240 */ #endif /* CONFIG_MIPS_MT_FPAFF */ - sys sys_io_setup 2 - sys sys_io_destroy 1 - sys sys_io_getevents 5 - sys sys_io_submit 3 - sys sys_io_cancel 3 /* 4245 */ - sys sys_exit_group 1 - sys sys_lookup_dcookie 4 - sys sys_epoll_create 1 - sys sys_epoll_ctl 4 - sys sys_epoll_wait 4 /* 4250 */ - sys sys_remap_file_pages 5 - sys sys_set_tid_address 1 - sys sys_restart_syscall 0 - sys sys_fadvise64_64 7 - sys sys_statfs64 3 /* 4255 */ - sys sys_fstatfs64 2 - sys sys_timer_create 3 - sys sys_timer_settime 4 - sys sys_timer_gettime 2 - sys sys_timer_getoverrun 1 /* 4260 */ - sys sys_timer_delete 1 - sys sys_clock_settime 2 - sys sys_clock_gettime 2 - sys sys_clock_getres 2 - sys sys_clock_nanosleep 4 /* 4265 */ - sys sys_tgkill 3 - sys sys_utimes 2 - sys sys_mbind 4 - sys sys_ni_syscall 0 /* sys_get_mempolicy */ - sys sys_ni_syscall 0 /* 4270 sys_set_mempolicy */ - sys sys_mq_open 4 - sys sys_mq_unlink 1 - sys sys_mq_timedsend 5 - sys sys_mq_timedreceive 5 - sys sys_mq_notify 2 /* 4275 */ - sys sys_mq_getsetattr 3 - sys sys_ni_syscall 0 /* sys_vserver */ - sys sys_waitid 5 - sys sys_ni_syscall 0 /* available, was setaltroot */ - sys sys_add_key 5 /* 4280 */ - sys sys_request_key 4 - sys sys_keyctl 5 - sys sys_set_thread_area 1 - sys sys_inotify_init 0 - sys sys_inotify_add_watch 3 /* 4285 */ - sys sys_inotify_rm_watch 2 - sys sys_migrate_pages 4 - sys sys_openat 4 - sys sys_mkdirat 3 - sys sys_mknodat 4 /* 4290 */ - sys sys_fchownat 5 - sys sys_futimesat 3 - sys sys_fstatat64 4 - sys sys_unlinkat 3 - sys sys_renameat 4 /* 4295 */ - sys sys_linkat 5 - sys sys_symlinkat 3 - sys sys_readlinkat 4 - sys sys_fchmodat 3 - sys sys_faccessat 3 /* 4300 */ - sys sys_pselect6 6 - sys sys_ppoll 5 - sys sys_unshare 1 - sys sys_splice 6 - sys sys_sync_file_range 7 /* 4305 */ - sys sys_tee 4 - sys sys_vmsplice 4 - sys sys_move_pages 6 - sys sys_set_robust_list 2 - sys sys_get_robust_list 3 /* 4310 */ - sys sys_kexec_load 4 - sys sys_getcpu 3 - sys sys_epoll_pwait 6 - sys sys_ioprio_set 3 - sys sys_ioprio_get 2 /* 4315 */ - sys sys_utimensat 4 - sys sys_signalfd 3 - sys sys_ni_syscall 0 /* was timerfd */ - sys sys_eventfd 1 - sys sys_fallocate 6 /* 4320 */ - sys sys_timerfd_create 2 - sys sys_timerfd_gettime 2 - sys sys_timerfd_settime 4 - sys sys_signalfd4 4 - sys sys_eventfd2 2 /* 4325 */ - sys sys_epoll_create1 1 - sys sys_dup3 3 - sys sys_pipe2 2 - sys sys_inotify_init1 1 - sys sys_preadv 6 /* 4330 */ - sys sys_pwritev 6 - sys sys_rt_tgsigqueueinfo 4 - sys sys_perf_event_open 5 - sys sys_accept4 4 - sys sys_recvmmsg 5 /* 4335 */ - sys sys_fanotify_init 2 - sys sys_fanotify_mark 6 - sys sys_prlimit64 4 - sys sys_name_to_handle_at 5 - sys sys_open_by_handle_at 3 /* 4340 */ - sys sys_clock_adjtime 2 - sys sys_syncfs 1 - sys sys_sendmmsg 4 - sys sys_setns 2 - sys sys_process_vm_readv 6 /* 4345 */ - sys sys_process_vm_writev 6 - sys sys_kcmp 5 - sys sys_finit_module 3 - .endm - - /* We pre-compute the number of _instruction_ bytes needed to - load or store the arguments 6-8. Negative values are ignored. */ - - .macro sys function, nargs - PTR \function - LONG (\nargs << 2) - (5 << 2) - .endm - - .align 3 - .type sys_call_table,@object -EXPORT(sys_call_table) - syscalltable - .size sys_call_table, . - sys_call_table + PTR sys_io_setup + PTR sys_io_destroy + PTR sys_io_getevents + PTR sys_io_submit + PTR sys_io_cancel /* 4245 */ + PTR sys_exit_group + PTR sys_lookup_dcookie + PTR sys_epoll_create + PTR sys_epoll_ctl + PTR sys_epoll_wait /* 4250 */ + PTR sys_remap_file_pages + PTR sys_set_tid_address + PTR sys_restart_syscall + PTR sys_fadvise64_64 + PTR sys_statfs64 /* 4255 */ + PTR sys_fstatfs64 + PTR sys_timer_create + PTR sys_timer_settime + PTR sys_timer_gettime + PTR sys_timer_getoverrun /* 4260 */ + PTR sys_timer_delete + PTR sys_clock_settime + PTR sys_clock_gettime + PTR sys_clock_getres + PTR sys_clock_nanosleep /* 4265 */ + PTR sys_tgkill + PTR sys_utimes + PTR sys_mbind + PTR sys_ni_syscall /* sys_get_mempolicy */ + PTR sys_ni_syscall /* 4270 sys_set_mempolicy */ + PTR sys_mq_open + PTR sys_mq_unlink + PTR sys_mq_timedsend + PTR sys_mq_timedreceive + PTR sys_mq_notify /* 4275 */ + PTR sys_mq_getsetattr + PTR sys_ni_syscall /* sys_vserver */ + PTR sys_waitid + PTR sys_ni_syscall /* available, was setaltroot */ + PTR sys_add_key /* 4280 */ + PTR sys_request_key + PTR sys_keyctl + PTR sys_set_thread_area + PTR sys_inotify_init + PTR sys_inotify_add_watch /* 4285 */ + PTR sys_inotify_rm_watch + PTR sys_migrate_pages + PTR sys_openat + PTR sys_mkdirat + PTR sys_mknodat /* 4290 */ + PTR sys_fchownat + PTR sys_futimesat + PTR sys_fstatat64 + PTR sys_unlinkat + PTR sys_renameat /* 4295 */ + PTR sys_linkat + PTR sys_symlinkat + PTR sys_readlinkat + PTR sys_fchmodat + PTR sys_faccessat /* 4300 */ + PTR sys_pselect6 + PTR sys_ppoll + PTR sys_unshare + PTR sys_splice + PTR sys_sync_file_range /* 4305 */ + PTR sys_tee + PTR sys_vmsplice + PTR sys_move_pages + PTR sys_set_robust_list + PTR sys_get_robust_list /* 4310 */ + PTR sys_kexec_load + PTR sys_getcpu + PTR sys_epoll_pwait + PTR sys_ioprio_set + PTR sys_ioprio_get /* 4315 */ + PTR sys_utimensat + PTR sys_signalfd + PTR sys_ni_syscall /* was timerfd */ + PTR sys_eventfd + PTR sys_fallocate /* 4320 */ + PTR sys_timerfd_create + PTR sys_timerfd_gettime + PTR sys_timerfd_settime + PTR sys_signalfd4 + PTR sys_eventfd2 /* 4325 */ + PTR sys_epoll_create1 + PTR sys_dup3 + PTR sys_pipe2 + PTR sys_inotify_init1 + PTR sys_preadv /* 4330 */ + PTR sys_pwritev + PTR sys_rt_tgsigqueueinfo + PTR sys_perf_event_open + PTR sys_accept4 + PTR sys_recvmmsg /* 4335 */ + PTR sys_fanotify_init + PTR sys_fanotify_mark + PTR sys_prlimit64 + PTR sys_name_to_handle_at + PTR sys_open_by_handle_at /* 4340 */ + PTR sys_clock_adjtime + PTR sys_syncfs + PTR sys_sendmmsg + PTR sys_setns + PTR sys_process_vm_readv /* 4345 */ + PTR sys_process_vm_writev + PTR sys_kcmp + PTR sys_finit_module diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index be6627ead619..57e3742fec59 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S @@ -114,7 +114,8 @@ illegal_syscall: END(handle_sys64) .align 3 -sys_call_table: + .type sys_call_table, @object +EXPORT(sys_call_table) PTR sys_read /* 5000 */ PTR sys_write PTR sys_open diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index cab150789c8d..2f48f5934399 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S @@ -103,6 +103,7 @@ not_n32_scall: END(handle_sysn32) + .type sysn32_call_table, @object EXPORT(sysn32_call_table) PTR sys_read /* 6000 */ PTR sys_write diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index 37605dc8eef7..f1acdb429f4f 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S @@ -53,7 +53,7 @@ NESTED(handle_sys, PT_SIZE, sp) sll a3, a3, 0 dsll t0, v0, 3 # offset into table - ld t2, (sys_call_table - (__NR_O32_Linux * 8))(t0) + ld t2, (sys32_call_table - (__NR_O32_Linux * 8))(t0) sd a3, PT_R26(sp) # save a3 for syscall restarting @@ -168,7 +168,7 @@ LEAF(sys32_syscall) beqz t0, einval # do not recurse dsll t1, t0, 3 beqz v0, einval - ld t2, sys_call_table(t1) # syscall routine + ld t2, sys32_call_table(t1) # syscall routine move a0, a1 # shift argument registers move a1, a2 @@ -190,8 +190,8 @@ einval: li v0, -ENOSYS END(sys32_syscall) .align 3 - .type sys_call_table,@object -sys_call_table: + .type sys32_call_table,@object +EXPORT(sys32_call_table) PTR sys32_syscall /* 4000 */ PTR sys_exit PTR __sys_fork @@ -541,4 +541,4 @@ sys_call_table: PTR compat_sys_process_vm_writev PTR sys_kcmp PTR sys_finit_module - .size sys_call_table,.-sys_call_table + .size sys32_call_table,.-sys32_call_table diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index c538d6e01b7b..a842154d57dc 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -300,12 +300,13 @@ static void __init bootmem_init(void) int i; /* - * Init any data related to initrd. It's a nop if INITRD is - * not selected. Once that done we can determine the low bound - * of usable memory. + * Sanity check any INITRD first. We don't take it into account + * for bootmem setup initially, rely on the end-of-kernel-code + * as our memory range starting point. Once bootmem is inited we + * will reserve the area used for the initrd. */ - reserved_end = max(init_initrd(), - (unsigned long) PFN_UP(__pa_symbol(&_end))); + init_initrd(); + reserved_end = (unsigned long) PFN_UP(__pa_symbol(&_end)); /* * max_low_pfn is not a number of pages. The number of pages @@ -362,6 +363,14 @@ static void __init bootmem_init(void) max_low_pfn = PFN_DOWN(HIGHMEM_START); } +#ifdef CONFIG_BLK_DEV_INITRD + /* + * mapstart should be after initrd_end + */ + if (initrd_end) + mapstart = max(mapstart, (unsigned long)PFN_UP(__pa(initrd_end))); +#endif + /* * Initialize the boot-time allocator with low memory only. */ diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c index 57de8b751627..1905a419aa46 100644 --- a/arch/mips/kernel/signal32.c +++ b/arch/mips/kernel/signal32.c @@ -314,7 +314,7 @@ SYSCALL_DEFINE3(32_sigaction, long, sig, const struct compat_sigaction __user *, return ret; } -int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from) +int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from) { int err; diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c index 126da74d4c55..2362665ba496 100644 --- a/arch/mips/kernel/smp-bmips.c +++ b/arch/mips/kernel/smp-bmips.c @@ -136,10 +136,10 @@ static void bmips_prepare_cpus(unsigned int max_cpus) { if (request_irq(IPI0_IRQ, bmips_ipi_interrupt, IRQF_PERCPU, "smp_ipi0", NULL)) - panic("Can't request IPI0 interrupt\n"); + panic("Can't request IPI0 interrupt"); if (request_irq(IPI1_IRQ, bmips_ipi_interrupt, IRQF_PERCPU, "smp_ipi1", NULL)) - panic("Can't request IPI1 interrupt\n"); + panic("Can't request IPI1 interrupt"); } /* diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 5c208ed8f856..0a022ee33b2a 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c @@ -150,7 +150,6 @@ asmlinkage void start_secondary(void) void __irq_entry smp_call_function_interrupt(void) { irq_enter(); - generic_smp_call_function_single_interrupt(); generic_smp_call_function_interrupt(); irq_exit(); } diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 524841f02803..f9c8746be8d6 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -330,6 +330,7 @@ void show_regs(struct pt_regs *regs) void show_registers(struct pt_regs *regs) { const int field = 2 * sizeof(unsigned long); + mm_segment_t old_fs = get_fs(); __show_regs(regs); print_modules(); @@ -344,9 +345,13 @@ void show_registers(struct pt_regs *regs) printk("*HwTLS: %0*lx\n", field, tls); } + if (!user_mode(regs)) + /* Necessary for getting the correct stack content */ + set_fs(KERNEL_DS); show_stacktrace(current, regs); show_code((unsigned int __user *) regs->cp0_epc); printk("\n"); + set_fs(old_fs); } static int regs_to_trapnr(struct pt_regs *regs) @@ -366,7 +371,8 @@ void __noreturn die(const char *str, struct pt_regs *regs) oops_enter(); - if (notify_die(DIE_OOPS, str, regs, 0, regs_to_trapnr(regs), SIGSEGV) == NOTIFY_STOP) + if (notify_die(DIE_OOPS, str, regs, 0, regs_to_trapnr(regs), + SIGSEGV) == NOTIFY_STOP) sig = 0; console_verbose(); @@ -457,8 +463,8 @@ asmlinkage void do_be(struct pt_regs *regs) printk(KERN_ALERT "%s bus error, epc == %0*lx, ra == %0*lx\n", data ? "Data" : "Instruction", field, regs->cp0_epc, field, regs->regs[31]); - if (notify_die(DIE_OOPS, "bus error", regs, 0, regs_to_trapnr(regs), SIGBUS) - == NOTIFY_STOP) + if (notify_die(DIE_OOPS, "bus error", regs, 0, regs_to_trapnr(regs), + SIGBUS) == NOTIFY_STOP) goto out; die_if_kernel("Oops", regs); @@ -727,8 +733,8 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) siginfo_t info = {0}; prev_state = exception_enter(); - if (notify_die(DIE_FP, "FP exception", regs, 0, regs_to_trapnr(regs), SIGFPE) - == NOTIFY_STOP) + if (notify_die(DIE_FP, "FP exception", regs, 0, regs_to_trapnr(regs), + SIGFPE) == NOTIFY_STOP) goto out; die_if_kernel("FP exception in kernel code", regs); @@ -798,7 +804,8 @@ static void do_trap_or_bp(struct pt_regs *regs, unsigned int code, return; #endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */ - if (notify_die(DIE_TRAP, str, regs, code, regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP) + if (notify_die(DIE_TRAP, str, regs, code, regs_to_trapnr(regs), + SIGTRAP) == NOTIFY_STOP) return; /* @@ -892,12 +899,14 @@ asmlinkage void do_bp(struct pt_regs *regs) */ switch (bcode) { case BRK_KPROBE_BP: - if (notify_die(DIE_BREAK, "debug", regs, bcode, regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP) + if (notify_die(DIE_BREAK, "debug", regs, bcode, + regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP) goto out; else break; case BRK_KPROBE_SSTEPBP: - if (notify_die(DIE_SSTEPBP, "single_step", regs, bcode, regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP) + if (notify_die(DIE_SSTEPBP, "single_step", regs, bcode, + regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP) goto out; else break; @@ -961,8 +970,8 @@ asmlinkage void do_ri(struct pt_regs *regs) int status = -1; prev_state = exception_enter(); - if (notify_die(DIE_RI, "RI Fault", regs, 0, regs_to_trapnr(regs), SIGILL) - == NOTIFY_STOP) + if (notify_die(DIE_RI, "RI Fault", regs, 0, regs_to_trapnr(regs), + SIGILL) == NOTIFY_STOP) goto out; die_if_kernel("Reserved instruction in kernel code", regs); @@ -1488,10 +1497,14 @@ int register_nmi_notifier(struct notifier_block *nb) void __noreturn nmi_exception_handler(struct pt_regs *regs) { + char str[100]; + raw_notifier_call_chain(&nmi_chain, 0, regs); bust_spinlocks(1); - printk("NMI taken!!!!\n"); - die("NMI", regs); + snprintf(str, 100, "CPU%d NMI taken, CP0_EPC=%lx\n", + smp_processor_id(), regs->cp0_epc); + regs->cp0_epc = read_c0_errorepc(); + die(str, regs); } #define VECTORSPACING 0x100 /* for EI/VI mode */ @@ -1554,7 +1567,6 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs) unsigned char *b; BUG_ON(!cpu_has_veic && !cpu_has_vint); - BUG_ON((n < 0) && (n > 9)); if (addr == NULL) { handler = (unsigned long) do_default_vi; diff --git a/arch/mips/kvm/kvm_mips.c b/arch/mips/kvm/kvm_mips.c index a7b044536de4..73b34827826c 100644 --- a/arch/mips/kvm/kvm_mips.c +++ b/arch/mips/kvm/kvm_mips.c @@ -198,12 +198,13 @@ kvm_arch_dev_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) return -ENOIOCTLCMD; } -void kvm_arch_free_memslot(struct kvm_memory_slot *free, +void kvm_arch_free_memslot(struct kvm *kvm, struct kvm_memory_slot *free, struct kvm_memory_slot *dont) { } -int kvm_arch_create_memslot(struct kvm_memory_slot *slot, unsigned long npages) +int kvm_arch_create_memslot(struct kvm *kvm, struct kvm_memory_slot *slot, + unsigned long npages) { return 0; } diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c index eb3e18659630..85685e1cdb89 100644 --- a/arch/mips/lantiq/irq.c +++ b/arch/mips/lantiq/irq.c @@ -390,7 +390,7 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent) ret = of_irq_to_resource_table(eiu_node, ltq_eiu_irq, exin_avail); if (ret != exin_avail) - panic("failed to load external irq resources\n"); + panic("failed to load external irq resources"); if (request_mem_region(res.start, resource_size(&res), res.name) < 0) diff --git a/arch/mips/lantiq/prom.c b/arch/mips/lantiq/prom.c index 49c460370285..19686c5bc5ed 100644 --- a/arch/mips/lantiq/prom.c +++ b/arch/mips/lantiq/prom.c @@ -14,6 +14,7 @@ #include <asm/bootinfo.h> #include <asm/time.h> +#include <asm/prom.h> #include <lantiq.h> diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c index c24924fe087d..51804b10a036 100644 --- a/arch/mips/lantiq/xway/sysctrl.c +++ b/arch/mips/lantiq/xway/sysctrl.c @@ -128,7 +128,7 @@ static int pmu_enable(struct clk *clk) do {} while (--retry && (pmu_r32(PWDSR(clk->module)) & clk->bits)); if (!retry) - panic("activating PMU module failed!\n"); + panic("activating PMU module failed!"); return 0; } diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index bc6f96fcb529..62ffd20ea869 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -346,14 +346,8 @@ static void r4k_blast_scache_setup(void) static inline void local_r4k___flush_cache_all(void * args) { -#if defined(CONFIG_CPU_LOONGSON2) - r4k_blast_scache(); - return; -#endif - r4k_blast_dcache(); - r4k_blast_icache(); - switch (current_cpu_type()) { + case CPU_LOONGSON2: case CPU_R4000SC: case CPU_R4000MC: case CPU_R4400SC: @@ -361,7 +355,18 @@ static inline void local_r4k___flush_cache_all(void * args) case CPU_R10000: case CPU_R12000: case CPU_R14000: + /* + * These caches are inclusive caches, that is, if something + * is not cached in the S-cache, we know it also won't be + * in one of the primary caches. + */ r4k_blast_scache(); + break; + + default: + r4k_blast_dcache(); + r4k_blast_icache(); + break; } } @@ -572,8 +577,17 @@ static inline void local_r4k_flush_icache_range(unsigned long start, unsigned lo if (end - start > icache_size) r4k_blast_icache(); - else - protected_blast_icache_range(start, end); + else { + switch (boot_cpu_type()) { + case CPU_LOONGSON2: + protected_blast_icache_range(start, end); + break; + + default: + protected_loongson23_blast_icache_range(start, end); + break; + } + } } static inline void local_r4k_flush_icache_range_ipi(void *args) @@ -1109,15 +1123,14 @@ static void probe_pcache(void) case CPU_ALCHEMY: c->icache.flags |= MIPS_CACHE_IC_F_DC; break; - } -#ifdef CONFIG_CPU_LOONGSON2 - /* - * LOONGSON2 has 4 way icache, but when using indexed cache op, - * one op will act on all 4 ways - */ - c->icache.ways = 1; -#endif + case CPU_LOONGSON2: + /* + * LOONGSON2 has 4 way icache, but when using indexed cache op, + * one op will act on all 4 ways + */ + c->icache.ways = 1; + } printk("Primary instruction cache %ldkB, %s, %s, linesize %d bytes.\n", icache_size >> 10, @@ -1193,7 +1206,6 @@ static int probe_scache(void) return 1; } -#if defined(CONFIG_CPU_LOONGSON2) static void __init loongson2_sc_init(void) { struct cpuinfo_mips *c = ¤t_cpu_data; @@ -1209,7 +1221,6 @@ static void __init loongson2_sc_init(void) c->options |= MIPS_CPU_INCLUSIVE_CACHES; } -#endif extern int r5k_sc_init(void); extern int rm7k_sc_init(void); @@ -1259,11 +1270,10 @@ static void setup_scache(void) #endif return; -#if defined(CONFIG_CPU_LOONGSON2) case CPU_LOONGSON2: loongson2_sc_init(); return; -#endif + case CPU_XLP: /* don't need to worry about L2, fully coherent */ return; diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index 5f8b95512580..2e9418562258 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c @@ -297,7 +297,6 @@ static void mips_dma_sync_single_for_cpu(struct device *dev, static void mips_dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) { - plat_extra_sync_for_device(dev); if (!plat_device_is_coherent(dev)) __dma_sync(dma_addr_to_page(dev, dma_handle), dma_handle & ~PAGE_MASK, size, direction); @@ -327,7 +326,7 @@ static void mips_dma_sync_sg_for_device(struct device *dev, int mips_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { - return plat_dma_mapping_error(dev, dma_addr); + return 0; } int mips_dma_supported(struct device *dev, u64 mask) @@ -340,7 +339,6 @@ void dma_cache_sync(struct device *dev, void *vaddr, size_t size, { BUG_ON(direction == DMA_NONE); - plat_extra_sync_for_device(dev); if (!plat_device_is_coherent(dev)) __dma_sync_virtual(vaddr, size, direction); } diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index e205ef598e97..12156176c7ca 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -124,7 +124,7 @@ void *kmap_coherent(struct page *page, unsigned long addr) BUG_ON(Page_dcache_dirty(page)); - inc_preempt_count(); + pagefault_disable(); idx = (addr >> PAGE_SHIFT) & (FIX_N_COLOURS - 1); #ifdef CONFIG_MIPS_MT_SMTC idx += FIX_N_COLOURS * smp_processor_id() + @@ -193,8 +193,7 @@ void kunmap_coherent(void) write_c0_entryhi(old_ctx); EXIT_CRITICAL(flags); #endif - dec_preempt_count(); - preempt_check_resched(); + pagefault_enable(); } void copy_user_highpage(struct page *to, struct page *from, diff --git a/arch/mips/mm/tlb-funcs.S b/arch/mips/mm/tlb-funcs.S index 79bca3130bd1..30a494db99c2 100644 --- a/arch/mips/mm/tlb-funcs.S +++ b/arch/mips/mm/tlb-funcs.S @@ -16,12 +16,10 @@ #define FASTPATH_SIZE 128 -#ifdef CONFIG_MIPS_PGD_C0_CONTEXT LEAF(tlbmiss_handler_setup_pgd) .space 16 * 4 END(tlbmiss_handler_setup_pgd) EXPORT(tlbmiss_handler_setup_pgd_end) -#endif LEAF(handle_tlbm) .space FASTPATH_SIZE * 4 diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index bb3a5f643e97..da3b0b9c9eae 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c @@ -52,21 +52,26 @@ extern void build_tlb_refill_handler(void); #endif /* CONFIG_MIPS_MT_SMTC */ -#if defined(CONFIG_CPU_LOONGSON2) /* * LOONGSON2 has a 4 entry itlb which is a subset of dtlb, * unfortrunately, itlb is not totally transparent to software. */ -#define FLUSH_ITLB write_c0_diag(4); - -#define FLUSH_ITLB_VM(vma) { if ((vma)->vm_flags & VM_EXEC) write_c0_diag(4); } - -#else - -#define FLUSH_ITLB -#define FLUSH_ITLB_VM(vma) +static inline void flush_itlb(void) +{ + switch (current_cpu_type()) { + case CPU_LOONGSON2: + write_c0_diag(4); + break; + default: + break; + } +} -#endif +static inline void flush_itlb_vm(struct vm_area_struct *vma) +{ + if (vma->vm_flags & VM_EXEC) + flush_itlb(); +} void local_flush_tlb_all(void) { @@ -93,7 +98,7 @@ void local_flush_tlb_all(void) } tlbw_use_hazard(); write_c0_entryhi(old_ctx); - FLUSH_ITLB; + flush_itlb(); EXIT_CRITICAL(flags); } EXPORT_SYMBOL(local_flush_tlb_all); @@ -155,7 +160,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, } else { drop_mmu_context(mm, cpu); } - FLUSH_ITLB; + flush_itlb(); EXIT_CRITICAL(flags); } } @@ -197,7 +202,7 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) } else { local_flush_tlb_all(); } - FLUSH_ITLB; + flush_itlb(); EXIT_CRITICAL(flags); } @@ -230,7 +235,7 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) finish: write_c0_entryhi(oldpid); - FLUSH_ITLB_VM(vma); + flush_itlb_vm(vma); EXIT_CRITICAL(flags); } } @@ -262,7 +267,7 @@ void local_flush_tlb_one(unsigned long page) tlbw_use_hazard(); } write_c0_entryhi(oldpid); - FLUSH_ITLB; + flush_itlb(); EXIT_CRITICAL(flags); } @@ -335,7 +340,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) tlb_write_indexed(); } tlbw_use_hazard(); - FLUSH_ITLB_VM(vma); + flush_itlb_vm(vma); EXIT_CRITICAL(flags); } diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 9bb3a9363b06..183f2b583e4d 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -340,10 +340,6 @@ static struct work_registers build_get_work_registers(u32 **p) { struct work_registers r; - int smp_processor_id_reg; - int smp_processor_id_sel; - int smp_processor_id_shift; - if (scratch_reg >= 0) { /* Save in CPU local C0_KScratch? */ UASM_i_MTC0(p, 1, c0_kscratch(), scratch_reg); @@ -354,25 +350,9 @@ static struct work_registers build_get_work_registers(u32 **p) } if (num_possible_cpus() > 1) { -#ifdef CONFIG_MIPS_PGD_C0_CONTEXT - smp_processor_id_shift = 51; - smp_processor_id_reg = 20; /* XContext */ - smp_processor_id_sel = 0; -#else -# ifdef CONFIG_32BIT - smp_processor_id_shift = 25; - smp_processor_id_reg = 4; /* Context */ - smp_processor_id_sel = 0; -# endif -# ifdef CONFIG_64BIT - smp_processor_id_shift = 26; - smp_processor_id_reg = 4; /* Context */ - smp_processor_id_sel = 0; -# endif -#endif /* Get smp_processor_id */ - UASM_i_MFC0(p, K0, smp_processor_id_reg, smp_processor_id_sel); - UASM_i_SRL_SAFE(p, K0, K0, smp_processor_id_shift); + UASM_i_CPUID_MFC0(p, K0, SMP_CPUID_REG); + UASM_i_SRL_SAFE(p, K0, K0, SMP_CPUID_REGSHIFT); /* handler_reg_save index in K0 */ UASM_i_SLL(p, K0, K0, ilog2(sizeof(struct tlb_reg_save))); @@ -819,11 +799,11 @@ build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r, } /* No uasm_i_nop needed here, since the next insn doesn't touch TMP. */ -#ifdef CONFIG_MIPS_PGD_C0_CONTEXT if (pgd_reg != -1) { /* pgd is in pgd_reg */ UASM_i_MFC0(p, ptr, c0_kscratch(), pgd_reg); } else { +#if defined(CONFIG_MIPS_PGD_C0_CONTEXT) /* * &pgd << 11 stored in CONTEXT [23..63]. */ @@ -835,30 +815,18 @@ build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r, /* 1 0 1 0 1 << 6 xkphys cached */ uasm_i_ori(p, ptr, ptr, 0x540); uasm_i_drotr(p, ptr, ptr, 11); - } #elif defined(CONFIG_SMP) -# ifdef CONFIG_MIPS_MT_SMTC - /* - * SMTC uses TCBind value as "CPU" index - */ - uasm_i_mfc0(p, ptr, C0_TCBIND); - uasm_i_dsrl_safe(p, ptr, ptr, 19); -# else - /* - * 64 bit SMP running in XKPHYS has smp_processor_id() << 3 - * stored in CONTEXT. - */ - uasm_i_dmfc0(p, ptr, C0_CONTEXT); - uasm_i_dsrl_safe(p, ptr, ptr, 23); -# endif - UASM_i_LA_mostly(p, tmp, pgdc); - uasm_i_daddu(p, ptr, ptr, tmp); - uasm_i_dmfc0(p, tmp, C0_BADVADDR); - uasm_i_ld(p, ptr, uasm_rel_lo(pgdc), ptr); + UASM_i_CPUID_MFC0(p, ptr, SMP_CPUID_REG); + uasm_i_dsrl_safe(p, ptr, ptr, SMP_CPUID_PTRSHIFT); + UASM_i_LA_mostly(p, tmp, pgdc); + uasm_i_daddu(p, ptr, ptr, tmp); + uasm_i_dmfc0(p, tmp, C0_BADVADDR); + uasm_i_ld(p, ptr, uasm_rel_lo(pgdc), ptr); #else - UASM_i_LA_mostly(p, ptr, pgdc); - uasm_i_ld(p, ptr, uasm_rel_lo(pgdc), ptr); + UASM_i_LA_mostly(p, ptr, pgdc); + uasm_i_ld(p, ptr, uasm_rel_lo(pgdc), ptr); #endif + } uasm_l_vmalloc_done(l, *p); @@ -953,31 +921,25 @@ build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r, static void __maybe_unused build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr) { - long pgdc = (long)pgd_current; + if (pgd_reg != -1) { + /* pgd is in pgd_reg */ + uasm_i_mfc0(p, ptr, c0_kscratch(), pgd_reg); + uasm_i_mfc0(p, tmp, C0_BADVADDR); /* get faulting address */ + } else { + long pgdc = (long)pgd_current; - /* 32 bit SMP has smp_processor_id() stored in CONTEXT. */ + /* 32 bit SMP has smp_processor_id() stored in CONTEXT. */ #ifdef CONFIG_SMP -#ifdef CONFIG_MIPS_MT_SMTC - /* - * SMTC uses TCBind value as "CPU" index - */ - uasm_i_mfc0(p, ptr, C0_TCBIND); - UASM_i_LA_mostly(p, tmp, pgdc); - uasm_i_srl(p, ptr, ptr, 19); -#else - /* - * smp_processor_id() << 2 is stored in CONTEXT. - */ - uasm_i_mfc0(p, ptr, C0_CONTEXT); - UASM_i_LA_mostly(p, tmp, pgdc); - uasm_i_srl(p, ptr, ptr, 23); -#endif - uasm_i_addu(p, ptr, tmp, ptr); + uasm_i_mfc0(p, ptr, SMP_CPUID_REG); + UASM_i_LA_mostly(p, tmp, pgdc); + uasm_i_srl(p, ptr, ptr, SMP_CPUID_PTRSHIFT); + uasm_i_addu(p, ptr, tmp, ptr); #else - UASM_i_LA_mostly(p, ptr, pgdc); + UASM_i_LA_mostly(p, ptr, pgdc); #endif - uasm_i_mfc0(p, tmp, C0_BADVADDR); /* get faulting address */ - uasm_i_lw(p, ptr, uasm_rel_lo(pgdc), ptr); + uasm_i_mfc0(p, tmp, C0_BADVADDR); /* get faulting address */ + uasm_i_lw(p, ptr, uasm_rel_lo(pgdc), ptr); + } uasm_i_srl(p, tmp, tmp, PGDIR_SHIFT); /* get pgd only bits */ uasm_i_sll(p, tmp, tmp, PGD_T_LOG2); uasm_i_addu(p, ptr, ptr, tmp); /* add in pgd offset */ @@ -1349,95 +1311,100 @@ static void build_r4000_tlb_refill_handler(void) * need three, with the second nop'ed and the third being * unused. */ - /* Loongson2 ebase is different than r4k, we have more space */ -#if defined(CONFIG_32BIT) || defined(CONFIG_CPU_LOONGSON2) - if ((p - tlb_handler) > 64) - panic("TLB refill handler space exceeded"); -#else - if (((p - tlb_handler) > (MIPS64_REFILL_INSNS * 2) - 1) - || (((p - tlb_handler) > (MIPS64_REFILL_INSNS * 2) - 3) - && uasm_insn_has_bdelay(relocs, - tlb_handler + MIPS64_REFILL_INSNS - 3))) - panic("TLB refill handler space exceeded"); -#endif - - /* - * Now fold the handler in the TLB refill handler space. - */ -#if defined(CONFIG_32BIT) || defined(CONFIG_CPU_LOONGSON2) - f = final_handler; - /* Simplest case, just copy the handler. */ - uasm_copy_handler(relocs, labels, tlb_handler, p, f); - final_len = p - tlb_handler; -#else /* CONFIG_64BIT */ - f = final_handler + MIPS64_REFILL_INSNS; - if ((p - tlb_handler) <= MIPS64_REFILL_INSNS) { - /* Just copy the handler. */ - uasm_copy_handler(relocs, labels, tlb_handler, p, f); - final_len = p - tlb_handler; - } else { -#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT - const enum label_id ls = label_tlb_huge_update; -#else - const enum label_id ls = label_vmalloc; -#endif - u32 *split; - int ov = 0; - int i; - - for (i = 0; i < ARRAY_SIZE(labels) && labels[i].lab != ls; i++) - ; - BUG_ON(i == ARRAY_SIZE(labels)); - split = labels[i].addr; - - /* - * See if we have overflown one way or the other. - */ - if (split > tlb_handler + MIPS64_REFILL_INSNS || - split < p - MIPS64_REFILL_INSNS) - ov = 1; - - if (ov) { + switch (boot_cpu_type()) { + default: + if (sizeof(long) == 4) { + case CPU_LOONGSON2: + /* Loongson2 ebase is different than r4k, we have more space */ + if ((p - tlb_handler) > 64) + panic("TLB refill handler space exceeded"); /* - * Split two instructions before the end. One - * for the branch and one for the instruction - * in the delay slot. + * Now fold the handler in the TLB refill handler space. */ - split = tlb_handler + MIPS64_REFILL_INSNS - 2; - + f = final_handler; + /* Simplest case, just copy the handler. */ + uasm_copy_handler(relocs, labels, tlb_handler, p, f); + final_len = p - tlb_handler; + break; + } else { + if (((p - tlb_handler) > (MIPS64_REFILL_INSNS * 2) - 1) + || (((p - tlb_handler) > (MIPS64_REFILL_INSNS * 2) - 3) + && uasm_insn_has_bdelay(relocs, + tlb_handler + MIPS64_REFILL_INSNS - 3))) + panic("TLB refill handler space exceeded"); /* - * If the branch would fall in a delay slot, - * we must back up an additional instruction - * so that it is no longer in a delay slot. + * Now fold the handler in the TLB refill handler space. */ - if (uasm_insn_has_bdelay(relocs, split - 1)) - split--; - } - /* Copy first part of the handler. */ - uasm_copy_handler(relocs, labels, tlb_handler, split, f); - f += split - tlb_handler; - - if (ov) { - /* Insert branch. */ - uasm_l_split(&l, final_handler); - uasm_il_b(&f, &r, label_split); - if (uasm_insn_has_bdelay(relocs, split)) - uasm_i_nop(&f); - else { - uasm_copy_handler(relocs, labels, - split, split + 1, f); - uasm_move_labels(labels, f, f + 1, -1); - f++; - split++; + f = final_handler + MIPS64_REFILL_INSNS; + if ((p - tlb_handler) <= MIPS64_REFILL_INSNS) { + /* Just copy the handler. */ + uasm_copy_handler(relocs, labels, tlb_handler, p, f); + final_len = p - tlb_handler; + } else { +#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT + const enum label_id ls = label_tlb_huge_update; +#else + const enum label_id ls = label_vmalloc; +#endif + u32 *split; + int ov = 0; + int i; + + for (i = 0; i < ARRAY_SIZE(labels) && labels[i].lab != ls; i++) + ; + BUG_ON(i == ARRAY_SIZE(labels)); + split = labels[i].addr; + + /* + * See if we have overflown one way or the other. + */ + if (split > tlb_handler + MIPS64_REFILL_INSNS || + split < p - MIPS64_REFILL_INSNS) + ov = 1; + + if (ov) { + /* + * Split two instructions before the end. One + * for the branch and one for the instruction + * in the delay slot. + */ + split = tlb_handler + MIPS64_REFILL_INSNS - 2; + + /* + * If the branch would fall in a delay slot, + * we must back up an additional instruction + * so that it is no longer in a delay slot. + */ + if (uasm_insn_has_bdelay(relocs, split - 1)) + split--; + } + /* Copy first part of the handler. */ + uasm_copy_handler(relocs, labels, tlb_handler, split, f); + f += split - tlb_handler; + + if (ov) { + /* Insert branch. */ + uasm_l_split(&l, final_handler); + uasm_il_b(&f, &r, label_split); + if (uasm_insn_has_bdelay(relocs, split)) + uasm_i_nop(&f); + else { + uasm_copy_handler(relocs, labels, + split, split + 1, f); + uasm_move_labels(labels, f, f + 1, -1); + f++; + split++; + } + } + + /* Copy the rest of the handler. */ + uasm_copy_handler(relocs, labels, split, p, final_handler); + final_len = (f - (final_handler + MIPS64_REFILL_INSNS)) + + (p - split); } } - - /* Copy the rest of the handler. */ - uasm_copy_handler(relocs, labels, split, p, final_handler); - final_len = (f - (final_handler + MIPS64_REFILL_INSNS)) + - (p - split); + break; } -#endif /* CONFIG_64BIT */ uasm_resolve_relocs(relocs, labels); pr_debug("Wrote TLB refill handler (%u instructions).\n", @@ -1451,28 +1418,30 @@ static void build_r4000_tlb_refill_handler(void) extern u32 handle_tlbl[], handle_tlbl_end[]; extern u32 handle_tlbs[], handle_tlbs_end[]; extern u32 handle_tlbm[], handle_tlbm_end[]; - -#ifdef CONFIG_MIPS_PGD_C0_CONTEXT extern u32 tlbmiss_handler_setup_pgd[], tlbmiss_handler_setup_pgd_end[]; -static void build_r4000_setup_pgd(void) +static void build_setup_pgd(void) { const int a0 = 4; - const int a1 = 5; + const int __maybe_unused a1 = 5; + const int __maybe_unused a2 = 6; u32 *p = tlbmiss_handler_setup_pgd; const int tlbmiss_handler_setup_pgd_size = tlbmiss_handler_setup_pgd_end - tlbmiss_handler_setup_pgd; - struct uasm_label *l = labels; - struct uasm_reloc *r = relocs; +#ifndef CONFIG_MIPS_PGD_C0_CONTEXT + long pgdc = (long)pgd_current; +#endif memset(tlbmiss_handler_setup_pgd, 0, tlbmiss_handler_setup_pgd_size * sizeof(tlbmiss_handler_setup_pgd[0])); memset(labels, 0, sizeof(labels)); memset(relocs, 0, sizeof(relocs)); - pgd_reg = allocate_kscratch(); - +#ifdef CONFIG_MIPS_PGD_C0_CONTEXT if (pgd_reg == -1) { + struct uasm_label *l = labels; + struct uasm_reloc *r = relocs; + /* PGD << 11 in c0_Context */ /* * If it is a ckseg0 address, convert to a physical @@ -1494,6 +1463,26 @@ static void build_r4000_setup_pgd(void) uasm_i_jr(&p, 31); UASM_i_MTC0(&p, a0, c0_kscratch(), pgd_reg); } +#else +#ifdef CONFIG_SMP + /* Save PGD to pgd_current[smp_processor_id()] */ + UASM_i_CPUID_MFC0(&p, a1, SMP_CPUID_REG); + UASM_i_SRL_SAFE(&p, a1, a1, SMP_CPUID_PTRSHIFT); + UASM_i_LA_mostly(&p, a2, pgdc); + UASM_i_ADDU(&p, a2, a2, a1); + UASM_i_SW(&p, a0, uasm_rel_lo(pgdc), a2); +#else + UASM_i_LA_mostly(&p, a2, pgdc); + UASM_i_SW(&p, a0, uasm_rel_lo(pgdc), a2); +#endif /* SMP */ + uasm_i_jr(&p, 31); + + /* if pgd_reg is allocated, save PGD also to scratch register */ + if (pgd_reg != -1) + UASM_i_MTC0(&p, a0, c0_kscratch(), pgd_reg); + else + uasm_i_nop(&p); +#endif if (p >= tlbmiss_handler_setup_pgd_end) panic("tlbmiss_handler_setup_pgd space exceeded"); @@ -1504,7 +1493,6 @@ static void build_r4000_setup_pgd(void) dump_handler("tlbmiss_handler", tlbmiss_handler_setup_pgd, tlbmiss_handler_setup_pgd_size); } -#endif static void iPTE_LW(u32 **p, unsigned int pte, unsigned int ptr) @@ -2197,10 +2185,8 @@ static void flush_tlb_handlers(void) (unsigned long)handle_tlbs_end); local_flush_icache_range((unsigned long)handle_tlbm, (unsigned long)handle_tlbm_end); -#ifdef CONFIG_MIPS_PGD_C0_CONTEXT local_flush_icache_range((unsigned long)tlbmiss_handler_setup_pgd, (unsigned long)tlbmiss_handler_setup_pgd_end); -#endif } void build_tlb_refill_handler(void) @@ -2232,6 +2218,7 @@ void build_tlb_refill_handler(void) if (!run_once) { if (!cpu_has_local_ebase) build_r3000_tlb_refill_handler(); + build_setup_pgd(); build_r3000_tlb_load_handler(); build_r3000_tlb_store_handler(); build_r3000_tlb_modify_handler(); @@ -2255,9 +2242,7 @@ void build_tlb_refill_handler(void) default: if (!run_once) { scratch_reg = allocate_kscratch(); -#ifdef CONFIG_MIPS_PGD_C0_CONTEXT - build_r4000_setup_pgd(); -#endif + build_setup_pgd(); build_r4000_tlb_load_handler(); build_r4000_tlb_store_handler(); build_r4000_tlb_modify_handler(); diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c index c69da3734699..0892575f829d 100644 --- a/arch/mips/mti-malta/malta-int.c +++ b/arch/mips/mti-malta/malta-int.c @@ -37,7 +37,6 @@ #include <asm/irq_regs.h> #include <asm/mips-boards/malta.h> #include <asm/mips-boards/maltaint.h> -#include <asm/mips-boards/piix4.h> #include <asm/gt64120.h> #include <asm/mips-boards/generic.h> #include <asm/mips-boards/msc01_pci.h> @@ -473,7 +472,7 @@ static void __init fill_ipi_map(void) { int cpu; - for (cpu = 0; cpu < NR_CPUS; cpu++) { + for (cpu = 0; cpu < nr_cpu_ids; cpu++) { fill_ipi_map1(gic_resched_int_base, cpu, GIC_CPU_INT1); fill_ipi_map1(gic_call_int_base, cpu, GIC_CPU_INT2); } @@ -574,8 +573,9 @@ void __init arch_init_irq(void) /* FIXME */ int i; #if defined(CONFIG_MIPS_MT_SMP) - gic_call_int_base = GIC_NUM_INTRS - NR_CPUS; - gic_resched_int_base = gic_call_int_base - NR_CPUS; + gic_call_int_base = GIC_NUM_INTRS - + (NR_CPUS - nr_cpu_ids) * 2 - nr_cpu_ids; + gic_resched_int_base = gic_call_int_base - nr_cpu_ids; fill_ipi_map(); #endif gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, gic_intr_map, @@ -599,7 +599,7 @@ void __init arch_init_irq(void) printk("CPU%d: status register now %08x\n", smp_processor_id(), read_c0_status()); write_c0_status(0x1100dc00); printk("CPU%d: status register frc %08x\n", smp_processor_id(), read_c0_status()); - for (i = 0; i < NR_CPUS; i++) { + for (i = 0; i < nr_cpu_ids; i++) { arch_init_ipiirq(MIPS_GIC_IRQ_BASE + GIC_RESCHED_INT(i), &irq_resched); arch_init_ipiirq(MIPS_GIC_IRQ_BASE + diff --git a/arch/mips/mti-sead3/sead3-setup.c b/arch/mips/mti-sead3/sead3-setup.c index b5059dc899f4..928ba84c8a78 100644 --- a/arch/mips/mti-sead3/sead3-setup.c +++ b/arch/mips/mti-sead3/sead3-setup.c @@ -10,6 +10,8 @@ #include <linux/of_fdt.h> #include <linux/bootmem.h> +#include <asm/prom.h> + #include <asm/mips-boards/generic.h> const char *get_system_type(void) diff --git a/arch/mips/netlogic/common/smp.c b/arch/mips/netlogic/common/smp.c index 6f8feb9efcff..c0eded01fde9 100644 --- a/arch/mips/netlogic/common/smp.c +++ b/arch/mips/netlogic/common/smp.c @@ -245,7 +245,7 @@ static int nlm_parse_cpumask(cpumask_t *wakeup_mask) return threadmode; unsupp: - panic("Unsupported CPU mask %lx\n", + panic("Unsupported CPU mask %lx", (unsigned long)cpumask_bits(wakeup_mask)[0]); return 0; } diff --git a/arch/mips/netlogic/xlp/dt.c b/arch/mips/netlogic/xlp/dt.c index 88df445dda76..8316d5454b17 100644 --- a/arch/mips/netlogic/xlp/dt.c +++ b/arch/mips/netlogic/xlp/dt.c @@ -39,8 +39,11 @@ #include <linux/of_platform.h> #include <linux/of_device.h> +#include <asm/prom.h> + extern u32 __dtb_xlp_evp_begin[], __dtb_xlp_svp_begin[], __dtb_xlp_fvp_begin[], __dtb_start[]; +static void *xlp_fdt_blob; void __init *xlp_dt_init(void *fdtp) { @@ -67,19 +70,26 @@ void __init *xlp_dt_init(void *fdtp) break; } } - initial_boot_params = fdtp; + xlp_fdt_blob = fdtp; return fdtp; } +void __init xlp_early_init_devtree(void) +{ + __dt_setup_arch(xlp_fdt_blob); + strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE); +} + void __init device_tree_init(void) { unsigned long base, size; + struct boot_param_header *fdtp = xlp_fdt_blob; - if (!initial_boot_params) + if (!fdtp) return; - base = virt_to_phys((void *)initial_boot_params); - size = be32_to_cpu(initial_boot_params->totalsize); + base = virt_to_phys(fdtp); + size = be32_to_cpu(fdtp->totalsize); /* Before we do anything, lets reserve the dt blob */ reserve_bootmem(base, size, BOOTMEM_DEFAULT); diff --git a/arch/mips/netlogic/xlp/setup.c b/arch/mips/netlogic/xlp/setup.c index 76a7131e486e..6d981bb337ec 100644 --- a/arch/mips/netlogic/xlp/setup.c +++ b/arch/mips/netlogic/xlp/setup.c @@ -98,7 +98,7 @@ void __init plat_mem_setup(void) pm_power_off = nlm_linux_exit; /* memory and bootargs from DT */ - early_init_devtree(initial_boot_params); + xlp_early_init_devtree(); if (boot_mem_map.nr_map == 0) { pr_info("Using DRAM BARs for memory map.\n"); diff --git a/arch/mips/pci/fixup-lantiq.c b/arch/mips/pci/fixup-lantiq.c index 6c829df28dc7..c2ce41ea61d7 100644 --- a/arch/mips/pci/fixup-lantiq.c +++ b/arch/mips/pci/fixup-lantiq.c @@ -25,16 +25,5 @@ int pcibios_plat_dev_init(struct pci_dev *dev) int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { - struct of_irq dev_irq; - int irq; - - if (of_irq_map_pci(dev, &dev_irq)) { - dev_err(&dev->dev, "trying to map irq for unknown slot:%d pin:%d\n", - slot, pin); - return 0; - } - irq = irq_create_of_mapping(dev_irq.controller, dev_irq.specifier, - dev_irq.size); - dev_info(&dev->dev, "SLOT:%d PIN:%d IRQ:%d\n", slot, pin, irq); - return irq; + return of_irq_parse_and_map_pci(dev, slot, pin); } diff --git a/arch/mips/pci/fixup-malta.c b/arch/mips/pci/fixup-malta.c index 07ada7f8441e..df36e2327c54 100644 --- a/arch/mips/pci/fixup-malta.c +++ b/arch/mips/pci/fixup-malta.c @@ -1,5 +1,6 @@ #include <linux/init.h> #include <linux/pci.h> +#include <asm/mips-boards/piix4.h> /* PCI interrupt pins */ #define PCIA 1 @@ -53,7 +54,8 @@ int pcibios_plat_dev_init(struct pci_dev *dev) static void malta_piix_func0_fixup(struct pci_dev *pdev) { unsigned char reg_val; - static int piixirqmap[16] = { /* PIIX PIRQC[A:D] irq mappings */ + /* PIIX PIRQC[A:D] irq mappings */ + static int piixirqmap[PIIX4_FUNC0_PIRQRC_IRQ_ROUTING_MAX] = { 0, 0, 0, 3, 4, 5, 6, 7, 0, 9, 10, 11, @@ -63,11 +65,12 @@ static void malta_piix_func0_fixup(struct pci_dev *pdev) /* Interrogate PIIX4 to get PCI IRQ mapping */ for (i = 0; i <= 3; i++) { - pci_read_config_byte(pdev, 0x60+i, ®_val); - if (reg_val & 0x80) + pci_read_config_byte(pdev, PIIX4_FUNC0_PIRQRC+i, ®_val); + if (reg_val & PIIX4_FUNC0_PIRQRC_IRQ_ROUTING_DISABLE) pci_irq[PCIA+i] = 0; /* Disabled */ else - pci_irq[PCIA+i] = piixirqmap[reg_val & 15]; + pci_irq[PCIA+i] = piixirqmap[reg_val & + PIIX4_FUNC0_PIRQRC_IRQ_ROUTING_MASK]; } /* Done by YAMON 2.00 onwards */ @@ -76,8 +79,9 @@ static void malta_piix_func0_fixup(struct pci_dev *pdev) * Set top of main memory accessible by ISA or DMA * devices to 16 Mb. */ - pci_read_config_byte(pdev, 0x69, ®_val); - pci_write_config_byte(pdev, 0x69, reg_val | 0xf0); + pci_read_config_byte(pdev, PIIX4_FUNC0_TOM, ®_val); + pci_write_config_byte(pdev, PIIX4_FUNC0_TOM, reg_val | + PIIX4_FUNC0_TOM_TOP_OF_MEMORY_MASK); } } @@ -93,10 +97,14 @@ static void malta_piix_func1_fixup(struct pci_dev *pdev) /* * IDE Decode enable. */ - pci_read_config_byte(pdev, 0x41, ®_val); - pci_write_config_byte(pdev, 0x41, reg_val|0x80); - pci_read_config_byte(pdev, 0x43, ®_val); - pci_write_config_byte(pdev, 0x43, reg_val|0x80); + pci_read_config_byte(pdev, PIIX4_FUNC1_IDETIM_PRIMARY_HI, + ®_val); + pci_write_config_byte(pdev, PIIX4_FUNC1_IDETIM_PRIMARY_HI, + reg_val|PIIX4_FUNC1_IDETIM_PRIMARY_HI_IDE_DECODE_EN); + pci_read_config_byte(pdev, PIIX4_FUNC1_IDETIM_SECONDARY_HI, + ®_val); + pci_write_config_byte(pdev, PIIX4_FUNC1_IDETIM_SECONDARY_HI, + reg_val|PIIX4_FUNC1_IDETIM_SECONDARY_HI_IDE_DECODE_EN); } } @@ -108,10 +116,12 @@ static void quirk_dlcsetup(struct pci_dev *dev) { u8 odlc, ndlc; - (void) pci_read_config_byte(dev, 0x82, &odlc); + (void) pci_read_config_byte(dev, PIIX4_FUNC0_DLC, &odlc); /* Enable passive releases and delayed transaction */ - ndlc = odlc | 7; - (void) pci_write_config_byte(dev, 0x82, ndlc); + ndlc = odlc | PIIX4_FUNC0_DLC_USBPR_EN | + PIIX4_FUNC0_DLC_PASSIVE_RELEASE_EN | + PIIX4_FUNC0_DLC_DELAYED_TRANSACTION_EN; + (void) pci_write_config_byte(dev, PIIX4_FUNC0_DLC, ndlc); } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0, diff --git a/arch/mips/pci/pci-ar71xx.c b/arch/mips/pci/pci-ar71xx.c index 18517dd0f709..d471a26dd5f8 100644 --- a/arch/mips/pci/pci-ar71xx.c +++ b/arch/mips/pci/pci-ar71xx.c @@ -363,9 +363,6 @@ static int ar71xx_pci_probe(struct platform_device *pdev) spin_lock_init(&apc->lock); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg_base"); - if (!res) - return -EINVAL; - apc->cfg_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(apc->cfg_base)) return PTR_ERR(apc->cfg_base); diff --git a/arch/mips/pci/pci-ar724x.c b/arch/mips/pci/pci-ar724x.c index 65ec032fa0b4..785b2659b519 100644 --- a/arch/mips/pci/pci-ar724x.c +++ b/arch/mips/pci/pci-ar724x.c @@ -362,25 +362,16 @@ static int ar724x_pci_probe(struct platform_device *pdev) return -ENOMEM; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl_base"); - if (!res) - return -EINVAL; - apc->ctrl_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(apc->ctrl_base)) return PTR_ERR(apc->ctrl_base); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg_base"); - if (!res) - return -EINVAL; - apc->devcfg_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(apc->devcfg_base)) return PTR_ERR(apc->devcfg_base); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "crp_base"); - if (!res) - return -EINVAL; - apc->crp_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(apc->crp_base)) return PTR_ERR(apc->crp_base); diff --git a/arch/mips/pci/pci-rt3883.c b/arch/mips/pci/pci-rt3883.c index 95c9d41382e7..adeff2bfe4cd 100644 --- a/arch/mips/pci/pci-rt3883.c +++ b/arch/mips/pci/pci-rt3883.c @@ -583,29 +583,7 @@ err_put_intc_node: int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { - struct of_irq dev_irq; - int err; - int irq; - - err = of_irq_map_pci(dev, &dev_irq); - if (err) { - pr_err("pci %s: unable to get irq map, err=%d\n", - pci_name((struct pci_dev *) dev), err); - return 0; - } - - irq = irq_create_of_mapping(dev_irq.controller, - dev_irq.specifier, - dev_irq.size); - - if (irq == 0) - pr_crit("pci %s: no irq found for pin %u\n", - pci_name((struct pci_dev *) dev), pin); - else - pr_info("pci %s: using irq %d for pin %u\n", - pci_name((struct pci_dev *) dev), irq, pin); - - return irq; + return of_irq_parse_and_map_pci(dev, slot, pin); } int pcibios_plat_dev_init(struct pci_dev *dev) diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index 33e7aa52d9c4..1bf60b127377 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c @@ -120,51 +120,37 @@ static void pcibios_scanbus(struct pci_controller *hose) #ifdef CONFIG_OF void pci_load_of_ranges(struct pci_controller *hose, struct device_node *node) { - const __be32 *ranges; - int rlen; - int pna = of_n_addr_cells(node); - int np = pna + 5; + struct of_pci_range range; + struct of_pci_range_parser parser; pr_info("PCI host bridge %s ranges:\n", node->full_name); - ranges = of_get_property(node, "ranges", &rlen); - if (ranges == NULL) - return; hose->of_node = node; - while ((rlen -= np * 4) >= 0) { - u32 pci_space; + if (of_pci_range_parser_init(&parser, node)) + return; + + for_each_of_pci_range(&parser, &range) { struct resource *res = NULL; - u64 addr, size; - - pci_space = be32_to_cpup(&ranges[0]); - addr = of_translate_address(node, ranges + 3); - size = of_read_number(ranges + pna + 3, 2); - ranges += np; - switch ((pci_space >> 24) & 0x3) { - case 1: /* PCI IO space */ + + switch (range.flags & IORESOURCE_TYPE_BITS) { + case IORESOURCE_IO: pr_info(" IO 0x%016llx..0x%016llx\n", - addr, addr + size - 1); + range.cpu_addr, + range.cpu_addr + range.size - 1); hose->io_map_base = - (unsigned long)ioremap(addr, size); + (unsigned long)ioremap(range.cpu_addr, + range.size); res = hose->io_resource; - res->flags = IORESOURCE_IO; break; - case 2: /* PCI Memory space */ - case 3: /* PCI 64 bits Memory space */ + case IORESOURCE_MEM: pr_info(" MEM 0x%016llx..0x%016llx\n", - addr, addr + size - 1); + range.cpu_addr, + range.cpu_addr + range.size - 1); res = hose->mem_resource; - res->flags = IORESOURCE_MEM; break; } - if (res != NULL) { - res->start = addr; - res->name = node->full_name; - res->end = res->start + size - 1; - res->parent = NULL; - res->sibling = NULL; - res->child = NULL; - } + if (res != NULL) + of_pci_range_to_resource(&range, node, res); } } diff --git a/arch/mips/powertv/Kconfig b/arch/mips/powertv/Kconfig deleted file mode 100644 index dd91fbacbcba..000000000000 --- a/arch/mips/powertv/Kconfig +++ /dev/null @@ -1,12 +0,0 @@ -config BOOTLOADER_FAMILY - string "POWERTV Bootloader Family string" - default "85" - depends on POWERTV - help - This value should be specified when the bootloader driver is disabled - and must be exactly two characters long. Families supported are: - R1 - RNG-100 R2 - RNG-200 - A1 - Class A B1 - Class B - E1 - Class E F1 - Class F - 44 - 45xx 46 - 46xx - 85 - 85xx 86 - 86xx diff --git a/arch/mips/powertv/Makefile b/arch/mips/powertv/Makefile deleted file mode 100644 index 39ca9f8d63ae..000000000000 --- a/arch/mips/powertv/Makefile +++ /dev/null @@ -1,29 +0,0 @@ -# -# Carsten Langgaard, carstenl@mips.com -# Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. -# -# Carsten Langgaard, carstenl@mips.com -# Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. -# Portions copyright (C) 2009 Cisco Systems, Inc. -# -# This program is free software; you can distribute it and/or modify it -# under the terms 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, write to the Free Software Foundation, Inc., -# 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -# -# Makefile for the Cisco PowerTV-specific kernel interface routines -# under Linux. -# - -obj-y += init.o ioremap.o memory.o powertv_setup.o reset.o time.o \ - asic/ pci/ - -obj-$(CONFIG_USB) += powertv-usb.o diff --git a/arch/mips/powertv/Platform b/arch/mips/powertv/Platform deleted file mode 100644 index 4eb5af1d8eea..000000000000 --- a/arch/mips/powertv/Platform +++ /dev/null @@ -1,7 +0,0 @@ -# -# Cisco PowerTV Platform -# -platform-$(CONFIG_POWERTV) += powertv/ -cflags-$(CONFIG_POWERTV) += \ - -I$(srctree)/arch/mips/include/asm/mach-powertv -load-$(CONFIG_POWERTV) += 0xffffffff90800000 diff --git a/arch/mips/powertv/asic/Makefile b/arch/mips/powertv/asic/Makefile deleted file mode 100644 index 35dcc53eb25f..000000000000 --- a/arch/mips/powertv/asic/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# -# Copyright (C) 2009 Scientific-Atlanta, Inc. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that 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, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -# - -obj-y += asic-calliope.o asic-cronus.o asic-gaia.o asic-zeus.o \ - asic_devices.o asic_int.o irq_asic.o prealloc-calliope.o \ - prealloc-cronus.o prealloc-cronuslite.o prealloc-gaia.o prealloc-zeus.o diff --git a/arch/mips/powertv/asic/asic-calliope.c b/arch/mips/powertv/asic/asic-calliope.c deleted file mode 100644 index 2f539b43f56b..000000000000 --- a/arch/mips/powertv/asic/asic-calliope.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Locations of devices in the Calliope ASIC. - * - * Copyright (C) 2005-2009 Scientific-Atlanta, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that 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, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Author: Ken Eppinett - * David Schleef <ds@schleef.org> - * - * Description: Defines the platform resources for the SA settop. - */ - -#include <linux/init.h> -#include <asm/mach-powertv/asic.h> - -#define CALLIOPE_ADDR(x) (CALLIOPE_IO_BASE + (x)) - -const struct register_map calliope_register_map __initconst = { - .eic_slow0_strt_add = {.phys = CALLIOPE_ADDR(0x800000)}, - .eic_cfg_bits = {.phys = CALLIOPE_ADDR(0x800038)}, - .eic_ready_status = {.phys = CALLIOPE_ADDR(0x80004c)}, - - .chipver3 = {.phys = CALLIOPE_ADDR(0xA00800)}, - .chipver2 = {.phys = CALLIOPE_ADDR(0xA00804)}, - .chipver1 = {.phys = CALLIOPE_ADDR(0xA00808)}, - .chipver0 = {.phys = CALLIOPE_ADDR(0xA0080c)}, - - /* The registers of IRBlaster */ - .uart1_intstat = {.phys = CALLIOPE_ADDR(0xA01800)}, - .uart1_inten = {.phys = CALLIOPE_ADDR(0xA01804)}, - .uart1_config1 = {.phys = CALLIOPE_ADDR(0xA01808)}, - .uart1_config2 = {.phys = CALLIOPE_ADDR(0xA0180C)}, - .uart1_divisorhi = {.phys = CALLIOPE_ADDR(0xA01810)}, - .uart1_divisorlo = {.phys = CALLIOPE_ADDR(0xA01814)}, - .uart1_data = {.phys = CALLIOPE_ADDR(0xA01818)}, - .uart1_status = {.phys = CALLIOPE_ADDR(0xA0181C)}, - - .int_stat_3 = {.phys = CALLIOPE_ADDR(0xA02800)}, - .int_stat_2 = {.phys = CALLIOPE_ADDR(0xA02804)}, - .int_stat_1 = {.phys = CALLIOPE_ADDR(0xA02808)}, - .int_stat_0 = {.phys = CALLIOPE_ADDR(0xA0280c)}, - .int_config = {.phys = CALLIOPE_ADDR(0xA02810)}, - .int_int_scan = {.phys = CALLIOPE_ADDR(0xA02818)}, - .ien_int_3 = {.phys = CALLIOPE_ADDR(0xA02830)}, - .ien_int_2 = {.phys = CALLIOPE_ADDR(0xA02834)}, - .ien_int_1 = {.phys = CALLIOPE_ADDR(0xA02838)}, - .ien_int_0 = {.phys = CALLIOPE_ADDR(0xA0283c)}, - .int_level_3_3 = {.phys = CALLIOPE_ADDR(0xA02880)}, - .int_level_3_2 = {.phys = CALLIOPE_ADDR(0xA02884)}, - .int_level_3_1 = {.phys = CALLIOPE_ADDR(0xA02888)}, - .int_level_3_0 = {.phys = CALLIOPE_ADDR(0xA0288c)}, - .int_level_2_3 = {.phys = CALLIOPE_ADDR(0xA02890)}, - .int_level_2_2 = {.phys = CALLIOPE_ADDR(0xA02894)}, - .int_level_2_1 = {.phys = CALLIOPE_ADDR(0xA02898)}, - .int_level_2_0 = {.phys = CALLIOPE_ADDR(0xA0289c)}, - .int_level_1_3 = {.phys = CALLIOPE_ADDR(0xA028a0)}, - .int_level_1_2 = {.phys = CALLIOPE_ADDR(0xA028a4)}, - .int_level_1_1 = {.phys = CALLIOPE_ADDR(0xA028a8)}, - .int_level_1_0 = {.phys = CALLIOPE_ADDR(0xA028ac)}, - .int_level_0_3 = {.phys = CALLIOPE_ADDR(0xA028b0)}, - .int_level_0_2 = {.phys = CALLIOPE_ADDR(0xA028b4)}, - .int_level_0_1 = {.phys = CALLIOPE_ADDR(0xA028b8)}, - .int_level_0_0 = {.phys = CALLIOPE_ADDR(0xA028bc)}, - .int_docsis_en = {.phys = CALLIOPE_ADDR(0xA028F4)}, - - .mips_pll_setup = {.phys = CALLIOPE_ADDR(0x980000)}, - .fs432x4b4_usb_ctl = {.phys = CALLIOPE_ADDR(0x980030)}, - .test_bus = {.phys = CALLIOPE_ADDR(0x9800CC)}, - .crt_spare = {.phys = CALLIOPE_ADDR(0x9800d4)}, - .usb2_ohci_int_mask = {.phys = CALLIOPE_ADDR(0x9A000c)}, - .usb2_strap = {.phys = CALLIOPE_ADDR(0x9A0014)}, - .ehci_hcapbase = {.phys = CALLIOPE_ADDR(0x9BFE00)}, - .ohci_hc_revision = {.phys = CALLIOPE_ADDR(0x9BFC00)}, - .bcm1_bs_lmi_steer = {.phys = CALLIOPE_ADDR(0x9E0004)}, - .usb2_control = {.phys = CALLIOPE_ADDR(0x9E0054)}, - .usb2_stbus_obc = {.phys = CALLIOPE_ADDR(0x9BFF00)}, - .usb2_stbus_mess_size = {.phys = CALLIOPE_ADDR(0x9BFF04)}, - .usb2_stbus_chunk_size = {.phys = CALLIOPE_ADDR(0x9BFF08)}, - - .pcie_regs = {.phys = 0x000000}, /* -doesn't exist- */ - .tim_ch = {.phys = CALLIOPE_ADDR(0xA02C10)}, - .tim_cl = {.phys = CALLIOPE_ADDR(0xA02C14)}, - .gpio_dout = {.phys = CALLIOPE_ADDR(0xA02c20)}, - .gpio_din = {.phys = CALLIOPE_ADDR(0xA02c24)}, - .gpio_dir = {.phys = CALLIOPE_ADDR(0xA02c2C)}, - .watchdog = {.phys = CALLIOPE_ADDR(0xA02c30)}, - .front_panel = {.phys = 0x000000}, /* -not used- */ -}; diff --git a/arch/mips/powertv/asic/asic-cronus.c b/arch/mips/powertv/asic/asic-cronus.c deleted file mode 100644 index 7f8f3429b35a..000000000000 --- a/arch/mips/powertv/asic/asic-cronus.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Locations of devices in the Cronus ASIC - * - * Copyright (C) 2005-2009 Scientific-Atlanta, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that 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, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Author: Ken Eppinett - * David Schleef <ds@schleef.org> - * - * Description: Defines the platform resources for the SA settop. - */ - -#include <linux/init.h> -#include <asm/mach-powertv/asic.h> - -#define CRONUS_ADDR(x) (CRONUS_IO_BASE + (x)) - -const struct register_map cronus_register_map __initconst = { - .eic_slow0_strt_add = {.phys = CRONUS_ADDR(0x000000)}, - .eic_cfg_bits = {.phys = CRONUS_ADDR(0x000038)}, - .eic_ready_status = {.phys = CRONUS_ADDR(0x00004C)}, - - .chipver3 = {.phys = CRONUS_ADDR(0x2A0800)}, - .chipver2 = {.phys = CRONUS_ADDR(0x2A0804)}, - .chipver1 = {.phys = CRONUS_ADDR(0x2A0808)}, - .chipver0 = {.phys = CRONUS_ADDR(0x2A080C)}, - - /* The registers of IRBlaster */ - .uart1_intstat = {.phys = CRONUS_ADDR(0x2A1800)}, - .uart1_inten = {.phys = CRONUS_ADDR(0x2A1804)}, - .uart1_config1 = {.phys = CRONUS_ADDR(0x2A1808)}, - .uart1_config2 = {.phys = CRONUS_ADDR(0x2A180C)}, - .uart1_divisorhi = {.phys = CRONUS_ADDR(0x2A1810)}, - .uart1_divisorlo = {.phys = CRONUS_ADDR(0x2A1814)}, - .uart1_data = {.phys = CRONUS_ADDR(0x2A1818)}, - .uart1_status = {.phys = CRONUS_ADDR(0x2A181C)}, - - .int_stat_3 = {.phys = CRONUS_ADDR(0x2A2800)}, - .int_stat_2 = {.phys = CRONUS_ADDR(0x2A2804)}, - .int_stat_1 = {.phys = CRONUS_ADDR(0x2A2808)}, - .int_stat_0 = {.phys = CRONUS_ADDR(0x2A280C)}, - .int_config = {.phys = CRONUS_ADDR(0x2A2810)}, - .int_int_scan = {.phys = CRONUS_ADDR(0x2A2818)}, - .ien_int_3 = {.phys = CRONUS_ADDR(0x2A2830)}, - .ien_int_2 = {.phys = CRONUS_ADDR(0x2A2834)}, - .ien_int_1 = {.phys = CRONUS_ADDR(0x2A2838)}, - .ien_int_0 = {.phys = CRONUS_ADDR(0x2A283C)}, - .int_level_3_3 = {.phys = CRONUS_ADDR(0x2A2880)}, - .int_level_3_2 = {.phys = CRONUS_ADDR(0x2A2884)}, - .int_level_3_1 = {.phys = CRONUS_ADDR(0x2A2888)}, - .int_level_3_0 = {.phys = CRONUS_ADDR(0x2A288C)}, - .int_level_2_3 = {.phys = CRONUS_ADDR(0x2A2890)}, - .int_level_2_2 = {.phys = CRONUS_ADDR(0x2A2894)}, - .int_level_2_1 = {.phys = CRONUS_ADDR(0x2A2898)}, - .int_level_2_0 = {.phys = CRONUS_ADDR(0x2A289C)}, - .int_level_1_3 = {.phys = CRONUS_ADDR(0x2A28A0)}, - .int_level_1_2 = {.phys = CRONUS_ADDR(0x2A28A4)}, - .int_level_1_1 = {.phys = CRONUS_ADDR(0x2A28A8)}, - .int_level_1_0 = {.phys = CRONUS_ADDR(0x2A28AC)}, - .int_level_0_3 = {.phys = CRONUS_ADDR(0x2A28B0)}, - .int_level_0_2 = {.phys = CRONUS_ADDR(0x2A28B4)}, - .int_level_0_1 = {.phys = CRONUS_ADDR(0x2A28B8)}, - .int_level_0_0 = {.phys = CRONUS_ADDR(0x2A28BC)}, - .int_docsis_en = {.phys = CRONUS_ADDR(0x2A28F4)}, - - .mips_pll_setup = {.phys = CRONUS_ADDR(0x1C0000)}, - .fs432x4b4_usb_ctl = {.phys = CRONUS_ADDR(0x1C0028)}, - .test_bus = {.phys = CRONUS_ADDR(0x1C00CC)}, - .crt_spare = {.phys = CRONUS_ADDR(0x1c00d4)}, - .usb2_ohci_int_mask = {.phys = CRONUS_ADDR(0x20000C)}, - .usb2_strap = {.phys = CRONUS_ADDR(0x200014)}, - .ehci_hcapbase = {.phys = CRONUS_ADDR(0x21FE00)}, - .ohci_hc_revision = {.phys = CRONUS_ADDR(0x21fc00)}, - .bcm1_bs_lmi_steer = {.phys = CRONUS_ADDR(0x2E0008)}, - .usb2_control = {.phys = CRONUS_ADDR(0x2E004C)}, - .usb2_stbus_obc = {.phys = CRONUS_ADDR(0x21FF00)}, - .usb2_stbus_mess_size = {.phys = CRONUS_ADDR(0x21FF04)}, - .usb2_stbus_chunk_size = {.phys = CRONUS_ADDR(0x21FF08)}, - - .pcie_regs = {.phys = CRONUS_ADDR(0x220000)}, - .tim_ch = {.phys = CRONUS_ADDR(0x2A2C10)}, - .tim_cl = {.phys = CRONUS_ADDR(0x2A2C14)}, - .gpio_dout = {.phys = CRONUS_ADDR(0x2A2C20)}, - .gpio_din = {.phys = CRONUS_ADDR(0x2A2C24)}, - .gpio_dir = {.phys = CRONUS_ADDR(0x2A2C2C)}, - .watchdog = {.phys = CRONUS_ADDR(0x2A2C30)}, - .front_panel = {.phys = CRONUS_ADDR(0x2A3800)}, -}; diff --git a/arch/mips/powertv/asic/asic-gaia.c b/arch/mips/powertv/asic/asic-gaia.c deleted file mode 100644 index 1265b49012e6..000000000000 --- a/arch/mips/powertv/asic/asic-gaia.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Locations of devices in the Gaia ASIC - * - * Copyright (C) 2005-2009 Scientific-Atlanta, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that 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, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Author: David VomLehn - */ - -#include <linux/init.h> -#include <asm/mach-powertv/asic.h> - -const struct register_map gaia_register_map __initconst = { - .eic_slow0_strt_add = {.phys = GAIA_IO_BASE + 0x000000}, - .eic_cfg_bits = {.phys = GAIA_IO_BASE + 0x000038}, - .eic_ready_status = {.phys = GAIA_IO_BASE + 0x00004C}, - - .chipver3 = {.phys = GAIA_IO_BASE + 0x2A0800}, - .chipver2 = {.phys = GAIA_IO_BASE + 0x2A0804}, - .chipver1 = {.phys = GAIA_IO_BASE + 0x2A0808}, - .chipver0 = {.phys = GAIA_IO_BASE + 0x2A080C}, - - /* The registers of IRBlaster */ - .uart1_intstat = {.phys = GAIA_IO_BASE + 0x2A1800}, - .uart1_inten = {.phys = GAIA_IO_BASE + 0x2A1804}, - .uart1_config1 = {.phys = GAIA_IO_BASE + 0x2A1808}, - .uart1_config2 = {.phys = GAIA_IO_BASE + 0x2A180C}, - .uart1_divisorhi = {.phys = GAIA_IO_BASE + 0x2A1810}, - .uart1_divisorlo = {.phys = GAIA_IO_BASE + 0x2A1814}, - .uart1_data = {.phys = GAIA_IO_BASE + 0x2A1818}, - .uart1_status = {.phys = GAIA_IO_BASE + 0x2A181C}, - - .int_stat_3 = {.phys = GAIA_IO_BASE + 0x2A2800}, - .int_stat_2 = {.phys = GAIA_IO_BASE + 0x2A2804}, - .int_stat_1 = {.phys = GAIA_IO_BASE + 0x2A2808}, - .int_stat_0 = {.phys = GAIA_IO_BASE + 0x2A280C}, - .int_config = {.phys = GAIA_IO_BASE + 0x2A2810}, - .int_int_scan = {.phys = GAIA_IO_BASE + 0x2A2818}, - .ien_int_3 = {.phys = GAIA_IO_BASE + 0x2A2830}, - .ien_int_2 = {.phys = GAIA_IO_BASE + 0x2A2834}, - .ien_int_1 = {.phys = GAIA_IO_BASE + 0x2A2838}, - .ien_int_0 = {.phys = GAIA_IO_BASE + 0x2A283C}, - .int_level_3_3 = {.phys = GAIA_IO_BASE + 0x2A2880}, - .int_level_3_2 = {.phys = GAIA_IO_BASE + 0x2A2884}, - .int_level_3_1 = {.phys = GAIA_IO_BASE + 0x2A2888}, - .int_level_3_0 = {.phys = GAIA_IO_BASE + 0x2A288C}, - .int_level_2_3 = {.phys = GAIA_IO_BASE + 0x2A2890}, - .int_level_2_2 = {.phys = GAIA_IO_BASE + 0x2A2894}, - .int_level_2_1 = {.phys = GAIA_IO_BASE + 0x2A2898}, - .int_level_2_0 = {.phys = GAIA_IO_BASE + 0x2A289C}, - .int_level_1_3 = {.phys = GAIA_IO_BASE + 0x2A28A0}, - .int_level_1_2 = {.phys = GAIA_IO_BASE + 0x2A28A4}, - .int_level_1_1 = {.phys = GAIA_IO_BASE + 0x2A28A8}, - .int_level_1_0 = {.phys = GAIA_IO_BASE + 0x2A28AC}, - .int_level_0_3 = {.phys = GAIA_IO_BASE + 0x2A28B0}, - .int_level_0_2 = {.phys = GAIA_IO_BASE + 0x2A28B4}, - .int_level_0_1 = {.phys = GAIA_IO_BASE + 0x2A28B8}, - .int_level_0_0 = {.phys = GAIA_IO_BASE + 0x2A28BC}, - .int_docsis_en = {.phys = GAIA_IO_BASE + 0x2A28F4}, - - .mips_pll_setup = {.phys = GAIA_IO_BASE + 0x1C0000}, - .fs432x4b4_usb_ctl = {.phys = GAIA_IO_BASE + 0x1C0024}, - .test_bus = {.phys = GAIA_IO_BASE + 0x1C00CC}, - .crt_spare = {.phys = GAIA_IO_BASE + 0x1c0108}, - .usb2_ohci_int_mask = {.phys = GAIA_IO_BASE + 0x20000C}, - .usb2_strap = {.phys = GAIA_IO_BASE + 0x200014}, - .ehci_hcapbase = {.phys = GAIA_IO_BASE + 0x21FE00}, - .ohci_hc_revision = {.phys = GAIA_IO_BASE + 0x21fc00}, - .bcm1_bs_lmi_steer = {.phys = GAIA_IO_BASE + 0x2E0004}, - .usb2_control = {.phys = GAIA_IO_BASE + 0x2E004C}, - .usb2_stbus_obc = {.phys = GAIA_IO_BASE + 0x21FF00}, - .usb2_stbus_mess_size = {.phys = GAIA_IO_BASE + 0x21FF04}, - .usb2_stbus_chunk_size = {.phys = GAIA_IO_BASE + 0x21FF08}, - - .pcie_regs = {.phys = GAIA_IO_BASE + 0x220000}, - .tim_ch = {.phys = GAIA_IO_BASE + 0x2A2C10}, - .tim_cl = {.phys = GAIA_IO_BASE + 0x2A2C14}, - .gpio_dout = {.phys = GAIA_IO_BASE + 0x2A2C20}, - .gpio_din = {.phys = GAIA_IO_BASE + 0x2A2C24}, - .gpio_dir = {.phys = GAIA_IO_BASE + 0x2A2C2C}, - .watchdog = {.phys = GAIA_IO_BASE + 0x2A2C30}, - .front_panel = {.phys = GAIA_IO_BASE + 0x2A3800}, -}; diff --git a/arch/mips/powertv/asic/asic-zeus.c b/arch/mips/powertv/asic/asic-zeus.c deleted file mode 100644 index 14e7de137e03..000000000000 --- a/arch/mips/powertv/asic/asic-zeus.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Locations of devices in the Zeus ASIC - * - * Copyright (C) 2005-2009 Scientific-Atlanta, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that 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, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Author: Ken Eppinett - * David Schleef <ds@schleef.org> - * - * Description: Defines the platform resources for the SA settop. - */ - -#include <linux/init.h> -#include <asm/mach-powertv/asic.h> - -#define ZEUS_ADDR(x) (ZEUS_IO_BASE + (x)) - -const struct register_map zeus_register_map __initconst = { - .eic_slow0_strt_add = {.phys = ZEUS_ADDR(0x000000)}, - .eic_cfg_bits = {.phys = ZEUS_ADDR(0x000038)}, - .eic_ready_status = {.phys = ZEUS_ADDR(0x00004c)}, - - .chipver3 = {.phys = ZEUS_ADDR(0x280800)}, - .chipver2 = {.phys = ZEUS_ADDR(0x280804)}, - .chipver1 = {.phys = ZEUS_ADDR(0x280808)}, - .chipver0 = {.phys = ZEUS_ADDR(0x28080c)}, - - /* The registers of IRBlaster */ - .uart1_intstat = {.phys = ZEUS_ADDR(0x281800)}, - .uart1_inten = {.phys = ZEUS_ADDR(0x281804)}, - .uart1_config1 = {.phys = ZEUS_ADDR(0x281808)}, - .uart1_config2 = {.phys = ZEUS_ADDR(0x28180C)}, - .uart1_divisorhi = {.phys = ZEUS_ADDR(0x281810)}, - .uart1_divisorlo = {.phys = ZEUS_ADDR(0x281814)}, - .uart1_data = {.phys = ZEUS_ADDR(0x281818)}, - .uart1_status = {.phys = ZEUS_ADDR(0x28181C)}, - - .int_stat_3 = {.phys = ZEUS_ADDR(0x282800)}, - .int_stat_2 = {.phys = ZEUS_ADDR(0x282804)}, - .int_stat_1 = {.phys = ZEUS_ADDR(0x282808)}, - .int_stat_0 = {.phys = ZEUS_ADDR(0x28280c)}, - .int_config = {.phys = ZEUS_ADDR(0x282810)}, - .int_int_scan = {.phys = ZEUS_ADDR(0x282818)}, - .ien_int_3 = {.phys = ZEUS_ADDR(0x282830)}, - .ien_int_2 = {.phys = ZEUS_ADDR(0x282834)}, - .ien_int_1 = {.phys = ZEUS_ADDR(0x282838)}, - .ien_int_0 = {.phys = ZEUS_ADDR(0x28283c)}, - .int_level_3_3 = {.phys = ZEUS_ADDR(0x282880)}, - .int_level_3_2 = {.phys = ZEUS_ADDR(0x282884)}, - .int_level_3_1 = {.phys = ZEUS_ADDR(0x282888)}, - .int_level_3_0 = {.phys = ZEUS_ADDR(0x28288c)}, - .int_level_2_3 = {.phys = ZEUS_ADDR(0x282890)}, - .int_level_2_2 = {.phys = ZEUS_ADDR(0x282894)}, - .int_level_2_1 = {.phys = ZEUS_ADDR(0x282898)}, - .int_level_2_0 = {.phys = ZEUS_ADDR(0x28289c)}, - .int_level_1_3 = {.phys = ZEUS_ADDR(0x2828a0)}, - .int_level_1_2 = {.phys = ZEUS_ADDR(0x2828a4)}, - .int_level_1_1 = {.phys = ZEUS_ADDR(0x2828a8)}, - .int_level_1_0 = {.phys = ZEUS_ADDR(0x2828ac)}, - .int_level_0_3 = {.phys = ZEUS_ADDR(0x2828b0)}, - .int_level_0_2 = {.phys = ZEUS_ADDR(0x2828b4)}, - .int_level_0_1 = {.phys = ZEUS_ADDR(0x2828b8)}, - .int_level_0_0 = {.phys = ZEUS_ADDR(0x2828bc)}, - .int_docsis_en = {.phys = ZEUS_ADDR(0x2828F4)}, - - .mips_pll_setup = {.phys = ZEUS_ADDR(0x1a0000)}, - .fs432x4b4_usb_ctl = {.phys = ZEUS_ADDR(0x1a0018)}, - .test_bus = {.phys = ZEUS_ADDR(0x1a0238)}, - .crt_spare = {.phys = ZEUS_ADDR(0x1a0090)}, - .usb2_ohci_int_mask = {.phys = ZEUS_ADDR(0x1e000c)}, - .usb2_strap = {.phys = ZEUS_ADDR(0x1e0014)}, - .ehci_hcapbase = {.phys = ZEUS_ADDR(0x1FFE00)}, - .ohci_hc_revision = {.phys = ZEUS_ADDR(0x1FFC00)}, - .bcm1_bs_lmi_steer = {.phys = ZEUS_ADDR(0x2C0008)}, - .usb2_control = {.phys = ZEUS_ADDR(0x2c01a0)}, - .usb2_stbus_obc = {.phys = ZEUS_ADDR(0x1FFF00)}, - .usb2_stbus_mess_size = {.phys = ZEUS_ADDR(0x1FFF04)}, - .usb2_stbus_chunk_size = {.phys = ZEUS_ADDR(0x1FFF08)}, - - .pcie_regs = {.phys = ZEUS_ADDR(0x200000)}, - .tim_ch = {.phys = ZEUS_ADDR(0x282C10)}, - .tim_cl = {.phys = ZEUS_ADDR(0x282C14)}, - .gpio_dout = {.phys = ZEUS_ADDR(0x282c20)}, - .gpio_din = {.phys = ZEUS_ADDR(0x282c24)}, - .gpio_dir = {.phys = ZEUS_ADDR(0x282c2C)}, - .watchdog = {.phys = ZEUS_ADDR(0x282c30)}, - .front_panel = {.phys = ZEUS_ADDR(0x283800)}, -}; diff --git a/arch/mips/powertv/asic/asic_devices.c b/arch/mips/powertv/asic/asic_devices.c deleted file mode 100644 index 8380605d597d..000000000000 --- a/arch/mips/powertv/asic/asic_devices.c +++ /dev/null @@ -1,549 +0,0 @@ -/* - * - * Description: Defines the platform resources for Gaia-based settops. - * - * Copyright (C) 2005-2009 Scientific-Atlanta, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that 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, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * NOTE: The bootloader allocates persistent memory at an address which is - * 16 MiB below the end of the highest address in KSEG0. All fixed - * address memory reservations must avoid this region. - */ - -#include <linux/device.h> -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/resource.h> -#include <linux/serial_reg.h> -#include <linux/io.h> -#include <linux/bootmem.h> -#include <linux/mm.h> -#include <linux/platform_device.h> -#include <linux/module.h> -#include <asm/page.h> -#include <linux/swap.h> -#include <linux/highmem.h> -#include <linux/dma-mapping.h> - -#include <asm/mach-powertv/asic.h> -#include <asm/mach-powertv/asic_regs.h> -#include <asm/mach-powertv/interrupts.h> - -#ifdef CONFIG_BOOTLOADER_DRIVER -#include <asm/mach-powertv/kbldr.h> -#endif -#include <asm/bootinfo.h> - -#define BOOTLDRFAMILY(byte1, byte0) (((byte1) << 8) | (byte0)) - -/* - * Forward Prototypes - */ -static void pmem_setup_resource(void); - -/* - * Global Variables - */ -enum asic_type asic; - -unsigned int platform_features; -unsigned int platform_family; -struct register_map _asic_register_map; -EXPORT_SYMBOL(_asic_register_map); /* Exported for testing */ -unsigned long asic_phy_base; -unsigned long asic_base; -EXPORT_SYMBOL(asic_base); /* Exported for testing */ -struct resource *gp_resources; - -/* - * Don't recommend to use it directly, it is usually used by kernel internally. - * Portable code should be using interfaces such as ioremp, dma_map_single, etc. - */ -unsigned long phys_to_dma_offset; -EXPORT_SYMBOL(phys_to_dma_offset); - -/* - * - * IO Resource Definition - * - */ - -struct resource asic_resource = { - .name = "ASIC Resource", - .start = 0, - .end = ASIC_IO_SIZE, - .flags = IORESOURCE_MEM, -}; - -/* - * Allow override of bootloader-specified model - * Returns zero on success, a negative errno value on failure. This parameter - * allows overriding of the bootloader-specified model. - */ -static char __initdata cmdline[COMMAND_LINE_SIZE]; - -#define FORCEFAMILY_PARAM "forcefamily" - -/* - * check_forcefamily - check for, and parse, forcefamily command line parameter - * @forced_family: Pointer to two-character array in which to store the - * value of the forcedfamily parameter, if any. - */ -static __init int check_forcefamily(unsigned char forced_family[2]) -{ - const char *p; - - forced_family[0] = '\0'; - forced_family[1] = '\0'; - - /* Check the command line for a forcefamily directive */ - strncpy(cmdline, arcs_cmdline, COMMAND_LINE_SIZE - 1); - p = strstr(cmdline, FORCEFAMILY_PARAM); - if (p && (p != cmdline) && (*(p - 1) != ' ')) - p = strstr(p, " " FORCEFAMILY_PARAM "="); - - if (p) { - p += strlen(FORCEFAMILY_PARAM "="); - - if (*p == '\0' || *(p + 1) == '\0' || - (*(p + 2) != '\0' && *(p + 2) != ' ')) - pr_err(FORCEFAMILY_PARAM " must be exactly two " - "characters long, ignoring value\n"); - - else { - forced_family[0] = *p; - forced_family[1] = *(p + 1); - } - } - - return 0; -} - -/* - * platform_set_family - determine major platform family type. - * - * Returns family type; -1 if none - * Returns the family type; -1 if none - * - */ -static __init noinline void platform_set_family(void) -{ - unsigned char forced_family[2]; - unsigned short bootldr_family; - - if (check_forcefamily(forced_family) == 0) - bootldr_family = BOOTLDRFAMILY(forced_family[0], - forced_family[1]); - else - bootldr_family = (unsigned short) BOOTLDRFAMILY( - CONFIG_BOOTLOADER_FAMILY[0], - CONFIG_BOOTLOADER_FAMILY[1]); - - pr_info("Bootloader Family = 0x%04X\n", bootldr_family); - - switch (bootldr_family) { - case BOOTLDRFAMILY('R', '1'): - platform_family = FAMILY_1500; - break; - case BOOTLDRFAMILY('4', '4'): - platform_family = FAMILY_4500; - break; - case BOOTLDRFAMILY('4', '6'): - platform_family = FAMILY_4600; - break; - case BOOTLDRFAMILY('A', '1'): - platform_family = FAMILY_4600VZA; - break; - case BOOTLDRFAMILY('8', '5'): - platform_family = FAMILY_8500; - break; - case BOOTLDRFAMILY('R', '2'): - platform_family = FAMILY_8500RNG; - break; - case BOOTLDRFAMILY('8', '6'): - platform_family = FAMILY_8600; - break; - case BOOTLDRFAMILY('B', '1'): - platform_family = FAMILY_8600VZB; - break; - case BOOTLDRFAMILY('E', '1'): - platform_family = FAMILY_1500VZE; - break; - case BOOTLDRFAMILY('F', '1'): - platform_family = FAMILY_1500VZF; - break; - case BOOTLDRFAMILY('8', '7'): - platform_family = FAMILY_8700; - break; - default: - platform_family = -1; - } -} - -unsigned int platform_get_family(void) -{ - return platform_family; -} -EXPORT_SYMBOL(platform_get_family); - -/* - * platform_get_asic - determine the ASIC type. - * - * Returns the ASIC type, or ASIC_UNKNOWN if unknown - * - */ -enum asic_type platform_get_asic(void) -{ - return asic; -} -EXPORT_SYMBOL(platform_get_asic); - -/* - * set_register_map - set ASIC register configuration - * @phys_base: Physical address of the base of the ASIC registers - * @map: Description of key ASIC registers - */ -static void __init set_register_map(unsigned long phys_base, - const struct register_map *map) -{ - asic_phy_base = phys_base; - _asic_register_map = *map; - register_map_virtualize(&_asic_register_map); - asic_base = (unsigned long)ioremap_nocache(phys_base, ASIC_IO_SIZE); -} - -/** - * configure_platform - configuration based on platform type. - */ -void __init configure_platform(void) -{ - platform_set_family(); - - switch (platform_family) { - case FAMILY_1500: - case FAMILY_1500VZE: - case FAMILY_1500VZF: - platform_features = FFS_CAPABLE; - asic = ASIC_CALLIOPE; - set_register_map(CALLIOPE_IO_BASE, &calliope_register_map); - - if (platform_family == FAMILY_1500VZE) { - gp_resources = non_dvr_vze_calliope_resources; - pr_info("Platform: 1500/Vz Class E - " - "CALLIOPE, NON_DVR_CAPABLE\n"); - } else if (platform_family == FAMILY_1500VZF) { - gp_resources = non_dvr_vzf_calliope_resources; - pr_info("Platform: 1500/Vz Class F - " - "CALLIOPE, NON_DVR_CAPABLE\n"); - } else { - gp_resources = non_dvr_calliope_resources; - pr_info("Platform: 1500/RNG100 - CALLIOPE, " - "NON_DVR_CAPABLE\n"); - } - break; - - case FAMILY_4500: - platform_features = FFS_CAPABLE | PCIE_CAPABLE | - DISPLAY_CAPABLE; - asic = ASIC_ZEUS; - set_register_map(ZEUS_IO_BASE, &zeus_register_map); - gp_resources = non_dvr_zeus_resources; - - pr_info("Platform: 4500 - ZEUS, NON_DVR_CAPABLE\n"); - break; - - case FAMILY_4600: - { - unsigned int chipversion = 0; - - /* The settop has PCIE but it isn't used, so don't advertise - * it*/ - platform_features = FFS_CAPABLE | DISPLAY_CAPABLE; - - /* Cronus and Cronus Lite have the same register map */ - set_register_map(CRONUS_IO_BASE, &cronus_register_map); - - /* ASIC version will determine if this is a real CronusLite or - * Castrati(Cronus) */ - chipversion = asic_read(chipver3) << 24; - chipversion |= asic_read(chipver2) << 16; - chipversion |= asic_read(chipver1) << 8; - chipversion |= asic_read(chipver0); - - if ((chipversion == CRONUS_10) || (chipversion == CRONUS_11)) - asic = ASIC_CRONUS; - else - asic = ASIC_CRONUSLITE; - - gp_resources = non_dvr_cronuslite_resources; - pr_info("Platform: 4600 - %s, NON_DVR_CAPABLE, " - "chipversion=0x%08X\n", - (asic == ASIC_CRONUS) ? "CRONUS" : "CRONUS LITE", - chipversion); - break; - } - case FAMILY_4600VZA: - platform_features = FFS_CAPABLE | DISPLAY_CAPABLE; - asic = ASIC_CRONUS; - set_register_map(CRONUS_IO_BASE, &cronus_register_map); - gp_resources = non_dvr_cronus_resources; - - pr_info("Platform: Vz Class A - CRONUS, NON_DVR_CAPABLE\n"); - break; - - case FAMILY_8500: - case FAMILY_8500RNG: - platform_features = DVR_CAPABLE | PCIE_CAPABLE | - DISPLAY_CAPABLE; - asic = ASIC_ZEUS; - set_register_map(ZEUS_IO_BASE, &zeus_register_map); - gp_resources = dvr_zeus_resources; - - pr_info("Platform: 8500/RNG200 - ZEUS, DVR_CAPABLE\n"); - break; - - case FAMILY_8600: - case FAMILY_8600VZB: - platform_features = DVR_CAPABLE | PCIE_CAPABLE | - DISPLAY_CAPABLE; - asic = ASIC_CRONUS; - set_register_map(CRONUS_IO_BASE, &cronus_register_map); - gp_resources = dvr_cronus_resources; - - pr_info("Platform: 8600/Vz Class B - CRONUS, " - "DVR_CAPABLE\n"); - break; - - case FAMILY_8700: - platform_features = FFS_CAPABLE | PCIE_CAPABLE; - asic = ASIC_GAIA; - set_register_map(GAIA_IO_BASE, &gaia_register_map); - gp_resources = dvr_gaia_resources; - - pr_info("Platform: 8700 - GAIA, DVR_CAPABLE\n"); - break; - - default: - pr_crit("Platform: UNKNOWN PLATFORM\n"); - break; - } - - switch (asic) { - case ASIC_ZEUS: - phys_to_dma_offset = 0x30000000; - break; - case ASIC_CALLIOPE: - phys_to_dma_offset = 0x10000000; - break; - case ASIC_CRONUSLITE: - /* Fall through */ - case ASIC_CRONUS: - /* - * TODO: We suppose 0x10000000 aliases into 0x20000000- - * 0x2XXXXXXX. If 0x10000000 aliases into 0x60000000- - * 0x6XXXXXXX, the offset should be 0x50000000, not 0x10000000. - */ - phys_to_dma_offset = 0x10000000; - break; - default: - phys_to_dma_offset = 0x00000000; - break; - } -} - -/* - * RESOURCE ALLOCATION - * - */ -/* - * Allocates/reserves the Platform memory resources early in the boot process. - * This ignores any resources that are designated IORESOURCE_IO - */ -void __init platform_alloc_bootmem(void) -{ - int i; - int total = 0; - - /* Get persistent memory data from command line before allocating - * resources. This need to happen before normal command line parsing - * has been done */ - pmem_setup_resource(); - - /* Loop through looking for resources that want a particular address */ - for (i = 0; gp_resources[i].flags != 0; i++) { - int size = resource_size(&gp_resources[i]); - if ((gp_resources[i].start != 0) && - ((gp_resources[i].flags & IORESOURCE_MEM) != 0)) { - reserve_bootmem(dma_to_phys(gp_resources[i].start), - size, 0); - total += resource_size(&gp_resources[i]); - pr_info("reserve resource %s at %08x (%u bytes)\n", - gp_resources[i].name, gp_resources[i].start, - resource_size(&gp_resources[i])); - } - } - - /* Loop through assigning addresses for those that are left */ - for (i = 0; gp_resources[i].flags != 0; i++) { - int size = resource_size(&gp_resources[i]); - if ((gp_resources[i].start == 0) && - ((gp_resources[i].flags & IORESOURCE_MEM) != 0)) { - void *mem = alloc_bootmem_pages(size); - - if (mem == NULL) - pr_err("Unable to allocate bootmem pages " - "for %s\n", gp_resources[i].name); - - else { - gp_resources[i].start = - phys_to_dma(virt_to_phys(mem)); - gp_resources[i].end = - gp_resources[i].start + size - 1; - total += size; - pr_info("allocate resource %s at %08x " - "(%u bytes)\n", - gp_resources[i].name, - gp_resources[i].start, size); - } - } - } - - pr_info("Total Platform driver memory allocation: 0x%08x\n", total); - - /* indicate resources that are platform I/O related */ - for (i = 0; gp_resources[i].flags != 0; i++) { - if ((gp_resources[i].start != 0) && - ((gp_resources[i].flags & IORESOURCE_IO) != 0)) { - pr_info("reserved platform resource %s at %08x\n", - gp_resources[i].name, gp_resources[i].start); - } - } -} - -/* - * - * PERSISTENT MEMORY (PMEM) CONFIGURATION - * - */ -static unsigned long pmemaddr __initdata; - -static int __init early_param_pmemaddr(char *p) -{ - pmemaddr = (unsigned long)simple_strtoul(p, NULL, 0); - return 0; -} -early_param("pmemaddr", early_param_pmemaddr); - -static long pmemlen __initdata; - -static int __init early_param_pmemlen(char *p) -{ -/* TODO: we can use this code when and if the bootloader ever changes this */ -#if 0 - pmemlen = (unsigned long)simple_strtoul(p, NULL, 0); -#else - pmemlen = 0x20000; -#endif - return 0; -} -early_param("pmemlen", early_param_pmemlen); - -/* - * Set up persistent memory. If we were given values, we patch the array of - * resources. Otherwise, persistent memory may be allocated anywhere at all. - */ -static void __init pmem_setup_resource(void) -{ - struct resource *resource; - resource = asic_resource_get("DiagPersistentMemory"); - - if (resource && pmemaddr && pmemlen) { - /* The address provided by bootloader is in kseg0. Convert to - * a bus address. */ - resource->start = phys_to_dma(pmemaddr - 0x80000000); - resource->end = resource->start + pmemlen - 1; - - pr_info("persistent memory: start=0x%x end=0x%x\n", - resource->start, resource->end); - } -} - -/* - * - * RESOURCE ACCESS FUNCTIONS - * - */ - -/** - * asic_resource_get - retrieves parameters for a platform resource. - * @name: string to match resource - * - * Returns a pointer to a struct resource corresponding to the given name. - * - * CANNOT BE NAMED platform_resource_get, which would be the obvious choice, - * as this function name is already declared - */ -struct resource *asic_resource_get(const char *name) -{ - int i; - - for (i = 0; gp_resources[i].flags != 0; i++) { - if (strcmp(gp_resources[i].name, name) == 0) - return &gp_resources[i]; - } - - return NULL; -} -EXPORT_SYMBOL(asic_resource_get); - -/** - * platform_release_memory - release pre-allocated memory - * @ptr: pointer to memory to release - * @size: size of resource - * - * This must only be called for memory allocated or reserved via the boot - * memory allocator. - */ -void platform_release_memory(void *ptr, int size) -{ - free_reserved_area(ptr, ptr + size, -1, NULL); -} -EXPORT_SYMBOL(platform_release_memory); - -/* - * - * FEATURE AVAILABILITY FUNCTIONS - * - */ -int platform_supports_dvr(void) -{ - return (platform_features & DVR_CAPABLE) != 0; -} - -int platform_supports_ffs(void) -{ - return (platform_features & FFS_CAPABLE) != 0; -} - -int platform_supports_pcie(void) -{ - return (platform_features & PCIE_CAPABLE) != 0; -} - -int platform_supports_display(void) -{ - return (platform_features & DISPLAY_CAPABLE) != 0; -} diff --git a/arch/mips/powertv/asic/asic_int.c b/arch/mips/powertv/asic/asic_int.c deleted file mode 100644 index f44cd9295cae..000000000000 --- a/arch/mips/powertv/asic/asic_int.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000, 2001, 2004 MIPS Technologies, Inc. - * Copyright (C) 2001 Ralf Baechle - * Portions copyright (C) 2009 Cisco Systems, Inc. - * - * This program is free software; you can distribute it and/or modify it - * under the terms 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, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * Routines for generic manipulation of the interrupts found on the PowerTV - * platform. - * - * The interrupt controller is located in the South Bridge a PIIX4 device - * with two internal 82C95 interrupt controllers. - */ -#include <linux/init.h> -#include <linux/irq.h> -#include <linux/sched.h> -#include <linux/interrupt.h> -#include <linux/kernel_stat.h> -#include <linux/kernel.h> -#include <linux/random.h> - -#include <asm/irq_cpu.h> -#include <linux/io.h> -#include <asm/irq_regs.h> -#include <asm/setup.h> -#include <asm/mips-boards/generic.h> - -#include <asm/mach-powertv/asic_regs.h> - -static DEFINE_RAW_SPINLOCK(asic_irq_lock); - -static inline int get_int(void) -{ - unsigned long flags; - int irq; - - raw_spin_lock_irqsave(&asic_irq_lock, flags); - - irq = (asic_read(int_int_scan) >> 4) - 1; - - if (irq == 0 || irq >= NR_IRQS) - irq = -1; - - raw_spin_unlock_irqrestore(&asic_irq_lock, flags); - - return irq; -} - -static void asic_irqdispatch(void) -{ - int irq; - - irq = get_int(); - if (irq < 0) - return; /* interrupt has already been cleared */ - - do_IRQ(irq); -} - -static inline int clz(unsigned long x) -{ - __asm__( - " .set push \n" - " .set mips32 \n" - " clz %0, %1 \n" - " .set pop \n" - : "=r" (x) - : "r" (x)); - - return x; -} - -/* - * Version of ffs that only looks at bits 12..15. - */ -static inline unsigned int irq_ffs(unsigned int pending) -{ - return fls(pending) - 1 + CAUSEB_IP; -} - -/* - * TODO: check how it works under EIC mode. - */ -asmlinkage void plat_irq_dispatch(void) -{ - unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; - int irq; - - irq = irq_ffs(pending); - - if (irq == CAUSEF_IP3) - asic_irqdispatch(); - else if (irq >= 0) - do_IRQ(irq); - else - spurious_interrupt(); -} - -void __init arch_init_irq(void) -{ - int i; - - asic_irq_init(); - - /* - * Initialize interrupt exception vectors. - */ - if (cpu_has_veic || cpu_has_vint) { - int nvec = cpu_has_veic ? 64 : 8; - for (i = 0; i < nvec; i++) - set_vi_handler(i, asic_irqdispatch); - } -} diff --git a/arch/mips/powertv/asic/irq_asic.c b/arch/mips/powertv/asic/irq_asic.c deleted file mode 100644 index 9344902dc586..000000000000 --- a/arch/mips/powertv/asic/irq_asic.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Portions copyright (C) 2005-2009 Scientific Atlanta - * Portions copyright (C) 2009 Cisco Systems, Inc. - * - * Modified from arch/mips/kernel/irq-rm7000.c: - * Copyright (C) 2003 Ralf Baechle - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/kernel.h> -#include <linux/irq.h> - -#include <asm/irq_cpu.h> -#include <asm/mipsregs.h> - -#include <asm/mach-powertv/asic_regs.h> - -static inline void unmask_asic_irq(struct irq_data *d) -{ - unsigned long enable_bit; - unsigned int irq = d->irq; - - enable_bit = (1 << (irq & 0x1f)); - - switch (irq >> 5) { - case 0: - asic_write(asic_read(ien_int_0) | enable_bit, ien_int_0); - break; - case 1: - asic_write(asic_read(ien_int_1) | enable_bit, ien_int_1); - break; - case 2: - asic_write(asic_read(ien_int_2) | enable_bit, ien_int_2); - break; - case 3: - asic_write(asic_read(ien_int_3) | enable_bit, ien_int_3); - break; - default: - BUG(); - } -} - -static inline void mask_asic_irq(struct irq_data *d) -{ - unsigned long disable_mask; - unsigned int irq = d->irq; - - disable_mask = ~(1 << (irq & 0x1f)); - - switch (irq >> 5) { - case 0: - asic_write(asic_read(ien_int_0) & disable_mask, ien_int_0); - break; - case 1: - asic_write(asic_read(ien_int_1) & disable_mask, ien_int_1); - break; - case 2: - asic_write(asic_read(ien_int_2) & disable_mask, ien_int_2); - break; - case 3: - asic_write(asic_read(ien_int_3) & disable_mask, ien_int_3); - break; - default: - BUG(); - } -} - -static struct irq_chip asic_irq_chip = { - .name = "ASIC Level", - .irq_mask = mask_asic_irq, - .irq_unmask = unmask_asic_irq, -}; - -void __init asic_irq_init(void) -{ - int i; - - /* set priority to 0 */ - write_c0_status(read_c0_status() & ~(0x0000fc00)); - - asic_write(0, ien_int_0); - asic_write(0, ien_int_1); - asic_write(0, ien_int_2); - asic_write(0, ien_int_3); - - asic_write(0x0fffffff, int_level_3_3); - asic_write(0xffffffff, int_level_3_2); - asic_write(0xffffffff, int_level_3_1); - asic_write(0xffffffff, int_level_3_0); - asic_write(0xffffffff, int_level_2_3); - asic_write(0xffffffff, int_level_2_2); - asic_write(0xffffffff, int_level_2_1); - asic_write(0xffffffff, int_level_2_0); - asic_write(0xffffffff, int_level_1_3); - asic_write(0xffffffff, int_level_1_2); - asic_write(0xffffffff, int_level_1_1); - asic_write(0xffffffff, int_level_1_0); - asic_write(0xffffffff, int_level_0_3); - asic_write(0xffffffff, int_level_0_2); - asic_write(0xffffffff, int_level_0_1); - asic_write(0xffffffff, int_level_0_0); - - asic_write(0xf, int_int_scan); - - /* - * Initialize interrupt handlers. - */ - for (i = 0; i < NR_IRQS; i++) - irq_set_chip_and_handler(i, &asic_irq_chip, handle_level_irq); -} diff --git a/arch/mips/powertv/asic/prealloc-calliope.c b/arch/mips/powertv/asic/prealloc-calliope.c deleted file mode 100644 index 98dc51650577..000000000000 --- a/arch/mips/powertv/asic/prealloc-calliope.c +++ /dev/null @@ -1,385 +0,0 @@ -/* - * Memory pre-allocations for Calliope boxes. - * - * Copyright (C) 2005-2009 Scientific-Atlanta, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that 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, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Author: Ken Eppinett - * David Schleef <ds@schleef.org> - */ - -#include <linux/init.h> -#include <linux/ioport.h> -#include <asm/mach-powertv/asic.h> -#include "prealloc.h" - -/* - * NON_DVR_CAPABLE CALLIOPE RESOURCES - */ -struct resource non_dvr_calliope_resources[] __initdata = -{ - /* - * VIDEO / LX1 - */ - /* Delta-Mu 1 image (2MiB) */ - PREALLOC_NORMAL("ST231aImage", 0x24000000, 0x24200000-1, - IORESOURCE_MEM) - /* Delta-Mu 1 monitor (8KiB) */ - PREALLOC_NORMAL("ST231aMonitor", 0x24200000, 0x24202000-1, - IORESOURCE_MEM) - /* Delta-Mu 1 RAM (~36.9MiB (32MiB - (2MiB + 8KiB))) */ - PREALLOC_NORMAL("MediaMemory1", 0x24202000, 0x26700000-1, - IORESOURCE_MEM) - - /* - * Sysaudio Driver - */ - /* DSP code and data images (1MiB) */ - PREALLOC_NORMAL("DSP_Image_Buff", 0x00000000, 0x00100000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - /* ADSC CPU PCM buffer (40KiB) */ - PREALLOC_NORMAL("ADSC_CPU_PCM_Buff", 0x00000000, 0x0000A000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - /* ADSC AUX buffer (128KiB) */ - PREALLOC_NORMAL("ADSC_AUX_Buff", 0x00000000, 0x00020000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - /* ADSC Main buffer (128KiB) */ - PREALLOC_NORMAL("ADSC_Main_Buff", 0x00000000, 0x00020000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * STAVEM driver/STAPI - */ - /* 6MiB */ - PREALLOC_NORMAL("AVMEMPartition0", 0x00000000, 0x00600000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * DOCSIS Subsystem - */ - /* 7MiB */ - PREALLOC_DOCSIS("Docsis", 0x27500000, 0x27c00000-1, IORESOURCE_MEM) - - /* - * GHW HAL Driver - */ - /* PowerTV Graphics Heap (14MiB) */ - PREALLOC_NORMAL("GraphicsHeap", 0x26700000, 0x26700000+(14*1048576)-1, - IORESOURCE_MEM) - - /* - * multi com buffer area - */ - /* 128KiB */ - PREALLOC_NORMAL("MulticomSHM", 0x23700000, 0x23720000-1, - IORESOURCE_MEM) - - /* - * DMA Ring buffer (don't need recording buffers) - */ - /* 680KiB */ - PREALLOC_NORMAL("BMM_Buffer", 0x00000000, 0x000AA000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * Display bins buffer for unit0 - */ - /* 4KiB */ - PREALLOC_NORMAL("DisplayBins0", 0x00000000, 0x00001000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * AVFS: player HAL memory - */ - /* 945K * 3 for playback */ - PREALLOC_NORMAL("AvfsDmaMem", 0x00000000, 0x002c4c00-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * PMEM - */ - /* Persistent memory for diagnostics (64KiB) */ - PREALLOC_PMEM("DiagPersistentMemory", 0x00000000, 0x10000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * Smartcard - */ - /* Read and write buffers for Internal/External cards (10KiB) */ - PREALLOC_NORMAL("SmartCardInfo", 0x00000000, 0x2800-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * NAND Flash - */ - /* 10KiB */ - PREALLOC_NORMAL("NandFlash", NAND_FLASH_BASE, NAND_FLASH_BASE+0x400-1, - IORESOURCE_MEM) - - /* - * Synopsys GMAC Memory Region - */ - /* 64KiB */ - PREALLOC_NORMAL("GMAC", 0x00000000, 0x00010000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * TFTPBuffer - * - * This buffer is used in some minimal configurations (e.g. two-way - * loader) for storing software images - */ - PREALLOC_TFTP("TFTPBuffer", 0x00000000, MEBIBYTE(80)-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * Add other resources here - */ - - /* - * End of Resource marker - */ - { - .flags = 0, - }, -}; - - -struct resource non_dvr_vze_calliope_resources[] __initdata = -{ - /* - * VIDEO / LX1 - */ - /* Delta-Mu 1 image (2MiB) */ - PREALLOC_NORMAL("ST231aImage", 0x22000000, 0x22200000-1, - IORESOURCE_MEM) - /* Delta-Mu 1 monitor (8KiB) */ - PREALLOC_NORMAL("ST231aMonitor", 0x22200000, 0x22202000-1, - IORESOURCE_MEM) - /* Delta-Mu 1 RAM (10.12MiB) */ - PREALLOC_NORMAL("MediaMemory1", 0x22202000, 0x22C20B85-1, - IORESOURCE_MEM) - - /* - * Sysaudio Driver - */ - /* DSP code and data images (1MiB) */ - PREALLOC_NORMAL("DSP_Image_Buff", 0x00000000, 0x00100000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - /* ADSC CPU PCM buffer (40KiB) */ - PREALLOC_NORMAL("ADSC_CPU_PCM_Buff", 0x00000000, 0x0000A000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - /* ADSC AUX buffer (16KiB) */ - PREALLOC_NORMAL("ADSC_AUX_Buff", 0x00000000, 0x00004000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - /* ADSC Main buffer (16KiB) */ - PREALLOC_NORMAL("ADSC_Main_Buff", 0x00000000, 0x00004000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * STAVEM driver/STAPI - */ - /* 3.125MiB */ - PREALLOC_NORMAL("AVMEMPartition0", 0x20396000, 0x206B6000-1, - IORESOURCE_MEM) - - /* - * GHW HAL Driver - */ - /* PowerTV Graphics Heap (2.59MiB) */ - PREALLOC_NORMAL("GraphicsHeap", 0x20100000, 0x20396000-1, - IORESOURCE_MEM) - - /* - * multi com buffer area - */ - /* 128KiB */ - PREALLOC_NORMAL("MulticomSHM", 0x206B6000, 0x206D6000-1, - IORESOURCE_MEM) - - /* - * DMA Ring buffer (don't need recording buffers) - */ - /* 680KiB */ - PREALLOC_NORMAL("BMM_Buffer", 0x00000000, 0x000AA000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * Display bins buffer for unit0 - */ - /* 4KiB */ - PREALLOC_NORMAL("DisplayBins0", 0x00000000, 0x00001000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * PMEM - */ - /* Persistent memory for diagnostics (64KiB) */ - PREALLOC_PMEM("DiagPersistentMemory", 0x00000000, 0x10000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * Smartcard - */ - /* Read and write buffers for Internal/External cards (10KiB) */ - PREALLOC_NORMAL("SmartCardInfo", 0x00000000, 0x2800-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * NAND Flash - */ - /* 10KiB */ - PREALLOC_NORMAL("NandFlash", NAND_FLASH_BASE, NAND_FLASH_BASE+0x400-1, - IORESOURCE_MEM) - - /* - * Synopsys GMAC Memory Region - */ - /* 64KiB */ - PREALLOC_NORMAL("GMAC", 0x00000000, 0x00010000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * Add other resources here - */ - - /* - * End of Resource marker - */ - { - .flags = 0, - }, -}; - -struct resource non_dvr_vzf_calliope_resources[] __initdata = -{ - /* - * VIDEO / LX1 - */ - /* Delta-Mu 1 image (2MiB) */ - PREALLOC_NORMAL("ST231aImage", 0x24000000, 0x24200000-1, - IORESOURCE_MEM) - /* Delta-Mu 1 monitor (8KiB) */ - PREALLOC_NORMAL("ST231aMonitor", 0x24200000, 0x24202000-1, - IORESOURCE_MEM) - /* Delta-Mu 1 RAM (~19.4 (21.5MiB - (2MiB + 8KiB))) */ - PREALLOC_NORMAL("MediaMemory1", 0x24202000, 0x25580000-1, - IORESOURCE_MEM) - - /* - * Sysaudio Driver - */ - /* DSP code and data images (1MiB) */ - PREALLOC_NORMAL("DSP_Image_Buff", 0x00000000, 0x00100000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - /* ADSC CPU PCM buffer (40KiB) */ - PREALLOC_NORMAL("ADSC_CPU_PCM_Buff", 0x00000000, 0x0000A000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - /* ADSC AUX buffer (128KiB) */ - PREALLOC_NORMAL("ADSC_AUX_Buff", 0x00000000, 0x00020000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - /* ADSC Main buffer (128KiB) */ - PREALLOC_NORMAL("ADSC_Main_Buff", 0x00000000, 0x00020000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * STAVEM driver/STAPI - */ - /* 4.5MiB */ - PREALLOC_NORMAL("AVMEMPartition0", 0x00000000, 0x00480000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * GHW HAL Driver - */ - /* PowerTV Graphics Heap (14MiB) */ - PREALLOC_NORMAL("GraphicsHeap", 0x25600000, 0x25600000+(14*1048576)-1, - IORESOURCE_MEM) - - /* - * multi com buffer area - */ - /* 128KiB */ - PREALLOC_NORMAL("MulticomSHM", 0x23700000, 0x23720000-1, - IORESOURCE_MEM) - - /* - * DMA Ring buffer (don't need recording buffers) - */ - /* 680KiB */ - PREALLOC_NORMAL("BMM_Buffer", 0x00000000, 0x000AA000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * Display bins buffer for unit0 - */ - /* 4KiB */ - PREALLOC_NORMAL("DisplayBins0", 0x00000000, 0x00001000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * Display bins buffer for unit1 - */ - /* 4KiB */ - PREALLOC_NORMAL("DisplayBins1", 0x00000000, 0x00001000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * AVFS: player HAL memory - */ - /* 945K * 3 for playback */ - PREALLOC_NORMAL("AvfsDmaMem", 0x00000000, 0x002c4c00-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * PMEM - */ - /* Persistent memory for diagnostics (64KiB) */ - PREALLOC_PMEM("DiagPersistentMemory", 0x00000000, 0x10000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * Smartcard - */ - /* Read and write buffers for Internal/External cards (10KiB) */ - PREALLOC_NORMAL("SmartCardInfo", 0x00000000, 0x2800-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * NAND Flash - */ - /* 10KiB */ - PREALLOC_NORMAL("NandFlash", NAND_FLASH_BASE, NAND_FLASH_BASE+0x400-1, - IORESOURCE_MEM) - - /* - * Synopsys GMAC Memory Region - */ - /* 64KiB */ - PREALLOC_NORMAL("GMAC", 0x00000000, 0x00010000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * Add other resources here - */ - - /* - * End of Resource marker - */ - { - .flags = 0, - }, -}; diff --git a/arch/mips/powertv/asic/prealloc-cronus.c b/arch/mips/powertv/asic/prealloc-cronus.c deleted file mode 100644 index 7c6ce7596935..000000000000 --- a/arch/mips/powertv/asic/prealloc-cronus.c +++ /dev/null @@ -1,340 +0,0 @@ -/* - * Memory pre-allocations for Cronus boxes. - * - * Copyright (C) 2005-2009 Scientific-Atlanta, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that 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, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Author: Ken Eppinett - * David Schleef <ds@schleef.org> - */ - -#include <linux/init.h> -#include <linux/ioport.h> -#include <asm/mach-powertv/asic.h> -#include "prealloc.h" - -/* - * DVR_CAPABLE CRONUS RESOURCES - */ -struct resource dvr_cronus_resources[] __initdata = -{ - /* - * VIDEO1 / LX1 - */ - /* Delta-Mu 1 image (2MiB) */ - PREALLOC_NORMAL("ST231aImage", 0x24000000, 0x24200000-1, - IORESOURCE_MEM) - /* Delta-Mu 1 monitor (8KiB) */ - PREALLOC_NORMAL("ST231aMonitor", 0x24200000, 0x24202000-1, - IORESOURCE_MEM) - /* Delta-Mu 1 RAM (~29.9MiB (32MiB - (2MiB + 8KiB))) */ - PREALLOC_NORMAL("MediaMemory1", 0x24202000, 0x26000000-1, - IORESOURCE_MEM) - - /* - * VIDEO2 / LX2 - */ - /* Delta-Mu 2 image (2MiB) */ - PREALLOC_NORMAL("ST231bImage", 0x60000000, 0x60200000-1, - IORESOURCE_MEM) - /* Delta-Mu 2 monitor (8KiB) */ - PREALLOC_NORMAL("ST231bMonitor", 0x60200000, 0x60202000-1, - IORESOURCE_MEM) - /* Delta-Mu 2 RAM (~29.9MiB (32MiB - (2MiB + 8KiB))) */ - PREALLOC_NORMAL("MediaMemory2", 0x60202000, 0x62000000-1, - IORESOURCE_MEM) - - /* - * Sysaudio Driver - */ - /* DSP code and data images (1MiB) */ - PREALLOC_NORMAL("DSP_Image_Buff", 0x00000000, 0x00100000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - /* ADSC CPU PCM buffer (40KiB) */ - PREALLOC_NORMAL("ADSC_CPU_PCM_Buff", 0x00000000, 0x0000A000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - /* ADSC AUX buffer (128KiB) */ - PREALLOC_NORMAL("ADSC_AUX_Buff", 0x00000000, 0x00020000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - /* ADSC Main buffer (128KiB) */ - PREALLOC_NORMAL("ADSC_Main_Buff", 0x00000000, 0x00020000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * STAVEM driver/STAPI - * - * This memory area is used for allocating buffers for Video decoding - * purposes. Allocation/De-allocation within this buffer is managed - * by the STAVMEM driver of the STAPI. They could be Decimated - * Picture Buffers, Intermediate Buffers, as deemed necessary for - * video decoding purposes, for any video decoders on Zeus. - */ - /* 12MiB */ - PREALLOC_NORMAL("AVMEMPartition0", 0x00000000, 0x00c00000-1, - IORESOURCE_MEM) - - /* - * DOCSIS Subsystem - */ - /* 7MiB */ - PREALLOC_DOCSIS("Docsis", 0x67500000, 0x67c00000-1, IORESOURCE_MEM) - - /* - * GHW HAL Driver - */ - /* PowerTV Graphics Heap (14MiB) */ - PREALLOC_NORMAL("GraphicsHeap", 0x62700000, 0x63500000-1, - IORESOURCE_MEM) - - /* - * multi com buffer area - */ - /* 128KiB */ - PREALLOC_NORMAL("MulticomSHM", 0x26000000, 0x26020000-1, - IORESOURCE_MEM) - - /* - * DMA Ring buffer - */ - PREALLOC_NORMAL("BMM_Buffer", 0x00000000, 0x002EA000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * Display bins buffer for unit0 - */ - /* 4KiB */ - PREALLOC_NORMAL("DisplayBins0", 0x00000000, 0x00001000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * Display bins buffer for unit1 - */ - /* 4KiB */ - PREALLOC_NORMAL("DisplayBins1", 0x00000000, 0x00001000-1, - IORESOURCE_MEM) - - /* - * ITFS - */ - /* 815,104 bytes each for 2 ITFS partitions. */ - PREALLOC_NORMAL("ITFS", 0x00000000, 0x0018E000-1, IORESOURCE_MEM) - - /* - * AVFS - */ - /* (945K * 8) = (128K * 3) 5 playbacks / 3 server */ - PREALLOC_NORMAL("AvfsDmaMem", 0x00000000, 0x007c2000-1, - IORESOURCE_MEM) - - /* 4KiB */ - PREALLOC_NORMAL("AvfsFileSys", 0x00000000, 0x00001000-1, - IORESOURCE_MEM) - - /* - * PMEM - */ - /* Persistent memory for diagnostics (64KiB) */ - PREALLOC_PMEM("DiagPersistentMemory", 0x00000000, 0x10000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * Smartcard - */ - /* Read and write buffers for Internal/External cards (10KiB) */ - PREALLOC_NORMAL("SmartCardInfo", 0x00000000, 0x2800-1, - IORESOURCE_MEM) - - /* - * KAVNET - */ - /* NP Reset Vector - must be of the form xxCxxxxx (4KiB) */ - PREALLOC_NORMAL("NP_Reset_Vector", 0x27c00000, 0x27c01000-1, - IORESOURCE_MEM) - /* NP Image - must be video bank 1 (320KiB) */ - PREALLOC_NORMAL("NP_Image", 0x27020000, 0x27070000-1, IORESOURCE_MEM) - /* NP IPC - must be video bank 2 (512KiB) */ - PREALLOC_NORMAL("NP_IPC", 0x63500000, 0x63580000-1, IORESOURCE_MEM) - - /* - * TFTPBuffer - * - * This buffer is used in some minimal configurations (e.g. two-way - * loader) for storing software images - */ - PREALLOC_TFTP("TFTPBuffer", 0x00000000, MEBIBYTE(80)-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * Add other resources here - */ - - /* - * End of Resource marker - */ - { - .flags = 0, - }, -}; - -/* - * NON_DVR_CAPABLE CRONUS RESOURCES - */ -struct resource non_dvr_cronus_resources[] __initdata = -{ - /* - * VIDEO1 / LX1 - */ - /* Delta-Mu 1 image (2MiB) */ - PREALLOC_NORMAL("ST231aImage", 0x24000000, 0x24200000-1, - IORESOURCE_MEM) - /* Delta-Mu 1 monitor (8KiB) */ - PREALLOC_NORMAL("ST231aMonitor", 0x24200000, 0x24202000-1, - IORESOURCE_MEM) - /* Delta-Mu 1 RAM (~29.9MiB (32MiB - (2MiB + 8KiB))) */ - PREALLOC_NORMAL("MediaMemory1", 0x24202000, 0x26000000-1, - IORESOURCE_MEM) - - /* - * VIDEO2 / LX2 - */ - /* Delta-Mu 2 image (2MiB) */ - PREALLOC_NORMAL("ST231bImage", 0x60000000, 0x60200000-1, - IORESOURCE_MEM) - /* Delta-Mu 2 monitor (8KiB) */ - PREALLOC_NORMAL("ST231bMonitor", 0x60200000, 0x60202000-1, - IORESOURCE_MEM) - /* Delta-Mu 2 RAM (~29.9MiB (32MiB - (2MiB + 8KiB))) */ - PREALLOC_NORMAL("MediaMemory2", 0x60202000, 0x62000000-1, - IORESOURCE_MEM) - - /* - * Sysaudio Driver - */ - /* DSP code and data images (1MiB) */ - PREALLOC_NORMAL("DSP_Image_Buff", 0x00000000, 0x00100000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - /* ADSC CPU PCM buffer (40KiB) */ - PREALLOC_NORMAL("ADSC_CPU_PCM_Buff", 0x00000000, 0x0000A000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - /* ADSC AUX buffer (128KiB) */ - PREALLOC_NORMAL("ADSC_AUX_Buff", 0x00000000, 0x00020000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - /* ADSC Main buffer (128KiB) */ - PREALLOC_NORMAL("ADSC_Main_Buff", 0x00000000, 0x00020000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * STAVEM driver/STAPI - * - * This memory area is used for allocating buffers for Video decoding - * purposes. Allocation/De-allocation within this buffer is managed - * by the STAVMEM driver of the STAPI. They could be Decimated - * Picture Buffers, Intermediate Buffers, as deemed necessary for - * video decoding purposes, for any video decoders on Zeus. - */ - /* 12MiB */ - PREALLOC_NORMAL("AVMEMPartition0", 0x00000000, 0x00c00000-1, - IORESOURCE_MEM) - - /* - * DOCSIS Subsystem - */ - /* 7MiB */ - PREALLOC_DOCSIS("Docsis", 0x67500000, 0x67c00000-1, IORESOURCE_MEM) - - /* - * GHW HAL Driver - */ - /* PowerTV Graphics Heap (14MiB) */ - PREALLOC_NORMAL("GraphicsHeap", 0x62700000, 0x63500000-1, - IORESOURCE_MEM) - - /* - * multi com buffer area - */ - /* 128KiB */ - PREALLOC_NORMAL("MulticomSHM", 0x26000000, 0x26020000-1, - IORESOURCE_MEM) - - /* - * DMA Ring buffer (don't need recording buffers) - */ - /* 680KiB */ - PREALLOC_NORMAL("BMM_Buffer", 0x00000000, 0x000AA000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * Display bins buffer for unit0 - */ - /* 4KiB */ - PREALLOC_NORMAL("DisplayBins0", 0x00000000, 0x00001000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * Display bins buffer for unit1 - */ - /* 4KiB */ - PREALLOC_NORMAL("DisplayBins1", 0x00000000, 0x00001000-1, - IORESOURCE_MEM) - - /* - * AVFS: player HAL memory - */ - /* 945K * 3 for playback */ - PREALLOC_NORMAL("AvfsDmaMem", 0x00000000, 0x002c4c00-1, IORESOURCE_MEM) - - /* - * PMEM - */ - /* Persistent memory for diagnostics (64KiB) */ - PREALLOC_PMEM("DiagPersistentMemory", 0x00000000, 0x10000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * Smartcard - */ - /* Read and write buffers for Internal/External cards (10KiB) */ - PREALLOC_NORMAL("SmartCardInfo", 0x00000000, 0x2800-1, IORESOURCE_MEM) - - /* - * KAVNET - */ - /* NP Reset Vector - must be of the form xxCxxxxx (4KiB) */ - PREALLOC_NORMAL("NP_Reset_Vector", 0x27c00000, 0x27c01000-1, - IORESOURCE_MEM) - /* NP Image - must be video bank 1 (320KiB) */ - PREALLOC_NORMAL("NP_Image", 0x27020000, 0x27070000-1, IORESOURCE_MEM) - /* NP IPC - must be video bank 2 (512KiB) */ - PREALLOC_NORMAL("NP_IPC", 0x63500000, 0x63580000-1, IORESOURCE_MEM) - - /* - * NAND Flash - */ - /* 10KiB */ - PREALLOC_NORMAL("NandFlash", NAND_FLASH_BASE, NAND_FLASH_BASE+0x400-1, - IORESOURCE_MEM) - - /* - * Add other resources here - */ - - /* - * End of Resource marker - */ - { - .flags = 0, - }, -}; diff --git a/arch/mips/powertv/asic/prealloc-cronuslite.c b/arch/mips/powertv/asic/prealloc-cronuslite.c deleted file mode 100644 index a7937ba7b4c0..000000000000 --- a/arch/mips/powertv/asic/prealloc-cronuslite.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Memory pre-allocations for Cronus Lite boxes. - * - * Copyright (C) 2005-2009 Scientific-Atlanta, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that 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, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Author: Ken Eppinett - * David Schleef <ds@schleef.org> - */ - -#include <linux/init.h> -#include <linux/ioport.h> -#include <asm/mach-powertv/asic.h> -#include "prealloc.h" - -/* - * NON_DVR_CAPABLE CRONUSLITE RESOURCES - */ -struct resource non_dvr_cronuslite_resources[] __initdata = -{ - /* - * VIDEO2 / LX2 - */ - /* Delta-Mu 1 image (2MiB) */ - PREALLOC_NORMAL("ST231aImage", 0x60000000, 0x60200000-1, - IORESOURCE_MEM) - /* Delta-Mu 1 monitor (8KiB) */ - PREALLOC_NORMAL("ST231aMonitor", 0x60200000, 0x60202000-1, - IORESOURCE_MEM) - /* Delta-Mu 1 RAM (~29.9MiB (32MiB - (2MiB + 8KiB))) */ - PREALLOC_NORMAL("MediaMemory1", 0x60202000, 0x62000000-1, - IORESOURCE_MEM) - - /* - * Sysaudio Driver - */ - /* DSP code and data images (1MiB) */ - PREALLOC_NORMAL("DSP_Image_Buff", 0x00000000, 0x00100000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - /* ADSC CPU PCM buffer (40KiB) */ - PREALLOC_NORMAL("ADSC_CPU_PCM_Buff", 0x00000000, 0x0000A000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - /* ADSC AUX buffer (128KiB) */ - PREALLOC_NORMAL("ADSC_AUX_Buff", 0x00000000, 0x00020000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - /* ADSC Main buffer (128KiB) */ - PREALLOC_NORMAL("ADSC_Main_Buff", 0x00000000, 0x00020000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * STAVEM driver/STAPI - * - * This memory area is used for allocating buffers for Video decoding - * purposes. Allocation/De-allocation within this buffer is managed - * by the STAVMEM driver of the STAPI. They could be Decimated - * Picture Buffers, Intermediate Buffers, as deemed necessary for - * video decoding purposes, for any video decoders on Zeus. - */ - /* 6MiB */ - PREALLOC_NORMAL("AVMEMPartition0", 0x00000000, 0x00600000-1, - IORESOURCE_MEM) - - /* - * DOCSIS Subsystem - */ - /* 7MiB */ - PREALLOC_DOCSIS("Docsis", 0x67500000, 0x67c00000-1, IORESOURCE_MEM) - - /* - * GHW HAL Driver - */ - /* PowerTV Graphics Heap (14MiB) */ - PREALLOC_NORMAL("GraphicsHeap", 0x62700000, 0x63500000-1, - IORESOURCE_MEM) - - /* - * multi com buffer area - */ - /* 128KiB */ - PREALLOC_NORMAL("MulticomSHM", 0x26000000, 0x26020000-1, - IORESOURCE_MEM) - - /* - * DMA Ring buffer (don't need recording buffers) - */ - /* 680KiB */ - PREALLOC_NORMAL("BMM_Buffer", 0x00000000, 0x000AA000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * Display bins buffer for unit0 - */ - /* 4KiB */ - PREALLOC_NORMAL("DisplayBins0", 0x00000000, 0x00001000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * Display bins buffer for unit1 - */ - /* 4KiB */ - PREALLOC_NORMAL("DisplayBins1", 0x00000000, 0x00001000-1, - IORESOURCE_MEM) - - /* - * AVFS: player HAL memory - */ - /* 945K * 3 for playback */ - PREALLOC_NORMAL("AvfsDmaMem", 0x00000000, 0x002c4c00-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * PMEM - */ - /* Persistent memory for diagnostics (64KiB) */ - PREALLOC_PMEM("DiagPersistentMemory", 0x00000000, 0x10000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * Smartcard - */ - /* Read and write buffers for Internal/External cards (10KiB) */ - PREALLOC_NORMAL("SmartCardInfo", 0x00000000, 0x2800-1, IORESOURCE_MEM) - - /* - * KAVNET - */ - /* NP Reset Vector - must be of the form xxCxxxxx (4KiB) */ - PREALLOC_NORMAL("NP_Reset_Vector", 0x27c00000, 0x27c01000-1, - IORESOURCE_MEM) - /* NP Image - must be video bank 1 (320KiB) */ - PREALLOC_NORMAL("NP_Image", 0x27020000, 0x27070000-1, IORESOURCE_MEM) - /* NP IPC - must be video bank 2 (512KiB) */ - PREALLOC_NORMAL("NP_IPC", 0x63500000, 0x63580000-1, IORESOURCE_MEM) - - /* - * NAND Flash - */ - /* 10KiB */ - PREALLOC_NORMAL("NandFlash", NAND_FLASH_BASE, NAND_FLASH_BASE+0x400-1, - IORESOURCE_MEM) - - /* - * TFTPBuffer - * - * This buffer is used in some minimal configurations (e.g. two-way - * loader) for storing software images - */ - PREALLOC_TFTP("TFTPBuffer", 0x00000000, MEBIBYTE(80)-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * Add other resources here - */ - - /* - * End of Resource marker - */ - { - .flags = 0, - }, -}; diff --git a/arch/mips/powertv/asic/prealloc-gaia.c b/arch/mips/powertv/asic/prealloc-gaia.c deleted file mode 100644 index 2303bbfe6b82..000000000000 --- a/arch/mips/powertv/asic/prealloc-gaia.c +++ /dev/null @@ -1,589 +0,0 @@ -/* - * Memory pre-allocations for Gaia boxes. - * - * Copyright (C) 2005-2009 Scientific-Atlanta, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that 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, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Author: David VomLehn - */ - -#include <linux/init.h> -#include <asm/mach-powertv/asic.h> - -/* - * DVR_CAPABLE GAIA RESOURCES - */ -struct resource dvr_gaia_resources[] __initdata = { - /* - * - * VIDEO1 / LX1 - * - */ - { - .name = "ST231aImage", /* Delta-Mu 1 image and ram */ - .start = 0x24000000, - .end = 0x241FFFFF, /* 2MiB */ - .flags = IORESOURCE_MEM, - }, - { - .name = "ST231aMonitor", /* 8KiB block ST231a monitor */ - .start = 0x24200000, - .end = 0x24201FFF, - .flags = IORESOURCE_MEM, - }, - { - .name = "MediaMemory1", - .start = 0x24202000, - .end = 0x25FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */ - .flags = IORESOURCE_MEM, - }, - /* - * - * VIDEO2 / LX2 - * - */ - { - .name = "ST231bImage", /* Delta-Mu 2 image and ram */ - .start = 0x60000000, - .end = 0x601FFFFF, /* 2MiB */ - .flags = IORESOURCE_IO, - }, - { - .name = "ST231bMonitor", /* 8KiB block ST231b monitor */ - .start = 0x60200000, - .end = 0x60201FFF, - .flags = IORESOURCE_IO, - }, - { - .name = "MediaMemory2", - .start = 0x60202000, - .end = 0x61FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */ - .flags = IORESOURCE_IO, - }, - /* - * - * Sysaudio Driver - * - * This driver requires: - * - * Arbitrary Based Buffers: - * DSP_Image_Buff - DSP code and data images (1MB) - * ADSC_CPU_PCM_Buff - ADSC CPU PCM buffer (40KB) - * ADSC_AUX_Buff - ADSC AUX buffer (16KB) - * ADSC_Main_Buff - ADSC Main buffer (16KB) - * - */ - { - .name = "DSP_Image_Buff", - .start = 0x00000000, - .end = 0x000FFFFF, - .flags = IORESOURCE_MEM, - }, - { - .name = "ADSC_CPU_PCM_Buff", - .start = 0x00000000, - .end = 0x00009FFF, - .flags = IORESOURCE_MEM, - }, - { - .name = "ADSC_AUX_Buff", - .start = 0x00000000, - .end = 0x00003FFF, - .flags = IORESOURCE_MEM, - }, - { - .name = "ADSC_Main_Buff", - .start = 0x00000000, - .end = 0x00003FFF, - .flags = IORESOURCE_MEM, - }, - /* - * - * STAVEM driver/STAPI - * - * This driver requires: - * - * Arbitrary Based Buffers: - * This memory area is used for allocating buffers for Video decoding - * purposes. Allocation/De-allocation within this buffer is managed - * by the STAVMEM driver of the STAPI. They could be Decimated - * Picture Buffers, Intermediate Buffers, as deemed necessary for - * video decoding purposes, for any video decoders on Zeus. - * - */ - { - .name = "AVMEMPartition0", - .start = 0x63580000, - .end = 0x64180000 - 1, /* 12 MB total */ - .flags = IORESOURCE_IO, - }, - /* - * - * DOCSIS Subsystem - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Docsis - - * - */ - { - .name = "Docsis", - .start = 0x62000000, - .end = 0x62700000 - 1, /* 7 MB total */ - .flags = IORESOURCE_IO, - }, - /* - * - * GHW HAL Driver - * - * This driver requires: - * - * Arbitrary Based Buffers: - * GraphicsHeap - PowerTV Graphics Heap - * - */ - { - .name = "GraphicsHeap", - .start = 0x62700000, - .end = 0x63500000 - 1, /* 14 MB total */ - .flags = IORESOURCE_IO, - }, - /* - * - * multi com buffer area - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Docsis - - * - */ - { - .name = "MulticomSHM", - .start = 0x26000000, - .end = 0x26020000 - 1, - .flags = IORESOURCE_MEM, - }, - /* - * - * DMA Ring buffer - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Docsis - - * - */ - { - .name = "BMM_Buffer", - .start = 0x00000000, - .end = 0x00280000 - 1, - .flags = IORESOURCE_MEM, - }, - /* - * - * Display bins buffer for unit0 - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Display Bins for unit0 - * - */ - { - .name = "DisplayBins0", - .start = 0x00000000, - .end = 0x00000FFF, /* 4 KB total */ - .flags = IORESOURCE_MEM, - }, - /* - * - * Display bins buffer - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Display Bins for unit1 - * - */ - { - .name = "DisplayBins1", - .start = 0x64AD4000, - .end = 0x64AD5000 - 1, /* 4 KB total */ - .flags = IORESOURCE_IO, - }, - /* - * - * ITFS - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Docsis - - * - */ - { - .name = "ITFS", - .start = 0x64180000, - /* 815,104 bytes each for 2 ITFS partitions. */ - .end = 0x6430DFFF, - .flags = IORESOURCE_IO, - }, - /* - * - * AVFS - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Docsis - - * - */ - { - .name = "AvfsDmaMem", - .start = 0x6430E000, - /* (945K * 8) = (128K *3) 5 playbacks / 3 server */ - .end = 0x64AD0000 - 1, - .flags = IORESOURCE_IO, - }, - { - .name = "AvfsFileSys", - .start = 0x64AD0000, - .end = 0x64AD1000 - 1, /* 4K */ - .flags = IORESOURCE_IO, - }, - /* - * - * Smartcard - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Read and write buffers for Internal/External cards - * - */ - { - .name = "SmartCardInfo", - .start = 0x64AD1000, - .end = 0x64AD3800 - 1, - .flags = IORESOURCE_IO, - }, - /* - * - * KAVNET - * NP Reset Vector - must be of the form xxCxxxxx - * NP Image - must be video bank 1 - * NP IPC - must be video bank 2 - */ - { - .name = "NP_Reset_Vector", - .start = 0x27c00000, - .end = 0x27c01000 - 1, - .flags = IORESOURCE_MEM, - }, - { - .name = "NP_Image", - .start = 0x27020000, - .end = 0x27060000 - 1, - .flags = IORESOURCE_MEM, - }, - { - .name = "NP_IPC", - .start = 0x63500000, - .end = 0x63580000 - 1, - .flags = IORESOURCE_IO, - }, - /* - * Add other resources here - */ - { }, -}; - -/* - * NON_DVR_CAPABLE GAIA RESOURCES - */ -struct resource non_dvr_gaia_resources[] __initdata = { - /* - * - * VIDEO1 / LX1 - * - */ - { - .name = "ST231aImage", /* Delta-Mu 1 image and ram */ - .start = 0x24000000, - .end = 0x241FFFFF, /* 2MiB */ - .flags = IORESOURCE_MEM, - }, - { - .name = "ST231aMonitor", /* 8KiB block ST231a monitor */ - .start = 0x24200000, - .end = 0x24201FFF, - .flags = IORESOURCE_MEM, - }, - { - .name = "MediaMemory1", - .start = 0x24202000, - .end = 0x25FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */ - .flags = IORESOURCE_MEM, - }, - /* - * - * VIDEO2 / LX2 - * - */ - { - .name = "ST231bImage", /* Delta-Mu 2 image and ram */ - .start = 0x60000000, - .end = 0x601FFFFF, /* 2MiB */ - .flags = IORESOURCE_IO, - }, - { - .name = "ST231bMonitor", /* 8KiB block ST231b monitor */ - .start = 0x60200000, - .end = 0x60201FFF, - .flags = IORESOURCE_IO, - }, - { - .name = "MediaMemory2", - .start = 0x60202000, - .end = 0x61FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */ - .flags = IORESOURCE_IO, - }, - /* - * - * Sysaudio Driver - * - * This driver requires: - * - * Arbitrary Based Buffers: - * DSP_Image_Buff - DSP code and data images (1MB) - * ADSC_CPU_PCM_Buff - ADSC CPU PCM buffer (40KB) - * ADSC_AUX_Buff - ADSC AUX buffer (16KB) - * ADSC_Main_Buff - ADSC Main buffer (16KB) - * - */ - { - .name = "DSP_Image_Buff", - .start = 0x00000000, - .end = 0x000FFFFF, - .flags = IORESOURCE_MEM, - }, - { - .name = "ADSC_CPU_PCM_Buff", - .start = 0x00000000, - .end = 0x00009FFF, - .flags = IORESOURCE_MEM, - }, - { - .name = "ADSC_AUX_Buff", - .start = 0x00000000, - .end = 0x00003FFF, - .flags = IORESOURCE_MEM, - }, - { - .name = "ADSC_Main_Buff", - .start = 0x00000000, - .end = 0x00003FFF, - .flags = IORESOURCE_MEM, - }, - /* - * - * STAVEM driver/STAPI - * - * This driver requires: - * - * Arbitrary Based Buffers: - * This memory area is used for allocating buffers for Video decoding - * purposes. Allocation/De-allocation within this buffer is managed - * by the STAVMEM driver of the STAPI. They could be Decimated - * Picture Buffers, Intermediate Buffers, as deemed necessary for - * video decoding purposes, for any video decoders on Zeus. - * - */ - { - .name = "AVMEMPartition0", - .start = 0x63580000, - .end = 0x64180000 - 1, /* 12 MB total */ - .flags = IORESOURCE_IO, - }, - /* - * - * DOCSIS Subsystem - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Docsis - - * - */ - { - .name = "Docsis", - .start = 0x62000000, - .end = 0x62700000 - 1, /* 7 MB total */ - .flags = IORESOURCE_IO, - }, - /* - * - * GHW HAL Driver - * - * This driver requires: - * - * Arbitrary Based Buffers: - * GraphicsHeap - PowerTV Graphics Heap - * - */ - { - .name = "GraphicsHeap", - .start = 0x62700000, - .end = 0x63500000 - 1, /* 14 MB total */ - .flags = IORESOURCE_IO, - }, - /* - * - * multi com buffer area - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Docsis - - * - */ - { - .name = "MulticomSHM", - .start = 0x26000000, - .end = 0x26020000 - 1, - .flags = IORESOURCE_MEM, - }, - /* - * - * DMA Ring buffer - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Docsis - - * - */ - { - .name = "BMM_Buffer", - .start = 0x00000000, - .end = 0x000AA000 - 1, - .flags = IORESOURCE_MEM, - }, - /* - * - * Display bins buffer for unit0 - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Display Bins for unit0 - * - */ - { - .name = "DisplayBins0", - .start = 0x00000000, - .end = 0x00000FFF, /* 4 KB total */ - .flags = IORESOURCE_MEM, - }, - /* - * - * Display bins buffer - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Display Bins for unit1 - * - */ - { - .name = "DisplayBins1", - .start = 0x64AD4000, - .end = 0x64AD5000 - 1, /* 4 KB total */ - .flags = IORESOURCE_IO, - }, - /* - * - * AVFS: player HAL memory - * - * - */ - { - .name = "AvfsDmaMem", - .start = 0x6430E000, - .end = 0x645D2C00 - 1, /* 945K * 3 for playback */ - .flags = IORESOURCE_IO, - }, - /* - * - * PMEM - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Persistent memory for diagnostics. - * - */ - { - .name = "DiagPersistentMemory", - .start = 0x00000000, - .end = 0x10000 - 1, - .flags = IORESOURCE_MEM, - }, - /* - * - * Smartcard - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Read and write buffers for Internal/External cards - * - */ - { - .name = "SmartCardInfo", - .start = 0x64AD1000, - .end = 0x64AD3800 - 1, - .flags = IORESOURCE_IO, - }, - /* - * - * KAVNET - * NP Reset Vector - must be of the form xxCxxxxx - * NP Image - must be video bank 1 - * NP IPC - must be video bank 2 - */ - { - .name = "NP_Reset_Vector", - .start = 0x27c00000, - .end = 0x27c01000 - 1, - .flags = IORESOURCE_MEM, - }, - { - .name = "NP_Image", - .start = 0x27020000, - .end = 0x27060000 - 1, - .flags = IORESOURCE_MEM, - }, - { - .name = "NP_IPC", - .start = 0x63500000, - .end = 0x63580000 - 1, - .flags = IORESOURCE_IO, - }, - { }, -}; diff --git a/arch/mips/powertv/asic/prealloc-zeus.c b/arch/mips/powertv/asic/prealloc-zeus.c deleted file mode 100644 index 6e76f09c68d6..000000000000 --- a/arch/mips/powertv/asic/prealloc-zeus.c +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Memory pre-allocations for Zeus boxes. - * - * Copyright (C) 2005-2009 Scientific-Atlanta, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that 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, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Author: Ken Eppinett - * David Schleef <ds@schleef.org> - */ - -#include <linux/init.h> -#include <linux/ioport.h> -#include <asm/mach-powertv/asic.h> -#include "prealloc.h" - -/* - * DVR_CAPABLE RESOURCES - */ -struct resource dvr_zeus_resources[] __initdata = -{ - /* - * VIDEO1 / LX1 - */ - /* Delta-Mu 1 image (2MiB) */ - PREALLOC_NORMAL("ST231aImage", 0x20000000, 0x20200000-1, - IORESOURCE_MEM) - /* Delta-Mu 1 monitor (8KiB) */ - PREALLOC_NORMAL("ST231aMonitor", 0x20200000, 0x20202000-1, - IORESOURCE_MEM) - /* Delta-Mu 1 RAM (~29.9MiB (32MiB - (2MiB + 8KiB))) */ - PREALLOC_NORMAL("MediaMemory1", 0x20202000, 0x22000000-1, - IORESOURCE_MEM) - - /* - * VIDEO2 / LX2 - */ - /* Delta-Mu 2 image (2MiB) */ - PREALLOC_NORMAL("ST231bImage", 0x30000000, 0x30200000-1, - IORESOURCE_MEM) - /* Delta-Mu 2 monitor (8KiB) */ - PREALLOC_NORMAL("ST231bMonitor", 0x30200000, 0x30202000-1, - IORESOURCE_MEM) - /* Delta-Mu 2 RAM (~29.9MiB (32MiB - (2MiB + 8KiB))) */ - PREALLOC_NORMAL("MediaMemory2", 0x30202000, 0x32000000-1, - IORESOURCE_MEM) - - /* - * Sysaudio Driver - */ - /* DSP code and data images (1MiB) */ - PREALLOC_NORMAL("DSP_Image_Buff", 0x00000000, 0x00100000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - /* ADSC CPU PCM buffer (40KiB) */ - PREALLOC_NORMAL("ADSC_CPU_PCM_Buff", 0x00000000, 0x0000A000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - /* ADSC AUX buffer (16KiB) */ - PREALLOC_NORMAL("ADSC_AUX_Buff", 0x00000000, 0x00004000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - /* ADSC Main buffer (16KiB) */ - PREALLOC_NORMAL("ADSC_Main_Buff", 0x00000000, 0x00004000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * STAVEM driver/STAPI - * - * This memory area is used for allocating buffers for Video decoding - * purposes. Allocation/De-allocation within this buffer is managed - * by the STAVMEM driver of the STAPI. They could be Decimated - * Picture Buffers, Intermediate Buffers, as deemed necessary for - * video decoding purposes, for any video decoders on Zeus. - */ - /* 12MiB */ - PREALLOC_NORMAL("AVMEMPartition0", 0x00000000, 0x00c00000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * DOCSIS Subsystem - */ - /* 7MiB */ - PREALLOC_DOCSIS("Docsis", 0x40100000, 0x40800000-1, IORESOURCE_MEM) - - /* - * GHW HAL Driver - */ - /* PowerTV Graphics Heap (14MiB) */ - PREALLOC_NORMAL("GraphicsHeap", 0x46900000, 0x47700000-1, - IORESOURCE_MEM) - - /* - * multi com buffer area - */ - /* 128KiB */ - PREALLOC_NORMAL("MulticomSHM", 0x47900000, 0x47920000-1, - IORESOURCE_MEM) - - /* - * DMA Ring buffer - */ - /* 2.5MiB */ - PREALLOC_NORMAL("BMM_Buffer", 0x00000000, 0x00280000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * Display bins buffer for unit0 - */ - /* 4KiB */ - PREALLOC_NORMAL("DisplayBins0", 0x00000000, 0x00001000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * Display bins buffer for unit1 - */ - /* 4KiB */ - PREALLOC_NORMAL("DisplayBins1", 0x00000000, 0x00001000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * ITFS - */ - /* 815,104 bytes each for 2 ITFS partitions. */ - PREALLOC_NORMAL("ITFS", 0x00000000, 0x0018E000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * AVFS - */ - /* (945K * 8) = (128K * 3) 5 playbacks / 3 server */ - PREALLOC_NORMAL("AvfsDmaMem", 0x00000000, 0x007c2000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - /* 4KiB */ - PREALLOC_NORMAL("AvfsFileSys", 0x00000000, 0x00001000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * PMEM - */ - /* Persistent memory for diagnostics (64KiB) */ - PREALLOC_PMEM("DiagPersistentMemory", 0x00000000, 0x10000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * Smartcard - */ - /* Read and write buffers for Internal/External cards (10KiB) */ - PREALLOC_NORMAL("SmartCardInfo", 0x00000000, 0x2800-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * TFTPBuffer - * - * This buffer is used in some minimal configurations (e.g. two-way - * loader) for storing software images - */ - PREALLOC_TFTP("TFTPBuffer", 0x00000000, MEBIBYTE(80)-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * Add other resources here - */ - - /* - * End of Resource marker - */ - { - .flags = 0, - }, -}; - -/* - * NON_DVR_CAPABLE ZEUS RESOURCES - */ -struct resource non_dvr_zeus_resources[] __initdata = -{ - /* - * VIDEO1 / LX1 - */ - /* Delta-Mu 1 image (2MiB) */ - PREALLOC_NORMAL("ST231aImage", 0x20000000, 0x20200000-1, - IORESOURCE_MEM) - /* Delta-Mu 1 monitor (8KiB) */ - PREALLOC_NORMAL("ST231aMonitor", 0x20200000, 0x20202000-1, - IORESOURCE_MEM) - /* Delta-Mu 1 RAM (~29.9MiB (32MiB - (2MiB + 8KiB))) */ - PREALLOC_NORMAL("MediaMemory1", 0x20202000, 0x22000000-1, - IORESOURCE_MEM) - - /* - * Sysaudio Driver - */ - /* DSP code and data images (1MiB) */ - PREALLOC_NORMAL("DSP_Image_Buff", 0x00000000, 0x00100000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - /* ADSC CPU PCM buffer (40KiB) */ - PREALLOC_NORMAL("ADSC_CPU_PCM_Buff", 0x00000000, 0x0000A000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - /* ADSC AUX buffer (16KiB) */ - PREALLOC_NORMAL("ADSC_AUX_Buff", 0x00000000, 0x00004000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - /* ADSC Main buffer (16KiB) */ - PREALLOC_NORMAL("ADSC_Main_Buff", 0x00000000, 0x00004000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * STAVEM driver/STAPI - */ - /* 6MiB */ - PREALLOC_NORMAL("AVMEMPartition0", 0x00000000, 0x00600000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * DOCSIS Subsystem - */ - /* 7MiB */ - PREALLOC_DOCSIS("Docsis", 0x40100000, 0x40800000-1, IORESOURCE_MEM) - - /* - * GHW HAL Driver - */ - /* PowerTV Graphics Heap (14MiB) */ - PREALLOC_NORMAL("GraphicsHeap", 0x46900000, 0x47700000-1, - IORESOURCE_MEM) - - /* - * multi com buffer area - */ - /* 128KiB */ - PREALLOC_NORMAL("MulticomSHM", 0x47900000, 0x47920000-1, - IORESOURCE_MEM) - - /* - * DMA Ring buffer - */ - /* 2.5MiB */ - PREALLOC_NORMAL("BMM_Buffer", 0x00000000, 0x00280000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * Display bins buffer for unit0 - */ - /* 4KiB */ - PREALLOC_NORMAL("DisplayBins0", 0x00000000, 0x00001000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * AVFS: player HAL memory - */ - /* 945K * 3 for playback */ - PREALLOC_NORMAL("AvfsDmaMem", 0x00000000, 0x002c4c00-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * PMEM - */ - /* Persistent memory for diagnostics (64KiB) */ - PREALLOC_PMEM("DiagPersistentMemory", 0x00000000, 0x10000-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * Smartcard - */ - /* Read and write buffers for Internal/External cards (10KiB) */ - PREALLOC_NORMAL("SmartCardInfo", 0x00000000, 0x2800-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * NAND Flash - */ - /* 10KiB */ - PREALLOC_NORMAL("NandFlash", NAND_FLASH_BASE, NAND_FLASH_BASE+0x400-1, - IORESOURCE_MEM) - - /* - * TFTPBuffer - * - * This buffer is used in some minimal configurations (e.g. two-way - * loader) for storing software images - */ - PREALLOC_TFTP("TFTPBuffer", 0x00000000, MEBIBYTE(80)-1, - (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) - - /* - * Add other resources here - */ - - /* - * End of Resource marker - */ - { - .flags = 0, - }, -}; diff --git a/arch/mips/powertv/asic/prealloc.h b/arch/mips/powertv/asic/prealloc.h deleted file mode 100644 index 8e682df17856..000000000000 --- a/arch/mips/powertv/asic/prealloc.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Definitions for memory preallocations - * - * Copyright (C) 2005-2009 Scientific-Atlanta, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that 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, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef _ARCH_MIPS_POWERTV_ASIC_PREALLOC_H -#define _ARCH_MIPS_POWERTV_ASIC_PREALLOC_H - -#define KIBIBYTE(n) ((n) * 1024) /* Number of kibibytes */ -#define MEBIBYTE(n) ((n) * KIBIBYTE(1024)) /* Number of mebibytes */ - -/* "struct resource" array element definition */ -#define PREALLOC(NAME, START, END, FLAGS) { \ - .name = (NAME), \ - .start = (START), \ - .end = (END), \ - .flags = (FLAGS) \ - }, - -/* Individual resources in the preallocated resource arrays are defined using - * macros. These macros are conditionally defined based on their - * corresponding kernel configuration flag: - * - CONFIG_PREALLOC_NORMAL: preallocate resources for a normal settop box - * - CONFIG_PREALLOC_TFTP: preallocate the TFTP download resource - * - CONFIG_PREALLOC_DOCSIS: preallocate the DOCSIS resource - * - CONFIG_PREALLOC_PMEM: reserve space for persistent memory - */ -#ifdef CONFIG_PREALLOC_NORMAL -#define PREALLOC_NORMAL(name, start, end, flags) \ - PREALLOC(name, start, end, flags) -#else -#define PREALLOC_NORMAL(name, start, end, flags) -#endif - -#ifdef CONFIG_PREALLOC_TFTP -#define PREALLOC_TFTP(name, start, end, flags) \ - PREALLOC(name, start, end, flags) -#else -#define PREALLOC_TFTP(name, start, end, flags) -#endif - -#ifdef CONFIG_PREALLOC_DOCSIS -#define PREALLOC_DOCSIS(name, start, end, flags) \ - PREALLOC(name, start, end, flags) -#else -#define PREALLOC_DOCSIS(name, start, end, flags) -#endif - -#ifdef CONFIG_PREALLOC_PMEM -#define PREALLOC_PMEM(name, start, end, flags) \ - PREALLOC(name, start, end, flags) -#else -#define PREALLOC_PMEM(name, start, end, flags) -#endif -#endif diff --git a/arch/mips/powertv/init.c b/arch/mips/powertv/init.c deleted file mode 100644 index 498926377e51..000000000000 --- a/arch/mips/powertv/init.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2004, 2005 MIPS Technologies, Inc. - * All rights reserved. - * Authors: Carsten Langgaard <carstenl@mips.com> - * Maciej W. Rozycki <macro@mips.com> - * Portions copyright (C) 2009 Cisco Systems, Inc. - * - * This program is free software; you can distribute it and/or modify it - * under the terms 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, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * PROM library initialisation code. - */ -#include <linux/init.h> -#include <linux/string.h> -#include <linux/kernel.h> - -#include <asm/bootinfo.h> -#include <linux/io.h> -#include <asm/cacheflush.h> -#include <asm/traps.h> - -#include <asm/mips-boards/generic.h> -#include <asm/mach-powertv/asic.h> - -#include "init.h" - -static int *_prom_envp; -unsigned long _prom_memsize; - -/* - * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer. - * This macro take care of sign extension, if running in 64-bit mode. - */ -#define prom_envp(index) ((char *)(long)_prom_envp[(index)]) - -char *prom_getenv(char *envname) -{ - char *result = NULL; - - if (_prom_envp != NULL) { - /* - * Return a pointer to the given environment variable. - * In 64-bit mode: we're using 64-bit pointers, but all pointers - * in the PROM structures are only 32-bit, so we need some - * workarounds, if we are running in 64-bit mode. - */ - int i, index = 0; - - i = strlen(envname); - - while (prom_envp(index)) { - if (strncmp(envname, prom_envp(index), i) == 0) { - result = prom_envp(index + 1); - break; - } - index += 2; - } - } - - return result; -} - -void __init prom_init(void) -{ - int prom_argc; - char *prom_argv; - - prom_argc = fw_arg0; - prom_argv = (char *) fw_arg1; - _prom_envp = (int *) fw_arg2; - _prom_memsize = (unsigned long) fw_arg3; - - if (prom_argc == 1) { - strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE); - strlcat(arcs_cmdline, prom_argv, COMMAND_LINE_SIZE); - } - - configure_platform(); - prom_meminit(); -} diff --git a/arch/mips/powertv/init.h b/arch/mips/powertv/init.h deleted file mode 100644 index c1a8bd0dbe4b..000000000000 --- a/arch/mips/powertv/init.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Definitions from powertv init.c file - * - * Copyright (C) 2009 Cisco Systems, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that 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, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Author: David VomLehn - */ - -#ifndef _POWERTV_INIT_H -#define _POWERTV_INIT_H -extern unsigned long _prom_memsize; -extern void prom_meminit(void); -extern char *prom_getenv(char *name); -#endif diff --git a/arch/mips/powertv/ioremap.c b/arch/mips/powertv/ioremap.c deleted file mode 100644 index d060478aab03..000000000000 --- a/arch/mips/powertv/ioremap.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * ioremap.c - * - * Support for mapping between dma_addr_t values a phys_addr_t values. - * - * Copyright (C) 2005-2009 Scientific-Atlanta, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that 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, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Author: David VomLehn <dvomlehn@cisco.com> - * - * Description: Defines the platform resources for the SA settop. - * - * NOTE: The bootloader allocates persistent memory at an address which is - * 16 MiB below the end of the highest address in KSEG0. All fixed - * address memory reservations must avoid this region. - */ - -#include <linux/kernel.h> -#include <linux/module.h> - -#include <asm/mach-powertv/ioremap.h> - -/* - * Define the sizes of and masks for grains in physical and DMA space. The - * values are the same but the types are not. - */ -#define IOR_PHYS_GRAIN ((phys_addr_t) 1 << IOR_LSBITS) -#define IOR_PHYS_GRAIN_MASK (IOR_PHYS_GRAIN - 1) - -#define IOR_DMA_GRAIN ((dma_addr_t) 1 << IOR_LSBITS) -#define IOR_DMA_GRAIN_MASK (IOR_DMA_GRAIN - 1) - -/* - * Values that, when accessed by an index derived from a phys_addr_t and - * added to phys_addr_t value, yield a DMA address - */ -struct ior_phys_to_dma _ior_phys_to_dma[IOR_NUM_PHYS_TO_DMA]; -EXPORT_SYMBOL(_ior_phys_to_dma); - -/* - * Values that, when accessed by an index derived from a dma_addr_t and - * added to that dma_addr_t value, yield a physical address - */ -struct ior_dma_to_phys _ior_dma_to_phys[IOR_NUM_DMA_TO_PHYS]; -EXPORT_SYMBOL(_ior_dma_to_phys); - -/** - * setup_dma_to_phys - set up conversion from DMA to physical addresses - * @dma_idx: Top IOR_LSBITS bits of the DMA address, i.e. an index - * into the array _dma_to_phys. - * @delta: Value that, when added to the DMA address, will yield the - * physical address - * @s: Number of bytes in the section of memory with the given delta - * between DMA and physical addresses. - */ -static void setup_dma_to_phys(dma_addr_t dma, phys_addr_t delta, dma_addr_t s) -{ - int dma_idx, first_idx, last_idx; - phys_addr_t first, last; - - /* - * Calculate the first and last indices, rounding the first up and - * the second down. - */ - first = dma & ~IOR_DMA_GRAIN_MASK; - last = (dma + s - 1) & ~IOR_DMA_GRAIN_MASK; - first_idx = first >> IOR_LSBITS; /* Convert to indices */ - last_idx = last >> IOR_LSBITS; - - for (dma_idx = first_idx; dma_idx <= last_idx; dma_idx++) - _ior_dma_to_phys[dma_idx].offset = delta >> IOR_DMA_SHIFT; -} - -/** - * setup_phys_to_dma - set up conversion from DMA to physical addresses - * @phys_idx: Top IOR_LSBITS bits of the DMA address, i.e. an index - * into the array _phys_to_dma. - * @delta: Value that, when added to the DMA address, will yield the - * physical address - * @s: Number of bytes in the section of memory with the given delta - * between DMA and physical addresses. - */ -static void setup_phys_to_dma(phys_addr_t phys, dma_addr_t delta, phys_addr_t s) -{ - int phys_idx, first_idx, last_idx; - phys_addr_t first, last; - - /* - * Calculate the first and last indices, rounding the first up and - * the second down. - */ - first = phys & ~IOR_PHYS_GRAIN_MASK; - last = (phys + s - 1) & ~IOR_PHYS_GRAIN_MASK; - first_idx = first >> IOR_LSBITS; /* Convert to indices */ - last_idx = last >> IOR_LSBITS; - - for (phys_idx = first_idx; phys_idx <= last_idx; phys_idx++) - _ior_phys_to_dma[phys_idx].offset = delta >> IOR_PHYS_SHIFT; -} - -/** - * ioremap_add_map - add to the physical and DMA address conversion arrays - * @phys: Process's view of the address of the start of the memory chunk - * @dma: DMA address of the start of the memory chunk - * @size: Size, in bytes, of the chunk of memory - * - * NOTE: It might be obvious, but the assumption is that all @size bytes have - * the same offset between the physical address and the DMA address. - */ -void ioremap_add_map(phys_addr_t phys, phys_addr_t dma, phys_addr_t size) -{ - if (size == 0) - return; - - if ((dma & IOR_DMA_GRAIN_MASK) != 0 || - (phys & IOR_PHYS_GRAIN_MASK) != 0 || - (size & IOR_PHYS_GRAIN_MASK) != 0) - pr_crit("Memory allocation must be in chunks of 0x%x bytes\n", - IOR_PHYS_GRAIN); - - setup_dma_to_phys(dma, phys - dma, size); - setup_phys_to_dma(phys, dma - phys, size); -} diff --git a/arch/mips/powertv/memory.c b/arch/mips/powertv/memory.c deleted file mode 100644 index bc2f3ca22b41..000000000000 --- a/arch/mips/powertv/memory.c +++ /dev/null @@ -1,353 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. - * Portions copyright (C) 2009 Cisco Systems, Inc. - * - * This program is free software; you can distribute it and/or modify it - * under the terms 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, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * Apparently originally from arch/mips/malta-memory.c. Modified to work - * with the PowerTV bootloader. - */ -#include <linux/init.h> -#include <linux/mm.h> -#include <linux/bootmem.h> -#include <linux/pfn.h> -#include <linux/string.h> - -#include <asm/bootinfo.h> -#include <asm/page.h> -#include <asm/sections.h> - -#include <asm/mach-powertv/asic.h> -#include <asm/mach-powertv/ioremap.h> - -#include "init.h" - -/* Memory constants */ -#define KIBIBYTE(n) ((n) * 1024) /* Number of kibibytes */ -#define MEBIBYTE(n) ((n) * KIBIBYTE(1024)) /* Number of mebibytes */ -#define DEFAULT_MEMSIZE MEBIBYTE(128) /* If no memsize provided */ - -#define BLDR_SIZE KIBIBYTE(256) /* Memory reserved for bldr */ -#define RV_SIZE MEBIBYTE(4) /* Size of reset vector */ - -#define LOW_MEM_END 0x20000000 /* Highest low memory address */ -#define BLDR_ALIAS 0x10000000 /* Bootloader address */ -#define RV_PHYS 0x1fc00000 /* Reset vector address */ -#define LOW_RAM_END RV_PHYS /* End of real RAM in low mem */ - -/* - * Very low-level conversion from processor physical address to device - * DMA address for the first bank of memory. - */ -#define PHYS_TO_DMA(paddr) ((paddr) + (CONFIG_LOW_RAM_DMA - LOW_RAM_ALIAS)) - -unsigned long ptv_memsize; - -/* - * struct low_mem_reserved - Items in low memory that are reserved - * @start: Physical address of item - * @size: Size, in bytes, of this item - * @is_aliased: True if this is RAM aliased from another location. If false, - * it is something other than aliased RAM and the RAM in the - * unaliased address is still visible outside of low memory. - */ -struct low_mem_reserved { - phys_addr_t start; - phys_addr_t size; - bool is_aliased; -}; - -/* - * Must be in ascending address order - */ -struct low_mem_reserved low_mem_reserved[] = { - {BLDR_ALIAS, BLDR_SIZE, true}, /* Bootloader RAM */ - {RV_PHYS, RV_SIZE, false}, /* Reset vector */ -}; - -/* - * struct mem_layout - layout of a piece of the system RAM - * @phys: Physical address of the start of this piece of RAM. This is the - * address at which both the processor and I/O devices see the - * RAM. - * @alias: Alias of this piece of memory in order to make it appear in - * the low memory part of the processor's address space. I/O - * devices don't see anything here. - * @size: Size, in bytes, of this piece of RAM - */ -struct mem_layout { - phys_addr_t phys; - phys_addr_t alias; - phys_addr_t size; -}; - -/* - * struct mem_layout_list - list descriptor for layouts of system RAM pieces - * @family: Specifies the family being described - * @n: Number of &struct mem_layout elements - * @layout: Pointer to the list of &mem_layout structures - */ -struct mem_layout_list { - enum family_type family; - size_t n; - struct mem_layout *layout; -}; - -static struct mem_layout f1500_layout[] = { - {0x20000000, 0x10000000, MEBIBYTE(256)}, -}; - -static struct mem_layout f4500_layout[] = { - {0x40000000, 0x10000000, MEBIBYTE(256)}, - {0x20000000, 0x20000000, MEBIBYTE(32)}, -}; - -static struct mem_layout f8500_layout[] = { - {0x40000000, 0x10000000, MEBIBYTE(256)}, - {0x20000000, 0x20000000, MEBIBYTE(32)}, - {0x30000000, 0x30000000, MEBIBYTE(32)}, -}; - -static struct mem_layout fx600_layout[] = { - {0x20000000, 0x10000000, MEBIBYTE(256)}, - {0x60000000, 0x60000000, MEBIBYTE(128)}, -}; - -static struct mem_layout_list layout_list[] = { - {FAMILY_1500, ARRAY_SIZE(f1500_layout), f1500_layout}, - {FAMILY_1500VZE, ARRAY_SIZE(f1500_layout), f1500_layout}, - {FAMILY_1500VZF, ARRAY_SIZE(f1500_layout), f1500_layout}, - {FAMILY_4500, ARRAY_SIZE(f4500_layout), f4500_layout}, - {FAMILY_8500, ARRAY_SIZE(f8500_layout), f8500_layout}, - {FAMILY_8500RNG, ARRAY_SIZE(f8500_layout), f8500_layout}, - {FAMILY_4600, ARRAY_SIZE(fx600_layout), fx600_layout}, - {FAMILY_4600VZA, ARRAY_SIZE(fx600_layout), fx600_layout}, - {FAMILY_8600, ARRAY_SIZE(fx600_layout), fx600_layout}, - {FAMILY_8600VZB, ARRAY_SIZE(fx600_layout), fx600_layout}, -}; - -/* If we can't determine the layout, use this */ -static struct mem_layout default_layout[] = { - {0x20000000, 0x10000000, MEBIBYTE(128)}, -}; - -/** - * register_non_ram - register low memory not available for RAM usage - */ -static __init void register_non_ram(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(low_mem_reserved); i++) - add_memory_region(low_mem_reserved[i].start, - low_mem_reserved[i].size, BOOT_MEM_RESERVED); -} - -/** - * get_memsize - get the size of memory as a single bank - */ -static phys_addr_t get_memsize(void) -{ - static char cmdline[COMMAND_LINE_SIZE] __initdata; - phys_addr_t memsize = 0; - char *memsize_str; - char *ptr; - - /* Check the command line first for a memsize directive */ - strcpy(cmdline, arcs_cmdline); - ptr = strstr(cmdline, "memsize="); - if (ptr && (ptr != cmdline) && (*(ptr - 1) != ' ')) - ptr = strstr(ptr, " memsize="); - - if (ptr) { - memsize = memparse(ptr + 8, &ptr); - } else { - /* otherwise look in the environment */ - memsize_str = prom_getenv("memsize"); - - if (memsize_str != NULL) { - pr_info("prom memsize = %s\n", memsize_str); - memsize = simple_strtol(memsize_str, NULL, 0); - } - - if (memsize == 0) { - if (_prom_memsize != 0) { - memsize = _prom_memsize; - pr_info("_prom_memsize = 0x%x\n", memsize); - /* add in memory that the bootloader doesn't - * report */ - memsize += BLDR_SIZE; - } else { - memsize = DEFAULT_MEMSIZE; - pr_info("Memsize not passed by bootloader, " - "defaulting to 0x%x\n", memsize); - } - } - } - - return memsize; -} - -/** - * register_low_ram - register an aliased section of RAM - * @p: Alias address of memory - * @n: Number of bytes in this section of memory - * - * Returns the number of bytes registered - * - */ -static __init phys_addr_t register_low_ram(phys_addr_t p, phys_addr_t n) -{ - phys_addr_t s; - int i; - phys_addr_t orig_n; - - orig_n = n; - - BUG_ON(p + n > RV_PHYS); - - for (i = 0; n != 0 && i < ARRAY_SIZE(low_mem_reserved); i++) { - phys_addr_t start; - phys_addr_t size; - - start = low_mem_reserved[i].start; - size = low_mem_reserved[i].size; - - /* Handle memory before this low memory section */ - if (p < start) { - phys_addr_t s; - s = min(n, start - p); - add_memory_region(p, s, BOOT_MEM_RAM); - p += s; - n -= s; - } - - /* Handle the low memory section itself. If it's aliased, - * we reduce the number of byes left, but if not, the RAM - * is available elsewhere and we don't reduce the number of - * bytes remaining. */ - if (p == start) { - if (low_mem_reserved[i].is_aliased) { - s = min(n, size); - n -= s; - p += s; - } else - p += n; - } - } - - return orig_n - n; -} - -/* - * register_ram - register real RAM - * @p: Address of memory as seen by devices - * @alias: If the memory is seen at an additional address by the processor, - * this will be the address, otherwise it is the same as @p. - * @n: Number of bytes in this section of memory - */ -static __init void register_ram(phys_addr_t p, phys_addr_t alias, - phys_addr_t n) -{ - /* - * If some or all of this memory has an alias, break it into the - * aliased and non-aliased portion. - */ - if (p != alias) { - phys_addr_t alias_size; - phys_addr_t registered; - - alias_size = min(n, LOW_RAM_END - alias); - registered = register_low_ram(alias, alias_size); - ioremap_add_map(alias, p, n); - n -= registered; - p += registered; - } - -#ifdef CONFIG_HIGHMEM - if (n != 0) { - add_memory_region(p, n, BOOT_MEM_RAM); - ioremap_add_map(p, p, n); - } -#endif -} - -/** - * register_address_space - register things in the address space - * @memsize: Number of bytes of RAM installed - * - * Takes the given number of bytes of RAM and registers as many of the regions, - * or partial regions, as it can. So, the default configuration might have - * two regions with 256 MiB each. If the memsize passed in on the command line - * is 384 MiB, it will register the first region with 256 MiB and the second - * with 128 MiB. - */ -static __init void register_address_space(phys_addr_t memsize) -{ - int i; - phys_addr_t size; - size_t n; - struct mem_layout *layout; - enum family_type family; - - /* - * Register all of the things that aren't available to the kernel as - * memory. - */ - register_non_ram(); - - /* Find the appropriate memory description */ - family = platform_get_family(); - - for (i = 0; i < ARRAY_SIZE(layout_list); i++) { - if (layout_list[i].family == family) - break; - } - - if (i == ARRAY_SIZE(layout_list)) { - n = ARRAY_SIZE(default_layout); - layout = default_layout; - } else { - n = layout_list[i].n; - layout = layout_list[i].layout; - } - - for (i = 0; memsize != 0 && i < n; i++) { - size = min(memsize, layout[i].size); - register_ram(layout[i].phys, layout[i].alias, size); - memsize -= size; - } -} - -void __init prom_meminit(void) -{ - ptv_memsize = get_memsize(); - register_address_space(ptv_memsize); -} - -void __init prom_free_prom_memory(void) -{ - unsigned long addr; - int i; - - for (i = 0; i < boot_mem_map.nr_map; i++) { - if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA) - continue; - - addr = boot_mem_map.map[i].addr; - free_init_pages("prom memory", - addr, addr + boot_mem_map.map[i].size); - } -} diff --git a/arch/mips/powertv/pci/Makefile b/arch/mips/powertv/pci/Makefile deleted file mode 100644 index 2610a6af5b2c..000000000000 --- a/arch/mips/powertv/pci/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -# -# Copyright (C) 2009 Scientific-Atlanta, Inc. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that 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, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -# - -obj-$(CONFIG_PCI) += fixup-powertv.o diff --git a/arch/mips/powertv/pci/fixup-powertv.c b/arch/mips/powertv/pci/fixup-powertv.c deleted file mode 100644 index d7ecbae64a6e..000000000000 --- a/arch/mips/powertv/pci/fixup-powertv.c +++ /dev/null @@ -1,37 +0,0 @@ -#include <linux/init.h> -#include <linux/export.h> -#include <linux/pci.h> -#include <asm/mach-powertv/interrupts.h> -#include "powertv-pci.h" - -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) -{ - return asic_pcie_map_irq(dev, slot, pin); -} - -/* Do platform specific device initialization at pci_enable_device() time */ -int pcibios_plat_dev_init(struct pci_dev *dev) -{ - return 0; -} - -/* - * asic_pcie_map_irq - * - * Parameters: - * *dev - pointer to a pci_dev structure (not used) - * slot - slot number (not used) - * pin - pin number (not used) - * - * Return Value: - * Returns: IRQ number (always the PCI Express IRQ number) - * - * Description: - * asic_pcie_map_irq will return the IRQ number of the PCI Express interrupt. - * - */ -int asic_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) -{ - return irq_pciexp; -} -EXPORT_SYMBOL(asic_pcie_map_irq); diff --git a/arch/mips/powertv/pci/powertv-pci.h b/arch/mips/powertv/pci/powertv-pci.h deleted file mode 100644 index 1b5886bbd759..000000000000 --- a/arch/mips/powertv/pci/powertv-pci.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * powertv-pci.c - * - * Copyright (C) 2009 Cisco Systems, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that 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, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -/* - * Local definitions for the powertv PCI code - */ - -#ifndef _POWERTV_PCI_POWERTV_PCI_H_ -#define _POWERTV_PCI_POWERTV_PCI_H_ -extern int asic_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin); -extern int asic_pcie_init(void); -extern int asic_pcie_init(void); - -extern int log_level; -#endif diff --git a/arch/mips/powertv/powertv-clock.h b/arch/mips/powertv/powertv-clock.h deleted file mode 100644 index d94c54311485..000000000000 --- a/arch/mips/powertv/powertv-clock.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2009 Cisco Systems, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that 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, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Author: David VomLehn - */ - -#ifndef _POWERTV_POWERTV_CLOCK_H -#define _POWERTV_POWERTV_CLOCK_H -extern int powertv_clockevent_init(void); -extern void powertv_clocksource_init(void); -extern unsigned int mips_get_pll_freq(void); -#endif diff --git a/arch/mips/powertv/powertv-usb.c b/arch/mips/powertv/powertv-usb.c deleted file mode 100644 index d845eace58e9..000000000000 --- a/arch/mips/powertv/powertv-usb.c +++ /dev/null @@ -1,404 +0,0 @@ -/* - * powertv-usb.c - * - * Description: ASIC-specific USB device setup and shutdown - * - * Copyright (C) 2005-2009 Scientific-Atlanta, Inc. - * Copyright (C) 2009 Cisco Systems, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that 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, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Author: Ken Eppinett - * David Schleef <ds@schleef.org> - * - * NOTE: The bootloader allocates persistent memory at an address which is - * 16 MiB below the end of the highest address in KSEG0. All fixed - * address memory reservations must avoid this region. - */ - -#include <linux/kernel.h> -#include <linux/export.h> -#include <linux/ioport.h> -#include <linux/platform_device.h> -#include <asm/mach-powertv/asic.h> -#include <asm/mach-powertv/interrupts.h> - -/* misc_clk_ctl1 values */ -#define MCC1_30MHZ_POWERUP_SELECT (1 << 14) -#define MCC1_DIV9 (1 << 13) -#define MCC1_ETHMIPS_POWERUP_SELECT (1 << 11) -#define MCC1_USB_POWERUP_SELECT (1 << 1) -#define MCC1_CLOCK108_POWERUP_SELECT (1 << 0) - -/* Possible values for clock select */ -#define MCC1_USB_CLOCK_HIGH_Z (0 << 4) -#define MCC1_USB_CLOCK_48MHZ (1 << 4) -#define MCC1_USB_CLOCK_24MHZ (2 << 4) -#define MCC1_USB_CLOCK_6MHZ (3 << 4) - -#define MCC1_CONFIG (MCC1_30MHZ_POWERUP_SELECT | \ - MCC1_DIV9 | \ - MCC1_ETHMIPS_POWERUP_SELECT | \ - MCC1_USB_POWERUP_SELECT | \ - MCC1_CLOCK108_POWERUP_SELECT) - -/* misc_clk_ctl2 values */ -#define MCC2_GMII_GCLK_TO_PAD (1 << 31) -#define MCC2_ETHER125_0_CLOCK_SELECT (1 << 29) -#define MCC2_RMII_0_CLOCK_SELECT (1 << 28) -#define MCC2_GMII_TX0_CLOCK_SELECT (1 << 27) -#define MCC2_GMII_RX0_CLOCK_SELECT (1 << 26) -#define MCC2_ETHER125_1_CLOCK_SELECT (1 << 24) -#define MCC2_RMII_1_CLOCK_SELECT (1 << 23) -#define MCC2_GMII_TX1_CLOCK_SELECT (1 << 22) -#define MCC2_GMII_RX1_CLOCK_SELECT (1 << 21) -#define MCC2_ETHER125_2_CLOCK_SELECT (1 << 19) -#define MCC2_RMII_2_CLOCK_SELECT (1 << 18) -#define MCC2_GMII_TX2_CLOCK_SELECT (1 << 17) -#define MCC2_GMII_RX2_CLOCK_SELECT (1 << 16) - -#define ETHER_CLK_CONFIG (MCC2_GMII_GCLK_TO_PAD | \ - MCC2_ETHER125_0_CLOCK_SELECT | \ - MCC2_RMII_0_CLOCK_SELECT | \ - MCC2_GMII_TX0_CLOCK_SELECT | \ - MCC2_GMII_RX0_CLOCK_SELECT | \ - MCC2_ETHER125_1_CLOCK_SELECT | \ - MCC2_RMII_1_CLOCK_SELECT | \ - MCC2_GMII_TX1_CLOCK_SELECT | \ - MCC2_GMII_RX1_CLOCK_SELECT | \ - MCC2_ETHER125_2_CLOCK_SELECT | \ - MCC2_RMII_2_CLOCK_SELECT | \ - MCC2_GMII_TX2_CLOCK_SELECT | \ - MCC2_GMII_RX2_CLOCK_SELECT) - -/* misc_clk_ctl2 definitions for Gaia */ -#define FSX4A_REF_SELECT (1 << 16) -#define FSX4B_REF_SELECT (1 << 17) -#define FSX4C_REF_SELECT (1 << 18) -#define DDR_PLL_REF_SELECT (1 << 19) -#define MIPS_PLL_REF_SELECT (1 << 20) - -/* Definitions for the QAM frequency select register FS432X4A4_QAM_CTL */ -#define QAM_FS_SDIV_SHIFT 29 -#define QAM_FS_MD_SHIFT 24 -#define QAM_FS_MD_MASK 0x1f /* Cut down to 5 bits */ -#define QAM_FS_PE_SHIFT 8 - -#define QAM_FS_DISABLE_DIVIDE_BY_3 (1 << 5) -#define QAM_FS_ENABLE_PROGRAM (1 << 4) -#define QAM_FS_ENABLE_OUTPUT (1 << 3) -#define QAM_FS_SELECT_TEST_BYPASS (1 << 2) -#define QAM_FS_DISABLE_DIGITAL_STANDBY (1 << 1) -#define QAM_FS_CHOOSE_FS (1 << 0) - -/* Definitions for fs432x4a_ctl register */ -#define QAM_FS_NSDIV_54MHZ (1 << 2) - -/* Definitions for bcm1_usb2_ctl register */ -#define BCM1_USB2_CTL_BISTOK (1 << 11) -#define BCM1_USB2_CTL_PORT2_SHIFT_JK (1 << 7) -#define BCM1_USB2_CTL_PORT1_SHIFT_JK (1 << 6) -#define BCM1_USB2_CTL_PORT2_FAST_EDGE (1 << 5) -#define BCM1_USB2_CTL_PORT1_FAST_EDGE (1 << 4) -#define BCM1_USB2_CTL_EHCI_PRT_PWR_ACTIVE_HIGH (1 << 1) -#define BCM1_USB2_CTL_APP_PRT_OVRCUR_IN_ACTIVE_HIGH (1 << 0) - -/* Definitions for crt_spare register */ -#define CRT_SPARE_PORT2_SHIFT_JK (1 << 21) -#define CRT_SPARE_PORT1_SHIFT_JK (1 << 20) -#define CRT_SPARE_PORT2_FAST_EDGE (1 << 19) -#define CRT_SPARE_PORT1_FAST_EDGE (1 << 18) -#define CRT_SPARE_DIVIDE_BY_9_FROM_432 (1 << 17) -#define CRT_SPARE_USB_DIVIDE_BY_9 (1 << 16) - -/* Definitions for usb2_stbus_obc register */ -#define USB_STBUS_OBC_STORE32_LOAD32 0x3 - -/* Definitions for usb2_stbus_mess_size register */ -#define USB2_STBUS_MESS_SIZE_2 0x1 /* 2 packets */ - -/* Definitions for usb2_stbus_chunk_size register */ -#define USB2_STBUS_CHUNK_SIZE_2 0x1 /* 2 packets */ - -/* Definitions for usb2_strap register */ -#define USB2_STRAP_HFREQ_SELECT 0x1 - -/* - * USB Host Resource Definition - */ - -static struct resource ehci_resources[] = { - { - .parent = &asic_resource, - .start = 0, - .end = 0xff, - .flags = IORESOURCE_MEM, - }, - { - .start = irq_usbehci, - .end = irq_usbehci, - .flags = IORESOURCE_IRQ, - }, -}; - -static u64 ehci_dmamask = 0xffffffffULL; - -static struct platform_device ehci_device = { - .name = "powertv-ehci", - .id = 0, - .num_resources = 2, - .resource = ehci_resources, - .dev = { - .dma_mask = &ehci_dmamask, - .coherent_dma_mask = 0xffffffff, - }, -}; - -static struct resource ohci_resources[] = { - { - .parent = &asic_resource, - .start = 0, - .end = 0xff, - .flags = IORESOURCE_MEM, - }, - { - .start = irq_usbohci, - .end = irq_usbohci, - .flags = IORESOURCE_IRQ, - }, -}; - -static u64 ohci_dmamask = 0xffffffffULL; - -static struct platform_device ohci_device = { - .name = "powertv-ohci", - .id = 0, - .num_resources = 2, - .resource = ohci_resources, - .dev = { - .dma_mask = &ohci_dmamask, - .coherent_dma_mask = 0xffffffff, - }, -}; - -static unsigned usb_users; -static DEFINE_SPINLOCK(usb_regs_lock); - -/* - * - * fs_update - set frequency synthesizer for USB - * @pe_bits Phase tap setting - * @md_bits Coarse selector bus for algorithm of phase tap - * @sdiv_bits Output divider setting - * @disable_div_by_3 Either QAM_FS_DISABLE_DIVIDE_BY_3 or zero - * @standby Either QAM_FS_DISABLE_DIGITAL_STANDBY or zero - * - * QAM frequency selection code, which affects the frequency at which USB - * runs. The frequency is calculated as: - * 2^15 * ndiv * Fin - * Fout = ------------------------------------------------------------ - * (sdiv * (ipe * (1 + md/32) - (ipe - 2^15)*(1 + (md + 1)/32))) - * where: - * Fin 54 MHz - * ndiv QAM_FS_NSDIV_54MHZ ? 8 : 16 - * sdiv 1 << (sdiv_bits + 1) - * ipe Same as pe_bits - * md A five-bit, two's-complement integer (range [-16, 15]), which - * is the lower 5 bits of md_bits. - */ -static void fs_update(u32 pe_bits, int md_bits, u32 sdiv_bits, - u32 disable_div_by_3, u32 standby) -{ - u32 val; - - val = ((sdiv_bits << QAM_FS_SDIV_SHIFT) | - ((md_bits & QAM_FS_MD_MASK) << QAM_FS_MD_SHIFT) | - (pe_bits << QAM_FS_PE_SHIFT) | - QAM_FS_ENABLE_OUTPUT | - standby | - disable_div_by_3); - asic_write(val, fs432x4b4_usb_ctl); - asic_write(val | QAM_FS_ENABLE_PROGRAM, fs432x4b4_usb_ctl); - asic_write(val | QAM_FS_ENABLE_PROGRAM | QAM_FS_CHOOSE_FS, - fs432x4b4_usb_ctl); -} - -/* - * usb_eye_configure - for optimizing the shape USB eye waveform - * @set: Bits to set in the register - * @clear: Bits to clear in the register; each bit with a one will - * be set in the register, zero bits will not be modified - */ -static void usb_eye_configure(u32 set, u32 clear) -{ - u32 old; - - old = asic_read(crt_spare); - old |= set; - old &= ~clear; - asic_write(old, crt_spare); -} - -/* - * platform_configure_usb - usb configuration based on platform type. - */ -static void platform_configure_usb(void) -{ - u32 bcm1_usb2_ctl_value; - enum asic_type asic_type; - unsigned long flags; - - spin_lock_irqsave(&usb_regs_lock, flags); - usb_users++; - - if (usb_users != 1) { - spin_unlock_irqrestore(&usb_regs_lock, flags); - return; - } - - asic_type = platform_get_asic(); - - switch (asic_type) { - case ASIC_ZEUS: - fs_update(0x0000, -15, 0x02, 0, 0); - bcm1_usb2_ctl_value = BCM1_USB2_CTL_EHCI_PRT_PWR_ACTIVE_HIGH | - BCM1_USB2_CTL_APP_PRT_OVRCUR_IN_ACTIVE_HIGH; - break; - - case ASIC_CRONUS: - case ASIC_CRONUSLITE: - usb_eye_configure(0, CRT_SPARE_USB_DIVIDE_BY_9); - fs_update(0x8000, -14, 0x03, QAM_FS_DISABLE_DIVIDE_BY_3, - QAM_FS_DISABLE_DIGITAL_STANDBY); - bcm1_usb2_ctl_value = BCM1_USB2_CTL_EHCI_PRT_PWR_ACTIVE_HIGH | - BCM1_USB2_CTL_APP_PRT_OVRCUR_IN_ACTIVE_HIGH; - break; - - case ASIC_CALLIOPE: - fs_update(0x0000, -15, 0x02, QAM_FS_DISABLE_DIVIDE_BY_3, - QAM_FS_DISABLE_DIGITAL_STANDBY); - - switch (platform_get_family()) { - case FAMILY_1500VZE: - break; - - case FAMILY_1500VZF: - usb_eye_configure(CRT_SPARE_PORT2_SHIFT_JK | - CRT_SPARE_PORT1_SHIFT_JK | - CRT_SPARE_PORT2_FAST_EDGE | - CRT_SPARE_PORT1_FAST_EDGE, 0); - break; - - default: - usb_eye_configure(CRT_SPARE_PORT2_SHIFT_JK | - CRT_SPARE_PORT1_SHIFT_JK, 0); - break; - } - - bcm1_usb2_ctl_value = BCM1_USB2_CTL_BISTOK | - BCM1_USB2_CTL_EHCI_PRT_PWR_ACTIVE_HIGH | - BCM1_USB2_CTL_APP_PRT_OVRCUR_IN_ACTIVE_HIGH; - break; - - case ASIC_GAIA: - fs_update(0x8000, -14, 0x03, QAM_FS_DISABLE_DIVIDE_BY_3, - QAM_FS_DISABLE_DIGITAL_STANDBY); - bcm1_usb2_ctl_value = BCM1_USB2_CTL_BISTOK | - BCM1_USB2_CTL_EHCI_PRT_PWR_ACTIVE_HIGH | - BCM1_USB2_CTL_APP_PRT_OVRCUR_IN_ACTIVE_HIGH; - break; - - default: - pr_err("Unknown ASIC type: %d\n", asic_type); - bcm1_usb2_ctl_value = 0; - break; - } - - /* turn on USB power */ - asic_write(0, usb2_strap); - /* Enable all OHCI interrupts */ - asic_write(bcm1_usb2_ctl_value, usb2_control); - /* usb2_stbus_obc store32/load32 */ - asic_write(USB_STBUS_OBC_STORE32_LOAD32, usb2_stbus_obc); - /* usb2_stbus_mess_size 2 packets */ - asic_write(USB2_STBUS_MESS_SIZE_2, usb2_stbus_mess_size); - /* usb2_stbus_chunk_size 2 packets */ - asic_write(USB2_STBUS_CHUNK_SIZE_2, usb2_stbus_chunk_size); - spin_unlock_irqrestore(&usb_regs_lock, flags); -} - -static void platform_unconfigure_usb(void) -{ - unsigned long flags; - - spin_lock_irqsave(&usb_regs_lock, flags); - usb_users--; - if (usb_users == 0) - asic_write(USB2_STRAP_HFREQ_SELECT, usb2_strap); - spin_unlock_irqrestore(&usb_regs_lock, flags); -} - -/* - * Set up the USB EHCI interface - */ -void platform_configure_usb_ehci() -{ - platform_configure_usb(); -} -EXPORT_SYMBOL(platform_configure_usb_ehci); - -/* - * Set up the USB OHCI interface - */ -void platform_configure_usb_ohci() -{ - platform_configure_usb(); -} -EXPORT_SYMBOL(platform_configure_usb_ohci); - -/* - * Shut the USB EHCI interface down - */ -void platform_unconfigure_usb_ehci() -{ - platform_unconfigure_usb(); -} -EXPORT_SYMBOL(platform_unconfigure_usb_ehci); - -/* - * Shut the USB OHCI interface down - */ -void platform_unconfigure_usb_ohci() -{ - platform_unconfigure_usb(); -} -EXPORT_SYMBOL(platform_unconfigure_usb_ohci); - -/** - * platform_devices_init - sets up USB device resourse. - */ -int __init platform_usb_devices_init(struct platform_device **ehci_dev, - struct platform_device **ohci_dev) -{ - *ehci_dev = &ehci_device; - ehci_resources[0].start = asic_reg_phys_addr(ehci_hcapbase); - ehci_resources[0].end += ehci_resources[0].start; - - *ohci_dev = &ohci_device; - ohci_resources[0].start = asic_reg_phys_addr(ohci_hc_revision); - ohci_resources[0].end += ohci_resources[0].start; - - return 0; -} diff --git a/arch/mips/powertv/powertv_setup.c b/arch/mips/powertv/powertv_setup.c deleted file mode 100644 index 24689bff1039..000000000000 --- a/arch/mips/powertv/powertv_setup.c +++ /dev/null @@ -1,319 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - * Portions copyright (C) 2009 Cisco Systems, Inc. - * - * This program is free software; you can distribute it and/or modify it - * under the terms 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, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - */ -#include <linux/init.h> -#include <linux/sched.h> -#include <linux/ioport.h> -#include <linux/pci.h> -#include <linux/screen_info.h> -#include <linux/notifier.h> -#include <linux/etherdevice.h> -#include <linux/if_ether.h> -#include <linux/ctype.h> -#include <linux/cpu.h> -#include <linux/time.h> - -#include <asm/bootinfo.h> -#include <asm/irq.h> -#include <asm/mips-boards/generic.h> -#include <asm/dma.h> -#include <asm/asm.h> -#include <asm/traps.h> -#include <asm/asm-offsets.h> -#include "reset.h" - -#define VAL(n) STR(n) - -/* - * Macros for loading addresses and storing registers: - * LONG_L_ Stringified version of LONG_L for use in asm() statement - * LONG_S_ Stringified version of LONG_S for use in asm() statement - * PTR_LA_ Stringified version of PTR_LA for use in asm() statement - * REG_SIZE Number of 8-bit bytes in a full width register - */ -#define LONG_L_ VAL(LONG_L) " " -#define LONG_S_ VAL(LONG_S) " " -#define PTR_LA_ VAL(PTR_LA) " " - -#ifdef CONFIG_64BIT -#warning TODO: 64-bit code needs to be verified -#define REG_SIZE "8" /* In bytes */ -#endif - -#ifdef CONFIG_32BIT -#define REG_SIZE "4" /* In bytes */ -#endif - -static void register_panic_notifier(void); -static int panic_handler(struct notifier_block *notifier_block, - unsigned long event, void *cause_string); - -const char *get_system_type(void) -{ - return "PowerTV"; -} - -void __init plat_mem_setup(void) -{ - panic_on_oops = 1; - register_panic_notifier(); - -#if 0 - mips_pcibios_init(); -#endif - mips_reboot_setup(); -} - -/* - * Install a panic notifier for platform-specific diagnostics - */ -static void register_panic_notifier() -{ - static struct notifier_block panic_notifier = { - .notifier_call = panic_handler, - .next = NULL, - .priority = INT_MAX - }; - atomic_notifier_chain_register(&panic_notifier_list, &panic_notifier); -} - -static int panic_handler(struct notifier_block *notifier_block, - unsigned long event, void *cause_string) -{ - struct pt_regs my_regs; - - /* Save all of the registers */ - { - unsigned long at, v0, v1; /* Must be on the stack */ - - /* Start by saving $at and v0 on the stack. We use $at - * ourselves, but it looks like the compiler may use v0 or v1 - * to load the address of the pt_regs structure. We'll come - * back later to store the registers in the pt_regs - * structure. */ - __asm__ __volatile__ ( - ".set noat\n" - LONG_S_ "$at, %[at]\n" - LONG_S_ "$2, %[v0]\n" - LONG_S_ "$3, %[v1]\n" - : - [at] "=m" (at), - [v0] "=m" (v0), - [v1] "=m" (v1) - : - : "at" - ); - - __asm__ __volatile__ ( - ".set noat\n" - "move $at, %[pt_regs]\n" - - /* Argument registers */ - LONG_S_ "$4, " VAL(PT_R4) "($at)\n" - LONG_S_ "$5, " VAL(PT_R5) "($at)\n" - LONG_S_ "$6, " VAL(PT_R6) "($at)\n" - LONG_S_ "$7, " VAL(PT_R7) "($at)\n" - - /* Temporary regs */ - LONG_S_ "$8, " VAL(PT_R8) "($at)\n" - LONG_S_ "$9, " VAL(PT_R9) "($at)\n" - LONG_S_ "$10, " VAL(PT_R10) "($at)\n" - LONG_S_ "$11, " VAL(PT_R11) "($at)\n" - LONG_S_ "$12, " VAL(PT_R12) "($at)\n" - LONG_S_ "$13, " VAL(PT_R13) "($at)\n" - LONG_S_ "$14, " VAL(PT_R14) "($at)\n" - LONG_S_ "$15, " VAL(PT_R15) "($at)\n" - - /* "Saved" registers */ - LONG_S_ "$16, " VAL(PT_R16) "($at)\n" - LONG_S_ "$17, " VAL(PT_R17) "($at)\n" - LONG_S_ "$18, " VAL(PT_R18) "($at)\n" - LONG_S_ "$19, " VAL(PT_R19) "($at)\n" - LONG_S_ "$20, " VAL(PT_R20) "($at)\n" - LONG_S_ "$21, " VAL(PT_R21) "($at)\n" - LONG_S_ "$22, " VAL(PT_R22) "($at)\n" - LONG_S_ "$23, " VAL(PT_R23) "($at)\n" - - /* Add'l temp regs */ - LONG_S_ "$24, " VAL(PT_R24) "($at)\n" - LONG_S_ "$25, " VAL(PT_R25) "($at)\n" - - /* Kernel temp regs */ - LONG_S_ "$26, " VAL(PT_R26) "($at)\n" - LONG_S_ "$27, " VAL(PT_R27) "($at)\n" - - /* Global pointer, stack pointer, frame pointer and - * return address */ - LONG_S_ "$gp, " VAL(PT_R28) "($at)\n" - LONG_S_ "$sp, " VAL(PT_R29) "($at)\n" - LONG_S_ "$fp, " VAL(PT_R30) "($at)\n" - LONG_S_ "$ra, " VAL(PT_R31) "($at)\n" - - /* Now we can get the $at and v0 registers back and - * store them */ - LONG_L_ "$8, %[at]\n" - LONG_S_ "$8, " VAL(PT_R1) "($at)\n" - LONG_L_ "$8, %[v0]\n" - LONG_S_ "$8, " VAL(PT_R2) "($at)\n" - LONG_L_ "$8, %[v1]\n" - LONG_S_ "$8, " VAL(PT_R3) "($at)\n" - : - : - [at] "m" (at), - [v0] "m" (v0), - [v1] "m" (v1), - [pt_regs] "r" (&my_regs) - : "at", "t0" - ); - - /* Set the current EPC value to be the current location in this - * function */ - __asm__ __volatile__ ( - ".set noat\n" - "1:\n" - PTR_LA_ "$at, 1b\n" - LONG_S_ "$at, %[cp0_epc]\n" - : - [cp0_epc] "=m" (my_regs.cp0_epc) - : - : "at" - ); - - my_regs.cp0_cause = read_c0_cause(); - my_regs.cp0_status = read_c0_status(); - } - - pr_crit("I'm feeling a bit sleepy. hmmmmm... perhaps a nap would... " - "zzzz... \n"); - - return NOTIFY_DONE; -} - -/* Information about the RF MAC address, if one was supplied on the - * command line. */ -static bool have_rfmac; -static u8 rfmac[ETH_ALEN]; - -static int rfmac_param(char *p) -{ - u8 *q; - bool is_high_nibble; - int c; - - /* Skip a leading "0x", if present */ - if (*p == '0' && *(p+1) == 'x') - p += 2; - - q = rfmac; - is_high_nibble = true; - - for (c = (unsigned char) *p++; - isxdigit(c) && q - rfmac < ETH_ALEN; - c = (unsigned char) *p++) { - int nibble; - - nibble = (isdigit(c) ? (c - '0') : - (isupper(c) ? c - 'A' + 10 : c - 'a' + 10)); - - if (is_high_nibble) - *q = nibble << 4; - else - *q++ |= nibble; - - is_high_nibble = !is_high_nibble; - } - - /* If we parsed all the way to the end of the parameter value and - * parsed all ETH_ALEN bytes, we have a usable RF MAC address */ - have_rfmac = (c == '\0' && q - rfmac == ETH_ALEN); - - return 0; -} - -early_param("rfmac", rfmac_param); - -/* - * Generate an Ethernet MAC address that has a good chance of being unique. - * @addr: Pointer to six-byte array containing the Ethernet address - * Generates an Ethernet MAC address that is highly likely to be unique for - * this particular system on a network with other systems of the same type. - * - * The problem we are solving is that, when eth_random_addr() is used to - * generate MAC addresses at startup, there isn't much entropy for the random - * number generator to use and the addresses it produces are fairly likely to - * be the same as those of other identical systems on the same local network. - * This is true even for relatively small numbers of systems (for the reason - * why, see the Wikipedia entry for "Birthday problem" at: - * http://en.wikipedia.org/wiki/Birthday_problem - * - * The good news is that we already have a MAC address known to be unique, the - * RF MAC address. The bad news is that this address is already in use on the - * RF interface. Worse, the obvious trick, taking the RF MAC address and - * turning on the locally managed bit, has already been used for other devices. - * Still, this does give us something to work with. - * - * The approach we take is: - * 1. If we can't get the RF MAC Address, just call eth_random_addr. - * 2. Use the 24-bit NIC-specific bits of the RF MAC address as the last 24 - * bits of the new address. This is very likely to be unique, except for - * the current box. - * 3. To avoid using addresses already on the current box, we set the top - * six bits of the address with a value different from any currently - * registered Scientific Atlanta organizationally unique identifyer - * (OUI). This avoids duplication with any addresses on the system that - * were generated from valid Scientific Atlanta-registered address by - * simply flipping the locally managed bit. - * 4. We aren't generating a multicast address, so we leave the multicast - * bit off. Since we aren't using a registered address, we have to set - * the locally managed bit. - * 5. We then randomly generate the remaining 16-bits. This does two - * things: - * a. It allows us to call this function for more than one device - * in this system - * b. It ensures that things will probably still work even if - * some device on the device network has a locally managed - * address that matches the top six bits from step 2. - */ -void platform_random_ether_addr(u8 addr[ETH_ALEN]) -{ - const int num_random_bytes = 2; - const unsigned char non_sciatl_oui_bits = 0xc0u; - const unsigned char mac_addr_locally_managed = (1 << 1); - - if (!have_rfmac) { - pr_warning("rfmac not available on command line; " - "generating random MAC address\n"); - eth_random_addr(addr); - } - - else { - int i; - - /* Set the first byte to something that won't match a Scientific - * Atlanta OUI, is locally managed, and isn't a multicast - * address */ - addr[0] = non_sciatl_oui_bits | mac_addr_locally_managed; - - /* Get some bytes of random address information */ - get_random_bytes(&addr[1], num_random_bytes); - - /* Copy over the NIC-specific bits of the RF MAC address */ - for (i = 1 + num_random_bytes; i < ETH_ALEN; i++) - addr[i] = rfmac[i]; - } -} diff --git a/arch/mips/powertv/reset.c b/arch/mips/powertv/reset.c deleted file mode 100644 index 11c32fbf2784..000000000000 --- a/arch/mips/powertv/reset.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. - * Portions copyright (C) 2009 Cisco Systems, Inc. - * - * This program is free software; you can distribute it and/or modify it - * under the terms 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, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - */ -#include <linux/pm.h> - -#include <linux/io.h> -#include <asm/reboot.h> /* Not included by linux/reboot.h */ - -#include <asm/mach-powertv/asic_regs.h> -#include "reset.h" - -static void mips_machine_restart(char *command) -{ - writel(0x1, asic_reg_addr(watchdog)); -} - -void mips_reboot_setup(void) -{ - _machine_restart = mips_machine_restart; -} diff --git a/arch/mips/powertv/reset.h b/arch/mips/powertv/reset.h deleted file mode 100644 index 888fd09e2620..000000000000 --- a/arch/mips/powertv/reset.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Definitions from powertv reset.c file - * - * Copyright (C) 2009 Cisco Systems, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that 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, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Author: David VomLehn - */ - -#ifndef _POWERTV_POWERTV_RESET_H -#define _POWERTV_POWERTV_RESET_H -extern void mips_reboot_setup(void); -#endif diff --git a/arch/mips/powertv/time.c b/arch/mips/powertv/time.c deleted file mode 100644 index f38b0d45eca9..000000000000 --- a/arch/mips/powertv/time.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. - * Portions copyright (C) 2009 Cisco Systems, Inc. - * - * This program is free software; you can distribute it and/or modify it - * under the terms 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, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * Setting up the clock on the MIPS boards. - */ - -#include <linux/init.h> -#include <asm/mach-powertv/interrupts.h> -#include <asm/time.h> - -#include "powertv-clock.h" - -unsigned int get_c0_compare_int(void) -{ - return irq_mips_timer; -} - -void __init plat_time_init(void) -{ - powertv_clocksource_init(); -} diff --git a/arch/mips/ralink/clk.c b/arch/mips/ralink/clk.c index bba0cdfd83bc..5d0983d47161 100644 --- a/arch/mips/ralink/clk.c +++ b/arch/mips/ralink/clk.c @@ -26,7 +26,7 @@ void ralink_clk_add(const char *dev, unsigned long rate) struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL); if (!clk) - panic("failed to add clock\n"); + panic("failed to add clock"); clk->cl.dev_id = dev; clk->cl.clk = clk; diff --git a/arch/mips/ralink/mt7620.c b/arch/mips/ralink/mt7620.c index d217509e5300..a3ad56c2372d 100644 --- a/arch/mips/ralink/mt7620.c +++ b/arch/mips/ralink/mt7620.c @@ -350,7 +350,7 @@ void prom_soc_init(struct ralink_soc_info *soc_info) name = "MT7620A"; soc_info->compatible = "ralink,mt7620a-soc"; } else { - panic("mt7620: unknown SoC, n0:%08x n1:%08x\n", n0, n1); + panic("mt7620: unknown SoC, n0:%08x n1:%08x", n0, n1); } rev = __raw_readl(sysc + SYSC_REG_CHIP_REV); diff --git a/arch/mips/ralink/of.c b/arch/mips/ralink/of.c index ce38d11f9da5..eccc5526155e 100644 --- a/arch/mips/ralink/of.c +++ b/arch/mips/ralink/of.c @@ -21,6 +21,7 @@ #include <asm/reboot.h> #include <asm/bootinfo.h> #include <asm/addrspace.h> +#include <asm/prom.h> #include "common.h" @@ -108,7 +109,7 @@ static int __init plat_of_setup(void) strncpy(of_ids[1].compatible, "palmbus", len); if (of_platform_populate(NULL, of_ids, NULL, NULL)) - panic("failed to populate DT\n"); + panic("failed to populate DT"); /* make sure ithat the reset controller is setup early */ ralink_rst_init(); diff --git a/arch/mips/ralink/rt305x.c b/arch/mips/ralink/rt305x.c index ca7ee3a33790..bb82a82da9e7 100644 --- a/arch/mips/ralink/rt305x.c +++ b/arch/mips/ralink/rt305x.c @@ -276,7 +276,7 @@ void prom_soc_init(struct ralink_soc_info *soc_info) name = "RT5350"; soc_info->compatible = "ralink,rt5350-soc"; } else { - panic("rt305x: unknown SoC, n0:%08x n1:%08x\n", n0, n1); + panic("rt305x: unknown SoC, n0:%08x n1:%08x", n0, n1); } id = __raw_readl(sysc + SYSC_REG_CHIP_ID); diff --git a/arch/mips/ralink/timer.c b/arch/mips/ralink/timer.c index e49241a2c39a..202785709441 100644 --- a/arch/mips/ralink/timer.c +++ b/arch/mips/ralink/timer.c @@ -126,7 +126,7 @@ static int rt_timer_probe(struct platform_device *pdev) return -ENOENT; } - rt->membase = devm_request_and_ioremap(&pdev->dev, res); + rt->membase = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(rt->membase)) return PTR_ERR(rt->membase); diff --git a/arch/mn10300/Kconfig b/arch/mn10300/Kconfig index 6aaa1607001a..8bde9237d13b 100644 --- a/arch/mn10300/Kconfig +++ b/arch/mn10300/Kconfig @@ -181,7 +181,6 @@ endmenu config SMP bool "Symmetric multi-processing support" default y - select USE_GENERIC_SMP_HELPERS depends on MN10300_PROC_MN2WS0038 || MN10300_PROC_MN2WS0050 ---help--- This enables support for systems with more than one CPU. If you have diff --git a/arch/mn10300/include/asm/Kbuild b/arch/mn10300/include/asm/Kbuild index c5d767028306..74742dc6a3da 100644 --- a/arch/mn10300/include/asm/Kbuild +++ b/arch/mn10300/include/asm/Kbuild @@ -2,3 +2,4 @@ generic-y += clkdev.h generic-y += exec.h generic-y += trace_clock.h +generic-y += preempt.h diff --git a/arch/mn10300/include/asm/mmu_context.h b/arch/mn10300/include/asm/mmu_context.h index c67c2b5365a6..75dbe696f830 100644 --- a/arch/mn10300/include/asm/mmu_context.h +++ b/arch/mn10300/include/asm/mmu_context.h @@ -71,7 +71,7 @@ static inline unsigned long allocate_mmu_context(struct mm_struct *mm) local_flush_tlb_all(); /* fix the TLB version if needed (we avoid version #0 so as to - * distingush MMU_NO_CONTEXT) */ + * distinguish MMU_NO_CONTEXT) */ if (!mc) *pmc = mc = MMU_CONTEXT_FIRST_VERSION; } diff --git a/arch/mn10300/include/asm/pci.h b/arch/mn10300/include/asm/pci.h index 6f31cc0f1a87..166323824683 100644 --- a/arch/mn10300/include/asm/pci.h +++ b/arch/mn10300/include/asm/pci.h @@ -44,7 +44,6 @@ extern void unit_pci_init(void); #define pcibios_assign_all_busses() 0 #endif -extern unsigned long pci_mem_start; #define PCIBIOS_MIN_IO 0xBE000004 #define PCIBIOS_MIN_MEM 0xB8000000 diff --git a/arch/mn10300/include/asm/pgalloc.h b/arch/mn10300/include/asm/pgalloc.h index 146bacf193ea..0f25d5fa86f3 100644 --- a/arch/mn10300/include/asm/pgalloc.h +++ b/arch/mn10300/include/asm/pgalloc.h @@ -46,6 +46,7 @@ static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) static inline void pte_free(struct mm_struct *mm, struct page *pte) { + pgtable_page_dtor(pte); __free_page(pte); } diff --git a/arch/mn10300/include/asm/thread_info.h b/arch/mn10300/include/asm/thread_info.h index 224b4262486d..bf280eaccd36 100644 --- a/arch/mn10300/include/asm/thread_info.h +++ b/arch/mn10300/include/asm/thread_info.h @@ -16,8 +16,6 @@ #include <asm/page.h> -#define PREEMPT_ACTIVE 0x10000000 - #ifdef CONFIG_4KSTACKS #define THREAD_SIZE (4096) #define THREAD_SIZE_ORDER (0) diff --git a/arch/mn10300/include/uapi/asm/socket.h b/arch/mn10300/include/uapi/asm/socket.h index e2a2b203eb00..71dedcae55a6 100644 --- a/arch/mn10300/include/uapi/asm/socket.h +++ b/arch/mn10300/include/uapi/asm/socket.h @@ -76,4 +76,6 @@ #define SO_BUSY_POLL 46 +#define SO_MAX_PACING_RATE 47 + #endif /* _ASM_SOCKET_H */ diff --git a/arch/mn10300/kernel/setup.c b/arch/mn10300/kernel/setup.c index ebac9c11f796..2ad7f32fa122 100644 --- a/arch/mn10300/kernel/setup.c +++ b/arch/mn10300/kernel/setup.c @@ -35,9 +35,6 @@ struct mn10300_cpuinfo boot_cpu_data; -/* For PCI or other memory-mapped resources */ -unsigned long pci_mem_start = 0x18000000; - static char __initdata cmd_line[COMMAND_LINE_SIZE]; char redboot_command_line[COMMAND_LINE_SIZE] = "console=ttyS0,115200 root=/dev/mtdblock3 rw"; diff --git a/arch/mn10300/mm/pgtable.c b/arch/mn10300/mm/pgtable.c index bd9ada693f95..e77a7c728081 100644 --- a/arch/mn10300/mm/pgtable.c +++ b/arch/mn10300/mm/pgtable.c @@ -78,8 +78,13 @@ struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address) #else pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT, 0); #endif - if (pte) - clear_highpage(pte); + if (!pte) + return NULL; + clear_highpage(pte); + if (!pgtable_page_ctor(pte)) { + __free_page(pte); + return NULL; + } return pte; } diff --git a/arch/mn10300/unit-asb2305/pci-asb2305.h b/arch/mn10300/unit-asb2305/pci-asb2305.h index 7fa66a0e4624..9e17aca5a2a1 100644 --- a/arch/mn10300/unit-asb2305/pci-asb2305.h +++ b/arch/mn10300/unit-asb2305/pci-asb2305.h @@ -35,7 +35,6 @@ extern void pcibios_resource_survey(void); /* pci.c */ -extern int pcibios_last_bus; extern struct pci_ops *pci_root_ops; extern struct irq_routing_table *pcibios_get_irq_routing_table(void); diff --git a/arch/mn10300/unit-asb2305/pci.c b/arch/mn10300/unit-asb2305/pci.c index e37fac0461f3..6b4339f8c9c2 100644 --- a/arch/mn10300/unit-asb2305/pci.c +++ b/arch/mn10300/unit-asb2305/pci.c @@ -24,7 +24,6 @@ unsigned int pci_probe = 1; -int pcibios_last_bus = -1; struct pci_ops *pci_root_ops; /* @@ -392,10 +391,6 @@ char *__init pcibios_setup(char *str) if (!strcmp(str, "off")) { pci_probe = 0; return NULL; - - } else if (!strncmp(str, "lastbus=", 8)) { - pcibios_last_bus = simple_strtol(str+8, NULL, 0); - return NULL; } return str; diff --git a/arch/openrisc/Makefile b/arch/openrisc/Makefile index 4739b8302a58..89076a66eee2 100644 --- a/arch/openrisc/Makefile +++ b/arch/openrisc/Makefile @@ -24,7 +24,7 @@ OBJCOPYFLAGS := -O binary -R .note -R .comment -S LDFLAGS_vmlinux := LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name) -KBUILD_CFLAGS += -pipe -ffixed-r10 +KBUILD_CFLAGS += -pipe -ffixed-r10 -D__linux__ ifeq ($(CONFIG_OPENRISC_HAVE_INST_MUL),y) KBUILD_CFLAGS += $(call cc-option,-mhard-mul) diff --git a/arch/openrisc/configs/or1ksim_defconfig b/arch/openrisc/configs/or1ksim_defconfig index ea172bdfa36a..42fe5303a370 100644 --- a/arch/openrisc/configs/or1ksim_defconfig +++ b/arch/openrisc/configs/or1ksim_defconfig @@ -1,9 +1,9 @@ CONFIG_CROSS_COMPILE="or32-linux-" +CONFIG_NO_HZ=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_BLK_DEV_INITRD=y # CONFIG_RD_GZIP is not set CONFIG_EXPERT=y -# CONFIG_SYSCTL_SYSCALL is not set # CONFIG_KALLSYMS is not set # CONFIG_EPOLL is not set # CONFIG_TIMERFD is not set @@ -15,7 +15,6 @@ CONFIG_SLOB=y CONFIG_MODULES=y # CONFIG_BLOCK is not set CONFIG_OPENRISC_BUILTIN_DTB="or1ksim" -CONFIG_NO_HZ=y CONFIG_HZ_100=y CONFIG_NET=y CONFIG_PACKET=y @@ -39,11 +38,8 @@ CONFIG_DEVTMPFS_MOUNT=y # CONFIG_FW_LOADER is not set CONFIG_PROC_DEVICETREE=y CONFIG_NETDEVICES=y -CONFIG_MICREL_PHY=y -CONFIG_NET_ETHERNET=y CONFIG_ETHOC=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set +CONFIG_MICREL_PHY=y # CONFIG_WLAN is not set # CONFIG_INPUT is not set # CONFIG_SERIO is not set @@ -55,11 +51,9 @@ CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_OF_PLATFORM=y # CONFIG_HW_RANDOM is not set # CONFIG_HWMON is not set -# CONFIG_MFD_SUPPORT is not set # CONFIG_USB_SUPPORT is not set # CONFIG_DNOTIFY is not set CONFIG_TMPFS=y CONFIG_NFS_FS=y -CONFIG_NFS_V3=y # CONFIG_ENABLE_WARN_DEPRECATED is not set # CONFIG_ENABLE_MUST_CHECK is not set diff --git a/arch/openrisc/include/asm/Kbuild b/arch/openrisc/include/asm/Kbuild index 195653e851da..da1951a22907 100644 --- a/arch/openrisc/include/asm/Kbuild +++ b/arch/openrisc/include/asm/Kbuild @@ -65,5 +65,7 @@ generic-y += trace_clock.h generic-y += types.h generic-y += ucontext.h generic-y += user.h +generic-y += vga.h generic-y += word-at-a-time.h generic-y += xor.h +generic-y += preempt.h diff --git a/arch/openrisc/include/asm/pgalloc.h b/arch/openrisc/include/asm/pgalloc.h index 05c39ecd2efd..21484e5b9e9a 100644 --- a/arch/openrisc/include/asm/pgalloc.h +++ b/arch/openrisc/include/asm/pgalloc.h @@ -78,8 +78,13 @@ static inline struct page *pte_alloc_one(struct mm_struct *mm, { struct page *pte; pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT, 0); - if (pte) - clear_page(page_address(pte)); + if (!pte) + return NULL; + clear_page(page_address(pte)); + if (!pgtable_page_ctor(pte)) { + __free_page(pte); + return NULL; + } return pte; } @@ -90,6 +95,7 @@ static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) static inline void pte_free(struct mm_struct *mm, struct page *pte) { + pgtable_page_dtor(pte); __free_page(pte); } diff --git a/arch/openrisc/include/asm/prom.h b/arch/openrisc/include/asm/prom.h deleted file mode 100644 index 93c9980e1b6b..000000000000 --- a/arch/openrisc/include/asm/prom.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * OpenRISC Linux - * - * Linux architectural port borrowing liberally from similar works of - * others. All original copyrights apply as per the original source - * declaration. - * - * OpenRISC implementation: - * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se> - * et al. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ -#ifndef _ASM_OPENRISC_PROM_H -#define _ASM_OPENRISC_PROM_H - -#define HAVE_ARCH_DEVTREE_FIXUPS - -#endif /* _ASM_OPENRISC_PROM_H */ diff --git a/arch/openrisc/kernel/module.c b/arch/openrisc/kernel/module.c index 10ff50f0202a..ef872ae4c878 100644 --- a/arch/openrisc/kernel/module.c +++ b/arch/openrisc/kernel/module.c @@ -47,12 +47,10 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, *location = value; break; case R_OR32_CONST: - location = (uint16_t *)location + 1; - *((uint16_t *)location) = (uint16_t) (value); + *((uint16_t *)location + 1) = value; break; case R_OR32_CONSTH: - location = (uint16_t *)location + 1; - *((uint16_t *)location) = (uint16_t) (value >> 16); + *((uint16_t *)location + 1) = value >> 16; break; case R_OR32_JUMPTARG: value -= (uint32_t)location; diff --git a/arch/openrisc/kernel/prom.c b/arch/openrisc/kernel/prom.c index a63e76872f84..6a44340d1b18 100644 --- a/arch/openrisc/kernel/prom.c +++ b/arch/openrisc/kernel/prom.c @@ -18,83 +18,15 @@ * */ -#include <stdarg.h> -#include <linux/kernel.h> -#include <linux/string.h> #include <linux/init.h> -#include <linux/threads.h> -#include <linux/spinlock.h> #include <linux/types.h> -#include <linux/pci.h> -#include <linux/stringify.h> -#include <linux/delay.h> -#include <linux/initrd.h> -#include <linux/bitops.h> -#include <linux/module.h> -#include <linux/kexec.h> -#include <linux/debugfs.h> -#include <linux/irq.h> #include <linux/memblock.h> #include <linux/of_fdt.h> -#include <asm/prom.h> #include <asm/page.h> -#include <asm/processor.h> -#include <asm/irq.h> -#include <linux/io.h> -#include <asm/mmu.h> -#include <asm/pgtable.h> -#include <asm/sections.h> -#include <asm/setup.h> - -extern char cmd_line[COMMAND_LINE_SIZE]; - -void __init early_init_dt_add_memory_arch(u64 base, u64 size) -{ - size &= PAGE_MASK; - memblock_add(base, size); -} void __init early_init_devtree(void *params) { - void *alloc; - - /* Setup flat device-tree pointer */ - initial_boot_params = params; - - - /* Retrieve various informations from the /chosen node of the - * device-tree, including the platform type, initrd location and - * size, TCE reserve, and more ... - */ - of_scan_flat_dt(early_init_dt_scan_chosen, cmd_line); - - /* Scan memory nodes and rebuild MEMBLOCKs */ - of_scan_flat_dt(early_init_dt_scan_root, NULL); - of_scan_flat_dt(early_init_dt_scan_memory, NULL); - - /* Save command line for /proc/cmdline and then parse parameters */ - strlcpy(boot_command_line, cmd_line, COMMAND_LINE_SIZE); - + early_init_dt_scan(params); memblock_allow_resize(); - - /* We must copy the flattend device tree from init memory to regular - * memory because the device tree references the strings in it - * directly. - */ - - alloc = __va(memblock_alloc(initial_boot_params->totalsize, PAGE_SIZE)); - - memcpy(alloc, initial_boot_params, initial_boot_params->totalsize); - - initial_boot_params = alloc; -} - -#ifdef CONFIG_BLK_DEV_INITRD -void __init early_init_dt_setup_initrd_arch(u64 start, u64 end) -{ - initrd_start = (unsigned long)__va(start); - initrd_end = (unsigned long)__va(end); - initrd_below_start_ok = 1; } -#endif diff --git a/arch/openrisc/kernel/setup.c b/arch/openrisc/kernel/setup.c index d7359ffbcbdd..4fc7ccc0a2cf 100644 --- a/arch/openrisc/kernel/setup.c +++ b/arch/openrisc/kernel/setup.c @@ -40,6 +40,7 @@ #include <linux/device.h> #include <linux/of_platform.h> +#include <asm/sections.h> #include <asm/segment.h> #include <asm/pgtable.h> #include <asm/types.h> @@ -50,8 +51,6 @@ #include "vmlinux.h" -char __initdata cmd_line[COMMAND_LINE_SIZE] = CONFIG_CMDLINE; - static unsigned long __init setup_memory(void) { unsigned long bootmap_size; @@ -77,7 +76,7 @@ static unsigned long __init setup_memory(void) ram_start_pfn = PFN_UP(memory_start); /* free_ram_start_pfn is first page after kernel */ - free_ram_start_pfn = PFN_UP(__pa(&_end)); + free_ram_start_pfn = PFN_UP(__pa(_end)); ram_end_pfn = PFN_DOWN(memblock_end_of_DRAM()); max_pfn = ram_end_pfn; @@ -209,15 +208,15 @@ void __init setup_cpuinfo(void) * Falls back on built-in device tree in case null pointer is passed. */ -void __init or32_early_setup(unsigned int fdt) +void __init or32_early_setup(void *fdt) { - if (fdt) { - early_init_devtree((void*) fdt); - printk(KERN_INFO "FDT at 0x%08x\n", fdt); - } else { - early_init_devtree(__dtb_start); - printk(KERN_INFO "Compiled-in FDT at %p\n", __dtb_start); + if (fdt) + pr_info("FDT at %p\n", fdt); + else { + fdt = __dtb_start; + pr_info("Compiled-in FDT at %p\n", fdt); } + early_init_devtree(fdt); } static int __init openrisc_device_probe(void) @@ -285,15 +284,15 @@ void __init setup_arch(char **cmdline_p) { unsigned long max_low_pfn; - unflatten_device_tree(); + unflatten_and_copy_device_tree(); setup_cpuinfo(); /* process 1's initial memory region is the kernel code/data */ - init_mm.start_code = (unsigned long)&_stext; - init_mm.end_code = (unsigned long)&_etext; - init_mm.end_data = (unsigned long)&_edata; - init_mm.brk = (unsigned long)&_end; + init_mm.start_code = (unsigned long)_stext; + init_mm.end_code = (unsigned long)_etext; + init_mm.end_data = (unsigned long)_edata; + init_mm.brk = (unsigned long)_end; #ifdef CONFIG_BLK_DEV_INITRD initrd_start = (unsigned long)&__initrd_start; @@ -316,7 +315,7 @@ void __init setup_arch(char **cmdline_p) conswitchp = &dummy_con; #endif - *cmdline_p = cmd_line; + *cmdline_p = boot_command_line; printk(KERN_INFO "OpenRISC Linux -- http://openrisc.net\n"); } diff --git a/arch/openrisc/kernel/vmlinux.h b/arch/openrisc/kernel/vmlinux.h index ee842a2d3f36..70b9ce41835c 100644 --- a/arch/openrisc/kernel/vmlinux.h +++ b/arch/openrisc/kernel/vmlinux.h @@ -1,10 +1,8 @@ #ifndef __OPENRISC_VMLINUX_H_ #define __OPENRISC_VMLINUX_H_ -extern char _stext, _etext, _edata, _end; #ifdef CONFIG_BLK_DEV_INITRD extern char __initrd_start, __initrd_end; -extern char __initramfs_start; #endif extern u32 __dtb_start[]; diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index ad2ce8dab996..b5f1858baf33 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -1,6 +1,7 @@ config PARISC def_bool y select ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS + select ARCH_MIGHT_HAVE_PC_PARPORT select HAVE_IDE select HAVE_OPROFILE select HAVE_FUNCTION_TRACER if 64BIT @@ -226,7 +227,6 @@ endchoice config SMP bool "Symmetric multi-processing support" - select USE_GENERIC_SMP_HELPERS ---help--- This enables support for systems with more than one CPU. If you have a system with only one CPU, like most personal computers, say N. If @@ -287,6 +287,9 @@ config SYSVIPC_COMPAT def_bool y depends on COMPAT && SYSVIPC +config AUDIT_ARCH + def_bool y + config HPUX bool "Support for HP-UX binaries" depends on !64BIT diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile index e02f665f804a..7187664034c3 100644 --- a/arch/parisc/Makefile +++ b/arch/parisc/Makefile @@ -94,7 +94,7 @@ PALOCONF := $(shell if [ -f $(src)/palo.conf ]; then echo $(src)/palo.conf; \ else echo $(obj)/palo.conf; \ fi) -palo: vmlinuz +palo lifimage: vmlinuz @if test ! -x "$(PALO)"; then \ echo 'ERROR: Please install palo first (apt-get install palo)';\ echo 'or build it from source and install it somewhere in your $$PATH';\ @@ -109,16 +109,23 @@ palo: vmlinuz fi $(PALO) -f $(PALOCONF) -# Shorthands for known targets not supported by parisc, use vmlinux/vmlinuz as default +BOOT_TARGETS = zImage Image palo lifimage +INSTALL_TARGETS = zinstall install + +PHONY += bzImage $(BOOT_TARGETS) $(INSTALL_TARGETS) + +bzImage zImage: vmlinuz Image: vmlinux -zImage bzImage: vmlinuz vmlinuz: vmlinux @gzip -cf -9 $< > $@ -install: vmlinuz - sh $(src)/arch/parisc/install.sh \ - $(KERNELRELEASE) $< System.map "$(INSTALL_PATH)" +install: + $(CONFIG_SHELL) $(src)/arch/parisc/install.sh \ + $(KERNELRELEASE) vmlinux System.map "$(INSTALL_PATH)" +zinstall: + $(CONFIG_SHELL) $(src)/arch/parisc/install.sh \ + $(KERNELRELEASE) vmlinuz System.map "$(INSTALL_PATH)" CLEAN_FILES += lifimage MRPROPER_FILES += palo.conf @@ -127,10 +134,11 @@ define archhelp @echo '* vmlinux - Uncompressed kernel image (./vmlinux)' @echo ' vmlinuz - Compressed kernel image (./vmlinuz)' @echo ' palo - Bootable image (./lifimage)' - @echo ' install - Install kernel using' + @echo ' install - Install uncompressed vmlinux kernel using' @echo ' (your) ~/bin/$(INSTALLKERNEL) or' @echo ' (distribution) /sbin/$(INSTALLKERNEL) or' @echo ' copy to $$(INSTALL_PATH)' + @echo ' zinstall - Install compressed vmlinuz kernel' endef # we require gcc 3.3 or above to compile the kernel diff --git a/arch/parisc/configs/generic-32bit_defconfig b/arch/parisc/configs/generic-32bit_defconfig new file mode 100644 index 000000000000..33b148f825ba --- /dev/null +++ b/arch/parisc/configs/generic-32bit_defconfig @@ -0,0 +1,328 @@ +CONFIG_LOCALVERSION="-32bit" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_FHANDLE=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=16 +CONFIG_BLK_DEV_INITRD=y +CONFIG_RD_BZIP2=y +CONFIG_RD_LZMA=y +CONFIG_RD_LZO=y +CONFIG_EXPERT=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_PERF_EVENTS=y +CONFIG_SLAB=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +# CONFIG_LBDAF is not set +# CONFIG_BLK_DEV_BSG is not set +CONFIG_PA7100LC=y +CONFIG_SMP=y +CONFIG_HZ_100=y +CONFIG_IOMMU_CCIO=y +CONFIG_GSC_LASI=y +CONFIG_GSC_WAX=y +CONFIG_EISA=y +CONFIG_PCI=y +CONFIG_GSC_DINO=y +CONFIG_PCI_LBA=y +CONFIG_PCCARD=m +CONFIG_YENTA=m +# CONFIG_PDC_CHASSIS is not set +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_BINFMT_MISC=m +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_XFRM_USER=m +CONFIG_NET_KEY=m +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=m +CONFIG_LLC2=m +# CONFIG_WIRELESS is not set +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +# CONFIG_STANDALONE is not set +# CONFIG_PREVENT_FIRMWARE_BUILD is not set +CONFIG_PARPORT=y +CONFIG_PARPORT_PC=m +CONFIG_PARPORT_1284=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_CRYPTOLOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=6144 +CONFIG_IDE=y +CONFIG_BLK_DEV_IDECD=y +CONFIG_BLK_DEV_GENERIC=y +CONFIG_BLK_DEV_NS87415=y +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_ST=y +CONFIG_BLK_DEV_SR=y +CONFIG_CHR_DEV_SG=y +CONFIG_SCSI_LASI700=y +CONFIG_SCSI_SYM53C8XX_2=y +CONFIG_SCSI_ZALON=y +CONFIG_SCSI_DH=y +CONFIG_ATA=y +CONFIG_MD=y +CONFIG_BLK_DEV_MD=m +CONFIG_MD_LINEAR=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +CONFIG_BLK_DEV_DM=y +CONFIG_DM_UEVENT=y +CONFIG_NETDEVICES=y +CONFIG_BONDING=m +CONFIG_DUMMY=m +CONFIG_TUN=m +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_NET_VENDOR_ADAPTEC is not set +# CONFIG_NET_VENDOR_ALTEON is not set +# CONFIG_NET_VENDOR_AMD is not set +# CONFIG_NET_VENDOR_ATHEROS is not set +# CONFIG_NET_CADENCE is not set +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_NET_VENDOR_BROCADE is not set +# CONFIG_NET_VENDOR_CHELSIO is not set +# CONFIG_NET_VENDOR_CISCO is not set +CONFIG_NET_TULIP=y +CONFIG_TULIP=y +# CONFIG_NET_VENDOR_DLINK is not set +# CONFIG_NET_VENDOR_EMULEX is not set +# CONFIG_NET_VENDOR_EXAR is not set +# CONFIG_NET_VENDOR_HP is not set +CONFIG_LASI_82596=y +# CONFIG_NET_VENDOR_MELLANOX is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_MYRI is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_NVIDIA is not set +# CONFIG_NET_VENDOR_OKI is not set +# CONFIG_NET_PACKET_ENGINE is not set +# CONFIG_NET_VENDOR_QLOGIC is not set +# CONFIG_NET_VENDOR_REALTEK is not set +# CONFIG_NET_VENDOR_RDC is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SILAN is not set +# CONFIG_NET_VENDOR_SIS is not set +# CONFIG_NET_VENDOR_STMICRO is not set +# CONFIG_NET_VENDOR_SUN is not set +# CONFIG_NET_VENDOR_TEHUTI is not set +# CONFIG_NET_VENDOR_TI is not set +# CONFIG_NET_VENDOR_VIA is not set +CONFIG_PPP=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPPOE=m +# CONFIG_WLAN is not set +CONFIG_INPUT_POLLDEV=y +CONFIG_KEYBOARD_HIL_OLD=m +CONFIG_KEYBOARD_HIL=m +CONFIG_MOUSE_SERIAL=y +CONFIG_INPUT_MISC=y +CONFIG_INPUT_UINPUT=m +CONFIG_LEGACY_PTY_COUNT=64 +CONFIG_SERIAL_8250=y +# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=8 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_PRINTER=m +CONFIG_PPDEV=m +# CONFIG_HW_RANDOM is not set +CONFIG_I2C=y +CONFIG_POWER_SUPPLY=y +# CONFIG_HWMON is not set +CONFIG_AGP=y +CONFIG_VIDEO_OUTPUT_CONTROL=y +CONFIG_FB=y +CONFIG_FB_FOREIGN_ENDIAN=y +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_MATROX=m +CONFIG_FB_MATROX_G=y +CONFIG_FB_VOODOO1=m +CONFIG_DUMMY_CONSOLE_COLUMNS=128 +CONFIG_DUMMY_CONSOLE_ROWS=48 +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +# CONFIG_LOGO_LINUX_CLUT224 is not set +CONFIG_SOUND=m +CONFIG_SND=m +CONFIG_SND_SEQUENCER=m +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_DYNAMIC_MINORS=y +CONFIG_SND_AD1889=m +CONFIG_SND_HARMONY=m +CONFIG_HIDRAW=y +CONFIG_HID_A4TECH=y +CONFIG_HID_APPLE=y +CONFIG_HID_BELKIN=y +CONFIG_HID_CHERRY=y +CONFIG_HID_CHICONY=y +CONFIG_HID_CYPRESS=y +CONFIG_HID_DRAGONRISE=y +CONFIG_HID_EZKEY=y +CONFIG_HID_KYE=y +CONFIG_HID_GYRATION=y +CONFIG_HID_TWINHAN=y +CONFIG_HID_KENSINGTON=y +CONFIG_HID_LOGITECH=y +CONFIG_HID_LOGITECH_DJ=m +CONFIG_HID_MICROSOFT=y +CONFIG_HID_MONTEREY=y +CONFIG_HID_NTRIG=y +CONFIG_HID_ORTEK=y +CONFIG_HID_PANTHERLORD=y +CONFIG_HID_PETALYNX=y +CONFIG_HID_SAMSUNG=y +CONFIG_HID_SONY=y +CONFIG_HID_SUNPLUS=y +CONFIG_HID_GREENASIA=y +CONFIG_HID_SMARTJOYPLUS=y +CONFIG_HID_TOPSEED=y +CONFIG_HID_THRUSTMASTER=y +CONFIG_HID_ZEROPLUS=y +CONFIG_USB=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +CONFIG_USB_MON=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_UHCI_HCD=y +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_IDE_DISK=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y +CONFIG_DMADEVICES=y +CONFIG_AUXDISPLAY=y +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +CONFIG_EXT3_FS_SECURITY=y +CONFIG_EXT4_FS=y +CONFIG_XFS_FS=m +CONFIG_XFS_QUOTA=y +CONFIG_XFS_RT=y +CONFIG_QUOTA=y +CONFIG_QUOTA_NETLINK_INTERFACE=y +CONFIG_QFMT_V2=y +CONFIG_AUTOFS4_FS=y +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_VFAT_FS=y +CONFIG_PROC_KCORE=y +CONFIG_TMPFS=y +CONFIG_TMPFS_XATTR=y +CONFIG_NFS_FS=m +# CONFIG_NFS_V2 is not set +CONFIG_NFSD=m +CONFIG_NFSD_V3=y +CONFIG_CIFS=m +CONFIG_CIFS_WEAK_PW_HASH=y +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y +# CONFIG_CIFS_DEBUG is not set +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_CODEPAGE_1250=y +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ASCII=m +CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=y +CONFIG_UNUSED_SYMBOLS=y +CONFIG_DEBUG_FS=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_MEMORY_INIT=y +CONFIG_DEBUG_STACKOVERFLOW=y +CONFIG_DEBUG_SHIRQ=y +CONFIG_DETECT_HUNG_TASK=y +CONFIG_TIMER_STATS=y +CONFIG_DEBUG_RT_MUTEXES=y +CONFIG_RT_MUTEX_TESTER=y +CONFIG_DEBUG_SPINLOCK=y +CONFIG_DEBUG_MUTEXES=y +CONFIG_RCU_CPU_STALL_INFO=y +CONFIG_LATENCYTOP=y +CONFIG_LKDTM=m +CONFIG_KEYS=y +CONFIG_KEYS_DEBUG_PROC_KEYS=y +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_TEST=m +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_DEFLATE=y +# CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRC_CCITT=m +CONFIG_CRC_T10DIF=y +CONFIG_FONTS=y diff --git a/arch/parisc/configs/generic-64bit_defconfig b/arch/parisc/configs/generic-64bit_defconfig new file mode 100644 index 000000000000..5874cebee077 --- /dev/null +++ b/arch/parisc/configs/generic-64bit_defconfig @@ -0,0 +1,346 @@ +CONFIG_LOCALVERSION="-64bit" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_TASKSTATS=y +CONFIG_TASK_DELAY_ACCT=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +# CONFIG_UTS_NS is not set +# CONFIG_IPC_NS is not set +# CONFIG_PID_NS is not set +# CONFIG_NET_NS is not set +CONFIG_RELAY=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +# CONFIG_COMPAT_BRK is not set +CONFIG_MODULES=y +CONFIG_MODULE_FORCE_LOAD=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_BLK_DEV_INTEGRITY=y +# CONFIG_IOSCHED_DEADLINE is not set +CONFIG_PA8X00=y +CONFIG_MLONGCALLS=y +CONFIG_64BIT=y +CONFIG_SMP=y +# CONFIG_COMPACTION is not set +CONFIG_HPPB=y +CONFIG_IOMMU_CCIO=y +CONFIG_GSC_LASI=y +CONFIG_GSC_WAX=y +CONFIG_PCI=y +CONFIG_PCI_STUB=m +CONFIG_PCI_IOV=y +CONFIG_GSC_DINO=y +CONFIG_PCI_LBA=y +CONFIG_BINFMT_MISC=m +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_XFRM_USER=m +CONFIG_XFRM_SUB_POLICY=y +CONFIG_XFRM_MIGRATE=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_LRO=m +CONFIG_INET_DIAG=m +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_ADVANCED is not set +CONFIG_NETFILTER_NETLINK_LOG=y +CONFIG_DCB=y +# CONFIG_WIRELESS is not set +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_IDE=y +CONFIG_IDE_GD=m +CONFIG_IDE_GD_ATAPI=y +CONFIG_BLK_DEV_IDECD=m +CONFIG_BLK_DEV_NS87415=y +CONFIG_BLK_DEV_SIIMAGE=y +# CONFIG_SCSI_PROC_FS is not set +CONFIG_BLK_DEV_SD=y +CONFIG_BLK_DEV_SR=y +CONFIG_SCSI_ISCSI_ATTRS=y +CONFIG_SCSI_SRP_ATTRS=y +CONFIG_ISCSI_BOOT_SYSFS=y +CONFIG_SCSI_MPT2SAS=y +CONFIG_SCSI_LASI700=m +CONFIG_SCSI_SYM53C8XX_2=y +CONFIG_SCSI_ZALON=y +CONFIG_SCSI_QLA_ISCSI=m +CONFIG_SCSI_DH=y +CONFIG_ATA=y +CONFIG_ATA_GENERIC=y +CONFIG_MD=y +CONFIG_MD_LINEAR=m +CONFIG_MD_RAID0=m +CONFIG_BLK_DEV_DM=m +CONFIG_DM_RAID=m +CONFIG_DM_UEVENT=y +CONFIG_FUSION=y +CONFIG_FUSION_SPI=y +CONFIG_FUSION_SAS=y +CONFIG_NETDEVICES=y +CONFIG_DUMMY=m +CONFIG_MACVLAN=m +CONFIG_MACVTAP=m +CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE_DYNAMIC=y +CONFIG_TUN=y +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_NET_VENDOR_ADAPTEC is not set +# CONFIG_NET_VENDOR_ALTEON is not set +# CONFIG_NET_VENDOR_AMD is not set +# CONFIG_NET_VENDOR_ATHEROS is not set +# CONFIG_NET_CADENCE is not set +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_NET_VENDOR_BROCADE is not set +# CONFIG_NET_VENDOR_CHELSIO is not set +# CONFIG_NET_VENDOR_CISCO is not set +CONFIG_NET_TULIP=y +CONFIG_TULIP=y +# CONFIG_NET_VENDOR_DLINK is not set +# CONFIG_NET_VENDOR_EMULEX is not set +# CONFIG_NET_VENDOR_EXAR is not set +CONFIG_HP100=m +CONFIG_E1000=y +CONFIG_LASI_82596=y +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MELLANOX is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_MYRI is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_NVIDIA is not set +# CONFIG_NET_VENDOR_OKI is not set +CONFIG_QLA3XXX=m +CONFIG_QLCNIC=m +CONFIG_QLGE=m +# CONFIG_NET_VENDOR_REALTEK is not set +# CONFIG_NET_VENDOR_RDC is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SILAN is not set +# CONFIG_NET_VENDOR_SIS is not set +# CONFIG_NET_VENDOR_SMSC is not set +# CONFIG_NET_VENDOR_STMICRO is not set +# CONFIG_NET_VENDOR_SUN is not set +# CONFIG_NET_VENDOR_TEHUTI is not set +# CONFIG_NET_VENDOR_TI is not set +# CONFIG_NET_VENDOR_VIA is not set +# CONFIG_NET_VENDOR_WIZNET is not set +CONFIG_PHYLIB=y +CONFIG_MARVELL_PHY=m +CONFIG_DAVICOM_PHY=m +CONFIG_QSEMI_PHY=m +CONFIG_LXT_PHY=m +CONFIG_CICADA_PHY=m +CONFIG_VITESSE_PHY=m +CONFIG_SMSC_PHY=m +CONFIG_BROADCOM_PHY=m +CONFIG_ICPLUS_PHY=m +CONFIG_REALTEK_PHY=m +CONFIG_NATIONAL_PHY=m +CONFIG_STE10XP=m +CONFIG_LSI_ET1011C_PHY=m +CONFIG_MDIO_BITBANG=m +CONFIG_SLIP=m +CONFIG_SLIP_COMPRESSED=y +CONFIG_SLIP_SMART=y +CONFIG_SLIP_MODE_SLIP6=y +# CONFIG_WLAN is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_KEYBOARD_HIL_OLD is not set +# CONFIG_KEYBOARD_HIL is not set +# CONFIG_INPUT_MOUSE is not set +CONFIG_INPUT_MISC=y +CONFIG_SERIO_SERPORT=m +# CONFIG_HP_SDC is not set +CONFIG_SERIO_RAW=m +CONFIG_DEVPTS_MULTIPLE_INSTANCES=y +# CONFIG_LEGACY_PTYS is not set +CONFIG_NOZOMI=m +# CONFIG_DEVKMEM is not set +CONFIG_SERIAL_8250=y +# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=8 +CONFIG_SERIAL_8250_RUNTIME_UARTS=8 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_JSM=m +CONFIG_IPMI_HANDLER=y +CONFIG_IPMI_DEVICE_INTERFACE=y +CONFIG_IPMI_SI=y +# CONFIG_HW_RANDOM is not set +CONFIG_TCG_TPM=m +CONFIG_TCG_ATMEL=m +CONFIG_PTP_1588_CLOCK=m +CONFIG_SENSORS_I5K_AMB=m +CONFIG_SENSORS_F71882FG=m +CONFIG_SENSORS_PC87427=m +CONFIG_SENSORS_VT1211=m +CONFIG_SENSORS_VT8231=m +CONFIG_SENSORS_W83627EHF=m +CONFIG_WATCHDOG=y +CONFIG_SOFT_WATCHDOG=m +CONFIG_SSB=m +CONFIG_SSB_DRIVER_PCICORE=y +CONFIG_HTC_PASIC3=m +CONFIG_LPC_SCH=m +CONFIG_MFD_SM501=m +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=m +CONFIG_REGULATOR_USERSPACE_CONSUMER=m +CONFIG_MEDIA_SUPPORT=m +CONFIG_AGP=y +CONFIG_AGP_PARISC=y +CONFIG_DRM=y +CONFIG_DRM_RADEON=y +CONFIG_DRM_RADEON_UMS=y +CONFIG_FIRMWARE_EDID=y +CONFIG_FB_MODE_HELPERS=y +CONFIG_BACKLIGHT_LCD_SUPPORT=y +# CONFIG_BACKLIGHT_GENERIC is not set +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +CONFIG_HID=m +CONFIG_HIDRAW=y +CONFIG_HID_DRAGONRISE=m +CONFIG_DRAGONRISE_FF=y +CONFIG_HID_KYE=m +CONFIG_HID_GYRATION=m +CONFIG_HID_TWINHAN=m +CONFIG_LOGITECH_FF=y +CONFIG_LOGIRUMBLEPAD2_FF=y +CONFIG_HID_NTRIG=m +CONFIG_HID_PANTHERLORD=m +CONFIG_PANTHERLORD_FF=y +CONFIG_HID_PETALYNX=m +CONFIG_HID_SAMSUNG=m +CONFIG_HID_SONY=m +CONFIG_HID_SUNPLUS=m +CONFIG_HID_GREENASIA=m +CONFIG_GREENASIA_FF=y +CONFIG_HID_SMARTJOYPLUS=m +CONFIG_SMARTJOYPLUS_FF=y +CONFIG_HID_TOPSEED=m +CONFIG_HID_THRUSTMASTER=m +CONFIG_THRUSTMASTER_FF=y +CONFIG_HID_ZEROPLUS=m +CONFIG_ZEROPLUS_FF=y +CONFIG_USB_HID=m +CONFIG_HID_PID=y +CONFIG_USB_HIDDEV=y +CONFIG_USB=y +CONFIG_USB_DEBUG=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +CONFIG_USB_DYNAMIC_MINORS=y +CONFIG_USB_MON=m +CONFIG_USB_WUSB_CBAF=m +CONFIG_USB_XHCI_HCD=m +CONFIG_USB_EHCI_HCD=m +CONFIG_USB_OHCI_HCD=m +CONFIG_USB_R8A66597_HCD=m +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m +CONFIG_USB_WDM=m +CONFIG_USB_TMC=m +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_ONESHOT=y +CONFIG_LEDS_TRIGGER_IDE_DISK=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=m +CONFIG_LEDS_TRIGGER_BACKLIGHT=m +CONFIG_LEDS_TRIGGER_DEFAULT_ON=m +CONFIG_UIO=y +CONFIG_UIO_PDRV_GENIRQ=m +CONFIG_UIO_AEC=m +CONFIG_UIO_SERCOS3=m +CONFIG_UIO_PCI_GENERIC=m +CONFIG_STAGING=y +# CONFIG_NET_VENDOR_SILICOM is not set +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_XFS_FS=m +CONFIG_BTRFS_FS=m +CONFIG_QUOTA=y +CONFIG_QUOTA_NETLINK_INTERFACE=y +CONFIG_QFMT_V2=y +CONFIG_AUTOFS4_FS=y +CONFIG_FUSE_FS=y +CONFIG_CUSE=y +CONFIG_ISO9660_FS=y +CONFIG_UDF_FS=y +CONFIG_VFAT_FS=m +CONFIG_PROC_KCORE=y +CONFIG_TMPFS=y +CONFIG_TMPFS_XATTR=y +CONFIG_CONFIGFS_FS=y +CONFIG_SYSV_FS=y +CONFIG_NFS_FS=m +CONFIG_NFS_V4=m +CONFIG_NFS_V4_1=y +CONFIG_NFSD=m +CONFIG_NFSD_V4=y +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ASCII=m +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_UTF8=m +CONFIG_PRINTK_TIME=y +CONFIG_STRIP_ASM_SYMS=y +CONFIG_UNUSED_SYMBOLS=y +CONFIG_DEBUG_FS=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_KERNEL=y +CONFIG_DEBUG_STACKOVERFLOW=y +CONFIG_LOCKUP_DETECTOR=y +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y +CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y +# CONFIG_SCHED_DEBUG is not set +CONFIG_TIMER_STATS=y +CONFIG_DEBUG_STRICT_USER_COPY_CHECKS=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_DEFLATE=m +# CONFIG_CRYPTO_HW is not set +CONFIG_CRC_CCITT=m +CONFIG_LIBCRC32C=y +CONFIG_XZ_DEC_X86=y +CONFIG_XZ_DEC_POWERPC=y +CONFIG_XZ_DEC_IA64=y +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_ARMTHUMB=y +CONFIG_XZ_DEC_SPARC=y diff --git a/arch/parisc/include/asm/Kbuild b/arch/parisc/include/asm/Kbuild index ff4c9faed546..a603b9ebe54c 100644 --- a/arch/parisc/include/asm/Kbuild +++ b/arch/parisc/include/asm/Kbuild @@ -4,3 +4,4 @@ generic-y += word-at-a-time.h auxvec.h user.h cputime.h emergency-restart.h \ div64.h irq_regs.h kdebug.h kvm_para.h local64.h local.h param.h \ poll.h xor.h clkdev.h exec.h generic-y += trace_clock.h +generic-y += preempt.h diff --git a/arch/parisc/include/asm/assembly.h b/arch/parisc/include/asm/assembly.h index 0da848232344..b3069fd83468 100644 --- a/arch/parisc/include/asm/assembly.h +++ b/arch/parisc/include/asm/assembly.h @@ -515,5 +515,17 @@ nop /* 7 */ .endm + /* + * ASM_EXCEPTIONTABLE_ENTRY + * + * Creates an exception table entry. + * Do not convert to a assembler macro. This won't work. + */ +#define ASM_EXCEPTIONTABLE_ENTRY(fault_addr, except_addr) \ + .section __ex_table,"aw" ! \ + ASM_ULONG_INSN fault_addr, except_addr ! \ + .previous + + #endif /* __ASSEMBLY__ */ #endif diff --git a/arch/parisc/include/asm/delay.h b/arch/parisc/include/asm/delay.h index 912ee7e6a579..08e58e679e3e 100644 --- a/arch/parisc/include/asm/delay.h +++ b/arch/parisc/include/asm/delay.h @@ -1,15 +1,5 @@ -#ifndef _PARISC_DELAY_H -#define _PARISC_DELAY_H - -#include <asm/special_insns.h> /* for mfctl() */ -#include <asm/processor.h> /* for boot_cpu_data */ - - -/* - * Copyright (C) 1993 Linus Torvalds - * - * Delay routines - */ +#ifndef _ASM_PARISC_DELAY_H +#define _ASM_PARISC_DELAY_H static __inline__ void __delay(unsigned long loops) { asm volatile( @@ -19,25 +9,14 @@ static __inline__ void __delay(unsigned long loops) { : "=r" (loops) : "0" (loops)); } -static __inline__ void __cr16_delay(unsigned long clocks) { - unsigned long start; - - /* - * Note: Due to unsigned math, cr16 rollovers shouldn't be - * a problem here. However, on 32 bit, we need to make sure - * we don't pass in too big a value. The current default - * value of MAX_UDELAY_MS should help prevent this. - */ +extern void __udelay(unsigned long usecs); +extern void __udelay_bad(unsigned long usecs); - start = mfctl(16); - while ((mfctl(16) - start) < clocks) - ; +static inline void udelay(unsigned long usecs) +{ + if (__builtin_constant_p(usecs) && (usecs) > 20000) + __udelay_bad(usecs); + __udelay(usecs); } -static __inline__ void __udelay(unsigned long usecs) { - __cr16_delay(usecs * ((unsigned long)boot_cpu_data.cpu_hz / 1000000UL)); -} - -#define udelay(n) __udelay(n) - -#endif /* defined(_PARISC_DELAY_H) */ +#endif /* _ASM_PARISC_DELAY_H */ diff --git a/arch/parisc/include/asm/hardirq.h b/arch/parisc/include/asm/hardirq.h index 241c34518465..9b3bd039a609 100644 --- a/arch/parisc/include/asm/hardirq.h +++ b/arch/parisc/include/asm/hardirq.h @@ -21,7 +21,6 @@ typedef struct { unsigned int irq_stack_usage; #ifdef CONFIG_SMP unsigned int irq_resched_count; - unsigned int irq_call_count; #endif unsigned int irq_unaligned_count; unsigned int irq_fpassist_count; diff --git a/arch/parisc/include/asm/pgalloc.h b/arch/parisc/include/asm/pgalloc.h index fc987a1c12a8..f213f5b4c423 100644 --- a/arch/parisc/include/asm/pgalloc.h +++ b/arch/parisc/include/asm/pgalloc.h @@ -121,8 +121,12 @@ static inline pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address) { struct page *page = alloc_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO); - if (page) - pgtable_page_ctor(page); + if (!page) + return NULL; + if (!pgtable_page_ctor(page)) { + __free_page(page); + return NULL; + } return page; } diff --git a/arch/parisc/include/asm/ptrace.h b/arch/parisc/include/asm/ptrace.h index a2db278a5def..3c3cb004b7e2 100644 --- a/arch/parisc/include/asm/ptrace.h +++ b/arch/parisc/include/asm/ptrace.h @@ -19,5 +19,9 @@ #define user_stack_pointer(regs) ((regs)->gr[30]) unsigned long profile_pc(struct pt_regs *); +static inline unsigned long regs_return_value(struct pt_regs *regs) +{ + return regs->gr[20]; +} #endif diff --git a/arch/parisc/include/asm/thread_info.h b/arch/parisc/include/asm/thread_info.h index 540c88fa8f86..d5f97ea3a4e1 100644 --- a/arch/parisc/include/asm/thread_info.h +++ b/arch/parisc/include/asm/thread_info.h @@ -46,9 +46,6 @@ struct thread_info { #define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) #define THREAD_SHIFT (PAGE_SHIFT + THREAD_SIZE_ORDER) -#define PREEMPT_ACTIVE_BIT 28 -#define PREEMPT_ACTIVE (1 << PREEMPT_ACTIVE_BIT) - /* * thread information flags */ @@ -59,6 +56,7 @@ struct thread_info { #define TIF_32BIT 4 /* 32 bit binary */ #define TIF_MEMDIE 5 /* is terminating due to OOM killer */ #define TIF_RESTORE_SIGMASK 6 /* restore saved signal mask */ +#define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */ #define TIF_NOTIFY_RESUME 8 /* callback before returning to user */ #define TIF_SINGLESTEP 9 /* single stepping? */ #define TIF_BLOCKSTEP 10 /* branch stepping? */ @@ -68,6 +66,7 @@ struct thread_info { #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) #define _TIF_32BIT (1 << TIF_32BIT) +#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) #define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP) #define _TIF_BLOCKSTEP (1 << TIF_BLOCKSTEP) @@ -75,7 +74,7 @@ struct thread_info { #define _TIF_USER_WORK_MASK (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | \ _TIF_NEED_RESCHED) #define _TIF_SYSCALL_TRACE_MASK (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP | \ - _TIF_BLOCKSTEP) + _TIF_BLOCKSTEP | _TIF_SYSCALL_AUDIT) #endif /* __KERNEL__ */ diff --git a/arch/parisc/include/asm/uaccess.h b/arch/parisc/include/asm/uaccess.h index e0a82358517e..63f4dd0b49c2 100644 --- a/arch/parisc/include/asm/uaccess.h +++ b/arch/parisc/include/asm/uaccess.h @@ -4,11 +4,14 @@ /* * User space memory access functions */ +#include <asm/processor.h> #include <asm/page.h> #include <asm/cache.h> #include <asm/errno.h> #include <asm-generic/uaccess-unaligned.h> +#include <linux/sched.h> + #define VERIFY_READ 0 #define VERIFY_WRITE 1 @@ -33,12 +36,43 @@ extern int __get_user_bad(void); extern int __put_kernel_bad(void); extern int __put_user_bad(void); -static inline long access_ok(int type, const void __user * addr, - unsigned long size) + +/* + * Test whether a block of memory is a valid user space address. + * Returns 0 if the range is valid, nonzero otherwise. + */ +static inline int __range_not_ok(unsigned long addr, unsigned long size, + unsigned long limit) { - return 1; + unsigned long __newaddr = addr + size; + return (__newaddr < addr || __newaddr > limit || size > limit); } +/** + * access_ok: - Checks if a user space pointer is valid + * @type: Type of access: %VERIFY_READ or %VERIFY_WRITE. Note that + * %VERIFY_WRITE is a superset of %VERIFY_READ - if it is safe + * to write to a block, it is always safe to read from it. + * @addr: User space pointer to start of block to check + * @size: Size of block to check + * + * Context: User context only. This function may sleep. + * + * Checks if a pointer to a block of memory in user space is valid. + * + * Returns true (nonzero) if the memory block may be valid, false (zero) + * if it is definitely invalid. + * + * Note that, depending on architecture, this function probably just + * checks that the pointer is in the user space range - after calling + * this function, memory access functions may still return -EFAULT. + */ +#define access_ok(type, addr, size) \ +( __chk_user_ptr(addr), \ + !__range_not_ok((unsigned long) (__force void *) (addr), \ + size, user_addr_max()) \ +) + #define put_user __put_user #define get_user __get_user @@ -59,12 +93,13 @@ static inline long access_ok(int type, const void __user * addr, /* * The exception table contains two values: the first is an address * for an instruction that is allowed to fault, and the second is - * the address to the fixup routine. + * the address to the fixup routine. Even on a 64bit kernel we could + * use a 32bit (unsigned int) address here. */ struct exception_table_entry { - unsigned long insn; /* address of insn that is allowed to fault. */ - long fixup; /* fixup routine */ + unsigned long insn; /* address of insn that is allowed to fault. */ + unsigned long fixup; /* fixup routine */ }; #define ASM_EXCEPTIONTABLE_ENTRY( fault_addr, except_addr )\ @@ -218,7 +253,11 @@ extern long lstrnlen_user(const char __user *,long); /* * Complex access routines -- macros */ -#define user_addr_max() (~0UL) +#ifdef CONFIG_COMPAT +#define user_addr_max() (TASK_SIZE) +#else +#define user_addr_max() (DEFAULT_TASK_SIZE) +#endif #define strnlen_user lstrnlen_user #define strlen_user(str) lstrnlen_user(str, 0x7fffffffL) diff --git a/arch/parisc/include/uapi/asm/errno.h b/arch/parisc/include/uapi/asm/errno.h index 135ad6047e51..f3a8aa554841 100644 --- a/arch/parisc/include/uapi/asm/errno.h +++ b/arch/parisc/include/uapi/asm/errno.h @@ -37,7 +37,7 @@ #define EBADMSG 67 /* Not a data message */ #define EUSERS 68 /* Too many users */ #define EDQUOT 69 /* Quota exceeded */ -#define ESTALE 70 /* Stale NFS file handle */ +#define ESTALE 70 /* Stale file handle */ #define EREMOTE 71 /* Object is remote */ #define EOVERFLOW 72 /* Value too large for defined data type */ diff --git a/arch/parisc/include/uapi/asm/socket.h b/arch/parisc/include/uapi/asm/socket.h index 71700e636a8e..7c614d01f1fa 100644 --- a/arch/parisc/include/uapi/asm/socket.h +++ b/arch/parisc/include/uapi/asm/socket.h @@ -75,6 +75,8 @@ #define SO_BUSY_POLL 0x4027 +#define SO_MAX_PACING_RATE 0x4048 + /* O_NONBLOCK clashes with the bits used for socket types. Therefore we * have to define SOCK_NONBLOCK to a different value here. */ diff --git a/arch/parisc/install.sh b/arch/parisc/install.sh index 4da682b466d0..6f68784fea25 100644 --- a/arch/parisc/install.sh +++ b/arch/parisc/install.sh @@ -19,20 +19,48 @@ # $4 - default install path (blank if root directory) # +verify () { + if [ ! -f "$1" ]; then + echo "" 1>&2 + echo " *** Missing file: $1" 1>&2 + echo ' *** You need to run "make" before "make install".' 1>&2 + echo "" 1>&2 + exit 1 + fi +} + +# Make sure the files actually exist + +verify "$2" +verify "$3" + # User may have a custom install script -if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi -if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi +if [ -n "${INSTALLKERNEL}" ]; then + if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi + if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi +fi # Default install -if [ -f $4/vmlinuz ]; then - mv $4/vmlinuz $4/vmlinuz.old +if [ "$(basename $2)" = "zImage" ]; then +# Compressed install + echo "Installing compressed kernel" + base=vmlinuz +else +# Normal install + echo "Installing normal kernel" + base=vmlinux +fi + +if [ -f $4/$base-$1 ]; then + mv $4/$base-$1 $4/$base-$1.old fi +cat $2 > $4/$base-$1 -if [ -f $4/System.map ]; then - mv $4/System.map $4/System.old +# Install system map file +if [ -f $4/System.map-$1 ]; then + mv $4/System.map-$1 $4/System.map-$1.old fi +cp $3 $4/System.map-$1 -cat $2 > $4/vmlinuz -cp $3 $4/System.map diff --git a/arch/parisc/kernel/Makefile b/arch/parisc/kernel/Makefile index 66ee3f12df58..ff87b4603e3d 100644 --- a/arch/parisc/kernel/Makefile +++ b/arch/parisc/kernel/Makefile @@ -29,7 +29,9 @@ obj-$(CONFIG_PCI) += pci.o obj-$(CONFIG_MODULES) += module.o obj-$(CONFIG_64BIT) += binfmt_elf32.o sys_parisc32.o signal32.o obj-$(CONFIG_STACKTRACE)+= stacktrace.o +obj-$(CONFIG_AUDIT) += audit.o +obj64-$(CONFIG_AUDIT) += compat_audit.o # only supported for PCX-W/U in 64-bit mode at the moment -obj-$(CONFIG_64BIT) += perf.o perf_asm.o +obj-$(CONFIG_64BIT) += perf.o perf_asm.o $(obj64-y) obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o diff --git a/arch/parisc/kernel/audit.c b/arch/parisc/kernel/audit.c new file mode 100644 index 000000000000..eb64a6148c82 --- /dev/null +++ b/arch/parisc/kernel/audit.c @@ -0,0 +1,81 @@ +#include <linux/init.h> +#include <linux/types.h> +#include <linux/audit.h> +#include <asm/unistd.h> + +static unsigned dir_class[] = { +#include <asm-generic/audit_dir_write.h> +~0U +}; + +static unsigned read_class[] = { +#include <asm-generic/audit_read.h> +~0U +}; + +static unsigned write_class[] = { +#include <asm-generic/audit_write.h> +~0U +}; + +static unsigned chattr_class[] = { +#include <asm-generic/audit_change_attr.h> +~0U +}; + +static unsigned signal_class[] = { +#include <asm-generic/audit_signal.h> +~0U +}; + +int audit_classify_arch(int arch) +{ +#ifdef CONFIG_COMPAT + if (arch == AUDIT_ARCH_PARISC) + return 1; +#endif + return 0; +} + +int audit_classify_syscall(int abi, unsigned syscall) +{ +#ifdef CONFIG_COMPAT + extern int parisc32_classify_syscall(unsigned); + if (abi == AUDIT_ARCH_PARISC) + return parisc32_classify_syscall(syscall); +#endif + switch (syscall) { + case __NR_open: + return 2; + case __NR_openat: + return 3; + case __NR_execve: + return 5; + default: + return 0; + } +} + +static int __init audit_classes_init(void) +{ +#ifdef CONFIG_COMPAT + extern __u32 parisc32_dir_class[]; + extern __u32 parisc32_write_class[]; + extern __u32 parisc32_read_class[]; + extern __u32 parisc32_chattr_class[]; + extern __u32 parisc32_signal_class[]; + audit_register_class(AUDIT_CLASS_WRITE_32, parisc32_write_class); + audit_register_class(AUDIT_CLASS_READ_32, parisc32_read_class); + audit_register_class(AUDIT_CLASS_DIR_WRITE_32, parisc32_dir_class); + audit_register_class(AUDIT_CLASS_CHATTR_32, parisc32_chattr_class); + audit_register_class(AUDIT_CLASS_SIGNAL_32, parisc32_signal_class); +#endif + audit_register_class(AUDIT_CLASS_WRITE, write_class); + audit_register_class(AUDIT_CLASS_READ, read_class); + audit_register_class(AUDIT_CLASS_DIR_WRITE, dir_class); + audit_register_class(AUDIT_CLASS_CHATTR, chattr_class); + audit_register_class(AUDIT_CLASS_SIGNAL, signal_class); + return 0; +} + +__initcall(audit_classes_init); diff --git a/arch/parisc/kernel/compat_audit.c b/arch/parisc/kernel/compat_audit.c new file mode 100644 index 000000000000..c74478f6bc74 --- /dev/null +++ b/arch/parisc/kernel/compat_audit.c @@ -0,0 +1,40 @@ +#include <asm/unistd.h> + +unsigned int parisc32_dir_class[] = { +#include <asm-generic/audit_dir_write.h> +~0U +}; + +unsigned int parisc32_chattr_class[] = { +#include <asm-generic/audit_change_attr.h> +~0U +}; + +unsigned int parisc32_write_class[] = { +#include <asm-generic/audit_write.h> +~0U +}; + +unsigned int parisc32_read_class[] = { +#include <asm-generic/audit_read.h> +~0U +}; + +unsigned int parisc32_signal_class[] = { +#include <asm-generic/audit_signal.h> +~0U +}; + +int parisc32_classify_syscall(unsigned syscall) +{ + switch (syscall) { + case __NR_open: + return 2; + case __NR_openat: + return 3; + case __NR_execve: + return 5; + default: + return 1; + } +} diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c index 2e6443b1e922..8ceac4785609 100644 --- a/arch/parisc/kernel/irq.c +++ b/arch/parisc/kernel/irq.c @@ -179,10 +179,6 @@ int arch_show_interrupts(struct seq_file *p, int prec) for_each_online_cpu(j) seq_printf(p, "%10u ", irq_stats(j)->irq_resched_count); seq_puts(p, " Rescheduling interrupts\n"); - seq_printf(p, "%*s: ", prec, "CAL"); - for_each_online_cpu(j) - seq_printf(p, "%10u ", irq_stats(j)->irq_call_count); - seq_puts(p, " Function call interrupts\n"); #endif seq_printf(p, "%*s: ", prec, "UAH"); for_each_online_cpu(j) @@ -499,22 +495,9 @@ static void execute_on_irq_stack(void *func, unsigned long param1) *irq_stack_in_use = 1; } -asmlinkage void do_softirq(void) +void do_softirq_own_stack(void) { - __u32 pending; - unsigned long flags; - - if (in_interrupt()) - return; - - local_irq_save(flags); - - pending = local_softirq_pending(); - - if (pending) - execute_on_irq_stack(__do_softirq, 0); - - local_irq_restore(flags); + execute_on_irq_stack(__do_softirq, 0); } #endif /* CONFIG_IRQSTACKS */ diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c index 2a625fb063e1..50dfafc3f2c1 100644 --- a/arch/parisc/kernel/module.c +++ b/arch/parisc/kernel/module.c @@ -219,7 +219,7 @@ void *module_alloc(unsigned long size) * init_data correctly */ return __vmalloc_node_range(size, 1, VMALLOC_START, VMALLOC_END, GFP_KERNEL | __GFP_HIGHMEM, - PAGE_KERNEL_RWX, -1, + PAGE_KERNEL_RWX, NUMA_NO_NODE, __builtin_return_address(0)); } diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c index 534abd4936e1..e842ee233db4 100644 --- a/arch/parisc/kernel/ptrace.c +++ b/arch/parisc/kernel/ptrace.c @@ -19,6 +19,7 @@ #include <linux/security.h> #include <linux/compat.h> #include <linux/signal.h> +#include <linux/audit.h> #include <asm/uaccess.h> #include <asm/pgtable.h> @@ -267,11 +268,28 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, long do_syscall_trace_enter(struct pt_regs *regs) { + long ret = 0; + if (test_thread_flag(TIF_SYSCALL_TRACE) && tracehook_report_syscall_entry(regs)) - return -1L; - - return regs->gr[20]; + ret = -1L; + +#ifdef CONFIG_64BIT + if (!is_compat_task()) + audit_syscall_entry(AUDIT_ARCH_PARISC64, + regs->gr[20], + regs->gr[26], regs->gr[25], + regs->gr[24], regs->gr[23]); + else +#endif + audit_syscall_entry(AUDIT_ARCH_PARISC, + regs->gr[20] & 0xffffffff, + regs->gr[26] & 0xffffffff, + regs->gr[25] & 0xffffffff, + regs->gr[24] & 0xffffffff, + regs->gr[23] & 0xffffffff); + + return ret ? : regs->gr[20]; } void do_syscall_trace_exit(struct pt_regs *regs) @@ -279,6 +297,8 @@ void do_syscall_trace_exit(struct pt_regs *regs) int stepping = test_thread_flag(TIF_SINGLESTEP) || test_thread_flag(TIF_BLOCKSTEP); + audit_syscall_exit(regs); + if (stepping || test_thread_flag(TIF_SYSCALL_TRACE)) tracehook_report_syscall_exit(regs, stepping); } diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c index 7349a3fedfc7..72a3c658ad7b 100644 --- a/arch/parisc/kernel/setup.c +++ b/arch/parisc/kernel/setup.c @@ -318,8 +318,12 @@ static int __init parisc_init(void) pdc_stable_write(0x40, &osid, sizeof(osid)); processor_init(); - printk(KERN_INFO "CPU(s): %d x %s at %d.%06d MHz\n", - num_present_cpus(), +#ifdef CONFIG_SMP + pr_info("CPU(s): %d out of %d %s at %d.%06d MHz online\n", + num_online_cpus(), num_present_cpus(), +#else + pr_info("CPU(s): 1 x %s at %d.%06d MHz\n", +#endif boot_cpu_data.cpu_name, boot_cpu_data.cpu_hz / 1000000, boot_cpu_data.cpu_hz % 1000000 ); diff --git a/arch/parisc/kernel/signal32.c b/arch/parisc/kernel/signal32.c index 6c6a271a6140..984abbee71ca 100644 --- a/arch/parisc/kernel/signal32.c +++ b/arch/parisc/kernel/signal32.c @@ -319,7 +319,7 @@ copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from) } int -copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from) +copy_siginfo_to_user32 (compat_siginfo_t __user *to, const siginfo_t *from) { compat_uptr_t addr; compat_int_t val; diff --git a/arch/parisc/kernel/signal32.h b/arch/parisc/kernel/signal32.h index 72ab41a51f32..af51d4ccee42 100644 --- a/arch/parisc/kernel/signal32.h +++ b/arch/parisc/kernel/signal32.h @@ -34,7 +34,7 @@ struct compat_ucontext { /* ELF32 signal handling */ -int copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from); +int copy_siginfo_to_user32 (compat_siginfo_t __user *to, const siginfo_t *from); int copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from); /* In a deft move of uber-hackery, we decide to carry the top half of all diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c index 2b96602e812f..ceda229ea6c2 100644 --- a/arch/parisc/kernel/smp.c +++ b/arch/parisc/kernel/smp.c @@ -125,11 +125,6 @@ ipi_interrupt(int irq, void *dev_id) unsigned long ops; unsigned long flags; - /* Count this now; we may make a call that never returns. */ - inc_irq_stat(irq_call_count); - - mb(); /* Order interrupt and bit testing. */ - for (;;) { spinlock_t *lock = &per_cpu(ipi_lock, this_cpu); spin_lock_irqsave(lock, flags); diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S index e767ab733e32..a63bb179f79a 100644 --- a/arch/parisc/kernel/syscall.S +++ b/arch/parisc/kernel/syscall.S @@ -649,10 +649,8 @@ cas_action: /* Two exception table entries, one for the load, the other for the store. Either return -EFAULT. Each of the entries must be relocated. */ - .section __ex_table,"aw" - ASM_ULONG_INSN (1b - linux_gateway_page), (3b - linux_gateway_page) - ASM_ULONG_INSN (2b - linux_gateway_page), (3b - linux_gateway_page) - .previous + ASM_EXCEPTIONTABLE_ENTRY(1b-linux_gateway_page, 3b-linux_gateway_page) + ASM_EXCEPTIONTABLE_ENTRY(2b-linux_gateway_page, 3b-linux_gateway_page) /* Make sure nothing else is placed on this page */ diff --git a/arch/parisc/lib/Makefile b/arch/parisc/lib/Makefile index 5651536ac733..8fa92b8d839a 100644 --- a/arch/parisc/lib/Makefile +++ b/arch/parisc/lib/Makefile @@ -3,6 +3,6 @@ # lib-y := lusercopy.o bitops.o checksum.o io.o memset.o fixup.o memcpy.o \ - ucmpdi2.o + ucmpdi2.o delay.o obj-y := iomap.o diff --git a/arch/parisc/lib/delay.c b/arch/parisc/lib/delay.c new file mode 100644 index 000000000000..ec9255f27a81 --- /dev/null +++ b/arch/parisc/lib/delay.c @@ -0,0 +1,73 @@ +/* + * Precise Delay Loops for parisc + * + * based on code by: + * Copyright (C) 1993 Linus Torvalds + * Copyright (C) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz> + * Copyright (C) 2008 Jiri Hladky <hladky _dot_ jiri _at_ gmail _dot_ com> + * + * parisc implementation: + * Copyright (C) 2013 Helge Deller <deller@gmx.de> + */ + + +#include <linux/module.h> +#include <linux/preempt.h> +#include <linux/init.h> + +#include <asm/processor.h> +#include <asm/delay.h> + +#include <asm/special_insns.h> /* for mfctl() */ +#include <asm/processor.h> /* for boot_cpu_data */ + +/* CR16 based delay: */ +static void __cr16_delay(unsigned long __loops) +{ + /* + * Note: Due to unsigned math, cr16 rollovers shouldn't be + * a problem here. However, on 32 bit, we need to make sure + * we don't pass in too big a value. The current default + * value of MAX_UDELAY_MS should help prevent this. + */ + u32 bclock, now, loops = __loops; + int cpu; + + preempt_disable(); + cpu = smp_processor_id(); + bclock = mfctl(16); + for (;;) { + now = mfctl(16); + if ((now - bclock) >= loops) + break; + + /* Allow RT tasks to run */ + preempt_enable(); + asm volatile(" nop\n"); + barrier(); + preempt_disable(); + + /* + * It is possible that we moved to another CPU, and + * since CR16's are per-cpu we need to calculate + * that. The delay must guarantee that we wait "at + * least" the amount of time. Being moved to another + * CPU could make the wait longer but we just need to + * make sure we waited long enough. Rebalance the + * counter for this CPU. + */ + if (unlikely(cpu != smp_processor_id())) { + loops -= (now - bclock); + cpu = smp_processor_id(); + bclock = mfctl(16); + } + } + preempt_enable(); +} + + +void __udelay(unsigned long usecs) +{ + __cr16_delay(usecs * ((unsigned long)boot_cpu_data.cpu_hz / 1000000UL)); +} +EXPORT_SYMBOL(__udelay); diff --git a/arch/parisc/lib/lusercopy.S b/arch/parisc/lib/lusercopy.S index 6f2d9355efe2..a512f07d4feb 100644 --- a/arch/parisc/lib/lusercopy.S +++ b/arch/parisc/lib/lusercopy.S @@ -88,9 +88,7 @@ ENDPROC(lclear_user) ldo 1(%r25),%r25 .previous - .section __ex_table,"aw" - ASM_ULONG_INSN 1b,2b - .previous + ASM_EXCEPTIONTABLE_ENTRY(1b,2b) .procend @@ -129,10 +127,8 @@ ENDPROC(lstrnlen_user) copy %r24,%r26 /* reset r26 so 0 is returned on fault */ .previous - .section __ex_table,"aw" - ASM_ULONG_INSN 1b,3b - ASM_ULONG_INSN 2b,3b - .previous + ASM_EXCEPTIONTABLE_ENTRY(1b,3b) + ASM_EXCEPTIONTABLE_ENTRY(2b,3b) .procend diff --git a/arch/parisc/math-emu/float.h b/arch/parisc/math-emu/float.h index ce76f6dfa25b..7a51f97e72e6 100644 --- a/arch/parisc/math-emu/float.h +++ b/arch/parisc/math-emu/float.h @@ -484,7 +484,6 @@ typedef int VOID; * | |G|L|E|U|X| * +-------+-------+-------+-------+-------+-------+-------+-------+ */ -#define Allexception(object) (object) #define Greaterthanbit(object) Bitfield_extract( 27, 1,object) #define Lessthanbit(object) Bitfield_extract( 28, 1,object) #define Equalbit(object) Bitfield_extract( 29, 1,object) diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c index 0293588d5b8c..7584a5df0fa4 100644 --- a/arch/parisc/mm/fault.c +++ b/arch/parisc/mm/fault.c @@ -142,6 +142,12 @@ int fixup_exception(struct pt_regs *regs) { const struct exception_table_entry *fix; + /* If we only stored 32bit addresses in the exception table we can drop + * out if we faulted on a 64bit address. */ + if ((sizeof(regs->iaoq[0]) > sizeof(fix->insn)) + && (regs->iaoq[0] >> 32)) + return 0; + fix = search_exception_tables(regs->iaoq[0]); if (fix) { struct exception_data *d; @@ -274,12 +280,22 @@ bad_area: } show_regs(regs); #endif - /* FIXME: actually we need to get the signo and code correct */ - si.si_signo = SIGSEGV; + switch (code) { + case 15: /* Data TLB miss fault/Data page fault */ + case 17: /* NA data TLB miss / page fault */ + case 18: /* Unaligned access - PCXS only */ + si.si_signo = SIGBUS; + si.si_code = BUS_ADRERR; + break; + case 16: /* Non-access instruction TLB miss fault */ + case 26: /* PCXL: Data memory access rights trap */ + default: + si.si_signo = SIGSEGV; + si.si_code = SEGV_MAPERR; + } si.si_errno = 0; - si.si_code = SEGV_MAPERR; si.si_addr = (void __user *) address; - force_sig_info(SIGSEGV, &si, current); + force_sig_info(si.si_signo, &si, current); return; } diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 38f3b7e47ec5..b44b52c0a8f0 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -85,6 +85,7 @@ config GENERIC_HWEIGHT config PPC bool default y + select ARCH_MIGHT_HAVE_PC_PARPORT select BINFMT_ELF select OF select OF_EARLY_FLATTREE @@ -97,7 +98,7 @@ config PPC select VIRT_TO_BUS if !PPC64 select HAVE_IDE select HAVE_IOREMAP_PROT - select HAVE_EFFICIENT_UNALIGNED_ACCESS + select HAVE_EFFICIENT_UNALIGNED_ACCESS if !CPU_LITTLE_ENDIAN select HAVE_KPROBES select HAVE_ARCH_KGDB select HAVE_KRETPROBES @@ -106,7 +107,6 @@ config PPC select HAVE_MEMBLOCK_NODE_MAP select HAVE_DMA_ATTRS select HAVE_DMA_API_DEBUG - select USE_GENERIC_SMP_HELPERS if SMP select HAVE_OPROFILE select HAVE_DEBUG_KMEMLEAK select GENERIC_ATOMIC64 if PPC32 @@ -138,6 +138,10 @@ config PPC select OLD_SIGSUSPEND select OLD_SIGACTION if PPC32 select HAVE_DEBUG_STACKOVERFLOW + select HAVE_IRQ_EXIT_ON_IRQ_STACK + +config GENERIC_CSUM + def_bool CPU_LITTLE_ENDIAN config EARLY_PRINTK bool @@ -404,7 +408,7 @@ config CRASH_DUMP config FA_DUMP bool "Firmware-assisted dump" - depends on PPC64 && PPC_RTAS && CRASH_DUMP + depends on PPC64 && PPC_RTAS && CRASH_DUMP && KEXEC help A robust mechanism to get reliable kernel crash dump with assistance from firmware. This approach does not use kexec, @@ -417,7 +421,7 @@ config FA_DUMP config IRQ_ALL_CPUS bool "Distribute interrupts on all CPUs by default" - depends on SMP && !MV64360 + depends on SMP help This option gives the kernel permission to distribute IRQs across multiple CPUs. Saying N here will route all IRQs to the first @@ -1009,6 +1013,9 @@ config PHYSICAL_START default "0x00000000" endif +config ARCH_RANDOM + def_bool n + source "net/Kconfig" source "drivers/Kconfig" diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 51cfb78d4061..607acf54a425 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -36,17 +36,26 @@ KBUILD_DEFCONFIG := ppc64_defconfig endif ifeq ($(CONFIG_PPC64),y) -OLDARCH := ppc64 - new_nm := $(shell if $(NM) --help 2>&1 | grep -- '--synthetic' > /dev/null; then echo y; else echo n; fi) ifeq ($(new_nm),y) NM := $(NM) --synthetic endif +endif +ifeq ($(CONFIG_PPC64),y) +ifeq ($(CONFIG_CPU_LITTLE_ENDIAN),y) +OLDARCH := ppc64le +else +OLDARCH := ppc64 +endif +else +ifeq ($(CONFIG_CPU_LITTLE_ENDIAN),y) +OLDARCH := ppcle else OLDARCH := ppc endif +endif # It seems there are times we use this Makefile without # including the config file, but this replicates the old behaviour @@ -56,11 +65,29 @@ endif UTS_MACHINE := $(OLDARCH) +ifeq ($(CONFIG_CPU_LITTLE_ENDIAN),y) +override CC += -mlittle-endian -mno-strict-align +override AS += -mlittle-endian +override LD += -EL +override CROSS32CC += -mlittle-endian +override CROSS32AS += -mlittle-endian +LDEMULATION := lppc +GNUTARGET := powerpcle +MULTIPLEWORD := -mno-multiple +else +override CC += -mbig-endian +override AS += -mbig-endian +override LD += -EB +LDEMULATION := ppc +GNUTARGET := powerpc +MULTIPLEWORD := -mmultiple +endif + ifeq ($(HAS_BIARCH),y) override AS += -a$(CONFIG_WORD_SIZE) -override LD += -m elf$(CONFIG_WORD_SIZE)ppc +override LD += -m elf$(CONFIG_WORD_SIZE)$(LDEMULATION) override CC += -m$(CONFIG_WORD_SIZE) -override AR := GNUTARGET=elf$(CONFIG_WORD_SIZE)-powerpc $(AR) +override AR := GNUTARGET=elf$(CONFIG_WORD_SIZE)-$(GNUTARGET) $(AR) endif LDFLAGS_vmlinux-y := -Bstatic @@ -86,7 +113,7 @@ endif CFLAGS-$(CONFIG_PPC64) := -mtraceback=no -mcall-aixdesc CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mcmodel=medium,-mminimal-toc) CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mno-pointers-to-nested-functions) -CFLAGS-$(CONFIG_PPC32) := -ffixed-r2 -mmultiple +CFLAGS-$(CONFIG_PPC32) := -ffixed-r2 $(MULTIPLEWORD) ifeq ($(CONFIG_PPC_BOOK3S_64),y) CFLAGS-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=power7,-mtune=power4) diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index 15ca2255f438..ca7f08cc4afd 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -22,7 +22,8 @@ all: $(obj)/zImage BOOTCFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ -fno-strict-aliasing -Os -msoft-float -pipe \ -fomit-frame-pointer -fno-builtin -fPIC -nostdinc \ - -isystem $(shell $(CROSS32CC) -print-file-name=include) + -isystem $(shell $(CROSS32CC) -print-file-name=include) \ + -mbig-endian BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc ifdef CONFIG_DEBUG_INFO diff --git a/arch/powerpc/boot/dts/b4860emu.dts b/arch/powerpc/boot/dts/b4860emu.dts new file mode 100644 index 000000000000..7290021f2dfc --- /dev/null +++ b/arch/powerpc/boot/dts/b4860emu.dts @@ -0,0 +1,218 @@ +/* + * B4860 emulator Device Tree Source + * + * Copyright 2013 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * This software is provided by Freescale Semiconductor "as is" and any + * express or implied warranties, including, but not limited to, the implied + * warranties of merchantability and fitness for a particular purpose are + * disclaimed. In no event shall Freescale Semiconductor be liable for any + * direct, indirect, incidental, special, exemplary, or consequential damages + * (including, but not limited to, procurement of substitute goods or services; + * loss of use, data, or profits; or business interruption) however caused and + * on any theory of liability, whether in contract, strict liability, or tort + * (including negligence or otherwise) arising in any way out of the use of + * this software, even if advised of the possibility of such damage. + */ + +/dts-v1/; + +/include/ "fsl/e6500_power_isa.dtsi" + +/ { + compatible = "fsl,B4860"; + #address-cells = <2>; + #size-cells = <2>; + interrupt-parent = <&mpic>; + + aliases { + ccsr = &soc; + + serial0 = &serial0; + serial1 = &serial1; + serial2 = &serial2; + serial3 = &serial3; + dma0 = &dma0; + dma1 = &dma1; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: PowerPC,e6500@0 { + device_type = "cpu"; + reg = <0 1>; + next-level-cache = <&L2>; + }; + cpu1: PowerPC,e6500@2 { + device_type = "cpu"; + reg = <2 3>; + next-level-cache = <&L2>; + }; + cpu2: PowerPC,e6500@4 { + device_type = "cpu"; + reg = <4 5>; + next-level-cache = <&L2>; + }; + cpu3: PowerPC,e6500@6 { + device_type = "cpu"; + reg = <6 7>; + next-level-cache = <&L2>; + }; + }; +}; + +/ { + model = "fsl,B4860QDS"; + compatible = "fsl,B4860EMU", "fsl,B4860QDS"; + #address-cells = <2>; + #size-cells = <2>; + interrupt-parent = <&mpic>; + + ifc: localbus@ffe124000 { + reg = <0xf 0xfe124000 0 0x2000>; + ranges = <0 0 0xf 0xe8000000 0x08000000 + 2 0 0xf 0xff800000 0x00010000 + 3 0 0xf 0xffdf0000 0x00008000>; + + nor@0,0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "cfi-flash"; + reg = <0x0 0x0 0x8000000>; + bank-width = <2>; + device-width = <1>; + }; + }; + + memory { + device_type = "memory"; + }; + + soc: soc@ffe000000 { + ranges = <0x00000000 0xf 0xfe000000 0x1000000>; + reg = <0xf 0xfe000000 0 0x00001000>; + }; +}; + +&ifc { + #address-cells = <2>; + #size-cells = <1>; + compatible = "fsl,ifc", "simple-bus"; + interrupts = <25 2 0 0>; +}; + +&soc { + #address-cells = <1>; + #size-cells = <1>; + device_type = "soc"; + compatible = "simple-bus"; + + soc-sram-error { + compatible = "fsl,soc-sram-error"; + interrupts = <16 2 1 2>; + }; + + corenet-law@0 { + compatible = "fsl,corenet-law"; + reg = <0x0 0x1000>; + fsl,num-laws = <32>; + }; + + ddr1: memory-controller@8000 { + compatible = "fsl,qoriq-memory-controller-v4.5", "fsl,qoriq-memory-controller"; + reg = <0x8000 0x1000>; + interrupts = <16 2 1 8>; + }; + + ddr2: memory-controller@9000 { + compatible = "fsl,qoriq-memory-controller-v4.5","fsl,qoriq-memory-controller"; + reg = <0x9000 0x1000>; + interrupts = <16 2 1 9>; + }; + + cpc: l3-cache-controller@10000 { + compatible = "fsl,b4-l3-cache-controller", "cache"; + reg = <0x10000 0x1000 + 0x11000 0x1000>; + interrupts = <16 2 1 4>; + }; + + corenet-cf@18000 { + compatible = "fsl,b4-corenet-cf"; + reg = <0x18000 0x1000>; + interrupts = <16 2 1 0>; + fsl,ccf-num-csdids = <32>; + fsl,ccf-num-snoopids = <32>; + }; + + iommu@20000 { + compatible = "fsl,pamu-v1.0", "fsl,pamu"; + reg = <0x20000 0x4000>; + #address-cells = <1>; + #size-cells = <1>; + interrupts = < + 24 2 0 0 + 16 2 1 1>; + pamu0: pamu@0 { + reg = <0 0x1000>; + fsl,primary-cache-geometry = <8 1>; + fsl,secondary-cache-geometry = <32 2>; + }; + }; + +/include/ "fsl/qoriq-mpic.dtsi" + + guts: global-utilities@e0000 { + compatible = "fsl,b4-device-config"; + reg = <0xe0000 0xe00>; + fsl,has-rstcr; + fsl,liodn-bits = <12>; + }; + + clockgen: global-utilities@e1000 { + compatible = "fsl,b4-clockgen", "fsl,qoriq-clockgen-2.0"; + reg = <0xe1000 0x1000>; + }; + +/include/ "fsl/qoriq-dma-0.dtsi" + dma@100300 { + fsl,iommu-parent = <&pamu0>; + fsl,liodn-reg = <&guts 0x580>; /* DMA1LIODNR */ + }; + +/include/ "fsl/qoriq-dma-1.dtsi" + dma@101300 { + fsl,iommu-parent = <&pamu0>; + fsl,liodn-reg = <&guts 0x584>; /* DMA2LIODNR */ + }; + +/include/ "fsl/qoriq-i2c-0.dtsi" +/include/ "fsl/qoriq-i2c-1.dtsi" +/include/ "fsl/qoriq-duart-0.dtsi" +/include/ "fsl/qoriq-duart-1.dtsi" + + L2: l2-cache-controller@c20000 { + compatible = "fsl,b4-l2-cache-controller"; + reg = <0xc20000 0x1000>; + next-level-cache = <&cpc>; + }; +}; diff --git a/arch/powerpc/boot/dts/b4qds.dtsi b/arch/powerpc/boot/dts/b4qds.dtsi index e6d2f8f90544..8b47edcfabf0 100644 --- a/arch/powerpc/boot/dts/b4qds.dtsi +++ b/arch/powerpc/boot/dts/b4qds.dtsi @@ -120,25 +120,38 @@ }; i2c@118000 { - eeprom@50 { - compatible = "at24,24c64"; - reg = <0x50>; - }; - eeprom@51 { - compatible = "at24,24c256"; - reg = <0x51>; - }; - eeprom@53 { - compatible = "at24,24c256"; - reg = <0x53>; - }; - eeprom@57 { - compatible = "at24,24c256"; - reg = <0x57>; - }; - rtc@68 { - compatible = "dallas,ds3232"; - reg = <0x68>; + mux@77 { + compatible = "nxp,pca9547"; + reg = <0x77>; + #address-cells = <1>; + #size-cells = <0>; + + i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + eeprom@50 { + compatible = "at24,24c64"; + reg = <0x50>; + }; + eeprom@51 { + compatible = "at24,24c256"; + reg = <0x51>; + }; + eeprom@53 { + compatible = "at24,24c256"; + reg = <0x53>; + }; + eeprom@57 { + compatible = "at24,24c256"; + reg = <0x57>; + }; + rtc@68 { + compatible = "dallas,ds3232"; + reg = <0x68>; + }; + }; }; }; diff --git a/arch/powerpc/boot/dts/c293pcie.dts b/arch/powerpc/boot/dts/c293pcie.dts index 1238bda8901f..6681cc21030b 100644 --- a/arch/powerpc/boot/dts/c293pcie.dts +++ b/arch/powerpc/boot/dts/c293pcie.dts @@ -45,6 +45,7 @@ ifc: ifc@fffe1e000 { reg = <0xf 0xffe1e000 0 0x2000>; ranges = <0x0 0x0 0xf 0xec000000 0x04000000 + 0x1 0x0 0xf 0xff800000 0x00010000 0x2 0x0 0xf 0xffdf0000 0x00010000>; }; diff --git a/arch/powerpc/boot/dts/fsl/b4420si-pre.dtsi b/arch/powerpc/boot/dts/fsl/b4420si-pre.dtsi index 7b4426e0a5a5..c6e451affb05 100644 --- a/arch/powerpc/boot/dts/fsl/b4420si-pre.dtsi +++ b/arch/powerpc/boot/dts/fsl/b4420si-pre.dtsi @@ -34,6 +34,8 @@ /dts-v1/; +/include/ "e6500_power_isa.dtsi" + / { compatible = "fsl,B4420"; #address-cells = <2>; diff --git a/arch/powerpc/boot/dts/fsl/b4860si-post.dtsi b/arch/powerpc/boot/dts/fsl/b4860si-post.dtsi index e5cf6c81dd66..981397518fc6 100644 --- a/arch/powerpc/boot/dts/fsl/b4860si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/b4860si-post.dtsi @@ -41,7 +41,7 @@ &rio { compatible = "fsl,srio"; - interrupts = <16 2 1 11>; + interrupts = <16 2 1 20>; #address-cells = <2>; #size-cells = <2>; fsl,iommu-parent = <&pamu0>; diff --git a/arch/powerpc/boot/dts/fsl/b4860si-pre.dtsi b/arch/powerpc/boot/dts/fsl/b4860si-pre.dtsi index 5263fa46a3fb..9bc26b147900 100644 --- a/arch/powerpc/boot/dts/fsl/b4860si-pre.dtsi +++ b/arch/powerpc/boot/dts/fsl/b4860si-pre.dtsi @@ -34,6 +34,8 @@ /dts-v1/; +/include/ "e6500_power_isa.dtsi" + / { compatible = "fsl,B4860"; #address-cells = <2>; diff --git a/arch/powerpc/boot/dts/fsl/bsc9131si-post.dtsi b/arch/powerpc/boot/dts/fsl/bsc9131si-post.dtsi index 5180d9d37989..0c0efa94cfb4 100644 --- a/arch/powerpc/boot/dts/fsl/bsc9131si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/bsc9131si-post.dtsi @@ -130,7 +130,7 @@ usb@22000 { /include/ "pq3-esdhc-0.dtsi" sdhc@2e000 { - fsl,sdhci-auto-cmd12; + sdhci,auto-cmd12; interrupts = <41 0x2 0 0>; }; diff --git a/arch/powerpc/boot/dts/fsl/bsc9131si-pre.dtsi b/arch/powerpc/boot/dts/fsl/bsc9131si-pre.dtsi index 743e4aeda349..f6ec4a67560c 100644 --- a/arch/powerpc/boot/dts/fsl/bsc9131si-pre.dtsi +++ b/arch/powerpc/boot/dts/fsl/bsc9131si-pre.dtsi @@ -33,6 +33,9 @@ */ /dts-v1/; + +/include/ "e500v2_power_isa.dtsi" + / { compatible = "fsl,BSC9131"; #address-cells = <2>; diff --git a/arch/powerpc/boot/dts/t4240emu.dts b/arch/powerpc/boot/dts/t4240emu.dts new file mode 100644 index 000000000000..ee24ab335598 --- /dev/null +++ b/arch/powerpc/boot/dts/t4240emu.dts @@ -0,0 +1,268 @@ +/* + * T4240 emulator Device Tree Source + * + * Copyright 2013 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/dts-v1/; + +/include/ "fsl/e6500_power_isa.dtsi" +/ { + compatible = "fsl,T4240"; + #address-cells = <2>; + #size-cells = <2>; + interrupt-parent = <&mpic>; + + aliases { + ccsr = &soc; + + serial0 = &serial0; + serial1 = &serial1; + serial2 = &serial2; + serial3 = &serial3; + dma0 = &dma0; + dma1 = &dma1; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: PowerPC,e6500@0 { + device_type = "cpu"; + reg = <0 1>; + next-level-cache = <&L2_1>; + }; + cpu1: PowerPC,e6500@2 { + device_type = "cpu"; + reg = <2 3>; + next-level-cache = <&L2_1>; + }; + cpu2: PowerPC,e6500@4 { + device_type = "cpu"; + reg = <4 5>; + next-level-cache = <&L2_1>; + }; + cpu3: PowerPC,e6500@6 { + device_type = "cpu"; + reg = <6 7>; + next-level-cache = <&L2_1>; + }; + + cpu4: PowerPC,e6500@8 { + device_type = "cpu"; + reg = <8 9>; + next-level-cache = <&L2_2>; + }; + cpu5: PowerPC,e6500@10 { + device_type = "cpu"; + reg = <10 11>; + next-level-cache = <&L2_2>; + }; + cpu6: PowerPC,e6500@12 { + device_type = "cpu"; + reg = <12 13>; + next-level-cache = <&L2_2>; + }; + cpu7: PowerPC,e6500@14 { + device_type = "cpu"; + reg = <14 15>; + next-level-cache = <&L2_2>; + }; + + cpu8: PowerPC,e6500@16 { + device_type = "cpu"; + reg = <16 17>; + next-level-cache = <&L2_3>; + }; + cpu9: PowerPC,e6500@18 { + device_type = "cpu"; + reg = <18 19>; + next-level-cache = <&L2_3>; + }; + cpu10: PowerPC,e6500@20 { + device_type = "cpu"; + reg = <20 21>; + next-level-cache = <&L2_3>; + }; + cpu11: PowerPC,e6500@22 { + device_type = "cpu"; + reg = <22 23>; + next-level-cache = <&L2_3>; + }; + }; +}; + +/ { + model = "fsl,T4240QDS"; + compatible = "fsl,T4240EMU", "fsl,T4240QDS"; + #address-cells = <2>; + #size-cells = <2>; + interrupt-parent = <&mpic>; + + ifc: localbus@ffe124000 { + reg = <0xf 0xfe124000 0 0x2000>; + ranges = <0 0 0xf 0xe8000000 0x08000000 + 2 0 0xf 0xff800000 0x00010000 + 3 0 0xf 0xffdf0000 0x00008000>; + + nor@0,0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "cfi-flash"; + reg = <0x0 0x0 0x8000000>; + + bank-width = <2>; + device-width = <1>; + }; + + }; + + memory { + device_type = "memory"; + }; + + soc: soc@ffe000000 { + ranges = <0x00000000 0xf 0xfe000000 0x1000000>; + reg = <0xf 0xfe000000 0 0x00001000>; + + }; +}; + +&ifc { + #address-cells = <2>; + #size-cells = <1>; + compatible = "fsl,ifc", "simple-bus"; + interrupts = <25 2 0 0>; +}; + +&soc { + #address-cells = <1>; + #size-cells = <1>; + device_type = "soc"; + compatible = "simple-bus"; + + soc-sram-error { + compatible = "fsl,soc-sram-error"; + interrupts = <16 2 1 29>; + }; + + corenet-law@0 { + compatible = "fsl,corenet-law"; + reg = <0x0 0x1000>; + fsl,num-laws = <32>; + }; + + ddr1: memory-controller@8000 { + compatible = "fsl,qoriq-memory-controller-v4.7", + "fsl,qoriq-memory-controller"; + reg = <0x8000 0x1000>; + interrupts = <16 2 1 23>; + }; + + ddr2: memory-controller@9000 { + compatible = "fsl,qoriq-memory-controller-v4.7", + "fsl,qoriq-memory-controller"; + reg = <0x9000 0x1000>; + interrupts = <16 2 1 22>; + }; + + ddr3: memory-controller@a000 { + compatible = "fsl,qoriq-memory-controller-v4.7", + "fsl,qoriq-memory-controller"; + reg = <0xa000 0x1000>; + interrupts = <16 2 1 21>; + }; + + cpc: l3-cache-controller@10000 { + compatible = "fsl,t4240-l3-cache-controller", "cache"; + reg = <0x10000 0x1000 + 0x11000 0x1000 + 0x12000 0x1000>; + interrupts = <16 2 1 27 + 16 2 1 26 + 16 2 1 25>; + }; + + corenet-cf@18000 { + compatible = "fsl,corenet-cf"; + reg = <0x18000 0x1000>; + interrupts = <16 2 1 31>; + fsl,ccf-num-csdids = <32>; + fsl,ccf-num-snoopids = <32>; + }; + + iommu@20000 { + compatible = "fsl,pamu-v1.0", "fsl,pamu"; + reg = <0x20000 0x6000>; + interrupts = < + 24 2 0 0 + 16 2 1 30>; + }; + +/include/ "fsl/qoriq-mpic.dtsi" + + guts: global-utilities@e0000 { + compatible = "fsl,t4240-device-config", "fsl,qoriq-device-config-2.0"; + reg = <0xe0000 0xe00>; + fsl,has-rstcr; + fsl,liodn-bits = <12>; + }; + + clockgen: global-utilities@e1000 { + compatible = "fsl,t4240-clockgen", "fsl,qoriq-clockgen-2.0"; + reg = <0xe1000 0x1000>; + }; + +/include/ "fsl/qoriq-dma-0.dtsi" +/include/ "fsl/qoriq-dma-1.dtsi" + +/include/ "fsl/qoriq-i2c-0.dtsi" +/include/ "fsl/qoriq-i2c-1.dtsi" +/include/ "fsl/qoriq-duart-0.dtsi" +/include/ "fsl/qoriq-duart-1.dtsi" + + L2_1: l2-cache-controller@c20000 { + compatible = "fsl,t4240-l2-cache-controller"; + reg = <0xc20000 0x40000>; + next-level-cache = <&cpc>; + }; + L2_2: l2-cache-controller@c60000 { + compatible = "fsl,t4240-l2-cache-controller"; + reg = <0xc60000 0x40000>; + next-level-cache = <&cpc>; + }; + L2_3: l2-cache-controller@ca0000 { + compatible = "fsl,t4240-l2-cache-controller"; + reg = <0xca0000 0x40000>; + next-level-cache = <&cpc>; + }; +}; diff --git a/arch/powerpc/boot/dts/t4240qds.dts b/arch/powerpc/boot/dts/t4240qds.dts index 0555976dd0f3..63e81b010804 100644 --- a/arch/powerpc/boot/dts/t4240qds.dts +++ b/arch/powerpc/boot/dts/t4240qds.dts @@ -118,36 +118,53 @@ }; i2c@118000 { - eeprom@51 { - compatible = "at24,24c256"; - reg = <0x51>; - }; - eeprom@52 { - compatible = "at24,24c256"; - reg = <0x52>; - }; - eeprom@53 { - compatible = "at24,24c256"; - reg = <0x53>; - }; - eeprom@54 { - compatible = "at24,24c256"; - reg = <0x54>; - }; - eeprom@55 { - compatible = "at24,24c256"; - reg = <0x55>; - }; - eeprom@56 { - compatible = "at24,24c256"; - reg = <0x56>; - }; - rtc@68 { - compatible = "dallas,ds3232"; - reg = <0x68>; - interrupts = <0x1 0x1 0 0>; + mux@77 { + compatible = "nxp,pca9547"; + reg = <0x77>; + #address-cells = <1>; + #size-cells = <0>; + + i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + eeprom@51 { + compatible = "at24,24c256"; + reg = <0x51>; + }; + eeprom@52 { + compatible = "at24,24c256"; + reg = <0x52>; + }; + eeprom@53 { + compatible = "at24,24c256"; + reg = <0x53>; + }; + eeprom@54 { + compatible = "at24,24c256"; + reg = <0x54>; + }; + eeprom@55 { + compatible = "at24,24c256"; + reg = <0x55>; + }; + eeprom@56 { + compatible = "at24,24c256"; + reg = <0x56>; + }; + rtc@68 { + compatible = "dallas,ds3232"; + reg = <0x68>; + interrupts = <0x1 0x1 0 0>; + }; + }; }; }; + + sdhc@114000 { + voltage-ranges = <1800 1800 3300 3300>; + }; }; pci0: pcie@ffe240000 { diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper index cd7af841ba05..2e1af74a64be 100755 --- a/arch/powerpc/boot/wrapper +++ b/arch/powerpc/boot/wrapper @@ -147,21 +147,29 @@ link_address='0x400000' make_space=y case "$platform" in +of) + platformo="$object/of.o $object/epapr.o" + make_space=n + ;; pseries) platformo="$object/of.o $object/epapr.o" link_address='0x4000000' + make_space=n ;; maple) platformo="$object/of.o $object/epapr.o" link_address='0x400000' + make_space=n ;; pmac|chrp) platformo="$object/of.o $object/epapr.o" + make_space=n ;; coff) platformo="$object/crt0.o $object/of.o $object/epapr.o" lds=$object/zImage.coff.lds link_address='0x500000' + make_space=n pie= ;; miboot|uboot*) diff --git a/arch/powerpc/configs/corenet32_smp_defconfig b/arch/powerpc/configs/corenet32_smp_defconfig index 3dfab4c40c76..bbd794deb6eb 100644 --- a/arch/powerpc/configs/corenet32_smp_defconfig +++ b/arch/powerpc/configs/corenet32_smp_defconfig @@ -23,11 +23,7 @@ CONFIG_MODVERSIONS=y # CONFIG_BLK_DEV_BSG is not set CONFIG_PARTITION_ADVANCED=y CONFIG_MAC_PARTITION=y -CONFIG_P2041_RDB=y -CONFIG_P3041_DS=y -CONFIG_P4080_DS=y -CONFIG_P5020_DS=y -CONFIG_P5040_DS=y +CONFIG_CORENET_GENERIC=y CONFIG_HIGHMEM=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_BINFMT_MISC=m @@ -104,6 +100,7 @@ CONFIG_FSL_PQ_MDIO=y CONFIG_E1000=y CONFIG_E1000E=y CONFIG_VITESSE_PHY=y +CONFIG_AT803X_PHY=y CONFIG_FIXED_PHY=y # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set diff --git a/arch/powerpc/configs/corenet64_smp_defconfig b/arch/powerpc/configs/corenet64_smp_defconfig index fa94fb3bb44d..63508ddee11c 100644 --- a/arch/powerpc/configs/corenet64_smp_defconfig +++ b/arch/powerpc/configs/corenet64_smp_defconfig @@ -21,10 +21,7 @@ CONFIG_MODVERSIONS=y # CONFIG_BLK_DEV_BSG is not set CONFIG_PARTITION_ADVANCED=y CONFIG_MAC_PARTITION=y -CONFIG_B4_QDS=y -CONFIG_P5020_DS=y -CONFIG_P5040_DS=y -CONFIG_T4240_QDS=y +CONFIG_CORENET_GENERIC=y # CONFIG_PPC_OF_BOOT_TRAMPOLINE is not set CONFIG_BINFMT_MISC=m CONFIG_MATH_EMULATION=y diff --git a/arch/powerpc/configs/mpc85xx_defconfig b/arch/powerpc/configs/mpc85xx_defconfig index dc098d988211..d2e0fab5ee5b 100644 --- a/arch/powerpc/configs/mpc85xx_defconfig +++ b/arch/powerpc/configs/mpc85xx_defconfig @@ -138,6 +138,7 @@ CONFIG_MARVELL_PHY=y CONFIG_DAVICOM_PHY=y CONFIG_CICADA_PHY=y CONFIG_VITESSE_PHY=y +CONFIG_AT803X_PHY=y CONFIG_FIXED_PHY=y CONFIG_INPUT_FF_MEMLESS=m # CONFIG_INPUT_MOUSEDEV is not set diff --git a/arch/powerpc/configs/mpc85xx_smp_defconfig b/arch/powerpc/configs/mpc85xx_smp_defconfig index 5bca60161bb3..4cb7b59e98bd 100644 --- a/arch/powerpc/configs/mpc85xx_smp_defconfig +++ b/arch/powerpc/configs/mpc85xx_smp_defconfig @@ -138,6 +138,7 @@ CONFIG_MARVELL_PHY=y CONFIG_DAVICOM_PHY=y CONFIG_CICADA_PHY=y CONFIG_VITESSE_PHY=y +CONFIG_AT803X_PHY=y CONFIG_FIXED_PHY=y CONFIG_INPUT_FF_MEMLESS=m # CONFIG_INPUT_MOUSEDEV is not set diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig index 0e8cfd09da2f..581a3bcae728 100644 --- a/arch/powerpc/configs/ppc64_defconfig +++ b/arch/powerpc/configs/ppc64_defconfig @@ -2,7 +2,6 @@ CONFIG_PPC64=y CONFIG_ALTIVEC=y CONFIG_VSX=y CONFIG_SMP=y -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y CONFIG_IRQ_DOMAIN_DEBUG=y @@ -25,7 +24,6 @@ CONFIG_MODULE_UNLOAD=y CONFIG_MODVERSIONS=y CONFIG_MODULE_SRCVERSION_ALL=y CONFIG_PARTITION_ADVANCED=y -CONFIG_EFI_PARTITION=y CONFIG_PPC_SPLPAR=y CONFIG_SCANLOG=m CONFIG_PPC_SMLPAR=y @@ -50,12 +48,10 @@ CONFIG_CPU_FREQ_PMAC64=y CONFIG_HZ_100=y CONFIG_BINFMT_MISC=m CONFIG_PPC_TRANSACTIONAL_MEM=y -CONFIG_HOTPLUG_CPU=y CONFIG_KEXEC=y CONFIG_IRQ_ALL_CPUS=y CONFIG_MEMORY_HOTREMOVE=y CONFIG_SCHED_SMT=y -CONFIG_PPC_DENORMALISATION=y CONFIG_PCCARD=y CONFIG_ELECTRA_CF=y CONFIG_HOTPLUG_PCI=y @@ -89,7 +85,6 @@ CONFIG_NF_CONNTRACK_PPTP=m CONFIG_NF_CONNTRACK_SIP=m CONFIG_NF_CONNTRACK_TFTP=m CONFIG_NF_CT_NETLINK=m -CONFIG_NETFILTER_TPROXY=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m CONFIG_NETFILTER_XT_TARGET_CONNMARK=m CONFIG_NETFILTER_XT_TARGET_DSCP=m @@ -131,7 +126,6 @@ CONFIG_NETFILTER_XT_MATCH_STRING=m CONFIG_NETFILTER_XT_MATCH_TCPMSS=m CONFIG_NETFILTER_XT_MATCH_U32=m CONFIG_NF_CONNTRACK_IPV4=m -CONFIG_IP_NF_QUEUE=m CONFIG_IP_NF_IPTABLES=m CONFIG_IP_NF_MATCH_AH=m CONFIG_IP_NF_MATCH_ECN=m @@ -157,6 +151,7 @@ CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=65536 +CONFIG_VIRTIO_BLK=m CONFIG_IDE=y CONFIG_BLK_DEV_IDECD=y CONFIG_BLK_DEV_GENERIC=y @@ -185,6 +180,10 @@ CONFIG_SCSI_IPR=y CONFIG_SCSI_QLA_FC=m CONFIG_SCSI_QLA_ISCSI=m CONFIG_SCSI_LPFC=m +CONFIG_SCSI_VIRTIO=m +CONFIG_SCSI_DH=m +CONFIG_SCSI_DH_RDAC=m +CONFIG_SCSI_DH_ALUA=m CONFIG_ATA=y CONFIG_SATA_SIL24=y CONFIG_SATA_SVW=y @@ -203,6 +202,9 @@ CONFIG_DM_SNAPSHOT=m CONFIG_DM_MIRROR=m CONFIG_DM_ZERO=m CONFIG_DM_MULTIPATH=m +CONFIG_DM_MULTIPATH_QL=m +CONFIG_DM_MULTIPATH_ST=m +CONFIG_DM_UEVENT=y CONFIG_ADB_PMU=y CONFIG_PMAC_SMU=y CONFIG_THERM_PM72=y @@ -216,6 +218,8 @@ CONFIG_DUMMY=m CONFIG_NETCONSOLE=y CONFIG_NETPOLL_TRAP=y CONFIG_TUN=m +CONFIG_VIRTIO_NET=m +CONFIG_VHOST_NET=m CONFIG_VORTEX=y CONFIG_ACENIC=m CONFIG_ACENIC_OMIT_TIGON_I=y @@ -262,6 +266,7 @@ CONFIG_HVC_CONSOLE=y CONFIG_HVC_RTAS=y CONFIG_HVC_BEAT=y CONFIG_HVCS=m +CONFIG_VIRTIO_CONSOLE=m CONFIG_IBM_BSR=m CONFIG_RAW_DRIVER=y CONFIG_I2C_CHARDEV=y @@ -301,7 +306,6 @@ CONFIG_HID_GYRATION=y CONFIG_HID_PANTHERLORD=y CONFIG_HID_PETALYNX=y CONFIG_HID_SAMSUNG=y -CONFIG_HID_SONY=y CONFIG_HID_SUNPLUS=y CONFIG_USB_HIDDEV=y CONFIG_USB=y @@ -328,6 +332,8 @@ CONFIG_EDAC_MM_EDAC=y CONFIG_EDAC_PASEMI=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_DS1307=y +CONFIG_VIRTIO_PCI=m +CONFIG_VIRTIO_BALLOON=m CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y @@ -386,21 +392,19 @@ CONFIG_NLS_UTF8=y CONFIG_CRC_T10DIF=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y +CONFIG_DEBUG_STACK_USAGE=y +CONFIG_DEBUG_STACKOVERFLOW=y CONFIG_LOCKUP_DETECTOR=y CONFIG_DEBUG_MUTEXES=y -CONFIG_DEBUG_STACK_USAGE=y CONFIG_LATENCYTOP=y CONFIG_SCHED_TRACER=y CONFIG_BLK_DEV_IO_TRACE=y -CONFIG_DEBUG_STACKOVERFLOW=y CONFIG_CODE_PATCHING_SELFTEST=y CONFIG_FTR_FIXUP_SELFTEST=y CONFIG_MSI_BITMAP_SELFTEST=y CONFIG_XMON=y CONFIG_BOOTX_TEXT=y CONFIG_PPC_EARLY_DEBUG=y -CONFIG_PPC_EARLY_DEBUG_BOOTX=y -CONFIG_CRYPTO_NULL=m CONFIG_CRYPTO_TEST=m CONFIG_CRYPTO_PCBC=m CONFIG_CRYPTO_HMAC=y @@ -422,4 +426,3 @@ CONFIG_CRYPTO_DEV_NX_ENCRYPT=m CONFIG_VIRTUALIZATION=y CONFIG_KVM_BOOK3S_64=m CONFIG_KVM_BOOK3S_64_HV=y -CONFIG_VHOST_NET=m diff --git a/arch/powerpc/configs/ppc64e_defconfig b/arch/powerpc/configs/ppc64e_defconfig index 0085dc4642c5..f627fda08953 100644 --- a/arch/powerpc/configs/ppc64e_defconfig +++ b/arch/powerpc/configs/ppc64e_defconfig @@ -1,7 +1,6 @@ CONFIG_PPC64=y CONFIG_PPC_BOOK3E_64=y CONFIG_SMP=y -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y CONFIG_NO_HZ=y @@ -23,7 +22,7 @@ CONFIG_MODULE_SRCVERSION_ALL=y CONFIG_PARTITION_ADVANCED=y CONFIG_MAC_PARTITION=y CONFIG_EFI_PARTITION=y -CONFIG_P5020_DS=y +CONFIG_CORENET_GENERIC=y CONFIG_CPU_FREQ=y CONFIG_CPU_FREQ_GOV_POWERSAVE=y CONFIG_CPU_FREQ_GOV_USERSPACE=y @@ -61,7 +60,6 @@ CONFIG_NF_CONNTRACK_PPTP=m CONFIG_NF_CONNTRACK_SIP=m CONFIG_NF_CONNTRACK_TFTP=m CONFIG_NF_CT_NETLINK=m -CONFIG_NETFILTER_TPROXY=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m CONFIG_NETFILTER_XT_TARGET_CONNMARK=m CONFIG_NETFILTER_XT_TARGET_DSCP=m @@ -103,7 +101,6 @@ CONFIG_NETFILTER_XT_MATCH_STRING=m CONFIG_NETFILTER_XT_MATCH_TCPMSS=m CONFIG_NETFILTER_XT_MATCH_U32=m CONFIG_NF_CONNTRACK_IPV4=m -CONFIG_IP_NF_QUEUE=m CONFIG_IP_NF_IPTABLES=m CONFIG_IP_NF_MATCH_AH=m CONFIG_IP_NF_MATCH_ECN=m @@ -193,7 +190,6 @@ CONFIG_PPP_SYNC_TTY=m CONFIG_INPUT_EVDEV=m CONFIG_INPUT_MISC=y # CONFIG_SERIO_SERPORT is not set -CONFIG_VT_HW_CONSOLE_BINDING=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y # CONFIG_HW_RANDOM is not set @@ -230,7 +226,6 @@ CONFIG_HID_NTRIG=y CONFIG_HID_PANTHERLORD=y CONFIG_HID_PETALYNX=y CONFIG_HID_SAMSUNG=y -CONFIG_HID_SONY=y CONFIG_HID_SUNPLUS=y CONFIG_HID_GREENASIA=y CONFIG_HID_SMARTJOYPLUS=y @@ -302,19 +297,18 @@ CONFIG_NLS_UTF8=y CONFIG_CRC_T10DIF=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y +CONFIG_DEBUG_STACK_USAGE=y +CONFIG_DEBUG_STACKOVERFLOW=y CONFIG_DETECT_HUNG_TASK=y CONFIG_DEBUG_MUTEXES=y -CONFIG_DEBUG_STACK_USAGE=y CONFIG_LATENCYTOP=y CONFIG_IRQSOFF_TRACER=y CONFIG_SCHED_TRACER=y CONFIG_BLK_DEV_IO_TRACE=y -CONFIG_DEBUG_STACKOVERFLOW=y CONFIG_CODE_PATCHING_SELFTEST=y CONFIG_FTR_FIXUP_SELFTEST=y CONFIG_MSI_BITMAP_SELFTEST=y CONFIG_XMON=y -CONFIG_CRYPTO_NULL=m CONFIG_CRYPTO_TEST=m CONFIG_CRYPTO_CCM=m CONFIG_CRYPTO_GCM=m diff --git a/arch/powerpc/configs/ppc6xx_defconfig b/arch/powerpc/configs/ppc6xx_defconfig index 20ebfaf7234b..c2353bf059fd 100644 --- a/arch/powerpc/configs/ppc6xx_defconfig +++ b/arch/powerpc/configs/ppc6xx_defconfig @@ -71,7 +71,7 @@ CONFIG_QUICC_ENGINE=y CONFIG_QE_GPIO=y CONFIG_PPC_BESTCOMM=y CONFIG_GPIO_MPC8XXX=y -CONFIG_MCU_MPC8349EMITX=m +CONFIG_MCU_MPC8349EMITX=y CONFIG_HIGHMEM=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig index 1d4b9763895d..e9a8b4e0a0f6 100644 --- a/arch/powerpc/configs/pseries_defconfig +++ b/arch/powerpc/configs/pseries_defconfig @@ -3,7 +3,6 @@ CONFIG_ALTIVEC=y CONFIG_VSX=y CONFIG_SMP=y CONFIG_NR_CPUS=2048 -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y CONFIG_AUDIT=y @@ -33,7 +32,6 @@ CONFIG_MODULE_UNLOAD=y CONFIG_MODVERSIONS=y CONFIG_MODULE_SRCVERSION_ALL=y CONFIG_PARTITION_ADVANCED=y -CONFIG_EFI_PARTITION=y CONFIG_PPC_SPLPAR=y CONFIG_SCANLOG=m CONFIG_PPC_SMLPAR=y @@ -44,7 +42,6 @@ CONFIG_IBMEBUS=y CONFIG_HZ_100=y CONFIG_BINFMT_MISC=m CONFIG_PPC_TRANSACTIONAL_MEM=y -CONFIG_HOTPLUG_CPU=y CONFIG_KEXEC=y CONFIG_IRQ_ALL_CPUS=y CONFIG_MEMORY_HOTPLUG=y @@ -52,7 +49,6 @@ CONFIG_MEMORY_HOTREMOVE=y CONFIG_PPC_64K_PAGES=y CONFIG_PPC_SUBPAGE_PROT=y CONFIG_SCHED_SMT=y -CONFIG_PPC_DENORMALISATION=y CONFIG_HOTPLUG_PCI=y CONFIG_HOTPLUG_PCI_RPA=m CONFIG_HOTPLUG_PCI_RPA_DLPAR=m @@ -113,7 +109,6 @@ CONFIG_NETFILTER_XT_MATCH_TCPMSS=m CONFIG_NETFILTER_XT_MATCH_TIME=m CONFIG_NETFILTER_XT_MATCH_U32=m CONFIG_NF_CONNTRACK_IPV4=m -CONFIG_IP_NF_QUEUE=m CONFIG_IP_NF_IPTABLES=m CONFIG_IP_NF_MATCH_AH=m CONFIG_IP_NF_MATCH_ECN=m @@ -132,6 +127,7 @@ CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=65536 +CONFIG_VIRTIO_BLK=m CONFIG_IDE=y CONFIG_BLK_DEV_IDECD=y CONFIG_BLK_DEV_GENERIC=y @@ -157,6 +153,10 @@ CONFIG_SCSI_IPR=y CONFIG_SCSI_QLA_FC=m CONFIG_SCSI_QLA_ISCSI=m CONFIG_SCSI_LPFC=m +CONFIG_SCSI_VIRTIO=m +CONFIG_SCSI_DH=m +CONFIG_SCSI_DH_RDAC=m +CONFIG_SCSI_DH_ALUA=m CONFIG_ATA=y # CONFIG_ATA_SFF is not set CONFIG_MD=y @@ -174,11 +174,16 @@ CONFIG_DM_SNAPSHOT=m CONFIG_DM_MIRROR=m CONFIG_DM_ZERO=m CONFIG_DM_MULTIPATH=m +CONFIG_DM_MULTIPATH_QL=m +CONFIG_DM_MULTIPATH_ST=m +CONFIG_DM_UEVENT=y CONFIG_BONDING=m CONFIG_DUMMY=m CONFIG_NETCONSOLE=y CONFIG_NETPOLL_TRAP=y CONFIG_TUN=m +CONFIG_VIRTIO_NET=m +CONFIG_VHOST_NET=m CONFIG_VORTEX=y CONFIG_ACENIC=m CONFIG_ACENIC_OMIT_TIGON_I=y @@ -216,6 +221,7 @@ CONFIG_SERIAL_JSM=m CONFIG_HVC_CONSOLE=y CONFIG_HVC_RTAS=y CONFIG_HVCS=m +CONFIG_VIRTIO_CONSOLE=m CONFIG_IBM_BSR=m CONFIG_GEN_RTC=y CONFIG_RAW_DRIVER=y @@ -237,7 +243,6 @@ CONFIG_HID_GYRATION=y CONFIG_HID_PANTHERLORD=y CONFIG_HID_PETALYNX=y CONFIG_HID_SAMSUNG=y -CONFIG_HID_SONY=y CONFIG_HID_SUNPLUS=y CONFIG_USB_HIDDEV=y CONFIG_USB=y @@ -258,6 +263,8 @@ CONFIG_INFINIBAND_IPOIB=m CONFIG_INFINIBAND_IPOIB_CM=y CONFIG_INFINIBAND_SRP=m CONFIG_INFINIBAND_ISER=m +CONFIG_VIRTIO_PCI=m +CONFIG_VIRTIO_BALLOON=m CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y @@ -314,18 +321,17 @@ CONFIG_NLS_UTF8=y CONFIG_CRC_T10DIF=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y -CONFIG_LOCKUP_DETECTOR=y CONFIG_DEBUG_STACK_USAGE=y +CONFIG_DEBUG_STACKOVERFLOW=y +CONFIG_LOCKUP_DETECTOR=y CONFIG_LATENCYTOP=y CONFIG_SCHED_TRACER=y CONFIG_BLK_DEV_IO_TRACE=y -CONFIG_DEBUG_STACKOVERFLOW=y CONFIG_CODE_PATCHING_SELFTEST=y CONFIG_FTR_FIXUP_SELFTEST=y CONFIG_MSI_BITMAP_SELFTEST=y CONFIG_XMON=y CONFIG_XMON_DEFAULT=y -CONFIG_CRYPTO_NULL=m CONFIG_CRYPTO_TEST=m CONFIG_CRYPTO_PCBC=m CONFIG_CRYPTO_HMAC=y @@ -347,4 +353,3 @@ CONFIG_CRYPTO_DEV_NX_ENCRYPT=m CONFIG_VIRTUALIZATION=y CONFIG_KVM_BOOK3S_64=m CONFIG_KVM_BOOK3S_64_HV=y -CONFIG_VHOST_NET=m diff --git a/arch/powerpc/include/asm/Kbuild b/arch/powerpc/include/asm/Kbuild index 704e6f10ae80..d8f9d2f18a23 100644 --- a/arch/powerpc/include/asm/Kbuild +++ b/arch/powerpc/include/asm/Kbuild @@ -2,4 +2,5 @@ generic-y += clkdev.h generic-y += rwsem.h generic-y += trace_clock.h +generic-y += preempt.h generic-y += vtime.h
\ No newline at end of file diff --git a/arch/powerpc/include/asm/archrandom.h b/arch/powerpc/include/asm/archrandom.h new file mode 100644 index 000000000000..d853d163ba47 --- /dev/null +++ b/arch/powerpc/include/asm/archrandom.h @@ -0,0 +1,32 @@ +#ifndef _ASM_POWERPC_ARCHRANDOM_H +#define _ASM_POWERPC_ARCHRANDOM_H + +#ifdef CONFIG_ARCH_RANDOM + +#include <asm/machdep.h> + +static inline int arch_get_random_long(unsigned long *v) +{ + if (ppc_md.get_random_long) + return ppc_md.get_random_long(v); + + return 0; +} + +static inline int arch_get_random_int(unsigned int *v) +{ + unsigned long val; + int rc; + + rc = arch_get_random_long(&val); + if (rc) + *v = val; + + return rc; +} + +int powernv_get_random_long(unsigned long *v); + +#endif /* CONFIG_ARCH_RANDOM */ + +#endif /* _ASM_POWERPC_ARCHRANDOM_H */ diff --git a/arch/powerpc/include/asm/checksum.h b/arch/powerpc/include/asm/checksum.h index ce0c28495f9a..8251a3ba870f 100644 --- a/arch/powerpc/include/asm/checksum.h +++ b/arch/powerpc/include/asm/checksum.h @@ -14,6 +14,9 @@ * which always checksum on 4 octet boundaries. ihl is the number * of 32-bit words and is always >= 5. */ +#ifdef CONFIG_GENERIC_CSUM +#include <asm-generic/checksum.h> +#else extern __sum16 ip_fast_csum(const void *iph, unsigned int ihl); /* @@ -123,5 +126,7 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, return sum; #endif } + +#endif #endif /* __KERNEL__ */ #endif diff --git a/arch/powerpc/include/asm/disassemble.h b/arch/powerpc/include/asm/disassemble.h index 9b198d1b3b2b..856f8deb557a 100644 --- a/arch/powerpc/include/asm/disassemble.h +++ b/arch/powerpc/include/asm/disassemble.h @@ -77,4 +77,8 @@ static inline unsigned int get_d(u32 inst) return inst & 0xffff; } +static inline unsigned int get_oc(u32 inst) +{ + return (inst >> 11) & 0x7fff; +} #endif /* __ASM_PPC_DISASSEMBLE_H__ */ diff --git a/arch/powerpc/include/asm/emulated_ops.h b/arch/powerpc/include/asm/emulated_ops.h index 5a8b82aa7241..4358e3002f35 100644 --- a/arch/powerpc/include/asm/emulated_ops.h +++ b/arch/powerpc/include/asm/emulated_ops.h @@ -43,6 +43,7 @@ extern struct ppc_emulated { struct ppc_emulated_entry popcntb; struct ppc_emulated_entry spe; struct ppc_emulated_entry string; + struct ppc_emulated_entry sync; struct ppc_emulated_entry unaligned; #ifdef CONFIG_MATH_EMULATION struct ppc_emulated_entry math; diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index cca12f084842..894662a5d4d5 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h @@ -198,12 +198,27 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) cmpwi r10,0; \ bne do_kvm_##n +#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE +/* + * If hv is possible, interrupts come into to the hv version + * of the kvmppc_interrupt code, which then jumps to the PR handler, + * kvmppc_interrupt_pr, if the guest is a PR guest. + */ +#define kvmppc_interrupt kvmppc_interrupt_hv +#else +#define kvmppc_interrupt kvmppc_interrupt_pr +#endif + #define __KVM_HANDLER(area, h, n) \ do_kvm_##n: \ BEGIN_FTR_SECTION_NESTED(947) \ ld r10,area+EX_CFAR(r13); \ std r10,HSTATE_CFAR(r13); \ END_FTR_SECTION_NESTED(CPU_FTR_CFAR,CPU_FTR_CFAR,947); \ + BEGIN_FTR_SECTION_NESTED(948) \ + ld r10,area+EX_PPR(r13); \ + std r10,HSTATE_PPR(r13); \ + END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,948); \ ld r10,area+EX_R10(r13); \ stw r9,HSTATE_SCRATCH1(r13); \ ld r9,area+EX_R9(r13); \ @@ -217,6 +232,10 @@ do_kvm_##n: \ ld r10,area+EX_R10(r13); \ beq 89f; \ stw r9,HSTATE_SCRATCH1(r13); \ + BEGIN_FTR_SECTION_NESTED(948) \ + ld r9,area+EX_PPR(r13); \ + std r9,HSTATE_PPR(r13); \ + END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,948); \ ld r9,area+EX_R9(r13); \ std r12,HSTATE_SCRATCH0(r13); \ li r12,n; \ @@ -236,7 +255,7 @@ do_kvm_##n: \ #define KVM_HANDLER_SKIP(area, h, n) #endif -#ifdef CONFIG_KVM_BOOK3S_PR +#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE #define KVMTEST_PR(n) __KVMTEST(n) #define KVM_HANDLER_PR(area, h, n) __KVM_HANDLER(area, h, n) #define KVM_HANDLER_PR_SKIP(area, h, n) __KVM_HANDLER_SKIP(area, h, n) diff --git a/arch/powerpc/include/asm/fsl_ifc.h b/arch/powerpc/include/asm/fsl_ifc.h index b8a4b9bc50b3..f49ddb1b2273 100644 --- a/arch/powerpc/include/asm/fsl_ifc.h +++ b/arch/powerpc/include/asm/fsl_ifc.h @@ -93,6 +93,7 @@ #define CSOR_NAND_PGS_512 0x00000000 #define CSOR_NAND_PGS_2K 0x00080000 #define CSOR_NAND_PGS_4K 0x00100000 +#define CSOR_NAND_PGS_8K 0x00180000 /* Spare region Size */ #define CSOR_NAND_SPRZ_MASK 0x0000E000 #define CSOR_NAND_SPRZ_SHIFT 13 @@ -102,6 +103,7 @@ #define CSOR_NAND_SPRZ_210 0x00006000 #define CSOR_NAND_SPRZ_218 0x00008000 #define CSOR_NAND_SPRZ_224 0x0000A000 +#define CSOR_NAND_SPRZ_CSOR_EXT 0x0000C000 /* Pages Per Block */ #define CSOR_NAND_PB_MASK 0x00000700 #define CSOR_NAND_PB_SHIFT 8 diff --git a/arch/powerpc/include/asm/hvsi.h b/arch/powerpc/include/asm/hvsi.h index d3f64f361814..d4a5315718ca 100644 --- a/arch/powerpc/include/asm/hvsi.h +++ b/arch/powerpc/include/asm/hvsi.h @@ -25,7 +25,7 @@ struct hvsi_header { uint8_t type; uint8_t len; - uint16_t seqno; + __be16 seqno; } __attribute__((packed)); struct hvsi_data { @@ -35,24 +35,24 @@ struct hvsi_data { struct hvsi_control { struct hvsi_header hdr; - uint16_t verb; + __be16 verb; /* optional depending on verb: */ - uint32_t word; - uint32_t mask; + __be32 word; + __be32 mask; } __attribute__((packed)); struct hvsi_query { struct hvsi_header hdr; - uint16_t verb; + __be16 verb; } __attribute__((packed)); struct hvsi_query_response { struct hvsi_header hdr; - uint16_t verb; - uint16_t query_seqno; + __be16 verb; + __be16 query_seqno; union { uint8_t version; - uint32_t mctrl_word; + __be32 mctrl_word; } u; } __attribute__((packed)); diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h index 5a64757dc0d1..575fbf81fad0 100644 --- a/arch/powerpc/include/asm/io.h +++ b/arch/powerpc/include/asm/io.h @@ -21,7 +21,7 @@ extern struct pci_dev *isa_bridge_pcidev; /* * has legacy ISA devices ? */ -#define arch_has_dev_port() (isa_bridge_pcidev != NULL) +#define arch_has_dev_port() (isa_bridge_pcidev != NULL || isa_io_special) #endif #include <linux/device.h> @@ -113,7 +113,7 @@ extern bool isa_io_special; /* gcc 4.0 and older doesn't have 'Z' constraint */ #if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ == 0) -#define DEF_MMIO_IN_LE(name, size, insn) \ +#define DEF_MMIO_IN_X(name, size, insn) \ static inline u##size name(const volatile u##size __iomem *addr) \ { \ u##size ret; \ @@ -122,7 +122,7 @@ static inline u##size name(const volatile u##size __iomem *addr) \ return ret; \ } -#define DEF_MMIO_OUT_LE(name, size, insn) \ +#define DEF_MMIO_OUT_X(name, size, insn) \ static inline void name(volatile u##size __iomem *addr, u##size val) \ { \ __asm__ __volatile__("sync;"#insn" %1,0,%2" \ @@ -130,7 +130,7 @@ static inline void name(volatile u##size __iomem *addr, u##size val) \ IO_SET_SYNC_FLAG(); \ } #else /* newer gcc */ -#define DEF_MMIO_IN_LE(name, size, insn) \ +#define DEF_MMIO_IN_X(name, size, insn) \ static inline u##size name(const volatile u##size __iomem *addr) \ { \ u##size ret; \ @@ -139,7 +139,7 @@ static inline u##size name(const volatile u##size __iomem *addr) \ return ret; \ } -#define DEF_MMIO_OUT_LE(name, size, insn) \ +#define DEF_MMIO_OUT_X(name, size, insn) \ static inline void name(volatile u##size __iomem *addr, u##size val) \ { \ __asm__ __volatile__("sync;"#insn" %1,%y0" \ @@ -148,7 +148,7 @@ static inline void name(volatile u##size __iomem *addr, u##size val) \ } #endif -#define DEF_MMIO_IN_BE(name, size, insn) \ +#define DEF_MMIO_IN_D(name, size, insn) \ static inline u##size name(const volatile u##size __iomem *addr) \ { \ u##size ret; \ @@ -157,7 +157,7 @@ static inline u##size name(const volatile u##size __iomem *addr) \ return ret; \ } -#define DEF_MMIO_OUT_BE(name, size, insn) \ +#define DEF_MMIO_OUT_D(name, size, insn) \ static inline void name(volatile u##size __iomem *addr, u##size val) \ { \ __asm__ __volatile__("sync;"#insn"%U0%X0 %1,%0" \ @@ -165,22 +165,37 @@ static inline void name(volatile u##size __iomem *addr, u##size val) \ IO_SET_SYNC_FLAG(); \ } +DEF_MMIO_IN_D(in_8, 8, lbz); +DEF_MMIO_OUT_D(out_8, 8, stb); -DEF_MMIO_IN_BE(in_8, 8, lbz); -DEF_MMIO_IN_BE(in_be16, 16, lhz); -DEF_MMIO_IN_BE(in_be32, 32, lwz); -DEF_MMIO_IN_LE(in_le16, 16, lhbrx); -DEF_MMIO_IN_LE(in_le32, 32, lwbrx); +#ifdef __BIG_ENDIAN__ +DEF_MMIO_IN_D(in_be16, 16, lhz); +DEF_MMIO_IN_D(in_be32, 32, lwz); +DEF_MMIO_IN_X(in_le16, 16, lhbrx); +DEF_MMIO_IN_X(in_le32, 32, lwbrx); -DEF_MMIO_OUT_BE(out_8, 8, stb); -DEF_MMIO_OUT_BE(out_be16, 16, sth); -DEF_MMIO_OUT_BE(out_be32, 32, stw); -DEF_MMIO_OUT_LE(out_le16, 16, sthbrx); -DEF_MMIO_OUT_LE(out_le32, 32, stwbrx); +DEF_MMIO_OUT_D(out_be16, 16, sth); +DEF_MMIO_OUT_D(out_be32, 32, stw); +DEF_MMIO_OUT_X(out_le16, 16, sthbrx); +DEF_MMIO_OUT_X(out_le32, 32, stwbrx); +#else +DEF_MMIO_IN_X(in_be16, 16, lhbrx); +DEF_MMIO_IN_X(in_be32, 32, lwbrx); +DEF_MMIO_IN_D(in_le16, 16, lhz); +DEF_MMIO_IN_D(in_le32, 32, lwz); + +DEF_MMIO_OUT_X(out_be16, 16, sthbrx); +DEF_MMIO_OUT_X(out_be32, 32, stwbrx); +DEF_MMIO_OUT_D(out_le16, 16, sth); +DEF_MMIO_OUT_D(out_le32, 32, stw); + +#endif /* __BIG_ENDIAN */ #ifdef __powerpc64__ -DEF_MMIO_OUT_BE(out_be64, 64, std); -DEF_MMIO_IN_BE(in_be64, 64, ld); + +#ifdef __BIG_ENDIAN__ +DEF_MMIO_OUT_D(out_be64, 64, std); +DEF_MMIO_IN_D(in_be64, 64, ld); /* There is no asm instructions for 64 bits reverse loads and stores */ static inline u64 in_le64(const volatile u64 __iomem *addr) @@ -192,6 +207,22 @@ static inline void out_le64(volatile u64 __iomem *addr, u64 val) { out_be64(addr, swab64(val)); } +#else +DEF_MMIO_OUT_D(out_le64, 64, std); +DEF_MMIO_IN_D(in_le64, 64, ld); + +/* There is no asm instructions for 64 bits reverse loads and stores */ +static inline u64 in_be64(const volatile u64 __iomem *addr) +{ + return swab64(in_le64(addr)); +} + +static inline void out_be64(volatile u64 __iomem *addr, u64 val) +{ + out_le64(addr, swab64(val)); +} + +#endif #endif /* __powerpc64__ */ /* diff --git a/arch/powerpc/include/asm/kvm_asm.h b/arch/powerpc/include/asm/kvm_asm.h index 851bac7afa4b..1bd92fd43cfb 100644 --- a/arch/powerpc/include/asm/kvm_asm.h +++ b/arch/powerpc/include/asm/kvm_asm.h @@ -123,6 +123,8 @@ #define BOOK3S_HFLAG_SLB 0x2 #define BOOK3S_HFLAG_PAIRED_SINGLE 0x4 #define BOOK3S_HFLAG_NATIVE_PS 0x8 +#define BOOK3S_HFLAG_MULTI_PGSIZE 0x10 +#define BOOK3S_HFLAG_NEW_TLBIE 0x20 #define RESUME_FLAG_NV (1<<0) /* Reload guest nonvolatile state? */ #define RESUME_FLAG_HOST (1<<1) /* Resume host? */ @@ -136,6 +138,8 @@ #define KVM_GUEST_MODE_NONE 0 #define KVM_GUEST_MODE_GUEST 1 #define KVM_GUEST_MODE_SKIP 2 +#define KVM_GUEST_MODE_GUEST_HV 3 +#define KVM_GUEST_MODE_HOST_HV 4 #define KVM_INST_FETCH_FAILED -1 diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h index fa19e2f1a874..4a594b76674d 100644 --- a/arch/powerpc/include/asm/kvm_book3s.h +++ b/arch/powerpc/include/asm/kvm_book3s.h @@ -58,16 +58,18 @@ struct hpte_cache { struct hlist_node list_pte_long; struct hlist_node list_vpte; struct hlist_node list_vpte_long; +#ifdef CONFIG_PPC_BOOK3S_64 + struct hlist_node list_vpte_64k; +#endif struct rcu_head rcu_head; u64 host_vpn; u64 pfn; ulong slot; struct kvmppc_pte pte; + int pagesize; }; struct kvmppc_vcpu_book3s { - struct kvm_vcpu vcpu; - struct kvmppc_book3s_shadow_vcpu *shadow_vcpu; struct kvmppc_sid_map sid_map[SID_MAP_NUM]; struct { u64 esid; @@ -99,6 +101,9 @@ struct kvmppc_vcpu_book3s { struct hlist_head hpte_hash_pte_long[HPTEG_HASH_NUM_PTE_LONG]; struct hlist_head hpte_hash_vpte[HPTEG_HASH_NUM_VPTE]; struct hlist_head hpte_hash_vpte_long[HPTEG_HASH_NUM_VPTE_LONG]; +#ifdef CONFIG_PPC_BOOK3S_64 + struct hlist_head hpte_hash_vpte_64k[HPTEG_HASH_NUM_VPTE_64K]; +#endif int hpte_cache_count; spinlock_t mmu_lock; }; @@ -107,8 +112,9 @@ struct kvmppc_vcpu_book3s { #define CONTEXT_GUEST 1 #define CONTEXT_GUEST_END 2 -#define VSID_REAL 0x0fffffffffc00000ULL -#define VSID_BAT 0x0fffffffffb00000ULL +#define VSID_REAL 0x07ffffffffc00000ULL +#define VSID_BAT 0x07ffffffffb00000ULL +#define VSID_64K 0x0800000000000000ULL #define VSID_1T 0x1000000000000000ULL #define VSID_REAL_DR 0x2000000000000000ULL #define VSID_REAL_IR 0x4000000000000000ULL @@ -118,11 +124,12 @@ extern void kvmppc_mmu_pte_flush(struct kvm_vcpu *vcpu, ulong ea, ulong ea_mask) extern void kvmppc_mmu_pte_vflush(struct kvm_vcpu *vcpu, u64 vp, u64 vp_mask); extern void kvmppc_mmu_pte_pflush(struct kvm_vcpu *vcpu, ulong pa_start, ulong pa_end); extern void kvmppc_set_msr(struct kvm_vcpu *vcpu, u64 new_msr); -extern void kvmppc_set_pvr(struct kvm_vcpu *vcpu, u32 pvr); extern void kvmppc_mmu_book3s_64_init(struct kvm_vcpu *vcpu); extern void kvmppc_mmu_book3s_32_init(struct kvm_vcpu *vcpu); extern void kvmppc_mmu_book3s_hv_init(struct kvm_vcpu *vcpu); -extern int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *pte); +extern int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *pte, + bool iswrite); +extern void kvmppc_mmu_unmap_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *pte); extern int kvmppc_mmu_map_segment(struct kvm_vcpu *vcpu, ulong eaddr); extern void kvmppc_mmu_flush_segment(struct kvm_vcpu *vcpu, ulong eaddr, ulong seg_size); extern void kvmppc_mmu_flush_segments(struct kvm_vcpu *vcpu); @@ -134,6 +141,7 @@ extern long kvmppc_hv_find_lock_hpte(struct kvm *kvm, gva_t eaddr, extern void kvmppc_mmu_hpte_cache_map(struct kvm_vcpu *vcpu, struct hpte_cache *pte); extern struct hpte_cache *kvmppc_mmu_hpte_cache_next(struct kvm_vcpu *vcpu); +extern void kvmppc_mmu_hpte_cache_free(struct hpte_cache *pte); extern void kvmppc_mmu_hpte_destroy(struct kvm_vcpu *vcpu); extern int kvmppc_mmu_hpte_init(struct kvm_vcpu *vcpu); extern void kvmppc_mmu_invalidate_pte(struct kvm_vcpu *vcpu, struct hpte_cache *pte); @@ -151,7 +159,8 @@ extern void kvmppc_set_bat(struct kvm_vcpu *vcpu, struct kvmppc_bat *bat, bool upper, u32 val); extern void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr); extern int kvmppc_emulate_paired_single(struct kvm_run *run, struct kvm_vcpu *vcpu); -extern pfn_t kvmppc_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn); +extern pfn_t kvmppc_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn, bool writing, + bool *writable); extern void kvmppc_add_revmap_chain(struct kvm *kvm, struct revmap_entry *rev, unsigned long *rmap, long pte_index, int realmode); extern void kvmppc_invalidate_hpte(struct kvm *kvm, unsigned long *hptep, @@ -172,6 +181,8 @@ extern long kvmppc_do_h_remove(struct kvm *kvm, unsigned long flags, unsigned long *hpret); extern long kvmppc_hv_get_dirty_log(struct kvm *kvm, struct kvm_memory_slot *memslot, unsigned long *map); +extern void kvmppc_update_lpcr(struct kvm *kvm, unsigned long lpcr, + unsigned long mask); extern void kvmppc_entry_trampoline(void); extern void kvmppc_hv_entry_trampoline(void); @@ -184,11 +195,9 @@ extern int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd); static inline struct kvmppc_vcpu_book3s *to_book3s(struct kvm_vcpu *vcpu) { - return container_of(vcpu, struct kvmppc_vcpu_book3s, vcpu); + return vcpu->arch.book3s; } -extern void kvm_return_point(void); - /* Also add subarch specific defines */ #ifdef CONFIG_KVM_BOOK3S_32_HANDLER @@ -198,203 +207,6 @@ extern void kvm_return_point(void); #include <asm/kvm_book3s_64.h> #endif -#ifdef CONFIG_KVM_BOOK3S_PR - -static inline unsigned long kvmppc_interrupt_offset(struct kvm_vcpu *vcpu) -{ - return to_book3s(vcpu)->hior; -} - -static inline void kvmppc_update_int_pending(struct kvm_vcpu *vcpu, - unsigned long pending_now, unsigned long old_pending) -{ - if (pending_now) - vcpu->arch.shared->int_pending = 1; - else if (old_pending) - vcpu->arch.shared->int_pending = 0; -} - -static inline void kvmppc_set_gpr(struct kvm_vcpu *vcpu, int num, ulong val) -{ - if ( num < 14 ) { - struct kvmppc_book3s_shadow_vcpu *svcpu = svcpu_get(vcpu); - svcpu->gpr[num] = val; - svcpu_put(svcpu); - to_book3s(vcpu)->shadow_vcpu->gpr[num] = val; - } else - vcpu->arch.gpr[num] = val; -} - -static inline ulong kvmppc_get_gpr(struct kvm_vcpu *vcpu, int num) -{ - if ( num < 14 ) { - struct kvmppc_book3s_shadow_vcpu *svcpu = svcpu_get(vcpu); - ulong r = svcpu->gpr[num]; - svcpu_put(svcpu); - return r; - } else - return vcpu->arch.gpr[num]; -} - -static inline void kvmppc_set_cr(struct kvm_vcpu *vcpu, u32 val) -{ - struct kvmppc_book3s_shadow_vcpu *svcpu = svcpu_get(vcpu); - svcpu->cr = val; - svcpu_put(svcpu); - to_book3s(vcpu)->shadow_vcpu->cr = val; -} - -static inline u32 kvmppc_get_cr(struct kvm_vcpu *vcpu) -{ - struct kvmppc_book3s_shadow_vcpu *svcpu = svcpu_get(vcpu); - u32 r; - r = svcpu->cr; - svcpu_put(svcpu); - return r; -} - -static inline void kvmppc_set_xer(struct kvm_vcpu *vcpu, u32 val) -{ - struct kvmppc_book3s_shadow_vcpu *svcpu = svcpu_get(vcpu); - svcpu->xer = val; - to_book3s(vcpu)->shadow_vcpu->xer = val; - svcpu_put(svcpu); -} - -static inline u32 kvmppc_get_xer(struct kvm_vcpu *vcpu) -{ - struct kvmppc_book3s_shadow_vcpu *svcpu = svcpu_get(vcpu); - u32 r; - r = svcpu->xer; - svcpu_put(svcpu); - return r; -} - -static inline void kvmppc_set_ctr(struct kvm_vcpu *vcpu, ulong val) -{ - struct kvmppc_book3s_shadow_vcpu *svcpu = svcpu_get(vcpu); - svcpu->ctr = val; - svcpu_put(svcpu); -} - -static inline ulong kvmppc_get_ctr(struct kvm_vcpu *vcpu) -{ - struct kvmppc_book3s_shadow_vcpu *svcpu = svcpu_get(vcpu); - ulong r; - r = svcpu->ctr; - svcpu_put(svcpu); - return r; -} - -static inline void kvmppc_set_lr(struct kvm_vcpu *vcpu, ulong val) -{ - struct kvmppc_book3s_shadow_vcpu *svcpu = svcpu_get(vcpu); - svcpu->lr = val; - svcpu_put(svcpu); -} - -static inline ulong kvmppc_get_lr(struct kvm_vcpu *vcpu) -{ - struct kvmppc_book3s_shadow_vcpu *svcpu = svcpu_get(vcpu); - ulong r; - r = svcpu->lr; - svcpu_put(svcpu); - return r; -} - -static inline void kvmppc_set_pc(struct kvm_vcpu *vcpu, ulong val) -{ - struct kvmppc_book3s_shadow_vcpu *svcpu = svcpu_get(vcpu); - svcpu->pc = val; - svcpu_put(svcpu); -} - -static inline ulong kvmppc_get_pc(struct kvm_vcpu *vcpu) -{ - struct kvmppc_book3s_shadow_vcpu *svcpu = svcpu_get(vcpu); - ulong r; - r = svcpu->pc; - svcpu_put(svcpu); - return r; -} - -static inline u32 kvmppc_get_last_inst(struct kvm_vcpu *vcpu) -{ - ulong pc = kvmppc_get_pc(vcpu); - struct kvmppc_book3s_shadow_vcpu *svcpu = svcpu_get(vcpu); - u32 r; - - /* Load the instruction manually if it failed to do so in the - * exit path */ - if (svcpu->last_inst == KVM_INST_FETCH_FAILED) - kvmppc_ld(vcpu, &pc, sizeof(u32), &svcpu->last_inst, false); - - r = svcpu->last_inst; - svcpu_put(svcpu); - return r; -} - -/* - * Like kvmppc_get_last_inst(), but for fetching a sc instruction. - * Because the sc instruction sets SRR0 to point to the following - * instruction, we have to fetch from pc - 4. - */ -static inline u32 kvmppc_get_last_sc(struct kvm_vcpu *vcpu) -{ - ulong pc = kvmppc_get_pc(vcpu) - 4; - struct kvmppc_book3s_shadow_vcpu *svcpu = svcpu_get(vcpu); - u32 r; - - /* Load the instruction manually if it failed to do so in the - * exit path */ - if (svcpu->last_inst == KVM_INST_FETCH_FAILED) - kvmppc_ld(vcpu, &pc, sizeof(u32), &svcpu->last_inst, false); - - r = svcpu->last_inst; - svcpu_put(svcpu); - return r; -} - -static inline ulong kvmppc_get_fault_dar(struct kvm_vcpu *vcpu) -{ - struct kvmppc_book3s_shadow_vcpu *svcpu = svcpu_get(vcpu); - ulong r; - r = svcpu->fault_dar; - svcpu_put(svcpu); - return r; -} - -static inline bool kvmppc_critical_section(struct kvm_vcpu *vcpu) -{ - ulong crit_raw = vcpu->arch.shared->critical; - ulong crit_r1 = kvmppc_get_gpr(vcpu, 1); - bool crit; - - /* Truncate crit indicators in 32 bit mode */ - if (!(vcpu->arch.shared->msr & MSR_SF)) { - crit_raw &= 0xffffffff; - crit_r1 &= 0xffffffff; - } - - /* Critical section when crit == r1 */ - crit = (crit_raw == crit_r1); - /* ... and we're in supervisor mode */ - crit = crit && !(vcpu->arch.shared->msr & MSR_PR); - - return crit; -} -#else /* CONFIG_KVM_BOOK3S_PR */ - -static inline unsigned long kvmppc_interrupt_offset(struct kvm_vcpu *vcpu) -{ - return 0; -} - -static inline void kvmppc_update_int_pending(struct kvm_vcpu *vcpu, - unsigned long pending_now, unsigned long old_pending) -{ -} - static inline void kvmppc_set_gpr(struct kvm_vcpu *vcpu, int num, ulong val) { vcpu->arch.gpr[num] = val; @@ -489,12 +301,6 @@ static inline ulong kvmppc_get_fault_dar(struct kvm_vcpu *vcpu) return vcpu->arch.fault_dar; } -static inline bool kvmppc_critical_section(struct kvm_vcpu *vcpu) -{ - return false; -} -#endif - /* Magic register values loaded into r3 and r4 before the 'sc' assembly * instruction for the OSI hypercalls */ #define OSI_SC_MAGIC_R3 0x113724FA diff --git a/arch/powerpc/include/asm/kvm_book3s_32.h b/arch/powerpc/include/asm/kvm_book3s_32.h index ce0ef6ce8f86..c720e0b3238d 100644 --- a/arch/powerpc/include/asm/kvm_book3s_32.h +++ b/arch/powerpc/include/asm/kvm_book3s_32.h @@ -22,7 +22,7 @@ static inline struct kvmppc_book3s_shadow_vcpu *svcpu_get(struct kvm_vcpu *vcpu) { - return to_book3s(vcpu)->shadow_vcpu; + return vcpu->arch.shadow_vcpu; } static inline void svcpu_put(struct kvmppc_book3s_shadow_vcpu *svcpu) diff --git a/arch/powerpc/include/asm/kvm_book3s_64.h b/arch/powerpc/include/asm/kvm_book3s_64.h index 86d638a3b359..bf0fa8b0a883 100644 --- a/arch/powerpc/include/asm/kvm_book3s_64.h +++ b/arch/powerpc/include/asm/kvm_book3s_64.h @@ -20,7 +20,7 @@ #ifndef __ASM_KVM_BOOK3S_64_H__ #define __ASM_KVM_BOOK3S_64_H__ -#ifdef CONFIG_KVM_BOOK3S_PR +#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE static inline struct kvmppc_book3s_shadow_vcpu *svcpu_get(struct kvm_vcpu *vcpu) { preempt_disable(); @@ -35,7 +35,7 @@ static inline void svcpu_put(struct kvmppc_book3s_shadow_vcpu *svcpu) #define SPAPR_TCE_SHIFT 12 -#ifdef CONFIG_KVM_BOOK3S_64_HV +#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE #define KVM_DEFAULT_HPT_ORDER 24 /* 16MB HPT by default */ extern unsigned long kvm_rma_pages; #endif @@ -278,7 +278,7 @@ static inline int is_vrma_hpte(unsigned long hpte_v) (HPTE_V_1TB_SEG | (VRMA_VSID << (40 - 16))); } -#ifdef CONFIG_KVM_BOOK3S_64_HV +#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE /* * Note modification of an HPTE; set the HPTE modified bit * if anyone is interested. @@ -289,6 +289,6 @@ static inline void note_hpte_modification(struct kvm *kvm, if (atomic_read(&kvm->arch.hpte_mod_interest)) rev->guest_rpte |= HPTE_GR_MODIFIED; } -#endif /* CONFIG_KVM_BOOK3S_64_HV */ +#endif /* CONFIG_KVM_BOOK3S_HV_POSSIBLE */ #endif /* __ASM_KVM_BOOK3S_64_H__ */ diff --git a/arch/powerpc/include/asm/kvm_book3s_asm.h b/arch/powerpc/include/asm/kvm_book3s_asm.h index 9039d3c97eec..0bd9348a4db9 100644 --- a/arch/powerpc/include/asm/kvm_book3s_asm.h +++ b/arch/powerpc/include/asm/kvm_book3s_asm.h @@ -83,7 +83,7 @@ struct kvmppc_host_state { u8 restore_hid5; u8 napping; -#ifdef CONFIG_KVM_BOOK3S_64_HV +#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE u8 hwthread_req; u8 hwthread_state; u8 host_ipi; @@ -101,6 +101,7 @@ struct kvmppc_host_state { #endif #ifdef CONFIG_PPC_BOOK3S_64 u64 cfar; + u64 ppr; #endif }; @@ -108,14 +109,14 @@ struct kvmppc_book3s_shadow_vcpu { ulong gpr[14]; u32 cr; u32 xer; - - u32 fault_dsisr; - u32 last_inst; ulong ctr; ulong lr; ulong pc; + ulong shadow_srr1; ulong fault_dar; + u32 fault_dsisr; + u32 last_inst; #ifdef CONFIG_PPC_BOOK3S_32 u32 sr[16]; /* Guest SRs */ diff --git a/arch/powerpc/include/asm/kvm_booke.h b/arch/powerpc/include/asm/kvm_booke.h index d3c1eb34c986..dd8f61510dfd 100644 --- a/arch/powerpc/include/asm/kvm_booke.h +++ b/arch/powerpc/include/asm/kvm_booke.h @@ -26,7 +26,12 @@ /* LPIDs we support with this build -- runtime limit may be lower */ #define KVMPPC_NR_LPIDS 64 -#define KVMPPC_INST_EHPRIV 0x7c00021c +#define KVMPPC_INST_EHPRIV 0x7c00021c +#define EHPRIV_OC_SHIFT 11 +/* "ehpriv 1" : ehpriv with OC = 1 is used for debug emulation */ +#define EHPRIV_OC_DEBUG 1 +#define KVMPPC_INST_EHPRIV_DEBUG (KVMPPC_INST_EHPRIV | \ + (EHPRIV_OC_DEBUG << EHPRIV_OC_SHIFT)) static inline void kvmppc_set_gpr(struct kvm_vcpu *vcpu, int num, ulong val) { diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 33283532e9d8..237d1d25b448 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -63,20 +63,17 @@ extern void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte); #endif -/* We don't currently support large pages. */ -#define KVM_HPAGE_GFN_SHIFT(x) 0 -#define KVM_NR_PAGE_SIZES 1 -#define KVM_PAGES_PER_HPAGE(x) (1UL<<31) - #define HPTEG_CACHE_NUM (1 << 15) #define HPTEG_HASH_BITS_PTE 13 #define HPTEG_HASH_BITS_PTE_LONG 12 #define HPTEG_HASH_BITS_VPTE 13 #define HPTEG_HASH_BITS_VPTE_LONG 5 +#define HPTEG_HASH_BITS_VPTE_64K 11 #define HPTEG_HASH_NUM_PTE (1 << HPTEG_HASH_BITS_PTE) #define HPTEG_HASH_NUM_PTE_LONG (1 << HPTEG_HASH_BITS_PTE_LONG) #define HPTEG_HASH_NUM_VPTE (1 << HPTEG_HASH_BITS_VPTE) #define HPTEG_HASH_NUM_VPTE_LONG (1 << HPTEG_HASH_BITS_VPTE_LONG) +#define HPTEG_HASH_NUM_VPTE_64K (1 << HPTEG_HASH_BITS_VPTE_64K) /* Physical Address Mask - allowed range of real mode RAM access */ #define KVM_PAM 0x0fffffffffffffffULL @@ -89,6 +86,9 @@ struct lppaca; struct slb_shadow; struct dtl_entry; +struct kvmppc_vcpu_book3s; +struct kvmppc_book3s_shadow_vcpu; + struct kvm_vm_stat { u32 remote_tlb_flush; }; @@ -224,15 +224,15 @@ struct revmap_entry { #define KVMPPC_GOT_PAGE 0x80 struct kvm_arch_memory_slot { -#ifdef CONFIG_KVM_BOOK3S_64_HV +#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE unsigned long *rmap; unsigned long *slot_phys; -#endif /* CONFIG_KVM_BOOK3S_64_HV */ +#endif /* CONFIG_KVM_BOOK3S_HV_POSSIBLE */ }; struct kvm_arch { unsigned int lpid; -#ifdef CONFIG_KVM_BOOK3S_64_HV +#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE unsigned long hpt_virt; struct revmap_entry *revmap; unsigned int host_lpid; @@ -256,7 +256,10 @@ struct kvm_arch { cpumask_t need_tlb_flush; struct kvmppc_vcore *vcores[KVM_MAX_VCORES]; int hpt_cma_alloc; -#endif /* CONFIG_KVM_BOOK3S_64_HV */ +#endif /* CONFIG_KVM_BOOK3S_HV_POSSIBLE */ +#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE + struct mutex hpt_mutex; +#endif #ifdef CONFIG_PPC_BOOK3S_64 struct list_head spapr_tce_tables; struct list_head rtas_tokens; @@ -267,6 +270,7 @@ struct kvm_arch { #ifdef CONFIG_KVM_XICS struct kvmppc_xics *xics; #endif + struct kvmppc_ops *kvm_ops; }; /* @@ -294,6 +298,10 @@ struct kvmppc_vcore { u64 stolen_tb; u64 preempt_tb; struct kvm_vcpu *runner; + u64 tb_offset; /* guest timebase - host timebase */ + ulong lpcr; + u32 arch_compat; + ulong pcr; }; #define VCORE_ENTRY_COUNT(vc) ((vc)->entry_exit_count & 0xff) @@ -328,6 +336,7 @@ struct kvmppc_pte { bool may_read : 1; bool may_write : 1; bool may_execute : 1; + u8 page_size; /* MMU_PAGE_xxx */ }; struct kvmppc_mmu { @@ -340,7 +349,8 @@ struct kvmppc_mmu { /* book3s */ void (*mtsrin)(struct kvm_vcpu *vcpu, u32 srnum, ulong value); u32 (*mfsrin)(struct kvm_vcpu *vcpu, u32 srnum); - int (*xlate)(struct kvm_vcpu *vcpu, gva_t eaddr, struct kvmppc_pte *pte, bool data); + int (*xlate)(struct kvm_vcpu *vcpu, gva_t eaddr, + struct kvmppc_pte *pte, bool data, bool iswrite); void (*reset_msr)(struct kvm_vcpu *vcpu); void (*tlbie)(struct kvm_vcpu *vcpu, ulong addr, bool large); int (*esid_to_vsid)(struct kvm_vcpu *vcpu, ulong esid, u64 *vsid); @@ -360,6 +370,7 @@ struct kvmppc_slb { bool large : 1; /* PTEs are 16MB */ bool tb : 1; /* 1TB segment */ bool class : 1; + u8 base_page_size; /* MMU_PAGE_xxx */ }; # ifdef CONFIG_PPC_FSL_BOOK3E @@ -377,17 +388,6 @@ struct kvmppc_slb { #define KVMPPC_EPR_USER 1 /* exit to userspace to fill EPR */ #define KVMPPC_EPR_KERNEL 2 /* in-kernel irqchip */ -struct kvmppc_booke_debug_reg { - u32 dbcr0; - u32 dbcr1; - u32 dbcr2; -#ifdef CONFIG_KVM_E500MC - u32 dbcr4; -#endif - u64 iac[KVMPPC_BOOKE_MAX_IAC]; - u64 dac[KVMPPC_BOOKE_MAX_DAC]; -}; - #define KVMPPC_IRQ_DEFAULT 0 #define KVMPPC_IRQ_MPIC 1 #define KVMPPC_IRQ_XICS 2 @@ -402,6 +402,10 @@ struct kvm_vcpu_arch { int slb_max; /* 1 + index of last valid entry in slb[] */ int slb_nr; /* total number of entries in SLB */ struct kvmppc_mmu mmu; + struct kvmppc_vcpu_book3s *book3s; +#endif +#ifdef CONFIG_PPC_BOOK3S_32 + struct kvmppc_book3s_shadow_vcpu *shadow_vcpu; #endif ulong gpr[32]; @@ -463,6 +467,8 @@ struct kvm_vcpu_arch { u32 ctrl; ulong dabr; ulong cfar; + ulong ppr; + ulong shadow_srr1; #endif u32 vrsave; /* also USPRG0 */ u32 mmucr; @@ -498,6 +504,8 @@ struct kvm_vcpu_arch { u64 mmcr[3]; u32 pmc[8]; + u64 siar; + u64 sdar; #ifdef CONFIG_KVM_EXIT_TIMING struct mutex exit_timing_lock; @@ -531,7 +539,10 @@ struct kvm_vcpu_arch { u32 eptcfg; u32 epr; u32 crit_save; - struct kvmppc_booke_debug_reg dbg_reg; + /* guest debug registers*/ + struct debug_reg dbg_reg; + /* hardware visible debug registers when in guest state */ + struct debug_reg shadow_dbg_reg; #endif gpa_t paddr_accessed; gva_t vaddr_accessed; @@ -582,7 +593,7 @@ struct kvm_vcpu_arch { struct kvmppc_icp *icp; /* XICS presentation controller */ #endif -#ifdef CONFIG_KVM_BOOK3S_64_HV +#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE struct kvm_vcpu_arch_shared shregs; unsigned long pgfault_addr; diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index b15554a26c20..c8317fbf92c4 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h @@ -106,13 +106,6 @@ extern void kvmppc_core_queue_external(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq); extern void kvmppc_core_dequeue_external(struct kvm_vcpu *vcpu); extern void kvmppc_core_flush_tlb(struct kvm_vcpu *vcpu); - -extern int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, - unsigned int op, int *advance); -extern int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, - ulong val); -extern int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, - ulong *val); extern int kvmppc_core_check_requests(struct kvm_vcpu *vcpu); extern int kvmppc_booke_init(void); @@ -135,17 +128,17 @@ extern long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm, struct kvm_create_spapr_tce *args); extern long kvmppc_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn, unsigned long ioba, unsigned long tce); -extern long kvm_vm_ioctl_allocate_rma(struct kvm *kvm, - struct kvm_allocate_rma *rma); extern struct kvm_rma_info *kvm_alloc_rma(void); extern void kvm_release_rma(struct kvm_rma_info *ri); extern struct page *kvm_alloc_hpt(unsigned long nr_pages); extern void kvm_release_hpt(struct page *page, unsigned long nr_pages); extern int kvmppc_core_init_vm(struct kvm *kvm); extern void kvmppc_core_destroy_vm(struct kvm *kvm); -extern void kvmppc_core_free_memslot(struct kvm_memory_slot *free, +extern void kvmppc_core_free_memslot(struct kvm *kvm, + struct kvm_memory_slot *free, struct kvm_memory_slot *dont); -extern int kvmppc_core_create_memslot(struct kvm_memory_slot *slot, +extern int kvmppc_core_create_memslot(struct kvm *kvm, + struct kvm_memory_slot *slot, unsigned long npages); extern int kvmppc_core_prepare_memory_region(struct kvm *kvm, struct kvm_memory_slot *memslot, @@ -177,6 +170,72 @@ extern int kvmppc_xics_get_xive(struct kvm *kvm, u32 irq, u32 *server, extern int kvmppc_xics_int_on(struct kvm *kvm, u32 irq); extern int kvmppc_xics_int_off(struct kvm *kvm, u32 irq); +union kvmppc_one_reg { + u32 wval; + u64 dval; + vector128 vval; + u64 vsxval[2]; + struct { + u64 addr; + u64 length; + } vpaval; +}; + +struct kvmppc_ops { + struct module *owner; + int (*get_sregs)(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs); + int (*set_sregs)(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs); + int (*get_one_reg)(struct kvm_vcpu *vcpu, u64 id, + union kvmppc_one_reg *val); + int (*set_one_reg)(struct kvm_vcpu *vcpu, u64 id, + union kvmppc_one_reg *val); + void (*vcpu_load)(struct kvm_vcpu *vcpu, int cpu); + void (*vcpu_put)(struct kvm_vcpu *vcpu); + void (*set_msr)(struct kvm_vcpu *vcpu, u64 msr); + int (*vcpu_run)(struct kvm_run *run, struct kvm_vcpu *vcpu); + struct kvm_vcpu *(*vcpu_create)(struct kvm *kvm, unsigned int id); + void (*vcpu_free)(struct kvm_vcpu *vcpu); + int (*check_requests)(struct kvm_vcpu *vcpu); + int (*get_dirty_log)(struct kvm *kvm, struct kvm_dirty_log *log); + void (*flush_memslot)(struct kvm *kvm, struct kvm_memory_slot *memslot); + int (*prepare_memory_region)(struct kvm *kvm, + struct kvm_memory_slot *memslot, + struct kvm_userspace_memory_region *mem); + void (*commit_memory_region)(struct kvm *kvm, + struct kvm_userspace_memory_region *mem, + const struct kvm_memory_slot *old); + int (*unmap_hva)(struct kvm *kvm, unsigned long hva); + int (*unmap_hva_range)(struct kvm *kvm, unsigned long start, + unsigned long end); + int (*age_hva)(struct kvm *kvm, unsigned long hva); + int (*test_age_hva)(struct kvm *kvm, unsigned long hva); + void (*set_spte_hva)(struct kvm *kvm, unsigned long hva, pte_t pte); + void (*mmu_destroy)(struct kvm_vcpu *vcpu); + void (*free_memslot)(struct kvm_memory_slot *free, + struct kvm_memory_slot *dont); + int (*create_memslot)(struct kvm_memory_slot *slot, + unsigned long npages); + int (*init_vm)(struct kvm *kvm); + void (*destroy_vm)(struct kvm *kvm); + int (*get_smmu_info)(struct kvm *kvm, struct kvm_ppc_smmu_info *info); + int (*emulate_op)(struct kvm_run *run, struct kvm_vcpu *vcpu, + unsigned int inst, int *advance); + int (*emulate_mtspr)(struct kvm_vcpu *vcpu, int sprn, ulong spr_val); + int (*emulate_mfspr)(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val); + void (*fast_vcpu_kick)(struct kvm_vcpu *vcpu); + long (*arch_vm_ioctl)(struct file *filp, unsigned int ioctl, + unsigned long arg); + +}; + +extern struct kvmppc_ops *kvmppc_hv_ops; +extern struct kvmppc_ops *kvmppc_pr_ops; + +static inline bool is_kvmppc_hv_enabled(struct kvm *kvm) +{ + return kvm->arch.kvm_ops == kvmppc_hv_ops; +} + /* * Cuts out inst bits with ordering according to spec. * That means the leftmost bit is zero. All given bits are included. @@ -210,17 +269,6 @@ static inline u32 kvmppc_set_field(u64 inst, int msb, int lsb, int value) return r; } -union kvmppc_one_reg { - u32 wval; - u64 dval; - vector128 vval; - u64 vsxval[2]; - struct { - u64 addr; - u64 length; - } vpaval; -}; - #define one_reg_size(id) \ (1ul << (((id) & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT)) @@ -245,10 +293,10 @@ union kvmppc_one_reg { __v; \ }) -void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs); +int kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs); int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs); -void kvmppc_get_sregs_ivor(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs); +int kvmppc_get_sregs_ivor(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs); int kvmppc_set_sregs_ivor(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs); int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg); @@ -260,7 +308,7 @@ void kvmppc_set_pid(struct kvm_vcpu *vcpu, u32 pid); struct openpic; -#ifdef CONFIG_KVM_BOOK3S_64_HV +#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE extern void kvm_cma_reserve(void) __init; static inline void kvmppc_set_xics_phys(int cpu, unsigned long addr) { @@ -269,10 +317,10 @@ static inline void kvmppc_set_xics_phys(int cpu, unsigned long addr) static inline u32 kvmppc_get_xics_latch(void) { - u32 xirr = get_paca()->kvm_hstate.saved_xirr; + u32 xirr; + xirr = get_paca()->kvm_hstate.saved_xirr; get_paca()->kvm_hstate.saved_xirr = 0; - return xirr; } @@ -281,7 +329,10 @@ static inline void kvmppc_set_host_ipi(int cpu, u8 host_ipi) paca[cpu].kvm_hstate.host_ipi = host_ipi; } -extern void kvmppc_fast_vcpu_kick(struct kvm_vcpu *vcpu); +static inline void kvmppc_fast_vcpu_kick(struct kvm_vcpu *vcpu) +{ + vcpu->kvm->arch.kvm_ops->fast_vcpu_kick(vcpu); +} #else static inline void __init kvm_cma_reserve(void) diff --git a/arch/powerpc/include/asm/lppaca.h b/arch/powerpc/include/asm/lppaca.h index 4470d1e34d23..844c28de7ec0 100644 --- a/arch/powerpc/include/asm/lppaca.h +++ b/arch/powerpc/include/asm/lppaca.h @@ -84,8 +84,8 @@ struct lppaca { * the processor is yielded (either because of an OS yield or a * hypervisor preempt). An even value implies that the processor is * currently executing. - * NOTE: This value will ALWAYS be zero for dedicated processors and - * will NEVER be zero for shared processors (ie, initialized to a 1). + * NOTE: Even dedicated processor partitions can yield so this + * field cannot be used to determine if we are shared or dedicated. */ volatile __be32 yield_count; volatile __be32 dispersion_count; /* dispatch changed physical cpu */ @@ -106,15 +106,15 @@ extern struct lppaca lppaca[]; #define lppaca_of(cpu) (*paca[cpu].lppaca_ptr) /* - * Old kernels used a reserved bit in the VPA to determine if it was running - * in shared processor mode. New kernels look for a non zero yield count - * but KVM still needs to set the bit to keep the old stuff happy. + * We are using a non architected field to determine if a partition is + * shared or dedicated. This currently works on both KVM and PHYP, but + * we will have to transition to something better. */ #define LPPACA_OLD_SHARED_PROC 2 static inline bool lppaca_shared_proc(struct lppaca *l) { - return l->yield_count != 0; + return !!(l->__old_status & LPPACA_OLD_SHARED_PROC); } /* diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h index 8b480901165a..ad3025d0880b 100644 --- a/arch/powerpc/include/asm/machdep.h +++ b/arch/powerpc/include/asm/machdep.h @@ -78,6 +78,18 @@ struct machdep_calls { long index); void (*tce_flush)(struct iommu_table *tbl); + /* _rm versions are for real mode use only */ + int (*tce_build_rm)(struct iommu_table *tbl, + long index, + long npages, + unsigned long uaddr, + enum dma_data_direction direction, + struct dma_attrs *attrs); + void (*tce_free_rm)(struct iommu_table *tbl, + long index, + long npages); + void (*tce_flush_rm)(struct iommu_table *tbl); + void __iomem * (*ioremap)(phys_addr_t addr, unsigned long size, unsigned long flags, void *caller); void (*iounmap)(volatile void __iomem *token); @@ -263,6 +275,10 @@ struct machdep_calls { ssize_t (*cpu_probe)(const char *, size_t); ssize_t (*cpu_release)(const char *, size_t); #endif + +#ifdef CONFIG_ARCH_RANDOM + int (*get_random_long)(unsigned long *v); +#endif }; extern void e500_idle(void); diff --git a/arch/powerpc/include/asm/mmu-hash64.h b/arch/powerpc/include/asm/mmu-hash64.h index c4cf01197273..807014dde821 100644 --- a/arch/powerpc/include/asm/mmu-hash64.h +++ b/arch/powerpc/include/asm/mmu-hash64.h @@ -135,8 +135,8 @@ extern char initial_stab[]; #ifndef __ASSEMBLY__ struct hash_pte { - unsigned long v; - unsigned long r; + __be64 v; + __be64 r; }; extern struct hash_pte *htab_address; diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index c5cd72833d6e..033c06be1d84 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h @@ -129,6 +129,9 @@ extern int opal_enter_rtas(struct rtas_args *args, #define OPAL_LPC_READ 67 #define OPAL_LPC_WRITE 68 #define OPAL_RETURN_CPU 69 +#define OPAL_FLASH_VALIDATE 76 +#define OPAL_FLASH_MANAGE 77 +#define OPAL_FLASH_UPDATE 78 #ifndef __ASSEMBLY__ @@ -460,10 +463,12 @@ enum { enum { OPAL_PHB_ERROR_DATA_TYPE_P7IOC = 1, + OPAL_PHB_ERROR_DATA_TYPE_PHB3 = 2 }; enum { OPAL_P7IOC_NUM_PEST_REGS = 128, + OPAL_PHB3_NUM_PEST_REGS = 256 }; struct OpalIoPhbErrorCommon { @@ -531,28 +536,94 @@ struct OpalIoP7IOCPhbErrorData { uint64_t pestB[OPAL_P7IOC_NUM_PEST_REGS]; }; +struct OpalIoPhb3ErrorData { + struct OpalIoPhbErrorCommon common; + + uint32_t brdgCtl; + + /* PHB3 UTL regs */ + uint32_t portStatusReg; + uint32_t rootCmplxStatus; + uint32_t busAgentStatus; + + /* PHB3 cfg regs */ + uint32_t deviceStatus; + uint32_t slotStatus; + uint32_t linkStatus; + uint32_t devCmdStatus; + uint32_t devSecStatus; + + /* cfg AER regs */ + uint32_t rootErrorStatus; + uint32_t uncorrErrorStatus; + uint32_t corrErrorStatus; + uint32_t tlpHdr1; + uint32_t tlpHdr2; + uint32_t tlpHdr3; + uint32_t tlpHdr4; + uint32_t sourceId; + + uint32_t rsv3; + + /* Record data about the call to allocate a buffer */ + uint64_t errorClass; + uint64_t correlator; + + uint64_t nFir; /* 000 */ + uint64_t nFirMask; /* 003 */ + uint64_t nFirWOF; /* 008 */ + + /* PHB3 MMIO Error Regs */ + uint64_t phbPlssr; /* 120 */ + uint64_t phbCsr; /* 110 */ + uint64_t lemFir; /* C00 */ + uint64_t lemErrorMask; /* C18 */ + uint64_t lemWOF; /* C40 */ + uint64_t phbErrorStatus; /* C80 */ + uint64_t phbFirstErrorStatus; /* C88 */ + uint64_t phbErrorLog0; /* CC0 */ + uint64_t phbErrorLog1; /* CC8 */ + uint64_t mmioErrorStatus; /* D00 */ + uint64_t mmioFirstErrorStatus; /* D08 */ + uint64_t mmioErrorLog0; /* D40 */ + uint64_t mmioErrorLog1; /* D48 */ + uint64_t dma0ErrorStatus; /* D80 */ + uint64_t dma0FirstErrorStatus; /* D88 */ + uint64_t dma0ErrorLog0; /* DC0 */ + uint64_t dma0ErrorLog1; /* DC8 */ + uint64_t dma1ErrorStatus; /* E00 */ + uint64_t dma1FirstErrorStatus; /* E08 */ + uint64_t dma1ErrorLog0; /* E40 */ + uint64_t dma1ErrorLog1; /* E48 */ + uint64_t pestA[OPAL_PHB3_NUM_PEST_REGS]; + uint64_t pestB[OPAL_PHB3_NUM_PEST_REGS]; +}; + typedef struct oppanel_line { const char * line; uint64_t line_len; } oppanel_line_t; +/* /sys/firmware/opal */ +extern struct kobject *opal_kobj; + /* API functions */ -int64_t opal_console_write(int64_t term_number, int64_t *length, +int64_t opal_console_write(int64_t term_number, __be64 *length, const uint8_t *buffer); -int64_t opal_console_read(int64_t term_number, int64_t *length, +int64_t opal_console_read(int64_t term_number, __be64 *length, uint8_t *buffer); int64_t opal_console_write_buffer_space(int64_t term_number, - int64_t *length); -int64_t opal_rtc_read(uint32_t *year_month_day, - uint64_t *hour_minute_second_millisecond); + __be64 *length); +int64_t opal_rtc_read(__be32 *year_month_day, + __be64 *hour_minute_second_millisecond); int64_t opal_rtc_write(uint32_t year_month_day, uint64_t hour_minute_second_millisecond); int64_t opal_cec_power_down(uint64_t request); int64_t opal_cec_reboot(void); int64_t opal_read_nvram(uint64_t buffer, uint64_t size, uint64_t offset); int64_t opal_write_nvram(uint64_t buffer, uint64_t size, uint64_t offset); -int64_t opal_handle_interrupt(uint64_t isn, uint64_t *outstanding_event_mask); -int64_t opal_poll_events(uint64_t *outstanding_event_mask); +int64_t opal_handle_interrupt(uint64_t isn, __be64 *outstanding_event_mask); +int64_t opal_poll_events(__be64 *outstanding_event_mask); int64_t opal_pci_set_hub_tce_memory(uint64_t hub_id, uint64_t tce_mem_addr, uint64_t tce_mem_size); int64_t opal_pci_set_phb_tce_memory(uint64_t phb_id, uint64_t tce_mem_addr, @@ -560,9 +631,9 @@ int64_t opal_pci_set_phb_tce_memory(uint64_t phb_id, uint64_t tce_mem_addr, int64_t opal_pci_config_read_byte(uint64_t phb_id, uint64_t bus_dev_func, uint64_t offset, uint8_t *data); int64_t opal_pci_config_read_half_word(uint64_t phb_id, uint64_t bus_dev_func, - uint64_t offset, uint16_t *data); + uint64_t offset, __be16 *data); int64_t opal_pci_config_read_word(uint64_t phb_id, uint64_t bus_dev_func, - uint64_t offset, uint32_t *data); + uint64_t offset, __be32 *data); int64_t opal_pci_config_write_byte(uint64_t phb_id, uint64_t bus_dev_func, uint64_t offset, uint8_t data); int64_t opal_pci_config_write_half_word(uint64_t phb_id, uint64_t bus_dev_func, @@ -570,14 +641,14 @@ int64_t opal_pci_config_write_half_word(uint64_t phb_id, uint64_t bus_dev_func, int64_t opal_pci_config_write_word(uint64_t phb_id, uint64_t bus_dev_func, uint64_t offset, uint32_t data); int64_t opal_set_xive(uint32_t isn, uint16_t server, uint8_t priority); -int64_t opal_get_xive(uint32_t isn, uint16_t *server, uint8_t *priority); +int64_t opal_get_xive(uint32_t isn, __be16 *server, uint8_t *priority); int64_t opal_register_exception_handler(uint64_t opal_exception, uint64_t handler_address, uint64_t glue_cache_line); int64_t opal_pci_eeh_freeze_status(uint64_t phb_id, uint64_t pe_number, uint8_t *freeze_state, - uint16_t *pci_error_type, - uint64_t *phb_status); + __be16 *pci_error_type, + __be64 *phb_status); int64_t opal_pci_eeh_freeze_clear(uint64_t phb_id, uint64_t pe_number, uint64_t eeh_action_token); int64_t opal_pci_shpc(uint64_t phb_id, uint64_t shpc_action, uint8_t *state); @@ -614,13 +685,13 @@ int64_t opal_pci_msi_eoi(uint64_t phb_id, uint32_t hw_irq); int64_t opal_pci_set_xive_pe(uint64_t phb_id, uint32_t pe_number, uint32_t xive_num); int64_t opal_get_xive_source(uint64_t phb_id, uint32_t xive_num, - int32_t *interrupt_source_number); + __be32 *interrupt_source_number); int64_t opal_get_msi_32(uint64_t phb_id, uint32_t mve_number, uint32_t xive_num, - uint8_t msi_range, uint32_t *msi_address, - uint32_t *message_data); + uint8_t msi_range, __be32 *msi_address, + __be32 *message_data); int64_t opal_get_msi_64(uint64_t phb_id, uint32_t mve_number, uint32_t xive_num, uint8_t msi_range, - uint64_t *msi_address, uint32_t *message_data); + __be64 *msi_address, __be32 *message_data); int64_t opal_start_cpu(uint64_t thread_number, uint64_t start_address); int64_t opal_query_cpu_status(uint64_t thread_number, uint8_t *thread_status); int64_t opal_write_oppanel(oppanel_line_t *lines, uint64_t num_lines); @@ -642,7 +713,7 @@ int64_t opal_pci_fence_phb(uint64_t phb_id); int64_t opal_pci_reinit(uint64_t phb_id, uint8_t reinit_scope); int64_t opal_pci_mask_pe_error(uint64_t phb_id, uint16_t pe_number, uint8_t error_type, uint8_t mask_action); int64_t opal_set_slot_led_status(uint64_t phb_id, uint64_t slot_id, uint8_t led_type, uint8_t led_action); -int64_t opal_get_epow_status(uint64_t *status); +int64_t opal_get_epow_status(__be64 *status); int64_t opal_set_system_attention_led(uint8_t led_action); int64_t opal_pci_next_error(uint64_t phb_id, uint64_t *first_frozen_pe, uint16_t *pci_error_type, uint16_t *severity); @@ -656,6 +727,9 @@ int64_t opal_lpc_write(uint32_t chip_id, enum OpalLPCAddressType addr_type, uint32_t addr, uint32_t data, uint32_t sz); int64_t opal_lpc_read(uint32_t chip_id, enum OpalLPCAddressType addr_type, uint32_t addr, uint32_t *data, uint32_t sz); +int64_t opal_validate_flash(uint64_t buffer, uint32_t *size, uint32_t *result); +int64_t opal_manage_flash(uint8_t op); +int64_t opal_update_flash(uint64_t blk_list); /* Internal functions */ extern int early_init_dt_scan_opal(unsigned long node, const char *uname, int depth, void *data); @@ -684,6 +758,7 @@ extern int opal_set_rtc_time(struct rtc_time *tm); extern void opal_get_rtc_time(struct rtc_time *tm); extern unsigned long opal_get_boot_time(void); extern void opal_nvram_init(void); +extern void opal_flash_init(void); extern int opal_machine_check(struct pt_regs *regs); diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h index a5954cebbc55..b6ea9e068c13 100644 --- a/arch/powerpc/include/asm/paca.h +++ b/arch/powerpc/include/asm/paca.h @@ -166,7 +166,7 @@ struct paca_struct { struct dtl_entry *dtl_curr; /* pointer corresponding to dtl_ridx */ #ifdef CONFIG_KVM_BOOK3S_HANDLER -#ifdef CONFIG_KVM_BOOK3S_PR +#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE /* We use this to store guest state in */ struct kvmppc_book3s_shadow_vcpu shadow_vcpu; #endif diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h index b9f426212d3a..32e4e212b9c1 100644 --- a/arch/powerpc/include/asm/page.h +++ b/arch/powerpc/include/asm/page.h @@ -78,7 +78,7 @@ extern unsigned int HPAGE_SHIFT; * * Also, KERNELBASE >= PAGE_OFFSET and PHYSICAL_START >= MEMORY_START * - * There are two was to determine a physical address from a virtual one: + * There are two ways to determine a physical address from a virtual one: * va = pa + PAGE_OFFSET - MEMORY_START * va = pa + KERNELBASE - PHYSICAL_START * @@ -403,7 +403,7 @@ void arch_free_page(struct page *page, int order); struct vm_area_struct; -#ifdef CONFIG_PPC_64K_PAGES +#if defined(CONFIG_PPC_64K_PAGES) && defined(CONFIG_PPC64) typedef pte_t *pgtable_t; #else typedef struct page *pgtable_t; diff --git a/arch/powerpc/include/asm/pgalloc-64.h b/arch/powerpc/include/asm/pgalloc-64.h index f65e27b09bd3..16cb92d215d2 100644 --- a/arch/powerpc/include/asm/pgalloc-64.h +++ b/arch/powerpc/include/asm/pgalloc-64.h @@ -91,7 +91,10 @@ static inline pgtable_t pte_alloc_one(struct mm_struct *mm, if (!pte) return NULL; page = virt_to_page(pte); - pgtable_page_ctor(page); + if (!pgtable_page_ctor(page)) { + __free_page(page); + return NULL; + } return page; } diff --git a/arch/powerpc/include/asm/pgtable-ppc64.h b/arch/powerpc/include/asm/pgtable-ppc64.h index 46db09414a10..4a191c472867 100644 --- a/arch/powerpc/include/asm/pgtable-ppc64.h +++ b/arch/powerpc/include/asm/pgtable-ppc64.h @@ -394,6 +394,8 @@ static inline void mark_hpte_slot_valid(unsigned char *hpte_slot_array, hpte_slot_array[index] = hidx << 4 | 0x1 << 3; } +struct page *realmode_pfn_to_page(unsigned long pfn); + static inline char *get_hpte_slot_array(pmd_t *pmdp) { /* diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h index d7fe9f5b46d4..3132bb9365f3 100644 --- a/arch/powerpc/include/asm/ppc-opcode.h +++ b/arch/powerpc/include/asm/ppc-opcode.h @@ -143,6 +143,8 @@ #define PPC_INST_LSWX 0x7c00042a #define PPC_INST_LWARX 0x7c000028 #define PPC_INST_LWSYNC 0x7c2004ac +#define PPC_INST_SYNC 0x7c0004ac +#define PPC_INST_SYNC_MASK 0xfc0007fe #define PPC_INST_LXVD2X 0x7c000698 #define PPC_INST_MCRXR 0x7c000400 #define PPC_INST_MCRXR_MASK 0xfc0007fe @@ -181,6 +183,7 @@ #define PPC_INST_TLBIVAX 0x7c000624 #define PPC_INST_TLBSRX_DOT 0x7c0006a5 #define PPC_INST_XXLOR 0xf0000510 +#define PPC_INST_XXSWAPD 0xf0000250 #define PPC_INST_XVCPSGNDP 0xf0000780 #define PPC_INST_TRECHKPT 0x7c0007dd #define PPC_INST_TRECLAIM 0x7c00075d @@ -200,6 +203,7 @@ /* Misc instructions for BPF compiler */ #define PPC_INST_LD 0xe8000000 #define PPC_INST_LHZ 0xa0000000 +#define PPC_INST_LHBRX 0x7c00062c #define PPC_INST_LWZ 0x80000000 #define PPC_INST_STD 0xf8000000 #define PPC_INST_STDU 0xf8000001 @@ -218,7 +222,7 @@ #define PPC_INST_MULLW 0x7c0001d6 #define PPC_INST_MULHWU 0x7c000016 #define PPC_INST_MULLI 0x1c000000 -#define PPC_INST_DIVWU 0x7c0003d6 +#define PPC_INST_DIVWU 0x7c000396 #define PPC_INST_RLWINM 0x54000000 #define PPC_INST_RLDICR 0x78000004 #define PPC_INST_SLW 0x7c000030 @@ -344,6 +348,8 @@ VSX_XX1((s), a, b)) #define XXLOR(t, a, b) stringify_in_c(.long PPC_INST_XXLOR | \ VSX_XX3((t), a, b)) +#define XXSWAPD(t, a) stringify_in_c(.long PPC_INST_XXSWAPD | \ + VSX_XX3((t), a, a)) #define XVCPSGNDP(t, a, b) stringify_in_c(.long (PPC_INST_XVCPSGNDP | \ VSX_XX3((t), (a), (b)))) diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h index 599545738af3..3c1acc31a092 100644 --- a/arch/powerpc/include/asm/ppc_asm.h +++ b/arch/powerpc/include/asm/ppc_asm.h @@ -98,123 +98,51 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR) #define REST_8GPRS(n, base) REST_4GPRS(n, base); REST_4GPRS(n+4, base) #define REST_10GPRS(n, base) REST_8GPRS(n, base); REST_2GPRS(n+8, base) -#define SAVE_FPR(n, base) stfd n,THREAD_FPR0+8*TS_FPRWIDTH*(n)(base) +#define SAVE_FPR(n, base) stfd n,8*TS_FPRWIDTH*(n)(base) #define SAVE_2FPRS(n, base) SAVE_FPR(n, base); SAVE_FPR(n+1, base) #define SAVE_4FPRS(n, base) SAVE_2FPRS(n, base); SAVE_2FPRS(n+2, base) #define SAVE_8FPRS(n, base) SAVE_4FPRS(n, base); SAVE_4FPRS(n+4, base) #define SAVE_16FPRS(n, base) SAVE_8FPRS(n, base); SAVE_8FPRS(n+8, base) #define SAVE_32FPRS(n, base) SAVE_16FPRS(n, base); SAVE_16FPRS(n+16, base) -#define REST_FPR(n, base) lfd n,THREAD_FPR0+8*TS_FPRWIDTH*(n)(base) +#define REST_FPR(n, base) lfd n,8*TS_FPRWIDTH*(n)(base) #define REST_2FPRS(n, base) REST_FPR(n, base); REST_FPR(n+1, base) #define REST_4FPRS(n, base) REST_2FPRS(n, base); REST_2FPRS(n+2, base) #define REST_8FPRS(n, base) REST_4FPRS(n, base); REST_4FPRS(n+4, base) #define REST_16FPRS(n, base) REST_8FPRS(n, base); REST_8FPRS(n+8, base) #define REST_32FPRS(n, base) REST_16FPRS(n, base); REST_16FPRS(n+16, base) -#define SAVE_VR(n,b,base) li b,THREAD_VR0+(16*(n)); stvx n,base,b +#define SAVE_VR(n,b,base) li b,16*(n); stvx n,base,b #define SAVE_2VRS(n,b,base) SAVE_VR(n,b,base); SAVE_VR(n+1,b,base) #define SAVE_4VRS(n,b,base) SAVE_2VRS(n,b,base); SAVE_2VRS(n+2,b,base) #define SAVE_8VRS(n,b,base) SAVE_4VRS(n,b,base); SAVE_4VRS(n+4,b,base) #define SAVE_16VRS(n,b,base) SAVE_8VRS(n,b,base); SAVE_8VRS(n+8,b,base) #define SAVE_32VRS(n,b,base) SAVE_16VRS(n,b,base); SAVE_16VRS(n+16,b,base) -#define REST_VR(n,b,base) li b,THREAD_VR0+(16*(n)); lvx n,base,b +#define REST_VR(n,b,base) li b,16*(n); lvx n,base,b #define REST_2VRS(n,b,base) REST_VR(n,b,base); REST_VR(n+1,b,base) #define REST_4VRS(n,b,base) REST_2VRS(n,b,base); REST_2VRS(n+2,b,base) #define REST_8VRS(n,b,base) REST_4VRS(n,b,base); REST_4VRS(n+4,b,base) #define REST_16VRS(n,b,base) REST_8VRS(n,b,base); REST_8VRS(n+8,b,base) #define REST_32VRS(n,b,base) REST_16VRS(n,b,base); REST_16VRS(n+16,b,base) -/* Save/restore FPRs, VRs and VSRs from their checkpointed backups in - * thread_struct: - */ -#define SAVE_FPR_TRANSACT(n, base) stfd n,THREAD_TRANSACT_FPR0+ \ - 8*TS_FPRWIDTH*(n)(base) -#define SAVE_2FPRS_TRANSACT(n, base) SAVE_FPR_TRANSACT(n, base); \ - SAVE_FPR_TRANSACT(n+1, base) -#define SAVE_4FPRS_TRANSACT(n, base) SAVE_2FPRS_TRANSACT(n, base); \ - SAVE_2FPRS_TRANSACT(n+2, base) -#define SAVE_8FPRS_TRANSACT(n, base) SAVE_4FPRS_TRANSACT(n, base); \ - SAVE_4FPRS_TRANSACT(n+4, base) -#define SAVE_16FPRS_TRANSACT(n, base) SAVE_8FPRS_TRANSACT(n, base); \ - SAVE_8FPRS_TRANSACT(n+8, base) -#define SAVE_32FPRS_TRANSACT(n, base) SAVE_16FPRS_TRANSACT(n, base); \ - SAVE_16FPRS_TRANSACT(n+16, base) - -#define REST_FPR_TRANSACT(n, base) lfd n,THREAD_TRANSACT_FPR0+ \ - 8*TS_FPRWIDTH*(n)(base) -#define REST_2FPRS_TRANSACT(n, base) REST_FPR_TRANSACT(n, base); \ - REST_FPR_TRANSACT(n+1, base) -#define REST_4FPRS_TRANSACT(n, base) REST_2FPRS_TRANSACT(n, base); \ - REST_2FPRS_TRANSACT(n+2, base) -#define REST_8FPRS_TRANSACT(n, base) REST_4FPRS_TRANSACT(n, base); \ - REST_4FPRS_TRANSACT(n+4, base) -#define REST_16FPRS_TRANSACT(n, base) REST_8FPRS_TRANSACT(n, base); \ - REST_8FPRS_TRANSACT(n+8, base) -#define REST_32FPRS_TRANSACT(n, base) REST_16FPRS_TRANSACT(n, base); \ - REST_16FPRS_TRANSACT(n+16, base) - - -#define SAVE_VR_TRANSACT(n,b,base) li b,THREAD_TRANSACT_VR0+(16*(n)); \ - stvx n,b,base -#define SAVE_2VRS_TRANSACT(n,b,base) SAVE_VR_TRANSACT(n,b,base); \ - SAVE_VR_TRANSACT(n+1,b,base) -#define SAVE_4VRS_TRANSACT(n,b,base) SAVE_2VRS_TRANSACT(n,b,base); \ - SAVE_2VRS_TRANSACT(n+2,b,base) -#define SAVE_8VRS_TRANSACT(n,b,base) SAVE_4VRS_TRANSACT(n,b,base); \ - SAVE_4VRS_TRANSACT(n+4,b,base) -#define SAVE_16VRS_TRANSACT(n,b,base) SAVE_8VRS_TRANSACT(n,b,base); \ - SAVE_8VRS_TRANSACT(n+8,b,base) -#define SAVE_32VRS_TRANSACT(n,b,base) SAVE_16VRS_TRANSACT(n,b,base); \ - SAVE_16VRS_TRANSACT(n+16,b,base) - -#define REST_VR_TRANSACT(n,b,base) li b,THREAD_TRANSACT_VR0+(16*(n)); \ - lvx n,b,base -#define REST_2VRS_TRANSACT(n,b,base) REST_VR_TRANSACT(n,b,base); \ - REST_VR_TRANSACT(n+1,b,base) -#define REST_4VRS_TRANSACT(n,b,base) REST_2VRS_TRANSACT(n,b,base); \ - REST_2VRS_TRANSACT(n+2,b,base) -#define REST_8VRS_TRANSACT(n,b,base) REST_4VRS_TRANSACT(n,b,base); \ - REST_4VRS_TRANSACT(n+4,b,base) -#define REST_16VRS_TRANSACT(n,b,base) REST_8VRS_TRANSACT(n,b,base); \ - REST_8VRS_TRANSACT(n+8,b,base) -#define REST_32VRS_TRANSACT(n,b,base) REST_16VRS_TRANSACT(n,b,base); \ - REST_16VRS_TRANSACT(n+16,b,base) - - -#define SAVE_VSR_TRANSACT(n,b,base) li b,THREAD_TRANSACT_VSR0+(16*(n)); \ - STXVD2X(n,R##base,R##b) -#define SAVE_2VSRS_TRANSACT(n,b,base) SAVE_VSR_TRANSACT(n,b,base); \ - SAVE_VSR_TRANSACT(n+1,b,base) -#define SAVE_4VSRS_TRANSACT(n,b,base) SAVE_2VSRS_TRANSACT(n,b,base); \ - SAVE_2VSRS_TRANSACT(n+2,b,base) -#define SAVE_8VSRS_TRANSACT(n,b,base) SAVE_4VSRS_TRANSACT(n,b,base); \ - SAVE_4VSRS_TRANSACT(n+4,b,base) -#define SAVE_16VSRS_TRANSACT(n,b,base) SAVE_8VSRS_TRANSACT(n,b,base); \ - SAVE_8VSRS_TRANSACT(n+8,b,base) -#define SAVE_32VSRS_TRANSACT(n,b,base) SAVE_16VSRS_TRANSACT(n,b,base); \ - SAVE_16VSRS_TRANSACT(n+16,b,base) - -#define REST_VSR_TRANSACT(n,b,base) li b,THREAD_TRANSACT_VSR0+(16*(n)); \ - LXVD2X(n,R##base,R##b) -#define REST_2VSRS_TRANSACT(n,b,base) REST_VSR_TRANSACT(n,b,base); \ - REST_VSR_TRANSACT(n+1,b,base) -#define REST_4VSRS_TRANSACT(n,b,base) REST_2VSRS_TRANSACT(n,b,base); \ - REST_2VSRS_TRANSACT(n+2,b,base) -#define REST_8VSRS_TRANSACT(n,b,base) REST_4VSRS_TRANSACT(n,b,base); \ - REST_4VSRS_TRANSACT(n+4,b,base) -#define REST_16VSRS_TRANSACT(n,b,base) REST_8VSRS_TRANSACT(n,b,base); \ - REST_8VSRS_TRANSACT(n+8,b,base) -#define REST_32VSRS_TRANSACT(n,b,base) REST_16VSRS_TRANSACT(n,b,base); \ - REST_16VSRS_TRANSACT(n+16,b,base) +#ifdef __BIG_ENDIAN__ +#define STXVD2X_ROT(n,b,base) STXVD2X(n,b,base) +#define LXVD2X_ROT(n,b,base) LXVD2X(n,b,base) +#else +#define STXVD2X_ROT(n,b,base) XXSWAPD(n,n); \ + STXVD2X(n,b,base); \ + XXSWAPD(n,n) +#define LXVD2X_ROT(n,b,base) LXVD2X(n,b,base); \ + XXSWAPD(n,n) +#endif /* Save the lower 32 VSRs in the thread VSR region */ -#define SAVE_VSR(n,b,base) li b,THREAD_VSR0+(16*(n)); STXVD2X(n,R##base,R##b) +#define SAVE_VSR(n,b,base) li b,16*(n); STXVD2X_ROT(n,R##base,R##b) #define SAVE_2VSRS(n,b,base) SAVE_VSR(n,b,base); SAVE_VSR(n+1,b,base) #define SAVE_4VSRS(n,b,base) SAVE_2VSRS(n,b,base); SAVE_2VSRS(n+2,b,base) #define SAVE_8VSRS(n,b,base) SAVE_4VSRS(n,b,base); SAVE_4VSRS(n+4,b,base) #define SAVE_16VSRS(n,b,base) SAVE_8VSRS(n,b,base); SAVE_8VSRS(n+8,b,base) #define SAVE_32VSRS(n,b,base) SAVE_16VSRS(n,b,base); SAVE_16VSRS(n+16,b,base) -#define REST_VSR(n,b,base) li b,THREAD_VSR0+(16*(n)); LXVD2X(n,R##base,R##b) +#define REST_VSR(n,b,base) li b,16*(n); LXVD2X_ROT(n,R##base,R##b) #define REST_2VSRS(n,b,base) REST_VSR(n,b,base); REST_VSR(n+1,b,base) #define REST_4VSRS(n,b,base) REST_2VSRS(n,b,base); REST_2VSRS(n+2,b,base) #define REST_8VSRS(n,b,base) REST_4VSRS(n,b,base); REST_4VSRS(n+4,b,base) @@ -478,13 +406,6 @@ BEGIN_FTR_SECTION_NESTED(945) \ std ra,TASKTHREADPPR(rb); \ END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,945) -#define RESTORE_PPR(ra, rb) \ -BEGIN_FTR_SECTION_NESTED(946) \ - ld ra,PACACURRENT(r13); \ - ld rb,TASKTHREADPPR(ra); \ - mtspr SPRN_PPR,rb; /* Restore PPR */ \ -END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,946) - #endif /* @@ -832,6 +753,35 @@ END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,946) #define N_SLINE 68 #define N_SO 100 -#endif /* __ASSEMBLY__ */ +/* + * Create an endian fixup trampoline + * + * This starts with a "tdi 0,0,0x48" instruction which is + * essentially a "trap never", and thus akin to a nop. + * + * The opcode for this instruction read with the wrong endian + * however results in a b . + 8 + * + * So essentially we use that trick to execute the following + * trampoline in "reverse endian" if we are running with the + * MSR_LE bit set the "wrong" way for whatever endianness the + * kernel is built for. + */ +#ifdef CONFIG_PPC_BOOK3E +#define FIXUP_ENDIAN +#else +#define FIXUP_ENDIAN \ + tdi 0,0,0x48; /* Reverse endian of b . + 8 */ \ + b $+36; /* Skip trampoline if endian is good */ \ + .long 0x05009f42; /* bcl 20,31,$+4 */ \ + .long 0xa602487d; /* mflr r10 */ \ + .long 0x1c004a39; /* addi r10,r10,28 */ \ + .long 0xa600607d; /* mfmsr r11 */ \ + .long 0x01006b69; /* xori r11,r11,1 */ \ + .long 0xa6035a7d; /* mtsrr0 r10 */ \ + .long 0xa6037b7d; /* mtsrr1 r11 */ \ + .long 0x2400004c /* rfid */ +#endif /* !CONFIG_PPC_BOOK3E */ +#endif /* __ASSEMBLY__ */ #endif /* _ASM_POWERPC_PPC_ASM_H */ diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index ce4de5aed7b5..fc14a38c7ccf 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -14,8 +14,18 @@ #ifdef CONFIG_VSX #define TS_FPRWIDTH 2 + +#ifdef __BIG_ENDIAN__ +#define TS_FPROFFSET 0 +#define TS_VSRLOWOFFSET 1 +#else +#define TS_FPROFFSET 1 +#define TS_VSRLOWOFFSET 0 +#endif + #else #define TS_FPRWIDTH 1 +#define TS_FPROFFSET 0 #endif #ifdef CONFIG_PPC64 @@ -142,26 +152,22 @@ typedef struct { unsigned long seg; } mm_segment_t; -#define TS_FPROFFSET 0 -#define TS_VSRLOWOFFSET 1 -#define TS_FPR(i) fpr[i][TS_FPROFFSET] -#define TS_TRANS_FPR(i) transact_fpr[i][TS_FPROFFSET] +#define TS_FPR(i) fp_state.fpr[i][TS_FPROFFSET] +#define TS_TRANS_FPR(i) transact_fp.fpr[i][TS_FPROFFSET] -struct thread_struct { - unsigned long ksp; /* Kernel stack pointer */ -#ifdef CONFIG_PPC64 - unsigned long ksp_vsid; -#endif - struct pt_regs *regs; /* Pointer to saved register state */ - mm_segment_t fs; /* for get_fs() validation */ -#ifdef CONFIG_BOOKE - /* BookE base exception scratch space; align on cacheline */ - unsigned long normsave[8] ____cacheline_aligned; -#endif -#ifdef CONFIG_PPC32 - void *pgdir; /* root of page-table tree */ - unsigned long ksp_limit; /* if ksp <= ksp_limit stack overflow */ -#endif +/* FP and VSX 0-31 register set */ +struct thread_fp_state { + u64 fpr[32][TS_FPRWIDTH] __attribute__((aligned(16))); + u64 fpscr; /* Floating point status */ +}; + +/* Complete AltiVec register set including VSCR */ +struct thread_vr_state { + vector128 vr[32] __attribute__((aligned(16))); + vector128 vscr __attribute__((aligned(16))); +}; + +struct debug_reg { #ifdef CONFIG_PPC_ADV_DEBUG_REGS /* * The following help to manage the use of Debug Control Registers @@ -198,13 +204,28 @@ struct thread_struct { unsigned long dvc2; #endif #endif - /* FP and VSX 0-31 register set */ - double fpr[32][TS_FPRWIDTH] __attribute__((aligned(16))); - struct { +}; - unsigned int pad; - unsigned int val; /* Floating point status */ - } fpscr; +struct thread_struct { + unsigned long ksp; /* Kernel stack pointer */ + +#ifdef CONFIG_PPC64 + unsigned long ksp_vsid; +#endif + struct pt_regs *regs; /* Pointer to saved register state */ + mm_segment_t fs; /* for get_fs() validation */ +#ifdef CONFIG_BOOKE + /* BookE base exception scratch space; align on cacheline */ + unsigned long normsave[8] ____cacheline_aligned; +#endif +#ifdef CONFIG_PPC32 + void *pgdir; /* root of page-table tree */ + unsigned long ksp_limit; /* if ksp <= ksp_limit stack overflow */ +#endif + /* Debug Registers */ + struct debug_reg debug; + struct thread_fp_state fp_state; + struct thread_fp_state *fp_save_area; int fpexc_mode; /* floating-point exception mode */ unsigned int align_ctl; /* alignment handling control */ #ifdef CONFIG_PPC64 @@ -222,10 +243,8 @@ struct thread_struct { struct arch_hw_breakpoint hw_brk; /* info on the hardware breakpoint */ unsigned long trap_nr; /* last trap # on this thread */ #ifdef CONFIG_ALTIVEC - /* Complete AltiVec register set */ - vector128 vr[32] __attribute__((aligned(16))); - /* AltiVec status */ - vector128 vscr __attribute__((aligned(16))); + struct thread_vr_state vr_state; + struct thread_vr_state *vr_save_area; unsigned long vrsave; int used_vr; /* set if process has used altivec */ #endif /* CONFIG_ALTIVEC */ @@ -262,13 +281,8 @@ struct thread_struct { * transact_fpr[] is the new set of transactional values. * VRs work the same way. */ - double transact_fpr[32][TS_FPRWIDTH]; - struct { - unsigned int pad; - unsigned int val; /* Floating point status */ - } transact_fpscr; - vector128 transact_vr[32] __attribute__((aligned(16))); - vector128 transact_vscr __attribute__((aligned(16))); + struct thread_fp_state transact_fp; + struct thread_vr_state transact_vr; unsigned long transact_vrsave; #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ #ifdef CONFIG_KVM_BOOK3S_32_HANDLER @@ -322,8 +336,6 @@ struct thread_struct { .ksp = INIT_SP, \ .regs = (struct pt_regs *)INIT_SP - 1, /* XXX bogus, I think */ \ .fs = KERNEL_DS, \ - .fpr = {{0}}, \ - .fpscr = { .val = 0, }, \ .fpexc_mode = 0, \ .ppr = INIT_PPR, \ } @@ -361,6 +373,11 @@ extern int set_endian(struct task_struct *tsk, unsigned int val); extern int get_unalign_ctl(struct task_struct *tsk, unsigned long adr); extern int set_unalign_ctl(struct task_struct *tsk, unsigned int val); +extern void load_fp_state(struct thread_fp_state *fp); +extern void store_fp_state(struct thread_fp_state *fp); +extern void load_vr_state(struct thread_vr_state *vr); +extern void store_vr_state(struct thread_vr_state *vr); + static inline unsigned int __unpack_fe01(unsigned long msr_bits) { return ((msr_bits & MSR_FE0) >> 10) | ((msr_bits & MSR_FE1) >> 8); diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h index 7d0c7f3a7171..d977b9b78696 100644 --- a/arch/powerpc/include/asm/prom.h +++ b/arch/powerpc/include/asm/prom.h @@ -1,4 +1,3 @@ -#include <linux/of.h> /* linux/of.h gets to determine #include ordering */ #ifndef _POWERPC_PROM_H #define _POWERPC_PROM_H #ifdef __KERNEL__ @@ -20,21 +19,17 @@ #include <asm/irq.h> #include <linux/atomic.h> -#define HAVE_ARCH_DEVTREE_FIXUPS +/* These includes should be removed once implicit includes are cleaned up. */ +#include <linux/of.h> +#include <linux/of_fdt.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> +#include <linux/platform_device.h> /* * OF address retreival & translation */ -/* Translate a DMA address from device space to CPU space */ -extern u64 of_translate_dma_address(struct device_node *dev, - const __be32 *in_addr); - -#ifdef CONFIG_PCI -extern unsigned long pci_address_to_pio(phys_addr_t address); -#define pci_address_to_pio pci_address_to_pio -#endif /* CONFIG_PCI */ - /* Parse the ibm,dma-window property of an OF node into the busno, phys and * size parameters. */ @@ -44,16 +39,6 @@ void of_parse_dma_window(struct device_node *dn, const __be32 *dma_window, extern void kdump_move_device_tree(void); -/* cache lookup */ -struct device_node *of_find_next_cache_node(struct device_node *np); - -#ifdef CONFIG_NUMA -extern int of_node_to_nid(struct device_node *device); -#else -static inline int of_node_to_nid(struct device_node *device) { return 0; } -#endif -#define of_node_to_nid of_node_to_nid - extern void of_instantiate_rtc(void); extern int of_get_ibm_chip_id(struct device_node *np); @@ -143,14 +128,5 @@ struct of_drconf_cell { */ extern unsigned char ibm_architecture_vec[]; -/* These includes are put at the bottom because they may contain things - * that are overridden by this file. Ideally they shouldn't be included - * by this file, but there are a bunch of .c files that currently depend - * on it. Eventually they will be cleaned up. */ -#include <linux/of_fdt.h> -#include <linux/of_address.h> -#include <linux/of_irq.h> -#include <linux/platform_device.h> - #endif /* __KERNEL__ */ #endif /* _POWERPC_PROM_H */ diff --git a/arch/powerpc/include/asm/pte-book3e.h b/arch/powerpc/include/asm/pte-book3e.h index 0156702ba24e..576ad88104cb 100644 --- a/arch/powerpc/include/asm/pte-book3e.h +++ b/arch/powerpc/include/asm/pte-book3e.h @@ -40,7 +40,7 @@ #define _PAGE_U1 0x010000 #define _PAGE_U0 0x020000 #define _PAGE_ACCESSED 0x040000 -#define _PAGE_LENDIAN 0x080000 +#define _PAGE_ENDIAN 0x080000 #define _PAGE_GUARDED 0x100000 #define _PAGE_COHERENT 0x200000 /* M: enforce memory coherence */ #define _PAGE_NO_CACHE 0x400000 /* I: cache inhibit */ diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index 10d1ef016bf1..5c45787d551e 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h @@ -115,7 +115,12 @@ #define MSR_64BIT MSR_SF /* Server variant */ -#define MSR_ (MSR_ME | MSR_RI | MSR_IR | MSR_DR | MSR_ISF |MSR_HV) +#define __MSR (MSR_ME | MSR_RI | MSR_IR | MSR_DR | MSR_ISF |MSR_HV) +#ifdef __BIG_ENDIAN__ +#define MSR_ __MSR +#else +#define MSR_ (__MSR | MSR_LE) +#endif #define MSR_KERNEL (MSR_ | MSR_64BIT) #define MSR_USER32 (MSR_ | MSR_PR | MSR_EE) #define MSR_USER64 (MSR_USER32 | MSR_64BIT) @@ -243,6 +248,7 @@ #define SPRN_TBRU 0x10D /* Time Base Read Upper Register (user, R/O) */ #define SPRN_TBWL 0x11C /* Time Base Lower Register (super, R/W) */ #define SPRN_TBWU 0x11D /* Time Base Upper Register (super, R/W) */ +#define SPRN_TBU40 0x11E /* Timebase upper 40 bits (hyper, R/W) */ #define SPRN_SPURR 0x134 /* Scaled PURR */ #define SPRN_HSPRG0 0x130 /* Hypervisor Scratch 0 */ #define SPRN_HSPRG1 0x131 /* Hypervisor Scratch 1 */ @@ -283,6 +289,7 @@ #define LPCR_ISL (1ul << (63-2)) #define LPCR_VC_SH (63-2) #define LPCR_DPFD_SH (63-11) +#define LPCR_DPFD (7ul << LPCR_DPFD_SH) #define LPCR_VRMASD (0x1ful << (63-16)) #define LPCR_VRMA_L (1ul << (63-12)) #define LPCR_VRMA_LP0 (1ul << (63-15)) @@ -299,6 +306,7 @@ #define LPCR_PECE2 0x00001000 /* machine check etc can cause exit */ #define LPCR_MER 0x00000800 /* Mediated External Exception */ #define LPCR_MER_SH 11 +#define LPCR_TC 0x00000200 /* Translation control */ #define LPCR_LPES 0x0000000c #define LPCR_LPES0 0x00000008 /* LPAR Env selector 0 */ #define LPCR_LPES1 0x00000004 /* LPAR Env selector 1 */ @@ -311,6 +319,10 @@ #define LPID_RSVD 0x3ff /* Reserved LPID for partn switching */ #define SPRN_HMER 0x150 /* Hardware m? error recovery */ #define SPRN_HMEER 0x151 /* Hardware m? enable error recovery */ +#define SPRN_PCR 0x152 /* Processor compatibility register */ +#define PCR_VEC_DIS (1ul << (63-0)) /* Vec. disable (bit NA since POWER8) */ +#define PCR_VSX_DIS (1ul << (63-1)) /* VSX disable (bit NA since POWER8) */ +#define PCR_ARCH_205 0x2 /* Architecture 2.05 */ #define SPRN_HEIR 0x153 /* Hypervisor Emulated Instruction Register */ #define SPRN_TLBINDEXR 0x154 /* P7 TLB control register */ #define SPRN_TLBVPNR 0x155 /* P7 TLB control register */ @@ -420,6 +432,7 @@ #define HID4_RMLS2_SH (63 - 2) /* Real mode limit bottom 2 bits */ #define HID4_LPID5_SH (63 - 6) /* partition ID bottom 4 bits */ #define HID4_RMOR_SH (63 - 22) /* real mode offset (16 bits) */ +#define HID4_RMOR (0xFFFFul << HID4_RMOR_SH) #define HID4_LPES1 (1 << (63-57)) /* LPAR env. sel. bit 1 */ #define HID4_RMLS0_SH (63 - 58) /* Real mode limit top bit */ #define HID4_LPID1_SH 0 /* partition ID top 2 bits */ @@ -1102,6 +1115,13 @@ #define PVR_BE 0x0070 #define PVR_PA6T 0x0090 +/* "Logical" PVR values defined in PAPR, representing architecture levels */ +#define PVR_ARCH_204 0x0f000001 +#define PVR_ARCH_205 0x0f000002 +#define PVR_ARCH_206 0x0f000003 +#define PVR_ARCH_206p 0x0f100003 +#define PVR_ARCH_207 0x0f000004 + /* Macros for setting and retrieving special purpose registers */ #ifndef __ASSEMBLY__ #define mfmsr() ({unsigned long rval; \ diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h index ed8f836da094..2e31aacd8acc 100644 --- a/arch/powerpc/include/asm/reg_booke.h +++ b/arch/powerpc/include/asm/reg_booke.h @@ -381,7 +381,7 @@ #define DBCR0_IA34T 0x00004000 /* Instr Addr 3-4 range Toggle */ #define DBCR0_FT 0x00000001 /* Freeze Timers on debug event */ -#define dbcr_iac_range(task) ((task)->thread.dbcr0) +#define dbcr_iac_range(task) ((task)->thread.debug.dbcr0) #define DBCR_IAC12I DBCR0_IA12 /* Range Inclusive */ #define DBCR_IAC12X (DBCR0_IA12 | DBCR0_IA12X) /* Range Exclusive */ #define DBCR_IAC12MODE (DBCR0_IA12 | DBCR0_IA12X) /* IAC 1-2 Mode Bits */ @@ -395,7 +395,7 @@ #define DBCR1_DAC1W 0x20000000 /* DAC1 Write Debug Event */ #define DBCR1_DAC2W 0x10000000 /* DAC2 Write Debug Event */ -#define dbcr_dac(task) ((task)->thread.dbcr1) +#define dbcr_dac(task) ((task)->thread.debug.dbcr1) #define DBCR_DAC1R DBCR1_DAC1R #define DBCR_DAC1W DBCR1_DAC1W #define DBCR_DAC2R DBCR1_DAC2R @@ -441,7 +441,7 @@ #define DBCR0_CRET 0x00000020 /* Critical Return Debug Event */ #define DBCR0_FT 0x00000001 /* Freeze Timers on debug event */ -#define dbcr_dac(task) ((task)->thread.dbcr0) +#define dbcr_dac(task) ((task)->thread.debug.dbcr0) #define DBCR_DAC1R DBCR0_DAC1R #define DBCR_DAC1W DBCR0_DAC1W #define DBCR_DAC2R DBCR0_DAC2R @@ -475,7 +475,7 @@ #define DBCR1_IAC34MX 0x000000C0 /* Instr Addr 3-4 range eXclusive */ #define DBCR1_IAC34AT 0x00000001 /* Instr Addr 3-4 range Toggle */ -#define dbcr_iac_range(task) ((task)->thread.dbcr1) +#define dbcr_iac_range(task) ((task)->thread.debug.dbcr1) #define DBCR_IAC12I DBCR1_IAC12M /* Range Inclusive */ #define DBCR_IAC12X DBCR1_IAC12MX /* Range Exclusive */ #define DBCR_IAC12MODE DBCR1_IAC12MX /* IAC 1-2 Mode Bits */ diff --git a/arch/powerpc/include/asm/scom.h b/arch/powerpc/include/asm/scom.h index 0cabfd7bc2d1..f5cde45b1161 100644 --- a/arch/powerpc/include/asm/scom.h +++ b/arch/powerpc/include/asm/scom.h @@ -54,8 +54,8 @@ struct scom_controller { scom_map_t (*map)(struct device_node *ctrl_dev, u64 reg, u64 count); void (*unmap)(scom_map_t map); - u64 (*read)(scom_map_t map, u32 reg); - void (*write)(scom_map_t map, u32 reg, u64 value); + int (*read)(scom_map_t map, u64 reg, u64 *value); + int (*write)(scom_map_t map, u64 reg, u64 value); }; extern const struct scom_controller *scom_controller; @@ -133,10 +133,18 @@ static inline void scom_unmap(scom_map_t map) * scom_read - Read a SCOM register * @map: Result of scom_map * @reg: Register index within that map + * @value: Updated with the value read + * + * Returns 0 (success) or a negative error code */ -static inline u64 scom_read(scom_map_t map, u32 reg) +static inline int scom_read(scom_map_t map, u64 reg, u64 *value) { - return scom_controller->read(map, reg); + int rc; + + rc = scom_controller->read(map, reg, value); + if (rc) + *value = 0xfffffffffffffffful; + return rc; } /** @@ -144,12 +152,15 @@ static inline u64 scom_read(scom_map_t map, u32 reg) * @map: Result of scom_map * @reg: Register index within that map * @value: Value to write + * + * Returns 0 (success) or a negative error code */ -static inline void scom_write(scom_map_t map, u32 reg, u64 value) +static inline int scom_write(scom_map_t map, u64 reg, u64 value) { - scom_controller->write(map, reg, value); + return scom_controller->write(map, reg, value); } + #endif /* CONFIG_PPC_SCOM */ #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ diff --git a/arch/powerpc/include/asm/setup.h b/arch/powerpc/include/asm/setup.h index d3ca85529b8b..703a8412dac2 100644 --- a/arch/powerpc/include/asm/setup.h +++ b/arch/powerpc/include/asm/setup.h @@ -23,6 +23,10 @@ extern void reloc_got2(unsigned long); #define PTRRELOC(x) ((typeof(x)) add_reloc_offset((unsigned long)(x))) +void check_for_initrd(void); +void do_init_bootmem(void); +void setup_panic(void); + #endif /* !__ASSEMBLY__ */ #endif /* _ASM_POWERPC_SETUP_H */ diff --git a/arch/powerpc/include/asm/sfp-machine.h b/arch/powerpc/include/asm/sfp-machine.h index 3a7a67a0d006..d89beaba26ff 100644 --- a/arch/powerpc/include/asm/sfp-machine.h +++ b/arch/powerpc/include/asm/sfp-machine.h @@ -125,7 +125,7 @@ #define FP_EX_DIVZERO (1 << (31 - 5)) #define FP_EX_INEXACT (1 << (31 - 6)) -#define __FPU_FPSCR (current->thread.fpscr.val) +#define __FPU_FPSCR (current->thread.fp_state.fpscr) /* We only actually write to the destination register * if exceptions signalled (if any) will not trap. diff --git a/arch/powerpc/include/asm/spu.h b/arch/powerpc/include/asm/spu.h index 93f280e23279..37b7ca39ec9f 100644 --- a/arch/powerpc/include/asm/spu.h +++ b/arch/powerpc/include/asm/spu.h @@ -235,6 +235,7 @@ extern long spu_sys_callback(struct spu_syscall_block *s); /* syscalls implemented in spufs */ struct file; +struct coredump_params; struct spufs_calls { long (*create_thread)(const char __user *name, unsigned int flags, umode_t mode, @@ -242,7 +243,7 @@ struct spufs_calls { long (*spu_run)(struct file *filp, __u32 __user *unpc, __u32 __user *ustatus); int (*coredump_extra_notes_size)(void); - int (*coredump_extra_notes_write)(struct file *file, loff_t *foffset); + int (*coredump_extra_notes_write)(struct coredump_params *cprm); void (*notify_spus_active)(void); struct module *owner; }; diff --git a/arch/powerpc/include/asm/string.h b/arch/powerpc/include/asm/string.h index e40010abcaf1..0dffad6bcc84 100644 --- a/arch/powerpc/include/asm/string.h +++ b/arch/powerpc/include/asm/string.h @@ -10,7 +10,9 @@ #define __HAVE_ARCH_STRNCMP #define __HAVE_ARCH_STRCAT #define __HAVE_ARCH_MEMSET +#ifdef __BIG_ENDIAN__ #define __HAVE_ARCH_MEMCPY +#endif #define __HAVE_ARCH_MEMMOVE #define __HAVE_ARCH_MEMCMP #define __HAVE_ARCH_MEMCHR @@ -22,7 +24,9 @@ extern int strcmp(const char *,const char *); extern int strncmp(const char *, const char *, __kernel_size_t); extern char * strcat(char *, const char *); extern void * memset(void *,int,__kernel_size_t); +#ifdef __BIG_ENDIAN__ extern void * memcpy(void *,const void *,__kernel_size_t); +#endif extern void * memmove(void *,const void *,__kernel_size_t); extern int memcmp(const void *,const void *,__kernel_size_t); extern void * memchr(const void *,int,__kernel_size_t); diff --git a/arch/powerpc/include/asm/switch_to.h b/arch/powerpc/include/asm/switch_to.h index 2be5618cdec6..9ee12610af02 100644 --- a/arch/powerpc/include/asm/switch_to.h +++ b/arch/powerpc/include/asm/switch_to.h @@ -35,6 +35,7 @@ extern void giveup_vsx(struct task_struct *); extern void enable_kernel_spe(void); extern void giveup_spe(struct task_struct *); extern void load_up_spe(struct task_struct *); +extern void switch_booke_debug_regs(struct thread_struct *new_thread); #ifndef CONFIG_SMP extern void discard_lazy_cpu_state(void); diff --git a/arch/powerpc/include/asm/thread_info.h b/arch/powerpc/include/asm/thread_info.h index ba7b1973866e..8fd6cf6dcee8 100644 --- a/arch/powerpc/include/asm/thread_info.h +++ b/arch/powerpc/include/asm/thread_info.h @@ -82,8 +82,6 @@ static inline struct thread_info *current_thread_info(void) #endif /* __ASSEMBLY__ */ -#define PREEMPT_ACTIVE 0x10000000 - /* * thread information flag bit numbers */ diff --git a/arch/powerpc/include/asm/uprobes.h b/arch/powerpc/include/asm/uprobes.h index 23016020915e..75c6ecdb8f37 100644 --- a/arch/powerpc/include/asm/uprobes.h +++ b/arch/powerpc/include/asm/uprobes.h @@ -37,6 +37,7 @@ typedef ppc_opcode_t uprobe_opcode_t; struct arch_uprobe { union { u8 insn[MAX_UINSN_BYTES]; + u8 ixol[MAX_UINSN_BYTES]; u32 ainsn; }; }; @@ -45,11 +46,4 @@ struct arch_uprobe_task { unsigned long saved_trap_nr; }; -extern int arch_uprobe_analyze_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long addr); -extern int arch_uprobe_pre_xol(struct arch_uprobe *aup, struct pt_regs *regs); -extern int arch_uprobe_post_xol(struct arch_uprobe *aup, struct pt_regs *regs); -extern bool arch_uprobe_xol_was_trapped(struct task_struct *tsk); -extern int arch_uprobe_exception_notify(struct notifier_block *self, unsigned long val, void *data); -extern void arch_uprobe_abort_xol(struct arch_uprobe *aup, struct pt_regs *regs); -extern unsigned long arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr, struct pt_regs *regs); #endif /* _ASM_UPROBES_H */ diff --git a/arch/powerpc/include/asm/word-at-a-time.h b/arch/powerpc/include/asm/word-at-a-time.h index d0b6d4ac6dda..9a5c928bb3c6 100644 --- a/arch/powerpc/include/asm/word-at-a-time.h +++ b/arch/powerpc/include/asm/word-at-a-time.h @@ -8,6 +8,8 @@ #include <linux/kernel.h> #include <asm/asm-compat.h> +#ifdef __BIG_ENDIAN__ + struct word_at_a_time { const unsigned long high_bits, low_bits; }; @@ -38,4 +40,80 @@ static inline bool has_zero(unsigned long val, unsigned long *data, const struct return (val + c->high_bits) & ~rhs; } +#else + +struct word_at_a_time { + const unsigned long one_bits, high_bits; +}; + +#define WORD_AT_A_TIME_CONSTANTS { REPEAT_BYTE(0x01), REPEAT_BYTE(0x80) } + +#ifdef CONFIG_64BIT + +/* Alan Modra's little-endian strlen tail for 64-bit */ +#define create_zero_mask(mask) (mask) + +static inline unsigned long find_zero(unsigned long mask) +{ + unsigned long leading_zero_bits; + long trailing_zero_bit_mask; + + asm ("addi %1,%2,-1\n\t" + "andc %1,%1,%2\n\t" + "popcntd %0,%1" + : "=r" (leading_zero_bits), "=&r" (trailing_zero_bit_mask) + : "r" (mask)); + return leading_zero_bits >> 3; +} + +#else /* 32-bit case */ + +/* + * This is largely generic for little-endian machines, but the + * optimal byte mask counting is probably going to be something + * that is architecture-specific. If you have a reliably fast + * bit count instruction, that might be better than the multiply + * and shift, for example. + */ + +/* Carl Chatfield / Jan Achrenius G+ version for 32-bit */ +static inline long count_masked_bytes(long mask) +{ + /* (000000 0000ff 00ffff ffffff) -> ( 1 1 2 3 ) */ + long a = (0x0ff0001+mask) >> 23; + /* Fix the 1 for 00 case */ + return a & mask; +} + +static inline unsigned long create_zero_mask(unsigned long bits) +{ + bits = (bits - 1) & ~bits; + return bits >> 7; +} + +static inline unsigned long find_zero(unsigned long mask) +{ + return count_masked_bytes(mask); +} + +#endif + +/* Return nonzero if it has a zero */ +static inline unsigned long has_zero(unsigned long a, unsigned long *bits, const struct word_at_a_time *c) +{ + unsigned long mask = ((a - c->one_bits) & ~a) & c->high_bits; + *bits = mask; + return mask; +} + +static inline unsigned long prep_zero_mask(unsigned long a, unsigned long bits, const struct word_at_a_time *c) +{ + return bits; +} + +/* The mask we created is directly usable as a bytemask */ +#define zero_bytemask(mask) (mask) + +#endif + #endif /* _ASM_WORD_AT_A_TIME_H */ diff --git a/arch/powerpc/include/asm/xor.h b/arch/powerpc/include/asm/xor.h index c82eb12a5b18..0abb97f3be10 100644 --- a/arch/powerpc/include/asm/xor.h +++ b/arch/powerpc/include/asm/xor.h @@ -1 +1,68 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Copyright (C) IBM Corporation, 2012 + * + * Author: Anton Blanchard <anton@au.ibm.com> + */ +#ifndef _ASM_POWERPC_XOR_H +#define _ASM_POWERPC_XOR_H + +#ifdef CONFIG_ALTIVEC + +#include <asm/cputable.h> + +void xor_altivec_2(unsigned long bytes, unsigned long *v1_in, + unsigned long *v2_in); +void xor_altivec_3(unsigned long bytes, unsigned long *v1_in, + unsigned long *v2_in, unsigned long *v3_in); +void xor_altivec_4(unsigned long bytes, unsigned long *v1_in, + unsigned long *v2_in, unsigned long *v3_in, + unsigned long *v4_in); +void xor_altivec_5(unsigned long bytes, unsigned long *v1_in, + unsigned long *v2_in, unsigned long *v3_in, + unsigned long *v4_in, unsigned long *v5_in); + +static struct xor_block_template xor_block_altivec = { + .name = "altivec", + .do_2 = xor_altivec_2, + .do_3 = xor_altivec_3, + .do_4 = xor_altivec_4, + .do_5 = xor_altivec_5, +}; + +#define XOR_SPEED_ALTIVEC() \ + do { \ + if (cpu_has_feature(CPU_FTR_ALTIVEC)) \ + xor_speed(&xor_block_altivec); \ + } while (0) +#else +#define XOR_SPEED_ALTIVEC() +#endif + +/* Also try the generic routines. */ #include <asm-generic/xor.h> + +#undef XOR_TRY_TEMPLATES +#define XOR_TRY_TEMPLATES \ +do { \ + xor_speed(&xor_block_8regs); \ + xor_speed(&xor_block_8regs_p); \ + xor_speed(&xor_block_32regs); \ + xor_speed(&xor_block_32regs_p); \ + XOR_SPEED_ALTIVEC(); \ +} while (0) + +#endif /* _ASM_POWERPC_XOR_H */ diff --git a/arch/powerpc/include/uapi/asm/byteorder.h b/arch/powerpc/include/uapi/asm/byteorder.h index aa6cc4fac965..ca931d074000 100644 --- a/arch/powerpc/include/uapi/asm/byteorder.h +++ b/arch/powerpc/include/uapi/asm/byteorder.h @@ -7,6 +7,10 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ +#ifdef __LITTLE_ENDIAN__ +#include <linux/byteorder/little_endian.h> +#else #include <linux/byteorder/big_endian.h> +#endif #endif /* _ASM_POWERPC_BYTEORDER_H */ diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h index 0fb1a6e9ff90..6836ec79a830 100644 --- a/arch/powerpc/include/uapi/asm/kvm.h +++ b/arch/powerpc/include/uapi/asm/kvm.h @@ -27,6 +27,7 @@ #define __KVM_HAVE_PPC_SMT #define __KVM_HAVE_IRQCHIP #define __KVM_HAVE_IRQ_LINE +#define __KVM_HAVE_GUEST_DEBUG struct kvm_regs { __u64 pc; @@ -269,7 +270,24 @@ struct kvm_fpu { __u64 fpr[32]; }; +/* + * Defines for h/w breakpoint, watchpoint (read, write or both) and + * software breakpoint. + * These are used as "type" in KVM_SET_GUEST_DEBUG ioctl and "status" + * for KVM_DEBUG_EXIT. + */ +#define KVMPPC_DEBUG_NONE 0x0 +#define KVMPPC_DEBUG_BREAKPOINT (1UL << 1) +#define KVMPPC_DEBUG_WATCH_WRITE (1UL << 2) +#define KVMPPC_DEBUG_WATCH_READ (1UL << 3) struct kvm_debug_exit_arch { + __u64 address; + /* + * exiting to userspace because of h/w breakpoint, watchpoint + * (read, write or both) and software breakpoint. + */ + __u32 status; + __u32 reserved; }; /* for KVM_SET_GUEST_DEBUG */ @@ -281,10 +299,6 @@ struct kvm_guest_debug_arch { * Type denotes h/w breakpoint, read watchpoint, write * watchpoint or watchpoint (both read and write). */ -#define KVMPPC_DEBUG_NONE 0x0 -#define KVMPPC_DEBUG_BREAKPOINT (1UL << 1) -#define KVMPPC_DEBUG_WATCH_WRITE (1UL << 2) -#define KVMPPC_DEBUG_WATCH_READ (1UL << 3) __u32 type; __u32 reserved; } bp[16]; @@ -429,6 +443,11 @@ struct kvm_get_htab_header { #define KVM_REG_PPC_MMCR0 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x10) #define KVM_REG_PPC_MMCR1 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x11) #define KVM_REG_PPC_MMCRA (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x12) +#define KVM_REG_PPC_MMCR2 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x13) +#define KVM_REG_PPC_MMCRS (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x14) +#define KVM_REG_PPC_SIAR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x15) +#define KVM_REG_PPC_SDAR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x16) +#define KVM_REG_PPC_SIER (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x17) #define KVM_REG_PPC_PMC1 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x18) #define KVM_REG_PPC_PMC2 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x19) @@ -499,6 +518,65 @@ struct kvm_get_htab_header { #define KVM_REG_PPC_TLB3PS (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x9a) #define KVM_REG_PPC_EPTCFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x9b) +/* Timebase offset */ +#define KVM_REG_PPC_TB_OFFSET (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x9c) + +/* POWER8 registers */ +#define KVM_REG_PPC_SPMC1 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x9d) +#define KVM_REG_PPC_SPMC2 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x9e) +#define KVM_REG_PPC_IAMR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x9f) +#define KVM_REG_PPC_TFHAR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xa0) +#define KVM_REG_PPC_TFIAR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xa1) +#define KVM_REG_PPC_TEXASR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xa2) +#define KVM_REG_PPC_FSCR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xa3) +#define KVM_REG_PPC_PSPB (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xa4) +#define KVM_REG_PPC_EBBHR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xa5) +#define KVM_REG_PPC_EBBRR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xa6) +#define KVM_REG_PPC_BESCR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xa7) +#define KVM_REG_PPC_TAR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xa8) +#define KVM_REG_PPC_DPDES (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xa9) +#define KVM_REG_PPC_DAWR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xaa) +#define KVM_REG_PPC_DAWRX (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xab) +#define KVM_REG_PPC_CIABR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xac) +#define KVM_REG_PPC_IC (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xad) +#define KVM_REG_PPC_VTB (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xae) +#define KVM_REG_PPC_CSIGR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xaf) +#define KVM_REG_PPC_TACR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xb0) +#define KVM_REG_PPC_TCSCR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xb1) +#define KVM_REG_PPC_PID (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xb2) +#define KVM_REG_PPC_ACOP (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xb3) + +#define KVM_REG_PPC_VRSAVE (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xb4) +#define KVM_REG_PPC_LPCR (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xb5) +#define KVM_REG_PPC_PPR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xb6) + +/* Architecture compatibility level */ +#define KVM_REG_PPC_ARCH_COMPAT (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xb7) + +/* Transactional Memory checkpointed state: + * This is all GPRs, all VSX regs and a subset of SPRs + */ +#define KVM_REG_PPC_TM (KVM_REG_PPC | 0x80000000) +/* TM GPRs */ +#define KVM_REG_PPC_TM_GPR0 (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0) +#define KVM_REG_PPC_TM_GPR(n) (KVM_REG_PPC_TM_GPR0 + (n)) +#define KVM_REG_PPC_TM_GPR31 (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x1f) +/* TM VSX */ +#define KVM_REG_PPC_TM_VSR0 (KVM_REG_PPC_TM | KVM_REG_SIZE_U128 | 0x20) +#define KVM_REG_PPC_TM_VSR(n) (KVM_REG_PPC_TM_VSR0 + (n)) +#define KVM_REG_PPC_TM_VSR63 (KVM_REG_PPC_TM | KVM_REG_SIZE_U128 | 0x5f) +/* TM SPRS */ +#define KVM_REG_PPC_TM_CR (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x60) +#define KVM_REG_PPC_TM_LR (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x61) +#define KVM_REG_PPC_TM_CTR (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x62) +#define KVM_REG_PPC_TM_FPSCR (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x63) +#define KVM_REG_PPC_TM_AMR (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x64) +#define KVM_REG_PPC_TM_PPR (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x65) +#define KVM_REG_PPC_TM_VRSAVE (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x66) +#define KVM_REG_PPC_TM_VSCR (KVM_REG_PPC_TM | KVM_REG_SIZE_U32 | 0x67) +#define KVM_REG_PPC_TM_DSCR (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x68) +#define KVM_REG_PPC_TM_TAR (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x69) + /* PPC64 eXternal Interrupt Controller Specification */ #define KVM_DEV_XICS_GRP_SOURCES 1 /* 64-bit source attributes */ diff --git a/arch/powerpc/include/uapi/asm/socket.h b/arch/powerpc/include/uapi/asm/socket.h index a6d74467c9ed..fa698324a1fd 100644 --- a/arch/powerpc/include/uapi/asm/socket.h +++ b/arch/powerpc/include/uapi/asm/socket.h @@ -83,4 +83,6 @@ #define SO_BUSY_POLL 46 +#define SO_MAX_PACING_RATE 47 + #endif /* _ASM_POWERPC_SOCKET_H */ diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c index a27ccd5dc6b9..de91f3ae631e 100644 --- a/arch/powerpc/kernel/align.c +++ b/arch/powerpc/kernel/align.c @@ -54,8 +54,6 @@ struct aligninfo { /* DSISR bits reported for a DCBZ instruction: */ #define DCBZ 0x5f /* 8xx/82xx dcbz faults when cache not enabled */ -#define SWAP(a, b) (t = (a), (a) = (b), (b) = t) - /* * The PowerPC stores certain bits of the instruction that caused the * alignment exception in the DSISR register. This array maps those @@ -256,11 +254,17 @@ static int emulate_dcbz(struct pt_regs *regs, unsigned char __user *addr) * bottom 4 bytes of each register, and the loads clear the * top 4 bytes of the affected register. */ +#ifdef __BIG_ENDIAN__ #ifdef CONFIG_PPC64 #define REG_BYTE(rp, i) *((u8 *)((rp) + ((i) >> 2)) + ((i) & 3) + 4) #else #define REG_BYTE(rp, i) *((u8 *)(rp) + (i)) #endif +#endif + +#ifdef __LITTLE_ENDIAN__ +#define REG_BYTE(rp, i) (*(((u8 *)((rp) + ((i)>>2)) + ((i)&3)))) +#endif #define SWIZ_PTR(p) ((unsigned char __user *)((p) ^ swiz)) @@ -305,6 +309,15 @@ static int emulate_multiple(struct pt_regs *regs, unsigned char __user *addr, nb0 = nb + reg * 4 - 128; nb = 128 - reg * 4; } +#ifdef __LITTLE_ENDIAN__ + /* + * String instructions are endian neutral but the code + * below is not. Force byte swapping on so that the + * effects of swizzling are undone in the load/store + * loops below. + */ + flags ^= SW; +#endif } else { /* lwm, stmw */ nb = (32 - reg) * 4; @@ -458,7 +471,7 @@ static struct aligninfo spe_aligninfo[32] = { static int emulate_spe(struct pt_regs *regs, unsigned int reg, unsigned int instr) { - int t, ret; + int ret; union { u64 ll; u32 w[2]; @@ -581,24 +594,18 @@ static int emulate_spe(struct pt_regs *regs, unsigned int reg, if (flags & SW) { switch (flags & 0xf0) { case E8: - SWAP(data.v[0], data.v[7]); - SWAP(data.v[1], data.v[6]); - SWAP(data.v[2], data.v[5]); - SWAP(data.v[3], data.v[4]); + data.ll = swab64(data.ll); break; case E4: - - SWAP(data.v[0], data.v[3]); - SWAP(data.v[1], data.v[2]); - SWAP(data.v[4], data.v[7]); - SWAP(data.v[5], data.v[6]); + data.w[0] = swab32(data.w[0]); + data.w[1] = swab32(data.w[1]); break; /* Its half word endian */ default: - SWAP(data.v[0], data.v[1]); - SWAP(data.v[2], data.v[3]); - SWAP(data.v[4], data.v[5]); - SWAP(data.v[6], data.v[7]); + data.h[0] = swab16(data.h[0]); + data.h[1] = swab16(data.h[1]); + data.h[2] = swab16(data.h[2]); + data.h[3] = swab16(data.h[3]); break; } } @@ -658,14 +665,31 @@ static int emulate_vsx(unsigned char __user *addr, unsigned int reg, flush_vsx_to_thread(current); if (reg < 32) - ptr = (char *) ¤t->thread.TS_FPR(reg); + ptr = (char *) ¤t->thread.fp_state.fpr[reg][0]; else - ptr = (char *) ¤t->thread.vr[reg - 32]; + ptr = (char *) ¤t->thread.vr_state.vr[reg - 32]; lptr = (unsigned long *) ptr; +#ifdef __LITTLE_ENDIAN__ + if (flags & SW) { + elsize = length; + sw = length-1; + } else { + /* + * The elements are BE ordered, even in LE mode, so process + * them in reverse order. + */ + addr += length - elsize; + + /* 8 byte memory accesses go in the top 8 bytes of the VR */ + if (length == 8) + ptr += 8; + } +#else if (flags & SW) sw = elsize-1; +#endif for (j = 0; j < length; j += elsize) { for (i = 0; i < elsize; ++i) { @@ -675,19 +699,31 @@ static int emulate_vsx(unsigned char __user *addr, unsigned int reg, ret |= __get_user(ptr[i^sw], addr + i); } ptr += elsize; +#ifdef __LITTLE_ENDIAN__ + addr -= elsize; +#else addr += elsize; +#endif } +#ifdef __BIG_ENDIAN__ +#define VSX_HI 0 +#define VSX_LO 1 +#else +#define VSX_HI 1 +#define VSX_LO 0 +#endif + if (!ret) { if (flags & U) regs->gpr[areg] = regs->dar; /* Splat load copies the same data to top and bottom 8 bytes */ if (flags & SPLT) - lptr[1] = lptr[0]; - /* For 8 byte loads, zero the top 8 bytes */ + lptr[VSX_LO] = lptr[VSX_HI]; + /* For 8 byte loads, zero the low 8 bytes */ else if (!(flags & ST) && (8 == length)) - lptr[1] = 0; + lptr[VSX_LO] = 0; } else return -EFAULT; @@ -710,18 +746,28 @@ int fix_alignment(struct pt_regs *regs) unsigned int dsisr; unsigned char __user *addr; unsigned long p, swiz; - int ret, t; - union { + int ret, i; + union data { u64 ll; double dd; unsigned char v[8]; struct { +#ifdef __LITTLE_ENDIAN__ + int low32; + unsigned hi32; +#else unsigned hi32; int low32; +#endif } x32; struct { +#ifdef __LITTLE_ENDIAN__ + short low16; + unsigned char hi48[6]; +#else unsigned char hi48[6]; short low16; +#endif } x16; } data; @@ -780,8 +826,9 @@ int fix_alignment(struct pt_regs *regs) /* Byteswap little endian loads and stores */ swiz = 0; - if (regs->msr & MSR_LE) { + if ((regs->msr & MSR_LE) != (MSR_KERNEL & MSR_LE)) { flags ^= SW; +#ifdef __BIG_ENDIAN__ /* * So-called "PowerPC little endian" mode works by * swizzling addresses rather than by actually doing @@ -794,6 +841,7 @@ int fix_alignment(struct pt_regs *regs) */ if (cpu_has_feature(CPU_FTR_PPC_LE)) swiz = 7; +#endif } /* DAR has the operand effective address */ @@ -818,7 +866,7 @@ int fix_alignment(struct pt_regs *regs) elsize = 8; flags = 0; - if (regs->msr & MSR_LE) + if ((regs->msr & MSR_LE) != (MSR_KERNEL & MSR_LE)) flags |= SW; if (instruction & 0x100) flags |= ST; @@ -878,32 +926,36 @@ int fix_alignment(struct pt_regs *regs) * get it from register values */ if (!(flags & ST)) { - data.ll = 0; - ret = 0; - p = (unsigned long) addr; + unsigned int start = 0; + switch (nb) { - case 8: - ret |= __get_user_inatomic(data.v[0], SWIZ_PTR(p++)); - ret |= __get_user_inatomic(data.v[1], SWIZ_PTR(p++)); - ret |= __get_user_inatomic(data.v[2], SWIZ_PTR(p++)); - ret |= __get_user_inatomic(data.v[3], SWIZ_PTR(p++)); case 4: - ret |= __get_user_inatomic(data.v[4], SWIZ_PTR(p++)); - ret |= __get_user_inatomic(data.v[5], SWIZ_PTR(p++)); + start = offsetof(union data, x32.low32); + break; case 2: - ret |= __get_user_inatomic(data.v[6], SWIZ_PTR(p++)); - ret |= __get_user_inatomic(data.v[7], SWIZ_PTR(p++)); - if (unlikely(ret)) - return -EFAULT; + start = offsetof(union data, x16.low16); + break; } + + data.ll = 0; + ret = 0; + p = (unsigned long)addr; + + for (i = 0; i < nb; i++) + ret |= __get_user_inatomic(data.v[start + i], + SWIZ_PTR(p++)); + + if (unlikely(ret)) + return -EFAULT; + } else if (flags & F) { - data.dd = current->thread.TS_FPR(reg); + data.ll = current->thread.TS_FPR(reg); if (flags & S) { /* Single-precision FP store requires conversion... */ #ifdef CONFIG_PPC_FPU preempt_disable(); enable_kernel_fp(); - cvt_df(&data.dd, (float *)&data.v[4]); + cvt_df(&data.dd, (float *)&data.x32.low32); preempt_enable(); #else return 0; @@ -915,17 +967,13 @@ int fix_alignment(struct pt_regs *regs) if (flags & SW) { switch (nb) { case 8: - SWAP(data.v[0], data.v[7]); - SWAP(data.v[1], data.v[6]); - SWAP(data.v[2], data.v[5]); - SWAP(data.v[3], data.v[4]); + data.ll = swab64(data.ll); break; case 4: - SWAP(data.v[4], data.v[7]); - SWAP(data.v[5], data.v[6]); + data.x32.low32 = swab32(data.x32.low32); break; case 2: - SWAP(data.v[6], data.v[7]); + data.x16.low16 = swab16(data.x16.low16); break; } } @@ -947,7 +995,7 @@ int fix_alignment(struct pt_regs *regs) #ifdef CONFIG_PPC_FPU preempt_disable(); enable_kernel_fp(); - cvt_fd((float *)&data.v[4], &data.dd); + cvt_fd((float *)&data.x32.low32, &data.dd); preempt_enable(); #else return 0; @@ -957,25 +1005,28 @@ int fix_alignment(struct pt_regs *regs) /* Store result to memory or update registers */ if (flags & ST) { - ret = 0; - p = (unsigned long) addr; + unsigned int start = 0; + switch (nb) { - case 8: - ret |= __put_user_inatomic(data.v[0], SWIZ_PTR(p++)); - ret |= __put_user_inatomic(data.v[1], SWIZ_PTR(p++)); - ret |= __put_user_inatomic(data.v[2], SWIZ_PTR(p++)); - ret |= __put_user_inatomic(data.v[3], SWIZ_PTR(p++)); case 4: - ret |= __put_user_inatomic(data.v[4], SWIZ_PTR(p++)); - ret |= __put_user_inatomic(data.v[5], SWIZ_PTR(p++)); + start = offsetof(union data, x32.low32); + break; case 2: - ret |= __put_user_inatomic(data.v[6], SWIZ_PTR(p++)); - ret |= __put_user_inatomic(data.v[7], SWIZ_PTR(p++)); + start = offsetof(union data, x16.low16); + break; } + + ret = 0; + p = (unsigned long)addr; + + for (i = 0; i < nb; i++) + ret |= __put_user_inatomic(data.v[start + i], + SWIZ_PTR(p++)); + if (unlikely(ret)) return -EFAULT; } else if (flags & F) - current->thread.TS_FPR(reg) = data.dd; + current->thread.TS_FPR(reg) = data.ll; else regs->gpr[reg] = data.ll; diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 502c7a4e73f7..2ea5cc033ec8 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -90,16 +90,17 @@ int main(void) DEFINE(THREAD_NORMSAVES, offsetof(struct thread_struct, normsave[0])); #endif DEFINE(THREAD_FPEXC_MODE, offsetof(struct thread_struct, fpexc_mode)); - DEFINE(THREAD_FPR0, offsetof(struct thread_struct, fpr[0])); - DEFINE(THREAD_FPSCR, offsetof(struct thread_struct, fpscr)); + DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fp_state)); + DEFINE(THREAD_FPSAVEAREA, offsetof(struct thread_struct, fp_save_area)); + DEFINE(FPSTATE_FPSCR, offsetof(struct thread_fp_state, fpscr)); #ifdef CONFIG_ALTIVEC - DEFINE(THREAD_VR0, offsetof(struct thread_struct, vr[0])); + DEFINE(THREAD_VRSTATE, offsetof(struct thread_struct, vr_state)); + DEFINE(THREAD_VRSAVEAREA, offsetof(struct thread_struct, vr_save_area)); DEFINE(THREAD_VRSAVE, offsetof(struct thread_struct, vrsave)); - DEFINE(THREAD_VSCR, offsetof(struct thread_struct, vscr)); DEFINE(THREAD_USED_VR, offsetof(struct thread_struct, used_vr)); + DEFINE(VRSTATE_VSCR, offsetof(struct thread_vr_state, vscr)); #endif /* CONFIG_ALTIVEC */ #ifdef CONFIG_VSX - DEFINE(THREAD_VSR0, offsetof(struct thread_struct, fpr)); DEFINE(THREAD_USED_VSR, offsetof(struct thread_struct, used_vsr)); #endif /* CONFIG_VSX */ #ifdef CONFIG_PPC64 @@ -114,7 +115,7 @@ int main(void) #endif /* CONFIG_SPE */ #endif /* CONFIG_PPC64 */ #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) - DEFINE(THREAD_DBCR0, offsetof(struct thread_struct, dbcr0)); + DEFINE(THREAD_DBCR0, offsetof(struct thread_struct, debug.dbcr0)); #endif #ifdef CONFIG_KVM_BOOK3S_32_HANDLER DEFINE(THREAD_KVM_SVCPU, offsetof(struct thread_struct, kvm_shadow_vcpu)); @@ -143,20 +144,12 @@ int main(void) DEFINE(THREAD_TM_PPR, offsetof(struct thread_struct, tm_ppr)); DEFINE(THREAD_TM_DSCR, offsetof(struct thread_struct, tm_dscr)); DEFINE(PT_CKPT_REGS, offsetof(struct thread_struct, ckpt_regs)); - DEFINE(THREAD_TRANSACT_VR0, offsetof(struct thread_struct, - transact_vr[0])); - DEFINE(THREAD_TRANSACT_VSCR, offsetof(struct thread_struct, - transact_vscr)); + DEFINE(THREAD_TRANSACT_VRSTATE, offsetof(struct thread_struct, + transact_vr)); DEFINE(THREAD_TRANSACT_VRSAVE, offsetof(struct thread_struct, transact_vrsave)); - DEFINE(THREAD_TRANSACT_FPR0, offsetof(struct thread_struct, - transact_fpr[0])); - DEFINE(THREAD_TRANSACT_FPSCR, offsetof(struct thread_struct, - transact_fpscr)); -#ifdef CONFIG_VSX - DEFINE(THREAD_TRANSACT_VSR0, offsetof(struct thread_struct, - transact_fpr[0])); -#endif + DEFINE(THREAD_TRANSACT_FPSTATE, offsetof(struct thread_struct, + transact_fp)); /* Local pt_regs on stack for Transactional Memory funcs. */ DEFINE(TM_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16); @@ -446,7 +439,7 @@ int main(void) DEFINE(VCPU_LR, offsetof(struct kvm_vcpu, arch.lr)); DEFINE(VCPU_CR, offsetof(struct kvm_vcpu, arch.cr)); DEFINE(VCPU_PC, offsetof(struct kvm_vcpu, arch.pc)); -#ifdef CONFIG_KVM_BOOK3S_64_HV +#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE DEFINE(VCPU_MSR, offsetof(struct kvm_vcpu, arch.shregs.msr)); DEFINE(VCPU_SRR0, offsetof(struct kvm_vcpu, arch.shregs.srr0)); DEFINE(VCPU_SRR1, offsetof(struct kvm_vcpu, arch.shregs.srr1)); @@ -477,7 +470,7 @@ int main(void) DEFINE(KVM_LPID, offsetof(struct kvm, arch.lpid)); /* book3s */ -#ifdef CONFIG_KVM_BOOK3S_64_HV +#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE DEFINE(KVM_SDR1, offsetof(struct kvm, arch.sdr1)); DEFINE(KVM_HOST_LPID, offsetof(struct kvm, arch.host_lpid)); DEFINE(KVM_HOST_LPCR, offsetof(struct kvm, arch.host_lpcr)); @@ -509,6 +502,8 @@ int main(void) DEFINE(VCPU_PRODDED, offsetof(struct kvm_vcpu, arch.prodded)); DEFINE(VCPU_MMCR, offsetof(struct kvm_vcpu, arch.mmcr)); DEFINE(VCPU_PMC, offsetof(struct kvm_vcpu, arch.pmc)); + DEFINE(VCPU_SIAR, offsetof(struct kvm_vcpu, arch.siar)); + DEFINE(VCPU_SDAR, offsetof(struct kvm_vcpu, arch.sdar)); DEFINE(VCPU_SLB, offsetof(struct kvm_vcpu, arch.slb)); DEFINE(VCPU_SLB_MAX, offsetof(struct kvm_vcpu, arch.slb_max)); DEFINE(VCPU_SLB_NR, offsetof(struct kvm_vcpu, arch.slb_nr)); @@ -518,18 +513,22 @@ int main(void) DEFINE(VCPU_TRAP, offsetof(struct kvm_vcpu, arch.trap)); DEFINE(VCPU_PTID, offsetof(struct kvm_vcpu, arch.ptid)); DEFINE(VCPU_CFAR, offsetof(struct kvm_vcpu, arch.cfar)); + DEFINE(VCPU_PPR, offsetof(struct kvm_vcpu, arch.ppr)); + DEFINE(VCPU_SHADOW_SRR1, offsetof(struct kvm_vcpu, arch.shadow_srr1)); DEFINE(VCORE_ENTRY_EXIT, offsetof(struct kvmppc_vcore, entry_exit_count)); DEFINE(VCORE_NAP_COUNT, offsetof(struct kvmppc_vcore, nap_count)); DEFINE(VCORE_IN_GUEST, offsetof(struct kvmppc_vcore, in_guest)); DEFINE(VCORE_NAPPING_THREADS, offsetof(struct kvmppc_vcore, napping_threads)); - DEFINE(VCPU_SVCPU, offsetof(struct kvmppc_vcpu_book3s, shadow_vcpu) - - offsetof(struct kvmppc_vcpu_book3s, vcpu)); + DEFINE(VCORE_TB_OFFSET, offsetof(struct kvmppc_vcore, tb_offset)); + DEFINE(VCORE_LPCR, offsetof(struct kvmppc_vcore, lpcr)); + DEFINE(VCORE_PCR, offsetof(struct kvmppc_vcore, pcr)); DEFINE(VCPU_SLB_E, offsetof(struct kvmppc_slb, orige)); DEFINE(VCPU_SLB_V, offsetof(struct kvmppc_slb, origv)); DEFINE(VCPU_SLB_SIZE, sizeof(struct kvmppc_slb)); #ifdef CONFIG_PPC_BOOK3S_64 -#ifdef CONFIG_KVM_BOOK3S_PR +#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE + DEFINE(PACA_SVCPU, offsetof(struct paca_struct, shadow_vcpu)); # define SVCPU_FIELD(x, f) DEFINE(x, offsetof(struct paca_struct, shadow_vcpu.f)) #else # define SVCPU_FIELD(x, f) @@ -581,7 +580,7 @@ int main(void) HSTATE_FIELD(HSTATE_RESTORE_HID5, restore_hid5); HSTATE_FIELD(HSTATE_NAPPING, napping); -#ifdef CONFIG_KVM_BOOK3S_64_HV +#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE HSTATE_FIELD(HSTATE_HWTHREAD_REQ, hwthread_req); HSTATE_FIELD(HSTATE_HWTHREAD_STATE, hwthread_state); HSTATE_FIELD(HSTATE_KVM_VCPU, kvm_vcpu); @@ -597,10 +596,11 @@ int main(void) HSTATE_FIELD(HSTATE_DABR, dabr); HSTATE_FIELD(HSTATE_DECEXP, dec_expires); DEFINE(IPI_PRIORITY, IPI_PRIORITY); -#endif /* CONFIG_KVM_BOOK3S_64_HV */ +#endif /* CONFIG_KVM_BOOK3S_HV_POSSIBLE */ #ifdef CONFIG_PPC_BOOK3S_64 HSTATE_FIELD(HSTATE_CFAR, cfar); + HSTATE_FIELD(HSTATE_PPR, ppr); #endif /* CONFIG_PPC_BOOK3S_64 */ #else /* CONFIG_PPC_BOOK3S */ diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c index 55593ee2d5aa..671302065347 100644 --- a/arch/powerpc/kernel/eeh.c +++ b/arch/powerpc/kernel/eeh.c @@ -189,14 +189,13 @@ static size_t eeh_gather_pci_data(struct eeh_dev *edev, char * buf, size_t len) } /* If PCI-E capable, dump PCI-E cap 10, and the AER */ - cap = pci_find_capability(dev, PCI_CAP_ID_EXP); - if (cap) { + if (pci_is_pcie(dev)) { n += scnprintf(buf+n, len-n, "pci-e cap10:\n"); printk(KERN_WARNING "EEH: PCI-E capabilities and status follow:\n"); for (i=0; i<=8; i++) { - eeh_ops->read_config(dn, cap+4*i, 4, &cfg); + eeh_ops->read_config(dn, dev->pcie_cap+4*i, 4, &cfg); n += scnprintf(buf+n, len-n, "%02x:%x\n", 4*i, cfg); printk(KERN_WARNING "EEH: PCI-E %02x: %08x\n", i, cfg); } @@ -327,11 +326,11 @@ static int eeh_phb_check_failure(struct eeh_pe *pe) /* Isolate the PHB and send event */ eeh_pe_state_mark(phb_pe, EEH_PE_ISOLATED); eeh_serialize_unlock(flags); - eeh_send_failure_event(phb_pe); pr_err("EEH: PHB#%x failure detected\n", phb_pe->phb->global_number); dump_stack(); + eeh_send_failure_event(phb_pe); return 1; out: @@ -454,8 +453,6 @@ int eeh_dev_check_failure(struct eeh_dev *edev) eeh_pe_state_mark(pe, EEH_PE_ISOLATED); eeh_serialize_unlock(flags); - eeh_send_failure_event(pe); - /* Most EEH events are due to device driver bugs. Having * a stack trace will help the device-driver authors figure * out what happened. So print that out. @@ -464,6 +461,8 @@ int eeh_dev_check_failure(struct eeh_dev *edev) pe->addr, pe->phb->global_number); dump_stack(); + eeh_send_failure_event(pe); + return 1; dn_unlock: diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index c04cdf70d487..bbfb0294b354 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -673,9 +673,7 @@ _GLOBAL(ret_from_except_lite) resume_kernel: /* check current_thread_info, _TIF_EMULATE_STACK_STORE */ - CURRENT_THREAD_INFO(r9, r1) - ld r8,TI_FLAGS(r9) - andis. r8,r8,_TIF_EMULATE_STACK_STORE@h + andis. r8,r4,_TIF_EMULATE_STACK_STORE@h beq+ 1f addi r8,r1,INT_FRAME_SIZE /* Get the kprobed function entry */ @@ -820,6 +818,12 @@ fast_exception_return: andi. r0,r3,MSR_RI beq- unrecov_restore + /* Load PPR from thread struct before we clear MSR:RI */ +BEGIN_FTR_SECTION + ld r2,PACACURRENT(r13) + ld r2,TASKTHREADPPR(r2) +END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) + /* * Clear RI before restoring r13. If we are returning to * userspace and we take an exception after restoring r13, @@ -840,8 +844,10 @@ fast_exception_return: */ andi. r0,r3,MSR_PR beq 1f +BEGIN_FTR_SECTION + mtspr SPRN_PPR,r2 /* Restore PPR */ +END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) ACCOUNT_CPU_USER_EXIT(r2, r4) - RESTORE_PPR(r2, r4) REST_GPR(13, r1) 1: mtspr SPRN_SRR1,r3 @@ -1017,7 +1023,7 @@ _GLOBAL(enter_rtas) li r9,1 rldicr r9,r9,MSR_SF_LG,(63-MSR_SF_LG) - ori r9,r9,MSR_IR|MSR_DR|MSR_FE0|MSR_FE1|MSR_FP|MSR_RI + ori r9,r9,MSR_IR|MSR_DR|MSR_FE0|MSR_FE1|MSR_FP|MSR_RI|MSR_LE andc r6,r0,r9 sync /* disable interrupts so SRR0/1 */ mtmsrd r0 /* don't get trashed */ @@ -1032,6 +1038,8 @@ _GLOBAL(enter_rtas) b . /* prevent speculative execution */ _STATIC(rtas_return_loc) + FIXUP_ENDIAN + /* relocation is off at this point */ GET_PACA(r4) clrldi r4,r4,2 /* convert to realmode address */ @@ -1103,28 +1111,30 @@ _GLOBAL(enter_prom) std r10,_CCR(r1) std r11,_MSR(r1) - /* Get the PROM entrypoint */ - mtlr r4 + /* Put PROM address in SRR0 */ + mtsrr0 r4 - /* Switch MSR to 32 bits mode + /* Setup our trampoline return addr in LR */ + bcl 20,31,$+4 +0: mflr r4 + addi r4,r4,(1f - 0b) + mtlr r4 + + /* Prepare a 32-bit mode big endian MSR */ #ifdef CONFIG_PPC_BOOK3E rlwinm r11,r11,0,1,31 - mtmsr r11 + mtsrr1 r11 + rfi #else /* CONFIG_PPC_BOOK3E */ - mfmsr r11 - li r12,1 - rldicr r12,r12,MSR_SF_LG,(63-MSR_SF_LG) - andc r11,r11,r12 - li r12,1 - rldicr r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG) - andc r11,r11,r12 - mtmsrd r11 + LOAD_REG_IMMEDIATE(r12, MSR_SF | MSR_ISF | MSR_LE) + andc r11,r11,r12 + mtsrr1 r11 + rfid #endif /* CONFIG_PPC_BOOK3E */ - isync - /* Enter PROM here... */ - blrl +1: /* Return from OF */ + FIXUP_ENDIAN /* Just make sure that r1 top 32 bits didn't get * corrupt by OF diff --git a/arch/powerpc/kernel/epapr_paravirt.c b/arch/powerpc/kernel/epapr_paravirt.c index 6300c13bbde4..7898be90f2dc 100644 --- a/arch/powerpc/kernel/epapr_paravirt.c +++ b/arch/powerpc/kernel/epapr_paravirt.c @@ -18,6 +18,7 @@ */ #include <linux/of.h> +#include <linux/of_fdt.h> #include <asm/epapr_hcalls.h> #include <asm/cacheflush.h> #include <asm/code-patching.h> diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S index 2d067049db27..e7751561fd1d 100644 --- a/arch/powerpc/kernel/exceptions-64e.S +++ b/arch/powerpc/kernel/exceptions-64e.S @@ -399,7 +399,7 @@ interrupt_end_book3e: /* Altivec Unavailable Interrupt */ START_EXCEPTION(altivec_unavailable); - NORMAL_EXCEPTION_PROLOG(0x200, BOOKE_INTERRUPT_ALTIVEC_UNAVAIL, + NORMAL_EXCEPTION_PROLOG(0x200, BOOKE_INTERRUPT_SPE_ALTIVEC_UNAVAIL, PROLOG_ADDITION_NONE) /* we can probably do a shorter exception entry for that one... */ EXCEPTION_COMMON(0x200, PACA_EXGEN, INTS_KEEP) @@ -421,7 +421,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) /* AltiVec Assist */ START_EXCEPTION(altivec_assist); - NORMAL_EXCEPTION_PROLOG(0x220, BOOKE_INTERRUPT_ALTIVEC_ASSIST, + NORMAL_EXCEPTION_PROLOG(0x220, + BOOKE_INTERRUPT_SPE_FP_DATA_ALTIVEC_ASSIST, PROLOG_ADDITION_NONE) EXCEPTION_COMMON(0x220, PACA_EXGEN, INTS_DISABLE) bl .save_nvgprs @@ -607,6 +608,7 @@ kernel_dbg_exc: NORMAL_EXCEPTION_PROLOG(0x260, BOOKE_INTERRUPT_PERFORMANCE_MONITOR, PROLOG_ADDITION_NONE) EXCEPTION_COMMON(0x260, PACA_EXGEN, INTS_DISABLE) + CHECK_NAPPING() addi r3,r1,STACK_FRAME_OVERHEAD bl .performance_monitor_exception b .ret_from_except_lite diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 3a9ed6ac224b..9f905e40922e 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -126,7 +126,7 @@ BEGIN_FTR_SECTION bgt cr1,. GET_PACA(r13) -#ifdef CONFIG_KVM_BOOK3S_64_HV +#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE li r0,KVM_HWTHREAD_IN_KERNEL stb r0,HSTATE_HWTHREAD_STATE(r13) /* Order setting hwthread_state vs. testing hwthread_req */ @@ -425,7 +425,7 @@ data_access_check_stab: mfspr r9,SPRN_DSISR srdi r10,r10,60 rlwimi r10,r9,16,0x20 -#ifdef CONFIG_KVM_BOOK3S_PR +#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE lbz r9,HSTATE_IN_GUEST(r13) rlwimi r10,r9,8,0x300 #endif @@ -650,6 +650,32 @@ slb_miss_user_pseries: b . /* prevent spec. execution */ #endif /* __DISABLED__ */ +#ifdef CONFIG_KVM_BOOK3S_64_HANDLER +kvmppc_skip_interrupt: + /* + * Here all GPRs are unchanged from when the interrupt happened + * except for r13, which is saved in SPRG_SCRATCH0. + */ + mfspr r13, SPRN_SRR0 + addi r13, r13, 4 + mtspr SPRN_SRR0, r13 + GET_SCRATCH0(r13) + rfid + b . + +kvmppc_skip_Hinterrupt: + /* + * Here all GPRs are unchanged from when the interrupt happened + * except for r13, which is saved in SPRG_SCRATCH0. + */ + mfspr r13, SPRN_HSRR0 + addi r13, r13, 4 + mtspr SPRN_HSRR0, r13 + GET_SCRATCH0(r13) + hrfid + b . +#endif + /* * Code from here down to __end_handlers is invoked from the * exception prologs above. Because the prologs assemble the diff --git a/arch/powerpc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S index caeaabf11a2f..f7f5b8bed68f 100644 --- a/arch/powerpc/kernel/fpu.S +++ b/arch/powerpc/kernel/fpu.S @@ -35,15 +35,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX); \ 2: REST_32VSRS(n,c,base); \ 3: -#define __REST_32FPVSRS_TRANSACT(n,c,base) \ -BEGIN_FTR_SECTION \ - b 2f; \ -END_FTR_SECTION_IFSET(CPU_FTR_VSX); \ - REST_32FPRS_TRANSACT(n,base); \ - b 3f; \ -2: REST_32VSRS_TRANSACT(n,c,base); \ -3: - #define __SAVE_32FPVSRS(n,c,base) \ BEGIN_FTR_SECTION \ b 2f; \ @@ -54,40 +45,12 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX); \ 3: #else #define __REST_32FPVSRS(n,b,base) REST_32FPRS(n, base) -#define __REST_32FPVSRS_TRANSACT(n,b,base) REST_32FPRS(n, base) #define __SAVE_32FPVSRS(n,b,base) SAVE_32FPRS(n, base) #endif #define REST_32FPVSRS(n,c,base) __REST_32FPVSRS(n,__REG_##c,__REG_##base) -#define REST_32FPVSRS_TRANSACT(n,c,base) \ - __REST_32FPVSRS_TRANSACT(n,__REG_##c,__REG_##base) #define SAVE_32FPVSRS(n,c,base) __SAVE_32FPVSRS(n,__REG_##c,__REG_##base) #ifdef CONFIG_PPC_TRANSACTIONAL_MEM -/* - * Wrapper to call load_up_fpu from C. - * void do_load_up_fpu(struct pt_regs *regs); - */ -_GLOBAL(do_load_up_fpu) - mflr r0 - std r0, 16(r1) - stdu r1, -112(r1) - - subi r6, r3, STACK_FRAME_OVERHEAD - /* load_up_fpu expects r12=MSR, r13=PACA, and returns - * with r12 = new MSR. - */ - ld r12,_MSR(r6) - GET_PACA(r13) - - bl load_up_fpu - std r12,_MSR(r6) - - ld r0, 112+16(r1) - addi r1, r1, 112 - mtlr r0 - blr - - /* void do_load_up_transact_fpu(struct thread_struct *thread) * * This is similar to load_up_fpu but for the transactional version of the FP @@ -105,9 +68,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX) SYNC MTMSRD(r5) - lfd fr0,THREAD_TRANSACT_FPSCR(r3) + addi r7,r3,THREAD_TRANSACT_FPSTATE + lfd fr0,FPSTATE_FPSCR(r7) MTFSF_L(fr0) - REST_32FPVSRS_TRANSACT(0, R4, R3) + REST_32FPVSRS(0, R4, R7) /* FP/VSX off again */ MTMSRD(r6) @@ -117,11 +81,33 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX) #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ /* + * Load state from memory into FP registers including FPSCR. + * Assumes the caller has enabled FP in the MSR. + */ +_GLOBAL(load_fp_state) + lfd fr0,FPSTATE_FPSCR(r3) + MTFSF_L(fr0) + REST_32FPVSRS(0, R4, R3) + blr + +/* + * Store FP state into memory, including FPSCR + * Assumes the caller has enabled FP in the MSR. + */ +_GLOBAL(store_fp_state) + SAVE_32FPVSRS(0, R4, R3) + mffs fr0 + stfd fr0,FPSTATE_FPSCR(r3) + blr + +/* * This task wants to use the FPU now. * On UP, disable FP for the task which had the FPU previously, * and save its floating-point registers in its thread_struct. * Load up this task's FP registers from its thread_struct, * enable the FPU for the current task and return to the task. + * Note that on 32-bit this can only use registers that will be + * restored by fast_exception_return, i.e. r3 - r6, r10 and r11. */ _GLOBAL(load_up_fpu) mfmsr r5 @@ -147,9 +133,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX) beq 1f toreal(r4) addi r4,r4,THREAD /* want last_task_used_math->thread */ - SAVE_32FPVSRS(0, R5, R4) + addi r10,r4,THREAD_FPSTATE + SAVE_32FPVSRS(0, R5, R10) mffs fr0 - stfd fr0,THREAD_FPSCR(r4) + stfd fr0,FPSTATE_FPSCR(r10) PPC_LL r5,PT_REGS(r4) toreal(r5) PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5) @@ -160,7 +147,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX) #endif /* CONFIG_SMP */ /* enable use of FP after return */ #ifdef CONFIG_PPC32 - mfspr r5,SPRN_SPRG_THREAD /* current task's THREAD (phys) */ + mfspr r5,SPRN_SPRG_THREAD /* current task's THREAD (phys) */ lwz r4,THREAD_FPEXC_MODE(r5) ori r9,r9,MSR_FP /* enable FP for current */ or r9,r9,r4 @@ -172,9 +159,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX) or r12,r12,r4 std r12,_MSR(r1) #endif - lfd fr0,THREAD_FPSCR(r5) + addi r10,r5,THREAD_FPSTATE + lfd fr0,FPSTATE_FPSCR(r10) MTFSF_L(fr0) - REST_32FPVSRS(0, R4, R5) + REST_32FPVSRS(0, R4, R10) #ifndef CONFIG_SMP subi r4,r5,THREAD fromreal(r4) @@ -206,11 +194,15 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX) PPC_LCMPI 0,r3,0 beqlr- /* if no previous owner, done */ addi r3,r3,THREAD /* want THREAD of task */ + PPC_LL r6,THREAD_FPSAVEAREA(r3) PPC_LL r5,PT_REGS(r3) - PPC_LCMPI 0,r5,0 - SAVE_32FPVSRS(0, R4 ,R3) + PPC_LCMPI 0,r6,0 + bne 2f + addi r6,r3,THREAD_FPSTATE +2: PPC_LCMPI 0,r5,0 + SAVE_32FPVSRS(0, R4, R6) mffs fr0 - stfd fr0,THREAD_FPSCR(r3) + stfd fr0,FPSTATE_FPSCR(r6) beq 1f PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5) li r3,MSR_FP|MSR_FE0|MSR_FE1 diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c index 1fb78561096a..9b27b293a922 100644 --- a/arch/powerpc/kernel/ftrace.c +++ b/arch/powerpc/kernel/ftrace.c @@ -174,7 +174,11 @@ __ftrace_make_nop(struct module *mod, pr_devel(" %08x %08x\n", jmp[0], jmp[1]); +#ifdef __LITTLE_ENDIAN__ + ptr = ((unsigned long)jmp[1] << 32) + jmp[0]; +#else ptr = ((unsigned long)jmp[0] << 32) + jmp[1]; +#endif /* This should match what was called */ if (ptr != ppc_function_entry((void *)addr)) { diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 3d11d8038dee..2ae41aba4053 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -68,6 +68,7 @@ _stext: _GLOBAL(__start) /* NOP this out unconditionally */ BEGIN_FTR_SECTION + FIXUP_ENDIAN b .__start_initialization_multiplatform END_FTR_SECTION(0, 1) @@ -115,6 +116,7 @@ __run_at_load: */ .globl __secondary_hold __secondary_hold: + FIXUP_ENDIAN #ifndef CONFIG_PPC_BOOK3E mfmsr r24 ori r24,r24,MSR_RI @@ -205,6 +207,7 @@ _GLOBAL(generic_secondary_thread_init) * as SCOM before entry). */ _GLOBAL(generic_secondary_smp_init) + FIXUP_ENDIAN mr r24,r3 mr r25,r4 diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index 1b92a97b1b04..7ee876d2adb5 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S @@ -858,6 +858,9 @@ initial_mmu: addis r11, r11, 0x0080 /* Add 8M */ mtspr SPRN_MD_RPN, r11 + addi r10, r10, 0x0100 + mtspr SPRN_MD_CTR, r10 + addis r8, r8, 0x0080 /* Add 8M */ mtspr SPRN_MD_EPN, r8 mtspr SPRN_MD_TWC, r9 diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index 289afaffbbb5..f45726a1d963 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S @@ -555,27 +555,27 @@ END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV) #ifdef CONFIG_SPE /* SPE Unavailable */ START_EXCEPTION(SPEUnavailable) - NORMAL_EXCEPTION_PROLOG(SPE_UNAVAIL) + NORMAL_EXCEPTION_PROLOG(SPE_ALTIVEC_UNAVAIL) beq 1f bl load_up_spe b fast_exception_return 1: addi r3,r1,STACK_FRAME_OVERHEAD EXC_XFER_EE_LITE(0x2010, KernelSPE) #else - EXCEPTION(0x2020, SPE_UNAVAIL, SPEUnavailable, \ + EXCEPTION(0x2020, SPE_ALTIVEC_UNAVAIL, SPEUnavailable, \ unknown_exception, EXC_XFER_EE) #endif /* CONFIG_SPE */ /* SPE Floating Point Data */ #ifdef CONFIG_SPE - EXCEPTION(0x2030, SPE_FP_DATA, SPEFloatingPointData, \ - SPEFloatingPointException, EXC_XFER_EE); + EXCEPTION(0x2030, SPE_FP_DATA_ALTIVEC_ASSIST, SPEFloatingPointData, + SPEFloatingPointException, EXC_XFER_EE) /* SPE Floating Point Round */ EXCEPTION(0x2050, SPE_FP_ROUND, SPEFloatingPointRound, \ SPEFloatingPointRoundException, EXC_XFER_EE) #else - EXCEPTION(0x2040, SPE_FP_DATA, SPEFloatingPointData, \ + EXCEPTION(0x2040, SPE_FP_DATA_ALTIVEC_ASSIST, SPEFloatingPointData, unknown_exception, EXC_XFER_EE) EXCEPTION(0x2050, SPE_FP_ROUND, SPEFloatingPointRound, \ unknown_exception, EXC_XFER_EE) diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c index 16a7c2326d48..1114d13ac19f 100644 --- a/arch/powerpc/kernel/ibmebus.c +++ b/arch/powerpc/kernel/ibmebus.c @@ -292,6 +292,7 @@ out: return rc; return count; } +static BUS_ATTR(probe, S_IWUSR, NULL, ibmebus_store_probe); static ssize_t ibmebus_store_remove(struct bus_type *bus, const char *buf, size_t count) @@ -317,13 +318,14 @@ static ssize_t ibmebus_store_remove(struct bus_type *bus, return -ENODEV; } } +static BUS_ATTR(remove, S_IWUSR, NULL, ibmebus_store_remove); - -static struct bus_attribute ibmebus_bus_attrs[] = { - __ATTR(probe, S_IWUSR, NULL, ibmebus_store_probe), - __ATTR(remove, S_IWUSR, NULL, ibmebus_store_remove), - __ATTR_NULL +static struct attribute *ibmbus_bus_attrs[] = { + &bus_attr_probe.attr, + &bus_attr_remove.attr, + NULL, }; +ATTRIBUTE_GROUPS(ibmbus_bus); static int ibmebus_bus_bus_match(struct device *dev, struct device_driver *drv) { @@ -713,7 +715,7 @@ static struct dev_pm_ops ibmebus_bus_dev_pm_ops = { struct bus_type ibmebus_bus_type = { .name = "ibmebus", .uevent = of_device_uevent_modalias, - .bus_attrs = ibmebus_bus_attrs, + .bus_groups = ibmbus_bus_groups, .match = ibmebus_bus_bus_match, .probe = ibmebus_bus_device_probe, .remove = ibmebus_bus_device_remove, diff --git a/arch/powerpc/kernel/idle_power7.S b/arch/powerpc/kernel/idle_power7.S index e11863f4e595..847e40e62fce 100644 --- a/arch/powerpc/kernel/idle_power7.S +++ b/arch/powerpc/kernel/idle_power7.S @@ -84,7 +84,7 @@ _GLOBAL(power7_nap) std r9,_MSR(r1) std r1,PACAR1(r13) -#ifdef CONFIG_KVM_BOOK3S_64_HV +#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE /* Tell KVM we're napping */ li r4,KVM_HWTHREAD_IN_NAP stb r4,HSTATE_HWTHREAD_STATE(r13) diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index c7cb8c232d2f..ba0165615215 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -594,7 +594,7 @@ void irq_ctx_init(void) } } -static inline void do_softirq_onstack(void) +void do_softirq_own_stack(void) { struct thread_info *curtp, *irqtp; @@ -612,21 +612,6 @@ static inline void do_softirq_onstack(void) set_bits(irqtp->flags, &curtp->flags); } -void do_softirq(void) -{ - unsigned long flags; - - if (in_interrupt()) - return; - - local_irq_save(flags); - - if (local_softirq_pending()) - do_softirq_onstack(); - - local_irq_restore(flags); -} - irq_hw_number_t virq_to_hw(unsigned int virq) { struct irq_data *irq_data = irq_get_irq_data(virq); diff --git a/arch/powerpc/kernel/kgdb.c b/arch/powerpc/kernel/kgdb.c index c1eef241017a..83e89d310734 100644 --- a/arch/powerpc/kernel/kgdb.c +++ b/arch/powerpc/kernel/kgdb.c @@ -151,15 +151,16 @@ static int kgdb_handle_breakpoint(struct pt_regs *regs) return 1; } +static DEFINE_PER_CPU(struct thread_info, kgdb_thread_info); static int kgdb_singlestep(struct pt_regs *regs) { struct thread_info *thread_info, *exception_thread_info; - struct thread_info *backup_current_thread_info; + struct thread_info *backup_current_thread_info = + &__get_cpu_var(kgdb_thread_info); if (user_mode(regs)) return 0; - backup_current_thread_info = kmalloc(sizeof(struct thread_info), GFP_KERNEL); /* * On Book E and perhaps other processors, singlestep is handled on * the critical exception stack. This causes current_thread_info() @@ -185,7 +186,6 @@ static int kgdb_singlestep(struct pt_regs *regs) /* Restore current_thread_info lastly. */ memcpy(exception_thread_info, backup_current_thread_info, sizeof *thread_info); - kfree(backup_current_thread_info); return 1; } diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c index 2156ea90eb54..90fab64d911d 100644 --- a/arch/powerpc/kernel/kprobes.c +++ b/arch/powerpc/kernel/kprobes.c @@ -429,7 +429,7 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) case KPROBE_HIT_SSDONE: /* * We increment the nmissed count for accounting, - * we can also use npre/npostfault count for accouting + * we can also use npre/npostfault count for accounting * these specific fault cases. */ kprobes_inc_nmissed_count(cur); diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c index 22e88dd2f34a..40bd7bd4e19a 100644 --- a/arch/powerpc/kernel/legacy_serial.c +++ b/arch/powerpc/kernel/legacy_serial.c @@ -35,7 +35,7 @@ static struct legacy_serial_info { phys_addr_t taddr; } legacy_serial_infos[MAX_LEGACY_SERIAL_PORTS]; -static struct __initdata of_device_id legacy_serial_parents[] = { +static struct of_device_id legacy_serial_parents[] __initdata = { {.type = "soc",}, {.type = "tsi-bridge",}, {.type = "opb", }, diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c index 611acdf30096..be4e6d648f60 100644 --- a/arch/powerpc/kernel/machine_kexec_64.c +++ b/arch/powerpc/kernel/machine_kexec_64.c @@ -312,7 +312,7 @@ static union thread_union kexec_stack __init_task_data = */ struct paca_struct kexec_paca; -/* Our assembly helper, in kexec_stub.S */ +/* Our assembly helper, in misc_64.S */ extern void kexec_sequence(void *newstack, unsigned long start, void *image, void *control, void (*clear_all)(void)) __noreturn; diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index 2b0ad9845363..e47d268727a4 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S @@ -659,6 +659,20 @@ _GLOBAL(__lshrdi3) blr /* + * 64-bit comparison: __cmpdi2(s64 a, s64 b) + * Returns 0 if a < b, 1 if a == b, 2 if a > b. + */ +_GLOBAL(__cmpdi2) + cmpw r3,r5 + li r3,1 + bne 1f + cmplw r4,r6 + beqlr +1: li r3,0 + bltlr + li r3,2 + blr +/* * 64-bit comparison: __ucmpdi2(u64 a, u64 b) * Returns 0 if a < b, 1 if a == b, 2 if a > b. */ diff --git a/arch/powerpc/kernel/module.c b/arch/powerpc/kernel/module.c index 2d275707f419..9547381b631a 100644 --- a/arch/powerpc/kernel/module.c +++ b/arch/powerpc/kernel/module.c @@ -25,8 +25,7 @@ #include <asm/uaccess.h> #include <asm/firmware.h> #include <linux/sort.h> - -#include "setup.h" +#include <asm/setup.h> LIST_HEAD(module_bug_list); diff --git a/arch/powerpc/kernel/module_32.c b/arch/powerpc/kernel/module_32.c index 2e3200ca485f..6cff040bf456 100644 --- a/arch/powerpc/kernel/module_32.c +++ b/arch/powerpc/kernel/module_32.c @@ -26,8 +26,7 @@ #include <linux/cache.h> #include <linux/bug.h> #include <linux/sort.h> - -#include "setup.h" +#include <asm/setup.h> #if 0 #define DEBUGP printk diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c index 6ee59a0eb268..12664c130d73 100644 --- a/arch/powerpc/kernel/module_64.c +++ b/arch/powerpc/kernel/module_64.c @@ -26,8 +26,7 @@ #include <asm/firmware.h> #include <asm/code-patching.h> #include <linux/sort.h> - -#include "setup.h" +#include <asm/setup.h> /* FIXME: We don't do .init separately. To do this, we'd need to have a separate r2 value in the init and core section, and stub between @@ -62,6 +61,16 @@ struct ppc64_stub_entry r2) into the stub. */ static struct ppc64_stub_entry ppc64_stub = { .jump = { +#ifdef __LITTLE_ENDIAN__ + 0x00, 0x00, 0x82, 0x3d, /* addis r12,r2, <high> */ + 0x00, 0x00, 0x8c, 0x39, /* addi r12,r12, <low> */ + /* Save current r2 value in magic place on the stack. */ + 0x28, 0x00, 0x41, 0xf8, /* std r2,40(r1) */ + 0x20, 0x00, 0x6c, 0xe9, /* ld r11,32(r12) */ + 0x28, 0x00, 0x4c, 0xe8, /* ld r2,40(r12) */ + 0xa6, 0x03, 0x69, 0x7d, /* mtctr r11 */ + 0x20, 0x04, 0x80, 0x4e /* bctr */ +#else 0x3d, 0x82, 0x00, 0x00, /* addis r12,r2, <high> */ 0x39, 0x8c, 0x00, 0x00, /* addi r12,r12, <low> */ /* Save current r2 value in magic place on the stack. */ @@ -70,6 +79,7 @@ static struct ppc64_stub_entry ppc64_stub = 0xe8, 0x4c, 0x00, 0x28, /* ld r2,40(r12) */ 0x7d, 0x69, 0x03, 0xa6, /* mtctr r11 */ 0x4e, 0x80, 0x04, 0x20 /* bctr */ +#endif } }; /* Count how many different 24-bit relocations (different symbol, @@ -269,8 +279,13 @@ static inline int create_stub(Elf64_Shdr *sechdrs, *entry = ppc64_stub; +#ifdef __LITTLE_ENDIAN__ + loc1 = (Elf64_Half *)&entry->jump[0]; + loc2 = (Elf64_Half *)&entry->jump[4]; +#else loc1 = (Elf64_Half *)&entry->jump[2]; loc2 = (Elf64_Half *)&entry->jump[6]; +#endif /* Stub uses address relative to r2. */ reladdr = (unsigned long)entry - my_r2(sechdrs, me); diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c index 8213ee1eb05a..fd82c289ab1c 100644 --- a/arch/powerpc/kernel/nvram_64.c +++ b/arch/powerpc/kernel/nvram_64.c @@ -223,9 +223,13 @@ static int __init nvram_write_header(struct nvram_partition * part) { loff_t tmp_index; int rc; - + struct nvram_header phead; + + memcpy(&phead, &part->header, NVRAM_HEADER_LEN); + phead.length = cpu_to_be16(phead.length); + tmp_index = part->index; - rc = ppc_md.nvram_write((char *)&part->header, NVRAM_HEADER_LEN, &tmp_index); + rc = ppc_md.nvram_write((char *)&phead, NVRAM_HEADER_LEN, &tmp_index); return rc; } @@ -505,6 +509,8 @@ int __init nvram_scan_partitions(void) memcpy(&phead, header, NVRAM_HEADER_LEN); + phead.length = be16_to_cpu(phead.length); + err = 0; c_sum = nvram_checksum(&phead); if (c_sum != phead.checksum) { diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c index 3fc16e3beb9f..0620eaaaad45 100644 --- a/arch/powerpc/kernel/paca.c +++ b/arch/powerpc/kernel/paca.c @@ -46,7 +46,7 @@ struct lppaca lppaca[] = { static struct lppaca *extra_lppacas; static long __initdata lppaca_size; -static void allocate_lppacas(int nr_cpus, unsigned long limit) +static void __init allocate_lppacas(int nr_cpus, unsigned long limit) { if (nr_cpus <= NR_LPPACAS) return; @@ -57,7 +57,7 @@ static void allocate_lppacas(int nr_cpus, unsigned long limit) PAGE_SIZE, limit)); } -static struct lppaca *new_lppaca(int cpu) +static struct lppaca * __init new_lppaca(int cpu) { struct lppaca *lp; @@ -70,7 +70,7 @@ static struct lppaca *new_lppaca(int cpu) return lp; } -static void free_lppacas(void) +static void __init free_lppacas(void) { long new_size = 0, nr; diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 905a24bb7acc..a1e3e40ca3fd 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -228,7 +228,7 @@ int pcibios_add_platform_entries(struct pci_dev *pdev) */ static int pci_read_irq_line(struct pci_dev *pci_dev) { - struct of_irq oirq; + struct of_phandle_args oirq; unsigned int virq; pr_debug("PCI: Try to map irq for %s...\n", pci_name(pci_dev)); @@ -237,7 +237,7 @@ static int pci_read_irq_line(struct pci_dev *pci_dev) memset(&oirq, 0xff, sizeof(oirq)); #endif /* Try to get a mapping from the device-tree */ - if (of_irq_map_pci(pci_dev, &oirq)) { + if (of_irq_parse_pci(pci_dev, &oirq)) { u8 line, pin; /* If that fails, lets fallback to what is in the config @@ -263,11 +263,10 @@ static int pci_read_irq_line(struct pci_dev *pci_dev) irq_set_irq_type(virq, IRQ_TYPE_LEVEL_LOW); } else { pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %s\n", - oirq.size, oirq.specifier[0], oirq.specifier[1], - of_node_full_name(oirq.controller)); + oirq.args_count, oirq.args[0], oirq.args[1], + of_node_full_name(oirq.np)); - virq = irq_create_of_mapping(oirq.controller, oirq.specifier, - oirq.size); + virq = irq_create_of_mapping(&oirq); } if(virq == NO_IRQ) { pr_debug(" Failed to map !\n"); diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c index 4368ec6fdc8c..ac0b034f9ae0 100644 --- a/arch/powerpc/kernel/pci_of_scan.c +++ b/arch/powerpc/kernel/pci_of_scan.c @@ -302,7 +302,7 @@ static struct pci_dev *of_scan_pci_dev(struct pci_bus *bus, struct device_node *dn) { struct pci_dev *dev = NULL; - const u32 *reg; + const __be32 *reg; int reglen, devfn; pr_debug(" * %s\n", dn->full_name); @@ -312,7 +312,7 @@ static struct pci_dev *of_scan_pci_dev(struct pci_bus *bus, reg = of_get_property(dn, "reg", ®len); if (reg == NULL || reglen < 20) return NULL; - devfn = (reg[0] >> 8) & 0xff; + devfn = (of_read_number(reg, 1) >> 8) & 0xff; /* Check if the PCI device is already there */ dev = pci_get_slot(bus, devfn); diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index 21646dbe1bb3..3bd77edd7610 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c @@ -79,10 +79,12 @@ EXPORT_SYMBOL(strlen); EXPORT_SYMBOL(strcmp); EXPORT_SYMBOL(strncmp); +#ifndef CONFIG_GENERIC_CSUM EXPORT_SYMBOL(csum_partial); EXPORT_SYMBOL(csum_partial_copy_generic); EXPORT_SYMBOL(ip_fast_csum); EXPORT_SYMBOL(csum_tcpudp_magic); +#endif EXPORT_SYMBOL(__copy_tofrom_user); EXPORT_SYMBOL(__clear_user); @@ -98,9 +100,13 @@ EXPORT_SYMBOL(start_thread); #ifdef CONFIG_PPC_FPU EXPORT_SYMBOL(giveup_fpu); +EXPORT_SYMBOL(load_fp_state); +EXPORT_SYMBOL(store_fp_state); #endif #ifdef CONFIG_ALTIVEC EXPORT_SYMBOL(giveup_altivec); +EXPORT_SYMBOL(load_vr_state); +EXPORT_SYMBOL(store_vr_state); #endif /* CONFIG_ALTIVEC */ #ifdef CONFIG_VSX EXPORT_SYMBOL(giveup_vsx); @@ -143,10 +149,14 @@ EXPORT_SYMBOL(__ashldi3); EXPORT_SYMBOL(__lshrdi3); int __ucmpdi2(unsigned long long, unsigned long long); EXPORT_SYMBOL(__ucmpdi2); +int __cmpdi2(long long, long long); +EXPORT_SYMBOL(__cmpdi2); #endif long long __bswapdi2(long long); EXPORT_SYMBOL(__bswapdi2); +#ifdef __BIG_ENDIAN__ EXPORT_SYMBOL(memcpy); +#endif EXPORT_SYMBOL(memset); EXPORT_SYMBOL(memmove); EXPORT_SYMBOL(memcmp); diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 96d2fdf3aa9e..75c2d1009985 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -314,28 +314,28 @@ static DEFINE_PER_CPU(struct arch_hw_breakpoint, current_brk); */ static void set_debug_reg_defaults(struct thread_struct *thread) { - thread->iac1 = thread->iac2 = 0; + thread->debug.iac1 = thread->debug.iac2 = 0; #if CONFIG_PPC_ADV_DEBUG_IACS > 2 - thread->iac3 = thread->iac4 = 0; + thread->debug.iac3 = thread->debug.iac4 = 0; #endif - thread->dac1 = thread->dac2 = 0; + thread->debug.dac1 = thread->debug.dac2 = 0; #if CONFIG_PPC_ADV_DEBUG_DVCS > 0 - thread->dvc1 = thread->dvc2 = 0; + thread->debug.dvc1 = thread->debug.dvc2 = 0; #endif - thread->dbcr0 = 0; + thread->debug.dbcr0 = 0; #ifdef CONFIG_BOOKE /* * Force User/Supervisor bits to b11 (user-only MSR[PR]=1) */ - thread->dbcr1 = DBCR1_IAC1US | DBCR1_IAC2US | \ + thread->debug.dbcr1 = DBCR1_IAC1US | DBCR1_IAC2US | DBCR1_IAC3US | DBCR1_IAC4US; /* * Force Data Address Compare User/Supervisor bits to be User-only * (0b11 MSR[PR]=1) and set all other bits in DBCR2 register to be 0. */ - thread->dbcr2 = DBCR2_DAC1US | DBCR2_DAC2US; + thread->debug.dbcr2 = DBCR2_DAC1US | DBCR2_DAC2US; #else - thread->dbcr1 = 0; + thread->debug.dbcr1 = 0; #endif } @@ -348,22 +348,22 @@ static void prime_debug_regs(struct thread_struct *thread) */ mtmsr(mfmsr() & ~MSR_DE); - mtspr(SPRN_IAC1, thread->iac1); - mtspr(SPRN_IAC2, thread->iac2); + mtspr(SPRN_IAC1, thread->debug.iac1); + mtspr(SPRN_IAC2, thread->debug.iac2); #if CONFIG_PPC_ADV_DEBUG_IACS > 2 - mtspr(SPRN_IAC3, thread->iac3); - mtspr(SPRN_IAC4, thread->iac4); + mtspr(SPRN_IAC3, thread->debug.iac3); + mtspr(SPRN_IAC4, thread->debug.iac4); #endif - mtspr(SPRN_DAC1, thread->dac1); - mtspr(SPRN_DAC2, thread->dac2); + mtspr(SPRN_DAC1, thread->debug.dac1); + mtspr(SPRN_DAC2, thread->debug.dac2); #if CONFIG_PPC_ADV_DEBUG_DVCS > 0 - mtspr(SPRN_DVC1, thread->dvc1); - mtspr(SPRN_DVC2, thread->dvc2); + mtspr(SPRN_DVC1, thread->debug.dvc1); + mtspr(SPRN_DVC2, thread->debug.dvc2); #endif - mtspr(SPRN_DBCR0, thread->dbcr0); - mtspr(SPRN_DBCR1, thread->dbcr1); + mtspr(SPRN_DBCR0, thread->debug.dbcr0); + mtspr(SPRN_DBCR1, thread->debug.dbcr1); #ifdef CONFIG_BOOKE - mtspr(SPRN_DBCR2, thread->dbcr2); + mtspr(SPRN_DBCR2, thread->debug.dbcr2); #endif } /* @@ -371,12 +371,13 @@ static void prime_debug_regs(struct thread_struct *thread) * debug registers, set the debug registers from the values * stored in the new thread. */ -static void switch_booke_debug_regs(struct thread_struct *new_thread) +void switch_booke_debug_regs(struct thread_struct *new_thread) { - if ((current->thread.dbcr0 & DBCR0_IDM) - || (new_thread->dbcr0 & DBCR0_IDM)) + if ((current->thread.debug.dbcr0 & DBCR0_IDM) + || (new_thread->debug.dbcr0 & DBCR0_IDM)) prime_debug_regs(new_thread); } +EXPORT_SYMBOL_GPL(switch_booke_debug_regs); #else /* !CONFIG_PPC_ADV_DEBUG_REGS */ #ifndef CONFIG_HAVE_HW_BREAKPOINT static void set_debug_reg_defaults(struct thread_struct *thread) @@ -596,12 +597,13 @@ struct task_struct *__switch_to(struct task_struct *prev, struct task_struct *new) { struct thread_struct *new_thread, *old_thread; - unsigned long flags; struct task_struct *last; #ifdef CONFIG_PPC_BOOK3S_64 struct ppc64_tlb_batch *batch; #endif + WARN_ON(!irqs_disabled()); + /* Back up the TAR across context switches. * Note that the TAR is not available for use in the kernel. (To * provide this, the TAR should be backed up/restored on exception @@ -721,8 +723,6 @@ struct task_struct *__switch_to(struct task_struct *prev, } #endif /* CONFIG_PPC_BOOK3S_64 */ - local_irq_save(flags); - /* * We can't take a PMU exception inside _switch() since there is a * window where the kernel stack SLB and the kernel stack are out @@ -742,8 +742,6 @@ struct task_struct *__switch_to(struct task_struct *prev, } #endif /* CONFIG_PPC_BOOK3S_64 */ - local_irq_restore(flags); - return last; } @@ -1008,6 +1006,11 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, p->thread.ptrace_bps[0] = NULL; #endif + p->thread.fp_save_area = NULL; +#ifdef CONFIG_ALTIVEC + p->thread.vr_save_area = NULL; +#endif + #ifdef CONFIG_PPC_STD_MMU_64 if (mmu_has_feature(MMU_FTR_SLB)) { unsigned long sp_vsid; @@ -1113,12 +1116,12 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp) #ifdef CONFIG_VSX current->thread.used_vsr = 0; #endif - memset(current->thread.fpr, 0, sizeof(current->thread.fpr)); - current->thread.fpscr.val = 0; + memset(¤t->thread.fp_state, 0, sizeof(current->thread.fp_state)); + current->thread.fp_save_area = NULL; #ifdef CONFIG_ALTIVEC - memset(current->thread.vr, 0, sizeof(current->thread.vr)); - memset(¤t->thread.vscr, 0, sizeof(current->thread.vscr)); - current->thread.vscr.u[3] = 0x00010000; /* Java mode disabled */ + memset(¤t->thread.vr_state, 0, sizeof(current->thread.vr_state)); + current->thread.vr_state.vscr.u[3] = 0x00010000; /* Java mode disabled */ + current->thread.vr_save_area = NULL; current->thread.vrsave = 0; current->thread.used_vr = 0; #endif /* CONFIG_ALTIVEC */ diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index b7634ce41dbc..f3a47098fb8e 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -546,15 +546,6 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size) memblock_add(base, size); } -#ifdef CONFIG_BLK_DEV_INITRD -void __init early_init_dt_setup_initrd_arch(u64 start, u64 end) -{ - initrd_start = (unsigned long)__va(start); - initrd_end = (unsigned long)__va(end); - initrd_below_start_ok = 1; -} -#endif - static void __init early_reserve_mem_dt(void) { unsigned long i, len, dt_root; @@ -761,37 +752,6 @@ void __init early_init_devtree(void *params) *******/ /** - * of_find_next_cache_node - Find a node's subsidiary cache - * @np: node of type "cpu" or "cache" - * - * Returns a node pointer with refcount incremented, use - * of_node_put() on it when done. Caller should hold a reference - * to np. - */ -struct device_node *of_find_next_cache_node(struct device_node *np) -{ - struct device_node *child; - const phandle *handle; - - handle = of_get_property(np, "l2-cache", NULL); - if (!handle) - handle = of_get_property(np, "next-level-cache", NULL); - - if (handle) - return of_find_node_by_phandle(*handle); - - /* OF on pmac has nodes instead of properties named "l2-cache" - * beneath CPU nodes. - */ - if (!strcmp(np->type, "cpu")) - for_each_child_of_node(np, child) - if (!strcmp(child->type, "cache")) - return child; - - return NULL; -} - -/** * of_get_ibm_chip_id - Returns the IBM "chip-id" of a device * @np: device node of the device * diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 5fe2842e8bab..cb64a6e1dc51 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -858,7 +858,8 @@ static void __init prom_send_capabilities(void) { ihandle root; prom_arg_t ret; - __be32 *cores; + u32 cores; + unsigned char *ptcores; root = call_prom("open", 1, 1, ADDR("/")); if (root != 0) { @@ -868,15 +869,30 @@ static void __init prom_send_capabilities(void) * (we assume this is the same for all cores) and use it to * divide NR_CPUS. */ - cores = (__be32 *)&ibm_architecture_vec[IBM_ARCH_VEC_NRCORES_OFFSET]; - if (be32_to_cpup(cores) != NR_CPUS) { + + /* The core value may start at an odd address. If such a word + * access is made at a cache line boundary, this leads to an + * exception which may not be handled at this time. + * Forcing a per byte access to avoid exception. + */ + ptcores = &ibm_architecture_vec[IBM_ARCH_VEC_NRCORES_OFFSET]; + cores = 0; + cores |= ptcores[0] << 24; + cores |= ptcores[1] << 16; + cores |= ptcores[2] << 8; + cores |= ptcores[3]; + if (cores != NR_CPUS) { prom_printf("WARNING ! " "ibm_architecture_vec structure inconsistent: %lu!\n", - be32_to_cpup(cores)); + cores); } else { - *cores = cpu_to_be32(DIV_ROUND_UP(NR_CPUS, prom_count_smt_threads())); + cores = DIV_ROUND_UP(NR_CPUS, prom_count_smt_threads()); prom_printf("Max number of cores passed to firmware: %lu (NR_CPUS = %lu)\n", - be32_to_cpup(cores), NR_CPUS); + cores, NR_CPUS); + ptcores[0] = (cores >> 24) & 0xff; + ptcores[1] = (cores >> 16) & 0xff; + ptcores[2] = (cores >> 8) & 0xff; + ptcores[3] = cores & 0xff; } /* try calling the ibm,client-architecture-support method */ diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index 9a0d24c390a3..75fb40498b41 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c @@ -362,7 +362,7 @@ static int fpr_get(struct task_struct *target, const struct user_regset *regset, void *kbuf, void __user *ubuf) { #ifdef CONFIG_VSX - double buf[33]; + u64 buf[33]; int i; #endif flush_fp_to_thread(target); @@ -371,15 +371,15 @@ static int fpr_get(struct task_struct *target, const struct user_regset *regset, /* copy to local buffer then write that out */ for (i = 0; i < 32 ; i++) buf[i] = target->thread.TS_FPR(i); - memcpy(&buf[32], &target->thread.fpscr, sizeof(double)); + buf[32] = target->thread.fp_state.fpscr; return user_regset_copyout(&pos, &count, &kbuf, &ubuf, buf, 0, -1); #else - BUILD_BUG_ON(offsetof(struct thread_struct, fpscr) != - offsetof(struct thread_struct, TS_FPR(32))); + BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) != + offsetof(struct thread_fp_state, fpr[32][0])); return user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.fpr, 0, -1); + &target->thread.fp_state, 0, -1); #endif } @@ -388,7 +388,7 @@ static int fpr_set(struct task_struct *target, const struct user_regset *regset, const void *kbuf, const void __user *ubuf) { #ifdef CONFIG_VSX - double buf[33]; + u64 buf[33]; int i; #endif flush_fp_to_thread(target); @@ -400,14 +400,14 @@ static int fpr_set(struct task_struct *target, const struct user_regset *regset, return i; for (i = 0; i < 32 ; i++) target->thread.TS_FPR(i) = buf[i]; - memcpy(&target->thread.fpscr, &buf[32], sizeof(double)); + target->thread.fp_state.fpscr = buf[32]; return 0; #else - BUILD_BUG_ON(offsetof(struct thread_struct, fpscr) != - offsetof(struct thread_struct, TS_FPR(32))); + BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) != + offsetof(struct thread_fp_state, fpr[32][0])); return user_regset_copyin(&pos, &count, &kbuf, &ubuf, - &target->thread.fpr, 0, -1); + &target->thread.fp_state, 0, -1); #endif } @@ -440,11 +440,11 @@ static int vr_get(struct task_struct *target, const struct user_regset *regset, flush_altivec_to_thread(target); - BUILD_BUG_ON(offsetof(struct thread_struct, vscr) != - offsetof(struct thread_struct, vr[32])); + BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) != + offsetof(struct thread_vr_state, vr[32])); ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.vr, 0, + &target->thread.vr_state, 0, 33 * sizeof(vector128)); if (!ret) { /* @@ -471,11 +471,12 @@ static int vr_set(struct task_struct *target, const struct user_regset *regset, flush_altivec_to_thread(target); - BUILD_BUG_ON(offsetof(struct thread_struct, vscr) != - offsetof(struct thread_struct, vr[32])); + BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) != + offsetof(struct thread_vr_state, vr[32])); ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, - &target->thread.vr, 0, 33 * sizeof(vector128)); + &target->thread.vr_state, 0, + 33 * sizeof(vector128)); if (!ret && count > 0) { /* * We use only the first word of vrsave. @@ -514,13 +515,13 @@ static int vsr_get(struct task_struct *target, const struct user_regset *regset, unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) { - double buf[32]; + u64 buf[32]; int ret, i; flush_vsx_to_thread(target); for (i = 0; i < 32 ; i++) - buf[i] = target->thread.fpr[i][TS_VSRLOWOFFSET]; + buf[i] = target->thread.fp_state.fpr[i][TS_VSRLOWOFFSET]; ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, buf, 0, 32 * sizeof(double)); @@ -531,7 +532,7 @@ static int vsr_set(struct task_struct *target, const struct user_regset *regset, unsigned int pos, unsigned int count, const void *kbuf, const void __user *ubuf) { - double buf[32]; + u64 buf[32]; int ret,i; flush_vsx_to_thread(target); @@ -539,7 +540,7 @@ static int vsr_set(struct task_struct *target, const struct user_regset *regset, ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, buf, 0, 32 * sizeof(double)); for (i = 0; i < 32 ; i++) - target->thread.fpr[i][TS_VSRLOWOFFSET] = buf[i]; + target->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i]; return ret; @@ -657,7 +658,7 @@ static const struct user_regset native_regsets[] = { #endif #ifdef CONFIG_SPE [REGSET_SPE] = { - .n = 35, + .core_note_type = NT_PPC_SPE, .n = 35, .size = sizeof(u32), .align = sizeof(u32), .active = evr_active, .get = evr_get, .set = evr_set }, @@ -854,8 +855,8 @@ void user_enable_single_step(struct task_struct *task) if (regs != NULL) { #ifdef CONFIG_PPC_ADV_DEBUG_REGS - task->thread.dbcr0 &= ~DBCR0_BT; - task->thread.dbcr0 |= DBCR0_IDM | DBCR0_IC; + task->thread.debug.dbcr0 &= ~DBCR0_BT; + task->thread.debug.dbcr0 |= DBCR0_IDM | DBCR0_IC; regs->msr |= MSR_DE; #else regs->msr &= ~MSR_BE; @@ -871,8 +872,8 @@ void user_enable_block_step(struct task_struct *task) if (regs != NULL) { #ifdef CONFIG_PPC_ADV_DEBUG_REGS - task->thread.dbcr0 &= ~DBCR0_IC; - task->thread.dbcr0 = DBCR0_IDM | DBCR0_BT; + task->thread.debug.dbcr0 &= ~DBCR0_IC; + task->thread.debug.dbcr0 = DBCR0_IDM | DBCR0_BT; regs->msr |= MSR_DE; #else regs->msr &= ~MSR_SE; @@ -894,16 +895,16 @@ void user_disable_single_step(struct task_struct *task) * And, after doing so, if all debug flags are off, turn * off DBCR0(IDM) and MSR(DE) .... Torez */ - task->thread.dbcr0 &= ~DBCR0_IC; + task->thread.debug.dbcr0 &= ~(DBCR0_IC|DBCR0_BT); /* * Test to see if any of the DBCR_ACTIVE_EVENTS bits are set. */ - if (!DBCR_ACTIVE_EVENTS(task->thread.dbcr0, - task->thread.dbcr1)) { + if (!DBCR_ACTIVE_EVENTS(task->thread.debug.dbcr0, + task->thread.debug.dbcr1)) { /* * All debug events were off..... */ - task->thread.dbcr0 &= ~DBCR0_IDM; + task->thread.debug.dbcr0 &= ~DBCR0_IDM; regs->msr &= ~MSR_DE; } #else @@ -1022,14 +1023,14 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, */ /* DAC's hold the whole address without any mode flags */ - task->thread.dac1 = data & ~0x3UL; + task->thread.debug.dac1 = data & ~0x3UL; - if (task->thread.dac1 == 0) { + if (task->thread.debug.dac1 == 0) { dbcr_dac(task) &= ~(DBCR_DAC1R | DBCR_DAC1W); - if (!DBCR_ACTIVE_EVENTS(task->thread.dbcr0, - task->thread.dbcr1)) { + if (!DBCR_ACTIVE_EVENTS(task->thread.debug.dbcr0, + task->thread.debug.dbcr1)) { task->thread.regs->msr &= ~MSR_DE; - task->thread.dbcr0 &= ~DBCR0_IDM; + task->thread.debug.dbcr0 &= ~DBCR0_IDM; } return 0; } @@ -1041,7 +1042,7 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, /* Set the Internal Debugging flag (IDM bit 1) for the DBCR0 register */ - task->thread.dbcr0 |= DBCR0_IDM; + task->thread.debug.dbcr0 |= DBCR0_IDM; /* Check for write and read flags and set DBCR0 accordingly */ @@ -1071,10 +1072,10 @@ static long set_instruction_bp(struct task_struct *child, struct ppc_hw_breakpoint *bp_info) { int slot; - int slot1_in_use = ((child->thread.dbcr0 & DBCR0_IAC1) != 0); - int slot2_in_use = ((child->thread.dbcr0 & DBCR0_IAC2) != 0); - int slot3_in_use = ((child->thread.dbcr0 & DBCR0_IAC3) != 0); - int slot4_in_use = ((child->thread.dbcr0 & DBCR0_IAC4) != 0); + int slot1_in_use = ((child->thread.debug.dbcr0 & DBCR0_IAC1) != 0); + int slot2_in_use = ((child->thread.debug.dbcr0 & DBCR0_IAC2) != 0); + int slot3_in_use = ((child->thread.debug.dbcr0 & DBCR0_IAC3) != 0); + int slot4_in_use = ((child->thread.debug.dbcr0 & DBCR0_IAC4) != 0); if (dbcr_iac_range(child) & DBCR_IAC12MODE) slot2_in_use = 1; @@ -1093,9 +1094,9 @@ static long set_instruction_bp(struct task_struct *child, /* We need a pair of IAC regsisters */ if ((!slot1_in_use) && (!slot2_in_use)) { slot = 1; - child->thread.iac1 = bp_info->addr; - child->thread.iac2 = bp_info->addr2; - child->thread.dbcr0 |= DBCR0_IAC1; + child->thread.debug.iac1 = bp_info->addr; + child->thread.debug.iac2 = bp_info->addr2; + child->thread.debug.dbcr0 |= DBCR0_IAC1; if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE) dbcr_iac_range(child) |= DBCR_IAC12X; @@ -1104,9 +1105,9 @@ static long set_instruction_bp(struct task_struct *child, #if CONFIG_PPC_ADV_DEBUG_IACS > 2 } else if ((!slot3_in_use) && (!slot4_in_use)) { slot = 3; - child->thread.iac3 = bp_info->addr; - child->thread.iac4 = bp_info->addr2; - child->thread.dbcr0 |= DBCR0_IAC3; + child->thread.debug.iac3 = bp_info->addr; + child->thread.debug.iac4 = bp_info->addr2; + child->thread.debug.dbcr0 |= DBCR0_IAC3; if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE) dbcr_iac_range(child) |= DBCR_IAC34X; @@ -1126,30 +1127,30 @@ static long set_instruction_bp(struct task_struct *child, */ if (slot2_in_use || (slot3_in_use == slot4_in_use)) { slot = 1; - child->thread.iac1 = bp_info->addr; - child->thread.dbcr0 |= DBCR0_IAC1; + child->thread.debug.iac1 = bp_info->addr; + child->thread.debug.dbcr0 |= DBCR0_IAC1; goto out; } } if (!slot2_in_use) { slot = 2; - child->thread.iac2 = bp_info->addr; - child->thread.dbcr0 |= DBCR0_IAC2; + child->thread.debug.iac2 = bp_info->addr; + child->thread.debug.dbcr0 |= DBCR0_IAC2; #if CONFIG_PPC_ADV_DEBUG_IACS > 2 } else if (!slot3_in_use) { slot = 3; - child->thread.iac3 = bp_info->addr; - child->thread.dbcr0 |= DBCR0_IAC3; + child->thread.debug.iac3 = bp_info->addr; + child->thread.debug.dbcr0 |= DBCR0_IAC3; } else if (!slot4_in_use) { slot = 4; - child->thread.iac4 = bp_info->addr; - child->thread.dbcr0 |= DBCR0_IAC4; + child->thread.debug.iac4 = bp_info->addr; + child->thread.debug.dbcr0 |= DBCR0_IAC4; #endif } else return -ENOSPC; } out: - child->thread.dbcr0 |= DBCR0_IDM; + child->thread.debug.dbcr0 |= DBCR0_IDM; child->thread.regs->msr |= MSR_DE; return slot; @@ -1159,49 +1160,49 @@ static int del_instruction_bp(struct task_struct *child, int slot) { switch (slot) { case 1: - if ((child->thread.dbcr0 & DBCR0_IAC1) == 0) + if ((child->thread.debug.dbcr0 & DBCR0_IAC1) == 0) return -ENOENT; if (dbcr_iac_range(child) & DBCR_IAC12MODE) { /* address range - clear slots 1 & 2 */ - child->thread.iac2 = 0; + child->thread.debug.iac2 = 0; dbcr_iac_range(child) &= ~DBCR_IAC12MODE; } - child->thread.iac1 = 0; - child->thread.dbcr0 &= ~DBCR0_IAC1; + child->thread.debug.iac1 = 0; + child->thread.debug.dbcr0 &= ~DBCR0_IAC1; break; case 2: - if ((child->thread.dbcr0 & DBCR0_IAC2) == 0) + if ((child->thread.debug.dbcr0 & DBCR0_IAC2) == 0) return -ENOENT; if (dbcr_iac_range(child) & DBCR_IAC12MODE) /* used in a range */ return -EINVAL; - child->thread.iac2 = 0; - child->thread.dbcr0 &= ~DBCR0_IAC2; + child->thread.debug.iac2 = 0; + child->thread.debug.dbcr0 &= ~DBCR0_IAC2; break; #if CONFIG_PPC_ADV_DEBUG_IACS > 2 case 3: - if ((child->thread.dbcr0 & DBCR0_IAC3) == 0) + if ((child->thread.debug.dbcr0 & DBCR0_IAC3) == 0) return -ENOENT; if (dbcr_iac_range(child) & DBCR_IAC34MODE) { /* address range - clear slots 3 & 4 */ - child->thread.iac4 = 0; + child->thread.debug.iac4 = 0; dbcr_iac_range(child) &= ~DBCR_IAC34MODE; } - child->thread.iac3 = 0; - child->thread.dbcr0 &= ~DBCR0_IAC3; + child->thread.debug.iac3 = 0; + child->thread.debug.dbcr0 &= ~DBCR0_IAC3; break; case 4: - if ((child->thread.dbcr0 & DBCR0_IAC4) == 0) + if ((child->thread.debug.dbcr0 & DBCR0_IAC4) == 0) return -ENOENT; if (dbcr_iac_range(child) & DBCR_IAC34MODE) /* Used in a range */ return -EINVAL; - child->thread.iac4 = 0; - child->thread.dbcr0 &= ~DBCR0_IAC4; + child->thread.debug.iac4 = 0; + child->thread.debug.dbcr0 &= ~DBCR0_IAC4; break; #endif default: @@ -1231,18 +1232,18 @@ static int set_dac(struct task_struct *child, struct ppc_hw_breakpoint *bp_info) dbcr_dac(child) |= DBCR_DAC1R; if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE) dbcr_dac(child) |= DBCR_DAC1W; - child->thread.dac1 = (unsigned long)bp_info->addr; + child->thread.debug.dac1 = (unsigned long)bp_info->addr; #if CONFIG_PPC_ADV_DEBUG_DVCS > 0 if (byte_enable) { - child->thread.dvc1 = + child->thread.debug.dvc1 = (unsigned long)bp_info->condition_value; - child->thread.dbcr2 |= + child->thread.debug.dbcr2 |= ((byte_enable << DBCR2_DVC1BE_SHIFT) | (condition_mode << DBCR2_DVC1M_SHIFT)); } #endif #ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE - } else if (child->thread.dbcr2 & DBCR2_DAC12MODE) { + } else if (child->thread.debug.dbcr2 & DBCR2_DAC12MODE) { /* Both dac1 and dac2 are part of a range */ return -ENOSPC; #endif @@ -1252,19 +1253,19 @@ static int set_dac(struct task_struct *child, struct ppc_hw_breakpoint *bp_info) dbcr_dac(child) |= DBCR_DAC2R; if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE) dbcr_dac(child) |= DBCR_DAC2W; - child->thread.dac2 = (unsigned long)bp_info->addr; + child->thread.debug.dac2 = (unsigned long)bp_info->addr; #if CONFIG_PPC_ADV_DEBUG_DVCS > 0 if (byte_enable) { - child->thread.dvc2 = + child->thread.debug.dvc2 = (unsigned long)bp_info->condition_value; - child->thread.dbcr2 |= + child->thread.debug.dbcr2 |= ((byte_enable << DBCR2_DVC2BE_SHIFT) | (condition_mode << DBCR2_DVC2M_SHIFT)); } #endif } else return -ENOSPC; - child->thread.dbcr0 |= DBCR0_IDM; + child->thread.debug.dbcr0 |= DBCR0_IDM; child->thread.regs->msr |= MSR_DE; return slot + 4; @@ -1276,32 +1277,32 @@ static int del_dac(struct task_struct *child, int slot) if ((dbcr_dac(child) & (DBCR_DAC1R | DBCR_DAC1W)) == 0) return -ENOENT; - child->thread.dac1 = 0; + child->thread.debug.dac1 = 0; dbcr_dac(child) &= ~(DBCR_DAC1R | DBCR_DAC1W); #ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE - if (child->thread.dbcr2 & DBCR2_DAC12MODE) { - child->thread.dac2 = 0; - child->thread.dbcr2 &= ~DBCR2_DAC12MODE; + if (child->thread.debug.dbcr2 & DBCR2_DAC12MODE) { + child->thread.debug.dac2 = 0; + child->thread.debug.dbcr2 &= ~DBCR2_DAC12MODE; } - child->thread.dbcr2 &= ~(DBCR2_DVC1M | DBCR2_DVC1BE); + child->thread.debug.dbcr2 &= ~(DBCR2_DVC1M | DBCR2_DVC1BE); #endif #if CONFIG_PPC_ADV_DEBUG_DVCS > 0 - child->thread.dvc1 = 0; + child->thread.debug.dvc1 = 0; #endif } else if (slot == 2) { if ((dbcr_dac(child) & (DBCR_DAC2R | DBCR_DAC2W)) == 0) return -ENOENT; #ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE - if (child->thread.dbcr2 & DBCR2_DAC12MODE) + if (child->thread.debug.dbcr2 & DBCR2_DAC12MODE) /* Part of a range */ return -EINVAL; - child->thread.dbcr2 &= ~(DBCR2_DVC2M | DBCR2_DVC2BE); + child->thread.debug.dbcr2 &= ~(DBCR2_DVC2M | DBCR2_DVC2BE); #endif #if CONFIG_PPC_ADV_DEBUG_DVCS > 0 - child->thread.dvc2 = 0; + child->thread.debug.dvc2 = 0; #endif - child->thread.dac2 = 0; + child->thread.debug.dac2 = 0; dbcr_dac(child) &= ~(DBCR_DAC2R | DBCR_DAC2W); } else return -EINVAL; @@ -1343,22 +1344,22 @@ static int set_dac_range(struct task_struct *child, return -EIO; } - if (child->thread.dbcr0 & + if (child->thread.debug.dbcr0 & (DBCR0_DAC1R | DBCR0_DAC1W | DBCR0_DAC2R | DBCR0_DAC2W)) return -ENOSPC; if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ) - child->thread.dbcr0 |= (DBCR0_DAC1R | DBCR0_IDM); + child->thread.debug.dbcr0 |= (DBCR0_DAC1R | DBCR0_IDM); if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE) - child->thread.dbcr0 |= (DBCR0_DAC1W | DBCR0_IDM); - child->thread.dac1 = bp_info->addr; - child->thread.dac2 = bp_info->addr2; + child->thread.debug.dbcr0 |= (DBCR0_DAC1W | DBCR0_IDM); + child->thread.debug.dac1 = bp_info->addr; + child->thread.debug.dac2 = bp_info->addr2; if (mode == PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE) - child->thread.dbcr2 |= DBCR2_DAC12M; + child->thread.debug.dbcr2 |= DBCR2_DAC12M; else if (mode == PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE) - child->thread.dbcr2 |= DBCR2_DAC12MX; + child->thread.debug.dbcr2 |= DBCR2_DAC12MX; else /* PPC_BREAKPOINT_MODE_MASK */ - child->thread.dbcr2 |= DBCR2_DAC12MM; + child->thread.debug.dbcr2 |= DBCR2_DAC12MM; child->thread.regs->msr |= MSR_DE; return 5; @@ -1489,9 +1490,9 @@ static long ppc_del_hwdebug(struct task_struct *child, long data) rc = del_dac(child, (int)data - 4); if (!rc) { - if (!DBCR_ACTIVE_EVENTS(child->thread.dbcr0, - child->thread.dbcr1)) { - child->thread.dbcr0 &= ~DBCR0_IDM; + if (!DBCR_ACTIVE_EVENTS(child->thread.debug.dbcr0, + child->thread.debug.dbcr1)) { + child->thread.debug.dbcr0 &= ~DBCR0_IDM; child->thread.regs->msr &= ~MSR_DE; } } @@ -1554,10 +1555,10 @@ long arch_ptrace(struct task_struct *child, long request, flush_fp_to_thread(child); if (fpidx < (PT_FPSCR - PT_FPR0)) - tmp = ((unsigned long *)child->thread.fpr) - [fpidx * TS_FPRWIDTH]; + memcpy(&tmp, &child->thread.fp_state.fpr, + sizeof(long)); else - tmp = child->thread.fpscr.val; + tmp = child->thread.fp_state.fpscr; } ret = put_user(tmp, datalp); break; @@ -1587,10 +1588,10 @@ long arch_ptrace(struct task_struct *child, long request, flush_fp_to_thread(child); if (fpidx < (PT_FPSCR - PT_FPR0)) - ((unsigned long *)child->thread.fpr) - [fpidx * TS_FPRWIDTH] = data; + memcpy(&child->thread.fp_state.fpr, &data, + sizeof(long)); else - child->thread.fpscr.val = data; + child->thread.fp_state.fpscr = data; ret = 0; } break; @@ -1669,7 +1670,7 @@ long arch_ptrace(struct task_struct *child, long request, if (addr > 0) break; #ifdef CONFIG_PPC_ADV_DEBUG_REGS - ret = put_user(child->thread.dac1, datalp); + ret = put_user(child->thread.debug.dac1, datalp); #else dabr_fake = ((child->thread.hw_brk.address & (~HW_BRK_TYPE_DABR)) | (child->thread.hw_brk.type & HW_BRK_TYPE_DABR)); diff --git a/arch/powerpc/kernel/ptrace32.c b/arch/powerpc/kernel/ptrace32.c index f51599e941c7..f52b7db327c8 100644 --- a/arch/powerpc/kernel/ptrace32.c +++ b/arch/powerpc/kernel/ptrace32.c @@ -43,7 +43,6 @@ #define FPRNUMBER(i) (((i) - PT_FPR0) >> 1) #define FPRHALF(i) (((i) - PT_FPR0) & 1) #define FPRINDEX(i) TS_FPRWIDTH * FPRNUMBER(i) * 2 + FPRHALF(i) -#define FPRINDEX_3264(i) (TS_FPRWIDTH * ((i) - PT_FPR0)) long compat_arch_ptrace(struct task_struct *child, compat_long_t request, compat_ulong_t caddr, compat_ulong_t cdata) @@ -105,7 +104,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, * to be an array of unsigned int (32 bits) - the * index passed in is based on this assumption. */ - tmp = ((unsigned int *)child->thread.fpr) + tmp = ((unsigned int *)child->thread.fp_state.fpr) [FPRINDEX(index)]; } ret = put_user((unsigned int)tmp, (u32 __user *)data); @@ -147,8 +146,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, if (numReg >= PT_FPR0) { flush_fp_to_thread(child); /* get 64 bit FPR */ - tmp = ((u64 *)child->thread.fpr) - [FPRINDEX_3264(numReg)]; + tmp = child->thread.fp_state.fpr[numReg - PT_FPR0][0]; } else { /* register within PT_REGS struct */ unsigned long tmp2; ret = ptrace_get_reg(child, numReg, &tmp2); @@ -207,7 +205,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, * to be an array of unsigned int (32 bits) - the * index passed in is based on this assumption. */ - ((unsigned int *)child->thread.fpr) + ((unsigned int *)child->thread.fp_state.fpr) [FPRINDEX(index)] = data; ret = 0; } @@ -251,8 +249,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, u64 *tmp; flush_fp_to_thread(child); /* get 64 bit FPR ... */ - tmp = &(((u64 *)child->thread.fpr) - [FPRINDEX_3264(numReg)]); + tmp = &child->thread.fp_state.fpr[numReg - PT_FPR0][0]; /* ... write the 32 bit part we want */ ((u32 *)tmp)[index % 2] = data; ret = 0; @@ -269,7 +266,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, if (addr > 0) break; #ifdef CONFIG_PPC_ADV_DEBUG_REGS - ret = put_user(child->thread.dac1, (u32 __user *)data); + ret = put_user(child->thread.debug.dac1, (u32 __user *)data); #else dabr_fake = ( (child->thread.hw_brk.address & (~HW_BRK_TYPE_DABR)) | diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c index 6e7b7cdeec65..7d4c7172f38e 100644 --- a/arch/powerpc/kernel/rtas_pci.c +++ b/arch/powerpc/kernel/rtas_pci.c @@ -223,7 +223,7 @@ unsigned long get_phb_buid(struct device_node *phb) static int phb_set_bus_ranges(struct device_node *dev, struct pci_controller *phb) { - const int *bus_range; + const __be32 *bus_range; unsigned int len; bus_range = of_get_property(dev, "bus-range", &len); @@ -231,8 +231,8 @@ static int phb_set_bus_ranges(struct device_node *dev, return 1; } - phb->first_busno = bus_range[0]; - phb->last_busno = bus_range[1]; + phb->first_busno = be32_to_cpu(bus_range[0]); + phb->last_busno = be32_to_cpu(bus_range[1]); return 0; } diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index 3d261c071fc8..febc80445d25 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c @@ -62,8 +62,6 @@ #include <mm/mmu_decl.h> #include <asm/fadump.h> -#include "setup.h" - #ifdef DEBUG #include <asm/udbg.h> #define DBG(fmt...) udbg_printf(fmt) diff --git a/arch/powerpc/kernel/setup.h b/arch/powerpc/kernel/setup.h deleted file mode 100644 index 4c67ad7fae08..000000000000 --- a/arch/powerpc/kernel/setup.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef _POWERPC_KERNEL_SETUP_H -#define _POWERPC_KERNEL_SETUP_H - -void check_for_initrd(void); -void do_init_bootmem(void); -void setup_panic(void); -extern int do_early_xmon; - -#endif /* _POWERPC_KERNEL_SETUP_H */ diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index a4bbcae72578..b903dc5cf944 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -40,8 +40,6 @@ #include <asm/mmu_context.h> #include <asm/epapr_hcalls.h> -#include "setup.h" - #define DBG(fmt...) extern void bootx_init(unsigned long r4, unsigned long phys); diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 278ca93e1f28..4085aaa9478f 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -68,8 +68,6 @@ #include <asm/hugetlb.h> #include <asm/epapr_hcalls.h> -#include "setup.h" - #ifdef DEBUG #define DBG(fmt...) udbg_printf(fmt) #else diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index bebdf1a1a540..749778e0a69d 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -265,27 +265,27 @@ struct rt_sigframe { unsigned long copy_fpr_to_user(void __user *to, struct task_struct *task) { - double buf[ELF_NFPREG]; + u64 buf[ELF_NFPREG]; int i; /* save FPR copy to local buffer then write to the thread_struct */ for (i = 0; i < (ELF_NFPREG - 1) ; i++) buf[i] = task->thread.TS_FPR(i); - memcpy(&buf[i], &task->thread.fpscr, sizeof(double)); + buf[i] = task->thread.fp_state.fpscr; return __copy_to_user(to, buf, ELF_NFPREG * sizeof(double)); } unsigned long copy_fpr_from_user(struct task_struct *task, void __user *from) { - double buf[ELF_NFPREG]; + u64 buf[ELF_NFPREG]; int i; if (__copy_from_user(buf, from, ELF_NFPREG * sizeof(double))) return 1; for (i = 0; i < (ELF_NFPREG - 1) ; i++) task->thread.TS_FPR(i) = buf[i]; - memcpy(&task->thread.fpscr, &buf[i], sizeof(double)); + task->thread.fp_state.fpscr = buf[i]; return 0; } @@ -293,25 +293,25 @@ unsigned long copy_fpr_from_user(struct task_struct *task, unsigned long copy_vsx_to_user(void __user *to, struct task_struct *task) { - double buf[ELF_NVSRHALFREG]; + u64 buf[ELF_NVSRHALFREG]; int i; /* save FPR copy to local buffer then write to the thread_struct */ for (i = 0; i < ELF_NVSRHALFREG; i++) - buf[i] = task->thread.fpr[i][TS_VSRLOWOFFSET]; + buf[i] = task->thread.fp_state.fpr[i][TS_VSRLOWOFFSET]; return __copy_to_user(to, buf, ELF_NVSRHALFREG * sizeof(double)); } unsigned long copy_vsx_from_user(struct task_struct *task, void __user *from) { - double buf[ELF_NVSRHALFREG]; + u64 buf[ELF_NVSRHALFREG]; int i; if (__copy_from_user(buf, from, ELF_NVSRHALFREG * sizeof(double))) return 1; for (i = 0; i < ELF_NVSRHALFREG ; i++) - task->thread.fpr[i][TS_VSRLOWOFFSET] = buf[i]; + task->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i]; return 0; } @@ -319,27 +319,27 @@ unsigned long copy_vsx_from_user(struct task_struct *task, unsigned long copy_transact_fpr_to_user(void __user *to, struct task_struct *task) { - double buf[ELF_NFPREG]; + u64 buf[ELF_NFPREG]; int i; /* save FPR copy to local buffer then write to the thread_struct */ for (i = 0; i < (ELF_NFPREG - 1) ; i++) buf[i] = task->thread.TS_TRANS_FPR(i); - memcpy(&buf[i], &task->thread.transact_fpscr, sizeof(double)); + buf[i] = task->thread.transact_fp.fpscr; return __copy_to_user(to, buf, ELF_NFPREG * sizeof(double)); } unsigned long copy_transact_fpr_from_user(struct task_struct *task, void __user *from) { - double buf[ELF_NFPREG]; + u64 buf[ELF_NFPREG]; int i; if (__copy_from_user(buf, from, ELF_NFPREG * sizeof(double))) return 1; for (i = 0; i < (ELF_NFPREG - 1) ; i++) task->thread.TS_TRANS_FPR(i) = buf[i]; - memcpy(&task->thread.transact_fpscr, &buf[i], sizeof(double)); + task->thread.transact_fp.fpscr = buf[i]; return 0; } @@ -347,25 +347,25 @@ unsigned long copy_transact_fpr_from_user(struct task_struct *task, unsigned long copy_transact_vsx_to_user(void __user *to, struct task_struct *task) { - double buf[ELF_NVSRHALFREG]; + u64 buf[ELF_NVSRHALFREG]; int i; /* save FPR copy to local buffer then write to the thread_struct */ for (i = 0; i < ELF_NVSRHALFREG; i++) - buf[i] = task->thread.transact_fpr[i][TS_VSRLOWOFFSET]; + buf[i] = task->thread.transact_fp.fpr[i][TS_VSRLOWOFFSET]; return __copy_to_user(to, buf, ELF_NVSRHALFREG * sizeof(double)); } unsigned long copy_transact_vsx_from_user(struct task_struct *task, void __user *from) { - double buf[ELF_NVSRHALFREG]; + u64 buf[ELF_NVSRHALFREG]; int i; if (__copy_from_user(buf, from, ELF_NVSRHALFREG * sizeof(double))) return 1; for (i = 0; i < ELF_NVSRHALFREG ; i++) - task->thread.transact_fpr[i][TS_VSRLOWOFFSET] = buf[i]; + task->thread.transact_fp.fpr[i][TS_VSRLOWOFFSET] = buf[i]; return 0; } #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ @@ -373,14 +373,14 @@ unsigned long copy_transact_vsx_from_user(struct task_struct *task, inline unsigned long copy_fpr_to_user(void __user *to, struct task_struct *task) { - return __copy_to_user(to, task->thread.fpr, + return __copy_to_user(to, task->thread.fp_state.fpr, ELF_NFPREG * sizeof(double)); } inline unsigned long copy_fpr_from_user(struct task_struct *task, void __user *from) { - return __copy_from_user(task->thread.fpr, from, + return __copy_from_user(task->thread.fp_state.fpr, from, ELF_NFPREG * sizeof(double)); } @@ -388,14 +388,14 @@ inline unsigned long copy_fpr_from_user(struct task_struct *task, inline unsigned long copy_transact_fpr_to_user(void __user *to, struct task_struct *task) { - return __copy_to_user(to, task->thread.transact_fpr, + return __copy_to_user(to, task->thread.transact_fp.fpr, ELF_NFPREG * sizeof(double)); } inline unsigned long copy_transact_fpr_from_user(struct task_struct *task, void __user *from) { - return __copy_from_user(task->thread.transact_fpr, from, + return __copy_from_user(task->thread.transact_fp.fpr, from, ELF_NFPREG * sizeof(double)); } #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ @@ -423,7 +423,7 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, /* save altivec registers */ if (current->thread.used_vr) { flush_altivec_to_thread(current); - if (__copy_to_user(&frame->mc_vregs, current->thread.vr, + if (__copy_to_user(&frame->mc_vregs, ¤t->thread.vr_state, ELF_NVRREG * sizeof(vector128))) return 1; /* set MSR_VEC in the saved MSR value to indicate that @@ -534,17 +534,17 @@ static int save_tm_user_regs(struct pt_regs *regs, /* save altivec registers */ if (current->thread.used_vr) { flush_altivec_to_thread(current); - if (__copy_to_user(&frame->mc_vregs, current->thread.vr, + if (__copy_to_user(&frame->mc_vregs, ¤t->thread.vr_state, ELF_NVRREG * sizeof(vector128))) return 1; if (msr & MSR_VEC) { if (__copy_to_user(&tm_frame->mc_vregs, - current->thread.transact_vr, + ¤t->thread.transact_vr, ELF_NVRREG * sizeof(vector128))) return 1; } else { if (__copy_to_user(&tm_frame->mc_vregs, - current->thread.vr, + ¤t->thread.vr_state, ELF_NVRREG * sizeof(vector128))) return 1; } @@ -692,11 +692,12 @@ static long restore_user_regs(struct pt_regs *regs, regs->msr &= ~MSR_VEC; if (msr & MSR_VEC) { /* restore altivec registers from the stack */ - if (__copy_from_user(current->thread.vr, &sr->mc_vregs, + if (__copy_from_user(¤t->thread.vr_state, &sr->mc_vregs, sizeof(sr->mc_vregs))) return 1; } else if (current->thread.used_vr) - memset(current->thread.vr, 0, ELF_NVRREG * sizeof(vector128)); + memset(¤t->thread.vr_state, 0, + ELF_NVRREG * sizeof(vector128)); /* Always get VRSAVE back */ if (__get_user(current->thread.vrsave, (u32 __user *)&sr->mc_vregs[32])) @@ -722,7 +723,7 @@ static long restore_user_regs(struct pt_regs *regs, return 1; } else if (current->thread.used_vsr) for (i = 0; i < 32 ; i++) - current->thread.fpr[i][TS_VSRLOWOFFSET] = 0; + current->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = 0; #endif /* CONFIG_VSX */ /* * force the process to reload the FP registers from @@ -798,15 +799,16 @@ static long restore_tm_user_regs(struct pt_regs *regs, regs->msr &= ~MSR_VEC; if (msr & MSR_VEC) { /* restore altivec registers from the stack */ - if (__copy_from_user(current->thread.vr, &sr->mc_vregs, + if (__copy_from_user(¤t->thread.vr_state, &sr->mc_vregs, sizeof(sr->mc_vregs)) || - __copy_from_user(current->thread.transact_vr, + __copy_from_user(¤t->thread.transact_vr, &tm_sr->mc_vregs, sizeof(sr->mc_vregs))) return 1; } else if (current->thread.used_vr) { - memset(current->thread.vr, 0, ELF_NVRREG * sizeof(vector128)); - memset(current->thread.transact_vr, 0, + memset(¤t->thread.vr_state, 0, + ELF_NVRREG * sizeof(vector128)); + memset(¤t->thread.transact_vr, 0, ELF_NVRREG * sizeof(vector128)); } @@ -838,8 +840,8 @@ static long restore_tm_user_regs(struct pt_regs *regs, return 1; } else if (current->thread.used_vsr) for (i = 0; i < 32 ; i++) { - current->thread.fpr[i][TS_VSRLOWOFFSET] = 0; - current->thread.transact_fpr[i][TS_VSRLOWOFFSET] = 0; + current->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = 0; + current->thread.transact_fp.fpr[i][TS_VSRLOWOFFSET] = 0; } #endif /* CONFIG_VSX */ @@ -891,7 +893,7 @@ static long restore_tm_user_regs(struct pt_regs *regs, #endif #ifdef CONFIG_PPC64 -int copy_siginfo_to_user32(struct compat_siginfo __user *d, siginfo_t *s) +int copy_siginfo_to_user32(struct compat_siginfo __user *d, const siginfo_t *s) { int err; @@ -1030,7 +1032,7 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka, if (__put_user(0, &rt_sf->uc.uc_link)) goto badframe; - current->thread.fpscr.val = 0; /* turn off all fp exceptions */ + current->thread.fp_state.fpscr = 0; /* turn off all fp exceptions */ /* create a stack frame for the caller of the handler */ newsp = ((unsigned long)rt_sf) - (__SIGNAL_FRAMESIZE + 16); @@ -1045,8 +1047,9 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka, regs->gpr[5] = (unsigned long) &rt_sf->uc; regs->gpr[6] = (unsigned long) rt_sf; regs->nip = (unsigned long) ka->sa.sa_handler; - /* enter the signal handler in big-endian mode */ + /* enter the signal handler in native-endian mode */ regs->msr &= ~MSR_LE; + regs->msr |= (MSR_KERNEL & MSR_LE); #ifdef CONFIG_PPC_TRANSACTIONAL_MEM /* Remove TM bits from thread's MSR. The MSR in the sigcontext * just indicates to userland that we were doing a transaction, but we @@ -1309,7 +1312,7 @@ int sys_debug_setcontext(struct ucontext __user *ctx, unsigned char tmp; unsigned long new_msr = regs->msr; #ifdef CONFIG_PPC_ADV_DEBUG_REGS - unsigned long new_dbcr0 = current->thread.dbcr0; + unsigned long new_dbcr0 = current->thread.debug.dbcr0; #endif for (i=0; i<ndbg; i++) { @@ -1324,7 +1327,7 @@ int sys_debug_setcontext(struct ucontext __user *ctx, } else { new_dbcr0 &= ~DBCR0_IC; if (!DBCR_ACTIVE_EVENTS(new_dbcr0, - current->thread.dbcr1)) { + current->thread.debug.dbcr1)) { new_msr &= ~MSR_DE; new_dbcr0 &= ~DBCR0_IDM; } @@ -1359,7 +1362,7 @@ int sys_debug_setcontext(struct ucontext __user *ctx, the user is really doing something wrong. */ regs->msr = new_msr; #ifdef CONFIG_PPC_ADV_DEBUG_REGS - current->thread.dbcr0 = new_dbcr0; + current->thread.debug.dbcr0 = new_dbcr0; #endif if (!access_ok(VERIFY_READ, ctx, sizeof(*ctx)) @@ -1462,7 +1465,7 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka, regs->link = tramp; - current->thread.fpscr.val = 0; /* turn off all fp exceptions */ + current->thread.fp_state.fpscr = 0; /* turn off all fp exceptions */ /* create a stack frame for the caller of the handler */ newsp = ((unsigned long)frame) - __SIGNAL_FRAMESIZE; diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index f93ec2835a13..b3c615764c9b 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -103,7 +103,8 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, if (current->thread.used_vr) { flush_altivec_to_thread(current); /* Copy 33 vec registers (vr0..31 and vscr) to the stack */ - err |= __copy_to_user(v_regs, current->thread.vr, 33 * sizeof(vector128)); + err |= __copy_to_user(v_regs, ¤t->thread.vr_state, + 33 * sizeof(vector128)); /* set MSR_VEC in the MSR value in the frame to indicate that sc->v_reg) * contains valid data. */ @@ -195,18 +196,18 @@ static long setup_tm_sigcontexts(struct sigcontext __user *sc, if (current->thread.used_vr) { flush_altivec_to_thread(current); /* Copy 33 vec registers (vr0..31 and vscr) to the stack */ - err |= __copy_to_user(v_regs, current->thread.vr, + err |= __copy_to_user(v_regs, ¤t->thread.vr_state, 33 * sizeof(vector128)); /* If VEC was enabled there are transactional VRs valid too, * else they're a copy of the checkpointed VRs. */ if (msr & MSR_VEC) err |= __copy_to_user(tm_v_regs, - current->thread.transact_vr, + ¤t->thread.transact_vr, 33 * sizeof(vector128)); else err |= __copy_to_user(tm_v_regs, - current->thread.vr, + ¤t->thread.vr_state, 33 * sizeof(vector128)); /* set MSR_VEC in the MSR value in the frame to indicate @@ -349,10 +350,10 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig, return -EFAULT; /* Copy 33 vec registers (vr0..31 and vscr) from the stack */ if (v_regs != NULL && (msr & MSR_VEC) != 0) - err |= __copy_from_user(current->thread.vr, v_regs, + err |= __copy_from_user(¤t->thread.vr_state, v_regs, 33 * sizeof(vector128)); else if (current->thread.used_vr) - memset(current->thread.vr, 0, 33 * sizeof(vector128)); + memset(¤t->thread.vr_state, 0, 33 * sizeof(vector128)); /* Always get VRSAVE back */ if (v_regs != NULL) err |= __get_user(current->thread.vrsave, (u32 __user *)&v_regs[33]); @@ -374,7 +375,7 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig, err |= copy_vsx_from_user(current, v_regs); else for (i = 0; i < 32 ; i++) - current->thread.fpr[i][TS_VSRLOWOFFSET] = 0; + current->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = 0; #endif return err; } @@ -468,14 +469,14 @@ static long restore_tm_sigcontexts(struct pt_regs *regs, return -EFAULT; /* Copy 33 vec registers (vr0..31 and vscr) from the stack */ if (v_regs != NULL && tm_v_regs != NULL && (msr & MSR_VEC) != 0) { - err |= __copy_from_user(current->thread.vr, v_regs, + err |= __copy_from_user(¤t->thread.vr_state, v_regs, 33 * sizeof(vector128)); - err |= __copy_from_user(current->thread.transact_vr, tm_v_regs, + err |= __copy_from_user(¤t->thread.transact_vr, tm_v_regs, 33 * sizeof(vector128)); } else if (current->thread.used_vr) { - memset(current->thread.vr, 0, 33 * sizeof(vector128)); - memset(current->thread.transact_vr, 0, 33 * sizeof(vector128)); + memset(¤t->thread.vr_state, 0, 33 * sizeof(vector128)); + memset(¤t->thread.transact_vr, 0, 33 * sizeof(vector128)); } /* Always get VRSAVE back */ if (v_regs != NULL && tm_v_regs != NULL) { @@ -507,8 +508,8 @@ static long restore_tm_sigcontexts(struct pt_regs *regs, err |= copy_transact_vsx_from_user(current, tm_v_regs); } else { for (i = 0; i < 32 ; i++) { - current->thread.fpr[i][TS_VSRLOWOFFSET] = 0; - current->thread.transact_fpr[i][TS_VSRLOWOFFSET] = 0; + current->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = 0; + current->thread.transact_fp.fpr[i][TS_VSRLOWOFFSET] = 0; } } #endif @@ -747,7 +748,7 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info, goto badframe; /* Make sure signal handler doesn't get spurious FP exceptions */ - current->thread.fpscr.val = 0; + current->thread.fp_state.fpscr = 0; #ifdef CONFIG_PPC_TRANSACTIONAL_MEM /* Remove TM bits from thread's MSR. The MSR in the sigcontext * just indicates to userland that we were doing a transaction, but we @@ -773,8 +774,9 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info, /* Set up "regs" so we "return" to the signal handler. */ err |= get_user(regs->nip, &funct_desc_ptr->entry); - /* enter the signal handler in big-endian mode */ + /* enter the signal handler in native-endian mode */ regs->msr &= ~MSR_LE; + regs->msr |= (MSR_KERNEL & MSR_LE); regs->gpr[1] = newsp; err |= get_user(regs->gpr[2], &funct_desc_ptr->toc); regs->gpr[3] = signr; diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 8e59abc237d7..930cd8af3503 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -844,18 +844,6 @@ void __cpu_die(unsigned int cpu) smp_ops->cpu_die(cpu); } -static DEFINE_MUTEX(powerpc_cpu_hotplug_driver_mutex); - -void cpu_hotplug_driver_lock() -{ - mutex_lock(&powerpc_cpu_hotplug_driver_mutex); -} - -void cpu_hotplug_driver_unlock() -{ - mutex_unlock(&powerpc_cpu_hotplug_driver_mutex); -} - void cpu_die(void) { if (ppc_md.cpu_die) diff --git a/arch/powerpc/kernel/swsusp_asm64.S b/arch/powerpc/kernel/swsusp_asm64.S index 22045984835f..988f38dced0f 100644 --- a/arch/powerpc/kernel/swsusp_asm64.S +++ b/arch/powerpc/kernel/swsusp_asm64.S @@ -114,7 +114,9 @@ _GLOBAL(swsusp_arch_suspend) SAVE_SPECIAL(MSR) SAVE_SPECIAL(XER) #ifdef CONFIG_PPC_BOOK3S_64 +BEGIN_FW_FTR_SECTION SAVE_SPECIAL(SDR1) +END_FW_FTR_SECTION_IFCLR(FW_FEATURE_LPAR) #else SAVE_SPR(TCR) @@ -231,7 +233,9 @@ nothing_to_copy: /* can't use RESTORE_SPECIAL(MSR) */ ld r0, SL_MSR(r11) mtmsrd r0, 0 +BEGIN_FW_FTR_SECTION RESTORE_SPECIAL(SDR1) +END_FW_FTR_SECTION_IFCLR(FW_FEATURE_LPAR) #else /* Restore SPRG1, be used to save paca */ ld r0, SL_SPRG1(r11) diff --git a/arch/powerpc/kernel/tm.S b/arch/powerpc/kernel/tm.S index cd809eaa8b5c..ef47bcbd4352 100644 --- a/arch/powerpc/kernel/tm.S +++ b/arch/powerpc/kernel/tm.S @@ -12,16 +12,15 @@ #include <asm/reg.h> #ifdef CONFIG_VSX -/* See fpu.S, this is very similar but to save/restore checkpointed FPRs/VSRs */ -#define __SAVE_32FPRS_VSRS_TRANSACT(n,c,base) \ +/* See fpu.S, this is borrowed from there */ +#define __SAVE_32FPRS_VSRS(n,c,base) \ BEGIN_FTR_SECTION \ b 2f; \ END_FTR_SECTION_IFSET(CPU_FTR_VSX); \ - SAVE_32FPRS_TRANSACT(n,base); \ + SAVE_32FPRS(n,base); \ b 3f; \ -2: SAVE_32VSRS_TRANSACT(n,c,base); \ +2: SAVE_32VSRS(n,c,base); \ 3: -/* ...and this is just plain borrowed from there. */ #define __REST_32FPRS_VSRS(n,c,base) \ BEGIN_FTR_SECTION \ b 2f; \ @@ -31,11 +30,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX); \ 2: REST_32VSRS(n,c,base); \ 3: #else -#define __SAVE_32FPRS_VSRS_TRANSACT(n,c,base) SAVE_32FPRS_TRANSACT(n, base) -#define __REST_32FPRS_VSRS(n,c,base) REST_32FPRS(n, base) +#define __SAVE_32FPRS_VSRS(n,c,base) SAVE_32FPRS(n, base) +#define __REST_32FPRS_VSRS(n,c,base) REST_32FPRS(n, base) #endif -#define SAVE_32FPRS_VSRS_TRANSACT(n,c,base) \ - __SAVE_32FPRS_VSRS_TRANSACT(n,__REG_##c,__REG_##base) +#define SAVE_32FPRS_VSRS(n,c,base) \ + __SAVE_32FPRS_VSRS(n,__REG_##c,__REG_##base) #define REST_32FPRS_VSRS(n,c,base) \ __REST_32FPRS_VSRS(n,__REG_##c,__REG_##base) @@ -107,7 +106,7 @@ DSCR_DEFAULT: _GLOBAL(tm_reclaim) mfcr r6 mflr r0 - std r6, 8(r1) + stw r6, 8(r1) std r0, 16(r1) std r2, 40(r1) stdu r1, -TM_FRAME_SIZE(r1) @@ -157,10 +156,11 @@ _GLOBAL(tm_reclaim) andis. r0, r4, MSR_VEC@h beq dont_backup_vec - SAVE_32VRS_TRANSACT(0, r6, r3) /* r6 scratch, r3 thread */ + addi r7, r3, THREAD_TRANSACT_VRSTATE + SAVE_32VRS(0, r6, r7) /* r6 scratch, r7 transact vr state */ mfvscr vr0 - li r6, THREAD_TRANSACT_VSCR - stvx vr0, r3, r6 + li r6, VRSTATE_VSCR + stvx vr0, r7, r6 dont_backup_vec: mfspr r0, SPRN_VRSAVE std r0, THREAD_TRANSACT_VRSAVE(r3) @@ -168,10 +168,11 @@ dont_backup_vec: andi. r0, r4, MSR_FP beq dont_backup_fp - SAVE_32FPRS_VSRS_TRANSACT(0, R6, R3) /* r6 scratch, r3 thread */ + addi r7, r3, THREAD_TRANSACT_FPSTATE + SAVE_32FPRS_VSRS(0, R6, R7) /* r6 scratch, r7 transact fp state */ mffs fr0 - stfd fr0,THREAD_TRANSACT_FPSCR(r3) + stfd fr0,FPSTATE_FPSCR(r7) dont_backup_fp: /* The moment we treclaim, ALL of our GPRs will switch @@ -284,7 +285,7 @@ dont_backup_fp: REST_NVGPRS(r1) addi r1, r1, TM_FRAME_SIZE - ld r4, 8(r1) + lwz r4, 8(r1) ld r0, 16(r1) mtcr r4 mtlr r0 @@ -309,7 +310,7 @@ dont_backup_fp: _GLOBAL(tm_recheckpoint) mfcr r5 mflr r0 - std r5, 8(r1) + stw r5, 8(r1) std r0, 16(r1) std r2, 40(r1) stdu r1, -TM_FRAME_SIZE(r1) @@ -358,10 +359,11 @@ _GLOBAL(tm_recheckpoint) andis. r0, r4, MSR_VEC@h beq dont_restore_vec - li r5, THREAD_VSCR - lvx vr0, r3, r5 + addi r8, r3, THREAD_VRSTATE + li r5, VRSTATE_VSCR + lvx vr0, r8, r5 mtvscr vr0 - REST_32VRS(0, r5, r3) /* r5 scratch, r3 THREAD ptr */ + REST_32VRS(0, r5, r8) /* r5 scratch, r8 ptr */ dont_restore_vec: ld r5, THREAD_VRSAVE(r3) mtspr SPRN_VRSAVE, r5 @@ -370,9 +372,10 @@ dont_restore_vec: andi. r0, r4, MSR_FP beq dont_restore_fp - lfd fr0, THREAD_FPSCR(r3) + addi r8, r3, THREAD_FPSTATE + lfd fr0, FPSTATE_FPSCR(r8) MTFSF_L(fr0) - REST_32FPRS_VSRS(0, R4, R3) + REST_32FPRS_VSRS(0, R4, R8) dont_restore_fp: mtmsr r6 /* FP/Vec off again! */ @@ -441,7 +444,7 @@ restore_gprs: REST_NVGPRS(r1) addi r1, r1, TM_FRAME_SIZE - ld r4, 8(r1) + lwz r4, 8(r1) ld r0, 16(r1) mtcr r4 mtlr r0 diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index f783c932faeb..907a472f9a9e 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -351,8 +351,8 @@ static inline int check_io_access(struct pt_regs *regs) #define REASON_TRAP ESR_PTR /* single-step stuff */ -#define single_stepping(regs) (current->thread.dbcr0 & DBCR0_IC) -#define clear_single_step(regs) (current->thread.dbcr0 &= ~DBCR0_IC) +#define single_stepping(regs) (current->thread.debug.dbcr0 & DBCR0_IC) +#define clear_single_step(regs) (current->thread.debug.dbcr0 &= ~DBCR0_IC) #else /* On non-4xx, the reason for the machine check or program @@ -816,7 +816,7 @@ static void parse_fpe(struct pt_regs *regs) flush_fp_to_thread(current); - code = __parse_fpscr(current->thread.fpscr.val); + code = __parse_fpscr(current->thread.fp_state.fpscr); _exception(SIGFPE, regs, code, regs->nip); } @@ -1018,6 +1018,13 @@ static int emulate_instruction(struct pt_regs *regs) return emulate_isel(regs, instword); } + /* Emulate sync instruction variants */ + if ((instword & PPC_INST_SYNC_MASK) == PPC_INST_SYNC) { + PPC_WARN_EMULATED(sync, regs); + asm volatile("sync"); + return 0; + } + #ifdef CONFIG_PPC64 /* Emulate the mfspr rD, DSCR. */ if ((((instword & PPC_INST_MFSPR_DSCR_USER_MASK) == @@ -1069,7 +1076,7 @@ static int emulate_math(struct pt_regs *regs) return 0; case 1: { int code = 0; - code = __parse_fpscr(current->thread.fpscr.val); + code = __parse_fpscr(current->thread.fp_state.fpscr); _exception(SIGFPE, regs, code, regs->nip); return 0; } @@ -1371,8 +1378,6 @@ void facility_unavailable_exception(struct pt_regs *regs) #ifdef CONFIG_PPC_TRANSACTIONAL_MEM -extern void do_load_up_fpu(struct pt_regs *regs); - void fp_unavailable_tm(struct pt_regs *regs) { /* Note: This does not handle any kind of FP laziness. */ @@ -1403,8 +1408,6 @@ void fp_unavailable_tm(struct pt_regs *regs) } #ifdef CONFIG_ALTIVEC -extern void do_load_up_altivec(struct pt_regs *regs); - void altivec_unavailable_tm(struct pt_regs *regs) { /* See the comments in fp_unavailable_tm(). This function operates @@ -1465,7 +1468,8 @@ void SoftwareEmulation(struct pt_regs *regs) if (!user_mode(regs)) { debugger(regs); - die("Kernel Mode Software FPU Emulation", regs, SIGFPE); + die("Kernel Mode Unimplemented Instruction or SW FPU Emulation", + regs, SIGFPE); } if (!emulate_math(regs)) @@ -1486,7 +1490,7 @@ static void handle_debug(struct pt_regs *regs, unsigned long debug_status) if (debug_status & (DBSR_DAC1R | DBSR_DAC1W)) { dbcr_dac(current) &= ~(DBCR_DAC1R | DBCR_DAC1W); #ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE - current->thread.dbcr2 &= ~DBCR2_DAC12MODE; + current->thread.debug.dbcr2 &= ~DBCR2_DAC12MODE; #endif do_send_trap(regs, mfspr(SPRN_DAC1), debug_status, TRAP_HWBKPT, 5); @@ -1497,24 +1501,24 @@ static void handle_debug(struct pt_regs *regs, unsigned long debug_status) 6); changed |= 0x01; } else if (debug_status & DBSR_IAC1) { - current->thread.dbcr0 &= ~DBCR0_IAC1; + current->thread.debug.dbcr0 &= ~DBCR0_IAC1; dbcr_iac_range(current) &= ~DBCR_IAC12MODE; do_send_trap(regs, mfspr(SPRN_IAC1), debug_status, TRAP_HWBKPT, 1); changed |= 0x01; } else if (debug_status & DBSR_IAC2) { - current->thread.dbcr0 &= ~DBCR0_IAC2; + current->thread.debug.dbcr0 &= ~DBCR0_IAC2; do_send_trap(regs, mfspr(SPRN_IAC2), debug_status, TRAP_HWBKPT, 2); changed |= 0x01; } else if (debug_status & DBSR_IAC3) { - current->thread.dbcr0 &= ~DBCR0_IAC3; + current->thread.debug.dbcr0 &= ~DBCR0_IAC3; dbcr_iac_range(current) &= ~DBCR_IAC34MODE; do_send_trap(regs, mfspr(SPRN_IAC3), debug_status, TRAP_HWBKPT, 3); changed |= 0x01; } else if (debug_status & DBSR_IAC4) { - current->thread.dbcr0 &= ~DBCR0_IAC4; + current->thread.debug.dbcr0 &= ~DBCR0_IAC4; do_send_trap(regs, mfspr(SPRN_IAC4), debug_status, TRAP_HWBKPT, 4); changed |= 0x01; @@ -1524,19 +1528,20 @@ static void handle_debug(struct pt_regs *regs, unsigned long debug_status) * Check all other debug flags and see if that bit needs to be turned * back on or not. */ - if (DBCR_ACTIVE_EVENTS(current->thread.dbcr0, current->thread.dbcr1)) + if (DBCR_ACTIVE_EVENTS(current->thread.debug.dbcr0, + current->thread.debug.dbcr1)) regs->msr |= MSR_DE; else /* Make sure the IDM flag is off */ - current->thread.dbcr0 &= ~DBCR0_IDM; + current->thread.debug.dbcr0 &= ~DBCR0_IDM; if (changed & 0x01) - mtspr(SPRN_DBCR0, current->thread.dbcr0); + mtspr(SPRN_DBCR0, current->thread.debug.dbcr0); } void __kprobes DebugException(struct pt_regs *regs, unsigned long debug_status) { - current->thread.dbsr = debug_status; + current->thread.debug.dbsr = debug_status; /* Hack alert: On BookE, Branch Taken stops on the branch itself, while * on server, it stops on the target of the branch. In order to simulate @@ -1553,8 +1558,8 @@ void __kprobes DebugException(struct pt_regs *regs, unsigned long debug_status) /* Do the single step trick only when coming from userspace */ if (user_mode(regs)) { - current->thread.dbcr0 &= ~DBCR0_BT; - current->thread.dbcr0 |= DBCR0_IDM | DBCR0_IC; + current->thread.debug.dbcr0 &= ~DBCR0_BT; + current->thread.debug.dbcr0 |= DBCR0_IDM | DBCR0_IC; regs->msr |= MSR_DE; return; } @@ -1582,13 +1587,13 @@ void __kprobes DebugException(struct pt_regs *regs, unsigned long debug_status) return; if (user_mode(regs)) { - current->thread.dbcr0 &= ~DBCR0_IC; - if (DBCR_ACTIVE_EVENTS(current->thread.dbcr0, - current->thread.dbcr1)) + current->thread.debug.dbcr0 &= ~DBCR0_IC; + if (DBCR_ACTIVE_EVENTS(current->thread.debug.dbcr0, + current->thread.debug.dbcr1)) regs->msr |= MSR_DE; else /* Make sure the IDM bit is off */ - current->thread.dbcr0 &= ~DBCR0_IDM; + current->thread.debug.dbcr0 &= ~DBCR0_IDM; } _exception(SIGTRAP, regs, TRAP_TRACE, regs->nip); @@ -1634,7 +1639,7 @@ void altivec_assist_exception(struct pt_regs *regs) /* XXX quick hack for now: set the non-Java bit in the VSCR */ printk_ratelimited(KERN_ERR "Unrecognized altivec instruction " "in %s at %lx\n", current->comm, regs->nip); - current->thread.vscr.u[3] |= 0x10000; + current->thread.vr_state.vscr.u[3] |= 0x10000; } } #endif /* CONFIG_ALTIVEC */ @@ -1815,6 +1820,7 @@ struct ppc_emulated ppc_emulated = { WARN_EMULATED_SETUP(popcntb), WARN_EMULATED_SETUP(spe), WARN_EMULATED_SETUP(string), + WARN_EMULATED_SETUP(sync), WARN_EMULATED_SETUP(unaligned), #ifdef CONFIG_MATH_EMULATION WARN_EMULATED_SETUP(math), diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c index 1d9c92621b36..094e45c16a17 100644 --- a/arch/powerpc/kernel/vdso.c +++ b/arch/powerpc/kernel/vdso.c @@ -34,8 +34,7 @@ #include <asm/firmware.h> #include <asm/vdso.h> #include <asm/vdso_datapage.h> - -#include "setup.h" +#include <asm/setup.h> #undef DEBUG diff --git a/arch/powerpc/kernel/vdso32/vdso32.lds.S b/arch/powerpc/kernel/vdso32/vdso32.lds.S index f223409629b9..e58ee10fa5c0 100644 --- a/arch/powerpc/kernel/vdso32/vdso32.lds.S +++ b/arch/powerpc/kernel/vdso32/vdso32.lds.S @@ -4,7 +4,11 @@ */ #include <asm/vdso.h> +#ifdef __LITTLE_ENDIAN__ +OUTPUT_FORMAT("elf32-powerpcle", "elf32-powerpcle", "elf32-powerpcle") +#else OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", "elf32-powerpc") +#endif OUTPUT_ARCH(powerpc:common) ENTRY(_start) diff --git a/arch/powerpc/kernel/vdso64/vdso64.lds.S b/arch/powerpc/kernel/vdso64/vdso64.lds.S index e4863819663b..64fb183a47c2 100644 --- a/arch/powerpc/kernel/vdso64/vdso64.lds.S +++ b/arch/powerpc/kernel/vdso64/vdso64.lds.S @@ -4,7 +4,11 @@ */ #include <asm/vdso.h> +#ifdef __LITTLE_ENDIAN__ +OUTPUT_FORMAT("elf64-powerpcle", "elf64-powerpcle", "elf64-powerpcle") +#else OUTPUT_FORMAT("elf64-powerpc", "elf64-powerpc", "elf64-powerpc") +#endif OUTPUT_ARCH(powerpc:common64) ENTRY(_start) diff --git a/arch/powerpc/kernel/vecemu.c b/arch/powerpc/kernel/vecemu.c index 604d0947cb20..c4bfadb2606b 100644 --- a/arch/powerpc/kernel/vecemu.c +++ b/arch/powerpc/kernel/vecemu.c @@ -271,7 +271,7 @@ int emulate_altivec(struct pt_regs *regs) vb = (instr >> 11) & 0x1f; vc = (instr >> 6) & 0x1f; - vrs = current->thread.vr; + vrs = current->thread.vr_state.vr; switch (instr & 0x3f) { case 10: switch (vc) { @@ -320,12 +320,12 @@ int emulate_altivec(struct pt_regs *regs) case 14: /* vctuxs */ for (i = 0; i < 4; ++i) vrs[vd].u[i] = ctuxs(vrs[vb].u[i], va, - ¤t->thread.vscr.u[3]); + ¤t->thread.vr_state.vscr.u[3]); break; case 15: /* vctsxs */ for (i = 0; i < 4; ++i) vrs[vd].u[i] = ctsxs(vrs[vb].u[i], va, - ¤t->thread.vscr.u[3]); + ¤t->thread.vr_state.vscr.u[3]); break; default: return -EINVAL; diff --git a/arch/powerpc/kernel/vector.S b/arch/powerpc/kernel/vector.S index 9e20999aaef2..0458a9aaba9d 100644 --- a/arch/powerpc/kernel/vector.S +++ b/arch/powerpc/kernel/vector.S @@ -8,29 +8,6 @@ #include <asm/ptrace.h> #ifdef CONFIG_PPC_TRANSACTIONAL_MEM -/* - * Wrapper to call load_up_altivec from C. - * void do_load_up_altivec(struct pt_regs *regs); - */ -_GLOBAL(do_load_up_altivec) - mflr r0 - std r0, 16(r1) - stdu r1, -112(r1) - - subi r6, r3, STACK_FRAME_OVERHEAD - /* load_up_altivec expects r12=MSR, r13=PACA, and returns - * with r12 = new MSR. - */ - ld r12,_MSR(r6) - GET_PACA(r13) - bl load_up_altivec - std r12,_MSR(r6) - - ld r0, 112+16(r1) - addi r1, r1, 112 - mtlr r0 - blr - /* void do_load_up_transact_altivec(struct thread_struct *thread) * * This is similar to load_up_altivec but for the transactional version of the @@ -46,10 +23,11 @@ _GLOBAL(do_load_up_transact_altivec) li r4,1 stw r4,THREAD_USED_VR(r3) - li r10,THREAD_TRANSACT_VSCR + li r10,THREAD_TRANSACT_VRSTATE+VRSTATE_VSCR lvx vr0,r10,r3 mtvscr vr0 - REST_32VRS_TRANSACT(0,r4,r3) + addi r10,r3,THREAD_TRANSACT_VRSTATE + REST_32VRS(0,r4,r10) /* Disable VEC again. */ MTMSRD(r6) @@ -59,12 +37,36 @@ _GLOBAL(do_load_up_transact_altivec) #endif /* - * load_up_altivec(unused, unused, tsk) + * Load state from memory into VMX registers including VSCR. + * Assumes the caller has enabled VMX in the MSR. + */ +_GLOBAL(load_vr_state) + li r4,VRSTATE_VSCR + lvx vr0,r4,r3 + mtvscr vr0 + REST_32VRS(0,r4,r3) + blr + +/* + * Store VMX state into memory, including VSCR. + * Assumes the caller has enabled VMX in the MSR. + */ +_GLOBAL(store_vr_state) + SAVE_32VRS(0, r4, r3) + mfvscr vr0 + li r4, VRSTATE_VSCR + stvx vr0, r4, r3 + blr + +/* * Disable VMX for the task which had it previously, * and save its vector registers in its thread_struct. * Enables the VMX for use in the kernel on return. * On SMP we know the VMX is free, since we give it up every * switch (ie, no lazy save of the vector registers). + * + * Note that on 32-bit this can only use registers that will be + * restored by fast_exception_return, i.e. r3 - r6, r10 and r11. */ _GLOBAL(load_up_altivec) mfmsr r5 /* grab the current MSR */ @@ -90,10 +92,11 @@ _GLOBAL(load_up_altivec) /* Save VMX state to last_task_used_altivec's THREAD struct */ toreal(r4) addi r4,r4,THREAD - SAVE_32VRS(0,r5,r4) + addi r6,r4,THREAD_VRSTATE + SAVE_32VRS(0,r5,r6) mfvscr vr0 - li r10,THREAD_VSCR - stvx vr0,r10,r4 + li r10,VRSTATE_VSCR + stvx vr0,r10,r6 /* Disable VMX for last_task_used_altivec */ PPC_LL r5,PT_REGS(r4) toreal(r5) @@ -125,12 +128,13 @@ _GLOBAL(load_up_altivec) oris r12,r12,MSR_VEC@h std r12,_MSR(r1) #endif + addi r6,r5,THREAD_VRSTATE li r4,1 - li r10,THREAD_VSCR + li r10,VRSTATE_VSCR stw r4,THREAD_USED_VR(r5) - lvx vr0,r10,r5 + lvx vr0,r10,r6 mtvscr vr0 - REST_32VRS(0,r4,r5) + REST_32VRS(0,r4,r6) #ifndef CONFIG_SMP /* Update last_task_used_altivec to 'current' */ subi r4,r5,THREAD /* Back to 'current' */ @@ -165,12 +169,16 @@ _GLOBAL(giveup_altivec) PPC_LCMPI 0,r3,0 beqlr /* if no previous owner, done */ addi r3,r3,THREAD /* want THREAD of task */ + PPC_LL r7,THREAD_VRSAVEAREA(r3) PPC_LL r5,PT_REGS(r3) - PPC_LCMPI 0,r5,0 - SAVE_32VRS(0,r4,r3) + PPC_LCMPI 0,r7,0 + bne 2f + addi r7,r3,THREAD_VRSTATE +2: PPC_LCMPI 0,r5,0 + SAVE_32VRS(0,r4,r7) mfvscr vr0 - li r4,THREAD_VSCR - stvx vr0,r4,r3 + li r4,VRSTATE_VSCR + stvx vr0,r4,r7 beq 1f PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5) #ifdef CONFIG_VSX diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index d38cc08b16c7..e7d0c88f621a 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c @@ -997,21 +997,36 @@ static struct device_attribute vio_cmo_dev_attrs[] = { /* sysfs bus functions and data structures for CMO */ #define viobus_cmo_rd_attr(name) \ -static ssize_t \ -viobus_cmo_##name##_show(struct bus_type *bt, char *buf) \ +static ssize_t cmo_##name##_show(struct bus_type *bt, char *buf) \ { \ return sprintf(buf, "%lu\n", vio_cmo.name); \ -} +} \ +static BUS_ATTR_RO(cmo_##name) #define viobus_cmo_pool_rd_attr(name, var) \ static ssize_t \ -viobus_cmo_##name##_pool_show_##var(struct bus_type *bt, char *buf) \ +cmo_##name##_##var##_show(struct bus_type *bt, char *buf) \ { \ return sprintf(buf, "%lu\n", vio_cmo.name.var); \ +} \ +static BUS_ATTR_RO(cmo_##name##_##var) + +viobus_cmo_rd_attr(entitled); +viobus_cmo_rd_attr(spare); +viobus_cmo_rd_attr(min); +viobus_cmo_rd_attr(desired); +viobus_cmo_rd_attr(curr); +viobus_cmo_pool_rd_attr(reserve, size); +viobus_cmo_pool_rd_attr(excess, size); +viobus_cmo_pool_rd_attr(excess, free); + +static ssize_t cmo_high_show(struct bus_type *bt, char *buf) +{ + return sprintf(buf, "%lu\n", vio_cmo.high); } -static ssize_t viobus_cmo_high_reset(struct bus_type *bt, const char *buf, - size_t count) +static ssize_t cmo_high_store(struct bus_type *bt, const char *buf, + size_t count) { unsigned long flags; @@ -1021,35 +1036,26 @@ static ssize_t viobus_cmo_high_reset(struct bus_type *bt, const char *buf, return count; } - -viobus_cmo_rd_attr(entitled); -viobus_cmo_pool_rd_attr(reserve, size); -viobus_cmo_pool_rd_attr(excess, size); -viobus_cmo_pool_rd_attr(excess, free); -viobus_cmo_rd_attr(spare); -viobus_cmo_rd_attr(min); -viobus_cmo_rd_attr(desired); -viobus_cmo_rd_attr(curr); -viobus_cmo_rd_attr(high); - -static struct bus_attribute vio_cmo_bus_attrs[] = { - __ATTR(cmo_entitled, S_IRUGO, viobus_cmo_entitled_show, NULL), - __ATTR(cmo_reserve_size, S_IRUGO, viobus_cmo_reserve_pool_show_size, NULL), - __ATTR(cmo_excess_size, S_IRUGO, viobus_cmo_excess_pool_show_size, NULL), - __ATTR(cmo_excess_free, S_IRUGO, viobus_cmo_excess_pool_show_free, NULL), - __ATTR(cmo_spare, S_IRUGO, viobus_cmo_spare_show, NULL), - __ATTR(cmo_min, S_IRUGO, viobus_cmo_min_show, NULL), - __ATTR(cmo_desired, S_IRUGO, viobus_cmo_desired_show, NULL), - __ATTR(cmo_curr, S_IRUGO, viobus_cmo_curr_show, NULL), - __ATTR(cmo_high, S_IWUSR|S_IRUSR|S_IWGRP|S_IRGRP|S_IROTH, - viobus_cmo_high_show, viobus_cmo_high_reset), - __ATTR_NULL +static BUS_ATTR_RW(cmo_high); + +static struct attribute *vio_bus_attrs[] = { + &bus_attr_cmo_entitled.attr, + &bus_attr_cmo_spare.attr, + &bus_attr_cmo_min.attr, + &bus_attr_cmo_desired.attr, + &bus_attr_cmo_curr.attr, + &bus_attr_cmo_high.attr, + &bus_attr_cmo_reserve_size.attr, + &bus_attr_cmo_excess_size.attr, + &bus_attr_cmo_excess_free.attr, + NULL, }; +ATTRIBUTE_GROUPS(vio_bus); static void vio_cmo_sysfs_init(void) { vio_bus_type.dev_attrs = vio_cmo_dev_attrs; - vio_bus_type.bus_attrs = vio_cmo_bus_attrs; + vio_bus_type.bus_groups = vio_bus_groups; } #else /* CONFIG_PPC_SMLPAR */ int vio_cmo_entitlement_update(size_t new_entitlement) { return 0; } @@ -1413,8 +1419,7 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node) /* needed to ensure proper operation of coherent allocations * later, in case driver doesn't set it explicitly */ - dma_set_mask(&viodev->dev, DMA_BIT_MASK(64)); - dma_set_coherent_mask(&viodev->dev, DMA_BIT_MASK(64)); + dma_set_mask_and_coherent(&viodev->dev, DMA_BIT_MASK(64)); } /* register with generic device framework */ @@ -1531,12 +1536,12 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, dn = dev->of_node; if (!dn) { - strcat(buf, "\n"); + strcpy(buf, "\n"); return strlen(buf); } cp = of_get_property(dn, "compatible", NULL); if (!cp) { - strcat(buf, "\n"); + strcpy(buf, "\n"); return strlen(buf); } diff --git a/arch/powerpc/kvm/44x.c b/arch/powerpc/kvm/44x.c index 2f5c6b6d6877..93221e87b911 100644 --- a/arch/powerpc/kvm/44x.c +++ b/arch/powerpc/kvm/44x.c @@ -31,13 +31,13 @@ #include "44x_tlb.h" #include "booke.h" -void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu) +static void kvmppc_core_vcpu_load_44x(struct kvm_vcpu *vcpu, int cpu) { kvmppc_booke_vcpu_load(vcpu, cpu); kvmppc_44x_tlb_load(vcpu); } -void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu) +static void kvmppc_core_vcpu_put_44x(struct kvm_vcpu *vcpu) { kvmppc_44x_tlb_put(vcpu); kvmppc_booke_vcpu_put(vcpu); @@ -114,29 +114,32 @@ int kvmppc_core_vcpu_translate(struct kvm_vcpu *vcpu, return 0; } -void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) +static int kvmppc_core_get_sregs_44x(struct kvm_vcpu *vcpu, + struct kvm_sregs *sregs) { - kvmppc_get_sregs_ivor(vcpu, sregs); + return kvmppc_get_sregs_ivor(vcpu, sregs); } -int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) +static int kvmppc_core_set_sregs_44x(struct kvm_vcpu *vcpu, + struct kvm_sregs *sregs) { return kvmppc_set_sregs_ivor(vcpu, sregs); } -int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id, - union kvmppc_one_reg *val) +static int kvmppc_get_one_reg_44x(struct kvm_vcpu *vcpu, u64 id, + union kvmppc_one_reg *val) { return -EINVAL; } -int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id, - union kvmppc_one_reg *val) +static int kvmppc_set_one_reg_44x(struct kvm_vcpu *vcpu, u64 id, + union kvmppc_one_reg *val) { return -EINVAL; } -struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) +static struct kvm_vcpu *kvmppc_core_vcpu_create_44x(struct kvm *kvm, + unsigned int id) { struct kvmppc_vcpu_44x *vcpu_44x; struct kvm_vcpu *vcpu; @@ -167,7 +170,7 @@ out: return ERR_PTR(err); } -void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu) +static void kvmppc_core_vcpu_free_44x(struct kvm_vcpu *vcpu) { struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu); @@ -176,28 +179,53 @@ void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu) kmem_cache_free(kvm_vcpu_cache, vcpu_44x); } -int kvmppc_core_init_vm(struct kvm *kvm) +static int kvmppc_core_init_vm_44x(struct kvm *kvm) { return 0; } -void kvmppc_core_destroy_vm(struct kvm *kvm) +static void kvmppc_core_destroy_vm_44x(struct kvm *kvm) { } +static struct kvmppc_ops kvm_ops_44x = { + .get_sregs = kvmppc_core_get_sregs_44x, + .set_sregs = kvmppc_core_set_sregs_44x, + .get_one_reg = kvmppc_get_one_reg_44x, + .set_one_reg = kvmppc_set_one_reg_44x, + .vcpu_load = kvmppc_core_vcpu_load_44x, + .vcpu_put = kvmppc_core_vcpu_put_44x, + .vcpu_create = kvmppc_core_vcpu_create_44x, + .vcpu_free = kvmppc_core_vcpu_free_44x, + .mmu_destroy = kvmppc_mmu_destroy_44x, + .init_vm = kvmppc_core_init_vm_44x, + .destroy_vm = kvmppc_core_destroy_vm_44x, + .emulate_op = kvmppc_core_emulate_op_44x, + .emulate_mtspr = kvmppc_core_emulate_mtspr_44x, + .emulate_mfspr = kvmppc_core_emulate_mfspr_44x, +}; + static int __init kvmppc_44x_init(void) { int r; r = kvmppc_booke_init(); if (r) - return r; + goto err_out; + + r = kvm_init(NULL, sizeof(struct kvmppc_vcpu_44x), 0, THIS_MODULE); + if (r) + goto err_out; + kvm_ops_44x.owner = THIS_MODULE; + kvmppc_pr_ops = &kvm_ops_44x; - return kvm_init(NULL, sizeof(struct kvmppc_vcpu_44x), 0, THIS_MODULE); +err_out: + return r; } static void __exit kvmppc_44x_exit(void) { + kvmppc_pr_ops = NULL; kvmppc_booke_exit(); } diff --git a/arch/powerpc/kvm/44x_emulate.c b/arch/powerpc/kvm/44x_emulate.c index 35ec0a8547da..92c9ab4bcfec 100644 --- a/arch/powerpc/kvm/44x_emulate.c +++ b/arch/powerpc/kvm/44x_emulate.c @@ -91,8 +91,8 @@ static int emulate_mfdcr(struct kvm_vcpu *vcpu, int rt, int dcrn) return EMULATE_DONE; } -int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, - unsigned int inst, int *advance) +int kvmppc_core_emulate_op_44x(struct kvm_run *run, struct kvm_vcpu *vcpu, + unsigned int inst, int *advance) { int emulated = EMULATE_DONE; int dcrn = get_dcrn(inst); @@ -152,7 +152,7 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, return emulated; } -int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val) +int kvmppc_core_emulate_mtspr_44x(struct kvm_vcpu *vcpu, int sprn, ulong spr_val) { int emulated = EMULATE_DONE; @@ -172,7 +172,7 @@ int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val) return emulated; } -int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val) +int kvmppc_core_emulate_mfspr_44x(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val) { int emulated = EMULATE_DONE; diff --git a/arch/powerpc/kvm/44x_tlb.c b/arch/powerpc/kvm/44x_tlb.c index ed0385448148..0deef1082e02 100644 --- a/arch/powerpc/kvm/44x_tlb.c +++ b/arch/powerpc/kvm/44x_tlb.c @@ -268,7 +268,7 @@ static void kvmppc_44x_shadow_release(struct kvmppc_vcpu_44x *vcpu_44x, trace_kvm_stlb_inval(stlb_index); } -void kvmppc_mmu_destroy(struct kvm_vcpu *vcpu) +void kvmppc_mmu_destroy_44x(struct kvm_vcpu *vcpu) { struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu); int i; diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig index ffaef2cb101a..141b2027189a 100644 --- a/arch/powerpc/kvm/Kconfig +++ b/arch/powerpc/kvm/Kconfig @@ -6,6 +6,7 @@ source "virt/kvm/Kconfig" menuconfig VIRTUALIZATION bool "Virtualization" + depends on !CPU_LITTLE_ENDIAN ---help--- Say Y here to get to see options for using your Linux host to run other operating systems inside virtual machines (guests). @@ -34,17 +35,20 @@ config KVM_BOOK3S_64_HANDLER bool select KVM_BOOK3S_HANDLER -config KVM_BOOK3S_PR +config KVM_BOOK3S_PR_POSSIBLE bool select KVM_MMIO select MMU_NOTIFIER +config KVM_BOOK3S_HV_POSSIBLE + bool + config KVM_BOOK3S_32 tristate "KVM support for PowerPC book3s_32 processors" depends on PPC_BOOK3S_32 && !SMP && !PTE_64BIT select KVM select KVM_BOOK3S_32_HANDLER - select KVM_BOOK3S_PR + select KVM_BOOK3S_PR_POSSIBLE ---help--- Support running unmodified book3s_32 guest kernels in virtual machines on book3s_32 host processors. @@ -59,6 +63,7 @@ config KVM_BOOK3S_64 depends on PPC_BOOK3S_64 select KVM_BOOK3S_64_HANDLER select KVM + select KVM_BOOK3S_PR_POSSIBLE if !KVM_BOOK3S_HV_POSSIBLE ---help--- Support running unmodified book3s_64 and book3s_32 guest kernels in virtual machines on book3s_64 host processors. @@ -69,8 +74,9 @@ config KVM_BOOK3S_64 If unsure, say N. config KVM_BOOK3S_64_HV - bool "KVM support for POWER7 and PPC970 using hypervisor mode in host" + tristate "KVM support for POWER7 and PPC970 using hypervisor mode in host" depends on KVM_BOOK3S_64 + select KVM_BOOK3S_HV_POSSIBLE select MMU_NOTIFIER select CMA ---help--- @@ -89,9 +95,20 @@ config KVM_BOOK3S_64_HV If unsure, say N. config KVM_BOOK3S_64_PR - def_bool y - depends on KVM_BOOK3S_64 && !KVM_BOOK3S_64_HV - select KVM_BOOK3S_PR + tristate "KVM support without using hypervisor mode in host" + depends on KVM_BOOK3S_64 + select KVM_BOOK3S_PR_POSSIBLE + ---help--- + Support running guest kernels in virtual machines on processors + without using hypervisor mode in the host, by running the + guest in user mode (problem state) and emulating all + privileged instructions and registers. + + This is not as fast as using hypervisor mode, but works on + machines where hypervisor mode is not available or not usable, + and can emulate processors that are different from the host + processor, including emulating 32-bit processors on a 64-bit + host. config KVM_BOOKE_HV bool diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile index 6646c952c5e3..ce569b6bf4d8 100644 --- a/arch/powerpc/kvm/Makefile +++ b/arch/powerpc/kvm/Makefile @@ -53,41 +53,51 @@ kvm-e500mc-objs := \ e500_emulate.o kvm-objs-$(CONFIG_KVM_E500MC) := $(kvm-e500mc-objs) -kvm-book3s_64-objs-$(CONFIG_KVM_BOOK3S_64_PR) := \ - $(KVM)/coalesced_mmio.o \ +kvm-book3s_64-builtin-objs-$(CONFIG_KVM_BOOK3S_64_HANDLER) := \ + book3s_64_vio_hv.o + +kvm-pr-y := \ fpu.o \ book3s_paired_singles.o \ book3s_pr.o \ book3s_pr_papr.o \ - book3s_64_vio_hv.o \ book3s_emulate.o \ book3s_interrupts.o \ book3s_mmu_hpte.o \ book3s_64_mmu_host.o \ book3s_64_mmu.o \ book3s_32_mmu.o -kvm-book3s_64-builtin-objs-$(CONFIG_KVM_BOOK3S_64_PR) := \ + +ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE +kvm-book3s_64-module-objs := \ + $(KVM)/coalesced_mmio.o + +kvm-book3s_64-builtin-objs-$(CONFIG_KVM_BOOK3S_64_HANDLER) += \ book3s_rmhandlers.o +endif -kvm-book3s_64-objs-$(CONFIG_KVM_BOOK3S_64_HV) := \ +kvm-hv-y += \ book3s_hv.o \ book3s_hv_interrupts.o \ book3s_64_mmu_hv.o + kvm-book3s_64-builtin-xics-objs-$(CONFIG_KVM_XICS) := \ book3s_hv_rm_xics.o -kvm-book3s_64-builtin-objs-$(CONFIG_KVM_BOOK3S_64_HV) := \ + +ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE +kvm-book3s_64-builtin-objs-$(CONFIG_KVM_BOOK3S_64_HANDLER) += \ book3s_hv_rmhandlers.o \ book3s_hv_rm_mmu.o \ - book3s_64_vio_hv.o \ book3s_hv_ras.o \ book3s_hv_builtin.o \ book3s_hv_cma.o \ $(kvm-book3s_64-builtin-xics-objs-y) +endif kvm-book3s_64-objs-$(CONFIG_KVM_XICS) += \ book3s_xics.o -kvm-book3s_64-module-objs := \ +kvm-book3s_64-module-objs += \ $(KVM)/kvm_main.o \ $(KVM)/eventfd.o \ powerpc.o \ @@ -123,4 +133,7 @@ obj-$(CONFIG_KVM_E500MC) += kvm.o obj-$(CONFIG_KVM_BOOK3S_64) += kvm.o obj-$(CONFIG_KVM_BOOK3S_32) += kvm.o +obj-$(CONFIG_KVM_BOOK3S_64_PR) += kvm-pr.o +obj-$(CONFIG_KVM_BOOK3S_64_HV) += kvm-hv.o + obj-y += $(kvm-book3s_64-builtin-objs-y) diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 700df6f1d32c..8912608b7e1b 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -34,6 +34,7 @@ #include <linux/vmalloc.h> #include <linux/highmem.h> +#include "book3s.h" #include "trace.h" #define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU @@ -69,6 +70,50 @@ void kvmppc_core_load_guest_debugstate(struct kvm_vcpu *vcpu) { } +static inline unsigned long kvmppc_interrupt_offset(struct kvm_vcpu *vcpu) +{ + if (!is_kvmppc_hv_enabled(vcpu->kvm)) + return to_book3s(vcpu)->hior; + return 0; +} + +static inline void kvmppc_update_int_pending(struct kvm_vcpu *vcpu, + unsigned long pending_now, unsigned long old_pending) +{ + if (is_kvmppc_hv_enabled(vcpu->kvm)) + return; + if (pending_now) + vcpu->arch.shared->int_pending = 1; + else if (old_pending) + vcpu->arch.shared->int_pending = 0; +} + +static inline bool kvmppc_critical_section(struct kvm_vcpu *vcpu) +{ + ulong crit_raw; + ulong crit_r1; + bool crit; + + if (is_kvmppc_hv_enabled(vcpu->kvm)) + return false; + + crit_raw = vcpu->arch.shared->critical; + crit_r1 = kvmppc_get_gpr(vcpu, 1); + + /* Truncate crit indicators in 32 bit mode */ + if (!(vcpu->arch.shared->msr & MSR_SF)) { + crit_raw &= 0xffffffff; + crit_r1 &= 0xffffffff; + } + + /* Critical section when crit == r1 */ + crit = (crit_raw == crit_r1); + /* ... and we're in supervisor mode */ + crit = crit && !(vcpu->arch.shared->msr & MSR_PR); + + return crit; +} + void kvmppc_inject_interrupt(struct kvm_vcpu *vcpu, int vec, u64 flags) { vcpu->arch.shared->srr0 = kvmppc_get_pc(vcpu); @@ -126,28 +171,32 @@ void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec) printk(KERN_INFO "Queueing interrupt %x\n", vec); #endif } - +EXPORT_SYMBOL_GPL(kvmppc_book3s_queue_irqprio); void kvmppc_core_queue_program(struct kvm_vcpu *vcpu, ulong flags) { /* might as well deliver this straight away */ kvmppc_inject_interrupt(vcpu, BOOK3S_INTERRUPT_PROGRAM, flags); } +EXPORT_SYMBOL_GPL(kvmppc_core_queue_program); void kvmppc_core_queue_dec(struct kvm_vcpu *vcpu) { kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_DECREMENTER); } +EXPORT_SYMBOL_GPL(kvmppc_core_queue_dec); int kvmppc_core_pending_dec(struct kvm_vcpu *vcpu) { return test_bit(BOOK3S_IRQPRIO_DECREMENTER, &vcpu->arch.pending_exceptions); } +EXPORT_SYMBOL_GPL(kvmppc_core_pending_dec); void kvmppc_core_dequeue_dec(struct kvm_vcpu *vcpu) { kvmppc_book3s_dequeue_irqprio(vcpu, BOOK3S_INTERRUPT_DECREMENTER); } +EXPORT_SYMBOL_GPL(kvmppc_core_dequeue_dec); void kvmppc_core_queue_external(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq) @@ -285,8 +334,10 @@ int kvmppc_core_prepare_to_enter(struct kvm_vcpu *vcpu) return 0; } +EXPORT_SYMBOL_GPL(kvmppc_core_prepare_to_enter); -pfn_t kvmppc_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn) +pfn_t kvmppc_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn, bool writing, + bool *writable) { ulong mp_pa = vcpu->arch.magic_page_pa; @@ -302,20 +353,23 @@ pfn_t kvmppc_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn) pfn = (pfn_t)virt_to_phys((void*)shared_page) >> PAGE_SHIFT; get_page(pfn_to_page(pfn)); + if (writable) + *writable = true; return pfn; } - return gfn_to_pfn(vcpu->kvm, gfn); + return gfn_to_pfn_prot(vcpu->kvm, gfn, writing, writable); } +EXPORT_SYMBOL_GPL(kvmppc_gfn_to_pfn); static int kvmppc_xlate(struct kvm_vcpu *vcpu, ulong eaddr, bool data, - struct kvmppc_pte *pte) + bool iswrite, struct kvmppc_pte *pte) { int relocated = (vcpu->arch.shared->msr & (data ? MSR_DR : MSR_IR)); int r; if (relocated) { - r = vcpu->arch.mmu.xlate(vcpu, eaddr, pte, data); + r = vcpu->arch.mmu.xlate(vcpu, eaddr, pte, data, iswrite); } else { pte->eaddr = eaddr; pte->raddr = eaddr & KVM_PAM; @@ -361,7 +415,7 @@ int kvmppc_st(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, vcpu->stat.st++; - if (kvmppc_xlate(vcpu, *eaddr, data, &pte)) + if (kvmppc_xlate(vcpu, *eaddr, data, true, &pte)) return -ENOENT; *eaddr = pte.raddr; @@ -374,6 +428,7 @@ int kvmppc_st(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, return EMULATE_DONE; } +EXPORT_SYMBOL_GPL(kvmppc_st); int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, bool data) @@ -383,7 +438,7 @@ int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, vcpu->stat.ld++; - if (kvmppc_xlate(vcpu, *eaddr, data, &pte)) + if (kvmppc_xlate(vcpu, *eaddr, data, false, &pte)) goto nopte; *eaddr = pte.raddr; @@ -404,6 +459,7 @@ nopte: mmio: return EMULATE_DO_MMIO; } +EXPORT_SYMBOL_GPL(kvmppc_ld); int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) { @@ -419,6 +475,18 @@ void kvmppc_subarch_vcpu_uninit(struct kvm_vcpu *vcpu) { } +int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, + struct kvm_sregs *sregs) +{ + return vcpu->kvm->arch.kvm_ops->get_sregs(vcpu, sregs); +} + +int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, + struct kvm_sregs *sregs) +{ + return vcpu->kvm->arch.kvm_ops->set_sregs(vcpu, sregs); +} + int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) { int i; @@ -495,8 +563,7 @@ int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) if (size > sizeof(val)) return -EINVAL; - r = kvmppc_get_one_reg(vcpu, reg->id, &val); - + r = vcpu->kvm->arch.kvm_ops->get_one_reg(vcpu, reg->id, &val); if (r == -EINVAL) { r = 0; switch (reg->id) { @@ -528,6 +595,9 @@ int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) } val = get_reg_val(reg->id, vcpu->arch.vscr.u[3]); break; + case KVM_REG_PPC_VRSAVE: + val = get_reg_val(reg->id, vcpu->arch.vrsave); + break; #endif /* CONFIG_ALTIVEC */ case KVM_REG_PPC_DEBUG_INST: { u32 opcode = INS_TW; @@ -572,8 +642,7 @@ int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) if (copy_from_user(&val, (char __user *)(unsigned long)reg->addr, size)) return -EFAULT; - r = kvmppc_set_one_reg(vcpu, reg->id, &val); - + r = vcpu->kvm->arch.kvm_ops->set_one_reg(vcpu, reg->id, &val); if (r == -EINVAL) { r = 0; switch (reg->id) { @@ -605,6 +674,13 @@ int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) } vcpu->arch.vscr.u[3] = set_reg_val(reg->id, val); break; + case KVM_REG_PPC_VRSAVE: + if (!cpu_has_feature(CPU_FTR_ALTIVEC)) { + r = -ENXIO; + break; + } + vcpu->arch.vrsave = set_reg_val(reg->id, val); + break; #endif /* CONFIG_ALTIVEC */ #ifdef CONFIG_KVM_XICS case KVM_REG_PPC_ICP_STATE: @@ -625,6 +701,27 @@ int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) return r; } +void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu) +{ + vcpu->kvm->arch.kvm_ops->vcpu_load(vcpu, cpu); +} + +void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu) +{ + vcpu->kvm->arch.kvm_ops->vcpu_put(vcpu); +} + +void kvmppc_set_msr(struct kvm_vcpu *vcpu, u64 msr) +{ + vcpu->kvm->arch.kvm_ops->set_msr(vcpu, msr); +} +EXPORT_SYMBOL_GPL(kvmppc_set_msr); + +int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) +{ + return vcpu->kvm->arch.kvm_ops->vcpu_run(kvm_run, vcpu); +} + int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu, struct kvm_translation *tr) { @@ -644,3 +741,141 @@ void kvmppc_decrementer_func(unsigned long data) kvmppc_core_queue_dec(vcpu); kvm_vcpu_kick(vcpu); } + +struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) +{ + return kvm->arch.kvm_ops->vcpu_create(kvm, id); +} + +void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu) +{ + vcpu->kvm->arch.kvm_ops->vcpu_free(vcpu); +} + +int kvmppc_core_check_requests(struct kvm_vcpu *vcpu) +{ + return vcpu->kvm->arch.kvm_ops->check_requests(vcpu); +} + +int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log) +{ + return kvm->arch.kvm_ops->get_dirty_log(kvm, log); +} + +void kvmppc_core_free_memslot(struct kvm *kvm, struct kvm_memory_slot *free, + struct kvm_memory_slot *dont) +{ + kvm->arch.kvm_ops->free_memslot(free, dont); +} + +int kvmppc_core_create_memslot(struct kvm *kvm, struct kvm_memory_slot *slot, + unsigned long npages) +{ + return kvm->arch.kvm_ops->create_memslot(slot, npages); +} + +void kvmppc_core_flush_memslot(struct kvm *kvm, struct kvm_memory_slot *memslot) +{ + kvm->arch.kvm_ops->flush_memslot(kvm, memslot); +} + +int kvmppc_core_prepare_memory_region(struct kvm *kvm, + struct kvm_memory_slot *memslot, + struct kvm_userspace_memory_region *mem) +{ + return kvm->arch.kvm_ops->prepare_memory_region(kvm, memslot, mem); +} + +void kvmppc_core_commit_memory_region(struct kvm *kvm, + struct kvm_userspace_memory_region *mem, + const struct kvm_memory_slot *old) +{ + kvm->arch.kvm_ops->commit_memory_region(kvm, mem, old); +} + +int kvm_unmap_hva(struct kvm *kvm, unsigned long hva) +{ + return kvm->arch.kvm_ops->unmap_hva(kvm, hva); +} +EXPORT_SYMBOL_GPL(kvm_unmap_hva); + +int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end) +{ + return kvm->arch.kvm_ops->unmap_hva_range(kvm, start, end); +} + +int kvm_age_hva(struct kvm *kvm, unsigned long hva) +{ + return kvm->arch.kvm_ops->age_hva(kvm, hva); +} + +int kvm_test_age_hva(struct kvm *kvm, unsigned long hva) +{ + return kvm->arch.kvm_ops->test_age_hva(kvm, hva); +} + +void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte) +{ + kvm->arch.kvm_ops->set_spte_hva(kvm, hva, pte); +} + +void kvmppc_mmu_destroy(struct kvm_vcpu *vcpu) +{ + vcpu->kvm->arch.kvm_ops->mmu_destroy(vcpu); +} + +int kvmppc_core_init_vm(struct kvm *kvm) +{ + +#ifdef CONFIG_PPC64 + INIT_LIST_HEAD(&kvm->arch.spapr_tce_tables); + INIT_LIST_HEAD(&kvm->arch.rtas_tokens); +#endif + + return kvm->arch.kvm_ops->init_vm(kvm); +} + +void kvmppc_core_destroy_vm(struct kvm *kvm) +{ + kvm->arch.kvm_ops->destroy_vm(kvm); + +#ifdef CONFIG_PPC64 + kvmppc_rtas_tokens_free(kvm); + WARN_ON(!list_empty(&kvm->arch.spapr_tce_tables)); +#endif +} + +int kvmppc_core_check_processor_compat(void) +{ + /* + * We always return 0 for book3s. We check + * for compatability while loading the HV + * or PR module + */ + return 0; +} + +static int kvmppc_book3s_init(void) +{ + int r; + + r = kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE); + if (r) + return r; +#ifdef CONFIG_KVM_BOOK3S_32 + r = kvmppc_book3s_init_pr(); +#endif + return r; + +} + +static void kvmppc_book3s_exit(void) +{ +#ifdef CONFIG_KVM_BOOK3S_32 + kvmppc_book3s_exit_pr(); +#endif + kvm_exit(); +} + +module_init(kvmppc_book3s_init); +module_exit(kvmppc_book3s_exit); diff --git a/arch/powerpc/kvm/book3s.h b/arch/powerpc/kvm/book3s.h new file mode 100644 index 000000000000..4bf956cf94d6 --- /dev/null +++ b/arch/powerpc/kvm/book3s.h @@ -0,0 +1,34 @@ +/* + * Copyright IBM Corporation, 2013 + * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License or (at your optional) any later version of the license. + * + */ + +#ifndef __POWERPC_KVM_BOOK3S_H__ +#define __POWERPC_KVM_BOOK3S_H__ + +extern void kvmppc_core_flush_memslot_hv(struct kvm *kvm, + struct kvm_memory_slot *memslot); +extern int kvm_unmap_hva_hv(struct kvm *kvm, unsigned long hva); +extern int kvm_unmap_hva_range_hv(struct kvm *kvm, unsigned long start, + unsigned long end); +extern int kvm_age_hva_hv(struct kvm *kvm, unsigned long hva); +extern int kvm_test_age_hva_hv(struct kvm *kvm, unsigned long hva); +extern void kvm_set_spte_hva_hv(struct kvm *kvm, unsigned long hva, pte_t pte); + +extern void kvmppc_mmu_destroy_pr(struct kvm_vcpu *vcpu); +extern int kvmppc_core_emulate_op_pr(struct kvm_run *run, struct kvm_vcpu *vcpu, + unsigned int inst, int *advance); +extern int kvmppc_core_emulate_mtspr_pr(struct kvm_vcpu *vcpu, + int sprn, ulong spr_val); +extern int kvmppc_core_emulate_mfspr_pr(struct kvm_vcpu *vcpu, + int sprn, ulong *spr_val); +extern int kvmppc_book3s_init_pr(void); +extern void kvmppc_book3s_exit_pr(void); + +#endif diff --git a/arch/powerpc/kvm/book3s_32_mmu.c b/arch/powerpc/kvm/book3s_32_mmu.c index c8cefdd15fd8..76a64ce6a5b6 100644 --- a/arch/powerpc/kvm/book3s_32_mmu.c +++ b/arch/powerpc/kvm/book3s_32_mmu.c @@ -84,7 +84,8 @@ static inline bool sr_nx(u32 sr_raw) } static int kvmppc_mmu_book3s_32_xlate_bat(struct kvm_vcpu *vcpu, gva_t eaddr, - struct kvmppc_pte *pte, bool data); + struct kvmppc_pte *pte, bool data, + bool iswrite); static int kvmppc_mmu_book3s_32_esid_to_vsid(struct kvm_vcpu *vcpu, ulong esid, u64 *vsid); @@ -99,7 +100,7 @@ static u64 kvmppc_mmu_book3s_32_ea_to_vp(struct kvm_vcpu *vcpu, gva_t eaddr, u64 vsid; struct kvmppc_pte pte; - if (!kvmppc_mmu_book3s_32_xlate_bat(vcpu, eaddr, &pte, data)) + if (!kvmppc_mmu_book3s_32_xlate_bat(vcpu, eaddr, &pte, data, false)) return pte.vpage; kvmppc_mmu_book3s_32_esid_to_vsid(vcpu, eaddr >> SID_SHIFT, &vsid); @@ -111,10 +112,11 @@ static void kvmppc_mmu_book3s_32_reset_msr(struct kvm_vcpu *vcpu) kvmppc_set_msr(vcpu, 0); } -static hva_t kvmppc_mmu_book3s_32_get_pteg(struct kvmppc_vcpu_book3s *vcpu_book3s, +static hva_t kvmppc_mmu_book3s_32_get_pteg(struct kvm_vcpu *vcpu, u32 sre, gva_t eaddr, bool primary) { + struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu); u32 page, hash, pteg, htabmask; hva_t r; @@ -132,7 +134,7 @@ static hva_t kvmppc_mmu_book3s_32_get_pteg(struct kvmppc_vcpu_book3s *vcpu_book3 kvmppc_get_pc(&vcpu_book3s->vcpu), eaddr, vcpu_book3s->sdr1, pteg, sr_vsid(sre)); - r = gfn_to_hva(vcpu_book3s->vcpu.kvm, pteg >> PAGE_SHIFT); + r = gfn_to_hva(vcpu->kvm, pteg >> PAGE_SHIFT); if (kvm_is_error_hva(r)) return r; return r | (pteg & ~PAGE_MASK); @@ -145,7 +147,8 @@ static u32 kvmppc_mmu_book3s_32_get_ptem(u32 sre, gva_t eaddr, bool primary) } static int kvmppc_mmu_book3s_32_xlate_bat(struct kvm_vcpu *vcpu, gva_t eaddr, - struct kvmppc_pte *pte, bool data) + struct kvmppc_pte *pte, bool data, + bool iswrite) { struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu); struct kvmppc_bat *bat; @@ -186,8 +189,7 @@ static int kvmppc_mmu_book3s_32_xlate_bat(struct kvm_vcpu *vcpu, gva_t eaddr, printk(KERN_INFO "BAT is not readable!\n"); continue; } - if (!pte->may_write) { - /* let's treat r/o BATs as not-readable for now */ + if (iswrite && !pte->may_write) { dprintk_pte("BAT is read-only!\n"); continue; } @@ -201,9 +203,8 @@ static int kvmppc_mmu_book3s_32_xlate_bat(struct kvm_vcpu *vcpu, gva_t eaddr, static int kvmppc_mmu_book3s_32_xlate_pte(struct kvm_vcpu *vcpu, gva_t eaddr, struct kvmppc_pte *pte, bool data, - bool primary) + bool iswrite, bool primary) { - struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu); u32 sre; hva_t ptegp; u32 pteg[16]; @@ -218,7 +219,7 @@ static int kvmppc_mmu_book3s_32_xlate_pte(struct kvm_vcpu *vcpu, gva_t eaddr, pte->vpage = kvmppc_mmu_book3s_32_ea_to_vp(vcpu, eaddr, data); - ptegp = kvmppc_mmu_book3s_32_get_pteg(vcpu_book3s, sre, eaddr, primary); + ptegp = kvmppc_mmu_book3s_32_get_pteg(vcpu, sre, eaddr, primary); if (kvm_is_error_hva(ptegp)) { printk(KERN_INFO "KVM: Invalid PTEG!\n"); goto no_page_found; @@ -258,9 +259,6 @@ static int kvmppc_mmu_book3s_32_xlate_pte(struct kvm_vcpu *vcpu, gva_t eaddr, break; } - if ( !pte->may_read ) - continue; - dprintk_pte("MMU: Found PTE -> %x %x - %x\n", pteg[i], pteg[i+1], pp); found = 1; @@ -271,19 +269,23 @@ static int kvmppc_mmu_book3s_32_xlate_pte(struct kvm_vcpu *vcpu, gva_t eaddr, /* Update PTE C and A bits, so the guest's swapper knows we used the page */ if (found) { - u32 oldpte = pteg[i+1]; - - if (pte->may_read) - pteg[i+1] |= PTEG_FLAG_ACCESSED; - if (pte->may_write) - pteg[i+1] |= PTEG_FLAG_DIRTY; - else - dprintk_pte("KVM: Mapping read-only page!\n"); - - /* Write back into the PTEG */ - if (pteg[i+1] != oldpte) - copy_to_user((void __user *)ptegp, pteg, sizeof(pteg)); - + u32 pte_r = pteg[i+1]; + char __user *addr = (char __user *) &pteg[i+1]; + + /* + * Use single-byte writes to update the HPTE, to + * conform to what real hardware does. + */ + if (pte->may_read && !(pte_r & PTEG_FLAG_ACCESSED)) { + pte_r |= PTEG_FLAG_ACCESSED; + put_user(pte_r >> 8, addr + 2); + } + if (iswrite && pte->may_write && !(pte_r & PTEG_FLAG_DIRTY)) { + pte_r |= PTEG_FLAG_DIRTY; + put_user(pte_r, addr + 3); + } + if (!pte->may_read || (iswrite && !pte->may_write)) + return -EPERM; return 0; } @@ -302,12 +304,14 @@ no_page_found: } static int kvmppc_mmu_book3s_32_xlate(struct kvm_vcpu *vcpu, gva_t eaddr, - struct kvmppc_pte *pte, bool data) + struct kvmppc_pte *pte, bool data, + bool iswrite) { int r; ulong mp_ea = vcpu->arch.magic_page_ea; pte->eaddr = eaddr; + pte->page_size = MMU_PAGE_4K; /* Magic page override */ if (unlikely(mp_ea) && @@ -323,11 +327,13 @@ static int kvmppc_mmu_book3s_32_xlate(struct kvm_vcpu *vcpu, gva_t eaddr, return 0; } - r = kvmppc_mmu_book3s_32_xlate_bat(vcpu, eaddr, pte, data); + r = kvmppc_mmu_book3s_32_xlate_bat(vcpu, eaddr, pte, data, iswrite); if (r < 0) - r = kvmppc_mmu_book3s_32_xlate_pte(vcpu, eaddr, pte, data, true); + r = kvmppc_mmu_book3s_32_xlate_pte(vcpu, eaddr, pte, + data, iswrite, true); if (r < 0) - r = kvmppc_mmu_book3s_32_xlate_pte(vcpu, eaddr, pte, data, false); + r = kvmppc_mmu_book3s_32_xlate_pte(vcpu, eaddr, pte, + data, iswrite, false); return r; } @@ -347,7 +353,12 @@ static void kvmppc_mmu_book3s_32_mtsrin(struct kvm_vcpu *vcpu, u32 srnum, static void kvmppc_mmu_book3s_32_tlbie(struct kvm_vcpu *vcpu, ulong ea, bool large) { - kvmppc_mmu_pte_flush(vcpu, ea, 0x0FFFF000); + int i; + struct kvm_vcpu *v; + + /* flush this VA on all cpus */ + kvm_for_each_vcpu(i, v, vcpu->kvm) + kvmppc_mmu_pte_flush(v, ea, 0x0FFFF000); } static int kvmppc_mmu_book3s_32_esid_to_vsid(struct kvm_vcpu *vcpu, ulong esid, diff --git a/arch/powerpc/kvm/book3s_32_mmu_host.c b/arch/powerpc/kvm/book3s_32_mmu_host.c index 00e619bf608e..3a0abd2e5a15 100644 --- a/arch/powerpc/kvm/book3s_32_mmu_host.c +++ b/arch/powerpc/kvm/book3s_32_mmu_host.c @@ -138,7 +138,8 @@ static u32 *kvmppc_mmu_get_pteg(struct kvm_vcpu *vcpu, u32 vsid, u32 eaddr, extern char etext[]; -int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte) +int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte, + bool iswrite) { pfn_t hpaddr; u64 vpn; @@ -152,9 +153,11 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte) bool evict = false; struct hpte_cache *pte; int r = 0; + bool writable; /* Get host physical address for gpa */ - hpaddr = kvmppc_gfn_to_pfn(vcpu, orig_pte->raddr >> PAGE_SHIFT); + hpaddr = kvmppc_gfn_to_pfn(vcpu, orig_pte->raddr >> PAGE_SHIFT, + iswrite, &writable); if (is_error_noslot_pfn(hpaddr)) { printk(KERN_INFO "Couldn't get guest page for gfn %lx!\n", orig_pte->eaddr); @@ -204,7 +207,7 @@ next_pteg: (primary ? 0 : PTE_SEC); pteg1 = hpaddr | PTE_M | PTE_R | PTE_C; - if (orig_pte->may_write) { + if (orig_pte->may_write && writable) { pteg1 |= PP_RWRW; mark_page_dirty(vcpu->kvm, orig_pte->raddr >> PAGE_SHIFT); } else { @@ -259,6 +262,11 @@ out: return r; } +void kvmppc_mmu_unmap_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *pte) +{ + kvmppc_mmu_pte_vflush(vcpu, pte->vpage, 0xfffffffffULL); +} + static struct kvmppc_sid_map *create_sid_map(struct kvm_vcpu *vcpu, u64 gvsid) { struct kvmppc_sid_map *map; @@ -341,7 +349,7 @@ void kvmppc_mmu_flush_segments(struct kvm_vcpu *vcpu) svcpu_put(svcpu); } -void kvmppc_mmu_destroy(struct kvm_vcpu *vcpu) +void kvmppc_mmu_destroy_pr(struct kvm_vcpu *vcpu) { int i; diff --git a/arch/powerpc/kvm/book3s_64_mmu.c b/arch/powerpc/kvm/book3s_64_mmu.c index 7e345e00661a..83da1f868fd5 100644 --- a/arch/powerpc/kvm/book3s_64_mmu.c +++ b/arch/powerpc/kvm/book3s_64_mmu.c @@ -107,9 +107,20 @@ static u64 kvmppc_mmu_book3s_64_ea_to_vp(struct kvm_vcpu *vcpu, gva_t eaddr, return kvmppc_slb_calc_vpn(slb, eaddr); } +static int mmu_pagesize(int mmu_pg) +{ + switch (mmu_pg) { + case MMU_PAGE_64K: + return 16; + case MMU_PAGE_16M: + return 24; + } + return 12; +} + static int kvmppc_mmu_book3s_64_get_pagesize(struct kvmppc_slb *slbe) { - return slbe->large ? 24 : 12; + return mmu_pagesize(slbe->base_page_size); } static u32 kvmppc_mmu_book3s_64_get_page(struct kvmppc_slb *slbe, gva_t eaddr) @@ -119,11 +130,11 @@ static u32 kvmppc_mmu_book3s_64_get_page(struct kvmppc_slb *slbe, gva_t eaddr) return ((eaddr & kvmppc_slb_offset_mask(slbe)) >> p); } -static hva_t kvmppc_mmu_book3s_64_get_pteg( - struct kvmppc_vcpu_book3s *vcpu_book3s, +static hva_t kvmppc_mmu_book3s_64_get_pteg(struct kvm_vcpu *vcpu, struct kvmppc_slb *slbe, gva_t eaddr, bool second) { + struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu); u64 hash, pteg, htabsize; u32 ssize; hva_t r; @@ -148,10 +159,10 @@ static hva_t kvmppc_mmu_book3s_64_get_pteg( /* When running a PAPR guest, SDR1 contains a HVA address instead of a GPA */ - if (vcpu_book3s->vcpu.arch.papr_enabled) + if (vcpu->arch.papr_enabled) r = pteg; else - r = gfn_to_hva(vcpu_book3s->vcpu.kvm, pteg >> PAGE_SHIFT); + r = gfn_to_hva(vcpu->kvm, pteg >> PAGE_SHIFT); if (kvm_is_error_hva(r)) return r; @@ -166,18 +177,38 @@ static u64 kvmppc_mmu_book3s_64_get_avpn(struct kvmppc_slb *slbe, gva_t eaddr) avpn = kvmppc_mmu_book3s_64_get_page(slbe, eaddr); avpn |= slbe->vsid << (kvmppc_slb_sid_shift(slbe) - p); - if (p < 24) - avpn >>= ((80 - p) - 56) - 8; + if (p < 16) + avpn >>= ((80 - p) - 56) - 8; /* 16 - p */ else - avpn <<= 8; + avpn <<= p - 16; return avpn; } +/* + * Return page size encoded in the second word of a HPTE, or + * -1 for an invalid encoding for the base page size indicated by + * the SLB entry. This doesn't handle mixed pagesize segments yet. + */ +static int decode_pagesize(struct kvmppc_slb *slbe, u64 r) +{ + switch (slbe->base_page_size) { + case MMU_PAGE_64K: + if ((r & 0xf000) == 0x1000) + return MMU_PAGE_64K; + break; + case MMU_PAGE_16M: + if ((r & 0xff000) == 0) + return MMU_PAGE_16M; + break; + } + return -1; +} + static int kvmppc_mmu_book3s_64_xlate(struct kvm_vcpu *vcpu, gva_t eaddr, - struct kvmppc_pte *gpte, bool data) + struct kvmppc_pte *gpte, bool data, + bool iswrite) { - struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu); struct kvmppc_slb *slbe; hva_t ptegp; u64 pteg[16]; @@ -189,6 +220,7 @@ static int kvmppc_mmu_book3s_64_xlate(struct kvm_vcpu *vcpu, gva_t eaddr, u8 pp, key = 0; bool found = false; bool second = false; + int pgsize; ulong mp_ea = vcpu->arch.magic_page_ea; /* Magic page override */ @@ -202,6 +234,7 @@ static int kvmppc_mmu_book3s_64_xlate(struct kvm_vcpu *vcpu, gva_t eaddr, gpte->may_execute = true; gpte->may_read = true; gpte->may_write = true; + gpte->page_size = MMU_PAGE_4K; return 0; } @@ -222,8 +255,12 @@ static int kvmppc_mmu_book3s_64_xlate(struct kvm_vcpu *vcpu, gva_t eaddr, v_mask = SLB_VSID_B | HPTE_V_AVPN | HPTE_V_LARGE | HPTE_V_VALID | HPTE_V_SECONDARY; + pgsize = slbe->large ? MMU_PAGE_16M : MMU_PAGE_4K; + + mutex_lock(&vcpu->kvm->arch.hpt_mutex); + do_second: - ptegp = kvmppc_mmu_book3s_64_get_pteg(vcpu_book3s, slbe, eaddr, second); + ptegp = kvmppc_mmu_book3s_64_get_pteg(vcpu, slbe, eaddr, second); if (kvm_is_error_hva(ptegp)) goto no_page_found; @@ -240,6 +277,13 @@ do_second: for (i=0; i<16; i+=2) { /* Check all relevant fields of 1st dword */ if ((pteg[i] & v_mask) == v_val) { + /* If large page bit is set, check pgsize encoding */ + if (slbe->large && + (vcpu->arch.hflags & BOOK3S_HFLAG_MULTI_PGSIZE)) { + pgsize = decode_pagesize(slbe, pteg[i+1]); + if (pgsize < 0) + continue; + } found = true; break; } @@ -256,13 +300,15 @@ do_second: v = pteg[i]; r = pteg[i+1]; pp = (r & HPTE_R_PP) | key; - eaddr_mask = 0xFFF; + if (r & HPTE_R_PP0) + pp |= 8; gpte->eaddr = eaddr; gpte->vpage = kvmppc_mmu_book3s_64_ea_to_vp(vcpu, eaddr, data); - if (slbe->large) - eaddr_mask = 0xFFFFFF; + + eaddr_mask = (1ull << mmu_pagesize(pgsize)) - 1; gpte->raddr = (r & HPTE_R_RPN & ~eaddr_mask) | (eaddr & eaddr_mask); + gpte->page_size = pgsize; gpte->may_execute = ((r & HPTE_R_N) ? false : true); gpte->may_read = false; gpte->may_write = false; @@ -277,6 +323,7 @@ do_second: case 3: case 5: case 7: + case 10: gpte->may_read = true; break; } @@ -287,30 +334,37 @@ do_second: /* Update PTE R and C bits, so the guest's swapper knows we used the * page */ - if (gpte->may_read) { - /* Set the accessed flag */ + if (gpte->may_read && !(r & HPTE_R_R)) { + /* + * Set the accessed flag. + * We have to write this back with a single byte write + * because another vcpu may be accessing this on + * non-PAPR platforms such as mac99, and this is + * what real hardware does. + */ + char __user *addr = (char __user *) &pteg[i+1]; r |= HPTE_R_R; + put_user(r >> 8, addr + 6); } - if (data && gpte->may_write) { - /* Set the dirty flag -- XXX even if not writing */ + if (iswrite && gpte->may_write && !(r & HPTE_R_C)) { + /* Set the dirty flag */ + /* Use a single byte write */ + char __user *addr = (char __user *) &pteg[i+1]; r |= HPTE_R_C; + put_user(r, addr + 7); } - /* Write back into the PTEG */ - if (pteg[i+1] != r) { - pteg[i+1] = r; - copy_to_user((void __user *)ptegp, pteg, sizeof(pteg)); - } + mutex_unlock(&vcpu->kvm->arch.hpt_mutex); - if (!gpte->may_read) + if (!gpte->may_read || (iswrite && !gpte->may_write)) return -EPERM; return 0; no_page_found: + mutex_unlock(&vcpu->kvm->arch.hpt_mutex); return -ENOENT; no_seg_found: - dprintk("KVM MMU: Trigger segment fault\n"); return -EINVAL; } @@ -345,6 +399,21 @@ static void kvmppc_mmu_book3s_64_slbmte(struct kvm_vcpu *vcpu, u64 rs, u64 rb) slbe->nx = (rs & SLB_VSID_N) ? 1 : 0; slbe->class = (rs & SLB_VSID_C) ? 1 : 0; + slbe->base_page_size = MMU_PAGE_4K; + if (slbe->large) { + if (vcpu->arch.hflags & BOOK3S_HFLAG_MULTI_PGSIZE) { + switch (rs & SLB_VSID_LP) { + case SLB_VSID_LP_00: + slbe->base_page_size = MMU_PAGE_16M; + break; + case SLB_VSID_LP_01: + slbe->base_page_size = MMU_PAGE_64K; + break; + } + } else + slbe->base_page_size = MMU_PAGE_16M; + } + slbe->orige = rb & (ESID_MASK | SLB_ESID_V); slbe->origv = rs; @@ -460,14 +529,45 @@ static void kvmppc_mmu_book3s_64_tlbie(struct kvm_vcpu *vcpu, ulong va, bool large) { u64 mask = 0xFFFFFFFFFULL; + long i; + struct kvm_vcpu *v; dprintk("KVM MMU: tlbie(0x%lx)\n", va); - if (large) - mask = 0xFFFFFF000ULL; - kvmppc_mmu_pte_vflush(vcpu, va >> 12, mask); + /* + * The tlbie instruction changed behaviour starting with + * POWER6. POWER6 and later don't have the large page flag + * in the instruction but in the RB value, along with bits + * indicating page and segment sizes. + */ + if (vcpu->arch.hflags & BOOK3S_HFLAG_NEW_TLBIE) { + /* POWER6 or later */ + if (va & 1) { /* L bit */ + if ((va & 0xf000) == 0x1000) + mask = 0xFFFFFFFF0ULL; /* 64k page */ + else + mask = 0xFFFFFF000ULL; /* 16M page */ + } + } else { + /* older processors, e.g. PPC970 */ + if (large) + mask = 0xFFFFFF000ULL; + } + /* flush this VA on all vcpus */ + kvm_for_each_vcpu(i, v, vcpu->kvm) + kvmppc_mmu_pte_vflush(v, va >> 12, mask); } +#ifdef CONFIG_PPC_64K_PAGES +static int segment_contains_magic_page(struct kvm_vcpu *vcpu, ulong esid) +{ + ulong mp_ea = vcpu->arch.magic_page_ea; + + return mp_ea && !(vcpu->arch.shared->msr & MSR_PR) && + (mp_ea >> SID_SHIFT) == esid; +} +#endif + static int kvmppc_mmu_book3s_64_esid_to_vsid(struct kvm_vcpu *vcpu, ulong esid, u64 *vsid) { @@ -475,11 +575,13 @@ static int kvmppc_mmu_book3s_64_esid_to_vsid(struct kvm_vcpu *vcpu, ulong esid, struct kvmppc_slb *slb; u64 gvsid = esid; ulong mp_ea = vcpu->arch.magic_page_ea; + int pagesize = MMU_PAGE_64K; if (vcpu->arch.shared->msr & (MSR_DR|MSR_IR)) { slb = kvmppc_mmu_book3s_64_find_slbe(vcpu, ea); if (slb) { gvsid = slb->vsid; + pagesize = slb->base_page_size; if (slb->tb) { gvsid <<= SID_SHIFT_1T - SID_SHIFT; gvsid |= esid & ((1ul << (SID_SHIFT_1T - SID_SHIFT)) - 1); @@ -490,28 +592,41 @@ static int kvmppc_mmu_book3s_64_esid_to_vsid(struct kvm_vcpu *vcpu, ulong esid, switch (vcpu->arch.shared->msr & (MSR_DR|MSR_IR)) { case 0: - *vsid = VSID_REAL | esid; + gvsid = VSID_REAL | esid; break; case MSR_IR: - *vsid = VSID_REAL_IR | gvsid; + gvsid |= VSID_REAL_IR; break; case MSR_DR: - *vsid = VSID_REAL_DR | gvsid; + gvsid |= VSID_REAL_DR; break; case MSR_DR|MSR_IR: if (!slb) goto no_slb; - *vsid = gvsid; break; default: BUG(); break; } +#ifdef CONFIG_PPC_64K_PAGES + /* + * Mark this as a 64k segment if the host is using + * 64k pages, the host MMU supports 64k pages and + * the guest segment page size is >= 64k, + * but not if this segment contains the magic page. + */ + if (pagesize >= MMU_PAGE_64K && + mmu_psize_defs[MMU_PAGE_64K].shift && + !segment_contains_magic_page(vcpu, esid)) + gvsid |= VSID_64K; +#endif + if (vcpu->arch.shared->msr & MSR_PR) - *vsid |= VSID_PR; + gvsid |= VSID_PR; + *vsid = gvsid; return 0; no_slb: diff --git a/arch/powerpc/kvm/book3s_64_mmu_host.c b/arch/powerpc/kvm/book3s_64_mmu_host.c index e5240524bf6c..0d513af62bba 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_host.c +++ b/arch/powerpc/kvm/book3s_64_mmu_host.c @@ -27,14 +27,14 @@ #include <asm/machdep.h> #include <asm/mmu_context.h> #include <asm/hw_irq.h> -#include "trace.h" +#include "trace_pr.h" #define PTE_SIZE 12 void kvmppc_mmu_invalidate_pte(struct kvm_vcpu *vcpu, struct hpte_cache *pte) { ppc_md.hpte_invalidate(pte->slot, pte->host_vpn, - MMU_PAGE_4K, MMU_PAGE_4K, MMU_SEGSIZE_256M, + pte->pagesize, pte->pagesize, MMU_SEGSIZE_256M, false); } @@ -78,7 +78,8 @@ static struct kvmppc_sid_map *find_sid_vsid(struct kvm_vcpu *vcpu, u64 gvsid) return NULL; } -int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte) +int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte, + bool iswrite) { unsigned long vpn; pfn_t hpaddr; @@ -90,16 +91,26 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte) int attempt = 0; struct kvmppc_sid_map *map; int r = 0; + int hpsize = MMU_PAGE_4K; + bool writable; + unsigned long mmu_seq; + struct kvm *kvm = vcpu->kvm; + struct hpte_cache *cpte; + unsigned long gfn = orig_pte->raddr >> PAGE_SHIFT; + unsigned long pfn; + + /* used to check for invalidations in progress */ + mmu_seq = kvm->mmu_notifier_seq; + smp_rmb(); /* Get host physical address for gpa */ - hpaddr = kvmppc_gfn_to_pfn(vcpu, orig_pte->raddr >> PAGE_SHIFT); - if (is_error_noslot_pfn(hpaddr)) { - printk(KERN_INFO "Couldn't get guest page for gfn %lx!\n", orig_pte->eaddr); + pfn = kvmppc_gfn_to_pfn(vcpu, gfn, iswrite, &writable); + if (is_error_noslot_pfn(pfn)) { + printk(KERN_INFO "Couldn't get guest page for gfn %lx!\n", gfn); r = -EINVAL; goto out; } - hpaddr <<= PAGE_SHIFT; - hpaddr |= orig_pte->raddr & (~0xfffULL & ~PAGE_MASK); + hpaddr = pfn << PAGE_SHIFT; /* and write the mapping ea -> hpa into the pt */ vcpu->arch.mmu.esid_to_vsid(vcpu, orig_pte->eaddr >> SID_SHIFT, &vsid); @@ -117,20 +128,39 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte) goto out; } - vsid = map->host_vsid; - vpn = hpt_vpn(orig_pte->eaddr, vsid, MMU_SEGSIZE_256M); + vpn = hpt_vpn(orig_pte->eaddr, map->host_vsid, MMU_SEGSIZE_256M); - if (!orig_pte->may_write) - rflags |= HPTE_R_PP; - else - mark_page_dirty(vcpu->kvm, orig_pte->raddr >> PAGE_SHIFT); + kvm_set_pfn_accessed(pfn); + if (!orig_pte->may_write || !writable) + rflags |= PP_RXRX; + else { + mark_page_dirty(vcpu->kvm, gfn); + kvm_set_pfn_dirty(pfn); + } if (!orig_pte->may_execute) rflags |= HPTE_R_N; else - kvmppc_mmu_flush_icache(hpaddr >> PAGE_SHIFT); + kvmppc_mmu_flush_icache(pfn); + + /* + * Use 64K pages if possible; otherwise, on 64K page kernels, + * we need to transfer 4 more bits from guest real to host real addr. + */ + if (vsid & VSID_64K) + hpsize = MMU_PAGE_64K; + else + hpaddr |= orig_pte->raddr & (~0xfffULL & ~PAGE_MASK); + + hash = hpt_hash(vpn, mmu_psize_defs[hpsize].shift, MMU_SEGSIZE_256M); - hash = hpt_hash(vpn, PTE_SIZE, MMU_SEGSIZE_256M); + cpte = kvmppc_mmu_hpte_cache_next(vcpu); + + spin_lock(&kvm->mmu_lock); + if (!cpte || mmu_notifier_retry(kvm, mmu_seq)) { + r = -EAGAIN; + goto out_unlock; + } map_again: hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP); @@ -139,11 +169,11 @@ map_again: if (attempt > 1) if (ppc_md.hpte_remove(hpteg) < 0) { r = -1; - goto out; + goto out_unlock; } ret = ppc_md.hpte_insert(hpteg, vpn, hpaddr, rflags, vflags, - MMU_PAGE_4K, MMU_PAGE_4K, MMU_SEGSIZE_256M); + hpsize, hpsize, MMU_SEGSIZE_256M); if (ret < 0) { /* If we couldn't map a primary PTE, try a secondary */ @@ -152,8 +182,6 @@ map_again: attempt++; goto map_again; } else { - struct hpte_cache *pte = kvmppc_mmu_hpte_cache_next(vcpu); - trace_kvm_book3s_64_mmu_map(rflags, hpteg, vpn, hpaddr, orig_pte); @@ -164,19 +192,37 @@ map_again: hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP); } - pte->slot = hpteg + (ret & 7); - pte->host_vpn = vpn; - pte->pte = *orig_pte; - pte->pfn = hpaddr >> PAGE_SHIFT; + cpte->slot = hpteg + (ret & 7); + cpte->host_vpn = vpn; + cpte->pte = *orig_pte; + cpte->pfn = pfn; + cpte->pagesize = hpsize; - kvmppc_mmu_hpte_cache_map(vcpu, pte); + kvmppc_mmu_hpte_cache_map(vcpu, cpte); + cpte = NULL; } - kvm_release_pfn_clean(hpaddr >> PAGE_SHIFT); + +out_unlock: + spin_unlock(&kvm->mmu_lock); + kvm_release_pfn_clean(pfn); + if (cpte) + kvmppc_mmu_hpte_cache_free(cpte); out: return r; } +void kvmppc_mmu_unmap_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *pte) +{ + u64 mask = 0xfffffffffULL; + u64 vsid; + + vcpu->arch.mmu.esid_to_vsid(vcpu, pte->eaddr >> SID_SHIFT, &vsid); + if (vsid & VSID_64K) + mask = 0xffffffff0ULL; + kvmppc_mmu_pte_vflush(vcpu, pte->vpage, mask); +} + static struct kvmppc_sid_map *create_sid_map(struct kvm_vcpu *vcpu, u64 gvsid) { struct kvmppc_sid_map *map; @@ -291,6 +337,12 @@ int kvmppc_mmu_map_segment(struct kvm_vcpu *vcpu, ulong eaddr) slb_vsid &= ~SLB_VSID_KP; slb_esid |= slb_index; +#ifdef CONFIG_PPC_64K_PAGES + /* Set host segment base page size to 64K if possible */ + if (gvsid & VSID_64K) + slb_vsid |= mmu_psize_defs[MMU_PAGE_64K].sllp; +#endif + svcpu->slb[slb_index].esid = slb_esid; svcpu->slb[slb_index].vsid = slb_vsid; @@ -326,7 +378,7 @@ void kvmppc_mmu_flush_segments(struct kvm_vcpu *vcpu) svcpu_put(svcpu); } -void kvmppc_mmu_destroy(struct kvm_vcpu *vcpu) +void kvmppc_mmu_destroy_pr(struct kvm_vcpu *vcpu) { kvmppc_mmu_hpte_destroy(vcpu); __destroy_context(to_book3s(vcpu)->context_id[0]); diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c index 043eec8461e7..f3ff587a8b7d 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_hv.c +++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c @@ -260,10 +260,6 @@ int kvmppc_mmu_hv_init(void) return 0; } -void kvmppc_mmu_destroy(struct kvm_vcpu *vcpu) -{ -} - static void kvmppc_mmu_book3s_64_hv_reset_msr(struct kvm_vcpu *vcpu) { kvmppc_set_msr(vcpu, MSR_SF | MSR_ME); @@ -451,7 +447,7 @@ static unsigned long kvmppc_mmu_get_real_addr(unsigned long v, unsigned long r, } static int kvmppc_mmu_book3s_64_hv_xlate(struct kvm_vcpu *vcpu, gva_t eaddr, - struct kvmppc_pte *gpte, bool data) + struct kvmppc_pte *gpte, bool data, bool iswrite) { struct kvm *kvm = vcpu->kvm; struct kvmppc_slb *slbe; @@ -906,21 +902,22 @@ static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp, return 0; } -int kvm_unmap_hva(struct kvm *kvm, unsigned long hva) +int kvm_unmap_hva_hv(struct kvm *kvm, unsigned long hva) { if (kvm->arch.using_mmu_notifiers) kvm_handle_hva(kvm, hva, kvm_unmap_rmapp); return 0; } -int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end) +int kvm_unmap_hva_range_hv(struct kvm *kvm, unsigned long start, unsigned long end) { if (kvm->arch.using_mmu_notifiers) kvm_handle_hva_range(kvm, start, end, kvm_unmap_rmapp); return 0; } -void kvmppc_core_flush_memslot(struct kvm *kvm, struct kvm_memory_slot *memslot) +void kvmppc_core_flush_memslot_hv(struct kvm *kvm, + struct kvm_memory_slot *memslot) { unsigned long *rmapp; unsigned long gfn; @@ -994,7 +991,7 @@ static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp, return ret; } -int kvm_age_hva(struct kvm *kvm, unsigned long hva) +int kvm_age_hva_hv(struct kvm *kvm, unsigned long hva) { if (!kvm->arch.using_mmu_notifiers) return 0; @@ -1032,14 +1029,14 @@ static int kvm_test_age_rmapp(struct kvm *kvm, unsigned long *rmapp, return ret; } -int kvm_test_age_hva(struct kvm *kvm, unsigned long hva) +int kvm_test_age_hva_hv(struct kvm *kvm, unsigned long hva) { if (!kvm->arch.using_mmu_notifiers) return 0; return kvm_handle_hva(kvm, hva, kvm_test_age_rmapp); } -void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte) +void kvm_set_spte_hva_hv(struct kvm *kvm, unsigned long hva, pte_t pte) { if (!kvm->arch.using_mmu_notifiers) return; @@ -1512,9 +1509,8 @@ static ssize_t kvm_htab_write(struct file *file, const char __user *buf, kvm->arch.vrma_slb_v = senc | SLB_VSID_B_1T | (VRMA_VSID << SLB_VSID_SHIFT_1T); - lpcr = kvm->arch.lpcr & ~LPCR_VRMASD; - lpcr |= senc << (LPCR_VRMASD_SH - 4); - kvm->arch.lpcr = lpcr; + lpcr = senc << (LPCR_VRMASD_SH - 4); + kvmppc_update_lpcr(kvm, lpcr, LPCR_VRMASD); rma_setup = 1; } ++i; diff --git a/arch/powerpc/kvm/book3s_64_vio_hv.c b/arch/powerpc/kvm/book3s_64_vio_hv.c index 30c2f3b134c6..2c25f5412bdb 100644 --- a/arch/powerpc/kvm/book3s_64_vio_hv.c +++ b/arch/powerpc/kvm/book3s_64_vio_hv.c @@ -74,3 +74,4 @@ long kvmppc_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn, /* Didn't find the liobn, punt it to userspace */ return H_TOO_HARD; } +EXPORT_SYMBOL_GPL(kvmppc_h_put_tce); diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c index 360ce68c9809..99d40f8977e8 100644 --- a/arch/powerpc/kvm/book3s_emulate.c +++ b/arch/powerpc/kvm/book3s_emulate.c @@ -86,8 +86,8 @@ static bool spr_allowed(struct kvm_vcpu *vcpu, enum priv_level level) return true; } -int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, - unsigned int inst, int *advance) +int kvmppc_core_emulate_op_pr(struct kvm_run *run, struct kvm_vcpu *vcpu, + unsigned int inst, int *advance) { int emulated = EMULATE_DONE; int rt = get_rt(inst); @@ -172,7 +172,7 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, vcpu->arch.mmu.tlbie(vcpu, addr, large); break; } -#ifdef CONFIG_KVM_BOOK3S_64_PR +#ifdef CONFIG_PPC_BOOK3S_64 case OP_31_XOP_FAKE_SC1: { /* SC 1 papr hypercalls */ @@ -267,12 +267,9 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, r = kvmppc_st(vcpu, &addr, 32, zeros, true); if ((r == -ENOENT) || (r == -EPERM)) { - struct kvmppc_book3s_shadow_vcpu *svcpu; - - svcpu = svcpu_get(vcpu); *advance = 0; vcpu->arch.shared->dar = vaddr; - svcpu->fault_dar = vaddr; + vcpu->arch.fault_dar = vaddr; dsisr = DSISR_ISSTORE; if (r == -ENOENT) @@ -281,8 +278,7 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, dsisr |= DSISR_PROTFAULT; vcpu->arch.shared->dsisr = dsisr; - svcpu->fault_dsisr = dsisr; - svcpu_put(svcpu); + vcpu->arch.fault_dsisr = dsisr; kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_DATA_STORAGE); @@ -349,7 +345,7 @@ static struct kvmppc_bat *kvmppc_find_bat(struct kvm_vcpu *vcpu, int sprn) return bat; } -int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val) +int kvmppc_core_emulate_mtspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val) { int emulated = EMULATE_DONE; @@ -472,7 +468,7 @@ unprivileged: return emulated; } -int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val) +int kvmppc_core_emulate_mfspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val) { int emulated = EMULATE_DONE; diff --git a/arch/powerpc/kvm/book3s_exports.c b/arch/powerpc/kvm/book3s_exports.c index 7057a02f0906..852989a9bad3 100644 --- a/arch/powerpc/kvm/book3s_exports.c +++ b/arch/powerpc/kvm/book3s_exports.c @@ -20,9 +20,10 @@ #include <linux/export.h> #include <asm/kvm_book3s.h> -#ifdef CONFIG_KVM_BOOK3S_64_HV +#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE EXPORT_SYMBOL_GPL(kvmppc_hv_entry_trampoline); -#else +#endif +#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE EXPORT_SYMBOL_GPL(kvmppc_entry_trampoline); EXPORT_SYMBOL_GPL(kvmppc_load_up_fpu); #ifdef CONFIG_ALTIVEC diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 62a2b5ab08ed..072287f1c3bc 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -52,6 +52,9 @@ #include <linux/vmalloc.h> #include <linux/highmem.h> #include <linux/hugetlb.h> +#include <linux/module.h> + +#include "book3s.h" /* #define EXIT_DEBUG */ /* #define EXIT_DEBUG_SIMPLE */ @@ -66,7 +69,7 @@ static void kvmppc_end_cede(struct kvm_vcpu *vcpu); static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu); -void kvmppc_fast_vcpu_kick(struct kvm_vcpu *vcpu) +static void kvmppc_fast_vcpu_kick_hv(struct kvm_vcpu *vcpu) { int me; int cpu = vcpu->cpu; @@ -125,7 +128,7 @@ void kvmppc_fast_vcpu_kick(struct kvm_vcpu *vcpu) * purely defensive; they should never fail.) */ -void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu) +static void kvmppc_core_vcpu_load_hv(struct kvm_vcpu *vcpu, int cpu) { struct kvmppc_vcore *vc = vcpu->arch.vcore; @@ -143,7 +146,7 @@ void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu) spin_unlock(&vcpu->arch.tbacct_lock); } -void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu) +static void kvmppc_core_vcpu_put_hv(struct kvm_vcpu *vcpu) { struct kvmppc_vcore *vc = vcpu->arch.vcore; @@ -155,17 +158,46 @@ void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu) spin_unlock(&vcpu->arch.tbacct_lock); } -void kvmppc_set_msr(struct kvm_vcpu *vcpu, u64 msr) +static void kvmppc_set_msr_hv(struct kvm_vcpu *vcpu, u64 msr) { vcpu->arch.shregs.msr = msr; kvmppc_end_cede(vcpu); } -void kvmppc_set_pvr(struct kvm_vcpu *vcpu, u32 pvr) +void kvmppc_set_pvr_hv(struct kvm_vcpu *vcpu, u32 pvr) { vcpu->arch.pvr = pvr; } +int kvmppc_set_arch_compat(struct kvm_vcpu *vcpu, u32 arch_compat) +{ + unsigned long pcr = 0; + struct kvmppc_vcore *vc = vcpu->arch.vcore; + + if (arch_compat) { + if (!cpu_has_feature(CPU_FTR_ARCH_206)) + return -EINVAL; /* 970 has no compat mode support */ + + switch (arch_compat) { + case PVR_ARCH_205: + pcr = PCR_ARCH_205; + break; + case PVR_ARCH_206: + case PVR_ARCH_206p: + break; + default: + return -EINVAL; + } + } + + spin_lock(&vc->lock); + vc->arch_compat = arch_compat; + vc->pcr = pcr; + spin_unlock(&vc->lock); + + return 0; +} + void kvmppc_dump_regs(struct kvm_vcpu *vcpu) { int r; @@ -195,7 +227,7 @@ void kvmppc_dump_regs(struct kvm_vcpu *vcpu) pr_err(" ESID = %.16llx VSID = %.16llx\n", vcpu->arch.slb[r].orige, vcpu->arch.slb[r].origv); pr_err("lpcr = %.16lx sdr1 = %.16lx last_inst = %.8x\n", - vcpu->kvm->arch.lpcr, vcpu->kvm->arch.sdr1, + vcpu->arch.vcore->lpcr, vcpu->kvm->arch.sdr1, vcpu->arch.last_inst); } @@ -489,7 +521,7 @@ static void kvmppc_create_dtl_entry(struct kvm_vcpu *vcpu, memset(dt, 0, sizeof(struct dtl_entry)); dt->dispatch_reason = 7; dt->processor_id = vc->pcpu + vcpu->arch.ptid; - dt->timebase = now; + dt->timebase = now + vc->tb_offset; dt->enqueue_to_dispatch_time = stolen; dt->srr0 = kvmppc_get_pc(vcpu); dt->srr1 = vcpu->arch.shregs.msr; @@ -538,6 +570,15 @@ int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu) } break; case H_CONFER: + target = kvmppc_get_gpr(vcpu, 4); + if (target == -1) + break; + tvcpu = kvmppc_find_vcpu(vcpu->kvm, target); + if (!tvcpu) { + ret = H_PARAMETER; + break; + } + kvm_vcpu_yield_to(tvcpu); break; case H_REGISTER_VPA: ret = do_h_register_vpa(vcpu, kvmppc_get_gpr(vcpu, 4), @@ -576,8 +617,8 @@ int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu) return RESUME_GUEST; } -static int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, - struct task_struct *tsk) +static int kvmppc_handle_exit_hv(struct kvm_run *run, struct kvm_vcpu *vcpu, + struct task_struct *tsk) { int r = RESUME_HOST; @@ -671,16 +712,16 @@ static int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, printk(KERN_EMERG "trap=0x%x | pc=0x%lx | msr=0x%llx\n", vcpu->arch.trap, kvmppc_get_pc(vcpu), vcpu->arch.shregs.msr); + run->hw.hardware_exit_reason = vcpu->arch.trap; r = RESUME_HOST; - BUG(); break; } return r; } -int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, - struct kvm_sregs *sregs) +static int kvm_arch_vcpu_ioctl_get_sregs_hv(struct kvm_vcpu *vcpu, + struct kvm_sregs *sregs) { int i; @@ -694,12 +735,12 @@ int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, return 0; } -int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, - struct kvm_sregs *sregs) +static int kvm_arch_vcpu_ioctl_set_sregs_hv(struct kvm_vcpu *vcpu, + struct kvm_sregs *sregs) { int i, j; - kvmppc_set_pvr(vcpu, sregs->pvr); + kvmppc_set_pvr_hv(vcpu, sregs->pvr); j = 0; for (i = 0; i < vcpu->arch.slb_nr; i++) { @@ -714,7 +755,23 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, return 0; } -int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id, union kvmppc_one_reg *val) +static void kvmppc_set_lpcr(struct kvm_vcpu *vcpu, u64 new_lpcr) +{ + struct kvmppc_vcore *vc = vcpu->arch.vcore; + u64 mask; + + spin_lock(&vc->lock); + /* + * Userspace can only modify DPFD (default prefetch depth), + * ILE (interrupt little-endian) and TC (translation control). + */ + mask = LPCR_DPFD | LPCR_ILE | LPCR_TC; + vc->lpcr = (vc->lpcr & ~mask) | (new_lpcr & mask); + spin_unlock(&vc->lock); +} + +static int kvmppc_get_one_reg_hv(struct kvm_vcpu *vcpu, u64 id, + union kvmppc_one_reg *val) { int r = 0; long int i; @@ -749,6 +806,12 @@ int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id, union kvmppc_one_reg *val) i = id - KVM_REG_PPC_PMC1; *val = get_reg_val(id, vcpu->arch.pmc[i]); break; + case KVM_REG_PPC_SIAR: + *val = get_reg_val(id, vcpu->arch.siar); + break; + case KVM_REG_PPC_SDAR: + *val = get_reg_val(id, vcpu->arch.sdar); + break; #ifdef CONFIG_VSX case KVM_REG_PPC_FPR0 ... KVM_REG_PPC_FPR31: if (cpu_has_feature(CPU_FTR_VSX)) { @@ -787,6 +850,18 @@ int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id, union kvmppc_one_reg *val) val->vpaval.length = vcpu->arch.dtl.len; spin_unlock(&vcpu->arch.vpa_update_lock); break; + case KVM_REG_PPC_TB_OFFSET: + *val = get_reg_val(id, vcpu->arch.vcore->tb_offset); + break; + case KVM_REG_PPC_LPCR: + *val = get_reg_val(id, vcpu->arch.vcore->lpcr); + break; + case KVM_REG_PPC_PPR: + *val = get_reg_val(id, vcpu->arch.ppr); + break; + case KVM_REG_PPC_ARCH_COMPAT: + *val = get_reg_val(id, vcpu->arch.vcore->arch_compat); + break; default: r = -EINVAL; break; @@ -795,7 +870,8 @@ int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id, union kvmppc_one_reg *val) return r; } -int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id, union kvmppc_one_reg *val) +static int kvmppc_set_one_reg_hv(struct kvm_vcpu *vcpu, u64 id, + union kvmppc_one_reg *val) { int r = 0; long int i; @@ -833,6 +909,12 @@ int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id, union kvmppc_one_reg *val) i = id - KVM_REG_PPC_PMC1; vcpu->arch.pmc[i] = set_reg_val(id, *val); break; + case KVM_REG_PPC_SIAR: + vcpu->arch.siar = set_reg_val(id, *val); + break; + case KVM_REG_PPC_SDAR: + vcpu->arch.sdar = set_reg_val(id, *val); + break; #ifdef CONFIG_VSX case KVM_REG_PPC_FPR0 ... KVM_REG_PPC_FPR31: if (cpu_has_feature(CPU_FTR_VSX)) { @@ -880,6 +962,20 @@ int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id, union kvmppc_one_reg *val) len -= len % sizeof(struct dtl_entry); r = set_vpa(vcpu, &vcpu->arch.dtl, addr, len); break; + case KVM_REG_PPC_TB_OFFSET: + /* round up to multiple of 2^24 */ + vcpu->arch.vcore->tb_offset = + ALIGN(set_reg_val(id, *val), 1UL << 24); + break; + case KVM_REG_PPC_LPCR: + kvmppc_set_lpcr(vcpu, set_reg_val(id, *val)); + break; + case KVM_REG_PPC_PPR: + vcpu->arch.ppr = set_reg_val(id, *val); + break; + case KVM_REG_PPC_ARCH_COMPAT: + r = kvmppc_set_arch_compat(vcpu, set_reg_val(id, *val)); + break; default: r = -EINVAL; break; @@ -888,14 +984,8 @@ int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id, union kvmppc_one_reg *val) return r; } -int kvmppc_core_check_processor_compat(void) -{ - if (cpu_has_feature(CPU_FTR_HVMODE)) - return 0; - return -EIO; -} - -struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) +static struct kvm_vcpu *kvmppc_core_vcpu_create_hv(struct kvm *kvm, + unsigned int id) { struct kvm_vcpu *vcpu; int err = -EINVAL; @@ -919,8 +1009,7 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) vcpu->arch.mmcr[0] = MMCR0_FC; vcpu->arch.ctrl = CTRL_RUNLATCH; /* default to host PVR, since we can't spoof it */ - vcpu->arch.pvr = mfspr(SPRN_PVR); - kvmppc_set_pvr(vcpu, vcpu->arch.pvr); + kvmppc_set_pvr_hv(vcpu, mfspr(SPRN_PVR)); spin_lock_init(&vcpu->arch.vpa_update_lock); spin_lock_init(&vcpu->arch.tbacct_lock); vcpu->arch.busy_preempt = TB_NIL; @@ -940,6 +1029,7 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) spin_lock_init(&vcore->lock); init_waitqueue_head(&vcore->wq); vcore->preempt_tb = TB_NIL; + vcore->lpcr = kvm->arch.lpcr; } kvm->arch.vcores[core] = vcore; kvm->arch.online_vcores++; @@ -972,7 +1062,7 @@ static void unpin_vpa(struct kvm *kvm, struct kvmppc_vpa *vpa) vpa->dirty); } -void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu) +static void kvmppc_core_vcpu_free_hv(struct kvm_vcpu *vcpu) { spin_lock(&vcpu->arch.vpa_update_lock); unpin_vpa(vcpu->kvm, &vcpu->arch.dtl); @@ -983,6 +1073,12 @@ void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu) kmem_cache_free(kvm_vcpu_cache, vcpu); } +static int kvmppc_core_check_requests_hv(struct kvm_vcpu *vcpu) +{ + /* Indicate we want to get back into the guest */ + return 1; +} + static void kvmppc_set_timer(struct kvm_vcpu *vcpu) { unsigned long dec_nsec, now; @@ -1264,8 +1360,8 @@ static void kvmppc_run_core(struct kvmppc_vcore *vc) ret = RESUME_GUEST; if (vcpu->arch.trap) - ret = kvmppc_handle_exit(vcpu->arch.kvm_run, vcpu, - vcpu->arch.run_task); + ret = kvmppc_handle_exit_hv(vcpu->arch.kvm_run, vcpu, + vcpu->arch.run_task); vcpu->arch.ret = ret; vcpu->arch.trap = 0; @@ -1424,7 +1520,7 @@ static int kvmppc_run_vcpu(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) return vcpu->arch.ret; } -int kvmppc_vcpu_run(struct kvm_run *run, struct kvm_vcpu *vcpu) +static int kvmppc_vcpu_run_hv(struct kvm_run *run, struct kvm_vcpu *vcpu) { int r; int srcu_idx; @@ -1546,7 +1642,8 @@ static const struct file_operations kvm_rma_fops = { .release = kvm_rma_release, }; -long kvm_vm_ioctl_allocate_rma(struct kvm *kvm, struct kvm_allocate_rma *ret) +static long kvm_vm_ioctl_allocate_rma(struct kvm *kvm, + struct kvm_allocate_rma *ret) { long fd; struct kvm_rma_info *ri; @@ -1592,7 +1689,8 @@ static void kvmppc_add_seg_page_size(struct kvm_ppc_one_seg_page_size **sps, (*sps)++; } -int kvm_vm_ioctl_get_smmu_info(struct kvm *kvm, struct kvm_ppc_smmu_info *info) +static int kvm_vm_ioctl_get_smmu_info_hv(struct kvm *kvm, + struct kvm_ppc_smmu_info *info) { struct kvm_ppc_one_seg_page_size *sps; @@ -1613,7 +1711,8 @@ int kvm_vm_ioctl_get_smmu_info(struct kvm *kvm, struct kvm_ppc_smmu_info *info) /* * Get (and clear) the dirty memory log for a memory slot. */ -int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log) +static int kvm_vm_ioctl_get_dirty_log_hv(struct kvm *kvm, + struct kvm_dirty_log *log) { struct kvm_memory_slot *memslot; int r; @@ -1667,8 +1766,8 @@ static void unpin_slot(struct kvm_memory_slot *memslot) } } -void kvmppc_core_free_memslot(struct kvm_memory_slot *free, - struct kvm_memory_slot *dont) +static void kvmppc_core_free_memslot_hv(struct kvm_memory_slot *free, + struct kvm_memory_slot *dont) { if (!dont || free->arch.rmap != dont->arch.rmap) { vfree(free->arch.rmap); @@ -1681,8 +1780,8 @@ void kvmppc_core_free_memslot(struct kvm_memory_slot *free, } } -int kvmppc_core_create_memslot(struct kvm_memory_slot *slot, - unsigned long npages) +static int kvmppc_core_create_memslot_hv(struct kvm_memory_slot *slot, + unsigned long npages) { slot->arch.rmap = vzalloc(npages * sizeof(*slot->arch.rmap)); if (!slot->arch.rmap) @@ -1692,9 +1791,9 @@ int kvmppc_core_create_memslot(struct kvm_memory_slot *slot, return 0; } -int kvmppc_core_prepare_memory_region(struct kvm *kvm, - struct kvm_memory_slot *memslot, - struct kvm_userspace_memory_region *mem) +static int kvmppc_core_prepare_memory_region_hv(struct kvm *kvm, + struct kvm_memory_slot *memslot, + struct kvm_userspace_memory_region *mem) { unsigned long *phys; @@ -1710,9 +1809,9 @@ int kvmppc_core_prepare_memory_region(struct kvm *kvm, return 0; } -void kvmppc_core_commit_memory_region(struct kvm *kvm, - struct kvm_userspace_memory_region *mem, - const struct kvm_memory_slot *old) +static void kvmppc_core_commit_memory_region_hv(struct kvm *kvm, + struct kvm_userspace_memory_region *mem, + const struct kvm_memory_slot *old) { unsigned long npages = mem->memory_size >> PAGE_SHIFT; struct kvm_memory_slot *memslot; @@ -1729,6 +1828,37 @@ void kvmppc_core_commit_memory_region(struct kvm *kvm, } } +/* + * Update LPCR values in kvm->arch and in vcores. + * Caller must hold kvm->lock. + */ +void kvmppc_update_lpcr(struct kvm *kvm, unsigned long lpcr, unsigned long mask) +{ + long int i; + u32 cores_done = 0; + + if ((kvm->arch.lpcr & mask) == lpcr) + return; + + kvm->arch.lpcr = (kvm->arch.lpcr & ~mask) | lpcr; + + for (i = 0; i < KVM_MAX_VCORES; ++i) { + struct kvmppc_vcore *vc = kvm->arch.vcores[i]; + if (!vc) + continue; + spin_lock(&vc->lock); + vc->lpcr = (vc->lpcr & ~mask) | lpcr; + spin_unlock(&vc->lock); + if (++cores_done >= kvm->arch.online_vcores) + break; + } +} + +static void kvmppc_mmu_destroy_hv(struct kvm_vcpu *vcpu) +{ + return; +} + static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu) { int err = 0; @@ -1737,7 +1867,8 @@ static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu) unsigned long hva; struct kvm_memory_slot *memslot; struct vm_area_struct *vma; - unsigned long lpcr, senc; + unsigned long lpcr = 0, senc; + unsigned long lpcr_mask = 0; unsigned long psize, porder; unsigned long rma_size; unsigned long rmls; @@ -1802,9 +1933,9 @@ static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu) senc = slb_pgsize_encoding(psize); kvm->arch.vrma_slb_v = senc | SLB_VSID_B_1T | (VRMA_VSID << SLB_VSID_SHIFT_1T); - lpcr = kvm->arch.lpcr & ~LPCR_VRMASD; - lpcr |= senc << (LPCR_VRMASD_SH - 4); - kvm->arch.lpcr = lpcr; + lpcr_mask = LPCR_VRMASD; + /* the -4 is to account for senc values starting at 0x10 */ + lpcr = senc << (LPCR_VRMASD_SH - 4); /* Create HPTEs in the hash page table for the VRMA */ kvmppc_map_vrma(vcpu, memslot, porder); @@ -1825,23 +1956,21 @@ static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu) kvm->arch.rma = ri; /* Update LPCR and RMOR */ - lpcr = kvm->arch.lpcr; if (cpu_has_feature(CPU_FTR_ARCH_201)) { /* PPC970; insert RMLS value (split field) in HID4 */ - lpcr &= ~((1ul << HID4_RMLS0_SH) | - (3ul << HID4_RMLS2_SH)); - lpcr |= ((rmls >> 2) << HID4_RMLS0_SH) | + lpcr_mask = (1ul << HID4_RMLS0_SH) | + (3ul << HID4_RMLS2_SH) | HID4_RMOR; + lpcr = ((rmls >> 2) << HID4_RMLS0_SH) | ((rmls & 3) << HID4_RMLS2_SH); /* RMOR is also in HID4 */ lpcr |= ((ri->base_pfn >> (26 - PAGE_SHIFT)) & 0xffff) << HID4_RMOR_SH; } else { /* POWER7 */ - lpcr &= ~(LPCR_VPM0 | LPCR_VRMA_L); - lpcr |= rmls << LPCR_RMLS_SH; + lpcr_mask = LPCR_VPM0 | LPCR_VRMA_L | LPCR_RMLS; + lpcr = rmls << LPCR_RMLS_SH; kvm->arch.rmor = ri->base_pfn << PAGE_SHIFT; } - kvm->arch.lpcr = lpcr; pr_info("KVM: Using RMO at %lx size %lx (LPCR = %lx)\n", ri->base_pfn << PAGE_SHIFT, rma_size, lpcr); @@ -1860,6 +1989,8 @@ static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu) } } + kvmppc_update_lpcr(kvm, lpcr, lpcr_mask); + /* Order updates to kvm->arch.lpcr etc. vs. rma_setup_done */ smp_wmb(); kvm->arch.rma_setup_done = 1; @@ -1875,7 +2006,7 @@ static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu) goto out_srcu; } -int kvmppc_core_init_vm(struct kvm *kvm) +static int kvmppc_core_init_vm_hv(struct kvm *kvm) { unsigned long lpcr, lpid; @@ -1893,9 +2024,6 @@ int kvmppc_core_init_vm(struct kvm *kvm) */ cpumask_setall(&kvm->arch.need_tlb_flush); - INIT_LIST_HEAD(&kvm->arch.spapr_tce_tables); - INIT_LIST_HEAD(&kvm->arch.rtas_tokens); - kvm->arch.rma = NULL; kvm->arch.host_sdr1 = mfspr(SPRN_SDR1); @@ -1931,61 +2059,162 @@ int kvmppc_core_init_vm(struct kvm *kvm) return 0; } -void kvmppc_core_destroy_vm(struct kvm *kvm) +static void kvmppc_free_vcores(struct kvm *kvm) +{ + long int i; + + for (i = 0; i < KVM_MAX_VCORES; ++i) + kfree(kvm->arch.vcores[i]); + kvm->arch.online_vcores = 0; +} + +static void kvmppc_core_destroy_vm_hv(struct kvm *kvm) { uninhibit_secondary_onlining(); + kvmppc_free_vcores(kvm); if (kvm->arch.rma) { kvm_release_rma(kvm->arch.rma); kvm->arch.rma = NULL; } - kvmppc_rtas_tokens_free(kvm); - kvmppc_free_hpt(kvm); - WARN_ON(!list_empty(&kvm->arch.spapr_tce_tables)); } -/* These are stubs for now */ -void kvmppc_mmu_pte_pflush(struct kvm_vcpu *vcpu, ulong pa_start, ulong pa_end) +/* We don't need to emulate any privileged instructions or dcbz */ +static int kvmppc_core_emulate_op_hv(struct kvm_run *run, struct kvm_vcpu *vcpu, + unsigned int inst, int *advance) { + return EMULATE_FAIL; } -/* We don't need to emulate any privileged instructions or dcbz */ -int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, - unsigned int inst, int *advance) +static int kvmppc_core_emulate_mtspr_hv(struct kvm_vcpu *vcpu, int sprn, + ulong spr_val) { return EMULATE_FAIL; } -int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val) +static int kvmppc_core_emulate_mfspr_hv(struct kvm_vcpu *vcpu, int sprn, + ulong *spr_val) { return EMULATE_FAIL; } -int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val) +static int kvmppc_core_check_processor_compat_hv(void) { - return EMULATE_FAIL; + if (!cpu_has_feature(CPU_FTR_HVMODE)) + return -EIO; + return 0; } -static int kvmppc_book3s_hv_init(void) +static long kvm_arch_vm_ioctl_hv(struct file *filp, + unsigned int ioctl, unsigned long arg) { - int r; + struct kvm *kvm __maybe_unused = filp->private_data; + void __user *argp = (void __user *)arg; + long r; - r = kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE); + switch (ioctl) { - if (r) + case KVM_ALLOCATE_RMA: { + struct kvm_allocate_rma rma; + struct kvm *kvm = filp->private_data; + + r = kvm_vm_ioctl_allocate_rma(kvm, &rma); + if (r >= 0 && copy_to_user(argp, &rma, sizeof(rma))) + r = -EFAULT; + break; + } + + case KVM_PPC_ALLOCATE_HTAB: { + u32 htab_order; + + r = -EFAULT; + if (get_user(htab_order, (u32 __user *)argp)) + break; + r = kvmppc_alloc_reset_hpt(kvm, &htab_order); + if (r) + break; + r = -EFAULT; + if (put_user(htab_order, (u32 __user *)argp)) + break; + r = 0; + break; + } + + case KVM_PPC_GET_HTAB_FD: { + struct kvm_get_htab_fd ghf; + + r = -EFAULT; + if (copy_from_user(&ghf, argp, sizeof(ghf))) + break; + r = kvm_vm_ioctl_get_htab_fd(kvm, &ghf); + break; + } + + default: + r = -ENOTTY; + } + + return r; +} + +static struct kvmppc_ops kvm_ops_hv = { + .get_sregs = kvm_arch_vcpu_ioctl_get_sregs_hv, + .set_sregs = kvm_arch_vcpu_ioctl_set_sregs_hv, + .get_one_reg = kvmppc_get_one_reg_hv, + .set_one_reg = kvmppc_set_one_reg_hv, + .vcpu_load = kvmppc_core_vcpu_load_hv, + .vcpu_put = kvmppc_core_vcpu_put_hv, + .set_msr = kvmppc_set_msr_hv, + .vcpu_run = kvmppc_vcpu_run_hv, + .vcpu_create = kvmppc_core_vcpu_create_hv, + .vcpu_free = kvmppc_core_vcpu_free_hv, + .check_requests = kvmppc_core_check_requests_hv, + .get_dirty_log = kvm_vm_ioctl_get_dirty_log_hv, + .flush_memslot = kvmppc_core_flush_memslot_hv, + .prepare_memory_region = kvmppc_core_prepare_memory_region_hv, + .commit_memory_region = kvmppc_core_commit_memory_region_hv, + .unmap_hva = kvm_unmap_hva_hv, + .unmap_hva_range = kvm_unmap_hva_range_hv, + .age_hva = kvm_age_hva_hv, + .test_age_hva = kvm_test_age_hva_hv, + .set_spte_hva = kvm_set_spte_hva_hv, + .mmu_destroy = kvmppc_mmu_destroy_hv, + .free_memslot = kvmppc_core_free_memslot_hv, + .create_memslot = kvmppc_core_create_memslot_hv, + .init_vm = kvmppc_core_init_vm_hv, + .destroy_vm = kvmppc_core_destroy_vm_hv, + .get_smmu_info = kvm_vm_ioctl_get_smmu_info_hv, + .emulate_op = kvmppc_core_emulate_op_hv, + .emulate_mtspr = kvmppc_core_emulate_mtspr_hv, + .emulate_mfspr = kvmppc_core_emulate_mfspr_hv, + .fast_vcpu_kick = kvmppc_fast_vcpu_kick_hv, + .arch_vm_ioctl = kvm_arch_vm_ioctl_hv, +}; + +static int kvmppc_book3s_init_hv(void) +{ + int r; + /* + * FIXME!! Do we need to check on all cpus ? + */ + r = kvmppc_core_check_processor_compat_hv(); + if (r < 0) return r; - r = kvmppc_mmu_hv_init(); + kvm_ops_hv.owner = THIS_MODULE; + kvmppc_hv_ops = &kvm_ops_hv; + r = kvmppc_mmu_hv_init(); return r; } -static void kvmppc_book3s_hv_exit(void) +static void kvmppc_book3s_exit_hv(void) { - kvm_exit(); + kvmppc_hv_ops = NULL; } -module_init(kvmppc_book3s_hv_init); -module_exit(kvmppc_book3s_hv_exit); +module_init(kvmppc_book3s_init_hv); +module_exit(kvmppc_book3s_exit_hv); +MODULE_LICENSE("GPL"); diff --git a/arch/powerpc/kvm/book3s_hv_interrupts.S b/arch/powerpc/kvm/book3s_hv_interrupts.S index 37f1cc417ca0..928142c64cb0 100644 --- a/arch/powerpc/kvm/book3s_hv_interrupts.S +++ b/arch/powerpc/kvm/book3s_hv_interrupts.S @@ -158,9 +158,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201) * Interrupts are enabled again at this point. */ -.global kvmppc_handler_highmem -kvmppc_handler_highmem: - /* * Register usage at this point: * diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index c71103b8a748..bc8de75b1925 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S @@ -33,30 +33,6 @@ #error Need to fix lppaca and SLB shadow accesses in little endian mode #endif -/***************************************************************************** - * * - * Real Mode handlers that need to be in the linear mapping * - * * - ****************************************************************************/ - - .globl kvmppc_skip_interrupt -kvmppc_skip_interrupt: - mfspr r13,SPRN_SRR0 - addi r13,r13,4 - mtspr SPRN_SRR0,r13 - GET_SCRATCH0(r13) - rfid - b . - - .globl kvmppc_skip_Hinterrupt -kvmppc_skip_Hinterrupt: - mfspr r13,SPRN_HSRR0 - addi r13,r13,4 - mtspr SPRN_HSRR0,r13 - GET_SCRATCH0(r13) - hrfid - b . - /* * Call kvmppc_hv_entry in real mode. * Must be called with interrupts hard-disabled. @@ -66,8 +42,11 @@ kvmppc_skip_Hinterrupt: * LR = return address to continue at after eventually re-enabling MMU */ _GLOBAL(kvmppc_hv_entry_trampoline) + mflr r0 + std r0, PPC_LR_STKOFF(r1) + stdu r1, -112(r1) mfmsr r10 - LOAD_REG_ADDR(r5, kvmppc_hv_entry) + LOAD_REG_ADDR(r5, kvmppc_call_hv_entry) li r0,MSR_RI andc r0,r10,r0 li r6,MSR_IR | MSR_DR @@ -77,11 +56,103 @@ _GLOBAL(kvmppc_hv_entry_trampoline) mtsrr1 r6 RFI -/****************************************************************************** - * * - * Entry code * - * * - *****************************************************************************/ +kvmppc_call_hv_entry: + bl kvmppc_hv_entry + + /* Back from guest - restore host state and return to caller */ + + /* Restore host DABR and DABRX */ + ld r5,HSTATE_DABR(r13) + li r6,7 + mtspr SPRN_DABR,r5 + mtspr SPRN_DABRX,r6 + + /* Restore SPRG3 */ + ld r3,PACA_SPRG3(r13) + mtspr SPRN_SPRG3,r3 + + /* + * Reload DEC. HDEC interrupts were disabled when + * we reloaded the host's LPCR value. + */ + ld r3, HSTATE_DECEXP(r13) + mftb r4 + subf r4, r4, r3 + mtspr SPRN_DEC, r4 + + /* Reload the host's PMU registers */ + ld r3, PACALPPACAPTR(r13) /* is the host using the PMU? */ + lbz r4, LPPACA_PMCINUSE(r3) + cmpwi r4, 0 + beq 23f /* skip if not */ + lwz r3, HSTATE_PMC(r13) + lwz r4, HSTATE_PMC + 4(r13) + lwz r5, HSTATE_PMC + 8(r13) + lwz r6, HSTATE_PMC + 12(r13) + lwz r8, HSTATE_PMC + 16(r13) + lwz r9, HSTATE_PMC + 20(r13) +BEGIN_FTR_SECTION + lwz r10, HSTATE_PMC + 24(r13) + lwz r11, HSTATE_PMC + 28(r13) +END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201) + mtspr SPRN_PMC1, r3 + mtspr SPRN_PMC2, r4 + mtspr SPRN_PMC3, r5 + mtspr SPRN_PMC4, r6 + mtspr SPRN_PMC5, r8 + mtspr SPRN_PMC6, r9 +BEGIN_FTR_SECTION + mtspr SPRN_PMC7, r10 + mtspr SPRN_PMC8, r11 +END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201) + ld r3, HSTATE_MMCR(r13) + ld r4, HSTATE_MMCR + 8(r13) + ld r5, HSTATE_MMCR + 16(r13) + mtspr SPRN_MMCR1, r4 + mtspr SPRN_MMCRA, r5 + mtspr SPRN_MMCR0, r3 + isync +23: + + /* + * For external and machine check interrupts, we need + * to call the Linux handler to process the interrupt. + * We do that by jumping to absolute address 0x500 for + * external interrupts, or the machine_check_fwnmi label + * for machine checks (since firmware might have patched + * the vector area at 0x200). The [h]rfid at the end of the + * handler will return to the book3s_hv_interrupts.S code. + * For other interrupts we do the rfid to get back + * to the book3s_hv_interrupts.S code here. + */ + ld r8, 112+PPC_LR_STKOFF(r1) + addi r1, r1, 112 + ld r7, HSTATE_HOST_MSR(r13) + + cmpwi cr1, r12, BOOK3S_INTERRUPT_MACHINE_CHECK + cmpwi r12, BOOK3S_INTERRUPT_EXTERNAL +BEGIN_FTR_SECTION + beq 11f +END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206) + + /* RFI into the highmem handler, or branch to interrupt handler */ + mfmsr r6 + li r0, MSR_RI + andc r6, r6, r0 + mtmsrd r6, 1 /* Clear RI in MSR */ + mtsrr0 r8 + mtsrr1 r7 + beqa 0x500 /* external interrupt (PPC970) */ + beq cr1, 13f /* machine check */ + RFI + + /* On POWER7, we have external interrupts set to use HSRR0/1 */ +11: mtspr SPRN_HSRR0, r8 + mtspr SPRN_HSRR1, r7 + ba 0x500 + +13: b machine_check_fwnmi + /* * We come in here when wakened from nap mode on a secondary hw thread. @@ -137,7 +208,7 @@ kvm_start_guest: cmpdi r4,0 /* if we have no vcpu to run, go back to sleep */ beq kvm_no_guest - b kvmppc_hv_entry + b 30f 27: /* XXX should handle hypervisor maintenance interrupts etc. here */ b kvm_no_guest @@ -147,6 +218,57 @@ kvm_start_guest: stw r8,HSTATE_SAVED_XIRR(r13) b kvm_no_guest +30: bl kvmppc_hv_entry + + /* Back from the guest, go back to nap */ + /* Clear our vcpu pointer so we don't come back in early */ + li r0, 0 + std r0, HSTATE_KVM_VCPU(r13) + lwsync + /* Clear any pending IPI - we're an offline thread */ + ld r5, HSTATE_XICS_PHYS(r13) + li r7, XICS_XIRR + lwzcix r3, r5, r7 /* ack any pending interrupt */ + rlwinm. r0, r3, 0, 0xffffff /* any pending? */ + beq 37f + sync + li r0, 0xff + li r6, XICS_MFRR + stbcix r0, r5, r6 /* clear the IPI */ + stwcix r3, r5, r7 /* EOI it */ +37: sync + + /* increment the nap count and then go to nap mode */ + ld r4, HSTATE_KVM_VCORE(r13) + addi r4, r4, VCORE_NAP_COUNT + lwsync /* make previous updates visible */ +51: lwarx r3, 0, r4 + addi r3, r3, 1 + stwcx. r3, 0, r4 + bne 51b + +kvm_no_guest: + li r0, KVM_HWTHREAD_IN_NAP + stb r0, HSTATE_HWTHREAD_STATE(r13) + li r3, LPCR_PECE0 + mfspr r4, SPRN_LPCR + rlwimi r4, r3, 0, LPCR_PECE0 | LPCR_PECE1 + mtspr SPRN_LPCR, r4 + isync + std r0, HSTATE_SCRATCH0(r13) + ptesync + ld r0, HSTATE_SCRATCH0(r13) +1: cmpd r0, r0 + bne 1b + nap + b . + +/****************************************************************************** + * * + * Entry code * + * * + *****************************************************************************/ + .global kvmppc_hv_entry kvmppc_hv_entry: @@ -159,7 +281,8 @@ kvmppc_hv_entry: * all other volatile GPRS = free */ mflr r0 - std r0, HSTATE_VMHANDLER(r13) + std r0, PPC_LR_STKOFF(r1) + stdu r1, -112(r1) /* Set partition DABR */ /* Do this before re-enabling PMU to avoid P7 DABR corruption bug */ @@ -200,8 +323,12 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201) ld r3, VCPU_MMCR(r4) ld r5, VCPU_MMCR + 8(r4) ld r6, VCPU_MMCR + 16(r4) + ld r7, VCPU_SIAR(r4) + ld r8, VCPU_SDAR(r4) mtspr SPRN_MMCR1, r5 mtspr SPRN_MMCRA, r6 + mtspr SPRN_SIAR, r7 + mtspr SPRN_SDAR, r8 mtspr SPRN_MMCR0, r3 isync @@ -254,22 +381,15 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206) /* Save R1 in the PACA */ std r1, HSTATE_HOST_R1(r13) - /* Increment yield count if they have a VPA */ - ld r3, VCPU_VPA(r4) - cmpdi r3, 0 - beq 25f - lwz r5, LPPACA_YIELDCOUNT(r3) - addi r5, r5, 1 - stw r5, LPPACA_YIELDCOUNT(r3) - li r6, 1 - stb r6, VCPU_VPA_DIRTY(r4) -25: /* Load up DAR and DSISR */ ld r5, VCPU_DAR(r4) lwz r6, VCPU_DSISR(r4) mtspr SPRN_DAR, r5 mtspr SPRN_DSISR, r6 + li r6, KVM_GUEST_MODE_HOST_HV + stb r6, HSTATE_IN_GUEST(r13) + BEGIN_FTR_SECTION /* Restore AMR and UAMOR, set AMOR to all 1s */ ld r5,VCPU_AMR(r4) @@ -343,7 +463,28 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201) bdnz 28b ptesync -22: li r0,1 + /* Add timebase offset onto timebase */ +22: ld r8,VCORE_TB_OFFSET(r5) + cmpdi r8,0 + beq 37f + mftb r6 /* current host timebase */ + add r8,r8,r6 + mtspr SPRN_TBU40,r8 /* update upper 40 bits */ + mftb r7 /* check if lower 24 bits overflowed */ + clrldi r6,r6,40 + clrldi r7,r7,40 + cmpld r7,r6 + bge 37f + addis r8,r8,0x100 /* if so, increment upper 40 bits */ + mtspr SPRN_TBU40,r8 + + /* Load guest PCR value to select appropriate compat mode */ +37: ld r7, VCORE_PCR(r5) + cmpdi r7, 0 + beq 38f + mtspr SPRN_PCR, r7 +38: + li r0,1 stb r0,VCORE_IN_GUEST(r5) /* signal secondaries to continue */ b 10f @@ -353,12 +494,22 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201) beq 20b /* Set LPCR and RMOR. */ -10: ld r8,KVM_LPCR(r9) +10: ld r8,VCORE_LPCR(r5) mtspr SPRN_LPCR,r8 ld r8,KVM_RMOR(r9) mtspr SPRN_RMOR,r8 isync + /* Increment yield count if they have a VPA */ + ld r3, VCPU_VPA(r4) + cmpdi r3, 0 + beq 25f + lwz r5, LPPACA_YIELDCOUNT(r3) + addi r5, r5, 1 + stw r5, LPPACA_YIELDCOUNT(r3) + li r6, 1 + stb r6, VCPU_VPA_DIRTY(r4) +25: /* Check if HDEC expires soon */ mfspr r3,SPRN_HDEC cmpwi r3,10 @@ -405,7 +556,8 @@ toc_tlbie_lock: bne 24b isync - ld r7,KVM_LPCR(r9) /* use kvm->arch.lpcr to store HID4 */ + ld r5,HSTATE_KVM_VCORE(r13) + ld r7,VCORE_LPCR(r5) /* use vcore->lpcr to store HID4 */ li r0,0x18f rotldi r0,r0,HID4_LPID5_SH /* all lpid bits in HID4 = 1 */ or r0,r7,r0 @@ -541,7 +693,7 @@ fast_guest_return: mtspr SPRN_HSRR1,r11 /* Activate guest mode, so faults get handled by KVM */ - li r9, KVM_GUEST_MODE_GUEST + li r9, KVM_GUEST_MODE_GUEST_HV stb r9, HSTATE_IN_GUEST(r13) /* Enter guest */ @@ -550,13 +702,15 @@ BEGIN_FTR_SECTION ld r5, VCPU_CFAR(r4) mtspr SPRN_CFAR, r5 END_FTR_SECTION_IFSET(CPU_FTR_CFAR) +BEGIN_FTR_SECTION + ld r0, VCPU_PPR(r4) +END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) ld r5, VCPU_LR(r4) lwz r6, VCPU_CR(r4) mtlr r5 mtcr r6 - ld r0, VCPU_GPR(R0)(r4) ld r1, VCPU_GPR(R1)(r4) ld r2, VCPU_GPR(R2)(r4) ld r3, VCPU_GPR(R3)(r4) @@ -570,6 +724,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR) ld r12, VCPU_GPR(R12)(r4) ld r13, VCPU_GPR(R13)(r4) +BEGIN_FTR_SECTION + mtspr SPRN_PPR, r0 +END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) + ld r0, VCPU_GPR(R0)(r4) ld r4, VCPU_GPR(R4)(r4) hrfid @@ -584,8 +742,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR) /* * We come here from the first-level interrupt handlers. */ - .globl kvmppc_interrupt -kvmppc_interrupt: + .globl kvmppc_interrupt_hv +kvmppc_interrupt_hv: /* * Register contents: * R12 = interrupt vector @@ -595,6 +753,19 @@ kvmppc_interrupt: */ /* abuse host_r2 as third scratch area; we get r2 from PACATOC(r13) */ std r9, HSTATE_HOST_R2(r13) + + lbz r9, HSTATE_IN_GUEST(r13) + cmpwi r9, KVM_GUEST_MODE_HOST_HV + beq kvmppc_bad_host_intr +#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE + cmpwi r9, KVM_GUEST_MODE_GUEST + ld r9, HSTATE_HOST_R2(r13) + beq kvmppc_interrupt_pr +#endif + /* We're now back in the host but in guest MMU context */ + li r9, KVM_GUEST_MODE_HOST_HV + stb r9, HSTATE_IN_GUEST(r13) + ld r9, HSTATE_KVM_VCPU(r13) /* Save registers */ @@ -620,6 +791,10 @@ BEGIN_FTR_SECTION ld r3, HSTATE_CFAR(r13) std r3, VCPU_CFAR(r9) END_FTR_SECTION_IFSET(CPU_FTR_CFAR) +BEGIN_FTR_SECTION + ld r4, HSTATE_PPR(r13) + std r4, VCPU_PPR(r9) +END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) /* Restore R1/R2 so we can handle faults */ ld r1, HSTATE_HOST_R1(r13) @@ -642,10 +817,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR) std r3, VCPU_GPR(R13)(r9) std r4, VCPU_LR(r9) - /* Unset guest mode */ - li r0, KVM_GUEST_MODE_NONE - stb r0, HSTATE_IN_GUEST(r13) - stw r12,VCPU_TRAP(r9) /* Save HEIR (HV emulation assist reg) in last_inst @@ -696,46 +867,11 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_206) * set, we know the host wants us out so let's do it now */ do_ext_interrupt: - lbz r0, HSTATE_HOST_IPI(r13) - cmpwi r0, 0 - bne ext_interrupt_to_host - - /* Now read the interrupt from the ICP */ - ld r5, HSTATE_XICS_PHYS(r13) - li r7, XICS_XIRR - cmpdi r5, 0 - beq- ext_interrupt_to_host - lwzcix r3, r5, r7 - rlwinm. r0, r3, 0, 0xffffff - sync - beq 3f /* if nothing pending in the ICP */ - - /* We found something in the ICP... - * - * If it's not an IPI, stash it in the PACA and return to - * the host, we don't (yet) handle directing real external - * interrupts directly to the guest - */ - cmpwi r0, XICS_IPI - bne ext_stash_for_host - - /* It's an IPI, clear the MFRR and EOI it */ - li r0, 0xff - li r6, XICS_MFRR - stbcix r0, r5, r6 /* clear the IPI */ - stwcix r3, r5, r7 /* EOI it */ - sync - - /* We need to re-check host IPI now in case it got set in the - * meantime. If it's clear, we bounce the interrupt to the - * guest - */ - lbz r0, HSTATE_HOST_IPI(r13) - cmpwi r0, 0 - bne- 1f + bl kvmppc_read_intr + cmpdi r3, 0 + bgt ext_interrupt_to_host /* Allright, looks like an IPI for the guest, we need to set MER */ -3: /* Check if any CPU is heading out to the host, if so head out too */ ld r5, HSTATE_KVM_VCORE(r13) lwz r0, VCORE_ENTRY_EXIT(r5) @@ -764,27 +900,9 @@ do_ext_interrupt: mtspr SPRN_LPCR, r8 b fast_guest_return - /* We raced with the host, we need to resend that IPI, bummer */ -1: li r0, IPI_PRIORITY - stbcix r0, r5, r6 /* set the IPI */ - sync - b ext_interrupt_to_host - -ext_stash_for_host: - /* It's not an IPI and it's for the host, stash it in the PACA - * before exit, it will be picked up by the host ICP driver - */ - stw r3, HSTATE_SAVED_XIRR(r13) ext_interrupt_to_host: guest_exit_cont: /* r9 = vcpu, r12 = trap, r13 = paca */ - /* Save DEC */ - mfspr r5,SPRN_DEC - mftb r6 - extsw r5,r5 - add r5,r5,r6 - std r5,VCPU_DEC_EXPIRES(r9) - /* Save more register state */ mfdar r6 mfdsisr r7 @@ -954,7 +1072,30 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201) mtspr SPRN_SDR1,r6 /* switch to partition page table */ mtspr SPRN_LPID,r7 isync - li r0,0 + + /* Subtract timebase offset from timebase */ + ld r8,VCORE_TB_OFFSET(r5) + cmpdi r8,0 + beq 17f + mftb r6 /* current host timebase */ + subf r8,r8,r6 + mtspr SPRN_TBU40,r8 /* update upper 40 bits */ + mftb r7 /* check if lower 24 bits overflowed */ + clrldi r6,r6,40 + clrldi r7,r7,40 + cmpld r7,r6 + bge 17f + addis r8,r8,0x100 /* if so, increment upper 40 bits */ + mtspr SPRN_TBU40,r8 + + /* Reset PCR */ +17: ld r0, VCORE_PCR(r5) + cmpdi r0, 0 + beq 18f + li r0, 0 + mtspr SPRN_PCR, r0 +18: + /* Signal secondary CPUs to continue */ stb r0,VCORE_IN_GUEST(r5) lis r8,0x7fff /* MAX_INT@h */ mtspr SPRN_HDEC,r8 @@ -1052,6 +1193,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201) 1: addi r8,r8,16 .endr + /* Save DEC */ + mfspr r5,SPRN_DEC + mftb r6 + extsw r5,r5 + add r5,r5,r6 + std r5,VCPU_DEC_EXPIRES(r9) + /* Save and reset AMR and UAMOR before turning on the MMU */ BEGIN_FTR_SECTION mfspr r5,SPRN_AMR @@ -1062,6 +1210,10 @@ BEGIN_FTR_SECTION mtspr SPRN_AMR,r6 END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206) + /* Unset guest mode */ + li r0, KVM_GUEST_MODE_NONE + stb r0, HSTATE_IN_GUEST(r13) + /* Switch DSCR back to host value */ BEGIN_FTR_SECTION mfspr r8, SPRN_DSCR @@ -1134,9 +1286,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206) std r3, VCPU_MMCR(r9) /* if not, set saved MMCR0 to FC */ b 22f 21: mfspr r5, SPRN_MMCR1 + mfspr r7, SPRN_SIAR + mfspr r8, SPRN_SDAR std r4, VCPU_MMCR(r9) std r5, VCPU_MMCR + 8(r9) std r6, VCPU_MMCR + 16(r9) + std r7, VCPU_SIAR(r9) + std r8, VCPU_SDAR(r9) mfspr r3, SPRN_PMC1 mfspr r4, SPRN_PMC2 mfspr r5, SPRN_PMC3 @@ -1158,103 +1314,30 @@ BEGIN_FTR_SECTION stw r11, VCPU_PMC + 28(r9) END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201) 22: + ld r0, 112+PPC_LR_STKOFF(r1) + addi r1, r1, 112 + mtlr r0 + blr +secondary_too_late: + ld r5,HSTATE_KVM_VCORE(r13) + HMT_LOW +13: lbz r3,VCORE_IN_GUEST(r5) + cmpwi r3,0 + bne 13b + HMT_MEDIUM + li r0, KVM_GUEST_MODE_NONE + stb r0, HSTATE_IN_GUEST(r13) + ld r11,PACA_SLBSHADOWPTR(r13) - /* Secondary threads go off to take a nap on POWER7 */ -BEGIN_FTR_SECTION - lwz r0,VCPU_PTID(r9) - cmpwi r0,0 - bne secondary_nap -END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206) - - /* Restore host DABR and DABRX */ - ld r5,HSTATE_DABR(r13) - li r6,7 - mtspr SPRN_DABR,r5 - mtspr SPRN_DABRX,r6 - - /* Restore SPRG3 */ - ld r3,PACA_SPRG3(r13) - mtspr SPRN_SPRG3,r3 - - /* - * Reload DEC. HDEC interrupts were disabled when - * we reloaded the host's LPCR value. - */ - ld r3, HSTATE_DECEXP(r13) - mftb r4 - subf r4, r4, r3 - mtspr SPRN_DEC, r4 - - /* Reload the host's PMU registers */ - ld r3, PACALPPACAPTR(r13) /* is the host using the PMU? */ - lbz r4, LPPACA_PMCINUSE(r3) - cmpwi r4, 0 - beq 23f /* skip if not */ - lwz r3, HSTATE_PMC(r13) - lwz r4, HSTATE_PMC + 4(r13) - lwz r5, HSTATE_PMC + 8(r13) - lwz r6, HSTATE_PMC + 12(r13) - lwz r8, HSTATE_PMC + 16(r13) - lwz r9, HSTATE_PMC + 20(r13) -BEGIN_FTR_SECTION - lwz r10, HSTATE_PMC + 24(r13) - lwz r11, HSTATE_PMC + 28(r13) -END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201) - mtspr SPRN_PMC1, r3 - mtspr SPRN_PMC2, r4 - mtspr SPRN_PMC3, r5 - mtspr SPRN_PMC4, r6 - mtspr SPRN_PMC5, r8 - mtspr SPRN_PMC6, r9 -BEGIN_FTR_SECTION - mtspr SPRN_PMC7, r10 - mtspr SPRN_PMC8, r11 -END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201) - ld r3, HSTATE_MMCR(r13) - ld r4, HSTATE_MMCR + 8(r13) - ld r5, HSTATE_MMCR + 16(r13) - mtspr SPRN_MMCR1, r4 - mtspr SPRN_MMCRA, r5 - mtspr SPRN_MMCR0, r3 - isync -23: - /* - * For external and machine check interrupts, we need - * to call the Linux handler to process the interrupt. - * We do that by jumping to absolute address 0x500 for - * external interrupts, or the machine_check_fwnmi label - * for machine checks (since firmware might have patched - * the vector area at 0x200). The [h]rfid at the end of the - * handler will return to the book3s_hv_interrupts.S code. - * For other interrupts we do the rfid to get back - * to the book3s_hv_interrupts.S code here. - */ - ld r8, HSTATE_VMHANDLER(r13) - ld r7, HSTATE_HOST_MSR(r13) - - cmpwi cr1, r12, BOOK3S_INTERRUPT_MACHINE_CHECK - cmpwi r12, BOOK3S_INTERRUPT_EXTERNAL -BEGIN_FTR_SECTION - beq 11f -END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206) - - /* RFI into the highmem handler, or branch to interrupt handler */ - mfmsr r6 - li r0, MSR_RI - andc r6, r6, r0 - mtmsrd r6, 1 /* Clear RI in MSR */ - mtsrr0 r8 - mtsrr1 r7 - beqa 0x500 /* external interrupt (PPC970) */ - beq cr1, 13f /* machine check */ - RFI - - /* On POWER7, we have external interrupts set to use HSRR0/1 */ -11: mtspr SPRN_HSRR0, r8 - mtspr SPRN_HSRR1, r7 - ba 0x500 - -13: b machine_check_fwnmi + .rept SLB_NUM_BOLTED + ld r5,SLBSHADOW_SAVEAREA(r11) + ld r6,SLBSHADOW_SAVEAREA+8(r11) + andis. r7,r5,SLB_ESID_V@h + beq 1f + slbmte r6,r5 +1: addi r11,r11,16 + .endr + b 22b /* * Check whether an HDSI is an HPTE not found fault or something else. @@ -1333,7 +1416,7 @@ fast_interrupt_c_return: stw r8, VCPU_LAST_INST(r9) /* Unset guest mode. */ - li r0, KVM_GUEST_MODE_NONE + li r0, KVM_GUEST_MODE_HOST_HV stb r0, HSTATE_IN_GUEST(r13) b guest_exit_cont @@ -1701,67 +1784,70 @@ machine_check_realmode: rotldi r11, r11, 63 b fast_interrupt_c_return -secondary_too_late: - ld r5,HSTATE_KVM_VCORE(r13) - HMT_LOW -13: lbz r3,VCORE_IN_GUEST(r5) - cmpwi r3,0 - bne 13b - HMT_MEDIUM - ld r11,PACA_SLBSHADOWPTR(r13) - - .rept SLB_NUM_BOLTED - ld r5,SLBSHADOW_SAVEAREA(r11) - ld r6,SLBSHADOW_SAVEAREA+8(r11) - andis. r7,r5,SLB_ESID_V@h - beq 1f - slbmte r6,r5 -1: addi r11,r11,16 - .endr +/* + * Determine what sort of external interrupt is pending (if any). + * Returns: + * 0 if no interrupt is pending + * 1 if an interrupt is pending that needs to be handled by the host + * -1 if there was a guest wakeup IPI (which has now been cleared) + */ +kvmppc_read_intr: + /* see if a host IPI is pending */ + li r3, 1 + lbz r0, HSTATE_HOST_IPI(r13) + cmpwi r0, 0 + bne 1f -secondary_nap: - /* Clear our vcpu pointer so we don't come back in early */ - li r0, 0 - std r0, HSTATE_KVM_VCPU(r13) - lwsync - /* Clear any pending IPI - assume we're a secondary thread */ - ld r5, HSTATE_XICS_PHYS(r13) + /* Now read the interrupt from the ICP */ + ld r6, HSTATE_XICS_PHYS(r13) li r7, XICS_XIRR - lwzcix r3, r5, r7 /* ack any pending interrupt */ - rlwinm. r0, r3, 0, 0xffffff /* any pending? */ - beq 37f + cmpdi r6, 0 + beq- 1f + lwzcix r0, r6, r7 + rlwinm. r3, r0, 0, 0xffffff sync - li r0, 0xff - li r6, XICS_MFRR - stbcix r0, r5, r6 /* clear the IPI */ - stwcix r3, r5, r7 /* EOI it */ -37: sync + beq 1f /* if nothing pending in the ICP */ - /* increment the nap count and then go to nap mode */ - ld r4, HSTATE_KVM_VCORE(r13) - addi r4, r4, VCORE_NAP_COUNT - lwsync /* make previous updates visible */ -51: lwarx r3, 0, r4 - addi r3, r3, 1 - stwcx. r3, 0, r4 - bne 51b + /* We found something in the ICP... + * + * If it's not an IPI, stash it in the PACA and return to + * the host, we don't (yet) handle directing real external + * interrupts directly to the guest + */ + cmpwi r3, XICS_IPI /* if there is, is it an IPI? */ + li r3, 1 + bne 42f -kvm_no_guest: - li r0, KVM_HWTHREAD_IN_NAP - stb r0, HSTATE_HWTHREAD_STATE(r13) + /* It's an IPI, clear the MFRR and EOI it */ + li r3, 0xff + li r8, XICS_MFRR + stbcix r3, r6, r8 /* clear the IPI */ + stwcix r0, r6, r7 /* EOI it */ + sync - li r3, LPCR_PECE0 - mfspr r4, SPRN_LPCR - rlwimi r4, r3, 0, LPCR_PECE0 | LPCR_PECE1 - mtspr SPRN_LPCR, r4 - isync - std r0, HSTATE_SCRATCH0(r13) - ptesync - ld r0, HSTATE_SCRATCH0(r13) -1: cmpd r0, r0 - bne 1b - nap - b . + /* We need to re-check host IPI now in case it got set in the + * meantime. If it's clear, we bounce the interrupt to the + * guest + */ + lbz r0, HSTATE_HOST_IPI(r13) + cmpwi r0, 0 + bne- 43f + + /* OK, it's an IPI for us */ + li r3, -1 +1: blr + +42: /* It's not an IPI and it's for the host, stash it in the PACA + * before exit, it will be picked up by the host ICP driver + */ + stw r0, HSTATE_SAVED_XIRR(r13) + b 1b + +43: /* We raced with the host, we need to resend that IPI, bummer */ + li r0, IPI_PRIORITY + stbcix r0, r6, r8 /* set the IPI */ + sync + b 1b /* * Save away FP, VMX and VSX registers. @@ -1879,3 +1965,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) lwz r7,VCPU_VRSAVE(r4) mtspr SPRN_VRSAVE,r7 blr + +/* + * We come here if we get any exception or interrupt while we are + * executing host real mode code while in guest MMU context. + * For now just spin, but we should do something better. + */ +kvmppc_bad_host_intr: + b . diff --git a/arch/powerpc/kvm/book3s_interrupts.S b/arch/powerpc/kvm/book3s_interrupts.S index 17cfae5497a3..f4dd041c14ea 100644 --- a/arch/powerpc/kvm/book3s_interrupts.S +++ b/arch/powerpc/kvm/book3s_interrupts.S @@ -26,8 +26,12 @@ #if defined(CONFIG_PPC_BOOK3S_64) #define FUNC(name) GLUE(.,name) +#define GET_SHADOW_VCPU(reg) addi reg, r13, PACA_SVCPU + #elif defined(CONFIG_PPC_BOOK3S_32) #define FUNC(name) name +#define GET_SHADOW_VCPU(reg) lwz reg, (THREAD + THREAD_KVM_SVCPU)(r2) + #endif /* CONFIG_PPC_BOOK3S_XX */ #define VCPU_LOAD_NVGPRS(vcpu) \ @@ -87,8 +91,14 @@ kvm_start_entry: VCPU_LOAD_NVGPRS(r4) kvm_start_lightweight: + /* Copy registers into shadow vcpu so we can access them in real mode */ + GET_SHADOW_VCPU(r3) + bl FUNC(kvmppc_copy_to_svcpu) + nop + REST_GPR(4, r1) #ifdef CONFIG_PPC_BOOK3S_64 + /* Get the dcbz32 flag */ PPC_LL r3, VCPU_HFLAGS(r4) rldicl r3, r3, 0, 63 /* r3 &= 1 */ stb r3, HSTATE_RESTORE_HID5(r13) @@ -111,9 +121,6 @@ kvm_start_lightweight: * */ -.global kvmppc_handler_highmem -kvmppc_handler_highmem: - /* * Register usage at this point: * @@ -125,18 +132,31 @@ kvmppc_handler_highmem: * */ - /* R7 = vcpu */ - PPC_LL r7, GPR4(r1) + /* Transfer reg values from shadow vcpu back to vcpu struct */ + /* On 64-bit, interrupts are still off at this point */ + PPC_LL r3, GPR4(r1) /* vcpu pointer */ + GET_SHADOW_VCPU(r4) + bl FUNC(kvmppc_copy_from_svcpu) + nop #ifdef CONFIG_PPC_BOOK3S_64 + /* Re-enable interrupts */ + ld r3, HSTATE_HOST_MSR(r13) + ori r3, r3, MSR_EE + MTMSR_EERI(r3) + /* * Reload kernel SPRG3 value. * No need to save guest value as usermode can't modify SPRG3. */ ld r3, PACA_SPRG3(r13) mtspr SPRN_SPRG3, r3 + #endif /* CONFIG_PPC_BOOK3S_64 */ + /* R7 = vcpu */ + PPC_LL r7, GPR4(r1) + PPC_STL r14, VCPU_GPR(R14)(r7) PPC_STL r15, VCPU_GPR(R15)(r7) PPC_STL r16, VCPU_GPR(R16)(r7) @@ -161,7 +181,7 @@ kvmppc_handler_highmem: /* Restore r3 (kvm_run) and r4 (vcpu) */ REST_2GPRS(3, r1) - bl FUNC(kvmppc_handle_exit) + bl FUNC(kvmppc_handle_exit_pr) /* If RESUME_GUEST, get back in the loop */ cmpwi r3, RESUME_GUEST diff --git a/arch/powerpc/kvm/book3s_mmu_hpte.c b/arch/powerpc/kvm/book3s_mmu_hpte.c index da8b13c4b776..5a1ab1250a05 100644 --- a/arch/powerpc/kvm/book3s_mmu_hpte.c +++ b/arch/powerpc/kvm/book3s_mmu_hpte.c @@ -28,7 +28,7 @@ #include <asm/mmu_context.h> #include <asm/hw_irq.h> -#include "trace.h" +#include "trace_pr.h" #define PTE_SIZE 12 @@ -56,6 +56,14 @@ static inline u64 kvmppc_mmu_hash_vpte_long(u64 vpage) HPTEG_HASH_BITS_VPTE_LONG); } +#ifdef CONFIG_PPC_BOOK3S_64 +static inline u64 kvmppc_mmu_hash_vpte_64k(u64 vpage) +{ + return hash_64((vpage & 0xffffffff0ULL) >> 4, + HPTEG_HASH_BITS_VPTE_64K); +} +#endif + void kvmppc_mmu_hpte_cache_map(struct kvm_vcpu *vcpu, struct hpte_cache *pte) { u64 index; @@ -83,6 +91,15 @@ void kvmppc_mmu_hpte_cache_map(struct kvm_vcpu *vcpu, struct hpte_cache *pte) hlist_add_head_rcu(&pte->list_vpte_long, &vcpu3s->hpte_hash_vpte_long[index]); +#ifdef CONFIG_PPC_BOOK3S_64 + /* Add to vPTE_64k list */ + index = kvmppc_mmu_hash_vpte_64k(pte->pte.vpage); + hlist_add_head_rcu(&pte->list_vpte_64k, + &vcpu3s->hpte_hash_vpte_64k[index]); +#endif + + vcpu3s->hpte_cache_count++; + spin_unlock(&vcpu3s->mmu_lock); } @@ -113,10 +130,13 @@ static void invalidate_pte(struct kvm_vcpu *vcpu, struct hpte_cache *pte) hlist_del_init_rcu(&pte->list_pte_long); hlist_del_init_rcu(&pte->list_vpte); hlist_del_init_rcu(&pte->list_vpte_long); +#ifdef CONFIG_PPC_BOOK3S_64 + hlist_del_init_rcu(&pte->list_vpte_64k); +#endif + vcpu3s->hpte_cache_count--; spin_unlock(&vcpu3s->mmu_lock); - vcpu3s->hpte_cache_count--; call_rcu(&pte->rcu_head, free_pte_rcu); } @@ -219,6 +239,29 @@ static void kvmppc_mmu_pte_vflush_short(struct kvm_vcpu *vcpu, u64 guest_vp) rcu_read_unlock(); } +#ifdef CONFIG_PPC_BOOK3S_64 +/* Flush with mask 0xffffffff0 */ +static void kvmppc_mmu_pte_vflush_64k(struct kvm_vcpu *vcpu, u64 guest_vp) +{ + struct kvmppc_vcpu_book3s *vcpu3s = to_book3s(vcpu); + struct hlist_head *list; + struct hpte_cache *pte; + u64 vp_mask = 0xffffffff0ULL; + + list = &vcpu3s->hpte_hash_vpte_64k[ + kvmppc_mmu_hash_vpte_64k(guest_vp)]; + + rcu_read_lock(); + + /* Check the list for matching entries and invalidate */ + hlist_for_each_entry_rcu(pte, list, list_vpte_64k) + if ((pte->pte.vpage & vp_mask) == guest_vp) + invalidate_pte(vcpu, pte); + + rcu_read_unlock(); +} +#endif + /* Flush with mask 0xffffff000 */ static void kvmppc_mmu_pte_vflush_long(struct kvm_vcpu *vcpu, u64 guest_vp) { @@ -249,6 +292,11 @@ void kvmppc_mmu_pte_vflush(struct kvm_vcpu *vcpu, u64 guest_vp, u64 vp_mask) case 0xfffffffffULL: kvmppc_mmu_pte_vflush_short(vcpu, guest_vp); break; +#ifdef CONFIG_PPC_BOOK3S_64 + case 0xffffffff0ULL: + kvmppc_mmu_pte_vflush_64k(vcpu, guest_vp); + break; +#endif case 0xffffff000ULL: kvmppc_mmu_pte_vflush_long(vcpu, guest_vp); break; @@ -285,15 +333,19 @@ struct hpte_cache *kvmppc_mmu_hpte_cache_next(struct kvm_vcpu *vcpu) struct kvmppc_vcpu_book3s *vcpu3s = to_book3s(vcpu); struct hpte_cache *pte; - pte = kmem_cache_zalloc(hpte_cache, GFP_KERNEL); - vcpu3s->hpte_cache_count++; - if (vcpu3s->hpte_cache_count == HPTEG_CACHE_NUM) kvmppc_mmu_pte_flush_all(vcpu); + pte = kmem_cache_zalloc(hpte_cache, GFP_KERNEL); + return pte; } +void kvmppc_mmu_hpte_cache_free(struct hpte_cache *pte) +{ + kmem_cache_free(hpte_cache, pte); +} + void kvmppc_mmu_hpte_destroy(struct kvm_vcpu *vcpu) { kvmppc_mmu_pte_flush(vcpu, 0, 0); @@ -320,6 +372,10 @@ int kvmppc_mmu_hpte_init(struct kvm_vcpu *vcpu) ARRAY_SIZE(vcpu3s->hpte_hash_vpte)); kvmppc_mmu_hpte_init_hash(vcpu3s->hpte_hash_vpte_long, ARRAY_SIZE(vcpu3s->hpte_hash_vpte_long)); +#ifdef CONFIG_PPC_BOOK3S_64 + kvmppc_mmu_hpte_init_hash(vcpu3s->hpte_hash_vpte_64k, + ARRAY_SIZE(vcpu3s->hpte_hash_vpte_64k)); +#endif spin_lock_init(&vcpu3s->mmu_lock); diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c index 27db1e665959..fe14ca3dd171 100644 --- a/arch/powerpc/kvm/book3s_pr.c +++ b/arch/powerpc/kvm/book3s_pr.c @@ -40,8 +40,12 @@ #include <linux/sched.h> #include <linux/vmalloc.h> #include <linux/highmem.h> +#include <linux/module.h> -#include "trace.h" +#include "book3s.h" + +#define CREATE_TRACE_POINTS +#include "trace_pr.h" /* #define EXIT_DEBUG */ /* #define DEBUG_EXT */ @@ -56,29 +60,25 @@ static int kvmppc_handle_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr, #define HW_PAGE_SIZE PAGE_SIZE #endif -void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu) +static void kvmppc_core_vcpu_load_pr(struct kvm_vcpu *vcpu, int cpu) { #ifdef CONFIG_PPC_BOOK3S_64 struct kvmppc_book3s_shadow_vcpu *svcpu = svcpu_get(vcpu); memcpy(svcpu->slb, to_book3s(vcpu)->slb_shadow, sizeof(svcpu->slb)); - memcpy(&get_paca()->shadow_vcpu, to_book3s(vcpu)->shadow_vcpu, - sizeof(get_paca()->shadow_vcpu)); svcpu->slb_max = to_book3s(vcpu)->slb_shadow_max; svcpu_put(svcpu); #endif vcpu->cpu = smp_processor_id(); #ifdef CONFIG_PPC_BOOK3S_32 - current->thread.kvm_shadow_vcpu = to_book3s(vcpu)->shadow_vcpu; + current->thread.kvm_shadow_vcpu = vcpu->arch.shadow_vcpu; #endif } -void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu) +static void kvmppc_core_vcpu_put_pr(struct kvm_vcpu *vcpu) { #ifdef CONFIG_PPC_BOOK3S_64 struct kvmppc_book3s_shadow_vcpu *svcpu = svcpu_get(vcpu); memcpy(to_book3s(vcpu)->slb_shadow, svcpu->slb, sizeof(svcpu->slb)); - memcpy(to_book3s(vcpu)->shadow_vcpu, &get_paca()->shadow_vcpu, - sizeof(get_paca()->shadow_vcpu)); to_book3s(vcpu)->slb_shadow_max = svcpu->slb_max; svcpu_put(svcpu); #endif @@ -87,7 +87,61 @@ void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu) vcpu->cpu = -1; } -int kvmppc_core_check_requests(struct kvm_vcpu *vcpu) +/* Copy data needed by real-mode code from vcpu to shadow vcpu */ +void kvmppc_copy_to_svcpu(struct kvmppc_book3s_shadow_vcpu *svcpu, + struct kvm_vcpu *vcpu) +{ + svcpu->gpr[0] = vcpu->arch.gpr[0]; + svcpu->gpr[1] = vcpu->arch.gpr[1]; + svcpu->gpr[2] = vcpu->arch.gpr[2]; + svcpu->gpr[3] = vcpu->arch.gpr[3]; + svcpu->gpr[4] = vcpu->arch.gpr[4]; + svcpu->gpr[5] = vcpu->arch.gpr[5]; + svcpu->gpr[6] = vcpu->arch.gpr[6]; + svcpu->gpr[7] = vcpu->arch.gpr[7]; + svcpu->gpr[8] = vcpu->arch.gpr[8]; + svcpu->gpr[9] = vcpu->arch.gpr[9]; + svcpu->gpr[10] = vcpu->arch.gpr[10]; + svcpu->gpr[11] = vcpu->arch.gpr[11]; + svcpu->gpr[12] = vcpu->arch.gpr[12]; + svcpu->gpr[13] = vcpu->arch.gpr[13]; + svcpu->cr = vcpu->arch.cr; + svcpu->xer = vcpu->arch.xer; + svcpu->ctr = vcpu->arch.ctr; + svcpu->lr = vcpu->arch.lr; + svcpu->pc = vcpu->arch.pc; +} + +/* Copy data touched by real-mode code from shadow vcpu back to vcpu */ +void kvmppc_copy_from_svcpu(struct kvm_vcpu *vcpu, + struct kvmppc_book3s_shadow_vcpu *svcpu) +{ + vcpu->arch.gpr[0] = svcpu->gpr[0]; + vcpu->arch.gpr[1] = svcpu->gpr[1]; + vcpu->arch.gpr[2] = svcpu->gpr[2]; + vcpu->arch.gpr[3] = svcpu->gpr[3]; + vcpu->arch.gpr[4] = svcpu->gpr[4]; + vcpu->arch.gpr[5] = svcpu->gpr[5]; + vcpu->arch.gpr[6] = svcpu->gpr[6]; + vcpu->arch.gpr[7] = svcpu->gpr[7]; + vcpu->arch.gpr[8] = svcpu->gpr[8]; + vcpu->arch.gpr[9] = svcpu->gpr[9]; + vcpu->arch.gpr[10] = svcpu->gpr[10]; + vcpu->arch.gpr[11] = svcpu->gpr[11]; + vcpu->arch.gpr[12] = svcpu->gpr[12]; + vcpu->arch.gpr[13] = svcpu->gpr[13]; + vcpu->arch.cr = svcpu->cr; + vcpu->arch.xer = svcpu->xer; + vcpu->arch.ctr = svcpu->ctr; + vcpu->arch.lr = svcpu->lr; + vcpu->arch.pc = svcpu->pc; + vcpu->arch.shadow_srr1 = svcpu->shadow_srr1; + vcpu->arch.fault_dar = svcpu->fault_dar; + vcpu->arch.fault_dsisr = svcpu->fault_dsisr; + vcpu->arch.last_inst = svcpu->last_inst; +} + +static int kvmppc_core_check_requests_pr(struct kvm_vcpu *vcpu) { int r = 1; /* Indicate we want to get back into the guest */ @@ -100,44 +154,69 @@ int kvmppc_core_check_requests(struct kvm_vcpu *vcpu) } /************* MMU Notifiers *************/ +static void do_kvm_unmap_hva(struct kvm *kvm, unsigned long start, + unsigned long end) +{ + long i; + struct kvm_vcpu *vcpu; + struct kvm_memslots *slots; + struct kvm_memory_slot *memslot; + + slots = kvm_memslots(kvm); + kvm_for_each_memslot(memslot, slots) { + unsigned long hva_start, hva_end; + gfn_t gfn, gfn_end; + + hva_start = max(start, memslot->userspace_addr); + hva_end = min(end, memslot->userspace_addr + + (memslot->npages << PAGE_SHIFT)); + if (hva_start >= hva_end) + continue; + /* + * {gfn(page) | page intersects with [hva_start, hva_end)} = + * {gfn, gfn+1, ..., gfn_end-1}. + */ + gfn = hva_to_gfn_memslot(hva_start, memslot); + gfn_end = hva_to_gfn_memslot(hva_end + PAGE_SIZE - 1, memslot); + kvm_for_each_vcpu(i, vcpu, kvm) + kvmppc_mmu_pte_pflush(vcpu, gfn << PAGE_SHIFT, + gfn_end << PAGE_SHIFT); + } +} -int kvm_unmap_hva(struct kvm *kvm, unsigned long hva) +static int kvm_unmap_hva_pr(struct kvm *kvm, unsigned long hva) { trace_kvm_unmap_hva(hva); - /* - * Flush all shadow tlb entries everywhere. This is slow, but - * we are 100% sure that we catch the to be unmapped page - */ - kvm_flush_remote_tlbs(kvm); + do_kvm_unmap_hva(kvm, hva, hva + PAGE_SIZE); return 0; } -int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end) +static int kvm_unmap_hva_range_pr(struct kvm *kvm, unsigned long start, + unsigned long end) { - /* kvm_unmap_hva flushes everything anyways */ - kvm_unmap_hva(kvm, start); + do_kvm_unmap_hva(kvm, start, end); return 0; } -int kvm_age_hva(struct kvm *kvm, unsigned long hva) +static int kvm_age_hva_pr(struct kvm *kvm, unsigned long hva) { /* XXX could be more clever ;) */ return 0; } -int kvm_test_age_hva(struct kvm *kvm, unsigned long hva) +static int kvm_test_age_hva_pr(struct kvm *kvm, unsigned long hva) { /* XXX could be more clever ;) */ return 0; } -void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte) +static void kvm_set_spte_hva_pr(struct kvm *kvm, unsigned long hva, pte_t pte) { /* The page will get remapped properly on its next fault */ - kvm_unmap_hva(kvm, hva); + do_kvm_unmap_hva(kvm, hva, hva + PAGE_SIZE); } /*****************************************/ @@ -159,7 +238,7 @@ static void kvmppc_recalc_shadow_msr(struct kvm_vcpu *vcpu) vcpu->arch.shadow_msr = smsr; } -void kvmppc_set_msr(struct kvm_vcpu *vcpu, u64 msr) +static void kvmppc_set_msr_pr(struct kvm_vcpu *vcpu, u64 msr) { ulong old_msr = vcpu->arch.shared->msr; @@ -219,7 +298,7 @@ void kvmppc_set_msr(struct kvm_vcpu *vcpu, u64 msr) kvmppc_handle_ext(vcpu, BOOK3S_INTERRUPT_FP_UNAVAIL, MSR_FP); } -void kvmppc_set_pvr(struct kvm_vcpu *vcpu, u32 pvr) +void kvmppc_set_pvr_pr(struct kvm_vcpu *vcpu, u32 pvr) { u32 host_pvr; @@ -256,6 +335,23 @@ void kvmppc_set_pvr(struct kvm_vcpu *vcpu, u32 pvr) if (!strcmp(cur_cpu_spec->platform, "ppc-cell-be")) to_book3s(vcpu)->msr_mask &= ~(MSR_FE0 | MSR_FE1); + /* + * If they're asking for POWER6 or later, set the flag + * indicating that we can do multiple large page sizes + * and 1TB segments. + * Also set the flag that indicates that tlbie has the large + * page bit in the RB operand instead of the instruction. + */ + switch (PVR_VER(pvr)) { + case PVR_POWER6: + case PVR_POWER7: + case PVR_POWER7p: + case PVR_POWER8: + vcpu->arch.hflags |= BOOK3S_HFLAG_MULTI_PGSIZE | + BOOK3S_HFLAG_NEW_TLBIE; + break; + } + #ifdef CONFIG_PPC_BOOK3S_32 /* 32 bit Book3S always has 32 byte dcbz */ vcpu->arch.hflags |= BOOK3S_HFLAG_DCBZ32; @@ -334,6 +430,7 @@ int kvmppc_handle_pagefault(struct kvm_run *run, struct kvm_vcpu *vcpu, ulong eaddr, int vec) { bool data = (vec == BOOK3S_INTERRUPT_DATA_STORAGE); + bool iswrite = false; int r = RESUME_GUEST; int relocated; int page_found = 0; @@ -344,10 +441,12 @@ int kvmppc_handle_pagefault(struct kvm_run *run, struct kvm_vcpu *vcpu, u64 vsid; relocated = data ? dr : ir; + if (data && (vcpu->arch.fault_dsisr & DSISR_ISSTORE)) + iswrite = true; /* Resolve real address if translation turned on */ if (relocated) { - page_found = vcpu->arch.mmu.xlate(vcpu, eaddr, &pte, data); + page_found = vcpu->arch.mmu.xlate(vcpu, eaddr, &pte, data, iswrite); } else { pte.may_execute = true; pte.may_read = true; @@ -355,6 +454,7 @@ int kvmppc_handle_pagefault(struct kvm_run *run, struct kvm_vcpu *vcpu, pte.raddr = eaddr & KVM_PAM; pte.eaddr = eaddr; pte.vpage = eaddr >> 12; + pte.page_size = MMU_PAGE_64K; } switch (vcpu->arch.shared->msr & (MSR_DR|MSR_IR)) { @@ -388,22 +488,18 @@ int kvmppc_handle_pagefault(struct kvm_run *run, struct kvm_vcpu *vcpu, if (page_found == -ENOENT) { /* Page not found in guest PTE entries */ - struct kvmppc_book3s_shadow_vcpu *svcpu = svcpu_get(vcpu); vcpu->arch.shared->dar = kvmppc_get_fault_dar(vcpu); - vcpu->arch.shared->dsisr = svcpu->fault_dsisr; + vcpu->arch.shared->dsisr = vcpu->arch.fault_dsisr; vcpu->arch.shared->msr |= - (svcpu->shadow_srr1 & 0x00000000f8000000ULL); - svcpu_put(svcpu); + vcpu->arch.shadow_srr1 & 0x00000000f8000000ULL; kvmppc_book3s_queue_irqprio(vcpu, vec); } else if (page_found == -EPERM) { /* Storage protection */ - struct kvmppc_book3s_shadow_vcpu *svcpu = svcpu_get(vcpu); vcpu->arch.shared->dar = kvmppc_get_fault_dar(vcpu); - vcpu->arch.shared->dsisr = svcpu->fault_dsisr & ~DSISR_NOHPTE; + vcpu->arch.shared->dsisr = vcpu->arch.fault_dsisr & ~DSISR_NOHPTE; vcpu->arch.shared->dsisr |= DSISR_PROTFAULT; vcpu->arch.shared->msr |= - svcpu->shadow_srr1 & 0x00000000f8000000ULL; - svcpu_put(svcpu); + vcpu->arch.shadow_srr1 & 0x00000000f8000000ULL; kvmppc_book3s_queue_irqprio(vcpu, vec); } else if (page_found == -EINVAL) { /* Page not found in guest SLB */ @@ -411,12 +507,20 @@ int kvmppc_handle_pagefault(struct kvm_run *run, struct kvm_vcpu *vcpu, kvmppc_book3s_queue_irqprio(vcpu, vec + 0x80); } else if (!is_mmio && kvmppc_visible_gfn(vcpu, pte.raddr >> PAGE_SHIFT)) { + if (data && !(vcpu->arch.fault_dsisr & DSISR_NOHPTE)) { + /* + * There is already a host HPTE there, presumably + * a read-only one for a page the guest thinks + * is writable, so get rid of it first. + */ + kvmppc_mmu_unmap_page(vcpu, &pte); + } /* The guest's PTE is not mapped yet. Map on the host */ - kvmppc_mmu_map_page(vcpu, &pte); + kvmppc_mmu_map_page(vcpu, &pte, iswrite); if (data) vcpu->stat.sp_storage++; else if (vcpu->arch.mmu.is_dcbz32(vcpu) && - (!(vcpu->arch.hflags & BOOK3S_HFLAG_DCBZ32))) + (!(vcpu->arch.hflags & BOOK3S_HFLAG_DCBZ32))) kvmppc_patch_dcbz(vcpu, &pte); } else { /* MMIO */ @@ -444,7 +548,7 @@ void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr) #ifdef CONFIG_VSX u64 *vcpu_vsx = vcpu->arch.vsr; #endif - u64 *thread_fpr = (u64*)t->fpr; + u64 *thread_fpr = &t->fp_state.fpr[0][0]; int i; /* @@ -466,14 +570,14 @@ void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr) /* * Note that on CPUs with VSX, giveup_fpu stores * both the traditional FP registers and the added VSX - * registers into thread.fpr[]. + * registers into thread.fp_state.fpr[]. */ if (current->thread.regs->msr & MSR_FP) giveup_fpu(current); for (i = 0; i < ARRAY_SIZE(vcpu->arch.fpr); i++) vcpu_fpr[i] = thread_fpr[get_fpr_index(i)]; - vcpu->arch.fpscr = t->fpscr.val; + vcpu->arch.fpscr = t->fp_state.fpscr; #ifdef CONFIG_VSX if (cpu_has_feature(CPU_FTR_VSX)) @@ -486,8 +590,8 @@ void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr) if (msr & MSR_VEC) { if (current->thread.regs->msr & MSR_VEC) giveup_altivec(current); - memcpy(vcpu->arch.vr, t->vr, sizeof(vcpu->arch.vr)); - vcpu->arch.vscr = t->vscr; + memcpy(vcpu->arch.vr, t->vr_state.vr, sizeof(vcpu->arch.vr)); + vcpu->arch.vscr = t->vr_state.vscr; } #endif @@ -539,7 +643,7 @@ static int kvmppc_handle_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr, #ifdef CONFIG_VSX u64 *vcpu_vsx = vcpu->arch.vsr; #endif - u64 *thread_fpr = (u64*)t->fpr; + u64 *thread_fpr = &t->fp_state.fpr[0][0]; int i; /* When we have paired singles, we emulate in software */ @@ -584,15 +688,15 @@ static int kvmppc_handle_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr, for (i = 0; i < ARRAY_SIZE(vcpu->arch.vsr) / 2; i++) thread_fpr[get_fpr_index(i) + 1] = vcpu_vsx[i]; #endif - t->fpscr.val = vcpu->arch.fpscr; + t->fp_state.fpscr = vcpu->arch.fpscr; t->fpexc_mode = 0; kvmppc_load_up_fpu(); } if (msr & MSR_VEC) { #ifdef CONFIG_ALTIVEC - memcpy(t->vr, vcpu->arch.vr, sizeof(vcpu->arch.vr)); - t->vscr = vcpu->arch.vscr; + memcpy(t->vr_state.vr, vcpu->arch.vr, sizeof(vcpu->arch.vr)); + t->vr_state.vscr = vcpu->arch.vscr; t->vrsave = -1; kvmppc_load_up_altivec(); #endif @@ -619,13 +723,15 @@ static void kvmppc_handle_lost_ext(struct kvm_vcpu *vcpu) if (lost_ext & MSR_FP) kvmppc_load_up_fpu(); +#ifdef CONFIG_ALTIVEC if (lost_ext & MSR_VEC) kvmppc_load_up_altivec(); +#endif current->thread.regs->msr |= lost_ext; } -int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, - unsigned int exit_nr) +int kvmppc_handle_exit_pr(struct kvm_run *run, struct kvm_vcpu *vcpu, + unsigned int exit_nr) { int r = RESUME_HOST; int s; @@ -643,25 +749,32 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, switch (exit_nr) { case BOOK3S_INTERRUPT_INST_STORAGE: { - struct kvmppc_book3s_shadow_vcpu *svcpu = svcpu_get(vcpu); - ulong shadow_srr1 = svcpu->shadow_srr1; + ulong shadow_srr1 = vcpu->arch.shadow_srr1; vcpu->stat.pf_instruc++; #ifdef CONFIG_PPC_BOOK3S_32 /* We set segments as unused segments when invalidating them. So * treat the respective fault as segment fault. */ - if (svcpu->sr[kvmppc_get_pc(vcpu) >> SID_SHIFT] == SR_INVALID) { - kvmppc_mmu_map_segment(vcpu, kvmppc_get_pc(vcpu)); - r = RESUME_GUEST; + { + struct kvmppc_book3s_shadow_vcpu *svcpu; + u32 sr; + + svcpu = svcpu_get(vcpu); + sr = svcpu->sr[kvmppc_get_pc(vcpu) >> SID_SHIFT]; svcpu_put(svcpu); - break; + if (sr == SR_INVALID) { + kvmppc_mmu_map_segment(vcpu, kvmppc_get_pc(vcpu)); + r = RESUME_GUEST; + break; + } } #endif - svcpu_put(svcpu); /* only care about PTEG not found errors, but leave NX alone */ if (shadow_srr1 & 0x40000000) { + int idx = srcu_read_lock(&vcpu->kvm->srcu); r = kvmppc_handle_pagefault(run, vcpu, kvmppc_get_pc(vcpu), exit_nr); + srcu_read_unlock(&vcpu->kvm->srcu, idx); vcpu->stat.sp_instruc++; } else if (vcpu->arch.mmu.is_dcbz32(vcpu) && (!(vcpu->arch.hflags & BOOK3S_HFLAG_DCBZ32))) { @@ -682,25 +795,36 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, case BOOK3S_INTERRUPT_DATA_STORAGE: { ulong dar = kvmppc_get_fault_dar(vcpu); - struct kvmppc_book3s_shadow_vcpu *svcpu = svcpu_get(vcpu); - u32 fault_dsisr = svcpu->fault_dsisr; + u32 fault_dsisr = vcpu->arch.fault_dsisr; vcpu->stat.pf_storage++; #ifdef CONFIG_PPC_BOOK3S_32 /* We set segments as unused segments when invalidating them. So * treat the respective fault as segment fault. */ - if ((svcpu->sr[dar >> SID_SHIFT]) == SR_INVALID) { - kvmppc_mmu_map_segment(vcpu, dar); - r = RESUME_GUEST; + { + struct kvmppc_book3s_shadow_vcpu *svcpu; + u32 sr; + + svcpu = svcpu_get(vcpu); + sr = svcpu->sr[dar >> SID_SHIFT]; svcpu_put(svcpu); - break; + if (sr == SR_INVALID) { + kvmppc_mmu_map_segment(vcpu, dar); + r = RESUME_GUEST; + break; + } } #endif - svcpu_put(svcpu); - /* The only case we need to handle is missing shadow PTEs */ - if (fault_dsisr & DSISR_NOHPTE) { + /* + * We need to handle missing shadow PTEs, and + * protection faults due to us mapping a page read-only + * when the guest thinks it is writable. + */ + if (fault_dsisr & (DSISR_NOHPTE | DSISR_PROTFAULT)) { + int idx = srcu_read_lock(&vcpu->kvm->srcu); r = kvmppc_handle_pagefault(run, vcpu, dar, exit_nr); + srcu_read_unlock(&vcpu->kvm->srcu, idx); } else { vcpu->arch.shared->dar = dar; vcpu->arch.shared->dsisr = fault_dsisr; @@ -743,13 +867,10 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, case BOOK3S_INTERRUPT_H_EMUL_ASSIST: { enum emulation_result er; - struct kvmppc_book3s_shadow_vcpu *svcpu; ulong flags; program_interrupt: - svcpu = svcpu_get(vcpu); - flags = svcpu->shadow_srr1 & 0x1f0000ull; - svcpu_put(svcpu); + flags = vcpu->arch.shadow_srr1 & 0x1f0000ull; if (vcpu->arch.shared->msr & MSR_PR) { #ifdef EXIT_DEBUG @@ -798,7 +919,7 @@ program_interrupt: ulong cmd = kvmppc_get_gpr(vcpu, 3); int i; -#ifdef CONFIG_KVM_BOOK3S_64_PR +#ifdef CONFIG_PPC_BOOK3S_64 if (kvmppc_h_pr(vcpu, cmd) == EMULATE_DONE) { r = RESUME_GUEST; break; @@ -881,9 +1002,7 @@ program_interrupt: break; default: { - struct kvmppc_book3s_shadow_vcpu *svcpu = svcpu_get(vcpu); - ulong shadow_srr1 = svcpu->shadow_srr1; - svcpu_put(svcpu); + ulong shadow_srr1 = vcpu->arch.shadow_srr1; /* Ugh - bork here! What did we get? */ printk(KERN_EMERG "exit_nr=0x%x | pc=0x%lx | msr=0x%lx\n", exit_nr, kvmppc_get_pc(vcpu), shadow_srr1); @@ -920,8 +1039,8 @@ program_interrupt: return r; } -int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, - struct kvm_sregs *sregs) +static int kvm_arch_vcpu_ioctl_get_sregs_pr(struct kvm_vcpu *vcpu, + struct kvm_sregs *sregs) { struct kvmppc_vcpu_book3s *vcpu3s = to_book3s(vcpu); int i; @@ -947,13 +1066,13 @@ int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, return 0; } -int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, - struct kvm_sregs *sregs) +static int kvm_arch_vcpu_ioctl_set_sregs_pr(struct kvm_vcpu *vcpu, + struct kvm_sregs *sregs) { struct kvmppc_vcpu_book3s *vcpu3s = to_book3s(vcpu); int i; - kvmppc_set_pvr(vcpu, sregs->pvr); + kvmppc_set_pvr_pr(vcpu, sregs->pvr); vcpu3s->sdr1 = sregs->u.s.sdr1; if (vcpu->arch.hflags & BOOK3S_HFLAG_SLB) { @@ -983,7 +1102,8 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, return 0; } -int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id, union kvmppc_one_reg *val) +static int kvmppc_get_one_reg_pr(struct kvm_vcpu *vcpu, u64 id, + union kvmppc_one_reg *val) { int r = 0; @@ -1012,7 +1132,8 @@ int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id, union kvmppc_one_reg *val) return r; } -int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id, union kvmppc_one_reg *val) +static int kvmppc_set_one_reg_pr(struct kvm_vcpu *vcpu, u64 id, + union kvmppc_one_reg *val) { int r = 0; @@ -1042,28 +1163,30 @@ int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id, union kvmppc_one_reg *val) return r; } -int kvmppc_core_check_processor_compat(void) -{ - return 0; -} - -struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) +static struct kvm_vcpu *kvmppc_core_vcpu_create_pr(struct kvm *kvm, + unsigned int id) { struct kvmppc_vcpu_book3s *vcpu_book3s; struct kvm_vcpu *vcpu; int err = -ENOMEM; unsigned long p; - vcpu_book3s = vzalloc(sizeof(struct kvmppc_vcpu_book3s)); - if (!vcpu_book3s) + vcpu = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL); + if (!vcpu) goto out; - vcpu_book3s->shadow_vcpu = - kzalloc(sizeof(*vcpu_book3s->shadow_vcpu), GFP_KERNEL); - if (!vcpu_book3s->shadow_vcpu) + vcpu_book3s = vzalloc(sizeof(struct kvmppc_vcpu_book3s)); + if (!vcpu_book3s) goto free_vcpu; + vcpu->arch.book3s = vcpu_book3s; + +#ifdef CONFIG_KVM_BOOK3S_32 + vcpu->arch.shadow_vcpu = + kzalloc(sizeof(*vcpu->arch.shadow_vcpu), GFP_KERNEL); + if (!vcpu->arch.shadow_vcpu) + goto free_vcpu3s; +#endif - vcpu = &vcpu_book3s->vcpu; err = kvm_vcpu_init(vcpu, kvm, id); if (err) goto free_shadow_vcpu; @@ -1076,13 +1199,19 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) vcpu->arch.shared = (void *)(p + PAGE_SIZE - 4096); #ifdef CONFIG_PPC_BOOK3S_64 - /* default to book3s_64 (970fx) */ + /* + * Default to the same as the host if we're on sufficiently + * recent machine that we have 1TB segments; + * otherwise default to PPC970FX. + */ vcpu->arch.pvr = 0x3C0301; + if (mmu_has_feature(MMU_FTR_1T_SEGMENT)) + vcpu->arch.pvr = mfspr(SPRN_PVR); #else /* default to book3s_32 (750) */ vcpu->arch.pvr = 0x84202; #endif - kvmppc_set_pvr(vcpu, vcpu->arch.pvr); + kvmppc_set_pvr_pr(vcpu, vcpu->arch.pvr); vcpu->arch.slb_nr = 64; vcpu->arch.shadow_msr = MSR_USER64; @@ -1096,32 +1225,37 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) uninit_vcpu: kvm_vcpu_uninit(vcpu); free_shadow_vcpu: - kfree(vcpu_book3s->shadow_vcpu); -free_vcpu: +#ifdef CONFIG_KVM_BOOK3S_32 + kfree(vcpu->arch.shadow_vcpu); +free_vcpu3s: +#endif vfree(vcpu_book3s); +free_vcpu: + kmem_cache_free(kvm_vcpu_cache, vcpu); out: return ERR_PTR(err); } -void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu) +static void kvmppc_core_vcpu_free_pr(struct kvm_vcpu *vcpu) { struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu); free_page((unsigned long)vcpu->arch.shared & PAGE_MASK); kvm_vcpu_uninit(vcpu); - kfree(vcpu_book3s->shadow_vcpu); +#ifdef CONFIG_KVM_BOOK3S_32 + kfree(vcpu->arch.shadow_vcpu); +#endif vfree(vcpu_book3s); + kmem_cache_free(kvm_vcpu_cache, vcpu); } -int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) +static int kvmppc_vcpu_run_pr(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) { int ret; - double fpr[32][TS_FPRWIDTH]; - unsigned int fpscr; + struct thread_fp_state fp; int fpexc_mode; #ifdef CONFIG_ALTIVEC - vector128 vr[32]; - vector128 vscr; + struct thread_vr_state vr; unsigned long uninitialized_var(vrsave); int used_vr; #endif @@ -1153,8 +1287,7 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) /* Save FPU state in stack */ if (current->thread.regs->msr & MSR_FP) giveup_fpu(current); - memcpy(fpr, current->thread.fpr, sizeof(current->thread.fpr)); - fpscr = current->thread.fpscr.val; + fp = current->thread.fp_state; fpexc_mode = current->thread.fpexc_mode; #ifdef CONFIG_ALTIVEC @@ -1163,8 +1296,7 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) if (used_vr) { if (current->thread.regs->msr & MSR_VEC) giveup_altivec(current); - memcpy(vr, current->thread.vr, sizeof(current->thread.vr)); - vscr = current->thread.vscr; + vr = current->thread.vr_state; vrsave = current->thread.vrsave; } #endif @@ -1196,15 +1328,13 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) current->thread.regs->msr = ext_msr; /* Restore FPU/VSX state from stack */ - memcpy(current->thread.fpr, fpr, sizeof(current->thread.fpr)); - current->thread.fpscr.val = fpscr; + current->thread.fp_state = fp; current->thread.fpexc_mode = fpexc_mode; #ifdef CONFIG_ALTIVEC /* Restore Altivec state from stack */ if (used_vr && current->thread.used_vr) { - memcpy(current->thread.vr, vr, sizeof(current->thread.vr)); - current->thread.vscr = vscr; + current->thread.vr_state = vr; current->thread.vrsave = vrsave; } current->thread.used_vr = used_vr; @@ -1222,8 +1352,8 @@ out: /* * Get (and clear) the dirty memory log for a memory slot. */ -int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, - struct kvm_dirty_log *log) +static int kvm_vm_ioctl_get_dirty_log_pr(struct kvm *kvm, + struct kvm_dirty_log *log) { struct kvm_memory_slot *memslot; struct kvm_vcpu *vcpu; @@ -1258,67 +1388,100 @@ out: return r; } -#ifdef CONFIG_PPC64 -int kvm_vm_ioctl_get_smmu_info(struct kvm *kvm, struct kvm_ppc_smmu_info *info) +static void kvmppc_core_flush_memslot_pr(struct kvm *kvm, + struct kvm_memory_slot *memslot) { - info->flags = KVM_PPC_1T_SEGMENTS; - - /* SLB is always 64 entries */ - info->slb_size = 64; - - /* Standard 4k base page size segment */ - info->sps[0].page_shift = 12; - info->sps[0].slb_enc = 0; - info->sps[0].enc[0].page_shift = 12; - info->sps[0].enc[0].pte_enc = 0; - - /* Standard 16M large page size segment */ - info->sps[1].page_shift = 24; - info->sps[1].slb_enc = SLB_VSID_L; - info->sps[1].enc[0].page_shift = 24; - info->sps[1].enc[0].pte_enc = 0; + return; +} +static int kvmppc_core_prepare_memory_region_pr(struct kvm *kvm, + struct kvm_memory_slot *memslot, + struct kvm_userspace_memory_region *mem) +{ return 0; } -#endif /* CONFIG_PPC64 */ -void kvmppc_core_free_memslot(struct kvm_memory_slot *free, - struct kvm_memory_slot *dont) +static void kvmppc_core_commit_memory_region_pr(struct kvm *kvm, + struct kvm_userspace_memory_region *mem, + const struct kvm_memory_slot *old) { + return; } -int kvmppc_core_create_memslot(struct kvm_memory_slot *slot, - unsigned long npages) +static void kvmppc_core_free_memslot_pr(struct kvm_memory_slot *free, + struct kvm_memory_slot *dont) { - return 0; + return; } -int kvmppc_core_prepare_memory_region(struct kvm *kvm, - struct kvm_memory_slot *memslot, - struct kvm_userspace_memory_region *mem) +static int kvmppc_core_create_memslot_pr(struct kvm_memory_slot *slot, + unsigned long npages) { return 0; } -void kvmppc_core_commit_memory_region(struct kvm *kvm, - struct kvm_userspace_memory_region *mem, - const struct kvm_memory_slot *old) + +#ifdef CONFIG_PPC64 +static int kvm_vm_ioctl_get_smmu_info_pr(struct kvm *kvm, + struct kvm_ppc_smmu_info *info) { -} + long int i; + struct kvm_vcpu *vcpu; + + info->flags = 0; + + /* SLB is always 64 entries */ + info->slb_size = 64; + + /* Standard 4k base page size segment */ + info->sps[0].page_shift = 12; + info->sps[0].slb_enc = 0; + info->sps[0].enc[0].page_shift = 12; + info->sps[0].enc[0].pte_enc = 0; + + /* + * 64k large page size. + * We only want to put this in if the CPUs we're emulating + * support it, but unfortunately we don't have a vcpu easily + * to hand here to test. Just pick the first vcpu, and if + * that doesn't exist yet, report the minimum capability, + * i.e., no 64k pages. + * 1T segment support goes along with 64k pages. + */ + i = 1; + vcpu = kvm_get_vcpu(kvm, 0); + if (vcpu && (vcpu->arch.hflags & BOOK3S_HFLAG_MULTI_PGSIZE)) { + info->flags = KVM_PPC_1T_SEGMENTS; + info->sps[i].page_shift = 16; + info->sps[i].slb_enc = SLB_VSID_L | SLB_VSID_LP_01; + info->sps[i].enc[0].page_shift = 16; + info->sps[i].enc[0].pte_enc = 1; + ++i; + } + + /* Standard 16M large page size segment */ + info->sps[i].page_shift = 24; + info->sps[i].slb_enc = SLB_VSID_L; + info->sps[i].enc[0].page_shift = 24; + info->sps[i].enc[0].pte_enc = 0; -void kvmppc_core_flush_memslot(struct kvm *kvm, struct kvm_memory_slot *memslot) + return 0; +} +#else +static int kvm_vm_ioctl_get_smmu_info_pr(struct kvm *kvm, + struct kvm_ppc_smmu_info *info) { + /* We should not get called */ + BUG(); } +#endif /* CONFIG_PPC64 */ static unsigned int kvm_global_user_count = 0; static DEFINE_SPINLOCK(kvm_global_user_count_lock); -int kvmppc_core_init_vm(struct kvm *kvm) +static int kvmppc_core_init_vm_pr(struct kvm *kvm) { -#ifdef CONFIG_PPC64 - INIT_LIST_HEAD(&kvm->arch.spapr_tce_tables); - INIT_LIST_HEAD(&kvm->arch.rtas_tokens); -#endif + mutex_init(&kvm->arch.hpt_mutex); if (firmware_has_feature(FW_FEATURE_SET_MODE)) { spin_lock(&kvm_global_user_count_lock); @@ -1329,7 +1492,7 @@ int kvmppc_core_init_vm(struct kvm *kvm) return 0; } -void kvmppc_core_destroy_vm(struct kvm *kvm) +static void kvmppc_core_destroy_vm_pr(struct kvm *kvm) { #ifdef CONFIG_PPC64 WARN_ON(!list_empty(&kvm->arch.spapr_tce_tables)); @@ -1344,26 +1507,81 @@ void kvmppc_core_destroy_vm(struct kvm *kvm) } } -static int kvmppc_book3s_init(void) +static int kvmppc_core_check_processor_compat_pr(void) { - int r; + /* we are always compatible */ + return 0; +} - r = kvm_init(NULL, sizeof(struct kvmppc_vcpu_book3s), 0, - THIS_MODULE); +static long kvm_arch_vm_ioctl_pr(struct file *filp, + unsigned int ioctl, unsigned long arg) +{ + return -ENOTTY; +} - if (r) +static struct kvmppc_ops kvm_ops_pr = { + .get_sregs = kvm_arch_vcpu_ioctl_get_sregs_pr, + .set_sregs = kvm_arch_vcpu_ioctl_set_sregs_pr, + .get_one_reg = kvmppc_get_one_reg_pr, + .set_one_reg = kvmppc_set_one_reg_pr, + .vcpu_load = kvmppc_core_vcpu_load_pr, + .vcpu_put = kvmppc_core_vcpu_put_pr, + .set_msr = kvmppc_set_msr_pr, + .vcpu_run = kvmppc_vcpu_run_pr, + .vcpu_create = kvmppc_core_vcpu_create_pr, + .vcpu_free = kvmppc_core_vcpu_free_pr, + .check_requests = kvmppc_core_check_requests_pr, + .get_dirty_log = kvm_vm_ioctl_get_dirty_log_pr, + .flush_memslot = kvmppc_core_flush_memslot_pr, + .prepare_memory_region = kvmppc_core_prepare_memory_region_pr, + .commit_memory_region = kvmppc_core_commit_memory_region_pr, + .unmap_hva = kvm_unmap_hva_pr, + .unmap_hva_range = kvm_unmap_hva_range_pr, + .age_hva = kvm_age_hva_pr, + .test_age_hva = kvm_test_age_hva_pr, + .set_spte_hva = kvm_set_spte_hva_pr, + .mmu_destroy = kvmppc_mmu_destroy_pr, + .free_memslot = kvmppc_core_free_memslot_pr, + .create_memslot = kvmppc_core_create_memslot_pr, + .init_vm = kvmppc_core_init_vm_pr, + .destroy_vm = kvmppc_core_destroy_vm_pr, + .get_smmu_info = kvm_vm_ioctl_get_smmu_info_pr, + .emulate_op = kvmppc_core_emulate_op_pr, + .emulate_mtspr = kvmppc_core_emulate_mtspr_pr, + .emulate_mfspr = kvmppc_core_emulate_mfspr_pr, + .fast_vcpu_kick = kvm_vcpu_kick, + .arch_vm_ioctl = kvm_arch_vm_ioctl_pr, +}; + + +int kvmppc_book3s_init_pr(void) +{ + int r; + + r = kvmppc_core_check_processor_compat_pr(); + if (r < 0) return r; - r = kvmppc_mmu_hpte_sysinit(); + kvm_ops_pr.owner = THIS_MODULE; + kvmppc_pr_ops = &kvm_ops_pr; + r = kvmppc_mmu_hpte_sysinit(); return r; } -static void kvmppc_book3s_exit(void) +void kvmppc_book3s_exit_pr(void) { + kvmppc_pr_ops = NULL; kvmppc_mmu_hpte_sysexit(); - kvm_exit(); } -module_init(kvmppc_book3s_init); -module_exit(kvmppc_book3s_exit); +/* + * We only support separate modules for book3s 64 + */ +#ifdef CONFIG_PPC_BOOK3S_64 + +module_init(kvmppc_book3s_init_pr); +module_exit(kvmppc_book3s_exit_pr); + +MODULE_LICENSE("GPL"); +#endif diff --git a/arch/powerpc/kvm/book3s_pr_papr.c b/arch/powerpc/kvm/book3s_pr_papr.c index da0e0bc268bd..5efa97b993d8 100644 --- a/arch/powerpc/kvm/book3s_pr_papr.c +++ b/arch/powerpc/kvm/book3s_pr_papr.c @@ -21,6 +21,8 @@ #include <asm/kvm_ppc.h> #include <asm/kvm_book3s.h> +#define HPTE_SIZE 16 /* bytes per HPT entry */ + static unsigned long get_pteg_addr(struct kvm_vcpu *vcpu, long pte_index) { struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu); @@ -40,32 +42,41 @@ static int kvmppc_h_pr_enter(struct kvm_vcpu *vcpu) long pte_index = kvmppc_get_gpr(vcpu, 5); unsigned long pteg[2 * 8]; unsigned long pteg_addr, i, *hpte; + long int ret; + i = pte_index & 7; pte_index &= ~7UL; pteg_addr = get_pteg_addr(vcpu, pte_index); + mutex_lock(&vcpu->kvm->arch.hpt_mutex); copy_from_user(pteg, (void __user *)pteg_addr, sizeof(pteg)); hpte = pteg; + ret = H_PTEG_FULL; if (likely((flags & H_EXACT) == 0)) { - pte_index &= ~7UL; for (i = 0; ; ++i) { if (i == 8) - return H_PTEG_FULL; + goto done; if ((*hpte & HPTE_V_VALID) == 0) break; hpte += 2; } } else { - i = kvmppc_get_gpr(vcpu, 5) & 7UL; hpte += i * 2; + if (*hpte & HPTE_V_VALID) + goto done; } hpte[0] = kvmppc_get_gpr(vcpu, 6); hpte[1] = kvmppc_get_gpr(vcpu, 7); - copy_to_user((void __user *)pteg_addr, pteg, sizeof(pteg)); - kvmppc_set_gpr(vcpu, 3, H_SUCCESS); + pteg_addr += i * HPTE_SIZE; + copy_to_user((void __user *)pteg_addr, hpte, HPTE_SIZE); kvmppc_set_gpr(vcpu, 4, pte_index | i); + ret = H_SUCCESS; + + done: + mutex_unlock(&vcpu->kvm->arch.hpt_mutex); + kvmppc_set_gpr(vcpu, 3, ret); return EMULATE_DONE; } @@ -77,26 +88,31 @@ static int kvmppc_h_pr_remove(struct kvm_vcpu *vcpu) unsigned long avpn = kvmppc_get_gpr(vcpu, 6); unsigned long v = 0, pteg, rb; unsigned long pte[2]; + long int ret; pteg = get_pteg_addr(vcpu, pte_index); + mutex_lock(&vcpu->kvm->arch.hpt_mutex); copy_from_user(pte, (void __user *)pteg, sizeof(pte)); + ret = H_NOT_FOUND; if ((pte[0] & HPTE_V_VALID) == 0 || ((flags & H_AVPN) && (pte[0] & ~0x7fUL) != avpn) || - ((flags & H_ANDCOND) && (pte[0] & avpn) != 0)) { - kvmppc_set_gpr(vcpu, 3, H_NOT_FOUND); - return EMULATE_DONE; - } + ((flags & H_ANDCOND) && (pte[0] & avpn) != 0)) + goto done; copy_to_user((void __user *)pteg, &v, sizeof(v)); rb = compute_tlbie_rb(pte[0], pte[1], pte_index); vcpu->arch.mmu.tlbie(vcpu, rb, rb & 1 ? true : false); - kvmppc_set_gpr(vcpu, 3, H_SUCCESS); + ret = H_SUCCESS; kvmppc_set_gpr(vcpu, 4, pte[0]); kvmppc_set_gpr(vcpu, 5, pte[1]); + done: + mutex_unlock(&vcpu->kvm->arch.hpt_mutex); + kvmppc_set_gpr(vcpu, 3, ret); + return EMULATE_DONE; } @@ -124,6 +140,7 @@ static int kvmppc_h_pr_bulk_remove(struct kvm_vcpu *vcpu) int paramnr = 4; int ret = H_SUCCESS; + mutex_lock(&vcpu->kvm->arch.hpt_mutex); for (i = 0; i < H_BULK_REMOVE_MAX_BATCH; i++) { unsigned long tsh = kvmppc_get_gpr(vcpu, paramnr+(2*i)); unsigned long tsl = kvmppc_get_gpr(vcpu, paramnr+(2*i)+1); @@ -172,6 +189,7 @@ static int kvmppc_h_pr_bulk_remove(struct kvm_vcpu *vcpu) } kvmppc_set_gpr(vcpu, paramnr+(2*i), tsh); } + mutex_unlock(&vcpu->kvm->arch.hpt_mutex); kvmppc_set_gpr(vcpu, 3, ret); return EMULATE_DONE; @@ -184,15 +202,16 @@ static int kvmppc_h_pr_protect(struct kvm_vcpu *vcpu) unsigned long avpn = kvmppc_get_gpr(vcpu, 6); unsigned long rb, pteg, r, v; unsigned long pte[2]; + long int ret; pteg = get_pteg_addr(vcpu, pte_index); + mutex_lock(&vcpu->kvm->arch.hpt_mutex); copy_from_user(pte, (void __user *)pteg, sizeof(pte)); + ret = H_NOT_FOUND; if ((pte[0] & HPTE_V_VALID) == 0 || - ((flags & H_AVPN) && (pte[0] & ~0x7fUL) != avpn)) { - kvmppc_set_gpr(vcpu, 3, H_NOT_FOUND); - return EMULATE_DONE; - } + ((flags & H_AVPN) && (pte[0] & ~0x7fUL) != avpn)) + goto done; v = pte[0]; r = pte[1]; @@ -207,8 +226,11 @@ static int kvmppc_h_pr_protect(struct kvm_vcpu *vcpu) rb = compute_tlbie_rb(v, r, pte_index); vcpu->arch.mmu.tlbie(vcpu, rb, rb & 1 ? true : false); copy_to_user((void __user *)pteg, pte, sizeof(pte)); + ret = H_SUCCESS; - kvmppc_set_gpr(vcpu, 3, H_SUCCESS); + done: + mutex_unlock(&vcpu->kvm->arch.hpt_mutex); + kvmppc_set_gpr(vcpu, 3, ret); return EMULATE_DONE; } diff --git a/arch/powerpc/kvm/book3s_rmhandlers.S b/arch/powerpc/kvm/book3s_rmhandlers.S index 8f7633e3afb8..a38c4c9edab8 100644 --- a/arch/powerpc/kvm/book3s_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_rmhandlers.S @@ -38,32 +38,6 @@ #define FUNC(name) GLUE(.,name) - .globl kvmppc_skip_interrupt -kvmppc_skip_interrupt: - /* - * Here all GPRs are unchanged from when the interrupt happened - * except for r13, which is saved in SPRG_SCRATCH0. - */ - mfspr r13, SPRN_SRR0 - addi r13, r13, 4 - mtspr SPRN_SRR0, r13 - GET_SCRATCH0(r13) - rfid - b . - - .globl kvmppc_skip_Hinterrupt -kvmppc_skip_Hinterrupt: - /* - * Here all GPRs are unchanged from when the interrupt happened - * except for r13, which is saved in SPRG_SCRATCH0. - */ - mfspr r13, SPRN_HSRR0 - addi r13, r13, 4 - mtspr SPRN_HSRR0, r13 - GET_SCRATCH0(r13) - hrfid - b . - #elif defined(CONFIG_PPC_BOOK3S_32) #define FUNC(name) name @@ -179,11 +153,15 @@ _GLOBAL(kvmppc_entry_trampoline) li r6, MSR_IR | MSR_DR andc r6, r5, r6 /* Clear DR and IR in MSR value */ +#ifdef CONFIG_PPC_BOOK3S_32 /* * Set EE in HOST_MSR so that it's enabled when we get into our - * C exit handler function + * C exit handler function. On 64-bit we delay enabling + * interrupts until we have finished transferring stuff + * to or from the PACA. */ ori r5, r5, MSR_EE +#endif mtsrr0 r7 mtsrr1 r6 RFI diff --git a/arch/powerpc/kvm/book3s_rtas.c b/arch/powerpc/kvm/book3s_rtas.c index 3219ba895246..cf95cdef73c9 100644 --- a/arch/powerpc/kvm/book3s_rtas.c +++ b/arch/powerpc/kvm/book3s_rtas.c @@ -260,6 +260,7 @@ fail: */ return rc; } +EXPORT_SYMBOL_GPL(kvmppc_rtas_hcall); void kvmppc_rtas_tokens_free(struct kvm *kvm) { diff --git a/arch/powerpc/kvm/book3s_segment.S b/arch/powerpc/kvm/book3s_segment.S index 1abe4788191a..bc50c97751d3 100644 --- a/arch/powerpc/kvm/book3s_segment.S +++ b/arch/powerpc/kvm/book3s_segment.S @@ -161,8 +161,8 @@ kvmppc_handler_trampoline_enter_end: .global kvmppc_handler_trampoline_exit kvmppc_handler_trampoline_exit: -.global kvmppc_interrupt -kvmppc_interrupt: +.global kvmppc_interrupt_pr +kvmppc_interrupt_pr: /* Register usage at this point: * diff --git a/arch/powerpc/kvm/book3s_xics.c b/arch/powerpc/kvm/book3s_xics.c index a3a5cb8ee7ea..02a17dcf1610 100644 --- a/arch/powerpc/kvm/book3s_xics.c +++ b/arch/powerpc/kvm/book3s_xics.c @@ -818,7 +818,7 @@ int kvmppc_xics_hcall(struct kvm_vcpu *vcpu, u32 req) } /* Check for real mode returning too hard */ - if (xics->real_mode) + if (xics->real_mode && is_kvmppc_hv_enabled(vcpu->kvm)) return kvmppc_xics_rm_complete(vcpu, req); switch (req) { @@ -840,6 +840,7 @@ int kvmppc_xics_hcall(struct kvm_vcpu *vcpu, u32 req) return rc; } +EXPORT_SYMBOL_GPL(kvmppc_xics_hcall); /* -- Initialisation code etc. -- */ @@ -1250,13 +1251,13 @@ static int kvmppc_xics_create(struct kvm_device *dev, u32 type) xics_debugfs_init(xics); -#ifdef CONFIG_KVM_BOOK3S_64_HV +#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE if (cpu_has_feature(CPU_FTR_ARCH_206)) { /* Enable real mode support */ xics->real_mode = ENABLE_REALMODE; xics->real_mode_dbg = DEBUG_REALMODE; } -#endif /* CONFIG_KVM_BOOK3S_64_HV */ +#endif /* CONFIG_KVM_BOOK3S_HV_POSSIBLE */ return 0; } diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index 17722d82f1d1..53e65a210b9a 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c @@ -40,7 +40,9 @@ #include "timing.h" #include "booke.h" -#include "trace.h" + +#define CREATE_TRACE_POINTS +#include "trace_booke.h" unsigned long kvmppc_booke_handlers; @@ -133,6 +135,29 @@ static void kvmppc_vcpu_sync_fpu(struct kvm_vcpu *vcpu) #endif } +static void kvmppc_vcpu_sync_debug(struct kvm_vcpu *vcpu) +{ + /* Synchronize guest's desire to get debug interrupts into shadow MSR */ +#ifndef CONFIG_KVM_BOOKE_HV + vcpu->arch.shadow_msr &= ~MSR_DE; + vcpu->arch.shadow_msr |= vcpu->arch.shared->msr & MSR_DE; +#endif + + /* Force enable debug interrupts when user space wants to debug */ + if (vcpu->guest_debug) { +#ifdef CONFIG_KVM_BOOKE_HV + /* + * Since there is no shadow MSR, sync MSR_DE into the guest + * visible MSR. + */ + vcpu->arch.shared->msr |= MSR_DE; +#else + vcpu->arch.shadow_msr |= MSR_DE; + vcpu->arch.shared->msr &= ~MSR_DE; +#endif + } +} + /* * Helper function for "full" MSR writes. No need to call this if only * EE/CE/ME/DE/RI are changing. @@ -150,6 +175,7 @@ void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32 new_msr) kvmppc_mmu_msr_notify(vcpu, old_msr); kvmppc_vcpu_sync_spe(vcpu); kvmppc_vcpu_sync_fpu(vcpu); + kvmppc_vcpu_sync_debug(vcpu); } static void kvmppc_booke_queue_irqprio(struct kvm_vcpu *vcpu, @@ -655,10 +681,10 @@ int kvmppc_core_check_requests(struct kvm_vcpu *vcpu) int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) { int ret, s; + struct thread_struct thread; #ifdef CONFIG_PPC_FPU - unsigned int fpscr; + struct thread_fp_state fp; int fpexc_mode; - u64 fpr[32]; #endif if (!vcpu->arch.sane) { @@ -677,13 +703,13 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) #ifdef CONFIG_PPC_FPU /* Save userspace FPU state in stack */ enable_kernel_fp(); - memcpy(fpr, current->thread.fpr, sizeof(current->thread.fpr)); - fpscr = current->thread.fpscr.val; + fp = current->thread.fp_state; fpexc_mode = current->thread.fpexc_mode; /* Restore guest FPU state to thread */ - memcpy(current->thread.fpr, vcpu->arch.fpr, sizeof(vcpu->arch.fpr)); - current->thread.fpscr.val = vcpu->arch.fpscr; + memcpy(current->thread.fp_state.fpr, vcpu->arch.fpr, + sizeof(vcpu->arch.fpr)); + current->thread.fp_state.fpscr = vcpu->arch.fpscr; /* * Since we can't trap on MSR_FP in GS-mode, we consider the guest @@ -696,6 +722,12 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) kvmppc_load_guest_fp(vcpu); #endif + /* Switch to guest debug context */ + thread.debug = vcpu->arch.shadow_dbg_reg; + switch_booke_debug_regs(&thread); + thread.debug = current->thread.debug; + current->thread.debug = vcpu->arch.shadow_dbg_reg; + kvmppc_fix_ee_before_entry(); ret = __kvmppc_vcpu_run(kvm_run, vcpu); @@ -703,18 +735,22 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) /* No need for kvm_guest_exit. It's done in handle_exit. We also get here with interrupts enabled. */ + /* Switch back to user space debug context */ + switch_booke_debug_regs(&thread); + current->thread.debug = thread.debug; + #ifdef CONFIG_PPC_FPU kvmppc_save_guest_fp(vcpu); vcpu->fpu_active = 0; /* Save guest FPU state from thread */ - memcpy(vcpu->arch.fpr, current->thread.fpr, sizeof(vcpu->arch.fpr)); - vcpu->arch.fpscr = current->thread.fpscr.val; + memcpy(vcpu->arch.fpr, current->thread.fp_state.fpr, + sizeof(vcpu->arch.fpr)); + vcpu->arch.fpscr = current->thread.fp_state.fpscr; /* Restore userspace FPU state from stack */ - memcpy(current->thread.fpr, fpr, sizeof(current->thread.fpr)); - current->thread.fpscr.val = fpscr; + current->thread.fp_state = fp; current->thread.fpexc_mode = fpexc_mode; #endif @@ -758,6 +794,30 @@ static int emulation_exit(struct kvm_run *run, struct kvm_vcpu *vcpu) } } +static int kvmppc_handle_debug(struct kvm_run *run, struct kvm_vcpu *vcpu) +{ + struct debug_reg *dbg_reg = &(vcpu->arch.shadow_dbg_reg); + u32 dbsr = vcpu->arch.dbsr; + + run->debug.arch.status = 0; + run->debug.arch.address = vcpu->arch.pc; + + if (dbsr & (DBSR_IAC1 | DBSR_IAC2 | DBSR_IAC3 | DBSR_IAC4)) { + run->debug.arch.status |= KVMPPC_DEBUG_BREAKPOINT; + } else { + if (dbsr & (DBSR_DAC1W | DBSR_DAC2W)) + run->debug.arch.status |= KVMPPC_DEBUG_WATCH_WRITE; + else if (dbsr & (DBSR_DAC1R | DBSR_DAC2R)) + run->debug.arch.status |= KVMPPC_DEBUG_WATCH_READ; + if (dbsr & (DBSR_DAC1R | DBSR_DAC1W)) + run->debug.arch.address = dbg_reg->dac1; + else if (dbsr & (DBSR_DAC2R | DBSR_DAC2W)) + run->debug.arch.address = dbg_reg->dac2; + } + + return RESUME_HOST; +} + static void kvmppc_fill_pt_regs(struct pt_regs *regs) { ulong r1, ip, msr, lr; @@ -818,6 +878,11 @@ static void kvmppc_restart_interrupt(struct kvm_vcpu *vcpu, case BOOKE_INTERRUPT_CRITICAL: unknown_exception(®s); break; + case BOOKE_INTERRUPT_DEBUG: + /* Save DBSR before preemption is enabled */ + vcpu->arch.dbsr = mfspr(SPRN_DBSR); + kvmppc_clear_dbsr(); + break; } } @@ -1135,18 +1200,10 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, } case BOOKE_INTERRUPT_DEBUG: { - u32 dbsr; - - vcpu->arch.pc = mfspr(SPRN_CSRR0); - - /* clear IAC events in DBSR register */ - dbsr = mfspr(SPRN_DBSR); - dbsr &= DBSR_IAC1 | DBSR_IAC2 | DBSR_IAC3 | DBSR_IAC4; - mtspr(SPRN_DBSR, dbsr); - - run->exit_reason = KVM_EXIT_DEBUG; + r = kvmppc_handle_debug(run, vcpu); + if (r == RESUME_HOST) + run->exit_reason = KVM_EXIT_DEBUG; kvmppc_account_exit(vcpu, DEBUG_EXITS); - r = RESUME_HOST; break; } @@ -1197,7 +1254,7 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) kvmppc_set_msr(vcpu, 0); #ifndef CONFIG_KVM_BOOKE_HV - vcpu->arch.shadow_msr = MSR_USER | MSR_DE | MSR_IS | MSR_DS; + vcpu->arch.shadow_msr = MSR_USER | MSR_IS | MSR_DS; vcpu->arch.shadow_pid = 1; vcpu->arch.shared->msr = 0; #endif @@ -1359,7 +1416,7 @@ static int set_sregs_arch206(struct kvm_vcpu *vcpu, return 0; } -void kvmppc_get_sregs_ivor(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) +int kvmppc_get_sregs_ivor(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) { sregs->u.e.features |= KVM_SREGS_E_IVOR; @@ -1379,6 +1436,7 @@ void kvmppc_get_sregs_ivor(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) sregs->u.e.ivor_low[13] = vcpu->arch.ivor[BOOKE_IRQPRIO_DTLB_MISS]; sregs->u.e.ivor_low[14] = vcpu->arch.ivor[BOOKE_IRQPRIO_ITLB_MISS]; sregs->u.e.ivor_low[15] = vcpu->arch.ivor[BOOKE_IRQPRIO_DEBUG]; + return 0; } int kvmppc_set_sregs_ivor(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) @@ -1413,8 +1471,7 @@ int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, get_sregs_base(vcpu, sregs); get_sregs_arch206(vcpu, sregs); - kvmppc_core_get_sregs(vcpu, sregs); - return 0; + return vcpu->kvm->arch.kvm_ops->get_sregs(vcpu, sregs); } int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, @@ -1433,7 +1490,7 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, if (ret < 0) return ret; - return kvmppc_core_set_sregs(vcpu, sregs); + return vcpu->kvm->arch.kvm_ops->set_sregs(vcpu, sregs); } int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) @@ -1441,7 +1498,6 @@ int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) int r = 0; union kvmppc_one_reg val; int size; - long int i; size = one_reg_size(reg->id); if (size > sizeof(val)) @@ -1449,16 +1505,24 @@ int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) switch (reg->id) { case KVM_REG_PPC_IAC1: + val = get_reg_val(reg->id, vcpu->arch.dbg_reg.iac1); + break; case KVM_REG_PPC_IAC2: + val = get_reg_val(reg->id, vcpu->arch.dbg_reg.iac2); + break; +#if CONFIG_PPC_ADV_DEBUG_IACS > 2 case KVM_REG_PPC_IAC3: + val = get_reg_val(reg->id, vcpu->arch.dbg_reg.iac3); + break; case KVM_REG_PPC_IAC4: - i = reg->id - KVM_REG_PPC_IAC1; - val = get_reg_val(reg->id, vcpu->arch.dbg_reg.iac[i]); + val = get_reg_val(reg->id, vcpu->arch.dbg_reg.iac4); break; +#endif case KVM_REG_PPC_DAC1: + val = get_reg_val(reg->id, vcpu->arch.dbg_reg.dac1); + break; case KVM_REG_PPC_DAC2: - i = reg->id - KVM_REG_PPC_DAC1; - val = get_reg_val(reg->id, vcpu->arch.dbg_reg.dac[i]); + val = get_reg_val(reg->id, vcpu->arch.dbg_reg.dac2); break; case KVM_REG_PPC_EPR: { u32 epr = get_guest_epr(vcpu); @@ -1477,10 +1541,13 @@ int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) val = get_reg_val(reg->id, vcpu->arch.tsr); break; case KVM_REG_PPC_DEBUG_INST: - val = get_reg_val(reg->id, KVMPPC_INST_EHPRIV); + val = get_reg_val(reg->id, KVMPPC_INST_EHPRIV_DEBUG); + break; + case KVM_REG_PPC_VRSAVE: + val = get_reg_val(reg->id, vcpu->arch.vrsave); break; default: - r = kvmppc_get_one_reg(vcpu, reg->id, &val); + r = vcpu->kvm->arch.kvm_ops->get_one_reg(vcpu, reg->id, &val); break; } @@ -1498,7 +1565,6 @@ int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) int r = 0; union kvmppc_one_reg val; int size; - long int i; size = one_reg_size(reg->id); if (size > sizeof(val)) @@ -1509,16 +1575,24 @@ int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) switch (reg->id) { case KVM_REG_PPC_IAC1: + vcpu->arch.dbg_reg.iac1 = set_reg_val(reg->id, val); + break; case KVM_REG_PPC_IAC2: + vcpu->arch.dbg_reg.iac2 = set_reg_val(reg->id, val); + break; +#if CONFIG_PPC_ADV_DEBUG_IACS > 2 case KVM_REG_PPC_IAC3: + vcpu->arch.dbg_reg.iac3 = set_reg_val(reg->id, val); + break; case KVM_REG_PPC_IAC4: - i = reg->id - KVM_REG_PPC_IAC1; - vcpu->arch.dbg_reg.iac[i] = set_reg_val(reg->id, val); + vcpu->arch.dbg_reg.iac4 = set_reg_val(reg->id, val); break; +#endif case KVM_REG_PPC_DAC1: + vcpu->arch.dbg_reg.dac1 = set_reg_val(reg->id, val); + break; case KVM_REG_PPC_DAC2: - i = reg->id - KVM_REG_PPC_DAC1; - vcpu->arch.dbg_reg.dac[i] = set_reg_val(reg->id, val); + vcpu->arch.dbg_reg.dac2 = set_reg_val(reg->id, val); break; case KVM_REG_PPC_EPR: { u32 new_epr = set_reg_val(reg->id, val); @@ -1552,20 +1626,17 @@ int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) kvmppc_set_tcr(vcpu, tcr); break; } + case KVM_REG_PPC_VRSAVE: + vcpu->arch.vrsave = set_reg_val(reg->id, val); + break; default: - r = kvmppc_set_one_reg(vcpu, reg->id, &val); + r = vcpu->kvm->arch.kvm_ops->set_one_reg(vcpu, reg->id, &val); break; } return r; } -int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, - struct kvm_guest_debug *dbg) -{ - return -EINVAL; -} - int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) { return -ENOTSUPP; @@ -1590,12 +1661,12 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log) return -ENOTSUPP; } -void kvmppc_core_free_memslot(struct kvm_memory_slot *free, +void kvmppc_core_free_memslot(struct kvm *kvm, struct kvm_memory_slot *free, struct kvm_memory_slot *dont) { } -int kvmppc_core_create_memslot(struct kvm_memory_slot *slot, +int kvmppc_core_create_memslot(struct kvm *kvm, struct kvm_memory_slot *slot, unsigned long npages) { return 0; @@ -1671,6 +1742,157 @@ void kvmppc_decrementer_func(unsigned long data) kvmppc_set_tsr_bits(vcpu, TSR_DIS); } +static int kvmppc_booke_add_breakpoint(struct debug_reg *dbg_reg, + uint64_t addr, int index) +{ + switch (index) { + case 0: + dbg_reg->dbcr0 |= DBCR0_IAC1; + dbg_reg->iac1 = addr; + break; + case 1: + dbg_reg->dbcr0 |= DBCR0_IAC2; + dbg_reg->iac2 = addr; + break; +#if CONFIG_PPC_ADV_DEBUG_IACS > 2 + case 2: + dbg_reg->dbcr0 |= DBCR0_IAC3; + dbg_reg->iac3 = addr; + break; + case 3: + dbg_reg->dbcr0 |= DBCR0_IAC4; + dbg_reg->iac4 = addr; + break; +#endif + default: + return -EINVAL; + } + + dbg_reg->dbcr0 |= DBCR0_IDM; + return 0; +} + +static int kvmppc_booke_add_watchpoint(struct debug_reg *dbg_reg, uint64_t addr, + int type, int index) +{ + switch (index) { + case 0: + if (type & KVMPPC_DEBUG_WATCH_READ) + dbg_reg->dbcr0 |= DBCR0_DAC1R; + if (type & KVMPPC_DEBUG_WATCH_WRITE) + dbg_reg->dbcr0 |= DBCR0_DAC1W; + dbg_reg->dac1 = addr; + break; + case 1: + if (type & KVMPPC_DEBUG_WATCH_READ) + dbg_reg->dbcr0 |= DBCR0_DAC2R; + if (type & KVMPPC_DEBUG_WATCH_WRITE) + dbg_reg->dbcr0 |= DBCR0_DAC2W; + dbg_reg->dac2 = addr; + break; + default: + return -EINVAL; + } + + dbg_reg->dbcr0 |= DBCR0_IDM; + return 0; +} +void kvm_guest_protect_msr(struct kvm_vcpu *vcpu, ulong prot_bitmap, bool set) +{ + /* XXX: Add similar MSR protection for BookE-PR */ +#ifdef CONFIG_KVM_BOOKE_HV + BUG_ON(prot_bitmap & ~(MSRP_UCLEP | MSRP_DEP | MSRP_PMMP)); + if (set) { + if (prot_bitmap & MSR_UCLE) + vcpu->arch.shadow_msrp |= MSRP_UCLEP; + if (prot_bitmap & MSR_DE) + vcpu->arch.shadow_msrp |= MSRP_DEP; + if (prot_bitmap & MSR_PMM) + vcpu->arch.shadow_msrp |= MSRP_PMMP; + } else { + if (prot_bitmap & MSR_UCLE) + vcpu->arch.shadow_msrp &= ~MSRP_UCLEP; + if (prot_bitmap & MSR_DE) + vcpu->arch.shadow_msrp &= ~MSRP_DEP; + if (prot_bitmap & MSR_PMM) + vcpu->arch.shadow_msrp &= ~MSRP_PMMP; + } +#endif +} + +int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, + struct kvm_guest_debug *dbg) +{ + struct debug_reg *dbg_reg; + int n, b = 0, w = 0; + + if (!(dbg->control & KVM_GUESTDBG_ENABLE)) { + vcpu->arch.shadow_dbg_reg.dbcr0 = 0; + vcpu->guest_debug = 0; + kvm_guest_protect_msr(vcpu, MSR_DE, false); + return 0; + } + + kvm_guest_protect_msr(vcpu, MSR_DE, true); + vcpu->guest_debug = dbg->control; + vcpu->arch.shadow_dbg_reg.dbcr0 = 0; + /* Set DBCR0_EDM in guest visible DBCR0 register. */ + vcpu->arch.dbg_reg.dbcr0 = DBCR0_EDM; + + if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) + vcpu->arch.shadow_dbg_reg.dbcr0 |= DBCR0_IDM | DBCR0_IC; + + /* Code below handles only HW breakpoints */ + dbg_reg = &(vcpu->arch.shadow_dbg_reg); + +#ifdef CONFIG_KVM_BOOKE_HV + /* + * On BookE-HV (e500mc) the guest is always executed with MSR.GS=1 + * DBCR1 and DBCR2 are set to trigger debug events when MSR.PR is 0 + */ + dbg_reg->dbcr1 = 0; + dbg_reg->dbcr2 = 0; +#else + /* + * On BookE-PR (e500v2) the guest is always executed with MSR.PR=1 + * We set DBCR1 and DBCR2 to only trigger debug events when MSR.PR + * is set. + */ + dbg_reg->dbcr1 = DBCR1_IAC1US | DBCR1_IAC2US | DBCR1_IAC3US | + DBCR1_IAC4US; + dbg_reg->dbcr2 = DBCR2_DAC1US | DBCR2_DAC2US; +#endif + + if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) + return 0; + + for (n = 0; n < (KVMPPC_BOOKE_IAC_NUM + KVMPPC_BOOKE_DAC_NUM); n++) { + uint64_t addr = dbg->arch.bp[n].addr; + uint32_t type = dbg->arch.bp[n].type; + + if (type == KVMPPC_DEBUG_NONE) + continue; + + if (type & !(KVMPPC_DEBUG_WATCH_READ | + KVMPPC_DEBUG_WATCH_WRITE | + KVMPPC_DEBUG_BREAKPOINT)) + return -EINVAL; + + if (type & KVMPPC_DEBUG_BREAKPOINT) { + /* Setting H/W breakpoint */ + if (kvmppc_booke_add_breakpoint(dbg_reg, addr, b++)) + return -EINVAL; + } else { + /* Setting H/W watchpoint */ + if (kvmppc_booke_add_watchpoint(dbg_reg, addr, + type, w++)) + return -EINVAL; + } + } + + return 0; +} + void kvmppc_booke_vcpu_load(struct kvm_vcpu *vcpu, int cpu) { vcpu->cpu = smp_processor_id(); @@ -1681,6 +1903,44 @@ void kvmppc_booke_vcpu_put(struct kvm_vcpu *vcpu) { current->thread.kvm_vcpu = NULL; vcpu->cpu = -1; + + /* Clear pending debug event in DBSR */ + kvmppc_clear_dbsr(); +} + +void kvmppc_mmu_destroy(struct kvm_vcpu *vcpu) +{ + vcpu->kvm->arch.kvm_ops->mmu_destroy(vcpu); +} + +int kvmppc_core_init_vm(struct kvm *kvm) +{ + return kvm->arch.kvm_ops->init_vm(kvm); +} + +struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) +{ + return kvm->arch.kvm_ops->vcpu_create(kvm, id); +} + +void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu) +{ + vcpu->kvm->arch.kvm_ops->vcpu_free(vcpu); +} + +void kvmppc_core_destroy_vm(struct kvm *kvm) +{ + kvm->arch.kvm_ops->destroy_vm(kvm); +} + +void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu) +{ + vcpu->kvm->arch.kvm_ops->vcpu_load(vcpu, cpu); +} + +void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu) +{ + vcpu->kvm->arch.kvm_ops->vcpu_put(vcpu); } int __init kvmppc_booke_init(void) diff --git a/arch/powerpc/kvm/booke.h b/arch/powerpc/kvm/booke.h index 5fd1ba693579..09bfd9bc7cf8 100644 --- a/arch/powerpc/kvm/booke.h +++ b/arch/powerpc/kvm/booke.h @@ -99,6 +99,30 @@ enum int_class { void kvmppc_set_pending_interrupt(struct kvm_vcpu *vcpu, enum int_class type); +extern void kvmppc_mmu_destroy_44x(struct kvm_vcpu *vcpu); +extern int kvmppc_core_emulate_op_44x(struct kvm_run *run, struct kvm_vcpu *vcpu, + unsigned int inst, int *advance); +extern int kvmppc_core_emulate_mtspr_44x(struct kvm_vcpu *vcpu, int sprn, + ulong spr_val); +extern int kvmppc_core_emulate_mfspr_44x(struct kvm_vcpu *vcpu, int sprn, + ulong *spr_val); +extern void kvmppc_mmu_destroy_e500(struct kvm_vcpu *vcpu); +extern int kvmppc_core_emulate_op_e500(struct kvm_run *run, + struct kvm_vcpu *vcpu, + unsigned int inst, int *advance); +extern int kvmppc_core_emulate_mtspr_e500(struct kvm_vcpu *vcpu, int sprn, + ulong spr_val); +extern int kvmppc_core_emulate_mfspr_e500(struct kvm_vcpu *vcpu, int sprn, + ulong *spr_val); +extern void kvmppc_mmu_destroy_e500(struct kvm_vcpu *vcpu); +extern int kvmppc_core_emulate_op_e500(struct kvm_run *run, + struct kvm_vcpu *vcpu, + unsigned int inst, int *advance); +extern int kvmppc_core_emulate_mtspr_e500(struct kvm_vcpu *vcpu, int sprn, + ulong spr_val); +extern int kvmppc_core_emulate_mfspr_e500(struct kvm_vcpu *vcpu, int sprn, + ulong *spr_val); + /* * Load up guest vcpu FP state if it's needed. * It also set the MSR_FP in thread so that host know @@ -129,4 +153,9 @@ static inline void kvmppc_save_guest_fp(struct kvm_vcpu *vcpu) giveup_fpu(current); #endif } + +static inline void kvmppc_clear_dbsr(void) +{ + mtspr(SPRN_DBSR, mfspr(SPRN_DBSR)); +} #endif /* __KVM_BOOKE_H__ */ diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c index ce6b73c29612..497b142f651c 100644 --- a/arch/powerpc/kvm/e500.c +++ b/arch/powerpc/kvm/e500.c @@ -305,7 +305,7 @@ void kvmppc_core_load_guest_debugstate(struct kvm_vcpu *vcpu) { } -void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu) +static void kvmppc_core_vcpu_load_e500(struct kvm_vcpu *vcpu, int cpu) { kvmppc_booke_vcpu_load(vcpu, cpu); @@ -313,7 +313,7 @@ void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu) kvmppc_e500_recalc_shadow_pid(to_e500(vcpu)); } -void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu) +static void kvmppc_core_vcpu_put_e500(struct kvm_vcpu *vcpu) { #ifdef CONFIG_SPE if (vcpu->arch.shadow_msr & MSR_SPE) @@ -367,7 +367,8 @@ int kvmppc_core_vcpu_setup(struct kvm_vcpu *vcpu) return 0; } -void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) +static int kvmppc_core_get_sregs_e500(struct kvm_vcpu *vcpu, + struct kvm_sregs *sregs) { struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); @@ -388,9 +389,11 @@ void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) kvmppc_get_sregs_ivor(vcpu, sregs); kvmppc_get_sregs_e500_tlb(vcpu, sregs); + return 0; } -int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) +static int kvmppc_core_set_sregs_e500(struct kvm_vcpu *vcpu, + struct kvm_sregs *sregs) { struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); int ret; @@ -425,21 +428,22 @@ int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) return kvmppc_set_sregs_ivor(vcpu, sregs); } -int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id, - union kvmppc_one_reg *val) +static int kvmppc_get_one_reg_e500(struct kvm_vcpu *vcpu, u64 id, + union kvmppc_one_reg *val) { int r = kvmppc_get_one_reg_e500_tlb(vcpu, id, val); return r; } -int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id, - union kvmppc_one_reg *val) +static int kvmppc_set_one_reg_e500(struct kvm_vcpu *vcpu, u64 id, + union kvmppc_one_reg *val) { int r = kvmppc_get_one_reg_e500_tlb(vcpu, id, val); return r; } -struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) +static struct kvm_vcpu *kvmppc_core_vcpu_create_e500(struct kvm *kvm, + unsigned int id) { struct kvmppc_vcpu_e500 *vcpu_e500; struct kvm_vcpu *vcpu; @@ -481,7 +485,7 @@ out: return ERR_PTR(err); } -void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu) +static void kvmppc_core_vcpu_free_e500(struct kvm_vcpu *vcpu) { struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); @@ -492,15 +496,32 @@ void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu) kmem_cache_free(kvm_vcpu_cache, vcpu_e500); } -int kvmppc_core_init_vm(struct kvm *kvm) +static int kvmppc_core_init_vm_e500(struct kvm *kvm) { return 0; } -void kvmppc_core_destroy_vm(struct kvm *kvm) +static void kvmppc_core_destroy_vm_e500(struct kvm *kvm) { } +static struct kvmppc_ops kvm_ops_e500 = { + .get_sregs = kvmppc_core_get_sregs_e500, + .set_sregs = kvmppc_core_set_sregs_e500, + .get_one_reg = kvmppc_get_one_reg_e500, + .set_one_reg = kvmppc_set_one_reg_e500, + .vcpu_load = kvmppc_core_vcpu_load_e500, + .vcpu_put = kvmppc_core_vcpu_put_e500, + .vcpu_create = kvmppc_core_vcpu_create_e500, + .vcpu_free = kvmppc_core_vcpu_free_e500, + .mmu_destroy = kvmppc_mmu_destroy_e500, + .init_vm = kvmppc_core_init_vm_e500, + .destroy_vm = kvmppc_core_destroy_vm_e500, + .emulate_op = kvmppc_core_emulate_op_e500, + .emulate_mtspr = kvmppc_core_emulate_mtspr_e500, + .emulate_mfspr = kvmppc_core_emulate_mfspr_e500, +}; + static int __init kvmppc_e500_init(void) { int r, i; @@ -512,11 +533,11 @@ static int __init kvmppc_e500_init(void) r = kvmppc_core_check_processor_compat(); if (r) - return r; + goto err_out; r = kvmppc_booke_init(); if (r) - return r; + goto err_out; /* copy extra E500 exception handlers */ ivor[0] = mfspr(SPRN_IVOR32); @@ -534,11 +555,19 @@ static int __init kvmppc_e500_init(void) flush_icache_range(kvmppc_booke_handlers, kvmppc_booke_handlers + ivor[max_ivor] + handler_len); - return kvm_init(NULL, sizeof(struct kvmppc_vcpu_e500), 0, THIS_MODULE); + r = kvm_init(NULL, sizeof(struct kvmppc_vcpu_e500), 0, THIS_MODULE); + if (r) + goto err_out; + kvm_ops_e500.owner = THIS_MODULE; + kvmppc_pr_ops = &kvm_ops_e500; + +err_out: + return r; } static void __exit kvmppc_e500_exit(void) { + kvmppc_pr_ops = NULL; kvmppc_booke_exit(); } diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h index c2e5e98453a6..4fd9650eb018 100644 --- a/arch/powerpc/kvm/e500.h +++ b/arch/powerpc/kvm/e500.h @@ -117,7 +117,7 @@ static inline struct kvmppc_vcpu_e500 *to_e500(struct kvm_vcpu *vcpu) #define E500_TLB_USER_PERM_MASK (MAS3_UX|MAS3_UR|MAS3_UW) #define E500_TLB_SUPER_PERM_MASK (MAS3_SX|MAS3_SR|MAS3_SW) #define MAS2_ATTRIB_MASK \ - (MAS2_X0 | MAS2_X1) + (MAS2_X0 | MAS2_X1 | MAS2_E | MAS2_G) #define MAS3_ATTRIB_MASK \ (MAS3_U0 | MAS3_U1 | MAS3_U2 | MAS3_U3 \ | E500_TLB_USER_PERM_MASK | E500_TLB_SUPER_PERM_MASK) diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c index b10a01243abd..89b7f821f6c4 100644 --- a/arch/powerpc/kvm/e500_emulate.c +++ b/arch/powerpc/kvm/e500_emulate.c @@ -26,6 +26,7 @@ #define XOP_TLBRE 946 #define XOP_TLBWE 978 #define XOP_TLBILX 18 +#define XOP_EHPRIV 270 #ifdef CONFIG_KVM_E500MC static int dbell2prio(ulong param) @@ -82,8 +83,28 @@ static int kvmppc_e500_emul_msgsnd(struct kvm_vcpu *vcpu, int rb) } #endif -int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, - unsigned int inst, int *advance) +static int kvmppc_e500_emul_ehpriv(struct kvm_run *run, struct kvm_vcpu *vcpu, + unsigned int inst, int *advance) +{ + int emulated = EMULATE_DONE; + + switch (get_oc(inst)) { + case EHPRIV_OC_DEBUG: + run->exit_reason = KVM_EXIT_DEBUG; + run->debug.arch.address = vcpu->arch.pc; + run->debug.arch.status = 0; + kvmppc_account_exit(vcpu, DEBUG_EXITS); + emulated = EMULATE_EXIT_USER; + *advance = 0; + break; + default: + emulated = EMULATE_FAIL; + } + return emulated; +} + +int kvmppc_core_emulate_op_e500(struct kvm_run *run, struct kvm_vcpu *vcpu, + unsigned int inst, int *advance) { int emulated = EMULATE_DONE; int ra = get_ra(inst); @@ -130,6 +151,11 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, emulated = kvmppc_e500_emul_tlbivax(vcpu, ea); break; + case XOP_EHPRIV: + emulated = kvmppc_e500_emul_ehpriv(run, vcpu, inst, + advance); + break; + default: emulated = EMULATE_FAIL; } @@ -146,7 +172,7 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, return emulated; } -int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val) +int kvmppc_core_emulate_mtspr_e500(struct kvm_vcpu *vcpu, int sprn, ulong spr_val) { struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); int emulated = EMULATE_DONE; @@ -237,7 +263,7 @@ int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val) return emulated; } -int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val) +int kvmppc_core_emulate_mfspr_e500(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val) { struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); int emulated = EMULATE_DONE; diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c index 6d6f153b6c1d..ebca6b88ea5e 100644 --- a/arch/powerpc/kvm/e500_mmu.c +++ b/arch/powerpc/kvm/e500_mmu.c @@ -32,7 +32,7 @@ #include <asm/kvm_ppc.h> #include "e500.h" -#include "trace.h" +#include "trace_booke.h" #include "timing.h" #include "e500_mmu_host.h" @@ -536,7 +536,7 @@ gpa_t kvmppc_mmu_xlate(struct kvm_vcpu *vcpu, unsigned int index, return get_tlb_raddr(gtlbe) | (eaddr & pgmask); } -void kvmppc_mmu_destroy(struct kvm_vcpu *vcpu) +void kvmppc_mmu_destroy_e500(struct kvm_vcpu *vcpu) { } diff --git a/arch/powerpc/kvm/e500_mmu_host.c b/arch/powerpc/kvm/e500_mmu_host.c index c65593abae8e..ecf2247b13be 100644 --- a/arch/powerpc/kvm/e500_mmu_host.c +++ b/arch/powerpc/kvm/e500_mmu_host.c @@ -32,10 +32,11 @@ #include <asm/kvm_ppc.h> #include "e500.h" -#include "trace.h" #include "timing.h" #include "e500_mmu_host.h" +#include "trace_booke.h" + #define to_htlb1_esel(esel) (host_tlb_params[1].entries - (esel) - 1) static struct kvmppc_e500_tlb_params host_tlb_params[E500_TLB_NUM]; @@ -253,6 +254,9 @@ static inline void kvmppc_e500_ref_setup(struct tlbe_ref *ref, ref->pfn = pfn; ref->flags |= E500_TLB_VALID; + /* Mark the page accessed */ + kvm_set_pfn_accessed(pfn); + if (tlbe_is_writable(gtlbe)) kvm_set_pfn_dirty(pfn); } diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c index 19c8379575f7..4132cd2fc171 100644 --- a/arch/powerpc/kvm/e500mc.c +++ b/arch/powerpc/kvm/e500mc.c @@ -110,7 +110,7 @@ void kvmppc_mmu_msr_notify(struct kvm_vcpu *vcpu, u32 old_msr) static DEFINE_PER_CPU(struct kvm_vcpu *, last_vcpu_on_cpu); -void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu) +static void kvmppc_core_vcpu_load_e500mc(struct kvm_vcpu *vcpu, int cpu) { struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); @@ -147,7 +147,7 @@ void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu) kvmppc_load_guest_fp(vcpu); } -void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu) +static void kvmppc_core_vcpu_put_e500mc(struct kvm_vcpu *vcpu) { vcpu->arch.eplc = mfspr(SPRN_EPLC); vcpu->arch.epsc = mfspr(SPRN_EPSC); @@ -204,7 +204,8 @@ int kvmppc_core_vcpu_setup(struct kvm_vcpu *vcpu) return 0; } -void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) +static int kvmppc_core_get_sregs_e500mc(struct kvm_vcpu *vcpu, + struct kvm_sregs *sregs) { struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); @@ -224,10 +225,11 @@ void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) sregs->u.e.ivor_high[4] = vcpu->arch.ivor[BOOKE_IRQPRIO_DBELL]; sregs->u.e.ivor_high[5] = vcpu->arch.ivor[BOOKE_IRQPRIO_DBELL_CRIT]; - kvmppc_get_sregs_ivor(vcpu, sregs); + return kvmppc_get_sregs_ivor(vcpu, sregs); } -int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) +static int kvmppc_core_set_sregs_e500mc(struct kvm_vcpu *vcpu, + struct kvm_sregs *sregs) { struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); int ret; @@ -260,21 +262,22 @@ int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) return kvmppc_set_sregs_ivor(vcpu, sregs); } -int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id, - union kvmppc_one_reg *val) +static int kvmppc_get_one_reg_e500mc(struct kvm_vcpu *vcpu, u64 id, + union kvmppc_one_reg *val) { int r = kvmppc_get_one_reg_e500_tlb(vcpu, id, val); return r; } -int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id, - union kvmppc_one_reg *val) +static int kvmppc_set_one_reg_e500mc(struct kvm_vcpu *vcpu, u64 id, + union kvmppc_one_reg *val) { int r = kvmppc_set_one_reg_e500_tlb(vcpu, id, val); return r; } -struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) +static struct kvm_vcpu *kvmppc_core_vcpu_create_e500mc(struct kvm *kvm, + unsigned int id) { struct kvmppc_vcpu_e500 *vcpu_e500; struct kvm_vcpu *vcpu; @@ -315,7 +318,7 @@ out: return ERR_PTR(err); } -void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu) +static void kvmppc_core_vcpu_free_e500mc(struct kvm_vcpu *vcpu) { struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); @@ -325,7 +328,7 @@ void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu) kmem_cache_free(kvm_vcpu_cache, vcpu_e500); } -int kvmppc_core_init_vm(struct kvm *kvm) +static int kvmppc_core_init_vm_e500mc(struct kvm *kvm) { int lpid; @@ -337,27 +340,52 @@ int kvmppc_core_init_vm(struct kvm *kvm) return 0; } -void kvmppc_core_destroy_vm(struct kvm *kvm) +static void kvmppc_core_destroy_vm_e500mc(struct kvm *kvm) { kvmppc_free_lpid(kvm->arch.lpid); } +static struct kvmppc_ops kvm_ops_e500mc = { + .get_sregs = kvmppc_core_get_sregs_e500mc, + .set_sregs = kvmppc_core_set_sregs_e500mc, + .get_one_reg = kvmppc_get_one_reg_e500mc, + .set_one_reg = kvmppc_set_one_reg_e500mc, + .vcpu_load = kvmppc_core_vcpu_load_e500mc, + .vcpu_put = kvmppc_core_vcpu_put_e500mc, + .vcpu_create = kvmppc_core_vcpu_create_e500mc, + .vcpu_free = kvmppc_core_vcpu_free_e500mc, + .mmu_destroy = kvmppc_mmu_destroy_e500, + .init_vm = kvmppc_core_init_vm_e500mc, + .destroy_vm = kvmppc_core_destroy_vm_e500mc, + .emulate_op = kvmppc_core_emulate_op_e500, + .emulate_mtspr = kvmppc_core_emulate_mtspr_e500, + .emulate_mfspr = kvmppc_core_emulate_mfspr_e500, +}; + static int __init kvmppc_e500mc_init(void) { int r; r = kvmppc_booke_init(); if (r) - return r; + goto err_out; kvmppc_init_lpid(64); kvmppc_claim_lpid(0); /* host */ - return kvm_init(NULL, sizeof(struct kvmppc_vcpu_e500), 0, THIS_MODULE); + r = kvm_init(NULL, sizeof(struct kvmppc_vcpu_e500), 0, THIS_MODULE); + if (r) + goto err_out; + kvm_ops_e500mc.owner = THIS_MODULE; + kvmppc_pr_ops = &kvm_ops_e500mc; + +err_out: + return r; } static void __exit kvmppc_e500mc_exit(void) { + kvmppc_pr_ops = NULL; kvmppc_booke_exit(); } diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c index 751cd45f65a0..2f9a0873b44f 100644 --- a/arch/powerpc/kvm/emulate.c +++ b/arch/powerpc/kvm/emulate.c @@ -130,8 +130,8 @@ static int kvmppc_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs) case SPRN_PIR: break; default: - emulated = kvmppc_core_emulate_mtspr(vcpu, sprn, - spr_val); + emulated = vcpu->kvm->arch.kvm_ops->emulate_mtspr(vcpu, sprn, + spr_val); if (emulated == EMULATE_FAIL) printk(KERN_INFO "mtspr: unknown spr " "0x%x\n", sprn); @@ -191,8 +191,8 @@ static int kvmppc_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt) spr_val = kvmppc_get_dec(vcpu, get_tb()); break; default: - emulated = kvmppc_core_emulate_mfspr(vcpu, sprn, - &spr_val); + emulated = vcpu->kvm->arch.kvm_ops->emulate_mfspr(vcpu, sprn, + &spr_val); if (unlikely(emulated == EMULATE_FAIL)) { printk(KERN_INFO "mfspr: unknown spr " "0x%x\n", sprn); @@ -464,7 +464,8 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) } if (emulated == EMULATE_FAIL) { - emulated = kvmppc_core_emulate_op(run, vcpu, inst, &advance); + emulated = vcpu->kvm->arch.kvm_ops->emulate_op(run, vcpu, inst, + &advance); if (emulated == EMULATE_AGAIN) { advance = 0; } else if (emulated == EMULATE_FAIL) { @@ -483,3 +484,4 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) return emulated; } +EXPORT_SYMBOL_GPL(kvmppc_emulate_instruction); diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 07c0106fab76..9ae97686e9f4 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -26,6 +26,7 @@ #include <linux/fs.h> #include <linux/slab.h> #include <linux/file.h> +#include <linux/module.h> #include <asm/cputable.h> #include <asm/uaccess.h> #include <asm/kvm_ppc.h> @@ -39,6 +40,12 @@ #define CREATE_TRACE_POINTS #include "trace.h" +struct kvmppc_ops *kvmppc_hv_ops; +EXPORT_SYMBOL_GPL(kvmppc_hv_ops); +struct kvmppc_ops *kvmppc_pr_ops; +EXPORT_SYMBOL_GPL(kvmppc_pr_ops); + + int kvm_arch_vcpu_runnable(struct kvm_vcpu *v) { return !!(v->arch.pending_exceptions) || @@ -50,7 +57,6 @@ int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu) return 1; } -#ifndef CONFIG_KVM_BOOK3S_64_HV /* * Common checks before entering the guest world. Call with interrupts * disabled. @@ -125,7 +131,7 @@ int kvmppc_prepare_to_enter(struct kvm_vcpu *vcpu) return r; } -#endif /* CONFIG_KVM_BOOK3S_64_HV */ +EXPORT_SYMBOL_GPL(kvmppc_prepare_to_enter); int kvmppc_kvm_pv(struct kvm_vcpu *vcpu) { @@ -179,6 +185,7 @@ int kvmppc_kvm_pv(struct kvm_vcpu *vcpu) return r; } +EXPORT_SYMBOL_GPL(kvmppc_kvm_pv); int kvmppc_sanity_check(struct kvm_vcpu *vcpu) { @@ -192,11 +199,9 @@ int kvmppc_sanity_check(struct kvm_vcpu *vcpu) if ((vcpu->arch.cpu_type != KVM_CPU_3S_64) && vcpu->arch.papr_enabled) goto out; -#ifdef CONFIG_KVM_BOOK3S_64_HV /* HV KVM can only do PAPR mode for now */ - if (!vcpu->arch.papr_enabled) + if (!vcpu->arch.papr_enabled && is_kvmppc_hv_enabled(vcpu->kvm)) goto out; -#endif #ifdef CONFIG_KVM_BOOKE_HV if (!cpu_has_feature(CPU_FTR_EMB_HV)) @@ -209,6 +214,7 @@ out: vcpu->arch.sane = r; return r ? 0 : -EINVAL; } +EXPORT_SYMBOL_GPL(kvmppc_sanity_check); int kvmppc_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu) { @@ -243,6 +249,7 @@ int kvmppc_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu) return r; } +EXPORT_SYMBOL_GPL(kvmppc_emulate_mmio); int kvm_arch_hardware_enable(void *garbage) { @@ -269,10 +276,35 @@ void kvm_arch_check_processor_compat(void *rtn) int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) { - if (type) - return -EINVAL; - + struct kvmppc_ops *kvm_ops = NULL; + /* + * if we have both HV and PR enabled, default is HV + */ + if (type == 0) { + if (kvmppc_hv_ops) + kvm_ops = kvmppc_hv_ops; + else + kvm_ops = kvmppc_pr_ops; + if (!kvm_ops) + goto err_out; + } else if (type == KVM_VM_PPC_HV) { + if (!kvmppc_hv_ops) + goto err_out; + kvm_ops = kvmppc_hv_ops; + } else if (type == KVM_VM_PPC_PR) { + if (!kvmppc_pr_ops) + goto err_out; + kvm_ops = kvmppc_pr_ops; + } else + goto err_out; + + if (kvm_ops->owner && !try_module_get(kvm_ops->owner)) + return -ENOENT; + + kvm->arch.kvm_ops = kvm_ops; return kvmppc_core_init_vm(kvm); +err_out: + return -EINVAL; } void kvm_arch_destroy_vm(struct kvm *kvm) @@ -292,6 +324,9 @@ void kvm_arch_destroy_vm(struct kvm *kvm) kvmppc_core_destroy_vm(kvm); mutex_unlock(&kvm->lock); + + /* drop the module reference */ + module_put(kvm->arch.kvm_ops->owner); } void kvm_arch_sync_events(struct kvm *kvm) @@ -301,6 +336,10 @@ void kvm_arch_sync_events(struct kvm *kvm) int kvm_dev_ioctl_check_extension(long ext) { int r; + /* FIXME!! + * Should some of this be vm ioctl ? is it possible now ? + */ + int hv_enabled = kvmppc_hv_ops ? 1 : 0; switch (ext) { #ifdef CONFIG_BOOKE @@ -320,22 +359,26 @@ int kvm_dev_ioctl_check_extension(long ext) case KVM_CAP_DEVICE_CTRL: r = 1; break; -#ifndef CONFIG_KVM_BOOK3S_64_HV case KVM_CAP_PPC_PAIRED_SINGLES: case KVM_CAP_PPC_OSI: case KVM_CAP_PPC_GET_PVINFO: #if defined(CONFIG_KVM_E500V2) || defined(CONFIG_KVM_E500MC) case KVM_CAP_SW_TLB: #endif -#ifdef CONFIG_KVM_MPIC - case KVM_CAP_IRQ_MPIC: -#endif - r = 1; + /* We support this only for PR */ + r = !hv_enabled; break; +#ifdef CONFIG_KVM_MMIO case KVM_CAP_COALESCED_MMIO: r = KVM_COALESCED_MMIO_PAGE_OFFSET; break; #endif +#ifdef CONFIG_KVM_MPIC + case KVM_CAP_IRQ_MPIC: + r = 1; + break; +#endif + #ifdef CONFIG_PPC_BOOK3S_64 case KVM_CAP_SPAPR_TCE: case KVM_CAP_PPC_ALLOC_HTAB: @@ -346,32 +389,37 @@ int kvm_dev_ioctl_check_extension(long ext) r = 1; break; #endif /* CONFIG_PPC_BOOK3S_64 */ -#ifdef CONFIG_KVM_BOOK3S_64_HV +#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE case KVM_CAP_PPC_SMT: - r = threads_per_core; + if (hv_enabled) + r = threads_per_core; + else + r = 0; break; case KVM_CAP_PPC_RMA: - r = 1; + r = hv_enabled; /* PPC970 requires an RMA */ - if (cpu_has_feature(CPU_FTR_ARCH_201)) + if (r && cpu_has_feature(CPU_FTR_ARCH_201)) r = 2; break; #endif case KVM_CAP_SYNC_MMU: -#ifdef CONFIG_KVM_BOOK3S_64_HV - r = cpu_has_feature(CPU_FTR_ARCH_206) ? 1 : 0; +#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE + if (hv_enabled) + r = cpu_has_feature(CPU_FTR_ARCH_206) ? 1 : 0; + else + r = 0; #elif defined(KVM_ARCH_WANT_MMU_NOTIFIER) r = 1; #else r = 0; - break; #endif -#ifdef CONFIG_KVM_BOOK3S_64_HV + break; +#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE case KVM_CAP_PPC_HTAB_FD: - r = 1; + r = hv_enabled; break; #endif - break; case KVM_CAP_NR_VCPUS: /* * Recommending a number of CPUs is somewhat arbitrary; we @@ -379,11 +427,10 @@ int kvm_dev_ioctl_check_extension(long ext) * will have secondary threads "offline"), and for other KVM * implementations just count online CPUs. */ -#ifdef CONFIG_KVM_BOOK3S_64_HV - r = num_present_cpus(); -#else - r = num_online_cpus(); -#endif + if (hv_enabled) + r = num_present_cpus(); + else + r = num_online_cpus(); break; case KVM_CAP_MAX_VCPUS: r = KVM_MAX_VCPUS; @@ -407,15 +454,16 @@ long kvm_arch_dev_ioctl(struct file *filp, return -EINVAL; } -void kvm_arch_free_memslot(struct kvm_memory_slot *free, +void kvm_arch_free_memslot(struct kvm *kvm, struct kvm_memory_slot *free, struct kvm_memory_slot *dont) { - kvmppc_core_free_memslot(free, dont); + kvmppc_core_free_memslot(kvm, free, dont); } -int kvm_arch_create_memslot(struct kvm_memory_slot *slot, unsigned long npages) +int kvm_arch_create_memslot(struct kvm *kvm, struct kvm_memory_slot *slot, + unsigned long npages) { - return kvmppc_core_create_memslot(slot, npages); + return kvmppc_core_create_memslot(kvm, slot, npages); } void kvm_arch_memslots_updated(struct kvm *kvm) @@ -659,6 +707,7 @@ int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu, return EMULATE_DO_MMIO; } +EXPORT_SYMBOL_GPL(kvmppc_handle_load); /* Same as above, but sign extends */ int kvmppc_handle_loads(struct kvm_run *run, struct kvm_vcpu *vcpu, @@ -720,6 +769,7 @@ int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu, return EMULATE_DO_MMIO; } +EXPORT_SYMBOL_GPL(kvmppc_handle_store); int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) { @@ -1024,52 +1074,12 @@ long kvm_arch_vm_ioctl(struct file *filp, r = kvm_vm_ioctl_create_spapr_tce(kvm, &create_tce); goto out; } -#endif /* CONFIG_PPC_BOOK3S_64 */ - -#ifdef CONFIG_KVM_BOOK3S_64_HV - case KVM_ALLOCATE_RMA: { - struct kvm_allocate_rma rma; - struct kvm *kvm = filp->private_data; - - r = kvm_vm_ioctl_allocate_rma(kvm, &rma); - if (r >= 0 && copy_to_user(argp, &rma, sizeof(rma))) - r = -EFAULT; - break; - } - - case KVM_PPC_ALLOCATE_HTAB: { - u32 htab_order; - - r = -EFAULT; - if (get_user(htab_order, (u32 __user *)argp)) - break; - r = kvmppc_alloc_reset_hpt(kvm, &htab_order); - if (r) - break; - r = -EFAULT; - if (put_user(htab_order, (u32 __user *)argp)) - break; - r = 0; - break; - } - - case KVM_PPC_GET_HTAB_FD: { - struct kvm_get_htab_fd ghf; - - r = -EFAULT; - if (copy_from_user(&ghf, argp, sizeof(ghf))) - break; - r = kvm_vm_ioctl_get_htab_fd(kvm, &ghf); - break; - } -#endif /* CONFIG_KVM_BOOK3S_64_HV */ - -#ifdef CONFIG_PPC_BOOK3S_64 case KVM_PPC_GET_SMMU_INFO: { struct kvm_ppc_smmu_info info; + struct kvm *kvm = filp->private_data; memset(&info, 0, sizeof(info)); - r = kvm_vm_ioctl_get_smmu_info(kvm, &info); + r = kvm->arch.kvm_ops->get_smmu_info(kvm, &info); if (r >= 0 && copy_to_user(argp, &info, sizeof(info))) r = -EFAULT; break; @@ -1080,11 +1090,15 @@ long kvm_arch_vm_ioctl(struct file *filp, r = kvm_vm_ioctl_rtas_define_token(kvm, argp); break; } -#endif /* CONFIG_PPC_BOOK3S_64 */ + default: { + struct kvm *kvm = filp->private_data; + r = kvm->arch.kvm_ops->arch_vm_ioctl(filp, ioctl, arg); + } +#else /* CONFIG_PPC_BOOK3S_64 */ default: r = -ENOTTY; +#endif } - out: return r; } @@ -1106,22 +1120,26 @@ long kvmppc_alloc_lpid(void) return lpid; } +EXPORT_SYMBOL_GPL(kvmppc_alloc_lpid); void kvmppc_claim_lpid(long lpid) { set_bit(lpid, lpid_inuse); } +EXPORT_SYMBOL_GPL(kvmppc_claim_lpid); void kvmppc_free_lpid(long lpid) { clear_bit(lpid, lpid_inuse); } +EXPORT_SYMBOL_GPL(kvmppc_free_lpid); void kvmppc_init_lpid(unsigned long nr_lpids_param) { nr_lpids = min_t(unsigned long, KVMPPC_NR_LPIDS, nr_lpids_param); memset(lpid_inuse, 0, sizeof(lpid_inuse)); } +EXPORT_SYMBOL_GPL(kvmppc_init_lpid); int kvm_arch_init(void *opaque) { @@ -1130,4 +1148,5 @@ int kvm_arch_init(void *opaque) void kvm_arch_exit(void) { + } diff --git a/arch/powerpc/kvm/trace.h b/arch/powerpc/kvm/trace.h index e326489a5420..2e0e67ef3544 100644 --- a/arch/powerpc/kvm/trace.h +++ b/arch/powerpc/kvm/trace.h @@ -31,126 +31,6 @@ TRACE_EVENT(kvm_ppc_instr, __entry->inst, __entry->pc, __entry->emulate) ); -#ifdef CONFIG_PPC_BOOK3S -#define kvm_trace_symbol_exit \ - {0x100, "SYSTEM_RESET"}, \ - {0x200, "MACHINE_CHECK"}, \ - {0x300, "DATA_STORAGE"}, \ - {0x380, "DATA_SEGMENT"}, \ - {0x400, "INST_STORAGE"}, \ - {0x480, "INST_SEGMENT"}, \ - {0x500, "EXTERNAL"}, \ - {0x501, "EXTERNAL_LEVEL"}, \ - {0x502, "EXTERNAL_HV"}, \ - {0x600, "ALIGNMENT"}, \ - {0x700, "PROGRAM"}, \ - {0x800, "FP_UNAVAIL"}, \ - {0x900, "DECREMENTER"}, \ - {0x980, "HV_DECREMENTER"}, \ - {0xc00, "SYSCALL"}, \ - {0xd00, "TRACE"}, \ - {0xe00, "H_DATA_STORAGE"}, \ - {0xe20, "H_INST_STORAGE"}, \ - {0xe40, "H_EMUL_ASSIST"}, \ - {0xf00, "PERFMON"}, \ - {0xf20, "ALTIVEC"}, \ - {0xf40, "VSX"} -#else -#define kvm_trace_symbol_exit \ - {0, "CRITICAL"}, \ - {1, "MACHINE_CHECK"}, \ - {2, "DATA_STORAGE"}, \ - {3, "INST_STORAGE"}, \ - {4, "EXTERNAL"}, \ - {5, "ALIGNMENT"}, \ - {6, "PROGRAM"}, \ - {7, "FP_UNAVAIL"}, \ - {8, "SYSCALL"}, \ - {9, "AP_UNAVAIL"}, \ - {10, "DECREMENTER"}, \ - {11, "FIT"}, \ - {12, "WATCHDOG"}, \ - {13, "DTLB_MISS"}, \ - {14, "ITLB_MISS"}, \ - {15, "DEBUG"}, \ - {32, "SPE_UNAVAIL"}, \ - {33, "SPE_FP_DATA"}, \ - {34, "SPE_FP_ROUND"}, \ - {35, "PERFORMANCE_MONITOR"}, \ - {36, "DOORBELL"}, \ - {37, "DOORBELL_CRITICAL"}, \ - {38, "GUEST_DBELL"}, \ - {39, "GUEST_DBELL_CRIT"}, \ - {40, "HV_SYSCALL"}, \ - {41, "HV_PRIV"} -#endif - -TRACE_EVENT(kvm_exit, - TP_PROTO(unsigned int exit_nr, struct kvm_vcpu *vcpu), - TP_ARGS(exit_nr, vcpu), - - TP_STRUCT__entry( - __field( unsigned int, exit_nr ) - __field( unsigned long, pc ) - __field( unsigned long, msr ) - __field( unsigned long, dar ) -#ifdef CONFIG_KVM_BOOK3S_PR - __field( unsigned long, srr1 ) -#endif - __field( unsigned long, last_inst ) - ), - - TP_fast_assign( -#ifdef CONFIG_KVM_BOOK3S_PR - struct kvmppc_book3s_shadow_vcpu *svcpu; -#endif - __entry->exit_nr = exit_nr; - __entry->pc = kvmppc_get_pc(vcpu); - __entry->dar = kvmppc_get_fault_dar(vcpu); - __entry->msr = vcpu->arch.shared->msr; -#ifdef CONFIG_KVM_BOOK3S_PR - svcpu = svcpu_get(vcpu); - __entry->srr1 = svcpu->shadow_srr1; - svcpu_put(svcpu); -#endif - __entry->last_inst = vcpu->arch.last_inst; - ), - - TP_printk("exit=%s" - " | pc=0x%lx" - " | msr=0x%lx" - " | dar=0x%lx" -#ifdef CONFIG_KVM_BOOK3S_PR - " | srr1=0x%lx" -#endif - " | last_inst=0x%lx" - , - __print_symbolic(__entry->exit_nr, kvm_trace_symbol_exit), - __entry->pc, - __entry->msr, - __entry->dar, -#ifdef CONFIG_KVM_BOOK3S_PR - __entry->srr1, -#endif - __entry->last_inst - ) -); - -TRACE_EVENT(kvm_unmap_hva, - TP_PROTO(unsigned long hva), - TP_ARGS(hva), - - TP_STRUCT__entry( - __field( unsigned long, hva ) - ), - - TP_fast_assign( - __entry->hva = hva; - ), - - TP_printk("unmap hva 0x%lx\n", __entry->hva) -); - TRACE_EVENT(kvm_stlb_inval, TP_PROTO(unsigned int stlb_index), TP_ARGS(stlb_index), @@ -236,315 +116,6 @@ TRACE_EVENT(kvm_check_requests, __entry->cpu_nr, __entry->requests) ); - -/************************************************************************* - * Book3S trace points * - *************************************************************************/ - -#ifdef CONFIG_KVM_BOOK3S_PR - -TRACE_EVENT(kvm_book3s_reenter, - TP_PROTO(int r, struct kvm_vcpu *vcpu), - TP_ARGS(r, vcpu), - - TP_STRUCT__entry( - __field( unsigned int, r ) - __field( unsigned long, pc ) - ), - - TP_fast_assign( - __entry->r = r; - __entry->pc = kvmppc_get_pc(vcpu); - ), - - TP_printk("reentry r=%d | pc=0x%lx", __entry->r, __entry->pc) -); - -#ifdef CONFIG_PPC_BOOK3S_64 - -TRACE_EVENT(kvm_book3s_64_mmu_map, - TP_PROTO(int rflags, ulong hpteg, ulong va, pfn_t hpaddr, - struct kvmppc_pte *orig_pte), - TP_ARGS(rflags, hpteg, va, hpaddr, orig_pte), - - TP_STRUCT__entry( - __field( unsigned char, flag_w ) - __field( unsigned char, flag_x ) - __field( unsigned long, eaddr ) - __field( unsigned long, hpteg ) - __field( unsigned long, va ) - __field( unsigned long long, vpage ) - __field( unsigned long, hpaddr ) - ), - - TP_fast_assign( - __entry->flag_w = ((rflags & HPTE_R_PP) == 3) ? '-' : 'w'; - __entry->flag_x = (rflags & HPTE_R_N) ? '-' : 'x'; - __entry->eaddr = orig_pte->eaddr; - __entry->hpteg = hpteg; - __entry->va = va; - __entry->vpage = orig_pte->vpage; - __entry->hpaddr = hpaddr; - ), - - TP_printk("KVM: %c%c Map 0x%lx: [%lx] 0x%lx (0x%llx) -> %lx", - __entry->flag_w, __entry->flag_x, __entry->eaddr, - __entry->hpteg, __entry->va, __entry->vpage, __entry->hpaddr) -); - -#endif /* CONFIG_PPC_BOOK3S_64 */ - -TRACE_EVENT(kvm_book3s_mmu_map, - TP_PROTO(struct hpte_cache *pte), - TP_ARGS(pte), - - TP_STRUCT__entry( - __field( u64, host_vpn ) - __field( u64, pfn ) - __field( ulong, eaddr ) - __field( u64, vpage ) - __field( ulong, raddr ) - __field( int, flags ) - ), - - TP_fast_assign( - __entry->host_vpn = pte->host_vpn; - __entry->pfn = pte->pfn; - __entry->eaddr = pte->pte.eaddr; - __entry->vpage = pte->pte.vpage; - __entry->raddr = pte->pte.raddr; - __entry->flags = (pte->pte.may_read ? 0x4 : 0) | - (pte->pte.may_write ? 0x2 : 0) | - (pte->pte.may_execute ? 0x1 : 0); - ), - - TP_printk("Map: hvpn=%llx pfn=%llx ea=%lx vp=%llx ra=%lx [%x]", - __entry->host_vpn, __entry->pfn, __entry->eaddr, - __entry->vpage, __entry->raddr, __entry->flags) -); - -TRACE_EVENT(kvm_book3s_mmu_invalidate, - TP_PROTO(struct hpte_cache *pte), - TP_ARGS(pte), - - TP_STRUCT__entry( - __field( u64, host_vpn ) - __field( u64, pfn ) - __field( ulong, eaddr ) - __field( u64, vpage ) - __field( ulong, raddr ) - __field( int, flags ) - ), - - TP_fast_assign( - __entry->host_vpn = pte->host_vpn; - __entry->pfn = pte->pfn; - __entry->eaddr = pte->pte.eaddr; - __entry->vpage = pte->pte.vpage; - __entry->raddr = pte->pte.raddr; - __entry->flags = (pte->pte.may_read ? 0x4 : 0) | - (pte->pte.may_write ? 0x2 : 0) | - (pte->pte.may_execute ? 0x1 : 0); - ), - - TP_printk("Flush: hva=%llx pfn=%llx ea=%lx vp=%llx ra=%lx [%x]", - __entry->host_vpn, __entry->pfn, __entry->eaddr, - __entry->vpage, __entry->raddr, __entry->flags) -); - -TRACE_EVENT(kvm_book3s_mmu_flush, - TP_PROTO(const char *type, struct kvm_vcpu *vcpu, unsigned long long p1, - unsigned long long p2), - TP_ARGS(type, vcpu, p1, p2), - - TP_STRUCT__entry( - __field( int, count ) - __field( unsigned long long, p1 ) - __field( unsigned long long, p2 ) - __field( const char *, type ) - ), - - TP_fast_assign( - __entry->count = to_book3s(vcpu)->hpte_cache_count; - __entry->p1 = p1; - __entry->p2 = p2; - __entry->type = type; - ), - - TP_printk("Flush %d %sPTEs: %llx - %llx", - __entry->count, __entry->type, __entry->p1, __entry->p2) -); - -TRACE_EVENT(kvm_book3s_slb_found, - TP_PROTO(unsigned long long gvsid, unsigned long long hvsid), - TP_ARGS(gvsid, hvsid), - - TP_STRUCT__entry( - __field( unsigned long long, gvsid ) - __field( unsigned long long, hvsid ) - ), - - TP_fast_assign( - __entry->gvsid = gvsid; - __entry->hvsid = hvsid; - ), - - TP_printk("%llx -> %llx", __entry->gvsid, __entry->hvsid) -); - -TRACE_EVENT(kvm_book3s_slb_fail, - TP_PROTO(u16 sid_map_mask, unsigned long long gvsid), - TP_ARGS(sid_map_mask, gvsid), - - TP_STRUCT__entry( - __field( unsigned short, sid_map_mask ) - __field( unsigned long long, gvsid ) - ), - - TP_fast_assign( - __entry->sid_map_mask = sid_map_mask; - __entry->gvsid = gvsid; - ), - - TP_printk("%x/%x: %llx", __entry->sid_map_mask, - SID_MAP_MASK - __entry->sid_map_mask, __entry->gvsid) -); - -TRACE_EVENT(kvm_book3s_slb_map, - TP_PROTO(u16 sid_map_mask, unsigned long long gvsid, - unsigned long long hvsid), - TP_ARGS(sid_map_mask, gvsid, hvsid), - - TP_STRUCT__entry( - __field( unsigned short, sid_map_mask ) - __field( unsigned long long, guest_vsid ) - __field( unsigned long long, host_vsid ) - ), - - TP_fast_assign( - __entry->sid_map_mask = sid_map_mask; - __entry->guest_vsid = gvsid; - __entry->host_vsid = hvsid; - ), - - TP_printk("%x: %llx -> %llx", __entry->sid_map_mask, - __entry->guest_vsid, __entry->host_vsid) -); - -TRACE_EVENT(kvm_book3s_slbmte, - TP_PROTO(u64 slb_vsid, u64 slb_esid), - TP_ARGS(slb_vsid, slb_esid), - - TP_STRUCT__entry( - __field( u64, slb_vsid ) - __field( u64, slb_esid ) - ), - - TP_fast_assign( - __entry->slb_vsid = slb_vsid; - __entry->slb_esid = slb_esid; - ), - - TP_printk("%llx, %llx", __entry->slb_vsid, __entry->slb_esid) -); - -#endif /* CONFIG_PPC_BOOK3S */ - - -/************************************************************************* - * Book3E trace points * - *************************************************************************/ - -#ifdef CONFIG_BOOKE - -TRACE_EVENT(kvm_booke206_stlb_write, - TP_PROTO(__u32 mas0, __u32 mas8, __u32 mas1, __u64 mas2, __u64 mas7_3), - TP_ARGS(mas0, mas8, mas1, mas2, mas7_3), - - TP_STRUCT__entry( - __field( __u32, mas0 ) - __field( __u32, mas8 ) - __field( __u32, mas1 ) - __field( __u64, mas2 ) - __field( __u64, mas7_3 ) - ), - - TP_fast_assign( - __entry->mas0 = mas0; - __entry->mas8 = mas8; - __entry->mas1 = mas1; - __entry->mas2 = mas2; - __entry->mas7_3 = mas7_3; - ), - - TP_printk("mas0=%x mas8=%x mas1=%x mas2=%llx mas7_3=%llx", - __entry->mas0, __entry->mas8, __entry->mas1, - __entry->mas2, __entry->mas7_3) -); - -TRACE_EVENT(kvm_booke206_gtlb_write, - TP_PROTO(__u32 mas0, __u32 mas1, __u64 mas2, __u64 mas7_3), - TP_ARGS(mas0, mas1, mas2, mas7_3), - - TP_STRUCT__entry( - __field( __u32, mas0 ) - __field( __u32, mas1 ) - __field( __u64, mas2 ) - __field( __u64, mas7_3 ) - ), - - TP_fast_assign( - __entry->mas0 = mas0; - __entry->mas1 = mas1; - __entry->mas2 = mas2; - __entry->mas7_3 = mas7_3; - ), - - TP_printk("mas0=%x mas1=%x mas2=%llx mas7_3=%llx", - __entry->mas0, __entry->mas1, - __entry->mas2, __entry->mas7_3) -); - -TRACE_EVENT(kvm_booke206_ref_release, - TP_PROTO(__u64 pfn, __u32 flags), - TP_ARGS(pfn, flags), - - TP_STRUCT__entry( - __field( __u64, pfn ) - __field( __u32, flags ) - ), - - TP_fast_assign( - __entry->pfn = pfn; - __entry->flags = flags; - ), - - TP_printk("pfn=%llx flags=%x", - __entry->pfn, __entry->flags) -); - -TRACE_EVENT(kvm_booke_queue_irqprio, - TP_PROTO(struct kvm_vcpu *vcpu, unsigned int priority), - TP_ARGS(vcpu, priority), - - TP_STRUCT__entry( - __field( __u32, cpu_nr ) - __field( __u32, priority ) - __field( unsigned long, pending ) - ), - - TP_fast_assign( - __entry->cpu_nr = vcpu->vcpu_id; - __entry->priority = priority; - __entry->pending = vcpu->arch.pending_exceptions; - ), - - TP_printk("vcpu=%x prio=%x pending=%lx", - __entry->cpu_nr, __entry->priority, __entry->pending) -); - -#endif - #endif /* _TRACE_KVM_H */ /* This part must be outside protection */ diff --git a/arch/powerpc/kvm/trace_booke.h b/arch/powerpc/kvm/trace_booke.h new file mode 100644 index 000000000000..f7537cf26ce7 --- /dev/null +++ b/arch/powerpc/kvm/trace_booke.h @@ -0,0 +1,177 @@ +#if !defined(_TRACE_KVM_BOOKE_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_KVM_BOOKE_H + +#include <linux/tracepoint.h> + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM kvm_booke +#define TRACE_INCLUDE_PATH . +#define TRACE_INCLUDE_FILE trace_booke + +#define kvm_trace_symbol_exit \ + {0, "CRITICAL"}, \ + {1, "MACHINE_CHECK"}, \ + {2, "DATA_STORAGE"}, \ + {3, "INST_STORAGE"}, \ + {4, "EXTERNAL"}, \ + {5, "ALIGNMENT"}, \ + {6, "PROGRAM"}, \ + {7, "FP_UNAVAIL"}, \ + {8, "SYSCALL"}, \ + {9, "AP_UNAVAIL"}, \ + {10, "DECREMENTER"}, \ + {11, "FIT"}, \ + {12, "WATCHDOG"}, \ + {13, "DTLB_MISS"}, \ + {14, "ITLB_MISS"}, \ + {15, "DEBUG"}, \ + {32, "SPE_UNAVAIL"}, \ + {33, "SPE_FP_DATA"}, \ + {34, "SPE_FP_ROUND"}, \ + {35, "PERFORMANCE_MONITOR"}, \ + {36, "DOORBELL"}, \ + {37, "DOORBELL_CRITICAL"}, \ + {38, "GUEST_DBELL"}, \ + {39, "GUEST_DBELL_CRIT"}, \ + {40, "HV_SYSCALL"}, \ + {41, "HV_PRIV"} + +TRACE_EVENT(kvm_exit, + TP_PROTO(unsigned int exit_nr, struct kvm_vcpu *vcpu), + TP_ARGS(exit_nr, vcpu), + + TP_STRUCT__entry( + __field( unsigned int, exit_nr ) + __field( unsigned long, pc ) + __field( unsigned long, msr ) + __field( unsigned long, dar ) + __field( unsigned long, last_inst ) + ), + + TP_fast_assign( + __entry->exit_nr = exit_nr; + __entry->pc = kvmppc_get_pc(vcpu); + __entry->dar = kvmppc_get_fault_dar(vcpu); + __entry->msr = vcpu->arch.shared->msr; + __entry->last_inst = vcpu->arch.last_inst; + ), + + TP_printk("exit=%s" + " | pc=0x%lx" + " | msr=0x%lx" + " | dar=0x%lx" + " | last_inst=0x%lx" + , + __print_symbolic(__entry->exit_nr, kvm_trace_symbol_exit), + __entry->pc, + __entry->msr, + __entry->dar, + __entry->last_inst + ) +); + +TRACE_EVENT(kvm_unmap_hva, + TP_PROTO(unsigned long hva), + TP_ARGS(hva), + + TP_STRUCT__entry( + __field( unsigned long, hva ) + ), + + TP_fast_assign( + __entry->hva = hva; + ), + + TP_printk("unmap hva 0x%lx\n", __entry->hva) +); + +TRACE_EVENT(kvm_booke206_stlb_write, + TP_PROTO(__u32 mas0, __u32 mas8, __u32 mas1, __u64 mas2, __u64 mas7_3), + TP_ARGS(mas0, mas8, mas1, mas2, mas7_3), + + TP_STRUCT__entry( + __field( __u32, mas0 ) + __field( __u32, mas8 ) + __field( __u32, mas1 ) + __field( __u64, mas2 ) + __field( __u64, mas7_3 ) + ), + + TP_fast_assign( + __entry->mas0 = mas0; + __entry->mas8 = mas8; + __entry->mas1 = mas1; + __entry->mas2 = mas2; + __entry->mas7_3 = mas7_3; + ), + + TP_printk("mas0=%x mas8=%x mas1=%x mas2=%llx mas7_3=%llx", + __entry->mas0, __entry->mas8, __entry->mas1, + __entry->mas2, __entry->mas7_3) +); + +TRACE_EVENT(kvm_booke206_gtlb_write, + TP_PROTO(__u32 mas0, __u32 mas1, __u64 mas2, __u64 mas7_3), + TP_ARGS(mas0, mas1, mas2, mas7_3), + + TP_STRUCT__entry( + __field( __u32, mas0 ) + __field( __u32, mas1 ) + __field( __u64, mas2 ) + __field( __u64, mas7_3 ) + ), + + TP_fast_assign( + __entry->mas0 = mas0; + __entry->mas1 = mas1; + __entry->mas2 = mas2; + __entry->mas7_3 = mas7_3; + ), + + TP_printk("mas0=%x mas1=%x mas2=%llx mas7_3=%llx", + __entry->mas0, __entry->mas1, + __entry->mas2, __entry->mas7_3) +); + +TRACE_EVENT(kvm_booke206_ref_release, + TP_PROTO(__u64 pfn, __u32 flags), + TP_ARGS(pfn, flags), + + TP_STRUCT__entry( + __field( __u64, pfn ) + __field( __u32, flags ) + ), + + TP_fast_assign( + __entry->pfn = pfn; + __entry->flags = flags; + ), + + TP_printk("pfn=%llx flags=%x", + __entry->pfn, __entry->flags) +); + +TRACE_EVENT(kvm_booke_queue_irqprio, + TP_PROTO(struct kvm_vcpu *vcpu, unsigned int priority), + TP_ARGS(vcpu, priority), + + TP_STRUCT__entry( + __field( __u32, cpu_nr ) + __field( __u32, priority ) + __field( unsigned long, pending ) + ), + + TP_fast_assign( + __entry->cpu_nr = vcpu->vcpu_id; + __entry->priority = priority; + __entry->pending = vcpu->arch.pending_exceptions; + ), + + TP_printk("vcpu=%x prio=%x pending=%lx", + __entry->cpu_nr, __entry->priority, __entry->pending) +); + +#endif + +/* This part must be outside protection */ +#include <trace/define_trace.h> diff --git a/arch/powerpc/kvm/trace_pr.h b/arch/powerpc/kvm/trace_pr.h new file mode 100644 index 000000000000..8b22e4748344 --- /dev/null +++ b/arch/powerpc/kvm/trace_pr.h @@ -0,0 +1,297 @@ + +#if !defined(_TRACE_KVM_PR_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_KVM_PR_H + +#include <linux/tracepoint.h> + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM kvm_pr +#define TRACE_INCLUDE_PATH . +#define TRACE_INCLUDE_FILE trace_pr + +#define kvm_trace_symbol_exit \ + {0x100, "SYSTEM_RESET"}, \ + {0x200, "MACHINE_CHECK"}, \ + {0x300, "DATA_STORAGE"}, \ + {0x380, "DATA_SEGMENT"}, \ + {0x400, "INST_STORAGE"}, \ + {0x480, "INST_SEGMENT"}, \ + {0x500, "EXTERNAL"}, \ + {0x501, "EXTERNAL_LEVEL"}, \ + {0x502, "EXTERNAL_HV"}, \ + {0x600, "ALIGNMENT"}, \ + {0x700, "PROGRAM"}, \ + {0x800, "FP_UNAVAIL"}, \ + {0x900, "DECREMENTER"}, \ + {0x980, "HV_DECREMENTER"}, \ + {0xc00, "SYSCALL"}, \ + {0xd00, "TRACE"}, \ + {0xe00, "H_DATA_STORAGE"}, \ + {0xe20, "H_INST_STORAGE"}, \ + {0xe40, "H_EMUL_ASSIST"}, \ + {0xf00, "PERFMON"}, \ + {0xf20, "ALTIVEC"}, \ + {0xf40, "VSX"} + +TRACE_EVENT(kvm_book3s_reenter, + TP_PROTO(int r, struct kvm_vcpu *vcpu), + TP_ARGS(r, vcpu), + + TP_STRUCT__entry( + __field( unsigned int, r ) + __field( unsigned long, pc ) + ), + + TP_fast_assign( + __entry->r = r; + __entry->pc = kvmppc_get_pc(vcpu); + ), + + TP_printk("reentry r=%d | pc=0x%lx", __entry->r, __entry->pc) +); + +#ifdef CONFIG_PPC_BOOK3S_64 + +TRACE_EVENT(kvm_book3s_64_mmu_map, + TP_PROTO(int rflags, ulong hpteg, ulong va, pfn_t hpaddr, + struct kvmppc_pte *orig_pte), + TP_ARGS(rflags, hpteg, va, hpaddr, orig_pte), + + TP_STRUCT__entry( + __field( unsigned char, flag_w ) + __field( unsigned char, flag_x ) + __field( unsigned long, eaddr ) + __field( unsigned long, hpteg ) + __field( unsigned long, va ) + __field( unsigned long long, vpage ) + __field( unsigned long, hpaddr ) + ), + + TP_fast_assign( + __entry->flag_w = ((rflags & HPTE_R_PP) == 3) ? '-' : 'w'; + __entry->flag_x = (rflags & HPTE_R_N) ? '-' : 'x'; + __entry->eaddr = orig_pte->eaddr; + __entry->hpteg = hpteg; + __entry->va = va; + __entry->vpage = orig_pte->vpage; + __entry->hpaddr = hpaddr; + ), + + TP_printk("KVM: %c%c Map 0x%lx: [%lx] 0x%lx (0x%llx) -> %lx", + __entry->flag_w, __entry->flag_x, __entry->eaddr, + __entry->hpteg, __entry->va, __entry->vpage, __entry->hpaddr) +); + +#endif /* CONFIG_PPC_BOOK3S_64 */ + +TRACE_EVENT(kvm_book3s_mmu_map, + TP_PROTO(struct hpte_cache *pte), + TP_ARGS(pte), + + TP_STRUCT__entry( + __field( u64, host_vpn ) + __field( u64, pfn ) + __field( ulong, eaddr ) + __field( u64, vpage ) + __field( ulong, raddr ) + __field( int, flags ) + ), + + TP_fast_assign( + __entry->host_vpn = pte->host_vpn; + __entry->pfn = pte->pfn; + __entry->eaddr = pte->pte.eaddr; + __entry->vpage = pte->pte.vpage; + __entry->raddr = pte->pte.raddr; + __entry->flags = (pte->pte.may_read ? 0x4 : 0) | + (pte->pte.may_write ? 0x2 : 0) | + (pte->pte.may_execute ? 0x1 : 0); + ), + + TP_printk("Map: hvpn=%llx pfn=%llx ea=%lx vp=%llx ra=%lx [%x]", + __entry->host_vpn, __entry->pfn, __entry->eaddr, + __entry->vpage, __entry->raddr, __entry->flags) +); + +TRACE_EVENT(kvm_book3s_mmu_invalidate, + TP_PROTO(struct hpte_cache *pte), + TP_ARGS(pte), + + TP_STRUCT__entry( + __field( u64, host_vpn ) + __field( u64, pfn ) + __field( ulong, eaddr ) + __field( u64, vpage ) + __field( ulong, raddr ) + __field( int, flags ) + ), + + TP_fast_assign( + __entry->host_vpn = pte->host_vpn; + __entry->pfn = pte->pfn; + __entry->eaddr = pte->pte.eaddr; + __entry->vpage = pte->pte.vpage; + __entry->raddr = pte->pte.raddr; + __entry->flags = (pte->pte.may_read ? 0x4 : 0) | + (pte->pte.may_write ? 0x2 : 0) | + (pte->pte.may_execute ? 0x1 : 0); + ), + + TP_printk("Flush: hva=%llx pfn=%llx ea=%lx vp=%llx ra=%lx [%x]", + __entry->host_vpn, __entry->pfn, __entry->eaddr, + __entry->vpage, __entry->raddr, __entry->flags) +); + +TRACE_EVENT(kvm_book3s_mmu_flush, + TP_PROTO(const char *type, struct kvm_vcpu *vcpu, unsigned long long p1, + unsigned long long p2), + TP_ARGS(type, vcpu, p1, p2), + + TP_STRUCT__entry( + __field( int, count ) + __field( unsigned long long, p1 ) + __field( unsigned long long, p2 ) + __field( const char *, type ) + ), + + TP_fast_assign( + __entry->count = to_book3s(vcpu)->hpte_cache_count; + __entry->p1 = p1; + __entry->p2 = p2; + __entry->type = type; + ), + + TP_printk("Flush %d %sPTEs: %llx - %llx", + __entry->count, __entry->type, __entry->p1, __entry->p2) +); + +TRACE_EVENT(kvm_book3s_slb_found, + TP_PROTO(unsigned long long gvsid, unsigned long long hvsid), + TP_ARGS(gvsid, hvsid), + + TP_STRUCT__entry( + __field( unsigned long long, gvsid ) + __field( unsigned long long, hvsid ) + ), + + TP_fast_assign( + __entry->gvsid = gvsid; + __entry->hvsid = hvsid; + ), + + TP_printk("%llx -> %llx", __entry->gvsid, __entry->hvsid) +); + +TRACE_EVENT(kvm_book3s_slb_fail, + TP_PROTO(u16 sid_map_mask, unsigned long long gvsid), + TP_ARGS(sid_map_mask, gvsid), + + TP_STRUCT__entry( + __field( unsigned short, sid_map_mask ) + __field( unsigned long long, gvsid ) + ), + + TP_fast_assign( + __entry->sid_map_mask = sid_map_mask; + __entry->gvsid = gvsid; + ), + + TP_printk("%x/%x: %llx", __entry->sid_map_mask, + SID_MAP_MASK - __entry->sid_map_mask, __entry->gvsid) +); + +TRACE_EVENT(kvm_book3s_slb_map, + TP_PROTO(u16 sid_map_mask, unsigned long long gvsid, + unsigned long long hvsid), + TP_ARGS(sid_map_mask, gvsid, hvsid), + + TP_STRUCT__entry( + __field( unsigned short, sid_map_mask ) + __field( unsigned long long, guest_vsid ) + __field( unsigned long long, host_vsid ) + ), + + TP_fast_assign( + __entry->sid_map_mask = sid_map_mask; + __entry->guest_vsid = gvsid; + __entry->host_vsid = hvsid; + ), + + TP_printk("%x: %llx -> %llx", __entry->sid_map_mask, + __entry->guest_vsid, __entry->host_vsid) +); + +TRACE_EVENT(kvm_book3s_slbmte, + TP_PROTO(u64 slb_vsid, u64 slb_esid), + TP_ARGS(slb_vsid, slb_esid), + + TP_STRUCT__entry( + __field( u64, slb_vsid ) + __field( u64, slb_esid ) + ), + + TP_fast_assign( + __entry->slb_vsid = slb_vsid; + __entry->slb_esid = slb_esid; + ), + + TP_printk("%llx, %llx", __entry->slb_vsid, __entry->slb_esid) +); + +TRACE_EVENT(kvm_exit, + TP_PROTO(unsigned int exit_nr, struct kvm_vcpu *vcpu), + TP_ARGS(exit_nr, vcpu), + + TP_STRUCT__entry( + __field( unsigned int, exit_nr ) + __field( unsigned long, pc ) + __field( unsigned long, msr ) + __field( unsigned long, dar ) + __field( unsigned long, srr1 ) + __field( unsigned long, last_inst ) + ), + + TP_fast_assign( + __entry->exit_nr = exit_nr; + __entry->pc = kvmppc_get_pc(vcpu); + __entry->dar = kvmppc_get_fault_dar(vcpu); + __entry->msr = vcpu->arch.shared->msr; + __entry->srr1 = vcpu->arch.shadow_srr1; + __entry->last_inst = vcpu->arch.last_inst; + ), + + TP_printk("exit=%s" + " | pc=0x%lx" + " | msr=0x%lx" + " | dar=0x%lx" + " | srr1=0x%lx" + " | last_inst=0x%lx" + , + __print_symbolic(__entry->exit_nr, kvm_trace_symbol_exit), + __entry->pc, + __entry->msr, + __entry->dar, + __entry->srr1, + __entry->last_inst + ) +); + +TRACE_EVENT(kvm_unmap_hva, + TP_PROTO(unsigned long hva), + TP_ARGS(hva), + + TP_STRUCT__entry( + __field( unsigned long, hva ) + ), + + TP_fast_assign( + __entry->hva = hva; + ), + + TP_printk("unmap hva 0x%lx\n", __entry->hva) +); + +#endif /* _TRACE_KVM_H */ + +/* This part must be outside protection */ +#include <trace/define_trace.h> diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index 450433276699..95a20e17dbff 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile @@ -10,15 +10,23 @@ CFLAGS_REMOVE_code-patching.o = -pg CFLAGS_REMOVE_feature-fixups.o = -pg obj-y := string.o alloc.o \ - checksum_$(CONFIG_WORD_SIZE).o crtsavres.o + crtsavres.o obj-$(CONFIG_PPC32) += div64.o copy_32.o obj-$(CONFIG_HAS_IOMEM) += devres.o obj-$(CONFIG_PPC64) += copypage_64.o copyuser_64.o \ - memcpy_64.o usercopy_64.o mem_64.o string.o \ - checksum_wrappers_64.o hweight_64.o \ - copyuser_power7.o string_64.o copypage_power7.o \ - memcpy_power7.o + usercopy_64.o mem_64.o string.o \ + hweight_64.o \ + copyuser_power7.o string_64.o copypage_power7.o +ifeq ($(CONFIG_GENERIC_CSUM),) +obj-y += checksum_$(CONFIG_WORD_SIZE).o +obj-$(CONFIG_PPC64) += checksum_wrappers_64.o +endif + +ifeq ($(CONFIG_CPU_LITTLE_ENDIAN),) +obj-$(CONFIG_PPC64) += memcpy_power7.o memcpy_64.o +endif + obj-$(CONFIG_PPC_EMULATE_SSTEP) += sstep.o ldstfp.o ifeq ($(CONFIG_PPC64),y) @@ -31,3 +39,6 @@ obj-$(CONFIG_PPC_LIB_RHEAP) += rheap.o obj-y += code-patching.o obj-y += feature-fixups.o obj-$(CONFIG_FTR_FIXUP_SELFTEST) += feature-fixups-test.o + +obj-$(CONFIG_ALTIVEC) += xor_vmx.o +CFLAGS_xor_vmx.o += -maltivec -mabi=altivec diff --git a/arch/powerpc/lib/copyuser_power7.S b/arch/powerpc/lib/copyuser_power7.S index d1f11795a7ad..e8e9c36dc784 100644 --- a/arch/powerpc/lib/copyuser_power7.S +++ b/arch/powerpc/lib/copyuser_power7.S @@ -19,6 +19,14 @@ */ #include <asm/ppc_asm.h> +#ifdef __BIG_ENDIAN__ +#define LVS(VRT,RA,RB) lvsl VRT,RA,RB +#define VPERM(VRT,VRA,VRB,VRC) vperm VRT,VRA,VRB,VRC +#else +#define LVS(VRT,RA,RB) lvsr VRT,RA,RB +#define VPERM(VRT,VRA,VRB,VRC) vperm VRT,VRB,VRA,VRC +#endif + .macro err1 100: .section __ex_table,"a" @@ -552,13 +560,13 @@ err3; stw r7,4(r3) li r10,32 li r11,48 - lvsl vr16,0,r4 /* Setup permute control vector */ + LVS(vr16,0,r4) /* Setup permute control vector */ err3; lvx vr0,0,r4 addi r4,r4,16 bf cr7*4+3,5f err3; lvx vr1,r0,r4 - vperm vr8,vr0,vr1,vr16 + VPERM(vr8,vr0,vr1,vr16) addi r4,r4,16 err3; stvx vr8,r0,r3 addi r3,r3,16 @@ -566,9 +574,9 @@ err3; stvx vr8,r0,r3 5: bf cr7*4+2,6f err3; lvx vr1,r0,r4 - vperm vr8,vr0,vr1,vr16 + VPERM(vr8,vr0,vr1,vr16) err3; lvx vr0,r4,r9 - vperm vr9,vr1,vr0,vr16 + VPERM(vr9,vr1,vr0,vr16) addi r4,r4,32 err3; stvx vr8,r0,r3 err3; stvx vr9,r3,r9 @@ -576,13 +584,13 @@ err3; stvx vr9,r3,r9 6: bf cr7*4+1,7f err3; lvx vr3,r0,r4 - vperm vr8,vr0,vr3,vr16 + VPERM(vr8,vr0,vr3,vr16) err3; lvx vr2,r4,r9 - vperm vr9,vr3,vr2,vr16 + VPERM(vr9,vr3,vr2,vr16) err3; lvx vr1,r4,r10 - vperm vr10,vr2,vr1,vr16 + VPERM(vr10,vr2,vr1,vr16) err3; lvx vr0,r4,r11 - vperm vr11,vr1,vr0,vr16 + VPERM(vr11,vr1,vr0,vr16) addi r4,r4,64 err3; stvx vr8,r0,r3 err3; stvx vr9,r3,r9 @@ -611,21 +619,21 @@ err3; stvx vr11,r3,r11 .align 5 8: err4; lvx vr7,r0,r4 - vperm vr8,vr0,vr7,vr16 + VPERM(vr8,vr0,vr7,vr16) err4; lvx vr6,r4,r9 - vperm vr9,vr7,vr6,vr16 + VPERM(vr9,vr7,vr6,vr16) err4; lvx vr5,r4,r10 - vperm vr10,vr6,vr5,vr16 + VPERM(vr10,vr6,vr5,vr16) err4; lvx vr4,r4,r11 - vperm vr11,vr5,vr4,vr16 + VPERM(vr11,vr5,vr4,vr16) err4; lvx vr3,r4,r12 - vperm vr12,vr4,vr3,vr16 + VPERM(vr12,vr4,vr3,vr16) err4; lvx vr2,r4,r14 - vperm vr13,vr3,vr2,vr16 + VPERM(vr13,vr3,vr2,vr16) err4; lvx vr1,r4,r15 - vperm vr14,vr2,vr1,vr16 + VPERM(vr14,vr2,vr1,vr16) err4; lvx vr0,r4,r16 - vperm vr15,vr1,vr0,vr16 + VPERM(vr15,vr1,vr0,vr16) addi r4,r4,128 err4; stvx vr8,r0,r3 err4; stvx vr9,r3,r9 @@ -649,13 +657,13 @@ err4; stvx vr15,r3,r16 bf cr7*4+1,9f err3; lvx vr3,r0,r4 - vperm vr8,vr0,vr3,vr16 + VPERM(vr8,vr0,vr3,vr16) err3; lvx vr2,r4,r9 - vperm vr9,vr3,vr2,vr16 + VPERM(vr9,vr3,vr2,vr16) err3; lvx vr1,r4,r10 - vperm vr10,vr2,vr1,vr16 + VPERM(vr10,vr2,vr1,vr16) err3; lvx vr0,r4,r11 - vperm vr11,vr1,vr0,vr16 + VPERM(vr11,vr1,vr0,vr16) addi r4,r4,64 err3; stvx vr8,r0,r3 err3; stvx vr9,r3,r9 @@ -665,9 +673,9 @@ err3; stvx vr11,r3,r11 9: bf cr7*4+2,10f err3; lvx vr1,r0,r4 - vperm vr8,vr0,vr1,vr16 + VPERM(vr8,vr0,vr1,vr16) err3; lvx vr0,r4,r9 - vperm vr9,vr1,vr0,vr16 + VPERM(vr9,vr1,vr0,vr16) addi r4,r4,32 err3; stvx vr8,r0,r3 err3; stvx vr9,r3,r9 @@ -675,7 +683,7 @@ err3; stvx vr9,r3,r9 10: bf cr7*4+3,11f err3; lvx vr1,r0,r4 - vperm vr8,vr0,vr1,vr16 + VPERM(vr8,vr0,vr1,vr16) addi r4,r4,16 err3; stvx vr8,r0,r3 addi r3,r3,16 diff --git a/arch/powerpc/lib/memcpy_power7.S b/arch/powerpc/lib/memcpy_power7.S index 0663630baf3b..e4177dbea6bd 100644 --- a/arch/powerpc/lib/memcpy_power7.S +++ b/arch/powerpc/lib/memcpy_power7.S @@ -20,6 +20,15 @@ #include <asm/ppc_asm.h> _GLOBAL(memcpy_power7) + +#ifdef __BIG_ENDIAN__ +#define LVS(VRT,RA,RB) lvsl VRT,RA,RB +#define VPERM(VRT,VRA,VRB,VRC) vperm VRT,VRA,VRB,VRC +#else +#define LVS(VRT,RA,RB) lvsr VRT,RA,RB +#define VPERM(VRT,VRA,VRB,VRC) vperm VRT,VRB,VRA,VRC +#endif + #ifdef CONFIG_ALTIVEC cmpldi r5,16 cmpldi cr1,r5,4096 @@ -485,13 +494,13 @@ _GLOBAL(memcpy_power7) li r10,32 li r11,48 - lvsl vr16,0,r4 /* Setup permute control vector */ + LVS(vr16,0,r4) /* Setup permute control vector */ lvx vr0,0,r4 addi r4,r4,16 bf cr7*4+3,5f lvx vr1,r0,r4 - vperm vr8,vr0,vr1,vr16 + VPERM(vr8,vr0,vr1,vr16) addi r4,r4,16 stvx vr8,r0,r3 addi r3,r3,16 @@ -499,9 +508,9 @@ _GLOBAL(memcpy_power7) 5: bf cr7*4+2,6f lvx vr1,r0,r4 - vperm vr8,vr0,vr1,vr16 + VPERM(vr8,vr0,vr1,vr16) lvx vr0,r4,r9 - vperm vr9,vr1,vr0,vr16 + VPERM(vr9,vr1,vr0,vr16) addi r4,r4,32 stvx vr8,r0,r3 stvx vr9,r3,r9 @@ -509,13 +518,13 @@ _GLOBAL(memcpy_power7) 6: bf cr7*4+1,7f lvx vr3,r0,r4 - vperm vr8,vr0,vr3,vr16 + VPERM(vr8,vr0,vr3,vr16) lvx vr2,r4,r9 - vperm vr9,vr3,vr2,vr16 + VPERM(vr9,vr3,vr2,vr16) lvx vr1,r4,r10 - vperm vr10,vr2,vr1,vr16 + VPERM(vr10,vr2,vr1,vr16) lvx vr0,r4,r11 - vperm vr11,vr1,vr0,vr16 + VPERM(vr11,vr1,vr0,vr16) addi r4,r4,64 stvx vr8,r0,r3 stvx vr9,r3,r9 @@ -544,21 +553,21 @@ _GLOBAL(memcpy_power7) .align 5 8: lvx vr7,r0,r4 - vperm vr8,vr0,vr7,vr16 + VPERM(vr8,vr0,vr7,vr16) lvx vr6,r4,r9 - vperm vr9,vr7,vr6,vr16 + VPERM(vr9,vr7,vr6,vr16) lvx vr5,r4,r10 - vperm vr10,vr6,vr5,vr16 + VPERM(vr10,vr6,vr5,vr16) lvx vr4,r4,r11 - vperm vr11,vr5,vr4,vr16 + VPERM(vr11,vr5,vr4,vr16) lvx vr3,r4,r12 - vperm vr12,vr4,vr3,vr16 + VPERM(vr12,vr4,vr3,vr16) lvx vr2,r4,r14 - vperm vr13,vr3,vr2,vr16 + VPERM(vr13,vr3,vr2,vr16) lvx vr1,r4,r15 - vperm vr14,vr2,vr1,vr16 + VPERM(vr14,vr2,vr1,vr16) lvx vr0,r4,r16 - vperm vr15,vr1,vr0,vr16 + VPERM(vr15,vr1,vr0,vr16) addi r4,r4,128 stvx vr8,r0,r3 stvx vr9,r3,r9 @@ -582,13 +591,13 @@ _GLOBAL(memcpy_power7) bf cr7*4+1,9f lvx vr3,r0,r4 - vperm vr8,vr0,vr3,vr16 + VPERM(vr8,vr0,vr3,vr16) lvx vr2,r4,r9 - vperm vr9,vr3,vr2,vr16 + VPERM(vr9,vr3,vr2,vr16) lvx vr1,r4,r10 - vperm vr10,vr2,vr1,vr16 + VPERM(vr10,vr2,vr1,vr16) lvx vr0,r4,r11 - vperm vr11,vr1,vr0,vr16 + VPERM(vr11,vr1,vr0,vr16) addi r4,r4,64 stvx vr8,r0,r3 stvx vr9,r3,r9 @@ -598,9 +607,9 @@ _GLOBAL(memcpy_power7) 9: bf cr7*4+2,10f lvx vr1,r0,r4 - vperm vr8,vr0,vr1,vr16 + VPERM(vr8,vr0,vr1,vr16) lvx vr0,r4,r9 - vperm vr9,vr1,vr0,vr16 + VPERM(vr9,vr1,vr0,vr16) addi r4,r4,32 stvx vr8,r0,r3 stvx vr9,r3,r9 @@ -608,7 +617,7 @@ _GLOBAL(memcpy_power7) 10: bf cr7*4+3,11f lvx vr1,r0,r4 - vperm vr8,vr0,vr1,vr16 + VPERM(vr8,vr0,vr1,vr16) addi r4,r4,16 stvx vr8,r0,r3 addi r3,r3,16 diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c index b1faa1593c90..c0511c27a733 100644 --- a/arch/powerpc/lib/sstep.c +++ b/arch/powerpc/lib/sstep.c @@ -212,11 +212,19 @@ static int __kprobes read_mem_unaligned(unsigned long *dest, unsigned long ea, { int err; unsigned long x, b, c; +#ifdef __LITTLE_ENDIAN__ + int len = nb; /* save a copy of the length for byte reversal */ +#endif /* unaligned, do this in pieces */ x = 0; for (; nb > 0; nb -= c) { +#ifdef __LITTLE_ENDIAN__ + c = 1; +#endif +#ifdef __BIG_ENDIAN__ c = max_align(ea); +#endif if (c > nb) c = max_align(nb); err = read_mem_aligned(&b, ea, c); @@ -225,7 +233,24 @@ static int __kprobes read_mem_unaligned(unsigned long *dest, unsigned long ea, x = (x << (8 * c)) + b; ea += c; } +#ifdef __LITTLE_ENDIAN__ + switch (len) { + case 2: + *dest = byterev_2(x); + break; + case 4: + *dest = byterev_4(x); + break; +#ifdef __powerpc64__ + case 8: + *dest = byterev_8(x); + break; +#endif + } +#endif +#ifdef __BIG_ENDIAN__ *dest = x; +#endif return 0; } @@ -273,9 +298,29 @@ static int __kprobes write_mem_unaligned(unsigned long val, unsigned long ea, int err; unsigned long c; +#ifdef __LITTLE_ENDIAN__ + switch (nb) { + case 2: + val = byterev_2(val); + break; + case 4: + val = byterev_4(val); + break; +#ifdef __powerpc64__ + case 8: + val = byterev_8(val); + break; +#endif + } +#endif /* unaligned or little-endian, do this in pieces */ for (; nb > 0; nb -= c) { +#ifdef __LITTLE_ENDIAN__ + c = 1; +#endif +#ifdef __BIG_ENDIAN__ c = max_align(ea); +#endif if (c > nb) c = max_align(nb); err = write_mem_aligned(val >> (nb - c) * 8, ea, c); @@ -310,22 +355,36 @@ static int __kprobes do_fp_load(int rn, int (*func)(int, unsigned long), struct pt_regs *regs) { int err; - unsigned long val[sizeof(double) / sizeof(long)]; + union { + double dbl; + unsigned long ul[2]; + struct { +#ifdef __BIG_ENDIAN__ + unsigned _pad_; + unsigned word; +#endif +#ifdef __LITTLE_ENDIAN__ + unsigned word; + unsigned _pad_; +#endif + } single; + } data; unsigned long ptr; if (!address_ok(regs, ea, nb)) return -EFAULT; if ((ea & 3) == 0) return (*func)(rn, ea); - ptr = (unsigned long) &val[0]; + ptr = (unsigned long) &data.ul; if (sizeof(unsigned long) == 8 || nb == 4) { - err = read_mem_unaligned(&val[0], ea, nb, regs); - ptr += sizeof(unsigned long) - nb; + err = read_mem_unaligned(&data.ul[0], ea, nb, regs); + if (nb == 4) + ptr = (unsigned long)&(data.single.word); } else { /* reading a double on 32-bit */ - err = read_mem_unaligned(&val[0], ea, 4, regs); + err = read_mem_unaligned(&data.ul[0], ea, 4, regs); if (!err) - err = read_mem_unaligned(&val[1], ea + 4, 4, regs); + err = read_mem_unaligned(&data.ul[1], ea + 4, 4, regs); } if (err) return err; @@ -337,28 +396,42 @@ static int __kprobes do_fp_store(int rn, int (*func)(int, unsigned long), struct pt_regs *regs) { int err; - unsigned long val[sizeof(double) / sizeof(long)]; + union { + double dbl; + unsigned long ul[2]; + struct { +#ifdef __BIG_ENDIAN__ + unsigned _pad_; + unsigned word; +#endif +#ifdef __LITTLE_ENDIAN__ + unsigned word; + unsigned _pad_; +#endif + } single; + } data; unsigned long ptr; if (!address_ok(regs, ea, nb)) return -EFAULT; if ((ea & 3) == 0) return (*func)(rn, ea); - ptr = (unsigned long) &val[0]; + ptr = (unsigned long) &data.ul[0]; if (sizeof(unsigned long) == 8 || nb == 4) { - ptr += sizeof(unsigned long) - nb; + if (nb == 4) + ptr = (unsigned long)&(data.single.word); err = (*func)(rn, ptr); if (err) return err; - err = write_mem_unaligned(val[0], ea, nb, regs); + err = write_mem_unaligned(data.ul[0], ea, nb, regs); } else { /* writing a double on 32-bit */ err = (*func)(rn, ptr); if (err) return err; - err = write_mem_unaligned(val[0], ea, 4, regs); + err = write_mem_unaligned(data.ul[0], ea, 4, regs); if (!err) - err = write_mem_unaligned(val[1], ea + 4, 4, regs); + err = write_mem_unaligned(data.ul[1], ea + 4, 4, regs); } return err; } diff --git a/arch/powerpc/lib/xor_vmx.c b/arch/powerpc/lib/xor_vmx.c new file mode 100644 index 000000000000..e905f7c2ea7b --- /dev/null +++ b/arch/powerpc/lib/xor_vmx.c @@ -0,0 +1,177 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Copyright (C) IBM Corporation, 2012 + * + * Author: Anton Blanchard <anton@au.ibm.com> + */ +#include <altivec.h> + +#include <linux/preempt.h> +#include <linux/export.h> +#include <linux/sched.h> +#include <asm/switch_to.h> + +typedef vector signed char unative_t; + +#define DEFINE(V) \ + unative_t *V = (unative_t *)V##_in; \ + unative_t V##_0, V##_1, V##_2, V##_3 + +#define LOAD(V) \ + do { \ + V##_0 = V[0]; \ + V##_1 = V[1]; \ + V##_2 = V[2]; \ + V##_3 = V[3]; \ + } while (0) + +#define STORE(V) \ + do { \ + V[0] = V##_0; \ + V[1] = V##_1; \ + V[2] = V##_2; \ + V[3] = V##_3; \ + } while (0) + +#define XOR(V1, V2) \ + do { \ + V1##_0 = vec_xor(V1##_0, V2##_0); \ + V1##_1 = vec_xor(V1##_1, V2##_1); \ + V1##_2 = vec_xor(V1##_2, V2##_2); \ + V1##_3 = vec_xor(V1##_3, V2##_3); \ + } while (0) + +void xor_altivec_2(unsigned long bytes, unsigned long *v1_in, + unsigned long *v2_in) +{ + DEFINE(v1); + DEFINE(v2); + unsigned long lines = bytes / (sizeof(unative_t)) / 4; + + preempt_disable(); + enable_kernel_altivec(); + + do { + LOAD(v1); + LOAD(v2); + XOR(v1, v2); + STORE(v1); + + v1 += 4; + v2 += 4; + } while (--lines > 0); + + preempt_enable(); +} +EXPORT_SYMBOL(xor_altivec_2); + +void xor_altivec_3(unsigned long bytes, unsigned long *v1_in, + unsigned long *v2_in, unsigned long *v3_in) +{ + DEFINE(v1); + DEFINE(v2); + DEFINE(v3); + unsigned long lines = bytes / (sizeof(unative_t)) / 4; + + preempt_disable(); + enable_kernel_altivec(); + + do { + LOAD(v1); + LOAD(v2); + LOAD(v3); + XOR(v1, v2); + XOR(v1, v3); + STORE(v1); + + v1 += 4; + v2 += 4; + v3 += 4; + } while (--lines > 0); + + preempt_enable(); +} +EXPORT_SYMBOL(xor_altivec_3); + +void xor_altivec_4(unsigned long bytes, unsigned long *v1_in, + unsigned long *v2_in, unsigned long *v3_in, + unsigned long *v4_in) +{ + DEFINE(v1); + DEFINE(v2); + DEFINE(v3); + DEFINE(v4); + unsigned long lines = bytes / (sizeof(unative_t)) / 4; + + preempt_disable(); + enable_kernel_altivec(); + + do { + LOAD(v1); + LOAD(v2); + LOAD(v3); + LOAD(v4); + XOR(v1, v2); + XOR(v3, v4); + XOR(v1, v3); + STORE(v1); + + v1 += 4; + v2 += 4; + v3 += 4; + v4 += 4; + } while (--lines > 0); + + preempt_enable(); +} +EXPORT_SYMBOL(xor_altivec_4); + +void xor_altivec_5(unsigned long bytes, unsigned long *v1_in, + unsigned long *v2_in, unsigned long *v3_in, + unsigned long *v4_in, unsigned long *v5_in) +{ + DEFINE(v1); + DEFINE(v2); + DEFINE(v3); + DEFINE(v4); + DEFINE(v5); + unsigned long lines = bytes / (sizeof(unative_t)) / 4; + + preempt_disable(); + enable_kernel_altivec(); + + do { + LOAD(v1); + LOAD(v2); + LOAD(v3); + LOAD(v4); + LOAD(v5); + XOR(v1, v2); + XOR(v3, v4); + XOR(v1, v5); + XOR(v1, v3); + STORE(v1); + + v1 += 4; + v2 += 4; + v3 += 4; + v4 += 4; + v5 += 4; + } while (--lines > 0); + + preempt_enable(); +} +EXPORT_SYMBOL(xor_altivec_5); diff --git a/arch/powerpc/mm/dma-noncoherent.c b/arch/powerpc/mm/dma-noncoherent.c index 6747eece84af..7b6c10750179 100644 --- a/arch/powerpc/mm/dma-noncoherent.c +++ b/arch/powerpc/mm/dma-noncoherent.c @@ -287,9 +287,7 @@ void __dma_free_coherent(size_t size, void *vaddr) pte_clear(&init_mm, addr, ptep); if (pfn_valid(pfn)) { struct page *page = pfn_to_page(pfn); - - ClearPageReserved(page); - __free_page(page); + __free_reserved_page(page); } } addr += PAGE_SIZE; diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c index c33d939120c9..3ea26c25590b 100644 --- a/arch/powerpc/mm/hash_native_64.c +++ b/arch/powerpc/mm/hash_native_64.c @@ -35,7 +35,11 @@ #define DBG_LOW(fmt...) #endif +#ifdef __BIG_ENDIAN__ #define HPTE_LOCK_BIT 3 +#else +#define HPTE_LOCK_BIT (56+3) +#endif DEFINE_RAW_SPINLOCK(native_tlbie_lock); @@ -172,7 +176,7 @@ static inline void tlbie(unsigned long vpn, int psize, int apsize, static inline void native_lock_hpte(struct hash_pte *hptep) { - unsigned long *word = &hptep->v; + unsigned long *word = (unsigned long *)&hptep->v; while (1) { if (!test_and_set_bit_lock(HPTE_LOCK_BIT, word)) @@ -184,7 +188,7 @@ static inline void native_lock_hpte(struct hash_pte *hptep) static inline void native_unlock_hpte(struct hash_pte *hptep) { - unsigned long *word = &hptep->v; + unsigned long *word = (unsigned long *)&hptep->v; clear_bit_unlock(HPTE_LOCK_BIT, word); } @@ -204,10 +208,10 @@ static long native_hpte_insert(unsigned long hpte_group, unsigned long vpn, } for (i = 0; i < HPTES_PER_GROUP; i++) { - if (! (hptep->v & HPTE_V_VALID)) { + if (! (be64_to_cpu(hptep->v) & HPTE_V_VALID)) { /* retry with lock held */ native_lock_hpte(hptep); - if (! (hptep->v & HPTE_V_VALID)) + if (! (be64_to_cpu(hptep->v) & HPTE_V_VALID)) break; native_unlock_hpte(hptep); } @@ -226,14 +230,14 @@ static long native_hpte_insert(unsigned long hpte_group, unsigned long vpn, i, hpte_v, hpte_r); } - hptep->r = hpte_r; + hptep->r = cpu_to_be64(hpte_r); /* Guarantee the second dword is visible before the valid bit */ eieio(); /* * Now set the first dword including the valid bit * NOTE: this also unlocks the hpte */ - hptep->v = hpte_v; + hptep->v = cpu_to_be64(hpte_v); __asm__ __volatile__ ("ptesync" : : : "memory"); @@ -254,12 +258,12 @@ static long native_hpte_remove(unsigned long hpte_group) for (i = 0; i < HPTES_PER_GROUP; i++) { hptep = htab_address + hpte_group + slot_offset; - hpte_v = hptep->v; + hpte_v = be64_to_cpu(hptep->v); if ((hpte_v & HPTE_V_VALID) && !(hpte_v & HPTE_V_BOLTED)) { /* retry with lock held */ native_lock_hpte(hptep); - hpte_v = hptep->v; + hpte_v = be64_to_cpu(hptep->v); if ((hpte_v & HPTE_V_VALID) && !(hpte_v & HPTE_V_BOLTED)) break; @@ -294,7 +298,7 @@ static long native_hpte_updatepp(unsigned long slot, unsigned long newpp, native_lock_hpte(hptep); - hpte_v = hptep->v; + hpte_v = be64_to_cpu(hptep->v); /* * We need to invalidate the TLB always because hpte_remove doesn't do * a tlb invalidate. If a hash bucket gets full, we "evict" a more/less @@ -308,8 +312,8 @@ static long native_hpte_updatepp(unsigned long slot, unsigned long newpp, } else { DBG_LOW(" -> hit\n"); /* Update the HPTE */ - hptep->r = (hptep->r & ~(HPTE_R_PP | HPTE_R_N)) | - (newpp & (HPTE_R_PP | HPTE_R_N | HPTE_R_C)); + hptep->r = cpu_to_be64((be64_to_cpu(hptep->r) & ~(HPTE_R_PP | HPTE_R_N)) | + (newpp & (HPTE_R_PP | HPTE_R_N | HPTE_R_C))); } native_unlock_hpte(hptep); @@ -334,7 +338,7 @@ static long native_hpte_find(unsigned long vpn, int psize, int ssize) slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; for (i = 0; i < HPTES_PER_GROUP; i++) { hptep = htab_address + slot; - hpte_v = hptep->v; + hpte_v = be64_to_cpu(hptep->v); if (HPTE_V_COMPARE(hpte_v, want_v) && (hpte_v & HPTE_V_VALID)) /* HPTE matches */ @@ -369,8 +373,9 @@ static void native_hpte_updateboltedpp(unsigned long newpp, unsigned long ea, hptep = htab_address + slot; /* Update the HPTE */ - hptep->r = (hptep->r & ~(HPTE_R_PP | HPTE_R_N)) | - (newpp & (HPTE_R_PP | HPTE_R_N)); + hptep->r = cpu_to_be64((be64_to_cpu(hptep->r) & + ~(HPTE_R_PP | HPTE_R_N)) | + (newpp & (HPTE_R_PP | HPTE_R_N))); /* * Ensure it is out of the tlb too. Bolted entries base and * actual page size will be same. @@ -392,7 +397,7 @@ static void native_hpte_invalidate(unsigned long slot, unsigned long vpn, want_v = hpte_encode_avpn(vpn, bpsize, ssize); native_lock_hpte(hptep); - hpte_v = hptep->v; + hpte_v = be64_to_cpu(hptep->v); /* * We need to invalidate the TLB always because hpte_remove doesn't do @@ -458,7 +463,7 @@ static void native_hugepage_invalidate(struct mm_struct *mm, hptep = htab_address + slot; want_v = hpte_encode_avpn(vpn, psize, ssize); native_lock_hpte(hptep); - hpte_v = hptep->v; + hpte_v = be64_to_cpu(hptep->v); /* Even if we miss, we need to invalidate the TLB */ if (!HPTE_V_COMPARE(hpte_v, want_v) || !(hpte_v & HPTE_V_VALID)) @@ -519,11 +524,12 @@ static void hpte_decode(struct hash_pte *hpte, unsigned long slot, int *psize, int *apsize, int *ssize, unsigned long *vpn) { unsigned long avpn, pteg, vpi; - unsigned long hpte_v = hpte->v; + unsigned long hpte_v = be64_to_cpu(hpte->v); + unsigned long hpte_r = be64_to_cpu(hpte->r); unsigned long vsid, seg_off; int size, a_size, shift; /* Look at the 8 bit LP value */ - unsigned int lp = (hpte->r >> LP_SHIFT) & ((1 << LP_BITS) - 1); + unsigned int lp = (hpte_r >> LP_SHIFT) & ((1 << LP_BITS) - 1); if (!(hpte_v & HPTE_V_LARGE)) { size = MMU_PAGE_4K; @@ -612,7 +618,7 @@ static void native_hpte_clear(void) * running, right? and for crash dump, we probably * don't want to wait for a maybe bad cpu. */ - hpte_v = hptep->v; + hpte_v = be64_to_cpu(hptep->v); /* * Call __tlbie() here rather than tlbie() since we @@ -664,7 +670,7 @@ static void native_flush_hash_range(unsigned long number, int local) hptep = htab_address + slot; want_v = hpte_encode_avpn(vpn, psize, ssize); native_lock_hpte(hptep); - hpte_v = hptep->v; + hpte_v = be64_to_cpu(hptep->v); if (!HPTE_V_COMPARE(hpte_v, want_v) || !(hpte_v & HPTE_V_VALID)) native_unlock_hpte(hptep); diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index bde8b5589755..6176b3cdf579 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c @@ -251,19 +251,18 @@ static int __init htab_dt_scan_seg_sizes(unsigned long node, void *data) { char *type = of_get_flat_dt_prop(node, "device_type", NULL); - u32 *prop; + __be32 *prop; unsigned long size = 0; /* We are scanning "cpu" nodes only */ if (type == NULL || strcmp(type, "cpu") != 0) return 0; - prop = (u32 *)of_get_flat_dt_prop(node, "ibm,processor-segment-sizes", - &size); + prop = of_get_flat_dt_prop(node, "ibm,processor-segment-sizes", &size); if (prop == NULL) return 0; for (; size >= 4; size -= 4, ++prop) { - if (prop[0] == 40) { + if (be32_to_cpu(prop[0]) == 40) { DBG("1T segment support detected\n"); cur_cpu_spec->mmu_features |= MMU_FTR_1T_SEGMENT; return 1; @@ -307,23 +306,22 @@ static int __init htab_dt_scan_page_sizes(unsigned long node, void *data) { char *type = of_get_flat_dt_prop(node, "device_type", NULL); - u32 *prop; + __be32 *prop; unsigned long size = 0; /* We are scanning "cpu" nodes only */ if (type == NULL || strcmp(type, "cpu") != 0) return 0; - prop = (u32 *)of_get_flat_dt_prop(node, - "ibm,segment-page-sizes", &size); + prop = of_get_flat_dt_prop(node, "ibm,segment-page-sizes", &size); if (prop != NULL) { pr_info("Page sizes from device-tree:\n"); size /= 4; cur_cpu_spec->mmu_features &= ~(MMU_FTR_16M_PAGE); while(size > 0) { - unsigned int base_shift = prop[0]; - unsigned int slbenc = prop[1]; - unsigned int lpnum = prop[2]; + unsigned int base_shift = be32_to_cpu(prop[0]); + unsigned int slbenc = be32_to_cpu(prop[1]); + unsigned int lpnum = be32_to_cpu(prop[2]); struct mmu_psize_def *def; int idx, base_idx; @@ -356,8 +354,8 @@ static int __init htab_dt_scan_page_sizes(unsigned long node, def->tlbiel = 0; while (size > 0 && lpnum) { - unsigned int shift = prop[0]; - int penc = prop[1]; + unsigned int shift = be32_to_cpu(prop[0]); + int penc = be32_to_cpu(prop[1]); prop += 2; size -= 2; lpnum--; @@ -390,8 +388,8 @@ static int __init htab_dt_scan_hugepage_blocks(unsigned long node, const char *uname, int depth, void *data) { char *type = of_get_flat_dt_prop(node, "device_type", NULL); - unsigned long *addr_prop; - u32 *page_count_prop; + __be64 *addr_prop; + __be32 *page_count_prop; unsigned int expected_pages; long unsigned int phys_addr; long unsigned int block_size; @@ -405,12 +403,12 @@ static int __init htab_dt_scan_hugepage_blocks(unsigned long node, page_count_prop = of_get_flat_dt_prop(node, "ibm,expected#pages", NULL); if (page_count_prop == NULL) return 0; - expected_pages = (1 << page_count_prop[0]); + expected_pages = (1 << be32_to_cpu(page_count_prop[0])); addr_prop = of_get_flat_dt_prop(node, "reg", NULL); if (addr_prop == NULL) return 0; - phys_addr = addr_prop[0]; - block_size = addr_prop[1]; + phys_addr = be64_to_cpu(addr_prop[0]); + block_size = be64_to_cpu(addr_prop[1]); if (block_size != (16 * GB)) return 0; printk(KERN_INFO "Huge page(16GB) memory: " @@ -534,16 +532,16 @@ static int __init htab_dt_scan_pftsize(unsigned long node, void *data) { char *type = of_get_flat_dt_prop(node, "device_type", NULL); - u32 *prop; + __be32 *prop; /* We are scanning "cpu" nodes only */ if (type == NULL || strcmp(type, "cpu") != 0) return 0; - prop = (u32 *)of_get_flat_dt_prop(node, "ibm,pft-size", NULL); + prop = of_get_flat_dt_prop(node, "ibm,pft-size", NULL); if (prop != NULL) { /* pft_size[0] is the NUMA CEC cookie */ - ppc64_pft_size = prop[1]; + ppc64_pft_size = be32_to_cpu(prop[1]); return 1; } return 0; diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index d67db4bd672d..90bb6d9409bf 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -633,8 +633,6 @@ static void hugetlb_free_pud_range(struct mmu_gather *tlb, pgd_t *pgd, /* * This function frees user-level page tables of a process. - * - * Must be called with pagetable lock held. */ void hugetlb_free_pgd_range(struct mmu_gather *tlb, unsigned long addr, unsigned long end, diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c index d47d3dab4870..cff59f1bec23 100644 --- a/arch/powerpc/mm/init_32.c +++ b/arch/powerpc/mm/init_32.c @@ -213,7 +213,12 @@ void setup_initial_memory_limit(phys_addr_t first_memblock_base, */ BUG_ON(first_memblock_base != 0); +#ifdef CONFIG_PIN_TLB + /* 8xx can only access 24MB at the moment */ + memblock_set_current_limit(min_t(u64, first_memblock_size, 0x01800000)); +#else /* 8xx can only access 8MB at the moment */ memblock_set_current_limit(min_t(u64, first_memblock_size, 0x00800000)); +#endif } #endif /* CONFIG_8xx */ diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c index 8ed035d2edb5..e3734edffa69 100644 --- a/arch/powerpc/mm/init_64.c +++ b/arch/powerpc/mm/init_64.c @@ -304,5 +304,54 @@ void register_page_bootmem_memmap(unsigned long section_nr, struct page *start_page, unsigned long size) { } -#endif /* CONFIG_SPARSEMEM_VMEMMAP */ +/* + * We do not have access to the sparsemem vmemmap, so we fallback to + * walking the list of sparsemem blocks which we already maintain for + * the sake of crashdump. In the long run, we might want to maintain + * a tree if performance of that linear walk becomes a problem. + * + * realmode_pfn_to_page functions can fail due to: + * 1) As real sparsemem blocks do not lay in RAM continously (they + * are in virtual address space which is not available in the real mode), + * the requested page struct can be split between blocks so get_page/put_page + * may fail. + * 2) When huge pages are used, the get_page/put_page API will fail + * in real mode as the linked addresses in the page struct are virtual + * too. + */ +struct page *realmode_pfn_to_page(unsigned long pfn) +{ + struct vmemmap_backing *vmem_back; + struct page *page; + unsigned long page_size = 1 << mmu_psize_defs[mmu_vmemmap_psize].shift; + unsigned long pg_va = (unsigned long) pfn_to_page(pfn); + + for (vmem_back = vmemmap_list; vmem_back; vmem_back = vmem_back->list) { + if (pg_va < vmem_back->virt_addr) + continue; + + /* Check that page struct is not split between real pages */ + if ((pg_va + sizeof(struct page)) > + (vmem_back->virt_addr + page_size)) + return NULL; + + page = (struct page *) (vmem_back->phys + pg_va - + vmem_back->virt_addr); + return page; + } + + return NULL; +} +EXPORT_SYMBOL_GPL(realmode_pfn_to_page); + +#elif defined(CONFIG_FLATMEM) + +struct page *realmode_pfn_to_page(unsigned long pfn) +{ + struct page *page = pfn_to_page(pfn); + return page; +} +EXPORT_SYMBOL_GPL(realmode_pfn_to_page); + +#endif /* CONFIG_SPARSEMEM_VMEMMAP/CONFIG_FLATMEM */ diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index c916127f10c3..078d3e00a616 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -195,7 +195,7 @@ static const __be32 *of_get_usable_memory(struct device_node *memory) u32 len; prop = of_get_property(memory, "linux,drconf-usable-memory", &len); if (!prop || len < sizeof(unsigned int)) - return 0; + return NULL; return prop; } @@ -938,8 +938,7 @@ static void __init mark_reserved_regions_for_nid(int nid) unsigned long start_pfn = physbase >> PAGE_SHIFT; unsigned long end_pfn = PFN_UP(physbase + size); struct node_active_region node_ar; - unsigned long node_end_pfn = node->node_start_pfn + - node->node_spanned_pages; + unsigned long node_end_pfn = pgdat_end_pfn(node); /* * Check to make sure that this memblock.reserved area is @@ -1154,7 +1153,7 @@ static int hot_add_drconf_scn_to_nid(struct device_node *memory, * represented in the device tree as a node (i.e. memory@XXXX) for * each memblock. */ -int hot_add_node_scn_to_nid(unsigned long scn_addr) +static int hot_add_node_scn_to_nid(unsigned long scn_addr) { struct device_node *memory; int nid = -1; @@ -1235,7 +1234,7 @@ static u64 hot_add_drconf_memory_max(void) struct device_node *memory = NULL; unsigned int drconf_cell_cnt = 0; u64 lmb_size = 0; - const __be32 *dm = 0; + const __be32 *dm = NULL; memory = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory"); if (memory) { @@ -1535,7 +1534,7 @@ static void topology_work_fn(struct work_struct *work) } static DECLARE_WORK(topology_work, topology_work_fn); -void topology_schedule_update(void) +static void topology_schedule_update(void) { schedule_work(&topology_work); } diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c index edda589795c3..841e0d00863c 100644 --- a/arch/powerpc/mm/pgtable.c +++ b/arch/powerpc/mm/pgtable.c @@ -32,8 +32,6 @@ #include <asm/tlbflush.h> #include <asm/tlb.h> -#include "mmu_decl.h" - static inline int is_exec_fault(void) { return current->thread.regs && TRAP(current->thread.regs) == 0x400; @@ -72,7 +70,7 @@ struct page * maybe_pte_to_page(pte_t pte) * support falls into the same category. */ -static pte_t set_pte_filter(pte_t pte, unsigned long addr) +static pte_t set_pte_filter(pte_t pte) { pte = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS); if (pte_looks_normal(pte) && !(cpu_has_feature(CPU_FTR_COHERENT_ICACHE) || @@ -81,17 +79,6 @@ static pte_t set_pte_filter(pte_t pte, unsigned long addr) if (!pg) return pte; if (!test_bit(PG_arch_1, &pg->flags)) { -#ifdef CONFIG_8xx - /* On 8xx, cache control instructions (particularly - * "dcbst" from flush_dcache_icache) fault as write - * operation if there is an unpopulated TLB entry - * for the address in question. To workaround that, - * we invalidate the TLB here, thus avoiding dcbst - * misbehaviour. - */ - /* 8xx doesn't care about PID, size or ind args */ - _tlbil_va(addr, 0, 0, 0); -#endif /* CONFIG_8xx */ flush_dcache_icache_page(pg); set_bit(PG_arch_1, &pg->flags); } @@ -111,7 +98,7 @@ static pte_t set_access_flags_filter(pte_t pte, struct vm_area_struct *vma, * as we don't have two bits to spare for _PAGE_EXEC and _PAGE_HWEXEC so * instead we "filter out" the exec permission for non clean pages. */ -static pte_t set_pte_filter(pte_t pte, unsigned long addr) +static pte_t set_pte_filter(pte_t pte) { struct page *pg; @@ -193,7 +180,7 @@ void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, * this context might not have been activated yet when this * is called. */ - pte = set_pte_filter(pte, addr); + pte = set_pte_filter(pte); /* Perform the setting of the PTE */ __set_pte_at(mm, addr, ptep, pte, 0); diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c index 6c856fb8c15b..5b9601715289 100644 --- a/arch/powerpc/mm/pgtable_32.c +++ b/arch/powerpc/mm/pgtable_32.c @@ -121,7 +121,10 @@ pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address) ptepage = alloc_pages(flags, 0); if (!ptepage) return NULL; - pgtable_page_ctor(ptepage); + if (!pgtable_page_ctor(ptepage)) { + __free_page(ptepage); + return NULL; + } return ptepage; } diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c index 536eec72c0f7..9d95786aa80f 100644 --- a/arch/powerpc/mm/pgtable_64.c +++ b/arch/powerpc/mm/pgtable_64.c @@ -378,6 +378,10 @@ static pte_t *__alloc_for_cache(struct mm_struct *mm, int kernel) __GFP_REPEAT | __GFP_ZERO); if (!page) return NULL; + if (!kernel && !pgtable_page_ctor(page)) { + __free_page(page); + return NULL; + } ret = page_address(page); spin_lock(&mm->page_table_lock); @@ -392,9 +396,6 @@ static pte_t *__alloc_for_cache(struct mm_struct *mm, int kernel) } spin_unlock(&mm->page_table_lock); - if (!kernel) - pgtable_page_ctor(page); - return (pte_t *)ret; } diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h index 8a5dfaf5c6b7..9aee27c582dc 100644 --- a/arch/powerpc/net/bpf_jit.h +++ b/arch/powerpc/net/bpf_jit.h @@ -39,6 +39,7 @@ #define r_X 5 #define r_addr 6 #define r_scratch1 7 +#define r_scratch2 8 #define r_D 14 #define r_HL 15 #define r_M 16 @@ -92,6 +93,8 @@ DECLARE_LOAD_FUNC(sk_load_byte_msh); ___PPC_RA(base) | IMM_L(i)) #define PPC_LHZ(r, base, i) EMIT(PPC_INST_LHZ | ___PPC_RT(r) | \ ___PPC_RA(base) | IMM_L(i)) +#define PPC_LHBRX(r, base, b) EMIT(PPC_INST_LHBRX | ___PPC_RT(r) | \ + ___PPC_RA(base) | ___PPC_RB(b)) /* Convenience helpers for the above with 'far' offsets: */ #define PPC_LD_OFFS(r, base, i) do { if ((i) < 32768) PPC_LD(r, base, i); \ else { PPC_ADDIS(r, base, IMM_HA(i)); \ @@ -186,6 +189,14 @@ DECLARE_LOAD_FUNC(sk_load_byte_msh); PPC_ORI(d, d, (uintptr_t)(i) & 0xffff); \ } } while (0); +#define PPC_LHBRX_OFFS(r, base, i) \ + do { PPC_LI32(r, i); PPC_LHBRX(r, r, base); } while(0) +#ifdef __LITTLE_ENDIAN__ +#define PPC_NTOHS_OFFS(r, base, i) PPC_LHBRX_OFFS(r, base, i) +#else +#define PPC_NTOHS_OFFS(r, base, i) PPC_LHZ_OFFS(r, base, i) +#endif + static inline bool is_nearbranch(int offset) { return (offset < 32768) && (offset >= -32768); diff --git a/arch/powerpc/net/bpf_jit_64.S b/arch/powerpc/net/bpf_jit_64.S index 7d3a3b5619a2..e76eba74d9da 100644 --- a/arch/powerpc/net/bpf_jit_64.S +++ b/arch/powerpc/net/bpf_jit_64.S @@ -43,8 +43,11 @@ sk_load_word_positive_offset: cmpd r_scratch1, r_addr blt bpf_slow_path_word /* Nope, just hitting the header. cr0 here is eq or gt! */ +#ifdef __LITTLE_ENDIAN__ + lwbrx r_A, r_D, r_addr +#else lwzx r_A, r_D, r_addr - /* When big endian we don't need to byteswap. */ +#endif blr /* Return success, cr0 != LT */ .globl sk_load_half @@ -56,7 +59,11 @@ sk_load_half_positive_offset: subi r_scratch1, r_HL, 2 cmpd r_scratch1, r_addr blt bpf_slow_path_half +#ifdef __LITTLE_ENDIAN__ + lhbrx r_A, r_D, r_addr +#else lhzx r_A, r_D, r_addr +#endif blr .globl sk_load_byte diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c index 2345bdb4d917..ac3c2a10dafd 100644 --- a/arch/powerpc/net/bpf_jit_comp.c +++ b/arch/powerpc/net/bpf_jit_comp.c @@ -17,14 +17,8 @@ #include "bpf_jit.h" -#ifndef __BIG_ENDIAN -/* There are endianness assumptions herein. */ -#error "Little-endian PPC not supported in BPF compiler" -#endif - int bpf_jit_enable __read_mostly; - static inline void bpf_flush_icache(void *start, void *end) { smp_wmb(); @@ -193,6 +187,26 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image, PPC_MUL(r_A, r_A, r_scratch1); } break; + case BPF_S_ALU_MOD_X: /* A %= X; */ + ctx->seen |= SEEN_XREG; + PPC_CMPWI(r_X, 0); + if (ctx->pc_ret0 != -1) { + PPC_BCC(COND_EQ, addrs[ctx->pc_ret0]); + } else { + PPC_BCC_SHORT(COND_NE, (ctx->idx*4)+12); + PPC_LI(r_ret, 0); + PPC_JMP(exit_addr); + } + PPC_DIVWU(r_scratch1, r_A, r_X); + PPC_MUL(r_scratch1, r_X, r_scratch1); + PPC_SUB(r_A, r_A, r_scratch1); + break; + case BPF_S_ALU_MOD_K: /* A %= K; */ + PPC_LI32(r_scratch2, K); + PPC_DIVWU(r_scratch1, r_A, r_scratch2); + PPC_MUL(r_scratch1, r_scratch2, r_scratch1); + PPC_SUB(r_A, r_A, r_scratch1); + break; case BPF_S_ALU_DIV_X: /* A /= X; */ ctx->seen |= SEEN_XREG; PPC_CMPWI(r_X, 0); @@ -346,18 +360,11 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image, break; /*** Ancillary info loads ***/ - - /* None of the BPF_S_ANC* codes appear to be passed by - * sk_chk_filter(). The interpreter and the x86 BPF - * compiler implement them so we do too -- they may be - * planted in future. - */ case BPF_S_ANC_PROTOCOL: /* A = ntohs(skb->protocol); */ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, protocol) != 2); - PPC_LHZ_OFFS(r_A, r_skb, offsetof(struct sk_buff, - protocol)); - /* ntohs is a NOP with BE loads. */ + PPC_NTOHS_OFFS(r_A, r_skb, offsetof(struct sk_buff, + protocol)); break; case BPF_S_ANC_IFINDEX: PPC_LD_OFFS(r_scratch1, r_skb, offsetof(struct sk_buff, diff --git a/arch/powerpc/platforms/512x/clock.c b/arch/powerpc/platforms/512x/clock.c index e504166e089a..fd8a37653417 100644 --- a/arch/powerpc/platforms/512x/clock.c +++ b/arch/powerpc/platforms/512x/clock.c @@ -24,6 +24,7 @@ #include <linux/mutex.h> #include <linux/io.h> +#include <linux/of_address.h> #include <linux/of_platform.h> #include <asm/mpc5xxx.h> #include <asm/mpc5121.h> diff --git a/arch/powerpc/platforms/512x/mpc512x_shared.c b/arch/powerpc/platforms/512x/mpc512x_shared.c index a82a41b4fd91..36b5652aada2 100644 --- a/arch/powerpc/platforms/512x/mpc512x_shared.c +++ b/arch/powerpc/platforms/512x/mpc512x_shared.c @@ -60,8 +60,6 @@ void mpc512x_restart(char *cmd) ; } -#if IS_ENABLED(CONFIG_FB_FSL_DIU) - struct fsl_diu_shared_fb { u8 gamma[0x300]; /* 32-bit aligned! */ struct diu_ad ad0; /* 32-bit aligned! */ @@ -71,7 +69,7 @@ struct fsl_diu_shared_fb { }; #define DIU_DIV_MASK 0x000000ff -void mpc512x_set_pixel_clock(unsigned int pixclock) +static void mpc512x_set_pixel_clock(unsigned int pixclock) { unsigned long bestval, bestfreq, speed, busfreq; unsigned long minpixclock, maxpixclock, pixval; @@ -164,7 +162,7 @@ void mpc512x_set_pixel_clock(unsigned int pixclock) iounmap(ccm); } -enum fsl_diu_monitor_port +static enum fsl_diu_monitor_port mpc512x_valid_monitor_port(enum fsl_diu_monitor_port port) { return FSL_DIU_PORT_DVI; @@ -179,7 +177,7 @@ static inline void mpc512x_free_bootmem(struct page *page) free_reserved_page(page); } -void mpc512x_release_bootmem(void) +static void mpc512x_release_bootmem(void) { unsigned long addr = diu_shared_fb.fb_phys & PAGE_MASK; unsigned long size = diu_shared_fb.fb_len; @@ -205,7 +203,7 @@ void mpc512x_release_bootmem(void) * address range will be reserved in setup_arch() after bootmem * allocator is up. */ -void __init mpc512x_init_diu(void) +static void __init mpc512x_init_diu(void) { struct device_node *np; struct diu __iomem *diu_reg; @@ -274,7 +272,7 @@ out: iounmap(diu_reg); } -void __init mpc512x_setup_diu(void) +static void __init mpc512x_setup_diu(void) { int ret; @@ -303,8 +301,6 @@ void __init mpc512x_setup_diu(void) diu_ops.release_bootmem = mpc512x_release_bootmem; } -#endif - void __init mpc512x_init_IRQ(void) { struct device_node *np; @@ -337,7 +333,7 @@ static struct of_device_id __initdata of_bus_ids[] = { {}, }; -void __init mpc512x_declare_of_platform_devices(void) +static void __init mpc512x_declare_of_platform_devices(void) { if (of_platform_bus_probe(NULL, of_bus_ids, NULL)) printk(KERN_ERR __FILE__ ": " @@ -387,7 +383,7 @@ static unsigned int __init get_fifo_size(struct device_node *np, ((u32)(_base) + sizeof(struct mpc52xx_psc))) /* Init PSC FIFO space for TX and RX slices */ -void __init mpc512x_psc_fifo_init(void) +static void __init mpc512x_psc_fifo_init(void) { struct device_node *np; void __iomem *psc; diff --git a/arch/powerpc/platforms/512x/pdm360ng.c b/arch/powerpc/platforms/512x/pdm360ng.c index 24b314d7bd5f..116f2325b20b 100644 --- a/arch/powerpc/platforms/512x/pdm360ng.c +++ b/arch/powerpc/platforms/512x/pdm360ng.c @@ -14,6 +14,8 @@ #include <linux/kernel.h> #include <linux/io.h> +#include <linux/of_address.h> +#include <linux/of_fdt.h> #include <linux/of_platform.h> #include <asm/machdep.h> diff --git a/arch/powerpc/platforms/52xx/Kconfig b/arch/powerpc/platforms/52xx/Kconfig index 90f4496017e4..af54174801f7 100644 --- a/arch/powerpc/platforms/52xx/Kconfig +++ b/arch/powerpc/platforms/52xx/Kconfig @@ -57,5 +57,5 @@ config PPC_MPC5200_BUGFIX config PPC_MPC5200_LPBFIFO tristate "MPC5200 LocalPlus bus FIFO driver" - depends on PPC_MPC52xx + depends on PPC_MPC52xx && PPC_BESTCOMM select PPC_BESTCOMM_GEN_BD diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c index b69221ba07fd..2898b737deb7 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c @@ -340,7 +340,7 @@ static int mpc52xx_irqhost_map(struct irq_domain *h, unsigned int virq, { int l1irq; int l2irq; - struct irq_chip *irqchip; + struct irq_chip *uninitialized_var(irqchip); void *hndlr; int type; u32 reg; @@ -373,9 +373,8 @@ static int mpc52xx_irqhost_map(struct irq_domain *h, unsigned int virq, case MPC52xx_IRQ_L1_PERP: irqchip = &mpc52xx_periph_irqchip; break; case MPC52xx_IRQ_L1_SDMA: irqchip = &mpc52xx_sdma_irqchip; break; case MPC52xx_IRQ_L1_CRIT: - default: pr_warn("%s: Critical IRQ #%d is unsupported! Nopping it.\n", - __func__, l1irq); + __func__, l2irq); irq_set_chip(virq, &no_irq_chip); return 0; } diff --git a/arch/powerpc/platforms/82xx/mpc8272_ads.c b/arch/powerpc/platforms/82xx/mpc8272_ads.c index 30394b409b3f..6a14cf50f4a2 100644 --- a/arch/powerpc/platforms/82xx/mpc8272_ads.c +++ b/arch/powerpc/platforms/82xx/mpc8272_ads.c @@ -16,6 +16,8 @@ #include <linux/init.h> #include <linux/interrupt.h> #include <linux/fsl_devices.h> +#include <linux/of_address.h> +#include <linux/of_fdt.h> #include <linux/of_platform.h> #include <linux/io.h> diff --git a/arch/powerpc/platforms/82xx/pq2fads.c b/arch/powerpc/platforms/82xx/pq2fads.c index e1dceeec4994..e5f82ec8df17 100644 --- a/arch/powerpc/platforms/82xx/pq2fads.c +++ b/arch/powerpc/platforms/82xx/pq2fads.c @@ -15,6 +15,8 @@ #include <linux/init.h> #include <linux/interrupt.h> #include <linux/fsl_devices.h> +#include <linux/of_address.h> +#include <linux/of_fdt.h> #include <linux/of_platform.h> #include <asm/io.h> diff --git a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c index 7bc315822935..fd71cfdf2380 100644 --- a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c +++ b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c @@ -204,7 +204,6 @@ static int mcu_remove(struct i2c_client *client) ret = mcu_gpiochip_remove(mcu); if (ret) return ret; - i2c_set_clientdata(client, NULL); kfree(mcu); return 0; } diff --git a/arch/powerpc/platforms/83xx/suspend.c b/arch/powerpc/platforms/83xx/suspend.c index 1d769a29249f..3d9716ccd327 100644 --- a/arch/powerpc/platforms/83xx/suspend.c +++ b/arch/powerpc/platforms/83xx/suspend.c @@ -20,6 +20,8 @@ #include <linux/freezer.h> #include <linux/suspend.h> #include <linux/fsl_devices.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> #include <linux/of_platform.h> #include <linux/export.h> diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig index de2eb9320993..4d4634958cfb 100644 --- a/arch/powerpc/platforms/85xx/Kconfig +++ b/arch/powerpc/platforms/85xx/Kconfig @@ -218,83 +218,16 @@ config GE_IMP3A This board is a 3U CompactPCI Single Board Computer with a Freescale P2020 processor. -config P2041_RDB - bool "Freescale P2041 RDB" - select DEFAULT_UIMAGE - select PPC_E500MC - select PHYS_64BIT - select SWIOTLB - select ARCH_REQUIRE_GPIOLIB - select GPIO_MPC8XXX - select HAS_RAPIDIO - select PPC_EPAPR_HV_PIC - help - This option enables support for the P2041 RDB board - -config P3041_DS - bool "Freescale P3041 DS" - select DEFAULT_UIMAGE - select PPC_E500MC - select PHYS_64BIT - select SWIOTLB - select ARCH_REQUIRE_GPIOLIB - select GPIO_MPC8XXX - select HAS_RAPIDIO - select PPC_EPAPR_HV_PIC - help - This option enables support for the P3041 DS board - -config P4080_DS - bool "Freescale P4080 DS" - select DEFAULT_UIMAGE - select PPC_E500MC - select PHYS_64BIT - select SWIOTLB - select ARCH_REQUIRE_GPIOLIB - select GPIO_MPC8XXX - select HAS_RAPIDIO - select PPC_EPAPR_HV_PIC - help - This option enables support for the P4080 DS board - config SGY_CTS1000 tristate "Servergy CTS-1000 support" select GPIOLIB select OF_GPIO - depends on P4080_DS + depends on CORENET_GENERIC help Enable this to support functionality in Servergy's CTS-1000 systems. endif # PPC32 -config P5020_DS - bool "Freescale P5020 DS" - select DEFAULT_UIMAGE - select E500 - select PPC_E500MC - select PHYS_64BIT - select SWIOTLB - select ARCH_REQUIRE_GPIOLIB - select GPIO_MPC8XXX - select HAS_RAPIDIO - select PPC_EPAPR_HV_PIC - help - This option enables support for the P5020 DS board - -config P5040_DS - bool "Freescale P5040 DS" - select DEFAULT_UIMAGE - select E500 - select PPC_E500MC - select PHYS_64BIT - select SWIOTLB - select ARCH_REQUIRE_GPIOLIB - select GPIO_MPC8XXX - select HAS_RAPIDIO - select PPC_EPAPR_HV_PIC - help - This option enables support for the P5040 DS board - config PPC_QEMU_E500 bool "QEMU generic e500 platform" select DEFAULT_UIMAGE @@ -310,10 +243,8 @@ config PPC_QEMU_E500 unset based on the emulated CPU (or actual host CPU in the case of KVM). -if PPC64 - -config T4240_QDS - bool "Freescale T4240 QDS" +config CORENET_GENERIC + bool "Freescale CoreNet Generic" select DEFAULT_UIMAGE select E500 select PPC_E500MC @@ -324,26 +255,14 @@ config T4240_QDS select HAS_RAPIDIO select PPC_EPAPR_HV_PIC help - This option enables support for the T4240 QDS board - -config B4_QDS - bool "Freescale B4 QDS" - select DEFAULT_UIMAGE - select E500 - select PPC_E500MC - select PHYS_64BIT - select SWIOTLB - select GPIOLIB - select ARCH_REQUIRE_GPIOLIB - select HAS_RAPIDIO - select PPC_EPAPR_HV_PIC - help - This option enables support for the B4 QDS board - The B4 application development system B4 QDS is a complete - debugging environment intended for engineers developing - applications for the B4. + This option enables support for the FSL CoreNet based boards. + For 32bit kernel, the following boards are supported: + P2041 RDB, P3041 DS and P4080 DS + For 64bit kernel, the following boards are supported: + T4240 QDS and B4 QDS + The following boards are supported for both 32bit and 64bit kernel: + P5020 DS and P5040 DS -endif endif # FSL_SOC_BOOKE config TQM85xx diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile index 53c9f75a6907..dd4c0b59577b 100644 --- a/arch/powerpc/platforms/85xx/Makefile +++ b/arch/powerpc/platforms/85xx/Makefile @@ -18,13 +18,7 @@ obj-$(CONFIG_P1010_RDB) += p1010rdb.o obj-$(CONFIG_P1022_DS) += p1022_ds.o obj-$(CONFIG_P1022_RDK) += p1022_rdk.o obj-$(CONFIG_P1023_RDS) += p1023_rds.o -obj-$(CONFIG_P2041_RDB) += p2041_rdb.o corenet_ds.o -obj-$(CONFIG_P3041_DS) += p3041_ds.o corenet_ds.o -obj-$(CONFIG_P4080_DS) += p4080_ds.o corenet_ds.o -obj-$(CONFIG_P5020_DS) += p5020_ds.o corenet_ds.o -obj-$(CONFIG_P5040_DS) += p5040_ds.o corenet_ds.o -obj-$(CONFIG_T4240_QDS) += t4240_qds.o corenet_ds.o -obj-$(CONFIG_B4_QDS) += b4_qds.o corenet_ds.o +obj-$(CONFIG_CORENET_GENERIC) += corenet_generic.o obj-$(CONFIG_STX_GP3) += stx_gp3.o obj-$(CONFIG_TQM85xx) += tqm85xx.o obj-$(CONFIG_SBC8548) += sbc8548.o diff --git a/arch/powerpc/platforms/85xx/b4_qds.c b/arch/powerpc/platforms/85xx/b4_qds.c deleted file mode 100644 index 0c6702f8b88e..000000000000 --- a/arch/powerpc/platforms/85xx/b4_qds.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * B4 QDS Setup - * Should apply for QDS platform of B4860 and it's personalities. - * viz B4860/B4420/B4220QDS - * - * Copyright 2012 Freescale Semiconductor Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include <linux/kernel.h> -#include <linux/pci.h> -#include <linux/kdev_t.h> -#include <linux/delay.h> -#include <linux/interrupt.h> -#include <linux/phy.h> - -#include <asm/time.h> -#include <asm/machdep.h> -#include <asm/pci-bridge.h> -#include <mm/mmu_decl.h> -#include <asm/prom.h> -#include <asm/udbg.h> -#include <asm/mpic.h> - -#include <linux/of_platform.h> -#include <sysdev/fsl_soc.h> -#include <sysdev/fsl_pci.h> -#include <asm/ehv_pic.h> - -#include "corenet_ds.h" - -/* - * Called very early, device-tree isn't unflattened - */ -static int __init b4_qds_probe(void) -{ - unsigned long root = of_get_flat_dt_root(); -#ifdef CONFIG_SMP - extern struct smp_ops_t smp_85xx_ops; -#endif - - if ((of_flat_dt_is_compatible(root, "fsl,B4860QDS")) || - (of_flat_dt_is_compatible(root, "fsl,B4420QDS")) || - (of_flat_dt_is_compatible(root, "fsl,B4220QDS"))) - return 1; - - /* Check if we're running under the Freescale hypervisor */ - if ((of_flat_dt_is_compatible(root, "fsl,B4860QDS-hv")) || - (of_flat_dt_is_compatible(root, "fsl,B4420QDS-hv")) || - (of_flat_dt_is_compatible(root, "fsl,B4220QDS-hv"))) { - ppc_md.init_IRQ = ehv_pic_init; - ppc_md.get_irq = ehv_pic_get_irq; - ppc_md.restart = fsl_hv_restart; - ppc_md.power_off = fsl_hv_halt; - ppc_md.halt = fsl_hv_halt; -#ifdef CONFIG_SMP - /* - * Disable the timebase sync operations because we can't write - * to the timebase registers under the hypervisor. - */ - smp_85xx_ops.give_timebase = NULL; - smp_85xx_ops.take_timebase = NULL; -#endif - return 1; - } - - return 0; -} - -define_machine(b4_qds) { - .name = "B4 QDS", - .probe = b4_qds_probe, - .setup_arch = corenet_ds_setup_arch, - .init_IRQ = corenet_ds_pic_init, -#ifdef CONFIG_PCI - .pcibios_fixup_bus = fsl_pcibios_fixup_bus, -#endif -/* coreint doesn't play nice with lazy EE, use legacy mpic for now */ -#ifdef CONFIG_PPC64 - .get_irq = mpic_get_irq, -#else - .get_irq = mpic_get_coreint_irq, -#endif - .restart = fsl_rstcr_restart, - .calibrate_decr = generic_calibrate_decr, - .progress = udbg_progress, -#ifdef CONFIG_PPC64 - .power_save = book3e_idle, -#else - .power_save = e500_idle, -#endif -}; - -machine_arch_initcall(b4_qds, corenet_ds_publish_devices); - -#ifdef CONFIG_SWIOTLB -machine_arch_initcall(b4_qds, swiotlb_setup_bus_notifier); -#endif diff --git a/arch/powerpc/platforms/85xx/c293pcie.c b/arch/powerpc/platforms/85xx/c293pcie.c index 6208e49142bf..213d5b815827 100644 --- a/arch/powerpc/platforms/85xx/c293pcie.c +++ b/arch/powerpc/platforms/85xx/c293pcie.c @@ -11,6 +11,7 @@ #include <linux/stddef.h> #include <linux/kernel.h> +#include <linux/of_fdt.h> #include <linux/of_platform.h> #include <asm/machdep.h> diff --git a/arch/powerpc/platforms/85xx/common.c b/arch/powerpc/platforms/85xx/common.c index d0861a0d8360..eba78c85303f 100644 --- a/arch/powerpc/platforms/85xx/common.c +++ b/arch/powerpc/platforms/85xx/common.c @@ -5,6 +5,8 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ + +#include <linux/of_irq.h> #include <linux/of_platform.h> #include <sysdev/cpm2_pic.h> diff --git a/arch/powerpc/platforms/85xx/corenet_ds.c b/arch/powerpc/platforms/85xx/corenet_ds.c deleted file mode 100644 index aa3690bae415..000000000000 --- a/arch/powerpc/platforms/85xx/corenet_ds.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Corenet based SoC DS Setup - * - * Maintained by Kumar Gala (see MAINTAINERS for contact information) - * - * Copyright 2009-2011 Freescale Semiconductor Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include <linux/kernel.h> -#include <linux/pci.h> -#include <linux/kdev_t.h> -#include <linux/delay.h> -#include <linux/interrupt.h> - -#include <asm/time.h> -#include <asm/machdep.h> -#include <asm/pci-bridge.h> -#include <asm/ppc-pci.h> -#include <mm/mmu_decl.h> -#include <asm/prom.h> -#include <asm/udbg.h> -#include <asm/mpic.h> - -#include <linux/of_platform.h> -#include <sysdev/fsl_soc.h> -#include <sysdev/fsl_pci.h> -#include "smp.h" - -void __init corenet_ds_pic_init(void) -{ - struct mpic *mpic; - unsigned int flags = MPIC_BIG_ENDIAN | MPIC_SINGLE_DEST_CPU | - MPIC_NO_RESET; - - if (ppc_md.get_irq == mpic_get_coreint_irq) - flags |= MPIC_ENABLE_COREINT; - - mpic = mpic_alloc(NULL, 0, flags, 0, 512, " OpenPIC "); - BUG_ON(mpic == NULL); - - mpic_init(mpic); -} - -/* - * Setup the architecture - */ -void __init corenet_ds_setup_arch(void) -{ - mpc85xx_smp_init(); - - swiotlb_detect_4g(); - - pr_info("%s board from Freescale Semiconductor\n", ppc_md.name); -} - -static const struct of_device_id of_device_ids[] = { - { - .compatible = "simple-bus" - }, - { - .compatible = "fsl,srio", - }, - { - .compatible = "fsl,p4080-pcie", - }, - { - .compatible = "fsl,qoriq-pcie-v2.2", - }, - { - .compatible = "fsl,qoriq-pcie-v2.3", - }, - { - .compatible = "fsl,qoriq-pcie-v2.4", - }, - { - .compatible = "fsl,qoriq-pcie-v3.0", - }, - /* The following two are for the Freescale hypervisor */ - { - .name = "hypervisor", - }, - { - .name = "handles", - }, - {} -}; - -int __init corenet_ds_publish_devices(void) -{ - return of_platform_bus_probe(NULL, of_device_ids, NULL); -} diff --git a/arch/powerpc/platforms/85xx/corenet_ds.h b/arch/powerpc/platforms/85xx/corenet_ds.h deleted file mode 100644 index ddd700b23031..000000000000 --- a/arch/powerpc/platforms/85xx/corenet_ds.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Corenet based SoC DS Setup - * - * Copyright 2009 Freescale Semiconductor Inc. - * - * 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 CORENET_DS_H -#define CORENET_DS_H - -extern void __init corenet_ds_pic_init(void); -extern void __init corenet_ds_setup_arch(void); -extern int __init corenet_ds_publish_devices(void); - -#endif diff --git a/arch/powerpc/platforms/85xx/corenet_generic.c b/arch/powerpc/platforms/85xx/corenet_generic.c new file mode 100644 index 000000000000..fbd871e69754 --- /dev/null +++ b/arch/powerpc/platforms/85xx/corenet_generic.c @@ -0,0 +1,182 @@ +/* + * Corenet based SoC DS Setup + * + * Maintained by Kumar Gala (see MAINTAINERS for contact information) + * + * Copyright 2009-2011 Freescale Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/kdev_t.h> +#include <linux/delay.h> +#include <linux/interrupt.h> + +#include <asm/time.h> +#include <asm/machdep.h> +#include <asm/pci-bridge.h> +#include <asm/ppc-pci.h> +#include <mm/mmu_decl.h> +#include <asm/prom.h> +#include <asm/udbg.h> +#include <asm/mpic.h> +#include <asm/ehv_pic.h> + +#include <linux/of_platform.h> +#include <sysdev/fsl_soc.h> +#include <sysdev/fsl_pci.h> +#include "smp.h" + +void __init corenet_gen_pic_init(void) +{ + struct mpic *mpic; + unsigned int flags = MPIC_BIG_ENDIAN | MPIC_SINGLE_DEST_CPU | + MPIC_NO_RESET; + + if (ppc_md.get_irq == mpic_get_coreint_irq) + flags |= MPIC_ENABLE_COREINT; + + mpic = mpic_alloc(NULL, 0, flags, 0, 512, " OpenPIC "); + BUG_ON(mpic == NULL); + + mpic_init(mpic); +} + +/* + * Setup the architecture + */ +void __init corenet_gen_setup_arch(void) +{ + mpc85xx_smp_init(); + + swiotlb_detect_4g(); + + pr_info("%s board from Freescale Semiconductor\n", ppc_md.name); +} + +static const struct of_device_id of_device_ids[] = { + { + .compatible = "simple-bus" + }, + { + .compatible = "fsl,srio", + }, + { + .compatible = "fsl,p4080-pcie", + }, + { + .compatible = "fsl,qoriq-pcie-v2.2", + }, + { + .compatible = "fsl,qoriq-pcie-v2.3", + }, + { + .compatible = "fsl,qoriq-pcie-v2.4", + }, + { + .compatible = "fsl,qoriq-pcie-v3.0", + }, + /* The following two are for the Freescale hypervisor */ + { + .name = "hypervisor", + }, + { + .name = "handles", + }, + {} +}; + +int __init corenet_gen_publish_devices(void) +{ + return of_platform_bus_probe(NULL, of_device_ids, NULL); +} + +static const char * const boards[] __initconst = { + "fsl,P2041RDB", + "fsl,P3041DS", + "fsl,P4080DS", + "fsl,P5020DS", + "fsl,P5040DS", + "fsl,T4240QDS", + "fsl,B4860QDS", + "fsl,B4420QDS", + "fsl,B4220QDS", + NULL +}; + +static const char * const hv_boards[] __initconst = { + "fsl,P2041RDB-hv", + "fsl,P3041DS-hv", + "fsl,P4080DS-hv", + "fsl,P5020DS-hv", + "fsl,P5040DS-hv", + "fsl,T4240QDS-hv", + "fsl,B4860QDS-hv", + "fsl,B4420QDS-hv", + "fsl,B4220QDS-hv", + NULL +}; + +/* + * Called very early, device-tree isn't unflattened + */ +static int __init corenet_generic_probe(void) +{ + unsigned long root = of_get_flat_dt_root(); +#ifdef CONFIG_SMP + extern struct smp_ops_t smp_85xx_ops; +#endif + + if (of_flat_dt_match(root, boards)) + return 1; + + /* Check if we're running under the Freescale hypervisor */ + if (of_flat_dt_match(root, hv_boards)) { + ppc_md.init_IRQ = ehv_pic_init; + ppc_md.get_irq = ehv_pic_get_irq; + ppc_md.restart = fsl_hv_restart; + ppc_md.power_off = fsl_hv_halt; + ppc_md.halt = fsl_hv_halt; +#ifdef CONFIG_SMP + /* + * Disable the timebase sync operations because we can't write + * to the timebase registers under the hypervisor. + */ + smp_85xx_ops.give_timebase = NULL; + smp_85xx_ops.take_timebase = NULL; +#endif + return 1; + } + + return 0; +} + +define_machine(corenet_generic) { + .name = "CoreNet Generic", + .probe = corenet_generic_probe, + .setup_arch = corenet_gen_setup_arch, + .init_IRQ = corenet_gen_pic_init, +#ifdef CONFIG_PCI + .pcibios_fixup_bus = fsl_pcibios_fixup_bus, +#endif + .get_irq = mpic_get_coreint_irq, + .restart = fsl_rstcr_restart, + .calibrate_decr = generic_calibrate_decr, + .progress = udbg_progress, +#ifdef CONFIG_PPC64 + .power_save = book3e_idle, +#else + .power_save = e500_idle, +#endif +}; + +machine_arch_initcall(corenet_generic, corenet_gen_publish_devices); + +#ifdef CONFIG_SWIOTLB +machine_arch_initcall(corenet_generic, swiotlb_setup_bus_notifier); +#endif diff --git a/arch/powerpc/platforms/85xx/p1010rdb.c b/arch/powerpc/platforms/85xx/p1010rdb.c index 0252961392d5..d6a3dd311494 100644 --- a/arch/powerpc/platforms/85xx/p1010rdb.c +++ b/arch/powerpc/platforms/85xx/p1010rdb.c @@ -66,6 +66,8 @@ static int __init p1010_rdb_probe(void) if (of_flat_dt_is_compatible(root, "fsl,P1010RDB")) return 1; + if (of_flat_dt_is_compatible(root, "fsl,P1010RDB-PB")) + return 1; return 0; } diff --git a/arch/powerpc/platforms/85xx/p2041_rdb.c b/arch/powerpc/platforms/85xx/p2041_rdb.c deleted file mode 100644 index 000c0892fc40..000000000000 --- a/arch/powerpc/platforms/85xx/p2041_rdb.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * P2041 RDB Setup - * - * Copyright 2011 Freescale Semiconductor Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include <linux/kernel.h> -#include <linux/pci.h> -#include <linux/kdev_t.h> -#include <linux/delay.h> -#include <linux/interrupt.h> -#include <linux/phy.h> - -#include <asm/time.h> -#include <asm/machdep.h> -#include <asm/pci-bridge.h> -#include <mm/mmu_decl.h> -#include <asm/prom.h> -#include <asm/udbg.h> -#include <asm/mpic.h> - -#include <linux/of_platform.h> -#include <sysdev/fsl_soc.h> -#include <sysdev/fsl_pci.h> -#include <asm/ehv_pic.h> - -#include "corenet_ds.h" - -/* - * Called very early, device-tree isn't unflattened - */ -static int __init p2041_rdb_probe(void) -{ - unsigned long root = of_get_flat_dt_root(); -#ifdef CONFIG_SMP - extern struct smp_ops_t smp_85xx_ops; -#endif - - if (of_flat_dt_is_compatible(root, "fsl,P2041RDB")) - return 1; - - /* Check if we're running under the Freescale hypervisor */ - if (of_flat_dt_is_compatible(root, "fsl,P2041RDB-hv")) { - ppc_md.init_IRQ = ehv_pic_init; - ppc_md.get_irq = ehv_pic_get_irq; - ppc_md.restart = fsl_hv_restart; - ppc_md.power_off = fsl_hv_halt; - ppc_md.halt = fsl_hv_halt; -#ifdef CONFIG_SMP - /* - * Disable the timebase sync operations because we can't write - * to the timebase registers under the hypervisor. - */ - smp_85xx_ops.give_timebase = NULL; - smp_85xx_ops.take_timebase = NULL; -#endif - return 1; - } - - return 0; -} - -define_machine(p2041_rdb) { - .name = "P2041 RDB", - .probe = p2041_rdb_probe, - .setup_arch = corenet_ds_setup_arch, - .init_IRQ = corenet_ds_pic_init, -#ifdef CONFIG_PCI - .pcibios_fixup_bus = fsl_pcibios_fixup_bus, -#endif - .get_irq = mpic_get_coreint_irq, - .restart = fsl_rstcr_restart, - .calibrate_decr = generic_calibrate_decr, - .progress = udbg_progress, - .power_save = e500_idle, -}; - -machine_arch_initcall(p2041_rdb, corenet_ds_publish_devices); - -#ifdef CONFIG_SWIOTLB -machine_arch_initcall(p2041_rdb, swiotlb_setup_bus_notifier); -#endif diff --git a/arch/powerpc/platforms/85xx/p3041_ds.c b/arch/powerpc/platforms/85xx/p3041_ds.c deleted file mode 100644 index b3edc205daa9..000000000000 --- a/arch/powerpc/platforms/85xx/p3041_ds.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * P3041 DS Setup - * - * Maintained by Kumar Gala (see MAINTAINERS for contact information) - * - * Copyright 2009-2010 Freescale Semiconductor Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include <linux/kernel.h> -#include <linux/pci.h> -#include <linux/kdev_t.h> -#include <linux/delay.h> -#include <linux/interrupt.h> -#include <linux/phy.h> - -#include <asm/time.h> -#include <asm/machdep.h> -#include <asm/pci-bridge.h> -#include <mm/mmu_decl.h> -#include <asm/prom.h> -#include <asm/udbg.h> -#include <asm/mpic.h> - -#include <linux/of_platform.h> -#include <sysdev/fsl_soc.h> -#include <sysdev/fsl_pci.h> -#include <asm/ehv_pic.h> - -#include "corenet_ds.h" - -/* - * Called very early, device-tree isn't unflattened - */ -static int __init p3041_ds_probe(void) -{ - unsigned long root = of_get_flat_dt_root(); -#ifdef CONFIG_SMP - extern struct smp_ops_t smp_85xx_ops; -#endif - - if (of_flat_dt_is_compatible(root, "fsl,P3041DS")) - return 1; - - /* Check if we're running under the Freescale hypervisor */ - if (of_flat_dt_is_compatible(root, "fsl,P3041DS-hv")) { - ppc_md.init_IRQ = ehv_pic_init; - ppc_md.get_irq = ehv_pic_get_irq; - ppc_md.restart = fsl_hv_restart; - ppc_md.power_off = fsl_hv_halt; - ppc_md.halt = fsl_hv_halt; -#ifdef CONFIG_SMP - /* - * Disable the timebase sync operations because we can't write - * to the timebase registers under the hypervisor. - */ - smp_85xx_ops.give_timebase = NULL; - smp_85xx_ops.take_timebase = NULL; -#endif - return 1; - } - - return 0; -} - -define_machine(p3041_ds) { - .name = "P3041 DS", - .probe = p3041_ds_probe, - .setup_arch = corenet_ds_setup_arch, - .init_IRQ = corenet_ds_pic_init, -#ifdef CONFIG_PCI - .pcibios_fixup_bus = fsl_pcibios_fixup_bus, -#endif - .get_irq = mpic_get_coreint_irq, - .restart = fsl_rstcr_restart, - .calibrate_decr = generic_calibrate_decr, - .progress = udbg_progress, - .power_save = e500_idle, -}; - -machine_arch_initcall(p3041_ds, corenet_ds_publish_devices); - -#ifdef CONFIG_SWIOTLB -machine_arch_initcall(p3041_ds, swiotlb_setup_bus_notifier); -#endif diff --git a/arch/powerpc/platforms/85xx/p4080_ds.c b/arch/powerpc/platforms/85xx/p4080_ds.c deleted file mode 100644 index 54df10632aea..000000000000 --- a/arch/powerpc/platforms/85xx/p4080_ds.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * P4080 DS Setup - * - * Maintained by Kumar Gala (see MAINTAINERS for contact information) - * - * Copyright 2009 Freescale Semiconductor Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include <linux/kernel.h> -#include <linux/pci.h> -#include <linux/kdev_t.h> -#include <linux/delay.h> -#include <linux/interrupt.h> - -#include <asm/time.h> -#include <asm/machdep.h> -#include <asm/pci-bridge.h> -#include <mm/mmu_decl.h> -#include <asm/prom.h> -#include <asm/udbg.h> -#include <asm/mpic.h> - -#include <linux/of_platform.h> -#include <sysdev/fsl_soc.h> -#include <sysdev/fsl_pci.h> -#include <asm/ehv_pic.h> - -#include "corenet_ds.h" - -/* - * Called very early, device-tree isn't unflattened - */ -static int __init p4080_ds_probe(void) -{ - unsigned long root = of_get_flat_dt_root(); -#ifdef CONFIG_SMP - extern struct smp_ops_t smp_85xx_ops; -#endif - - if (of_flat_dt_is_compatible(root, "fsl,P4080DS")) - return 1; - - /* Check if we're running under the Freescale hypervisor */ - if (of_flat_dt_is_compatible(root, "fsl,P4080DS-hv")) { - ppc_md.init_IRQ = ehv_pic_init; - ppc_md.get_irq = ehv_pic_get_irq; - ppc_md.restart = fsl_hv_restart; - ppc_md.power_off = fsl_hv_halt; - ppc_md.halt = fsl_hv_halt; -#ifdef CONFIG_SMP - /* - * Disable the timebase sync operations because we can't write - * to the timebase registers under the hypervisor. - */ - smp_85xx_ops.give_timebase = NULL; - smp_85xx_ops.take_timebase = NULL; -#endif - return 1; - } - - return 0; -} - -define_machine(p4080_ds) { - .name = "P4080 DS", - .probe = p4080_ds_probe, - .setup_arch = corenet_ds_setup_arch, - .init_IRQ = corenet_ds_pic_init, -#ifdef CONFIG_PCI - .pcibios_fixup_bus = fsl_pcibios_fixup_bus, -#endif - .get_irq = mpic_get_coreint_irq, - .restart = fsl_rstcr_restart, - .calibrate_decr = generic_calibrate_decr, - .progress = udbg_progress, - .power_save = e500_idle, -}; - -machine_arch_initcall(p4080_ds, corenet_ds_publish_devices); -#ifdef CONFIG_SWIOTLB -machine_arch_initcall(p4080_ds, swiotlb_setup_bus_notifier); -#endif diff --git a/arch/powerpc/platforms/85xx/p5020_ds.c b/arch/powerpc/platforms/85xx/p5020_ds.c deleted file mode 100644 index 39cfa4044e6c..000000000000 --- a/arch/powerpc/platforms/85xx/p5020_ds.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * P5020 DS Setup - * - * Maintained by Kumar Gala (see MAINTAINERS for contact information) - * - * Copyright 2009-2010 Freescale Semiconductor Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include <linux/kernel.h> -#include <linux/pci.h> -#include <linux/kdev_t.h> -#include <linux/delay.h> -#include <linux/interrupt.h> -#include <linux/phy.h> - -#include <asm/time.h> -#include <asm/machdep.h> -#include <asm/pci-bridge.h> -#include <mm/mmu_decl.h> -#include <asm/prom.h> -#include <asm/udbg.h> -#include <asm/mpic.h> - -#include <linux/of_platform.h> -#include <sysdev/fsl_soc.h> -#include <sysdev/fsl_pci.h> -#include <asm/ehv_pic.h> - -#include "corenet_ds.h" - -/* - * Called very early, device-tree isn't unflattened - */ -static int __init p5020_ds_probe(void) -{ - unsigned long root = of_get_flat_dt_root(); -#ifdef CONFIG_SMP - extern struct smp_ops_t smp_85xx_ops; -#endif - - if (of_flat_dt_is_compatible(root, "fsl,P5020DS")) - return 1; - - /* Check if we're running under the Freescale hypervisor */ - if (of_flat_dt_is_compatible(root, "fsl,P5020DS-hv")) { - ppc_md.init_IRQ = ehv_pic_init; - ppc_md.get_irq = ehv_pic_get_irq; - ppc_md.restart = fsl_hv_restart; - ppc_md.power_off = fsl_hv_halt; - ppc_md.halt = fsl_hv_halt; -#ifdef CONFIG_SMP - /* - * Disable the timebase sync operations because we can't write - * to the timebase registers under the hypervisor. - */ - smp_85xx_ops.give_timebase = NULL; - smp_85xx_ops.take_timebase = NULL; -#endif - return 1; - } - - return 0; -} - -define_machine(p5020_ds) { - .name = "P5020 DS", - .probe = p5020_ds_probe, - .setup_arch = corenet_ds_setup_arch, - .init_IRQ = corenet_ds_pic_init, -#ifdef CONFIG_PCI - .pcibios_fixup_bus = fsl_pcibios_fixup_bus, -#endif - .get_irq = mpic_get_coreint_irq, - .restart = fsl_rstcr_restart, - .calibrate_decr = generic_calibrate_decr, - .progress = udbg_progress, -#ifdef CONFIG_PPC64 - .power_save = book3e_idle, -#else - .power_save = e500_idle, -#endif -}; - -machine_arch_initcall(p5020_ds, corenet_ds_publish_devices); - -#ifdef CONFIG_SWIOTLB -machine_arch_initcall(p5020_ds, swiotlb_setup_bus_notifier); -#endif diff --git a/arch/powerpc/platforms/85xx/p5040_ds.c b/arch/powerpc/platforms/85xx/p5040_ds.c deleted file mode 100644 index f70e74cddf97..000000000000 --- a/arch/powerpc/platforms/85xx/p5040_ds.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * P5040 DS Setup - * - * Copyright 2009-2010 Freescale Semiconductor Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include <linux/kernel.h> -#include <linux/pci.h> - -#include <asm/machdep.h> -#include <asm/udbg.h> -#include <asm/mpic.h> - -#include <linux/of_fdt.h> - -#include <sysdev/fsl_soc.h> -#include <sysdev/fsl_pci.h> -#include <asm/ehv_pic.h> - -#include "corenet_ds.h" - -/* - * Called very early, device-tree isn't unflattened - */ -static int __init p5040_ds_probe(void) -{ - unsigned long root = of_get_flat_dt_root(); -#ifdef CONFIG_SMP - extern struct smp_ops_t smp_85xx_ops; -#endif - - if (of_flat_dt_is_compatible(root, "fsl,P5040DS")) - return 1; - - /* Check if we're running under the Freescale hypervisor */ - if (of_flat_dt_is_compatible(root, "fsl,P5040DS-hv")) { - ppc_md.init_IRQ = ehv_pic_init; - ppc_md.get_irq = ehv_pic_get_irq; - ppc_md.restart = fsl_hv_restart; - ppc_md.power_off = fsl_hv_halt; - ppc_md.halt = fsl_hv_halt; -#ifdef CONFIG_SMP - /* - * Disable the timebase sync operations because we can't write - * to the timebase registers under the hypervisor. - */ - smp_85xx_ops.give_timebase = NULL; - smp_85xx_ops.take_timebase = NULL; -#endif - return 1; - } - - return 0; -} - -define_machine(p5040_ds) { - .name = "P5040 DS", - .probe = p5040_ds_probe, - .setup_arch = corenet_ds_setup_arch, - .init_IRQ = corenet_ds_pic_init, -#ifdef CONFIG_PCI - .pcibios_fixup_bus = fsl_pcibios_fixup_bus, -#endif - .get_irq = mpic_get_coreint_irq, - .restart = fsl_rstcr_restart, - .calibrate_decr = generic_calibrate_decr, - .progress = udbg_progress, -#ifdef CONFIG_PPC64 - .power_save = book3e_idle, -#else - .power_save = e500_idle, -#endif -}; - -machine_arch_initcall(p5040_ds, corenet_ds_publish_devices); - -#ifdef CONFIG_SWIOTLB -machine_arch_initcall(p5040_ds, swiotlb_setup_bus_notifier); -#endif diff --git a/arch/powerpc/platforms/85xx/ppa8548.c b/arch/powerpc/platforms/85xx/ppa8548.c index 6a7704b92c3b..3daff7c63569 100644 --- a/arch/powerpc/platforms/85xx/ppa8548.c +++ b/arch/powerpc/platforms/85xx/ppa8548.c @@ -19,6 +19,7 @@ #include <linux/init.h> #include <linux/reboot.h> #include <linux/seq_file.h> +#include <linux/of_fdt.h> #include <linux/of_platform.h> #include <asm/machdep.h> diff --git a/arch/powerpc/platforms/85xx/sgy_cts1000.c b/arch/powerpc/platforms/85xx/sgy_cts1000.c index 7179726ba5c5..b9197cea1854 100644 --- a/arch/powerpc/platforms/85xx/sgy_cts1000.c +++ b/arch/powerpc/platforms/85xx/sgy_cts1000.c @@ -16,6 +16,7 @@ #include <linux/module.h> #include <linux/init.h> #include <linux/of_gpio.h> +#include <linux/of_irq.h> #include <linux/workqueue.h> #include <linux/reboot.h> #include <linux/interrupt.h> diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index 281b7f01df63..393f975ab397 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -15,6 +15,7 @@ #include <linux/init.h> #include <linux/delay.h> #include <linux/of.h> +#include <linux/of_address.h> #include <linux/kexec.h> #include <linux/highmem.h> #include <linux/cpu.h> diff --git a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c index 3bbbf7489487..55a9682b9529 100644 --- a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c +++ b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c @@ -9,6 +9,8 @@ */ #include <linux/irq.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> #include <linux/of_platform.h> #include <linux/io.h> diff --git a/arch/powerpc/platforms/85xx/t4240_qds.c b/arch/powerpc/platforms/85xx/t4240_qds.c deleted file mode 100644 index 91ead6b1b8af..000000000000 --- a/arch/powerpc/platforms/85xx/t4240_qds.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * T4240 QDS Setup - * - * Maintained by Kumar Gala (see MAINTAINERS for contact information) - * - * Copyright 2012 Freescale Semiconductor Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include <linux/kernel.h> -#include <linux/pci.h> -#include <linux/kdev_t.h> -#include <linux/delay.h> -#include <linux/interrupt.h> -#include <linux/phy.h> - -#include <asm/time.h> -#include <asm/machdep.h> -#include <asm/pci-bridge.h> -#include <mm/mmu_decl.h> -#include <asm/prom.h> -#include <asm/udbg.h> -#include <asm/mpic.h> - -#include <linux/of_platform.h> -#include <sysdev/fsl_soc.h> -#include <sysdev/fsl_pci.h> -#include <asm/ehv_pic.h> - -#include "corenet_ds.h" - -/* - * Called very early, device-tree isn't unflattened - */ -static int __init t4240_qds_probe(void) -{ - unsigned long root = of_get_flat_dt_root(); -#ifdef CONFIG_SMP - extern struct smp_ops_t smp_85xx_ops; -#endif - - if (of_flat_dt_is_compatible(root, "fsl,T4240QDS")) - return 1; - - /* Check if we're running under the Freescale hypervisor */ - if (of_flat_dt_is_compatible(root, "fsl,T4240QDS-hv")) { - ppc_md.init_IRQ = ehv_pic_init; - ppc_md.get_irq = ehv_pic_get_irq; - ppc_md.restart = fsl_hv_restart; - ppc_md.power_off = fsl_hv_halt; - ppc_md.halt = fsl_hv_halt; -#ifdef CONFIG_SMP - /* - * Disable the timebase sync operations because we can't write - * to the timebase registers under the hypervisor. - */ - smp_85xx_ops.give_timebase = NULL; - smp_85xx_ops.take_timebase = NULL; -#endif - return 1; - } - - return 0; -} - -define_machine(t4240_qds) { - .name = "T4240 QDS", - .probe = t4240_qds_probe, - .setup_arch = corenet_ds_setup_arch, - .init_IRQ = corenet_ds_pic_init, -#ifdef CONFIG_PCI - .pcibios_fixup_bus = fsl_pcibios_fixup_bus, -#endif - .get_irq = mpic_get_coreint_irq, - .restart = fsl_rstcr_restart, - .calibrate_decr = generic_calibrate_decr, - .progress = udbg_progress, -#ifdef CONFIG_PPC64 - .power_save = book3e_idle, -#else - .power_save = e500_idle, -#endif -}; - -machine_arch_initcall(t4240_qds, corenet_ds_publish_devices); - -#ifdef CONFIG_SWIOTLB -machine_arch_initcall(t4240_qds, swiotlb_setup_bus_notifier); -#endif diff --git a/arch/powerpc/platforms/86xx/pic.c b/arch/powerpc/platforms/86xx/pic.c index 9982f57c98b9..d5b98c0f958a 100644 --- a/arch/powerpc/platforms/86xx/pic.c +++ b/arch/powerpc/platforms/86xx/pic.c @@ -10,6 +10,7 @@ #include <linux/stddef.h> #include <linux/kernel.h> #include <linux/interrupt.h> +#include <linux/of_irq.h> #include <linux/of_platform.h> #include <asm/mpic.h> diff --git a/arch/powerpc/platforms/8xx/ep88xc.c b/arch/powerpc/platforms/8xx/ep88xc.c index 7d9ac6040d63..e62166681d08 100644 --- a/arch/powerpc/platforms/8xx/ep88xc.c +++ b/arch/powerpc/platforms/8xx/ep88xc.c @@ -10,6 +10,8 @@ */ #include <linux/init.h> +#include <linux/of_address.h> +#include <linux/of_fdt.h> #include <linux/of_platform.h> #include <asm/machdep.h> diff --git a/arch/powerpc/platforms/8xx/mpc86xads_setup.c b/arch/powerpc/platforms/8xx/mpc86xads_setup.c index 866feff83c91..63084640c5c5 100644 --- a/arch/powerpc/platforms/8xx/mpc86xads_setup.c +++ b/arch/powerpc/platforms/8xx/mpc86xads_setup.c @@ -15,6 +15,8 @@ */ #include <linux/init.h> +#include <linux/of_address.h> +#include <linux/of_fdt.h> #include <linux/of_platform.h> #include <asm/io.h> diff --git a/arch/powerpc/platforms/8xx/mpc885ads_setup.c b/arch/powerpc/platforms/8xx/mpc885ads_setup.c index 5d98398c2f5e..c1262581b63c 100644 --- a/arch/powerpc/platforms/8xx/mpc885ads_setup.c +++ b/arch/powerpc/platforms/8xx/mpc885ads_setup.c @@ -25,6 +25,8 @@ #include <linux/fs_uart_pd.h> #include <linux/fsl_devices.h> #include <linux/mii.h> +#include <linux/of_address.h> +#include <linux/of_fdt.h> #include <linux/of_platform.h> #include <asm/delay.h> diff --git a/arch/powerpc/platforms/8xx/tqm8xx_setup.c b/arch/powerpc/platforms/8xx/tqm8xx_setup.c index 8d21ab70e06c..251aba8759e4 100644 --- a/arch/powerpc/platforms/8xx/tqm8xx_setup.c +++ b/arch/powerpc/platforms/8xx/tqm8xx_setup.c @@ -28,6 +28,7 @@ #include <linux/fs_uart_pd.h> #include <linux/fsl_devices.h> #include <linux/mii.h> +#include <linux/of_fdt.h> #include <linux/of_platform.h> #include <asm/delay.h> @@ -48,7 +49,7 @@ struct cpm_pin { int port, pin, flags; }; -static struct __initdata cpm_pin tqm8xx_pins[] = { +static struct cpm_pin tqm8xx_pins[] __initdata = { /* SMC1 */ {CPM_PORTB, 24, CPM_PIN_INPUT}, /* RX */ {CPM_PORTB, 25, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* TX */ @@ -63,7 +64,7 @@ static struct __initdata cpm_pin tqm8xx_pins[] = { {CPM_PORTC, 11, CPM_PIN_INPUT | CPM_PIN_SECONDARY | CPM_PIN_GPIO}, }; -static struct __initdata cpm_pin tqm8xx_fec_pins[] = { +static struct cpm_pin tqm8xx_fec_pins[] __initdata = { /* MII */ {CPM_PORTD, 3, CPM_PIN_OUTPUT}, {CPM_PORTD, 4, CPM_PIN_OUTPUT}, diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype index 6704e2e20e6b..c2a566fb8bb8 100644 --- a/arch/powerpc/platforms/Kconfig.cputype +++ b/arch/powerpc/platforms/Kconfig.cputype @@ -93,22 +93,23 @@ choice config GENERIC_CPU bool "Generic" + depends on !CPU_LITTLE_ENDIAN config CELL_CPU bool "Cell Broadband Engine" - depends on PPC_BOOK3S_64 + depends on PPC_BOOK3S_64 && !CPU_LITTLE_ENDIAN config POWER4_CPU bool "POWER4" - depends on PPC_BOOK3S_64 + depends on PPC_BOOK3S_64 && !CPU_LITTLE_ENDIAN config POWER5_CPU bool "POWER5" - depends on PPC_BOOK3S_64 + depends on PPC_BOOK3S_64 && !CPU_LITTLE_ENDIAN config POWER6_CPU bool "POWER6" - depends on PPC_BOOK3S_64 + depends on PPC_BOOK3S_64 && !CPU_LITTLE_ENDIAN config POWER7_CPU bool "POWER7" diff --git a/arch/powerpc/platforms/cell/celleb_scc_pciex.c b/arch/powerpc/platforms/cell/celleb_scc_pciex.c index 14be2bd358b8..4278acfa2ede 100644 --- a/arch/powerpc/platforms/cell/celleb_scc_pciex.c +++ b/arch/powerpc/platforms/cell/celleb_scc_pciex.c @@ -486,7 +486,6 @@ static __init int celleb_setup_pciex(struct device_node *node, struct pci_controller *phb) { struct resource r; - struct of_irq oirq; int virq; /* SMMIO registers; used inside this file */ @@ -507,12 +506,11 @@ static __init int celleb_setup_pciex(struct device_node *node, phb->ops = &scc_pciex_pci_ops; /* internal interrupt handler */ - if (of_irq_map_one(node, 1, &oirq)) { + virq = irq_of_parse_and_map(node, 1); + if (!virq) { pr_err("PCIEXC:Failed to map irq\n"); goto error; } - virq = irq_create_of_mapping(oirq.controller, oirq.specifier, - oirq.size); if (request_irq(virq, pciex_handle_internal_irq, 0, "pciex", (void *)phb)) { pr_err("PCIEXC:Failed to request irq\n"); diff --git a/arch/powerpc/platforms/cell/celleb_scc_sio.c b/arch/powerpc/platforms/cell/celleb_scc_sio.c index 9c339ec646f5..c8eb57193826 100644 --- a/arch/powerpc/platforms/cell/celleb_scc_sio.c +++ b/arch/powerpc/platforms/cell/celleb_scc_sio.c @@ -45,7 +45,7 @@ static int __init txx9_serial_init(void) struct device_node *node; int i; struct uart_port req; - struct of_irq irq; + struct of_phandle_args irq; struct resource res; for_each_compatible_node(node, "serial", "toshiba,sio-scc") { @@ -53,7 +53,7 @@ static int __init txx9_serial_init(void) if (!(txx9_serial_bitmap & (1<<i))) continue; - if (of_irq_map_one(node, i, &irq)) + if (of_irq_parse_one(node, i, &irq)) continue; if (of_address_to_resource(node, txx9_scc_tab[i].index, &res)) @@ -66,8 +66,7 @@ static int __init txx9_serial_init(void) #ifdef CONFIG_SERIAL_TXX9_CONSOLE req.membase = ioremap(req.mapbase, 0x24); #endif - req.irq = irq_create_of_mapping(irq.controller, - irq.specifier, irq.size); + req.irq = irq_create_of_mapping(&irq); req.flags |= UPF_IOREMAP | UPF_BUGGY_UART /*HAVE_CTS_LINE*/; req.uartclk = 83300000; diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c index 8e299447127e..1f72f4ab6353 100644 --- a/arch/powerpc/platforms/cell/spider-pic.c +++ b/arch/powerpc/platforms/cell/spider-pic.c @@ -235,12 +235,9 @@ static unsigned int __init spider_find_cascade_and_node(struct spider_pic *pic) /* First, we check whether we have a real "interrupts" in the device * tree in case the device-tree is ever fixed */ - struct of_irq oirq; - if (of_irq_map_one(pic->host->of_node, 0, &oirq) == 0) { - virq = irq_create_of_mapping(oirq.controller, oirq.specifier, - oirq.size); + virq = irq_of_parse_and_map(pic->host->of_node, 0); + if (virq) return virq; - } /* Now do the horrible hacks */ tmp = of_get_property(pic->host->of_node, "#interrupt-cells", NULL); diff --git a/arch/powerpc/platforms/cell/spu_manage.c b/arch/powerpc/platforms/cell/spu_manage.c index 2bb6977c0a5a..c3327f3d8cf7 100644 --- a/arch/powerpc/platforms/cell/spu_manage.c +++ b/arch/powerpc/platforms/cell/spu_manage.c @@ -177,21 +177,20 @@ out: static int __init spu_map_interrupts(struct spu *spu, struct device_node *np) { - struct of_irq oirq; + struct of_phandle_args oirq; int ret; int i; for (i=0; i < 3; i++) { - ret = of_irq_map_one(np, i, &oirq); + ret = of_irq_parse_one(np, i, &oirq); if (ret) { pr_debug("spu_new: failed to get irq %d\n", i); goto err; } ret = -EINVAL; - pr_debug(" irq %d no 0x%x on %s\n", i, oirq.specifier[0], - oirq.controller->full_name); - spu->irqs[i] = irq_create_of_mapping(oirq.controller, - oirq.specifier, oirq.size); + pr_debug(" irq %d no 0x%x on %s\n", i, oirq.args[0], + oirq.np->full_name); + spu->irqs[i] = irq_create_of_mapping(&oirq); if (spu->irqs[i] == NO_IRQ) { pr_debug("spu_new: failed to map it !\n"); goto err; @@ -200,7 +199,7 @@ static int __init spu_map_interrupts(struct spu *spu, struct device_node *np) return 0; err: - pr_debug("failed to map irq %x for spu %s\n", *oirq.specifier, + pr_debug("failed to map irq %x for spu %s\n", *oirq.args, spu->name); for (; i >= 0; i--) { if (spu->irqs[i] != NO_IRQ) diff --git a/arch/powerpc/platforms/cell/spu_syscalls.c b/arch/powerpc/platforms/cell/spu_syscalls.c index db4e638cf408..3844f1397fc3 100644 --- a/arch/powerpc/platforms/cell/spu_syscalls.c +++ b/arch/powerpc/platforms/cell/spu_syscalls.c @@ -25,6 +25,7 @@ #include <linux/module.h> #include <linux/syscalls.h> #include <linux/rcupdate.h> +#include <linux/binfmts.h> #include <asm/spu.h> @@ -126,7 +127,7 @@ int elf_coredump_extra_notes_size(void) return ret; } -int elf_coredump_extra_notes_write(struct file *file, loff_t *foffset) +int elf_coredump_extra_notes_write(struct coredump_params *cprm) { struct spufs_calls *calls; int ret; @@ -135,7 +136,7 @@ int elf_coredump_extra_notes_write(struct file *file, loff_t *foffset) if (!calls) return 0; - ret = calls->coredump_extra_notes_write(file, foffset); + ret = calls->coredump_extra_notes_write(cprm); spufs_calls_put(calls); diff --git a/arch/powerpc/platforms/cell/spufs/coredump.c b/arch/powerpc/platforms/cell/spufs/coredump.c index c9500ea7be2f..be6212ddbf06 100644 --- a/arch/powerpc/platforms/cell/spufs/coredump.c +++ b/arch/powerpc/platforms/cell/spufs/coredump.c @@ -27,6 +27,8 @@ #include <linux/gfp.h> #include <linux/list.h> #include <linux/syscalls.h> +#include <linux/coredump.h> +#include <linux/binfmts.h> #include <asm/uaccess.h> @@ -48,44 +50,6 @@ static ssize_t do_coredump_read(int num, struct spu_context *ctx, void *buffer, return ++ret; /* count trailing NULL */ } -/* - * These are the only things you should do on a core-file: use only these - * functions to write out all the necessary info. - */ -static int spufs_dump_write(struct file *file, const void *addr, int nr, loff_t *foffset) -{ - unsigned long limit = rlimit(RLIMIT_CORE); - ssize_t written; - - if (*foffset + nr > limit) - return -EIO; - - written = file->f_op->write(file, addr, nr, &file->f_pos); - *foffset += written; - - if (written != nr) - return -EIO; - - return 0; -} - -static int spufs_dump_align(struct file *file, char *buf, loff_t new_off, - loff_t *foffset) -{ - int rc, size; - - size = min((loff_t)PAGE_SIZE, new_off - *foffset); - memset(buf, 0, size); - - rc = 0; - while (rc == 0 && new_off > *foffset) { - size = min((loff_t)PAGE_SIZE, new_off - *foffset); - rc = spufs_dump_write(file, buf, size, foffset); - } - - return rc; -} - static int spufs_ctx_note_size(struct spu_context *ctx, int dfd) { int i, sz, total = 0; @@ -165,10 +129,10 @@ int spufs_coredump_extra_notes_size(void) } static int spufs_arch_write_note(struct spu_context *ctx, int i, - struct file *file, int dfd, loff_t *foffset) + struct coredump_params *cprm, int dfd) { loff_t pos = 0; - int sz, rc, nread, total = 0; + int sz, rc, total = 0; const int bufsz = PAGE_SIZE; char *name; char fullname[80], *buf; @@ -186,42 +150,39 @@ static int spufs_arch_write_note(struct spu_context *ctx, int i, en.n_descsz = sz; en.n_type = NT_SPU; - rc = spufs_dump_write(file, &en, sizeof(en), foffset); - if (rc) - goto out; + if (!dump_emit(cprm, &en, sizeof(en))) + goto Eio; - rc = spufs_dump_write(file, fullname, en.n_namesz, foffset); - if (rc) - goto out; + if (!dump_emit(cprm, fullname, en.n_namesz)) + goto Eio; - rc = spufs_dump_align(file, buf, roundup(*foffset, 4), foffset); - if (rc) - goto out; + if (!dump_align(cprm, 4)) + goto Eio; do { - nread = do_coredump_read(i, ctx, buf, bufsz, &pos); - if (nread > 0) { - rc = spufs_dump_write(file, buf, nread, foffset); - if (rc) - goto out; - total += nread; + rc = do_coredump_read(i, ctx, buf, bufsz, &pos); + if (rc > 0) { + if (!dump_emit(cprm, buf, rc)) + goto Eio; + total += rc; } - } while (nread == bufsz && total < sz); + } while (rc == bufsz && total < sz); - if (nread < 0) { - rc = nread; + if (rc < 0) goto out; - } - - rc = spufs_dump_align(file, buf, roundup(*foffset - total + sz, 4), - foffset); + if (!dump_skip(cprm, + roundup(cprm->written - total + sz, 4) - cprm->written)) + goto Eio; out: free_page((unsigned long)buf); return rc; +Eio: + free_page((unsigned long)buf); + return -EIO; } -int spufs_coredump_extra_notes_write(struct file *file, loff_t *foffset) +int spufs_coredump_extra_notes_write(struct coredump_params *cprm) { struct spu_context *ctx; int fd, j, rc; @@ -233,7 +194,7 @@ int spufs_coredump_extra_notes_write(struct file *file, loff_t *foffset) return rc; for (j = 0; spufs_coredump_read[j].name != NULL; j++) { - rc = spufs_arch_write_note(ctx, j, file, fd, foffset); + rc = spufs_arch_write_note(ctx, j, cprm, fd); if (rc) { spu_release_saved(ctx); return rc; diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h index 67852ade4c01..0ba3c9598358 100644 --- a/arch/powerpc/platforms/cell/spufs/spufs.h +++ b/arch/powerpc/platforms/cell/spufs/spufs.h @@ -247,12 +247,13 @@ extern const struct spufs_tree_descr spufs_dir_debug_contents[]; /* system call implementation */ extern struct spufs_calls spufs_calls; +struct coredump_params; long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *status); long spufs_create(struct path *nd, struct dentry *dentry, unsigned int flags, umode_t mode, struct file *filp); /* ELF coredump callbacks for writing SPU ELF notes */ extern int spufs_coredump_extra_notes_size(void); -extern int spufs_coredump_extra_notes_write(struct file *file, loff_t *foffset); +extern int spufs_coredump_extra_notes_write(struct coredump_params *cprm); extern const struct file_operations spufs_context_fops; diff --git a/arch/powerpc/platforms/chrp/nvram.c b/arch/powerpc/platforms/chrp/nvram.c index d3ceff04ffc7..9ef8cc3378d0 100644 --- a/arch/powerpc/platforms/chrp/nvram.c +++ b/arch/powerpc/platforms/chrp/nvram.c @@ -66,7 +66,7 @@ static void chrp_nvram_write(int addr, unsigned char val) void __init chrp_nvram_init(void) { struct device_node *nvram; - const unsigned int *nbytes_p; + const __be32 *nbytes_p; unsigned int proplen; nvram = of_find_node_by_type(NULL, "nvram"); @@ -79,7 +79,7 @@ void __init chrp_nvram_init(void) return; } - nvram_size = *nbytes_p; + nvram_size = be32_to_cpup(nbytes_p); printk(KERN_INFO "CHRP nvram contains %u bytes\n", nvram_size); of_node_put(nvram); diff --git a/arch/powerpc/platforms/embedded6xx/flipper-pic.c b/arch/powerpc/platforms/embedded6xx/flipper-pic.c index 53d6eee01963..4cde8e7da4b8 100644 --- a/arch/powerpc/platforms/embedded6xx/flipper-pic.c +++ b/arch/powerpc/platforms/embedded6xx/flipper-pic.c @@ -18,6 +18,7 @@ #include <linux/init.h> #include <linux/irq.h> #include <linux/of.h> +#include <linux/of_address.h> #include <asm/io.h> #include "flipper-pic.h" diff --git a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c index 3006b5117ec6..6c03034dbbd3 100644 --- a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c +++ b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c @@ -18,6 +18,8 @@ #include <linux/init.h> #include <linux/irq.h> #include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> #include <asm/io.h> #include "hlwd-pic.h" @@ -181,6 +183,7 @@ struct irq_domain *hlwd_pic_init(struct device_node *np) &hlwd_irq_domain_ops, io_base); if (!irq_domain) { pr_err("failed to allocate irq_domain\n"); + iounmap(io_base); return NULL; } diff --git a/arch/powerpc/platforms/fsl_uli1575.c b/arch/powerpc/platforms/fsl_uli1575.c index 92ac9b52b32d..b97f6f3d3c5b 100644 --- a/arch/powerpc/platforms/fsl_uli1575.c +++ b/arch/powerpc/platforms/fsl_uli1575.c @@ -321,8 +321,7 @@ static void hpcd_final_uli5288(struct pci_dev *dev) { struct pci_controller *hose = pci_bus_to_host(dev->bus); struct device_node *hosenode = hose ? hose->dn : NULL; - struct of_irq oirq; - int virq, pin = 2; + struct of_phandle_args oirq; u32 laddr[3]; if (!machine_is(mpc86xx_hpcd)) @@ -331,12 +330,13 @@ static void hpcd_final_uli5288(struct pci_dev *dev) if (!hosenode) return; + oirq.np = hosenode; + oirq.args[0] = 2; + oirq.args_count = 1; laddr[0] = (hose->first_busno << 16) | (PCI_DEVFN(31, 0) << 8); laddr[1] = laddr[2] = 0; - of_irq_map_raw(hosenode, &pin, 1, laddr, &oirq); - virq = irq_create_of_mapping(oirq.controller, oirq.specifier, - oirq.size); - dev->irq = virq; + of_irq_parse_raw(laddr, &oirq); + dev->irq = irq_create_of_mapping(&oirq); } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1575, hpcd_quirk_uli1575); diff --git a/arch/powerpc/platforms/pasemi/gpio_mdio.c b/arch/powerpc/platforms/pasemi/gpio_mdio.c index 0237ab782fb8..15adee544638 100644 --- a/arch/powerpc/platforms/pasemi/gpio_mdio.c +++ b/arch/powerpc/platforms/pasemi/gpio_mdio.c @@ -30,6 +30,7 @@ #include <linux/ioport.h> #include <linux/interrupt.h> #include <linux/phy.h> +#include <linux/of_address.h> #include <linux/of_mdio.h> #include <linux/of_platform.h> diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c index fc536f2971c0..7553b6a77c64 100644 --- a/arch/powerpc/platforms/powermac/low_i2c.c +++ b/arch/powerpc/platforms/powermac/low_i2c.c @@ -452,7 +452,7 @@ static int kw_i2c_xfer(struct pmac_i2c_bus *bus, u8 addrdir, int subsize, */ if (use_irq) { /* Clear completion */ - INIT_COMPLETION(host->complete); + reinit_completion(&host->complete); /* Ack stale interrupts */ kw_write_reg(reg_isr, kw_read_reg(reg_isr)); /* Arm timeout */ @@ -717,7 +717,7 @@ static int pmu_i2c_xfer(struct pmac_i2c_bus *bus, u8 addrdir, int subsize, return -EINVAL; } - INIT_COMPLETION(comp); + reinit_completion(&comp); req->data[0] = PMU_I2C_CMD; req->reply[0] = 0xff; req->nbytes = sizeof(struct pmu_i2c_hdr) + 1; @@ -748,7 +748,7 @@ static int pmu_i2c_xfer(struct pmac_i2c_bus *bus, u8 addrdir, int subsize, hdr->bus = PMU_I2C_BUS_STATUS; - INIT_COMPLETION(comp); + reinit_completion(&comp); req->data[0] = PMU_I2C_CMD; req->reply[0] = 0xff; req->nbytes = 2; diff --git a/arch/powerpc/platforms/powermac/pfunc_base.c b/arch/powerpc/platforms/powermac/pfunc_base.c index f5e3cda6660e..e49d07f3d542 100644 --- a/arch/powerpc/platforms/powermac/pfunc_base.c +++ b/arch/powerpc/platforms/powermac/pfunc_base.c @@ -4,6 +4,7 @@ #include <linux/kernel.h> #include <linux/interrupt.h> #include <linux/spinlock.h> +#include <linux/of_irq.h> #include <asm/pmac_feature.h> #include <asm/pmac_pfunc.h> diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c index 31036b56670e..4c24bf60d39d 100644 --- a/arch/powerpc/platforms/powermac/pic.c +++ b/arch/powerpc/platforms/powermac/pic.c @@ -393,8 +393,8 @@ static void __init pmac_pic_probe_oldstyle(void) #endif } -int of_irq_map_oldworld(struct device_node *device, int index, - struct of_irq *out_irq) +int of_irq_parse_oldworld(struct device_node *device, int index, + struct of_phandle_args *out_irq) { const u32 *ints = NULL; int intlen; @@ -422,9 +422,9 @@ int of_irq_map_oldworld(struct device_node *device, int index, if (index >= intlen) return -EINVAL; - out_irq->controller = NULL; - out_irq->specifier[0] = ints[index]; - out_irq->size = 1; + out_irq->np = NULL; + out_irq->args[0] = ints[index]; + out_irq->args_count = 1; return 0; } diff --git a/arch/powerpc/platforms/powernv/Kconfig b/arch/powerpc/platforms/powernv/Kconfig index 6fae5eb99ea6..9fced3f6d2dc 100644 --- a/arch/powerpc/platforms/powernv/Kconfig +++ b/arch/powerpc/platforms/powernv/Kconfig @@ -9,6 +9,8 @@ config PPC_POWERNV select EPAPR_BOOT select PPC_INDIRECT_PIO select PPC_UDBG_16550 + select PPC_SCOM + select ARCH_RANDOM default y config POWERNV_MSI diff --git a/arch/powerpc/platforms/powernv/Makefile b/arch/powerpc/platforms/powernv/Makefile index 300c437d713c..873fa1370dc4 100644 --- a/arch/powerpc/platforms/powernv/Makefile +++ b/arch/powerpc/platforms/powernv/Makefile @@ -1,6 +1,8 @@ obj-y += setup.o opal-takeover.o opal-wrappers.o opal.o -obj-y += opal-rtc.o opal-nvram.o opal-lpc.o +obj-y += opal-rtc.o opal-nvram.o opal-lpc.o opal-flash.o +obj-y += rng.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_PCI) += pci.o pci-p5ioc2.o pci-ioda.o obj-$(CONFIG_EEH) += eeh-ioda.o eeh-powernv.o +obj-$(CONFIG_PPC_SCOM) += opal-xscom.o diff --git a/arch/powerpc/platforms/powernv/eeh-ioda.c b/arch/powerpc/platforms/powernv/eeh-ioda.c index cf42e74514fa..02245cee7818 100644 --- a/arch/powerpc/platforms/powernv/eeh-ioda.c +++ b/arch/powerpc/platforms/powernv/eeh-ioda.c @@ -59,26 +59,60 @@ static struct notifier_block ioda_eeh_nb = { }; #ifdef CONFIG_DEBUG_FS -static int ioda_eeh_dbgfs_set(void *data, u64 val) +static int ioda_eeh_dbgfs_set(void *data, int offset, u64 val) { struct pci_controller *hose = data; struct pnv_phb *phb = hose->private_data; - out_be64(phb->regs + 0xD10, val); + out_be64(phb->regs + offset, val); return 0; } -static int ioda_eeh_dbgfs_get(void *data, u64 *val) +static int ioda_eeh_dbgfs_get(void *data, int offset, u64 *val) { struct pci_controller *hose = data; struct pnv_phb *phb = hose->private_data; - *val = in_be64(phb->regs + 0xD10); + *val = in_be64(phb->regs + offset); return 0; } -DEFINE_SIMPLE_ATTRIBUTE(ioda_eeh_dbgfs_ops, ioda_eeh_dbgfs_get, - ioda_eeh_dbgfs_set, "0x%llx\n"); +static int ioda_eeh_outb_dbgfs_set(void *data, u64 val) +{ + return ioda_eeh_dbgfs_set(data, 0xD10, val); +} + +static int ioda_eeh_outb_dbgfs_get(void *data, u64 *val) +{ + return ioda_eeh_dbgfs_get(data, 0xD10, val); +} + +static int ioda_eeh_inbA_dbgfs_set(void *data, u64 val) +{ + return ioda_eeh_dbgfs_set(data, 0xD90, val); +} + +static int ioda_eeh_inbA_dbgfs_get(void *data, u64 *val) +{ + return ioda_eeh_dbgfs_get(data, 0xD90, val); +} + +static int ioda_eeh_inbB_dbgfs_set(void *data, u64 val) +{ + return ioda_eeh_dbgfs_set(data, 0xE10, val); +} + +static int ioda_eeh_inbB_dbgfs_get(void *data, u64 *val) +{ + return ioda_eeh_dbgfs_get(data, 0xE10, val); +} + +DEFINE_SIMPLE_ATTRIBUTE(ioda_eeh_outb_dbgfs_ops, ioda_eeh_outb_dbgfs_get, + ioda_eeh_outb_dbgfs_set, "0x%llx\n"); +DEFINE_SIMPLE_ATTRIBUTE(ioda_eeh_inbA_dbgfs_ops, ioda_eeh_inbA_dbgfs_get, + ioda_eeh_inbA_dbgfs_set, "0x%llx\n"); +DEFINE_SIMPLE_ATTRIBUTE(ioda_eeh_inbB_dbgfs_ops, ioda_eeh_inbB_dbgfs_get, + ioda_eeh_inbB_dbgfs_set, "0x%llx\n"); #endif /* CONFIG_DEBUG_FS */ /** @@ -106,27 +140,30 @@ static int ioda_eeh_post_init(struct pci_controller *hose) ioda_eeh_nb_init = 1; } - /* FIXME: Enable it for PHB3 later */ - if (phb->type == PNV_PHB_IODA1) { + /* We needn't HUB diag-data on PHB3 */ + if (phb->type == PNV_PHB_IODA1 && !hub_diag) { + hub_diag = (char *)__get_free_page(GFP_KERNEL | __GFP_ZERO); if (!hub_diag) { - hub_diag = (char *)__get_free_page(GFP_KERNEL | - __GFP_ZERO); - if (!hub_diag) { - pr_err("%s: Out of memory !\n", - __func__); - return -ENOMEM; - } + pr_err("%s: Out of memory !\n", __func__); + return -ENOMEM; } + } #ifdef CONFIG_DEBUG_FS - if (phb->dbgfs) - debugfs_create_file("err_injct", 0600, - phb->dbgfs, hose, - &ioda_eeh_dbgfs_ops); + if (phb->dbgfs) { + debugfs_create_file("err_injct_outbound", 0600, + phb->dbgfs, hose, + &ioda_eeh_outb_dbgfs_ops); + debugfs_create_file("err_injct_inboundA", 0600, + phb->dbgfs, hose, + &ioda_eeh_inbA_dbgfs_ops); + debugfs_create_file("err_injct_inboundB", 0600, + phb->dbgfs, hose, + &ioda_eeh_inbB_dbgfs_ops); + } #endif - phb->eeh_state |= PNV_EEH_STATE_ENABLED; - } + phb->eeh_state |= PNV_EEH_STATE_ENABLED; return 0; } @@ -546,8 +583,8 @@ static int ioda_eeh_get_log(struct eeh_pe *pe, int severity, phb->diag.blob, PNV_PCI_DIAG_BUF_SIZE); if (ret) { spin_unlock_irqrestore(&phb->lock, flags); - pr_warning("%s: Failed to get log for PHB#%x-PE#%x\n", - __func__, hose->global_number, pe->addr); + pr_warning("%s: Can't get log for PHB#%x-PE#%x (%lld)\n", + __func__, hose->global_number, pe->addr, ret); return -EIO; } @@ -710,6 +747,73 @@ static void ioda_eeh_p7ioc_phb_diag(struct pci_controller *hose, } } +static void ioda_eeh_phb3_phb_diag(struct pci_controller *hose, + struct OpalIoPhbErrorCommon *common) +{ + struct OpalIoPhb3ErrorData *data; + int i; + + data = (struct OpalIoPhb3ErrorData*)common; + pr_info("PHB3 PHB#%x Diag-data (Version: %d)\n\n", + hose->global_number, common->version); + + pr_info(" brdgCtl: %08x\n", data->brdgCtl); + + pr_info(" portStatusReg: %08x\n", data->portStatusReg); + pr_info(" rootCmplxStatus: %08x\n", data->rootCmplxStatus); + pr_info(" busAgentStatus: %08x\n", data->busAgentStatus); + + pr_info(" deviceStatus: %08x\n", data->deviceStatus); + pr_info(" slotStatus: %08x\n", data->slotStatus); + pr_info(" linkStatus: %08x\n", data->linkStatus); + pr_info(" devCmdStatus: %08x\n", data->devCmdStatus); + pr_info(" devSecStatus: %08x\n", data->devSecStatus); + + pr_info(" rootErrorStatus: %08x\n", data->rootErrorStatus); + pr_info(" uncorrErrorStatus: %08x\n", data->uncorrErrorStatus); + pr_info(" corrErrorStatus: %08x\n", data->corrErrorStatus); + pr_info(" tlpHdr1: %08x\n", data->tlpHdr1); + pr_info(" tlpHdr2: %08x\n", data->tlpHdr2); + pr_info(" tlpHdr3: %08x\n", data->tlpHdr3); + pr_info(" tlpHdr4: %08x\n", data->tlpHdr4); + pr_info(" sourceId: %08x\n", data->sourceId); + pr_info(" errorClass: %016llx\n", data->errorClass); + pr_info(" correlator: %016llx\n", data->correlator); + pr_info(" nFir: %016llx\n", data->nFir); + pr_info(" nFirMask: %016llx\n", data->nFirMask); + pr_info(" nFirWOF: %016llx\n", data->nFirWOF); + pr_info(" PhbPlssr: %016llx\n", data->phbPlssr); + pr_info(" PhbCsr: %016llx\n", data->phbCsr); + pr_info(" lemFir: %016llx\n", data->lemFir); + pr_info(" lemErrorMask: %016llx\n", data->lemErrorMask); + pr_info(" lemWOF: %016llx\n", data->lemWOF); + pr_info(" phbErrorStatus: %016llx\n", data->phbErrorStatus); + pr_info(" phbFirstErrorStatus: %016llx\n", data->phbFirstErrorStatus); + pr_info(" phbErrorLog0: %016llx\n", data->phbErrorLog0); + pr_info(" phbErrorLog1: %016llx\n", data->phbErrorLog1); + pr_info(" mmioErrorStatus: %016llx\n", data->mmioErrorStatus); + pr_info(" mmioFirstErrorStatus: %016llx\n", data->mmioFirstErrorStatus); + pr_info(" mmioErrorLog0: %016llx\n", data->mmioErrorLog0); + pr_info(" mmioErrorLog1: %016llx\n", data->mmioErrorLog1); + pr_info(" dma0ErrorStatus: %016llx\n", data->dma0ErrorStatus); + pr_info(" dma0FirstErrorStatus: %016llx\n", data->dma0FirstErrorStatus); + pr_info(" dma0ErrorLog0: %016llx\n", data->dma0ErrorLog0); + pr_info(" dma0ErrorLog1: %016llx\n", data->dma0ErrorLog1); + pr_info(" dma1ErrorStatus: %016llx\n", data->dma1ErrorStatus); + pr_info(" dma1FirstErrorStatus: %016llx\n", data->dma1FirstErrorStatus); + pr_info(" dma1ErrorLog0: %016llx\n", data->dma1ErrorLog0); + pr_info(" dma1ErrorLog1: %016llx\n", data->dma1ErrorLog1); + + for (i = 0; i < OPAL_PHB3_NUM_PEST_REGS; i++) { + if ((data->pestA[i] >> 63) == 0 && + (data->pestB[i] >> 63) == 0) + continue; + + pr_info(" PE[%3d] PESTA: %016llx\n", i, data->pestA[i]); + pr_info(" PESTB: %016llx\n", data->pestB[i]); + } +} + static void ioda_eeh_phb_diag(struct pci_controller *hose) { struct pnv_phb *phb = hose->private_data; @@ -728,6 +832,9 @@ static void ioda_eeh_phb_diag(struct pci_controller *hose) case OPAL_PHB_ERROR_DATA_TYPE_P7IOC: ioda_eeh_p7ioc_phb_diag(hose, common); break; + case OPAL_PHB_ERROR_DATA_TYPE_PHB3: + ioda_eeh_phb3_phb_diag(hose, common); + break; default: pr_warning("%s: Unrecognized I/O chip %d\n", __func__, common->ioType); diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c index 79663d26e6ea..73b981438cc5 100644 --- a/arch/powerpc/platforms/powernv/eeh-powernv.c +++ b/arch/powerpc/platforms/powernv/eeh-powernv.c @@ -144,11 +144,8 @@ static int powernv_eeh_dev_probe(struct pci_dev *dev, void *flag) /* * Enable EEH explicitly so that we will do EEH check * while accessing I/O stuff - * - * FIXME: Enable that for PHB3 later */ - if (phb->type == PNV_PHB_IODA1) - eeh_subsystem_enabled = 1; + eeh_subsystem_enabled = 1; /* Save memory bars */ eeh_save_bars(edev); diff --git a/arch/powerpc/platforms/powernv/opal-flash.c b/arch/powerpc/platforms/powernv/opal-flash.c new file mode 100644 index 000000000000..6ffa6b1ec5b7 --- /dev/null +++ b/arch/powerpc/platforms/powernv/opal-flash.c @@ -0,0 +1,667 @@ +/* + * PowerNV OPAL Firmware Update Interface + * + * Copyright 2013 IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#define DEBUG + +#include <linux/kernel.h> +#include <linux/reboot.h> +#include <linux/init.h> +#include <linux/kobject.h> +#include <linux/sysfs.h> +#include <linux/slab.h> +#include <linux/mm.h> +#include <linux/vmalloc.h> +#include <linux/pagemap.h> + +#include <asm/opal.h> + +/* FLASH status codes */ +#define FLASH_NO_OP -1099 /* No operation initiated by user */ +#define FLASH_NO_AUTH -9002 /* Not a service authority partition */ + +/* Validate image status values */ +#define VALIDATE_IMG_READY -1001 /* Image ready for validation */ +#define VALIDATE_IMG_INCOMPLETE -1002 /* User copied < VALIDATE_BUF_SIZE */ + +/* Manage image status values */ +#define MANAGE_ACTIVE_ERR -9001 /* Cannot overwrite active img */ + +/* Flash image status values */ +#define FLASH_IMG_READY 0 /* Img ready for flash on reboot */ +#define FLASH_INVALID_IMG -1003 /* Flash image shorter than expected */ +#define FLASH_IMG_NULL_DATA -1004 /* Bad data in sg list entry */ +#define FLASH_IMG_BAD_LEN -1005 /* Bad length in sg list entry */ + +/* Manage operation tokens */ +#define FLASH_REJECT_TMP_SIDE 0 /* Reject temporary fw image */ +#define FLASH_COMMIT_TMP_SIDE 1 /* Commit temporary fw image */ + +/* Update tokens */ +#define FLASH_UPDATE_CANCEL 0 /* Cancel update request */ +#define FLASH_UPDATE_INIT 1 /* Initiate update */ + +/* Validate image update result tokens */ +#define VALIDATE_TMP_UPDATE 0 /* T side will be updated */ +#define VALIDATE_FLASH_AUTH 1 /* Partition does not have authority */ +#define VALIDATE_INVALID_IMG 2 /* Candidate image is not valid */ +#define VALIDATE_CUR_UNKNOWN 3 /* Current fixpack level is unknown */ +/* + * Current T side will be committed to P side before being replace with new + * image, and the new image is downlevel from current image + */ +#define VALIDATE_TMP_COMMIT_DL 4 +/* + * Current T side will be committed to P side before being replaced with new + * image + */ +#define VALIDATE_TMP_COMMIT 5 +/* + * T side will be updated with a downlevel image + */ +#define VALIDATE_TMP_UPDATE_DL 6 +/* + * The candidate image's release date is later than the system's firmware + * service entitlement date - service warranty period has expired + */ +#define VALIDATE_OUT_OF_WRNTY 7 + +/* Validate buffer size */ +#define VALIDATE_BUF_SIZE 4096 + +/* XXX: Assume candidate image size is <= 256MB */ +#define MAX_IMAGE_SIZE 0x10000000 + +/* Flash sg list version */ +#define SG_LIST_VERSION (1UL) + +/* Image status */ +enum { + IMAGE_INVALID, + IMAGE_LOADING, + IMAGE_READY, +}; + +/* Candidate image data */ +struct image_data_t { + int status; + void *data; + uint32_t size; +}; + +/* Candidate image header */ +struct image_header_t { + uint16_t magic; + uint16_t version; + uint32_t size; +}; + +/* Scatter/gather entry */ +struct opal_sg_entry { + void *data; + long length; +}; + +/* We calculate number of entries based on PAGE_SIZE */ +#define SG_ENTRIES_PER_NODE ((PAGE_SIZE - 16) / sizeof(struct opal_sg_entry)) + +/* + * This struct is very similar but not identical to that + * needed by the opal flash update. All we need to do for + * opal is rewrite num_entries into a version/length and + * translate the pointers to absolute. + */ +struct opal_sg_list { + unsigned long num_entries; + struct opal_sg_list *next; + struct opal_sg_entry entry[SG_ENTRIES_PER_NODE]; +}; + +struct validate_flash_t { + int status; /* Return status */ + void *buf; /* Candiate image buffer */ + uint32_t buf_size; /* Image size */ + uint32_t result; /* Update results token */ +}; + +struct manage_flash_t { + int status; /* Return status */ +}; + +struct update_flash_t { + int status; /* Return status */ +}; + +static struct image_header_t image_header; +static struct image_data_t image_data; +static struct validate_flash_t validate_flash_data; +static struct manage_flash_t manage_flash_data; +static struct update_flash_t update_flash_data; + +static DEFINE_MUTEX(image_data_mutex); + +/* + * Validate candidate image + */ +static inline void opal_flash_validate(void) +{ + struct validate_flash_t *args_buf = &validate_flash_data; + + args_buf->status = opal_validate_flash(__pa(args_buf->buf), + &(args_buf->buf_size), + &(args_buf->result)); +} + +/* + * Validate output format: + * validate result token + * current image version details + * new image version details + */ +static ssize_t validate_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + struct validate_flash_t *args_buf = &validate_flash_data; + int len; + + /* Candidate image is not validated */ + if (args_buf->status < VALIDATE_TMP_UPDATE) { + len = sprintf(buf, "%d\n", args_buf->status); + goto out; + } + + /* Result token */ + len = sprintf(buf, "%d\n", args_buf->result); + + /* Current and candidate image version details */ + if ((args_buf->result != VALIDATE_TMP_UPDATE) && + (args_buf->result < VALIDATE_CUR_UNKNOWN)) + goto out; + + if (args_buf->buf_size > (VALIDATE_BUF_SIZE - len)) { + memcpy(buf + len, args_buf->buf, VALIDATE_BUF_SIZE - len); + len = VALIDATE_BUF_SIZE; + } else { + memcpy(buf + len, args_buf->buf, args_buf->buf_size); + len += args_buf->buf_size; + } +out: + /* Set status to default */ + args_buf->status = FLASH_NO_OP; + return len; +} + +/* + * Validate candidate firmware image + * + * Note: + * We are only interested in first 4K bytes of the + * candidate image. + */ +static ssize_t validate_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t count) +{ + struct validate_flash_t *args_buf = &validate_flash_data; + + if (buf[0] != '1') + return -EINVAL; + + mutex_lock(&image_data_mutex); + + if (image_data.status != IMAGE_READY || + image_data.size < VALIDATE_BUF_SIZE) { + args_buf->result = VALIDATE_INVALID_IMG; + args_buf->status = VALIDATE_IMG_INCOMPLETE; + goto out; + } + + /* Copy first 4k bytes of candidate image */ + memcpy(args_buf->buf, image_data.data, VALIDATE_BUF_SIZE); + + args_buf->status = VALIDATE_IMG_READY; + args_buf->buf_size = VALIDATE_BUF_SIZE; + + /* Validate candidate image */ + opal_flash_validate(); + +out: + mutex_unlock(&image_data_mutex); + return count; +} + +/* + * Manage flash routine + */ +static inline void opal_flash_manage(uint8_t op) +{ + struct manage_flash_t *const args_buf = &manage_flash_data; + + args_buf->status = opal_manage_flash(op); +} + +/* + * Show manage flash status + */ +static ssize_t manage_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + struct manage_flash_t *const args_buf = &manage_flash_data; + int rc; + + rc = sprintf(buf, "%d\n", args_buf->status); + /* Set status to default*/ + args_buf->status = FLASH_NO_OP; + return rc; +} + +/* + * Manage operations: + * 0 - Reject + * 1 - Commit + */ +static ssize_t manage_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t count) +{ + uint8_t op; + switch (buf[0]) { + case '0': + op = FLASH_REJECT_TMP_SIDE; + break; + case '1': + op = FLASH_COMMIT_TMP_SIDE; + break; + default: + return -EINVAL; + } + + /* commit/reject temporary image */ + opal_flash_manage(op); + return count; +} + +/* + * Free sg list + */ +static void free_sg_list(struct opal_sg_list *list) +{ + struct opal_sg_list *sg1; + while (list) { + sg1 = list->next; + kfree(list); + list = sg1; + } + list = NULL; +} + +/* + * Build candidate image scatter gather list + * + * list format: + * ----------------------------------- + * | VER (8) | Entry length in bytes | + * ----------------------------------- + * | Pointer to next entry | + * ----------------------------------- + * | Address of memory area 1 | + * ----------------------------------- + * | Length of memory area 1 | + * ----------------------------------- + * | ......... | + * ----------------------------------- + * | ......... | + * ----------------------------------- + * | Address of memory area N | + * ----------------------------------- + * | Length of memory area N | + * ----------------------------------- + */ +static struct opal_sg_list *image_data_to_sglist(void) +{ + struct opal_sg_list *sg1, *list = NULL; + void *addr; + int size; + + addr = image_data.data; + size = image_data.size; + + sg1 = kzalloc((sizeof(struct opal_sg_list)), GFP_KERNEL); + if (!sg1) + return NULL; + + list = sg1; + sg1->num_entries = 0; + while (size > 0) { + /* Translate virtual address to physical address */ + sg1->entry[sg1->num_entries].data = + (void *)(vmalloc_to_pfn(addr) << PAGE_SHIFT); + + if (size > PAGE_SIZE) + sg1->entry[sg1->num_entries].length = PAGE_SIZE; + else + sg1->entry[sg1->num_entries].length = size; + + sg1->num_entries++; + if (sg1->num_entries >= SG_ENTRIES_PER_NODE) { + sg1->next = kzalloc((sizeof(struct opal_sg_list)), + GFP_KERNEL); + if (!sg1->next) { + pr_err("%s : Failed to allocate memory\n", + __func__); + goto nomem; + } + + sg1 = sg1->next; + sg1->num_entries = 0; + } + addr += PAGE_SIZE; + size -= PAGE_SIZE; + } + return list; +nomem: + free_sg_list(list); + return NULL; +} + +/* + * OPAL update flash + */ +static int opal_flash_update(int op) +{ + struct opal_sg_list *sg, *list, *next; + unsigned long addr; + int64_t rc = OPAL_PARAMETER; + + if (op == FLASH_UPDATE_CANCEL) { + pr_alert("FLASH: Image update cancelled\n"); + addr = '\0'; + goto flash; + } + + list = image_data_to_sglist(); + if (!list) + goto invalid_img; + + /* First entry address */ + addr = __pa(list); + + /* Translate sg list address to absolute */ + for (sg = list; sg; sg = next) { + next = sg->next; + /* Don't translate NULL pointer for last entry */ + if (sg->next) + sg->next = (struct opal_sg_list *)__pa(sg->next); + else + sg->next = NULL; + + /* Make num_entries into the version/length field */ + sg->num_entries = (SG_LIST_VERSION << 56) | + (sg->num_entries * sizeof(struct opal_sg_entry) + 16); + } + + pr_alert("FLASH: Image is %u bytes\n", image_data.size); + pr_alert("FLASH: Image update requested\n"); + pr_alert("FLASH: Image will be updated during system reboot\n"); + pr_alert("FLASH: This will take several minutes. Do not power off!\n"); + +flash: + rc = opal_update_flash(addr); + +invalid_img: + return rc; +} + +/* + * Show candidate image status + */ +static ssize_t update_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + struct update_flash_t *const args_buf = &update_flash_data; + return sprintf(buf, "%d\n", args_buf->status); +} + +/* + * Set update image flag + * 1 - Flash new image + * 0 - Cancel flash request + */ +static ssize_t update_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t count) +{ + struct update_flash_t *const args_buf = &update_flash_data; + int rc = count; + + mutex_lock(&image_data_mutex); + + switch (buf[0]) { + case '0': + if (args_buf->status == FLASH_IMG_READY) + opal_flash_update(FLASH_UPDATE_CANCEL); + args_buf->status = FLASH_NO_OP; + break; + case '1': + /* Image is loaded? */ + if (image_data.status == IMAGE_READY) + args_buf->status = + opal_flash_update(FLASH_UPDATE_INIT); + else + args_buf->status = FLASH_INVALID_IMG; + break; + default: + rc = -EINVAL; + } + + mutex_unlock(&image_data_mutex); + return rc; +} + +/* + * Free image buffer + */ +static void free_image_buf(void) +{ + void *addr; + int size; + + addr = image_data.data; + size = PAGE_ALIGN(image_data.size); + while (size > 0) { + ClearPageReserved(vmalloc_to_page(addr)); + addr += PAGE_SIZE; + size -= PAGE_SIZE; + } + vfree(image_data.data); + image_data.data = NULL; + image_data.status = IMAGE_INVALID; +} + +/* + * Allocate image buffer. + */ +static int alloc_image_buf(char *buffer, size_t count) +{ + void *addr; + int size; + + if (count < sizeof(struct image_header_t)) { + pr_warn("FLASH: Invalid candidate image\n"); + return -EINVAL; + } + + memcpy(&image_header, (void *)buffer, sizeof(struct image_header_t)); + image_data.size = be32_to_cpu(image_header.size); + pr_debug("FLASH: Candiate image size = %u\n", image_data.size); + + if (image_data.size > MAX_IMAGE_SIZE) { + pr_warn("FLASH: Too large image\n"); + return -EINVAL; + } + if (image_data.size < VALIDATE_BUF_SIZE) { + pr_warn("FLASH: Image is shorter than expected\n"); + return -EINVAL; + } + + image_data.data = vzalloc(PAGE_ALIGN(image_data.size)); + if (!image_data.data) { + pr_err("%s : Failed to allocate memory\n", __func__); + return -ENOMEM; + } + + /* Pin memory */ + addr = image_data.data; + size = PAGE_ALIGN(image_data.size); + while (size > 0) { + SetPageReserved(vmalloc_to_page(addr)); + addr += PAGE_SIZE; + size -= PAGE_SIZE; + } + + image_data.status = IMAGE_LOADING; + return 0; +} + +/* + * Copy candidate image + * + * Parse candidate image header to get total image size + * and pre-allocate required memory. + */ +static ssize_t image_data_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buffer, loff_t pos, size_t count) +{ + int rc; + + mutex_lock(&image_data_mutex); + + /* New image ? */ + if (pos == 0) { + /* Free memory, if already allocated */ + if (image_data.data) + free_image_buf(); + + /* Cancel outstanding image update request */ + if (update_flash_data.status == FLASH_IMG_READY) + opal_flash_update(FLASH_UPDATE_CANCEL); + + /* Allocate memory */ + rc = alloc_image_buf(buffer, count); + if (rc) + goto out; + } + + if (image_data.status != IMAGE_LOADING) { + rc = -ENOMEM; + goto out; + } + + if ((pos + count) > image_data.size) { + rc = -EINVAL; + goto out; + } + + memcpy(image_data.data + pos, (void *)buffer, count); + rc = count; + + /* Set image status */ + if ((pos + count) == image_data.size) { + pr_debug("FLASH: Candidate image loaded....\n"); + image_data.status = IMAGE_READY; + } + +out: + mutex_unlock(&image_data_mutex); + return rc; +} + +/* + * sysfs interface : + * OPAL uses below sysfs files for code update. + * We create these files under /sys/firmware/opal. + * + * image : Interface to load candidate firmware image + * validate_flash : Validate firmware image + * manage_flash : Commit/Reject firmware image + * update_flash : Flash new firmware image + * + */ +static struct bin_attribute image_data_attr = { + .attr = {.name = "image", .mode = 0200}, + .size = MAX_IMAGE_SIZE, /* Limit image size */ + .write = image_data_write, +}; + +static struct kobj_attribute validate_attribute = + __ATTR(validate_flash, 0600, validate_show, validate_store); + +static struct kobj_attribute manage_attribute = + __ATTR(manage_flash, 0600, manage_show, manage_store); + +static struct kobj_attribute update_attribute = + __ATTR(update_flash, 0600, update_show, update_store); + +static struct attribute *image_op_attrs[] = { + &validate_attribute.attr, + &manage_attribute.attr, + &update_attribute.attr, + NULL /* need to NULL terminate the list of attributes */ +}; + +static struct attribute_group image_op_attr_group = { + .attrs = image_op_attrs, +}; + +void __init opal_flash_init(void) +{ + int ret; + + /* Allocate validate image buffer */ + validate_flash_data.buf = kzalloc(VALIDATE_BUF_SIZE, GFP_KERNEL); + if (!validate_flash_data.buf) { + pr_err("%s : Failed to allocate memory\n", __func__); + return; + } + + /* Make sure /sys/firmware/opal directory is created */ + if (!opal_kobj) { + pr_warn("FLASH: opal kobject is not available\n"); + goto nokobj; + } + + /* Create the sysfs files */ + ret = sysfs_create_group(opal_kobj, &image_op_attr_group); + if (ret) { + pr_warn("FLASH: Failed to create sysfs files\n"); + goto nokobj; + } + + ret = sysfs_create_bin_file(opal_kobj, &image_data_attr); + if (ret) { + pr_warn("FLASH: Failed to create sysfs files\n"); + goto nosysfs_file; + } + + /* Set default status */ + validate_flash_data.status = FLASH_NO_OP; + manage_flash_data.status = FLASH_NO_OP; + update_flash_data.status = FLASH_NO_OP; + image_data.status = IMAGE_INVALID; + return; + +nosysfs_file: + sysfs_remove_group(opal_kobj, &image_op_attr_group); + +nokobj: + kfree(validate_flash_data.buf); + return; +} diff --git a/arch/powerpc/platforms/powernv/opal-lpc.c b/arch/powerpc/platforms/powernv/opal-lpc.c index a7614bb14e17..e7e59e4f9892 100644 --- a/arch/powerpc/platforms/powernv/opal-lpc.c +++ b/arch/powerpc/platforms/powernv/opal-lpc.c @@ -17,6 +17,7 @@ #include <asm/firmware.h> #include <asm/xics.h> #include <asm/opal.h> +#include <asm/prom.h> static int opal_lpc_chip_id = -1; diff --git a/arch/powerpc/platforms/powernv/opal-nvram.c b/arch/powerpc/platforms/powernv/opal-nvram.c index 3f83e1ae26ac..acd9f7e96678 100644 --- a/arch/powerpc/platforms/powernv/opal-nvram.c +++ b/arch/powerpc/platforms/powernv/opal-nvram.c @@ -65,7 +65,7 @@ static ssize_t opal_nvram_write(char *buf, size_t count, loff_t *index) void __init opal_nvram_init(void) { struct device_node *np; - const u32 *nbytes_p; + const __be32 *nbytes_p; np = of_find_compatible_node(NULL, NULL, "ibm,opal-nvram"); if (np == NULL) @@ -76,7 +76,7 @@ void __init opal_nvram_init(void) of_node_put(np); return; } - nvram_size = *nbytes_p; + nvram_size = be32_to_cpup(nbytes_p); printk(KERN_INFO "OPAL nvram setup, %u bytes\n", nvram_size); of_node_put(np); diff --git a/arch/powerpc/platforms/powernv/opal-rtc.c b/arch/powerpc/platforms/powernv/opal-rtc.c index 2aa7641aac9b..7d07c7e80ec0 100644 --- a/arch/powerpc/platforms/powernv/opal-rtc.c +++ b/arch/powerpc/platforms/powernv/opal-rtc.c @@ -37,10 +37,12 @@ unsigned long __init opal_get_boot_time(void) struct rtc_time tm; u32 y_m_d; u64 h_m_s_ms; + __be32 __y_m_d; + __be64 __h_m_s_ms; long rc = OPAL_BUSY; while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) { - rc = opal_rtc_read(&y_m_d, &h_m_s_ms); + rc = opal_rtc_read(&__y_m_d, &__h_m_s_ms); if (rc == OPAL_BUSY_EVENT) opal_poll_events(NULL); else @@ -48,6 +50,8 @@ unsigned long __init opal_get_boot_time(void) } if (rc != OPAL_SUCCESS) return 0; + y_m_d = be32_to_cpu(__y_m_d); + h_m_s_ms = be64_to_cpu(__h_m_s_ms); opal_to_tm(y_m_d, h_m_s_ms, &tm); return mktime(tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); @@ -58,9 +62,11 @@ void opal_get_rtc_time(struct rtc_time *tm) long rc = OPAL_BUSY; u32 y_m_d; u64 h_m_s_ms; + __be32 __y_m_d; + __be64 __h_m_s_ms; while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) { - rc = opal_rtc_read(&y_m_d, &h_m_s_ms); + rc = opal_rtc_read(&__y_m_d, &__h_m_s_ms); if (rc == OPAL_BUSY_EVENT) opal_poll_events(NULL); else @@ -68,6 +74,8 @@ void opal_get_rtc_time(struct rtc_time *tm) } if (rc != OPAL_SUCCESS) return; + y_m_d = be32_to_cpu(__y_m_d); + h_m_s_ms = be64_to_cpu(__h_m_s_ms); opal_to_tm(y_m_d, h_m_s_ms, tm); } diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S index 8f3844535fbb..e7806504e976 100644 --- a/arch/powerpc/platforms/powernv/opal-wrappers.S +++ b/arch/powerpc/platforms/powernv/opal-wrappers.S @@ -24,7 +24,7 @@ mflr r0; \ mfcr r12; \ std r0,16(r1); \ - std r12,8(r1); \ + stw r12,8(r1); \ std r1,PACAR1(r13); \ li r0,0; \ mfmsr r12; \ @@ -34,7 +34,7 @@ mtmsrd r12,1; \ LOAD_REG_ADDR(r0,.opal_return); \ mtlr r0; \ - li r0,MSR_DR|MSR_IR; \ + li r0,MSR_DR|MSR_IR|MSR_LE;\ andc r12,r12,r0; \ li r0,token; \ mtspr SPRN_HSRR1,r12; \ @@ -45,8 +45,15 @@ hrfid _STATIC(opal_return) + /* + * Fixup endian on OPAL return... we should be able to simplify + * this by instead converting the below trampoline to a set of + * bytes (always BE) since MSR:LE will end up fixed up as a side + * effect of the rfid. + */ + FIXUP_ENDIAN ld r2,PACATOC(r13); - ld r4,8(r1); + lwz r4,8(r1); ld r5,16(r1); ld r6,PACASAVEDMSR(r13); mtspr SPRN_SRR0,r5; @@ -116,3 +123,6 @@ OPAL_CALL(opal_xscom_write, OPAL_XSCOM_WRITE); OPAL_CALL(opal_lpc_read, OPAL_LPC_READ); OPAL_CALL(opal_lpc_write, OPAL_LPC_WRITE); OPAL_CALL(opal_return_cpu, OPAL_RETURN_CPU); +OPAL_CALL(opal_validate_flash, OPAL_FLASH_VALIDATE); +OPAL_CALL(opal_manage_flash, OPAL_FLASH_MANAGE); +OPAL_CALL(opal_update_flash, OPAL_FLASH_UPDATE); diff --git a/arch/powerpc/platforms/powernv/opal-xscom.c b/arch/powerpc/platforms/powernv/opal-xscom.c new file mode 100644 index 000000000000..4d99a8fd55ac --- /dev/null +++ b/arch/powerpc/platforms/powernv/opal-xscom.c @@ -0,0 +1,128 @@ +/* + * PowerNV LPC bus handling. + * + * Copyright 2013 IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include <linux/kernel.h> +#include <linux/of.h> +#include <linux/bug.h> +#include <linux/gfp.h> +#include <linux/slab.h> + +#include <asm/machdep.h> +#include <asm/firmware.h> +#include <asm/opal.h> +#include <asm/scom.h> + +/* + * We could probably fit that inside the scom_map_t + * which is a void* after all but it's really too ugly + * so let's kmalloc it for now + */ +struct opal_scom_map { + uint32_t chip; + uint64_t addr; +}; + +static scom_map_t opal_scom_map(struct device_node *dev, u64 reg, u64 count) +{ + struct opal_scom_map *m; + const __be32 *gcid; + + if (!of_get_property(dev, "scom-controller", NULL)) { + pr_err("%s: device %s is not a SCOM controller\n", + __func__, dev->full_name); + return SCOM_MAP_INVALID; + } + gcid = of_get_property(dev, "ibm,chip-id", NULL); + if (!gcid) { + pr_err("%s: device %s has no ibm,chip-id\n", + __func__, dev->full_name); + return SCOM_MAP_INVALID; + } + m = kmalloc(sizeof(struct opal_scom_map), GFP_KERNEL); + if (!m) + return NULL; + m->chip = be32_to_cpup(gcid); + m->addr = reg; + + return (scom_map_t)m; +} + +static void opal_scom_unmap(scom_map_t map) +{ + kfree(map); +} + +static int opal_xscom_err_xlate(int64_t rc) +{ + switch(rc) { + case 0: + return 0; + /* Add more translations if necessary */ + default: + return -EIO; + } +} + +static u64 opal_scom_unmangle(u64 reg) +{ + /* + * XSCOM indirect addresses have the top bit set. Additionally + * the reset of the top 3 nibbles is always 0. + * + * Because the debugfs interface uses signed offsets and shifts + * the address left by 3, we basically cannot use the top 4 bits + * of the 64-bit address, and thus cannot use the indirect bit. + * + * To deal with that, we support the indirect bit being in bit + * 4 (IBM notation) instead of bit 0 in this API, we do the + * conversion here. To leave room for further xscom address + * expansion, we only clear out the top byte + * + */ + if (reg & (1ull << 59)) + reg = (reg & ~(0xffull << 56)) | (1ull << 63); + return reg; +} + +static int opal_scom_read(scom_map_t map, u64 reg, u64 *value) +{ + struct opal_scom_map *m = map; + int64_t rc; + + reg = opal_scom_unmangle(reg); + rc = opal_xscom_read(m->chip, m->addr + reg, (uint64_t *)__pa(value)); + return opal_xscom_err_xlate(rc); +} + +static int opal_scom_write(scom_map_t map, u64 reg, u64 value) +{ + struct opal_scom_map *m = map; + int64_t rc; + + reg = opal_scom_unmangle(reg); + rc = opal_xscom_write(m->chip, m->addr + reg, value); + return opal_xscom_err_xlate(rc); +} + +static const struct scom_controller opal_scom_controller = { + .map = opal_scom_map, + .unmap = opal_scom_unmap, + .read = opal_scom_read, + .write = opal_scom_write +}; + +static int opal_xscom_init(void) +{ + if (firmware_has_feature(FW_FEATURE_OPALv3)) + scom_init(&opal_scom_controller); + return 0; +} +arch_initcall(opal_xscom_init); diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c index 2911abe550f1..1c798cd55372 100644 --- a/arch/powerpc/platforms/powernv/opal.c +++ b/arch/powerpc/platforms/powernv/opal.c @@ -13,15 +13,20 @@ #include <linux/types.h> #include <linux/of.h> +#include <linux/of_fdt.h> #include <linux/of_platform.h> #include <linux/interrupt.h> #include <linux/notifier.h> #include <linux/slab.h> +#include <linux/kobject.h> #include <asm/opal.h> #include <asm/firmware.h> #include "powernv.h" +/* /sys/firmware/opal */ +struct kobject *opal_kobj; + struct opal { u64 base; u64 entry; @@ -77,6 +82,7 @@ int __init early_init_dt_scan_opal(unsigned long node, static int __init opal_register_exception_handlers(void) { +#ifdef __BIG_ENDIAN__ u64 glue; if (!(powerpc_firmware_features & FW_FEATURE_OPAL)) @@ -94,6 +100,7 @@ static int __init opal_register_exception_handlers(void) 0, glue); glue += 128; opal_register_exception_handler(OPAL_SOFTPATCH_HANDLER, 0, glue); +#endif return 0; } @@ -164,27 +171,28 @@ void opal_notifier_disable(void) int opal_get_chars(uint32_t vtermno, char *buf, int count) { - s64 len, rc; - u64 evt; + s64 rc; + __be64 evt, len; if (!opal.entry) return -ENODEV; opal_poll_events(&evt); - if ((evt & OPAL_EVENT_CONSOLE_INPUT) == 0) + if ((be64_to_cpu(evt) & OPAL_EVENT_CONSOLE_INPUT) == 0) return 0; - len = count; - rc = opal_console_read(vtermno, &len, buf); + len = cpu_to_be64(count); + rc = opal_console_read(vtermno, &len, buf); if (rc == OPAL_SUCCESS) - return len; + return be64_to_cpu(len); return 0; } int opal_put_chars(uint32_t vtermno, const char *data, int total_len) { int written = 0; + __be64 olen; s64 len, rc; unsigned long flags; - u64 evt; + __be64 evt; if (!opal.entry) return -ENODEV; @@ -199,13 +207,14 @@ int opal_put_chars(uint32_t vtermno, const char *data, int total_len) */ spin_lock_irqsave(&opal_write_lock, flags); if (firmware_has_feature(FW_FEATURE_OPALv2)) { - rc = opal_console_write_buffer_space(vtermno, &len); + rc = opal_console_write_buffer_space(vtermno, &olen); + len = be64_to_cpu(olen); if (rc || len < total_len) { spin_unlock_irqrestore(&opal_write_lock, flags); /* Closed -> drop characters */ if (rc) return total_len; - opal_poll_events(&evt); + opal_poll_events(NULL); return -EAGAIN; } } @@ -216,8 +225,9 @@ int opal_put_chars(uint32_t vtermno, const char *data, int total_len) rc = OPAL_BUSY; while(total_len > 0 && (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT || rc == OPAL_SUCCESS)) { - len = total_len; - rc = opal_console_write(vtermno, &len, data); + olen = cpu_to_be64(total_len); + rc = opal_console_write(vtermno, &olen, data); + len = be64_to_cpu(olen); /* Closed or other error drop */ if (rc != OPAL_SUCCESS && rc != OPAL_BUSY && @@ -237,7 +247,8 @@ int opal_put_chars(uint32_t vtermno, const char *data, int total_len) */ do opal_poll_events(&evt); - while(rc == OPAL_SUCCESS && (evt & OPAL_EVENT_CONSOLE_OUTPUT)); + while(rc == OPAL_SUCCESS && + (be64_to_cpu(evt) & OPAL_EVENT_CONSOLE_OUTPUT)); } spin_unlock_irqrestore(&opal_write_lock, flags); return written; @@ -360,7 +371,7 @@ int opal_machine_check(struct pt_regs *regs) static irqreturn_t opal_interrupt(int irq, void *data) { - uint64_t events; + __be64 events; opal_handle_interrupt(virq_to_hw(irq), &events); @@ -369,10 +380,21 @@ static irqreturn_t opal_interrupt(int irq, void *data) return IRQ_HANDLED; } +static int opal_sysfs_init(void) +{ + opal_kobj = kobject_create_and_add("opal", firmware_kobj); + if (!opal_kobj) { + pr_warn("kobject_create_and_add opal failed\n"); + return -ENOMEM; + } + + return 0; +} + static int __init opal_init(void) { struct device_node *np, *consoles; - const u32 *irqs; + const __be32 *irqs; int rc, i, irqlen; opal_node = of_find_node_by_path("/ibm,opal"); @@ -414,6 +436,14 @@ static int __init opal_init(void) " (0x%x)\n", rc, irq, hwirq); opal_irqs[i] = irq; } + + /* Create "opal" kobject under /sys/firmware */ + rc = opal_sysfs_init(); + if (rc == 0) { + /* Setup code update interface */ + opal_flash_init(); + } + return 0; } subsys_initcall(opal_init); diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 74a5a5773b1f..084cdfa40682 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -70,6 +70,16 @@ define_pe_printk_level(pe_err, KERN_ERR); define_pe_printk_level(pe_warn, KERN_WARNING); define_pe_printk_level(pe_info, KERN_INFO); +/* + * stdcix is only supposed to be used in hypervisor real mode as per + * the architecture spec + */ +static inline void __raw_rm_writeq(u64 val, volatile void __iomem *paddr) +{ + __asm__ __volatile__("stdcix %0,0,%1" + : : "r" (val), "r" (paddr) : "memory"); +} + static int pnv_ioda_alloc_pe(struct pnv_phb *phb) { unsigned long pe; @@ -153,13 +163,23 @@ static int pnv_ioda_configure_pe(struct pnv_phb *phb, struct pnv_ioda_pe *pe) rid_end = pe->rid + 1; } - /* Associate PE in PELT */ + /* + * Associate PE in PELT. We need add the PE into the + * corresponding PELT-V as well. Otherwise, the error + * originated from the PE might contribute to other + * PEs. + */ rc = opal_pci_set_pe(phb->opal_id, pe->pe_number, pe->rid, bcomp, dcomp, fcomp, OPAL_MAP_PE); if (rc) { pe_err(pe, "OPAL error %ld trying to setup PELT table\n", rc); return -ENXIO; } + + rc = opal_pci_set_peltv(phb->opal_id, pe->pe_number, + pe->pe_number, OPAL_ADD_PE_TO_DOMAIN); + if (rc) + pe_warn(pe, "OPAL error %d adding self to PELTV\n", rc); opal_pci_eeh_freeze_clear(phb->opal_id, pe->pe_number, OPAL_EEH_ACTION_CLEAR_FREEZE_ALL); @@ -454,10 +474,13 @@ static void pnv_ioda_setup_bus_dma(struct pnv_ioda_pe *pe, struct pci_bus *bus) } } -static void pnv_pci_ioda1_tce_invalidate(struct iommu_table *tbl, - u64 *startp, u64 *endp) +static void pnv_pci_ioda1_tce_invalidate(struct pnv_ioda_pe *pe, + struct iommu_table *tbl, + __be64 *startp, __be64 *endp, bool rm) { - u64 __iomem *invalidate = (u64 __iomem *)tbl->it_index; + __be64 __iomem *invalidate = rm ? + (__be64 __iomem *)pe->tce_inval_reg_phys : + (__be64 __iomem *)tbl->it_index; unsigned long start, end, inc; start = __pa(startp); @@ -484,7 +507,10 @@ static void pnv_pci_ioda1_tce_invalidate(struct iommu_table *tbl, mb(); /* Ensure above stores are visible */ while (start <= end) { - __raw_writeq(start, invalidate); + if (rm) + __raw_rm_writeq(cpu_to_be64(start), invalidate); + else + __raw_writeq(cpu_to_be64(start), invalidate); start += inc; } @@ -496,10 +522,12 @@ static void pnv_pci_ioda1_tce_invalidate(struct iommu_table *tbl, static void pnv_pci_ioda2_tce_invalidate(struct pnv_ioda_pe *pe, struct iommu_table *tbl, - u64 *startp, u64 *endp) + __be64 *startp, __be64 *endp, bool rm) { unsigned long start, end, inc; - u64 __iomem *invalidate = (u64 __iomem *)tbl->it_index; + __be64 __iomem *invalidate = rm ? + (__be64 __iomem *)pe->tce_inval_reg_phys : + (__be64 __iomem *)tbl->it_index; /* We'll invalidate DMA address in PE scope */ start = 0x2ul << 60; @@ -515,22 +543,25 @@ static void pnv_pci_ioda2_tce_invalidate(struct pnv_ioda_pe *pe, mb(); while (start <= end) { - __raw_writeq(start, invalidate); + if (rm) + __raw_rm_writeq(cpu_to_be64(start), invalidate); + else + __raw_writeq(cpu_to_be64(start), invalidate); start += inc; } } void pnv_pci_ioda_tce_invalidate(struct iommu_table *tbl, - u64 *startp, u64 *endp) + __be64 *startp, __be64 *endp, bool rm) { struct pnv_ioda_pe *pe = container_of(tbl, struct pnv_ioda_pe, tce32_table); struct pnv_phb *phb = pe->phb; if (phb->type == PNV_PHB_IODA1) - pnv_pci_ioda1_tce_invalidate(tbl, startp, endp); + pnv_pci_ioda1_tce_invalidate(pe, tbl, startp, endp, rm); else - pnv_pci_ioda2_tce_invalidate(pe, tbl, startp, endp); + pnv_pci_ioda2_tce_invalidate(pe, tbl, startp, endp, rm); } static void pnv_pci_ioda_setup_dma_pe(struct pnv_phb *phb, @@ -603,7 +634,9 @@ static void pnv_pci_ioda_setup_dma_pe(struct pnv_phb *phb, * bus number, print that out instead. */ tbl->it_busno = 0; - tbl->it_index = (unsigned long)ioremap(be64_to_cpup(swinvp), 8); + pe->tce_inval_reg_phys = be64_to_cpup(swinvp); + tbl->it_index = (unsigned long)ioremap(pe->tce_inval_reg_phys, + 8); tbl->it_type = TCE_PCI_SWINV_CREATE | TCE_PCI_SWINV_FREE | TCE_PCI_SWINV_PAIR; } @@ -681,7 +714,9 @@ static void pnv_pci_ioda2_setup_dma_pe(struct pnv_phb *phb, * bus number, print that out instead. */ tbl->it_busno = 0; - tbl->it_index = (unsigned long)ioremap(be64_to_cpup(swinvp), 8); + pe->tce_inval_reg_phys = be64_to_cpup(swinvp); + tbl->it_index = (unsigned long)ioremap(pe->tce_inval_reg_phys, + 8); tbl->it_type = TCE_PCI_SWINV_CREATE | TCE_PCI_SWINV_FREE; } iommu_init_table(tbl, phb->hose->node); @@ -786,8 +821,7 @@ static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, struct irq_data *idata; struct irq_chip *ichip; unsigned int xive_num = hwirq - phb->msi_base; - uint64_t addr64; - uint32_t addr32, data; + __be32 data; int rc; /* No PE assigned ? bail out ... no MSI for you ! */ @@ -811,6 +845,8 @@ static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, } if (is_64) { + __be64 addr64; + rc = opal_get_msi_64(phb->opal_id, pe->mve_number, xive_num, 1, &addr64, &data); if (rc) { @@ -818,9 +854,11 @@ static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, pci_name(dev), rc); return -EIO; } - msg->address_hi = addr64 >> 32; - msg->address_lo = addr64 & 0xfffffffful; + msg->address_hi = be64_to_cpu(addr64) >> 32; + msg->address_lo = be64_to_cpu(addr64) & 0xfffffffful; } else { + __be32 addr32; + rc = opal_get_msi_32(phb->opal_id, pe->mve_number, xive_num, 1, &addr32, &data); if (rc) { @@ -829,9 +867,9 @@ static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, return -EIO; } msg->address_hi = 0; - msg->address_lo = addr32; + msg->address_lo = be32_to_cpu(addr32); } - msg->data = data; + msg->data = be32_to_cpu(data); /* * Change the IRQ chip for the MSI interrupts on PHB3. @@ -1106,8 +1144,8 @@ void __init pnv_pci_init_ioda_phb(struct device_node *np, struct pci_controller *hose; struct pnv_phb *phb; unsigned long size, m32map_off, iomap_off, pemap_off; - const u64 *prop64; - const u32 *prop32; + const __be64 *prop64; + const __be32 *prop32; int len; u64 phb_id; void *aux; @@ -1142,8 +1180,8 @@ void __init pnv_pci_init_ioda_phb(struct device_node *np, spin_lock_init(&phb->lock); prop32 = of_get_property(np, "bus-range", &len); if (prop32 && len == 8) { - hose->first_busno = prop32[0]; - hose->last_busno = prop32[1]; + hose->first_busno = be32_to_cpu(prop32[0]); + hose->last_busno = be32_to_cpu(prop32[1]); } else { pr_warn(" Broken <bus-range> on %s\n", np->full_name); hose->first_busno = 0; @@ -1171,12 +1209,13 @@ void __init pnv_pci_init_ioda_phb(struct device_node *np, pr_err(" Failed to map registers !\n"); /* Initialize more IODA stuff */ + phb->ioda.total_pe = 1; prop32 = of_get_property(np, "ibm,opal-num-pes", NULL); - if (!prop32) - phb->ioda.total_pe = 1; - else - phb->ioda.total_pe = *prop32; - + if (prop32) + phb->ioda.total_pe = be32_to_cpup(prop32); + prop32 = of_get_property(np, "ibm,opal-reserved-pe", NULL); + if (prop32) + phb->ioda.reserved_pe = be32_to_cpup(prop32); phb->ioda.m32_size = resource_size(&hose->mem_resources[0]); /* FW Has already off top 64k of M32 space (MSI space) */ phb->ioda.m32_size += 0x10000; @@ -1205,7 +1244,7 @@ void __init pnv_pci_init_ioda_phb(struct device_node *np, if (phb->type == PNV_PHB_IODA1) phb->ioda.io_segmap = aux + iomap_off; phb->ioda.pe_array = aux + pemap_off; - set_bit(0, phb->ioda.pe_alloc); + set_bit(phb->ioda.reserved_pe, phb->ioda.pe_alloc); INIT_LIST_HEAD(&phb->ioda.pe_dma_list); INIT_LIST_HEAD(&phb->ioda.pe_list); @@ -1230,8 +1269,10 @@ void __init pnv_pci_init_ioda_phb(struct device_node *np, segment_size); #endif - pr_info(" %d PE's M32: 0x%x [segment=0x%x] IO: 0x%x [segment=0x%x]\n", + pr_info(" %d (%d) PE's M32: 0x%x [segment=0x%x]" + " IO: 0x%x [segment=0x%x]\n", phb->ioda.total_pe, + phb->ioda.reserved_pe, phb->ioda.m32_size, phb->ioda.m32_segsize, phb->ioda.io_size, phb->ioda.io_segsize); @@ -1268,13 +1309,6 @@ void __init pnv_pci_init_ioda_phb(struct device_node *np, rc = opal_pci_reset(phb_id, OPAL_PCI_IODA_TABLE_RESET, OPAL_ASSERT_RESET); if (rc) pr_warning(" OPAL Error %ld performing IODA table reset !\n", rc); - - /* - * On IODA1 map everything to PE#0, on IODA2 we assume the IODA reset - * has cleared the RTT which has the same effect - */ - if (ioda_type == PNV_PHB_IODA1) - opal_pci_set_pe(phb_id, 0, 0, 7, 1, 1 , OPAL_MAP_PE); } void __init pnv_pci_init_ioda2_phb(struct device_node *np) @@ -1285,7 +1319,7 @@ void __init pnv_pci_init_ioda2_phb(struct device_node *np) void __init pnv_pci_init_ioda_hub(struct device_node *np) { struct device_node *phbn; - const u64 *prop64; + const __be64 *prop64; u64 hub_id; pr_info("Probing IODA IO-Hub %s\n", np->full_name); diff --git a/arch/powerpc/platforms/powernv/pci-p5ioc2.c b/arch/powerpc/platforms/powernv/pci-p5ioc2.c index b68db6325c1b..f8b4bd8afb2e 100644 --- a/arch/powerpc/platforms/powernv/pci-p5ioc2.c +++ b/arch/powerpc/platforms/powernv/pci-p5ioc2.c @@ -99,7 +99,7 @@ static void __init pnv_pci_init_p5ioc2_phb(struct device_node *np, u64 hub_id, void *tce_mem, u64 tce_size) { struct pnv_phb *phb; - const u64 *prop64; + const __be64 *prop64; u64 phb_id; int64_t rc; static int primary = 1; @@ -178,7 +178,7 @@ static void __init pnv_pci_init_p5ioc2_phb(struct device_node *np, u64 hub_id, void __init pnv_pci_init_p5ioc2_hub(struct device_node *np) { struct device_node *phbn; - const u64 *prop64; + const __be64 *prop64; u64 hub_id; void *tce_mem; uint64_t tce_per_phb; diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index a28d3b5e6393..4eb33a9ed532 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c @@ -236,17 +236,21 @@ static void pnv_pci_config_check_eeh(struct pnv_phb *phb, { s64 rc; u8 fstate; - u16 pcierr; + __be16 pcierr; u32 pe_no; /* * Get the PE#. During the PCI probe stage, we might not * setup that yet. So all ER errors should be mapped to - * PE#0 + * reserved PE. */ pe_no = PCI_DN(dn)->pe_number; - if (pe_no == IODA_INVALID_PE) - pe_no = 0; + if (pe_no == IODA_INVALID_PE) { + if (phb->type == PNV_PHB_P5IOC2) + pe_no = 0; + else + pe_no = phb->ioda.reserved_pe; + } /* Read freeze status */ rc = opal_pci_eeh_freeze_status(phb->opal_id, pe_no, &fstate, &pcierr, @@ -283,16 +287,16 @@ int pnv_pci_cfg_read(struct device_node *dn, break; } case 2: { - u16 v16; + __be16 v16; rc = opal_pci_config_read_half_word(phb->opal_id, bdfn, where, &v16); - *val = (rc == OPAL_SUCCESS) ? v16 : 0xffff; + *val = (rc == OPAL_SUCCESS) ? be16_to_cpu(v16) : 0xffff; break; } case 4: { - u32 v32; + __be32 v32; rc = opal_pci_config_read_word(phb->opal_id, bdfn, where, &v32); - *val = (rc == OPAL_SUCCESS) ? v32 : 0xffffffff; + *val = (rc == OPAL_SUCCESS) ? be32_to_cpu(v32) : 0xffffffff; break; } default: @@ -401,10 +405,10 @@ struct pci_ops pnv_pci_ops = { static int pnv_tce_build(struct iommu_table *tbl, long index, long npages, unsigned long uaddr, enum dma_data_direction direction, - struct dma_attrs *attrs) + struct dma_attrs *attrs, bool rm) { u64 proto_tce; - u64 *tcep, *tces; + __be64 *tcep, *tces; u64 rpn; proto_tce = TCE_PCI_READ; // Read allowed @@ -412,33 +416,48 @@ static int pnv_tce_build(struct iommu_table *tbl, long index, long npages, if (direction != DMA_TO_DEVICE) proto_tce |= TCE_PCI_WRITE; - tces = tcep = ((u64 *)tbl->it_base) + index - tbl->it_offset; + tces = tcep = ((__be64 *)tbl->it_base) + index - tbl->it_offset; rpn = __pa(uaddr) >> TCE_SHIFT; while (npages--) - *(tcep++) = proto_tce | (rpn++ << TCE_RPN_SHIFT); + *(tcep++) = cpu_to_be64(proto_tce | (rpn++ << TCE_RPN_SHIFT)); /* Some implementations won't cache invalid TCEs and thus may not * need that flush. We'll probably turn it_type into a bit mask * of flags if that becomes the case */ if (tbl->it_type & TCE_PCI_SWINV_CREATE) - pnv_pci_ioda_tce_invalidate(tbl, tces, tcep - 1); + pnv_pci_ioda_tce_invalidate(tbl, tces, tcep - 1, rm); return 0; } -static void pnv_tce_free(struct iommu_table *tbl, long index, long npages) +static int pnv_tce_build_vm(struct iommu_table *tbl, long index, long npages, + unsigned long uaddr, + enum dma_data_direction direction, + struct dma_attrs *attrs) { - u64 *tcep, *tces; + return pnv_tce_build(tbl, index, npages, uaddr, direction, attrs, + false); +} - tces = tcep = ((u64 *)tbl->it_base) + index - tbl->it_offset; +static void pnv_tce_free(struct iommu_table *tbl, long index, long npages, + bool rm) +{ + __be64 *tcep, *tces; + + tces = tcep = ((__be64 *)tbl->it_base) + index - tbl->it_offset; while (npages--) - *(tcep++) = 0; + *(tcep++) = cpu_to_be64(0); if (tbl->it_type & TCE_PCI_SWINV_FREE) - pnv_pci_ioda_tce_invalidate(tbl, tces, tcep - 1); + pnv_pci_ioda_tce_invalidate(tbl, tces, tcep - 1, rm); +} + +static void pnv_tce_free_vm(struct iommu_table *tbl, long index, long npages) +{ + pnv_tce_free(tbl, index, npages, false); } static unsigned long pnv_tce_get(struct iommu_table *tbl, long index) @@ -446,6 +465,19 @@ static unsigned long pnv_tce_get(struct iommu_table *tbl, long index) return ((u64 *)tbl->it_base)[index - tbl->it_offset]; } +static int pnv_tce_build_rm(struct iommu_table *tbl, long index, long npages, + unsigned long uaddr, + enum dma_data_direction direction, + struct dma_attrs *attrs) +{ + return pnv_tce_build(tbl, index, npages, uaddr, direction, attrs, true); +} + +static void pnv_tce_free_rm(struct iommu_table *tbl, long index, long npages) +{ + pnv_tce_free(tbl, index, npages, true); +} + void pnv_pci_setup_iommu_table(struct iommu_table *tbl, void *tce_mem, u64 tce_size, u64 dma_offset) @@ -484,8 +516,8 @@ static struct iommu_table *pnv_pci_setup_bml_iommu(struct pci_controller *hose) swinvp = of_get_property(hose->dn, "linux,tce-sw-invalidate-info", NULL); if (swinvp) { - tbl->it_busno = swinvp[1]; - tbl->it_index = (unsigned long)ioremap(swinvp[0], 8); + tbl->it_busno = be64_to_cpu(swinvp[1]); + tbl->it_index = (unsigned long)ioremap(be64_to_cpup(swinvp), 8); tbl->it_type = TCE_PCI_SWINV_CREATE | TCE_PCI_SWINV_FREE; } return tbl; @@ -610,8 +642,10 @@ void __init pnv_pci_init(void) /* Configure IOMMU DMA hooks */ ppc_md.pci_dma_dev_setup = pnv_pci_dma_dev_setup; - ppc_md.tce_build = pnv_tce_build; - ppc_md.tce_free = pnv_tce_free; + ppc_md.tce_build = pnv_tce_build_vm; + ppc_md.tce_free = pnv_tce_free_vm; + ppc_md.tce_build_rm = pnv_tce_build_rm; + ppc_md.tce_free_rm = pnv_tce_free_rm; ppc_md.tce_get = pnv_tce_get; ppc_md.pci_probe_mode = pnv_pci_probe_mode; set_pci_dma_ops(&dma_iommu_ops); diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h index d633c64e05a1..911c24ef033e 100644 --- a/arch/powerpc/platforms/powernv/pci.h +++ b/arch/powerpc/platforms/powernv/pci.h @@ -17,7 +17,7 @@ enum pnv_phb_model { PNV_PHB_MODEL_PHB3, }; -#define PNV_PCI_DIAG_BUF_SIZE 4096 +#define PNV_PCI_DIAG_BUF_SIZE 8192 #define PNV_IODA_PE_DEV (1 << 0) /* PE has single PCI device */ #define PNV_IODA_PE_BUS (1 << 1) /* PE has primary PCI bus */ #define PNV_IODA_PE_BUS_ALL (1 << 2) /* PE has subordinate buses */ @@ -52,6 +52,7 @@ struct pnv_ioda_pe { int tce32_seg; int tce32_segcount; struct iommu_table tce32_table; + phys_addr_t tce_inval_reg_phys; /* XXX TODO: Add support for additional 64-bit iommus */ @@ -124,6 +125,7 @@ struct pnv_phb { struct { /* Global bridge info */ unsigned int total_pe; + unsigned int reserved_pe; unsigned int m32_size; unsigned int m32_segsize; unsigned int m32_pci_base; @@ -193,6 +195,6 @@ extern void pnv_pci_init_p5ioc2_hub(struct device_node *np); extern void pnv_pci_init_ioda_hub(struct device_node *np); extern void pnv_pci_init_ioda2_phb(struct device_node *np); extern void pnv_pci_ioda_tce_invalidate(struct iommu_table *tbl, - u64 *startp, u64 *endp); + __be64 *startp, __be64 *endp, bool rm); #endif /* __POWERNV_PCI_H */ diff --git a/arch/powerpc/platforms/powernv/rng.c b/arch/powerpc/platforms/powernv/rng.c new file mode 100644 index 000000000000..8844628915dc --- /dev/null +++ b/arch/powerpc/platforms/powernv/rng.c @@ -0,0 +1,125 @@ +/* + * Copyright 2013, Michael Ellerman, IBM Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#define pr_fmt(fmt) "powernv-rng: " fmt + +#include <linux/kernel.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_platform.h> +#include <linux/slab.h> +#include <linux/smp.h> +#include <asm/archrandom.h> +#include <asm/io.h> +#include <asm/prom.h> +#include <asm/machdep.h> + + +struct powernv_rng { + void __iomem *regs; + unsigned long mask; +}; + +static DEFINE_PER_CPU(struct powernv_rng *, powernv_rng); + + +static unsigned long rng_whiten(struct powernv_rng *rng, unsigned long val) +{ + unsigned long parity; + + /* Calculate the parity of the value */ + asm ("popcntd %0,%1" : "=r" (parity) : "r" (val)); + + /* xor our value with the previous mask */ + val ^= rng->mask; + + /* update the mask based on the parity of this value */ + rng->mask = (rng->mask << 1) | (parity & 1); + + return val; +} + +int powernv_get_random_long(unsigned long *v) +{ + struct powernv_rng *rng; + + rng = get_cpu_var(powernv_rng); + + *v = rng_whiten(rng, in_be64(rng->regs)); + + put_cpu_var(rng); + + return 1; +} +EXPORT_SYMBOL_GPL(powernv_get_random_long); + +static __init void rng_init_per_cpu(struct powernv_rng *rng, + struct device_node *dn) +{ + int chip_id, cpu; + + chip_id = of_get_ibm_chip_id(dn); + if (chip_id == -1) + pr_warn("No ibm,chip-id found for %s.\n", dn->full_name); + + for_each_possible_cpu(cpu) { + if (per_cpu(powernv_rng, cpu) == NULL || + cpu_to_chip_id(cpu) == chip_id) { + per_cpu(powernv_rng, cpu) = rng; + } + } +} + +static __init int rng_create(struct device_node *dn) +{ + struct powernv_rng *rng; + unsigned long val; + + rng = kzalloc(sizeof(*rng), GFP_KERNEL); + if (!rng) + return -ENOMEM; + + rng->regs = of_iomap(dn, 0); + if (!rng->regs) { + kfree(rng); + return -ENXIO; + } + + val = in_be64(rng->regs); + rng->mask = val; + + rng_init_per_cpu(rng, dn); + + pr_info_once("Registering arch random hook.\n"); + + ppc_md.get_random_long = powernv_get_random_long; + + return 0; +} + +static __init int rng_init(void) +{ + struct device_node *dn; + int rc; + + for_each_compatible_node(dn, NULL, "ibm,power-rng") { + rc = rng_create(dn); + if (rc) { + pr_err("Failed creating rng for %s (%d).\n", + dn->full_name, rc); + continue; + } + + /* Create devices for hwrng driver */ + of_platform_device_create(dn, NULL, NULL); + } + + return 0; +} +subsys_initcall(rng_init); diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c index e239dcfa224c..19884b2a51b4 100644 --- a/arch/powerpc/platforms/powernv/setup.c +++ b/arch/powerpc/platforms/powernv/setup.c @@ -23,6 +23,7 @@ #include <linux/irq.h> #include <linux/seq_file.h> #include <linux/of.h> +#include <linux/of_fdt.h> #include <linux/interrupt.h> #include <linux/bug.h> diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile index 6c61ec5ee914..fbccac9cd2dc 100644 --- a/arch/powerpc/platforms/pseries/Makefile +++ b/arch/powerpc/platforms/pseries/Makefile @@ -3,7 +3,7 @@ ccflags-$(CONFIG_PPC_PSERIES_DEBUG) += -DDEBUG obj-y := lpar.o hvCall.o nvram.o reconfig.o \ setup.o iommu.o event_sources.o ras.o \ - firmware.o power.o dlpar.o mobility.o + firmware.o power.o dlpar.o mobility.o rng.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_SCANLOG) += scanlog.o obj-$(CONFIG_EEH) += eeh_pseries.o diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c index 7cfdaae1721a..a8fe5aa3d34f 100644 --- a/arch/powerpc/platforms/pseries/dlpar.c +++ b/arch/powerpc/platforms/pseries/dlpar.c @@ -404,46 +404,38 @@ static ssize_t dlpar_cpu_probe(const char *buf, size_t count) unsigned long drc_index; int rc; - cpu_hotplug_driver_lock(); rc = strict_strtoul(buf, 0, &drc_index); - if (rc) { - rc = -EINVAL; - goto out; - } + if (rc) + return -EINVAL; parent = of_find_node_by_path("/cpus"); - if (!parent) { - rc = -ENODEV; - goto out; - } + if (!parent) + return -ENODEV; dn = dlpar_configure_connector(drc_index, parent); - if (!dn) { - rc = -EINVAL; - goto out; - } + if (!dn) + return -EINVAL; of_node_put(parent); rc = dlpar_acquire_drc(drc_index); if (rc) { dlpar_free_cc_nodes(dn); - rc = -EINVAL; - goto out; + return -EINVAL; } rc = dlpar_attach_node(dn); if (rc) { dlpar_release_drc(drc_index); dlpar_free_cc_nodes(dn); - goto out; + return rc; } rc = dlpar_online_cpu(dn); -out: - cpu_hotplug_driver_unlock(); + if (rc) + return rc; - return rc ? rc : count; + return count; } static int dlpar_offline_cpu(struct device_node *dn) @@ -516,30 +508,27 @@ static ssize_t dlpar_cpu_release(const char *buf, size_t count) return -EINVAL; } - cpu_hotplug_driver_lock(); rc = dlpar_offline_cpu(dn); if (rc) { of_node_put(dn); - rc = -EINVAL; - goto out; + return -EINVAL; } rc = dlpar_release_drc(*drc_index); if (rc) { of_node_put(dn); - goto out; + return rc; } rc = dlpar_detach_node(dn); if (rc) { dlpar_acquire_drc(*drc_index); - goto out; + return rc; } of_node_put(dn); -out: - cpu_hotplug_driver_unlock(); - return rc ? rc : count; + + return count; } static int __init pseries_dlpar_init(void) diff --git a/arch/powerpc/platforms/pseries/event_sources.c b/arch/powerpc/platforms/pseries/event_sources.c index 2605c310166a..18380e8f6dfe 100644 --- a/arch/powerpc/platforms/pseries/event_sources.c +++ b/arch/powerpc/platforms/pseries/event_sources.c @@ -25,7 +25,7 @@ void request_event_sources_irqs(struct device_node *np, const char *name) { int i, index, count = 0; - struct of_irq oirq; + struct of_phandle_args oirq; const u32 *opicprop; unsigned int opicplen; unsigned int virqs[16]; @@ -55,13 +55,11 @@ void request_event_sources_irqs(struct device_node *np, /* Else use normal interrupt tree parsing */ else { /* First try to do a proper OF tree parsing */ - for (index = 0; of_irq_map_one(np, index, &oirq) == 0; + for (index = 0; of_irq_parse_one(np, index, &oirq) == 0; index++) { if (count > 15) break; - virqs[count] = irq_create_of_mapping(oirq.controller, - oirq.specifier, - oirq.size); + virqs[count] = irq_create_of_mapping(&oirq); if (virqs[count] == NO_IRQ) { pr_err("event-sources: Unable to allocate " "interrupt number for %s\n", diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c index 9a432de363b8..9590dbb756f2 100644 --- a/arch/powerpc/platforms/pseries/hotplug-memory.c +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c @@ -10,12 +10,14 @@ */ #include <linux/of.h> +#include <linux/of_address.h> #include <linux/memblock.h> #include <linux/vmalloc.h> #include <linux/memory.h> #include <asm/firmware.h> #include <asm/machdep.h> +#include <asm/prom.h> #include <asm/sparsemem.h> static unsigned long get_memblock_size(void) diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index 0307901e4132..f253361552ae 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -52,7 +52,7 @@ static void tce_invalidate_pSeries_sw(struct iommu_table *tbl, - u64 *startp, u64 *endp) + __be64 *startp, __be64 *endp) { u64 __iomem *invalidate = (u64 __iomem *)tbl->it_index; unsigned long start, end, inc; @@ -86,7 +86,7 @@ static int tce_build_pSeries(struct iommu_table *tbl, long index, struct dma_attrs *attrs) { u64 proto_tce; - u64 *tcep, *tces; + __be64 *tcep, *tces; u64 rpn; proto_tce = TCE_PCI_READ; // Read allowed @@ -94,12 +94,12 @@ static int tce_build_pSeries(struct iommu_table *tbl, long index, if (direction != DMA_TO_DEVICE) proto_tce |= TCE_PCI_WRITE; - tces = tcep = ((u64 *)tbl->it_base) + index; + tces = tcep = ((__be64 *)tbl->it_base) + index; while (npages--) { /* can't move this out since we might cross MEMBLOCK boundary */ rpn = __pa(uaddr) >> TCE_SHIFT; - *tcep = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT; + *tcep = cpu_to_be64(proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT); uaddr += TCE_PAGE_SIZE; tcep++; @@ -113,9 +113,9 @@ static int tce_build_pSeries(struct iommu_table *tbl, long index, static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages) { - u64 *tcep, *tces; + __be64 *tcep, *tces; - tces = tcep = ((u64 *)tbl->it_base) + index; + tces = tcep = ((__be64 *)tbl->it_base) + index; while (npages--) *(tcep++) = 0; @@ -126,11 +126,11 @@ static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages) static unsigned long tce_get_pseries(struct iommu_table *tbl, long index) { - u64 *tcep; + __be64 *tcep; - tcep = ((u64 *)tbl->it_base) + index; + tcep = ((__be64 *)tbl->it_base) + index; - return *tcep; + return be64_to_cpu(*tcep); } static void tce_free_pSeriesLP(struct iommu_table*, long, long); @@ -177,7 +177,7 @@ static int tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum, return ret; } -static DEFINE_PER_CPU(u64 *, tce_page); +static DEFINE_PER_CPU(__be64 *, tce_page); static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages, unsigned long uaddr, @@ -186,7 +186,7 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, { u64 rc = 0; u64 proto_tce; - u64 *tcep; + __be64 *tcep; u64 rpn; long l, limit; long tcenum_start = tcenum, npages_start = npages; @@ -206,7 +206,7 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, * from iommu_alloc{,_sg}() */ if (!tcep) { - tcep = (u64 *)__get_free_page(GFP_ATOMIC); + tcep = (__be64 *)__get_free_page(GFP_ATOMIC); /* If allocation fails, fall back to the loop implementation */ if (!tcep) { local_irq_restore(flags); @@ -230,7 +230,7 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, limit = min_t(long, npages, 4096/TCE_ENTRY_SIZE); for (l = 0; l < limit; l++) { - tcep[l] = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT; + tcep[l] = cpu_to_be64(proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT); rpn++; } @@ -329,16 +329,16 @@ struct direct_window { /* Dynamic DMA Window support */ struct ddw_query_response { - u32 windows_available; - u32 largest_available_block; - u32 page_size; - u32 migration_capable; + __be32 windows_available; + __be32 largest_available_block; + __be32 page_size; + __be32 migration_capable; }; struct ddw_create_response { - u32 liobn; - u32 addr_hi; - u32 addr_lo; + __be32 liobn; + __be32 addr_hi; + __be32 addr_lo; }; static LIST_HEAD(direct_window_list); @@ -392,7 +392,8 @@ static int tce_setrange_multi_pSeriesLP(unsigned long start_pfn, unsigned long num_pfn, const void *arg) { const struct dynamic_dma_window_prop *maprange = arg; - u64 *tcep, tce_size, num_tce, dma_offset, next, proto_tce, liobn; + u64 tce_size, num_tce, dma_offset, next, proto_tce, liobn; + __be64 *tcep; u32 tce_shift; u64 rc = 0; long l, limit; @@ -401,7 +402,7 @@ static int tce_setrange_multi_pSeriesLP(unsigned long start_pfn, tcep = __get_cpu_var(tce_page); if (!tcep) { - tcep = (u64 *)__get_free_page(GFP_ATOMIC); + tcep = (__be64 *)__get_free_page(GFP_ATOMIC); if (!tcep) { local_irq_enable(); return -ENOMEM; @@ -435,7 +436,7 @@ static int tce_setrange_multi_pSeriesLP(unsigned long start_pfn, dma_offset = next + be64_to_cpu(maprange->dma_base); for (l = 0; l < limit; l++) { - tcep[l] = proto_tce | next; + tcep[l] = cpu_to_be64(proto_tce | next); next += tce_size; } @@ -780,7 +781,7 @@ static u64 find_existing_ddw(struct device_node *pdn) list_for_each_entry(window, &direct_window_list, list) { if (window->device == pdn) { direct64 = window->prop; - dma_addr = direct64->dma_base; + dma_addr = be64_to_cpu(direct64->dma_base); break; } } @@ -1045,11 +1046,11 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn) dev_dbg(&dev->dev, "no free dynamic windows"); goto out_restore_window; } - if (query.page_size & 4) { + if (be32_to_cpu(query.page_size) & 4) { page_shift = 24; /* 16MB */ - } else if (query.page_size & 2) { + } else if (be32_to_cpu(query.page_size) & 2) { page_shift = 16; /* 64kB */ - } else if (query.page_size & 1) { + } else if (be32_to_cpu(query.page_size) & 1) { page_shift = 12; /* 4kB */ } else { dev_dbg(&dev->dev, "no supported direct page size in mask %x", @@ -1059,7 +1060,7 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn) /* verify the window * number of ptes will map the partition */ /* check largest block * page size > max memory hotplug addr */ max_addr = memory_hotplug_max(); - if (query.largest_available_block < (max_addr >> page_shift)) { + if (be32_to_cpu(query.largest_available_block) < (max_addr >> page_shift)) { dev_dbg(&dev->dev, "can't map partiton max 0x%llx with %u " "%llu-sized pages\n", max_addr, query.largest_available_block, 1ULL << page_shift); @@ -1085,7 +1086,7 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn) if (ret != 0) goto out_free_prop; - ddwprop->liobn = cpu_to_be32(create.liobn); + ddwprop->liobn = create.liobn; ddwprop->dma_base = cpu_to_be64(of_read_number(&create.addr_hi, 2)); ddwprop->tce_shift = cpu_to_be32(page_shift); ddwprop->window_shift = cpu_to_be32(len); diff --git a/arch/powerpc/platforms/pseries/nvram.c b/arch/powerpc/platforms/pseries/nvram.c index d276cd3edd8f..7bfaf58d4664 100644 --- a/arch/powerpc/platforms/pseries/nvram.c +++ b/arch/powerpc/platforms/pseries/nvram.c @@ -31,7 +31,7 @@ #define NVRW_CNT 0x20 /* - * Set oops header version to distingush between old and new format header. + * Set oops header version to distinguish between old and new format header. * lnx,oops-log partition max size is 4000, header version > 4000 will * help in identifying new header. */ @@ -429,9 +429,6 @@ static int __init pseries_nvram_init_os_partition(struct nvram_os_partition loff_t p; int size; - /* Scan nvram for partitions */ - nvram_scan_partitions(); - /* Look for ours */ p = nvram_find_partition(part->name, NVRAM_SIG_OS, &size); @@ -795,6 +792,9 @@ static int __init pseries_nvram_init_log_partitions(void) { int rc; + /* Scan nvram for partitions */ + nvram_scan_partitions(); + rc = pseries_nvram_init_os_partition(&rtas_log_partition); nvram_init_oops_partition(rc == 0); return 0; @@ -804,7 +804,7 @@ machine_arch_initcall(pseries, pseries_nvram_init_log_partitions); int __init pSeries_nvram_init(void) { struct device_node *nvram; - const unsigned int *nbytes_p; + const __be32 *nbytes_p; unsigned int proplen; nvram = of_find_node_by_type(NULL, "nvram"); @@ -817,7 +817,7 @@ int __init pSeries_nvram_init(void) return -EIO; } - nvram_size = *nbytes_p; + nvram_size = be32_to_cpup(nbytes_p); nvram_fetch = rtas_token("nvram-fetch"); nvram_store = rtas_token("nvram-store"); diff --git a/arch/powerpc/platforms/pseries/rng.c b/arch/powerpc/platforms/pseries/rng.c new file mode 100644 index 000000000000..a702f1c08242 --- /dev/null +++ b/arch/powerpc/platforms/pseries/rng.c @@ -0,0 +1,44 @@ +/* + * Copyright 2013, Michael Ellerman, IBM Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#define pr_fmt(fmt) "pseries-rng: " fmt + +#include <linux/kernel.h> +#include <linux/of.h> +#include <asm/archrandom.h> +#include <asm/machdep.h> + + +static int pseries_get_random_long(unsigned long *v) +{ + unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; + + if (plpar_hcall(H_RANDOM, retbuf) == H_SUCCESS) { + *v = retbuf[0]; + return 1; + } + + return 0; +} + +static __init int rng_init(void) +{ + struct device_node *dn; + + dn = of_find_compatible_node(NULL, NULL, "ibm,random"); + if (!dn) + return -ENODEV; + + pr_info("Registering arch random hook.\n"); + + ppc_md.get_random_long = pseries_get_random_long; + + return 0; +} +subsys_initcall(rng_init); diff --git a/arch/powerpc/platforms/pseries/suspend.c b/arch/powerpc/platforms/pseries/suspend.c index 5f997e79d570..16a255255d30 100644 --- a/arch/powerpc/platforms/pseries/suspend.c +++ b/arch/powerpc/platforms/pseries/suspend.c @@ -106,7 +106,7 @@ static int pseries_prepare_late(void) atomic_set(&suspend_data.done, 0); atomic_set(&suspend_data.error, 0); suspend_data.complete = &suspend_work; - INIT_COMPLETION(suspend_work); + reinit_completion(&suspend_work); return 0; } diff --git a/arch/powerpc/platforms/wsp/scom_smp.c b/arch/powerpc/platforms/wsp/scom_smp.c index b56b70aeb497..268bc899c1f7 100644 --- a/arch/powerpc/platforms/wsp/scom_smp.c +++ b/arch/powerpc/platforms/wsp/scom_smp.c @@ -116,7 +116,14 @@ static int a2_scom_ram(scom_map_t scom, int thread, u32 insn, int extmask) scom_write(scom, SCOM_RAMIC, cmd); - while (!((val = scom_read(scom, SCOM_RAMC)) & mask)) { + for (;;) { + if (scom_read(scom, SCOM_RAMC, &val) != 0) { + pr_err("SCOM error on instruction 0x%08x, thread %d\n", + insn, thread); + return -1; + } + if (val & mask) + break; pr_devel("Waiting on RAMC = 0x%llx\n", val); if (++n == 3) { pr_err("RAMC timeout on instruction 0x%08x, thread %d\n", @@ -151,9 +158,7 @@ static int a2_scom_getgpr(scom_map_t scom, int thread, int gpr, int alt, if (rc) return rc; - *out_gpr = scom_read(scom, SCOM_RAMD); - - return 0; + return scom_read(scom, SCOM_RAMD, out_gpr); } static int a2_scom_getspr(scom_map_t scom, int thread, int spr, u64 *out_spr) @@ -353,7 +358,10 @@ int a2_scom_startup_cpu(unsigned int lcpu, int thr_idx, struct device_node *np) pr_devel("Bringing up CPU%d using SCOM...\n", lcpu); - pccr0 = scom_read(scom, SCOM_PCCR0); + if (scom_read(scom, SCOM_PCCR0, &pccr0) != 0) { + printk(KERN_ERR "XSCOM failure readng PCCR0 on CPU%d\n", lcpu); + return -1; + } scom_write(scom, SCOM_PCCR0, pccr0 | SCOM_PCCR0_ENABLE_DEBUG | SCOM_PCCR0_ENABLE_RAM); diff --git a/arch/powerpc/platforms/wsp/scom_wsp.c b/arch/powerpc/platforms/wsp/scom_wsp.c index 4052e2259f30..8928507affea 100644 --- a/arch/powerpc/platforms/wsp/scom_wsp.c +++ b/arch/powerpc/platforms/wsp/scom_wsp.c @@ -50,18 +50,22 @@ static void wsp_scom_unmap(scom_map_t map) iounmap((void *)map); } -static u64 wsp_scom_read(scom_map_t map, u32 reg) +static int wsp_scom_read(scom_map_t map, u64 reg, u64 *value) { u64 __iomem *addr = (u64 __iomem *)map; - return in_be64(addr + reg); + *value = in_be64(addr + reg); + + return 0; } -static void wsp_scom_write(scom_map_t map, u32 reg, u64 value) +static int wsp_scom_write(scom_map_t map, u64 reg, u64 value) { u64 __iomem *addr = (u64 __iomem *)map; - return out_be64(addr + reg, value); + out_be64(addr + reg, value); + + return 0; } static const struct scom_controller wsp_scom_controller = { diff --git a/arch/powerpc/platforms/wsp/wsp.c b/arch/powerpc/platforms/wsp/wsp.c index d25cc96c21b8..ddb6efe88914 100644 --- a/arch/powerpc/platforms/wsp/wsp.c +++ b/arch/powerpc/platforms/wsp/wsp.c @@ -89,6 +89,7 @@ void wsp_halt(void) struct device_node *dn; struct device_node *mine; struct device_node *me; + int rc; me = of_get_cpu_node(smp_processor_id(), NULL); mine = scom_find_parent(me); @@ -101,15 +102,15 @@ void wsp_halt(void) /* read-modify-write it so the HW probe does not get * confused */ - val = scom_read(m, 0); - val |= 1; - scom_write(m, 0, val); + rc = scom_read(m, 0, &val); + if (rc == 0) + scom_write(m, 0, val | 1); scom_unmap(m); } m = scom_map(mine, 0, 1); - val = scom_read(m, 0); - val |= 1; - scom_write(m, 0, val); + rc = scom_read(m, 0, &val); + if (rc == 0) + scom_write(m, 0, val | 1); /* should never return */ scom_unmap(m); } diff --git a/arch/powerpc/sysdev/Kconfig b/arch/powerpc/sysdev/Kconfig index ab4cb5476472..13ec968be4c7 100644 --- a/arch/powerpc/sysdev/Kconfig +++ b/arch/powerpc/sysdev/Kconfig @@ -28,7 +28,7 @@ config PPC_SCOM config SCOM_DEBUGFS bool "Expose SCOM controllers via debugfs" - depends on PPC_SCOM + depends on PPC_SCOM && DEBUG_FS default n config GE_FPGA diff --git a/arch/powerpc/sysdev/cpm_common.c b/arch/powerpc/sysdev/cpm_common.c index 4dd534194ae8..4f7869571290 100644 --- a/arch/powerpc/sysdev/cpm_common.c +++ b/arch/powerpc/sysdev/cpm_common.c @@ -22,6 +22,7 @@ #include <linux/spinlock.h> #include <linux/export.h> #include <linux/of.h> +#include <linux/of_address.h> #include <linux/slab.h> #include <asm/udbg.h> diff --git a/arch/powerpc/sysdev/ehv_pic.c b/arch/powerpc/sysdev/ehv_pic.c index 9cd0e60716fe..b74085cea1af 100644 --- a/arch/powerpc/sysdev/ehv_pic.c +++ b/arch/powerpc/sysdev/ehv_pic.c @@ -19,6 +19,7 @@ #include <linux/slab.h> #include <linux/spinlock.h> #include <linux/of.h> +#include <linux/of_address.h> #include <asm/io.h> #include <asm/irq.h> diff --git a/arch/powerpc/sysdev/fsl_gtm.c b/arch/powerpc/sysdev/fsl_gtm.c index 0eb871cc3437..06ac3c61b3d0 100644 --- a/arch/powerpc/sysdev/fsl_gtm.c +++ b/arch/powerpc/sysdev/fsl_gtm.c @@ -19,6 +19,8 @@ #include <linux/list.h> #include <linux/io.h> #include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> #include <linux/spinlock.h> #include <linux/bitops.h> #include <linux/slab.h> @@ -401,16 +403,15 @@ static int __init fsl_gtm_init(void) gtm->clock = *clock; for (i = 0; i < ARRAY_SIZE(gtm->timers); i++) { - int ret; - struct resource irq; + unsigned int irq; - ret = of_irq_to_resource(np, i, &irq); - if (ret == NO_IRQ) { + irq = irq_of_parse_and_map(np, i); + if (irq == NO_IRQ) { pr_err("%s: not enough interrupts specified\n", np->full_name); goto err; } - gtm->timers[i].irq = irq.start; + gtm->timers[i].irq = irq; gtm->timers[i].gtm = gtm; } diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index ccfb50ddfe38..4dfd61df8aba 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -40,12 +40,12 @@ static int fsl_pcie_bus_fixup, is_mpc83xx_pci; -static void quirk_fsl_pcie_header(struct pci_dev *dev) +static void quirk_fsl_pcie_early(struct pci_dev *dev) { u8 hdr_type; /* if we aren't a PCIe don't bother */ - if (!pci_find_capability(dev, PCI_CAP_ID_EXP)) + if (!pci_is_pcie(dev)) return; /* if we aren't in host mode don't bother */ @@ -562,7 +562,8 @@ no_bridge: } #endif /* CONFIG_FSL_SOC_BOOKE || CONFIG_PPC_86xx */ -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID, quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID, + quirk_fsl_pcie_early); #if defined(CONFIG_PPC_83xx) || defined(CONFIG_PPC_MPC512x) struct mpc83xx_pcie_priv { diff --git a/arch/powerpc/sysdev/fsl_pmc.c b/arch/powerpc/sysdev/fsl_pmc.c index 592a0f8d527a..8cf4aa0e3a25 100644 --- a/arch/powerpc/sysdev/fsl_pmc.c +++ b/arch/powerpc/sysdev/fsl_pmc.c @@ -18,6 +18,7 @@ #include <linux/suspend.h> #include <linux/delay.h> #include <linux/device.h> +#include <linux/of_address.h> #include <linux/of_platform.h> struct pmc_regs { diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index e2fb3171f41b..95dd892e9904 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c @@ -28,6 +28,8 @@ #include <linux/dma-mapping.h> #include <linux/interrupt.h> #include <linux/device.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> #include <linux/of_platform.h> #include <linux/delay.h> #include <linux/slab.h> diff --git a/arch/powerpc/sysdev/fsl_rmu.c b/arch/powerpc/sysdev/fsl_rmu.c index 14bd5221f28a..00e224a1048c 100644 --- a/arch/powerpc/sysdev/fsl_rmu.c +++ b/arch/powerpc/sysdev/fsl_rmu.c @@ -27,6 +27,7 @@ #include <linux/types.h> #include <linux/dma-mapping.h> #include <linux/interrupt.h> +#include <linux/of_irq.h> #include <linux/of_platform.h> #include <linux/slab.h> diff --git a/arch/powerpc/sysdev/fsl_soc.h b/arch/powerpc/sysdev/fsl_soc.h index c6d00736f07f..4c5a19ef4f0b 100644 --- a/arch/powerpc/sysdev/fsl_soc.h +++ b/arch/powerpc/sysdev/fsl_soc.h @@ -21,8 +21,6 @@ struct device_node; extern void fsl_rstcr_restart(char *cmd); -#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE) - /* The different ports that the DIU can be connected to */ enum fsl_diu_monitor_port { FSL_DIU_PORT_DVI, /* DVI */ @@ -43,7 +41,6 @@ struct platform_diu_data_ops { }; extern struct platform_diu_data_ops diu_ops; -#endif void fsl_hv_restart(char *cmd); void fsl_hv_halt(void); diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 1be54faf60dd..0e166ed4cd16 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -535,7 +535,7 @@ static void __init mpic_scan_ht_pic(struct mpic *mpic, u8 __iomem *devbase, mpic->fixups[irq].data = readl(base + 4) | 0x80000000; } } - + static void __init mpic_scan_ht_pics(struct mpic *mpic) { @@ -1088,8 +1088,14 @@ static int mpic_host_map(struct irq_domain *h, unsigned int virq, * is done here. */ if (!mpic_is_ipi(mpic, hw) && (mpic->flags & MPIC_NO_RESET)) { + int cpu; + + preempt_disable(); + cpu = mpic_processor_id(mpic); + preempt_enable(); + mpic_set_vector(virq, hw); - mpic_set_destination(virq, mpic_processor_id(mpic)); + mpic_set_destination(virq, cpu); mpic_irq_set_priority(virq, 8); } @@ -1475,7 +1481,7 @@ struct mpic * __init mpic_alloc(struct device_node *node, * as a default instead of the value read from the HW. */ last_irq = (greg_feature & MPIC_GREG_FEATURE_LAST_SRC_MASK) - >> MPIC_GREG_FEATURE_LAST_SRC_SHIFT; + >> MPIC_GREG_FEATURE_LAST_SRC_SHIFT; if (isu_size) last_irq = isu_size * MPIC_MAX_ISU - 1; of_property_read_u32(mpic->node, "last-interrupt-source", &last_irq); @@ -1625,7 +1631,7 @@ void __init mpic_init(struct mpic *mpic) /* start with vector = source number, and masked */ u32 vecpri = MPIC_VECPRI_MASK | i | (8 << MPIC_VECPRI_PRIORITY_SHIFT); - + /* check if protected */ if (mpic->protected && test_bit(i, mpic->protected)) continue; @@ -1634,7 +1640,7 @@ void __init mpic_init(struct mpic *mpic) mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION), 1 << cpu); } } - + /* Init spurious vector */ mpic_write(mpic->gregs, MPIC_INFO(GREG_SPURIOUS), mpic->spurious_vec); diff --git a/arch/powerpc/sysdev/mpic_msgr.c b/arch/powerpc/sysdev/mpic_msgr.c index c75325865a85..2c9b52aa266c 100644 --- a/arch/powerpc/sysdev/mpic_msgr.c +++ b/arch/powerpc/sysdev/mpic_msgr.c @@ -237,15 +237,13 @@ static int mpic_msgr_probe(struct platform_device *dev) raw_spin_lock_init(&msgr->lock); if (receive_mask & (1 << i)) { - struct resource irq; - - if (of_irq_to_resource(np, irq_index, &irq) == NO_IRQ) { + msgr->irq = irq_of_parse_and_map(np, irq_index); + if (msgr->irq == NO_IRQ) { dev_err(&dev->dev, "Missing interrupt specifier"); kfree(msgr); return -EFAULT; } - msgr->irq = irq.start; irq_index += 1; } else { msgr->irq = NO_IRQ; diff --git a/arch/powerpc/sysdev/mpic_msi.c b/arch/powerpc/sysdev/mpic_msi.c index bbf342c88314..7dc39f35a4cc 100644 --- a/arch/powerpc/sysdev/mpic_msi.c +++ b/arch/powerpc/sysdev/mpic_msi.c @@ -35,7 +35,7 @@ static int mpic_msi_reserve_u3_hwirqs(struct mpic *mpic) const struct irq_domain_ops *ops = mpic->irqhost->ops; struct device_node *np; int flags, index, i; - struct of_irq oirq; + struct of_phandle_args oirq; pr_debug("mpic: found U3, guessing msi allocator setup\n"); @@ -63,9 +63,9 @@ static int mpic_msi_reserve_u3_hwirqs(struct mpic *mpic) pr_debug("mpic: mapping hwirqs for %s\n", np->full_name); index = 0; - while (of_irq_map_one(np, index++, &oirq) == 0) { - ops->xlate(mpic->irqhost, NULL, oirq.specifier, - oirq.size, &hwirq, &flags); + while (of_irq_parse_one(np, index++, &oirq) == 0) { + ops->xlate(mpic->irqhost, NULL, oirq.args, + oirq.args_count, &hwirq, &flags); msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, hwirq); } } diff --git a/arch/powerpc/sysdev/mpic_timer.c b/arch/powerpc/sysdev/mpic_timer.c index c06db92a4fb1..22d7d57eead9 100644 --- a/arch/powerpc/sysdev/mpic_timer.c +++ b/arch/powerpc/sysdev/mpic_timer.c @@ -19,7 +19,9 @@ #include <linux/interrupt.h> #include <linux/slab.h> #include <linux/of.h> +#include <linux/of_address.h> #include <linux/of_device.h> +#include <linux/of_irq.h> #include <linux/syscore_ops.h> #include <sysdev/fsl_soc.h> #include <asm/io.h> diff --git a/arch/powerpc/sysdev/mv64x60_dev.c b/arch/powerpc/sysdev/mv64x60_dev.c index 4a25c26f0bf4..a3a8fad8537d 100644 --- a/arch/powerpc/sysdev/mv64x60_dev.c +++ b/arch/powerpc/sysdev/mv64x60_dev.c @@ -228,7 +228,7 @@ static struct platform_device * __init mv64x60_eth_register_shared_pdev( if (id == 0) { pdev = platform_device_register_simple("orion-mdio", -1, &r[1], 1); - if (!pdev) + if (IS_ERR(pdev)) return pdev; } diff --git a/arch/powerpc/sysdev/of_rtc.c b/arch/powerpc/sysdev/of_rtc.c index c9e803f3e267..6f54b54b1328 100644 --- a/arch/powerpc/sysdev/of_rtc.c +++ b/arch/powerpc/sysdev/of_rtc.c @@ -11,6 +11,7 @@ #include <linux/kernel.h> #include <linux/of.h> #include <linux/init.h> +#include <linux/of_address.h> #include <linux/of_platform.h> #include <linux/slab.h> diff --git a/arch/powerpc/sysdev/ppc4xx_ocm.c b/arch/powerpc/sysdev/ppc4xx_ocm.c index 1b15f93479c3..b7c43453236d 100644 --- a/arch/powerpc/sysdev/ppc4xx_ocm.c +++ b/arch/powerpc/sysdev/ppc4xx_ocm.c @@ -26,6 +26,7 @@ #include <linux/kernel.h> #include <linux/dma-mapping.h> #include <linux/of.h> +#include <linux/of_address.h> #include <asm/rheap.h> #include <asm/ppc4xx_ocm.h> #include <linux/slab.h> diff --git a/arch/powerpc/sysdev/ppc4xx_soc.c b/arch/powerpc/sysdev/ppc4xx_soc.c index 0debcc31ad70..5c77c9ba33aa 100644 --- a/arch/powerpc/sysdev/ppc4xx_soc.c +++ b/arch/powerpc/sysdev/ppc4xx_soc.c @@ -19,6 +19,7 @@ #include <linux/errno.h> #include <linux/interrupt.h> #include <linux/irq.h> +#include <linux/of_irq.h> #include <linux/of_platform.h> #include <asm/dcr.h> diff --git a/arch/powerpc/sysdev/scom.c b/arch/powerpc/sysdev/scom.c index 9193e12df695..6f5a8d177c42 100644 --- a/arch/powerpc/sysdev/scom.c +++ b/arch/powerpc/sysdev/scom.c @@ -25,6 +25,7 @@ #include <asm/debug.h> #include <asm/prom.h> #include <asm/scom.h> +#include <asm/uaccess.h> const struct scom_controller *scom_controller; EXPORT_SYMBOL_GPL(scom_controller); @@ -53,7 +54,7 @@ scom_map_t scom_map_device(struct device_node *dev, int index) { struct device_node *parent; unsigned int cells, size; - const u32 *prop; + const __be32 *prop, *sprop; u64 reg, cnt; scom_map_t ret; @@ -62,12 +63,24 @@ scom_map_t scom_map_device(struct device_node *dev, int index) if (parent == NULL) return 0; - prop = of_get_property(parent, "#scom-cells", NULL); - cells = prop ? *prop : 1; - + /* + * We support "scom-reg" properties for adding scom registers + * to a random device-tree node with an explicit scom-parent + * + * We also support the simple "reg" property if the device is + * a direct child of a scom controller. + * + * In case both exist, "scom-reg" takes precedence. + */ prop = of_get_property(dev, "scom-reg", &size); + sprop = of_get_property(parent, "#scom-cells", NULL); + if (!prop && parent == dev->parent) { + prop = of_get_property(dev, "reg", &size); + sprop = of_get_property(parent, "#address-cells", NULL); + } if (!prop) - return 0; + return NULL; + cells = sprop ? be32_to_cpup(sprop) : 1; size >>= 2; if (index >= (size / (2*cells))) @@ -86,62 +99,89 @@ EXPORT_SYMBOL_GPL(scom_map_device); #ifdef CONFIG_SCOM_DEBUGFS struct scom_debug_entry { struct device_node *dn; - unsigned long addr; - scom_map_t map; - spinlock_t lock; - char name[8]; - struct debugfs_blob_wrapper blob; + struct debugfs_blob_wrapper path; + char name[16]; }; -static int scom_addr_set(void *data, u64 val) +static ssize_t scom_debug_read(struct file *filp, char __user *ubuf, + size_t count, loff_t *ppos) { - struct scom_debug_entry *ent = data; - - ent->addr = 0; - scom_unmap(ent->map); - - ent->map = scom_map(ent->dn, val, 1); - if (scom_map_ok(ent->map)) - ent->addr = val; - else - return -EFAULT; - - return 0; -} - -static int scom_addr_get(void *data, u64 *val) -{ - struct scom_debug_entry *ent = data; - *val = ent->addr; - return 0; + struct scom_debug_entry *ent = filp->private_data; + u64 __user *ubuf64 = (u64 __user *)ubuf; + loff_t off = *ppos; + ssize_t done = 0; + u64 reg, reg_cnt, val; + scom_map_t map; + int rc; + + if (off < 0 || (off & 7) || (count & 7)) + return -EINVAL; + reg = off >> 3; + reg_cnt = count >> 3; + + map = scom_map(ent->dn, reg, reg_cnt); + if (!scom_map_ok(map)) + return -ENXIO; + + for (reg = 0; reg < reg_cnt; reg++) { + rc = scom_read(map, reg, &val); + if (!rc) + rc = put_user(val, ubuf64); + if (rc) { + if (!done) + done = rc; + break; + } + ubuf64++; + *ppos += 8; + done += 8; + } + scom_unmap(map); + return done; } -DEFINE_SIMPLE_ATTRIBUTE(scom_addr_fops, scom_addr_get, scom_addr_set, - "0x%llx\n"); -static int scom_val_set(void *data, u64 val) +static ssize_t scom_debug_write(struct file* filp, const char __user *ubuf, + size_t count, loff_t *ppos) { - struct scom_debug_entry *ent = data; - - if (!scom_map_ok(ent->map)) - return -EFAULT; - - scom_write(ent->map, 0, val); - - return 0; + struct scom_debug_entry *ent = filp->private_data; + u64 __user *ubuf64 = (u64 __user *)ubuf; + loff_t off = *ppos; + ssize_t done = 0; + u64 reg, reg_cnt, val; + scom_map_t map; + int rc; + + if (off < 0 || (off & 7) || (count & 7)) + return -EINVAL; + reg = off >> 3; + reg_cnt = count >> 3; + + map = scom_map(ent->dn, reg, reg_cnt); + if (!scom_map_ok(map)) + return -ENXIO; + + for (reg = 0; reg < reg_cnt; reg++) { + rc = get_user(val, ubuf64); + if (!rc) + rc = scom_write(map, reg, val); + if (rc) { + if (!done) + done = rc; + break; + } + ubuf64++; + done += 8; + } + scom_unmap(map); + return done; } -static int scom_val_get(void *data, u64 *val) -{ - struct scom_debug_entry *ent = data; - - if (!scom_map_ok(ent->map)) - return -EFAULT; - - *val = scom_read(ent->map, 0); - return 0; -} -DEFINE_SIMPLE_ATTRIBUTE(scom_val_fops, scom_val_get, scom_val_set, - "0x%llx\n"); +static const struct file_operations scom_debug_fops = { + .read = scom_debug_read, + .write = scom_debug_write, + .open = simple_open, + .llseek = default_llseek, +}; static int scom_debug_init_one(struct dentry *root, struct device_node *dn, int i) @@ -154,11 +194,9 @@ static int scom_debug_init_one(struct dentry *root, struct device_node *dn, return -ENOMEM; ent->dn = of_node_get(dn); - ent->map = SCOM_MAP_INVALID; - spin_lock_init(&ent->lock); - snprintf(ent->name, 8, "scom%d", i); - ent->blob.data = (void*) dn->full_name; - ent->blob.size = strlen(dn->full_name); + snprintf(ent->name, 16, "%08x", i); + ent->path.data = (void*) dn->full_name; + ent->path.size = strlen(dn->full_name); dir = debugfs_create_dir(ent->name, root); if (!dir) { @@ -167,9 +205,8 @@ static int scom_debug_init_one(struct dentry *root, struct device_node *dn, return -1; } - debugfs_create_file("addr", 0600, dir, ent, &scom_addr_fops); - debugfs_create_file("value", 0600, dir, ent, &scom_val_fops); - debugfs_create_blob("path", 0400, dir, &ent->blob); + debugfs_create_blob("devspec", 0400, dir, &ent->path); + debugfs_create_file("access", 0600, dir, ent, &scom_debug_fops); return 0; } @@ -185,8 +222,13 @@ static int scom_debug_init(void) return -1; i = rc = 0; - for_each_node_with_property(dn, "scom-controller") - rc |= scom_debug_init_one(root, dn, i++); + for_each_node_with_property(dn, "scom-controller") { + int id = of_get_ibm_chip_id(dn); + if (id == -1) + id = i; + rc |= scom_debug_init_one(root, dn, id); + i++; + } return rc; } diff --git a/arch/powerpc/sysdev/xics/ics-opal.c b/arch/powerpc/sysdev/xics/ics-opal.c index 39d72212655e..3c6ee1b64e5d 100644 --- a/arch/powerpc/sysdev/xics/ics-opal.c +++ b/arch/powerpc/sysdev/xics/ics-opal.c @@ -112,6 +112,7 @@ static int ics_opal_set_affinity(struct irq_data *d, bool force) { unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d); + __be16 oserver; int16_t server; int8_t priority; int64_t rc; @@ -120,13 +121,13 @@ static int ics_opal_set_affinity(struct irq_data *d, if (hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS) return -1; - rc = opal_get_xive(hw_irq, &server, &priority); + rc = opal_get_xive(hw_irq, &oserver, &priority); if (rc != OPAL_SUCCESS) { - pr_err("%s: opal_set_xive(irq=%d [hw 0x%x] server=%x)" - " error %lld\n", - __func__, d->irq, hw_irq, server, rc); + pr_err("%s: opal_get_xive(irq=%d [hw 0x%x]) error %lld\n", + __func__, d->irq, hw_irq, rc); return -1; } + server = be16_to_cpu(oserver); wanted_server = xics_get_irq_server(d->irq, cpumask, 1); if (wanted_server < 0) { @@ -181,7 +182,7 @@ static int ics_opal_map(struct ics *ics, unsigned int virq) { unsigned int hw_irq = (unsigned int)virq_to_hw(virq); int64_t rc; - int16_t server; + __be16 server; int8_t priority; if (WARN_ON(hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS)) @@ -201,7 +202,7 @@ static int ics_opal_map(struct ics *ics, unsigned int virq) static void ics_opal_mask_unknown(struct ics *ics, unsigned long vec) { int64_t rc; - int16_t server; + __be16 server; int8_t priority; /* Check if HAL knows about this interrupt */ @@ -215,14 +216,14 @@ static void ics_opal_mask_unknown(struct ics *ics, unsigned long vec) static long ics_opal_get_server(struct ics *ics, unsigned long vec) { int64_t rc; - int16_t server; + __be16 server; int8_t priority; /* Check if HAL knows about this interrupt */ rc = opal_get_xive(vec, &server, &priority); if (rc != OPAL_SUCCESS) return -1; - return ics_opal_unmangle_server(server); + return ics_opal_unmangle_server(be16_to_cpu(server)); } int __init ics_opal_init(void) diff --git a/arch/powerpc/sysdev/xilinx_intc.c b/arch/powerpc/sysdev/xilinx_intc.c index 8d73c3c0bee6..83f943a8e0db 100644 --- a/arch/powerpc/sysdev/xilinx_intc.c +++ b/arch/powerpc/sysdev/xilinx_intc.c @@ -23,6 +23,8 @@ #include <linux/kernel.h> #include <linux/irq.h> #include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> #include <asm/io.h> #include <asm/processor.h> #include <asm/i8259.h> diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 7143793859fa..314fced4fc14 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -99,6 +99,7 @@ config S390 select CLONE_BACKWARDS2 select GENERIC_CLOCKEVENTS select GENERIC_CPU_DEVICES if !SMP + select GENERIC_FIND_FIRST_BIT select GENERIC_SMP_IDLE_THREAD select GENERIC_TIME_VSYSCALL_OLD select HAVE_ALIGNED_STRUCT_PAGE if SLUB @@ -140,7 +141,6 @@ config S390 select OLD_SIGACTION select OLD_SIGSUSPEND3 select SYSCTL_EXCEPTION_TRACE - select USE_GENERIC_SMP_HELPERS if SMP select VIRT_CPU_ACCOUNTING select VIRT_TO_BUS @@ -237,6 +237,67 @@ config MARCH_ZEC12 endchoice +config MARCH_G5_TUNE + def_bool TUNE_G5 || MARCH_G5 && TUNE_DEFAULT + +config MARCH_Z900_TUNE + def_bool TUNE_Z900 || MARCH_Z900 && TUNE_DEFAULT + +config MARCH_Z990_TUNE + def_bool TUNE_Z990 || MARCH_Z990 && TUNE_DEFAULT + +config MARCH_Z9_109_TUNE + def_bool TUNE_Z9_109 || MARCH_Z9_109 && TUNE_DEFAULT + +config MARCH_Z10_TUNE + def_bool TUNE_Z10 || MARCH_Z10 && TUNE_DEFAULT + +config MARCH_Z196_TUNE + def_bool TUNE_Z196 || MARCH_Z196 && TUNE_DEFAULT + +config MARCH_ZEC12_TUNE + def_bool TUNE_ZEC12 || MARCH_ZEC12 && TUNE_DEFAULT + +choice + prompt "Tune code generation" + default TUNE_DEFAULT + help + Cause the compiler to tune (-mtune) the generated code for a machine. + This will make the code run faster on the selected machine but + somewhat slower on other machines. + This option only changes how the compiler emits instructions, not the + selection of instructions itself, so the resulting kernel will run on + all other machines. + +config TUNE_DEFAULT + bool "Default" + help + Tune the generated code for the target processor for which the kernel + will be compiled. + +config TUNE_G5 + bool "System/390 model G5 and G6" + +config TUNE_Z900 + bool "IBM zSeries model z800 and z900" + +config TUNE_Z990 + bool "IBM zSeries model z890 and z990" + +config TUNE_Z9_109 + bool "IBM System z9" + +config TUNE_Z10 + bool "IBM System z10" + +config TUNE_Z196 + bool "IBM zEnterprise 114 and 196" + +config TUNE_ZEC12 + bool "IBM zBC12 and zEC12" + +endchoice + config 64BIT def_bool y prompt "64 bit kernel" diff --git a/arch/s390/Makefile b/arch/s390/Makefile index a7d68a467ce8..874e6d6e9c5f 100644 --- a/arch/s390/Makefile +++ b/arch/s390/Makefile @@ -35,13 +35,21 @@ endif export LD_BFD -cflags-$(CONFIG_MARCH_G5) += $(call cc-option,-march=g5) -cflags-$(CONFIG_MARCH_Z900) += $(call cc-option,-march=z900) -cflags-$(CONFIG_MARCH_Z990) += $(call cc-option,-march=z990) -cflags-$(CONFIG_MARCH_Z9_109) += $(call cc-option,-march=z9-109) -cflags-$(CONFIG_MARCH_Z10) += $(call cc-option,-march=z10) -cflags-$(CONFIG_MARCH_Z196) += $(call cc-option,-march=z196) -cflags-$(CONFIG_MARCH_ZEC12) += $(call cc-option,-march=zEC12) +cflags-$(CONFIG_MARCH_G5) += -march=g5 +cflags-$(CONFIG_MARCH_Z900) += -march=z900 +cflags-$(CONFIG_MARCH_Z990) += -march=z990 +cflags-$(CONFIG_MARCH_Z9_109) += -march=z9-109 +cflags-$(CONFIG_MARCH_Z10) += -march=z10 +cflags-$(CONFIG_MARCH_Z196) += -march=z196 +cflags-$(CONFIG_MARCH_ZEC12) += -march=zEC12 + +cflags-$(CONFIG_MARCH_G5_TUNE) += -mtune=g5 +cflags-$(CONFIG_MARCH_Z900_TUNE) += -mtune=z900 +cflags-$(CONFIG_MARCH_Z990_TUNE) += -mtune=z990 +cflags-$(CONFIG_MARCH_Z9_109_TUNE) += -mtune=z9-109 +cflags-$(CONFIG_MARCH_Z10_TUNE) += -mtune=z10 +cflags-$(CONFIG_MARCH_Z196_TUNE) += -mtune=z196 +cflags-$(CONFIG_MARCH_ZEC12_TUNE) += -mtune=zEC12 #KBUILD_IMAGE is necessary for make rpm KBUILD_IMAGE :=arch/s390/boot/image diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c index 87a22092b68f..4c4a1cef5208 100644 --- a/arch/s390/appldata/appldata_base.c +++ b/arch/s390/appldata/appldata_base.c @@ -48,9 +48,9 @@ static struct platform_device *appldata_pdev; * /proc entries (sysctl) */ static const char appldata_proc_name[APPLDATA_PROC_NAME_LENGTH] = "appldata"; -static int appldata_timer_handler(ctl_table *ctl, int write, +static int appldata_timer_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos); -static int appldata_interval_handler(ctl_table *ctl, int write, +static int appldata_interval_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos); @@ -201,10 +201,10 @@ static void __appldata_vtimer_setup(int cmd) * Start/Stop timer, show status of timer (0 = not active, 1 = active) */ static int -appldata_timer_handler(ctl_table *ctl, int write, +appldata_timer_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { - int len; + unsigned int len; char buf[2]; if (!*lenp || *ppos) { @@ -243,10 +243,11 @@ out: * current timer interval. */ static int -appldata_interval_handler(ctl_table *ctl, int write, +appldata_interval_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { - int len, interval; + unsigned int len; + int interval; char buf[16]; if (!*lenp || *ppos) { @@ -286,11 +287,12 @@ out: * monitoring (0 = not in process, 1 = in process) */ static int -appldata_generic_handler(ctl_table *ctl, int write, +appldata_generic_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { struct appldata_ops *ops = NULL, *tmp_ops; - int rc, len, found; + unsigned int len; + int rc, found; char buf[2]; struct list_head *lh; diff --git a/arch/s390/boot/Makefile b/arch/s390/boot/Makefile index f2737a005afc..9a42ecec5647 100644 --- a/arch/s390/boot/Makefile +++ b/arch/s390/boot/Makefile @@ -21,6 +21,6 @@ $(obj)/bzImage: $(obj)/compressed/vmlinux FORCE $(obj)/compressed/vmlinux: FORCE $(Q)$(MAKE) $(build)=$(obj)/compressed $@ -install: $(CONFIGURE) $(obj)/image - sh -x $(srctree)/$(obj)/install.sh $(KERNELRELEASE) $(obj)/image \ +install: $(CONFIGURE) $(obj)/bzImage + sh -x $(srctree)/$(obj)/install.sh $(KERNELRELEASE) $(obj)/bzImage \ System.map "$(INSTALL_PATH)" diff --git a/arch/s390/configs/default_defconfig b/arch/s390/configs/default_defconfig new file mode 100644 index 000000000000..e0af2ee58751 --- /dev/null +++ b/arch/s390/configs/default_defconfig @@ -0,0 +1,655 @@ +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_FHANDLE=y +CONFIG_AUDIT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_TASKSTATS=y +CONFIG_TASK_DELAY_ACCT=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_RCU_FAST_NO_HZ=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CPUSETS=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_RESOURCE_COUNTERS=y +CONFIG_CGROUP_PERF=y +CONFIG_CFS_BANDWIDTH=y +CONFIG_RT_GROUP_SCHED=y +CONFIG_BLK_CGROUP=y +CONFIG_SCHED_AUTOGROUP=y +CONFIG_BLK_DEV_INITRD=y +# CONFIG_COMPAT_BRK is not set +CONFIG_PROFILING=y +CONFIG_OPROFILE=m +CONFIG_KPROBES=y +CONFIG_JUMP_LABEL=y +CONFIG_MODULES=y +CONFIG_MODULE_FORCE_LOAD=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_BLK_DEV_INTEGRITY=y +CONFIG_BLK_DEV_THROTTLING=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_IBM_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_CFQ_GROUP_IOSCHED=y +CONFIG_DEFAULT_DEADLINE=y +CONFIG_MARCH_Z9_109=y +CONFIG_PREEMPT=y +CONFIG_HZ_100=y +CONFIG_MEMORY_HOTPLUG=y +CONFIG_MEMORY_HOTREMOVE=y +CONFIG_KSM=y +CONFIG_TRANSPARENT_HUGEPAGE=y +CONFIG_PCI=y +CONFIG_PCI_DEBUG=y +CONFIG_HOTPLUG_PCI=y +CONFIG_HOTPLUG_PCI_S390=y +CONFIG_CHSC_SCH=y +CONFIG_CRASH_DUMP=y +CONFIG_ZFCPDUMP=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_BINFMT_MISC=m +CONFIG_HIBERNATION=y +CONFIG_PACKET=y +CONFIG_PACKET_DIAG=m +CONFIG_UNIX=y +CONFIG_UNIX_DIAG=m +CONFIG_XFRM_USER=m +CONFIG_NET_KEY=m +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE_DEMUX=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE=y +CONFIG_IP_MROUTE_MULTIPLE_TABLES=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +CONFIG_SYN_COOKIES=y +CONFIG_NET_IPVTI=m +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_DIAG=m +CONFIG_INET_UDP_DIAG=m +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_HSTCP=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_TCP_CONG_SCALABLE=m +CONFIG_TCP_CONG_LP=m +CONFIG_TCP_CONG_VENO=m +CONFIG_TCP_CONG_YEAH=m +CONFIG_TCP_CONG_ILLINOIS=m +CONFIG_IPV6=y +CONFIG_IPV6_PRIVACY=y +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_MIP6=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_IPV6_SIT=m +CONFIG_IPV6_GRE=m +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_SUBTREES=y +CONFIG_NETFILTER=y +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_TIMEOUT=y +CONFIG_NF_CONNTRACK_TIMESTAMP=y +CONFIG_NF_CT_PROTO_DCCP=m +CONFIG_NF_CT_PROTO_UDPLITE=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_SNMP=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_SANE=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_NETLINK=m +CONFIG_NF_CT_NETLINK_TIMEOUT=m +CONFIG_NETFILTER_TPROXY=m +CONFIG_NETFILTER_XT_SET=m +CONFIG_NETFILTER_XT_TARGET_AUDIT=m +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +CONFIG_NETFILTER_XT_TARGET_CT=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HMARK=m +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m +CONFIG_NETFILTER_XT_TARGET_LOG=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_TEE=m +CONFIG_NETFILTER_XT_TARGET_TPROXY=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +CONFIG_NETFILTER_XT_MATCH_BPF=m +CONFIG_NETFILTER_XT_MATCH_CLUSTER=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_CPU=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +CONFIG_NETFILTER_XT_MATCH_IPVS=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_NFACCT=m +CONFIG_NETFILTER_XT_MATCH_OSF=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +CONFIG_NETFILTER_XT_MATCH_SOCKET=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_IP_SET=m +CONFIG_IP_SET_BITMAP_IP=m +CONFIG_IP_SET_BITMAP_IPMAC=m +CONFIG_IP_SET_BITMAP_PORT=m +CONFIG_IP_SET_HASH_IP=m +CONFIG_IP_SET_HASH_IPPORT=m +CONFIG_IP_SET_HASH_IPPORTIP=m +CONFIG_IP_SET_HASH_IPPORTNET=m +CONFIG_IP_SET_HASH_NET=m +CONFIG_IP_SET_HASH_NETPORT=m +CONFIG_IP_SET_HASH_NETIFACE=m +CONFIG_IP_SET_LIST_SET=m +CONFIG_IP_VS=m +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m +CONFIG_IP_VS_FTP=m +CONFIG_IP_VS_PE_SIP=m +CONFIG_NF_CONNTRACK_IPV4=m +# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_RPFILTER=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_NF_NAT_IPV4=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_SECURITY=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RPFILTER=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_SECURITY=m +CONFIG_NF_NAT_IPV6=m +CONFIG_IP6_NF_TARGET_MASQUERADE=m +CONFIG_IP6_NF_TARGET_NPT=m +CONFIG_NET_SCTPPROBE=m +CONFIG_RDS=m +CONFIG_RDS_RDMA=m +CONFIG_RDS_TCP=m +CONFIG_RDS_DEBUG=y +CONFIG_L2TP=m +CONFIG_L2TP_DEBUGFS=m +CONFIG_L2TP_V3=y +CONFIG_L2TP_IP=m +CONFIG_L2TP_ETH=m +CONFIG_BRIDGE=m +CONFIG_VLAN_8021Q=m +CONFIG_VLAN_8021Q_GVRP=y +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_MULTIQ=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFB=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_DRR=m +CONFIG_NET_SCH_MQPRIO=m +CONFIG_NET_SCH_CHOKE=m +CONFIG_NET_SCH_QFQ=m +CONFIG_NET_SCH_CODEL=m +CONFIG_NET_SCH_FQ_CODEL=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_PLUG=m +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +CONFIG_CLS_U32_PERF=y +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_FLOW=m +CONFIG_NET_CLS_CGROUP=y +CONFIG_NET_CLS_ACT=y +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_GACT=m +CONFIG_GACT_PROB=y +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_SIMP=m +CONFIG_NET_ACT_SKBEDIT=m +CONFIG_NET_ACT_CSUM=m +CONFIG_DNS_RESOLVER=y +CONFIG_BPF_JIT=y +CONFIG_NET_PKTGEN=m +CONFIG_NET_TCPPROBE=m +CONFIG_DEVTMPFS=y +CONFIG_CONNECTOR=y +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_OSD=m +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=32768 +CONFIG_BLK_DEV_XIP=y +CONFIG_CDROM_PKTCDVD=m +CONFIG_ATA_OVER_ETH=m +CONFIG_VIRTIO_BLK=y +CONFIG_ENCLOSURE_SERVICES=m +CONFIG_RAID_ATTRS=m +CONFIG_SCSI=y +CONFIG_SCSI_TGT=m +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_ST=m +CONFIG_CHR_DEV_OSST=m +CONFIG_BLK_DEV_SR=m +CONFIG_CHR_DEV_SG=y +CONFIG_CHR_DEV_SCH=m +CONFIG_SCSI_ENCLOSURE=m +CONFIG_SCSI_MULTI_LUN=y +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_SPI_ATTRS=m +CONFIG_SCSI_SAS_LIBSAS=m +CONFIG_SCSI_SRP_ATTRS=m +CONFIG_SCSI_SRP_TGT_ATTRS=y +CONFIG_ISCSI_TCP=m +CONFIG_LIBFCOE=m +CONFIG_SCSI_DEBUG=m +CONFIG_ZFCP=y +CONFIG_SCSI_VIRTIO=m +CONFIG_SCSI_DH=m +CONFIG_SCSI_DH_RDAC=m +CONFIG_SCSI_DH_HP_SW=m +CONFIG_SCSI_DH_EMC=m +CONFIG_SCSI_DH_ALUA=m +CONFIG_SCSI_OSD_INITIATOR=m +CONFIG_SCSI_OSD_ULD=m +CONFIG_MD=y +CONFIG_BLK_DEV_MD=y +CONFIG_MD_LINEAR=m +CONFIG_MD_RAID0=m +CONFIG_MD_MULTIPATH=m +CONFIG_MD_FAULTY=m +CONFIG_BLK_DEV_DM=m +CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_MIRROR=m +CONFIG_DM_RAID=m +CONFIG_DM_LOG_USERSPACE=m +CONFIG_DM_ZERO=m +CONFIG_DM_MULTIPATH=m +CONFIG_DM_MULTIPATH_QL=m +CONFIG_DM_MULTIPATH_ST=m +CONFIG_DM_DELAY=m +CONFIG_DM_UEVENT=y +CONFIG_DM_FLAKEY=m +CONFIG_DM_VERITY=m +CONFIG_DM_SWITCH=m +CONFIG_NETDEVICES=y +CONFIG_BONDING=m +CONFIG_DUMMY=m +CONFIG_EQUALIZER=m +CONFIG_IFB=m +CONFIG_MACVLAN=m +CONFIG_MACVTAP=m +CONFIG_VXLAN=m +CONFIG_TUN=m +CONFIG_VETH=m +CONFIG_VIRTIO_NET=m +CONFIG_NLMON=m +CONFIG_VHOST_NET=m +# CONFIG_NET_VENDOR_ARC is not set +# CONFIG_NET_CADENCE is not set +# CONFIG_NET_VENDOR_CHELSIO is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_MARVELL is not set +CONFIG_MLX4_EN=m +# CONFIG_NET_VENDOR_NATSEMI is not set +CONFIG_PPP=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_MPPE=m +CONFIG_PPPOE=m +CONFIG_PPTP=m +CONFIG_PPPOL2TP=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_SERIO is not set +CONFIG_DEVPTS_MULTIPLE_INSTANCES=y +CONFIG_LEGACY_PTY_COUNT=0 +CONFIG_HW_RANDOM_VIRTIO=m +CONFIG_RAW_DRIVER=m +CONFIG_HANGCHECK_TIMER=m +CONFIG_TN3270_FS=y +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_NOWAYOUT=y +CONFIG_SOFT_WATCHDOG=m +CONFIG_ZVM_WATCHDOG=m +# CONFIG_HID is not set +# CONFIG_USB_SUPPORT is not set +CONFIG_INFINIBAND=m +CONFIG_INFINIBAND_USER_ACCESS=m +CONFIG_MLX4_INFINIBAND=m +CONFIG_VIRTIO_BALLOON=m +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT2_FS_XIP=y +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_JBD_DEBUG=y +CONFIG_JBD2_DEBUG=y +CONFIG_JFS_FS=m +CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y +CONFIG_JFS_STATISTICS=y +CONFIG_XFS_FS=m +CONFIG_XFS_QUOTA=y +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_RT=y +CONFIG_XFS_DEBUG=y +CONFIG_GFS2_FS=m +CONFIG_OCFS2_FS=m +CONFIG_BTRFS_FS=m +CONFIG_BTRFS_FS_POSIX_ACL=y +CONFIG_NILFS2_FS=m +CONFIG_FANOTIFY=y +CONFIG_QUOTA_NETLINK_INTERFACE=y +CONFIG_QFMT_V1=m +CONFIG_QFMT_V2=m +CONFIG_AUTOFS4_FS=m +CONFIG_FUSE_FS=m +CONFIG_CUSE=m +CONFIG_FSCACHE=m +CONFIG_CACHEFILES=m +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_NTFS_FS=m +CONFIG_NTFS_RW=y +CONFIG_PROC_KCORE=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_HUGETLBFS=y +CONFIG_CONFIGFS_FS=m +CONFIG_ECRYPT_FS=m +CONFIG_CRAMFS=m +CONFIG_SQUASHFS=m +CONFIG_SQUASHFS_XATTR=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y +CONFIG_ROMFS_FS=m +CONFIG_NFS_FS=m +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=m +CONFIG_NFS_SWAP=y +CONFIG_NFSD=m +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_NFSD_V4_SECURITY_LABEL=y +CONFIG_CIFS=m +CONFIG_CIFS_STATS=y +CONFIG_CIFS_STATS2=y +CONFIG_CIFS_WEAK_PW_HASH=y +CONFIG_CIFS_UPCALL=y +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y +# CONFIG_CIFS_DEBUG is not set +CONFIG_CIFS_DFS_UPCALL=y +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_ASCII=m +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_UTF8=m +CONFIG_DLM=m +CONFIG_PRINTK_TIME=y +CONFIG_DYNAMIC_DEBUG=y +CONFIG_DEBUG_INFO=y +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_FRAME_WARN=1024 +CONFIG_READABLE_ASM=y +CONFIG_UNUSED_SYMBOLS=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_KERNEL=y +CONFIG_DEBUG_PAGEALLOC=y +CONFIG_SLUB_DEBUG_ON=y +CONFIG_SLUB_STATS=y +CONFIG_DEBUG_STACK_USAGE=y +CONFIG_DEBUG_VM=y +CONFIG_DEBUG_VM_RB=y +CONFIG_MEMORY_NOTIFIER_ERROR_INJECT=m +CONFIG_DEBUG_PER_CPU_MAPS=y +CONFIG_TIMER_STATS=y +CONFIG_DEBUG_RT_MUTEXES=y +CONFIG_RT_MUTEX_TESTER=y +CONFIG_DEBUG_WW_MUTEX_SLOWPATH=y +CONFIG_PROVE_LOCKING=y +CONFIG_LOCK_STAT=y +CONFIG_DEBUG_LOCKDEP=y +CONFIG_DEBUG_ATOMIC_SLEEP=y +CONFIG_DEBUG_LOCKING_API_SELFTESTS=y +CONFIG_DEBUG_WRITECOUNT=y +CONFIG_DEBUG_LIST=y +CONFIG_DEBUG_SG=y +CONFIG_DEBUG_NOTIFIERS=y +CONFIG_DEBUG_CREDENTIALS=y +CONFIG_PROVE_RCU=y +CONFIG_RCU_TORTURE_TEST=m +CONFIG_RCU_CPU_STALL_TIMEOUT=300 +CONFIG_NOTIFIER_ERROR_INJECTION=m +CONFIG_CPU_NOTIFIER_ERROR_INJECT=m +CONFIG_PM_NOTIFIER_ERROR_INJECT=m +CONFIG_FAULT_INJECTION=y +CONFIG_FAILSLAB=y +CONFIG_FAIL_PAGE_ALLOC=y +CONFIG_FAIL_MAKE_REQUEST=y +CONFIG_FAIL_IO_TIMEOUT=y +CONFIG_FAULT_INJECTION_DEBUG_FS=y +CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y +CONFIG_LATENCYTOP=y +CONFIG_DEBUG_STRICT_USER_COPY_CHECKS=y +CONFIG_BLK_DEV_IO_TRACE=y +# CONFIG_KPROBE_EVENT is not set +CONFIG_LKDTM=m +CONFIG_KPROBES_SANITY_TEST=y +CONFIG_RBTREE_TEST=m +CONFIG_INTERVAL_TREE_TEST=m +CONFIG_ATOMIC64_SELFTEST=y +CONFIG_DMA_API_DEBUG=y +# CONFIG_STRICT_DEVMEM is not set +CONFIG_S390_PTDUMP=y +CONFIG_ENCRYPTED_KEYS=m +CONFIG_KEYS_DEBUG_PROC_KEYS=y +CONFIG_SECURITY=y +CONFIG_SECURITY_NETWORK=y +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_SELINUX_BOOTPARAM=y +CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 +CONFIG_SECURITY_SELINUX_DISABLE=y +CONFIG_IMA=y +CONFIG_IMA_APPRAISE=y +CONFIG_CRYPTO_USER=m +# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_TEST=m +CONFIG_CRYPTO_CCM=m +CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_XTS=m +CONFIG_CRYPTO_XCBC=m +CONFIG_CRYPTO_VMAC=m +CONFIG_CRYPTO_CRC32=m +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_RMD128=m +CONFIG_CRYPTO_RMD160=m +CONFIG_CRYPTO_RMD256=m +CONFIG_CRYPTO_RMD320=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_SALSA20=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_ZLIB=y +CONFIG_CRYPTO_LZO=m +CONFIG_CRYPTO_LZ4=m +CONFIG_CRYPTO_LZ4HC=m +CONFIG_CRYPTO_USER_API_HASH=m +CONFIG_CRYPTO_USER_API_SKCIPHER=m +CONFIG_ZCRYPT=m +CONFIG_CRYPTO_SHA1_S390=m +CONFIG_CRYPTO_SHA256_S390=m +CONFIG_CRYPTO_SHA512_S390=m +CONFIG_CRYPTO_DES_S390=m +CONFIG_CRYPTO_AES_S390=m +CONFIG_CRYPTO_GHASH_S390=m +CONFIG_ASYMMETRIC_KEY_TYPE=m +CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=m +CONFIG_PUBLIC_KEY_ALGO_RSA=m +CONFIG_X509_CERTIFICATE_PARSER=m +CONFIG_CRC7=m +CONFIG_CRC8=m +CONFIG_XZ_DEC_X86=y +CONFIG_XZ_DEC_POWERPC=y +CONFIG_XZ_DEC_IA64=y +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_ARMTHUMB=y +CONFIG_XZ_DEC_SPARC=y +CONFIG_CORDIC=m +CONFIG_CMM=m +CONFIG_APPLDATA_BASE=y +CONFIG_KVM=m +CONFIG_KVM_S390_UCONTROL=y diff --git a/arch/s390/configs/gcov_defconfig b/arch/s390/configs/gcov_defconfig new file mode 100644 index 000000000000..b9f6b4cab927 --- /dev/null +++ b/arch/s390/configs/gcov_defconfig @@ -0,0 +1,618 @@ +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_FHANDLE=y +CONFIG_AUDIT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_TASKSTATS=y +CONFIG_TASK_DELAY_ACCT=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_RCU_FAST_NO_HZ=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CPUSETS=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_RESOURCE_COUNTERS=y +CONFIG_CGROUP_PERF=y +CONFIG_BLK_CGROUP=y +CONFIG_SCHED_AUTOGROUP=y +CONFIG_BLK_DEV_INITRD=y +# CONFIG_COMPAT_BRK is not set +CONFIG_PROFILING=y +CONFIG_OPROFILE=m +CONFIG_KPROBES=y +CONFIG_JUMP_LABEL=y +CONFIG_GCOV_KERNEL=y +CONFIG_GCOV_PROFILE_ALL=y +CONFIG_MODULES=y +CONFIG_MODULE_FORCE_LOAD=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_BLK_DEV_INTEGRITY=y +CONFIG_BLK_DEV_THROTTLING=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_IBM_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_CFQ_GROUP_IOSCHED=y +CONFIG_DEFAULT_DEADLINE=y +CONFIG_MARCH_Z9_109=y +CONFIG_HZ_100=y +CONFIG_MEMORY_HOTPLUG=y +CONFIG_MEMORY_HOTREMOVE=y +CONFIG_KSM=y +CONFIG_TRANSPARENT_HUGEPAGE=y +CONFIG_PCI=y +CONFIG_HOTPLUG_PCI=y +CONFIG_HOTPLUG_PCI_S390=y +CONFIG_CHSC_SCH=y +CONFIG_CRASH_DUMP=y +CONFIG_ZFCPDUMP=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_BINFMT_MISC=m +CONFIG_HIBERNATION=y +CONFIG_PACKET=y +CONFIG_PACKET_DIAG=m +CONFIG_UNIX=y +CONFIG_UNIX_DIAG=m +CONFIG_XFRM_USER=m +CONFIG_NET_KEY=m +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE_DEMUX=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE=y +CONFIG_IP_MROUTE_MULTIPLE_TABLES=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +CONFIG_SYN_COOKIES=y +CONFIG_NET_IPVTI=m +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_DIAG=m +CONFIG_INET_UDP_DIAG=m +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_HSTCP=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_TCP_CONG_SCALABLE=m +CONFIG_TCP_CONG_LP=m +CONFIG_TCP_CONG_VENO=m +CONFIG_TCP_CONG_YEAH=m +CONFIG_TCP_CONG_ILLINOIS=m +CONFIG_IPV6=y +CONFIG_IPV6_PRIVACY=y +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_MIP6=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_IPV6_SIT=m +CONFIG_IPV6_GRE=m +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_SUBTREES=y +CONFIG_NETFILTER=y +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_TIMEOUT=y +CONFIG_NF_CONNTRACK_TIMESTAMP=y +CONFIG_NF_CT_PROTO_DCCP=m +CONFIG_NF_CT_PROTO_UDPLITE=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_SNMP=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_SANE=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_NETLINK=m +CONFIG_NF_CT_NETLINK_TIMEOUT=m +CONFIG_NETFILTER_TPROXY=m +CONFIG_NETFILTER_XT_SET=m +CONFIG_NETFILTER_XT_TARGET_AUDIT=m +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +CONFIG_NETFILTER_XT_TARGET_CT=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HMARK=m +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m +CONFIG_NETFILTER_XT_TARGET_LOG=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_TEE=m +CONFIG_NETFILTER_XT_TARGET_TPROXY=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +CONFIG_NETFILTER_XT_MATCH_BPF=m +CONFIG_NETFILTER_XT_MATCH_CLUSTER=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_CPU=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +CONFIG_NETFILTER_XT_MATCH_IPVS=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_NFACCT=m +CONFIG_NETFILTER_XT_MATCH_OSF=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +CONFIG_NETFILTER_XT_MATCH_SOCKET=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_IP_SET=m +CONFIG_IP_SET_BITMAP_IP=m +CONFIG_IP_SET_BITMAP_IPMAC=m +CONFIG_IP_SET_BITMAP_PORT=m +CONFIG_IP_SET_HASH_IP=m +CONFIG_IP_SET_HASH_IPPORT=m +CONFIG_IP_SET_HASH_IPPORTIP=m +CONFIG_IP_SET_HASH_IPPORTNET=m +CONFIG_IP_SET_HASH_NET=m +CONFIG_IP_SET_HASH_NETPORT=m +CONFIG_IP_SET_HASH_NETIFACE=m +CONFIG_IP_SET_LIST_SET=m +CONFIG_IP_VS=m +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m +CONFIG_IP_VS_FTP=m +CONFIG_IP_VS_PE_SIP=m +CONFIG_NF_CONNTRACK_IPV4=m +# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_RPFILTER=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_NF_NAT_IPV4=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_SECURITY=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RPFILTER=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_SECURITY=m +CONFIG_NF_NAT_IPV6=m +CONFIG_IP6_NF_TARGET_MASQUERADE=m +CONFIG_IP6_NF_TARGET_NPT=m +CONFIG_NET_SCTPPROBE=m +CONFIG_RDS=m +CONFIG_RDS_RDMA=m +CONFIG_RDS_TCP=m +CONFIG_L2TP=m +CONFIG_L2TP_DEBUGFS=m +CONFIG_L2TP_V3=y +CONFIG_L2TP_IP=m +CONFIG_L2TP_ETH=m +CONFIG_BRIDGE=m +CONFIG_VLAN_8021Q=m +CONFIG_VLAN_8021Q_GVRP=y +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_MULTIQ=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFB=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_DRR=m +CONFIG_NET_SCH_MQPRIO=m +CONFIG_NET_SCH_CHOKE=m +CONFIG_NET_SCH_QFQ=m +CONFIG_NET_SCH_CODEL=m +CONFIG_NET_SCH_FQ_CODEL=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_PLUG=m +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +CONFIG_CLS_U32_PERF=y +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_FLOW=m +CONFIG_NET_CLS_CGROUP=y +CONFIG_NET_CLS_ACT=y +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_GACT=m +CONFIG_GACT_PROB=y +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_SIMP=m +CONFIG_NET_ACT_SKBEDIT=m +CONFIG_NET_ACT_CSUM=m +CONFIG_DNS_RESOLVER=y +CONFIG_BPF_JIT=y +CONFIG_NET_PKTGEN=m +CONFIG_NET_TCPPROBE=m +CONFIG_DEVTMPFS=y +CONFIG_CONNECTOR=y +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_OSD=m +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=32768 +CONFIG_BLK_DEV_XIP=y +CONFIG_CDROM_PKTCDVD=m +CONFIG_ATA_OVER_ETH=m +CONFIG_VIRTIO_BLK=y +CONFIG_ENCLOSURE_SERVICES=m +CONFIG_RAID_ATTRS=m +CONFIG_SCSI=y +CONFIG_SCSI_TGT=m +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_ST=m +CONFIG_CHR_DEV_OSST=m +CONFIG_BLK_DEV_SR=m +CONFIG_CHR_DEV_SG=y +CONFIG_CHR_DEV_SCH=m +CONFIG_SCSI_ENCLOSURE=m +CONFIG_SCSI_MULTI_LUN=y +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_SPI_ATTRS=m +CONFIG_SCSI_SAS_LIBSAS=m +CONFIG_SCSI_SRP_ATTRS=m +CONFIG_SCSI_SRP_TGT_ATTRS=y +CONFIG_ISCSI_TCP=m +CONFIG_LIBFCOE=m +CONFIG_SCSI_DEBUG=m +CONFIG_ZFCP=y +CONFIG_SCSI_VIRTIO=m +CONFIG_SCSI_DH=m +CONFIG_SCSI_DH_RDAC=m +CONFIG_SCSI_DH_HP_SW=m +CONFIG_SCSI_DH_EMC=m +CONFIG_SCSI_DH_ALUA=m +CONFIG_SCSI_OSD_INITIATOR=m +CONFIG_SCSI_OSD_ULD=m +CONFIG_MD=y +CONFIG_BLK_DEV_MD=y +CONFIG_MD_LINEAR=m +CONFIG_MD_RAID0=m +CONFIG_MD_MULTIPATH=m +CONFIG_MD_FAULTY=m +CONFIG_BLK_DEV_DM=m +CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_MIRROR=m +CONFIG_DM_RAID=m +CONFIG_DM_LOG_USERSPACE=m +CONFIG_DM_ZERO=m +CONFIG_DM_MULTIPATH=m +CONFIG_DM_MULTIPATH_QL=m +CONFIG_DM_MULTIPATH_ST=m +CONFIG_DM_DELAY=m +CONFIG_DM_UEVENT=y +CONFIG_DM_FLAKEY=m +CONFIG_DM_VERITY=m +CONFIG_DM_SWITCH=m +CONFIG_NETDEVICES=y +CONFIG_BONDING=m +CONFIG_DUMMY=m +CONFIG_EQUALIZER=m +CONFIG_IFB=m +CONFIG_MACVLAN=m +CONFIG_MACVTAP=m +CONFIG_VXLAN=m +CONFIG_TUN=m +CONFIG_VETH=m +CONFIG_VIRTIO_NET=m +CONFIG_NLMON=m +CONFIG_VHOST_NET=m +# CONFIG_NET_VENDOR_ARC is not set +# CONFIG_NET_CADENCE is not set +# CONFIG_NET_VENDOR_CHELSIO is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_MARVELL is not set +CONFIG_MLX4_EN=m +# CONFIG_NET_VENDOR_NATSEMI is not set +CONFIG_PPP=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_MPPE=m +CONFIG_PPPOE=m +CONFIG_PPTP=m +CONFIG_PPPOL2TP=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_SERIO is not set +CONFIG_DEVPTS_MULTIPLE_INSTANCES=y +CONFIG_LEGACY_PTY_COUNT=0 +CONFIG_HW_RANDOM_VIRTIO=m +CONFIG_RAW_DRIVER=m +CONFIG_HANGCHECK_TIMER=m +CONFIG_TN3270_FS=y +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_NOWAYOUT=y +CONFIG_SOFT_WATCHDOG=m +CONFIG_ZVM_WATCHDOG=m +# CONFIG_HID is not set +# CONFIG_USB_SUPPORT is not set +CONFIG_INFINIBAND=m +CONFIG_INFINIBAND_USER_ACCESS=m +CONFIG_MLX4_INFINIBAND=m +CONFIG_VIRTIO_BALLOON=m +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT2_FS_XIP=y +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_JBD_DEBUG=y +CONFIG_JBD2_DEBUG=y +CONFIG_JFS_FS=m +CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y +CONFIG_JFS_STATISTICS=y +CONFIG_XFS_FS=m +CONFIG_XFS_QUOTA=y +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_RT=y +CONFIG_GFS2_FS=m +CONFIG_OCFS2_FS=m +CONFIG_BTRFS_FS=m +CONFIG_BTRFS_FS_POSIX_ACL=y +CONFIG_NILFS2_FS=m +CONFIG_FANOTIFY=y +CONFIG_QUOTA_NETLINK_INTERFACE=y +CONFIG_QFMT_V1=m +CONFIG_QFMT_V2=m +CONFIG_AUTOFS4_FS=m +CONFIG_FUSE_FS=m +CONFIG_CUSE=m +CONFIG_FSCACHE=m +CONFIG_CACHEFILES=m +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_NTFS_FS=m +CONFIG_NTFS_RW=y +CONFIG_PROC_KCORE=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_HUGETLBFS=y +CONFIG_CONFIGFS_FS=m +CONFIG_ECRYPT_FS=m +CONFIG_CRAMFS=m +CONFIG_SQUASHFS=m +CONFIG_SQUASHFS_XATTR=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y +CONFIG_ROMFS_FS=m +CONFIG_NFS_FS=m +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=m +CONFIG_NFS_SWAP=y +CONFIG_NFSD=m +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_NFSD_V4_SECURITY_LABEL=y +CONFIG_CIFS=m +CONFIG_CIFS_STATS=y +CONFIG_CIFS_STATS2=y +CONFIG_CIFS_WEAK_PW_HASH=y +CONFIG_CIFS_UPCALL=y +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y +# CONFIG_CIFS_DEBUG is not set +CONFIG_CIFS_DFS_UPCALL=y +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_ASCII=m +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_UTF8=m +CONFIG_DLM=m +CONFIG_PRINTK_TIME=y +CONFIG_DEBUG_INFO=y +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_FRAME_WARN=1024 +CONFIG_UNUSED_SYMBOLS=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_KERNEL=y +CONFIG_MEMORY_NOTIFIER_ERROR_INJECT=m +CONFIG_TIMER_STATS=y +CONFIG_RCU_TORTURE_TEST=m +CONFIG_RCU_CPU_STALL_TIMEOUT=60 +CONFIG_NOTIFIER_ERROR_INJECTION=m +CONFIG_CPU_NOTIFIER_ERROR_INJECT=m +CONFIG_PM_NOTIFIER_ERROR_INJECT=m +CONFIG_LATENCYTOP=y +CONFIG_BLK_DEV_IO_TRACE=y +# CONFIG_KPROBE_EVENT is not set +CONFIG_LKDTM=m +CONFIG_RBTREE_TEST=m +CONFIG_INTERVAL_TREE_TEST=m +CONFIG_ATOMIC64_SELFTEST=y +# CONFIG_STRICT_DEVMEM is not set +CONFIG_S390_PTDUMP=y +CONFIG_ENCRYPTED_KEYS=m +CONFIG_KEYS_DEBUG_PROC_KEYS=y +CONFIG_SECURITY=y +CONFIG_SECURITY_NETWORK=y +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_SELINUX_BOOTPARAM=y +CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 +CONFIG_SECURITY_SELINUX_DISABLE=y +CONFIG_IMA=y +CONFIG_IMA_APPRAISE=y +CONFIG_CRYPTO_USER=m +# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_TEST=m +CONFIG_CRYPTO_CCM=m +CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_XTS=m +CONFIG_CRYPTO_XCBC=m +CONFIG_CRYPTO_VMAC=m +CONFIG_CRYPTO_CRC32=m +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_RMD128=m +CONFIG_CRYPTO_RMD160=m +CONFIG_CRYPTO_RMD256=m +CONFIG_CRYPTO_RMD320=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_SALSA20=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_ZLIB=y +CONFIG_CRYPTO_LZO=m +CONFIG_CRYPTO_LZ4=m +CONFIG_CRYPTO_LZ4HC=m +CONFIG_CRYPTO_USER_API_HASH=m +CONFIG_CRYPTO_USER_API_SKCIPHER=m +CONFIG_ZCRYPT=m +CONFIG_CRYPTO_SHA1_S390=m +CONFIG_CRYPTO_SHA256_S390=m +CONFIG_CRYPTO_SHA512_S390=m +CONFIG_CRYPTO_DES_S390=m +CONFIG_CRYPTO_AES_S390=m +CONFIG_CRYPTO_GHASH_S390=m +CONFIG_ASYMMETRIC_KEY_TYPE=m +CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=m +CONFIG_PUBLIC_KEY_ALGO_RSA=m +CONFIG_X509_CERTIFICATE_PARSER=m +CONFIG_CRC7=m +CONFIG_CRC8=m +CONFIG_XZ_DEC_X86=y +CONFIG_XZ_DEC_POWERPC=y +CONFIG_XZ_DEC_IA64=y +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_ARMTHUMB=y +CONFIG_XZ_DEC_SPARC=y +CONFIG_CORDIC=m +CONFIG_CMM=m +CONFIG_APPLDATA_BASE=y +CONFIG_KVM=m +CONFIG_KVM_S390_UCONTROL=y diff --git a/arch/s390/configs/performance_defconfig b/arch/s390/configs/performance_defconfig new file mode 100644 index 000000000000..91087b43e8fa --- /dev/null +++ b/arch/s390/configs/performance_defconfig @@ -0,0 +1,610 @@ +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_FHANDLE=y +CONFIG_AUDIT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_TASKSTATS=y +CONFIG_TASK_DELAY_ACCT=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_RCU_FAST_NO_HZ=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CPUSETS=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_RESOURCE_COUNTERS=y +CONFIG_CGROUP_PERF=y +CONFIG_BLK_CGROUP=y +CONFIG_SCHED_AUTOGROUP=y +CONFIG_BLK_DEV_INITRD=y +# CONFIG_COMPAT_BRK is not set +CONFIG_PROFILING=y +CONFIG_OPROFILE=m +CONFIG_KPROBES=y +CONFIG_JUMP_LABEL=y +CONFIG_MODULES=y +CONFIG_MODULE_FORCE_LOAD=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_BLK_DEV_INTEGRITY=y +CONFIG_BLK_DEV_THROTTLING=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_IBM_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_CFQ_GROUP_IOSCHED=y +CONFIG_DEFAULT_DEADLINE=y +CONFIG_MARCH_Z9_109=y +CONFIG_HZ_100=y +CONFIG_MEMORY_HOTPLUG=y +CONFIG_MEMORY_HOTREMOVE=y +CONFIG_KSM=y +CONFIG_TRANSPARENT_HUGEPAGE=y +CONFIG_PCI=y +CONFIG_HOTPLUG_PCI=y +CONFIG_HOTPLUG_PCI_S390=y +CONFIG_CHSC_SCH=y +CONFIG_CRASH_DUMP=y +CONFIG_ZFCPDUMP=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_BINFMT_MISC=m +CONFIG_HIBERNATION=y +CONFIG_PACKET=y +CONFIG_PACKET_DIAG=m +CONFIG_UNIX=y +CONFIG_UNIX_DIAG=m +CONFIG_XFRM_USER=m +CONFIG_NET_KEY=m +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE_DEMUX=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE=y +CONFIG_IP_MROUTE_MULTIPLE_TABLES=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +CONFIG_SYN_COOKIES=y +CONFIG_NET_IPVTI=m +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_DIAG=m +CONFIG_INET_UDP_DIAG=m +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_HSTCP=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_TCP_CONG_SCALABLE=m +CONFIG_TCP_CONG_LP=m +CONFIG_TCP_CONG_VENO=m +CONFIG_TCP_CONG_YEAH=m +CONFIG_TCP_CONG_ILLINOIS=m +CONFIG_IPV6=y +CONFIG_IPV6_PRIVACY=y +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_MIP6=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_IPV6_SIT=m +CONFIG_IPV6_GRE=m +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_SUBTREES=y +CONFIG_NETFILTER=y +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_TIMEOUT=y +CONFIG_NF_CONNTRACK_TIMESTAMP=y +CONFIG_NF_CT_PROTO_DCCP=m +CONFIG_NF_CT_PROTO_UDPLITE=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_SNMP=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_SANE=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_NETLINK=m +CONFIG_NF_CT_NETLINK_TIMEOUT=m +CONFIG_NETFILTER_TPROXY=m +CONFIG_NETFILTER_XT_SET=m +CONFIG_NETFILTER_XT_TARGET_AUDIT=m +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +CONFIG_NETFILTER_XT_TARGET_CT=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HMARK=m +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m +CONFIG_NETFILTER_XT_TARGET_LOG=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_TEE=m +CONFIG_NETFILTER_XT_TARGET_TPROXY=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +CONFIG_NETFILTER_XT_MATCH_BPF=m +CONFIG_NETFILTER_XT_MATCH_CLUSTER=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_CPU=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +CONFIG_NETFILTER_XT_MATCH_IPVS=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_NFACCT=m +CONFIG_NETFILTER_XT_MATCH_OSF=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +CONFIG_NETFILTER_XT_MATCH_SOCKET=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_IP_SET=m +CONFIG_IP_SET_BITMAP_IP=m +CONFIG_IP_SET_BITMAP_IPMAC=m +CONFIG_IP_SET_BITMAP_PORT=m +CONFIG_IP_SET_HASH_IP=m +CONFIG_IP_SET_HASH_IPPORT=m +CONFIG_IP_SET_HASH_IPPORTIP=m +CONFIG_IP_SET_HASH_IPPORTNET=m +CONFIG_IP_SET_HASH_NET=m +CONFIG_IP_SET_HASH_NETPORT=m +CONFIG_IP_SET_HASH_NETIFACE=m +CONFIG_IP_SET_LIST_SET=m +CONFIG_IP_VS=m +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m +CONFIG_IP_VS_FTP=m +CONFIG_IP_VS_PE_SIP=m +CONFIG_NF_CONNTRACK_IPV4=m +# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_RPFILTER=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_NF_NAT_IPV4=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_SECURITY=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RPFILTER=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_SECURITY=m +CONFIG_NF_NAT_IPV6=m +CONFIG_IP6_NF_TARGET_MASQUERADE=m +CONFIG_IP6_NF_TARGET_NPT=m +CONFIG_NET_SCTPPROBE=m +CONFIG_RDS=m +CONFIG_RDS_RDMA=m +CONFIG_RDS_TCP=m +CONFIG_L2TP=m +CONFIG_L2TP_DEBUGFS=m +CONFIG_L2TP_V3=y +CONFIG_L2TP_IP=m +CONFIG_L2TP_ETH=m +CONFIG_BRIDGE=m +CONFIG_VLAN_8021Q=m +CONFIG_VLAN_8021Q_GVRP=y +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_MULTIQ=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFB=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_DRR=m +CONFIG_NET_SCH_MQPRIO=m +CONFIG_NET_SCH_CHOKE=m +CONFIG_NET_SCH_QFQ=m +CONFIG_NET_SCH_CODEL=m +CONFIG_NET_SCH_FQ_CODEL=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_PLUG=m +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +CONFIG_CLS_U32_PERF=y +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_FLOW=m +CONFIG_NET_CLS_CGROUP=y +CONFIG_NET_CLS_ACT=y +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_GACT=m +CONFIG_GACT_PROB=y +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_SIMP=m +CONFIG_NET_ACT_SKBEDIT=m +CONFIG_NET_ACT_CSUM=m +CONFIG_DNS_RESOLVER=y +CONFIG_BPF_JIT=y +CONFIG_NET_PKTGEN=m +CONFIG_NET_TCPPROBE=m +CONFIG_DEVTMPFS=y +CONFIG_CONNECTOR=y +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_OSD=m +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=32768 +CONFIG_BLK_DEV_XIP=y +CONFIG_CDROM_PKTCDVD=m +CONFIG_ATA_OVER_ETH=m +CONFIG_VIRTIO_BLK=y +CONFIG_ENCLOSURE_SERVICES=m +CONFIG_RAID_ATTRS=m +CONFIG_SCSI=y +CONFIG_SCSI_TGT=m +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_ST=m +CONFIG_CHR_DEV_OSST=m +CONFIG_BLK_DEV_SR=m +CONFIG_CHR_DEV_SG=y +CONFIG_CHR_DEV_SCH=m +CONFIG_SCSI_ENCLOSURE=m +CONFIG_SCSI_MULTI_LUN=y +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_SPI_ATTRS=m +CONFIG_SCSI_SAS_LIBSAS=m +CONFIG_SCSI_SRP_ATTRS=m +CONFIG_SCSI_SRP_TGT_ATTRS=y +CONFIG_ISCSI_TCP=m +CONFIG_LIBFCOE=m +CONFIG_SCSI_DEBUG=m +CONFIG_ZFCP=y +CONFIG_SCSI_VIRTIO=m +CONFIG_SCSI_DH=m +CONFIG_SCSI_DH_RDAC=m +CONFIG_SCSI_DH_HP_SW=m +CONFIG_SCSI_DH_EMC=m +CONFIG_SCSI_DH_ALUA=m +CONFIG_SCSI_OSD_INITIATOR=m +CONFIG_SCSI_OSD_ULD=m +CONFIG_MD=y +CONFIG_BLK_DEV_MD=y +CONFIG_MD_LINEAR=m +CONFIG_MD_RAID0=m +CONFIG_MD_MULTIPATH=m +CONFIG_MD_FAULTY=m +CONFIG_BLK_DEV_DM=m +CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_MIRROR=m +CONFIG_DM_RAID=m +CONFIG_DM_LOG_USERSPACE=m +CONFIG_DM_ZERO=m +CONFIG_DM_MULTIPATH=m +CONFIG_DM_MULTIPATH_QL=m +CONFIG_DM_MULTIPATH_ST=m +CONFIG_DM_DELAY=m +CONFIG_DM_UEVENT=y +CONFIG_DM_FLAKEY=m +CONFIG_DM_VERITY=m +CONFIG_DM_SWITCH=m +CONFIG_NETDEVICES=y +CONFIG_BONDING=m +CONFIG_DUMMY=m +CONFIG_EQUALIZER=m +CONFIG_IFB=m +CONFIG_MACVLAN=m +CONFIG_MACVTAP=m +CONFIG_VXLAN=m +CONFIG_TUN=m +CONFIG_VETH=m +CONFIG_VIRTIO_NET=m +CONFIG_NLMON=m +CONFIG_VHOST_NET=m +# CONFIG_NET_VENDOR_ARC is not set +# CONFIG_NET_CADENCE is not set +# CONFIG_NET_VENDOR_CHELSIO is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_MARVELL is not set +CONFIG_MLX4_EN=m +# CONFIG_NET_VENDOR_NATSEMI is not set +CONFIG_PPP=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_MPPE=m +CONFIG_PPPOE=m +CONFIG_PPTP=m +CONFIG_PPPOL2TP=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_SERIO is not set +CONFIG_DEVPTS_MULTIPLE_INSTANCES=y +CONFIG_LEGACY_PTY_COUNT=0 +CONFIG_HW_RANDOM_VIRTIO=m +CONFIG_RAW_DRIVER=m +CONFIG_HANGCHECK_TIMER=m +CONFIG_TN3270_FS=y +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_NOWAYOUT=y +CONFIG_SOFT_WATCHDOG=m +CONFIG_ZVM_WATCHDOG=m +# CONFIG_HID is not set +# CONFIG_USB_SUPPORT is not set +CONFIG_INFINIBAND=m +CONFIG_INFINIBAND_USER_ACCESS=m +CONFIG_MLX4_INFINIBAND=m +CONFIG_VIRTIO_BALLOON=m +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT2_FS_XIP=y +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_JBD_DEBUG=y +CONFIG_JBD2_DEBUG=y +CONFIG_JFS_FS=m +CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y +CONFIG_JFS_STATISTICS=y +CONFIG_XFS_FS=m +CONFIG_XFS_QUOTA=y +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_RT=y +CONFIG_GFS2_FS=m +CONFIG_OCFS2_FS=m +CONFIG_BTRFS_FS=m +CONFIG_BTRFS_FS_POSIX_ACL=y +CONFIG_NILFS2_FS=m +CONFIG_FANOTIFY=y +CONFIG_QUOTA_NETLINK_INTERFACE=y +CONFIG_QFMT_V1=m +CONFIG_QFMT_V2=m +CONFIG_AUTOFS4_FS=m +CONFIG_FUSE_FS=m +CONFIG_CUSE=m +CONFIG_FSCACHE=m +CONFIG_CACHEFILES=m +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_NTFS_FS=m +CONFIG_NTFS_RW=y +CONFIG_PROC_KCORE=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_HUGETLBFS=y +CONFIG_CONFIGFS_FS=m +CONFIG_ECRYPT_FS=m +CONFIG_CRAMFS=m +CONFIG_SQUASHFS=m +CONFIG_SQUASHFS_XATTR=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y +CONFIG_ROMFS_FS=m +CONFIG_NFS_FS=m +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=m +CONFIG_NFS_SWAP=y +CONFIG_NFSD=m +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_NFSD_V4_SECURITY_LABEL=y +CONFIG_CIFS=m +CONFIG_CIFS_STATS=y +CONFIG_CIFS_STATS2=y +CONFIG_CIFS_WEAK_PW_HASH=y +CONFIG_CIFS_UPCALL=y +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y +# CONFIG_CIFS_DEBUG is not set +CONFIG_CIFS_DFS_UPCALL=y +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_ASCII=m +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_UTF8=m +CONFIG_DLM=m +CONFIG_PRINTK_TIME=y +CONFIG_DEBUG_INFO=y +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_FRAME_WARN=1024 +CONFIG_UNUSED_SYMBOLS=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_KERNEL=y +CONFIG_TIMER_STATS=y +CONFIG_RCU_TORTURE_TEST=m +CONFIG_RCU_CPU_STALL_TIMEOUT=60 +CONFIG_LATENCYTOP=y +CONFIG_BLK_DEV_IO_TRACE=y +# CONFIG_KPROBE_EVENT is not set +CONFIG_LKDTM=m +CONFIG_ATOMIC64_SELFTEST=y +# CONFIG_STRICT_DEVMEM is not set +CONFIG_S390_PTDUMP=y +CONFIG_ENCRYPTED_KEYS=m +CONFIG_KEYS_DEBUG_PROC_KEYS=y +CONFIG_SECURITY=y +CONFIG_SECURITY_NETWORK=y +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_SELINUX_BOOTPARAM=y +CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 +CONFIG_SECURITY_SELINUX_DISABLE=y +CONFIG_IMA=y +CONFIG_IMA_APPRAISE=y +CONFIG_CRYPTO_USER=m +# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_TEST=m +CONFIG_CRYPTO_CCM=m +CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_XTS=m +CONFIG_CRYPTO_XCBC=m +CONFIG_CRYPTO_VMAC=m +CONFIG_CRYPTO_CRC32=m +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_RMD128=m +CONFIG_CRYPTO_RMD160=m +CONFIG_CRYPTO_RMD256=m +CONFIG_CRYPTO_RMD320=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_SALSA20=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_ZLIB=y +CONFIG_CRYPTO_LZO=m +CONFIG_CRYPTO_LZ4=m +CONFIG_CRYPTO_LZ4HC=m +CONFIG_CRYPTO_USER_API_HASH=m +CONFIG_CRYPTO_USER_API_SKCIPHER=m +CONFIG_ZCRYPT=m +CONFIG_CRYPTO_SHA1_S390=m +CONFIG_CRYPTO_SHA256_S390=m +CONFIG_CRYPTO_SHA512_S390=m +CONFIG_CRYPTO_DES_S390=m +CONFIG_CRYPTO_AES_S390=m +CONFIG_CRYPTO_GHASH_S390=m +CONFIG_ASYMMETRIC_KEY_TYPE=m +CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=m +CONFIG_PUBLIC_KEY_ALGO_RSA=m +CONFIG_X509_CERTIFICATE_PARSER=m +CONFIG_CRC7=m +CONFIG_CRC8=m +CONFIG_XZ_DEC_X86=y +CONFIG_XZ_DEC_POWERPC=y +CONFIG_XZ_DEC_IA64=y +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_ARMTHUMB=y +CONFIG_XZ_DEC_SPARC=y +CONFIG_CORDIC=m +CONFIG_CMM=m +CONFIG_APPLDATA_BASE=y +CONFIG_KVM=m +CONFIG_KVM_S390_UCONTROL=y diff --git a/arch/s390/configs/zfcpdump_defconfig b/arch/s390/configs/zfcpdump_defconfig new file mode 100644 index 000000000000..d725c4d956e4 --- /dev/null +++ b/arch/s390/configs/zfcpdump_defconfig @@ -0,0 +1,86 @@ +# CONFIG_SWAP is not set +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_RCU_FAST_NO_HZ=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +# CONFIG_COMPAT_BRK is not set +CONFIG_PARTITION_ADVANCED=y +CONFIG_IBM_PARTITION=y +CONFIG_DEFAULT_DEADLINE=y +CONFIG_MARCH_Z9_109=y +# CONFIG_COMPAT is not set +CONFIG_NR_CPUS=2 +# CONFIG_HOTPLUG_CPU is not set +CONFIG_HZ_100=y +# CONFIG_COMPACTION is not set +# CONFIG_MIGRATION is not set +# CONFIG_CHECK_STACK is not set +# CONFIG_CHSC_SCH is not set +# CONFIG_SCM_BUS is not set +CONFIG_CRASH_DUMP=y +CONFIG_ZFCPDUMP=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_SECCOMP is not set +# CONFIG_IUCV is not set +CONFIG_ATM=y +CONFIG_ATM_LANE=y +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y +# CONFIG_FIRMWARE_IN_KERNEL is not set +# CONFIG_BLK_DEV_XPRAM is not set +# CONFIG_DCSSBLK is not set +# CONFIG_DASD is not set +CONFIG_ENCLOSURE_SERVICES=y +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y +CONFIG_SCSI_ENCLOSURE=y +CONFIG_SCSI_MULTI_LUN=y +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_SRP_ATTRS=y +CONFIG_ZFCP=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_SERIO is not set +# CONFIG_HVC_IUCV is not set +CONFIG_RAW_DRIVER=y +# CONFIG_SCLP_ASYNC is not set +# CONFIG_HMC_DRV is not set +# CONFIG_S390_TAPE is not set +# CONFIG_VMCP is not set +# CONFIG_MONWRITER is not set +# CONFIG_S390_VMUR is not set +# CONFIG_HID is not set +CONFIG_MEMSTICK=y +CONFIG_MEMSTICK_DEBUG=y +CONFIG_MEMSTICK_UNSAFE_RESUME=y +CONFIG_MSPRO_BLOCK=y +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_EXT2_FS=y +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +# CONFIG_INOTIFY_USER is not set +CONFIG_CONFIGFS_FS=y +CONFIG_PRINTK_TIME=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_FS=y +CONFIG_DEBUG_KERNEL=y +# CONFIG_SCHED_DEBUG is not set +CONFIG_RCU_CPU_STALL_TIMEOUT=60 +# CONFIG_FTRACE is not set +# CONFIG_STRICT_DEVMEM is not set +CONFIG_XZ_DEC_X86=y +CONFIG_XZ_DEC_POWERPC=y +CONFIG_XZ_DEC_IA64=y +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_ARMTHUMB=y +CONFIG_XZ_DEC_SPARC=y +# CONFIG_PFAULT is not set +# CONFIG_S390_HYPFS_FS is not set +# CONFIG_VIRTUALIZATION is not set +# CONFIG_S390_GUEST is not set diff --git a/arch/s390/crypto/aes_s390.c b/arch/s390/crypto/aes_s390.c index b4dbade8ca24..46cae138ece2 100644 --- a/arch/s390/crypto/aes_s390.c +++ b/arch/s390/crypto/aes_s390.c @@ -725,6 +725,8 @@ static struct crypto_alg xts_aes_alg = { } }; +static int xts_aes_alg_reg; + static int ctr_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, unsigned int key_len) { @@ -846,6 +848,8 @@ static struct crypto_alg ctr_aes_alg = { } }; +static int ctr_aes_alg_reg; + static int __init aes_s390_init(void) { int ret; @@ -884,6 +888,7 @@ static int __init aes_s390_init(void) ret = crypto_register_alg(&xts_aes_alg); if (ret) goto xts_aes_err; + xts_aes_alg_reg = 1; } if (crypt_s390_func_available(KMCTR_AES_128_ENCRYPT, @@ -902,6 +907,7 @@ static int __init aes_s390_init(void) free_page((unsigned long) ctrblk); goto ctr_aes_err; } + ctr_aes_alg_reg = 1; } out: @@ -921,9 +927,12 @@ aes_err: static void __exit aes_s390_fini(void) { - crypto_unregister_alg(&ctr_aes_alg); - free_page((unsigned long) ctrblk); - crypto_unregister_alg(&xts_aes_alg); + if (ctr_aes_alg_reg) { + crypto_unregister_alg(&ctr_aes_alg); + free_page((unsigned long) ctrblk); + } + if (xts_aes_alg_reg) + crypto_unregister_alg(&xts_aes_alg); crypto_unregister_alg(&cbc_aes_alg); crypto_unregister_alg(&ecb_aes_alg); crypto_unregister_alg(&aes_alg); diff --git a/arch/s390/defconfig b/arch/s390/defconfig index d204c65bf722..33f57514f424 100644 --- a/arch/s390/defconfig +++ b/arch/s390/defconfig @@ -38,13 +38,14 @@ CONFIG_MODULE_UNLOAD=y CONFIG_MODVERSIONS=y CONFIG_PARTITION_ADVANCED=y CONFIG_IBM_PARTITION=y -# CONFIG_EFI_PARTITION is not set CONFIG_DEFAULT_DEADLINE=y +CONFIG_MARCH_Z196=y CONFIG_HZ_100=y CONFIG_MEMORY_HOTPLUG=y CONFIG_MEMORY_HOTREMOVE=y CONFIG_KSM=y CONFIG_TRANSPARENT_HUGEPAGE=y +CONFIG_CMA=y CONFIG_CRASH_DUMP=y CONFIG_BINFMT_MISC=m CONFIG_HIBERNATION=y @@ -152,6 +153,7 @@ CONFIG_CRYPTO_CMAC=m CONFIG_CRYPTO_XCBC=m CONFIG_CRYPTO_VMAC=m CONFIG_CRYPTO_CRC32=m +CONFIG_CRYPTO_CRCT10DIF=m CONFIG_CRYPTO_MD4=m CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_RMD128=m diff --git a/arch/s390/include/asm/Kbuild b/arch/s390/include/asm/Kbuild index f313f9cbcf44..7a5288f3479a 100644 --- a/arch/s390/include/asm/Kbuild +++ b/arch/s390/include/asm/Kbuild @@ -2,3 +2,4 @@ generic-y += clkdev.h generic-y += trace_clock.h +generic-y += preempt.h diff --git a/arch/s390/include/asm/atomic.h b/arch/s390/include/asm/atomic.h index c797832daa5f..fa9aaf7144b7 100644 --- a/arch/s390/include/asm/atomic.h +++ b/arch/s390/include/asm/atomic.h @@ -19,21 +19,50 @@ #define ATOMIC_INIT(i) { (i) } -#define __CS_LOOP(ptr, op_val, op_string) ({ \ +#ifdef CONFIG_HAVE_MARCH_Z196_FEATURES + +#define __ATOMIC_OR "lao" +#define __ATOMIC_AND "lan" +#define __ATOMIC_ADD "laa" + +#define __ATOMIC_LOOP(ptr, op_val, op_string) \ +({ \ + int old_val; \ + \ + typecheck(atomic_t *, ptr); \ + asm volatile( \ + op_string " %0,%2,%1\n" \ + : "=d" (old_val), "+Q" ((ptr)->counter) \ + : "d" (op_val) \ + : "cc", "memory"); \ + old_val; \ +}) + +#else /* CONFIG_HAVE_MARCH_Z196_FEATURES */ + +#define __ATOMIC_OR "or" +#define __ATOMIC_AND "nr" +#define __ATOMIC_ADD "ar" + +#define __ATOMIC_LOOP(ptr, op_val, op_string) \ +({ \ int old_val, new_val; \ + \ + typecheck(atomic_t *, ptr); \ asm volatile( \ " l %0,%2\n" \ "0: lr %1,%0\n" \ op_string " %1,%3\n" \ " cs %0,%1,%2\n" \ " jl 0b" \ - : "=&d" (old_val), "=&d" (new_val), \ - "=Q" (((atomic_t *)(ptr))->counter) \ - : "d" (op_val), "Q" (((atomic_t *)(ptr))->counter) \ + : "=&d" (old_val), "=&d" (new_val), "+Q" ((ptr)->counter)\ + : "d" (op_val) \ : "cc", "memory"); \ - new_val; \ + old_val; \ }) +#endif /* CONFIG_HAVE_MARCH_Z196_FEATURES */ + static inline int atomic_read(const atomic_t *v) { int c; @@ -53,32 +82,45 @@ static inline void atomic_set(atomic_t *v, int i) static inline int atomic_add_return(int i, atomic_t *v) { - return __CS_LOOP(v, i, "ar"); + return __ATOMIC_LOOP(v, i, __ATOMIC_ADD) + i; } -#define atomic_add(_i, _v) atomic_add_return(_i, _v) -#define atomic_add_negative(_i, _v) (atomic_add_return(_i, _v) < 0) -#define atomic_inc(_v) atomic_add_return(1, _v) -#define atomic_inc_return(_v) atomic_add_return(1, _v) -#define atomic_inc_and_test(_v) (atomic_add_return(1, _v) == 0) -static inline int atomic_sub_return(int i, atomic_t *v) +static inline void atomic_add(int i, atomic_t *v) { - return __CS_LOOP(v, i, "sr"); +#ifdef CONFIG_HAVE_MARCH_Z196_FEATURES + if (__builtin_constant_p(i) && (i > -129) && (i < 128)) { + asm volatile( + "asi %0,%1\n" + : "+Q" (v->counter) + : "i" (i) + : "cc", "memory"); + } else { + atomic_add_return(i, v); + } +#else + atomic_add_return(i, v); +#endif } -#define atomic_sub(_i, _v) atomic_sub_return(_i, _v) + +#define atomic_add_negative(_i, _v) (atomic_add_return(_i, _v) < 0) +#define atomic_inc(_v) atomic_add(1, _v) +#define atomic_inc_return(_v) atomic_add_return(1, _v) +#define atomic_inc_and_test(_v) (atomic_add_return(1, _v) == 0) +#define atomic_sub(_i, _v) atomic_add(-(int)(_i), _v) +#define atomic_sub_return(_i, _v) atomic_add_return(-(int)(_i), _v) #define atomic_sub_and_test(_i, _v) (atomic_sub_return(_i, _v) == 0) -#define atomic_dec(_v) atomic_sub_return(1, _v) +#define atomic_dec(_v) atomic_sub(1, _v) #define atomic_dec_return(_v) atomic_sub_return(1, _v) #define atomic_dec_and_test(_v) (atomic_sub_return(1, _v) == 0) -static inline void atomic_clear_mask(unsigned long mask, atomic_t *v) +static inline void atomic_clear_mask(unsigned int mask, atomic_t *v) { - __CS_LOOP(v, ~mask, "nr"); + __ATOMIC_LOOP(v, ~mask, __ATOMIC_AND); } -static inline void atomic_set_mask(unsigned long mask, atomic_t *v) +static inline void atomic_set_mask(unsigned int mask, atomic_t *v) { - __CS_LOOP(v, mask, "or"); + __ATOMIC_LOOP(v, mask, __ATOMIC_OR); } #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) @@ -87,8 +129,8 @@ static inline int atomic_cmpxchg(atomic_t *v, int old, int new) { asm volatile( " cs %0,%2,%1" - : "+d" (old), "=Q" (v->counter) - : "d" (new), "Q" (v->counter) + : "+d" (old), "+Q" (v->counter) + : "d" (new) : "cc", "memory"); return old; } @@ -109,27 +151,56 @@ static inline int __atomic_add_unless(atomic_t *v, int a, int u) } -#undef __CS_LOOP +#undef __ATOMIC_LOOP #define ATOMIC64_INIT(i) { (i) } #ifdef CONFIG_64BIT -#define __CSG_LOOP(ptr, op_val, op_string) ({ \ +#ifdef CONFIG_HAVE_MARCH_Z196_FEATURES + +#define __ATOMIC64_OR "laog" +#define __ATOMIC64_AND "lang" +#define __ATOMIC64_ADD "laag" + +#define __ATOMIC64_LOOP(ptr, op_val, op_string) \ +({ \ + long long old_val; \ + \ + typecheck(atomic64_t *, ptr); \ + asm volatile( \ + op_string " %0,%2,%1\n" \ + : "=d" (old_val), "+Q" ((ptr)->counter) \ + : "d" (op_val) \ + : "cc", "memory"); \ + old_val; \ +}) + +#else /* CONFIG_HAVE_MARCH_Z196_FEATURES */ + +#define __ATOMIC64_OR "ogr" +#define __ATOMIC64_AND "ngr" +#define __ATOMIC64_ADD "agr" + +#define __ATOMIC64_LOOP(ptr, op_val, op_string) \ +({ \ long long old_val, new_val; \ + \ + typecheck(atomic64_t *, ptr); \ asm volatile( \ " lg %0,%2\n" \ "0: lgr %1,%0\n" \ op_string " %1,%3\n" \ " csg %0,%1,%2\n" \ " jl 0b" \ - : "=&d" (old_val), "=&d" (new_val), \ - "=Q" (((atomic_t *)(ptr))->counter) \ - : "d" (op_val), "Q" (((atomic_t *)(ptr))->counter) \ + : "=&d" (old_val), "=&d" (new_val), "+Q" ((ptr)->counter)\ + : "d" (op_val) \ : "cc", "memory"); \ - new_val; \ + old_val; \ }) +#endif /* CONFIG_HAVE_MARCH_Z196_FEATURES */ + static inline long long atomic64_read(const atomic64_t *v) { long long c; @@ -149,22 +220,17 @@ static inline void atomic64_set(atomic64_t *v, long long i) static inline long long atomic64_add_return(long long i, atomic64_t *v) { - return __CSG_LOOP(v, i, "agr"); -} - -static inline long long atomic64_sub_return(long long i, atomic64_t *v) -{ - return __CSG_LOOP(v, i, "sgr"); + return __ATOMIC64_LOOP(v, i, __ATOMIC64_ADD) + i; } static inline void atomic64_clear_mask(unsigned long mask, atomic64_t *v) { - __CSG_LOOP(v, ~mask, "ngr"); + __ATOMIC64_LOOP(v, ~mask, __ATOMIC64_AND); } static inline void atomic64_set_mask(unsigned long mask, atomic64_t *v) { - __CSG_LOOP(v, mask, "ogr"); + __ATOMIC64_LOOP(v, mask, __ATOMIC64_OR); } #define atomic64_xchg(v, new) (xchg(&((v)->counter), new)) @@ -174,13 +240,13 @@ static inline long long atomic64_cmpxchg(atomic64_t *v, { asm volatile( " csg %0,%2,%1" - : "+d" (old), "=Q" (v->counter) - : "d" (new), "Q" (v->counter) + : "+d" (old), "+Q" (v->counter) + : "d" (new) : "cc", "memory"); return old; } -#undef __CSG_LOOP +#undef __ATOMIC64_LOOP #else /* CONFIG_64BIT */ @@ -216,8 +282,8 @@ static inline long long atomic64_xchg(atomic64_t *v, long long new) " lm %0,%N0,%1\n" "0: cds %0,%2,%1\n" " jl 0b\n" - : "=&d" (rp_old), "=Q" (v->counter) - : "d" (rp_new), "Q" (v->counter) + : "=&d" (rp_old), "+Q" (v->counter) + : "d" (rp_new) : "cc"); return rp_old.pair; } @@ -230,8 +296,8 @@ static inline long long atomic64_cmpxchg(atomic64_t *v, asm volatile( " cds %0,%2,%1" - : "+&d" (rp_old), "=Q" (v->counter) - : "d" (rp_new), "Q" (v->counter) + : "+&d" (rp_old), "+Q" (v->counter) + : "d" (rp_new) : "cc"); return rp_old.pair; } @@ -248,17 +314,6 @@ static inline long long atomic64_add_return(long long i, atomic64_t *v) return new; } -static inline long long atomic64_sub_return(long long i, atomic64_t *v) -{ - long long old, new; - - do { - old = atomic64_read(v); - new = old - i; - } while (atomic64_cmpxchg(v, old, new) != old); - return new; -} - static inline void atomic64_set_mask(unsigned long long mask, atomic64_t *v) { long long old, new; @@ -281,7 +336,24 @@ static inline void atomic64_clear_mask(unsigned long long mask, atomic64_t *v) #endif /* CONFIG_64BIT */ -static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u) +static inline void atomic64_add(long long i, atomic64_t *v) +{ +#ifdef CONFIG_HAVE_MARCH_Z196_FEATURES + if (__builtin_constant_p(i) && (i > -129) && (i < 128)) { + asm volatile( + "agsi %0,%1\n" + : "+Q" (v->counter) + : "i" (i) + : "cc", "memory"); + } else { + atomic64_add_return(i, v); + } +#else + atomic64_add_return(i, v); +#endif +} + +static inline int atomic64_add_unless(atomic64_t *v, long long i, long long u) { long long c, old; @@ -289,7 +361,7 @@ static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u) for (;;) { if (unlikely(c == u)) break; - old = atomic64_cmpxchg(v, c, c + a); + old = atomic64_cmpxchg(v, c, c + i); if (likely(old == c)) break; c = old; @@ -314,14 +386,14 @@ static inline long long atomic64_dec_if_positive(atomic64_t *v) return dec; } -#define atomic64_add(_i, _v) atomic64_add_return(_i, _v) #define atomic64_add_negative(_i, _v) (atomic64_add_return(_i, _v) < 0) -#define atomic64_inc(_v) atomic64_add_return(1, _v) +#define atomic64_inc(_v) atomic64_add(1, _v) #define atomic64_inc_return(_v) atomic64_add_return(1, _v) #define atomic64_inc_and_test(_v) (atomic64_add_return(1, _v) == 0) -#define atomic64_sub(_i, _v) atomic64_sub_return(_i, _v) +#define atomic64_sub_return(_i, _v) atomic64_add_return(-(long long)(_i), _v) +#define atomic64_sub(_i, _v) atomic64_add(-(long long)(_i), _v) #define atomic64_sub_and_test(_i, _v) (atomic64_sub_return(_i, _v) == 0) -#define atomic64_dec(_v) atomic64_sub_return(1, _v) +#define atomic64_dec(_v) atomic64_sub(1, _v) #define atomic64_dec_return(_v) atomic64_sub_return(1, _v) #define atomic64_dec_and_test(_v) (atomic64_sub_return(1, _v) == 0) #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) diff --git a/arch/s390/include/asm/bitops.h b/arch/s390/include/asm/bitops.h index 10135a38673c..6e6ad0680829 100644 --- a/arch/s390/include/asm/bitops.h +++ b/arch/s390/include/asm/bitops.h @@ -1,10 +1,40 @@ /* - * S390 version - * Copyright IBM Corp. 1999 - * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) + * Copyright IBM Corp. 1999,2013 * - * Derived from "include/asm-i386/bitops.h" - * Copyright (C) 1992, Linus Torvalds + * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>, + * + * The description below was taken in large parts from the powerpc + * bitops header file: + * Within a word, bits are numbered LSB first. Lot's of places make + * this assumption by directly testing bits with (val & (1<<nr)). + * This can cause confusion for large (> 1 word) bitmaps on a + * big-endian system because, unlike little endian, the number of each + * bit depends on the word size. + * + * The bitop functions are defined to work on unsigned longs, so for an + * s390x system the bits end up numbered: + * |63..............0|127............64|191...........128|255...........196| + * and on s390: + * |31.....0|63....31|95....64|127...96|159..128|191..160|223..192|255..224| + * + * There are a few little-endian macros used mostly for filesystem + * bitmaps, these work on similar bit arrays layouts, but + * byte-oriented: + * |7...0|15...8|23...16|31...24|39...32|47...40|55...48|63...56| + * + * The main difference is that bit 3-5 (64b) or 3-4 (32b) in the bit + * number field needs to be reversed compared to the big-endian bit + * fields. This can be achieved by XOR with 0x38 (64b) or 0x18 (32b). + * + * We also have special functions which work with an MSB0 encoding: + * on an s390x system the bits are numbered: + * |0..............63|64............127|128...........191|192...........255| + * and on s390: + * |0.....31|31....63|64....95|96...127|128..159|160..191|192..223|224..255| + * + * The main difference is that bit 0-63 (64b) or 0-31 (32b) in the bit + * number field needs to be reversed compared to the LSB0 encoded bit + * fields. This can be achieved by XOR with 0x3f (64b) or 0x1f (32b). * */ @@ -15,556 +45,348 @@ #error only <linux/bitops.h> can be included directly #endif +#include <linux/typecheck.h> #include <linux/compiler.h> -/* - * 32 bit bitops format: - * bit 0 is the LSB of *addr; bit 31 is the MSB of *addr; - * bit 32 is the LSB of *(addr+4). That combined with the - * big endian byte order on S390 give the following bit - * order in memory: - * 1f 1e 1d 1c 1b 1a 19 18 17 16 15 14 13 12 11 10 \ - * 0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00 - * after that follows the next long with bit numbers - * 3f 3e 3d 3c 3b 3a 39 38 37 36 35 34 33 32 31 30 - * 2f 2e 2d 2c 2b 2a 29 28 27 26 25 24 23 22 21 20 - * The reason for this bit ordering is the fact that - * in the architecture independent code bits operations - * of the form "flags |= (1 << bitnr)" are used INTERMIXED - * with operation of the form "set_bit(bitnr, flags)". - * - * 64 bit bitops format: - * bit 0 is the LSB of *addr; bit 63 is the MSB of *addr; - * bit 64 is the LSB of *(addr+8). That combined with the - * big endian byte order on S390 give the following bit - * order in memory: - * 3f 3e 3d 3c 3b 3a 39 38 37 36 35 34 33 32 31 30 - * 2f 2e 2d 2c 2b 2a 29 28 27 26 25 24 23 22 21 20 - * 1f 1e 1d 1c 1b 1a 19 18 17 16 15 14 13 12 11 10 - * 0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00 - * after that follows the next long with bit numbers - * 7f 7e 7d 7c 7b 7a 79 78 77 76 75 74 73 72 71 70 - * 6f 6e 6d 6c 6b 6a 69 68 67 66 65 64 63 62 61 60 - * 5f 5e 5d 5c 5b 5a 59 58 57 56 55 54 53 52 51 50 - * 4f 4e 4d 4c 4b 4a 49 48 47 46 45 44 43 42 41 40 - * The reason for this bit ordering is the fact that - * in the architecture independent code bits operations - * of the form "flags |= (1 << bitnr)" are used INTERMIXED - * with operation of the form "set_bit(bitnr, flags)". - */ - -/* bitmap tables from arch/s390/kernel/bitmap.c */ -extern const char _oi_bitmap[]; -extern const char _ni_bitmap[]; -extern const char _zb_findmap[]; -extern const char _sb_findmap[]; - #ifndef CONFIG_64BIT #define __BITOPS_OR "or" #define __BITOPS_AND "nr" #define __BITOPS_XOR "xr" -#define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string) \ +#define __BITOPS_LOOP(__addr, __val, __op_string) \ +({ \ + unsigned long __old, __new; \ + \ + typecheck(unsigned long *, (__addr)); \ asm volatile( \ " l %0,%2\n" \ "0: lr %1,%0\n" \ __op_string " %1,%3\n" \ " cs %0,%1,%2\n" \ " jl 0b" \ - : "=&d" (__old), "=&d" (__new), \ - "=Q" (*(unsigned long *) __addr) \ - : "d" (__val), "Q" (*(unsigned long *) __addr) \ - : "cc"); + : "=&d" (__old), "=&d" (__new), "+Q" (*(__addr))\ + : "d" (__val) \ + : "cc"); \ + __old; \ +}) #else /* CONFIG_64BIT */ +#ifdef CONFIG_HAVE_MARCH_Z196_FEATURES + +#define __BITOPS_OR "laog" +#define __BITOPS_AND "lang" +#define __BITOPS_XOR "laxg" + +#define __BITOPS_LOOP(__addr, __val, __op_string) \ +({ \ + unsigned long __old; \ + \ + typecheck(unsigned long *, (__addr)); \ + asm volatile( \ + __op_string " %0,%2,%1\n" \ + : "=d" (__old), "+Q" (*(__addr)) \ + : "d" (__val) \ + : "cc"); \ + __old; \ +}) + +#else /* CONFIG_HAVE_MARCH_Z196_FEATURES */ + #define __BITOPS_OR "ogr" #define __BITOPS_AND "ngr" #define __BITOPS_XOR "xgr" -#define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string) \ +#define __BITOPS_LOOP(__addr, __val, __op_string) \ +({ \ + unsigned long __old, __new; \ + \ + typecheck(unsigned long *, (__addr)); \ asm volatile( \ " lg %0,%2\n" \ "0: lgr %1,%0\n" \ __op_string " %1,%3\n" \ " csg %0,%1,%2\n" \ " jl 0b" \ - : "=&d" (__old), "=&d" (__new), \ - "=Q" (*(unsigned long *) __addr) \ - : "d" (__val), "Q" (*(unsigned long *) __addr) \ - : "cc"); + : "=&d" (__old), "=&d" (__new), "+Q" (*(__addr))\ + : "d" (__val) \ + : "cc"); \ + __old; \ +}) + +#endif /* CONFIG_HAVE_MARCH_Z196_FEATURES */ #endif /* CONFIG_64BIT */ #define __BITOPS_WORDS(bits) (((bits) + BITS_PER_LONG - 1) / BITS_PER_LONG) -#ifdef CONFIG_SMP -/* - * SMP safe set_bit routine based on compare and swap (CS) - */ -static inline void set_bit_cs(unsigned long nr, volatile unsigned long *ptr) +static inline unsigned long * +__bitops_word(unsigned long nr, volatile unsigned long *ptr) +{ + unsigned long addr; + + addr = (unsigned long)ptr + ((nr ^ (nr & (BITS_PER_LONG - 1))) >> 3); + return (unsigned long *)addr; +} + +static inline unsigned char * +__bitops_byte(unsigned long nr, volatile unsigned long *ptr) { - unsigned long addr, old, new, mask; + return ((unsigned char *)ptr) + ((nr ^ (BITS_PER_LONG - 8)) >> 3); +} + +static inline void set_bit(unsigned long nr, volatile unsigned long *ptr) +{ + unsigned long *addr = __bitops_word(nr, ptr); + unsigned long mask; - addr = (unsigned long) ptr; - /* calculate address for CS */ - addr += (nr ^ (nr & (BITS_PER_LONG - 1))) >> 3; - /* make OR mask */ +#ifdef CONFIG_HAVE_MARCH_ZEC12_FEATURES + if (__builtin_constant_p(nr)) { + unsigned char *caddr = __bitops_byte(nr, ptr); + + asm volatile( + "oi %0,%b1\n" + : "+Q" (*caddr) + : "i" (1 << (nr & 7)) + : "cc"); + return; + } +#endif mask = 1UL << (nr & (BITS_PER_LONG - 1)); - /* Do the atomic update. */ - __BITOPS_LOOP(old, new, addr, mask, __BITOPS_OR); + __BITOPS_LOOP(addr, mask, __BITOPS_OR); } -/* - * SMP safe clear_bit routine based on compare and swap (CS) - */ -static inline void clear_bit_cs(unsigned long nr, volatile unsigned long *ptr) +static inline void clear_bit(unsigned long nr, volatile unsigned long *ptr) { - unsigned long addr, old, new, mask; + unsigned long *addr = __bitops_word(nr, ptr); + unsigned long mask; + +#ifdef CONFIG_HAVE_MARCH_ZEC12_FEATURES + if (__builtin_constant_p(nr)) { + unsigned char *caddr = __bitops_byte(nr, ptr); - addr = (unsigned long) ptr; - /* calculate address for CS */ - addr += (nr ^ (nr & (BITS_PER_LONG - 1))) >> 3; - /* make AND mask */ + asm volatile( + "ni %0,%b1\n" + : "+Q" (*caddr) + : "i" (~(1 << (nr & 7))) + : "cc"); + return; + } +#endif mask = ~(1UL << (nr & (BITS_PER_LONG - 1))); - /* Do the atomic update. */ - __BITOPS_LOOP(old, new, addr, mask, __BITOPS_AND); + __BITOPS_LOOP(addr, mask, __BITOPS_AND); } -/* - * SMP safe change_bit routine based on compare and swap (CS) - */ -static inline void change_bit_cs(unsigned long nr, volatile unsigned long *ptr) +static inline void change_bit(unsigned long nr, volatile unsigned long *ptr) { - unsigned long addr, old, new, mask; + unsigned long *addr = __bitops_word(nr, ptr); + unsigned long mask; + +#ifdef CONFIG_HAVE_MARCH_ZEC12_FEATURES + if (__builtin_constant_p(nr)) { + unsigned char *caddr = __bitops_byte(nr, ptr); - addr = (unsigned long) ptr; - /* calculate address for CS */ - addr += (nr ^ (nr & (BITS_PER_LONG - 1))) >> 3; - /* make XOR mask */ + asm volatile( + "xi %0,%b1\n" + : "+Q" (*caddr) + : "i" (1 << (nr & 7)) + : "cc"); + return; + } +#endif mask = 1UL << (nr & (BITS_PER_LONG - 1)); - /* Do the atomic update. */ - __BITOPS_LOOP(old, new, addr, mask, __BITOPS_XOR); + __BITOPS_LOOP(addr, mask, __BITOPS_XOR); } -/* - * SMP safe test_and_set_bit routine based on compare and swap (CS) - */ static inline int -test_and_set_bit_cs(unsigned long nr, volatile unsigned long *ptr) +test_and_set_bit(unsigned long nr, volatile unsigned long *ptr) { - unsigned long addr, old, new, mask; + unsigned long *addr = __bitops_word(nr, ptr); + unsigned long old, mask; - addr = (unsigned long) ptr; - /* calculate address for CS */ - addr += (nr ^ (nr & (BITS_PER_LONG - 1))) >> 3; - /* make OR/test mask */ mask = 1UL << (nr & (BITS_PER_LONG - 1)); - /* Do the atomic update. */ - __BITOPS_LOOP(old, new, addr, mask, __BITOPS_OR); + old = __BITOPS_LOOP(addr, mask, __BITOPS_OR); barrier(); return (old & mask) != 0; } -/* - * SMP safe test_and_clear_bit routine based on compare and swap (CS) - */ static inline int -test_and_clear_bit_cs(unsigned long nr, volatile unsigned long *ptr) +test_and_clear_bit(unsigned long nr, volatile unsigned long *ptr) { - unsigned long addr, old, new, mask; + unsigned long *addr = __bitops_word(nr, ptr); + unsigned long old, mask; - addr = (unsigned long) ptr; - /* calculate address for CS */ - addr += (nr ^ (nr & (BITS_PER_LONG - 1))) >> 3; - /* make AND/test mask */ mask = ~(1UL << (nr & (BITS_PER_LONG - 1))); - /* Do the atomic update. */ - __BITOPS_LOOP(old, new, addr, mask, __BITOPS_AND); + old = __BITOPS_LOOP(addr, mask, __BITOPS_AND); barrier(); - return (old ^ new) != 0; + return (old & ~mask) != 0; } -/* - * SMP safe test_and_change_bit routine based on compare and swap (CS) - */ static inline int -test_and_change_bit_cs(unsigned long nr, volatile unsigned long *ptr) +test_and_change_bit(unsigned long nr, volatile unsigned long *ptr) { - unsigned long addr, old, new, mask; + unsigned long *addr = __bitops_word(nr, ptr); + unsigned long old, mask; - addr = (unsigned long) ptr; - /* calculate address for CS */ - addr += (nr ^ (nr & (BITS_PER_LONG - 1))) >> 3; - /* make XOR/test mask */ mask = 1UL << (nr & (BITS_PER_LONG - 1)); - /* Do the atomic update. */ - __BITOPS_LOOP(old, new, addr, mask, __BITOPS_XOR); + old = __BITOPS_LOOP(addr, mask, __BITOPS_XOR); barrier(); return (old & mask) != 0; } -#endif /* CONFIG_SMP */ -/* - * fast, non-SMP set_bit routine - */ static inline void __set_bit(unsigned long nr, volatile unsigned long *ptr) { - unsigned long addr; - - addr = (unsigned long) ptr + ((nr ^ (BITS_PER_LONG - 8)) >> 3); - asm volatile( - " oc %O0(1,%R0),%1" - : "+Q" (*(char *) addr) : "Q" (_oi_bitmap[nr & 7]) : "cc"); -} - -static inline void -__constant_set_bit(const unsigned long nr, volatile unsigned long *ptr) -{ - unsigned long addr; + unsigned char *addr = __bitops_byte(nr, ptr); - addr = ((unsigned long) ptr) + ((nr ^ (BITS_PER_LONG - 8)) >> 3); - *(unsigned char *) addr |= 1 << (nr & 7); + *addr |= 1 << (nr & 7); } -#define set_bit_simple(nr,addr) \ -(__builtin_constant_p((nr)) ? \ - __constant_set_bit((nr),(addr)) : \ - __set_bit((nr),(addr)) ) - -/* - * fast, non-SMP clear_bit routine - */ static inline void __clear_bit(unsigned long nr, volatile unsigned long *ptr) { - unsigned long addr; - - addr = (unsigned long) ptr + ((nr ^ (BITS_PER_LONG - 8)) >> 3); - asm volatile( - " nc %O0(1,%R0),%1" - : "+Q" (*(char *) addr) : "Q" (_ni_bitmap[nr & 7]) : "cc"); -} - -static inline void -__constant_clear_bit(const unsigned long nr, volatile unsigned long *ptr) -{ - unsigned long addr; + unsigned char *addr = __bitops_byte(nr, ptr); - addr = ((unsigned long) ptr) + ((nr ^ (BITS_PER_LONG - 8)) >> 3); - *(unsigned char *) addr &= ~(1 << (nr & 7)); + *addr &= ~(1 << (nr & 7)); } -#define clear_bit_simple(nr,addr) \ -(__builtin_constant_p((nr)) ? \ - __constant_clear_bit((nr),(addr)) : \ - __clear_bit((nr),(addr)) ) - -/* - * fast, non-SMP change_bit routine - */ static inline void __change_bit(unsigned long nr, volatile unsigned long *ptr) { - unsigned long addr; - - addr = (unsigned long) ptr + ((nr ^ (BITS_PER_LONG - 8)) >> 3); - asm volatile( - " xc %O0(1,%R0),%1" - : "+Q" (*(char *) addr) : "Q" (_oi_bitmap[nr & 7]) : "cc"); -} - -static inline void -__constant_change_bit(const unsigned long nr, volatile unsigned long *ptr) -{ - unsigned long addr; + unsigned char *addr = __bitops_byte(nr, ptr); - addr = ((unsigned long) ptr) + ((nr ^ (BITS_PER_LONG - 8)) >> 3); - *(unsigned char *) addr ^= 1 << (nr & 7); + *addr ^= 1 << (nr & 7); } -#define change_bit_simple(nr,addr) \ -(__builtin_constant_p((nr)) ? \ - __constant_change_bit((nr),(addr)) : \ - __change_bit((nr),(addr)) ) - -/* - * fast, non-SMP test_and_set_bit routine - */ static inline int -test_and_set_bit_simple(unsigned long nr, volatile unsigned long *ptr) +__test_and_set_bit(unsigned long nr, volatile unsigned long *ptr) { - unsigned long addr; + unsigned char *addr = __bitops_byte(nr, ptr); unsigned char ch; - addr = (unsigned long) ptr + ((nr ^ (BITS_PER_LONG - 8)) >> 3); - ch = *(unsigned char *) addr; - asm volatile( - " oc %O0(1,%R0),%1" - : "+Q" (*(char *) addr) : "Q" (_oi_bitmap[nr & 7]) - : "cc", "memory"); + ch = *addr; + *addr |= 1 << (nr & 7); return (ch >> (nr & 7)) & 1; } -#define __test_and_set_bit(X,Y) test_and_set_bit_simple(X,Y) -/* - * fast, non-SMP test_and_clear_bit routine - */ static inline int -test_and_clear_bit_simple(unsigned long nr, volatile unsigned long *ptr) +__test_and_clear_bit(unsigned long nr, volatile unsigned long *ptr) { - unsigned long addr; + unsigned char *addr = __bitops_byte(nr, ptr); unsigned char ch; - addr = (unsigned long) ptr + ((nr ^ (BITS_PER_LONG - 8)) >> 3); - ch = *(unsigned char *) addr; - asm volatile( - " nc %O0(1,%R0),%1" - : "+Q" (*(char *) addr) : "Q" (_ni_bitmap[nr & 7]) - : "cc", "memory"); + ch = *addr; + *addr &= ~(1 << (nr & 7)); return (ch >> (nr & 7)) & 1; } -#define __test_and_clear_bit(X,Y) test_and_clear_bit_simple(X,Y) -/* - * fast, non-SMP test_and_change_bit routine - */ static inline int -test_and_change_bit_simple(unsigned long nr, volatile unsigned long *ptr) +__test_and_change_bit(unsigned long nr, volatile unsigned long *ptr) { - unsigned long addr; + unsigned char *addr = __bitops_byte(nr, ptr); unsigned char ch; - addr = (unsigned long) ptr + ((nr ^ (BITS_PER_LONG - 8)) >> 3); - ch = *(unsigned char *) addr; - asm volatile( - " xc %O0(1,%R0),%1" - : "+Q" (*(char *) addr) : "Q" (_oi_bitmap[nr & 7]) - : "cc", "memory"); + ch = *addr; + *addr ^= 1 << (nr & 7); return (ch >> (nr & 7)) & 1; } -#define __test_and_change_bit(X,Y) test_and_change_bit_simple(X,Y) - -#ifdef CONFIG_SMP -#define set_bit set_bit_cs -#define clear_bit clear_bit_cs -#define change_bit change_bit_cs -#define test_and_set_bit test_and_set_bit_cs -#define test_and_clear_bit test_and_clear_bit_cs -#define test_and_change_bit test_and_change_bit_cs -#else -#define set_bit set_bit_simple -#define clear_bit clear_bit_simple -#define change_bit change_bit_simple -#define test_and_set_bit test_and_set_bit_simple -#define test_and_clear_bit test_and_clear_bit_simple -#define test_and_change_bit test_and_change_bit_simple -#endif - - -/* - * This routine doesn't need to be atomic. - */ -static inline int __test_bit(unsigned long nr, const volatile unsigned long *ptr) +static inline int test_bit(unsigned long nr, const volatile unsigned long *ptr) { - unsigned long addr; - unsigned char ch; - - addr = (unsigned long) ptr + ((nr ^ (BITS_PER_LONG - 8)) >> 3); - ch = *(volatile unsigned char *) addr; - return (ch >> (nr & 7)) & 1; -} + const volatile unsigned char *addr; -static inline int -__constant_test_bit(unsigned long nr, const volatile unsigned long *addr) { - return (((volatile char *) addr) - [(nr^(BITS_PER_LONG-8))>>3] & (1<<(nr&7))) != 0; + addr = ((const volatile unsigned char *)ptr); + addr += (nr ^ (BITS_PER_LONG - 8)) >> 3; + return (*addr >> (nr & 7)) & 1; } -#define test_bit(nr,addr) \ -(__builtin_constant_p((nr)) ? \ - __constant_test_bit((nr),(addr)) : \ - __test_bit((nr),(addr)) ) - /* - * Optimized find bit helper functions. - */ - -/** - * __ffz_word_loop - find byte offset of first long != -1UL - * @addr: pointer to array of unsigned long - * @size: size of the array in bits + * Functions which use MSB0 bit numbering. + * On an s390x system the bits are numbered: + * |0..............63|64............127|128...........191|192...........255| + * and on s390: + * |0.....31|31....63|64....95|96...127|128..159|160..191|192..223|224..255| */ -static inline unsigned long __ffz_word_loop(const unsigned long *addr, - unsigned long size) -{ - typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype; - unsigned long bytes = 0; - - asm volatile( -#ifndef CONFIG_64BIT - " ahi %1,-1\n" - " sra %1,5\n" - " jz 1f\n" - "0: c %2,0(%0,%3)\n" - " jne 1f\n" - " la %0,4(%0)\n" - " brct %1,0b\n" - "1:\n" -#else - " aghi %1,-1\n" - " srag %1,%1,6\n" - " jz 1f\n" - "0: cg %2,0(%0,%3)\n" - " jne 1f\n" - " la %0,8(%0)\n" - " brct %1,0b\n" - "1:\n" -#endif - : "+&a" (bytes), "+&d" (size) - : "d" (-1UL), "a" (addr), "m" (*(addrtype *) addr) - : "cc" ); - return bytes; -} +unsigned long find_first_bit_inv(const unsigned long *addr, unsigned long size); +unsigned long find_next_bit_inv(const unsigned long *addr, unsigned long size, + unsigned long offset); -/** - * __ffs_word_loop - find byte offset of first long != 0UL - * @addr: pointer to array of unsigned long - * @size: size of the array in bits - */ -static inline unsigned long __ffs_word_loop(const unsigned long *addr, - unsigned long size) +static inline void set_bit_inv(unsigned long nr, volatile unsigned long *ptr) { - typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype; - unsigned long bytes = 0; - - asm volatile( -#ifndef CONFIG_64BIT - " ahi %1,-1\n" - " sra %1,5\n" - " jz 1f\n" - "0: c %2,0(%0,%3)\n" - " jne 1f\n" - " la %0,4(%0)\n" - " brct %1,0b\n" - "1:\n" -#else - " aghi %1,-1\n" - " srag %1,%1,6\n" - " jz 1f\n" - "0: cg %2,0(%0,%3)\n" - " jne 1f\n" - " la %0,8(%0)\n" - " brct %1,0b\n" - "1:\n" -#endif - : "+&a" (bytes), "+&a" (size) - : "d" (0UL), "a" (addr), "m" (*(addrtype *) addr) - : "cc" ); - return bytes; + return set_bit(nr ^ (BITS_PER_LONG - 1), ptr); } -/** - * __ffz_word - add number of the first unset bit - * @nr: base value the bit number is added to - * @word: the word that is searched for unset bits - */ -static inline unsigned long __ffz_word(unsigned long nr, unsigned long word) +static inline void clear_bit_inv(unsigned long nr, volatile unsigned long *ptr) { -#ifdef CONFIG_64BIT - if ((word & 0xffffffff) == 0xffffffff) { - word >>= 32; - nr += 32; - } -#endif - if ((word & 0xffff) == 0xffff) { - word >>= 16; - nr += 16; - } - if ((word & 0xff) == 0xff) { - word >>= 8; - nr += 8; - } - return nr + _zb_findmap[(unsigned char) word]; + return clear_bit(nr ^ (BITS_PER_LONG - 1), ptr); } -/** - * __ffs_word - add number of the first set bit - * @nr: base value the bit number is added to - * @word: the word that is searched for set bits - */ -static inline unsigned long __ffs_word(unsigned long nr, unsigned long word) +static inline void __set_bit_inv(unsigned long nr, volatile unsigned long *ptr) { -#ifdef CONFIG_64BIT - if ((word & 0xffffffff) == 0) { - word >>= 32; - nr += 32; - } -#endif - if ((word & 0xffff) == 0) { - word >>= 16; - nr += 16; - } - if ((word & 0xff) == 0) { - word >>= 8; - nr += 8; - } - return nr + _sb_findmap[(unsigned char) word]; + return __set_bit(nr ^ (BITS_PER_LONG - 1), ptr); } - -/** - * __load_ulong_be - load big endian unsigned long - * @p: pointer to array of unsigned long - * @offset: byte offset of source value in the array - */ -static inline unsigned long __load_ulong_be(const unsigned long *p, - unsigned long offset) +static inline void __clear_bit_inv(unsigned long nr, volatile unsigned long *ptr) { - p = (unsigned long *)((unsigned long) p + offset); - return *p; + return __clear_bit(nr ^ (BITS_PER_LONG - 1), ptr); } -/** - * __load_ulong_le - load little endian unsigned long - * @p: pointer to array of unsigned long - * @offset: byte offset of source value in the array - */ -static inline unsigned long __load_ulong_le(const unsigned long *p, - unsigned long offset) +static inline int test_bit_inv(unsigned long nr, + const volatile unsigned long *ptr) { - unsigned long word; - - p = (unsigned long *)((unsigned long) p + offset); -#ifndef CONFIG_64BIT - asm volatile( - " ic %0,%O1(%R1)\n" - " icm %0,2,%O1+1(%R1)\n" - " icm %0,4,%O1+2(%R1)\n" - " icm %0,8,%O1+3(%R1)" - : "=&d" (word) : "Q" (*p) : "cc"); -#else - asm volatile( - " lrvg %0,%1" - : "=d" (word) : "m" (*p) ); -#endif - return word; + return test_bit(nr ^ (BITS_PER_LONG - 1), ptr); } -/* - * The various find bit functions. - */ +#ifdef CONFIG_HAVE_MARCH_Z9_109_FEATURES -/* - * ffz - find first zero in word. - * @word: The word to search +/** + * __flogr - find leftmost one + * @word - The word to search * - * Undefined if no zero exists, so code should check against ~0UL first. - */ -static inline unsigned long ffz(unsigned long word) -{ - return __ffz_word(0, word); + * Returns the bit number of the most significant bit set, + * where the most significant bit has bit number 0. + * If no bit is set this function returns 64. + */ +static inline unsigned char __flogr(unsigned long word) +{ + if (__builtin_constant_p(word)) { + unsigned long bit = 0; + + if (!word) + return 64; + if (!(word & 0xffffffff00000000UL)) { + word <<= 32; + bit += 32; + } + if (!(word & 0xffff000000000000UL)) { + word <<= 16; + bit += 16; + } + if (!(word & 0xff00000000000000UL)) { + word <<= 8; + bit += 8; + } + if (!(word & 0xf000000000000000UL)) { + word <<= 4; + bit += 4; + } + if (!(word & 0xc000000000000000UL)) { + word <<= 2; + bit += 2; + } + if (!(word & 0x8000000000000000UL)) { + word <<= 1; + bit += 1; + } + return bit; + } else { + register unsigned long bit asm("4") = word; + register unsigned long out asm("5"); + + asm volatile( + " flogr %[bit],%[bit]\n" + : [bit] "+d" (bit), [out] "=d" (out) : : "cc"); + return bit; + } } /** @@ -573,337 +395,83 @@ static inline unsigned long ffz(unsigned long word) * * Undefined if no bit exists, so code should check against 0 first. */ -static inline unsigned long __ffs (unsigned long word) +static inline unsigned long __ffs(unsigned long word) { - return __ffs_word(0, word); + return __flogr(-word & word) ^ (BITS_PER_LONG - 1); } /** * ffs - find first bit set - * @x: the word to search + * @word: the word to search * - * This is defined the same way as - * the libc and compiler builtin ffs routines, therefore - * differs in spirit from the above ffz (man ffs). + * This is defined the same way as the libc and + * compiler builtin ffs routines (man ffs). */ -static inline int ffs(int x) +static inline int ffs(int word) { - if (!x) - return 0; - return __ffs_word(1, x); + unsigned long mask = 2 * BITS_PER_LONG - 1; + unsigned int val = (unsigned int)word; + + return (1 + (__flogr(-val & val) ^ (BITS_PER_LONG - 1))) & mask; } /** - * find_first_zero_bit - find the first zero bit in a memory region - * @addr: The address to start the search at - * @size: The maximum size to search + * __fls - find last (most-significant) set bit in a long word + * @word: the word to search * - * Returns the bit-number of the first zero bit, not the number of the byte - * containing a bit. + * Undefined if no set bit exists, so code should check against 0 first. */ -static inline unsigned long find_first_zero_bit(const unsigned long *addr, - unsigned long size) +static inline unsigned long __fls(unsigned long word) { - unsigned long bytes, bits; - - if (!size) - return 0; - bytes = __ffz_word_loop(addr, size); - bits = __ffz_word(bytes*8, __load_ulong_be(addr, bytes)); - return (bits < size) ? bits : size; + return __flogr(word) ^ (BITS_PER_LONG - 1); } -#define find_first_zero_bit find_first_zero_bit /** - * find_first_bit - find the first set bit in a memory region - * @addr: The address to start the search at - * @size: The maximum size to search + * fls64 - find last set bit in a 64-bit word + * @word: the word to search * - * Returns the bit-number of the first set bit, not the number of the byte - * containing a bit. - */ -static inline unsigned long find_first_bit(const unsigned long * addr, - unsigned long size) -{ - unsigned long bytes, bits; - - if (!size) - return 0; - bytes = __ffs_word_loop(addr, size); - bits = __ffs_word(bytes*8, __load_ulong_be(addr, bytes)); - return (bits < size) ? bits : size; -} -#define find_first_bit find_first_bit - -/* - * Big endian variant whichs starts bit counting from left using - * the flogr (find leftmost one) instruction. - */ -static inline unsigned long __flo_word(unsigned long nr, unsigned long val) -{ - register unsigned long bit asm("2") = val; - register unsigned long out asm("3"); - - asm volatile ( - " .insn rre,0xb9830000,%[bit],%[bit]\n" - : [bit] "+d" (bit), [out] "=d" (out) : : "cc"); - return nr + bit; -} - -/* - * 64 bit special left bitops format: - * order in memory: - * 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f - * 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f - * 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f - * 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f - * after that follows the next long with bit numbers - * 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f - * 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f - * 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f - * 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f - * The reason for this bit ordering is the fact that - * the hardware sets bits in a bitmap starting at bit 0 - * and we don't want to scan the bitmap from the 'wrong - * end'. + * This is defined in a similar way as the libc and compiler builtin + * ffsll, but returns the position of the most significant set bit. + * + * fls64(value) returns 0 if value is 0 or the position of the last + * set bit if value is nonzero. The last (most significant) bit is + * at position 64. */ -static inline unsigned long find_first_bit_left(const unsigned long *addr, - unsigned long size) -{ - unsigned long bytes, bits; - - if (!size) - return 0; - bytes = __ffs_word_loop(addr, size); - bits = __flo_word(bytes * 8, __load_ulong_be(addr, bytes)); - return (bits < size) ? bits : size; -} - -static inline int find_next_bit_left(const unsigned long *addr, - unsigned long size, - unsigned long offset) +static inline int fls64(unsigned long word) { - const unsigned long *p; - unsigned long bit, set; - - if (offset >= size) - return size; - bit = offset & (BITS_PER_LONG - 1); - offset -= bit; - size -= offset; - p = addr + offset / BITS_PER_LONG; - if (bit) { - set = __flo_word(0, *p & (~0UL >> bit)); - if (set >= size) - return size + offset; - if (set < BITS_PER_LONG) - return set + offset; - offset += BITS_PER_LONG; - size -= BITS_PER_LONG; - p++; - } - return offset + find_first_bit_left(p, size); -} - -#define for_each_set_bit_left(bit, addr, size) \ - for ((bit) = find_first_bit_left((addr), (size)); \ - (bit) < (size); \ - (bit) = find_next_bit_left((addr), (size), (bit) + 1)) - -/* same as for_each_set_bit() but use bit as value to start with */ -#define for_each_set_bit_left_cont(bit, addr, size) \ - for ((bit) = find_next_bit_left((addr), (size), (bit)); \ - (bit) < (size); \ - (bit) = find_next_bit_left((addr), (size), (bit) + 1)) + unsigned long mask = 2 * BITS_PER_LONG - 1; -/** - * find_next_zero_bit - find the first zero bit in a memory region - * @addr: The address to base the search on - * @offset: The bitnumber to start searching at - * @size: The maximum size to search - */ -static inline int find_next_zero_bit (const unsigned long * addr, - unsigned long size, - unsigned long offset) -{ - const unsigned long *p; - unsigned long bit, set; - - if (offset >= size) - return size; - bit = offset & (BITS_PER_LONG - 1); - offset -= bit; - size -= offset; - p = addr + offset / BITS_PER_LONG; - if (bit) { - /* - * __ffz_word returns BITS_PER_LONG - * if no zero bit is present in the word. - */ - set = __ffz_word(bit, *p >> bit); - if (set >= size) - return size + offset; - if (set < BITS_PER_LONG) - return set + offset; - offset += BITS_PER_LONG; - size -= BITS_PER_LONG; - p++; - } - return offset + find_first_zero_bit(p, size); + return (1 + (__flogr(word) ^ (BITS_PER_LONG - 1))) & mask; } -#define find_next_zero_bit find_next_zero_bit /** - * find_next_bit - find the first set bit in a memory region - * @addr: The address to base the search on - * @offset: The bitnumber to start searching at - * @size: The maximum size to search + * fls - find last (most-significant) bit set + * @word: the word to search + * + * This is defined the same way as ffs. + * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32. */ -static inline int find_next_bit (const unsigned long * addr, - unsigned long size, - unsigned long offset) +static inline int fls(int word) { - const unsigned long *p; - unsigned long bit, set; - - if (offset >= size) - return size; - bit = offset & (BITS_PER_LONG - 1); - offset -= bit; - size -= offset; - p = addr + offset / BITS_PER_LONG; - if (bit) { - /* - * __ffs_word returns BITS_PER_LONG - * if no one bit is present in the word. - */ - set = __ffs_word(0, *p & (~0UL << bit)); - if (set >= size) - return size + offset; - if (set < BITS_PER_LONG) - return set + offset; - offset += BITS_PER_LONG; - size -= BITS_PER_LONG; - p++; - } - return offset + find_first_bit(p, size); + return fls64((unsigned int)word); } -#define find_next_bit find_next_bit -/* - * Every architecture must define this function. It's the fastest - * way of searching a 140-bit bitmap where the first 100 bits are - * unlikely to be set. It's guaranteed that at least one of the 140 - * bits is cleared. - */ -static inline int sched_find_first_bit(unsigned long *b) -{ - return find_first_bit(b, 140); -} +#else /* CONFIG_HAVE_MARCH_Z9_109_FEATURES */ -#include <asm-generic/bitops/fls.h> +#include <asm-generic/bitops/__ffs.h> +#include <asm-generic/bitops/ffs.h> #include <asm-generic/bitops/__fls.h> +#include <asm-generic/bitops/fls.h> #include <asm-generic/bitops/fls64.h> +#endif /* CONFIG_HAVE_MARCH_Z9_109_FEATURES */ + +#include <asm-generic/bitops/ffz.h> +#include <asm-generic/bitops/find.h> #include <asm-generic/bitops/hweight.h> #include <asm-generic/bitops/lock.h> - -/* - * ATTENTION: intel byte ordering convention for ext2 and minix !! - * bit 0 is the LSB of addr; bit 31 is the MSB of addr; - * bit 32 is the LSB of (addr+4). - * That combined with the little endian byte order of Intel gives the - * following bit order in memory: - * 07 06 05 04 03 02 01 00 15 14 13 12 11 10 09 08 \ - * 23 22 21 20 19 18 17 16 31 30 29 28 27 26 25 24 - */ - -static inline int find_first_zero_bit_le(void *vaddr, unsigned int size) -{ - unsigned long bytes, bits; - - if (!size) - return 0; - bytes = __ffz_word_loop(vaddr, size); - bits = __ffz_word(bytes*8, __load_ulong_le(vaddr, bytes)); - return (bits < size) ? bits : size; -} -#define find_first_zero_bit_le find_first_zero_bit_le - -static inline int find_next_zero_bit_le(void *vaddr, unsigned long size, - unsigned long offset) -{ - unsigned long *addr = vaddr, *p; - unsigned long bit, set; - - if (offset >= size) - return size; - bit = offset & (BITS_PER_LONG - 1); - offset -= bit; - size -= offset; - p = addr + offset / BITS_PER_LONG; - if (bit) { - /* - * s390 version of ffz returns BITS_PER_LONG - * if no zero bit is present in the word. - */ - set = __ffz_word(bit, __load_ulong_le(p, 0) >> bit); - if (set >= size) - return size + offset; - if (set < BITS_PER_LONG) - return set + offset; - offset += BITS_PER_LONG; - size -= BITS_PER_LONG; - p++; - } - return offset + find_first_zero_bit_le(p, size); -} -#define find_next_zero_bit_le find_next_zero_bit_le - -static inline unsigned long find_first_bit_le(void *vaddr, unsigned long size) -{ - unsigned long bytes, bits; - - if (!size) - return 0; - bytes = __ffs_word_loop(vaddr, size); - bits = __ffs_word(bytes*8, __load_ulong_le(vaddr, bytes)); - return (bits < size) ? bits : size; -} -#define find_first_bit_le find_first_bit_le - -static inline int find_next_bit_le(void *vaddr, unsigned long size, - unsigned long offset) -{ - unsigned long *addr = vaddr, *p; - unsigned long bit, set; - - if (offset >= size) - return size; - bit = offset & (BITS_PER_LONG - 1); - offset -= bit; - size -= offset; - p = addr + offset / BITS_PER_LONG; - if (bit) { - /* - * s390 version of ffz returns BITS_PER_LONG - * if no zero bit is present in the word. - */ - set = __ffs_word(0, __load_ulong_le(p, 0) & (~0UL << bit)); - if (set >= size) - return size + offset; - if (set < BITS_PER_LONG) - return set + offset; - offset += BITS_PER_LONG; - size -= BITS_PER_LONG; - p++; - } - return offset + find_first_bit_le(p, size); -} -#define find_next_bit_le find_next_bit_le - +#include <asm-generic/bitops/sched.h> #include <asm-generic/bitops/le.h> - #include <asm-generic/bitops/ext2-atomic-setbit.h> #endif /* _S390_BITOPS_H */ diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h index c1e7c646727c..4bf9da03591e 100644 --- a/arch/s390/include/asm/compat.h +++ b/arch/s390/include/asm/compat.h @@ -22,6 +22,7 @@ #define PSW32_MASK_ASC 0x0000C000UL #define PSW32_MASK_CC 0x00003000UL #define PSW32_MASK_PM 0x00000f00UL +#define PSW32_MASK_RI 0x00000080UL #define PSW32_MASK_USER 0x0000FF00UL @@ -35,7 +36,9 @@ #define PSW32_ASC_SECONDARY 0x00008000UL #define PSW32_ASC_HOME 0x0000C000UL -extern u32 psw32_user_bits; +#define PSW32_USER_BITS (PSW32_MASK_DAT | PSW32_MASK_IO | PSW32_MASK_EXT | \ + PSW32_DEFAULT_KEY | PSW32_MASK_BASE | \ + PSW32_MASK_MCHECK | PSW32_MASK_PSTATE | PSW32_ASC_HOME) #define COMPAT_USER_HZ 100 #define COMPAT_UTS_MACHINE "s390\0\0\0\0" diff --git a/arch/s390/include/asm/ctl_reg.h b/arch/s390/include/asm/ctl_reg.h index debfda33d1f8..4e63f1a13600 100644 --- a/arch/s390/include/asm/ctl_reg.h +++ b/arch/s390/include/asm/ctl_reg.h @@ -7,70 +7,62 @@ #ifndef __ASM_CTL_REG_H #define __ASM_CTL_REG_H -#ifdef CONFIG_64BIT - -#define __ctl_load(array, low, high) ({ \ - typedef struct { char _[sizeof(array)]; } addrtype; \ - asm volatile( \ - " lctlg %1,%2,%0\n" \ - : : "Q" (*(addrtype *)(&array)), \ - "i" (low), "i" (high)); \ - }) - -#define __ctl_store(array, low, high) ({ \ - typedef struct { char _[sizeof(array)]; } addrtype; \ - asm volatile( \ - " stctg %1,%2,%0\n" \ - : "=Q" (*(addrtype *)(&array)) \ - : "i" (low), "i" (high)); \ - }) - -#else /* CONFIG_64BIT */ - -#define __ctl_load(array, low, high) ({ \ - typedef struct { char _[sizeof(array)]; } addrtype; \ - asm volatile( \ - " lctl %1,%2,%0\n" \ - : : "Q" (*(addrtype *)(&array)), \ - "i" (low), "i" (high)); \ -}) - -#define __ctl_store(array, low, high) ({ \ - typedef struct { char _[sizeof(array)]; } addrtype; \ - asm volatile( \ - " stctl %1,%2,%0\n" \ - : "=Q" (*(addrtype *)(&array)) \ - : "i" (low), "i" (high)); \ - }) - -#endif /* CONFIG_64BIT */ +#include <linux/bug.h> -#define __ctl_set_bit(cr, bit) ({ \ - unsigned long __dummy; \ - __ctl_store(__dummy, cr, cr); \ - __dummy |= 1UL << (bit); \ - __ctl_load(__dummy, cr, cr); \ -}) - -#define __ctl_clear_bit(cr, bit) ({ \ - unsigned long __dummy; \ - __ctl_store(__dummy, cr, cr); \ - __dummy &= ~(1UL << (bit)); \ - __ctl_load(__dummy, cr, cr); \ -}) +#ifdef CONFIG_64BIT +# define __CTL_LOAD "lctlg" +# define __CTL_STORE "stctg" +#else +# define __CTL_LOAD "lctl" +# define __CTL_STORE "stctl" +#endif + +#define __ctl_load(array, low, high) { \ + typedef struct { char _[sizeof(array)]; } addrtype; \ + \ + BUILD_BUG_ON(sizeof(addrtype) != (high - low + 1) * sizeof(long));\ + asm volatile( \ + __CTL_LOAD " %1,%2,%0\n" \ + : : "Q" (*(addrtype *)(&array)), "i" (low), "i" (high));\ +} + +#define __ctl_store(array, low, high) { \ + typedef struct { char _[sizeof(array)]; } addrtype; \ + \ + BUILD_BUG_ON(sizeof(addrtype) != (high - low + 1) * sizeof(long));\ + asm volatile( \ + __CTL_STORE " %1,%2,%0\n" \ + : "=Q" (*(addrtype *)(&array)) \ + : "i" (low), "i" (high)); \ +} + +static inline void __ctl_set_bit(unsigned int cr, unsigned int bit) +{ + unsigned long reg; + + __ctl_store(reg, cr, cr); + reg |= 1UL << bit; + __ctl_load(reg, cr, cr); +} + +static inline void __ctl_clear_bit(unsigned int cr, unsigned int bit) +{ + unsigned long reg; + + __ctl_store(reg, cr, cr); + reg &= ~(1UL << bit); + __ctl_load(reg, cr, cr); +} + +void smp_ctl_set_bit(int cr, int bit); +void smp_ctl_clear_bit(int cr, int bit); #ifdef CONFIG_SMP - -extern void smp_ctl_set_bit(int cr, int bit); -extern void smp_ctl_clear_bit(int cr, int bit); -#define ctl_set_bit(cr, bit) smp_ctl_set_bit(cr, bit) -#define ctl_clear_bit(cr, bit) smp_ctl_clear_bit(cr, bit) - +# define ctl_set_bit(cr, bit) smp_ctl_set_bit(cr, bit) +# define ctl_clear_bit(cr, bit) smp_ctl_clear_bit(cr, bit) #else - -#define ctl_set_bit(cr, bit) __ctl_set_bit(cr, bit) -#define ctl_clear_bit(cr, bit) __ctl_clear_bit(cr, bit) - -#endif /* CONFIG_SMP */ +# define ctl_set_bit(cr, bit) __ctl_set_bit(cr, bit) +# define ctl_clear_bit(cr, bit) __ctl_clear_bit(cr, bit) +#endif #endif /* __ASM_CTL_REG_H */ diff --git a/arch/s390/include/asm/debug.h b/arch/s390/include/asm/debug.h index 188c5052a20a..530c15eb01e9 100644 --- a/arch/s390/include/asm/debug.h +++ b/arch/s390/include/asm/debug.h @@ -107,6 +107,11 @@ void debug_set_level(debug_info_t* id, int new_level); void debug_set_critical(void); void debug_stop_all(void); +static inline bool debug_level_enabled(debug_info_t* id, int level) +{ + return level <= id->level; +} + static inline debug_entry_t* debug_event(debug_info_t* id, int level, void* data, int length) { diff --git a/arch/s390/include/asm/dis.h b/arch/s390/include/asm/dis.h new file mode 100644 index 000000000000..04a83f5773cd --- /dev/null +++ b/arch/s390/include/asm/dis.h @@ -0,0 +1,52 @@ +/* + * Disassemble s390 instructions. + * + * Copyright IBM Corp. 2007 + * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), + */ + +#ifndef __ASM_S390_DIS_H__ +#define __ASM_S390_DIS_H__ + +/* Type of operand */ +#define OPERAND_GPR 0x1 /* Operand printed as %rx */ +#define OPERAND_FPR 0x2 /* Operand printed as %fx */ +#define OPERAND_AR 0x4 /* Operand printed as %ax */ +#define OPERAND_CR 0x8 /* Operand printed as %cx */ +#define OPERAND_DISP 0x10 /* Operand printed as displacement */ +#define OPERAND_BASE 0x20 /* Operand printed as base register */ +#define OPERAND_INDEX 0x40 /* Operand printed as index register */ +#define OPERAND_PCREL 0x80 /* Operand printed as pc-relative symbol */ +#define OPERAND_SIGNED 0x100 /* Operand printed as signed value */ +#define OPERAND_LENGTH 0x200 /* Operand printed as length (+1) */ + + +struct s390_operand { + int bits; /* The number of bits in the operand. */ + int shift; /* The number of bits to shift. */ + int flags; /* One bit syntax flags. */ +}; + +struct s390_insn { + const char name[5]; + unsigned char opfrag; + unsigned char format; +}; + + +static inline int insn_length(unsigned char code) +{ + return ((((int) code + 64) >> 7) + 1) << 1; +} + +void show_code(struct pt_regs *regs); +void print_fn_code(unsigned char *code, unsigned long len); +int insn_to_mnemonic(unsigned char *instruction, char *buf, unsigned int len); +struct s390_insn *find_insn(unsigned char *code); + +static inline int is_known_insn(unsigned char *code) +{ + return !!find_insn(code); +} + +#endif /* __ASM_S390_DIS_H__ */ diff --git a/arch/s390/include/asm/eadm.h b/arch/s390/include/asm/eadm.h index dc9200ca32ed..67026300c88e 100644 --- a/arch/s390/include/asm/eadm.h +++ b/arch/s390/include/asm/eadm.h @@ -111,18 +111,7 @@ struct scm_driver { int scm_driver_register(struct scm_driver *scmdrv); void scm_driver_unregister(struct scm_driver *scmdrv); -int scm_start_aob(struct aob *aob); +int eadm_start_aob(struct aob *aob); void scm_irq_handler(struct aob *aob, int error); -struct eadm_ops { - int (*eadm_start) (struct aob *aob); - struct module *owner; -}; - -int scm_get_ref(void); -void scm_put_ref(void); - -void register_eadm_ops(struct eadm_ops *ops); -void unregister_eadm_ops(struct eadm_ops *ops); - #endif /* _ASM_S390_EADM_H */ diff --git a/arch/s390/include/asm/fcx.h b/arch/s390/include/asm/fcx.h index ef6170995076..7ecb92b469b6 100644 --- a/arch/s390/include/asm/fcx.h +++ b/arch/s390/include/asm/fcx.h @@ -12,9 +12,9 @@ #define TCW_FORMAT_DEFAULT 0 #define TCW_TIDAW_FORMAT_DEFAULT 0 -#define TCW_FLAGS_INPUT_TIDA 1 << (23 - 5) -#define TCW_FLAGS_TCCB_TIDA 1 << (23 - 6) -#define TCW_FLAGS_OUTPUT_TIDA 1 << (23 - 7) +#define TCW_FLAGS_INPUT_TIDA (1 << (23 - 5)) +#define TCW_FLAGS_TCCB_TIDA (1 << (23 - 6)) +#define TCW_FLAGS_OUTPUT_TIDA (1 << (23 - 7)) #define TCW_FLAGS_TIDAW_FORMAT(x) ((x) & 3) << (23 - 9) #define TCW_FLAGS_GET_TIDAW_FORMAT(x) (((x) >> (23 - 9)) & 3) @@ -54,11 +54,11 @@ struct tcw { u32 intrg; } __attribute__ ((packed, aligned(64))); -#define TIDAW_FLAGS_LAST 1 << (7 - 0) -#define TIDAW_FLAGS_SKIP 1 << (7 - 1) -#define TIDAW_FLAGS_DATA_INT 1 << (7 - 2) -#define TIDAW_FLAGS_TTIC 1 << (7 - 3) -#define TIDAW_FLAGS_INSERT_CBC 1 << (7 - 4) +#define TIDAW_FLAGS_LAST (1 << (7 - 0)) +#define TIDAW_FLAGS_SKIP (1 << (7 - 1)) +#define TIDAW_FLAGS_DATA_INT (1 << (7 - 2)) +#define TIDAW_FLAGS_TTIC (1 << (7 - 3)) +#define TIDAW_FLAGS_INSERT_CBC (1 << (7 - 4)) /** * struct tidaw - Transport-Indirect-Addressing Word (TIDAW) @@ -106,9 +106,9 @@ struct tsa_ddpc { u8 sense[32]; } __attribute__ ((packed)); -#define TSA_INTRG_FLAGS_CU_STATE_VALID 1 << (7 - 0) -#define TSA_INTRG_FLAGS_DEV_STATE_VALID 1 << (7 - 1) -#define TSA_INTRG_FLAGS_OP_STATE_VALID 1 << (7 - 2) +#define TSA_INTRG_FLAGS_CU_STATE_VALID (1 << (7 - 0)) +#define TSA_INTRG_FLAGS_DEV_STATE_VALID (1 << (7 - 1)) +#define TSA_INTRG_FLAGS_OP_STATE_VALID (1 << (7 - 2)) /** * struct tsa_intrg - Interrogate Transport-Status Area (Intrg. TSA) @@ -140,10 +140,10 @@ struct tsa_intrg { #define TSB_FORMAT_DDPC 2 #define TSB_FORMAT_INTRG 3 -#define TSB_FLAGS_DCW_OFFSET_VALID 1 << (7 - 0) -#define TSB_FLAGS_COUNT_VALID 1 << (7 - 1) -#define TSB_FLAGS_CACHE_MISS 1 << (7 - 2) -#define TSB_FLAGS_TIME_VALID 1 << (7 - 3) +#define TSB_FLAGS_DCW_OFFSET_VALID (1 << (7 - 0)) +#define TSB_FLAGS_COUNT_VALID (1 << (7 - 1)) +#define TSB_FLAGS_CACHE_MISS (1 << (7 - 2)) +#define TSB_FLAGS_TIME_VALID (1 << (7 - 3)) #define TSB_FLAGS_FORMAT(x) ((x) & 7) #define TSB_FORMAT(t) ((t)->flags & 7) @@ -179,9 +179,9 @@ struct tsb { #define DCW_INTRG_RCQ_PRIMARY 1 #define DCW_INTRG_RCQ_SECONDARY 2 -#define DCW_INTRG_FLAGS_MPM 1 < (7 - 0) -#define DCW_INTRG_FLAGS_PPR 1 < (7 - 1) -#define DCW_INTRG_FLAGS_CRIT 1 < (7 - 2) +#define DCW_INTRG_FLAGS_MPM (1 << (7 - 0)) +#define DCW_INTRG_FLAGS_PPR (1 << (7 - 1)) +#define DCW_INTRG_FLAGS_CRIT (1 << (7 - 2)) /** * struct dcw_intrg_data - Interrogate DCW data @@ -216,7 +216,7 @@ struct dcw_intrg_data { u8 prog_data[0]; } __attribute__ ((packed)); -#define DCW_FLAGS_CC 1 << (7 - 1) +#define DCW_FLAGS_CC (1 << (7 - 1)) #define DCW_CMD_WRITE 0x01 #define DCW_CMD_READ 0x02 diff --git a/arch/s390/include/asm/hardirq.h b/arch/s390/include/asm/hardirq.h index a908d2941c5d..b7eabaaeffbd 100644 --- a/arch/s390/include/asm/hardirq.h +++ b/arch/s390/include/asm/hardirq.h @@ -18,8 +18,6 @@ #define __ARCH_HAS_DO_SOFTIRQ #define __ARCH_IRQ_EXIT_IRQS_DISABLED -#define HARDIRQ_BITS 8 - static inline void ack_bad_irq(unsigned int irq) { printk(KERN_CRIT "unexpected IRQ trap at vector %02x\n", irq); diff --git a/arch/s390/include/asm/ipl.h b/arch/s390/include/asm/ipl.h index 2bd6cb897b90..2fcccc0c997c 100644 --- a/arch/s390/include/asm/ipl.h +++ b/arch/s390/include/asm/ipl.h @@ -7,6 +7,7 @@ #ifndef _ASM_S390_IPL_H #define _ASM_S390_IPL_H +#include <asm/lowcore.h> #include <asm/types.h> #include <asm/cio.h> #include <asm/setup.h> @@ -86,7 +87,14 @@ struct ipl_parameter_block { */ extern u32 ipl_flags; extern u32 dump_prefix_page; -extern unsigned int zfcpdump_prefix_array[]; + +struct dump_save_areas { + struct save_area **areas; + int count; +}; + +extern struct dump_save_areas dump_save_areas; +struct save_area *dump_save_area_create(int cpu); extern void do_reipl(void); extern void do_halt(void); diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index e87ecaa2c569..d5bc3750616e 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h @@ -38,13 +38,6 @@ struct sca_block { struct sca_entry cpu[64]; } __attribute__((packed)); -#define KVM_NR_PAGE_SIZES 2 -#define KVM_HPAGE_GFN_SHIFT(x) (((x) - 1) * 8) -#define KVM_HPAGE_SHIFT(x) (PAGE_SHIFT + KVM_HPAGE_GFN_SHIFT(x)) -#define KVM_HPAGE_SIZE(x) (1UL << KVM_HPAGE_SHIFT(x)) -#define KVM_HPAGE_MASK(x) (~(KVM_HPAGE_SIZE(x) - 1)) -#define KVM_PAGES_PER_HPAGE(x) (KVM_HPAGE_SIZE(x) / PAGE_SIZE) - #define CPUSTAT_STOPPED 0x80000000 #define CPUSTAT_WAIT 0x10000000 #define CPUSTAT_ECALL_PEND 0x08000000 @@ -220,7 +213,6 @@ struct kvm_s390_interrupt_info { /* for local_interrupt.action_flags */ #define ACTION_STORE_ON_STOP (1<<0) #define ACTION_STOP_ON_STOP (1<<1) -#define ACTION_RELOADVCPU_ON_STOP (1<<2) struct kvm_s390_local_interrupt { spinlock_t lock; diff --git a/arch/s390/include/asm/mmu_context.h b/arch/s390/include/asm/mmu_context.h index 9f973d8de90e..5d1f950704dc 100644 --- a/arch/s390/include/asm/mmu_context.h +++ b/arch/s390/include/asm/mmu_context.h @@ -40,14 +40,8 @@ static inline void update_mm(struct mm_struct *mm, struct task_struct *tsk) pgd_t *pgd = mm->pgd; S390_lowcore.user_asce = mm->context.asce_bits | __pa(pgd); - if (s390_user_mode != HOME_SPACE_MODE) { - /* Load primary space page table origin. */ - asm volatile(LCTL_OPCODE" 1,1,%0\n" - : : "m" (S390_lowcore.user_asce) ); - } else - /* Load home space page table origin. */ - asm volatile(LCTL_OPCODE" 13,13,%0" - : : "m" (S390_lowcore.user_asce) ); + /* Load primary space page table origin. */ + asm volatile(LCTL_OPCODE" 1,1,%0\n" : : "m" (S390_lowcore.user_asce)); set_fs(current->thread.mm_segment); } diff --git a/arch/s390/include/asm/page.h b/arch/s390/include/asm/page.h index 1e51f2915b2e..316c8503a3b4 100644 --- a/arch/s390/include/asm/page.h +++ b/arch/s390/include/asm/page.h @@ -30,7 +30,12 @@ #include <asm/setup.h> #ifndef __ASSEMBLY__ -void storage_key_init_range(unsigned long start, unsigned long end); +static inline void storage_key_init_range(unsigned long start, unsigned long end) +{ +#if PAGE_DEFAULT_KEY + __storage_key_init_range(start, end); +#endif +} static inline void clear_page(void *page) { diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h index 1cc185da9d38..c129ab2ac731 100644 --- a/arch/s390/include/asm/pci.h +++ b/arch/s390/include/asm/pci.h @@ -63,9 +63,10 @@ enum zpci_state { }; struct zpci_bar_struct { + struct resource *res; /* bus resource */ u32 val; /* bar start & 3 flag bits */ - u8 size; /* order 2 exponent */ u16 map_idx; /* index into bar mapping array */ + u8 size; /* order 2 exponent */ }; /* Private data per function */ @@ -97,6 +98,7 @@ struct zpci_dev { unsigned long iommu_pages; unsigned int next_bit; + char res_name[16]; struct zpci_bar_struct bars[PCI_BAR_COUNT]; u64 start_dma; /* Start of available DMA addresses */ @@ -122,12 +124,10 @@ static inline bool zdev_enabled(struct zpci_dev *zdev) Prototypes ----------------------------------------------------------------------------- */ /* Base stuff */ -struct zpci_dev *zpci_alloc_device(void); int zpci_create_device(struct zpci_dev *); int zpci_enable_device(struct zpci_dev *); int zpci_disable_device(struct zpci_dev *); void zpci_stop_device(struct zpci_dev *); -void zpci_free_device(struct zpci_dev *); int zpci_register_ioat(struct zpci_dev *, u8, u64, u64, u64); int zpci_unregister_ioat(struct zpci_dev *, u8); diff --git a/arch/s390/include/asm/pci_debug.h b/arch/s390/include/asm/pci_debug.h index 1ca5d1047c71..ac24b26fc065 100644 --- a/arch/s390/include/asm/pci_debug.h +++ b/arch/s390/include/asm/pci_debug.h @@ -6,14 +6,9 @@ extern debug_info_t *pci_debug_msg_id; extern debug_info_t *pci_debug_err_id; -#ifdef CONFIG_PCI_DEBUG #define zpci_dbg(imp, fmt, args...) \ debug_sprintf_event(pci_debug_msg_id, imp, fmt, ##args) -#else /* !CONFIG_PCI_DEBUG */ -#define zpci_dbg(imp, fmt, args...) do { } while (0) -#endif - #define zpci_err(text...) \ do { \ char debug_buffer[16]; \ diff --git a/arch/s390/include/asm/pci_insn.h b/arch/s390/include/asm/pci_insn.h index df6eac9f0cb4..649eb62c52b3 100644 --- a/arch/s390/include/asm/pci_insn.h +++ b/arch/s390/include/asm/pci_insn.h @@ -54,11 +54,9 @@ struct zpci_fib { u32 fmt : 8; /* format */ u32 : 24; - u32 reserved1; + u32 : 32; u8 fc; /* function controls */ - u8 reserved2; - u16 reserved3; - u32 reserved4; + u64 : 56; u64 pba; /* PCI base address */ u64 pal; /* PCI address limit */ u64 iota; /* I/O Translation Anchor */ @@ -70,14 +68,13 @@ struct zpci_fib { u32 sum : 1; /* Adapter int summary bit enabled */ u32 : 1; u32 aisbo : 6; /* Adapter int summary bit offset */ - u32 reserved5; + u32 : 32; u64 aibv; /* Adapter int bit vector address */ u64 aisb; /* Adapter int summary bit address */ u64 fmb_addr; /* Function measurement block address and key */ - u64 reserved6; - u64 reserved7; -} __packed; - + u32 : 32; + u32 gd; +} __packed __aligned(8); int zpci_mod_fc(u64 req, struct zpci_fib *fib); int zpci_refresh_trans(u64 fn, u64 addr, u64 range); diff --git a/arch/s390/include/asm/percpu.h b/arch/s390/include/asm/percpu.h index 86fe0ee2cee5..fa91e0097458 100644 --- a/arch/s390/include/asm/percpu.h +++ b/arch/s390/include/asm/percpu.h @@ -10,16 +10,22 @@ */ #define __my_cpu_offset S390_lowcore.percpu_offset +#ifdef CONFIG_64BIT + /* * For 64 bit module code, the module may be more than 4G above the * per cpu area, use weak definitions to force the compiler to * generate external references. */ -#if defined(CONFIG_SMP) && defined(CONFIG_64BIT) && defined(MODULE) +#if defined(CONFIG_SMP) && defined(MODULE) #define ARCH_NEEDS_WEAK_PER_CPU #endif -#define arch_this_cpu_to_op(pcp, val, op) \ +/* + * We use a compare-and-swap loop since that uses less cpu cycles than + * disabling and enabling interrupts like the generic variant would do. + */ +#define arch_this_cpu_to_op_simple(pcp, val, op) \ ({ \ typedef typeof(pcp) pcp_op_T__; \ pcp_op_T__ old__, new__, prev__; \ @@ -30,42 +36,101 @@ do { \ old__ = prev__; \ new__ = old__ op (val); \ - switch (sizeof(*ptr__)) { \ - case 8: \ - prev__ = cmpxchg64(ptr__, old__, new__); \ - break; \ - default: \ - prev__ = cmpxchg(ptr__, old__, new__); \ - } \ + prev__ = cmpxchg(ptr__, old__, new__); \ } while (prev__ != old__); \ preempt_enable(); \ new__; \ }) -#define this_cpu_add_1(pcp, val) arch_this_cpu_to_op(pcp, val, +) -#define this_cpu_add_2(pcp, val) arch_this_cpu_to_op(pcp, val, +) -#define this_cpu_add_4(pcp, val) arch_this_cpu_to_op(pcp, val, +) -#define this_cpu_add_8(pcp, val) arch_this_cpu_to_op(pcp, val, +) +#define this_cpu_add_1(pcp, val) arch_this_cpu_to_op_simple(pcp, val, +) +#define this_cpu_add_2(pcp, val) arch_this_cpu_to_op_simple(pcp, val, +) +#define this_cpu_add_return_1(pcp, val) arch_this_cpu_to_op_simple(pcp, val, +) +#define this_cpu_add_return_2(pcp, val) arch_this_cpu_to_op_simple(pcp, val, +) +#define this_cpu_and_1(pcp, val) arch_this_cpu_to_op_simple(pcp, val, &) +#define this_cpu_and_2(pcp, val) arch_this_cpu_to_op_simple(pcp, val, &) +#define this_cpu_or_1(pcp, val) arch_this_cpu_to_op_simple(pcp, val, |) +#define this_cpu_or_2(pcp, val) arch_this_cpu_to_op_simple(pcp, val, |) + +#ifndef CONFIG_HAVE_MARCH_Z196_FEATURES + +#define this_cpu_add_4(pcp, val) arch_this_cpu_to_op_simple(pcp, val, +) +#define this_cpu_add_8(pcp, val) arch_this_cpu_to_op_simple(pcp, val, +) +#define this_cpu_add_return_4(pcp, val) arch_this_cpu_to_op_simple(pcp, val, +) +#define this_cpu_add_return_8(pcp, val) arch_this_cpu_to_op_simple(pcp, val, +) +#define this_cpu_and_4(pcp, val) arch_this_cpu_to_op_simple(pcp, val, &) +#define this_cpu_and_8(pcp, val) arch_this_cpu_to_op_simple(pcp, val, &) +#define this_cpu_or_4(pcp, val) arch_this_cpu_to_op_simple(pcp, val, |) +#define this_cpu_or_8(pcp, val) arch_this_cpu_to_op_simple(pcp, val, |) + +#else /* CONFIG_HAVE_MARCH_Z196_FEATURES */ + +#define arch_this_cpu_add(pcp, val, op1, op2, szcast) \ +{ \ + typedef typeof(pcp) pcp_op_T__; \ + pcp_op_T__ val__ = (val); \ + pcp_op_T__ old__, *ptr__; \ + preempt_disable(); \ + ptr__ = __this_cpu_ptr(&(pcp)); \ + if (__builtin_constant_p(val__) && \ + ((szcast)val__ > -129) && ((szcast)val__ < 128)) { \ + asm volatile( \ + op2 " %[ptr__],%[val__]\n" \ + : [ptr__] "+Q" (*ptr__) \ + : [val__] "i" ((szcast)val__) \ + : "cc"); \ + } else { \ + asm volatile( \ + op1 " %[old__],%[val__],%[ptr__]\n" \ + : [old__] "=d" (old__), [ptr__] "+Q" (*ptr__) \ + : [val__] "d" (val__) \ + : "cc"); \ + } \ + preempt_enable(); \ +} -#define this_cpu_add_return_1(pcp, val) arch_this_cpu_to_op(pcp, val, +) -#define this_cpu_add_return_2(pcp, val) arch_this_cpu_to_op(pcp, val, +) -#define this_cpu_add_return_4(pcp, val) arch_this_cpu_to_op(pcp, val, +) -#define this_cpu_add_return_8(pcp, val) arch_this_cpu_to_op(pcp, val, +) +#define this_cpu_add_4(pcp, val) arch_this_cpu_add(pcp, val, "laa", "asi", int) +#define this_cpu_add_8(pcp, val) arch_this_cpu_add(pcp, val, "laag", "agsi", long) -#define this_cpu_and_1(pcp, val) arch_this_cpu_to_op(pcp, val, &) -#define this_cpu_and_2(pcp, val) arch_this_cpu_to_op(pcp, val, &) -#define this_cpu_and_4(pcp, val) arch_this_cpu_to_op(pcp, val, &) -#define this_cpu_and_8(pcp, val) arch_this_cpu_to_op(pcp, val, &) +#define arch_this_cpu_add_return(pcp, val, op) \ +({ \ + typedef typeof(pcp) pcp_op_T__; \ + pcp_op_T__ val__ = (val); \ + pcp_op_T__ old__, *ptr__; \ + preempt_disable(); \ + ptr__ = __this_cpu_ptr(&(pcp)); \ + asm volatile( \ + op " %[old__],%[val__],%[ptr__]\n" \ + : [old__] "=d" (old__), [ptr__] "+Q" (*ptr__) \ + : [val__] "d" (val__) \ + : "cc"); \ + preempt_enable(); \ + old__ + val__; \ +}) -#define this_cpu_or_1(pcp, val) arch_this_cpu_to_op(pcp, val, |) -#define this_cpu_or_2(pcp, val) arch_this_cpu_to_op(pcp, val, |) -#define this_cpu_or_4(pcp, val) arch_this_cpu_to_op(pcp, val, |) -#define this_cpu_or_8(pcp, val) arch_this_cpu_to_op(pcp, val, |) +#define this_cpu_add_return_4(pcp, val) arch_this_cpu_add_return(pcp, val, "laa") +#define this_cpu_add_return_8(pcp, val) arch_this_cpu_add_return(pcp, val, "laag") -#define this_cpu_xor_1(pcp, val) arch_this_cpu_to_op(pcp, val, ^) -#define this_cpu_xor_2(pcp, val) arch_this_cpu_to_op(pcp, val, ^) -#define this_cpu_xor_4(pcp, val) arch_this_cpu_to_op(pcp, val, ^) -#define this_cpu_xor_8(pcp, val) arch_this_cpu_to_op(pcp, val, ^) +#define arch_this_cpu_to_op(pcp, val, op) \ +{ \ + typedef typeof(pcp) pcp_op_T__; \ + pcp_op_T__ val__ = (val); \ + pcp_op_T__ old__, *ptr__; \ + preempt_disable(); \ + ptr__ = __this_cpu_ptr(&(pcp)); \ + asm volatile( \ + op " %[old__],%[val__],%[ptr__]\n" \ + : [old__] "=d" (old__), [ptr__] "+Q" (*ptr__) \ + : [val__] "d" (val__) \ + : "cc"); \ + preempt_enable(); \ +} + +#define this_cpu_and_4(pcp, val) arch_this_cpu_to_op(pcp, val, "lan") +#define this_cpu_and_8(pcp, val) arch_this_cpu_to_op(pcp, val, "lang") +#define this_cpu_or_4(pcp, val) arch_this_cpu_to_op(pcp, val, "lao") +#define this_cpu_or_8(pcp, val) arch_this_cpu_to_op(pcp, val, "laog") + +#endif /* CONFIG_HAVE_MARCH_Z196_FEATURES */ #define arch_this_cpu_cmpxchg(pcp, oval, nval) \ ({ \ @@ -74,13 +139,7 @@ pcp_op_T__ *ptr__; \ preempt_disable(); \ ptr__ = __this_cpu_ptr(&(pcp)); \ - switch (sizeof(*ptr__)) { \ - case 8: \ - ret__ = cmpxchg64(ptr__, oval, nval); \ - break; \ - default: \ - ret__ = cmpxchg(ptr__, oval, nval); \ - } \ + ret__ = cmpxchg(ptr__, oval, nval); \ preempt_enable(); \ ret__; \ }) @@ -104,9 +163,7 @@ #define this_cpu_xchg_1(pcp, nval) arch_this_cpu_xchg(pcp, nval) #define this_cpu_xchg_2(pcp, nval) arch_this_cpu_xchg(pcp, nval) #define this_cpu_xchg_4(pcp, nval) arch_this_cpu_xchg(pcp, nval) -#ifdef CONFIG_64BIT #define this_cpu_xchg_8(pcp, nval) arch_this_cpu_xchg(pcp, nval) -#endif #define arch_this_cpu_cmpxchg_double(pcp1, pcp2, o1, o2, n1, n2) \ ({ \ @@ -124,9 +181,9 @@ }) #define this_cpu_cmpxchg_double_4 arch_this_cpu_cmpxchg_double -#ifdef CONFIG_64BIT #define this_cpu_cmpxchg_double_8 arch_this_cpu_cmpxchg_double -#endif + +#endif /* CONFIG_64BIT */ #include <asm-generic/percpu.h> diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index ca7821f07260..0a876bc543d3 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h @@ -134,19 +134,17 @@ struct stack_frame { * Do necessary setup to start up a new thread. */ #define start_thread(regs, new_psw, new_stackp) do { \ - regs->psw.mask = psw_user_bits | PSW_MASK_EA | PSW_MASK_BA; \ + regs->psw.mask = PSW_USER_BITS | PSW_MASK_EA | PSW_MASK_BA; \ regs->psw.addr = new_psw | PSW_ADDR_AMODE; \ regs->gprs[15] = new_stackp; \ execve_tail(); \ } while (0) #define start_thread31(regs, new_psw, new_stackp) do { \ - regs->psw.mask = psw_user_bits | PSW_MASK_BA; \ + regs->psw.mask = PSW_USER_BITS | PSW_MASK_BA; \ regs->psw.addr = new_psw | PSW_ADDR_AMODE; \ regs->gprs[15] = new_stackp; \ - __tlb_flush_mm(current->mm); \ crst_table_downgrade(current->mm, 1UL << 31); \ - update_mm(current->mm, current); \ execve_tail(); \ } while (0) @@ -169,17 +167,15 @@ extern void release_thread(struct task_struct *); */ extern unsigned long thread_saved_pc(struct task_struct *t); -extern void show_code(struct pt_regs *regs); -extern void print_fn_code(unsigned char *code, unsigned long len); -extern int insn_to_mnemonic(unsigned char *instruction, char *buf, - unsigned int len); - unsigned long get_wchan(struct task_struct *p); #define task_pt_regs(tsk) ((struct pt_regs *) \ (task_stack_page(tsk) + THREAD_SIZE) - 1) #define KSTK_EIP(tsk) (task_pt_regs(tsk)->psw.addr) #define KSTK_ESP(tsk) (task_pt_regs(tsk)->gprs[15]) +/* Has task runtime instrumentation enabled ? */ +#define is_ri_task(tsk) (!!(tsk)->thread.ri_cb) + static inline unsigned short stap(void) { unsigned short cpu_address; @@ -348,9 +344,9 @@ __set_psw_mask(unsigned long mask) } #define local_mcck_enable() \ - __set_psw_mask(psw_kernel_bits | PSW_MASK_DAT | PSW_MASK_MCHECK) + __set_psw_mask(PSW_KERNEL_BITS | PSW_MASK_DAT | PSW_MASK_MCHECK) #define local_mcck_disable() \ - __set_psw_mask(psw_kernel_bits | PSW_MASK_DAT) + __set_psw_mask(PSW_KERNEL_BITS | PSW_MASK_DAT) /* * Basic Machine Check/Program Check Handler. diff --git a/arch/s390/include/asm/ptrace.h b/arch/s390/include/asm/ptrace.h index 52b56533c57c..9c82cebddabd 100644 --- a/arch/s390/include/asm/ptrace.h +++ b/arch/s390/include/asm/ptrace.h @@ -10,8 +10,11 @@ #ifndef __ASSEMBLY__ -extern long psw_kernel_bits; -extern long psw_user_bits; +#define PSW_KERNEL_BITS (PSW_DEFAULT_KEY | PSW_MASK_BASE | PSW_ASC_HOME | \ + PSW_MASK_EA | PSW_MASK_BA) +#define PSW_USER_BITS (PSW_MASK_DAT | PSW_MASK_IO | PSW_MASK_EXT | \ + PSW_DEFAULT_KEY | PSW_MASK_BASE | PSW_MASK_MCHECK | \ + PSW_MASK_PSTATE | PSW_ASC_PRIMARY) /* * The pt_regs struct defines the way the registers are stored on diff --git a/arch/s390/include/asm/sclp.h b/arch/s390/include/asm/sclp.h index 7dc7f9c63b65..30ef748bc161 100644 --- a/arch/s390/include/asm/sclp.h +++ b/arch/s390/include/asm/sclp.h @@ -43,7 +43,6 @@ struct sclp_cpu_info { int sclp_get_cpu_info(struct sclp_cpu_info *info); int sclp_cpu_configure(u8 cpu); int sclp_cpu_deconfigure(u8 cpu); -void sclp_facilities_detect(void); unsigned long long sclp_get_rnmax(void); unsigned long long sclp_get_rzm(void); int sclp_sdias_blk_count(void); @@ -57,5 +56,7 @@ bool sclp_has_vt220(void); int sclp_pci_configure(u32 fid); int sclp_pci_deconfigure(u32 fid); int memcpy_hsa(void *dest, unsigned long src, size_t count, int mode); +unsigned long sclp_get_hsa_size(void); +void sclp_early_detect(void); #endif /* _ASM_S390_SCLP_H */ diff --git a/arch/s390/include/asm/setup.h b/arch/s390/include/asm/setup.h index 59880dbaf360..94cfbe442f12 100644 --- a/arch/s390/include/asm/setup.h +++ b/arch/s390/include/asm/setup.h @@ -48,13 +48,6 @@ void detect_memory_layout(struct mem_chunk chunk[], unsigned long maxsize); void create_mem_hole(struct mem_chunk mem_chunk[], unsigned long addr, unsigned long size); -#define PRIMARY_SPACE_MODE 0 -#define ACCESS_REGISTER_MODE 1 -#define SECONDARY_SPACE_MODE 2 -#define HOME_SPACE_MODE 3 - -extern unsigned int s390_user_mode; - /* * Machine features detected in head.S */ @@ -114,9 +107,6 @@ extern unsigned int s390_user_mode; #define MACHINE_HAS_RRBM (S390_lowcore.machine_flags & MACHINE_FLAG_RRBM) #endif /* CONFIG_64BIT */ -#define ZFCPDUMP_HSA_SIZE (32UL<<20) -#define ZFCPDUMP_HSA_SIZE_MAX (64UL<<20) - /* * Console mode. Override with conmode= */ diff --git a/arch/s390/include/asm/smp.h b/arch/s390/include/asm/smp.h index b64f15c3b4cc..ac9bed8e103f 100644 --- a/arch/s390/include/asm/smp.h +++ b/arch/s390/include/asm/smp.h @@ -14,7 +14,6 @@ #define raw_smp_processor_id() (S390_lowcore.cpu_nr) extern struct mutex smp_cpu_state_mutex; -extern struct save_area *zfcpdump_save_areas[NR_CPUS + 1]; extern int __cpu_up(unsigned int cpu, struct task_struct *tidle); diff --git a/arch/s390/include/asm/switch_to.h b/arch/s390/include/asm/switch_to.h index 6dbd559763c9..29c81f82705e 100644 --- a/arch/s390/include/asm/switch_to.h +++ b/arch/s390/include/asm/switch_to.h @@ -13,58 +13,94 @@ extern struct task_struct *__switch_to(void *, void *); extern void update_cr_regs(struct task_struct *task); -static inline void save_fp_regs(s390_fp_regs *fpregs) +static inline int test_fp_ctl(u32 fpc) { + u32 orig_fpc; + int rc; + + if (!MACHINE_HAS_IEEE) + return 0; + asm volatile( - " std 0,%O0+8(%R0)\n" - " std 2,%O0+24(%R0)\n" - " std 4,%O0+40(%R0)\n" - " std 6,%O0+56(%R0)" - : "=Q" (*fpregs) : "Q" (*fpregs)); + " efpc %1\n" + " sfpc %2\n" + "0: sfpc %1\n" + " la %0,0\n" + "1:\n" + EX_TABLE(0b,1b) + : "=d" (rc), "=d" (orig_fpc) + : "d" (fpc), "0" (-EINVAL)); + return rc; +} + +static inline void save_fp_ctl(u32 *fpc) +{ if (!MACHINE_HAS_IEEE) return; + asm volatile( - " stfpc %0\n" - " std 1,%O0+16(%R0)\n" - " std 3,%O0+32(%R0)\n" - " std 5,%O0+48(%R0)\n" - " std 7,%O0+64(%R0)\n" - " std 8,%O0+72(%R0)\n" - " std 9,%O0+80(%R0)\n" - " std 10,%O0+88(%R0)\n" - " std 11,%O0+96(%R0)\n" - " std 12,%O0+104(%R0)\n" - " std 13,%O0+112(%R0)\n" - " std 14,%O0+120(%R0)\n" - " std 15,%O0+128(%R0)\n" - : "=Q" (*fpregs) : "Q" (*fpregs)); + " stfpc %0\n" + : "+Q" (*fpc)); } -static inline void restore_fp_regs(s390_fp_regs *fpregs) +static inline int restore_fp_ctl(u32 *fpc) { + int rc; + + if (!MACHINE_HAS_IEEE) + return 0; + asm volatile( - " ld 0,%O0+8(%R0)\n" - " ld 2,%O0+24(%R0)\n" - " ld 4,%O0+40(%R0)\n" - " ld 6,%O0+56(%R0)" - : : "Q" (*fpregs)); + "0: lfpc %1\n" + " la %0,0\n" + "1:\n" + EX_TABLE(0b,1b) + : "=d" (rc) : "Q" (*fpc), "0" (-EINVAL)); + return rc; +} + +static inline void save_fp_regs(freg_t *fprs) +{ + asm volatile("std 0,%0" : "=Q" (fprs[0])); + asm volatile("std 2,%0" : "=Q" (fprs[2])); + asm volatile("std 4,%0" : "=Q" (fprs[4])); + asm volatile("std 6,%0" : "=Q" (fprs[6])); if (!MACHINE_HAS_IEEE) return; - asm volatile( - " lfpc %0\n" - " ld 1,%O0+16(%R0)\n" - " ld 3,%O0+32(%R0)\n" - " ld 5,%O0+48(%R0)\n" - " ld 7,%O0+64(%R0)\n" - " ld 8,%O0+72(%R0)\n" - " ld 9,%O0+80(%R0)\n" - " ld 10,%O0+88(%R0)\n" - " ld 11,%O0+96(%R0)\n" - " ld 12,%O0+104(%R0)\n" - " ld 13,%O0+112(%R0)\n" - " ld 14,%O0+120(%R0)\n" - " ld 15,%O0+128(%R0)\n" - : : "Q" (*fpregs)); + asm volatile("std 1,%0" : "=Q" (fprs[1])); + asm volatile("std 3,%0" : "=Q" (fprs[3])); + asm volatile("std 5,%0" : "=Q" (fprs[5])); + asm volatile("std 7,%0" : "=Q" (fprs[7])); + asm volatile("std 8,%0" : "=Q" (fprs[8])); + asm volatile("std 9,%0" : "=Q" (fprs[9])); + asm volatile("std 10,%0" : "=Q" (fprs[10])); + asm volatile("std 11,%0" : "=Q" (fprs[11])); + asm volatile("std 12,%0" : "=Q" (fprs[12])); + asm volatile("std 13,%0" : "=Q" (fprs[13])); + asm volatile("std 14,%0" : "=Q" (fprs[14])); + asm volatile("std 15,%0" : "=Q" (fprs[15])); +} + +static inline void restore_fp_regs(freg_t *fprs) +{ + asm volatile("ld 0,%0" : : "Q" (fprs[0])); + asm volatile("ld 2,%0" : : "Q" (fprs[2])); + asm volatile("ld 4,%0" : : "Q" (fprs[4])); + asm volatile("ld 6,%0" : : "Q" (fprs[6])); + if (!MACHINE_HAS_IEEE) + return; + asm volatile("ld 1,%0" : : "Q" (fprs[1])); + asm volatile("ld 3,%0" : : "Q" (fprs[3])); + asm volatile("ld 5,%0" : : "Q" (fprs[5])); + asm volatile("ld 7,%0" : : "Q" (fprs[7])); + asm volatile("ld 8,%0" : : "Q" (fprs[8])); + asm volatile("ld 9,%0" : : "Q" (fprs[9])); + asm volatile("ld 10,%0" : : "Q" (fprs[10])); + asm volatile("ld 11,%0" : : "Q" (fprs[11])); + asm volatile("ld 12,%0" : : "Q" (fprs[12])); + asm volatile("ld 13,%0" : : "Q" (fprs[13])); + asm volatile("ld 14,%0" : : "Q" (fprs[14])); + asm volatile("ld 15,%0" : : "Q" (fprs[15])); } static inline void save_access_regs(unsigned int *acrs) @@ -83,12 +119,14 @@ static inline void restore_access_regs(unsigned int *acrs) #define switch_to(prev,next,last) do { \ if (prev->mm) { \ - save_fp_regs(&prev->thread.fp_regs); \ + save_fp_ctl(&prev->thread.fp_regs.fpc); \ + save_fp_regs(prev->thread.fp_regs.fprs); \ save_access_regs(&prev->thread.acrs[0]); \ save_ri_cb(prev->thread.ri_cb); \ } \ if (next->mm) { \ - restore_fp_regs(&next->thread.fp_regs); \ + restore_fp_ctl(&next->thread.fp_regs.fpc); \ + restore_fp_regs(next->thread.fp_regs.fprs); \ restore_access_regs(&next->thread.acrs[0]); \ restore_ri_cb(next->thread.ri_cb, prev->thread.ri_cb); \ update_cr_regs(next); \ diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h index eb5f64d26d06..10e0fcd3633d 100644 --- a/arch/s390/include/asm/thread_info.h +++ b/arch/s390/include/asm/thread_info.h @@ -111,6 +111,4 @@ static inline struct thread_info *current_thread_info(void) #define is_32bit_task() (1) #endif -#define PREEMPT_ACTIVE 0x4000000 - #endif /* _ASM_THREAD_INFO_H */ diff --git a/arch/s390/include/asm/timex.h b/arch/s390/include/asm/timex.h index 819b94d22720..8beee1cceba4 100644 --- a/arch/s390/include/asm/timex.h +++ b/arch/s390/include/asm/timex.h @@ -71,9 +71,11 @@ static inline void local_tick_enable(unsigned long long comp) typedef unsigned long long cycles_t; -static inline void get_tod_clock_ext(char *clk) +static inline void get_tod_clock_ext(char clk[16]) { - asm volatile("stcke %0" : "=Q" (*clk) : : "cc"); + typedef struct { char _[sizeof(clk)]; } addrtype; + + asm volatile("stcke %0" : "=Q" (*(addrtype *) clk) : : "cc"); } static inline unsigned long long get_tod_clock(void) diff --git a/arch/s390/include/asm/uaccess.h b/arch/s390/include/asm/uaccess.h index 9c33ed4e666f..79330af9a5f8 100644 --- a/arch/s390/include/asm/uaccess.h +++ b/arch/s390/include/asm/uaccess.h @@ -94,9 +94,7 @@ static inline unsigned long extable_fixup(const struct exception_table_entry *x) struct uaccess_ops { size_t (*copy_from_user)(size_t, const void __user *, void *); - size_t (*copy_from_user_small)(size_t, const void __user *, void *); size_t (*copy_to_user)(size_t, void __user *, const void *); - size_t (*copy_to_user_small)(size_t, void __user *, const void *); size_t (*copy_in_user)(size_t, void __user *, const void __user *); size_t (*clear_user)(size_t, void __user *); size_t (*strnlen_user)(size_t, const char __user *); @@ -106,22 +104,20 @@ struct uaccess_ops { }; extern struct uaccess_ops uaccess; -extern struct uaccess_ops uaccess_std; extern struct uaccess_ops uaccess_mvcos; -extern struct uaccess_ops uaccess_mvcos_switch; extern struct uaccess_ops uaccess_pt; extern int __handle_fault(unsigned long, unsigned long, int); static inline int __put_user_fn(size_t size, void __user *ptr, void *x) { - size = uaccess.copy_to_user_small(size, ptr, x); + size = uaccess.copy_to_user(size, ptr, x); return size ? -EFAULT : size; } static inline int __get_user_fn(size_t size, const void __user *ptr, void *x) { - size = uaccess.copy_from_user_small(size, ptr, x); + size = uaccess.copy_from_user(size, ptr, x); return size ? -EFAULT : size; } @@ -226,10 +222,7 @@ extern int __get_user_bad(void) __attribute__((noreturn)); static inline unsigned long __must_check __copy_to_user(void __user *to, const void *from, unsigned long n) { - if (__builtin_constant_p(n) && (n <= 256)) - return uaccess.copy_to_user_small(n, to, from); - else - return uaccess.copy_to_user(n, to, from); + return uaccess.copy_to_user(n, to, from); } #define __copy_to_user_inatomic __copy_to_user @@ -275,10 +268,7 @@ copy_to_user(void __user *to, const void *from, unsigned long n) static inline unsigned long __must_check __copy_from_user(void *to, const void __user *from, unsigned long n) { - if (__builtin_constant_p(n) && (n <= 256)) - return uaccess.copy_from_user_small(n, from, to); - else - return uaccess.copy_from_user(n, from, to); + return uaccess.copy_from_user(n, from, to); } extern void copy_from_user_overflow(void) diff --git a/arch/s390/include/uapi/asm/ptrace.h b/arch/s390/include/uapi/asm/ptrace.h index 7a84619e315e..7e0b498a2c2b 100644 --- a/arch/s390/include/uapi/asm/ptrace.h +++ b/arch/s390/include/uapi/asm/ptrace.h @@ -199,6 +199,7 @@ typedef union typedef struct { __u32 fpc; + __u32 pad; freg_t fprs[NUM_FPRS]; } s390_fp_regs; @@ -206,7 +207,6 @@ typedef struct #define FPC_FLAGS_MASK 0x00F80000 #define FPC_DXC_MASK 0x0000FF00 #define FPC_RM_MASK 0x00000003 -#define FPC_VALID_MASK 0xF8F8FF03 /* this typedef defines how a Program Status Word looks like */ typedef struct @@ -263,7 +263,7 @@ typedef struct #define PSW_MASK_EA 0x0000000100000000UL #define PSW_MASK_BA 0x0000000080000000UL -#define PSW_MASK_USER 0x0000FF8180000000UL +#define PSW_MASK_USER 0x0000FF0180000000UL #define PSW_ADDR_AMODE 0x0000000000000000UL #define PSW_ADDR_INSN 0xFFFFFFFFFFFFFFFFUL diff --git a/arch/s390/include/uapi/asm/sigcontext.h b/arch/s390/include/uapi/asm/sigcontext.h index 584787f6ce44..b30de9c01bbe 100644 --- a/arch/s390/include/uapi/asm/sigcontext.h +++ b/arch/s390/include/uapi/asm/sigcontext.h @@ -49,6 +49,7 @@ typedef struct typedef struct { unsigned int fpc; + unsigned int pad; double fprs[__NUM_FPRS]; } _s390_fp_regs; diff --git a/arch/s390/include/uapi/asm/socket.h b/arch/s390/include/uapi/asm/socket.h index 92494494692e..c286c2e868f0 100644 --- a/arch/s390/include/uapi/asm/socket.h +++ b/arch/s390/include/uapi/asm/socket.h @@ -82,4 +82,6 @@ #define SO_BUSY_POLL 46 +#define SO_MAX_PACING_RATE 47 + #endif /* _ASM_SOCKET_H */ diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index 4bb2a4656163..2403303cfed7 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile @@ -28,7 +28,7 @@ CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"' CFLAGS_sysinfo.o += -Iinclude/math-emu -Iarch/s390/math-emu -w -obj-y := bitmap.o traps.o time.o process.o base.o early.o setup.o vtime.o +obj-y := traps.o time.o process.o base.o early.o setup.o vtime.o obj-y += processor.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o nmi.o obj-y += debug.o irq.o ipl.o dis.o diag.o sclp.o vdso.o obj-y += sysinfo.o jump_label.o lgr.o os_info.o machine_kexec.o pgm_check.o diff --git a/arch/s390/kernel/bitmap.c b/arch/s390/kernel/bitmap.c deleted file mode 100644 index 102da5e23037..000000000000 --- a/arch/s390/kernel/bitmap.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Bitmaps for set_bit, clear_bit, test_and_set_bit, ... - * See include/asm/{bitops.h|posix_types.h} for details - * - * Copyright IBM Corp. 1999, 2009 - * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>, - */ - -#include <linux/bitops.h> -#include <linux/module.h> - -const char _oi_bitmap[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; -EXPORT_SYMBOL(_oi_bitmap); - -const char _ni_bitmap[] = { 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f }; -EXPORT_SYMBOL(_ni_bitmap); - -const char _zb_findmap[] = { - 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4, - 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5, - 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4, - 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6, - 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4, - 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5, - 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4, - 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,7, - 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4, - 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5, - 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4, - 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6, - 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4, - 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5, - 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4, - 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,8 }; -EXPORT_SYMBOL(_zb_findmap); - -const char _sb_findmap[] = { - 8,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, - 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, - 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, - 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, - 6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, - 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, - 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, - 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, - 7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, - 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, - 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, - 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, - 6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, - 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, - 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, - 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0 }; -EXPORT_SYMBOL(_sb_findmap); diff --git a/arch/s390/kernel/cache.c b/arch/s390/kernel/cache.c index dd62071624be..3a414c0f93ed 100644 --- a/arch/s390/kernel/cache.c +++ b/arch/s390/kernel/cache.c @@ -146,15 +146,14 @@ static void __init cache_build_info(void) ct.raw = ecag(EXTRACT_TOPOLOGY, 0, 0); for (level = 0; level < CACHE_MAX_LEVEL; level++) { switch (ct.ci[level].scope) { - case CACHE_SCOPE_NOTEXISTS: - case CACHE_SCOPE_RESERVED: - return; case CACHE_SCOPE_SHARED: private = 0; break; case CACHE_SCOPE_PRIVATE: private = 1; break; + default: + return; } if (ct.ci[level].type == CACHE_TYPE_SEPARATE) { rc = cache_add(level, private, CACHE_TYPE_DATA); diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index 1f1b8c70ab97..e030d2bdec1b 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c @@ -58,10 +58,6 @@ #include "compat_linux.h" -u32 psw32_user_bits = PSW32_MASK_DAT | PSW32_MASK_IO | PSW32_MASK_EXT | - PSW32_DEFAULT_KEY | PSW32_MASK_BASE | PSW32_MASK_MCHECK | - PSW32_MASK_PSTATE | PSW32_ASC_HOME; - /* For this source file, we want overflow handling. */ #undef high2lowuid diff --git a/arch/s390/kernel/compat_linux.h b/arch/s390/kernel/compat_linux.h index 976518c0592a..1bfda3eca379 100644 --- a/arch/s390/kernel/compat_linux.h +++ b/arch/s390/kernel/compat_linux.h @@ -27,6 +27,7 @@ typedef union typedef struct { unsigned int fpc; + unsigned int pad; freg_t32 fprs[__NUM_FPRS]; } _s390_fp_regs32; diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c index adaa9e9478d8..6e2442978409 100644 --- a/arch/s390/kernel/compat_signal.c +++ b/arch/s390/kernel/compat_signal.c @@ -49,7 +49,7 @@ typedef struct __u32 gprs_high[NUM_GPRS]; } rt_sigframe32; -int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from) +int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from) { int err; @@ -153,57 +153,66 @@ int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from) static int save_sigregs32(struct pt_regs *regs, _sigregs32 __user *sregs) { - _s390_regs_common32 regs32; - int err, i; + _sigregs32 user_sregs; + int i; - regs32.psw.mask = psw32_user_bits | - ((__u32)(regs->psw.mask >> 32) & PSW32_MASK_USER); - regs32.psw.addr = (__u32) regs->psw.addr | + user_sregs.regs.psw.mask = (__u32)(regs->psw.mask >> 32); + user_sregs.regs.psw.mask &= PSW32_MASK_USER | PSW32_MASK_RI; + user_sregs.regs.psw.mask |= PSW32_USER_BITS; + user_sregs.regs.psw.addr = (__u32) regs->psw.addr | (__u32)(regs->psw.mask & PSW_MASK_BA); for (i = 0; i < NUM_GPRS; i++) - regs32.gprs[i] = (__u32) regs->gprs[i]; + user_sregs.regs.gprs[i] = (__u32) regs->gprs[i]; save_access_regs(current->thread.acrs); - memcpy(regs32.acrs, current->thread.acrs, sizeof(regs32.acrs)); - err = __copy_to_user(&sregs->regs, ®s32, sizeof(regs32)); - if (err) - return err; - save_fp_regs(¤t->thread.fp_regs); - /* s390_fp_regs and _s390_fp_regs32 are the same ! */ - return __copy_to_user(&sregs->fpregs, ¤t->thread.fp_regs, - sizeof(_s390_fp_regs32)); + memcpy(&user_sregs.regs.acrs, current->thread.acrs, + sizeof(user_sregs.regs.acrs)); + save_fp_ctl(¤t->thread.fp_regs.fpc); + save_fp_regs(current->thread.fp_regs.fprs); + memcpy(&user_sregs.fpregs, ¤t->thread.fp_regs, + sizeof(user_sregs.fpregs)); + if (__copy_to_user(sregs, &user_sregs, sizeof(_sigregs32))) + return -EFAULT; + return 0; } static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs) { - _s390_regs_common32 regs32; - int err, i; + _sigregs32 user_sregs; + int i; /* Alwys make any pending restarted system call return -EINTR */ current_thread_info()->restart_block.fn = do_no_restart_syscall; - err = __copy_from_user(®s32, &sregs->regs, sizeof(regs32)); - if (err) - return err; + if (__copy_from_user(&user_sregs, &sregs->regs, sizeof(user_sregs))) + return -EFAULT; + + if (!is_ri_task(current) && (user_sregs.regs.psw.mask & PSW32_MASK_RI)) + return -EINVAL; + + /* Loading the floating-point-control word can fail. Do that first. */ + if (restore_fp_ctl(&user_sregs.fpregs.fpc)) + return -EINVAL; + + /* Use regs->psw.mask instead of PSW_USER_BITS to preserve PER bit. */ regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) | - (__u64)(regs32.psw.mask & PSW32_MASK_USER) << 32 | - (__u64)(regs32.psw.addr & PSW32_ADDR_AMODE); + (__u64)(user_sregs.regs.psw.mask & PSW32_MASK_USER) << 32 | + (__u64)(user_sregs.regs.psw.mask & PSW32_MASK_RI) << 32 | + (__u64)(user_sregs.regs.psw.addr & PSW32_ADDR_AMODE); /* Check for invalid user address space control. */ - if ((regs->psw.mask & PSW_MASK_ASC) >= (psw_kernel_bits & PSW_MASK_ASC)) - regs->psw.mask = (psw_user_bits & PSW_MASK_ASC) | + if ((regs->psw.mask & PSW_MASK_ASC) == PSW_ASC_HOME) + regs->psw.mask = PSW_ASC_PRIMARY | (regs->psw.mask & ~PSW_MASK_ASC); - regs->psw.addr = (__u64)(regs32.psw.addr & PSW32_ADDR_INSN); + regs->psw.addr = (__u64)(user_sregs.regs.psw.addr & PSW32_ADDR_INSN); for (i = 0; i < NUM_GPRS; i++) - regs->gprs[i] = (__u64) regs32.gprs[i]; - memcpy(current->thread.acrs, regs32.acrs, sizeof(current->thread.acrs)); + regs->gprs[i] = (__u64) user_sregs.regs.gprs[i]; + memcpy(¤t->thread.acrs, &user_sregs.regs.acrs, + sizeof(current->thread.acrs)); restore_access_regs(current->thread.acrs); - err = __copy_from_user(¤t->thread.fp_regs, &sregs->fpregs, - sizeof(_s390_fp_regs32)); - current->thread.fp_regs.fpc &= FPC_VALID_MASK; - if (err) - return err; + memcpy(¤t->thread.fp_regs, &user_sregs.fpregs, + sizeof(current->thread.fp_regs)); - restore_fp_regs(¤t->thread.fp_regs); + restore_fp_regs(current->thread.fp_regs.fprs); clear_thread_flag(TIF_SYSCALL); /* No longer in a system call */ return 0; } @@ -215,18 +224,18 @@ static int save_sigregs_gprs_high(struct pt_regs *regs, __u32 __user *uregs) for (i = 0; i < NUM_GPRS; i++) gprs_high[i] = regs->gprs[i] >> 32; - - return __copy_to_user(uregs, &gprs_high, sizeof(gprs_high)); + if (__copy_to_user(uregs, &gprs_high, sizeof(gprs_high))) + return -EFAULT; + return 0; } static int restore_sigregs_gprs_high(struct pt_regs *regs, __u32 __user *uregs) { __u32 gprs_high[NUM_GPRS]; - int err, i; + int i; - err = __copy_from_user(&gprs_high, uregs, sizeof(gprs_high)); - if (err) - return err; + if (__copy_from_user(&gprs_high, uregs, sizeof(gprs_high))) + return -EFAULT; for (i = 0; i < NUM_GPRS; i++) *(__u32 *)®s->gprs[i] = gprs_high[i]; return 0; @@ -348,7 +357,7 @@ static int setup_frame32(int sig, struct k_sigaction *ka, regs->gprs[15] = (__force __u64) frame; /* Force 31 bit amode and default user address space control. */ regs->psw.mask = PSW_MASK_BA | - (psw_user_bits & PSW_MASK_ASC) | + (PSW_USER_BITS & PSW_MASK_ASC) | (regs->psw.mask & ~PSW_MASK_ASC); regs->psw.addr = (__force __u64) ka->sa.sa_handler; @@ -415,7 +424,7 @@ static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info, regs->gprs[15] = (__force __u64) frame; /* Force 31 bit amode and default user address space control. */ regs->psw.mask = PSW_MASK_BA | - (psw_user_bits & PSW_MASK_ASC) | + (PSW_USER_BITS & PSW_MASK_ASC) | (regs->psw.mask & ~PSW_MASK_ASC); regs->psw.addr = (__u64 __force) ka->sa.sa_handler; diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c index 7dd21720e5b0..d7658c4b2ed5 100644 --- a/arch/s390/kernel/crash_dump.c +++ b/arch/s390/kernel/crash_dump.c @@ -22,6 +22,32 @@ #define PTR_SUB(x, y) (((char *) (x)) - ((unsigned long) (y))) #define PTR_DIFF(x, y) ((unsigned long)(((char *) (x)) - ((unsigned long) (y)))) +struct dump_save_areas dump_save_areas; + +/* + * Allocate and add a save area for a CPU + */ +struct save_area *dump_save_area_create(int cpu) +{ + struct save_area **save_areas, *save_area; + + save_area = kmalloc(sizeof(*save_area), GFP_KERNEL); + if (!save_area) + return NULL; + if (cpu + 1 > dump_save_areas.count) { + dump_save_areas.count = cpu + 1; + save_areas = krealloc(dump_save_areas.areas, + dump_save_areas.count * sizeof(void *), + GFP_KERNEL | __GFP_ZERO); + if (!save_areas) { + kfree(save_area); + return NULL; + } + dump_save_areas.areas = save_areas; + } + dump_save_areas.areas[cpu] = save_area; + return save_area; +} /* * Return physical address for virtual address @@ -45,7 +71,6 @@ static inline void *load_real_addr(void *addr) static int copy_from_realmem(void *dest, void *src, size_t count) { unsigned long size; - int rc; if (!count) return 0; @@ -70,7 +95,7 @@ static void *elfcorehdr_newmem; /* * Copy one page from zfcpdump "oldmem" * - * For pages below ZFCPDUMP_HSA_SIZE memory from the HSA is copied. Otherwise + * For pages below HSA size memory from the HSA is copied. Otherwise * real memory copy is used. */ static ssize_t copy_oldmem_page_zfcpdump(char *buf, size_t csize, @@ -78,7 +103,7 @@ static ssize_t copy_oldmem_page_zfcpdump(char *buf, size_t csize, { int rc; - if (src < ZFCPDUMP_HSA_SIZE) { + if (src < sclp_get_hsa_size()) { rc = memcpy_hsa(buf, src, csize, userbuf); } else { if (userbuf) @@ -163,18 +188,19 @@ static int remap_oldmem_pfn_range_kdump(struct vm_area_struct *vma, /* * Remap "oldmem" for zfcpdump * - * We only map available memory above ZFCPDUMP_HSA_SIZE. Memory below - * ZFCPDUMP_HSA_SIZE is read on demand using the copy_oldmem_page() function. + * We only map available memory above HSA size. Memory below HSA size + * is read on demand using the copy_oldmem_page() function. */ static int remap_oldmem_pfn_range_zfcpdump(struct vm_area_struct *vma, unsigned long from, unsigned long pfn, unsigned long size, pgprot_t prot) { + unsigned long hsa_end = sclp_get_hsa_size(); unsigned long size_hsa; - if (pfn < ZFCPDUMP_HSA_SIZE >> PAGE_SHIFT) { - size_hsa = min(size, ZFCPDUMP_HSA_SIZE - (pfn << PAGE_SHIFT)); + if (pfn < hsa_end >> PAGE_SHIFT) { + size_hsa = min(size, hsa_end - (pfn << PAGE_SHIFT)); if (size == size_hsa) return 0; size -= size_hsa; @@ -213,9 +239,9 @@ int copy_from_oldmem(void *dest, void *src, size_t count) return rc; } } else { - if ((unsigned long) src < ZFCPDUMP_HSA_SIZE) { - copied = min(count, - ZFCPDUMP_HSA_SIZE - (unsigned long) src); + unsigned long hsa_end = sclp_get_hsa_size(); + if ((unsigned long) src < hsa_end) { + copied = min(count, hsa_end - (unsigned long) src); rc = memcpy_hsa(dest, (unsigned long) src, copied, 0); if (rc) return rc; @@ -451,8 +477,8 @@ static int get_cpu_cnt(void) { int i, cpus = 0; - for (i = 0; zfcpdump_save_areas[i]; i++) { - if (zfcpdump_save_areas[i]->pref_reg == 0) + for (i = 0; i < dump_save_areas.count; i++) { + if (dump_save_areas.areas[i]->pref_reg == 0) continue; cpus++; } @@ -523,8 +549,8 @@ static void *notes_init(Elf64_Phdr *phdr, void *ptr, u64 notes_offset) ptr = nt_prpsinfo(ptr); - for (i = 0; zfcpdump_save_areas[i]; i++) { - sa = zfcpdump_save_areas[i]; + for (i = 0; i < dump_save_areas.count; i++) { + sa = dump_save_areas.areas[i]; if (sa->pref_reg == 0) continue; ptr = fill_cpu_elf_notes(ptr, sa); @@ -555,6 +581,9 @@ int elfcorehdr_alloc(unsigned long long *addr, unsigned long long *size) /* If elfcorehdr= has been passed via cmdline, we use that one */ if (elfcorehdr_addr != ELFCORE_ADDR_MAX) return 0; + /* If we cannot get HSA size for zfcpdump return error */ + if (ipl_info.type == IPL_TYPE_FCP_DUMP && !sclp_get_hsa_size()) + return -ENODEV; mem_chunk_cnt = get_mem_chunk_cnt(); alloc_size = 0x1000 + get_cpu_cnt() * 0x300 + diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c index 17d62fe5d7b7..ee8390da6ea7 100644 --- a/arch/s390/kernel/debug.c +++ b/arch/s390/kernel/debug.c @@ -889,7 +889,7 @@ static int debug_active=1; * if debug_active is already off */ static int -s390dbf_procactive(ctl_table *table, int write, +s390dbf_procactive(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { if (!write || debug_stoppable || !debug_active) diff --git a/arch/s390/kernel/dis.c b/arch/s390/kernel/dis.c index be87d3e05a5b..993efe6a887c 100644 --- a/arch/s390/kernel/dis.c +++ b/arch/s390/kernel/dis.c @@ -23,6 +23,7 @@ #include <linux/kdebug.h> #include <asm/uaccess.h> +#include <asm/dis.h> #include <asm/io.h> #include <linux/atomic.h> #include <asm/mathemu.h> @@ -37,17 +38,6 @@ #define ONELONG "%016lx: " #endif /* CONFIG_64BIT */ -#define OPERAND_GPR 0x1 /* Operand printed as %rx */ -#define OPERAND_FPR 0x2 /* Operand printed as %fx */ -#define OPERAND_AR 0x4 /* Operand printed as %ax */ -#define OPERAND_CR 0x8 /* Operand printed as %cx */ -#define OPERAND_DISP 0x10 /* Operand printed as displacement */ -#define OPERAND_BASE 0x20 /* Operand printed as base register */ -#define OPERAND_INDEX 0x40 /* Operand printed as index register */ -#define OPERAND_PCREL 0x80 /* Operand printed as pc-relative symbol */ -#define OPERAND_SIGNED 0x100 /* Operand printed as signed value */ -#define OPERAND_LENGTH 0x200 /* Operand printed as length (+1) */ - enum { UNUSED, /* Indicates the end of the operand list */ R_8, /* GPR starting at position 8 */ @@ -155,19 +145,7 @@ enum { INSTR_S_00, INSTR_S_RD, }; -struct operand { - int bits; /* The number of bits in the operand. */ - int shift; /* The number of bits to shift. */ - int flags; /* One bit syntax flags. */ -}; - -struct insn { - const char name[5]; - unsigned char opfrag; - unsigned char format; -}; - -static const struct operand operands[] = +static const struct s390_operand operands[] = { [UNUSED] = { 0, 0, 0 }, [R_8] = { 4, 8, OPERAND_GPR }, @@ -479,7 +457,7 @@ static char *long_insn_name[] = { [LONG_INSN_PCISTB] = "pcistb", }; -static struct insn opcode[] = { +static struct s390_insn opcode[] = { #ifdef CONFIG_64BIT { "bprp", 0xc5, INSTR_MII_UPI }, { "bpp", 0xc7, INSTR_SMI_U0RDP }, @@ -668,7 +646,7 @@ static struct insn opcode[] = { { "", 0, INSTR_INVALID } }; -static struct insn opcode_01[] = { +static struct s390_insn opcode_01[] = { #ifdef CONFIG_64BIT { "ptff", 0x04, INSTR_E }, { "pfpo", 0x0a, INSTR_E }, @@ -684,7 +662,7 @@ static struct insn opcode_01[] = { { "", 0, INSTR_INVALID } }; -static struct insn opcode_a5[] = { +static struct s390_insn opcode_a5[] = { #ifdef CONFIG_64BIT { "iihh", 0x00, INSTR_RI_RU }, { "iihl", 0x01, INSTR_RI_RU }, @@ -706,7 +684,7 @@ static struct insn opcode_a5[] = { { "", 0, INSTR_INVALID } }; -static struct insn opcode_a7[] = { +static struct s390_insn opcode_a7[] = { #ifdef CONFIG_64BIT { "tmhh", 0x02, INSTR_RI_RU }, { "tmhl", 0x03, INSTR_RI_RU }, @@ -728,7 +706,7 @@ static struct insn opcode_a7[] = { { "", 0, INSTR_INVALID } }; -static struct insn opcode_aa[] = { +static struct s390_insn opcode_aa[] = { #ifdef CONFIG_64BIT { { 0, LONG_INSN_RINEXT }, 0x00, INSTR_RI_RI }, { "rion", 0x01, INSTR_RI_RI }, @@ -739,7 +717,7 @@ static struct insn opcode_aa[] = { { "", 0, INSTR_INVALID } }; -static struct insn opcode_b2[] = { +static struct s390_insn opcode_b2[] = { #ifdef CONFIG_64BIT { "stckf", 0x7c, INSTR_S_RD }, { "lpp", 0x80, INSTR_S_RD }, @@ -851,7 +829,7 @@ static struct insn opcode_b2[] = { { "", 0, INSTR_INVALID } }; -static struct insn opcode_b3[] = { +static struct s390_insn opcode_b3[] = { #ifdef CONFIG_64BIT { "maylr", 0x38, INSTR_RRF_F0FF }, { "mylr", 0x39, INSTR_RRF_F0FF }, @@ -1034,7 +1012,7 @@ static struct insn opcode_b3[] = { { "", 0, INSTR_INVALID } }; -static struct insn opcode_b9[] = { +static struct s390_insn opcode_b9[] = { #ifdef CONFIG_64BIT { "lpgr", 0x00, INSTR_RRE_RR }, { "lngr", 0x01, INSTR_RRE_RR }, @@ -1167,7 +1145,7 @@ static struct insn opcode_b9[] = { { "", 0, INSTR_INVALID } }; -static struct insn opcode_c0[] = { +static struct s390_insn opcode_c0[] = { #ifdef CONFIG_64BIT { "lgfi", 0x01, INSTR_RIL_RI }, { "xihf", 0x06, INSTR_RIL_RU }, @@ -1187,7 +1165,7 @@ static struct insn opcode_c0[] = { { "", 0, INSTR_INVALID } }; -static struct insn opcode_c2[] = { +static struct s390_insn opcode_c2[] = { #ifdef CONFIG_64BIT { "msgfi", 0x00, INSTR_RIL_RI }, { "msfi", 0x01, INSTR_RIL_RI }, @@ -1205,7 +1183,7 @@ static struct insn opcode_c2[] = { { "", 0, INSTR_INVALID } }; -static struct insn opcode_c4[] = { +static struct s390_insn opcode_c4[] = { #ifdef CONFIG_64BIT { "llhrl", 0x02, INSTR_RIL_RP }, { "lghrl", 0x04, INSTR_RIL_RP }, @@ -1222,7 +1200,7 @@ static struct insn opcode_c4[] = { { "", 0, INSTR_INVALID } }; -static struct insn opcode_c6[] = { +static struct s390_insn opcode_c6[] = { #ifdef CONFIG_64BIT { "exrl", 0x00, INSTR_RIL_RP }, { "pfdrl", 0x02, INSTR_RIL_UP }, @@ -1240,7 +1218,7 @@ static struct insn opcode_c6[] = { { "", 0, INSTR_INVALID } }; -static struct insn opcode_c8[] = { +static struct s390_insn opcode_c8[] = { #ifdef CONFIG_64BIT { "mvcos", 0x00, INSTR_SSF_RRDRD }, { "ectg", 0x01, INSTR_SSF_RRDRD }, @@ -1251,7 +1229,7 @@ static struct insn opcode_c8[] = { { "", 0, INSTR_INVALID } }; -static struct insn opcode_cc[] = { +static struct s390_insn opcode_cc[] = { #ifdef CONFIG_64BIT { "brcth", 0x06, INSTR_RIL_RP }, { "aih", 0x08, INSTR_RIL_RI }, @@ -1263,7 +1241,7 @@ static struct insn opcode_cc[] = { { "", 0, INSTR_INVALID } }; -static struct insn opcode_e3[] = { +static struct s390_insn opcode_e3[] = { #ifdef CONFIG_64BIT { "ltg", 0x02, INSTR_RXY_RRRD }, { "lrag", 0x03, INSTR_RXY_RRRD }, @@ -1369,7 +1347,7 @@ static struct insn opcode_e3[] = { { "", 0, INSTR_INVALID } }; -static struct insn opcode_e5[] = { +static struct s390_insn opcode_e5[] = { #ifdef CONFIG_64BIT { "strag", 0x02, INSTR_SSE_RDRD }, { "mvhhi", 0x44, INSTR_SIL_RDI }, @@ -1391,7 +1369,7 @@ static struct insn opcode_e5[] = { { "", 0, INSTR_INVALID } }; -static struct insn opcode_eb[] = { +static struct s390_insn opcode_eb[] = { #ifdef CONFIG_64BIT { "lmg", 0x04, INSTR_RSY_RRRD }, { "srag", 0x0a, INSTR_RSY_RRRD }, @@ -1465,7 +1443,7 @@ static struct insn opcode_eb[] = { { "", 0, INSTR_INVALID } }; -static struct insn opcode_ec[] = { +static struct s390_insn opcode_ec[] = { #ifdef CONFIG_64BIT { "brxhg", 0x44, INSTR_RIE_RRP }, { "brxlg", 0x45, INSTR_RIE_RRP }, @@ -1504,7 +1482,7 @@ static struct insn opcode_ec[] = { { "", 0, INSTR_INVALID } }; -static struct insn opcode_ed[] = { +static struct s390_insn opcode_ed[] = { #ifdef CONFIG_64BIT { "mayl", 0x38, INSTR_RXF_FRRDF }, { "myl", 0x39, INSTR_RXF_FRRDF }, @@ -1572,7 +1550,7 @@ static struct insn opcode_ed[] = { /* Extracts an operand value from an instruction. */ static unsigned int extract_operand(unsigned char *code, - const struct operand *operand) + const struct s390_operand *operand) { unsigned int val; int bits; @@ -1608,16 +1586,11 @@ static unsigned int extract_operand(unsigned char *code, return val; } -static inline int insn_length(unsigned char code) -{ - return ((((int) code + 64) >> 7) + 1) << 1; -} - -static struct insn *find_insn(unsigned char *code) +struct s390_insn *find_insn(unsigned char *code) { unsigned char opfrag = code[1]; unsigned char opmask; - struct insn *table; + struct s390_insn *table; switch (code[0]) { case 0x01: @@ -1706,7 +1679,7 @@ static struct insn *find_insn(unsigned char *code) */ int insn_to_mnemonic(unsigned char *instruction, char *buf, unsigned int len) { - struct insn *insn; + struct s390_insn *insn; insn = find_insn(instruction); if (!insn) @@ -1722,9 +1695,9 @@ EXPORT_SYMBOL_GPL(insn_to_mnemonic); static int print_insn(char *buffer, unsigned char *code, unsigned long addr) { - struct insn *insn; + struct s390_insn *insn; const unsigned char *ops; - const struct operand *operand; + const struct s390_operand *operand; unsigned int value; char separator; char *ptr; diff --git a/arch/s390/kernel/dumpstack.c b/arch/s390/kernel/dumpstack.c index 99e7f6035895..e6af9406987c 100644 --- a/arch/s390/kernel/dumpstack.c +++ b/arch/s390/kernel/dumpstack.c @@ -15,6 +15,7 @@ #include <linux/sched.h> #include <asm/processor.h> #include <asm/debug.h> +#include <asm/dis.h> #include <asm/ipl.h> #ifndef CONFIG_64BIT diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index dc8770d7173c..fca20b5fe79e 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c @@ -206,6 +206,7 @@ static noinline __init void clear_bss_section(void) */ static noinline __init void init_kernel_storage_key(void) { +#if PAGE_DEFAULT_KEY unsigned long end_pfn, init_pfn; end_pfn = PFN_UP(__pa(&_end)); @@ -213,6 +214,7 @@ static noinline __init void init_kernel_storage_key(void) for (init_pfn = 0 ; init_pfn < end_pfn; init_pfn++) page_set_storage_key(init_pfn << PAGE_SHIFT, PAGE_DEFAULT_KEY, 0); +#endif } static __initdata char sysinfo_page[PAGE_SIZE] __aligned(PAGE_SIZE); @@ -481,7 +483,7 @@ void __init startup_init(void) detect_diag44(); detect_machine_facilities(); setup_topology(); - sclp_facilities_detect(); + sclp_early_detect(); #ifdef CONFIG_DYNAMIC_FTRACE S390_lowcore.ftrace_func = (unsigned long)ftrace_caller; #endif diff --git a/arch/s390/kernel/entry.h b/arch/s390/kernel/entry.h index e9b04c33d383..cb533f78c09e 100644 --- a/arch/s390/kernel/entry.h +++ b/arch/s390/kernel/entry.h @@ -23,7 +23,6 @@ asmlinkage void do_syscall_trace_exit(struct pt_regs *regs); void do_protection_exception(struct pt_regs *regs); void do_dat_exception(struct pt_regs *regs); -void do_asce_exception(struct pt_regs *regs); void addressing_exception(struct pt_regs *regs); void data_exception(struct pt_regs *regs); diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c index 1014ad5f7693..224db03e9518 100644 --- a/arch/s390/kernel/ftrace.c +++ b/arch/s390/kernel/ftrace.c @@ -151,14 +151,13 @@ unsigned long __kprobes prepare_ftrace_return(unsigned long parent, if (unlikely(atomic_read(¤t->tracing_graph_pause))) goto out; ip = (ip & PSW_ADDR_INSN) - MCOUNT_INSN_SIZE; - if (ftrace_push_return_trace(parent, ip, &trace.depth, 0) == -EBUSY) - goto out; trace.func = ip; + trace.depth = current->curr_ret_stack + 1; /* Only trace if the calling function expects to. */ - if (!ftrace_graph_entry(&trace)) { - current->curr_ret_stack--; + if (!ftrace_graph_entry(&trace)) + goto out; + if (ftrace_push_return_trace(parent, ip, &trace.depth, 0) == -EBUSY) goto out; - } parent = (unsigned long) return_to_handler; out: return parent; diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S index fd8db63dfc94..429afcc480cb 100644 --- a/arch/s390/kernel/head.S +++ b/arch/s390/kernel/head.S @@ -437,7 +437,7 @@ ENTRY(startup_kdump) #if defined(CONFIG_64BIT) #if defined(CONFIG_MARCH_ZEC12) - .long 3, 0xc100efe3, 0xf46ce000, 0x00400000 + .long 3, 0xc100efe3, 0xf46ce800, 0x00400000 #elif defined(CONFIG_MARCH_Z196) .long 2, 0xc100efe3, 0xf46c0000 #elif defined(CONFIG_MARCH_Z10) diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index feb719d3c851..633ca7504536 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c @@ -2051,12 +2051,12 @@ void s390_reset_system(void (*func)(void *), void *data) __ctl_clear_bit(0,28); /* Set new machine check handler */ - S390_lowcore.mcck_new_psw.mask = psw_kernel_bits | PSW_MASK_DAT; + S390_lowcore.mcck_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT; S390_lowcore.mcck_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) s390_base_mcck_handler; /* Set new program check handler */ - S390_lowcore.program_new_psw.mask = psw_kernel_bits | PSW_MASK_DAT; + S390_lowcore.program_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT; S390_lowcore.program_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) s390_base_pgm_handler; diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c index 8ac2097f13d4..bb27a262c44a 100644 --- a/arch/s390/kernel/irq.c +++ b/arch/s390/kernel/irq.c @@ -157,39 +157,29 @@ int arch_show_interrupts(struct seq_file *p, int prec) /* * Switch to the asynchronous interrupt stack for softirq execution. */ -asmlinkage void do_softirq(void) +void do_softirq_own_stack(void) { - unsigned long flags, old, new; - - if (in_interrupt()) - return; - - local_irq_save(flags); - - if (local_softirq_pending()) { - /* Get current stack pointer. */ - asm volatile("la %0,0(15)" : "=a" (old)); - /* Check against async. stack address range. */ - new = S390_lowcore.async_stack; - if (((new - old) >> (PAGE_SHIFT + THREAD_ORDER)) != 0) { - /* Need to switch to the async. stack. */ - new -= STACK_FRAME_OVERHEAD; - ((struct stack_frame *) new)->back_chain = old; - - asm volatile(" la 15,0(%0)\n" - " basr 14,%2\n" - " la 15,0(%1)\n" - : : "a" (new), "a" (old), - "a" (__do_softirq) - : "0", "1", "2", "3", "4", "5", "14", - "cc", "memory" ); - } else { - /* We are already on the async stack. */ - __do_softirq(); - } + unsigned long old, new; + + /* Get current stack pointer. */ + asm volatile("la %0,0(15)" : "=a" (old)); + /* Check against async. stack address range. */ + new = S390_lowcore.async_stack; + if (((new - old) >> (PAGE_SHIFT + THREAD_ORDER)) != 0) { + /* Need to switch to the async. stack. */ + new -= STACK_FRAME_OVERHEAD; + ((struct stack_frame *) new)->back_chain = old; + asm volatile(" la 15,0(%0)\n" + " basr 14,%2\n" + " la 15,0(%1)\n" + : : "a" (new), "a" (old), + "a" (__do_softirq) + : "0", "1", "2", "3", "4", "5", "14", + "cc", "memory" ); + } else { + /* We are already on the async stack. */ + __do_softirq(); } - - local_irq_restore(flags); } /* diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c index d86e64eddb42..bc71a7b95af5 100644 --- a/arch/s390/kernel/kprobes.c +++ b/arch/s390/kernel/kprobes.c @@ -26,11 +26,12 @@ #include <linux/stop_machine.h> #include <linux/kdebug.h> #include <linux/uaccess.h> -#include <asm/cacheflush.h> -#include <asm/sections.h> #include <linux/module.h> #include <linux/slab.h> #include <linux/hardirq.h> +#include <asm/cacheflush.h> +#include <asm/sections.h> +#include <asm/dis.h> DEFINE_PER_CPU(struct kprobe *, current_kprobe); DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); @@ -59,6 +60,8 @@ struct kprobe_insn_cache kprobe_dmainsn_slots = { static int __kprobes is_prohibited_opcode(kprobe_opcode_t *insn) { + if (!is_known_insn((unsigned char *)insn)) + return -EINVAL; switch (insn[0] >> 8) { case 0x0c: /* bassm */ case 0x0b: /* bsm */ @@ -208,7 +211,7 @@ static void __kprobes copy_instruction(struct kprobe *p) s64 disp, new_disp; u64 addr, new_addr; - memcpy(p->ainsn.insn, p->addr, ((p->opcode >> 14) + 3) & -2); + memcpy(p->ainsn.insn, p->addr, insn_length(p->opcode >> 8)); if (!is_insn_relative_long(p->ainsn.insn)) return; /* @@ -252,7 +255,7 @@ static int __kprobes s390_get_insn_slot(struct kprobe *p) p->ainsn.insn = NULL; if (is_kernel_addr(p->addr)) p->ainsn.insn = get_dmainsn_slot(); - if (is_module_addr(p->addr)) + else if (is_module_addr(p->addr)) p->ainsn.insn = get_insn_slot(); return p->ainsn.insn ? 0 : -ENOMEM; } @@ -608,7 +611,7 @@ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs) ip += (unsigned long) p->addr - (unsigned long) p->ainsn.insn; if (fixup & FIXUP_BRANCH_NOT_TAKEN) { - int ilen = ((p->ainsn.insn[0] >> 14) + 3) & -2; + int ilen = insn_length(p->ainsn.insn[0] >> 8); if (ip - (unsigned long) p->ainsn.insn == ilen) ip = (unsigned long) p->addr + ilen; } @@ -677,7 +680,7 @@ static int __kprobes kprobe_trap_handler(struct pt_regs *regs, int trapnr) case KPROBE_HIT_SSDONE: /* * We increment the nmissed count for accounting, - * we can also use npre/npostfault count for accouting + * we can also use npre/npostfault count for accounting * these specific fault cases. */ kprobes_inc_nmissed_count(p); diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c index 7845e15a17df..b89b59158b95 100644 --- a/arch/s390/kernel/module.c +++ b/arch/s390/kernel/module.c @@ -50,7 +50,7 @@ void *module_alloc(unsigned long size) if (PAGE_ALIGN(size) > MODULES_LEN) return NULL; return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END, - GFP_KERNEL, PAGE_KERNEL, -1, + GFP_KERNEL, PAGE_KERNEL, NUMA_NO_NODE, __builtin_return_address(0)); } #endif diff --git a/arch/s390/kernel/pgm_check.S b/arch/s390/kernel/pgm_check.S index 14bdecb61923..4a460c44e17e 100644 --- a/arch/s390/kernel/pgm_check.S +++ b/arch/s390/kernel/pgm_check.S @@ -78,7 +78,7 @@ PGM_CHECK_DEFAULT /* 34 */ PGM_CHECK_DEFAULT /* 35 */ PGM_CHECK_DEFAULT /* 36 */ PGM_CHECK_DEFAULT /* 37 */ -PGM_CHECK_64BIT(do_asce_exception) /* 38 */ +PGM_CHECK_DEFAULT /* 38 */ PGM_CHECK_64BIT(do_dat_exception) /* 39 */ PGM_CHECK_64BIT(do_dat_exception) /* 3a */ PGM_CHECK_64BIT(do_dat_exception) /* 3b */ diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index c5dbb335716d..7ed0d4e2a435 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c @@ -139,7 +139,7 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp, if (unlikely(p->flags & PF_KTHREAD)) { /* kernel thread */ memset(&frame->childregs, 0, sizeof(struct pt_regs)); - frame->childregs.psw.mask = psw_kernel_bits | PSW_MASK_DAT | + frame->childregs.psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK; frame->childregs.psw.addr = PSW_ADDR_AMODE | (unsigned long) kernel_thread_starter; @@ -165,7 +165,8 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp, * save fprs to current->thread.fp_regs to merge them with * the emulated registers and then copy the result to the child. */ - save_fp_regs(¤t->thread.fp_regs); + save_fp_ctl(¤t->thread.fp_regs.fpc); + save_fp_regs(current->thread.fp_regs.fprs); memcpy(&p->thread.fp_regs, ¤t->thread.fp_regs, sizeof(s390_fp_regs)); /* Set a new TLS ? */ @@ -173,7 +174,9 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp, p->thread.acrs[0] = frame->childregs.gprs[6]; #else /* CONFIG_64BIT */ /* Save the fpu registers to new thread structure. */ - save_fp_regs(&p->thread.fp_regs); + save_fp_ctl(&p->thread.fp_regs.fpc); + save_fp_regs(p->thread.fp_regs.fprs); + p->thread.fp_regs.pad = 0; /* Set a new TLS ? */ if (clone_flags & CLONE_SETTLS) { unsigned long tls = frame->childregs.gprs[6]; @@ -205,10 +208,12 @@ int dump_fpu (struct pt_regs * regs, s390_fp_regs *fpregs) * save fprs to current->thread.fp_regs to merge them with * the emulated registers and then copy the result to the dump. */ - save_fp_regs(¤t->thread.fp_regs); + save_fp_ctl(¤t->thread.fp_regs.fpc); + save_fp_regs(current->thread.fp_regs.fprs); memcpy(fpregs, ¤t->thread.fp_regs, sizeof(s390_fp_regs)); #else /* CONFIG_64BIT */ - save_fp_regs(fpregs); + save_fp_ctl(&fpregs->fpc); + save_fp_regs(fpregs->fprs); #endif /* CONFIG_64BIT */ return 1; } diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index 9556905bd3ce..e65c91c591e8 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c @@ -198,9 +198,11 @@ static unsigned long __peek_user(struct task_struct *child, addr_t addr) * psw and gprs are stored on the stack */ tmp = *(addr_t *)((addr_t) &task_pt_regs(child)->psw + addr); - if (addr == (addr_t) &dummy->regs.psw.mask) + if (addr == (addr_t) &dummy->regs.psw.mask) { /* Return a clean psw mask. */ - tmp = psw_user_bits | (tmp & PSW_MASK_USER); + tmp &= PSW_MASK_USER | PSW_MASK_RI; + tmp |= PSW_USER_BITS; + } } else if (addr < (addr_t) &dummy->regs.orig_gpr2) { /* @@ -239,8 +241,7 @@ static unsigned long __peek_user(struct task_struct *child, addr_t addr) offset = addr - (addr_t) &dummy->regs.fp_regs; tmp = *(addr_t *)((addr_t) &child->thread.fp_regs + offset); if (addr == (addr_t) &dummy->regs.fp_regs.fpc) - tmp &= (unsigned long) FPC_VALID_MASK - << (BITS_PER_LONG - 32); + tmp <<= BITS_PER_LONG - 32; } else if (addr < (addr_t) (&dummy->regs.per_info + 1)) { /* @@ -321,11 +322,15 @@ static int __poke_user(struct task_struct *child, addr_t addr, addr_t data) /* * psw and gprs are stored on the stack */ - if (addr == (addr_t) &dummy->regs.psw.mask && - ((data & ~PSW_MASK_USER) != psw_user_bits || - ((data & PSW_MASK_EA) && !(data & PSW_MASK_BA)))) - /* Invalid psw mask. */ - return -EINVAL; + if (addr == (addr_t) &dummy->regs.psw.mask) { + unsigned long mask = PSW_MASK_USER; + + mask |= is_ri_task(child) ? PSW_MASK_RI : 0; + if ((data & ~mask) != PSW_USER_BITS) + return -EINVAL; + if ((data & PSW_MASK_EA) && !(data & PSW_MASK_BA)) + return -EINVAL; + } *(addr_t *)((addr_t) &task_pt_regs(child)->psw + addr) = data; } else if (addr < (addr_t) (&dummy->regs.orig_gpr2)) { @@ -363,10 +368,10 @@ static int __poke_user(struct task_struct *child, addr_t addr, addr_t data) /* * floating point regs. are stored in the thread structure */ - if (addr == (addr_t) &dummy->regs.fp_regs.fpc && - (data & ~((unsigned long) FPC_VALID_MASK - << (BITS_PER_LONG - 32))) != 0) - return -EINVAL; + if (addr == (addr_t) &dummy->regs.fp_regs.fpc) + if ((unsigned int) data != 0 || + test_fp_ctl(data >> (BITS_PER_LONG - 32))) + return -EINVAL; offset = addr - (addr_t) &dummy->regs.fp_regs; *(addr_t *)((addr_t) &child->thread.fp_regs + offset) = data; @@ -557,7 +562,8 @@ static u32 __peek_user_compat(struct task_struct *child, addr_t addr) if (addr == (addr_t) &dummy32->regs.psw.mask) { /* Fake a 31 bit psw mask. */ tmp = (__u32)(regs->psw.mask >> 32); - tmp = psw32_user_bits | (tmp & PSW32_MASK_USER); + tmp &= PSW32_MASK_USER | PSW32_MASK_RI; + tmp |= PSW32_USER_BITS; } else if (addr == (addr_t) &dummy32->regs.psw.addr) { /* Fake a 31 bit psw address. */ tmp = (__u32) regs->psw.addr | @@ -654,13 +660,16 @@ static int __poke_user_compat(struct task_struct *child, * psw, gprs, acrs and orig_gpr2 are stored on the stack */ if (addr == (addr_t) &dummy32->regs.psw.mask) { + __u32 mask = PSW32_MASK_USER; + + mask |= is_ri_task(child) ? PSW32_MASK_RI : 0; /* Build a 64 bit psw mask from 31 bit mask. */ - if ((tmp & ~PSW32_MASK_USER) != psw32_user_bits) + if ((tmp & ~mask) != PSW32_USER_BITS) /* Invalid psw mask. */ return -EINVAL; regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) | (regs->psw.mask & PSW_MASK_BA) | - (__u64)(tmp & PSW32_MASK_USER) << 32; + (__u64)(tmp & mask) << 32; } else if (addr == (addr_t) &dummy32->regs.psw.addr) { /* Build a 64 bit psw address from 31 bit address. */ regs->psw.addr = (__u64) tmp & PSW32_ADDR_INSN; @@ -696,8 +705,7 @@ static int __poke_user_compat(struct task_struct *child, * floating point regs. are stored in the thread structure */ if (addr == (addr_t) &dummy32->regs.fp_regs.fpc && - (tmp & ~FPC_VALID_MASK) != 0) - /* Invalid floating point control. */ + test_fp_ctl(tmp)) return -EINVAL; offset = addr - (addr_t) &dummy32->regs.fp_regs; *(__u32 *)((addr_t) &child->thread.fp_regs + offset) = tmp; @@ -895,8 +903,10 @@ static int s390_fpregs_get(struct task_struct *target, const struct user_regset *regset, unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) { - if (target == current) - save_fp_regs(&target->thread.fp_regs); + if (target == current) { + save_fp_ctl(&target->thread.fp_regs.fpc); + save_fp_regs(target->thread.fp_regs.fprs); + } return user_regset_copyout(&pos, &count, &kbuf, &ubuf, &target->thread.fp_regs, 0, -1); @@ -909,19 +919,21 @@ static int s390_fpregs_set(struct task_struct *target, { int rc = 0; - if (target == current) - save_fp_regs(&target->thread.fp_regs); + if (target == current) { + save_fp_ctl(&target->thread.fp_regs.fpc); + save_fp_regs(target->thread.fp_regs.fprs); + } /* If setting FPC, must validate it first. */ if (count > 0 && pos < offsetof(s390_fp_regs, fprs)) { - u32 fpc[2] = { target->thread.fp_regs.fpc, 0 }; - rc = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &fpc, + u32 ufpc[2] = { target->thread.fp_regs.fpc, 0 }; + rc = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &ufpc, 0, offsetof(s390_fp_regs, fprs)); if (rc) return rc; - if ((fpc[0] & ~FPC_VALID_MASK) != 0 || fpc[1] != 0) + if (ufpc[1] != 0 || test_fp_ctl(ufpc[0])) return -EINVAL; - target->thread.fp_regs.fpc = fpc[0]; + target->thread.fp_regs.fpc = ufpc[0]; } if (rc == 0 && count > 0) @@ -929,8 +941,10 @@ static int s390_fpregs_set(struct task_struct *target, target->thread.fp_regs.fprs, offsetof(s390_fp_regs, fprs), -1); - if (rc == 0 && target == current) - restore_fp_regs(&target->thread.fp_regs); + if (rc == 0 && target == current) { + restore_fp_ctl(&target->thread.fp_regs.fpc); + restore_fp_regs(target->thread.fp_regs.fprs); + } return rc; } diff --git a/arch/s390/kernel/runtime_instr.c b/arch/s390/kernel/runtime_instr.c index e1c9d1c292fa..d817cce7e72d 100644 --- a/arch/s390/kernel/runtime_instr.c +++ b/arch/s390/kernel/runtime_instr.c @@ -40,8 +40,6 @@ static void disable_runtime_instr(void) static void init_runtime_instr_cb(struct runtime_instr_cb *cb) { cb->buf_limit = 0xfff; - if (s390_user_mode == HOME_SPACE_MODE) - cb->home_space = 1; cb->int_requested = 1; cb->pstate = 1; cb->pstate_set_buf = 1; diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index aeed8a61fa0d..4444875266ee 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -64,12 +64,6 @@ #include <asm/sclp.h> #include "entry.h" -long psw_kernel_bits = PSW_DEFAULT_KEY | PSW_MASK_BASE | PSW_ASC_PRIMARY | - PSW_MASK_EA | PSW_MASK_BA; -long psw_user_bits = PSW_MASK_DAT | PSW_MASK_IO | PSW_MASK_EXT | - PSW_DEFAULT_KEY | PSW_MASK_BASE | PSW_MASK_MCHECK | - PSW_MASK_PSTATE | PSW_ASC_HOME; - /* * User copy operations. */ @@ -300,43 +294,14 @@ static int __init parse_vmalloc(char *arg) } early_param("vmalloc", parse_vmalloc); -unsigned int s390_user_mode = PRIMARY_SPACE_MODE; -EXPORT_SYMBOL_GPL(s390_user_mode); - -static void __init set_user_mode_primary(void) -{ - psw_kernel_bits = (psw_kernel_bits & ~PSW_MASK_ASC) | PSW_ASC_HOME; - psw_user_bits = (psw_user_bits & ~PSW_MASK_ASC) | PSW_ASC_PRIMARY; -#ifdef CONFIG_COMPAT - psw32_user_bits = - (psw32_user_bits & ~PSW32_MASK_ASC) | PSW32_ASC_PRIMARY; -#endif - uaccess = MACHINE_HAS_MVCOS ? uaccess_mvcos_switch : uaccess_pt; -} - static int __init early_parse_user_mode(char *p) { - if (p && strcmp(p, "primary") == 0) - s390_user_mode = PRIMARY_SPACE_MODE; - else if (!p || strcmp(p, "home") == 0) - s390_user_mode = HOME_SPACE_MODE; - else - return 1; - return 0; + if (!p || strcmp(p, "primary") == 0) + return 0; + return 1; } early_param("user_mode", early_parse_user_mode); -static void __init setup_addressing_mode(void) -{ - if (s390_user_mode != PRIMARY_SPACE_MODE) - return; - set_user_mode_primary(); - if (MACHINE_HAS_MVCOS) - pr_info("Address spaces switched, mvcos available\n"); - else - pr_info("Address spaces switched, mvcos not available\n"); -} - void *restart_stack __attribute__((__section__(".data"))); static void __init setup_lowcore(void) @@ -348,24 +313,24 @@ static void __init setup_lowcore(void) */ BUILD_BUG_ON(sizeof(struct _lowcore) != LC_PAGES * 4096); lc = __alloc_bootmem_low(LC_PAGES * PAGE_SIZE, LC_PAGES * PAGE_SIZE, 0); - lc->restart_psw.mask = psw_kernel_bits; + lc->restart_psw.mask = PSW_KERNEL_BITS; lc->restart_psw.addr = PSW_ADDR_AMODE | (unsigned long) restart_int_handler; - lc->external_new_psw.mask = psw_kernel_bits | + lc->external_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT | PSW_MASK_MCHECK; lc->external_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) ext_int_handler; - lc->svc_new_psw.mask = psw_kernel_bits | + lc->svc_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK; lc->svc_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) system_call; - lc->program_new_psw.mask = psw_kernel_bits | + lc->program_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT | PSW_MASK_MCHECK; lc->program_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) pgm_check_handler; - lc->mcck_new_psw.mask = psw_kernel_bits; + lc->mcck_new_psw.mask = PSW_KERNEL_BITS; lc->mcck_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) mcck_int_handler; - lc->io_new_psw.mask = psw_kernel_bits | + lc->io_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT | PSW_MASK_MCHECK; lc->io_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) io_int_handler; lc->clock_comparator = -1ULL; @@ -506,8 +471,9 @@ static void __init setup_memory_end(void) #ifdef CONFIG_ZFCPDUMP - if (ipl_info.type == IPL_TYPE_FCP_DUMP && !OLDMEM_BASE) { - memory_end = ZFCPDUMP_HSA_SIZE; + if (ipl_info.type == IPL_TYPE_FCP_DUMP && + !OLDMEM_BASE && sclp_get_hsa_size()) { + memory_end = sclp_get_hsa_size(); memory_end_set = 1; } #endif @@ -621,7 +587,7 @@ static unsigned long __init find_crash_base(unsigned long crash_size, crash_base = (chunk->addr + chunk->size) - crash_size; if (crash_base < crash_size) continue; - if (crash_base < ZFCPDUMP_HSA_SIZE_MAX) + if (crash_base < sclp_get_hsa_size()) continue; if (crash_base < (unsigned long) INITRD_START + INITRD_SIZE) continue; @@ -1043,10 +1009,7 @@ void __init setup_arch(char **cmdline_p) init_mm.end_data = (unsigned long) &_edata; init_mm.brk = (unsigned long) &_end; - if (MACHINE_HAS_MVCOS) - memcpy(&uaccess, &uaccess_mvcos, sizeof(uaccess)); - else - memcpy(&uaccess, &uaccess_std, sizeof(uaccess)); + uaccess = MACHINE_HAS_MVCOS ? uaccess_mvcos : uaccess_pt; parse_early_param(); detect_memory_layout(memory_chunk, memory_end); @@ -1054,7 +1017,6 @@ void __init setup_arch(char **cmdline_p) setup_ipl(); reserve_oldmem(); setup_memory_end(); - setup_addressing_mode(); reserve_crashkernel(); setup_memory(); setup_resources(); diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index c45becf82e01..fb535874a246 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c @@ -57,40 +57,48 @@ static int save_sigregs(struct pt_regs *regs, _sigregs __user *sregs) /* Copy a 'clean' PSW mask to the user to avoid leaking information about whether PER is currently on. */ - user_sregs.regs.psw.mask = psw_user_bits | - (regs->psw.mask & PSW_MASK_USER); + user_sregs.regs.psw.mask = PSW_USER_BITS | + (regs->psw.mask & (PSW_MASK_USER | PSW_MASK_RI)); user_sregs.regs.psw.addr = regs->psw.addr; memcpy(&user_sregs.regs.gprs, ®s->gprs, sizeof(sregs->regs.gprs)); memcpy(&user_sregs.regs.acrs, current->thread.acrs, - sizeof(sregs->regs.acrs)); + sizeof(user_sregs.regs.acrs)); /* * We have to store the fp registers to current->thread.fp_regs * to merge them with the emulated registers. */ - save_fp_regs(¤t->thread.fp_regs); + save_fp_ctl(¤t->thread.fp_regs.fpc); + save_fp_regs(current->thread.fp_regs.fprs); memcpy(&user_sregs.fpregs, ¤t->thread.fp_regs, - sizeof(s390_fp_regs)); - return __copy_to_user(sregs, &user_sregs, sizeof(_sigregs)); + sizeof(user_sregs.fpregs)); + if (__copy_to_user(sregs, &user_sregs, sizeof(_sigregs))) + return -EFAULT; + return 0; } -/* Returns positive number on error */ static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs) { - int err; _sigregs user_sregs; /* Alwys make any pending restarted system call return -EINTR */ current_thread_info()->restart_block.fn = do_no_restart_syscall; - err = __copy_from_user(&user_sregs, sregs, sizeof(_sigregs)); - if (err) - return err; - /* Use regs->psw.mask instead of psw_user_bits to preserve PER bit. */ + if (__copy_from_user(&user_sregs, sregs, sizeof(user_sregs))) + return -EFAULT; + + if (!is_ri_task(current) && (user_sregs.regs.psw.mask & PSW_MASK_RI)) + return -EINVAL; + + /* Loading the floating-point-control word can fail. Do that first. */ + if (restore_fp_ctl(&user_sregs.fpregs.fpc)) + return -EINVAL; + + /* Use regs->psw.mask instead of PSW_USER_BITS to preserve PER bit. */ regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) | - (user_sregs.regs.psw.mask & PSW_MASK_USER); + (user_sregs.regs.psw.mask & (PSW_MASK_USER | PSW_MASK_RI)); /* Check for invalid user address space control. */ - if ((regs->psw.mask & PSW_MASK_ASC) >= (psw_kernel_bits & PSW_MASK_ASC)) - regs->psw.mask = (psw_user_bits & PSW_MASK_ASC) | + if ((regs->psw.mask & PSW_MASK_ASC) == PSW_ASC_HOME) + regs->psw.mask = PSW_ASC_PRIMARY | (regs->psw.mask & ~PSW_MASK_ASC); /* Check for invalid amode */ if (regs->psw.mask & PSW_MASK_EA) @@ -98,14 +106,13 @@ static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs) regs->psw.addr = user_sregs.regs.psw.addr; memcpy(®s->gprs, &user_sregs.regs.gprs, sizeof(sregs->regs.gprs)); memcpy(¤t->thread.acrs, &user_sregs.regs.acrs, - sizeof(sregs->regs.acrs)); + sizeof(current->thread.acrs)); restore_access_regs(current->thread.acrs); memcpy(¤t->thread.fp_regs, &user_sregs.fpregs, - sizeof(s390_fp_regs)); - current->thread.fp_regs.fpc &= FPC_VALID_MASK; + sizeof(current->thread.fp_regs)); - restore_fp_regs(¤t->thread.fp_regs); + restore_fp_regs(current->thread.fp_regs.fprs); clear_thread_flag(TIF_SYSCALL); /* No longer in a system call */ return 0; } @@ -224,7 +231,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, regs->gprs[15] = (unsigned long) frame; /* Force default amode and default user address space control. */ regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA | - (psw_user_bits & PSW_MASK_ASC) | + (PSW_USER_BITS & PSW_MASK_ASC) | (regs->psw.mask & ~PSW_MASK_ASC); regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE; @@ -295,7 +302,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, regs->gprs[15] = (unsigned long) frame; /* Force default amode and default user address space control. */ regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA | - (psw_user_bits & PSW_MASK_ASC) | + (PSW_USER_BITS & PSW_MASK_ASC) | (regs->psw.mask & ~PSW_MASK_ASC); regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE; diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 1a4313a1b60f..dc4a53465060 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -283,7 +283,7 @@ static void pcpu_delegate(struct pcpu *pcpu, void (*func)(void *), struct _lowcore *lc = lowcore_ptr[pcpu - pcpu_devices]; unsigned long source_cpu = stap(); - __load_psw_mask(psw_kernel_bits); + __load_psw_mask(PSW_KERNEL_BITS); if (pcpu->address == source_cpu) func(data); /* should not return */ /* Stop target cpu (if func returns this stops the current cpu). */ @@ -395,7 +395,7 @@ void smp_send_stop(void) int cpu; /* Disable all interrupts/machine checks */ - __load_psw_mask(psw_kernel_bits | PSW_MASK_DAT); + __load_psw_mask(PSW_KERNEL_BITS | PSW_MASK_DAT); trace_hardirqs_off(); debug_set_critical(); @@ -533,9 +533,6 @@ EXPORT_SYMBOL(smp_ctl_clear_bit); #if defined(CONFIG_ZFCPDUMP) || defined(CONFIG_CRASH_DUMP) -struct save_area *zfcpdump_save_areas[NR_CPUS + 1]; -EXPORT_SYMBOL_GPL(zfcpdump_save_areas); - static void __init smp_get_save_area(int cpu, u16 address) { void *lc = pcpu_devices[0].lowcore; @@ -546,15 +543,9 @@ static void __init smp_get_save_area(int cpu, u16 address) if (!OLDMEM_BASE && (address == boot_cpu_address || ipl_info.type != IPL_TYPE_FCP_DUMP)) return; - if (cpu >= NR_CPUS) { - pr_warning("CPU %i exceeds the maximum %i and is excluded " - "from the dump\n", cpu, NR_CPUS - 1); - return; - } - save_area = kmalloc(sizeof(struct save_area), GFP_KERNEL); + save_area = dump_save_area_create(cpu); if (!save_area) panic("could not allocate memory for save area\n"); - zfcpdump_save_areas[cpu] = save_area; #ifdef CONFIG_CRASH_DUMP if (address == boot_cpu_address) { /* Copy the registers of the boot cpu. */ @@ -693,7 +684,7 @@ static void smp_start_secondary(void *cpuvoid) S390_lowcore.restart_source = -1UL; restore_access_regs(S390_lowcore.access_regs_save_area); __ctl_load(S390_lowcore.cregs_save_area, 0, 15); - __load_psw_mask(psw_kernel_bits | PSW_MASK_DAT); + __load_psw_mask(PSW_KERNEL_BITS | PSW_MASK_DAT); cpu_init(); preempt_disable(); init_cpu_timer(); @@ -929,7 +920,7 @@ static ssize_t show_idle_count(struct device *dev, idle_count = ACCESS_ONCE(idle->idle_count); if (ACCESS_ONCE(idle->clock_idle_enter)) idle_count++; - } while ((sequence & 1) || (idle->sequence != sequence)); + } while ((sequence & 1) || (ACCESS_ONCE(idle->sequence) != sequence)); return sprintf(buf, "%llu\n", idle_count); } static DEVICE_ATTR(idle_count, 0444, show_idle_count, NULL); @@ -947,7 +938,7 @@ static ssize_t show_idle_time(struct device *dev, idle_time = ACCESS_ONCE(idle->idle_time); idle_enter = ACCESS_ONCE(idle->clock_idle_enter); idle_exit = ACCESS_ONCE(idle->clock_idle_exit); - } while ((sequence & 1) || (idle->sequence != sequence)); + } while ((sequence & 1) || (ACCESS_ONCE(idle->sequence) != sequence)); idle_time += idle_enter ? ((idle_exit ? : now) - idle_enter) : 0; return sprintf(buf, "%llu\n", idle_time >> 12); } diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c index 05d75c413137..a84476f2a9bb 100644 --- a/arch/s390/kernel/vdso.c +++ b/arch/s390/kernel/vdso.c @@ -84,8 +84,7 @@ struct vdso_data *vdso_data = &vdso_data_store.data; */ static void vdso_init_data(struct vdso_data *vd) { - vd->ectg_available = - s390_user_mode != HOME_SPACE_MODE && test_facility(31); + vd->ectg_available = test_facility(31); } #ifdef CONFIG_64BIT @@ -102,7 +101,7 @@ int vdso_alloc_per_cpu(struct _lowcore *lowcore) lowcore->vdso_per_cpu_data = __LC_PASTE; - if (s390_user_mode == HOME_SPACE_MODE || !vdso_enabled) + if (!vdso_enabled) return 0; segment_table = __get_free_pages(GFP_KERNEL, SEGMENT_ORDER); @@ -147,7 +146,7 @@ void vdso_free_per_cpu(struct _lowcore *lowcore) unsigned long segment_table, page_table, page_frame; u32 *psal, *aste; - if (s390_user_mode == HOME_SPACE_MODE || !vdso_enabled) + if (!vdso_enabled) return; psal = (u32 *)(addr_t) lowcore->paste[4]; @@ -165,7 +164,7 @@ static void vdso_init_cr5(void) { unsigned long cr5; - if (s390_user_mode == HOME_SPACE_MODE || !vdso_enabled) + if (!vdso_enabled) return; cr5 = offsetof(struct _lowcore, paste); __ctl_load(cr5, 5, 5); diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c index abcfab55f99b..8c34363d6f1e 100644 --- a/arch/s390/kernel/vtime.c +++ b/arch/s390/kernel/vtime.c @@ -161,7 +161,7 @@ void __kprobes vtime_stop_cpu(void) trace_hardirqs_on(); /* Wait for external, I/O or machine check interrupt. */ - psw_mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_DAT | + psw_mask = PSW_KERNEL_BITS | PSW_MASK_WAIT | PSW_MASK_DAT | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK; idle->nohz_delay = 0; @@ -191,7 +191,7 @@ cputime64_t s390_get_idle_time(int cpu) sequence = ACCESS_ONCE(idle->sequence); idle_enter = ACCESS_ONCE(idle->clock_idle_enter); idle_exit = ACCESS_ONCE(idle->clock_idle_exit); - } while ((sequence & 1) || (idle->sequence != sequence)); + } while ((sequence & 1) || (ACCESS_ONCE(idle->sequence) != sequence)); return idle_enter ? ((idle_exit ?: now) - idle_enter) : 0; } diff --git a/arch/s390/kvm/diag.c b/arch/s390/kvm/diag.c index 3a74d8af0d69..78d967f180f4 100644 --- a/arch/s390/kvm/diag.c +++ b/arch/s390/kvm/diag.c @@ -107,14 +107,13 @@ static int __diag_ipl_functions(struct kvm_vcpu *vcpu) static int __diag_virtio_hypercall(struct kvm_vcpu *vcpu) { - int ret, idx; + int ret; /* No virtio-ccw notification? Get out quickly. */ if (!vcpu->kvm->arch.css_support || (vcpu->run->s.regs.gprs[1] != KVM_S390_VIRTIO_CCW_NOTIFY)) return -EOPNOTSUPP; - idx = srcu_read_lock(&vcpu->kvm->srcu); /* * The layout is as follows: * - gpr 2 contains the subchannel id (passed as addr) @@ -125,7 +124,6 @@ static int __diag_virtio_hypercall(struct kvm_vcpu *vcpu) vcpu->run->s.regs.gprs[2], 8, &vcpu->run->s.regs.gprs[3], vcpu->run->s.regs.gprs[4]); - srcu_read_unlock(&vcpu->kvm->srcu, idx); /* * Return cookie in gpr 2, but don't overwrite the register if the diff --git a/arch/s390/kvm/gaccess.h b/arch/s390/kvm/gaccess.h index 99d789e8a018..374a439ccc60 100644 --- a/arch/s390/kvm/gaccess.h +++ b/arch/s390/kvm/gaccess.h @@ -18,20 +18,27 @@ #include <asm/uaccess.h> #include "kvm-s390.h" +/* Convert real to absolute address by applying the prefix of the CPU */ +static inline unsigned long kvm_s390_real_to_abs(struct kvm_vcpu *vcpu, + unsigned long gaddr) +{ + unsigned long prefix = vcpu->arch.sie_block->prefix; + if (gaddr < 2 * PAGE_SIZE) + gaddr += prefix; + else if (gaddr >= prefix && gaddr < prefix + 2 * PAGE_SIZE) + gaddr -= prefix; + return gaddr; +} + static inline void __user *__gptr_to_uptr(struct kvm_vcpu *vcpu, void __user *gptr, int prefixing) { - unsigned long prefix = vcpu->arch.sie_block->prefix; unsigned long gaddr = (unsigned long) gptr; unsigned long uaddr; - if (prefixing) { - if (gaddr < 2 * PAGE_SIZE) - gaddr += prefix; - else if ((gaddr >= prefix) && (gaddr < prefix + 2 * PAGE_SIZE)) - gaddr -= prefix; - } + if (prefixing) + gaddr = kvm_s390_real_to_abs(vcpu, gaddr); uaddr = gmap_fault(gaddr, vcpu->arch.gmap); if (IS_ERR_VALUE(uaddr)) uaddr = -EFAULT; diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c index 5ee56e5acc23..5ddbbde6f65c 100644 --- a/arch/s390/kvm/intercept.c +++ b/arch/s390/kvm/intercept.c @@ -62,12 +62,6 @@ static int handle_stop(struct kvm_vcpu *vcpu) trace_kvm_s390_stop_request(vcpu->arch.local_int.action_bits); - if (vcpu->arch.local_int.action_bits & ACTION_RELOADVCPU_ON_STOP) { - vcpu->arch.local_int.action_bits &= ~ACTION_RELOADVCPU_ON_STOP; - rc = SIE_INTERCEPT_RERUNVCPU; - vcpu->run->exit_reason = KVM_EXIT_INTR; - } - if (vcpu->arch.local_int.action_bits & ACTION_STOP_ON_STOP) { atomic_set_mask(CPUSTAT_STOPPED, &vcpu->arch.sie_block->cpuflags); diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index 7f1f7ac5cf7f..5f79d2d79ca7 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c @@ -436,6 +436,7 @@ int kvm_s390_handle_wait(struct kvm_vcpu *vcpu) hrtimer_start(&vcpu->arch.ckc_timer, ktime_set (0, sltime) , HRTIMER_MODE_REL); VCPU_EVENT(vcpu, 5, "enabled wait via clock comparator: %llx ns", sltime); no_timer: + srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx); spin_lock(&vcpu->arch.local_int.float_int->lock); spin_lock_bh(&vcpu->arch.local_int.lock); add_wait_queue(&vcpu->wq, &wait); @@ -455,6 +456,8 @@ no_timer: remove_wait_queue(&vcpu->wq, &wait); spin_unlock_bh(&vcpu->arch.local_int.lock); spin_unlock(&vcpu->arch.local_int.float_int->lock); + vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu); + hrtimer_try_to_cancel(&vcpu->arch.ckc_timer); return 0; } diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 776dafe918db..569494e01ec6 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -343,10 +343,11 @@ void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) { - save_fp_regs(&vcpu->arch.host_fpregs); + save_fp_ctl(&vcpu->arch.host_fpregs.fpc); + save_fp_regs(vcpu->arch.host_fpregs.fprs); save_access_regs(vcpu->arch.host_acrs); - vcpu->arch.guest_fpregs.fpc &= FPC_VALID_MASK; - restore_fp_regs(&vcpu->arch.guest_fpregs); + restore_fp_ctl(&vcpu->arch.guest_fpregs.fpc); + restore_fp_regs(vcpu->arch.guest_fpregs.fprs); restore_access_regs(vcpu->run->s.regs.acrs); gmap_enable(vcpu->arch.gmap); atomic_set_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags); @@ -356,9 +357,11 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) { atomic_clear_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags); gmap_disable(vcpu->arch.gmap); - save_fp_regs(&vcpu->arch.guest_fpregs); + save_fp_ctl(&vcpu->arch.guest_fpregs.fpc); + save_fp_regs(vcpu->arch.guest_fpregs.fprs); save_access_regs(vcpu->run->s.regs.acrs); - restore_fp_regs(&vcpu->arch.host_fpregs); + restore_fp_ctl(&vcpu->arch.host_fpregs.fpc); + restore_fp_regs(vcpu->arch.host_fpregs.fprs); restore_access_regs(vcpu->arch.host_acrs); } @@ -618,9 +621,12 @@ int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) { + if (test_fp_ctl(fpu->fpc)) + return -EINVAL; memcpy(&vcpu->arch.guest_fpregs.fprs, &fpu->fprs, sizeof(fpu->fprs)); - vcpu->arch.guest_fpregs.fpc = fpu->fpc & FPC_VALID_MASK; - restore_fp_regs(&vcpu->arch.guest_fpregs); + vcpu->arch.guest_fpregs.fpc = fpu->fpc; + restore_fp_ctl(&vcpu->arch.guest_fpregs.fpc); + restore_fp_regs(vcpu->arch.guest_fpregs.fprs); return 0; } @@ -689,9 +695,9 @@ static int kvm_s390_handle_requests(struct kvm_vcpu *vcpu) return 0; } -static int __vcpu_run(struct kvm_vcpu *vcpu) +static int vcpu_pre_run(struct kvm_vcpu *vcpu) { - int rc; + int rc, cpuflags; memcpy(&vcpu->arch.sie_block->gg14, &vcpu->run->s.regs.gprs[14], 16); @@ -709,28 +715,24 @@ static int __vcpu_run(struct kvm_vcpu *vcpu) return rc; vcpu->arch.sie_block->icptcode = 0; - VCPU_EVENT(vcpu, 6, "entering sie flags %x", - atomic_read(&vcpu->arch.sie_block->cpuflags)); - trace_kvm_s390_sie_enter(vcpu, - atomic_read(&vcpu->arch.sie_block->cpuflags)); + cpuflags = atomic_read(&vcpu->arch.sie_block->cpuflags); + VCPU_EVENT(vcpu, 6, "entering sie flags %x", cpuflags); + trace_kvm_s390_sie_enter(vcpu, cpuflags); - /* - * As PF_VCPU will be used in fault handler, between guest_enter - * and guest_exit should be no uaccess. - */ - preempt_disable(); - kvm_guest_enter(); - preempt_enable(); - rc = sie64a(vcpu->arch.sie_block, vcpu->run->s.regs.gprs); - kvm_guest_exit(); + return 0; +} + +static int vcpu_post_run(struct kvm_vcpu *vcpu, int exit_reason) +{ + int rc; VCPU_EVENT(vcpu, 6, "exit sie icptcode %d", vcpu->arch.sie_block->icptcode); trace_kvm_s390_sie_exit(vcpu, vcpu->arch.sie_block->icptcode); - if (rc > 0) + if (exit_reason >= 0) { rc = 0; - if (rc < 0) { + } else { if (kvm_is_ucontrol(vcpu->kvm)) { rc = SIE_INTERCEPT_UCONTROL; } else { @@ -741,6 +743,49 @@ static int __vcpu_run(struct kvm_vcpu *vcpu) } memcpy(&vcpu->run->s.regs.gprs[14], &vcpu->arch.sie_block->gg14, 16); + + if (rc == 0) { + if (kvm_is_ucontrol(vcpu->kvm)) + rc = -EOPNOTSUPP; + else + rc = kvm_handle_sie_intercept(vcpu); + } + + return rc; +} + +static int __vcpu_run(struct kvm_vcpu *vcpu) +{ + int rc, exit_reason; + + /* + * We try to hold kvm->srcu during most of vcpu_run (except when run- + * ning the guest), so that memslots (and other stuff) are protected + */ + vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu); + + do { + rc = vcpu_pre_run(vcpu); + if (rc) + break; + + srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx); + /* + * As PF_VCPU will be used in fault handler, between + * guest_enter and guest_exit should be no uaccess. + */ + preempt_disable(); + kvm_guest_enter(); + preempt_enable(); + exit_reason = sie64a(vcpu->arch.sie_block, + vcpu->run->s.regs.gprs); + kvm_guest_exit(); + vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu); + + rc = vcpu_post_run(vcpu, exit_reason); + } while (!signal_pending(current) && !rc); + + srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx); return rc; } @@ -749,7 +794,6 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) int rc; sigset_t sigsaved; -rerun_vcpu: if (vcpu->sigset_active) sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved); @@ -782,19 +826,7 @@ rerun_vcpu: } might_fault(); - - do { - rc = __vcpu_run(vcpu); - if (rc) - break; - if (kvm_is_ucontrol(vcpu->kvm)) - rc = -EOPNOTSUPP; - else - rc = kvm_handle_sie_intercept(vcpu); - } while (!signal_pending(current) && !rc); - - if (rc == SIE_INTERCEPT_RERUNVCPU) - goto rerun_vcpu; + rc = __vcpu_run(vcpu); if (signal_pending(current) && !rc) { kvm_run->exit_reason = KVM_EXIT_INTR; @@ -876,7 +908,8 @@ int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr) * copying in vcpu load/put. Lets update our copies before we save * it into the save area */ - save_fp_regs(&vcpu->arch.guest_fpregs); + save_fp_ctl(&vcpu->arch.guest_fpregs.fpc); + save_fp_regs(vcpu->arch.guest_fpregs.fprs); save_access_regs(vcpu->run->s.regs.acrs); if (__guestcopy(vcpu, addr + offsetof(struct save_area, fp_regs), @@ -951,6 +984,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp, { struct kvm_vcpu *vcpu = filp->private_data; void __user *argp = (void __user *)arg; + int idx; long r; switch (ioctl) { @@ -964,7 +998,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp, break; } case KVM_S390_STORE_STATUS: + idx = srcu_read_lock(&vcpu->kvm->srcu); r = kvm_s390_vcpu_store_status(vcpu, arg); + srcu_read_unlock(&vcpu->kvm->srcu, idx); break; case KVM_S390_SET_INITIAL_PSW: { psw_t psw; @@ -1060,12 +1096,13 @@ int kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf) return VM_FAULT_SIGBUS; } -void kvm_arch_free_memslot(struct kvm_memory_slot *free, +void kvm_arch_free_memslot(struct kvm *kvm, struct kvm_memory_slot *free, struct kvm_memory_slot *dont) { } -int kvm_arch_create_memslot(struct kvm_memory_slot *slot, unsigned long npages) +int kvm_arch_create_memslot(struct kvm *kvm, struct kvm_memory_slot *slot, + unsigned long npages) { return 0; } diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h index dc99f1ca4267..b44912a32949 100644 --- a/arch/s390/kvm/kvm-s390.h +++ b/arch/s390/kvm/kvm-s390.h @@ -28,8 +28,7 @@ typedef int (*intercept_handler_t)(struct kvm_vcpu *vcpu); extern unsigned long *vfacilities; /* negativ values are error codes, positive values for internal conditions */ -#define SIE_INTERCEPT_RERUNVCPU (1<<0) -#define SIE_INTERCEPT_UCONTROL (1<<1) +#define SIE_INTERCEPT_UCONTROL (1<<0) int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu); #define VM_EVENT(d_kvm, d_loglevel, d_string, d_args...)\ @@ -91,8 +90,10 @@ static inline void kvm_s390_get_base_disp_sse(struct kvm_vcpu *vcpu, static inline void kvm_s390_get_regs_rre(struct kvm_vcpu *vcpu, int *r1, int *r2) { - *r1 = (vcpu->arch.sie_block->ipb & 0x00f00000) >> 20; - *r2 = (vcpu->arch.sie_block->ipb & 0x000f0000) >> 16; + if (r1) + *r1 = (vcpu->arch.sie_block->ipb & 0x00f00000) >> 20; + if (r2) + *r2 = (vcpu->arch.sie_block->ipb & 0x000f0000) >> 16; } static inline u64 kvm_s390_get_base_disp_rsy(struct kvm_vcpu *vcpu) diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c index 59200ee275e5..2440602e6df1 100644 --- a/arch/s390/kvm/priv.c +++ b/arch/s390/kvm/priv.c @@ -30,6 +30,38 @@ #include "kvm-s390.h" #include "trace.h" +/* Handle SCK (SET CLOCK) interception */ +static int handle_set_clock(struct kvm_vcpu *vcpu) +{ + struct kvm_vcpu *cpup; + s64 hostclk, val; + u64 op2; + int i; + + if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) + return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); + + op2 = kvm_s390_get_base_disp_s(vcpu); + if (op2 & 7) /* Operand must be on a doubleword boundary */ + return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); + if (get_guest(vcpu, val, (u64 __user *) op2)) + return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); + + if (store_tod_clock(&hostclk)) { + kvm_s390_set_psw_cc(vcpu, 3); + return 0; + } + val = (val - hostclk) & ~0x3fUL; + + mutex_lock(&vcpu->kvm->lock); + kvm_for_each_vcpu(i, cpup, vcpu->kvm) + cpup->arch.sie_block->epoch = val; + mutex_unlock(&vcpu->kvm->lock); + + kvm_s390_set_psw_cc(vcpu, 0); + return 0; +} + static int handle_set_prefix(struct kvm_vcpu *vcpu) { u64 operand2; @@ -128,6 +160,33 @@ static int handle_skey(struct kvm_vcpu *vcpu) return 0; } +static int handle_test_block(struct kvm_vcpu *vcpu) +{ + unsigned long hva; + gpa_t addr; + int reg2; + + if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) + return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); + + kvm_s390_get_regs_rre(vcpu, NULL, ®2); + addr = vcpu->run->s.regs.gprs[reg2] & PAGE_MASK; + addr = kvm_s390_real_to_abs(vcpu, addr); + + hva = gfn_to_hva(vcpu->kvm, gpa_to_gfn(addr)); + if (kvm_is_error_hva(hva)) + return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); + /* + * We don't expect errors on modern systems, and do not care + * about storage keys (yet), so let's just clear the page. + */ + if (clear_user((void __user *)hva, PAGE_SIZE) != 0) + return -EFAULT; + kvm_s390_set_psw_cc(vcpu, 0); + vcpu->run->s.regs.gprs[0] = 0; + return 0; +} + static int handle_tpi(struct kvm_vcpu *vcpu) { struct kvm_s390_interrupt_info *inti; @@ -438,12 +497,14 @@ out_exception: static const intercept_handler_t b2_handlers[256] = { [0x02] = handle_stidp, + [0x04] = handle_set_clock, [0x10] = handle_set_prefix, [0x11] = handle_store_prefix, [0x12] = handle_store_cpu_address, [0x29] = handle_skey, [0x2a] = handle_skey, [0x2b] = handle_skey, + [0x2c] = handle_test_block, [0x30] = handle_io_inst, [0x31] = handle_io_inst, [0x32] = handle_io_inst, diff --git a/arch/s390/kvm/trace.h b/arch/s390/kvm/trace.h index c2f582bb1cb2..0c991c6748ab 100644 --- a/arch/s390/kvm/trace.h +++ b/arch/s390/kvm/trace.h @@ -4,6 +4,7 @@ #include <linux/tracepoint.h> #include <asm/sigp.h> #include <asm/debug.h> +#include <asm/dis.h> #undef TRACE_SYSTEM #define TRACE_SYSTEM kvm diff --git a/arch/s390/lib/Makefile b/arch/s390/lib/Makefile index 20b0e97a7df2..b068729e50ac 100644 --- a/arch/s390/lib/Makefile +++ b/arch/s390/lib/Makefile @@ -2,7 +2,7 @@ # Makefile for s390-specific library files.. # -lib-y += delay.o string.o uaccess_std.o uaccess_pt.o +lib-y += delay.o string.o uaccess_pt.o find.o obj-$(CONFIG_32BIT) += div64.o qrnnd.o ucmpdi2.o mem32.o obj-$(CONFIG_64BIT) += mem64.o lib-$(CONFIG_64BIT) += uaccess_mvcos.o diff --git a/arch/s390/lib/find.c b/arch/s390/lib/find.c new file mode 100644 index 000000000000..620d34d6487e --- /dev/null +++ b/arch/s390/lib/find.c @@ -0,0 +1,77 @@ +/* + * MSB0 numbered special bitops handling. + * + * On s390x the bits are numbered: + * |0..............63|64............127|128...........191|192...........255| + * and on s390: + * |0.....31|31....63|64....95|96...127|128..159|160..191|192..223|224..255| + * + * The reason for this bit numbering is the fact that the hardware sets bits + * in a bitmap starting at bit 0 (MSB) and we don't want to scan the bitmap + * from the 'wrong end'. + */ + +#include <linux/compiler.h> +#include <linux/bitops.h> +#include <linux/export.h> + +unsigned long find_first_bit_inv(const unsigned long *addr, unsigned long size) +{ + const unsigned long *p = addr; + unsigned long result = 0; + unsigned long tmp; + + while (size & ~(BITS_PER_LONG - 1)) { + if ((tmp = *(p++))) + goto found; + result += BITS_PER_LONG; + size -= BITS_PER_LONG; + } + if (!size) + return result; + tmp = (*p) & (~0UL << (BITS_PER_LONG - size)); + if (!tmp) /* Are any bits set? */ + return result + size; /* Nope. */ +found: + return result + (__fls(tmp) ^ (BITS_PER_LONG - 1)); +} +EXPORT_SYMBOL(find_first_bit_inv); + +unsigned long find_next_bit_inv(const unsigned long *addr, unsigned long size, + unsigned long offset) +{ + const unsigned long *p = addr + (offset / BITS_PER_LONG); + unsigned long result = offset & ~(BITS_PER_LONG - 1); + unsigned long tmp; + + if (offset >= size) + return size; + size -= result; + offset %= BITS_PER_LONG; + if (offset) { + tmp = *(p++); + tmp &= (~0UL >> offset); + if (size < BITS_PER_LONG) + goto found_first; + if (tmp) + goto found_middle; + size -= BITS_PER_LONG; + result += BITS_PER_LONG; + } + while (size & ~(BITS_PER_LONG-1)) { + if ((tmp = *(p++))) + goto found_middle; + result += BITS_PER_LONG; + size -= BITS_PER_LONG; + } + if (!size) + return result; + tmp = *p; +found_first: + tmp &= (~0UL << (BITS_PER_LONG - size)); + if (!tmp) /* Are any bits set? */ + return result + size; /* Nope. */ +found_middle: + return result + (__fls(tmp) ^ (BITS_PER_LONG - 1)); +} +EXPORT_SYMBOL(find_next_bit_inv); diff --git a/arch/s390/lib/uaccess_mvcos.c b/arch/s390/lib/uaccess_mvcos.c index 1829742bf479..4b7993bf69b9 100644 --- a/arch/s390/lib/uaccess_mvcos.c +++ b/arch/s390/lib/uaccess_mvcos.c @@ -65,13 +65,6 @@ static size_t copy_from_user_mvcos(size_t size, const void __user *ptr, void *x) return size; } -static size_t copy_from_user_mvcos_check(size_t size, const void __user *ptr, void *x) -{ - if (size <= 256) - return copy_from_user_std(size, ptr, x); - return copy_from_user_mvcos(size, ptr, x); -} - static size_t copy_to_user_mvcos(size_t size, void __user *ptr, const void *x) { register unsigned long reg0 asm("0") = 0x810000UL; @@ -101,14 +94,6 @@ static size_t copy_to_user_mvcos(size_t size, void __user *ptr, const void *x) return size; } -static size_t copy_to_user_mvcos_check(size_t size, void __user *ptr, - const void *x) -{ - if (size <= 256) - return copy_to_user_std(size, ptr, x); - return copy_to_user_mvcos(size, ptr, x); -} - static size_t copy_in_user_mvcos(size_t size, void __user *to, const void __user *from) { @@ -201,23 +186,8 @@ static size_t strncpy_from_user_mvcos(size_t count, const char __user *src, } struct uaccess_ops uaccess_mvcos = { - .copy_from_user = copy_from_user_mvcos_check, - .copy_from_user_small = copy_from_user_std, - .copy_to_user = copy_to_user_mvcos_check, - .copy_to_user_small = copy_to_user_std, - .copy_in_user = copy_in_user_mvcos, - .clear_user = clear_user_mvcos, - .strnlen_user = strnlen_user_std, - .strncpy_from_user = strncpy_from_user_std, - .futex_atomic_op = futex_atomic_op_std, - .futex_atomic_cmpxchg = futex_atomic_cmpxchg_std, -}; - -struct uaccess_ops uaccess_mvcos_switch = { .copy_from_user = copy_from_user_mvcos, - .copy_from_user_small = copy_from_user_mvcos, .copy_to_user = copy_to_user_mvcos, - .copy_to_user_small = copy_to_user_mvcos, .copy_in_user = copy_in_user_mvcos, .clear_user = clear_user_mvcos, .strnlen_user = strnlen_user_mvcos, diff --git a/arch/s390/lib/uaccess_pt.c b/arch/s390/lib/uaccess_pt.c index 1694d738b175..97e03caf7825 100644 --- a/arch/s390/lib/uaccess_pt.c +++ b/arch/s390/lib/uaccess_pt.c @@ -461,9 +461,7 @@ int futex_atomic_cmpxchg_pt(u32 *uval, u32 __user *uaddr, struct uaccess_ops uaccess_pt = { .copy_from_user = copy_from_user_pt, - .copy_from_user_small = copy_from_user_pt, .copy_to_user = copy_to_user_pt, - .copy_to_user_small = copy_to_user_pt, .copy_in_user = copy_in_user_pt, .clear_user = clear_user_pt, .strnlen_user = strnlen_user_pt, diff --git a/arch/s390/lib/uaccess_std.c b/arch/s390/lib/uaccess_std.c deleted file mode 100644 index 4a75d475b06a..000000000000 --- a/arch/s390/lib/uaccess_std.c +++ /dev/null @@ -1,305 +0,0 @@ -/* - * Standard user space access functions based on mvcp/mvcs and doing - * interesting things in the secondary space mode. - * - * Copyright IBM Corp. 2006 - * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), - * Gerald Schaefer (gerald.schaefer@de.ibm.com) - */ - -#include <linux/errno.h> -#include <linux/mm.h> -#include <linux/uaccess.h> -#include <asm/futex.h> -#include "uaccess.h" - -#ifndef CONFIG_64BIT -#define AHI "ahi" -#define ALR "alr" -#define CLR "clr" -#define LHI "lhi" -#define SLR "slr" -#else -#define AHI "aghi" -#define ALR "algr" -#define CLR "clgr" -#define LHI "lghi" -#define SLR "slgr" -#endif - -size_t copy_from_user_std(size_t size, const void __user *ptr, void *x) -{ - unsigned long tmp1, tmp2; - - tmp1 = -256UL; - asm volatile( - "0: mvcp 0(%0,%2),0(%1),%3\n" - "10:jz 8f\n" - "1:"ALR" %0,%3\n" - " la %1,256(%1)\n" - " la %2,256(%2)\n" - "2: mvcp 0(%0,%2),0(%1),%3\n" - "11:jnz 1b\n" - " j 8f\n" - "3: la %4,255(%1)\n" /* %4 = ptr + 255 */ - " "LHI" %3,-4096\n" - " nr %4,%3\n" /* %4 = (ptr + 255) & -4096 */ - " "SLR" %4,%1\n" - " "CLR" %0,%4\n" /* copy crosses next page boundary? */ - " jnh 5f\n" - "4: mvcp 0(%4,%2),0(%1),%3\n" - "12:"SLR" %0,%4\n" - " "ALR" %2,%4\n" - "5:"LHI" %4,-1\n" - " "ALR" %4,%0\n" /* copy remaining size, subtract 1 */ - " bras %3,7f\n" /* memset loop */ - " xc 0(1,%2),0(%2)\n" - "6: xc 0(256,%2),0(%2)\n" - " la %2,256(%2)\n" - "7:"AHI" %4,-256\n" - " jnm 6b\n" - " ex %4,0(%3)\n" - " j 9f\n" - "8:"SLR" %0,%0\n" - "9: \n" - EX_TABLE(0b,3b) EX_TABLE(2b,3b) EX_TABLE(4b,5b) - EX_TABLE(10b,3b) EX_TABLE(11b,3b) EX_TABLE(12b,5b) - : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2) - : : "cc", "memory"); - return size; -} - -static size_t copy_from_user_std_check(size_t size, const void __user *ptr, - void *x) -{ - if (size <= 1024) - return copy_from_user_std(size, ptr, x); - return copy_from_user_pt(size, ptr, x); -} - -size_t copy_to_user_std(size_t size, void __user *ptr, const void *x) -{ - unsigned long tmp1, tmp2; - - tmp1 = -256UL; - asm volatile( - "0: mvcs 0(%0,%1),0(%2),%3\n" - "7: jz 5f\n" - "1:"ALR" %0,%3\n" - " la %1,256(%1)\n" - " la %2,256(%2)\n" - "2: mvcs 0(%0,%1),0(%2),%3\n" - "8: jnz 1b\n" - " j 5f\n" - "3: la %4,255(%1)\n" /* %4 = ptr + 255 */ - " "LHI" %3,-4096\n" - " nr %4,%3\n" /* %4 = (ptr + 255) & -4096 */ - " "SLR" %4,%1\n" - " "CLR" %0,%4\n" /* copy crosses next page boundary? */ - " jnh 6f\n" - "4: mvcs 0(%4,%1),0(%2),%3\n" - "9:"SLR" %0,%4\n" - " j 6f\n" - "5:"SLR" %0,%0\n" - "6: \n" - EX_TABLE(0b,3b) EX_TABLE(2b,3b) EX_TABLE(4b,6b) - EX_TABLE(7b,3b) EX_TABLE(8b,3b) EX_TABLE(9b,6b) - : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2) - : : "cc", "memory"); - return size; -} - -static size_t copy_to_user_std_check(size_t size, void __user *ptr, - const void *x) -{ - if (size <= 1024) - return copy_to_user_std(size, ptr, x); - return copy_to_user_pt(size, ptr, x); -} - -static size_t copy_in_user_std(size_t size, void __user *to, - const void __user *from) -{ - unsigned long tmp1; - - asm volatile( - " sacf 256\n" - " "AHI" %0,-1\n" - " jo 5f\n" - " bras %3,3f\n" - "0:"AHI" %0,257\n" - "1: mvc 0(1,%1),0(%2)\n" - " la %1,1(%1)\n" - " la %2,1(%2)\n" - " "AHI" %0,-1\n" - " jnz 1b\n" - " j 5f\n" - "2: mvc 0(256,%1),0(%2)\n" - " la %1,256(%1)\n" - " la %2,256(%2)\n" - "3:"AHI" %0,-256\n" - " jnm 2b\n" - "4: ex %0,1b-0b(%3)\n" - "5: "SLR" %0,%0\n" - "6: sacf 0\n" - EX_TABLE(1b,6b) EX_TABLE(2b,0b) EX_TABLE(4b,0b) - : "+a" (size), "+a" (to), "+a" (from), "=a" (tmp1) - : : "cc", "memory"); - return size; -} - -static size_t clear_user_std(size_t size, void __user *to) -{ - unsigned long tmp1, tmp2; - - asm volatile( - " sacf 256\n" - " "AHI" %0,-1\n" - " jo 5f\n" - " bras %3,3f\n" - " xc 0(1,%1),0(%1)\n" - "0:"AHI" %0,257\n" - " la %2,255(%1)\n" /* %2 = ptr + 255 */ - " srl %2,12\n" - " sll %2,12\n" /* %2 = (ptr + 255) & -4096 */ - " "SLR" %2,%1\n" - " "CLR" %0,%2\n" /* clear crosses next page boundary? */ - " jnh 5f\n" - " "AHI" %2,-1\n" - "1: ex %2,0(%3)\n" - " "AHI" %2,1\n" - " "SLR" %0,%2\n" - " j 5f\n" - "2: xc 0(256,%1),0(%1)\n" - " la %1,256(%1)\n" - "3:"AHI" %0,-256\n" - " jnm 2b\n" - "4: ex %0,0(%3)\n" - "5: "SLR" %0,%0\n" - "6: sacf 0\n" - EX_TABLE(1b,6b) EX_TABLE(2b,0b) EX_TABLE(4b,0b) - : "+a" (size), "+a" (to), "=a" (tmp1), "=a" (tmp2) - : : "cc", "memory"); - return size; -} - -size_t strnlen_user_std(size_t size, const char __user *src) -{ - register unsigned long reg0 asm("0") = 0UL; - unsigned long tmp1, tmp2; - - if (unlikely(!size)) - return 0; - asm volatile( - " la %2,0(%1)\n" - " la %3,0(%0,%1)\n" - " "SLR" %0,%0\n" - " sacf 256\n" - "0: srst %3,%2\n" - " jo 0b\n" - " la %0,1(%3)\n" /* strnlen_user results includes \0 */ - " "SLR" %0,%1\n" - "1: sacf 0\n" - EX_TABLE(0b,1b) - : "+a" (size), "+a" (src), "=a" (tmp1), "=a" (tmp2) - : "d" (reg0) : "cc", "memory"); - return size; -} - -size_t strncpy_from_user_std(size_t count, const char __user *src, char *dst) -{ - size_t done, len, offset, len_str; - - if (unlikely(!count)) - return 0; - done = 0; - do { - offset = (size_t)src & ~PAGE_MASK; - len = min(count - done, PAGE_SIZE - offset); - if (copy_from_user_std(len, src, dst)) - return -EFAULT; - len_str = strnlen(dst, len); - done += len_str; - src += len_str; - dst += len_str; - } while ((len_str == len) && (done < count)); - return done; -} - -#define __futex_atomic_op(insn, ret, oldval, newval, uaddr, oparg) \ - asm volatile( \ - " sacf 256\n" \ - "0: l %1,0(%6)\n" \ - "1:"insn \ - "2: cs %1,%2,0(%6)\n" \ - "3: jl 1b\n" \ - " lhi %0,0\n" \ - "4: sacf 0\n" \ - EX_TABLE(0b,4b) EX_TABLE(2b,4b) EX_TABLE(3b,4b) \ - : "=d" (ret), "=&d" (oldval), "=&d" (newval), \ - "=m" (*uaddr) \ - : "0" (-EFAULT), "d" (oparg), "a" (uaddr), \ - "m" (*uaddr) : "cc"); - -int futex_atomic_op_std(int op, u32 __user *uaddr, int oparg, int *old) -{ - int oldval = 0, newval, ret; - - switch (op) { - case FUTEX_OP_SET: - __futex_atomic_op("lr %2,%5\n", - ret, oldval, newval, uaddr, oparg); - break; - case FUTEX_OP_ADD: - __futex_atomic_op("lr %2,%1\nar %2,%5\n", - ret, oldval, newval, uaddr, oparg); - break; - case FUTEX_OP_OR: - __futex_atomic_op("lr %2,%1\nor %2,%5\n", - ret, oldval, newval, uaddr, oparg); - break; - case FUTEX_OP_ANDN: - __futex_atomic_op("lr %2,%1\nnr %2,%5\n", - ret, oldval, newval, uaddr, oparg); - break; - case FUTEX_OP_XOR: - __futex_atomic_op("lr %2,%1\nxr %2,%5\n", - ret, oldval, newval, uaddr, oparg); - break; - default: - ret = -ENOSYS; - } - *old = oldval; - return ret; -} - -int futex_atomic_cmpxchg_std(u32 *uval, u32 __user *uaddr, - u32 oldval, u32 newval) -{ - int ret; - - asm volatile( - " sacf 256\n" - "0: cs %1,%4,0(%5)\n" - "1: la %0,0\n" - "2: sacf 0\n" - EX_TABLE(0b,2b) EX_TABLE(1b,2b) - : "=d" (ret), "+d" (oldval), "=m" (*uaddr) - : "0" (-EFAULT), "d" (newval), "a" (uaddr), "m" (*uaddr) - : "cc", "memory" ); - *uval = oldval; - return ret; -} - -struct uaccess_ops uaccess_std = { - .copy_from_user = copy_from_user_std_check, - .copy_from_user_small = copy_from_user_std, - .copy_to_user = copy_to_user_std_check, - .copy_to_user_small = copy_to_user_std, - .copy_in_user = copy_in_user_std, - .clear_user = clear_user_std, - .strnlen_user = strnlen_user_std, - .strncpy_from_user = strncpy_from_user_std, - .futex_atomic_op = futex_atomic_op_std, - .futex_atomic_cmpxchg = futex_atomic_cmpxchg_std, -}; diff --git a/arch/s390/math-emu/math.c b/arch/s390/math-emu/math.c index 58bff541fde9..a6ba0d724335 100644 --- a/arch/s390/math-emu/math.c +++ b/arch/s390/math-emu/math.c @@ -19,6 +19,8 @@ #include <math-emu/double.h> #include <math-emu/quad.h> +#define FPC_VALID_MASK 0xF8F8FF03 + /* * I miss a macro to round a floating point number to the * nearest integer in the same floating point format. diff --git a/arch/s390/mm/cmm.c b/arch/s390/mm/cmm.c index 9d84a1feefef..79ddd580d605 100644 --- a/arch/s390/mm/cmm.c +++ b/arch/s390/mm/cmm.c @@ -253,12 +253,12 @@ static int cmm_skip_blanks(char *cp, char **endp) static struct ctl_table cmm_table[]; -static int cmm_pages_handler(ctl_table *ctl, int write, void __user *buffer, - size_t *lenp, loff_t *ppos) +static int cmm_pages_handler(struct ctl_table *ctl, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) { char buf[16], *p; + unsigned int len; long nr; - int len; if (!*lenp || (*ppos && !write)) { *lenp = 0; @@ -293,12 +293,12 @@ static int cmm_pages_handler(ctl_table *ctl, int write, void __user *buffer, return 0; } -static int cmm_timeout_handler(ctl_table *ctl, int write, void __user *buffer, - size_t *lenp, loff_t *ppos) +static int cmm_timeout_handler(struct ctl_table *ctl, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) { char buf[64], *p; long nr, seconds; - int len; + unsigned int len; if (!*lenp || (*ppos && !write)) { *lenp = 0; diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index fc6679210d83..d95265b2719f 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -115,13 +115,8 @@ static inline int user_space_fault(unsigned long trans_exc_code) if (trans_exc_code == 2) /* Access via secondary space, set_fs setting decides */ return current->thread.mm_segment.ar4; - if (s390_user_mode == HOME_SPACE_MODE) - /* User space if the access has been done via home space. */ - return trans_exc_code == 3; /* - * If the user space is not the home space the kernel runs in home - * space. Access via secondary space has already been covered, - * access via primary space or access register is from user space + * Access via primary space or access register is from user space * and access via home space is from the kernel. */ return trans_exc_code != 3; @@ -428,50 +423,13 @@ void __kprobes do_dat_exception(struct pt_regs *regs) do_fault_error(regs, fault); } -#ifdef CONFIG_64BIT -void __kprobes do_asce_exception(struct pt_regs *regs) -{ - struct mm_struct *mm = current->mm; - struct vm_area_struct *vma; - unsigned long trans_exc_code; - - /* - * The instruction that caused the program check has - * been nullified. Don't signal single step via SIGTRAP. - */ - clear_tsk_thread_flag(current, TIF_PER_TRAP); - - trans_exc_code = regs->int_parm_long; - if (unlikely(!user_space_fault(trans_exc_code) || in_atomic() || !mm)) - goto no_context; - - down_read(&mm->mmap_sem); - vma = find_vma(mm, trans_exc_code & __FAIL_ADDR_MASK); - up_read(&mm->mmap_sem); - - if (vma) { - update_mm(mm, current); - return; - } - - /* User mode accesses just cause a SIGSEGV */ - if (user_mode(regs)) { - do_sigsegv(regs, SEGV_MAPERR); - return; - } - -no_context: - do_no_context(regs); -} -#endif - int __handle_fault(unsigned long uaddr, unsigned long pgm_int_code, int write) { struct pt_regs regs; int access, fault; /* Emulate a uaccess fault from kernel mode. */ - regs.psw.mask = psw_kernel_bits | PSW_MASK_DAT | PSW_MASK_MCHECK; + regs.psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT | PSW_MASK_MCHECK; if (!irqs_disabled()) regs.psw.mask |= PSW_MASK_IO | PSW_MASK_EXT; regs.psw.addr = (unsigned long) __builtin_return_address(0); diff --git a/arch/s390/mm/gup.c b/arch/s390/mm/gup.c index 5d758db27bdc..639fce464008 100644 --- a/arch/s390/mm/gup.c +++ b/arch/s390/mm/gup.c @@ -180,9 +180,15 @@ int __get_user_pages_fast(unsigned long start, int nr_pages, int write, addr = start; len = (unsigned long) nr_pages << PAGE_SHIFT; end = start + len; - if ((end < start) || (end > TASK_SIZE)) + if ((end <= start) || (end > TASK_SIZE)) return 0; - + /* + * local_irq_save() doesn't prevent pagetable teardown, but does + * prevent the pagetables from being freed on s390. + * + * So long as we atomically load page table pointers versus teardown, + * we can follow the address down to the the page and take a ref on it. + */ local_irq_save(flags); pgdp = pgd_offset(mm, addr); do { @@ -219,63 +225,22 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write, struct page **pages) { struct mm_struct *mm = current->mm; - unsigned long addr, len, end; - unsigned long next; - pgd_t *pgdp, pgd; - int nr = 0; + int nr, ret; start &= PAGE_MASK; - addr = start; - len = (unsigned long) nr_pages << PAGE_SHIFT; - end = start + len; - if ((end < start) || (end > TASK_SIZE)) - goto slow_irqon; - - /* - * local_irq_disable() doesn't prevent pagetable teardown, but does - * prevent the pagetables from being freed on s390. - * - * So long as we atomically load page table pointers versus teardown, - * we can follow the address down to the the page and take a ref on it. - */ - local_irq_disable(); - pgdp = pgd_offset(mm, addr); - do { - pgd = *pgdp; - barrier(); - next = pgd_addr_end(addr, end); - if (pgd_none(pgd)) - goto slow; - if (!gup_pud_range(pgdp, pgd, addr, next, write, pages, &nr)) - goto slow; - } while (pgdp++, addr = next, addr != end); - local_irq_enable(); - - VM_BUG_ON(nr != (end - start) >> PAGE_SHIFT); - return nr; - - { - int ret; -slow: - local_irq_enable(); -slow_irqon: - /* Try to get the remaining pages with get_user_pages */ - start += nr << PAGE_SHIFT; - pages += nr; - - down_read(&mm->mmap_sem); - ret = get_user_pages(current, mm, start, - (end - start) >> PAGE_SHIFT, write, 0, pages, NULL); - up_read(&mm->mmap_sem); - - /* Have to be a bit careful with return values */ - if (nr > 0) { - if (ret < 0) - ret = nr; - else - ret += nr; - } - - return ret; - } + nr = __get_user_pages_fast(start, nr_pages, write, pages); + if (nr == nr_pages) + return nr; + + /* Try to get the remaining pages with get_user_pages */ + start += nr << PAGE_SHIFT; + pages += nr; + down_read(&mm->mmap_sem); + ret = get_user_pages(current, mm, start, + nr_pages - nr, write, 0, pages, NULL); + up_read(&mm->mmap_sem); + /* Have to be a bit careful with return values */ + if (nr > 0) + ret = (ret < 0) ? nr : ret + nr; + return ret; } diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c index 40023290ee5b..9b436c21195e 100644 --- a/arch/s390/mm/mmap.c +++ b/arch/s390/mm/mmap.c @@ -64,6 +64,11 @@ static unsigned long mmap_rnd(void) return (get_random_int() & 0x7ffUL) << PAGE_SHIFT; } +static unsigned long mmap_base_legacy(void) +{ + return TASK_UNMAPPED_BASE + mmap_rnd(); +} + static inline unsigned long mmap_base(void) { unsigned long gap = rlimit(RLIMIT_STACK); @@ -89,7 +94,7 @@ void arch_pick_mmap_layout(struct mm_struct *mm) * bit is set, or if the expected stack growth is unlimited: */ if (mmap_is_legacy()) { - mm->mmap_base = TASK_UNMAPPED_BASE; + mm->mmap_base = mmap_base_legacy(); mm->get_unmapped_area = arch_get_unmapped_area; } else { mm->mmap_base = mmap_base(); @@ -101,18 +106,12 @@ void arch_pick_mmap_layout(struct mm_struct *mm) int s390_mmap_check(unsigned long addr, unsigned long len, unsigned long flags) { - int rc; - if (is_compat_task() || (TASK_SIZE >= (1UL << 53))) return 0; if (!(flags & MAP_FIXED)) addr = 0; - if ((addr + len) >= TASK_SIZE) { - rc = crst_table_upgrade(current->mm, 1UL << 53); - if (rc) - return rc; - update_mm(current->mm, current); - } + if ((addr + len) >= TASK_SIZE) + return crst_table_upgrade(current->mm, 1UL << 53); return 0; } @@ -132,7 +131,6 @@ s390_get_unmapped_area(struct file *filp, unsigned long addr, rc = crst_table_upgrade(mm, 1UL << 53); if (rc) return (unsigned long) rc; - update_mm(mm, current); area = arch_get_unmapped_area(filp, addr, len, pgoff, flags); } return area; @@ -155,7 +153,6 @@ s390_get_unmapped_area_topdown(struct file *filp, const unsigned long addr, rc = crst_table_upgrade(mm, 1UL << 53); if (rc) return (unsigned long) rc; - update_mm(mm, current); area = arch_get_unmapped_area_topdown(filp, addr, len, pgoff, flags); } @@ -172,7 +169,7 @@ void arch_pick_mmap_layout(struct mm_struct *mm) * bit is set, or if the expected stack growth is unlimited: */ if (mmap_is_legacy()) { - mm->mmap_base = TASK_UNMAPPED_BASE; + mm->mmap_base = mmap_base_legacy(); mm->get_unmapped_area = s390_get_unmapped_area; } else { mm->mmap_base = mmap_base(); diff --git a/arch/s390/mm/pageattr.c b/arch/s390/mm/pageattr.c index 990397420e6b..8400f494623f 100644 --- a/arch/s390/mm/pageattr.c +++ b/arch/s390/mm/pageattr.c @@ -9,6 +9,7 @@ #include <asm/pgtable.h> #include <asm/page.h> +#if PAGE_DEFAULT_KEY static inline unsigned long sske_frame(unsigned long addr, unsigned char skey) { asm volatile(".insn rrf,0xb22b0000,%[skey],%[addr],9,0" @@ -16,7 +17,7 @@ static inline unsigned long sske_frame(unsigned long addr, unsigned char skey) return addr; } -void storage_key_init_range(unsigned long start, unsigned long end) +void __storage_key_init_range(unsigned long start, unsigned long end) { unsigned long boundary, size; @@ -36,6 +37,7 @@ void storage_key_init_range(unsigned long start, unsigned long end) start += PAGE_SIZE; } } +#endif static pte_t *walk_page_table(unsigned long addr) { diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index de8cbc30dcd1..e794c88f699a 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c @@ -48,12 +48,23 @@ void crst_table_free(struct mm_struct *mm, unsigned long *table) } #ifdef CONFIG_64BIT +static void __crst_table_upgrade(void *arg) +{ + struct mm_struct *mm = arg; + + if (current->active_mm == mm) + update_mm(mm, current); + __tlb_flush_local(); +} + int crst_table_upgrade(struct mm_struct *mm, unsigned long limit) { unsigned long *table, *pgd; unsigned long entry; + int flush; BUG_ON(limit > (1UL << 53)); + flush = 0; repeat: table = crst_table_alloc(mm); if (!table) @@ -79,12 +90,15 @@ repeat: mm->pgd = (pgd_t *) table; mm->task_size = mm->context.asce_limit; table = NULL; + flush = 1; } spin_unlock_bh(&mm->page_table_lock); if (table) crst_table_free(mm, table); if (mm->context.asce_limit < limit) goto repeat; + if (flush) + on_each_cpu(__crst_table_upgrade, mm, 0); return 0; } @@ -92,6 +106,8 @@ void crst_table_downgrade(struct mm_struct *mm, unsigned long limit) { pgd_t *pgd; + if (current->active_mm == mm) + __tlb_flush_mm(mm); while (mm->context.asce_limit > limit) { pgd = mm->pgd; switch (pgd_val(*pgd) & _REGION_ENTRY_TYPE_MASK) { @@ -114,6 +130,8 @@ void crst_table_downgrade(struct mm_struct *mm, unsigned long limit) mm->task_size = mm->context.asce_limit; crst_table_free(mm, (unsigned long *) pgd); } + if (current->active_mm == mm) + update_mm(mm, current); } #endif @@ -754,7 +772,11 @@ static inline unsigned long *page_table_alloc_pgste(struct mm_struct *mm, __free_page(page); return NULL; } - pgtable_page_ctor(page); + if (!pgtable_page_ctor(page)) { + kfree(mp); + __free_page(page); + return NULL; + } mp->vmaddr = vmaddr & PMD_MASK; INIT_LIST_HEAD(&mp->mapper); page->index = (unsigned long) mp; @@ -884,7 +906,10 @@ unsigned long *page_table_alloc(struct mm_struct *mm, unsigned long vmaddr) page = alloc_page(GFP_KERNEL|__GFP_REPEAT); if (!page) return NULL; - pgtable_page_ctor(page); + if (!pgtable_page_ctor(page)) { + __free_page(page); + return NULL; + } atomic_set(&page->_mapcount, 1); table = (unsigned long *) page_to_phys(page); clear_table(table, _PAGE_INVALID, PAGE_SIZE); @@ -1087,10 +1112,9 @@ again: continue; /* Allocate new page table with pgstes */ new = page_table_alloc_pgste(mm, addr); - if (!new) { - mm->context.has_pgste = 0; - continue; - } + if (!new) + return -ENOMEM; + spin_lock(&mm->page_table_lock); if (likely((unsigned long *) pmd_deref(*pmd) == table)) { /* Nuke pmd entry pointing to the "short" page table */ @@ -1128,13 +1152,15 @@ static unsigned long page_table_realloc_pud(struct mmu_gather *tlb, if (pud_none_or_clear_bad(pud)) continue; next = page_table_realloc_pmd(tlb, mm, pud, addr, next); + if (unlikely(IS_ERR_VALUE(next))) + return next; } while (pud++, addr = next, addr != end); return addr; } -static void page_table_realloc(struct mmu_gather *tlb, struct mm_struct *mm, - unsigned long addr, unsigned long end) +static unsigned long page_table_realloc(struct mmu_gather *tlb, struct mm_struct *mm, + unsigned long addr, unsigned long end) { unsigned long next; pgd_t *pgd; @@ -1145,7 +1171,11 @@ static void page_table_realloc(struct mmu_gather *tlb, struct mm_struct *mm, if (pgd_none_or_clear_bad(pgd)) continue; next = page_table_realloc_pud(tlb, mm, pgd, addr, next); + if (unlikely(IS_ERR_VALUE(next))) + return next; } while (pgd++, addr = next, addr != end); + + return 0; } /* @@ -1157,10 +1187,6 @@ int s390_enable_sie(void) struct mm_struct *mm = tsk->mm; struct mmu_gather tlb; - /* Do we have switched amode? If no, we cannot do sie */ - if (s390_user_mode == HOME_SPACE_MODE) - return -EINVAL; - /* Do we have pgstes? if yes, we are done */ if (mm_has_pgste(tsk->mm)) return 0; @@ -1169,9 +1195,9 @@ int s390_enable_sie(void) /* split thp mappings and disable thp for future mappings */ thp_split_mm(mm); /* Reallocate the page tables with pgstes */ - mm->context.has_pgste = 1; tlb_gather_mmu(&tlb, mm, 0, TASK_SIZE); - page_table_realloc(&tlb, mm, 0, TASK_SIZE); + if (!page_table_realloc(&tlb, mm, 0, TASK_SIZE)) + mm->context.has_pgste = 1; tlb_finish_mmu(&tlb, 0, TASK_SIZE); up_write(&mm->mmap_sem); return mm->context.has_pgste ? 0 : -ENOMEM; @@ -1225,11 +1251,11 @@ void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp, assert_spin_locked(&mm->page_table_lock); /* FIFO */ - if (!mm->pmd_huge_pte) + if (!pmd_huge_pte(mm, pmdp)) INIT_LIST_HEAD(lh); else - list_add(lh, (struct list_head *) mm->pmd_huge_pte); - mm->pmd_huge_pte = pgtable; + list_add(lh, (struct list_head *) pmd_huge_pte(mm, pmdp)); + pmd_huge_pte(mm, pmdp) = pgtable; } pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp) @@ -1241,12 +1267,12 @@ pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp) assert_spin_locked(&mm->page_table_lock); /* FIFO */ - pgtable = mm->pmd_huge_pte; + pgtable = pmd_huge_pte(mm, pmdp); lh = (struct list_head *) pgtable; if (list_empty(lh)) - mm->pmd_huge_pte = NULL; + pmd_huge_pte(mm, pmdp) = NULL; else { - mm->pmd_huge_pte = (pgtable_t) lh->next; + pmd_huge_pte(mm, pmdp) = (pgtable_t) lh->next; list_del(lh); } ptep = (pte_t *) pgtable; diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c index a5df511e27a2..16871da37371 100644 --- a/arch/s390/net/bpf_jit_comp.c +++ b/arch/s390/net/bpf_jit_comp.c @@ -12,8 +12,8 @@ #include <linux/random.h> #include <linux/init.h> #include <asm/cacheflush.h> -#include <asm/processor.h> #include <asm/facility.h> +#include <asm/dis.h> /* * Conventions: @@ -156,8 +156,8 @@ static void bpf_jit_prologue(struct bpf_jit *jit) EMIT6(0xeb8ff058, 0x0024); /* lgr %r14,%r15 */ EMIT4(0xb90400ef); - /* ahi %r15,<offset> */ - EMIT4_IMM(0xa7fa0000, (jit->seen & SEEN_MEM) ? -112 : -80); + /* aghi %r15,<offset> */ + EMIT4_IMM(0xa7fb0000, (jit->seen & SEEN_MEM) ? -112 : -80); /* stg %r14,152(%r15) */ EMIT6(0xe3e0f098, 0x0024); } else if ((jit->seen & SEEN_XREG) && (jit->seen & SEEN_LITERAL)) diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index f17a8343e360..bf7c73d71eef 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c @@ -120,26 +120,17 @@ EXPORT_SYMBOL_GPL(pci_proc_domain); static int zpci_set_airq(struct zpci_dev *zdev) { u64 req = ZPCI_CREATE_REQ(zdev->fh, 0, ZPCI_MOD_FC_REG_INT); - struct zpci_fib *fib; - int rc; - - fib = (void *) get_zeroed_page(GFP_KERNEL); - if (!fib) - return -ENOMEM; + struct zpci_fib fib = {0}; - fib->isc = PCI_ISC; - fib->sum = 1; /* enable summary notifications */ - fib->noi = airq_iv_end(zdev->aibv); - fib->aibv = (unsigned long) zdev->aibv->vector; - fib->aibvo = 0; /* each zdev has its own interrupt vector */ - fib->aisb = (unsigned long) zpci_aisb_iv->vector + (zdev->aisb/64)*8; - fib->aisbo = zdev->aisb & 63; + fib.isc = PCI_ISC; + fib.sum = 1; /* enable summary notifications */ + fib.noi = airq_iv_end(zdev->aibv); + fib.aibv = (unsigned long) zdev->aibv->vector; + fib.aibvo = 0; /* each zdev has its own interrupt vector */ + fib.aisb = (unsigned long) zpci_aisb_iv->vector + (zdev->aisb/64)*8; + fib.aisbo = zdev->aisb & 63; - rc = zpci_mod_fc(req, fib); - pr_debug("%s mpcifc returned noi: %d\n", __func__, fib->noi); - - free_page((unsigned long) fib); - return rc; + return zpci_mod_fc(req, &fib); } struct mod_pci_args { @@ -152,22 +143,14 @@ struct mod_pci_args { static int mod_pci(struct zpci_dev *zdev, int fn, u8 dmaas, struct mod_pci_args *args) { u64 req = ZPCI_CREATE_REQ(zdev->fh, dmaas, fn); - struct zpci_fib *fib; - int rc; - - /* The FIB must be available even if it's not used */ - fib = (void *) get_zeroed_page(GFP_KERNEL); - if (!fib) - return -ENOMEM; + struct zpci_fib fib = {0}; - fib->pba = args->base; - fib->pal = args->limit; - fib->iota = args->iota; - fib->fmb_addr = args->fmb_addr; + fib.pba = args->base; + fib.pal = args->limit; + fib.iota = args->iota; + fib.fmb_addr = args->fmb_addr; - rc = zpci_mod_fc(req, fib); - free_page((unsigned long) fib); - return rc; + return zpci_mod_fc(req, &fib); } /* Modify PCI: Register I/O address translation parameters */ @@ -424,7 +407,6 @@ int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) struct msi_msg msg; int rc; - pr_debug("%s: requesting %d MSI-X interrupts...", __func__, nvec); if (type != PCI_CAP_ID_MSIX && type != PCI_CAP_ID_MSI) return -EINVAL; msi_vecs = min(nvec, ZPCI_MSI_VEC_MAX); @@ -489,7 +471,6 @@ out_msi: out_si: airq_iv_free_bit(zpci_aisb_iv, aisb); out: - dev_err(&pdev->dev, "register MSI failed with: %d\n", rc); return rc; } @@ -499,14 +480,10 @@ void arch_teardown_msi_irqs(struct pci_dev *pdev) struct msi_desc *msi; int rc; - pr_info("%s: on pdev: %p\n", __func__, pdev); - /* Disable adapter interrupts */ rc = zpci_clear_airq(zdev); - if (rc) { - dev_err(&pdev->dev, "deregister MSI failed with: %d\n", rc); + if (rc) return; - } /* Release MSI interrupts */ list_for_each_entry(msi, &pdev->msi_list, list) { @@ -553,20 +530,6 @@ static void zpci_unmap_resources(struct zpci_dev *zdev) } } -struct zpci_dev *zpci_alloc_device(void) -{ - struct zpci_dev *zdev; - - /* Alloc memory for our private pci device data */ - zdev = kzalloc(sizeof(*zdev), GFP_KERNEL); - return zdev ? : ERR_PTR(-ENOMEM); -} - -void zpci_free_device(struct zpci_dev *zdev) -{ - kfree(zdev); -} - int pcibios_add_platform_entries(struct pci_dev *pdev) { return zpci_sysfs_add_device(&pdev->dev); @@ -602,34 +565,6 @@ static void zpci_irq_exit(void) unregister_adapter_interrupt(&zpci_airq); } -static struct resource *zpci_alloc_bus_resource(unsigned long start, unsigned long size, - unsigned long flags, int domain) -{ - struct resource *r; - char *name; - int rc; - - r = kzalloc(sizeof(*r), GFP_KERNEL); - if (!r) - return ERR_PTR(-ENOMEM); - r->start = start; - r->end = r->start + size - 1; - r->flags = flags; - r->parent = &iomem_resource; - name = kmalloc(18, GFP_KERNEL); - if (!name) { - kfree(r); - return ERR_PTR(-ENOMEM); - } - sprintf(name, "PCI Bus: %04x:%02x", domain, ZPCI_BUS_NR); - r->name = name; - - rc = request_resource(&iomem_resource, r); - if (rc) - pr_debug("request resource %pR failed\n", r); - return r; -} - static int zpci_alloc_iomap(struct zpci_dev *zdev) { int entry; @@ -653,6 +588,82 @@ static void zpci_free_iomap(struct zpci_dev *zdev, int entry) spin_unlock(&zpci_iomap_lock); } +static struct resource *__alloc_res(struct zpci_dev *zdev, unsigned long start, + unsigned long size, unsigned long flags) +{ + struct resource *r; + + r = kzalloc(sizeof(*r), GFP_KERNEL); + if (!r) + return NULL; + + r->start = start; + r->end = r->start + size - 1; + r->flags = flags; + r->name = zdev->res_name; + + if (request_resource(&iomem_resource, r)) { + kfree(r); + return NULL; + } + return r; +} + +static int zpci_setup_bus_resources(struct zpci_dev *zdev, + struct list_head *resources) +{ + unsigned long addr, size, flags; + struct resource *res; + int i, entry; + + snprintf(zdev->res_name, sizeof(zdev->res_name), + "PCI Bus %04x:%02x", zdev->domain, ZPCI_BUS_NR); + + for (i = 0; i < PCI_BAR_COUNT; i++) { + if (!zdev->bars[i].size) + continue; + entry = zpci_alloc_iomap(zdev); + if (entry < 0) + return entry; + zdev->bars[i].map_idx = entry; + + /* only MMIO is supported */ + flags = IORESOURCE_MEM; + if (zdev->bars[i].val & 8) + flags |= IORESOURCE_PREFETCH; + if (zdev->bars[i].val & 4) + flags |= IORESOURCE_MEM_64; + + addr = ZPCI_IOMAP_ADDR_BASE + ((u64) entry << 48); + + size = 1UL << zdev->bars[i].size; + + res = __alloc_res(zdev, addr, size, flags); + if (!res) { + zpci_free_iomap(zdev, entry); + return -ENOMEM; + } + zdev->bars[i].res = res; + pci_add_resource(resources, res); + } + + return 0; +} + +static void zpci_cleanup_bus_resources(struct zpci_dev *zdev) +{ + int i; + + for (i = 0; i < PCI_BAR_COUNT; i++) { + if (!zdev->bars[i].size) + continue; + + zpci_free_iomap(zdev, zdev->bars[i].map_idx); + release_resource(zdev->bars[i].res); + kfree(zdev->bars[i].res); + } +} + int pcibios_add_device(struct pci_dev *pdev) { struct zpci_dev *zdev = get_zdev(pdev); @@ -708,52 +719,47 @@ void pcibios_disable_device(struct pci_dev *pdev) zdev->pdev = NULL; } -static int zpci_scan_bus(struct zpci_dev *zdev) +#ifdef CONFIG_HIBERNATE_CALLBACKS +static int zpci_restore(struct device *dev) { - struct resource *res; - LIST_HEAD(resources); - int i; + struct zpci_dev *zdev = get_zdev(to_pci_dev(dev)); + int ret = 0; - /* allocate mapping entry for each used bar */ - for (i = 0; i < PCI_BAR_COUNT; i++) { - unsigned long addr, size, flags; - int entry; - - if (!zdev->bars[i].size) - continue; - entry = zpci_alloc_iomap(zdev); - if (entry < 0) - return entry; - zdev->bars[i].map_idx = entry; + if (zdev->state != ZPCI_FN_STATE_ONLINE) + goto out; - /* only MMIO is supported */ - flags = IORESOURCE_MEM; - if (zdev->bars[i].val & 8) - flags |= IORESOURCE_PREFETCH; - if (zdev->bars[i].val & 4) - flags |= IORESOURCE_MEM_64; + ret = clp_enable_fh(zdev, ZPCI_NR_DMA_SPACES); + if (ret) + goto out; - addr = ZPCI_IOMAP_ADDR_BASE + ((u64) entry << 48); + zpci_map_resources(zdev); + zpci_register_ioat(zdev, 0, zdev->start_dma + PAGE_OFFSET, + zdev->start_dma + zdev->iommu_size - 1, + (u64) zdev->dma_table); - size = 1UL << zdev->bars[i].size; +out: + return ret; +} - res = zpci_alloc_bus_resource(addr, size, flags, zdev->domain); - if (IS_ERR(res)) { - zpci_free_iomap(zdev, entry); - return PTR_ERR(res); - } - pci_add_resource(&resources, res); - } +static int zpci_freeze(struct device *dev) +{ + struct zpci_dev *zdev = get_zdev(to_pci_dev(dev)); - zdev->bus = pci_scan_root_bus(NULL, ZPCI_BUS_NR, &pci_root_ops, - zdev, &resources); - if (!zdev->bus) - return -EIO; + if (zdev->state != ZPCI_FN_STATE_ONLINE) + return 0; - zdev->bus->max_bus_speed = zdev->max_bus_speed; - return 0; + zpci_unregister_ioat(zdev, 0); + return clp_disable_fh(zdev); } +struct dev_pm_ops pcibios_pm_ops = { + .thaw_noirq = zpci_restore, + .freeze_noirq = zpci_freeze, + .restore_noirq = zpci_restore, + .poweroff_noirq = zpci_freeze, +}; +#endif /* CONFIG_HIBERNATE_CALLBACKS */ + static int zpci_alloc_domain(struct zpci_dev *zdev) { spin_lock(&zpci_domain_lock); @@ -774,6 +780,41 @@ static void zpci_free_domain(struct zpci_dev *zdev) spin_unlock(&zpci_domain_lock); } +void pcibios_remove_bus(struct pci_bus *bus) +{ + struct zpci_dev *zdev = get_zdev_by_bus(bus); + + zpci_exit_slot(zdev); + zpci_cleanup_bus_resources(zdev); + zpci_free_domain(zdev); + + spin_lock(&zpci_list_lock); + list_del(&zdev->entry); + spin_unlock(&zpci_list_lock); + + kfree(zdev); +} + +static int zpci_scan_bus(struct zpci_dev *zdev) +{ + LIST_HEAD(resources); + int ret; + + ret = zpci_setup_bus_resources(zdev, &resources); + if (ret) + return ret; + + zdev->bus = pci_scan_root_bus(NULL, ZPCI_BUS_NR, &pci_root_ops, + zdev, &resources); + if (!zdev->bus) { + zpci_cleanup_bus_resources(zdev); + return -EIO; + } + + zdev->bus->max_bus_speed = zdev->max_bus_speed; + return 0; +} + int zpci_enable_device(struct zpci_dev *zdev) { int rc; @@ -781,7 +822,6 @@ int zpci_enable_device(struct zpci_dev *zdev) rc = clp_enable_fh(zdev, ZPCI_NR_DMA_SPACES); if (rc) goto out; - pr_info("Enabled fh: 0x%x fid: 0x%x\n", zdev->fh, zdev->fid); rc = zpci_dma_init_device(zdev); if (rc) @@ -901,10 +941,6 @@ static int __init pci_base_init(void) || !test_facility(71) || !test_facility(72)) return 0; - pr_info("Probing PCI hardware: PCI:%d SID:%d AEN:%d\n", - test_facility(69), test_facility(70), - test_facility(71)); - rc = zpci_debug_init(); if (rc) goto out; diff --git a/arch/s390/pci/pci_clp.c b/arch/s390/pci/pci_clp.c index 475563c3d1e4..c747394029ee 100644 --- a/arch/s390/pci/pci_clp.c +++ b/arch/s390/pci/pci_clp.c @@ -16,6 +16,16 @@ #include <asm/pci_debug.h> #include <asm/pci_clp.h> +static inline void zpci_err_clp(unsigned int rsp, int rc) +{ + struct { + unsigned int rsp; + int rc; + } __packed data = {rsp, rc}; + + zpci_err_hex(&data, sizeof(data)); +} + /* * Call Logical Processor * Retry logic is handled by the caller. @@ -54,7 +64,6 @@ static void clp_store_query_pci_fngrp(struct zpci_dev *zdev, zdev->msi_addr = response->msia; zdev->fmb_update = response->mui; - pr_debug("Supported number of MSI vectors: %u\n", response->noi); switch (response->version) { case 1: zdev->max_bus_speed = PCIE_SPEED_5_0GT; @@ -84,8 +93,8 @@ static int clp_query_pci_fngrp(struct zpci_dev *zdev, u8 pfgid) if (!rc && rrb->response.hdr.rsp == CLP_RC_OK) clp_store_query_pci_fngrp(zdev, &rrb->response); else { - pr_err("Query PCI FNGRP failed with response: %x cc: %d\n", - rrb->response.hdr.rsp, rc); + zpci_err("Q PCI FGRP:\n"); + zpci_err_clp(rrb->response.hdr.rsp, rc); rc = -EIO; } clp_free_block(rrb); @@ -131,8 +140,8 @@ static int clp_query_pci_fn(struct zpci_dev *zdev, u32 fh) if (rrb->response.pfgid) rc = clp_query_pci_fngrp(zdev, rrb->response.pfgid); } else { - pr_err("Query PCI failed with response: %x cc: %d\n", - rrb->response.hdr.rsp, rc); + zpci_err("Q PCI FN:\n"); + zpci_err_clp(rrb->response.hdr.rsp, rc); rc = -EIO; } out: @@ -146,9 +155,9 @@ int clp_add_pci_device(u32 fid, u32 fh, int configured) int rc; zpci_dbg(3, "add fid:%x, fh:%x, c:%d\n", fid, fh, configured); - zdev = zpci_alloc_device(); - if (IS_ERR(zdev)) - return PTR_ERR(zdev); + zdev = kzalloc(sizeof(*zdev), GFP_KERNEL); + if (!zdev) + return -ENOMEM; zdev->fh = fh; zdev->fid = fid; @@ -169,7 +178,7 @@ int clp_add_pci_device(u32 fid, u32 fh, int configured) return 0; error: - zpci_free_device(zdev); + kfree(zdev); return rc; } @@ -206,8 +215,8 @@ static int clp_set_pci_fn(u32 *fh, u8 nr_dma_as, u8 command) if (!rc && rrb->response.hdr.rsp == CLP_RC_OK) *fh = rrb->response.fh; else { - zpci_dbg(0, "SPF fh:%x, cc:%d, resp:%x\n", *fh, rc, - rrb->response.hdr.rsp); + zpci_err("Set PCI FN:\n"); + zpci_err_clp(rrb->response.hdr.rsp, rc); rc = -EIO; } clp_free_block(rrb); @@ -262,8 +271,8 @@ static int clp_list_pci(struct clp_req_rsp_list_pci *rrb, /* Get PCI function handle list */ rc = clp_instr(rrb); if (rc || rrb->response.hdr.rsp != CLP_RC_OK) { - pr_err("List PCI failed with response: 0x%x cc: %d\n", - rrb->response.hdr.rsp, rc); + zpci_err("List PCI FN:\n"); + zpci_err_clp(rrb->response.hdr.rsp, rc); rc = -EIO; goto out; } @@ -273,17 +282,11 @@ static int clp_list_pci(struct clp_req_rsp_list_pci *rrb, entries = (rrb->response.hdr.len - LIST_PCI_HDR_LEN) / rrb->response.entry_size; - pr_info("Detected number of PCI functions: %u\n", entries); - /* Store the returned resume token as input for the next call */ resume_token = rrb->response.resume_token; - for (i = 0; i < entries; i++) cb(&rrb->response.fh_list[i]); } while (resume_token); - - pr_debug("Maximum number of supported PCI functions: %u\n", - rrb->response.max_fn); out: return rc; } diff --git a/arch/s390/pci/pci_dma.c b/arch/s390/pci/pci_dma.c index 7e5573acb063..9b83d080902d 100644 --- a/arch/s390/pci/pci_dma.c +++ b/arch/s390/pci/pci_dma.c @@ -145,10 +145,8 @@ static int dma_update_trans(struct zpci_dev *zdev, unsigned long pa, return -EINVAL; spin_lock_irqsave(&zdev->dma_table_lock, irq_flags); - if (!zdev->dma_table) { - dev_err(&zdev->pdev->dev, "Missing DMA table\n"); + if (!zdev->dma_table) goto no_refresh; - } for (i = 0; i < nr_pages; i++) { dma_update_cpu_trans(zdev, page_addr, dma_addr, flags); @@ -280,11 +278,8 @@ static dma_addr_t s390_dma_map_pages(struct device *dev, struct page *page, size = nr_pages * PAGE_SIZE; dma_addr = zdev->start_dma + iommu_page_index * PAGE_SIZE; - if (dma_addr + size > zdev->end_dma) { - dev_err(dev, "(dma_addr: 0x%16.16LX + size: 0x%16.16lx) > end_dma: 0x%16.16Lx\n", - dma_addr, size, zdev->end_dma); + if (dma_addr + size > zdev->end_dma) goto out_free; - } if (direction == DMA_NONE || direction == DMA_TO_DEVICE) flags |= ZPCI_TABLE_PROTECTED; @@ -297,7 +292,8 @@ static dma_addr_t s390_dma_map_pages(struct device *dev, struct page *page, out_free: dma_free_iommu(zdev, iommu_page_index, nr_pages); out_err: - dev_err(dev, "Failed to map addr: %lx\n", pa); + zpci_err("map error:\n"); + zpci_err_hex(&pa, sizeof(pa)); return DMA_ERROR_CODE; } @@ -312,8 +308,10 @@ static void s390_dma_unmap_pages(struct device *dev, dma_addr_t dma_addr, npages = iommu_num_pages(dma_addr, size, PAGE_SIZE); dma_addr = dma_addr & PAGE_MASK; if (dma_update_trans(zdev, 0, dma_addr, npages * PAGE_SIZE, - ZPCI_TABLE_PROTECTED | ZPCI_PTE_INVALID)) - dev_err(dev, "Failed to unmap addr: %Lx\n", dma_addr); + ZPCI_TABLE_PROTECTED | ZPCI_PTE_INVALID)) { + zpci_err("unmap error:\n"); + zpci_err_hex(&dma_addr, sizeof(dma_addr)); + } atomic64_add(npages, (atomic64_t *) &zdev->fmb->unmapped_pages); iommu_page_index = (dma_addr - zdev->start_dma) >> PAGE_SHIFT; diff --git a/arch/s390/pci/pci_event.c b/arch/s390/pci/pci_event.c index 0aecaf954845..800f064b0da7 100644 --- a/arch/s390/pci/pci_event.c +++ b/arch/s390/pci/pci_event.c @@ -10,6 +10,8 @@ #include <linux/kernel.h> #include <linux/pci.h> +#include <asm/pci_debug.h> +#include <asm/sclp.h> /* Content Code Description for PCI Function Error */ struct zpci_ccdf_err { @@ -41,55 +43,75 @@ struct zpci_ccdf_avail { u16 pec; /* PCI event code */ } __packed; -static void zpci_event_log_err(struct zpci_ccdf_err *ccdf) +void zpci_event_error(void *data) { + struct zpci_ccdf_err *ccdf = data; struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid); - zpci_err("SEI error CCD:\n"); + zpci_err("error CCDF:\n"); zpci_err_hex(ccdf, sizeof(*ccdf)); - dev_err(&zdev->pdev->dev, "event code: 0x%x\n", ccdf->pec); + + if (!zdev) + return; + + pr_err("%s: Event 0x%x reports an error for PCI function 0x%x\n", + pci_name(zdev->pdev), ccdf->pec, ccdf->fid); } -static void zpci_event_log_avail(struct zpci_ccdf_avail *ccdf) +void zpci_event_availability(void *data) { + struct zpci_ccdf_avail *ccdf = data; struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid); + struct pci_dev *pdev = zdev ? zdev->pdev : NULL; + int ret; - pr_err("%s%s: availability event: fh: 0x%x fid: 0x%x event code: 0x%x reason:", - (zdev) ? dev_driver_string(&zdev->pdev->dev) : "?", - (zdev) ? dev_name(&zdev->pdev->dev) : "?", - ccdf->fh, ccdf->fid, ccdf->pec); - print_hex_dump(KERN_CONT, "ccdf", DUMP_PREFIX_OFFSET, - 16, 1, ccdf, sizeof(*ccdf), false); + pr_info("%s: Event 0x%x reconfigured PCI function 0x%x\n", + pdev ? pci_name(pdev) : "n/a", ccdf->pec, ccdf->fid); + zpci_err("avail CCDF:\n"); + zpci_err_hex(ccdf, sizeof(*ccdf)); switch (ccdf->pec) { - case 0x0301: - zpci_enable_device(zdev); + case 0x0301: /* Standby -> Configured */ + if (!zdev || zdev->state == ZPCI_FN_STATE_CONFIGURED) + break; + zdev->state = ZPCI_FN_STATE_CONFIGURED; + ret = zpci_enable_device(zdev); + if (ret) + break; + pci_rescan_bus(zdev->bus); break; - case 0x0302: + case 0x0302: /* Reserved -> Standby */ clp_add_pci_device(ccdf->fid, ccdf->fh, 0); break; - case 0x0306: + case 0x0303: /* Deconfiguration requested */ + if (pdev) + pci_stop_and_remove_bus_device(pdev); + + ret = zpci_disable_device(zdev); + if (ret) + break; + + ret = sclp_pci_deconfigure(zdev->fid); + zpci_dbg(3, "deconf fid:%x, rc:%d\n", zdev->fid, ret); + if (!ret) + zdev->state = ZPCI_FN_STATE_STANDBY; + + break; + case 0x0304: /* Configured -> Standby */ + if (pdev) + pci_stop_and_remove_bus_device(pdev); + + zpci_disable_device(zdev); + zdev->state = ZPCI_FN_STATE_STANDBY; + break; + case 0x0306: /* 0x308 or 0x302 for multiple devices */ clp_rescan_pci_devices(); break; + case 0x0308: /* Standby -> Reserved */ + pci_stop_root_bus(zdev->bus); + pci_remove_root_bus(zdev->bus); + break; default: break; } } - -void zpci_event_error(void *data) -{ - struct zpci_ccdf_err *ccdf = data; - struct zpci_dev *zdev; - - zpci_event_log_err(ccdf); - zdev = get_zdev_by_fid(ccdf->fid); - if (!zdev) { - pr_err("Error event for unknown fid: %x", ccdf->fid); - return; - } -} - -void zpci_event_availability(void *data) -{ - zpci_event_log_avail(data); -} diff --git a/arch/score/include/asm/Kbuild b/arch/score/include/asm/Kbuild index e1c7bb999b06..f3414ade77a3 100644 --- a/arch/score/include/asm/Kbuild +++ b/arch/score/include/asm/Kbuild @@ -4,3 +4,4 @@ header-y += generic-y += clkdev.h generic-y += trace_clock.h generic-y += xor.h +generic-y += preempt.h diff --git a/arch/score/include/asm/pgalloc.h b/arch/score/include/asm/pgalloc.h index 716b3fd1d863..2e067657db98 100644 --- a/arch/score/include/asm/pgalloc.h +++ b/arch/score/include/asm/pgalloc.h @@ -54,9 +54,12 @@ static inline struct page *pte_alloc_one(struct mm_struct *mm, struct page *pte; pte = alloc_pages(GFP_KERNEL | __GFP_REPEAT, PTE_ORDER); - if (pte) { - clear_highpage(pte); - pgtable_page_ctor(pte); + if (!pte) + return NULL; + clear_highpage(pte); + if (!pgtable_page_ctor(pte)) { + __free_page(pte); + return NULL; } return pte; } diff --git a/arch/score/include/asm/thread_info.h b/arch/score/include/asm/thread_info.h index 1425cc034872..656b7ada9326 100644 --- a/arch/score/include/asm/thread_info.h +++ b/arch/score/include/asm/thread_info.h @@ -72,8 +72,6 @@ register struct thread_info *__current_thread_info __asm__("r28"); #endif /* !__ASSEMBLY__ */ -#define PREEMPT_ACTIVE 0x10000000 - /* * thread information flags * - these are process state flags that various assembly files may need to diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 224f4bc9925e..9b0979f4df7a 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -1,5 +1,6 @@ config SUPERH def_bool y + select ARCH_MIGHT_HAVE_PC_PARPORT select EXPERT select CLKDEV_LOOKUP select HAVE_IDE if HAS_IOPORT @@ -711,7 +712,6 @@ config CC_STACKPROTECTOR config SMP bool "Symmetric multi-processing support" depends on SYS_SUPPORTS_SMP - select USE_GENERIC_SMP_HELPERS ---help--- This enables support for systems with more than one CPU. If you have a system with only one CPU, like most personal computers, say N. If diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c index 1fa8be409771..122f737a901f 100644 --- a/arch/sh/boards/mach-ecovec24/setup.c +++ b/arch/sh/boards/mach-ecovec24/setup.c @@ -15,6 +15,7 @@ #include <linux/mmc/sh_mmcif.h> #include <linux/mmc/sh_mobile_sdhi.h> #include <linux/mtd/physmap.h> +#include <linux/mfd/tmio.h> #include <linux/gpio.h> #include <linux/interrupt.h> #include <linux/io.h> diff --git a/arch/sh/include/asm/Kbuild b/arch/sh/include/asm/Kbuild index 280bea9e5e2b..231efbb68108 100644 --- a/arch/sh/include/asm/Kbuild +++ b/arch/sh/include/asm/Kbuild @@ -34,3 +34,4 @@ generic-y += termios.h generic-y += trace_clock.h generic-y += ucontext.h generic-y += xor.h +generic-y += preempt.h diff --git a/arch/sh/include/asm/fpu.h b/arch/sh/include/asm/fpu.h index 06c4281aab65..09fc2bc8a790 100644 --- a/arch/sh/include/asm/fpu.h +++ b/arch/sh/include/asm/fpu.h @@ -46,7 +46,7 @@ static inline void __unlazy_fpu(struct task_struct *tsk, struct pt_regs *regs) save_fpu(tsk); release_fpu(regs); } else - tsk->fpu_counter = 0; + tsk->thread.fpu_counter = 0; } static inline void unlazy_fpu(struct task_struct *tsk, struct pt_regs *regs) diff --git a/arch/sh/include/asm/mmu_context.h b/arch/sh/include/asm/mmu_context.h index 21c5088788da..b9d9489a5012 100644 --- a/arch/sh/include/asm/mmu_context.h +++ b/arch/sh/include/asm/mmu_context.h @@ -81,7 +81,7 @@ static inline void get_mmu_context(struct mm_struct *mm, unsigned int cpu) /* * Fix version; Note that we avoid version #0 - * to distingush NO_CONTEXT. + * to distinguish NO_CONTEXT. */ if (!asid) asid = MMU_CONTEXT_FIRST_VERSION; diff --git a/arch/sh/include/asm/pgalloc.h b/arch/sh/include/asm/pgalloc.h index 8c00785c60d5..a33673b3687d 100644 --- a/arch/sh/include/asm/pgalloc.h +++ b/arch/sh/include/asm/pgalloc.h @@ -47,7 +47,10 @@ static inline pgtable_t pte_alloc_one(struct mm_struct *mm, if (!pg) return NULL; page = virt_to_page(pg); - pgtable_page_ctor(page); + if (!pgtable_page_ctor(page)) { + quicklist_free(QUICK_PT, NULL, pg); + return NULL; + } return page; } diff --git a/arch/sh/include/asm/processor_32.h b/arch/sh/include/asm/processor_32.h index e699a12cdcca..18e0377f72bb 100644 --- a/arch/sh/include/asm/processor_32.h +++ b/arch/sh/include/asm/processor_32.h @@ -111,6 +111,16 @@ struct thread_struct { /* Extended processor state */ union thread_xstate *xstate; + + /* + * fpu_counter contains the number of consecutive context switches + * that the FPU is used. If this is over a threshold, the lazy fpu + * saving becomes unlazy to save the trap. This is an unsigned char + * so that after 256 times the counter wraps and the behavior turns + * lazy again; this to deal with bursty apps that only use FPU for + * a short time + */ + unsigned char fpu_counter; }; #define INIT_THREAD { \ diff --git a/arch/sh/include/asm/processor_64.h b/arch/sh/include/asm/processor_64.h index 1cc7d3197143..eedd4f625d07 100644 --- a/arch/sh/include/asm/processor_64.h +++ b/arch/sh/include/asm/processor_64.h @@ -126,6 +126,16 @@ struct thread_struct { /* floating point info */ union thread_xstate *xstate; + + /* + * fpu_counter contains the number of consecutive context switches + * that the FPU is used. If this is over a threshold, the lazy fpu + * saving becomes unlazy to save the trap. This is an unsigned char + * so that after 256 times the counter wraps and the behavior turns + * lazy again; this to deal with bursty apps that only use FPU for + * a short time + */ + unsigned char fpu_counter; }; #define INIT_MMAP \ diff --git a/arch/sh/include/asm/thread_info.h b/arch/sh/include/asm/thread_info.h index 45a93669289d..ad27ffa65e2e 100644 --- a/arch/sh/include/asm/thread_info.h +++ b/arch/sh/include/asm/thread_info.h @@ -41,8 +41,6 @@ struct thread_info { #endif -#define PREEMPT_ACTIVE 0x10000000 - #if defined(CONFIG_4KSTACKS) #define THREAD_SHIFT 12 #else diff --git a/arch/sh/kernel/cpu/fpu.c b/arch/sh/kernel/cpu/fpu.c index f8f7af51c128..4e332244ea75 100644 --- a/arch/sh/kernel/cpu/fpu.c +++ b/arch/sh/kernel/cpu/fpu.c @@ -44,7 +44,7 @@ void __fpu_state_restore(void) restore_fpu(tsk); task_thread_info(tsk)->status |= TS_USEDFPU; - tsk->fpu_counter++; + tsk->thread.fpu_counter++; } void fpu_state_restore(struct pt_regs *regs) diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S index 9b6e4beeb296..ca46834294b7 100644 --- a/arch/sh/kernel/entry-common.S +++ b/arch/sh/kernel/entry-common.S @@ -108,7 +108,7 @@ need_resched: and #(0xf0>>1), r0 ! interrupts off (exception path)? cmp/eq #(0xf0>>1), r0 bt noresched - mov.l 3f, r0 + mov.l 1f, r0 jsr @r0 ! call preempt_schedule_irq nop bra need_resched @@ -119,9 +119,7 @@ noresched: nop .align 2 -1: .long PREEMPT_ACTIVE -2: .long schedule -3: .long preempt_schedule_irq +1: .long preempt_schedule_irq #endif ENTRY(resume_userspace) diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c index 063af10ff3c1..0833736afa32 100644 --- a/arch/sh/kernel/irq.c +++ b/arch/sh/kernel/irq.c @@ -149,47 +149,32 @@ void irq_ctx_exit(int cpu) hardirq_ctx[cpu] = NULL; } -asmlinkage void do_softirq(void) +void do_softirq_own_stack(void) { - unsigned long flags; struct thread_info *curctx; union irq_ctx *irqctx; u32 *isp; - if (in_interrupt()) - return; - - local_irq_save(flags); - - if (local_softirq_pending()) { - curctx = current_thread_info(); - irqctx = softirq_ctx[smp_processor_id()]; - irqctx->tinfo.task = curctx->task; - irqctx->tinfo.previous_sp = current_stack_pointer; - - /* build the stack frame on the softirq stack */ - isp = (u32 *)((char *)irqctx + sizeof(*irqctx)); - - __asm__ __volatile__ ( - "mov r15, r9 \n" - "jsr @%0 \n" - /* switch to the softirq stack */ - " mov %1, r15 \n" - /* restore the thread stack */ - "mov r9, r15 \n" - : /* no outputs */ - : "r" (__do_softirq), "r" (isp) - : "memory", "r0", "r1", "r2", "r3", "r4", - "r5", "r6", "r7", "r8", "r9", "r15", "t", "pr" - ); - - /* - * Shouldn't happen, we returned above if in_interrupt(): - */ - WARN_ON_ONCE(softirq_count()); - } - - local_irq_restore(flags); + curctx = current_thread_info(); + irqctx = softirq_ctx[smp_processor_id()]; + irqctx->tinfo.task = curctx->task; + irqctx->tinfo.previous_sp = current_stack_pointer; + + /* build the stack frame on the softirq stack */ + isp = (u32 *)((char *)irqctx + sizeof(*irqctx)); + + __asm__ __volatile__ ( + "mov r15, r9 \n" + "jsr @%0 \n" + /* switch to the softirq stack */ + " mov %1, r15 \n" + /* restore the thread stack */ + "mov r9, r15 \n" + : /* no outputs */ + : "r" (__do_softirq), "r" (isp) + : "memory", "r0", "r1", "r2", "r3", "r4", + "r5", "r6", "r7", "r8", "r9", "r15", "t", "pr" + ); } #else static inline void handle_one_irq(unsigned int irq) diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c index ebd3933005b4..2885fc9d9dcd 100644 --- a/arch/sh/kernel/process_32.c +++ b/arch/sh/kernel/process_32.c @@ -156,7 +156,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, #endif ti->addr_limit = KERNEL_DS; ti->status &= ~TS_USEDFPU; - p->fpu_counter = 0; + p->thread.fpu_counter = 0; return 0; } *childregs = *current_pt_regs(); @@ -189,7 +189,7 @@ __switch_to(struct task_struct *prev, struct task_struct *next) unlazy_fpu(prev, task_pt_regs(prev)); /* we're going to use this soon, after a few expensive things */ - if (next->fpu_counter > 5) + if (next->thread.fpu_counter > 5) prefetch(next_t->xstate); #ifdef CONFIG_MMU @@ -207,7 +207,7 @@ __switch_to(struct task_struct *prev, struct task_struct *next) * restore of the math state immediately to avoid the trap; the * chances of needing FPU soon are obviously high now */ - if (next->fpu_counter > 5) + if (next->thread.fpu_counter > 5) __fpu_state_restore(); return prev; diff --git a/arch/sh/kernel/process_64.c b/arch/sh/kernel/process_64.c index 174d124b419e..e2062e643341 100644 --- a/arch/sh/kernel/process_64.c +++ b/arch/sh/kernel/process_64.c @@ -374,7 +374,7 @@ asmlinkage void ret_from_kernel_thread(void); int copy_thread(unsigned long clone_flags, unsigned long usp, unsigned long arg, struct task_struct *p) { - struct pt_regs *childregs, *regs = current_pt_regs(); + struct pt_regs *childregs; #ifdef CONFIG_SH_FPU /* can't happen for a kernel thread */ @@ -393,7 +393,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, if (unlikely(p->flags & PF_KTHREAD)) { memset(childregs, 0, sizeof(struct pt_regs)); childregs->regs[2] = (unsigned long)arg; - childregs->regs[3] = (unsigned long)fn; + childregs->regs[3] = (unsigned long)usp; childregs->sr = (1 << 30); /* not user_mode */ childregs->sr |= SR_FD; /* Invalidate FPU flag */ p->thread.pc = (unsigned long) ret_from_kernel_thread; diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index 33890fd267cb..2d089fe2cba9 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -231,7 +231,7 @@ static void __init bootmem_init_one_node(unsigned int nid) if (!p->node_spanned_pages) return; - end_pfn = p->node_start_pfn + p->node_spanned_pages; + end_pfn = pgdat_end_pfn(p); total_pages = bootmem_bootmap_pages(p->node_spanned_pages); diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 78c4fdb91bc5..d4f7a6a163dc 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -12,6 +12,7 @@ config 64BIT config SPARC bool default y + select ARCH_MIGHT_HAVE_PC_PARPORT if SPARC64 && PCI select OF select OF_PROMTREE select HAVE_IDE @@ -28,7 +29,6 @@ config SPARC select HAVE_ARCH_JUMP_LABEL select GENERIC_IRQ_SHOW select ARCH_WANT_IPC_PARSE_VERSION - select USE_GENERIC_SMP_HELPERS if SMP select GENERIC_PCI_IOMAP select HAVE_NMI_WATCHDOG if SPARC64 select HAVE_BPF_JIT @@ -64,6 +64,7 @@ config SPARC64 select HAVE_DYNAMIC_FTRACE select HAVE_FTRACE_MCOUNT_RECORD select HAVE_SYSCALL_TRACEPOINTS + select HAVE_CONTEXT_TRACKING select HAVE_DEBUG_KMEMLEAK select RTC_DRV_CMOS select RTC_DRV_BQ4802 diff --git a/arch/sparc/include/asm/Kbuild b/arch/sparc/include/asm/Kbuild index 7e4a97fbded4..bf390667657a 100644 --- a/arch/sparc/include/asm/Kbuild +++ b/arch/sparc/include/asm/Kbuild @@ -16,3 +16,4 @@ generic-y += serial.h generic-y += trace_clock.h generic-y += types.h generic-y += word-at-a-time.h +generic-y += preempt.h diff --git a/arch/sparc/include/asm/hardirq_32.h b/arch/sparc/include/asm/hardirq_32.h index 162007643cdc..ee93923b7f82 100644 --- a/arch/sparc/include/asm/hardirq_32.h +++ b/arch/sparc/include/asm/hardirq_32.h @@ -7,7 +7,6 @@ #ifndef __SPARC_HARDIRQ_H #define __SPARC_HARDIRQ_H -#define HARDIRQ_BITS 8 #include <asm-generic/hardirq.h> #endif /* __SPARC_HARDIRQ_H */ diff --git a/arch/sparc/include/asm/hardirq_64.h b/arch/sparc/include/asm/hardirq_64.h index 7c29fd1a87aa..f478ff1ddd02 100644 --- a/arch/sparc/include/asm/hardirq_64.h +++ b/arch/sparc/include/asm/hardirq_64.h @@ -14,6 +14,4 @@ void ack_bad_irq(unsigned int irq); -#define HARDIRQ_BITS 8 - #endif /* !(__SPARC64_HARDIRQ_H) */ diff --git a/arch/sparc/include/asm/mmu_64.h b/arch/sparc/include/asm/mmu_64.h index 76092c4dd277..f668797ae234 100644 --- a/arch/sparc/include/asm/mmu_64.h +++ b/arch/sparc/include/asm/mmu_64.h @@ -93,7 +93,6 @@ typedef struct { spinlock_t lock; unsigned long sparc64_ctx_val; unsigned long huge_pte_count; - struct page *pgtable_page; struct tsb_config tsb_block[MM_NUM_TSBS]; struct hv_tsb_descr tsb_descr[MM_NUM_TSBS]; } mm_context_t; diff --git a/arch/sparc/include/asm/page_64.h b/arch/sparc/include/asm/page_64.h index e15538899f3d..aac53fcea807 100644 --- a/arch/sparc/include/asm/page_64.h +++ b/arch/sparc/include/asm/page_64.h @@ -15,7 +15,10 @@ #define DCACHE_ALIASING_POSSIBLE #endif -#define HPAGE_SHIFT 22 +#define HPAGE_SHIFT 23 +#define REAL_HPAGE_SHIFT 22 + +#define REAL_HPAGE_SIZE (_AC(1,UL) << REAL_HPAGE_SHIFT) #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE) #define HPAGE_SIZE (_AC(1,UL) << HPAGE_SHIFT) @@ -53,8 +56,8 @@ extern void copy_user_page(void *to, void *from, unsigned long vaddr, struct pag /* These are used to make use of C type-checking.. */ typedef struct { unsigned long pte; } pte_t; typedef struct { unsigned long iopte; } iopte_t; -typedef struct { unsigned int pmd; } pmd_t; -typedef struct { unsigned int pgd; } pgd_t; +typedef struct { unsigned long pmd; } pmd_t; +typedef struct { unsigned long pgd; } pgd_t; typedef struct { unsigned long pgprot; } pgprot_t; #define pte_val(x) ((x).pte) @@ -73,8 +76,8 @@ typedef struct { unsigned long pgprot; } pgprot_t; /* .. while these make it easier on the compiler */ typedef unsigned long pte_t; typedef unsigned long iopte_t; -typedef unsigned int pmd_t; -typedef unsigned int pgd_t; +typedef unsigned long pmd_t; +typedef unsigned long pgd_t; typedef unsigned long pgprot_t; #define pte_val(x) (x) @@ -93,18 +96,44 @@ typedef unsigned long pgprot_t; typedef pte_t *pgtable_t; +/* These two values define the virtual address space range in which we + * must forbid 64-bit user processes from making mappings. It used to + * represent precisely the virtual address space hole present in most + * early sparc64 chips including UltraSPARC-I. But now it also is + * further constrained by the limits of our page tables, which is + * 43-bits of virtual address. + */ +#define SPARC64_VA_HOLE_TOP _AC(0xfffffc0000000000,UL) +#define SPARC64_VA_HOLE_BOTTOM _AC(0x0000040000000000,UL) + +/* The next two defines specify the actual exclusion region we + * enforce, wherein we use a 4GB red zone on each side of the VA hole. + */ +#define VA_EXCLUDE_START (SPARC64_VA_HOLE_BOTTOM - (1UL << 32UL)) +#define VA_EXCLUDE_END (SPARC64_VA_HOLE_TOP + (1UL << 32UL)) + #define TASK_UNMAPPED_BASE (test_thread_flag(TIF_32BIT) ? \ - (_AC(0x0000000070000000,UL)) : \ - (_AC(0xfffff80000000000,UL) + (1UL << 32UL))) + _AC(0x0000000070000000,UL) : \ + VA_EXCLUDE_END) #include <asm-generic/memory_model.h> +#define PAGE_OFFSET_BY_BITS(X) (-(_AC(1,UL) << (X))) +extern unsigned long PAGE_OFFSET; + #endif /* !(__ASSEMBLY__) */ -/* We used to stick this into a hard-coded global register (%g4) - * but that does not make sense anymore. +/* The maximum number of physical memory address bits we support, this + * is used to size various tables used to manage kernel TLB misses and + * also the sparsemem code. + */ +#define MAX_PHYS_ADDRESS_BITS 47 + +/* These two shift counts are used when indexing sparc64_valid_addr_bitmap + * and kpte_linear_bitmap. */ -#define PAGE_OFFSET _AC(0xFFFFF80000000000,UL) +#define ILOG2_4MB 22 +#define ILOG2_256MB 28 #ifndef __ASSEMBLY__ diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h index 36760317814f..8358dc144959 100644 --- a/arch/sparc/include/asm/pgtable_64.h +++ b/arch/sparc/include/asm/pgtable_64.h @@ -48,18 +48,18 @@ /* PMD_SHIFT determines the size of the area a second-level page * table can map */ -#define PMD_SHIFT (PAGE_SHIFT + (PAGE_SHIFT-4)) +#define PMD_SHIFT (PAGE_SHIFT + (PAGE_SHIFT-3)) #define PMD_SIZE (_AC(1,UL) << PMD_SHIFT) #define PMD_MASK (~(PMD_SIZE-1)) -#define PMD_BITS (PAGE_SHIFT - 2) +#define PMD_BITS (PAGE_SHIFT - 3) /* PGDIR_SHIFT determines what a third-level page table entry can map */ -#define PGDIR_SHIFT (PAGE_SHIFT + (PAGE_SHIFT-4) + PMD_BITS) +#define PGDIR_SHIFT (PAGE_SHIFT + (PAGE_SHIFT-3) + PMD_BITS) #define PGDIR_SIZE (_AC(1,UL) << PGDIR_SHIFT) #define PGDIR_MASK (~(PGDIR_SIZE-1)) -#define PGDIR_BITS (PAGE_SHIFT - 2) +#define PGDIR_BITS (PAGE_SHIFT - 3) -#if (PGDIR_SHIFT + PGDIR_BITS) != 44 +#if (PGDIR_SHIFT + PGDIR_BITS) != 43 #error Page table parameters do not cover virtual address space properly. #endif @@ -67,35 +67,12 @@ #error PMD_SHIFT must equal HPAGE_SHIFT for transparent huge pages. #endif -/* PMDs point to PTE tables which are 4K aligned. */ -#define PMD_PADDR _AC(0xfffffffe,UL) -#define PMD_PADDR_SHIFT _AC(11,UL) - -#define PMD_ISHUGE _AC(0x00000001,UL) - -/* This is the PMD layout when PMD_ISHUGE is set. With 4MB huge - * pages, this frees up a bunch of bits in the layout that we can - * use for the protection settings and software metadata. - */ -#define PMD_HUGE_PADDR _AC(0xfffff800,UL) -#define PMD_HUGE_PROTBITS _AC(0x000007ff,UL) -#define PMD_HUGE_PRESENT _AC(0x00000400,UL) -#define PMD_HUGE_WRITE _AC(0x00000200,UL) -#define PMD_HUGE_DIRTY _AC(0x00000100,UL) -#define PMD_HUGE_ACCESSED _AC(0x00000080,UL) -#define PMD_HUGE_EXEC _AC(0x00000040,UL) -#define PMD_HUGE_SPLITTING _AC(0x00000020,UL) - -/* PGDs point to PMD tables which are 8K aligned. */ -#define PGD_PADDR _AC(0xfffffffc,UL) -#define PGD_PADDR_SHIFT _AC(11,UL) - #ifndef __ASSEMBLY__ #include <linux/sched.h> /* Entries per page directory level. */ -#define PTRS_PER_PTE (1UL << (PAGE_SHIFT-4)) +#define PTRS_PER_PTE (1UL << (PAGE_SHIFT-3)) #define PTRS_PER_PMD (1UL << PMD_BITS) #define PTRS_PER_PGD (1UL << PGDIR_BITS) @@ -112,6 +89,7 @@ #define _PAGE_VALID _AC(0x8000000000000000,UL) /* Valid TTE */ #define _PAGE_R _AC(0x8000000000000000,UL) /* Keep ref bit uptodate*/ #define _PAGE_SPECIAL _AC(0x0200000000000000,UL) /* Special page */ +#define _PAGE_PMD_HUGE _AC(0x0100000000000000,UL) /* Huge page */ /* Advertise support for _PAGE_SPECIAL */ #define __HAVE_ARCH_PTE_SPECIAL @@ -125,6 +103,7 @@ #define _PAGE_IE_4U _AC(0x0800000000000000,UL) /* Invert Endianness */ #define _PAGE_SOFT2_4U _AC(0x07FC000000000000,UL) /* Software bits, set 2 */ #define _PAGE_SPECIAL_4U _AC(0x0200000000000000,UL) /* Special page */ +#define _PAGE_PMD_HUGE_4U _AC(0x0100000000000000,UL) /* Huge page */ #define _PAGE_RES1_4U _AC(0x0002000000000000,UL) /* Reserved */ #define _PAGE_SZ32MB_4U _AC(0x0001000000000000,UL) /* (Panther) 32MB page */ #define _PAGE_SZ256MB_4U _AC(0x2001000000000000,UL) /* (Panther) 256MB page */ @@ -155,6 +134,7 @@ #define _PAGE_READ_4V _AC(0x0800000000000000,UL) /* Readable SW Bit */ #define _PAGE_WRITE_4V _AC(0x0400000000000000,UL) /* Writable SW Bit */ #define _PAGE_SPECIAL_4V _AC(0x0200000000000000,UL) /* Special page */ +#define _PAGE_PMD_HUGE_4V _AC(0x0100000000000000,UL) /* Huge page */ #define _PAGE_PADDR_4V _AC(0x00FFFFFFFFFFE000,UL) /* paddr[55:13] */ #define _PAGE_IE_4V _AC(0x0000000000001000,UL) /* Invert Endianness */ #define _PAGE_E_4V _AC(0x0000000000000800,UL) /* side-Effect */ @@ -180,6 +160,10 @@ #define _PAGE_SZBITS_4U _PAGE_SZ8K_4U #define _PAGE_SZBITS_4V _PAGE_SZ8K_4V +#if REAL_HPAGE_SHIFT != 22 +#error REAL_HPAGE_SHIFT and _PAGE_SZHUGE_foo must match up +#endif + #define _PAGE_SZHUGE_4U _PAGE_SZ4MB_4U #define _PAGE_SZHUGE_4V _PAGE_SZ4MB_4V @@ -239,16 +223,13 @@ static inline pte_t pfn_pte(unsigned long pfn, pgprot_t prot) #define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) #ifdef CONFIG_TRANSPARENT_HUGEPAGE -extern pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot); -#define mk_pmd(page, pgprot) pfn_pmd(page_to_pfn(page), (pgprot)) - -extern pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot); - -static inline pmd_t pmd_mkhuge(pmd_t pmd) +static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot) { - /* Do nothing, mk_pmd() does this part. */ - return pmd; + pte_t pte = pfn_pte(page_nr, pgprot); + + return __pmd(pte_val(pte)); } +#define mk_pmd(page, pgprot) pfn_pmd(page_to_pfn(page), (pgprot)) #endif /* This one can be done with two shifts. */ @@ -309,14 +290,25 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t prot) : "=r" (mask), "=r" (tmp) : "i" (_PAGE_PADDR_4U | _PAGE_MODIFIED_4U | _PAGE_ACCESSED_4U | _PAGE_CP_4U | _PAGE_CV_4U | _PAGE_E_4U | _PAGE_PRESENT_4U | - _PAGE_SPECIAL), + _PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4U), "i" (_PAGE_PADDR_4V | _PAGE_MODIFIED_4V | _PAGE_ACCESSED_4V | _PAGE_CP_4V | _PAGE_CV_4V | _PAGE_E_4V | _PAGE_PRESENT_4V | - _PAGE_SPECIAL)); + _PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4V)); return __pte((pte_val(pte) & mask) | (pgprot_val(prot) & ~mask)); } +#ifdef CONFIG_TRANSPARENT_HUGEPAGE +static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot) +{ + pte_t pte = __pte(pmd_val(pmd)); + + pte = pte_modify(pte, newprot); + + return __pmd(pte_val(pte)); +} +#endif + static inline pte_t pgoff_to_pte(unsigned long off) { off <<= PAGE_SHIFT; @@ -357,7 +349,7 @@ static inline pgprot_t pgprot_noncached(pgprot_t prot) */ #define pgprot_noncached pgprot_noncached -#ifdef CONFIG_HUGETLB_PAGE +#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE) static inline pte_t pte_mkhuge(pte_t pte) { unsigned long mask; @@ -375,6 +367,17 @@ static inline pte_t pte_mkhuge(pte_t pte) return __pte(pte_val(pte) | mask); } +#ifdef CONFIG_TRANSPARENT_HUGEPAGE +static inline pmd_t pmd_mkhuge(pmd_t pmd) +{ + pte_t pte = __pte(pmd_val(pmd)); + + pte = pte_mkhuge(pte); + pte_val(pte) |= _PAGE_PMD_HUGE; + + return __pmd(pte_val(pte)); +} +#endif #endif static inline pte_t pte_mkdirty(pte_t pte) @@ -626,91 +629,130 @@ static inline unsigned long pte_special(pte_t pte) return pte_val(pte) & _PAGE_SPECIAL; } -static inline int pmd_large(pmd_t pmd) +static inline unsigned long pmd_large(pmd_t pmd) { - return (pmd_val(pmd) & (PMD_ISHUGE | PMD_HUGE_PRESENT)) == - (PMD_ISHUGE | PMD_HUGE_PRESENT); + pte_t pte = __pte(pmd_val(pmd)); + + return (pte_val(pte) & _PAGE_PMD_HUGE) && pte_present(pte); } #ifdef CONFIG_TRANSPARENT_HUGEPAGE -static inline int pmd_young(pmd_t pmd) +static inline unsigned long pmd_young(pmd_t pmd) { - return pmd_val(pmd) & PMD_HUGE_ACCESSED; + pte_t pte = __pte(pmd_val(pmd)); + + return pte_young(pte); } -static inline int pmd_write(pmd_t pmd) +static inline unsigned long pmd_write(pmd_t pmd) { - return pmd_val(pmd) & PMD_HUGE_WRITE; + pte_t pte = __pte(pmd_val(pmd)); + + return pte_write(pte); } static inline unsigned long pmd_pfn(pmd_t pmd) { - unsigned long val = pmd_val(pmd) & PMD_HUGE_PADDR; + pte_t pte = __pte(pmd_val(pmd)); - return val >> (PAGE_SHIFT - PMD_PADDR_SHIFT); + return pte_pfn(pte); } -static inline int pmd_trans_splitting(pmd_t pmd) +static inline unsigned long pmd_trans_huge(pmd_t pmd) { - return (pmd_val(pmd) & (PMD_ISHUGE|PMD_HUGE_SPLITTING)) == - (PMD_ISHUGE|PMD_HUGE_SPLITTING); + pte_t pte = __pte(pmd_val(pmd)); + + return pte_val(pte) & _PAGE_PMD_HUGE; } -static inline int pmd_trans_huge(pmd_t pmd) +static inline unsigned long pmd_trans_splitting(pmd_t pmd) { - return pmd_val(pmd) & PMD_ISHUGE; + pte_t pte = __pte(pmd_val(pmd)); + + return pmd_trans_huge(pmd) && pte_special(pte); } #define has_transparent_hugepage() 1 static inline pmd_t pmd_mkold(pmd_t pmd) { - pmd_val(pmd) &= ~PMD_HUGE_ACCESSED; - return pmd; + pte_t pte = __pte(pmd_val(pmd)); + + pte = pte_mkold(pte); + + return __pmd(pte_val(pte)); } static inline pmd_t pmd_wrprotect(pmd_t pmd) { - pmd_val(pmd) &= ~PMD_HUGE_WRITE; - return pmd; + pte_t pte = __pte(pmd_val(pmd)); + + pte = pte_wrprotect(pte); + + return __pmd(pte_val(pte)); } static inline pmd_t pmd_mkdirty(pmd_t pmd) { - pmd_val(pmd) |= PMD_HUGE_DIRTY; - return pmd; + pte_t pte = __pte(pmd_val(pmd)); + + pte = pte_mkdirty(pte); + + return __pmd(pte_val(pte)); } static inline pmd_t pmd_mkyoung(pmd_t pmd) { - pmd_val(pmd) |= PMD_HUGE_ACCESSED; - return pmd; + pte_t pte = __pte(pmd_val(pmd)); + + pte = pte_mkyoung(pte); + + return __pmd(pte_val(pte)); } static inline pmd_t pmd_mkwrite(pmd_t pmd) { - pmd_val(pmd) |= PMD_HUGE_WRITE; - return pmd; + pte_t pte = __pte(pmd_val(pmd)); + + pte = pte_mkwrite(pte); + + return __pmd(pte_val(pte)); } static inline pmd_t pmd_mknotpresent(pmd_t pmd) { - pmd_val(pmd) &= ~PMD_HUGE_PRESENT; + unsigned long mask; + + if (tlb_type == hypervisor) + mask = _PAGE_PRESENT_4V; + else + mask = _PAGE_PRESENT_4U; + + pmd_val(pmd) &= ~mask; + return pmd; } static inline pmd_t pmd_mksplitting(pmd_t pmd) { - pmd_val(pmd) |= PMD_HUGE_SPLITTING; - return pmd; + pte_t pte = __pte(pmd_val(pmd)); + + pte = pte_mkspecial(pte); + + return __pmd(pte_val(pte)); } -extern pgprot_t pmd_pgprot(pmd_t entry); +static inline pgprot_t pmd_pgprot(pmd_t entry) +{ + unsigned long val = pmd_val(entry); + + return __pgprot(val); +} #endif static inline int pmd_present(pmd_t pmd) { - return pmd_val(pmd) != 0U; + return pmd_val(pmd) != 0UL; } #define pmd_none(pmd) (!pmd_val(pmd)) @@ -728,33 +770,32 @@ static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr, static inline void pmd_set(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep) { - unsigned long val = __pa((unsigned long) (ptep)) >> PMD_PADDR_SHIFT; + unsigned long val = __pa((unsigned long) (ptep)); pmd_val(*pmdp) = val; } #define pud_set(pudp, pmdp) \ - (pud_val(*(pudp)) = (__pa((unsigned long) (pmdp)) >> PGD_PADDR_SHIFT)) + (pud_val(*(pudp)) = (__pa((unsigned long) (pmdp)))) static inline unsigned long __pmd_page(pmd_t pmd) { - unsigned long paddr = (unsigned long) pmd_val(pmd); -#ifdef CONFIG_TRANSPARENT_HUGEPAGE - if (pmd_val(pmd) & PMD_ISHUGE) - paddr &= PMD_HUGE_PADDR; -#endif - paddr <<= PMD_PADDR_SHIFT; - return ((unsigned long) __va(paddr)); + pte_t pte = __pte(pmd_val(pmd)); + unsigned long pfn; + + pfn = pte_pfn(pte); + + return ((unsigned long) __va(pfn << PAGE_SHIFT)); } #define pmd_page(pmd) virt_to_page((void *)__pmd_page(pmd)) #define pud_page_vaddr(pud) \ - ((unsigned long) __va((((unsigned long)pud_val(pud))<<PGD_PADDR_SHIFT))) + ((unsigned long) __va(pud_val(pud))) #define pud_page(pud) virt_to_page((void *)pud_page_vaddr(pud)) #define pmd_bad(pmd) (0) -#define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0U) +#define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0UL) #define pud_none(pud) (!pud_val(pud)) #define pud_bad(pud) (0) #define pud_present(pud) (pud_val(pud) != 0U) -#define pud_clear(pudp) (pud_val(*(pudp)) = 0U) +#define pud_clear(pudp) (pud_val(*(pudp)) = 0UL) /* Same in both SUN4V and SUN4U. */ #define pte_none(pte) (!pte_val(pte)) @@ -789,7 +830,7 @@ static inline pmd_t pmdp_get_and_clear(struct mm_struct *mm, pmd_t *pmdp) { pmd_t pmd = *pmdp; - set_pmd_at(mm, addr, pmdp, __pmd(0U)); + set_pmd_at(mm, addr, pmdp, __pmd(0UL)); return pmd; } @@ -837,8 +878,8 @@ static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr, }) #endif -extern pgd_t swapper_pg_dir[2048]; -extern pmd_t swapper_low_pmd_dir[2048]; +extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; +extern pmd_t swapper_low_pmd_dir[PTRS_PER_PMD]; extern void paging_init(void); extern unsigned long find_ecache_flush_span(unsigned long size); diff --git a/arch/sparc/include/asm/prom.h b/arch/sparc/include/asm/prom.h index 67c62578d170..11ebd659e7b6 100644 --- a/arch/sparc/include/asm/prom.h +++ b/arch/sparc/include/asm/prom.h @@ -43,10 +43,6 @@ extern int of_getintprop_default(struct device_node *np, const char *name, int def); extern int of_find_in_proplist(const char *list, const char *match, int len); -#ifdef CONFIG_NUMA -extern int of_node_to_nid(struct device_node *dp); -#define of_node_to_nid of_node_to_nid -#endif extern void prom_build_devicetree(void); extern void of_populate_present_mask(void); @@ -63,13 +59,5 @@ extern char *of_console_options; extern void irq_trans_init(struct device_node *dp); extern char *build_path_component(struct device_node *dp); -/* SPARC has local implementations */ -extern int of_address_to_resource(struct device_node *dev, int index, - struct resource *r); -#define of_address_to_resource of_address_to_resource - -void __iomem *of_iomap(struct device_node *node, int index); -#define of_iomap of_iomap - #endif /* __KERNEL__ */ #endif /* _SPARC_PROM_H */ diff --git a/arch/sparc/include/asm/sparsemem.h b/arch/sparc/include/asm/sparsemem.h index b99d4e4b6d28..e5e1752d5d78 100644 --- a/arch/sparc/include/asm/sparsemem.h +++ b/arch/sparc/include/asm/sparsemem.h @@ -3,9 +3,11 @@ #ifdef __KERNEL__ +#include <asm/page.h> + #define SECTION_SIZE_BITS 30 -#define MAX_PHYSADDR_BITS 42 -#define MAX_PHYSMEM_BITS 42 +#define MAX_PHYSADDR_BITS MAX_PHYS_ADDRESS_BITS +#define MAX_PHYSMEM_BITS MAX_PHYS_ADDRESS_BITS #endif /* !(__KERNEL__) */ diff --git a/arch/sparc/include/asm/thread_info_32.h b/arch/sparc/include/asm/thread_info_32.h index dd3807599bb9..96efa7adc223 100644 --- a/arch/sparc/include/asm/thread_info_32.h +++ b/arch/sparc/include/asm/thread_info_32.h @@ -105,8 +105,6 @@ register struct thread_info *current_thread_info_reg asm("g6"); #define TI_W_SAVED 0x250 /* #define TI_RESTART_BLOCK 0x25n */ /* Nobody cares */ -#define PREEMPT_ACTIVE 0x4000000 - /* * thread information flag bit numbers */ diff --git a/arch/sparc/include/asm/thread_info_64.h b/arch/sparc/include/asm/thread_info_64.h index d5e504251079..a5f01ac6d0f1 100644 --- a/arch/sparc/include/asm/thread_info_64.h +++ b/arch/sparc/include/asm/thread_info_64.h @@ -111,8 +111,6 @@ struct thread_info { #define THREAD_SHIFT PAGE_SHIFT #endif /* PAGE_SHIFT == 13 */ -#define PREEMPT_ACTIVE 0x10000000 - /* * macros/functions for gaining access to the thread information structure */ @@ -192,7 +190,7 @@ register struct thread_info *current_thread_info_reg asm("g6"); #define TIF_UNALIGNED 5 /* allowed to do unaligned accesses */ /* flag bit 6 is available */ #define TIF_32BIT 7 /* 32-bit binary */ -/* flag bit 8 is available */ +#define TIF_NOHZ 8 /* in adaptive nohz mode */ #define TIF_SECCOMP 9 /* secure computing */ #define TIF_SYSCALL_AUDIT 10 /* syscall auditing active */ #define TIF_SYSCALL_TRACEPOINT 11 /* syscall tracepoint instrumentation */ @@ -210,6 +208,7 @@ register struct thread_info *current_thread_info_reg asm("g6"); #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) #define _TIF_UNALIGNED (1<<TIF_UNALIGNED) #define _TIF_32BIT (1<<TIF_32BIT) +#define _TIF_NOHZ (1<<TIF_NOHZ) #define _TIF_SECCOMP (1<<TIF_SECCOMP) #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) #define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT) diff --git a/arch/sparc/include/asm/tlbflush_64.h b/arch/sparc/include/asm/tlbflush_64.h index f0d6a9700f4c..3c3c89f52643 100644 --- a/arch/sparc/include/asm/tlbflush_64.h +++ b/arch/sparc/include/asm/tlbflush_64.h @@ -1,7 +1,6 @@ #ifndef _SPARC64_TLBFLUSH_H #define _SPARC64_TLBFLUSH_H -#include <linux/mm.h> #include <asm/mmu_context.h> /* TSB flush operations. */ diff --git a/arch/sparc/include/asm/tsb.h b/arch/sparc/include/asm/tsb.h index e696432b950d..2230f80d9fe3 100644 --- a/arch/sparc/include/asm/tsb.h +++ b/arch/sparc/include/asm/tsb.h @@ -142,98 +142,39 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; or REG1, %lo(swapper_pg_dir), REG1; \ sllx VADDR, 64 - (PGDIR_SHIFT + PGDIR_BITS), REG2; \ srlx REG2, 64 - PAGE_SHIFT, REG2; \ - andn REG2, 0x3, REG2; \ - lduw [REG1 + REG2], REG1; \ + andn REG2, 0x7, REG2; \ + ldx [REG1 + REG2], REG1; \ brz,pn REG1, FAIL_LABEL; \ sllx VADDR, 64 - (PMD_SHIFT + PMD_BITS), REG2; \ srlx REG2, 64 - PAGE_SHIFT, REG2; \ - sllx REG1, PGD_PADDR_SHIFT, REG1; \ - andn REG2, 0x3, REG2; \ - lduwa [REG1 + REG2] ASI_PHYS_USE_EC, REG1; \ + andn REG2, 0x7, REG2; \ + ldxa [REG1 + REG2] ASI_PHYS_USE_EC, REG1; \ brz,pn REG1, FAIL_LABEL; \ sllx VADDR, 64 - PMD_SHIFT, REG2; \ - srlx REG2, 64 - (PAGE_SHIFT - 1), REG2; \ - sllx REG1, PMD_PADDR_SHIFT, REG1; \ + srlx REG2, 64 - PAGE_SHIFT, REG2; \ andn REG2, 0x7, REG2; \ add REG1, REG2, REG1; - /* These macros exists only to make the PMD translator below - * easier to read. It hides the ELF section switch for the - * sun4v code patching. - */ -#define OR_PTE_BIT_1INSN(REG, NAME) \ -661: or REG, _PAGE_##NAME##_4U, REG; \ - .section .sun4v_1insn_patch, "ax"; \ - .word 661b; \ - or REG, _PAGE_##NAME##_4V, REG; \ - .previous; - -#define OR_PTE_BIT_2INSN(REG, TMP, NAME) \ -661: sethi %hi(_PAGE_##NAME##_4U), TMP; \ - or REG, TMP, REG; \ - .section .sun4v_2insn_patch, "ax"; \ - .word 661b; \ - mov -1, TMP; \ - or REG, _PAGE_##NAME##_4V, REG; \ - .previous; - - /* Load into REG the PTE value for VALID, CACHE, and SZHUGE. */ -#define BUILD_PTE_VALID_SZHUGE_CACHE(REG) \ -661: sethi %uhi(_PAGE_VALID|_PAGE_SZHUGE_4U), REG; \ - .section .sun4v_1insn_patch, "ax"; \ - .word 661b; \ - sethi %uhi(_PAGE_VALID), REG; \ - .previous; \ - sllx REG, 32, REG; \ -661: or REG, _PAGE_CP_4U|_PAGE_CV_4U, REG; \ - .section .sun4v_1insn_patch, "ax"; \ - .word 661b; \ - or REG, _PAGE_CP_4V|_PAGE_CV_4V|_PAGE_SZHUGE_4V, REG; \ - .previous; - /* PMD has been loaded into REG1, interpret the value, seeing * if it is a HUGE PMD or a normal one. If it is not valid * then jump to FAIL_LABEL. If it is a HUGE PMD, and it * translates to a valid PTE, branch to PTE_LABEL. * - * We translate the PMD by hand, one bit at a time, - * constructing the huge PTE. - * - * So we construct the PTE in REG2 as follows: - * - * 1) Extract the PMD PFN from REG1 and place it into REG2. - * - * 2) Translate PMD protection bits in REG1 into REG2, one bit - * at a time using andcc tests on REG1 and OR's into REG2. - * - * Only two bits to be concerned with here, EXEC and WRITE. - * Now REG1 is freed up and we can use it as a temporary. - * - * 3) Construct the VALID, CACHE, and page size PTE bits in - * REG1, OR with REG2 to form final PTE. + * We have to propagate the 4MB bit of the virtual address + * because we are fabricating 8MB pages using 4MB hw pages. */ #ifdef CONFIG_TRANSPARENT_HUGEPAGE #define USER_PGTABLE_CHECK_PMD_HUGE(VADDR, REG1, REG2, FAIL_LABEL, PTE_LABEL) \ - brz,pn REG1, FAIL_LABEL; \ - andcc REG1, PMD_ISHUGE, %g0; \ - be,pt %xcc, 700f; \ - and REG1, PMD_HUGE_PRESENT|PMD_HUGE_ACCESSED, REG2; \ - cmp REG2, PMD_HUGE_PRESENT|PMD_HUGE_ACCESSED; \ - bne,pn %xcc, FAIL_LABEL; \ - andn REG1, PMD_HUGE_PROTBITS, REG2; \ - sllx REG2, PMD_PADDR_SHIFT, REG2; \ - /* REG2 now holds PFN << PAGE_SHIFT */ \ - andcc REG1, PMD_HUGE_WRITE, %g0; \ - bne,a,pt %xcc, 1f; \ - OR_PTE_BIT_1INSN(REG2, W); \ -1: andcc REG1, PMD_HUGE_EXEC, %g0; \ - be,pt %xcc, 1f; \ - nop; \ - OR_PTE_BIT_2INSN(REG2, REG1, EXEC); \ - /* REG1 can now be clobbered, build final PTE */ \ -1: BUILD_PTE_VALID_SZHUGE_CACHE(REG1); \ - ba,pt %xcc, PTE_LABEL; \ - or REG1, REG2, REG1; \ + brz,pn REG1, FAIL_LABEL; \ + sethi %uhi(_PAGE_PMD_HUGE), REG2; \ + sllx REG2, 32, REG2; \ + andcc REG1, REG2, %g0; \ + be,pt %xcc, 700f; \ + sethi %hi(4 * 1024 * 1024), REG2; \ + andn REG1, REG2, REG1; \ + and VADDR, REG2, REG2; \ + brlz,pt REG1, PTE_LABEL; \ + or REG1, REG2, REG1; \ 700: #else #define USER_PGTABLE_CHECK_PMD_HUGE(VADDR, REG1, REG2, FAIL_LABEL, PTE_LABEL) \ @@ -253,18 +194,16 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; #define USER_PGTABLE_WALK_TL1(VADDR, PHYS_PGD, REG1, REG2, FAIL_LABEL) \ sllx VADDR, 64 - (PGDIR_SHIFT + PGDIR_BITS), REG2; \ srlx REG2, 64 - PAGE_SHIFT, REG2; \ - andn REG2, 0x3, REG2; \ - lduwa [PHYS_PGD + REG2] ASI_PHYS_USE_EC, REG1; \ + andn REG2, 0x7, REG2; \ + ldxa [PHYS_PGD + REG2] ASI_PHYS_USE_EC, REG1; \ brz,pn REG1, FAIL_LABEL; \ sllx VADDR, 64 - (PMD_SHIFT + PMD_BITS), REG2; \ srlx REG2, 64 - PAGE_SHIFT, REG2; \ - sllx REG1, PGD_PADDR_SHIFT, REG1; \ - andn REG2, 0x3, REG2; \ - lduwa [REG1 + REG2] ASI_PHYS_USE_EC, REG1; \ + andn REG2, 0x7, REG2; \ + ldxa [REG1 + REG2] ASI_PHYS_USE_EC, REG1; \ USER_PGTABLE_CHECK_PMD_HUGE(VADDR, REG1, REG2, FAIL_LABEL, 800f) \ sllx VADDR, 64 - PMD_SHIFT, REG2; \ - srlx REG2, 64 - (PAGE_SHIFT - 1), REG2; \ - sllx REG1, PMD_PADDR_SHIFT, REG1; \ + srlx REG2, 64 - PAGE_SHIFT, REG2; \ andn REG2, 0x7, REG2; \ add REG1, REG2, REG1; \ ldxa [REG1] ASI_PHYS_USE_EC, REG1; \ diff --git a/arch/sparc/include/uapi/asm/errno.h b/arch/sparc/include/uapi/asm/errno.h index c351aba997b7..20423e172853 100644 --- a/arch/sparc/include/uapi/asm/errno.h +++ b/arch/sparc/include/uapi/asm/errno.h @@ -40,7 +40,7 @@ #define EPROCLIM 67 /* SUNOS: Too many processes */ #define EUSERS 68 /* Too many users */ #define EDQUOT 69 /* Quota exceeded */ -#define ESTALE 70 /* Stale NFS file handle */ +#define ESTALE 70 /* Stale file handle */ #define EREMOTE 71 /* Object is remote */ #define ENOSTR 72 /* Device not a stream */ #define ETIME 73 /* Timer expired */ diff --git a/arch/sparc/include/uapi/asm/socket.h b/arch/sparc/include/uapi/asm/socket.h index 4e1d66c3ce71..0f21e9a5ca18 100644 --- a/arch/sparc/include/uapi/asm/socket.h +++ b/arch/sparc/include/uapi/asm/socket.h @@ -72,6 +72,8 @@ #define SO_BUSY_POLL 0x0030 +#define SO_MAX_PACING_RATE 0x0031 + /* Security levels - as per NRL IPv6 - don't actually do anything */ #define SO_SECURITY_AUTHENTICATION 0x5001 #define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002 diff --git a/arch/sparc/kernel/entry.h b/arch/sparc/kernel/entry.h index 9c179fbfb219..140966fbd303 100644 --- a/arch/sparc/kernel/entry.h +++ b/arch/sparc/kernel/entry.h @@ -88,7 +88,6 @@ extern asmlinkage void syscall_trace_leave(struct pt_regs *regs); extern void bad_trap_tl1(struct pt_regs *regs, long lvl); -extern void do_fpe_common(struct pt_regs *regs); extern void do_fpieee(struct pt_regs *regs); extern void do_fpother(struct pt_regs *regs); extern void do_tof(struct pt_regs *regs); diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c index d4840cec2c55..666193f4e8bb 100644 --- a/arch/sparc/kernel/irq_64.c +++ b/arch/sparc/kernel/irq_64.c @@ -698,30 +698,19 @@ void __irq_entry handler_irq(int pil, struct pt_regs *regs) set_irq_regs(old_regs); } -void do_softirq(void) +void do_softirq_own_stack(void) { - unsigned long flags; - - if (in_interrupt()) - return; - - local_irq_save(flags); + void *orig_sp, *sp = softirq_stack[smp_processor_id()]; - if (local_softirq_pending()) { - void *orig_sp, *sp = softirq_stack[smp_processor_id()]; - - sp += THREAD_SIZE - 192 - STACK_BIAS; - - __asm__ __volatile__("mov %%sp, %0\n\t" - "mov %1, %%sp" - : "=&r" (orig_sp) - : "r" (sp)); - __do_softirq(); - __asm__ __volatile__("mov %0, %%sp" - : : "r" (orig_sp)); - } + sp += THREAD_SIZE - 192 - STACK_BIAS; - local_irq_restore(flags); + __asm__ __volatile__("mov %%sp, %0\n\t" + "mov %1, %%sp" + : "=&r" (orig_sp) + : "r" (sp)); + __do_softirq(); + __asm__ __volatile__("mov %0, %%sp" + : : "r" (orig_sp)); } #ifdef CONFIG_HOTPLUG_CPU diff --git a/arch/sparc/kernel/kgdb_64.c b/arch/sparc/kernel/kgdb_64.c index 53c0a82e6030..60b19f50c80a 100644 --- a/arch/sparc/kernel/kgdb_64.c +++ b/arch/sparc/kernel/kgdb_64.c @@ -159,11 +159,12 @@ int kgdb_arch_handle_exception(int e_vector, int signo, int err_code, asmlinkage void kgdb_trap(unsigned long trap_level, struct pt_regs *regs) { + enum ctx_state prev_state = exception_enter(); unsigned long flags; if (user_mode(regs)) { bad_trap(regs, trap_level); - return; + goto out; } flushw_all(); @@ -171,6 +172,8 @@ asmlinkage void kgdb_trap(unsigned long trap_level, struct pt_regs *regs) local_irq_save(flags); kgdb_handle_exception(0x172, SIGTRAP, 0, regs); local_irq_restore(flags); +out: + exception_exit(prev_state); } int kgdb_arch_init(void) diff --git a/arch/sparc/kernel/kprobes.c b/arch/sparc/kernel/kprobes.c index e72212148d2a..1b0973503197 100644 --- a/arch/sparc/kernel/kprobes.c +++ b/arch/sparc/kernel/kprobes.c @@ -8,6 +8,7 @@ #include <linux/module.h> #include <linux/kdebug.h> #include <linux/slab.h> +#include <linux/context_tracking.h> #include <asm/signal.h> #include <asm/cacheflush.h> #include <asm/uaccess.h> @@ -349,7 +350,7 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) case KPROBE_HIT_SSDONE: /* * We increment the nmissed count for accounting, - * we can also use npre/npostfault count for accouting + * we can also use npre/npostfault count for accounting * these specific fault cases. */ kprobes_inc_nmissed_count(cur); @@ -418,12 +419,14 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, asmlinkage void __kprobes kprobe_trap(unsigned long trap_level, struct pt_regs *regs) { + enum ctx_state prev_state = exception_enter(); + BUG_ON(trap_level != 0x170 && trap_level != 0x171); if (user_mode(regs)) { local_irq_enable(); bad_trap(regs, trap_level); - return; + goto out; } /* trap_level == 0x170 --> ta 0x70 @@ -433,6 +436,8 @@ asmlinkage void __kprobes kprobe_trap(unsigned long trap_level, (trap_level == 0x170) ? "debug" : "debug_2", regs, 0, trap_level, SIGTRAP) != NOTIFY_STOP) bad_trap(regs, trap_level); +out: + exception_exit(prev_state); } /* Jprobes support. */ diff --git a/arch/sparc/kernel/ktlb.S b/arch/sparc/kernel/ktlb.S index fde5a419cf27..542e96ac4d39 100644 --- a/arch/sparc/kernel/ktlb.S +++ b/arch/sparc/kernel/ktlb.S @@ -153,12 +153,19 @@ kvmap_dtlb_tsb4m_miss: /* Clear the PAGE_OFFSET top virtual bits, shift * down to get PFN, and make sure PFN is in range. */ - sllx %g4, 21, %g5 +661: sllx %g4, 0, %g5 + .section .page_offset_shift_patch, "ax" + .word 661b + .previous /* Check to see if we know about valid memory at the 4MB * chunk this physical address will reside within. */ - srlx %g5, 21 + 41, %g2 +661: srlx %g5, MAX_PHYS_ADDRESS_BITS, %g2 + .section .page_offset_shift_patch, "ax" + .word 661b + .previous + brnz,pn %g2, kvmap_dtlb_longpath nop @@ -176,7 +183,11 @@ valid_addr_bitmap_patch: or %g7, %lo(sparc64_valid_addr_bitmap), %g7 .previous - srlx %g5, 21 + 22, %g2 +661: srlx %g5, ILOG2_4MB, %g2 + .section .page_offset_shift_patch, "ax" + .word 661b + .previous + srlx %g2, 6, %g5 and %g2, 63, %g2 sllx %g5, 3, %g5 @@ -189,9 +200,18 @@ valid_addr_bitmap_patch: 2: sethi %hi(kpte_linear_bitmap), %g2 /* Get the 256MB physical address index. */ - sllx %g4, 21, %g5 +661: sllx %g4, 0, %g5 + .section .page_offset_shift_patch, "ax" + .word 661b + .previous + or %g2, %lo(kpte_linear_bitmap), %g2 - srlx %g5, 21 + 28, %g5 + +661: srlx %g5, ILOG2_256MB, %g5 + .section .page_offset_shift_patch, "ax" + .word 661b + .previous + and %g5, (32 - 1), %g7 /* Divide by 32 to get the offset into the bitmask. */ diff --git a/arch/sparc/kernel/module.c b/arch/sparc/kernel/module.c index 4435488ebe25..97655e0fd243 100644 --- a/arch/sparc/kernel/module.c +++ b/arch/sparc/kernel/module.c @@ -29,7 +29,7 @@ static void *module_map(unsigned long size) if (PAGE_ALIGN(size) > MODULES_LEN) return NULL; return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END, - GFP_KERNEL, PAGE_KERNEL, -1, + GFP_KERNEL, PAGE_KERNEL, NUMA_NO_NODE, __builtin_return_address(0)); } #else diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index bc4d3f5d2e5d..cb021453de2a 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -398,8 +398,8 @@ static void apb_fake_ranges(struct pci_dev *dev, apb_calc_first_last(map, &first, &last); res = bus->resource[1]; res->flags = IORESOURCE_MEM; - region.start = (first << 21); - region.end = (last << 21) + ((1 << 21) - 1); + region.start = (first << 29); + region.end = (last << 29) + ((1 << 29) - 1); pcibios_bus_to_resource(dev, res, ®ion); } diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c index baebab215492..32a280ec38c1 100644 --- a/arch/sparc/kernel/process_64.c +++ b/arch/sparc/kernel/process_64.c @@ -31,6 +31,7 @@ #include <linux/elfcore.h> #include <linux/sysrq.h> #include <linux/nmi.h> +#include <linux/context_tracking.h> #include <asm/uaccess.h> #include <asm/page.h> @@ -557,6 +558,7 @@ void fault_in_user_windows(void) barf: set_thread_wsaved(window + 1); + user_exit(); do_exit(SIGILL); } diff --git a/arch/sparc/kernel/prom_64.c b/arch/sparc/kernel/prom_64.c index d397d7fc5c28..6b39125eb927 100644 --- a/arch/sparc/kernel/prom_64.c +++ b/arch/sparc/kernel/prom_64.c @@ -373,6 +373,59 @@ static const char *get_mid_prop(void) return (tlb_type == spitfire ? "upa-portid" : "portid"); } +bool arch_find_n_match_cpu_physical_id(struct device_node *cpun, + int cpu, unsigned int *thread) +{ + const char *mid_prop = get_mid_prop(); + int this_cpu_id; + + /* On hypervisor based platforms we interrogate the 'reg' + * property. On everything else we look for a 'upa-portis', + * 'portid', or 'cpuid' property. + */ + + if (tlb_type == hypervisor) { + struct property *prop = of_find_property(cpun, "reg", NULL); + u32 *regs; + + if (!prop) { + pr_warn("CPU node missing reg property\n"); + return false; + } + regs = prop->value; + this_cpu_id = regs[0] & 0x0fffffff; + } else { + this_cpu_id = of_getintprop_default(cpun, mid_prop, -1); + + if (this_cpu_id < 0) { + mid_prop = "cpuid"; + this_cpu_id = of_getintprop_default(cpun, mid_prop, -1); + } + if (this_cpu_id < 0) { + pr_warn("CPU node missing cpu ID property\n"); + return false; + } + } + if (this_cpu_id == cpu) { + if (thread) { + int proc_id = cpu_data(cpu).proc_id; + + /* On sparc64, the cpu thread information is obtained + * either from OBP or the machine description. We've + * actually probed this information already long before + * this interface gets called so instead of interrogating + * both the OF node and the MDESC again, just use what + * we discovered already. + */ + if (proc_id < 0) + proc_id = 0; + *thread = proc_id; + } + return true; + } + return false; +} + static void *of_iterate_over_cpus(void *(*func)(struct device_node *, int, int), int arg) { struct device_node *dp; diff --git a/arch/sparc/kernel/ptrace_64.c b/arch/sparc/kernel/ptrace_64.c index 773c1f2983ce..c13c9f25d83a 100644 --- a/arch/sparc/kernel/ptrace_64.c +++ b/arch/sparc/kernel/ptrace_64.c @@ -27,6 +27,7 @@ #include <trace/syscall.h> #include <linux/compat.h> #include <linux/elf.h> +#include <linux/context_tracking.h> #include <asm/asi.h> #include <asm/pgtable.h> @@ -1066,6 +1067,9 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs) /* do the secure computing check first */ secure_computing_strict(regs->u_regs[UREG_G1]); + if (test_thread_flag(TIF_NOHZ)) + user_exit(); + if (test_thread_flag(TIF_SYSCALL_TRACE)) ret = tracehook_report_syscall_entry(regs); @@ -1086,6 +1090,9 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs) asmlinkage void syscall_trace_leave(struct pt_regs *regs) { + if (test_thread_flag(TIF_NOHZ)) + user_exit(); + audit_syscall_exit(regs); if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) @@ -1093,4 +1100,7 @@ asmlinkage void syscall_trace_leave(struct pt_regs *regs) if (test_thread_flag(TIF_SYSCALL_TRACE)) tracehook_report_syscall_exit(regs, 0); + + if (test_thread_flag(TIF_NOHZ)) + user_enter(); } diff --git a/arch/sparc/kernel/rtrap_64.S b/arch/sparc/kernel/rtrap_64.S index afa2a9e3d0a0..39f0c662f4c8 100644 --- a/arch/sparc/kernel/rtrap_64.S +++ b/arch/sparc/kernel/rtrap_64.S @@ -18,10 +18,16 @@ #define RTRAP_PSTATE_IRQOFF (PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV) #define RTRAP_PSTATE_AG_IRQOFF (PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV|PSTATE_AG) +#ifdef CONFIG_CONTEXT_TRACKING +# define SCHEDULE_USER schedule_user +#else +# define SCHEDULE_USER schedule +#endif + .text .align 32 __handle_preemption: - call schedule + call SCHEDULE_USER wrpr %g0, RTRAP_PSTATE, %pstate ba,pt %xcc, __handle_preemption_continue wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate @@ -306,12 +312,10 @@ to_kernel: nop cmp %l4, 0 bne,pn %xcc, kern_fpucheck - sethi %hi(PREEMPT_ACTIVE), %l6 - stw %l6, [%g6 + TI_PRE_COUNT] - call schedule + nop + call preempt_schedule_irq nop ba,pt %xcc, rtrap - stw %g0, [%g6 + TI_PRE_COUNT] #endif kern_fpucheck: ldub [%g6 + TI_FPDEPTH], %l5 brz,pt %l5, rt_continue diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c index b524f91dd0e5..ee789d2ef05d 100644 --- a/arch/sparc/kernel/signal32.c +++ b/arch/sparc/kernel/signal32.c @@ -68,7 +68,7 @@ struct rt_signal_frame32 { /* __siginfo_rwin_t * */u32 rwin_save; } __attribute__((aligned(8))); -int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from) +int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from) { int err; diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c index 35923e8abd82..cd91d010e6d3 100644 --- a/arch/sparc/kernel/signal_64.c +++ b/arch/sparc/kernel/signal_64.c @@ -23,6 +23,7 @@ #include <linux/tty.h> #include <linux/binfmts.h> #include <linux/bitops.h> +#include <linux/context_tracking.h> #include <asm/uaccess.h> #include <asm/ptrace.h> @@ -43,6 +44,7 @@ asmlinkage void sparc64_set_context(struct pt_regs *regs) { struct ucontext __user *ucp = (struct ucontext __user *) regs->u_regs[UREG_I0]; + enum ctx_state prev_state = exception_enter(); mc_gregset_t __user *grp; unsigned long pc, npc, tstate; unsigned long fp, i7; @@ -129,16 +131,19 @@ asmlinkage void sparc64_set_context(struct pt_regs *regs) } if (err) goto do_sigsegv; - +out: + exception_exit(prev_state); return; do_sigsegv: force_sig(SIGSEGV, current); + goto out; } asmlinkage void sparc64_get_context(struct pt_regs *regs) { struct ucontext __user *ucp = (struct ucontext __user *) regs->u_regs[UREG_I0]; + enum ctx_state prev_state = exception_enter(); mc_gregset_t __user *grp; mcontext_t __user *mcp; unsigned long fp, i7; @@ -220,10 +225,12 @@ asmlinkage void sparc64_get_context(struct pt_regs *regs) } if (err) goto do_sigsegv; - +out: + exception_exit(prev_state); return; do_sigsegv: force_sig(SIGSEGV, current); + goto out; } struct rt_signal_frame { @@ -528,11 +535,13 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long thread_info_flags) { + user_exit(); if (thread_info_flags & _TIF_SIGPENDING) do_signal(regs, orig_i0); if (thread_info_flags & _TIF_NOTIFY_RESUME) { clear_thread_flag(TIF_NOTIFY_RESUME); tracehook_notify_resume(regs); } + user_enter(); } diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c index e142545244f2..b66a5338231e 100644 --- a/arch/sparc/kernel/smp_64.c +++ b/arch/sparc/kernel/smp_64.c @@ -1399,8 +1399,13 @@ void __init smp_cpus_done(unsigned int max_cpus) void smp_send_reschedule(int cpu) { - xcall_deliver((u64) &xcall_receive_signal, 0, 0, - cpumask_of(cpu)); + if (cpu == smp_processor_id()) { + WARN_ON_ONCE(preemptible()); + set_softint(1 << PIL_SMP_RECEIVE_SIGNAL); + } else { + xcall_deliver((u64) &xcall_receive_signal, + 0, 0, cpumask_of(cpu)); + } } void __irq_entry smp_receive_signal_client(int irq, struct pt_regs *regs) diff --git a/arch/sparc/kernel/sun4v_tlb_miss.S b/arch/sparc/kernel/sun4v_tlb_miss.S index bde867fd71e8..e0c09bf85610 100644 --- a/arch/sparc/kernel/sun4v_tlb_miss.S +++ b/arch/sparc/kernel/sun4v_tlb_miss.S @@ -182,7 +182,7 @@ sun4v_tsb_miss_common: cmp %g5, -1 be,pt %xcc, 80f nop - COMPUTE_TSB_PTR(%g5, %g4, HPAGE_SHIFT, %g2, %g7) + COMPUTE_TSB_PTR(%g5, %g4, REAL_HPAGE_SHIFT, %g2, %g7) /* That clobbered %g2, reload it. */ ldxa [%g0] ASI_SCRATCHPAD, %g2 diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c index 51561b8b15ba..beb0b5a5f21f 100644 --- a/arch/sparc/kernel/sys_sparc_64.c +++ b/arch/sparc/kernel/sys_sparc_64.c @@ -24,6 +24,7 @@ #include <linux/personality.h> #include <linux/random.h> #include <linux/export.h> +#include <linux/context_tracking.h> #include <asm/uaccess.h> #include <asm/utrap.h> @@ -39,9 +40,6 @@ asmlinkage unsigned long sys_getpagesize(void) return PAGE_SIZE; } -#define VA_EXCLUDE_START (0x0000080000000000UL - (1UL << 32UL)) -#define VA_EXCLUDE_END (0xfffff80000000000UL + (1UL << 32UL)) - /* Does addr --> addr+len fall within 4GB of the VA-space hole or * overflow past the end of the 64-bit address space? */ @@ -499,6 +497,7 @@ asmlinkage unsigned long c_sys_nis_syscall(struct pt_regs *regs) asmlinkage void sparc_breakpoint(struct pt_regs *regs) { + enum ctx_state prev_state = exception_enter(); siginfo_t info; if (test_thread_flag(TIF_32BIT)) { @@ -517,6 +516,7 @@ asmlinkage void sparc_breakpoint(struct pt_regs *regs) #ifdef DEBUG_SPARC_BREAKPOINT printk ("TRAP: Returning to space: PC=%lx nPC=%lx\n", regs->tpc, regs->tnpc); #endif + exception_exit(prev_state); } extern void check_pending(int signum); diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S index d950197a17e1..87729fff13b9 100644 --- a/arch/sparc/kernel/syscalls.S +++ b/arch/sparc/kernel/syscalls.S @@ -52,7 +52,7 @@ sys32_rt_sigreturn: #endif .align 32 1: ldx [%g6 + TI_FLAGS], %l5 - andcc %l5, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %g0 + andcc %l5, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT|_TIF_NOHZ), %g0 be,pt %icc, rtrap nop call syscall_trace_leave @@ -184,7 +184,7 @@ linux_sparc_syscall32: srl %i3, 0, %o3 ! IEU0 srl %i2, 0, %o2 ! IEU0 Group - andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %g0 + andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT|_TIF_NOHZ), %g0 bne,pn %icc, linux_syscall_trace32 ! CTI mov %i0, %l5 ! IEU1 5: call %l7 ! CTI Group brk forced @@ -207,7 +207,7 @@ linux_sparc_syscall: mov %i3, %o3 ! IEU1 mov %i4, %o4 ! IEU0 Group - andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %g0 + andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT|_TIF_NOHZ), %g0 bne,pn %icc, linux_syscall_trace ! CTI Group mov %i0, %l5 ! IEU0 2: call %l7 ! CTI Group brk forced @@ -223,7 +223,7 @@ ret_sys_call: cmp %o0, -ERESTART_RESTARTBLOCK bgeu,pn %xcc, 1f - andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %g0 + andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT|_TIF_NOHZ), %g0 ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc 2: diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c index b3f833ab90eb..4ced92f05358 100644 --- a/arch/sparc/kernel/traps_64.c +++ b/arch/sparc/kernel/traps_64.c @@ -20,6 +20,7 @@ #include <linux/ftrace.h> #include <linux/reboot.h> #include <linux/gfp.h> +#include <linux/context_tracking.h> #include <asm/smp.h> #include <asm/delay.h> @@ -186,11 +187,12 @@ EXPORT_SYMBOL_GPL(unregister_dimm_printer); void spitfire_insn_access_exception(struct pt_regs *regs, unsigned long sfsr, unsigned long sfar) { + enum ctx_state prev_state = exception_enter(); siginfo_t info; if (notify_die(DIE_TRAP, "instruction access exception", regs, 0, 0x8, SIGTRAP) == NOTIFY_STOP) - return; + goto out; if (regs->tstate & TSTATE_PRIV) { printk("spitfire_insn_access_exception: SFSR[%016lx] " @@ -207,6 +209,8 @@ void spitfire_insn_access_exception(struct pt_regs *regs, unsigned long sfsr, un info.si_addr = (void __user *)regs->tpc; info.si_trapno = 0; force_sig_info(SIGSEGV, &info, current); +out: + exception_exit(prev_state); } void spitfire_insn_access_exception_tl1(struct pt_regs *regs, unsigned long sfsr, unsigned long sfar) @@ -260,11 +264,12 @@ void sun4v_insn_access_exception_tl1(struct pt_regs *regs, unsigned long addr, u void spitfire_data_access_exception(struct pt_regs *regs, unsigned long sfsr, unsigned long sfar) { + enum ctx_state prev_state = exception_enter(); siginfo_t info; if (notify_die(DIE_TRAP, "data access exception", regs, 0, 0x30, SIGTRAP) == NOTIFY_STOP) - return; + goto out; if (regs->tstate & TSTATE_PRIV) { /* Test if this comes from uaccess places. */ @@ -280,7 +285,7 @@ void spitfire_data_access_exception(struct pt_regs *regs, unsigned long sfsr, un #endif regs->tpc = entry->fixup; regs->tnpc = regs->tpc + 4; - return; + goto out; } /* Shit... */ printk("spitfire_data_access_exception: SFSR[%016lx] " @@ -294,6 +299,8 @@ void spitfire_data_access_exception(struct pt_regs *regs, unsigned long sfsr, un info.si_addr = (void __user *)sfar; info.si_trapno = 0; force_sig_info(SIGSEGV, &info, current); +out: + exception_exit(prev_state); } void spitfire_data_access_exception_tl1(struct pt_regs *regs, unsigned long sfsr, unsigned long sfar) @@ -1994,6 +2001,7 @@ static void sun4v_log_error(struct pt_regs *regs, struct sun4v_error_entry *ent, */ void sun4v_resum_error(struct pt_regs *regs, unsigned long offset) { + enum ctx_state prev_state = exception_enter(); struct sun4v_error_entry *ent, local_copy; struct trap_per_cpu *tb; unsigned long paddr; @@ -2022,12 +2030,14 @@ void sun4v_resum_error(struct pt_regs *regs, unsigned long offset) pr_info("Shutdown request, %u seconds...\n", local_copy.err_secs); orderly_poweroff(true); - return; + goto out; } sun4v_log_error(regs, &local_copy, cpu, KERN_ERR "RESUMABLE ERROR", &sun4v_resum_oflow_cnt); +out: + exception_exit(prev_state); } /* If we try to printk() we'll probably make matters worse, by trying @@ -2152,7 +2162,7 @@ void hypervisor_tlbop_error_xcall(unsigned long err, unsigned long op) err, op); } -void do_fpe_common(struct pt_regs *regs) +static void do_fpe_common(struct pt_regs *regs) { if (regs->tstate & TSTATE_PRIV) { regs->tpc = regs->tnpc; @@ -2188,23 +2198,28 @@ void do_fpe_common(struct pt_regs *regs) void do_fpieee(struct pt_regs *regs) { + enum ctx_state prev_state = exception_enter(); + if (notify_die(DIE_TRAP, "fpu exception ieee", regs, 0, 0x24, SIGFPE) == NOTIFY_STOP) - return; + goto out; do_fpe_common(regs); +out: + exception_exit(prev_state); } extern int do_mathemu(struct pt_regs *, struct fpustate *, bool); void do_fpother(struct pt_regs *regs) { + enum ctx_state prev_state = exception_enter(); struct fpustate *f = FPUSTATE; int ret = 0; if (notify_die(DIE_TRAP, "fpu exception other", regs, 0, 0x25, SIGFPE) == NOTIFY_STOP) - return; + goto out; switch ((current_thread_info()->xfsr[0] & 0x1c000)) { case (2 << 14): /* unfinished_FPop */ @@ -2213,17 +2228,20 @@ void do_fpother(struct pt_regs *regs) break; } if (ret) - return; + goto out; do_fpe_common(regs); +out: + exception_exit(prev_state); } void do_tof(struct pt_regs *regs) { + enum ctx_state prev_state = exception_enter(); siginfo_t info; if (notify_die(DIE_TRAP, "tagged arithmetic overflow", regs, 0, 0x26, SIGEMT) == NOTIFY_STOP) - return; + goto out; if (regs->tstate & TSTATE_PRIV) die_if_kernel("Penguin overflow trap from kernel mode", regs); @@ -2237,15 +2255,18 @@ void do_tof(struct pt_regs *regs) info.si_addr = (void __user *)regs->tpc; info.si_trapno = 0; force_sig_info(SIGEMT, &info, current); +out: + exception_exit(prev_state); } void do_div0(struct pt_regs *regs) { + enum ctx_state prev_state = exception_enter(); siginfo_t info; if (notify_die(DIE_TRAP, "integer division by zero", regs, 0, 0x28, SIGFPE) == NOTIFY_STOP) - return; + goto out; if (regs->tstate & TSTATE_PRIV) die_if_kernel("TL0: Kernel divide by zero.", regs); @@ -2259,6 +2280,8 @@ void do_div0(struct pt_regs *regs) info.si_addr = (void __user *)regs->tpc; info.si_trapno = 0; force_sig_info(SIGFPE, &info, current); +out: + exception_exit(prev_state); } static void instruction_dump(unsigned int *pc) @@ -2415,6 +2438,7 @@ extern int handle_ldf_stq(u32 insn, struct pt_regs *regs); void do_illegal_instruction(struct pt_regs *regs) { + enum ctx_state prev_state = exception_enter(); unsigned long pc = regs->tpc; unsigned long tstate = regs->tstate; u32 insn; @@ -2422,7 +2446,7 @@ void do_illegal_instruction(struct pt_regs *regs) if (notify_die(DIE_TRAP, "illegal instruction", regs, 0, 0x10, SIGILL) == NOTIFY_STOP) - return; + goto out; if (tstate & TSTATE_PRIV) die_if_kernel("Kernel illegal instruction", regs); @@ -2431,14 +2455,14 @@ void do_illegal_instruction(struct pt_regs *regs) if (get_user(insn, (u32 __user *) pc) != -EFAULT) { if ((insn & 0xc1ffc000) == 0x81700000) /* POPC */ { if (handle_popc(insn, regs)) - return; + goto out; } else if ((insn & 0xc1580000) == 0xc1100000) /* LDQ/STQ */ { if (handle_ldf_stq(insn, regs)) - return; + goto out; } else if (tlb_type == hypervisor) { if ((insn & VIS_OPCODE_MASK) == VIS_OPCODE_VAL) { if (!vis_emul(regs, insn)) - return; + goto out; } else { struct fpustate *f = FPUSTATE; @@ -2448,7 +2472,7 @@ void do_illegal_instruction(struct pt_regs *regs) * Trap in the %fsr to unimplemented_FPop. */ if (do_mathemu(regs, f, true)) - return; + goto out; } } } @@ -2458,21 +2482,24 @@ void do_illegal_instruction(struct pt_regs *regs) info.si_addr = (void __user *)pc; info.si_trapno = 0; force_sig_info(SIGILL, &info, current); +out: + exception_exit(prev_state); } extern void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn); void mem_address_unaligned(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr) { + enum ctx_state prev_state = exception_enter(); siginfo_t info; if (notify_die(DIE_TRAP, "memory address unaligned", regs, 0, 0x34, SIGSEGV) == NOTIFY_STOP) - return; + goto out; if (regs->tstate & TSTATE_PRIV) { kernel_unaligned_trap(regs, *((unsigned int *)regs->tpc)); - return; + goto out; } info.si_signo = SIGBUS; info.si_errno = 0; @@ -2480,6 +2507,8 @@ void mem_address_unaligned(struct pt_regs *regs, unsigned long sfar, unsigned lo info.si_addr = (void __user *)sfar; info.si_trapno = 0; force_sig_info(SIGBUS, &info, current); +out: + exception_exit(prev_state); } void sun4v_do_mna(struct pt_regs *regs, unsigned long addr, unsigned long type_ctx) @@ -2504,11 +2533,12 @@ void sun4v_do_mna(struct pt_regs *regs, unsigned long addr, unsigned long type_c void do_privop(struct pt_regs *regs) { + enum ctx_state prev_state = exception_enter(); siginfo_t info; if (notify_die(DIE_TRAP, "privileged operation", regs, 0, 0x11, SIGILL) == NOTIFY_STOP) - return; + goto out; if (test_thread_flag(TIF_32BIT)) { regs->tpc &= 0xffffffff; @@ -2520,6 +2550,8 @@ void do_privop(struct pt_regs *regs) info.si_addr = (void __user *)regs->tpc; info.si_trapno = 0; force_sig_info(SIGILL, &info, current); +out: + exception_exit(prev_state); } void do_privact(struct pt_regs *regs) @@ -2530,99 +2562,116 @@ void do_privact(struct pt_regs *regs) /* Trap level 1 stuff or other traps we should never see... */ void do_cee(struct pt_regs *regs) { + exception_enter(); die_if_kernel("TL0: Cache Error Exception", regs); } void do_cee_tl1(struct pt_regs *regs) { + exception_enter(); dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); die_if_kernel("TL1: Cache Error Exception", regs); } void do_dae_tl1(struct pt_regs *regs) { + exception_enter(); dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); die_if_kernel("TL1: Data Access Exception", regs); } void do_iae_tl1(struct pt_regs *regs) { + exception_enter(); dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); die_if_kernel("TL1: Instruction Access Exception", regs); } void do_div0_tl1(struct pt_regs *regs) { + exception_enter(); dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); die_if_kernel("TL1: DIV0 Exception", regs); } void do_fpdis_tl1(struct pt_regs *regs) { + exception_enter(); dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); die_if_kernel("TL1: FPU Disabled", regs); } void do_fpieee_tl1(struct pt_regs *regs) { + exception_enter(); dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); die_if_kernel("TL1: FPU IEEE Exception", regs); } void do_fpother_tl1(struct pt_regs *regs) { + exception_enter(); dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); die_if_kernel("TL1: FPU Other Exception", regs); } void do_ill_tl1(struct pt_regs *regs) { + exception_enter(); dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); die_if_kernel("TL1: Illegal Instruction Exception", regs); } void do_irq_tl1(struct pt_regs *regs) { + exception_enter(); dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); die_if_kernel("TL1: IRQ Exception", regs); } void do_lddfmna_tl1(struct pt_regs *regs) { + exception_enter(); dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); die_if_kernel("TL1: LDDF Exception", regs); } void do_stdfmna_tl1(struct pt_regs *regs) { + exception_enter(); dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); die_if_kernel("TL1: STDF Exception", regs); } void do_paw(struct pt_regs *regs) { + exception_enter(); die_if_kernel("TL0: Phys Watchpoint Exception", regs); } void do_paw_tl1(struct pt_regs *regs) { + exception_enter(); dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); die_if_kernel("TL1: Phys Watchpoint Exception", regs); } void do_vaw(struct pt_regs *regs) { + exception_enter(); die_if_kernel("TL0: Virt Watchpoint Exception", regs); } void do_vaw_tl1(struct pt_regs *regs) { + exception_enter(); dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); die_if_kernel("TL1: Virt Watchpoint Exception", regs); } void do_tof_tl1(struct pt_regs *regs) { + exception_enter(); dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); die_if_kernel("TL1: Tag Overflow Exception", regs); } diff --git a/arch/sparc/kernel/tsb.S b/arch/sparc/kernel/tsb.S index a313e4a9399b..14158d40ba76 100644 --- a/arch/sparc/kernel/tsb.S +++ b/arch/sparc/kernel/tsb.S @@ -75,7 +75,7 @@ tsb_miss_page_table_walk: mov 512, %g7 andn %g5, 0x7, %g5 sllx %g7, %g6, %g7 - srlx %g4, HPAGE_SHIFT, %g6 + srlx %g4, REAL_HPAGE_SHIFT, %g6 sub %g7, 1, %g7 and %g6, %g7, %g6 sllx %g6, 4, %g6 diff --git a/arch/sparc/kernel/unaligned_64.c b/arch/sparc/kernel/unaligned_64.c index 8201c25e7669..3c1a7cb31579 100644 --- a/arch/sparc/kernel/unaligned_64.c +++ b/arch/sparc/kernel/unaligned_64.c @@ -21,9 +21,12 @@ #include <linux/bitops.h> #include <linux/perf_event.h> #include <linux/ratelimit.h> +#include <linux/context_tracking.h> #include <asm/fpumacro.h> #include <asm/cacheflush.h> +#include "entry.h" + enum direction { load, /* ld, ldd, ldh, ldsh */ store, /* st, std, sth, stsh */ @@ -418,9 +421,6 @@ int handle_popc(u32 insn, struct pt_regs *regs) extern void do_fpother(struct pt_regs *regs); extern void do_privact(struct pt_regs *regs); -extern void spitfire_data_access_exception(struct pt_regs *regs, - unsigned long sfsr, - unsigned long sfar); extern void sun4v_data_access_exception(struct pt_regs *regs, unsigned long addr, unsigned long type_ctx); @@ -578,6 +578,7 @@ void handle_ld_nf(u32 insn, struct pt_regs *regs) void handle_lddfmna(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr) { + enum ctx_state prev_state = exception_enter(); unsigned long pc = regs->tpc; unsigned long tstate = regs->tstate; u32 insn; @@ -632,13 +633,16 @@ daex: sun4v_data_access_exception(regs, sfar, sfsr); else spitfire_data_access_exception(regs, sfsr, sfar); - return; + goto out; } advance(regs); +out: + exception_exit(prev_state); } void handle_stdfmna(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr) { + enum ctx_state prev_state = exception_enter(); unsigned long pc = regs->tpc; unsigned long tstate = regs->tstate; u32 insn; @@ -680,7 +684,9 @@ daex: sun4v_data_access_exception(regs, sfar, sfsr); else spitfire_data_access_exception(regs, sfsr, sfar); - return; + goto out; } advance(regs); +out: + exception_exit(prev_state); } diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S index 0bacceb19150..932ff90fd760 100644 --- a/arch/sparc/kernel/vmlinux.lds.S +++ b/arch/sparc/kernel/vmlinux.lds.S @@ -122,6 +122,11 @@ SECTIONS *(.swapper_4m_tsb_phys_patch) __swapper_4m_tsb_phys_patch_end = .; } + .page_offset_shift_patch : { + __page_offset_shift_patch = .; + *(.page_offset_shift_patch) + __page_offset_shift_patch_end = .; + } .popc_3insn_patch : { __popc_3insn_patch = .; *(.popc_3insn_patch) diff --git a/arch/sparc/lib/clear_page.S b/arch/sparc/lib/clear_page.S index 77e531f6c2a7..46272dfc26e8 100644 --- a/arch/sparc/lib/clear_page.S +++ b/arch/sparc/lib/clear_page.S @@ -37,10 +37,10 @@ _clear_page: /* %o0=dest */ .globl clear_user_page clear_user_page: /* %o0=dest, %o1=vaddr */ lduw [%g6 + TI_PRE_COUNT], %o2 - sethi %uhi(PAGE_OFFSET), %g2 + sethi %hi(PAGE_OFFSET), %g2 sethi %hi(PAGE_SIZE), %o4 - sllx %g2, 32, %g2 + ldx [%g2 + %lo(PAGE_OFFSET)], %g2 sethi %hi(PAGE_KERNEL_LOCKED), %g3 ldx [%g3 + %lo(PAGE_KERNEL_LOCKED)], %g3 diff --git a/arch/sparc/lib/copy_page.S b/arch/sparc/lib/copy_page.S index 4d2df328e514..dd16c61f3263 100644 --- a/arch/sparc/lib/copy_page.S +++ b/arch/sparc/lib/copy_page.S @@ -46,10 +46,10 @@ .type copy_user_page,#function copy_user_page: /* %o0=dest, %o1=src, %o2=vaddr */ lduw [%g6 + TI_PRE_COUNT], %o4 - sethi %uhi(PAGE_OFFSET), %g2 + sethi %hi(PAGE_OFFSET), %g2 sethi %hi(PAGE_SIZE), %o3 - sllx %g2, 32, %g2 + ldx [%g2 + %lo(PAGE_OFFSET)], %g2 sethi %hi(PAGE_KERNEL_LOCKED), %g3 ldx [%g3 + %lo(PAGE_KERNEL_LOCKED)], %g3 diff --git a/arch/sparc/mm/fault_64.c b/arch/sparc/mm/fault_64.c index 2ebec263d685..69bb818fdd79 100644 --- a/arch/sparc/mm/fault_64.c +++ b/arch/sparc/mm/fault_64.c @@ -21,6 +21,7 @@ #include <linux/kprobes.h> #include <linux/kdebug.h> #include <linux/percpu.h> +#include <linux/context_tracking.h> #include <asm/page.h> #include <asm/pgtable.h> @@ -272,6 +273,7 @@ static void noinline __kprobes bogus_32bit_fault_address(struct pt_regs *regs, asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs) { + enum ctx_state prev_state = exception_enter(); struct mm_struct *mm = current->mm; struct vm_area_struct *vma; unsigned int insn = 0; @@ -282,7 +284,7 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs) fault_code = get_thread_fault_code(); if (notify_page_fault(regs)) - return; + goto exit_exception; si_code = SEGV_MAPERR; address = current_thread_info()->fault_address; @@ -313,7 +315,7 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs) /* Valid, no problems... */ } else { bad_kernel_pc(regs, address); - return; + goto exit_exception; } } else flags |= FAULT_FLAG_USER; @@ -430,7 +432,7 @@ good_area: fault = handle_mm_fault(mm, vma, address, flags); if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) - return; + goto exit_exception; if (unlikely(fault & VM_FAULT_ERROR)) { if (fault & VM_FAULT_OOM) @@ -482,6 +484,8 @@ good_area: } #endif +exit_exception: + exception_exit(prev_state); return; /* @@ -494,7 +498,7 @@ bad_area: handle_kernel_fault: do_kernel_fault(regs, si_code, fault_code, insn, address); - return; + goto exit_exception; /* * We ran out of memory, or some other thing happened to us that made @@ -505,7 +509,7 @@ out_of_memory: up_read(&mm->mmap_sem); if (!(regs->tstate & TSTATE_PRIV)) { pagefault_out_of_memory(); - return; + goto exit_exception; } goto handle_kernel_fault; diff --git a/arch/sparc/mm/gup.c b/arch/sparc/mm/gup.c index 01ee23dd724d..c4d3da68b800 100644 --- a/arch/sparc/mm/gup.c +++ b/arch/sparc/mm/gup.c @@ -71,13 +71,12 @@ static int gup_huge_pmd(pmd_t *pmdp, pmd_t pmd, unsigned long addr, int *nr) { struct page *head, *page, *tail; - u32 mask; int refs; - mask = PMD_HUGE_PRESENT; - if (write) - mask |= PMD_HUGE_WRITE; - if ((pmd_val(pmd) & mask) != mask) + if (!pmd_large(pmd)) + return 0; + + if (write && !pmd_write(pmd)) return 0; refs = 0; diff --git a/arch/sparc/mm/hugetlbpage.c b/arch/sparc/mm/hugetlbpage.c index 96399646570a..30963178d7e9 100644 --- a/arch/sparc/mm/hugetlbpage.c +++ b/arch/sparc/mm/hugetlbpage.c @@ -21,8 +21,6 @@ /* Slightly simplified from the non-hugepage variant because by * definition we don't have to worry about any page coloring stuff */ -#define VA_EXCLUDE_START (0x0000080000000000UL - (1UL << 32UL)) -#define VA_EXCLUDE_END (0xfffff80000000000UL + (1UL << 32UL)) static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *filp, unsigned long addr, diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index ed82edad1a39..5322e530d09c 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c @@ -354,7 +354,7 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t * #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE) if (mm->context.huge_pte_count && is_hugetlb_pte(pte)) - __update_mmu_tsb_insert(mm, MM_TSB_HUGE, HPAGE_SHIFT, + __update_mmu_tsb_insert(mm, MM_TSB_HUGE, REAL_HPAGE_SHIFT, address, pte_val(pte)); else #endif @@ -1557,6 +1557,96 @@ unsigned long __init find_ecache_flush_span(unsigned long size) return ~0UL; } +unsigned long PAGE_OFFSET; +EXPORT_SYMBOL(PAGE_OFFSET); + +static void __init page_offset_shift_patch_one(unsigned int *insn, unsigned long phys_bits) +{ + unsigned long final_shift; + unsigned int val = *insn; + unsigned int cnt; + + /* We are patching in ilog2(max_supported_phys_address), and + * we are doing so in a manner similar to a relocation addend. + * That is, we are adding the shift value to whatever value + * is in the shift instruction count field already. + */ + cnt = (val & 0x3f); + val &= ~0x3f; + + /* If we are trying to shift >= 64 bits, clear the destination + * register. This can happen when phys_bits ends up being equal + * to MAX_PHYS_ADDRESS_BITS. + */ + final_shift = (cnt + (64 - phys_bits)); + if (final_shift >= 64) { + unsigned int rd = (val >> 25) & 0x1f; + + val = 0x80100000 | (rd << 25); + } else { + val |= final_shift; + } + *insn = val; + + __asm__ __volatile__("flush %0" + : /* no outputs */ + : "r" (insn)); +} + +static void __init page_offset_shift_patch(unsigned long phys_bits) +{ + extern unsigned int __page_offset_shift_patch; + extern unsigned int __page_offset_shift_patch_end; + unsigned int *p; + + p = &__page_offset_shift_patch; + while (p < &__page_offset_shift_patch_end) { + unsigned int *insn = (unsigned int *)(unsigned long)*p; + + page_offset_shift_patch_one(insn, phys_bits); + + p++; + } +} + +static void __init setup_page_offset(void) +{ + unsigned long max_phys_bits = 40; + + if (tlb_type == cheetah || tlb_type == cheetah_plus) { + max_phys_bits = 42; + } else if (tlb_type == hypervisor) { + switch (sun4v_chip_type) { + case SUN4V_CHIP_NIAGARA1: + case SUN4V_CHIP_NIAGARA2: + max_phys_bits = 39; + break; + case SUN4V_CHIP_NIAGARA3: + max_phys_bits = 43; + break; + case SUN4V_CHIP_NIAGARA4: + case SUN4V_CHIP_NIAGARA5: + case SUN4V_CHIP_SPARC64X: + default: + max_phys_bits = 47; + break; + } + } + + if (max_phys_bits > MAX_PHYS_ADDRESS_BITS) { + prom_printf("MAX_PHYS_ADDRESS_BITS is too small, need %lu\n", + max_phys_bits); + prom_halt(); + } + + PAGE_OFFSET = PAGE_OFFSET_BY_BITS(max_phys_bits); + + pr_info("PAGE_OFFSET is 0x%016lx (max_phys_bits == %lu)\n", + PAGE_OFFSET, max_phys_bits); + + page_offset_shift_patch(max_phys_bits); +} + static void __init tsb_phys_patch(void) { struct tsb_ldquad_phys_patch_entry *pquad; @@ -1722,7 +1812,7 @@ static void __init sun4v_linear_pte_xor_finalize(void) #ifndef CONFIG_DEBUG_PAGEALLOC if (cpu_pgsz_mask & HV_PGSZ_MASK_256MB) { kern_linear_pte_xor[1] = (_PAGE_VALID | _PAGE_SZ256MB_4V) ^ - 0xfffff80000000000UL; + PAGE_OFFSET; kern_linear_pte_xor[1] |= (_PAGE_CP_4V | _PAGE_CV_4V | _PAGE_P_4V | _PAGE_W_4V); } else { @@ -1731,7 +1821,7 @@ static void __init sun4v_linear_pte_xor_finalize(void) if (cpu_pgsz_mask & HV_PGSZ_MASK_2GB) { kern_linear_pte_xor[2] = (_PAGE_VALID | _PAGE_SZ2GB_4V) ^ - 0xfffff80000000000UL; + PAGE_OFFSET; kern_linear_pte_xor[2] |= (_PAGE_CP_4V | _PAGE_CV_4V | _PAGE_P_4V | _PAGE_W_4V); } else { @@ -1740,7 +1830,7 @@ static void __init sun4v_linear_pte_xor_finalize(void) if (cpu_pgsz_mask & HV_PGSZ_MASK_16GB) { kern_linear_pte_xor[3] = (_PAGE_VALID | _PAGE_SZ16GB_4V) ^ - 0xfffff80000000000UL; + PAGE_OFFSET; kern_linear_pte_xor[3] |= (_PAGE_CP_4V | _PAGE_CV_4V | _PAGE_P_4V | _PAGE_W_4V); } else { @@ -1752,7 +1842,7 @@ static void __init sun4v_linear_pte_xor_finalize(void) /* paging_init() sets up the page tables */ static unsigned long last_valid_pfn; -pgd_t swapper_pg_dir[2048]; +pgd_t swapper_pg_dir[PTRS_PER_PGD]; static void sun4u_pgprot_init(void); static void sun4v_pgprot_init(void); @@ -1763,6 +1853,8 @@ void __init paging_init(void) unsigned long real_end, i; int node; + setup_page_offset(); + /* These build time checkes make sure that the dcache_dirty_cpu() * page->flags usage will work. * @@ -2261,10 +2353,10 @@ static void __init sun4u_pgprot_init(void) __ACCESS_BITS_4U | _PAGE_E_4U); #ifdef CONFIG_DEBUG_PAGEALLOC - kern_linear_pte_xor[0] = _PAGE_VALID ^ 0xfffff80000000000UL; + kern_linear_pte_xor[0] = _PAGE_VALID ^ PAGE_OFFSET; #else kern_linear_pte_xor[0] = (_PAGE_VALID | _PAGE_SZ4MB_4U) ^ - 0xfffff80000000000UL; + PAGE_OFFSET; #endif kern_linear_pte_xor[0] |= (_PAGE_CP_4U | _PAGE_CV_4U | _PAGE_P_4U | _PAGE_W_4U); @@ -2308,10 +2400,10 @@ static void __init sun4v_pgprot_init(void) _PAGE_CACHE = _PAGE_CACHE_4V; #ifdef CONFIG_DEBUG_PAGEALLOC - kern_linear_pte_xor[0] = _PAGE_VALID ^ 0xfffff80000000000UL; + kern_linear_pte_xor[0] = _PAGE_VALID ^ PAGE_OFFSET; #else kern_linear_pte_xor[0] = (_PAGE_VALID | _PAGE_SZ4MB_4V) ^ - 0xfffff80000000000UL; + PAGE_OFFSET; #endif kern_linear_pte_xor[0] |= (_PAGE_CP_4V | _PAGE_CV_4V | _PAGE_P_4V | _PAGE_W_4V); @@ -2455,53 +2547,13 @@ void __flush_tlb_all(void) : : "r" (pstate)); } -static pte_t *get_from_cache(struct mm_struct *mm) -{ - struct page *page; - pte_t *ret; - - spin_lock(&mm->page_table_lock); - page = mm->context.pgtable_page; - ret = NULL; - if (page) { - void *p = page_address(page); - - mm->context.pgtable_page = NULL; - - ret = (pte_t *) (p + (PAGE_SIZE / 2)); - } - spin_unlock(&mm->page_table_lock); - - return ret; -} - -static struct page *__alloc_for_cache(struct mm_struct *mm) -{ - struct page *page = alloc_page(GFP_KERNEL | __GFP_NOTRACK | - __GFP_REPEAT | __GFP_ZERO); - - if (page) { - spin_lock(&mm->page_table_lock); - if (!mm->context.pgtable_page) { - atomic_set(&page->_count, 2); - mm->context.pgtable_page = page; - } - spin_unlock(&mm->page_table_lock); - } - return page; -} - pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) { - struct page *page; - pte_t *pte; - - pte = get_from_cache(mm); - if (pte) - return pte; + struct page *page = alloc_page(GFP_KERNEL | __GFP_NOTRACK | + __GFP_REPEAT | __GFP_ZERO); + pte_t *pte = NULL; - page = __alloc_for_cache(mm); if (page) pte = (pte_t *) page_address(page); @@ -2511,36 +2563,28 @@ pte_t *pte_alloc_one_kernel(struct mm_struct *mm, pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address) { - struct page *page; - pte_t *pte; - - pte = get_from_cache(mm); - if (pte) - return pte; - - page = __alloc_for_cache(mm); - if (page) { - pgtable_page_ctor(page); - pte = (pte_t *) page_address(page); + struct page *page = alloc_page(GFP_KERNEL | __GFP_NOTRACK | + __GFP_REPEAT | __GFP_ZERO); + if (!page) + return NULL; + if (!pgtable_page_ctor(page)) { + free_hot_cold_page(page, 0); + return NULL; } - - return pte; + return (pte_t *) page_address(page); } void pte_free_kernel(struct mm_struct *mm, pte_t *pte) { - struct page *page = virt_to_page(pte); - if (put_page_testzero(page)) - free_hot_cold_page(page, 0); + free_page((unsigned long)pte); } static void __pte_free(pgtable_t pte) { struct page *page = virt_to_page(pte); - if (put_page_testzero(page)) { - pgtable_page_dtor(page); - free_hot_cold_page(page, 0); - } + + pgtable_page_dtor(page); + __free_page(page); } void pte_free(struct mm_struct *mm, pgtable_t pte) @@ -2557,124 +2601,27 @@ void pgtable_free(void *table, bool is_page) } #ifdef CONFIG_TRANSPARENT_HUGEPAGE -static pmd_t pmd_set_protbits(pmd_t pmd, pgprot_t pgprot, bool for_modify) -{ - if (pgprot_val(pgprot) & _PAGE_VALID) - pmd_val(pmd) |= PMD_HUGE_PRESENT; - if (tlb_type == hypervisor) { - if (pgprot_val(pgprot) & _PAGE_WRITE_4V) - pmd_val(pmd) |= PMD_HUGE_WRITE; - if (pgprot_val(pgprot) & _PAGE_EXEC_4V) - pmd_val(pmd) |= PMD_HUGE_EXEC; - - if (!for_modify) { - if (pgprot_val(pgprot) & _PAGE_ACCESSED_4V) - pmd_val(pmd) |= PMD_HUGE_ACCESSED; - if (pgprot_val(pgprot) & _PAGE_MODIFIED_4V) - pmd_val(pmd) |= PMD_HUGE_DIRTY; - } - } else { - if (pgprot_val(pgprot) & _PAGE_WRITE_4U) - pmd_val(pmd) |= PMD_HUGE_WRITE; - if (pgprot_val(pgprot) & _PAGE_EXEC_4U) - pmd_val(pmd) |= PMD_HUGE_EXEC; - - if (!for_modify) { - if (pgprot_val(pgprot) & _PAGE_ACCESSED_4U) - pmd_val(pmd) |= PMD_HUGE_ACCESSED; - if (pgprot_val(pgprot) & _PAGE_MODIFIED_4U) - pmd_val(pmd) |= PMD_HUGE_DIRTY; - } - } - - return pmd; -} - -pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot) -{ - pmd_t pmd; - - pmd_val(pmd) = (page_nr << ((PAGE_SHIFT - PMD_PADDR_SHIFT))); - pmd_val(pmd) |= PMD_ISHUGE; - pmd = pmd_set_protbits(pmd, pgprot, false); - return pmd; -} - -pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot) -{ - pmd_val(pmd) &= ~(PMD_HUGE_PRESENT | - PMD_HUGE_WRITE | - PMD_HUGE_EXEC); - pmd = pmd_set_protbits(pmd, newprot, true); - return pmd; -} - -pgprot_t pmd_pgprot(pmd_t entry) -{ - unsigned long pte = 0; - - if (pmd_val(entry) & PMD_HUGE_PRESENT) - pte |= _PAGE_VALID; - - if (tlb_type == hypervisor) { - if (pmd_val(entry) & PMD_HUGE_PRESENT) - pte |= _PAGE_PRESENT_4V; - if (pmd_val(entry) & PMD_HUGE_EXEC) - pte |= _PAGE_EXEC_4V; - if (pmd_val(entry) & PMD_HUGE_WRITE) - pte |= _PAGE_W_4V; - if (pmd_val(entry) & PMD_HUGE_ACCESSED) - pte |= _PAGE_ACCESSED_4V; - if (pmd_val(entry) & PMD_HUGE_DIRTY) - pte |= _PAGE_MODIFIED_4V; - pte |= _PAGE_CP_4V|_PAGE_CV_4V; - } else { - if (pmd_val(entry) & PMD_HUGE_PRESENT) - pte |= _PAGE_PRESENT_4U; - if (pmd_val(entry) & PMD_HUGE_EXEC) - pte |= _PAGE_EXEC_4U; - if (pmd_val(entry) & PMD_HUGE_WRITE) - pte |= _PAGE_W_4U; - if (pmd_val(entry) & PMD_HUGE_ACCESSED) - pte |= _PAGE_ACCESSED_4U; - if (pmd_val(entry) & PMD_HUGE_DIRTY) - pte |= _PAGE_MODIFIED_4U; - pte |= _PAGE_CP_4U|_PAGE_CV_4U; - } - - return __pgprot(pte); -} - void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr, pmd_t *pmd) { unsigned long pte, flags; struct mm_struct *mm; pmd_t entry = *pmd; - pgprot_t prot; if (!pmd_large(entry) || !pmd_young(entry)) return; - pte = (pmd_val(entry) & ~PMD_HUGE_PROTBITS); - pte <<= PMD_PADDR_SHIFT; - pte |= _PAGE_VALID; - - prot = pmd_pgprot(entry); - - if (tlb_type == hypervisor) - pgprot_val(prot) |= _PAGE_SZHUGE_4V; - else - pgprot_val(prot) |= _PAGE_SZHUGE_4U; + pte = pmd_val(entry); - pte |= pgprot_val(prot); + /* We are fabricating 8MB pages using 4MB real hw pages. */ + pte |= (addr & (1UL << REAL_HPAGE_SHIFT)); mm = vma->vm_mm; spin_lock_irqsave(&mm->context.lock, flags); if (mm->context.tsb_block[MM_TSB_HUGE].tsb != NULL) - __update_mmu_tsb_insert(mm, MM_TSB_HUGE, HPAGE_SHIFT, + __update_mmu_tsb_insert(mm, MM_TSB_HUGE, REAL_HPAGE_SHIFT, addr, pte); spin_unlock_irqrestore(&mm->context.lock, flags); diff --git a/arch/sparc/mm/init_64.h b/arch/sparc/mm/init_64.h index 0661aa606dec..5d3782deb403 100644 --- a/arch/sparc/mm/init_64.h +++ b/arch/sparc/mm/init_64.h @@ -1,11 +1,13 @@ #ifndef _SPARC64_MM_INIT_H #define _SPARC64_MM_INIT_H +#include <asm/page.h> + /* Most of the symbols in this file are defined in init.c and * marked non-static so that assembler code can get at them. */ -#define MAX_PHYS_ADDRESS (1UL << 41UL) +#define MAX_PHYS_ADDRESS (1UL << MAX_PHYS_ADDRESS_BITS) #define KPTE_BITMAP_CHUNK_SZ (256UL * 1024UL * 1024UL) #define KPTE_BITMAP_BYTES \ ((MAX_PHYS_ADDRESS / KPTE_BITMAP_CHUNK_SZ) / 4) diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c index 5d721df48a72..869023abe5a4 100644 --- a/arch/sparc/mm/srmmu.c +++ b/arch/sparc/mm/srmmu.c @@ -345,7 +345,10 @@ pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address) if ((pte = (unsigned long)pte_alloc_one_kernel(mm, address)) == 0) return NULL; page = pfn_to_page(__nocache_pa(pte) >> PAGE_SHIFT); - pgtable_page_ctor(page); + if (!pgtable_page_ctor(page)) { + __free_page(page); + return NULL; + } return page; } diff --git a/arch/sparc/mm/tlb.c b/arch/sparc/mm/tlb.c index 7a91f288c708..ad3bf4b4324d 100644 --- a/arch/sparc/mm/tlb.c +++ b/arch/sparc/mm/tlb.c @@ -161,8 +161,8 @@ void set_pmd_at(struct mm_struct *mm, unsigned long addr, if (mm == &init_mm) return; - if ((pmd_val(pmd) ^ pmd_val(orig)) & PMD_ISHUGE) { - if (pmd_val(pmd) & PMD_ISHUGE) + if ((pmd_val(pmd) ^ pmd_val(orig)) & _PAGE_PMD_HUGE) { + if (pmd_val(pmd) & _PAGE_PMD_HUGE) mm->context.huge_pte_count++; else mm->context.huge_pte_count--; @@ -178,13 +178,16 @@ void set_pmd_at(struct mm_struct *mm, unsigned long addr, } if (!pmd_none(orig)) { - bool exec = ((pmd_val(orig) & PMD_HUGE_EXEC) != 0); + pte_t orig_pte = __pte(pmd_val(orig)); + bool exec = pte_exec(orig_pte); addr &= HPAGE_MASK; - if (pmd_val(orig) & PMD_ISHUGE) + if (pmd_trans_huge(orig)) { tlb_batch_add_one(mm, addr, exec); - else + tlb_batch_add_one(mm, addr + REAL_HPAGE_SIZE, exec); + } else { tlb_batch_pmd_scan(mm, addr, orig, exec); + } } } @@ -196,11 +199,11 @@ void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp, assert_spin_locked(&mm->page_table_lock); /* FIFO */ - if (!mm->pmd_huge_pte) + if (!pmd_huge_pte(mm, pmdp)) INIT_LIST_HEAD(lh); else - list_add(lh, (struct list_head *) mm->pmd_huge_pte); - mm->pmd_huge_pte = pgtable; + list_add(lh, (struct list_head *) pmd_huge_pte(mm, pmdp)); + pmd_huge_pte(mm, pmdp) = pgtable; } pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp) @@ -211,12 +214,12 @@ pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp) assert_spin_locked(&mm->page_table_lock); /* FIFO */ - pgtable = mm->pmd_huge_pte; + pgtable = pmd_huge_pte(mm, pmdp); lh = (struct list_head *) pgtable; if (list_empty(lh)) - mm->pmd_huge_pte = NULL; + pmd_huge_pte(mm, pmdp) = NULL; else { - mm->pmd_huge_pte = (pgtable_t) lh->next; + pmd_huge_pte(mm, pmdp) = (pgtable_t) lh->next; list_del(lh); } pte_val(pgtable[0]) = 0; diff --git a/arch/sparc/mm/tsb.c b/arch/sparc/mm/tsb.c index 2cc3bce5ee91..3b3a360b429a 100644 --- a/arch/sparc/mm/tsb.c +++ b/arch/sparc/mm/tsb.c @@ -87,7 +87,7 @@ void flush_tsb_user(struct tlb_batch *tb) nentries = mm->context.tsb_block[MM_TSB_HUGE].tsb_nentries; if (tlb_type == cheetah_plus || tlb_type == hypervisor) base = __pa(base); - __flush_tsb_one(tb, HPAGE_SHIFT, base, nentries); + __flush_tsb_one(tb, REAL_HPAGE_SHIFT, base, nentries); } #endif spin_unlock_irqrestore(&mm->context.lock, flags); @@ -111,7 +111,7 @@ void flush_tsb_user_page(struct mm_struct *mm, unsigned long vaddr) nentries = mm->context.tsb_block[MM_TSB_HUGE].tsb_nentries; if (tlb_type == cheetah_plus || tlb_type == hypervisor) base = __pa(base); - __flush_tsb_one_entry(base, vaddr, HPAGE_SHIFT, nentries); + __flush_tsb_one_entry(base, vaddr, REAL_HPAGE_SHIFT, nentries); } #endif spin_unlock_irqrestore(&mm->context.lock, flags); @@ -472,8 +472,6 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm) mm->context.huge_pte_count = 0; #endif - mm->context.pgtable_page = NULL; - /* copy_mm() copies over the parent's mm_struct before calling * us, so we need to zero out the TSB pointer or else tsb_grow() * will be confused and think there is an older TSB to free up. @@ -512,17 +510,10 @@ static void tsb_destroy_one(struct tsb_config *tp) void destroy_context(struct mm_struct *mm) { unsigned long flags, i; - struct page *page; for (i = 0; i < MM_NUM_TSBS; i++) tsb_destroy_one(&mm->context.tsb_block[i]); - page = mm->context.pgtable_page; - if (page && put_page_testzero(page)) { - pgtable_page_dtor(page); - free_hot_cold_page(page, 0); - } - spin_lock_irqsave(&ctx_alloc_lock, flags); if (CTX_VALID(mm->context)) { diff --git a/arch/sparc/mm/ultra.S b/arch/sparc/mm/ultra.S index 432aa0cb1b38..b4f4733abc6e 100644 --- a/arch/sparc/mm/ultra.S +++ b/arch/sparc/mm/ultra.S @@ -153,10 +153,10 @@ __spitfire_flush_tlb_mm_slow: .globl __flush_icache_page __flush_icache_page: /* %o0 = phys_page */ srlx %o0, PAGE_SHIFT, %o0 - sethi %uhi(PAGE_OFFSET), %g1 + sethi %hi(PAGE_OFFSET), %g1 sllx %o0, PAGE_SHIFT, %o0 sethi %hi(PAGE_SIZE), %g2 - sllx %g1, 32, %g1 + ldx [%g1 + %lo(PAGE_OFFSET)], %g1 add %o0, %g1, %o0 1: subcc %g2, 32, %g2 bne,pt %icc, 1b @@ -178,8 +178,8 @@ __flush_icache_page: /* %o0 = phys_page */ .align 64 .globl __flush_dcache_page __flush_dcache_page: /* %o0=kaddr, %o1=flush_icache */ - sethi %uhi(PAGE_OFFSET), %g1 - sllx %g1, 32, %g1 + sethi %hi(PAGE_OFFSET), %g1 + ldx [%g1 + %lo(PAGE_OFFSET)], %g1 sub %o0, %g1, %o0 ! physical address srlx %o0, 11, %o0 ! make D-cache TAG sethi %hi(1 << 14), %o2 ! D-cache size @@ -287,8 +287,8 @@ __cheetah_flush_tlb_pending: /* 27 insns */ #ifdef DCACHE_ALIASING_POSSIBLE __cheetah_flush_dcache_page: /* 11 insns */ - sethi %uhi(PAGE_OFFSET), %g1 - sllx %g1, 32, %g1 + sethi %hi(PAGE_OFFSET), %g1 + ldx [%g1 + %lo(PAGE_OFFSET)], %g1 sub %o0, %g1, %o0 sethi %hi(PAGE_SIZE), %o4 1: subcc %o4, (1 << 5), %o4 diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig index d45a2c48f185..b3692ce78f90 100644 --- a/arch/tile/Kconfig +++ b/arch/tile/Kconfig @@ -8,7 +8,6 @@ config TILE select HAVE_KVM if !TILEGX select GENERIC_FIND_FIRST_BIT select SYSCTL_EXCEPTION_TRACE - select USE_GENERIC_SMP_HELPERS select CC_OPTIMIZE_FOR_SIZE select HAVE_DEBUG_KMEMLEAK select GENERIC_IRQ_PROBE diff --git a/arch/tile/include/asm/Kbuild b/arch/tile/include/asm/Kbuild index 664d6ad23f80..22f3bd147fa7 100644 --- a/arch/tile/include/asm/Kbuild +++ b/arch/tile/include/asm/Kbuild @@ -38,3 +38,4 @@ generic-y += termios.h generic-y += trace_clock.h generic-y += types.h generic-y += xor.h +generic-y += preempt.h diff --git a/arch/tile/include/asm/hardirq.h b/arch/tile/include/asm/hardirq.h index 822390f9a154..54110af23985 100644 --- a/arch/tile/include/asm/hardirq.h +++ b/arch/tile/include/asm/hardirq.h @@ -42,6 +42,4 @@ DECLARE_PER_CPU(irq_cpustat_t, irq_stat); #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ -#define HARDIRQ_BITS 8 - #endif /* _ASM_TILE_HARDIRQ_H */ diff --git a/arch/tile/include/asm/thread_info.h b/arch/tile/include/asm/thread_info.h index b8aa6df3e102..729aa107f64e 100644 --- a/arch/tile/include/asm/thread_info.h +++ b/arch/tile/include/asm/thread_info.h @@ -113,8 +113,6 @@ extern void _cpu_idle(void); #endif /* !__ASSEMBLY__ */ -#define PREEMPT_ACTIVE 0x10000000 - /* * Thread information flags that various assembly files may need to access. * Keep flags accessed frequently in low bits, particular since it makes diff --git a/arch/tile/kernel/compat_signal.c b/arch/tile/kernel/compat_signal.c index 85e00b2f39bf..19c04b5ce408 100644 --- a/arch/tile/kernel/compat_signal.c +++ b/arch/tile/kernel/compat_signal.c @@ -49,7 +49,7 @@ struct compat_rt_sigframe { struct compat_ucontext uc; }; -int copy_siginfo_to_user32(struct compat_siginfo __user *to, siginfo_t *from) +int copy_siginfo_to_user32(struct compat_siginfo __user *to, const siginfo_t *from) { int err; diff --git a/arch/tile/kernel/pci.c b/arch/tile/kernel/pci.c index b7180e6e900d..c45593db7718 100644 --- a/arch/tile/kernel/pci.c +++ b/arch/tile/kernel/pci.c @@ -251,15 +251,12 @@ static void fixup_read_and_payload_sizes(void) /* Scan for the smallest maximum payload size. */ for_each_pci_dev(dev) { u32 devcap; - int max_payload; if (!pci_is_pcie(dev)) continue; - pcie_capability_read_dword(dev, PCI_EXP_DEVCAP, &devcap); - max_payload = devcap & PCI_EXP_DEVCAP_PAYLOAD; - if (max_payload < smallest_max_payload) - smallest_max_payload = max_payload; + if (dev->pcie_mpss < smallest_max_payload) + smallest_max_payload = dev->pcie_mpss; } /* Now, set the max_payload_size for all devices to that value. */ diff --git a/arch/tile/mm/pgtable.c b/arch/tile/mm/pgtable.c index 4fd9ec0b58ed..5e86eac4bfae 100644 --- a/arch/tile/mm/pgtable.c +++ b/arch/tile/mm/pgtable.c @@ -241,6 +241,11 @@ struct page *pgtable_alloc_one(struct mm_struct *mm, unsigned long address, if (p == NULL) return NULL; + if (!pgtable_page_ctor(p)) { + __free_pages(p, L2_USER_PGTABLE_ORDER); + return NULL; + } + /* * Make every page have a page_count() of one, not just the first. * We don't use __GFP_COMP since it doesn't look like it works @@ -251,7 +256,6 @@ struct page *pgtable_alloc_one(struct mm_struct *mm, unsigned long address, inc_zone_page_state(p+i, NR_PAGETABLE); } - pgtable_page_ctor(p); return p; } diff --git a/arch/um/Kconfig.char b/arch/um/Kconfig.char index b9d7c4276682..f10738d68b2d 100644 --- a/arch/um/Kconfig.char +++ b/arch/um/Kconfig.char @@ -6,10 +6,6 @@ config STDERR_CONSOLE help console driver which dumps all printk messages to stderr. -config STDIO_CONSOLE - bool - default y - config SSL bool "Virtual serial line" help diff --git a/arch/um/Kconfig.common b/arch/um/Kconfig.common index 8ddea1f8006a..21ca44c4f6d5 100644 --- a/arch/um/Kconfig.common +++ b/arch/um/Kconfig.common @@ -1,8 +1,3 @@ -config DEFCONFIG_LIST - string - option defconfig_list - default "arch/$ARCH/defconfig" - config UML bool default y diff --git a/arch/um/Makefile b/arch/um/Makefile index 133f7de2a13d..48d92bbe62e9 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile @@ -6,6 +6,17 @@ # Licensed under the GPL # +# select defconfig based on actual architecture +ifeq ($(SUBARCH),x86) + ifeq ($(shell uname -m),x86_64) + KBUILD_DEFCONFIG := x86_64_defconfig + else + KBUILD_DEFCONFIG := i386_defconfig + endif +else + KBUILD_DEFCONFIG := $(SUBARCH)_defconfig +endif + ARCH_DIR := arch/um OS := $(shell uname -s) # We require bash because the vmlinux link and loader script cpp use bash diff --git a/arch/um/configs/i386_defconfig b/arch/um/configs/i386_defconfig new file mode 100644 index 000000000000..a12bf68c9f3a --- /dev/null +++ b/arch/um/configs/i386_defconfig @@ -0,0 +1,76 @@ +CONFIG_3_LEVEL_PGTABLES=y +# CONFIG_COMPACTION is not set +CONFIG_BINFMT_MISC=m +CONFIG_HOSTFS=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_KERNEL_STACK_ORDER=1 +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_CGROUPS=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CPUSETS=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_RESOURCE_COUNTERS=y +CONFIG_CGROUP_SCHED=y +CONFIG_BLK_CGROUP=y +# CONFIG_PID_NS is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SLAB=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_BLK_DEV_BSG is not set +CONFIG_IOSCHED_CFQ=m +CONFIG_SSL=y +CONFIG_NULL_CHAN=y +CONFIG_PORT_CHAN=y +CONFIG_PTY_CHAN=y +CONFIG_TTY_CHAN=y +CONFIG_XTERM_CHAN=y +CONFIG_CON_CHAN="pts" +CONFIG_SSL_CHAN="pts" +CONFIG_UML_SOUND=m +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_BLK_DEV_UBD=y +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_NBD=m +CONFIG_DUMMY=m +CONFIG_TUN=m +CONFIG_PPP=m +CONFIG_SLIP=m +CONFIG_LEGACY_PTY_COUNT=32 +# CONFIG_HW_RANDOM is not set +CONFIG_UML_RANDOM=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_INET_LRO is not set +# CONFIG_IPV6 is not set +CONFIG_UML_NET=y +CONFIG_UML_NET_ETHERTAP=y +CONFIG_UML_NET_TUNTAP=y +CONFIG_UML_NET_SLIP=y +CONFIG_UML_NET_DAEMON=y +CONFIG_UML_NET_MCAST=y +CONFIG_UML_NET_SLIRP=y +CONFIG_EXT4_FS=y +CONFIG_REISERFS_FS=y +CONFIG_QUOTA=y +CONFIG_AUTOFS4_FS=m +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +CONFIG_PROC_KCORE=y +CONFIG_TMPFS=y +CONFIG_NLS=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_KERNEL=y diff --git a/arch/um/configs/x86_64_defconfig b/arch/um/configs/x86_64_defconfig new file mode 100644 index 000000000000..3aab117bd553 --- /dev/null +++ b/arch/um/configs/x86_64_defconfig @@ -0,0 +1,75 @@ +# CONFIG_COMPACTION is not set +CONFIG_BINFMT_MISC=m +CONFIG_HOSTFS=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_CGROUPS=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CPUSETS=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_RESOURCE_COUNTERS=y +CONFIG_CGROUP_SCHED=y +CONFIG_BLK_CGROUP=y +# CONFIG_PID_NS is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SLAB=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_BLK_DEV_BSG is not set +CONFIG_IOSCHED_CFQ=m +CONFIG_SSL=y +CONFIG_NULL_CHAN=y +CONFIG_PORT_CHAN=y +CONFIG_PTY_CHAN=y +CONFIG_TTY_CHAN=y +CONFIG_XTERM_CHAN=y +CONFIG_CON_CHAN="pts" +CONFIG_SSL_CHAN="pts" +CONFIG_UML_SOUND=m +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_BLK_DEV_UBD=y +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_NBD=m +CONFIG_DUMMY=m +CONFIG_TUN=m +CONFIG_PPP=m +CONFIG_SLIP=m +CONFIG_LEGACY_PTY_COUNT=32 +# CONFIG_HW_RANDOM is not set +CONFIG_UML_RANDOM=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_INET_LRO is not set +# CONFIG_IPV6 is not set +CONFIG_UML_NET=y +CONFIG_UML_NET_ETHERTAP=y +CONFIG_UML_NET_TUNTAP=y +CONFIG_UML_NET_SLIP=y +CONFIG_UML_NET_DAEMON=y +CONFIG_UML_NET_MCAST=y +CONFIG_UML_NET_SLIRP=y +CONFIG_EXT4_FS=y +CONFIG_REISERFS_FS=y +CONFIG_QUOTA=y +CONFIG_AUTOFS4_FS=m +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +CONFIG_PROC_KCORE=y +CONFIG_TMPFS=y +CONFIG_NLS=y +CONFIG_DEBUG_INFO=y +CONFIG_FRAME_WARN=1024 +CONFIG_DEBUG_KERNEL=y diff --git a/arch/um/defconfig b/arch/um/defconfig deleted file mode 100644 index 2665e6b683f5..000000000000 --- a/arch/um/defconfig +++ /dev/null @@ -1,899 +0,0 @@ -# -# Automatically generated file; DO NOT EDIT. -# User Mode Linux/i386 3.3.0 Kernel Configuration -# -CONFIG_DEFCONFIG_LIST="arch/$ARCH/defconfig" -CONFIG_UML=y -CONFIG_MMU=y -CONFIG_NO_IOMEM=y -# CONFIG_TRACE_IRQFLAGS_SUPPORT is not set -CONFIG_LOCKDEP_SUPPORT=y -# CONFIG_STACKTRACE_SUPPORT is not set -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_BUG=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_HZ=100 - -# -# UML-specific options -# - -# -# Host processor type and features -# -# CONFIG_M486 is not set -# CONFIG_M586 is not set -# CONFIG_M586TSC is not set -# CONFIG_M586MMX is not set -CONFIG_M686=y -# CONFIG_MPENTIUMII is not set -# CONFIG_MPENTIUMIII is not set -# CONFIG_MPENTIUMM is not set -# CONFIG_MPENTIUM4 is not set -# CONFIG_MK6 is not set -# CONFIG_MK7 is not set -# CONFIG_MK8 is not set -# CONFIG_MCRUSOE is not set -# CONFIG_MEFFICEON is not set -# CONFIG_MWINCHIPC6 is not set -# CONFIG_MWINCHIP3D is not set -# CONFIG_MELAN is not set -# CONFIG_MGEODEGX1 is not set -# CONFIG_MGEODE_LX is not set -# CONFIG_MCYRIXIII is not set -# CONFIG_MVIAC3_2 is not set -# CONFIG_MVIAC7 is not set -# CONFIG_MCORE2 is not set -# CONFIG_MATOM is not set -# CONFIG_X86_GENERIC is not set -CONFIG_X86_INTERNODE_CACHE_SHIFT=5 -CONFIG_X86_CMPXCHG=y -CONFIG_X86_L1_CACHE_SHIFT=5 -CONFIG_X86_XADD=y -CONFIG_X86_PPRO_FENCE=y -CONFIG_X86_WP_WORKS_OK=y -CONFIG_X86_INVLPG=y -CONFIG_X86_BSWAP=y -CONFIG_X86_POPAD_OK=y -CONFIG_X86_USE_PPRO_CHECKSUM=y -CONFIG_X86_TSC=y -CONFIG_X86_CMPXCHG64=y -CONFIG_X86_CMOV=y -CONFIG_X86_MINIMUM_CPU_FAMILY=5 -CONFIG_CPU_SUP_INTEL=y -CONFIG_CPU_SUP_CYRIX_32=y -CONFIG_CPU_SUP_AMD=y -CONFIG_CPU_SUP_CENTAUR=y -CONFIG_CPU_SUP_TRANSMETA_32=y -CONFIG_CPU_SUP_UMC_32=y -CONFIG_UML_X86=y -# CONFIG_64BIT is not set -CONFIG_X86_32=y -# CONFIG_X86_64 is not set -# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_3_LEVEL_PGTABLES is not set -CONFIG_ARCH_HAS_SC_SIGNALS=y -CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA=y -CONFIG_GENERIC_HWEIGHT=y -# CONFIG_STATIC_LINK is not set -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -CONFIG_PAGEFLAGS_EXTENDED=y -CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_COMPACTION is not set -# CONFIG_PHYS_ADDR_T_64BIT is not set -CONFIG_ZONE_DMA_FLAG=0 -CONFIG_VIRT_TO_BUS=y -# CONFIG_KSM is not set -CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 -CONFIG_NEED_PER_CPU_KM=y -# CONFIG_CLEANCACHE is not set -CONFIG_TICK_ONESHOT=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -CONFIG_LD_SCRIPT_DYN=y -CONFIG_BINFMT_ELF=y -CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y -CONFIG_HAVE_AOUT=y -# CONFIG_BINFMT_AOUT is not set -CONFIG_BINFMT_MISC=m -CONFIG_HOSTFS=y -# CONFIG_HPPFS is not set -CONFIG_MCONSOLE=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_KERNEL_STACK_ORDER=0 -# CONFIG_MMAPPER is not set -CONFIG_NO_DMA=y - -# -# General setup -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=128 -CONFIG_CROSS_COMPILE="" -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_DEFAULT_HOSTNAME="(none)" -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -CONFIG_SYSVIPC_SYSCTL=y -CONFIG_POSIX_MQUEUE=y -CONFIG_POSIX_MQUEUE_SYSCTL=y -CONFIG_BSD_PROCESS_ACCT=y -# CONFIG_BSD_PROCESS_ACCT_V3 is not set -# CONFIG_FHANDLE is not set -# CONFIG_TASKSTATS is not set -# CONFIG_AUDIT is not set - -# -# IRQ subsystem -# -CONFIG_GENERIC_IRQ_SHOW=y - -# -# RCU Subsystem -# -CONFIG_TINY_RCU=y -# CONFIG_PREEMPT_RCU is not set -# CONFIG_RCU_TRACE is not set -# CONFIG_TREE_RCU_TRACE is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_CGROUPS=y -# CONFIG_CGROUP_DEBUG is not set -CONFIG_CGROUP_FREEZER=y -CONFIG_CGROUP_DEVICE=y -CONFIG_CPUSETS=y -CONFIG_PROC_PID_CPUSET=y -CONFIG_CGROUP_CPUACCT=y -CONFIG_RESOURCE_COUNTERS=y -CONFIG_CGROUP_MEMCG=y -CONFIG_CGROUP_MEMCG_SWAP=y -# CONFIG_CGROUP_MEMCG_SWAP_ENABLED is not set -# CONFIG_CGROUP_MEMCG_KMEM is not set -CONFIG_CGROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_CFS_BANDWIDTH is not set -# CONFIG_RT_GROUP_SCHED is not set -CONFIG_BLK_CGROUP=y -# CONFIG_DEBUG_BLK_CGROUP is not set -# CONFIG_CHECKPOINT_RESTORE is not set -CONFIG_NAMESPACES=y -CONFIG_UTS_NS=y -CONFIG_IPC_NS=y -# CONFIG_USER_NS is not set -# CONFIG_PID_NS is not set -CONFIG_NET_NS=y -# CONFIG_SCHED_AUTOGROUP is not set -CONFIG_MM_OWNER=y -CONFIG_SYSFS_DEPRECATED=y -# CONFIG_SYSFS_DEPRECATED_V2 is not set -# CONFIG_RELAY is not set -# CONFIG_BLK_DEV_INITRD is not set -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_SYSCTL=y -CONFIG_ANON_INODES=y -# CONFIG_EXPERT is not set -CONFIG_UID16=y -# CONFIG_SYSCTL_SYSCALL is not set -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_ALL is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_SIGNALFD=y -CONFIG_TIMERFD=y -CONFIG_EVENTFD=y -CONFIG_SHMEM=y -CONFIG_AIO=y -# CONFIG_EMBEDDED is not set - -# -# Kernel Performance Events And Counters -# -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_COMPAT_BRK=y -CONFIG_SLAB=y -# CONFIG_SLUB is not set -# CONFIG_PROFILING is not set - -# -# GCOV-based kernel profiling -# -# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set -CONFIG_SLABINFO=y -CONFIG_RT_MUTEXES=y -CONFIG_BASE_SMALL=0 -CONFIG_MODULES=y -# CONFIG_MODULE_FORCE_LOAD is not set -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_BLOCK=y -CONFIG_LBDAF=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_BLK_DEV_BSGLIB is not set -# CONFIG_BLK_DEV_INTEGRITY is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=m -# CONFIG_CFQ_GROUP_IOSCHED is not set -CONFIG_DEFAULT_DEADLINE=y -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="deadline" -# CONFIG_INLINE_SPIN_TRYLOCK is not set -# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set -# CONFIG_INLINE_SPIN_LOCK is not set -# CONFIG_INLINE_SPIN_LOCK_BH is not set -# CONFIG_INLINE_SPIN_LOCK_IRQ is not set -# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set -CONFIG_INLINE_SPIN_UNLOCK=y -# CONFIG_INLINE_SPIN_UNLOCK_BH is not set -CONFIG_INLINE_SPIN_UNLOCK_IRQ=y -# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set -# CONFIG_INLINE_READ_TRYLOCK is not set -# CONFIG_INLINE_READ_LOCK is not set -# CONFIG_INLINE_READ_LOCK_BH is not set -# CONFIG_INLINE_READ_LOCK_IRQ is not set -# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set -CONFIG_INLINE_READ_UNLOCK=y -# CONFIG_INLINE_READ_UNLOCK_BH is not set -CONFIG_INLINE_READ_UNLOCK_IRQ=y -# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set -# CONFIG_INLINE_WRITE_TRYLOCK is not set -# CONFIG_INLINE_WRITE_LOCK is not set -# CONFIG_INLINE_WRITE_LOCK_BH is not set -# CONFIG_INLINE_WRITE_LOCK_IRQ is not set -# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set -CONFIG_INLINE_WRITE_UNLOCK=y -# CONFIG_INLINE_WRITE_UNLOCK_BH is not set -CONFIG_INLINE_WRITE_UNLOCK_IRQ=y -# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set -# CONFIG_MUTEX_SPIN_ON_OWNER is not set -CONFIG_FREEZER=y - -# -# UML Character Devices -# -CONFIG_STDERR_CONSOLE=y -CONFIG_STDIO_CONSOLE=y -CONFIG_SSL=y -CONFIG_NULL_CHAN=y -CONFIG_PORT_CHAN=y -CONFIG_PTY_CHAN=y -CONFIG_TTY_CHAN=y -CONFIG_XTERM_CHAN=y -# CONFIG_NOCONFIG_CHAN is not set -CONFIG_CON_ZERO_CHAN="fd:0,fd:1" -CONFIG_CON_CHAN="xterm" -CONFIG_SSL_CHAN="pts" -CONFIG_UML_SOUND=m -CONFIG_SOUND=m -CONFIG_SOUND_OSS_CORE=y -CONFIG_HOSTAUDIO=m - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_DEVTMPFS=y -CONFIG_DEVTMPFS_MOUNT=y -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=y -CONFIG_FIRMWARE_IN_KERNEL=y -CONFIG_EXTRA_FIRMWARE="" -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_DEVRES is not set -# CONFIG_SYS_HYPERVISOR is not set -CONFIG_GENERIC_CPU_DEVICES=y -# CONFIG_DMA_SHARED_BUFFER is not set -# CONFIG_CONNECTOR is not set -# CONFIG_MTD is not set -CONFIG_BLK_DEV=y -CONFIG_BLK_DEV_UBD=y -# CONFIG_BLK_DEV_UBD_SYNC is not set -CONFIG_BLK_DEV_COW_COMMON=y -CONFIG_BLK_DEV_LOOP=m -CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 -# CONFIG_BLK_DEV_CRYPTOLOOP is not set - -# -# DRBD disabled because PROC_FS, INET or CONNECTOR not selected -# -CONFIG_BLK_DEV_NBD=m -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_ATA_OVER_ETH is not set -# CONFIG_BLK_DEV_RBD is not set - -# -# Misc devices -# -# CONFIG_ENCLOSURE_SERVICES is not set -# CONFIG_C2PORT is not set - -# -# EEPROM support -# -# CONFIG_EEPROM_93CX6 is not set - -# -# Texas Instruments shared transport line discipline -# - -# -# Altera FPGA firmware download module -# - -# -# SCSI device support -# -CONFIG_SCSI_MOD=y -# CONFIG_RAID_ATTRS is not set -# CONFIG_SCSI is not set -# CONFIG_SCSI_DMA is not set -# CONFIG_SCSI_NETLINK is not set -# CONFIG_MD is not set -CONFIG_NETDEVICES=y -CONFIG_NET_CORE=y -# CONFIG_BONDING is not set -CONFIG_DUMMY=m -# CONFIG_EQUALIZER is not set -# CONFIG_MII is not set -# CONFIG_NET_TEAM is not set -# CONFIG_MACVLAN is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -CONFIG_TUN=m -# CONFIG_VETH is not set - -# -# CAIF transport drivers -# -CONFIG_ETHERNET=y -CONFIG_NET_VENDOR_CHELSIO=y -CONFIG_NET_VENDOR_INTEL=y -CONFIG_NET_VENDOR_I825XX=y -CONFIG_NET_VENDOR_MARVELL=y -CONFIG_NET_VENDOR_NATSEMI=y -CONFIG_NET_VENDOR_8390=y -# CONFIG_PHYLIB is not set -CONFIG_PPP=m -# CONFIG_PPP_BSDCOMP is not set -# CONFIG_PPP_DEFLATE is not set -# CONFIG_PPP_FILTER is not set -# CONFIG_PPP_MPPE is not set -# CONFIG_PPP_MULTILINK is not set -# CONFIG_PPPOE is not set -# CONFIG_PPP_ASYNC is not set -# CONFIG_PPP_SYNC_TTY is not set -CONFIG_SLIP=m -CONFIG_SLHC=m -# CONFIG_SLIP_COMPRESSED is not set -# CONFIG_SLIP_SMART is not set -# CONFIG_SLIP_MODE_SLIP6 is not set -CONFIG_WLAN=y -# CONFIG_HOSTAP is not set - -# -# Enable WiMAX (Networking options) to see the WiMAX drivers -# -# CONFIG_WAN is not set - -# -# Character devices -# -CONFIG_UNIX98_PTYS=y -# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=32 -# CONFIG_N_GSM is not set -# CONFIG_TRACE_SINK is not set -CONFIG_DEVKMEM=y -# CONFIG_HW_RANDOM is not set -CONFIG_UML_RANDOM=y -# CONFIG_R3964 is not set -# CONFIG_NSC_GPIO is not set -# CONFIG_RAW_DRIVER is not set - -# -# PPS support -# -# CONFIG_PPS is not set - -# -# PPS generators support -# - -# -# PTP clock support -# - -# -# Enable Device Drivers -> PPS to see the PTP clock options. -# -# CONFIG_POWER_SUPPLY is not set -# CONFIG_THERMAL is not set -# CONFIG_WATCHDOG is not set -# CONFIG_REGULATOR is not set -CONFIG_SOUND_OSS_CORE_PRECLAIM=y -# CONFIG_MEMSTICK is not set -# CONFIG_NEW_LEDS is not set -# CONFIG_ACCESSIBILITY is not set -# CONFIG_AUXDISPLAY is not set -# CONFIG_UIO is not set - -# -# Virtio drivers -# -# CONFIG_VIRTIO_BALLOON is not set - -# -# Microsoft Hyper-V guest support -# -# CONFIG_STAGING is not set - -# -# Hardware Spinlock drivers -# -CONFIG_IOMMU_SUPPORT=y -# CONFIG_VIRT_DRIVERS is not set -# CONFIG_PM_DEVFREQ is not set -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_UNIX=y -# CONFIG_UNIX_DIAG is not set -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_STATISTICS is not set -# CONFIG_NET_KEY is not set -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -# CONFIG_IP_PNP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE_DEMUX is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y -# CONFIG_INET_LRO is not set -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_INET_UDP_DIAG is not set -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set -# CONFIG_IPV6 is not set -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETWORK_PHY_TIMESTAMPING is not set -# CONFIG_NETFILTER is not set -# CONFIG_IP_DCCP is not set -# CONFIG_IP_SCTP is not set -# CONFIG_RDS is not set -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_L2TP is not set -# CONFIG_BRIDGE is not set -# CONFIG_NET_DSA is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_PHONET is not set -# CONFIG_IEEE802154 is not set -# CONFIG_NET_SCHED is not set -# CONFIG_DCB is not set -# CONFIG_BATMAN_ADV is not set -# CONFIG_OPENVSWITCH is not set -# CONFIG_NETPRIO_CGROUP is not set -CONFIG_BQL=y - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_CAN is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_AF_RXRPC is not set -CONFIG_WIRELESS=y -# CONFIG_CFG80211 is not set -# CONFIG_LIB80211 is not set - -# -# CFG80211 needs to be enabled for MAC80211 -# -# CONFIG_WIMAX is not set -# CONFIG_RFKILL is not set -# CONFIG_NET_9P is not set -# CONFIG_CAIF is not set -# CONFIG_CEPH_LIB is not set -# CONFIG_NFC is not set - -# -# UML Network Devices -# -CONFIG_UML_NET=y -CONFIG_UML_NET_ETHERTAP=y -CONFIG_UML_NET_TUNTAP=y -CONFIG_UML_NET_SLIP=y -CONFIG_UML_NET_DAEMON=y -# CONFIG_UML_NET_VDE is not set -CONFIG_UML_NET_MCAST=y -# CONFIG_UML_NET_PCAP is not set -CONFIG_UML_NET_SLIRP=y - -# -# File systems -# -# CONFIG_EXT2_FS is not set -# CONFIG_EXT3_FS is not set -CONFIG_EXT4_FS=y -CONFIG_EXT4_USE_FOR_EXT23=y -CONFIG_EXT4_FS_XATTR=y -# CONFIG_EXT4_FS_POSIX_ACL is not set -# CONFIG_EXT4_FS_SECURITY is not set -# CONFIG_EXT4_DEBUG is not set -CONFIG_JBD2=y -CONFIG_FS_MBCACHE=y -CONFIG_REISERFS_FS=y -# CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_PROC_INFO is not set -# CONFIG_REISERFS_FS_XATTR is not set -# CONFIG_JFS_FS is not set -# CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set -# CONFIG_BTRFS_FS is not set -# CONFIG_NILFS2_FS is not set -# CONFIG_FS_POSIX_ACL is not set -CONFIG_FILE_LOCKING=y -CONFIG_FSNOTIFY=y -CONFIG_DNOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_FANOTIFY is not set -CONFIG_QUOTA=y -# CONFIG_QUOTA_NETLINK_INTERFACE is not set -CONFIG_PRINT_QUOTA_WARNING=y -# CONFIG_QUOTA_DEBUG is not set -# CONFIG_QFMT_V1 is not set -# CONFIG_QFMT_V2 is not set -CONFIG_QUOTACTL=y -CONFIG_AUTOFS4_FS=m -# CONFIG_FUSE_FS is not set - -# -# Caches -# -# CONFIG_FSCACHE is not set - -# -# CD-ROM/DVD Filesystems -# -CONFIG_ISO9660_FS=m -CONFIG_JOLIET=y -# CONFIG_ZISOFS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_PROC_SYSCTL=y -CONFIG_PROC_PAGE_MONITOR=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set -# CONFIG_TMPFS_XATTR is not set -# CONFIG_HUGETLB_PAGE is not set -# CONFIG_CONFIGFS_FS is not set -CONFIG_MISC_FILESYSTEMS=y -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_LOGFS is not set -# CONFIG_CRAMFS is not set -# CONFIG_SQUASHFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_OMFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_PSTORE is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set -CONFIG_NETWORK_FILESYSTEMS=y -# CONFIG_NFS_FS is not set -# CONFIG_NFSD is not set -# CONFIG_CEPH_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -# CONFIG_NLS_CODEPAGE_437 is not set -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ASCII is not set -# CONFIG_NLS_ISO8859_1 is not set -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY_DMESG_RESTRICT is not set -# CONFIG_SECURITY is not set -# CONFIG_SECURITYFS is not set -CONFIG_DEFAULT_SECURITY_DAC=y -CONFIG_DEFAULT_SECURITY="" -CONFIG_CRYPTO=y - -# -# Crypto core or helper -# -# CONFIG_CRYPTO_FIPS is not set -CONFIG_CRYPTO_ALGAPI=m -CONFIG_CRYPTO_ALGAPI2=m -CONFIG_CRYPTO_RNG=m -CONFIG_CRYPTO_RNG2=m -# CONFIG_CRYPTO_MANAGER is not set -# CONFIG_CRYPTO_MANAGER2 is not set -# CONFIG_CRYPTO_USER is not set -# CONFIG_CRYPTO_GF128MUL is not set -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_CRYPTD is not set -# CONFIG_CRYPTO_AUTHENC is not set -# CONFIG_CRYPTO_TEST is not set - -# -# Authenticated Encryption with Associated Data -# -# CONFIG_CRYPTO_CCM is not set -# CONFIG_CRYPTO_GCM is not set -# CONFIG_CRYPTO_SEQIV is not set - -# -# Block modes -# -# CONFIG_CRYPTO_CBC is not set -# CONFIG_CRYPTO_CTR is not set -# CONFIG_CRYPTO_CTS is not set -# CONFIG_CRYPTO_ECB is not set -# CONFIG_CRYPTO_LRW is not set -# CONFIG_CRYPTO_PCBC is not set -# CONFIG_CRYPTO_XTS is not set - -# -# Hash modes -# -# CONFIG_CRYPTO_HMAC is not set -# CONFIG_CRYPTO_XCBC is not set -# CONFIG_CRYPTO_VMAC is not set - -# -# Digest -# -# CONFIG_CRYPTO_CRC32C is not set -# CONFIG_CRYPTO_GHASH is not set -# CONFIG_CRYPTO_MD4 is not set -# CONFIG_CRYPTO_MD5 is not set -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# CONFIG_CRYPTO_RMD128 is not set -# CONFIG_CRYPTO_RMD160 is not set -# CONFIG_CRYPTO_RMD256 is not set -# CONFIG_CRYPTO_RMD320 is not set -# CONFIG_CRYPTO_SHA1 is not set -# CONFIG_CRYPTO_SHA256 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_TGR192 is not set -# CONFIG_CRYPTO_WP512 is not set - -# -# Ciphers -# -CONFIG_CRYPTO_AES=m -# CONFIG_CRYPTO_AES_586 is not set -# CONFIG_CRYPTO_ANUBIS is not set -# CONFIG_CRYPTO_ARC4 is not set -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_CAMELLIA is not set -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -# CONFIG_CRYPTO_DES is not set -# CONFIG_CRYPTO_FCRYPT is not set -# CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_SALSA20 is not set -# CONFIG_CRYPTO_SALSA20_586 is not set -# CONFIG_CRYPTO_SEED is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_TEA is not set -# CONFIG_CRYPTO_TWOFISH is not set -# CONFIG_CRYPTO_TWOFISH_586 is not set - -# -# Compression -# -# CONFIG_CRYPTO_DEFLATE is not set -# CONFIG_CRYPTO_ZLIB is not set -# CONFIG_CRYPTO_LZO is not set - -# -# Random Number Generation -# -CONFIG_CRYPTO_ANSI_CPRNG=m -# CONFIG_CRYPTO_USER_API_HASH is not set -# CONFIG_CRYPTO_USER_API_SKCIPHER is not set -CONFIG_CRYPTO_HW=y -# CONFIG_BINARY_PRINTF is not set - -# -# Library routines -# -CONFIG_BITREVERSE=y -CONFIG_GENERIC_FIND_FIRST_BIT=y -CONFIG_GENERIC_IO=y -# CONFIG_CRC_CCITT is not set -CONFIG_CRC16=y -# CONFIG_CRC_T10DIF is not set -# CONFIG_CRC_ITU_T is not set -CONFIG_CRC32=y -# CONFIG_CRC7 is not set -# CONFIG_LIBCRC32C is not set -# CONFIG_CRC8 is not set -# CONFIG_XZ_DEC is not set -# CONFIG_XZ_DEC_BCJ is not set -CONFIG_DQL=y -CONFIG_NLATTR=y -# CONFIG_AVERAGE is not set -# CONFIG_CORDIC is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4 -CONFIG_ENABLE_WARN_DEPRECATED=y -CONFIG_ENABLE_MUST_CHECK=y -CONFIG_FRAME_WARN=1024 -# CONFIG_STRIP_ASM_SYMS is not set -# CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_DEBUG_SECTION_MISMATCH is not set -CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_SHIRQ is not set -# CONFIG_LOCKUP_DETECTOR is not set -# CONFIG_HARDLOCKUP_DETECTOR is not set -# CONFIG_DETECT_HUNG_TASK is not set -CONFIG_SCHED_DEBUG=y -# CONFIG_SCHEDSTATS is not set -# CONFIG_TIMER_STATS is not set -# CONFIG_DEBUG_OBJECTS is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_MUTEXES is not set -# CONFIG_SPARSE_RCU_POINTER is not set -# CONFIG_DEBUG_ATOMIC_SLEEP is not set -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -# CONFIG_DEBUG_STACK_USAGE is not set -# CONFIG_DEBUG_KOBJECT is not set -CONFIG_DEBUG_BUGVERBOSE=y -CONFIG_DEBUG_INFO=y -# CONFIG_DEBUG_INFO_REDUCED is not set -# CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_WRITECOUNT is not set -CONFIG_DEBUG_MEMORY_INIT=y -# CONFIG_DEBUG_LIST is not set -# CONFIG_TEST_LIST_SORT is not set -# CONFIG_DEBUG_SG is not set -# CONFIG_DEBUG_NOTIFIERS is not set -# CONFIG_DEBUG_CREDENTIALS is not set -CONFIG_FRAME_POINTER=y -# CONFIG_BOOT_PRINTK_DELAY is not set -# CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_BACKTRACE_SELF_TEST is not set -# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set -# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set -# CONFIG_FAULT_INJECTION is not set -# CONFIG_SYSCTL_SYSCALL_CHECK is not set -# CONFIG_DEBUG_PAGEALLOC is not set -# CONFIG_ATOMIC64_SELFTEST is not set -# CONFIG_SAMPLES is not set -# CONFIG_TEST_KSTRTOX is not set -# CONFIG_GPROF is not set -# CONFIG_GCOV is not set -CONFIG_EARLY_PRINTK=y diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index 3df3bd544492..29880c9b324e 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c @@ -645,11 +645,9 @@ void mconsole_sysrq(struct mc_request *req) static void stack_proc(void *arg) { - struct task_struct *from = current, *to = arg; + struct task_struct *task = arg; - to->thread.saved_task = from; - rcu_user_hooks_switch(from, to); - switch_to(from, to, from); + show_stack(task, NULL); } /* diff --git a/arch/um/include/asm/Kbuild b/arch/um/include/asm/Kbuild index b30f34a79882..fdde187e6087 100644 --- a/arch/um/include/asm/Kbuild +++ b/arch/um/include/asm/Kbuild @@ -3,3 +3,4 @@ generic-y += hw_irq.h irq_regs.h kdebug.h percpu.h sections.h topology.h xor.h generic-y += ftrace.h pci.h io.h param.h delay.h mutex.h current.h exec.h generic-y += switch_to.h clkdev.h generic-y += trace_clock.h +generic-y += preempt.h diff --git a/arch/um/include/asm/processor-generic.h b/arch/um/include/asm/processor-generic.h index c03cd5a02364..d89b02bb6262 100644 --- a/arch/um/include/asm/processor-generic.h +++ b/arch/um/include/asm/processor-generic.h @@ -19,8 +19,8 @@ struct task_struct; struct mm_struct; struct thread_struct { - struct task_struct *saved_task; struct pt_regs regs; + struct pt_regs *segv_regs; int singlestep_syscall; void *fault_addr; jmp_buf *fault_catcher; diff --git a/arch/um/include/asm/thread_info.h b/arch/um/include/asm/thread_info.h index 2c8eeb2df8b4..1c5b2a83046a 100644 --- a/arch/um/include/asm/thread_info.h +++ b/arch/um/include/asm/thread_info.h @@ -60,8 +60,6 @@ static inline struct thread_info *current_thread_info(void) #endif -#define PREEMPT_ACTIVE 0x10000000 - #define TIF_SYSCALL_TRACE 0 /* syscall trace active */ #define TIF_SIGPENDING 1 /* signal pending */ #define TIF_NEED_RESCHED 2 /* rescheduling necessary */ diff --git a/arch/um/include/shared/as-layout.h b/arch/um/include/shared/as-layout.h index 694c792bab4e..41c8c774ec10 100644 --- a/arch/um/include/shared/as-layout.h +++ b/arch/um/include/shared/as-layout.h @@ -44,7 +44,6 @@ struct cpu_task { extern struct cpu_task cpu_tasks[]; -extern unsigned long low_physmem; extern unsigned long high_physmem; extern unsigned long uml_physmem; extern unsigned long uml_reserved; @@ -52,8 +51,6 @@ extern unsigned long end_vm; extern unsigned long start_vm; extern unsigned long long highmem; -extern unsigned long _stext, _etext, _sdata, _edata, __bss_start, _end; -extern unsigned long _unprotected_end; extern unsigned long brk_start; extern unsigned long host_task_size; diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h index 021104d98cb3..75298d3358e7 100644 --- a/arch/um/include/shared/os.h +++ b/arch/um/include/shared/os.h @@ -227,6 +227,7 @@ extern void block_signals(void); extern void unblock_signals(void); extern int get_signals(void); extern int set_signals(int enable); +extern int os_is_signal_stack(void); /* util.c */ extern void stack_protections(unsigned long address); diff --git a/arch/um/kernel/exitcode.c b/arch/um/kernel/exitcode.c index 829df49dee99..41ebbfebb333 100644 --- a/arch/um/kernel/exitcode.c +++ b/arch/um/kernel/exitcode.c @@ -40,9 +40,11 @@ static ssize_t exitcode_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *pos) { char *end, buf[sizeof("nnnnn\0")]; + size_t size; int tmp; - if (copy_from_user(buf, buffer, count)) + size = min(count, sizeof(buf)); + if (copy_from_user(buf, buffer, size)) return -EFAULT; tmp = simple_strtol(buf, &end, 0); diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c index 7ddb64baf327..8636e905426f 100644 --- a/arch/um/kernel/mem.c +++ b/arch/um/kernel/mem.c @@ -279,8 +279,12 @@ pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address) struct page *pte; pte = alloc_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO); - if (pte) - pgtable_page_ctor(pte); + if (!pte) + return NULL; + if (!pgtable_page_ctor(pte)) { + __free_page(pte); + return NULL; + } return pte; } diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index bbcef522bcb1..eecc4142764c 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -82,19 +82,8 @@ void *__switch_to(struct task_struct *from, struct task_struct *to) to->thread.prev_sched = from; set_current(to); - do { - current->thread.saved_task = NULL; - - switch_threads(&from->thread.switch_buf, - &to->thread.switch_buf); - - arch_switch_to(current); - - if (current->thread.saved_task) - show_regs(&(current->thread.regs)); - to = current->thread.saved_task; - from = current; - } while (current->thread.saved_task); + switch_threads(&from->thread.switch_buf, &to->thread.switch_buf); + arch_switch_to(current); return current->thread.prev_sched; } diff --git a/arch/um/kernel/sysrq.c b/arch/um/kernel/sysrq.c index 0dc4d1c6f98a..4d6fdf68edf3 100644 --- a/arch/um/kernel/sysrq.c +++ b/arch/um/kernel/sysrq.c @@ -1,6 +1,10 @@ /* * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL + * Copyright (C) 2013 Richard Weinberger <richrd@nod.at> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. */ #include <linux/kallsyms.h> @@ -8,59 +12,87 @@ #include <linux/module.h> #include <linux/sched.h> #include <asm/sysrq.h> +#include <os.h> -/* Catch non-i386 SUBARCH's. */ -#if !defined(CONFIG_UML_X86) || defined(CONFIG_64BIT) -void show_trace(struct task_struct *task, unsigned long * stack) +struct stack_frame { + struct stack_frame *next_frame; + unsigned long return_address; +}; + +static void print_stack_trace(unsigned long *sp, unsigned long bp) { + int reliable; unsigned long addr; + struct stack_frame *frame = (struct stack_frame *)bp; - if (!stack) { - stack = (unsigned long*) &stack; - WARN_ON(1); - } - - printk(KERN_INFO "Call Trace: \n"); - while (((long) stack & (THREAD_SIZE-1)) != 0) { - addr = *stack; + printk(KERN_INFO "Call Trace:\n"); + while (((long) sp & (THREAD_SIZE-1)) != 0) { + addr = *sp; if (__kernel_text_address(addr)) { - printk(KERN_INFO "%08lx: [<%08lx>]", - (unsigned long) stack, addr); - print_symbol(KERN_CONT " %s", addr); + reliable = 0; + if ((unsigned long) sp == bp + sizeof(long)) { + frame = frame ? frame->next_frame : NULL; + bp = (unsigned long)frame; + reliable = 1; + } + + printk(KERN_INFO " [<%08lx>]", addr); + printk(KERN_CONT " %s", reliable ? "" : "? "); + print_symbol(KERN_CONT "%s", addr); printk(KERN_CONT "\n"); } - stack++; + sp++; } printk(KERN_INFO "\n"); } -#endif -/*Stolen from arch/i386/kernel/traps.c */ -static const int kstack_depth_to_print = 24; +static unsigned long get_frame_pointer(struct task_struct *task, + struct pt_regs *segv_regs) +{ + if (!task || task == current) + return segv_regs ? PT_REGS_BP(segv_regs) : current_bp(); + else + return KSTK_EBP(task); +} -/* This recently started being used in arch-independent code too, as in - * kernel/sched/core.c.*/ -void show_stack(struct task_struct *task, unsigned long *esp) +static unsigned long *get_stack_pointer(struct task_struct *task, + struct pt_regs *segv_regs) { - unsigned long *stack; + if (!task || task == current) + return segv_regs ? (unsigned long *)PT_REGS_SP(segv_regs) : current_sp(); + else + return (unsigned long *)KSTK_ESP(task); +} + +void show_stack(struct task_struct *task, unsigned long *stack) +{ + unsigned long *sp = stack, bp = 0; + struct pt_regs *segv_regs = current->thread.segv_regs; int i; - if (esp == NULL) { - if (task != current && task != NULL) { - esp = (unsigned long *) KSTK_ESP(task); - } else { - esp = (unsigned long *) &esp; - } + if (!segv_regs && os_is_signal_stack()) { + printk(KERN_ERR "Received SIGSEGV in SIGSEGV handler," + " aborting stack trace!\n"); + return; } - stack = esp; - for (i = 0; i < kstack_depth_to_print; i++) { +#ifdef CONFIG_FRAME_POINTER + bp = get_frame_pointer(task, segv_regs); +#endif + + if (!stack) + sp = get_stack_pointer(task, segv_regs); + + printk(KERN_INFO "Stack:\n"); + stack = sp; + for (i = 0; i < 3 * STACKSLOTS_PER_LINE; i++) { if (kstack_end(stack)) break; - if (i && ((i % 8) == 0)) - printk(KERN_INFO " "); - printk(KERN_CONT "%08lx ", *stack++); + if (i && ((i % STACKSLOTS_PER_LINE) == 0)) + printk(KERN_CONT "\n"); + printk(KERN_CONT " %08lx", *stack++); } + printk(KERN_CONT "\n"); - show_trace(task, esp); + print_stack_trace(sp, bp); } diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c index 5c3aef74237f..974b87474a99 100644 --- a/arch/um/kernel/trap.c +++ b/arch/um/kernel/trap.c @@ -206,9 +206,12 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, int is_write = FAULT_WRITE(fi); unsigned long address = FAULT_ADDRESS(fi); + if (regs) + current->thread.segv_regs = container_of(regs, struct pt_regs, regs); + if (!is_user && (address >= start_vm) && (address < end_vm)) { flush_tlb_kernel_vm(); - return 0; + goto out; } else if (current->mm == NULL) { show_regs(container_of(regs, struct pt_regs, regs)); @@ -230,7 +233,7 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, catcher = current->thread.fault_catcher; if (!err) - return 0; + goto out; else if (catcher != NULL) { current->thread.fault_addr = (void *) address; UML_LONGJMP(catcher, 1); @@ -238,7 +241,7 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, else if (current->thread.fault_addr != NULL) panic("fault_addr set but no fault catcher"); else if (!is_user && arch_fixup(ip, regs)) - return 0; + goto out; if (!is_user) { show_regs(container_of(regs, struct pt_regs, regs)); @@ -262,6 +265,11 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, current->thread.arch.faultinfo = fi; force_sig_info(SIGSEGV, &si, current); } + +out: + if (regs) + current->thread.segv_regs = NULL; + return 0; } diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 87df5e3acc26..016adf0985d5 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -13,6 +13,7 @@ #include <linux/sched.h> #include <asm/pgtable.h> #include <asm/processor.h> +#include <asm/sections.h> #include <asm/setup.h> #include <as-layout.h> #include <arch.h> @@ -234,7 +235,6 @@ static int panic_exit(struct notifier_block *self, unsigned long unused1, void *unused2) { bust_spinlocks(1); - show_regs(&(current->thread.regs)); bust_spinlocks(0); uml_exitcode = 1; os_dump_core(); diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index 905924b773d3..7b605e4dfffa 100644 --- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c @@ -304,3 +304,11 @@ int set_signals(int enable) return ret; } + +int os_is_signal_stack(void) +{ + stack_t ss; + sigaltstack(NULL, &ss); + + return ss.ss_flags & SS_ONSTACK; +} diff --git a/arch/unicore32/Kconfig b/arch/unicore32/Kconfig index 82cdd8906f3d..a7ba27b2752b 100644 --- a/arch/unicore32/Kconfig +++ b/arch/unicore32/Kconfig @@ -1,5 +1,6 @@ config UNICORE32 def_bool y + select ARCH_MIGHT_HAVE_PC_PARPORT select HAVE_MEMBLOCK select HAVE_GENERIC_DMA_COHERENT select HAVE_DMA_ATTRS diff --git a/arch/unicore32/include/asm/Kbuild b/arch/unicore32/include/asm/Kbuild index 89d8b6c4e39a..00045cbe5c63 100644 --- a/arch/unicore32/include/asm/Kbuild +++ b/arch/unicore32/include/asm/Kbuild @@ -60,3 +60,4 @@ generic-y += unaligned.h generic-y += user.h generic-y += vga.h generic-y += xor.h +generic-y += preempt.h diff --git a/arch/unicore32/include/asm/pgalloc.h b/arch/unicore32/include/asm/pgalloc.h index 0213e373a895..2e02d1356fdf 100644 --- a/arch/unicore32/include/asm/pgalloc.h +++ b/arch/unicore32/include/asm/pgalloc.h @@ -51,12 +51,14 @@ pte_alloc_one(struct mm_struct *mm, unsigned long addr) struct page *pte; pte = alloc_pages(PGALLOC_GFP, 0); - if (pte) { - if (!PageHighMem(pte)) { - void *page = page_address(pte); - clean_dcache_area(page, PTRS_PER_PTE * sizeof(pte_t)); - } - pgtable_page_ctor(pte); + if (!pte) + return NULL; + if (!PageHighMem(pte)) { + void *page = page_address(pte); + clean_dcache_area(page, PTRS_PER_PTE * sizeof(pte_t)); + } + if (!pgtable_page_ctor(pte)) { + __free_page(pte); } return pte; diff --git a/arch/unicore32/include/asm/thread_info.h b/arch/unicore32/include/asm/thread_info.h index 818b4a1edb5b..af36d8eabdf1 100644 --- a/arch/unicore32/include/asm/thread_info.h +++ b/arch/unicore32/include/asm/thread_info.h @@ -118,12 +118,6 @@ static inline struct thread_info *current_thread_info(void) #endif /* - * We use bit 30 of the preempt_count to indicate that kernel - * preemption is occurring. See <asm/hardirq.h>. - */ -#define PREEMPT_ACTIVE 0x40000000 - -/* * thread information flags: * TIF_SYSCALL_TRACE - syscall trace active * TIF_SIGPENDING - signal pending diff --git a/arch/unicore32/kernel/puv3-nb0916.c b/arch/unicore32/kernel/puv3-nb0916.c index 181108b8ecce..0c6618e71897 100644 --- a/arch/unicore32/kernel/puv3-nb0916.c +++ b/arch/unicore32/kernel/puv3-nb0916.c @@ -54,6 +54,7 @@ static struct platform_pwm_backlight_data nb0916_backlight_data = { .max_brightness = 100, .dft_brightness = 100, .pwm_period_ns = 70 * 1024, + .enable_gpio = -1, }; static struct gpio_keys_button nb0916_gpio_keys[] = { diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index f67e839f06c8..e903c71f7e69 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -22,6 +22,7 @@ config X86_64 config X86 def_bool y select ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS + select ARCH_MIGHT_HAVE_PC_PARPORT select HAVE_AOUT if X86_32 select HAVE_UNSTABLE_SCHED_CLOCK select ARCH_SUPPORTS_NUMA_BALANCING @@ -90,7 +91,6 @@ config X86 select GENERIC_IRQ_SHOW select GENERIC_CLOCKEVENTS_MIN_ADJUST select IRQ_FORCED_THREADING - select USE_GENERIC_SMP_HELPERS if SMP select HAVE_BPF_JIT if X86_64 select HAVE_ARCH_TRANSPARENT_HUGEPAGE select CLKEVT_I8253 @@ -123,6 +123,7 @@ config X86 select COMPAT_OLD_SIGACTION if IA32_EMULATION select RTC_LIB select HAVE_DEBUG_STACKOVERFLOW + select HAVE_IRQ_EXIT_ON_IRQ_STACK if X86_64 config INSTRUCTION_DECODER def_bool y @@ -254,10 +255,6 @@ config ARCH_HWEIGHT_CFLAGS default "-fcall-saved-ecx -fcall-saved-edx" if X86_32 default "-fcall-saved-rdi -fcall-saved-rsi -fcall-saved-rdx -fcall-saved-rcx -fcall-saved-r8 -fcall-saved-r9 -fcall-saved-r10 -fcall-saved-r11" if X86_64 -config ARCH_CPU_PROBE_RELEASE - def_bool y - depends on HOTPLUG_CPU - config ARCH_SUPPORTS_UPROBES def_bool y @@ -638,10 +635,10 @@ config PARAVIRT_SPINLOCKS spinlock implementation with something virtualization-friendly (for example, block the virtual CPU rather than spinning). - Unfortunately the downside is an up to 5% performance hit on - native kernels, with various workloads. + It has a minimal impact on native kernels and gives a nice performance + benefit on paravirtualized KVM / Xen kernels. - If you are unsure how to answer this question, answer N. + If you are unsure how to answer this question, answer Y. source "arch/x86/xen/Kconfig" @@ -756,20 +753,25 @@ config DMI BIOS code. config GART_IOMMU - bool "GART IOMMU support" if EXPERT - default y + bool "Old AMD GART IOMMU support" select SWIOTLB depends on X86_64 && PCI && AMD_NB ---help--- - Support for full DMA access of devices with 32bit memory access only - on systems with more than 3GB. This is usually needed for USB, - sound, many IDE/SATA chipsets and some other devices. - Provides a driver for the AMD Athlon64/Opteron/Turion/Sempron GART - based hardware IOMMU and a software bounce buffer based IOMMU used - on Intel systems and as fallback. - The code is only active when needed (enough memory and limited - device) unless CONFIG_IOMMU_DEBUG or iommu=force is specified - too. + Provides a driver for older AMD Athlon64/Opteron/Turion/Sempron + GART based hardware IOMMUs. + + The GART supports full DMA access for devices with 32-bit access + limitations, on systems with more than 3 GB. This is usually needed + for USB, sound, many IDE/SATA chipsets and some other devices. + + Newer systems typically have a modern AMD IOMMU, supported via + the CONFIG_AMD_IOMMU=y config option. + + In normal configurations this driver is only active when needed: + there's more than 3 GB of memory and the system contains a + 32-bit limited device. + + If unsure, say Y. config CALGARY_IOMMU bool "IBM Calgary IOMMU support" @@ -825,14 +827,16 @@ config MAXSMP config NR_CPUS int "Maximum number of CPUs" if SMP && !MAXSMP range 2 8 if SMP && X86_32 && !X86_BIGSMP - range 2 512 if SMP && !MAXSMP + range 2 512 if SMP && !MAXSMP && !CPUMASK_OFFSTACK + range 2 8192 if SMP && !MAXSMP && CPUMASK_OFFSTACK && X86_64 default "1" if !SMP - default "4096" if MAXSMP + default "8192" if MAXSMP default "32" if SMP && (X86_NUMAQ || X86_SUMMIT || X86_BIGSMP || X86_ES7000) default "8" if SMP ---help--- This allows you to specify the maximum number of CPUs which this - kernel will support. The maximum supported value is 512 and the + kernel will support. If CPUMASK_OFFSTACK is enabled, the maximum + supported value is 4096, otherwise the maximum value is 512. The minimum value which makes sense is 2. This is purely to save memory - each supported CPU adds @@ -1594,7 +1598,7 @@ config EFI_STUB This kernel feature allows a bzImage to be loaded directly by EFI firmware without the use of a bootloader. - See Documentation/x86/efi-stub.txt for more information. + See Documentation/efi-stub.txt for more information. config SECCOMP def_bool y @@ -1881,6 +1885,10 @@ config USE_PERCPU_NUMA_NODE_ID def_bool y depends on NUMA +config ARCH_ENABLE_SPLIT_PMD_PTLOCK + def_bool y + depends on X86_64 || X86_PAE + menu "Power management and ACPI options" config ARCH_HIBERNATION_HEADER diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index 78d91afb8e50..0f3621ed1db6 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug @@ -59,6 +59,16 @@ config EARLY_PRINTK_DBGP with klogd/syslogd or the X server. You should normally N here, unless you want to debug such a crash. You need usb debug device. +config EARLY_PRINTK_EFI + bool "Early printk via the EFI framebuffer" + depends on EFI && EARLY_PRINTK + select FONT_SUPPORT + ---help--- + Write kernel log output directly into the EFI framebuffer. + + This is useful for kernel debugging when your machine crashes very + early before the console code is initialized. + config X86_PTDUMP bool "Export kernel pagetable layout to userspace via debugfs" depends on DEBUG_KERNEL diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile index 379814bc41e3..dce69a256896 100644 --- a/arch/x86/boot/Makefile +++ b/arch/x86/boot/Makefile @@ -71,7 +71,8 @@ GCOV_PROFILE := n $(obj)/bzImage: asflags-y := $(SVGA_MODE) quiet_cmd_image = BUILD $@ -cmd_image = $(obj)/tools/build $(obj)/setup.bin $(obj)/vmlinux.bin $(obj)/zoffset.h > $@ +cmd_image = $(obj)/tools/build $(obj)/setup.bin $(obj)/vmlinux.bin \ + $(obj)/zoffset.h $@ $(obj)/bzImage: $(obj)/setup.bin $(obj)/vmlinux.bin $(obj)/tools/build FORCE $(call if_changed,image) diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index b7388a425f09..a7677babf946 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c @@ -19,214 +19,10 @@ static efi_system_table_t *sys_table; -static void efi_char16_printk(efi_char16_t *str) -{ - struct efi_simple_text_output_protocol *out; - - out = (struct efi_simple_text_output_protocol *)sys_table->con_out; - efi_call_phys2(out->output_string, out, str); -} - -static void efi_printk(char *str) -{ - char *s8; - - for (s8 = str; *s8; s8++) { - efi_char16_t ch[2] = { 0 }; - - ch[0] = *s8; - if (*s8 == '\n') { - efi_char16_t nl[2] = { '\r', 0 }; - efi_char16_printk(nl); - } - - efi_char16_printk(ch); - } -} - -static efi_status_t __get_map(efi_memory_desc_t **map, unsigned long *map_size, - unsigned long *desc_size) -{ - efi_memory_desc_t *m = NULL; - efi_status_t status; - unsigned long key; - u32 desc_version; - - *map_size = sizeof(*m) * 32; -again: - /* - * Add an additional efi_memory_desc_t because we're doing an - * allocation which may be in a new descriptor region. - */ - *map_size += sizeof(*m); - status = efi_call_phys3(sys_table->boottime->allocate_pool, - EFI_LOADER_DATA, *map_size, (void **)&m); - if (status != EFI_SUCCESS) - goto fail; - - status = efi_call_phys5(sys_table->boottime->get_memory_map, map_size, - m, &key, desc_size, &desc_version); - if (status == EFI_BUFFER_TOO_SMALL) { - efi_call_phys1(sys_table->boottime->free_pool, m); - goto again; - } - - if (status != EFI_SUCCESS) - efi_call_phys1(sys_table->boottime->free_pool, m); -fail: - *map = m; - return status; -} - -/* - * Allocate at the highest possible address that is not above 'max'. - */ -static efi_status_t high_alloc(unsigned long size, unsigned long align, - unsigned long *addr, unsigned long max) -{ - unsigned long map_size, desc_size; - efi_memory_desc_t *map; - efi_status_t status; - unsigned long nr_pages; - u64 max_addr = 0; - int i; - - status = __get_map(&map, &map_size, &desc_size); - if (status != EFI_SUCCESS) - goto fail; - - nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE; -again: - for (i = 0; i < map_size / desc_size; i++) { - efi_memory_desc_t *desc; - unsigned long m = (unsigned long)map; - u64 start, end; - - desc = (efi_memory_desc_t *)(m + (i * desc_size)); - if (desc->type != EFI_CONVENTIONAL_MEMORY) - continue; - - if (desc->num_pages < nr_pages) - continue; +#include "../../../../drivers/firmware/efi/efi-stub-helper.c" - start = desc->phys_addr; - end = start + desc->num_pages * (1UL << EFI_PAGE_SHIFT); - if ((start + size) > end || (start + size) > max) - continue; - - if (end - size > max) - end = max; - - if (round_down(end - size, align) < start) - continue; - - start = round_down(end - size, align); - - /* - * Don't allocate at 0x0. It will confuse code that - * checks pointers against NULL. - */ - if (start == 0x0) - continue; - - if (start > max_addr) - max_addr = start; - } - - if (!max_addr) - status = EFI_NOT_FOUND; - else { - status = efi_call_phys4(sys_table->boottime->allocate_pages, - EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA, - nr_pages, &max_addr); - if (status != EFI_SUCCESS) { - max = max_addr; - max_addr = 0; - goto again; - } - - *addr = max_addr; - } - -free_pool: - efi_call_phys1(sys_table->boottime->free_pool, map); - -fail: - return status; -} - -/* - * Allocate at the lowest possible address. - */ -static efi_status_t low_alloc(unsigned long size, unsigned long align, - unsigned long *addr) -{ - unsigned long map_size, desc_size; - efi_memory_desc_t *map; - efi_status_t status; - unsigned long nr_pages; - int i; - - status = __get_map(&map, &map_size, &desc_size); - if (status != EFI_SUCCESS) - goto fail; - - nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE; - for (i = 0; i < map_size / desc_size; i++) { - efi_memory_desc_t *desc; - unsigned long m = (unsigned long)map; - u64 start, end; - - desc = (efi_memory_desc_t *)(m + (i * desc_size)); - - if (desc->type != EFI_CONVENTIONAL_MEMORY) - continue; - - if (desc->num_pages < nr_pages) - continue; - - start = desc->phys_addr; - end = start + desc->num_pages * (1UL << EFI_PAGE_SHIFT); - - /* - * Don't allocate at 0x0. It will confuse code that - * checks pointers against NULL. Skip the first 8 - * bytes so we start at a nice even number. - */ - if (start == 0x0) - start += 8; - - start = round_up(start, align); - if ((start + size) > end) - continue; - - status = efi_call_phys4(sys_table->boottime->allocate_pages, - EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA, - nr_pages, &start); - if (status == EFI_SUCCESS) { - *addr = start; - break; - } - } - - if (i == map_size / desc_size) - status = EFI_NOT_FOUND; - -free_pool: - efi_call_phys1(sys_table->boottime->free_pool, map); -fail: - return status; -} - -static void low_free(unsigned long size, unsigned long addr) -{ - unsigned long nr_pages; - - nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE; - efi_call_phys2(sys_table->boottime->free_pages, addr, nr_pages); -} static void find_bits(unsigned long mask, u8 *pos, u8 *size) { @@ -624,242 +420,6 @@ void setup_graphics(struct boot_params *boot_params) } } -struct initrd { - efi_file_handle_t *handle; - u64 size; -}; - -/* - * Check the cmdline for a LILO-style initrd= arguments. - * - * We only support loading an initrd from the same filesystem as the - * kernel image. - */ -static efi_status_t handle_ramdisks(efi_loaded_image_t *image, - struct setup_header *hdr) -{ - struct initrd *initrds; - unsigned long initrd_addr; - efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID; - u64 initrd_total; - efi_file_io_interface_t *io; - efi_file_handle_t *fh; - efi_status_t status; - int nr_initrds; - char *str; - int i, j, k; - - initrd_addr = 0; - initrd_total = 0; - - str = (char *)(unsigned long)hdr->cmd_line_ptr; - - j = 0; /* See close_handles */ - - if (!str || !*str) - return EFI_SUCCESS; - - for (nr_initrds = 0; *str; nr_initrds++) { - str = strstr(str, "initrd="); - if (!str) - break; - - str += 7; - - /* Skip any leading slashes */ - while (*str == '/' || *str == '\\') - str++; - - while (*str && *str != ' ' && *str != '\n') - str++; - } - - if (!nr_initrds) - return EFI_SUCCESS; - - status = efi_call_phys3(sys_table->boottime->allocate_pool, - EFI_LOADER_DATA, - nr_initrds * sizeof(*initrds), - &initrds); - if (status != EFI_SUCCESS) { - efi_printk("Failed to alloc mem for initrds\n"); - goto fail; - } - - str = (char *)(unsigned long)hdr->cmd_line_ptr; - for (i = 0; i < nr_initrds; i++) { - struct initrd *initrd; - efi_file_handle_t *h; - efi_file_info_t *info; - efi_char16_t filename_16[256]; - unsigned long info_sz; - efi_guid_t info_guid = EFI_FILE_INFO_ID; - efi_char16_t *p; - u64 file_sz; - - str = strstr(str, "initrd="); - if (!str) - break; - - str += 7; - - initrd = &initrds[i]; - p = filename_16; - - /* Skip any leading slashes */ - while (*str == '/' || *str == '\\') - str++; - - while (*str && *str != ' ' && *str != '\n') { - if ((u8 *)p >= (u8 *)filename_16 + sizeof(filename_16)) - break; - - if (*str == '/') { - *p++ = '\\'; - *str++; - } else { - *p++ = *str++; - } - } - - *p = '\0'; - - /* Only open the volume once. */ - if (!i) { - efi_boot_services_t *boottime; - - boottime = sys_table->boottime; - - status = efi_call_phys3(boottime->handle_protocol, - image->device_handle, &fs_proto, &io); - if (status != EFI_SUCCESS) { - efi_printk("Failed to handle fs_proto\n"); - goto free_initrds; - } - - status = efi_call_phys2(io->open_volume, io, &fh); - if (status != EFI_SUCCESS) { - efi_printk("Failed to open volume\n"); - goto free_initrds; - } - } - - status = efi_call_phys5(fh->open, fh, &h, filename_16, - EFI_FILE_MODE_READ, (u64)0); - if (status != EFI_SUCCESS) { - efi_printk("Failed to open initrd file: "); - efi_char16_printk(filename_16); - efi_printk("\n"); - goto close_handles; - } - - initrd->handle = h; - - info_sz = 0; - status = efi_call_phys4(h->get_info, h, &info_guid, - &info_sz, NULL); - if (status != EFI_BUFFER_TOO_SMALL) { - efi_printk("Failed to get initrd info size\n"); - goto close_handles; - } - -grow: - status = efi_call_phys3(sys_table->boottime->allocate_pool, - EFI_LOADER_DATA, info_sz, &info); - if (status != EFI_SUCCESS) { - efi_printk("Failed to alloc mem for initrd info\n"); - goto close_handles; - } - - status = efi_call_phys4(h->get_info, h, &info_guid, - &info_sz, info); - if (status == EFI_BUFFER_TOO_SMALL) { - efi_call_phys1(sys_table->boottime->free_pool, info); - goto grow; - } - - file_sz = info->file_size; - efi_call_phys1(sys_table->boottime->free_pool, info); - - if (status != EFI_SUCCESS) { - efi_printk("Failed to get initrd info\n"); - goto close_handles; - } - - initrd->size = file_sz; - initrd_total += file_sz; - } - - if (initrd_total) { - unsigned long addr; - - /* - * Multiple initrd's need to be at consecutive - * addresses in memory, so allocate enough memory for - * all the initrd's. - */ - status = high_alloc(initrd_total, 0x1000, - &initrd_addr, hdr->initrd_addr_max); - if (status != EFI_SUCCESS) { - efi_printk("Failed to alloc highmem for initrds\n"); - goto close_handles; - } - - /* We've run out of free low memory. */ - if (initrd_addr > hdr->initrd_addr_max) { - efi_printk("We've run out of free low memory\n"); - status = EFI_INVALID_PARAMETER; - goto free_initrd_total; - } - - addr = initrd_addr; - for (j = 0; j < nr_initrds; j++) { - u64 size; - - size = initrds[j].size; - while (size) { - u64 chunksize; - if (size > EFI_READ_CHUNK_SIZE) - chunksize = EFI_READ_CHUNK_SIZE; - else - chunksize = size; - status = efi_call_phys3(fh->read, - initrds[j].handle, - &chunksize, addr); - if (status != EFI_SUCCESS) { - efi_printk("Failed to read initrd\n"); - goto free_initrd_total; - } - addr += chunksize; - size -= chunksize; - } - - efi_call_phys1(fh->close, initrds[j].handle); - } - - } - - efi_call_phys1(sys_table->boottime->free_pool, initrds); - - hdr->ramdisk_image = initrd_addr; - hdr->ramdisk_size = initrd_total; - - return status; - -free_initrd_total: - low_free(initrd_total, initrd_addr); - -close_handles: - for (k = j; k < i; k++) - efi_call_phys1(fh->close, initrds[k].handle); -free_initrds: - efi_call_phys1(sys_table->boottime->free_pool, initrds); -fail: - hdr->ramdisk_image = 0; - hdr->ramdisk_size = 0; - - return status; -} /* * Because the x86 boot code expects to be passed a boot_params we @@ -875,14 +435,15 @@ struct boot_params *make_boot_params(void *handle, efi_system_table_t *_table) struct efi_info *efi; efi_loaded_image_t *image; void *options; - u32 load_options_size; efi_guid_t proto = LOADED_IMAGE_PROTOCOL_GUID; int options_size = 0; efi_status_t status; - unsigned long cmdline; + char *cmdline_ptr; u16 *s2; u8 *s1; int i; + unsigned long ramdisk_addr; + unsigned long ramdisk_size; sys_table = _table; @@ -893,13 +454,14 @@ struct boot_params *make_boot_params(void *handle, efi_system_table_t *_table) status = efi_call_phys3(sys_table->boottime->handle_protocol, handle, &proto, (void *)&image); if (status != EFI_SUCCESS) { - efi_printk("Failed to get handle for LOADED_IMAGE_PROTOCOL\n"); + efi_printk(sys_table, "Failed to get handle for LOADED_IMAGE_PROTOCOL\n"); return NULL; } - status = low_alloc(0x4000, 1, (unsigned long *)&boot_params); + status = efi_low_alloc(sys_table, 0x4000, 1, + (unsigned long *)&boot_params); if (status != EFI_SUCCESS) { - efi_printk("Failed to alloc lowmem for boot params\n"); + efi_printk(sys_table, "Failed to alloc lowmem for boot params\n"); return NULL; } @@ -926,40 +488,11 @@ struct boot_params *make_boot_params(void *handle, efi_system_table_t *_table) hdr->type_of_loader = 0x21; /* Convert unicode cmdline to ascii */ - options = image->load_options; - load_options_size = image->load_options_size / 2; /* ASCII */ - cmdline = 0; - s2 = (u16 *)options; - - if (s2) { - while (*s2 && *s2 != '\n' && options_size < load_options_size) { - s2++; - options_size++; - } - - if (options_size) { - if (options_size > hdr->cmdline_size) - options_size = hdr->cmdline_size; - - options_size++; /* NUL termination */ - - status = low_alloc(options_size, 1, &cmdline); - if (status != EFI_SUCCESS) { - efi_printk("Failed to alloc mem for cmdline\n"); - goto fail; - } - - s1 = (u8 *)(unsigned long)cmdline; - s2 = (u16 *)options; - - for (i = 0; i < options_size - 1; i++) - *s1++ = *s2++; - - *s1 = '\0'; - } - } - - hdr->cmd_line_ptr = cmdline; + cmdline_ptr = efi_convert_cmdline_to_ascii(sys_table, image, + &options_size); + if (!cmdline_ptr) + goto fail; + hdr->cmd_line_ptr = (unsigned long)cmdline_ptr; hdr->ramdisk_image = 0; hdr->ramdisk_size = 0; @@ -969,96 +502,64 @@ struct boot_params *make_boot_params(void *handle, efi_system_table_t *_table) memset(sdt, 0, sizeof(*sdt)); - status = handle_ramdisks(image, hdr); + status = handle_cmdline_files(sys_table, image, + (char *)(unsigned long)hdr->cmd_line_ptr, + "initrd=", hdr->initrd_addr_max, + &ramdisk_addr, &ramdisk_size); if (status != EFI_SUCCESS) goto fail2; + hdr->ramdisk_image = ramdisk_addr; + hdr->ramdisk_size = ramdisk_size; return boot_params; fail2: - if (options_size) - low_free(options_size, hdr->cmd_line_ptr); + efi_free(sys_table, options_size, hdr->cmd_line_ptr); fail: - low_free(0x4000, (unsigned long)boot_params); + efi_free(sys_table, 0x4000, (unsigned long)boot_params); return NULL; } -static efi_status_t exit_boot(struct boot_params *boot_params, - void *handle) +static void add_e820ext(struct boot_params *params, + struct setup_data *e820ext, u32 nr_entries) { - struct efi_info *efi = &boot_params->efi_info; - struct e820entry *e820_map = &boot_params->e820_map[0]; - struct e820entry *prev = NULL; - unsigned long size, key, desc_size, _size; - efi_memory_desc_t *mem_map; + struct setup_data *data; efi_status_t status; - __u32 desc_version; - bool called_exit = false; - u8 nr_entries; - int i; - - size = sizeof(*mem_map) * 32; - -again: - size += sizeof(*mem_map) * 2; - _size = size; - status = low_alloc(size, 1, (unsigned long *)&mem_map); - if (status != EFI_SUCCESS) - return status; - -get_map: - status = efi_call_phys5(sys_table->boottime->get_memory_map, &size, - mem_map, &key, &desc_size, &desc_version); - if (status == EFI_BUFFER_TOO_SMALL) { - low_free(_size, (unsigned long)mem_map); - goto again; - } + unsigned long size; - if (status != EFI_SUCCESS) - goto free_mem_map; + e820ext->type = SETUP_E820_EXT; + e820ext->len = nr_entries * sizeof(struct e820entry); + e820ext->next = 0; - memcpy(&efi->efi_loader_signature, EFI_LOADER_SIGNATURE, sizeof(__u32)); - efi->efi_systab = (unsigned long)sys_table; - efi->efi_memdesc_size = desc_size; - efi->efi_memdesc_version = desc_version; - efi->efi_memmap = (unsigned long)mem_map; - efi->efi_memmap_size = size; - -#ifdef CONFIG_X86_64 - efi->efi_systab_hi = (unsigned long)sys_table >> 32; - efi->efi_memmap_hi = (unsigned long)mem_map >> 32; -#endif + data = (struct setup_data *)(unsigned long)params->hdr.setup_data; - /* Might as well exit boot services now */ - status = efi_call_phys2(sys_table->boottime->exit_boot_services, - handle, key); - if (status != EFI_SUCCESS) { - /* - * ExitBootServices() will fail if any of the event - * handlers change the memory map. In which case, we - * must be prepared to retry, but only once so that - * we're guaranteed to exit on repeated failures instead - * of spinning forever. - */ - if (called_exit) - goto free_mem_map; + while (data && data->next) + data = (struct setup_data *)(unsigned long)data->next; - called_exit = true; - goto get_map; - } + if (data) + data->next = (unsigned long)e820ext; + else + params->hdr.setup_data = (unsigned long)e820ext; +} - /* Historic? */ - boot_params->alt_mem_k = 32 * 1024; +static efi_status_t setup_e820(struct boot_params *params, + struct setup_data *e820ext, u32 e820ext_size) +{ + struct e820entry *e820_map = ¶ms->e820_map[0]; + struct efi_info *efi = ¶ms->efi_info; + struct e820entry *prev = NULL; + u32 nr_entries; + u32 nr_desc; + int i; - /* - * Convert the EFI memory map to E820. - */ nr_entries = 0; - for (i = 0; i < size / desc_size; i++) { + nr_desc = efi->efi_memmap_size / efi->efi_memdesc_size; + + for (i = 0; i < nr_desc; i++) { efi_memory_desc_t *d; unsigned int e820_type = 0; - unsigned long m = (unsigned long)mem_map; + unsigned long m = efi->efi_memmap; - d = (efi_memory_desc_t *)(m + (i * desc_size)); + d = (efi_memory_desc_t *)(m + (i * efi->efi_memdesc_size)); switch (d->type) { case EFI_RESERVED_TYPE: case EFI_RUNTIME_SERVICES_CODE: @@ -1095,61 +596,151 @@ get_map: /* Merge adjacent mappings */ if (prev && prev->type == e820_type && - (prev->addr + prev->size) == d->phys_addr) + (prev->addr + prev->size) == d->phys_addr) { prev->size += d->num_pages << 12; - else { - e820_map->addr = d->phys_addr; - e820_map->size = d->num_pages << 12; - e820_map->type = e820_type; - prev = e820_map++; - nr_entries++; + continue; + } + + if (nr_entries == ARRAY_SIZE(params->e820_map)) { + u32 need = (nr_desc - i) * sizeof(struct e820entry) + + sizeof(struct setup_data); + + if (!e820ext || e820ext_size < need) + return EFI_BUFFER_TOO_SMALL; + + /* boot_params map full, switch to e820 extended */ + e820_map = (struct e820entry *)e820ext->data; } + + e820_map->addr = d->phys_addr; + e820_map->size = d->num_pages << PAGE_SHIFT; + e820_map->type = e820_type; + prev = e820_map++; + nr_entries++; } - boot_params->e820_entries = nr_entries; + if (nr_entries > ARRAY_SIZE(params->e820_map)) { + u32 nr_e820ext = nr_entries - ARRAY_SIZE(params->e820_map); + + add_e820ext(params, e820ext, nr_e820ext); + nr_entries -= nr_e820ext; + } + + params->e820_entries = (u8)nr_entries; return EFI_SUCCESS; +} + +static efi_status_t alloc_e820ext(u32 nr_desc, struct setup_data **e820ext, + u32 *e820ext_size) +{ + efi_status_t status; + unsigned long size; + + size = sizeof(struct setup_data) + + sizeof(struct e820entry) * nr_desc; + + if (*e820ext) { + efi_call_phys1(sys_table->boottime->free_pool, *e820ext); + *e820ext = NULL; + *e820ext_size = 0; + } + + status = efi_call_phys3(sys_table->boottime->allocate_pool, + EFI_LOADER_DATA, size, e820ext); + + if (status == EFI_SUCCESS) + *e820ext_size = size; -free_mem_map: - low_free(_size, (unsigned long)mem_map); return status; } -static efi_status_t relocate_kernel(struct setup_header *hdr) +static efi_status_t exit_boot(struct boot_params *boot_params, + void *handle) { - unsigned long start, nr_pages; + struct efi_info *efi = &boot_params->efi_info; + unsigned long map_sz, key, desc_size; + efi_memory_desc_t *mem_map; + struct setup_data *e820ext; + __u32 e820ext_size; + __u32 nr_desc, prev_nr_desc; efi_status_t status; + __u32 desc_version; + bool called_exit = false; + u8 nr_entries; + int i; - /* - * The EFI firmware loader could have placed the kernel image - * anywhere in memory, but the kernel has various restrictions - * on the max physical address it can run at. Attempt to move - * the kernel to boot_params.pref_address, or as low as - * possible. - */ - start = hdr->pref_address; - nr_pages = round_up(hdr->init_size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE; + nr_desc = 0; + e820ext = NULL; + e820ext_size = 0; - status = efi_call_phys4(sys_table->boottime->allocate_pages, - EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA, - nr_pages, &start); - if (status != EFI_SUCCESS) { - status = low_alloc(hdr->init_size, hdr->kernel_alignment, - &start); +get_map: + status = efi_get_memory_map(sys_table, &mem_map, &map_sz, &desc_size, + &desc_version, &key); + + if (status != EFI_SUCCESS) + return status; + + prev_nr_desc = nr_desc; + nr_desc = map_sz / desc_size; + if (nr_desc > prev_nr_desc && + nr_desc > ARRAY_SIZE(boot_params->e820_map)) { + u32 nr_e820ext = nr_desc - ARRAY_SIZE(boot_params->e820_map); + + status = alloc_e820ext(nr_e820ext, &e820ext, &e820ext_size); if (status != EFI_SUCCESS) - efi_printk("Failed to alloc mem for kernel\n"); + goto free_mem_map; + + efi_call_phys1(sys_table->boottime->free_pool, mem_map); + goto get_map; /* Allocated memory, get map again */ } - if (status == EFI_SUCCESS) - memcpy((void *)start, (void *)(unsigned long)hdr->code32_start, - hdr->init_size); + memcpy(&efi->efi_loader_signature, EFI_LOADER_SIGNATURE, sizeof(__u32)); + efi->efi_systab = (unsigned long)sys_table; + efi->efi_memdesc_size = desc_size; + efi->efi_memdesc_version = desc_version; + efi->efi_memmap = (unsigned long)mem_map; + efi->efi_memmap_size = map_sz; + +#ifdef CONFIG_X86_64 + efi->efi_systab_hi = (unsigned long)sys_table >> 32; + efi->efi_memmap_hi = (unsigned long)mem_map >> 32; +#endif - hdr->pref_address = hdr->code32_start; - hdr->code32_start = (__u32)start; + /* Might as well exit boot services now */ + status = efi_call_phys2(sys_table->boottime->exit_boot_services, + handle, key); + if (status != EFI_SUCCESS) { + /* + * ExitBootServices() will fail if any of the event + * handlers change the memory map. In which case, we + * must be prepared to retry, but only once so that + * we're guaranteed to exit on repeated failures instead + * of spinning forever. + */ + if (called_exit) + goto free_mem_map; + called_exit = true; + efi_call_phys1(sys_table->boottime->free_pool, mem_map); + goto get_map; + } + + /* Historic? */ + boot_params->alt_mem_k = 32 * 1024; + + status = setup_e820(boot_params, e820ext, e820ext_size); + if (status != EFI_SUCCESS) + return status; + + return EFI_SUCCESS; + +free_mem_map: + efi_call_phys1(sys_table->boottime->free_pool, mem_map); return status; } + /* * On success we return a pointer to a boot_params structure, and NULL * on failure. @@ -1157,7 +748,7 @@ static efi_status_t relocate_kernel(struct setup_header *hdr) struct boot_params *efi_main(void *handle, efi_system_table_t *_table, struct boot_params *boot_params) { - struct desc_ptr *gdt, *idt; + struct desc_ptr *gdt; efi_loaded_image_t *image; struct setup_header *hdr = &boot_params->hdr; efi_status_t status; @@ -1177,37 +768,33 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table, EFI_LOADER_DATA, sizeof(*gdt), (void **)&gdt); if (status != EFI_SUCCESS) { - efi_printk("Failed to alloc mem for gdt structure\n"); + efi_printk(sys_table, "Failed to alloc mem for gdt structure\n"); goto fail; } gdt->size = 0x800; - status = low_alloc(gdt->size, 8, (unsigned long *)&gdt->address); - if (status != EFI_SUCCESS) { - efi_printk("Failed to alloc mem for gdt\n"); - goto fail; - } - - status = efi_call_phys3(sys_table->boottime->allocate_pool, - EFI_LOADER_DATA, sizeof(*idt), - (void **)&idt); + status = efi_low_alloc(sys_table, gdt->size, 8, + (unsigned long *)&gdt->address); if (status != EFI_SUCCESS) { - efi_printk("Failed to alloc mem for idt structure\n"); + efi_printk(sys_table, "Failed to alloc mem for gdt\n"); goto fail; } - idt->size = 0; - idt->address = 0; - /* * If the kernel isn't already loaded at the preferred load * address, relocate it. */ if (hdr->pref_address != hdr->code32_start) { - status = relocate_kernel(hdr); - + unsigned long bzimage_addr = hdr->code32_start; + status = efi_relocate_kernel(sys_table, &bzimage_addr, + hdr->init_size, hdr->init_size, + hdr->pref_address, + hdr->kernel_alignment); if (status != EFI_SUCCESS) goto fail; + + hdr->pref_address = hdr->code32_start; + hdr->code32_start = bzimage_addr; } status = exit_boot(boot_params, handle); @@ -1267,10 +854,8 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table, desc->base2 = 0x00; #endif /* CONFIG_X86_64 */ - asm volatile ("lidt %0" : : "m" (*idt)); - asm volatile ("lgdt %0" : : "m" (*gdt)); - asm volatile("cli"); + asm volatile ("lgdt %0" : : "m" (*gdt)); return boot_params; fail: diff --git a/arch/x86/boot/compressed/eboot.h b/arch/x86/boot/compressed/eboot.h index e5b0a8f91c5f..81b6b652b46a 100644 --- a/arch/x86/boot/compressed/eboot.h +++ b/arch/x86/boot/compressed/eboot.h @@ -11,9 +11,6 @@ #define DESC_TYPE_CODE_DATA (1 << 0) -#define EFI_PAGE_SIZE (1UL << EFI_PAGE_SHIFT) -#define EFI_READ_CHUNK_SIZE (1024 * 1024) - #define EFI_CONSOLE_OUT_DEVICE_GUID \ EFI_GUID(0xd3b36f2c, 0xd551, 0x11d4, 0x9a, 0x46, 0x0, 0x90, 0x27, \ 0x3f, 0xc1, 0x4d) @@ -62,10 +59,4 @@ struct efi_uga_draw_protocol { void *blt; }; -struct efi_simple_text_output_protocol { - void *reset; - void *output_string; - void *test_string; -}; - #endif /* BOOT_COMPRESSED_EBOOT_H */ diff --git a/arch/x86/boot/compressed/mkpiggy.c b/arch/x86/boot/compressed/mkpiggy.c index 958a641483dd..b669ab65bf6c 100644 --- a/arch/x86/boot/compressed/mkpiggy.c +++ b/arch/x86/boot/compressed/mkpiggy.c @@ -36,11 +36,12 @@ int main(int argc, char *argv[]) uint32_t olen; long ilen; unsigned long offs; - FILE *f; + FILE *f = NULL; + int retval = 1; if (argc < 2) { fprintf(stderr, "Usage: %s compressed_file\n", argv[0]); - return 1; + goto bail; } /* Get the information for the compressed kernel image first */ @@ -48,7 +49,7 @@ int main(int argc, char *argv[]) f = fopen(argv[1], "r"); if (!f) { perror(argv[1]); - return 1; + goto bail; } @@ -58,12 +59,11 @@ int main(int argc, char *argv[]) if (fread(&olen, sizeof(olen), 1, f) != 1) { perror(argv[1]); - return 1; + goto bail; } ilen = ftell(f); olen = get_unaligned_le32(&olen); - fclose(f); /* * Now we have the input (compressed) and output (uncompressed) @@ -91,5 +91,9 @@ int main(int argc, char *argv[]) printf(".incbin \"%s\"\n", argv[1]); printf("input_data_end:\n"); - return 0; + retval = 0; +bail: + if (f) + fclose(f); + return retval; } diff --git a/arch/x86/boot/tools/build.c b/arch/x86/boot/tools/build.c index c941d6a8887f..8e15b22391fc 100644 --- a/arch/x86/boot/tools/build.c +++ b/arch/x86/boot/tools/build.c @@ -5,14 +5,15 @@ */ /* - * This file builds a disk-image from two different files: + * This file builds a disk-image from three different files: * * - setup: 8086 machine code, sets up system parm * - system: 80386 code for actual system + * - zoffset.h: header with ZO_* defines * - * It does some checking that all files are of the correct type, and - * just writes the result to stdout, removing headers and padding to - * the right amount. It also writes some system data to stderr. + * It does some checking that all files are of the correct type, and writes + * the result to the specified destination, removing headers and padding to + * the right amount. It also writes some system data to stdout. */ /* @@ -136,7 +137,7 @@ static void die(const char * str, ...) static void usage(void) { - die("Usage: build setup system [zoffset.h] [> image]"); + die("Usage: build setup system zoffset.h image"); } #ifdef CONFIG_EFI_STUB @@ -265,7 +266,7 @@ int main(int argc, char ** argv) int c; u32 sys_size; struct stat sb; - FILE *file; + FILE *file, *dest; int fd; void *kernel; u32 crc = 0xffffffffUL; @@ -280,10 +281,13 @@ int main(int argc, char ** argv) startup_64 = 0x200; #endif - if (argc == 4) - parse_zoffset(argv[3]); - else if (argc != 3) + if (argc != 5) usage(); + parse_zoffset(argv[3]); + + dest = fopen(argv[4], "w"); + if (!dest) + die("Unable to write `%s': %m", argv[4]); /* Copy the setup code */ file = fopen(argv[1], "r"); @@ -318,7 +322,7 @@ int main(int argc, char ** argv) /* Set the default root device */ put_unaligned_le16(DEFAULT_ROOT_DEV, &buf[508]); - fprintf(stderr, "Setup is %d bytes (padded to %d bytes).\n", c, i); + printf("Setup is %d bytes (padded to %d bytes).\n", c, i); /* Open and stat the kernel file */ fd = open(argv[2], O_RDONLY); @@ -327,7 +331,7 @@ int main(int argc, char ** argv) if (fstat(fd, &sb)) die("Unable to stat `%s': %m", argv[2]); sz = sb.st_size; - fprintf (stderr, "System is %d kB\n", (sz+1023)/1024); + printf("System is %d kB\n", (sz+1023)/1024); kernel = mmap(NULL, sz, PROT_READ, MAP_SHARED, fd, 0); if (kernel == MAP_FAILED) die("Unable to mmap '%s': %m", argv[2]); @@ -348,27 +352,31 @@ int main(int argc, char ** argv) #endif crc = partial_crc32(buf, i, crc); - if (fwrite(buf, 1, i, stdout) != i) + if (fwrite(buf, 1, i, dest) != i) die("Writing setup failed"); /* Copy the kernel code */ crc = partial_crc32(kernel, sz, crc); - if (fwrite(kernel, 1, sz, stdout) != sz) + if (fwrite(kernel, 1, sz, dest) != sz) die("Writing kernel failed"); /* Add padding leaving 4 bytes for the checksum */ while (sz++ < (sys_size*16) - 4) { crc = partial_crc32_one('\0', crc); - if (fwrite("\0", 1, 1, stdout) != 1) + if (fwrite("\0", 1, 1, dest) != 1) die("Writing padding failed"); } /* Write the CRC */ - fprintf(stderr, "CRC %x\n", crc); + printf("CRC %x\n", crc); put_unaligned_le32(crc, buf); - if (fwrite(buf, 1, 4, stdout) != 4) + if (fwrite(buf, 1, 4, dest) != 4) die("Writing CRC failed"); + /* Catch any delayed write failures */ + if (fclose(dest)) + die("Writing image failed"); + close(fd); /* Everything is OK */ diff --git a/arch/x86/configs/i386_defconfig b/arch/x86/configs/i386_defconfig index 94447086e551..a7fef2621cc9 100644 --- a/arch/x86/configs/i386_defconfig +++ b/arch/x86/configs/i386_defconfig @@ -142,6 +142,8 @@ CONFIG_MAC80211=y CONFIG_MAC80211_LEDS=y CONFIG_RFKILL=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y CONFIG_DEBUG_DEVRES=y CONFIG_CONNECTOR=y CONFIG_BLK_DEV_LOOP=y diff --git a/arch/x86/configs/x86_64_defconfig b/arch/x86/configs/x86_64_defconfig index 671524d0f6c0..c1119d4c1281 100644 --- a/arch/x86/configs/x86_64_defconfig +++ b/arch/x86/configs/x86_64_defconfig @@ -141,6 +141,8 @@ CONFIG_MAC80211=y CONFIG_MAC80211_LEDS=y CONFIG_RFKILL=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y CONFIG_DEBUG_DEVRES=y CONFIG_CONNECTOR=y CONFIG_BLK_DEV_LOOP=y diff --git a/arch/x86/ia32/ia32_aout.c b/arch/x86/ia32/ia32_aout.c index bae3aba95b15..d21ff89207cd 100644 --- a/arch/x86/ia32/ia32_aout.c +++ b/arch/x86/ia32/ia32_aout.c @@ -25,6 +25,7 @@ #include <linux/personality.h> #include <linux/init.h> #include <linux/jiffies.h> +#include <linux/perf_event.h> #include <asm/uaccess.h> #include <asm/pgalloc.h> @@ -33,14 +34,18 @@ #include <asm/ia32.h> #undef WARN_OLD -#undef CORE_DUMP /* definitely broken */ static int load_aout_binary(struct linux_binprm *); static int load_aout_library(struct file *); -#ifdef CORE_DUMP -static int aout_core_dump(long signr, struct pt_regs *regs, struct file *file, - unsigned long limit); +#ifdef CONFIG_COREDUMP +static int aout_core_dump(struct coredump_params *); + +static unsigned long get_dr(int n) +{ + struct perf_event *bp = current->thread.ptrace_bps[n]; + return bp ? bp->hw.info.address : 0; +} /* * fill in the user structure for a core dump.. @@ -48,6 +53,7 @@ static int aout_core_dump(long signr, struct pt_regs *regs, struct file *file, static void dump_thread32(struct pt_regs *regs, struct user32 *dump) { u32 fs, gs; + memset(dump, 0, sizeof(*dump)); /* changed the size calculations - should hopefully work better. lbt */ dump->magic = CMAGIC; @@ -57,15 +63,12 @@ static void dump_thread32(struct pt_regs *regs, struct user32 *dump) dump->u_dsize = ((unsigned long) (current->mm->brk + (PAGE_SIZE-1))) >> PAGE_SHIFT; dump->u_dsize -= dump->u_tsize; - dump->u_ssize = 0; - dump->u_debugreg[0] = current->thread.debugreg0; - dump->u_debugreg[1] = current->thread.debugreg1; - dump->u_debugreg[2] = current->thread.debugreg2; - dump->u_debugreg[3] = current->thread.debugreg3; - dump->u_debugreg[4] = 0; - dump->u_debugreg[5] = 0; + dump->u_debugreg[0] = get_dr(0); + dump->u_debugreg[1] = get_dr(1); + dump->u_debugreg[2] = get_dr(2); + dump->u_debugreg[3] = get_dr(3); dump->u_debugreg[6] = current->thread.debugreg6; - dump->u_debugreg[7] = current->thread.debugreg7; + dump->u_debugreg[7] = current->thread.ptrace_dr7; if (dump->start_stack < 0xc0000000) { unsigned long tmp; @@ -74,24 +77,24 @@ static void dump_thread32(struct pt_regs *regs, struct user32 *dump) dump->u_ssize = tmp >> PAGE_SHIFT; } - dump->regs.bx = regs->bx; - dump->regs.cx = regs->cx; - dump->regs.dx = regs->dx; - dump->regs.si = regs->si; - dump->regs.di = regs->di; - dump->regs.bp = regs->bp; - dump->regs.ax = regs->ax; + dump->regs.ebx = regs->bx; + dump->regs.ecx = regs->cx; + dump->regs.edx = regs->dx; + dump->regs.esi = regs->si; + dump->regs.edi = regs->di; + dump->regs.ebp = regs->bp; + dump->regs.eax = regs->ax; dump->regs.ds = current->thread.ds; dump->regs.es = current->thread.es; savesegment(fs, fs); dump->regs.fs = fs; savesegment(gs, gs); dump->regs.gs = gs; - dump->regs.orig_ax = regs->orig_ax; - dump->regs.ip = regs->ip; + dump->regs.orig_eax = regs->orig_ax; + dump->regs.eip = regs->ip; dump->regs.cs = regs->cs; - dump->regs.flags = regs->flags; - dump->regs.sp = regs->sp; + dump->regs.eflags = regs->flags; + dump->regs.esp = regs->sp; dump->regs.ss = regs->ss; #if 1 /* FIXME */ @@ -107,7 +110,7 @@ static struct linux_binfmt aout_format = { .module = THIS_MODULE, .load_binary = load_aout_binary, .load_shlib = load_aout_library, -#ifdef CORE_DUMP +#ifdef CONFIG_COREDUMP .core_dump = aout_core_dump, #endif .min_coredump = PAGE_SIZE @@ -122,7 +125,7 @@ static void set_brk(unsigned long start, unsigned long end) vm_brk(start, end - start); } -#ifdef CORE_DUMP +#ifdef CONFIG_COREDUMP /* * These are the only things you should do on a core-file: use only these * macros to write out all the necessary info. @@ -130,15 +133,7 @@ static void set_brk(unsigned long start, unsigned long end) #include <linux/coredump.h> -#define DUMP_WRITE(addr, nr) \ - if (!dump_write(file, (void *)(addr), (nr))) \ - goto end_coredump; - -#define DUMP_SEEK(offset) \ - if (!dump_seek(file, offset)) \ - goto end_coredump; - -#define START_DATA() (u.u_tsize << PAGE_SHIFT) +#define START_DATA(u) (u.u_tsize << PAGE_SHIFT) #define START_STACK(u) (u.start_stack) /* @@ -151,8 +146,7 @@ static void set_brk(unsigned long start, unsigned long end) * dumping of the process results in another error.. */ -static int aout_core_dump(long signr, struct pt_regs *regs, struct file *file, - unsigned long limit) +static int aout_core_dump(struct coredump_params *cprm) { mm_segment_t fs; int has_dumped = 0; @@ -164,19 +158,19 @@ static int aout_core_dump(long signr, struct pt_regs *regs, struct file *file, has_dumped = 1; strncpy(dump.u_comm, current->comm, sizeof(current->comm)); dump.u_ar0 = offsetof(struct user32, regs); - dump.signal = signr; - dump_thread32(regs, &dump); + dump.signal = cprm->siginfo->si_signo; + dump_thread32(cprm->regs, &dump); /* * If the size of the dump file exceeds the rlimit, then see * what would happen if we wrote the stack, but not the data * area. */ - if ((dump.u_dsize + dump.u_ssize + 1) * PAGE_SIZE > limit) + if ((dump.u_dsize + dump.u_ssize + 1) * PAGE_SIZE > cprm->limit) dump.u_dsize = 0; /* Make sure we have enough room to write the stack and data areas. */ - if ((dump.u_ssize + 1) * PAGE_SIZE > limit) + if ((dump.u_ssize + 1) * PAGE_SIZE > cprm->limit) dump.u_ssize = 0; /* make sure we actually have a data and stack area to dump */ @@ -190,22 +184,26 @@ static int aout_core_dump(long signr, struct pt_regs *regs, struct file *file, set_fs(KERNEL_DS); /* struct user */ - DUMP_WRITE(&dump, sizeof(dump)); + if (!dump_emit(cprm, &dump, sizeof(dump))) + goto end_coredump; /* Now dump all of the user data. Include malloced stuff as well */ - DUMP_SEEK(PAGE_SIZE - sizeof(dump)); + if (!dump_skip(cprm, PAGE_SIZE - sizeof(dump))) + goto end_coredump; /* now we start writing out the user space info */ set_fs(USER_DS); /* Dump the data area */ if (dump.u_dsize != 0) { dump_start = START_DATA(dump); dump_size = dump.u_dsize << PAGE_SHIFT; - DUMP_WRITE(dump_start, dump_size); + if (!dump_emit(cprm, (void *)dump_start, dump_size)) + goto end_coredump; } /* Now prepare to dump the stack area */ if (dump.u_ssize != 0) { dump_start = START_STACK(dump); dump_size = dump.u_ssize << PAGE_SHIFT; - DUMP_WRITE(dump_start, dump_size); + if (!dump_emit(cprm, (void *)dump_start, dump_size)) + goto end_coredump; } end_coredump: set_fs(fs); diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c index 665a730307f2..220675795e08 100644 --- a/arch/x86/ia32/ia32_signal.c +++ b/arch/x86/ia32/ia32_signal.c @@ -34,7 +34,7 @@ #include <asm/sys_ia32.h> #include <asm/smap.h> -int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from) +int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from) { int err = 0; bool ia32 = test_thread_flag(TIF_IA32); diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h index b1977bad5435..c8c1e700c26e 100644 --- a/arch/x86/include/asm/acpi.h +++ b/arch/x86/include/asm/acpi.h @@ -26,6 +26,7 @@ #include <acpi/pdc_intel.h> #include <asm/numa.h> +#include <asm/fixmap.h> #include <asm/processor.h> #include <asm/mmu.h> #include <asm/mpspec.h> diff --git a/arch/x86/include/asm/atomic.h b/arch/x86/include/asm/atomic.h index 722aa3b04624..da31c8b8a92d 100644 --- a/arch/x86/include/asm/atomic.h +++ b/arch/x86/include/asm/atomic.h @@ -6,6 +6,7 @@ #include <asm/processor.h> #include <asm/alternative.h> #include <asm/cmpxchg.h> +#include <asm/rmwcc.h> /* * Atomic operations that C can't guarantee us. Useful for @@ -76,12 +77,7 @@ static inline void atomic_sub(int i, atomic_t *v) */ static inline int atomic_sub_and_test(int i, atomic_t *v) { - unsigned char c; - - asm volatile(LOCK_PREFIX "subl %2,%0; sete %1" - : "+m" (v->counter), "=qm" (c) - : "ir" (i) : "memory"); - return c; + GEN_BINARY_RMWcc(LOCK_PREFIX "subl", v->counter, i, "%0", "e"); } /** @@ -118,12 +114,7 @@ static inline void atomic_dec(atomic_t *v) */ static inline int atomic_dec_and_test(atomic_t *v) { - unsigned char c; - - asm volatile(LOCK_PREFIX "decl %0; sete %1" - : "+m" (v->counter), "=qm" (c) - : : "memory"); - return c != 0; + GEN_UNARY_RMWcc(LOCK_PREFIX "decl", v->counter, "%0", "e"); } /** @@ -136,12 +127,7 @@ static inline int atomic_dec_and_test(atomic_t *v) */ static inline int atomic_inc_and_test(atomic_t *v) { - unsigned char c; - - asm volatile(LOCK_PREFIX "incl %0; sete %1" - : "+m" (v->counter), "=qm" (c) - : : "memory"); - return c != 0; + GEN_UNARY_RMWcc(LOCK_PREFIX "incl", v->counter, "%0", "e"); } /** @@ -155,12 +141,7 @@ static inline int atomic_inc_and_test(atomic_t *v) */ static inline int atomic_add_negative(int i, atomic_t *v) { - unsigned char c; - - asm volatile(LOCK_PREFIX "addl %2,%0; sets %1" - : "+m" (v->counter), "=qm" (c) - : "ir" (i) : "memory"); - return c; + GEN_BINARY_RMWcc(LOCK_PREFIX "addl", v->counter, i, "%0", "s"); } /** diff --git a/arch/x86/include/asm/atomic64_64.h b/arch/x86/include/asm/atomic64_64.h index 0e1cbfc8ee06..3f065c985aee 100644 --- a/arch/x86/include/asm/atomic64_64.h +++ b/arch/x86/include/asm/atomic64_64.h @@ -72,12 +72,7 @@ static inline void atomic64_sub(long i, atomic64_t *v) */ static inline int atomic64_sub_and_test(long i, atomic64_t *v) { - unsigned char c; - - asm volatile(LOCK_PREFIX "subq %2,%0; sete %1" - : "=m" (v->counter), "=qm" (c) - : "er" (i), "m" (v->counter) : "memory"); - return c; + GEN_BINARY_RMWcc(LOCK_PREFIX "subq", v->counter, i, "%0", "e"); } /** @@ -116,12 +111,7 @@ static inline void atomic64_dec(atomic64_t *v) */ static inline int atomic64_dec_and_test(atomic64_t *v) { - unsigned char c; - - asm volatile(LOCK_PREFIX "decq %0; sete %1" - : "=m" (v->counter), "=qm" (c) - : "m" (v->counter) : "memory"); - return c != 0; + GEN_UNARY_RMWcc(LOCK_PREFIX "decq", v->counter, "%0", "e"); } /** @@ -134,12 +124,7 @@ static inline int atomic64_dec_and_test(atomic64_t *v) */ static inline int atomic64_inc_and_test(atomic64_t *v) { - unsigned char c; - - asm volatile(LOCK_PREFIX "incq %0; sete %1" - : "=m" (v->counter), "=qm" (c) - : "m" (v->counter) : "memory"); - return c != 0; + GEN_UNARY_RMWcc(LOCK_PREFIX "incq", v->counter, "%0", "e"); } /** @@ -153,12 +138,7 @@ static inline int atomic64_inc_and_test(atomic64_t *v) */ static inline int atomic64_add_negative(long i, atomic64_t *v) { - unsigned char c; - - asm volatile(LOCK_PREFIX "addq %2,%0; sets %1" - : "=m" (v->counter), "=qm" (c) - : "er" (i), "m" (v->counter) : "memory"); - return c; + GEN_BINARY_RMWcc(LOCK_PREFIX "addq", v->counter, i, "%0", "s"); } /** diff --git a/arch/x86/include/asm/bitops.h b/arch/x86/include/asm/bitops.h index 41639ce8fd63..6d76d0935989 100644 --- a/arch/x86/include/asm/bitops.h +++ b/arch/x86/include/asm/bitops.h @@ -14,6 +14,7 @@ #include <linux/compiler.h> #include <asm/alternative.h> +#include <asm/rmwcc.h> #if BITS_PER_LONG == 32 # define _BITOPS_LONG_SHIFT 5 @@ -204,12 +205,7 @@ static inline void change_bit(long nr, volatile unsigned long *addr) */ static inline int test_and_set_bit(long nr, volatile unsigned long *addr) { - int oldbit; - - asm volatile(LOCK_PREFIX "bts %2,%1\n\t" - "sbb %0,%0" : "=r" (oldbit), ADDR : "Ir" (nr) : "memory"); - - return oldbit; + GEN_BINARY_RMWcc(LOCK_PREFIX "bts", *addr, nr, "%0", "c"); } /** @@ -255,13 +251,7 @@ static inline int __test_and_set_bit(long nr, volatile unsigned long *addr) */ static inline int test_and_clear_bit(long nr, volatile unsigned long *addr) { - int oldbit; - - asm volatile(LOCK_PREFIX "btr %2,%1\n\t" - "sbb %0,%0" - : "=r" (oldbit), ADDR : "Ir" (nr) : "memory"); - - return oldbit; + GEN_BINARY_RMWcc(LOCK_PREFIX "btr", *addr, nr, "%0", "c"); } /** @@ -314,13 +304,7 @@ static inline int __test_and_change_bit(long nr, volatile unsigned long *addr) */ static inline int test_and_change_bit(long nr, volatile unsigned long *addr) { - int oldbit; - - asm volatile(LOCK_PREFIX "btc %2,%1\n\t" - "sbb %0,%0" - : "=r" (oldbit), ADDR : "Ir" (nr) : "memory"); - - return oldbit; + GEN_BINARY_RMWcc(LOCK_PREFIX "btc", *addr, nr, "%0", "c"); } static __always_inline int constant_test_bit(long nr, const volatile unsigned long *addr) diff --git a/arch/x86/include/asm/calling.h b/arch/x86/include/asm/calling.h index 0fa675033912..cb4c73bfeb48 100644 --- a/arch/x86/include/asm/calling.h +++ b/arch/x86/include/asm/calling.h @@ -48,6 +48,8 @@ For 32-bit we have the following conventions - kernel is built with #include <asm/dwarf2.h> +#ifdef CONFIG_X86_64 + /* * 64-bit system call stack frame layout defines and helpers, * for assembly code: @@ -192,3 +194,51 @@ For 32-bit we have the following conventions - kernel is built with .macro icebp .byte 0xf1 .endm + +#else /* CONFIG_X86_64 */ + +/* + * For 32bit only simplified versions of SAVE_ALL/RESTORE_ALL. These + * are different from the entry_32.S versions in not changing the segment + * registers. So only suitable for in kernel use, not when transitioning + * from or to user space. The resulting stack frame is not a standard + * pt_regs frame. The main use case is calling C code from assembler + * when all the registers need to be preserved. + */ + + .macro SAVE_ALL + pushl_cfi %eax + CFI_REL_OFFSET eax, 0 + pushl_cfi %ebp + CFI_REL_OFFSET ebp, 0 + pushl_cfi %edi + CFI_REL_OFFSET edi, 0 + pushl_cfi %esi + CFI_REL_OFFSET esi, 0 + pushl_cfi %edx + CFI_REL_OFFSET edx, 0 + pushl_cfi %ecx + CFI_REL_OFFSET ecx, 0 + pushl_cfi %ebx + CFI_REL_OFFSET ebx, 0 + .endm + + .macro RESTORE_ALL + popl_cfi %ebx + CFI_RESTORE ebx + popl_cfi %ecx + CFI_RESTORE ecx + popl_cfi %edx + CFI_RESTORE edx + popl_cfi %esi + CFI_RESTORE esi + popl_cfi %edi + CFI_RESTORE edi + popl_cfi %ebp + CFI_RESTORE ebp + popl_cfi %eax + CFI_RESTORE eax + .endm + +#endif /* CONFIG_X86_64 */ + diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h index b90e5dfeee46..50d033a8947d 100644 --- a/arch/x86/include/asm/desc.h +++ b/arch/x86/include/asm/desc.h @@ -327,10 +327,25 @@ static inline void write_trace_idt_entry(int entry, const gate_desc *gate) { write_idt_entry(trace_idt_table, entry, gate); } + +static inline void _trace_set_gate(int gate, unsigned type, void *addr, + unsigned dpl, unsigned ist, unsigned seg) +{ + gate_desc s; + + pack_gate(&s, type, (unsigned long)addr, dpl, ist, seg); + /* + * does not need to be atomic because it is only done once at + * setup time + */ + write_trace_idt_entry(gate, &s); +} #else static inline void write_trace_idt_entry(int entry, const gate_desc *gate) { } + +#define _trace_set_gate(gate, type, addr, dpl, ist, seg) #endif static inline void _set_gate(int gate, unsigned type, void *addr, @@ -353,11 +368,14 @@ static inline void _set_gate(int gate, unsigned type, void *addr, * Pentium F0 0F bugfix can have resulted in the mapped * IDT being write-protected. */ -static inline void set_intr_gate(unsigned int n, void *addr) -{ - BUG_ON((unsigned)n > 0xFF); - _set_gate(n, GATE_INTERRUPT, addr, 0, 0, __KERNEL_CS); -} +#define set_intr_gate(n, addr) \ + do { \ + BUG_ON((unsigned)n > 0xFF); \ + _set_gate(n, GATE_INTERRUPT, (void *)addr, 0, 0, \ + __KERNEL_CS); \ + _trace_set_gate(n, GATE_INTERRUPT, (void *)trace_##addr,\ + 0, 0, __KERNEL_CS); \ + } while (0) extern int first_system_vector; /* used_vectors is BITMAP for irq is not managed by percpu vector_irq */ @@ -374,37 +392,10 @@ static inline void alloc_system_vector(int vector) } } -#ifdef CONFIG_TRACING -static inline void trace_set_intr_gate(unsigned int gate, void *addr) -{ - gate_desc s; - - pack_gate(&s, GATE_INTERRUPT, (unsigned long)addr, 0, 0, __KERNEL_CS); - write_idt_entry(trace_idt_table, gate, &s); -} - -static inline void __trace_alloc_intr_gate(unsigned int n, void *addr) -{ - trace_set_intr_gate(n, addr); -} -#else -static inline void trace_set_intr_gate(unsigned int gate, void *addr) -{ -} - -#define __trace_alloc_intr_gate(n, addr) -#endif - -static inline void __alloc_intr_gate(unsigned int n, void *addr) -{ - set_intr_gate(n, addr); -} - #define alloc_intr_gate(n, addr) \ do { \ alloc_system_vector(n); \ - __alloc_intr_gate(n, addr); \ - __trace_alloc_intr_gate(n, trace_##addr); \ + set_intr_gate(n, addr); \ } while (0) /* diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index 0062a0125041..65c6e6e3a552 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h @@ -109,6 +109,8 @@ static inline bool efi_is_native(void) return IS_ENABLED(CONFIG_X86_64) == efi_enabled(EFI_64BIT); } +extern struct console early_efi_console; + #else /* * IF EFI is not configured, have the EFI calls return -ENOSYS. diff --git a/arch/x86/include/asm/fpu-internal.h b/arch/x86/include/asm/fpu-internal.h index 4d0bda7b11e3..c49a613c6452 100644 --- a/arch/x86/include/asm/fpu-internal.h +++ b/arch/x86/include/asm/fpu-internal.h @@ -365,7 +365,7 @@ static inline void drop_fpu(struct task_struct *tsk) * Forget coprocessor state.. */ preempt_disable(); - tsk->fpu_counter = 0; + tsk->thread.fpu_counter = 0; __drop_fpu(tsk); clear_used_math(); preempt_enable(); @@ -424,7 +424,7 @@ static inline fpu_switch_t switch_fpu_prepare(struct task_struct *old, struct ta * or if the past 5 consecutive context-switches used math. */ fpu.preload = tsk_used_math(new) && (use_eager_fpu() || - new->fpu_counter > 5); + new->thread.fpu_counter > 5); if (__thread_has_fpu(old)) { if (!__save_init_fpu(old)) cpu = ~0; @@ -433,16 +433,16 @@ static inline fpu_switch_t switch_fpu_prepare(struct task_struct *old, struct ta /* Don't change CR0.TS if we just switch! */ if (fpu.preload) { - new->fpu_counter++; + new->thread.fpu_counter++; __thread_set_has_fpu(new); prefetch(new->thread.fpu.state); } else if (!use_eager_fpu()) stts(); } else { - old->fpu_counter = 0; + old->thread.fpu_counter = 0; old->thread.fpu.last_cpu = ~0; if (fpu.preload) { - new->fpu_counter++; + new->thread.fpu_counter++; if (!use_eager_fpu() && fpu_lazy_restore(new, cpu)) fpu.preload = 0; else diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h index 92b3bae08b74..cba45d99ac1a 100644 --- a/arch/x86/include/asm/hw_irq.h +++ b/arch/x86/include/asm/hw_irq.h @@ -187,6 +187,9 @@ extern __visible void smp_invalidate_interrupt(struct pt_regs *); #endif extern void (*__initconst interrupt[NR_VECTORS-FIRST_EXTERNAL_VECTOR])(void); +#ifdef CONFIG_TRACING +#define trace_interrupt interrupt +#endif typedef int vector_irq_t[NR_VECTORS]; DECLARE_PER_CPU(vector_irq_t, vector_irq); diff --git a/arch/x86/include/asm/intel-mid.h b/arch/x86/include/asm/intel-mid.h new file mode 100644 index 000000000000..459769d39263 --- /dev/null +++ b/arch/x86/include/asm/intel-mid.h @@ -0,0 +1,113 @@ +/* + * intel-mid.h: Intel MID specific setup code + * + * (C) Copyright 2009 Intel Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + */ +#ifndef _ASM_X86_INTEL_MID_H +#define _ASM_X86_INTEL_MID_H + +#include <linux/sfi.h> +#include <linux/platform_device.h> + +extern int intel_mid_pci_init(void); +extern int get_gpio_by_name(const char *name); +extern void intel_scu_device_register(struct platform_device *pdev); +extern int __init sfi_parse_mrtc(struct sfi_table_header *table); +extern int __init sfi_parse_mtmr(struct sfi_table_header *table); +extern int sfi_mrtc_num; +extern struct sfi_rtc_table_entry sfi_mrtc_array[]; + +/* + * Here defines the array of devices platform data that IAFW would export + * through SFI "DEVS" table, we use name and type to match the device and + * its platform data. + */ +struct devs_id { + char name[SFI_NAME_LEN + 1]; + u8 type; + u8 delay; + void *(*get_platform_data)(void *info); + /* Custom handler for devices */ + void (*device_handler)(struct sfi_device_table_entry *pentry, + struct devs_id *dev); +}; + +#define sfi_device(i) \ + static const struct devs_id *const __intel_mid_sfi_##i##_dev __used \ + __attribute__((__section__(".x86_intel_mid_dev.init"))) = &i + +/* + * Medfield is the follow-up of Moorestown, it combines two chip solution into + * one. Other than that it also added always-on and constant tsc and lapic + * timers. Medfield is the platform name, and the chip name is called Penwell + * we treat Medfield/Penwell as a variant of Moorestown. Penwell can be + * identified via MSRs. + */ +enum intel_mid_cpu_type { + /* 1 was Moorestown */ + INTEL_MID_CPU_CHIP_PENWELL = 2, +}; + +extern enum intel_mid_cpu_type __intel_mid_cpu_chip; + +#ifdef CONFIG_X86_INTEL_MID + +static inline enum intel_mid_cpu_type intel_mid_identify_cpu(void) +{ + return __intel_mid_cpu_chip; +} + +static inline bool intel_mid_has_msic(void) +{ + return (intel_mid_identify_cpu() == INTEL_MID_CPU_CHIP_PENWELL); +} + +#else /* !CONFIG_X86_INTEL_MID */ + +#define intel_mid_identify_cpu() (0) +#define intel_mid_has_msic() (0) + +#endif /* !CONFIG_X86_INTEL_MID */ + +enum intel_mid_timer_options { + INTEL_MID_TIMER_DEFAULT, + INTEL_MID_TIMER_APBT_ONLY, + INTEL_MID_TIMER_LAPIC_APBT, +}; + +extern enum intel_mid_timer_options intel_mid_timer_options; + +/* + * Penwell uses spread spectrum clock, so the freq number is not exactly + * the same as reported by MSR based on SDM. + */ +#define PENWELL_FSB_FREQ_83SKU 83200 +#define PENWELL_FSB_FREQ_100SKU 99840 + +#define SFI_MTMR_MAX_NUM 8 +#define SFI_MRTC_MAX 8 + +extern struct console early_mrst_console; +extern void mrst_early_console_init(void); + +extern struct console early_hsu_console; +extern void hsu_early_console_init(const char *); + +extern void intel_scu_devices_create(void); +extern void intel_scu_devices_destroy(void); + +/* VRTC timer */ +#define MRST_VRTC_MAP_SZ (1024) +/*#define MRST_VRTC_PGOFFSET (0xc00) */ + +extern void intel_mid_rtc_init(void); + +/* the offset for the mapping of global gpio pin to irq */ +#define INTEL_MID_IRQ_OFFSET 0x100 + +#endif /* _ASM_X86_INTEL_MID_H */ diff --git a/arch/x86/include/asm/mrst-vrtc.h b/arch/x86/include/asm/intel_mid_vrtc.h index 1e69a75412a4..86ff4685c409 100644 --- a/arch/x86/include/asm/mrst-vrtc.h +++ b/arch/x86/include/asm/intel_mid_vrtc.h @@ -1,5 +1,5 @@ -#ifndef _MRST_VRTC_H -#define _MRST_VRTC_H +#ifndef _INTEL_MID_VRTC_H +#define _INTEL_MID_VRTC_H extern unsigned char vrtc_cmos_read(unsigned char reg); extern void vrtc_cmos_write(unsigned char val, unsigned char reg); diff --git a/arch/x86/include/asm/kdebug.h b/arch/x86/include/asm/kdebug.h index 2c37aadcbc35..32ce71375b21 100644 --- a/arch/x86/include/asm/kdebug.h +++ b/arch/x86/include/asm/kdebug.h @@ -21,7 +21,7 @@ enum die_val { DIE_NMIUNKNOWN, }; -extern void printk_address(unsigned long address, int reliable); +extern void printk_address(unsigned long address); extern void die(const char *, struct pt_regs *,long); extern int __must_check __die(const char *, struct pt_regs *, long); extern void show_trace(struct task_struct *t, struct pt_regs *regs, diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h index 15f960c06ff7..24ec1216596e 100644 --- a/arch/x86/include/asm/kvm_emulate.h +++ b/arch/x86/include/asm/kvm_emulate.h @@ -274,13 +274,17 @@ struct x86_emulate_ctxt { bool guest_mode; /* guest running a nested guest */ bool perm_ok; /* do not check permissions if true */ - bool only_vendor_specific_insn; + bool ud; /* inject an #UD if host doesn't support insn */ bool have_exception; struct x86_exception exception; - /* decode cache */ - u8 twobyte; + /* + * decode cache + */ + + /* current opcode length in bytes */ + u8 opcode_len; u8 b; u8 intercept; u8 lock_prefix; diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index c76ff74a98f2..ae5d7830855c 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -79,6 +79,13 @@ #define KVM_HPAGE_MASK(x) (~(KVM_HPAGE_SIZE(x) - 1)) #define KVM_PAGES_PER_HPAGE(x) (KVM_HPAGE_SIZE(x) / PAGE_SIZE) +static inline gfn_t gfn_to_index(gfn_t gfn, gfn_t base_gfn, int level) +{ + /* KVM_HPAGE_GFN_SHIFT(PT_PAGE_TABLE_LEVEL) must be 0. */ + return (gfn >> KVM_HPAGE_GFN_SHIFT(level)) - + (base_gfn >> KVM_HPAGE_GFN_SHIFT(level)); +} + #define SELECTOR_TI_MASK (1 << 2) #define SELECTOR_RPL_MASK 0x03 @@ -253,7 +260,6 @@ struct kvm_pio_request { * mode. */ struct kvm_mmu { - void (*new_cr3)(struct kvm_vcpu *vcpu); void (*set_cr3)(struct kvm_vcpu *vcpu, unsigned long root); unsigned long (*get_cr3)(struct kvm_vcpu *vcpu); u64 (*get_pdptr)(struct kvm_vcpu *vcpu, int index); @@ -261,7 +267,6 @@ struct kvm_mmu { bool prefault); void (*inject_page_fault)(struct kvm_vcpu *vcpu, struct x86_exception *fault); - void (*free)(struct kvm_vcpu *vcpu); gpa_t (*gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t gva, u32 access, struct x86_exception *exception); gpa_t (*translate_gpa)(struct kvm_vcpu *vcpu, gpa_t gpa, u32 access); @@ -389,6 +394,8 @@ struct kvm_vcpu_arch { struct fpu guest_fpu; u64 xcr0; + u64 guest_supported_xcr0; + u32 guest_xstate_size; struct kvm_pio_request pio; void *pio_data; @@ -557,7 +564,9 @@ struct kvm_arch { struct list_head assigned_dev_head; struct iommu_domain *iommu_domain; - int iommu_flags; + bool iommu_noncoherent; +#define __KVM_HAVE_ARCH_NONCOHERENT_DMA + atomic_t noncoherent_dma_count; struct kvm_pic *vpic; struct kvm_ioapic *vioapic; struct kvm_pit *vpit; @@ -780,11 +789,11 @@ void kvm_mmu_module_exit(void); void kvm_mmu_destroy(struct kvm_vcpu *vcpu); int kvm_mmu_create(struct kvm_vcpu *vcpu); -int kvm_mmu_setup(struct kvm_vcpu *vcpu); +void kvm_mmu_setup(struct kvm_vcpu *vcpu); void kvm_mmu_set_mask_ptes(u64 user_mask, u64 accessed_mask, u64 dirty_mask, u64 nx_mask, u64 x_mask); -int kvm_mmu_reset_context(struct kvm_vcpu *vcpu); +void kvm_mmu_reset_context(struct kvm_vcpu *vcpu); void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot); void kvm_mmu_write_protect_pt_masked(struct kvm *kvm, struct kvm_memory_slot *slot, @@ -922,13 +931,11 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu); int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva, u32 error_code, void *insn, int insn_len); void kvm_mmu_invlpg(struct kvm_vcpu *vcpu, gva_t gva); +void kvm_mmu_new_cr3(struct kvm_vcpu *vcpu); void kvm_enable_tdp(void); void kvm_disable_tdp(void); -int complete_pio(struct kvm_vcpu *vcpu); -bool kvm_check_iopl(struct kvm_vcpu *vcpu); - static inline gpa_t translate_gpa(struct kvm_vcpu *vcpu, gpa_t gpa, u32 access) { return gpa; diff --git a/arch/x86/include/asm/local.h b/arch/x86/include/asm/local.h index 2d89e3980cbd..5b23e605e707 100644 --- a/arch/x86/include/asm/local.h +++ b/arch/x86/include/asm/local.h @@ -52,12 +52,7 @@ static inline void local_sub(long i, local_t *l) */ static inline int local_sub_and_test(long i, local_t *l) { - unsigned char c; - - asm volatile(_ASM_SUB "%2,%0; sete %1" - : "+m" (l->a.counter), "=qm" (c) - : "ir" (i) : "memory"); - return c; + GEN_BINARY_RMWcc(_ASM_SUB, l->a.counter, i, "%0", "e"); } /** @@ -70,12 +65,7 @@ static inline int local_sub_and_test(long i, local_t *l) */ static inline int local_dec_and_test(local_t *l) { - unsigned char c; - - asm volatile(_ASM_DEC "%0; sete %1" - : "+m" (l->a.counter), "=qm" (c) - : : "memory"); - return c != 0; + GEN_UNARY_RMWcc(_ASM_DEC, l->a.counter, "%0", "e"); } /** @@ -88,12 +78,7 @@ static inline int local_dec_and_test(local_t *l) */ static inline int local_inc_and_test(local_t *l) { - unsigned char c; - - asm volatile(_ASM_INC "%0; sete %1" - : "+m" (l->a.counter), "=qm" (c) - : : "memory"); - return c != 0; + GEN_UNARY_RMWcc(_ASM_INC, l->a.counter, "%0", "e"); } /** @@ -107,12 +92,7 @@ static inline int local_inc_and_test(local_t *l) */ static inline int local_add_negative(long i, local_t *l) { - unsigned char c; - - asm volatile(_ASM_ADD "%2,%0; sets %1" - : "+m" (l->a.counter), "=qm" (c) - : "ir" (i) : "memory"); - return c; + GEN_BINARY_RMWcc(_ASM_ADD, l->a.counter, i, "%0", "s"); } /** diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h index cbe6b9e404ce..c696a8687567 100644 --- a/arch/x86/include/asm/mce.h +++ b/arch/x86/include/asm/mce.h @@ -16,6 +16,7 @@ #define MCG_EXT_CNT_SHIFT 16 #define MCG_EXT_CNT(c) (((c) & MCG_EXT_CNT_MASK) >> MCG_EXT_CNT_SHIFT) #define MCG_SER_P (1ULL<<24) /* MCA recovery/new status bits */ +#define MCG_ELOG_P (1ULL<<26) /* Extended error log supported */ /* MCG_STATUS register defines */ #define MCG_STATUS_RIPV (1ULL<<0) /* restart ip valid */ diff --git a/arch/x86/include/asm/misc.h b/arch/x86/include/asm/misc.h new file mode 100644 index 000000000000..475f5bbc7f53 --- /dev/null +++ b/arch/x86/include/asm/misc.h @@ -0,0 +1,6 @@ +#ifndef _ASM_X86_MISC_H +#define _ASM_X86_MISC_H + +int num_digits(int val); + +#endif /* _ASM_X86_MISC_H */ diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h index 626cf70082d7..3142a94c7b4b 100644 --- a/arch/x86/include/asm/mpspec.h +++ b/arch/x86/include/asm/mpspec.h @@ -94,7 +94,7 @@ static inline void early_reserve_e820_mpc_new(void) { } #define default_get_smp_config x86_init_uint_noop #endif -void generic_processor_info(int apicid, int version); +int generic_processor_info(int apicid, int version); #ifdef CONFIG_ACPI extern void mp_register_ioapic(int id, u32 address, u32 gsi_base); extern void mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, diff --git a/arch/x86/include/asm/mrst.h b/arch/x86/include/asm/mrst.h deleted file mode 100644 index fc18bf3ce7c8..000000000000 --- a/arch/x86/include/asm/mrst.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * mrst.h: Intel Moorestown platform specific setup code - * - * (C) Copyright 2009 Intel Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; version 2 - * of the License. - */ -#ifndef _ASM_X86_MRST_H -#define _ASM_X86_MRST_H - -#include <linux/sfi.h> - -extern int pci_mrst_init(void); -extern int __init sfi_parse_mrtc(struct sfi_table_header *table); -extern int sfi_mrtc_num; -extern struct sfi_rtc_table_entry sfi_mrtc_array[]; - -/* - * Medfield is the follow-up of Moorestown, it combines two chip solution into - * one. Other than that it also added always-on and constant tsc and lapic - * timers. Medfield is the platform name, and the chip name is called Penwell - * we treat Medfield/Penwell as a variant of Moorestown. Penwell can be - * identified via MSRs. - */ -enum mrst_cpu_type { - /* 1 was Moorestown */ - MRST_CPU_CHIP_PENWELL = 2, -}; - -extern enum mrst_cpu_type __mrst_cpu_chip; - -#ifdef CONFIG_X86_INTEL_MID - -static inline enum mrst_cpu_type mrst_identify_cpu(void) -{ - return __mrst_cpu_chip; -} - -#else /* !CONFIG_X86_INTEL_MID */ - -#define mrst_identify_cpu() (0) - -#endif /* !CONFIG_X86_INTEL_MID */ - -enum mrst_timer_options { - MRST_TIMER_DEFAULT, - MRST_TIMER_APBT_ONLY, - MRST_TIMER_LAPIC_APBT, -}; - -extern enum mrst_timer_options mrst_timer_options; - -/* - * Penwell uses spread spectrum clock, so the freq number is not exactly - * the same as reported by MSR based on SDM. - */ -#define PENWELL_FSB_FREQ_83SKU 83200 -#define PENWELL_FSB_FREQ_100SKU 99840 - -#define SFI_MTMR_MAX_NUM 8 -#define SFI_MRTC_MAX 8 - -extern struct console early_mrst_console; -extern void mrst_early_console_init(void); - -extern struct console early_hsu_console; -extern void hsu_early_console_init(const char *); - -extern void intel_scu_devices_create(void); -extern void intel_scu_devices_destroy(void); - -/* VRTC timer */ -#define MRST_VRTC_MAP_SZ (1024) -/*#define MRST_VRTC_PGOFFSET (0xc00) */ - -extern void mrst_rtc_init(void); - -#endif /* _ASM_X86_MRST_H */ diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h index cb7502852acb..e139b13f2a33 100644 --- a/arch/x86/include/asm/msr.h +++ b/arch/x86/include/asm/msr.h @@ -218,10 +218,14 @@ void msrs_free(struct msr *msrs); #ifdef CONFIG_SMP int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h); int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h); +int rdmsrl_on_cpu(unsigned int cpu, u32 msr_no, u64 *q); +int wrmsrl_on_cpu(unsigned int cpu, u32 msr_no, u64 q); void rdmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs); void wrmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs); int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h); int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h); +int rdmsrl_safe_on_cpu(unsigned int cpu, u32 msr_no, u64 *q); +int wrmsrl_safe_on_cpu(unsigned int cpu, u32 msr_no, u64 q); int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]); int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]); #else /* CONFIG_SMP */ @@ -235,6 +239,16 @@ static inline int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) wrmsr(msr_no, l, h); return 0; } +static inline int rdmsrl_on_cpu(unsigned int cpu, u32 msr_no, u64 *q) +{ + rdmsrl(msr_no, *q); + return 0; +} +static inline int wrmsrl_on_cpu(unsigned int cpu, u32 msr_no, u64 q) +{ + wrmsrl(msr_no, q); + return 0; +} static inline void rdmsr_on_cpus(const struct cpumask *m, u32 msr_no, struct msr *msrs) { @@ -254,6 +268,14 @@ static inline int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) { return wrmsr_safe(msr_no, l, h); } +static inline int rdmsrl_safe_on_cpu(unsigned int cpu, u32 msr_no, u64 *q) +{ + return rdmsrl_safe(msr_no, q); +} +static inline int wrmsrl_safe_on_cpu(unsigned int cpu, u32 msr_no, u64 q) +{ + return wrmsrl_safe(msr_no, q); +} static inline int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]) { return rdmsr_safe_regs(regs); diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h index 0da5200ee79d..94220d14d5cc 100644 --- a/arch/x86/include/asm/percpu.h +++ b/arch/x86/include/asm/percpu.h @@ -128,7 +128,8 @@ do { \ do { \ typedef typeof(var) pao_T__; \ const int pao_ID__ = (__builtin_constant_p(val) && \ - ((val) == 1 || (val) == -1)) ? (val) : 0; \ + ((val) == 1 || (val) == -1)) ? \ + (int)(val) : 0; \ if (0) { \ pao_T__ pao_tmp__; \ pao_tmp__ = (val); \ @@ -377,9 +378,6 @@ do { \ #define __this_cpu_or_1(pcp, val) percpu_to_op("or", (pcp), val) #define __this_cpu_or_2(pcp, val) percpu_to_op("or", (pcp), val) #define __this_cpu_or_4(pcp, val) percpu_to_op("or", (pcp), val) -#define __this_cpu_xor_1(pcp, val) percpu_to_op("xor", (pcp), val) -#define __this_cpu_xor_2(pcp, val) percpu_to_op("xor", (pcp), val) -#define __this_cpu_xor_4(pcp, val) percpu_to_op("xor", (pcp), val) #define __this_cpu_xchg_1(pcp, val) percpu_xchg_op(pcp, val) #define __this_cpu_xchg_2(pcp, val) percpu_xchg_op(pcp, val) #define __this_cpu_xchg_4(pcp, val) percpu_xchg_op(pcp, val) @@ -399,9 +397,6 @@ do { \ #define this_cpu_or_1(pcp, val) percpu_to_op("or", (pcp), val) #define this_cpu_or_2(pcp, val) percpu_to_op("or", (pcp), val) #define this_cpu_or_4(pcp, val) percpu_to_op("or", (pcp), val) -#define this_cpu_xor_1(pcp, val) percpu_to_op("xor", (pcp), val) -#define this_cpu_xor_2(pcp, val) percpu_to_op("xor", (pcp), val) -#define this_cpu_xor_4(pcp, val) percpu_to_op("xor", (pcp), val) #define this_cpu_xchg_1(pcp, nval) percpu_xchg_op(pcp, nval) #define this_cpu_xchg_2(pcp, nval) percpu_xchg_op(pcp, nval) #define this_cpu_xchg_4(pcp, nval) percpu_xchg_op(pcp, nval) @@ -446,7 +441,6 @@ do { \ #define __this_cpu_add_8(pcp, val) percpu_add_op((pcp), val) #define __this_cpu_and_8(pcp, val) percpu_to_op("and", (pcp), val) #define __this_cpu_or_8(pcp, val) percpu_to_op("or", (pcp), val) -#define __this_cpu_xor_8(pcp, val) percpu_to_op("xor", (pcp), val) #define __this_cpu_add_return_8(pcp, val) percpu_add_return_op(pcp, val) #define __this_cpu_xchg_8(pcp, nval) percpu_xchg_op(pcp, nval) #define __this_cpu_cmpxchg_8(pcp, oval, nval) percpu_cmpxchg_op(pcp, oval, nval) @@ -456,7 +450,6 @@ do { \ #define this_cpu_add_8(pcp, val) percpu_add_op((pcp), val) #define this_cpu_and_8(pcp, val) percpu_to_op("and", (pcp), val) #define this_cpu_or_8(pcp, val) percpu_to_op("or", (pcp), val) -#define this_cpu_xor_8(pcp, val) percpu_to_op("xor", (pcp), val) #define this_cpu_add_return_8(pcp, val) percpu_add_return_op(pcp, val) #define this_cpu_xchg_8(pcp, nval) percpu_xchg_op(pcp, nval) #define this_cpu_cmpxchg_8(pcp, oval, nval) percpu_cmpxchg_op(pcp, oval, nval) diff --git a/arch/x86/include/asm/pgalloc.h b/arch/x86/include/asm/pgalloc.h index b4389a468fb6..c4412e972bbd 100644 --- a/arch/x86/include/asm/pgalloc.h +++ b/arch/x86/include/asm/pgalloc.h @@ -80,12 +80,21 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, #if PAGETABLE_LEVELS > 2 static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr) { - return (pmd_t *)get_zeroed_page(GFP_KERNEL|__GFP_REPEAT); + struct page *page; + page = alloc_pages(GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO, 0); + if (!page) + return NULL; + if (!pgtable_pmd_page_ctor(page)) { + __free_pages(page, 0); + return NULL; + } + return (pmd_t *)page_address(page); } static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) { BUG_ON((unsigned long)pmd & (PAGE_SIZE-1)); + pgtable_pmd_page_dtor(virt_to_page(pmd)); free_page((unsigned long)pmd); } diff --git a/arch/x86/include/asm/preempt.h b/arch/x86/include/asm/preempt.h new file mode 100644 index 000000000000..8729723636fd --- /dev/null +++ b/arch/x86/include/asm/preempt.h @@ -0,0 +1,100 @@ +#ifndef __ASM_PREEMPT_H +#define __ASM_PREEMPT_H + +#include <asm/rmwcc.h> +#include <asm/percpu.h> +#include <linux/thread_info.h> + +DECLARE_PER_CPU(int, __preempt_count); + +/* + * We mask the PREEMPT_NEED_RESCHED bit so as not to confuse all current users + * that think a non-zero value indicates we cannot preempt. + */ +static __always_inline int preempt_count(void) +{ + return __this_cpu_read_4(__preempt_count) & ~PREEMPT_NEED_RESCHED; +} + +static __always_inline void preempt_count_set(int pc) +{ + __this_cpu_write_4(__preempt_count, pc); +} + +/* + * must be macros to avoid header recursion hell + */ +#define task_preempt_count(p) \ + (task_thread_info(p)->saved_preempt_count & ~PREEMPT_NEED_RESCHED) + +#define init_task_preempt_count(p) do { \ + task_thread_info(p)->saved_preempt_count = PREEMPT_DISABLED; \ +} while (0) + +#define init_idle_preempt_count(p, cpu) do { \ + task_thread_info(p)->saved_preempt_count = PREEMPT_ENABLED; \ + per_cpu(__preempt_count, (cpu)) = PREEMPT_ENABLED; \ +} while (0) + +/* + * We fold the NEED_RESCHED bit into the preempt count such that + * preempt_enable() can decrement and test for needing to reschedule with a + * single instruction. + * + * We invert the actual bit, so that when the decrement hits 0 we know we both + * need to resched (the bit is cleared) and can resched (no preempt count). + */ + +static __always_inline void set_preempt_need_resched(void) +{ + __this_cpu_and_4(__preempt_count, ~PREEMPT_NEED_RESCHED); +} + +static __always_inline void clear_preempt_need_resched(void) +{ + __this_cpu_or_4(__preempt_count, PREEMPT_NEED_RESCHED); +} + +static __always_inline bool test_preempt_need_resched(void) +{ + return !(__this_cpu_read_4(__preempt_count) & PREEMPT_NEED_RESCHED); +} + +/* + * The various preempt_count add/sub methods + */ + +static __always_inline void __preempt_count_add(int val) +{ + __this_cpu_add_4(__preempt_count, val); +} + +static __always_inline void __preempt_count_sub(int val) +{ + __this_cpu_add_4(__preempt_count, -val); +} + +static __always_inline bool __preempt_count_dec_and_test(void) +{ + GEN_UNARY_RMWcc("decl", __preempt_count, __percpu_arg(0), "e"); +} + +/* + * Returns true when we need to resched and can (barring IRQ state). + */ +static __always_inline bool should_resched(void) +{ + return unlikely(!__this_cpu_read_4(__preempt_count)); +} + +#ifdef CONFIG_PREEMPT + extern asmlinkage void ___preempt_schedule(void); +# define __preempt_schedule() asm ("call ___preempt_schedule") + extern asmlinkage void preempt_schedule(void); +# ifdef CONFIG_CONTEXT_TRACKING + extern asmlinkage void ___preempt_schedule_context(void); +# define __preempt_schedule_context() asm ("call ___preempt_schedule_context") +# endif +#endif + +#endif /* __ASM_PREEMPT_H */ diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 987c75ecc334..7b034a4057f9 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -488,6 +488,15 @@ struct thread_struct { unsigned long iopl; /* Max allowed port in the bitmap, in bytes: */ unsigned io_bitmap_max; + /* + * fpu_counter contains the number of consecutive context switches + * that the FPU is used. If this is over a threshold, the lazy fpu + * saving becomes unlazy to save the trap. This is an unsigned char + * so that after 256 times the counter wraps and the behavior turns + * lazy again; this to deal with bursty apps that only use FPU for + * a short time + */ + unsigned char fpu_counter; }; /* diff --git a/arch/x86/include/asm/prom.h b/arch/x86/include/asm/prom.h index bade6ac3b14f..fbeb06ed0eaa 100644 --- a/arch/x86/include/asm/prom.h +++ b/arch/x86/include/asm/prom.h @@ -39,10 +39,5 @@ static inline void x86_dtb_init(void) { } extern char cmd_line[COMMAND_LINE_SIZE]; -#define pci_address_to_pio pci_address_to_pio -unsigned long pci_address_to_pio(phys_addr_t addr); - -#define HAVE_ARCH_DEVTREE_FIXUPS - #endif /* __ASSEMBLY__ */ #endif diff --git a/arch/x86/include/asm/pvclock.h b/arch/x86/include/asm/pvclock.h index be8269b00e2a..d6b078e9fa28 100644 --- a/arch/x86/include/asm/pvclock.h +++ b/arch/x86/include/asm/pvclock.h @@ -14,6 +14,8 @@ void pvclock_read_wallclock(struct pvclock_wall_clock *wall, struct timespec *ts); void pvclock_resume(void); +void pvclock_touch_watchdogs(void); + /* * Scale a 64-bit delta by scaling and multiplying by a 32-bit fraction, * yielding a 64-bit result. diff --git a/arch/x86/include/asm/rmwcc.h b/arch/x86/include/asm/rmwcc.h new file mode 100644 index 000000000000..1ff990f1de8e --- /dev/null +++ b/arch/x86/include/asm/rmwcc.h @@ -0,0 +1,41 @@ +#ifndef _ASM_X86_RMWcc +#define _ASM_X86_RMWcc + +#ifdef CC_HAVE_ASM_GOTO + +#define __GEN_RMWcc(fullop, var, cc, ...) \ +do { \ + asm_volatile_goto (fullop "; j" cc " %l[cc_label]" \ + : : "m" (var), ## __VA_ARGS__ \ + : "memory" : cc_label); \ + return 0; \ +cc_label: \ + return 1; \ +} while (0) + +#define GEN_UNARY_RMWcc(op, var, arg0, cc) \ + __GEN_RMWcc(op " " arg0, var, cc) + +#define GEN_BINARY_RMWcc(op, var, val, arg0, cc) \ + __GEN_RMWcc(op " %1, " arg0, var, cc, "er" (val)) + +#else /* !CC_HAVE_ASM_GOTO */ + +#define __GEN_RMWcc(fullop, var, cc, ...) \ +do { \ + char c; \ + asm volatile (fullop "; set" cc " %1" \ + : "+m" (var), "=qm" (c) \ + : __VA_ARGS__ : "memory"); \ + return c != 0; \ +} while (0) + +#define GEN_UNARY_RMWcc(op, var, arg0, cc) \ + __GEN_RMWcc(op " " arg0, var, cc) + +#define GEN_BINARY_RMWcc(op, var, val, arg0, cc) \ + __GEN_RMWcc(op " %2, " arg0, var, cc, "er" (val)) + +#endif /* CC_HAVE_ASM_GOTO */ + +#endif /* _ASM_X86_RMWcc */ diff --git a/arch/x86/include/asm/segment.h b/arch/x86/include/asm/segment.h index c48a95035a77..6f1c3a8a33ab 100644 --- a/arch/x86/include/asm/segment.h +++ b/arch/x86/include/asm/segment.h @@ -214,6 +214,9 @@ #ifdef __KERNEL__ #ifndef __ASSEMBLY__ extern const char early_idt_handlers[NUM_EXCEPTION_VECTORS][2+2+5]; +#ifdef CONFIG_TRACING +#define trace_early_idt_handlers early_idt_handlers +#endif /* * Load a segment. Fall back on loading the zero diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h index 347555492dad..59bcf4e22418 100644 --- a/arch/x86/include/asm/setup.h +++ b/arch/x86/include/asm/setup.h @@ -51,9 +51,9 @@ extern void i386_reserve_resources(void); extern void setup_default_timer_irq(void); #ifdef CONFIG_X86_INTEL_MID -extern void x86_mrst_early_setup(void); +extern void x86_intel_mid_early_setup(void); #else -static inline void x86_mrst_early_setup(void) { } +static inline void x86_intel_mid_early_setup(void) { } #endif #ifdef CONFIG_X86_INTEL_CE diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h index 27811190cbd7..3ba3de457d05 100644 --- a/arch/x86/include/asm/thread_info.h +++ b/arch/x86/include/asm/thread_info.h @@ -28,8 +28,7 @@ struct thread_info { __u32 flags; /* low level flags */ __u32 status; /* thread synchronous flags */ __u32 cpu; /* current CPU */ - int preempt_count; /* 0 => preemptable, - <0 => BUG */ + int saved_preempt_count; mm_segment_t addr_limit; struct restart_block restart_block; void __user *sysenter_return; @@ -49,7 +48,7 @@ struct thread_info { .exec_domain = &default_exec_domain, \ .flags = 0, \ .cpu = 0, \ - .preempt_count = INIT_PREEMPT_COUNT, \ + .saved_preempt_count = INIT_PREEMPT_COUNT, \ .addr_limit = KERNEL_DS, \ .restart_block = { \ .fn = do_no_restart_syscall, \ @@ -154,8 +153,6 @@ struct thread_info { #define _TIF_WORK_CTXSW_PREV (_TIF_WORK_CTXSW|_TIF_USER_RETURN_NOTIFY) #define _TIF_WORK_CTXSW_NEXT (_TIF_WORK_CTXSW) -#define PREEMPT_ACTIVE 0x10000000 - #ifdef CONFIG_X86_32 #define STACK_WARN (THREAD_SIZE/8) diff --git a/arch/x86/include/asm/trace/exceptions.h b/arch/x86/include/asm/trace/exceptions.h new file mode 100644 index 000000000000..2fbc66c7885b --- /dev/null +++ b/arch/x86/include/asm/trace/exceptions.h @@ -0,0 +1,52 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM exceptions + +#if !defined(_TRACE_PAGE_FAULT_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_PAGE_FAULT_H + +#include <linux/tracepoint.h> + +extern void trace_irq_vector_regfunc(void); +extern void trace_irq_vector_unregfunc(void); + +DECLARE_EVENT_CLASS(x86_exceptions, + + TP_PROTO(unsigned long address, struct pt_regs *regs, + unsigned long error_code), + + TP_ARGS(address, regs, error_code), + + TP_STRUCT__entry( + __field( unsigned long, address ) + __field( unsigned long, ip ) + __field( unsigned long, error_code ) + ), + + TP_fast_assign( + __entry->address = address; + __entry->ip = regs->ip; + __entry->error_code = error_code; + ), + + TP_printk("address=%pf ip=%pf error_code=0x%lx", + (void *)__entry->address, (void *)__entry->ip, + __entry->error_code) ); + +#define DEFINE_PAGE_FAULT_EVENT(name) \ +DEFINE_EVENT_FN(x86_exceptions, name, \ + TP_PROTO(unsigned long address, struct pt_regs *regs, \ + unsigned long error_code), \ + TP_ARGS(address, regs, error_code), \ + trace_irq_vector_regfunc, \ + trace_irq_vector_unregfunc); + +DEFINE_PAGE_FAULT_EVENT(page_fault_user); +DEFINE_PAGE_FAULT_EVENT(page_fault_kernel); + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#define TRACE_INCLUDE_FILE exceptions +#endif /* _TRACE_PAGE_FAULT_H */ + +/* This part must be outside protection */ +#include <trace/define_trace.h> diff --git a/arch/x86/include/asm/traps.h b/arch/x86/include/asm/traps.h index 7036cb60cd87..58d66fe06b61 100644 --- a/arch/x86/include/asm/traps.h +++ b/arch/x86/include/asm/traps.h @@ -37,6 +37,23 @@ asmlinkage void machine_check(void); #endif /* CONFIG_X86_MCE */ asmlinkage void simd_coprocessor_error(void); +#ifdef CONFIG_TRACING +asmlinkage void trace_page_fault(void); +#define trace_divide_error divide_error +#define trace_bounds bounds +#define trace_invalid_op invalid_op +#define trace_device_not_available device_not_available +#define trace_coprocessor_segment_overrun coprocessor_segment_overrun +#define trace_invalid_TSS invalid_TSS +#define trace_segment_not_present segment_not_present +#define trace_general_protection general_protection +#define trace_spurious_interrupt_bug spurious_interrupt_bug +#define trace_coprocessor_error coprocessor_error +#define trace_alignment_check alignment_check +#define trace_simd_coprocessor_error simd_coprocessor_error +#define trace_async_page_fault async_page_fault +#endif + dotraplinkage void do_divide_error(struct pt_regs *, long); dotraplinkage void do_debug(struct pt_regs *, long); dotraplinkage void do_nmi(struct pt_regs *, long); @@ -55,6 +72,9 @@ asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *); #endif dotraplinkage void do_general_protection(struct pt_regs *, long); dotraplinkage void do_page_fault(struct pt_regs *, unsigned long); +#ifdef CONFIG_TRACING +dotraplinkage void trace_do_page_fault(struct pt_regs *, unsigned long); +#endif dotraplinkage void do_spurious_interrupt_bug(struct pt_regs *, long); dotraplinkage void do_coprocessor_error(struct pt_regs *, long); dotraplinkage void do_alignment_check(struct pt_regs *, long); diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h index 5838fa911aa0..8ec57c07b125 100644 --- a/arch/x86/include/asm/uaccess.h +++ b/arch/x86/include/asm/uaccess.h @@ -542,5 +542,103 @@ extern struct movsl_mask { # include <asm/uaccess_64.h> #endif +unsigned long __must_check _copy_from_user(void *to, const void __user *from, + unsigned n); +unsigned long __must_check _copy_to_user(void __user *to, const void *from, + unsigned n); + +#ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS +# define copy_user_diag __compiletime_error +#else +# define copy_user_diag __compiletime_warning +#endif + +extern void copy_user_diag("copy_from_user() buffer size is too small") +copy_from_user_overflow(void); +extern void copy_user_diag("copy_to_user() buffer size is too small") +copy_to_user_overflow(void) __asm__("copy_from_user_overflow"); + +#undef copy_user_diag + +#ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS + +extern void +__compiletime_warning("copy_from_user() buffer size is not provably correct") +__copy_from_user_overflow(void) __asm__("copy_from_user_overflow"); +#define __copy_from_user_overflow(size, count) __copy_from_user_overflow() + +extern void +__compiletime_warning("copy_to_user() buffer size is not provably correct") +__copy_to_user_overflow(void) __asm__("copy_from_user_overflow"); +#define __copy_to_user_overflow(size, count) __copy_to_user_overflow() + +#else + +static inline void +__copy_from_user_overflow(int size, unsigned long count) +{ + WARN(1, "Buffer overflow detected (%d < %lu)!\n", size, count); +} + +#define __copy_to_user_overflow __copy_from_user_overflow + +#endif + +static inline unsigned long __must_check +copy_from_user(void *to, const void __user *from, unsigned long n) +{ + int sz = __compiletime_object_size(to); + + might_fault(); + + /* + * While we would like to have the compiler do the checking for us + * even in the non-constant size case, any false positives there are + * a problem (especially when DEBUG_STRICT_USER_COPY_CHECKS, but even + * without - the [hopefully] dangerous looking nature of the warning + * would make people go look at the respecitive call sites over and + * over again just to find that there's no problem). + * + * And there are cases where it's just not realistic for the compiler + * to prove the count to be in range. For example when multiple call + * sites of a helper function - perhaps in different source files - + * all doing proper range checking, yet the helper function not doing + * so again. + * + * Therefore limit the compile time checking to the constant size + * case, and do only runtime checking for non-constant sizes. + */ + + if (likely(sz < 0 || sz >= n)) + n = _copy_from_user(to, from, n); + else if(__builtin_constant_p(n)) + copy_from_user_overflow(); + else + __copy_from_user_overflow(sz, n); + + return n; +} + +static inline unsigned long __must_check +copy_to_user(void __user *to, const void *from, unsigned long n) +{ + int sz = __compiletime_object_size(from); + + might_fault(); + + /* See the comment in copy_from_user() above. */ + if (likely(sz < 0 || sz >= n)) + n = _copy_to_user(to, from, n); + else if(__builtin_constant_p(n)) + copy_to_user_overflow(); + else + __copy_to_user_overflow(sz, n); + + return n; +} + +#undef __copy_from_user_overflow +#undef __copy_to_user_overflow + #endif /* _ASM_X86_UACCESS_H */ diff --git a/arch/x86/include/asm/uaccess_32.h b/arch/x86/include/asm/uaccess_32.h index 7f760a9f1f61..3c03a5de64d3 100644 --- a/arch/x86/include/asm/uaccess_32.h +++ b/arch/x86/include/asm/uaccess_32.h @@ -184,33 +184,4 @@ __copy_from_user_inatomic_nocache(void *to, const void __user *from, return __copy_from_user_ll_nocache_nozero(to, from, n); } -unsigned long __must_check copy_to_user(void __user *to, - const void *from, unsigned long n); -unsigned long __must_check _copy_from_user(void *to, - const void __user *from, - unsigned long n); - - -extern void copy_from_user_overflow(void) -#ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS - __compiletime_error("copy_from_user() buffer size is not provably correct") -#else - __compiletime_warning("copy_from_user() buffer size is not provably correct") -#endif -; - -static inline unsigned long __must_check copy_from_user(void *to, - const void __user *from, - unsigned long n) -{ - int sz = __compiletime_object_size(to); - - if (likely(sz == -1 || sz >= n)) - n = _copy_from_user(to, from, n); - else - copy_from_user_overflow(); - - return n; -} - #endif /* _ASM_X86_UACCESS_32_H */ diff --git a/arch/x86/include/asm/uaccess_64.h b/arch/x86/include/asm/uaccess_64.h index 4f7923dd0007..190413d0de57 100644 --- a/arch/x86/include/asm/uaccess_64.h +++ b/arch/x86/include/asm/uaccess_64.h @@ -46,42 +46,13 @@ copy_user_generic(void *to, const void *from, unsigned len) } __must_check unsigned long -_copy_to_user(void __user *to, const void *from, unsigned len); -__must_check unsigned long -_copy_from_user(void *to, const void __user *from, unsigned len); -__must_check unsigned long copy_in_user(void __user *to, const void __user *from, unsigned len); -static inline unsigned long __must_check copy_from_user(void *to, - const void __user *from, - unsigned long n) -{ - int sz = __compiletime_object_size(to); - - might_fault(); - if (likely(sz == -1 || sz >= n)) - n = _copy_from_user(to, from, n); -#ifdef CONFIG_DEBUG_VM - else - WARN(1, "Buffer overflow detected!\n"); -#endif - return n; -} - static __always_inline __must_check -int copy_to_user(void __user *dst, const void *src, unsigned size) -{ - might_fault(); - - return _copy_to_user(dst, src, size); -} - -static __always_inline __must_check -int __copy_from_user(void *dst, const void __user *src, unsigned size) +int __copy_from_user_nocheck(void *dst, const void __user *src, unsigned size) { int ret = 0; - might_fault(); if (!__builtin_constant_p(size)) return copy_user_generic(dst, (__force void *)src, size); switch (size) { @@ -121,11 +92,17 @@ int __copy_from_user(void *dst, const void __user *src, unsigned size) } static __always_inline __must_check -int __copy_to_user(void __user *dst, const void *src, unsigned size) +int __copy_from_user(void *dst, const void __user *src, unsigned size) +{ + might_fault(); + return __copy_from_user_nocheck(dst, src, size); +} + +static __always_inline __must_check +int __copy_to_user_nocheck(void __user *dst, const void *src, unsigned size) { int ret = 0; - might_fault(); if (!__builtin_constant_p(size)) return copy_user_generic((__force void *)dst, src, size); switch (size) { @@ -165,6 +142,13 @@ int __copy_to_user(void __user *dst, const void *src, unsigned size) } static __always_inline __must_check +int __copy_to_user(void __user *dst, const void *src, unsigned size) +{ + might_fault(); + return __copy_to_user_nocheck(dst, src, size); +} + +static __always_inline __must_check int __copy_in_user(void __user *dst, const void __user *src, unsigned size) { int ret = 0; @@ -220,13 +204,13 @@ int __copy_in_user(void __user *dst, const void __user *src, unsigned size) static __must_check __always_inline int __copy_from_user_inatomic(void *dst, const void __user *src, unsigned size) { - return copy_user_generic(dst, (__force const void *)src, size); + return __copy_from_user_nocheck(dst, (__force const void *)src, size); } static __must_check __always_inline int __copy_to_user_inatomic(void __user *dst, const void *src, unsigned size) { - return copy_user_generic((__force void *)dst, src, size); + return __copy_to_user_nocheck((__force void *)dst, src, size); } extern long __copy_user_nocache(void *dst, const void __user *src, diff --git a/arch/x86/include/asm/uprobes.h b/arch/x86/include/asm/uprobes.h index 6e5197910fd8..3087ea9c5f2e 100644 --- a/arch/x86/include/asm/uprobes.h +++ b/arch/x86/include/asm/uprobes.h @@ -35,7 +35,10 @@ typedef u8 uprobe_opcode_t; struct arch_uprobe { u16 fixups; - u8 insn[MAX_UINSN_BYTES]; + union { + u8 insn[MAX_UINSN_BYTES]; + u8 ixol[MAX_UINSN_BYTES]; + }; #ifdef CONFIG_X86_64 unsigned long rip_rela_target_address; #endif @@ -49,11 +52,4 @@ struct arch_uprobe_task { unsigned int saved_tf; }; -extern int arch_uprobe_analyze_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long addr); -extern int arch_uprobe_pre_xol(struct arch_uprobe *aup, struct pt_regs *regs); -extern int arch_uprobe_post_xol(struct arch_uprobe *aup, struct pt_regs *regs); -extern bool arch_uprobe_xol_was_trapped(struct task_struct *tsk); -extern int arch_uprobe_exception_notify(struct notifier_block *self, unsigned long val, void *data); -extern void arch_uprobe_abort_xol(struct arch_uprobe *aup, struct pt_regs *regs); -extern unsigned long arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr, struct pt_regs *regs); #endif /* _ASM_UPROBES_H */ diff --git a/arch/x86/include/asm/uv/uv.h b/arch/x86/include/asm/uv/uv.h index 062921ef34e9..6b964a0b86d1 100644 --- a/arch/x86/include/asm/uv/uv.h +++ b/arch/x86/include/asm/uv/uv.h @@ -12,6 +12,7 @@ extern enum uv_system_type get_uv_system_type(void); extern int is_uv_system(void); extern void uv_cpu_init(void); extern void uv_nmi_init(void); +extern void uv_register_nmi_notifier(void); extern void uv_system_init(void); extern const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, struct mm_struct *mm, @@ -25,6 +26,7 @@ static inline enum uv_system_type get_uv_system_type(void) { return UV_NONE; } static inline int is_uv_system(void) { return 0; } static inline void uv_cpu_init(void) { } static inline void uv_system_init(void) { } +static inline void uv_register_nmi_notifier(void) { } static inline const struct cpumask * uv_flush_tlb_others(const struct cpumask *cpumask, struct mm_struct *mm, unsigned long start, unsigned long end, unsigned int cpu) diff --git a/arch/x86/include/asm/uv/uv_hub.h b/arch/x86/include/asm/uv/uv_hub.h index 2c32df95bb78..a30836c8ac4d 100644 --- a/arch/x86/include/asm/uv/uv_hub.h +++ b/arch/x86/include/asm/uv/uv_hub.h @@ -502,8 +502,8 @@ struct uv_blade_info { unsigned short nr_online_cpus; unsigned short pnode; short memory_nid; - spinlock_t nmi_lock; - unsigned long nmi_count; + spinlock_t nmi_lock; /* obsolete, see uv_hub_nmi */ + unsigned long nmi_count; /* obsolete, see uv_hub_nmi */ }; extern struct uv_blade_info *uv_blade_info; extern short *uv_node_to_blade; @@ -576,6 +576,59 @@ static inline int uv_num_possible_blades(void) return uv_possible_blades; } +/* Per Hub NMI support */ +extern void uv_nmi_setup(void); + +/* BMC sets a bit this MMR non-zero before sending an NMI */ +#define UVH_NMI_MMR UVH_SCRATCH5 +#define UVH_NMI_MMR_CLEAR UVH_SCRATCH5_ALIAS +#define UVH_NMI_MMR_SHIFT 63 +#define UVH_NMI_MMR_TYPE "SCRATCH5" + +/* Newer SMM NMI handler, not present in all systems */ +#define UVH_NMI_MMRX UVH_EVENT_OCCURRED0 +#define UVH_NMI_MMRX_CLEAR UVH_EVENT_OCCURRED0_ALIAS +#define UVH_NMI_MMRX_SHIFT (is_uv1_hub() ? \ + UV1H_EVENT_OCCURRED0_EXTIO_INT0_SHFT :\ + UVXH_EVENT_OCCURRED0_EXTIO_INT0_SHFT) +#define UVH_NMI_MMRX_TYPE "EXTIO_INT0" + +/* Non-zero indicates newer SMM NMI handler present */ +#define UVH_NMI_MMRX_SUPPORTED UVH_EXTIO_INT0_BROADCAST + +/* Indicates to BIOS that we want to use the newer SMM NMI handler */ +#define UVH_NMI_MMRX_REQ UVH_SCRATCH5_ALIAS_2 +#define UVH_NMI_MMRX_REQ_SHIFT 62 + +struct uv_hub_nmi_s { + raw_spinlock_t nmi_lock; + atomic_t in_nmi; /* flag this node in UV NMI IRQ */ + atomic_t cpu_owner; /* last locker of this struct */ + atomic_t read_mmr_count; /* count of MMR reads */ + atomic_t nmi_count; /* count of true UV NMIs */ + unsigned long nmi_value; /* last value read from NMI MMR */ +}; + +struct uv_cpu_nmi_s { + struct uv_hub_nmi_s *hub; + atomic_t state; + atomic_t pinging; + int queries; + int pings; +}; + +DECLARE_PER_CPU(struct uv_cpu_nmi_s, __uv_cpu_nmi); +#define uv_cpu_nmi (__get_cpu_var(__uv_cpu_nmi)) +#define uv_hub_nmi (uv_cpu_nmi.hub) +#define uv_cpu_nmi_per(cpu) (per_cpu(__uv_cpu_nmi, cpu)) +#define uv_hub_nmi_per(cpu) (uv_cpu_nmi_per(cpu).hub) + +/* uv_cpu_nmi_states */ +#define UV_NMI_STATE_OUT 0 +#define UV_NMI_STATE_IN 1 +#define UV_NMI_STATE_DUMP 2 +#define UV_NMI_STATE_DUMP_DONE 3 + /* Update SCIR state */ static inline void uv_set_scir_bits(unsigned char value) { diff --git a/arch/x86/include/asm/uv/uv_mmrs.h b/arch/x86/include/asm/uv/uv_mmrs.h index bd5f80e58a23..e42249bcf7e1 100644 --- a/arch/x86/include/asm/uv/uv_mmrs.h +++ b/arch/x86/include/asm/uv/uv_mmrs.h @@ -461,6 +461,23 @@ union uvh_event_occurred0_u { /* ========================================================================= */ +/* UVH_EXTIO_INT0_BROADCAST */ +/* ========================================================================= */ +#define UVH_EXTIO_INT0_BROADCAST 0x61448UL +#define UVH_EXTIO_INT0_BROADCAST_32 0x3f0 + +#define UVH_EXTIO_INT0_BROADCAST_ENABLE_SHFT 0 +#define UVH_EXTIO_INT0_BROADCAST_ENABLE_MASK 0x0000000000000001UL + +union uvh_extio_int0_broadcast_u { + unsigned long v; + struct uvh_extio_int0_broadcast_s { + unsigned long enable:1; /* RW */ + unsigned long rsvd_1_63:63; + } s; +}; + +/* ========================================================================= */ /* UVH_GR0_TLB_INT0_CONFIG */ /* ========================================================================= */ #define UVH_GR0_TLB_INT0_CONFIG 0x61b00UL @@ -2606,6 +2623,20 @@ union uvh_scratch5_u { }; /* ========================================================================= */ +/* UVH_SCRATCH5_ALIAS */ +/* ========================================================================= */ +#define UVH_SCRATCH5_ALIAS 0x2d0208UL +#define UVH_SCRATCH5_ALIAS_32 0x780 + + +/* ========================================================================= */ +/* UVH_SCRATCH5_ALIAS_2 */ +/* ========================================================================= */ +#define UVH_SCRATCH5_ALIAS_2 0x2d0210UL +#define UVH_SCRATCH5_ALIAS_2_32 0x788 + + +/* ========================================================================= */ /* UVXH_EVENT_OCCURRED2 */ /* ========================================================================= */ #define UVXH_EVENT_OCCURRED2 0x70100UL diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h index 828a1565ba57..0f1be11e43d2 100644 --- a/arch/x86/include/asm/x86_init.h +++ b/arch/x86/include/asm/x86_init.h @@ -172,6 +172,7 @@ struct x86_platform_ops { struct pci_dev; struct msi_msg; +struct msi_desc; struct x86_msi_ops { int (*setup_msi_irqs)(struct pci_dev *dev, int nvec, int type); @@ -182,6 +183,8 @@ struct x86_msi_ops { void (*teardown_msi_irqs)(struct pci_dev *dev); void (*restore_msi_irqs)(struct pci_dev *dev, int irq); int (*setup_hpet_msi)(unsigned int irq, unsigned int id); + u32 (*msi_mask_irq)(struct msi_desc *desc, u32 mask, u32 flag); + u32 (*msix_mask_irq)(struct msi_desc *desc, u32 flag); }; struct IO_APIC_route_entry; diff --git a/arch/x86/include/asm/xen/page-coherent.h b/arch/x86/include/asm/xen/page-coherent.h new file mode 100644 index 000000000000..7f02fe4e2c7b --- /dev/null +++ b/arch/x86/include/asm/xen/page-coherent.h @@ -0,0 +1,38 @@ +#ifndef _ASM_X86_XEN_PAGE_COHERENT_H +#define _ASM_X86_XEN_PAGE_COHERENT_H + +#include <asm/page.h> +#include <linux/dma-attrs.h> +#include <linux/dma-mapping.h> + +static inline void *xen_alloc_coherent_pages(struct device *hwdev, size_t size, + dma_addr_t *dma_handle, gfp_t flags, + struct dma_attrs *attrs) +{ + void *vstart = (void*)__get_free_pages(flags, get_order(size)); + *dma_handle = virt_to_phys(vstart); + return vstart; +} + +static inline void xen_free_coherent_pages(struct device *hwdev, size_t size, + void *cpu_addr, dma_addr_t dma_handle, + struct dma_attrs *attrs) +{ + free_pages((unsigned long) cpu_addr, get_order(size)); +} + +static inline void xen_dma_map_page(struct device *hwdev, struct page *page, + unsigned long offset, size_t size, enum dma_data_direction dir, + struct dma_attrs *attrs) { } + +static inline void xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle, + size_t size, enum dma_data_direction dir, + struct dma_attrs *attrs) { } + +static inline void xen_dma_sync_single_for_cpu(struct device *hwdev, + dma_addr_t handle, size_t size, enum dma_data_direction dir) { } + +static inline void xen_dma_sync_single_for_device(struct device *hwdev, + dma_addr_t handle, size_t size, enum dma_data_direction dir) { } + +#endif /* _ASM_X86_XEN_PAGE_COHERENT_H */ diff --git a/arch/x86/include/uapi/asm/bootparam.h b/arch/x86/include/uapi/asm/bootparam.h index c15ddaf90710..9c3733c5f8f7 100644 --- a/arch/x86/include/uapi/asm/bootparam.h +++ b/arch/x86/include/uapi/asm/bootparam.h @@ -158,7 +158,7 @@ enum { X86_SUBARCH_PC = 0, X86_SUBARCH_LGUEST, X86_SUBARCH_XEN, - X86_SUBARCH_MRST, + X86_SUBARCH_INTEL_MID, X86_SUBARCH_CE4100, X86_NR_SUBARCHS, }; diff --git a/arch/x86/include/uapi/asm/hyperv.h b/arch/x86/include/uapi/asm/hyperv.h index b80420bcd09d..b8f1c0176cbc 100644 --- a/arch/x86/include/uapi/asm/hyperv.h +++ b/arch/x86/include/uapi/asm/hyperv.h @@ -27,6 +27,19 @@ #define HV_X64_MSR_VP_RUNTIME_AVAILABLE (1 << 0) /* Partition Reference Counter (HV_X64_MSR_TIME_REF_COUNT) available*/ #define HV_X64_MSR_TIME_REF_COUNT_AVAILABLE (1 << 1) + +/* + * There is a single feature flag that signifies the presence of the MSR + * that can be used to retrieve both the local APIC Timer frequency as + * well as the TSC frequency. + */ + +/* Local APIC timer frequency MSR (HV_X64_MSR_APIC_FREQUENCY) is available */ +#define HV_X64_MSR_APIC_FREQUENCY_AVAILABLE (1 << 11) + +/* TSC frequency MSR (HV_X64_MSR_TSC_FREQUENCY) is available */ +#define HV_X64_MSR_TSC_FREQUENCY_AVAILABLE (1 << 11) + /* * Basic SynIC MSRs (HV_X64_MSR_SCONTROL through HV_X64_MSR_EOM * and HV_X64_MSR_SINT0 through HV_X64_MSR_SINT15) available @@ -136,6 +149,12 @@ /* MSR used to read the per-partition time reference counter */ #define HV_X64_MSR_TIME_REF_COUNT 0x40000020 +/* MSR used to retrieve the TSC frequency */ +#define HV_X64_MSR_TSC_FREQUENCY 0x40000022 + +/* MSR used to retrieve the local APIC timer frequency */ +#define HV_X64_MSR_APIC_FREQUENCY 0x40000023 + /* Define the virtual APIC registers */ #define HV_X64_MSR_EOI 0x40000070 #define HV_X64_MSR_ICR 0x40000071 diff --git a/arch/x86/include/uapi/asm/kvm.h b/arch/x86/include/uapi/asm/kvm.h index 5d9a3033b3d7..d3a87780c70b 100644 --- a/arch/x86/include/uapi/asm/kvm.h +++ b/arch/x86/include/uapi/asm/kvm.h @@ -211,9 +211,9 @@ struct kvm_cpuid_entry2 { __u32 padding[3]; }; -#define KVM_CPUID_FLAG_SIGNIFCANT_INDEX 1 -#define KVM_CPUID_FLAG_STATEFUL_FUNC 2 -#define KVM_CPUID_FLAG_STATE_READ_NEXT 4 +#define KVM_CPUID_FLAG_SIGNIFCANT_INDEX BIT(0) +#define KVM_CPUID_FLAG_STATEFUL_FUNC BIT(1) +#define KVM_CPUID_FLAG_STATE_READ_NEXT BIT(2) /* for KVM_SET_CPUID2 */ struct kvm_cpuid2 { diff --git a/arch/x86/include/uapi/asm/msr-index.h b/arch/x86/include/uapi/asm/msr-index.h index bb0465090ae5..b93e09a0fa21 100644 --- a/arch/x86/include/uapi/asm/msr-index.h +++ b/arch/x86/include/uapi/asm/msr-index.h @@ -536,6 +536,7 @@ /* MSR_IA32_VMX_MISC bits */ #define MSR_IA32_VMX_MISC_VMWRITE_SHADOW_RO_FIELDS (1ULL << 29) +#define MSR_IA32_VMX_MISC_PREEMPTION_TIMER_SCALE 0x1F /* AMD-V MSRs */ #define MSR_VM_CR 0xc0010114 diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index a5408b965c9d..9b0a34e2cd79 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -36,6 +36,8 @@ obj-y += tsc.o io_delay.o rtc.o obj-y += pci-iommu_table.o obj-y += resource.o +obj-$(CONFIG_PREEMPT) += preempt.o + obj-y += process.o obj-y += i387.o xsave.o obj-y += ptrace.o diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 40c76604199f..6c0b43bd024b 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -189,24 +189,31 @@ static int __init acpi_parse_madt(struct acpi_table_header *table) return 0; } -static void acpi_register_lapic(int id, u8 enabled) +/** + * acpi_register_lapic - register a local apic and generates a logic cpu number + * @id: local apic id to register + * @enabled: this cpu is enabled or not + * + * Returns the logic cpu number which maps to the local apic + */ +static int acpi_register_lapic(int id, u8 enabled) { unsigned int ver = 0; if (id >= MAX_LOCAL_APIC) { printk(KERN_INFO PREFIX "skipped apicid that is too big\n"); - return; + return -EINVAL; } if (!enabled) { ++disabled_cpus; - return; + return -EINVAL; } if (boot_cpu_physical_apicid != -1U) ver = apic_version[boot_cpu_physical_apicid]; - generic_processor_info(id, ver); + return generic_processor_info(id, ver); } static int __init @@ -614,84 +621,27 @@ static void acpi_map_cpu2node(acpi_handle handle, int cpu, int physid) #endif } -static int _acpi_map_lsapic(acpi_handle handle, int *pcpu) +static int _acpi_map_lsapic(acpi_handle handle, int physid, int *pcpu) { - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; - union acpi_object *obj; - struct acpi_madt_local_apic *lapic; - cpumask_var_t tmp_map, new_map; - u8 physid; int cpu; - int retval = -ENOMEM; - - if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer))) - return -EINVAL; - - if (!buffer.length || !buffer.pointer) - return -EINVAL; - - obj = buffer.pointer; - if (obj->type != ACPI_TYPE_BUFFER || - obj->buffer.length < sizeof(*lapic)) { - kfree(buffer.pointer); - return -EINVAL; - } - lapic = (struct acpi_madt_local_apic *)obj->buffer.pointer; - - if (lapic->header.type != ACPI_MADT_TYPE_LOCAL_APIC || - !(lapic->lapic_flags & ACPI_MADT_ENABLED)) { - kfree(buffer.pointer); - return -EINVAL; - } - - physid = lapic->id; - - kfree(buffer.pointer); - buffer.length = ACPI_ALLOCATE_BUFFER; - buffer.pointer = NULL; - lapic = NULL; - - if (!alloc_cpumask_var(&tmp_map, GFP_KERNEL)) - goto out; - - if (!alloc_cpumask_var(&new_map, GFP_KERNEL)) - goto free_tmp_map; - - cpumask_copy(tmp_map, cpu_present_mask); - acpi_register_lapic(physid, ACPI_MADT_ENABLED); - - /* - * If acpi_register_lapic successfully generates a new logical cpu - * number, then the following will get us exactly what was mapped - */ - cpumask_andnot(new_map, cpu_present_mask, tmp_map); - if (cpumask_empty(new_map)) { - printk ("Unable to map lapic to logical cpu number\n"); - retval = -EINVAL; - goto free_new_map; + cpu = acpi_register_lapic(physid, ACPI_MADT_ENABLED); + if (cpu < 0) { + pr_info(PREFIX "Unable to map lapic to logical cpu number\n"); + return cpu; } acpi_processor_set_pdc(handle); - - cpu = cpumask_first(new_map); acpi_map_cpu2node(handle, cpu, physid); *pcpu = cpu; - retval = 0; - -free_new_map: - free_cpumask_var(new_map); -free_tmp_map: - free_cpumask_var(tmp_map); -out: - return retval; + return 0; } /* wrapper to silence section mismatch warning */ -int __ref acpi_map_lsapic(acpi_handle handle, int *pcpu) +int __ref acpi_map_lsapic(acpi_handle handle, int physid, int *pcpu) { - return _acpi_map_lsapic(handle, pcpu); + return _acpi_map_lsapic(handle, physid, pcpu); } EXPORT_SYMBOL(acpi_map_lsapic); @@ -745,7 +695,7 @@ static int __init acpi_parse_sbf(struct acpi_table_header *table) #ifdef CONFIG_HPET_TIMER #include <asm/hpet.h> -static struct __initdata resource *hpet_res; +static struct resource *hpet_res __initdata; static int __init acpi_parse_hpet(struct acpi_table_header *table) { diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c index 33120100ff5e..3a2ae4c88948 100644 --- a/arch/x86/kernel/acpi/sleep.c +++ b/arch/x86/kernel/acpi/sleep.c @@ -26,6 +26,17 @@ static char temp_stack[4096]; #endif /** + * x86_acpi_enter_sleep_state - enter sleep state + * @state: Sleep state to enter. + * + * Wrapper around acpi_enter_sleep_state() to be called by assmebly. + */ +acpi_status asmlinkage x86_acpi_enter_sleep_state(u8 state) +{ + return acpi_enter_sleep_state(state); +} + +/** * x86_acpi_suspend_lowlevel - save kernel state * * Create an identity mapped page table and copy the wakeup routine to diff --git a/arch/x86/kernel/acpi/sleep.h b/arch/x86/kernel/acpi/sleep.h index c9c2c982d5e4..65c7b606b606 100644 --- a/arch/x86/kernel/acpi/sleep.h +++ b/arch/x86/kernel/acpi/sleep.h @@ -17,3 +17,5 @@ extern void wakeup_long64(void); extern void do_suspend_lowlevel(void); extern int x86_acpi_suspend_lowlevel(void); + +acpi_status asmlinkage x86_acpi_enter_sleep_state(u8 state); diff --git a/arch/x86/kernel/acpi/wakeup_32.S b/arch/x86/kernel/acpi/wakeup_32.S index d1daa66ab162..665c6b7d2ea9 100644 --- a/arch/x86/kernel/acpi/wakeup_32.S +++ b/arch/x86/kernel/acpi/wakeup_32.S @@ -73,7 +73,7 @@ ENTRY(do_suspend_lowlevel) call save_processor_state call save_registers pushl $3 - call acpi_enter_sleep_state + call x86_acpi_enter_sleep_state addl $4, %esp # In case of S3 failure, we'll emerge here. Jump diff --git a/arch/x86/kernel/acpi/wakeup_64.S b/arch/x86/kernel/acpi/wakeup_64.S index 8ea5164cbd04..ae693b51ed8e 100644 --- a/arch/x86/kernel/acpi/wakeup_64.S +++ b/arch/x86/kernel/acpi/wakeup_64.S @@ -73,7 +73,7 @@ ENTRY(do_suspend_lowlevel) addq $8, %rsp movl $3, %edi xorl %eax, %eax - call acpi_enter_sleep_state + call x86_acpi_enter_sleep_state /* in case something went wrong, restore the machine status and go on */ jmp resume_point diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index 15e8563e5c24..df94598ad05a 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c @@ -402,17 +402,6 @@ void alternatives_enable_smp(void) { struct smp_alt_module *mod; -#ifdef CONFIG_LOCKDEP - /* - * Older binutils section handling bug prevented - * alternatives-replacement from working reliably. - * - * If this still occurs then you should see a hang - * or crash shortly after this line: - */ - pr_info("lockdep: fixing up alternatives\n"); -#endif - /* Why bother if there are no other CPUs? */ BUG_ON(num_possible_cpus() == 1); diff --git a/arch/x86/kernel/apb_timer.c b/arch/x86/kernel/apb_timer.c index c9876efecafb..af5b08ab3b71 100644 --- a/arch/x86/kernel/apb_timer.c +++ b/arch/x86/kernel/apb_timer.c @@ -40,7 +40,7 @@ #include <asm/fixmap.h> #include <asm/apb_timer.h> -#include <asm/mrst.h> +#include <asm/intel-mid.h> #include <asm/time.h> #define APBT_CLOCKEVENT_RATING 110 @@ -157,13 +157,13 @@ static int __init apbt_clockevent_register(void) adev->num = smp_processor_id(); adev->timer = dw_apb_clockevent_init(smp_processor_id(), "apbt0", - mrst_timer_options == MRST_TIMER_LAPIC_APBT ? + intel_mid_timer_options == INTEL_MID_TIMER_LAPIC_APBT ? APBT_CLOCKEVENT_RATING - 100 : APBT_CLOCKEVENT_RATING, adev_virt_addr(adev), 0, apbt_freq); /* Firmware does EOI handling for us. */ adev->timer->eoi = NULL; - if (mrst_timer_options == MRST_TIMER_LAPIC_APBT) { + if (intel_mid_timer_options == INTEL_MID_TIMER_LAPIC_APBT) { global_clock_event = &adev->timer->ced; printk(KERN_DEBUG "%s clockevent registered as global\n", global_clock_event->name); @@ -253,7 +253,7 @@ static int apbt_cpuhp_notify(struct notifier_block *n, static __init int apbt_late_init(void) { - if (mrst_timer_options == MRST_TIMER_LAPIC_APBT || + if (intel_mid_timer_options == INTEL_MID_TIMER_LAPIC_APBT || !apb_timer_block_enabled) return 0; /* This notifier should be called after workqueue is ready */ @@ -340,7 +340,7 @@ void __init apbt_time_init(void) } #ifdef CONFIG_SMP /* kernel cmdline disable apb timer, so we will use lapic timers */ - if (mrst_timer_options == MRST_TIMER_LAPIC_APBT) { + if (intel_mid_timer_options == INTEL_MID_TIMER_LAPIC_APBT) { printk(KERN_INFO "apbt: disabled per cpu timer\n"); return; } diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index a7eb82d9b012..d278736bf774 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -62,6 +62,7 @@ unsigned disabled_cpus; /* Processor that is doing the boot up */ unsigned int boot_cpu_physical_apicid = -1U; +EXPORT_SYMBOL_GPL(boot_cpu_physical_apicid); /* * The highest APIC ID seen during enumeration. @@ -2107,7 +2108,7 @@ void disconnect_bsp_APIC(int virt_wire_setup) apic_write(APIC_LVT1, value); } -void generic_processor_info(int apicid, int version) +int generic_processor_info(int apicid, int version) { int cpu, max = nr_cpu_ids; bool boot_cpu_detected = physid_isset(boot_cpu_physical_apicid, @@ -2127,7 +2128,7 @@ void generic_processor_info(int apicid, int version) " Processor %d/0x%x ignored.\n", max, thiscpu, apicid); disabled_cpus++; - return; + return -ENODEV; } if (num_processors >= nr_cpu_ids) { @@ -2138,7 +2139,7 @@ void generic_processor_info(int apicid, int version) " Processor %d/0x%x ignored.\n", max, thiscpu, apicid); disabled_cpus++; - return; + return -EINVAL; } num_processors++; @@ -2183,6 +2184,8 @@ void generic_processor_info(int apicid, int version) #endif set_cpu_possible(cpu, true); set_cpu_present(cpu, true); + + return cpu; } int hard_smp_processor_id(void) diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index a419814cea57..ad0dc0428baf 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c @@ -39,12 +39,6 @@ #include <asm/x86_init.h> #include <asm/nmi.h> -/* BMC sets a bit this MMR non-zero before sending an NMI */ -#define UVH_NMI_MMR UVH_SCRATCH5 -#define UVH_NMI_MMR_CLEAR (UVH_NMI_MMR + 8) -#define UV_NMI_PENDING_MASK (1UL << 63) -DEFINE_PER_CPU(unsigned long, cpu_last_nmi_count); - DEFINE_PER_CPU(int, x2apic_extra_bits); #define PR_DEVEL(fmt, args...) pr_devel("%s: " fmt, __func__, args) @@ -58,7 +52,6 @@ int uv_min_hub_revision_id; EXPORT_SYMBOL_GPL(uv_min_hub_revision_id); unsigned int uv_apicid_hibits; EXPORT_SYMBOL_GPL(uv_apicid_hibits); -static DEFINE_SPINLOCK(uv_nmi_lock); static struct apic apic_x2apic_uv_x; @@ -847,68 +840,6 @@ void uv_cpu_init(void) set_x2apic_extra_bits(uv_hub_info->pnode); } -/* - * When NMI is received, print a stack trace. - */ -int uv_handle_nmi(unsigned int reason, struct pt_regs *regs) -{ - unsigned long real_uv_nmi; - int bid; - - /* - * Each blade has an MMR that indicates when an NMI has been sent - * to cpus on the blade. If an NMI is detected, atomically - * clear the MMR and update a per-blade NMI count used to - * cause each cpu on the blade to notice a new NMI. - */ - bid = uv_numa_blade_id(); - real_uv_nmi = (uv_read_local_mmr(UVH_NMI_MMR) & UV_NMI_PENDING_MASK); - - if (unlikely(real_uv_nmi)) { - spin_lock(&uv_blade_info[bid].nmi_lock); - real_uv_nmi = (uv_read_local_mmr(UVH_NMI_MMR) & UV_NMI_PENDING_MASK); - if (real_uv_nmi) { - uv_blade_info[bid].nmi_count++; - uv_write_local_mmr(UVH_NMI_MMR_CLEAR, UV_NMI_PENDING_MASK); - } - spin_unlock(&uv_blade_info[bid].nmi_lock); - } - - if (likely(__get_cpu_var(cpu_last_nmi_count) == uv_blade_info[bid].nmi_count)) - return NMI_DONE; - - __get_cpu_var(cpu_last_nmi_count) = uv_blade_info[bid].nmi_count; - - /* - * Use a lock so only one cpu prints at a time. - * This prevents intermixed output. - */ - spin_lock(&uv_nmi_lock); - pr_info("UV NMI stack dump cpu %u:\n", smp_processor_id()); - dump_stack(); - spin_unlock(&uv_nmi_lock); - - return NMI_HANDLED; -} - -void uv_register_nmi_notifier(void) -{ - if (register_nmi_handler(NMI_UNKNOWN, uv_handle_nmi, 0, "uv")) - printk(KERN_WARNING "UV NMI handler failed to register\n"); -} - -void uv_nmi_init(void) -{ - unsigned int value; - - /* - * Unmask NMI on all cpus - */ - value = apic_read(APIC_LVT1) | APIC_DM_NMI; - value &= ~APIC_LVT_MASKED; - apic_write(APIC_LVT1, value); -} - void __init uv_system_init(void) { union uvh_rh_gam_config_mmr_u m_n_config; @@ -1046,6 +977,7 @@ void __init uv_system_init(void) map_mmr_high(max_pnode); map_mmioh_high(min_pnode, max_pnode); + uv_nmi_setup(); uv_cpu_init(); uv_scir_register_cpu_notifier(); uv_register_nmi_notifier(); diff --git a/arch/x86/kernel/asm-offsets.c b/arch/x86/kernel/asm-offsets.c index 28610822fb3c..9f6b9341950f 100644 --- a/arch/x86/kernel/asm-offsets.c +++ b/arch/x86/kernel/asm-offsets.c @@ -32,7 +32,6 @@ void common(void) { OFFSET(TI_flags, thread_info, flags); OFFSET(TI_status, thread_info, status); OFFSET(TI_addr_limit, thread_info, addr_limit); - OFFSET(TI_preempt_count, thread_info, preempt_count); BLANK(); OFFSET(crypto_tfm_ctx_offset, crypto_tfm, __crt_ctx); diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index 903a264af981..bca023bdd6b2 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -339,7 +339,7 @@ static void amd_get_topology(struct cpuinfo_x86 *c) #endif /* - * On a AMD dual core setup the lower bits of the APIC id distingush the cores. + * On a AMD dual core setup the lower bits of the APIC id distinguish the cores. * Assumes number of cores is a power of two. */ static void amd_detect_cmp(struct cpuinfo_x86 *c) @@ -823,8 +823,8 @@ static const struct cpu_dev amd_cpu_dev = { .c_vendor = "AMD", .c_ident = { "AuthenticAMD" }, #ifdef CONFIG_X86_32 - .c_models = { - { .vendor = X86_VENDOR_AMD, .family = 4, .model_names = + .legacy_models = { + { .family = 4, .model_names = { [3] = "486 DX/2", [7] = "486 DX/2-WB", @@ -835,7 +835,7 @@ static const struct cpu_dev amd_cpu_dev = { } }, }, - .c_size_cache = amd_size_cache, + .legacy_cache_size = amd_size_cache, #endif .c_early_init = early_init_amd, .c_detect_tlb = cpu_detect_tlb_amd, diff --git a/arch/x86/kernel/cpu/centaur.c b/arch/x86/kernel/cpu/centaur.c index fbf6c3bc2400..8d5652dc99dd 100644 --- a/arch/x86/kernel/cpu/centaur.c +++ b/arch/x86/kernel/cpu/centaur.c @@ -468,10 +468,10 @@ static void init_centaur(struct cpuinfo_x86 *c) #endif } +#ifdef CONFIG_X86_32 static unsigned int centaur_size_cache(struct cpuinfo_x86 *c, unsigned int size) { -#ifdef CONFIG_X86_32 /* VIA C3 CPUs (670-68F) need further shifting. */ if ((c->x86 == 6) && ((c->x86_model == 7) || (c->x86_model == 8))) size >>= 8; @@ -484,16 +484,18 @@ centaur_size_cache(struct cpuinfo_x86 *c, unsigned int size) if ((c->x86 == 6) && (c->x86_model == 9) && (c->x86_mask == 1) && (size == 65)) size -= 1; -#endif return size; } +#endif static const struct cpu_dev centaur_cpu_dev = { .c_vendor = "Centaur", .c_ident = { "CentaurHauls" }, .c_early_init = early_init_centaur, .c_init = init_centaur, - .c_size_cache = centaur_size_cache, +#ifdef CONFIG_X86_32 + .legacy_cache_size = centaur_size_cache, +#endif .c_x86_vendor = X86_VENDOR_CENTAUR, }; diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 2793d1f095a2..6abc172b8258 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -346,7 +346,8 @@ static void filter_cpuid_features(struct cpuinfo_x86 *c, bool warn) /* Look up CPU names by table lookup. */ static const char *table_lookup_model(struct cpuinfo_x86 *c) { - const struct cpu_model_info *info; +#ifdef CONFIG_X86_32 + const struct legacy_cpu_model_info *info; if (c->x86_model >= 16) return NULL; /* Range check */ @@ -354,13 +355,14 @@ static const char *table_lookup_model(struct cpuinfo_x86 *c) if (!this_cpu) return NULL; - info = this_cpu->c_models; + info = this_cpu->legacy_models; - while (info && info->family) { + while (info->family) { if (info->family == c->x86) return info->model_names[c->x86_model]; info++; } +#endif return NULL; /* Not found */ } @@ -450,8 +452,8 @@ void cpu_detect_cache_sizes(struct cpuinfo_x86 *c) c->x86_tlbsize += ((ebx >> 16) & 0xfff) + (ebx & 0xfff); #else /* do processor-specific cache resizing */ - if (this_cpu->c_size_cache) - l2size = this_cpu->c_size_cache(c, l2size); + if (this_cpu->legacy_cache_size) + l2size = this_cpu->legacy_cache_size(c, l2size); /* Allow user to override all this if necessary. */ if (cachesize_override != -1) @@ -1095,6 +1097,9 @@ DEFINE_PER_CPU(char *, irq_stack_ptr) = DEFINE_PER_CPU(unsigned int, irq_count) __visible = -1; +DEFINE_PER_CPU(int, __preempt_count) = INIT_PREEMPT_COUNT; +EXPORT_PER_CPU_SYMBOL(__preempt_count); + DEFINE_PER_CPU(struct task_struct *, fpu_owner_task); /* @@ -1169,6 +1174,8 @@ void debug_stack_reset(void) DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task; EXPORT_PER_CPU_SYMBOL(current_task); +DEFINE_PER_CPU(int, __preempt_count) = INIT_PREEMPT_COUNT; +EXPORT_PER_CPU_SYMBOL(__preempt_count); DEFINE_PER_CPU(struct task_struct *, fpu_owner_task); #ifdef CONFIG_CC_STACKPROTECTOR diff --git a/arch/x86/kernel/cpu/cpu.h b/arch/x86/kernel/cpu/cpu.h index 4041c24ae7db..c37dc37e8317 100644 --- a/arch/x86/kernel/cpu/cpu.h +++ b/arch/x86/kernel/cpu/cpu.h @@ -1,12 +1,6 @@ #ifndef ARCH_X86_CPU_H #define ARCH_X86_CPU_H -struct cpu_model_info { - int vendor; - int family; - const char *model_names[16]; -}; - /* attempt to consolidate cpu attributes */ struct cpu_dev { const char *c_vendor; @@ -14,15 +8,23 @@ struct cpu_dev { /* some have two possibilities for cpuid string */ const char *c_ident[2]; - struct cpu_model_info c_models[4]; - void (*c_early_init)(struct cpuinfo_x86 *); void (*c_bsp_init)(struct cpuinfo_x86 *); void (*c_init)(struct cpuinfo_x86 *); void (*c_identify)(struct cpuinfo_x86 *); void (*c_detect_tlb)(struct cpuinfo_x86 *); - unsigned int (*c_size_cache)(struct cpuinfo_x86 *, unsigned int); int c_x86_vendor; +#ifdef CONFIG_X86_32 + /* Optional vendor specific routine to obtain the cache size. */ + unsigned int (*legacy_cache_size)(struct cpuinfo_x86 *, + unsigned int); + + /* Family/stepping-based lookup table for model names. */ + struct legacy_cpu_model_info { + int family; + const char *model_names[16]; + } legacy_models[5]; +#endif }; struct _tlb_table { diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index ec7299566f79..dc1ec0dff939 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -665,8 +665,8 @@ static const struct cpu_dev intel_cpu_dev = { .c_vendor = "Intel", .c_ident = { "GenuineIntel" }, #ifdef CONFIG_X86_32 - .c_models = { - { .vendor = X86_VENDOR_INTEL, .family = 4, .model_names = + .legacy_models = { + { .family = 4, .model_names = { [0] = "486 DX-25/33", [1] = "486 DX-50", @@ -679,7 +679,7 @@ static const struct cpu_dev intel_cpu_dev = { [9] = "486 DX/4-WB" } }, - { .vendor = X86_VENDOR_INTEL, .family = 5, .model_names = + { .family = 5, .model_names = { [0] = "Pentium 60/66 A-step", [1] = "Pentium 60/66", @@ -690,7 +690,7 @@ static const struct cpu_dev intel_cpu_dev = { [8] = "Mobile Pentium MMX" } }, - { .vendor = X86_VENDOR_INTEL, .family = 6, .model_names = + { .family = 6, .model_names = { [0] = "Pentium Pro A-step", [1] = "Pentium Pro", @@ -704,7 +704,7 @@ static const struct cpu_dev intel_cpu_dev = { [11] = "Pentium III (Tualatin)", } }, - { .vendor = X86_VENDOR_INTEL, .family = 15, .model_names = + { .family = 15, .model_names = { [0] = "Pentium 4 (Unknown)", [1] = "Pentium 4 (Willamette)", @@ -714,7 +714,7 @@ static const struct cpu_dev intel_cpu_dev = { } }, }, - .c_size_cache = intel_size_cache, + .legacy_cache_size = intel_size_cache, #endif .c_detect_tlb = intel_detect_tlb, .c_early_init = early_init_intel, diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c index 1414c90feaba..0641113e2965 100644 --- a/arch/x86/kernel/cpu/intel_cacheinfo.c +++ b/arch/x86/kernel/cpu/intel_cacheinfo.c @@ -1,5 +1,5 @@ /* - * Routines to indentify caches on Intel CPU. + * Routines to identify caches on Intel CPU. * * Changes: * Venkatesh Pallipadi : Adding cache identification through cpuid(4) diff --git a/arch/x86/kernel/cpu/mcheck/mce-apei.c b/arch/x86/kernel/cpu/mcheck/mce-apei.c index cd8b166a1735..de8b60a53f69 100644 --- a/arch/x86/kernel/cpu/mcheck/mce-apei.c +++ b/arch/x86/kernel/cpu/mcheck/mce-apei.c @@ -42,8 +42,7 @@ void apei_mce_report_mem_error(int corrected, struct cper_sec_mem_err *mem_err) struct mce m; /* Only corrected MC is reported */ - if (!corrected || !(mem_err->validation_bits & - CPER_MEM_VALID_PHYSICAL_ADDRESS)) + if (!corrected || !(mem_err->validation_bits & CPER_MEM_VALID_PA)) return; mce_setup(&m); diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index 71a39f3621ba..9f7ca266864a 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c @@ -15,6 +15,7 @@ #include <linux/clocksource.h> #include <linux/module.h> #include <linux/hardirq.h> +#include <linux/efi.h> #include <linux/interrupt.h> #include <asm/processor.h> #include <asm/hypervisor.h> @@ -23,6 +24,8 @@ #include <asm/desc.h> #include <asm/idle.h> #include <asm/irq_regs.h> +#include <asm/i8259.h> +#include <asm/apic.h> struct ms_hyperv_info ms_hyperv; EXPORT_SYMBOL_GPL(ms_hyperv); @@ -76,6 +79,30 @@ static void __init ms_hyperv_init_platform(void) printk(KERN_INFO "HyperV: features 0x%x, hints 0x%x\n", ms_hyperv.features, ms_hyperv.hints); +#ifdef CONFIG_X86_LOCAL_APIC + if (ms_hyperv.features & HV_X64_MSR_APIC_FREQUENCY_AVAILABLE) { + /* + * Get the APIC frequency. + */ + u64 hv_lapic_frequency; + + rdmsrl(HV_X64_MSR_APIC_FREQUENCY, hv_lapic_frequency); + hv_lapic_frequency = div_u64(hv_lapic_frequency, HZ); + lapic_timer_frequency = hv_lapic_frequency; + printk(KERN_INFO "HyperV: LAPIC Timer Frequency: %#x\n", + lapic_timer_frequency); + + /* + * On Hyper-V, when we are booting off an EFI firmware stack, + * we do not have many legacy devices including PIC, PIT etc. + */ + if (efi_enabled(EFI_BOOT)) { + printk(KERN_INFO "HyperV: Using null_legacy_pic\n"); + legacy_pic = &null_legacy_pic; + } + } +#endif + if (ms_hyperv.features & HV_X64_MSR_TIME_REF_COUNT_AVAILABLE) clocksource_register_hz(&hyperv_cs, NSEC_PER_SEC/100); } diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 9d8449158cf9..8e132931614d 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -1276,16 +1276,16 @@ void perf_events_lapic_init(void) static int __kprobes perf_event_nmi_handler(unsigned int cmd, struct pt_regs *regs) { - int ret; u64 start_clock; u64 finish_clock; + int ret; if (!atomic_read(&active_events)) return NMI_DONE; - start_clock = local_clock(); + start_clock = sched_clock(); ret = x86_pmu.handle_irq(regs); - finish_clock = local_clock(); + finish_clock = sched_clock(); perf_sample_event_took(finish_clock - start_clock); @@ -1989,7 +1989,7 @@ perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry) frame.return_address = 0; bytes = copy_from_user_nmi(&frame, fp, sizeof(frame)); - if (bytes != sizeof(frame)) + if (bytes != 0) break; if (!valid_user_frame(fp, sizeof(frame))) @@ -2041,7 +2041,7 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) frame.return_address = 0; bytes = copy_from_user_nmi(&frame, fp, sizeof(frame)); - if (bytes != sizeof(frame)) + if (bytes != 0) break; if (!valid_user_frame(fp, sizeof(frame))) diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h index cc16faae0538..fd00bb29425d 100644 --- a/arch/x86/kernel/cpu/perf_event.h +++ b/arch/x86/kernel/cpu/perf_event.h @@ -164,6 +164,11 @@ struct cpu_hw_events { struct perf_guest_switch_msr guest_switch_msrs[X86_PMC_IDX_MAX]; /* + * Intel checkpoint mask + */ + u64 intel_cp_status; + + /* * manage shared (per-core, per-cpu) registers * used on Intel NHM/WSM/SNB */ @@ -440,6 +445,7 @@ struct x86_pmu { int lbr_nr; /* hardware stack size */ u64 lbr_sel_mask; /* LBR_SELECT valid bits */ const int *lbr_sel_map; /* lbr_select mappings */ + bool lbr_double_abort; /* duplicated lbr aborts */ /* * Extra registers for events diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index f31a1655d1ff..0fa4f242f050 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -190,9 +190,9 @@ static struct extra_reg intel_snbep_extra_regs[] __read_mostly = { EVENT_EXTRA_END }; -EVENT_ATTR_STR(mem-loads, mem_ld_nhm, "event=0x0b,umask=0x10,ldlat=3"); -EVENT_ATTR_STR(mem-loads, mem_ld_snb, "event=0xcd,umask=0x1,ldlat=3"); -EVENT_ATTR_STR(mem-stores, mem_st_snb, "event=0xcd,umask=0x2"); +EVENT_ATTR_STR(mem-loads, mem_ld_nhm, "event=0x0b,umask=0x10,ldlat=3"); +EVENT_ATTR_STR(mem-loads, mem_ld_snb, "event=0xcd,umask=0x1,ldlat=3"); +EVENT_ATTR_STR(mem-stores, mem_st_snb, "event=0xcd,umask=0x2"); struct attribute *nhm_events_attrs[] = { EVENT_PTR(mem_ld_nhm), @@ -1184,6 +1184,11 @@ static void intel_pmu_disable_fixed(struct hw_perf_event *hwc) wrmsrl(hwc->config_base, ctrl_val); } +static inline bool event_is_checkpointed(struct perf_event *event) +{ + return (event->hw.config & HSW_IN_TX_CHECKPOINTED) != 0; +} + static void intel_pmu_disable_event(struct perf_event *event) { struct hw_perf_event *hwc = &event->hw; @@ -1197,6 +1202,7 @@ static void intel_pmu_disable_event(struct perf_event *event) cpuc->intel_ctrl_guest_mask &= ~(1ull << hwc->idx); cpuc->intel_ctrl_host_mask &= ~(1ull << hwc->idx); + cpuc->intel_cp_status &= ~(1ull << hwc->idx); /* * must disable before any actual event @@ -1271,6 +1277,9 @@ static void intel_pmu_enable_event(struct perf_event *event) if (event->attr.exclude_guest) cpuc->intel_ctrl_host_mask |= (1ull << hwc->idx); + if (unlikely(event_is_checkpointed(event))) + cpuc->intel_cp_status |= (1ull << hwc->idx); + if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) { intel_pmu_enable_fixed(hwc); return; @@ -1289,6 +1298,17 @@ static void intel_pmu_enable_event(struct perf_event *event) int intel_pmu_save_and_restart(struct perf_event *event) { x86_perf_event_update(event); + /* + * For a checkpointed counter always reset back to 0. This + * avoids a situation where the counter overflows, aborts the + * transaction and is then set back to shortly before the + * overflow, and overflows and aborts again. + */ + if (unlikely(event_is_checkpointed(event))) { + /* No race with NMIs because the counter should not be armed */ + wrmsrl(event->hw.event_base, 0); + local64_set(&event->hw.prev_count, 0); + } return x86_perf_event_set_period(event); } @@ -1372,6 +1392,13 @@ again: x86_pmu.drain_pebs(regs); } + /* + * Checkpointed counters can lead to 'spurious' PMIs because the + * rollback caused by the PMI will have cleared the overflow status + * bit. Therefore always force probe these counters. + */ + status |= cpuc->intel_cp_status; + for_each_set_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) { struct perf_event *event = cpuc->events[bit]; @@ -1837,6 +1864,20 @@ static int hsw_hw_config(struct perf_event *event) event->attr.precise_ip > 0)) return -EOPNOTSUPP; + if (event_is_checkpointed(event)) { + /* + * Sampling of checkpointed events can cause situations where + * the CPU constantly aborts because of a overflow, which is + * then checkpointed back and ignored. Forbid checkpointing + * for sampling. + * + * But still allow a long sampling period, so that perf stat + * from KVM works. + */ + if (event->attr.sample_period > 0 && + event->attr.sample_period < 0x7fffffff) + return -EOPNOTSUPP; + } return 0; } @@ -2182,10 +2223,36 @@ static __init void intel_nehalem_quirk(void) } } -EVENT_ATTR_STR(mem-loads, mem_ld_hsw, "event=0xcd,umask=0x1,ldlat=3"); -EVENT_ATTR_STR(mem-stores, mem_st_hsw, "event=0xd0,umask=0x82") +EVENT_ATTR_STR(mem-loads, mem_ld_hsw, "event=0xcd,umask=0x1,ldlat=3"); +EVENT_ATTR_STR(mem-stores, mem_st_hsw, "event=0xd0,umask=0x82") + +/* Haswell special events */ +EVENT_ATTR_STR(tx-start, tx_start, "event=0xc9,umask=0x1"); +EVENT_ATTR_STR(tx-commit, tx_commit, "event=0xc9,umask=0x2"); +EVENT_ATTR_STR(tx-abort, tx_abort, "event=0xc9,umask=0x4"); +EVENT_ATTR_STR(tx-capacity, tx_capacity, "event=0x54,umask=0x2"); +EVENT_ATTR_STR(tx-conflict, tx_conflict, "event=0x54,umask=0x1"); +EVENT_ATTR_STR(el-start, el_start, "event=0xc8,umask=0x1"); +EVENT_ATTR_STR(el-commit, el_commit, "event=0xc8,umask=0x2"); +EVENT_ATTR_STR(el-abort, el_abort, "event=0xc8,umask=0x4"); +EVENT_ATTR_STR(el-capacity, el_capacity, "event=0x54,umask=0x2"); +EVENT_ATTR_STR(el-conflict, el_conflict, "event=0x54,umask=0x1"); +EVENT_ATTR_STR(cycles-t, cycles_t, "event=0x3c,in_tx=1"); +EVENT_ATTR_STR(cycles-ct, cycles_ct, "event=0x3c,in_tx=1,in_tx_cp=1"); static struct attribute *hsw_events_attrs[] = { + EVENT_PTR(tx_start), + EVENT_PTR(tx_commit), + EVENT_PTR(tx_abort), + EVENT_PTR(tx_capacity), + EVENT_PTR(tx_conflict), + EVENT_PTR(el_start), + EVENT_PTR(el_commit), + EVENT_PTR(el_abort), + EVENT_PTR(el_capacity), + EVENT_PTR(el_conflict), + EVENT_PTR(cycles_t), + EVENT_PTR(cycles_ct), EVENT_PTR(mem_ld_hsw), EVENT_PTR(mem_st_hsw), NULL @@ -2452,6 +2519,7 @@ __init int intel_pmu_init(void) x86_pmu.hw_config = hsw_hw_config; x86_pmu.get_event_constraints = hsw_get_event_constraints; x86_pmu.cpu_events = hsw_events_attrs; + x86_pmu.lbr_double_abort = true; pr_cont("Haswell events, "); break; diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c index ab3ba1c1b7dd..ae96cfa5eddd 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c @@ -12,6 +12,7 @@ #define BTS_BUFFER_SIZE (PAGE_SIZE << 4) #define PEBS_BUFFER_SIZE PAGE_SIZE +#define PEBS_FIXUP_SIZE PAGE_SIZE /* * pebs_record_32 for p4 and core not supported @@ -182,18 +183,32 @@ struct pebs_record_nhm { * Same as pebs_record_nhm, with two additional fields. */ struct pebs_record_hsw { - struct pebs_record_nhm nhm; - /* - * Real IP of the event. In the Intel documentation this - * is called eventingrip. - */ - u64 real_ip; - /* - * TSX tuning information field: abort cycles and abort flags. - */ - u64 tsx_tuning; + u64 flags, ip; + u64 ax, bx, cx, dx; + u64 si, di, bp, sp; + u64 r8, r9, r10, r11; + u64 r12, r13, r14, r15; + u64 status, dla, dse, lat; + u64 real_ip, tsx_tuning; +}; + +union hsw_tsx_tuning { + struct { + u32 cycles_last_block : 32, + hle_abort : 1, + rtm_abort : 1, + instruction_abort : 1, + non_instruction_abort : 1, + retry : 1, + data_conflict : 1, + capacity_writes : 1, + capacity_reads : 1; + }; + u64 value; }; +#define PEBS_HSW_TSX_FLAGS 0xff00000000ULL + void init_debug_store_on_cpu(int cpu) { struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds; @@ -214,12 +229,14 @@ void fini_debug_store_on_cpu(int cpu) wrmsr_on_cpu(cpu, MSR_IA32_DS_AREA, 0, 0); } +static DEFINE_PER_CPU(void *, insn_buffer); + static int alloc_pebs_buffer(int cpu) { struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds; int node = cpu_to_node(cpu); int max, thresh = 1; /* always use a single PEBS record */ - void *buffer; + void *buffer, *ibuffer; if (!x86_pmu.pebs) return 0; @@ -228,6 +245,19 @@ static int alloc_pebs_buffer(int cpu) if (unlikely(!buffer)) return -ENOMEM; + /* + * HSW+ already provides us the eventing ip; no need to allocate this + * buffer then. + */ + if (x86_pmu.intel_cap.pebs_format < 2) { + ibuffer = kzalloc_node(PEBS_FIXUP_SIZE, GFP_KERNEL, node); + if (!ibuffer) { + kfree(buffer); + return -ENOMEM; + } + per_cpu(insn_buffer, cpu) = ibuffer; + } + max = PEBS_BUFFER_SIZE / x86_pmu.pebs_record_size; ds->pebs_buffer_base = (u64)(unsigned long)buffer; @@ -248,6 +278,9 @@ static void release_pebs_buffer(int cpu) if (!ds || !x86_pmu.pebs) return; + kfree(per_cpu(insn_buffer, cpu)); + per_cpu(insn_buffer, cpu) = NULL; + kfree((void *)(unsigned long)ds->pebs_buffer_base); ds->pebs_buffer_base = 0; } @@ -715,6 +748,7 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs) unsigned long old_to, to = cpuc->lbr_entries[0].to; unsigned long ip = regs->ip; int is_64bit = 0; + void *kaddr; /* * We don't need to fixup if the PEBS assist is fault like @@ -738,7 +772,7 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs) * unsigned math, either ip is before the start (impossible) or * the basic block is larger than 1 page (sanity) */ - if ((ip - to) > PAGE_SIZE) + if ((ip - to) > PEBS_FIXUP_SIZE) return 0; /* @@ -749,29 +783,33 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs) return 1; } + if (!kernel_ip(ip)) { + int size, bytes; + u8 *buf = this_cpu_read(insn_buffer); + + size = ip - to; /* Must fit our buffer, see above */ + bytes = copy_from_user_nmi(buf, (void __user *)to, size); + if (bytes != 0) + return 0; + + kaddr = buf; + } else { + kaddr = (void *)to; + } + do { struct insn insn; - u8 buf[MAX_INSN_SIZE]; - void *kaddr; old_to = to; - if (!kernel_ip(ip)) { - int bytes, size = MAX_INSN_SIZE; - - bytes = copy_from_user_nmi(buf, (void __user *)to, size); - if (bytes != size) - return 0; - - kaddr = buf; - } else - kaddr = (void *)to; #ifdef CONFIG_X86_64 is_64bit = kernel_ip(to) || !test_thread_flag(TIF_IA32); #endif insn_init(&insn, kaddr, is_64bit); insn_get_length(&insn); + to += insn.length; + kaddr += insn.length; } while (to < ip); if (to == ip) { @@ -786,16 +824,34 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs) return 0; } +static inline u64 intel_hsw_weight(struct pebs_record_hsw *pebs) +{ + if (pebs->tsx_tuning) { + union hsw_tsx_tuning tsx = { .value = pebs->tsx_tuning }; + return tsx.cycles_last_block; + } + return 0; +} + +static inline u64 intel_hsw_transaction(struct pebs_record_hsw *pebs) +{ + u64 txn = (pebs->tsx_tuning & PEBS_HSW_TSX_FLAGS) >> 32; + + /* For RTM XABORTs also log the abort code from AX */ + if ((txn & PERF_TXN_TRANSACTION) && (pebs->ax & 1)) + txn |= ((pebs->ax >> 24) & 0xff) << PERF_TXN_ABORT_SHIFT; + return txn; +} + static void __intel_pmu_pebs_event(struct perf_event *event, struct pt_regs *iregs, void *__pebs) { /* - * We cast to pebs_record_nhm to get the load latency data - * if extra_reg MSR_PEBS_LD_LAT_THRESHOLD used + * We cast to the biggest pebs_record but are careful not to + * unconditionally access the 'extra' entries. */ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); - struct pebs_record_nhm *pebs = __pebs; - struct pebs_record_hsw *pebs_hsw = __pebs; + struct pebs_record_hsw *pebs = __pebs; struct perf_sample_data data; struct pt_regs regs; u64 sample_type; @@ -854,7 +910,7 @@ static void __intel_pmu_pebs_event(struct perf_event *event, regs.sp = pebs->sp; if (event->attr.precise_ip > 1 && x86_pmu.intel_cap.pebs_format >= 2) { - regs.ip = pebs_hsw->real_ip; + regs.ip = pebs->real_ip; regs.flags |= PERF_EFLAGS_EXACT; } else if (event->attr.precise_ip > 1 && intel_pmu_pebs_fixup_ip(®s)) regs.flags |= PERF_EFLAGS_EXACT; @@ -862,9 +918,18 @@ static void __intel_pmu_pebs_event(struct perf_event *event, regs.flags &= ~PERF_EFLAGS_EXACT; if ((event->attr.sample_type & PERF_SAMPLE_ADDR) && - x86_pmu.intel_cap.pebs_format >= 1) + x86_pmu.intel_cap.pebs_format >= 1) data.addr = pebs->dla; + if (x86_pmu.intel_cap.pebs_format >= 2) { + /* Only set the TSX weight when no memory weight. */ + if ((event->attr.sample_type & PERF_SAMPLE_WEIGHT) && !fll) + data.weight = intel_hsw_weight(pebs); + + if (event->attr.sample_type & PERF_SAMPLE_TRANSACTION) + data.txn = intel_hsw_transaction(pebs); + } + if (has_branch_stack(event)) data.br_stack = &cpuc->lbr_stack; @@ -913,17 +978,34 @@ static void intel_pmu_drain_pebs_core(struct pt_regs *iregs) __intel_pmu_pebs_event(event, iregs, at); } -static void __intel_pmu_drain_pebs_nhm(struct pt_regs *iregs, void *at, - void *top) +static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs) { struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); struct debug_store *ds = cpuc->ds; struct perf_event *event = NULL; + void *at, *top; u64 status = 0; int bit; + if (!x86_pmu.pebs_active) + return; + + at = (struct pebs_record_nhm *)(unsigned long)ds->pebs_buffer_base; + top = (struct pebs_record_nhm *)(unsigned long)ds->pebs_index; + ds->pebs_index = ds->pebs_buffer_base; + if (unlikely(at > top)) + return; + + /* + * Should not happen, we program the threshold at 1 and do not + * set a reset value. + */ + WARN_ONCE(top - at > x86_pmu.max_pebs_events * x86_pmu.pebs_record_size, + "Unexpected number of pebs records %ld\n", + (long)(top - at) / x86_pmu.pebs_record_size); + for (; at < top; at += x86_pmu.pebs_record_size) { struct pebs_record_nhm *p = at; @@ -951,61 +1033,6 @@ static void __intel_pmu_drain_pebs_nhm(struct pt_regs *iregs, void *at, } } -static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs) -{ - struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); - struct debug_store *ds = cpuc->ds; - struct pebs_record_nhm *at, *top; - int n; - - if (!x86_pmu.pebs_active) - return; - - at = (struct pebs_record_nhm *)(unsigned long)ds->pebs_buffer_base; - top = (struct pebs_record_nhm *)(unsigned long)ds->pebs_index; - - ds->pebs_index = ds->pebs_buffer_base; - - n = top - at; - if (n <= 0) - return; - - /* - * Should not happen, we program the threshold at 1 and do not - * set a reset value. - */ - WARN_ONCE(n > x86_pmu.max_pebs_events, - "Unexpected number of pebs records %d\n", n); - - return __intel_pmu_drain_pebs_nhm(iregs, at, top); -} - -static void intel_pmu_drain_pebs_hsw(struct pt_regs *iregs) -{ - struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); - struct debug_store *ds = cpuc->ds; - struct pebs_record_hsw *at, *top; - int n; - - if (!x86_pmu.pebs_active) - return; - - at = (struct pebs_record_hsw *)(unsigned long)ds->pebs_buffer_base; - top = (struct pebs_record_hsw *)(unsigned long)ds->pebs_index; - - n = top - at; - if (n <= 0) - return; - /* - * Should not happen, we program the threshold at 1 and do not - * set a reset value. - */ - WARN_ONCE(n > x86_pmu.max_pebs_events, - "Unexpected number of pebs records %d\n", n); - - return __intel_pmu_drain_pebs_nhm(iregs, at, top); -} - /* * BTS, PEBS probe and setup */ @@ -1040,7 +1067,7 @@ void intel_ds_init(void) case 2: pr_cont("PEBS fmt2%c, ", pebs_type); x86_pmu.pebs_record_size = sizeof(struct pebs_record_hsw); - x86_pmu.drain_pebs = intel_pmu_drain_pebs_hsw; + x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm; break; default: diff --git a/arch/x86/kernel/cpu/perf_event_intel_lbr.c b/arch/x86/kernel/cpu/perf_event_intel_lbr.c index d5be06a5005e..d82d155aca8c 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_lbr.c +++ b/arch/x86/kernel/cpu/perf_event_intel_lbr.c @@ -284,6 +284,7 @@ static void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc) int lbr_format = x86_pmu.intel_cap.lbr_format; u64 tos = intel_pmu_lbr_tos(); int i; + int out = 0; for (i = 0; i < x86_pmu.lbr_nr; i++) { unsigned long lbr_idx = (tos - i) & mask; @@ -306,15 +307,27 @@ static void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc) } from = (u64)((((s64)from) << skip) >> skip); - cpuc->lbr_entries[i].from = from; - cpuc->lbr_entries[i].to = to; - cpuc->lbr_entries[i].mispred = mis; - cpuc->lbr_entries[i].predicted = pred; - cpuc->lbr_entries[i].in_tx = in_tx; - cpuc->lbr_entries[i].abort = abort; - cpuc->lbr_entries[i].reserved = 0; + /* + * Some CPUs report duplicated abort records, + * with the second entry not having an abort bit set. + * Skip them here. This loop runs backwards, + * so we need to undo the previous record. + * If the abort just happened outside the window + * the extra entry cannot be removed. + */ + if (abort && x86_pmu.lbr_double_abort && out > 0) + out--; + + cpuc->lbr_entries[out].from = from; + cpuc->lbr_entries[out].to = to; + cpuc->lbr_entries[out].mispred = mis; + cpuc->lbr_entries[out].predicted = pred; + cpuc->lbr_entries[out].in_tx = in_tx; + cpuc->lbr_entries[out].abort = abort; + cpuc->lbr_entries[out].reserved = 0; + out++; } - cpuc->lbr_stack.nr = i; + cpuc->lbr_stack.nr = out; } void intel_pmu_lbr_read(void) @@ -478,7 +491,7 @@ static int branch_type(unsigned long from, unsigned long to, int abort) /* may fail if text not present */ bytes = copy_from_user_nmi(buf, (void __user *)from, size); - if (bytes != size) + if (bytes != 0) return X86_BR_NONE; addr = buf; diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c index 4118f9f68315..29c248799ced 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c @@ -997,6 +997,20 @@ static int snbep_pci2phy_map_init(int devid) } } + if (!err) { + /* + * For PCI bus with no UBOX device, find the next bus + * that has UBOX device and use its mapping. + */ + i = -1; + for (bus = 255; bus >= 0; bus--) { + if (pcibus_to_physid[bus] >= 0) + i = pcibus_to_physid[bus]; + else + pcibus_to_physid[bus] = i; + } + } + if (ubox_dev) pci_dev_put(ubox_dev); @@ -1099,6 +1113,24 @@ static struct attribute *ivt_uncore_qpi_formats_attr[] = { &format_attr_umask.attr, &format_attr_edge.attr, &format_attr_thresh8.attr, + &format_attr_match_rds.attr, + &format_attr_match_rnid30.attr, + &format_attr_match_rnid4.attr, + &format_attr_match_dnid.attr, + &format_attr_match_mc.attr, + &format_attr_match_opc.attr, + &format_attr_match_vnw.attr, + &format_attr_match0.attr, + &format_attr_match1.attr, + &format_attr_mask_rds.attr, + &format_attr_mask_rnid30.attr, + &format_attr_mask_rnid4.attr, + &format_attr_mask_dnid.attr, + &format_attr_mask_mc.attr, + &format_attr_mask_opc.attr, + &format_attr_mask_vnw.attr, + &format_attr_mask0.attr, + &format_attr_mask1.attr, NULL, }; @@ -1312,17 +1344,83 @@ static struct intel_uncore_type ivt_uncore_imc = { IVT_UNCORE_PCI_COMMON_INIT(), }; +/* registers in IRP boxes are not properly aligned */ +static unsigned ivt_uncore_irp_ctls[] = {0xd8, 0xdc, 0xe0, 0xe4}; +static unsigned ivt_uncore_irp_ctrs[] = {0xa0, 0xb0, 0xb8, 0xc0}; + +static void ivt_uncore_irp_enable_event(struct intel_uncore_box *box, struct perf_event *event) +{ + struct pci_dev *pdev = box->pci_dev; + struct hw_perf_event *hwc = &event->hw; + + pci_write_config_dword(pdev, ivt_uncore_irp_ctls[hwc->idx], + hwc->config | SNBEP_PMON_CTL_EN); +} + +static void ivt_uncore_irp_disable_event(struct intel_uncore_box *box, struct perf_event *event) +{ + struct pci_dev *pdev = box->pci_dev; + struct hw_perf_event *hwc = &event->hw; + + pci_write_config_dword(pdev, ivt_uncore_irp_ctls[hwc->idx], hwc->config); +} + +static u64 ivt_uncore_irp_read_counter(struct intel_uncore_box *box, struct perf_event *event) +{ + struct pci_dev *pdev = box->pci_dev; + struct hw_perf_event *hwc = &event->hw; + u64 count = 0; + + pci_read_config_dword(pdev, ivt_uncore_irp_ctrs[hwc->idx], (u32 *)&count); + pci_read_config_dword(pdev, ivt_uncore_irp_ctrs[hwc->idx] + 4, (u32 *)&count + 1); + + return count; +} + +static struct intel_uncore_ops ivt_uncore_irp_ops = { + .init_box = ivt_uncore_pci_init_box, + .disable_box = snbep_uncore_pci_disable_box, + .enable_box = snbep_uncore_pci_enable_box, + .disable_event = ivt_uncore_irp_disable_event, + .enable_event = ivt_uncore_irp_enable_event, + .read_counter = ivt_uncore_irp_read_counter, +}; + +static struct intel_uncore_type ivt_uncore_irp = { + .name = "irp", + .num_counters = 4, + .num_boxes = 1, + .perf_ctr_bits = 48, + .event_mask = IVT_PMON_RAW_EVENT_MASK, + .box_ctl = SNBEP_PCI_PMON_BOX_CTL, + .ops = &ivt_uncore_irp_ops, + .format_group = &ivt_uncore_format_group, +}; + +static struct intel_uncore_ops ivt_uncore_qpi_ops = { + .init_box = ivt_uncore_pci_init_box, + .disable_box = snbep_uncore_pci_disable_box, + .enable_box = snbep_uncore_pci_enable_box, + .disable_event = snbep_uncore_pci_disable_event, + .enable_event = snbep_qpi_enable_event, + .read_counter = snbep_uncore_pci_read_counter, + .hw_config = snbep_qpi_hw_config, + .get_constraint = uncore_get_constraint, + .put_constraint = uncore_put_constraint, +}; + static struct intel_uncore_type ivt_uncore_qpi = { - .name = "qpi", - .num_counters = 4, - .num_boxes = 3, - .perf_ctr_bits = 48, - .perf_ctr = SNBEP_PCI_PMON_CTR0, - .event_ctl = SNBEP_PCI_PMON_CTL0, - .event_mask = IVT_QPI_PCI_PMON_RAW_EVENT_MASK, - .box_ctl = SNBEP_PCI_PMON_BOX_CTL, - .ops = &ivt_uncore_pci_ops, - .format_group = &ivt_uncore_qpi_format_group, + .name = "qpi", + .num_counters = 4, + .num_boxes = 3, + .perf_ctr_bits = 48, + .perf_ctr = SNBEP_PCI_PMON_CTR0, + .event_ctl = SNBEP_PCI_PMON_CTL0, + .event_mask = IVT_QPI_PCI_PMON_RAW_EVENT_MASK, + .box_ctl = SNBEP_PCI_PMON_BOX_CTL, + .num_shared_regs = 1, + .ops = &ivt_uncore_qpi_ops, + .format_group = &ivt_uncore_qpi_format_group, }; static struct intel_uncore_type ivt_uncore_r2pcie = { @@ -1346,6 +1444,7 @@ static struct intel_uncore_type ivt_uncore_r3qpi = { enum { IVT_PCI_UNCORE_HA, IVT_PCI_UNCORE_IMC, + IVT_PCI_UNCORE_IRP, IVT_PCI_UNCORE_QPI, IVT_PCI_UNCORE_R2PCIE, IVT_PCI_UNCORE_R3QPI, @@ -1354,6 +1453,7 @@ enum { static struct intel_uncore_type *ivt_pci_uncores[] = { [IVT_PCI_UNCORE_HA] = &ivt_uncore_ha, [IVT_PCI_UNCORE_IMC] = &ivt_uncore_imc, + [IVT_PCI_UNCORE_IRP] = &ivt_uncore_irp, [IVT_PCI_UNCORE_QPI] = &ivt_uncore_qpi, [IVT_PCI_UNCORE_R2PCIE] = &ivt_uncore_r2pcie, [IVT_PCI_UNCORE_R3QPI] = &ivt_uncore_r3qpi, @@ -1401,6 +1501,10 @@ static DEFINE_PCI_DEVICE_TABLE(ivt_uncore_pci_ids) = { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef1), .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 7), }, + { /* IRP */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe39), + .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IRP, 0), + }, { /* QPI0 Port 0 */ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe32), .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_QPI, 0), @@ -1429,6 +1533,16 @@ static DEFINE_PCI_DEVICE_TABLE(ivt_uncore_pci_ids) = { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe3e), .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_R3QPI, 2), }, + { /* QPI Port 0 filter */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe86), + .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV, + SNBEP_PCI_QPI_PORT0_FILTER), + }, + { /* QPI Port 0 filter */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe96), + .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV, + SNBEP_PCI_QPI_PORT1_FILTER), + }, { /* end: all zeroes */ } }; diff --git a/arch/x86/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c index aee6317b902f..06fe3ed8b851 100644 --- a/arch/x86/kernel/cpu/proc.c +++ b/arch/x86/kernel/cpu/proc.c @@ -11,15 +11,12 @@ static void show_cpuinfo_core(struct seq_file *m, struct cpuinfo_x86 *c, unsigned int cpu) { #ifdef CONFIG_SMP - if (c->x86_max_cores * smp_num_siblings > 1) { - seq_printf(m, "physical id\t: %d\n", c->phys_proc_id); - seq_printf(m, "siblings\t: %d\n", - cpumask_weight(cpu_core_mask(cpu))); - seq_printf(m, "core id\t\t: %d\n", c->cpu_core_id); - seq_printf(m, "cpu cores\t: %d\n", c->booted_cores); - seq_printf(m, "apicid\t\t: %d\n", c->apicid); - seq_printf(m, "initial apicid\t: %d\n", c->initial_apicid); - } + seq_printf(m, "physical id\t: %d\n", c->phys_proc_id); + seq_printf(m, "siblings\t: %d\n", cpumask_weight(cpu_core_mask(cpu))); + seq_printf(m, "core id\t\t: %d\n", c->cpu_core_id); + seq_printf(m, "cpu cores\t: %d\n", c->booted_cores); + seq_printf(m, "apicid\t\t: %d\n", c->apicid); + seq_printf(m, "initial apicid\t: %d\n", c->initial_apicid); #endif } diff --git a/arch/x86/kernel/cpu/scattered.c b/arch/x86/kernel/cpu/scattered.c index f2cc63e9cf08..b6f794aa1693 100644 --- a/arch/x86/kernel/cpu/scattered.c +++ b/arch/x86/kernel/cpu/scattered.c @@ -1,5 +1,5 @@ /* - * Routines to indentify additional cpu features that are scattered in + * Routines to identify additional cpu features that are scattered in * cpuid space. */ #include <linux/cpu.h> diff --git a/arch/x86/kernel/cpu/umc.c b/arch/x86/kernel/cpu/umc.c index 202759a14121..75c5ad5d35cc 100644 --- a/arch/x86/kernel/cpu/umc.c +++ b/arch/x86/kernel/cpu/umc.c @@ -11,8 +11,8 @@ static const struct cpu_dev umc_cpu_dev = { .c_vendor = "UMC", .c_ident = { "UMC UMC UMC" }, - .c_models = { - { .vendor = X86_VENDOR_UMC, .family = 4, .model_names = + .legacy_models = { + { .family = 4, .model_names = { [1] = "U5D", [2] = "U5S", diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c index e0e0841eef45..18677a90d6a3 100644 --- a/arch/x86/kernel/crash.c +++ b/arch/x86/kernel/crash.c @@ -127,12 +127,12 @@ void native_machine_crash_shutdown(struct pt_regs *regs) cpu_emergency_vmxoff(); cpu_emergency_svm_disable(); - lapic_shutdown(); #ifdef CONFIG_X86_IO_APIC /* Prevent crash_kexec() from deadlocking on ioapic_lock. */ ioapic_zap_locks(); disable_IO_APIC(); #endif + lapic_shutdown(); #ifdef CONFIG_HPET_TIMER hpet_disable(); #endif diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c index 376dc7873447..d35078ea1446 100644 --- a/arch/x86/kernel/devicetree.c +++ b/arch/x86/kernel/devicetree.c @@ -20,22 +20,13 @@ #include <asm/hpet.h> #include <asm/apic.h> #include <asm/pci_x86.h> +#include <asm/setup.h> __initdata u64 initial_dtb; char __initdata cmd_line[COMMAND_LINE_SIZE]; int __initdata of_ioapic; -unsigned long pci_address_to_pio(phys_addr_t address) -{ - /* - * The ioport address can be directly used by inX / outX - */ - BUG_ON(address >= (1 << 16)); - return (unsigned long)address; -} -EXPORT_SYMBOL_GPL(pci_address_to_pio); - void __init early_init_dt_scan_chosen_arch(unsigned long node) { BUG(); @@ -51,15 +42,6 @@ void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) return __alloc_bootmem(size, align, __pa(MAX_DMA_ADDRESS)); } -#ifdef CONFIG_BLK_DEV_INITRD -void __init early_init_dt_setup_initrd_arch(u64 start, u64 end) -{ - initrd_start = (unsigned long)__va(start); - initrd_end = (unsigned long)__va(end); - initrd_below_start_ok = 1; -} -#endif - void __init add_dtb(u64 data) { initial_dtb = data + offsetof(struct setup_data, data); @@ -105,7 +87,6 @@ struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus) static int x86_of_pci_irq_enable(struct pci_dev *dev) { - struct of_irq oirq; u32 virq; int ret; u8 pin; @@ -116,12 +97,7 @@ static int x86_of_pci_irq_enable(struct pci_dev *dev) if (!pin) return 0; - ret = of_irq_map_pci(dev, &oirq); - if (ret) - return ret; - - virq = irq_create_of_mapping(oirq.controller, oirq.specifier, - oirq.size); + virq = of_irq_parse_and_map_pci(dev, 0, 0); if (virq == 0) return -EINVAL; dev->irq = virq; @@ -230,7 +206,7 @@ static void __init dtb_apic_setup(void) static void __init x86_flattree_get_config(void) { u32 size, map_len; - void *new_dtb; + struct boot_param_header *dt; if (!initial_dtb) return; @@ -238,24 +214,17 @@ static void __init x86_flattree_get_config(void) map_len = max(PAGE_SIZE - (initial_dtb & ~PAGE_MASK), (u64)sizeof(struct boot_param_header)); - initial_boot_params = early_memremap(initial_dtb, map_len); - size = be32_to_cpu(initial_boot_params->totalsize); + dt = early_memremap(initial_dtb, map_len); + size = be32_to_cpu(dt->totalsize); if (map_len < size) { - early_iounmap(initial_boot_params, map_len); - initial_boot_params = early_memremap(initial_dtb, size); + early_iounmap(dt, map_len); + dt = early_memremap(initial_dtb, size); map_len = size; } - new_dtb = alloc_bootmem(size); - memcpy(new_dtb, initial_boot_params, size); - early_iounmap(initial_boot_params, map_len); - - initial_boot_params = new_dtb; - - /* root level address cells */ - of_scan_flat_dt(early_init_dt_scan_root, NULL); - - unflatten_device_tree(); + initial_boot_params = dt; + unflatten_and_copy_device_tree(); + early_iounmap(dt, map_len); } #else static inline void x86_flattree_get_config(void) { } diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c index deb6421c9e69..d9c12d3022a7 100644 --- a/arch/x86/kernel/dumpstack.c +++ b/arch/x86/kernel/dumpstack.c @@ -25,12 +25,17 @@ unsigned int code_bytes = 64; int kstack_depth_to_print = 3 * STACKSLOTS_PER_LINE; static int die_counter; -void printk_address(unsigned long address, int reliable) +static void printk_stack_address(unsigned long address, int reliable) { pr_cont(" [<%p>] %s%pB\n", (void *)address, reliable ? "" : "? ", (void *)address); } +void printk_address(unsigned long address) +{ + pr_cont(" [<%p>] %pS\n", (void *)address, (void *)address); +} + #ifdef CONFIG_FUNCTION_GRAPH_TRACER static void print_ftrace_graph_addr(unsigned long addr, void *data, @@ -151,7 +156,7 @@ static void print_trace_address(void *data, unsigned long addr, int reliable) { touch_nmi_watchdog(); printk(data); - printk_address(addr, reliable); + printk_stack_address(addr, reliable); } static const struct stacktrace_ops print_trace_ops = { @@ -281,7 +286,7 @@ int __kprobes __die(const char *str, struct pt_regs *regs, long err) #else /* Executive summary in case the oops scrolled away */ printk(KERN_ALERT "RIP "); - printk_address(regs->ip, 1); + printk_address(regs->ip); printk(" RSP <%016lx>\n", regs->sp); #endif return 0; diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c index b3cd3ebae077..96f958d8cd45 100644 --- a/arch/x86/kernel/early-quirks.c +++ b/arch/x86/kernel/early-quirks.c @@ -313,6 +313,16 @@ static size_t __init gen6_stolen_size(int num, int slot, int func) return gmch_ctrl << 25; /* 32 MB units */ } +static inline size_t gen8_stolen_size(int num, int slot, int func) +{ + u16 gmch_ctrl; + + gmch_ctrl = read_pci_config_16(num, slot, func, SNB_GMCH_CTRL); + gmch_ctrl >>= BDW_GMCH_GMS_SHIFT; + gmch_ctrl &= BDW_GMCH_GMS_MASK; + return gmch_ctrl << 25; /* 32 MB units */ +} + typedef size_t (*stolen_size_fn)(int num, int slot, int func); static struct pci_device_id intel_stolen_ids[] __initdata = { @@ -336,6 +346,8 @@ static struct pci_device_id intel_stolen_ids[] __initdata = { INTEL_IVB_D_IDS(gen6_stolen_size), INTEL_HSW_D_IDS(gen6_stolen_size), INTEL_HSW_M_IDS(gen6_stolen_size), + INTEL_BDW_M_IDS(gen8_stolen_size), + INTEL_BDW_D_IDS(gen8_stolen_size) }; static void __init intel_graphics_stolen(int num, int slot, int func) diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c index d15f575a861b..01d1c187c9f9 100644 --- a/arch/x86/kernel/early_printk.c +++ b/arch/x86/kernel/early_printk.c @@ -14,9 +14,11 @@ #include <xen/hvc-console.h> #include <asm/pci-direct.h> #include <asm/fixmap.h> -#include <asm/mrst.h> +#include <asm/intel-mid.h> #include <asm/pgtable.h> #include <linux/usb/ehci_def.h> +#include <linux/efi.h> +#include <asm/efi.h> /* Simple VGA output */ #define VGABASE (__ISA_IO_base + 0xb8000) @@ -234,6 +236,11 @@ static int __init setup_early_printk(char *buf) early_console_register(&early_hsu_console, keep); } #endif +#ifdef CONFIG_EARLY_PRINTK_EFI + if (!strncmp(buf, "efi", 3)) + early_console_register(&early_efi_console, keep); +#endif + buf++; } return 0; diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index f0dcb0ceb6a2..51e2988c5728 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S @@ -362,12 +362,9 @@ END(ret_from_exception) #ifdef CONFIG_PREEMPT ENTRY(resume_kernel) DISABLE_INTERRUPTS(CLBR_ANY) - cmpl $0,TI_preempt_count(%ebp) # non-zero preempt_count ? - jnz restore_all need_resched: - movl TI_flags(%ebp), %ecx # need_resched set ? - testb $_TIF_NEED_RESCHED, %cl - jz restore_all + cmpl $0,PER_CPU_VAR(__preempt_count) + jnz restore_all testl $X86_EFLAGS_IF,PT_EFLAGS(%esp) # interrupts off (exception path) ? jz restore_all call preempt_schedule_irq @@ -1247,6 +1244,16 @@ return_to_handler: */ .pushsection .kprobes.text, "ax" +#ifdef CONFIG_TRACING +ENTRY(trace_page_fault) + RING0_EC_FRAME + ASM_CLAC + pushl_cfi $trace_do_page_fault + jmp error_code + CFI_ENDPROC +END(trace_page_fault) +#endif + ENTRY(page_fault) RING0_EC_FRAME ASM_CLAC diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index b077f4cc225a..e21b0785a85b 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -1103,10 +1103,8 @@ retint_signal: /* Returning to kernel space. Check if we need preemption */ /* rcx: threadinfo. interrupts off. */ ENTRY(retint_kernel) - cmpl $0,TI_preempt_count(%rcx) + cmpl $0,PER_CPU_VAR(__preempt_count) jnz retint_restore_args - bt $TIF_NEED_RESCHED,TI_flags(%rcx) - jnc retint_restore_args bt $9,EFLAGS-ARGOFFSET(%rsp) /* interrupts off? */ jnc retint_restore_args call preempt_schedule_irq @@ -1280,6 +1278,17 @@ ENTRY(\sym) END(\sym) .endm +#ifdef CONFIG_TRACING +.macro trace_errorentry sym do_sym +errorentry trace(\sym) trace(\do_sym) +errorentry \sym \do_sym +.endm +#else +.macro trace_errorentry sym do_sym +errorentry \sym \do_sym +.endm +#endif + /* error code is on the stack already */ .macro paranoiderrorentry sym do_sym ENTRY(\sym) @@ -1342,7 +1351,7 @@ bad_gs: .previous /* Call softirq on interrupt stack. Interrupts are off. */ -ENTRY(call_softirq) +ENTRY(do_softirq_own_stack) CFI_STARTPROC pushq_cfi %rbp CFI_REL_OFFSET rbp,0 @@ -1359,7 +1368,7 @@ ENTRY(call_softirq) decl PER_CPU_VAR(irq_count) ret CFI_ENDPROC -END(call_softirq) +END(do_softirq_own_stack) #ifdef CONFIG_XEN zeroentry xen_hypervisor_callback xen_do_hypervisor_callback @@ -1482,7 +1491,7 @@ zeroentry xen_int3 do_int3 errorentry xen_stack_segment do_stack_segment #endif errorentry general_protection do_general_protection -errorentry page_fault do_page_fault +trace_errorentry page_fault do_page_fault #ifdef CONFIG_KVM_GUEST errorentry async_page_fault do_async_page_fault #endif diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index 42a392a9fd02..d4bdd253fea7 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c @@ -248,6 +248,15 @@ int ftrace_update_ftrace_func(ftrace_func_t func) return ret; } +static int is_ftrace_caller(unsigned long ip) +{ + if (ip == (unsigned long)(&ftrace_call) || + ip == (unsigned long)(&ftrace_regs_call)) + return 1; + + return 0; +} + /* * A breakpoint was added to the code address we are about to * modify, and this is the handle that will just skip over it. @@ -257,10 +266,13 @@ int ftrace_update_ftrace_func(ftrace_func_t func) */ int ftrace_int3_handler(struct pt_regs *regs) { + unsigned long ip; + if (WARN_ON_ONCE(!regs)) return 0; - if (!ftrace_location(regs->ip - 1)) + ip = regs->ip - 1; + if (!ftrace_location(ip) && !is_ftrace_caller(ip)) return 0; regs->ip += MCOUNT_INSN_SIZE - 1; diff --git a/arch/x86/kernel/head32.c b/arch/x86/kernel/head32.c index 06f87bece92a..c61a14a4a310 100644 --- a/arch/x86/kernel/head32.c +++ b/arch/x86/kernel/head32.c @@ -35,8 +35,8 @@ asmlinkage void __init i386_start_kernel(void) /* Call the subarch specific early setup function */ switch (boot_params.hdr.hardware_subarch) { - case X86_SUBARCH_MRST: - x86_mrst_early_setup(); + case X86_SUBARCH_INTEL_MID: + x86_intel_mid_early_setup(); break; case X86_SUBARCH_CE4100: x86_ce4100_early_setup(); diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index 1be8e43b669e..85126ccbdf6b 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c @@ -162,7 +162,7 @@ asmlinkage void __init x86_64_start_kernel(char * real_mode_data) clear_bss(); for (i = 0; i < NUM_EXCEPTION_VECTORS; i++) - set_intr_gate(i, &early_idt_handlers[i]); + set_intr_gate(i, early_idt_handlers[i]); load_idt((const struct desc_ptr *)&idt_descr); copy_bootdata(__va(real_mode_data)); diff --git a/arch/x86/kernel/i386_ksyms_32.c b/arch/x86/kernel/i386_ksyms_32.c index 0fa69127209a..05fd74f537d6 100644 --- a/arch/x86/kernel/i386_ksyms_32.c +++ b/arch/x86/kernel/i386_ksyms_32.c @@ -37,3 +37,10 @@ EXPORT_SYMBOL(strstr); EXPORT_SYMBOL(csum_partial); EXPORT_SYMBOL(empty_zero_page); + +#ifdef CONFIG_PREEMPT +EXPORT_SYMBOL(___preempt_schedule); +#ifdef CONFIG_CONTEXT_TRACKING +EXPORT_SYMBOL(___preempt_schedule_context); +#endif +#endif diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c index 5d576ab34403..e8368c6dd2a2 100644 --- a/arch/x86/kernel/i387.c +++ b/arch/x86/kernel/i387.c @@ -100,7 +100,7 @@ void unlazy_fpu(struct task_struct *tsk) __save_init_fpu(tsk); __thread_fpu_end(tsk); } else - tsk->fpu_counter = 0; + tsk->thread.fpu_counter = 0; preempt_enable(); } EXPORT_SYMBOL(unlazy_fpu); diff --git a/arch/x86/kernel/i8259.c b/arch/x86/kernel/i8259.c index 9a5c460404dc..2e977b5d61dd 100644 --- a/arch/x86/kernel/i8259.c +++ b/arch/x86/kernel/i8259.c @@ -312,8 +312,7 @@ static void init_8259A(int auto_eoi) */ outb_pic(0x11, PIC_MASTER_CMD); /* ICW1: select 8259A-1 init */ - /* ICW2: 8259A-1 IR0-7 mapped to 0x30-0x37 on x86-64, - to 0x20-0x27 on i386 */ + /* ICW2: 8259A-1 IR0-7 mapped to 0x30-0x37 */ outb_pic(IRQ0_VECTOR, PIC_MASTER_IMR); /* 8259A-1 (the master) has a slave on IR2 */ diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c index 4186755f1d7c..d7fcbedc9c43 100644 --- a/arch/x86/kernel/irq_32.c +++ b/arch/x86/kernel/irq_32.c @@ -100,9 +100,6 @@ execute_on_irq_stack(int overflow, struct irq_desc *desc, int irq) irqctx->tinfo.task = curctx->tinfo.task; irqctx->tinfo.previous_esp = current_stack_pointer; - /* Copy the preempt_count so that the [soft]irq checks work. */ - irqctx->tinfo.preempt_count = curctx->tinfo.preempt_count; - if (unlikely(overflow)) call_on_stack(print_stack_overflow, isp); @@ -131,7 +128,6 @@ void irq_ctx_init(int cpu) THREAD_SIZE_ORDER)); memset(&irqctx->tinfo, 0, sizeof(struct thread_info)); irqctx->tinfo.cpu = cpu; - irqctx->tinfo.preempt_count = HARDIRQ_OFFSET; irqctx->tinfo.addr_limit = MAKE_MM_SEG(0); per_cpu(hardirq_ctx, cpu) = irqctx; @@ -149,35 +145,21 @@ void irq_ctx_init(int cpu) cpu, per_cpu(hardirq_ctx, cpu), per_cpu(softirq_ctx, cpu)); } -asmlinkage void do_softirq(void) +void do_softirq_own_stack(void) { - unsigned long flags; struct thread_info *curctx; union irq_ctx *irqctx; u32 *isp; - if (in_interrupt()) - return; - - local_irq_save(flags); - - if (local_softirq_pending()) { - curctx = current_thread_info(); - irqctx = __this_cpu_read(softirq_ctx); - irqctx->tinfo.task = curctx->task; - irqctx->tinfo.previous_esp = current_stack_pointer; - - /* build the stack frame on the softirq stack */ - isp = (u32 *) ((char *)irqctx + sizeof(*irqctx)); + curctx = current_thread_info(); + irqctx = __this_cpu_read(softirq_ctx); + irqctx->tinfo.task = curctx->task; + irqctx->tinfo.previous_esp = current_stack_pointer; - call_on_stack(__do_softirq, isp); - /* - * Shouldn't happen, we returned above if in_interrupt(): - */ - WARN_ON_ONCE(softirq_count()); - } + /* build the stack frame on the softirq stack */ + isp = (u32 *) ((char *)irqctx + sizeof(*irqctx)); - local_irq_restore(flags); + call_on_stack(__do_softirq, isp); } bool handle_irq(unsigned irq, struct pt_regs *regs) diff --git a/arch/x86/kernel/irq_64.c b/arch/x86/kernel/irq_64.c index d04d3ecded62..4d1c746892eb 100644 --- a/arch/x86/kernel/irq_64.c +++ b/arch/x86/kernel/irq_64.c @@ -87,24 +87,3 @@ bool handle_irq(unsigned irq, struct pt_regs *regs) generic_handle_irq_desc(irq, desc); return true; } - - -extern void call_softirq(void); - -asmlinkage void do_softirq(void) -{ - __u32 pending; - unsigned long flags; - - if (in_interrupt()) - return; - - local_irq_save(flags); - pending = local_softirq_pending(); - /* Switch to interrupt stack */ - if (pending) { - call_softirq(); - WARN_ON_ONCE(softirq_count()); - } - local_irq_restore(flags); -} diff --git a/arch/x86/kernel/jump_label.c b/arch/x86/kernel/jump_label.c index ee11b7dfbfbb..26d5a55a2736 100644 --- a/arch/x86/kernel/jump_label.c +++ b/arch/x86/kernel/jump_label.c @@ -42,15 +42,27 @@ static void __jump_label_transform(struct jump_entry *entry, int init) { union jump_code_union code; + const unsigned char default_nop[] = { STATIC_KEY_INIT_NOP }; const unsigned char *ideal_nop = ideal_nops[NOP_ATOMIC5]; if (type == JUMP_LABEL_ENABLE) { - /* - * We are enabling this jump label. If it is not a nop - * then something must have gone wrong. - */ - if (unlikely(memcmp((void *)entry->code, ideal_nop, 5) != 0)) - bug_at((void *)entry->code, __LINE__); + if (init) { + /* + * Jump label is enabled for the first time. + * So we expect a default_nop... + */ + if (unlikely(memcmp((void *)entry->code, default_nop, 5) + != 0)) + bug_at((void *)entry->code, __LINE__); + } else { + /* + * ...otherwise expect an ideal_nop. Otherwise + * something went horribly wrong. + */ + if (unlikely(memcmp((void *)entry->code, ideal_nop, 5) + != 0)) + bug_at((void *)entry->code, __LINE__); + } code.jump = 0xe9; code.offset = entry->target - @@ -63,7 +75,6 @@ static void __jump_label_transform(struct jump_entry *entry, * are converting the default nop to the ideal nop. */ if (init) { - const unsigned char default_nop[] = { STATIC_KEY_INIT_NOP }; if (unlikely(memcmp((void *)entry->code, default_nop, 5) != 0)) bug_at((void *)entry->code, __LINE__); } else { diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index a0e2a8a80c94..6dd802c6d780 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c @@ -464,7 +464,7 @@ static struct notifier_block kvm_cpu_notifier = { static void __init kvm_apf_trap_init(void) { - set_intr_gate(14, &async_page_fault); + set_intr_gate(14, async_page_fault); } void __init kvm_guest_init(void) @@ -609,7 +609,7 @@ static struct dentry *d_kvm_debug; struct dentry *kvm_init_debugfs(void) { - d_kvm_debug = debugfs_create_dir("kvm", NULL); + d_kvm_debug = debugfs_create_dir("kvm-guest", NULL); if (!d_kvm_debug) printk(KERN_WARNING "Could not create 'kvm' debugfs directory\n"); diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c index 1570e0741344..e6041094ff26 100644 --- a/arch/x86/kernel/kvmclock.c +++ b/arch/x86/kernel/kvmclock.c @@ -139,6 +139,7 @@ bool kvm_check_and_clear_guest_paused(void) src = &hv_clock[cpu].pvti; if ((src->flags & PVCLOCK_GUEST_STOPPED) != 0) { src->flags &= ~PVCLOCK_GUEST_STOPPED; + pvclock_touch_watchdogs(); ret = true; } diff --git a/arch/x86/kernel/microcode_amd.c b/arch/x86/kernel/microcode_amd.c index af99f71aeb7f..c3d4cc972eca 100644 --- a/arch/x86/kernel/microcode_amd.c +++ b/arch/x86/kernel/microcode_amd.c @@ -431,7 +431,7 @@ static enum ucode_state request_microcode_amd(int cpu, struct device *device, snprintf(fw_name, sizeof(fw_name), "amd-ucode/microcode_amd_fam%.2xh.bin", c->x86); if (request_firmware(&fw, (const char *)fw_name, device)) { - pr_err("failed to load file %s\n", fw_name); + pr_debug("failed to load file %s\n", fw_name); goto out; } diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c index 216a4d754b0c..18be189368bb 100644 --- a/arch/x86/kernel/module.c +++ b/arch/x86/kernel/module.c @@ -49,7 +49,7 @@ void *module_alloc(unsigned long size) return NULL; return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC, - -1, __builtin_return_address(0)); + NUMA_NO_NODE, __builtin_return_address(0)); } #ifdef CONFIG_X86_32 diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c index 88458faea2f8..05266b5aae22 100644 --- a/arch/x86/kernel/msr.c +++ b/arch/x86/kernel/msr.c @@ -46,7 +46,7 @@ static struct class *msr_class; static loff_t msr_seek(struct file *file, loff_t offset, int orig) { loff_t ret; - struct inode *inode = file->f_mapping->host; + struct inode *inode = file_inode(file); mutex_lock(&inode->i_mutex); switch (orig) { diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c index ba77ebc2c353..6fcb49ce50a1 100644 --- a/arch/x86/kernel/nmi.c +++ b/arch/x86/kernel/nmi.c @@ -113,10 +113,10 @@ static int __kprobes nmi_handle(unsigned int type, struct pt_regs *regs, bool b2 u64 before, delta, whole_msecs; int remainder_ns, decimal_msecs, thishandled; - before = local_clock(); + before = sched_clock(); thishandled = a->handler(type, regs); handled += thishandled; - delta = local_clock() - before; + delta = sched_clock() - before; trace_nmi_handler(a->handler, (int)delta, thishandled); if (delta < nmi_longest_ns) diff --git a/arch/x86/kernel/preempt.S b/arch/x86/kernel/preempt.S new file mode 100644 index 000000000000..ca7f0d58a87d --- /dev/null +++ b/arch/x86/kernel/preempt.S @@ -0,0 +1,25 @@ + +#include <linux/linkage.h> +#include <asm/dwarf2.h> +#include <asm/asm.h> +#include <asm/calling.h> + +ENTRY(___preempt_schedule) + CFI_STARTPROC + SAVE_ALL + call preempt_schedule + RESTORE_ALL + ret + CFI_ENDPROC + +#ifdef CONFIG_CONTEXT_TRACKING + +ENTRY(___preempt_schedule_context) + CFI_STARTPROC + SAVE_ALL + call preempt_schedule_context + RESTORE_ALL + ret + CFI_ENDPROC + +#endif diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index c83516be1052..3fb8d95ab8b5 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -391,9 +391,9 @@ static void amd_e400_idle(void) * The switch back from broadcast mode needs to be * called with interrupts disabled. */ - local_irq_disable(); - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu); - local_irq_enable(); + local_irq_disable(); + clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu); + local_irq_enable(); } else default_idle(); } diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index 884f98f69354..6f1236c29c4b 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c @@ -153,7 +153,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, childregs->orig_ax = -1; childregs->cs = __KERNEL_CS | get_kernel_rpl(); childregs->flags = X86_EFLAGS_IF | X86_EFLAGS_FIXED; - p->fpu_counter = 0; + p->thread.fpu_counter = 0; p->thread.io_bitmap_ptr = NULL; memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps)); return 0; @@ -166,7 +166,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, p->thread.ip = (unsigned long) ret_from_fork; task_user_gs(p) = get_user_gs(current_pt_regs()); - p->fpu_counter = 0; + p->thread.fpu_counter = 0; p->thread.io_bitmap_ptr = NULL; tsk = current; err = -ENOMEM; @@ -292,6 +292,14 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) set_iopl_mask(next->iopl); /* + * If it were not for PREEMPT_ACTIVE we could guarantee that the + * preempt_count of all tasks was equal here and this would not be + * needed. + */ + task_thread_info(prev_p)->saved_preempt_count = this_cpu_read(__preempt_count); + this_cpu_write(__preempt_count, task_thread_info(next_p)->saved_preempt_count); + + /* * Now maybe handle debug registers and/or IO bitmaps */ if (unlikely(task_thread_info(prev_p)->flags & _TIF_WORK_CTXSW_PREV || diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index bb1dc51bab05..9c0280f93d05 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -63,7 +63,7 @@ void __show_regs(struct pt_regs *regs, int all) unsigned int ds, cs, es; printk(KERN_DEFAULT "RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->ip); - printk_address(regs->ip, 1); + printk_address(regs->ip); printk(KERN_DEFAULT "RSP: %04lx:%016lx EFLAGS: %08lx\n", regs->ss, regs->sp, regs->flags); printk(KERN_DEFAULT "RAX: %016lx RBX: %016lx RCX: %016lx\n", @@ -163,7 +163,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, p->thread.sp = (unsigned long) childregs; p->thread.usersp = me->thread.usersp; set_tsk_thread_flag(p, TIF_FORK); - p->fpu_counter = 0; + p->thread.fpu_counter = 0; p->thread.io_bitmap_ptr = NULL; savesegment(gs, p->thread.gsindex); @@ -363,6 +363,14 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) this_cpu_write(old_rsp, next->usersp); this_cpu_write(current_task, next_p); + /* + * If it were not for PREEMPT_ACTIVE we could guarantee that the + * preempt_count of all tasks was equal here and this would not be + * needed. + */ + task_thread_info(prev_p)->saved_preempt_count = this_cpu_read(__preempt_count); + this_cpu_write(__preempt_count, task_thread_info(next_p)->saved_preempt_count); + this_cpu_write(kernel_stack, (unsigned long)task_stack_page(next_p) + THREAD_SIZE - KERNEL_STACK_OFFSET); diff --git a/arch/x86/kernel/pvclock.c b/arch/x86/kernel/pvclock.c index a16bae3f83b3..2f355d229a58 100644 --- a/arch/x86/kernel/pvclock.c +++ b/arch/x86/kernel/pvclock.c @@ -43,6 +43,14 @@ unsigned long pvclock_tsc_khz(struct pvclock_vcpu_time_info *src) return pv_tsc_khz; } +void pvclock_touch_watchdogs(void) +{ + touch_softlockup_watchdog_sync(); + clocksource_touch_watchdog(); + rcu_cpu_stall_reset(); + reset_hung_task_detector(); +} + static atomic64_t last_value = ATOMIC64_INIT(0); void pvclock_resume(void) @@ -74,6 +82,11 @@ cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src) version = __pvclock_read_cycles(src, &ret, &flags); } while ((src->version & 1) || version != src->version); + if (unlikely((flags & PVCLOCK_GUEST_STOPPED) != 0)) { + src->flags &= ~PVCLOCK_GUEST_STOPPED; + pvclock_touch_watchdogs(); + } + if ((valid_flags & PVCLOCK_TSC_STABLE_BIT) && (flags & PVCLOCK_TSC_STABLE_BIT)) return ret; diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index 7e920bff99a3..da3c599584a3 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c @@ -61,7 +61,7 @@ static int __init set_bios_reboot(const struct dmi_system_id *d) if (reboot_type != BOOT_BIOS) { reboot_type = BOOT_BIOS; pr_info("%s series board detected. Selecting %s-method for reboots.\n", - "BIOS", d->ident); + d->ident, "BIOS"); } return 0; } @@ -117,7 +117,7 @@ static int __init set_pci_reboot(const struct dmi_system_id *d) if (reboot_type != BOOT_CF9) { reboot_type = BOOT_CF9; pr_info("%s series board detected. Selecting %s-method for reboots.\n", - "PCI", d->ident); + d->ident, "PCI"); } return 0; } @@ -127,7 +127,7 @@ static int __init set_kbd_reboot(const struct dmi_system_id *d) if (reboot_type != BOOT_KBD) { reboot_type = BOOT_KBD; pr_info("%s series board detected. Selecting %s-method for reboot.\n", - "KBD", d->ident); + d->ident, "KBD"); } return 0; } @@ -136,252 +136,256 @@ static int __init set_kbd_reboot(const struct dmi_system_id *d) * This is a single dmi_table handling all reboot quirks. */ static struct dmi_system_id __initdata reboot_dmi_table[] = { - { /* Handle problems with rebooting on Dell E520's */ - .callback = set_bios_reboot, - .ident = "Dell E520", + + /* Acer */ + { /* Handle reboot issue on Acer Aspire one */ + .callback = set_kbd_reboot, + .ident = "Acer Aspire One A110", .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Dell DM061"), + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "AOA110"), }, }, - { /* Handle problems with rebooting on Dell 1300's */ - .callback = set_bios_reboot, - .ident = "Dell PowerEdge 1300", + + /* Apple */ + { /* Handle problems with rebooting on Apple MacBook5 */ + .callback = set_pci_reboot, + .ident = "Apple MacBook5", .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), - DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1300/"), + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5"), }, }, - { /* Handle problems with rebooting on Dell 300's */ - .callback = set_bios_reboot, - .ident = "Dell PowerEdge 300", + { /* Handle problems with rebooting on Apple MacBookPro5 */ + .callback = set_pci_reboot, + .ident = "Apple MacBookPro5", .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), - DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 300/"), + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5"), }, }, - { /* Handle problems with rebooting on Dell Optiplex 745's SFF */ - .callback = set_bios_reboot, - .ident = "Dell OptiPlex 745", + { /* Handle problems with rebooting on Apple Macmini3,1 */ + .callback = set_pci_reboot, + .ident = "Apple Macmini3,1", .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 745"), + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Macmini3,1"), }, }, - { /* Handle problems with rebooting on Dell Optiplex 745's DFF */ - .callback = set_bios_reboot, - .ident = "Dell OptiPlex 745", + { /* Handle problems with rebooting on the iMac9,1. */ + .callback = set_pci_reboot, + .ident = "Apple iMac9,1", .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 745"), - DMI_MATCH(DMI_BOARD_NAME, "0MM599"), + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "iMac9,1"), }, }, - { /* Handle problems with rebooting on Dell Optiplex 745 with 0KW626 */ + + /* ASUS */ + { /* Handle problems with rebooting on ASUS P4S800 */ .callback = set_bios_reboot, - .ident = "Dell OptiPlex 745", + .ident = "ASUS P4S800", .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 745"), - DMI_MATCH(DMI_BOARD_NAME, "0KW626"), + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), + DMI_MATCH(DMI_BOARD_NAME, "P4S800"), }, }, - { /* Handle problems with rebooting on Dell Optiplex 330 with 0KP561 */ + + /* Dell */ + { /* Handle problems with rebooting on Dell DXP061 */ .callback = set_bios_reboot, - .ident = "Dell OptiPlex 330", + .ident = "Dell DXP061", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 330"), - DMI_MATCH(DMI_BOARD_NAME, "0KP561"), + DMI_MATCH(DMI_PRODUCT_NAME, "Dell DXP061"), }, }, - { /* Handle problems with rebooting on Dell Optiplex 360 with 0T656F */ + { /* Handle problems with rebooting on Dell E520's */ .callback = set_bios_reboot, - .ident = "Dell OptiPlex 360", + .ident = "Dell E520", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 360"), - DMI_MATCH(DMI_BOARD_NAME, "0T656F"), + DMI_MATCH(DMI_PRODUCT_NAME, "Dell DM061"), }, }, - { /* Handle problems with rebooting on Dell OptiPlex 760 with 0G919G */ - .callback = set_bios_reboot, - .ident = "Dell OptiPlex 760", + { /* Handle problems with rebooting on the Latitude E5410. */ + .callback = set_pci_reboot, + .ident = "Dell Latitude E5410", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 760"), - DMI_MATCH(DMI_BOARD_NAME, "0G919G"), + DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E5410"), }, }, - { /* Handle problems with rebooting on Dell 2400's */ - .callback = set_bios_reboot, - .ident = "Dell PowerEdge 2400", + { /* Handle problems with rebooting on the Latitude E5420. */ + .callback = set_pci_reboot, + .ident = "Dell Latitude E5420", .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), - DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2400"), + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E5420"), }, }, - { /* Handle problems with rebooting on Dell T5400's */ - .callback = set_bios_reboot, - .ident = "Dell Precision T5400", + { /* Handle problems with rebooting on the Latitude E6320. */ + .callback = set_pci_reboot, + .ident = "Dell Latitude E6320", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Precision WorkStation T5400"), + DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E6320"), }, }, - { /* Handle problems with rebooting on Dell T7400's */ - .callback = set_bios_reboot, - .ident = "Dell Precision T7400", + { /* Handle problems with rebooting on the Latitude E6420. */ + .callback = set_pci_reboot, + .ident = "Dell Latitude E6420", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Precision WorkStation T7400"), + DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E6420"), }, }, - { /* Handle problems with rebooting on HP laptops */ + { /* Handle problems with rebooting on Dell Optiplex 330 with 0KP561 */ .callback = set_bios_reboot, - .ident = "HP Compaq Laptop", + .ident = "Dell OptiPlex 330", .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq"), + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 330"), + DMI_MATCH(DMI_BOARD_NAME, "0KP561"), }, }, - { /* Handle problems with rebooting on Dell XPS710 */ + { /* Handle problems with rebooting on Dell Optiplex 360 with 0T656F */ .callback = set_bios_reboot, - .ident = "Dell XPS710", + .ident = "Dell OptiPlex 360", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Dell XPS710"), + DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 360"), + DMI_MATCH(DMI_BOARD_NAME, "0T656F"), }, }, - { /* Handle problems with rebooting on Dell DXP061 */ + { /* Handle problems with rebooting on Dell Optiplex 745's SFF */ .callback = set_bios_reboot, - .ident = "Dell DXP061", + .ident = "Dell OptiPlex 745", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Dell DXP061"), + DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 745"), }, }, - { /* Handle problems with rebooting on Sony VGN-Z540N */ + { /* Handle problems with rebooting on Dell Optiplex 745's DFF */ .callback = set_bios_reboot, - .ident = "Sony VGN-Z540N", + .ident = "Dell OptiPlex 745", .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), - DMI_MATCH(DMI_PRODUCT_NAME, "VGN-Z540N"), + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 745"), + DMI_MATCH(DMI_BOARD_NAME, "0MM599"), }, }, - { /* Handle problems with rebooting on ASUS P4S800 */ + { /* Handle problems with rebooting on Dell Optiplex 745 with 0KW626 */ .callback = set_bios_reboot, - .ident = "ASUS P4S800", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), - DMI_MATCH(DMI_BOARD_NAME, "P4S800"), - }, - }, - - { /* Handle reboot issue on Acer Aspire one */ - .callback = set_kbd_reboot, - .ident = "Acer Aspire One A110", + .ident = "Dell OptiPlex 745", .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "AOA110"), + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 745"), + DMI_MATCH(DMI_BOARD_NAME, "0KW626"), }, }, - { /* Handle problems with rebooting on Apple MacBook5 */ - .callback = set_pci_reboot, - .ident = "Apple MacBook5", + { /* Handle problems with rebooting on Dell OptiPlex 760 with 0G919G */ + .callback = set_bios_reboot, + .ident = "Dell OptiPlex 760", .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5"), + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 760"), + DMI_MATCH(DMI_BOARD_NAME, "0G919G"), }, }, - { /* Handle problems with rebooting on Apple MacBookPro5 */ + { /* Handle problems with rebooting on the OptiPlex 990. */ .callback = set_pci_reboot, - .ident = "Apple MacBookPro5", + .ident = "Dell OptiPlex 990", .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5"), + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 990"), }, }, - { /* Handle problems with rebooting on Apple Macmini3,1 */ - .callback = set_pci_reboot, - .ident = "Apple Macmini3,1", + { /* Handle problems with rebooting on Dell 300's */ + .callback = set_bios_reboot, + .ident = "Dell PowerEdge 300", .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Macmini3,1"), + DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 300/"), }, }, - { /* Handle problems with rebooting on the iMac9,1. */ - .callback = set_pci_reboot, - .ident = "Apple iMac9,1", + { /* Handle problems with rebooting on Dell 1300's */ + .callback = set_bios_reboot, + .ident = "Dell PowerEdge 1300", .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "iMac9,1"), + DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1300/"), }, }, - { /* Handle problems with rebooting on the Latitude E6320. */ - .callback = set_pci_reboot, - .ident = "Dell Latitude E6320", + { /* Handle problems with rebooting on Dell 2400's */ + .callback = set_bios_reboot, + .ident = "Dell PowerEdge 2400", .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E6320"), + DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2400"), }, }, - { /* Handle problems with rebooting on the Latitude E5410. */ + { /* Handle problems with rebooting on the Dell PowerEdge C6100. */ .callback = set_pci_reboot, - .ident = "Dell Latitude E5410", + .ident = "Dell PowerEdge C6100", .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E5410"), + DMI_MATCH(DMI_SYS_VENDOR, "Dell"), + DMI_MATCH(DMI_PRODUCT_NAME, "C6100"), }, }, - { /* Handle problems with rebooting on the Latitude E5420. */ + { /* Handle problems with rebooting on the Precision M6600. */ .callback = set_pci_reboot, - .ident = "Dell Latitude E5420", + .ident = "Dell Precision M6600", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E5420"), + DMI_MATCH(DMI_PRODUCT_NAME, "Precision M6600"), }, }, - { /* Handle problems with rebooting on the Latitude E6420. */ - .callback = set_pci_reboot, - .ident = "Dell Latitude E6420", + { /* Handle problems with rebooting on Dell T5400's */ + .callback = set_bios_reboot, + .ident = "Dell Precision T5400", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E6420"), + DMI_MATCH(DMI_PRODUCT_NAME, "Precision WorkStation T5400"), }, }, - { /* Handle problems with rebooting on the OptiPlex 990. */ - .callback = set_pci_reboot, - .ident = "Dell OptiPlex 990", + { /* Handle problems with rebooting on Dell T7400's */ + .callback = set_bios_reboot, + .ident = "Dell Precision T7400", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 990"), + DMI_MATCH(DMI_PRODUCT_NAME, "Precision WorkStation T7400"), }, }, - { /* Handle problems with rebooting on the Precision M6600. */ - .callback = set_pci_reboot, - .ident = "Dell Precision M6600", + { /* Handle problems with rebooting on Dell XPS710 */ + .callback = set_bios_reboot, + .ident = "Dell XPS710", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Precision M6600"), + DMI_MATCH(DMI_PRODUCT_NAME, "Dell XPS710"), }, }, - { /* Handle problems with rebooting on the Dell PowerEdge C6100. */ - .callback = set_pci_reboot, - .ident = "Dell PowerEdge C6100", + + /* Hewlett-Packard */ + { /* Handle problems with rebooting on HP laptops */ + .callback = set_bios_reboot, + .ident = "HP Compaq Laptop", .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "C6100"), + DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq"), }, }, - { /* Some C6100 machines were shipped with vendor being 'Dell'. */ - .callback = set_pci_reboot, - .ident = "Dell PowerEdge C6100", + + /* Sony */ + { /* Handle problems with rebooting on Sony VGN-Z540N */ + .callback = set_bios_reboot, + .ident = "Sony VGN-Z540N", .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell"), - DMI_MATCH(DMI_PRODUCT_NAME, "C6100"), + DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "VGN-Z540N"), }, }, + { } }; @@ -535,10 +539,13 @@ static void native_machine_emergency_restart(void) case BOOT_CF9_COND: if (port_cf9_safe) { - u8 cf9 = inb(0xcf9) & ~6; + u8 reboot_code = reboot_mode == REBOOT_WARM ? + 0x06 : 0x0E; + u8 cf9 = inb(0xcf9) & ~reboot_code; outb(cf9|2, 0xcf9); /* Request hard reset */ udelay(50); - outb(cf9|6, 0xcf9); /* Actually do the reset */ + /* Actually do the reset */ + outb(cf9|reboot_code, 0xcf9); udelay(50); } reboot_type = BOOT_KBD; @@ -550,6 +557,10 @@ static void native_machine_emergency_restart(void) void native_machine_shutdown(void) { /* Stop the cpus and apics */ +#ifdef CONFIG_X86_IO_APIC + disable_IO_APIC(); +#endif + #ifdef CONFIG_SMP /* * Stop all of the others. Also disable the local irq to @@ -562,10 +573,6 @@ void native_machine_shutdown(void) lapic_shutdown(); -#ifdef CONFIG_X86_IO_APIC - disable_IO_APIC(); -#endif - #ifdef CONFIG_HPET_TIMER hpet_disable(); #endif diff --git a/arch/x86/kernel/rtc.c b/arch/x86/kernel/rtc.c index 0aa29394ed6f..ca9622a25e95 100644 --- a/arch/x86/kernel/rtc.c +++ b/arch/x86/kernel/rtc.c @@ -12,7 +12,7 @@ #include <asm/vsyscall.h> #include <asm/x86_init.h> #include <asm/time.h> -#include <asm/mrst.h> +#include <asm/intel-mid.h> #include <asm/rtc.h> #ifdef CONFIG_X86_32 @@ -189,9 +189,17 @@ static __init int add_rtc_cmos(void) return 0; /* Intel MID platforms don't have ioport rtc */ - if (mrst_identify_cpu()) + if (intel_mid_identify_cpu()) return -ENODEV; +#ifdef CONFIG_ACPI + if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_CMOS_RTC) { + /* This warning can likely go away again in a year or two. */ + pr_info("ACPI: not registering RTC platform device\n"); + return -ENODEV; + } +#endif + platform_device_register(&rtc_device); dev_info(&rtc_device.dev, "registered platform RTC device (no PNP device found)\n"); diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index f0de6294b955..cb233bc9dee3 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -993,6 +993,7 @@ void __init setup_arch(char **cmdline_p) efi_init(); dmi_scan_machine(); + dmi_memdev_walk(); dmi_set_dump_stack_arch_desc(); /* @@ -1120,8 +1121,6 @@ void __init setup_arch(char **cmdline_p) acpi_initrd_override((void *)initrd_start, initrd_end - initrd_start); #endif - reserve_crashkernel(); - vsmp_init(); io_delay_init(); @@ -1134,6 +1133,13 @@ void __init setup_arch(char **cmdline_p) early_acpi_boot_init(); initmem_init(); + + /* + * Reserve memory for crash kernel after SRAT is parsed so that it + * won't consume hotpluggable memory. + */ + reserve_crashkernel(); + memblock_find_dma_reserve(); #ifdef CONFIG_KVM_GUEST diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 6cacab671f9b..85dc05a3aa02 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -73,36 +73,14 @@ #include <asm/setup.h> #include <asm/uv/uv.h> #include <linux/mc146818rtc.h> - #include <asm/smpboot_hooks.h> #include <asm/i8259.h> - #include <asm/realmode.h> +#include <asm/misc.h> /* State of each CPU */ DEFINE_PER_CPU(int, cpu_state) = { 0 }; -#ifdef CONFIG_HOTPLUG_CPU -/* - * We need this for trampoline_base protection from concurrent accesses when - * off- and onlining cores wildly. - */ -static DEFINE_MUTEX(x86_cpu_hotplug_driver_mutex); - -void cpu_hotplug_driver_lock(void) -{ - mutex_lock(&x86_cpu_hotplug_driver_mutex); -} - -void cpu_hotplug_driver_unlock(void) -{ - mutex_unlock(&x86_cpu_hotplug_driver_mutex); -} - -ssize_t arch_cpu_probe(const char *buf, size_t count) { return -1; } -ssize_t arch_cpu_release(const char *buf, size_t count) { return -1; } -#endif - /* Number of siblings per CPU package */ int smp_num_siblings = 1; EXPORT_SYMBOL(smp_num_siblings); @@ -648,22 +626,46 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip) return (send_status | accept_status); } +void smp_announce(void) +{ + int num_nodes = num_online_nodes(); + + printk(KERN_INFO "x86: Booted up %d node%s, %d CPUs\n", + num_nodes, (num_nodes > 1 ? "s" : ""), num_online_cpus()); +} + /* reduce the number of lines printed when booting a large cpu count system */ static void announce_cpu(int cpu, int apicid) { static int current_node = -1; int node = early_cpu_to_node(cpu); - int max_cpu_present = find_last_bit(cpumask_bits(cpu_present_mask), NR_CPUS); + static int width, node_width; + + if (!width) + width = num_digits(num_possible_cpus()) + 1; /* + '#' sign */ + + if (!node_width) + node_width = num_digits(num_possible_nodes()) + 1; /* + '#' */ + + if (cpu == 1) + printk(KERN_INFO "x86: Booting SMP configuration:\n"); if (system_state == SYSTEM_BOOTING) { if (node != current_node) { if (current_node > (-1)) - pr_cont(" OK\n"); + pr_cont("\n"); current_node = node; - pr_info("Booting Node %3d, Processors ", node); + + printk(KERN_INFO ".... node %*s#%d, CPUs: ", + node_width - num_digits(node), " ", node); } - pr_cont(" #%4d%s", cpu, cpu == max_cpu_present ? " OK\n" : ""); - return; + + /* Add padding for the BSP */ + if (cpu == 1) + pr_cont("%*s", width + 1, " "); + + pr_cont("%*s#%d", width - num_digits(cpu), " ", cpu); + } else pr_info("Booting Node %d Processor %d APIC 0x%x\n", node, cpu, apicid); diff --git a/arch/x86/kernel/topology.c b/arch/x86/kernel/topology.c index 6e60b5fe2244..649b010da00b 100644 --- a/arch/x86/kernel/topology.c +++ b/arch/x86/kernel/topology.c @@ -65,29 +65,32 @@ int __ref _debug_hotplug_cpu(int cpu, int action) if (!cpu_is_hotpluggable(cpu)) return -EINVAL; - cpu_hotplug_driver_lock(); + lock_device_hotplug(); switch (action) { case 0: ret = cpu_down(cpu); if (!ret) { pr_info("CPU %u is now offline\n", cpu); + dev->offline = true; kobject_uevent(&dev->kobj, KOBJ_OFFLINE); } else pr_debug("Can't offline CPU%d.\n", cpu); break; case 1: ret = cpu_up(cpu); - if (!ret) + if (!ret) { + dev->offline = false; kobject_uevent(&dev->kobj, KOBJ_ONLINE); - else + } else { pr_debug("Can't online CPU%d.\n", cpu); + } break; default: ret = -EINVAL; } - cpu_hotplug_driver_unlock(); + unlock_device_hotplug(); return ret; } diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 8c8093b146ca..b857ed890b4c 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -88,7 +88,7 @@ static inline void conditional_sti(struct pt_regs *regs) static inline void preempt_conditional_sti(struct pt_regs *regs) { - inc_preempt_count(); + preempt_count_inc(); if (regs->flags & X86_EFLAGS_IF) local_irq_enable(); } @@ -103,7 +103,7 @@ static inline void preempt_conditional_cli(struct pt_regs *regs) { if (regs->flags & X86_EFLAGS_IF) local_irq_disable(); - dec_preempt_count(); + preempt_count_dec(); } static int __kprobes @@ -653,7 +653,7 @@ void math_state_restore(void) return; } - tsk->fpu_counter++; + tsk->thread.fpu_counter++; } EXPORT_SYMBOL_GPL(math_state_restore); @@ -713,7 +713,7 @@ void __init early_trap_init(void) /* int3 can be called from all */ set_system_intr_gate_ist(X86_TRAP_BP, &int3, DEBUG_STACK); #ifdef CONFIG_X86_32 - set_intr_gate(X86_TRAP_PF, &page_fault); + set_intr_gate(X86_TRAP_PF, page_fault); #endif load_idt(&idt_descr); } @@ -721,7 +721,7 @@ void __init early_trap_init(void) void __init early_trap_pf_init(void) { #ifdef CONFIG_X86_64 - set_intr_gate(X86_TRAP_PF, &page_fault); + set_intr_gate(X86_TRAP_PF, page_fault); #endif } @@ -737,30 +737,30 @@ void __init trap_init(void) early_iounmap(p, 4); #endif - set_intr_gate(X86_TRAP_DE, ÷_error); + set_intr_gate(X86_TRAP_DE, divide_error); set_intr_gate_ist(X86_TRAP_NMI, &nmi, NMI_STACK); /* int4 can be called from all */ set_system_intr_gate(X86_TRAP_OF, &overflow); - set_intr_gate(X86_TRAP_BR, &bounds); - set_intr_gate(X86_TRAP_UD, &invalid_op); - set_intr_gate(X86_TRAP_NM, &device_not_available); + set_intr_gate(X86_TRAP_BR, bounds); + set_intr_gate(X86_TRAP_UD, invalid_op); + set_intr_gate(X86_TRAP_NM, device_not_available); #ifdef CONFIG_X86_32 set_task_gate(X86_TRAP_DF, GDT_ENTRY_DOUBLEFAULT_TSS); #else set_intr_gate_ist(X86_TRAP_DF, &double_fault, DOUBLEFAULT_STACK); #endif - set_intr_gate(X86_TRAP_OLD_MF, &coprocessor_segment_overrun); - set_intr_gate(X86_TRAP_TS, &invalid_TSS); - set_intr_gate(X86_TRAP_NP, &segment_not_present); + set_intr_gate(X86_TRAP_OLD_MF, coprocessor_segment_overrun); + set_intr_gate(X86_TRAP_TS, invalid_TSS); + set_intr_gate(X86_TRAP_NP, segment_not_present); set_intr_gate_ist(X86_TRAP_SS, &stack_segment, STACKFAULT_STACK); - set_intr_gate(X86_TRAP_GP, &general_protection); - set_intr_gate(X86_TRAP_SPURIOUS, &spurious_interrupt_bug); - set_intr_gate(X86_TRAP_MF, &coprocessor_error); - set_intr_gate(X86_TRAP_AC, &alignment_check); + set_intr_gate(X86_TRAP_GP, general_protection); + set_intr_gate(X86_TRAP_SPURIOUS, spurious_interrupt_bug); + set_intr_gate(X86_TRAP_MF, coprocessor_error); + set_intr_gate(X86_TRAP_AC, alignment_check); #ifdef CONFIG_X86_MCE set_intr_gate_ist(X86_TRAP_MC, &machine_check, MCE_STACK); #endif - set_intr_gate(X86_TRAP_XF, &simd_coprocessor_error); + set_intr_gate(X86_TRAP_XF, simd_coprocessor_error); /* Reserve all the builtin and the syscall vector: */ for (i = 0; i < FIRST_EXTERNAL_VECTOR; i++) diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S index 10c4f3006afd..da6b35a98260 100644 --- a/arch/x86/kernel/vmlinux.lds.S +++ b/arch/x86/kernel/vmlinux.lds.S @@ -199,6 +199,15 @@ SECTIONS __x86_cpu_dev_end = .; } +#ifdef CONFIG_X86_INTEL_MID + .x86_intel_mid_dev.init : AT(ADDR(.x86_intel_mid_dev.init) - \ + LOAD_OFFSET) { + __x86_intel_mid_dev_start = .; + *(.x86_intel_mid_dev.init) + __x86_intel_mid_dev_end = .; + } +#endif + /* * start address and size of operations which during runtime * can be patched with virtualization friendly instructions or diff --git a/arch/x86/kernel/x8664_ksyms_64.c b/arch/x86/kernel/x8664_ksyms_64.c index b014d9414d08..040681928e9d 100644 --- a/arch/x86/kernel/x8664_ksyms_64.c +++ b/arch/x86/kernel/x8664_ksyms_64.c @@ -66,3 +66,10 @@ EXPORT_SYMBOL(empty_zero_page); #ifndef CONFIG_PARAVIRT EXPORT_SYMBOL(native_load_gs_index); #endif + +#ifdef CONFIG_PREEMPT +EXPORT_SYMBOL(___preempt_schedule); +#ifdef CONFIG_CONTEXT_TRACKING +EXPORT_SYMBOL(___preempt_schedule_context); +#endif +#endif diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c index 8ce0072cd700..021783b1f46a 100644 --- a/arch/x86/kernel/x86_init.c +++ b/arch/x86/kernel/x86_init.c @@ -116,6 +116,8 @@ struct x86_msi_ops x86_msi = { .teardown_msi_irqs = default_teardown_msi_irqs, .restore_msi_irqs = default_restore_msi_irqs, .setup_hpet_msi = default_setup_hpet_msi, + .msi_mask_irq = default_msi_mask_irq, + .msix_mask_irq = default_msix_mask_irq, }; /* MSI arch specific hooks */ @@ -138,6 +140,14 @@ void arch_restore_msi_irqs(struct pci_dev *dev, int irq) { x86_msi.restore_msi_irqs(dev, irq); } +u32 arch_msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag) +{ + return x86_msi.msi_mask_irq(desc, mask, flag); +} +u32 arch_msix_mask_irq(struct msi_desc *desc, u32 flag) +{ + return x86_msi.msix_mask_irq(desc, flag); +} #endif struct x86_io_apic_ops x86_io_apic_ops = { diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig index a47a3e54b964..b89c5db2b832 100644 --- a/arch/x86/kvm/Kconfig +++ b/arch/x86/kvm/Kconfig @@ -38,6 +38,7 @@ config KVM select PERF_EVENTS select HAVE_KVM_MSI select HAVE_KVM_CPU_RELAX_INTERCEPT + select KVM_VFIO ---help--- Support hosting fully virtualized guest machines using hardware virtualization extensions. You will need a fairly recent diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile index bf4fb04d0112..25d22b2d6509 100644 --- a/arch/x86/kvm/Makefile +++ b/arch/x86/kvm/Makefile @@ -9,7 +9,7 @@ KVM := ../../../virt/kvm kvm-y += $(KVM)/kvm_main.o $(KVM)/ioapic.o \ $(KVM)/coalesced_mmio.o $(KVM)/irq_comm.o \ - $(KVM)/eventfd.o $(KVM)/irqchip.o + $(KVM)/eventfd.o $(KVM)/irqchip.o $(KVM)/vfio.o kvm-$(CONFIG_KVM_DEVICE_ASSIGNMENT) += $(KVM)/assigned-dev.o $(KVM)/iommu.o kvm-$(CONFIG_KVM_ASYNC_PF) += $(KVM)/async_pf.o diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index b110fe6c03d4..c6976257eff5 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -23,6 +23,26 @@ #include "mmu.h" #include "trace.h" +static u32 xstate_required_size(u64 xstate_bv) +{ + int feature_bit = 0; + u32 ret = XSAVE_HDR_SIZE + XSAVE_HDR_OFFSET; + + xstate_bv &= ~XSTATE_FPSSE; + while (xstate_bv) { + if (xstate_bv & 0x1) { + u32 eax, ebx, ecx, edx; + cpuid_count(0xD, feature_bit, &eax, &ebx, &ecx, &edx); + ret = max(ret, eax + ebx); + } + + xstate_bv >>= 1; + feature_bit++; + } + + return ret; +} + void kvm_update_cpuid(struct kvm_vcpu *vcpu) { struct kvm_cpuid_entry2 *best; @@ -46,6 +66,18 @@ void kvm_update_cpuid(struct kvm_vcpu *vcpu) apic->lapic_timer.timer_mode_mask = 1 << 17; } + best = kvm_find_cpuid_entry(vcpu, 0xD, 0); + if (!best) { + vcpu->arch.guest_supported_xcr0 = 0; + vcpu->arch.guest_xstate_size = XSAVE_HDR_SIZE + XSAVE_HDR_OFFSET; + } else { + vcpu->arch.guest_supported_xcr0 = + (best->eax | ((u64)best->edx << 32)) & + host_xcr0 & KVM_SUPPORTED_XCR0; + vcpu->arch.guest_xstate_size = + xstate_required_size(vcpu->arch.guest_supported_xcr0); + } + kvm_pmu_cpuid_update(vcpu); } @@ -182,13 +214,35 @@ static bool supported_xcr0_bit(unsigned bit) { u64 mask = ((u64)1 << bit); - return mask & (XSTATE_FP | XSTATE_SSE | XSTATE_YMM) & host_xcr0; + return mask & KVM_SUPPORTED_XCR0 & host_xcr0; } #define F(x) bit(X86_FEATURE_##x) -static int do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, - u32 index, int *nent, int maxnent) +static int __do_cpuid_ent_emulated(struct kvm_cpuid_entry2 *entry, + u32 func, u32 index, int *nent, int maxnent) +{ + switch (func) { + case 0: + entry->eax = 1; /* only one leaf currently */ + ++*nent; + break; + case 1: + entry->ecx = F(MOVBE); + ++*nent; + break; + default: + break; + } + + entry->function = func; + entry->index = index; + + return 0; +} + +static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, + u32 index, int *nent, int maxnent) { int r; unsigned f_nx = is_efer_nx() ? F(NX) : 0; @@ -383,6 +437,8 @@ static int do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, case 0xd: { int idx, i; + entry->eax &= host_xcr0 & KVM_SUPPORTED_XCR0; + entry->edx &= (host_xcr0 & KVM_SUPPORTED_XCR0) >> 32; entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX; for (idx = 1, i = 1; idx < 64; ++idx) { if (*nent >= maxnent) @@ -481,6 +537,15 @@ out: return r; } +static int do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 func, + u32 idx, int *nent, int maxnent, unsigned int type) +{ + if (type == KVM_GET_EMULATED_CPUID) + return __do_cpuid_ent_emulated(entry, func, idx, nent, maxnent); + + return __do_cpuid_ent(entry, func, idx, nent, maxnent); +} + #undef F struct kvm_cpuid_param { @@ -495,8 +560,36 @@ static bool is_centaur_cpu(const struct kvm_cpuid_param *param) return boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR; } -int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid, - struct kvm_cpuid_entry2 __user *entries) +static bool sanity_check_entries(struct kvm_cpuid_entry2 __user *entries, + __u32 num_entries, unsigned int ioctl_type) +{ + int i; + __u32 pad[3]; + + if (ioctl_type != KVM_GET_EMULATED_CPUID) + return false; + + /* + * We want to make sure that ->padding is being passed clean from + * userspace in case we want to use it for something in the future. + * + * Sadly, this wasn't enforced for KVM_GET_SUPPORTED_CPUID and so we + * have to give ourselves satisfied only with the emulated side. /me + * sheds a tear. + */ + for (i = 0; i < num_entries; i++) { + if (copy_from_user(pad, entries[i].padding, sizeof(pad))) + return true; + + if (pad[0] || pad[1] || pad[2]) + return true; + } + return false; +} + +int kvm_dev_ioctl_get_cpuid(struct kvm_cpuid2 *cpuid, + struct kvm_cpuid_entry2 __user *entries, + unsigned int type) { struct kvm_cpuid_entry2 *cpuid_entries; int limit, nent = 0, r = -E2BIG, i; @@ -513,8 +606,12 @@ int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid, goto out; if (cpuid->nent > KVM_MAX_CPUID_ENTRIES) cpuid->nent = KVM_MAX_CPUID_ENTRIES; + + if (sanity_check_entries(entries, cpuid->nent, type)) + return -EINVAL; + r = -ENOMEM; - cpuid_entries = vmalloc(sizeof(struct kvm_cpuid_entry2) * cpuid->nent); + cpuid_entries = vzalloc(sizeof(struct kvm_cpuid_entry2) * cpuid->nent); if (!cpuid_entries) goto out; @@ -526,7 +623,7 @@ int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid, continue; r = do_cpuid_ent(&cpuid_entries[nent], ent->func, ent->idx, - &nent, cpuid->nent); + &nent, cpuid->nent, type); if (r) goto out_free; @@ -537,7 +634,7 @@ int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid, limit = cpuid_entries[nent - 1].eax; for (func = ent->func + 1; func <= limit && nent < cpuid->nent && r == 0; ++func) r = do_cpuid_ent(&cpuid_entries[nent], func, ent->idx, - &nent, cpuid->nent); + &nent, cpuid->nent, type); if (r) goto out_free; @@ -661,6 +758,7 @@ void kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx) *edx = best->edx; } else *eax = *ebx = *ecx = *edx = 0; + trace_kvm_cpuid(function, *eax, *ebx, *ecx, *edx); } EXPORT_SYMBOL_GPL(kvm_cpuid); @@ -676,6 +774,5 @@ void kvm_emulate_cpuid(struct kvm_vcpu *vcpu) kvm_register_write(vcpu, VCPU_REGS_RCX, ecx); kvm_register_write(vcpu, VCPU_REGS_RDX, edx); kvm_x86_ops->skip_emulated_instruction(vcpu); - trace_kvm_cpuid(function, eax, ebx, ecx, edx); } EXPORT_SYMBOL_GPL(kvm_emulate_cpuid); diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h index b7fd07984888..f1e4895174b2 100644 --- a/arch/x86/kvm/cpuid.h +++ b/arch/x86/kvm/cpuid.h @@ -6,8 +6,9 @@ void kvm_update_cpuid(struct kvm_vcpu *vcpu); struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu, u32 function, u32 index); -int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid, - struct kvm_cpuid_entry2 __user *entries); +int kvm_dev_ioctl_get_cpuid(struct kvm_cpuid2 *cpuid, + struct kvm_cpuid_entry2 __user *entries, + unsigned int type); int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid *cpuid, struct kvm_cpuid_entry __user *entries); diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index ddc3f3d2afdb..07ffca0a89e9 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -130,7 +130,7 @@ #define Mov (1<<20) /* Misc flags */ #define Prot (1<<21) /* instruction generates #UD if not in prot-mode */ -#define VendorSpecific (1<<22) /* Vendor specific instruction */ +#define EmulateOnUD (1<<22) /* Emulate if unsupported by the host */ #define NoAccess (1<<23) /* Don't access memory (lea/invlpg/verr etc) */ #define Op3264 (1<<24) /* Operand is 64b in long mode, 32b otherwise */ #define Undefined (1<<25) /* No Such Instruction */ @@ -785,9 +785,10 @@ static int do_insn_fetch(struct x86_emulate_ctxt *ctxt, * @highbyte_regs specifies whether to decode AH,CH,DH,BH. */ static void *decode_register(struct x86_emulate_ctxt *ctxt, u8 modrm_reg, - int highbyte_regs) + int byteop) { void *p; + int highbyte_regs = (ctxt->rex_prefix == 0) && byteop; if (highbyte_regs && modrm_reg >= 4 && modrm_reg < 8) p = (unsigned char *)reg_rmw(ctxt, modrm_reg & 3) + 1; @@ -1024,7 +1025,6 @@ static void decode_register_operand(struct x86_emulate_ctxt *ctxt, struct operand *op) { unsigned reg = ctxt->modrm_reg; - int highbyte_regs = ctxt->rex_prefix == 0; if (!(ctxt->d & ModRM)) reg = (ctxt->b & 7) | ((ctxt->rex_prefix & 1) << 3); @@ -1045,13 +1045,9 @@ static void decode_register_operand(struct x86_emulate_ctxt *ctxt, } op->type = OP_REG; - if (ctxt->d & ByteOp) { - op->addr.reg = decode_register(ctxt, reg, highbyte_regs); - op->bytes = 1; - } else { - op->addr.reg = decode_register(ctxt, reg, 0); - op->bytes = ctxt->op_bytes; - } + op->bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes; + op->addr.reg = decode_register(ctxt, reg, ctxt->d & ByteOp); + fetch_register_operand(op); op->orig_val = op->val; } @@ -1082,12 +1078,10 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt, ctxt->modrm_seg = VCPU_SREG_DS; if (ctxt->modrm_mod == 3) { - int highbyte_regs = ctxt->rex_prefix == 0; - op->type = OP_REG; op->bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes; op->addr.reg = decode_register(ctxt, ctxt->modrm_rm, - highbyte_regs && (ctxt->d & ByteOp)); + ctxt->d & ByteOp); if (ctxt->d & Sse) { op->type = OP_XMM; op->bytes = 16; @@ -2961,6 +2955,46 @@ static int em_mov(struct x86_emulate_ctxt *ctxt) return X86EMUL_CONTINUE; } +#define FFL(x) bit(X86_FEATURE_##x) + +static int em_movbe(struct x86_emulate_ctxt *ctxt) +{ + u32 ebx, ecx, edx, eax = 1; + u16 tmp; + + /* + * Check MOVBE is set in the guest-visible CPUID leaf. + */ + ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx); + if (!(ecx & FFL(MOVBE))) + return emulate_ud(ctxt); + + switch (ctxt->op_bytes) { + case 2: + /* + * From MOVBE definition: "...When the operand size is 16 bits, + * the upper word of the destination register remains unchanged + * ..." + * + * Both casting ->valptr and ->val to u16 breaks strict aliasing + * rules so we have to do the operation almost per hand. + */ + tmp = (u16)ctxt->src.val; + ctxt->dst.val &= ~0xffffUL; + ctxt->dst.val |= (unsigned long)swab16(tmp); + break; + case 4: + ctxt->dst.val = swab32((u32)ctxt->src.val); + break; + case 8: + ctxt->dst.val = swab64(ctxt->src.val); + break; + default: + return X86EMUL_PROPAGATE_FAULT; + } + return X86EMUL_CONTINUE; +} + static int em_cr_write(struct x86_emulate_ctxt *ctxt) { if (ctxt->ops->set_cr(ctxt, ctxt->modrm_reg, ctxt->src.val)) @@ -3256,6 +3290,18 @@ static int em_cpuid(struct x86_emulate_ctxt *ctxt) return X86EMUL_CONTINUE; } +static int em_sahf(struct x86_emulate_ctxt *ctxt) +{ + u32 flags; + + flags = EFLG_CF | EFLG_PF | EFLG_AF | EFLG_ZF | EFLG_SF; + flags &= *reg_rmw(ctxt, VCPU_REGS_RAX) >> 8; + + ctxt->eflags &= ~0xffUL; + ctxt->eflags |= flags | X86_EFLAGS_FIXED; + return X86EMUL_CONTINUE; +} + static int em_lahf(struct x86_emulate_ctxt *ctxt) { *reg_rmw(ctxt, VCPU_REGS_RAX) &= ~0xff00UL; @@ -3502,7 +3548,7 @@ static const struct opcode group7_rm1[] = { static const struct opcode group7_rm3[] = { DIP(SrcNone | Prot | Priv, vmrun, check_svme_pa), - II(SrcNone | Prot | VendorSpecific, em_vmmcall, vmmcall), + II(SrcNone | Prot | EmulateOnUD, em_vmmcall, vmmcall), DIP(SrcNone | Prot | Priv, vmload, check_svme_pa), DIP(SrcNone | Prot | Priv, vmsave, check_svme_pa), DIP(SrcNone | Prot | Priv, stgi, check_svme), @@ -3587,7 +3633,7 @@ static const struct group_dual group7 = { { II(SrcMem16 | Mov | Priv, em_lmsw, lmsw), II(SrcMem | ByteOp | Priv | NoAccess, em_invlpg, invlpg), }, { - I(SrcNone | Priv | VendorSpecific, em_vmcall), + I(SrcNone | Priv | EmulateOnUD, em_vmcall), EXT(0, group7_rm1), N, EXT(0, group7_rm3), II(SrcNone | DstMem | Mov, em_smsw, smsw), N, @@ -3750,7 +3796,8 @@ static const struct opcode opcode_table[256] = { D(DstAcc | SrcNone), I(ImplicitOps | SrcAcc, em_cwd), I(SrcImmFAddr | No64, em_call_far), N, II(ImplicitOps | Stack, em_pushf, pushf), - II(ImplicitOps | Stack, em_popf, popf), N, I(ImplicitOps, em_lahf), + II(ImplicitOps | Stack, em_popf, popf), + I(ImplicitOps, em_sahf), I(ImplicitOps, em_lahf), /* 0xA0 - 0xA7 */ I2bv(DstAcc | SrcMem | Mov | MemAbs, em_mov), I2bv(DstMem | SrcAcc | Mov | MemAbs | PageTable, em_mov), @@ -3810,7 +3857,7 @@ static const struct opcode opcode_table[256] = { static const struct opcode twobyte_table[256] = { /* 0x00 - 0x0F */ G(0, group6), GD(0, &group7), N, N, - N, I(ImplicitOps | VendorSpecific, em_syscall), + N, I(ImplicitOps | EmulateOnUD, em_syscall), II(ImplicitOps | Priv, em_clts, clts), N, DI(ImplicitOps | Priv, invd), DI(ImplicitOps | Priv, wbinvd), N, N, N, D(ImplicitOps | ModRM), N, N, @@ -3830,8 +3877,8 @@ static const struct opcode twobyte_table[256] = { IIP(ImplicitOps, em_rdtsc, rdtsc, check_rdtsc), II(ImplicitOps | Priv, em_rdmsr, rdmsr), IIP(ImplicitOps, em_rdpmc, rdpmc, check_rdpmc), - I(ImplicitOps | VendorSpecific, em_sysenter), - I(ImplicitOps | Priv | VendorSpecific, em_sysexit), + I(ImplicitOps | EmulateOnUD, em_sysenter), + I(ImplicitOps | Priv | EmulateOnUD, em_sysexit), N, N, N, N, N, N, N, N, N, N, /* 0x40 - 0x4F */ @@ -3892,6 +3939,30 @@ static const struct opcode twobyte_table[256] = { N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N }; +static const struct gprefix three_byte_0f_38_f0 = { + I(DstReg | SrcMem | Mov, em_movbe), N, N, N +}; + +static const struct gprefix three_byte_0f_38_f1 = { + I(DstMem | SrcReg | Mov, em_movbe), N, N, N +}; + +/* + * Insns below are selected by the prefix which indexed by the third opcode + * byte. + */ +static const struct opcode opcode_map_0f_38[256] = { + /* 0x00 - 0x7f */ + X16(N), X16(N), X16(N), X16(N), X16(N), X16(N), X16(N), X16(N), + /* 0x80 - 0xef */ + X16(N), X16(N), X16(N), X16(N), X16(N), X16(N), X16(N), + /* 0xf0 - 0xf1 */ + GP(EmulateOnUD | ModRM | Prefix, &three_byte_0f_38_f0), + GP(EmulateOnUD | ModRM | Prefix, &three_byte_0f_38_f1), + /* 0xf2 - 0xff */ + N, N, X4(N), X8(N) +}; + #undef D #undef N #undef G @@ -4040,7 +4111,8 @@ static int decode_operand(struct x86_emulate_ctxt *ctxt, struct operand *op, case OpMem8: ctxt->memop.bytes = 1; if (ctxt->memop.type == OP_REG) { - ctxt->memop.addr.reg = decode_register(ctxt, ctxt->modrm_rm, 1); + ctxt->memop.addr.reg = decode_register(ctxt, + ctxt->modrm_rm, true); fetch_register_operand(&ctxt->memop); } goto mem_common; @@ -4126,6 +4198,7 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len) ctxt->_eip = ctxt->eip; ctxt->fetch.start = ctxt->_eip; ctxt->fetch.end = ctxt->fetch.start + insn_len; + ctxt->opcode_len = 1; if (insn_len > 0) memcpy(ctxt->fetch.data, insn, insn_len); @@ -4208,9 +4281,16 @@ done_prefixes: opcode = opcode_table[ctxt->b]; /* Two-byte opcode? */ if (ctxt->b == 0x0f) { - ctxt->twobyte = 1; + ctxt->opcode_len = 2; ctxt->b = insn_fetch(u8, ctxt); opcode = twobyte_table[ctxt->b]; + + /* 0F_38 opcode map */ + if (ctxt->b == 0x38) { + ctxt->opcode_len = 3; + ctxt->b = insn_fetch(u8, ctxt); + opcode = opcode_map_0f_38[ctxt->b]; + } } ctxt->d = opcode.flags; @@ -4267,7 +4347,7 @@ done_prefixes: if (ctxt->d == 0 || (ctxt->d & NotImpl)) return EMULATION_FAILED; - if (!(ctxt->d & VendorSpecific) && ctxt->only_vendor_specific_insn) + if (!(ctxt->d & EmulateOnUD) && ctxt->ud) return EMULATION_FAILED; if (mode == X86EMUL_MODE_PROT64 && (ctxt->d & Stack)) @@ -4540,8 +4620,10 @@ special_insn: goto writeback; } - if (ctxt->twobyte) + if (ctxt->opcode_len == 2) goto twobyte_insn; + else if (ctxt->opcode_len == 3) + goto threebyte_insn; switch (ctxt->b) { case 0x63: /* movsxd */ @@ -4726,6 +4808,8 @@ twobyte_insn: goto cannot_emulate; } +threebyte_insn: + if (rc != X86EMUL_CONTINUE) goto done; diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index dce0df8150df..40772ef0f2b1 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -2570,11 +2570,6 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *sptep, kvm_release_pfn_clean(pfn); } -static void nonpaging_new_cr3(struct kvm_vcpu *vcpu) -{ - mmu_free_roots(vcpu); -} - static pfn_t pte_prefetch_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn, bool no_dirty_log) { @@ -3424,18 +3419,11 @@ out_unlock: return 0; } -static void nonpaging_free(struct kvm_vcpu *vcpu) -{ - mmu_free_roots(vcpu); -} - -static int nonpaging_init_context(struct kvm_vcpu *vcpu, - struct kvm_mmu *context) +static void nonpaging_init_context(struct kvm_vcpu *vcpu, + struct kvm_mmu *context) { - context->new_cr3 = nonpaging_new_cr3; context->page_fault = nonpaging_page_fault; context->gva_to_gpa = nonpaging_gva_to_gpa; - context->free = nonpaging_free; context->sync_page = nonpaging_sync_page; context->invlpg = nonpaging_invlpg; context->update_pte = nonpaging_update_pte; @@ -3444,7 +3432,6 @@ static int nonpaging_init_context(struct kvm_vcpu *vcpu, context->root_hpa = INVALID_PAGE; context->direct_map = true; context->nx = false; - return 0; } void kvm_mmu_flush_tlb(struct kvm_vcpu *vcpu) @@ -3454,9 +3441,8 @@ void kvm_mmu_flush_tlb(struct kvm_vcpu *vcpu) } EXPORT_SYMBOL_GPL(kvm_mmu_flush_tlb); -static void paging_new_cr3(struct kvm_vcpu *vcpu) +void kvm_mmu_new_cr3(struct kvm_vcpu *vcpu) { - pgprintk("%s: cr3 %lx\n", __func__, kvm_read_cr3(vcpu)); mmu_free_roots(vcpu); } @@ -3471,11 +3457,6 @@ static void inject_page_fault(struct kvm_vcpu *vcpu, vcpu->arch.mmu.inject_page_fault(vcpu, fault); } -static void paging_free(struct kvm_vcpu *vcpu) -{ - nonpaging_free(vcpu); -} - static bool sync_mmio_spte(struct kvm *kvm, u64 *sptep, gfn_t gfn, unsigned access, int *nr_present) { @@ -3665,9 +3646,9 @@ static void update_last_pte_bitmap(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu) mmu->last_pte_bitmap = map; } -static int paging64_init_context_common(struct kvm_vcpu *vcpu, - struct kvm_mmu *context, - int level) +static void paging64_init_context_common(struct kvm_vcpu *vcpu, + struct kvm_mmu *context, + int level) { context->nx = is_nx(vcpu); context->root_level = level; @@ -3677,27 +3658,24 @@ static int paging64_init_context_common(struct kvm_vcpu *vcpu, update_last_pte_bitmap(vcpu, context); ASSERT(is_pae(vcpu)); - context->new_cr3 = paging_new_cr3; context->page_fault = paging64_page_fault; context->gva_to_gpa = paging64_gva_to_gpa; context->sync_page = paging64_sync_page; context->invlpg = paging64_invlpg; context->update_pte = paging64_update_pte; - context->free = paging_free; context->shadow_root_level = level; context->root_hpa = INVALID_PAGE; context->direct_map = false; - return 0; } -static int paging64_init_context(struct kvm_vcpu *vcpu, - struct kvm_mmu *context) +static void paging64_init_context(struct kvm_vcpu *vcpu, + struct kvm_mmu *context) { - return paging64_init_context_common(vcpu, context, PT64_ROOT_LEVEL); + paging64_init_context_common(vcpu, context, PT64_ROOT_LEVEL); } -static int paging32_init_context(struct kvm_vcpu *vcpu, - struct kvm_mmu *context) +static void paging32_init_context(struct kvm_vcpu *vcpu, + struct kvm_mmu *context) { context->nx = false; context->root_level = PT32_ROOT_LEVEL; @@ -3706,33 +3684,28 @@ static int paging32_init_context(struct kvm_vcpu *vcpu, update_permission_bitmask(vcpu, context, false); update_last_pte_bitmap(vcpu, context); - context->new_cr3 = paging_new_cr3; context->page_fault = paging32_page_fault; context->gva_to_gpa = paging32_gva_to_gpa; - context->free = paging_free; context->sync_page = paging32_sync_page; context->invlpg = paging32_invlpg; context->update_pte = paging32_update_pte; context->shadow_root_level = PT32E_ROOT_LEVEL; context->root_hpa = INVALID_PAGE; context->direct_map = false; - return 0; } -static int paging32E_init_context(struct kvm_vcpu *vcpu, - struct kvm_mmu *context) +static void paging32E_init_context(struct kvm_vcpu *vcpu, + struct kvm_mmu *context) { - return paging64_init_context_common(vcpu, context, PT32E_ROOT_LEVEL); + paging64_init_context_common(vcpu, context, PT32E_ROOT_LEVEL); } -static int init_kvm_tdp_mmu(struct kvm_vcpu *vcpu) +static void init_kvm_tdp_mmu(struct kvm_vcpu *vcpu) { struct kvm_mmu *context = vcpu->arch.walk_mmu; context->base_role.word = 0; - context->new_cr3 = nonpaging_new_cr3; context->page_fault = tdp_page_fault; - context->free = nonpaging_free; context->sync_page = nonpaging_sync_page; context->invlpg = nonpaging_invlpg; context->update_pte = nonpaging_update_pte; @@ -3767,37 +3740,32 @@ static int init_kvm_tdp_mmu(struct kvm_vcpu *vcpu) update_permission_bitmask(vcpu, context, false); update_last_pte_bitmap(vcpu, context); - - return 0; } -int kvm_init_shadow_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *context) +void kvm_init_shadow_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *context) { - int r; bool smep = kvm_read_cr4_bits(vcpu, X86_CR4_SMEP); ASSERT(vcpu); ASSERT(!VALID_PAGE(vcpu->arch.mmu.root_hpa)); if (!is_paging(vcpu)) - r = nonpaging_init_context(vcpu, context); + nonpaging_init_context(vcpu, context); else if (is_long_mode(vcpu)) - r = paging64_init_context(vcpu, context); + paging64_init_context(vcpu, context); else if (is_pae(vcpu)) - r = paging32E_init_context(vcpu, context); + paging32E_init_context(vcpu, context); else - r = paging32_init_context(vcpu, context); + paging32_init_context(vcpu, context); vcpu->arch.mmu.base_role.nxe = is_nx(vcpu); vcpu->arch.mmu.base_role.cr4_pae = !!is_pae(vcpu); vcpu->arch.mmu.base_role.cr0_wp = is_write_protection(vcpu); vcpu->arch.mmu.base_role.smep_andnot_wp = smep && !is_write_protection(vcpu); - - return r; } EXPORT_SYMBOL_GPL(kvm_init_shadow_mmu); -int kvm_init_shadow_ept_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *context, +void kvm_init_shadow_ept_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *context, bool execonly) { ASSERT(vcpu); @@ -3806,37 +3774,30 @@ int kvm_init_shadow_ept_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *context, context->shadow_root_level = kvm_x86_ops->get_tdp_level(); context->nx = true; - context->new_cr3 = paging_new_cr3; context->page_fault = ept_page_fault; context->gva_to_gpa = ept_gva_to_gpa; context->sync_page = ept_sync_page; context->invlpg = ept_invlpg; context->update_pte = ept_update_pte; - context->free = paging_free; context->root_level = context->shadow_root_level; context->root_hpa = INVALID_PAGE; context->direct_map = false; update_permission_bitmask(vcpu, context, true); reset_rsvds_bits_mask_ept(vcpu, context, execonly); - - return 0; } EXPORT_SYMBOL_GPL(kvm_init_shadow_ept_mmu); -static int init_kvm_softmmu(struct kvm_vcpu *vcpu) +static void init_kvm_softmmu(struct kvm_vcpu *vcpu) { - int r = kvm_init_shadow_mmu(vcpu, vcpu->arch.walk_mmu); - + kvm_init_shadow_mmu(vcpu, vcpu->arch.walk_mmu); vcpu->arch.walk_mmu->set_cr3 = kvm_x86_ops->set_cr3; vcpu->arch.walk_mmu->get_cr3 = get_cr3; vcpu->arch.walk_mmu->get_pdptr = kvm_pdptr_read; vcpu->arch.walk_mmu->inject_page_fault = kvm_inject_page_fault; - - return r; } -static int init_kvm_nested_mmu(struct kvm_vcpu *vcpu) +static void init_kvm_nested_mmu(struct kvm_vcpu *vcpu) { struct kvm_mmu *g_context = &vcpu->arch.nested_mmu; @@ -3873,11 +3834,9 @@ static int init_kvm_nested_mmu(struct kvm_vcpu *vcpu) update_permission_bitmask(vcpu, g_context, false); update_last_pte_bitmap(vcpu, g_context); - - return 0; } -static int init_kvm_mmu(struct kvm_vcpu *vcpu) +static void init_kvm_mmu(struct kvm_vcpu *vcpu) { if (mmu_is_nested(vcpu)) return init_kvm_nested_mmu(vcpu); @@ -3887,18 +3846,12 @@ static int init_kvm_mmu(struct kvm_vcpu *vcpu) return init_kvm_softmmu(vcpu); } -static void destroy_kvm_mmu(struct kvm_vcpu *vcpu) +void kvm_mmu_reset_context(struct kvm_vcpu *vcpu) { ASSERT(vcpu); - if (VALID_PAGE(vcpu->arch.mmu.root_hpa)) - /* mmu.free() should set root_hpa = INVALID_PAGE */ - vcpu->arch.mmu.free(vcpu); -} -int kvm_mmu_reset_context(struct kvm_vcpu *vcpu) -{ - destroy_kvm_mmu(vcpu); - return init_kvm_mmu(vcpu); + kvm_mmu_unload(vcpu); + init_kvm_mmu(vcpu); } EXPORT_SYMBOL_GPL(kvm_mmu_reset_context); @@ -3923,6 +3876,7 @@ EXPORT_SYMBOL_GPL(kvm_mmu_load); void kvm_mmu_unload(struct kvm_vcpu *vcpu) { mmu_free_roots(vcpu); + WARN_ON(VALID_PAGE(vcpu->arch.mmu.root_hpa)); } EXPORT_SYMBOL_GPL(kvm_mmu_unload); @@ -4281,12 +4235,12 @@ int kvm_mmu_create(struct kvm_vcpu *vcpu) return alloc_mmu_pages(vcpu); } -int kvm_mmu_setup(struct kvm_vcpu *vcpu) +void kvm_mmu_setup(struct kvm_vcpu *vcpu) { ASSERT(vcpu); ASSERT(!VALID_PAGE(vcpu->arch.mmu.root_hpa)); - return init_kvm_mmu(vcpu); + init_kvm_mmu(vcpu); } void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot) @@ -4428,7 +4382,7 @@ mmu_shrink_scan(struct shrinker *shrink, struct shrink_control *sc) int nr_to_scan = sc->nr_to_scan; unsigned long freed = 0; - raw_spin_lock(&kvm_lock); + spin_lock(&kvm_lock); list_for_each_entry(kvm, &vm_list, vm_list) { int idx; @@ -4478,9 +4432,8 @@ unlock: break; } - raw_spin_unlock(&kvm_lock); + spin_unlock(&kvm_lock); return freed; - } static unsigned long @@ -4574,7 +4527,7 @@ void kvm_mmu_destroy(struct kvm_vcpu *vcpu) { ASSERT(vcpu); - destroy_kvm_mmu(vcpu); + kvm_mmu_unload(vcpu); free_mmu_pages(vcpu); mmu_free_memory_caches(vcpu); } diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h index 77e044a0f5f7..292615274358 100644 --- a/arch/x86/kvm/mmu.h +++ b/arch/x86/kvm/mmu.h @@ -70,8 +70,8 @@ enum { }; int handle_mmio_page_fault_common(struct kvm_vcpu *vcpu, u64 addr, bool direct); -int kvm_init_shadow_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *context); -int kvm_init_shadow_ept_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *context, +void kvm_init_shadow_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *context); +void kvm_init_shadow_ept_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *context, bool execonly); static inline unsigned int kvm_mmu_available_pages(struct kvm *kvm) diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index c0bc80391e40..c7168a5cff1b 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -1959,11 +1959,9 @@ static void nested_svm_inject_npf_exit(struct kvm_vcpu *vcpu, nested_svm_vmexit(svm); } -static int nested_svm_init_mmu_context(struct kvm_vcpu *vcpu) +static void nested_svm_init_mmu_context(struct kvm_vcpu *vcpu) { - int r; - - r = kvm_init_shadow_mmu(vcpu, &vcpu->arch.mmu); + kvm_init_shadow_mmu(vcpu, &vcpu->arch.mmu); vcpu->arch.mmu.set_cr3 = nested_svm_set_tdp_cr3; vcpu->arch.mmu.get_cr3 = nested_svm_get_tdp_cr3; @@ -1971,8 +1969,6 @@ static int nested_svm_init_mmu_context(struct kvm_vcpu *vcpu) vcpu->arch.mmu.inject_page_fault = nested_svm_inject_npf_exit; vcpu->arch.mmu.shadow_root_level = get_npt_level(); vcpu->arch.walk_mmu = &vcpu->arch.nested_mmu; - - return r; } static void nested_svm_uninit_mmu_context(struct kvm_vcpu *vcpu) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 2b2fce1b2009..b2fe1c252f35 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -1498,7 +1498,7 @@ static void add_atomic_switch_msr(struct vcpu_vmx *vmx, unsigned msr, break; if (i == NR_AUTOLOAD_MSRS) { - printk_once(KERN_WARNING"Not enough mst switch entries. " + printk_once(KERN_WARNING "Not enough msr switch entries. " "Can't add msr %x\n", msr); return; } else if (i == m->nr) { @@ -1898,16 +1898,12 @@ static void skip_emulated_instruction(struct kvm_vcpu *vcpu) /* * KVM wants to inject page-faults which it got to the guest. This function * checks whether in a nested guest, we need to inject them to L1 or L2. - * This function assumes it is called with the exit reason in vmcs02 being - * a #PF exception (this is the only case in which KVM injects a #PF when L2 - * is running). */ -static int nested_pf_handled(struct kvm_vcpu *vcpu) +static int nested_vmx_check_exception(struct kvm_vcpu *vcpu, unsigned nr) { struct vmcs12 *vmcs12 = get_vmcs12(vcpu); - /* TODO: also check PFEC_MATCH/MASK, not just EB.PF. */ - if (!(vmcs12->exception_bitmap & (1u << PF_VECTOR))) + if (!(vmcs12->exception_bitmap & (1u << nr))) return 0; nested_vmx_vmexit(vcpu); @@ -1921,8 +1917,8 @@ static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr, struct vcpu_vmx *vmx = to_vmx(vcpu); u32 intr_info = nr | INTR_INFO_VALID_MASK; - if (nr == PF_VECTOR && is_guest_mode(vcpu) && - !vmx->nested.nested_run_pending && nested_pf_handled(vcpu)) + if (!reinject && is_guest_mode(vcpu) && + nested_vmx_check_exception(vcpu, nr)) return; if (has_error_code) { @@ -2204,9 +2200,15 @@ static __init void nested_vmx_setup_ctls_msrs(void) #ifdef CONFIG_X86_64 VM_EXIT_HOST_ADDR_SPACE_SIZE | #endif - VM_EXIT_LOAD_IA32_PAT | VM_EXIT_SAVE_IA32_PAT; + VM_EXIT_LOAD_IA32_PAT | VM_EXIT_SAVE_IA32_PAT | + VM_EXIT_SAVE_VMX_PREEMPTION_TIMER; + if (!(nested_vmx_pinbased_ctls_high & PIN_BASED_VMX_PREEMPTION_TIMER) || + !(nested_vmx_exit_ctls_high & VM_EXIT_SAVE_VMX_PREEMPTION_TIMER)) { + nested_vmx_exit_ctls_high &= ~VM_EXIT_SAVE_VMX_PREEMPTION_TIMER; + nested_vmx_pinbased_ctls_high &= ~PIN_BASED_VMX_PREEMPTION_TIMER; + } nested_vmx_exit_ctls_high |= (VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR | - VM_EXIT_LOAD_IA32_EFER); + VM_EXIT_LOAD_IA32_EFER | VM_EXIT_SAVE_IA32_EFER); /* entry controls */ rdmsr(MSR_IA32_VMX_ENTRY_CTLS, @@ -2226,7 +2228,8 @@ static __init void nested_vmx_setup_ctls_msrs(void) nested_vmx_procbased_ctls_low, nested_vmx_procbased_ctls_high); nested_vmx_procbased_ctls_low = 0; nested_vmx_procbased_ctls_high &= - CPU_BASED_VIRTUAL_INTR_PENDING | CPU_BASED_USE_TSC_OFFSETING | + CPU_BASED_VIRTUAL_INTR_PENDING | + CPU_BASED_VIRTUAL_NMI_PENDING | CPU_BASED_USE_TSC_OFFSETING | CPU_BASED_HLT_EXITING | CPU_BASED_INVLPG_EXITING | CPU_BASED_MWAIT_EXITING | CPU_BASED_CR3_LOAD_EXITING | CPU_BASED_CR3_STORE_EXITING | @@ -2252,13 +2255,15 @@ static __init void nested_vmx_setup_ctls_msrs(void) nested_vmx_secondary_ctls_low = 0; nested_vmx_secondary_ctls_high &= SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | + SECONDARY_EXEC_UNRESTRICTED_GUEST | SECONDARY_EXEC_WBINVD_EXITING; if (enable_ept) { /* nested EPT: emulate EPT also to L1 */ nested_vmx_secondary_ctls_high |= SECONDARY_EXEC_ENABLE_EPT; nested_vmx_ept_caps = VMX_EPT_PAGE_WALK_4_BIT | - VMX_EPTP_WB_BIT | VMX_EPT_INVEPT_BIT; + VMX_EPTP_WB_BIT | VMX_EPT_2MB_PAGE_BIT | + VMX_EPT_INVEPT_BIT; nested_vmx_ept_caps &= vmx_capability.ept; /* * Since invept is completely emulated we support both global @@ -3380,8 +3385,10 @@ static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) if (enable_ept) { eptp = construct_eptp(cr3); vmcs_write64(EPT_POINTER, eptp); - guest_cr3 = is_paging(vcpu) ? kvm_read_cr3(vcpu) : - vcpu->kvm->arch.ept_identity_map_addr; + if (is_paging(vcpu) || is_guest_mode(vcpu)) + guest_cr3 = kvm_read_cr3(vcpu); + else + guest_cr3 = vcpu->kvm->arch.ept_identity_map_addr; ept_load_pdptrs(vcpu); } @@ -4879,6 +4886,17 @@ vmx_patch_hypercall(struct kvm_vcpu *vcpu, unsigned char *hypercall) hypercall[2] = 0xc1; } +static bool nested_cr0_valid(struct vmcs12 *vmcs12, unsigned long val) +{ + unsigned long always_on = VMXON_CR0_ALWAYSON; + + if (nested_vmx_secondary_ctls_high & + SECONDARY_EXEC_UNRESTRICTED_GUEST && + nested_cpu_has2(vmcs12, SECONDARY_EXEC_UNRESTRICTED_GUEST)) + always_on &= ~(X86_CR0_PE | X86_CR0_PG); + return (val & always_on) == always_on; +} + /* called to set cr0 as appropriate for a mov-to-cr0 exit. */ static int handle_set_cr0(struct kvm_vcpu *vcpu, unsigned long val) { @@ -4897,9 +4915,7 @@ static int handle_set_cr0(struct kvm_vcpu *vcpu, unsigned long val) val = (val & ~vmcs12->cr0_guest_host_mask) | (vmcs12->guest_cr0 & vmcs12->cr0_guest_host_mask); - /* TODO: will have to take unrestricted guest mode into - * account */ - if ((val & VMXON_CR0_ALWAYSON) != VMXON_CR0_ALWAYSON) + if (!nested_cr0_valid(vmcs12, val)) return 1; if (kvm_set_cr0(vcpu, val)) @@ -6627,6 +6643,9 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu) return 0; else if (is_page_fault(intr_info)) return enable_ept; + else if (is_no_device(intr_info) && + !(nested_read_cr0(vmcs12) & X86_CR0_TS)) + return 0; return vmcs12->exception_bitmap & (1u << (intr_info & INTR_INFO_VECTOR_MASK)); case EXIT_REASON_EXTERNAL_INTERRUPT: @@ -6722,6 +6741,27 @@ static void vmx_get_exit_info(struct kvm_vcpu *vcpu, u64 *info1, u64 *info2) *info2 = vmcs_read32(VM_EXIT_INTR_INFO); } +static void nested_adjust_preemption_timer(struct kvm_vcpu *vcpu) +{ + u64 delta_tsc_l1; + u32 preempt_val_l1, preempt_val_l2, preempt_scale; + + if (!(get_vmcs12(vcpu)->pin_based_vm_exec_control & + PIN_BASED_VMX_PREEMPTION_TIMER)) + return; + preempt_scale = native_read_msr(MSR_IA32_VMX_MISC) & + MSR_IA32_VMX_MISC_PREEMPTION_TIMER_SCALE; + preempt_val_l2 = vmcs_read32(VMX_PREEMPTION_TIMER_VALUE); + delta_tsc_l1 = vmx_read_l1_tsc(vcpu, native_read_tsc()) + - vcpu->arch.last_guest_tsc; + preempt_val_l1 = delta_tsc_l1 >> preempt_scale; + if (preempt_val_l2 <= preempt_val_l1) + preempt_val_l2 = 0; + else + preempt_val_l2 -= preempt_val_l1; + vmcs_write32(VMX_PREEMPTION_TIMER_VALUE, preempt_val_l2); +} + /* * The guest has exited. See if we can fix it or if we need userspace * assistance. @@ -6736,20 +6776,6 @@ static int vmx_handle_exit(struct kvm_vcpu *vcpu) if (vmx->emulation_required) return handle_invalid_guest_state(vcpu); - /* - * the KVM_REQ_EVENT optimization bit is only on for one entry, and if - * we did not inject a still-pending event to L1 now because of - * nested_run_pending, we need to re-enable this bit. - */ - if (vmx->nested.nested_run_pending) - kvm_make_request(KVM_REQ_EVENT, vcpu); - - if (!is_guest_mode(vcpu) && (exit_reason == EXIT_REASON_VMLAUNCH || - exit_reason == EXIT_REASON_VMRESUME)) - vmx->nested.nested_run_pending = 1; - else - vmx->nested.nested_run_pending = 0; - if (is_guest_mode(vcpu) && nested_vmx_exit_handled(vcpu)) { nested_vmx_vmexit(vcpu); return 1; @@ -7061,9 +7087,9 @@ static void __vmx_complete_interrupts(struct kvm_vcpu *vcpu, case INTR_TYPE_HARD_EXCEPTION: if (idt_vectoring_info & VECTORING_INFO_DELIVER_CODE_MASK) { u32 err = vmcs_read32(error_code_field); - kvm_queue_exception_e(vcpu, vector, err); + kvm_requeue_exception_e(vcpu, vector, err); } else - kvm_queue_exception(vcpu, vector); + kvm_requeue_exception(vcpu, vector); break; case INTR_TYPE_SOFT_INTR: vcpu->arch.event_exit_inst_len = vmcs_read32(instr_len_field); @@ -7146,6 +7172,8 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) atomic_switch_perf_msrs(vmx); debugctlmsr = get_debugctlmsr(); + if (is_guest_mode(vcpu) && !vmx->nested.nested_run_pending) + nested_adjust_preemption_timer(vcpu); vmx->__launched = vmx->loaded_vmcs->launched; asm( /* Store host registers */ @@ -7284,6 +7312,16 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) vmx->exit_reason = vmcs_read32(VM_EXIT_REASON); trace_kvm_exit(vmx->exit_reason, vcpu, KVM_ISA_VMX); + /* + * the KVM_REQ_EVENT optimization bit is only on for one entry, and if + * we did not inject a still-pending event to L1 now because of + * nested_run_pending, we need to re-enable this bit. + */ + if (vmx->nested.nested_run_pending) + kvm_make_request(KVM_REQ_EVENT, vcpu); + + vmx->nested.nested_run_pending = 0; + vmx_complete_atomic_exit(vmx); vmx_recover_nmi_blocking(vmx); vmx_complete_interrupts(vmx); @@ -7410,8 +7448,7 @@ static u64 vmx_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio) */ if (is_mmio) ret = MTRR_TYPE_UNCACHABLE << VMX_EPT_MT_EPTE_SHIFT; - else if (vcpu->kvm->arch.iommu_domain && - !(vcpu->kvm->arch.iommu_flags & KVM_IOMMU_CACHE_COHERENCY)) + else if (kvm_arch_has_noncoherent_dma(vcpu->kvm)) ret = kvm_get_guest_memory_type(vcpu, gfn) << VMX_EPT_MT_EPTE_SHIFT; else @@ -7501,9 +7538,9 @@ static unsigned long nested_ept_get_cr3(struct kvm_vcpu *vcpu) return get_vmcs12(vcpu)->ept_pointer; } -static int nested_ept_init_mmu_context(struct kvm_vcpu *vcpu) +static void nested_ept_init_mmu_context(struct kvm_vcpu *vcpu) { - int r = kvm_init_shadow_ept_mmu(vcpu, &vcpu->arch.mmu, + kvm_init_shadow_ept_mmu(vcpu, &vcpu->arch.mmu, nested_vmx_ept_caps & VMX_EPT_EXECUTE_ONLY_BIT); vcpu->arch.mmu.set_cr3 = vmx_set_cr3; @@ -7511,8 +7548,6 @@ static int nested_ept_init_mmu_context(struct kvm_vcpu *vcpu) vcpu->arch.mmu.inject_page_fault = nested_ept_inject_page_fault; vcpu->arch.walk_mmu = &vcpu->arch.nested_mmu; - - return r; } static void nested_ept_uninit_mmu_context(struct kvm_vcpu *vcpu) @@ -7520,6 +7555,20 @@ static void nested_ept_uninit_mmu_context(struct kvm_vcpu *vcpu) vcpu->arch.walk_mmu = &vcpu->arch.mmu; } +static void vmx_inject_page_fault_nested(struct kvm_vcpu *vcpu, + struct x86_exception *fault) +{ + struct vmcs12 *vmcs12 = get_vmcs12(vcpu); + + WARN_ON(!is_guest_mode(vcpu)); + + /* TODO: also check PFEC_MATCH/MASK, not just EB.PF. */ + if (vmcs12->exception_bitmap & (1u << PF_VECTOR)) + nested_vmx_vmexit(vcpu); + else + kvm_inject_page_fault(vcpu, fault); +} + /* * prepare_vmcs02 is called when the L1 guest hypervisor runs its nested * L2 guest. L1 has a vmcs for L2 (vmcs12), and this function "merges" it @@ -7533,6 +7582,7 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) { struct vcpu_vmx *vmx = to_vmx(vcpu); u32 exec_control; + u32 exit_control; vmcs_write16(GUEST_ES_SELECTOR, vmcs12->guest_es_selector); vmcs_write16(GUEST_CS_SELECTOR, vmcs12->guest_cs_selector); @@ -7706,7 +7756,10 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) * we should use its exit controls. Note that VM_EXIT_LOAD_IA32_EFER * bits are further modified by vmx_set_efer() below. */ - vmcs_write32(VM_EXIT_CONTROLS, vmcs_config.vmexit_ctrl); + exit_control = vmcs_config.vmexit_ctrl; + if (vmcs12->pin_based_vm_exec_control & PIN_BASED_VMX_PREEMPTION_TIMER) + exit_control |= VM_EXIT_SAVE_VMX_PREEMPTION_TIMER; + vmcs_write32(VM_EXIT_CONTROLS, exit_control); /* vmcs12's VM_ENTRY_LOAD_IA32_EFER and VM_ENTRY_IA32E_MODE are * emulated by vmx_set_efer(), below. @@ -7773,6 +7826,9 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) kvm_set_cr3(vcpu, vmcs12->guest_cr3); kvm_mmu_reset_context(vcpu); + if (!enable_ept) + vcpu->arch.walk_mmu->inject_page_fault = vmx_inject_page_fault_nested; + /* * L1 may access the L2's PDPTR, so save them to construct vmcs12 */ @@ -7876,7 +7932,7 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch) return 1; } - if (((vmcs12->guest_cr0 & VMXON_CR0_ALWAYSON) != VMXON_CR0_ALWAYSON) || + if (!nested_cr0_valid(vmcs12, vmcs12->guest_cr0) || ((vmcs12->guest_cr4 & VMXON_CR4_ALWAYSON) != VMXON_CR4_ALWAYSON)) { nested_vmx_entry_failure(vcpu, vmcs12, EXIT_REASON_INVALID_STATE, ENTRY_FAIL_DEFAULT); @@ -7938,6 +7994,8 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch) enter_guest_mode(vcpu); + vmx->nested.nested_run_pending = 1; + vmx->nested.vmcs01_tsc_offset = vmcs_read64(TSC_OFFSET); cpu = get_cpu(); @@ -8005,7 +8063,7 @@ static void vmcs12_save_pending_event(struct kvm_vcpu *vcpu, u32 idt_vectoring; unsigned int nr; - if (vcpu->arch.exception.pending) { + if (vcpu->arch.exception.pending && vcpu->arch.exception.reinject) { nr = vcpu->arch.exception.nr; idt_vectoring = nr | VECTORING_INFO_VALID_MASK; @@ -8023,7 +8081,7 @@ static void vmcs12_save_pending_event(struct kvm_vcpu *vcpu, } vmcs12->idt_vectoring_info_field = idt_vectoring; - } else if (vcpu->arch.nmi_pending) { + } else if (vcpu->arch.nmi_injected) { vmcs12->idt_vectoring_info_field = INTR_TYPE_NMI_INTR | INTR_INFO_VALID_MASK | NMI_VECTOR; } else if (vcpu->arch.interrupt.pending) { @@ -8105,6 +8163,11 @@ static void prepare_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) vmcs12->guest_pending_dbg_exceptions = vmcs_readl(GUEST_PENDING_DBG_EXCEPTIONS); + if ((vmcs12->pin_based_vm_exec_control & PIN_BASED_VMX_PREEMPTION_TIMER) && + (vmcs12->vm_exit_controls & VM_EXIT_SAVE_VMX_PREEMPTION_TIMER)) + vmcs12->vmx_preemption_timer_value = + vmcs_read32(VMX_PREEMPTION_TIMER_VALUE); + /* * In some cases (usually, nested EPT), L2 is allowed to change its * own CR3 without exiting. If it has changed it, we must keep it. @@ -8130,6 +8193,8 @@ static void prepare_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) vmcs12->guest_ia32_debugctl = vmcs_read64(GUEST_IA32_DEBUGCTL); if (vmcs12->vm_exit_controls & VM_EXIT_SAVE_IA32_PAT) vmcs12->guest_ia32_pat = vmcs_read64(GUEST_IA32_PAT); + if (vmcs12->vm_exit_controls & VM_EXIT_SAVE_IA32_EFER) + vmcs12->guest_ia32_efer = vcpu->arch.efer; vmcs12->guest_sysenter_cs = vmcs_read32(GUEST_SYSENTER_CS); vmcs12->guest_sysenter_esp = vmcs_readl(GUEST_SYSENTER_ESP); vmcs12->guest_sysenter_eip = vmcs_readl(GUEST_SYSENTER_EIP); @@ -8201,7 +8266,7 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu, * fpu_active (which may have changed). * Note that vmx_set_cr0 refers to efer set above. */ - kvm_set_cr0(vcpu, vmcs12->host_cr0); + vmx_set_cr0(vcpu, vmcs12->host_cr0); /* * If we did fpu_activate()/fpu_deactivate() during L2's run, we need * to apply the same changes to L1's vmcs. We just set cr0 correctly, @@ -8224,6 +8289,9 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu, kvm_set_cr3(vcpu, vmcs12->host_cr3); kvm_mmu_reset_context(vcpu); + if (!enable_ept) + vcpu->arch.walk_mmu->inject_page_fault = kvm_inject_page_fault; + if (enable_vpid) { /* * Trivially support vpid by letting L2s share their parent diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index e5ca72a5cdb6..21ef1ba184ae 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -577,6 +577,7 @@ static void kvm_put_guest_xcr0(struct kvm_vcpu *vcpu) int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr) { u64 xcr0; + u64 valid_bits; /* Only support XCR_XFEATURE_ENABLED_MASK(xcr0) now */ if (index != XCR_XFEATURE_ENABLED_MASK) @@ -586,8 +587,16 @@ int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr) return 1; if ((xcr0 & XSTATE_YMM) && !(xcr0 & XSTATE_SSE)) return 1; - if (xcr0 & ~host_xcr0) + + /* + * Do not allow the guest to set bits that we do not support + * saving. However, xcr0 bit 0 is always set, even if the + * emulated CPU does not support XSAVE (see fx_init). + */ + valid_bits = vcpu->arch.guest_supported_xcr0 | XSTATE_FP; + if (xcr0 & ~valid_bits) return 1; + kvm_put_guest_xcr0(vcpu); vcpu->arch.xcr0 = xcr0; return 0; @@ -684,7 +693,7 @@ int kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) vcpu->arch.cr3 = cr3; __set_bit(VCPU_EXREG_CR3, (ulong *)&vcpu->arch.regs_avail); - vcpu->arch.mmu.new_cr3(vcpu); + kvm_mmu_new_cr3(vcpu); return 0; } EXPORT_SYMBOL_GPL(kvm_set_cr3); @@ -2564,6 +2573,7 @@ int kvm_dev_ioctl_check_extension(long ext) case KVM_CAP_MMU_SHADOW_CACHE_CONTROL: case KVM_CAP_SET_TSS_ADDR: case KVM_CAP_EXT_CPUID: + case KVM_CAP_EXT_EMUL_CPUID: case KVM_CAP_CLOCKSOURCE: case KVM_CAP_PIT: case KVM_CAP_NOP_IO_DELAY: @@ -2673,15 +2683,17 @@ long kvm_arch_dev_ioctl(struct file *filp, r = 0; break; } - case KVM_GET_SUPPORTED_CPUID: { + case KVM_GET_SUPPORTED_CPUID: + case KVM_GET_EMULATED_CPUID: { struct kvm_cpuid2 __user *cpuid_arg = argp; struct kvm_cpuid2 cpuid; r = -EFAULT; if (copy_from_user(&cpuid, cpuid_arg, sizeof cpuid)) goto out; - r = kvm_dev_ioctl_get_supported_cpuid(&cpuid, - cpuid_arg->entries); + + r = kvm_dev_ioctl_get_cpuid(&cpuid, cpuid_arg->entries, + ioctl); if (r) goto out; @@ -2715,8 +2727,7 @@ static void wbinvd_ipi(void *garbage) static bool need_emulate_wbinvd(struct kvm_vcpu *vcpu) { - return vcpu->kvm->arch.iommu_domain && - !(vcpu->kvm->arch.iommu_flags & KVM_IOMMU_CACHE_COHERENCY); + return kvm_arch_has_noncoherent_dma(vcpu->kvm); } void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) @@ -2984,11 +2995,13 @@ static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu, static void kvm_vcpu_ioctl_x86_get_xsave(struct kvm_vcpu *vcpu, struct kvm_xsave *guest_xsave) { - if (cpu_has_xsave) + if (cpu_has_xsave) { memcpy(guest_xsave->region, &vcpu->arch.guest_fpu.state->xsave, - xstate_size); - else { + vcpu->arch.guest_xstate_size); + *(u64 *)&guest_xsave->region[XSAVE_HDR_OFFSET / sizeof(u32)] &= + vcpu->arch.guest_supported_xcr0 | XSTATE_FPSSE; + } else { memcpy(guest_xsave->region, &vcpu->arch.guest_fpu.state->fxsave, sizeof(struct i387_fxsave_struct)); @@ -3003,10 +3016,19 @@ static int kvm_vcpu_ioctl_x86_set_xsave(struct kvm_vcpu *vcpu, u64 xstate_bv = *(u64 *)&guest_xsave->region[XSAVE_HDR_OFFSET / sizeof(u32)]; - if (cpu_has_xsave) + if (cpu_has_xsave) { + /* + * Here we allow setting states that are not present in + * CPUID leaf 0xD, index 0, EDX:EAX. This is for compatibility + * with old userspace. + */ + if (xstate_bv & ~KVM_SUPPORTED_XCR0) + return -EINVAL; + if (xstate_bv & ~host_xcr0) + return -EINVAL; memcpy(&vcpu->arch.guest_fpu.state->xsave, - guest_xsave->region, xstate_size); - else { + guest_xsave->region, vcpu->arch.guest_xstate_size); + } else { if (xstate_bv & ~XSTATE_FPSSE) return -EINVAL; memcpy(&vcpu->arch.guest_fpu.state->fxsave, @@ -3042,9 +3064,9 @@ static int kvm_vcpu_ioctl_x86_set_xcrs(struct kvm_vcpu *vcpu, for (i = 0; i < guest_xcrs->nr_xcrs; i++) /* Only support XCR0 currently */ - if (guest_xcrs->xcrs[0].xcr == XCR_XFEATURE_ENABLED_MASK) { + if (guest_xcrs->xcrs[i].xcr == XCR_XFEATURE_ENABLED_MASK) { r = __kvm_set_xcr(vcpu, XCR_XFEATURE_ENABLED_MASK, - guest_xcrs->xcrs[0].value); + guest_xcrs->xcrs[i].value); break; } if (r) @@ -4775,8 +4797,8 @@ static void inject_emulated_exception(struct kvm_vcpu *vcpu) static void init_decode_cache(struct x86_emulate_ctxt *ctxt) { - memset(&ctxt->twobyte, 0, - (void *)&ctxt->_regs - (void *)&ctxt->twobyte); + memset(&ctxt->opcode_len, 0, + (void *)&ctxt->_regs - (void *)&ctxt->opcode_len); ctxt->fetch.start = 0; ctxt->fetch.end = 0; @@ -5094,8 +5116,7 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu, ctxt->have_exception = false; ctxt->perm_ok = false; - ctxt->only_vendor_specific_insn - = emulation_type & EMULTYPE_TRAP_UD; + ctxt->ud = emulation_type & EMULTYPE_TRAP_UD; r = x86_decode_insn(ctxt, insn, insn_len); @@ -5263,7 +5284,7 @@ static int kvmclock_cpufreq_notifier(struct notifier_block *nb, unsigned long va smp_call_function_single(freq->cpu, tsc_khz_changed, freq, 1); - raw_spin_lock(&kvm_lock); + spin_lock(&kvm_lock); list_for_each_entry(kvm, &vm_list, vm_list) { kvm_for_each_vcpu(i, vcpu, kvm) { if (vcpu->cpu != freq->cpu) @@ -5273,7 +5294,7 @@ static int kvmclock_cpufreq_notifier(struct notifier_block *nb, unsigned long va send_ipi = 1; } } - raw_spin_unlock(&kvm_lock); + spin_unlock(&kvm_lock); if (freq->old < freq->new && send_ipi) { /* @@ -5426,12 +5447,12 @@ static void pvclock_gtod_update_fn(struct work_struct *work) struct kvm_vcpu *vcpu; int i; - raw_spin_lock(&kvm_lock); + spin_lock(&kvm_lock); list_for_each_entry(kvm, &vm_list, vm_list) kvm_for_each_vcpu(i, vcpu, kvm) set_bit(KVM_REQ_MASTERCLOCK_UPDATE, &vcpu->requests); atomic_set(&kvm_guest_has_master_clock, 0); - raw_spin_unlock(&kvm_lock); + spin_unlock(&kvm_lock); } static DECLARE_WORK(pvclock_gtod_work, pvclock_gtod_update_fn); @@ -5945,10 +5966,12 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) vcpu->mode = IN_GUEST_MODE; + srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx); + /* We should set ->mode before check ->requests, * see the comment in make_all_cpus_request. */ - smp_mb(); + smp_mb__after_srcu_read_unlock(); local_irq_disable(); @@ -5958,12 +5981,11 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) smp_wmb(); local_irq_enable(); preempt_enable(); + vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu); r = 1; goto cancel_injection; } - srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx); - if (req_immediate_exit) smp_send_reschedule(vcpu->cpu); @@ -6688,7 +6710,7 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) if (r) return r; kvm_vcpu_reset(vcpu); - r = kvm_mmu_setup(vcpu); + kvm_mmu_setup(vcpu); vcpu_put(vcpu); return r; @@ -6940,6 +6962,10 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) vcpu->arch.ia32_tsc_adjust_msr = 0x0; vcpu->arch.pv_time_enabled = false; + + vcpu->arch.guest_supported_xcr0 = 0; + vcpu->arch.guest_xstate_size = XSAVE_HDR_SIZE + XSAVE_HDR_OFFSET; + kvm_async_pf_hash_reset(vcpu); kvm_pmu_init(vcpu); @@ -6981,6 +7007,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) INIT_LIST_HEAD(&kvm->arch.active_mmu_pages); INIT_LIST_HEAD(&kvm->arch.zapped_obsolete_pages); INIT_LIST_HEAD(&kvm->arch.assigned_dev_head); + atomic_set(&kvm->arch.noncoherent_dma_count, 0); /* Reserve bit 0 of irq_sources_bitmap for userspace irq source */ set_bit(KVM_USERSPACE_IRQ_SOURCE_ID, &kvm->arch.irq_sources_bitmap); @@ -7065,7 +7092,7 @@ void kvm_arch_destroy_vm(struct kvm *kvm) kfree(rcu_dereference_check(kvm->arch.apic_map, 1)); } -void kvm_arch_free_memslot(struct kvm_memory_slot *free, +void kvm_arch_free_memslot(struct kvm *kvm, struct kvm_memory_slot *free, struct kvm_memory_slot *dont) { int i; @@ -7086,7 +7113,8 @@ void kvm_arch_free_memslot(struct kvm_memory_slot *free, } } -int kvm_arch_create_memslot(struct kvm_memory_slot *slot, unsigned long npages) +int kvm_arch_create_memslot(struct kvm *kvm, struct kvm_memory_slot *slot, + unsigned long npages) { int i; @@ -7283,7 +7311,7 @@ void kvm_arch_async_page_ready(struct kvm_vcpu *vcpu, struct kvm_async_pf *work) int r; if ((vcpu->arch.mmu.direct_map != work->arch.direct_map) || - is_error_page(work->page)) + work->wakeup_all) return; r = kvm_mmu_reload(vcpu); @@ -7393,7 +7421,7 @@ void kvm_arch_async_page_present(struct kvm_vcpu *vcpu, struct x86_exception fault; trace_kvm_async_pf_ready(work->arch.token, work->gva); - if (is_error_page(work->page)) + if (work->wakeup_all) work->arch.token = ~0; /* broadcast wakeup */ else kvm_del_async_pf_gfn(vcpu, work->arch.gfn); @@ -7420,6 +7448,24 @@ bool kvm_arch_can_inject_async_page_present(struct kvm_vcpu *vcpu) kvm_x86_ops->interrupt_allowed(vcpu); } +void kvm_arch_register_noncoherent_dma(struct kvm *kvm) +{ + atomic_inc(&kvm->arch.noncoherent_dma_count); +} +EXPORT_SYMBOL_GPL(kvm_arch_register_noncoherent_dma); + +void kvm_arch_unregister_noncoherent_dma(struct kvm *kvm) +{ + atomic_dec(&kvm->arch.noncoherent_dma_count); +} +EXPORT_SYMBOL_GPL(kvm_arch_unregister_noncoherent_dma); + +bool kvm_arch_has_noncoherent_dma(struct kvm *kvm) +{ + return atomic_read(&kvm->arch.noncoherent_dma_count); +} +EXPORT_SYMBOL_GPL(kvm_arch_has_noncoherent_dma); + EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_exit); EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_inj_virq); EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_page_fault); diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h index e224f7a671b6..587fb9ede436 100644 --- a/arch/x86/kvm/x86.h +++ b/arch/x86/kvm/x86.h @@ -122,6 +122,7 @@ int kvm_write_guest_virt_system(struct x86_emulate_ctxt *ctxt, gva_t addr, void *val, unsigned int bytes, struct x86_exception *exception); +#define KVM_SUPPORTED_XCR0 (XSTATE_FP | XSTATE_SSE | XSTATE_YMM) extern u64 host_xcr0; extern struct static_key kvm_no_apic_vcpu; diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index 96b2c6697c9d..992d63bb154f 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -16,7 +16,7 @@ clean-files := inat-tables.c obj-$(CONFIG_SMP) += msr-smp.o cache-smp.o -lib-y := delay.o +lib-y := delay.o misc.o lib-y += thunk_$(BITS).o lib-y += usercopy_$(BITS).o usercopy.o getuser.o putuser.o lib-y += memcpy_$(BITS).o diff --git a/arch/x86/lib/misc.c b/arch/x86/lib/misc.c new file mode 100644 index 000000000000..76b373af03f0 --- /dev/null +++ b/arch/x86/lib/misc.c @@ -0,0 +1,21 @@ +/* + * Count the digits of @val including a possible sign. + * + * (Typed on and submitted from hpa's mobile phone.) + */ +int num_digits(int val) +{ + int m = 10; + int d = 1; + + if (val < 0) { + d++; + val = -val; + } + + while (val >= m) { + m *= 10; + d++; + } + return d; +} diff --git a/arch/x86/lib/msr-smp.c b/arch/x86/lib/msr-smp.c index a6b1b86d2253..518532e6a3fa 100644 --- a/arch/x86/lib/msr-smp.c +++ b/arch/x86/lib/msr-smp.c @@ -47,6 +47,21 @@ int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h) } EXPORT_SYMBOL(rdmsr_on_cpu); +int rdmsrl_on_cpu(unsigned int cpu, u32 msr_no, u64 *q) +{ + int err; + struct msr_info rv; + + memset(&rv, 0, sizeof(rv)); + + rv.msr_no = msr_no; + err = smp_call_function_single(cpu, __rdmsr_on_cpu, &rv, 1); + *q = rv.reg.q; + + return err; +} +EXPORT_SYMBOL(rdmsrl_on_cpu); + int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) { int err; @@ -63,6 +78,22 @@ int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) } EXPORT_SYMBOL(wrmsr_on_cpu); +int wrmsrl_on_cpu(unsigned int cpu, u32 msr_no, u64 q) +{ + int err; + struct msr_info rv; + + memset(&rv, 0, sizeof(rv)); + + rv.msr_no = msr_no; + rv.reg.q = q; + + err = smp_call_function_single(cpu, __wrmsr_on_cpu, &rv, 1); + + return err; +} +EXPORT_SYMBOL(wrmsrl_on_cpu); + static void __rwmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs, void (*msr_func) (void *info)) @@ -159,6 +190,37 @@ int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) } EXPORT_SYMBOL(wrmsr_safe_on_cpu); +int wrmsrl_safe_on_cpu(unsigned int cpu, u32 msr_no, u64 q) +{ + int err; + struct msr_info rv; + + memset(&rv, 0, sizeof(rv)); + + rv.msr_no = msr_no; + rv.reg.q = q; + + err = smp_call_function_single(cpu, __wrmsr_safe_on_cpu, &rv, 1); + + return err ? err : rv.err; +} +EXPORT_SYMBOL(wrmsrl_safe_on_cpu); + +int rdmsrl_safe_on_cpu(unsigned int cpu, u32 msr_no, u64 *q) +{ + int err; + struct msr_info rv; + + memset(&rv, 0, sizeof(rv)); + + rv.msr_no = msr_no; + err = smp_call_function_single(cpu, __rdmsr_safe_on_cpu, &rv, 1); + *q = rv.reg.q; + + return err ? err : rv.err; +} +EXPORT_SYMBOL(rdmsrl_safe_on_cpu); + /* * These variants are significantly slower, but allows control over * the entire 32-bit GPR set. diff --git a/arch/x86/lib/usercopy.c b/arch/x86/lib/usercopy.c index 4f74d94c8d97..ddf9ecb53cc3 100644 --- a/arch/x86/lib/usercopy.c +++ b/arch/x86/lib/usercopy.c @@ -11,39 +11,26 @@ #include <linux/sched.h> /* - * best effort, GUP based copy_from_user() that is NMI-safe + * We rely on the nested NMI work to allow atomic faults from the NMI path; the + * nested NMI paths are careful to preserve CR2. */ unsigned long copy_from_user_nmi(void *to, const void __user *from, unsigned long n) { - unsigned long offset, addr = (unsigned long)from; - unsigned long size, len = 0; - struct page *page; - void *map; - int ret; + unsigned long ret; if (__range_not_ok(from, n, TASK_SIZE)) - return len; - - do { - ret = __get_user_pages_fast(addr, 1, 0, &page); - if (!ret) - break; - - offset = addr & (PAGE_SIZE - 1); - size = min(PAGE_SIZE - offset, n - len); - - map = kmap_atomic(page); - memcpy(to, map+offset, size); - kunmap_atomic(map); - put_page(page); - - len += size; - to += size; - addr += size; - - } while (len < n); - - return len; + return 0; + + /* + * Even though this function is typically called from NMI/IRQ context + * disable pagefaults so that its behaviour is consistent even when + * called form other contexts. + */ + pagefault_disable(); + ret = __copy_from_user_inatomic(to, from, n); + pagefault_enable(); + + return ret; } EXPORT_SYMBOL_GPL(copy_from_user_nmi); diff --git a/arch/x86/lib/usercopy_32.c b/arch/x86/lib/usercopy_32.c index 3eb18acd0e40..e2f5e21c03b3 100644 --- a/arch/x86/lib/usercopy_32.c +++ b/arch/x86/lib/usercopy_32.c @@ -654,14 +654,13 @@ EXPORT_SYMBOL(__copy_from_user_ll_nocache_nozero); * Returns number of bytes that could not be copied. * On success, this will be zero. */ -unsigned long -copy_to_user(void __user *to, const void *from, unsigned long n) +unsigned long _copy_to_user(void __user *to, const void *from, unsigned n) { if (access_ok(VERIFY_WRITE, to, n)) n = __copy_to_user(to, from, n); return n; } -EXPORT_SYMBOL(copy_to_user); +EXPORT_SYMBOL(_copy_to_user); /** * copy_from_user: - Copy a block of data from user space. @@ -679,8 +678,7 @@ EXPORT_SYMBOL(copy_to_user); * If some data could not be copied, this function will pad the copied * data to the requested size using zero bytes. */ -unsigned long -_copy_from_user(void *to, const void __user *from, unsigned long n) +unsigned long _copy_from_user(void *to, const void __user *from, unsigned n) { if (access_ok(VERIFY_READ, from, n)) n = __copy_from_user(to, from, n); diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile index 23d8e5fecf76..6a19ad9f370d 100644 --- a/arch/x86/mm/Makefile +++ b/arch/x86/mm/Makefile @@ -6,6 +6,8 @@ nostackp := $(call cc-option, -fno-stack-protector) CFLAGS_physaddr.o := $(nostackp) CFLAGS_setup_nx.o := $(nostackp) +CFLAGS_fault.o := -I$(src)/../include/asm/trace + obj-$(CONFIG_X86_PAT) += pat_rbtree.o obj-$(CONFIG_SMP) += tlb.o diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 3aaeffcfd67a..9ff85bb8dd69 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -20,6 +20,9 @@ #include <asm/kmemcheck.h> /* kmemcheck_*(), ... */ #include <asm/fixmap.h> /* VSYSCALL_START */ +#define CREATE_TRACE_POINTS +#include <asm/trace/exceptions.h> + /* * Page fault error code bits: * @@ -51,7 +54,7 @@ kmmio_fault(struct pt_regs *regs, unsigned long addr) return 0; } -static inline int __kprobes notify_page_fault(struct pt_regs *regs) +static inline int __kprobes kprobes_fault(struct pt_regs *regs) { int ret = 0; @@ -596,7 +599,7 @@ show_fault_oops(struct pt_regs *regs, unsigned long error_code, printk(KERN_CONT " at %p\n", (void *) address); printk(KERN_ALERT "IP:"); - printk_address(regs->ip, 1); + printk_address(regs->ip); dump_pagetable(address); } @@ -1048,7 +1051,7 @@ __do_page_fault(struct pt_regs *regs, unsigned long error_code) return; /* kprobes don't want to hook the spurious faults: */ - if (notify_page_fault(regs)) + if (kprobes_fault(regs)) return; /* * Don't take the mm semaphore here. If we fixup a prefetch @@ -1060,23 +1063,8 @@ __do_page_fault(struct pt_regs *regs, unsigned long error_code) } /* kprobes don't want to hook the spurious faults: */ - if (unlikely(notify_page_fault(regs))) + if (unlikely(kprobes_fault(regs))) return; - /* - * It's safe to allow irq's after cr2 has been saved and the - * vmalloc fault has been handled. - * - * User-mode registers count as a user access even for any - * potential system fault or CPU buglet: - */ - if (user_mode_vm(regs)) { - local_irq_enable(); - error_code |= PF_USER; - flags |= FAULT_FLAG_USER; - } else { - if (regs->flags & X86_EFLAGS_IF) - local_irq_enable(); - } if (unlikely(error_code & PF_RSVD)) pgtable_bad(regs, error_code, address); @@ -1088,8 +1076,6 @@ __do_page_fault(struct pt_regs *regs, unsigned long error_code) } } - perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address); - /* * If we're in an interrupt, have no user context or are running * in an atomic region then we must not take the fault: @@ -1099,6 +1085,24 @@ __do_page_fault(struct pt_regs *regs, unsigned long error_code) return; } + /* + * It's safe to allow irq's after cr2 has been saved and the + * vmalloc fault has been handled. + * + * User-mode registers count as a user access even for any + * potential system fault or CPU buglet: + */ + if (user_mode_vm(regs)) { + local_irq_enable(); + error_code |= PF_USER; + flags |= FAULT_FLAG_USER; + } else { + if (regs->flags & X86_EFLAGS_IF) + local_irq_enable(); + } + + perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address); + if (error_code & PF_WRITE) flags |= FAULT_FLAG_WRITE; @@ -1231,3 +1235,23 @@ do_page_fault(struct pt_regs *regs, unsigned long error_code) __do_page_fault(regs, error_code); exception_exit(prev_state); } + +static void trace_page_fault_entries(struct pt_regs *regs, + unsigned long error_code) +{ + if (user_mode(regs)) + trace_page_fault_user(read_cr2(), regs, error_code); + else + trace_page_fault_kernel(read_cr2(), regs, error_code); +} + +dotraplinkage void __kprobes +trace_do_page_fault(struct pt_regs *regs, unsigned long error_code) +{ + enum ctx_state prev_state; + + prev_state = exception_enter(); + trace_page_fault_entries(regs, error_code); + __do_page_fault(regs, error_code); + exception_exit(prev_state); +} diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c index 04664cdb7fda..f97130618113 100644 --- a/arch/x86/mm/init.c +++ b/arch/x86/mm/init.c @@ -53,12 +53,12 @@ __ref void *alloc_low_pages(unsigned int num) if ((pgt_buf_end + num) > pgt_buf_top || !can_use_brk_pgt) { unsigned long ret; if (min_pfn_mapped >= max_pfn_mapped) - panic("alloc_low_page: ran out of memory"); + panic("alloc_low_pages: ran out of memory"); ret = memblock_find_in_range(min_pfn_mapped << PAGE_SHIFT, max_pfn_mapped << PAGE_SHIFT, PAGE_SIZE * num , PAGE_SIZE); if (!ret) - panic("alloc_low_page: can not alloc memory"); + panic("alloc_low_pages: can not alloc memory"); memblock_reserve(ret, PAGE_SIZE * num); pfn = ret >> PAGE_SHIFT; } else { @@ -399,29 +399,46 @@ static unsigned long __init init_range_memory_mapping( return mapped_ram_size; } -/* (PUD_SHIFT-PMD_SHIFT)/2 */ -#define STEP_SIZE_SHIFT 5 -void __init init_mem_mapping(void) +static unsigned long __init get_new_step_size(unsigned long step_size) +{ + /* + * Explain why we shift by 5 and why we don't have to worry about + * 'step_size << 5' overflowing: + * + * initial mapped size is PMD_SIZE (2M). + * We can not set step_size to be PUD_SIZE (1G) yet. + * In worse case, when we cross the 1G boundary, and + * PG_LEVEL_2M is not set, we will need 1+1+512 pages (2M + 8k) + * to map 1G range with PTE. Use 5 as shift for now. + * + * Don't need to worry about overflow, on 32bit, when step_size + * is 0, round_down() returns 0 for start, and that turns it + * into 0x100000000ULL. + */ + return step_size << 5; +} + +/** + * memory_map_top_down - Map [map_start, map_end) top down + * @map_start: start address of the target memory range + * @map_end: end address of the target memory range + * + * This function will setup direct mapping for memory range + * [map_start, map_end) in top-down. That said, the page tables + * will be allocated at the end of the memory, and we map the + * memory in top-down. + */ +static void __init memory_map_top_down(unsigned long map_start, + unsigned long map_end) { - unsigned long end, real_end, start, last_start; + unsigned long real_end, start, last_start; unsigned long step_size; unsigned long addr; unsigned long mapped_ram_size = 0; unsigned long new_mapped_ram_size; - probe_page_size_mask(); - -#ifdef CONFIG_X86_64 - end = max_pfn << PAGE_SHIFT; -#else - end = max_low_pfn << PAGE_SHIFT; -#endif - - /* the ISA range is always mapped regardless of memory holes */ - init_memory_mapping(0, ISA_END_ADDRESS); - /* xen has big range in reserved near end of ram, skip it at first.*/ - addr = memblock_find_in_range(ISA_END_ADDRESS, end, PMD_SIZE, PMD_SIZE); + addr = memblock_find_in_range(map_start, map_end, PMD_SIZE, PMD_SIZE); real_end = addr + PMD_SIZE; /* step_size need to be small so pgt_buf from BRK could cover it */ @@ -436,25 +453,106 @@ void __init init_mem_mapping(void) * end of RAM in [min_pfn_mapped, max_pfn_mapped) used as new pages * for page table. */ - while (last_start > ISA_END_ADDRESS) { + while (last_start > map_start) { if (last_start > step_size) { start = round_down(last_start - 1, step_size); - if (start < ISA_END_ADDRESS) - start = ISA_END_ADDRESS; + if (start < map_start) + start = map_start; } else - start = ISA_END_ADDRESS; + start = map_start; new_mapped_ram_size = init_range_memory_mapping(start, last_start); last_start = start; min_pfn_mapped = last_start >> PAGE_SHIFT; /* only increase step_size after big range get mapped */ if (new_mapped_ram_size > mapped_ram_size) - step_size <<= STEP_SIZE_SHIFT; + step_size = get_new_step_size(step_size); mapped_ram_size += new_mapped_ram_size; } - if (real_end < end) - init_range_memory_mapping(real_end, end); + if (real_end < map_end) + init_range_memory_mapping(real_end, map_end); +} + +/** + * memory_map_bottom_up - Map [map_start, map_end) bottom up + * @map_start: start address of the target memory range + * @map_end: end address of the target memory range + * + * This function will setup direct mapping for memory range + * [map_start, map_end) in bottom-up. Since we have limited the + * bottom-up allocation above the kernel, the page tables will + * be allocated just above the kernel and we map the memory + * in [map_start, map_end) in bottom-up. + */ +static void __init memory_map_bottom_up(unsigned long map_start, + unsigned long map_end) +{ + unsigned long next, new_mapped_ram_size, start; + unsigned long mapped_ram_size = 0; + /* step_size need to be small so pgt_buf from BRK could cover it */ + unsigned long step_size = PMD_SIZE; + + start = map_start; + min_pfn_mapped = start >> PAGE_SHIFT; + + /* + * We start from the bottom (@map_start) and go to the top (@map_end). + * The memblock_find_in_range() gets us a block of RAM from the + * end of RAM in [min_pfn_mapped, max_pfn_mapped) used as new pages + * for page table. + */ + while (start < map_end) { + if (map_end - start > step_size) { + next = round_up(start + 1, step_size); + if (next > map_end) + next = map_end; + } else + next = map_end; + + new_mapped_ram_size = init_range_memory_mapping(start, next); + start = next; + + if (new_mapped_ram_size > mapped_ram_size) + step_size = get_new_step_size(step_size); + mapped_ram_size += new_mapped_ram_size; + } +} + +void __init init_mem_mapping(void) +{ + unsigned long end; + + probe_page_size_mask(); + +#ifdef CONFIG_X86_64 + end = max_pfn << PAGE_SHIFT; +#else + end = max_low_pfn << PAGE_SHIFT; +#endif + + /* the ISA range is always mapped regardless of memory holes */ + init_memory_mapping(0, ISA_END_ADDRESS); + + /* + * If the allocation is in bottom-up direction, we setup direct mapping + * in bottom-up, otherwise we setup direct mapping in top-down. + */ + if (memblock_bottom_up()) { + unsigned long kernel_end = __pa_symbol(_end); + + /* + * we need two separate calls here. This is because we want to + * allocate page tables above the kernel. So we first map + * [kernel_end, end) to make memory above the kernel be mapped + * as soon as possible. And then use page tables allocated above + * the kernel to map [ISA_END_ADDRESS, kernel_end). + */ + memory_map_bottom_up(kernel_end, end); + memory_map_bottom_up(ISA_END_ADDRESS, kernel_end); + } else { + memory_map_top_down(ISA_END_ADDRESS, end); + } #ifdef CONFIG_X86_64 if (max_pfn > max_low_pfn) { diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c index 8bf93bae1f13..24aec58d6afd 100644 --- a/arch/x86/mm/numa.c +++ b/arch/x86/mm/numa.c @@ -567,6 +567,17 @@ static int __init numa_init(int (*init_func)(void)) ret = init_func(); if (ret < 0) return ret; + + /* + * We reset memblock back to the top-down direction + * here because if we configured ACPI_NUMA, we have + * parsed SRAT in init_func(). It is ok to have the + * reset here even if we did't configure ACPI_NUMA + * or acpi numa init fails and fallbacks to dummy + * numa init. + */ + memblock_set_bottom_up(false); + ret = numa_cleanup_meminfo(&numa_meminfo); if (ret < 0) return ret; diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c index dfa537a03be1..a7cccb6d7fec 100644 --- a/arch/x86/mm/pgtable.c +++ b/arch/x86/mm/pgtable.c @@ -25,8 +25,12 @@ pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address) struct page *pte; pte = alloc_pages(__userpte_alloc_gfp, 0); - if (pte) - pgtable_page_ctor(pte); + if (!pte) + return NULL; + if (!pgtable_page_ctor(pte)) { + __free_page(pte); + return NULL; + } return pte; } @@ -189,8 +193,10 @@ static void free_pmds(pmd_t *pmds[]) int i; for(i = 0; i < PREALLOCATED_PMDS; i++) - if (pmds[i]) + if (pmds[i]) { + pgtable_pmd_page_dtor(virt_to_page(pmds[i])); free_page((unsigned long)pmds[i]); + } } static int preallocate_pmds(pmd_t *pmds[]) @@ -200,8 +206,13 @@ static int preallocate_pmds(pmd_t *pmds[]) for(i = 0; i < PREALLOCATED_PMDS; i++) { pmd_t *pmd = (pmd_t *)__get_free_page(PGALLOC_GFP); - if (pmd == NULL) + if (!pmd) failed = true; + if (pmd && !pgtable_pmd_page_ctor(virt_to_page(pmd))) { + free_page((unsigned long)pmds[i]); + pmd = NULL; + failed = true; + } pmds[i] = pmd; } diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c index 516593e1ce33..26328e800869 100644 --- a/arch/x86/net/bpf_jit_comp.c +++ b/arch/x86/net/bpf_jit_comp.c @@ -788,5 +788,7 @@ void bpf_jit_free(struct sk_filter *fp) if (fp->bpf_func != sk_run_filter) { INIT_WORK(&fp->work, bpf_jit_free_deferred); schedule_work(&fp->work); + } else { + kfree(fp); } } diff --git a/arch/x86/oprofile/backtrace.c b/arch/x86/oprofile/backtrace.c index d6aa6e8315d1..5d04be5efb64 100644 --- a/arch/x86/oprofile/backtrace.c +++ b/arch/x86/oprofile/backtrace.c @@ -47,7 +47,7 @@ dump_user_backtrace_32(struct stack_frame_ia32 *head) unsigned long bytes; bytes = copy_from_user_nmi(bufhead, head, sizeof(bufhead)); - if (bytes != sizeof(bufhead)) + if (bytes != 0) return NULL; fp = (struct stack_frame_ia32 *) compat_ptr(bufhead[0].next_frame); @@ -93,7 +93,7 @@ static struct stack_frame *dump_user_backtrace(struct stack_frame *head) unsigned long bytes; bytes = copy_from_user_nmi(bufhead, head, sizeof(bufhead)); - if (bytes != sizeof(bufhead)) + if (bytes != 0) return NULL; oprofile_add_trace(bufhead[0].return_address); diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile index ee0af58ca5bd..e063eed0f912 100644 --- a/arch/x86/pci/Makefile +++ b/arch/x86/pci/Makefile @@ -18,7 +18,7 @@ obj-$(CONFIG_X86_VISWS) += visws.o obj-$(CONFIG_X86_NUMAQ) += numaq_32.o obj-$(CONFIG_X86_NUMACHIP) += numachip.o -obj-$(CONFIG_X86_INTEL_MID) += mrst.o +obj-$(CONFIG_X86_INTEL_MID) += intel_mid_pci.o obj-y += common.o early.o obj-y += bus_numa.o diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index b30e937689d6..7fb24e53d4c8 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c @@ -354,12 +354,12 @@ static void coalesce_windows(struct pci_root_info *info, unsigned long type) * the kernel resource tree doesn't allow overlaps. */ if (resource_overlaps(res1, res2)) { - res1->start = min(res1->start, res2->start); - res1->end = max(res1->end, res2->end); + res2->start = min(res1->start, res2->start); + res2->end = max(res1->end, res2->end); dev_info(&info->bridge->dev, "host bridge window expanded to %pR; %pR ignored\n", - res1, res2); - res2->flags = 0; + res2, res1); + res1->flags = 0; } } } diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c index f5809fa2753e..b046e070e088 100644 --- a/arch/x86/pci/fixup.c +++ b/arch/x86/pci/fixup.c @@ -231,7 +231,7 @@ static int quirk_pcie_aspm_write(struct pci_bus *bus, unsigned int devfn, int wh offset = quirk_aspm_offset[GET_INDEX(bus->self->device, devfn)]; if ((offset) && (where == offset)) - value = value & 0xfffffffc; + value = value & ~PCI_EXP_LNKCTL_ASPMC; return raw_pci_write(pci_domain_nr(bus), bus->number, devfn, where, size, value); @@ -252,7 +252,7 @@ static struct pci_ops quirk_pcie_aspm_ops = { */ static void pcie_rootport_aspm_quirk(struct pci_dev *pdev) { - int cap_base, i; + int i; struct pci_bus *pbus; struct pci_dev *dev; @@ -278,7 +278,7 @@ static void pcie_rootport_aspm_quirk(struct pci_dev *pdev) for (i = GET_INDEX(pdev->device, 0); i <= GET_INDEX(pdev->device, 7); ++i) quirk_aspm_offset[i] = 0; - pbus->ops = pbus->parent->ops; + pci_bus_set_ops(pbus, pbus->parent->ops); } else { /* * If devices are attached to the root port at power-up or @@ -286,13 +286,15 @@ static void pcie_rootport_aspm_quirk(struct pci_dev *pdev) * each root port to save the register offsets and replace the * bus ops. */ - list_for_each_entry(dev, &pbus->devices, bus_list) { + list_for_each_entry(dev, &pbus->devices, bus_list) /* There are 0 to 8 devices attached to this bus */ - cap_base = pci_find_capability(dev, PCI_CAP_ID_EXP); - quirk_aspm_offset[GET_INDEX(pdev->device, dev->devfn)] = cap_base + 0x10; - } - pbus->ops = &quirk_pcie_aspm_ops; + quirk_aspm_offset[GET_INDEX(pdev->device, dev->devfn)] = + dev->pcie_cap + PCI_EXP_LNKCTL; + + pci_bus_set_ops(pbus, &quirk_pcie_aspm_ops); + dev_info(&pbus->dev, "writes to ASPM control bits will be ignored\n"); } + } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PA, pcie_rootport_aspm_quirk); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PA1, pcie_rootport_aspm_quirk); diff --git a/arch/x86/pci/mrst.c b/arch/x86/pci/intel_mid_pci.c index 903fded50786..51384ca727ad 100644 --- a/arch/x86/pci/mrst.c +++ b/arch/x86/pci/intel_mid_pci.c @@ -1,5 +1,5 @@ /* - * Moorestown PCI support + * Intel MID PCI support * Copyright (c) 2008 Intel Corporation * Jesse Barnes <jesse.barnes@intel.com> * @@ -150,12 +150,12 @@ static bool type1_access_ok(unsigned int bus, unsigned int devfn, int reg) * shim. Therefore, use the header type in shim instead. */ if (reg >= 0x100 || reg == PCI_STATUS || reg == PCI_HEADER_TYPE) - return 0; + return false; if (bus == 0 && (devfn == PCI_DEVFN(2, 0) || devfn == PCI_DEVFN(0, 0) || devfn == PCI_DEVFN(3, 0))) - return 1; - return 0; /* Langwell on others */ + return true; + return false; /* Langwell on others */ } static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, @@ -205,7 +205,7 @@ static int pci_write(struct pci_bus *bus, unsigned int devfn, int where, where, size, value); } -static int mrst_pci_irq_enable(struct pci_dev *dev) +static int intel_mid_pci_irq_enable(struct pci_dev *dev) { u8 pin; struct io_apic_irq_attr irq_attr; @@ -225,23 +225,23 @@ static int mrst_pci_irq_enable(struct pci_dev *dev) return 0; } -struct pci_ops pci_mrst_ops = { +struct pci_ops intel_mid_pci_ops = { .read = pci_read, .write = pci_write, }; /** - * pci_mrst_init - installs pci_mrst_ops + * intel_mid_pci_init - installs intel_mid_pci_ops * * Moorestown has an interesting PCI implementation (see above). * Called when the early platform detection installs it. */ -int __init pci_mrst_init(void) +int __init intel_mid_pci_init(void) { pr_info("Intel MID platform detected, using MID PCI ops\n"); pci_mmcfg_late_init(); - pcibios_enable_irq = mrst_pci_irq_enable; - pci_root_ops = pci_mrst_ops; + pcibios_enable_irq = intel_mid_pci_irq_enable; + pci_root_ops = intel_mid_pci_ops; pci_soc_mode = 1; /* Continue with standard init */ return 1; diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index 48e8461057ba..5eee4959785d 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c @@ -382,7 +382,14 @@ static void xen_teardown_msi_irq(unsigned int irq) { xen_destroy_irq(irq); } - +static u32 xen_nop_msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag) +{ + return 0; +} +static u32 xen_nop_msix_mask_irq(struct msi_desc *desc, u32 flag) +{ + return 0; +} #endif int __init pci_xen_init(void) @@ -406,6 +413,8 @@ int __init pci_xen_init(void) x86_msi.setup_msi_irqs = xen_setup_msi_irqs; x86_msi.teardown_msi_irq = xen_teardown_msi_irq; x86_msi.teardown_msi_irqs = xen_teardown_msi_irqs; + x86_msi.msi_mask_irq = xen_nop_msi_mask_irq; + x86_msi.msix_mask_irq = xen_nop_msix_mask_irq; #endif return 0; } @@ -485,6 +494,8 @@ int __init pci_xen_initial_domain(void) x86_msi.setup_msi_irqs = xen_initdom_setup_msi_irqs; x86_msi.teardown_msi_irq = xen_teardown_msi_irq; x86_msi.restore_msi_irqs = xen_initdom_restore_msi_irqs; + x86_msi.msi_mask_irq = xen_nop_msi_mask_irq; + x86_msi.msix_mask_irq = xen_nop_msix_mask_irq; #endif xen_setup_acpi_sci(); __acpi_register_gsi = acpi_register_gsi_xen; diff --git a/arch/x86/platform/Makefile b/arch/x86/platform/Makefile index 01e0231a113e..20342d4c82ce 100644 --- a/arch/x86/platform/Makefile +++ b/arch/x86/platform/Makefile @@ -4,7 +4,7 @@ obj-y += efi/ obj-y += geode/ obj-y += goldfish/ obj-y += iris/ -obj-y += mrst/ +obj-y += intel-mid/ obj-y += olpc/ obj-y += scx200/ obj-y += sfi/ diff --git a/arch/x86/platform/efi/Makefile b/arch/x86/platform/efi/Makefile index 6db1cc4c7534..b7b0b35c1981 100644 --- a/arch/x86/platform/efi/Makefile +++ b/arch/x86/platform/efi/Makefile @@ -1,2 +1,3 @@ obj-$(CONFIG_EFI) += efi.o efi_$(BITS).o efi_stub_$(BITS).o obj-$(CONFIG_ACPI_BGRT) += efi-bgrt.o +obj-$(CONFIG_EARLY_PRINTK_EFI) += early_printk.o diff --git a/arch/x86/platform/efi/early_printk.c b/arch/x86/platform/efi/early_printk.c new file mode 100644 index 000000000000..6599a0027b76 --- /dev/null +++ b/arch/x86/platform/efi/early_printk.c @@ -0,0 +1,191 @@ +/* + * Copyright (C) 2013 Intel Corporation; author Matt Fleming + * + * This file is part of the Linux kernel, and is made available under + * the terms of the GNU General Public License version 2. + */ + +#include <linux/console.h> +#include <linux/efi.h> +#include <linux/font.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <asm/setup.h> + +static const struct font_desc *font; +static u32 efi_x, efi_y; + +static __init void early_efi_clear_scanline(unsigned int y) +{ + unsigned long base, *dst; + u16 len; + + base = boot_params.screen_info.lfb_base; + len = boot_params.screen_info.lfb_linelength; + + dst = early_ioremap(base + y*len, len); + if (!dst) + return; + + memset(dst, 0, len); + early_iounmap(dst, len); +} + +static __init void early_efi_scroll_up(void) +{ + unsigned long base, *dst, *src; + u16 len; + u32 i, height; + + base = boot_params.screen_info.lfb_base; + len = boot_params.screen_info.lfb_linelength; + height = boot_params.screen_info.lfb_height; + + for (i = 0; i < height - font->height; i++) { + dst = early_ioremap(base + i*len, len); + if (!dst) + return; + + src = early_ioremap(base + (i + font->height) * len, len); + if (!src) { + early_iounmap(dst, len); + return; + } + + memmove(dst, src, len); + + early_iounmap(src, len); + early_iounmap(dst, len); + } +} + +static void early_efi_write_char(u32 *dst, unsigned char c, unsigned int h) +{ + const u32 color_black = 0x00000000; + const u32 color_white = 0x00ffffff; + const u8 *src; + u8 s8; + int m; + + src = font->data + c * font->height; + s8 = *(src + h); + + for (m = 0; m < 8; m++) { + if ((s8 >> (7 - m)) & 1) + *dst = color_white; + else + *dst = color_black; + dst++; + } +} + +static __init void +early_efi_write(struct console *con, const char *str, unsigned int num) +{ + struct screen_info *si; + unsigned long base; + unsigned int len; + const char *s; + void *dst; + + base = boot_params.screen_info.lfb_base; + si = &boot_params.screen_info; + len = si->lfb_linelength; + + while (num) { + unsigned int linemax; + unsigned int h, count = 0; + + for (s = str; *s && *s != '\n'; s++) { + if (count == num) + break; + count++; + } + + linemax = (si->lfb_width - efi_x) / font->width; + if (count > linemax) + count = linemax; + + for (h = 0; h < font->height; h++) { + unsigned int n, x; + + dst = early_ioremap(base + (efi_y + h) * len, len); + if (!dst) + return; + + s = str; + n = count; + x = efi_x; + + while (n-- > 0) { + early_efi_write_char(dst + x*4, *s, h); + x += font->width; + s++; + } + + early_iounmap(dst, len); + } + + num -= count; + efi_x += count * font->width; + str += count; + + if (num > 0 && *s == '\n') { + efi_x = 0; + efi_y += font->height; + str++; + num--; + } + + if (efi_x >= si->lfb_width) { + efi_x = 0; + efi_y += font->height; + } + + if (efi_y + font->height >= si->lfb_height) { + u32 i; + + efi_y -= font->height; + early_efi_scroll_up(); + + for (i = 0; i < font->height; i++) + early_efi_clear_scanline(efi_y + i); + } + } +} + +static __init int early_efi_setup(struct console *con, char *options) +{ + struct screen_info *si; + u16 xres, yres; + u32 i; + + si = &boot_params.screen_info; + xres = si->lfb_width; + yres = si->lfb_height; + + /* + * early_efi_write_char() implicitly assumes a framebuffer with + * 32-bits per pixel. + */ + if (si->lfb_depth != 32) + return -ENODEV; + + font = get_default_font(xres, yres, -1, -1); + if (!font) + return -ENODEV; + + efi_y = rounddown(yres, font->height) - font->height; + for (i = 0; i < (yres - efi_y) / font->height; i++) + early_efi_scroll_up(); + + return 0; +} + +struct console early_efi_console = { + .name = "earlyefi", + .write = early_efi_write, + .setup = early_efi_setup, + .flags = CON_PRINTBUFFER, + .index = -1, +}; diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index c7e22ab29a5a..92c02344a060 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c @@ -60,19 +60,6 @@ static efi_char16_t efi_dummy_name[6] = { 'D', 'U', 'M', 'M', 'Y', 0 }; -struct efi __read_mostly efi = { - .mps = EFI_INVALID_TABLE_ADDR, - .acpi = EFI_INVALID_TABLE_ADDR, - .acpi20 = EFI_INVALID_TABLE_ADDR, - .smbios = EFI_INVALID_TABLE_ADDR, - .sal_systab = EFI_INVALID_TABLE_ADDR, - .boot_info = EFI_INVALID_TABLE_ADDR, - .hcdp = EFI_INVALID_TABLE_ADDR, - .uga = EFI_INVALID_TABLE_ADDR, - .uv_systab = EFI_INVALID_TABLE_ADDR, -}; -EXPORT_SYMBOL(efi); - struct efi_memory_map memmap; static struct efi efi_phys __initdata; @@ -80,6 +67,13 @@ static efi_system_table_t efi_systab __initdata; unsigned long x86_efi_facility; +static __initdata efi_config_table_type_t arch_tables[] = { +#ifdef CONFIG_X86_UV + {UV_SYSTEM_TABLE_GUID, "UVsystab", &efi.uv_systab}, +#endif + {NULL_GUID, NULL, NULL}, +}; + /* * Returns 1 if 'facility' is enabled, 0 otherwise. */ @@ -399,6 +393,8 @@ int __init efi_memblock_x86_reserve_range(void) memblock_reserve(pmap, memmap.nr_map * memmap.desc_size); + efi.memmap = &memmap; + return 0; } @@ -578,80 +574,6 @@ static int __init efi_systab_init(void *phys) return 0; } -static int __init efi_config_init(u64 tables, int nr_tables) -{ - void *config_tables, *tablep; - int i, sz; - - if (efi_enabled(EFI_64BIT)) - sz = sizeof(efi_config_table_64_t); - else - sz = sizeof(efi_config_table_32_t); - - /* - * Let's see what config tables the firmware passed to us. - */ - config_tables = early_ioremap(tables, nr_tables * sz); - if (config_tables == NULL) { - pr_err("Could not map Configuration table!\n"); - return -ENOMEM; - } - - tablep = config_tables; - pr_info(""); - for (i = 0; i < efi.systab->nr_tables; i++) { - efi_guid_t guid; - unsigned long table; - - if (efi_enabled(EFI_64BIT)) { - u64 table64; - guid = ((efi_config_table_64_t *)tablep)->guid; - table64 = ((efi_config_table_64_t *)tablep)->table; - table = table64; -#ifdef CONFIG_X86_32 - if (table64 >> 32) { - pr_cont("\n"); - pr_err("Table located above 4GB, disabling EFI.\n"); - early_iounmap(config_tables, - efi.systab->nr_tables * sz); - return -EINVAL; - } -#endif - } else { - guid = ((efi_config_table_32_t *)tablep)->guid; - table = ((efi_config_table_32_t *)tablep)->table; - } - if (!efi_guidcmp(guid, MPS_TABLE_GUID)) { - efi.mps = table; - pr_cont(" MPS=0x%lx ", table); - } else if (!efi_guidcmp(guid, ACPI_20_TABLE_GUID)) { - efi.acpi20 = table; - pr_cont(" ACPI 2.0=0x%lx ", table); - } else if (!efi_guidcmp(guid, ACPI_TABLE_GUID)) { - efi.acpi = table; - pr_cont(" ACPI=0x%lx ", table); - } else if (!efi_guidcmp(guid, SMBIOS_TABLE_GUID)) { - efi.smbios = table; - pr_cont(" SMBIOS=0x%lx ", table); -#ifdef CONFIG_X86_UV - } else if (!efi_guidcmp(guid, UV_SYSTEM_TABLE_GUID)) { - efi.uv_systab = table; - pr_cont(" UVsystab=0x%lx ", table); -#endif - } else if (!efi_guidcmp(guid, HCDP_TABLE_GUID)) { - efi.hcdp = table; - pr_cont(" HCDP=0x%lx ", table); - } else if (!efi_guidcmp(guid, UGA_IO_PROTOCOL_GUID)) { - efi.uga = table; - pr_cont(" UGA=0x%lx ", table); - } - tablep += sz; - } - pr_cont("\n"); - early_iounmap(config_tables, efi.systab->nr_tables * sz); - return 0; -} - static int __init efi_runtime_init(void) { efi_runtime_services_t *runtime; @@ -745,7 +667,7 @@ void __init efi_init(void) efi.systab->hdr.revision >> 16, efi.systab->hdr.revision & 0xffff, vendor); - if (efi_config_init(efi.systab->tables, efi.systab->nr_tables)) + if (efi_config_init(arch_tables)) return; set_bit(EFI_CONFIG_TABLES, &x86_efi_facility); @@ -816,34 +738,6 @@ static void __init runtime_code_page_mkexec(void) } } -/* - * We can't ioremap data in EFI boot services RAM, because we've already mapped - * it as RAM. So, look it up in the existing EFI memory map instead. Only - * callable after efi_enter_virtual_mode and before efi_free_boot_services. - */ -void __iomem *efi_lookup_mapped_addr(u64 phys_addr) -{ - void *p; - if (WARN_ON(!memmap.map)) - return NULL; - for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { - efi_memory_desc_t *md = p; - u64 size = md->num_pages << EFI_PAGE_SHIFT; - u64 end = md->phys_addr + size; - if (!(md->attribute & EFI_MEMORY_RUNTIME) && - md->type != EFI_BOOT_SERVICES_CODE && - md->type != EFI_BOOT_SERVICES_DATA) - continue; - if (!md->virt_addr) - continue; - if (phys_addr >= md->phys_addr && phys_addr < end) { - phys_addr += md->virt_addr - md->phys_addr; - return (__force void __iomem *)(unsigned long)phys_addr; - } - } - return NULL; -} - void efi_memory_uc(u64 addr, unsigned long size) { unsigned long page_shift = 1UL << EFI_PAGE_SHIFT; diff --git a/arch/x86/platform/geode/alix.c b/arch/x86/platform/geode/alix.c index 90e23e7679a5..76b6632d3143 100644 --- a/arch/x86/platform/geode/alix.c +++ b/arch/x86/platform/geode/alix.c @@ -98,7 +98,7 @@ static struct platform_device alix_leds_dev = { .dev.platform_data = &alix_leds_data, }; -static struct __initdata platform_device *alix_devs[] = { +static struct platform_device *alix_devs[] __initdata = { &alix_buttons_dev, &alix_leds_dev, }; diff --git a/arch/x86/platform/geode/geos.c b/arch/x86/platform/geode/geos.c index c2e6d53558be..aa733fba2471 100644 --- a/arch/x86/platform/geode/geos.c +++ b/arch/x86/platform/geode/geos.c @@ -87,7 +87,7 @@ static struct platform_device geos_leds_dev = { .dev.platform_data = &geos_leds_data, }; -static struct __initdata platform_device *geos_devs[] = { +static struct platform_device *geos_devs[] __initdata = { &geos_buttons_dev, &geos_leds_dev, }; diff --git a/arch/x86/platform/geode/net5501.c b/arch/x86/platform/geode/net5501.c index 646e3b5b4bb6..927e38c0089f 100644 --- a/arch/x86/platform/geode/net5501.c +++ b/arch/x86/platform/geode/net5501.c @@ -78,7 +78,7 @@ static struct platform_device net5501_leds_dev = { .dev.platform_data = &net5501_leds_data, }; -static struct __initdata platform_device *net5501_devs[] = { +static struct platform_device *net5501_devs[] __initdata = { &net5501_buttons_dev, &net5501_leds_dev, }; diff --git a/arch/x86/platform/intel-mid/Makefile b/arch/x86/platform/intel-mid/Makefile new file mode 100644 index 000000000000..01cc29ea5ff7 --- /dev/null +++ b/arch/x86/platform/intel-mid/Makefile @@ -0,0 +1,7 @@ +obj-$(CONFIG_X86_INTEL_MID) += intel-mid.o +obj-$(CONFIG_X86_INTEL_MID) += intel_mid_vrtc.o +obj-$(CONFIG_EARLY_PRINTK_INTEL_MID) += early_printk_intel_mid.o +# SFI specific code +ifdef CONFIG_X86_INTEL_MID +obj-$(CONFIG_SFI) += sfi.o device_libs/ +endif diff --git a/arch/x86/platform/intel-mid/device_libs/Makefile b/arch/x86/platform/intel-mid/device_libs/Makefile new file mode 100644 index 000000000000..097e7a7940d8 --- /dev/null +++ b/arch/x86/platform/intel-mid/device_libs/Makefile @@ -0,0 +1,22 @@ +# IPC Devices +obj-y += platform_ipc.o +obj-$(subst m,y,$(CONFIG_MFD_INTEL_MSIC)) += platform_msic.o +obj-$(subst m,y,$(CONFIG_SND_MFLD_MACHINE)) += platform_msic_audio.o +obj-$(subst m,y,$(CONFIG_GPIO_MSIC)) += platform_msic_gpio.o +obj-$(subst m,y,$(CONFIG_MFD_INTEL_MSIC)) += platform_msic_ocd.o +obj-$(subst m,y,$(CONFIG_MFD_INTEL_MSIC)) += platform_msic_battery.o +obj-$(subst m,y,$(CONFIG_INTEL_MID_POWER_BUTTON)) += platform_msic_power_btn.o +obj-$(subst m,y,$(CONFIG_GPIO_INTEL_PMIC)) += platform_pmic_gpio.o +obj-$(subst m,y,$(CONFIG_INTEL_MFLD_THERMAL)) += platform_msic_thermal.o +# I2C Devices +obj-$(subst m,y,$(CONFIG_SENSORS_EMC1403)) += platform_emc1403.o +obj-$(subst m,y,$(CONFIG_SENSORS_LIS3LV02D)) += platform_lis331.o +obj-$(subst m,y,$(CONFIG_GPIO_PCA953X)) += platform_max7315.o +obj-$(subst m,y,$(CONFIG_INPUT_MPU3050)) += platform_mpu3050.o +obj-$(subst m,y,$(CONFIG_INPUT_BMA150)) += platform_bma023.o +obj-$(subst m,y,$(CONFIG_GPIO_PCA953X)) += platform_tca6416.o +obj-$(subst m,y,$(CONFIG_DRM_MEDFIELD)) += platform_tc35876x.o +# SPI Devices +obj-$(subst m,y,$(CONFIG_SERIAL_MRST_MAX3110)) += platform_max3111.o +# MISC Devices +obj-$(subst m,y,$(CONFIG_KEYBOARD_GPIO)) += platform_gpio_keys.o diff --git a/arch/x86/platform/intel-mid/device_libs/platform_bma023.c b/arch/x86/platform/intel-mid/device_libs/platform_bma023.c new file mode 100644 index 000000000000..0ae7f2ae2296 --- /dev/null +++ b/arch/x86/platform/intel-mid/device_libs/platform_bma023.c @@ -0,0 +1,20 @@ +/* + * platform_bma023.c: bma023 platform data initilization file + * + * (C) Copyright 2013 Intel Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + */ + +#include <asm/intel-mid.h> + +static const struct devs_id bma023_dev_id __initconst = { + .name = "bma023", + .type = SFI_DEV_TYPE_I2C, + .delay = 1, +}; + +sfi_device(bma023_dev_id); diff --git a/arch/x86/platform/intel-mid/device_libs/platform_emc1403.c b/arch/x86/platform/intel-mid/device_libs/platform_emc1403.c new file mode 100644 index 000000000000..0d942c1d26d5 --- /dev/null +++ b/arch/x86/platform/intel-mid/device_libs/platform_emc1403.c @@ -0,0 +1,41 @@ +/* + * platform_emc1403.c: emc1403 platform data initilization file + * + * (C) Copyright 2013 Intel Corporation + * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + */ + +#include <linux/init.h> +#include <linux/gpio.h> +#include <linux/i2c.h> +#include <asm/intel-mid.h> + +static void __init *emc1403_platform_data(void *info) +{ + static short intr2nd_pdata; + struct i2c_board_info *i2c_info = info; + int intr = get_gpio_by_name("thermal_int"); + int intr2nd = get_gpio_by_name("thermal_alert"); + + if (intr == -1 || intr2nd == -1) + return NULL; + + i2c_info->irq = intr + INTEL_MID_IRQ_OFFSET; + intr2nd_pdata = intr2nd + INTEL_MID_IRQ_OFFSET; + + return &intr2nd_pdata; +} + +static const struct devs_id emc1403_dev_id __initconst = { + .name = "emc1403", + .type = SFI_DEV_TYPE_I2C, + .delay = 1, + .get_platform_data = &emc1403_platform_data, +}; + +sfi_device(emc1403_dev_id); diff --git a/arch/x86/platform/intel-mid/device_libs/platform_gpio_keys.c b/arch/x86/platform/intel-mid/device_libs/platform_gpio_keys.c new file mode 100644 index 000000000000..a013a4834bbe --- /dev/null +++ b/arch/x86/platform/intel-mid/device_libs/platform_gpio_keys.c @@ -0,0 +1,83 @@ +/* + * platform_gpio_keys.c: gpio_keys platform data initilization file + * + * (C) Copyright 2013 Intel Corporation + * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + */ + +#include <linux/input.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/gpio.h> +#include <linux/gpio_keys.h> +#include <linux/platform_device.h> +#include <asm/intel-mid.h> + +#define DEVICE_NAME "gpio-keys" + +/* + * we will search these buttons in SFI GPIO table (by name) + * and register them dynamically. Please add all possible + * buttons here, we will shrink them if no GPIO found. + */ +static struct gpio_keys_button gpio_button[] = { + {KEY_POWER, -1, 1, "power_btn", EV_KEY, 0, 3000}, + {KEY_PROG1, -1, 1, "prog_btn1", EV_KEY, 0, 20}, + {KEY_PROG2, -1, 1, "prog_btn2", EV_KEY, 0, 20}, + {SW_LID, -1, 1, "lid_switch", EV_SW, 0, 20}, + {KEY_VOLUMEUP, -1, 1, "vol_up", EV_KEY, 0, 20}, + {KEY_VOLUMEDOWN, -1, 1, "vol_down", EV_KEY, 0, 20}, + {KEY_CAMERA, -1, 1, "camera_full", EV_KEY, 0, 20}, + {KEY_CAMERA_FOCUS, -1, 1, "camera_half", EV_KEY, 0, 20}, + {SW_KEYPAD_SLIDE, -1, 1, "MagSw1", EV_SW, 0, 20}, + {SW_KEYPAD_SLIDE, -1, 1, "MagSw2", EV_SW, 0, 20}, +}; + +static struct gpio_keys_platform_data gpio_keys = { + .buttons = gpio_button, + .rep = 1, + .nbuttons = -1, /* will fill it after search */ +}; + +static struct platform_device pb_device = { + .name = DEVICE_NAME, + .id = -1, + .dev = { + .platform_data = &gpio_keys, + }, +}; + +/* + * Shrink the non-existent buttons, register the gpio button + * device if there is some + */ +static int __init pb_keys_init(void) +{ + struct gpio_keys_button *gb = gpio_button; + int i, num, good = 0; + + num = sizeof(gpio_button) / sizeof(struct gpio_keys_button); + for (i = 0; i < num; i++) { + gb[i].gpio = get_gpio_by_name(gb[i].desc); + pr_debug("info[%2d]: name = %s, gpio = %d\n", i, gb[i].desc, + gb[i].gpio); + if (gb[i].gpio == -1) + continue; + + if (i != good) + gb[good] = gb[i]; + good++; + } + + if (good) { + gpio_keys.nbuttons = good; + return platform_device_register(&pb_device); + } + return 0; +} +late_initcall(pb_keys_init); diff --git a/arch/x86/platform/intel-mid/device_libs/platform_ipc.c b/arch/x86/platform/intel-mid/device_libs/platform_ipc.c new file mode 100644 index 000000000000..a84b73d6c4a0 --- /dev/null +++ b/arch/x86/platform/intel-mid/device_libs/platform_ipc.c @@ -0,0 +1,68 @@ +/* + * platform_ipc.c: IPC platform library file + * + * (C) Copyright 2013 Intel Corporation + * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/sfi.h> +#include <linux/gpio.h> +#include <asm/intel-mid.h> +#include "platform_ipc.h" + +void __init ipc_device_handler(struct sfi_device_table_entry *pentry, + struct devs_id *dev) +{ + struct platform_device *pdev; + void *pdata = NULL; + static struct resource res __initdata = { + .name = "IRQ", + .flags = IORESOURCE_IRQ, + }; + + pr_debug("IPC bus, name = %16.16s, irq = 0x%2x\n", + pentry->name, pentry->irq); + + /* + * We need to call platform init of IPC devices to fill misc_pdata + * structure. It will be used in msic_init for initialization. + */ + if (dev != NULL) + pdata = dev->get_platform_data(pentry); + + /* + * On Medfield the platform device creation is handled by the MSIC + * MFD driver so we don't need to do it here. + */ + if (intel_mid_has_msic()) + return; + + pdev = platform_device_alloc(pentry->name, 0); + if (pdev == NULL) { + pr_err("out of memory for SFI platform device '%s'.\n", + pentry->name); + return; + } + res.start = pentry->irq; + platform_device_add_resources(pdev, &res, 1); + + pdev->dev.platform_data = pdata; + intel_scu_device_register(pdev); +} + +static const struct devs_id pmic_audio_dev_id __initconst = { + .name = "pmic_audio", + .type = SFI_DEV_TYPE_IPC, + .delay = 1, + .device_handler = &ipc_device_handler, +}; + +sfi_device(pmic_audio_dev_id); diff --git a/arch/x86/platform/intel-mid/device_libs/platform_ipc.h b/arch/x86/platform/intel-mid/device_libs/platform_ipc.h new file mode 100644 index 000000000000..8f568dd79605 --- /dev/null +++ b/arch/x86/platform/intel-mid/device_libs/platform_ipc.h @@ -0,0 +1,17 @@ +/* + * platform_ipc.h: IPC platform library header file + * + * (C) Copyright 2013 Intel Corporation + * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + */ +#ifndef _PLATFORM_IPC_H_ +#define _PLATFORM_IPC_H_ + +extern void __init ipc_device_handler(struct sfi_device_table_entry *pentry, + struct devs_id *dev) __attribute__((weak)); +#endif diff --git a/arch/x86/platform/intel-mid/device_libs/platform_lis331.c b/arch/x86/platform/intel-mid/device_libs/platform_lis331.c new file mode 100644 index 000000000000..15278c11f714 --- /dev/null +++ b/arch/x86/platform/intel-mid/device_libs/platform_lis331.c @@ -0,0 +1,39 @@ +/* + * platform_lis331.c: lis331 platform data initilization file + * + * (C) Copyright 2013 Intel Corporation + * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + */ + +#include <linux/i2c.h> +#include <linux/gpio.h> +#include <asm/intel-mid.h> + +static void __init *lis331dl_platform_data(void *info) +{ + static short intr2nd_pdata; + struct i2c_board_info *i2c_info = info; + int intr = get_gpio_by_name("accel_int"); + int intr2nd = get_gpio_by_name("accel_2"); + + if (intr == -1 || intr2nd == -1) + return NULL; + + i2c_info->irq = intr + INTEL_MID_IRQ_OFFSET; + intr2nd_pdata = intr2nd + INTEL_MID_IRQ_OFFSET; + + return &intr2nd_pdata; +} + +static const struct devs_id lis331dl_dev_id __initconst = { + .name = "i2c_accel", + .type = SFI_DEV_TYPE_I2C, + .get_platform_data = &lis331dl_platform_data, +}; + +sfi_device(lis331dl_dev_id); diff --git a/arch/x86/platform/intel-mid/device_libs/platform_max3111.c b/arch/x86/platform/intel-mid/device_libs/platform_max3111.c new file mode 100644 index 000000000000..afd1df94e0e5 --- /dev/null +++ b/arch/x86/platform/intel-mid/device_libs/platform_max3111.c @@ -0,0 +1,35 @@ +/* + * platform_max3111.c: max3111 platform data initilization file + * + * (C) Copyright 2013 Intel Corporation + * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + */ + +#include <linux/gpio.h> +#include <linux/spi/spi.h> +#include <asm/intel-mid.h> + +static void __init *max3111_platform_data(void *info) +{ + struct spi_board_info *spi_info = info; + int intr = get_gpio_by_name("max3111_int"); + + spi_info->mode = SPI_MODE_0; + if (intr == -1) + return NULL; + spi_info->irq = intr + INTEL_MID_IRQ_OFFSET; + return NULL; +} + +static const struct devs_id max3111_dev_id __initconst = { + .name = "spi_max3111", + .type = SFI_DEV_TYPE_SPI, + .get_platform_data = &max3111_platform_data, +}; + +sfi_device(max3111_dev_id); diff --git a/arch/x86/platform/intel-mid/device_libs/platform_max7315.c b/arch/x86/platform/intel-mid/device_libs/platform_max7315.c new file mode 100644 index 000000000000..94ade10024ae --- /dev/null +++ b/arch/x86/platform/intel-mid/device_libs/platform_max7315.c @@ -0,0 +1,79 @@ +/* + * platform_max7315.c: max7315 platform data initilization file + * + * (C) Copyright 2013 Intel Corporation + * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + */ + +#include <linux/init.h> +#include <linux/gpio.h> +#include <linux/i2c.h> +#include <linux/platform_data/pca953x.h> +#include <asm/intel-mid.h> + +#define MAX7315_NUM 2 + +static void __init *max7315_platform_data(void *info) +{ + static struct pca953x_platform_data max7315_pdata[MAX7315_NUM]; + static int nr; + struct pca953x_platform_data *max7315 = &max7315_pdata[nr]; + struct i2c_board_info *i2c_info = info; + int gpio_base, intr; + char base_pin_name[SFI_NAME_LEN + 1]; + char intr_pin_name[SFI_NAME_LEN + 1]; + + if (nr == MAX7315_NUM) { + pr_err("too many max7315s, we only support %d\n", + MAX7315_NUM); + return NULL; + } + /* we have several max7315 on the board, we only need load several + * instances of the same pca953x driver to cover them + */ + strcpy(i2c_info->type, "max7315"); + if (nr++) { + sprintf(base_pin_name, "max7315_%d_base", nr); + sprintf(intr_pin_name, "max7315_%d_int", nr); + } else { + strcpy(base_pin_name, "max7315_base"); + strcpy(intr_pin_name, "max7315_int"); + } + + gpio_base = get_gpio_by_name(base_pin_name); + intr = get_gpio_by_name(intr_pin_name); + + if (gpio_base == -1) + return NULL; + max7315->gpio_base = gpio_base; + if (intr != -1) { + i2c_info->irq = intr + INTEL_MID_IRQ_OFFSET; + max7315->irq_base = gpio_base + INTEL_MID_IRQ_OFFSET; + } else { + i2c_info->irq = -1; + max7315->irq_base = -1; + } + return max7315; +} + +static const struct devs_id max7315_dev_id __initconst = { + .name = "i2c_max7315", + .type = SFI_DEV_TYPE_I2C, + .delay = 1, + .get_platform_data = &max7315_platform_data, +}; + +static const struct devs_id max7315_2_dev_id __initconst = { + .name = "i2c_max7315_2", + .type = SFI_DEV_TYPE_I2C, + .delay = 1, + .get_platform_data = &max7315_platform_data, +}; + +sfi_device(max7315_dev_id); +sfi_device(max7315_2_dev_id); diff --git a/arch/x86/platform/intel-mid/device_libs/platform_mpu3050.c b/arch/x86/platform/intel-mid/device_libs/platform_mpu3050.c new file mode 100644 index 000000000000..dd28d63c84fb --- /dev/null +++ b/arch/x86/platform/intel-mid/device_libs/platform_mpu3050.c @@ -0,0 +1,36 @@ +/* + * platform_mpu3050.c: mpu3050 platform data initilization file + * + * (C) Copyright 2013 Intel Corporation + * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + */ + +#include <linux/gpio.h> +#include <linux/i2c.h> +#include <asm/intel-mid.h> + +static void *mpu3050_platform_data(void *info) +{ + struct i2c_board_info *i2c_info = info; + int intr = get_gpio_by_name("mpu3050_int"); + + if (intr == -1) + return NULL; + + i2c_info->irq = intr + INTEL_MID_IRQ_OFFSET; + return NULL; +} + +static const struct devs_id mpu3050_dev_id __initconst = { + .name = "mpu3050", + .type = SFI_DEV_TYPE_I2C, + .delay = 1, + .get_platform_data = &mpu3050_platform_data, +}; + +sfi_device(mpu3050_dev_id); diff --git a/arch/x86/platform/intel-mid/device_libs/platform_msic.c b/arch/x86/platform/intel-mid/device_libs/platform_msic.c new file mode 100644 index 000000000000..9f4a775a69d6 --- /dev/null +++ b/arch/x86/platform/intel-mid/device_libs/platform_msic.c @@ -0,0 +1,87 @@ +/* + * platform_msic.c: MSIC platform data initilization file + * + * (C) Copyright 2013 Intel Corporation + * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + */ + +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/scatterlist.h> +#include <linux/init.h> +#include <linux/sfi.h> +#include <linux/mfd/intel_msic.h> +#include <asm/intel_scu_ipc.h> +#include <asm/intel-mid.h> +#include "platform_msic.h" + +struct intel_msic_platform_data msic_pdata; + +static struct resource msic_resources[] = { + { + .start = INTEL_MSIC_IRQ_PHYS_BASE, + .end = INTEL_MSIC_IRQ_PHYS_BASE + 64 - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device msic_device = { + .name = "intel_msic", + .id = -1, + .dev = { + .platform_data = &msic_pdata, + }, + .num_resources = ARRAY_SIZE(msic_resources), + .resource = msic_resources, +}; + +static int msic_scu_status_change(struct notifier_block *nb, + unsigned long code, void *data) +{ + if (code == SCU_DOWN) { + platform_device_unregister(&msic_device); + return 0; + } + + return platform_device_register(&msic_device); +} + +static int __init msic_init(void) +{ + static struct notifier_block msic_scu_notifier = { + .notifier_call = msic_scu_status_change, + }; + + /* + * We need to be sure that the SCU IPC is ready before MSIC device + * can be registered. + */ + if (intel_mid_has_msic()) + intel_scu_notifier_add(&msic_scu_notifier); + + return 0; +} +arch_initcall(msic_init); + +/* + * msic_generic_platform_data - sets generic platform data for the block + * @info: pointer to the SFI device table entry for this block + * @block: MSIC block + * + * Function sets IRQ number from the SFI table entry for given device to + * the MSIC platform data. + */ +void *msic_generic_platform_data(void *info, enum intel_msic_block block) +{ + struct sfi_device_table_entry *entry = info; + + BUG_ON(block < 0 || block >= INTEL_MSIC_BLOCK_LAST); + msic_pdata.irq[block] = entry->irq; + + return NULL; +} diff --git a/arch/x86/platform/intel-mid/device_libs/platform_msic.h b/arch/x86/platform/intel-mid/device_libs/platform_msic.h new file mode 100644 index 000000000000..917eb56d77da --- /dev/null +++ b/arch/x86/platform/intel-mid/device_libs/platform_msic.h @@ -0,0 +1,19 @@ +/* + * platform_msic.h: MSIC platform data header file + * + * (C) Copyright 2013 Intel Corporation + * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + */ +#ifndef _PLATFORM_MSIC_H_ +#define _PLATFORM_MSIC_H_ + +extern struct intel_msic_platform_data msic_pdata; + +extern void *msic_generic_platform_data(void *info, + enum intel_msic_block block) __attribute__((weak)); +#endif diff --git a/arch/x86/platform/intel-mid/device_libs/platform_msic_audio.c b/arch/x86/platform/intel-mid/device_libs/platform_msic_audio.c new file mode 100644 index 000000000000..29629397d2b3 --- /dev/null +++ b/arch/x86/platform/intel-mid/device_libs/platform_msic_audio.c @@ -0,0 +1,47 @@ +/* + * platform_msic_audio.c: MSIC audio platform data initilization file + * + * (C) Copyright 2013 Intel Corporation + * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + */ + +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/scatterlist.h> +#include <linux/init.h> +#include <linux/sfi.h> +#include <linux/platform_device.h> +#include <linux/mfd/intel_msic.h> +#include <asm/intel-mid.h> + +#include "platform_msic.h" +#include "platform_ipc.h" + +static void *msic_audio_platform_data(void *info) +{ + struct platform_device *pdev; + + pdev = platform_device_register_simple("sst-platform", -1, NULL, 0); + + if (IS_ERR(pdev)) { + pr_err("failed to create audio platform device\n"); + return NULL; + } + + return msic_generic_platform_data(info, INTEL_MSIC_BLOCK_AUDIO); +} + +static const struct devs_id msic_audio_dev_id __initconst = { + .name = "msic_audio", + .type = SFI_DEV_TYPE_IPC, + .delay = 1, + .get_platform_data = &msic_audio_platform_data, + .device_handler = &ipc_device_handler, +}; + +sfi_device(msic_audio_dev_id); diff --git a/arch/x86/platform/intel-mid/device_libs/platform_msic_battery.c b/arch/x86/platform/intel-mid/device_libs/platform_msic_battery.c new file mode 100644 index 000000000000..f446c33df1a8 --- /dev/null +++ b/arch/x86/platform/intel-mid/device_libs/platform_msic_battery.c @@ -0,0 +1,37 @@ +/* + * platform_msic_battery.c: MSIC battery platform data initilization file + * + * (C) Copyright 2013 Intel Corporation + * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + */ + +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/scatterlist.h> +#include <linux/init.h> +#include <linux/sfi.h> +#include <linux/mfd/intel_msic.h> +#include <asm/intel-mid.h> + +#include "platform_msic.h" +#include "platform_ipc.h" + +static void __init *msic_battery_platform_data(void *info) +{ + return msic_generic_platform_data(info, INTEL_MSIC_BLOCK_BATTERY); +} + +static const struct devs_id msic_battery_dev_id __initconst = { + .name = "msic_battery", + .type = SFI_DEV_TYPE_IPC, + .delay = 1, + .get_platform_data = &msic_battery_platform_data, + .device_handler = &ipc_device_handler, +}; + +sfi_device(msic_battery_dev_id); diff --git a/arch/x86/platform/intel-mid/device_libs/platform_msic_gpio.c b/arch/x86/platform/intel-mid/device_libs/platform_msic_gpio.c new file mode 100644 index 000000000000..2a4f7b1dd917 --- /dev/null +++ b/arch/x86/platform/intel-mid/device_libs/platform_msic_gpio.c @@ -0,0 +1,48 @@ +/* + * platform_msic_gpio.c: MSIC GPIO platform data initilization file + * + * (C) Copyright 2013 Intel Corporation + * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + */ + +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/scatterlist.h> +#include <linux/sfi.h> +#include <linux/init.h> +#include <linux/gpio.h> +#include <linux/mfd/intel_msic.h> +#include <asm/intel-mid.h> + +#include "platform_msic.h" +#include "platform_ipc.h" + +static void __init *msic_gpio_platform_data(void *info) +{ + static struct intel_msic_gpio_pdata msic_gpio_pdata; + + int gpio = get_gpio_by_name("msic_gpio_base"); + + if (gpio < 0) + return NULL; + + msic_gpio_pdata.gpio_base = gpio; + msic_pdata.gpio = &msic_gpio_pdata; + + return msic_generic_platform_data(info, INTEL_MSIC_BLOCK_GPIO); +} + +static const struct devs_id msic_gpio_dev_id __initconst = { + .name = "msic_gpio", + .type = SFI_DEV_TYPE_IPC, + .delay = 1, + .get_platform_data = &msic_gpio_platform_data, + .device_handler = &ipc_device_handler, +}; + +sfi_device(msic_gpio_dev_id); diff --git a/arch/x86/platform/intel-mid/device_libs/platform_msic_ocd.c b/arch/x86/platform/intel-mid/device_libs/platform_msic_ocd.c new file mode 100644 index 000000000000..6497111ddb54 --- /dev/null +++ b/arch/x86/platform/intel-mid/device_libs/platform_msic_ocd.c @@ -0,0 +1,49 @@ +/* + * platform_msic_ocd.c: MSIC OCD platform data initilization file + * + * (C) Copyright 2013 Intel Corporation + * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + */ + +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/scatterlist.h> +#include <linux/sfi.h> +#include <linux/init.h> +#include <linux/gpio.h> +#include <linux/mfd/intel_msic.h> +#include <asm/intel-mid.h> + +#include "platform_msic.h" +#include "platform_ipc.h" + +static void __init *msic_ocd_platform_data(void *info) +{ + static struct intel_msic_ocd_pdata msic_ocd_pdata; + int gpio; + + gpio = get_gpio_by_name("ocd_gpio"); + + if (gpio < 0) + return NULL; + + msic_ocd_pdata.gpio = gpio; + msic_pdata.ocd = &msic_ocd_pdata; + + return msic_generic_platform_data(info, INTEL_MSIC_BLOCK_OCD); +} + +static const struct devs_id msic_ocd_dev_id __initconst = { + .name = "msic_ocd", + .type = SFI_DEV_TYPE_IPC, + .delay = 1, + .get_platform_data = &msic_ocd_platform_data, + .device_handler = &ipc_device_handler, +}; + +sfi_device(msic_ocd_dev_id); diff --git a/arch/x86/platform/intel-mid/device_libs/platform_msic_power_btn.c b/arch/x86/platform/intel-mid/device_libs/platform_msic_power_btn.c new file mode 100644 index 000000000000..83a3459bc337 --- /dev/null +++ b/arch/x86/platform/intel-mid/device_libs/platform_msic_power_btn.c @@ -0,0 +1,36 @@ +/* + * platform_msic_power_btn.c: MSIC power btn platform data initilization file + * + * (C) Copyright 2013 Intel Corporation + * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + */ +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/scatterlist.h> +#include <linux/sfi.h> +#include <linux/init.h> +#include <linux/mfd/intel_msic.h> +#include <asm/intel-mid.h> + +#include "platform_msic.h" +#include "platform_ipc.h" + +static void __init *msic_power_btn_platform_data(void *info) +{ + return msic_generic_platform_data(info, INTEL_MSIC_BLOCK_POWER_BTN); +} + +static const struct devs_id msic_power_btn_dev_id __initconst = { + .name = "msic_power_btn", + .type = SFI_DEV_TYPE_IPC, + .delay = 1, + .get_platform_data = &msic_power_btn_platform_data, + .device_handler = &ipc_device_handler, +}; + +sfi_device(msic_power_btn_dev_id); diff --git a/arch/x86/platform/intel-mid/device_libs/platform_msic_thermal.c b/arch/x86/platform/intel-mid/device_libs/platform_msic_thermal.c new file mode 100644 index 000000000000..a351878b96bc --- /dev/null +++ b/arch/x86/platform/intel-mid/device_libs/platform_msic_thermal.c @@ -0,0 +1,37 @@ +/* + * platform_msic_thermal.c: msic_thermal platform data initilization file + * + * (C) Copyright 2013 Intel Corporation + * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + */ + +#include <linux/input.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/gpio.h> +#include <linux/platform_device.h> +#include <linux/mfd/intel_msic.h> +#include <asm/intel-mid.h> + +#include "platform_msic.h" +#include "platform_ipc.h" + +static void __init *msic_thermal_platform_data(void *info) +{ + return msic_generic_platform_data(info, INTEL_MSIC_BLOCK_THERMAL); +} + +static const struct devs_id msic_thermal_dev_id __initconst = { + .name = "msic_thermal", + .type = SFI_DEV_TYPE_IPC, + .delay = 1, + .get_platform_data = &msic_thermal_platform_data, + .device_handler = &ipc_device_handler, +}; + +sfi_device(msic_thermal_dev_id); diff --git a/arch/x86/platform/intel-mid/device_libs/platform_pmic_gpio.c b/arch/x86/platform/intel-mid/device_libs/platform_pmic_gpio.c new file mode 100644 index 000000000000..d87182a09263 --- /dev/null +++ b/arch/x86/platform/intel-mid/device_libs/platform_pmic_gpio.c @@ -0,0 +1,54 @@ +/* + * platform_pmic_gpio.c: PMIC GPIO platform data initilization file + * + * (C) Copyright 2013 Intel Corporation + * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + */ + +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/scatterlist.h> +#include <linux/gpio.h> +#include <linux/init.h> +#include <linux/sfi.h> +#include <linux/intel_pmic_gpio.h> +#include <asm/intel-mid.h> + +#include "platform_ipc.h" + +static void __init *pmic_gpio_platform_data(void *info) +{ + static struct intel_pmic_gpio_platform_data pmic_gpio_pdata; + int gpio_base = get_gpio_by_name("pmic_gpio_base"); + + if (gpio_base == -1) + gpio_base = 64; + pmic_gpio_pdata.gpio_base = gpio_base; + pmic_gpio_pdata.irq_base = gpio_base + INTEL_MID_IRQ_OFFSET; + pmic_gpio_pdata.gpiointr = 0xffffeff8; + + return &pmic_gpio_pdata; +} + +static const struct devs_id pmic_gpio_spi_dev_id __initconst = { + .name = "pmic_gpio", + .type = SFI_DEV_TYPE_SPI, + .delay = 1, + .get_platform_data = &pmic_gpio_platform_data, +}; + +static const struct devs_id pmic_gpio_ipc_dev_id __initconst = { + .name = "pmic_gpio", + .type = SFI_DEV_TYPE_IPC, + .delay = 1, + .get_platform_data = &pmic_gpio_platform_data, + .device_handler = &ipc_device_handler +}; + +sfi_device(pmic_gpio_spi_dev_id); +sfi_device(pmic_gpio_ipc_dev_id); diff --git a/arch/x86/platform/intel-mid/device_libs/platform_tc35876x.c b/arch/x86/platform/intel-mid/device_libs/platform_tc35876x.c new file mode 100644 index 000000000000..740fc757050c --- /dev/null +++ b/arch/x86/platform/intel-mid/device_libs/platform_tc35876x.c @@ -0,0 +1,36 @@ +/* + * platform_tc35876x.c: tc35876x platform data initilization file + * + * (C) Copyright 2013 Intel Corporation + * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + */ + +#include <linux/gpio.h> +#include <linux/i2c/tc35876x.h> +#include <asm/intel-mid.h> + +/*tc35876x DSI_LVDS bridge chip and panel platform data*/ +static void *tc35876x_platform_data(void *data) +{ + static struct tc35876x_platform_data pdata; + + /* gpio pins set to -1 will not be used by the driver */ + pdata.gpio_bridge_reset = get_gpio_by_name("LCMB_RXEN"); + pdata.gpio_panel_bl_en = get_gpio_by_name("6S6P_BL_EN"); + pdata.gpio_panel_vadd = get_gpio_by_name("EN_VREG_LCD_V3P3"); + + return &pdata; +} + +static const struct devs_id tc35876x_dev_id __initconst = { + .name = "i2c_disp_brig", + .type = SFI_DEV_TYPE_I2C, + .get_platform_data = &tc35876x_platform_data, +}; + +sfi_device(tc35876x_dev_id); diff --git a/arch/x86/platform/intel-mid/device_libs/platform_tca6416.c b/arch/x86/platform/intel-mid/device_libs/platform_tca6416.c new file mode 100644 index 000000000000..22881c9a6737 --- /dev/null +++ b/arch/x86/platform/intel-mid/device_libs/platform_tca6416.c @@ -0,0 +1,57 @@ +/* + * platform_tca6416.c: tca6416 platform data initilization file + * + * (C) Copyright 2013 Intel Corporation + * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + */ + +#include <linux/platform_data/pca953x.h> +#include <linux/i2c.h> +#include <linux/gpio.h> +#include <asm/intel-mid.h> + +#define TCA6416_NAME "tca6416" +#define TCA6416_BASE "tca6416_base" +#define TCA6416_INTR "tca6416_int" + +static void *tca6416_platform_data(void *info) +{ + static struct pca953x_platform_data tca6416; + struct i2c_board_info *i2c_info = info; + int gpio_base, intr; + char base_pin_name[SFI_NAME_LEN + 1]; + char intr_pin_name[SFI_NAME_LEN + 1]; + + strcpy(i2c_info->type, TCA6416_NAME); + strcpy(base_pin_name, TCA6416_BASE); + strcpy(intr_pin_name, TCA6416_INTR); + + gpio_base = get_gpio_by_name(base_pin_name); + intr = get_gpio_by_name(intr_pin_name); + + if (gpio_base == -1) + return NULL; + tca6416.gpio_base = gpio_base; + if (intr != -1) { + i2c_info->irq = intr + INTEL_MID_IRQ_OFFSET; + tca6416.irq_base = gpio_base + INTEL_MID_IRQ_OFFSET; + } else { + i2c_info->irq = -1; + tca6416.irq_base = -1; + } + return &tca6416; +} + +static const struct devs_id tca6416_dev_id __initconst = { + .name = "tca6416", + .type = SFI_DEV_TYPE_I2C, + .delay = 1, + .get_platform_data = &tca6416_platform_data, +}; + +sfi_device(tca6416_dev_id); diff --git a/arch/x86/platform/mrst/early_printk_mrst.c b/arch/x86/platform/intel-mid/early_printk_intel_mid.c index 028454f0c3a5..4f702f554f6e 100644 --- a/arch/x86/platform/mrst/early_printk_mrst.c +++ b/arch/x86/platform/intel-mid/early_printk_intel_mid.c @@ -1,5 +1,5 @@ /* - * early_printk_mrst.c - early consoles for Intel MID platforms + * early_printk_intel_mid.c - early consoles for Intel MID platforms * * Copyright (c) 2008-2010, Intel Corporation * @@ -27,7 +27,7 @@ #include <asm/fixmap.h> #include <asm/pgtable.h> -#include <asm/mrst.h> +#include <asm/intel-mid.h> #define MRST_SPI_TIMEOUT 0x200000 #define MRST_REGBASE_SPI0 0xff128000 @@ -152,7 +152,7 @@ void mrst_early_console_init(void) spi0_cdiv = ((*pclk_spi0) & 0xe00) >> 9; freq = 100000000 / (spi0_cdiv + 1); - if (mrst_identify_cpu() == MRST_CPU_CHIP_PENWELL) + if (intel_mid_identify_cpu() == INTEL_MID_CPU_CHIP_PENWELL) mrst_spi_paddr = MRST_REGBASE_SPI1; pspi = (void *)set_fixmap_offset_nocache(FIX_EARLYCON_MEM_BASE, @@ -213,13 +213,14 @@ static void early_mrst_spi_putc(char c) } if (!timeout) - pr_warning("MRST earlycon: timed out\n"); + pr_warn("MRST earlycon: timed out\n"); else max3110_write_data(c); } /* Early SPI only uses polling mode */ -static void early_mrst_spi_write(struct console *con, const char *str, unsigned n) +static void early_mrst_spi_write(struct console *con, const char *str, + unsigned n) { int i; diff --git a/arch/x86/platform/intel-mid/intel-mid.c b/arch/x86/platform/intel-mid/intel-mid.c new file mode 100644 index 000000000000..f90e290f689f --- /dev/null +++ b/arch/x86/platform/intel-mid/intel-mid.c @@ -0,0 +1,213 @@ +/* + * intel-mid.c: Intel MID platform setup code + * + * (C) Copyright 2008, 2012 Intel Corporation + * Author: Jacob Pan (jacob.jun.pan@intel.com) + * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + */ + +#define pr_fmt(fmt) "intel_mid: " fmt + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/scatterlist.h> +#include <linux/sfi.h> +#include <linux/irq.h> +#include <linux/module.h> +#include <linux/notifier.h> + +#include <asm/setup.h> +#include <asm/mpspec_def.h> +#include <asm/hw_irq.h> +#include <asm/apic.h> +#include <asm/io_apic.h> +#include <asm/intel-mid.h> +#include <asm/intel_mid_vrtc.h> +#include <asm/io.h> +#include <asm/i8259.h> +#include <asm/intel_scu_ipc.h> +#include <asm/apb_timer.h> +#include <asm/reboot.h> + +/* + * the clockevent devices on Moorestown/Medfield can be APBT or LAPIC clock, + * cmdline option x86_intel_mid_timer can be used to override the configuration + * to prefer one or the other. + * at runtime, there are basically three timer configurations: + * 1. per cpu apbt clock only + * 2. per cpu always-on lapic clocks only, this is Penwell/Medfield only + * 3. per cpu lapic clock (C3STOP) and one apbt clock, with broadcast. + * + * by default (without cmdline option), platform code first detects cpu type + * to see if we are on lincroft or penwell, then set up both lapic or apbt + * clocks accordingly. + * i.e. by default, medfield uses configuration #2, moorestown uses #1. + * config #3 is supported but not recommended on medfield. + * + * rating and feature summary: + * lapic (with C3STOP) --------- 100 + * apbt (always-on) ------------ 110 + * lapic (always-on,ARAT) ------ 150 + */ + +enum intel_mid_timer_options intel_mid_timer_options; + +enum intel_mid_cpu_type __intel_mid_cpu_chip; +EXPORT_SYMBOL_GPL(__intel_mid_cpu_chip); + +static void intel_mid_power_off(void) +{ +} + +static void intel_mid_reboot(void) +{ + intel_scu_ipc_simple_command(IPCMSG_COLD_BOOT, 0); +} + +static unsigned long __init intel_mid_calibrate_tsc(void) +{ + unsigned long fast_calibrate; + u32 lo, hi, ratio, fsb; + + rdmsr(MSR_IA32_PERF_STATUS, lo, hi); + pr_debug("IA32 perf status is 0x%x, 0x%0x\n", lo, hi); + ratio = (hi >> 8) & 0x1f; + pr_debug("ratio is %d\n", ratio); + if (!ratio) { + pr_err("read a zero ratio, should be incorrect!\n"); + pr_err("force tsc ratio to 16 ...\n"); + ratio = 16; + } + rdmsr(MSR_FSB_FREQ, lo, hi); + if ((lo & 0x7) == 0x7) + fsb = PENWELL_FSB_FREQ_83SKU; + else + fsb = PENWELL_FSB_FREQ_100SKU; + fast_calibrate = ratio * fsb; + pr_debug("read penwell tsc %lu khz\n", fast_calibrate); + lapic_timer_frequency = fsb * 1000 / HZ; + /* mark tsc clocksource as reliable */ + set_cpu_cap(&boot_cpu_data, X86_FEATURE_TSC_RELIABLE); + + if (fast_calibrate) + return fast_calibrate; + + return 0; +} + +static void __init intel_mid_time_init(void) +{ + sfi_table_parse(SFI_SIG_MTMR, NULL, NULL, sfi_parse_mtmr); + switch (intel_mid_timer_options) { + case INTEL_MID_TIMER_APBT_ONLY: + break; + case INTEL_MID_TIMER_LAPIC_APBT: + x86_init.timers.setup_percpu_clockev = setup_boot_APIC_clock; + x86_cpuinit.setup_percpu_clockev = setup_secondary_APIC_clock; + break; + default: + if (!boot_cpu_has(X86_FEATURE_ARAT)) + break; + x86_init.timers.setup_percpu_clockev = setup_boot_APIC_clock; + x86_cpuinit.setup_percpu_clockev = setup_secondary_APIC_clock; + return; + } + /* we need at least one APB timer */ + pre_init_apic_IRQ0(); + apbt_time_init(); +} + +static void intel_mid_arch_setup(void) +{ + if (boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model == 0x27) + __intel_mid_cpu_chip = INTEL_MID_CPU_CHIP_PENWELL; + else { + pr_err("Unknown Intel MID CPU (%d:%d), default to Penwell\n", + boot_cpu_data.x86, boot_cpu_data.x86_model); + __intel_mid_cpu_chip = INTEL_MID_CPU_CHIP_PENWELL; + } +} + +/* MID systems don't have i8042 controller */ +static int intel_mid_i8042_detect(void) +{ + return 0; +} + +/* + * Moorestown does not have external NMI source nor port 0x61 to report + * NMI status. The possible NMI sources are from pmu as a result of NMI + * watchdog or lock debug. Reading io port 0x61 results in 0xff which + * misled NMI handler. + */ +static unsigned char intel_mid_get_nmi_reason(void) +{ + return 0; +} + +/* + * Moorestown specific x86_init function overrides and early setup + * calls. + */ +void __init x86_intel_mid_early_setup(void) +{ + x86_init.resources.probe_roms = x86_init_noop; + x86_init.resources.reserve_resources = x86_init_noop; + + x86_init.timers.timer_init = intel_mid_time_init; + x86_init.timers.setup_percpu_clockev = x86_init_noop; + + x86_init.irqs.pre_vector_init = x86_init_noop; + + x86_init.oem.arch_setup = intel_mid_arch_setup; + + x86_cpuinit.setup_percpu_clockev = apbt_setup_secondary_clock; + + x86_platform.calibrate_tsc = intel_mid_calibrate_tsc; + x86_platform.i8042_detect = intel_mid_i8042_detect; + x86_init.timers.wallclock_init = intel_mid_rtc_init; + x86_platform.get_nmi_reason = intel_mid_get_nmi_reason; + + x86_init.pci.init = intel_mid_pci_init; + x86_init.pci.fixup_irqs = x86_init_noop; + + legacy_pic = &null_legacy_pic; + + pm_power_off = intel_mid_power_off; + machine_ops.emergency_restart = intel_mid_reboot; + + /* Avoid searching for BIOS MP tables */ + x86_init.mpparse.find_smp_config = x86_init_noop; + x86_init.mpparse.get_smp_config = x86_init_uint_noop; + set_bit(MP_BUS_ISA, mp_bus_not_pci); +} + +/* + * if user does not want to use per CPU apb timer, just give it a lower rating + * than local apic timer and skip the late per cpu timer init. + */ +static inline int __init setup_x86_intel_mid_timer(char *arg) +{ + if (!arg) + return -EINVAL; + + if (strcmp("apbt_only", arg) == 0) + intel_mid_timer_options = INTEL_MID_TIMER_APBT_ONLY; + else if (strcmp("lapic_and_apbt", arg) == 0) + intel_mid_timer_options = INTEL_MID_TIMER_LAPIC_APBT; + else { + pr_warn("X86 INTEL_MID timer option %s not recognised" + " use x86_intel_mid_timer=apbt_only or lapic_and_apbt\n", + arg); + return -EINVAL; + } + return 0; +} +__setup("x86_intel_mid_timer=", setup_x86_intel_mid_timer); + diff --git a/arch/x86/platform/mrst/vrtc.c b/arch/x86/platform/intel-mid/intel_mid_vrtc.c index 5e355b134ba4..4762cff7facd 100644 --- a/arch/x86/platform/mrst/vrtc.c +++ b/arch/x86/platform/intel-mid/intel_mid_vrtc.c @@ -1,5 +1,5 @@ /* - * vrtc.c: Driver for virtual RTC device on Intel MID platform + * intel_mid_vrtc.c: Driver for virtual RTC device on Intel MID platform * * (C) Copyright 2009 Intel Corporation * @@ -23,8 +23,8 @@ #include <linux/sfi.h> #include <linux/platform_device.h> -#include <asm/mrst.h> -#include <asm/mrst-vrtc.h> +#include <asm/intel-mid.h> +#include <asm/intel_mid_vrtc.h> #include <asm/time.h> #include <asm/fixmap.h> @@ -79,7 +79,7 @@ void vrtc_get_time(struct timespec *now) /* vRTC YEAR reg contains the offset to 1972 */ year += 1972; - printk(KERN_INFO "vRTC: sec: %d min: %d hour: %d day: %d " + pr_info("vRTC: sec: %d min: %d hour: %d day: %d " "mon: %d year: %d\n", sec, min, hour, mday, mon, year); now->tv_sec = mktime(year, mon, mday, hour, min, sec); @@ -109,15 +109,14 @@ int vrtc_set_mmss(const struct timespec *now) vrtc_cmos_write(tm.tm_sec, RTC_SECONDS); spin_unlock_irqrestore(&rtc_lock, flags); } else { - printk(KERN_ERR - "%s: Invalid vRTC value: write of %lx to vRTC failed\n", + pr_err("%s: Invalid vRTC value: write of %lx to vRTC failed\n", __FUNCTION__, now->tv_sec); retval = -EINVAL; } return retval; } -void __init mrst_rtc_init(void) +void __init intel_mid_rtc_init(void) { unsigned long vrtc_paddr; @@ -155,10 +154,10 @@ static struct platform_device vrtc_device = { }; /* Register the RTC device if appropriate */ -static int __init mrst_device_create(void) +static int __init intel_mid_device_create(void) { /* No Moorestown, no device */ - if (!mrst_identify_cpu()) + if (!intel_mid_identify_cpu()) return -ENODEV; /* No timer, no device */ if (!sfi_mrtc_num) @@ -175,4 +174,4 @@ static int __init mrst_device_create(void) return platform_device_register(&vrtc_device); } -module_init(mrst_device_create); +module_init(intel_mid_device_create); diff --git a/arch/x86/platform/intel-mid/sfi.c b/arch/x86/platform/intel-mid/sfi.c new file mode 100644 index 000000000000..c84c1ca396bf --- /dev/null +++ b/arch/x86/platform/intel-mid/sfi.c @@ -0,0 +1,488 @@ +/* + * intel_mid_sfi.c: Intel MID SFI initialization code + * + * (C) Copyright 2013 Intel Corporation + * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/scatterlist.h> +#include <linux/sfi.h> +#include <linux/intel_pmic_gpio.h> +#include <linux/spi/spi.h> +#include <linux/i2c.h> +#include <linux/skbuff.h> +#include <linux/gpio.h> +#include <linux/gpio_keys.h> +#include <linux/input.h> +#include <linux/platform_device.h> +#include <linux/irq.h> +#include <linux/module.h> +#include <linux/notifier.h> +#include <linux/mmc/core.h> +#include <linux/mmc/card.h> +#include <linux/blkdev.h> + +#include <asm/setup.h> +#include <asm/mpspec_def.h> +#include <asm/hw_irq.h> +#include <asm/apic.h> +#include <asm/io_apic.h> +#include <asm/intel-mid.h> +#include <asm/intel_mid_vrtc.h> +#include <asm/io.h> +#include <asm/i8259.h> +#include <asm/intel_scu_ipc.h> +#include <asm/apb_timer.h> +#include <asm/reboot.h> + +#define SFI_SIG_OEM0 "OEM0" +#define MAX_IPCDEVS 24 +#define MAX_SCU_SPI 24 +#define MAX_SCU_I2C 24 + +static struct platform_device *ipc_devs[MAX_IPCDEVS]; +static struct spi_board_info *spi_devs[MAX_SCU_SPI]; +static struct i2c_board_info *i2c_devs[MAX_SCU_I2C]; +static struct sfi_gpio_table_entry *gpio_table; +static struct sfi_timer_table_entry sfi_mtimer_array[SFI_MTMR_MAX_NUM]; +static int ipc_next_dev; +static int spi_next_dev; +static int i2c_next_dev; +static int i2c_bus[MAX_SCU_I2C]; +static int gpio_num_entry; +static u32 sfi_mtimer_usage[SFI_MTMR_MAX_NUM]; +int sfi_mrtc_num; +int sfi_mtimer_num; + +struct sfi_rtc_table_entry sfi_mrtc_array[SFI_MRTC_MAX]; +EXPORT_SYMBOL_GPL(sfi_mrtc_array); + +struct blocking_notifier_head intel_scu_notifier = + BLOCKING_NOTIFIER_INIT(intel_scu_notifier); +EXPORT_SYMBOL_GPL(intel_scu_notifier); + +#define intel_mid_sfi_get_pdata(dev, priv) \ + ((dev)->get_platform_data ? (dev)->get_platform_data(priv) : NULL) + +/* parse all the mtimer info to a static mtimer array */ +int __init sfi_parse_mtmr(struct sfi_table_header *table) +{ + struct sfi_table_simple *sb; + struct sfi_timer_table_entry *pentry; + struct mpc_intsrc mp_irq; + int totallen; + + sb = (struct sfi_table_simple *)table; + if (!sfi_mtimer_num) { + sfi_mtimer_num = SFI_GET_NUM_ENTRIES(sb, + struct sfi_timer_table_entry); + pentry = (struct sfi_timer_table_entry *) sb->pentry; + totallen = sfi_mtimer_num * sizeof(*pentry); + memcpy(sfi_mtimer_array, pentry, totallen); + } + + pr_debug("SFI MTIMER info (num = %d):\n", sfi_mtimer_num); + pentry = sfi_mtimer_array; + for (totallen = 0; totallen < sfi_mtimer_num; totallen++, pentry++) { + pr_debug("timer[%d]: paddr = 0x%08x, freq = %dHz, irq = %d\n", + totallen, (u32)pentry->phys_addr, + pentry->freq_hz, pentry->irq); + if (!pentry->irq) + continue; + mp_irq.type = MP_INTSRC; + mp_irq.irqtype = mp_INT; +/* triggering mode edge bit 2-3, active high polarity bit 0-1 */ + mp_irq.irqflag = 5; + mp_irq.srcbus = MP_BUS_ISA; + mp_irq.srcbusirq = pentry->irq; /* IRQ */ + mp_irq.dstapic = MP_APIC_ALL; + mp_irq.dstirq = pentry->irq; + mp_save_irq(&mp_irq); + } + + return 0; +} + +struct sfi_timer_table_entry *sfi_get_mtmr(int hint) +{ + int i; + if (hint < sfi_mtimer_num) { + if (!sfi_mtimer_usage[hint]) { + pr_debug("hint taken for timer %d irq %d\n", + hint, sfi_mtimer_array[hint].irq); + sfi_mtimer_usage[hint] = 1; + return &sfi_mtimer_array[hint]; + } + } + /* take the first timer available */ + for (i = 0; i < sfi_mtimer_num;) { + if (!sfi_mtimer_usage[i]) { + sfi_mtimer_usage[i] = 1; + return &sfi_mtimer_array[i]; + } + i++; + } + return NULL; +} + +void sfi_free_mtmr(struct sfi_timer_table_entry *mtmr) +{ + int i; + for (i = 0; i < sfi_mtimer_num;) { + if (mtmr->irq == sfi_mtimer_array[i].irq) { + sfi_mtimer_usage[i] = 0; + return; + } + i++; + } +} + +/* parse all the mrtc info to a global mrtc array */ +int __init sfi_parse_mrtc(struct sfi_table_header *table) +{ + struct sfi_table_simple *sb; + struct sfi_rtc_table_entry *pentry; + struct mpc_intsrc mp_irq; + + int totallen; + + sb = (struct sfi_table_simple *)table; + if (!sfi_mrtc_num) { + sfi_mrtc_num = SFI_GET_NUM_ENTRIES(sb, + struct sfi_rtc_table_entry); + pentry = (struct sfi_rtc_table_entry *)sb->pentry; + totallen = sfi_mrtc_num * sizeof(*pentry); + memcpy(sfi_mrtc_array, pentry, totallen); + } + + pr_debug("SFI RTC info (num = %d):\n", sfi_mrtc_num); + pentry = sfi_mrtc_array; + for (totallen = 0; totallen < sfi_mrtc_num; totallen++, pentry++) { + pr_debug("RTC[%d]: paddr = 0x%08x, irq = %d\n", + totallen, (u32)pentry->phys_addr, pentry->irq); + mp_irq.type = MP_INTSRC; + mp_irq.irqtype = mp_INT; + mp_irq.irqflag = 0xf; /* level trigger and active low */ + mp_irq.srcbus = MP_BUS_ISA; + mp_irq.srcbusirq = pentry->irq; /* IRQ */ + mp_irq.dstapic = MP_APIC_ALL; + mp_irq.dstirq = pentry->irq; + mp_save_irq(&mp_irq); + } + return 0; +} + + +/* + * Parsing GPIO table first, since the DEVS table will need this table + * to map the pin name to the actual pin. + */ +static int __init sfi_parse_gpio(struct sfi_table_header *table) +{ + struct sfi_table_simple *sb; + struct sfi_gpio_table_entry *pentry; + int num, i; + + if (gpio_table) + return 0; + sb = (struct sfi_table_simple *)table; + num = SFI_GET_NUM_ENTRIES(sb, struct sfi_gpio_table_entry); + pentry = (struct sfi_gpio_table_entry *)sb->pentry; + + gpio_table = kmalloc(num * sizeof(*pentry), GFP_KERNEL); + if (!gpio_table) + return -1; + memcpy(gpio_table, pentry, num * sizeof(*pentry)); + gpio_num_entry = num; + + pr_debug("GPIO pin info:\n"); + for (i = 0; i < num; i++, pentry++) + pr_debug("info[%2d]: controller = %16.16s, pin_name = %16.16s," + " pin = %d\n", i, + pentry->controller_name, + pentry->pin_name, + pentry->pin_no); + return 0; +} + +int get_gpio_by_name(const char *name) +{ + struct sfi_gpio_table_entry *pentry = gpio_table; + int i; + + if (!pentry) + return -1; + for (i = 0; i < gpio_num_entry; i++, pentry++) { + if (!strncmp(name, pentry->pin_name, SFI_NAME_LEN)) + return pentry->pin_no; + } + return -1; +} + +void __init intel_scu_device_register(struct platform_device *pdev) +{ + if (ipc_next_dev == MAX_IPCDEVS) + pr_err("too many SCU IPC devices"); + else + ipc_devs[ipc_next_dev++] = pdev; +} + +static void __init intel_scu_spi_device_register(struct spi_board_info *sdev) +{ + struct spi_board_info *new_dev; + + if (spi_next_dev == MAX_SCU_SPI) { + pr_err("too many SCU SPI devices"); + return; + } + + new_dev = kzalloc(sizeof(*sdev), GFP_KERNEL); + if (!new_dev) { + pr_err("failed to alloc mem for delayed spi dev %s\n", + sdev->modalias); + return; + } + memcpy(new_dev, sdev, sizeof(*sdev)); + + spi_devs[spi_next_dev++] = new_dev; +} + +static void __init intel_scu_i2c_device_register(int bus, + struct i2c_board_info *idev) +{ + struct i2c_board_info *new_dev; + + if (i2c_next_dev == MAX_SCU_I2C) { + pr_err("too many SCU I2C devices"); + return; + } + + new_dev = kzalloc(sizeof(*idev), GFP_KERNEL); + if (!new_dev) { + pr_err("failed to alloc mem for delayed i2c dev %s\n", + idev->type); + return; + } + memcpy(new_dev, idev, sizeof(*idev)); + + i2c_bus[i2c_next_dev] = bus; + i2c_devs[i2c_next_dev++] = new_dev; +} + +/* Called by IPC driver */ +void intel_scu_devices_create(void) +{ + int i; + + for (i = 0; i < ipc_next_dev; i++) + platform_device_add(ipc_devs[i]); + + for (i = 0; i < spi_next_dev; i++) + spi_register_board_info(spi_devs[i], 1); + + for (i = 0; i < i2c_next_dev; i++) { + struct i2c_adapter *adapter; + struct i2c_client *client; + + adapter = i2c_get_adapter(i2c_bus[i]); + if (adapter) { + client = i2c_new_device(adapter, i2c_devs[i]); + if (!client) + pr_err("can't create i2c device %s\n", + i2c_devs[i]->type); + } else + i2c_register_board_info(i2c_bus[i], i2c_devs[i], 1); + } + intel_scu_notifier_post(SCU_AVAILABLE, NULL); +} +EXPORT_SYMBOL_GPL(intel_scu_devices_create); + +/* Called by IPC driver */ +void intel_scu_devices_destroy(void) +{ + int i; + + intel_scu_notifier_post(SCU_DOWN, NULL); + + for (i = 0; i < ipc_next_dev; i++) + platform_device_del(ipc_devs[i]); +} +EXPORT_SYMBOL_GPL(intel_scu_devices_destroy); + +static void __init install_irq_resource(struct platform_device *pdev, int irq) +{ + /* Single threaded */ + static struct resource res __initdata = { + .name = "IRQ", + .flags = IORESOURCE_IRQ, + }; + res.start = irq; + platform_device_add_resources(pdev, &res, 1); +} + +static void __init sfi_handle_ipc_dev(struct sfi_device_table_entry *pentry, + struct devs_id *dev) +{ + struct platform_device *pdev; + void *pdata = NULL; + + pr_debug("IPC bus, name = %16.16s, irq = 0x%2x\n", + pentry->name, pentry->irq); + pdata = intel_mid_sfi_get_pdata(dev, pentry); + + pdev = platform_device_alloc(pentry->name, 0); + if (pdev == NULL) { + pr_err("out of memory for SFI platform device '%s'.\n", + pentry->name); + return; + } + install_irq_resource(pdev, pentry->irq); + + pdev->dev.platform_data = pdata; + platform_device_add(pdev); +} + +static void __init sfi_handle_spi_dev(struct sfi_device_table_entry *pentry, + struct devs_id *dev) +{ + struct spi_board_info spi_info; + void *pdata = NULL; + + memset(&spi_info, 0, sizeof(spi_info)); + strncpy(spi_info.modalias, pentry->name, SFI_NAME_LEN); + spi_info.irq = ((pentry->irq == (u8)0xff) ? 0 : pentry->irq); + spi_info.bus_num = pentry->host_num; + spi_info.chip_select = pentry->addr; + spi_info.max_speed_hz = pentry->max_freq; + pr_debug("SPI bus=%d, name=%16.16s, irq=0x%2x, max_freq=%d, cs=%d\n", + spi_info.bus_num, + spi_info.modalias, + spi_info.irq, + spi_info.max_speed_hz, + spi_info.chip_select); + + pdata = intel_mid_sfi_get_pdata(dev, &spi_info); + + spi_info.platform_data = pdata; + if (dev->delay) + intel_scu_spi_device_register(&spi_info); + else + spi_register_board_info(&spi_info, 1); +} + +static void __init sfi_handle_i2c_dev(struct sfi_device_table_entry *pentry, + struct devs_id *dev) +{ + struct i2c_board_info i2c_info; + void *pdata = NULL; + + memset(&i2c_info, 0, sizeof(i2c_info)); + strncpy(i2c_info.type, pentry->name, SFI_NAME_LEN); + i2c_info.irq = ((pentry->irq == (u8)0xff) ? 0 : pentry->irq); + i2c_info.addr = pentry->addr; + pr_debug("I2C bus = %d, name = %16.16s, irq = 0x%2x, addr = 0x%x\n", + pentry->host_num, + i2c_info.type, + i2c_info.irq, + i2c_info.addr); + pdata = intel_mid_sfi_get_pdata(dev, &i2c_info); + i2c_info.platform_data = pdata; + + if (dev->delay) + intel_scu_i2c_device_register(pentry->host_num, &i2c_info); + else + i2c_register_board_info(pentry->host_num, &i2c_info, 1); +} + +extern struct devs_id *const __x86_intel_mid_dev_start[], + *const __x86_intel_mid_dev_end[]; + +static struct devs_id __init *get_device_id(u8 type, char *name) +{ + struct devs_id *const *dev_table; + + for (dev_table = __x86_intel_mid_dev_start; + dev_table < __x86_intel_mid_dev_end; dev_table++) { + struct devs_id *dev = *dev_table; + if (dev->type == type && + !strncmp(dev->name, name, SFI_NAME_LEN)) { + return dev; + } + } + + return NULL; +} + +static int __init sfi_parse_devs(struct sfi_table_header *table) +{ + struct sfi_table_simple *sb; + struct sfi_device_table_entry *pentry; + struct devs_id *dev = NULL; + int num, i; + int ioapic; + struct io_apic_irq_attr irq_attr; + + sb = (struct sfi_table_simple *)table; + num = SFI_GET_NUM_ENTRIES(sb, struct sfi_device_table_entry); + pentry = (struct sfi_device_table_entry *)sb->pentry; + + for (i = 0; i < num; i++, pentry++) { + int irq = pentry->irq; + + if (irq != (u8)0xff) { /* native RTE case */ + /* these SPI2 devices are not exposed to system as PCI + * devices, but they have separate RTE entry in IOAPIC + * so we have to enable them one by one here + */ + ioapic = mp_find_ioapic(irq); + irq_attr.ioapic = ioapic; + irq_attr.ioapic_pin = irq; + irq_attr.trigger = 1; + irq_attr.polarity = 1; + io_apic_set_pci_routing(NULL, irq, &irq_attr); + } else + irq = 0; /* No irq */ + + dev = get_device_id(pentry->type, pentry->name); + + if (!dev) + continue; + + if (dev->device_handler) { + dev->device_handler(pentry, dev); + } else { + switch (pentry->type) { + case SFI_DEV_TYPE_IPC: + sfi_handle_ipc_dev(pentry, dev); + break; + case SFI_DEV_TYPE_SPI: + sfi_handle_spi_dev(pentry, dev); + break; + case SFI_DEV_TYPE_I2C: + sfi_handle_i2c_dev(pentry, dev); + break; + case SFI_DEV_TYPE_UART: + case SFI_DEV_TYPE_HSI: + default: + break; + } + } + } + return 0; +} + +static int __init intel_mid_platform_init(void) +{ + sfi_table_parse(SFI_SIG_GPIO, NULL, NULL, sfi_parse_gpio); + sfi_table_parse(SFI_SIG_DEVS, NULL, NULL, sfi_parse_devs); + return 0; +} +arch_initcall(intel_mid_platform_init); diff --git a/arch/x86/platform/mrst/Makefile b/arch/x86/platform/mrst/Makefile deleted file mode 100644 index af1da7e623f9..000000000000 --- a/arch/x86/platform/mrst/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -obj-$(CONFIG_X86_INTEL_MID) += mrst.o -obj-$(CONFIG_X86_INTEL_MID) += vrtc.o -obj-$(CONFIG_EARLY_PRINTK_INTEL_MID) += early_printk_mrst.o diff --git a/arch/x86/platform/mrst/mrst.c b/arch/x86/platform/mrst/mrst.c deleted file mode 100644 index 3ca5957b7a34..000000000000 --- a/arch/x86/platform/mrst/mrst.c +++ /dev/null @@ -1,1052 +0,0 @@ -/* - * mrst.c: Intel Moorestown platform specific setup code - * - * (C) Copyright 2008 Intel Corporation - * Author: Jacob Pan (jacob.jun.pan@intel.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; version 2 - * of the License. - */ - -#define pr_fmt(fmt) "mrst: " fmt - -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/interrupt.h> -#include <linux/scatterlist.h> -#include <linux/sfi.h> -#include <linux/intel_pmic_gpio.h> -#include <linux/spi/spi.h> -#include <linux/i2c.h> -#include <linux/platform_data/pca953x.h> -#include <linux/gpio_keys.h> -#include <linux/input.h> -#include <linux/platform_device.h> -#include <linux/irq.h> -#include <linux/module.h> -#include <linux/notifier.h> -#include <linux/mfd/intel_msic.h> -#include <linux/gpio.h> -#include <linux/i2c/tc35876x.h> - -#include <asm/setup.h> -#include <asm/mpspec_def.h> -#include <asm/hw_irq.h> -#include <asm/apic.h> -#include <asm/io_apic.h> -#include <asm/mrst.h> -#include <asm/mrst-vrtc.h> -#include <asm/io.h> -#include <asm/i8259.h> -#include <asm/intel_scu_ipc.h> -#include <asm/apb_timer.h> -#include <asm/reboot.h> - -/* - * the clockevent devices on Moorestown/Medfield can be APBT or LAPIC clock, - * cmdline option x86_mrst_timer can be used to override the configuration - * to prefer one or the other. - * at runtime, there are basically three timer configurations: - * 1. per cpu apbt clock only - * 2. per cpu always-on lapic clocks only, this is Penwell/Medfield only - * 3. per cpu lapic clock (C3STOP) and one apbt clock, with broadcast. - * - * by default (without cmdline option), platform code first detects cpu type - * to see if we are on lincroft or penwell, then set up both lapic or apbt - * clocks accordingly. - * i.e. by default, medfield uses configuration #2, moorestown uses #1. - * config #3 is supported but not recommended on medfield. - * - * rating and feature summary: - * lapic (with C3STOP) --------- 100 - * apbt (always-on) ------------ 110 - * lapic (always-on,ARAT) ------ 150 - */ - -enum mrst_timer_options mrst_timer_options; - -static u32 sfi_mtimer_usage[SFI_MTMR_MAX_NUM]; -static struct sfi_timer_table_entry sfi_mtimer_array[SFI_MTMR_MAX_NUM]; -enum mrst_cpu_type __mrst_cpu_chip; -EXPORT_SYMBOL_GPL(__mrst_cpu_chip); - -int sfi_mtimer_num; - -struct sfi_rtc_table_entry sfi_mrtc_array[SFI_MRTC_MAX]; -EXPORT_SYMBOL_GPL(sfi_mrtc_array); -int sfi_mrtc_num; - -static void mrst_power_off(void) -{ -} - -static void mrst_reboot(void) -{ - intel_scu_ipc_simple_command(IPCMSG_COLD_BOOT, 0); -} - -/* parse all the mtimer info to a static mtimer array */ -static int __init sfi_parse_mtmr(struct sfi_table_header *table) -{ - struct sfi_table_simple *sb; - struct sfi_timer_table_entry *pentry; - struct mpc_intsrc mp_irq; - int totallen; - - sb = (struct sfi_table_simple *)table; - if (!sfi_mtimer_num) { - sfi_mtimer_num = SFI_GET_NUM_ENTRIES(sb, - struct sfi_timer_table_entry); - pentry = (struct sfi_timer_table_entry *) sb->pentry; - totallen = sfi_mtimer_num * sizeof(*pentry); - memcpy(sfi_mtimer_array, pentry, totallen); - } - - pr_debug("SFI MTIMER info (num = %d):\n", sfi_mtimer_num); - pentry = sfi_mtimer_array; - for (totallen = 0; totallen < sfi_mtimer_num; totallen++, pentry++) { - pr_debug("timer[%d]: paddr = 0x%08x, freq = %dHz," - " irq = %d\n", totallen, (u32)pentry->phys_addr, - pentry->freq_hz, pentry->irq); - if (!pentry->irq) - continue; - mp_irq.type = MP_INTSRC; - mp_irq.irqtype = mp_INT; -/* triggering mode edge bit 2-3, active high polarity bit 0-1 */ - mp_irq.irqflag = 5; - mp_irq.srcbus = MP_BUS_ISA; - mp_irq.srcbusirq = pentry->irq; /* IRQ */ - mp_irq.dstapic = MP_APIC_ALL; - mp_irq.dstirq = pentry->irq; - mp_save_irq(&mp_irq); - } - - return 0; -} - -struct sfi_timer_table_entry *sfi_get_mtmr(int hint) -{ - int i; - if (hint < sfi_mtimer_num) { - if (!sfi_mtimer_usage[hint]) { - pr_debug("hint taken for timer %d irq %d\n",\ - hint, sfi_mtimer_array[hint].irq); - sfi_mtimer_usage[hint] = 1; - return &sfi_mtimer_array[hint]; - } - } - /* take the first timer available */ - for (i = 0; i < sfi_mtimer_num;) { - if (!sfi_mtimer_usage[i]) { - sfi_mtimer_usage[i] = 1; - return &sfi_mtimer_array[i]; - } - i++; - } - return NULL; -} - -void sfi_free_mtmr(struct sfi_timer_table_entry *mtmr) -{ - int i; - for (i = 0; i < sfi_mtimer_num;) { - if (mtmr->irq == sfi_mtimer_array[i].irq) { - sfi_mtimer_usage[i] = 0; - return; - } - i++; - } -} - -/* parse all the mrtc info to a global mrtc array */ -int __init sfi_parse_mrtc(struct sfi_table_header *table) -{ - struct sfi_table_simple *sb; - struct sfi_rtc_table_entry *pentry; - struct mpc_intsrc mp_irq; - - int totallen; - - sb = (struct sfi_table_simple *)table; - if (!sfi_mrtc_num) { - sfi_mrtc_num = SFI_GET_NUM_ENTRIES(sb, - struct sfi_rtc_table_entry); - pentry = (struct sfi_rtc_table_entry *)sb->pentry; - totallen = sfi_mrtc_num * sizeof(*pentry); - memcpy(sfi_mrtc_array, pentry, totallen); - } - - pr_debug("SFI RTC info (num = %d):\n", sfi_mrtc_num); - pentry = sfi_mrtc_array; - for (totallen = 0; totallen < sfi_mrtc_num; totallen++, pentry++) { - pr_debug("RTC[%d]: paddr = 0x%08x, irq = %d\n", - totallen, (u32)pentry->phys_addr, pentry->irq); - mp_irq.type = MP_INTSRC; - mp_irq.irqtype = mp_INT; - mp_irq.irqflag = 0xf; /* level trigger and active low */ - mp_irq.srcbus = MP_BUS_ISA; - mp_irq.srcbusirq = pentry->irq; /* IRQ */ - mp_irq.dstapic = MP_APIC_ALL; - mp_irq.dstirq = pentry->irq; - mp_save_irq(&mp_irq); - } - return 0; -} - -static unsigned long __init mrst_calibrate_tsc(void) -{ - unsigned long fast_calibrate; - u32 lo, hi, ratio, fsb; - - rdmsr(MSR_IA32_PERF_STATUS, lo, hi); - pr_debug("IA32 perf status is 0x%x, 0x%0x\n", lo, hi); - ratio = (hi >> 8) & 0x1f; - pr_debug("ratio is %d\n", ratio); - if (!ratio) { - pr_err("read a zero ratio, should be incorrect!\n"); - pr_err("force tsc ratio to 16 ...\n"); - ratio = 16; - } - rdmsr(MSR_FSB_FREQ, lo, hi); - if ((lo & 0x7) == 0x7) - fsb = PENWELL_FSB_FREQ_83SKU; - else - fsb = PENWELL_FSB_FREQ_100SKU; - fast_calibrate = ratio * fsb; - pr_debug("read penwell tsc %lu khz\n", fast_calibrate); - lapic_timer_frequency = fsb * 1000 / HZ; - /* mark tsc clocksource as reliable */ - set_cpu_cap(&boot_cpu_data, X86_FEATURE_TSC_RELIABLE); - - if (fast_calibrate) - return fast_calibrate; - - return 0; -} - -static void __init mrst_time_init(void) -{ - sfi_table_parse(SFI_SIG_MTMR, NULL, NULL, sfi_parse_mtmr); - switch (mrst_timer_options) { - case MRST_TIMER_APBT_ONLY: - break; - case MRST_TIMER_LAPIC_APBT: - x86_init.timers.setup_percpu_clockev = setup_boot_APIC_clock; - x86_cpuinit.setup_percpu_clockev = setup_secondary_APIC_clock; - break; - default: - if (!boot_cpu_has(X86_FEATURE_ARAT)) - break; - x86_init.timers.setup_percpu_clockev = setup_boot_APIC_clock; - x86_cpuinit.setup_percpu_clockev = setup_secondary_APIC_clock; - return; - } - /* we need at least one APB timer */ - pre_init_apic_IRQ0(); - apbt_time_init(); -} - -static void mrst_arch_setup(void) -{ - if (boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model == 0x27) - __mrst_cpu_chip = MRST_CPU_CHIP_PENWELL; - else { - pr_err("Unknown Intel MID CPU (%d:%d), default to Penwell\n", - boot_cpu_data.x86, boot_cpu_data.x86_model); - __mrst_cpu_chip = MRST_CPU_CHIP_PENWELL; - } -} - -/* MID systems don't have i8042 controller */ -static int mrst_i8042_detect(void) -{ - return 0; -} - -/* - * Moorestown does not have external NMI source nor port 0x61 to report - * NMI status. The possible NMI sources are from pmu as a result of NMI - * watchdog or lock debug. Reading io port 0x61 results in 0xff which - * misled NMI handler. - */ -static unsigned char mrst_get_nmi_reason(void) -{ - return 0; -} - -/* - * Moorestown specific x86_init function overrides and early setup - * calls. - */ -void __init x86_mrst_early_setup(void) -{ - x86_init.resources.probe_roms = x86_init_noop; - x86_init.resources.reserve_resources = x86_init_noop; - - x86_init.timers.timer_init = mrst_time_init; - x86_init.timers.setup_percpu_clockev = x86_init_noop; - - x86_init.irqs.pre_vector_init = x86_init_noop; - - x86_init.oem.arch_setup = mrst_arch_setup; - - x86_cpuinit.setup_percpu_clockev = apbt_setup_secondary_clock; - - x86_platform.calibrate_tsc = mrst_calibrate_tsc; - x86_platform.i8042_detect = mrst_i8042_detect; - x86_init.timers.wallclock_init = mrst_rtc_init; - x86_platform.get_nmi_reason = mrst_get_nmi_reason; - - x86_init.pci.init = pci_mrst_init; - x86_init.pci.fixup_irqs = x86_init_noop; - - legacy_pic = &null_legacy_pic; - - /* Moorestown specific power_off/restart method */ - pm_power_off = mrst_power_off; - machine_ops.emergency_restart = mrst_reboot; - - /* Avoid searching for BIOS MP tables */ - x86_init.mpparse.find_smp_config = x86_init_noop; - x86_init.mpparse.get_smp_config = x86_init_uint_noop; - set_bit(MP_BUS_ISA, mp_bus_not_pci); -} - -/* - * if user does not want to use per CPU apb timer, just give it a lower rating - * than local apic timer and skip the late per cpu timer init. - */ -static inline int __init setup_x86_mrst_timer(char *arg) -{ - if (!arg) - return -EINVAL; - - if (strcmp("apbt_only", arg) == 0) - mrst_timer_options = MRST_TIMER_APBT_ONLY; - else if (strcmp("lapic_and_apbt", arg) == 0) - mrst_timer_options = MRST_TIMER_LAPIC_APBT; - else { - pr_warning("X86 MRST timer option %s not recognised" - " use x86_mrst_timer=apbt_only or lapic_and_apbt\n", - arg); - return -EINVAL; - } - return 0; -} -__setup("x86_mrst_timer=", setup_x86_mrst_timer); - -/* - * Parsing GPIO table first, since the DEVS table will need this table - * to map the pin name to the actual pin. - */ -static struct sfi_gpio_table_entry *gpio_table; -static int gpio_num_entry; - -static int __init sfi_parse_gpio(struct sfi_table_header *table) -{ - struct sfi_table_simple *sb; - struct sfi_gpio_table_entry *pentry; - int num, i; - - if (gpio_table) - return 0; - sb = (struct sfi_table_simple *)table; - num = SFI_GET_NUM_ENTRIES(sb, struct sfi_gpio_table_entry); - pentry = (struct sfi_gpio_table_entry *)sb->pentry; - - gpio_table = kmalloc(num * sizeof(*pentry), GFP_KERNEL); - if (!gpio_table) - return -1; - memcpy(gpio_table, pentry, num * sizeof(*pentry)); - gpio_num_entry = num; - - pr_debug("GPIO pin info:\n"); - for (i = 0; i < num; i++, pentry++) - pr_debug("info[%2d]: controller = %16.16s, pin_name = %16.16s," - " pin = %d\n", i, - pentry->controller_name, - pentry->pin_name, - pentry->pin_no); - return 0; -} - -static int get_gpio_by_name(const char *name) -{ - struct sfi_gpio_table_entry *pentry = gpio_table; - int i; - - if (!pentry) - return -1; - for (i = 0; i < gpio_num_entry; i++, pentry++) { - if (!strncmp(name, pentry->pin_name, SFI_NAME_LEN)) - return pentry->pin_no; - } - return -1; -} - -/* - * Here defines the array of devices platform data that IAFW would export - * through SFI "DEVS" table, we use name and type to match the device and - * its platform data. - */ -struct devs_id { - char name[SFI_NAME_LEN + 1]; - u8 type; - u8 delay; - void *(*get_platform_data)(void *info); -}; - -/* the offset for the mapping of global gpio pin to irq */ -#define MRST_IRQ_OFFSET 0x100 - -static void __init *pmic_gpio_platform_data(void *info) -{ - static struct intel_pmic_gpio_platform_data pmic_gpio_pdata; - int gpio_base = get_gpio_by_name("pmic_gpio_base"); - - if (gpio_base == -1) - gpio_base = 64; - pmic_gpio_pdata.gpio_base = gpio_base; - pmic_gpio_pdata.irq_base = gpio_base + MRST_IRQ_OFFSET; - pmic_gpio_pdata.gpiointr = 0xffffeff8; - - return &pmic_gpio_pdata; -} - -static void __init *max3111_platform_data(void *info) -{ - struct spi_board_info *spi_info = info; - int intr = get_gpio_by_name("max3111_int"); - - spi_info->mode = SPI_MODE_0; - if (intr == -1) - return NULL; - spi_info->irq = intr + MRST_IRQ_OFFSET; - return NULL; -} - -/* we have multiple max7315 on the board ... */ -#define MAX7315_NUM 2 -static void __init *max7315_platform_data(void *info) -{ - static struct pca953x_platform_data max7315_pdata[MAX7315_NUM]; - static int nr; - struct pca953x_platform_data *max7315 = &max7315_pdata[nr]; - struct i2c_board_info *i2c_info = info; - int gpio_base, intr; - char base_pin_name[SFI_NAME_LEN + 1]; - char intr_pin_name[SFI_NAME_LEN + 1]; - - if (nr == MAX7315_NUM) { - pr_err("too many max7315s, we only support %d\n", - MAX7315_NUM); - return NULL; - } - /* we have several max7315 on the board, we only need load several - * instances of the same pca953x driver to cover them - */ - strcpy(i2c_info->type, "max7315"); - if (nr++) { - sprintf(base_pin_name, "max7315_%d_base", nr); - sprintf(intr_pin_name, "max7315_%d_int", nr); - } else { - strcpy(base_pin_name, "max7315_base"); - strcpy(intr_pin_name, "max7315_int"); - } - - gpio_base = get_gpio_by_name(base_pin_name); - intr = get_gpio_by_name(intr_pin_name); - - if (gpio_base == -1) - return NULL; - max7315->gpio_base = gpio_base; - if (intr != -1) { - i2c_info->irq = intr + MRST_IRQ_OFFSET; - max7315->irq_base = gpio_base + MRST_IRQ_OFFSET; - } else { - i2c_info->irq = -1; - max7315->irq_base = -1; - } - return max7315; -} - -static void *tca6416_platform_data(void *info) -{ - static struct pca953x_platform_data tca6416; - struct i2c_board_info *i2c_info = info; - int gpio_base, intr; - char base_pin_name[SFI_NAME_LEN + 1]; - char intr_pin_name[SFI_NAME_LEN + 1]; - - strcpy(i2c_info->type, "tca6416"); - strcpy(base_pin_name, "tca6416_base"); - strcpy(intr_pin_name, "tca6416_int"); - - gpio_base = get_gpio_by_name(base_pin_name); - intr = get_gpio_by_name(intr_pin_name); - - if (gpio_base == -1) - return NULL; - tca6416.gpio_base = gpio_base; - if (intr != -1) { - i2c_info->irq = intr + MRST_IRQ_OFFSET; - tca6416.irq_base = gpio_base + MRST_IRQ_OFFSET; - } else { - i2c_info->irq = -1; - tca6416.irq_base = -1; - } - return &tca6416; -} - -static void *mpu3050_platform_data(void *info) -{ - struct i2c_board_info *i2c_info = info; - int intr = get_gpio_by_name("mpu3050_int"); - - if (intr == -1) - return NULL; - - i2c_info->irq = intr + MRST_IRQ_OFFSET; - return NULL; -} - -static void __init *emc1403_platform_data(void *info) -{ - static short intr2nd_pdata; - struct i2c_board_info *i2c_info = info; - int intr = get_gpio_by_name("thermal_int"); - int intr2nd = get_gpio_by_name("thermal_alert"); - - if (intr == -1 || intr2nd == -1) - return NULL; - - i2c_info->irq = intr + MRST_IRQ_OFFSET; - intr2nd_pdata = intr2nd + MRST_IRQ_OFFSET; - - return &intr2nd_pdata; -} - -static void __init *lis331dl_platform_data(void *info) -{ - static short intr2nd_pdata; - struct i2c_board_info *i2c_info = info; - int intr = get_gpio_by_name("accel_int"); - int intr2nd = get_gpio_by_name("accel_2"); - - if (intr == -1 || intr2nd == -1) - return NULL; - - i2c_info->irq = intr + MRST_IRQ_OFFSET; - intr2nd_pdata = intr2nd + MRST_IRQ_OFFSET; - - return &intr2nd_pdata; -} - -static void __init *no_platform_data(void *info) -{ - return NULL; -} - -static struct resource msic_resources[] = { - { - .start = INTEL_MSIC_IRQ_PHYS_BASE, - .end = INTEL_MSIC_IRQ_PHYS_BASE + 64 - 1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct intel_msic_platform_data msic_pdata; - -static struct platform_device msic_device = { - .name = "intel_msic", - .id = -1, - .dev = { - .platform_data = &msic_pdata, - }, - .num_resources = ARRAY_SIZE(msic_resources), - .resource = msic_resources, -}; - -static inline bool mrst_has_msic(void) -{ - return mrst_identify_cpu() == MRST_CPU_CHIP_PENWELL; -} - -static int msic_scu_status_change(struct notifier_block *nb, - unsigned long code, void *data) -{ - if (code == SCU_DOWN) { - platform_device_unregister(&msic_device); - return 0; - } - - return platform_device_register(&msic_device); -} - -static int __init msic_init(void) -{ - static struct notifier_block msic_scu_notifier = { - .notifier_call = msic_scu_status_change, - }; - - /* - * We need to be sure that the SCU IPC is ready before MSIC device - * can be registered. - */ - if (mrst_has_msic()) - intel_scu_notifier_add(&msic_scu_notifier); - - return 0; -} -arch_initcall(msic_init); - -/* - * msic_generic_platform_data - sets generic platform data for the block - * @info: pointer to the SFI device table entry for this block - * @block: MSIC block - * - * Function sets IRQ number from the SFI table entry for given device to - * the MSIC platform data. - */ -static void *msic_generic_platform_data(void *info, enum intel_msic_block block) -{ - struct sfi_device_table_entry *entry = info; - - BUG_ON(block < 0 || block >= INTEL_MSIC_BLOCK_LAST); - msic_pdata.irq[block] = entry->irq; - - return no_platform_data(info); -} - -static void *msic_battery_platform_data(void *info) -{ - return msic_generic_platform_data(info, INTEL_MSIC_BLOCK_BATTERY); -} - -static void *msic_gpio_platform_data(void *info) -{ - static struct intel_msic_gpio_pdata pdata; - int gpio = get_gpio_by_name("msic_gpio_base"); - - if (gpio < 0) - return NULL; - - pdata.gpio_base = gpio; - msic_pdata.gpio = &pdata; - - return msic_generic_platform_data(info, INTEL_MSIC_BLOCK_GPIO); -} - -static void *msic_audio_platform_data(void *info) -{ - struct platform_device *pdev; - - pdev = platform_device_register_simple("sst-platform", -1, NULL, 0); - if (IS_ERR(pdev)) { - pr_err("failed to create audio platform device\n"); - return NULL; - } - - return msic_generic_platform_data(info, INTEL_MSIC_BLOCK_AUDIO); -} - -static void *msic_power_btn_platform_data(void *info) -{ - return msic_generic_platform_data(info, INTEL_MSIC_BLOCK_POWER_BTN); -} - -static void *msic_ocd_platform_data(void *info) -{ - static struct intel_msic_ocd_pdata pdata; - int gpio = get_gpio_by_name("ocd_gpio"); - - if (gpio < 0) - return NULL; - - pdata.gpio = gpio; - msic_pdata.ocd = &pdata; - - return msic_generic_platform_data(info, INTEL_MSIC_BLOCK_OCD); -} - -static void *msic_thermal_platform_data(void *info) -{ - return msic_generic_platform_data(info, INTEL_MSIC_BLOCK_THERMAL); -} - -/* tc35876x DSI-LVDS bridge chip and panel platform data */ -static void *tc35876x_platform_data(void *data) -{ - static struct tc35876x_platform_data pdata; - - /* gpio pins set to -1 will not be used by the driver */ - pdata.gpio_bridge_reset = get_gpio_by_name("LCMB_RXEN"); - pdata.gpio_panel_bl_en = get_gpio_by_name("6S6P_BL_EN"); - pdata.gpio_panel_vadd = get_gpio_by_name("EN_VREG_LCD_V3P3"); - - return &pdata; -} - -static const struct devs_id __initconst device_ids[] = { - {"bma023", SFI_DEV_TYPE_I2C, 1, &no_platform_data}, - {"pmic_gpio", SFI_DEV_TYPE_SPI, 1, &pmic_gpio_platform_data}, - {"pmic_gpio", SFI_DEV_TYPE_IPC, 1, &pmic_gpio_platform_data}, - {"spi_max3111", SFI_DEV_TYPE_SPI, 0, &max3111_platform_data}, - {"i2c_max7315", SFI_DEV_TYPE_I2C, 1, &max7315_platform_data}, - {"i2c_max7315_2", SFI_DEV_TYPE_I2C, 1, &max7315_platform_data}, - {"tca6416", SFI_DEV_TYPE_I2C, 1, &tca6416_platform_data}, - {"emc1403", SFI_DEV_TYPE_I2C, 1, &emc1403_platform_data}, - {"i2c_accel", SFI_DEV_TYPE_I2C, 0, &lis331dl_platform_data}, - {"pmic_audio", SFI_DEV_TYPE_IPC, 1, &no_platform_data}, - {"mpu3050", SFI_DEV_TYPE_I2C, 1, &mpu3050_platform_data}, - {"i2c_disp_brig", SFI_DEV_TYPE_I2C, 0, &tc35876x_platform_data}, - - /* MSIC subdevices */ - {"msic_battery", SFI_DEV_TYPE_IPC, 1, &msic_battery_platform_data}, - {"msic_gpio", SFI_DEV_TYPE_IPC, 1, &msic_gpio_platform_data}, - {"msic_audio", SFI_DEV_TYPE_IPC, 1, &msic_audio_platform_data}, - {"msic_power_btn", SFI_DEV_TYPE_IPC, 1, &msic_power_btn_platform_data}, - {"msic_ocd", SFI_DEV_TYPE_IPC, 1, &msic_ocd_platform_data}, - {"msic_thermal", SFI_DEV_TYPE_IPC, 1, &msic_thermal_platform_data}, - - {}, -}; - -#define MAX_IPCDEVS 24 -static struct platform_device *ipc_devs[MAX_IPCDEVS]; -static int ipc_next_dev; - -#define MAX_SCU_SPI 24 -static struct spi_board_info *spi_devs[MAX_SCU_SPI]; -static int spi_next_dev; - -#define MAX_SCU_I2C 24 -static struct i2c_board_info *i2c_devs[MAX_SCU_I2C]; -static int i2c_bus[MAX_SCU_I2C]; -static int i2c_next_dev; - -static void __init intel_scu_device_register(struct platform_device *pdev) -{ - if(ipc_next_dev == MAX_IPCDEVS) - pr_err("too many SCU IPC devices"); - else - ipc_devs[ipc_next_dev++] = pdev; -} - -static void __init intel_scu_spi_device_register(struct spi_board_info *sdev) -{ - struct spi_board_info *new_dev; - - if (spi_next_dev == MAX_SCU_SPI) { - pr_err("too many SCU SPI devices"); - return; - } - - new_dev = kzalloc(sizeof(*sdev), GFP_KERNEL); - if (!new_dev) { - pr_err("failed to alloc mem for delayed spi dev %s\n", - sdev->modalias); - return; - } - memcpy(new_dev, sdev, sizeof(*sdev)); - - spi_devs[spi_next_dev++] = new_dev; -} - -static void __init intel_scu_i2c_device_register(int bus, - struct i2c_board_info *idev) -{ - struct i2c_board_info *new_dev; - - if (i2c_next_dev == MAX_SCU_I2C) { - pr_err("too many SCU I2C devices"); - return; - } - - new_dev = kzalloc(sizeof(*idev), GFP_KERNEL); - if (!new_dev) { - pr_err("failed to alloc mem for delayed i2c dev %s\n", - idev->type); - return; - } - memcpy(new_dev, idev, sizeof(*idev)); - - i2c_bus[i2c_next_dev] = bus; - i2c_devs[i2c_next_dev++] = new_dev; -} - -BLOCKING_NOTIFIER_HEAD(intel_scu_notifier); -EXPORT_SYMBOL_GPL(intel_scu_notifier); - -/* Called by IPC driver */ -void intel_scu_devices_create(void) -{ - int i; - - for (i = 0; i < ipc_next_dev; i++) - platform_device_add(ipc_devs[i]); - - for (i = 0; i < spi_next_dev; i++) - spi_register_board_info(spi_devs[i], 1); - - for (i = 0; i < i2c_next_dev; i++) { - struct i2c_adapter *adapter; - struct i2c_client *client; - - adapter = i2c_get_adapter(i2c_bus[i]); - if (adapter) { - client = i2c_new_device(adapter, i2c_devs[i]); - if (!client) - pr_err("can't create i2c device %s\n", - i2c_devs[i]->type); - } else - i2c_register_board_info(i2c_bus[i], i2c_devs[i], 1); - } - intel_scu_notifier_post(SCU_AVAILABLE, NULL); -} -EXPORT_SYMBOL_GPL(intel_scu_devices_create); - -/* Called by IPC driver */ -void intel_scu_devices_destroy(void) -{ - int i; - - intel_scu_notifier_post(SCU_DOWN, NULL); - - for (i = 0; i < ipc_next_dev; i++) - platform_device_del(ipc_devs[i]); -} -EXPORT_SYMBOL_GPL(intel_scu_devices_destroy); - -static void __init install_irq_resource(struct platform_device *pdev, int irq) -{ - /* Single threaded */ - static struct resource __initdata res = { - .name = "IRQ", - .flags = IORESOURCE_IRQ, - }; - res.start = irq; - platform_device_add_resources(pdev, &res, 1); -} - -static void __init sfi_handle_ipc_dev(struct sfi_device_table_entry *entry) -{ - const struct devs_id *dev = device_ids; - struct platform_device *pdev; - void *pdata = NULL; - - while (dev->name[0]) { - if (dev->type == SFI_DEV_TYPE_IPC && - !strncmp(dev->name, entry->name, SFI_NAME_LEN)) { - pdata = dev->get_platform_data(entry); - break; - } - dev++; - } - - /* - * On Medfield the platform device creation is handled by the MSIC - * MFD driver so we don't need to do it here. - */ - if (mrst_has_msic()) - return; - - pdev = platform_device_alloc(entry->name, 0); - if (pdev == NULL) { - pr_err("out of memory for SFI platform device '%s'.\n", - entry->name); - return; - } - install_irq_resource(pdev, entry->irq); - - pdev->dev.platform_data = pdata; - intel_scu_device_register(pdev); -} - -static void __init sfi_handle_spi_dev(struct spi_board_info *spi_info) -{ - const struct devs_id *dev = device_ids; - void *pdata = NULL; - - while (dev->name[0]) { - if (dev->type == SFI_DEV_TYPE_SPI && - !strncmp(dev->name, spi_info->modalias, SFI_NAME_LEN)) { - pdata = dev->get_platform_data(spi_info); - break; - } - dev++; - } - spi_info->platform_data = pdata; - if (dev->delay) - intel_scu_spi_device_register(spi_info); - else - spi_register_board_info(spi_info, 1); -} - -static void __init sfi_handle_i2c_dev(int bus, struct i2c_board_info *i2c_info) -{ - const struct devs_id *dev = device_ids; - void *pdata = NULL; - - while (dev->name[0]) { - if (dev->type == SFI_DEV_TYPE_I2C && - !strncmp(dev->name, i2c_info->type, SFI_NAME_LEN)) { - pdata = dev->get_platform_data(i2c_info); - break; - } - dev++; - } - i2c_info->platform_data = pdata; - - if (dev->delay) - intel_scu_i2c_device_register(bus, i2c_info); - else - i2c_register_board_info(bus, i2c_info, 1); - } - - -static int __init sfi_parse_devs(struct sfi_table_header *table) -{ - struct sfi_table_simple *sb; - struct sfi_device_table_entry *pentry; - struct spi_board_info spi_info; - struct i2c_board_info i2c_info; - int num, i, bus; - int ioapic; - struct io_apic_irq_attr irq_attr; - - sb = (struct sfi_table_simple *)table; - num = SFI_GET_NUM_ENTRIES(sb, struct sfi_device_table_entry); - pentry = (struct sfi_device_table_entry *)sb->pentry; - - for (i = 0; i < num; i++, pentry++) { - int irq = pentry->irq; - - if (irq != (u8)0xff) { /* native RTE case */ - /* these SPI2 devices are not exposed to system as PCI - * devices, but they have separate RTE entry in IOAPIC - * so we have to enable them one by one here - */ - ioapic = mp_find_ioapic(irq); - irq_attr.ioapic = ioapic; - irq_attr.ioapic_pin = irq; - irq_attr.trigger = 1; - irq_attr.polarity = 1; - io_apic_set_pci_routing(NULL, irq, &irq_attr); - } else - irq = 0; /* No irq */ - - switch (pentry->type) { - case SFI_DEV_TYPE_IPC: - pr_debug("info[%2d]: IPC bus, name = %16.16s, " - "irq = 0x%2x\n", i, pentry->name, pentry->irq); - sfi_handle_ipc_dev(pentry); - break; - case SFI_DEV_TYPE_SPI: - memset(&spi_info, 0, sizeof(spi_info)); - strncpy(spi_info.modalias, pentry->name, SFI_NAME_LEN); - spi_info.irq = irq; - spi_info.bus_num = pentry->host_num; - spi_info.chip_select = pentry->addr; - spi_info.max_speed_hz = pentry->max_freq; - pr_debug("info[%2d]: SPI bus = %d, name = %16.16s, " - "irq = 0x%2x, max_freq = %d, cs = %d\n", i, - spi_info.bus_num, - spi_info.modalias, - spi_info.irq, - spi_info.max_speed_hz, - spi_info.chip_select); - sfi_handle_spi_dev(&spi_info); - break; - case SFI_DEV_TYPE_I2C: - memset(&i2c_info, 0, sizeof(i2c_info)); - bus = pentry->host_num; - strncpy(i2c_info.type, pentry->name, SFI_NAME_LEN); - i2c_info.irq = irq; - i2c_info.addr = pentry->addr; - pr_debug("info[%2d]: I2C bus = %d, name = %16.16s, " - "irq = 0x%2x, addr = 0x%x\n", i, bus, - i2c_info.type, - i2c_info.irq, - i2c_info.addr); - sfi_handle_i2c_dev(bus, &i2c_info); - break; - case SFI_DEV_TYPE_UART: - case SFI_DEV_TYPE_HSI: - default: - ; - } - } - return 0; -} - -static int __init mrst_platform_init(void) -{ - sfi_table_parse(SFI_SIG_GPIO, NULL, NULL, sfi_parse_gpio); - sfi_table_parse(SFI_SIG_DEVS, NULL, NULL, sfi_parse_devs); - return 0; -} -arch_initcall(mrst_platform_init); - -/* - * we will search these buttons in SFI GPIO table (by name) - * and register them dynamically. Please add all possible - * buttons here, we will shrink them if no GPIO found. - */ -static struct gpio_keys_button gpio_button[] = { - {KEY_POWER, -1, 1, "power_btn", EV_KEY, 0, 3000}, - {KEY_PROG1, -1, 1, "prog_btn1", EV_KEY, 0, 20}, - {KEY_PROG2, -1, 1, "prog_btn2", EV_KEY, 0, 20}, - {SW_LID, -1, 1, "lid_switch", EV_SW, 0, 20}, - {KEY_VOLUMEUP, -1, 1, "vol_up", EV_KEY, 0, 20}, - {KEY_VOLUMEDOWN, -1, 1, "vol_down", EV_KEY, 0, 20}, - {KEY_CAMERA, -1, 1, "camera_full", EV_KEY, 0, 20}, - {KEY_CAMERA_FOCUS, -1, 1, "camera_half", EV_KEY, 0, 20}, - {SW_KEYPAD_SLIDE, -1, 1, "MagSw1", EV_SW, 0, 20}, - {SW_KEYPAD_SLIDE, -1, 1, "MagSw2", EV_SW, 0, 20}, -}; - -static struct gpio_keys_platform_data mrst_gpio_keys = { - .buttons = gpio_button, - .rep = 1, - .nbuttons = -1, /* will fill it after search */ -}; - -static struct platform_device pb_device = { - .name = "gpio-keys", - .id = -1, - .dev = { - .platform_data = &mrst_gpio_keys, - }, -}; - -/* - * Shrink the non-existent buttons, register the gpio button - * device if there is some - */ -static int __init pb_keys_init(void) -{ - struct gpio_keys_button *gb = gpio_button; - int i, num, good = 0; - - num = sizeof(gpio_button) / sizeof(struct gpio_keys_button); - for (i = 0; i < num; i++) { - gb[i].gpio = get_gpio_by_name(gb[i].desc); - pr_debug("info[%2d]: name = %s, gpio = %d\n", i, gb[i].desc, gb[i].gpio); - if (gb[i].gpio == -1) - continue; - - if (i != good) - gb[good] = gb[i]; - good++; - } - - if (good) { - mrst_gpio_keys.nbuttons = good; - return platform_device_register(&pb_device); - } - return 0; -} -late_initcall(pb_keys_init); diff --git a/arch/x86/platform/olpc/olpc-xo15-sci.c b/arch/x86/platform/olpc/olpc-xo15-sci.c index fef7d0ba7e3a..649a12befba9 100644 --- a/arch/x86/platform/olpc/olpc-xo15-sci.c +++ b/arch/x86/platform/olpc/olpc-xo15-sci.c @@ -40,16 +40,9 @@ static bool lid_wake_on_close; */ static int set_lid_wake_behavior(bool wake_on_close) { - struct acpi_object_list arg_list; - union acpi_object arg; acpi_status status; - arg_list.count = 1; - arg_list.pointer = &arg; - arg.type = ACPI_TYPE_INTEGER; - arg.integer.value = wake_on_close; - - status = acpi_evaluate_object(NULL, "\\_SB.PCI0.LID.LIDW", &arg_list, NULL); + status = acpi_execute_simple_method(NULL, "\\_SB.PCI0.LID.LIDW", wake_on_close); if (ACPI_FAILURE(status)) { pr_warning(PFX "failed to set lid behavior\n"); return 1; diff --git a/arch/x86/platform/uv/Makefile b/arch/x86/platform/uv/Makefile index 6c40995fefb8..52079bebd014 100644 --- a/arch/x86/platform/uv/Makefile +++ b/arch/x86/platform/uv/Makefile @@ -1 +1 @@ -obj-$(CONFIG_X86_UV) += tlb_uv.o bios_uv.o uv_irq.o uv_sysfs.o uv_time.o +obj-$(CONFIG_X86_UV) += tlb_uv.o bios_uv.o uv_irq.o uv_sysfs.o uv_time.o uv_nmi.o diff --git a/arch/x86/platform/uv/uv_nmi.c b/arch/x86/platform/uv/uv_nmi.c new file mode 100644 index 000000000000..8eeccba73130 --- /dev/null +++ b/arch/x86/platform/uv/uv_nmi.c @@ -0,0 +1,700 @@ +/* + * SGI NMI support routines + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Copyright (c) 2009-2013 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) Mike Travis + */ + +#include <linux/cpu.h> +#include <linux/delay.h> +#include <linux/kdb.h> +#include <linux/kexec.h> +#include <linux/kgdb.h> +#include <linux/module.h> +#include <linux/nmi.h> +#include <linux/sched.h> +#include <linux/slab.h> + +#include <asm/apic.h> +#include <asm/current.h> +#include <asm/kdebug.h> +#include <asm/local64.h> +#include <asm/nmi.h> +#include <asm/traps.h> +#include <asm/uv/uv.h> +#include <asm/uv/uv_hub.h> +#include <asm/uv/uv_mmrs.h> + +/* + * UV handler for NMI + * + * Handle system-wide NMI events generated by the global 'power nmi' command. + * + * Basic operation is to field the NMI interrupt on each cpu and wait + * until all cpus have arrived into the nmi handler. If some cpus do not + * make it into the handler, try and force them in with the IPI(NMI) signal. + * + * We also have to lessen UV Hub MMR accesses as much as possible as this + * disrupts the UV Hub's primary mission of directing NumaLink traffic and + * can cause system problems to occur. + * + * To do this we register our primary NMI notifier on the NMI_UNKNOWN + * chain. This reduces the number of false NMI calls when the perf + * tools are running which generate an enormous number of NMIs per + * second (~4M/s for 1024 cpu threads). Our secondary NMI handler is + * very short as it only checks that if it has been "pinged" with the + * IPI(NMI) signal as mentioned above, and does not read the UV Hub's MMR. + * + */ + +static struct uv_hub_nmi_s **uv_hub_nmi_list; + +DEFINE_PER_CPU(struct uv_cpu_nmi_s, __uv_cpu_nmi); +EXPORT_PER_CPU_SYMBOL_GPL(__uv_cpu_nmi); + +static unsigned long nmi_mmr; +static unsigned long nmi_mmr_clear; +static unsigned long nmi_mmr_pending; + +static atomic_t uv_in_nmi; +static atomic_t uv_nmi_cpu = ATOMIC_INIT(-1); +static atomic_t uv_nmi_cpus_in_nmi = ATOMIC_INIT(-1); +static atomic_t uv_nmi_slave_continue; +static atomic_t uv_nmi_kexec_failed; +static cpumask_var_t uv_nmi_cpu_mask; + +/* Values for uv_nmi_slave_continue */ +#define SLAVE_CLEAR 0 +#define SLAVE_CONTINUE 1 +#define SLAVE_EXIT 2 + +/* + * Default is all stack dumps go to the console and buffer. + * Lower level to send to log buffer only. + */ +static int uv_nmi_loglevel = 7; +module_param_named(dump_loglevel, uv_nmi_loglevel, int, 0644); + +/* + * The following values show statistics on how perf events are affecting + * this system. + */ +static int param_get_local64(char *buffer, const struct kernel_param *kp) +{ + return sprintf(buffer, "%lu\n", local64_read((local64_t *)kp->arg)); +} + +static int param_set_local64(const char *val, const struct kernel_param *kp) +{ + /* clear on any write */ + local64_set((local64_t *)kp->arg, 0); + return 0; +} + +static struct kernel_param_ops param_ops_local64 = { + .get = param_get_local64, + .set = param_set_local64, +}; +#define param_check_local64(name, p) __param_check(name, p, local64_t) + +static local64_t uv_nmi_count; +module_param_named(nmi_count, uv_nmi_count, local64, 0644); + +static local64_t uv_nmi_misses; +module_param_named(nmi_misses, uv_nmi_misses, local64, 0644); + +static local64_t uv_nmi_ping_count; +module_param_named(ping_count, uv_nmi_ping_count, local64, 0644); + +static local64_t uv_nmi_ping_misses; +module_param_named(ping_misses, uv_nmi_ping_misses, local64, 0644); + +/* + * Following values allow tuning for large systems under heavy loading + */ +static int uv_nmi_initial_delay = 100; +module_param_named(initial_delay, uv_nmi_initial_delay, int, 0644); + +static int uv_nmi_slave_delay = 100; +module_param_named(slave_delay, uv_nmi_slave_delay, int, 0644); + +static int uv_nmi_loop_delay = 100; +module_param_named(loop_delay, uv_nmi_loop_delay, int, 0644); + +static int uv_nmi_trigger_delay = 10000; +module_param_named(trigger_delay, uv_nmi_trigger_delay, int, 0644); + +static int uv_nmi_wait_count = 100; +module_param_named(wait_count, uv_nmi_wait_count, int, 0644); + +static int uv_nmi_retry_count = 500; +module_param_named(retry_count, uv_nmi_retry_count, int, 0644); + +/* + * Valid NMI Actions: + * "dump" - dump process stack for each cpu + * "ips" - dump IP info for each cpu + * "kdump" - do crash dump + * "kdb" - enter KDB/KGDB (default) + */ +static char uv_nmi_action[8] = "kdb"; +module_param_string(action, uv_nmi_action, sizeof(uv_nmi_action), 0644); + +static inline bool uv_nmi_action_is(const char *action) +{ + return (strncmp(uv_nmi_action, action, strlen(action)) == 0); +} + +/* Setup which NMI support is present in system */ +static void uv_nmi_setup_mmrs(void) +{ + if (uv_read_local_mmr(UVH_NMI_MMRX_SUPPORTED)) { + uv_write_local_mmr(UVH_NMI_MMRX_REQ, + 1UL << UVH_NMI_MMRX_REQ_SHIFT); + nmi_mmr = UVH_NMI_MMRX; + nmi_mmr_clear = UVH_NMI_MMRX_CLEAR; + nmi_mmr_pending = 1UL << UVH_NMI_MMRX_SHIFT; + pr_info("UV: SMI NMI support: %s\n", UVH_NMI_MMRX_TYPE); + } else { + nmi_mmr = UVH_NMI_MMR; + nmi_mmr_clear = UVH_NMI_MMR_CLEAR; + nmi_mmr_pending = 1UL << UVH_NMI_MMR_SHIFT; + pr_info("UV: SMI NMI support: %s\n", UVH_NMI_MMR_TYPE); + } +} + +/* Read NMI MMR and check if NMI flag was set by BMC. */ +static inline int uv_nmi_test_mmr(struct uv_hub_nmi_s *hub_nmi) +{ + hub_nmi->nmi_value = uv_read_local_mmr(nmi_mmr); + atomic_inc(&hub_nmi->read_mmr_count); + return !!(hub_nmi->nmi_value & nmi_mmr_pending); +} + +static inline void uv_local_mmr_clear_nmi(void) +{ + uv_write_local_mmr(nmi_mmr_clear, nmi_mmr_pending); +} + +/* + * If first cpu in on this hub, set hub_nmi "in_nmi" and "owner" values and + * return true. If first cpu in on the system, set global "in_nmi" flag. + */ +static int uv_set_in_nmi(int cpu, struct uv_hub_nmi_s *hub_nmi) +{ + int first = atomic_add_unless(&hub_nmi->in_nmi, 1, 1); + + if (first) { + atomic_set(&hub_nmi->cpu_owner, cpu); + if (atomic_add_unless(&uv_in_nmi, 1, 1)) + atomic_set(&uv_nmi_cpu, cpu); + + atomic_inc(&hub_nmi->nmi_count); + } + return first; +} + +/* Check if this is a system NMI event */ +static int uv_check_nmi(struct uv_hub_nmi_s *hub_nmi) +{ + int cpu = smp_processor_id(); + int nmi = 0; + + local64_inc(&uv_nmi_count); + uv_cpu_nmi.queries++; + + do { + nmi = atomic_read(&hub_nmi->in_nmi); + if (nmi) + break; + + if (raw_spin_trylock(&hub_nmi->nmi_lock)) { + + /* check hub MMR NMI flag */ + if (uv_nmi_test_mmr(hub_nmi)) { + uv_set_in_nmi(cpu, hub_nmi); + nmi = 1; + break; + } + + /* MMR NMI flag is clear */ + raw_spin_unlock(&hub_nmi->nmi_lock); + + } else { + /* wait a moment for the hub nmi locker to set flag */ + cpu_relax(); + udelay(uv_nmi_slave_delay); + + /* re-check hub in_nmi flag */ + nmi = atomic_read(&hub_nmi->in_nmi); + if (nmi) + break; + } + + /* check if this BMC missed setting the MMR NMI flag */ + if (!nmi) { + nmi = atomic_read(&uv_in_nmi); + if (nmi) + uv_set_in_nmi(cpu, hub_nmi); + } + + } while (0); + + if (!nmi) + local64_inc(&uv_nmi_misses); + + return nmi; +} + +/* Need to reset the NMI MMR register, but only once per hub. */ +static inline void uv_clear_nmi(int cpu) +{ + struct uv_hub_nmi_s *hub_nmi = uv_hub_nmi; + + if (cpu == atomic_read(&hub_nmi->cpu_owner)) { + atomic_set(&hub_nmi->cpu_owner, -1); + atomic_set(&hub_nmi->in_nmi, 0); + uv_local_mmr_clear_nmi(); + raw_spin_unlock(&hub_nmi->nmi_lock); + } +} + +/* Print non-responding cpus */ +static void uv_nmi_nr_cpus_pr(char *fmt) +{ + static char cpu_list[1024]; + int len = sizeof(cpu_list); + int c = cpumask_weight(uv_nmi_cpu_mask); + int n = cpulist_scnprintf(cpu_list, len, uv_nmi_cpu_mask); + + if (n >= len-1) + strcpy(&cpu_list[len - 6], "...\n"); + + printk(fmt, c, cpu_list); +} + +/* Ping non-responding cpus attemping to force them into the NMI handler */ +static void uv_nmi_nr_cpus_ping(void) +{ + int cpu; + + for_each_cpu(cpu, uv_nmi_cpu_mask) + atomic_set(&uv_cpu_nmi_per(cpu).pinging, 1); + + apic->send_IPI_mask(uv_nmi_cpu_mask, APIC_DM_NMI); +} + +/* Clean up flags for cpus that ignored both NMI and ping */ +static void uv_nmi_cleanup_mask(void) +{ + int cpu; + + for_each_cpu(cpu, uv_nmi_cpu_mask) { + atomic_set(&uv_cpu_nmi_per(cpu).pinging, 0); + atomic_set(&uv_cpu_nmi_per(cpu).state, UV_NMI_STATE_OUT); + cpumask_clear_cpu(cpu, uv_nmi_cpu_mask); + } +} + +/* Loop waiting as cpus enter nmi handler */ +static int uv_nmi_wait_cpus(int first) +{ + int i, j, k, n = num_online_cpus(); + int last_k = 0, waiting = 0; + + if (first) { + cpumask_copy(uv_nmi_cpu_mask, cpu_online_mask); + k = 0; + } else { + k = n - cpumask_weight(uv_nmi_cpu_mask); + } + + udelay(uv_nmi_initial_delay); + for (i = 0; i < uv_nmi_retry_count; i++) { + int loop_delay = uv_nmi_loop_delay; + + for_each_cpu(j, uv_nmi_cpu_mask) { + if (atomic_read(&uv_cpu_nmi_per(j).state)) { + cpumask_clear_cpu(j, uv_nmi_cpu_mask); + if (++k >= n) + break; + } + } + if (k >= n) { /* all in? */ + k = n; + break; + } + if (last_k != k) { /* abort if no new cpus coming in */ + last_k = k; + waiting = 0; + } else if (++waiting > uv_nmi_wait_count) + break; + + /* extend delay if waiting only for cpu 0 */ + if (waiting && (n - k) == 1 && + cpumask_test_cpu(0, uv_nmi_cpu_mask)) + loop_delay *= 100; + + udelay(loop_delay); + } + atomic_set(&uv_nmi_cpus_in_nmi, k); + return n - k; +} + +/* Wait until all slave cpus have entered UV NMI handler */ +static void uv_nmi_wait(int master) +{ + /* indicate this cpu is in */ + atomic_set(&uv_cpu_nmi.state, UV_NMI_STATE_IN); + + /* if not the first cpu in (the master), then we are a slave cpu */ + if (!master) + return; + + do { + /* wait for all other cpus to gather here */ + if (!uv_nmi_wait_cpus(1)) + break; + + /* if not all made it in, send IPI NMI to them */ + uv_nmi_nr_cpus_pr(KERN_ALERT + "UV: Sending NMI IPI to %d non-responding CPUs: %s\n"); + uv_nmi_nr_cpus_ping(); + + /* if all cpus are in, then done */ + if (!uv_nmi_wait_cpus(0)) + break; + + uv_nmi_nr_cpus_pr(KERN_ALERT + "UV: %d CPUs not in NMI loop: %s\n"); + } while (0); + + pr_alert("UV: %d of %d CPUs in NMI\n", + atomic_read(&uv_nmi_cpus_in_nmi), num_online_cpus()); +} + +static void uv_nmi_dump_cpu_ip_hdr(void) +{ + printk(KERN_DEFAULT + "\nUV: %4s %6s %-32s %s (Note: PID 0 not listed)\n", + "CPU", "PID", "COMMAND", "IP"); +} + +static void uv_nmi_dump_cpu_ip(int cpu, struct pt_regs *regs) +{ + printk(KERN_DEFAULT "UV: %4d %6d %-32.32s ", + cpu, current->pid, current->comm); + + printk_address(regs->ip); +} + +/* Dump this cpu's state */ +static void uv_nmi_dump_state_cpu(int cpu, struct pt_regs *regs) +{ + const char *dots = " ................................. "; + + if (uv_nmi_action_is("ips")) { + if (cpu == 0) + uv_nmi_dump_cpu_ip_hdr(); + + if (current->pid != 0) + uv_nmi_dump_cpu_ip(cpu, regs); + + } else if (uv_nmi_action_is("dump")) { + printk(KERN_DEFAULT + "UV:%sNMI process trace for CPU %d\n", dots, cpu); + show_regs(regs); + } + atomic_set(&uv_cpu_nmi.state, UV_NMI_STATE_DUMP_DONE); +} + +/* Trigger a slave cpu to dump it's state */ +static void uv_nmi_trigger_dump(int cpu) +{ + int retry = uv_nmi_trigger_delay; + + if (atomic_read(&uv_cpu_nmi_per(cpu).state) != UV_NMI_STATE_IN) + return; + + atomic_set(&uv_cpu_nmi_per(cpu).state, UV_NMI_STATE_DUMP); + do { + cpu_relax(); + udelay(10); + if (atomic_read(&uv_cpu_nmi_per(cpu).state) + != UV_NMI_STATE_DUMP) + return; + } while (--retry > 0); + + pr_crit("UV: CPU %d stuck in process dump function\n", cpu); + atomic_set(&uv_cpu_nmi_per(cpu).state, UV_NMI_STATE_DUMP_DONE); +} + +/* Wait until all cpus ready to exit */ +static void uv_nmi_sync_exit(int master) +{ + atomic_dec(&uv_nmi_cpus_in_nmi); + if (master) { + while (atomic_read(&uv_nmi_cpus_in_nmi) > 0) + cpu_relax(); + atomic_set(&uv_nmi_slave_continue, SLAVE_CLEAR); + } else { + while (atomic_read(&uv_nmi_slave_continue)) + cpu_relax(); + } +} + +/* Walk through cpu list and dump state of each */ +static void uv_nmi_dump_state(int cpu, struct pt_regs *regs, int master) +{ + if (master) { + int tcpu; + int ignored = 0; + int saved_console_loglevel = console_loglevel; + + pr_alert("UV: tracing %s for %d CPUs from CPU %d\n", + uv_nmi_action_is("ips") ? "IPs" : "processes", + atomic_read(&uv_nmi_cpus_in_nmi), cpu); + + console_loglevel = uv_nmi_loglevel; + atomic_set(&uv_nmi_slave_continue, SLAVE_EXIT); + for_each_online_cpu(tcpu) { + if (cpumask_test_cpu(tcpu, uv_nmi_cpu_mask)) + ignored++; + else if (tcpu == cpu) + uv_nmi_dump_state_cpu(tcpu, regs); + else + uv_nmi_trigger_dump(tcpu); + } + if (ignored) + printk(KERN_DEFAULT "UV: %d CPUs ignored NMI\n", + ignored); + + console_loglevel = saved_console_loglevel; + pr_alert("UV: process trace complete\n"); + } else { + while (!atomic_read(&uv_nmi_slave_continue)) + cpu_relax(); + while (atomic_read(&uv_cpu_nmi.state) != UV_NMI_STATE_DUMP) + cpu_relax(); + uv_nmi_dump_state_cpu(cpu, regs); + } + uv_nmi_sync_exit(master); +} + +static void uv_nmi_touch_watchdogs(void) +{ + touch_softlockup_watchdog_sync(); + clocksource_touch_watchdog(); + rcu_cpu_stall_reset(); + touch_nmi_watchdog(); +} + +#if defined(CONFIG_KEXEC) +static void uv_nmi_kdump(int cpu, int master, struct pt_regs *regs) +{ + /* Call crash to dump system state */ + if (master) { + pr_emerg("UV: NMI executing crash_kexec on CPU%d\n", cpu); + crash_kexec(regs); + + pr_emerg("UV: crash_kexec unexpectedly returned, "); + if (!kexec_crash_image) { + pr_cont("crash kernel not loaded\n"); + atomic_set(&uv_nmi_kexec_failed, 1); + uv_nmi_sync_exit(1); + return; + } + pr_cont("kexec busy, stalling cpus while waiting\n"); + } + + /* If crash exec fails the slaves should return, otherwise stall */ + while (atomic_read(&uv_nmi_kexec_failed) == 0) + mdelay(10); + + /* Crash kernel most likely not loaded, return in an orderly fashion */ + uv_nmi_sync_exit(0); +} + +#else /* !CONFIG_KEXEC */ +static inline void uv_nmi_kdump(int cpu, int master, struct pt_regs *regs) +{ + if (master) + pr_err("UV: NMI kdump: KEXEC not supported in this kernel\n"); +} +#endif /* !CONFIG_KEXEC */ + +#ifdef CONFIG_KGDB_KDB +/* Call KDB from NMI handler */ +static void uv_call_kdb(int cpu, struct pt_regs *regs, int master) +{ + int ret; + + if (master) { + /* call KGDB NMI handler as MASTER */ + ret = kgdb_nmicallin(cpu, X86_TRAP_NMI, regs, + &uv_nmi_slave_continue); + if (ret) { + pr_alert("KDB returned error, is kgdboc set?\n"); + atomic_set(&uv_nmi_slave_continue, SLAVE_EXIT); + } + } else { + /* wait for KGDB signal that it's ready for slaves to enter */ + int sig; + + do { + cpu_relax(); + sig = atomic_read(&uv_nmi_slave_continue); + } while (!sig); + + /* call KGDB as slave */ + if (sig == SLAVE_CONTINUE) + kgdb_nmicallback(cpu, regs); + } + uv_nmi_sync_exit(master); +} + +#else /* !CONFIG_KGDB_KDB */ +static inline void uv_call_kdb(int cpu, struct pt_regs *regs, int master) +{ + pr_err("UV: NMI error: KGDB/KDB is not enabled in this kernel\n"); +} +#endif /* !CONFIG_KGDB_KDB */ + +/* + * UV NMI handler + */ +int uv_handle_nmi(unsigned int reason, struct pt_regs *regs) +{ + struct uv_hub_nmi_s *hub_nmi = uv_hub_nmi; + int cpu = smp_processor_id(); + int master = 0; + unsigned long flags; + + local_irq_save(flags); + + /* If not a UV System NMI, ignore */ + if (!atomic_read(&uv_cpu_nmi.pinging) && !uv_check_nmi(hub_nmi)) { + local_irq_restore(flags); + return NMI_DONE; + } + + /* Indicate we are the first CPU into the NMI handler */ + master = (atomic_read(&uv_nmi_cpu) == cpu); + + /* If NMI action is "kdump", then attempt to do it */ + if (uv_nmi_action_is("kdump")) + uv_nmi_kdump(cpu, master, regs); + + /* Pause as all cpus enter the NMI handler */ + uv_nmi_wait(master); + + /* Dump state of each cpu */ + if (uv_nmi_action_is("ips") || uv_nmi_action_is("dump")) + uv_nmi_dump_state(cpu, regs, master); + + /* Call KDB if enabled */ + else if (uv_nmi_action_is("kdb")) + uv_call_kdb(cpu, regs, master); + + /* Clear per_cpu "in nmi" flag */ + atomic_set(&uv_cpu_nmi.state, UV_NMI_STATE_OUT); + + /* Clear MMR NMI flag on each hub */ + uv_clear_nmi(cpu); + + /* Clear global flags */ + if (master) { + if (cpumask_weight(uv_nmi_cpu_mask)) + uv_nmi_cleanup_mask(); + atomic_set(&uv_nmi_cpus_in_nmi, -1); + atomic_set(&uv_nmi_cpu, -1); + atomic_set(&uv_in_nmi, 0); + } + + uv_nmi_touch_watchdogs(); + local_irq_restore(flags); + + return NMI_HANDLED; +} + +/* + * NMI handler for pulling in CPUs when perf events are grabbing our NMI + */ +int uv_handle_nmi_ping(unsigned int reason, struct pt_regs *regs) +{ + int ret; + + uv_cpu_nmi.queries++; + if (!atomic_read(&uv_cpu_nmi.pinging)) { + local64_inc(&uv_nmi_ping_misses); + return NMI_DONE; + } + + uv_cpu_nmi.pings++; + local64_inc(&uv_nmi_ping_count); + ret = uv_handle_nmi(reason, regs); + atomic_set(&uv_cpu_nmi.pinging, 0); + return ret; +} + +void uv_register_nmi_notifier(void) +{ + if (register_nmi_handler(NMI_UNKNOWN, uv_handle_nmi, 0, "uv")) + pr_warn("UV: NMI handler failed to register\n"); + + if (register_nmi_handler(NMI_LOCAL, uv_handle_nmi_ping, 0, "uvping")) + pr_warn("UV: PING NMI handler failed to register\n"); +} + +void uv_nmi_init(void) +{ + unsigned int value; + + /* + * Unmask NMI on all cpus + */ + value = apic_read(APIC_LVT1) | APIC_DM_NMI; + value &= ~APIC_LVT_MASKED; + apic_write(APIC_LVT1, value); +} + +void uv_nmi_setup(void) +{ + int size = sizeof(void *) * (1 << NODES_SHIFT); + int cpu, nid; + + /* Setup hub nmi info */ + uv_nmi_setup_mmrs(); + uv_hub_nmi_list = kzalloc(size, GFP_KERNEL); + pr_info("UV: NMI hub list @ 0x%p (%d)\n", uv_hub_nmi_list, size); + BUG_ON(!uv_hub_nmi_list); + size = sizeof(struct uv_hub_nmi_s); + for_each_present_cpu(cpu) { + nid = cpu_to_node(cpu); + if (uv_hub_nmi_list[nid] == NULL) { + uv_hub_nmi_list[nid] = kzalloc_node(size, + GFP_KERNEL, nid); + BUG_ON(!uv_hub_nmi_list[nid]); + raw_spin_lock_init(&(uv_hub_nmi_list[nid]->nmi_lock)); + atomic_set(&uv_hub_nmi_list[nid]->cpu_owner, -1); + } + uv_hub_nmi_per(cpu) = uv_hub_nmi_list[nid]; + } + BUG_ON(!alloc_cpumask_var(&uv_nmi_cpu_mask, GFP_KERNEL)); +} + + diff --git a/arch/x86/um/Kconfig b/arch/x86/um/Kconfig index 14ef8d1dbc33..ed56a1c4ae73 100644 --- a/arch/x86/um/Kconfig +++ b/arch/x86/um/Kconfig @@ -31,6 +31,11 @@ config X86_64 def_bool 64BIT select MODULES_USE_ELF_RELA +config ARCH_DEFCONFIG + string + default "arch/um/configs/i386_defconfig" if X86_32 + default "arch/um/configs/x86_64_defconfig" if X86_64 + config RWSEM_XCHGADD_ALGORITHM def_bool 64BIT diff --git a/arch/x86/um/asm/processor_32.h b/arch/x86/um/asm/processor_32.h index 6c6689e574ce..c112de81c9e1 100644 --- a/arch/x86/um/asm/processor_32.h +++ b/arch/x86/um/asm/processor_32.h @@ -33,6 +33,8 @@ struct arch_thread { .faultinfo = { 0, 0, 0 } \ } +#define STACKSLOTS_PER_LINE 8 + static inline void arch_flush_thread(struct arch_thread *thread) { /* Clear any TLS still hanging */ @@ -53,4 +55,7 @@ static inline void arch_copy_thread(struct arch_thread *from, #define current_text_addr() \ ({ void *pc; __asm__("movl $1f,%0\n1:":"=g" (pc)); pc; }) +#define current_sp() ({ void *sp; __asm__("movl %%esp, %0" : "=r" (sp) : ); sp; }) +#define current_bp() ({ unsigned long bp; __asm__("movl %%ebp, %0" : "=r" (bp) : ); bp; }) + #endif diff --git a/arch/x86/um/asm/processor_64.h b/arch/x86/um/asm/processor_64.h index 4b02a8455bd1..c3be85205a65 100644 --- a/arch/x86/um/asm/processor_64.h +++ b/arch/x86/um/asm/processor_64.h @@ -19,6 +19,8 @@ struct arch_thread { .fs = 0, \ .faultinfo = { 0, 0, 0 } } +#define STACKSLOTS_PER_LINE 4 + static inline void arch_flush_thread(struct arch_thread *thread) { } @@ -32,4 +34,7 @@ static inline void arch_copy_thread(struct arch_thread *from, #define current_text_addr() \ ({ void *pc; __asm__("movq $1f,%0\n1:":"=g" (pc)); pc; }) +#define current_sp() ({ void *sp; __asm__("movq %%rsp, %0" : "=r" (sp) : ); sp; }) +#define current_bp() ({ unsigned long bp; __asm__("movq %%rbp, %0" : "=r" (bp) : ); bp; }) + #endif diff --git a/arch/x86/um/elfcore.c b/arch/x86/um/elfcore.c index 6bb49b687c97..7bb89a27a5e4 100644 --- a/arch/x86/um/elfcore.c +++ b/arch/x86/um/elfcore.c @@ -11,8 +11,7 @@ Elf32_Half elf_core_extra_phdrs(void) return vsyscall_ehdr ? (((struct elfhdr *)vsyscall_ehdr)->e_phnum) : 0; } -int elf_core_write_extra_phdrs(struct file *file, loff_t offset, size_t *size, - unsigned long limit) +int elf_core_write_extra_phdrs(struct coredump_params *cprm, loff_t offset) { if ( vsyscall_ehdr ) { const struct elfhdr *const ehdrp = @@ -32,17 +31,14 @@ int elf_core_write_extra_phdrs(struct file *file, loff_t offset, size_t *size, phdr.p_offset += ofs; } phdr.p_paddr = 0; /* match other core phdrs */ - *size += sizeof(phdr); - if (*size > limit - || !dump_write(file, &phdr, sizeof(phdr))) + if (!dump_emit(cprm, &phdr, sizeof(phdr))) return 0; } } return 1; } -int elf_core_write_extra_data(struct file *file, size_t *size, - unsigned long limit) +int elf_core_write_extra_data(struct coredump_params *cprm) { if ( vsyscall_ehdr ) { const struct elfhdr *const ehdrp = @@ -55,10 +51,7 @@ int elf_core_write_extra_data(struct file *file, size_t *size, if (phdrp[i].p_type == PT_LOAD) { void *addr = (void *) phdrp[i].p_vaddr; size_t filesz = phdrp[i].p_filesz; - - *size += filesz; - if (*size > limit - || !dump_write(file, addr, filesz)) + if (!dump_emit(cprm, addr, filesz)) return 0; } } diff --git a/arch/x86/um/sysrq_32.c b/arch/x86/um/sysrq_32.c index c9bee5b8c0d3..16ee0e450e3e 100644 --- a/arch/x86/um/sysrq_32.c +++ b/arch/x86/um/sysrq_32.c @@ -30,70 +30,4 @@ void show_regs(struct pt_regs *regs) printk(" DS: %04lx ES: %04lx\n", 0xffff & PT_REGS_DS(regs), 0xffff & PT_REGS_ES(regs)); - - show_trace(NULL, (unsigned long *) ®s); } - -/* Copied from i386. */ -static inline int valid_stack_ptr(struct thread_info *tinfo, void *p) -{ - return p > (void *)tinfo && - p < (void *)tinfo + THREAD_SIZE - 3; -} - -/* Adapted from i386 (we also print the address we read from). */ -static inline unsigned long print_context_stack(struct thread_info *tinfo, - unsigned long *stack, unsigned long ebp) -{ - unsigned long addr; - -#ifdef CONFIG_FRAME_POINTER - while (valid_stack_ptr(tinfo, (void *)ebp)) { - addr = *(unsigned long *)(ebp + 4); - printk("%08lx: [<%08lx>]", ebp + 4, addr); - print_symbol(" %s", addr); - printk("\n"); - ebp = *(unsigned long *)ebp; - } -#else - while (valid_stack_ptr(tinfo, stack)) { - addr = *stack; - if (__kernel_text_address(addr)) { - printk("%08lx: [<%08lx>]", (unsigned long) stack, addr); - print_symbol(" %s", addr); - printk("\n"); - } - stack++; - } -#endif - return ebp; -} - -void show_trace(struct task_struct* task, unsigned long * stack) -{ - unsigned long ebp; - struct thread_info *context; - - /* Turn this into BUG_ON if possible. */ - if (!stack) { - stack = (unsigned long*) &stack; - printk("show_trace: got NULL stack, implicit assumption task == current"); - WARN_ON(1); - } - - if (!task) - task = current; - - if (task != current) { - ebp = (unsigned long) KSTK_EBP(task); - } else { - asm ("movl %%ebp, %0" : "=r" (ebp) : ); - } - - context = (struct thread_info *) - ((unsigned long)stack & (~(THREAD_SIZE - 1))); - print_context_stack(context, stack, ebp); - - printk("\n"); -} - diff --git a/arch/x86/um/sysrq_64.c b/arch/x86/um/sysrq_64.c index a0e7fb1134a0..38b4e4abd0f8 100644 --- a/arch/x86/um/sysrq_64.c +++ b/arch/x86/um/sysrq_64.c @@ -12,7 +12,7 @@ #include <asm/ptrace.h> #include <asm/sysrq.h> -void __show_regs(struct pt_regs *regs) +void show_regs(struct pt_regs *regs) { printk("\n"); print_modules(); @@ -33,9 +33,3 @@ void __show_regs(struct pt_regs *regs) printk(KERN_INFO "R13: %016lx R14: %016lx R15: %016lx\n", PT_REGS_R13(regs), PT_REGS_R14(regs), PT_REGS_R15(regs)); } - -void show_regs(struct pt_regs *regs) -{ - __show_regs(regs); - show_trace(current, (unsigned long *) ®s); -} diff --git a/arch/x86/um/vdso/.gitignore b/arch/x86/um/vdso/.gitignore new file mode 100644 index 000000000000..9cac6d072199 --- /dev/null +++ b/arch/x86/um/vdso/.gitignore @@ -0,0 +1,2 @@ +vdso-syms.lds +vdso.lds diff --git a/arch/x86/vdso/vclock_gettime.c b/arch/x86/vdso/vclock_gettime.c index 72074d528400..2ada505067cc 100644 --- a/arch/x86/vdso/vclock_gettime.c +++ b/arch/x86/vdso/vclock_gettime.c @@ -178,7 +178,7 @@ notrace static int __always_inline do_realtime(struct timespec *ts) ts->tv_nsec = 0; do { - seq = read_seqcount_begin(>od->seq); + seq = read_seqcount_begin_no_lockdep(>od->seq); mode = gtod->clock.vclock_mode; ts->tv_sec = gtod->wall_time_sec; ns = gtod->wall_time_snsec; @@ -198,7 +198,7 @@ notrace static int do_monotonic(struct timespec *ts) ts->tv_nsec = 0; do { - seq = read_seqcount_begin(>od->seq); + seq = read_seqcount_begin_no_lockdep(>od->seq); mode = gtod->clock.vclock_mode; ts->tv_sec = gtod->monotonic_time_sec; ns = gtod->monotonic_time_snsec; @@ -214,7 +214,7 @@ notrace static int do_realtime_coarse(struct timespec *ts) { unsigned long seq; do { - seq = read_seqcount_begin(>od->seq); + seq = read_seqcount_begin_no_lockdep(>od->seq); ts->tv_sec = gtod->wall_time_coarse.tv_sec; ts->tv_nsec = gtod->wall_time_coarse.tv_nsec; } while (unlikely(read_seqcount_retry(>od->seq, seq))); @@ -225,7 +225,7 @@ notrace static int do_monotonic_coarse(struct timespec *ts) { unsigned long seq; do { - seq = read_seqcount_begin(>od->seq); + seq = read_seqcount_begin_no_lockdep(>od->seq); ts->tv_sec = gtod->monotonic_time_coarse.tv_sec; ts->tv_nsec = gtod->monotonic_time_coarse.tv_nsec; } while (unlikely(read_seqcount_retry(>od->seq, seq))); diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index fdc3ba28ca38..ce563be09cc1 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c @@ -468,8 +468,8 @@ PV_CALLEE_SAVE_REGS_THUNK(xen_pgd_val); * 3 PCD PWT UC UC UC * 4 PAT WB WC WB * 5 PAT PWT WC WP WT - * 6 PAT PCD UC- UC UC- - * 7 PAT PCD PWT UC UC UC + * 6 PAT PCD UC- rsv UC- + * 7 PAT PCD PWT UC rsv UC */ void xen_set_pat(u64 pat) @@ -796,8 +796,8 @@ static spinlock_t *xen_pte_lock(struct page *page, struct mm_struct *mm) { spinlock_t *ptl = NULL; -#if USE_SPLIT_PTLOCKS - ptl = __pte_lockptr(page); +#if USE_SPLIT_PTE_PTLOCKS + ptl = ptlock_ptr(page); spin_lock_nest_lock(ptl, &mm->page_table_lock); #endif @@ -1637,7 +1637,7 @@ static inline void xen_alloc_ptpage(struct mm_struct *mm, unsigned long pfn, __set_pfn_prot(pfn, PAGE_KERNEL_RO); - if (level == PT_PTE && USE_SPLIT_PTLOCKS) + if (level == PT_PTE && USE_SPLIT_PTE_PTLOCKS) __pin_pagetable_pfn(MMUEXT_PIN_L1_TABLE, pfn); xen_mc_issue(PARAVIRT_LAZY_MMU); @@ -1671,7 +1671,7 @@ static inline void xen_release_ptpage(unsigned long pfn, unsigned level) if (!PageHighMem(page)) { xen_mc_batch(); - if (level == PT_PTE && USE_SPLIT_PTLOCKS) + if (level == PT_PTE && USE_SPLIT_PTE_PTLOCKS) __pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, pfn); __set_pfn_prot(pfn, PAGE_KERNEL); @@ -2328,12 +2328,14 @@ static int xen_exchange_memory(unsigned long extents_in, unsigned int order_in, return success; } -int xen_create_contiguous_region(unsigned long vstart, unsigned int order, - unsigned int address_bits) +int xen_create_contiguous_region(phys_addr_t pstart, unsigned int order, + unsigned int address_bits, + dma_addr_t *dma_handle) { unsigned long *in_frames = discontig_frames, out_frame; unsigned long flags; int success; + unsigned long vstart = (unsigned long)phys_to_virt(pstart); /* * Currently an auto-translated guest will not perform I/O, nor will @@ -2368,15 +2370,17 @@ int xen_create_contiguous_region(unsigned long vstart, unsigned int order, spin_unlock_irqrestore(&xen_reservation_lock, flags); + *dma_handle = virt_to_machine(vstart).maddr; return success ? 0 : -ENOMEM; } EXPORT_SYMBOL_GPL(xen_create_contiguous_region); -void xen_destroy_contiguous_region(unsigned long vstart, unsigned int order) +void xen_destroy_contiguous_region(phys_addr_t pstart, unsigned int order) { unsigned long *out_frames = discontig_frames, in_frame; unsigned long flags; int success; + unsigned long vstart; if (xen_feature(XENFEAT_auto_translated_physmap)) return; @@ -2384,6 +2388,7 @@ void xen_destroy_contiguous_region(unsigned long vstart, unsigned int order) if (unlikely(order > MAX_CONTIG_ORDER)) return; + vstart = (unsigned long)phys_to_virt(pstart); memset((void *) vstart, 0, PAGE_SIZE << order); spin_lock_irqsave(&xen_reservation_lock, flags); diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c index a61c7d5811be..2ae8699e8767 100644 --- a/arch/x86/xen/p2m.c +++ b/arch/x86/xen/p2m.c @@ -799,10 +799,10 @@ bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn) { unsigned topidx, mididx, idx; - if (unlikely(xen_feature(XENFEAT_auto_translated_physmap))) { - BUG_ON(pfn != mfn && mfn != INVALID_P2M_ENTRY); + /* don't track P2M changes in autotranslate guests */ + if (unlikely(xen_feature(XENFEAT_auto_translated_physmap))) return true; - } + if (unlikely(pfn >= MAX_P2M_PFN)) { BUG_ON(mfn != INVALID_P2M_ENTRY); return true; diff --git a/arch/x86/xen/pci-swiotlb-xen.c b/arch/x86/xen/pci-swiotlb-xen.c index 969570491c39..0e98e5d241d0 100644 --- a/arch/x86/xen/pci-swiotlb-xen.c +++ b/arch/x86/xen/pci-swiotlb-xen.c @@ -75,8 +75,10 @@ void __init pci_xen_swiotlb_init(void) xen_swiotlb_init(1, true /* early */); dma_ops = &xen_swiotlb_dma_ops; +#ifdef CONFIG_PCI /* Make sure ACS will be enabled */ pci_request_acs(); +#endif } } @@ -92,8 +94,10 @@ int pci_xen_swiotlb_init_late(void) return rc; dma_ops = &xen_swiotlb_dma_ops; +#ifdef CONFIG_PCI /* Make sure ACS will be enabled */ pci_request_acs(); +#endif return 0; } diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c index 09f3059cb00b..68c054f59de6 100644 --- a/arch/x86/xen/setup.c +++ b/arch/x86/xen/setup.c @@ -556,7 +556,7 @@ void xen_enable_syscall(void) } #endif /* CONFIG_X86_64 */ } -void __cpuinit xen_enable_nmi(void) +void xen_enable_nmi(void) { #ifdef CONFIG_X86_64 if (register_callback(CALLBACKTYPE_nmi, nmi)) diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index 31d04758b76f..c36b325abd83 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c @@ -149,7 +149,7 @@ static int xen_smp_intr_init(unsigned int cpu) rc = bind_ipi_to_irqhandler(XEN_RESCHEDULE_VECTOR, cpu, xen_reschedule_interrupt, - IRQF_DISABLED|IRQF_PERCPU|IRQF_NOBALANCING, + IRQF_PERCPU|IRQF_NOBALANCING, resched_name, NULL); if (rc < 0) @@ -161,7 +161,7 @@ static int xen_smp_intr_init(unsigned int cpu) rc = bind_ipi_to_irqhandler(XEN_CALL_FUNCTION_VECTOR, cpu, xen_call_function_interrupt, - IRQF_DISABLED|IRQF_PERCPU|IRQF_NOBALANCING, + IRQF_PERCPU|IRQF_NOBALANCING, callfunc_name, NULL); if (rc < 0) @@ -171,7 +171,7 @@ static int xen_smp_intr_init(unsigned int cpu) debug_name = kasprintf(GFP_KERNEL, "debug%d", cpu); rc = bind_virq_to_irqhandler(VIRQ_DEBUG, cpu, xen_debug_interrupt, - IRQF_DISABLED | IRQF_PERCPU | IRQF_NOBALANCING, + IRQF_PERCPU | IRQF_NOBALANCING, debug_name, NULL); if (rc < 0) goto fail; @@ -182,7 +182,7 @@ static int xen_smp_intr_init(unsigned int cpu) rc = bind_ipi_to_irqhandler(XEN_CALL_FUNCTION_SINGLE_VECTOR, cpu, xen_call_function_single_interrupt, - IRQF_DISABLED|IRQF_PERCPU|IRQF_NOBALANCING, + IRQF_PERCPU|IRQF_NOBALANCING, callfunc_name, NULL); if (rc < 0) @@ -201,7 +201,7 @@ static int xen_smp_intr_init(unsigned int cpu) rc = bind_ipi_to_irqhandler(XEN_IRQ_WORK_VECTOR, cpu, xen_irq_work_interrupt, - IRQF_DISABLED|IRQF_PERCPU|IRQF_NOBALANCING, + IRQF_PERCPU|IRQF_NOBALANCING, callfunc_name, NULL); if (rc < 0) diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c index be6b86078957..0e36cde12f7e 100644 --- a/arch/x86/xen/spinlock.c +++ b/arch/x86/xen/spinlock.c @@ -234,7 +234,7 @@ void xen_init_lock_cpu(int cpu) irq = bind_ipi_to_irqhandler(XEN_SPIN_UNLOCK_VECTOR, cpu, dummy_handler, - IRQF_DISABLED|IRQF_PERCPU|IRQF_NOBALANCING, + IRQF_PERCPU|IRQF_NOBALANCING, name, NULL); diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c index ee365895b06b..12a1ca707b94 100644 --- a/arch/x86/xen/time.c +++ b/arch/x86/xen/time.c @@ -443,8 +443,7 @@ void xen_setup_timer(int cpu) name = "<timer kasprintf failed>"; irq = bind_virq_to_irqhandler(VIRQ_TIMER, cpu, xen_timer_interrupt, - IRQF_DISABLED|IRQF_PERCPU| - IRQF_NOBALANCING|IRQF_TIMER| + IRQF_PERCPU|IRQF_NOBALANCING|IRQF_TIMER| IRQF_FORCE_RESUME, name, NULL); diff --git a/arch/xtensa/include/asm/Kbuild b/arch/xtensa/include/asm/Kbuild index 1b982641ec35..228d6aee3a16 100644 --- a/arch/xtensa/include/asm/Kbuild +++ b/arch/xtensa/include/asm/Kbuild @@ -28,3 +28,4 @@ generic-y += termios.h generic-y += topology.h generic-y += trace_clock.h generic-y += xor.h +generic-y += preempt.h diff --git a/arch/xtensa/include/asm/pgalloc.h b/arch/xtensa/include/asm/pgalloc.h index cf914c8c249a..d38eb9237e64 100644 --- a/arch/xtensa/include/asm/pgalloc.h +++ b/arch/xtensa/include/asm/pgalloc.h @@ -38,35 +38,46 @@ static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) free_page((unsigned long)pgd); } -/* Use a slab cache for the pte pages (see also sparc64 implementation) */ - -extern struct kmem_cache *pgtable_cache; - static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) { - return kmem_cache_alloc(pgtable_cache, GFP_KERNEL|__GFP_REPEAT); + pte_t *ptep; + int i; + + ptep = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT); + if (!ptep) + return NULL; + for (i = 0; i < 1024; i++) + pte_clear(NULL, 0, ptep + i); + return ptep; } static inline pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long addr) { + pte_t *pte; struct page *page; - page = virt_to_page(pte_alloc_one_kernel(mm, addr)); - pgtable_page_ctor(page); + pte = pte_alloc_one_kernel(mm, addr); + if (!pte) + return NULL; + page = virt_to_page(pte); + if (!pgtable_page_ctor(page)) { + __free_page(page); + return NULL; + } return page; } static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) { - kmem_cache_free(pgtable_cache, pte); + free_page((unsigned long)pte); } static inline void pte_free(struct mm_struct *mm, pgtable_t pte) { pgtable_page_dtor(pte); - kmem_cache_free(pgtable_cache, page_address(pte)); + __free_page(pte); } #define pmd_pgtable(pmd) pmd_page(pmd) diff --git a/arch/xtensa/include/asm/pgtable.h b/arch/xtensa/include/asm/pgtable.h index 0fdf5d043f82..216446295ada 100644 --- a/arch/xtensa/include/asm/pgtable.h +++ b/arch/xtensa/include/asm/pgtable.h @@ -220,12 +220,11 @@ extern unsigned long empty_zero_page[1024]; #ifdef CONFIG_MMU extern pgd_t swapper_pg_dir[PAGE_SIZE/sizeof(pgd_t)]; extern void paging_init(void); -extern void pgtable_cache_init(void); #else # define swapper_pg_dir NULL static inline void paging_init(void) { } -static inline void pgtable_cache_init(void) { } #endif +static inline void pgtable_cache_init(void) { } /* * The pmd contains the kernel virtual address of the pte page. diff --git a/arch/xtensa/include/asm/prom.h b/arch/xtensa/include/asm/prom.h deleted file mode 100644 index f3d7cd2c0de7..000000000000 --- a/arch/xtensa/include/asm/prom.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _XTENSA_ASM_PROM_H -#define _XTENSA_ASM_PROM_H - -#define HAVE_ARCH_DEVTREE_FIXUPS - -#endif /* _XTENSA_ASM_PROM_H */ diff --git a/arch/xtensa/include/asm/thread_info.h b/arch/xtensa/include/asm/thread_info.h index 9481004ac119..470153e8547c 100644 --- a/arch/xtensa/include/asm/thread_info.h +++ b/arch/xtensa/include/asm/thread_info.h @@ -76,8 +76,6 @@ struct thread_info { #endif -#define PREEMPT_ACTIVE 0x10000000 - /* * macros/functions for gaining access to the thread information structure */ diff --git a/arch/xtensa/include/uapi/asm/socket.h b/arch/xtensa/include/uapi/asm/socket.h index c114483010c1..7db5c22faa68 100644 --- a/arch/xtensa/include/uapi/asm/socket.h +++ b/arch/xtensa/include/uapi/asm/socket.h @@ -87,4 +87,6 @@ #define SO_BUSY_POLL 46 +#define SO_MAX_PACING_RATE 47 + #endif /* _XTENSA_SOCKET_H */ diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S index de1dfa18d0a1..21dbe6bdb8ed 100644 --- a/arch/xtensa/kernel/entry.S +++ b/arch/xtensa/kernel/entry.S @@ -1122,7 +1122,7 @@ ENDPROC(fast_syscall_spill_registers) * a3: exctable, original value in excsave1 */ -fast_syscall_spill_registers_fixup: +ENTRY(fast_syscall_spill_registers_fixup) rsr a2, windowbase # get current windowbase (a2 is saved) xsr a0, depc # restore depc and a0 @@ -1134,22 +1134,26 @@ fast_syscall_spill_registers_fixup: */ xsr a3, excsave1 # get spill-mask - slli a2, a3, 1 # shift left by one + slli a3, a3, 1 # shift left by one - slli a3, a2, 32-WSBITS - src a2, a2, a3 # a1 = xxwww1yyxxxwww1yy...... + slli a2, a3, 32-WSBITS + src a2, a3, a2 # a2 = xxwww1yyxxxwww1yy...... wsr a2, windowstart # set corrected windowstart - rsr a3, excsave1 - l32i a2, a3, EXC_TABLE_DOUBLE_SAVE # restore a2 - l32i a3, a3, EXC_TABLE_PARAM # original WB (in user task) + srli a3, a3, 1 + rsr a2, excsave1 + l32i a2, a2, EXC_TABLE_DOUBLE_SAVE # restore a2 + xsr a2, excsave1 + s32i a3, a2, EXC_TABLE_DOUBLE_SAVE # save a3 + l32i a3, a2, EXC_TABLE_PARAM # original WB (in user task) + xsr a2, excsave1 /* Return to the original (user task) WINDOWBASE. * We leave the following frame behind: * a0, a1, a2 same - * a3: trashed (saved in excsave_1) + * a3: trashed (saved in EXC_TABLE_DOUBLE_SAVE) * depc: depc (we have to return to that address) - * excsave_1: a3 + * excsave_1: exctable */ wsr a3, windowbase @@ -1159,9 +1163,9 @@ fast_syscall_spill_registers_fixup: * a0: return address * a1: used, stack pointer * a2: kernel stack pointer - * a3: available, saved in EXCSAVE_1 + * a3: available * depc: exception address - * excsave: a3 + * excsave: exctable * Note: This frame might be the same as above. */ @@ -1181,9 +1185,12 @@ fast_syscall_spill_registers_fixup: rsr a0, exccause addx4 a0, a0, a3 # find entry in table l32i a0, a0, EXC_TABLE_FAST_USER # load handler + l32i a3, a3, EXC_TABLE_DOUBLE_SAVE jx a0 -fast_syscall_spill_registers_fixup_return: +ENDPROC(fast_syscall_spill_registers_fixup) + +ENTRY(fast_syscall_spill_registers_fixup_return) /* When we return here, all registers have been restored (a2: DEPC) */ @@ -1191,13 +1198,13 @@ fast_syscall_spill_registers_fixup_return: /* Restore fixup handler. */ - xsr a3, excsave1 - movi a2, fast_syscall_spill_registers_fixup - s32i a2, a3, EXC_TABLE_FIXUP - s32i a0, a3, EXC_TABLE_DOUBLE_SAVE - rsr a2, windowbase - s32i a2, a3, EXC_TABLE_PARAM - l32i a2, a3, EXC_TABLE_KSTK + rsr a2, excsave1 + s32i a3, a2, EXC_TABLE_DOUBLE_SAVE + movi a3, fast_syscall_spill_registers_fixup + s32i a3, a2, EXC_TABLE_FIXUP + rsr a3, windowbase + s32i a3, a2, EXC_TABLE_PARAM + l32i a2, a2, EXC_TABLE_KSTK /* Load WB at the time the exception occurred. */ @@ -1206,8 +1213,12 @@ fast_syscall_spill_registers_fixup_return: wsr a3, windowbase rsync + rsr a3, excsave1 + l32i a3, a3, EXC_TABLE_DOUBLE_SAVE + rfde +ENDPROC(fast_syscall_spill_registers_fixup_return) /* * spill all registers. diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c index 946fb8d06c8b..6e2b6638122d 100644 --- a/arch/xtensa/kernel/setup.c +++ b/arch/xtensa/kernel/setup.c @@ -21,11 +21,8 @@ #include <linux/screen_info.h> #include <linux/bootmem.h> #include <linux/kernel.h> - -#ifdef CONFIG_OF #include <linux/of_fdt.h> #include <linux/of_platform.h> -#endif #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE) # include <linux/console.h> @@ -64,8 +61,8 @@ extern struct rtc_ops no_rtc_ops; struct rtc_ops *rtc_ops; #ifdef CONFIG_BLK_DEV_INITRD -extern void *initrd_start; -extern void *initrd_end; +extern unsigned long initrd_start; +extern unsigned long initrd_end; int initrd_is_mapped = 0; extern int initrd_below_start_ok; #endif @@ -152,8 +149,8 @@ static int __init parse_tag_initrd(const bp_tag_t* tag) { meminfo_t* mi; mi = (meminfo_t*)(tag->data); - initrd_start = __va(mi->start); - initrd_end = __va(mi->end); + initrd_start = (unsigned long)__va(mi->start); + initrd_end = (unsigned long)__va(mi->end); return 0; } @@ -170,13 +167,6 @@ static int __init parse_tag_fdt(const bp_tag_t *tag) __tagtable(BP_TAG_FDT, parse_tag_fdt); -void __init early_init_dt_setup_initrd_arch(u64 start, u64 end) -{ - initrd_start = (void *)__va(start); - initrd_end = (void *)__va(end); - initrd_below_start_ok = 1; -} - #endif /* CONFIG_OF */ #endif /* CONFIG_BLK_DEV_INITRD */ @@ -222,9 +212,13 @@ static int __init parse_bootparam(const bp_tag_t* tag) } #ifdef CONFIG_OF +bool __initdata dt_memory_scan = false; void __init early_init_dt_add_memory_arch(u64 base, u64 size) { + if (!dt_memory_scan) + return; + size &= PAGE_MASK; add_sysmem_bank(MEMORY_TYPE_CONVENTIONAL, base, base + size); } @@ -236,31 +230,13 @@ void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) void __init early_init_devtree(void *params) { - /* Setup flat device-tree pointer */ - initial_boot_params = params; - - /* Retrieve various informations from the /chosen node of the - * device-tree, including the platform type, initrd location and - * size, TCE reserve, and more ... - */ - if (!command_line[0]) - of_scan_flat_dt(early_init_dt_scan_chosen, command_line); - - /* Scan memory nodes and rebuild MEMBLOCKs */ - of_scan_flat_dt(early_init_dt_scan_root, NULL); if (sysmem.nr_banks == 0) - of_scan_flat_dt(early_init_dt_scan_memory, NULL); -} + dt_memory_scan = true; -static void __init copy_devtree(void) -{ - void *alloc = early_init_dt_alloc_memory_arch( - be32_to_cpu(initial_boot_params->totalsize), 8); - if (alloc) { - memcpy(alloc, initial_boot_params, - be32_to_cpu(initial_boot_params->totalsize)); - initial_boot_params = alloc; - } + early_init_dt_scan(params); + + if (!command_line[0]) + strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); } static int __init xtensa_device_probe(void) @@ -525,10 +501,7 @@ void __init setup_arch(char **cmdline_p) bootmem_init(); -#ifdef CONFIG_OF - copy_devtree(); - unflatten_device_tree(); -#endif + unflatten_and_copy_device_tree(); platform_setup(cmdline_p); diff --git a/arch/xtensa/kernel/signal.c b/arch/xtensa/kernel/signal.c index 718eca1850bd..98b67d5f1514 100644 --- a/arch/xtensa/kernel/signal.c +++ b/arch/xtensa/kernel/signal.c @@ -341,7 +341,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info, sp = regs->areg[1]; - if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! on_sig_stack(sp)) { + if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && sas_ss_flags(sp) == 0) { sp = current->sas_ss_sp + current->sas_ss_size; } diff --git a/arch/xtensa/mm/mmu.c b/arch/xtensa/mm/mmu.c index a1077570e383..c43771c974be 100644 --- a/arch/xtensa/mm/mmu.c +++ b/arch/xtensa/mm/mmu.c @@ -50,23 +50,3 @@ void __init init_mmu(void) */ set_ptevaddr_register(PGTABLE_START); } - -struct kmem_cache *pgtable_cache __read_mostly; - -static void pgd_ctor(void *addr) -{ - pte_t *ptep = (pte_t *)addr; - int i; - - for (i = 0; i < 1024; i++, ptep++) - pte_clear(NULL, 0, ptep); - -} - -void __init pgtable_cache_init(void) -{ - pgtable_cache = kmem_cache_create("pgd", - PAGE_SIZE, PAGE_SIZE, - SLAB_HWCACHE_ALIGN, - pgd_ctor); -} diff --git a/arch/xtensa/platforms/iss/network.c b/arch/xtensa/platforms/iss/network.c index 56f88b7afe2f..e9e1aad8c271 100644 --- a/arch/xtensa/platforms/iss/network.c +++ b/arch/xtensa/platforms/iss/network.c @@ -737,7 +737,8 @@ static int __init iss_net_setup(char *str) return 1; } - if ((new = alloc_bootmem(sizeof new)) == NULL) { + new = alloc_bootmem(sizeof(*new)); + if (new == NULL) { printk("Alloc_bootmem failed\n"); return 1; } |