diff options
| author | Paul Mundt <lethal@linux-sh.org> | 2012-08-01 00:49:13 -0400 |
|---|---|---|
| committer | Paul Mundt <lethal@linux-sh.org> | 2012-08-01 00:49:13 -0400 |
| commit | 91ba548cfd5cc8ee93b9435527efb8fa4caf5c5e (patch) | |
| tree | c96ed92413044a28d17783e84a8824bfd2437af1 /arch | |
| parent | b9ccfda293ee6fca9a89a1584f0900e0627b975e (diff) | |
| parent | 4dc4c51675c137c30838425ecc8d471ff5eb138b (diff) | |
Merge branch 'sh/dmaengine' into sh-latest
Diffstat (limited to 'arch')
510 files changed, 16618 insertions, 8244 deletions
diff --git a/arch/Kconfig b/arch/Kconfig index 8c3d957fa8e2..72f2fa189cc5 100644 --- a/arch/Kconfig +++ b/arch/Kconfig | |||
| @@ -248,7 +248,14 @@ config HAVE_CMPXCHG_LOCAL | |||
| 248 | config HAVE_CMPXCHG_DOUBLE | 248 | config HAVE_CMPXCHG_DOUBLE |
| 249 | bool | 249 | bool |
| 250 | 250 | ||
| 251 | config ARCH_WANT_IPC_PARSE_VERSION | ||
| 252 | bool | ||
| 253 | |||
| 254 | config ARCH_WANT_COMPAT_IPC_PARSE_VERSION | ||
| 255 | bool | ||
| 256 | |||
| 251 | config ARCH_WANT_OLD_COMPAT_IPC | 257 | config ARCH_WANT_OLD_COMPAT_IPC |
| 258 | select ARCH_WANT_COMPAT_IPC_PARSE_VERSION | ||
| 252 | bool | 259 | bool |
| 253 | 260 | ||
| 254 | config HAVE_ARCH_SECCOMP_FILTER | 261 | config HAVE_ARCH_SECCOMP_FILTER |
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index 3de74c9f9610..d5b9b5e645cc 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig | |||
| @@ -14,6 +14,7 @@ config ALPHA | |||
| 14 | select AUTO_IRQ_AFFINITY if SMP | 14 | select AUTO_IRQ_AFFINITY if SMP |
| 15 | select GENERIC_IRQ_SHOW | 15 | select GENERIC_IRQ_SHOW |
| 16 | select ARCH_WANT_OPTIONAL_GPIOLIB | 16 | select ARCH_WANT_OPTIONAL_GPIOLIB |
| 17 | select ARCH_WANT_IPC_PARSE_VERSION | ||
| 17 | select ARCH_HAVE_NMI_SAFE_CMPXCHG | 18 | select ARCH_HAVE_NMI_SAFE_CMPXCHG |
| 18 | select GENERIC_SMP_IDLE_THREAD | 19 | select GENERIC_SMP_IDLE_THREAD |
| 19 | select GENERIC_CMOS_UPDATE | 20 | select GENERIC_CMOS_UPDATE |
diff --git a/arch/alpha/include/asm/unistd.h b/arch/alpha/include/asm/unistd.h index d1f23b722df4..633b23b0664a 100644 --- a/arch/alpha/include/asm/unistd.h +++ b/arch/alpha/include/asm/unistd.h | |||
| @@ -470,7 +470,6 @@ | |||
| 470 | 470 | ||
| 471 | #define NR_SYSCALLS 504 | 471 | #define NR_SYSCALLS 504 |
| 472 | 472 | ||
| 473 | #define __ARCH_WANT_IPC_PARSE_VERSION | ||
| 474 | #define __ARCH_WANT_OLD_READDIR | 473 | #define __ARCH_WANT_OLD_READDIR |
| 475 | #define __ARCH_WANT_STAT64 | 474 | #define __ARCH_WANT_STAT64 |
| 476 | #define __ARCH_WANT_SYS_GETHOSTNAME | 475 | #define __ARCH_WANT_SYS_GETHOSTNAME |
diff --git a/arch/alpha/kernel/smc37c669.c b/arch/alpha/kernel/smc37c669.c index 0435921d41c6..c803fc76ae4f 100644 --- a/arch/alpha/kernel/smc37c669.c +++ b/arch/alpha/kernel/smc37c669.c | |||
| @@ -933,18 +933,6 @@ void SMC37c669_display_device_info( | |||
| 933 | * | 933 | * |
| 934 | *-- | 934 | *-- |
| 935 | */ | 935 | */ |
| 936 | #if 0 | ||
| 937 | /* $INCLUDE_OPTIONS$ */ | ||
| 938 | #include "cp$inc:platform_io.h" | ||
| 939 | /* $INCLUDE_OPTIONS_END$ */ | ||
| 940 | #include "cp$src:common.h" | ||
| 941 | #include "cp$inc:prototypes.h" | ||
| 942 | #include "cp$src:kernel_def.h" | ||
| 943 | #include "cp$src:msg_def.h" | ||
| 944 | #include "cp$src:smcc669_def.h" | ||
| 945 | /* Platform-specific includes */ | ||
| 946 | #include "cp$src:platform.h" | ||
| 947 | #endif | ||
| 948 | 936 | ||
| 949 | #ifndef TRUE | 937 | #ifndef TRUE |
| 950 | #define TRUE 1 | 938 | #define TRUE 1 |
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index b25c9d3c379a..7980873525b2 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
| @@ -11,6 +11,7 @@ config ARM | |||
| 11 | select RTC_LIB | 11 | select RTC_LIB |
| 12 | select SYS_SUPPORTS_APM_EMULATION | 12 | select SYS_SUPPORTS_APM_EMULATION |
| 13 | select GENERIC_ATOMIC64 if (CPU_V6 || !CPU_32v6K || !AEABI) | 13 | select GENERIC_ATOMIC64 if (CPU_V6 || !CPU_32v6K || !AEABI) |
| 14 | select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE | ||
| 14 | select HAVE_OPROFILE if (HAVE_PERF_EVENTS) | 15 | select HAVE_OPROFILE if (HAVE_PERF_EVENTS) |
| 15 | select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL | 16 | select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL |
| 16 | select HAVE_ARCH_KGDB | 17 | select HAVE_ARCH_KGDB |
| @@ -38,6 +39,7 @@ config ARM | |||
| 38 | select GENERIC_IRQ_PROBE | 39 | select GENERIC_IRQ_PROBE |
| 39 | select GENERIC_IRQ_SHOW | 40 | select GENERIC_IRQ_SHOW |
| 40 | select GENERIC_IRQ_PROBE | 41 | select GENERIC_IRQ_PROBE |
| 42 | select ARCH_WANT_IPC_PARSE_VERSION | ||
| 41 | select HARDIRQS_SW_RESEND | 43 | select HARDIRQS_SW_RESEND |
| 42 | select CPU_PM if (SUSPEND || CPU_IDLE) | 44 | select CPU_PM if (SUSPEND || CPU_IDLE) |
| 43 | select GENERIC_PCI_IOMAP | 45 | select GENERIC_PCI_IOMAP |
| @@ -45,6 +47,9 @@ config ARM | |||
| 45 | select GENERIC_SMP_IDLE_THREAD | 47 | select GENERIC_SMP_IDLE_THREAD |
| 46 | select KTIME_SCALAR | 48 | select KTIME_SCALAR |
| 47 | select GENERIC_CLOCKEVENTS_BROADCAST if SMP | 49 | select GENERIC_CLOCKEVENTS_BROADCAST if SMP |
| 50 | select GENERIC_STRNCPY_FROM_USER | ||
| 51 | select GENERIC_STRNLEN_USER | ||
| 52 | select DCACHE_WORD_ACCESS if (CPU_V6 || CPU_V6K || CPU_V7) && !CPU_BIG_ENDIAN | ||
| 48 | help | 53 | help |
| 49 | The ARM series is a line of low-power-consumption RISC chip designs | 54 | The ARM series is a line of low-power-consumption RISC chip designs |
| 50 | licensed by ARM Ltd and targeted at embedded applications and | 55 | licensed by ARM Ltd and targeted at embedded applications and |
| @@ -279,7 +284,6 @@ config ARCH_INTEGRATOR | |||
| 279 | select ICST | 284 | select ICST |
| 280 | select GENERIC_CLOCKEVENTS | 285 | select GENERIC_CLOCKEVENTS |
| 281 | select PLAT_VERSATILE | 286 | select PLAT_VERSATILE |
| 282 | select PLAT_VERSATILE_CLOCK | ||
| 283 | select PLAT_VERSATILE_FPGA_IRQ | 287 | select PLAT_VERSATILE_FPGA_IRQ |
| 284 | select NEED_MACH_IO_H | 288 | select NEED_MACH_IO_H |
| 285 | select NEED_MACH_MEMORY_H | 289 | select NEED_MACH_MEMORY_H |
| @@ -336,7 +340,6 @@ config ARCH_VEXPRESS | |||
| 336 | select ICST | 340 | select ICST |
| 337 | select NO_IOPORT | 341 | select NO_IOPORT |
| 338 | select PLAT_VERSATILE | 342 | select PLAT_VERSATILE |
| 339 | select PLAT_VERSATILE_CLOCK | ||
| 340 | select PLAT_VERSATILE_CLCD | 343 | select PLAT_VERSATILE_CLCD |
| 341 | select REGULATOR_FIXED_VOLTAGE if REGULATOR | 344 | select REGULATOR_FIXED_VOLTAGE if REGULATOR |
| 342 | help | 345 | help |
| @@ -1008,7 +1011,6 @@ config ARCH_VT8500 | |||
| 1008 | select ARCH_HAS_CPUFREQ | 1011 | select ARCH_HAS_CPUFREQ |
| 1009 | select GENERIC_CLOCKEVENTS | 1012 | select GENERIC_CLOCKEVENTS |
| 1010 | select ARCH_REQUIRE_GPIOLIB | 1013 | select ARCH_REQUIRE_GPIOLIB |
| 1011 | select HAVE_PWM | ||
| 1012 | help | 1014 | help |
| 1013 | Support for VIA/WonderMedia VT8500/WM85xx System-on-Chip. | 1015 | Support for VIA/WonderMedia VT8500/WM85xx System-on-Chip. |
| 1014 | 1016 | ||
| @@ -2006,6 +2008,25 @@ config ARM_ATAG_DTB_COMPAT | |||
| 2006 | bootloaders, this option allows zImage to extract the information | 2008 | bootloaders, this option allows zImage to extract the information |
| 2007 | from the ATAG list and store it at run time into the appended DTB. | 2009 | from the ATAG list and store it at run time into the appended DTB. |
| 2008 | 2010 | ||
| 2011 | choice | ||
| 2012 | prompt "Kernel command line type" if ARM_ATAG_DTB_COMPAT | ||
| 2013 | default ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER | ||
| 2014 | |||
| 2015 | config ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER | ||
| 2016 | bool "Use bootloader kernel arguments if available" | ||
| 2017 | help | ||
| 2018 | Uses the command-line options passed by the boot loader instead of | ||
| 2019 | the device tree bootargs property. If the boot loader doesn't provide | ||
| 2020 | any, the device tree bootargs property will be used. | ||
| 2021 | |||
| 2022 | config ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND | ||
| 2023 | bool "Extend with bootloader kernel arguments" | ||
| 2024 | help | ||
| 2025 | The command-line arguments provided by the boot loader will be | ||
| 2026 | appended to the the device tree bootargs property. | ||
| 2027 | |||
| 2028 | endchoice | ||
| 2029 | |||
| 2009 | config CMDLINE | 2030 | config CMDLINE |
| 2010 | string "Default kernel command string" | 2031 | string "Default kernel command string" |
| 2011 | default "" | 2032 | default "" |
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index a03b5a7059e2..f15f82bf3a50 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug | |||
| @@ -395,4 +395,13 @@ config ARM_KPROBES_TEST | |||
| 395 | help | 395 | help |
| 396 | Perform tests of kprobes API and instruction set simulation. | 396 | Perform tests of kprobes API and instruction set simulation. |
| 397 | 397 | ||
| 398 | config PID_IN_CONTEXTIDR | ||
| 399 | bool "Write the current PID to the CONTEXTIDR register" | ||
| 400 | depends on CPU_COPY_V6 | ||
| 401 | help | ||
| 402 | Enabling this option causes the kernel to write the current PID to | ||
| 403 | the PROCID field of the CONTEXTIDR register, at the expense of some | ||
| 404 | additional instructions during context switch. Say Y here only if you | ||
| 405 | are planning to use hardware trace tools with this kernel. | ||
| 406 | |||
| 398 | endmenu | 407 | endmenu |
diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 4d6d31115cf2..30eae87ead6d 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile | |||
| @@ -10,6 +10,9 @@ | |||
| 10 | # | 10 | # |
| 11 | # Copyright (C) 1995-2001 by Russell King | 11 | # Copyright (C) 1995-2001 by Russell King |
| 12 | 12 | ||
| 13 | # Ensure linker flags are correct | ||
| 14 | LDFLAGS := | ||
| 15 | |||
| 13 | LDFLAGS_vmlinux :=-p --no-undefined -X | 16 | LDFLAGS_vmlinux :=-p --no-undefined -X |
| 14 | ifeq ($(CONFIG_CPU_ENDIAN_BE8),y) | 17 | ifeq ($(CONFIG_CPU_ENDIAN_BE8),y) |
| 15 | LDFLAGS_vmlinux += --be8 | 18 | LDFLAGS_vmlinux += --be8 |
diff --git a/arch/arm/boot/compressed/atags_to_fdt.c b/arch/arm/boot/compressed/atags_to_fdt.c index 797f04bedb47..aabc02a68482 100644 --- a/arch/arm/boot/compressed/atags_to_fdt.c +++ b/arch/arm/boot/compressed/atags_to_fdt.c | |||
| @@ -1,6 +1,12 @@ | |||
| 1 | #include <asm/setup.h> | 1 | #include <asm/setup.h> |
| 2 | #include <libfdt.h> | 2 | #include <libfdt.h> |
| 3 | 3 | ||
| 4 | #if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND) | ||
| 5 | #define do_extend_cmdline 1 | ||
| 6 | #else | ||
| 7 | #define do_extend_cmdline 0 | ||
| 8 | #endif | ||
| 9 | |||
| 4 | static int node_offset(void *fdt, const char *node_path) | 10 | static int node_offset(void *fdt, const char *node_path) |
| 5 | { | 11 | { |
| 6 | int offset = fdt_path_offset(fdt, node_path); | 12 | int offset = fdt_path_offset(fdt, node_path); |
| @@ -36,6 +42,48 @@ static int setprop_cell(void *fdt, const char *node_path, | |||
| 36 | return fdt_setprop_cell(fdt, offset, property, val); | 42 | return fdt_setprop_cell(fdt, offset, property, val); |
| 37 | } | 43 | } |
| 38 | 44 | ||
| 45 | static const void *getprop(const void *fdt, const char *node_path, | ||
| 46 | const char *property, int *len) | ||
| 47 | { | ||
| 48 | int offset = fdt_path_offset(fdt, node_path); | ||
| 49 | |||
| 50 | if (offset == -FDT_ERR_NOTFOUND) | ||
| 51 | return NULL; | ||
| 52 | |||
| 53 | return fdt_getprop(fdt, offset, property, len); | ||
| 54 | } | ||
| 55 | |||
| 56 | static void merge_fdt_bootargs(void *fdt, const char *fdt_cmdline) | ||
| 57 | { | ||
| 58 | char cmdline[COMMAND_LINE_SIZE]; | ||
| 59 | const char *fdt_bootargs; | ||
| 60 | char *ptr = cmdline; | ||
| 61 | int len = 0; | ||
| 62 | |||
| 63 | /* copy the fdt command line into the buffer */ | ||
| 64 | fdt_bootargs = getprop(fdt, "/chosen", "bootargs", &len); | ||
| 65 | if (fdt_bootargs) | ||
| 66 | if (len < COMMAND_LINE_SIZE) { | ||
| 67 | memcpy(ptr, fdt_bootargs, len); | ||
| 68 | /* len is the length of the string | ||
| 69 | * including the NULL terminator */ | ||
| 70 | ptr += len - 1; | ||
| 71 | } | ||
| 72 | |||
| 73 | /* and append the ATAG_CMDLINE */ | ||
| 74 | if (fdt_cmdline) { | ||
| 75 | len = strlen(fdt_cmdline); | ||
| 76 | if (ptr - cmdline + len + 2 < COMMAND_LINE_SIZE) { | ||
| 77 | *ptr++ = ' '; | ||
| 78 | memcpy(ptr, fdt_cmdline, len); | ||
| 79 | ptr += len; | ||
| 80 | } | ||
| 81 | } | ||
| 82 | *ptr = '\0'; | ||
| 83 | |||
| 84 | setprop_string(fdt, "/chosen", "bootargs", cmdline); | ||
| 85 | } | ||
| 86 | |||
| 39 | /* | 87 | /* |
| 40 | * Convert and fold provided ATAGs into the provided FDT. | 88 | * Convert and fold provided ATAGs into the provided FDT. |
| 41 | * | 89 | * |
| @@ -72,8 +120,18 @@ int atags_to_fdt(void *atag_list, void *fdt, int total_space) | |||
| 72 | 120 | ||
| 73 | for_each_tag(atag, atag_list) { | 121 | for_each_tag(atag, atag_list) { |
| 74 | if (atag->hdr.tag == ATAG_CMDLINE) { | 122 | if (atag->hdr.tag == ATAG_CMDLINE) { |
| 75 | setprop_string(fdt, "/chosen", "bootargs", | 123 | /* Append the ATAGS command line to the device tree |
| 76 | atag->u.cmdline.cmdline); | 124 | * command line. |
| 125 | * NB: This means that if the same parameter is set in | ||
| 126 | * the device tree and in the tags, the one from the | ||
| 127 | * tags will be chosen. | ||
| 128 | */ | ||
| 129 | if (do_extend_cmdline) | ||
| 130 | merge_fdt_bootargs(fdt, | ||
| 131 | atag->u.cmdline.cmdline); | ||
| 132 | else | ||
| 133 | setprop_string(fdt, "/chosen", "bootargs", | ||
| 134 | atag->u.cmdline.cmdline); | ||
| 77 | } else if (atag->hdr.tag == ATAG_MEM) { | 135 | } else if (atag->hdr.tag == ATAG_MEM) { |
| 78 | if (memcount >= sizeof(mem_reg_property)/4) | 136 | if (memcount >= sizeof(mem_reg_property)/4) |
| 79 | continue; | 137 | continue; |
diff --git a/arch/arm/boot/dts/highbank.dts b/arch/arm/boot/dts/highbank.dts index 2e1cfa00c25b..9fecf1ae777b 100644 --- a/arch/arm/boot/dts/highbank.dts +++ b/arch/arm/boot/dts/highbank.dts | |||
| @@ -130,6 +130,12 @@ | |||
| 130 | clocks = <&eclk>; | 130 | clocks = <&eclk>; |
| 131 | }; | 131 | }; |
| 132 | 132 | ||
| 133 | memory-controller@fff00000 { | ||
| 134 | compatible = "calxeda,hb-ddr-ctrl"; | ||
| 135 | reg = <0xfff00000 0x1000>; | ||
| 136 | interrupts = <0 91 4>; | ||
| 137 | }; | ||
| 138 | |||
| 133 | ipc@fff20000 { | 139 | ipc@fff20000 { |
| 134 | compatible = "arm,pl320", "arm,primecell"; | 140 | compatible = "arm,pl320", "arm,primecell"; |
| 135 | reg = <0xfff20000 0x1000>; | 141 | reg = <0xfff20000 0x1000>; |
| @@ -275,6 +281,12 @@ | |||
| 275 | }; | 281 | }; |
| 276 | }; | 282 | }; |
| 277 | 283 | ||
| 284 | sregs@fff3c200 { | ||
| 285 | compatible = "calxeda,hb-sregs-l2-ecc"; | ||
| 286 | reg = <0xfff3c200 0x100>; | ||
| 287 | interrupts = <0 71 4 0 72 4>; | ||
| 288 | }; | ||
| 289 | |||
| 278 | dma@fff3d000 { | 290 | dma@fff3d000 { |
| 279 | compatible = "arm,pl330", "arm,primecell"; | 291 | compatible = "arm,pl330", "arm,primecell"; |
| 280 | reg = <0xfff3d000 0x1000>; | 292 | reg = <0xfff3d000 0x1000>; |
diff --git a/arch/arm/boot/dts/imx28.dtsi b/arch/arm/boot/dts/imx28.dtsi index 915db89e3644..787efac68da8 100644 --- a/arch/arm/boot/dts/imx28.dtsi +++ b/arch/arm/boot/dts/imx28.dtsi | |||
| @@ -660,6 +660,7 @@ | |||
| 660 | compatible = "fsl,imx28-i2c"; | 660 | compatible = "fsl,imx28-i2c"; |
| 661 | reg = <0x80058000 2000>; | 661 | reg = <0x80058000 2000>; |
| 662 | interrupts = <111 68>; | 662 | interrupts = <111 68>; |
| 663 | clock-frequency = <100000>; | ||
| 663 | status = "disabled"; | 664 | status = "disabled"; |
| 664 | }; | 665 | }; |
| 665 | 666 | ||
| @@ -669,6 +670,7 @@ | |||
| 669 | compatible = "fsl,imx28-i2c"; | 670 | compatible = "fsl,imx28-i2c"; |
| 670 | reg = <0x8005a000 2000>; | 671 | reg = <0x8005a000 2000>; |
| 671 | interrupts = <110 69>; | 672 | interrupts = <110 69>; |
| 673 | clock-frequency = <100000>; | ||
| 672 | status = "disabled"; | 674 | status = "disabled"; |
| 673 | }; | 675 | }; |
| 674 | 676 | ||
diff --git a/arch/arm/boot/dts/imx51.dtsi b/arch/arm/boot/dts/imx51.dtsi index 922adefdd291..53cbaa3d4f90 100644 --- a/arch/arm/boot/dts/imx51.dtsi +++ b/arch/arm/boot/dts/imx51.dtsi | |||
| @@ -127,7 +127,7 @@ | |||
| 127 | }; | 127 | }; |
| 128 | 128 | ||
| 129 | gpio1: gpio@73f84000 { | 129 | gpio1: gpio@73f84000 { |
| 130 | compatible = "fsl,imx51-gpio", "fsl,imx31-gpio"; | 130 | compatible = "fsl,imx51-gpio", "fsl,imx35-gpio"; |
| 131 | reg = <0x73f84000 0x4000>; | 131 | reg = <0x73f84000 0x4000>; |
| 132 | interrupts = <50 51>; | 132 | interrupts = <50 51>; |
| 133 | gpio-controller; | 133 | gpio-controller; |
| @@ -137,7 +137,7 @@ | |||
| 137 | }; | 137 | }; |
| 138 | 138 | ||
| 139 | gpio2: gpio@73f88000 { | 139 | gpio2: gpio@73f88000 { |
| 140 | compatible = "fsl,imx51-gpio", "fsl,imx31-gpio"; | 140 | compatible = "fsl,imx51-gpio", "fsl,imx35-gpio"; |
| 141 | reg = <0x73f88000 0x4000>; | 141 | reg = <0x73f88000 0x4000>; |
| 142 | interrupts = <52 53>; | 142 | interrupts = <52 53>; |
| 143 | gpio-controller; | 143 | gpio-controller; |
| @@ -147,7 +147,7 @@ | |||
| 147 | }; | 147 | }; |
| 148 | 148 | ||
| 149 | gpio3: gpio@73f8c000 { | 149 | gpio3: gpio@73f8c000 { |
| 150 | compatible = "fsl,imx51-gpio", "fsl,imx31-gpio"; | 150 | compatible = "fsl,imx51-gpio", "fsl,imx35-gpio"; |
| 151 | reg = <0x73f8c000 0x4000>; | 151 | reg = <0x73f8c000 0x4000>; |
| 152 | interrupts = <54 55>; | 152 | interrupts = <54 55>; |
| 153 | gpio-controller; | 153 | gpio-controller; |
| @@ -157,7 +157,7 @@ | |||
| 157 | }; | 157 | }; |
| 158 | 158 | ||
| 159 | gpio4: gpio@73f90000 { | 159 | gpio4: gpio@73f90000 { |
| 160 | compatible = "fsl,imx51-gpio", "fsl,imx31-gpio"; | 160 | compatible = "fsl,imx51-gpio", "fsl,imx35-gpio"; |
| 161 | reg = <0x73f90000 0x4000>; | 161 | reg = <0x73f90000 0x4000>; |
| 162 | interrupts = <56 57>; | 162 | interrupts = <56 57>; |
| 163 | gpio-controller; | 163 | gpio-controller; |
diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi index 4e735edc78ed..fc79cdc4b4e6 100644 --- a/arch/arm/boot/dts/imx53.dtsi +++ b/arch/arm/boot/dts/imx53.dtsi | |||
| @@ -129,7 +129,7 @@ | |||
| 129 | }; | 129 | }; |
| 130 | 130 | ||
| 131 | gpio1: gpio@53f84000 { | 131 | gpio1: gpio@53f84000 { |
| 132 | compatible = "fsl,imx53-gpio", "fsl,imx31-gpio"; | 132 | compatible = "fsl,imx53-gpio", "fsl,imx35-gpio"; |
| 133 | reg = <0x53f84000 0x4000>; | 133 | reg = <0x53f84000 0x4000>; |
| 134 | interrupts = <50 51>; | 134 | interrupts = <50 51>; |
| 135 | gpio-controller; | 135 | gpio-controller; |
| @@ -139,7 +139,7 @@ | |||
| 139 | }; | 139 | }; |
| 140 | 140 | ||
| 141 | gpio2: gpio@53f88000 { | 141 | gpio2: gpio@53f88000 { |
| 142 | compatible = "fsl,imx53-gpio", "fsl,imx31-gpio"; | 142 | compatible = "fsl,imx53-gpio", "fsl,imx35-gpio"; |
| 143 | reg = <0x53f88000 0x4000>; | 143 | reg = <0x53f88000 0x4000>; |
| 144 | interrupts = <52 53>; | 144 | interrupts = <52 53>; |
| 145 | gpio-controller; | 145 | gpio-controller; |
| @@ -149,7 +149,7 @@ | |||
| 149 | }; | 149 | }; |
| 150 | 150 | ||
| 151 | gpio3: gpio@53f8c000 { | 151 | gpio3: gpio@53f8c000 { |
| 152 | compatible = "fsl,imx53-gpio", "fsl,imx31-gpio"; | 152 | compatible = "fsl,imx53-gpio", "fsl,imx35-gpio"; |
| 153 | reg = <0x53f8c000 0x4000>; | 153 | reg = <0x53f8c000 0x4000>; |
| 154 | interrupts = <54 55>; | 154 | interrupts = <54 55>; |
| 155 | gpio-controller; | 155 | gpio-controller; |
| @@ -159,7 +159,7 @@ | |||
| 159 | }; | 159 | }; |
| 160 | 160 | ||
| 161 | gpio4: gpio@53f90000 { | 161 | gpio4: gpio@53f90000 { |
| 162 | compatible = "fsl,imx53-gpio", "fsl,imx31-gpio"; | 162 | compatible = "fsl,imx53-gpio", "fsl,imx35-gpio"; |
| 163 | reg = <0x53f90000 0x4000>; | 163 | reg = <0x53f90000 0x4000>; |
| 164 | interrupts = <56 57>; | 164 | interrupts = <56 57>; |
| 165 | gpio-controller; | 165 | gpio-controller; |
| @@ -197,7 +197,7 @@ | |||
| 197 | }; | 197 | }; |
| 198 | 198 | ||
| 199 | gpio5: gpio@53fdc000 { | 199 | gpio5: gpio@53fdc000 { |
| 200 | compatible = "fsl,imx53-gpio", "fsl,imx31-gpio"; | 200 | compatible = "fsl,imx53-gpio", "fsl,imx35-gpio"; |
| 201 | reg = <0x53fdc000 0x4000>; | 201 | reg = <0x53fdc000 0x4000>; |
| 202 | interrupts = <103 104>; | 202 | interrupts = <103 104>; |
| 203 | gpio-controller; | 203 | gpio-controller; |
| @@ -207,7 +207,7 @@ | |||
| 207 | }; | 207 | }; |
| 208 | 208 | ||
| 209 | gpio6: gpio@53fe0000 { | 209 | gpio6: gpio@53fe0000 { |
| 210 | compatible = "fsl,imx53-gpio", "fsl,imx31-gpio"; | 210 | compatible = "fsl,imx53-gpio", "fsl,imx35-gpio"; |
| 211 | reg = <0x53fe0000 0x4000>; | 211 | reg = <0x53fe0000 0x4000>; |
| 212 | interrupts = <105 106>; | 212 | interrupts = <105 106>; |
| 213 | gpio-controller; | 213 | gpio-controller; |
| @@ -217,7 +217,7 @@ | |||
| 217 | }; | 217 | }; |
| 218 | 218 | ||
| 219 | gpio7: gpio@53fe4000 { | 219 | gpio7: gpio@53fe4000 { |
| 220 | compatible = "fsl,imx53-gpio", "fsl,imx31-gpio"; | 220 | compatible = "fsl,imx53-gpio", "fsl,imx35-gpio"; |
| 221 | reg = <0x53fe4000 0x4000>; | 221 | reg = <0x53fe4000 0x4000>; |
| 222 | interrupts = <107 108>; | 222 | interrupts = <107 108>; |
| 223 | gpio-controller; | 223 | gpio-controller; |
diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi index c25d49584814..3d3c64b014e6 100644 --- a/arch/arm/boot/dts/imx6q.dtsi +++ b/arch/arm/boot/dts/imx6q.dtsi | |||
| @@ -277,7 +277,7 @@ | |||
| 277 | }; | 277 | }; |
| 278 | 278 | ||
| 279 | gpio1: gpio@0209c000 { | 279 | gpio1: gpio@0209c000 { |
| 280 | compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio"; | 280 | compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio"; |
| 281 | reg = <0x0209c000 0x4000>; | 281 | reg = <0x0209c000 0x4000>; |
| 282 | interrupts = <0 66 0x04 0 67 0x04>; | 282 | interrupts = <0 66 0x04 0 67 0x04>; |
| 283 | gpio-controller; | 283 | gpio-controller; |
| @@ -287,7 +287,7 @@ | |||
| 287 | }; | 287 | }; |
| 288 | 288 | ||
| 289 | gpio2: gpio@020a0000 { | 289 | gpio2: gpio@020a0000 { |
| 290 | compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio"; | 290 | compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio"; |
| 291 | reg = <0x020a0000 0x4000>; | 291 | reg = <0x020a0000 0x4000>; |
| 292 | interrupts = <0 68 0x04 0 69 0x04>; | 292 | interrupts = <0 68 0x04 0 69 0x04>; |
| 293 | gpio-controller; | 293 | gpio-controller; |
| @@ -297,7 +297,7 @@ | |||
| 297 | }; | 297 | }; |
| 298 | 298 | ||
| 299 | gpio3: gpio@020a4000 { | 299 | gpio3: gpio@020a4000 { |
| 300 | compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio"; | 300 | compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio"; |
| 301 | reg = <0x020a4000 0x4000>; | 301 | reg = <0x020a4000 0x4000>; |
| 302 | interrupts = <0 70 0x04 0 71 0x04>; | 302 | interrupts = <0 70 0x04 0 71 0x04>; |
| 303 | gpio-controller; | 303 | gpio-controller; |
| @@ -307,7 +307,7 @@ | |||
| 307 | }; | 307 | }; |
| 308 | 308 | ||
| 309 | gpio4: gpio@020a8000 { | 309 | gpio4: gpio@020a8000 { |
| 310 | compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio"; | 310 | compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio"; |
| 311 | reg = <0x020a8000 0x4000>; | 311 | reg = <0x020a8000 0x4000>; |
| 312 | interrupts = <0 72 0x04 0 73 0x04>; | 312 | interrupts = <0 72 0x04 0 73 0x04>; |
| 313 | gpio-controller; | 313 | gpio-controller; |
| @@ -317,7 +317,7 @@ | |||
| 317 | }; | 317 | }; |
| 318 | 318 | ||
| 319 | gpio5: gpio@020ac000 { | 319 | gpio5: gpio@020ac000 { |
| 320 | compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio"; | 320 | compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio"; |
| 321 | reg = <0x020ac000 0x4000>; | 321 | reg = <0x020ac000 0x4000>; |
| 322 | interrupts = <0 74 0x04 0 75 0x04>; | 322 | interrupts = <0 74 0x04 0 75 0x04>; |
| 323 | gpio-controller; | 323 | gpio-controller; |
| @@ -327,7 +327,7 @@ | |||
| 327 | }; | 327 | }; |
| 328 | 328 | ||
| 329 | gpio6: gpio@020b0000 { | 329 | gpio6: gpio@020b0000 { |
| 330 | compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio"; | 330 | compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio"; |
| 331 | reg = <0x020b0000 0x4000>; | 331 | reg = <0x020b0000 0x4000>; |
| 332 | interrupts = <0 76 0x04 0 77 0x04>; | 332 | interrupts = <0 76 0x04 0 77 0x04>; |
| 333 | gpio-controller; | 333 | gpio-controller; |
| @@ -337,7 +337,7 @@ | |||
| 337 | }; | 337 | }; |
| 338 | 338 | ||
| 339 | gpio7: gpio@020b4000 { | 339 | gpio7: gpio@020b4000 { |
| 340 | compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio"; | 340 | compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio"; |
| 341 | reg = <0x020b4000 0x4000>; | 341 | reg = <0x020b4000 0x4000>; |
| 342 | interrupts = <0 78 0x04 0 79 0x04>; | 342 | interrupts = <0 78 0x04 0 79 0x04>; |
| 343 | gpio-controller; | 343 | gpio-controller; |
diff --git a/arch/arm/boot/dts/kirkwood-dns320.dts b/arch/arm/boot/dts/kirkwood-dns320.dts index dc09a735b04a..9a33077130e8 100644 --- a/arch/arm/boot/dts/kirkwood-dns320.dts +++ b/arch/arm/boot/dts/kirkwood-dns320.dts | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | / { | 5 | / { |
| 6 | model = "D-Link DNS-320 NAS (Rev A1)"; | 6 | model = "D-Link DNS-320 NAS (Rev A1)"; |
| 7 | compatible = "dlink,dns-320-a1", "dlink,dns-320", "dlink,dns-kirkwood", "mrvl,kirkwood-88f6281", "mrvl,kirkwood"; | 7 | compatible = "dlink,dns-320-a1", "dlink,dns-320", "dlink,dns-kirkwood", "marvell,kirkwood-88f6281", "marvell,kirkwood"; |
| 8 | 8 | ||
| 9 | memory { | 9 | memory { |
| 10 | device_type = "memory"; | 10 | device_type = "memory"; |
diff --git a/arch/arm/boot/dts/kirkwood-dns325.dts b/arch/arm/boot/dts/kirkwood-dns325.dts index c2a5562525d2..16734c1b5dfe 100644 --- a/arch/arm/boot/dts/kirkwood-dns325.dts +++ b/arch/arm/boot/dts/kirkwood-dns325.dts | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | / { | 5 | / { |
| 6 | model = "D-Link DNS-325 NAS (Rev A1)"; | 6 | model = "D-Link DNS-325 NAS (Rev A1)"; |
| 7 | compatible = "dlink,dns-325-a1", "dlink,dns-325", "dlink,dns-kirkwood", "mrvl,kirkwood-88f6281", "mrvl,kirkwood"; | 7 | compatible = "dlink,dns-325-a1", "dlink,dns-325", "dlink,dns-kirkwood", "marvell,kirkwood-88f6281", "marvell,kirkwood"; |
| 8 | 8 | ||
| 9 | memory { | 9 | memory { |
| 10 | device_type = "memory"; | 10 | device_type = "memory"; |
diff --git a/arch/arm/boot/dts/kirkwood-dreamplug.dts b/arch/arm/boot/dts/kirkwood-dreamplug.dts index a5376b84227f..78b0f06a09a2 100644 --- a/arch/arm/boot/dts/kirkwood-dreamplug.dts +++ b/arch/arm/boot/dts/kirkwood-dreamplug.dts | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | / { | 5 | / { |
| 6 | model = "Globalscale Technologies Dreamplug"; | 6 | model = "Globalscale Technologies Dreamplug"; |
| 7 | compatible = "globalscale,dreamplug-003-ds2001", "globalscale,dreamplug", "mrvl,kirkwood-88f6281", "mrvl,kirkwood"; | 7 | compatible = "globalscale,dreamplug-003-ds2001", "globalscale,dreamplug", "marvell,kirkwood-88f6281", "marvell,kirkwood"; |
| 8 | 8 | ||
| 9 | memory { | 9 | memory { |
| 10 | device_type = "memory"; | 10 | device_type = "memory"; |
diff --git a/arch/arm/boot/dts/kirkwood-ib62x0.dts b/arch/arm/boot/dts/kirkwood-ib62x0.dts index ada0f0c23085..f59dcf6dc45f 100644 --- a/arch/arm/boot/dts/kirkwood-ib62x0.dts +++ b/arch/arm/boot/dts/kirkwood-ib62x0.dts | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | / { | 5 | / { |
| 6 | model = "RaidSonic ICY BOX IB-NAS62x0 (Rev B)"; | 6 | model = "RaidSonic ICY BOX IB-NAS62x0 (Rev B)"; |
| 7 | compatible = "raidsonic,ib-nas6210-b", "raidsonic,ib-nas6220-b", "raidsonic,ib-nas6210", "raidsonic,ib-nas6220", "raidsonic,ib-nas62x0", "mrvl,kirkwood-88f6281", "mrvl,kirkwood"; | 7 | compatible = "raidsonic,ib-nas6210-b", "raidsonic,ib-nas6220-b", "raidsonic,ib-nas6210", "raidsonic,ib-nas6220", "raidsonic,ib-nas62x0", "marvell,kirkwood-88f6281", "marvell,kirkwood"; |
| 8 | 8 | ||
| 9 | memory { | 9 | memory { |
| 10 | device_type = "memory"; | 10 | device_type = "memory"; |
diff --git a/arch/arm/boot/dts/kirkwood-iconnect.dts b/arch/arm/boot/dts/kirkwood-iconnect.dts index 1ba75d4adecc..026a1f82d813 100644 --- a/arch/arm/boot/dts/kirkwood-iconnect.dts +++ b/arch/arm/boot/dts/kirkwood-iconnect.dts | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | / { | 5 | / { |
| 6 | model = "Iomega Iconnect"; | 6 | model = "Iomega Iconnect"; |
| 7 | compatible = "iom,iconnect-1.1", "iom,iconnect", "mrvl,kirkwood-88f6281", "mrvl,kirkwood"; | 7 | compatible = "iom,iconnect-1.1", "iom,iconnect", "marvell,kirkwood-88f6281", "marvell,kirkwood"; |
| 8 | 8 | ||
| 9 | memory { | 9 | memory { |
| 10 | device_type = "memory"; | 10 | device_type = "memory"; |
diff --git a/arch/arm/boot/dts/kirkwood.dtsi b/arch/arm/boot/dts/kirkwood.dtsi index 926528b81baa..f95dbc190ab6 100644 --- a/arch/arm/boot/dts/kirkwood.dtsi +++ b/arch/arm/boot/dts/kirkwood.dtsi | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /include/ "skeleton.dtsi" | 1 | /include/ "skeleton.dtsi" |
| 2 | 2 | ||
| 3 | / { | 3 | / { |
| 4 | compatible = "mrvl,kirkwood"; | 4 | compatible = "marvell,kirkwood"; |
| 5 | 5 | ||
| 6 | ocp@f1000000 { | 6 | ocp@f1000000 { |
| 7 | compatible = "simple-bus"; | 7 | compatible = "simple-bus"; |
| @@ -28,7 +28,7 @@ | |||
| 28 | }; | 28 | }; |
| 29 | 29 | ||
| 30 | rtc@10300 { | 30 | rtc@10300 { |
| 31 | compatible = "mrvl,kirkwood-rtc", "mrvl,orion-rtc"; | 31 | compatible = "marvell,kirkwood-rtc", "marvell,orion-rtc"; |
| 32 | reg = <0x10300 0x20>; | 32 | reg = <0x10300 0x20>; |
| 33 | interrupts = <53>; | 33 | interrupts = <53>; |
| 34 | }; | 34 | }; |
| @@ -39,7 +39,7 @@ | |||
| 39 | cle = <0>; | 39 | cle = <0>; |
| 40 | ale = <1>; | 40 | ale = <1>; |
| 41 | bank-width = <1>; | 41 | bank-width = <1>; |
| 42 | compatible = "mrvl,orion-nand"; | 42 | compatible = "marvell,orion-nand"; |
| 43 | reg = <0x3000000 0x400>; | 43 | reg = <0x3000000 0x400>; |
| 44 | chip-delay = <25>; | 44 | chip-delay = <25>; |
| 45 | /* set partition map and/or chip-delay in board dts */ | 45 | /* set partition map and/or chip-delay in board dts */ |
diff --git a/arch/arm/boot/dts/r8a7740.dtsi b/arch/arm/boot/dts/r8a7740.dtsi new file mode 100644 index 000000000000..798fa35c0005 --- /dev/null +++ b/arch/arm/boot/dts/r8a7740.dtsi | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | /* | ||
| 2 | * Device Tree Source for the r8a7740 SoC | ||
| 3 | * | ||
| 4 | * Copyright (C) 2012 Renesas Solutions Corp. | ||
| 5 | * | ||
| 6 | * This file is licensed under the terms of the GNU General Public License | ||
| 7 | * version 2. This program is licensed "as is" without any warranty of any | ||
| 8 | * kind, whether express or implied. | ||
| 9 | */ | ||
| 10 | |||
| 11 | /include/ "skeleton.dtsi" | ||
| 12 | |||
| 13 | / { | ||
| 14 | compatible = "renesas,r8a7740"; | ||
| 15 | |||
| 16 | cpus { | ||
| 17 | cpu@0 { | ||
| 18 | compatible = "arm,cortex-a9"; | ||
| 19 | }; | ||
| 20 | }; | ||
| 21 | }; | ||
diff --git a/arch/arm/boot/dts/sh7377.dtsi b/arch/arm/boot/dts/sh7377.dtsi new file mode 100644 index 000000000000..767ee0796daa --- /dev/null +++ b/arch/arm/boot/dts/sh7377.dtsi | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | /* | ||
| 2 | * Device Tree Source for the sh7377 SoC | ||
| 3 | * | ||
| 4 | * Copyright (C) 2012 Renesas Solutions Corp. | ||
| 5 | * | ||
| 6 | * This file is licensed under the terms of the GNU General Public License | ||
| 7 | * version 2. This program is licensed "as is" without any warranty of any | ||
| 8 | * kind, whether express or implied. | ||
| 9 | */ | ||
| 10 | |||
| 11 | /include/ "skeleton.dtsi" | ||
| 12 | |||
| 13 | / { | ||
| 14 | compatible = "renesas,sh7377"; | ||
| 15 | |||
| 16 | cpus { | ||
| 17 | cpu@0 { | ||
| 18 | compatible = "arm,cortex-a8"; | ||
| 19 | }; | ||
| 20 | }; | ||
| 21 | }; | ||
diff --git a/arch/arm/boot/dts/tegra20-trimslice.dts b/arch/arm/boot/dts/tegra20-trimslice.dts index 9de5636023f6..27fb8a67ea42 100644 --- a/arch/arm/boot/dts/tegra20-trimslice.dts +++ b/arch/arm/boot/dts/tegra20-trimslice.dts | |||
| @@ -276,9 +276,11 @@ | |||
| 276 | 276 | ||
| 277 | usb@c5000000 { | 277 | usb@c5000000 { |
| 278 | status = "okay"; | 278 | status = "okay"; |
| 279 | nvidia,vbus-gpio = <&gpio 170 0>; /* gpio PV2 */ | ||
| 279 | }; | 280 | }; |
| 280 | 281 | ||
| 281 | usb@c5004000 { | 282 | usb@c5004000 { |
| 283 | status = "okay"; | ||
| 282 | nvidia,phy-reset-gpio = <&gpio 168 0>; /* gpio PV0 */ | 284 | nvidia,phy-reset-gpio = <&gpio 168 0>; /* gpio PV0 */ |
| 283 | }; | 285 | }; |
| 284 | 286 | ||
diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi index 9f1921634eb7..405d1673904e 100644 --- a/arch/arm/boot/dts/tegra20.dtsi +++ b/arch/arm/boot/dts/tegra20.dtsi | |||
| @@ -123,6 +123,12 @@ | |||
| 123 | status = "disabled"; | 123 | status = "disabled"; |
| 124 | }; | 124 | }; |
| 125 | 125 | ||
| 126 | pwm { | ||
| 127 | compatible = "nvidia,tegra20-pwm"; | ||
| 128 | reg = <0x7000a000 0x100>; | ||
| 129 | #pwm-cells = <2>; | ||
| 130 | }; | ||
| 131 | |||
| 126 | i2c@7000c000 { | 132 | i2c@7000c000 { |
| 127 | compatible = "nvidia,tegra20-i2c"; | 133 | compatible = "nvidia,tegra20-i2c"; |
| 128 | reg = <0x7000c000 0x100>; | 134 | reg = <0x7000c000 0x100>; |
diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi index da740191771f..3e4334d14efb 100644 --- a/arch/arm/boot/dts/tegra30.dtsi +++ b/arch/arm/boot/dts/tegra30.dtsi | |||
| @@ -117,6 +117,12 @@ | |||
| 117 | status = "disabled"; | 117 | status = "disabled"; |
| 118 | }; | 118 | }; |
| 119 | 119 | ||
| 120 | pwm { | ||
| 121 | compatible = "nvidia,tegra30-pwm", "nvidia,tegra20-pwm"; | ||
| 122 | reg = <0x7000a000 0x100>; | ||
| 123 | #pwm-cells = <2>; | ||
| 124 | }; | ||
| 125 | |||
| 120 | i2c@7000c000 { | 126 | i2c@7000c000 { |
| 121 | compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c"; | 127 | compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c"; |
| 122 | reg = <0x7000c000 0x100>; | 128 | reg = <0x7000c000 0x100>; |
diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c index aa07f5938f05..1143c4d5c567 100644 --- a/arch/arm/common/dmabounce.c +++ b/arch/arm/common/dmabounce.c | |||
| @@ -452,6 +452,7 @@ static struct dma_map_ops dmabounce_ops = { | |||
| 452 | .alloc = arm_dma_alloc, | 452 | .alloc = arm_dma_alloc, |
| 453 | .free = arm_dma_free, | 453 | .free = arm_dma_free, |
| 454 | .mmap = arm_dma_mmap, | 454 | .mmap = arm_dma_mmap, |
| 455 | .get_sgtable = arm_dma_get_sgtable, | ||
| 455 | .map_page = dmabounce_map_page, | 456 | .map_page = dmabounce_map_page, |
| 456 | .unmap_page = dmabounce_unmap_page, | 457 | .unmap_page = dmabounce_unmap_page, |
| 457 | .sync_single_for_cpu = dmabounce_sync_for_cpu, | 458 | .sync_single_for_cpu = dmabounce_sync_for_cpu, |
diff --git a/arch/arm/configs/armadillo800eva_defconfig b/arch/arm/configs/armadillo800eva_defconfig index ddc9fe6a78ac..7d8718468e0d 100644 --- a/arch/arm/configs/armadillo800eva_defconfig +++ b/arch/arm/configs/armadillo800eva_defconfig | |||
| @@ -5,10 +5,7 @@ CONFIG_IKCONFIG_PROC=y | |||
| 5 | CONFIG_LOG_BUF_SHIFT=16 | 5 | CONFIG_LOG_BUF_SHIFT=16 |
| 6 | # CONFIG_UTS_NS is not set | 6 | # CONFIG_UTS_NS is not set |
| 7 | # CONFIG_IPC_NS is not set | 7 | # CONFIG_IPC_NS is not set |
| 8 | # CONFIG_USER_NS is not set | ||
| 9 | # CONFIG_PID_NS is not set | 8 | # CONFIG_PID_NS is not set |
| 10 | CONFIG_SYSFS_DEPRECATED=y | ||
| 11 | CONFIG_SYSFS_DEPRECATED_V2=y | ||
| 12 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | 9 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y |
| 13 | CONFIG_SLAB=y | 10 | CONFIG_SLAB=y |
| 14 | CONFIG_MODULES=y | 11 | CONFIG_MODULES=y |
| @@ -21,7 +18,7 @@ CONFIG_ARCH_SHMOBILE=y | |||
| 21 | CONFIG_ARCH_R8A7740=y | 18 | CONFIG_ARCH_R8A7740=y |
| 22 | CONFIG_MACH_ARMADILLO800EVA=y | 19 | CONFIG_MACH_ARMADILLO800EVA=y |
| 23 | # CONFIG_SH_TIMER_TMU is not set | 20 | # CONFIG_SH_TIMER_TMU is not set |
| 24 | # CONFIG_ARM_THUMB is not set | 21 | CONFIG_ARM_THUMB=y |
| 25 | CONFIG_CPU_BPREDICT_DISABLE=y | 22 | CONFIG_CPU_BPREDICT_DISABLE=y |
| 26 | # CONFIG_CACHE_L2X0 is not set | 23 | # CONFIG_CACHE_L2X0 is not set |
| 27 | CONFIG_ARM_ERRATA_430973=y | 24 | CONFIG_ARM_ERRATA_430973=y |
| @@ -39,6 +36,7 @@ CONFIG_ZBOOT_ROM_BSS=0x0 | |||
| 39 | CONFIG_CMDLINE="console=tty0 console=ttySC1,115200 earlyprintk=sh-sci.1,115200 ignore_loglevel root=/dev/nfs ip=dhcp nfsroot=,rsize=4096,wsize=4096" | 36 | CONFIG_CMDLINE="console=tty0 console=ttySC1,115200 earlyprintk=sh-sci.1,115200 ignore_loglevel root=/dev/nfs ip=dhcp nfsroot=,rsize=4096,wsize=4096" |
| 40 | CONFIG_CMDLINE_FORCE=y | 37 | CONFIG_CMDLINE_FORCE=y |
| 41 | CONFIG_KEXEC=y | 38 | CONFIG_KEXEC=y |
| 39 | CONFIG_VFP=y | ||
| 42 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set | 40 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set |
| 43 | # CONFIG_SUSPEND is not set | 41 | # CONFIG_SUSPEND is not set |
| 44 | CONFIG_NET=y | 42 | CONFIG_NET=y |
| @@ -89,26 +87,32 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y | |||
| 89 | CONFIG_I2C=y | 87 | CONFIG_I2C=y |
| 90 | CONFIG_I2C_SH_MOBILE=y | 88 | CONFIG_I2C_SH_MOBILE=y |
| 91 | # CONFIG_HWMON is not set | 89 | # CONFIG_HWMON is not set |
| 90 | CONFIG_MEDIA_SUPPORT=y | ||
| 91 | CONFIG_VIDEO_DEV=y | ||
| 92 | # CONFIG_RC_CORE is not set | ||
| 93 | # CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set | ||
| 94 | # CONFIG_V4L_USB_DRIVERS is not set | ||
| 95 | CONFIG_V4L_PLATFORM_DRIVERS=y | ||
| 96 | CONFIG_SOC_CAMERA=y | ||
| 97 | CONFIG_SOC_CAMERA_MT9T112=y | ||
| 98 | CONFIG_VIDEO_SH_MOBILE_CEU=y | ||
| 99 | # CONFIG_RADIO_ADAPTERS is not set | ||
| 92 | CONFIG_FB=y | 100 | CONFIG_FB=y |
| 93 | CONFIG_FB_MODE_HELPERS=y | ||
| 94 | CONFIG_FB_SH_MOBILE_LCDC=y | 101 | CONFIG_FB_SH_MOBILE_LCDC=y |
| 102 | CONFIG_FB_SH_MOBILE_HDMI=y | ||
| 95 | CONFIG_LCD_CLASS_DEVICE=y | 103 | CONFIG_LCD_CLASS_DEVICE=y |
| 96 | CONFIG_FRAMEBUFFER_CONSOLE=y | 104 | CONFIG_FRAMEBUFFER_CONSOLE=y |
| 97 | CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y | 105 | CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y |
| 98 | CONFIG_LOGO=y | 106 | CONFIG_LOGO=y |
| 99 | # CONFIG_LOGO_LINUX_MONO is not set | 107 | # CONFIG_LOGO_LINUX_MONO is not set |
| 100 | # CONFIG_LOGO_LINUX_VGA16 is not set | 108 | # CONFIG_LOGO_LINUX_VGA16 is not set |
| 101 | CONFIG_SOUND=y | ||
| 102 | CONFIG_SND=y | ||
| 103 | # CONFIG_SND_SUPPORT_OLD_API is not set | 109 | # CONFIG_SND_SUPPORT_OLD_API is not set |
| 104 | # CONFIG_SND_VERBOSE_PROCFS is not set | 110 | # CONFIG_SND_VERBOSE_PROCFS is not set |
| 105 | # CONFIG_SND_DRIVERS is not set | 111 | # CONFIG_SND_DRIVERS is not set |
| 106 | # CONFIG_SND_ARM is not set | 112 | # CONFIG_SND_ARM is not set |
| 107 | CONFIG_SND_SOC=y | ||
| 108 | CONFIG_SND_SOC_SH4_FSI=y | 113 | CONFIG_SND_SOC_SH4_FSI=y |
| 109 | # CONFIG_HID_SUPPORT is not set | 114 | # CONFIG_HID_SUPPORT is not set |
| 110 | CONFIG_USB=y | 115 | CONFIG_USB=y |
| 111 | # CONFIG_USB_DEVICE_CLASS is not set | ||
| 112 | CONFIG_USB_RENESAS_USBHS=y | 116 | CONFIG_USB_RENESAS_USBHS=y |
| 113 | CONFIG_USB_GADGET=y | 117 | CONFIG_USB_GADGET=y |
| 114 | CONFIG_USB_RENESAS_USBHS_UDC=y | 118 | CONFIG_USB_RENESAS_USBHS_UDC=y |
| @@ -116,6 +120,8 @@ CONFIG_USB_ETH=m | |||
| 116 | CONFIG_MMC=y | 120 | CONFIG_MMC=y |
| 117 | CONFIG_MMC_SDHI=y | 121 | CONFIG_MMC_SDHI=y |
| 118 | CONFIG_MMC_SH_MMCIF=y | 122 | CONFIG_MMC_SH_MMCIF=y |
| 123 | CONFIG_DMADEVICES=y | ||
| 124 | CONFIG_SH_DMAE=y | ||
| 119 | CONFIG_UIO=y | 125 | CONFIG_UIO=y |
| 120 | CONFIG_UIO_PDRV_GENIRQ=y | 126 | CONFIG_UIO_PDRV_GENIRQ=y |
| 121 | # CONFIG_DNOTIFY is not set | 127 | # CONFIG_DNOTIFY is not set |
| @@ -124,7 +130,6 @@ CONFIG_VFAT_FS=y | |||
| 124 | CONFIG_TMPFS=y | 130 | CONFIG_TMPFS=y |
| 125 | # CONFIG_MISC_FILESYSTEMS is not set | 131 | # CONFIG_MISC_FILESYSTEMS is not set |
| 126 | CONFIG_NFS_FS=y | 132 | CONFIG_NFS_FS=y |
| 127 | CONFIG_NFS_V3=y | ||
| 128 | CONFIG_NFS_V3_ACL=y | 133 | CONFIG_NFS_V3_ACL=y |
| 129 | CONFIG_NFS_V4=y | 134 | CONFIG_NFS_V4=y |
| 130 | CONFIG_NFS_V4_1=y | 135 | CONFIG_NFS_V4_1=y |
diff --git a/arch/arm/configs/kzm9d_defconfig b/arch/arm/configs/kzm9d_defconfig new file mode 100644 index 000000000000..26146ffea1a5 --- /dev/null +++ b/arch/arm/configs/kzm9d_defconfig | |||
| @@ -0,0 +1,89 @@ | |||
| 1 | # CONFIG_ARM_PATCH_PHYS_VIRT is not set | ||
| 2 | CONFIG_EXPERIMENTAL=y | ||
| 3 | CONFIG_SYSVIPC=y | ||
| 4 | CONFIG_NO_HZ=y | ||
| 5 | CONFIG_IKCONFIG=y | ||
| 6 | CONFIG_IKCONFIG_PROC=y | ||
| 7 | CONFIG_LOG_BUF_SHIFT=16 | ||
| 8 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | ||
| 9 | CONFIG_SYSCTL_SYSCALL=y | ||
| 10 | CONFIG_EMBEDDED=y | ||
| 11 | CONFIG_SLAB=y | ||
| 12 | # CONFIG_BLK_DEV_BSG is not set | ||
| 13 | # CONFIG_IOSCHED_DEADLINE is not set | ||
| 14 | # CONFIG_IOSCHED_CFQ is not set | ||
| 15 | CONFIG_ARCH_SHMOBILE=y | ||
| 16 | CONFIG_ARCH_EMEV2=y | ||
| 17 | CONFIG_MACH_KZM9D=y | ||
| 18 | CONFIG_MEMORY_START=0x40000000 | ||
| 19 | CONFIG_MEMORY_SIZE=0x10000000 | ||
| 20 | # CONFIG_SH_TIMER_TMU is not set | ||
| 21 | # CONFIG_SWP_EMULATE is not set | ||
| 22 | # CONFIG_CACHE_L2X0 is not set | ||
| 23 | CONFIG_SMP=y | ||
| 24 | CONFIG_NR_CPUS=2 | ||
| 25 | CONFIG_HOTPLUG_CPU=y | ||
| 26 | # CONFIG_LOCAL_TIMERS is not set | ||
| 27 | CONFIG_AEABI=y | ||
| 28 | # CONFIG_OABI_COMPAT is not set | ||
| 29 | # CONFIG_CROSS_MEMORY_ATTACH is not set | ||
| 30 | CONFIG_FORCE_MAX_ZONEORDER=13 | ||
| 31 | CONFIG_ZBOOT_ROM_TEXT=0x0 | ||
| 32 | CONFIG_ZBOOT_ROM_BSS=0x0 | ||
| 33 | CONFIG_ARM_APPENDED_DTB=y | ||
| 34 | CONFIG_CMDLINE="console=tty0 console=ttyS1,115200n81 earlyprintk=serial8250-em.1,115200n81 mem=128M@0x40000000 ignore_loglevel root=/dev/nfs ip=dhcp nfsroot=,rsize=4096,wsize=4096" | ||
| 35 | CONFIG_CMDLINE_FORCE=y | ||
| 36 | CONFIG_VFP=y | ||
| 37 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set | ||
| 38 | # CONFIG_SUSPEND is not set | ||
| 39 | CONFIG_NET=y | ||
| 40 | CONFIG_PACKET=y | ||
| 41 | CONFIG_UNIX=y | ||
| 42 | CONFIG_INET=y | ||
| 43 | CONFIG_IP_PNP=y | ||
| 44 | CONFIG_IP_PNP_DHCP=y | ||
| 45 | # CONFIG_INET_XFRM_MODE_TRANSPORT is not set | ||
| 46 | # CONFIG_INET_XFRM_MODE_TUNNEL is not set | ||
| 47 | # CONFIG_INET_XFRM_MODE_BEET is not set | ||
| 48 | # CONFIG_INET_LRO is not set | ||
| 49 | # CONFIG_INET_DIAG is not set | ||
| 50 | # CONFIG_IPV6 is not set | ||
| 51 | # CONFIG_WIRELESS is not set | ||
| 52 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||
| 53 | # CONFIG_BLK_DEV is not set | ||
| 54 | CONFIG_NETDEVICES=y | ||
| 55 | # CONFIG_NET_VENDOR_BROADCOM is not set | ||
| 56 | # CONFIG_NET_VENDOR_CHELSIO is not set | ||
| 57 | # CONFIG_NET_VENDOR_CIRRUS is not set | ||
| 58 | # CONFIG_NET_VENDOR_FARADAY is not set | ||
| 59 | # CONFIG_NET_VENDOR_INTEL is not set | ||
| 60 | # CONFIG_NET_VENDOR_MARVELL is not set | ||
| 61 | # CONFIG_NET_VENDOR_MICREL is not set | ||
| 62 | # CONFIG_NET_VENDOR_NATSEMI is not set | ||
| 63 | # CONFIG_NET_VENDOR_SEEQ is not set | ||
| 64 | CONFIG_SMSC911X=y | ||
| 65 | # CONFIG_NET_VENDOR_STMICRO is not set | ||
| 66 | # CONFIG_NET_VENDOR_WIZNET is not set | ||
| 67 | # CONFIG_WLAN is not set | ||
| 68 | # CONFIG_INPUT_MOUSEDEV is not set | ||
| 69 | # CONFIG_INPUT_KEYBOARD is not set | ||
| 70 | # CONFIG_INPUT_MOUSE is not set | ||
| 71 | # CONFIG_SERIO is not set | ||
| 72 | # CONFIG_LEGACY_PTYS is not set | ||
| 73 | # CONFIG_DEVKMEM is not set | ||
| 74 | CONFIG_SERIAL_8250=y | ||
| 75 | CONFIG_SERIAL_8250_CONSOLE=y | ||
| 76 | CONFIG_SERIAL_8250_EM=y | ||
| 77 | # CONFIG_HW_RANDOM is not set | ||
| 78 | CONFIG_GPIOLIB=y | ||
| 79 | CONFIG_GPIO_EM=y | ||
| 80 | # CONFIG_HWMON is not set | ||
| 81 | # CONFIG_HID_SUPPORT is not set | ||
| 82 | # CONFIG_USB_SUPPORT is not set | ||
| 83 | # CONFIG_IOMMU_SUPPORT is not set | ||
| 84 | # CONFIG_DNOTIFY is not set | ||
| 85 | CONFIG_TMPFS=y | ||
| 86 | # CONFIG_MISC_FILESYSTEMS is not set | ||
| 87 | CONFIG_NFS_FS=y | ||
| 88 | CONFIG_ROOT_NFS=y | ||
| 89 | # CONFIG_FTRACE is not set | ||
diff --git a/arch/arm/configs/kzm9g_defconfig b/arch/arm/configs/kzm9g_defconfig index e3ebc20ed0a7..2388c8610627 100644 --- a/arch/arm/configs/kzm9g_defconfig +++ b/arch/arm/configs/kzm9g_defconfig | |||
| @@ -100,7 +100,12 @@ CONFIG_SND_SOC_SH4_FSI=y | |||
| 100 | CONFIG_USB=y | 100 | CONFIG_USB=y |
| 101 | CONFIG_USB_DEVICEFS=y | 101 | CONFIG_USB_DEVICEFS=y |
| 102 | CONFIG_USB_R8A66597_HCD=y | 102 | CONFIG_USB_R8A66597_HCD=y |
| 103 | CONFIG_USB_RENESAS_USBHS=y | ||
| 103 | CONFIG_USB_STORAGE=y | 104 | CONFIG_USB_STORAGE=y |
| 105 | CONFIG_USB_GADGET=y | ||
| 106 | CONFIG_USB_RENESAS_USBHS_UDC=y | ||
| 107 | CONFIG_USB_ETH=m | ||
| 108 | CONFIG_USB_MASS_STORAGE=m | ||
| 104 | CONFIG_MMC=y | 109 | CONFIG_MMC=y |
| 105 | # CONFIG_MMC_BLOCK_BOUNCE is not set | 110 | # CONFIG_MMC_BLOCK_BOUNCE is not set |
| 106 | CONFIG_MMC_SDHI=y | 111 | CONFIG_MMC_SDHI=y |
| @@ -108,12 +113,13 @@ CONFIG_MMC_SH_MMCIF=y | |||
| 108 | CONFIG_NEW_LEDS=y | 113 | CONFIG_NEW_LEDS=y |
| 109 | CONFIG_LEDS_CLASS=y | 114 | CONFIG_LEDS_CLASS=y |
| 110 | CONFIG_RTC_CLASS=y | 115 | CONFIG_RTC_CLASS=y |
| 116 | CONFIG_RTC_DRV_RS5C372=y | ||
| 111 | CONFIG_DMADEVICES=y | 117 | CONFIG_DMADEVICES=y |
| 112 | CONFIG_SH_DMAE=y | 118 | CONFIG_SH_DMAE=y |
| 113 | CONFIG_ASYNC_TX_DMA=y | 119 | CONFIG_ASYNC_TX_DMA=y |
| 114 | CONFIG_STAGING=y | 120 | CONFIG_STAGING=y |
| 115 | # CONFIG_DNOTIFY is not set | 121 | # CONFIG_DNOTIFY is not set |
| 116 | # CONFIG_INOTIFY_USER is not set | 122 | CONFIG_INOTIFY_USER=y |
| 117 | CONFIG_VFAT_FS=y | 123 | CONFIG_VFAT_FS=y |
| 118 | CONFIG_TMPFS=y | 124 | CONFIG_TMPFS=y |
| 119 | # CONFIG_MISC_FILESYSTEMS is not set | 125 | # CONFIG_MISC_FILESYSTEMS is not set |
diff --git a/arch/arm/configs/tegra_defconfig b/arch/arm/configs/tegra_defconfig index 4be9c1e80ee6..db2245353f0f 100644 --- a/arch/arm/configs/tegra_defconfig +++ b/arch/arm/configs/tegra_defconfig | |||
| @@ -106,6 +106,7 @@ CONFIG_I2C_TEGRA=y | |||
| 106 | CONFIG_SPI=y | 106 | CONFIG_SPI=y |
| 107 | CONFIG_SPI_TEGRA=y | 107 | CONFIG_SPI_TEGRA=y |
| 108 | CONFIG_GPIO_TPS65910=y | 108 | CONFIG_GPIO_TPS65910=y |
| 109 | CONFIG_GPIO_TPS6586X=y | ||
| 109 | CONFIG_POWER_SUPPLY=y | 110 | CONFIG_POWER_SUPPLY=y |
| 110 | CONFIG_BATTERY_SBS=y | 111 | CONFIG_BATTERY_SBS=y |
| 111 | CONFIG_SENSORS_LM90=y | 112 | CONFIG_SENSORS_LM90=y |
diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h index ed2e95d46e29..62e75475e57e 100644 --- a/arch/arm/include/asm/arch_timer.h +++ b/arch/arm/include/asm/arch_timer.h | |||
| @@ -1,7 +1,10 @@ | |||
| 1 | #ifndef __ASMARM_ARCH_TIMER_H | 1 | #ifndef __ASMARM_ARCH_TIMER_H |
| 2 | #define __ASMARM_ARCH_TIMER_H | 2 | #define __ASMARM_ARCH_TIMER_H |
| 3 | 3 | ||
| 4 | #include <asm/errno.h> | ||
| 5 | |||
| 4 | #ifdef CONFIG_ARM_ARCH_TIMER | 6 | #ifdef CONFIG_ARM_ARCH_TIMER |
| 7 | #define ARCH_HAS_READ_CURRENT_TIMER | ||
| 5 | int arch_timer_of_register(void); | 8 | int arch_timer_of_register(void); |
| 6 | int arch_timer_sched_clock_init(void); | 9 | int arch_timer_sched_clock_init(void); |
| 7 | #else | 10 | #else |
diff --git a/arch/arm/include/asm/delay.h b/arch/arm/include/asm/delay.h index b2deda181549..dc6145120de3 100644 --- a/arch/arm/include/asm/delay.h +++ b/arch/arm/include/asm/delay.h | |||
| @@ -6,9 +6,22 @@ | |||
| 6 | #ifndef __ASM_ARM_DELAY_H | 6 | #ifndef __ASM_ARM_DELAY_H |
| 7 | #define __ASM_ARM_DELAY_H | 7 | #define __ASM_ARM_DELAY_H |
| 8 | 8 | ||
| 9 | #include <asm/memory.h> | ||
| 9 | #include <asm/param.h> /* HZ */ | 10 | #include <asm/param.h> /* HZ */ |
| 10 | 11 | ||
| 11 | extern void __delay(int loops); | 12 | #define MAX_UDELAY_MS 2 |
| 13 | #define UDELAY_MULT ((UL(2199023) * HZ) >> 11) | ||
| 14 | #define UDELAY_SHIFT 30 | ||
| 15 | |||
| 16 | #ifndef __ASSEMBLY__ | ||
| 17 | |||
| 18 | extern struct arm_delay_ops { | ||
| 19 | void (*delay)(unsigned long); | ||
| 20 | void (*const_udelay)(unsigned long); | ||
| 21 | void (*udelay)(unsigned long); | ||
| 22 | } arm_delay_ops; | ||
| 23 | |||
| 24 | #define __delay(n) arm_delay_ops.delay(n) | ||
| 12 | 25 | ||
| 13 | /* | 26 | /* |
| 14 | * This function intentionally does not exist; if you see references to | 27 | * This function intentionally does not exist; if you see references to |
| @@ -23,22 +36,27 @@ extern void __bad_udelay(void); | |||
| 23 | * division by multiplication: you don't have to worry about | 36 | * division by multiplication: you don't have to worry about |
| 24 | * loss of precision. | 37 | * loss of precision. |
| 25 | * | 38 | * |
| 26 | * Use only for very small delays ( < 1 msec). Should probably use a | 39 | * Use only for very small delays ( < 2 msec). Should probably use a |
| 27 | * lookup table, really, as the multiplications take much too long with | 40 | * lookup table, really, as the multiplications take much too long with |
| 28 | * short delays. This is a "reasonable" implementation, though (and the | 41 | * short delays. This is a "reasonable" implementation, though (and the |
| 29 | * first constant multiplications gets optimized away if the delay is | 42 | * first constant multiplications gets optimized away if the delay is |
| 30 | * a constant) | 43 | * a constant) |
| 31 | */ | 44 | */ |
| 32 | extern void __udelay(unsigned long usecs); | 45 | #define __udelay(n) arm_delay_ops.udelay(n) |
| 33 | extern void __const_udelay(unsigned long); | 46 | #define __const_udelay(n) arm_delay_ops.const_udelay(n) |
| 34 | |||
| 35 | #define MAX_UDELAY_MS 2 | ||
| 36 | 47 | ||
| 37 | #define udelay(n) \ | 48 | #define udelay(n) \ |
| 38 | (__builtin_constant_p(n) ? \ | 49 | (__builtin_constant_p(n) ? \ |
| 39 | ((n) > (MAX_UDELAY_MS * 1000) ? __bad_udelay() : \ | 50 | ((n) > (MAX_UDELAY_MS * 1000) ? __bad_udelay() : \ |
| 40 | __const_udelay((n) * ((2199023U*HZ)>>11))) : \ | 51 | __const_udelay((n) * UDELAY_MULT)) : \ |
| 41 | __udelay(n)) | 52 | __udelay(n)) |
| 42 | 53 | ||
| 54 | /* Loop-based definitions for assembly code. */ | ||
| 55 | extern void __loop_delay(unsigned long loops); | ||
| 56 | extern void __loop_udelay(unsigned long usecs); | ||
| 57 | extern void __loop_const_udelay(unsigned long); | ||
| 58 | |||
| 59 | #endif /* __ASSEMBLY__ */ | ||
| 60 | |||
| 43 | #endif /* defined(_ARM_DELAY_H) */ | 61 | #endif /* defined(_ARM_DELAY_H) */ |
| 44 | 62 | ||
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h index bbef15d04890..2ae842df4551 100644 --- a/arch/arm/include/asm/dma-mapping.h +++ b/arch/arm/include/asm/dma-mapping.h | |||
| @@ -186,17 +186,6 @@ extern int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma, | |||
| 186 | void *cpu_addr, dma_addr_t dma_addr, size_t size, | 186 | void *cpu_addr, dma_addr_t dma_addr, size_t size, |
| 187 | struct dma_attrs *attrs); | 187 | struct dma_attrs *attrs); |
| 188 | 188 | ||
| 189 | #define dma_mmap_coherent(d, v, c, h, s) dma_mmap_attrs(d, v, c, h, s, NULL) | ||
| 190 | |||
| 191 | static inline int dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma, | ||
| 192 | void *cpu_addr, dma_addr_t dma_addr, | ||
| 193 | size_t size, struct dma_attrs *attrs) | ||
| 194 | { | ||
| 195 | struct dma_map_ops *ops = get_dma_ops(dev); | ||
| 196 | BUG_ON(!ops); | ||
| 197 | return ops->mmap(dev, vma, cpu_addr, dma_addr, size, attrs); | ||
| 198 | } | ||
| 199 | |||
| 200 | static inline void *dma_alloc_writecombine(struct device *dev, size_t size, | 189 | static inline void *dma_alloc_writecombine(struct device *dev, size_t size, |
| 201 | dma_addr_t *dma_handle, gfp_t flag) | 190 | dma_addr_t *dma_handle, gfp_t flag) |
| 202 | { | 191 | { |
| @@ -213,20 +202,12 @@ static inline void dma_free_writecombine(struct device *dev, size_t size, | |||
| 213 | return dma_free_attrs(dev, size, cpu_addr, dma_handle, &attrs); | 202 | return dma_free_attrs(dev, size, cpu_addr, dma_handle, &attrs); |
| 214 | } | 203 | } |
| 215 | 204 | ||
| 216 | static inline int dma_mmap_writecombine(struct device *dev, struct vm_area_struct *vma, | ||
| 217 | void *cpu_addr, dma_addr_t dma_addr, size_t size) | ||
| 218 | { | ||
| 219 | DEFINE_DMA_ATTRS(attrs); | ||
| 220 | dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs); | ||
| 221 | return dma_mmap_attrs(dev, vma, cpu_addr, dma_addr, size, &attrs); | ||
| 222 | } | ||
| 223 | |||
| 224 | /* | 205 | /* |
| 225 | * This can be called during boot to increase the size of the consistent | 206 | * This can be called during boot to increase the size of the consistent |
| 226 | * DMA region above it's default value of 2MB. It must be called before the | 207 | * DMA region above it's default value of 2MB. It must be called before the |
| 227 | * memory allocator is initialised, i.e. before any core_initcall. | 208 | * memory allocator is initialised, i.e. before any core_initcall. |
| 228 | */ | 209 | */ |
| 229 | extern void __init init_consistent_dma_size(unsigned long size); | 210 | static inline void init_consistent_dma_size(unsigned long size) { } |
| 230 | 211 | ||
| 231 | /* | 212 | /* |
| 232 | * For SA-1111, IXP425, and ADI systems the dma-mapping functions are "magic" | 213 | * For SA-1111, IXP425, and ADI systems the dma-mapping functions are "magic" |
| @@ -280,6 +261,9 @@ extern void arm_dma_sync_sg_for_cpu(struct device *, struct scatterlist *, int, | |||
| 280 | enum dma_data_direction); | 261 | enum dma_data_direction); |
| 281 | extern void arm_dma_sync_sg_for_device(struct device *, struct scatterlist *, int, | 262 | extern void arm_dma_sync_sg_for_device(struct device *, struct scatterlist *, int, |
| 282 | enum dma_data_direction); | 263 | enum dma_data_direction); |
| 264 | extern int arm_dma_get_sgtable(struct device *dev, struct sg_table *sgt, | ||
| 265 | void *cpu_addr, dma_addr_t dma_addr, size_t size, | ||
| 266 | struct dma_attrs *attrs); | ||
| 283 | 267 | ||
| 284 | #endif /* __KERNEL__ */ | 268 | #endif /* __KERNEL__ */ |
| 285 | #endif | 269 | #endif |
diff --git a/arch/arm/include/asm/kmap_types.h b/arch/arm/include/asm/kmap_types.h index e51b1e81df05..83eb2f772911 100644 --- a/arch/arm/include/asm/kmap_types.h +++ b/arch/arm/include/asm/kmap_types.h | |||
| @@ -4,30 +4,6 @@ | |||
| 4 | /* | 4 | /* |
| 5 | * This is the "bare minimum". AIO seems to require this. | 5 | * This is the "bare minimum". AIO seems to require this. |
| 6 | */ | 6 | */ |
| 7 | enum km_type { | 7 | #define KM_TYPE_NR 16 |
| 8 | KM_BOUNCE_READ, | ||
| 9 | KM_SKB_SUNRPC_DATA, | ||
| 10 | KM_SKB_DATA_SOFTIRQ, | ||
| 11 | KM_USER0, | ||
| 12 | KM_USER1, | ||
| 13 | KM_BIO_SRC_IRQ, | ||
| 14 | KM_BIO_DST_IRQ, | ||
| 15 | KM_PTE0, | ||
| 16 | KM_PTE1, | ||
| 17 | KM_IRQ0, | ||
| 18 | KM_IRQ1, | ||
| 19 | KM_SOFTIRQ0, | ||
| 20 | KM_SOFTIRQ1, | ||
| 21 | KM_L1_CACHE, | ||
| 22 | KM_L2_CACHE, | ||
| 23 | KM_KDB, | ||
| 24 | KM_TYPE_NR | ||
| 25 | }; | ||
| 26 | |||
| 27 | #ifdef CONFIG_DEBUG_HIGHMEM | ||
| 28 | #define KM_NMI (-1) | ||
| 29 | #define KM_NMI_PTE (-1) | ||
| 30 | #define KM_IRQ_PTE (-1) | ||
| 31 | #endif | ||
| 32 | 8 | ||
| 33 | #endif | 9 | #endif |
diff --git a/arch/arm/include/asm/locks.h b/arch/arm/include/asm/locks.h deleted file mode 100644 index ef4c897772d1..000000000000 --- a/arch/arm/include/asm/locks.h +++ /dev/null | |||
| @@ -1,274 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * arch/arm/include/asm/locks.h | ||
| 3 | * | ||
| 4 | * Copyright (C) 2000 Russell King | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License version 2 as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | * | ||
| 10 | * Interrupt safe locking assembler. | ||
| 11 | */ | ||
| 12 | #ifndef __ASM_PROC_LOCKS_H | ||
| 13 | #define __ASM_PROC_LOCKS_H | ||
| 14 | |||
| 15 | #if __LINUX_ARM_ARCH__ >= 6 | ||
| 16 | |||
| 17 | #define __down_op(ptr,fail) \ | ||
| 18 | ({ \ | ||
| 19 | __asm__ __volatile__( \ | ||
| 20 | "@ down_op\n" \ | ||
| 21 | "1: ldrex lr, [%0]\n" \ | ||
| 22 | " sub lr, lr, %1\n" \ | ||
| 23 | " strex ip, lr, [%0]\n" \ | ||
| 24 | " teq ip, #0\n" \ | ||
| 25 | " bne 1b\n" \ | ||
| 26 | " teq lr, #0\n" \ | ||
| 27 | " movmi ip, %0\n" \ | ||
| 28 | " blmi " #fail \ | ||
| 29 | : \ | ||
| 30 | : "r" (ptr), "I" (1) \ | ||
| 31 | : "ip", "lr", "cc"); \ | ||
| 32 | smp_mb(); \ | ||
| 33 | }) | ||
| 34 | |||
| 35 | #define __down_op_ret(ptr,fail) \ | ||
| 36 | ({ \ | ||
| 37 | unsigned int ret; \ | ||
| 38 | __asm__ __volatile__( \ | ||
| 39 | "@ down_op_ret\n" \ | ||
| 40 | "1: ldrex lr, [%1]\n" \ | ||
| 41 | " sub lr, lr, %2\n" \ | ||
| 42 | " strex ip, lr, [%1]\n" \ | ||
| 43 | " teq ip, #0\n" \ | ||
| 44 | " bne 1b\n" \ | ||
| 45 | " teq lr, #0\n" \ | ||
| 46 | " movmi ip, %1\n" \ | ||
| 47 | " movpl ip, #0\n" \ | ||
| 48 | " blmi " #fail "\n" \ | ||
| 49 | " mov %0, ip" \ | ||
| 50 | : "=&r" (ret) \ | ||
| 51 | : "r" (ptr), "I" (1) \ | ||
| 52 | : "ip", "lr", "cc"); \ | ||
| 53 | smp_mb(); \ | ||
| 54 | ret; \ | ||
| 55 | }) | ||
| 56 | |||
| 57 | #define __up_op(ptr,wake) \ | ||
| 58 | ({ \ | ||
| 59 | smp_mb(); \ | ||
| 60 | __asm__ __volatile__( \ | ||
| 61 | "@ up_op\n" \ | ||
| 62 | "1: ldrex lr, [%0]\n" \ | ||
| 63 | " add lr, lr, %1\n" \ | ||
| 64 | " strex ip, lr, [%0]\n" \ | ||
| 65 | " teq ip, #0\n" \ | ||
| 66 | " bne 1b\n" \ | ||
| 67 | " cmp lr, #0\n" \ | ||
| 68 | " movle ip, %0\n" \ | ||
| 69 | " blle " #wake \ | ||
| 70 | : \ | ||
| 71 | : "r" (ptr), "I" (1) \ | ||
| 72 | : "ip", "lr", "cc"); \ | ||
| 73 | }) | ||
| 74 | |||
| 75 | /* | ||
| 76 | * The value 0x01000000 supports up to 128 processors and | ||
| 77 | * lots of processes. BIAS must be chosen such that sub'ing | ||
| 78 | * BIAS once per CPU will result in the long remaining | ||
| 79 | * negative. | ||
| 80 | */ | ||
| 81 | #define RW_LOCK_BIAS 0x01000000 | ||
| 82 | #define RW_LOCK_BIAS_STR "0x01000000" | ||
| 83 | |||
| 84 | #define __down_op_write(ptr,fail) \ | ||
| 85 | ({ \ | ||
| 86 | __asm__ __volatile__( \ | ||
| 87 | "@ down_op_write\n" \ | ||
| 88 | "1: ldrex lr, [%0]\n" \ | ||
| 89 | " sub lr, lr, %1\n" \ | ||
| 90 | " strex ip, lr, [%0]\n" \ | ||
| 91 | " teq ip, #0\n" \ | ||
| 92 | " bne 1b\n" \ | ||
| 93 | " teq lr, #0\n" \ | ||
| 94 | " movne ip, %0\n" \ | ||
| 95 | " blne " #fail \ | ||
| 96 | : \ | ||
| 97 | : "r" (ptr), "I" (RW_LOCK_BIAS) \ | ||
| 98 | : "ip", "lr", "cc"); \ | ||
| 99 | smp_mb(); \ | ||
| 100 | }) | ||
| 101 | |||
| 102 | #define __up_op_write(ptr,wake) \ | ||
| 103 | ({ \ | ||
| 104 | smp_mb(); \ | ||
| 105 | __asm__ __volatile__( \ | ||
| 106 | "@ up_op_write\n" \ | ||
| 107 | "1: ldrex lr, [%0]\n" \ | ||
| 108 | " adds lr, lr, %1\n" \ | ||
| 109 | " strex ip, lr, [%0]\n" \ | ||
| 110 | " teq ip, #0\n" \ | ||
| 111 | " bne 1b\n" \ | ||
| 112 | " movcs ip, %0\n" \ | ||
| 113 | " blcs " #wake \ | ||
| 114 | : \ | ||
| 115 | : "r" (ptr), "I" (RW_LOCK_BIAS) \ | ||
| 116 | : "ip", "lr", "cc"); \ | ||
| 117 | }) | ||
| 118 | |||
| 119 | #define __down_op_read(ptr,fail) \ | ||
| 120 | __down_op(ptr, fail) | ||
| 121 | |||
| 122 | #define __up_op_read(ptr,wake) \ | ||
| 123 | ({ \ | ||
| 124 | smp_mb(); \ | ||
| 125 | __asm__ __volatile__( \ | ||
| 126 | "@ up_op_read\n" \ | ||
| 127 | "1: ldrex lr, [%0]\n" \ | ||
| 128 | " add lr, lr, %1\n" \ | ||
| 129 | " strex ip, lr, [%0]\n" \ | ||
| 130 | " teq ip, #0\n" \ | ||
| 131 | " bne 1b\n" \ | ||
| 132 | " teq lr, #0\n" \ | ||
| 133 | " moveq ip, %0\n" \ | ||
| 134 | " bleq " #wake \ | ||
| 135 | : \ | ||
| 136 | : "r" (ptr), "I" (1) \ | ||
| 137 | : "ip", "lr", "cc"); \ | ||
| 138 | }) | ||
| 139 | |||
| 140 | #else | ||
| 141 | |||
| 142 | #define __down_op(ptr,fail) \ | ||
| 143 | ({ \ | ||
| 144 | __asm__ __volatile__( \ | ||
| 145 | "@ down_op\n" \ | ||
| 146 | " mrs ip, cpsr\n" \ | ||
| 147 | " orr lr, ip, #128\n" \ | ||
| 148 | " msr cpsr_c, lr\n" \ | ||
| 149 | " ldr lr, [%0]\n" \ | ||
| 150 | " subs lr, lr, %1\n" \ | ||
| 151 | " str lr, [%0]\n" \ | ||
| 152 | " msr cpsr_c, ip\n" \ | ||
| 153 | " movmi ip, %0\n" \ | ||
| 154 | " blmi " #fail \ | ||
| 155 | : \ | ||
| 156 | : "r" (ptr), "I" (1) \ | ||
| 157 | : "ip", "lr", "cc"); \ | ||
| 158 | smp_mb(); \ | ||
| 159 | }) | ||
| 160 | |||
| 161 | #define __down_op_ret(ptr,fail) \ | ||
| 162 | ({ \ | ||
| 163 | unsigned int ret; \ | ||
| 164 | __asm__ __volatile__( \ | ||
| 165 | "@ down_op_ret\n" \ | ||
| 166 | " mrs ip, cpsr\n" \ | ||
| 167 | " orr lr, ip, #128\n" \ | ||
| 168 | " msr cpsr_c, lr\n" \ | ||
| 169 | " ldr lr, [%1]\n" \ | ||
| 170 | " subs lr, lr, %2\n" \ | ||
| 171 | " str lr, [%1]\n" \ | ||
| 172 | " msr cpsr_c, ip\n" \ | ||
| 173 | " movmi ip, %1\n" \ | ||
| 174 | " movpl ip, #0\n" \ | ||
| 175 | " blmi " #fail "\n" \ | ||
| 176 | " mov %0, ip" \ | ||
| 177 | : "=&r" (ret) \ | ||
| 178 | : "r" (ptr), "I" (1) \ | ||
| 179 | : "ip", "lr", "cc"); \ | ||
| 180 | smp_mb(); \ | ||
| 181 | ret; \ | ||
| 182 | }) | ||
| 183 | |||
| 184 | #define __up_op(ptr,wake) \ | ||
| 185 | ({ \ | ||
| 186 | smp_mb(); \ | ||
| 187 | __asm__ __volatile__( \ | ||
| 188 | "@ up_op\n" \ | ||
| 189 | " mrs ip, cpsr\n" \ | ||
| 190 | " orr lr, ip, #128\n" \ | ||
| 191 | " msr cpsr_c, lr\n" \ | ||
| 192 | " ldr lr, [%0]\n" \ | ||
| 193 | " adds lr, lr, %1\n" \ | ||
| 194 | " str lr, [%0]\n" \ | ||
| 195 | " msr cpsr_c, ip\n" \ | ||
| 196 | " movle ip, %0\n" \ | ||
| 197 | " blle " #wake \ | ||
| 198 | : \ | ||
| 199 | : "r" (ptr), "I" (1) \ | ||
| 200 | : "ip", "lr", "cc"); \ | ||
| 201 | }) | ||
| 202 | |||
| 203 | /* | ||
| 204 | * The value 0x01000000 supports up to 128 processors and | ||
| 205 | * lots of processes. BIAS must be chosen such that sub'ing | ||
| 206 | * BIAS once per CPU will result in the long remaining | ||
| 207 | * negative. | ||
| 208 | */ | ||
| 209 | #define RW_LOCK_BIAS 0x01000000 | ||
| 210 | #define RW_LOCK_BIAS_STR "0x01000000" | ||
| 211 | |||
| 212 | #define __down_op_write(ptr,fail) \ | ||
| 213 | ({ \ | ||
| 214 | __asm__ __volatile__( \ | ||
| 215 | "@ down_op_write\n" \ | ||
| 216 | " mrs ip, cpsr\n" \ | ||
| 217 | " orr lr, ip, #128\n" \ | ||
| 218 | " msr cpsr_c, lr\n" \ | ||
| 219 | " ldr lr, [%0]\n" \ | ||
| 220 | " subs lr, lr, %1\n" \ | ||
| 221 | " str lr, [%0]\n" \ | ||
| 222 | " msr cpsr_c, ip\n" \ | ||
| 223 | " movne ip, %0\n" \ | ||
| 224 | " blne " #fail \ | ||
| 225 | : \ | ||
| 226 | : "r" (ptr), "I" (RW_LOCK_BIAS) \ | ||
| 227 | : "ip", "lr", "cc"); \ | ||
| 228 | smp_mb(); \ | ||
| 229 | }) | ||
| 230 | |||
| 231 | #define __up_op_write(ptr,wake) \ | ||
| 232 | ({ \ | ||
| 233 | __asm__ __volatile__( \ | ||
| 234 | "@ up_op_write\n" \ | ||
| 235 | " mrs ip, cpsr\n" \ | ||
| 236 | " orr lr, ip, #128\n" \ | ||
| 237 | " msr cpsr_c, lr\n" \ | ||
| 238 | " ldr lr, [%0]\n" \ | ||
| 239 | " adds lr, lr, %1\n" \ | ||
| 240 | " str lr, [%0]\n" \ | ||
| 241 | " msr cpsr_c, ip\n" \ | ||
| 242 | " movcs ip, %0\n" \ | ||
| 243 | " blcs " #wake \ | ||
| 244 | : \ | ||
| 245 | : "r" (ptr), "I" (RW_LOCK_BIAS) \ | ||
| 246 | : "ip", "lr", "cc"); \ | ||
| 247 | smp_mb(); \ | ||
| 248 | }) | ||
| 249 | |||
| 250 | #define __down_op_read(ptr,fail) \ | ||
| 251 | __down_op(ptr, fail) | ||
| 252 | |||
| 253 | #define __up_op_read(ptr,wake) \ | ||
| 254 | ({ \ | ||
| 255 | smp_mb(); \ | ||
| 256 | __asm__ __volatile__( \ | ||
| 257 | "@ up_op_read\n" \ | ||
| 258 | " mrs ip, cpsr\n" \ | ||
| 259 | " orr lr, ip, #128\n" \ | ||
| 260 | " msr cpsr_c, lr\n" \ | ||
| 261 | " ldr lr, [%0]\n" \ | ||
| 262 | " adds lr, lr, %1\n" \ | ||
| 263 | " str lr, [%0]\n" \ | ||
| 264 | " msr cpsr_c, ip\n" \ | ||
| 265 | " moveq ip, %0\n" \ | ||
| 266 | " bleq " #wake \ | ||
| 267 | : \ | ||
| 268 | : "r" (ptr), "I" (1) \ | ||
| 269 | : "ip", "lr", "cc"); \ | ||
| 270 | }) | ||
| 271 | |||
| 272 | #endif | ||
| 273 | |||
| 274 | #endif | ||
diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h index fcb575747e5e..e965f1b560f1 100644 --- a/arch/arm/include/asm/memory.h +++ b/arch/arm/include/asm/memory.h | |||
| @@ -16,7 +16,7 @@ | |||
| 16 | #include <linux/compiler.h> | 16 | #include <linux/compiler.h> |
| 17 | #include <linux/const.h> | 17 | #include <linux/const.h> |
| 18 | #include <linux/types.h> | 18 | #include <linux/types.h> |
| 19 | #include <asm/sizes.h> | 19 | #include <linux/sizes.h> |
| 20 | 20 | ||
| 21 | #ifdef CONFIG_NEED_MACH_MEMORY_H | 21 | #ifdef CONFIG_NEED_MACH_MEMORY_H |
| 22 | #include <mach/memory.h> | 22 | #include <mach/memory.h> |
diff --git a/arch/arm/include/asm/perf_event.h b/arch/arm/include/asm/perf_event.h index 00cbe10a50e3..e074948d8143 100644 --- a/arch/arm/include/asm/perf_event.h +++ b/arch/arm/include/asm/perf_event.h | |||
| @@ -12,21 +12,6 @@ | |||
| 12 | #ifndef __ARM_PERF_EVENT_H__ | 12 | #ifndef __ARM_PERF_EVENT_H__ |
| 13 | #define __ARM_PERF_EVENT_H__ | 13 | #define __ARM_PERF_EVENT_H__ |
| 14 | 14 | ||
| 15 | /* ARM perf PMU IDs for use by internal perf clients. */ | 15 | /* Nothing to see here... */ |
| 16 | enum arm_perf_pmu_ids { | ||
| 17 | ARM_PERF_PMU_ID_XSCALE1 = 0, | ||
| 18 | ARM_PERF_PMU_ID_XSCALE2, | ||
| 19 | ARM_PERF_PMU_ID_V6, | ||
| 20 | ARM_PERF_PMU_ID_V6MP, | ||
| 21 | ARM_PERF_PMU_ID_CA8, | ||
| 22 | ARM_PERF_PMU_ID_CA9, | ||
| 23 | ARM_PERF_PMU_ID_CA5, | ||
| 24 | ARM_PERF_PMU_ID_CA15, | ||
| 25 | ARM_PERF_PMU_ID_CA7, | ||
| 26 | ARM_NUM_PMU_IDS, | ||
| 27 | }; | ||
| 28 | |||
| 29 | extern enum arm_perf_pmu_ids | ||
| 30 | armpmu_get_pmu_id(void); | ||
| 31 | 16 | ||
| 32 | #endif /* __ARM_PERF_EVENT_H__ */ | 17 | #endif /* __ARM_PERF_EVENT_H__ */ |
diff --git a/arch/arm/include/asm/pmu.h b/arch/arm/include/asm/pmu.h index 90114faa9f3c..4432305f4a2a 100644 --- a/arch/arm/include/asm/pmu.h +++ b/arch/arm/include/asm/pmu.h | |||
| @@ -103,10 +103,9 @@ struct pmu_hw_events { | |||
| 103 | 103 | ||
| 104 | struct arm_pmu { | 104 | struct arm_pmu { |
| 105 | struct pmu pmu; | 105 | struct pmu pmu; |
| 106 | enum arm_perf_pmu_ids id; | ||
| 107 | enum arm_pmu_type type; | 106 | enum arm_pmu_type type; |
| 108 | cpumask_t active_irqs; | 107 | cpumask_t active_irqs; |
| 109 | const char *name; | 108 | char *name; |
| 110 | irqreturn_t (*handle_irq)(int irq_num, void *dev); | 109 | irqreturn_t (*handle_irq)(int irq_num, void *dev); |
| 111 | void (*enable)(struct hw_perf_event *evt, int idx); | 110 | void (*enable)(struct hw_perf_event *evt, int idx); |
| 112 | void (*disable)(struct hw_perf_event *evt, int idx); | 111 | void (*disable)(struct hw_perf_event *evt, int idx); |
diff --git a/arch/arm/include/asm/spinlock.h b/arch/arm/include/asm/spinlock.h index 65fa3c88095c..b4ca707d0a69 100644 --- a/arch/arm/include/asm/spinlock.h +++ b/arch/arm/include/asm/spinlock.h | |||
| @@ -59,18 +59,13 @@ static inline void dsb_sev(void) | |||
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | /* | 61 | /* |
| 62 | * ARMv6 Spin-locking. | 62 | * ARMv6 ticket-based spin-locking. |
| 63 | * | 63 | * |
| 64 | * We exclusively read the old value. If it is zero, we may have | 64 | * A memory barrier is required after we get a lock, and before we |
| 65 | * won the lock, so we try exclusively storing it. A memory barrier | 65 | * release it, because V6 CPUs are assumed to have weakly ordered |
| 66 | * is required after we get a lock, and before we release it, because | 66 | * memory. |
| 67 | * V6 CPUs are assumed to have weakly ordered memory. | ||
| 68 | * | ||
| 69 | * Unlocked value: 0 | ||
| 70 | * Locked value: 1 | ||
| 71 | */ | 67 | */ |
| 72 | 68 | ||
| 73 | #define arch_spin_is_locked(x) ((x)->lock != 0) | ||
| 74 | #define arch_spin_unlock_wait(lock) \ | 69 | #define arch_spin_unlock_wait(lock) \ |
| 75 | do { while (arch_spin_is_locked(lock)) cpu_relax(); } while (0) | 70 | do { while (arch_spin_is_locked(lock)) cpu_relax(); } while (0) |
| 76 | 71 | ||
| @@ -79,31 +74,39 @@ static inline void dsb_sev(void) | |||
| 79 | static inline void arch_spin_lock(arch_spinlock_t *lock) | 74 | static inline void arch_spin_lock(arch_spinlock_t *lock) |
| 80 | { | 75 | { |
| 81 | unsigned long tmp; | 76 | unsigned long tmp; |
| 77 | u32 newval; | ||
| 78 | arch_spinlock_t lockval; | ||
| 82 | 79 | ||
| 83 | __asm__ __volatile__( | 80 | __asm__ __volatile__( |
| 84 | "1: ldrex %0, [%1]\n" | 81 | "1: ldrex %0, [%3]\n" |
| 85 | " teq %0, #0\n" | 82 | " add %1, %0, %4\n" |
| 86 | WFE("ne") | 83 | " strex %2, %1, [%3]\n" |
| 87 | " strexeq %0, %2, [%1]\n" | 84 | " teq %2, #0\n" |
| 88 | " teqeq %0, #0\n" | ||
| 89 | " bne 1b" | 85 | " bne 1b" |
| 90 | : "=&r" (tmp) | 86 | : "=&r" (lockval), "=&r" (newval), "=&r" (tmp) |
| 91 | : "r" (&lock->lock), "r" (1) | 87 | : "r" (&lock->slock), "I" (1 << TICKET_SHIFT) |
| 92 | : "cc"); | 88 | : "cc"); |
| 93 | 89 | ||
| 90 | while (lockval.tickets.next != lockval.tickets.owner) { | ||
| 91 | wfe(); | ||
| 92 | lockval.tickets.owner = ACCESS_ONCE(lock->tickets.owner); | ||
| 93 | } | ||
| 94 | |||
| 94 | smp_mb(); | 95 | smp_mb(); |
| 95 | } | 96 | } |
| 96 | 97 | ||
| 97 | static inline int arch_spin_trylock(arch_spinlock_t *lock) | 98 | static inline int arch_spin_trylock(arch_spinlock_t *lock) |
| 98 | { | 99 | { |
| 99 | unsigned long tmp; | 100 | unsigned long tmp; |
| 101 | u32 slock; | ||
| 100 | 102 | ||
| 101 | __asm__ __volatile__( | 103 | __asm__ __volatile__( |
| 102 | " ldrex %0, [%1]\n" | 104 | " ldrex %0, [%2]\n" |
| 103 | " teq %0, #0\n" | 105 | " subs %1, %0, %0, ror #16\n" |
| 104 | " strexeq %0, %2, [%1]" | 106 | " addeq %0, %0, %3\n" |
| 105 | : "=&r" (tmp) | 107 | " strexeq %1, %0, [%2]" |
| 106 | : "r" (&lock->lock), "r" (1) | 108 | : "=&r" (slock), "=&r" (tmp) |
| 109 | : "r" (&lock->slock), "I" (1 << TICKET_SHIFT) | ||
| 107 | : "cc"); | 110 | : "cc"); |
| 108 | 111 | ||
| 109 | if (tmp == 0) { | 112 | if (tmp == 0) { |
| @@ -116,17 +119,38 @@ static inline int arch_spin_trylock(arch_spinlock_t *lock) | |||
| 116 | 119 | ||
| 117 | static inline void arch_spin_unlock(arch_spinlock_t *lock) | 120 | static inline void arch_spin_unlock(arch_spinlock_t *lock) |
| 118 | { | 121 | { |
| 122 | unsigned long tmp; | ||
| 123 | u32 slock; | ||
| 124 | |||
| 119 | smp_mb(); | 125 | smp_mb(); |
| 120 | 126 | ||
| 121 | __asm__ __volatile__( | 127 | __asm__ __volatile__( |
| 122 | " str %1, [%0]\n" | 128 | " mov %1, #1\n" |
| 123 | : | 129 | "1: ldrex %0, [%2]\n" |
| 124 | : "r" (&lock->lock), "r" (0) | 130 | " uadd16 %0, %0, %1\n" |
| 131 | " strex %1, %0, [%2]\n" | ||
| 132 | " teq %1, #0\n" | ||
| 133 | " bne 1b" | ||
| 134 | : "=&r" (slock), "=&r" (tmp) | ||
| 135 | : "r" (&lock->slock) | ||
| 125 | : "cc"); | 136 | : "cc"); |
| 126 | 137 | ||
| 127 | dsb_sev(); | 138 | dsb_sev(); |
| 128 | } | 139 | } |
| 129 | 140 | ||
| 141 | static inline int arch_spin_is_locked(arch_spinlock_t *lock) | ||
| 142 | { | ||
| 143 | struct __raw_tickets tickets = ACCESS_ONCE(lock->tickets); | ||
| 144 | return tickets.owner != tickets.next; | ||
| 145 | } | ||
| 146 | |||
| 147 | static inline int arch_spin_is_contended(arch_spinlock_t *lock) | ||
| 148 | { | ||
| 149 | struct __raw_tickets tickets = ACCESS_ONCE(lock->tickets); | ||
| 150 | return (tickets.next - tickets.owner) > 1; | ||
| 151 | } | ||
| 152 | #define arch_spin_is_contended arch_spin_is_contended | ||
| 153 | |||
| 130 | /* | 154 | /* |
| 131 | * RWLOCKS | 155 | * RWLOCKS |
| 132 | * | 156 | * |
| @@ -158,7 +182,7 @@ static inline int arch_write_trylock(arch_rwlock_t *rw) | |||
| 158 | unsigned long tmp; | 182 | unsigned long tmp; |
| 159 | 183 | ||
| 160 | __asm__ __volatile__( | 184 | __asm__ __volatile__( |
| 161 | "1: ldrex %0, [%1]\n" | 185 | " ldrex %0, [%1]\n" |
| 162 | " teq %0, #0\n" | 186 | " teq %0, #0\n" |
| 163 | " strexeq %0, %2, [%1]" | 187 | " strexeq %0, %2, [%1]" |
| 164 | : "=&r" (tmp) | 188 | : "=&r" (tmp) |
| @@ -244,7 +268,7 @@ static inline int arch_read_trylock(arch_rwlock_t *rw) | |||
| 244 | unsigned long tmp, tmp2 = 1; | 268 | unsigned long tmp, tmp2 = 1; |
| 245 | 269 | ||
| 246 | __asm__ __volatile__( | 270 | __asm__ __volatile__( |
| 247 | "1: ldrex %0, [%2]\n" | 271 | " ldrex %0, [%2]\n" |
| 248 | " adds %0, %0, #1\n" | 272 | " adds %0, %0, #1\n" |
| 249 | " strexpl %1, %0, [%2]\n" | 273 | " strexpl %1, %0, [%2]\n" |
| 250 | : "=&r" (tmp), "+r" (tmp2) | 274 | : "=&r" (tmp), "+r" (tmp2) |
diff --git a/arch/arm/include/asm/spinlock_types.h b/arch/arm/include/asm/spinlock_types.h index d14d197ae04a..b262d2f8b478 100644 --- a/arch/arm/include/asm/spinlock_types.h +++ b/arch/arm/include/asm/spinlock_types.h | |||
| @@ -5,11 +5,24 @@ | |||
| 5 | # error "please don't include this file directly" | 5 | # error "please don't include this file directly" |
| 6 | #endif | 6 | #endif |
| 7 | 7 | ||
| 8 | #define TICKET_SHIFT 16 | ||
| 9 | |||
| 8 | typedef struct { | 10 | typedef struct { |
| 9 | volatile unsigned int lock; | 11 | union { |
| 12 | u32 slock; | ||
| 13 | struct __raw_tickets { | ||
| 14 | #ifdef __ARMEB__ | ||
| 15 | u16 next; | ||
| 16 | u16 owner; | ||
| 17 | #else | ||
| 18 | u16 owner; | ||
| 19 | u16 next; | ||
| 20 | #endif | ||
| 21 | } tickets; | ||
| 22 | }; | ||
| 10 | } arch_spinlock_t; | 23 | } arch_spinlock_t; |
| 11 | 24 | ||
| 12 | #define __ARCH_SPIN_LOCK_UNLOCKED { 0 } | 25 | #define __ARCH_SPIN_LOCK_UNLOCKED { { 0 } } |
| 13 | 26 | ||
| 14 | typedef struct { | 27 | typedef struct { |
| 15 | volatile unsigned int lock; | 28 | volatile unsigned int lock; |
diff --git a/arch/arm/include/asm/timex.h b/arch/arm/include/asm/timex.h index 3be8de3adaba..ce119442277c 100644 --- a/arch/arm/include/asm/timex.h +++ b/arch/arm/include/asm/timex.h | |||
| @@ -12,13 +12,15 @@ | |||
| 12 | #ifndef _ASMARM_TIMEX_H | 12 | #ifndef _ASMARM_TIMEX_H |
| 13 | #define _ASMARM_TIMEX_H | 13 | #define _ASMARM_TIMEX_H |
| 14 | 14 | ||
| 15 | #include <asm/arch_timer.h> | ||
| 15 | #include <mach/timex.h> | 16 | #include <mach/timex.h> |
| 16 | 17 | ||
| 17 | typedef unsigned long cycles_t; | 18 | typedef unsigned long cycles_t; |
| 18 | 19 | ||
| 19 | static inline cycles_t get_cycles (void) | 20 | #ifdef ARCH_HAS_READ_CURRENT_TIMER |
| 20 | { | 21 | #define get_cycles() ({ cycles_t c; read_current_timer(&c) ? 0 : c; }) |
| 21 | return 0; | 22 | #else |
| 22 | } | 23 | #define get_cycles() (0) |
| 24 | #endif | ||
| 23 | 25 | ||
| 24 | #endif | 26 | #endif |
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h index 71f6536d17ac..479a6352e0b5 100644 --- a/arch/arm/include/asm/uaccess.h +++ b/arch/arm/include/asm/uaccess.h | |||
| @@ -189,6 +189,9 @@ static inline void set_fs(mm_segment_t fs) | |||
| 189 | 189 | ||
| 190 | #define access_ok(type,addr,size) (__range_ok(addr,size) == 0) | 190 | #define access_ok(type,addr,size) (__range_ok(addr,size) == 0) |
| 191 | 191 | ||
| 192 | #define user_addr_max() \ | ||
| 193 | (segment_eq(get_fs(), USER_DS) ? TASK_SIZE : ~0UL) | ||
| 194 | |||
| 192 | /* | 195 | /* |
| 193 | * The "__xxx" versions of the user access functions do not verify the | 196 | * The "__xxx" versions of the user access functions do not verify the |
| 194 | * address space - it must have been done previously with a separate | 197 | * address space - it must have been done previously with a separate |
| @@ -398,9 +401,6 @@ extern unsigned long __must_check __clear_user_std(void __user *addr, unsigned l | |||
| 398 | #define __clear_user(addr,n) (memset((void __force *)addr, 0, n), 0) | 401 | #define __clear_user(addr,n) (memset((void __force *)addr, 0, n), 0) |
| 399 | #endif | 402 | #endif |
| 400 | 403 | ||
| 401 | extern unsigned long __must_check __strncpy_from_user(char *to, const char __user *from, unsigned long count); | ||
| 402 | extern unsigned long __must_check __strnlen_user(const char __user *s, long n); | ||
| 403 | |||
| 404 | static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n) | 404 | static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n) |
| 405 | { | 405 | { |
| 406 | if (access_ok(VERIFY_READ, from, n)) | 406 | if (access_ok(VERIFY_READ, from, n)) |
| @@ -427,24 +427,9 @@ static inline unsigned long __must_check clear_user(void __user *to, unsigned lo | |||
| 427 | return n; | 427 | return n; |
| 428 | } | 428 | } |
| 429 | 429 | ||
| 430 | static inline long __must_check strncpy_from_user(char *dst, const char __user *src, long count) | 430 | extern long strncpy_from_user(char *dest, const char __user *src, long count); |
| 431 | { | ||
| 432 | long res = -EFAULT; | ||
| 433 | if (access_ok(VERIFY_READ, src, 1)) | ||
| 434 | res = __strncpy_from_user(dst, src, count); | ||
| 435 | return res; | ||
| 436 | } | ||
| 437 | |||
| 438 | #define strlen_user(s) strnlen_user(s, ~0UL >> 1) | ||
| 439 | 431 | ||
| 440 | static inline long __must_check strnlen_user(const char __user *s, long n) | 432 | extern __must_check long strlen_user(const char __user *str); |
| 441 | { | 433 | extern __must_check long strnlen_user(const char __user *str, long n); |
| 442 | unsigned long res = 0; | ||
| 443 | |||
| 444 | if (__addr_ok(s)) | ||
| 445 | res = __strnlen_user(s, n); | ||
| 446 | |||
| 447 | return res; | ||
| 448 | } | ||
| 449 | 434 | ||
| 450 | #endif /* _ASMARM_UACCESS_H */ | 435 | #endif /* _ASMARM_UACCESS_H */ |
diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h index 512cd1473454..0cab47d4a83f 100644 --- a/arch/arm/include/asm/unistd.h +++ b/arch/arm/include/asm/unistd.h | |||
| @@ -446,7 +446,6 @@ | |||
| 446 | 446 | ||
| 447 | #ifdef __KERNEL__ | 447 | #ifdef __KERNEL__ |
| 448 | 448 | ||
| 449 | #define __ARCH_WANT_IPC_PARSE_VERSION | ||
| 450 | #define __ARCH_WANT_STAT64 | 449 | #define __ARCH_WANT_STAT64 |
| 451 | #define __ARCH_WANT_SYS_GETHOSTNAME | 450 | #define __ARCH_WANT_SYS_GETHOSTNAME |
| 452 | #define __ARCH_WANT_SYS_PAUSE | 451 | #define __ARCH_WANT_SYS_PAUSE |
diff --git a/arch/arm/include/asm/word-at-a-time.h b/arch/arm/include/asm/word-at-a-time.h new file mode 100644 index 000000000000..4d52f92967a6 --- /dev/null +++ b/arch/arm/include/asm/word-at-a-time.h | |||
| @@ -0,0 +1,96 @@ | |||
| 1 | #ifndef __ASM_ARM_WORD_AT_A_TIME_H | ||
| 2 | #define __ASM_ARM_WORD_AT_A_TIME_H | ||
| 3 | |||
| 4 | #ifndef __ARMEB__ | ||
| 5 | |||
| 6 | /* | ||
| 7 | * Little-endian word-at-a-time zero byte handling. | ||
| 8 | * Heavily based on the x86 algorithm. | ||
| 9 | */ | ||
| 10 | #include <linux/kernel.h> | ||
| 11 | |||
| 12 | struct word_at_a_time { | ||
| 13 | const unsigned long one_bits, high_bits; | ||
| 14 | }; | ||
| 15 | |||
| 16 | #define WORD_AT_A_TIME_CONSTANTS { REPEAT_BYTE(0x01), REPEAT_BYTE(0x80) } | ||
| 17 | |||
| 18 | static inline unsigned long has_zero(unsigned long a, unsigned long *bits, | ||
| 19 | const struct word_at_a_time *c) | ||
| 20 | { | ||
| 21 | unsigned long mask = ((a - c->one_bits) & ~a) & c->high_bits; | ||
| 22 | *bits = mask; | ||
| 23 | return mask; | ||
| 24 | } | ||
| 25 | |||
| 26 | #define prep_zero_mask(a, bits, c) (bits) | ||
| 27 | |||
| 28 | static inline unsigned long create_zero_mask(unsigned long bits) | ||
| 29 | { | ||
| 30 | bits = (bits - 1) & ~bits; | ||
| 31 | return bits >> 7; | ||
| 32 | } | ||
| 33 | |||
| 34 | static inline unsigned long find_zero(unsigned long mask) | ||
| 35 | { | ||
| 36 | unsigned long ret; | ||
| 37 | |||
| 38 | #if __LINUX_ARM_ARCH__ >= 5 | ||
| 39 | /* We have clz available. */ | ||
| 40 | ret = fls(mask) >> 3; | ||
| 41 | #else | ||
| 42 | /* (000000 0000ff 00ffff ffffff) -> ( 1 1 2 3 ) */ | ||
| 43 | ret = (0x0ff0001 + mask) >> 23; | ||
| 44 | /* Fix the 1 for 00 case */ | ||
| 45 | ret &= mask; | ||
| 46 | #endif | ||
| 47 | |||
| 48 | return ret; | ||
| 49 | } | ||
| 50 | |||
| 51 | #ifdef CONFIG_DCACHE_WORD_ACCESS | ||
| 52 | |||
| 53 | #define zero_bytemask(mask) (mask) | ||
| 54 | |||
| 55 | /* | ||
| 56 | * Load an unaligned word from kernel space. | ||
| 57 | * | ||
| 58 | * In the (very unlikely) case of the word being a page-crosser | ||
| 59 | * and the next page not being mapped, take the exception and | ||
| 60 | * return zeroes in the non-existing part. | ||
| 61 | */ | ||
| 62 | static inline unsigned long load_unaligned_zeropad(const void *addr) | ||
| 63 | { | ||
| 64 | unsigned long ret, offset; | ||
| 65 | |||
| 66 | /* Load word from unaligned pointer addr */ | ||
| 67 | asm( | ||
| 68 | "1: ldr %0, [%2]\n" | ||
| 69 | "2:\n" | ||
| 70 | " .pushsection .fixup,\"ax\"\n" | ||
| 71 | " .align 2\n" | ||
| 72 | "3: and %1, %2, #0x3\n" | ||
| 73 | " bic %2, %2, #0x3\n" | ||
| 74 | " ldr %0, [%2]\n" | ||
| 75 | " lsl %1, %1, #0x3\n" | ||
| 76 | " lsr %0, %0, %1\n" | ||
| 77 | " b 2b\n" | ||
| 78 | " .popsection\n" | ||
| 79 | " .pushsection __ex_table,\"a\"\n" | ||
| 80 | " .align 3\n" | ||
| 81 | " .long 1b, 3b\n" | ||
| 82 | " .popsection" | ||
| 83 | : "=&r" (ret), "=&r" (offset) | ||
| 84 | : "r" (addr), "Qo" (*(unsigned long *)addr)); | ||
| 85 | |||
| 86 | return ret; | ||
| 87 | } | ||
| 88 | |||
| 89 | |||
| 90 | #endif /* DCACHE_WORD_ACCESS */ | ||
| 91 | |||
| 92 | #else /* __ARMEB__ */ | ||
| 93 | #include <asm-generic/word-at-a-time.h> | ||
| 94 | #endif | ||
| 95 | |||
| 96 | #endif /* __ASM_ARM_WORD_AT_A_TIME_H */ | ||
diff --git a/arch/arm/kernel/arch_timer.c b/arch/arm/kernel/arch_timer.c index dd58035621f7..cf258807160d 100644 --- a/arch/arm/kernel/arch_timer.c +++ b/arch/arm/kernel/arch_timer.c | |||
| @@ -32,6 +32,8 @@ static int arch_timer_ppi2; | |||
| 32 | 32 | ||
| 33 | static struct clock_event_device __percpu **arch_timer_evt; | 33 | static struct clock_event_device __percpu **arch_timer_evt; |
| 34 | 34 | ||
| 35 | extern void init_current_timer_delay(unsigned long freq); | ||
| 36 | |||
| 35 | /* | 37 | /* |
| 36 | * Architected system timer support. | 38 | * Architected system timer support. |
| 37 | */ | 39 | */ |
| @@ -137,7 +139,7 @@ static int __cpuinit arch_timer_setup(struct clock_event_device *clk) | |||
| 137 | /* Be safe... */ | 139 | /* Be safe... */ |
| 138 | arch_timer_disable(); | 140 | arch_timer_disable(); |
| 139 | 141 | ||
| 140 | clk->features = CLOCK_EVT_FEAT_ONESHOT; | 142 | clk->features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_C3STOP; |
| 141 | clk->name = "arch_sys_timer"; | 143 | clk->name = "arch_sys_timer"; |
| 142 | clk->rating = 450; | 144 | clk->rating = 450; |
| 143 | clk->set_mode = arch_timer_set_mode; | 145 | clk->set_mode = arch_timer_set_mode; |
| @@ -223,6 +225,14 @@ static cycle_t arch_counter_read(struct clocksource *cs) | |||
| 223 | return arch_counter_get_cntpct(); | 225 | return arch_counter_get_cntpct(); |
| 224 | } | 226 | } |
| 225 | 227 | ||
| 228 | int read_current_timer(unsigned long *timer_val) | ||
| 229 | { | ||
| 230 | if (!arch_timer_rate) | ||
| 231 | return -ENXIO; | ||
| 232 | *timer_val = arch_counter_get_cntpct(); | ||
| 233 | return 0; | ||
| 234 | } | ||
| 235 | |||
| 226 | static struct clocksource clocksource_counter = { | 236 | static struct clocksource clocksource_counter = { |
| 227 | .name = "arch_sys_counter", | 237 | .name = "arch_sys_counter", |
| 228 | .rating = 400, | 238 | .rating = 400, |
| @@ -296,6 +306,7 @@ static int __init arch_timer_register(void) | |||
| 296 | if (err) | 306 | if (err) |
| 297 | goto out_free_irq; | 307 | goto out_free_irq; |
| 298 | 308 | ||
| 309 | init_current_timer_delay(arch_timer_rate); | ||
| 299 | return 0; | 310 | return 0; |
| 300 | 311 | ||
| 301 | out_free_irq: | 312 | out_free_irq: |
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c index b57c75e0b01f..60d3b738d420 100644 --- a/arch/arm/kernel/armksyms.c +++ b/arch/arm/kernel/armksyms.c | |||
| @@ -49,8 +49,7 @@ extern void __aeabi_ulcmp(void); | |||
| 49 | extern void fpundefinstr(void); | 49 | extern void fpundefinstr(void); |
| 50 | 50 | ||
| 51 | /* platform dependent support */ | 51 | /* platform dependent support */ |
| 52 | EXPORT_SYMBOL(__udelay); | 52 | EXPORT_SYMBOL(arm_delay_ops); |
| 53 | EXPORT_SYMBOL(__const_udelay); | ||
| 54 | 53 | ||
| 55 | /* networking */ | 54 | /* networking */ |
| 56 | EXPORT_SYMBOL(csum_partial); | 55 | EXPORT_SYMBOL(csum_partial); |
| @@ -87,10 +86,6 @@ EXPORT_SYMBOL(memmove); | |||
| 87 | EXPORT_SYMBOL(memchr); | 86 | EXPORT_SYMBOL(memchr); |
| 88 | EXPORT_SYMBOL(__memzero); | 87 | EXPORT_SYMBOL(__memzero); |
| 89 | 88 | ||
| 90 | /* user mem (segment) */ | ||
| 91 | EXPORT_SYMBOL(__strnlen_user); | ||
| 92 | EXPORT_SYMBOL(__strncpy_from_user); | ||
| 93 | |||
| 94 | #ifdef CONFIG_MMU | 89 | #ifdef CONFIG_MMU |
| 95 | EXPORT_SYMBOL(copy_page); | 90 | EXPORT_SYMBOL(copy_page); |
| 96 | 91 | ||
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 4afed88d250a..49d9f9305247 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S | |||
| @@ -95,13 +95,7 @@ ENDPROC(ret_to_user) | |||
| 95 | ENTRY(ret_from_fork) | 95 | ENTRY(ret_from_fork) |
| 96 | bl schedule_tail | 96 | bl schedule_tail |
| 97 | get_thread_info tsk | 97 | get_thread_info tsk |
| 98 | ldr r1, [tsk, #TI_FLAGS] @ check for syscall tracing | ||
| 99 | mov why, #1 | 98 | mov why, #1 |
| 100 | tst r1, #_TIF_SYSCALL_WORK @ are we tracing syscalls? | ||
| 101 | beq ret_slow_syscall | ||
| 102 | mov r1, sp | ||
| 103 | mov r0, #1 @ trace exit [IP = 1] | ||
| 104 | bl syscall_trace | ||
| 105 | b ret_slow_syscall | 99 | b ret_slow_syscall |
| 106 | ENDPROC(ret_from_fork) | 100 | ENDPROC(ret_from_fork) |
| 107 | 101 | ||
| @@ -448,10 +442,9 @@ ENDPROC(vector_swi) | |||
| 448 | * context switches, and waiting for our parent to respond. | 442 | * context switches, and waiting for our parent to respond. |
| 449 | */ | 443 | */ |
| 450 | __sys_trace: | 444 | __sys_trace: |
| 451 | mov r2, scno | 445 | mov r1, scno |
| 452 | add r1, sp, #S_OFF | 446 | add r0, sp, #S_OFF |
| 453 | mov r0, #0 @ trace entry [IP = 0] | 447 | bl syscall_trace_enter |
| 454 | bl syscall_trace | ||
| 455 | 448 | ||
| 456 | adr lr, BSYM(__sys_trace_return) @ return address | 449 | adr lr, BSYM(__sys_trace_return) @ return address |
| 457 | mov scno, r0 @ syscall number (possibly new) | 450 | mov scno, r0 @ syscall number (possibly new) |
| @@ -463,10 +456,9 @@ __sys_trace: | |||
| 463 | 456 | ||
| 464 | __sys_trace_return: | 457 | __sys_trace_return: |
| 465 | str r0, [sp, #S_R0 + S_OFF]! @ save returned r0 | 458 | str r0, [sp, #S_R0 + S_OFF]! @ save returned r0 |
| 466 | mov r2, scno | 459 | mov r1, scno |
| 467 | mov r1, sp | 460 | mov r0, sp |
| 468 | mov r0, #1 @ trace exit [IP = 1] | 461 | bl syscall_trace_exit |
| 469 | bl syscall_trace | ||
| 470 | b ret_slow_syscall | 462 | b ret_slow_syscall |
| 471 | 463 | ||
| 472 | .align 5 | 464 | .align 5 |
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index 835898e7d704..3db960e20cb8 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S | |||
| @@ -55,14 +55,6 @@ | |||
| 55 | add \rd, \phys, #TEXT_OFFSET - PG_DIR_SIZE | 55 | add \rd, \phys, #TEXT_OFFSET - PG_DIR_SIZE |
| 56 | .endm | 56 | .endm |
| 57 | 57 | ||
| 58 | #ifdef CONFIG_XIP_KERNEL | ||
| 59 | #define KERNEL_START XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR) | ||
| 60 | #define KERNEL_END _edata_loc | ||
| 61 | #else | ||
| 62 | #define KERNEL_START KERNEL_RAM_VADDR | ||
| 63 | #define KERNEL_END _end | ||
| 64 | #endif | ||
| 65 | |||
| 66 | /* | 58 | /* |
| 67 | * Kernel startup entry point. | 59 | * Kernel startup entry point. |
| 68 | * --------------------------- | 60 | * --------------------------- |
| @@ -218,51 +210,46 @@ __create_page_tables: | |||
| 218 | blo 1b | 210 | blo 1b |
| 219 | 211 | ||
| 220 | /* | 212 | /* |
| 221 | * Now setup the pagetables for our kernel direct | 213 | * Map our RAM from the start to the end of the kernel .bss section. |
| 222 | * mapped region. | ||
| 223 | */ | 214 | */ |
| 224 | mov r3, pc | 215 | add r0, r4, #PAGE_OFFSET >> (SECTION_SHIFT - PMD_ORDER) |
| 225 | mov r3, r3, lsr #SECTION_SHIFT | 216 | ldr r6, =(_end - 1) |
| 226 | orr r3, r7, r3, lsl #SECTION_SHIFT | 217 | orr r3, r8, r7 |
| 227 | add r0, r4, #(KERNEL_START & 0xff000000) >> (SECTION_SHIFT - PMD_ORDER) | ||
| 228 | str r3, [r0, #((KERNEL_START & 0x00f00000) >> SECTION_SHIFT) << PMD_ORDER]! | ||
| 229 | ldr r6, =(KERNEL_END - 1) | ||
| 230 | add r0, r0, #1 << PMD_ORDER | ||
| 231 | add r6, r4, r6, lsr #(SECTION_SHIFT - PMD_ORDER) | 218 | add r6, r4, r6, lsr #(SECTION_SHIFT - PMD_ORDER) |
| 232 | 1: cmp r0, r6 | 219 | 1: str r3, [r0], #1 << PMD_ORDER |
| 233 | add r3, r3, #1 << SECTION_SHIFT | 220 | add r3, r3, #1 << SECTION_SHIFT |
| 234 | strls r3, [r0], #1 << PMD_ORDER | 221 | cmp r0, r6 |
| 235 | bls 1b | 222 | bls 1b |
| 236 | 223 | ||
| 237 | #ifdef CONFIG_XIP_KERNEL | 224 | #ifdef CONFIG_XIP_KERNEL |
| 238 | /* | 225 | /* |
| 239 | * Map some ram to cover our .data and .bss areas. | 226 | * Map the kernel image separately as it is not located in RAM. |
| 240 | */ | 227 | */ |
| 241 | add r3, r8, #TEXT_OFFSET | 228 | #define XIP_START XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR) |
| 242 | orr r3, r3, r7 | 229 | mov r3, pc |
| 243 | add r0, r4, #(KERNEL_RAM_VADDR & 0xff000000) >> (SECTION_SHIFT - PMD_ORDER) | 230 | mov r3, r3, lsr #SECTION_SHIFT |
| 244 | str r3, [r0, #(KERNEL_RAM_VADDR & 0x00f00000) >> (SECTION_SHIFT - PMD_ORDER)]! | 231 | orr r3, r7, r3, lsl #SECTION_SHIFT |
| 245 | ldr r6, =(_end - 1) | 232 | add r0, r4, #(XIP_START & 0xff000000) >> (SECTION_SHIFT - PMD_ORDER) |
| 246 | add r0, r0, #4 | 233 | str r3, [r0, #((XIP_START & 0x00f00000) >> SECTION_SHIFT) << PMD_ORDER]! |
| 234 | ldr r6, =(_edata_loc - 1) | ||
| 235 | add r0, r0, #1 << PMD_ORDER | ||
| 247 | add r6, r4, r6, lsr #(SECTION_SHIFT - PMD_ORDER) | 236 | add r6, r4, r6, lsr #(SECTION_SHIFT - PMD_ORDER) |
| 248 | 1: cmp r0, r6 | 237 | 1: cmp r0, r6 |
| 249 | add r3, r3, #1 << 20 | 238 | add r3, r3, #1 << SECTION_SHIFT |
| 250 | strls r3, [r0], #4 | 239 | strls r3, [r0], #1 << PMD_ORDER |
| 251 | bls 1b | 240 | bls 1b |
| 252 | #endif | 241 | #endif |
| 253 | 242 | ||
| 254 | /* | 243 | /* |
| 255 | * Then map boot params address in r2 or the first 1MB (2MB with LPAE) | 244 | * Then map boot params address in r2 if specified. |
| 256 | * of ram if boot params address is not specified. | ||
| 257 | */ | 245 | */ |
| 258 | mov r0, r2, lsr #SECTION_SHIFT | 246 | mov r0, r2, lsr #SECTION_SHIFT |
| 259 | movs r0, r0, lsl #SECTION_SHIFT | 247 | movs r0, r0, lsl #SECTION_SHIFT |
| 260 | moveq r0, r8 | 248 | subne r3, r0, r8 |
| 261 | sub r3, r0, r8 | 249 | addne r3, r3, #PAGE_OFFSET |
| 262 | add r3, r3, #PAGE_OFFSET | 250 | addne r3, r4, r3, lsr #(SECTION_SHIFT - PMD_ORDER) |
| 263 | add r3, r4, r3, lsr #(SECTION_SHIFT - PMD_ORDER) | 251 | orrne r6, r7, r0 |
| 264 | orr r6, r7, r0 | 252 | strne r6, [r3] |
| 265 | str r6, [r3] | ||
| 266 | 253 | ||
| 267 | #ifdef CONFIG_DEBUG_LL | 254 | #ifdef CONFIG_DEBUG_LL |
| 268 | #if !defined(CONFIG_DEBUG_ICEDCC) && !defined(CONFIG_DEBUG_SEMIHOSTING) | 255 | #if !defined(CONFIG_DEBUG_ICEDCC) && !defined(CONFIG_DEBUG_SEMIHOSTING) |
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index a02eada3aa5d..ab243b87118d 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c | |||
| @@ -47,17 +47,14 @@ static DEFINE_PER_CPU(struct pmu_hw_events, cpu_hw_events); | |||
| 47 | /* Set at runtime when we know what CPU type we are. */ | 47 | /* Set at runtime when we know what CPU type we are. */ |
| 48 | static struct arm_pmu *cpu_pmu; | 48 | static struct arm_pmu *cpu_pmu; |
| 49 | 49 | ||
| 50 | enum arm_perf_pmu_ids | 50 | const char *perf_pmu_name(void) |
| 51 | armpmu_get_pmu_id(void) | ||
| 52 | { | 51 | { |
| 53 | int id = -ENODEV; | 52 | if (!cpu_pmu) |
| 54 | 53 | return NULL; | |
| 55 | if (cpu_pmu != NULL) | ||
| 56 | id = cpu_pmu->id; | ||
| 57 | 54 | ||
| 58 | return id; | 55 | return cpu_pmu->pmu.name; |
| 59 | } | 56 | } |
| 60 | EXPORT_SYMBOL_GPL(armpmu_get_pmu_id); | 57 | EXPORT_SYMBOL_GPL(perf_pmu_name); |
| 61 | 58 | ||
| 62 | int perf_num_counters(void) | 59 | int perf_num_counters(void) |
| 63 | { | 60 | { |
| @@ -760,7 +757,7 @@ init_hw_perf_events(void) | |||
| 760 | cpu_pmu->name, cpu_pmu->num_events); | 757 | cpu_pmu->name, cpu_pmu->num_events); |
| 761 | cpu_pmu_init(cpu_pmu); | 758 | cpu_pmu_init(cpu_pmu); |
| 762 | register_cpu_notifier(&pmu_cpu_notifier); | 759 | register_cpu_notifier(&pmu_cpu_notifier); |
| 763 | armpmu_register(cpu_pmu, "cpu", PERF_TYPE_RAW); | 760 | armpmu_register(cpu_pmu, cpu_pmu->name, PERF_TYPE_RAW); |
| 764 | } else { | 761 | } else { |
| 765 | pr_info("no hardware support available\n"); | 762 | pr_info("no hardware support available\n"); |
| 766 | } | 763 | } |
diff --git a/arch/arm/kernel/perf_event_v6.c b/arch/arm/kernel/perf_event_v6.c index ab627a740fa3..c90fcb2b6967 100644 --- a/arch/arm/kernel/perf_event_v6.c +++ b/arch/arm/kernel/perf_event_v6.c | |||
| @@ -650,7 +650,6 @@ static int armv6_map_event(struct perf_event *event) | |||
| 650 | } | 650 | } |
| 651 | 651 | ||
| 652 | static struct arm_pmu armv6pmu = { | 652 | static struct arm_pmu armv6pmu = { |
| 653 | .id = ARM_PERF_PMU_ID_V6, | ||
| 654 | .name = "v6", | 653 | .name = "v6", |
| 655 | .handle_irq = armv6pmu_handle_irq, | 654 | .handle_irq = armv6pmu_handle_irq, |
| 656 | .enable = armv6pmu_enable_event, | 655 | .enable = armv6pmu_enable_event, |
| @@ -685,7 +684,6 @@ static int armv6mpcore_map_event(struct perf_event *event) | |||
| 685 | } | 684 | } |
| 686 | 685 | ||
| 687 | static struct arm_pmu armv6mpcore_pmu = { | 686 | static struct arm_pmu armv6mpcore_pmu = { |
| 688 | .id = ARM_PERF_PMU_ID_V6MP, | ||
| 689 | .name = "v6mpcore", | 687 | .name = "v6mpcore", |
| 690 | .handle_irq = armv6pmu_handle_irq, | 688 | .handle_irq = armv6pmu_handle_irq, |
| 691 | .enable = armv6pmu_enable_event, | 689 | .enable = armv6pmu_enable_event, |
diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c index d3c536068162..f04070bd2183 100644 --- a/arch/arm/kernel/perf_event_v7.c +++ b/arch/arm/kernel/perf_event_v7.c | |||
| @@ -1258,7 +1258,6 @@ static u32 __init armv7_read_num_pmnc_events(void) | |||
| 1258 | 1258 | ||
| 1259 | static struct arm_pmu *__init armv7_a8_pmu_init(void) | 1259 | static struct arm_pmu *__init armv7_a8_pmu_init(void) |
| 1260 | { | 1260 | { |
| 1261 | armv7pmu.id = ARM_PERF_PMU_ID_CA8; | ||
| 1262 | armv7pmu.name = "ARMv7 Cortex-A8"; | 1261 | armv7pmu.name = "ARMv7 Cortex-A8"; |
| 1263 | armv7pmu.map_event = armv7_a8_map_event; | 1262 | armv7pmu.map_event = armv7_a8_map_event; |
| 1264 | armv7pmu.num_events = armv7_read_num_pmnc_events(); | 1263 | armv7pmu.num_events = armv7_read_num_pmnc_events(); |
| @@ -1267,7 +1266,6 @@ static struct arm_pmu *__init armv7_a8_pmu_init(void) | |||
| 1267 | 1266 | ||
| 1268 | static struct arm_pmu *__init armv7_a9_pmu_init(void) | 1267 | static struct arm_pmu *__init armv7_a9_pmu_init(void) |
| 1269 | { | 1268 | { |
| 1270 | armv7pmu.id = ARM_PERF_PMU_ID_CA9; | ||
| 1271 | armv7pmu.name = "ARMv7 Cortex-A9"; | 1269 | armv7pmu.name = "ARMv7 Cortex-A9"; |
| 1272 | armv7pmu.map_event = armv7_a9_map_event; | 1270 | armv7pmu.map_event = armv7_a9_map_event; |
| 1273 | armv7pmu.num_events = armv7_read_num_pmnc_events(); | 1271 | armv7pmu.num_events = armv7_read_num_pmnc_events(); |
| @@ -1276,7 +1274,6 @@ static struct arm_pmu *__init armv7_a9_pmu_init(void) | |||
| 1276 | 1274 | ||
| 1277 | static struct arm_pmu *__init armv7_a5_pmu_init(void) | 1275 | static struct arm_pmu *__init armv7_a5_pmu_init(void) |
| 1278 | { | 1276 | { |
| 1279 | armv7pmu.id = ARM_PERF_PMU_ID_CA5; | ||
| 1280 | armv7pmu.name = "ARMv7 Cortex-A5"; | 1277 | armv7pmu.name = "ARMv7 Cortex-A5"; |
| 1281 | armv7pmu.map_event = armv7_a5_map_event; | 1278 | armv7pmu.map_event = armv7_a5_map_event; |
| 1282 | armv7pmu.num_events = armv7_read_num_pmnc_events(); | 1279 | armv7pmu.num_events = armv7_read_num_pmnc_events(); |
| @@ -1285,7 +1282,6 @@ static struct arm_pmu *__init armv7_a5_pmu_init(void) | |||
| 1285 | 1282 | ||
| 1286 | static struct arm_pmu *__init armv7_a15_pmu_init(void) | 1283 | static struct arm_pmu *__init armv7_a15_pmu_init(void) |
| 1287 | { | 1284 | { |
| 1288 | armv7pmu.id = ARM_PERF_PMU_ID_CA15; | ||
| 1289 | armv7pmu.name = "ARMv7 Cortex-A15"; | 1285 | armv7pmu.name = "ARMv7 Cortex-A15"; |
| 1290 | armv7pmu.map_event = armv7_a15_map_event; | 1286 | armv7pmu.map_event = armv7_a15_map_event; |
| 1291 | armv7pmu.num_events = armv7_read_num_pmnc_events(); | 1287 | armv7pmu.num_events = armv7_read_num_pmnc_events(); |
| @@ -1295,7 +1291,6 @@ static struct arm_pmu *__init armv7_a15_pmu_init(void) | |||
| 1295 | 1291 | ||
| 1296 | static struct arm_pmu *__init armv7_a7_pmu_init(void) | 1292 | static struct arm_pmu *__init armv7_a7_pmu_init(void) |
| 1297 | { | 1293 | { |
| 1298 | armv7pmu.id = ARM_PERF_PMU_ID_CA7; | ||
| 1299 | armv7pmu.name = "ARMv7 Cortex-A7"; | 1294 | armv7pmu.name = "ARMv7 Cortex-A7"; |
| 1300 | armv7pmu.map_event = armv7_a7_map_event; | 1295 | armv7pmu.map_event = armv7_a7_map_event; |
| 1301 | armv7pmu.num_events = armv7_read_num_pmnc_events(); | 1296 | armv7pmu.num_events = armv7_read_num_pmnc_events(); |
diff --git a/arch/arm/kernel/perf_event_xscale.c b/arch/arm/kernel/perf_event_xscale.c index e34e7254e652..f759fe0bab63 100644 --- a/arch/arm/kernel/perf_event_xscale.c +++ b/arch/arm/kernel/perf_event_xscale.c | |||
| @@ -435,7 +435,6 @@ static int xscale_map_event(struct perf_event *event) | |||
| 435 | } | 435 | } |
| 436 | 436 | ||
| 437 | static struct arm_pmu xscale1pmu = { | 437 | static struct arm_pmu xscale1pmu = { |
| 438 | .id = ARM_PERF_PMU_ID_XSCALE1, | ||
| 439 | .name = "xscale1", | 438 | .name = "xscale1", |
| 440 | .handle_irq = xscale1pmu_handle_irq, | 439 | .handle_irq = xscale1pmu_handle_irq, |
| 441 | .enable = xscale1pmu_enable_event, | 440 | .enable = xscale1pmu_enable_event, |
| @@ -803,7 +802,6 @@ xscale2pmu_write_counter(int counter, u32 val) | |||
| 803 | } | 802 | } |
| 804 | 803 | ||
| 805 | static struct arm_pmu xscale2pmu = { | 804 | static struct arm_pmu xscale2pmu = { |
| 806 | .id = ARM_PERF_PMU_ID_XSCALE2, | ||
| 807 | .name = "xscale2", | 805 | .name = "xscale2", |
| 808 | .handle_irq = xscale2pmu_handle_irq, | 806 | .handle_irq = xscale2pmu_handle_irq, |
| 809 | .enable = xscale2pmu_enable_event, | 807 | .enable = xscale2pmu_enable_event, |
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index 14e38261cd31..dab711e6e1ca 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c | |||
| @@ -907,16 +907,16 @@ long arch_ptrace(struct task_struct *child, long request, | |||
| 907 | return ret; | 907 | return ret; |
| 908 | } | 908 | } |
| 909 | 909 | ||
| 910 | asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno) | 910 | enum ptrace_syscall_dir { |
| 911 | PTRACE_SYSCALL_ENTER = 0, | ||
| 912 | PTRACE_SYSCALL_EXIT, | ||
| 913 | }; | ||
| 914 | |||
| 915 | static int ptrace_syscall_trace(struct pt_regs *regs, int scno, | ||
| 916 | enum ptrace_syscall_dir dir) | ||
| 911 | { | 917 | { |
| 912 | unsigned long ip; | 918 | unsigned long ip; |
| 913 | 919 | ||
| 914 | if (why) | ||
| 915 | audit_syscall_exit(regs); | ||
| 916 | else | ||
| 917 | audit_syscall_entry(AUDIT_ARCH_ARM, scno, regs->ARM_r0, | ||
| 918 | regs->ARM_r1, regs->ARM_r2, regs->ARM_r3); | ||
| 919 | |||
| 920 | if (!test_thread_flag(TIF_SYSCALL_TRACE)) | 920 | if (!test_thread_flag(TIF_SYSCALL_TRACE)) |
| 921 | return scno; | 921 | return scno; |
| 922 | 922 | ||
| @@ -927,14 +927,28 @@ asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno) | |||
| 927 | * IP = 0 -> entry, =1 -> exit | 927 | * IP = 0 -> entry, =1 -> exit |
| 928 | */ | 928 | */ |
| 929 | ip = regs->ARM_ip; | 929 | ip = regs->ARM_ip; |
| 930 | regs->ARM_ip = why; | 930 | regs->ARM_ip = dir; |
| 931 | 931 | ||
| 932 | if (why) | 932 | if (dir == PTRACE_SYSCALL_EXIT) |
| 933 | tracehook_report_syscall_exit(regs, 0); | 933 | tracehook_report_syscall_exit(regs, 0); |
| 934 | else if (tracehook_report_syscall_entry(regs)) | 934 | else if (tracehook_report_syscall_entry(regs)) |
| 935 | current_thread_info()->syscall = -1; | 935 | current_thread_info()->syscall = -1; |
| 936 | 936 | ||
| 937 | regs->ARM_ip = ip; | 937 | regs->ARM_ip = ip; |
| 938 | |||
| 939 | return current_thread_info()->syscall; | 938 | return current_thread_info()->syscall; |
| 940 | } | 939 | } |
| 940 | |||
| 941 | asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno) | ||
| 942 | { | ||
| 943 | int ret = ptrace_syscall_trace(regs, scno, PTRACE_SYSCALL_ENTER); | ||
| 944 | audit_syscall_entry(AUDIT_ARCH_ARM, scno, regs->ARM_r0, regs->ARM_r1, | ||
| 945 | regs->ARM_r2, regs->ARM_r3); | ||
| 946 | return ret; | ||
| 947 | } | ||
| 948 | |||
| 949 | asmlinkage int syscall_trace_exit(struct pt_regs *regs, int scno) | ||
| 950 | { | ||
| 951 | int ret = ptrace_syscall_trace(regs, scno, PTRACE_SYSCALL_EXIT); | ||
| 952 | audit_syscall_exit(regs); | ||
| 953 | return ret; | ||
| 954 | } | ||
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 2c7217d971db..aea74f5bc34a 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c | |||
| @@ -179,7 +179,7 @@ void __ref cpu_die(void) | |||
| 179 | mb(); | 179 | mb(); |
| 180 | 180 | ||
| 181 | /* Tell __cpu_die() that this CPU is now safe to dispose of */ | 181 | /* Tell __cpu_die() that this CPU is now safe to dispose of */ |
| 182 | complete(&cpu_died); | 182 | RCU_NONIDLE(complete(&cpu_died)); |
| 183 | 183 | ||
| 184 | /* | 184 | /* |
| 185 | * actual CPU shutdown procedure is at least platform (if not | 185 | * actual CPU shutdown procedure is at least platform (if not |
diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c index 8200deaa14f6..198b08456e90 100644 --- a/arch/arm/kernel/topology.c +++ b/arch/arm/kernel/topology.c | |||
| @@ -17,11 +17,190 @@ | |||
| 17 | #include <linux/percpu.h> | 17 | #include <linux/percpu.h> |
| 18 | #include <linux/node.h> | 18 | #include <linux/node.h> |
| 19 | #include <linux/nodemask.h> | 19 | #include <linux/nodemask.h> |
| 20 | #include <linux/of.h> | ||
| 20 | #include <linux/sched.h> | 21 | #include <linux/sched.h> |
| 22 | #include <linux/slab.h> | ||
| 21 | 23 | ||
| 22 | #include <asm/cputype.h> | 24 | #include <asm/cputype.h> |
| 23 | #include <asm/topology.h> | 25 | #include <asm/topology.h> |
| 24 | 26 | ||
| 27 | /* | ||
| 28 | * cpu power scale management | ||
| 29 | */ | ||
| 30 | |||
| 31 | /* | ||
| 32 | * cpu power table | ||
| 33 | * This per cpu data structure describes the relative capacity of each core. | ||
| 34 | * On a heteregenous system, cores don't have the same computation capacity | ||
| 35 | * and we reflect that difference in the cpu_power field so the scheduler can | ||
| 36 | * take this difference into account during load balance. A per cpu structure | ||
| 37 | * is preferred because each CPU updates its own cpu_power field during the | ||
| 38 | * load balance except for idle cores. One idle core is selected to run the | ||
| 39 | * rebalance_domains for all idle cores and the cpu_power can be updated | ||
| 40 | * during this sequence. | ||
| 41 | */ | ||
| 42 | static DEFINE_PER_CPU(unsigned long, cpu_scale); | ||
| 43 | |||
| 44 | unsigned long arch_scale_freq_power(struct sched_domain *sd, int cpu) | ||
| 45 | { | ||
| 46 | return per_cpu(cpu_scale, cpu); | ||
| 47 | } | ||
| 48 | |||
| 49 | static void set_power_scale(unsigned int cpu, unsigned long power) | ||
| 50 | { | ||
| 51 | per_cpu(cpu_scale, cpu) = power; | ||
| 52 | } | ||
| 53 | |||
| 54 | #ifdef CONFIG_OF | ||
| 55 | struct cpu_efficiency { | ||
| 56 | const char *compatible; | ||
| 57 | unsigned long efficiency; | ||
| 58 | }; | ||
| 59 | |||
| 60 | /* | ||
| 61 | * Table of relative efficiency of each processors | ||
| 62 | * The efficiency value must fit in 20bit and the final | ||
| 63 | * cpu_scale value must be in the range | ||
| 64 | * 0 < cpu_scale < 3*SCHED_POWER_SCALE/2 | ||
| 65 | * in order to return at most 1 when DIV_ROUND_CLOSEST | ||
| 66 | * is used to compute the capacity of a CPU. | ||
| 67 | * Processors that are not defined in the table, | ||
| 68 | * use the default SCHED_POWER_SCALE value for cpu_scale. | ||
| 69 | */ | ||
| 70 | struct cpu_efficiency table_efficiency[] = { | ||
| 71 | {"arm,cortex-a15", 3891}, | ||
| 72 | {"arm,cortex-a7", 2048}, | ||
| 73 | {NULL, }, | ||
| 74 | }; | ||
| 75 | |||
| 76 | struct cpu_capacity { | ||
| 77 | unsigned long hwid; | ||
| 78 | unsigned long capacity; | ||
| 79 | }; | ||
| 80 | |||
| 81 | struct cpu_capacity *cpu_capacity; | ||
| 82 | |||
| 83 | unsigned long middle_capacity = 1; | ||
| 84 | |||
| 85 | /* | ||
| 86 | * Iterate all CPUs' descriptor in DT and compute the efficiency | ||
| 87 | * (as per table_efficiency). Also calculate a middle efficiency | ||
| 88 | * as close as possible to (max{eff_i} - min{eff_i}) / 2 | ||
| 89 | * This is later used to scale the cpu_power field such that an | ||
| 90 | * 'average' CPU is of middle power. Also see the comments near | ||
| 91 | * table_efficiency[] and update_cpu_power(). | ||
| 92 | */ | ||
| 93 | static void __init parse_dt_topology(void) | ||
| 94 | { | ||
| 95 | struct cpu_efficiency *cpu_eff; | ||
| 96 | struct device_node *cn = NULL; | ||
| 97 | unsigned long min_capacity = (unsigned long)(-1); | ||
| 98 | unsigned long max_capacity = 0; | ||
| 99 | unsigned long capacity = 0; | ||
| 100 | int alloc_size, cpu = 0; | ||
| 101 | |||
| 102 | alloc_size = nr_cpu_ids * sizeof(struct cpu_capacity); | ||
| 103 | cpu_capacity = (struct cpu_capacity *)kzalloc(alloc_size, GFP_NOWAIT); | ||
| 104 | |||
| 105 | while ((cn = of_find_node_by_type(cn, "cpu"))) { | ||
| 106 | const u32 *rate, *reg; | ||
| 107 | int len; | ||
| 108 | |||
| 109 | if (cpu >= num_possible_cpus()) | ||
| 110 | break; | ||
| 111 | |||
| 112 | for (cpu_eff = table_efficiency; cpu_eff->compatible; cpu_eff++) | ||
| 113 | if (of_device_is_compatible(cn, cpu_eff->compatible)) | ||
| 114 | break; | ||
| 115 | |||
| 116 | if (cpu_eff->compatible == NULL) | ||
| 117 | continue; | ||
| 118 | |||
| 119 | rate = of_get_property(cn, "clock-frequency", &len); | ||
| 120 | if (!rate || len != 4) { | ||
| 121 | pr_err("%s missing clock-frequency property\n", | ||
| 122 | cn->full_name); | ||
| 123 | continue; | ||
| 124 | } | ||
| 125 | |||
| 126 | reg = of_get_property(cn, "reg", &len); | ||
| 127 | if (!reg || len != 4) { | ||
| 128 | pr_err("%s missing reg property\n", cn->full_name); | ||
| 129 | continue; | ||
| 130 | } | ||
| 131 | |||
| 132 | capacity = ((be32_to_cpup(rate)) >> 20) * cpu_eff->efficiency; | ||
| 133 | |||
| 134 | /* Save min capacity of the system */ | ||
| 135 | if (capacity < min_capacity) | ||
| 136 | min_capacity = capacity; | ||
| 137 | |||
| 138 | /* Save max capacity of the system */ | ||
| 139 | if (capacity > max_capacity) | ||
| 140 | max_capacity = capacity; | ||
| 141 | |||
| 142 | cpu_capacity[cpu].capacity = capacity; | ||
| 143 | cpu_capacity[cpu++].hwid = be32_to_cpup(reg); | ||
| 144 | } | ||
| 145 | |||
| 146 | if (cpu < num_possible_cpus()) | ||
| 147 | cpu_capacity[cpu].hwid = (unsigned long)(-1); | ||
| 148 | |||
| 149 | /* If min and max capacities are equals, we bypass the update of the | ||
| 150 | * cpu_scale because all CPUs have the same capacity. Otherwise, we | ||
| 151 | * compute a middle_capacity factor that will ensure that the capacity | ||
| 152 | * of an 'average' CPU of the system will be as close as possible to | ||
| 153 | * SCHED_POWER_SCALE, which is the default value, but with the | ||
| 154 | * constraint explained near table_efficiency[]. | ||
| 155 | */ | ||
| 156 | if (min_capacity == max_capacity) | ||
| 157 | cpu_capacity[0].hwid = (unsigned long)(-1); | ||
| 158 | else if (4*max_capacity < (3*(max_capacity + min_capacity))) | ||
| 159 | middle_capacity = (min_capacity + max_capacity) | ||
| 160 | >> (SCHED_POWER_SHIFT+1); | ||
| 161 | else | ||
| 162 | middle_capacity = ((max_capacity / 3) | ||
| 163 | >> (SCHED_POWER_SHIFT-1)) + 1; | ||
| 164 | |||
| 165 | } | ||
| 166 | |||
| 167 | /* | ||
| 168 | * Look for a customed capacity of a CPU in the cpu_capacity table during the | ||
| 169 | * boot. The update of all CPUs is in O(n^2) for heteregeneous system but the | ||
| 170 | * function returns directly for SMP system. | ||
| 171 | */ | ||
| 172 | void update_cpu_power(unsigned int cpu, unsigned long hwid) | ||
| 173 | { | ||
| 174 | unsigned int idx = 0; | ||
| 175 | |||
| 176 | /* look for the cpu's hwid in the cpu capacity table */ | ||
| 177 | for (idx = 0; idx < num_possible_cpus(); idx++) { | ||
| 178 | if (cpu_capacity[idx].hwid == hwid) | ||
| 179 | break; | ||
| 180 | |||
| 181 | if (cpu_capacity[idx].hwid == -1) | ||
| 182 | return; | ||
| 183 | } | ||
| 184 | |||
| 185 | if (idx == num_possible_cpus()) | ||
| 186 | return; | ||
| 187 | |||
| 188 | set_power_scale(cpu, cpu_capacity[idx].capacity / middle_capacity); | ||
| 189 | |||
| 190 | printk(KERN_INFO "CPU%u: update cpu_power %lu\n", | ||
| 191 | cpu, arch_scale_freq_power(NULL, cpu)); | ||
| 192 | } | ||
| 193 | |||
| 194 | #else | ||
| 195 | static inline void parse_dt_topology(void) {} | ||
| 196 | static inline void update_cpu_power(unsigned int cpuid, unsigned int mpidr) {} | ||
| 197 | #endif | ||
| 198 | |||
| 199 | |||
| 200 | /* | ||
| 201 | * cpu topology management | ||
| 202 | */ | ||
| 203 | |||
| 25 | #define MPIDR_SMP_BITMASK (0x3 << 30) | 204 | #define MPIDR_SMP_BITMASK (0x3 << 30) |
| 26 | #define MPIDR_SMP_VALUE (0x2 << 30) | 205 | #define MPIDR_SMP_VALUE (0x2 << 30) |
| 27 | 206 | ||
| @@ -31,6 +210,7 @@ | |||
| 31 | * These masks reflect the current use of the affinity levels. | 210 | * These masks reflect the current use of the affinity levels. |
| 32 | * The affinity level can be up to 16 bits according to ARM ARM | 211 | * The affinity level can be up to 16 bits according to ARM ARM |
| 33 | */ | 212 | */ |
| 213 | #define MPIDR_HWID_BITMASK 0xFFFFFF | ||
| 34 | 214 | ||
| 35 | #define MPIDR_LEVEL0_MASK 0x3 | 215 | #define MPIDR_LEVEL0_MASK 0x3 |
| 36 | #define MPIDR_LEVEL0_SHIFT 0 | 216 | #define MPIDR_LEVEL0_SHIFT 0 |
| @@ -41,6 +221,9 @@ | |||
| 41 | #define MPIDR_LEVEL2_MASK 0xFF | 221 | #define MPIDR_LEVEL2_MASK 0xFF |
| 42 | #define MPIDR_LEVEL2_SHIFT 16 | 222 | #define MPIDR_LEVEL2_SHIFT 16 |
| 43 | 223 | ||
| 224 | /* | ||
| 225 | * cpu topology table | ||
| 226 | */ | ||
| 44 | struct cputopo_arm cpu_topology[NR_CPUS]; | 227 | struct cputopo_arm cpu_topology[NR_CPUS]; |
| 45 | 228 | ||
| 46 | const struct cpumask *cpu_coregroup_mask(int cpu) | 229 | const struct cpumask *cpu_coregroup_mask(int cpu) |
| @@ -48,6 +231,32 @@ const struct cpumask *cpu_coregroup_mask(int cpu) | |||
| 48 | return &cpu_topology[cpu].core_sibling; | 231 | return &cpu_topology[cpu].core_sibling; |
| 49 | } | 232 | } |
| 50 | 233 | ||
| 234 | void update_siblings_masks(unsigned int cpuid) | ||
| 235 | { | ||
| 236 | struct cputopo_arm *cpu_topo, *cpuid_topo = &cpu_topology[cpuid]; | ||
| 237 | int cpu; | ||
| 238 | |||
| 239 | /* update core and thread sibling masks */ | ||
| 240 | for_each_possible_cpu(cpu) { | ||
| 241 | cpu_topo = &cpu_topology[cpu]; | ||
| 242 | |||
| 243 | if (cpuid_topo->socket_id != cpu_topo->socket_id) | ||
| 244 | continue; | ||
| 245 | |||
| 246 | cpumask_set_cpu(cpuid, &cpu_topo->core_sibling); | ||
| 247 | if (cpu != cpuid) | ||
| 248 | cpumask_set_cpu(cpu, &cpuid_topo->core_sibling); | ||
| 249 | |||
| 250 | if (cpuid_topo->core_id != cpu_topo->core_id) | ||
| 251 | continue; | ||
| 252 | |||
| 253 | cpumask_set_cpu(cpuid, &cpu_topo->thread_sibling); | ||
| 254 | if (cpu != cpuid) | ||
| 255 | cpumask_set_cpu(cpu, &cpuid_topo->thread_sibling); | ||
| 256 | } | ||
| 257 | smp_wmb(); | ||
| 258 | } | ||
| 259 | |||
| 51 | /* | 260 | /* |
| 52 | * store_cpu_topology is called at boot when only one cpu is running | 261 | * store_cpu_topology is called at boot when only one cpu is running |
| 53 | * and with the mutex cpu_hotplug.lock locked, when several cpus have booted, | 262 | * and with the mutex cpu_hotplug.lock locked, when several cpus have booted, |
| @@ -57,7 +266,6 @@ void store_cpu_topology(unsigned int cpuid) | |||
| 57 | { | 266 | { |
| 58 | struct cputopo_arm *cpuid_topo = &cpu_topology[cpuid]; | 267 | struct cputopo_arm *cpuid_topo = &cpu_topology[cpuid]; |
| 59 | unsigned int mpidr; | 268 | unsigned int mpidr; |
| 60 | unsigned int cpu; | ||
| 61 | 269 | ||
| 62 | /* If the cpu topology has been already set, just return */ | 270 | /* If the cpu topology has been already set, just return */ |
| 63 | if (cpuid_topo->core_id != -1) | 271 | if (cpuid_topo->core_id != -1) |
| @@ -99,26 +307,9 @@ void store_cpu_topology(unsigned int cpuid) | |||
| 99 | cpuid_topo->socket_id = -1; | 307 | cpuid_topo->socket_id = -1; |
| 100 | } | 308 | } |
| 101 | 309 | ||
| 102 | /* update core and thread sibling masks */ | 310 | update_siblings_masks(cpuid); |
| 103 | for_each_possible_cpu(cpu) { | 311 | |
| 104 | struct cputopo_arm *cpu_topo = &cpu_topology[cpu]; | 312 | update_cpu_power(cpuid, mpidr & MPIDR_HWID_BITMASK); |
| 105 | |||
| 106 | if (cpuid_topo->socket_id == cpu_topo->socket_id) { | ||
| 107 | cpumask_set_cpu(cpuid, &cpu_topo->core_sibling); | ||
| 108 | if (cpu != cpuid) | ||
| 109 | cpumask_set_cpu(cpu, | ||
| 110 | &cpuid_topo->core_sibling); | ||
| 111 | |||
| 112 | if (cpuid_topo->core_id == cpu_topo->core_id) { | ||
| 113 | cpumask_set_cpu(cpuid, | ||
| 114 | &cpu_topo->thread_sibling); | ||
| 115 | if (cpu != cpuid) | ||
| 116 | cpumask_set_cpu(cpu, | ||
| 117 | &cpuid_topo->thread_sibling); | ||
| 118 | } | ||
| 119 | } | ||
| 120 | } | ||
| 121 | smp_wmb(); | ||
| 122 | 313 | ||
| 123 | printk(KERN_INFO "CPU%u: thread %d, cpu %d, socket %d, mpidr %x\n", | 314 | printk(KERN_INFO "CPU%u: thread %d, cpu %d, socket %d, mpidr %x\n", |
| 124 | cpuid, cpu_topology[cpuid].thread_id, | 315 | cpuid, cpu_topology[cpuid].thread_id, |
| @@ -134,7 +325,7 @@ void init_cpu_topology(void) | |||
| 134 | { | 325 | { |
| 135 | unsigned int cpu; | 326 | unsigned int cpu; |
| 136 | 327 | ||
| 137 | /* init core mask */ | 328 | /* init core mask and power*/ |
| 138 | for_each_possible_cpu(cpu) { | 329 | for_each_possible_cpu(cpu) { |
| 139 | struct cputopo_arm *cpu_topo = &(cpu_topology[cpu]); | 330 | struct cputopo_arm *cpu_topo = &(cpu_topology[cpu]); |
| 140 | 331 | ||
| @@ -143,6 +334,10 @@ void init_cpu_topology(void) | |||
| 143 | cpu_topo->socket_id = -1; | 334 | cpu_topo->socket_id = -1; |
| 144 | cpumask_clear(&cpu_topo->core_sibling); | 335 | cpumask_clear(&cpu_topo->core_sibling); |
| 145 | cpumask_clear(&cpu_topo->thread_sibling); | 336 | cpumask_clear(&cpu_topo->thread_sibling); |
| 337 | |||
| 338 | set_power_scale(cpu, SCHED_POWER_SCALE); | ||
| 146 | } | 339 | } |
| 147 | smp_wmb(); | 340 | smp_wmb(); |
| 341 | |||
| 342 | parse_dt_topology(); | ||
| 148 | } | 343 | } |
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 3647170e9a16..8b97d739b17b 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c | |||
| @@ -233,9 +233,9 @@ void show_stack(struct task_struct *tsk, unsigned long *sp) | |||
| 233 | #define S_ISA " ARM" | 233 | #define S_ISA " ARM" |
| 234 | #endif | 234 | #endif |
| 235 | 235 | ||
| 236 | static int __die(const char *str, int err, struct thread_info *thread, struct pt_regs *regs) | 236 | static int __die(const char *str, int err, struct pt_regs *regs) |
| 237 | { | 237 | { |
| 238 | struct task_struct *tsk = thread->task; | 238 | struct task_struct *tsk = current; |
| 239 | static int die_counter; | 239 | static int die_counter; |
| 240 | int ret; | 240 | int ret; |
| 241 | 241 | ||
| @@ -245,12 +245,12 @@ static int __die(const char *str, int err, struct thread_info *thread, struct pt | |||
| 245 | /* trap and error numbers are mostly meaningless on ARM */ | 245 | /* trap and error numbers are mostly meaningless on ARM */ |
| 246 | ret = notify_die(DIE_OOPS, str, regs, err, tsk->thread.trap_no, SIGSEGV); | 246 | ret = notify_die(DIE_OOPS, str, regs, err, tsk->thread.trap_no, SIGSEGV); |
| 247 | if (ret == NOTIFY_STOP) | 247 | if (ret == NOTIFY_STOP) |
| 248 | return ret; | 248 | return 1; |
| 249 | 249 | ||
| 250 | print_modules(); | 250 | print_modules(); |
| 251 | __show_regs(regs); | 251 | __show_regs(regs); |
| 252 | printk(KERN_EMERG "Process %.*s (pid: %d, stack limit = 0x%p)\n", | 252 | printk(KERN_EMERG "Process %.*s (pid: %d, stack limit = 0x%p)\n", |
| 253 | TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), thread + 1); | 253 | TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), end_of_stack(tsk)); |
| 254 | 254 | ||
| 255 | if (!user_mode(regs) || in_interrupt()) { | 255 | if (!user_mode(regs) || in_interrupt()) { |
| 256 | dump_mem(KERN_EMERG, "Stack: ", regs->ARM_sp, | 256 | dump_mem(KERN_EMERG, "Stack: ", regs->ARM_sp, |
| @@ -259,45 +259,77 @@ static int __die(const char *str, int err, struct thread_info *thread, struct pt | |||
| 259 | dump_instr(KERN_EMERG, regs); | 259 | dump_instr(KERN_EMERG, regs); |
| 260 | } | 260 | } |
| 261 | 261 | ||
| 262 | return ret; | 262 | return 0; |
| 263 | } | 263 | } |
| 264 | 264 | ||
| 265 | static DEFINE_RAW_SPINLOCK(die_lock); | 265 | static arch_spinlock_t die_lock = __ARCH_SPIN_LOCK_UNLOCKED; |
| 266 | static int die_owner = -1; | ||
| 267 | static unsigned int die_nest_count; | ||
| 266 | 268 | ||
| 267 | /* | 269 | static unsigned long oops_begin(void) |
| 268 | * This function is protected against re-entrancy. | ||
| 269 | */ | ||
| 270 | void die(const char *str, struct pt_regs *regs, int err) | ||
| 271 | { | 270 | { |
| 272 | struct thread_info *thread = current_thread_info(); | 271 | int cpu; |
| 273 | int ret; | 272 | unsigned long flags; |
| 274 | enum bug_trap_type bug_type = BUG_TRAP_TYPE_NONE; | ||
| 275 | 273 | ||
| 276 | oops_enter(); | 274 | oops_enter(); |
| 277 | 275 | ||
| 278 | raw_spin_lock_irq(&die_lock); | 276 | /* racy, but better than risking deadlock. */ |
| 277 | raw_local_irq_save(flags); | ||
| 278 | cpu = smp_processor_id(); | ||
| 279 | if (!arch_spin_trylock(&die_lock)) { | ||
| 280 | if (cpu == die_owner) | ||
| 281 | /* nested oops. should stop eventually */; | ||
| 282 | else | ||
| 283 | arch_spin_lock(&die_lock); | ||
| 284 | } | ||
| 285 | die_nest_count++; | ||
| 286 | die_owner = cpu; | ||
| 279 | console_verbose(); | 287 | console_verbose(); |
| 280 | bust_spinlocks(1); | 288 | bust_spinlocks(1); |
| 281 | if (!user_mode(regs)) | 289 | return flags; |
| 282 | bug_type = report_bug(regs->ARM_pc, regs); | 290 | } |
| 283 | if (bug_type != BUG_TRAP_TYPE_NONE) | ||
| 284 | str = "Oops - BUG"; | ||
| 285 | ret = __die(str, err, thread, regs); | ||
| 286 | 291 | ||
| 287 | if (regs && kexec_should_crash(thread->task)) | 292 | static void oops_end(unsigned long flags, struct pt_regs *regs, int signr) |
| 293 | { | ||
| 294 | if (regs && kexec_should_crash(current)) | ||
| 288 | crash_kexec(regs); | 295 | crash_kexec(regs); |
| 289 | 296 | ||
| 290 | bust_spinlocks(0); | 297 | bust_spinlocks(0); |
| 298 | die_owner = -1; | ||
| 291 | add_taint(TAINT_DIE); | 299 | add_taint(TAINT_DIE); |
| 292 | raw_spin_unlock_irq(&die_lock); | 300 | die_nest_count--; |
| 301 | if (!die_nest_count) | ||
| 302 | /* Nest count reaches zero, release the lock. */ | ||
| 303 | arch_spin_unlock(&die_lock); | ||
| 304 | raw_local_irq_restore(flags); | ||
| 293 | oops_exit(); | 305 | oops_exit(); |
| 294 | 306 | ||
| 295 | if (in_interrupt()) | 307 | if (in_interrupt()) |
| 296 | panic("Fatal exception in interrupt"); | 308 | panic("Fatal exception in interrupt"); |
| 297 | if (panic_on_oops) | 309 | if (panic_on_oops) |
| 298 | panic("Fatal exception"); | 310 | panic("Fatal exception"); |
| 299 | if (ret != NOTIFY_STOP) | 311 | if (signr) |
| 300 | do_exit(SIGSEGV); | 312 | do_exit(signr); |
| 313 | } | ||
| 314 | |||
| 315 | /* | ||
| 316 | * This function is protected against re-entrancy. | ||
| 317 | */ | ||
| 318 | void die(const char *str, struct pt_regs *regs, int err) | ||
| 319 | { | ||
| 320 | enum bug_trap_type bug_type = BUG_TRAP_TYPE_NONE; | ||
| 321 | unsigned long flags = oops_begin(); | ||
| 322 | int sig = SIGSEGV; | ||
| 323 | |||
| 324 | if (!user_mode(regs)) | ||
| 325 | bug_type = report_bug(regs->ARM_pc, regs); | ||
| 326 | if (bug_type != BUG_TRAP_TYPE_NONE) | ||
| 327 | str = "Oops - BUG"; | ||
| 328 | |||
| 329 | if (__die(str, err, regs)) | ||
| 330 | sig = 0; | ||
| 331 | |||
| 332 | oops_end(flags, regs, sig); | ||
| 301 | } | 333 | } |
| 302 | 334 | ||
| 303 | void arm_notify_die(const char *str, struct pt_regs *regs, | 335 | void arm_notify_die(const char *str, struct pt_regs *regs, |
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index 992769ae2599..2473fd1fd51c 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile | |||
| @@ -6,9 +6,8 @@ | |||
| 6 | 6 | ||
| 7 | lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \ | 7 | lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \ |
| 8 | csumpartialcopy.o csumpartialcopyuser.o clearbit.o \ | 8 | csumpartialcopy.o csumpartialcopyuser.o clearbit.o \ |
| 9 | delay.o findbit.o memchr.o memcpy.o \ | 9 | delay.o delay-loop.o findbit.o memchr.o memcpy.o \ |
| 10 | memmove.o memset.o memzero.o setbit.o \ | 10 | memmove.o memset.o memzero.o setbit.o \ |
| 11 | strncpy_from_user.o strnlen_user.o \ | ||
| 12 | strchr.o strrchr.o \ | 11 | strchr.o strrchr.o \ |
| 13 | testchangebit.o testclearbit.o testsetbit.o \ | 12 | testchangebit.o testclearbit.o testsetbit.o \ |
| 14 | ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ | 13 | ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ |
diff --git a/arch/arm/lib/delay.S b/arch/arm/lib/delay-loop.S index 3c9a05c8d20b..36b668d8e121 100644 --- a/arch/arm/lib/delay.S +++ b/arch/arm/lib/delay-loop.S | |||
| @@ -9,11 +9,11 @@ | |||
| 9 | */ | 9 | */ |
| 10 | #include <linux/linkage.h> | 10 | #include <linux/linkage.h> |
| 11 | #include <asm/assembler.h> | 11 | #include <asm/assembler.h> |
| 12 | #include <asm/param.h> | 12 | #include <asm/delay.h> |
| 13 | .text | 13 | .text |
| 14 | 14 | ||
| 15 | .LC0: .word loops_per_jiffy | 15 | .LC0: .word loops_per_jiffy |
| 16 | .LC1: .word (2199023*HZ)>>11 | 16 | .LC1: .word UDELAY_MULT |
| 17 | 17 | ||
| 18 | /* | 18 | /* |
| 19 | * r0 <= 2000 | 19 | * r0 <= 2000 |
| @@ -21,10 +21,10 @@ | |||
| 21 | * HZ <= 1000 | 21 | * HZ <= 1000 |
| 22 | */ | 22 | */ |
| 23 | 23 | ||
| 24 | ENTRY(__udelay) | 24 | ENTRY(__loop_udelay) |
| 25 | ldr r2, .LC1 | 25 | ldr r2, .LC1 |
| 26 | mul r0, r2, r0 | 26 | mul r0, r2, r0 |
| 27 | ENTRY(__const_udelay) @ 0 <= r0 <= 0x7fffff06 | 27 | ENTRY(__loop_const_udelay) @ 0 <= r0 <= 0x7fffff06 |
| 28 | mov r1, #-1 | 28 | mov r1, #-1 |
| 29 | ldr r2, .LC0 | 29 | ldr r2, .LC0 |
| 30 | ldr r2, [r2] @ max = 0x01ffffff | 30 | ldr r2, [r2] @ max = 0x01ffffff |
| @@ -39,12 +39,10 @@ ENTRY(__const_udelay) @ 0 <= r0 <= 0x7fffff06 | |||
| 39 | 39 | ||
| 40 | /* | 40 | /* |
| 41 | * loops = r0 * HZ * loops_per_jiffy / 1000000 | 41 | * loops = r0 * HZ * loops_per_jiffy / 1000000 |
| 42 | * | ||
| 43 | * Oh, if only we had a cycle counter... | ||
| 44 | */ | 42 | */ |
| 45 | 43 | ||
| 46 | @ Delay routine | 44 | @ Delay routine |
| 47 | ENTRY(__delay) | 45 | ENTRY(__loop_delay) |
| 48 | subs r0, r0, #1 | 46 | subs r0, r0, #1 |
| 49 | #if 0 | 47 | #if 0 |
| 50 | movls pc, lr | 48 | movls pc, lr |
| @@ -62,8 +60,8 @@ ENTRY(__delay) | |||
| 62 | movls pc, lr | 60 | movls pc, lr |
| 63 | subs r0, r0, #1 | 61 | subs r0, r0, #1 |
| 64 | #endif | 62 | #endif |
| 65 | bhi __delay | 63 | bhi __loop_delay |
| 66 | mov pc, lr | 64 | mov pc, lr |
| 67 | ENDPROC(__udelay) | 65 | ENDPROC(__loop_udelay) |
| 68 | ENDPROC(__const_udelay) | 66 | ENDPROC(__loop_const_udelay) |
| 69 | ENDPROC(__delay) | 67 | ENDPROC(__loop_delay) |
diff --git a/arch/arm/lib/delay.c b/arch/arm/lib/delay.c new file mode 100644 index 000000000000..d6dacc69254e --- /dev/null +++ b/arch/arm/lib/delay.c | |||
| @@ -0,0 +1,71 @@ | |||
| 1 | /* | ||
| 2 | * Delay loops based on the OpenRISC implementation. | ||
| 3 | * | ||
| 4 | * Copyright (C) 2012 ARM Limited | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License version 2 as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 18 | * | ||
| 19 | * Author: Will Deacon <will.deacon@arm.com> | ||
| 20 | */ | ||
| 21 | |||
| 22 | #include <linux/delay.h> | ||
| 23 | #include <linux/init.h> | ||
| 24 | #include <linux/kernel.h> | ||
| 25 | #include <linux/module.h> | ||
| 26 | #include <linux/timex.h> | ||
| 27 | |||
| 28 | /* | ||
| 29 | * Default to the loop-based delay implementation. | ||
| 30 | */ | ||
| 31 | struct arm_delay_ops arm_delay_ops = { | ||
| 32 | .delay = __loop_delay, | ||
| 33 | .const_udelay = __loop_const_udelay, | ||
| 34 | .udelay = __loop_udelay, | ||
| 35 | }; | ||
| 36 | |||
| 37 | #ifdef ARCH_HAS_READ_CURRENT_TIMER | ||
| 38 | static void __timer_delay(unsigned long cycles) | ||
| 39 | { | ||
| 40 | cycles_t start = get_cycles(); | ||
| 41 | |||
| 42 | while ((get_cycles() - start) < cycles) | ||
| 43 | cpu_relax(); | ||
| 44 | } | ||
| 45 | |||
| 46 | static void __timer_const_udelay(unsigned long xloops) | ||
| 47 | { | ||
| 48 | unsigned long long loops = xloops; | ||
| 49 | loops *= loops_per_jiffy; | ||
| 50 | __timer_delay(loops >> UDELAY_SHIFT); | ||
| 51 | } | ||
| 52 | |||
| 53 | static void __timer_udelay(unsigned long usecs) | ||
| 54 | { | ||
| 55 | __timer_const_udelay(usecs * UDELAY_MULT); | ||
| 56 | } | ||
| 57 | |||
| 58 | void __init init_current_timer_delay(unsigned long freq) | ||
| 59 | { | ||
| 60 | pr_info("Switching to timer-based delay loop\n"); | ||
| 61 | lpj_fine = freq / HZ; | ||
| 62 | arm_delay_ops.delay = __timer_delay; | ||
| 63 | arm_delay_ops.const_udelay = __timer_const_udelay; | ||
| 64 | arm_delay_ops.udelay = __timer_udelay; | ||
| 65 | } | ||
| 66 | |||
| 67 | unsigned long __cpuinit calibrate_delay_is_known(void) | ||
| 68 | { | ||
| 69 | return lpj_fine; | ||
| 70 | } | ||
| 71 | #endif | ||
diff --git a/arch/arm/lib/io-acorn.S b/arch/arm/lib/io-acorn.S index 1b197ea7aab3..69719bad674d 100644 --- a/arch/arm/lib/io-acorn.S +++ b/arch/arm/lib/io-acorn.S | |||
| @@ -11,13 +11,14 @@ | |||
| 11 | * | 11 | * |
| 12 | */ | 12 | */ |
| 13 | #include <linux/linkage.h> | 13 | #include <linux/linkage.h> |
| 14 | #include <linux/kern_levels.h> | ||
| 14 | #include <asm/assembler.h> | 15 | #include <asm/assembler.h> |
| 15 | 16 | ||
| 16 | .text | 17 | .text |
| 17 | .align | 18 | .align |
| 18 | 19 | ||
| 19 | .Liosl_warning: | 20 | .Liosl_warning: |
| 20 | .ascii "<4>insl/outsl not implemented, called from %08lX\0" | 21 | .ascii KERN_WARNING "insl/outsl not implemented, called from %08lX\0" |
| 21 | .align | 22 | .align |
| 22 | 23 | ||
| 23 | /* | 24 | /* |
diff --git a/arch/arm/lib/strncpy_from_user.S b/arch/arm/lib/strncpy_from_user.S deleted file mode 100644 index f202d7bd1647..000000000000 --- a/arch/arm/lib/strncpy_from_user.S +++ /dev/null | |||
| @@ -1,43 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/arm/lib/strncpy_from_user.S | ||
| 3 | * | ||
| 4 | * Copyright (C) 1995-2000 Russell King | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License version 2 as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | */ | ||
| 10 | #include <linux/linkage.h> | ||
| 11 | #include <asm/assembler.h> | ||
| 12 | #include <asm/errno.h> | ||
| 13 | |||
| 14 | .text | ||
| 15 | .align 5 | ||
| 16 | |||
| 17 | /* | ||
| 18 | * Copy a string from user space to kernel space. | ||
| 19 | * r0 = dst, r1 = src, r2 = byte length | ||
| 20 | * returns the number of characters copied (strlen of copied string), | ||
| 21 | * -EFAULT on exception, or "len" if we fill the whole buffer | ||
| 22 | */ | ||
| 23 | ENTRY(__strncpy_from_user) | ||
| 24 | mov ip, r1 | ||
| 25 | 1: subs r2, r2, #1 | ||
| 26 | ldrusr r3, r1, 1, pl | ||
| 27 | bmi 2f | ||
| 28 | strb r3, [r0], #1 | ||
| 29 | teq r3, #0 | ||
| 30 | bne 1b | ||
| 31 | sub r1, r1, #1 @ take NUL character out of count | ||
| 32 | 2: sub r0, r1, ip | ||
| 33 | mov pc, lr | ||
| 34 | ENDPROC(__strncpy_from_user) | ||
| 35 | |||
| 36 | .pushsection .fixup,"ax" | ||
| 37 | .align 0 | ||
| 38 | 9001: mov r3, #0 | ||
| 39 | strb r3, [r0, #0] @ null terminate | ||
| 40 | mov r0, #-EFAULT | ||
| 41 | mov pc, lr | ||
| 42 | .popsection | ||
| 43 | |||
diff --git a/arch/arm/lib/strnlen_user.S b/arch/arm/lib/strnlen_user.S deleted file mode 100644 index 0ecbb459c4f1..000000000000 --- a/arch/arm/lib/strnlen_user.S +++ /dev/null | |||
| @@ -1,40 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/arm/lib/strnlen_user.S | ||
| 3 | * | ||
| 4 | * Copyright (C) 1995-2000 Russell King | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License version 2 as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | */ | ||
| 10 | #include <linux/linkage.h> | ||
| 11 | #include <asm/assembler.h> | ||
| 12 | #include <asm/errno.h> | ||
| 13 | |||
| 14 | .text | ||
| 15 | .align 5 | ||
| 16 | |||
| 17 | /* Prototype: unsigned long __strnlen_user(const char *str, long n) | ||
| 18 | * Purpose : get length of a string in user memory | ||
| 19 | * Params : str - address of string in user memory | ||
| 20 | * Returns : length of string *including terminator* | ||
| 21 | * or zero on exception, or n + 1 if too long | ||
| 22 | */ | ||
| 23 | ENTRY(__strnlen_user) | ||
| 24 | mov r2, r0 | ||
| 25 | 1: | ||
| 26 | ldrusr r3, r0, 1 | ||
| 27 | teq r3, #0 | ||
| 28 | beq 2f | ||
| 29 | subs r1, r1, #1 | ||
| 30 | bne 1b | ||
| 31 | add r0, r0, #1 | ||
| 32 | 2: sub r0, r0, r2 | ||
| 33 | mov pc, lr | ||
| 34 | ENDPROC(__strnlen_user) | ||
| 35 | |||
| 36 | .pushsection .fixup,"ax" | ||
| 37 | .align 0 | ||
| 38 | 9001: mov r0, #0 | ||
| 39 | mov pc, lr | ||
| 40 | .popsection | ||
diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index 977127368a7d..ef6cedd52e3c 100644 --- a/arch/arm/mach-at91/at91sam9g45.c +++ b/arch/arm/mach-at91/at91sam9g45.c | |||
| @@ -183,6 +183,13 @@ static struct clk adc_op_clk = { | |||
| 183 | .rate_hz = 13200000, | 183 | .rate_hz = 13200000, |
| 184 | }; | 184 | }; |
| 185 | 185 | ||
| 186 | /* AES/TDES/SHA clock - Only for sam9m11/sam9g56 */ | ||
| 187 | static struct clk aestdessha_clk = { | ||
| 188 | .name = "aestdessha_clk", | ||
| 189 | .pmc_mask = 1 << AT91SAM9G45_ID_AESTDESSHA, | ||
| 190 | .type = CLK_TYPE_PERIPHERAL, | ||
| 191 | }; | ||
| 192 | |||
| 186 | static struct clk *periph_clocks[] __initdata = { | 193 | static struct clk *periph_clocks[] __initdata = { |
| 187 | &pioA_clk, | 194 | &pioA_clk, |
| 188 | &pioB_clk, | 195 | &pioB_clk, |
| @@ -212,6 +219,7 @@ static struct clk *periph_clocks[] __initdata = { | |||
| 212 | &udphs_clk, | 219 | &udphs_clk, |
| 213 | &mmc1_clk, | 220 | &mmc1_clk, |
| 214 | &adc_op_clk, | 221 | &adc_op_clk, |
| 222 | &aestdessha_clk, | ||
| 215 | // irq0 | 223 | // irq0 |
| 216 | }; | 224 | }; |
| 217 | 225 | ||
| @@ -232,6 +240,9 @@ static struct clk_lookup periph_clocks_lookups[] = { | |||
| 232 | CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), | 240 | CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), |
| 233 | CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), | 241 | CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), |
| 234 | CLKDEV_CON_DEV_ID(NULL, "atmel-trng", &trng_clk), | 242 | CLKDEV_CON_DEV_ID(NULL, "atmel-trng", &trng_clk), |
| 243 | CLKDEV_CON_DEV_ID(NULL, "atmel_sha", &aestdessha_clk), | ||
| 244 | CLKDEV_CON_DEV_ID(NULL, "atmel_tdes", &aestdessha_clk), | ||
| 245 | CLKDEV_CON_DEV_ID(NULL, "atmel_aes", &aestdessha_clk), | ||
| 235 | /* more usart lookup table for DT entries */ | 246 | /* more usart lookup table for DT entries */ |
| 236 | CLKDEV_CON_DEV_ID("usart", "ffffee00.serial", &mck), | 247 | CLKDEV_CON_DEV_ID("usart", "ffffee00.serial", &mck), |
| 237 | CLKDEV_CON_DEV_ID("usart", "fff8c000.serial", &usart0_clk), | 248 | CLKDEV_CON_DEV_ID("usart", "fff8c000.serial", &usart0_clk), |
| @@ -388,7 +399,7 @@ static unsigned int at91sam9g45_default_irq_priority[NR_AIC_IRQS] __initdata = { | |||
| 388 | 3, /* Ethernet */ | 399 | 3, /* Ethernet */ |
| 389 | 0, /* Image Sensor Interface */ | 400 | 0, /* Image Sensor Interface */ |
| 390 | 2, /* USB Device High speed port */ | 401 | 2, /* USB Device High speed port */ |
| 391 | 0, | 402 | 0, /* AESTDESSHA Crypto HW Accelerators */ |
| 392 | 0, /* Multimedia Card Interface 1 */ | 403 | 0, /* Multimedia Card Interface 1 */ |
| 393 | 0, | 404 | 0, |
| 394 | 0, /* Advanced Interrupt Controller (IRQ0) */ | 405 | 0, /* Advanced Interrupt Controller (IRQ0) */ |
diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index 40fb79df2de0..06073996a382 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
| 19 | #include <linux/i2c-gpio.h> | 19 | #include <linux/i2c-gpio.h> |
| 20 | #include <linux/atmel-mci.h> | 20 | #include <linux/atmel-mci.h> |
| 21 | #include <linux/platform_data/atmel-aes.h> | ||
| 21 | 22 | ||
| 22 | #include <linux/platform_data/at91_adc.h> | 23 | #include <linux/platform_data/at91_adc.h> |
| 23 | 24 | ||
| @@ -1830,6 +1831,130 @@ void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {} | |||
| 1830 | void __init at91_add_device_serial(void) {} | 1831 | void __init at91_add_device_serial(void) {} |
| 1831 | #endif | 1832 | #endif |
| 1832 | 1833 | ||
| 1834 | /* -------------------------------------------------------------------- | ||
| 1835 | * SHA1/SHA256 | ||
| 1836 | * -------------------------------------------------------------------- */ | ||
| 1837 | |||
| 1838 | #if defined(CONFIG_CRYPTO_DEV_ATMEL_SHA) || defined(CONFIG_CRYPTO_DEV_ATMEL_SHA_MODULE) | ||
| 1839 | static struct resource sha_resources[] = { | ||
| 1840 | { | ||
| 1841 | .start = AT91SAM9G45_BASE_SHA, | ||
| 1842 | .end = AT91SAM9G45_BASE_SHA + SZ_16K - 1, | ||
| 1843 | .flags = IORESOURCE_MEM, | ||
| 1844 | }, | ||
| 1845 | [1] = { | ||
| 1846 | .start = AT91SAM9G45_ID_AESTDESSHA, | ||
| 1847 | .end = AT91SAM9G45_ID_AESTDESSHA, | ||
| 1848 | .flags = IORESOURCE_IRQ, | ||
| 1849 | }, | ||
| 1850 | }; | ||
| 1851 | |||
| 1852 | static struct platform_device at91sam9g45_sha_device = { | ||
| 1853 | .name = "atmel_sha", | ||
| 1854 | .id = -1, | ||
| 1855 | .resource = sha_resources, | ||
| 1856 | .num_resources = ARRAY_SIZE(sha_resources), | ||
| 1857 | }; | ||
| 1858 | |||
| 1859 | static void __init at91_add_device_sha(void) | ||
| 1860 | { | ||
| 1861 | platform_device_register(&at91sam9g45_sha_device); | ||
| 1862 | } | ||
| 1863 | #else | ||
| 1864 | static void __init at91_add_device_sha(void) {} | ||
| 1865 | #endif | ||
| 1866 | |||
| 1867 | /* -------------------------------------------------------------------- | ||
| 1868 | * DES/TDES | ||
| 1869 | * -------------------------------------------------------------------- */ | ||
| 1870 | |||
| 1871 | #if defined(CONFIG_CRYPTO_DEV_ATMEL_TDES) || defined(CONFIG_CRYPTO_DEV_ATMEL_TDES_MODULE) | ||
| 1872 | static struct resource tdes_resources[] = { | ||
| 1873 | [0] = { | ||
| 1874 | .start = AT91SAM9G45_BASE_TDES, | ||
| 1875 | .end = AT91SAM9G45_BASE_TDES + SZ_16K - 1, | ||
| 1876 | .flags = IORESOURCE_MEM, | ||
| 1877 | }, | ||
| 1878 | [1] = { | ||
| 1879 | .start = AT91SAM9G45_ID_AESTDESSHA, | ||
| 1880 | .end = AT91SAM9G45_ID_AESTDESSHA, | ||
| 1881 | .flags = IORESOURCE_IRQ, | ||
| 1882 | }, | ||
| 1883 | }; | ||
| 1884 | |||
| 1885 | static struct platform_device at91sam9g45_tdes_device = { | ||
| 1886 | .name = "atmel_tdes", | ||
| 1887 | .id = -1, | ||
| 1888 | .resource = tdes_resources, | ||
| 1889 | .num_resources = ARRAY_SIZE(tdes_resources), | ||
| 1890 | }; | ||
| 1891 | |||
| 1892 | static void __init at91_add_device_tdes(void) | ||
| 1893 | { | ||
| 1894 | platform_device_register(&at91sam9g45_tdes_device); | ||
| 1895 | } | ||
| 1896 | #else | ||
| 1897 | static void __init at91_add_device_tdes(void) {} | ||
| 1898 | #endif | ||
| 1899 | |||
| 1900 | /* -------------------------------------------------------------------- | ||
| 1901 | * AES | ||
| 1902 | * -------------------------------------------------------------------- */ | ||
| 1903 | |||
| 1904 | #if defined(CONFIG_CRYPTO_DEV_ATMEL_AES) || defined(CONFIG_CRYPTO_DEV_ATMEL_AES_MODULE) | ||
| 1905 | static struct aes_platform_data aes_data; | ||
| 1906 | static u64 aes_dmamask = DMA_BIT_MASK(32); | ||
| 1907 | |||
| 1908 | static struct resource aes_resources[] = { | ||
| 1909 | [0] = { | ||
| 1910 | .start = AT91SAM9G45_BASE_AES, | ||
| 1911 | .end = AT91SAM9G45_BASE_AES + SZ_16K - 1, | ||
| 1912 | .flags = IORESOURCE_MEM, | ||
| 1913 | }, | ||
| 1914 | [1] = { | ||
| 1915 | .start = AT91SAM9G45_ID_AESTDESSHA, | ||
| 1916 | .end = AT91SAM9G45_ID_AESTDESSHA, | ||
| 1917 | .flags = IORESOURCE_IRQ, | ||
| 1918 | }, | ||
| 1919 | }; | ||
| 1920 | |||
| 1921 | static struct platform_device at91sam9g45_aes_device = { | ||
| 1922 | .name = "atmel_aes", | ||
| 1923 | .id = -1, | ||
| 1924 | .dev = { | ||
| 1925 | .dma_mask = &aes_dmamask, | ||
| 1926 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
| 1927 | .platform_data = &aes_data, | ||
| 1928 | }, | ||
| 1929 | .resource = aes_resources, | ||
| 1930 | .num_resources = ARRAY_SIZE(aes_resources), | ||
| 1931 | }; | ||
| 1932 | |||
| 1933 | static void __init at91_add_device_aes(void) | ||
| 1934 | { | ||
| 1935 | struct at_dma_slave *atslave; | ||
| 1936 | struct aes_dma_data *alt_atslave; | ||
| 1937 | |||
| 1938 | alt_atslave = kzalloc(sizeof(struct aes_dma_data), GFP_KERNEL); | ||
| 1939 | |||
| 1940 | /* DMA TX slave channel configuration */ | ||
| 1941 | atslave = &alt_atslave->txdata; | ||
| 1942 | atslave->dma_dev = &at_hdmac_device.dev; | ||
| 1943 | atslave->cfg = ATC_FIFOCFG_ENOUGHSPACE | ATC_SRC_H2SEL_HW | | ||
| 1944 | ATC_SRC_PER(AT_DMA_ID_AES_RX); | ||
| 1945 | |||
| 1946 | /* DMA RX slave channel configuration */ | ||
| 1947 | atslave = &alt_atslave->rxdata; | ||
| 1948 | atslave->dma_dev = &at_hdmac_device.dev; | ||
| 1949 | atslave->cfg = ATC_FIFOCFG_ENOUGHSPACE | ATC_DST_H2SEL_HW | | ||
| 1950 | ATC_DST_PER(AT_DMA_ID_AES_TX); | ||
| 1951 | |||
| 1952 | aes_data.dma_slave = alt_atslave; | ||
| 1953 | platform_device_register(&at91sam9g45_aes_device); | ||
| 1954 | } | ||
| 1955 | #else | ||
| 1956 | static void __init at91_add_device_aes(void) {} | ||
| 1957 | #endif | ||
| 1833 | 1958 | ||
| 1834 | /* -------------------------------------------------------------------- */ | 1959 | /* -------------------------------------------------------------------- */ |
| 1835 | /* | 1960 | /* |
| @@ -1847,6 +1972,9 @@ static int __init at91_add_standard_devices(void) | |||
| 1847 | at91_add_device_trng(); | 1972 | at91_add_device_trng(); |
| 1848 | at91_add_device_watchdog(); | 1973 | at91_add_device_watchdog(); |
| 1849 | at91_add_device_tc(); | 1974 | at91_add_device_tc(); |
| 1975 | at91_add_device_sha(); | ||
| 1976 | at91_add_device_tdes(); | ||
| 1977 | at91_add_device_aes(); | ||
| 1850 | return 0; | 1978 | return 0; |
| 1851 | } | 1979 | } |
| 1852 | 1980 | ||
diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45.h b/arch/arm/mach-at91/include/mach/at91sam9g45.h index 3a4da24d5911..8eba1021f533 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9g45.h +++ b/arch/arm/mach-at91/include/mach/at91sam9g45.h | |||
| @@ -136,6 +136,8 @@ | |||
| 136 | #define AT_DMA_ID_SSC1_RX 8 | 136 | #define AT_DMA_ID_SSC1_RX 8 |
| 137 | #define AT_DMA_ID_AC97_TX 9 | 137 | #define AT_DMA_ID_AC97_TX 9 |
| 138 | #define AT_DMA_ID_AC97_RX 10 | 138 | #define AT_DMA_ID_AC97_RX 10 |
| 139 | #define AT_DMA_ID_AES_TX 11 | ||
| 140 | #define AT_DMA_ID_AES_RX 12 | ||
| 139 | #define AT_DMA_ID_MCI1 13 | 141 | #define AT_DMA_ID_MCI1 13 |
| 140 | 142 | ||
| 141 | #endif | 143 | #endif |
diff --git a/arch/arm/mach-dove/common.c b/arch/arm/mach-dove/common.c index 9493076fc594..4db5de54b6a7 100644 --- a/arch/arm/mach-dove/common.c +++ b/arch/arm/mach-dove/common.c | |||
| @@ -101,8 +101,8 @@ void __init dove_ehci1_init(void) | |||
| 101 | ****************************************************************************/ | 101 | ****************************************************************************/ |
| 102 | void __init dove_ge00_init(struct mv643xx_eth_platform_data *eth_data) | 102 | void __init dove_ge00_init(struct mv643xx_eth_platform_data *eth_data) |
| 103 | { | 103 | { |
| 104 | orion_ge00_init(eth_data, | 104 | orion_ge00_init(eth_data, DOVE_GE00_PHYS_BASE, |
| 105 | DOVE_GE00_PHYS_BASE, IRQ_DOVE_GE00_SUM, 0); | 105 | IRQ_DOVE_GE00_SUM, IRQ_DOVE_GE00_ERR); |
| 106 | } | 106 | } |
| 107 | 107 | ||
| 108 | /***************************************************************************** | 108 | /***************************************************************************** |
diff --git a/arch/arm/mach-exynos/clock-exynos4.c b/arch/arm/mach-exynos/clock-exynos4.c index 26fe9de35ecb..2f51293c1875 100644 --- a/arch/arm/mach-exynos/clock-exynos4.c +++ b/arch/arm/mach-exynos/clock-exynos4.c | |||
| @@ -620,10 +620,6 @@ static struct clk exynos4_init_clocks_off[] = { | |||
| 620 | .enable = exynos4_clk_ip_peril_ctrl, | 620 | .enable = exynos4_clk_ip_peril_ctrl, |
| 621 | .ctrlbit = (1 << 27), | 621 | .ctrlbit = (1 << 27), |
| 622 | }, { | 622 | }, { |
| 623 | .name = "fimg2d", | ||
| 624 | .enable = exynos4_clk_ip_image_ctrl, | ||
| 625 | .ctrlbit = (1 << 0), | ||
| 626 | }, { | ||
| 627 | .name = "mfc", | 623 | .name = "mfc", |
| 628 | .devname = "s5p-mfc", | 624 | .devname = "s5p-mfc", |
| 629 | .enable = exynos4_clk_ip_mfc_ctrl, | 625 | .enable = exynos4_clk_ip_mfc_ctrl, |
| @@ -819,47 +815,21 @@ static struct clk *exynos4_clkset_mout_g2d0_list[] = { | |||
| 819 | [1] = &exynos4_clk_sclk_apll.clk, | 815 | [1] = &exynos4_clk_sclk_apll.clk, |
| 820 | }; | 816 | }; |
| 821 | 817 | ||
| 822 | static struct clksrc_sources exynos4_clkset_mout_g2d0 = { | 818 | struct clksrc_sources exynos4_clkset_mout_g2d0 = { |
| 823 | .sources = exynos4_clkset_mout_g2d0_list, | 819 | .sources = exynos4_clkset_mout_g2d0_list, |
| 824 | .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_g2d0_list), | 820 | .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_g2d0_list), |
| 825 | }; | 821 | }; |
| 826 | 822 | ||
| 827 | static struct clksrc_clk exynos4_clk_mout_g2d0 = { | ||
| 828 | .clk = { | ||
| 829 | .name = "mout_g2d0", | ||
| 830 | }, | ||
| 831 | .sources = &exynos4_clkset_mout_g2d0, | ||
| 832 | .reg_src = { .reg = EXYNOS4_CLKSRC_IMAGE, .shift = 0, .size = 1 }, | ||
| 833 | }; | ||
| 834 | |||
| 835 | static struct clk *exynos4_clkset_mout_g2d1_list[] = { | 823 | static struct clk *exynos4_clkset_mout_g2d1_list[] = { |
| 836 | [0] = &exynos4_clk_mout_epll.clk, | 824 | [0] = &exynos4_clk_mout_epll.clk, |
| 837 | [1] = &exynos4_clk_sclk_vpll.clk, | 825 | [1] = &exynos4_clk_sclk_vpll.clk, |
| 838 | }; | 826 | }; |
| 839 | 827 | ||
| 840 | static struct clksrc_sources exynos4_clkset_mout_g2d1 = { | 828 | struct clksrc_sources exynos4_clkset_mout_g2d1 = { |
| 841 | .sources = exynos4_clkset_mout_g2d1_list, | 829 | .sources = exynos4_clkset_mout_g2d1_list, |
| 842 | .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_g2d1_list), | 830 | .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_g2d1_list), |
| 843 | }; | 831 | }; |
| 844 | 832 | ||
| 845 | static struct clksrc_clk exynos4_clk_mout_g2d1 = { | ||
| 846 | .clk = { | ||
| 847 | .name = "mout_g2d1", | ||
| 848 | }, | ||
| 849 | .sources = &exynos4_clkset_mout_g2d1, | ||
| 850 | .reg_src = { .reg = EXYNOS4_CLKSRC_IMAGE, .shift = 4, .size = 1 }, | ||
| 851 | }; | ||
| 852 | |||
| 853 | static struct clk *exynos4_clkset_mout_g2d_list[] = { | ||
| 854 | [0] = &exynos4_clk_mout_g2d0.clk, | ||
| 855 | [1] = &exynos4_clk_mout_g2d1.clk, | ||
| 856 | }; | ||
| 857 | |||
| 858 | static struct clksrc_sources exynos4_clkset_mout_g2d = { | ||
| 859 | .sources = exynos4_clkset_mout_g2d_list, | ||
| 860 | .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_g2d_list), | ||
| 861 | }; | ||
| 862 | |||
| 863 | static struct clk *exynos4_clkset_mout_mfc0_list[] = { | 833 | static struct clk *exynos4_clkset_mout_mfc0_list[] = { |
| 864 | [0] = &exynos4_clk_mout_mpll.clk, | 834 | [0] = &exynos4_clk_mout_mpll.clk, |
| 865 | [1] = &exynos4_clk_sclk_apll.clk, | 835 | [1] = &exynos4_clk_sclk_apll.clk, |
| @@ -1126,13 +1096,6 @@ static struct clksrc_clk exynos4_clksrcs[] = { | |||
| 1126 | .reg_div = { .reg = EXYNOS4_CLKDIV_LCD0, .shift = 0, .size = 4 }, | 1096 | .reg_div = { .reg = EXYNOS4_CLKDIV_LCD0, .shift = 0, .size = 4 }, |
| 1127 | }, { | 1097 | }, { |
| 1128 | .clk = { | 1098 | .clk = { |
| 1129 | .name = "sclk_fimg2d", | ||
| 1130 | }, | ||
| 1131 | .sources = &exynos4_clkset_mout_g2d, | ||
| 1132 | .reg_src = { .reg = EXYNOS4_CLKSRC_IMAGE, .shift = 8, .size = 1 }, | ||
| 1133 | .reg_div = { .reg = EXYNOS4_CLKDIV_IMAGE, .shift = 0, .size = 4 }, | ||
| 1134 | }, { | ||
| 1135 | .clk = { | ||
| 1136 | .name = "sclk_mfc", | 1099 | .name = "sclk_mfc", |
| 1137 | .devname = "s5p-mfc", | 1100 | .devname = "s5p-mfc", |
| 1138 | }, | 1101 | }, |
diff --git a/arch/arm/mach-exynos/clock-exynos4.h b/arch/arm/mach-exynos/clock-exynos4.h index 28a119701182..bd12d5f8b63d 100644 --- a/arch/arm/mach-exynos/clock-exynos4.h +++ b/arch/arm/mach-exynos/clock-exynos4.h | |||
| @@ -23,6 +23,9 @@ extern struct clksrc_sources exynos4_clkset_group; | |||
| 23 | extern struct clk *exynos4_clkset_aclk_top_list[]; | 23 | extern struct clk *exynos4_clkset_aclk_top_list[]; |
| 24 | extern struct clk *exynos4_clkset_group_list[]; | 24 | extern struct clk *exynos4_clkset_group_list[]; |
| 25 | 25 | ||
| 26 | extern struct clksrc_sources exynos4_clkset_mout_g2d0; | ||
| 27 | extern struct clksrc_sources exynos4_clkset_mout_g2d1; | ||
| 28 | |||
| 26 | extern int exynos4_clksrc_mask_fsys_ctrl(struct clk *clk, int enable); | 29 | extern int exynos4_clksrc_mask_fsys_ctrl(struct clk *clk, int enable); |
| 27 | extern int exynos4_clk_ip_fsys_ctrl(struct clk *clk, int enable); | 30 | extern int exynos4_clk_ip_fsys_ctrl(struct clk *clk, int enable); |
| 28 | extern int exynos4_clk_ip_lcd1_ctrl(struct clk *clk, int enable); | 31 | extern int exynos4_clk_ip_lcd1_ctrl(struct clk *clk, int enable); |
diff --git a/arch/arm/mach-exynos/clock-exynos4210.c b/arch/arm/mach-exynos/clock-exynos4210.c index b8689ff60baf..fed4c26e9dad 100644 --- a/arch/arm/mach-exynos/clock-exynos4210.c +++ b/arch/arm/mach-exynos/clock-exynos4210.c | |||
| @@ -48,6 +48,32 @@ static struct clksrc_clk *sysclks[] = { | |||
| 48 | /* nothing here yet */ | 48 | /* nothing here yet */ |
| 49 | }; | 49 | }; |
| 50 | 50 | ||
| 51 | static struct clksrc_clk exynos4210_clk_mout_g2d0 = { | ||
| 52 | .clk = { | ||
| 53 | .name = "mout_g2d0", | ||
| 54 | }, | ||
| 55 | .sources = &exynos4_clkset_mout_g2d0, | ||
| 56 | .reg_src = { .reg = EXYNOS4_CLKSRC_IMAGE, .shift = 0, .size = 1 }, | ||
| 57 | }; | ||
| 58 | |||
| 59 | static struct clksrc_clk exynos4210_clk_mout_g2d1 = { | ||
| 60 | .clk = { | ||
| 61 | .name = "mout_g2d1", | ||
| 62 | }, | ||
| 63 | .sources = &exynos4_clkset_mout_g2d1, | ||
| 64 | .reg_src = { .reg = EXYNOS4_CLKSRC_IMAGE, .shift = 4, .size = 1 }, | ||
| 65 | }; | ||
| 66 | |||
| 67 | static struct clk *exynos4210_clkset_mout_g2d_list[] = { | ||
| 68 | [0] = &exynos4210_clk_mout_g2d0.clk, | ||
| 69 | [1] = &exynos4210_clk_mout_g2d1.clk, | ||
| 70 | }; | ||
| 71 | |||
| 72 | static struct clksrc_sources exynos4210_clkset_mout_g2d = { | ||
| 73 | .sources = exynos4210_clkset_mout_g2d_list, | ||
| 74 | .nr_sources = ARRAY_SIZE(exynos4210_clkset_mout_g2d_list), | ||
| 75 | }; | ||
| 76 | |||
| 51 | static int exynos4_clksrc_mask_lcd1_ctrl(struct clk *clk, int enable) | 77 | static int exynos4_clksrc_mask_lcd1_ctrl(struct clk *clk, int enable) |
| 52 | { | 78 | { |
| 53 | return s5p_gatectrl(EXYNOS4210_CLKSRC_MASK_LCD1, clk, enable); | 79 | return s5p_gatectrl(EXYNOS4210_CLKSRC_MASK_LCD1, clk, enable); |
| @@ -74,6 +100,13 @@ static struct clksrc_clk clksrcs[] = { | |||
| 74 | .sources = &exynos4_clkset_group, | 100 | .sources = &exynos4_clkset_group, |
| 75 | .reg_src = { .reg = EXYNOS4210_CLKSRC_LCD1, .shift = 0, .size = 4 }, | 101 | .reg_src = { .reg = EXYNOS4210_CLKSRC_LCD1, .shift = 0, .size = 4 }, |
| 76 | .reg_div = { .reg = EXYNOS4210_CLKDIV_LCD1, .shift = 0, .size = 4 }, | 102 | .reg_div = { .reg = EXYNOS4210_CLKDIV_LCD1, .shift = 0, .size = 4 }, |
| 103 | }, { | ||
| 104 | .clk = { | ||
| 105 | .name = "sclk_fimg2d", | ||
| 106 | }, | ||
| 107 | .sources = &exynos4210_clkset_mout_g2d, | ||
| 108 | .reg_src = { .reg = EXYNOS4_CLKSRC_IMAGE, .shift = 8, .size = 1 }, | ||
| 109 | .reg_div = { .reg = EXYNOS4_CLKDIV_IMAGE, .shift = 0, .size = 4 }, | ||
| 77 | }, | 110 | }, |
| 78 | }; | 111 | }; |
| 79 | 112 | ||
| @@ -105,6 +138,10 @@ static struct clk init_clocks_off[] = { | |||
| 105 | .devname = SYSMMU_CLOCK_DEVNAME(fimd1, 11), | 138 | .devname = SYSMMU_CLOCK_DEVNAME(fimd1, 11), |
| 106 | .enable = exynos4_clk_ip_lcd1_ctrl, | 139 | .enable = exynos4_clk_ip_lcd1_ctrl, |
| 107 | .ctrlbit = (1 << 4), | 140 | .ctrlbit = (1 << 4), |
| 141 | }, { | ||
| 142 | .name = "fimg2d", | ||
| 143 | .enable = exynos4_clk_ip_image_ctrl, | ||
| 144 | .ctrlbit = (1 << 0), | ||
| 108 | }, | 145 | }, |
| 109 | }; | 146 | }; |
| 110 | 147 | ||
diff --git a/arch/arm/mach-exynos/clock-exynos4212.c b/arch/arm/mach-exynos/clock-exynos4212.c index da397d21bbcf..8fba0b5fb8ab 100644 --- a/arch/arm/mach-exynos/clock-exynos4212.c +++ b/arch/arm/mach-exynos/clock-exynos4212.c | |||
| @@ -68,12 +68,45 @@ static struct clksrc_clk clk_mout_mpll_user = { | |||
| 68 | .reg_src = { .reg = EXYNOS4_CLKSRC_CPU, .shift = 24, .size = 1 }, | 68 | .reg_src = { .reg = EXYNOS4_CLKSRC_CPU, .shift = 24, .size = 1 }, |
| 69 | }; | 69 | }; |
| 70 | 70 | ||
| 71 | static struct clksrc_clk exynos4x12_clk_mout_g2d0 = { | ||
| 72 | .clk = { | ||
| 73 | .name = "mout_g2d0", | ||
| 74 | }, | ||
| 75 | .sources = &exynos4_clkset_mout_g2d0, | ||
| 76 | .reg_src = { .reg = EXYNOS4_CLKSRC_DMC, .shift = 20, .size = 1 }, | ||
| 77 | }; | ||
| 78 | |||
| 79 | static struct clksrc_clk exynos4x12_clk_mout_g2d1 = { | ||
| 80 | .clk = { | ||
| 81 | .name = "mout_g2d1", | ||
| 82 | }, | ||
| 83 | .sources = &exynos4_clkset_mout_g2d1, | ||
| 84 | .reg_src = { .reg = EXYNOS4_CLKSRC_DMC, .shift = 24, .size = 1 }, | ||
| 85 | }; | ||
| 86 | |||
| 87 | static struct clk *exynos4x12_clkset_mout_g2d_list[] = { | ||
| 88 | [0] = &exynos4x12_clk_mout_g2d0.clk, | ||
| 89 | [1] = &exynos4x12_clk_mout_g2d1.clk, | ||
| 90 | }; | ||
| 91 | |||
| 92 | static struct clksrc_sources exynos4x12_clkset_mout_g2d = { | ||
| 93 | .sources = exynos4x12_clkset_mout_g2d_list, | ||
| 94 | .nr_sources = ARRAY_SIZE(exynos4x12_clkset_mout_g2d_list), | ||
| 95 | }; | ||
| 96 | |||
| 71 | static struct clksrc_clk *sysclks[] = { | 97 | static struct clksrc_clk *sysclks[] = { |
| 72 | &clk_mout_mpll_user, | 98 | &clk_mout_mpll_user, |
| 73 | }; | 99 | }; |
| 74 | 100 | ||
| 75 | static struct clksrc_clk clksrcs[] = { | 101 | static struct clksrc_clk clksrcs[] = { |
| 76 | /* nothing here yet */ | 102 | { |
| 103 | .clk = { | ||
| 104 | .name = "sclk_fimg2d", | ||
| 105 | }, | ||
| 106 | .sources = &exynos4x12_clkset_mout_g2d, | ||
| 107 | .reg_src = { .reg = EXYNOS4_CLKSRC_DMC, .shift = 28, .size = 1 }, | ||
| 108 | .reg_div = { .reg = EXYNOS4_CLKDIV_DMC1, .shift = 0, .size = 4 }, | ||
| 109 | }, | ||
| 77 | }; | 110 | }; |
| 78 | 111 | ||
| 79 | static struct clk init_clocks_off[] = { | 112 | static struct clk init_clocks_off[] = { |
| @@ -102,7 +135,11 @@ static struct clk init_clocks_off[] = { | |||
| 102 | .devname = "exynos-fimc-lite.1", | 135 | .devname = "exynos-fimc-lite.1", |
| 103 | .enable = exynos4212_clk_ip_isp0_ctrl, | 136 | .enable = exynos4212_clk_ip_isp0_ctrl, |
| 104 | .ctrlbit = (1 << 3), | 137 | .ctrlbit = (1 << 3), |
| 105 | } | 138 | }, { |
| 139 | .name = "fimg2d", | ||
| 140 | .enable = exynos4_clk_ip_dmc_ctrl, | ||
| 141 | .ctrlbit = (1 << 23), | ||
| 142 | }, | ||
| 106 | }; | 143 | }; |
| 107 | 144 | ||
| 108 | #ifdef CONFIG_PM_SLEEP | 145 | #ifdef CONFIG_PM_SLEEP |
diff --git a/arch/arm/mach-exynos/mach-nuri.c b/arch/arm/mach-exynos/mach-nuri.c index f98a83a81ce7..ea785fcaf6c3 100644 --- a/arch/arm/mach-exynos/mach-nuri.c +++ b/arch/arm/mach-exynos/mach-nuri.c | |||
| @@ -1066,12 +1066,8 @@ static struct platform_device nuri_max8903_device = { | |||
| 1066 | static void __init nuri_power_init(void) | 1066 | static void __init nuri_power_init(void) |
| 1067 | { | 1067 | { |
| 1068 | int gpio; | 1068 | int gpio; |
| 1069 | int irq_base = IRQ_GPIO_END + 1; | ||
| 1070 | int ta_en = 0; | 1069 | int ta_en = 0; |
| 1071 | 1070 | ||
| 1072 | nuri_max8997_pdata.irq_base = irq_base; | ||
| 1073 | irq_base += MAX8997_IRQ_NR; | ||
| 1074 | |||
| 1075 | gpio = EXYNOS4_GPX0(7); | 1071 | gpio = EXYNOS4_GPX0(7); |
| 1076 | gpio_request(gpio, "AP_PMIC_IRQ"); | 1072 | gpio_request(gpio, "AP_PMIC_IRQ"); |
| 1077 | s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf)); | 1073 | s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf)); |
diff --git a/arch/arm/mach-exynos/mach-origen.c b/arch/arm/mach-exynos/mach-origen.c index 5a12dc26f496..5ca80307d6d7 100644 --- a/arch/arm/mach-exynos/mach-origen.c +++ b/arch/arm/mach-exynos/mach-origen.c | |||
| @@ -426,7 +426,6 @@ static struct max8997_platform_data __initdata origen_max8997_pdata = { | |||
| 426 | .buck1_gpiodvs = false, | 426 | .buck1_gpiodvs = false, |
| 427 | .buck2_gpiodvs = false, | 427 | .buck2_gpiodvs = false, |
| 428 | .buck5_gpiodvs = false, | 428 | .buck5_gpiodvs = false, |
| 429 | .irq_base = IRQ_GPIO_END + 1, | ||
| 430 | 429 | ||
| 431 | .ignore_gpiodvs_side_effect = true, | 430 | .ignore_gpiodvs_side_effect = true, |
| 432 | .buck125_default_idx = 0x0, | 431 | .buck125_default_idx = 0x0, |
diff --git a/arch/arm/mach-imx/mm-imx25.c b/arch/arm/mach-imx/mm-imx25.c index 388928fdb11a..f3f5c6542ab4 100644 --- a/arch/arm/mach-imx/mm-imx25.c +++ b/arch/arm/mach-imx/mm-imx25.c | |||
| @@ -89,11 +89,11 @@ static const struct resource imx25_audmux_res[] __initconst = { | |||
| 89 | 89 | ||
| 90 | void __init imx25_soc_init(void) | 90 | void __init imx25_soc_init(void) |
| 91 | { | 91 | { |
| 92 | /* i.mx25 has the i.mx31 type gpio */ | 92 | /* i.mx25 has the i.mx35 type gpio */ |
| 93 | mxc_register_gpio("imx31-gpio", 0, MX25_GPIO1_BASE_ADDR, SZ_16K, MX25_INT_GPIO1, 0); | 93 | mxc_register_gpio("imx35-gpio", 0, MX25_GPIO1_BASE_ADDR, SZ_16K, MX25_INT_GPIO1, 0); |
| 94 | mxc_register_gpio("imx31-gpio", 1, MX25_GPIO2_BASE_ADDR, SZ_16K, MX25_INT_GPIO2, 0); | 94 | mxc_register_gpio("imx35-gpio", 1, MX25_GPIO2_BASE_ADDR, SZ_16K, MX25_INT_GPIO2, 0); |
| 95 | mxc_register_gpio("imx31-gpio", 2, MX25_GPIO3_BASE_ADDR, SZ_16K, MX25_INT_GPIO3, 0); | 95 | mxc_register_gpio("imx35-gpio", 2, MX25_GPIO3_BASE_ADDR, SZ_16K, MX25_INT_GPIO3, 0); |
| 96 | mxc_register_gpio("imx31-gpio", 3, MX25_GPIO4_BASE_ADDR, SZ_16K, MX25_INT_GPIO4, 0); | 96 | mxc_register_gpio("imx35-gpio", 3, MX25_GPIO4_BASE_ADDR, SZ_16K, MX25_INT_GPIO4, 0); |
| 97 | 97 | ||
| 98 | pinctrl_provide_dummies(); | 98 | pinctrl_provide_dummies(); |
| 99 | /* i.mx25 has the i.mx35 type sdma */ | 99 | /* i.mx25 has the i.mx35 type sdma */ |
diff --git a/arch/arm/mach-imx/mm-imx3.c b/arch/arm/mach-imx/mm-imx3.c index fe96105109b3..9d2c843bde02 100644 --- a/arch/arm/mach-imx/mm-imx3.c +++ b/arch/arm/mach-imx/mm-imx3.c | |||
| @@ -272,10 +272,9 @@ void __init imx35_soc_init(void) | |||
| 272 | 272 | ||
| 273 | imx3_init_l2x0(); | 273 | imx3_init_l2x0(); |
| 274 | 274 | ||
| 275 | /* i.mx35 has the i.mx31 type gpio */ | 275 | mxc_register_gpio("imx35-gpio", 0, MX35_GPIO1_BASE_ADDR, SZ_16K, MX35_INT_GPIO1, 0); |
| 276 | mxc_register_gpio("imx31-gpio", 0, MX35_GPIO1_BASE_ADDR, SZ_16K, MX35_INT_GPIO1, 0); | 276 | mxc_register_gpio("imx35-gpio", 1, MX35_GPIO2_BASE_ADDR, SZ_16K, MX35_INT_GPIO2, 0); |
| 277 | mxc_register_gpio("imx31-gpio", 1, MX35_GPIO2_BASE_ADDR, SZ_16K, MX35_INT_GPIO2, 0); | 277 | mxc_register_gpio("imx35-gpio", 2, MX35_GPIO3_BASE_ADDR, SZ_16K, MX35_INT_GPIO3, 0); |
| 278 | mxc_register_gpio("imx31-gpio", 2, MX35_GPIO3_BASE_ADDR, SZ_16K, MX35_INT_GPIO3, 0); | ||
| 279 | 278 | ||
| 280 | pinctrl_provide_dummies(); | 279 | pinctrl_provide_dummies(); |
| 281 | if (to_version == 1) { | 280 | if (to_version == 1) { |
diff --git a/arch/arm/mach-imx/mm-imx5.c b/arch/arm/mach-imx/mm-imx5.c index f19d604e1b2a..52d8f534be10 100644 --- a/arch/arm/mach-imx/mm-imx5.c +++ b/arch/arm/mach-imx/mm-imx5.c | |||
| @@ -161,13 +161,13 @@ static const struct resource imx53_audmux_res[] __initconst = { | |||
| 161 | 161 | ||
| 162 | void __init imx50_soc_init(void) | 162 | void __init imx50_soc_init(void) |
| 163 | { | 163 | { |
| 164 | /* i.mx50 has the i.mx31 type gpio */ | 164 | /* i.mx50 has the i.mx35 type gpio */ |
| 165 | mxc_register_gpio("imx31-gpio", 0, MX50_GPIO1_BASE_ADDR, SZ_16K, MX50_INT_GPIO1_LOW, MX50_INT_GPIO1_HIGH); | 165 | mxc_register_gpio("imx35-gpio", 0, MX50_GPIO1_BASE_ADDR, SZ_16K, MX50_INT_GPIO1_LOW, MX50_INT_GPIO1_HIGH); |
| 166 | mxc_register_gpio("imx31-gpio", 1, MX50_GPIO2_BASE_ADDR, SZ_16K, MX50_INT_GPIO2_LOW, MX50_INT_GPIO2_HIGH); | 166 | mxc_register_gpio("imx35-gpio", 1, MX50_GPIO2_BASE_ADDR, SZ_16K, MX50_INT_GPIO2_LOW, MX50_INT_GPIO2_HIGH); |
| 167 | mxc_register_gpio("imx31-gpio", 2, MX50_GPIO3_BASE_ADDR, SZ_16K, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH); | 167 | mxc_register_gpio("imx35-gpio", 2, MX50_GPIO3_BASE_ADDR, SZ_16K, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH); |
| 168 | mxc_register_gpio("imx31-gpio", 3, MX50_GPIO4_BASE_ADDR, SZ_16K, MX50_INT_GPIO4_LOW, MX50_INT_GPIO4_HIGH); | 168 | mxc_register_gpio("imx35-gpio", 3, MX50_GPIO4_BASE_ADDR, SZ_16K, MX50_INT_GPIO4_LOW, MX50_INT_GPIO4_HIGH); |
| 169 | mxc_register_gpio("imx31-gpio", 4, MX50_GPIO5_BASE_ADDR, SZ_16K, MX50_INT_GPIO5_LOW, MX50_INT_GPIO5_HIGH); | 169 | mxc_register_gpio("imx35-gpio", 4, MX50_GPIO5_BASE_ADDR, SZ_16K, MX50_INT_GPIO5_LOW, MX50_INT_GPIO5_HIGH); |
| 170 | mxc_register_gpio("imx31-gpio", 5, MX50_GPIO6_BASE_ADDR, SZ_16K, MX50_INT_GPIO6_LOW, MX50_INT_GPIO6_HIGH); | 170 | mxc_register_gpio("imx35-gpio", 5, MX50_GPIO6_BASE_ADDR, SZ_16K, MX50_INT_GPIO6_LOW, MX50_INT_GPIO6_HIGH); |
| 171 | 171 | ||
| 172 | /* i.mx50 has the i.mx31 type audmux */ | 172 | /* i.mx50 has the i.mx31 type audmux */ |
| 173 | platform_device_register_simple("imx31-audmux", 0, imx50_audmux_res, | 173 | platform_device_register_simple("imx31-audmux", 0, imx50_audmux_res, |
| @@ -176,11 +176,11 @@ void __init imx50_soc_init(void) | |||
| 176 | 176 | ||
| 177 | void __init imx51_soc_init(void) | 177 | void __init imx51_soc_init(void) |
| 178 | { | 178 | { |
| 179 | /* i.mx51 has the i.mx31 type gpio */ | 179 | /* i.mx51 has the i.mx35 type gpio */ |
| 180 | mxc_register_gpio("imx31-gpio", 0, MX51_GPIO1_BASE_ADDR, SZ_16K, MX51_INT_GPIO1_LOW, MX51_INT_GPIO1_HIGH); | 180 | mxc_register_gpio("imx35-gpio", 0, MX51_GPIO1_BASE_ADDR, SZ_16K, MX51_INT_GPIO1_LOW, MX51_INT_GPIO1_HIGH); |
| 181 | mxc_register_gpio("imx31-gpio", 1, MX51_GPIO2_BASE_ADDR, SZ_16K, MX51_INT_GPIO2_LOW, MX51_INT_GPIO2_HIGH); | 181 | mxc_register_gpio("imx35-gpio", 1, MX51_GPIO2_BASE_ADDR, SZ_16K, MX51_INT_GPIO2_LOW, MX51_INT_GPIO2_HIGH); |
| 182 | mxc_register_gpio("imx31-gpio", 2, MX51_GPIO3_BASE_ADDR, SZ_16K, MX51_INT_GPIO3_LOW, MX51_INT_GPIO3_HIGH); | 182 | mxc_register_gpio("imx35-gpio", 2, MX51_GPIO3_BASE_ADDR, SZ_16K, MX51_INT_GPIO3_LOW, MX51_INT_GPIO3_HIGH); |
| 183 | mxc_register_gpio("imx31-gpio", 3, MX51_GPIO4_BASE_ADDR, SZ_16K, MX51_INT_GPIO4_LOW, MX51_INT_GPIO4_HIGH); | 183 | mxc_register_gpio("imx35-gpio", 3, MX51_GPIO4_BASE_ADDR, SZ_16K, MX51_INT_GPIO4_LOW, MX51_INT_GPIO4_HIGH); |
| 184 | 184 | ||
| 185 | pinctrl_provide_dummies(); | 185 | pinctrl_provide_dummies(); |
| 186 | 186 | ||
| @@ -198,14 +198,14 @@ void __init imx51_soc_init(void) | |||
| 198 | 198 | ||
| 199 | void __init imx53_soc_init(void) | 199 | void __init imx53_soc_init(void) |
| 200 | { | 200 | { |
| 201 | /* i.mx53 has the i.mx31 type gpio */ | 201 | /* i.mx53 has the i.mx35 type gpio */ |
| 202 | mxc_register_gpio("imx31-gpio", 0, MX53_GPIO1_BASE_ADDR, SZ_16K, MX53_INT_GPIO1_LOW, MX53_INT_GPIO1_HIGH); | 202 | mxc_register_gpio("imx35-gpio", 0, MX53_GPIO1_BASE_ADDR, SZ_16K, MX53_INT_GPIO1_LOW, MX53_INT_GPIO1_HIGH); |
| 203 | mxc_register_gpio("imx31-gpio", 1, MX53_GPIO2_BASE_ADDR, SZ_16K, MX53_INT_GPIO2_LOW, MX53_INT_GPIO2_HIGH); | 203 | mxc_register_gpio("imx35-gpio", 1, MX53_GPIO2_BASE_ADDR, SZ_16K, MX53_INT_GPIO2_LOW, MX53_INT_GPIO2_HIGH); |
| 204 | mxc_register_gpio("imx31-gpio", 2, MX53_GPIO3_BASE_ADDR, SZ_16K, MX53_INT_GPIO3_LOW, MX53_INT_GPIO3_HIGH); | 204 | mxc_register_gpio("imx35-gpio", 2, MX53_GPIO3_BASE_ADDR, SZ_16K, MX53_INT_GPIO3_LOW, MX53_INT_GPIO3_HIGH); |
| 205 | mxc_register_gpio("imx31-gpio", 3, MX53_GPIO4_BASE_ADDR, SZ_16K, MX53_INT_GPIO4_LOW, MX53_INT_GPIO4_HIGH); | 205 | mxc_register_gpio("imx35-gpio", 3, MX53_GPIO4_BASE_ADDR, SZ_16K, MX53_INT_GPIO4_LOW, MX53_INT_GPIO4_HIGH); |
| 206 | mxc_register_gpio("imx31-gpio", 4, MX53_GPIO5_BASE_ADDR, SZ_16K, MX53_INT_GPIO5_LOW, MX53_INT_GPIO5_HIGH); | 206 | mxc_register_gpio("imx35-gpio", 4, MX53_GPIO5_BASE_ADDR, SZ_16K, MX53_INT_GPIO5_LOW, MX53_INT_GPIO5_HIGH); |
| 207 | mxc_register_gpio("imx31-gpio", 5, MX53_GPIO6_BASE_ADDR, SZ_16K, MX53_INT_GPIO6_LOW, MX53_INT_GPIO6_HIGH); | 207 | mxc_register_gpio("imx35-gpio", 5, MX53_GPIO6_BASE_ADDR, SZ_16K, MX53_INT_GPIO6_LOW, MX53_INT_GPIO6_HIGH); |
| 208 | mxc_register_gpio("imx31-gpio", 6, MX53_GPIO7_BASE_ADDR, SZ_16K, MX53_INT_GPIO7_LOW, MX53_INT_GPIO7_HIGH); | 208 | mxc_register_gpio("imx35-gpio", 6, MX53_GPIO7_BASE_ADDR, SZ_16K, MX53_INT_GPIO7_LOW, MX53_INT_GPIO7_HIGH); |
| 209 | 209 | ||
| 210 | pinctrl_provide_dummies(); | 210 | pinctrl_provide_dummies(); |
| 211 | /* i.mx53 has the i.mx35 type sdma */ | 211 | /* i.mx53 has the i.mx35 type sdma */ |
diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index f261cd242643..c9201539ffbd 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c | |||
| @@ -67,6 +67,14 @@ void __init kirkwood_map_io(void) | |||
| 67 | * CLK tree | 67 | * CLK tree |
| 68 | ****************************************************************************/ | 68 | ****************************************************************************/ |
| 69 | 69 | ||
| 70 | static void enable_sata0(void) | ||
| 71 | { | ||
| 72 | /* Enable PLL and IVREF */ | ||
| 73 | writel(readl(SATA0_PHY_MODE_2) | 0xf, SATA0_PHY_MODE_2); | ||
| 74 | /* Enable PHY */ | ||
| 75 | writel(readl(SATA0_IF_CTRL) & ~0x200, SATA0_IF_CTRL); | ||
| 76 | } | ||
| 77 | |||
| 70 | static void disable_sata0(void) | 78 | static void disable_sata0(void) |
| 71 | { | 79 | { |
| 72 | /* Disable PLL and IVREF */ | 80 | /* Disable PLL and IVREF */ |
| @@ -75,6 +83,14 @@ static void disable_sata0(void) | |||
| 75 | writel(readl(SATA0_IF_CTRL) | 0x200, SATA0_IF_CTRL); | 83 | writel(readl(SATA0_IF_CTRL) | 0x200, SATA0_IF_CTRL); |
| 76 | } | 84 | } |
| 77 | 85 | ||
| 86 | static void enable_sata1(void) | ||
| 87 | { | ||
| 88 | /* Enable PLL and IVREF */ | ||
| 89 | writel(readl(SATA1_PHY_MODE_2) | 0xf, SATA1_PHY_MODE_2); | ||
| 90 | /* Enable PHY */ | ||
| 91 | writel(readl(SATA1_IF_CTRL) & ~0x200, SATA1_IF_CTRL); | ||
| 92 | } | ||
| 93 | |||
| 78 | static void disable_sata1(void) | 94 | static void disable_sata1(void) |
| 79 | { | 95 | { |
| 80 | /* Disable PLL and IVREF */ | 96 | /* Disable PLL and IVREF */ |
| @@ -107,23 +123,38 @@ static void disable_pcie1(void) | |||
| 107 | } | 123 | } |
| 108 | } | 124 | } |
| 109 | 125 | ||
| 110 | /* An extended version of the gated clk. This calls fn() before | 126 | /* An extended version of the gated clk. This calls fn_en()/fn_dis |
| 111 | * disabling the clock. We use this to turn off PHYs etc. */ | 127 | * before enabling/disabling the clock. We use this to turn on/off |
| 128 | * PHYs etc. */ | ||
| 112 | struct clk_gate_fn { | 129 | struct clk_gate_fn { |
| 113 | struct clk_gate gate; | 130 | struct clk_gate gate; |
| 114 | void (*fn)(void); | 131 | void (*fn_en)(void); |
| 132 | void (*fn_dis)(void); | ||
| 115 | }; | 133 | }; |
| 116 | 134 | ||
| 117 | #define to_clk_gate_fn(_gate) container_of(_gate, struct clk_gate_fn, gate) | 135 | #define to_clk_gate_fn(_gate) container_of(_gate, struct clk_gate_fn, gate) |
| 118 | #define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw) | 136 | #define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw) |
| 119 | 137 | ||
| 138 | static int clk_gate_fn_enable(struct clk_hw *hw) | ||
| 139 | { | ||
| 140 | struct clk_gate *gate = to_clk_gate(hw); | ||
| 141 | struct clk_gate_fn *gate_fn = to_clk_gate_fn(gate); | ||
| 142 | int ret; | ||
| 143 | |||
| 144 | ret = clk_gate_ops.enable(hw); | ||
| 145 | if (!ret && gate_fn->fn_en) | ||
| 146 | gate_fn->fn_en(); | ||
| 147 | |||
| 148 | return ret; | ||
| 149 | } | ||
| 150 | |||
| 120 | static void clk_gate_fn_disable(struct clk_hw *hw) | 151 | static void clk_gate_fn_disable(struct clk_hw *hw) |
| 121 | { | 152 | { |
| 122 | struct clk_gate *gate = to_clk_gate(hw); | 153 | struct clk_gate *gate = to_clk_gate(hw); |
| 123 | struct clk_gate_fn *gate_fn = to_clk_gate_fn(gate); | 154 | struct clk_gate_fn *gate_fn = to_clk_gate_fn(gate); |
| 124 | 155 | ||
| 125 | if (gate_fn->fn) | 156 | if (gate_fn->fn_dis) |
| 126 | gate_fn->fn(); | 157 | gate_fn->fn_dis(); |
| 127 | 158 | ||
| 128 | clk_gate_ops.disable(hw); | 159 | clk_gate_ops.disable(hw); |
| 129 | } | 160 | } |
| @@ -135,7 +166,7 @@ static struct clk __init *clk_register_gate_fn(struct device *dev, | |||
| 135 | const char *parent_name, unsigned long flags, | 166 | const char *parent_name, unsigned long flags, |
| 136 | void __iomem *reg, u8 bit_idx, | 167 | void __iomem *reg, u8 bit_idx, |
| 137 | u8 clk_gate_flags, spinlock_t *lock, | 168 | u8 clk_gate_flags, spinlock_t *lock, |
| 138 | void (*fn)(void)) | 169 | void (*fn_en)(void), void (*fn_dis)(void)) |
| 139 | { | 170 | { |
| 140 | struct clk_gate_fn *gate_fn; | 171 | struct clk_gate_fn *gate_fn; |
| 141 | struct clk *clk; | 172 | struct clk *clk; |
| @@ -159,11 +190,14 @@ static struct clk __init *clk_register_gate_fn(struct device *dev, | |||
| 159 | gate_fn->gate.flags = clk_gate_flags; | 190 | gate_fn->gate.flags = clk_gate_flags; |
| 160 | gate_fn->gate.lock = lock; | 191 | gate_fn->gate.lock = lock; |
| 161 | gate_fn->gate.hw.init = &init; | 192 | gate_fn->gate.hw.init = &init; |
| 162 | gate_fn->fn = fn; | 193 | gate_fn->fn_en = fn_en; |
| 194 | gate_fn->fn_dis = fn_dis; | ||
| 163 | 195 | ||
| 164 | /* ops is the gate ops, but with our disable function */ | 196 | /* ops is the gate ops, but with our enable/disable functions */ |
| 165 | if (clk_gate_fn_ops.disable != clk_gate_fn_disable) { | 197 | if (clk_gate_fn_ops.enable != clk_gate_fn_enable || |
| 198 | clk_gate_fn_ops.disable != clk_gate_fn_disable) { | ||
| 166 | clk_gate_fn_ops = clk_gate_ops; | 199 | clk_gate_fn_ops = clk_gate_ops; |
| 200 | clk_gate_fn_ops.enable = clk_gate_fn_enable; | ||
| 167 | clk_gate_fn_ops.disable = clk_gate_fn_disable; | 201 | clk_gate_fn_ops.disable = clk_gate_fn_disable; |
| 168 | } | 202 | } |
| 169 | 203 | ||
| @@ -187,11 +221,12 @@ static struct clk __init *kirkwood_register_gate(const char *name, u8 bit_idx) | |||
| 187 | 221 | ||
| 188 | static struct clk __init *kirkwood_register_gate_fn(const char *name, | 222 | static struct clk __init *kirkwood_register_gate_fn(const char *name, |
| 189 | u8 bit_idx, | 223 | u8 bit_idx, |
| 190 | void (*fn)(void)) | 224 | void (*fn_en)(void), |
| 225 | void (*fn_dis)(void)) | ||
| 191 | { | 226 | { |
| 192 | return clk_register_gate_fn(NULL, name, "tclk", 0, | 227 | return clk_register_gate_fn(NULL, name, "tclk", 0, |
| 193 | (void __iomem *)CLOCK_GATING_CTRL, | 228 | (void __iomem *)CLOCK_GATING_CTRL, |
| 194 | bit_idx, 0, &gating_lock, fn); | 229 | bit_idx, 0, &gating_lock, fn_en, fn_dis); |
| 195 | } | 230 | } |
| 196 | 231 | ||
| 197 | static struct clk *ge0, *ge1; | 232 | static struct clk *ge0, *ge1; |
| @@ -208,18 +243,18 @@ void __init kirkwood_clk_init(void) | |||
| 208 | ge0 = kirkwood_register_gate("ge0", CGC_BIT_GE0); | 243 | ge0 = kirkwood_register_gate("ge0", CGC_BIT_GE0); |
| 209 | ge1 = kirkwood_register_gate("ge1", CGC_BIT_GE1); | 244 | ge1 = kirkwood_register_gate("ge1", CGC_BIT_GE1); |
| 210 | sata0 = kirkwood_register_gate_fn("sata0", CGC_BIT_SATA0, | 245 | sata0 = kirkwood_register_gate_fn("sata0", CGC_BIT_SATA0, |
| 211 | disable_sata0); | 246 | enable_sata0, disable_sata0); |
| 212 | sata1 = kirkwood_register_gate_fn("sata1", CGC_BIT_SATA1, | 247 | sata1 = kirkwood_register_gate_fn("sata1", CGC_BIT_SATA1, |
| 213 | disable_sata1); | 248 | enable_sata1, disable_sata1); |
| 214 | usb0 = kirkwood_register_gate("usb0", CGC_BIT_USB0); | 249 | usb0 = kirkwood_register_gate("usb0", CGC_BIT_USB0); |
| 215 | sdio = kirkwood_register_gate("sdio", CGC_BIT_SDIO); | 250 | sdio = kirkwood_register_gate("sdio", CGC_BIT_SDIO); |
| 216 | crypto = kirkwood_register_gate("crypto", CGC_BIT_CRYPTO); | 251 | crypto = kirkwood_register_gate("crypto", CGC_BIT_CRYPTO); |
| 217 | xor0 = kirkwood_register_gate("xor0", CGC_BIT_XOR0); | 252 | xor0 = kirkwood_register_gate("xor0", CGC_BIT_XOR0); |
| 218 | xor1 = kirkwood_register_gate("xor1", CGC_BIT_XOR1); | 253 | xor1 = kirkwood_register_gate("xor1", CGC_BIT_XOR1); |
| 219 | pex0 = kirkwood_register_gate_fn("pex0", CGC_BIT_PEX0, | 254 | pex0 = kirkwood_register_gate_fn("pex0", CGC_BIT_PEX0, |
| 220 | disable_pcie0); | 255 | NULL, disable_pcie0); |
| 221 | pex1 = kirkwood_register_gate_fn("pex1", CGC_BIT_PEX1, | 256 | pex1 = kirkwood_register_gate_fn("pex1", CGC_BIT_PEX1, |
| 222 | disable_pcie1); | 257 | NULL, disable_pcie1); |
| 223 | audio = kirkwood_register_gate("audio", CGC_BIT_AUDIO); | 258 | audio = kirkwood_register_gate("audio", CGC_BIT_AUDIO); |
| 224 | kirkwood_register_gate("tdm", CGC_BIT_TDM); | 259 | kirkwood_register_gate("tdm", CGC_BIT_TDM); |
| 225 | kirkwood_register_gate("tsu", CGC_BIT_TSU); | 260 | kirkwood_register_gate("tsu", CGC_BIT_TSU); |
| @@ -241,6 +276,11 @@ void __init kirkwood_clk_init(void) | |||
| 241 | orion_clkdev_add("0", "pcie", pex0); | 276 | orion_clkdev_add("0", "pcie", pex0); |
| 242 | orion_clkdev_add("1", "pcie", pex1); | 277 | orion_clkdev_add("1", "pcie", pex1); |
| 243 | orion_clkdev_add(NULL, "kirkwood-i2s", audio); | 278 | orion_clkdev_add(NULL, "kirkwood-i2s", audio); |
| 279 | |||
| 280 | /* Marvell says runit is used by SPI, UART, NAND, TWSI, ..., | ||
| 281 | * so should never be gated. | ||
| 282 | */ | ||
| 283 | clk_prepare_enable(runit); | ||
| 244 | } | 284 | } |
| 245 | 285 | ||
| 246 | /***************************************************************************** | 286 | /***************************************************************************** |
diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c index db0117ec55f4..e012dc8391cf 100644 --- a/arch/arm/mach-msm/platsmp.c +++ b/arch/arm/mach-msm/platsmp.c | |||
| @@ -127,7 +127,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) | |||
| 127 | * the boot monitor to read the system wide flags register, | 127 | * the boot monitor to read the system wide flags register, |
| 128 | * and branch to the address found there. | 128 | * and branch to the address found there. |
| 129 | */ | 129 | */ |
| 130 | gic_raise_softirq(cpumask_of(cpu), 1); | 130 | gic_raise_softirq(cpumask_of(cpu), 0); |
| 131 | 131 | ||
| 132 | timeout = jiffies + (1 * HZ); | 132 | timeout = jiffies + (1 * HZ); |
| 133 | while (time_before(jiffies, timeout)) { | 133 | while (time_before(jiffies, timeout)) { |
diff --git a/arch/arm/mach-mxs/mach-mxs.c b/arch/arm/mach-mxs/mach-mxs.c index 648bdd05d38b..8dabfe81d07c 100644 --- a/arch/arm/mach-mxs/mach-mxs.c +++ b/arch/arm/mach-mxs/mach-mxs.c | |||
| @@ -162,7 +162,7 @@ enum mac_oui { | |||
| 162 | static void __init update_fec_mac_prop(enum mac_oui oui) | 162 | static void __init update_fec_mac_prop(enum mac_oui oui) |
| 163 | { | 163 | { |
| 164 | struct device_node *np, *from = NULL; | 164 | struct device_node *np, *from = NULL; |
| 165 | struct property *oldmac, *newmac; | 165 | struct property *newmac; |
| 166 | const u32 *ocotp = mxs_get_ocotp(); | 166 | const u32 *ocotp = mxs_get_ocotp(); |
| 167 | u8 *macaddr; | 167 | u8 *macaddr; |
| 168 | u32 val; | 168 | u32 val; |
| @@ -208,11 +208,7 @@ static void __init update_fec_mac_prop(enum mac_oui oui) | |||
| 208 | macaddr[4] = (val >> 8) & 0xff; | 208 | macaddr[4] = (val >> 8) & 0xff; |
| 209 | macaddr[5] = (val >> 0) & 0xff; | 209 | macaddr[5] = (val >> 0) & 0xff; |
| 210 | 210 | ||
| 211 | oldmac = of_find_property(np, newmac->name, NULL); | 211 | prom_update_property(np, newmac); |
| 212 | if (oldmac) | ||
| 213 | prom_update_property(np, newmac, oldmac); | ||
| 214 | else | ||
| 215 | prom_add_property(np, newmac); | ||
| 216 | } | 212 | } |
| 217 | } | 213 | } |
| 218 | 214 | ||
diff --git a/arch/arm/mach-netx/fb.c b/arch/arm/mach-netx/fb.c index 2cdf6ef69bee..d122ee6ab991 100644 --- a/arch/arm/mach-netx/fb.c +++ b/arch/arm/mach-netx/fb.c | |||
| @@ -69,29 +69,6 @@ void netx_clcd_remove(struct clcd_fb *fb) | |||
| 69 | fb->fb.screen_base, fb->fb.fix.smem_start); | 69 | fb->fb.screen_base, fb->fb.fix.smem_start); |
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | void clk_disable(struct clk *clk) | ||
| 73 | { | ||
| 74 | } | ||
| 75 | |||
| 76 | int clk_set_rate(struct clk *clk, unsigned long rate) | ||
| 77 | { | ||
| 78 | return 0; | ||
| 79 | } | ||
| 80 | |||
| 81 | int clk_enable(struct clk *clk) | ||
| 82 | { | ||
| 83 | return 0; | ||
| 84 | } | ||
| 85 | |||
| 86 | struct clk *clk_get(struct device *dev, const char *id) | ||
| 87 | { | ||
| 88 | return dev && strcmp(dev_name(dev), "fb") == 0 ? NULL : ERR_PTR(-ENOENT); | ||
| 89 | } | ||
| 90 | |||
| 91 | void clk_put(struct clk *clk) | ||
| 92 | { | ||
| 93 | } | ||
| 94 | |||
| 95 | static AMBA_AHB_DEVICE(fb, "fb", 0, 0x00104000, { NETX_IRQ_LCD }, NULL); | 72 | static AMBA_AHB_DEVICE(fb, "fb", 0, 0x00104000, { NETX_IRQ_LCD }, NULL); |
| 96 | 73 | ||
| 97 | int netx_fb_init(struct clcd_board *board, struct clcd_panel *panel) | 74 | int netx_fb_init(struct clcd_board *board, struct clcd_panel *panel) |
diff --git a/arch/arm/mach-omap1/board-palmz71.c b/arch/arm/mach-omap1/board-palmz71.c index cc71a26723ef..355980321c2d 100644 --- a/arch/arm/mach-omap1/board-palmz71.c +++ b/arch/arm/mach-omap1/board-palmz71.c | |||
| @@ -288,8 +288,7 @@ palmz71_gpio_setup(int early) | |||
| 288 | } | 288 | } |
| 289 | gpio_direction_input(PALMZ71_USBDETECT_GPIO); | 289 | gpio_direction_input(PALMZ71_USBDETECT_GPIO); |
| 290 | if (request_irq(gpio_to_irq(PALMZ71_USBDETECT_GPIO), | 290 | if (request_irq(gpio_to_irq(PALMZ71_USBDETECT_GPIO), |
| 291 | palmz71_powercable, IRQF_SAMPLE_RANDOM, | 291 | palmz71_powercable, 0, "palmz71-cable", NULL)) |
| 292 | "palmz71-cable", NULL)) | ||
| 293 | printk(KERN_ERR | 292 | printk(KERN_ERR |
| 294 | "IRQ request for power cable failed!\n"); | 293 | "IRQ request for power cable failed!\n"); |
| 295 | palmz71_powercable(gpio_to_irq(PALMZ71_USBDETECT_GPIO), NULL); | 294 | palmz71_powercable(gpio_to_irq(PALMZ71_USBDETECT_GPIO), NULL); |
diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c index 91b3d5c60bfe..83bed9ad3017 100644 --- a/arch/arm/mach-omap2/clock3xxx_data.c +++ b/arch/arm/mach-omap2/clock3xxx_data.c | |||
| @@ -3376,15 +3376,15 @@ static struct omap_clk omap3xxx_clks[] = { | |||
| 3376 | CLK(NULL, "usbhost_48m_fck", &usbhost_48m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), | 3376 | CLK(NULL, "usbhost_48m_fck", &usbhost_48m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), |
| 3377 | CLK(NULL, "usbhost_ick", &usbhost_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), | 3377 | CLK(NULL, "usbhost_ick", &usbhost_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), |
| 3378 | CLK("usbhs_omap", "usbhost_ick", &usbhost_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), | 3378 | CLK("usbhs_omap", "usbhost_ick", &usbhost_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), |
| 3379 | CLK("usbhs_omap", "utmi_p1_gfclk", &dummy_ck, CK_3XXX), | 3379 | CLK(NULL, "utmi_p1_gfclk", &dummy_ck, CK_3XXX), |
| 3380 | CLK("usbhs_omap", "utmi_p2_gfclk", &dummy_ck, CK_3XXX), | 3380 | CLK(NULL, "utmi_p2_gfclk", &dummy_ck, CK_3XXX), |
| 3381 | CLK("usbhs_omap", "xclk60mhsp1_ck", &dummy_ck, CK_3XXX), | 3381 | CLK(NULL, "xclk60mhsp1_ck", &dummy_ck, CK_3XXX), |
| 3382 | CLK("usbhs_omap", "xclk60mhsp2_ck", &dummy_ck, CK_3XXX), | 3382 | CLK(NULL, "xclk60mhsp2_ck", &dummy_ck, CK_3XXX), |
| 3383 | CLK("usbhs_omap", "usb_host_hs_utmi_p1_clk", &dummy_ck, CK_3XXX), | 3383 | CLK(NULL, "usb_host_hs_utmi_p1_clk", &dummy_ck, CK_3XXX), |
| 3384 | CLK("usbhs_omap", "usb_host_hs_utmi_p2_clk", &dummy_ck, CK_3XXX), | 3384 | CLK(NULL, "usb_host_hs_utmi_p2_clk", &dummy_ck, CK_3XXX), |
| 3385 | CLK("usbhs_omap", "usb_tll_hs_usb_ch0_clk", &dummy_ck, CK_3XXX), | 3385 | CLK("usbhs_omap", "usb_tll_hs_usb_ch0_clk", &dummy_ck, CK_3XXX), |
| 3386 | CLK("usbhs_omap", "usb_tll_hs_usb_ch1_clk", &dummy_ck, CK_3XXX), | 3386 | CLK("usbhs_omap", "usb_tll_hs_usb_ch1_clk", &dummy_ck, CK_3XXX), |
| 3387 | CLK("usbhs_omap", "init_60m_fclk", &dummy_ck, CK_3XXX), | 3387 | CLK(NULL, "init_60m_fclk", &dummy_ck, CK_3XXX), |
| 3388 | CLK(NULL, "usim_fck", &usim_fck, CK_3430ES2PLUS | CK_36XX), | 3388 | CLK(NULL, "usim_fck", &usim_fck, CK_3430ES2PLUS | CK_36XX), |
| 3389 | CLK(NULL, "gpt1_fck", &gpt1_fck, CK_3XXX), | 3389 | CLK(NULL, "gpt1_fck", &gpt1_fck, CK_3XXX), |
| 3390 | CLK(NULL, "wkup_32k_fck", &wkup_32k_fck, CK_3XXX), | 3390 | CLK(NULL, "wkup_32k_fck", &wkup_32k_fck, CK_3XXX), |
diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index 7d118b9bdd5f..9a35adf91232 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c | |||
| @@ -125,7 +125,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) | |||
| 125 | booted = true; | 125 | booted = true; |
| 126 | } | 126 | } |
| 127 | 127 | ||
| 128 | gic_raise_softirq(cpumask_of(cpu), 1); | 128 | gic_raise_softirq(cpumask_of(cpu), 0); |
| 129 | 129 | ||
| 130 | /* | 130 | /* |
| 131 | * Now the secondary core is starting up let it run its | 131 | * Now the secondary core is starting up let it run its |
diff --git a/arch/arm/mach-pxa/eseries.h b/arch/arm/mach-pxa/eseries.h deleted file mode 100644 index b96949dd5adb..000000000000 --- a/arch/arm/mach-pxa/eseries.h +++ /dev/null | |||
| @@ -1,14 +0,0 @@ | |||
| 1 | void __init eseries_fixup(struct tag *tags, char **cmdline, struct meminfo *mi); | ||
| 2 | |||
| 3 | extern struct pxa2xx_udc_mach_info e7xx_udc_mach_info; | ||
| 4 | extern struct pxaficp_platform_data e7xx_ficp_platform_data; | ||
| 5 | extern int e7xx_irda_init(void); | ||
| 6 | |||
| 7 | extern int eseries_tmio_enable(struct platform_device *dev); | ||
| 8 | extern int eseries_tmio_disable(struct platform_device *dev); | ||
| 9 | extern int eseries_tmio_suspend(struct platform_device *dev); | ||
| 10 | extern int eseries_tmio_resume(struct platform_device *dev); | ||
| 11 | extern void eseries_get_tmio_gpios(void); | ||
| 12 | extern struct resource eseries_tmio_resources[]; | ||
| 13 | extern struct platform_device e300_tc6387xb_device; | ||
| 14 | |||
diff --git a/arch/arm/mach-pxa/hx4700.c b/arch/arm/mach-pxa/hx4700.c index d3de84b0dcbe..e6311988add2 100644 --- a/arch/arm/mach-pxa/hx4700.c +++ b/arch/arm/mach-pxa/hx4700.c | |||
| @@ -296,27 +296,11 @@ static struct asic3_led asic3_leds[ASIC3_NUM_LEDS] = { | |||
| 296 | 296 | ||
| 297 | static struct resource asic3_resources[] = { | 297 | static struct resource asic3_resources[] = { |
| 298 | /* GPIO part */ | 298 | /* GPIO part */ |
| 299 | [0] = { | 299 | [0] = DEFINE_RES_MEM(ASIC3_PHYS, ASIC3_MAP_SIZE_16BIT), |
| 300 | .start = ASIC3_PHYS, | 300 | [1] = DEFINE_RES_IRQ(PXA_GPIO_TO_IRQ(GPIO12_HX4700_ASIC3_IRQ)), |
| 301 | .end = ASIC3_PHYS + ASIC3_MAP_SIZE_16BIT - 1, | ||
| 302 | .flags = IORESOURCE_MEM, | ||
| 303 | }, | ||
| 304 | [1] = { | ||
| 305 | .start = PXA_GPIO_TO_IRQ(GPIO12_HX4700_ASIC3_IRQ), | ||
| 306 | .end = PXA_GPIO_TO_IRQ(GPIO12_HX4700_ASIC3_IRQ), | ||
| 307 | .flags = IORESOURCE_IRQ, | ||
| 308 | }, | ||
| 309 | /* SD part */ | 301 | /* SD part */ |
| 310 | [2] = { | 302 | [2] = DEFINE_RES_MEM(ASIC3_SD_PHYS, ASIC3_MAP_SIZE_16BIT), |
| 311 | .start = ASIC3_SD_PHYS, | 303 | [3] = DEFINE_RES_IRQ(PXA_GPIO_TO_IRQ(GPIO66_HX4700_ASIC3_nSDIO_IRQ)), |
| 312 | .end = ASIC3_SD_PHYS + ASIC3_MAP_SIZE_16BIT - 1, | ||
| 313 | .flags = IORESOURCE_MEM, | ||
| 314 | }, | ||
| 315 | [3] = { | ||
| 316 | .start = PXA_GPIO_TO_IRQ(GPIO66_HX4700_ASIC3_nSDIO_IRQ), | ||
| 317 | .end = PXA_GPIO_TO_IRQ(GPIO66_HX4700_ASIC3_nSDIO_IRQ), | ||
| 318 | .flags = IORESOURCE_IRQ, | ||
| 319 | }, | ||
| 320 | }; | 304 | }; |
| 321 | 305 | ||
| 322 | static struct asic3_platform_data asic3_platform_data = { | 306 | static struct asic3_platform_data asic3_platform_data = { |
| @@ -343,11 +327,7 @@ static struct platform_device asic3 = { | |||
| 343 | */ | 327 | */ |
| 344 | 328 | ||
| 345 | static struct resource egpio_resources[] = { | 329 | static struct resource egpio_resources[] = { |
| 346 | [0] = { | 330 | [0] = DEFINE_RES_MEM(PXA_CS5_PHYS, 0x4), |
| 347 | .start = PXA_CS5_PHYS, | ||
| 348 | .end = PXA_CS5_PHYS + 0x4 - 1, | ||
| 349 | .flags = IORESOURCE_MEM, | ||
| 350 | }, | ||
| 351 | }; | 331 | }; |
| 352 | 332 | ||
| 353 | static struct htc_egpio_chip egpio_chips[] = { | 333 | static struct htc_egpio_chip egpio_chips[] = { |
| @@ -537,11 +517,7 @@ static struct w100fb_mach_info w3220_info = { | |||
| 537 | }; | 517 | }; |
| 538 | 518 | ||
| 539 | static struct resource w3220_resources[] = { | 519 | static struct resource w3220_resources[] = { |
| 540 | [0] = { | 520 | [0] = DEFINE_RES_MEM(ATI_W3220_PHYS, SZ_16M), |
| 541 | .start = ATI_W3220_PHYS, | ||
| 542 | .end = ATI_W3220_PHYS + 0x00ffffff, | ||
| 543 | .flags = IORESOURCE_MEM, | ||
| 544 | }, | ||
| 545 | }; | 521 | }; |
| 546 | 522 | ||
| 547 | static struct platform_device w3220 = { | 523 | static struct platform_device w3220 = { |
| @@ -683,20 +659,12 @@ static struct pda_power_pdata power_supply_info = { | |||
| 683 | }; | 659 | }; |
| 684 | 660 | ||
| 685 | static struct resource power_supply_resources[] = { | 661 | static struct resource power_supply_resources[] = { |
| 686 | [0] = { | 662 | [0] = DEFINE_RES_NAMED(PXA_GPIO_TO_IRQ(GPIOD9_nAC_IN), 1, "ac", |
| 687 | .name = "ac", | 663 | IORESOURCE_IRQ | |
| 688 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE | | 664 | IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE), |
| 689 | IORESOURCE_IRQ_LOWEDGE, | 665 | [1] = DEFINE_RES_NAMED(PXA_GPIO_TO_IRQ(GPIOD14_nUSBC_DETECT), 1, "usb", |
| 690 | .start = PXA_GPIO_TO_IRQ(GPIOD9_nAC_IN), | 666 | IORESOURCE_IRQ | |
| 691 | .end = PXA_GPIO_TO_IRQ(GPIOD9_nAC_IN), | 667 | IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE), |
| 692 | }, | ||
| 693 | [1] = { | ||
| 694 | .name = "usb", | ||
| 695 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE | | ||
| 696 | IORESOURCE_IRQ_LOWEDGE, | ||
| 697 | .start = PXA_GPIO_TO_IRQ(GPIOD14_nUSBC_DETECT), | ||
| 698 | .end = PXA_GPIO_TO_IRQ(GPIOD14_nUSBC_DETECT), | ||
| 699 | }, | ||
| 700 | }; | 668 | }; |
| 701 | 669 | ||
| 702 | static struct platform_device power_supply = { | 670 | static struct platform_device power_supply = { |
diff --git a/arch/arm/mach-pxa/include/mach/regs-ost.h b/arch/arm/mach-pxa/include/mach/regs-ost.h index a3e5f86ef67e..628819995c52 100644 --- a/arch/arm/mach-pxa/include/mach/regs-ost.h +++ b/arch/arm/mach-pxa/include/mach/regs-ost.h | |||
| @@ -7,17 +7,17 @@ | |||
| 7 | * OS Timer & Match Registers | 7 | * OS Timer & Match Registers |
| 8 | */ | 8 | */ |
| 9 | 9 | ||
| 10 | #define OSMR0 __REG(0x40A00000) /* */ | 10 | #define OSMR0 io_p2v(0x40A00000) /* */ |
| 11 | #define OSMR1 __REG(0x40A00004) /* */ | 11 | #define OSMR1 io_p2v(0x40A00004) /* */ |
| 12 | #define OSMR2 __REG(0x40A00008) /* */ | 12 | #define OSMR2 io_p2v(0x40A00008) /* */ |
| 13 | #define OSMR3 __REG(0x40A0000C) /* */ | 13 | #define OSMR3 io_p2v(0x40A0000C) /* */ |
| 14 | #define OSMR4 __REG(0x40A00080) /* */ | 14 | #define OSMR4 io_p2v(0x40A00080) /* */ |
| 15 | #define OSCR __REG(0x40A00010) /* OS Timer Counter Register */ | 15 | #define OSCR io_p2v(0x40A00010) /* OS Timer Counter Register */ |
| 16 | #define OSCR4 __REG(0x40A00040) /* OS Timer Counter Register */ | 16 | #define OSCR4 io_p2v(0x40A00040) /* OS Timer Counter Register */ |
| 17 | #define OMCR4 __REG(0x40A000C0) /* */ | 17 | #define OMCR4 io_p2v(0x40A000C0) /* */ |
| 18 | #define OSSR __REG(0x40A00014) /* OS Timer Status Register */ | 18 | #define OSSR io_p2v(0x40A00014) /* OS Timer Status Register */ |
| 19 | #define OWER __REG(0x40A00018) /* OS Timer Watchdog Enable Register */ | 19 | #define OWER io_p2v(0x40A00018) /* OS Timer Watchdog Enable Register */ |
| 20 | #define OIER __REG(0x40A0001C) /* OS Timer Interrupt Enable Register */ | 20 | #define OIER io_p2v(0x40A0001C) /* OS Timer Interrupt Enable Register */ |
| 21 | 21 | ||
| 22 | #define OSSR_M3 (1 << 3) /* Match status channel 3 */ | 22 | #define OSSR_M3 (1 << 3) /* Match status channel 3 */ |
| 23 | #define OSSR_M2 (1 << 2) /* Match status channel 2 */ | 23 | #define OSSR_M2 (1 << 2) /* Match status channel 2 */ |
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index 6bb3f47b1f14..0ca0db787903 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c | |||
| @@ -456,7 +456,7 @@ static int lubbock_mci_init(struct device *dev, | |||
| 456 | init_timer(&mmc_timer); | 456 | init_timer(&mmc_timer); |
| 457 | mmc_timer.data = (unsigned long) data; | 457 | mmc_timer.data = (unsigned long) data; |
| 458 | return request_irq(LUBBOCK_SD_IRQ, lubbock_detect_int, | 458 | return request_irq(LUBBOCK_SD_IRQ, lubbock_detect_int, |
| 459 | IRQF_SAMPLE_RANDOM, "lubbock-sd-detect", data); | 459 | 0, "lubbock-sd-detect", data); |
| 460 | } | 460 | } |
| 461 | 461 | ||
| 462 | static int lubbock_mci_get_ro(struct device *dev) | 462 | static int lubbock_mci_get_ro(struct device *dev) |
diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c index 2db697cd2b4e..39561dcf65f2 100644 --- a/arch/arm/mach-pxa/magician.c +++ b/arch/arm/mach-pxa/magician.c | |||
| @@ -633,9 +633,8 @@ static struct platform_device bq24022 = { | |||
| 633 | static int magician_mci_init(struct device *dev, | 633 | static int magician_mci_init(struct device *dev, |
| 634 | irq_handler_t detect_irq, void *data) | 634 | irq_handler_t detect_irq, void *data) |
| 635 | { | 635 | { |
| 636 | return request_irq(IRQ_MAGICIAN_SD, detect_irq, | 636 | return request_irq(IRQ_MAGICIAN_SD, detect_irq, IRQF_DISABLED, |
| 637 | IRQF_DISABLED | IRQF_SAMPLE_RANDOM, | 637 | "mmc card detect", data); |
| 638 | "mmc card detect", data); | ||
| 639 | } | 638 | } |
| 640 | 639 | ||
| 641 | static void magician_mci_exit(struct device *dev, void *data) | 640 | static void magician_mci_exit(struct device *dev, void *data) |
diff --git a/arch/arm/mach-pxa/reset.c b/arch/arm/mach-pxa/reset.c index b4528899ef08..3fab583755d4 100644 --- a/arch/arm/mach-pxa/reset.c +++ b/arch/arm/mach-pxa/reset.c | |||
| @@ -77,9 +77,10 @@ static void do_gpio_reset(void) | |||
| 77 | static void do_hw_reset(void) | 77 | static void do_hw_reset(void) |
| 78 | { | 78 | { |
| 79 | /* Initialize the watchdog and let it fire */ | 79 | /* Initialize the watchdog and let it fire */ |
| 80 | OWER = OWER_WME; | 80 | writel_relaxed(OWER_WME, OWER); |
| 81 | OSSR = OSSR_M3; | 81 | writel_relaxed(OSSR_M3, OSSR); |
| 82 | OSMR3 = OSCR + 368640; /* ... in 100 ms */ | 82 | /* ... in 100 ms */ |
| 83 | writel_relaxed(readl_relaxed(OSCR) + 368640, OSMR3); | ||
| 83 | } | 84 | } |
| 84 | 85 | ||
| 85 | void pxa_restart(char mode, const char *cmd) | 86 | void pxa_restart(char mode, const char *cmd) |
diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c index 3d6c9bd90de6..4bc47d63698b 100644 --- a/arch/arm/mach-pxa/time.c +++ b/arch/arm/mach-pxa/time.c | |||
| @@ -35,7 +35,7 @@ | |||
| 35 | 35 | ||
| 36 | static u32 notrace pxa_read_sched_clock(void) | 36 | static u32 notrace pxa_read_sched_clock(void) |
| 37 | { | 37 | { |
| 38 | return OSCR; | 38 | return readl_relaxed(OSCR); |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | 41 | ||
| @@ -47,8 +47,8 @@ pxa_ost0_interrupt(int irq, void *dev_id) | |||
| 47 | struct clock_event_device *c = dev_id; | 47 | struct clock_event_device *c = dev_id; |
| 48 | 48 | ||
| 49 | /* Disarm the compare/match, signal the event. */ | 49 | /* Disarm the compare/match, signal the event. */ |
| 50 | OIER &= ~OIER_E0; | 50 | writel_relaxed(readl_relaxed(OIER) & ~OIER_E0, OIER); |
| 51 | OSSR = OSSR_M0; | 51 | writel_relaxed(OSSR_M0, OSSR); |
| 52 | c->event_handler(c); | 52 | c->event_handler(c); |
| 53 | 53 | ||
| 54 | return IRQ_HANDLED; | 54 | return IRQ_HANDLED; |
| @@ -59,10 +59,10 @@ pxa_osmr0_set_next_event(unsigned long delta, struct clock_event_device *dev) | |||
| 59 | { | 59 | { |
| 60 | unsigned long next, oscr; | 60 | unsigned long next, oscr; |
| 61 | 61 | ||
| 62 | OIER |= OIER_E0; | 62 | writel_relaxed(readl_relaxed(OIER) | OIER_E0, OIER); |
| 63 | next = OSCR + delta; | 63 | next = readl_relaxed(OSCR) + delta; |
| 64 | OSMR0 = next; | 64 | writel_relaxed(next, OSMR0); |
| 65 | oscr = OSCR; | 65 | oscr = readl_relaxed(OSCR); |
| 66 | 66 | ||
| 67 | return (signed)(next - oscr) <= MIN_OSCR_DELTA ? -ETIME : 0; | 67 | return (signed)(next - oscr) <= MIN_OSCR_DELTA ? -ETIME : 0; |
| 68 | } | 68 | } |
| @@ -72,15 +72,15 @@ pxa_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *dev) | |||
| 72 | { | 72 | { |
| 73 | switch (mode) { | 73 | switch (mode) { |
| 74 | case CLOCK_EVT_MODE_ONESHOT: | 74 | case CLOCK_EVT_MODE_ONESHOT: |
| 75 | OIER &= ~OIER_E0; | 75 | writel_relaxed(readl_relaxed(OIER) & ~OIER_E0, OIER); |
| 76 | OSSR = OSSR_M0; | 76 | writel_relaxed(OSSR_M0, OSSR); |
| 77 | break; | 77 | break; |
| 78 | 78 | ||
| 79 | case CLOCK_EVT_MODE_UNUSED: | 79 | case CLOCK_EVT_MODE_UNUSED: |
| 80 | case CLOCK_EVT_MODE_SHUTDOWN: | 80 | case CLOCK_EVT_MODE_SHUTDOWN: |
| 81 | /* initializing, released, or preparing for suspend */ | 81 | /* initializing, released, or preparing for suspend */ |
| 82 | OIER &= ~OIER_E0; | 82 | writel_relaxed(readl_relaxed(OIER) & ~OIER_E0, OIER); |
| 83 | OSSR = OSSR_M0; | 83 | writel_relaxed(OSSR_M0, OSSR); |
| 84 | break; | 84 | break; |
| 85 | 85 | ||
| 86 | case CLOCK_EVT_MODE_RESUME: | 86 | case CLOCK_EVT_MODE_RESUME: |
| @@ -108,8 +108,8 @@ static void __init pxa_timer_init(void) | |||
| 108 | { | 108 | { |
| 109 | unsigned long clock_tick_rate = get_clock_tick_rate(); | 109 | unsigned long clock_tick_rate = get_clock_tick_rate(); |
| 110 | 110 | ||
| 111 | OIER = 0; | 111 | writel_relaxed(0, OIER); |
| 112 | OSSR = OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3; | 112 | writel_relaxed(OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3, OSSR); |
| 113 | 113 | ||
| 114 | setup_sched_clock(pxa_read_sched_clock, 32, clock_tick_rate); | 114 | setup_sched_clock(pxa_read_sched_clock, 32, clock_tick_rate); |
| 115 | 115 | ||
| @@ -122,7 +122,7 @@ static void __init pxa_timer_init(void) | |||
| 122 | 122 | ||
| 123 | setup_irq(IRQ_OST0, &pxa_ost0_irq); | 123 | setup_irq(IRQ_OST0, &pxa_ost0_irq); |
| 124 | 124 | ||
| 125 | clocksource_mmio_init(&OSCR, "oscr0", clock_tick_rate, 200, 32, | 125 | clocksource_mmio_init(OSCR, "oscr0", clock_tick_rate, 200, 32, |
| 126 | clocksource_mmio_readl_up); | 126 | clocksource_mmio_readl_up); |
| 127 | clockevents_register_device(&ckevt_pxa_osmr0); | 127 | clockevents_register_device(&ckevt_pxa_osmr0); |
| 128 | } | 128 | } |
| @@ -132,12 +132,12 @@ static unsigned long osmr[4], oier, oscr; | |||
| 132 | 132 | ||
| 133 | static void pxa_timer_suspend(void) | 133 | static void pxa_timer_suspend(void) |
| 134 | { | 134 | { |
| 135 | osmr[0] = OSMR0; | 135 | osmr[0] = readl_relaxed(OSMR0); |
| 136 | osmr[1] = OSMR1; | 136 | osmr[1] = readl_relaxed(OSMR1); |
| 137 | osmr[2] = OSMR2; | 137 | osmr[2] = readl_relaxed(OSMR2); |
| 138 | osmr[3] = OSMR3; | 138 | osmr[3] = readl_relaxed(OSMR3); |
| 139 | oier = OIER; | 139 | oier = readl_relaxed(OIER); |
| 140 | oscr = OSCR; | 140 | oscr = readl_relaxed(OSCR); |
| 141 | } | 141 | } |
| 142 | 142 | ||
| 143 | static void pxa_timer_resume(void) | 143 | static void pxa_timer_resume(void) |
| @@ -151,12 +151,12 @@ static void pxa_timer_resume(void) | |||
| 151 | if (osmr[0] - oscr < MIN_OSCR_DELTA) | 151 | if (osmr[0] - oscr < MIN_OSCR_DELTA) |
| 152 | osmr[0] += MIN_OSCR_DELTA; | 152 | osmr[0] += MIN_OSCR_DELTA; |
| 153 | 153 | ||
| 154 | OSMR0 = osmr[0]; | 154 | writel_relaxed(osmr[0], OSMR0); |
| 155 | OSMR1 = osmr[1]; | 155 | writel_relaxed(osmr[1], OSMR1); |
| 156 | OSMR2 = osmr[2]; | 156 | writel_relaxed(osmr[2], OSMR2); |
| 157 | OSMR3 = osmr[3]; | 157 | writel_relaxed(osmr[3], OSMR3); |
| 158 | OIER = oier; | 158 | writel_relaxed(oier, OIER); |
| 159 | OSCR = oscr; | 159 | writel_relaxed(oscr, OSCR); |
| 160 | } | 160 | } |
| 161 | #else | 161 | #else |
| 162 | #define pxa_timer_suspend NULL | 162 | #define pxa_timer_suspend NULL |
diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c index 2b6ac00b2cd9..166dd32cc1d3 100644 --- a/arch/arm/mach-pxa/trizeps4.c +++ b/arch/arm/mach-pxa/trizeps4.c | |||
| @@ -332,8 +332,8 @@ static int trizeps4_mci_init(struct device *dev, irq_handler_t mci_detect_int, | |||
| 332 | int err; | 332 | int err; |
| 333 | 333 | ||
| 334 | err = request_irq(TRIZEPS4_MMC_IRQ, mci_detect_int, | 334 | err = request_irq(TRIZEPS4_MMC_IRQ, mci_detect_int, |
| 335 | IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_SAMPLE_RANDOM, | 335 | IRQF_DISABLED | IRQF_TRIGGER_RISING, |
| 336 | "MMC card detect", data); | 336 | "MMC card detect", data); |
| 337 | if (err) { | 337 | if (err) { |
| 338 | printk(KERN_ERR "trizeps4_mci_init: MMC/SD: can't request" | 338 | printk(KERN_ERR "trizeps4_mci_init: MMC/SD: can't request" |
| 339 | "MMC card detect IRQ\n"); | 339 | "MMC card detect IRQ\n"); |
diff --git a/arch/arm/mach-s3c64xx/include/mach/pm-core.h b/arch/arm/mach-s3c64xx/include/mach/pm-core.h index fcf3dcabb694..c0537f40a3d8 100644 --- a/arch/arm/mach-s3c64xx/include/mach/pm-core.h +++ b/arch/arm/mach-s3c64xx/include/mach/pm-core.h | |||
| @@ -12,6 +12,9 @@ | |||
| 12 | * published by the Free Software Foundation. | 12 | * published by the Free Software Foundation. |
| 13 | */ | 13 | */ |
| 14 | 14 | ||
| 15 | #ifndef __MACH_S3C64XX_PM_CORE_H | ||
| 16 | #define __MACH_S3C64XX_PM_CORE_H __FILE__ | ||
| 17 | |||
| 15 | #include <mach/regs-gpio.h> | 18 | #include <mach/regs-gpio.h> |
| 16 | 19 | ||
| 17 | static inline void s3c_pm_debug_init_uart(void) | 20 | static inline void s3c_pm_debug_init_uart(void) |
| @@ -113,3 +116,4 @@ static inline void samsung_pm_saved_gpios(void) | |||
| 113 | 116 | ||
| 114 | __raw_writel(S3C64XX_SLPEN_USE_xSLP, S3C64XX_SLPEN); | 117 | __raw_writel(S3C64XX_SLPEN_USE_xSLP, S3C64XX_SLPEN); |
| 115 | } | 118 | } |
| 119 | #endif /* __MACH_S3C64XX_PM_CORE_H */ | ||
diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c index d1dc7f1a239c..d673211f121c 100644 --- a/arch/arm/mach-sa1100/assabet.c +++ b/arch/arm/mach-sa1100/assabet.c | |||
| @@ -362,7 +362,7 @@ static void __init assabet_init(void) | |||
| 362 | static void __init map_sa1100_gpio_regs( void ) | 362 | static void __init map_sa1100_gpio_regs( void ) |
| 363 | { | 363 | { |
| 364 | unsigned long phys = __PREG(GPLR) & PMD_MASK; | 364 | unsigned long phys = __PREG(GPLR) & PMD_MASK; |
| 365 | unsigned long virt = io_p2v(phys); | 365 | unsigned long virt = (unsigned long)io_p2v(phys); |
| 366 | int prot = PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_DOMAIN(DOMAIN_IO); | 366 | int prot = PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_DOMAIN(DOMAIN_IO); |
| 367 | pmd_t *pmd; | 367 | pmd_t *pmd; |
| 368 | 368 | ||
diff --git a/arch/arm/mach-sa1100/cpu-sa1100.c b/arch/arm/mach-sa1100/cpu-sa1100.c index 19b2053f5af4..e8f4d1e19233 100644 --- a/arch/arm/mach-sa1100/cpu-sa1100.c +++ b/arch/arm/mach-sa1100/cpu-sa1100.c | |||
| @@ -87,6 +87,7 @@ | |||
| 87 | #include <linux/types.h> | 87 | #include <linux/types.h> |
| 88 | #include <linux/init.h> | 88 | #include <linux/init.h> |
| 89 | #include <linux/cpufreq.h> | 89 | #include <linux/cpufreq.h> |
| 90 | #include <linux/io.h> | ||
| 90 | 91 | ||
| 91 | #include <asm/cputype.h> | 92 | #include <asm/cputype.h> |
| 92 | 93 | ||
diff --git a/arch/arm/mach-sa1100/cpu-sa1110.c b/arch/arm/mach-sa1100/cpu-sa1110.c index 675bf8ef97e8..48c45b0c92bb 100644 --- a/arch/arm/mach-sa1100/cpu-sa1110.c +++ b/arch/arm/mach-sa1100/cpu-sa1110.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <linux/cpufreq.h> | 19 | #include <linux/cpufreq.h> |
| 20 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
| 21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
| 22 | #include <linux/io.h> | ||
| 22 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
| 23 | #include <linux/moduleparam.h> | 24 | #include <linux/moduleparam.h> |
| 24 | #include <linux/types.h> | 25 | #include <linux/types.h> |
diff --git a/arch/arm/mach-sa1100/include/mach/SA-1100.h b/arch/arm/mach-sa1100/include/mach/SA-1100.h index 3f2d1b60188c..0ac6cc08a19c 100644 --- a/arch/arm/mach-sa1100/include/mach/SA-1100.h +++ b/arch/arm/mach-sa1100/include/mach/SA-1100.h | |||
| @@ -830,14 +830,14 @@ | |||
| 830 | * (read/write). | 830 | * (read/write). |
| 831 | */ | 831 | */ |
| 832 | 832 | ||
| 833 | #define OSMR0 __REG(0x90000000) /* OS timer Match Reg. 0 */ | 833 | #define OSMR0 io_p2v(0x90000000) /* OS timer Match Reg. 0 */ |
| 834 | #define OSMR1 __REG(0x90000004) /* OS timer Match Reg. 1 */ | 834 | #define OSMR1 io_p2v(0x90000004) /* OS timer Match Reg. 1 */ |
| 835 | #define OSMR2 __REG(0x90000008) /* OS timer Match Reg. 2 */ | 835 | #define OSMR2 io_p2v(0x90000008) /* OS timer Match Reg. 2 */ |
| 836 | #define OSMR3 __REG(0x9000000c) /* OS timer Match Reg. 3 */ | 836 | #define OSMR3 io_p2v(0x9000000c) /* OS timer Match Reg. 3 */ |
| 837 | #define OSCR __REG(0x90000010) /* OS timer Counter Reg. */ | 837 | #define OSCR io_p2v(0x90000010) /* OS timer Counter Reg. */ |
| 838 | #define OSSR __REG(0x90000014 ) /* OS timer Status Reg. */ | 838 | #define OSSR io_p2v(0x90000014) /* OS timer Status Reg. */ |
| 839 | #define OWER __REG(0x90000018 ) /* OS timer Watch-dog Enable Reg. */ | 839 | #define OWER io_p2v(0x90000018) /* OS timer Watch-dog Enable Reg. */ |
| 840 | #define OIER __REG(0x9000001C ) /* OS timer Interrupt Enable Reg. */ | 840 | #define OIER io_p2v(0x9000001C) /* OS timer Interrupt Enable Reg. */ |
| 841 | 841 | ||
| 842 | #define OSSR_M(Nb) /* Match detected [0..3] */ \ | 842 | #define OSSR_M(Nb) /* Match detected [0..3] */ \ |
| 843 | (0x00000001 << (Nb)) | 843 | (0x00000001 << (Nb)) |
diff --git a/arch/arm/mach-sa1100/include/mach/gpio.h b/arch/arm/mach-sa1100/include/mach/gpio.h index a38fc4f54241..6a9eecf3137e 100644 --- a/arch/arm/mach-sa1100/include/mach/gpio.h +++ b/arch/arm/mach-sa1100/include/mach/gpio.h | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #ifndef __ASM_ARCH_SA1100_GPIO_H | 24 | #ifndef __ASM_ARCH_SA1100_GPIO_H |
| 25 | #define __ASM_ARCH_SA1100_GPIO_H | 25 | #define __ASM_ARCH_SA1100_GPIO_H |
| 26 | 26 | ||
| 27 | #include <linux/io.h> | ||
| 27 | #include <mach/hardware.h> | 28 | #include <mach/hardware.h> |
| 28 | #include <asm/irq.h> | 29 | #include <asm/irq.h> |
| 29 | #include <asm-generic/gpio.h> | 30 | #include <asm-generic/gpio.h> |
diff --git a/arch/arm/mach-sa1100/include/mach/hardware.h b/arch/arm/mach-sa1100/include/mach/hardware.h index 99f5856d8de4..cbedd75a9d65 100644 --- a/arch/arm/mach-sa1100/include/mach/hardware.h +++ b/arch/arm/mach-sa1100/include/mach/hardware.h | |||
| @@ -32,7 +32,7 @@ | |||
| 32 | #define PIO_START 0x80000000 /* physical start of IO space */ | 32 | #define PIO_START 0x80000000 /* physical start of IO space */ |
| 33 | 33 | ||
| 34 | #define io_p2v( x ) \ | 34 | #define io_p2v( x ) \ |
| 35 | ( (((x)&0x00ffffff) | (((x)&0x30000000)>>VIO_SHIFT)) + VIO_BASE ) | 35 | IOMEM( (((x)&0x00ffffff) | (((x)&0x30000000)>>VIO_SHIFT)) + VIO_BASE ) |
| 36 | #define io_v2p( x ) \ | 36 | #define io_v2p( x ) \ |
| 37 | ( (((x)&0x00ffffff) | (((x)&(0x30000000>>VIO_SHIFT))<<VIO_SHIFT)) + PIO_START ) | 37 | ( (((x)&0x00ffffff) | (((x)&(0x30000000>>VIO_SHIFT))<<VIO_SHIFT)) + PIO_START ) |
| 38 | 38 | ||
| @@ -47,6 +47,8 @@ | |||
| 47 | #define CPU_SA1110_ID (0x6901b110) | 47 | #define CPU_SA1110_ID (0x6901b110) |
| 48 | #define CPU_SA1110_MASK (0xfffffff0) | 48 | #define CPU_SA1110_MASK (0xfffffff0) |
| 49 | 49 | ||
| 50 | #define __MREG(x) IOMEM(io_p2v(x)) | ||
| 51 | |||
| 50 | #ifndef __ASSEMBLY__ | 52 | #ifndef __ASSEMBLY__ |
| 51 | 53 | ||
| 52 | #include <asm/cputype.h> | 54 | #include <asm/cputype.h> |
| @@ -56,7 +58,7 @@ | |||
| 56 | #define cpu_is_sa1100() ((read_cpuid_id() & CPU_SA1100_MASK) == CPU_SA1100_ID) | 58 | #define cpu_is_sa1100() ((read_cpuid_id() & CPU_SA1100_MASK) == CPU_SA1100_ID) |
| 57 | #define cpu_is_sa1110() ((read_cpuid_id() & CPU_SA1110_MASK) == CPU_SA1110_ID) | 59 | #define cpu_is_sa1110() ((read_cpuid_id() & CPU_SA1110_MASK) == CPU_SA1110_ID) |
| 58 | 60 | ||
| 59 | # define __REG(x) (*((volatile unsigned long *)io_p2v(x))) | 61 | # define __REG(x) (*((volatile unsigned long __iomem *)io_p2v(x))) |
| 60 | # define __PREG(x) (io_v2p((unsigned long)&(x))) | 62 | # define __PREG(x) (io_v2p((unsigned long)&(x))) |
| 61 | 63 | ||
| 62 | static inline unsigned long get_clock_tick_rate(void) | 64 | static inline unsigned long get_clock_tick_rate(void) |
diff --git a/arch/arm/mach-sa1100/include/mach/uncompress.h b/arch/arm/mach-sa1100/include/mach/uncompress.h index 6cb39ddde656..5cf71da60e42 100644 --- a/arch/arm/mach-sa1100/include/mach/uncompress.h +++ b/arch/arm/mach-sa1100/include/mach/uncompress.h | |||
| @@ -8,6 +8,8 @@ | |||
| 8 | 8 | ||
| 9 | #include "hardware.h" | 9 | #include "hardware.h" |
| 10 | 10 | ||
| 11 | #define IOMEM(x) (x) | ||
| 12 | |||
| 11 | /* | 13 | /* |
| 12 | * The following code assumes the serial port has already been | 14 | * The following code assumes the serial port has already been |
| 13 | * initialized by the bootloader. We search for the first enabled | 15 | * initialized by the bootloader. We search for the first enabled |
diff --git a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c index 516ccc25d7fd..2124f1fc2fbe 100644 --- a/arch/arm/mach-sa1100/irq.c +++ b/arch/arm/mach-sa1100/irq.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
| 13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
| 14 | #include <linux/interrupt.h> | 14 | #include <linux/interrupt.h> |
| 15 | #include <linux/io.h> | ||
| 15 | #include <linux/irq.h> | 16 | #include <linux/irq.h> |
| 16 | #include <linux/ioport.h> | 17 | #include <linux/ioport.h> |
| 17 | #include <linux/syscore_ops.h> | 18 | #include <linux/syscore_ops.h> |
diff --git a/arch/arm/mach-sa1100/jornada720_ssp.c b/arch/arm/mach-sa1100/jornada720_ssp.c index b412fc09c80c..7f07f08d8968 100644 --- a/arch/arm/mach-sa1100/jornada720_ssp.c +++ b/arch/arm/mach-sa1100/jornada720_ssp.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
| 19 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
| 20 | #include <linux/sched.h> | 20 | #include <linux/sched.h> |
| 21 | #include <linux/io.h> | ||
| 21 | 22 | ||
| 22 | #include <mach/hardware.h> | 23 | #include <mach/hardware.h> |
| 23 | #include <mach/jornada720.h> | 24 | #include <mach/jornada720.h> |
diff --git a/arch/arm/mach-sa1100/leds-cerf.c b/arch/arm/mach-sa1100/leds-cerf.c index 040540fb7d8a..30fc3b2bf555 100644 --- a/arch/arm/mach-sa1100/leds-cerf.c +++ b/arch/arm/mach-sa1100/leds-cerf.c | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | * Author: ??? | 4 | * Author: ??? |
| 5 | */ | 5 | */ |
| 6 | #include <linux/init.h> | 6 | #include <linux/init.h> |
| 7 | #include <linux/io.h> | ||
| 7 | 8 | ||
| 8 | #include <mach/hardware.h> | 9 | #include <mach/hardware.h> |
| 9 | #include <asm/leds.h> | 10 | #include <asm/leds.h> |
diff --git a/arch/arm/mach-sa1100/leds-lart.c b/arch/arm/mach-sa1100/leds-lart.c index a51830c60e53..50a5b143b460 100644 --- a/arch/arm/mach-sa1100/leds-lart.c +++ b/arch/arm/mach-sa1100/leds-lart.c | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | * pace of the LED. | 10 | * pace of the LED. |
| 11 | */ | 11 | */ |
| 12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
| 13 | #include <linux/io.h> | ||
| 13 | 14 | ||
| 14 | #include <mach/hardware.h> | 15 | #include <mach/hardware.h> |
| 15 | #include <asm/leds.h> | 16 | #include <asm/leds.h> |
diff --git a/arch/arm/mach-sa1100/pm.c b/arch/arm/mach-sa1100/pm.c index 690cf0ce5c0c..6645d1e31f14 100644 --- a/arch/arm/mach-sa1100/pm.c +++ b/arch/arm/mach-sa1100/pm.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | * Storage is local on the stack now. | 23 | * Storage is local on the stack now. |
| 24 | */ | 24 | */ |
| 25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
| 26 | #include <linux/io.h> | ||
| 26 | #include <linux/suspend.h> | 27 | #include <linux/suspend.h> |
| 27 | #include <linux/errno.h> | 28 | #include <linux/errno.h> |
| 28 | #include <linux/time.h> | 29 | #include <linux/time.h> |
diff --git a/arch/arm/mach-sa1100/sleep.S b/arch/arm/mach-sa1100/sleep.S index 30cc6721665b..85863741ef8b 100644 --- a/arch/arm/mach-sa1100/sleep.S +++ b/arch/arm/mach-sa1100/sleep.S | |||
| @@ -38,9 +38,9 @@ ENTRY(sa1100_finish_suspend) | |||
| 38 | orr r4, r4, #MDREFR_K1DB2 | 38 | orr r4, r4, #MDREFR_K1DB2 |
| 39 | ldr r5, =PPCR | 39 | ldr r5, =PPCR |
| 40 | 40 | ||
| 41 | @ Pre-load __udelay into the I-cache | 41 | @ Pre-load __loop_udelay into the I-cache |
| 42 | mov r0, #1 | 42 | mov r0, #1 |
| 43 | bl __udelay | 43 | bl __loop_udelay |
| 44 | mov r0, r0 | 44 | mov r0, r0 |
| 45 | 45 | ||
| 46 | @ The following must all exist in a single cache line to | 46 | @ The following must all exist in a single cache line to |
| @@ -53,11 +53,11 @@ ENTRY(sa1100_finish_suspend) | |||
| 53 | @ delay 90us and set CPU PLL to lowest speed | 53 | @ delay 90us and set CPU PLL to lowest speed |
| 54 | @ fixes resume problem on high speed SA1110 | 54 | @ fixes resume problem on high speed SA1110 |
| 55 | mov r0, #90 | 55 | mov r0, #90 |
| 56 | bl __udelay | 56 | bl __loop_udelay |
| 57 | mov r1, #0 | 57 | mov r1, #0 |
| 58 | str r1, [r5] | 58 | str r1, [r5] |
| 59 | mov r0, #90 | 59 | mov r0, #90 |
| 60 | bl __udelay | 60 | bl __loop_udelay |
| 61 | 61 | ||
| 62 | /* | 62 | /* |
| 63 | * SA1110 SDRAM controller workaround. register values: | 63 | * SA1110 SDRAM controller workaround. register values: |
diff --git a/arch/arm/mach-sa1100/time.c b/arch/arm/mach-sa1100/time.c index 6af26e8d55e6..80702c9ecc77 100644 --- a/arch/arm/mach-sa1100/time.c +++ b/arch/arm/mach-sa1100/time.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | 22 | ||
| 23 | static u32 notrace sa1100_read_sched_clock(void) | 23 | static u32 notrace sa1100_read_sched_clock(void) |
| 24 | { | 24 | { |
| 25 | return OSCR; | 25 | return readl_relaxed(OSCR); |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | #define MIN_OSCR_DELTA 2 | 28 | #define MIN_OSCR_DELTA 2 |
| @@ -32,8 +32,8 @@ static irqreturn_t sa1100_ost0_interrupt(int irq, void *dev_id) | |||
| 32 | struct clock_event_device *c = dev_id; | 32 | struct clock_event_device *c = dev_id; |
| 33 | 33 | ||
| 34 | /* Disarm the compare/match, signal the event. */ | 34 | /* Disarm the compare/match, signal the event. */ |
| 35 | OIER &= ~OIER_E0; | 35 | writel_relaxed(readl_relaxed(OIER) & ~OIER_E0, OIER); |
| 36 | OSSR = OSSR_M0; | 36 | writel_relaxed(OSSR_M0, OSSR); |
| 37 | c->event_handler(c); | 37 | c->event_handler(c); |
| 38 | 38 | ||
| 39 | return IRQ_HANDLED; | 39 | return IRQ_HANDLED; |
| @@ -44,10 +44,10 @@ sa1100_osmr0_set_next_event(unsigned long delta, struct clock_event_device *c) | |||
| 44 | { | 44 | { |
| 45 | unsigned long next, oscr; | 45 | unsigned long next, oscr; |
| 46 | 46 | ||
| 47 | OIER |= OIER_E0; | 47 | writel_relaxed(readl_relaxed(OIER) | OIER_E0, OIER); |
| 48 | next = OSCR + delta; | 48 | next = readl_relaxed(OSCR) + delta; |
| 49 | OSMR0 = next; | 49 | writel_relaxed(next, OSMR0); |
| 50 | oscr = OSCR; | 50 | oscr = readl_relaxed(OSCR); |
| 51 | 51 | ||
| 52 | return (signed)(next - oscr) <= MIN_OSCR_DELTA ? -ETIME : 0; | 52 | return (signed)(next - oscr) <= MIN_OSCR_DELTA ? -ETIME : 0; |
| 53 | } | 53 | } |
| @@ -59,8 +59,8 @@ sa1100_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *c) | |||
| 59 | case CLOCK_EVT_MODE_ONESHOT: | 59 | case CLOCK_EVT_MODE_ONESHOT: |
| 60 | case CLOCK_EVT_MODE_UNUSED: | 60 | case CLOCK_EVT_MODE_UNUSED: |
| 61 | case CLOCK_EVT_MODE_SHUTDOWN: | 61 | case CLOCK_EVT_MODE_SHUTDOWN: |
| 62 | OIER &= ~OIER_E0; | 62 | writel_relaxed(readl_relaxed(OIER) & ~OIER_E0, OIER); |
| 63 | OSSR = OSSR_M0; | 63 | writel_relaxed(OSSR_M0, OSSR); |
| 64 | break; | 64 | break; |
| 65 | 65 | ||
| 66 | case CLOCK_EVT_MODE_RESUME: | 66 | case CLOCK_EVT_MODE_RESUME: |
| @@ -86,8 +86,8 @@ static struct irqaction sa1100_timer_irq = { | |||
| 86 | 86 | ||
| 87 | static void __init sa1100_timer_init(void) | 87 | static void __init sa1100_timer_init(void) |
| 88 | { | 88 | { |
| 89 | OIER = 0; | 89 | writel_relaxed(0, OIER); |
| 90 | OSSR = OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3; | 90 | writel_relaxed(OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3, OSSR); |
| 91 | 91 | ||
| 92 | setup_sched_clock(sa1100_read_sched_clock, 32, 3686400); | 92 | setup_sched_clock(sa1100_read_sched_clock, 32, 3686400); |
| 93 | 93 | ||
| @@ -100,7 +100,7 @@ static void __init sa1100_timer_init(void) | |||
| 100 | 100 | ||
| 101 | setup_irq(IRQ_OST0, &sa1100_timer_irq); | 101 | setup_irq(IRQ_OST0, &sa1100_timer_irq); |
| 102 | 102 | ||
| 103 | clocksource_mmio_init(&OSCR, "oscr", CLOCK_TICK_RATE, 200, 32, | 103 | clocksource_mmio_init(OSCR, "oscr", CLOCK_TICK_RATE, 200, 32, |
| 104 | clocksource_mmio_readl_up); | 104 | clocksource_mmio_readl_up); |
| 105 | clockevents_register_device(&ckevt_sa1100_osmr0); | 105 | clockevents_register_device(&ckevt_sa1100_osmr0); |
| 106 | } | 106 | } |
| @@ -110,26 +110,26 @@ unsigned long osmr[4], oier; | |||
| 110 | 110 | ||
| 111 | static void sa1100_timer_suspend(void) | 111 | static void sa1100_timer_suspend(void) |
| 112 | { | 112 | { |
| 113 | osmr[0] = OSMR0; | 113 | osmr[0] = readl_relaxed(OSMR0); |
| 114 | osmr[1] = OSMR1; | 114 | osmr[1] = readl_relaxed(OSMR1); |
| 115 | osmr[2] = OSMR2; | 115 | osmr[2] = readl_relaxed(OSMR2); |
| 116 | osmr[3] = OSMR3; | 116 | osmr[3] = readl_relaxed(OSMR3); |
| 117 | oier = OIER; | 117 | oier = readl_relaxed(OIER); |
| 118 | } | 118 | } |
| 119 | 119 | ||
| 120 | static void sa1100_timer_resume(void) | 120 | static void sa1100_timer_resume(void) |
| 121 | { | 121 | { |
| 122 | OSSR = 0x0f; | 122 | writel_relaxed(0x0f, OSSR); |
| 123 | OSMR0 = osmr[0]; | 123 | writel_relaxed(osmr[0], OSMR0); |
| 124 | OSMR1 = osmr[1]; | 124 | writel_relaxed(osmr[1], OSMR1); |
| 125 | OSMR2 = osmr[2]; | 125 | writel_relaxed(osmr[2], OSMR2); |
| 126 | OSMR3 = osmr[3]; | 126 | writel_relaxed(osmr[3], OSMR3); |
| 127 | OIER = oier; | 127 | writel_relaxed(oier, OIER); |
| 128 | 128 | ||
| 129 | /* | 129 | /* |
| 130 | * OSMR0 is the system timer: make sure OSCR is sufficiently behind | 130 | * OSMR0 is the system timer: make sure OSCR is sufficiently behind |
| 131 | */ | 131 | */ |
| 132 | OSCR = OSMR0 - LATCH; | 132 | writel_relaxed(OSMR0 - LATCH, OSCR); |
| 133 | } | 133 | } |
| 134 | #else | 134 | #else |
| 135 | #define sa1100_timer_suspend NULL | 135 | #define sa1100_timer_suspend NULL |
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig index df33909205e2..4cacc2d22fbe 100644 --- a/arch/arm/mach-shmobile/Kconfig +++ b/arch/arm/mach-shmobile/Kconfig | |||
| @@ -19,6 +19,7 @@ config ARCH_SH7372 | |||
| 19 | select CPU_V7 | 19 | select CPU_V7 |
| 20 | select SH_CLK_CPG | 20 | select SH_CLK_CPG |
| 21 | select ARCH_WANT_OPTIONAL_GPIOLIB | 21 | select ARCH_WANT_OPTIONAL_GPIOLIB |
| 22 | select ARM_CPU_SUSPEND if PM || CPU_IDLE | ||
| 22 | 23 | ||
| 23 | config ARCH_SH73A0 | 24 | config ARCH_SH73A0 |
| 24 | bool "SH-Mobile AG5 (R8A73A00)" | 25 | bool "SH-Mobile AG5 (R8A73A00)" |
| @@ -58,6 +59,7 @@ config MACH_G4EVM | |||
| 58 | bool "G4EVM board" | 59 | bool "G4EVM board" |
| 59 | depends on ARCH_SH7377 | 60 | depends on ARCH_SH7377 |
| 60 | select ARCH_REQUIRE_GPIOLIB | 61 | select ARCH_REQUIRE_GPIOLIB |
| 62 | select REGULATOR_FIXED_VOLTAGE if REGULATOR | ||
| 61 | 63 | ||
| 62 | config MACH_AP4EVB | 64 | config MACH_AP4EVB |
| 63 | bool "AP4EVB board" | 65 | bool "AP4EVB board" |
| @@ -65,6 +67,7 @@ config MACH_AP4EVB | |||
| 65 | select ARCH_REQUIRE_GPIOLIB | 67 | select ARCH_REQUIRE_GPIOLIB |
| 66 | select SH_LCD_MIPI_DSI | 68 | select SH_LCD_MIPI_DSI |
| 67 | select SND_SOC_AK4642 if SND_SIMPLE_CARD | 69 | select SND_SOC_AK4642 if SND_SIMPLE_CARD |
| 70 | select REGULATOR_FIXED_VOLTAGE if REGULATOR | ||
| 68 | 71 | ||
| 69 | choice | 72 | choice |
| 70 | prompt "AP4EVB LCD panel selection" | 73 | prompt "AP4EVB LCD panel selection" |
| @@ -83,6 +86,7 @@ config MACH_AG5EVM | |||
| 83 | bool "AG5EVM board" | 86 | bool "AG5EVM board" |
| 84 | select ARCH_REQUIRE_GPIOLIB | 87 | select ARCH_REQUIRE_GPIOLIB |
| 85 | select SH_LCD_MIPI_DSI | 88 | select SH_LCD_MIPI_DSI |
| 89 | select REGULATOR_FIXED_VOLTAGE if REGULATOR | ||
| 86 | depends on ARCH_SH73A0 | 90 | depends on ARCH_SH73A0 |
| 87 | 91 | ||
| 88 | config MACH_MACKEREL | 92 | config MACH_MACKEREL |
| @@ -90,15 +94,18 @@ config MACH_MACKEREL | |||
| 90 | depends on ARCH_SH7372 | 94 | depends on ARCH_SH7372 |
| 91 | select ARCH_REQUIRE_GPIOLIB | 95 | select ARCH_REQUIRE_GPIOLIB |
| 92 | select SND_SOC_AK4642 if SND_SIMPLE_CARD | 96 | select SND_SOC_AK4642 if SND_SIMPLE_CARD |
| 97 | select REGULATOR_FIXED_VOLTAGE if REGULATOR | ||
| 93 | 98 | ||
| 94 | config MACH_KOTA2 | 99 | config MACH_KOTA2 |
| 95 | bool "KOTA2 board" | 100 | bool "KOTA2 board" |
| 96 | select ARCH_REQUIRE_GPIOLIB | 101 | select ARCH_REQUIRE_GPIOLIB |
| 102 | select REGULATOR_FIXED_VOLTAGE if REGULATOR | ||
| 97 | depends on ARCH_SH73A0 | 103 | depends on ARCH_SH73A0 |
| 98 | 104 | ||
| 99 | config MACH_BONITO | 105 | config MACH_BONITO |
| 100 | bool "bonito board" | 106 | bool "bonito board" |
| 101 | select ARCH_REQUIRE_GPIOLIB | 107 | select ARCH_REQUIRE_GPIOLIB |
| 108 | select REGULATOR_FIXED_VOLTAGE if REGULATOR | ||
| 102 | depends on ARCH_R8A7740 | 109 | depends on ARCH_R8A7740 |
| 103 | 110 | ||
| 104 | config MACH_ARMADILLO800EVA | 111 | config MACH_ARMADILLO800EVA |
| @@ -106,22 +113,28 @@ config MACH_ARMADILLO800EVA | |||
| 106 | depends on ARCH_R8A7740 | 113 | depends on ARCH_R8A7740 |
| 107 | select ARCH_REQUIRE_GPIOLIB | 114 | select ARCH_REQUIRE_GPIOLIB |
| 108 | select USE_OF | 115 | select USE_OF |
| 116 | select REGULATOR_FIXED_VOLTAGE if REGULATOR | ||
| 117 | select SND_SOC_WM8978 if SND_SIMPLE_CARD | ||
| 109 | 118 | ||
| 110 | config MACH_MARZEN | 119 | config MACH_MARZEN |
| 111 | bool "MARZEN board" | 120 | bool "MARZEN board" |
| 112 | depends on ARCH_R8A7779 | 121 | depends on ARCH_R8A7779 |
| 113 | select ARCH_REQUIRE_GPIOLIB | 122 | select ARCH_REQUIRE_GPIOLIB |
| 123 | select REGULATOR_FIXED_VOLTAGE if REGULATOR | ||
| 114 | 124 | ||
| 115 | config MACH_KZM9D | 125 | config MACH_KZM9D |
| 116 | bool "KZM9D board" | 126 | bool "KZM9D board" |
| 117 | depends on ARCH_EMEV2 | 127 | depends on ARCH_EMEV2 |
| 118 | select USE_OF | 128 | select USE_OF |
| 129 | select REGULATOR_FIXED_VOLTAGE if REGULATOR | ||
| 119 | 130 | ||
| 120 | config MACH_KZM9G | 131 | config MACH_KZM9G |
| 121 | bool "KZM-A9-GT board" | 132 | bool "KZM-A9-GT board" |
| 122 | depends on ARCH_SH73A0 | 133 | depends on ARCH_SH73A0 |
| 123 | select ARCH_REQUIRE_GPIOLIB | 134 | select ARCH_REQUIRE_GPIOLIB |
| 124 | select USE_OF | 135 | select USE_OF |
| 136 | select SND_SOC_AK4642 if SND_SIMPLE_CARD | ||
| 137 | select REGULATOR_FIXED_VOLTAGE if REGULATOR | ||
| 125 | 138 | ||
| 126 | comment "SH-Mobile System Configuration" | 139 | comment "SH-Mobile System Configuration" |
| 127 | 140 | ||
diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile index 8aa1962c22a2..0df5ae6740c6 100644 --- a/arch/arm/mach-shmobile/Makefile +++ b/arch/arm/mach-shmobile/Makefile | |||
| @@ -39,7 +39,9 @@ obj-$(CONFIG_ARCH_R8A7740) += entry-intc.o | |||
| 39 | # PM objects | 39 | # PM objects |
| 40 | obj-$(CONFIG_SUSPEND) += suspend.o | 40 | obj-$(CONFIG_SUSPEND) += suspend.o |
| 41 | obj-$(CONFIG_CPU_IDLE) += cpuidle.o | 41 | obj-$(CONFIG_CPU_IDLE) += cpuidle.o |
| 42 | obj-$(CONFIG_ARCH_SHMOBILE) += pm-rmobile.o | ||
| 42 | obj-$(CONFIG_ARCH_SH7372) += pm-sh7372.o sleep-sh7372.o | 43 | obj-$(CONFIG_ARCH_SH7372) += pm-sh7372.o sleep-sh7372.o |
| 44 | obj-$(CONFIG_ARCH_R8A7740) += pm-r8a7740.o | ||
| 43 | obj-$(CONFIG_ARCH_R8A7779) += pm-r8a7779.o | 45 | obj-$(CONFIG_ARCH_R8A7779) += pm-r8a7779.o |
| 44 | 46 | ||
| 45 | # Board objects | 47 | # Board objects |
diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c index 5a6f22f05e99..d82c010fdfc6 100644 --- a/arch/arm/mach-shmobile/board-ag5evm.c +++ b/arch/arm/mach-shmobile/board-ag5evm.c | |||
| @@ -27,6 +27,8 @@ | |||
| 27 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
| 28 | #include <linux/io.h> | 28 | #include <linux/io.h> |
| 29 | #include <linux/dma-mapping.h> | 29 | #include <linux/dma-mapping.h> |
| 30 | #include <linux/regulator/fixed.h> | ||
| 31 | #include <linux/regulator/machine.h> | ||
| 30 | #include <linux/serial_sci.h> | 32 | #include <linux/serial_sci.h> |
| 31 | #include <linux/smsc911x.h> | 33 | #include <linux/smsc911x.h> |
| 32 | #include <linux/gpio.h> | 34 | #include <linux/gpio.h> |
| @@ -52,6 +54,12 @@ | |||
| 52 | #include <asm/hardware/cache-l2x0.h> | 54 | #include <asm/hardware/cache-l2x0.h> |
| 53 | #include <asm/traps.h> | 55 | #include <asm/traps.h> |
| 54 | 56 | ||
| 57 | /* Dummy supplies, where voltage doesn't matter */ | ||
| 58 | static struct regulator_consumer_supply dummy_supplies[] = { | ||
| 59 | REGULATOR_SUPPLY("vddvario", "smsc911x"), | ||
| 60 | REGULATOR_SUPPLY("vdd33a", "smsc911x"), | ||
| 61 | }; | ||
| 62 | |||
| 55 | static struct resource smsc9220_resources[] = { | 63 | static struct resource smsc9220_resources[] = { |
| 56 | [0] = { | 64 | [0] = { |
| 57 | .start = 0x14000000, | 65 | .start = 0x14000000, |
| @@ -142,6 +150,13 @@ static struct platform_device fsi_device = { | |||
| 142 | .resource = fsi_resources, | 150 | .resource = fsi_resources, |
| 143 | }; | 151 | }; |
| 144 | 152 | ||
| 153 | /* Fixed 1.8V regulator to be used by MMCIF */ | ||
| 154 | static struct regulator_consumer_supply fixed1v8_power_consumers[] = | ||
| 155 | { | ||
| 156 | REGULATOR_SUPPLY("vmmc", "sh_mmcif.0"), | ||
| 157 | REGULATOR_SUPPLY("vqmmc", "sh_mmcif.0"), | ||
| 158 | }; | ||
| 159 | |||
| 145 | static struct resource sh_mmcif_resources[] = { | 160 | static struct resource sh_mmcif_resources[] = { |
| 146 | [0] = { | 161 | [0] = { |
| 147 | .name = "MMCIF", | 162 | .name = "MMCIF", |
| @@ -364,6 +379,13 @@ static struct platform_device mipidsi0_device = { | |||
| 364 | }, | 379 | }, |
| 365 | }; | 380 | }; |
| 366 | 381 | ||
| 382 | /* Fixed 2.8V regulators to be used by SDHI0 */ | ||
| 383 | static struct regulator_consumer_supply fixed2v8_power_consumers[] = | ||
| 384 | { | ||
| 385 | REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"), | ||
| 386 | REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"), | ||
| 387 | }; | ||
| 388 | |||
| 367 | /* SDHI0 */ | 389 | /* SDHI0 */ |
| 368 | static struct sh_mobile_sdhi_info sdhi0_info = { | 390 | static struct sh_mobile_sdhi_info sdhi0_info = { |
| 369 | .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, | 391 | .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, |
| @@ -408,8 +430,57 @@ static struct platform_device sdhi0_device = { | |||
| 408 | }, | 430 | }, |
| 409 | }; | 431 | }; |
| 410 | 432 | ||
| 411 | void ag5evm_sdhi1_set_pwr(struct platform_device *pdev, int state) | 433 | /* Fixed 3.3V regulator to be used by SDHI1 */ |
| 434 | static struct regulator_consumer_supply cn4_power_consumers[] = | ||
| 412 | { | 435 | { |
| 436 | REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"), | ||
| 437 | REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.1"), | ||
| 438 | }; | ||
| 439 | |||
| 440 | static struct regulator_init_data cn4_power_init_data = { | ||
| 441 | .constraints = { | ||
| 442 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
| 443 | }, | ||
| 444 | .num_consumer_supplies = ARRAY_SIZE(cn4_power_consumers), | ||
| 445 | .consumer_supplies = cn4_power_consumers, | ||
| 446 | }; | ||
| 447 | |||
| 448 | static struct fixed_voltage_config cn4_power_info = { | ||
| 449 | .supply_name = "CN4 SD/MMC Vdd", | ||
| 450 | .microvolts = 3300000, | ||
| 451 | .gpio = GPIO_PORT114, | ||
| 452 | .enable_high = 1, | ||
| 453 | .init_data = &cn4_power_init_data, | ||
| 454 | }; | ||
| 455 | |||
| 456 | static struct platform_device cn4_power = { | ||
| 457 | .name = "reg-fixed-voltage", | ||
| 458 | .id = 2, | ||
| 459 | .dev = { | ||
| 460 | .platform_data = &cn4_power_info, | ||
| 461 | }, | ||
| 462 | }; | ||
| 463 | |||
| 464 | static void ag5evm_sdhi1_set_pwr(struct platform_device *pdev, int state) | ||
| 465 | { | ||
| 466 | static int power_gpio = -EINVAL; | ||
| 467 | |||
| 468 | if (power_gpio < 0) { | ||
| 469 | int ret = gpio_request(GPIO_PORT114, "sdhi1_power"); | ||
| 470 | if (!ret) { | ||
| 471 | power_gpio = GPIO_PORT114; | ||
| 472 | gpio_direction_output(power_gpio, 0); | ||
| 473 | } | ||
| 474 | } | ||
| 475 | |||
| 476 | /* | ||
| 477 | * If requesting the GPIO above failed, it means, that the regulator got | ||
| 478 | * probed and grabbed the GPIO, but we don't know, whether the sdhi | ||
| 479 | * driver already uses the regulator. If it doesn't, we have to toggle | ||
| 480 | * the GPIO ourselves, even though it is now owned by the fixed | ||
| 481 | * regulator driver. We have to live with the race in case the driver | ||
| 482 | * gets unloaded and the GPIO freed between these two steps. | ||
| 483 | */ | ||
| 413 | gpio_set_value(GPIO_PORT114, state); | 484 | gpio_set_value(GPIO_PORT114, state); |
| 414 | } | 485 | } |
| 415 | 486 | ||
| @@ -455,6 +526,7 @@ static struct platform_device sdhi1_device = { | |||
| 455 | }; | 526 | }; |
| 456 | 527 | ||
| 457 | static struct platform_device *ag5evm_devices[] __initdata = { | 528 | static struct platform_device *ag5evm_devices[] __initdata = { |
| 529 | &cn4_power, | ||
| 458 | ð_device, | 530 | ð_device, |
| 459 | &keysc_device, | 531 | &keysc_device, |
| 460 | &fsi_device, | 532 | &fsi_device, |
| @@ -468,6 +540,12 @@ static struct platform_device *ag5evm_devices[] __initdata = { | |||
| 468 | 540 | ||
| 469 | static void __init ag5evm_init(void) | 541 | static void __init ag5evm_init(void) |
| 470 | { | 542 | { |
| 543 | regulator_register_always_on(0, "fixed-1.8V", fixed1v8_power_consumers, | ||
| 544 | ARRAY_SIZE(fixed1v8_power_consumers), 1800000); | ||
| 545 | regulator_register_always_on(1, "fixed-2.8V", fixed2v8_power_consumers, | ||
| 546 | ARRAY_SIZE(fixed2v8_power_consumers), 3300000); | ||
| 547 | regulator_register_fixed(3, dummy_supplies, ARRAY_SIZE(dummy_supplies)); | ||
| 548 | |||
| 471 | sh73a0_pinmux_init(); | 549 | sh73a0_pinmux_init(); |
| 472 | 550 | ||
| 473 | /* enable SCIFA2 */ | 551 | /* enable SCIFA2 */ |
| @@ -562,8 +640,6 @@ static void __init ag5evm_init(void) | |||
| 562 | gpio_request(GPIO_FN_SDHID1_2_PU, NULL); | 640 | gpio_request(GPIO_FN_SDHID1_2_PU, NULL); |
| 563 | gpio_request(GPIO_FN_SDHID1_1_PU, NULL); | 641 | gpio_request(GPIO_FN_SDHID1_1_PU, NULL); |
| 564 | gpio_request(GPIO_FN_SDHID1_0_PU, NULL); | 642 | gpio_request(GPIO_FN_SDHID1_0_PU, NULL); |
| 565 | gpio_request(GPIO_PORT114, "sdhi1_power"); | ||
| 566 | gpio_direction_output(GPIO_PORT114, 0); | ||
| 567 | 643 | ||
| 568 | #ifdef CONFIG_CACHE_L2X0 | 644 | #ifdef CONFIG_CACHE_L2X0 |
| 569 | /* Shared attribute override enable, 64K*8way */ | 645 | /* Shared attribute override enable, 64K*8way */ |
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c index ace60246a5df..f172ca85905c 100644 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c | |||
| @@ -34,6 +34,8 @@ | |||
| 34 | #include <linux/i2c.h> | 34 | #include <linux/i2c.h> |
| 35 | #include <linux/i2c/tsc2007.h> | 35 | #include <linux/i2c/tsc2007.h> |
| 36 | #include <linux/io.h> | 36 | #include <linux/io.h> |
| 37 | #include <linux/regulator/fixed.h> | ||
| 38 | #include <linux/regulator/machine.h> | ||
| 37 | #include <linux/smsc911x.h> | 39 | #include <linux/smsc911x.h> |
| 38 | #include <linux/sh_intc.h> | 40 | #include <linux/sh_intc.h> |
| 39 | #include <linux/sh_clk.h> | 41 | #include <linux/sh_clk.h> |
| @@ -159,6 +161,27 @@ | |||
| 159 | * CN12: 3.3v | 161 | * CN12: 3.3v |
| 160 | */ | 162 | */ |
| 161 | 163 | ||
| 164 | /* Dummy supplies, where voltage doesn't matter */ | ||
| 165 | static struct regulator_consumer_supply fixed1v8_power_consumers[] = | ||
| 166 | { | ||
| 167 | /* J22 default position: 1.8V */ | ||
| 168 | REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"), | ||
| 169 | REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.1"), | ||
| 170 | REGULATOR_SUPPLY("vmmc", "sh_mmcif.0"), | ||
| 171 | REGULATOR_SUPPLY("vqmmc", "sh_mmcif.0"), | ||
| 172 | }; | ||
| 173 | |||
| 174 | static struct regulator_consumer_supply fixed3v3_power_consumers[] = | ||
| 175 | { | ||
| 176 | REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"), | ||
| 177 | REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"), | ||
| 178 | }; | ||
| 179 | |||
| 180 | static struct regulator_consumer_supply dummy_supplies[] = { | ||
| 181 | REGULATOR_SUPPLY("vddvario", "smsc911x"), | ||
| 182 | REGULATOR_SUPPLY("vdd33a", "smsc911x"), | ||
| 183 | }; | ||
| 184 | |||
| 162 | /* MTD */ | 185 | /* MTD */ |
| 163 | static struct mtd_partition nor_flash_partitions[] = { | 186 | static struct mtd_partition nor_flash_partitions[] = { |
| 164 | { | 187 | { |
| @@ -1138,21 +1161,6 @@ static void __init fsi_init_pm_clock(void) | |||
| 1138 | clk_put(fsia_ick); | 1161 | clk_put(fsia_ick); |
| 1139 | } | 1162 | } |
| 1140 | 1163 | ||
| 1141 | /* | ||
| 1142 | * FIXME !! | ||
| 1143 | * | ||
| 1144 | * gpio_no_direction | ||
| 1145 | * are quick_hack. | ||
| 1146 | * | ||
| 1147 | * current gpio frame work doesn't have | ||
| 1148 | * the method to control only pull up/down/free. | ||
| 1149 | * this function should be replaced by correct gpio function | ||
| 1150 | */ | ||
| 1151 | static void __init gpio_no_direction(u32 addr) | ||
| 1152 | { | ||
| 1153 | __raw_writeb(0x00, addr); | ||
| 1154 | } | ||
| 1155 | |||
| 1156 | /* TouchScreen */ | 1164 | /* TouchScreen */ |
| 1157 | #ifdef CONFIG_AP4EVB_QHD | 1165 | #ifdef CONFIG_AP4EVB_QHD |
| 1158 | # define GPIO_TSC_IRQ GPIO_FN_IRQ28_123 | 1166 | # define GPIO_TSC_IRQ GPIO_FN_IRQ28_123 |
| @@ -1224,6 +1232,12 @@ static void __init ap4evb_init(void) | |||
| 1224 | u32 srcr4; | 1232 | u32 srcr4; |
| 1225 | struct clk *clk; | 1233 | struct clk *clk; |
| 1226 | 1234 | ||
| 1235 | regulator_register_always_on(0, "fixed-1.8V", fixed1v8_power_consumers, | ||
| 1236 | ARRAY_SIZE(fixed1v8_power_consumers), 1800000); | ||
| 1237 | regulator_register_always_on(1, "fixed-3.3V", fixed3v3_power_consumers, | ||
| 1238 | ARRAY_SIZE(fixed3v3_power_consumers), 3300000); | ||
| 1239 | regulator_register_fixed(2, dummy_supplies, ARRAY_SIZE(dummy_supplies)); | ||
| 1240 | |||
| 1227 | /* External clock source */ | 1241 | /* External clock source */ |
| 1228 | clk_set_rate(&sh7372_dv_clki_clk, 27000000); | 1242 | clk_set_rate(&sh7372_dv_clki_clk, 27000000); |
| 1229 | 1243 | ||
| @@ -1302,8 +1316,8 @@ static void __init ap4evb_init(void) | |||
| 1302 | 1316 | ||
| 1303 | gpio_request(GPIO_PORT9, NULL); | 1317 | gpio_request(GPIO_PORT9, NULL); |
| 1304 | gpio_request(GPIO_PORT10, NULL); | 1318 | gpio_request(GPIO_PORT10, NULL); |
| 1305 | gpio_no_direction(GPIO_PORT9CR); /* FSIAOBT needs no direction */ | 1319 | gpio_direction_none(GPIO_PORT9CR); /* FSIAOBT needs no direction */ |
| 1306 | gpio_no_direction(GPIO_PORT10CR); /* FSIAOLR needs no direction */ | 1320 | gpio_direction_none(GPIO_PORT10CR); /* FSIAOLR needs no direction */ |
| 1307 | 1321 | ||
| 1308 | /* card detect pin for MMC slot (CN7) */ | 1322 | /* card detect pin for MMC slot (CN7) */ |
| 1309 | gpio_request(GPIO_PORT41, NULL); | 1323 | gpio_request(GPIO_PORT41, NULL); |
| @@ -1447,14 +1461,14 @@ static void __init ap4evb_init(void) | |||
| 1447 | 1461 | ||
| 1448 | platform_add_devices(ap4evb_devices, ARRAY_SIZE(ap4evb_devices)); | 1462 | platform_add_devices(ap4evb_devices, ARRAY_SIZE(ap4evb_devices)); |
| 1449 | 1463 | ||
| 1450 | sh7372_add_device_to_domain(&sh7372_a4lc, &lcdc1_device); | 1464 | rmobile_add_device_to_domain(&sh7372_pd_a4lc, &lcdc1_device); |
| 1451 | sh7372_add_device_to_domain(&sh7372_a4lc, &lcdc_device); | 1465 | rmobile_add_device_to_domain(&sh7372_pd_a4lc, &lcdc_device); |
| 1452 | sh7372_add_device_to_domain(&sh7372_a4mp, &fsi_device); | 1466 | rmobile_add_device_to_domain(&sh7372_pd_a4mp, &fsi_device); |
| 1453 | 1467 | ||
| 1454 | sh7372_add_device_to_domain(&sh7372_a3sp, &sh_mmcif_device); | 1468 | rmobile_add_device_to_domain(&sh7372_pd_a3sp, &sh_mmcif_device); |
| 1455 | sh7372_add_device_to_domain(&sh7372_a3sp, &sdhi0_device); | 1469 | rmobile_add_device_to_domain(&sh7372_pd_a3sp, &sdhi0_device); |
| 1456 | sh7372_add_device_to_domain(&sh7372_a3sp, &sdhi1_device); | 1470 | rmobile_add_device_to_domain(&sh7372_pd_a3sp, &sdhi1_device); |
| 1457 | sh7372_add_device_to_domain(&sh7372_a4r, &ceu_device); | 1471 | rmobile_add_device_to_domain(&sh7372_pd_a4r, &ceu_device); |
| 1458 | 1472 | ||
| 1459 | hdmi_init_pm_clock(); | 1473 | hdmi_init_pm_clock(); |
| 1460 | fsi_init_pm_clock(); | 1474 | fsi_init_pm_clock(); |
diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c index 9bd135531d76..cf10f92856dc 100644 --- a/arch/arm/mach-shmobile/board-armadillo800eva.c +++ b/arch/arm/mach-shmobile/board-armadillo800eva.c | |||
| @@ -28,6 +28,8 @@ | |||
| 28 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
| 29 | #include <linux/gpio.h> | 29 | #include <linux/gpio.h> |
| 30 | #include <linux/gpio_keys.h> | 30 | #include <linux/gpio_keys.h> |
| 31 | #include <linux/regulator/fixed.h> | ||
| 32 | #include <linux/regulator/machine.h> | ||
| 31 | #include <linux/sh_eth.h> | 33 | #include <linux/sh_eth.h> |
| 32 | #include <linux/videodev2.h> | 34 | #include <linux/videodev2.h> |
| 33 | #include <linux/usb/renesas_usbhs.h> | 35 | #include <linux/usb/renesas_usbhs.h> |
| @@ -37,14 +39,20 @@ | |||
| 37 | #include <linux/mmc/sh_mobile_sdhi.h> | 39 | #include <linux/mmc/sh_mobile_sdhi.h> |
| 38 | #include <mach/common.h> | 40 | #include <mach/common.h> |
| 39 | #include <mach/irqs.h> | 41 | #include <mach/irqs.h> |
| 42 | #include <mach/r8a7740.h> | ||
| 43 | #include <media/mt9t112.h> | ||
| 44 | #include <media/sh_mobile_ceu.h> | ||
| 45 | #include <media/soc_camera.h> | ||
| 40 | #include <asm/page.h> | 46 | #include <asm/page.h> |
| 41 | #include <asm/mach-types.h> | 47 | #include <asm/mach-types.h> |
| 42 | #include <asm/mach/arch.h> | 48 | #include <asm/mach/arch.h> |
| 43 | #include <asm/mach/map.h> | 49 | #include <asm/mach/map.h> |
| 44 | #include <asm/mach/time.h> | 50 | #include <asm/mach/time.h> |
| 45 | #include <asm/hardware/cache-l2x0.h> | 51 | #include <asm/hardware/cache-l2x0.h> |
| 46 | #include <mach/r8a7740.h> | ||
| 47 | #include <video/sh_mobile_lcdc.h> | 52 | #include <video/sh_mobile_lcdc.h> |
| 53 | #include <video/sh_mobile_hdmi.h> | ||
| 54 | #include <sound/sh_fsi.h> | ||
| 55 | #include <sound/simple_card.h> | ||
| 48 | 56 | ||
| 49 | /* | 57 | /* |
| 50 | * CON1 Camera Module | 58 | * CON1 Camera Module |
| @@ -108,6 +116,14 @@ | |||
| 108 | */ | 116 | */ |
| 109 | 117 | ||
| 110 | /* | 118 | /* |
| 119 | * FSI-WM8978 | ||
| 120 | * | ||
| 121 | * this command is required when playback. | ||
| 122 | * | ||
| 123 | * # amixer set "Headphone" 50 | ||
| 124 | */ | ||
| 125 | |||
| 126 | /* | ||
| 111 | * USB function | 127 | * USB function |
| 112 | * | 128 | * |
| 113 | * When you use USB Function, | 129 | * When you use USB Function, |
| @@ -117,14 +133,8 @@ | |||
| 117 | * These are a little bit complex. | 133 | * These are a little bit complex. |
| 118 | * see | 134 | * see |
| 119 | * usbhsf_power_ctrl() | 135 | * usbhsf_power_ctrl() |
| 120 | * | ||
| 121 | * CAUTION | ||
| 122 | * | ||
| 123 | * It uses autonomy mode for USB hotplug at this point | ||
| 124 | * (= usbhs_private.platform_callback.get_vbus is NULL), | ||
| 125 | * since we don't know what's happen on PM control | ||
| 126 | * on this workaround. | ||
| 127 | */ | 136 | */ |
| 137 | #define IRQ7 evt2irq(0x02e0) | ||
| 128 | #define USBCR1 0xe605810a | 138 | #define USBCR1 0xe605810a |
| 129 | #define USBH 0xC6700000 | 139 | #define USBH 0xC6700000 |
| 130 | #define USBH_USBCTR 0x10834 | 140 | #define USBH_USBCTR 0x10834 |
| @@ -204,6 +214,20 @@ static void usbhsf_power_ctrl(struct platform_device *pdev, | |||
| 204 | } | 214 | } |
| 205 | } | 215 | } |
| 206 | 216 | ||
| 217 | static int usbhsf_get_vbus(struct platform_device *pdev) | ||
| 218 | { | ||
| 219 | return gpio_get_value(GPIO_PORT209); | ||
| 220 | } | ||
| 221 | |||
| 222 | static irqreturn_t usbhsf_interrupt(int irq, void *data) | ||
| 223 | { | ||
| 224 | struct platform_device *pdev = data; | ||
| 225 | |||
| 226 | renesas_usbhs_call_notify_hotplug(pdev); | ||
| 227 | |||
| 228 | return IRQ_HANDLED; | ||
| 229 | } | ||
| 230 | |||
| 207 | static void usbhsf_hardware_exit(struct platform_device *pdev) | 231 | static void usbhsf_hardware_exit(struct platform_device *pdev) |
| 208 | { | 232 | { |
| 209 | struct usbhsf_private *priv = usbhsf_get_priv(pdev); | 233 | struct usbhsf_private *priv = usbhsf_get_priv(pdev); |
| @@ -227,11 +251,14 @@ static void usbhsf_hardware_exit(struct platform_device *pdev) | |||
| 227 | priv->host = NULL; | 251 | priv->host = NULL; |
| 228 | priv->func = NULL; | 252 | priv->func = NULL; |
| 229 | priv->usbh_base = NULL; | 253 | priv->usbh_base = NULL; |
| 254 | |||
| 255 | free_irq(IRQ7, pdev); | ||
| 230 | } | 256 | } |
| 231 | 257 | ||
| 232 | static int usbhsf_hardware_init(struct platform_device *pdev) | 258 | static int usbhsf_hardware_init(struct platform_device *pdev) |
| 233 | { | 259 | { |
| 234 | struct usbhsf_private *priv = usbhsf_get_priv(pdev); | 260 | struct usbhsf_private *priv = usbhsf_get_priv(pdev); |
| 261 | int ret; | ||
| 235 | 262 | ||
| 236 | priv->phy = clk_get(&pdev->dev, "phy"); | 263 | priv->phy = clk_get(&pdev->dev, "phy"); |
| 237 | priv->usb24 = clk_get(&pdev->dev, "usb24"); | 264 | priv->usb24 = clk_get(&pdev->dev, "usb24"); |
| @@ -251,6 +278,14 @@ static int usbhsf_hardware_init(struct platform_device *pdev) | |||
| 251 | return -EIO; | 278 | return -EIO; |
| 252 | } | 279 | } |
| 253 | 280 | ||
| 281 | ret = request_irq(IRQ7, usbhsf_interrupt, IRQF_TRIGGER_NONE, | ||
| 282 | dev_name(&pdev->dev), pdev); | ||
| 283 | if (ret) { | ||
| 284 | dev_err(&pdev->dev, "request_irq err\n"); | ||
| 285 | return ret; | ||
| 286 | } | ||
| 287 | irq_set_irq_type(IRQ7, IRQ_TYPE_EDGE_BOTH); | ||
| 288 | |||
| 254 | /* usb24 use 1/1 of parent clock (= usb24s = 24MHz) */ | 289 | /* usb24 use 1/1 of parent clock (= usb24s = 24MHz) */ |
| 255 | clk_set_rate(priv->usb24, | 290 | clk_set_rate(priv->usb24, |
| 256 | clk_get_rate(clk_get_parent(priv->usb24))); | 291 | clk_get_rate(clk_get_parent(priv->usb24))); |
| @@ -262,6 +297,7 @@ static struct usbhsf_private usbhsf_private = { | |||
| 262 | .info = { | 297 | .info = { |
| 263 | .platform_callback = { | 298 | .platform_callback = { |
| 264 | .get_id = usbhsf_get_id, | 299 | .get_id = usbhsf_get_id, |
| 300 | .get_vbus = usbhsf_get_vbus, | ||
| 265 | .hardware_init = usbhsf_hardware_init, | 301 | .hardware_init = usbhsf_hardware_init, |
| 266 | .hardware_exit = usbhsf_hardware_exit, | 302 | .hardware_exit = usbhsf_hardware_exit, |
| 267 | .power_ctrl = usbhsf_power_ctrl, | 303 | .power_ctrl = usbhsf_power_ctrl, |
| @@ -269,6 +305,8 @@ static struct usbhsf_private usbhsf_private = { | |||
| 269 | .driver_param = { | 305 | .driver_param = { |
| 270 | .buswait_bwait = 5, | 306 | .buswait_bwait = 5, |
| 271 | .detection_delay = 5, | 307 | .detection_delay = 5, |
| 308 | .d0_rx_id = SHDMA_SLAVE_USBHS_RX, | ||
| 309 | .d1_tx_id = SHDMA_SLAVE_USBHS_TX, | ||
| 272 | }, | 310 | }, |
| 273 | } | 311 | } |
| 274 | }; | 312 | }; |
| @@ -384,6 +422,103 @@ static struct platform_device lcdc0_device = { | |||
| 384 | }, | 422 | }, |
| 385 | }; | 423 | }; |
| 386 | 424 | ||
| 425 | /* | ||
| 426 | * LCDC1/HDMI | ||
| 427 | */ | ||
| 428 | static struct sh_mobile_hdmi_info hdmi_info = { | ||
| 429 | .flags = HDMI_OUTPUT_PUSH_PULL | | ||
| 430 | HDMI_OUTPUT_POLARITY_HI | | ||
| 431 | HDMI_32BIT_REG | | ||
| 432 | HDMI_HAS_HTOP1 | | ||
| 433 | HDMI_SND_SRC_SPDIF, | ||
| 434 | }; | ||
| 435 | |||
| 436 | static struct resource hdmi_resources[] = { | ||
| 437 | [0] = { | ||
| 438 | .name = "HDMI", | ||
| 439 | .start = 0xe6be0000, | ||
| 440 | .end = 0xe6be03ff, | ||
| 441 | .flags = IORESOURCE_MEM, | ||
| 442 | }, | ||
| 443 | [1] = { | ||
| 444 | .start = evt2irq(0x1700), | ||
| 445 | .flags = IORESOURCE_IRQ, | ||
| 446 | }, | ||
| 447 | [2] = { | ||
| 448 | .name = "HDMI emma3pf", | ||
| 449 | .start = 0xe6be4000, | ||
| 450 | .end = 0xe6be43ff, | ||
| 451 | .flags = IORESOURCE_MEM, | ||
| 452 | }, | ||
| 453 | }; | ||
| 454 | |||
| 455 | static struct platform_device hdmi_device = { | ||
| 456 | .name = "sh-mobile-hdmi", | ||
| 457 | .num_resources = ARRAY_SIZE(hdmi_resources), | ||
| 458 | .resource = hdmi_resources, | ||
| 459 | .id = -1, | ||
| 460 | .dev = { | ||
| 461 | .platform_data = &hdmi_info, | ||
| 462 | }, | ||
| 463 | }; | ||
| 464 | |||
| 465 | static const struct fb_videomode lcdc1_mode = { | ||
| 466 | .name = "HDMI 720p", | ||
| 467 | .xres = 1280, | ||
| 468 | .yres = 720, | ||
| 469 | .pixclock = 13468, | ||
| 470 | .left_margin = 220, | ||
| 471 | .right_margin = 110, | ||
| 472 | .hsync_len = 40, | ||
| 473 | .upper_margin = 20, | ||
| 474 | .lower_margin = 5, | ||
| 475 | .vsync_len = 5, | ||
| 476 | .refresh = 60, | ||
| 477 | .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT, | ||
| 478 | }; | ||
| 479 | |||
| 480 | static struct sh_mobile_lcdc_info hdmi_lcdc_info = { | ||
| 481 | .clock_source = LCDC_CLK_PERIPHERAL, /* HDMI clock */ | ||
| 482 | .ch[0] = { | ||
| 483 | .chan = LCDC_CHAN_MAINLCD, | ||
| 484 | .fourcc = V4L2_PIX_FMT_RGB565, | ||
| 485 | .interface_type = RGB24, | ||
| 486 | .clock_divider = 1, | ||
| 487 | .flags = LCDC_FLAGS_DWPOL, | ||
| 488 | .lcd_modes = &lcdc1_mode, | ||
| 489 | .num_modes = 1, | ||
| 490 | .tx_dev = &hdmi_device, | ||
| 491 | .panel_cfg = { | ||
| 492 | .width = 1280, | ||
| 493 | .height = 720, | ||
| 494 | }, | ||
| 495 | }, | ||
| 496 | }; | ||
| 497 | |||
| 498 | static struct resource hdmi_lcdc_resources[] = { | ||
| 499 | [0] = { | ||
| 500 | .name = "LCDC1", | ||
| 501 | .start = 0xfe944000, | ||
| 502 | .end = 0xfe948000 - 1, | ||
| 503 | .flags = IORESOURCE_MEM, | ||
| 504 | }, | ||
| 505 | [1] = { | ||
| 506 | .start = intcs_evt2irq(0x1780), | ||
| 507 | .flags = IORESOURCE_IRQ, | ||
| 508 | }, | ||
| 509 | }; | ||
| 510 | |||
| 511 | static struct platform_device hdmi_lcdc_device = { | ||
| 512 | .name = "sh_mobile_lcdc_fb", | ||
| 513 | .num_resources = ARRAY_SIZE(hdmi_lcdc_resources), | ||
| 514 | .resource = hdmi_lcdc_resources, | ||
| 515 | .id = 1, | ||
| 516 | .dev = { | ||
| 517 | .platform_data = &hdmi_lcdc_info, | ||
| 518 | .coherent_dma_mask = ~0, | ||
| 519 | }, | ||
| 520 | }; | ||
| 521 | |||
| 387 | /* GPIO KEY */ | 522 | /* GPIO KEY */ |
| 388 | #define GPIO_KEY(c, g, d) { .code = c, .gpio = g, .desc = d, .active_low = 1 } | 523 | #define GPIO_KEY(c, g, d) { .code = c, .gpio = g, .desc = d, .active_low = 1 } |
| 389 | 524 | ||
| @@ -407,6 +542,17 @@ static struct platform_device gpio_keys_device = { | |||
| 407 | }, | 542 | }, |
| 408 | }; | 543 | }; |
| 409 | 544 | ||
| 545 | /* Fixed 3.3V regulator to be used by SDHI0, SDHI1, MMCIF */ | ||
| 546 | static struct regulator_consumer_supply fixed3v3_power_consumers[] = | ||
| 547 | { | ||
| 548 | REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"), | ||
| 549 | REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"), | ||
| 550 | REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"), | ||
| 551 | REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.1"), | ||
| 552 | REGULATOR_SUPPLY("vmmc", "sh_mmcif"), | ||
| 553 | REGULATOR_SUPPLY("vqmmc", "sh_mmcif"), | ||
| 554 | }; | ||
| 555 | |||
| 410 | /* SDHI0 */ | 556 | /* SDHI0 */ |
| 411 | /* | 557 | /* |
| 412 | * FIXME | 558 | * FIXME |
| @@ -418,6 +564,8 @@ static struct platform_device gpio_keys_device = { | |||
| 418 | */ | 564 | */ |
| 419 | #define IRQ31 evt2irq(0x33E0) | 565 | #define IRQ31 evt2irq(0x33E0) |
| 420 | static struct sh_mobile_sdhi_info sdhi0_info = { | 566 | static struct sh_mobile_sdhi_info sdhi0_info = { |
| 567 | .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, | ||
| 568 | .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, | ||
| 421 | .tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |\ | 569 | .tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |\ |
| 422 | MMC_CAP_NEEDS_POLL, | 570 | MMC_CAP_NEEDS_POLL, |
| 423 | .tmio_ocr_mask = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34, | 571 | .tmio_ocr_mask = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34, |
| @@ -458,6 +606,8 @@ static struct platform_device sdhi0_device = { | |||
| 458 | 606 | ||
| 459 | /* SDHI1 */ | 607 | /* SDHI1 */ |
| 460 | static struct sh_mobile_sdhi_info sdhi1_info = { | 608 | static struct sh_mobile_sdhi_info sdhi1_info = { |
| 609 | .dma_slave_tx = SHDMA_SLAVE_SDHI1_TX, | ||
| 610 | .dma_slave_rx = SHDMA_SLAVE_SDHI1_RX, | ||
| 461 | .tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ, | 611 | .tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ, |
| 462 | .tmio_ocr_mask = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34, | 612 | .tmio_ocr_mask = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34, |
| 463 | .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT, | 613 | .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT, |
| @@ -532,12 +682,209 @@ static struct platform_device sh_mmcif_device = { | |||
| 532 | .resource = sh_mmcif_resources, | 682 | .resource = sh_mmcif_resources, |
| 533 | }; | 683 | }; |
| 534 | 684 | ||
| 685 | /* Camera */ | ||
| 686 | static int mt9t111_power(struct device *dev, int mode) | ||
| 687 | { | ||
| 688 | struct clk *mclk = clk_get(NULL, "video1"); | ||
| 689 | |||
| 690 | if (IS_ERR(mclk)) { | ||
| 691 | dev_err(dev, "can't get video1 clock\n"); | ||
| 692 | return -EINVAL; | ||
| 693 | } | ||
| 694 | |||
| 695 | if (mode) { | ||
| 696 | /* video1 (= CON1 camera) expect 24MHz */ | ||
| 697 | clk_set_rate(mclk, clk_round_rate(mclk, 24000000)); | ||
| 698 | clk_enable(mclk); | ||
| 699 | gpio_direction_output(GPIO_PORT158, 1); | ||
| 700 | } else { | ||
| 701 | gpio_direction_output(GPIO_PORT158, 0); | ||
| 702 | clk_disable(mclk); | ||
| 703 | } | ||
| 704 | |||
| 705 | clk_put(mclk); | ||
| 706 | |||
| 707 | return 0; | ||
| 708 | } | ||
| 709 | |||
| 710 | static struct i2c_board_info i2c_camera_mt9t111 = { | ||
| 711 | I2C_BOARD_INFO("mt9t112", 0x3d), | ||
| 712 | }; | ||
| 713 | |||
| 714 | static struct mt9t112_camera_info mt9t111_info = { | ||
| 715 | .divider = { 16, 0, 0, 7, 0, 10, 14, 7, 7 }, | ||
| 716 | }; | ||
| 717 | |||
| 718 | static struct soc_camera_link mt9t111_link = { | ||
| 719 | .i2c_adapter_id = 0, | ||
| 720 | .bus_id = 0, | ||
| 721 | .board_info = &i2c_camera_mt9t111, | ||
| 722 | .power = mt9t111_power, | ||
| 723 | .priv = &mt9t111_info, | ||
| 724 | }; | ||
| 725 | |||
| 726 | static struct platform_device camera_device = { | ||
| 727 | .name = "soc-camera-pdrv", | ||
| 728 | .id = 0, | ||
| 729 | .dev = { | ||
| 730 | .platform_data = &mt9t111_link, | ||
| 731 | }, | ||
| 732 | }; | ||
| 733 | |||
| 734 | /* CEU0 */ | ||
| 735 | static struct sh_mobile_ceu_info sh_mobile_ceu0_info = { | ||
| 736 | .flags = SH_CEU_FLAG_LOWER_8BIT, | ||
| 737 | }; | ||
| 738 | |||
| 739 | static struct resource ceu0_resources[] = { | ||
| 740 | [0] = { | ||
| 741 | .name = "CEU", | ||
| 742 | .start = 0xfe910000, | ||
| 743 | .end = 0xfe91009f, | ||
| 744 | .flags = IORESOURCE_MEM, | ||
| 745 | }, | ||
| 746 | [1] = { | ||
| 747 | .start = intcs_evt2irq(0x0500), | ||
| 748 | .flags = IORESOURCE_IRQ, | ||
| 749 | }, | ||
| 750 | [2] = { | ||
| 751 | /* place holder for contiguous memory */ | ||
| 752 | }, | ||
| 753 | }; | ||
| 754 | |||
| 755 | static struct platform_device ceu0_device = { | ||
| 756 | .name = "sh_mobile_ceu", | ||
| 757 | .id = 0, | ||
| 758 | .num_resources = ARRAY_SIZE(ceu0_resources), | ||
| 759 | .resource = ceu0_resources, | ||
| 760 | .dev = { | ||
| 761 | .platform_data = &sh_mobile_ceu0_info, | ||
| 762 | .coherent_dma_mask = 0xffffffff, | ||
| 763 | }, | ||
| 764 | }; | ||
| 765 | |||
| 766 | /* FSI */ | ||
| 767 | static int fsi_hdmi_set_rate(struct device *dev, int rate, int enable) | ||
| 768 | { | ||
| 769 | struct clk *fsib; | ||
| 770 | int ret; | ||
| 771 | |||
| 772 | /* it support 48KHz only */ | ||
| 773 | if (48000 != rate) | ||
| 774 | return -EINVAL; | ||
| 775 | |||
| 776 | fsib = clk_get(dev, "ickb"); | ||
| 777 | if (IS_ERR(fsib)) | ||
| 778 | return -EINVAL; | ||
| 779 | |||
| 780 | if (enable) { | ||
| 781 | ret = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64; | ||
| 782 | clk_enable(fsib); | ||
| 783 | } else { | ||
| 784 | ret = 0; | ||
| 785 | clk_disable(fsib); | ||
| 786 | } | ||
| 787 | |||
| 788 | clk_put(fsib); | ||
| 789 | |||
| 790 | return ret; | ||
| 791 | } | ||
| 792 | |||
| 793 | static struct sh_fsi_platform_info fsi_info = { | ||
| 794 | /* FSI-WM8978 */ | ||
| 795 | .port_a = { | ||
| 796 | .tx_id = SHDMA_SLAVE_FSIA_TX, | ||
| 797 | }, | ||
| 798 | /* FSI-HDMI */ | ||
| 799 | .port_b = { | ||
| 800 | .flags = SH_FSI_FMT_SPDIF | | ||
| 801 | SH_FSI_ENABLE_STREAM_MODE, | ||
| 802 | .set_rate = fsi_hdmi_set_rate, | ||
| 803 | .tx_id = SHDMA_SLAVE_FSIB_TX, | ||
| 804 | } | ||
| 805 | }; | ||
| 806 | |||
| 807 | static struct resource fsi_resources[] = { | ||
| 808 | [0] = { | ||
| 809 | .name = "FSI", | ||
| 810 | .start = 0xfe1f0000, | ||
| 811 | .end = 0xfe1f8400 - 1, | ||
| 812 | .flags = IORESOURCE_MEM, | ||
| 813 | }, | ||
| 814 | [1] = { | ||
| 815 | .start = evt2irq(0x1840), | ||
| 816 | .flags = IORESOURCE_IRQ, | ||
| 817 | }, | ||
| 818 | }; | ||
| 819 | |||
| 820 | static struct platform_device fsi_device = { | ||
| 821 | .name = "sh_fsi2", | ||
| 822 | .id = -1, | ||
| 823 | .num_resources = ARRAY_SIZE(fsi_resources), | ||
| 824 | .resource = fsi_resources, | ||
| 825 | .dev = { | ||
| 826 | .platform_data = &fsi_info, | ||
| 827 | }, | ||
| 828 | }; | ||
| 829 | |||
| 830 | /* FSI-WM8978 */ | ||
| 831 | static struct asoc_simple_dai_init_info fsi_wm8978_init_info = { | ||
| 832 | .fmt = SND_SOC_DAIFMT_I2S, | ||
| 833 | .codec_daifmt = SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_NB_NF, | ||
| 834 | .cpu_daifmt = SND_SOC_DAIFMT_CBS_CFS, | ||
| 835 | .sysclk = 12288000, | ||
| 836 | }; | ||
| 837 | |||
| 838 | static struct asoc_simple_card_info fsi_wm8978_info = { | ||
| 839 | .name = "wm8978", | ||
| 840 | .card = "FSI2A-WM8978", | ||
| 841 | .cpu_dai = "fsia-dai", | ||
| 842 | .codec = "wm8978.0-001a", | ||
| 843 | .platform = "sh_fsi2", | ||
| 844 | .codec_dai = "wm8978-hifi", | ||
| 845 | .init = &fsi_wm8978_init_info, | ||
| 846 | }; | ||
| 847 | |||
| 848 | static struct platform_device fsi_wm8978_device = { | ||
| 849 | .name = "asoc-simple-card", | ||
| 850 | .id = 0, | ||
| 851 | .dev = { | ||
| 852 | .platform_data = &fsi_wm8978_info, | ||
| 853 | }, | ||
| 854 | }; | ||
| 855 | |||
| 856 | /* FSI-HDMI */ | ||
| 857 | static struct asoc_simple_dai_init_info fsi2_hdmi_init_info = { | ||
| 858 | .cpu_daifmt = SND_SOC_DAIFMT_CBM_CFM, | ||
| 859 | }; | ||
| 860 | |||
| 861 | static struct asoc_simple_card_info fsi2_hdmi_info = { | ||
| 862 | .name = "HDMI", | ||
| 863 | .card = "FSI2B-HDMI", | ||
| 864 | .cpu_dai = "fsib-dai", | ||
| 865 | .codec = "sh-mobile-hdmi", | ||
| 866 | .platform = "sh_fsi2", | ||
| 867 | .codec_dai = "sh_mobile_hdmi-hifi", | ||
| 868 | .init = &fsi2_hdmi_init_info, | ||
| 869 | }; | ||
| 870 | |||
| 871 | static struct platform_device fsi_hdmi_device = { | ||
| 872 | .name = "asoc-simple-card", | ||
| 873 | .id = 1, | ||
| 874 | .dev = { | ||
| 875 | .platform_data = &fsi2_hdmi_info, | ||
| 876 | }, | ||
| 877 | }; | ||
| 878 | |||
| 535 | /* I2C */ | 879 | /* I2C */ |
| 536 | static struct i2c_board_info i2c0_devices[] = { | 880 | static struct i2c_board_info i2c0_devices[] = { |
| 537 | { | 881 | { |
| 538 | I2C_BOARD_INFO("st1232-ts", 0x55), | 882 | I2C_BOARD_INFO("st1232-ts", 0x55), |
| 539 | .irq = evt2irq(0x0340), | 883 | .irq = evt2irq(0x0340), |
| 540 | }, | 884 | }, |
| 885 | { | ||
| 886 | I2C_BOARD_INFO("wm8978", 0x1a), | ||
| 887 | }, | ||
| 541 | }; | 888 | }; |
| 542 | 889 | ||
| 543 | /* | 890 | /* |
| @@ -549,6 +896,13 @@ static struct platform_device *eva_devices[] __initdata = { | |||
| 549 | &sh_eth_device, | 896 | &sh_eth_device, |
| 550 | &sdhi0_device, | 897 | &sdhi0_device, |
| 551 | &sh_mmcif_device, | 898 | &sh_mmcif_device, |
| 899 | &hdmi_device, | ||
| 900 | &hdmi_lcdc_device, | ||
| 901 | &camera_device, | ||
| 902 | &ceu0_device, | ||
| 903 | &fsi_device, | ||
| 904 | &fsi_hdmi_device, | ||
| 905 | &fsi_wm8978_device, | ||
| 552 | }; | 906 | }; |
| 553 | 907 | ||
| 554 | static void __init eva_clock_init(void) | 908 | static void __init eva_clock_init(void) |
| @@ -556,10 +910,14 @@ static void __init eva_clock_init(void) | |||
| 556 | struct clk *system = clk_get(NULL, "system_clk"); | 910 | struct clk *system = clk_get(NULL, "system_clk"); |
| 557 | struct clk *xtal1 = clk_get(NULL, "extal1"); | 911 | struct clk *xtal1 = clk_get(NULL, "extal1"); |
| 558 | struct clk *usb24s = clk_get(NULL, "usb24s"); | 912 | struct clk *usb24s = clk_get(NULL, "usb24s"); |
| 913 | struct clk *fsibck = clk_get(NULL, "fsibck"); | ||
| 914 | struct clk *fsib = clk_get(&fsi_device.dev, "ickb"); | ||
| 559 | 915 | ||
| 560 | if (IS_ERR(system) || | 916 | if (IS_ERR(system) || |
| 561 | IS_ERR(xtal1) || | 917 | IS_ERR(xtal1) || |
| 562 | IS_ERR(usb24s)) { | 918 | IS_ERR(usb24s) || |
| 919 | IS_ERR(fsibck) || | ||
| 920 | IS_ERR(fsib)) { | ||
| 563 | pr_err("armadillo800eva board clock init failed\n"); | 921 | pr_err("armadillo800eva board clock init failed\n"); |
| 564 | goto clock_error; | 922 | goto clock_error; |
| 565 | } | 923 | } |
| @@ -570,6 +928,11 @@ static void __init eva_clock_init(void) | |||
| 570 | /* usb24s use extal1 (= system) clock (= 24MHz) */ | 928 | /* usb24s use extal1 (= system) clock (= 24MHz) */ |
| 571 | clk_set_parent(usb24s, system); | 929 | clk_set_parent(usb24s, system); |
| 572 | 930 | ||
| 931 | /* FSIBCK is 12.288MHz, and it is parent of FSI-B */ | ||
| 932 | clk_set_parent(fsib, fsibck); | ||
| 933 | clk_set_rate(fsibck, 12288000); | ||
| 934 | clk_set_rate(fsib, 12288000); | ||
| 935 | |||
| 573 | clock_error: | 936 | clock_error: |
| 574 | if (!IS_ERR(system)) | 937 | if (!IS_ERR(system)) |
| 575 | clk_put(system); | 938 | clk_put(system); |
| @@ -577,16 +940,26 @@ clock_error: | |||
| 577 | clk_put(xtal1); | 940 | clk_put(xtal1); |
| 578 | if (!IS_ERR(usb24s)) | 941 | if (!IS_ERR(usb24s)) |
| 579 | clk_put(usb24s); | 942 | clk_put(usb24s); |
| 943 | if (!IS_ERR(fsibck)) | ||
| 944 | clk_put(fsibck); | ||
| 945 | if (!IS_ERR(fsib)) | ||
| 946 | clk_put(fsib); | ||
| 580 | } | 947 | } |
| 581 | 948 | ||
| 582 | /* | 949 | /* |
| 583 | * board init | 950 | * board init |
| 584 | */ | 951 | */ |
| 952 | #define GPIO_PORT7CR 0xe6050007 | ||
| 953 | #define GPIO_PORT8CR 0xe6050008 | ||
| 585 | static void __init eva_init(void) | 954 | static void __init eva_init(void) |
| 586 | { | 955 | { |
| 587 | eva_clock_init(); | 956 | struct platform_device *usb = NULL; |
| 957 | |||
| 958 | regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers, | ||
| 959 | ARRAY_SIZE(fixed3v3_power_consumers), 3300000); | ||
| 588 | 960 | ||
| 589 | r8a7740_pinmux_init(); | 961 | r8a7740_pinmux_init(); |
| 962 | r8a7740_meram_workaround(); | ||
| 590 | 963 | ||
| 591 | /* SCIFA1 */ | 964 | /* SCIFA1 */ |
| 592 | gpio_request(GPIO_FN_SCIFA1_RXD, NULL); | 965 | gpio_request(GPIO_FN_SCIFA1_RXD, NULL); |
| @@ -667,8 +1040,19 @@ static void __init eva_init(void) | |||
| 667 | /* USB Host */ | 1040 | /* USB Host */ |
| 668 | } else { | 1041 | } else { |
| 669 | /* USB Func */ | 1042 | /* USB Func */ |
| 670 | gpio_request(GPIO_FN_VBUS, NULL); | 1043 | /* |
| 1044 | * A1 chip has 2 IRQ7 pin and it was controled by MSEL register. | ||
| 1045 | * OTOH, usbhs interrupt needs its value (HI/LOW) to decide | ||
| 1046 | * USB connection/disconnection (usbhsf_get_vbus()). | ||
| 1047 | * This means we needs to select GPIO_FN_IRQ7_PORT209 first, | ||
| 1048 | * and select GPIO_PORT209 here | ||
| 1049 | */ | ||
| 1050 | gpio_request(GPIO_FN_IRQ7_PORT209, NULL); | ||
| 1051 | gpio_request(GPIO_PORT209, NULL); | ||
| 1052 | gpio_direction_input(GPIO_PORT209); | ||
| 1053 | |||
| 671 | platform_device_register(&usbhsf_device); | 1054 | platform_device_register(&usbhsf_device); |
| 1055 | usb = &usbhsf_device; | ||
| 672 | } | 1056 | } |
| 673 | 1057 | ||
| 674 | /* SDHI0 */ | 1058 | /* SDHI0 */ |
| @@ -706,6 +1090,48 @@ static void __init eva_init(void) | |||
| 706 | gpio_request(GPIO_FN_MMC1_D6_PORT143, NULL); | 1090 | gpio_request(GPIO_FN_MMC1_D6_PORT143, NULL); |
| 707 | gpio_request(GPIO_FN_MMC1_D7_PORT142, NULL); | 1091 | gpio_request(GPIO_FN_MMC1_D7_PORT142, NULL); |
| 708 | 1092 | ||
| 1093 | /* CEU0 */ | ||
| 1094 | gpio_request(GPIO_FN_VIO0_D7, NULL); | ||
| 1095 | gpio_request(GPIO_FN_VIO0_D6, NULL); | ||
| 1096 | gpio_request(GPIO_FN_VIO0_D5, NULL); | ||
| 1097 | gpio_request(GPIO_FN_VIO0_D4, NULL); | ||
| 1098 | gpio_request(GPIO_FN_VIO0_D3, NULL); | ||
| 1099 | gpio_request(GPIO_FN_VIO0_D2, NULL); | ||
| 1100 | gpio_request(GPIO_FN_VIO0_D1, NULL); | ||
| 1101 | gpio_request(GPIO_FN_VIO0_D0, NULL); | ||
| 1102 | gpio_request(GPIO_FN_VIO0_CLK, NULL); | ||
| 1103 | gpio_request(GPIO_FN_VIO0_HD, NULL); | ||
| 1104 | gpio_request(GPIO_FN_VIO0_VD, NULL); | ||
| 1105 | gpio_request(GPIO_FN_VIO0_FIELD, NULL); | ||
| 1106 | gpio_request(GPIO_FN_VIO_CKO, NULL); | ||
| 1107 | |||
| 1108 | /* CON1/CON15 Camera */ | ||
| 1109 | gpio_request(GPIO_PORT173, NULL); /* STANDBY */ | ||
| 1110 | gpio_request(GPIO_PORT172, NULL); /* RST */ | ||
| 1111 | gpio_request(GPIO_PORT158, NULL); /* CAM_PON */ | ||
| 1112 | gpio_direction_output(GPIO_PORT173, 0); | ||
| 1113 | gpio_direction_output(GPIO_PORT172, 1); | ||
| 1114 | gpio_direction_output(GPIO_PORT158, 0); /* see mt9t111_power() */ | ||
| 1115 | |||
| 1116 | /* FSI-WM8978 */ | ||
| 1117 | gpio_request(GPIO_FN_FSIAIBT, NULL); | ||
| 1118 | gpio_request(GPIO_FN_FSIAILR, NULL); | ||
| 1119 | gpio_request(GPIO_FN_FSIAOMC, NULL); | ||
| 1120 | gpio_request(GPIO_FN_FSIAOSLD, NULL); | ||
| 1121 | gpio_request(GPIO_FN_FSIAISLD_PORT5, NULL); | ||
| 1122 | |||
| 1123 | gpio_request(GPIO_PORT7, NULL); | ||
| 1124 | gpio_request(GPIO_PORT8, NULL); | ||
| 1125 | gpio_direction_none(GPIO_PORT7CR); /* FSIAOBT needs no direction */ | ||
| 1126 | gpio_direction_none(GPIO_PORT8CR); /* FSIAOLR needs no direction */ | ||
| 1127 | |||
| 1128 | /* FSI-HDMI */ | ||
| 1129 | gpio_request(GPIO_FN_FSIBCK, NULL); | ||
| 1130 | |||
| 1131 | /* HDMI */ | ||
| 1132 | gpio_request(GPIO_FN_HDMI_HPD, NULL); | ||
| 1133 | gpio_request(GPIO_FN_HDMI_CEC, NULL); | ||
| 1134 | |||
| 709 | /* | 1135 | /* |
| 710 | * CAUTION | 1136 | * CAUTION |
| 711 | * | 1137 | * |
| @@ -752,6 +1178,13 @@ static void __init eva_init(void) | |||
| 752 | 1178 | ||
| 753 | platform_add_devices(eva_devices, | 1179 | platform_add_devices(eva_devices, |
| 754 | ARRAY_SIZE(eva_devices)); | 1180 | ARRAY_SIZE(eva_devices)); |
| 1181 | |||
| 1182 | eva_clock_init(); | ||
| 1183 | |||
| 1184 | rmobile_add_device_to_domain(&r8a7740_pd_a4lc, &lcdc0_device); | ||
| 1185 | rmobile_add_device_to_domain(&r8a7740_pd_a4lc, &hdmi_lcdc_device); | ||
| 1186 | if (usb) | ||
| 1187 | rmobile_add_device_to_domain(&r8a7740_pd_a3sp, usb); | ||
| 755 | } | 1188 | } |
| 756 | 1189 | ||
| 757 | static void __init eva_earlytimer_init(void) | 1190 | static void __init eva_earlytimer_init(void) |
diff --git a/arch/arm/mach-shmobile/board-bonito.c b/arch/arm/mach-shmobile/board-bonito.c index e9b32cfbf741..4129008eae29 100644 --- a/arch/arm/mach-shmobile/board-bonito.c +++ b/arch/arm/mach-shmobile/board-bonito.c | |||
| @@ -26,6 +26,8 @@ | |||
| 26 | #include <linux/irq.h> | 26 | #include <linux/irq.h> |
| 27 | #include <linux/platform_device.h> | 27 | #include <linux/platform_device.h> |
| 28 | #include <linux/gpio.h> | 28 | #include <linux/gpio.h> |
| 29 | #include <linux/regulator/fixed.h> | ||
| 30 | #include <linux/regulator/machine.h> | ||
| 29 | #include <linux/smsc911x.h> | 31 | #include <linux/smsc911x.h> |
| 30 | #include <linux/videodev2.h> | 32 | #include <linux/videodev2.h> |
| 31 | #include <mach/common.h> | 33 | #include <mach/common.h> |
| @@ -75,6 +77,12 @@ | |||
| 75 | * S38.2 = OFF | 77 | * S38.2 = OFF |
| 76 | */ | 78 | */ |
| 77 | 79 | ||
| 80 | /* Dummy supplies, where voltage doesn't matter */ | ||
| 81 | static struct regulator_consumer_supply dummy_supplies[] = { | ||
| 82 | REGULATOR_SUPPLY("vddvario", "smsc911x"), | ||
| 83 | REGULATOR_SUPPLY("vdd33a", "smsc911x"), | ||
| 84 | }; | ||
| 85 | |||
| 78 | /* | 86 | /* |
| 79 | * FPGA | 87 | * FPGA |
| 80 | */ | 88 | */ |
| @@ -360,6 +368,8 @@ static void __init bonito_init(void) | |||
| 360 | { | 368 | { |
| 361 | u16 val; | 369 | u16 val; |
| 362 | 370 | ||
| 371 | regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); | ||
| 372 | |||
| 363 | r8a7740_pinmux_init(); | 373 | r8a7740_pinmux_init(); |
| 364 | bonito_fpga_init(); | 374 | bonito_fpga_init(); |
| 365 | 375 | ||
diff --git a/arch/arm/mach-shmobile/board-g4evm.c b/arch/arm/mach-shmobile/board-g4evm.c index f1257321999a..fa5dfc5c8ed6 100644 --- a/arch/arm/mach-shmobile/board-g4evm.c +++ b/arch/arm/mach-shmobile/board-g4evm.c | |||
| @@ -26,6 +26,8 @@ | |||
| 26 | #include <linux/mtd/mtd.h> | 26 | #include <linux/mtd/mtd.h> |
| 27 | #include <linux/mtd/partitions.h> | 27 | #include <linux/mtd/partitions.h> |
| 28 | #include <linux/mtd/physmap.h> | 28 | #include <linux/mtd/physmap.h> |
| 29 | #include <linux/regulator/fixed.h> | ||
| 30 | #include <linux/regulator/machine.h> | ||
| 29 | #include <linux/usb/r8a66597.h> | 31 | #include <linux/usb/r8a66597.h> |
| 30 | #include <linux/io.h> | 32 | #include <linux/io.h> |
| 31 | #include <linux/input.h> | 33 | #include <linux/input.h> |
| @@ -196,6 +198,15 @@ static struct platform_device keysc_device = { | |||
| 196 | }, | 198 | }, |
| 197 | }; | 199 | }; |
| 198 | 200 | ||
| 201 | /* Fixed 3.3V regulator to be used by SDHI0 and SDHI1 */ | ||
| 202 | static struct regulator_consumer_supply fixed3v3_power_consumers[] = | ||
| 203 | { | ||
| 204 | REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"), | ||
| 205 | REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"), | ||
| 206 | REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"), | ||
| 207 | REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.1"), | ||
| 208 | }; | ||
| 209 | |||
| 199 | /* SDHI */ | 210 | /* SDHI */ |
| 200 | static struct sh_mobile_sdhi_info sdhi0_info = { | 211 | static struct sh_mobile_sdhi_info sdhi0_info = { |
| 201 | .tmio_caps = MMC_CAP_SDIO_IRQ, | 212 | .tmio_caps = MMC_CAP_SDIO_IRQ, |
| @@ -271,26 +282,11 @@ static struct platform_device *g4evm_devices[] __initdata = { | |||
| 271 | #define GPIO_SDHID1_D3 0xe6052106 | 282 | #define GPIO_SDHID1_D3 0xe6052106 |
| 272 | #define GPIO_SDHICMD1 0xe6052107 | 283 | #define GPIO_SDHICMD1 0xe6052107 |
| 273 | 284 | ||
| 274 | /* | ||
| 275 | * FIXME !! | ||
| 276 | * | ||
| 277 | * gpio_pull_up is quick_hack. | ||
| 278 | * | ||
| 279 | * current gpio frame work doesn't have | ||
| 280 | * the method to control only pull up/down/free. | ||
| 281 | * this function should be replaced by correct gpio function | ||
| 282 | */ | ||
| 283 | static void __init gpio_pull_up(u32 addr) | ||
| 284 | { | ||
| 285 | u8 data = __raw_readb(addr); | ||
| 286 | |||
| 287 | data &= 0x0F; | ||
| 288 | data |= 0xC0; | ||
| 289 | __raw_writeb(data, addr); | ||
| 290 | } | ||
| 291 | |||
| 292 | static void __init g4evm_init(void) | 285 | static void __init g4evm_init(void) |
| 293 | { | 286 | { |
| 287 | regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers, | ||
| 288 | ARRAY_SIZE(fixed3v3_power_consumers), 3300000); | ||
| 289 | |||
| 294 | sh7377_pinmux_init(); | 290 | sh7377_pinmux_init(); |
| 295 | 291 | ||
| 296 | /* Lit DS14 LED */ | 292 | /* Lit DS14 LED */ |
| @@ -351,11 +347,11 @@ static void __init g4evm_init(void) | |||
| 351 | gpio_request(GPIO_FN_SDHID0_3, NULL); | 347 | gpio_request(GPIO_FN_SDHID0_3, NULL); |
| 352 | gpio_request(GPIO_FN_SDHICMD0, NULL); | 348 | gpio_request(GPIO_FN_SDHICMD0, NULL); |
| 353 | gpio_request(GPIO_FN_SDHIWP0, NULL); | 349 | gpio_request(GPIO_FN_SDHIWP0, NULL); |
| 354 | gpio_pull_up(GPIO_SDHID0_D0); | 350 | gpio_request_pullup(GPIO_SDHID0_D0); |
| 355 | gpio_pull_up(GPIO_SDHID0_D1); | 351 | gpio_request_pullup(GPIO_SDHID0_D1); |
| 356 | gpio_pull_up(GPIO_SDHID0_D2); | 352 | gpio_request_pullup(GPIO_SDHID0_D2); |
| 357 | gpio_pull_up(GPIO_SDHID0_D3); | 353 | gpio_request_pullup(GPIO_SDHID0_D3); |
| 358 | gpio_pull_up(GPIO_SDHICMD0); | 354 | gpio_request_pullup(GPIO_SDHICMD0); |
| 359 | 355 | ||
| 360 | /* SDHI1 */ | 356 | /* SDHI1 */ |
| 361 | gpio_request(GPIO_FN_SDHICLK1, NULL); | 357 | gpio_request(GPIO_FN_SDHICLK1, NULL); |
| @@ -364,11 +360,11 @@ static void __init g4evm_init(void) | |||
| 364 | gpio_request(GPIO_FN_SDHID1_2, NULL); | 360 | gpio_request(GPIO_FN_SDHID1_2, NULL); |
| 365 | gpio_request(GPIO_FN_SDHID1_3, NULL); | 361 | gpio_request(GPIO_FN_SDHID1_3, NULL); |
| 366 | gpio_request(GPIO_FN_SDHICMD1, NULL); | 362 | gpio_request(GPIO_FN_SDHICMD1, NULL); |
| 367 | gpio_pull_up(GPIO_SDHID1_D0); | 363 | gpio_request_pullup(GPIO_SDHID1_D0); |
| 368 | gpio_pull_up(GPIO_SDHID1_D1); | 364 | gpio_request_pullup(GPIO_SDHID1_D1); |
| 369 | gpio_pull_up(GPIO_SDHID1_D2); | 365 | gpio_request_pullup(GPIO_SDHID1_D2); |
| 370 | gpio_pull_up(GPIO_SDHID1_D3); | 366 | gpio_request_pullup(GPIO_SDHID1_D3); |
| 371 | gpio_pull_up(GPIO_SDHICMD1); | 367 | gpio_request_pullup(GPIO_SDHICMD1); |
| 372 | 368 | ||
| 373 | sh7377_add_standard_devices(); | 369 | sh7377_add_standard_devices(); |
| 374 | 370 | ||
diff --git a/arch/arm/mach-shmobile/board-kota2.c b/arch/arm/mach-shmobile/board-kota2.c index f60f1b281cc4..21dbe54304d5 100644 --- a/arch/arm/mach-shmobile/board-kota2.c +++ b/arch/arm/mach-shmobile/board-kota2.c | |||
| @@ -27,6 +27,8 @@ | |||
| 27 | #include <linux/platform_device.h> | 27 | #include <linux/platform_device.h> |
| 28 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
| 29 | #include <linux/io.h> | 29 | #include <linux/io.h> |
| 30 | #include <linux/regulator/fixed.h> | ||
| 31 | #include <linux/regulator/machine.h> | ||
| 30 | #include <linux/smsc911x.h> | 32 | #include <linux/smsc911x.h> |
| 31 | #include <linux/gpio.h> | 33 | #include <linux/gpio.h> |
| 32 | #include <linux/input.h> | 34 | #include <linux/input.h> |
| @@ -49,6 +51,12 @@ | |||
| 49 | #include <asm/hardware/cache-l2x0.h> | 51 | #include <asm/hardware/cache-l2x0.h> |
| 50 | #include <asm/traps.h> | 52 | #include <asm/traps.h> |
| 51 | 53 | ||
| 54 | /* Dummy supplies, where voltage doesn't matter */ | ||
| 55 | static struct regulator_consumer_supply dummy_supplies[] = { | ||
| 56 | REGULATOR_SUPPLY("vddvario", "smsc911x"), | ||
| 57 | REGULATOR_SUPPLY("vdd33a", "smsc911x"), | ||
| 58 | }; | ||
| 59 | |||
| 52 | /* SMSC 9220 */ | 60 | /* SMSC 9220 */ |
| 53 | static struct resource smsc9220_resources[] = { | 61 | static struct resource smsc9220_resources[] = { |
| 54 | [0] = { | 62 | [0] = { |
| @@ -288,6 +296,13 @@ static struct platform_device leds_tpu30_device = { | |||
| 288 | .resource = tpu30_resources, | 296 | .resource = tpu30_resources, |
| 289 | }; | 297 | }; |
| 290 | 298 | ||
| 299 | /* Fixed 1.8V regulator to be used by MMCIF */ | ||
| 300 | static struct regulator_consumer_supply fixed1v8_power_consumers[] = | ||
| 301 | { | ||
| 302 | REGULATOR_SUPPLY("vmmc", "sh_mmcif.0"), | ||
| 303 | REGULATOR_SUPPLY("vqmmc", "sh_mmcif.0"), | ||
| 304 | }; | ||
| 305 | |||
| 291 | /* MMCIF */ | 306 | /* MMCIF */ |
| 292 | static struct resource mmcif_resources[] = { | 307 | static struct resource mmcif_resources[] = { |
| 293 | [0] = { | 308 | [0] = { |
| @@ -321,6 +336,15 @@ static struct platform_device mmcif_device = { | |||
| 321 | .resource = mmcif_resources, | 336 | .resource = mmcif_resources, |
| 322 | }; | 337 | }; |
| 323 | 338 | ||
| 339 | /* Fixed 3.3V regulator to be used by SDHI0 and SDHI1 */ | ||
| 340 | static struct regulator_consumer_supply fixed3v3_power_consumers[] = | ||
| 341 | { | ||
| 342 | REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"), | ||
| 343 | REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"), | ||
| 344 | REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"), | ||
| 345 | REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.1"), | ||
| 346 | }; | ||
| 347 | |||
| 324 | /* SDHI0 */ | 348 | /* SDHI0 */ |
| 325 | static struct sh_mobile_sdhi_info sdhi0_info = { | 349 | static struct sh_mobile_sdhi_info sdhi0_info = { |
| 326 | .tmio_caps = MMC_CAP_SD_HIGHSPEED, | 350 | .tmio_caps = MMC_CAP_SD_HIGHSPEED, |
| @@ -411,6 +435,12 @@ static struct platform_device *kota2_devices[] __initdata = { | |||
| 411 | 435 | ||
| 412 | static void __init kota2_init(void) | 436 | static void __init kota2_init(void) |
| 413 | { | 437 | { |
| 438 | regulator_register_always_on(0, "fixed-1.8V", fixed1v8_power_consumers, | ||
| 439 | ARRAY_SIZE(fixed1v8_power_consumers), 1800000); | ||
| 440 | regulator_register_always_on(1, "fixed-3.3V", fixed3v3_power_consumers, | ||
| 441 | ARRAY_SIZE(fixed3v3_power_consumers), 3300000); | ||
| 442 | regulator_register_fixed(2, dummy_supplies, ARRAY_SIZE(dummy_supplies)); | ||
| 443 | |||
| 414 | sh73a0_pinmux_init(); | 444 | sh73a0_pinmux_init(); |
| 415 | 445 | ||
| 416 | /* SCIFA2 (UART2) */ | 446 | /* SCIFA2 (UART2) */ |
diff --git a/arch/arm/mach-shmobile/board-kzm9d.c b/arch/arm/mach-shmobile/board-kzm9d.c index 6a33cf393428..2c986eaae7b4 100644 --- a/arch/arm/mach-shmobile/board-kzm9d.c +++ b/arch/arm/mach-shmobile/board-kzm9d.c | |||
| @@ -21,6 +21,8 @@ | |||
| 21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
| 22 | #include <linux/interrupt.h> | 22 | #include <linux/interrupt.h> |
| 23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
| 24 | #include <linux/regulator/fixed.h> | ||
| 25 | #include <linux/regulator/machine.h> | ||
| 24 | #include <linux/smsc911x.h> | 26 | #include <linux/smsc911x.h> |
| 25 | #include <mach/common.h> | 27 | #include <mach/common.h> |
| 26 | #include <mach/emev2.h> | 28 | #include <mach/emev2.h> |
| @@ -28,6 +30,12 @@ | |||
| 28 | #include <asm/mach/arch.h> | 30 | #include <asm/mach/arch.h> |
| 29 | #include <asm/hardware/gic.h> | 31 | #include <asm/hardware/gic.h> |
| 30 | 32 | ||
| 33 | /* Dummy supplies, where voltage doesn't matter */ | ||
| 34 | static struct regulator_consumer_supply dummy_supplies[] = { | ||
| 35 | REGULATOR_SUPPLY("vddvario", "smsc911x"), | ||
| 36 | REGULATOR_SUPPLY("vdd33a", "smsc911x"), | ||
| 37 | }; | ||
| 38 | |||
| 31 | /* Ether */ | 39 | /* Ether */ |
| 32 | static struct resource smsc911x_resources[] = { | 40 | static struct resource smsc911x_resources[] = { |
| 33 | [0] = { | 41 | [0] = { |
| @@ -63,6 +71,8 @@ static struct platform_device *kzm9d_devices[] __initdata = { | |||
| 63 | 71 | ||
| 64 | void __init kzm9d_add_standard_devices(void) | 72 | void __init kzm9d_add_standard_devices(void) |
| 65 | { | 73 | { |
| 74 | regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); | ||
| 75 | |||
| 66 | emev2_add_standard_devices(); | 76 | emev2_add_standard_devices(); |
| 67 | 77 | ||
| 68 | platform_add_devices(kzm9d_devices, ARRAY_SIZE(kzm9d_devices)); | 78 | platform_add_devices(kzm9d_devices, ARRAY_SIZE(kzm9d_devices)); |
diff --git a/arch/arm/mach-shmobile/board-kzm9g.c b/arch/arm/mach-shmobile/board-kzm9g.c index c0ae815e7beb..53b7ea92c32c 100644 --- a/arch/arm/mach-shmobile/board-kzm9g.c +++ b/arch/arm/mach-shmobile/board-kzm9g.c | |||
| @@ -30,9 +30,14 @@ | |||
| 30 | #include <linux/mmc/sh_mobile_sdhi.h> | 30 | #include <linux/mmc/sh_mobile_sdhi.h> |
| 31 | #include <linux/mfd/tmio.h> | 31 | #include <linux/mfd/tmio.h> |
| 32 | #include <linux/platform_device.h> | 32 | #include <linux/platform_device.h> |
| 33 | #include <linux/regulator/fixed.h> | ||
| 34 | #include <linux/regulator/machine.h> | ||
| 33 | #include <linux/smsc911x.h> | 35 | #include <linux/smsc911x.h> |
| 34 | #include <linux/usb/r8a66597.h> | 36 | #include <linux/usb/r8a66597.h> |
| 37 | #include <linux/usb/renesas_usbhs.h> | ||
| 35 | #include <linux/videodev2.h> | 38 | #include <linux/videodev2.h> |
| 39 | #include <sound/sh_fsi.h> | ||
| 40 | #include <sound/simple_card.h> | ||
| 36 | #include <mach/irqs.h> | 41 | #include <mach/irqs.h> |
| 37 | #include <mach/sh73a0.h> | 42 | #include <mach/sh73a0.h> |
| 38 | #include <mach/common.h> | 43 | #include <mach/common.h> |
| @@ -54,6 +59,20 @@ | |||
| 54 | #define GPIO_PCF8575_PORT15 (GPIO_NR + 13) | 59 | #define GPIO_PCF8575_PORT15 (GPIO_NR + 13) |
| 55 | #define GPIO_PCF8575_PORT16 (GPIO_NR + 14) | 60 | #define GPIO_PCF8575_PORT16 (GPIO_NR + 14) |
| 56 | 61 | ||
| 62 | /* Dummy supplies, where voltage doesn't matter */ | ||
| 63 | static struct regulator_consumer_supply dummy_supplies[] = { | ||
| 64 | REGULATOR_SUPPLY("vddvario", "smsc911x"), | ||
| 65 | REGULATOR_SUPPLY("vdd33a", "smsc911x"), | ||
| 66 | }; | ||
| 67 | |||
| 68 | /* | ||
| 69 | * FSI-AK4648 | ||
| 70 | * | ||
| 71 | * this command is required when playback. | ||
| 72 | * | ||
| 73 | * # amixer set "LINEOUT Mixer DACL" on | ||
| 74 | */ | ||
| 75 | |||
| 57 | /* SMSC 9221 */ | 76 | /* SMSC 9221 */ |
| 58 | static struct resource smsc9221_resources[] = { | 77 | static struct resource smsc9221_resources[] = { |
| 59 | [0] = { | 78 | [0] = { |
| @@ -112,6 +131,151 @@ static struct platform_device usb_host_device = { | |||
| 112 | .resource = usb_resources, | 131 | .resource = usb_resources, |
| 113 | }; | 132 | }; |
| 114 | 133 | ||
| 134 | /* USB Func CN17 */ | ||
| 135 | struct usbhs_private { | ||
| 136 | unsigned int phy; | ||
| 137 | unsigned int cr2; | ||
| 138 | struct renesas_usbhs_platform_info info; | ||
| 139 | }; | ||
| 140 | |||
| 141 | #define IRQ15 intcs_evt2irq(0x03e0) | ||
| 142 | #define USB_PHY_MODE (1 << 4) | ||
| 143 | #define USB_PHY_INT_EN ((1 << 3) | (1 << 2)) | ||
| 144 | #define USB_PHY_ON (1 << 1) | ||
| 145 | #define USB_PHY_OFF (1 << 0) | ||
| 146 | #define USB_PHY_INT_CLR (USB_PHY_ON | USB_PHY_OFF) | ||
| 147 | |||
| 148 | #define usbhs_get_priv(pdev) \ | ||
| 149 | container_of(renesas_usbhs_get_info(pdev), struct usbhs_private, info) | ||
| 150 | |||
| 151 | static int usbhs_get_vbus(struct platform_device *pdev) | ||
| 152 | { | ||
| 153 | struct usbhs_private *priv = usbhs_get_priv(pdev); | ||
| 154 | |||
| 155 | return !((1 << 7) & __raw_readw(priv->cr2)); | ||
| 156 | } | ||
| 157 | |||
| 158 | static void usbhs_phy_reset(struct platform_device *pdev) | ||
| 159 | { | ||
| 160 | struct usbhs_private *priv = usbhs_get_priv(pdev); | ||
| 161 | |||
| 162 | /* init phy */ | ||
| 163 | __raw_writew(0x8a0a, priv->cr2); | ||
| 164 | } | ||
| 165 | |||
| 166 | static int usbhs_get_id(struct platform_device *pdev) | ||
| 167 | { | ||
| 168 | return USBHS_GADGET; | ||
| 169 | } | ||
| 170 | |||
| 171 | static irqreturn_t usbhs_interrupt(int irq, void *data) | ||
| 172 | { | ||
| 173 | struct platform_device *pdev = data; | ||
| 174 | struct usbhs_private *priv = usbhs_get_priv(pdev); | ||
| 175 | |||
| 176 | renesas_usbhs_call_notify_hotplug(pdev); | ||
| 177 | |||
| 178 | /* clear status */ | ||
| 179 | __raw_writew(__raw_readw(priv->phy) | USB_PHY_INT_CLR, priv->phy); | ||
| 180 | |||
| 181 | return IRQ_HANDLED; | ||
| 182 | } | ||
| 183 | |||
| 184 | static int usbhs_hardware_init(struct platform_device *pdev) | ||
| 185 | { | ||
| 186 | struct usbhs_private *priv = usbhs_get_priv(pdev); | ||
| 187 | int ret; | ||
| 188 | |||
| 189 | /* clear interrupt status */ | ||
| 190 | __raw_writew(USB_PHY_MODE | USB_PHY_INT_CLR, priv->phy); | ||
| 191 | |||
| 192 | ret = request_irq(IRQ15, usbhs_interrupt, IRQF_TRIGGER_HIGH, | ||
| 193 | dev_name(&pdev->dev), pdev); | ||
| 194 | if (ret) { | ||
| 195 | dev_err(&pdev->dev, "request_irq err\n"); | ||
| 196 | return ret; | ||
| 197 | } | ||
| 198 | |||
| 199 | /* enable USB phy interrupt */ | ||
| 200 | __raw_writew(USB_PHY_MODE | USB_PHY_INT_EN, priv->phy); | ||
| 201 | |||
| 202 | return 0; | ||
| 203 | } | ||
| 204 | |||
| 205 | static void usbhs_hardware_exit(struct platform_device *pdev) | ||
| 206 | { | ||
| 207 | struct usbhs_private *priv = usbhs_get_priv(pdev); | ||
| 208 | |||
| 209 | /* clear interrupt status */ | ||
| 210 | __raw_writew(USB_PHY_MODE | USB_PHY_INT_CLR, priv->phy); | ||
| 211 | |||
| 212 | free_irq(IRQ15, pdev); | ||
| 213 | } | ||
| 214 | |||
| 215 | static u32 usbhs_pipe_cfg[] = { | ||
| 216 | USB_ENDPOINT_XFER_CONTROL, | ||
| 217 | USB_ENDPOINT_XFER_ISOC, | ||
| 218 | USB_ENDPOINT_XFER_ISOC, | ||
| 219 | USB_ENDPOINT_XFER_BULK, | ||
| 220 | USB_ENDPOINT_XFER_BULK, | ||
| 221 | USB_ENDPOINT_XFER_BULK, | ||
| 222 | USB_ENDPOINT_XFER_INT, | ||
| 223 | USB_ENDPOINT_XFER_INT, | ||
| 224 | USB_ENDPOINT_XFER_INT, | ||
| 225 | USB_ENDPOINT_XFER_BULK, | ||
| 226 | USB_ENDPOINT_XFER_BULK, | ||
| 227 | USB_ENDPOINT_XFER_BULK, | ||
| 228 | USB_ENDPOINT_XFER_BULK, | ||
| 229 | USB_ENDPOINT_XFER_BULK, | ||
| 230 | USB_ENDPOINT_XFER_BULK, | ||
| 231 | USB_ENDPOINT_XFER_BULK, | ||
| 232 | }; | ||
| 233 | |||
| 234 | static struct usbhs_private usbhs_private = { | ||
| 235 | .phy = 0xe60781e0, /* USBPHYINT */ | ||
| 236 | .cr2 = 0xe605810c, /* USBCR2 */ | ||
| 237 | .info = { | ||
| 238 | .platform_callback = { | ||
| 239 | .hardware_init = usbhs_hardware_init, | ||
| 240 | .hardware_exit = usbhs_hardware_exit, | ||
| 241 | .get_id = usbhs_get_id, | ||
| 242 | .phy_reset = usbhs_phy_reset, | ||
| 243 | .get_vbus = usbhs_get_vbus, | ||
| 244 | }, | ||
| 245 | .driver_param = { | ||
| 246 | .buswait_bwait = 4, | ||
| 247 | .has_otg = 1, | ||
| 248 | .pipe_type = usbhs_pipe_cfg, | ||
| 249 | .pipe_size = ARRAY_SIZE(usbhs_pipe_cfg), | ||
| 250 | }, | ||
| 251 | }, | ||
| 252 | }; | ||
| 253 | |||
| 254 | static struct resource usbhs_resources[] = { | ||
| 255 | [0] = { | ||
| 256 | .start = 0xE6890000, | ||
| 257 | .end = 0xE68900e6 - 1, | ||
| 258 | .flags = IORESOURCE_MEM, | ||
| 259 | }, | ||
| 260 | [1] = { | ||
| 261 | .start = gic_spi(62), | ||
| 262 | .end = gic_spi(62), | ||
| 263 | .flags = IORESOURCE_IRQ, | ||
| 264 | }, | ||
| 265 | }; | ||
| 266 | |||
| 267 | static struct platform_device usbhs_device = { | ||
| 268 | .name = "renesas_usbhs", | ||
| 269 | .id = -1, | ||
| 270 | .dev = { | ||
| 271 | .dma_mask = NULL, | ||
| 272 | .coherent_dma_mask = 0xffffffff, | ||
| 273 | .platform_data = &usbhs_private.info, | ||
| 274 | }, | ||
| 275 | .num_resources = ARRAY_SIZE(usbhs_resources), | ||
| 276 | .resource = usbhs_resources, | ||
| 277 | }; | ||
| 278 | |||
| 115 | /* LCDC */ | 279 | /* LCDC */ |
| 116 | static struct fb_videomode kzm_lcdc_mode = { | 280 | static struct fb_videomode kzm_lcdc_mode = { |
| 117 | .name = "WVGA Panel", | 281 | .name = "WVGA Panel", |
| @@ -166,6 +330,13 @@ static struct platform_device lcdc_device = { | |||
| 166 | }, | 330 | }, |
| 167 | }; | 331 | }; |
| 168 | 332 | ||
| 333 | /* Fixed 1.8V regulator to be used by MMCIF */ | ||
| 334 | static struct regulator_consumer_supply fixed1v8_power_consumers[] = | ||
| 335 | { | ||
| 336 | REGULATOR_SUPPLY("vmmc", "sh_mmcif.0"), | ||
| 337 | REGULATOR_SUPPLY("vqmmc", "sh_mmcif.0"), | ||
| 338 | }; | ||
| 339 | |||
| 169 | /* MMCIF */ | 340 | /* MMCIF */ |
| 170 | static struct resource sh_mmcif_resources[] = { | 341 | static struct resource sh_mmcif_resources[] = { |
| 171 | [0] = { | 342 | [0] = { |
| @@ -187,6 +358,8 @@ static struct resource sh_mmcif_resources[] = { | |||
| 187 | static struct sh_mmcif_plat_data sh_mmcif_platdata = { | 358 | static struct sh_mmcif_plat_data sh_mmcif_platdata = { |
| 188 | .ocr = MMC_VDD_165_195, | 359 | .ocr = MMC_VDD_165_195, |
| 189 | .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE, | 360 | .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE, |
| 361 | .slave_id_tx = SHDMA_SLAVE_MMCIF_TX, | ||
| 362 | .slave_id_rx = SHDMA_SLAVE_MMCIF_RX, | ||
| 190 | }; | 363 | }; |
| 191 | 364 | ||
| 192 | static struct platform_device mmc_device = { | 365 | static struct platform_device mmc_device = { |
| @@ -200,6 +373,15 @@ static struct platform_device mmc_device = { | |||
| 200 | .resource = sh_mmcif_resources, | 373 | .resource = sh_mmcif_resources, |
| 201 | }; | 374 | }; |
| 202 | 375 | ||
| 376 | /* Fixed 2.8V regulators to be used by SDHI0 and SDHI2 */ | ||
| 377 | static struct regulator_consumer_supply fixed2v8_power_consumers[] = | ||
| 378 | { | ||
| 379 | REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"), | ||
| 380 | REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"), | ||
| 381 | REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.2"), | ||
| 382 | REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.2"), | ||
| 383 | }; | ||
| 384 | |||
| 203 | /* SDHI */ | 385 | /* SDHI */ |
| 204 | static struct sh_mobile_sdhi_info sdhi0_info = { | 386 | static struct sh_mobile_sdhi_info sdhi0_info = { |
| 205 | .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT, | 387 | .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT, |
| @@ -240,6 +422,50 @@ static struct platform_device sdhi0_device = { | |||
| 240 | }, | 422 | }, |
| 241 | }; | 423 | }; |
| 242 | 424 | ||
| 425 | /* Micro SD */ | ||
| 426 | static struct sh_mobile_sdhi_info sdhi2_info = { | ||
| 427 | .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | | ||
| 428 | TMIO_MMC_USE_GPIO_CD | | ||
| 429 | TMIO_MMC_WRPROTECT_DISABLE, | ||
| 430 | .tmio_caps = MMC_CAP_SD_HIGHSPEED, | ||
| 431 | .tmio_ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29, | ||
| 432 | .cd_gpio = GPIO_PORT13, | ||
| 433 | }; | ||
| 434 | |||
| 435 | static struct resource sdhi2_resources[] = { | ||
| 436 | [0] = { | ||
| 437 | .name = "SDHI2", | ||
| 438 | .start = 0xee140000, | ||
| 439 | .end = 0xee1400ff, | ||
| 440 | .flags = IORESOURCE_MEM, | ||
| 441 | }, | ||
| 442 | [1] = { | ||
| 443 | .name = SH_MOBILE_SDHI_IRQ_CARD_DETECT, | ||
| 444 | .start = gic_spi(103), | ||
| 445 | .flags = IORESOURCE_IRQ, | ||
| 446 | }, | ||
| 447 | [2] = { | ||
| 448 | .name = SH_MOBILE_SDHI_IRQ_SDCARD, | ||
| 449 | .start = gic_spi(104), | ||
| 450 | .flags = IORESOURCE_IRQ, | ||
| 451 | }, | ||
| 452 | [3] = { | ||
| 453 | .name = SH_MOBILE_SDHI_IRQ_SDIO, | ||
| 454 | .start = gic_spi(105), | ||
| 455 | .flags = IORESOURCE_IRQ, | ||
| 456 | }, | ||
| 457 | }; | ||
| 458 | |||
| 459 | static struct platform_device sdhi2_device = { | ||
| 460 | .name = "sh_mobile_sdhi", | ||
| 461 | .id = 2, | ||
| 462 | .num_resources = ARRAY_SIZE(sdhi2_resources), | ||
| 463 | .resource = sdhi2_resources, | ||
| 464 | .dev = { | ||
| 465 | .platform_data = &sdhi2_info, | ||
| 466 | }, | ||
| 467 | }; | ||
| 468 | |||
| 243 | /* KEY */ | 469 | /* KEY */ |
| 244 | #define GPIO_KEY(c, g, d) { .code = c, .gpio = g, .desc = d, .active_low = 1 } | 470 | #define GPIO_KEY(c, g, d) { .code = c, .gpio = g, .desc = d, .active_low = 1 } |
| 245 | 471 | ||
| @@ -267,11 +493,74 @@ static struct platform_device gpio_keys_device = { | |||
| 267 | }, | 493 | }, |
| 268 | }; | 494 | }; |
| 269 | 495 | ||
| 496 | /* FSI-AK4648 */ | ||
| 497 | static struct sh_fsi_platform_info fsi_info = { | ||
| 498 | .port_a = { | ||
| 499 | .tx_id = SHDMA_SLAVE_FSI2A_TX, | ||
| 500 | }, | ||
| 501 | }; | ||
| 502 | |||
| 503 | static struct resource fsi_resources[] = { | ||
| 504 | [0] = { | ||
| 505 | .name = "FSI", | ||
| 506 | .start = 0xEC230000, | ||
| 507 | .end = 0xEC230400 - 1, | ||
| 508 | .flags = IORESOURCE_MEM, | ||
| 509 | }, | ||
| 510 | [1] = { | ||
| 511 | .start = gic_spi(146), | ||
| 512 | .flags = IORESOURCE_IRQ, | ||
| 513 | }, | ||
| 514 | }; | ||
| 515 | |||
| 516 | static struct platform_device fsi_device = { | ||
| 517 | .name = "sh_fsi2", | ||
| 518 | .id = -1, | ||
| 519 | .num_resources = ARRAY_SIZE(fsi_resources), | ||
| 520 | .resource = fsi_resources, | ||
| 521 | .dev = { | ||
| 522 | .platform_data = &fsi_info, | ||
| 523 | }, | ||
| 524 | }; | ||
| 525 | |||
| 526 | static struct asoc_simple_dai_init_info fsi2_ak4648_init_info = { | ||
| 527 | .fmt = SND_SOC_DAIFMT_LEFT_J, | ||
| 528 | .codec_daifmt = SND_SOC_DAIFMT_CBM_CFM, | ||
| 529 | .cpu_daifmt = SND_SOC_DAIFMT_CBS_CFS, | ||
| 530 | .sysclk = 11289600, | ||
| 531 | }; | ||
| 532 | |||
| 533 | static struct asoc_simple_card_info fsi2_ak4648_info = { | ||
| 534 | .name = "AK4648", | ||
| 535 | .card = "FSI2A-AK4648", | ||
| 536 | .cpu_dai = "fsia-dai", | ||
| 537 | .codec = "ak4642-codec.0-0012", | ||
| 538 | .platform = "sh_fsi2", | ||
| 539 | .codec_dai = "ak4642-hifi", | ||
| 540 | .init = &fsi2_ak4648_init_info, | ||
| 541 | }; | ||
| 542 | |||
| 543 | static struct platform_device fsi_ak4648_device = { | ||
| 544 | .name = "asoc-simple-card", | ||
| 545 | .dev = { | ||
| 546 | .platform_data = &fsi2_ak4648_info, | ||
| 547 | }, | ||
| 548 | }; | ||
| 549 | |||
| 270 | /* I2C */ | 550 | /* I2C */ |
| 271 | static struct pcf857x_platform_data pcf8575_pdata = { | 551 | static struct pcf857x_platform_data pcf8575_pdata = { |
| 272 | .gpio_base = GPIO_PCF8575_BASE, | 552 | .gpio_base = GPIO_PCF8575_BASE, |
| 273 | }; | 553 | }; |
| 274 | 554 | ||
| 555 | static struct i2c_board_info i2c0_devices[] = { | ||
| 556 | { | ||
| 557 | I2C_BOARD_INFO("ak4648", 0x12), | ||
| 558 | }, | ||
| 559 | { | ||
| 560 | I2C_BOARD_INFO("r2025sd", 0x32), | ||
| 561 | } | ||
| 562 | }; | ||
| 563 | |||
| 275 | static struct i2c_board_info i2c1_devices[] = { | 564 | static struct i2c_board_info i2c1_devices[] = { |
| 276 | { | 565 | { |
| 277 | I2C_BOARD_INFO("st1232-ts", 0x55), | 566 | I2C_BOARD_INFO("st1232-ts", 0x55), |
| @@ -289,10 +578,14 @@ static struct i2c_board_info i2c3_devices[] = { | |||
| 289 | static struct platform_device *kzm_devices[] __initdata = { | 578 | static struct platform_device *kzm_devices[] __initdata = { |
| 290 | &smsc_device, | 579 | &smsc_device, |
| 291 | &usb_host_device, | 580 | &usb_host_device, |
| 581 | &usbhs_device, | ||
| 292 | &lcdc_device, | 582 | &lcdc_device, |
| 293 | &mmc_device, | 583 | &mmc_device, |
| 294 | &sdhi0_device, | 584 | &sdhi0_device, |
| 585 | &sdhi2_device, | ||
| 295 | &gpio_keys_device, | 586 | &gpio_keys_device, |
| 587 | &fsi_device, | ||
| 588 | &fsi_ak4648_device, | ||
| 296 | }; | 589 | }; |
| 297 | 590 | ||
| 298 | /* | 591 | /* |
| @@ -350,6 +643,12 @@ device_initcall(as3711_enable_lcdc_backlight); | |||
| 350 | 643 | ||
| 351 | static void __init kzm_init(void) | 644 | static void __init kzm_init(void) |
| 352 | { | 645 | { |
| 646 | regulator_register_always_on(0, "fixed-1.8V", fixed1v8_power_consumers, | ||
| 647 | ARRAY_SIZE(fixed1v8_power_consumers), 1800000); | ||
| 648 | regulator_register_always_on(1, "fixed-2.8V", fixed2v8_power_consumers, | ||
| 649 | ARRAY_SIZE(fixed2v8_power_consumers), 2800000); | ||
| 650 | regulator_register_fixed(2, dummy_supplies, ARRAY_SIZE(dummy_supplies)); | ||
| 651 | |||
| 353 | sh73a0_pinmux_init(); | 652 | sh73a0_pinmux_init(); |
| 354 | 653 | ||
| 355 | /* enable SCIFA4 */ | 654 | /* enable SCIFA4 */ |
| @@ -427,15 +726,36 @@ static void __init kzm_init(void) | |||
| 427 | gpio_request(GPIO_PORT15, NULL); | 726 | gpio_request(GPIO_PORT15, NULL); |
| 428 | gpio_direction_output(GPIO_PORT15, 1); /* power */ | 727 | gpio_direction_output(GPIO_PORT15, 1); /* power */ |
| 429 | 728 | ||
| 729 | /* enable Micro SD */ | ||
| 730 | gpio_request(GPIO_FN_SDHID2_0, NULL); | ||
| 731 | gpio_request(GPIO_FN_SDHID2_1, NULL); | ||
| 732 | gpio_request(GPIO_FN_SDHID2_2, NULL); | ||
| 733 | gpio_request(GPIO_FN_SDHID2_3, NULL); | ||
| 734 | gpio_request(GPIO_FN_SDHICMD2, NULL); | ||
| 735 | gpio_request(GPIO_FN_SDHICLK2, NULL); | ||
| 736 | gpio_request(GPIO_PORT14, NULL); | ||
| 737 | gpio_direction_output(GPIO_PORT14, 1); /* power */ | ||
| 738 | |||
| 430 | /* I2C 3 */ | 739 | /* I2C 3 */ |
| 431 | gpio_request(GPIO_FN_PORT27_I2C_SCL3, NULL); | 740 | gpio_request(GPIO_FN_PORT27_I2C_SCL3, NULL); |
| 432 | gpio_request(GPIO_FN_PORT28_I2C_SDA3, NULL); | 741 | gpio_request(GPIO_FN_PORT28_I2C_SDA3, NULL); |
| 433 | 742 | ||
| 743 | /* enable FSI2 port A (ak4648) */ | ||
| 744 | gpio_request(GPIO_FN_FSIACK, NULL); | ||
| 745 | gpio_request(GPIO_FN_FSIAILR, NULL); | ||
| 746 | gpio_request(GPIO_FN_FSIAIBT, NULL); | ||
| 747 | gpio_request(GPIO_FN_FSIAISLD, NULL); | ||
| 748 | gpio_request(GPIO_FN_FSIAOSLD, NULL); | ||
| 749 | |||
| 750 | /* enable USB */ | ||
| 751 | gpio_request(GPIO_FN_VBUS_0, NULL); | ||
| 752 | |||
| 434 | #ifdef CONFIG_CACHE_L2X0 | 753 | #ifdef CONFIG_CACHE_L2X0 |
| 435 | /* Early BRESP enable, Shared attribute override enable, 64K*8way */ | 754 | /* Early BRESP enable, Shared attribute override enable, 64K*8way */ |
| 436 | l2x0_init(IOMEM(0xf0100000), 0x40460000, 0x82000fff); | 755 | l2x0_init(IOMEM(0xf0100000), 0x40460000, 0x82000fff); |
| 437 | #endif | 756 | #endif |
| 438 | 757 | ||
| 758 | i2c_register_board_info(0, i2c0_devices, ARRAY_SIZE(i2c0_devices)); | ||
| 439 | i2c_register_board_info(1, i2c1_devices, ARRAY_SIZE(i2c1_devices)); | 759 | i2c_register_board_info(1, i2c1_devices, ARRAY_SIZE(i2c1_devices)); |
| 440 | i2c_register_board_info(3, i2c3_devices, ARRAY_SIZE(i2c3_devices)); | 760 | i2c_register_board_info(3, i2c3_devices, ARRAY_SIZE(i2c3_devices)); |
| 441 | 761 | ||
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c index 150122a44630..7ea2b31e3199 100644 --- a/arch/arm/mach-shmobile/board-mackerel.c +++ b/arch/arm/mach-shmobile/board-mackerel.c | |||
| @@ -41,6 +41,8 @@ | |||
| 41 | #include <linux/mtd/physmap.h> | 41 | #include <linux/mtd/physmap.h> |
| 42 | #include <linux/mtd/sh_flctl.h> | 42 | #include <linux/mtd/sh_flctl.h> |
| 43 | #include <linux/pm_clock.h> | 43 | #include <linux/pm_clock.h> |
| 44 | #include <linux/regulator/fixed.h> | ||
| 45 | #include <linux/regulator/machine.h> | ||
| 44 | #include <linux/smsc911x.h> | 46 | #include <linux/smsc911x.h> |
| 45 | #include <linux/sh_intc.h> | 47 | #include <linux/sh_intc.h> |
| 46 | #include <linux/tca6416_keypad.h> | 48 | #include <linux/tca6416_keypad.h> |
| @@ -203,31 +205,32 @@ | |||
| 203 | * amixer set "HPOUTR Mixer DACH" on | 205 | * amixer set "HPOUTR Mixer DACH" on |
| 204 | */ | 206 | */ |
| 205 | 207 | ||
| 206 | /* | 208 | /* Fixed 3.3V and 1.8V regulators to be used by multiple devices */ |
| 207 | * FIXME !! | 209 | static struct regulator_consumer_supply fixed1v8_power_consumers[] = |
| 208 | * | ||
| 209 | * gpio_no_direction | ||
| 210 | * gpio_pull_down | ||
| 211 | * are quick_hack. | ||
| 212 | * | ||
| 213 | * current gpio frame work doesn't have | ||
| 214 | * the method to control only pull up/down/free. | ||
| 215 | * this function should be replaced by correct gpio function | ||
| 216 | */ | ||
| 217 | static void __init gpio_no_direction(u32 addr) | ||
| 218 | { | 210 | { |
| 219 | __raw_writeb(0x00, addr); | 211 | /* |
| 220 | } | 212 | * J22 on mackerel switches mmcif.0 and sdhi.1 between 1.8V and 3.3V |
| 213 | * Since we cannot support both voltages, we support the default 1.8V | ||
| 214 | */ | ||
| 215 | REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"), | ||
| 216 | REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.1"), | ||
| 217 | REGULATOR_SUPPLY("vmmc", "sh_mmcif.0"), | ||
| 218 | REGULATOR_SUPPLY("vqmmc", "sh_mmcif.0"), | ||
| 219 | }; | ||
| 221 | 220 | ||
| 222 | static void __init gpio_pull_down(u32 addr) | 221 | static struct regulator_consumer_supply fixed3v3_power_consumers[] = |
| 223 | { | 222 | { |
| 224 | u8 data = __raw_readb(addr); | 223 | REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"), |
| 225 | 224 | REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"), | |
| 226 | data &= 0x0F; | 225 | REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.2"), |
| 227 | data |= 0xA0; | 226 | REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.2"), |
| 227 | }; | ||
| 228 | 228 | ||
| 229 | __raw_writeb(data, addr); | 229 | /* Dummy supplies, where voltage doesn't matter */ |
| 230 | } | 230 | static struct regulator_consumer_supply dummy_supplies[] = { |
| 231 | REGULATOR_SUPPLY("vddvario", "smsc911x"), | ||
| 232 | REGULATOR_SUPPLY("vdd33a", "smsc911x"), | ||
| 233 | }; | ||
| 231 | 234 | ||
| 232 | /* MTD */ | 235 | /* MTD */ |
| 233 | static struct mtd_partition nor_flash_partitions[] = { | 236 | static struct mtd_partition nor_flash_partitions[] = { |
| @@ -1409,6 +1412,12 @@ static void __init mackerel_init(void) | |||
| 1409 | u32 srcr4; | 1412 | u32 srcr4; |
| 1410 | struct clk *clk; | 1413 | struct clk *clk; |
| 1411 | 1414 | ||
| 1415 | regulator_register_always_on(0, "fixed-1.8V", fixed1v8_power_consumers, | ||
| 1416 | ARRAY_SIZE(fixed1v8_power_consumers), 1800000); | ||
| 1417 | regulator_register_always_on(1, "fixed-3.3V", fixed3v3_power_consumers, | ||
| 1418 | ARRAY_SIZE(fixed3v3_power_consumers), 3300000); | ||
| 1419 | regulator_register_fixed(2, dummy_supplies, ARRAY_SIZE(dummy_supplies)); | ||
| 1420 | |||
| 1412 | /* External clock source */ | 1421 | /* External clock source */ |
| 1413 | clk_set_rate(&sh7372_dv_clki_clk, 27000000); | 1422 | clk_set_rate(&sh7372_dv_clki_clk, 27000000); |
| 1414 | 1423 | ||
| @@ -1458,11 +1467,11 @@ static void __init mackerel_init(void) | |||
| 1458 | 1467 | ||
| 1459 | /* USBHS0 */ | 1468 | /* USBHS0 */ |
| 1460 | gpio_request(GPIO_FN_VBUS0_0, NULL); | 1469 | gpio_request(GPIO_FN_VBUS0_0, NULL); |
| 1461 | gpio_pull_down(GPIO_PORT168CR); /* VBUS0_0 pull down */ | 1470 | gpio_request_pulldown(GPIO_PORT168CR); /* VBUS0_0 pull down */ |
| 1462 | 1471 | ||
| 1463 | /* USBHS1 */ | 1472 | /* USBHS1 */ |
| 1464 | gpio_request(GPIO_FN_VBUS0_1, NULL); | 1473 | gpio_request(GPIO_FN_VBUS0_1, NULL); |
| 1465 | gpio_pull_down(GPIO_PORT167CR); /* VBUS0_1 pull down */ | 1474 | gpio_request_pulldown(GPIO_PORT167CR); /* VBUS0_1 pull down */ |
| 1466 | gpio_request(GPIO_FN_IDIN_1_113, NULL); | 1475 | gpio_request(GPIO_FN_IDIN_1_113, NULL); |
| 1467 | 1476 | ||
| 1468 | /* enable FSI2 port A (ak4643) */ | 1477 | /* enable FSI2 port A (ak4643) */ |
| @@ -1475,8 +1484,8 @@ static void __init mackerel_init(void) | |||
| 1475 | 1484 | ||
| 1476 | gpio_request(GPIO_PORT9, NULL); | 1485 | gpio_request(GPIO_PORT9, NULL); |
| 1477 | gpio_request(GPIO_PORT10, NULL); | 1486 | gpio_request(GPIO_PORT10, NULL); |
| 1478 | gpio_no_direction(GPIO_PORT9CR); /* FSIAOBT needs no direction */ | 1487 | gpio_direction_none(GPIO_PORT9CR); /* FSIAOBT needs no direction */ |
| 1479 | gpio_no_direction(GPIO_PORT10CR); /* FSIAOLR needs no direction */ | 1488 | gpio_direction_none(GPIO_PORT10CR); /* FSIAOLR needs no direction */ |
| 1480 | 1489 | ||
| 1481 | intc_set_priority(IRQ_FSI, 3); /* irq priority FSI(3) > SMSC911X(2) */ | 1490 | intc_set_priority(IRQ_FSI, 3); /* irq priority FSI(3) > SMSC911X(2) */ |
| 1482 | 1491 | ||
| @@ -1614,20 +1623,20 @@ static void __init mackerel_init(void) | |||
| 1614 | 1623 | ||
| 1615 | platform_add_devices(mackerel_devices, ARRAY_SIZE(mackerel_devices)); | 1624 | platform_add_devices(mackerel_devices, ARRAY_SIZE(mackerel_devices)); |
| 1616 | 1625 | ||
| 1617 | sh7372_add_device_to_domain(&sh7372_a4lc, &lcdc_device); | 1626 | rmobile_add_device_to_domain(&sh7372_pd_a4lc, &lcdc_device); |
| 1618 | sh7372_add_device_to_domain(&sh7372_a4lc, &hdmi_lcdc_device); | 1627 | rmobile_add_device_to_domain(&sh7372_pd_a4lc, &hdmi_lcdc_device); |
| 1619 | sh7372_add_device_to_domain(&sh7372_a4lc, &meram_device); | 1628 | rmobile_add_device_to_domain(&sh7372_pd_a4lc, &meram_device); |
| 1620 | sh7372_add_device_to_domain(&sh7372_a4mp, &fsi_device); | 1629 | rmobile_add_device_to_domain(&sh7372_pd_a4mp, &fsi_device); |
| 1621 | sh7372_add_device_to_domain(&sh7372_a3sp, &usbhs0_device); | 1630 | rmobile_add_device_to_domain(&sh7372_pd_a3sp, &usbhs0_device); |
| 1622 | sh7372_add_device_to_domain(&sh7372_a3sp, &usbhs1_device); | 1631 | rmobile_add_device_to_domain(&sh7372_pd_a3sp, &usbhs1_device); |
| 1623 | sh7372_add_device_to_domain(&sh7372_a3sp, &nand_flash_device); | 1632 | rmobile_add_device_to_domain(&sh7372_pd_a3sp, &nand_flash_device); |
| 1624 | sh7372_add_device_to_domain(&sh7372_a3sp, &sh_mmcif_device); | 1633 | rmobile_add_device_to_domain(&sh7372_pd_a3sp, &sh_mmcif_device); |
| 1625 | sh7372_add_device_to_domain(&sh7372_a3sp, &sdhi0_device); | 1634 | rmobile_add_device_to_domain(&sh7372_pd_a3sp, &sdhi0_device); |
| 1626 | #if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) | 1635 | #if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) |
| 1627 | sh7372_add_device_to_domain(&sh7372_a3sp, &sdhi1_device); | 1636 | rmobile_add_device_to_domain(&sh7372_pd_a3sp, &sdhi1_device); |
| 1628 | #endif | 1637 | #endif |
| 1629 | sh7372_add_device_to_domain(&sh7372_a3sp, &sdhi2_device); | 1638 | rmobile_add_device_to_domain(&sh7372_pd_a3sp, &sdhi2_device); |
| 1630 | sh7372_add_device_to_domain(&sh7372_a4r, &ceu_device); | 1639 | rmobile_add_device_to_domain(&sh7372_pd_a4r, &ceu_device); |
| 1631 | 1640 | ||
| 1632 | hdmi_init_pm_clock(); | 1641 | hdmi_init_pm_clock(); |
| 1633 | sh7372_pm_init(); | 1642 | sh7372_pm_init(); |
diff --git a/arch/arm/mach-shmobile/board-marzen.c b/arch/arm/mach-shmobile/board-marzen.c index 14de3787cafc..3a528cf4366c 100644 --- a/arch/arm/mach-shmobile/board-marzen.c +++ b/arch/arm/mach-shmobile/board-marzen.c | |||
| @@ -27,6 +27,8 @@ | |||
| 27 | #include <linux/io.h> | 27 | #include <linux/io.h> |
| 28 | #include <linux/gpio.h> | 28 | #include <linux/gpio.h> |
| 29 | #include <linux/dma-mapping.h> | 29 | #include <linux/dma-mapping.h> |
| 30 | #include <linux/regulator/fixed.h> | ||
| 31 | #include <linux/regulator/machine.h> | ||
| 30 | #include <linux/smsc911x.h> | 32 | #include <linux/smsc911x.h> |
| 31 | #include <mach/hardware.h> | 33 | #include <mach/hardware.h> |
| 32 | #include <mach/r8a7779.h> | 34 | #include <mach/r8a7779.h> |
| @@ -37,6 +39,12 @@ | |||
| 37 | #include <asm/hardware/gic.h> | 39 | #include <asm/hardware/gic.h> |
| 38 | #include <asm/traps.h> | 40 | #include <asm/traps.h> |
| 39 | 41 | ||
| 42 | /* Dummy supplies, where voltage doesn't matter */ | ||
| 43 | static struct regulator_consumer_supply dummy_supplies[] = { | ||
| 44 | REGULATOR_SUPPLY("vddvario", "smsc911x"), | ||
| 45 | REGULATOR_SUPPLY("vdd33a", "smsc911x"), | ||
| 46 | }; | ||
| 47 | |||
| 40 | /* SMSC LAN89218 */ | 48 | /* SMSC LAN89218 */ |
| 41 | static struct resource smsc911x_resources[] = { | 49 | static struct resource smsc911x_resources[] = { |
| 42 | [0] = { | 50 | [0] = { |
| @@ -73,6 +81,8 @@ static struct platform_device *marzen_devices[] __initdata = { | |||
| 73 | 81 | ||
| 74 | static void __init marzen_init(void) | 82 | static void __init marzen_init(void) |
| 75 | { | 83 | { |
| 84 | regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); | ||
| 85 | |||
| 76 | r8a7779_pinmux_init(); | 86 | r8a7779_pinmux_init(); |
| 77 | 87 | ||
| 78 | /* SCIF2 (CN18: DEBUG0) */ | 88 | /* SCIF2 (CN18: DEBUG0) */ |
diff --git a/arch/arm/mach-shmobile/clock-r8a7740.c b/arch/arm/mach-shmobile/clock-r8a7740.c index 26eea5f21054..ad5fccc7b5e7 100644 --- a/arch/arm/mach-shmobile/clock-r8a7740.c +++ b/arch/arm/mach-shmobile/clock-r8a7740.c | |||
| @@ -43,7 +43,10 @@ | |||
| 43 | /* CPG registers */ | 43 | /* CPG registers */ |
| 44 | #define FRQCRA 0xe6150000 | 44 | #define FRQCRA 0xe6150000 |
| 45 | #define FRQCRB 0xe6150004 | 45 | #define FRQCRB 0xe6150004 |
| 46 | #define VCLKCR1 0xE6150008 | ||
| 47 | #define VCLKCR2 0xE615000c | ||
| 46 | #define FRQCRC 0xe61500e0 | 48 | #define FRQCRC 0xe61500e0 |
| 49 | #define FSIACKCR 0xe6150018 | ||
| 47 | #define PLLC01CR 0xe6150028 | 50 | #define PLLC01CR 0xe6150028 |
| 48 | 51 | ||
| 49 | #define SUBCKCR 0xe6150080 | 52 | #define SUBCKCR 0xe6150080 |
| @@ -54,6 +57,8 @@ | |||
| 54 | #define MSTPSR2 0xe6150040 | 57 | #define MSTPSR2 0xe6150040 |
| 55 | #define MSTPSR3 0xe6150048 | 58 | #define MSTPSR3 0xe6150048 |
| 56 | #define MSTPSR4 0xe615004c | 59 | #define MSTPSR4 0xe615004c |
| 60 | #define FSIBCKCR 0xe6150090 | ||
| 61 | #define HDMICKCR 0xe6150094 | ||
| 57 | #define SMSTPCR0 0xe6150130 | 62 | #define SMSTPCR0 0xe6150130 |
| 58 | #define SMSTPCR1 0xe6150134 | 63 | #define SMSTPCR1 0xe6150134 |
| 59 | #define SMSTPCR2 0xe6150138 | 64 | #define SMSTPCR2 0xe6150138 |
| @@ -271,6 +276,13 @@ static struct clk usb24_clk = { | |||
| 271 | .parent = &usb24s_clk, | 276 | .parent = &usb24s_clk, |
| 272 | }; | 277 | }; |
| 273 | 278 | ||
| 279 | /* External FSIACK/FSIBCK clock */ | ||
| 280 | static struct clk fsiack_clk = { | ||
| 281 | }; | ||
| 282 | |||
| 283 | static struct clk fsibck_clk = { | ||
| 284 | }; | ||
| 285 | |||
| 274 | struct clk *main_clks[] = { | 286 | struct clk *main_clks[] = { |
| 275 | &extalr_clk, | 287 | &extalr_clk, |
| 276 | &extal1_clk, | 288 | &extal1_clk, |
| @@ -288,6 +300,8 @@ struct clk *main_clks[] = { | |||
| 288 | &pllc1_div2_clk, | 300 | &pllc1_div2_clk, |
| 289 | &usb24s_clk, | 301 | &usb24s_clk, |
| 290 | &usb24_clk, | 302 | &usb24_clk, |
| 303 | &fsiack_clk, | ||
| 304 | &fsibck_clk, | ||
| 291 | }; | 305 | }; |
| 292 | 306 | ||
| 293 | static void div4_kick(struct clk *clk) | 307 | static void div4_kick(struct clk *clk) |
| @@ -313,6 +327,107 @@ static struct clk_div4_table div4_table = { | |||
| 313 | .kick = div4_kick, | 327 | .kick = div4_kick, |
| 314 | }; | 328 | }; |
| 315 | 329 | ||
| 330 | /* DIV6 reparent */ | ||
| 331 | enum { | ||
| 332 | DIV6_HDMI, | ||
| 333 | DIV6_VCLK1, DIV6_VCLK2, | ||
| 334 | DIV6_FSIA, DIV6_FSIB, | ||
| 335 | DIV6_REPARENT_NR, | ||
| 336 | }; | ||
| 337 | |||
| 338 | static struct clk *hdmi_parent[] = { | ||
| 339 | [0] = &pllc1_div2_clk, | ||
| 340 | [1] = &system_clk, | ||
| 341 | [2] = &dv_clk | ||
| 342 | }; | ||
| 343 | |||
| 344 | static struct clk *vclk_parents[8] = { | ||
| 345 | [0] = &pllc1_div2_clk, | ||
| 346 | [2] = &dv_clk, | ||
| 347 | [3] = &usb24s_clk, | ||
| 348 | [4] = &extal1_div2_clk, | ||
| 349 | [5] = &extalr_clk, | ||
| 350 | }; | ||
| 351 | |||
| 352 | static struct clk *fsia_parents[] = { | ||
| 353 | [0] = &pllc1_div2_clk, | ||
| 354 | [1] = &fsiack_clk, /* external clock */ | ||
| 355 | }; | ||
| 356 | |||
| 357 | static struct clk *fsib_parents[] = { | ||
| 358 | [0] = &pllc1_div2_clk, | ||
| 359 | [1] = &fsibck_clk, /* external clock */ | ||
| 360 | }; | ||
| 361 | |||
| 362 | static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = { | ||
| 363 | [DIV6_HDMI] = SH_CLK_DIV6_EXT(HDMICKCR, 0, | ||
| 364 | hdmi_parent, ARRAY_SIZE(hdmi_parent), 6, 2), | ||
| 365 | [DIV6_VCLK1] = SH_CLK_DIV6_EXT(VCLKCR1, 0, | ||
| 366 | vclk_parents, ARRAY_SIZE(vclk_parents), 12, 3), | ||
| 367 | [DIV6_VCLK2] = SH_CLK_DIV6_EXT(VCLKCR2, 0, | ||
| 368 | vclk_parents, ARRAY_SIZE(vclk_parents), 12, 3), | ||
| 369 | [DIV6_FSIA] = SH_CLK_DIV6_EXT(FSIACKCR, 0, | ||
| 370 | fsia_parents, ARRAY_SIZE(fsia_parents), 6, 2), | ||
| 371 | [DIV6_FSIB] = SH_CLK_DIV6_EXT(FSIBCKCR, 0, | ||
| 372 | fsib_parents, ARRAY_SIZE(fsib_parents), 6, 2), | ||
| 373 | }; | ||
| 374 | |||
| 375 | /* HDMI1/2 clock */ | ||
| 376 | static unsigned long hdmi12_recalc(struct clk *clk) | ||
| 377 | { | ||
| 378 | u32 val = __raw_readl(HDMICKCR); | ||
| 379 | int shift = (int)clk->priv; | ||
| 380 | |||
| 381 | val >>= shift; | ||
| 382 | val &= 0x3; | ||
| 383 | |||
| 384 | return clk->parent->rate / (1 << val); | ||
| 385 | }; | ||
| 386 | |||
| 387 | static int hdmi12_set_rate(struct clk *clk, unsigned long rate) | ||
| 388 | { | ||
| 389 | u32 val, mask; | ||
| 390 | int i, shift; | ||
| 391 | |||
| 392 | for (i = 0; i < 3; i++) | ||
| 393 | if (rate == clk->parent->rate / (1 << i)) | ||
| 394 | goto find; | ||
| 395 | return -ENODEV; | ||
| 396 | |||
| 397 | find: | ||
| 398 | shift = (int)clk->priv; | ||
| 399 | |||
| 400 | val = __raw_readl(HDMICKCR); | ||
| 401 | mask = ~(0x3 << shift); | ||
| 402 | val = (val & mask) | i << shift; | ||
| 403 | __raw_writel(val, HDMICKCR); | ||
| 404 | |||
| 405 | return 0; | ||
| 406 | }; | ||
| 407 | |||
| 408 | static struct sh_clk_ops hdmi12_clk_ops = { | ||
| 409 | .recalc = hdmi12_recalc, | ||
| 410 | .set_rate = hdmi12_set_rate, | ||
| 411 | }; | ||
| 412 | |||
| 413 | static struct clk hdmi1_clk = { | ||
| 414 | .ops = &hdmi12_clk_ops, | ||
| 415 | .priv = (void *)9, | ||
| 416 | .parent = &div6_reparent_clks[DIV6_HDMI], /* late install */ | ||
| 417 | }; | ||
| 418 | |||
| 419 | static struct clk hdmi2_clk = { | ||
| 420 | .ops = &hdmi12_clk_ops, | ||
| 421 | .priv = (void *)11, | ||
| 422 | .parent = &div6_reparent_clks[DIV6_HDMI], /* late install */ | ||
| 423 | }; | ||
| 424 | |||
| 425 | static struct clk *late_main_clks[] = { | ||
| 426 | &hdmi1_clk, | ||
| 427 | &hdmi2_clk, | ||
| 428 | }; | ||
| 429 | |||
| 430 | /* MSTP */ | ||
| 316 | enum { | 431 | enum { |
| 317 | DIV4_I, DIV4_ZG, DIV4_B, DIV4_M1, DIV4_HP, | 432 | DIV4_I, DIV4_ZG, DIV4_B, DIV4_M1, DIV4_HP, |
| 318 | DIV4_HPP, DIV4_USBP, DIV4_S, DIV4_ZB, DIV4_M3, DIV4_CP, | 433 | DIV4_HPP, DIV4_USBP, DIV4_S, DIV4_ZB, DIV4_M3, DIV4_CP, |
| @@ -343,11 +458,12 @@ static struct clk div6_clks[DIV6_NR] = { | |||
| 343 | }; | 458 | }; |
| 344 | 459 | ||
| 345 | enum { | 460 | enum { |
| 346 | MSTP125, | 461 | MSTP128, MSTP127, MSTP125, |
| 347 | MSTP116, MSTP111, MSTP100, MSTP117, | 462 | MSTP116, MSTP111, MSTP100, MSTP117, |
| 348 | 463 | ||
| 349 | MSTP230, | 464 | MSTP230, |
| 350 | MSTP222, | 465 | MSTP222, |
| 466 | MSTP218, MSTP217, MSTP216, MSTP214, | ||
| 351 | MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200, | 467 | MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200, |
| 352 | 468 | ||
| 353 | MSTP329, MSTP328, MSTP323, MSTP320, | 469 | MSTP329, MSTP328, MSTP323, MSTP320, |
| @@ -360,6 +476,8 @@ enum { | |||
| 360 | }; | 476 | }; |
| 361 | 477 | ||
| 362 | static struct clk mstp_clks[MSTP_NR] = { | 478 | static struct clk mstp_clks[MSTP_NR] = { |
| 479 | [MSTP128] = SH_CLK_MSTP32(&div4_clks[DIV4_S], SMSTPCR1, 28, 0), /* CEU21 */ | ||
| 480 | [MSTP127] = SH_CLK_MSTP32(&div4_clks[DIV4_S], SMSTPCR1, 27, 0), /* CEU20 */ | ||
| 363 | [MSTP125] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */ | 481 | [MSTP125] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */ |
| 364 | [MSTP117] = SH_CLK_MSTP32(&div4_clks[DIV4_B], SMSTPCR1, 17, 0), /* LCDC1 */ | 482 | [MSTP117] = SH_CLK_MSTP32(&div4_clks[DIV4_B], SMSTPCR1, 17, 0), /* LCDC1 */ |
| 365 | [MSTP116] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */ | 483 | [MSTP116] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */ |
| @@ -368,6 +486,10 @@ static struct clk mstp_clks[MSTP_NR] = { | |||
| 368 | 486 | ||
| 369 | [MSTP230] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 30, 0), /* SCIFA6 */ | 487 | [MSTP230] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 30, 0), /* SCIFA6 */ |
| 370 | [MSTP222] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 22, 0), /* SCIFA7 */ | 488 | [MSTP222] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 22, 0), /* SCIFA7 */ |
| 489 | [MSTP218] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* DMAC1 */ | ||
| 490 | [MSTP217] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR2, 17, 0), /* DMAC2 */ | ||
| 491 | [MSTP216] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR2, 16, 0), /* DMAC3 */ | ||
| 492 | [MSTP214] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR2, 14, 0), /* USBDMAC */ | ||
| 371 | [MSTP207] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */ | 493 | [MSTP207] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */ |
| 372 | [MSTP206] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */ | 494 | [MSTP206] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */ |
| 373 | [MSTP204] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */ | 495 | [MSTP204] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */ |
| @@ -408,6 +530,12 @@ static struct clk_lookup lookups[] = { | |||
| 408 | CLKDEV_CON_ID("pllc1_clk", &pllc1_clk), | 530 | CLKDEV_CON_ID("pllc1_clk", &pllc1_clk), |
| 409 | CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk), | 531 | CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk), |
| 410 | CLKDEV_CON_ID("usb24s", &usb24s_clk), | 532 | CLKDEV_CON_ID("usb24s", &usb24s_clk), |
| 533 | CLKDEV_CON_ID("hdmi1", &hdmi1_clk), | ||
| 534 | CLKDEV_CON_ID("hdmi2", &hdmi2_clk), | ||
| 535 | CLKDEV_CON_ID("video1", &div6_reparent_clks[DIV6_VCLK1]), | ||
| 536 | CLKDEV_CON_ID("video2", &div6_reparent_clks[DIV6_VCLK2]), | ||
| 537 | CLKDEV_CON_ID("fsiack", &fsiack_clk), | ||
| 538 | CLKDEV_CON_ID("fsibck", &fsibck_clk), | ||
| 411 | 539 | ||
| 412 | /* DIV4 clocks */ | 540 | /* DIV4 clocks */ |
| 413 | CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]), | 541 | CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]), |
| @@ -430,6 +558,8 @@ static struct clk_lookup lookups[] = { | |||
| 430 | CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), | 558 | CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), |
| 431 | CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), | 559 | CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), |
| 432 | CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]), | 560 | CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]), |
| 561 | CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), | ||
| 562 | CLKDEV_DEV_ID("sh_mobile_ceu.1", &mstp_clks[MSTP128]), | ||
| 433 | 563 | ||
| 434 | CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), | 564 | CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), |
| 435 | CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), | 565 | CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), |
| @@ -438,7 +568,10 @@ static struct clk_lookup lookups[] = { | |||
| 438 | CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), | 568 | CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), |
| 439 | CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]), | 569 | CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]), |
| 440 | CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), | 570 | CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), |
| 441 | 571 | CLKDEV_DEV_ID("sh-dma-engine.3", &mstp_clks[MSTP214]), | |
| 572 | CLKDEV_DEV_ID("sh-dma-engine.2", &mstp_clks[MSTP216]), | ||
| 573 | CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP217]), | ||
| 574 | CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), | ||
| 442 | CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP222]), | 575 | CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP222]), |
| 443 | CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP230]), | 576 | CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP230]), |
| 444 | 577 | ||
| @@ -459,6 +592,10 @@ static struct clk_lookup lookups[] = { | |||
| 459 | CLKDEV_ICK_ID("phy", "renesas_usbhs", &mstp_clks[MSTP406]), | 592 | CLKDEV_ICK_ID("phy", "renesas_usbhs", &mstp_clks[MSTP406]), |
| 460 | CLKDEV_ICK_ID("pci", "renesas_usbhs", &div4_clks[DIV4_USBP]), | 593 | CLKDEV_ICK_ID("pci", "renesas_usbhs", &div4_clks[DIV4_USBP]), |
| 461 | CLKDEV_ICK_ID("usb24", "renesas_usbhs", &usb24_clk), | 594 | CLKDEV_ICK_ID("usb24", "renesas_usbhs", &usb24_clk), |
| 595 | CLKDEV_ICK_ID("ick", "sh-mobile-hdmi", &div6_reparent_clks[DIV6_HDMI]), | ||
| 596 | |||
| 597 | CLKDEV_ICK_ID("icka", "sh_fsi2", &div6_reparent_clks[DIV6_FSIA]), | ||
| 598 | CLKDEV_ICK_ID("ickb", "sh_fsi2", &div6_reparent_clks[DIV6_FSIB]), | ||
| 462 | }; | 599 | }; |
| 463 | 600 | ||
| 464 | void __init r8a7740_clock_init(u8 md_ck) | 601 | void __init r8a7740_clock_init(u8 md_ck) |
| @@ -495,7 +632,14 @@ void __init r8a7740_clock_init(u8 md_ck) | |||
| 495 | ret = sh_clk_div6_register(div6_clks, DIV6_NR); | 632 | ret = sh_clk_div6_register(div6_clks, DIV6_NR); |
| 496 | 633 | ||
| 497 | if (!ret) | 634 | if (!ret) |
| 498 | ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR); | 635 | ret = sh_clk_div6_reparent_register(div6_reparent_clks, |
| 636 | DIV6_REPARENT_NR); | ||
| 637 | |||
| 638 | if (!ret) | ||
| 639 | ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); | ||
| 640 | |||
| 641 | for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++) | ||
| 642 | ret = clk_register(late_main_clks[k]); | ||
| 499 | 643 | ||
| 500 | clkdev_add_table(lookups, ARRAY_SIZE(lookups)); | 644 | clkdev_add_table(lookups, ARRAY_SIZE(lookups)); |
| 501 | 645 | ||
diff --git a/arch/arm/mach-shmobile/clock-r8a7779.c b/arch/arm/mach-shmobile/clock-r8a7779.c index 7d6e9fe47b56..339c62c824d5 100644 --- a/arch/arm/mach-shmobile/clock-r8a7779.c +++ b/arch/arm/mach-shmobile/clock-r8a7779.c | |||
| @@ -162,7 +162,7 @@ void __init r8a7779_clock_init(void) | |||
| 162 | ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table); | 162 | ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table); |
| 163 | 163 | ||
| 164 | if (!ret) | 164 | if (!ret) |
| 165 | ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR); | 165 | ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); |
| 166 | 166 | ||
| 167 | for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++) | 167 | for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++) |
| 168 | ret = clk_register(late_main_clks[k]); | 168 | ret = clk_register(late_main_clks[k]); |
diff --git a/arch/arm/mach-shmobile/clock-sh7367.c b/arch/arm/mach-shmobile/clock-sh7367.c index 006e7b5d304c..162b791b8984 100644 --- a/arch/arm/mach-shmobile/clock-sh7367.c +++ b/arch/arm/mach-shmobile/clock-sh7367.c | |||
| @@ -344,7 +344,7 @@ void __init sh7367_clock_init(void) | |||
| 344 | ret = sh_clk_div6_register(div6_clks, DIV6_NR); | 344 | ret = sh_clk_div6_register(div6_clks, DIV6_NR); |
| 345 | 345 | ||
| 346 | if (!ret) | 346 | if (!ret) |
| 347 | ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR); | 347 | ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); |
| 348 | 348 | ||
| 349 | clkdev_add_table(lookups, ARRAY_SIZE(lookups)); | 349 | clkdev_add_table(lookups, ARRAY_SIZE(lookups)); |
| 350 | 350 | ||
diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c index 94d1f88246d3..5a2894b1c965 100644 --- a/arch/arm/mach-shmobile/clock-sh7372.c +++ b/arch/arm/mach-shmobile/clock-sh7372.c | |||
| @@ -704,7 +704,7 @@ void __init sh7372_clock_init(void) | |||
| 704 | ret = sh_clk_div6_reparent_register(div6_reparent_clks, DIV6_REPARENT_NR); | 704 | ret = sh_clk_div6_reparent_register(div6_reparent_clks, DIV6_REPARENT_NR); |
| 705 | 705 | ||
| 706 | if (!ret) | 706 | if (!ret) |
| 707 | ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR); | 707 | ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); |
| 708 | 708 | ||
| 709 | for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++) | 709 | for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++) |
| 710 | ret = clk_register(late_main_clks[k]); | 710 | ret = clk_register(late_main_clks[k]); |
diff --git a/arch/arm/mach-shmobile/clock-sh7377.c b/arch/arm/mach-shmobile/clock-sh7377.c index 0798a15936c3..85f2a3ec2c44 100644 --- a/arch/arm/mach-shmobile/clock-sh7377.c +++ b/arch/arm/mach-shmobile/clock-sh7377.c | |||
| @@ -355,7 +355,7 @@ void __init sh7377_clock_init(void) | |||
| 355 | ret = sh_clk_div6_register(div6_clks, DIV6_NR); | 355 | ret = sh_clk_div6_register(div6_clks, DIV6_NR); |
| 356 | 356 | ||
| 357 | if (!ret) | 357 | if (!ret) |
| 358 | ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR); | 358 | ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); |
| 359 | 359 | ||
| 360 | clkdev_add_table(lookups, ARRAY_SIZE(lookups)); | 360 | clkdev_add_table(lookups, ARRAY_SIZE(lookups)); |
| 361 | 361 | ||
diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c index 3946c4ba2aa8..7f8da18a8580 100644 --- a/arch/arm/mach-shmobile/clock-sh73a0.c +++ b/arch/arm/mach-shmobile/clock-sh73a0.c | |||
| @@ -475,9 +475,9 @@ static struct clk *late_main_clks[] = { | |||
| 475 | 475 | ||
| 476 | enum { MSTP001, | 476 | enum { MSTP001, |
| 477 | MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP116, MSTP100, | 477 | MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP116, MSTP100, |
| 478 | MSTP219, MSTP218, | 478 | MSTP219, MSTP218, MSTP217, |
| 479 | MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200, | 479 | MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200, |
| 480 | MSTP331, MSTP329, MSTP325, MSTP323, | 480 | MSTP331, MSTP329, MSTP328, MSTP325, MSTP323, MSTP322, |
| 481 | MSTP314, MSTP313, MSTP312, MSTP311, | 481 | MSTP314, MSTP313, MSTP312, MSTP311, |
| 482 | MSTP303, MSTP302, MSTP301, MSTP300, | 482 | MSTP303, MSTP302, MSTP301, MSTP300, |
| 483 | MSTP411, MSTP410, MSTP403, | 483 | MSTP411, MSTP410, MSTP403, |
| @@ -498,6 +498,7 @@ static struct clk mstp_clks[MSTP_NR] = { | |||
| 498 | [MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */ | 498 | [MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */ |
| 499 | [MSTP219] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 19, 0), /* SCIFA7 */ | 499 | [MSTP219] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 19, 0), /* SCIFA7 */ |
| 500 | [MSTP218] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* SY-DMAC */ | 500 | [MSTP218] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* SY-DMAC */ |
| 501 | [MSTP217] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 17, 0), /* MP-DMAC */ | ||
| 501 | [MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */ | 502 | [MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */ |
| 502 | [MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */ | 503 | [MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */ |
| 503 | [MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */ | 504 | [MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */ |
| @@ -507,8 +508,10 @@ static struct clk mstp_clks[MSTP_NR] = { | |||
| 507 | [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */ | 508 | [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */ |
| 508 | [MSTP331] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 31, 0), /* SCIFA6 */ | 509 | [MSTP331] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 31, 0), /* SCIFA6 */ |
| 509 | [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */ | 510 | [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */ |
| 511 | [MSTP328] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 28, 0), /*FSI*/ | ||
| 510 | [MSTP325] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 25, 0), /* IrDA */ | 512 | [MSTP325] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 25, 0), /* IrDA */ |
| 511 | [MSTP323] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 23, 0), /* IIC1 */ | 513 | [MSTP323] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 23, 0), /* IIC1 */ |
| 514 | [MSTP322] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 22, 0), /* USB */ | ||
| 512 | [MSTP314] = MSTP(&div6_clks[DIV6_SDHI0], SMSTPCR3, 14, 0), /* SDHI0 */ | 515 | [MSTP314] = MSTP(&div6_clks[DIV6_SDHI0], SMSTPCR3, 14, 0), /* SDHI0 */ |
| 513 | [MSTP313] = MSTP(&div6_clks[DIV6_SDHI1], SMSTPCR3, 13, 0), /* SDHI1 */ | 516 | [MSTP313] = MSTP(&div6_clks[DIV6_SDHI1], SMSTPCR3, 13, 0), /* SDHI1 */ |
| 514 | [MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMCIF0 */ | 517 | [MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMCIF0 */ |
| @@ -553,6 +556,7 @@ static struct clk_lookup lookups[] = { | |||
| 553 | CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */ | 556 | CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */ |
| 554 | CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP219]), /* SCIFA7 */ | 557 | CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP219]), /* SCIFA7 */ |
| 555 | CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), /* SY-DMAC */ | 558 | CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), /* SY-DMAC */ |
| 559 | CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP217]), /* MP-DMAC */ | ||
| 556 | CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */ | 560 | CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */ |
| 557 | CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]), /* SCIFB */ | 561 | CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]), /* SCIFB */ |
| 558 | CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */ | 562 | CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */ |
| @@ -562,8 +566,10 @@ static struct clk_lookup lookups[] = { | |||
| 562 | CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */ | 566 | CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */ |
| 563 | CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP331]), /* SCIFA6 */ | 567 | CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP331]), /* SCIFA6 */ |
| 564 | CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */ | 568 | CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */ |
| 569 | CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI */ | ||
| 565 | CLKDEV_DEV_ID("sh_irda.0", &mstp_clks[MSTP325]), /* IrDA */ | 570 | CLKDEV_DEV_ID("sh_irda.0", &mstp_clks[MSTP325]), /* IrDA */ |
| 566 | CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* I2C1 */ | 571 | CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* I2C1 */ |
| 572 | CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP322]), /* USB */ | ||
| 567 | CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */ | 573 | CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */ |
| 568 | CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */ | 574 | CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */ |
| 569 | CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */ | 575 | CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */ |
| @@ -612,7 +618,7 @@ void __init sh73a0_clock_init(void) | |||
| 612 | ret = sh_clk_div6_reparent_register(div6_clks, DIV6_NR); | 618 | ret = sh_clk_div6_reparent_register(div6_clks, DIV6_NR); |
| 613 | 619 | ||
| 614 | if (!ret) | 620 | if (!ret) |
| 615 | ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR); | 621 | ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); |
| 616 | 622 | ||
| 617 | for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++) | 623 | for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++) |
| 618 | ret = clk_register(late_main_clks[k]); | 624 | ret = clk_register(late_main_clks[k]); |
diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h index 01e2bc014f15..45e61dada030 100644 --- a/arch/arm/mach-shmobile/include/mach/common.h +++ b/arch/arm/mach-shmobile/include/mach/common.h | |||
| @@ -77,6 +77,7 @@ extern void r8a7779_add_standard_devices(void); | |||
| 77 | extern void r8a7779_clock_init(void); | 77 | extern void r8a7779_clock_init(void); |
| 78 | extern void r8a7779_pinmux_init(void); | 78 | extern void r8a7779_pinmux_init(void); |
| 79 | extern void r8a7779_pm_init(void); | 79 | extern void r8a7779_pm_init(void); |
| 80 | extern void r8a7740_meram_workaround(void); | ||
| 80 | 81 | ||
| 81 | extern unsigned int r8a7779_get_core_count(void); | 82 | extern unsigned int r8a7779_get_core_count(void); |
| 82 | extern int r8a7779_platform_cpu_kill(unsigned int cpu); | 83 | extern int r8a7779_platform_cpu_kill(unsigned int cpu); |
diff --git a/arch/arm/mach-shmobile/include/mach/dma-register.h b/arch/arm/mach-shmobile/include/mach/dma-register.h new file mode 100644 index 000000000000..97c40bd9b94f --- /dev/null +++ b/arch/arm/mach-shmobile/include/mach/dma-register.h | |||
| @@ -0,0 +1,84 @@ | |||
| 1 | /* | ||
| 2 | * SH-ARM CPU-specific DMA definitions, used by both DMA drivers | ||
| 3 | * | ||
| 4 | * Copyright (C) 2012 Renesas Solutions Corp | ||
| 5 | * | ||
| 6 | * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | ||
| 7 | * | ||
| 8 | * Based on arch/sh/include/cpu-sh4/cpu/dma-register.h | ||
| 9 | * Copyright (C) 2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de> | ||
| 10 | * | ||
| 11 | * This program is free software; you can redistribute it and/or modify | ||
| 12 | * it under the terms of the GNU General Public License version 2 as | ||
| 13 | * published by the Free Software Foundation. | ||
| 14 | */ | ||
| 15 | |||
| 16 | #ifndef DMA_REGISTER_H | ||
| 17 | #define DMA_REGISTER_H | ||
| 18 | |||
| 19 | /* | ||
| 20 | * Direct Memory Access Controller | ||
| 21 | */ | ||
| 22 | |||
| 23 | /* Transmit sizes and respective CHCR register values */ | ||
| 24 | enum { | ||
| 25 | XMIT_SZ_8BIT = 0, | ||
| 26 | XMIT_SZ_16BIT = 1, | ||
| 27 | XMIT_SZ_32BIT = 2, | ||
| 28 | XMIT_SZ_64BIT = 7, | ||
| 29 | XMIT_SZ_128BIT = 3, | ||
| 30 | XMIT_SZ_256BIT = 4, | ||
| 31 | XMIT_SZ_512BIT = 5, | ||
| 32 | }; | ||
| 33 | |||
| 34 | /* log2(size / 8) - used to calculate number of transfers */ | ||
| 35 | static const unsigned int dma_ts_shift[] = { | ||
| 36 | [XMIT_SZ_8BIT] = 0, | ||
| 37 | [XMIT_SZ_16BIT] = 1, | ||
| 38 | [XMIT_SZ_32BIT] = 2, | ||
| 39 | [XMIT_SZ_64BIT] = 3, | ||
| 40 | [XMIT_SZ_128BIT] = 4, | ||
| 41 | [XMIT_SZ_256BIT] = 5, | ||
| 42 | [XMIT_SZ_512BIT] = 6, | ||
| 43 | }; | ||
| 44 | |||
| 45 | #define TS_LOW_BIT 0x3 /* --xx */ | ||
| 46 | #define TS_HI_BIT 0xc /* xx-- */ | ||
| 47 | |||
| 48 | #define TS_LOW_SHIFT (3) | ||
| 49 | #define TS_HI_SHIFT (20 - 2) /* 2 bits for shifted low TS */ | ||
| 50 | |||
| 51 | #define TS_INDEX2VAL(i) \ | ||
| 52 | ((((i) & TS_LOW_BIT) << TS_LOW_SHIFT) |\ | ||
| 53 | (((i) & TS_HI_BIT) << TS_HI_SHIFT)) | ||
| 54 | |||
| 55 | #define CHCR_TX(xmit_sz) (DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL((xmit_sz))) | ||
| 56 | #define CHCR_RX(xmit_sz) (DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL((xmit_sz))) | ||
| 57 | |||
| 58 | |||
| 59 | /* | ||
| 60 | * USB High-Speed DMAC | ||
| 61 | */ | ||
| 62 | /* Transmit sizes and respective CHCR register values */ | ||
| 63 | enum { | ||
| 64 | USBTS_XMIT_SZ_8BYTE = 0, | ||
| 65 | USBTS_XMIT_SZ_16BYTE = 1, | ||
| 66 | USBTS_XMIT_SZ_32BYTE = 2, | ||
| 67 | }; | ||
| 68 | |||
| 69 | /* log2(size / 8) - used to calculate number of transfers */ | ||
| 70 | static const unsigned int dma_usbts_shift[] = { | ||
| 71 | [USBTS_XMIT_SZ_8BYTE] = 3, | ||
| 72 | [USBTS_XMIT_SZ_16BYTE] = 4, | ||
| 73 | [USBTS_XMIT_SZ_32BYTE] = 5, | ||
| 74 | }; | ||
| 75 | |||
| 76 | #define USBTS_LOW_BIT 0x3 /* --xx */ | ||
| 77 | #define USBTS_HI_BIT 0x0 /* ---- */ | ||
| 78 | |||
| 79 | #define USBTS_LOW_SHIFT 6 | ||
| 80 | #define USBTS_HI_SHIFT 0 | ||
| 81 | |||
| 82 | #define USBTS_INDEX2VAL(i) (((i) & 3) << 6) | ||
| 83 | |||
| 84 | #endif /* DMA_REGISTER_H */ | ||
diff --git a/arch/arm/mach-shmobile/include/mach/gpio.h b/arch/arm/mach-shmobile/include/mach/gpio.h index de795b42232a..844507d937cb 100644 --- a/arch/arm/mach-shmobile/include/mach/gpio.h +++ b/arch/arm/mach-shmobile/include/mach/gpio.h | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
| 14 | #include <linux/errno.h> | 14 | #include <linux/errno.h> |
| 15 | #include <linux/sh_pfc.h> | 15 | #include <linux/sh_pfc.h> |
| 16 | #include <linux/io.h> | ||
| 16 | 17 | ||
| 17 | #ifdef CONFIG_GPIOLIB | 18 | #ifdef CONFIG_GPIOLIB |
| 18 | 19 | ||
| @@ -27,4 +28,35 @@ static inline int irq_to_gpio(unsigned int irq) | |||
| 27 | 28 | ||
| 28 | #endif /* CONFIG_GPIOLIB */ | 29 | #endif /* CONFIG_GPIOLIB */ |
| 29 | 30 | ||
| 31 | /* | ||
| 32 | * FIXME !! | ||
| 33 | * | ||
| 34 | * current gpio frame work doesn't have | ||
| 35 | * the method to control only pull up/down/free. | ||
| 36 | * this function should be replaced by correct gpio function | ||
| 37 | */ | ||
| 38 | static inline void __init gpio_direction_none(u32 addr) | ||
| 39 | { | ||
| 40 | __raw_writeb(0x00, addr); | ||
| 41 | } | ||
| 42 | |||
| 43 | static inline void __init gpio_request_pullup(u32 addr) | ||
| 44 | { | ||
| 45 | u8 data = __raw_readb(addr); | ||
| 46 | |||
| 47 | data &= 0x0F; | ||
| 48 | data |= 0xC0; | ||
| 49 | __raw_writeb(data, addr); | ||
| 50 | } | ||
| 51 | |||
| 52 | static inline void __init gpio_request_pulldown(u32 addr) | ||
| 53 | { | ||
| 54 | u8 data = __raw_readb(addr); | ||
| 55 | |||
| 56 | data &= 0x0F; | ||
| 57 | data |= 0xA0; | ||
| 58 | |||
| 59 | __raw_writeb(data, addr); | ||
| 60 | } | ||
| 61 | |||
| 30 | #endif /* __ASM_ARCH_GPIO_H */ | 62 | #endif /* __ASM_ARCH_GPIO_H */ |
diff --git a/arch/arm/mach-shmobile/include/mach/pm-rmobile.h b/arch/arm/mach-shmobile/include/mach/pm-rmobile.h new file mode 100644 index 000000000000..5a402840fe28 --- /dev/null +++ b/arch/arm/mach-shmobile/include/mach/pm-rmobile.h | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2012 Renesas Solutions Corp. | ||
| 3 | * | ||
| 4 | * Kuninori Morimoto <morimoto.kuninori@renesas.com> | ||
| 5 | * | ||
| 6 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 7 | * License. See the file "COPYING" in the main directory of this archive | ||
| 8 | * for more details. | ||
| 9 | */ | ||
| 10 | #ifndef PM_RMOBILE_H | ||
| 11 | #define PM_RMOBILE_H | ||
| 12 | |||
| 13 | #include <linux/pm_domain.h> | ||
| 14 | |||
| 15 | struct platform_device; | ||
| 16 | |||
| 17 | struct rmobile_pm_domain { | ||
| 18 | struct generic_pm_domain genpd; | ||
| 19 | struct dev_power_governor *gov; | ||
| 20 | int (*suspend)(void); | ||
| 21 | void (*resume)(void); | ||
| 22 | unsigned int bit_shift; | ||
| 23 | bool no_debug; | ||
| 24 | }; | ||
| 25 | |||
| 26 | static inline | ||
| 27 | struct rmobile_pm_domain *to_rmobile_pd(struct generic_pm_domain *d) | ||
| 28 | { | ||
| 29 | return container_of(d, struct rmobile_pm_domain, genpd); | ||
| 30 | } | ||
| 31 | |||
| 32 | #ifdef CONFIG_PM | ||
| 33 | extern void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd); | ||
| 34 | extern void rmobile_add_device_to_domain(struct rmobile_pm_domain *rmobile_pd, | ||
| 35 | struct platform_device *pdev); | ||
| 36 | extern void rmobile_pm_add_subdomain(struct rmobile_pm_domain *rmobile_pd, | ||
| 37 | struct rmobile_pm_domain *rmobile_sd); | ||
| 38 | #else | ||
| 39 | #define rmobile_init_pm_domain(pd) do { } while (0) | ||
| 40 | #define rmobile_add_device_to_domain(pd, pdev) do { } while (0) | ||
| 41 | #define rmobile_pm_add_subdomain(pd, sd) do { } while (0) | ||
| 42 | #endif /* CONFIG_PM */ | ||
| 43 | |||
| 44 | #endif /* PM_RMOBILE_H */ | ||
diff --git a/arch/arm/mach-shmobile/include/mach/r8a7740.h b/arch/arm/mach-shmobile/include/mach/r8a7740.h index 9d447abb969c..7143147780df 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7740.h +++ b/arch/arm/mach-shmobile/include/mach/r8a7740.h | |||
| @@ -19,6 +19,8 @@ | |||
| 19 | #ifndef __ASM_R8A7740_H__ | 19 | #ifndef __ASM_R8A7740_H__ |
| 20 | #define __ASM_R8A7740_H__ | 20 | #define __ASM_R8A7740_H__ |
| 21 | 21 | ||
| 22 | #include <mach/pm-rmobile.h> | ||
| 23 | |||
| 22 | /* | 24 | /* |
| 23 | * MD_CKx pin | 25 | * MD_CKx pin |
| 24 | */ | 26 | */ |
| @@ -139,7 +141,7 @@ enum { | |||
| 139 | GPIO_FN_DBGMD10, GPIO_FN_DBGMD11, GPIO_FN_DBGMD20, | 141 | GPIO_FN_DBGMD10, GPIO_FN_DBGMD11, GPIO_FN_DBGMD20, |
| 140 | GPIO_FN_DBGMD21, | 142 | GPIO_FN_DBGMD21, |
| 141 | 143 | ||
| 142 | /* FSI */ | 144 | /* FSI-A */ |
| 143 | GPIO_FN_FSIAISLD_PORT0, /* FSIAISLD Port 0/5 */ | 145 | GPIO_FN_FSIAISLD_PORT0, /* FSIAISLD Port 0/5 */ |
| 144 | GPIO_FN_FSIAISLD_PORT5, | 146 | GPIO_FN_FSIAISLD_PORT5, |
| 145 | GPIO_FN_FSIASPDIF_PORT9, /* FSIASPDIF Port 9/18 */ | 147 | GPIO_FN_FSIASPDIF_PORT9, /* FSIASPDIF Port 9/18 */ |
| @@ -150,6 +152,9 @@ enum { | |||
| 150 | GPIO_FN_FSIACK, GPIO_FN_FSIAILR, | 152 | GPIO_FN_FSIACK, GPIO_FN_FSIAILR, |
| 151 | GPIO_FN_FSIAIBT, | 153 | GPIO_FN_FSIAIBT, |
| 152 | 154 | ||
| 155 | /* FSI-B */ | ||
| 156 | GPIO_FN_FSIBCK, | ||
| 157 | |||
| 153 | /* FMSI */ | 158 | /* FMSI */ |
| 154 | GPIO_FN_FMSISLD_PORT1, /* FMSISLD Port 1/6 */ | 159 | GPIO_FN_FMSISLD_PORT1, /* FMSISLD Port 1/6 */ |
| 155 | GPIO_FN_FMSISLD_PORT6, | 160 | GPIO_FN_FMSISLD_PORT6, |
| @@ -565,6 +570,10 @@ enum { | |||
| 565 | GPIO_FN_RESETP_PULLUP, | 570 | GPIO_FN_RESETP_PULLUP, |
| 566 | GPIO_FN_RESETP_PLAIN, | 571 | GPIO_FN_RESETP_PLAIN, |
| 567 | 572 | ||
| 573 | /* HDMI */ | ||
| 574 | GPIO_FN_HDMI_HPD, | ||
| 575 | GPIO_FN_HDMI_CEC, | ||
| 576 | |||
| 568 | /* SDENC */ | 577 | /* SDENC */ |
| 569 | GPIO_FN_SDENC_CPG, | 578 | GPIO_FN_SDENC_CPG, |
| 570 | GPIO_FN_SDENC_DV_CLKI, | 579 | GPIO_FN_SDENC_DV_CLKI, |
| @@ -581,4 +590,26 @@ enum { | |||
| 581 | GPIO_FN_TRACEAUD_FROM_MEMC, | 590 | GPIO_FN_TRACEAUD_FROM_MEMC, |
| 582 | }; | 591 | }; |
| 583 | 592 | ||
| 593 | /* DMA slave IDs */ | ||
| 594 | enum { | ||
| 595 | SHDMA_SLAVE_INVALID, | ||
| 596 | SHDMA_SLAVE_SDHI0_RX, | ||
| 597 | SHDMA_SLAVE_SDHI0_TX, | ||
| 598 | SHDMA_SLAVE_SDHI1_RX, | ||
| 599 | SHDMA_SLAVE_SDHI1_TX, | ||
| 600 | SHDMA_SLAVE_SDHI2_RX, | ||
| 601 | SHDMA_SLAVE_SDHI2_TX, | ||
| 602 | SHDMA_SLAVE_FSIA_RX, | ||
| 603 | SHDMA_SLAVE_FSIA_TX, | ||
| 604 | SHDMA_SLAVE_FSIB_TX, | ||
| 605 | SHDMA_SLAVE_USBHS_TX, | ||
| 606 | SHDMA_SLAVE_USBHS_RX, | ||
| 607 | }; | ||
| 608 | |||
| 609 | #ifdef CONFIG_PM | ||
| 610 | extern struct rmobile_pm_domain r8a7740_pd_a4s; | ||
| 611 | extern struct rmobile_pm_domain r8a7740_pd_a3sp; | ||
| 612 | extern struct rmobile_pm_domain r8a7740_pd_a4lc; | ||
| 613 | #endif /* CONFIG_PM */ | ||
| 614 | |||
| 584 | #endif /* __ASM_R8A7740_H__ */ | 615 | #endif /* __ASM_R8A7740_H__ */ |
diff --git a/arch/arm/mach-shmobile/include/mach/sh7372.h b/arch/arm/mach-shmobile/include/mach/sh7372.h index 915d0093da08..b59048e6d8fd 100644 --- a/arch/arm/mach-shmobile/include/mach/sh7372.h +++ b/arch/arm/mach-shmobile/include/mach/sh7372.h | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | 13 | ||
| 14 | #include <linux/sh_clk.h> | 14 | #include <linux/sh_clk.h> |
| 15 | #include <linux/pm_domain.h> | 15 | #include <linux/pm_domain.h> |
| 16 | #include <mach/pm-rmobile.h> | ||
| 16 | 17 | ||
| 17 | /* | 18 | /* |
| 18 | * Pin Function Controller: | 19 | * Pin Function Controller: |
| @@ -477,42 +478,16 @@ extern struct clk sh7372_fsibck_clk; | |||
| 477 | extern struct clk sh7372_fsidiva_clk; | 478 | extern struct clk sh7372_fsidiva_clk; |
| 478 | extern struct clk sh7372_fsidivb_clk; | 479 | extern struct clk sh7372_fsidivb_clk; |
| 479 | 480 | ||
| 480 | struct platform_device; | ||
| 481 | |||
| 482 | struct sh7372_pm_domain { | ||
| 483 | struct generic_pm_domain genpd; | ||
| 484 | struct dev_power_governor *gov; | ||
| 485 | int (*suspend)(void); | ||
| 486 | void (*resume)(void); | ||
| 487 | unsigned int bit_shift; | ||
| 488 | bool no_debug; | ||
| 489 | }; | ||
| 490 | |||
| 491 | static inline struct sh7372_pm_domain *to_sh7372_pd(struct generic_pm_domain *d) | ||
| 492 | { | ||
| 493 | return container_of(d, struct sh7372_pm_domain, genpd); | ||
| 494 | } | ||
| 495 | |||
| 496 | #ifdef CONFIG_PM | 481 | #ifdef CONFIG_PM |
| 497 | extern struct sh7372_pm_domain sh7372_a4lc; | 482 | extern struct rmobile_pm_domain sh7372_pd_a4lc; |
| 498 | extern struct sh7372_pm_domain sh7372_a4mp; | 483 | extern struct rmobile_pm_domain sh7372_pd_a4mp; |
| 499 | extern struct sh7372_pm_domain sh7372_d4; | 484 | extern struct rmobile_pm_domain sh7372_pd_d4; |
| 500 | extern struct sh7372_pm_domain sh7372_a4r; | 485 | extern struct rmobile_pm_domain sh7372_pd_a4r; |
| 501 | extern struct sh7372_pm_domain sh7372_a3rv; | 486 | extern struct rmobile_pm_domain sh7372_pd_a3rv; |
| 502 | extern struct sh7372_pm_domain sh7372_a3ri; | 487 | extern struct rmobile_pm_domain sh7372_pd_a3ri; |
| 503 | extern struct sh7372_pm_domain sh7372_a4s; | 488 | extern struct rmobile_pm_domain sh7372_pd_a4s; |
| 504 | extern struct sh7372_pm_domain sh7372_a3sp; | 489 | extern struct rmobile_pm_domain sh7372_pd_a3sp; |
| 505 | extern struct sh7372_pm_domain sh7372_a3sg; | 490 | extern struct rmobile_pm_domain sh7372_pd_a3sg; |
| 506 | |||
| 507 | extern void sh7372_init_pm_domain(struct sh7372_pm_domain *sh7372_pd); | ||
| 508 | extern void sh7372_add_device_to_domain(struct sh7372_pm_domain *sh7372_pd, | ||
| 509 | struct platform_device *pdev); | ||
| 510 | extern void sh7372_pm_add_subdomain(struct sh7372_pm_domain *sh7372_pd, | ||
| 511 | struct sh7372_pm_domain *sh7372_sd); | ||
| 512 | #else | ||
| 513 | #define sh7372_init_pm_domain(pd) do { } while(0) | ||
| 514 | #define sh7372_add_device_to_domain(pd, pdev) do { } while(0) | ||
| 515 | #define sh7372_pm_add_subdomain(pd, sd) do { } while(0) | ||
| 516 | #endif /* CONFIG_PM */ | 491 | #endif /* CONFIG_PM */ |
| 517 | 492 | ||
| 518 | extern void sh7372_intcs_suspend(void); | 493 | extern void sh7372_intcs_suspend(void); |
diff --git a/arch/arm/mach-shmobile/include/mach/sh73a0.h b/arch/arm/mach-shmobile/include/mach/sh73a0.h index 398e2c10913b..fe950f25d793 100644 --- a/arch/arm/mach-shmobile/include/mach/sh73a0.h +++ b/arch/arm/mach-shmobile/include/mach/sh73a0.h | |||
| @@ -516,6 +516,13 @@ enum { | |||
| 516 | SHDMA_SLAVE_SDHI2_RX, | 516 | SHDMA_SLAVE_SDHI2_RX, |
| 517 | SHDMA_SLAVE_MMCIF_TX, | 517 | SHDMA_SLAVE_MMCIF_TX, |
| 518 | SHDMA_SLAVE_MMCIF_RX, | 518 | SHDMA_SLAVE_MMCIF_RX, |
| 519 | SHDMA_SLAVE_FSI2A_TX, | ||
| 520 | SHDMA_SLAVE_FSI2A_RX, | ||
| 521 | SHDMA_SLAVE_FSI2B_TX, | ||
| 522 | SHDMA_SLAVE_FSI2B_RX, | ||
| 523 | SHDMA_SLAVE_FSI2C_TX, | ||
| 524 | SHDMA_SLAVE_FSI2C_RX, | ||
| 525 | SHDMA_SLAVE_FSI2D_RX, | ||
| 519 | }; | 526 | }; |
| 520 | 527 | ||
| 521 | /* | 528 | /* |
diff --git a/arch/arm/mach-shmobile/intc-r8a7740.c b/arch/arm/mach-shmobile/intc-r8a7740.c index 09c42afcb22d..9a69a31918ba 100644 --- a/arch/arm/mach-shmobile/intc-r8a7740.c +++ b/arch/arm/mach-shmobile/intc-r8a7740.c | |||
| @@ -71,10 +71,12 @@ enum { | |||
| 71 | DMAC3_1_DEI0, DMAC3_1_DEI1, DMAC3_1_DEI2, DMAC3_1_DEI3, | 71 | DMAC3_1_DEI0, DMAC3_1_DEI1, DMAC3_1_DEI2, DMAC3_1_DEI3, |
| 72 | DMAC3_2_DEI4, DMAC3_2_DEI5, DMAC3_2_DADERR, | 72 | DMAC3_2_DEI4, DMAC3_2_DEI5, DMAC3_2_DADERR, |
| 73 | SHWYSTAT_RT, SHWYSTAT_HS, SHWYSTAT_COM, | 73 | SHWYSTAT_RT, SHWYSTAT_HS, SHWYSTAT_COM, |
| 74 | HDMI, | ||
| 74 | USBH_INT, USBH_OHCI, USBH_EHCI, USBH_PME, USBH_BIND, | 75 | USBH_INT, USBH_OHCI, USBH_EHCI, USBH_PME, USBH_BIND, |
| 75 | RSPI_OVRF, RSPI_SPTEF, RSPI_SPRF, | 76 | RSPI_OVRF, RSPI_SPTEF, RSPI_SPRF, |
| 76 | SPU2_0, SPU2_1, | 77 | SPU2_0, SPU2_1, |
| 77 | FSI, FMSI, | 78 | FSI, FMSI, |
| 79 | HDMI_SSS, HDMI_KEY, | ||
| 78 | IPMMU, | 80 | IPMMU, |
| 79 | AP_ARM_CTIIRQ, AP_ARM_PMURQ, | 81 | AP_ARM_CTIIRQ, AP_ARM_PMURQ, |
| 80 | MFIS2, | 82 | MFIS2, |
| @@ -182,6 +184,7 @@ static struct intc_vect intca_vectors[] __initdata = { | |||
| 182 | INTC_VECT(USBH_EHCI, 0x1580), | 184 | INTC_VECT(USBH_EHCI, 0x1580), |
| 183 | INTC_VECT(USBH_PME, 0x15A0), | 185 | INTC_VECT(USBH_PME, 0x15A0), |
| 184 | INTC_VECT(USBH_BIND, 0x15C0), | 186 | INTC_VECT(USBH_BIND, 0x15C0), |
| 187 | INTC_VECT(HDMI, 0x1700), | ||
| 185 | INTC_VECT(RSPI_OVRF, 0x1780), | 188 | INTC_VECT(RSPI_OVRF, 0x1780), |
| 186 | INTC_VECT(RSPI_SPTEF, 0x17A0), | 189 | INTC_VECT(RSPI_SPTEF, 0x17A0), |
| 187 | INTC_VECT(RSPI_SPRF, 0x17C0), | 190 | INTC_VECT(RSPI_SPRF, 0x17C0), |
| @@ -189,6 +192,8 @@ static struct intc_vect intca_vectors[] __initdata = { | |||
| 189 | INTC_VECT(SPU2_1, 0x1820), | 192 | INTC_VECT(SPU2_1, 0x1820), |
| 190 | INTC_VECT(FSI, 0x1840), | 193 | INTC_VECT(FSI, 0x1840), |
| 191 | INTC_VECT(FMSI, 0x1860), | 194 | INTC_VECT(FMSI, 0x1860), |
| 195 | INTC_VECT(HDMI_SSS, 0x18A0), | ||
| 196 | INTC_VECT(HDMI_KEY, 0x18C0), | ||
| 192 | INTC_VECT(IPMMU, 0x1920), | 197 | INTC_VECT(IPMMU, 0x1920), |
| 193 | INTC_VECT(AP_ARM_CTIIRQ, 0x1980), | 198 | INTC_VECT(AP_ARM_CTIIRQ, 0x1980), |
| 194 | INTC_VECT(AP_ARM_PMURQ, 0x19A0), | 199 | INTC_VECT(AP_ARM_PMURQ, 0x19A0), |
| @@ -304,11 +309,11 @@ static struct intc_mask_reg intca_mask_registers[] __initdata = { | |||
| 304 | USBH_EHCI, USBH_PME, USBH_BIND, 0 } }, | 309 | USBH_EHCI, USBH_PME, USBH_BIND, 0 } }, |
| 305 | /* IMR3A3 / IMCR3A3 */ | 310 | /* IMR3A3 / IMCR3A3 */ |
| 306 | { /* IMR4A3 / IMCR4A3 */ 0xe6950090, 0xe69500d0, 8, | 311 | { /* IMR4A3 / IMCR4A3 */ 0xe6950090, 0xe69500d0, 8, |
| 307 | { 0, 0, 0, 0, | 312 | { HDMI, 0, 0, 0, |
| 308 | RSPI_OVRF, RSPI_SPTEF, RSPI_SPRF, 0 } }, | 313 | RSPI_OVRF, RSPI_SPTEF, RSPI_SPRF, 0 } }, |
| 309 | { /* IMR5A3 / IMCR5A3 */ 0xe6950094, 0xe69500d4, 8, | 314 | { /* IMR5A3 / IMCR5A3 */ 0xe6950094, 0xe69500d4, 8, |
| 310 | { SPU2_0, SPU2_1, FSI, FMSI, | 315 | { SPU2_0, SPU2_1, FSI, FMSI, |
| 311 | 0, 0, 0, 0 } }, | 316 | 0, HDMI_SSS, HDMI_KEY, 0 } }, |
| 312 | { /* IMR6A3 / IMCR6A3 */ 0xe6950098, 0xe69500d8, 8, | 317 | { /* IMR6A3 / IMCR6A3 */ 0xe6950098, 0xe69500d8, 8, |
| 313 | { 0, IPMMU, 0, 0, | 318 | { 0, IPMMU, 0, 0, |
| 314 | AP_ARM_CTIIRQ, AP_ARM_PMURQ, 0, 0 } }, | 319 | AP_ARM_CTIIRQ, AP_ARM_PMURQ, 0, 0 } }, |
| @@ -353,10 +358,10 @@ static struct intc_prio_reg intca_prio_registers[] __initdata = { | |||
| 353 | { 0xe6950014, 0, 16, 4, /* IPRFA3 */ { USBH2, 0, 0, 0 } }, | 358 | { 0xe6950014, 0, 16, 4, /* IPRFA3 */ { USBH2, 0, 0, 0 } }, |
| 354 | /* IPRGA3 */ | 359 | /* IPRGA3 */ |
| 355 | /* IPRHA3 */ | 360 | /* IPRHA3 */ |
| 356 | /* IPRIA3 */ | 361 | { 0xe6950020, 0, 16, 4, /* IPRIA3 */ { HDMI, 0, 0, 0 } }, |
| 357 | { 0xe6950024, 0, 16, 4, /* IPRJA3 */ { RSPI, 0, 0, 0 } }, | 362 | { 0xe6950024, 0, 16, 4, /* IPRJA3 */ { RSPI, 0, 0, 0 } }, |
| 358 | { 0xe6950028, 0, 16, 4, /* IPRKA3 */ { SPU2, 0, FSI, FMSI } }, | 363 | { 0xe6950028, 0, 16, 4, /* IPRKA3 */ { SPU2, 0, FSI, FMSI } }, |
| 359 | /* IPRLA3 */ | 364 | { 0xe695002c, 0, 16, 4, /* IPRLA3 */ { 0, HDMI_SSS, HDMI_KEY, 0 } }, |
| 360 | { 0xe6950030, 0, 16, 4, /* IPRMA3 */ { IPMMU, 0, 0, 0 } }, | 365 | { 0xe6950030, 0, 16, 4, /* IPRMA3 */ { IPMMU, 0, 0, 0 } }, |
| 361 | { 0xe6950034, 0, 16, 4, /* IPRNA3 */ { AP_ARM2, 0, 0, 0 } }, | 366 | { 0xe6950034, 0, 16, 4, /* IPRNA3 */ { AP_ARM2, 0, 0, 0 } }, |
| 362 | { 0xe6950038, 0, 16, 4, /* IPROA3 */ { MFIS2, CPORTR2S, | 367 | { 0xe6950038, 0, 16, 4, /* IPROA3 */ { MFIS2, CPORTR2S, |
diff --git a/arch/arm/mach-shmobile/pfc-r8a7740.c b/arch/arm/mach-shmobile/pfc-r8a7740.c index 670fe1869dbc..ce9e7fa5cc8a 100644 --- a/arch/arm/mach-shmobile/pfc-r8a7740.c +++ b/arch/arm/mach-shmobile/pfc-r8a7740.c | |||
| @@ -169,7 +169,7 @@ enum { | |||
| 169 | DBGMD10_MARK, DBGMD11_MARK, DBGMD20_MARK, | 169 | DBGMD10_MARK, DBGMD11_MARK, DBGMD20_MARK, |
| 170 | DBGMD21_MARK, | 170 | DBGMD21_MARK, |
| 171 | 171 | ||
| 172 | /* FSI */ | 172 | /* FSI-A */ |
| 173 | FSIAISLD_PORT0_MARK, /* FSIAISLD Port 0/5 */ | 173 | FSIAISLD_PORT0_MARK, /* FSIAISLD Port 0/5 */ |
| 174 | FSIAISLD_PORT5_MARK, | 174 | FSIAISLD_PORT5_MARK, |
| 175 | FSIASPDIF_PORT9_MARK, /* FSIASPDIF Port 9/18 */ | 175 | FSIASPDIF_PORT9_MARK, /* FSIASPDIF Port 9/18 */ |
| @@ -178,6 +178,9 @@ enum { | |||
| 178 | FSIAOBT_MARK, FSIAOSLD_MARK, FSIAOMC_MARK, | 178 | FSIAOBT_MARK, FSIAOSLD_MARK, FSIAOMC_MARK, |
| 179 | FSIACK_MARK, FSIAILR_MARK, FSIAIBT_MARK, | 179 | FSIACK_MARK, FSIAILR_MARK, FSIAIBT_MARK, |
| 180 | 180 | ||
| 181 | /* FSI-B */ | ||
| 182 | FSIBCK_MARK, | ||
| 183 | |||
| 181 | /* FMSI */ | 184 | /* FMSI */ |
| 182 | FMSISLD_PORT1_MARK, /* FMSISLD Port 1/6 */ | 185 | FMSISLD_PORT1_MARK, /* FMSISLD Port 1/6 */ |
| 183 | FMSISLD_PORT6_MARK, | 186 | FMSISLD_PORT6_MARK, |
| @@ -560,6 +563,9 @@ enum { | |||
| 560 | /* SDENC */ | 563 | /* SDENC */ |
| 561 | SDENC_CPG_MARK, SDENC_DV_CLKI_MARK, | 564 | SDENC_CPG_MARK, SDENC_DV_CLKI_MARK, |
| 562 | 565 | ||
| 566 | /* HDMI */ | ||
| 567 | HDMI_HPD_MARK, HDMI_CEC_MARK, | ||
| 568 | |||
| 563 | /* DEBUG */ | 569 | /* DEBUG */ |
| 564 | EDEBGREQ_PULLUP_MARK, /* for JTAG */ | 570 | EDEBGREQ_PULLUP_MARK, /* for JTAG */ |
| 565 | EDEBGREQ_PULLDOWN_MARK, | 571 | EDEBGREQ_PULLDOWN_MARK, |
| @@ -771,6 +777,7 @@ static pinmux_enum_t pinmux_data[] = { | |||
| 771 | 777 | ||
| 772 | /* Port11 */ | 778 | /* Port11 */ |
| 773 | PINMUX_DATA(FSIACK_MARK, PORT11_FN1), | 779 | PINMUX_DATA(FSIACK_MARK, PORT11_FN1), |
| 780 | PINMUX_DATA(FSIBCK_MARK, PORT11_FN2), | ||
| 774 | PINMUX_DATA(IRQ2_PORT11_MARK, PORT11_FN0, MSEL1CR_2_0), | 781 | PINMUX_DATA(IRQ2_PORT11_MARK, PORT11_FN0, MSEL1CR_2_0), |
| 775 | 782 | ||
| 776 | /* Port12 */ | 783 | /* Port12 */ |
| @@ -1254,7 +1261,7 @@ static pinmux_enum_t pinmux_data[] = { | |||
| 1254 | PINMUX_DATA(A21_MARK, PORT120_FN1), | 1261 | PINMUX_DATA(A21_MARK, PORT120_FN1), |
| 1255 | PINMUX_DATA(MSIOF0_RSYNC_MARK, PORT120_FN2), | 1262 | PINMUX_DATA(MSIOF0_RSYNC_MARK, PORT120_FN2), |
| 1256 | PINMUX_DATA(MSIOF1_TSYNC_PORT120_MARK, PORT120_FN3, MSEL4CR_10_0), | 1263 | PINMUX_DATA(MSIOF1_TSYNC_PORT120_MARK, PORT120_FN3, MSEL4CR_10_0), |
| 1257 | PINMUX_DATA(IRQ7_PORT120_MARK, PORT120_FN0, MSEL1CR_7_0), | 1264 | PINMUX_DATA(IRQ7_PORT120_MARK, PORT120_FN0, MSEL1CR_7_1), |
| 1258 | 1265 | ||
| 1259 | /* Port121 */ | 1266 | /* Port121 */ |
| 1260 | PINMUX_DATA(A20_MARK, PORT121_FN1), | 1267 | PINMUX_DATA(A20_MARK, PORT121_FN1), |
| @@ -1616,13 +1623,15 @@ static pinmux_enum_t pinmux_data[] = { | |||
| 1616 | 1623 | ||
| 1617 | /* Port209 */ | 1624 | /* Port209 */ |
| 1618 | PINMUX_DATA(VBUS_MARK, PORT209_FN1), | 1625 | PINMUX_DATA(VBUS_MARK, PORT209_FN1), |
| 1619 | PINMUX_DATA(IRQ7_PORT209_MARK, PORT209_FN0, MSEL1CR_7_1), | 1626 | PINMUX_DATA(IRQ7_PORT209_MARK, PORT209_FN0, MSEL1CR_7_0), |
| 1620 | 1627 | ||
| 1621 | /* Port210 */ | 1628 | /* Port210 */ |
| 1622 | PINMUX_DATA(IRQ9_PORT210_MARK, PORT210_FN0, MSEL1CR_9_1), | 1629 | PINMUX_DATA(IRQ9_PORT210_MARK, PORT210_FN0, MSEL1CR_9_1), |
| 1630 | PINMUX_DATA(HDMI_HPD_MARK, PORT210_FN1), | ||
| 1623 | 1631 | ||
| 1624 | /* Port211 */ | 1632 | /* Port211 */ |
| 1625 | PINMUX_DATA(IRQ16_PORT211_MARK, PORT211_FN0, MSEL1CR_16_1), | 1633 | PINMUX_DATA(IRQ16_PORT211_MARK, PORT211_FN0, MSEL1CR_16_1), |
| 1634 | PINMUX_DATA(HDMI_CEC_MARK, PORT211_FN1), | ||
| 1626 | 1635 | ||
| 1627 | /* LCDC select */ | 1636 | /* LCDC select */ |
| 1628 | PINMUX_DATA(LCDC0_SELECT_MARK, MSEL3CR_6_0), | 1637 | PINMUX_DATA(LCDC0_SELECT_MARK, MSEL3CR_6_0), |
| @@ -1691,7 +1700,7 @@ static struct pinmux_gpio pinmux_gpios[] = { | |||
| 1691 | GPIO_FN(DBGMD10), GPIO_FN(DBGMD11), GPIO_FN(DBGMD20), | 1700 | GPIO_FN(DBGMD10), GPIO_FN(DBGMD11), GPIO_FN(DBGMD20), |
| 1692 | GPIO_FN(DBGMD21), | 1701 | GPIO_FN(DBGMD21), |
| 1693 | 1702 | ||
| 1694 | /* FSI */ | 1703 | /* FSI-A */ |
| 1695 | GPIO_FN(FSIAISLD_PORT0), /* FSIAISLD Port 0/5 */ | 1704 | GPIO_FN(FSIAISLD_PORT0), /* FSIAISLD Port 0/5 */ |
| 1696 | GPIO_FN(FSIAISLD_PORT5), | 1705 | GPIO_FN(FSIAISLD_PORT5), |
| 1697 | GPIO_FN(FSIASPDIF_PORT9), /* FSIASPDIF Port 9/18 */ | 1706 | GPIO_FN(FSIASPDIF_PORT9), /* FSIASPDIF Port 9/18 */ |
| @@ -1700,6 +1709,9 @@ static struct pinmux_gpio pinmux_gpios[] = { | |||
| 1700 | GPIO_FN(FSIAOBT), GPIO_FN(FSIAOSLD), GPIO_FN(FSIAOMC), | 1709 | GPIO_FN(FSIAOBT), GPIO_FN(FSIAOSLD), GPIO_FN(FSIAOMC), |
| 1701 | GPIO_FN(FSIACK), GPIO_FN(FSIAILR), GPIO_FN(FSIAIBT), | 1710 | GPIO_FN(FSIACK), GPIO_FN(FSIAILR), GPIO_FN(FSIAIBT), |
| 1702 | 1711 | ||
| 1712 | /* FSI-B */ | ||
| 1713 | GPIO_FN(FSIBCK), | ||
| 1714 | |||
| 1703 | /* FMSI */ | 1715 | /* FMSI */ |
| 1704 | GPIO_FN(FMSISLD_PORT1), /* FMSISLD Port 1/6 */ | 1716 | GPIO_FN(FMSISLD_PORT1), /* FMSISLD Port 1/6 */ |
| 1705 | GPIO_FN(FMSISLD_PORT6), | 1717 | GPIO_FN(FMSISLD_PORT6), |
| @@ -2097,6 +2109,10 @@ static struct pinmux_gpio pinmux_gpios[] = { | |||
| 2097 | GPIO_FN(SDENC_CPG), | 2109 | GPIO_FN(SDENC_CPG), |
| 2098 | GPIO_FN(SDENC_DV_CLKI), | 2110 | GPIO_FN(SDENC_DV_CLKI), |
| 2099 | 2111 | ||
| 2112 | /* HDMI */ | ||
| 2113 | GPIO_FN(HDMI_HPD), | ||
| 2114 | GPIO_FN(HDMI_CEC), | ||
| 2115 | |||
| 2100 | /* SYSC */ | 2116 | /* SYSC */ |
| 2101 | GPIO_FN(RESETP_PULLUP), | 2117 | GPIO_FN(RESETP_PULLUP), |
| 2102 | GPIO_FN(RESETP_PLAIN), | 2118 | GPIO_FN(RESETP_PLAIN), |
diff --git a/arch/arm/mach-shmobile/pm-r8a7740.c b/arch/arm/mach-shmobile/pm-r8a7740.c new file mode 100644 index 000000000000..893504d012a6 --- /dev/null +++ b/arch/arm/mach-shmobile/pm-r8a7740.c | |||
| @@ -0,0 +1,54 @@ | |||
| 1 | /* | ||
| 2 | * r8a7740 power management support | ||
| 3 | * | ||
| 4 | * Copyright (C) 2012 Renesas Solutions Corp. | ||
| 5 | * Copyright (C) 2012 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | ||
| 6 | * | ||
| 7 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 8 | * License. See the file "COPYING" in the main directory of this archive | ||
| 9 | * for more details. | ||
| 10 | */ | ||
| 11 | #include <linux/console.h> | ||
| 12 | #include <mach/pm-rmobile.h> | ||
| 13 | |||
| 14 | #ifdef CONFIG_PM | ||
| 15 | static int r8a7740_pd_a4s_suspend(void) | ||
| 16 | { | ||
| 17 | /* | ||
| 18 | * The A4S domain contains the CPU core and therefore it should | ||
| 19 | * only be turned off if the CPU is in use. | ||
| 20 | */ | ||
| 21 | return -EBUSY; | ||
| 22 | } | ||
| 23 | |||
| 24 | struct rmobile_pm_domain r8a7740_pd_a4s = { | ||
| 25 | .genpd.name = "A4S", | ||
| 26 | .bit_shift = 10, | ||
| 27 | .gov = &pm_domain_always_on_gov, | ||
| 28 | .no_debug = true, | ||
| 29 | .suspend = r8a7740_pd_a4s_suspend, | ||
| 30 | }; | ||
| 31 | |||
| 32 | static int r8a7740_pd_a3sp_suspend(void) | ||
| 33 | { | ||
| 34 | /* | ||
| 35 | * Serial consoles make use of SCIF hardware located in A3SP, | ||
| 36 | * keep such power domain on if "no_console_suspend" is set. | ||
| 37 | */ | ||
| 38 | return console_suspend_enabled ? 0 : -EBUSY; | ||
| 39 | } | ||
| 40 | |||
| 41 | struct rmobile_pm_domain r8a7740_pd_a3sp = { | ||
| 42 | .genpd.name = "A3SP", | ||
| 43 | .bit_shift = 11, | ||
| 44 | .gov = &pm_domain_always_on_gov, | ||
| 45 | .no_debug = true, | ||
| 46 | .suspend = r8a7740_pd_a3sp_suspend, | ||
| 47 | }; | ||
| 48 | |||
| 49 | struct rmobile_pm_domain r8a7740_pd_a4lc = { | ||
| 50 | .genpd.name = "A4LC", | ||
| 51 | .bit_shift = 1, | ||
| 52 | }; | ||
| 53 | |||
| 54 | #endif /* CONFIG_PM */ | ||
diff --git a/arch/arm/mach-shmobile/pm-rmobile.c b/arch/arm/mach-shmobile/pm-rmobile.c new file mode 100644 index 000000000000..a8562540f1d6 --- /dev/null +++ b/arch/arm/mach-shmobile/pm-rmobile.c | |||
| @@ -0,0 +1,167 @@ | |||
| 1 | /* | ||
| 2 | * rmobile power management support | ||
| 3 | * | ||
| 4 | * Copyright (C) 2012 Renesas Solutions Corp. | ||
| 5 | * Copyright (C) 2012 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | ||
| 6 | * | ||
| 7 | * based on pm-sh7372.c | ||
| 8 | * Copyright (C) 2011 Magnus Damm | ||
| 9 | * | ||
| 10 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 11 | * License. See the file "COPYING" in the main directory of this archive | ||
| 12 | * for more details. | ||
| 13 | */ | ||
| 14 | #include <linux/console.h> | ||
| 15 | #include <linux/delay.h> | ||
| 16 | #include <linux/platform_device.h> | ||
| 17 | #include <linux/pm.h> | ||
| 18 | #include <linux/pm_clock.h> | ||
| 19 | #include <asm/io.h> | ||
| 20 | #include <mach/pm-rmobile.h> | ||
| 21 | |||
| 22 | /* SYSC */ | ||
| 23 | #define SPDCR 0xe6180008 | ||
| 24 | #define SWUCR 0xe6180014 | ||
| 25 | #define PSTR 0xe6180080 | ||
| 26 | |||
| 27 | #define PSTR_RETRIES 100 | ||
| 28 | #define PSTR_DELAY_US 10 | ||
| 29 | |||
| 30 | #ifdef CONFIG_PM | ||
| 31 | static int rmobile_pd_power_down(struct generic_pm_domain *genpd) | ||
| 32 | { | ||
| 33 | struct rmobile_pm_domain *rmobile_pd = to_rmobile_pd(genpd); | ||
| 34 | unsigned int mask = 1 << rmobile_pd->bit_shift; | ||
| 35 | |||
| 36 | if (rmobile_pd->suspend) { | ||
| 37 | int ret = rmobile_pd->suspend(); | ||
| 38 | |||
| 39 | if (ret) | ||
| 40 | return ret; | ||
| 41 | } | ||
| 42 | |||
| 43 | if (__raw_readl(PSTR) & mask) { | ||
| 44 | unsigned int retry_count; | ||
| 45 | __raw_writel(mask, SPDCR); | ||
| 46 | |||
| 47 | for (retry_count = PSTR_RETRIES; retry_count; retry_count--) { | ||
| 48 | if (!(__raw_readl(SPDCR) & mask)) | ||
| 49 | break; | ||
| 50 | cpu_relax(); | ||
| 51 | } | ||
| 52 | } | ||
| 53 | |||
| 54 | if (!rmobile_pd->no_debug) | ||
| 55 | pr_debug("%s: Power off, 0x%08x -> PSTR = 0x%08x\n", | ||
| 56 | genpd->name, mask, __raw_readl(PSTR)); | ||
| 57 | |||
| 58 | return 0; | ||
| 59 | } | ||
| 60 | |||
| 61 | static int __rmobile_pd_power_up(struct rmobile_pm_domain *rmobile_pd, | ||
| 62 | bool do_resume) | ||
| 63 | { | ||
| 64 | unsigned int mask = 1 << rmobile_pd->bit_shift; | ||
| 65 | unsigned int retry_count; | ||
| 66 | int ret = 0; | ||
| 67 | |||
| 68 | if (__raw_readl(PSTR) & mask) | ||
| 69 | goto out; | ||
| 70 | |||
| 71 | __raw_writel(mask, SWUCR); | ||
| 72 | |||
| 73 | for (retry_count = 2 * PSTR_RETRIES; retry_count; retry_count--) { | ||
| 74 | if (!(__raw_readl(SWUCR) & mask)) | ||
| 75 | break; | ||
| 76 | if (retry_count > PSTR_RETRIES) | ||
| 77 | udelay(PSTR_DELAY_US); | ||
| 78 | else | ||
| 79 | cpu_relax(); | ||
| 80 | } | ||
| 81 | if (!retry_count) | ||
| 82 | ret = -EIO; | ||
| 83 | |||
| 84 | if (!rmobile_pd->no_debug) | ||
| 85 | pr_debug("%s: Power on, 0x%08x -> PSTR = 0x%08x\n", | ||
| 86 | rmobile_pd->genpd.name, mask, __raw_readl(PSTR)); | ||
| 87 | |||
| 88 | out: | ||
| 89 | if (ret == 0 && rmobile_pd->resume && do_resume) | ||
| 90 | rmobile_pd->resume(); | ||
| 91 | |||
| 92 | return ret; | ||
| 93 | } | ||
| 94 | |||
| 95 | static int rmobile_pd_power_up(struct generic_pm_domain *genpd) | ||
| 96 | { | ||
| 97 | return __rmobile_pd_power_up(to_rmobile_pd(genpd), true); | ||
| 98 | } | ||
| 99 | |||
| 100 | static bool rmobile_pd_active_wakeup(struct device *dev) | ||
| 101 | { | ||
| 102 | bool (*active_wakeup)(struct device *dev); | ||
| 103 | |||
| 104 | active_wakeup = dev_gpd_data(dev)->ops.active_wakeup; | ||
| 105 | return active_wakeup ? active_wakeup(dev) : true; | ||
| 106 | } | ||
| 107 | |||
| 108 | static int rmobile_pd_stop_dev(struct device *dev) | ||
| 109 | { | ||
| 110 | int (*stop)(struct device *dev); | ||
| 111 | |||
| 112 | stop = dev_gpd_data(dev)->ops.stop; | ||
| 113 | if (stop) { | ||
| 114 | int ret = stop(dev); | ||
| 115 | if (ret) | ||
| 116 | return ret; | ||
| 117 | } | ||
| 118 | return pm_clk_suspend(dev); | ||
| 119 | } | ||
| 120 | |||
| 121 | static int rmobile_pd_start_dev(struct device *dev) | ||
| 122 | { | ||
| 123 | int (*start)(struct device *dev); | ||
| 124 | int ret; | ||
| 125 | |||
| 126 | ret = pm_clk_resume(dev); | ||
| 127 | if (ret) | ||
| 128 | return ret; | ||
| 129 | |||
| 130 | start = dev_gpd_data(dev)->ops.start; | ||
| 131 | if (start) | ||
| 132 | ret = start(dev); | ||
| 133 | |||
| 134 | return ret; | ||
| 135 | } | ||
| 136 | |||
| 137 | void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd) | ||
| 138 | { | ||
| 139 | struct generic_pm_domain *genpd = &rmobile_pd->genpd; | ||
| 140 | struct dev_power_governor *gov = rmobile_pd->gov; | ||
| 141 | |||
| 142 | pm_genpd_init(genpd, gov ? : &simple_qos_governor, false); | ||
| 143 | genpd->dev_ops.stop = rmobile_pd_stop_dev; | ||
| 144 | genpd->dev_ops.start = rmobile_pd_start_dev; | ||
| 145 | genpd->dev_ops.active_wakeup = rmobile_pd_active_wakeup; | ||
| 146 | genpd->dev_irq_safe = true; | ||
| 147 | genpd->power_off = rmobile_pd_power_down; | ||
| 148 | genpd->power_on = rmobile_pd_power_up; | ||
| 149 | __rmobile_pd_power_up(rmobile_pd, false); | ||
| 150 | } | ||
| 151 | |||
| 152 | void rmobile_add_device_to_domain(struct rmobile_pm_domain *rmobile_pd, | ||
| 153 | struct platform_device *pdev) | ||
| 154 | { | ||
| 155 | struct device *dev = &pdev->dev; | ||
| 156 | |||
| 157 | pm_genpd_add_device(&rmobile_pd->genpd, dev); | ||
| 158 | if (pm_clk_no_clocks(dev)) | ||
| 159 | pm_clk_add(dev, NULL); | ||
| 160 | } | ||
| 161 | |||
| 162 | void rmobile_pm_add_subdomain(struct rmobile_pm_domain *rmobile_pd, | ||
| 163 | struct rmobile_pm_domain *rmobile_sd) | ||
| 164 | { | ||
| 165 | pm_genpd_add_subdomain(&rmobile_pd->genpd, &rmobile_sd->genpd); | ||
| 166 | } | ||
| 167 | #endif /* CONFIG_PM */ | ||
diff --git a/arch/arm/mach-shmobile/pm-sh7372.c b/arch/arm/mach-shmobile/pm-sh7372.c index a3bdb12acde9..792037069226 100644 --- a/arch/arm/mach-shmobile/pm-sh7372.c +++ b/arch/arm/mach-shmobile/pm-sh7372.c | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #include <asm/suspend.h> | 26 | #include <asm/suspend.h> |
| 27 | #include <mach/common.h> | 27 | #include <mach/common.h> |
| 28 | #include <mach/sh7372.h> | 28 | #include <mach/sh7372.h> |
| 29 | #include <mach/pm-rmobile.h> | ||
| 29 | 30 | ||
| 30 | /* DBG */ | 31 | /* DBG */ |
| 31 | #define DBGREG1 0xe6100020 | 32 | #define DBGREG1 0xe6100020 |
| @@ -41,13 +42,10 @@ | |||
| 41 | #define PLLC01STPCR 0xe61500c8 | 42 | #define PLLC01STPCR 0xe61500c8 |
| 42 | 43 | ||
| 43 | /* SYSC */ | 44 | /* SYSC */ |
| 44 | #define SPDCR 0xe6180008 | ||
| 45 | #define SWUCR 0xe6180014 | ||
| 46 | #define SBAR 0xe6180020 | 45 | #define SBAR 0xe6180020 |
| 47 | #define WUPRMSK 0xe6180028 | 46 | #define WUPRMSK 0xe6180028 |
| 48 | #define WUPSMSK 0xe618002c | 47 | #define WUPSMSK 0xe618002c |
| 49 | #define WUPSMSK2 0xe6180048 | 48 | #define WUPSMSK2 0xe6180048 |
| 50 | #define PSTR 0xe6180080 | ||
| 51 | #define WUPSFAC 0xe6180098 | 49 | #define WUPSFAC 0xe6180098 |
| 52 | #define IRQCR 0xe618022c | 50 | #define IRQCR 0xe618022c |
| 53 | #define IRQCR2 0xe6180238 | 51 | #define IRQCR2 0xe6180238 |
| @@ -71,188 +69,48 @@ | |||
| 71 | /* AP-System Core */ | 69 | /* AP-System Core */ |
| 72 | #define APARMBAREA 0xe6f10020 | 70 | #define APARMBAREA 0xe6f10020 |
| 73 | 71 | ||
| 74 | #define PSTR_RETRIES 100 | ||
| 75 | #define PSTR_DELAY_US 10 | ||
| 76 | |||
| 77 | #ifdef CONFIG_PM | 72 | #ifdef CONFIG_PM |
| 78 | 73 | ||
| 79 | static int pd_power_down(struct generic_pm_domain *genpd) | 74 | struct rmobile_pm_domain sh7372_pd_a4lc = { |
| 80 | { | ||
| 81 | struct sh7372_pm_domain *sh7372_pd = to_sh7372_pd(genpd); | ||
| 82 | unsigned int mask = 1 << sh7372_pd->bit_shift; | ||
| 83 | |||
| 84 | if (sh7372_pd->suspend) { | ||
| 85 | int ret = sh7372_pd->suspend(); | ||
| 86 | |||
| 87 | if (ret) | ||
| 88 | return ret; | ||
| 89 | } | ||
| 90 | |||
| 91 | if (__raw_readl(PSTR) & mask) { | ||
| 92 | unsigned int retry_count; | ||
| 93 | |||
| 94 | __raw_writel(mask, SPDCR); | ||
| 95 | |||
| 96 | for (retry_count = PSTR_RETRIES; retry_count; retry_count--) { | ||
| 97 | if (!(__raw_readl(SPDCR) & mask)) | ||
| 98 | break; | ||
| 99 | cpu_relax(); | ||
| 100 | } | ||
| 101 | } | ||
| 102 | |||
| 103 | if (!sh7372_pd->no_debug) | ||
| 104 | pr_debug("%s: Power off, 0x%08x -> PSTR = 0x%08x\n", | ||
| 105 | genpd->name, mask, __raw_readl(PSTR)); | ||
| 106 | |||
| 107 | return 0; | ||
| 108 | } | ||
| 109 | |||
| 110 | static int __pd_power_up(struct sh7372_pm_domain *sh7372_pd, bool do_resume) | ||
| 111 | { | ||
| 112 | unsigned int mask = 1 << sh7372_pd->bit_shift; | ||
| 113 | unsigned int retry_count; | ||
| 114 | int ret = 0; | ||
| 115 | |||
| 116 | if (__raw_readl(PSTR) & mask) | ||
| 117 | goto out; | ||
| 118 | |||
| 119 | __raw_writel(mask, SWUCR); | ||
| 120 | |||
| 121 | for (retry_count = 2 * PSTR_RETRIES; retry_count; retry_count--) { | ||
| 122 | if (!(__raw_readl(SWUCR) & mask)) | ||
| 123 | break; | ||
| 124 | if (retry_count > PSTR_RETRIES) | ||
| 125 | udelay(PSTR_DELAY_US); | ||
| 126 | else | ||
| 127 | cpu_relax(); | ||
| 128 | } | ||
| 129 | if (!retry_count) | ||
| 130 | ret = -EIO; | ||
| 131 | |||
| 132 | if (!sh7372_pd->no_debug) | ||
| 133 | pr_debug("%s: Power on, 0x%08x -> PSTR = 0x%08x\n", | ||
| 134 | sh7372_pd->genpd.name, mask, __raw_readl(PSTR)); | ||
| 135 | |||
| 136 | out: | ||
| 137 | if (ret == 0 && sh7372_pd->resume && do_resume) | ||
| 138 | sh7372_pd->resume(); | ||
| 139 | |||
| 140 | return ret; | ||
| 141 | } | ||
| 142 | |||
| 143 | static int pd_power_up(struct generic_pm_domain *genpd) | ||
| 144 | { | ||
| 145 | return __pd_power_up(to_sh7372_pd(genpd), true); | ||
| 146 | } | ||
| 147 | |||
| 148 | static int sh7372_a4r_suspend(void) | ||
| 149 | { | ||
| 150 | sh7372_intcs_suspend(); | ||
| 151 | __raw_writel(0x300fffff, WUPRMSK); /* avoid wakeup */ | ||
| 152 | return 0; | ||
| 153 | } | ||
| 154 | |||
| 155 | static bool pd_active_wakeup(struct device *dev) | ||
| 156 | { | ||
| 157 | bool (*active_wakeup)(struct device *dev); | ||
| 158 | |||
| 159 | active_wakeup = dev_gpd_data(dev)->ops.active_wakeup; | ||
| 160 | return active_wakeup ? active_wakeup(dev) : true; | ||
| 161 | } | ||
| 162 | |||
| 163 | static int sh7372_stop_dev(struct device *dev) | ||
| 164 | { | ||
| 165 | int (*stop)(struct device *dev); | ||
| 166 | |||
| 167 | stop = dev_gpd_data(dev)->ops.stop; | ||
| 168 | if (stop) { | ||
| 169 | int ret = stop(dev); | ||
| 170 | if (ret) | ||
| 171 | return ret; | ||
| 172 | } | ||
| 173 | return pm_clk_suspend(dev); | ||
| 174 | } | ||
| 175 | |||
| 176 | static int sh7372_start_dev(struct device *dev) | ||
| 177 | { | ||
| 178 | int (*start)(struct device *dev); | ||
| 179 | int ret; | ||
| 180 | |||
| 181 | ret = pm_clk_resume(dev); | ||
| 182 | if (ret) | ||
| 183 | return ret; | ||
| 184 | |||
| 185 | start = dev_gpd_data(dev)->ops.start; | ||
| 186 | if (start) | ||
| 187 | ret = start(dev); | ||
| 188 | |||
| 189 | return ret; | ||
| 190 | } | ||
| 191 | |||
| 192 | void sh7372_init_pm_domain(struct sh7372_pm_domain *sh7372_pd) | ||
| 193 | { | ||
| 194 | struct generic_pm_domain *genpd = &sh7372_pd->genpd; | ||
| 195 | struct dev_power_governor *gov = sh7372_pd->gov; | ||
| 196 | |||
| 197 | pm_genpd_init(genpd, gov ? : &simple_qos_governor, false); | ||
| 198 | genpd->dev_ops.stop = sh7372_stop_dev; | ||
| 199 | genpd->dev_ops.start = sh7372_start_dev; | ||
| 200 | genpd->dev_ops.active_wakeup = pd_active_wakeup; | ||
| 201 | genpd->dev_irq_safe = true; | ||
| 202 | genpd->power_off = pd_power_down; | ||
| 203 | genpd->power_on = pd_power_up; | ||
| 204 | __pd_power_up(sh7372_pd, false); | ||
| 205 | } | ||
| 206 | |||
| 207 | void sh7372_add_device_to_domain(struct sh7372_pm_domain *sh7372_pd, | ||
| 208 | struct platform_device *pdev) | ||
| 209 | { | ||
| 210 | struct device *dev = &pdev->dev; | ||
| 211 | |||
| 212 | pm_genpd_add_device(&sh7372_pd->genpd, dev); | ||
| 213 | if (pm_clk_no_clocks(dev)) | ||
| 214 | pm_clk_add(dev, NULL); | ||
| 215 | } | ||
| 216 | |||
| 217 | void sh7372_pm_add_subdomain(struct sh7372_pm_domain *sh7372_pd, | ||
| 218 | struct sh7372_pm_domain *sh7372_sd) | ||
| 219 | { | ||
| 220 | pm_genpd_add_subdomain(&sh7372_pd->genpd, &sh7372_sd->genpd); | ||
| 221 | } | ||
| 222 | |||
| 223 | struct sh7372_pm_domain sh7372_a4lc = { | ||
| 224 | .genpd.name = "A4LC", | 75 | .genpd.name = "A4LC", |
| 225 | .bit_shift = 1, | 76 | .bit_shift = 1, |
| 226 | }; | 77 | }; |
| 227 | 78 | ||
| 228 | struct sh7372_pm_domain sh7372_a4mp = { | 79 | struct rmobile_pm_domain sh7372_pd_a4mp = { |
| 229 | .genpd.name = "A4MP", | 80 | .genpd.name = "A4MP", |
| 230 | .bit_shift = 2, | 81 | .bit_shift = 2, |
| 231 | }; | 82 | }; |
| 232 | 83 | ||
| 233 | struct sh7372_pm_domain sh7372_d4 = { | 84 | struct rmobile_pm_domain sh7372_pd_d4 = { |
| 234 | .genpd.name = "D4", | 85 | .genpd.name = "D4", |
| 235 | .bit_shift = 3, | 86 | .bit_shift = 3, |
| 236 | }; | 87 | }; |
| 237 | 88 | ||
| 238 | struct sh7372_pm_domain sh7372_a4r = { | 89 | static int sh7372_a4r_pd_suspend(void) |
| 90 | { | ||
| 91 | sh7372_intcs_suspend(); | ||
| 92 | __raw_writel(0x300fffff, WUPRMSK); /* avoid wakeup */ | ||
| 93 | return 0; | ||
| 94 | } | ||
| 95 | |||
| 96 | struct rmobile_pm_domain sh7372_pd_a4r = { | ||
| 239 | .genpd.name = "A4R", | 97 | .genpd.name = "A4R", |
| 240 | .bit_shift = 5, | 98 | .bit_shift = 5, |
| 241 | .suspend = sh7372_a4r_suspend, | 99 | .suspend = sh7372_a4r_pd_suspend, |
| 242 | .resume = sh7372_intcs_resume, | 100 | .resume = sh7372_intcs_resume, |
| 243 | }; | 101 | }; |
| 244 | 102 | ||
| 245 | struct sh7372_pm_domain sh7372_a3rv = { | 103 | struct rmobile_pm_domain sh7372_pd_a3rv = { |
| 246 | .genpd.name = "A3RV", | 104 | .genpd.name = "A3RV", |
| 247 | .bit_shift = 6, | 105 | .bit_shift = 6, |
| 248 | }; | 106 | }; |
| 249 | 107 | ||
| 250 | struct sh7372_pm_domain sh7372_a3ri = { | 108 | struct rmobile_pm_domain sh7372_pd_a3ri = { |
| 251 | .genpd.name = "A3RI", | 109 | .genpd.name = "A3RI", |
| 252 | .bit_shift = 8, | 110 | .bit_shift = 8, |
| 253 | }; | 111 | }; |
| 254 | 112 | ||
| 255 | static int sh7372_a4s_suspend(void) | 113 | static int sh7372_pd_a4s_suspend(void) |
| 256 | { | 114 | { |
| 257 | /* | 115 | /* |
| 258 | * The A4S domain contains the CPU core and therefore it should | 116 | * The A4S domain contains the CPU core and therefore it should |
| @@ -261,15 +119,15 @@ static int sh7372_a4s_suspend(void) | |||
| 261 | return -EBUSY; | 119 | return -EBUSY; |
| 262 | } | 120 | } |
| 263 | 121 | ||
| 264 | struct sh7372_pm_domain sh7372_a4s = { | 122 | struct rmobile_pm_domain sh7372_pd_a4s = { |
| 265 | .genpd.name = "A4S", | 123 | .genpd.name = "A4S", |
| 266 | .bit_shift = 10, | 124 | .bit_shift = 10, |
| 267 | .gov = &pm_domain_always_on_gov, | 125 | .gov = &pm_domain_always_on_gov, |
| 268 | .no_debug = true, | 126 | .no_debug = true, |
| 269 | .suspend = sh7372_a4s_suspend, | 127 | .suspend = sh7372_pd_a4s_suspend, |
| 270 | }; | 128 | }; |
| 271 | 129 | ||
| 272 | static int sh7372_a3sp_suspend(void) | 130 | static int sh7372_a3sp_pd_suspend(void) |
| 273 | { | 131 | { |
| 274 | /* | 132 | /* |
| 275 | * Serial consoles make use of SCIF hardware located in A3SP, | 133 | * Serial consoles make use of SCIF hardware located in A3SP, |
| @@ -278,32 +136,22 @@ static int sh7372_a3sp_suspend(void) | |||
| 278 | return console_suspend_enabled ? 0 : -EBUSY; | 136 | return console_suspend_enabled ? 0 : -EBUSY; |
| 279 | } | 137 | } |
| 280 | 138 | ||
| 281 | struct sh7372_pm_domain sh7372_a3sp = { | 139 | struct rmobile_pm_domain sh7372_pd_a3sp = { |
| 282 | .genpd.name = "A3SP", | 140 | .genpd.name = "A3SP", |
| 283 | .bit_shift = 11, | 141 | .bit_shift = 11, |
| 284 | .gov = &pm_domain_always_on_gov, | 142 | .gov = &pm_domain_always_on_gov, |
| 285 | .no_debug = true, | 143 | .no_debug = true, |
| 286 | .suspend = sh7372_a3sp_suspend, | 144 | .suspend = sh7372_a3sp_pd_suspend, |
| 287 | }; | 145 | }; |
| 288 | 146 | ||
| 289 | struct sh7372_pm_domain sh7372_a3sg = { | 147 | struct rmobile_pm_domain sh7372_pd_a3sg = { |
| 290 | .genpd.name = "A3SG", | 148 | .genpd.name = "A3SG", |
| 291 | .bit_shift = 13, | 149 | .bit_shift = 13, |
| 292 | }; | 150 | }; |
| 293 | 151 | ||
| 294 | #else /* !CONFIG_PM */ | 152 | #endif /* CONFIG_PM */ |
| 295 | |||
| 296 | static inline void sh7372_a3sp_init(void) {} | ||
| 297 | |||
| 298 | #endif /* !CONFIG_PM */ | ||
| 299 | 153 | ||
| 300 | #if defined(CONFIG_SUSPEND) || defined(CONFIG_CPU_IDLE) | 154 | #if defined(CONFIG_SUSPEND) || defined(CONFIG_CPU_IDLE) |
| 301 | static int sh7372_do_idle_core_standby(unsigned long unused) | ||
| 302 | { | ||
| 303 | cpu_do_idle(); /* WFI when SYSTBCR == 0x10 -> Core Standby */ | ||
| 304 | return 0; | ||
| 305 | } | ||
| 306 | |||
| 307 | static void sh7372_set_reset_vector(unsigned long address) | 155 | static void sh7372_set_reset_vector(unsigned long address) |
| 308 | { | 156 | { |
| 309 | /* set reset vector, translate 4k */ | 157 | /* set reset vector, translate 4k */ |
| @@ -311,21 +159,6 @@ static void sh7372_set_reset_vector(unsigned long address) | |||
| 311 | __raw_writel(0, APARMBAREA); | 159 | __raw_writel(0, APARMBAREA); |
| 312 | } | 160 | } |
| 313 | 161 | ||
| 314 | static void sh7372_enter_core_standby(void) | ||
| 315 | { | ||
| 316 | sh7372_set_reset_vector(__pa(sh7372_resume_core_standby_sysc)); | ||
| 317 | |||
| 318 | /* enter sleep mode with SYSTBCR to 0x10 */ | ||
| 319 | __raw_writel(0x10, SYSTBCR); | ||
| 320 | cpu_suspend(0, sh7372_do_idle_core_standby); | ||
| 321 | __raw_writel(0, SYSTBCR); | ||
| 322 | |||
| 323 | /* disable reset vector translation */ | ||
| 324 | __raw_writel(0, SBAR); | ||
| 325 | } | ||
| 326 | #endif | ||
| 327 | |||
| 328 | #ifdef CONFIG_SUSPEND | ||
| 329 | static void sh7372_enter_sysc(int pllc0_on, unsigned long sleep_mode) | 162 | static void sh7372_enter_sysc(int pllc0_on, unsigned long sleep_mode) |
| 330 | { | 163 | { |
| 331 | if (pllc0_on) | 164 | if (pllc0_on) |
| @@ -465,22 +298,42 @@ static void sh7372_setup_sysc(unsigned long msk, unsigned long msk2) | |||
| 465 | 298 | ||
| 466 | static void sh7372_enter_a3sm_common(int pllc0_on) | 299 | static void sh7372_enter_a3sm_common(int pllc0_on) |
| 467 | { | 300 | { |
| 301 | /* use INTCA together with SYSC for wakeup */ | ||
| 302 | sh7372_setup_sysc(1 << 0, 0); | ||
| 468 | sh7372_set_reset_vector(__pa(sh7372_resume_core_standby_sysc)); | 303 | sh7372_set_reset_vector(__pa(sh7372_resume_core_standby_sysc)); |
| 469 | sh7372_enter_sysc(pllc0_on, 1 << 12); | 304 | sh7372_enter_sysc(pllc0_on, 1 << 12); |
| 470 | } | 305 | } |
| 306 | #endif /* CONFIG_SUSPEND || CONFIG_CPU_IDLE */ | ||
| 471 | 307 | ||
| 472 | static void sh7372_enter_a4s_common(int pllc0_on) | 308 | #ifdef CONFIG_CPU_IDLE |
| 309 | static int sh7372_do_idle_core_standby(unsigned long unused) | ||
| 473 | { | 310 | { |
| 474 | sh7372_intca_suspend(); | 311 | cpu_do_idle(); /* WFI when SYSTBCR == 0x10 -> Core Standby */ |
| 475 | memcpy((void *)SMFRAM, sh7372_resume_core_standby_sysc, 0x100); | 312 | return 0; |
| 476 | sh7372_set_reset_vector(SMFRAM); | ||
| 477 | sh7372_enter_sysc(pllc0_on, 1 << 10); | ||
| 478 | sh7372_intca_resume(); | ||
| 479 | } | 313 | } |
| 480 | 314 | ||
| 481 | #endif | 315 | static void sh7372_enter_core_standby(void) |
| 316 | { | ||
| 317 | sh7372_set_reset_vector(__pa(sh7372_resume_core_standby_sysc)); | ||
| 482 | 318 | ||
| 483 | #ifdef CONFIG_CPU_IDLE | 319 | /* enter sleep mode with SYSTBCR to 0x10 */ |
| 320 | __raw_writel(0x10, SYSTBCR); | ||
| 321 | cpu_suspend(0, sh7372_do_idle_core_standby); | ||
| 322 | __raw_writel(0, SYSTBCR); | ||
| 323 | |||
| 324 | /* disable reset vector translation */ | ||
| 325 | __raw_writel(0, SBAR); | ||
| 326 | } | ||
| 327 | |||
| 328 | static void sh7372_enter_a3sm_pll_on(void) | ||
| 329 | { | ||
| 330 | sh7372_enter_a3sm_common(1); | ||
| 331 | } | ||
| 332 | |||
| 333 | static void sh7372_enter_a3sm_pll_off(void) | ||
| 334 | { | ||
| 335 | sh7372_enter_a3sm_common(0); | ||
| 336 | } | ||
| 484 | 337 | ||
| 485 | static void sh7372_cpuidle_setup(struct cpuidle_driver *drv) | 338 | static void sh7372_cpuidle_setup(struct cpuidle_driver *drv) |
| 486 | { | 339 | { |
| @@ -492,7 +345,24 @@ static void sh7372_cpuidle_setup(struct cpuidle_driver *drv) | |||
| 492 | state->target_residency = 20 + 10; | 345 | state->target_residency = 20 + 10; |
| 493 | state->flags = CPUIDLE_FLAG_TIME_VALID; | 346 | state->flags = CPUIDLE_FLAG_TIME_VALID; |
| 494 | shmobile_cpuidle_modes[drv->state_count] = sh7372_enter_core_standby; | 347 | shmobile_cpuidle_modes[drv->state_count] = sh7372_enter_core_standby; |
| 348 | drv->state_count++; | ||
| 349 | |||
| 350 | state = &drv->states[drv->state_count]; | ||
| 351 | snprintf(state->name, CPUIDLE_NAME_LEN, "C3"); | ||
| 352 | strncpy(state->desc, "A3SM PLL ON", CPUIDLE_DESC_LEN); | ||
| 353 | state->exit_latency = 20; | ||
| 354 | state->target_residency = 30 + 20; | ||
| 355 | state->flags = CPUIDLE_FLAG_TIME_VALID; | ||
| 356 | shmobile_cpuidle_modes[drv->state_count] = sh7372_enter_a3sm_pll_on; | ||
| 357 | drv->state_count++; | ||
| 495 | 358 | ||
| 359 | state = &drv->states[drv->state_count]; | ||
| 360 | snprintf(state->name, CPUIDLE_NAME_LEN, "C4"); | ||
| 361 | strncpy(state->desc, "A3SM PLL OFF", CPUIDLE_DESC_LEN); | ||
| 362 | state->exit_latency = 120; | ||
| 363 | state->target_residency = 30 + 120; | ||
| 364 | state->flags = CPUIDLE_FLAG_TIME_VALID; | ||
| 365 | shmobile_cpuidle_modes[drv->state_count] = sh7372_enter_a3sm_pll_off; | ||
| 496 | drv->state_count++; | 366 | drv->state_count++; |
| 497 | } | 367 | } |
| 498 | 368 | ||
| @@ -505,6 +375,14 @@ static void sh7372_cpuidle_init(void) {} | |||
| 505 | #endif | 375 | #endif |
| 506 | 376 | ||
| 507 | #ifdef CONFIG_SUSPEND | 377 | #ifdef CONFIG_SUSPEND |
| 378 | static void sh7372_enter_a4s_common(int pllc0_on) | ||
| 379 | { | ||
| 380 | sh7372_intca_suspend(); | ||
| 381 | memcpy((void *)SMFRAM, sh7372_resume_core_standby_sysc, 0x100); | ||
| 382 | sh7372_set_reset_vector(SMFRAM); | ||
| 383 | sh7372_enter_sysc(pllc0_on, 1 << 10); | ||
| 384 | sh7372_intca_resume(); | ||
| 385 | } | ||
| 508 | 386 | ||
| 509 | static int sh7372_enter_suspend(suspend_state_t suspend_state) | 387 | static int sh7372_enter_suspend(suspend_state_t suspend_state) |
| 510 | { | 388 | { |
| @@ -512,24 +390,21 @@ static int sh7372_enter_suspend(suspend_state_t suspend_state) | |||
| 512 | 390 | ||
| 513 | /* check active clocks to determine potential wakeup sources */ | 391 | /* check active clocks to determine potential wakeup sources */ |
| 514 | if (sh7372_sysc_valid(&msk, &msk2)) { | 392 | if (sh7372_sysc_valid(&msk, &msk2)) { |
| 515 | /* convert INTC mask and sense to SYSC mask and sense */ | ||
| 516 | sh7372_setup_sysc(msk, msk2); | ||
| 517 | |||
| 518 | if (!console_suspend_enabled && | 393 | if (!console_suspend_enabled && |
| 519 | sh7372_a4s.genpd.status == GPD_STATE_POWER_OFF) { | 394 | sh7372_pd_a4s.genpd.status == GPD_STATE_POWER_OFF) { |
| 395 | /* convert INTC mask/sense to SYSC mask/sense */ | ||
| 396 | sh7372_setup_sysc(msk, msk2); | ||
| 397 | |||
| 520 | /* enter A4S sleep with PLLC0 off */ | 398 | /* enter A4S sleep with PLLC0 off */ |
| 521 | pr_debug("entering A4S\n"); | 399 | pr_debug("entering A4S\n"); |
| 522 | sh7372_enter_a4s_common(0); | 400 | sh7372_enter_a4s_common(0); |
| 523 | } else { | 401 | return 0; |
| 524 | /* enter A3SM sleep with PLLC0 off */ | ||
| 525 | pr_debug("entering A3SM\n"); | ||
| 526 | sh7372_enter_a3sm_common(0); | ||
| 527 | } | 402 | } |
| 528 | } else { | ||
| 529 | /* default to Core Standby that supports all wakeup sources */ | ||
| 530 | pr_debug("entering Core Standby\n"); | ||
| 531 | sh7372_enter_core_standby(); | ||
| 532 | } | 403 | } |
| 404 | |||
| 405 | /* default to enter A3SM sleep with PLLC0 off */ | ||
| 406 | pr_debug("entering A3SM\n"); | ||
| 407 | sh7372_enter_a3sm_common(0); | ||
| 533 | return 0; | 408 | return 0; |
| 534 | } | 409 | } |
| 535 | 410 | ||
| @@ -550,7 +425,7 @@ static int sh7372_pm_notifier_fn(struct notifier_block *notifier, | |||
| 550 | * executed during system suspend and resume, respectively, so | 425 | * executed during system suspend and resume, respectively, so |
| 551 | * that those functions don't crash while accessing the INTCS. | 426 | * that those functions don't crash while accessing the INTCS. |
| 552 | */ | 427 | */ |
| 553 | pm_genpd_poweron(&sh7372_a4r.genpd); | 428 | pm_genpd_poweron(&sh7372_pd_a4r.genpd); |
| 554 | break; | 429 | break; |
| 555 | case PM_POST_SUSPEND: | 430 | case PM_POST_SUSPEND: |
| 556 | pm_genpd_poweroff_unused(); | 431 | pm_genpd_poweroff_unused(); |
diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c index ec4eb49c1693..78948a9dba0e 100644 --- a/arch/arm/mach-shmobile/setup-r8a7740.c +++ b/arch/arm/mach-shmobile/setup-r8a7740.c | |||
| @@ -23,9 +23,14 @@ | |||
| 23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
| 24 | #include <linux/io.h> | 24 | #include <linux/io.h> |
| 25 | #include <linux/platform_device.h> | 25 | #include <linux/platform_device.h> |
| 26 | #include <linux/of_platform.h> | ||
| 26 | #include <linux/serial_sci.h> | 27 | #include <linux/serial_sci.h> |
| 28 | #include <linux/sh_dma.h> | ||
| 27 | #include <linux/sh_timer.h> | 29 | #include <linux/sh_timer.h> |
| 30 | #include <linux/dma-mapping.h> | ||
| 31 | #include <mach/dma-register.h> | ||
| 28 | #include <mach/r8a7740.h> | 32 | #include <mach/r8a7740.h> |
| 33 | #include <mach/pm-rmobile.h> | ||
| 29 | #include <mach/common.h> | 34 | #include <mach/common.h> |
| 30 | #include <mach/irqs.h> | 35 | #include <mach/irqs.h> |
| 31 | #include <asm/mach-types.h> | 36 | #include <asm/mach-types.h> |
| @@ -276,6 +281,272 @@ static struct platform_device *r8a7740_early_devices[] __initdata = { | |||
| 276 | &cmt10_device, | 281 | &cmt10_device, |
| 277 | }; | 282 | }; |
| 278 | 283 | ||
| 284 | /* DMA */ | ||
| 285 | static const struct sh_dmae_slave_config r8a7740_dmae_slaves[] = { | ||
| 286 | { | ||
| 287 | .slave_id = SHDMA_SLAVE_SDHI0_TX, | ||
| 288 | .addr = 0xe6850030, | ||
| 289 | .chcr = CHCR_TX(XMIT_SZ_16BIT), | ||
| 290 | .mid_rid = 0xc1, | ||
| 291 | }, { | ||
| 292 | .slave_id = SHDMA_SLAVE_SDHI0_RX, | ||
| 293 | .addr = 0xe6850030, | ||
| 294 | .chcr = CHCR_RX(XMIT_SZ_16BIT), | ||
| 295 | .mid_rid = 0xc2, | ||
| 296 | }, { | ||
| 297 | .slave_id = SHDMA_SLAVE_SDHI1_TX, | ||
| 298 | .addr = 0xe6860030, | ||
| 299 | .chcr = CHCR_TX(XMIT_SZ_16BIT), | ||
| 300 | .mid_rid = 0xc9, | ||
| 301 | }, { | ||
| 302 | .slave_id = SHDMA_SLAVE_SDHI1_RX, | ||
| 303 | .addr = 0xe6860030, | ||
| 304 | .chcr = CHCR_RX(XMIT_SZ_16BIT), | ||
| 305 | .mid_rid = 0xca, | ||
| 306 | }, { | ||
| 307 | .slave_id = SHDMA_SLAVE_SDHI2_TX, | ||
| 308 | .addr = 0xe6870030, | ||
| 309 | .chcr = CHCR_TX(XMIT_SZ_16BIT), | ||
| 310 | .mid_rid = 0xcd, | ||
| 311 | }, { | ||
| 312 | .slave_id = SHDMA_SLAVE_SDHI2_RX, | ||
| 313 | .addr = 0xe6870030, | ||
| 314 | .chcr = CHCR_RX(XMIT_SZ_16BIT), | ||
| 315 | .mid_rid = 0xce, | ||
| 316 | }, { | ||
| 317 | .slave_id = SHDMA_SLAVE_FSIA_TX, | ||
| 318 | .addr = 0xfe1f0024, | ||
| 319 | .chcr = CHCR_TX(XMIT_SZ_32BIT), | ||
| 320 | .mid_rid = 0xb1, | ||
| 321 | }, { | ||
| 322 | .slave_id = SHDMA_SLAVE_FSIA_RX, | ||
| 323 | .addr = 0xfe1f0020, | ||
| 324 | .chcr = CHCR_RX(XMIT_SZ_32BIT), | ||
| 325 | .mid_rid = 0xb2, | ||
| 326 | }, { | ||
| 327 | .slave_id = SHDMA_SLAVE_FSIB_TX, | ||
| 328 | .addr = 0xfe1f0064, | ||
| 329 | .chcr = CHCR_TX(XMIT_SZ_32BIT), | ||
| 330 | .mid_rid = 0xb5, | ||
| 331 | }, | ||
| 332 | }; | ||
| 333 | |||
| 334 | #define DMA_CHANNEL(a, b, c) \ | ||
| 335 | { \ | ||
| 336 | .offset = a, \ | ||
| 337 | .dmars = b, \ | ||
| 338 | .dmars_bit = c, \ | ||
| 339 | .chclr_offset = (0x220 - 0x20) + a \ | ||
| 340 | } | ||
| 341 | |||
| 342 | static const struct sh_dmae_channel r8a7740_dmae_channels[] = { | ||
| 343 | DMA_CHANNEL(0x00, 0, 0), | ||
| 344 | DMA_CHANNEL(0x10, 0, 8), | ||
| 345 | DMA_CHANNEL(0x20, 4, 0), | ||
| 346 | DMA_CHANNEL(0x30, 4, 8), | ||
| 347 | DMA_CHANNEL(0x50, 8, 0), | ||
| 348 | DMA_CHANNEL(0x60, 8, 8), | ||
| 349 | }; | ||
| 350 | |||
| 351 | static struct sh_dmae_pdata dma_platform_data = { | ||
| 352 | .slave = r8a7740_dmae_slaves, | ||
| 353 | .slave_num = ARRAY_SIZE(r8a7740_dmae_slaves), | ||
| 354 | .channel = r8a7740_dmae_channels, | ||
| 355 | .channel_num = ARRAY_SIZE(r8a7740_dmae_channels), | ||
| 356 | .ts_low_shift = TS_LOW_SHIFT, | ||
| 357 | .ts_low_mask = TS_LOW_BIT << TS_LOW_SHIFT, | ||
| 358 | .ts_high_shift = TS_HI_SHIFT, | ||
| 359 | .ts_high_mask = TS_HI_BIT << TS_HI_SHIFT, | ||
| 360 | .ts_shift = dma_ts_shift, | ||
| 361 | .ts_shift_num = ARRAY_SIZE(dma_ts_shift), | ||
| 362 | .dmaor_init = DMAOR_DME, | ||
| 363 | .chclr_present = 1, | ||
| 364 | }; | ||
| 365 | |||
| 366 | /* Resource order important! */ | ||
| 367 | static struct resource r8a7740_dmae0_resources[] = { | ||
| 368 | { | ||
| 369 | /* Channel registers and DMAOR */ | ||
| 370 | .start = 0xfe008020, | ||
| 371 | .end = 0xfe00828f, | ||
| 372 | .flags = IORESOURCE_MEM, | ||
| 373 | }, | ||
| 374 | { | ||
| 375 | /* DMARSx */ | ||
| 376 | .start = 0xfe009000, | ||
| 377 | .end = 0xfe00900b, | ||
| 378 | .flags = IORESOURCE_MEM, | ||
| 379 | }, | ||
| 380 | { | ||
| 381 | .name = "error_irq", | ||
| 382 | .start = evt2irq(0x20c0), | ||
| 383 | .end = evt2irq(0x20c0), | ||
| 384 | .flags = IORESOURCE_IRQ, | ||
| 385 | }, | ||
| 386 | { | ||
| 387 | /* IRQ for channels 0-5 */ | ||
| 388 | .start = evt2irq(0x2000), | ||
| 389 | .end = evt2irq(0x20a0), | ||
| 390 | .flags = IORESOURCE_IRQ, | ||
| 391 | }, | ||
| 392 | }; | ||
| 393 | |||
| 394 | /* Resource order important! */ | ||
| 395 | static struct resource r8a7740_dmae1_resources[] = { | ||
| 396 | { | ||
| 397 | /* Channel registers and DMAOR */ | ||
| 398 | .start = 0xfe018020, | ||
| 399 | .end = 0xfe01828f, | ||
| 400 | .flags = IORESOURCE_MEM, | ||
| 401 | }, | ||
| 402 | { | ||
| 403 | /* DMARSx */ | ||
| 404 | .start = 0xfe019000, | ||
| 405 | .end = 0xfe01900b, | ||
| 406 | .flags = IORESOURCE_MEM, | ||
| 407 | }, | ||
| 408 | { | ||
| 409 | .name = "error_irq", | ||
| 410 | .start = evt2irq(0x21c0), | ||
| 411 | .end = evt2irq(0x21c0), | ||
| 412 | .flags = IORESOURCE_IRQ, | ||
| 413 | }, | ||
| 414 | { | ||
| 415 | /* IRQ for channels 0-5 */ | ||
| 416 | .start = evt2irq(0x2100), | ||
| 417 | .end = evt2irq(0x21a0), | ||
| 418 | .flags = IORESOURCE_IRQ, | ||
| 419 | }, | ||
| 420 | }; | ||
| 421 | |||
| 422 | /* Resource order important! */ | ||
| 423 | static struct resource r8a7740_dmae2_resources[] = { | ||
| 424 | { | ||
| 425 | /* Channel registers and DMAOR */ | ||
| 426 | .start = 0xfe028020, | ||
| 427 | .end = 0xfe02828f, | ||
| 428 | .flags = IORESOURCE_MEM, | ||
| 429 | }, | ||
| 430 | { | ||
| 431 | /* DMARSx */ | ||
| 432 | .start = 0xfe029000, | ||
| 433 | .end = 0xfe02900b, | ||
| 434 | .flags = IORESOURCE_MEM, | ||
| 435 | }, | ||
| 436 | { | ||
| 437 | .name = "error_irq", | ||
| 438 | .start = evt2irq(0x22c0), | ||
| 439 | .end = evt2irq(0x22c0), | ||
| 440 | .flags = IORESOURCE_IRQ, | ||
| 441 | }, | ||
| 442 | { | ||
| 443 | /* IRQ for channels 0-5 */ | ||
| 444 | .start = evt2irq(0x2200), | ||
| 445 | .end = evt2irq(0x22a0), | ||
| 446 | .flags = IORESOURCE_IRQ, | ||
| 447 | }, | ||
| 448 | }; | ||
| 449 | |||
| 450 | static struct platform_device dma0_device = { | ||
| 451 | .name = "sh-dma-engine", | ||
| 452 | .id = 0, | ||
| 453 | .resource = r8a7740_dmae0_resources, | ||
| 454 | .num_resources = ARRAY_SIZE(r8a7740_dmae0_resources), | ||
| 455 | .dev = { | ||
| 456 | .platform_data = &dma_platform_data, | ||
| 457 | }, | ||
| 458 | }; | ||
| 459 | |||
| 460 | static struct platform_device dma1_device = { | ||
| 461 | .name = "sh-dma-engine", | ||
| 462 | .id = 1, | ||
| 463 | .resource = r8a7740_dmae1_resources, | ||
| 464 | .num_resources = ARRAY_SIZE(r8a7740_dmae1_resources), | ||
| 465 | .dev = { | ||
| 466 | .platform_data = &dma_platform_data, | ||
| 467 | }, | ||
| 468 | }; | ||
| 469 | |||
| 470 | static struct platform_device dma2_device = { | ||
| 471 | .name = "sh-dma-engine", | ||
| 472 | .id = 2, | ||
| 473 | .resource = r8a7740_dmae2_resources, | ||
| 474 | .num_resources = ARRAY_SIZE(r8a7740_dmae2_resources), | ||
| 475 | .dev = { | ||
| 476 | .platform_data = &dma_platform_data, | ||
| 477 | }, | ||
| 478 | }; | ||
| 479 | |||
| 480 | /* USB-DMAC */ | ||
| 481 | static const struct sh_dmae_channel r8a7740_usb_dma_channels[] = { | ||
| 482 | { | ||
| 483 | .offset = 0, | ||
| 484 | }, { | ||
| 485 | .offset = 0x20, | ||
| 486 | }, | ||
| 487 | }; | ||
| 488 | |||
| 489 | static const struct sh_dmae_slave_config r8a7740_usb_dma_slaves[] = { | ||
| 490 | { | ||
| 491 | .slave_id = SHDMA_SLAVE_USBHS_TX, | ||
| 492 | .chcr = USBTS_INDEX2VAL(USBTS_XMIT_SZ_8BYTE), | ||
| 493 | }, { | ||
| 494 | .slave_id = SHDMA_SLAVE_USBHS_RX, | ||
| 495 | .chcr = USBTS_INDEX2VAL(USBTS_XMIT_SZ_8BYTE), | ||
| 496 | }, | ||
| 497 | }; | ||
| 498 | |||
| 499 | static struct sh_dmae_pdata usb_dma_platform_data = { | ||
| 500 | .slave = r8a7740_usb_dma_slaves, | ||
| 501 | .slave_num = ARRAY_SIZE(r8a7740_usb_dma_slaves), | ||
| 502 | .channel = r8a7740_usb_dma_channels, | ||
| 503 | .channel_num = ARRAY_SIZE(r8a7740_usb_dma_channels), | ||
| 504 | .ts_low_shift = USBTS_LOW_SHIFT, | ||
| 505 | .ts_low_mask = USBTS_LOW_BIT << USBTS_LOW_SHIFT, | ||
| 506 | .ts_high_shift = USBTS_HI_SHIFT, | ||
| 507 | .ts_high_mask = USBTS_HI_BIT << USBTS_HI_SHIFT, | ||
| 508 | .ts_shift = dma_usbts_shift, | ||
| 509 | .ts_shift_num = ARRAY_SIZE(dma_usbts_shift), | ||
| 510 | .dmaor_init = DMAOR_DME, | ||
| 511 | .chcr_offset = 0x14, | ||
| 512 | .chcr_ie_bit = 1 << 5, | ||
| 513 | .dmaor_is_32bit = 1, | ||
| 514 | .needs_tend_set = 1, | ||
| 515 | .no_dmars = 1, | ||
| 516 | .slave_only = 1, | ||
| 517 | }; | ||
| 518 | |||
| 519 | static struct resource r8a7740_usb_dma_resources[] = { | ||
| 520 | { | ||
| 521 | /* Channel registers and DMAOR */ | ||
| 522 | .start = 0xe68a0020, | ||
| 523 | .end = 0xe68a0064 - 1, | ||
| 524 | .flags = IORESOURCE_MEM, | ||
| 525 | }, | ||
| 526 | { | ||
| 527 | /* VCR/SWR/DMICR */ | ||
| 528 | .start = 0xe68a0000, | ||
| 529 | .end = 0xe68a0014 - 1, | ||
| 530 | .flags = IORESOURCE_MEM, | ||
| 531 | }, | ||
| 532 | { | ||
| 533 | /* IRQ for channels */ | ||
| 534 | .start = evt2irq(0x0a00), | ||
| 535 | .end = evt2irq(0x0a00), | ||
| 536 | .flags = IORESOURCE_IRQ, | ||
| 537 | }, | ||
| 538 | }; | ||
| 539 | |||
| 540 | static struct platform_device usb_dma_device = { | ||
| 541 | .name = "sh-dma-engine", | ||
| 542 | .id = 3, | ||
| 543 | .resource = r8a7740_usb_dma_resources, | ||
| 544 | .num_resources = ARRAY_SIZE(r8a7740_usb_dma_resources), | ||
| 545 | .dev = { | ||
| 546 | .platform_data = &usb_dma_platform_data, | ||
| 547 | }, | ||
| 548 | }; | ||
| 549 | |||
| 279 | /* I2C */ | 550 | /* I2C */ |
| 280 | static struct resource i2c0_resources[] = { | 551 | static struct resource i2c0_resources[] = { |
| 281 | [0] = { | 552 | [0] = { |
| @@ -322,8 +593,30 @@ static struct platform_device i2c1_device = { | |||
| 322 | static struct platform_device *r8a7740_late_devices[] __initdata = { | 593 | static struct platform_device *r8a7740_late_devices[] __initdata = { |
| 323 | &i2c0_device, | 594 | &i2c0_device, |
| 324 | &i2c1_device, | 595 | &i2c1_device, |
| 596 | &dma0_device, | ||
| 597 | &dma1_device, | ||
| 598 | &dma2_device, | ||
| 599 | &usb_dma_device, | ||
| 325 | }; | 600 | }; |
| 326 | 601 | ||
| 602 | /* | ||
| 603 | * r8a7740 chip has lasting errata on MERAM buffer. | ||
| 604 | * this is work-around for it. | ||
| 605 | * see | ||
| 606 | * "Media RAM (MERAM)" on r8a7740 documentation | ||
| 607 | */ | ||
| 608 | #define MEBUFCNTR 0xFE950098 | ||
| 609 | void r8a7740_meram_workaround(void) | ||
| 610 | { | ||
| 611 | void __iomem *reg; | ||
| 612 | |||
| 613 | reg = ioremap_nocache(MEBUFCNTR, 4); | ||
| 614 | if (reg) { | ||
| 615 | iowrite32(0x01600164, reg); | ||
| 616 | iounmap(reg); | ||
| 617 | } | ||
| 618 | } | ||
| 619 | |||
| 327 | #define ICCR 0x0004 | 620 | #define ICCR 0x0004 |
| 328 | #define ICSTART 0x0070 | 621 | #define ICSTART 0x0070 |
| 329 | 622 | ||
| @@ -380,10 +673,31 @@ void __init r8a7740_add_standard_devices(void) | |||
| 380 | r8a7740_i2c_workaround(&i2c0_device); | 673 | r8a7740_i2c_workaround(&i2c0_device); |
| 381 | r8a7740_i2c_workaround(&i2c1_device); | 674 | r8a7740_i2c_workaround(&i2c1_device); |
| 382 | 675 | ||
| 676 | /* PM domain */ | ||
| 677 | rmobile_init_pm_domain(&r8a7740_pd_a4s); | ||
| 678 | rmobile_init_pm_domain(&r8a7740_pd_a3sp); | ||
| 679 | rmobile_init_pm_domain(&r8a7740_pd_a4lc); | ||
| 680 | |||
| 681 | rmobile_pm_add_subdomain(&r8a7740_pd_a4s, &r8a7740_pd_a3sp); | ||
| 682 | |||
| 683 | /* add devices */ | ||
| 383 | platform_add_devices(r8a7740_early_devices, | 684 | platform_add_devices(r8a7740_early_devices, |
| 384 | ARRAY_SIZE(r8a7740_early_devices)); | 685 | ARRAY_SIZE(r8a7740_early_devices)); |
| 385 | platform_add_devices(r8a7740_late_devices, | 686 | platform_add_devices(r8a7740_late_devices, |
| 386 | ARRAY_SIZE(r8a7740_late_devices)); | 687 | ARRAY_SIZE(r8a7740_late_devices)); |
| 688 | |||
| 689 | /* add devices to PM domain */ | ||
| 690 | |||
| 691 | rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif0_device); | ||
| 692 | rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif1_device); | ||
| 693 | rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif2_device); | ||
| 694 | rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif3_device); | ||
| 695 | rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif4_device); | ||
| 696 | rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif5_device); | ||
| 697 | rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif6_device); | ||
| 698 | rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif7_device); | ||
| 699 | rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scifb_device); | ||
| 700 | rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &i2c1_device); | ||
| 387 | } | 701 | } |
| 388 | 702 | ||
| 389 | static void __init r8a7740_earlytimer_init(void) | 703 | static void __init r8a7740_earlytimer_init(void) |
| @@ -403,3 +717,49 @@ void __init r8a7740_add_early_devices(void) | |||
| 403 | /* override timer setup with soc-specific code */ | 717 | /* override timer setup with soc-specific code */ |
| 404 | shmobile_timer.init = r8a7740_earlytimer_init; | 718 | shmobile_timer.init = r8a7740_earlytimer_init; |
| 405 | } | 719 | } |
| 720 | |||
| 721 | #ifdef CONFIG_USE_OF | ||
| 722 | |||
| 723 | void __init r8a7740_add_early_devices_dt(void) | ||
| 724 | { | ||
| 725 | shmobile_setup_delay(800, 1, 3); /* Cortex-A9 @ 800MHz */ | ||
| 726 | |||
| 727 | early_platform_add_devices(r8a7740_early_devices, | ||
| 728 | ARRAY_SIZE(r8a7740_early_devices)); | ||
| 729 | |||
| 730 | /* setup early console here as well */ | ||
| 731 | shmobile_setup_console(); | ||
| 732 | } | ||
| 733 | |||
| 734 | static const struct of_dev_auxdata r8a7740_auxdata_lookup[] __initconst = { | ||
| 735 | { } | ||
| 736 | }; | ||
| 737 | |||
| 738 | void __init r8a7740_add_standard_devices_dt(void) | ||
| 739 | { | ||
| 740 | /* clocks are setup late during boot in the case of DT */ | ||
| 741 | r8a7740_clock_init(0); | ||
| 742 | |||
| 743 | platform_add_devices(r8a7740_early_devices, | ||
| 744 | ARRAY_SIZE(r8a7740_early_devices)); | ||
| 745 | |||
| 746 | of_platform_populate(NULL, of_default_bus_match_table, | ||
| 747 | r8a7740_auxdata_lookup, NULL); | ||
| 748 | } | ||
| 749 | |||
| 750 | static const char *r8a7740_boards_compat_dt[] __initdata = { | ||
| 751 | "renesas,r8a7740", | ||
| 752 | NULL, | ||
| 753 | }; | ||
| 754 | |||
| 755 | DT_MACHINE_START(SH7372_DT, "Generic R8A7740 (Flattened Device Tree)") | ||
| 756 | .map_io = r8a7740_map_io, | ||
| 757 | .init_early = r8a7740_add_early_devices_dt, | ||
| 758 | .init_irq = r8a7740_init_irq, | ||
| 759 | .handle_irq = shmobile_handle_irq_intc, | ||
| 760 | .init_machine = r8a7740_add_standard_devices_dt, | ||
| 761 | .timer = &shmobile_timer, | ||
| 762 | .dt_compat = r8a7740_boards_compat_dt, | ||
| 763 | MACHINE_END | ||
| 764 | |||
| 765 | #endif /* CONFIG_USE_OF */ | ||
diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c index fafce9ce8218..838a87be1d5c 100644 --- a/arch/arm/mach-shmobile/setup-sh7372.c +++ b/arch/arm/mach-shmobile/setup-sh7372.c | |||
| @@ -33,6 +33,7 @@ | |||
| 33 | #include <linux/sh_timer.h> | 33 | #include <linux/sh_timer.h> |
| 34 | #include <linux/pm_domain.h> | 34 | #include <linux/pm_domain.h> |
| 35 | #include <linux/dma-mapping.h> | 35 | #include <linux/dma-mapping.h> |
| 36 | #include <mach/dma-register.h> | ||
| 36 | #include <mach/hardware.h> | 37 | #include <mach/hardware.h> |
| 37 | #include <mach/irqs.h> | 38 | #include <mach/irqs.h> |
| 38 | #include <mach/sh7372.h> | 39 | #include <mach/sh7372.h> |
| @@ -335,151 +336,126 @@ static struct platform_device iic1_device = { | |||
| 335 | }; | 336 | }; |
| 336 | 337 | ||
| 337 | /* DMA */ | 338 | /* DMA */ |
| 338 | /* Transmit sizes and respective CHCR register values */ | ||
| 339 | enum { | ||
| 340 | XMIT_SZ_8BIT = 0, | ||
| 341 | XMIT_SZ_16BIT = 1, | ||
| 342 | XMIT_SZ_32BIT = 2, | ||
| 343 | XMIT_SZ_64BIT = 7, | ||
| 344 | XMIT_SZ_128BIT = 3, | ||
| 345 | XMIT_SZ_256BIT = 4, | ||
| 346 | XMIT_SZ_512BIT = 5, | ||
| 347 | }; | ||
| 348 | |||
| 349 | /* log2(size / 8) - used to calculate number of transfers */ | ||
| 350 | #define TS_SHIFT { \ | ||
| 351 | [XMIT_SZ_8BIT] = 0, \ | ||
| 352 | [XMIT_SZ_16BIT] = 1, \ | ||
| 353 | [XMIT_SZ_32BIT] = 2, \ | ||
| 354 | [XMIT_SZ_64BIT] = 3, \ | ||
| 355 | [XMIT_SZ_128BIT] = 4, \ | ||
| 356 | [XMIT_SZ_256BIT] = 5, \ | ||
| 357 | [XMIT_SZ_512BIT] = 6, \ | ||
| 358 | } | ||
| 359 | |||
| 360 | #define TS_INDEX2VAL(i) ((((i) & 3) << 3) | \ | ||
| 361 | (((i) & 0xc) << (20 - 2))) | ||
| 362 | |||
| 363 | static const struct sh_dmae_slave_config sh7372_dmae_slaves[] = { | 339 | static const struct sh_dmae_slave_config sh7372_dmae_slaves[] = { |
| 364 | { | 340 | { |
| 365 | .slave_id = SHDMA_SLAVE_SCIF0_TX, | 341 | .slave_id = SHDMA_SLAVE_SCIF0_TX, |
| 366 | .addr = 0xe6c40020, | 342 | .addr = 0xe6c40020, |
| 367 | .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), | 343 | .chcr = CHCR_TX(XMIT_SZ_8BIT), |
| 368 | .mid_rid = 0x21, | 344 | .mid_rid = 0x21, |
| 369 | }, { | 345 | }, { |
| 370 | .slave_id = SHDMA_SLAVE_SCIF0_RX, | 346 | .slave_id = SHDMA_SLAVE_SCIF0_RX, |
| 371 | .addr = 0xe6c40024, | 347 | .addr = 0xe6c40024, |
| 372 | .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), | 348 | .chcr = CHCR_RX(XMIT_SZ_8BIT), |
| 373 | .mid_rid = 0x22, | 349 | .mid_rid = 0x22, |
| 374 | }, { | 350 | }, { |
| 375 | .slave_id = SHDMA_SLAVE_SCIF1_TX, | 351 | .slave_id = SHDMA_SLAVE_SCIF1_TX, |
| 376 | .addr = 0xe6c50020, | 352 | .addr = 0xe6c50020, |
| 377 | .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), | 353 | .chcr = CHCR_TX(XMIT_SZ_8BIT), |
| 378 | .mid_rid = 0x25, | 354 | .mid_rid = 0x25, |
| 379 | }, { | 355 | }, { |
| 380 | .slave_id = SHDMA_SLAVE_SCIF1_RX, | 356 | .slave_id = SHDMA_SLAVE_SCIF1_RX, |
| 381 | .addr = 0xe6c50024, | 357 | .addr = 0xe6c50024, |
| 382 | .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), | 358 | .chcr = CHCR_RX(XMIT_SZ_8BIT), |
| 383 | .mid_rid = 0x26, | 359 | .mid_rid = 0x26, |
| 384 | }, { | 360 | }, { |
| 385 | .slave_id = SHDMA_SLAVE_SCIF2_TX, | 361 | .slave_id = SHDMA_SLAVE_SCIF2_TX, |
| 386 | .addr = 0xe6c60020, | 362 | .addr = 0xe6c60020, |
| 387 | .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), | 363 | .chcr = CHCR_TX(XMIT_SZ_8BIT), |
| 388 | .mid_rid = 0x29, | 364 | .mid_rid = 0x29, |
| 389 | }, { | 365 | }, { |
| 390 | .slave_id = SHDMA_SLAVE_SCIF2_RX, | 366 | .slave_id = SHDMA_SLAVE_SCIF2_RX, |
| 391 | .addr = 0xe6c60024, | 367 | .addr = 0xe6c60024, |
| 392 | .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), | 368 | .chcr = CHCR_RX(XMIT_SZ_8BIT), |
| 393 | .mid_rid = 0x2a, | 369 | .mid_rid = 0x2a, |
| 394 | }, { | 370 | }, { |
| 395 | .slave_id = SHDMA_SLAVE_SCIF3_TX, | 371 | .slave_id = SHDMA_SLAVE_SCIF3_TX, |
| 396 | .addr = 0xe6c70020, | 372 | .addr = 0xe6c70020, |
| 397 | .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), | 373 | .chcr = CHCR_TX(XMIT_SZ_8BIT), |
| 398 | .mid_rid = 0x2d, | 374 | .mid_rid = 0x2d, |
| 399 | }, { | 375 | }, { |
| 400 | .slave_id = SHDMA_SLAVE_SCIF3_RX, | 376 | .slave_id = SHDMA_SLAVE_SCIF3_RX, |
| 401 | .addr = 0xe6c70024, | 377 | .addr = 0xe6c70024, |
| 402 | .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), | 378 | .chcr = CHCR_RX(XMIT_SZ_8BIT), |
| 403 | .mid_rid = 0x2e, | 379 | .mid_rid = 0x2e, |
| 404 | }, { | 380 | }, { |
| 405 | .slave_id = SHDMA_SLAVE_SCIF4_TX, | 381 | .slave_id = SHDMA_SLAVE_SCIF4_TX, |
| 406 | .addr = 0xe6c80020, | 382 | .addr = 0xe6c80020, |
| 407 | .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), | 383 | .chcr = CHCR_TX(XMIT_SZ_8BIT), |
| 408 | .mid_rid = 0x39, | 384 | .mid_rid = 0x39, |
| 409 | }, { | 385 | }, { |
| 410 | .slave_id = SHDMA_SLAVE_SCIF4_RX, | 386 | .slave_id = SHDMA_SLAVE_SCIF4_RX, |
| 411 | .addr = 0xe6c80024, | 387 | .addr = 0xe6c80024, |
| 412 | .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), | 388 | .chcr = CHCR_RX(XMIT_SZ_8BIT), |
| 413 | .mid_rid = 0x3a, | 389 | .mid_rid = 0x3a, |
| 414 | }, { | 390 | }, { |
| 415 | .slave_id = SHDMA_SLAVE_SCIF5_TX, | 391 | .slave_id = SHDMA_SLAVE_SCIF5_TX, |
| 416 | .addr = 0xe6cb0020, | 392 | .addr = 0xe6cb0020, |
| 417 | .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), | 393 | .chcr = CHCR_TX(XMIT_SZ_8BIT), |
| 418 | .mid_rid = 0x35, | 394 | .mid_rid = 0x35, |
| 419 | }, { | 395 | }, { |
| 420 | .slave_id = SHDMA_SLAVE_SCIF5_RX, | 396 | .slave_id = SHDMA_SLAVE_SCIF5_RX, |
| 421 | .addr = 0xe6cb0024, | 397 | .addr = 0xe6cb0024, |
| 422 | .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), | 398 | .chcr = CHCR_RX(XMIT_SZ_8BIT), |
| 423 | .mid_rid = 0x36, | 399 | .mid_rid = 0x36, |
| 424 | }, { | 400 | }, { |
| 425 | .slave_id = SHDMA_SLAVE_SCIF6_TX, | 401 | .slave_id = SHDMA_SLAVE_SCIF6_TX, |
| 426 | .addr = 0xe6c30040, | 402 | .addr = 0xe6c30040, |
| 427 | .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), | 403 | .chcr = CHCR_TX(XMIT_SZ_8BIT), |
| 428 | .mid_rid = 0x3d, | 404 | .mid_rid = 0x3d, |
| 429 | }, { | 405 | }, { |
| 430 | .slave_id = SHDMA_SLAVE_SCIF6_RX, | 406 | .slave_id = SHDMA_SLAVE_SCIF6_RX, |
| 431 | .addr = 0xe6c30060, | 407 | .addr = 0xe6c30060, |
| 432 | .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), | 408 | .chcr = CHCR_RX(XMIT_SZ_8BIT), |
| 433 | .mid_rid = 0x3e, | 409 | .mid_rid = 0x3e, |
| 434 | }, { | 410 | }, { |
| 435 | .slave_id = SHDMA_SLAVE_SDHI0_TX, | 411 | .slave_id = SHDMA_SLAVE_SDHI0_TX, |
| 436 | .addr = 0xe6850030, | 412 | .addr = 0xe6850030, |
| 437 | .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT), | 413 | .chcr = CHCR_TX(XMIT_SZ_16BIT), |
| 438 | .mid_rid = 0xc1, | 414 | .mid_rid = 0xc1, |
| 439 | }, { | 415 | }, { |
| 440 | .slave_id = SHDMA_SLAVE_SDHI0_RX, | 416 | .slave_id = SHDMA_SLAVE_SDHI0_RX, |
| 441 | .addr = 0xe6850030, | 417 | .addr = 0xe6850030, |
| 442 | .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT), | 418 | .chcr = CHCR_RX(XMIT_SZ_16BIT), |
| 443 | .mid_rid = 0xc2, | 419 | .mid_rid = 0xc2, |
| 444 | }, { | 420 | }, { |
| 445 | .slave_id = SHDMA_SLAVE_SDHI1_TX, | 421 | .slave_id = SHDMA_SLAVE_SDHI1_TX, |
| 446 | .addr = 0xe6860030, | 422 | .addr = 0xe6860030, |
| 447 | .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT), | 423 | .chcr = CHCR_TX(XMIT_SZ_16BIT), |
| 448 | .mid_rid = 0xc9, | 424 | .mid_rid = 0xc9, |
| 449 | }, { | 425 | }, { |
| 450 | .slave_id = SHDMA_SLAVE_SDHI1_RX, | 426 | .slave_id = SHDMA_SLAVE_SDHI1_RX, |
| 451 | .addr = 0xe6860030, | 427 | .addr = 0xe6860030, |
| 452 | .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT), | 428 | .chcr = CHCR_RX(XMIT_SZ_16BIT), |
| 453 | .mid_rid = 0xca, | 429 | .mid_rid = 0xca, |
| 454 | }, { | 430 | }, { |
| 455 | .slave_id = SHDMA_SLAVE_SDHI2_TX, | 431 | .slave_id = SHDMA_SLAVE_SDHI2_TX, |
| 456 | .addr = 0xe6870030, | 432 | .addr = 0xe6870030, |
| 457 | .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT), | 433 | .chcr = CHCR_TX(XMIT_SZ_16BIT), |
| 458 | .mid_rid = 0xcd, | 434 | .mid_rid = 0xcd, |
| 459 | }, { | 435 | }, { |
| 460 | .slave_id = SHDMA_SLAVE_SDHI2_RX, | 436 | .slave_id = SHDMA_SLAVE_SDHI2_RX, |
| 461 | .addr = 0xe6870030, | 437 | .addr = 0xe6870030, |
| 462 | .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT), | 438 | .chcr = CHCR_RX(XMIT_SZ_16BIT), |
| 463 | .mid_rid = 0xce, | 439 | .mid_rid = 0xce, |
| 464 | }, { | 440 | }, { |
| 465 | .slave_id = SHDMA_SLAVE_FSIA_TX, | 441 | .slave_id = SHDMA_SLAVE_FSIA_TX, |
| 466 | .addr = 0xfe1f0024, | 442 | .addr = 0xfe1f0024, |
| 467 | .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT), | 443 | .chcr = CHCR_TX(XMIT_SZ_32BIT), |
| 468 | .mid_rid = 0xb1, | 444 | .mid_rid = 0xb1, |
| 469 | }, { | 445 | }, { |
| 470 | .slave_id = SHDMA_SLAVE_FSIA_RX, | 446 | .slave_id = SHDMA_SLAVE_FSIA_RX, |
| 471 | .addr = 0xfe1f0020, | 447 | .addr = 0xfe1f0020, |
| 472 | .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT), | 448 | .chcr = CHCR_RX(XMIT_SZ_32BIT), |
| 473 | .mid_rid = 0xb2, | 449 | .mid_rid = 0xb2, |
| 474 | }, { | 450 | }, { |
| 475 | .slave_id = SHDMA_SLAVE_MMCIF_TX, | 451 | .slave_id = SHDMA_SLAVE_MMCIF_TX, |
| 476 | .addr = 0xe6bd0034, | 452 | .addr = 0xe6bd0034, |
| 477 | .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT), | 453 | .chcr = CHCR_TX(XMIT_SZ_32BIT), |
| 478 | .mid_rid = 0xd1, | 454 | .mid_rid = 0xd1, |
| 479 | }, { | 455 | }, { |
| 480 | .slave_id = SHDMA_SLAVE_MMCIF_RX, | 456 | .slave_id = SHDMA_SLAVE_MMCIF_RX, |
| 481 | .addr = 0xe6bd0034, | 457 | .addr = 0xe6bd0034, |
| 482 | .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT), | 458 | .chcr = CHCR_RX(XMIT_SZ_32BIT), |
| 483 | .mid_rid = 0xd2, | 459 | .mid_rid = 0xd2, |
| 484 | }, | 460 | }, |
| 485 | }; | 461 | }; |
| @@ -520,19 +496,17 @@ static const struct sh_dmae_channel sh7372_dmae_channels[] = { | |||
| 520 | } | 496 | } |
| 521 | }; | 497 | }; |
| 522 | 498 | ||
| 523 | static const unsigned int ts_shift[] = TS_SHIFT; | ||
| 524 | |||
| 525 | static struct sh_dmae_pdata dma_platform_data = { | 499 | static struct sh_dmae_pdata dma_platform_data = { |
| 526 | .slave = sh7372_dmae_slaves, | 500 | .slave = sh7372_dmae_slaves, |
| 527 | .slave_num = ARRAY_SIZE(sh7372_dmae_slaves), | 501 | .slave_num = ARRAY_SIZE(sh7372_dmae_slaves), |
| 528 | .channel = sh7372_dmae_channels, | 502 | .channel = sh7372_dmae_channels, |
| 529 | .channel_num = ARRAY_SIZE(sh7372_dmae_channels), | 503 | .channel_num = ARRAY_SIZE(sh7372_dmae_channels), |
| 530 | .ts_low_shift = 3, | 504 | .ts_low_shift = TS_LOW_SHIFT, |
| 531 | .ts_low_mask = 0x18, | 505 | .ts_low_mask = TS_LOW_BIT << TS_LOW_SHIFT, |
| 532 | .ts_high_shift = (20 - 2), /* 2 bits for shifted low TS */ | 506 | .ts_high_shift = TS_HI_SHIFT, |
| 533 | .ts_high_mask = 0x00300000, | 507 | .ts_high_mask = TS_HI_BIT << TS_HI_SHIFT, |
| 534 | .ts_shift = ts_shift, | 508 | .ts_shift = dma_ts_shift, |
| 535 | .ts_shift_num = ARRAY_SIZE(ts_shift), | 509 | .ts_shift_num = ARRAY_SIZE(dma_ts_shift), |
| 536 | .dmaor_init = DMAOR_DME, | 510 | .dmaor_init = DMAOR_DME, |
| 537 | .chclr_present = 1, | 511 | .chclr_present = 1, |
| 538 | }; | 512 | }; |
| @@ -654,17 +628,6 @@ static struct platform_device dma2_device = { | |||
| 654 | /* | 628 | /* |
| 655 | * USB-DMAC | 629 | * USB-DMAC |
| 656 | */ | 630 | */ |
| 657 | |||
| 658 | unsigned int usbts_shift[] = {3, 4, 5}; | ||
| 659 | |||
| 660 | enum { | ||
| 661 | XMIT_SZ_8BYTE = 0, | ||
| 662 | XMIT_SZ_16BYTE = 1, | ||
| 663 | XMIT_SZ_32BYTE = 2, | ||
| 664 | }; | ||
| 665 | |||
| 666 | #define USBTS_INDEX2VAL(i) (((i) & 3) << 6) | ||
| 667 | |||
| 668 | static const struct sh_dmae_channel sh7372_usb_dmae_channels[] = { | 631 | static const struct sh_dmae_channel sh7372_usb_dmae_channels[] = { |
| 669 | { | 632 | { |
| 670 | .offset = 0, | 633 | .offset = 0, |
| @@ -677,10 +640,10 @@ static const struct sh_dmae_channel sh7372_usb_dmae_channels[] = { | |||
| 677 | static const struct sh_dmae_slave_config sh7372_usb_dmae0_slaves[] = { | 640 | static const struct sh_dmae_slave_config sh7372_usb_dmae0_slaves[] = { |
| 678 | { | 641 | { |
| 679 | .slave_id = SHDMA_SLAVE_USB0_TX, | 642 | .slave_id = SHDMA_SLAVE_USB0_TX, |
| 680 | .chcr = USBTS_INDEX2VAL(XMIT_SZ_8BYTE), | 643 | .chcr = USBTS_INDEX2VAL(USBTS_XMIT_SZ_8BYTE), |
| 681 | }, { | 644 | }, { |
| 682 | .slave_id = SHDMA_SLAVE_USB0_RX, | 645 | .slave_id = SHDMA_SLAVE_USB0_RX, |
| 683 | .chcr = USBTS_INDEX2VAL(XMIT_SZ_8BYTE), | 646 | .chcr = USBTS_INDEX2VAL(USBTS_XMIT_SZ_8BYTE), |
| 684 | }, | 647 | }, |
| 685 | }; | 648 | }; |
| 686 | 649 | ||
| @@ -689,12 +652,12 @@ static struct sh_dmae_pdata usb_dma0_platform_data = { | |||
| 689 | .slave_num = ARRAY_SIZE(sh7372_usb_dmae0_slaves), | 652 | .slave_num = ARRAY_SIZE(sh7372_usb_dmae0_slaves), |
| 690 | .channel = sh7372_usb_dmae_channels, | 653 | .channel = sh7372_usb_dmae_channels, |
| 691 | .channel_num = ARRAY_SIZE(sh7372_usb_dmae_channels), | 654 | .channel_num = ARRAY_SIZE(sh7372_usb_dmae_channels), |
| 692 | .ts_low_shift = 6, | 655 | .ts_low_shift = USBTS_LOW_SHIFT, |
| 693 | .ts_low_mask = 0xc0, | 656 | .ts_low_mask = USBTS_LOW_BIT << USBTS_LOW_SHIFT, |
| 694 | .ts_high_shift = 0, | 657 | .ts_high_shift = USBTS_HI_SHIFT, |
| 695 | .ts_high_mask = 0, | 658 | .ts_high_mask = USBTS_HI_BIT << USBTS_HI_SHIFT, |
| 696 | .ts_shift = usbts_shift, | 659 | .ts_shift = dma_usbts_shift, |
| 697 | .ts_shift_num = ARRAY_SIZE(usbts_shift), | 660 | .ts_shift_num = ARRAY_SIZE(dma_usbts_shift), |
| 698 | .dmaor_init = DMAOR_DME, | 661 | .dmaor_init = DMAOR_DME, |
| 699 | .chcr_offset = 0x14, | 662 | .chcr_offset = 0x14, |
| 700 | .chcr_ie_bit = 1 << 5, | 663 | .chcr_ie_bit = 1 << 5, |
| @@ -739,10 +702,10 @@ static struct platform_device usb_dma0_device = { | |||
| 739 | static const struct sh_dmae_slave_config sh7372_usb_dmae1_slaves[] = { | 702 | static const struct sh_dmae_slave_config sh7372_usb_dmae1_slaves[] = { |
| 740 | { | 703 | { |
| 741 | .slave_id = SHDMA_SLAVE_USB1_TX, | 704 | .slave_id = SHDMA_SLAVE_USB1_TX, |
| 742 | .chcr = USBTS_INDEX2VAL(XMIT_SZ_8BYTE), | 705 | .chcr = USBTS_INDEX2VAL(USBTS_XMIT_SZ_8BYTE), |
| 743 | }, { | 706 | }, { |
| 744 | .slave_id = SHDMA_SLAVE_USB1_RX, | 707 | .slave_id = SHDMA_SLAVE_USB1_RX, |
| 745 | .chcr = USBTS_INDEX2VAL(XMIT_SZ_8BYTE), | 708 | .chcr = USBTS_INDEX2VAL(USBTS_XMIT_SZ_8BYTE), |
| 746 | }, | 709 | }, |
| 747 | }; | 710 | }; |
| 748 | 711 | ||
| @@ -751,12 +714,12 @@ static struct sh_dmae_pdata usb_dma1_platform_data = { | |||
| 751 | .slave_num = ARRAY_SIZE(sh7372_usb_dmae1_slaves), | 714 | .slave_num = ARRAY_SIZE(sh7372_usb_dmae1_slaves), |
| 752 | .channel = sh7372_usb_dmae_channels, | 715 | .channel = sh7372_usb_dmae_channels, |
| 753 | .channel_num = ARRAY_SIZE(sh7372_usb_dmae_channels), | 716 | .channel_num = ARRAY_SIZE(sh7372_usb_dmae_channels), |
| 754 | .ts_low_shift = 6, | 717 | .ts_low_shift = USBTS_LOW_SHIFT, |
| 755 | .ts_low_mask = 0xc0, | 718 | .ts_low_mask = USBTS_LOW_BIT << USBTS_LOW_SHIFT, |
| 756 | .ts_high_shift = 0, | 719 | .ts_high_shift = USBTS_HI_SHIFT, |
| 757 | .ts_high_mask = 0, | 720 | .ts_high_mask = USBTS_HI_BIT << USBTS_HI_SHIFT, |
| 758 | .ts_shift = usbts_shift, | 721 | .ts_shift = dma_usbts_shift, |
| 759 | .ts_shift_num = ARRAY_SIZE(usbts_shift), | 722 | .ts_shift_num = ARRAY_SIZE(dma_usbts_shift), |
| 760 | .dmaor_init = DMAOR_DME, | 723 | .dmaor_init = DMAOR_DME, |
| 761 | .chcr_offset = 0x14, | 724 | .chcr_offset = 0x14, |
| 762 | .chcr_ie_bit = 1 << 5, | 725 | .chcr_ie_bit = 1 << 5, |
| @@ -1038,21 +1001,21 @@ static struct platform_device *sh7372_late_devices[] __initdata = { | |||
| 1038 | 1001 | ||
| 1039 | void __init sh7372_add_standard_devices(void) | 1002 | void __init sh7372_add_standard_devices(void) |
| 1040 | { | 1003 | { |
| 1041 | sh7372_init_pm_domain(&sh7372_a4lc); | 1004 | rmobile_init_pm_domain(&sh7372_pd_a4lc); |
| 1042 | sh7372_init_pm_domain(&sh7372_a4mp); | 1005 | rmobile_init_pm_domain(&sh7372_pd_a4mp); |
| 1043 | sh7372_init_pm_domain(&sh7372_d4); | 1006 | rmobile_init_pm_domain(&sh7372_pd_d4); |
| 1044 | sh7372_init_pm_domain(&sh7372_a4r); | 1007 | rmobile_init_pm_domain(&sh7372_pd_a4r); |
| 1045 | sh7372_init_pm_domain(&sh7372_a3rv); | 1008 | rmobile_init_pm_domain(&sh7372_pd_a3rv); |
| 1046 | sh7372_init_pm_domain(&sh7372_a3ri); | 1009 | rmobile_init_pm_domain(&sh7372_pd_a3ri); |
| 1047 | sh7372_init_pm_domain(&sh7372_a4s); | 1010 | rmobile_init_pm_domain(&sh7372_pd_a4s); |
| 1048 | sh7372_init_pm_domain(&sh7372_a3sp); | 1011 | rmobile_init_pm_domain(&sh7372_pd_a3sp); |
| 1049 | sh7372_init_pm_domain(&sh7372_a3sg); | 1012 | rmobile_init_pm_domain(&sh7372_pd_a3sg); |
| 1050 | 1013 | ||
| 1051 | sh7372_pm_add_subdomain(&sh7372_a4lc, &sh7372_a3rv); | 1014 | rmobile_pm_add_subdomain(&sh7372_pd_a4lc, &sh7372_pd_a3rv); |
| 1052 | sh7372_pm_add_subdomain(&sh7372_a4r, &sh7372_a4lc); | 1015 | rmobile_pm_add_subdomain(&sh7372_pd_a4r, &sh7372_pd_a4lc); |
| 1053 | 1016 | ||
| 1054 | sh7372_pm_add_subdomain(&sh7372_a4s, &sh7372_a3sg); | 1017 | rmobile_pm_add_subdomain(&sh7372_pd_a4s, &sh7372_pd_a3sg); |
| 1055 | sh7372_pm_add_subdomain(&sh7372_a4s, &sh7372_a3sp); | 1018 | rmobile_pm_add_subdomain(&sh7372_pd_a4s, &sh7372_pd_a3sp); |
| 1056 | 1019 | ||
| 1057 | platform_add_devices(sh7372_early_devices, | 1020 | platform_add_devices(sh7372_early_devices, |
| 1058 | ARRAY_SIZE(sh7372_early_devices)); | 1021 | ARRAY_SIZE(sh7372_early_devices)); |
| @@ -1060,30 +1023,30 @@ void __init sh7372_add_standard_devices(void) | |||
| 1060 | platform_add_devices(sh7372_late_devices, | 1023 | platform_add_devices(sh7372_late_devices, |
| 1061 | ARRAY_SIZE(sh7372_late_devices)); | 1024 | ARRAY_SIZE(sh7372_late_devices)); |
| 1062 | 1025 | ||
| 1063 | sh7372_add_device_to_domain(&sh7372_a3rv, &vpu_device); | 1026 | rmobile_add_device_to_domain(&sh7372_pd_a3rv, &vpu_device); |
| 1064 | sh7372_add_device_to_domain(&sh7372_a4mp, &spu0_device); | 1027 | rmobile_add_device_to_domain(&sh7372_pd_a4mp, &spu0_device); |
| 1065 | sh7372_add_device_to_domain(&sh7372_a4mp, &spu1_device); | 1028 | rmobile_add_device_to_domain(&sh7372_pd_a4mp, &spu1_device); |
| 1066 | sh7372_add_device_to_domain(&sh7372_a3sp, &scif0_device); | 1029 | rmobile_add_device_to_domain(&sh7372_pd_a3sp, &scif0_device); |
| 1067 | sh7372_add_device_to_domain(&sh7372_a3sp, &scif1_device); | 1030 | rmobile_add_device_to_domain(&sh7372_pd_a3sp, &scif1_device); |
| 1068 | sh7372_add_device_to_domain(&sh7372_a3sp, &scif2_device); | 1031 | rmobile_add_device_to_domain(&sh7372_pd_a3sp, &scif2_device); |
| 1069 | sh7372_add_device_to_domain(&sh7372_a3sp, &scif3_device); | 1032 | rmobile_add_device_to_domain(&sh7372_pd_a3sp, &scif3_device); |
| 1070 | sh7372_add_device_to_domain(&sh7372_a3sp, &scif4_device); | 1033 | rmobile_add_device_to_domain(&sh7372_pd_a3sp, &scif4_device); |
| 1071 | sh7372_add_device_to_domain(&sh7372_a3sp, &scif5_device); | 1034 | rmobile_add_device_to_domain(&sh7372_pd_a3sp, &scif5_device); |
| 1072 | sh7372_add_device_to_domain(&sh7372_a3sp, &scif6_device); | 1035 | rmobile_add_device_to_domain(&sh7372_pd_a3sp, &scif6_device); |
| 1073 | sh7372_add_device_to_domain(&sh7372_a3sp, &iic1_device); | 1036 | rmobile_add_device_to_domain(&sh7372_pd_a3sp, &iic1_device); |
| 1074 | sh7372_add_device_to_domain(&sh7372_a3sp, &dma0_device); | 1037 | rmobile_add_device_to_domain(&sh7372_pd_a3sp, &dma0_device); |
| 1075 | sh7372_add_device_to_domain(&sh7372_a3sp, &dma1_device); | 1038 | rmobile_add_device_to_domain(&sh7372_pd_a3sp, &dma1_device); |
| 1076 | sh7372_add_device_to_domain(&sh7372_a3sp, &dma2_device); | 1039 | rmobile_add_device_to_domain(&sh7372_pd_a3sp, &dma2_device); |
| 1077 | sh7372_add_device_to_domain(&sh7372_a3sp, &usb_dma0_device); | 1040 | rmobile_add_device_to_domain(&sh7372_pd_a3sp, &usb_dma0_device); |
| 1078 | sh7372_add_device_to_domain(&sh7372_a3sp, &usb_dma1_device); | 1041 | rmobile_add_device_to_domain(&sh7372_pd_a3sp, &usb_dma1_device); |
| 1079 | sh7372_add_device_to_domain(&sh7372_a4r, &iic0_device); | 1042 | rmobile_add_device_to_domain(&sh7372_pd_a4r, &iic0_device); |
| 1080 | sh7372_add_device_to_domain(&sh7372_a4r, &veu0_device); | 1043 | rmobile_add_device_to_domain(&sh7372_pd_a4r, &veu0_device); |
| 1081 | sh7372_add_device_to_domain(&sh7372_a4r, &veu1_device); | 1044 | rmobile_add_device_to_domain(&sh7372_pd_a4r, &veu1_device); |
| 1082 | sh7372_add_device_to_domain(&sh7372_a4r, &veu2_device); | 1045 | rmobile_add_device_to_domain(&sh7372_pd_a4r, &veu2_device); |
| 1083 | sh7372_add_device_to_domain(&sh7372_a4r, &veu3_device); | 1046 | rmobile_add_device_to_domain(&sh7372_pd_a4r, &veu3_device); |
| 1084 | sh7372_add_device_to_domain(&sh7372_a4r, &jpu_device); | 1047 | rmobile_add_device_to_domain(&sh7372_pd_a4r, &jpu_device); |
| 1085 | sh7372_add_device_to_domain(&sh7372_a4r, &tmu00_device); | 1048 | rmobile_add_device_to_domain(&sh7372_pd_a4r, &tmu00_device); |
| 1086 | sh7372_add_device_to_domain(&sh7372_a4r, &tmu01_device); | 1049 | rmobile_add_device_to_domain(&sh7372_pd_a4r, &tmu01_device); |
| 1087 | } | 1050 | } |
| 1088 | 1051 | ||
| 1089 | static void __init sh7372_earlytimer_init(void) | 1052 | static void __init sh7372_earlytimer_init(void) |
diff --git a/arch/arm/mach-shmobile/setup-sh7377.c b/arch/arm/mach-shmobile/setup-sh7377.c index d576a6abbade..855b1506caf8 100644 --- a/arch/arm/mach-shmobile/setup-sh7377.c +++ b/arch/arm/mach-shmobile/setup-sh7377.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #include <linux/interrupt.h> | 22 | #include <linux/interrupt.h> |
| 23 | #include <linux/irq.h> | 23 | #include <linux/irq.h> |
| 24 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
| 25 | #include <linux/of_platform.h> | ||
| 25 | #include <linux/uio_driver.h> | 26 | #include <linux/uio_driver.h> |
| 26 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
| 27 | #include <linux/input.h> | 28 | #include <linux/input.h> |
| @@ -500,3 +501,49 @@ void __init sh7377_add_early_devices(void) | |||
| 500 | /* override timer setup with soc-specific code */ | 501 | /* override timer setup with soc-specific code */ |
| 501 | shmobile_timer.init = sh7377_earlytimer_init; | 502 | shmobile_timer.init = sh7377_earlytimer_init; |
| 502 | } | 503 | } |
| 504 | |||
| 505 | #ifdef CONFIG_USE_OF | ||
| 506 | |||
| 507 | void __init sh7377_add_early_devices_dt(void) | ||
| 508 | { | ||
| 509 | shmobile_setup_delay(600, 1, 3); /* Cortex-A8 @ 600MHz */ | ||
| 510 | |||
| 511 | early_platform_add_devices(sh7377_early_devices, | ||
| 512 | ARRAY_SIZE(sh7377_early_devices)); | ||
| 513 | |||
| 514 | /* setup early console here as well */ | ||
| 515 | shmobile_setup_console(); | ||
| 516 | } | ||
| 517 | |||
| 518 | static const struct of_dev_auxdata sh7377_auxdata_lookup[] __initconst = { | ||
| 519 | { } | ||
| 520 | }; | ||
| 521 | |||
| 522 | void __init sh7377_add_standard_devices_dt(void) | ||
| 523 | { | ||
| 524 | /* clocks are setup late during boot in the case of DT */ | ||
| 525 | sh7377_clock_init(); | ||
| 526 | |||
| 527 | platform_add_devices(sh7377_early_devices, | ||
| 528 | ARRAY_SIZE(sh7377_early_devices)); | ||
| 529 | |||
| 530 | of_platform_populate(NULL, of_default_bus_match_table, | ||
| 531 | sh7377_auxdata_lookup, NULL); | ||
| 532 | } | ||
| 533 | |||
| 534 | static const char *sh7377_boards_compat_dt[] __initdata = { | ||
| 535 | "renesas,sh7377", | ||
| 536 | NULL, | ||
| 537 | }; | ||
| 538 | |||
| 539 | DT_MACHINE_START(SH7377_DT, "Generic SH7377 (Flattened Device Tree)") | ||
| 540 | .map_io = sh7377_map_io, | ||
| 541 | .init_early = sh7377_add_early_devices_dt, | ||
| 542 | .init_irq = sh7377_init_irq, | ||
| 543 | .handle_irq = shmobile_handle_irq_intc, | ||
| 544 | .init_machine = sh7377_add_standard_devices_dt, | ||
| 545 | .timer = &shmobile_timer, | ||
| 546 | .dt_compat = sh7377_boards_compat_dt, | ||
| 547 | MACHINE_END | ||
| 548 | |||
| 549 | #endif /* CONFIG_USE_OF */ | ||
diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c index 04a0dfe75493..d230af656fc9 100644 --- a/arch/arm/mach-shmobile/setup-sh73a0.c +++ b/arch/arm/mach-shmobile/setup-sh73a0.c | |||
| @@ -30,6 +30,7 @@ | |||
| 30 | #include <linux/sh_dma.h> | 30 | #include <linux/sh_dma.h> |
| 31 | #include <linux/sh_intc.h> | 31 | #include <linux/sh_intc.h> |
| 32 | #include <linux/sh_timer.h> | 32 | #include <linux/sh_timer.h> |
| 33 | #include <mach/dma-register.h> | ||
| 33 | #include <mach/hardware.h> | 34 | #include <mach/hardware.h> |
| 34 | #include <mach/irqs.h> | 35 | #include <mach/irqs.h> |
| 35 | #include <mach/sh73a0.h> | 36 | #include <mach/sh73a0.h> |
| @@ -415,32 +416,6 @@ static struct platform_device i2c4_device = { | |||
| 415 | .num_resources = ARRAY_SIZE(i2c4_resources), | 416 | .num_resources = ARRAY_SIZE(i2c4_resources), |
| 416 | }; | 417 | }; |
| 417 | 418 | ||
| 418 | /* Transmit sizes and respective CHCR register values */ | ||
| 419 | enum { | ||
| 420 | XMIT_SZ_8BIT = 0, | ||
| 421 | XMIT_SZ_16BIT = 1, | ||
| 422 | XMIT_SZ_32BIT = 2, | ||
| 423 | XMIT_SZ_64BIT = 7, | ||
| 424 | XMIT_SZ_128BIT = 3, | ||
| 425 | XMIT_SZ_256BIT = 4, | ||
| 426 | XMIT_SZ_512BIT = 5, | ||
| 427 | }; | ||
| 428 | |||
| 429 | /* log2(size / 8) - used to calculate number of transfers */ | ||
| 430 | #define TS_SHIFT { \ | ||
| 431 | [XMIT_SZ_8BIT] = 0, \ | ||
| 432 | [XMIT_SZ_16BIT] = 1, \ | ||
| 433 | [XMIT_SZ_32BIT] = 2, \ | ||
| 434 | [XMIT_SZ_64BIT] = 3, \ | ||
| 435 | [XMIT_SZ_128BIT] = 4, \ | ||
| 436 | [XMIT_SZ_256BIT] = 5, \ | ||
| 437 | [XMIT_SZ_512BIT] = 6, \ | ||
| 438 | } | ||
| 439 | |||
| 440 | #define TS_INDEX2VAL(i) ((((i) & 3) << 3) | (((i) & 0xc) << (20 - 2))) | ||
| 441 | #define CHCR_TX(xmit_sz) (DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL((xmit_sz))) | ||
| 442 | #define CHCR_RX(xmit_sz) (DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL((xmit_sz))) | ||
| 443 | |||
| 444 | static const struct sh_dmae_slave_config sh73a0_dmae_slaves[] = { | 419 | static const struct sh_dmae_slave_config sh73a0_dmae_slaves[] = { |
| 445 | { | 420 | { |
| 446 | .slave_id = SHDMA_SLAVE_SCIF0_TX, | 421 | .slave_id = SHDMA_SLAVE_SCIF0_TX, |
| @@ -604,19 +579,17 @@ static const struct sh_dmae_channel sh73a0_dmae_channels[] = { | |||
| 604 | DMAE_CHANNEL(0x8980), | 579 | DMAE_CHANNEL(0x8980), |
| 605 | }; | 580 | }; |
| 606 | 581 | ||
| 607 | static const unsigned int ts_shift[] = TS_SHIFT; | ||
| 608 | |||
| 609 | static struct sh_dmae_pdata sh73a0_dmae_platform_data = { | 582 | static struct sh_dmae_pdata sh73a0_dmae_platform_data = { |
| 610 | .slave = sh73a0_dmae_slaves, | 583 | .slave = sh73a0_dmae_slaves, |
| 611 | .slave_num = ARRAY_SIZE(sh73a0_dmae_slaves), | 584 | .slave_num = ARRAY_SIZE(sh73a0_dmae_slaves), |
| 612 | .channel = sh73a0_dmae_channels, | 585 | .channel = sh73a0_dmae_channels, |
| 613 | .channel_num = ARRAY_SIZE(sh73a0_dmae_channels), | 586 | .channel_num = ARRAY_SIZE(sh73a0_dmae_channels), |
| 614 | .ts_low_shift = 3, | 587 | .ts_low_shift = TS_LOW_SHIFT, |
| 615 | .ts_low_mask = 0x18, | 588 | .ts_low_mask = TS_LOW_BIT << TS_LOW_SHIFT, |
| 616 | .ts_high_shift = (20 - 2), /* 2 bits for shifted low TS */ | 589 | .ts_high_shift = TS_HI_SHIFT, |
| 617 | .ts_high_mask = 0x00300000, | 590 | .ts_high_mask = TS_HI_BIT << TS_HI_SHIFT, |
| 618 | .ts_shift = ts_shift, | 591 | .ts_shift = dma_ts_shift, |
| 619 | .ts_shift_num = ARRAY_SIZE(ts_shift), | 592 | .ts_shift_num = ARRAY_SIZE(dma_ts_shift), |
| 620 | .dmaor_init = DMAOR_DME, | 593 | .dmaor_init = DMAOR_DME, |
| 621 | }; | 594 | }; |
| 622 | 595 | ||
| @@ -651,6 +624,116 @@ static struct platform_device dma0_device = { | |||
| 651 | }, | 624 | }, |
| 652 | }; | 625 | }; |
| 653 | 626 | ||
| 627 | /* MPDMAC */ | ||
| 628 | static const struct sh_dmae_slave_config sh73a0_mpdma_slaves[] = { | ||
| 629 | { | ||
| 630 | .slave_id = SHDMA_SLAVE_FSI2A_RX, | ||
| 631 | .addr = 0xec230020, | ||
| 632 | .chcr = CHCR_RX(XMIT_SZ_32BIT), | ||
| 633 | .mid_rid = 0xd6, /* CHECK ME */ | ||
| 634 | }, { | ||
| 635 | .slave_id = SHDMA_SLAVE_FSI2A_TX, | ||
| 636 | .addr = 0xec230024, | ||
| 637 | .chcr = CHCR_TX(XMIT_SZ_32BIT), | ||
| 638 | .mid_rid = 0xd5, /* CHECK ME */ | ||
| 639 | }, { | ||
| 640 | .slave_id = SHDMA_SLAVE_FSI2C_RX, | ||
| 641 | .addr = 0xec230060, | ||
| 642 | .chcr = CHCR_RX(XMIT_SZ_32BIT), | ||
| 643 | .mid_rid = 0xda, /* CHECK ME */ | ||
| 644 | }, { | ||
| 645 | .slave_id = SHDMA_SLAVE_FSI2C_TX, | ||
| 646 | .addr = 0xec230064, | ||
| 647 | .chcr = CHCR_TX(XMIT_SZ_32BIT), | ||
| 648 | .mid_rid = 0xd9, /* CHECK ME */ | ||
| 649 | }, { | ||
| 650 | .slave_id = SHDMA_SLAVE_FSI2B_RX, | ||
| 651 | .addr = 0xec240020, | ||
| 652 | .chcr = CHCR_RX(XMIT_SZ_32BIT), | ||
| 653 | .mid_rid = 0x8e, /* CHECK ME */ | ||
| 654 | }, { | ||
| 655 | .slave_id = SHDMA_SLAVE_FSI2B_TX, | ||
| 656 | .addr = 0xec240024, | ||
| 657 | .chcr = CHCR_RX(XMIT_SZ_32BIT), | ||
| 658 | .mid_rid = 0x8d, /* CHECK ME */ | ||
| 659 | }, { | ||
| 660 | .slave_id = SHDMA_SLAVE_FSI2D_RX, | ||
| 661 | .addr = 0xec240060, | ||
| 662 | .chcr = CHCR_RX(XMIT_SZ_32BIT), | ||
| 663 | .mid_rid = 0x9a, /* CHECK ME */ | ||
| 664 | }, | ||
| 665 | }; | ||
| 666 | |||
| 667 | #define MPDMA_CHANNEL(a, b, c) \ | ||
| 668 | { \ | ||
| 669 | .offset = a, \ | ||
| 670 | .dmars = b, \ | ||
| 671 | .dmars_bit = c, \ | ||
| 672 | .chclr_offset = (0x220 - 0x20) + a \ | ||
| 673 | } | ||
| 674 | |||
| 675 | static const struct sh_dmae_channel sh73a0_mpdma_channels[] = { | ||
| 676 | MPDMA_CHANNEL(0x00, 0, 0), | ||
| 677 | MPDMA_CHANNEL(0x10, 0, 8), | ||
| 678 | MPDMA_CHANNEL(0x20, 4, 0), | ||
| 679 | MPDMA_CHANNEL(0x30, 4, 8), | ||
| 680 | MPDMA_CHANNEL(0x50, 8, 0), | ||
| 681 | MPDMA_CHANNEL(0x70, 8, 8), | ||
| 682 | }; | ||
| 683 | |||
| 684 | static struct sh_dmae_pdata sh73a0_mpdma_platform_data = { | ||
| 685 | .slave = sh73a0_mpdma_slaves, | ||
| 686 | .slave_num = ARRAY_SIZE(sh73a0_mpdma_slaves), | ||
| 687 | .channel = sh73a0_mpdma_channels, | ||
| 688 | .channel_num = ARRAY_SIZE(sh73a0_mpdma_channels), | ||
| 689 | .ts_low_shift = TS_LOW_SHIFT, | ||
| 690 | .ts_low_mask = TS_LOW_BIT << TS_LOW_SHIFT, | ||
| 691 | .ts_high_shift = TS_HI_SHIFT, | ||
| 692 | .ts_high_mask = TS_HI_BIT << TS_HI_SHIFT, | ||
| 693 | .ts_shift = dma_ts_shift, | ||
| 694 | .ts_shift_num = ARRAY_SIZE(dma_ts_shift), | ||
| 695 | .dmaor_init = DMAOR_DME, | ||
| 696 | .chclr_present = 1, | ||
| 697 | }; | ||
| 698 | |||
| 699 | /* Resource order important! */ | ||
| 700 | static struct resource sh73a0_mpdma_resources[] = { | ||
| 701 | { | ||
| 702 | /* Channel registers and DMAOR */ | ||
| 703 | .start = 0xec618020, | ||
| 704 | .end = 0xec61828f, | ||
| 705 | .flags = IORESOURCE_MEM, | ||
| 706 | }, | ||
| 707 | { | ||
| 708 | /* DMARSx */ | ||
| 709 | .start = 0xec619000, | ||
| 710 | .end = 0xec61900b, | ||
| 711 | .flags = IORESOURCE_MEM, | ||
| 712 | }, | ||
| 713 | { | ||
| 714 | .name = "error_irq", | ||
| 715 | .start = gic_spi(181), | ||
| 716 | .end = gic_spi(181), | ||
| 717 | .flags = IORESOURCE_IRQ, | ||
| 718 | }, | ||
| 719 | { | ||
| 720 | /* IRQ for channels 0-5 */ | ||
| 721 | .start = gic_spi(175), | ||
| 722 | .end = gic_spi(180), | ||
| 723 | .flags = IORESOURCE_IRQ, | ||
| 724 | }, | ||
| 725 | }; | ||
| 726 | |||
| 727 | static struct platform_device mpdma0_device = { | ||
| 728 | .name = "sh-dma-engine", | ||
| 729 | .id = 1, | ||
| 730 | .resource = sh73a0_mpdma_resources, | ||
| 731 | .num_resources = ARRAY_SIZE(sh73a0_mpdma_resources), | ||
| 732 | .dev = { | ||
| 733 | .platform_data = &sh73a0_mpdma_platform_data, | ||
| 734 | }, | ||
| 735 | }; | ||
| 736 | |||
| 654 | static struct platform_device *sh73a0_early_devices[] __initdata = { | 737 | static struct platform_device *sh73a0_early_devices[] __initdata = { |
| 655 | &scif0_device, | 738 | &scif0_device, |
| 656 | &scif1_device, | 739 | &scif1_device, |
| @@ -673,6 +756,7 @@ static struct platform_device *sh73a0_late_devices[] __initdata = { | |||
| 673 | &i2c3_device, | 756 | &i2c3_device, |
| 674 | &i2c4_device, | 757 | &i2c4_device, |
| 675 | &dma0_device, | 758 | &dma0_device, |
| 759 | &mpdma0_device, | ||
| 676 | }; | 760 | }; |
| 677 | 761 | ||
| 678 | #define SRCR2 0xe61580b0 | 762 | #define SRCR2 0xe61580b0 |
diff --git a/arch/arm/mach-tegra/board-dt-tegra20.c b/arch/arm/mach-tegra/board-dt-tegra20.c index d0de9c1192f7..c0999633a9ab 100644 --- a/arch/arm/mach-tegra/board-dt-tegra20.c +++ b/arch/arm/mach-tegra/board-dt-tegra20.c | |||
| @@ -64,7 +64,8 @@ struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = { | |||
| 64 | &tegra_ehci2_pdata), | 64 | &tegra_ehci2_pdata), |
| 65 | OF_DEV_AUXDATA("nvidia,tegra20-ehci", TEGRA_USB3_BASE, "tegra-ehci.2", | 65 | OF_DEV_AUXDATA("nvidia,tegra20-ehci", TEGRA_USB3_BASE, "tegra-ehci.2", |
| 66 | &tegra_ehci3_pdata), | 66 | &tegra_ehci3_pdata), |
| 67 | OF_DEV_AUXDATA("nvidia,tegra20-apbdma", 0x6000a000, "tegra-apbdma", NULL), | 67 | OF_DEV_AUXDATA("nvidia,tegra20-apbdma", TEGRA_APB_DMA_BASE, "tegra-apbdma", NULL), |
| 68 | OF_DEV_AUXDATA("nvidia,tegra20-pwm", TEGRA_PWFM_BASE, "tegra-pwm", NULL), | ||
| 68 | {} | 69 | {} |
| 69 | }; | 70 | }; |
| 70 | 71 | ||
diff --git a/arch/arm/mach-tegra/board-dt-tegra30.c b/arch/arm/mach-tegra/board-dt-tegra30.c index ee48214bfd89..53bf60f11580 100644 --- a/arch/arm/mach-tegra/board-dt-tegra30.c +++ b/arch/arm/mach-tegra/board-dt-tegra30.c | |||
| @@ -33,6 +33,8 @@ | |||
| 33 | #include <asm/mach/arch.h> | 33 | #include <asm/mach/arch.h> |
| 34 | #include <asm/hardware/gic.h> | 34 | #include <asm/hardware/gic.h> |
| 35 | 35 | ||
| 36 | #include <mach/iomap.h> | ||
| 37 | |||
| 36 | #include "board.h" | 38 | #include "board.h" |
| 37 | #include "clock.h" | 39 | #include "clock.h" |
| 38 | 40 | ||
| @@ -48,6 +50,7 @@ struct of_dev_auxdata tegra30_auxdata_lookup[] __initdata = { | |||
| 48 | OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000D000, "tegra-i2c.4", NULL), | 50 | OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000D000, "tegra-i2c.4", NULL), |
| 49 | OF_DEV_AUXDATA("nvidia,tegra30-ahub", 0x70080000, "tegra30-ahub", NULL), | 51 | OF_DEV_AUXDATA("nvidia,tegra30-ahub", 0x70080000, "tegra30-ahub", NULL), |
| 50 | OF_DEV_AUXDATA("nvidia,tegra30-apbdma", 0x6000a000, "tegra-apbdma", NULL), | 52 | OF_DEV_AUXDATA("nvidia,tegra30-apbdma", 0x6000a000, "tegra-apbdma", NULL), |
| 53 | OF_DEV_AUXDATA("nvidia,tegra30-pwm", TEGRA_PWFM_BASE, "tegra-pwm", NULL), | ||
| 51 | {} | 54 | {} |
| 52 | }; | 55 | }; |
| 53 | 56 | ||
diff --git a/arch/arm/mach-tegra/board-harmony-power.c b/arch/arm/mach-tegra/board-harmony-power.c index 44dcb2e869b5..8fd387bf31f0 100644 --- a/arch/arm/mach-tegra/board-harmony-power.c +++ b/arch/arm/mach-tegra/board-harmony-power.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
| 20 | #include <linux/gpio.h> | 20 | #include <linux/gpio.h> |
| 21 | #include <linux/regulator/machine.h> | 21 | #include <linux/regulator/machine.h> |
| 22 | #include <linux/regulator/fixed.h> | ||
| 22 | #include <linux/mfd/tps6586x.h> | 23 | #include <linux/mfd/tps6586x.h> |
| 23 | #include <linux/of.h> | 24 | #include <linux/of.h> |
| 24 | #include <linux/of_i2c.h> | 25 | #include <linux/of_i2c.h> |
| @@ -34,7 +35,9 @@ static struct regulator_consumer_supply tps658621_ldo0_supply[] = { | |||
| 34 | }; | 35 | }; |
| 35 | 36 | ||
| 36 | static struct regulator_init_data ldo0_data = { | 37 | static struct regulator_init_data ldo0_data = { |
| 38 | .supply_regulator = "vdd_sm2", | ||
| 37 | .constraints = { | 39 | .constraints = { |
| 40 | .name = "vdd_ldo0", | ||
| 38 | .min_uV = 3300 * 1000, | 41 | .min_uV = 3300 * 1000, |
| 39 | .max_uV = 3300 * 1000, | 42 | .max_uV = 3300 * 1000, |
| 40 | .valid_modes_mask = (REGULATOR_MODE_NORMAL | | 43 | .valid_modes_mask = (REGULATOR_MODE_NORMAL | |
| @@ -48,9 +51,11 @@ static struct regulator_init_data ldo0_data = { | |||
| 48 | .consumer_supplies = tps658621_ldo0_supply, | 51 | .consumer_supplies = tps658621_ldo0_supply, |
| 49 | }; | 52 | }; |
| 50 | 53 | ||
| 51 | #define HARMONY_REGULATOR_INIT(_id, _minmv, _maxmv) \ | 54 | #define HARMONY_REGULATOR_INIT(_id, _name, _supply, _minmv, _maxmv) \ |
| 52 | static struct regulator_init_data _id##_data = { \ | 55 | static struct regulator_init_data _id##_data = { \ |
| 56 | .supply_regulator = _supply, \ | ||
| 53 | .constraints = { \ | 57 | .constraints = { \ |
| 58 | .name = _name, \ | ||
| 54 | .min_uV = (_minmv)*1000, \ | 59 | .min_uV = (_minmv)*1000, \ |
| 55 | .max_uV = (_maxmv)*1000, \ | 60 | .max_uV = (_maxmv)*1000, \ |
| 56 | .valid_modes_mask = (REGULATOR_MODE_NORMAL | \ | 61 | .valid_modes_mask = (REGULATOR_MODE_NORMAL | \ |
| @@ -61,18 +66,18 @@ static struct regulator_init_data ldo0_data = { | |||
| 61 | }, \ | 66 | }, \ |
| 62 | } | 67 | } |
| 63 | 68 | ||
| 64 | HARMONY_REGULATOR_INIT(sm0, 725, 1500); | 69 | HARMONY_REGULATOR_INIT(sm0, "vdd_sm0", "vdd_sys", 725, 1500); |
| 65 | HARMONY_REGULATOR_INIT(sm1, 725, 1500); | 70 | HARMONY_REGULATOR_INIT(sm1, "vdd_sm1", "vdd_sys", 725, 1500); |
| 66 | HARMONY_REGULATOR_INIT(sm2, 3000, 4550); | 71 | HARMONY_REGULATOR_INIT(sm2, "vdd_sm2", "vdd_sys", 3000, 4550); |
| 67 | HARMONY_REGULATOR_INIT(ldo1, 725, 1500); | 72 | HARMONY_REGULATOR_INIT(ldo1, "vdd_ldo1", "vdd_sm2", 725, 1500); |
| 68 | HARMONY_REGULATOR_INIT(ldo2, 725, 1500); | 73 | HARMONY_REGULATOR_INIT(ldo2, "vdd_ldo2", "vdd_sm2", 725, 1500); |
| 69 | HARMONY_REGULATOR_INIT(ldo3, 1250, 3300); | 74 | HARMONY_REGULATOR_INIT(ldo3, "vdd_ldo3", "vdd_sm2", 1250, 3300); |
| 70 | HARMONY_REGULATOR_INIT(ldo4, 1700, 2475); | 75 | HARMONY_REGULATOR_INIT(ldo4, "vdd_ldo4", "vdd_sm2", 1700, 2475); |
| 71 | HARMONY_REGULATOR_INIT(ldo5, 1250, 3300); | 76 | HARMONY_REGULATOR_INIT(ldo5, "vdd_ldo5", NULL, 1250, 3300); |
| 72 | HARMONY_REGULATOR_INIT(ldo6, 1250, 3300); | 77 | HARMONY_REGULATOR_INIT(ldo6, "vdd_ldo6", "vdd_sm2", 1250, 3300); |
| 73 | HARMONY_REGULATOR_INIT(ldo7, 1250, 3300); | 78 | HARMONY_REGULATOR_INIT(ldo7, "vdd_ldo7", "vdd_sm2", 1250, 3300); |
| 74 | HARMONY_REGULATOR_INIT(ldo8, 1250, 3300); | 79 | HARMONY_REGULATOR_INIT(ldo8, "vdd_ldo8", "vdd_sm2", 1250, 3300); |
| 75 | HARMONY_REGULATOR_INIT(ldo9, 1250, 3300); | 80 | HARMONY_REGULATOR_INIT(ldo9, "vdd_ldo9", "vdd_sm2", 1250, 3300); |
| 76 | 81 | ||
| 77 | #define TPS_REG(_id, _data) \ | 82 | #define TPS_REG(_id, _data) \ |
| 78 | { \ | 83 | { \ |
| @@ -115,6 +120,8 @@ static struct i2c_board_info __initdata harmony_regulators[] = { | |||
| 115 | int __init harmony_regulator_init(void) | 120 | int __init harmony_regulator_init(void) |
| 116 | { | 121 | { |
| 117 | if (machine_is_harmony()) { | 122 | if (machine_is_harmony()) { |
| 123 | regulator_register_always_on(0, "vdd_sys", | ||
| 124 | NULL, 0, 5000000); | ||
| 118 | i2c_register_board_info(3, harmony_regulators, 1); | 125 | i2c_register_board_info(3, harmony_regulators, 1); |
| 119 | } else { /* Harmony, booted using device tree */ | 126 | } else { /* Harmony, booted using device tree */ |
| 120 | struct device_node *np; | 127 | struct device_node *np; |
diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index a310222951da..8674a890fd1c 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
| 16 | #include <linux/io.h> | 16 | #include <linux/io.h> |
| 17 | #include <linux/i2c.h> | 17 | #include <linux/i2c.h> |
| 18 | #include <linux/platform_data/i2c-nomadik.h> | ||
| 18 | #include <linux/gpio.h> | 19 | #include <linux/gpio.h> |
| 19 | #include <linux/amba/bus.h> | 20 | #include <linux/amba/bus.h> |
| 20 | #include <linux/amba/pl022.h> | 21 | #include <linux/amba/pl022.h> |
| @@ -40,7 +41,6 @@ | |||
| 40 | #include <asm/mach/arch.h> | 41 | #include <asm/mach/arch.h> |
| 41 | #include <asm/hardware/gic.h> | 42 | #include <asm/hardware/gic.h> |
| 42 | 43 | ||
| 43 | #include <plat/i2c.h> | ||
| 44 | #include <plat/ste_dma40.h> | 44 | #include <plat/ste_dma40.h> |
| 45 | #include <plat/gpio-nomadik.h> | 45 | #include <plat/gpio-nomadik.h> |
| 46 | 46 | ||
| @@ -211,24 +211,6 @@ static struct ab8500_platform_data ab8500_platdata = { | |||
| 211 | .codec = &ab8500_codec_pdata, | 211 | .codec = &ab8500_codec_pdata, |
| 212 | }; | 212 | }; |
| 213 | 213 | ||
| 214 | static struct resource ab8500_resources[] = { | ||
| 215 | [0] = { | ||
| 216 | .start = IRQ_DB8500_AB8500, | ||
| 217 | .end = IRQ_DB8500_AB8500, | ||
| 218 | .flags = IORESOURCE_IRQ | ||
| 219 | } | ||
| 220 | }; | ||
| 221 | |||
| 222 | struct platform_device ab8500_device = { | ||
| 223 | .name = "ab8500-core", | ||
| 224 | .id = 0, | ||
| 225 | .dev = { | ||
| 226 | .platform_data = &ab8500_platdata, | ||
| 227 | }, | ||
| 228 | .num_resources = 1, | ||
| 229 | .resource = ab8500_resources, | ||
| 230 | }; | ||
| 231 | |||
| 232 | /* | 214 | /* |
| 233 | * TPS61052 | 215 | * TPS61052 |
| 234 | */ | 216 | */ |
| @@ -443,7 +425,6 @@ static struct hash_platform_data u8500_hash1_platform_data = { | |||
| 443 | /* add any platform devices here - TODO */ | 425 | /* add any platform devices here - TODO */ |
| 444 | static struct platform_device *mop500_platform_devs[] __initdata = { | 426 | static struct platform_device *mop500_platform_devs[] __initdata = { |
| 445 | &mop500_gpio_keys_device, | 427 | &mop500_gpio_keys_device, |
| 446 | &ab8500_device, | ||
| 447 | }; | 428 | }; |
| 448 | 429 | ||
| 449 | #ifdef CONFIG_STE_DMA40 | 430 | #ifdef CONFIG_STE_DMA40 |
| @@ -605,7 +586,6 @@ static struct platform_device *snowball_platform_devs[] __initdata = { | |||
| 605 | &snowball_led_dev, | 586 | &snowball_led_dev, |
| 606 | &snowball_key_dev, | 587 | &snowball_key_dev, |
| 607 | &snowball_sbnet_dev, | 588 | &snowball_sbnet_dev, |
| 608 | &ab8500_device, | ||
| 609 | }; | 589 | }; |
| 610 | 590 | ||
| 611 | static void __init mop500_init_machine(void) | 591 | static void __init mop500_init_machine(void) |
| @@ -617,9 +597,8 @@ static void __init mop500_init_machine(void) | |||
| 617 | mop500_gpio_keys[0].gpio = GPIO_PROX_SENSOR; | 597 | mop500_gpio_keys[0].gpio = GPIO_PROX_SENSOR; |
| 618 | 598 | ||
| 619 | mop500_pinmaps_init(); | 599 | mop500_pinmaps_init(); |
| 620 | parent = u8500_init_devices(); | 600 | parent = u8500_init_devices(&ab8500_platdata); |
| 621 | 601 | ||
| 622 | /* FIXME: parent of ab8500 should be prcmu */ | ||
| 623 | for (i = 0; i < ARRAY_SIZE(mop500_platform_devs); i++) | 602 | for (i = 0; i < ARRAY_SIZE(mop500_platform_devs); i++) |
| 624 | mop500_platform_devs[i]->dev.parent = parent; | 603 | mop500_platform_devs[i]->dev.parent = parent; |
| 625 | 604 | ||
| @@ -652,7 +631,7 @@ static void __init snowball_init_machine(void) | |||
| 652 | int i; | 631 | int i; |
| 653 | 632 | ||
| 654 | snowball_pinmaps_init(); | 633 | snowball_pinmaps_init(); |
| 655 | parent = u8500_init_devices(); | 634 | parent = u8500_init_devices(&ab8500_platdata); |
| 656 | 635 | ||
| 657 | for (i = 0; i < ARRAY_SIZE(snowball_platform_devs); i++) | 636 | for (i = 0; i < ARRAY_SIZE(snowball_platform_devs); i++) |
| 658 | snowball_platform_devs[i]->dev.parent = parent; | 637 | snowball_platform_devs[i]->dev.parent = parent; |
| @@ -684,7 +663,7 @@ static void __init hrefv60_init_machine(void) | |||
| 684 | mop500_gpio_keys[0].gpio = HREFV60_PROX_SENSE_GPIO; | 663 | mop500_gpio_keys[0].gpio = HREFV60_PROX_SENSE_GPIO; |
| 685 | 664 | ||
| 686 | hrefv60_pinmaps_init(); | 665 | hrefv60_pinmaps_init(); |
| 687 | parent = u8500_init_devices(); | 666 | parent = u8500_init_devices(&ab8500_platdata); |
| 688 | 667 | ||
| 689 | for (i = 0; i < ARRAY_SIZE(mop500_platform_devs); i++) | 668 | for (i = 0; i < ARRAY_SIZE(mop500_platform_devs); i++) |
| 690 | mop500_platform_devs[i]->dev.parent = parent; | 669 | mop500_platform_devs[i]->dev.parent = parent; |
| @@ -785,9 +764,6 @@ static const struct of_device_id u8500_local_bus_nodes[] = { | |||
| 785 | /* only create devices below soc node */ | 764 | /* only create devices below soc node */ |
| 786 | { .compatible = "stericsson,db8500", }, | 765 | { .compatible = "stericsson,db8500", }, |
| 787 | { .compatible = "stericsson,db8500-prcmu", }, | 766 | { .compatible = "stericsson,db8500-prcmu", }, |
| 788 | { .compatible = "stericsson,db8500-prcmu-regulator", }, | ||
| 789 | { .compatible = "stericsson,ab8500", }, | ||
| 790 | { .compatible = "stericsson,ab8500-regulator", }, | ||
| 791 | { .compatible = "simple-bus"}, | 767 | { .compatible = "simple-bus"}, |
| 792 | { }, | 768 | { }, |
| 793 | }; | 769 | }; |
diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index c8dd94f606dc..db3c52d56ca4 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | #include <linux/irq.h> | 16 | #include <linux/irq.h> |
| 17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
| 18 | #include <linux/io.h> | 18 | #include <linux/io.h> |
| 19 | #include <linux/mfd/abx500/ab8500.h> | ||
| 19 | 20 | ||
| 20 | #include <asm/mach/map.h> | 21 | #include <asm/mach/map.h> |
| 21 | #include <asm/pmu.h> | 22 | #include <asm/pmu.h> |
| @@ -115,7 +116,7 @@ static irqreturn_t db8500_pmu_handler(int irq, void *dev, irq_handler_t handler) | |||
| 115 | return ret; | 116 | return ret; |
| 116 | } | 117 | } |
| 117 | 118 | ||
| 118 | static struct arm_pmu_platdata db8500_pmu_platdata = { | 119 | struct arm_pmu_platdata db8500_pmu_platdata = { |
| 119 | .handle_irq = db8500_pmu_handler, | 120 | .handle_irq = db8500_pmu_handler, |
| 120 | }; | 121 | }; |
| 121 | 122 | ||
| @@ -206,7 +207,7 @@ static struct device * __init db8500_soc_device_init(void) | |||
| 206 | /* | 207 | /* |
| 207 | * This function is called from the board init | 208 | * This function is called from the board init |
| 208 | */ | 209 | */ |
| 209 | struct device * __init u8500_init_devices(void) | 210 | struct device * __init u8500_init_devices(struct ab8500_platform_data *ab8500) |
| 210 | { | 211 | { |
| 211 | struct device *parent; | 212 | struct device *parent; |
| 212 | int i; | 213 | int i; |
| @@ -223,6 +224,8 @@ struct device * __init u8500_init_devices(void) | |||
| 223 | for (i = 0; i < ARRAY_SIZE(platform_devs); i++) | 224 | for (i = 0; i < ARRAY_SIZE(platform_devs); i++) |
| 224 | platform_devs[i]->dev.parent = parent; | 225 | platform_devs[i]->dev.parent = parent; |
| 225 | 226 | ||
| 227 | db8500_prcmu_device.dev.platform_data = ab8500; | ||
| 228 | |||
| 226 | platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); | 229 | platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); |
| 227 | 230 | ||
| 228 | return parent; | 231 | return parent; |
diff --git a/arch/arm/mach-ux500/devices-common.h b/arch/arm/mach-ux500/devices-common.h index 6e4706560266..ecdd8386cffb 100644 --- a/arch/arm/mach-ux500/devices-common.h +++ b/arch/arm/mach-ux500/devices-common.h | |||
| @@ -12,7 +12,7 @@ | |||
| 12 | #include <linux/dma-mapping.h> | 12 | #include <linux/dma-mapping.h> |
| 13 | #include <linux/sys_soc.h> | 13 | #include <linux/sys_soc.h> |
| 14 | #include <linux/amba/bus.h> | 14 | #include <linux/amba/bus.h> |
| 15 | #include <plat/i2c.h> | 15 | #include <linux/platform_data/i2c-nomadik.h> |
| 16 | #include <mach/crypto-ux500.h> | 16 | #include <mach/crypto-ux500.h> |
| 17 | 17 | ||
| 18 | struct spi_master_cntlr; | 18 | struct spi_master_cntlr; |
| @@ -56,27 +56,15 @@ dbx500_add_uart(struct device *parent, const char *name, resource_size_t base, | |||
| 56 | 56 | ||
| 57 | struct nmk_i2c_controller; | 57 | struct nmk_i2c_controller; |
| 58 | 58 | ||
| 59 | static inline struct platform_device * | 59 | static inline struct amba_device * |
| 60 | dbx500_add_i2c(struct device *parent, int id, resource_size_t base, int irq, | 60 | dbx500_add_i2c(struct device *parent, int id, resource_size_t base, int irq, |
| 61 | struct nmk_i2c_controller *data) | 61 | struct nmk_i2c_controller *data) |
| 62 | { | 62 | { |
| 63 | struct resource res[] = { | 63 | /* Conjure a name similar to what the platform device used to have */ |
| 64 | DEFINE_RES_MEM(base, SZ_4K), | 64 | char name[16]; |
| 65 | DEFINE_RES_IRQ(irq), | ||
| 66 | }; | ||
| 67 | 65 | ||
| 68 | struct platform_device_info pdevinfo = { | 66 | snprintf(name, sizeof(name), "nmk-i2c.%d", id); |
| 69 | .parent = parent, | 67 | return amba_apb_device_add(parent, name, base, SZ_4K, irq, 0, data, 0); |
| 70 | .name = "nmk-i2c", | ||
| 71 | .id = id, | ||
| 72 | .res = res, | ||
| 73 | .num_res = ARRAY_SIZE(res), | ||
| 74 | .data = data, | ||
| 75 | .size_data = sizeof(*data), | ||
| 76 | .dma_mask = DMA_BIT_MASK(32), | ||
| 77 | }; | ||
| 78 | |||
| 79 | return platform_device_register_full(&pdevinfo); | ||
| 80 | } | 68 | } |
| 81 | 69 | ||
| 82 | static inline struct amba_device * | 70 | static inline struct amba_device * |
diff --git a/arch/arm/mach-ux500/include/mach/setup.h b/arch/arm/mach-ux500/include/mach/setup.h index 8b7ed82a2866..7914e5eaa9c7 100644 --- a/arch/arm/mach-ux500/include/mach/setup.h +++ b/arch/arm/mach-ux500/include/mach/setup.h | |||
| @@ -13,11 +13,12 @@ | |||
| 13 | 13 | ||
| 14 | #include <asm/mach/time.h> | 14 | #include <asm/mach/time.h> |
| 15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
| 16 | #include <linux/mfd/abx500/ab8500.h> | ||
| 16 | 17 | ||
| 17 | void __init ux500_map_io(void); | 18 | void __init ux500_map_io(void); |
| 18 | extern void __init u8500_map_io(void); | 19 | extern void __init u8500_map_io(void); |
| 19 | 20 | ||
| 20 | extern struct device * __init u8500_init_devices(void); | 21 | extern struct device * __init u8500_init_devices(struct ab8500_platform_data *ab8500); |
| 21 | 22 | ||
| 22 | extern void __init ux500_init_irq(void); | 23 | extern void __init ux500_init_irq(void); |
| 23 | extern void __init ux500_init_late(void); | 24 | extern void __init ux500_init_late(void); |
diff --git a/arch/arm/mach-vt8500/Makefile b/arch/arm/mach-vt8500/Makefile index 54e69973f39b..7ce51767c99c 100644 --- a/arch/arm/mach-vt8500/Makefile +++ b/arch/arm/mach-vt8500/Makefile | |||
| @@ -5,5 +5,3 @@ obj-$(CONFIG_VTWM_VERSION_WM8505) += devices-wm8505.o | |||
| 5 | 5 | ||
| 6 | obj-$(CONFIG_MACH_BV07) += bv07.o | 6 | obj-$(CONFIG_MACH_BV07) += bv07.o |
| 7 | obj-$(CONFIG_MACH_WM8505_7IN_NETBOOK) += wm8505_7in.o | 7 | obj-$(CONFIG_MACH_WM8505_7IN_NETBOOK) += wm8505_7in.o |
| 8 | |||
| 9 | obj-$(CONFIG_HAVE_PWM) += pwm.o | ||
diff --git a/arch/arm/mach-vt8500/pwm.c b/arch/arm/mach-vt8500/pwm.c deleted file mode 100644 index 8ad825e93592..000000000000 --- a/arch/arm/mach-vt8500/pwm.c +++ /dev/null | |||
| @@ -1,265 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * arch/arm/mach-vt8500/pwm.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> | ||
| 5 | * | ||
| 6 | * This software is licensed under the terms of the GNU General Public | ||
| 7 | * License version 2, as published by the Free Software Foundation, and | ||
| 8 | * may be copied, distributed, and modified under those terms. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | */ | ||
| 15 | |||
| 16 | #include <linux/module.h> | ||
| 17 | #include <linux/kernel.h> | ||
| 18 | #include <linux/platform_device.h> | ||
| 19 | #include <linux/slab.h> | ||
| 20 | #include <linux/err.h> | ||
| 21 | #include <linux/io.h> | ||
| 22 | #include <linux/pwm.h> | ||
| 23 | #include <linux/delay.h> | ||
| 24 | |||
| 25 | #include <asm/div64.h> | ||
| 26 | |||
| 27 | #define VT8500_NR_PWMS 4 | ||
| 28 | |||
| 29 | static DEFINE_MUTEX(pwm_lock); | ||
| 30 | static LIST_HEAD(pwm_list); | ||
| 31 | |||
| 32 | struct pwm_device { | ||
| 33 | struct list_head node; | ||
| 34 | struct platform_device *pdev; | ||
| 35 | |||
| 36 | const char *label; | ||
| 37 | |||
| 38 | void __iomem *regbase; | ||
| 39 | |||
| 40 | unsigned int use_count; | ||
| 41 | unsigned int pwm_id; | ||
| 42 | }; | ||
| 43 | |||
| 44 | #define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t) | ||
| 45 | static inline void pwm_busy_wait(void __iomem *reg, u8 bitmask) | ||
| 46 | { | ||
| 47 | int loops = msecs_to_loops(10); | ||
| 48 | while ((readb(reg) & bitmask) && --loops) | ||
| 49 | cpu_relax(); | ||
| 50 | |||
| 51 | if (unlikely(!loops)) | ||
| 52 | pr_warning("Waiting for status bits 0x%x to clear timed out\n", | ||
| 53 | bitmask); | ||
| 54 | } | ||
| 55 | |||
| 56 | int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) | ||
| 57 | { | ||
| 58 | unsigned long long c; | ||
| 59 | unsigned long period_cycles, prescale, pv, dc; | ||
| 60 | |||
| 61 | if (pwm == NULL || period_ns == 0 || duty_ns > period_ns) | ||
| 62 | return -EINVAL; | ||
| 63 | |||
| 64 | c = 25000000/2; /* wild guess --- need to implement clocks */ | ||
| 65 | c = c * period_ns; | ||
| 66 | do_div(c, 1000000000); | ||
| 67 | period_cycles = c; | ||
| 68 | |||
| 69 | if (period_cycles < 1) | ||
| 70 | period_cycles = 1; | ||
| 71 | prescale = (period_cycles - 1) / 4096; | ||
| 72 | pv = period_cycles / (prescale + 1) - 1; | ||
| 73 | if (pv > 4095) | ||
| 74 | pv = 4095; | ||
| 75 | |||
| 76 | if (prescale > 1023) | ||
| 77 | return -EINVAL; | ||
| 78 | |||
| 79 | c = (unsigned long long)pv * duty_ns; | ||
| 80 | do_div(c, period_ns); | ||
| 81 | dc = c; | ||
| 82 | |||
| 83 | pwm_busy_wait(pwm->regbase + 0x40 + pwm->pwm_id, (1 << 1)); | ||
| 84 | writel(prescale, pwm->regbase + 0x4 + (pwm->pwm_id << 4)); | ||
| 85 | |||
| 86 | pwm_busy_wait(pwm->regbase + 0x40 + pwm->pwm_id, (1 << 2)); | ||
| 87 | writel(pv, pwm->regbase + 0x8 + (pwm->pwm_id << 4)); | ||
| 88 | |||
| 89 | pwm_busy_wait(pwm->regbase + 0x40 + pwm->pwm_id, (1 << 3)); | ||
| 90 | writel(dc, pwm->regbase + 0xc + (pwm->pwm_id << 4)); | ||
| 91 | |||
| 92 | return 0; | ||
| 93 | } | ||
| 94 | EXPORT_SYMBOL(pwm_config); | ||
| 95 | |||
| 96 | int pwm_enable(struct pwm_device *pwm) | ||
| 97 | { | ||
| 98 | pwm_busy_wait(pwm->regbase + 0x40 + pwm->pwm_id, (1 << 0)); | ||
| 99 | writel(5, pwm->regbase + (pwm->pwm_id << 4)); | ||
| 100 | return 0; | ||
| 101 | } | ||
| 102 | EXPORT_SYMBOL(pwm_enable); | ||
| 103 | |||
| 104 | void pwm_disable(struct pwm_device *pwm) | ||
| 105 | { | ||
| 106 | pwm_busy_wait(pwm->regbase + 0x40 + pwm->pwm_id, (1 << 0)); | ||
| 107 | writel(0, pwm->regbase + (pwm->pwm_id << 4)); | ||
| 108 | } | ||
| 109 | EXPORT_SYMBOL(pwm_disable); | ||
| 110 | |||
| 111 | struct pwm_device *pwm_request(int pwm_id, const char *label) | ||
| 112 | { | ||
| 113 | struct pwm_device *pwm; | ||
| 114 | int found = 0; | ||
| 115 | |||
| 116 | mutex_lock(&pwm_lock); | ||
| 117 | |||
| 118 | list_for_each_entry(pwm, &pwm_list, node) { | ||
| 119 | if (pwm->pwm_id == pwm_id) { | ||
| 120 | found = 1; | ||
| 121 | break; | ||
| 122 | } | ||
| 123 | } | ||
| 124 | |||
| 125 | if (found) { | ||
| 126 | if (pwm->use_count == 0) { | ||
| 127 | pwm->use_count++; | ||
| 128 | pwm->label = label; | ||
| 129 | } else { | ||
| 130 | pwm = ERR_PTR(-EBUSY); | ||
| 131 | } | ||
| 132 | } else { | ||
| 133 | pwm = ERR_PTR(-ENOENT); | ||
| 134 | } | ||
| 135 | |||
| 136 | mutex_unlock(&pwm_lock); | ||
| 137 | return pwm; | ||
| 138 | } | ||
| 139 | EXPORT_SYMBOL(pwm_request); | ||
| 140 | |||
| 141 | void pwm_free(struct pwm_device *pwm) | ||
| 142 | { | ||
| 143 | mutex_lock(&pwm_lock); | ||
| 144 | |||
| 145 | if (pwm->use_count) { | ||
| 146 | pwm->use_count--; | ||
| 147 | pwm->label = NULL; | ||
| 148 | } else { | ||
| 149 | pr_warning("PWM device already freed\n"); | ||
| 150 | } | ||
| 151 | |||
| 152 | mutex_unlock(&pwm_lock); | ||
| 153 | } | ||
| 154 | EXPORT_SYMBOL(pwm_free); | ||
| 155 | |||
| 156 | static inline void __add_pwm(struct pwm_device *pwm) | ||
| 157 | { | ||
| 158 | mutex_lock(&pwm_lock); | ||
| 159 | list_add_tail(&pwm->node, &pwm_list); | ||
| 160 | mutex_unlock(&pwm_lock); | ||
| 161 | } | ||
| 162 | |||
| 163 | static int __devinit pwm_probe(struct platform_device *pdev) | ||
| 164 | { | ||
| 165 | struct pwm_device *pwms; | ||
| 166 | struct resource *r; | ||
| 167 | int ret = 0; | ||
| 168 | int i; | ||
| 169 | |||
| 170 | pwms = kzalloc(sizeof(struct pwm_device) * VT8500_NR_PWMS, GFP_KERNEL); | ||
| 171 | if (pwms == NULL) { | ||
| 172 | dev_err(&pdev->dev, "failed to allocate memory\n"); | ||
| 173 | return -ENOMEM; | ||
| 174 | } | ||
| 175 | |||
| 176 | for (i = 0; i < VT8500_NR_PWMS; i++) { | ||
| 177 | pwms[i].use_count = 0; | ||
| 178 | pwms[i].pwm_id = i; | ||
| 179 | pwms[i].pdev = pdev; | ||
| 180 | } | ||
| 181 | |||
| 182 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 183 | if (r == NULL) { | ||
| 184 | dev_err(&pdev->dev, "no memory resource defined\n"); | ||
| 185 | ret = -ENODEV; | ||
| 186 | goto err_free; | ||
| 187 | } | ||
| 188 | |||
| 189 | r = request_mem_region(r->start, resource_size(r), pdev->name); | ||
| 190 | if (r == NULL) { | ||
| 191 | dev_err(&pdev->dev, "failed to request memory resource\n"); | ||
| 192 | ret = -EBUSY; | ||
| 193 | goto err_free; | ||
| 194 | } | ||
| 195 | |||
| 196 | pwms[0].regbase = ioremap(r->start, resource_size(r)); | ||
| 197 | if (pwms[0].regbase == NULL) { | ||
| 198 | dev_err(&pdev->dev, "failed to ioremap() registers\n"); | ||
| 199 | ret = -ENODEV; | ||
| 200 | goto err_free_mem; | ||
| 201 | } | ||
| 202 | |||
| 203 | for (i = 1; i < VT8500_NR_PWMS; i++) | ||
| 204 | pwms[i].regbase = pwms[0].regbase; | ||
| 205 | |||
| 206 | for (i = 0; i < VT8500_NR_PWMS; i++) | ||
| 207 | __add_pwm(&pwms[i]); | ||
| 208 | |||
| 209 | platform_set_drvdata(pdev, pwms); | ||
| 210 | return 0; | ||
| 211 | |||
| 212 | err_free_mem: | ||
| 213 | release_mem_region(r->start, resource_size(r)); | ||
| 214 | err_free: | ||
| 215 | kfree(pwms); | ||
| 216 | return ret; | ||
| 217 | } | ||
| 218 | |||
| 219 | static int __devexit pwm_remove(struct platform_device *pdev) | ||
| 220 | { | ||
| 221 | struct pwm_device *pwms; | ||
| 222 | struct resource *r; | ||
| 223 | int i; | ||
| 224 | |||
| 225 | pwms = platform_get_drvdata(pdev); | ||
| 226 | if (pwms == NULL) | ||
| 227 | return -ENODEV; | ||
| 228 | |||
| 229 | mutex_lock(&pwm_lock); | ||
| 230 | |||
| 231 | for (i = 0; i < VT8500_NR_PWMS; i++) | ||
| 232 | list_del(&pwms[i].node); | ||
| 233 | mutex_unlock(&pwm_lock); | ||
| 234 | |||
| 235 | iounmap(pwms[0].regbase); | ||
| 236 | |||
| 237 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 238 | release_mem_region(r->start, resource_size(r)); | ||
| 239 | |||
| 240 | kfree(pwms); | ||
| 241 | return 0; | ||
| 242 | } | ||
| 243 | |||
| 244 | static struct platform_driver pwm_driver = { | ||
| 245 | .driver = { | ||
| 246 | .name = "vt8500-pwm", | ||
| 247 | .owner = THIS_MODULE, | ||
| 248 | }, | ||
| 249 | .probe = pwm_probe, | ||
| 250 | .remove = __devexit_p(pwm_remove), | ||
| 251 | }; | ||
| 252 | |||
| 253 | static int __init pwm_init(void) | ||
| 254 | { | ||
| 255 | return platform_driver_register(&pwm_driver); | ||
| 256 | } | ||
| 257 | arch_initcall(pwm_init); | ||
| 258 | |||
| 259 | static void __exit pwm_exit(void) | ||
| 260 | { | ||
| 261 | platform_driver_unregister(&pwm_driver); | ||
| 262 | } | ||
| 263 | module_exit(pwm_exit); | ||
| 264 | |||
| 265 | MODULE_LICENSE("GPL"); | ||
diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c index 806cc4f63516..119bc52ab93e 100644 --- a/arch/arm/mm/context.c +++ b/arch/arm/mm/context.c | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include <linux/percpu.h> | 14 | #include <linux/percpu.h> |
| 15 | 15 | ||
| 16 | #include <asm/mmu_context.h> | 16 | #include <asm/mmu_context.h> |
| 17 | #include <asm/thread_notify.h> | ||
| 17 | #include <asm/tlbflush.h> | 18 | #include <asm/tlbflush.h> |
| 18 | 19 | ||
| 19 | static DEFINE_RAW_SPINLOCK(cpu_asid_lock); | 20 | static DEFINE_RAW_SPINLOCK(cpu_asid_lock); |
| @@ -48,6 +49,40 @@ void cpu_set_reserved_ttbr0(void) | |||
| 48 | } | 49 | } |
| 49 | #endif | 50 | #endif |
| 50 | 51 | ||
| 52 | #ifdef CONFIG_PID_IN_CONTEXTIDR | ||
| 53 | static int contextidr_notifier(struct notifier_block *unused, unsigned long cmd, | ||
| 54 | void *t) | ||
| 55 | { | ||
| 56 | u32 contextidr; | ||
| 57 | pid_t pid; | ||
| 58 | struct thread_info *thread = t; | ||
| 59 | |||
| 60 | if (cmd != THREAD_NOTIFY_SWITCH) | ||
| 61 | return NOTIFY_DONE; | ||
| 62 | |||
| 63 | pid = task_pid_nr(thread->task) << ASID_BITS; | ||
| 64 | asm volatile( | ||
| 65 | " mrc p15, 0, %0, c13, c0, 1\n" | ||
| 66 | " bfi %1, %0, #0, %2\n" | ||
| 67 | " mcr p15, 0, %1, c13, c0, 1\n" | ||
| 68 | : "=r" (contextidr), "+r" (pid) | ||
| 69 | : "I" (ASID_BITS)); | ||
| 70 | isb(); | ||
| 71 | |||
| 72 | return NOTIFY_OK; | ||
| 73 | } | ||
| 74 | |||
| 75 | static struct notifier_block contextidr_notifier_block = { | ||
| 76 | .notifier_call = contextidr_notifier, | ||
| 77 | }; | ||
| 78 | |||
| 79 | static int __init contextidr_notifier_init(void) | ||
| 80 | { | ||
| 81 | return thread_register_notifier(&contextidr_notifier_block); | ||
| 82 | } | ||
| 83 | arch_initcall(contextidr_notifier_init); | ||
| 84 | #endif | ||
| 85 | |||
| 51 | /* | 86 | /* |
| 52 | * We fork()ed a process, and we need a new context for the child | 87 | * We fork()ed a process, and we need a new context for the child |
| 53 | * to run in. | 88 | * to run in. |
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 655878bcc96d..c2cdf6500f75 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c | |||
| @@ -22,13 +22,14 @@ | |||
| 22 | #include <linux/memblock.h> | 22 | #include <linux/memblock.h> |
| 23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
| 24 | #include <linux/iommu.h> | 24 | #include <linux/iommu.h> |
| 25 | #include <linux/io.h> | ||
| 25 | #include <linux/vmalloc.h> | 26 | #include <linux/vmalloc.h> |
| 27 | #include <linux/sizes.h> | ||
| 26 | 28 | ||
| 27 | #include <asm/memory.h> | 29 | #include <asm/memory.h> |
| 28 | #include <asm/highmem.h> | 30 | #include <asm/highmem.h> |
| 29 | #include <asm/cacheflush.h> | 31 | #include <asm/cacheflush.h> |
| 30 | #include <asm/tlbflush.h> | 32 | #include <asm/tlbflush.h> |
| 31 | #include <asm/sizes.h> | ||
| 32 | #include <asm/mach/arch.h> | 33 | #include <asm/mach/arch.h> |
| 33 | #include <asm/dma-iommu.h> | 34 | #include <asm/dma-iommu.h> |
| 34 | #include <asm/mach/map.h> | 35 | #include <asm/mach/map.h> |
| @@ -72,7 +73,7 @@ static dma_addr_t arm_dma_map_page(struct device *dev, struct page *page, | |||
| 72 | unsigned long offset, size_t size, enum dma_data_direction dir, | 73 | unsigned long offset, size_t size, enum dma_data_direction dir, |
| 73 | struct dma_attrs *attrs) | 74 | struct dma_attrs *attrs) |
| 74 | { | 75 | { |
| 75 | if (!arch_is_coherent()) | 76 | if (!arch_is_coherent() && !dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs)) |
| 76 | __dma_page_cpu_to_dev(page, offset, size, dir); | 77 | __dma_page_cpu_to_dev(page, offset, size, dir); |
| 77 | return pfn_to_dma(dev, page_to_pfn(page)) + offset; | 78 | return pfn_to_dma(dev, page_to_pfn(page)) + offset; |
| 78 | } | 79 | } |
| @@ -95,7 +96,7 @@ static void arm_dma_unmap_page(struct device *dev, dma_addr_t handle, | |||
| 95 | size_t size, enum dma_data_direction dir, | 96 | size_t size, enum dma_data_direction dir, |
| 96 | struct dma_attrs *attrs) | 97 | struct dma_attrs *attrs) |
| 97 | { | 98 | { |
| 98 | if (!arch_is_coherent()) | 99 | if (!arch_is_coherent() && !dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs)) |
| 99 | __dma_page_dev_to_cpu(pfn_to_page(dma_to_pfn(dev, handle)), | 100 | __dma_page_dev_to_cpu(pfn_to_page(dma_to_pfn(dev, handle)), |
| 100 | handle & ~PAGE_MASK, size, dir); | 101 | handle & ~PAGE_MASK, size, dir); |
| 101 | } | 102 | } |
| @@ -124,6 +125,7 @@ struct dma_map_ops arm_dma_ops = { | |||
| 124 | .alloc = arm_dma_alloc, | 125 | .alloc = arm_dma_alloc, |
| 125 | .free = arm_dma_free, | 126 | .free = arm_dma_free, |
| 126 | .mmap = arm_dma_mmap, | 127 | .mmap = arm_dma_mmap, |
| 128 | .get_sgtable = arm_dma_get_sgtable, | ||
| 127 | .map_page = arm_dma_map_page, | 129 | .map_page = arm_dma_map_page, |
| 128 | .unmap_page = arm_dma_unmap_page, | 130 | .unmap_page = arm_dma_unmap_page, |
| 129 | .map_sg = arm_dma_map_sg, | 131 | .map_sg = arm_dma_map_sg, |
| @@ -217,115 +219,70 @@ static void __dma_free_buffer(struct page *page, size_t size) | |||
| 217 | } | 219 | } |
| 218 | 220 | ||
| 219 | #ifdef CONFIG_MMU | 221 | #ifdef CONFIG_MMU |
| 222 | #ifdef CONFIG_HUGETLB_PAGE | ||
| 223 | #error ARM Coherent DMA allocator does not (yet) support huge TLB | ||
| 224 | #endif | ||
| 220 | 225 | ||
| 221 | #define CONSISTENT_OFFSET(x) (((unsigned long)(x) - consistent_base) >> PAGE_SHIFT) | 226 | static void *__alloc_from_contiguous(struct device *dev, size_t size, |
| 222 | #define CONSISTENT_PTE_INDEX(x) (((unsigned long)(x) - consistent_base) >> PMD_SHIFT) | 227 | pgprot_t prot, struct page **ret_page); |
| 223 | |||
| 224 | /* | ||
| 225 | * These are the page tables (2MB each) covering uncached, DMA consistent allocations | ||
| 226 | */ | ||
| 227 | static pte_t **consistent_pte; | ||
| 228 | |||
| 229 | #define DEFAULT_CONSISTENT_DMA_SIZE SZ_2M | ||
| 230 | 228 | ||
| 231 | static unsigned long consistent_base = CONSISTENT_END - DEFAULT_CONSISTENT_DMA_SIZE; | 229 | static void *__alloc_remap_buffer(struct device *dev, size_t size, gfp_t gfp, |
| 230 | pgprot_t prot, struct page **ret_page, | ||
| 231 | const void *caller); | ||
| 232 | 232 | ||
| 233 | void __init init_consistent_dma_size(unsigned long size) | 233 | static void * |
| 234 | __dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot, | ||
| 235 | const void *caller) | ||
| 234 | { | 236 | { |
| 235 | unsigned long base = CONSISTENT_END - ALIGN(size, SZ_2M); | 237 | struct vm_struct *area; |
| 238 | unsigned long addr; | ||
| 236 | 239 | ||
| 237 | BUG_ON(consistent_pte); /* Check we're called before DMA region init */ | 240 | /* |
| 238 | BUG_ON(base < VMALLOC_END); | 241 | * DMA allocation can be mapped to user space, so lets |
| 242 | * set VM_USERMAP flags too. | ||
| 243 | */ | ||
| 244 | area = get_vm_area_caller(size, VM_ARM_DMA_CONSISTENT | VM_USERMAP, | ||
| 245 | caller); | ||
| 246 | if (!area) | ||
| 247 | return NULL; | ||
| 248 | addr = (unsigned long)area->addr; | ||
| 249 | area->phys_addr = __pfn_to_phys(page_to_pfn(page)); | ||
| 239 | 250 | ||
| 240 | /* Grow region to accommodate specified size */ | 251 | if (ioremap_page_range(addr, addr + size, area->phys_addr, prot)) { |
| 241 | if (base < consistent_base) | 252 | vunmap((void *)addr); |
| 242 | consistent_base = base; | 253 | return NULL; |
| 254 | } | ||
| 255 | return (void *)addr; | ||
| 243 | } | 256 | } |
| 244 | 257 | ||
| 245 | #include "vmregion.h" | 258 | static void __dma_free_remap(void *cpu_addr, size_t size) |
| 246 | |||
| 247 | static struct arm_vmregion_head consistent_head = { | ||
| 248 | .vm_lock = __SPIN_LOCK_UNLOCKED(&consistent_head.vm_lock), | ||
| 249 | .vm_list = LIST_HEAD_INIT(consistent_head.vm_list), | ||
| 250 | .vm_end = CONSISTENT_END, | ||
| 251 | }; | ||
| 252 | |||
| 253 | #ifdef CONFIG_HUGETLB_PAGE | ||
| 254 | #error ARM Coherent DMA allocator does not (yet) support huge TLB | ||
| 255 | #endif | ||
| 256 | |||
| 257 | /* | ||
| 258 | * Initialise the consistent memory allocation. | ||
| 259 | */ | ||
| 260 | static int __init consistent_init(void) | ||
| 261 | { | 259 | { |
| 262 | int ret = 0; | 260 | unsigned int flags = VM_ARM_DMA_CONSISTENT | VM_USERMAP; |
| 263 | pgd_t *pgd; | 261 | struct vm_struct *area = find_vm_area(cpu_addr); |
| 264 | pud_t *pud; | 262 | if (!area || (area->flags & flags) != flags) { |
| 265 | pmd_t *pmd; | 263 | WARN(1, "trying to free invalid coherent area: %p\n", cpu_addr); |
| 266 | pte_t *pte; | 264 | return; |
| 267 | int i = 0; | ||
| 268 | unsigned long base = consistent_base; | ||
| 269 | unsigned long num_ptes = (CONSISTENT_END - base) >> PMD_SHIFT; | ||
| 270 | |||
| 271 | if (IS_ENABLED(CONFIG_CMA) && !IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)) | ||
| 272 | return 0; | ||
| 273 | |||
| 274 | consistent_pte = kmalloc(num_ptes * sizeof(pte_t), GFP_KERNEL); | ||
| 275 | if (!consistent_pte) { | ||
| 276 | pr_err("%s: no memory\n", __func__); | ||
| 277 | return -ENOMEM; | ||
| 278 | } | 265 | } |
| 279 | 266 | unmap_kernel_range((unsigned long)cpu_addr, size); | |
| 280 | pr_debug("DMA memory: 0x%08lx - 0x%08lx:\n", base, CONSISTENT_END); | 267 | vunmap(cpu_addr); |
| 281 | consistent_head.vm_start = base; | ||
| 282 | |||
| 283 | do { | ||
| 284 | pgd = pgd_offset(&init_mm, base); | ||
| 285 | |||
| 286 | pud = pud_alloc(&init_mm, pgd, base); | ||
| 287 | if (!pud) { | ||
| 288 | pr_err("%s: no pud tables\n", __func__); | ||
| 289 | ret = -ENOMEM; | ||
| 290 | break; | ||
| 291 | } | ||
| 292 | |||
| 293 | pmd = pmd_alloc(&init_mm, pud, base); | ||
| 294 | if (!pmd) { | ||
| 295 | pr_err("%s: no pmd tables\n", __func__); | ||
| 296 | ret = -ENOMEM; | ||
| 297 | break; | ||
| 298 | } | ||
| 299 | WARN_ON(!pmd_none(*pmd)); | ||
| 300 | |||
| 301 | pte = pte_alloc_kernel(pmd, base); | ||
| 302 | if (!pte) { | ||
| 303 | pr_err("%s: no pte tables\n", __func__); | ||
| 304 | ret = -ENOMEM; | ||
| 305 | break; | ||
| 306 | } | ||
| 307 | |||
| 308 | consistent_pte[i++] = pte; | ||
| 309 | base += PMD_SIZE; | ||
| 310 | } while (base < CONSISTENT_END); | ||
| 311 | |||
| 312 | return ret; | ||
| 313 | } | 268 | } |
| 314 | core_initcall(consistent_init); | ||
| 315 | 269 | ||
| 316 | static void *__alloc_from_contiguous(struct device *dev, size_t size, | 270 | struct dma_pool { |
| 317 | pgprot_t prot, struct page **ret_page); | 271 | size_t size; |
| 318 | 272 | spinlock_t lock; | |
| 319 | static struct arm_vmregion_head coherent_head = { | 273 | unsigned long *bitmap; |
| 320 | .vm_lock = __SPIN_LOCK_UNLOCKED(&coherent_head.vm_lock), | 274 | unsigned long nr_pages; |
| 321 | .vm_list = LIST_HEAD_INIT(coherent_head.vm_list), | 275 | void *vaddr; |
| 276 | struct page *page; | ||
| 322 | }; | 277 | }; |
| 323 | 278 | ||
| 324 | static size_t coherent_pool_size = DEFAULT_CONSISTENT_DMA_SIZE / 8; | 279 | static struct dma_pool atomic_pool = { |
| 280 | .size = SZ_256K, | ||
| 281 | }; | ||
| 325 | 282 | ||
| 326 | static int __init early_coherent_pool(char *p) | 283 | static int __init early_coherent_pool(char *p) |
| 327 | { | 284 | { |
| 328 | coherent_pool_size = memparse(p, &p); | 285 | atomic_pool.size = memparse(p, &p); |
| 329 | return 0; | 286 | return 0; |
| 330 | } | 287 | } |
| 331 | early_param("coherent_pool", early_coherent_pool); | 288 | early_param("coherent_pool", early_coherent_pool); |
| @@ -333,32 +290,45 @@ early_param("coherent_pool", early_coherent_pool); | |||
| 333 | /* | 290 | /* |
| 334 | * Initialise the coherent pool for atomic allocations. | 291 | * Initialise the coherent pool for atomic allocations. |
| 335 | */ | 292 | */ |
| 336 | static int __init coherent_init(void) | 293 | static int __init atomic_pool_init(void) |
| 337 | { | 294 | { |
| 295 | struct dma_pool *pool = &atomic_pool; | ||
| 338 | pgprot_t prot = pgprot_dmacoherent(pgprot_kernel); | 296 | pgprot_t prot = pgprot_dmacoherent(pgprot_kernel); |
| 339 | size_t size = coherent_pool_size; | 297 | unsigned long nr_pages = pool->size >> PAGE_SHIFT; |
| 298 | unsigned long *bitmap; | ||
| 340 | struct page *page; | 299 | struct page *page; |
| 341 | void *ptr; | 300 | void *ptr; |
| 301 | int bitmap_size = BITS_TO_LONGS(nr_pages) * sizeof(long); | ||
| 342 | 302 | ||
| 343 | if (!IS_ENABLED(CONFIG_CMA)) | 303 | bitmap = kzalloc(bitmap_size, GFP_KERNEL); |
| 344 | return 0; | 304 | if (!bitmap) |
| 305 | goto no_bitmap; | ||
| 345 | 306 | ||
| 346 | ptr = __alloc_from_contiguous(NULL, size, prot, &page); | 307 | if (IS_ENABLED(CONFIG_CMA)) |
| 308 | ptr = __alloc_from_contiguous(NULL, pool->size, prot, &page); | ||
| 309 | else | ||
| 310 | ptr = __alloc_remap_buffer(NULL, pool->size, GFP_KERNEL, prot, | ||
| 311 | &page, NULL); | ||
| 347 | if (ptr) { | 312 | if (ptr) { |
| 348 | coherent_head.vm_start = (unsigned long) ptr; | 313 | spin_lock_init(&pool->lock); |
| 349 | coherent_head.vm_end = (unsigned long) ptr + size; | 314 | pool->vaddr = ptr; |
| 350 | printk(KERN_INFO "DMA: preallocated %u KiB pool for atomic coherent allocations\n", | 315 | pool->page = page; |
| 351 | (unsigned)size / 1024); | 316 | pool->bitmap = bitmap; |
| 317 | pool->nr_pages = nr_pages; | ||
| 318 | pr_info("DMA: preallocated %u KiB pool for atomic coherent allocations\n", | ||
| 319 | (unsigned)pool->size / 1024); | ||
| 352 | return 0; | 320 | return 0; |
| 353 | } | 321 | } |
| 354 | printk(KERN_ERR "DMA: failed to allocate %u KiB pool for atomic coherent allocation\n", | 322 | kfree(bitmap); |
| 355 | (unsigned)size / 1024); | 323 | no_bitmap: |
| 324 | pr_err("DMA: failed to allocate %u KiB pool for atomic coherent allocation\n", | ||
| 325 | (unsigned)pool->size / 1024); | ||
| 356 | return -ENOMEM; | 326 | return -ENOMEM; |
| 357 | } | 327 | } |
| 358 | /* | 328 | /* |
| 359 | * CMA is activated by core_initcall, so we must be called after it. | 329 | * CMA is activated by core_initcall, so we must be called after it. |
| 360 | */ | 330 | */ |
| 361 | postcore_initcall(coherent_init); | 331 | postcore_initcall(atomic_pool_init); |
| 362 | 332 | ||
| 363 | struct dma_contig_early_reserve { | 333 | struct dma_contig_early_reserve { |
| 364 | phys_addr_t base; | 334 | phys_addr_t base; |
| @@ -406,112 +376,6 @@ void __init dma_contiguous_remap(void) | |||
| 406 | } | 376 | } |
| 407 | } | 377 | } |
| 408 | 378 | ||
| 409 | static void * | ||
| 410 | __dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot, | ||
| 411 | const void *caller) | ||
| 412 | { | ||
| 413 | struct arm_vmregion *c; | ||
| 414 | size_t align; | ||
| 415 | int bit; | ||
| 416 | |||
| 417 | if (!consistent_pte) { | ||
| 418 | pr_err("%s: not initialised\n", __func__); | ||
| 419 | dump_stack(); | ||
| 420 | return NULL; | ||
| 421 | } | ||
| 422 | |||
| 423 | /* | ||
| 424 | * Align the virtual region allocation - maximum alignment is | ||
| 425 | * a section size, minimum is a page size. This helps reduce | ||
| 426 | * fragmentation of the DMA space, and also prevents allocations | ||
| 427 | * smaller than a section from crossing a section boundary. | ||
| 428 | */ | ||
| 429 | bit = fls(size - 1); | ||
| 430 | if (bit > SECTION_SHIFT) | ||
| 431 | bit = SECTION_SHIFT; | ||
| 432 | align = 1 << bit; | ||
| 433 | |||
| 434 | /* | ||
| 435 | * Allocate a virtual address in the consistent mapping region. | ||
| 436 | */ | ||
| 437 | c = arm_vmregion_alloc(&consistent_head, align, size, | ||
| 438 | gfp & ~(__GFP_DMA | __GFP_HIGHMEM), caller); | ||
| 439 | if (c) { | ||
| 440 | pte_t *pte; | ||
| 441 | int idx = CONSISTENT_PTE_INDEX(c->vm_start); | ||
| 442 | u32 off = CONSISTENT_OFFSET(c->vm_start) & (PTRS_PER_PTE-1); | ||
| 443 | |||
| 444 | pte = consistent_pte[idx] + off; | ||
| 445 | c->priv = page; | ||
| 446 | |||
| 447 | do { | ||
| 448 | BUG_ON(!pte_none(*pte)); | ||
| 449 | |||
| 450 | set_pte_ext(pte, mk_pte(page, prot), 0); | ||
| 451 | page++; | ||
| 452 | pte++; | ||
| 453 | off++; | ||
| 454 | if (off >= PTRS_PER_PTE) { | ||
| 455 | off = 0; | ||
| 456 | pte = consistent_pte[++idx]; | ||
| 457 | } | ||
| 458 | } while (size -= PAGE_SIZE); | ||
| 459 | |||
| 460 | dsb(); | ||
| 461 | |||
| 462 | return (void *)c->vm_start; | ||
| 463 | } | ||
| 464 | return NULL; | ||
| 465 | } | ||
| 466 | |||
| 467 | static void __dma_free_remap(void *cpu_addr, size_t size) | ||
| 468 | { | ||
| 469 | struct arm_vmregion *c; | ||
| 470 | unsigned long addr; | ||
| 471 | pte_t *ptep; | ||
| 472 | int idx; | ||
| 473 | u32 off; | ||
| 474 | |||
| 475 | c = arm_vmregion_find_remove(&consistent_head, (unsigned long)cpu_addr); | ||
| 476 | if (!c) { | ||
| 477 | pr_err("%s: trying to free invalid coherent area: %p\n", | ||
| 478 | __func__, cpu_addr); | ||
| 479 | dump_stack(); | ||
| 480 | return; | ||
| 481 | } | ||
| 482 | |||
| 483 | if ((c->vm_end - c->vm_start) != size) { | ||
| 484 | pr_err("%s: freeing wrong coherent size (%ld != %d)\n", | ||
| 485 | __func__, c->vm_end - c->vm_start, size); | ||
| 486 | dump_stack(); | ||
| 487 | size = c->vm_end - c->vm_start; | ||
| 488 | } | ||
| 489 | |||
| 490 | idx = CONSISTENT_PTE_INDEX(c->vm_start); | ||
| 491 | off = CONSISTENT_OFFSET(c->vm_start) & (PTRS_PER_PTE-1); | ||
| 492 | ptep = consistent_pte[idx] + off; | ||
| 493 | addr = c->vm_start; | ||
| 494 | do { | ||
| 495 | pte_t pte = ptep_get_and_clear(&init_mm, addr, ptep); | ||
| 496 | |||
| 497 | ptep++; | ||
| 498 | addr += PAGE_SIZE; | ||
| 499 | off++; | ||
| 500 | if (off >= PTRS_PER_PTE) { | ||
| 501 | off = 0; | ||
| 502 | ptep = consistent_pte[++idx]; | ||
| 503 | } | ||
| 504 | |||
| 505 | if (pte_none(pte) || !pte_present(pte)) | ||
| 506 | pr_crit("%s: bad page in kernel page table\n", | ||
| 507 | __func__); | ||
| 508 | } while (size -= PAGE_SIZE); | ||
| 509 | |||
| 510 | flush_tlb_kernel_range(c->vm_start, c->vm_end); | ||
| 511 | |||
| 512 | arm_vmregion_free(&consistent_head, c); | ||
| 513 | } | ||
| 514 | |||
| 515 | static int __dma_update_pte(pte_t *pte, pgtable_t token, unsigned long addr, | 379 | static int __dma_update_pte(pte_t *pte, pgtable_t token, unsigned long addr, |
| 516 | void *data) | 380 | void *data) |
| 517 | { | 381 | { |
| @@ -552,16 +416,17 @@ static void *__alloc_remap_buffer(struct device *dev, size_t size, gfp_t gfp, | |||
| 552 | return ptr; | 416 | return ptr; |
| 553 | } | 417 | } |
| 554 | 418 | ||
| 555 | static void *__alloc_from_pool(struct device *dev, size_t size, | 419 | static void *__alloc_from_pool(size_t size, struct page **ret_page) |
| 556 | struct page **ret_page, const void *caller) | ||
| 557 | { | 420 | { |
| 558 | struct arm_vmregion *c; | 421 | struct dma_pool *pool = &atomic_pool; |
| 422 | unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT; | ||
| 423 | unsigned int pageno; | ||
| 424 | unsigned long flags; | ||
| 425 | void *ptr = NULL; | ||
| 559 | size_t align; | 426 | size_t align; |
| 560 | 427 | ||
| 561 | if (!coherent_head.vm_start) { | 428 | if (!pool->vaddr) { |
| 562 | printk(KERN_ERR "%s: coherent pool not initialised!\n", | 429 | WARN(1, "coherent pool not initialised!\n"); |
| 563 | __func__); | ||
| 564 | dump_stack(); | ||
| 565 | return NULL; | 430 | return NULL; |
| 566 | } | 431 | } |
| 567 | 432 | ||
| @@ -571,35 +436,41 @@ static void *__alloc_from_pool(struct device *dev, size_t size, | |||
| 571 | * size. This helps reduce fragmentation of the DMA space. | 436 | * size. This helps reduce fragmentation of the DMA space. |
| 572 | */ | 437 | */ |
| 573 | align = PAGE_SIZE << get_order(size); | 438 | align = PAGE_SIZE << get_order(size); |
| 574 | c = arm_vmregion_alloc(&coherent_head, align, size, 0, caller); | 439 | |
| 575 | if (c) { | 440 | spin_lock_irqsave(&pool->lock, flags); |
| 576 | void *ptr = (void *)c->vm_start; | 441 | pageno = bitmap_find_next_zero_area(pool->bitmap, pool->nr_pages, |
| 577 | struct page *page = virt_to_page(ptr); | 442 | 0, count, (1 << align) - 1); |
| 578 | *ret_page = page; | 443 | if (pageno < pool->nr_pages) { |
| 579 | return ptr; | 444 | bitmap_set(pool->bitmap, pageno, count); |
| 445 | ptr = pool->vaddr + PAGE_SIZE * pageno; | ||
| 446 | *ret_page = pool->page + pageno; | ||
| 580 | } | 447 | } |
| 581 | return NULL; | 448 | spin_unlock_irqrestore(&pool->lock, flags); |
| 449 | |||
| 450 | return ptr; | ||
| 582 | } | 451 | } |
| 583 | 452 | ||
| 584 | static int __free_from_pool(void *cpu_addr, size_t size) | 453 | static int __free_from_pool(void *start, size_t size) |
| 585 | { | 454 | { |
| 586 | unsigned long start = (unsigned long)cpu_addr; | 455 | struct dma_pool *pool = &atomic_pool; |
| 587 | unsigned long end = start + size; | 456 | unsigned long pageno, count; |
| 588 | struct arm_vmregion *c; | 457 | unsigned long flags; |
| 589 | 458 | ||
| 590 | if (start < coherent_head.vm_start || end > coherent_head.vm_end) | 459 | if (start < pool->vaddr || start > pool->vaddr + pool->size) |
| 591 | return 0; | 460 | return 0; |
| 592 | 461 | ||
| 593 | c = arm_vmregion_find_remove(&coherent_head, (unsigned long)start); | 462 | if (start + size > pool->vaddr + pool->size) { |
| 594 | 463 | WARN(1, "freeing wrong coherent size from pool\n"); | |
| 595 | if ((c->vm_end - c->vm_start) != size) { | 464 | return 0; |
| 596 | printk(KERN_ERR "%s: freeing wrong coherent size (%ld != %d)\n", | ||
| 597 | __func__, c->vm_end - c->vm_start, size); | ||
| 598 | dump_stack(); | ||
| 599 | size = c->vm_end - c->vm_start; | ||
| 600 | } | 465 | } |
| 601 | 466 | ||
| 602 | arm_vmregion_free(&coherent_head, c); | 467 | pageno = (start - pool->vaddr) >> PAGE_SHIFT; |
| 468 | count = size >> PAGE_SHIFT; | ||
| 469 | |||
| 470 | spin_lock_irqsave(&pool->lock, flags); | ||
| 471 | bitmap_clear(pool->bitmap, pageno, count); | ||
| 472 | spin_unlock_irqrestore(&pool->lock, flags); | ||
| 473 | |||
| 603 | return 1; | 474 | return 1; |
| 604 | } | 475 | } |
| 605 | 476 | ||
| @@ -644,7 +515,7 @@ static inline pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t prot) | |||
| 644 | 515 | ||
| 645 | #define __get_dma_pgprot(attrs, prot) __pgprot(0) | 516 | #define __get_dma_pgprot(attrs, prot) __pgprot(0) |
| 646 | #define __alloc_remap_buffer(dev, size, gfp, prot, ret, c) NULL | 517 | #define __alloc_remap_buffer(dev, size, gfp, prot, ret, c) NULL |
| 647 | #define __alloc_from_pool(dev, size, ret_page, c) NULL | 518 | #define __alloc_from_pool(size, ret_page) NULL |
| 648 | #define __alloc_from_contiguous(dev, size, prot, ret) NULL | 519 | #define __alloc_from_contiguous(dev, size, prot, ret) NULL |
| 649 | #define __free_from_pool(cpu_addr, size) 0 | 520 | #define __free_from_pool(cpu_addr, size) 0 |
| 650 | #define __free_from_contiguous(dev, page, size) do { } while (0) | 521 | #define __free_from_contiguous(dev, page, size) do { } while (0) |
| @@ -702,10 +573,10 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, | |||
| 702 | 573 | ||
| 703 | if (arch_is_coherent() || nommu()) | 574 | if (arch_is_coherent() || nommu()) |
| 704 | addr = __alloc_simple_buffer(dev, size, gfp, &page); | 575 | addr = __alloc_simple_buffer(dev, size, gfp, &page); |
| 576 | else if (gfp & GFP_ATOMIC) | ||
| 577 | addr = __alloc_from_pool(size, &page); | ||
| 705 | else if (!IS_ENABLED(CONFIG_CMA)) | 578 | else if (!IS_ENABLED(CONFIG_CMA)) |
| 706 | addr = __alloc_remap_buffer(dev, size, gfp, prot, &page, caller); | 579 | addr = __alloc_remap_buffer(dev, size, gfp, prot, &page, caller); |
| 707 | else if (gfp & GFP_ATOMIC) | ||
| 708 | addr = __alloc_from_pool(dev, size, &page, caller); | ||
| 709 | else | 580 | else |
| 710 | addr = __alloc_from_contiguous(dev, size, prot, &page); | 581 | addr = __alloc_from_contiguous(dev, size, prot, &page); |
| 711 | 582 | ||
| @@ -741,16 +612,22 @@ int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma, | |||
| 741 | { | 612 | { |
| 742 | int ret = -ENXIO; | 613 | int ret = -ENXIO; |
| 743 | #ifdef CONFIG_MMU | 614 | #ifdef CONFIG_MMU |
| 615 | unsigned long nr_vma_pages = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; | ||
| 616 | unsigned long nr_pages = PAGE_ALIGN(size) >> PAGE_SHIFT; | ||
| 744 | unsigned long pfn = dma_to_pfn(dev, dma_addr); | 617 | unsigned long pfn = dma_to_pfn(dev, dma_addr); |
| 618 | unsigned long off = vma->vm_pgoff; | ||
| 619 | |||
| 745 | vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot); | 620 | vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot); |
| 746 | 621 | ||
| 747 | if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret)) | 622 | if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret)) |
| 748 | return ret; | 623 | return ret; |
| 749 | 624 | ||
| 750 | ret = remap_pfn_range(vma, vma->vm_start, | 625 | if (off < nr_pages && nr_vma_pages <= (nr_pages - off)) { |
| 751 | pfn + vma->vm_pgoff, | 626 | ret = remap_pfn_range(vma, vma->vm_start, |
| 752 | vma->vm_end - vma->vm_start, | 627 | pfn + off, |
| 753 | vma->vm_page_prot); | 628 | vma->vm_end - vma->vm_start, |
| 629 | vma->vm_page_prot); | ||
| 630 | } | ||
| 754 | #endif /* CONFIG_MMU */ | 631 | #endif /* CONFIG_MMU */ |
| 755 | 632 | ||
| 756 | return ret; | 633 | return ret; |
| @@ -785,6 +662,21 @@ void arm_dma_free(struct device *dev, size_t size, void *cpu_addr, | |||
| 785 | } | 662 | } |
| 786 | } | 663 | } |
| 787 | 664 | ||
| 665 | int arm_dma_get_sgtable(struct device *dev, struct sg_table *sgt, | ||
| 666 | void *cpu_addr, dma_addr_t handle, size_t size, | ||
| 667 | struct dma_attrs *attrs) | ||
| 668 | { | ||
| 669 | struct page *page = pfn_to_page(dma_to_pfn(dev, handle)); | ||
| 670 | int ret; | ||
| 671 | |||
| 672 | ret = sg_alloc_table(sgt, 1, GFP_KERNEL); | ||
| 673 | if (unlikely(ret)) | ||
| 674 | return ret; | ||
| 675 | |||
| 676 | sg_set_page(sgt->sgl, page, PAGE_ALIGN(size), 0); | ||
| 677 | return 0; | ||
| 678 | } | ||
| 679 | |||
| 788 | static void dma_cache_maint_page(struct page *page, unsigned long offset, | 680 | static void dma_cache_maint_page(struct page *page, unsigned long offset, |
| 789 | size_t size, enum dma_data_direction dir, | 681 | size_t size, enum dma_data_direction dir, |
| 790 | void (*op)(const void *, size_t, int)) | 682 | void (*op)(const void *, size_t, int)) |
| @@ -998,9 +890,6 @@ static int arm_dma_set_mask(struct device *dev, u64 dma_mask) | |||
| 998 | 890 | ||
| 999 | static int __init dma_debug_do_init(void) | 891 | static int __init dma_debug_do_init(void) |
| 1000 | { | 892 | { |
| 1001 | #ifdef CONFIG_MMU | ||
| 1002 | arm_vmregion_create_proc("dma-mappings", &consistent_head); | ||
| 1003 | #endif | ||
| 1004 | dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES); | 893 | dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES); |
| 1005 | return 0; | 894 | return 0; |
| 1006 | } | 895 | } |
| @@ -1088,7 +977,7 @@ static struct page **__iommu_alloc_buffer(struct device *dev, size_t size, gfp_t | |||
| 1088 | 977 | ||
| 1089 | return pages; | 978 | return pages; |
| 1090 | error: | 979 | error: |
| 1091 | while (--i) | 980 | while (i--) |
| 1092 | if (pages[i]) | 981 | if (pages[i]) |
| 1093 | __free_pages(pages[i], 0); | 982 | __free_pages(pages[i], 0); |
| 1094 | if (array_size <= PAGE_SIZE) | 983 | if (array_size <= PAGE_SIZE) |
| @@ -1117,61 +1006,32 @@ static int __iommu_free_buffer(struct device *dev, struct page **pages, size_t s | |||
| 1117 | * Create a CPU mapping for a specified pages | 1006 | * Create a CPU mapping for a specified pages |
| 1118 | */ | 1007 | */ |
| 1119 | static void * | 1008 | static void * |
| 1120 | __iommu_alloc_remap(struct page **pages, size_t size, gfp_t gfp, pgprot_t prot) | 1009 | __iommu_alloc_remap(struct page **pages, size_t size, gfp_t gfp, pgprot_t prot, |
| 1010 | const void *caller) | ||
| 1121 | { | 1011 | { |
| 1122 | struct arm_vmregion *c; | 1012 | unsigned int i, nr_pages = PAGE_ALIGN(size) >> PAGE_SHIFT; |
| 1123 | size_t align; | 1013 | struct vm_struct *area; |
| 1124 | size_t count = size >> PAGE_SHIFT; | 1014 | unsigned long p; |
| 1125 | int bit; | ||
| 1126 | 1015 | ||
| 1127 | if (!consistent_pte[0]) { | 1016 | area = get_vm_area_caller(size, VM_ARM_DMA_CONSISTENT | VM_USERMAP, |
| 1128 | pr_err("%s: not initialised\n", __func__); | 1017 | caller); |
| 1129 | dump_stack(); | 1018 | if (!area) |
| 1130 | return NULL; | 1019 | return NULL; |
| 1131 | } | ||
| 1132 | |||
| 1133 | /* | ||
| 1134 | * Align the virtual region allocation - maximum alignment is | ||
| 1135 | * a section size, minimum is a page size. This helps reduce | ||
| 1136 | * fragmentation of the DMA space, and also prevents allocations | ||
| 1137 | * smaller than a section from crossing a section boundary. | ||
| 1138 | */ | ||
| 1139 | bit = fls(size - 1); | ||
| 1140 | if (bit > SECTION_SHIFT) | ||
| 1141 | bit = SECTION_SHIFT; | ||
| 1142 | align = 1 << bit; | ||
| 1143 | |||
| 1144 | /* | ||
| 1145 | * Allocate a virtual address in the consistent mapping region. | ||
| 1146 | */ | ||
| 1147 | c = arm_vmregion_alloc(&consistent_head, align, size, | ||
| 1148 | gfp & ~(__GFP_DMA | __GFP_HIGHMEM), NULL); | ||
| 1149 | if (c) { | ||
| 1150 | pte_t *pte; | ||
| 1151 | int idx = CONSISTENT_PTE_INDEX(c->vm_start); | ||
| 1152 | int i = 0; | ||
| 1153 | u32 off = CONSISTENT_OFFSET(c->vm_start) & (PTRS_PER_PTE-1); | ||
| 1154 | |||
| 1155 | pte = consistent_pte[idx] + off; | ||
| 1156 | c->priv = pages; | ||
| 1157 | |||
| 1158 | do { | ||
| 1159 | BUG_ON(!pte_none(*pte)); | ||
| 1160 | |||
| 1161 | set_pte_ext(pte, mk_pte(pages[i], prot), 0); | ||
| 1162 | pte++; | ||
| 1163 | off++; | ||
| 1164 | i++; | ||
| 1165 | if (off >= PTRS_PER_PTE) { | ||
| 1166 | off = 0; | ||
| 1167 | pte = consistent_pte[++idx]; | ||
| 1168 | } | ||
| 1169 | } while (i < count); | ||
| 1170 | 1020 | ||
| 1171 | dsb(); | 1021 | area->pages = pages; |
| 1022 | area->nr_pages = nr_pages; | ||
| 1023 | p = (unsigned long)area->addr; | ||
| 1172 | 1024 | ||
| 1173 | return (void *)c->vm_start; | 1025 | for (i = 0; i < nr_pages; i++) { |
| 1026 | phys_addr_t phys = __pfn_to_phys(page_to_pfn(pages[i])); | ||
| 1027 | if (ioremap_page_range(p, p + PAGE_SIZE, phys, prot)) | ||
| 1028 | goto err; | ||
| 1029 | p += PAGE_SIZE; | ||
| 1174 | } | 1030 | } |
| 1031 | return area->addr; | ||
| 1032 | err: | ||
| 1033 | unmap_kernel_range((unsigned long)area->addr, size); | ||
| 1034 | vunmap(area->addr); | ||
| 1175 | return NULL; | 1035 | return NULL; |
| 1176 | } | 1036 | } |
| 1177 | 1037 | ||
| @@ -1230,6 +1090,19 @@ static int __iommu_remove_mapping(struct device *dev, dma_addr_t iova, size_t si | |||
| 1230 | return 0; | 1090 | return 0; |
| 1231 | } | 1091 | } |
| 1232 | 1092 | ||
| 1093 | static struct page **__iommu_get_pages(void *cpu_addr, struct dma_attrs *attrs) | ||
| 1094 | { | ||
| 1095 | struct vm_struct *area; | ||
| 1096 | |||
| 1097 | if (dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs)) | ||
| 1098 | return cpu_addr; | ||
| 1099 | |||
| 1100 | area = find_vm_area(cpu_addr); | ||
| 1101 | if (area && (area->flags & VM_ARM_DMA_CONSISTENT)) | ||
| 1102 | return area->pages; | ||
| 1103 | return NULL; | ||
| 1104 | } | ||
| 1105 | |||
| 1233 | static void *arm_iommu_alloc_attrs(struct device *dev, size_t size, | 1106 | static void *arm_iommu_alloc_attrs(struct device *dev, size_t size, |
| 1234 | dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs) | 1107 | dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs) |
| 1235 | { | 1108 | { |
| @@ -1248,7 +1121,11 @@ static void *arm_iommu_alloc_attrs(struct device *dev, size_t size, | |||
| 1248 | if (*handle == DMA_ERROR_CODE) | 1121 | if (*handle == DMA_ERROR_CODE) |
| 1249 | goto err_buffer; | 1122 | goto err_buffer; |
| 1250 | 1123 | ||
| 1251 | addr = __iommu_alloc_remap(pages, size, gfp, prot); | 1124 | if (dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs)) |
| 1125 | return pages; | ||
| 1126 | |||
| 1127 | addr = __iommu_alloc_remap(pages, size, gfp, prot, | ||
| 1128 | __builtin_return_address(0)); | ||
| 1252 | if (!addr) | 1129 | if (!addr) |
| 1253 | goto err_mapping; | 1130 | goto err_mapping; |
| 1254 | 1131 | ||
| @@ -1265,31 +1142,25 @@ static int arm_iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma, | |||
| 1265 | void *cpu_addr, dma_addr_t dma_addr, size_t size, | 1142 | void *cpu_addr, dma_addr_t dma_addr, size_t size, |
| 1266 | struct dma_attrs *attrs) | 1143 | struct dma_attrs *attrs) |
| 1267 | { | 1144 | { |
| 1268 | struct arm_vmregion *c; | 1145 | unsigned long uaddr = vma->vm_start; |
| 1146 | unsigned long usize = vma->vm_end - vma->vm_start; | ||
| 1147 | struct page **pages = __iommu_get_pages(cpu_addr, attrs); | ||
| 1269 | 1148 | ||
| 1270 | vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot); | 1149 | vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot); |
| 1271 | c = arm_vmregion_find(&consistent_head, (unsigned long)cpu_addr); | ||
| 1272 | |||
| 1273 | if (c) { | ||
| 1274 | struct page **pages = c->priv; | ||
| 1275 | |||
| 1276 | unsigned long uaddr = vma->vm_start; | ||
| 1277 | unsigned long usize = vma->vm_end - vma->vm_start; | ||
| 1278 | int i = 0; | ||
| 1279 | 1150 | ||
| 1280 | do { | 1151 | if (!pages) |
| 1281 | int ret; | 1152 | return -ENXIO; |
| 1282 | 1153 | ||
| 1283 | ret = vm_insert_page(vma, uaddr, pages[i++]); | 1154 | do { |
| 1284 | if (ret) { | 1155 | int ret = vm_insert_page(vma, uaddr, *pages++); |
| 1285 | pr_err("Remapping memory, error: %d\n", ret); | 1156 | if (ret) { |
| 1286 | return ret; | 1157 | pr_err("Remapping memory failed: %d\n", ret); |
| 1287 | } | 1158 | return ret; |
| 1159 | } | ||
| 1160 | uaddr += PAGE_SIZE; | ||
| 1161 | usize -= PAGE_SIZE; | ||
| 1162 | } while (usize > 0); | ||
| 1288 | 1163 | ||
| 1289 | uaddr += PAGE_SIZE; | ||
| 1290 | usize -= PAGE_SIZE; | ||
| 1291 | } while (usize > 0); | ||
| 1292 | } | ||
| 1293 | return 0; | 1164 | return 0; |
| 1294 | } | 1165 | } |
| 1295 | 1166 | ||
| @@ -1300,16 +1171,35 @@ static int arm_iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma, | |||
| 1300 | void arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr, | 1171 | void arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr, |
| 1301 | dma_addr_t handle, struct dma_attrs *attrs) | 1172 | dma_addr_t handle, struct dma_attrs *attrs) |
| 1302 | { | 1173 | { |
| 1303 | struct arm_vmregion *c; | 1174 | struct page **pages = __iommu_get_pages(cpu_addr, attrs); |
| 1304 | size = PAGE_ALIGN(size); | 1175 | size = PAGE_ALIGN(size); |
| 1305 | 1176 | ||
| 1306 | c = arm_vmregion_find(&consistent_head, (unsigned long)cpu_addr); | 1177 | if (!pages) { |
| 1307 | if (c) { | 1178 | WARN(1, "trying to free invalid coherent area: %p\n", cpu_addr); |
| 1308 | struct page **pages = c->priv; | 1179 | return; |
| 1309 | __dma_free_remap(cpu_addr, size); | ||
| 1310 | __iommu_remove_mapping(dev, handle, size); | ||
| 1311 | __iommu_free_buffer(dev, pages, size); | ||
| 1312 | } | 1180 | } |
| 1181 | |||
| 1182 | if (!dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs)) { | ||
| 1183 | unmap_kernel_range((unsigned long)cpu_addr, size); | ||
| 1184 | vunmap(cpu_addr); | ||
| 1185 | } | ||
| 1186 | |||
| 1187 | __iommu_remove_mapping(dev, handle, size); | ||
| 1188 | __iommu_free_buffer(dev, pages, size); | ||
| 1189 | } | ||
| 1190 | |||
| 1191 | static int arm_iommu_get_sgtable(struct device *dev, struct sg_table *sgt, | ||
| 1192 | void *cpu_addr, dma_addr_t dma_addr, | ||
| 1193 | size_t size, struct dma_attrs *attrs) | ||
| 1194 | { | ||
| 1195 | unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT; | ||
| 1196 | struct page **pages = __iommu_get_pages(cpu_addr, attrs); | ||
| 1197 | |||
| 1198 | if (!pages) | ||
| 1199 | return -ENXIO; | ||
| 1200 | |||
| 1201 | return sg_alloc_table_from_pages(sgt, pages, count, 0, size, | ||
| 1202 | GFP_KERNEL); | ||
| 1313 | } | 1203 | } |
| 1314 | 1204 | ||
| 1315 | /* | 1205 | /* |
| @@ -1317,7 +1207,7 @@ void arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr, | |||
| 1317 | */ | 1207 | */ |
| 1318 | static int __map_sg_chunk(struct device *dev, struct scatterlist *sg, | 1208 | static int __map_sg_chunk(struct device *dev, struct scatterlist *sg, |
| 1319 | size_t size, dma_addr_t *handle, | 1209 | size_t size, dma_addr_t *handle, |
| 1320 | enum dma_data_direction dir) | 1210 | enum dma_data_direction dir, struct dma_attrs *attrs) |
| 1321 | { | 1211 | { |
| 1322 | struct dma_iommu_mapping *mapping = dev->archdata.mapping; | 1212 | struct dma_iommu_mapping *mapping = dev->archdata.mapping; |
| 1323 | dma_addr_t iova, iova_base; | 1213 | dma_addr_t iova, iova_base; |
| @@ -1336,7 +1226,8 @@ static int __map_sg_chunk(struct device *dev, struct scatterlist *sg, | |||
| 1336 | phys_addr_t phys = page_to_phys(sg_page(s)); | 1226 | phys_addr_t phys = page_to_phys(sg_page(s)); |
| 1337 | unsigned int len = PAGE_ALIGN(s->offset + s->length); | 1227 | unsigned int len = PAGE_ALIGN(s->offset + s->length); |
| 1338 | 1228 | ||
| 1339 | if (!arch_is_coherent()) | 1229 | if (!arch_is_coherent() && |
| 1230 | !dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs)) | ||
| 1340 | __dma_page_cpu_to_dev(sg_page(s), s->offset, s->length, dir); | 1231 | __dma_page_cpu_to_dev(sg_page(s), s->offset, s->length, dir); |
| 1341 | 1232 | ||
| 1342 | ret = iommu_map(mapping->domain, iova, phys, len, 0); | 1233 | ret = iommu_map(mapping->domain, iova, phys, len, 0); |
| @@ -1383,7 +1274,7 @@ int arm_iommu_map_sg(struct device *dev, struct scatterlist *sg, int nents, | |||
| 1383 | 1274 | ||
| 1384 | if (s->offset || (size & ~PAGE_MASK) || size + s->length > max) { | 1275 | if (s->offset || (size & ~PAGE_MASK) || size + s->length > max) { |
| 1385 | if (__map_sg_chunk(dev, start, size, &dma->dma_address, | 1276 | if (__map_sg_chunk(dev, start, size, &dma->dma_address, |
| 1386 | dir) < 0) | 1277 | dir, attrs) < 0) |
| 1387 | goto bad_mapping; | 1278 | goto bad_mapping; |
| 1388 | 1279 | ||
| 1389 | dma->dma_address += offset; | 1280 | dma->dma_address += offset; |
| @@ -1396,7 +1287,7 @@ int arm_iommu_map_sg(struct device *dev, struct scatterlist *sg, int nents, | |||
| 1396 | } | 1287 | } |
| 1397 | size += s->length; | 1288 | size += s->length; |
| 1398 | } | 1289 | } |
| 1399 | if (__map_sg_chunk(dev, start, size, &dma->dma_address, dir) < 0) | 1290 | if (__map_sg_chunk(dev, start, size, &dma->dma_address, dir, attrs) < 0) |
| 1400 | goto bad_mapping; | 1291 | goto bad_mapping; |
| 1401 | 1292 | ||
| 1402 | dma->dma_address += offset; | 1293 | dma->dma_address += offset; |
| @@ -1430,7 +1321,8 @@ void arm_iommu_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, | |||
| 1430 | if (sg_dma_len(s)) | 1321 | if (sg_dma_len(s)) |
| 1431 | __iommu_remove_mapping(dev, sg_dma_address(s), | 1322 | __iommu_remove_mapping(dev, sg_dma_address(s), |
| 1432 | sg_dma_len(s)); | 1323 | sg_dma_len(s)); |
| 1433 | if (!arch_is_coherent()) | 1324 | if (!arch_is_coherent() && |
| 1325 | !dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs)) | ||
| 1434 | __dma_page_dev_to_cpu(sg_page(s), s->offset, | 1326 | __dma_page_dev_to_cpu(sg_page(s), s->offset, |
| 1435 | s->length, dir); | 1327 | s->length, dir); |
| 1436 | } | 1328 | } |
| @@ -1492,7 +1384,7 @@ static dma_addr_t arm_iommu_map_page(struct device *dev, struct page *page, | |||
| 1492 | dma_addr_t dma_addr; | 1384 | dma_addr_t dma_addr; |
| 1493 | int ret, len = PAGE_ALIGN(size + offset); | 1385 | int ret, len = PAGE_ALIGN(size + offset); |
| 1494 | 1386 | ||
| 1495 | if (!arch_is_coherent()) | 1387 | if (!arch_is_coherent() && !dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs)) |
| 1496 | __dma_page_cpu_to_dev(page, offset, size, dir); | 1388 | __dma_page_cpu_to_dev(page, offset, size, dir); |
| 1497 | 1389 | ||
| 1498 | dma_addr = __alloc_iova(mapping, len); | 1390 | dma_addr = __alloc_iova(mapping, len); |
| @@ -1531,7 +1423,7 @@ static void arm_iommu_unmap_page(struct device *dev, dma_addr_t handle, | |||
| 1531 | if (!iova) | 1423 | if (!iova) |
| 1532 | return; | 1424 | return; |
| 1533 | 1425 | ||
| 1534 | if (!arch_is_coherent()) | 1426 | if (!arch_is_coherent() && !dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs)) |
| 1535 | __dma_page_dev_to_cpu(page, offset, size, dir); | 1427 | __dma_page_dev_to_cpu(page, offset, size, dir); |
| 1536 | 1428 | ||
| 1537 | iommu_unmap(mapping->domain, iova, len); | 1429 | iommu_unmap(mapping->domain, iova, len); |
| @@ -1571,6 +1463,7 @@ struct dma_map_ops iommu_ops = { | |||
| 1571 | .alloc = arm_iommu_alloc_attrs, | 1463 | .alloc = arm_iommu_alloc_attrs, |
| 1572 | .free = arm_iommu_free_attrs, | 1464 | .free = arm_iommu_free_attrs, |
| 1573 | .mmap = arm_iommu_mmap_attrs, | 1465 | .mmap = arm_iommu_mmap_attrs, |
| 1466 | .get_sgtable = arm_iommu_get_sgtable, | ||
| 1574 | 1467 | ||
| 1575 | .map_page = arm_iommu_map_page, | 1468 | .map_page = arm_iommu_map_page, |
| 1576 | .unmap_page = arm_iommu_unmap_page, | 1469 | .unmap_page = arm_iommu_unmap_page, |
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index f54d59219764..9aec41fa80ae 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c | |||
| @@ -21,13 +21,13 @@ | |||
| 21 | #include <linux/gfp.h> | 21 | #include <linux/gfp.h> |
| 22 | #include <linux/memblock.h> | 22 | #include <linux/memblock.h> |
| 23 | #include <linux/dma-contiguous.h> | 23 | #include <linux/dma-contiguous.h> |
| 24 | #include <linux/sizes.h> | ||
| 24 | 25 | ||
| 25 | #include <asm/mach-types.h> | 26 | #include <asm/mach-types.h> |
| 26 | #include <asm/memblock.h> | 27 | #include <asm/memblock.h> |
| 27 | #include <asm/prom.h> | 28 | #include <asm/prom.h> |
| 28 | #include <asm/sections.h> | 29 | #include <asm/sections.h> |
| 29 | #include <asm/setup.h> | 30 | #include <asm/setup.h> |
| 30 | #include <asm/sizes.h> | ||
| 31 | #include <asm/tlb.h> | 31 | #include <asm/tlb.h> |
| 32 | #include <asm/fixmap.h> | 32 | #include <asm/fixmap.h> |
| 33 | 33 | ||
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c index 4f55f5062ab7..566750fa57d4 100644 --- a/arch/arm/mm/ioremap.c +++ b/arch/arm/mm/ioremap.c | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #include <linux/mm.h> | 25 | #include <linux/mm.h> |
| 26 | #include <linux/vmalloc.h> | 26 | #include <linux/vmalloc.h> |
| 27 | #include <linux/io.h> | 27 | #include <linux/io.h> |
| 28 | #include <linux/sizes.h> | ||
| 28 | 29 | ||
| 29 | #include <asm/cp15.h> | 30 | #include <asm/cp15.h> |
| 30 | #include <asm/cputype.h> | 31 | #include <asm/cputype.h> |
| @@ -32,7 +33,6 @@ | |||
| 32 | #include <asm/mmu_context.h> | 33 | #include <asm/mmu_context.h> |
| 33 | #include <asm/pgalloc.h> | 34 | #include <asm/pgalloc.h> |
| 34 | #include <asm/tlbflush.h> | 35 | #include <asm/tlbflush.h> |
| 35 | #include <asm/sizes.h> | ||
| 36 | #include <asm/system_info.h> | 36 | #include <asm/system_info.h> |
| 37 | 37 | ||
| 38 | #include <asm/mach/map.h> | 38 | #include <asm/mach/map.h> |
diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h index 2e8a1efdf7b8..6776160618ef 100644 --- a/arch/arm/mm/mm.h +++ b/arch/arm/mm/mm.h | |||
| @@ -59,6 +59,9 @@ extern void __flush_dcache_page(struct address_space *mapping, struct page *page | |||
| 59 | #define VM_ARM_MTYPE(mt) ((mt) << 20) | 59 | #define VM_ARM_MTYPE(mt) ((mt) << 20) |
| 60 | #define VM_ARM_MTYPE_MASK (0x1f << 20) | 60 | #define VM_ARM_MTYPE_MASK (0x1f << 20) |
| 61 | 61 | ||
| 62 | /* consistent regions used by dma_alloc_attrs() */ | ||
| 63 | #define VM_ARM_DMA_CONSISTENT 0x20000000 | ||
| 64 | |||
| 62 | #endif | 65 | #endif |
| 63 | 66 | ||
| 64 | #ifdef CONFIG_ZONE_DMA | 67 | #ifdef CONFIG_ZONE_DMA |
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index cf4528d51774..4c2d0451e84a 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c | |||
| @@ -16,13 +16,13 @@ | |||
| 16 | #include <linux/memblock.h> | 16 | #include <linux/memblock.h> |
| 17 | #include <linux/fs.h> | 17 | #include <linux/fs.h> |
| 18 | #include <linux/vmalloc.h> | 18 | #include <linux/vmalloc.h> |
| 19 | #include <linux/sizes.h> | ||
| 19 | 20 | ||
| 20 | #include <asm/cp15.h> | 21 | #include <asm/cp15.h> |
| 21 | #include <asm/cputype.h> | 22 | #include <asm/cputype.h> |
| 22 | #include <asm/sections.h> | 23 | #include <asm/sections.h> |
| 23 | #include <asm/cachetype.h> | 24 | #include <asm/cachetype.h> |
| 24 | #include <asm/setup.h> | 25 | #include <asm/setup.h> |
| 25 | #include <asm/sizes.h> | ||
| 26 | #include <asm/smp_plat.h> | 26 | #include <asm/smp_plat.h> |
| 27 | #include <asm/tlb.h> | 27 | #include <asm/tlb.h> |
| 28 | #include <asm/highmem.h> | 28 | #include <asm/highmem.h> |
| @@ -422,12 +422,6 @@ static void __init build_mem_type_table(void) | |||
| 422 | vecs_pgprot = kern_pgprot = user_pgprot = cp->pte; | 422 | vecs_pgprot = kern_pgprot = user_pgprot = cp->pte; |
| 423 | 423 | ||
| 424 | /* | 424 | /* |
| 425 | * Only use write-through for non-SMP systems | ||
| 426 | */ | ||
| 427 | if (!is_smp() && cpu_arch >= CPU_ARCH_ARMv5 && cachepolicy > CPOLICY_WRITETHROUGH) | ||
| 428 | vecs_pgprot = cache_policies[CPOLICY_WRITETHROUGH].pte; | ||
| 429 | |||
| 430 | /* | ||
| 431 | * Enable CPU-specific coherency if supported. | 425 | * Enable CPU-specific coherency if supported. |
| 432 | * (Only available on XSC3 at the moment.) | 426 | * (Only available on XSC3 at the moment.) |
| 433 | */ | 427 | */ |
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S index 5900cd520e84..86b8b480634f 100644 --- a/arch/arm/mm/proc-v6.S +++ b/arch/arm/mm/proc-v6.S | |||
| @@ -107,6 +107,12 @@ ENTRY(cpu_v6_switch_mm) | |||
| 107 | mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB | 107 | mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB |
| 108 | mcr p15, 0, r2, c7, c10, 4 @ drain write buffer | 108 | mcr p15, 0, r2, c7, c10, 4 @ drain write buffer |
| 109 | mcr p15, 0, r0, c2, c0, 0 @ set TTB 0 | 109 | mcr p15, 0, r0, c2, c0, 0 @ set TTB 0 |
| 110 | #ifdef CONFIG_PID_IN_CONTEXTIDR | ||
| 111 | mrc p15, 0, r2, c13, c0, 1 @ read current context ID | ||
| 112 | bic r2, r2, #0xff @ extract the PID | ||
| 113 | and r1, r1, #0xff | ||
| 114 | orr r1, r1, r2 @ insert into new context ID | ||
| 115 | #endif | ||
| 110 | mcr p15, 0, r1, c13, c0, 1 @ set context ID | 116 | mcr p15, 0, r1, c13, c0, 1 @ set context ID |
| 111 | #endif | 117 | #endif |
| 112 | mov pc, lr | 118 | mov pc, lr |
diff --git a/arch/arm/mm/proc-v7-2level.S b/arch/arm/mm/proc-v7-2level.S index 42ac069c8012..fd045e706390 100644 --- a/arch/arm/mm/proc-v7-2level.S +++ b/arch/arm/mm/proc-v7-2level.S | |||
| @@ -46,6 +46,11 @@ ENTRY(cpu_v7_switch_mm) | |||
| 46 | #ifdef CONFIG_ARM_ERRATA_430973 | 46 | #ifdef CONFIG_ARM_ERRATA_430973 |
| 47 | mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB | 47 | mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB |
| 48 | #endif | 48 | #endif |
| 49 | #ifdef CONFIG_PID_IN_CONTEXTIDR | ||
| 50 | mrc p15, 0, r2, c13, c0, 1 @ read current context ID | ||
| 51 | lsr r2, r2, #8 @ extract the PID | ||
| 52 | bfi r1, r2, #8, #24 @ insert into new context ID | ||
| 53 | #endif | ||
| 49 | #ifdef CONFIG_ARM_ERRATA_754322 | 54 | #ifdef CONFIG_ARM_ERRATA_754322 |
| 50 | dsb | 55 | dsb |
| 51 | #endif | 56 | #endif |
diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c index 4e0a371630b3..99c63d4b6af8 100644 --- a/arch/arm/oprofile/common.c +++ b/arch/arm/oprofile/common.c | |||
| @@ -23,26 +23,37 @@ | |||
| 23 | #include <asm/ptrace.h> | 23 | #include <asm/ptrace.h> |
| 24 | 24 | ||
| 25 | #ifdef CONFIG_HW_PERF_EVENTS | 25 | #ifdef CONFIG_HW_PERF_EVENTS |
| 26 | |||
| 27 | /* | ||
| 28 | * OProfile has a curious naming scheme for the ARM PMUs, but they are | ||
| 29 | * part of the user ABI so we need to map from the perf PMU name for | ||
| 30 | * supported PMUs. | ||
| 31 | */ | ||
| 32 | static struct op_perf_name { | ||
| 33 | char *perf_name; | ||
| 34 | char *op_name; | ||
| 35 | } op_perf_name_map[] = { | ||
| 36 | { "xscale1", "arm/xscale1" }, | ||
| 37 | { "xscale1", "arm/xscale2" }, | ||
| 38 | { "v6", "arm/armv6" }, | ||
| 39 | { "v6mpcore", "arm/mpcore" }, | ||
| 40 | { "ARMv7 Cortex-A8", "arm/armv7" }, | ||
| 41 | { "ARMv7 Cortex-A9", "arm/armv7-ca9" }, | ||
| 42 | }; | ||
| 43 | |||
| 26 | char *op_name_from_perf_id(void) | 44 | char *op_name_from_perf_id(void) |
| 27 | { | 45 | { |
| 28 | enum arm_perf_pmu_ids id = armpmu_get_pmu_id(); | 46 | int i; |
| 29 | 47 | struct op_perf_name names; | |
| 30 | switch (id) { | 48 | const char *perf_name = perf_pmu_name(); |
| 31 | case ARM_PERF_PMU_ID_XSCALE1: | 49 | |
| 32 | return "arm/xscale1"; | 50 | for (i = 0; i < ARRAY_SIZE(op_perf_name_map); ++i) { |
| 33 | case ARM_PERF_PMU_ID_XSCALE2: | 51 | names = op_perf_name_map[i]; |
| 34 | return "arm/xscale2"; | 52 | if (!strcmp(names.perf_name, perf_name)) |
| 35 | case ARM_PERF_PMU_ID_V6: | 53 | return names.op_name; |
| 36 | return "arm/armv6"; | ||
| 37 | case ARM_PERF_PMU_ID_V6MP: | ||
| 38 | return "arm/mpcore"; | ||
| 39 | case ARM_PERF_PMU_ID_CA8: | ||
| 40 | return "arm/armv7"; | ||
| 41 | case ARM_PERF_PMU_ID_CA9: | ||
| 42 | return "arm/armv7-ca9"; | ||
| 43 | default: | ||
| 44 | return NULL; | ||
| 45 | } | 54 | } |
| 55 | |||
| 56 | return NULL; | ||
| 46 | } | 57 | } |
| 47 | #endif | 58 | #endif |
| 48 | 59 | ||
diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig index c722f9ce6918..baf9064c0844 100644 --- a/arch/arm/plat-mxc/Kconfig +++ b/arch/arm/plat-mxc/Kconfig | |||
| @@ -47,12 +47,6 @@ config MXC_TZIC | |||
| 47 | config MXC_AVIC | 47 | config MXC_AVIC |
| 48 | bool | 48 | bool |
| 49 | 49 | ||
| 50 | config MXC_PWM | ||
| 51 | tristate "Enable PWM driver" | ||
| 52 | select HAVE_PWM | ||
| 53 | help | ||
| 54 | Enable support for the i.MX PWM controller(s). | ||
| 55 | |||
| 56 | config MXC_DEBUG_BOARD | 50 | config MXC_DEBUG_BOARD |
| 57 | bool "Enable MXC debug board(for 3-stack)" | 51 | bool "Enable MXC debug board(for 3-stack)" |
| 58 | help | 52 | help |
diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile index 63b064b5c1d5..6ac720031150 100644 --- a/arch/arm/plat-mxc/Makefile +++ b/arch/arm/plat-mxc/Makefile | |||
| @@ -11,7 +11,6 @@ obj-$(CONFIG_MXC_AVIC) += avic.o | |||
| 11 | obj-$(CONFIG_IMX_HAVE_IOMUX_V1) += iomux-v1.o | 11 | obj-$(CONFIG_IMX_HAVE_IOMUX_V1) += iomux-v1.o |
| 12 | obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o | 12 | obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o |
| 13 | obj-$(CONFIG_IRAM_ALLOC) += iram_alloc.o | 13 | obj-$(CONFIG_IRAM_ALLOC) += iram_alloc.o |
| 14 | obj-$(CONFIG_MXC_PWM) += pwm.o | ||
| 15 | obj-$(CONFIG_MXC_ULPI) += ulpi.o | 14 | obj-$(CONFIG_MXC_ULPI) += ulpi.o |
| 16 | obj-$(CONFIG_MXC_USE_EPIT) += epit.o | 15 | obj-$(CONFIG_MXC_USE_EPIT) += epit.o |
| 17 | obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o | 16 | obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o |
diff --git a/arch/arm/plat-mxc/include/mach/i2c.h b/arch/arm/plat-mxc/include/mach/i2c.h index 375cdd0cf876..8289d915e615 100644 --- a/arch/arm/plat-mxc/include/mach/i2c.h +++ b/arch/arm/plat-mxc/include/mach/i2c.h | |||
| @@ -15,7 +15,7 @@ | |||
| 15 | * | 15 | * |
| 16 | **/ | 16 | **/ |
| 17 | struct imxi2c_platform_data { | 17 | struct imxi2c_platform_data { |
| 18 | int bitrate; | 18 | u32 bitrate; |
| 19 | }; | 19 | }; |
| 20 | 20 | ||
| 21 | #endif /* __ASM_ARCH_I2C_H_ */ | 21 | #endif /* __ASM_ARCH_I2C_H_ */ |
diff --git a/arch/arm/plat-mxc/pwm.c b/arch/arm/plat-mxc/pwm.c deleted file mode 100644 index c0cab2270dd1..000000000000 --- a/arch/arm/plat-mxc/pwm.c +++ /dev/null | |||
| @@ -1,306 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * simple driver for PWM (Pulse Width Modulator) controller | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License version 2 as | ||
| 6 | * published by the Free Software Foundation. | ||
| 7 | * | ||
| 8 | * Derived from pxa PWM driver by eric miao <eric.miao@marvell.com> | ||
| 9 | */ | ||
| 10 | |||
| 11 | #include <linux/module.h> | ||
| 12 | #include <linux/kernel.h> | ||
| 13 | #include <linux/platform_device.h> | ||
| 14 | #include <linux/slab.h> | ||
| 15 | #include <linux/err.h> | ||
| 16 | #include <linux/clk.h> | ||
| 17 | #include <linux/io.h> | ||
| 18 | #include <linux/pwm.h> | ||
| 19 | #include <mach/hardware.h> | ||
| 20 | |||
| 21 | |||
| 22 | /* i.MX1 and i.MX21 share the same PWM function block: */ | ||
| 23 | |||
| 24 | #define MX1_PWMC 0x00 /* PWM Control Register */ | ||
| 25 | #define MX1_PWMS 0x04 /* PWM Sample Register */ | ||
| 26 | #define MX1_PWMP 0x08 /* PWM Period Register */ | ||
| 27 | |||
| 28 | |||
| 29 | /* i.MX27, i.MX31, i.MX35 share the same PWM function block: */ | ||
| 30 | |||
| 31 | #define MX3_PWMCR 0x00 /* PWM Control Register */ | ||
| 32 | #define MX3_PWMSAR 0x0C /* PWM Sample Register */ | ||
| 33 | #define MX3_PWMPR 0x10 /* PWM Period Register */ | ||
| 34 | #define MX3_PWMCR_PRESCALER(x) (((x - 1) & 0xFFF) << 4) | ||
| 35 | #define MX3_PWMCR_DOZEEN (1 << 24) | ||
| 36 | #define MX3_PWMCR_WAITEN (1 << 23) | ||
| 37 | #define MX3_PWMCR_DBGEN (1 << 22) | ||
| 38 | #define MX3_PWMCR_CLKSRC_IPG_HIGH (2 << 16) | ||
| 39 | #define MX3_PWMCR_CLKSRC_IPG (1 << 16) | ||
| 40 | #define MX3_PWMCR_EN (1 << 0) | ||
| 41 | |||
| 42 | |||
| 43 | |||
| 44 | struct pwm_device { | ||
| 45 | struct list_head node; | ||
| 46 | struct platform_device *pdev; | ||
| 47 | |||
| 48 | const char *label; | ||
| 49 | struct clk *clk; | ||
| 50 | |||
| 51 | int clk_enabled; | ||
| 52 | void __iomem *mmio_base; | ||
| 53 | |||
| 54 | unsigned int use_count; | ||
| 55 | unsigned int pwm_id; | ||
| 56 | }; | ||
| 57 | |||
| 58 | int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) | ||
| 59 | { | ||
| 60 | if (pwm == NULL || period_ns == 0 || duty_ns > period_ns) | ||
| 61 | return -EINVAL; | ||
| 62 | |||
| 63 | if (!(cpu_is_mx1() || cpu_is_mx21())) { | ||
| 64 | unsigned long long c; | ||
| 65 | unsigned long period_cycles, duty_cycles, prescale; | ||
| 66 | u32 cr; | ||
| 67 | |||
| 68 | c = clk_get_rate(pwm->clk); | ||
| 69 | c = c * period_ns; | ||
| 70 | do_div(c, 1000000000); | ||
| 71 | period_cycles = c; | ||
| 72 | |||
| 73 | prescale = period_cycles / 0x10000 + 1; | ||
| 74 | |||
| 75 | period_cycles /= prescale; | ||
| 76 | c = (unsigned long long)period_cycles * duty_ns; | ||
| 77 | do_div(c, period_ns); | ||
| 78 | duty_cycles = c; | ||
| 79 | |||
| 80 | /* | ||
| 81 | * according to imx pwm RM, the real period value should be | ||
| 82 | * PERIOD value in PWMPR plus 2. | ||
| 83 | */ | ||
| 84 | if (period_cycles > 2) | ||
| 85 | period_cycles -= 2; | ||
| 86 | else | ||
| 87 | period_cycles = 0; | ||
| 88 | |||
| 89 | writel(duty_cycles, pwm->mmio_base + MX3_PWMSAR); | ||
| 90 | writel(period_cycles, pwm->mmio_base + MX3_PWMPR); | ||
| 91 | |||
| 92 | cr = MX3_PWMCR_PRESCALER(prescale) | | ||
| 93 | MX3_PWMCR_DOZEEN | MX3_PWMCR_WAITEN | | ||
| 94 | MX3_PWMCR_DBGEN | MX3_PWMCR_EN; | ||
| 95 | |||
| 96 | if (cpu_is_mx25()) | ||
| 97 | cr |= MX3_PWMCR_CLKSRC_IPG; | ||
| 98 | else | ||
| 99 | cr |= MX3_PWMCR_CLKSRC_IPG_HIGH; | ||
| 100 | |||
| 101 | writel(cr, pwm->mmio_base + MX3_PWMCR); | ||
| 102 | } else if (cpu_is_mx1() || cpu_is_mx21()) { | ||
| 103 | /* The PWM subsystem allows for exact frequencies. However, | ||
| 104 | * I cannot connect a scope on my device to the PWM line and | ||
| 105 | * thus cannot provide the program the PWM controller | ||
| 106 | * exactly. Instead, I'm relying on the fact that the | ||
| 107 | * Bootloader (u-boot or WinCE+haret) has programmed the PWM | ||
| 108 | * function group already. So I'll just modify the PWM sample | ||
| 109 | * register to follow the ratio of duty_ns vs. period_ns | ||
| 110 | * accordingly. | ||
| 111 | * | ||
| 112 | * This is good enough for programming the brightness of | ||
| 113 | * the LCD backlight. | ||
| 114 | * | ||
| 115 | * The real implementation would divide PERCLK[0] first by | ||
| 116 | * both the prescaler (/1 .. /128) and then by CLKSEL | ||
| 117 | * (/2 .. /16). | ||
| 118 | */ | ||
| 119 | u32 max = readl(pwm->mmio_base + MX1_PWMP); | ||
| 120 | u32 p = max * duty_ns / period_ns; | ||
| 121 | writel(max - p, pwm->mmio_base + MX1_PWMS); | ||
| 122 | } else { | ||
| 123 | BUG(); | ||
| 124 | } | ||
| 125 | |||
| 126 | return 0; | ||
| 127 | } | ||
| 128 | EXPORT_SYMBOL(pwm_config); | ||
| 129 | |||
| 130 | int pwm_enable(struct pwm_device *pwm) | ||
| 131 | { | ||
| 132 | int rc = 0; | ||
| 133 | |||
| 134 | if (!pwm->clk_enabled) { | ||
| 135 | rc = clk_prepare_enable(pwm->clk); | ||
| 136 | if (!rc) | ||
| 137 | pwm->clk_enabled = 1; | ||
| 138 | } | ||
| 139 | return rc; | ||
| 140 | } | ||
| 141 | EXPORT_SYMBOL(pwm_enable); | ||
| 142 | |||
| 143 | void pwm_disable(struct pwm_device *pwm) | ||
| 144 | { | ||
| 145 | writel(0, pwm->mmio_base + MX3_PWMCR); | ||
| 146 | |||
| 147 | if (pwm->clk_enabled) { | ||
| 148 | clk_disable_unprepare(pwm->clk); | ||
| 149 | pwm->clk_enabled = 0; | ||
| 150 | } | ||
| 151 | } | ||
| 152 | EXPORT_SYMBOL(pwm_disable); | ||
| 153 | |||
| 154 | static DEFINE_MUTEX(pwm_lock); | ||
| 155 | static LIST_HEAD(pwm_list); | ||
| 156 | |||
| 157 | struct pwm_device *pwm_request(int pwm_id, const char *label) | ||
| 158 | { | ||
| 159 | struct pwm_device *pwm; | ||
| 160 | int found = 0; | ||
| 161 | |||
| 162 | mutex_lock(&pwm_lock); | ||
| 163 | |||
| 164 | list_for_each_entry(pwm, &pwm_list, node) { | ||
| 165 | if (pwm->pwm_id == pwm_id) { | ||
| 166 | found = 1; | ||
| 167 | break; | ||
| 168 | } | ||
| 169 | } | ||
| 170 | |||
| 171 | if (found) { | ||
| 172 | if (pwm->use_count == 0) { | ||
| 173 | pwm->use_count++; | ||
| 174 | pwm->label = label; | ||
| 175 | } else | ||
| 176 | pwm = ERR_PTR(-EBUSY); | ||
| 177 | } else | ||
| 178 | pwm = ERR_PTR(-ENOENT); | ||
| 179 | |||
| 180 | mutex_unlock(&pwm_lock); | ||
| 181 | return pwm; | ||
| 182 | } | ||
| 183 | EXPORT_SYMBOL(pwm_request); | ||
| 184 | |||
| 185 | void pwm_free(struct pwm_device *pwm) | ||
| 186 | { | ||
| 187 | mutex_lock(&pwm_lock); | ||
| 188 | |||
| 189 | if (pwm->use_count) { | ||
| 190 | pwm->use_count--; | ||
| 191 | pwm->label = NULL; | ||
| 192 | } else | ||
| 193 | pr_warning("PWM device already freed\n"); | ||
| 194 | |||
| 195 | mutex_unlock(&pwm_lock); | ||
| 196 | } | ||
| 197 | EXPORT_SYMBOL(pwm_free); | ||
| 198 | |||
| 199 | static int __devinit mxc_pwm_probe(struct platform_device *pdev) | ||
| 200 | { | ||
| 201 | struct pwm_device *pwm; | ||
| 202 | struct resource *r; | ||
| 203 | int ret = 0; | ||
| 204 | |||
| 205 | pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL); | ||
| 206 | if (pwm == NULL) { | ||
| 207 | dev_err(&pdev->dev, "failed to allocate memory\n"); | ||
| 208 | return -ENOMEM; | ||
| 209 | } | ||
| 210 | |||
| 211 | pwm->clk = clk_get(&pdev->dev, "pwm"); | ||
| 212 | |||
| 213 | if (IS_ERR(pwm->clk)) { | ||
| 214 | ret = PTR_ERR(pwm->clk); | ||
| 215 | goto err_free; | ||
| 216 | } | ||
| 217 | |||
| 218 | pwm->clk_enabled = 0; | ||
| 219 | |||
| 220 | pwm->use_count = 0; | ||
| 221 | pwm->pwm_id = pdev->id; | ||
| 222 | pwm->pdev = pdev; | ||
| 223 | |||
| 224 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 225 | if (r == NULL) { | ||
| 226 | dev_err(&pdev->dev, "no memory resource defined\n"); | ||
| 227 | ret = -ENODEV; | ||
| 228 | goto err_free_clk; | ||
| 229 | } | ||
| 230 | |||
| 231 | r = request_mem_region(r->start, resource_size(r), pdev->name); | ||
| 232 | if (r == NULL) { | ||
| 233 | dev_err(&pdev->dev, "failed to request memory resource\n"); | ||
| 234 | ret = -EBUSY; | ||
| 235 | goto err_free_clk; | ||
| 236 | } | ||
| 237 | |||
| 238 | pwm->mmio_base = ioremap(r->start, resource_size(r)); | ||
| 239 | if (pwm->mmio_base == NULL) { | ||
| 240 | dev_err(&pdev->dev, "failed to ioremap() registers\n"); | ||
| 241 | ret = -ENODEV; | ||
| 242 | goto err_free_mem; | ||
| 243 | } | ||
| 244 | |||
| 245 | mutex_lock(&pwm_lock); | ||
| 246 | list_add_tail(&pwm->node, &pwm_list); | ||
| 247 | mutex_unlock(&pwm_lock); | ||
| 248 | |||
| 249 | platform_set_drvdata(pdev, pwm); | ||
| 250 | return 0; | ||
| 251 | |||
| 252 | err_free_mem: | ||
| 253 | release_mem_region(r->start, resource_size(r)); | ||
| 254 | err_free_clk: | ||
| 255 | clk_put(pwm->clk); | ||
| 256 | err_free: | ||
| 257 | kfree(pwm); | ||
| 258 | return ret; | ||
| 259 | } | ||
| 260 | |||
| 261 | static int __devexit mxc_pwm_remove(struct platform_device *pdev) | ||
| 262 | { | ||
| 263 | struct pwm_device *pwm; | ||
| 264 | struct resource *r; | ||
| 265 | |||
| 266 | pwm = platform_get_drvdata(pdev); | ||
| 267 | if (pwm == NULL) | ||
| 268 | return -ENODEV; | ||
| 269 | |||
| 270 | mutex_lock(&pwm_lock); | ||
| 271 | list_del(&pwm->node); | ||
| 272 | mutex_unlock(&pwm_lock); | ||
| 273 | |||
| 274 | iounmap(pwm->mmio_base); | ||
| 275 | |||
| 276 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 277 | release_mem_region(r->start, resource_size(r)); | ||
| 278 | |||
| 279 | clk_put(pwm->clk); | ||
| 280 | |||
| 281 | kfree(pwm); | ||
| 282 | return 0; | ||
| 283 | } | ||
| 284 | |||
| 285 | static struct platform_driver mxc_pwm_driver = { | ||
| 286 | .driver = { | ||
| 287 | .name = "mxc_pwm", | ||
| 288 | }, | ||
| 289 | .probe = mxc_pwm_probe, | ||
| 290 | .remove = __devexit_p(mxc_pwm_remove), | ||
| 291 | }; | ||
| 292 | |||
| 293 | static int __init mxc_pwm_init(void) | ||
| 294 | { | ||
| 295 | return platform_driver_register(&mxc_pwm_driver); | ||
| 296 | } | ||
| 297 | arch_initcall(mxc_pwm_init); | ||
| 298 | |||
| 299 | static void __exit mxc_pwm_exit(void) | ||
| 300 | { | ||
| 301 | platform_driver_unregister(&mxc_pwm_driver); | ||
| 302 | } | ||
| 303 | module_exit(mxc_pwm_exit); | ||
| 304 | |||
| 305 | MODULE_LICENSE("GPL v2"); | ||
| 306 | MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>"); | ||
diff --git a/arch/arm/plat-nomadik/include/plat/i2c.h b/arch/arm/plat-nomadik/include/plat/i2c.h deleted file mode 100644 index 8ba70ffc31ec..000000000000 --- a/arch/arm/plat-nomadik/include/plat/i2c.h +++ /dev/null | |||
| @@ -1,39 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2009 ST-Ericsson | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License version 2, as | ||
| 6 | * published by the Free Software Foundation. | ||
| 7 | */ | ||
| 8 | #ifndef __PLAT_I2C_H | ||
| 9 | #define __PLAT_I2C_H | ||
| 10 | |||
| 11 | enum i2c_freq_mode { | ||
| 12 | I2C_FREQ_MODE_STANDARD, /* up to 100 Kb/s */ | ||
| 13 | I2C_FREQ_MODE_FAST, /* up to 400 Kb/s */ | ||
| 14 | I2C_FREQ_MODE_HIGH_SPEED, /* up to 3.4 Mb/s */ | ||
| 15 | I2C_FREQ_MODE_FAST_PLUS, /* up to 1 Mb/s */ | ||
| 16 | }; | ||
| 17 | |||
| 18 | /** | ||
| 19 | * struct nmk_i2c_controller - client specific controller configuration | ||
| 20 | * @clk_freq: clock frequency for the operation mode | ||
| 21 | * @slsu: Slave data setup time in ns. | ||
| 22 | * The needed setup time for three modes of operation | ||
| 23 | * are 250ns, 100ns and 10ns respectively thus leading | ||
| 24 | * to the values of 14, 6, 2 for a 48 MHz i2c clk | ||
| 25 | * @tft: Tx FIFO Threshold in bytes | ||
| 26 | * @rft: Rx FIFO Threshold in bytes | ||
| 27 | * @timeout Slave response timeout(ms) | ||
| 28 | * @sm: speed mode | ||
| 29 | */ | ||
| 30 | struct nmk_i2c_controller { | ||
| 31 | unsigned long clk_freq; | ||
| 32 | unsigned short slsu; | ||
| 33 | unsigned char tft; | ||
| 34 | unsigned char rft; | ||
| 35 | int timeout; | ||
| 36 | enum i2c_freq_mode sm; | ||
| 37 | }; | ||
| 38 | |||
| 39 | #endif /* __PLAT_I2C_H */ | ||
diff --git a/arch/arm/plat-pxa/Makefile b/arch/arm/plat-pxa/Makefile index f302d048392d..af8e484001e5 100644 --- a/arch/arm/plat-pxa/Makefile +++ b/arch/arm/plat-pxa/Makefile | |||
| @@ -8,5 +8,4 @@ obj-$(CONFIG_PXA3xx) += mfp.o | |||
| 8 | obj-$(CONFIG_PXA95x) += mfp.o | 8 | obj-$(CONFIG_PXA95x) += mfp.o |
| 9 | obj-$(CONFIG_ARCH_MMP) += mfp.o | 9 | obj-$(CONFIG_ARCH_MMP) += mfp.o |
| 10 | 10 | ||
| 11 | obj-$(CONFIG_HAVE_PWM) += pwm.o | ||
| 12 | obj-$(CONFIG_PXA_SSP) += ssp.o | 11 | obj-$(CONFIG_PXA_SSP) += ssp.o |
diff --git a/arch/arm/plat-pxa/pwm.c b/arch/arm/plat-pxa/pwm.c deleted file mode 100644 index ef32686feef9..000000000000 --- a/arch/arm/plat-pxa/pwm.c +++ /dev/null | |||
| @@ -1,304 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/arm/mach-pxa/pwm.c | ||
| 3 | * | ||
| 4 | * simple driver for PWM (Pulse Width Modulator) controller | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License version 2 as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | * | ||
| 10 | * 2008-02-13 initial version | ||
| 11 | * eric miao <eric.miao@marvell.com> | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/module.h> | ||
| 15 | #include <linux/kernel.h> | ||
| 16 | #include <linux/platform_device.h> | ||
| 17 | #include <linux/slab.h> | ||
| 18 | #include <linux/err.h> | ||
| 19 | #include <linux/clk.h> | ||
| 20 | #include <linux/io.h> | ||
| 21 | #include <linux/pwm.h> | ||
| 22 | |||
| 23 | #include <asm/div64.h> | ||
| 24 | |||
| 25 | #define HAS_SECONDARY_PWM 0x10 | ||
| 26 | #define PWM_ID_BASE(d) ((d) & 0xf) | ||
| 27 | |||
| 28 | static const struct platform_device_id pwm_id_table[] = { | ||
| 29 | /* PWM has_secondary_pwm? */ | ||
| 30 | { "pxa25x-pwm", 0 }, | ||
| 31 | { "pxa27x-pwm", 0 | HAS_SECONDARY_PWM }, | ||
| 32 | { "pxa168-pwm", 1 }, | ||
| 33 | { "pxa910-pwm", 1 }, | ||
| 34 | { }, | ||
| 35 | }; | ||
| 36 | MODULE_DEVICE_TABLE(platform, pwm_id_table); | ||
| 37 | |||
| 38 | /* PWM registers and bits definitions */ | ||
| 39 | #define PWMCR (0x00) | ||
| 40 | #define PWMDCR (0x04) | ||
| 41 | #define PWMPCR (0x08) | ||
| 42 | |||
| 43 | #define PWMCR_SD (1 << 6) | ||
| 44 | #define PWMDCR_FD (1 << 10) | ||
| 45 | |||
| 46 | struct pwm_device { | ||
| 47 | struct list_head node; | ||
| 48 | struct pwm_device *secondary; | ||
| 49 | struct platform_device *pdev; | ||
| 50 | |||
| 51 | const char *label; | ||
| 52 | struct clk *clk; | ||
| 53 | int clk_enabled; | ||
| 54 | void __iomem *mmio_base; | ||
| 55 | |||
| 56 | unsigned int use_count; | ||
| 57 | unsigned int pwm_id; | ||
| 58 | }; | ||
| 59 | |||
| 60 | /* | ||
| 61 | * period_ns = 10^9 * (PRESCALE + 1) * (PV + 1) / PWM_CLK_RATE | ||
| 62 | * duty_ns = 10^9 * (PRESCALE + 1) * DC / PWM_CLK_RATE | ||
| 63 | */ | ||
| 64 | int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) | ||
| 65 | { | ||
| 66 | unsigned long long c; | ||
| 67 | unsigned long period_cycles, prescale, pv, dc; | ||
| 68 | |||
| 69 | if (pwm == NULL || period_ns == 0 || duty_ns > period_ns) | ||
| 70 | return -EINVAL; | ||
| 71 | |||
| 72 | c = clk_get_rate(pwm->clk); | ||
| 73 | c = c * period_ns; | ||
| 74 | do_div(c, 1000000000); | ||
| 75 | period_cycles = c; | ||
| 76 | |||
| 77 | if (period_cycles < 1) | ||
| 78 | period_cycles = 1; | ||
| 79 | prescale = (period_cycles - 1) / 1024; | ||
| 80 | pv = period_cycles / (prescale + 1) - 1; | ||
| 81 | |||
| 82 | if (prescale > 63) | ||
| 83 | return -EINVAL; | ||
| 84 | |||
| 85 | if (duty_ns == period_ns) | ||
| 86 | dc = PWMDCR_FD; | ||
| 87 | else | ||
| 88 | dc = (pv + 1) * duty_ns / period_ns; | ||
| 89 | |||
| 90 | /* NOTE: the clock to PWM has to be enabled first | ||
| 91 | * before writing to the registers | ||
| 92 | */ | ||
| 93 | clk_enable(pwm->clk); | ||
| 94 | __raw_writel(prescale, pwm->mmio_base + PWMCR); | ||
| 95 | __raw_writel(dc, pwm->mmio_base + PWMDCR); | ||
| 96 | __raw_writel(pv, pwm->mmio_base + PWMPCR); | ||
| 97 | clk_disable(pwm->clk); | ||
| 98 | |||
| 99 | return 0; | ||
| 100 | } | ||
| 101 | EXPORT_SYMBOL(pwm_config); | ||
| 102 | |||
| 103 | int pwm_enable(struct pwm_device *pwm) | ||
| 104 | { | ||
| 105 | int rc = 0; | ||
| 106 | |||
| 107 | if (!pwm->clk_enabled) { | ||
| 108 | rc = clk_enable(pwm->clk); | ||
| 109 | if (!rc) | ||
| 110 | pwm->clk_enabled = 1; | ||
| 111 | } | ||
| 112 | return rc; | ||
| 113 | } | ||
| 114 | EXPORT_SYMBOL(pwm_enable); | ||
| 115 | |||
| 116 | void pwm_disable(struct pwm_device *pwm) | ||
| 117 | { | ||
| 118 | if (pwm->clk_enabled) { | ||
| 119 | clk_disable(pwm->clk); | ||
| 120 | pwm->clk_enabled = 0; | ||
| 121 | } | ||
| 122 | } | ||
| 123 | EXPORT_SYMBOL(pwm_disable); | ||
| 124 | |||
| 125 | static DEFINE_MUTEX(pwm_lock); | ||
| 126 | static LIST_HEAD(pwm_list); | ||
| 127 | |||
| 128 | struct pwm_device *pwm_request(int pwm_id, const char *label) | ||
| 129 | { | ||
| 130 | struct pwm_device *pwm; | ||
| 131 | int found = 0; | ||
| 132 | |||
| 133 | mutex_lock(&pwm_lock); | ||
| 134 | |||
| 135 | list_for_each_entry(pwm, &pwm_list, node) { | ||
| 136 | if (pwm->pwm_id == pwm_id) { | ||
| 137 | found = 1; | ||
| 138 | break; | ||
| 139 | } | ||
| 140 | } | ||
| 141 | |||
| 142 | if (found) { | ||
| 143 | if (pwm->use_count == 0) { | ||
| 144 | pwm->use_count++; | ||
| 145 | pwm->label = label; | ||
| 146 | } else | ||
| 147 | pwm = ERR_PTR(-EBUSY); | ||
| 148 | } else | ||
| 149 | pwm = ERR_PTR(-ENOENT); | ||
| 150 | |||
| 151 | mutex_unlock(&pwm_lock); | ||
| 152 | return pwm; | ||
| 153 | } | ||
| 154 | EXPORT_SYMBOL(pwm_request); | ||
| 155 | |||
| 156 | void pwm_free(struct pwm_device *pwm) | ||
| 157 | { | ||
| 158 | mutex_lock(&pwm_lock); | ||
| 159 | |||
| 160 | if (pwm->use_count) { | ||
| 161 | pwm->use_count--; | ||
| 162 | pwm->label = NULL; | ||
| 163 | } else | ||
| 164 | pr_warning("PWM device already freed\n"); | ||
| 165 | |||
| 166 | mutex_unlock(&pwm_lock); | ||
| 167 | } | ||
| 168 | EXPORT_SYMBOL(pwm_free); | ||
| 169 | |||
| 170 | static inline void __add_pwm(struct pwm_device *pwm) | ||
| 171 | { | ||
| 172 | mutex_lock(&pwm_lock); | ||
| 173 | list_add_tail(&pwm->node, &pwm_list); | ||
| 174 | mutex_unlock(&pwm_lock); | ||
| 175 | } | ||
| 176 | |||
| 177 | static int __devinit pwm_probe(struct platform_device *pdev) | ||
| 178 | { | ||
| 179 | const struct platform_device_id *id = platform_get_device_id(pdev); | ||
| 180 | struct pwm_device *pwm, *secondary = NULL; | ||
| 181 | struct resource *r; | ||
| 182 | int ret = 0; | ||
| 183 | |||
| 184 | pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL); | ||
| 185 | if (pwm == NULL) { | ||
| 186 | dev_err(&pdev->dev, "failed to allocate memory\n"); | ||
| 187 | return -ENOMEM; | ||
| 188 | } | ||
| 189 | |||
| 190 | pwm->clk = clk_get(&pdev->dev, NULL); | ||
| 191 | if (IS_ERR(pwm->clk)) { | ||
| 192 | ret = PTR_ERR(pwm->clk); | ||
| 193 | goto err_free; | ||
| 194 | } | ||
| 195 | pwm->clk_enabled = 0; | ||
| 196 | |||
| 197 | pwm->use_count = 0; | ||
| 198 | pwm->pwm_id = PWM_ID_BASE(id->driver_data) + pdev->id; | ||
| 199 | pwm->pdev = pdev; | ||
| 200 | |||
| 201 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 202 | if (r == NULL) { | ||
| 203 | dev_err(&pdev->dev, "no memory resource defined\n"); | ||
| 204 | ret = -ENODEV; | ||
| 205 | goto err_free_clk; | ||
| 206 | } | ||
| 207 | |||
| 208 | r = request_mem_region(r->start, resource_size(r), pdev->name); | ||
| 209 | if (r == NULL) { | ||
| 210 | dev_err(&pdev->dev, "failed to request memory resource\n"); | ||
| 211 | ret = -EBUSY; | ||
| 212 | goto err_free_clk; | ||
| 213 | } | ||
| 214 | |||
| 215 | pwm->mmio_base = ioremap(r->start, resource_size(r)); | ||
| 216 | if (pwm->mmio_base == NULL) { | ||
| 217 | dev_err(&pdev->dev, "failed to ioremap() registers\n"); | ||
| 218 | ret = -ENODEV; | ||
| 219 | goto err_free_mem; | ||
| 220 | } | ||
| 221 | |||
| 222 | if (id->driver_data & HAS_SECONDARY_PWM) { | ||
| 223 | secondary = kzalloc(sizeof(struct pwm_device), GFP_KERNEL); | ||
| 224 | if (secondary == NULL) { | ||
| 225 | ret = -ENOMEM; | ||
| 226 | goto err_free_mem; | ||
| 227 | } | ||
| 228 | |||
| 229 | *secondary = *pwm; | ||
| 230 | pwm->secondary = secondary; | ||
| 231 | |||
| 232 | /* registers for the second PWM has offset of 0x10 */ | ||
| 233 | secondary->mmio_base = pwm->mmio_base + 0x10; | ||
| 234 | secondary->pwm_id = pdev->id + 2; | ||
| 235 | } | ||
| 236 | |||
| 237 | __add_pwm(pwm); | ||
| 238 | if (secondary) | ||
| 239 | __add_pwm(secondary); | ||
| 240 | |||
| 241 | platform_set_drvdata(pdev, pwm); | ||
| 242 | return 0; | ||
| 243 | |||
| 244 | err_free_mem: | ||
| 245 | release_mem_region(r->start, resource_size(r)); | ||
| 246 | err_free_clk: | ||
| 247 | clk_put(pwm->clk); | ||
| 248 | err_free: | ||
| 249 | kfree(pwm); | ||
| 250 | return ret; | ||
| 251 | } | ||
| 252 | |||
| 253 | static int __devexit pwm_remove(struct platform_device *pdev) | ||
| 254 | { | ||
| 255 | struct pwm_device *pwm; | ||
| 256 | struct resource *r; | ||
| 257 | |||
| 258 | pwm = platform_get_drvdata(pdev); | ||
| 259 | if (pwm == NULL) | ||
| 260 | return -ENODEV; | ||
| 261 | |||
| 262 | mutex_lock(&pwm_lock); | ||
| 263 | |||
| 264 | if (pwm->secondary) { | ||
| 265 | list_del(&pwm->secondary->node); | ||
| 266 | kfree(pwm->secondary); | ||
| 267 | } | ||
| 268 | |||
| 269 | list_del(&pwm->node); | ||
| 270 | mutex_unlock(&pwm_lock); | ||
| 271 | |||
| 272 | iounmap(pwm->mmio_base); | ||
| 273 | |||
| 274 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 275 | release_mem_region(r->start, resource_size(r)); | ||
| 276 | |||
| 277 | clk_put(pwm->clk); | ||
| 278 | kfree(pwm); | ||
| 279 | return 0; | ||
| 280 | } | ||
| 281 | |||
| 282 | static struct platform_driver pwm_driver = { | ||
| 283 | .driver = { | ||
| 284 | .name = "pxa25x-pwm", | ||
| 285 | .owner = THIS_MODULE, | ||
| 286 | }, | ||
| 287 | .probe = pwm_probe, | ||
| 288 | .remove = __devexit_p(pwm_remove), | ||
| 289 | .id_table = pwm_id_table, | ||
| 290 | }; | ||
| 291 | |||
| 292 | static int __init pwm_init(void) | ||
| 293 | { | ||
| 294 | return platform_driver_register(&pwm_driver); | ||
| 295 | } | ||
| 296 | arch_initcall(pwm_init); | ||
| 297 | |||
| 298 | static void __exit pwm_exit(void) | ||
| 299 | { | ||
| 300 | platform_driver_unregister(&pwm_driver); | ||
| 301 | } | ||
| 302 | module_exit(pwm_exit); | ||
| 303 | |||
| 304 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile index b78717496677..9e40e8d00740 100644 --- a/arch/arm/plat-samsung/Makefile +++ b/arch/arm/plat-samsung/Makefile | |||
| @@ -59,7 +59,3 @@ obj-$(CONFIG_SAMSUNG_WAKEMASK) += wakeup-mask.o | |||
| 59 | 59 | ||
| 60 | obj-$(CONFIG_S5P_PM) += s5p-pm.o s5p-irq-pm.o | 60 | obj-$(CONFIG_S5P_PM) += s5p-pm.o s5p-irq-pm.o |
| 61 | obj-$(CONFIG_S5P_SLEEP) += s5p-sleep.o | 61 | obj-$(CONFIG_S5P_SLEEP) += s5p-sleep.o |
| 62 | |||
| 63 | # PWM support | ||
| 64 | |||
| 65 | obj-$(CONFIG_HAVE_PWM) += pwm.o | ||
diff --git a/arch/arm/plat-samsung/pwm.c b/arch/arm/plat-samsung/pwm.c deleted file mode 100644 index d3583050fb05..000000000000 --- a/arch/arm/plat-samsung/pwm.c +++ /dev/null | |||
| @@ -1,416 +0,0 @@ | |||
| 1 | /* arch/arm/plat-s3c/pwm.c | ||
| 2 | * | ||
| 3 | * Copyright (c) 2007 Ben Dooks | ||
| 4 | * Copyright (c) 2008 Simtec Electronics | ||
| 5 | * Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org> | ||
| 6 | * | ||
| 7 | * S3C series PWM device core | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License as published by | ||
| 11 | * the Free Software Foundation; either version 2 of the License. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/export.h> | ||
| 15 | #include <linux/kernel.h> | ||
| 16 | #include <linux/platform_device.h> | ||
| 17 | #include <linux/slab.h> | ||
| 18 | #include <linux/err.h> | ||
| 19 | #include <linux/clk.h> | ||
| 20 | #include <linux/io.h> | ||
| 21 | #include <linux/pwm.h> | ||
| 22 | |||
| 23 | #include <mach/map.h> | ||
| 24 | |||
| 25 | #include <plat/regs-timer.h> | ||
| 26 | |||
| 27 | struct pwm_device { | ||
| 28 | struct list_head list; | ||
| 29 | struct platform_device *pdev; | ||
| 30 | |||
| 31 | struct clk *clk_div; | ||
| 32 | struct clk *clk; | ||
| 33 | const char *label; | ||
| 34 | |||
| 35 | unsigned int period_ns; | ||
| 36 | unsigned int duty_ns; | ||
| 37 | |||
| 38 | unsigned char tcon_base; | ||
| 39 | unsigned char use_count; | ||
| 40 | unsigned char pwm_id; | ||
| 41 | }; | ||
| 42 | |||
| 43 | #define pwm_dbg(_pwm, msg...) dev_dbg(&(_pwm)->pdev->dev, msg) | ||
| 44 | |||
| 45 | static struct clk *clk_scaler[2]; | ||
| 46 | |||
| 47 | static inline int pwm_is_tdiv(struct pwm_device *pwm) | ||
| 48 | { | ||
| 49 | return clk_get_parent(pwm->clk) == pwm->clk_div; | ||
| 50 | } | ||
| 51 | |||
| 52 | static DEFINE_MUTEX(pwm_lock); | ||
| 53 | static LIST_HEAD(pwm_list); | ||
| 54 | |||
| 55 | struct pwm_device *pwm_request(int pwm_id, const char *label) | ||
| 56 | { | ||
| 57 | struct pwm_device *pwm; | ||
| 58 | int found = 0; | ||
| 59 | |||
| 60 | mutex_lock(&pwm_lock); | ||
| 61 | |||
| 62 | list_for_each_entry(pwm, &pwm_list, list) { | ||
| 63 | if (pwm->pwm_id == pwm_id) { | ||
| 64 | found = 1; | ||
| 65 | break; | ||
| 66 | } | ||
| 67 | } | ||
| 68 | |||
| 69 | if (found) { | ||
| 70 | if (pwm->use_count == 0) { | ||
| 71 | pwm->use_count = 1; | ||
| 72 | pwm->label = label; | ||
| 73 | } else | ||
| 74 | pwm = ERR_PTR(-EBUSY); | ||
| 75 | } else | ||
| 76 | pwm = ERR_PTR(-ENOENT); | ||
| 77 | |||
| 78 | mutex_unlock(&pwm_lock); | ||
| 79 | return pwm; | ||
| 80 | } | ||
| 81 | |||
| 82 | EXPORT_SYMBOL(pwm_request); | ||
| 83 | |||
| 84 | |||
| 85 | void pwm_free(struct pwm_device *pwm) | ||
| 86 | { | ||
| 87 | mutex_lock(&pwm_lock); | ||
| 88 | |||
| 89 | if (pwm->use_count) { | ||
| 90 | pwm->use_count--; | ||
| 91 | pwm->label = NULL; | ||
| 92 | } else | ||
| 93 | printk(KERN_ERR "PWM%d device already freed\n", pwm->pwm_id); | ||
| 94 | |||
| 95 | mutex_unlock(&pwm_lock); | ||
| 96 | } | ||
| 97 | |||
| 98 | EXPORT_SYMBOL(pwm_free); | ||
| 99 | |||
| 100 | #define pwm_tcon_start(pwm) (1 << (pwm->tcon_base + 0)) | ||
| 101 | #define pwm_tcon_invert(pwm) (1 << (pwm->tcon_base + 2)) | ||
| 102 | #define pwm_tcon_autoreload(pwm) (1 << (pwm->tcon_base + 3)) | ||
| 103 | #define pwm_tcon_manulupdate(pwm) (1 << (pwm->tcon_base + 1)) | ||
| 104 | |||
| 105 | int pwm_enable(struct pwm_device *pwm) | ||
| 106 | { | ||
| 107 | unsigned long flags; | ||
| 108 | unsigned long tcon; | ||
| 109 | |||
| 110 | local_irq_save(flags); | ||
| 111 | |||
| 112 | tcon = __raw_readl(S3C2410_TCON); | ||
| 113 | tcon |= pwm_tcon_start(pwm); | ||
| 114 | __raw_writel(tcon, S3C2410_TCON); | ||
| 115 | |||
| 116 | local_irq_restore(flags); | ||
| 117 | |||
| 118 | return 0; | ||
| 119 | } | ||
| 120 | |||
| 121 | EXPORT_SYMBOL(pwm_enable); | ||
| 122 | |||
| 123 | void pwm_disable(struct pwm_device *pwm) | ||
| 124 | { | ||
| 125 | unsigned long flags; | ||
| 126 | unsigned long tcon; | ||
| 127 | |||
| 128 | local_irq_save(flags); | ||
| 129 | |||
| 130 | tcon = __raw_readl(S3C2410_TCON); | ||
| 131 | tcon &= ~pwm_tcon_start(pwm); | ||
| 132 | __raw_writel(tcon, S3C2410_TCON); | ||
| 133 | |||
| 134 | local_irq_restore(flags); | ||
| 135 | } | ||
| 136 | |||
| 137 | EXPORT_SYMBOL(pwm_disable); | ||
| 138 | |||
| 139 | static unsigned long pwm_calc_tin(struct pwm_device *pwm, unsigned long freq) | ||
| 140 | { | ||
| 141 | unsigned long tin_parent_rate; | ||
| 142 | unsigned int div; | ||
| 143 | |||
| 144 | tin_parent_rate = clk_get_rate(clk_get_parent(pwm->clk_div)); | ||
| 145 | pwm_dbg(pwm, "tin parent at %lu\n", tin_parent_rate); | ||
| 146 | |||
| 147 | for (div = 2; div <= 16; div *= 2) { | ||
| 148 | if ((tin_parent_rate / (div << 16)) < freq) | ||
| 149 | return tin_parent_rate / div; | ||
| 150 | } | ||
| 151 | |||
| 152 | return tin_parent_rate / 16; | ||
| 153 | } | ||
| 154 | |||
| 155 | #define NS_IN_HZ (1000000000UL) | ||
| 156 | |||
| 157 | int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) | ||
| 158 | { | ||
| 159 | unsigned long tin_rate; | ||
| 160 | unsigned long tin_ns; | ||
| 161 | unsigned long period; | ||
| 162 | unsigned long flags; | ||
| 163 | unsigned long tcon; | ||
| 164 | unsigned long tcnt; | ||
| 165 | long tcmp; | ||
| 166 | |||
| 167 | /* We currently avoid using 64bit arithmetic by using the | ||
| 168 | * fact that anything faster than 1Hz is easily representable | ||
| 169 | * by 32bits. */ | ||
| 170 | |||
| 171 | if (period_ns > NS_IN_HZ || duty_ns > NS_IN_HZ) | ||
| 172 | return -ERANGE; | ||
| 173 | |||
| 174 | if (duty_ns > period_ns) | ||
| 175 | return -EINVAL; | ||
| 176 | |||
| 177 | if (period_ns == pwm->period_ns && | ||
| 178 | duty_ns == pwm->duty_ns) | ||
| 179 | return 0; | ||
| 180 | |||
| 181 | /* The TCMP and TCNT can be read without a lock, they're not | ||
| 182 | * shared between the timers. */ | ||
| 183 | |||
| 184 | tcmp = __raw_readl(S3C2410_TCMPB(pwm->pwm_id)); | ||
| 185 | tcnt = __raw_readl(S3C2410_TCNTB(pwm->pwm_id)); | ||
| 186 | |||
| 187 | period = NS_IN_HZ / period_ns; | ||
| 188 | |||
| 189 | pwm_dbg(pwm, "duty_ns=%d, period_ns=%d (%lu)\n", | ||
| 190 | duty_ns, period_ns, period); | ||
| 191 | |||
| 192 | /* Check to see if we are changing the clock rate of the PWM */ | ||
| 193 | |||
| 194 | if (pwm->period_ns != period_ns) { | ||
| 195 | if (pwm_is_tdiv(pwm)) { | ||
| 196 | tin_rate = pwm_calc_tin(pwm, period); | ||
| 197 | clk_set_rate(pwm->clk_div, tin_rate); | ||
| 198 | } else | ||
| 199 | tin_rate = clk_get_rate(pwm->clk); | ||
| 200 | |||
| 201 | pwm->period_ns = period_ns; | ||
| 202 | |||
| 203 | pwm_dbg(pwm, "tin_rate=%lu\n", tin_rate); | ||
| 204 | |||
| 205 | tin_ns = NS_IN_HZ / tin_rate; | ||
| 206 | tcnt = period_ns / tin_ns; | ||
| 207 | } else | ||
| 208 | tin_ns = NS_IN_HZ / clk_get_rate(pwm->clk); | ||
| 209 | |||
| 210 | /* Note, counters count down */ | ||
| 211 | |||
| 212 | tcmp = duty_ns / tin_ns; | ||
| 213 | tcmp = tcnt - tcmp; | ||
| 214 | /* the pwm hw only checks the compare register after a decrement, | ||
| 215 | so the pin never toggles if tcmp = tcnt */ | ||
| 216 | if (tcmp == tcnt) | ||
| 217 | tcmp--; | ||
| 218 | |||
| 219 | pwm_dbg(pwm, "tin_ns=%lu, tcmp=%ld/%lu\n", tin_ns, tcmp, tcnt); | ||
| 220 | |||
| 221 | if (tcmp < 0) | ||
| 222 | tcmp = 0; | ||
| 223 | |||
| 224 | /* Update the PWM register block. */ | ||
| 225 | |||
| 226 | local_irq_save(flags); | ||
| 227 | |||
| 228 | __raw_writel(tcmp, S3C2410_TCMPB(pwm->pwm_id)); | ||
| 229 | __raw_writel(tcnt, S3C2410_TCNTB(pwm->pwm_id)); | ||
| 230 | |||
| 231 | tcon = __raw_readl(S3C2410_TCON); | ||
| 232 | tcon |= pwm_tcon_manulupdate(pwm); | ||
| 233 | tcon |= pwm_tcon_autoreload(pwm); | ||
| 234 | __raw_writel(tcon, S3C2410_TCON); | ||
| 235 | |||
| 236 | tcon &= ~pwm_tcon_manulupdate(pwm); | ||
| 237 | __raw_writel(tcon, S3C2410_TCON); | ||
| 238 | |||
| 239 | local_irq_restore(flags); | ||
| 240 | |||
| 241 | return 0; | ||
| 242 | } | ||
| 243 | |||
| 244 | EXPORT_SYMBOL(pwm_config); | ||
| 245 | |||
| 246 | static int pwm_register(struct pwm_device *pwm) | ||
| 247 | { | ||
| 248 | pwm->duty_ns = -1; | ||
| 249 | pwm->period_ns = -1; | ||
| 250 | |||
| 251 | mutex_lock(&pwm_lock); | ||
| 252 | list_add_tail(&pwm->list, &pwm_list); | ||
| 253 | mutex_unlock(&pwm_lock); | ||
| 254 | |||
| 255 | return 0; | ||
| 256 | } | ||
| 257 | |||
| 258 | static int s3c_pwm_probe(struct platform_device *pdev) | ||
| 259 | { | ||
| 260 | struct device *dev = &pdev->dev; | ||
| 261 | struct pwm_device *pwm; | ||
| 262 | unsigned long flags; | ||
| 263 | unsigned long tcon; | ||
| 264 | unsigned int id = pdev->id; | ||
| 265 | int ret; | ||
| 266 | |||
| 267 | if (id == 4) { | ||
| 268 | dev_err(dev, "TIMER4 is currently not supported\n"); | ||
| 269 | return -ENXIO; | ||
| 270 | } | ||
| 271 | |||
| 272 | pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL); | ||
| 273 | if (pwm == NULL) { | ||
| 274 | dev_err(dev, "failed to allocate pwm_device\n"); | ||
| 275 | return -ENOMEM; | ||
| 276 | } | ||
| 277 | |||
| 278 | pwm->pdev = pdev; | ||
| 279 | pwm->pwm_id = id; | ||
| 280 | |||
| 281 | /* calculate base of control bits in TCON */ | ||
| 282 | pwm->tcon_base = id == 0 ? 0 : (id * 4) + 4; | ||
| 283 | |||
| 284 | pwm->clk = clk_get(dev, "pwm-tin"); | ||
| 285 | if (IS_ERR(pwm->clk)) { | ||
| 286 | dev_err(dev, "failed to get pwm tin clk\n"); | ||
| 287 | ret = PTR_ERR(pwm->clk); | ||
| 288 | goto err_alloc; | ||
| 289 | } | ||
| 290 | |||
| 291 | pwm->clk_div = clk_get(dev, "pwm-tdiv"); | ||
| 292 | if (IS_ERR(pwm->clk_div)) { | ||
| 293 | dev_err(dev, "failed to get pwm tdiv clk\n"); | ||
| 294 | ret = PTR_ERR(pwm->clk_div); | ||
| 295 | goto err_clk_tin; | ||
| 296 | } | ||
| 297 | |||
| 298 | clk_enable(pwm->clk); | ||
| 299 | clk_enable(pwm->clk_div); | ||
| 300 | |||
| 301 | local_irq_save(flags); | ||
| 302 | |||
| 303 | tcon = __raw_readl(S3C2410_TCON); | ||
| 304 | tcon |= pwm_tcon_invert(pwm); | ||
| 305 | __raw_writel(tcon, S3C2410_TCON); | ||
| 306 | |||
| 307 | local_irq_restore(flags); | ||
| 308 | |||
| 309 | |||
| 310 | ret = pwm_register(pwm); | ||
| 311 | if (ret) { | ||
| 312 | dev_err(dev, "failed to register pwm\n"); | ||
| 313 | goto err_clk_tdiv; | ||
| 314 | } | ||
| 315 | |||
| 316 | pwm_dbg(pwm, "config bits %02x\n", | ||
| 317 | (__raw_readl(S3C2410_TCON) >> pwm->tcon_base) & 0x0f); | ||
| 318 | |||
| 319 | dev_info(dev, "tin at %lu, tdiv at %lu, tin=%sclk, base %d\n", | ||
| 320 | clk_get_rate(pwm->clk), | ||
| 321 | clk_get_rate(pwm->clk_div), | ||
| 322 | pwm_is_tdiv(pwm) ? "div" : "ext", pwm->tcon_base); | ||
| 323 | |||
| 324 | platform_set_drvdata(pdev, pwm); | ||
| 325 | return 0; | ||
| 326 | |||
| 327 | err_clk_tdiv: | ||
| 328 | clk_disable(pwm->clk_div); | ||
| 329 | clk_disable(pwm->clk); | ||
| 330 | clk_put(pwm->clk_div); | ||
| 331 | |||
| 332 | err_clk_tin: | ||
| 333 | clk_put(pwm->clk); | ||
| 334 | |||
| 335 | err_alloc: | ||
| 336 | kfree(pwm); | ||
| 337 | return ret; | ||
| 338 | } | ||
| 339 | |||
| 340 | static int __devexit s3c_pwm_remove(struct platform_device *pdev) | ||
| 341 | { | ||
| 342 | struct pwm_device *pwm = platform_get_drvdata(pdev); | ||
| 343 | |||
| 344 | clk_disable(pwm->clk_div); | ||
| 345 | clk_disable(pwm->clk); | ||
| 346 | clk_put(pwm->clk_div); | ||
| 347 | clk_put(pwm->clk); | ||
| 348 | kfree(pwm); | ||
| 349 | |||
| 350 | return 0; | ||
| 351 | } | ||
| 352 | |||
| 353 | #ifdef CONFIG_PM | ||
| 354 | static int s3c_pwm_suspend(struct platform_device *pdev, pm_message_t state) | ||
| 355 | { | ||
| 356 | struct pwm_device *pwm = platform_get_drvdata(pdev); | ||
| 357 | |||
| 358 | /* No one preserve these values during suspend so reset them | ||
| 359 | * Otherwise driver leaves PWM unconfigured if same values | ||
| 360 | * passed to pwm_config | ||
| 361 | */ | ||
| 362 | pwm->period_ns = 0; | ||
| 363 | pwm->duty_ns = 0; | ||
| 364 | |||
| 365 | return 0; | ||
| 366 | } | ||
| 367 | |||
| 368 | static int s3c_pwm_resume(struct platform_device *pdev) | ||
| 369 | { | ||
| 370 | struct pwm_device *pwm = platform_get_drvdata(pdev); | ||
| 371 | unsigned long tcon; | ||
| 372 | |||
| 373 | /* Restore invertion */ | ||
| 374 | tcon = __raw_readl(S3C2410_TCON); | ||
| 375 | tcon |= pwm_tcon_invert(pwm); | ||
| 376 | __raw_writel(tcon, S3C2410_TCON); | ||
| 377 | |||
| 378 | return 0; | ||
| 379 | } | ||
| 380 | |||
| 381 | #else | ||
| 382 | #define s3c_pwm_suspend NULL | ||
| 383 | #define s3c_pwm_resume NULL | ||
| 384 | #endif | ||
| 385 | |||
| 386 | static struct platform_driver s3c_pwm_driver = { | ||
| 387 | .driver = { | ||
| 388 | .name = "s3c24xx-pwm", | ||
| 389 | .owner = THIS_MODULE, | ||
| 390 | }, | ||
| 391 | .probe = s3c_pwm_probe, | ||
| 392 | .remove = __devexit_p(s3c_pwm_remove), | ||
| 393 | .suspend = s3c_pwm_suspend, | ||
| 394 | .resume = s3c_pwm_resume, | ||
| 395 | }; | ||
| 396 | |||
| 397 | static int __init pwm_init(void) | ||
| 398 | { | ||
| 399 | int ret; | ||
| 400 | |||
| 401 | clk_scaler[0] = clk_get(NULL, "pwm-scaler0"); | ||
| 402 | clk_scaler[1] = clk_get(NULL, "pwm-scaler1"); | ||
| 403 | |||
| 404 | if (IS_ERR(clk_scaler[0]) || IS_ERR(clk_scaler[1])) { | ||
| 405 | printk(KERN_ERR "%s: failed to get scaler clocks\n", __func__); | ||
| 406 | return -EINVAL; | ||
| 407 | } | ||
| 408 | |||
| 409 | ret = platform_driver_register(&s3c_pwm_driver); | ||
| 410 | if (ret) | ||
| 411 | printk(KERN_ERR "%s: failed to add pwm driver\n", __func__); | ||
| 412 | |||
| 413 | return ret; | ||
| 414 | } | ||
| 415 | |||
| 416 | arch_initcall(pwm_init); | ||
diff --git a/arch/arm/plat-spear/include/plat/keyboard.h b/arch/arm/plat-spear/include/plat/keyboard.h index 0562f134621d..9248e3a7e333 100644 --- a/arch/arm/plat-spear/include/plat/keyboard.h +++ b/arch/arm/plat-spear/include/plat/keyboard.h | |||
| @@ -149,6 +149,7 @@ int _name[] = { \ | |||
| 149 | * keymap: pointer to keymap data (table and size) | 149 | * keymap: pointer to keymap data (table and size) |
| 150 | * rep: enables key autorepeat | 150 | * rep: enables key autorepeat |
| 151 | * mode: choose keyboard support(9x9, 6x6, 2x2) | 151 | * mode: choose keyboard support(9x9, 6x6, 2x2) |
| 152 | * suspended_rate: rate at which keyboard would operate in suspended mode | ||
| 152 | * | 153 | * |
| 153 | * This structure is supposed to be used by platform code to supply | 154 | * This structure is supposed to be used by platform code to supply |
| 154 | * keymaps to drivers that implement keyboards. | 155 | * keymaps to drivers that implement keyboards. |
| @@ -157,6 +158,7 @@ struct kbd_platform_data { | |||
| 157 | const struct matrix_keymap_data *keymap; | 158 | const struct matrix_keymap_data *keymap; |
| 158 | bool rep; | 159 | bool rep; |
| 159 | unsigned int mode; | 160 | unsigned int mode; |
| 161 | unsigned int suspended_rate; | ||
| 160 | }; | 162 | }; |
| 161 | 163 | ||
| 162 | #endif /* __PLAT_KEYBOARD_H */ | 164 | #endif /* __PLAT_KEYBOARD_H */ |
diff --git a/arch/arm/plat-versatile/platsmp.c b/arch/arm/plat-versatile/platsmp.c index 49c7db48c7f1..d7c5c171f5aa 100644 --- a/arch/arm/plat-versatile/platsmp.c +++ b/arch/arm/plat-versatile/platsmp.c | |||
| @@ -85,7 +85,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) | |||
| 85 | * the boot monitor to read the system wide flags register, | 85 | * the boot monitor to read the system wide flags register, |
| 86 | * and branch to the address found there. | 86 | * and branch to the address found there. |
| 87 | */ | 87 | */ |
| 88 | gic_raise_softirq(cpumask_of(cpu), 1); | 88 | gic_raise_softirq(cpumask_of(cpu), 0); |
| 89 | 89 | ||
| 90 | timeout = jiffies + (1 * HZ); | 90 | timeout = jiffies + (1 * HZ); |
| 91 | while (time_before(jiffies, timeout)) { | 91 | while (time_before(jiffies, timeout)) { |
diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S index 2d30c7f6edd3..d50f0e486cf2 100644 --- a/arch/arm/vfp/vfphw.S +++ b/arch/arm/vfp/vfphw.S | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | */ | 16 | */ |
| 17 | #include <asm/thread_info.h> | 17 | #include <asm/thread_info.h> |
| 18 | #include <asm/vfpmacros.h> | 18 | #include <asm/vfpmacros.h> |
| 19 | #include <linux/kern_levels.h> | ||
| 19 | #include "../kernel/entry-header.S" | 20 | #include "../kernel/entry-header.S" |
| 20 | 21 | ||
| 21 | .macro DBGSTR, str | 22 | .macro DBGSTR, str |
| @@ -24,7 +25,7 @@ | |||
| 24 | add r0, pc, #4 | 25 | add r0, pc, #4 |
| 25 | bl printk | 26 | bl printk |
| 26 | b 1f | 27 | b 1f |
| 27 | .asciz "<7>VFP: \str\n" | 28 | .asciz KERN_DEBUG "VFP: \str\n" |
| 28 | .balign 4 | 29 | .balign 4 |
| 29 | 1: ldmfd sp!, {r0-r3, ip, lr} | 30 | 1: ldmfd sp!, {r0-r3, ip, lr} |
| 30 | #endif | 31 | #endif |
| @@ -37,7 +38,7 @@ | |||
| 37 | add r0, pc, #4 | 38 | add r0, pc, #4 |
| 38 | bl printk | 39 | bl printk |
| 39 | b 1f | 40 | b 1f |
| 40 | .asciz "<7>VFP: \str\n" | 41 | .asciz KERN_DEBUG "VFP: \str\n" |
| 41 | .balign 4 | 42 | .balign 4 |
| 42 | 1: ldmfd sp!, {r0-r3, ip, lr} | 43 | 1: ldmfd sp!, {r0-r3, ip, lr} |
| 43 | #endif | 44 | #endif |
| @@ -52,7 +53,7 @@ | |||
| 52 | add r0, pc, #4 | 53 | add r0, pc, #4 |
| 53 | bl printk | 54 | bl printk |
| 54 | b 1f | 55 | b 1f |
| 55 | .asciz "<7>VFP: \str\n" | 56 | .asciz KERN_DEBUG "VFP: \str\n" |
| 56 | .balign 4 | 57 | .balign 4 |
| 57 | 1: ldmfd sp!, {r0-r3, ip, lr} | 58 | 1: ldmfd sp!, {r0-r3, ip, lr} |
| 58 | #endif | 59 | #endif |
diff --git a/arch/avr32/Kconfig b/arch/avr32/Kconfig index 71d38c76726c..5ade51c8a87f 100644 --- a/arch/avr32/Kconfig +++ b/arch/avr32/Kconfig | |||
| @@ -12,6 +12,7 @@ config AVR32 | |||
| 12 | select HARDIRQS_SW_RESEND | 12 | select HARDIRQS_SW_RESEND |
| 13 | select GENERIC_IRQ_SHOW | 13 | select GENERIC_IRQ_SHOW |
| 14 | select ARCH_HAVE_CUSTOM_GPIO_H | 14 | select ARCH_HAVE_CUSTOM_GPIO_H |
| 15 | select ARCH_WANT_IPC_PARSE_VERSION | ||
| 15 | select ARCH_HAVE_NMI_SAFE_CMPXCHG | 16 | select ARCH_HAVE_NMI_SAFE_CMPXCHG |
| 16 | select GENERIC_CLOCKEVENTS | 17 | select GENERIC_CLOCKEVENTS |
| 17 | help | 18 | help |
diff --git a/arch/avr32/boards/atstk1000/atstk1002.c b/arch/avr32/boards/atstk1000/atstk1002.c index dc5263321480..6c80aba7bf96 100644 --- a/arch/avr32/boards/atstk1000/atstk1002.c +++ b/arch/avr32/boards/atstk1000/atstk1002.c | |||
| @@ -97,7 +97,7 @@ static struct atmel_nand_data atstk1006_nand_data __initdata = { | |||
| 97 | .enable_pin = GPIO_PIN_PB(29), | 97 | .enable_pin = GPIO_PIN_PB(29), |
| 98 | .ecc_mode = NAND_ECC_SOFT, | 98 | .ecc_mode = NAND_ECC_SOFT, |
| 99 | .parts = nand_partitions, | 99 | .parts = nand_partitions, |
| 100 | .num_parts = ARRAY_SIZE(num_partitions), | 100 | .num_parts = ARRAY_SIZE(nand_partitions), |
| 101 | }; | 101 | }; |
| 102 | #endif | 102 | #endif |
| 103 | 103 | ||
diff --git a/arch/avr32/include/asm/kmap_types.h b/arch/avr32/include/asm/kmap_types.h index b7f5c6870107..479330b89796 100644 --- a/arch/avr32/include/asm/kmap_types.h +++ b/arch/avr32/include/asm/kmap_types.h | |||
| @@ -2,29 +2,9 @@ | |||
| 2 | #define __ASM_AVR32_KMAP_TYPES_H | 2 | #define __ASM_AVR32_KMAP_TYPES_H |
| 3 | 3 | ||
| 4 | #ifdef CONFIG_DEBUG_HIGHMEM | 4 | #ifdef CONFIG_DEBUG_HIGHMEM |
| 5 | # define D(n) __KM_FENCE_##n , | 5 | # define KM_TYPE_NR 29 |
| 6 | #else | 6 | #else |
| 7 | # define D(n) | 7 | # define KM_TYPE_NR 14 |
| 8 | #endif | 8 | #endif |
| 9 | 9 | ||
| 10 | enum km_type { | ||
| 11 | D(0) KM_BOUNCE_READ, | ||
| 12 | D(1) KM_SKB_SUNRPC_DATA, | ||
| 13 | D(2) KM_SKB_DATA_SOFTIRQ, | ||
| 14 | D(3) KM_USER0, | ||
| 15 | D(4) KM_USER1, | ||
| 16 | D(5) KM_BIO_SRC_IRQ, | ||
| 17 | D(6) KM_BIO_DST_IRQ, | ||
| 18 | D(7) KM_PTE0, | ||
| 19 | D(8) KM_PTE1, | ||
| 20 | D(9) KM_PTE2, | ||
| 21 | D(10) KM_IRQ0, | ||
| 22 | D(11) KM_IRQ1, | ||
| 23 | D(12) KM_SOFTIRQ0, | ||
| 24 | D(13) KM_SOFTIRQ1, | ||
| 25 | D(14) KM_TYPE_NR | ||
| 26 | }; | ||
| 27 | |||
| 28 | #undef D | ||
| 29 | |||
| 30 | #endif /* __ASM_AVR32_KMAP_TYPES_H */ | 10 | #endif /* __ASM_AVR32_KMAP_TYPES_H */ |
diff --git a/arch/avr32/include/asm/unistd.h b/arch/avr32/include/asm/unistd.h index f714544e5560..1358e366f4be 100644 --- a/arch/avr32/include/asm/unistd.h +++ b/arch/avr32/include/asm/unistd.h | |||
| @@ -318,7 +318,6 @@ | |||
| 318 | /* SMP stuff */ | 318 | /* SMP stuff */ |
| 319 | #define __IGNORE_getcpu | 319 | #define __IGNORE_getcpu |
| 320 | 320 | ||
| 321 | #define __ARCH_WANT_IPC_PARSE_VERSION | ||
| 322 | #define __ARCH_WANT_STAT64 | 321 | #define __ARCH_WANT_STAT64 |
| 323 | #define __ARCH_WANT_SYS_ALARM | 322 | #define __ARCH_WANT_SYS_ALARM |
| 324 | #define __ARCH_WANT_SYS_GETHOSTNAME | 323 | #define __ARCH_WANT_SYS_GETHOSTNAME |
diff --git a/arch/avr32/mm/fault.c b/arch/avr32/mm/fault.c index f7040a1e399f..b92e60958617 100644 --- a/arch/avr32/mm/fault.c +++ b/arch/avr32/mm/fault.c | |||
| @@ -61,10 +61,10 @@ asmlinkage void do_page_fault(unsigned long ecr, struct pt_regs *regs) | |||
| 61 | const struct exception_table_entry *fixup; | 61 | const struct exception_table_entry *fixup; |
| 62 | unsigned long address; | 62 | unsigned long address; |
| 63 | unsigned long page; | 63 | unsigned long page; |
| 64 | int writeaccess; | ||
| 65 | long signr; | 64 | long signr; |
| 66 | int code; | 65 | int code; |
| 67 | int fault; | 66 | int fault; |
| 67 | unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; | ||
| 68 | 68 | ||
| 69 | if (notify_page_fault(regs, ecr)) | 69 | if (notify_page_fault(regs, ecr)) |
| 70 | return; | 70 | return; |
| @@ -86,6 +86,7 @@ asmlinkage void do_page_fault(unsigned long ecr, struct pt_regs *regs) | |||
| 86 | 86 | ||
| 87 | local_irq_enable(); | 87 | local_irq_enable(); |
| 88 | 88 | ||
| 89 | retry: | ||
| 89 | down_read(&mm->mmap_sem); | 90 | down_read(&mm->mmap_sem); |
| 90 | 91 | ||
| 91 | vma = find_vma(mm, address); | 92 | vma = find_vma(mm, address); |
| @@ -104,7 +105,6 @@ asmlinkage void do_page_fault(unsigned long ecr, struct pt_regs *regs) | |||
| 104 | */ | 105 | */ |
| 105 | good_area: | 106 | good_area: |
| 106 | code = SEGV_ACCERR; | 107 | code = SEGV_ACCERR; |
| 107 | writeaccess = 0; | ||
| 108 | 108 | ||
| 109 | switch (ecr) { | 109 | switch (ecr) { |
| 110 | case ECR_PROTECTION_X: | 110 | case ECR_PROTECTION_X: |
| @@ -121,7 +121,7 @@ good_area: | |||
| 121 | case ECR_TLB_MISS_W: | 121 | case ECR_TLB_MISS_W: |
| 122 | if (!(vma->vm_flags & VM_WRITE)) | 122 | if (!(vma->vm_flags & VM_WRITE)) |
| 123 | goto bad_area; | 123 | goto bad_area; |
| 124 | writeaccess = 1; | 124 | flags |= FAULT_FLAG_WRITE; |
| 125 | break; | 125 | break; |
| 126 | default: | 126 | default: |
| 127 | panic("Unhandled case %lu in do_page_fault!", ecr); | 127 | panic("Unhandled case %lu in do_page_fault!", ecr); |
| @@ -132,7 +132,11 @@ good_area: | |||
| 132 | * sure we exit gracefully rather than endlessly redo the | 132 | * sure we exit gracefully rather than endlessly redo the |
| 133 | * fault. | 133 | * fault. |
| 134 | */ | 134 | */ |
| 135 | fault = handle_mm_fault(mm, vma, address, writeaccess ? FAULT_FLAG_WRITE : 0); | 135 | fault = handle_mm_fault(mm, vma, address, flags); |
| 136 | |||
| 137 | if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) | ||
| 138 | return; | ||
| 139 | |||
| 136 | if (unlikely(fault & VM_FAULT_ERROR)) { | 140 | if (unlikely(fault & VM_FAULT_ERROR)) { |
| 137 | if (fault & VM_FAULT_OOM) | 141 | if (fault & VM_FAULT_OOM) |
| 138 | goto out_of_memory; | 142 | goto out_of_memory; |
| @@ -140,10 +144,23 @@ good_area: | |||
| 140 | goto do_sigbus; | 144 | goto do_sigbus; |
| 141 | BUG(); | 145 | BUG(); |
| 142 | } | 146 | } |
| 143 | if (fault & VM_FAULT_MAJOR) | 147 | |
| 144 | tsk->maj_flt++; | 148 | if (flags & FAULT_FLAG_ALLOW_RETRY) { |
| 145 | else | 149 | if (fault & VM_FAULT_MAJOR) |
| 146 | tsk->min_flt++; | 150 | tsk->maj_flt++; |
| 151 | else | ||
| 152 | tsk->min_flt++; | ||
| 153 | if (fault & VM_FAULT_RETRY) { | ||
| 154 | flags &= ~FAULT_FLAG_ALLOW_RETRY; | ||
| 155 | |||
| 156 | /* | ||
| 157 | * No need to up_read(&mm->mmap_sem) as we would have | ||
| 158 | * already released it in __lock_page_or_retry() in | ||
| 159 | * mm/filemap.c. | ||
| 160 | */ | ||
| 161 | goto retry; | ||
| 162 | } | ||
| 163 | } | ||
| 147 | 164 | ||
| 148 | up_read(&mm->mmap_sem); | 165 | up_read(&mm->mmap_sem); |
| 149 | return; | 166 | return; |
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index 9b765107e15c..f34861920634 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig | |||
| @@ -33,6 +33,7 @@ config BLACKFIN | |||
| 33 | select HAVE_PERF_EVENTS | 33 | select HAVE_PERF_EVENTS |
| 34 | select ARCH_HAVE_CUSTOM_GPIO_H | 34 | select ARCH_HAVE_CUSTOM_GPIO_H |
| 35 | select ARCH_WANT_OPTIONAL_GPIOLIB | 35 | select ARCH_WANT_OPTIONAL_GPIOLIB |
| 36 | select ARCH_WANT_IPC_PARSE_VERSION | ||
| 36 | select HAVE_GENERIC_HARDIRQS | 37 | select HAVE_GENERIC_HARDIRQS |
| 37 | select GENERIC_ATOMIC64 | 38 | select GENERIC_ATOMIC64 |
| 38 | select GENERIC_IRQ_PROBE | 39 | select GENERIC_IRQ_PROBE |
| @@ -1002,16 +1003,6 @@ config BFIN_GPTIMERS | |||
| 1002 | To compile this driver as a module, choose M here: the module | 1003 | To compile this driver as a module, choose M here: the module |
| 1003 | will be called gptimers. | 1004 | will be called gptimers. |
| 1004 | 1005 | ||
| 1005 | config HAVE_PWM | ||
| 1006 | tristate "Enable PWM API support" | ||
| 1007 | depends on BFIN_GPTIMERS | ||
| 1008 | help | ||
| 1009 | Enable support for the Pulse Width Modulation framework (as | ||
| 1010 | found in linux/pwm.h). | ||
| 1011 | |||
| 1012 | To compile this driver as a module, choose M here: the module | ||
| 1013 | will be called pwm. | ||
| 1014 | |||
| 1015 | choice | 1006 | choice |
| 1016 | prompt "Uncached DMA region" | 1007 | prompt "Uncached DMA region" |
| 1017 | default DMA_UNCACHED_1M | 1008 | default DMA_UNCACHED_1M |
diff --git a/arch/blackfin/include/asm/unistd.h b/arch/blackfin/include/asm/unistd.h index 3287222cba34..5b2a0748d7d3 100644 --- a/arch/blackfin/include/asm/unistd.h +++ b/arch/blackfin/include/asm/unistd.h | |||
| @@ -434,7 +434,6 @@ | |||
| 434 | #define __IGNORE_getcpu | 434 | #define __IGNORE_getcpu |
| 435 | 435 | ||
| 436 | #ifdef __KERNEL__ | 436 | #ifdef __KERNEL__ |
| 437 | #define __ARCH_WANT_IPC_PARSE_VERSION | ||
| 438 | #define __ARCH_WANT_STAT64 | 437 | #define __ARCH_WANT_STAT64 |
| 439 | #define __ARCH_WANT_SYS_ALARM | 438 | #define __ARCH_WANT_SYS_ALARM |
| 440 | #define __ARCH_WANT_SYS_GETHOSTNAME | 439 | #define __ARCH_WANT_SYS_GETHOSTNAME |
diff --git a/arch/blackfin/kernel/Makefile b/arch/blackfin/kernel/Makefile index 08e6625106be..735f24e07425 100644 --- a/arch/blackfin/kernel/Makefile +++ b/arch/blackfin/kernel/Makefile | |||
| @@ -21,7 +21,6 @@ obj-$(CONFIG_FUNCTION_TRACER) += ftrace-entry.o | |||
| 21 | obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o | 21 | obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o |
| 22 | CFLAGS_REMOVE_ftrace.o = -pg | 22 | CFLAGS_REMOVE_ftrace.o = -pg |
| 23 | 23 | ||
| 24 | obj-$(CONFIG_HAVE_PWM) += pwm.o | ||
| 25 | obj-$(CONFIG_IPIPE) += ipipe.o | 24 | obj-$(CONFIG_IPIPE) += ipipe.o |
| 26 | obj-$(CONFIG_BFIN_GPTIMERS) += gptimers.o | 25 | obj-$(CONFIG_BFIN_GPTIMERS) += gptimers.o |
| 27 | obj-$(CONFIG_CPLB_INFO) += cplbinfo.o | 26 | obj-$(CONFIG_CPLB_INFO) += cplbinfo.o |
diff --git a/arch/blackfin/kernel/pwm.c b/arch/blackfin/kernel/pwm.c deleted file mode 100644 index 33f5942733bd..000000000000 --- a/arch/blackfin/kernel/pwm.c +++ /dev/null | |||
| @@ -1,100 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Blackfin Pulse Width Modulation (PWM) core | ||
| 3 | * | ||
| 4 | * Copyright (c) 2011 Analog Devices Inc. | ||
| 5 | * | ||
| 6 | * Licensed under the GPL-2 or later. | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/module.h> | ||
| 10 | #include <linux/pwm.h> | ||
| 11 | #include <linux/slab.h> | ||
| 12 | |||
| 13 | #include <asm/gptimers.h> | ||
| 14 | #include <asm/portmux.h> | ||
| 15 | |||
| 16 | struct pwm_device { | ||
| 17 | unsigned id; | ||
| 18 | unsigned short pin; | ||
| 19 | }; | ||
| 20 | |||
| 21 | static const unsigned short pwm_to_gptimer_per[] = { | ||
| 22 | P_TMR0, P_TMR1, P_TMR2, P_TMR3, P_TMR4, P_TMR5, | ||
| 23 | P_TMR6, P_TMR7, P_TMR8, P_TMR9, P_TMR10, P_TMR11, | ||
| 24 | }; | ||
| 25 | |||
| 26 | struct pwm_device *pwm_request(int pwm_id, const char *label) | ||
| 27 | { | ||
| 28 | struct pwm_device *pwm; | ||
| 29 | int ret; | ||
| 30 | |||
| 31 | /* XXX: pwm_id really should be unsigned */ | ||
| 32 | if (pwm_id < 0) | ||
| 33 | return NULL; | ||
| 34 | |||
| 35 | pwm = kzalloc(sizeof(*pwm), GFP_KERNEL); | ||
| 36 | if (!pwm) | ||
| 37 | return pwm; | ||
| 38 | |||
| 39 | pwm->id = pwm_id; | ||
| 40 | if (pwm->id >= ARRAY_SIZE(pwm_to_gptimer_per)) | ||
| 41 | goto err; | ||
| 42 | |||
| 43 | pwm->pin = pwm_to_gptimer_per[pwm->id]; | ||
| 44 | ret = peripheral_request(pwm->pin, label); | ||
| 45 | if (ret) | ||
| 46 | goto err; | ||
| 47 | |||
| 48 | return pwm; | ||
| 49 | err: | ||
| 50 | kfree(pwm); | ||
| 51 | return NULL; | ||
| 52 | } | ||
| 53 | EXPORT_SYMBOL(pwm_request); | ||
| 54 | |||
| 55 | void pwm_free(struct pwm_device *pwm) | ||
| 56 | { | ||
| 57 | peripheral_free(pwm->pin); | ||
| 58 | kfree(pwm); | ||
| 59 | } | ||
| 60 | EXPORT_SYMBOL(pwm_free); | ||
| 61 | |||
| 62 | int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) | ||
| 63 | { | ||
| 64 | unsigned long period, duty; | ||
| 65 | unsigned long long val; | ||
| 66 | |||
| 67 | if (duty_ns < 0 || duty_ns > period_ns) | ||
| 68 | return -EINVAL; | ||
| 69 | |||
| 70 | val = (unsigned long long)get_sclk() * period_ns; | ||
| 71 | do_div(val, NSEC_PER_SEC); | ||
| 72 | period = val; | ||
| 73 | |||
| 74 | val = (unsigned long long)period * duty_ns; | ||
| 75 | do_div(val, period_ns); | ||
| 76 | duty = period - val; | ||
| 77 | |||
| 78 | if (duty >= period) | ||
| 79 | duty = period - 1; | ||
| 80 | |||
| 81 | set_gptimer_config(pwm->id, TIMER_MODE_PWM | TIMER_PERIOD_CNT); | ||
| 82 | set_gptimer_pwidth(pwm->id, duty); | ||
| 83 | set_gptimer_period(pwm->id, period); | ||
| 84 | |||
| 85 | return 0; | ||
| 86 | } | ||
| 87 | EXPORT_SYMBOL(pwm_config); | ||
| 88 | |||
| 89 | int pwm_enable(struct pwm_device *pwm) | ||
| 90 | { | ||
| 91 | enable_gptimer(pwm->id); | ||
| 92 | return 0; | ||
| 93 | } | ||
| 94 | EXPORT_SYMBOL(pwm_enable); | ||
| 95 | |||
| 96 | void pwm_disable(struct pwm_device *pwm) | ||
| 97 | { | ||
| 98 | disable_gptimer(pwm->id); | ||
| 99 | } | ||
| 100 | EXPORT_SYMBOL(pwm_disable); | ||
diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig index bb344650a14f..e92215428a37 100644 --- a/arch/cris/Kconfig +++ b/arch/cris/Kconfig | |||
| @@ -42,6 +42,7 @@ config CRIS | |||
| 42 | select HAVE_IDE | 42 | select HAVE_IDE |
| 43 | select GENERIC_ATOMIC64 | 43 | select GENERIC_ATOMIC64 |
| 44 | select HAVE_GENERIC_HARDIRQS | 44 | select HAVE_GENERIC_HARDIRQS |
| 45 | select ARCH_WANT_IPC_PARSE_VERSION | ||
| 45 | select GENERIC_IRQ_SHOW | 46 | select GENERIC_IRQ_SHOW |
| 46 | select GENERIC_IOMAP | 47 | select GENERIC_IOMAP |
| 47 | select GENERIC_SMP_IDLE_THREAD if ETRAX_ARCH_V32 | 48 | select GENERIC_SMP_IDLE_THREAD if ETRAX_ARCH_V32 |
diff --git a/arch/cris/include/asm/unistd.h b/arch/cris/include/asm/unistd.h index f921b8b0f97e..51873a446f87 100644 --- a/arch/cris/include/asm/unistd.h +++ b/arch/cris/include/asm/unistd.h | |||
| @@ -347,7 +347,6 @@ | |||
| 347 | 347 | ||
| 348 | #include <arch/unistd.h> | 348 | #include <arch/unistd.h> |
| 349 | 349 | ||
| 350 | #define __ARCH_WANT_IPC_PARSE_VERSION | ||
| 351 | #define __ARCH_WANT_OLD_READDIR | 350 | #define __ARCH_WANT_OLD_READDIR |
| 352 | #define __ARCH_WANT_OLD_STAT | 351 | #define __ARCH_WANT_OLD_STAT |
| 353 | #define __ARCH_WANT_STAT64 | 352 | #define __ARCH_WANT_STAT64 |
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig index a685910d2d5c..971c0a19facb 100644 --- a/arch/frv/Kconfig +++ b/arch/frv/Kconfig | |||
| @@ -9,6 +9,7 @@ config FRV | |||
| 9 | select GENERIC_IRQ_SHOW | 9 | select GENERIC_IRQ_SHOW |
| 10 | select ARCH_HAVE_NMI_SAFE_CMPXCHG | 10 | select ARCH_HAVE_NMI_SAFE_CMPXCHG |
| 11 | select GENERIC_CPU_DEVICES | 11 | select GENERIC_CPU_DEVICES |
| 12 | select ARCH_WANT_IPC_PARSE_VERSION | ||
| 12 | 13 | ||
| 13 | config ZONE_DMA | 14 | config ZONE_DMA |
| 14 | bool | 15 | bool |
diff --git a/arch/frv/include/asm/cpumask.h b/arch/frv/include/asm/cpumask.h deleted file mode 100644 index d999c20c84d2..000000000000 --- a/arch/frv/include/asm/cpumask.h +++ /dev/null | |||
| @@ -1,6 +0,0 @@ | |||
| 1 | #ifndef _ASM_CPUMASK_H | ||
| 2 | #define _ASM_CPUMASK_H | ||
| 3 | |||
| 4 | #include <asm-generic/cpumask.h> | ||
| 5 | |||
| 6 | #endif /* _ASM_CPUMASK_H */ | ||
diff --git a/arch/frv/include/asm/highmem.h b/arch/frv/include/asm/highmem.h index 716956a5317b..b3adc93611f3 100644 --- a/arch/frv/include/asm/highmem.h +++ b/arch/frv/include/asm/highmem.h | |||
| @@ -76,15 +76,16 @@ extern struct page *kmap_atomic_to_page(void *ptr); | |||
| 76 | 76 | ||
| 77 | #ifndef __ASSEMBLY__ | 77 | #ifndef __ASSEMBLY__ |
| 78 | 78 | ||
| 79 | #define __kmap_atomic_primary(type, paddr, ampr) \ | 79 | #define __kmap_atomic_primary(cached, paddr, ampr) \ |
| 80 | ({ \ | 80 | ({ \ |
| 81 | unsigned long damlr, dampr; \ | 81 | unsigned long damlr, dampr; \ |
| 82 | \ | 82 | \ |
| 83 | dampr = paddr | xAMPRx_L | xAMPRx_M | xAMPRx_S | xAMPRx_SS_16Kb | xAMPRx_V; \ | 83 | dampr = paddr | xAMPRx_L | xAMPRx_M | xAMPRx_S | xAMPRx_SS_16Kb | xAMPRx_V; \ |
| 84 | \ | 84 | \ |
| 85 | if (type != __KM_CACHE) \ | 85 | if (!cached) \ |
| 86 | asm volatile("movgs %0,dampr"#ampr :: "r"(dampr) : "memory"); \ | 86 | asm volatile("movgs %0,dampr"#ampr :: "r"(dampr) : "memory"); \ |
| 87 | else \ | 87 | else \ |
| 88 | /* cache flush page attachment point */ \ | ||
| 88 | asm volatile("movgs %0,iampr"#ampr"\n" \ | 89 | asm volatile("movgs %0,iampr"#ampr"\n" \ |
| 89 | "movgs %0,dampr"#ampr"\n" \ | 90 | "movgs %0,dampr"#ampr"\n" \ |
| 90 | :: "r"(dampr) : "memory" \ | 91 | :: "r"(dampr) : "memory" \ |
| @@ -112,29 +113,20 @@ extern struct page *kmap_atomic_to_page(void *ptr); | |||
| 112 | (void *) damlr; \ | 113 | (void *) damlr; \ |
| 113 | }) | 114 | }) |
| 114 | 115 | ||
| 115 | static inline void *kmap_atomic_primary(struct page *page, enum km_type type) | 116 | static inline void *kmap_atomic_primary(struct page *page) |
| 116 | { | 117 | { |
| 117 | unsigned long paddr; | 118 | unsigned long paddr; |
| 118 | 119 | ||
| 119 | pagefault_disable(); | 120 | pagefault_disable(); |
| 120 | paddr = page_to_phys(page); | 121 | paddr = page_to_phys(page); |
| 121 | 122 | ||
| 122 | switch (type) { | 123 | return __kmap_atomic_primary(1, paddr, 2); |
| 123 | case 0: return __kmap_atomic_primary(0, paddr, 2); | ||
| 124 | case 1: return __kmap_atomic_primary(1, paddr, 3); | ||
| 125 | case 2: return __kmap_atomic_primary(2, paddr, 4); | ||
| 126 | case 3: return __kmap_atomic_primary(3, paddr, 5); | ||
| 127 | |||
| 128 | default: | ||
| 129 | BUG(); | ||
| 130 | return NULL; | ||
| 131 | } | ||
| 132 | } | 124 | } |
| 133 | 125 | ||
| 134 | #define __kunmap_atomic_primary(type, ampr) \ | 126 | #define __kunmap_atomic_primary(cached, ampr) \ |
| 135 | do { \ | 127 | do { \ |
| 136 | asm volatile("movgs gr0,dampr"#ampr"\n" ::: "memory"); \ | 128 | asm volatile("movgs gr0,dampr"#ampr"\n" ::: "memory"); \ |
| 137 | if (type == __KM_CACHE) \ | 129 | if (cached) \ |
| 138 | asm volatile("movgs gr0,iampr"#ampr"\n" ::: "memory"); \ | 130 | asm volatile("movgs gr0,iampr"#ampr"\n" ::: "memory"); \ |
| 139 | } while(0) | 131 | } while(0) |
| 140 | 132 | ||
| @@ -143,17 +135,9 @@ do { \ | |||
| 143 | asm volatile("tlbpr %0,gr0,#4,#1" : : "r"(vaddr) : "memory"); \ | 135 | asm volatile("tlbpr %0,gr0,#4,#1" : : "r"(vaddr) : "memory"); \ |
| 144 | } while(0) | 136 | } while(0) |
| 145 | 137 | ||
| 146 | static inline void kunmap_atomic_primary(void *kvaddr, enum km_type type) | 138 | static inline void kunmap_atomic_primary(void *kvaddr) |
| 147 | { | 139 | { |
| 148 | switch (type) { | 140 | __kunmap_atomic_primary(1, 2); |
| 149 | case 0: __kunmap_atomic_primary(0, 2); break; | ||
| 150 | case 1: __kunmap_atomic_primary(1, 3); break; | ||
| 151 | case 2: __kunmap_atomic_primary(2, 4); break; | ||
| 152 | case 3: __kunmap_atomic_primary(3, 5); break; | ||
| 153 | |||
| 154 | default: | ||
| 155 | BUG(); | ||
| 156 | } | ||
| 157 | pagefault_enable(); | 141 | pagefault_enable(); |
| 158 | } | 142 | } |
| 159 | 143 | ||
diff --git a/arch/frv/include/asm/kmap_types.h b/arch/frv/include/asm/kmap_types.h index f8e16b2a5804..43901f220963 100644 --- a/arch/frv/include/asm/kmap_types.h +++ b/arch/frv/include/asm/kmap_types.h | |||
| @@ -2,28 +2,6 @@ | |||
| 2 | #ifndef _ASM_KMAP_TYPES_H | 2 | #ifndef _ASM_KMAP_TYPES_H |
| 3 | #define _ASM_KMAP_TYPES_H | 3 | #define _ASM_KMAP_TYPES_H |
| 4 | 4 | ||
| 5 | enum km_type { | 5 | #define KM_TYPE_NR 17 |
| 6 | /* arch specific kmaps - change the numbers attached to these at your peril */ | ||
| 7 | __KM_CACHE, /* cache flush page attachment point */ | ||
| 8 | __KM_PGD, /* current page directory */ | ||
| 9 | __KM_ITLB_PTD, /* current instruction TLB miss page table lookup */ | ||
| 10 | __KM_DTLB_PTD, /* current data TLB miss page table lookup */ | ||
| 11 | |||
| 12 | /* general kmaps */ | ||
| 13 | KM_BOUNCE_READ, | ||
| 14 | KM_SKB_SUNRPC_DATA, | ||
| 15 | KM_SKB_DATA_SOFTIRQ, | ||
| 16 | KM_USER0, | ||
| 17 | KM_USER1, | ||
| 18 | KM_BIO_SRC_IRQ, | ||
| 19 | KM_BIO_DST_IRQ, | ||
| 20 | KM_PTE0, | ||
| 21 | KM_PTE1, | ||
| 22 | KM_IRQ0, | ||
| 23 | KM_IRQ1, | ||
| 24 | KM_SOFTIRQ0, | ||
| 25 | KM_SOFTIRQ1, | ||
| 26 | KM_TYPE_NR | ||
| 27 | }; | ||
| 28 | 6 | ||
| 29 | #endif | 7 | #endif |
diff --git a/arch/frv/include/asm/unistd.h b/arch/frv/include/asm/unistd.h index a569dff7cd59..67f23a311db6 100644 --- a/arch/frv/include/asm/unistd.h +++ b/arch/frv/include/asm/unistd.h | |||
| @@ -349,7 +349,6 @@ | |||
| 349 | 349 | ||
| 350 | #define NR_syscalls 338 | 350 | #define NR_syscalls 338 |
| 351 | 351 | ||
| 352 | #define __ARCH_WANT_IPC_PARSE_VERSION | ||
| 353 | /* #define __ARCH_WANT_OLD_READDIR */ | 352 | /* #define __ARCH_WANT_OLD_READDIR */ |
| 354 | #define __ARCH_WANT_OLD_STAT | 353 | #define __ARCH_WANT_OLD_STAT |
| 355 | #define __ARCH_WANT_STAT64 | 354 | #define __ARCH_WANT_STAT64 |
diff --git a/arch/frv/kernel/kernel_thread.S b/arch/frv/kernel/kernel_thread.S index 4531c830d20b..f0e52943f923 100644 --- a/arch/frv/kernel/kernel_thread.S +++ b/arch/frv/kernel/kernel_thread.S | |||
| @@ -10,10 +10,10 @@ | |||
| 10 | */ | 10 | */ |
| 11 | 11 | ||
| 12 | #include <linux/linkage.h> | 12 | #include <linux/linkage.h> |
| 13 | #include <linux/kern_levels.h> | ||
| 13 | #include <asm/unistd.h> | 14 | #include <asm/unistd.h> |
| 14 | 15 | ||
| 15 | #define CLONE_VM 0x00000100 /* set if VM shared between processes */ | 16 | #define CLONE_VM 0x00000100 /* set if VM shared between processes */ |
| 16 | #define KERN_ERR "<3>" | ||
| 17 | 17 | ||
| 18 | .section .rodata | 18 | .section .rodata |
| 19 | kernel_thread_emsg: | 19 | kernel_thread_emsg: |
diff --git a/arch/frv/mb93090-mb00/pci-dma.c b/arch/frv/mb93090-mb00/pci-dma.c index 4f8d8bcdc7de..82478979ac9a 100644 --- a/arch/frv/mb93090-mb00/pci-dma.c +++ b/arch/frv/mb93090-mb00/pci-dma.c | |||
| @@ -62,14 +62,14 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, | |||
| 62 | dampr2 = __get_DAMPR(2); | 62 | dampr2 = __get_DAMPR(2); |
| 63 | 63 | ||
| 64 | for (i = 0; i < nents; i++) { | 64 | for (i = 0; i < nents; i++) { |
| 65 | vaddr = kmap_atomic_primary(sg_page(&sg[i]), __KM_CACHE); | 65 | vaddr = kmap_atomic_primary(sg_page(&sg[i])); |
| 66 | 66 | ||
| 67 | frv_dcache_writeback((unsigned long) vaddr, | 67 | frv_dcache_writeback((unsigned long) vaddr, |
| 68 | (unsigned long) vaddr + PAGE_SIZE); | 68 | (unsigned long) vaddr + PAGE_SIZE); |
| 69 | 69 | ||
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | kunmap_atomic_primary(vaddr, __KM_CACHE); | 72 | kunmap_atomic_primary(vaddr); |
| 73 | if (dampr2) { | 73 | if (dampr2) { |
| 74 | __set_DAMPR(2, dampr2); | 74 | __set_DAMPR(2, dampr2); |
| 75 | __set_IAMPR(2, dampr2); | 75 | __set_IAMPR(2, dampr2); |
diff --git a/arch/frv/mm/cache-page.c b/arch/frv/mm/cache-page.c index b24ade27a0f0..8e09dae0ec3f 100644 --- a/arch/frv/mm/cache-page.c +++ b/arch/frv/mm/cache-page.c | |||
| @@ -26,11 +26,11 @@ void flush_dcache_page(struct page *page) | |||
| 26 | 26 | ||
| 27 | dampr2 = __get_DAMPR(2); | 27 | dampr2 = __get_DAMPR(2); |
| 28 | 28 | ||
| 29 | vaddr = kmap_atomic_primary(page, __KM_CACHE); | 29 | vaddr = kmap_atomic_primary(page); |
| 30 | 30 | ||
| 31 | frv_dcache_writeback((unsigned long) vaddr, (unsigned long) vaddr + PAGE_SIZE); | 31 | frv_dcache_writeback((unsigned long) vaddr, (unsigned long) vaddr + PAGE_SIZE); |
| 32 | 32 | ||
| 33 | kunmap_atomic_primary(vaddr, __KM_CACHE); | 33 | kunmap_atomic_primary(vaddr); |
| 34 | 34 | ||
| 35 | if (dampr2) { | 35 | if (dampr2) { |
| 36 | __set_DAMPR(2, dampr2); | 36 | __set_DAMPR(2, dampr2); |
| @@ -54,12 +54,12 @@ void flush_icache_user_range(struct vm_area_struct *vma, struct page *page, | |||
| 54 | 54 | ||
| 55 | dampr2 = __get_DAMPR(2); | 55 | dampr2 = __get_DAMPR(2); |
| 56 | 56 | ||
| 57 | vaddr = kmap_atomic_primary(page, __KM_CACHE); | 57 | vaddr = kmap_atomic_primary(page); |
| 58 | 58 | ||
| 59 | start = (start & ~PAGE_MASK) | (unsigned long) vaddr; | 59 | start = (start & ~PAGE_MASK) | (unsigned long) vaddr; |
| 60 | frv_cache_wback_inv(start, start + len); | 60 | frv_cache_wback_inv(start, start + len); |
| 61 | 61 | ||
| 62 | kunmap_atomic_primary(vaddr, __KM_CACHE); | 62 | kunmap_atomic_primary(vaddr); |
| 63 | 63 | ||
| 64 | if (dampr2) { | 64 | if (dampr2) { |
| 65 | __set_DAMPR(2, dampr2); | 65 | __set_DAMPR(2, dampr2); |
diff --git a/arch/frv/mm/highmem.c b/arch/frv/mm/highmem.c index 31902c9d5be5..bed9a9bd3c10 100644 --- a/arch/frv/mm/highmem.c +++ b/arch/frv/mm/highmem.c | |||
| @@ -50,11 +50,11 @@ void *kmap_atomic(struct page *page) | |||
| 50 | /* | 50 | /* |
| 51 | * The first 4 primary maps are reserved for architecture code | 51 | * The first 4 primary maps are reserved for architecture code |
| 52 | */ | 52 | */ |
| 53 | case 0: return __kmap_atomic_primary(4, paddr, 6); | 53 | case 0: return __kmap_atomic_primary(0, paddr, 6); |
| 54 | case 1: return __kmap_atomic_primary(5, paddr, 7); | 54 | case 1: return __kmap_atomic_primary(0, paddr, 7); |
| 55 | case 2: return __kmap_atomic_primary(6, paddr, 8); | 55 | case 2: return __kmap_atomic_primary(0, paddr, 8); |
| 56 | case 3: return __kmap_atomic_primary(7, paddr, 9); | 56 | case 3: return __kmap_atomic_primary(0, paddr, 9); |
| 57 | case 4: return __kmap_atomic_primary(8, paddr, 10); | 57 | case 4: return __kmap_atomic_primary(0, paddr, 10); |
| 58 | 58 | ||
| 59 | case 5 ... 5 + NR_TLB_LINES - 1: | 59 | case 5 ... 5 + NR_TLB_LINES - 1: |
| 60 | return __kmap_atomic_secondary(type - 5, paddr); | 60 | return __kmap_atomic_secondary(type - 5, paddr); |
| @@ -70,11 +70,11 @@ void __kunmap_atomic(void *kvaddr) | |||
| 70 | { | 70 | { |
| 71 | int type = kmap_atomic_idx(); | 71 | int type = kmap_atomic_idx(); |
| 72 | switch (type) { | 72 | switch (type) { |
| 73 | case 0: __kunmap_atomic_primary(4, 6); break; | 73 | case 0: __kunmap_atomic_primary(0, 6); break; |
| 74 | case 1: __kunmap_atomic_primary(5, 7); break; | 74 | case 1: __kunmap_atomic_primary(0, 7); break; |
| 75 | case 2: __kunmap_atomic_primary(6, 8); break; | 75 | case 2: __kunmap_atomic_primary(0, 8); break; |
| 76 | case 3: __kunmap_atomic_primary(7, 9); break; | 76 | case 3: __kunmap_atomic_primary(0, 9); break; |
| 77 | case 4: __kunmap_atomic_primary(8, 10); break; | 77 | case 4: __kunmap_atomic_primary(0, 10); break; |
| 78 | 78 | ||
| 79 | case 5 ... 5 + NR_TLB_LINES - 1: | 79 | case 5 ... 5 + NR_TLB_LINES - 1: |
| 80 | __kunmap_atomic_secondary(type - 5, kvaddr); | 80 | __kunmap_atomic_secondary(type - 5, kvaddr); |
diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig index 56e890df5053..5e8a0d9a09ce 100644 --- a/arch/h8300/Kconfig +++ b/arch/h8300/Kconfig | |||
| @@ -3,6 +3,7 @@ config H8300 | |||
| 3 | default y | 3 | default y |
| 4 | select HAVE_IDE | 4 | select HAVE_IDE |
| 5 | select HAVE_GENERIC_HARDIRQS | 5 | select HAVE_GENERIC_HARDIRQS |
| 6 | select ARCH_WANT_IPC_PARSE_VERSION | ||
| 6 | select GENERIC_IRQ_SHOW | 7 | select GENERIC_IRQ_SHOW |
| 7 | select GENERIC_CPU_DEVICES | 8 | select GENERIC_CPU_DEVICES |
| 8 | 9 | ||
diff --git a/arch/h8300/include/asm/unistd.h b/arch/h8300/include/asm/unistd.h index 718511303b4e..5cd882801d79 100644 --- a/arch/h8300/include/asm/unistd.h +++ b/arch/h8300/include/asm/unistd.h | |||
| @@ -331,7 +331,6 @@ | |||
| 331 | 331 | ||
| 332 | #define NR_syscalls 321 | 332 | #define NR_syscalls 321 |
| 333 | 333 | ||
| 334 | #define __ARCH_WANT_IPC_PARSE_VERSION | ||
| 335 | #define __ARCH_WANT_OLD_READDIR | 334 | #define __ARCH_WANT_OLD_READDIR |
| 336 | #define __ARCH_WANT_OLD_STAT | 335 | #define __ARCH_WANT_OLD_STAT |
| 337 | #define __ARCH_WANT_STAT64 | 336 | #define __ARCH_WANT_STAT64 |
diff --git a/arch/hexagon/include/asm/Kbuild b/arch/hexagon/include/asm/Kbuild index 9aa17f1917ea..06906427c0ac 100644 --- a/arch/hexagon/include/asm/Kbuild +++ b/arch/hexagon/include/asm/Kbuild | |||
| @@ -7,7 +7,6 @@ header-y += user.h | |||
| 7 | generic-y += auxvec.h | 7 | generic-y += auxvec.h |
| 8 | generic-y += bug.h | 8 | generic-y += bug.h |
| 9 | generic-y += bugs.h | 9 | generic-y += bugs.h |
| 10 | generic-y += cpumask.h | ||
| 11 | generic-y += cputime.h | 10 | generic-y += cputime.h |
| 12 | generic-y += current.h | 11 | generic-y += current.h |
| 13 | generic-y += device.h | 12 | generic-y += device.h |
| @@ -23,7 +22,6 @@ generic-y += ioctl.h | |||
| 23 | generic-y += ioctls.h | 22 | generic-y += ioctls.h |
| 24 | generic-y += iomap.h | 23 | generic-y += iomap.h |
| 25 | generic-y += ipcbuf.h | 24 | generic-y += ipcbuf.h |
| 26 | generic-y += ipc.h | ||
| 27 | generic-y += irq_regs.h | 25 | generic-y += irq_regs.h |
| 28 | generic-y += kdebug.h | 26 | generic-y += kdebug.h |
| 29 | generic-y += kmap_types.h | 27 | generic-y += kmap_types.h |
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 8186ec5ea151..310cf5781fad 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig | |||
| @@ -126,6 +126,7 @@ config AUDIT_ARCH | |||
| 126 | 126 | ||
| 127 | menuconfig PARAVIRT_GUEST | 127 | menuconfig PARAVIRT_GUEST |
| 128 | bool "Paravirtualized guest support" | 128 | bool "Paravirtualized guest support" |
| 129 | depends on BROKEN | ||
| 129 | help | 130 | help |
| 130 | Say Y here to get to see options related to running Linux under | 131 | Say Y here to get to see options related to running Linux under |
| 131 | various hypervisors. This option alone does not add any kernel code. | 132 | various hypervisors. This option alone does not add any kernel code. |
| @@ -138,8 +139,6 @@ config PARAVIRT | |||
| 138 | bool "Enable paravirtualization code" | 139 | bool "Enable paravirtualization code" |
| 139 | depends on PARAVIRT_GUEST | 140 | depends on PARAVIRT_GUEST |
| 140 | default y | 141 | default y |
| 141 | bool | ||
| 142 | default y | ||
| 143 | help | 142 | help |
| 144 | This changes the kernel so it can modify itself when it is run | 143 | This changes the kernel so it can modify itself when it is run |
| 145 | under a hypervisor, potentially improving performance significantly | 144 | under a hypervisor, potentially improving performance significantly |
diff --git a/arch/ia64/include/asm/atomic.h b/arch/ia64/include/asm/atomic.h index 7d9116600a36..6e6fe1839f5d 100644 --- a/arch/ia64/include/asm/atomic.h +++ b/arch/ia64/include/asm/atomic.h | |||
| @@ -17,8 +17,8 @@ | |||
| 17 | #include <asm/intrinsics.h> | 17 | #include <asm/intrinsics.h> |
| 18 | 18 | ||
| 19 | 19 | ||
| 20 | #define ATOMIC_INIT(i) ((atomic_t) { (i) }) | 20 | #define ATOMIC_INIT(i) { (i) } |
| 21 | #define ATOMIC64_INIT(i) ((atomic64_t) { (i) }) | 21 | #define ATOMIC64_INIT(i) { (i) } |
| 22 | 22 | ||
| 23 | #define atomic_read(v) (*(volatile int *)&(v)->counter) | 23 | #define atomic_read(v) (*(volatile int *)&(v)->counter) |
| 24 | #define atomic64_read(v) (*(volatile long *)&(v)->counter) | 24 | #define atomic64_read(v) (*(volatile long *)&(v)->counter) |
diff --git a/arch/ia64/include/asm/machvec.h b/arch/ia64/include/asm/machvec.h index 367d299d9938..2d1ad4b11a85 100644 --- a/arch/ia64/include/asm/machvec.h +++ b/arch/ia64/include/asm/machvec.h | |||
| @@ -120,7 +120,7 @@ extern void machvec_tlb_migrate_finish (struct mm_struct *); | |||
| 120 | # ifdef MACHVEC_PLATFORM_HEADER | 120 | # ifdef MACHVEC_PLATFORM_HEADER |
| 121 | # include MACHVEC_PLATFORM_HEADER | 121 | # include MACHVEC_PLATFORM_HEADER |
| 122 | # else | 122 | # else |
| 123 | # define platform_name ia64_mv.name | 123 | # define ia64_platform_name ia64_mv.name |
| 124 | # define platform_setup ia64_mv.setup | 124 | # define platform_setup ia64_mv.setup |
| 125 | # define platform_cpu_init ia64_mv.cpu_init | 125 | # define platform_cpu_init ia64_mv.cpu_init |
| 126 | # define platform_irq_init ia64_mv.irq_init | 126 | # define platform_irq_init ia64_mv.irq_init |
diff --git a/arch/ia64/include/asm/machvec_dig.h b/arch/ia64/include/asm/machvec_dig.h index 8a0752f40987..1f7403a2fbee 100644 --- a/arch/ia64/include/asm/machvec_dig.h +++ b/arch/ia64/include/asm/machvec_dig.h | |||
| @@ -10,7 +10,7 @@ extern ia64_mv_setup_t dig_setup; | |||
| 10 | * platform's machvec structure. When compiling a non-generic kernel, | 10 | * platform's machvec structure. When compiling a non-generic kernel, |
| 11 | * the macros are used directly. | 11 | * the macros are used directly. |
| 12 | */ | 12 | */ |
| 13 | #define platform_name "dig" | 13 | #define ia64_platform_name "dig" |
| 14 | #define platform_setup dig_setup | 14 | #define platform_setup dig_setup |
| 15 | 15 | ||
| 16 | #endif /* _ASM_IA64_MACHVEC_DIG_h */ | 16 | #endif /* _ASM_IA64_MACHVEC_DIG_h */ |
diff --git a/arch/ia64/include/asm/machvec_dig_vtd.h b/arch/ia64/include/asm/machvec_dig_vtd.h index 6ab1de5c45ef..44308b4c3f6e 100644 --- a/arch/ia64/include/asm/machvec_dig_vtd.h +++ b/arch/ia64/include/asm/machvec_dig_vtd.h | |||
| @@ -11,7 +11,7 @@ extern ia64_mv_dma_init pci_iommu_alloc; | |||
| 11 | * platform's machvec structure. When compiling a non-generic kernel, | 11 | * platform's machvec structure. When compiling a non-generic kernel, |
| 12 | * the macros are used directly. | 12 | * the macros are used directly. |
| 13 | */ | 13 | */ |
| 14 | #define platform_name "dig_vtd" | 14 | #define ia64_platform_name "dig_vtd" |
| 15 | #define platform_setup dig_setup | 15 | #define platform_setup dig_setup |
| 16 | #define platform_dma_init pci_iommu_alloc | 16 | #define platform_dma_init pci_iommu_alloc |
| 17 | 17 | ||
diff --git a/arch/ia64/include/asm/machvec_hpsim.h b/arch/ia64/include/asm/machvec_hpsim.h index cf72fc87fdfe..e75711279366 100644 --- a/arch/ia64/include/asm/machvec_hpsim.h +++ b/arch/ia64/include/asm/machvec_hpsim.h | |||
| @@ -11,7 +11,7 @@ extern ia64_mv_irq_init_t hpsim_irq_init; | |||
| 11 | * platform's machvec structure. When compiling a non-generic kernel, | 11 | * platform's machvec structure. When compiling a non-generic kernel, |
| 12 | * the macros are used directly. | 12 | * the macros are used directly. |
| 13 | */ | 13 | */ |
| 14 | #define platform_name "hpsim" | 14 | #define ia64_platform_name "hpsim" |
| 15 | #define platform_setup hpsim_setup | 15 | #define platform_setup hpsim_setup |
| 16 | #define platform_irq_init hpsim_irq_init | 16 | #define platform_irq_init hpsim_irq_init |
| 17 | 17 | ||
diff --git a/arch/ia64/include/asm/machvec_hpzx1.h b/arch/ia64/include/asm/machvec_hpzx1.h index 3bd83d78a412..c74d3159e9eb 100644 --- a/arch/ia64/include/asm/machvec_hpzx1.h +++ b/arch/ia64/include/asm/machvec_hpzx1.h | |||
| @@ -11,7 +11,7 @@ extern ia64_mv_dma_init sba_dma_init; | |||
| 11 | * platform's machvec structure. When compiling a non-generic kernel, | 11 | * platform's machvec structure. When compiling a non-generic kernel, |
| 12 | * the macros are used directly. | 12 | * the macros are used directly. |
| 13 | */ | 13 | */ |
| 14 | #define platform_name "hpzx1" | 14 | #define ia64_platform_name "hpzx1" |
| 15 | #define platform_setup dig_setup | 15 | #define platform_setup dig_setup |
| 16 | #define platform_dma_init sba_dma_init | 16 | #define platform_dma_init sba_dma_init |
| 17 | 17 | ||
diff --git a/arch/ia64/include/asm/machvec_hpzx1_swiotlb.h b/arch/ia64/include/asm/machvec_hpzx1_swiotlb.h index 1091ac39740c..906ef6210774 100644 --- a/arch/ia64/include/asm/machvec_hpzx1_swiotlb.h +++ b/arch/ia64/include/asm/machvec_hpzx1_swiotlb.h | |||
| @@ -11,7 +11,7 @@ extern ia64_mv_dma_get_ops hwsw_dma_get_ops; | |||
| 11 | * platform's machvec structure. When compiling a non-generic kernel, | 11 | * platform's machvec structure. When compiling a non-generic kernel, |
| 12 | * the macros are used directly. | 12 | * the macros are used directly. |
| 13 | */ | 13 | */ |
| 14 | #define platform_name "hpzx1_swiotlb" | 14 | #define ia64_platform_name "hpzx1_swiotlb" |
| 15 | #define platform_setup dig_setup | 15 | #define platform_setup dig_setup |
| 16 | #define platform_dma_init machvec_noop | 16 | #define platform_dma_init machvec_noop |
| 17 | #define platform_dma_get_ops hwsw_dma_get_ops | 17 | #define platform_dma_get_ops hwsw_dma_get_ops |
diff --git a/arch/ia64/include/asm/machvec_sn2.h b/arch/ia64/include/asm/machvec_sn2.h index f061a30aac42..ece9fa85be88 100644 --- a/arch/ia64/include/asm/machvec_sn2.h +++ b/arch/ia64/include/asm/machvec_sn2.h | |||
| @@ -71,7 +71,7 @@ extern ia64_mv_pci_fixup_bus_t sn_pci_fixup_bus; | |||
| 71 | * platform's machvec structure. When compiling a non-generic kernel, | 71 | * platform's machvec structure. When compiling a non-generic kernel, |
| 72 | * the macros are used directly. | 72 | * the macros are used directly. |
| 73 | */ | 73 | */ |
| 74 | #define platform_name "sn2" | 74 | #define ia64_platform_name "sn2" |
| 75 | #define platform_setup sn_setup | 75 | #define platform_setup sn_setup |
| 76 | #define platform_cpu_init sn_cpu_init | 76 | #define platform_cpu_init sn_cpu_init |
| 77 | #define platform_irq_init sn_irq_init | 77 | #define platform_irq_init sn_irq_init |
diff --git a/arch/ia64/include/asm/machvec_uv.h b/arch/ia64/include/asm/machvec_uv.h index 2931447f3813..2c50853f35ac 100644 --- a/arch/ia64/include/asm/machvec_uv.h +++ b/arch/ia64/include/asm/machvec_uv.h | |||
| @@ -20,7 +20,7 @@ extern ia64_mv_setup_t uv_setup; | |||
| 20 | * platform's machvec structure. When compiling a non-generic kernel, | 20 | * platform's machvec structure. When compiling a non-generic kernel, |
| 21 | * the macros are used directly. | 21 | * the macros are used directly. |
| 22 | */ | 22 | */ |
| 23 | #define platform_name "uv" | 23 | #define ia64_platform_name "uv" |
| 24 | #define platform_setup uv_setup | 24 | #define platform_setup uv_setup |
| 25 | 25 | ||
| 26 | #endif /* _ASM_IA64_MACHVEC_UV_H */ | 26 | #endif /* _ASM_IA64_MACHVEC_UV_H */ |
diff --git a/arch/ia64/include/asm/machvec_xen.h b/arch/ia64/include/asm/machvec_xen.h index 55f9228056cd..8b8bd0eb3923 100644 --- a/arch/ia64/include/asm/machvec_xen.h +++ b/arch/ia64/include/asm/machvec_xen.h | |||
| @@ -13,7 +13,7 @@ extern ia64_mv_send_ipi_t xen_platform_send_ipi; | |||
| 13 | * platform's machvec structure. When compiling a non-generic kernel, | 13 | * platform's machvec structure. When compiling a non-generic kernel, |
| 14 | * the macros are used directly. | 14 | * the macros are used directly. |
| 15 | */ | 15 | */ |
| 16 | #define platform_name "xen" | 16 | #define ia64_platform_name "xen" |
| 17 | #define platform_setup dig_setup | 17 | #define platform_setup dig_setup |
| 18 | #define platform_cpu_init xen_cpu_init | 18 | #define platform_cpu_init xen_cpu_init |
| 19 | #define platform_irq_init xen_irq_init | 19 | #define platform_irq_init xen_irq_init |
diff --git a/arch/ia64/include/asm/processor.h b/arch/ia64/include/asm/processor.h index 832dd3789e9d..944152a50912 100644 --- a/arch/ia64/include/asm/processor.h +++ b/arch/ia64/include/asm/processor.h | |||
| @@ -719,7 +719,7 @@ enum idle_boot_override {IDLE_NO_OVERRIDE=0, IDLE_HALT, IDLE_FORCE_MWAIT, | |||
| 719 | 719 | ||
| 720 | void default_idle(void); | 720 | void default_idle(void); |
| 721 | 721 | ||
| 722 | #define ia64_platform_is(x) (strcmp(x, platform_name) == 0) | 722 | #define ia64_platform_is(x) (strcmp(x, ia64_platform_name) == 0) |
| 723 | 723 | ||
| 724 | #endif /* !__ASSEMBLY__ */ | 724 | #endif /* !__ASSEMBLY__ */ |
| 725 | 725 | ||
diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c index 5c3e0888265a..1034884b77da 100644 --- a/arch/ia64/kernel/irq_ia64.c +++ b/arch/ia64/kernel/irq_ia64.c | |||
| @@ -23,7 +23,6 @@ | |||
| 23 | #include <linux/ioport.h> | 23 | #include <linux/ioport.h> |
| 24 | #include <linux/kernel_stat.h> | 24 | #include <linux/kernel_stat.h> |
| 25 | #include <linux/ptrace.h> | 25 | #include <linux/ptrace.h> |
| 26 | #include <linux/random.h> /* for rand_initialize_irq() */ | ||
| 27 | #include <linux/signal.h> | 26 | #include <linux/signal.h> |
| 28 | #include <linux/smp.h> | 27 | #include <linux/smp.h> |
| 29 | #include <linux/threads.h> | 28 | #include <linux/threads.h> |
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index d7f558c1e711..3fa4bc536953 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c | |||
| @@ -2353,7 +2353,6 @@ pfm_smpl_buffer_alloc(struct task_struct *task, struct file *filp, pfm_context_t | |||
| 2353 | */ | 2353 | */ |
| 2354 | insert_vm_struct(mm, vma); | 2354 | insert_vm_struct(mm, vma); |
| 2355 | 2355 | ||
| 2356 | mm->total_vm += size >> PAGE_SHIFT; | ||
| 2357 | vm_stat_account(vma->vm_mm, vma->vm_flags, vma->vm_file, | 2356 | vm_stat_account(vma->vm_mm, vma->vm_flags, vma->vm_file, |
| 2358 | vma_pages(vma)); | 2357 | vma_pages(vma)); |
| 2359 | up_write(&task->mm->mmap_sem); | 2358 | up_write(&task->mm->mmap_sem); |
diff --git a/arch/ia64/kvm/Kconfig b/arch/ia64/kvm/Kconfig index df5351e3eed7..e7947528aee6 100644 --- a/arch/ia64/kvm/Kconfig +++ b/arch/ia64/kvm/Kconfig | |||
| @@ -23,6 +23,7 @@ config KVM | |||
| 23 | depends on HAVE_KVM && MODULES && EXPERIMENTAL | 23 | depends on HAVE_KVM && MODULES && EXPERIMENTAL |
| 24 | # for device assignment: | 24 | # for device assignment: |
| 25 | depends on PCI | 25 | depends on PCI |
| 26 | depends on BROKEN | ||
| 26 | select PREEMPT_NOTIFIERS | 27 | select PREEMPT_NOTIFIERS |
| 27 | select ANON_INODES | 28 | select ANON_INODES |
| 28 | select HAVE_KVM_IRQCHIP | 29 | select HAVE_KVM_IRQCHIP |
diff --git a/arch/ia64/pci/fixup.c b/arch/ia64/pci/fixup.c index f5959c0c1810..eab28e314022 100644 --- a/arch/ia64/pci/fixup.c +++ b/arch/ia64/pci/fixup.c | |||
| @@ -30,8 +30,8 @@ static void __devinit pci_fixup_video(struct pci_dev *pdev) | |||
| 30 | struct pci_bus *bus; | 30 | struct pci_bus *bus; |
| 31 | u16 config; | 31 | u16 config; |
| 32 | 32 | ||
| 33 | if ((strcmp(platform_name, "dig") != 0) | 33 | if ((strcmp(ia64_platform_name, "dig") != 0) |
| 34 | && (strcmp(platform_name, "hpzx1") != 0)) | 34 | && (strcmp(ia64_platform_name, "hpzx1") != 0)) |
| 35 | return; | 35 | return; |
| 36 | /* Maybe, this machine supports legacy memory map. */ | 36 | /* Maybe, this machine supports legacy memory map. */ |
| 37 | 37 | ||
diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig index b638d5bfa14d..49498bbb9616 100644 --- a/arch/m32r/Kconfig +++ b/arch/m32r/Kconfig | |||
| @@ -7,6 +7,7 @@ config M32R | |||
| 7 | select HAVE_KERNEL_GZIP | 7 | select HAVE_KERNEL_GZIP |
| 8 | select HAVE_KERNEL_BZIP2 | 8 | select HAVE_KERNEL_BZIP2 |
| 9 | select HAVE_KERNEL_LZMA | 9 | select HAVE_KERNEL_LZMA |
| 10 | select ARCH_WANT_IPC_PARSE_VERSION | ||
| 10 | select HAVE_GENERIC_HARDIRQS | 11 | select HAVE_GENERIC_HARDIRQS |
| 11 | select GENERIC_IRQ_PROBE | 12 | select GENERIC_IRQ_PROBE |
| 12 | select GENERIC_IRQ_SHOW | 13 | select GENERIC_IRQ_SHOW |
diff --git a/arch/m32r/include/asm/unistd.h b/arch/m32r/include/asm/unistd.h index 3e1db561aacc..d5e66a480782 100644 --- a/arch/m32r/include/asm/unistd.h +++ b/arch/m32r/include/asm/unistd.h | |||
| @@ -336,7 +336,6 @@ | |||
| 336 | 336 | ||
| 337 | #define NR_syscalls 326 | 337 | #define NR_syscalls 326 |
| 338 | 338 | ||
| 339 | #define __ARCH_WANT_IPC_PARSE_VERSION | ||
| 340 | #define __ARCH_WANT_STAT64 | 339 | #define __ARCH_WANT_STAT64 |
| 341 | #define __ARCH_WANT_SYS_ALARM | 340 | #define __ARCH_WANT_SYS_ALARM |
| 342 | #define __ARCH_WANT_SYS_GETHOSTNAME | 341 | #define __ARCH_WANT_SYS_GETHOSTNAME |
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index 147120128260..0b0f8b8c4a26 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig | |||
| @@ -10,6 +10,7 @@ config M68K | |||
| 10 | select GENERIC_STRNCPY_FROM_USER if MMU | 10 | select GENERIC_STRNCPY_FROM_USER if MMU |
| 11 | select GENERIC_STRNLEN_USER if MMU | 11 | select GENERIC_STRNLEN_USER if MMU |
| 12 | select FPU if MMU | 12 | select FPU if MMU |
| 13 | select ARCH_WANT_IPC_PARSE_VERSION | ||
| 13 | select ARCH_USES_GETTIMEOFFSET if MMU && !COLDFIRE | 14 | select ARCH_USES_GETTIMEOFFSET if MMU && !COLDFIRE |
| 14 | 15 | ||
| 15 | config RWSEM_GENERIC_SPINLOCK | 16 | config RWSEM_GENERIC_SPINLOCK |
diff --git a/arch/m68k/include/asm/unistd.h b/arch/m68k/include/asm/unistd.h index ea0b502f845e..045cfd6a9e31 100644 --- a/arch/m68k/include/asm/unistd.h +++ b/arch/m68k/include/asm/unistd.h | |||
| @@ -357,7 +357,6 @@ | |||
| 357 | 357 | ||
| 358 | #define NR_syscalls 347 | 358 | #define NR_syscalls 347 |
| 359 | 359 | ||
| 360 | #define __ARCH_WANT_IPC_PARSE_VERSION | ||
| 361 | #define __ARCH_WANT_OLD_READDIR | 360 | #define __ARCH_WANT_OLD_READDIR |
| 362 | #define __ARCH_WANT_OLD_STAT | 361 | #define __ARCH_WANT_OLD_STAT |
| 363 | #define __ARCH_WANT_STAT64 | 362 | #define __ARCH_WANT_STAT64 |
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index 0bf44231aaf9..ab9afcaa7f6a 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig | |||
| @@ -15,6 +15,7 @@ config MICROBLAZE | |||
| 15 | select TRACING_SUPPORT | 15 | select TRACING_SUPPORT |
| 16 | select OF | 16 | select OF |
| 17 | select OF_EARLY_FLATTREE | 17 | select OF_EARLY_FLATTREE |
| 18 | select ARCH_WANT_IPC_PARSE_VERSION | ||
| 18 | select IRQ_DOMAIN | 19 | select IRQ_DOMAIN |
| 19 | select HAVE_GENERIC_HARDIRQS | 20 | select HAVE_GENERIC_HARDIRQS |
| 20 | select GENERIC_IRQ_PROBE | 21 | select GENERIC_IRQ_PROBE |
diff --git a/arch/microblaze/include/asm/unistd.h b/arch/microblaze/include/asm/unistd.h index d20ffbc86beb..6985e6e9d826 100644 --- a/arch/microblaze/include/asm/unistd.h +++ b/arch/microblaze/include/asm/unistd.h | |||
| @@ -400,7 +400,6 @@ | |||
| 400 | #ifdef __KERNEL__ | 400 | #ifdef __KERNEL__ |
| 401 | #ifndef __ASSEMBLY__ | 401 | #ifndef __ASSEMBLY__ |
| 402 | 402 | ||
| 403 | #define __ARCH_WANT_IPC_PARSE_VERSION | ||
| 404 | /* #define __ARCH_WANT_OLD_READDIR */ | 403 | /* #define __ARCH_WANT_OLD_READDIR */ |
| 405 | /* #define __ARCH_WANT_OLD_STAT */ | 404 | /* #define __ARCH_WANT_OLD_STAT */ |
| 406 | #define __ARCH_WANT_STAT64 | 405 | #define __ARCH_WANT_STAT64 |
diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms index 5ce8029f558b..d64786d5e2f3 100644 --- a/arch/mips/Kbuild.platforms +++ b/arch/mips/Kbuild.platforms | |||
| @@ -14,6 +14,7 @@ platforms += jz4740 | |||
| 14 | platforms += lantiq | 14 | platforms += lantiq |
| 15 | platforms += lasat | 15 | platforms += lasat |
| 16 | platforms += loongson | 16 | platforms += loongson |
| 17 | platforms += loongson1 | ||
| 17 | platforms += mipssim | 18 | platforms += mipssim |
| 18 | platforms += mti-malta | 19 | platforms += mti-malta |
| 19 | platforms += netlogic | 20 | platforms += netlogic |
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index b3e10fdd3898..e3efc06e6409 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
| @@ -20,12 +20,14 @@ config MIPS | |||
| 20 | select ARCH_BINFMT_ELF_RANDOMIZE_PIE | 20 | select ARCH_BINFMT_ELF_RANDOMIZE_PIE |
| 21 | select RTC_LIB if !MACH_LOONGSON | 21 | select RTC_LIB if !MACH_LOONGSON |
| 22 | select GENERIC_ATOMIC64 if !64BIT | 22 | select GENERIC_ATOMIC64 if !64BIT |
| 23 | select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE | ||
| 23 | select HAVE_DMA_ATTRS | 24 | select HAVE_DMA_ATTRS |
| 24 | select HAVE_DMA_API_DEBUG | 25 | select HAVE_DMA_API_DEBUG |
| 25 | select HAVE_GENERIC_HARDIRQS | 26 | select HAVE_GENERIC_HARDIRQS |
| 26 | select GENERIC_IRQ_PROBE | 27 | select GENERIC_IRQ_PROBE |
| 27 | select GENERIC_IRQ_SHOW | 28 | select GENERIC_IRQ_SHOW |
| 28 | select HAVE_ARCH_JUMP_LABEL | 29 | select HAVE_ARCH_JUMP_LABEL |
| 30 | select ARCH_WANT_IPC_PARSE_VERSION | ||
| 29 | select IRQ_FORCED_THREADING | 31 | select IRQ_FORCED_THREADING |
| 30 | select HAVE_MEMBLOCK | 32 | select HAVE_MEMBLOCK |
| 31 | select HAVE_MEMBLOCK_NODE_MAP | 33 | select HAVE_MEMBLOCK_NODE_MAP |
| @@ -209,6 +211,7 @@ config MACH_JZ4740 | |||
| 209 | select SYS_HAS_CPU_MIPS32_R1 | 211 | select SYS_HAS_CPU_MIPS32_R1 |
| 210 | select SYS_SUPPORTS_32BIT_KERNEL | 212 | select SYS_SUPPORTS_32BIT_KERNEL |
| 211 | select SYS_SUPPORTS_LITTLE_ENDIAN | 213 | select SYS_SUPPORTS_LITTLE_ENDIAN |
| 214 | select SYS_SUPPORTS_ZBOOT_UART16550 | ||
| 212 | select DMA_NONCOHERENT | 215 | select DMA_NONCOHERENT |
| 213 | select IRQ_CPU | 216 | select IRQ_CPU |
| 214 | select GENERIC_GPIO | 217 | select GENERIC_GPIO |
| @@ -264,6 +267,16 @@ config MACH_LOONGSON | |||
| 264 | Chinese Academy of Sciences (CAS) in the People's Republic | 267 | Chinese Academy of Sciences (CAS) in the People's Republic |
| 265 | of China. The chief architect is Professor Weiwu Hu. | 268 | of China. The chief architect is Professor Weiwu Hu. |
| 266 | 269 | ||
| 270 | config MACH_LOONGSON1 | ||
| 271 | bool "Loongson 1 family of machines" | ||
| 272 | select SYS_SUPPORTS_ZBOOT | ||
| 273 | help | ||
| 274 | This enables support for the Loongson 1 based machines. | ||
| 275 | |||
| 276 | Loongson 1 is a family of 32-bit MIPS-compatible SoCs developed by | ||
| 277 | the ICT (Institute of Computing Technology) and the Chinese Academy | ||
| 278 | of Sciences. | ||
| 279 | |||
| 267 | config MIPS_MALTA | 280 | config MIPS_MALTA |
| 268 | bool "MIPS Malta board" | 281 | bool "MIPS Malta board" |
| 269 | select ARCH_MAY_HAVE_PC_FDC | 282 | select ARCH_MAY_HAVE_PC_FDC |
| @@ -787,6 +800,8 @@ config NLM_XLR_BOARD | |||
| 787 | select ZONE_DMA if 64BIT | 800 | select ZONE_DMA if 64BIT |
| 788 | select SYNC_R4K | 801 | select SYNC_R4K |
| 789 | select SYS_HAS_EARLY_PRINTK | 802 | select SYS_HAS_EARLY_PRINTK |
| 803 | select USB_ARCH_HAS_OHCI if USB_SUPPORT | ||
| 804 | select USB_ARCH_HAS_EHCI if USB_SUPPORT | ||
| 790 | help | 805 | help |
| 791 | Support for systems based on Netlogic XLR and XLS processors. | 806 | Support for systems based on Netlogic XLR and XLS processors. |
| 792 | Say Y here if you have a XLR or XLS based board. | 807 | Say Y here if you have a XLR or XLS based board. |
| @@ -799,7 +814,6 @@ config NLM_XLP_BOARD | |||
| 799 | select SYS_HAS_CPU_XLP | 814 | select SYS_HAS_CPU_XLP |
| 800 | select SYS_SUPPORTS_SMP | 815 | select SYS_SUPPORTS_SMP |
| 801 | select HW_HAS_PCI | 816 | select HW_HAS_PCI |
| 802 | select SWAP_IO_SPACE | ||
| 803 | select SYS_SUPPORTS_32BIT_KERNEL | 817 | select SYS_SUPPORTS_32BIT_KERNEL |
| 804 | select SYS_SUPPORTS_64BIT_KERNEL | 818 | select SYS_SUPPORTS_64BIT_KERNEL |
| 805 | select 64BIT_PHYS_ADDR | 819 | select 64BIT_PHYS_ADDR |
| @@ -836,6 +850,7 @@ source "arch/mips/txx9/Kconfig" | |||
| 836 | source "arch/mips/vr41xx/Kconfig" | 850 | source "arch/mips/vr41xx/Kconfig" |
| 837 | source "arch/mips/cavium-octeon/Kconfig" | 851 | source "arch/mips/cavium-octeon/Kconfig" |
| 838 | source "arch/mips/loongson/Kconfig" | 852 | source "arch/mips/loongson/Kconfig" |
| 853 | source "arch/mips/loongson1/Kconfig" | ||
| 839 | source "arch/mips/netlogic/Kconfig" | 854 | source "arch/mips/netlogic/Kconfig" |
| 840 | 855 | ||
| 841 | endmenu | 856 | endmenu |
| @@ -1217,6 +1232,14 @@ config CPU_LOONGSON2F | |||
| 1217 | have a similar programming interface with FPGA northbridge used in | 1232 | have a similar programming interface with FPGA northbridge used in |
| 1218 | Loongson2E. | 1233 | Loongson2E. |
| 1219 | 1234 | ||
| 1235 | config CPU_LOONGSON1B | ||
| 1236 | bool "Loongson 1B" | ||
| 1237 | depends on SYS_HAS_CPU_LOONGSON1B | ||
| 1238 | select CPU_LOONGSON1 | ||
| 1239 | help | ||
| 1240 | The Loongson 1B is a 32-bit SoC, which implements the MIPS32 | ||
| 1241 | release 2 instruction set. | ||
| 1242 | |||
| 1220 | config CPU_MIPS32_R1 | 1243 | config CPU_MIPS32_R1 |
| 1221 | bool "MIPS32 Release 1" | 1244 | bool "MIPS32 Release 1" |
| 1222 | depends on SYS_HAS_CPU_MIPS32_R1 | 1245 | depends on SYS_HAS_CPU_MIPS32_R1 |
| @@ -1432,6 +1455,8 @@ config CPU_CAVIUM_OCTEON | |||
| 1432 | select WEAK_ORDERING | 1455 | select WEAK_ORDERING |
| 1433 | select CPU_SUPPORTS_HIGHMEM | 1456 | select CPU_SUPPORTS_HIGHMEM |
| 1434 | select CPU_SUPPORTS_HUGEPAGES | 1457 | select CPU_SUPPORTS_HUGEPAGES |
| 1458 | select LIBFDT | ||
| 1459 | select USE_OF | ||
| 1435 | help | 1460 | help |
| 1436 | The Cavium Octeon processor is a highly integrated chip containing | 1461 | The Cavium Octeon processor is a highly integrated chip containing |
| 1437 | many ethernet hardware widgets for networking tasks. The processor | 1462 | many ethernet hardware widgets for networking tasks. The processor |
| @@ -1544,6 +1569,14 @@ config CPU_LOONGSON2 | |||
| 1544 | select CPU_SUPPORTS_64BIT_KERNEL | 1569 | select CPU_SUPPORTS_64BIT_KERNEL |
| 1545 | select CPU_SUPPORTS_HIGHMEM | 1570 | select CPU_SUPPORTS_HIGHMEM |
| 1546 | 1571 | ||
| 1572 | config CPU_LOONGSON1 | ||
| 1573 | bool | ||
| 1574 | select CPU_MIPS32 | ||
| 1575 | select CPU_MIPSR2 | ||
| 1576 | select CPU_HAS_PREFETCH | ||
| 1577 | select CPU_SUPPORTS_32BIT_KERNEL | ||
| 1578 | select CPU_SUPPORTS_HIGHMEM | ||
| 1579 | |||
| 1547 | config CPU_BMIPS | 1580 | config CPU_BMIPS |
| 1548 | bool | 1581 | bool |
| 1549 | select CPU_MIPS32 | 1582 | select CPU_MIPS32 |
| @@ -1562,6 +1595,9 @@ config SYS_HAS_CPU_LOONGSON2F | |||
| 1562 | select CPU_SUPPORTS_ADDRWINCFG if 64BIT | 1595 | select CPU_SUPPORTS_ADDRWINCFG if 64BIT |
| 1563 | select CPU_SUPPORTS_UNCACHED_ACCELERATED | 1596 | select CPU_SUPPORTS_UNCACHED_ACCELERATED |
| 1564 | 1597 | ||
| 1598 | config SYS_HAS_CPU_LOONGSON1B | ||
| 1599 | bool | ||
| 1600 | |||
| 1565 | config SYS_HAS_CPU_MIPS32_R1 | 1601 | config SYS_HAS_CPU_MIPS32_R1 |
| 1566 | bool | 1602 | bool |
| 1567 | 1603 | ||
| @@ -2366,6 +2402,8 @@ config PCI_DOMAINS | |||
| 2366 | 2402 | ||
| 2367 | source "drivers/pci/Kconfig" | 2403 | source "drivers/pci/Kconfig" |
| 2368 | 2404 | ||
| 2405 | source "drivers/pci/pcie/Kconfig" | ||
| 2406 | |||
| 2369 | # | 2407 | # |
| 2370 | # ISA support is now enabled via select. Too many systems still have the one | 2408 | # ISA support is now enabled via select. Too many systems still have the one |
| 2371 | # or other ISA chip on the board that users don't know about so don't expect | 2409 | # or other ISA chip on the board that users don't know about so don't expect |
diff --git a/arch/mips/alchemy/board-mtx1.c b/arch/mips/alchemy/board-mtx1.c index 295f1a95f745..99969484c475 100644 --- a/arch/mips/alchemy/board-mtx1.c +++ b/arch/mips/alchemy/board-mtx1.c | |||
| @@ -81,10 +81,10 @@ static void mtx1_power_off(void) | |||
| 81 | 81 | ||
| 82 | void __init board_setup(void) | 82 | void __init board_setup(void) |
| 83 | { | 83 | { |
| 84 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) | 84 | #if IS_ENABLED(CONFIG_USB_OHCI_HCD) |
| 85 | /* Enable USB power switch */ | 85 | /* Enable USB power switch */ |
| 86 | alchemy_gpio_direction_output(204, 0); | 86 | alchemy_gpio_direction_output(204, 0); |
| 87 | #endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */ | 87 | #endif /* IS_ENABLED(CONFIG_USB_OHCI_HCD) */ |
| 88 | 88 | ||
| 89 | /* Initialize sys_pinfunc */ | 89 | /* Initialize sys_pinfunc */ |
| 90 | au_writel(SYS_PF_NI2, SYS_PINFUNC); | 90 | au_writel(SYS_PF_NI2, SYS_PINFUNC); |
diff --git a/arch/mips/alchemy/common/platform.c b/arch/mips/alchemy/common/platform.c index 95cb9113b12c..c0f3ce6dcb56 100644 --- a/arch/mips/alchemy/common/platform.c +++ b/arch/mips/alchemy/common/platform.c | |||
| @@ -334,13 +334,12 @@ static void __init alchemy_setup_macs(int ctype) | |||
| 334 | if (alchemy_get_macs(ctype) < 1) | 334 | if (alchemy_get_macs(ctype) < 1) |
| 335 | return; | 335 | return; |
| 336 | 336 | ||
| 337 | macres = kmalloc(sizeof(struct resource) * MAC_RES_COUNT, GFP_KERNEL); | 337 | macres = kmemdup(au1xxx_eth0_resources[ctype], |
| 338 | sizeof(struct resource) * MAC_RES_COUNT, GFP_KERNEL); | ||
| 338 | if (!macres) { | 339 | if (!macres) { |
| 339 | printk(KERN_INFO "Alchemy: no memory for MAC0 resources\n"); | 340 | printk(KERN_INFO "Alchemy: no memory for MAC0 resources\n"); |
| 340 | return; | 341 | return; |
| 341 | } | 342 | } |
| 342 | memcpy(macres, au1xxx_eth0_resources[ctype], | ||
| 343 | sizeof(struct resource) * MAC_RES_COUNT); | ||
| 344 | au1xxx_eth0_device.resource = macres; | 343 | au1xxx_eth0_device.resource = macres; |
| 345 | 344 | ||
| 346 | i = prom_get_ethernet_addr(ethaddr); | 345 | i = prom_get_ethernet_addr(ethaddr); |
| @@ -356,13 +355,12 @@ static void __init alchemy_setup_macs(int ctype) | |||
| 356 | if (alchemy_get_macs(ctype) < 2) | 355 | if (alchemy_get_macs(ctype) < 2) |
| 357 | return; | 356 | return; |
| 358 | 357 | ||
| 359 | macres = kmalloc(sizeof(struct resource) * MAC_RES_COUNT, GFP_KERNEL); | 358 | macres = kmemdup(au1xxx_eth1_resources[ctype], |
| 359 | sizeof(struct resource) * MAC_RES_COUNT, GFP_KERNEL); | ||
| 360 | if (!macres) { | 360 | if (!macres) { |
| 361 | printk(KERN_INFO "Alchemy: no memory for MAC1 resources\n"); | 361 | printk(KERN_INFO "Alchemy: no memory for MAC1 resources\n"); |
| 362 | return; | 362 | return; |
| 363 | } | 363 | } |
| 364 | memcpy(macres, au1xxx_eth1_resources[ctype], | ||
| 365 | sizeof(struct resource) * MAC_RES_COUNT); | ||
| 366 | au1xxx_eth1_device.resource = macres; | 364 | au1xxx_eth1_device.resource = macres; |
| 367 | 365 | ||
| 368 | ethaddr[5] += 1; /* next addr for 2nd MAC */ | 366 | ethaddr[5] += 1; /* next addr for 2nd MAC */ |
diff --git a/arch/mips/alchemy/devboards/Makefile b/arch/mips/alchemy/devboards/Makefile index 3c37fb303364..c9e747dd9fc2 100644 --- a/arch/mips/alchemy/devboards/Makefile +++ b/arch/mips/alchemy/devboards/Makefile | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | # Alchemy Develboards | 2 | # Alchemy Develboards |
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | obj-y += prom.o bcsr.o platform.o | 5 | obj-y += bcsr.o platform.o |
| 6 | obj-$(CONFIG_PM) += pm.o | 6 | obj-$(CONFIG_PM) += pm.o |
| 7 | obj-$(CONFIG_MIPS_PB1100) += pb1100.o | 7 | obj-$(CONFIG_MIPS_PB1100) += pb1100.o |
| 8 | obj-$(CONFIG_MIPS_PB1500) += pb1500.o | 8 | obj-$(CONFIG_MIPS_PB1500) += pb1500.o |
diff --git a/arch/mips/alchemy/devboards/bcsr.c b/arch/mips/alchemy/devboards/bcsr.c index 1e83ce2e1147..f2039ef2c293 100644 --- a/arch/mips/alchemy/devboards/bcsr.c +++ b/arch/mips/alchemy/devboards/bcsr.c | |||
| @@ -90,10 +90,7 @@ static void bcsr_csc_handler(unsigned int irq, struct irq_desc *d) | |||
| 90 | unsigned short bisr = __raw_readw(bcsr_virt + BCSR_REG_INTSTAT); | 90 | unsigned short bisr = __raw_readw(bcsr_virt + BCSR_REG_INTSTAT); |
| 91 | 91 | ||
| 92 | disable_irq_nosync(irq); | 92 | disable_irq_nosync(irq); |
| 93 | 93 | generic_handle_irq(bcsr_csc_base + __ffs(bisr)); | |
| 94 | for ( ; bisr; bisr &= bisr - 1) | ||
| 95 | generic_handle_irq(bcsr_csc_base + __ffs(bisr)); | ||
| 96 | |||
| 97 | enable_irq(irq); | 94 | enable_irq(irq); |
| 98 | } | 95 | } |
| 99 | 96 | ||
diff --git a/arch/mips/alchemy/devboards/pb1100.c b/arch/mips/alchemy/devboards/pb1100.c index cff50d05ddd4..78c77a44a317 100644 --- a/arch/mips/alchemy/devboards/pb1100.c +++ b/arch/mips/alchemy/devboards/pb1100.c | |||
| @@ -46,7 +46,7 @@ void __init board_setup(void) | |||
| 46 | alchemy_gpio1_input_enable(); | 46 | alchemy_gpio1_input_enable(); |
| 47 | udelay(100); | 47 | udelay(100); |
| 48 | 48 | ||
| 49 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) | 49 | #if IS_ENABLED(CONFIG_USB_OHCI_HCD) |
| 50 | { | 50 | { |
| 51 | u32 pin_func, sys_freqctrl, sys_clksrc; | 51 | u32 pin_func, sys_freqctrl, sys_clksrc; |
| 52 | 52 | ||
| @@ -93,7 +93,7 @@ void __init board_setup(void) | |||
| 93 | pin_func |= SYS_PF_USB; | 93 | pin_func |= SYS_PF_USB; |
| 94 | au_writel(pin_func, SYS_PINFUNC); | 94 | au_writel(pin_func, SYS_PINFUNC); |
| 95 | } | 95 | } |
| 96 | #endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */ | 96 | #endif /* IS_ENABLED(CONFIG_USB_OHCI_HCD) */ |
| 97 | 97 | ||
| 98 | /* Enable sys bus clock divider when IDLE state or no bus activity. */ | 98 | /* Enable sys bus clock divider when IDLE state or no bus activity. */ |
| 99 | au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL); | 99 | au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL); |
diff --git a/arch/mips/alchemy/devboards/pb1500.c b/arch/mips/alchemy/devboards/pb1500.c index e7b807b3ec51..232fee942000 100644 --- a/arch/mips/alchemy/devboards/pb1500.c +++ b/arch/mips/alchemy/devboards/pb1500.c | |||
| @@ -53,7 +53,7 @@ void __init board_setup(void) | |||
| 53 | alchemy_gpio_direction_input(201); | 53 | alchemy_gpio_direction_input(201); |
| 54 | alchemy_gpio_direction_input(203); | 54 | alchemy_gpio_direction_input(203); |
| 55 | 55 | ||
| 56 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) | 56 | #if IS_ENABLED(CONFIG_USB_OHCI_HCD) |
| 57 | 57 | ||
| 58 | /* Zero and disable FREQ2 */ | 58 | /* Zero and disable FREQ2 */ |
| 59 | sys_freqctrl = au_readl(SYS_FREQCTRL0); | 59 | sys_freqctrl = au_readl(SYS_FREQCTRL0); |
| @@ -87,7 +87,7 @@ void __init board_setup(void) | |||
| 87 | /* 2nd USB port is USB host */ | 87 | /* 2nd USB port is USB host */ |
| 88 | pin_func |= SYS_PF_USB; | 88 | pin_func |= SYS_PF_USB; |
| 89 | au_writel(pin_func, SYS_PINFUNC); | 89 | au_writel(pin_func, SYS_PINFUNC); |
| 90 | #endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */ | 90 | #endif /* IS_ENABLED(CONFIG_USB_OHCI_HCD) */ |
| 91 | 91 | ||
| 92 | #ifdef CONFIG_PCI | 92 | #ifdef CONFIG_PCI |
| 93 | { | 93 | { |
diff --git a/arch/mips/alchemy/devboards/platform.c b/arch/mips/alchemy/devboards/platform.c index 621f70afb63a..f39042e99d0d 100644 --- a/arch/mips/alchemy/devboards/platform.c +++ b/arch/mips/alchemy/devboards/platform.c | |||
| @@ -10,9 +10,39 @@ | |||
| 10 | #include <linux/platform_device.h> | 10 | #include <linux/platform_device.h> |
| 11 | #include <linux/pm.h> | 11 | #include <linux/pm.h> |
| 12 | 12 | ||
| 13 | #include <asm/bootinfo.h> | ||
| 13 | #include <asm/reboot.h> | 14 | #include <asm/reboot.h> |
| 15 | #include <asm/mach-au1x00/au1000.h> | ||
| 14 | #include <asm/mach-db1x00/bcsr.h> | 16 | #include <asm/mach-db1x00/bcsr.h> |
| 15 | 17 | ||
| 18 | #include <prom.h> | ||
| 19 | |||
| 20 | void __init prom_init(void) | ||
| 21 | { | ||
| 22 | unsigned char *memsize_str; | ||
| 23 | unsigned long memsize; | ||
| 24 | |||
| 25 | prom_argc = (int)fw_arg0; | ||
| 26 | prom_argv = (char **)fw_arg1; | ||
| 27 | prom_envp = (char **)fw_arg2; | ||
| 28 | |||
| 29 | prom_init_cmdline(); | ||
| 30 | memsize_str = prom_getenv("memsize"); | ||
| 31 | if (!memsize_str || kstrtoul(memsize_str, 0, &memsize)) | ||
| 32 | memsize = 64 << 20; /* all devboards have at least 64MB RAM */ | ||
| 33 | |||
| 34 | add_memory_region(0, memsize, BOOT_MEM_RAM); | ||
| 35 | } | ||
| 36 | |||
| 37 | void prom_putchar(unsigned char c) | ||
| 38 | { | ||
| 39 | #ifdef CONFIG_MIPS_DB1300 | ||
| 40 | alchemy_uart_putchar(AU1300_UART2_PHYS_ADDR, c); | ||
| 41 | #else | ||
| 42 | alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c); | ||
| 43 | #endif | ||
| 44 | } | ||
| 45 | |||
| 16 | 46 | ||
| 17 | static struct platform_device db1x00_rtc_dev = { | 47 | static struct platform_device db1x00_rtc_dev = { |
| 18 | .name = "rtc-au1xxx", | 48 | .name = "rtc-au1xxx", |
diff --git a/arch/mips/alchemy/devboards/prom.c b/arch/mips/alchemy/devboards/prom.c deleted file mode 100644 index 93a22107cc41..000000000000 --- a/arch/mips/alchemy/devboards/prom.c +++ /dev/null | |||
| @@ -1,69 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Common code used by all Alchemy develboards. | ||
| 3 | * | ||
| 4 | * Extracted from files which had this to say: | ||
| 5 | * | ||
| 6 | * Copyright 2000, 2008 MontaVista Software Inc. | ||
| 7 | * Author: MontaVista Software, Inc. <source@mvista.com> | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify it | ||
| 10 | * under the terms of the GNU General Public License as published by the | ||
| 11 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 12 | * option) any later version. | ||
| 13 | * | ||
| 14 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
| 15 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
| 16 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
| 17 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 18 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
| 19 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
| 20 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
| 21 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
| 23 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 24 | * | ||
| 25 | * You should have received a copy of the GNU General Public License along | ||
| 26 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
| 27 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 28 | */ | ||
| 29 | |||
| 30 | #include <linux/init.h> | ||
| 31 | #include <linux/kernel.h> | ||
| 32 | #include <asm/bootinfo.h> | ||
| 33 | #include <asm/mach-au1x00/au1000.h> | ||
| 34 | #include <prom.h> | ||
| 35 | |||
| 36 | #if defined(CONFIG_MIPS_DB1000) || \ | ||
| 37 | defined(CONFIG_MIPS_PB1100) || \ | ||
| 38 | defined(CONFIG_MIPS_PB1500) | ||
| 39 | #define ALCHEMY_BOARD_DEFAULT_MEMSIZE 0x04000000 | ||
| 40 | |||
| 41 | #else /* Au1550/Au1200-based develboards */ | ||
| 42 | #define ALCHEMY_BOARD_DEFAULT_MEMSIZE 0x08000000 | ||
| 43 | #endif | ||
| 44 | |||
| 45 | void __init prom_init(void) | ||
| 46 | { | ||
| 47 | unsigned char *memsize_str; | ||
| 48 | unsigned long memsize; | ||
| 49 | |||
| 50 | prom_argc = (int)fw_arg0; | ||
| 51 | prom_argv = (char **)fw_arg1; | ||
| 52 | prom_envp = (char **)fw_arg2; | ||
| 53 | |||
| 54 | prom_init_cmdline(); | ||
| 55 | memsize_str = prom_getenv("memsize"); | ||
| 56 | if (!memsize_str || strict_strtoul(memsize_str, 0, &memsize)) | ||
| 57 | memsize = ALCHEMY_BOARD_DEFAULT_MEMSIZE; | ||
| 58 | |||
| 59 | add_memory_region(0, memsize, BOOT_MEM_RAM); | ||
| 60 | } | ||
| 61 | |||
| 62 | void prom_putchar(unsigned char c) | ||
| 63 | { | ||
| 64 | #ifdef CONFIG_MIPS_DB1300 | ||
| 65 | alchemy_uart_putchar(AU1300_UART2_PHYS_ADDR, c); | ||
| 66 | #else | ||
| 67 | alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c); | ||
| 68 | #endif | ||
| 69 | } | ||
diff --git a/arch/mips/bcm63xx/Kconfig b/arch/mips/bcm63xx/Kconfig index 6b1b9ad8d857..d03e8799d1cf 100644 --- a/arch/mips/bcm63xx/Kconfig +++ b/arch/mips/bcm63xx/Kconfig | |||
| @@ -1,6 +1,10 @@ | |||
| 1 | menu "CPU support" | 1 | menu "CPU support" |
| 2 | depends on BCM63XX | 2 | depends on BCM63XX |
| 3 | 3 | ||
| 4 | config BCM63XX_CPU_6328 | ||
| 5 | bool "support 6328 CPU" | ||
| 6 | select HW_HAS_PCI | ||
| 7 | |||
| 4 | config BCM63XX_CPU_6338 | 8 | config BCM63XX_CPU_6338 |
| 5 | bool "support 6338 CPU" | 9 | bool "support 6338 CPU" |
| 6 | select HW_HAS_PCI | 10 | select HW_HAS_PCI |
diff --git a/arch/mips/bcm63xx/Makefile b/arch/mips/bcm63xx/Makefile index 6dfdc69928ac..833af72c852a 100644 --- a/arch/mips/bcm63xx/Makefile +++ b/arch/mips/bcm63xx/Makefile | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | obj-y += clk.o cpu.o cs.o gpio.o irq.o prom.o setup.o timer.o \ | 1 | obj-y += clk.o cpu.o cs.o gpio.o irq.o prom.o setup.o timer.o \ |
| 2 | dev-dsp.o dev-enet.o dev-pcmcia.o dev-uart.o dev-wdt.o | 2 | dev-dsp.o dev-enet.o dev-flash.o dev-pcmcia.o dev-rng.o \ |
| 3 | dev-spi.o dev-uart.o dev-wdt.o | ||
| 3 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o | 4 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o |
| 4 | 5 | ||
| 5 | obj-y += boards/ | 6 | obj-y += boards/ |
diff --git a/arch/mips/bcm63xx/boards/board_bcm963xx.c b/arch/mips/bcm63xx/boards/board_bcm963xx.c index 2f1773f3fb7a..feb05258a4d1 100644 --- a/arch/mips/bcm63xx/boards/board_bcm963xx.c +++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c | |||
| @@ -11,9 +11,6 @@ | |||
| 11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
| 12 | #include <linux/string.h> | 12 | #include <linux/string.h> |
| 13 | #include <linux/platform_device.h> | 13 | #include <linux/platform_device.h> |
| 14 | #include <linux/mtd/mtd.h> | ||
| 15 | #include <linux/mtd/partitions.h> | ||
| 16 | #include <linux/mtd/physmap.h> | ||
| 17 | #include <linux/ssb/ssb.h> | 14 | #include <linux/ssb/ssb.h> |
| 18 | #include <asm/addrspace.h> | 15 | #include <asm/addrspace.h> |
| 19 | #include <bcm63xx_board.h> | 16 | #include <bcm63xx_board.h> |
| @@ -24,7 +21,9 @@ | |||
| 24 | #include <bcm63xx_dev_pci.h> | 21 | #include <bcm63xx_dev_pci.h> |
| 25 | #include <bcm63xx_dev_enet.h> | 22 | #include <bcm63xx_dev_enet.h> |
| 26 | #include <bcm63xx_dev_dsp.h> | 23 | #include <bcm63xx_dev_dsp.h> |
| 24 | #include <bcm63xx_dev_flash.h> | ||
| 27 | #include <bcm63xx_dev_pcmcia.h> | 25 | #include <bcm63xx_dev_pcmcia.h> |
| 26 | #include <bcm63xx_dev_spi.h> | ||
| 28 | #include <board_bcm963xx.h> | 27 | #include <board_bcm963xx.h> |
| 29 | 28 | ||
| 30 | #define PFX "board_bcm963xx: " | 29 | #define PFX "board_bcm963xx: " |
| @@ -34,6 +33,48 @@ static unsigned int mac_addr_used; | |||
| 34 | static struct board_info board; | 33 | static struct board_info board; |
| 35 | 34 | ||
| 36 | /* | 35 | /* |
| 36 | * known 6328 boards | ||
| 37 | */ | ||
| 38 | #ifdef CONFIG_BCM63XX_CPU_6328 | ||
| 39 | static struct board_info __initdata board_96328avng = { | ||
| 40 | .name = "96328avng", | ||
| 41 | .expected_cpu_id = 0x6328, | ||
| 42 | |||
| 43 | .has_uart0 = 1, | ||
| 44 | .has_pci = 1, | ||
| 45 | |||
| 46 | .leds = { | ||
| 47 | { | ||
| 48 | .name = "96328avng::ppp-fail", | ||
| 49 | .gpio = 2, | ||
| 50 | .active_low = 1, | ||
| 51 | }, | ||
| 52 | { | ||
| 53 | .name = "96328avng::power", | ||
| 54 | .gpio = 4, | ||
| 55 | .active_low = 1, | ||
| 56 | .default_trigger = "default-on", | ||
| 57 | }, | ||
| 58 | { | ||
| 59 | .name = "96328avng::power-fail", | ||
| 60 | .gpio = 8, | ||
| 61 | .active_low = 1, | ||
| 62 | }, | ||
| 63 | { | ||
| 64 | .name = "96328avng::wps", | ||
| 65 | .gpio = 9, | ||
| 66 | .active_low = 1, | ||
| 67 | }, | ||
| 68 | { | ||
| 69 | .name = "96328avng::ppp", | ||
| 70 | .gpio = 11, | ||
| 71 | .active_low = 1, | ||
| 72 | }, | ||
| 73 | }, | ||
| 74 | }; | ||
| 75 | #endif | ||
| 76 | |||
| 77 | /* | ||
| 37 | * known 6338 boards | 78 | * known 6338 boards |
| 38 | */ | 79 | */ |
| 39 | #ifdef CONFIG_BCM63XX_CPU_6338 | 80 | #ifdef CONFIG_BCM63XX_CPU_6338 |
| @@ -592,6 +633,9 @@ static struct board_info __initdata board_DWVS0 = { | |||
| 592 | * all boards | 633 | * all boards |
| 593 | */ | 634 | */ |
| 594 | static const struct board_info __initdata *bcm963xx_boards[] = { | 635 | static const struct board_info __initdata *bcm963xx_boards[] = { |
| 636 | #ifdef CONFIG_BCM63XX_CPU_6328 | ||
| 637 | &board_96328avng, | ||
| 638 | #endif | ||
| 595 | #ifdef CONFIG_BCM63XX_CPU_6338 | 639 | #ifdef CONFIG_BCM63XX_CPU_6338 |
| 596 | &board_96338gw, | 640 | &board_96338gw, |
| 597 | &board_96338w, | 641 | &board_96338w, |
| @@ -709,9 +753,15 @@ void __init board_prom_init(void) | |||
| 709 | char cfe_version[32]; | 753 | char cfe_version[32]; |
| 710 | u32 val; | 754 | u32 val; |
| 711 | 755 | ||
| 712 | /* read base address of boot chip select (0) */ | 756 | /* read base address of boot chip select (0) |
| 713 | val = bcm_mpi_readl(MPI_CSBASE_REG(0)); | 757 | * 6328 does not have MPI but boots from a fixed address |
| 714 | val &= MPI_CSBASE_BASE_MASK; | 758 | */ |
| 759 | if (BCMCPU_IS_6328()) | ||
| 760 | val = 0x18000000; | ||
| 761 | else { | ||
| 762 | val = bcm_mpi_readl(MPI_CSBASE_REG(0)); | ||
| 763 | val &= MPI_CSBASE_BASE_MASK; | ||
| 764 | } | ||
| 715 | boot_addr = (u8 *)KSEG1ADDR(val); | 765 | boot_addr = (u8 *)KSEG1ADDR(val); |
| 716 | 766 | ||
| 717 | /* dump cfe version */ | 767 | /* dump cfe version */ |
| @@ -808,40 +858,6 @@ void __init board_setup(void) | |||
| 808 | panic("unexpected CPU for bcm963xx board"); | 858 | panic("unexpected CPU for bcm963xx board"); |
| 809 | } | 859 | } |
| 810 | 860 | ||
| 811 | static struct mtd_partition mtd_partitions[] = { | ||
| 812 | { | ||
| 813 | .name = "cfe", | ||
| 814 | .offset = 0x0, | ||
| 815 | .size = 0x40000, | ||
| 816 | } | ||
| 817 | }; | ||
| 818 | |||
| 819 | static const char *bcm63xx_part_types[] = { "bcm63xxpart", NULL }; | ||
| 820 | |||
| 821 | static struct physmap_flash_data flash_data = { | ||
| 822 | .width = 2, | ||
| 823 | .nr_parts = ARRAY_SIZE(mtd_partitions), | ||
| 824 | .parts = mtd_partitions, | ||
| 825 | .part_probe_types = bcm63xx_part_types, | ||
| 826 | }; | ||
| 827 | |||
| 828 | static struct resource mtd_resources[] = { | ||
| 829 | { | ||
| 830 | .start = 0, /* filled at runtime */ | ||
| 831 | .end = 0, /* filled at runtime */ | ||
| 832 | .flags = IORESOURCE_MEM, | ||
| 833 | } | ||
| 834 | }; | ||
| 835 | |||
| 836 | static struct platform_device mtd_dev = { | ||
| 837 | .name = "physmap-flash", | ||
| 838 | .resource = mtd_resources, | ||
| 839 | .num_resources = ARRAY_SIZE(mtd_resources), | ||
| 840 | .dev = { | ||
| 841 | .platform_data = &flash_data, | ||
| 842 | }, | ||
| 843 | }; | ||
| 844 | |||
| 845 | static struct gpio_led_platform_data bcm63xx_led_data; | 861 | static struct gpio_led_platform_data bcm63xx_led_data; |
| 846 | 862 | ||
| 847 | static struct platform_device bcm63xx_gpio_leds = { | 863 | static struct platform_device bcm63xx_gpio_leds = { |
| @@ -855,8 +871,6 @@ static struct platform_device bcm63xx_gpio_leds = { | |||
| 855 | */ | 871 | */ |
| 856 | int __init board_register_devices(void) | 872 | int __init board_register_devices(void) |
| 857 | { | 873 | { |
| 858 | u32 val; | ||
| 859 | |||
| 860 | if (board.has_uart0) | 874 | if (board.has_uart0) |
| 861 | bcm63xx_uart_register(0); | 875 | bcm63xx_uart_register(0); |
| 862 | 876 | ||
| @@ -890,14 +904,9 @@ int __init board_register_devices(void) | |||
| 890 | } | 904 | } |
| 891 | #endif | 905 | #endif |
| 892 | 906 | ||
| 893 | /* read base address of boot chip select (0) */ | 907 | bcm63xx_spi_register(); |
| 894 | val = bcm_mpi_readl(MPI_CSBASE_REG(0)); | ||
| 895 | val &= MPI_CSBASE_BASE_MASK; | ||
| 896 | |||
| 897 | mtd_resources[0].start = val; | ||
| 898 | mtd_resources[0].end = 0x1FFFFFFF; | ||
| 899 | 908 | ||
| 900 | platform_device_register(&mtd_dev); | 909 | bcm63xx_flash_register(); |
| 901 | 910 | ||
| 902 | bcm63xx_led_data.num_leds = ARRAY_SIZE(board.leds); | 911 | bcm63xx_led_data.num_leds = ARRAY_SIZE(board.leds); |
| 903 | bcm63xx_led_data.leds = board.leds; | 912 | bcm63xx_led_data.leds = board.leds; |
diff --git a/arch/mips/bcm63xx/clk.c b/arch/mips/bcm63xx/clk.c index 9d57c71b7b58..1db48adb543a 100644 --- a/arch/mips/bcm63xx/clk.c +++ b/arch/mips/bcm63xx/clk.c | |||
| @@ -120,7 +120,7 @@ static void enetsw_set(struct clk *clk, int enable) | |||
| 120 | { | 120 | { |
| 121 | if (!BCMCPU_IS_6368()) | 121 | if (!BCMCPU_IS_6368()) |
| 122 | return; | 122 | return; |
| 123 | bcm_hwclock_set(CKCTL_6368_ROBOSW_CLK_EN | | 123 | bcm_hwclock_set(CKCTL_6368_ROBOSW_EN | |
| 124 | CKCTL_6368_SWPKT_USB_EN | | 124 | CKCTL_6368_SWPKT_USB_EN | |
| 125 | CKCTL_6368_SWPKT_SAR_EN, enable); | 125 | CKCTL_6368_SWPKT_SAR_EN, enable); |
| 126 | if (enable) { | 126 | if (enable) { |
| @@ -163,7 +163,7 @@ static void usbh_set(struct clk *clk, int enable) | |||
| 163 | if (BCMCPU_IS_6348()) | 163 | if (BCMCPU_IS_6348()) |
| 164 | bcm_hwclock_set(CKCTL_6348_USBH_EN, enable); | 164 | bcm_hwclock_set(CKCTL_6348_USBH_EN, enable); |
| 165 | else if (BCMCPU_IS_6368()) | 165 | else if (BCMCPU_IS_6368()) |
| 166 | bcm_hwclock_set(CKCTL_6368_USBH_CLK_EN, enable); | 166 | bcm_hwclock_set(CKCTL_6368_USBH_EN, enable); |
| 167 | } | 167 | } |
| 168 | 168 | ||
| 169 | static struct clk clk_usbh = { | 169 | static struct clk clk_usbh = { |
| @@ -181,9 +181,11 @@ static void spi_set(struct clk *clk, int enable) | |||
| 181 | mask = CKCTL_6338_SPI_EN; | 181 | mask = CKCTL_6338_SPI_EN; |
| 182 | else if (BCMCPU_IS_6348()) | 182 | else if (BCMCPU_IS_6348()) |
| 183 | mask = CKCTL_6348_SPI_EN; | 183 | mask = CKCTL_6348_SPI_EN; |
| 184 | else | 184 | else if (BCMCPU_IS_6358()) |
| 185 | /* BCMCPU_IS_6358 */ | ||
| 186 | mask = CKCTL_6358_SPI_EN; | 185 | mask = CKCTL_6358_SPI_EN; |
| 186 | else | ||
| 187 | /* BCMCPU_IS_6368 */ | ||
| 188 | mask = CKCTL_6368_SPI_EN; | ||
| 187 | bcm_hwclock_set(mask, enable); | 189 | bcm_hwclock_set(mask, enable); |
| 188 | } | 190 | } |
| 189 | 191 | ||
| @@ -199,7 +201,7 @@ static void xtm_set(struct clk *clk, int enable) | |||
| 199 | if (!BCMCPU_IS_6368()) | 201 | if (!BCMCPU_IS_6368()) |
| 200 | return; | 202 | return; |
| 201 | 203 | ||
| 202 | bcm_hwclock_set(CKCTL_6368_SAR_CLK_EN | | 204 | bcm_hwclock_set(CKCTL_6368_SAR_EN | |
| 203 | CKCTL_6368_SWPKT_SAR_EN, enable); | 205 | CKCTL_6368_SWPKT_SAR_EN, enable); |
| 204 | 206 | ||
| 205 | if (enable) { | 207 | if (enable) { |
| @@ -222,6 +224,18 @@ static struct clk clk_xtm = { | |||
| 222 | }; | 224 | }; |
| 223 | 225 | ||
| 224 | /* | 226 | /* |
| 227 | * IPsec clock | ||
| 228 | */ | ||
| 229 | static void ipsec_set(struct clk *clk, int enable) | ||
| 230 | { | ||
| 231 | bcm_hwclock_set(CKCTL_6368_IPSEC_EN, enable); | ||
| 232 | } | ||
| 233 | |||
| 234 | static struct clk clk_ipsec = { | ||
| 235 | .set = ipsec_set, | ||
| 236 | }; | ||
| 237 | |||
| 238 | /* | ||
| 225 | * Internal peripheral clock | 239 | * Internal peripheral clock |
| 226 | */ | 240 | */ |
| 227 | static struct clk clk_periph = { | 241 | static struct clk clk_periph = { |
| @@ -278,6 +292,8 @@ struct clk *clk_get(struct device *dev, const char *id) | |||
| 278 | return &clk_periph; | 292 | return &clk_periph; |
| 279 | if (BCMCPU_IS_6358() && !strcmp(id, "pcm")) | 293 | if (BCMCPU_IS_6358() && !strcmp(id, "pcm")) |
| 280 | return &clk_pcm; | 294 | return &clk_pcm; |
| 295 | if (BCMCPU_IS_6368() && !strcmp(id, "ipsec")) | ||
| 296 | return &clk_ipsec; | ||
| 281 | return ERR_PTR(-ENOENT); | 297 | return ERR_PTR(-ENOENT); |
| 282 | } | 298 | } |
| 283 | 299 | ||
diff --git a/arch/mips/bcm63xx/cpu.c b/arch/mips/bcm63xx/cpu.c index 8f0d6c7725ea..a7afb289b15a 100644 --- a/arch/mips/bcm63xx/cpu.c +++ b/arch/mips/bcm63xx/cpu.c | |||
| @@ -29,6 +29,14 @@ static u16 bcm63xx_cpu_rev; | |||
| 29 | static unsigned int bcm63xx_cpu_freq; | 29 | static unsigned int bcm63xx_cpu_freq; |
| 30 | static unsigned int bcm63xx_memory_size; | 30 | static unsigned int bcm63xx_memory_size; |
| 31 | 31 | ||
| 32 | static const unsigned long bcm6328_regs_base[] = { | ||
| 33 | __GEN_CPU_REGS_TABLE(6328) | ||
| 34 | }; | ||
| 35 | |||
| 36 | static const int bcm6328_irqs[] = { | ||
| 37 | __GEN_CPU_IRQ_TABLE(6328) | ||
| 38 | }; | ||
| 39 | |||
| 32 | static const unsigned long bcm6338_regs_base[] = { | 40 | static const unsigned long bcm6338_regs_base[] = { |
| 33 | __GEN_CPU_REGS_TABLE(6338) | 41 | __GEN_CPU_REGS_TABLE(6338) |
| 34 | }; | 42 | }; |
| @@ -99,6 +107,33 @@ unsigned int bcm63xx_get_memory_size(void) | |||
| 99 | static unsigned int detect_cpu_clock(void) | 107 | static unsigned int detect_cpu_clock(void) |
| 100 | { | 108 | { |
| 101 | switch (bcm63xx_get_cpu_id()) { | 109 | switch (bcm63xx_get_cpu_id()) { |
| 110 | case BCM6328_CPU_ID: | ||
| 111 | { | ||
| 112 | unsigned int tmp, mips_pll_fcvo; | ||
| 113 | |||
| 114 | tmp = bcm_misc_readl(MISC_STRAPBUS_6328_REG); | ||
| 115 | mips_pll_fcvo = (tmp & STRAPBUS_6328_FCVO_MASK) | ||
| 116 | >> STRAPBUS_6328_FCVO_SHIFT; | ||
| 117 | |||
| 118 | switch (mips_pll_fcvo) { | ||
| 119 | case 0x12: | ||
| 120 | case 0x14: | ||
| 121 | case 0x19: | ||
| 122 | return 160000000; | ||
| 123 | case 0x1c: | ||
| 124 | return 192000000; | ||
| 125 | case 0x13: | ||
| 126 | case 0x15: | ||
| 127 | return 200000000; | ||
| 128 | case 0x1a: | ||
| 129 | return 384000000; | ||
| 130 | case 0x16: | ||
| 131 | return 400000000; | ||
| 132 | default: | ||
| 133 | return 320000000; | ||
| 134 | } | ||
| 135 | |||
| 136 | } | ||
| 102 | case BCM6338_CPU_ID: | 137 | case BCM6338_CPU_ID: |
| 103 | /* BCM6338 has a fixed 240 Mhz frequency */ | 138 | /* BCM6338 has a fixed 240 Mhz frequency */ |
| 104 | return 240000000; | 139 | return 240000000; |
| @@ -170,6 +205,9 @@ static unsigned int detect_memory_size(void) | |||
| 170 | unsigned int cols = 0, rows = 0, is_32bits = 0, banks = 0; | 205 | unsigned int cols = 0, rows = 0, is_32bits = 0, banks = 0; |
| 171 | u32 val; | 206 | u32 val; |
| 172 | 207 | ||
| 208 | if (BCMCPU_IS_6328()) | ||
| 209 | return bcm_ddr_readl(DDR_CSEND_REG) << 24; | ||
| 210 | |||
| 173 | if (BCMCPU_IS_6345()) { | 211 | if (BCMCPU_IS_6345()) { |
| 174 | val = bcm_sdram_readl(SDRAM_MBASE_REG); | 212 | val = bcm_sdram_readl(SDRAM_MBASE_REG); |
| 175 | return (val * 8 * 1024 * 1024); | 213 | return (val * 8 * 1024 * 1024); |
| @@ -228,17 +266,26 @@ void __init bcm63xx_cpu_init(void) | |||
| 228 | bcm63xx_irqs = bcm6345_irqs; | 266 | bcm63xx_irqs = bcm6345_irqs; |
| 229 | break; | 267 | break; |
| 230 | case CPU_BMIPS4350: | 268 | case CPU_BMIPS4350: |
| 231 | switch (read_c0_prid() & 0xf0) { | 269 | if ((read_c0_prid() & 0xf0) == 0x10) { |
| 232 | case 0x10: | ||
| 233 | expected_cpu_id = BCM6358_CPU_ID; | 270 | expected_cpu_id = BCM6358_CPU_ID; |
| 234 | bcm63xx_regs_base = bcm6358_regs_base; | 271 | bcm63xx_regs_base = bcm6358_regs_base; |
| 235 | bcm63xx_irqs = bcm6358_irqs; | 272 | bcm63xx_irqs = bcm6358_irqs; |
| 236 | break; | 273 | } else { |
| 237 | case 0x30: | 274 | /* all newer chips have the same chip id location */ |
| 238 | expected_cpu_id = BCM6368_CPU_ID; | 275 | u16 chip_id = bcm_readw(BCM_6368_PERF_BASE); |
| 239 | bcm63xx_regs_base = bcm6368_regs_base; | 276 | |
| 240 | bcm63xx_irqs = bcm6368_irqs; | 277 | switch (chip_id) { |
| 241 | break; | 278 | case BCM6328_CPU_ID: |
| 279 | expected_cpu_id = BCM6328_CPU_ID; | ||
| 280 | bcm63xx_regs_base = bcm6328_regs_base; | ||
| 281 | bcm63xx_irqs = bcm6328_irqs; | ||
| 282 | break; | ||
| 283 | case BCM6368_CPU_ID: | ||
| 284 | expected_cpu_id = BCM6368_CPU_ID; | ||
| 285 | bcm63xx_regs_base = bcm6368_regs_base; | ||
| 286 | bcm63xx_irqs = bcm6368_irqs; | ||
| 287 | break; | ||
| 288 | } | ||
| 242 | } | 289 | } |
| 243 | break; | 290 | break; |
| 244 | } | 291 | } |
diff --git a/arch/mips/bcm63xx/dev-dsp.c b/arch/mips/bcm63xx/dev-dsp.c index da46d1d3c77c..5bb5b154c9bd 100644 --- a/arch/mips/bcm63xx/dev-dsp.c +++ b/arch/mips/bcm63xx/dev-dsp.c | |||
| @@ -31,7 +31,7 @@ static struct resource voip_dsp_resources[] = { | |||
| 31 | 31 | ||
| 32 | static struct platform_device bcm63xx_voip_dsp_device = { | 32 | static struct platform_device bcm63xx_voip_dsp_device = { |
| 33 | .name = "bcm63xx-voip-dsp", | 33 | .name = "bcm63xx-voip-dsp", |
| 34 | .id = 0, | 34 | .id = -1, |
| 35 | .num_resources = ARRAY_SIZE(voip_dsp_resources), | 35 | .num_resources = ARRAY_SIZE(voip_dsp_resources), |
| 36 | .resource = voip_dsp_resources, | 36 | .resource = voip_dsp_resources, |
| 37 | }; | 37 | }; |
diff --git a/arch/mips/bcm63xx/dev-flash.c b/arch/mips/bcm63xx/dev-flash.c new file mode 100644 index 000000000000..58371c7deac2 --- /dev/null +++ b/arch/mips/bcm63xx/dev-flash.c | |||
| @@ -0,0 +1,123 @@ | |||
| 1 | /* | ||
| 2 | * Broadcom BCM63xx flash registration | ||
| 3 | * | ||
| 4 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 5 | * License. See the file "COPYING" in the main directory of this archive | ||
| 6 | * for more details. | ||
| 7 | * | ||
| 8 | * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr> | ||
| 9 | * Copyright (C) 2008 Florian Fainelli <florian@openwrt.org> | ||
| 10 | * Copyright (C) 2012 Jonas Gorski <jonas.gorski@gmail.com> | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/init.h> | ||
| 14 | #include <linux/kernel.h> | ||
| 15 | #include <linux/platform_device.h> | ||
| 16 | #include <linux/mtd/mtd.h> | ||
| 17 | #include <linux/mtd/partitions.h> | ||
| 18 | #include <linux/mtd/physmap.h> | ||
| 19 | |||
| 20 | #include <bcm63xx_cpu.h> | ||
| 21 | #include <bcm63xx_dev_flash.h> | ||
| 22 | #include <bcm63xx_regs.h> | ||
| 23 | #include <bcm63xx_io.h> | ||
| 24 | |||
| 25 | static struct mtd_partition mtd_partitions[] = { | ||
| 26 | { | ||
| 27 | .name = "cfe", | ||
| 28 | .offset = 0x0, | ||
| 29 | .size = 0x40000, | ||
| 30 | } | ||
| 31 | }; | ||
| 32 | |||
| 33 | static const char *bcm63xx_part_types[] = { "bcm63xxpart", NULL }; | ||
| 34 | |||
| 35 | static struct physmap_flash_data flash_data = { | ||
| 36 | .width = 2, | ||
| 37 | .parts = mtd_partitions, | ||
| 38 | .part_probe_types = bcm63xx_part_types, | ||
| 39 | }; | ||
| 40 | |||
| 41 | static struct resource mtd_resources[] = { | ||
| 42 | { | ||
| 43 | .start = 0, /* filled at runtime */ | ||
| 44 | .end = 0, /* filled at runtime */ | ||
| 45 | .flags = IORESOURCE_MEM, | ||
| 46 | } | ||
| 47 | }; | ||
| 48 | |||
| 49 | static struct platform_device mtd_dev = { | ||
| 50 | .name = "physmap-flash", | ||
| 51 | .resource = mtd_resources, | ||
| 52 | .num_resources = ARRAY_SIZE(mtd_resources), | ||
| 53 | .dev = { | ||
| 54 | .platform_data = &flash_data, | ||
| 55 | }, | ||
| 56 | }; | ||
| 57 | |||
| 58 | static int __init bcm63xx_detect_flash_type(void) | ||
| 59 | { | ||
| 60 | u32 val; | ||
| 61 | |||
| 62 | switch (bcm63xx_get_cpu_id()) { | ||
| 63 | case BCM6328_CPU_ID: | ||
| 64 | val = bcm_misc_readl(MISC_STRAPBUS_6328_REG); | ||
| 65 | if (val & STRAPBUS_6328_BOOT_SEL_SERIAL) | ||
| 66 | return BCM63XX_FLASH_TYPE_SERIAL; | ||
| 67 | else | ||
| 68 | return BCM63XX_FLASH_TYPE_NAND; | ||
| 69 | case BCM6338_CPU_ID: | ||
| 70 | case BCM6345_CPU_ID: | ||
| 71 | case BCM6348_CPU_ID: | ||
| 72 | /* no way to auto detect so assume parallel */ | ||
| 73 | return BCM63XX_FLASH_TYPE_PARALLEL; | ||
| 74 | case BCM6358_CPU_ID: | ||
| 75 | val = bcm_gpio_readl(GPIO_STRAPBUS_REG); | ||
| 76 | if (val & STRAPBUS_6358_BOOT_SEL_PARALLEL) | ||
| 77 | return BCM63XX_FLASH_TYPE_PARALLEL; | ||
| 78 | else | ||
| 79 | return BCM63XX_FLASH_TYPE_SERIAL; | ||
| 80 | case BCM6368_CPU_ID: | ||
| 81 | val = bcm_gpio_readl(GPIO_STRAPBUS_REG); | ||
| 82 | switch (val & STRAPBUS_6368_BOOT_SEL_MASK) { | ||
| 83 | case STRAPBUS_6368_BOOT_SEL_NAND: | ||
| 84 | return BCM63XX_FLASH_TYPE_NAND; | ||
| 85 | case STRAPBUS_6368_BOOT_SEL_SERIAL: | ||
| 86 | return BCM63XX_FLASH_TYPE_SERIAL; | ||
| 87 | case STRAPBUS_6368_BOOT_SEL_PARALLEL: | ||
| 88 | return BCM63XX_FLASH_TYPE_PARALLEL; | ||
| 89 | } | ||
| 90 | default: | ||
| 91 | return -EINVAL; | ||
| 92 | } | ||
| 93 | } | ||
| 94 | |||
| 95 | int __init bcm63xx_flash_register(void) | ||
| 96 | { | ||
| 97 | int flash_type; | ||
| 98 | u32 val; | ||
| 99 | |||
| 100 | flash_type = bcm63xx_detect_flash_type(); | ||
| 101 | |||
| 102 | switch (flash_type) { | ||
| 103 | case BCM63XX_FLASH_TYPE_PARALLEL: | ||
| 104 | /* read base address of boot chip select (0) */ | ||
| 105 | val = bcm_mpi_readl(MPI_CSBASE_REG(0)); | ||
| 106 | val &= MPI_CSBASE_BASE_MASK; | ||
| 107 | |||
| 108 | mtd_resources[0].start = val; | ||
| 109 | mtd_resources[0].end = 0x1FFFFFFF; | ||
| 110 | |||
| 111 | return platform_device_register(&mtd_dev); | ||
| 112 | case BCM63XX_FLASH_TYPE_SERIAL: | ||
| 113 | pr_warn("unsupported serial flash detected\n"); | ||
| 114 | return -ENODEV; | ||
| 115 | case BCM63XX_FLASH_TYPE_NAND: | ||
| 116 | pr_warn("unsupported NAND flash detected\n"); | ||
| 117 | return -ENODEV; | ||
| 118 | default: | ||
| 119 | pr_err("flash detection failed for BCM%x: %d\n", | ||
| 120 | bcm63xx_get_cpu_id(), flash_type); | ||
| 121 | return -ENODEV; | ||
| 122 | } | ||
| 123 | } | ||
diff --git a/arch/mips/bcm63xx/dev-rng.c b/arch/mips/bcm63xx/dev-rng.c new file mode 100644 index 000000000000..d277b4dc6c68 --- /dev/null +++ b/arch/mips/bcm63xx/dev-rng.c | |||
| @@ -0,0 +1,40 @@ | |||
| 1 | /* | ||
| 2 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 3 | * License. See the file "COPYING" in the main directory of this archive | ||
| 4 | * for more details. | ||
| 5 | * | ||
| 6 | * Copyright (C) 2011 Florian Fainelli <florian@openwrt.org> | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/init.h> | ||
| 10 | #include <linux/kernel.h> | ||
| 11 | #include <linux/platform_device.h> | ||
| 12 | #include <bcm63xx_cpu.h> | ||
| 13 | |||
| 14 | static struct resource rng_resources[] = { | ||
| 15 | { | ||
| 16 | .start = -1, /* filled at runtime */ | ||
| 17 | .end = -1, /* filled at runtime */ | ||
| 18 | .flags = IORESOURCE_MEM, | ||
| 19 | }, | ||
| 20 | }; | ||
| 21 | |||
| 22 | static struct platform_device bcm63xx_rng_device = { | ||
| 23 | .name = "bcm63xx-rng", | ||
| 24 | .id = -1, | ||
| 25 | .num_resources = ARRAY_SIZE(rng_resources), | ||
| 26 | .resource = rng_resources, | ||
| 27 | }; | ||
| 28 | |||
| 29 | int __init bcm63xx_rng_register(void) | ||
| 30 | { | ||
| 31 | if (!BCMCPU_IS_6368()) | ||
| 32 | return -ENODEV; | ||
| 33 | |||
| 34 | rng_resources[0].start = bcm63xx_regset_address(RSET_RNG); | ||
| 35 | rng_resources[0].end = rng_resources[0].start; | ||
| 36 | rng_resources[0].end += RSET_RNG_SIZE - 1; | ||
| 37 | |||
| 38 | return platform_device_register(&bcm63xx_rng_device); | ||
| 39 | } | ||
| 40 | arch_initcall(bcm63xx_rng_register); | ||
diff --git a/arch/mips/bcm63xx/dev-spi.c b/arch/mips/bcm63xx/dev-spi.c new file mode 100644 index 000000000000..e39f73048d4f --- /dev/null +++ b/arch/mips/bcm63xx/dev-spi.c | |||
| @@ -0,0 +1,119 @@ | |||
| 1 | /* | ||
| 2 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 3 | * License. See the file "COPYING" in the main directory of this archive | ||
| 4 | * for more details. | ||
| 5 | * | ||
| 6 | * Copyright (C) 2009-2011 Florian Fainelli <florian@openwrt.org> | ||
| 7 | * Copyright (C) 2010 Tanguy Bouzeloc <tanguy.bouzeloc@efixo.com> | ||
| 8 | */ | ||
| 9 | |||
| 10 | #include <linux/init.h> | ||
| 11 | #include <linux/kernel.h> | ||
| 12 | #include <linux/export.h> | ||
| 13 | #include <linux/platform_device.h> | ||
| 14 | #include <linux/err.h> | ||
| 15 | #include <linux/clk.h> | ||
| 16 | |||
| 17 | #include <bcm63xx_cpu.h> | ||
| 18 | #include <bcm63xx_dev_spi.h> | ||
| 19 | #include <bcm63xx_regs.h> | ||
| 20 | |||
| 21 | #ifdef BCMCPU_RUNTIME_DETECT | ||
| 22 | /* | ||
| 23 | * register offsets | ||
| 24 | */ | ||
| 25 | static const unsigned long bcm6338_regs_spi[] = { | ||
| 26 | __GEN_SPI_REGS_TABLE(6338) | ||
| 27 | }; | ||
| 28 | |||
| 29 | static const unsigned long bcm6348_regs_spi[] = { | ||
| 30 | __GEN_SPI_REGS_TABLE(6348) | ||
| 31 | }; | ||
| 32 | |||
| 33 | static const unsigned long bcm6358_regs_spi[] = { | ||
| 34 | __GEN_SPI_REGS_TABLE(6358) | ||
| 35 | }; | ||
| 36 | |||
| 37 | static const unsigned long bcm6368_regs_spi[] = { | ||
| 38 | __GEN_SPI_REGS_TABLE(6368) | ||
| 39 | }; | ||
| 40 | |||
| 41 | const unsigned long *bcm63xx_regs_spi; | ||
| 42 | EXPORT_SYMBOL(bcm63xx_regs_spi); | ||
| 43 | |||
| 44 | static __init void bcm63xx_spi_regs_init(void) | ||
| 45 | { | ||
| 46 | if (BCMCPU_IS_6338()) | ||
| 47 | bcm63xx_regs_spi = bcm6338_regs_spi; | ||
| 48 | if (BCMCPU_IS_6348()) | ||
| 49 | bcm63xx_regs_spi = bcm6348_regs_spi; | ||
| 50 | if (BCMCPU_IS_6358()) | ||
| 51 | bcm63xx_regs_spi = bcm6358_regs_spi; | ||
| 52 | if (BCMCPU_IS_6368()) | ||
| 53 | bcm63xx_regs_spi = bcm6368_regs_spi; | ||
| 54 | } | ||
| 55 | #else | ||
| 56 | static __init void bcm63xx_spi_regs_init(void) { } | ||
| 57 | #endif | ||
| 58 | |||
| 59 | static struct resource spi_resources[] = { | ||
| 60 | { | ||
| 61 | .start = -1, /* filled at runtime */ | ||
| 62 | .end = -1, /* filled at runtime */ | ||
| 63 | .flags = IORESOURCE_MEM, | ||
| 64 | }, | ||
| 65 | { | ||
| 66 | .start = -1, /* filled at runtime */ | ||
| 67 | .flags = IORESOURCE_IRQ, | ||
| 68 | }, | ||
| 69 | }; | ||
| 70 | |||
| 71 | static struct bcm63xx_spi_pdata spi_pdata = { | ||
| 72 | .bus_num = 0, | ||
| 73 | .num_chipselect = 8, | ||
| 74 | }; | ||
| 75 | |||
| 76 | static struct platform_device bcm63xx_spi_device = { | ||
| 77 | .name = "bcm63xx-spi", | ||
| 78 | .id = -1, | ||
| 79 | .num_resources = ARRAY_SIZE(spi_resources), | ||
| 80 | .resource = spi_resources, | ||
| 81 | .dev = { | ||
| 82 | .platform_data = &spi_pdata, | ||
| 83 | }, | ||
| 84 | }; | ||
| 85 | |||
| 86 | int __init bcm63xx_spi_register(void) | ||
| 87 | { | ||
| 88 | struct clk *periph_clk; | ||
| 89 | |||
| 90 | if (BCMCPU_IS_6328() || BCMCPU_IS_6345()) | ||
| 91 | return -ENODEV; | ||
| 92 | |||
| 93 | periph_clk = clk_get(NULL, "periph"); | ||
| 94 | if (IS_ERR(periph_clk)) { | ||
| 95 | pr_err("unable to get periph clock\n"); | ||
| 96 | return -ENODEV; | ||
| 97 | } | ||
| 98 | |||
| 99 | /* Set bus frequency */ | ||
| 100 | spi_pdata.speed_hz = clk_get_rate(periph_clk); | ||
| 101 | |||
| 102 | spi_resources[0].start = bcm63xx_regset_address(RSET_SPI); | ||
| 103 | spi_resources[0].end = spi_resources[0].start; | ||
| 104 | spi_resources[1].start = bcm63xx_get_irq_number(IRQ_SPI); | ||
| 105 | |||
| 106 | if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) { | ||
| 107 | spi_resources[0].end += BCM_6338_RSET_SPI_SIZE - 1; | ||
| 108 | spi_pdata.fifo_size = SPI_6338_MSG_DATA_SIZE; | ||
| 109 | } | ||
| 110 | |||
| 111 | if (BCMCPU_IS_6358() || BCMCPU_IS_6368()) { | ||
| 112 | spi_resources[0].end += BCM_6358_RSET_SPI_SIZE - 1; | ||
| 113 | spi_pdata.fifo_size = SPI_6358_MSG_DATA_SIZE; | ||
| 114 | } | ||
| 115 | |||
| 116 | bcm63xx_spi_regs_init(); | ||
| 117 | |||
| 118 | return platform_device_register(&bcm63xx_spi_device); | ||
| 119 | } | ||
diff --git a/arch/mips/bcm63xx/dev-wdt.c b/arch/mips/bcm63xx/dev-wdt.c index 3e6c716a4c11..2a2346a99bcb 100644 --- a/arch/mips/bcm63xx/dev-wdt.c +++ b/arch/mips/bcm63xx/dev-wdt.c | |||
| @@ -21,7 +21,7 @@ static struct resource wdt_resources[] = { | |||
| 21 | 21 | ||
| 22 | static struct platform_device bcm63xx_wdt_device = { | 22 | static struct platform_device bcm63xx_wdt_device = { |
| 23 | .name = "bcm63xx-wdt", | 23 | .name = "bcm63xx-wdt", |
| 24 | .id = 0, | 24 | .id = -1, |
| 25 | .num_resources = ARRAY_SIZE(wdt_resources), | 25 | .num_resources = ARRAY_SIZE(wdt_resources), |
| 26 | .resource = wdt_resources, | 26 | .resource = wdt_resources, |
| 27 | }; | 27 | }; |
diff --git a/arch/mips/bcm63xx/irq.c b/arch/mips/bcm63xx/irq.c index 9a216a451d92..18e051ad18a5 100644 --- a/arch/mips/bcm63xx/irq.c +++ b/arch/mips/bcm63xx/irq.c | |||
| @@ -27,6 +27,17 @@ static void __internal_irq_unmask_32(unsigned int irq) __maybe_unused; | |||
| 27 | static void __internal_irq_unmask_64(unsigned int irq) __maybe_unused; | 27 | static void __internal_irq_unmask_64(unsigned int irq) __maybe_unused; |
| 28 | 28 | ||
| 29 | #ifndef BCMCPU_RUNTIME_DETECT | 29 | #ifndef BCMCPU_RUNTIME_DETECT |
| 30 | #ifdef CONFIG_BCM63XX_CPU_6328 | ||
| 31 | #define irq_stat_reg PERF_IRQSTAT_6328_REG | ||
| 32 | #define irq_mask_reg PERF_IRQMASK_6328_REG | ||
| 33 | #define irq_bits 64 | ||
| 34 | #define is_ext_irq_cascaded 1 | ||
| 35 | #define ext_irq_start (BCM_6328_EXT_IRQ0 - IRQ_INTERNAL_BASE) | ||
| 36 | #define ext_irq_end (BCM_6328_EXT_IRQ3 - IRQ_INTERNAL_BASE) | ||
| 37 | #define ext_irq_count 4 | ||
| 38 | #define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6328 | ||
| 39 | #define ext_irq_cfg_reg2 0 | ||
| 40 | #endif | ||
| 30 | #ifdef CONFIG_BCM63XX_CPU_6338 | 41 | #ifdef CONFIG_BCM63XX_CPU_6338 |
| 31 | #define irq_stat_reg PERF_IRQSTAT_6338_REG | 42 | #define irq_stat_reg PERF_IRQSTAT_6338_REG |
| 32 | #define irq_mask_reg PERF_IRQMASK_6338_REG | 43 | #define irq_mask_reg PERF_IRQMASK_6338_REG |
| @@ -118,6 +129,16 @@ static void bcm63xx_init_irq(void) | |||
| 118 | irq_mask_addr = bcm63xx_regset_address(RSET_PERF); | 129 | irq_mask_addr = bcm63xx_regset_address(RSET_PERF); |
| 119 | 130 | ||
| 120 | switch (bcm63xx_get_cpu_id()) { | 131 | switch (bcm63xx_get_cpu_id()) { |
| 132 | case BCM6328_CPU_ID: | ||
| 133 | irq_stat_addr += PERF_IRQSTAT_6328_REG; | ||
| 134 | irq_mask_addr += PERF_IRQMASK_6328_REG; | ||
| 135 | irq_bits = 64; | ||
| 136 | ext_irq_count = 4; | ||
| 137 | is_ext_irq_cascaded = 1; | ||
| 138 | ext_irq_start = BCM_6328_EXT_IRQ0 - IRQ_INTERNAL_BASE; | ||
| 139 | ext_irq_end = BCM_6328_EXT_IRQ3 - IRQ_INTERNAL_BASE; | ||
| 140 | ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6328; | ||
| 141 | break; | ||
| 121 | case BCM6338_CPU_ID: | 142 | case BCM6338_CPU_ID: |
| 122 | irq_stat_addr += PERF_IRQSTAT_6338_REG; | 143 | irq_stat_addr += PERF_IRQSTAT_6338_REG; |
| 123 | irq_mask_addr += PERF_IRQMASK_6338_REG; | 144 | irq_mask_addr += PERF_IRQMASK_6338_REG; |
diff --git a/arch/mips/bcm63xx/prom.c b/arch/mips/bcm63xx/prom.c index 99d7f405cbeb..10eaff458071 100644 --- a/arch/mips/bcm63xx/prom.c +++ b/arch/mips/bcm63xx/prom.c | |||
| @@ -26,7 +26,9 @@ void __init prom_init(void) | |||
| 26 | bcm_wdt_writel(WDT_STOP_2, WDT_CTL_REG); | 26 | bcm_wdt_writel(WDT_STOP_2, WDT_CTL_REG); |
| 27 | 27 | ||
| 28 | /* disable all hardware blocks clock for now */ | 28 | /* disable all hardware blocks clock for now */ |
| 29 | if (BCMCPU_IS_6338()) | 29 | if (BCMCPU_IS_6328()) |
| 30 | mask = CKCTL_6328_ALL_SAFE_EN; | ||
| 31 | else if (BCMCPU_IS_6338()) | ||
| 30 | mask = CKCTL_6338_ALL_SAFE_EN; | 32 | mask = CKCTL_6338_ALL_SAFE_EN; |
| 31 | else if (BCMCPU_IS_6345()) | 33 | else if (BCMCPU_IS_6345()) |
| 32 | mask = CKCTL_6345_ALL_SAFE_EN; | 34 | mask = CKCTL_6345_ALL_SAFE_EN; |
diff --git a/arch/mips/bcm63xx/setup.c b/arch/mips/bcm63xx/setup.c index 356b05583e14..0e74a13639cd 100644 --- a/arch/mips/bcm63xx/setup.c +++ b/arch/mips/bcm63xx/setup.c | |||
| @@ -68,6 +68,9 @@ void bcm63xx_machine_reboot(void) | |||
| 68 | 68 | ||
| 69 | /* mask and clear all external irq */ | 69 | /* mask and clear all external irq */ |
| 70 | switch (bcm63xx_get_cpu_id()) { | 70 | switch (bcm63xx_get_cpu_id()) { |
| 71 | case BCM6328_CPU_ID: | ||
| 72 | perf_regs[0] = PERF_EXTIRQ_CFG_REG_6328; | ||
| 73 | break; | ||
| 71 | case BCM6338_CPU_ID: | 74 | case BCM6338_CPU_ID: |
| 72 | perf_regs[0] = PERF_EXTIRQ_CFG_REG_6338; | 75 | perf_regs[0] = PERF_EXTIRQ_CFG_REG_6338; |
| 73 | break; | 76 | break; |
| @@ -95,9 +98,13 @@ void bcm63xx_machine_reboot(void) | |||
| 95 | bcm6348_a1_reboot(); | 98 | bcm6348_a1_reboot(); |
| 96 | 99 | ||
| 97 | printk(KERN_INFO "triggering watchdog soft-reset...\n"); | 100 | printk(KERN_INFO "triggering watchdog soft-reset...\n"); |
| 98 | reg = bcm_perf_readl(PERF_SYS_PLL_CTL_REG); | 101 | if (BCMCPU_IS_6328()) { |
| 99 | reg |= SYS_PLL_SOFT_RESET; | 102 | bcm_wdt_writel(1, WDT_SOFTRESET_REG); |
| 100 | bcm_perf_writel(reg, PERF_SYS_PLL_CTL_REG); | 103 | } else { |
| 104 | reg = bcm_perf_readl(PERF_SYS_PLL_CTL_REG); | ||
| 105 | reg |= SYS_PLL_SOFT_RESET; | ||
| 106 | bcm_perf_writel(reg, PERF_SYS_PLL_CTL_REG); | ||
| 107 | } | ||
| 101 | while (1) | 108 | while (1) |
| 102 | ; | 109 | ; |
| 103 | } | 110 | } |
diff --git a/arch/mips/boot/compressed/Makefile b/arch/mips/boot/compressed/Makefile index 5042d51b0512..c2a3fb0ffc87 100644 --- a/arch/mips/boot/compressed/Makefile +++ b/arch/mips/boot/compressed/Makefile | |||
| @@ -58,8 +58,12 @@ $(obj)/piggy.o: $(obj)/dummy.o $(obj)/vmlinux.bin.z FORCE | |||
| 58 | # Calculate the load address of the compressed kernel image | 58 | # Calculate the load address of the compressed kernel image |
| 59 | hostprogs-y := calc_vmlinuz_load_addr | 59 | hostprogs-y := calc_vmlinuz_load_addr |
| 60 | 60 | ||
| 61 | ifeq ($(CONFIG_MACH_JZ4740),y) | ||
| 62 | VMLINUZ_LOAD_ADDRESS := 0x80600000 | ||
| 63 | else | ||
| 61 | VMLINUZ_LOAD_ADDRESS = $(shell $(obj)/calc_vmlinuz_load_addr \ | 64 | VMLINUZ_LOAD_ADDRESS = $(shell $(obj)/calc_vmlinuz_load_addr \ |
| 62 | $(obj)/vmlinux.bin $(VMLINUX_LOAD_ADDRESS)) | 65 | $(obj)/vmlinux.bin $(VMLINUX_LOAD_ADDRESS)) |
| 66 | endif | ||
| 63 | 67 | ||
| 64 | vmlinuzobjs-y += $(obj)/piggy.o | 68 | vmlinuzobjs-y += $(obj)/piggy.o |
| 65 | 69 | ||
diff --git a/arch/mips/boot/compressed/uart-16550.c b/arch/mips/boot/compressed/uart-16550.c index c9caaf4fbf60..1c7b739b6a1d 100644 --- a/arch/mips/boot/compressed/uart-16550.c +++ b/arch/mips/boot/compressed/uart-16550.c | |||
| @@ -18,6 +18,11 @@ | |||
| 18 | #define PORT(offset) (CKSEG1ADDR(AR7_REGS_UART0) + (4 * offset)) | 18 | #define PORT(offset) (CKSEG1ADDR(AR7_REGS_UART0) + (4 * offset)) |
| 19 | #endif | 19 | #endif |
| 20 | 20 | ||
| 21 | #ifdef CONFIG_MACH_JZ4740 | ||
| 22 | #define UART0_BASE 0xB0030000 | ||
| 23 | #define PORT(offset) (UART0_BASE + (4 * offset)) | ||
| 24 | #endif | ||
| 25 | |||
| 21 | #ifndef PORT | 26 | #ifndef PORT |
| 22 | #error please define the serial port address for your own machine | 27 | #error please define the serial port address for your own machine |
| 23 | #endif | 28 | #endif |
diff --git a/arch/mips/cavium-octeon/.gitignore b/arch/mips/cavium-octeon/.gitignore new file mode 100644 index 000000000000..39c968605ff6 --- /dev/null +++ b/arch/mips/cavium-octeon/.gitignore | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | *.dtb.S | ||
| 2 | *.dtb | ||
diff --git a/arch/mips/cavium-octeon/Makefile b/arch/mips/cavium-octeon/Makefile index 19eb0434269f..bc96e2908f14 100644 --- a/arch/mips/cavium-octeon/Makefile +++ b/arch/mips/cavium-octeon/Makefile | |||
| @@ -9,9 +9,25 @@ | |||
| 9 | # Copyright (C) 2005-2009 Cavium Networks | 9 | # Copyright (C) 2005-2009 Cavium Networks |
| 10 | # | 10 | # |
| 11 | 11 | ||
| 12 | CFLAGS_octeon-platform.o = -I$(src)/../../../scripts/dtc/libfdt | ||
| 13 | CFLAGS_setup.o = -I$(src)/../../../scripts/dtc/libfdt | ||
| 14 | |||
| 12 | obj-y := cpu.o setup.o serial.o octeon-platform.o octeon-irq.o csrc-octeon.o | 15 | obj-y := cpu.o setup.o serial.o octeon-platform.o octeon-irq.o csrc-octeon.o |
| 13 | obj-y += dma-octeon.o flash_setup.o | 16 | obj-y += dma-octeon.o flash_setup.o |
| 14 | obj-y += octeon-memcpy.o | 17 | obj-y += octeon-memcpy.o |
| 15 | obj-y += executive/ | 18 | obj-y += executive/ |
| 16 | 19 | ||
| 17 | obj-$(CONFIG_SMP) += smp.o | 20 | obj-$(CONFIG_SMP) += smp.o |
| 21 | |||
| 22 | DTS_FILES = octeon_3xxx.dts octeon_68xx.dts | ||
| 23 | DTB_FILES = $(patsubst %.dts, %.dtb, $(DTS_FILES)) | ||
| 24 | |||
| 25 | obj-y += $(patsubst %.dts, %.dtb.o, $(DTS_FILES)) | ||
| 26 | |||
| 27 | $(obj)/%.dtb: $(src)/%.dts FORCE | ||
| 28 | $(call if_changed_dep,dtc) | ||
| 29 | |||
| 30 | # Let's keep the .dtb files around in case we want to look at them. | ||
| 31 | .SECONDARY: $(addprefix $(obj)/, $(DTB_FILES)) | ||
| 32 | |||
| 33 | clean-files += $(DTB_FILES) $(patsubst %.dtb, %.dtb.S, $(DTB_FILES)) | ||
diff --git a/arch/mips/cavium-octeon/executive/cvmx-fpa.c b/arch/mips/cavium-octeon/executive/cvmx-fpa.c deleted file mode 100644 index ad44b8bd8057..000000000000 --- a/arch/mips/cavium-octeon/executive/cvmx-fpa.c +++ /dev/null | |||
| @@ -1,183 +0,0 @@ | |||
| 1 | /***********************license start*************** | ||
| 2 | * Author: Cavium Networks | ||
| 3 | * | ||
| 4 | * Contact: support@caviumnetworks.com | ||
| 5 | * This file is part of the OCTEON SDK | ||
| 6 | * | ||
| 7 | * Copyright (c) 2003-2008 Cavium Networks | ||
| 8 | * | ||
| 9 | * This file is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License, Version 2, as | ||
| 11 | * published by the Free Software Foundation. | ||
| 12 | * | ||
| 13 | * This file is distributed in the hope that it will be useful, but | ||
| 14 | * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty | ||
| 15 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or | ||
| 16 | * NONINFRINGEMENT. See the GNU General Public License for more | ||
| 17 | * details. | ||
| 18 | * | ||
| 19 | * You should have received a copy of the GNU General Public License | ||
| 20 | * along with this file; if not, write to the Free Software | ||
| 21 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 22 | * or visit http://www.gnu.org/licenses/. | ||
| 23 | * | ||
| 24 | * This file may also be available under a different license from Cavium. | ||
| 25 | * Contact Cavium Networks for more information | ||
| 26 | ***********************license end**************************************/ | ||
| 27 | |||
| 28 | /** | ||
| 29 | * @file | ||
| 30 | * | ||
| 31 | * Support library for the hardware Free Pool Allocator. | ||
| 32 | * | ||
| 33 | * | ||
| 34 | */ | ||
| 35 | |||
| 36 | #include "cvmx-config.h" | ||
| 37 | #include "cvmx.h" | ||
| 38 | #include "cvmx-fpa.h" | ||
| 39 | #include "cvmx-ipd.h" | ||
| 40 | |||
| 41 | /** | ||
| 42 | * Current state of all the pools. Use access functions | ||
| 43 | * instead of using it directly. | ||
| 44 | */ | ||
| 45 | CVMX_SHARED cvmx_fpa_pool_info_t cvmx_fpa_pool_info[CVMX_FPA_NUM_POOLS]; | ||
| 46 | |||
| 47 | /** | ||
| 48 | * Setup a FPA pool to control a new block of memory. The | ||
| 49 | * buffer pointer must be a physical address. | ||
| 50 | * | ||
| 51 | * @pool: Pool to initialize | ||
| 52 | * 0 <= pool < 8 | ||
| 53 | * @name: Constant character string to name this pool. | ||
| 54 | * String is not copied. | ||
| 55 | * @buffer: Pointer to the block of memory to use. This must be | ||
| 56 | * accessible by all processors and external hardware. | ||
| 57 | * @block_size: Size for each block controlled by the FPA | ||
| 58 | * @num_blocks: Number of blocks | ||
| 59 | * | ||
| 60 | * Returns 0 on Success, | ||
| 61 | * -1 on failure | ||
| 62 | */ | ||
| 63 | int cvmx_fpa_setup_pool(uint64_t pool, const char *name, void *buffer, | ||
| 64 | uint64_t block_size, uint64_t num_blocks) | ||
| 65 | { | ||
| 66 | char *ptr; | ||
| 67 | if (!buffer) { | ||
| 68 | cvmx_dprintf | ||
| 69 | ("ERROR: cvmx_fpa_setup_pool: NULL buffer pointer!\n"); | ||
| 70 | return -1; | ||
| 71 | } | ||
| 72 | if (pool >= CVMX_FPA_NUM_POOLS) { | ||
| 73 | cvmx_dprintf("ERROR: cvmx_fpa_setup_pool: Illegal pool!\n"); | ||
| 74 | return -1; | ||
| 75 | } | ||
| 76 | |||
| 77 | if (block_size < CVMX_FPA_MIN_BLOCK_SIZE) { | ||
| 78 | cvmx_dprintf | ||
| 79 | ("ERROR: cvmx_fpa_setup_pool: Block size too small.\n"); | ||
| 80 | return -1; | ||
| 81 | } | ||
| 82 | |||
| 83 | if (((unsigned long)buffer & (CVMX_FPA_ALIGNMENT - 1)) != 0) { | ||
| 84 | cvmx_dprintf | ||
| 85 | ("ERROR: cvmx_fpa_setup_pool: Buffer not aligned properly.\n"); | ||
| 86 | return -1; | ||
| 87 | } | ||
| 88 | |||
| 89 | cvmx_fpa_pool_info[pool].name = name; | ||
| 90 | cvmx_fpa_pool_info[pool].size = block_size; | ||
| 91 | cvmx_fpa_pool_info[pool].starting_element_count = num_blocks; | ||
| 92 | cvmx_fpa_pool_info[pool].base = buffer; | ||
| 93 | |||
| 94 | ptr = (char *)buffer; | ||
| 95 | while (num_blocks--) { | ||
| 96 | cvmx_fpa_free(ptr, pool, 0); | ||
| 97 | ptr += block_size; | ||
| 98 | } | ||
| 99 | return 0; | ||
| 100 | } | ||
| 101 | |||
| 102 | /** | ||
| 103 | * Shutdown a Memory pool and validate that it had all of | ||
| 104 | * the buffers originally placed in it. | ||
| 105 | * | ||
| 106 | * @pool: Pool to shutdown | ||
| 107 | * Returns Zero on success | ||
| 108 | * - Positive is count of missing buffers | ||
| 109 | * - Negative is too many buffers or corrupted pointers | ||
| 110 | */ | ||
| 111 | uint64_t cvmx_fpa_shutdown_pool(uint64_t pool) | ||
| 112 | { | ||
| 113 | uint64_t errors = 0; | ||
| 114 | uint64_t count = 0; | ||
| 115 | uint64_t base = cvmx_ptr_to_phys(cvmx_fpa_pool_info[pool].base); | ||
| 116 | uint64_t finish = | ||
| 117 | base + | ||
| 118 | cvmx_fpa_pool_info[pool].size * | ||
| 119 | cvmx_fpa_pool_info[pool].starting_element_count; | ||
| 120 | void *ptr; | ||
| 121 | uint64_t address; | ||
| 122 | |||
| 123 | count = 0; | ||
| 124 | do { | ||
| 125 | ptr = cvmx_fpa_alloc(pool); | ||
| 126 | if (ptr) | ||
| 127 | address = cvmx_ptr_to_phys(ptr); | ||
| 128 | else | ||
| 129 | address = 0; | ||
| 130 | if (address) { | ||
| 131 | if ((address >= base) && (address < finish) && | ||
| 132 | (((address - | ||
| 133 | base) % cvmx_fpa_pool_info[pool].size) == 0)) { | ||
| 134 | count++; | ||
| 135 | } else { | ||
| 136 | cvmx_dprintf | ||
| 137 | ("ERROR: cvmx_fpa_shutdown_pool: Illegal address 0x%llx in pool %s(%d)\n", | ||
| 138 | (unsigned long long)address, | ||
| 139 | cvmx_fpa_pool_info[pool].name, (int)pool); | ||
| 140 | errors++; | ||
| 141 | } | ||
| 142 | } | ||
| 143 | } while (address); | ||
| 144 | |||
| 145 | #ifdef CVMX_ENABLE_PKO_FUNCTIONS | ||
| 146 | if (pool == 0) | ||
| 147 | cvmx_ipd_free_ptr(); | ||
| 148 | #endif | ||
| 149 | |||
| 150 | if (errors) { | ||
| 151 | cvmx_dprintf | ||
| 152 | ("ERROR: cvmx_fpa_shutdown_pool: Pool %s(%d) started at 0x%llx, ended at 0x%llx, with a step of 0x%llx\n", | ||
| 153 | cvmx_fpa_pool_info[pool].name, (int)pool, | ||
| 154 | (unsigned long long)base, (unsigned long long)finish, | ||
| 155 | (unsigned long long)cvmx_fpa_pool_info[pool].size); | ||
| 156 | return -errors; | ||
| 157 | } else | ||
| 158 | return 0; | ||
| 159 | } | ||
| 160 | |||
| 161 | uint64_t cvmx_fpa_get_block_size(uint64_t pool) | ||
| 162 | { | ||
| 163 | switch (pool) { | ||
| 164 | case 0: | ||
| 165 | return CVMX_FPA_POOL_0_SIZE; | ||
| 166 | case 1: | ||
| 167 | return CVMX_FPA_POOL_1_SIZE; | ||
| 168 | case 2: | ||
| 169 | return CVMX_FPA_POOL_2_SIZE; | ||
| 170 | case 3: | ||
| 171 | return CVMX_FPA_POOL_3_SIZE; | ||
| 172 | case 4: | ||
| 173 | return CVMX_FPA_POOL_4_SIZE; | ||
| 174 | case 5: | ||
| 175 | return CVMX_FPA_POOL_5_SIZE; | ||
| 176 | case 6: | ||
| 177 | return CVMX_FPA_POOL_6_SIZE; | ||
| 178 | case 7: | ||
| 179 | return CVMX_FPA_POOL_7_SIZE; | ||
| 180 | default: | ||
| 181 | return 0; | ||
| 182 | } | ||
| 183 | } | ||
diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper-fpa.c b/arch/mips/cavium-octeon/executive/cvmx-helper-fpa.c deleted file mode 100644 index c239e5f4ab9a..000000000000 --- a/arch/mips/cavium-octeon/executive/cvmx-helper-fpa.c +++ /dev/null | |||
| @@ -1,243 +0,0 @@ | |||
| 1 | /***********************license start*************** | ||
| 2 | * Author: Cavium Networks | ||
| 3 | * | ||
| 4 | * Contact: support@caviumnetworks.com | ||
| 5 | * This file is part of the OCTEON SDK | ||
| 6 | * | ||
| 7 | * Copyright (c) 2003-2008 Cavium Networks | ||
| 8 | * | ||
| 9 | * This file is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License, Version 2, as | ||
| 11 | * published by the Free Software Foundation. | ||
| 12 | * | ||
| 13 | * This file is distributed in the hope that it will be useful, but | ||
| 14 | * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty | ||
| 15 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or | ||
| 16 | * NONINFRINGEMENT. See the GNU General Public License for more | ||
| 17 | * details. | ||
| 18 | * | ||
| 19 | * You should have received a copy of the GNU General Public License | ||
| 20 | * along with this file; if not, write to the Free Software | ||
| 21 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 22 | * or visit http://www.gnu.org/licenses/. | ||
| 23 | * | ||
| 24 | * This file may also be available under a different license from Cavium. | ||
| 25 | * Contact Cavium Networks for more information | ||
| 26 | ***********************license end**************************************/ | ||
| 27 | |||
| 28 | /** | ||
| 29 | * @file | ||
| 30 | * | ||
| 31 | * Helper functions for FPA setup. | ||
| 32 | * | ||
| 33 | */ | ||
| 34 | #include "executive-config.h" | ||
| 35 | #include "cvmx-config.h" | ||
| 36 | #include "cvmx.h" | ||
| 37 | #include "cvmx-bootmem.h" | ||
| 38 | #include "cvmx-fpa.h" | ||
| 39 | #include "cvmx-helper-fpa.h" | ||
| 40 | |||
| 41 | /** | ||
| 42 | * Allocate memory for and initialize a single FPA pool. | ||
| 43 | * | ||
| 44 | * @pool: Pool to initialize | ||
| 45 | * @buffer_size: Size of buffers to allocate in bytes | ||
| 46 | * @buffers: Number of buffers to put in the pool. Zero is allowed | ||
| 47 | * @name: String name of the pool for debugging purposes | ||
| 48 | * Returns Zero on success, non-zero on failure | ||
| 49 | */ | ||
| 50 | static int __cvmx_helper_initialize_fpa_pool(int pool, uint64_t buffer_size, | ||
| 51 | uint64_t buffers, const char *name) | ||
| 52 | { | ||
| 53 | uint64_t current_num; | ||
| 54 | void *memory; | ||
| 55 | uint64_t align = CVMX_CACHE_LINE_SIZE; | ||
| 56 | |||
| 57 | /* | ||
| 58 | * Align the allocation so that power of 2 size buffers are | ||
| 59 | * naturally aligned. | ||
| 60 | */ | ||
| 61 | while (align < buffer_size) | ||
| 62 | align = align << 1; | ||
| 63 | |||
| 64 | if (buffers == 0) | ||
| 65 | return 0; | ||
| 66 | |||
| 67 | current_num = cvmx_read_csr(CVMX_FPA_QUEX_AVAILABLE(pool)); | ||
| 68 | if (current_num) { | ||
| 69 | cvmx_dprintf("Fpa pool %d(%s) already has %llu buffers. " | ||
| 70 | "Skipping setup.\n", | ||
| 71 | pool, name, (unsigned long long)current_num); | ||
| 72 | return 0; | ||
| 73 | } | ||
| 74 | |||
| 75 | memory = cvmx_bootmem_alloc(buffer_size * buffers, align); | ||
| 76 | if (memory == NULL) { | ||
| 77 | cvmx_dprintf("Out of memory initializing fpa pool %d(%s).\n", | ||
| 78 | pool, name); | ||
| 79 | return -1; | ||
| 80 | } | ||
| 81 | cvmx_fpa_setup_pool(pool, name, memory, buffer_size, buffers); | ||
| 82 | return 0; | ||
| 83 | } | ||
| 84 | |||
| 85 | /** | ||
| 86 | * Allocate memory and initialize the FPA pools using memory | ||
| 87 | * from cvmx-bootmem. Specifying zero for the number of | ||
| 88 | * buffers will cause that FPA pool to not be setup. This is | ||
| 89 | * useful if you aren't using some of the hardware and want | ||
| 90 | * to save memory. Use cvmx_helper_initialize_fpa instead of | ||
| 91 | * this function directly. | ||
| 92 | * | ||
| 93 | * @pip_pool: Should always be CVMX_FPA_PACKET_POOL | ||
| 94 | * @pip_size: Should always be CVMX_FPA_PACKET_POOL_SIZE | ||
| 95 | * @pip_buffers: | ||
| 96 | * Number of packet buffers. | ||
| 97 | * @wqe_pool: Should always be CVMX_FPA_WQE_POOL | ||
| 98 | * @wqe_size: Should always be CVMX_FPA_WQE_POOL_SIZE | ||
| 99 | * @wqe_entries: | ||
| 100 | * Number of work queue entries | ||
| 101 | * @pko_pool: Should always be CVMX_FPA_OUTPUT_BUFFER_POOL | ||
| 102 | * @pko_size: Should always be CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE | ||
| 103 | * @pko_buffers: | ||
| 104 | * PKO Command buffers. You should at minimum have two per | ||
| 105 | * each PKO queue. | ||
| 106 | * @tim_pool: Should always be CVMX_FPA_TIMER_POOL | ||
| 107 | * @tim_size: Should always be CVMX_FPA_TIMER_POOL_SIZE | ||
| 108 | * @tim_buffers: | ||
| 109 | * TIM ring buffer command queues. At least two per timer bucket | ||
| 110 | * is recommened. | ||
| 111 | * @dfa_pool: Should always be CVMX_FPA_DFA_POOL | ||
| 112 | * @dfa_size: Should always be CVMX_FPA_DFA_POOL_SIZE | ||
| 113 | * @dfa_buffers: | ||
| 114 | * DFA command buffer. A relatively small (32 for example) | ||
| 115 | * number should work. | ||
| 116 | * Returns Zero on success, non-zero if out of memory | ||
| 117 | */ | ||
| 118 | static int __cvmx_helper_initialize_fpa(int pip_pool, int pip_size, | ||
| 119 | int pip_buffers, int wqe_pool, | ||
| 120 | int wqe_size, int wqe_entries, | ||
| 121 | int pko_pool, int pko_size, | ||
| 122 | int pko_buffers, int tim_pool, | ||
| 123 | int tim_size, int tim_buffers, | ||
| 124 | int dfa_pool, int dfa_size, | ||
| 125 | int dfa_buffers) | ||
| 126 | { | ||
| 127 | int status; | ||
| 128 | |||
| 129 | cvmx_fpa_enable(); | ||
| 130 | |||
| 131 | if ((pip_buffers > 0) && (pip_buffers <= 64)) | ||
| 132 | cvmx_dprintf | ||
| 133 | ("Warning: %d packet buffers may not be enough for hardware" | ||
| 134 | " prefetch. 65 or more is recommended.\n", pip_buffers); | ||
| 135 | |||
| 136 | if (pip_pool >= 0) { | ||
| 137 | status = | ||
| 138 | __cvmx_helper_initialize_fpa_pool(pip_pool, pip_size, | ||
| 139 | pip_buffers, | ||
| 140 | "Packet Buffers"); | ||
| 141 | if (status) | ||
| 142 | return status; | ||
| 143 | } | ||
| 144 | |||
| 145 | if (wqe_pool >= 0) { | ||
| 146 | status = | ||
| 147 | __cvmx_helper_initialize_fpa_pool(wqe_pool, wqe_size, | ||
| 148 | wqe_entries, | ||
| 149 | "Work Queue Entries"); | ||
| 150 | if (status) | ||
| 151 | return status; | ||
| 152 | } | ||
| 153 | |||
| 154 | if (pko_pool >= 0) { | ||
| 155 | status = | ||
| 156 | __cvmx_helper_initialize_fpa_pool(pko_pool, pko_size, | ||
| 157 | pko_buffers, | ||
| 158 | "PKO Command Buffers"); | ||
| 159 | if (status) | ||
| 160 | return status; | ||
| 161 | } | ||
| 162 | |||
| 163 | if (tim_pool >= 0) { | ||
| 164 | status = | ||
| 165 | __cvmx_helper_initialize_fpa_pool(tim_pool, tim_size, | ||
| 166 | tim_buffers, | ||
| 167 | "TIM Command Buffers"); | ||
| 168 | if (status) | ||
| 169 | return status; | ||
| 170 | } | ||
| 171 | |||
| 172 | if (dfa_pool >= 0) { | ||
| 173 | status = | ||
| 174 | __cvmx_helper_initialize_fpa_pool(dfa_pool, dfa_size, | ||
| 175 | dfa_buffers, | ||
| 176 | "DFA Command Buffers"); | ||
| 177 | if (status) | ||
| 178 | return status; | ||
| 179 | } | ||
| 180 | |||
| 181 | return 0; | ||
| 182 | } | ||
| 183 | |||
| 184 | /** | ||
| 185 | * Allocate memory and initialize the FPA pools using memory | ||
| 186 | * from cvmx-bootmem. Sizes of each element in the pools is | ||
| 187 | * controlled by the cvmx-config.h header file. Specifying | ||
| 188 | * zero for any parameter will cause that FPA pool to not be | ||
| 189 | * setup. This is useful if you aren't using some of the | ||
| 190 | * hardware and want to save memory. | ||
| 191 | * | ||
| 192 | * @packet_buffers: | ||
| 193 | * Number of packet buffers to allocate | ||
| 194 | * @work_queue_entries: | ||
| 195 | * Number of work queue entries | ||
| 196 | * @pko_buffers: | ||
| 197 | * PKO Command buffers. You should at minimum have two per | ||
| 198 | * each PKO queue. | ||
| 199 | * @tim_buffers: | ||
| 200 | * TIM ring buffer command queues. At least two per timer bucket | ||
| 201 | * is recommened. | ||
| 202 | * @dfa_buffers: | ||
| 203 | * DFA command buffer. A relatively small (32 for example) | ||
| 204 | * number should work. | ||
| 205 | * Returns Zero on success, non-zero if out of memory | ||
| 206 | */ | ||
| 207 | int cvmx_helper_initialize_fpa(int packet_buffers, int work_queue_entries, | ||
| 208 | int pko_buffers, int tim_buffers, | ||
| 209 | int dfa_buffers) | ||
| 210 | { | ||
| 211 | #ifndef CVMX_FPA_PACKET_POOL | ||
| 212 | #define CVMX_FPA_PACKET_POOL -1 | ||
| 213 | #define CVMX_FPA_PACKET_POOL_SIZE 0 | ||
| 214 | #endif | ||
| 215 | #ifndef CVMX_FPA_WQE_POOL | ||
| 216 | #define CVMX_FPA_WQE_POOL -1 | ||
| 217 | #define CVMX_FPA_WQE_POOL_SIZE 0 | ||
| 218 | #endif | ||
| 219 | #ifndef CVMX_FPA_OUTPUT_BUFFER_POOL | ||
| 220 | #define CVMX_FPA_OUTPUT_BUFFER_POOL -1 | ||
| 221 | #define CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE 0 | ||
| 222 | #endif | ||
| 223 | #ifndef CVMX_FPA_TIMER_POOL | ||
| 224 | #define CVMX_FPA_TIMER_POOL -1 | ||
| 225 | #define CVMX_FPA_TIMER_POOL_SIZE 0 | ||
| 226 | #endif | ||
| 227 | #ifndef CVMX_FPA_DFA_POOL | ||
| 228 | #define CVMX_FPA_DFA_POOL -1 | ||
| 229 | #define CVMX_FPA_DFA_POOL_SIZE 0 | ||
| 230 | #endif | ||
| 231 | return __cvmx_helper_initialize_fpa(CVMX_FPA_PACKET_POOL, | ||
| 232 | CVMX_FPA_PACKET_POOL_SIZE, | ||
| 233 | packet_buffers, CVMX_FPA_WQE_POOL, | ||
| 234 | CVMX_FPA_WQE_POOL_SIZE, | ||
| 235 | work_queue_entries, | ||
| 236 | CVMX_FPA_OUTPUT_BUFFER_POOL, | ||
| 237 | CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE, | ||
| 238 | pko_buffers, CVMX_FPA_TIMER_POOL, | ||
| 239 | CVMX_FPA_TIMER_POOL_SIZE, | ||
| 240 | tim_buffers, CVMX_FPA_DFA_POOL, | ||
| 241 | CVMX_FPA_DFA_POOL_SIZE, | ||
| 242 | dfa_buffers); | ||
| 243 | } | ||
diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c index ffd4ae660f79..7fb1f222b8a5 100644 --- a/arch/mips/cavium-octeon/octeon-irq.c +++ b/arch/mips/cavium-octeon/octeon-irq.c | |||
| @@ -3,14 +3,17 @@ | |||
| 3 | * License. See the file "COPYING" in the main directory of this archive | 3 | * License. See the file "COPYING" in the main directory of this archive |
| 4 | * for more details. | 4 | * for more details. |
| 5 | * | 5 | * |
| 6 | * Copyright (C) 2004-2008, 2009, 2010, 2011 Cavium Networks | 6 | * Copyright (C) 2004-2012 Cavium, Inc. |
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | #include <linux/interrupt.h> | 9 | #include <linux/interrupt.h> |
| 10 | #include <linux/irqdomain.h> | ||
| 10 | #include <linux/bitops.h> | 11 | #include <linux/bitops.h> |
| 11 | #include <linux/percpu.h> | 12 | #include <linux/percpu.h> |
| 13 | #include <linux/slab.h> | ||
| 12 | #include <linux/irq.h> | 14 | #include <linux/irq.h> |
| 13 | #include <linux/smp.h> | 15 | #include <linux/smp.h> |
| 16 | #include <linux/of.h> | ||
| 14 | 17 | ||
| 15 | #include <asm/octeon/octeon.h> | 18 | #include <asm/octeon/octeon.h> |
| 16 | 19 | ||
| @@ -42,9 +45,9 @@ struct octeon_core_chip_data { | |||
| 42 | 45 | ||
| 43 | static struct octeon_core_chip_data octeon_irq_core_chip_data[MIPS_CORE_IRQ_LINES]; | 46 | static struct octeon_core_chip_data octeon_irq_core_chip_data[MIPS_CORE_IRQ_LINES]; |
| 44 | 47 | ||
| 45 | static void __init octeon_irq_set_ciu_mapping(int irq, int line, int bit, | 48 | static void octeon_irq_set_ciu_mapping(int irq, int line, int bit, |
| 46 | struct irq_chip *chip, | 49 | struct irq_chip *chip, |
| 47 | irq_flow_handler_t handler) | 50 | irq_flow_handler_t handler) |
| 48 | { | 51 | { |
| 49 | union octeon_ciu_chip_data cd; | 52 | union octeon_ciu_chip_data cd; |
| 50 | 53 | ||
| @@ -505,6 +508,85 @@ static void octeon_irq_ciu_enable_all_v2(struct irq_data *data) | |||
| 505 | } | 508 | } |
| 506 | } | 509 | } |
| 507 | 510 | ||
| 511 | static void octeon_irq_gpio_setup(struct irq_data *data) | ||
| 512 | { | ||
| 513 | union cvmx_gpio_bit_cfgx cfg; | ||
| 514 | union octeon_ciu_chip_data cd; | ||
| 515 | u32 t = irqd_get_trigger_type(data); | ||
| 516 | |||
| 517 | cd.p = irq_data_get_irq_chip_data(data); | ||
| 518 | |||
| 519 | cfg.u64 = 0; | ||
| 520 | cfg.s.int_en = 1; | ||
| 521 | cfg.s.int_type = (t & IRQ_TYPE_EDGE_BOTH) != 0; | ||
| 522 | cfg.s.rx_xor = (t & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING)) != 0; | ||
| 523 | |||
| 524 | /* 140 nS glitch filter*/ | ||
| 525 | cfg.s.fil_cnt = 7; | ||
| 526 | cfg.s.fil_sel = 3; | ||
| 527 | |||
| 528 | cvmx_write_csr(CVMX_GPIO_BIT_CFGX(cd.s.bit - 16), cfg.u64); | ||
| 529 | } | ||
| 530 | |||
| 531 | static void octeon_irq_ciu_enable_gpio_v2(struct irq_data *data) | ||
| 532 | { | ||
| 533 | octeon_irq_gpio_setup(data); | ||
| 534 | octeon_irq_ciu_enable_v2(data); | ||
| 535 | } | ||
| 536 | |||
| 537 | static void octeon_irq_ciu_enable_gpio(struct irq_data *data) | ||
| 538 | { | ||
| 539 | octeon_irq_gpio_setup(data); | ||
| 540 | octeon_irq_ciu_enable(data); | ||
| 541 | } | ||
| 542 | |||
| 543 | static int octeon_irq_ciu_gpio_set_type(struct irq_data *data, unsigned int t) | ||
| 544 | { | ||
| 545 | irqd_set_trigger_type(data, t); | ||
| 546 | octeon_irq_gpio_setup(data); | ||
| 547 | |||
| 548 | return IRQ_SET_MASK_OK; | ||
| 549 | } | ||
| 550 | |||
| 551 | static void octeon_irq_ciu_disable_gpio_v2(struct irq_data *data) | ||
| 552 | { | ||
| 553 | union octeon_ciu_chip_data cd; | ||
| 554 | |||
| 555 | cd.p = irq_data_get_irq_chip_data(data); | ||
| 556 | cvmx_write_csr(CVMX_GPIO_BIT_CFGX(cd.s.bit - 16), 0); | ||
| 557 | |||
| 558 | octeon_irq_ciu_disable_all_v2(data); | ||
| 559 | } | ||
| 560 | |||
| 561 | static void octeon_irq_ciu_disable_gpio(struct irq_data *data) | ||
| 562 | { | ||
| 563 | union octeon_ciu_chip_data cd; | ||
| 564 | |||
| 565 | cd.p = irq_data_get_irq_chip_data(data); | ||
| 566 | cvmx_write_csr(CVMX_GPIO_BIT_CFGX(cd.s.bit - 16), 0); | ||
| 567 | |||
| 568 | octeon_irq_ciu_disable_all(data); | ||
| 569 | } | ||
| 570 | |||
| 571 | static void octeon_irq_ciu_gpio_ack(struct irq_data *data) | ||
| 572 | { | ||
| 573 | union octeon_ciu_chip_data cd; | ||
| 574 | u64 mask; | ||
| 575 | |||
| 576 | cd.p = irq_data_get_irq_chip_data(data); | ||
| 577 | mask = 1ull << (cd.s.bit - 16); | ||
| 578 | |||
| 579 | cvmx_write_csr(CVMX_GPIO_INT_CLR, mask); | ||
| 580 | } | ||
| 581 | |||
| 582 | static void octeon_irq_handle_gpio(unsigned int irq, struct irq_desc *desc) | ||
| 583 | { | ||
| 584 | if (irqd_get_trigger_type(irq_desc_get_irq_data(desc)) & IRQ_TYPE_EDGE_BOTH) | ||
| 585 | handle_edge_irq(irq, desc); | ||
| 586 | else | ||
| 587 | handle_level_irq(irq, desc); | ||
| 588 | } | ||
| 589 | |||
| 508 | #ifdef CONFIG_SMP | 590 | #ifdef CONFIG_SMP |
| 509 | 591 | ||
| 510 | static void octeon_irq_cpu_offline_ciu(struct irq_data *data) | 592 | static void octeon_irq_cpu_offline_ciu(struct irq_data *data) |
| @@ -650,18 +732,6 @@ static struct irq_chip octeon_irq_chip_ciu_v2 = { | |||
| 650 | .name = "CIU", | 732 | .name = "CIU", |
| 651 | .irq_enable = octeon_irq_ciu_enable_v2, | 733 | .irq_enable = octeon_irq_ciu_enable_v2, |
| 652 | .irq_disable = octeon_irq_ciu_disable_all_v2, | 734 | .irq_disable = octeon_irq_ciu_disable_all_v2, |
| 653 | .irq_mask = octeon_irq_ciu_disable_local_v2, | ||
| 654 | .irq_unmask = octeon_irq_ciu_enable_v2, | ||
| 655 | #ifdef CONFIG_SMP | ||
| 656 | .irq_set_affinity = octeon_irq_ciu_set_affinity_v2, | ||
| 657 | .irq_cpu_offline = octeon_irq_cpu_offline_ciu, | ||
| 658 | #endif | ||
| 659 | }; | ||
| 660 | |||
| 661 | static struct irq_chip octeon_irq_chip_ciu_edge_v2 = { | ||
| 662 | .name = "CIU-E", | ||
| 663 | .irq_enable = octeon_irq_ciu_enable_v2, | ||
| 664 | .irq_disable = octeon_irq_ciu_disable_all_v2, | ||
| 665 | .irq_ack = octeon_irq_ciu_ack, | 735 | .irq_ack = octeon_irq_ciu_ack, |
| 666 | .irq_mask = octeon_irq_ciu_disable_local_v2, | 736 | .irq_mask = octeon_irq_ciu_disable_local_v2, |
| 667 | .irq_unmask = octeon_irq_ciu_enable_v2, | 737 | .irq_unmask = octeon_irq_ciu_enable_v2, |
| @@ -675,19 +745,8 @@ static struct irq_chip octeon_irq_chip_ciu = { | |||
| 675 | .name = "CIU", | 745 | .name = "CIU", |
| 676 | .irq_enable = octeon_irq_ciu_enable, | 746 | .irq_enable = octeon_irq_ciu_enable, |
| 677 | .irq_disable = octeon_irq_ciu_disable_all, | 747 | .irq_disable = octeon_irq_ciu_disable_all, |
| 678 | .irq_mask = octeon_irq_dummy_mask, | ||
| 679 | #ifdef CONFIG_SMP | ||
| 680 | .irq_set_affinity = octeon_irq_ciu_set_affinity, | ||
| 681 | .irq_cpu_offline = octeon_irq_cpu_offline_ciu, | ||
| 682 | #endif | ||
| 683 | }; | ||
| 684 | |||
| 685 | static struct irq_chip octeon_irq_chip_ciu_edge = { | ||
| 686 | .name = "CIU-E", | ||
| 687 | .irq_enable = octeon_irq_ciu_enable, | ||
| 688 | .irq_disable = octeon_irq_ciu_disable_all, | ||
| 689 | .irq_mask = octeon_irq_dummy_mask, | ||
| 690 | .irq_ack = octeon_irq_ciu_ack, | 748 | .irq_ack = octeon_irq_ciu_ack, |
| 749 | .irq_mask = octeon_irq_dummy_mask, | ||
| 691 | #ifdef CONFIG_SMP | 750 | #ifdef CONFIG_SMP |
| 692 | .irq_set_affinity = octeon_irq_ciu_set_affinity, | 751 | .irq_set_affinity = octeon_irq_ciu_set_affinity, |
| 693 | .irq_cpu_offline = octeon_irq_cpu_offline_ciu, | 752 | .irq_cpu_offline = octeon_irq_cpu_offline_ciu, |
| @@ -717,6 +776,33 @@ static struct irq_chip octeon_irq_chip_ciu_mbox = { | |||
| 717 | .flags = IRQCHIP_ONOFFLINE_ENABLED, | 776 | .flags = IRQCHIP_ONOFFLINE_ENABLED, |
| 718 | }; | 777 | }; |
| 719 | 778 | ||
| 779 | static struct irq_chip octeon_irq_chip_ciu_gpio_v2 = { | ||
| 780 | .name = "CIU-GPIO", | ||
| 781 | .irq_enable = octeon_irq_ciu_enable_gpio_v2, | ||
| 782 | .irq_disable = octeon_irq_ciu_disable_gpio_v2, | ||
| 783 | .irq_ack = octeon_irq_ciu_gpio_ack, | ||
| 784 | .irq_mask = octeon_irq_ciu_disable_local_v2, | ||
| 785 | .irq_unmask = octeon_irq_ciu_enable_v2, | ||
| 786 | .irq_set_type = octeon_irq_ciu_gpio_set_type, | ||
| 787 | #ifdef CONFIG_SMP | ||
| 788 | .irq_set_affinity = octeon_irq_ciu_set_affinity_v2, | ||
| 789 | #endif | ||
| 790 | .flags = IRQCHIP_SET_TYPE_MASKED, | ||
| 791 | }; | ||
| 792 | |||
| 793 | static struct irq_chip octeon_irq_chip_ciu_gpio = { | ||
| 794 | .name = "CIU-GPIO", | ||
| 795 | .irq_enable = octeon_irq_ciu_enable_gpio, | ||
| 796 | .irq_disable = octeon_irq_ciu_disable_gpio, | ||
| 797 | .irq_mask = octeon_irq_dummy_mask, | ||
| 798 | .irq_ack = octeon_irq_ciu_gpio_ack, | ||
| 799 | .irq_set_type = octeon_irq_ciu_gpio_set_type, | ||
| 800 | #ifdef CONFIG_SMP | ||
| 801 | .irq_set_affinity = octeon_irq_ciu_set_affinity, | ||
| 802 | #endif | ||
| 803 | .flags = IRQCHIP_SET_TYPE_MASKED, | ||
| 804 | }; | ||
| 805 | |||
| 720 | /* | 806 | /* |
| 721 | * Watchdog interrupts are special. They are associated with a single | 807 | * Watchdog interrupts are special. They are associated with a single |
| 722 | * core, so we hardwire the affinity to that core. | 808 | * core, so we hardwire the affinity to that core. |
| @@ -764,6 +850,178 @@ static struct irq_chip octeon_irq_chip_ciu_wd = { | |||
| 764 | .irq_mask = octeon_irq_dummy_mask, | 850 | .irq_mask = octeon_irq_dummy_mask, |
| 765 | }; | 851 | }; |
| 766 | 852 | ||
| 853 | static bool octeon_irq_ciu_is_edge(unsigned int line, unsigned int bit) | ||
| 854 | { | ||
| 855 | bool edge = false; | ||
| 856 | |||
| 857 | if (line == 0) | ||
| 858 | switch (bit) { | ||
| 859 | case 48 ... 49: /* GMX DRP */ | ||
| 860 | case 50: /* IPD_DRP */ | ||
| 861 | case 52 ... 55: /* Timers */ | ||
| 862 | case 58: /* MPI */ | ||
| 863 | edge = true; | ||
| 864 | break; | ||
| 865 | default: | ||
| 866 | break; | ||
| 867 | } | ||
| 868 | else /* line == 1 */ | ||
| 869 | switch (bit) { | ||
| 870 | case 47: /* PTP */ | ||
| 871 | edge = true; | ||
| 872 | break; | ||
| 873 | default: | ||
| 874 | break; | ||
| 875 | } | ||
| 876 | return edge; | ||
| 877 | } | ||
| 878 | |||
| 879 | struct octeon_irq_gpio_domain_data { | ||
| 880 | unsigned int base_hwirq; | ||
| 881 | }; | ||
| 882 | |||
| 883 | static int octeon_irq_gpio_xlat(struct irq_domain *d, | ||
| 884 | struct device_node *node, | ||
| 885 | const u32 *intspec, | ||
| 886 | unsigned int intsize, | ||
| 887 | unsigned long *out_hwirq, | ||
| 888 | unsigned int *out_type) | ||
| 889 | { | ||
| 890 | unsigned int type; | ||
| 891 | unsigned int pin; | ||
| 892 | unsigned int trigger; | ||
| 893 | struct octeon_irq_gpio_domain_data *gpiod; | ||
| 894 | |||
| 895 | if (d->of_node != node) | ||
| 896 | return -EINVAL; | ||
| 897 | |||
| 898 | if (intsize < 2) | ||
| 899 | return -EINVAL; | ||
| 900 | |||
| 901 | pin = intspec[0]; | ||
| 902 | if (pin >= 16) | ||
| 903 | return -EINVAL; | ||
| 904 | |||
| 905 | trigger = intspec[1]; | ||
| 906 | |||
| 907 | switch (trigger) { | ||
| 908 | case 1: | ||
| 909 | type = IRQ_TYPE_EDGE_RISING; | ||
| 910 | break; | ||
| 911 | case 2: | ||
| 912 | type = IRQ_TYPE_EDGE_FALLING; | ||
| 913 | break; | ||
| 914 | case 4: | ||
| 915 | type = IRQ_TYPE_LEVEL_HIGH; | ||
| 916 | break; | ||
| 917 | case 8: | ||
| 918 | type = IRQ_TYPE_LEVEL_LOW; | ||
| 919 | break; | ||
| 920 | default: | ||
| 921 | pr_err("Error: (%s) Invalid irq trigger specification: %x\n", | ||
| 922 | node->name, | ||
| 923 | trigger); | ||
| 924 | type = IRQ_TYPE_LEVEL_LOW; | ||
| 925 | break; | ||
| 926 | } | ||
| 927 | *out_type = type; | ||
| 928 | gpiod = d->host_data; | ||
| 929 | *out_hwirq = gpiod->base_hwirq + pin; | ||
| 930 | |||
| 931 | return 0; | ||
| 932 | } | ||
| 933 | |||
| 934 | static int octeon_irq_ciu_xlat(struct irq_domain *d, | ||
| 935 | struct device_node *node, | ||
| 936 | const u32 *intspec, | ||
| 937 | unsigned int intsize, | ||
| 938 | unsigned long *out_hwirq, | ||
| 939 | unsigned int *out_type) | ||
| 940 | { | ||
| 941 | unsigned int ciu, bit; | ||
| 942 | |||
| 943 | ciu = intspec[0]; | ||
| 944 | bit = intspec[1]; | ||
| 945 | |||
| 946 | if (ciu > 1 || bit > 63) | ||
| 947 | return -EINVAL; | ||
| 948 | |||
| 949 | /* These are the GPIO lines */ | ||
| 950 | if (ciu == 0 && bit >= 16 && bit < 32) | ||
| 951 | return -EINVAL; | ||
| 952 | |||
| 953 | *out_hwirq = (ciu << 6) | bit; | ||
| 954 | *out_type = 0; | ||
| 955 | |||
| 956 | return 0; | ||
| 957 | } | ||
| 958 | |||
| 959 | static struct irq_chip *octeon_irq_ciu_chip; | ||
| 960 | static struct irq_chip *octeon_irq_gpio_chip; | ||
| 961 | |||
| 962 | static bool octeon_irq_virq_in_range(unsigned int virq) | ||
| 963 | { | ||
| 964 | /* We cannot let it overflow the mapping array. */ | ||
| 965 | if (virq < (1ul << 8 * sizeof(octeon_irq_ciu_to_irq[0][0]))) | ||
| 966 | return true; | ||
| 967 | |||
| 968 | WARN_ONCE(true, "virq out of range %u.\n", virq); | ||
| 969 | return false; | ||
| 970 | } | ||
| 971 | |||
| 972 | static int octeon_irq_ciu_map(struct irq_domain *d, | ||
| 973 | unsigned int virq, irq_hw_number_t hw) | ||
| 974 | { | ||
| 975 | unsigned int line = hw >> 6; | ||
| 976 | unsigned int bit = hw & 63; | ||
| 977 | |||
| 978 | if (!octeon_irq_virq_in_range(virq)) | ||
| 979 | return -EINVAL; | ||
| 980 | |||
| 981 | if (line > 1 || octeon_irq_ciu_to_irq[line][bit] != 0) | ||
| 982 | return -EINVAL; | ||
| 983 | |||
| 984 | if (octeon_irq_ciu_is_edge(line, bit)) | ||
| 985 | octeon_irq_set_ciu_mapping(virq, line, bit, | ||
| 986 | octeon_irq_ciu_chip, | ||
| 987 | handle_edge_irq); | ||
| 988 | else | ||
| 989 | octeon_irq_set_ciu_mapping(virq, line, bit, | ||
| 990 | octeon_irq_ciu_chip, | ||
| 991 | handle_level_irq); | ||
| 992 | |||
| 993 | return 0; | ||
| 994 | } | ||
| 995 | |||
| 996 | static int octeon_irq_gpio_map(struct irq_domain *d, | ||
| 997 | unsigned int virq, irq_hw_number_t hw) | ||
| 998 | { | ||
| 999 | unsigned int line = hw >> 6; | ||
| 1000 | unsigned int bit = hw & 63; | ||
| 1001 | |||
| 1002 | if (!octeon_irq_virq_in_range(virq)) | ||
| 1003 | return -EINVAL; | ||
| 1004 | |||
| 1005 | if (line > 1 || octeon_irq_ciu_to_irq[line][bit] != 0) | ||
| 1006 | return -EINVAL; | ||
| 1007 | |||
| 1008 | octeon_irq_set_ciu_mapping(virq, line, bit, | ||
| 1009 | octeon_irq_gpio_chip, | ||
| 1010 | octeon_irq_handle_gpio); | ||
| 1011 | |||
| 1012 | return 0; | ||
| 1013 | } | ||
| 1014 | |||
| 1015 | static struct irq_domain_ops octeon_irq_domain_ciu_ops = { | ||
| 1016 | .map = octeon_irq_ciu_map, | ||
| 1017 | .xlate = octeon_irq_ciu_xlat, | ||
| 1018 | }; | ||
| 1019 | |||
| 1020 | static struct irq_domain_ops octeon_irq_domain_gpio_ops = { | ||
| 1021 | .map = octeon_irq_gpio_map, | ||
| 1022 | .xlate = octeon_irq_gpio_xlat, | ||
| 1023 | }; | ||
| 1024 | |||
| 767 | static void octeon_irq_ip2_v1(void) | 1025 | static void octeon_irq_ip2_v1(void) |
| 768 | { | 1026 | { |
| 769 | const unsigned long core_id = cvmx_get_core_num(); | 1027 | const unsigned long core_id = cvmx_get_core_num(); |
| @@ -887,9 +1145,10 @@ static void __init octeon_irq_init_ciu(void) | |||
| 887 | { | 1145 | { |
| 888 | unsigned int i; | 1146 | unsigned int i; |
| 889 | struct irq_chip *chip; | 1147 | struct irq_chip *chip; |
| 890 | struct irq_chip *chip_edge; | ||
| 891 | struct irq_chip *chip_mbox; | 1148 | struct irq_chip *chip_mbox; |
| 892 | struct irq_chip *chip_wd; | 1149 | struct irq_chip *chip_wd; |
| 1150 | struct device_node *gpio_node; | ||
| 1151 | struct device_node *ciu_node; | ||
| 893 | 1152 | ||
| 894 | octeon_irq_init_ciu_percpu(); | 1153 | octeon_irq_init_ciu_percpu(); |
| 895 | octeon_irq_setup_secondary = octeon_irq_setup_secondary_ciu; | 1154 | octeon_irq_setup_secondary = octeon_irq_setup_secondary_ciu; |
| @@ -901,17 +1160,18 @@ static void __init octeon_irq_init_ciu(void) | |||
| 901 | octeon_irq_ip2 = octeon_irq_ip2_v2; | 1160 | octeon_irq_ip2 = octeon_irq_ip2_v2; |
| 902 | octeon_irq_ip3 = octeon_irq_ip3_v2; | 1161 | octeon_irq_ip3 = octeon_irq_ip3_v2; |
| 903 | chip = &octeon_irq_chip_ciu_v2; | 1162 | chip = &octeon_irq_chip_ciu_v2; |
| 904 | chip_edge = &octeon_irq_chip_ciu_edge_v2; | ||
| 905 | chip_mbox = &octeon_irq_chip_ciu_mbox_v2; | 1163 | chip_mbox = &octeon_irq_chip_ciu_mbox_v2; |
| 906 | chip_wd = &octeon_irq_chip_ciu_wd_v2; | 1164 | chip_wd = &octeon_irq_chip_ciu_wd_v2; |
| 1165 | octeon_irq_gpio_chip = &octeon_irq_chip_ciu_gpio_v2; | ||
| 907 | } else { | 1166 | } else { |
| 908 | octeon_irq_ip2 = octeon_irq_ip2_v1; | 1167 | octeon_irq_ip2 = octeon_irq_ip2_v1; |
| 909 | octeon_irq_ip3 = octeon_irq_ip3_v1; | 1168 | octeon_irq_ip3 = octeon_irq_ip3_v1; |
| 910 | chip = &octeon_irq_chip_ciu; | 1169 | chip = &octeon_irq_chip_ciu; |
| 911 | chip_edge = &octeon_irq_chip_ciu_edge; | ||
| 912 | chip_mbox = &octeon_irq_chip_ciu_mbox; | 1170 | chip_mbox = &octeon_irq_chip_ciu_mbox; |
| 913 | chip_wd = &octeon_irq_chip_ciu_wd; | 1171 | chip_wd = &octeon_irq_chip_ciu_wd; |
| 1172 | octeon_irq_gpio_chip = &octeon_irq_chip_ciu_gpio; | ||
| 914 | } | 1173 | } |
| 1174 | octeon_irq_ciu_chip = chip; | ||
| 915 | octeon_irq_ip4 = octeon_irq_ip4_mask; | 1175 | octeon_irq_ip4 = octeon_irq_ip4_mask; |
| 916 | 1176 | ||
| 917 | /* Mips internal */ | 1177 | /* Mips internal */ |
| @@ -920,80 +1180,49 @@ static void __init octeon_irq_init_ciu(void) | |||
| 920 | /* CIU_0 */ | 1180 | /* CIU_0 */ |
| 921 | for (i = 0; i < 16; i++) | 1181 | for (i = 0; i < 16; i++) |
| 922 | octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WORKQ0, 0, i + 0, chip, handle_level_irq); | 1182 | octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WORKQ0, 0, i + 0, chip, handle_level_irq); |
| 923 | for (i = 0; i < 16; i++) | ||
| 924 | octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_GPIO0, 0, i + 16, chip, handle_level_irq); | ||
| 925 | 1183 | ||
| 926 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX0, 0, 32, chip_mbox, handle_percpu_irq); | 1184 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX0, 0, 32, chip_mbox, handle_percpu_irq); |
| 927 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX1, 0, 33, chip_mbox, handle_percpu_irq); | 1185 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX1, 0, 33, chip_mbox, handle_percpu_irq); |
| 928 | 1186 | ||
| 929 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_UART0, 0, 34, chip, handle_level_irq); | ||
| 930 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_UART1, 0, 35, chip, handle_level_irq); | ||
| 931 | |||
| 932 | for (i = 0; i < 4; i++) | 1187 | for (i = 0; i < 4; i++) |
| 933 | octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_INT0, 0, i + 36, chip, handle_level_irq); | 1188 | octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_INT0, 0, i + 36, chip, handle_level_irq); |
| 934 | for (i = 0; i < 4; i++) | 1189 | for (i = 0; i < 4; i++) |
| 935 | octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_MSI0, 0, i + 40, chip, handle_level_irq); | 1190 | octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_MSI0, 0, i + 40, chip, handle_level_irq); |
| 936 | 1191 | ||
| 937 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_TWSI, 0, 45, chip, handle_level_irq); | ||
| 938 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_RML, 0, 46, chip, handle_level_irq); | 1192 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_RML, 0, 46, chip, handle_level_irq); |
| 939 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_TRACE0, 0, 47, chip, handle_level_irq); | ||
| 940 | |||
| 941 | for (i = 0; i < 2; i++) | ||
| 942 | octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_GMX_DRP0, 0, i + 48, chip_edge, handle_edge_irq); | ||
| 943 | |||
| 944 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_IPD_DRP, 0, 50, chip_edge, handle_edge_irq); | ||
| 945 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_KEY_ZERO, 0, 51, chip_edge, handle_edge_irq); | ||
| 946 | |||
| 947 | for (i = 0; i < 4; i++) | 1193 | for (i = 0; i < 4; i++) |
| 948 | octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_TIMER0, 0, i + 52, chip_edge, handle_edge_irq); | 1194 | octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_TIMER0, 0, i + 52, chip, handle_edge_irq); |
| 949 | 1195 | ||
| 950 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB0, 0, 56, chip, handle_level_irq); | 1196 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB0, 0, 56, chip, handle_level_irq); |
| 951 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_PCM, 0, 57, chip, handle_level_irq); | ||
| 952 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_MPI, 0, 58, chip, handle_level_irq); | ||
| 953 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_TWSI2, 0, 59, chip, handle_level_irq); | ||
| 954 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_POWIQ, 0, 60, chip, handle_level_irq); | ||
| 955 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_IPDPPTHR, 0, 61, chip, handle_level_irq); | ||
| 956 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_MII0, 0, 62, chip, handle_level_irq); | ||
| 957 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_BOOTDMA, 0, 63, chip, handle_level_irq); | 1197 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_BOOTDMA, 0, 63, chip, handle_level_irq); |
| 958 | 1198 | ||
| 959 | /* CIU_1 */ | 1199 | /* CIU_1 */ |
| 960 | for (i = 0; i < 16; i++) | 1200 | for (i = 0; i < 16; i++) |
| 961 | octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WDOG0, 1, i + 0, chip_wd, handle_level_irq); | 1201 | octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WDOG0, 1, i + 0, chip_wd, handle_level_irq); |
| 962 | 1202 | ||
| 963 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_UART2, 1, 16, chip, handle_level_irq); | ||
| 964 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB1, 1, 17, chip, handle_level_irq); | 1203 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB1, 1, 17, chip, handle_level_irq); |
| 965 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_MII1, 1, 18, chip, handle_level_irq); | 1204 | |
| 966 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_NAND, 1, 19, chip, handle_level_irq); | 1205 | gpio_node = of_find_compatible_node(NULL, NULL, "cavium,octeon-3860-gpio"); |
| 967 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_MIO, 1, 20, chip, handle_level_irq); | 1206 | if (gpio_node) { |
| 968 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_IOB, 1, 21, chip, handle_level_irq); | 1207 | struct octeon_irq_gpio_domain_data *gpiod; |
| 969 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_FPA, 1, 22, chip, handle_level_irq); | 1208 | |
| 970 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_POW, 1, 23, chip, handle_level_irq); | 1209 | gpiod = kzalloc(sizeof(*gpiod), GFP_KERNEL); |
| 971 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_L2C, 1, 24, chip, handle_level_irq); | 1210 | if (gpiod) { |
| 972 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_IPD, 1, 25, chip, handle_level_irq); | 1211 | /* gpio domain host_data is the base hwirq number. */ |
| 973 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_PIP, 1, 26, chip, handle_level_irq); | 1212 | gpiod->base_hwirq = 16; |
| 974 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_PKO, 1, 27, chip, handle_level_irq); | 1213 | irq_domain_add_linear(gpio_node, 16, &octeon_irq_domain_gpio_ops, gpiod); |
| 975 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_ZIP, 1, 28, chip, handle_level_irq); | 1214 | of_node_put(gpio_node); |
| 976 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_TIM, 1, 29, chip, handle_level_irq); | 1215 | } else |
| 977 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_RAD, 1, 30, chip, handle_level_irq); | 1216 | pr_warn("Cannot allocate memory for GPIO irq_domain.\n"); |
| 978 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_KEY, 1, 31, chip, handle_level_irq); | 1217 | } else |
| 979 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_DFA, 1, 32, chip, handle_level_irq); | 1218 | pr_warn("Cannot find device node for cavium,octeon-3860-gpio.\n"); |
| 980 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_USBCTL, 1, 33, chip, handle_level_irq); | 1219 | |
| 981 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_SLI, 1, 34, chip, handle_level_irq); | 1220 | ciu_node = of_find_compatible_node(NULL, NULL, "cavium,octeon-3860-ciu"); |
| 982 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_DPI, 1, 35, chip, handle_level_irq); | 1221 | if (ciu_node) { |
| 983 | 1222 | irq_domain_add_tree(ciu_node, &octeon_irq_domain_ciu_ops, NULL); | |
| 984 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_AGX0, 1, 36, chip, handle_level_irq); | 1223 | of_node_put(ciu_node); |
| 985 | 1224 | } else | |
| 986 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_AGL, 1, 46, chip, handle_level_irq); | 1225 | pr_warn("Cannot find device node for cavium,octeon-3860-ciu.\n"); |
| 987 | |||
| 988 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_PTP, 1, 47, chip_edge, handle_edge_irq); | ||
| 989 | |||
| 990 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_PEM0, 1, 48, chip, handle_level_irq); | ||
| 991 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_PEM1, 1, 49, chip, handle_level_irq); | ||
| 992 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_SRIO0, 1, 50, chip, handle_level_irq); | ||
| 993 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_SRIO1, 1, 51, chip, handle_level_irq); | ||
| 994 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_LMC0, 1, 52, chip, handle_level_irq); | ||
| 995 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_DFM, 1, 56, chip, handle_level_irq); | ||
| 996 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_RST, 1, 63, chip, handle_level_irq); | ||
| 997 | 1226 | ||
| 998 | /* Enable the CIU lines */ | 1227 | /* Enable the CIU lines */ |
| 999 | set_c0_status(STATUSF_IP3 | STATUSF_IP2); | 1228 | set_c0_status(STATUSF_IP3 | STATUSF_IP2); |
diff --git a/arch/mips/cavium-octeon/octeon-memcpy.S b/arch/mips/cavium-octeon/octeon-memcpy.S index 88e0cddca205..db478dbb9c7b 100644 --- a/arch/mips/cavium-octeon/octeon-memcpy.S +++ b/arch/mips/cavium-octeon/octeon-memcpy.S | |||
| @@ -164,6 +164,14 @@ | |||
| 164 | .set noat | 164 | .set noat |
| 165 | 165 | ||
| 166 | /* | 166 | /* |
| 167 | * t7 is used as a flag to note inatomic mode. | ||
| 168 | */ | ||
| 169 | LEAF(__copy_user_inatomic) | ||
| 170 | b __copy_user_common | ||
| 171 | li t7, 1 | ||
| 172 | END(__copy_user_inatomic) | ||
| 173 | |||
| 174 | /* | ||
| 167 | * A combined memcpy/__copy_user | 175 | * A combined memcpy/__copy_user |
| 168 | * __copy_user sets len to 0 for success; else to an upper bound of | 176 | * __copy_user sets len to 0 for success; else to an upper bound of |
| 169 | * the number of uncopied bytes. | 177 | * the number of uncopied bytes. |
| @@ -174,6 +182,8 @@ LEAF(memcpy) /* a0=dst a1=src a2=len */ | |||
| 174 | move v0, dst /* return value */ | 182 | move v0, dst /* return value */ |
| 175 | __memcpy: | 183 | __memcpy: |
| 176 | FEXPORT(__copy_user) | 184 | FEXPORT(__copy_user) |
| 185 | li t7, 0 /* not inatomic */ | ||
| 186 | __copy_user_common: | ||
| 177 | /* | 187 | /* |
| 178 | * Note: dst & src may be unaligned, len may be 0 | 188 | * Note: dst & src may be unaligned, len may be 0 |
| 179 | * Temps | 189 | * Temps |
| @@ -412,7 +422,6 @@ l_exc_copy: | |||
| 412 | * Assumes src < THREAD_BUADDR($28) | 422 | * Assumes src < THREAD_BUADDR($28) |
| 413 | */ | 423 | */ |
| 414 | LOAD t0, TI_TASK($28) | 424 | LOAD t0, TI_TASK($28) |
| 415 | nop | ||
| 416 | LOAD t0, THREAD_BUADDR(t0) | 425 | LOAD t0, THREAD_BUADDR(t0) |
| 417 | 1: | 426 | 1: |
| 418 | EXC( lb t1, 0(src), l_exc) | 427 | EXC( lb t1, 0(src), l_exc) |
| @@ -422,10 +431,9 @@ EXC( lb t1, 0(src), l_exc) | |||
| 422 | ADD dst, dst, 1 | 431 | ADD dst, dst, 1 |
| 423 | l_exc: | 432 | l_exc: |
| 424 | LOAD t0, TI_TASK($28) | 433 | LOAD t0, TI_TASK($28) |
| 425 | nop | ||
| 426 | LOAD t0, THREAD_BUADDR(t0) # t0 is just past last good address | 434 | LOAD t0, THREAD_BUADDR(t0) # t0 is just past last good address |
| 427 | nop | ||
| 428 | SUB len, AT, t0 # len number of uncopied bytes | 435 | SUB len, AT, t0 # len number of uncopied bytes |
| 436 | bnez t7, 2f /* Skip the zeroing out part if inatomic */ | ||
| 429 | /* | 437 | /* |
| 430 | * Here's where we rely on src and dst being incremented in tandem, | 438 | * Here's where we rely on src and dst being incremented in tandem, |
| 431 | * See (3) above. | 439 | * See (3) above. |
| @@ -443,7 +451,7 @@ l_exc: | |||
| 443 | ADD dst, dst, 1 | 451 | ADD dst, dst, 1 |
| 444 | bnez src, 1b | 452 | bnez src, 1b |
| 445 | SUB src, src, 1 | 453 | SUB src, src, 1 |
| 446 | jr ra | 454 | 2: jr ra |
| 447 | nop | 455 | nop |
| 448 | 456 | ||
| 449 | 457 | ||
diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c index cd61d7281d91..0938df10a71c 100644 --- a/arch/mips/cavium-octeon/octeon-platform.c +++ b/arch/mips/cavium-octeon/octeon-platform.c | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * License. See the file "COPYING" in the main directory of this archive | 3 | * License. See the file "COPYING" in the main directory of this archive |
| 4 | * for more details. | 4 | * for more details. |
| 5 | * | 5 | * |
| 6 | * Copyright (C) 2004-2010 Cavium Networks | 6 | * Copyright (C) 2004-2011 Cavium Networks |
| 7 | * Copyright (C) 2008 Wind River Systems | 7 | * Copyright (C) 2008 Wind River Systems |
| 8 | */ | 8 | */ |
| 9 | 9 | ||
| @@ -13,10 +13,16 @@ | |||
| 13 | #include <linux/usb.h> | 13 | #include <linux/usb.h> |
| 14 | #include <linux/dma-mapping.h> | 14 | #include <linux/dma-mapping.h> |
| 15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
| 16 | #include <linux/slab.h> | ||
| 16 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
| 18 | #include <linux/of_platform.h> | ||
| 19 | #include <linux/of_fdt.h> | ||
| 20 | #include <linux/libfdt.h> | ||
| 17 | 21 | ||
| 18 | #include <asm/octeon/octeon.h> | 22 | #include <asm/octeon/octeon.h> |
| 19 | #include <asm/octeon/cvmx-rnm-defs.h> | 23 | #include <asm/octeon/cvmx-rnm-defs.h> |
| 24 | #include <asm/octeon/cvmx-helper.h> | ||
| 25 | #include <asm/octeon/cvmx-helper-board.h> | ||
| 20 | 26 | ||
| 21 | static struct octeon_cf_data octeon_cf_data; | 27 | static struct octeon_cf_data octeon_cf_data; |
| 22 | 28 | ||
| @@ -162,182 +168,6 @@ out: | |||
| 162 | } | 168 | } |
| 163 | device_initcall(octeon_rng_device_init); | 169 | device_initcall(octeon_rng_device_init); |
| 164 | 170 | ||
| 165 | static struct i2c_board_info __initdata octeon_i2c_devices[] = { | ||
| 166 | { | ||
| 167 | I2C_BOARD_INFO("ds1337", 0x68), | ||
| 168 | }, | ||
| 169 | }; | ||
| 170 | |||
| 171 | static int __init octeon_i2c_devices_init(void) | ||
| 172 | { | ||
| 173 | return i2c_register_board_info(0, octeon_i2c_devices, | ||
| 174 | ARRAY_SIZE(octeon_i2c_devices)); | ||
| 175 | } | ||
| 176 | arch_initcall(octeon_i2c_devices_init); | ||
| 177 | |||
| 178 | #define OCTEON_I2C_IO_BASE 0x1180000001000ull | ||
| 179 | #define OCTEON_I2C_IO_UNIT_OFFSET 0x200 | ||
| 180 | |||
| 181 | static struct octeon_i2c_data octeon_i2c_data[2]; | ||
| 182 | |||
| 183 | static int __init octeon_i2c_device_init(void) | ||
| 184 | { | ||
| 185 | struct platform_device *pd; | ||
| 186 | int ret = 0; | ||
| 187 | int port, num_ports; | ||
| 188 | |||
| 189 | struct resource i2c_resources[] = { | ||
| 190 | { | ||
| 191 | .flags = IORESOURCE_MEM, | ||
| 192 | }, { | ||
| 193 | .flags = IORESOURCE_IRQ, | ||
| 194 | } | ||
| 195 | }; | ||
| 196 | |||
| 197 | if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX)) | ||
| 198 | num_ports = 2; | ||
| 199 | else | ||
| 200 | num_ports = 1; | ||
| 201 | |||
| 202 | for (port = 0; port < num_ports; port++) { | ||
| 203 | octeon_i2c_data[port].sys_freq = octeon_get_io_clock_rate(); | ||
| 204 | /*FIXME: should be examined. At the moment is set for 100Khz */ | ||
| 205 | octeon_i2c_data[port].i2c_freq = 100000; | ||
| 206 | |||
| 207 | pd = platform_device_alloc("i2c-octeon", port); | ||
| 208 | if (!pd) { | ||
| 209 | ret = -ENOMEM; | ||
| 210 | goto out; | ||
| 211 | } | ||
| 212 | |||
| 213 | pd->dev.platform_data = octeon_i2c_data + port; | ||
| 214 | |||
| 215 | i2c_resources[0].start = | ||
| 216 | OCTEON_I2C_IO_BASE + (port * OCTEON_I2C_IO_UNIT_OFFSET); | ||
| 217 | i2c_resources[0].end = i2c_resources[0].start + 0x1f; | ||
| 218 | switch (port) { | ||
| 219 | case 0: | ||
| 220 | i2c_resources[1].start = OCTEON_IRQ_TWSI; | ||
| 221 | i2c_resources[1].end = OCTEON_IRQ_TWSI; | ||
| 222 | break; | ||
| 223 | case 1: | ||
| 224 | i2c_resources[1].start = OCTEON_IRQ_TWSI2; | ||
| 225 | i2c_resources[1].end = OCTEON_IRQ_TWSI2; | ||
| 226 | break; | ||
| 227 | default: | ||
| 228 | BUG(); | ||
| 229 | } | ||
| 230 | |||
| 231 | ret = platform_device_add_resources(pd, | ||
| 232 | i2c_resources, | ||
| 233 | ARRAY_SIZE(i2c_resources)); | ||
| 234 | if (ret) | ||
| 235 | goto fail; | ||
| 236 | |||
| 237 | ret = platform_device_add(pd); | ||
| 238 | if (ret) | ||
| 239 | goto fail; | ||
| 240 | } | ||
| 241 | return ret; | ||
| 242 | fail: | ||
| 243 | platform_device_put(pd); | ||
| 244 | out: | ||
| 245 | return ret; | ||
| 246 | } | ||
| 247 | device_initcall(octeon_i2c_device_init); | ||
| 248 | |||
| 249 | /* Octeon SMI/MDIO interface. */ | ||
| 250 | static int __init octeon_mdiobus_device_init(void) | ||
| 251 | { | ||
| 252 | struct platform_device *pd; | ||
| 253 | int ret = 0; | ||
| 254 | |||
| 255 | if (octeon_is_simulation()) | ||
| 256 | return 0; /* No mdio in the simulator. */ | ||
| 257 | |||
| 258 | /* The bus number is the platform_device id. */ | ||
| 259 | pd = platform_device_alloc("mdio-octeon", 0); | ||
| 260 | if (!pd) { | ||
| 261 | ret = -ENOMEM; | ||
| 262 | goto out; | ||
| 263 | } | ||
| 264 | |||
| 265 | ret = platform_device_add(pd); | ||
| 266 | if (ret) | ||
| 267 | goto fail; | ||
| 268 | |||
| 269 | return ret; | ||
| 270 | fail: | ||
| 271 | platform_device_put(pd); | ||
| 272 | |||
| 273 | out: | ||
| 274 | return ret; | ||
| 275 | |||
| 276 | } | ||
| 277 | device_initcall(octeon_mdiobus_device_init); | ||
| 278 | |||
| 279 | /* Octeon mgmt port Ethernet interface. */ | ||
| 280 | static int __init octeon_mgmt_device_init(void) | ||
| 281 | { | ||
| 282 | struct platform_device *pd; | ||
| 283 | int ret = 0; | ||
| 284 | int port, num_ports; | ||
| 285 | |||
| 286 | struct resource mgmt_port_resource = { | ||
| 287 | .flags = IORESOURCE_IRQ, | ||
| 288 | .start = -1, | ||
| 289 | .end = -1 | ||
| 290 | }; | ||
| 291 | |||
| 292 | if (!OCTEON_IS_MODEL(OCTEON_CN56XX) && !OCTEON_IS_MODEL(OCTEON_CN52XX)) | ||
| 293 | return 0; | ||
| 294 | |||
| 295 | if (OCTEON_IS_MODEL(OCTEON_CN56XX)) | ||
| 296 | num_ports = 1; | ||
| 297 | else | ||
| 298 | num_ports = 2; | ||
| 299 | |||
| 300 | for (port = 0; port < num_ports; port++) { | ||
| 301 | pd = platform_device_alloc("octeon_mgmt", port); | ||
| 302 | if (!pd) { | ||
| 303 | ret = -ENOMEM; | ||
| 304 | goto out; | ||
| 305 | } | ||
| 306 | /* No DMA restrictions */ | ||
| 307 | pd->dev.coherent_dma_mask = DMA_BIT_MASK(64); | ||
| 308 | pd->dev.dma_mask = &pd->dev.coherent_dma_mask; | ||
| 309 | |||
| 310 | switch (port) { | ||
| 311 | case 0: | ||
| 312 | mgmt_port_resource.start = OCTEON_IRQ_MII0; | ||
| 313 | break; | ||
| 314 | case 1: | ||
| 315 | mgmt_port_resource.start = OCTEON_IRQ_MII1; | ||
| 316 | break; | ||
| 317 | default: | ||
| 318 | BUG(); | ||
| 319 | } | ||
| 320 | mgmt_port_resource.end = mgmt_port_resource.start; | ||
| 321 | |||
| 322 | ret = platform_device_add_resources(pd, &mgmt_port_resource, 1); | ||
| 323 | |||
| 324 | if (ret) | ||
| 325 | goto fail; | ||
| 326 | |||
| 327 | ret = platform_device_add(pd); | ||
| 328 | if (ret) | ||
| 329 | goto fail; | ||
| 330 | } | ||
| 331 | return ret; | ||
| 332 | fail: | ||
| 333 | platform_device_put(pd); | ||
| 334 | |||
| 335 | out: | ||
| 336 | return ret; | ||
| 337 | |||
| 338 | } | ||
| 339 | device_initcall(octeon_mgmt_device_init); | ||
| 340 | |||
| 341 | #ifdef CONFIG_USB | 171 | #ifdef CONFIG_USB |
| 342 | 172 | ||
| 343 | static int __init octeon_ehci_device_init(void) | 173 | static int __init octeon_ehci_device_init(void) |
| @@ -440,6 +270,521 @@ device_initcall(octeon_ohci_device_init); | |||
| 440 | 270 | ||
| 441 | #endif /* CONFIG_USB */ | 271 | #endif /* CONFIG_USB */ |
| 442 | 272 | ||
| 273 | static struct of_device_id __initdata octeon_ids[] = { | ||
| 274 | { .compatible = "simple-bus", }, | ||
| 275 | { .compatible = "cavium,octeon-6335-uctl", }, | ||
| 276 | { .compatible = "cavium,octeon-3860-bootbus", }, | ||
| 277 | { .compatible = "cavium,mdio-mux", }, | ||
| 278 | { .compatible = "gpio-leds", }, | ||
| 279 | {}, | ||
| 280 | }; | ||
| 281 | |||
| 282 | static bool __init octeon_has_88e1145(void) | ||
| 283 | { | ||
| 284 | return !OCTEON_IS_MODEL(OCTEON_CN52XX) && | ||
| 285 | !OCTEON_IS_MODEL(OCTEON_CN6XXX) && | ||
| 286 | !OCTEON_IS_MODEL(OCTEON_CN56XX); | ||
| 287 | } | ||
| 288 | |||
| 289 | static void __init octeon_fdt_set_phy(int eth, int phy_addr) | ||
| 290 | { | ||
| 291 | const __be32 *phy_handle; | ||
| 292 | const __be32 *alt_phy_handle; | ||
| 293 | const __be32 *reg; | ||
| 294 | u32 phandle; | ||
| 295 | int phy; | ||
| 296 | int alt_phy; | ||
| 297 | const char *p; | ||
| 298 | int current_len; | ||
| 299 | char new_name[20]; | ||
| 300 | |||
| 301 | phy_handle = fdt_getprop(initial_boot_params, eth, "phy-handle", NULL); | ||
| 302 | if (!phy_handle) | ||
| 303 | return; | ||
| 304 | |||
| 305 | phandle = be32_to_cpup(phy_handle); | ||
| 306 | phy = fdt_node_offset_by_phandle(initial_boot_params, phandle); | ||
| 307 | |||
| 308 | alt_phy_handle = fdt_getprop(initial_boot_params, eth, "cavium,alt-phy-handle", NULL); | ||
| 309 | if (alt_phy_handle) { | ||
| 310 | u32 alt_phandle = be32_to_cpup(alt_phy_handle); | ||
| 311 | alt_phy = fdt_node_offset_by_phandle(initial_boot_params, alt_phandle); | ||
| 312 | } else { | ||
| 313 | alt_phy = -1; | ||
| 314 | } | ||
| 315 | |||
| 316 | if (phy_addr < 0 || phy < 0) { | ||
| 317 | /* Delete the PHY things */ | ||
| 318 | fdt_nop_property(initial_boot_params, eth, "phy-handle"); | ||
| 319 | /* This one may fail */ | ||
| 320 | fdt_nop_property(initial_boot_params, eth, "cavium,alt-phy-handle"); | ||
| 321 | if (phy >= 0) | ||
| 322 | fdt_nop_node(initial_boot_params, phy); | ||
| 323 | if (alt_phy >= 0) | ||
| 324 | fdt_nop_node(initial_boot_params, alt_phy); | ||
| 325 | return; | ||
| 326 | } | ||
| 327 | |||
| 328 | if (phy_addr >= 256 && alt_phy > 0) { | ||
| 329 | const struct fdt_property *phy_prop; | ||
| 330 | struct fdt_property *alt_prop; | ||
| 331 | u32 phy_handle_name; | ||
| 332 | |||
| 333 | /* Use the alt phy node instead.*/ | ||
| 334 | phy_prop = fdt_get_property(initial_boot_params, eth, "phy-handle", NULL); | ||
| 335 | phy_handle_name = phy_prop->nameoff; | ||
| 336 | fdt_nop_node(initial_boot_params, phy); | ||
| 337 | fdt_nop_property(initial_boot_params, eth, "phy-handle"); | ||
| 338 | alt_prop = fdt_get_property_w(initial_boot_params, eth, "cavium,alt-phy-handle", NULL); | ||
| 339 | alt_prop->nameoff = phy_handle_name; | ||
| 340 | phy = alt_phy; | ||
| 341 | } | ||
| 342 | |||
| 343 | phy_addr &= 0xff; | ||
| 344 | |||
| 345 | if (octeon_has_88e1145()) { | ||
| 346 | fdt_nop_property(initial_boot_params, phy, "marvell,reg-init"); | ||
| 347 | memset(new_name, 0, sizeof(new_name)); | ||
| 348 | strcpy(new_name, "marvell,88e1145"); | ||
| 349 | p = fdt_getprop(initial_boot_params, phy, "compatible", | ||
| 350 | ¤t_len); | ||
| 351 | if (p && current_len >= strlen(new_name)) | ||
| 352 | fdt_setprop_inplace(initial_boot_params, phy, | ||
| 353 | "compatible", new_name, current_len); | ||
| 354 | } | ||
| 355 | |||
| 356 | reg = fdt_getprop(initial_boot_params, phy, "reg", NULL); | ||
| 357 | if (phy_addr == be32_to_cpup(reg)) | ||
| 358 | return; | ||
| 359 | |||
| 360 | fdt_setprop_inplace_cell(initial_boot_params, phy, "reg", phy_addr); | ||
| 361 | |||
| 362 | snprintf(new_name, sizeof(new_name), "ethernet-phy@%x", phy_addr); | ||
| 363 | |||
| 364 | p = fdt_get_name(initial_boot_params, phy, ¤t_len); | ||
| 365 | if (p && current_len == strlen(new_name)) | ||
| 366 | fdt_set_name(initial_boot_params, phy, new_name); | ||
| 367 | else | ||
| 368 | pr_err("Error: could not rename ethernet phy: <%s>", p); | ||
| 369 | } | ||
| 370 | |||
| 371 | static void __init octeon_fdt_set_mac_addr(int n, u64 *pmac) | ||
| 372 | { | ||
| 373 | u8 new_mac[6]; | ||
| 374 | u64 mac = *pmac; | ||
| 375 | int r; | ||
| 376 | |||
| 377 | new_mac[0] = (mac >> 40) & 0xff; | ||
| 378 | new_mac[1] = (mac >> 32) & 0xff; | ||
| 379 | new_mac[2] = (mac >> 24) & 0xff; | ||
| 380 | new_mac[3] = (mac >> 16) & 0xff; | ||
| 381 | new_mac[4] = (mac >> 8) & 0xff; | ||
| 382 | new_mac[5] = mac & 0xff; | ||
| 383 | |||
| 384 | r = fdt_setprop_inplace(initial_boot_params, n, "local-mac-address", | ||
| 385 | new_mac, sizeof(new_mac)); | ||
| 386 | |||
| 387 | if (r) { | ||
| 388 | pr_err("Setting \"local-mac-address\" failed %d", r); | ||
| 389 | return; | ||
| 390 | } | ||
| 391 | *pmac = mac + 1; | ||
| 392 | } | ||
| 393 | |||
| 394 | static void __init octeon_fdt_rm_ethernet(int node) | ||
| 395 | { | ||
| 396 | const __be32 *phy_handle; | ||
| 397 | |||
| 398 | phy_handle = fdt_getprop(initial_boot_params, node, "phy-handle", NULL); | ||
| 399 | if (phy_handle) { | ||
| 400 | u32 ph = be32_to_cpup(phy_handle); | ||
| 401 | int p = fdt_node_offset_by_phandle(initial_boot_params, ph); | ||
| 402 | if (p >= 0) | ||
| 403 | fdt_nop_node(initial_boot_params, p); | ||
| 404 | } | ||
| 405 | fdt_nop_node(initial_boot_params, node); | ||
| 406 | } | ||
| 407 | |||
| 408 | static void __init octeon_fdt_pip_port(int iface, int i, int p, int max, u64 *pmac) | ||
| 409 | { | ||
| 410 | char name_buffer[20]; | ||
| 411 | int eth; | ||
| 412 | int phy_addr; | ||
| 413 | int ipd_port; | ||
| 414 | |||
| 415 | snprintf(name_buffer, sizeof(name_buffer), "ethernet@%x", p); | ||
| 416 | eth = fdt_subnode_offset(initial_boot_params, iface, name_buffer); | ||
| 417 | if (eth < 0) | ||
| 418 | return; | ||
| 419 | if (p > max) { | ||
| 420 | pr_debug("Deleting port %x:%x\n", i, p); | ||
| 421 | octeon_fdt_rm_ethernet(eth); | ||
| 422 | return; | ||
| 423 | } | ||
| 424 | if (OCTEON_IS_MODEL(OCTEON_CN68XX)) | ||
| 425 | ipd_port = (0x100 * i) + (0x10 * p) + 0x800; | ||
| 426 | else | ||
| 427 | ipd_port = 16 * i + p; | ||
| 428 | |||
| 429 | phy_addr = cvmx_helper_board_get_mii_address(ipd_port); | ||
| 430 | octeon_fdt_set_phy(eth, phy_addr); | ||
| 431 | octeon_fdt_set_mac_addr(eth, pmac); | ||
| 432 | } | ||
| 433 | |||
| 434 | static void __init octeon_fdt_pip_iface(int pip, int idx, u64 *pmac) | ||
| 435 | { | ||
| 436 | char name_buffer[20]; | ||
| 437 | int iface; | ||
| 438 | int p; | ||
| 439 | int count; | ||
| 440 | |||
| 441 | count = cvmx_helper_interface_enumerate(idx); | ||
| 442 | |||
| 443 | snprintf(name_buffer, sizeof(name_buffer), "interface@%d", idx); | ||
| 444 | iface = fdt_subnode_offset(initial_boot_params, pip, name_buffer); | ||
| 445 | if (iface < 0) | ||
| 446 | return; | ||
| 447 | |||
| 448 | for (p = 0; p < 16; p++) | ||
| 449 | octeon_fdt_pip_port(iface, idx, p, count - 1, pmac); | ||
| 450 | } | ||
| 451 | |||
| 452 | int __init octeon_prune_device_tree(void) | ||
| 453 | { | ||
| 454 | int i, max_port, uart_mask; | ||
| 455 | const char *pip_path; | ||
| 456 | const char *alias_prop; | ||
| 457 | char name_buffer[20]; | ||
| 458 | int aliases; | ||
| 459 | u64 mac_addr_base; | ||
| 460 | |||
| 461 | if (fdt_check_header(initial_boot_params)) | ||
| 462 | panic("Corrupt Device Tree."); | ||
| 463 | |||
| 464 | aliases = fdt_path_offset(initial_boot_params, "/aliases"); | ||
| 465 | if (aliases < 0) { | ||
| 466 | pr_err("Error: No /aliases node in device tree."); | ||
| 467 | return -EINVAL; | ||
| 468 | } | ||
| 469 | |||
| 470 | |||
| 471 | mac_addr_base = | ||
| 472 | ((octeon_bootinfo->mac_addr_base[0] & 0xffull)) << 40 | | ||
| 473 | ((octeon_bootinfo->mac_addr_base[1] & 0xffull)) << 32 | | ||
| 474 | ((octeon_bootinfo->mac_addr_base[2] & 0xffull)) << 24 | | ||
| 475 | ((octeon_bootinfo->mac_addr_base[3] & 0xffull)) << 16 | | ||
| 476 | ((octeon_bootinfo->mac_addr_base[4] & 0xffull)) << 8 | | ||
| 477 | (octeon_bootinfo->mac_addr_base[5] & 0xffull); | ||
| 478 | |||
| 479 | if (OCTEON_IS_MODEL(OCTEON_CN52XX) || OCTEON_IS_MODEL(OCTEON_CN63XX)) | ||
| 480 | max_port = 2; | ||
| 481 | else if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN68XX)) | ||
| 482 | max_port = 1; | ||
| 483 | else | ||
| 484 | max_port = 0; | ||
| 485 | |||
| 486 | if (octeon_bootinfo->board_type == CVMX_BOARD_TYPE_NIC10E) | ||
| 487 | max_port = 0; | ||
| 488 | |||
| 489 | for (i = 0; i < 2; i++) { | ||
| 490 | int mgmt; | ||
| 491 | snprintf(name_buffer, sizeof(name_buffer), | ||
| 492 | "mix%d", i); | ||
| 493 | alias_prop = fdt_getprop(initial_boot_params, aliases, | ||
| 494 | name_buffer, NULL); | ||
| 495 | if (alias_prop) { | ||
| 496 | mgmt = fdt_path_offset(initial_boot_params, alias_prop); | ||
| 497 | if (mgmt < 0) | ||
| 498 | continue; | ||
| 499 | if (i >= max_port) { | ||
| 500 | pr_debug("Deleting mix%d\n", i); | ||
| 501 | octeon_fdt_rm_ethernet(mgmt); | ||
| 502 | fdt_nop_property(initial_boot_params, aliases, | ||
| 503 | name_buffer); | ||
| 504 | } else { | ||
| 505 | int phy_addr = cvmx_helper_board_get_mii_address(CVMX_HELPER_BOARD_MGMT_IPD_PORT + i); | ||
| 506 | octeon_fdt_set_phy(mgmt, phy_addr); | ||
| 507 | octeon_fdt_set_mac_addr(mgmt, &mac_addr_base); | ||
| 508 | } | ||
| 509 | } | ||
| 510 | } | ||
| 511 | |||
| 512 | pip_path = fdt_getprop(initial_boot_params, aliases, "pip", NULL); | ||
| 513 | if (pip_path) { | ||
| 514 | int pip = fdt_path_offset(initial_boot_params, pip_path); | ||
| 515 | if (pip >= 0) | ||
| 516 | for (i = 0; i <= 4; i++) | ||
| 517 | octeon_fdt_pip_iface(pip, i, &mac_addr_base); | ||
| 518 | } | ||
| 519 | |||
| 520 | /* I2C */ | ||
| 521 | if (OCTEON_IS_MODEL(OCTEON_CN52XX) || | ||
| 522 | OCTEON_IS_MODEL(OCTEON_CN63XX) || | ||
| 523 | OCTEON_IS_MODEL(OCTEON_CN68XX) || | ||
| 524 | OCTEON_IS_MODEL(OCTEON_CN56XX)) | ||
| 525 | max_port = 2; | ||
| 526 | else | ||
| 527 | max_port = 1; | ||
| 528 | |||
| 529 | for (i = 0; i < 2; i++) { | ||
| 530 | int i2c; | ||
| 531 | snprintf(name_buffer, sizeof(name_buffer), | ||
| 532 | "twsi%d", i); | ||
| 533 | alias_prop = fdt_getprop(initial_boot_params, aliases, | ||
| 534 | name_buffer, NULL); | ||
| 535 | |||
| 536 | if (alias_prop) { | ||
| 537 | i2c = fdt_path_offset(initial_boot_params, alias_prop); | ||
| 538 | if (i2c < 0) | ||
| 539 | continue; | ||
| 540 | if (i >= max_port) { | ||
| 541 | pr_debug("Deleting twsi%d\n", i); | ||
| 542 | fdt_nop_node(initial_boot_params, i2c); | ||
| 543 | fdt_nop_property(initial_boot_params, aliases, | ||
| 544 | name_buffer); | ||
| 545 | } | ||
| 546 | } | ||
| 547 | } | ||
| 548 | |||
| 549 | /* SMI/MDIO */ | ||
| 550 | if (OCTEON_IS_MODEL(OCTEON_CN68XX)) | ||
| 551 | max_port = 4; | ||
| 552 | else if (OCTEON_IS_MODEL(OCTEON_CN52XX) || | ||
| 553 | OCTEON_IS_MODEL(OCTEON_CN63XX) || | ||
| 554 | OCTEON_IS_MODEL(OCTEON_CN56XX)) | ||
| 555 | max_port = 2; | ||
| 556 | else | ||
| 557 | max_port = 1; | ||
| 558 | |||
| 559 | for (i = 0; i < 2; i++) { | ||
| 560 | int i2c; | ||
| 561 | snprintf(name_buffer, sizeof(name_buffer), | ||
| 562 | "smi%d", i); | ||
| 563 | alias_prop = fdt_getprop(initial_boot_params, aliases, | ||
| 564 | name_buffer, NULL); | ||
| 565 | |||
| 566 | if (alias_prop) { | ||
| 567 | i2c = fdt_path_offset(initial_boot_params, alias_prop); | ||
| 568 | if (i2c < 0) | ||
| 569 | continue; | ||
| 570 | if (i >= max_port) { | ||
| 571 | pr_debug("Deleting smi%d\n", i); | ||
| 572 | fdt_nop_node(initial_boot_params, i2c); | ||
| 573 | fdt_nop_property(initial_boot_params, aliases, | ||
| 574 | name_buffer); | ||
| 575 | } | ||
| 576 | } | ||
| 577 | } | ||
| 578 | |||
| 579 | /* Serial */ | ||
| 580 | uart_mask = 3; | ||
| 581 | |||
| 582 | /* Right now CN52XX is the only chip with a third uart */ | ||
| 583 | if (OCTEON_IS_MODEL(OCTEON_CN52XX)) | ||
| 584 | uart_mask |= 4; /* uart2 */ | ||
| 585 | |||
| 586 | for (i = 0; i < 3; i++) { | ||
| 587 | int uart; | ||
| 588 | snprintf(name_buffer, sizeof(name_buffer), | ||
| 589 | "uart%d", i); | ||
| 590 | alias_prop = fdt_getprop(initial_boot_params, aliases, | ||
| 591 | name_buffer, NULL); | ||
| 592 | |||
| 593 | if (alias_prop) { | ||
| 594 | uart = fdt_path_offset(initial_boot_params, alias_prop); | ||
| 595 | if (uart_mask & (1 << i)) | ||
| 596 | continue; | ||
| 597 | pr_debug("Deleting uart%d\n", i); | ||
| 598 | fdt_nop_node(initial_boot_params, uart); | ||
| 599 | fdt_nop_property(initial_boot_params, aliases, | ||
| 600 | name_buffer); | ||
| 601 | } | ||
| 602 | } | ||
| 603 | |||
| 604 | /* Compact Flash */ | ||
| 605 | alias_prop = fdt_getprop(initial_boot_params, aliases, | ||
| 606 | "cf0", NULL); | ||
| 607 | if (alias_prop) { | ||
| 608 | union cvmx_mio_boot_reg_cfgx mio_boot_reg_cfg; | ||
| 609 | unsigned long base_ptr, region_base, region_size; | ||
| 610 | unsigned long region1_base = 0; | ||
| 611 | unsigned long region1_size = 0; | ||
| 612 | int cs, bootbus; | ||
| 613 | bool is_16bit = false; | ||
| 614 | bool is_true_ide = false; | ||
| 615 | __be32 new_reg[6]; | ||
| 616 | __be32 *ranges; | ||
| 617 | int len; | ||
| 618 | |||
| 619 | int cf = fdt_path_offset(initial_boot_params, alias_prop); | ||
| 620 | base_ptr = 0; | ||
| 621 | if (octeon_bootinfo->major_version == 1 | ||
| 622 | && octeon_bootinfo->minor_version >= 1) { | ||
| 623 | if (octeon_bootinfo->compact_flash_common_base_addr) | ||
| 624 | base_ptr = octeon_bootinfo->compact_flash_common_base_addr; | ||
| 625 | } else { | ||
| 626 | base_ptr = 0x1d000800; | ||
| 627 | } | ||
| 628 | |||
| 629 | if (!base_ptr) | ||
| 630 | goto no_cf; | ||
| 631 | |||
| 632 | /* Find CS0 region. */ | ||
| 633 | for (cs = 0; cs < 8; cs++) { | ||
| 634 | mio_boot_reg_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(cs)); | ||
| 635 | region_base = mio_boot_reg_cfg.s.base << 16; | ||
| 636 | region_size = (mio_boot_reg_cfg.s.size + 1) << 16; | ||
| 637 | if (mio_boot_reg_cfg.s.en && base_ptr >= region_base | ||
| 638 | && base_ptr < region_base + region_size) { | ||
| 639 | is_16bit = mio_boot_reg_cfg.s.width; | ||
| 640 | break; | ||
| 641 | } | ||
| 642 | } | ||
| 643 | if (cs >= 7) { | ||
| 644 | /* cs and cs + 1 are CS0 and CS1, both must be less than 8. */ | ||
| 645 | goto no_cf; | ||
| 646 | } | ||
| 647 | |||
| 648 | if (!(base_ptr & 0xfffful)) { | ||
| 649 | /* | ||
| 650 | * Boot loader signals availability of DMA (true_ide | ||
| 651 | * mode) by setting low order bits of base_ptr to | ||
| 652 | * zero. | ||
| 653 | */ | ||
| 654 | |||
| 655 | /* Asume that CS1 immediately follows. */ | ||
| 656 | mio_boot_reg_cfg.u64 = | ||
| 657 | cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(cs + 1)); | ||
| 658 | region1_base = mio_boot_reg_cfg.s.base << 16; | ||
| 659 | region1_size = (mio_boot_reg_cfg.s.size + 1) << 16; | ||
| 660 | if (!mio_boot_reg_cfg.s.en) | ||
| 661 | goto no_cf; | ||
| 662 | is_true_ide = true; | ||
| 663 | |||
| 664 | } else { | ||
| 665 | fdt_nop_property(initial_boot_params, cf, "cavium,true-ide"); | ||
| 666 | fdt_nop_property(initial_boot_params, cf, "cavium,dma-engine-handle"); | ||
| 667 | if (!is_16bit) { | ||
| 668 | __be32 width = cpu_to_be32(8); | ||
| 669 | fdt_setprop_inplace(initial_boot_params, cf, | ||
| 670 | "cavium,bus-width", &width, sizeof(width)); | ||
| 671 | } | ||
| 672 | } | ||
| 673 | new_reg[0] = cpu_to_be32(cs); | ||
| 674 | new_reg[1] = cpu_to_be32(0); | ||
| 675 | new_reg[2] = cpu_to_be32(0x10000); | ||
| 676 | new_reg[3] = cpu_to_be32(cs + 1); | ||
| 677 | new_reg[4] = cpu_to_be32(0); | ||
| 678 | new_reg[5] = cpu_to_be32(0x10000); | ||
| 679 | fdt_setprop_inplace(initial_boot_params, cf, | ||
| 680 | "reg", new_reg, sizeof(new_reg)); | ||
| 681 | |||
| 682 | bootbus = fdt_parent_offset(initial_boot_params, cf); | ||
| 683 | if (bootbus < 0) | ||
| 684 | goto no_cf; | ||
| 685 | ranges = fdt_getprop_w(initial_boot_params, bootbus, "ranges", &len); | ||
| 686 | if (!ranges || len < (5 * 8 * sizeof(__be32))) | ||
| 687 | goto no_cf; | ||
| 688 | |||
| 689 | ranges[(cs * 5) + 2] = cpu_to_be32(region_base >> 32); | ||
| 690 | ranges[(cs * 5) + 3] = cpu_to_be32(region_base & 0xffffffff); | ||
| 691 | ranges[(cs * 5) + 4] = cpu_to_be32(region_size); | ||
| 692 | if (is_true_ide) { | ||
| 693 | cs++; | ||
| 694 | ranges[(cs * 5) + 2] = cpu_to_be32(region1_base >> 32); | ||
| 695 | ranges[(cs * 5) + 3] = cpu_to_be32(region1_base & 0xffffffff); | ||
| 696 | ranges[(cs * 5) + 4] = cpu_to_be32(region1_size); | ||
| 697 | } | ||
| 698 | goto end_cf; | ||
| 699 | no_cf: | ||
| 700 | fdt_nop_node(initial_boot_params, cf); | ||
| 701 | |||
| 702 | end_cf: | ||
| 703 | ; | ||
| 704 | } | ||
| 705 | |||
| 706 | /* 8 char LED */ | ||
| 707 | alias_prop = fdt_getprop(initial_boot_params, aliases, | ||
| 708 | "led0", NULL); | ||
| 709 | if (alias_prop) { | ||
| 710 | union cvmx_mio_boot_reg_cfgx mio_boot_reg_cfg; | ||
| 711 | unsigned long base_ptr, region_base, region_size; | ||
| 712 | int cs, bootbus; | ||
| 713 | __be32 new_reg[6]; | ||
| 714 | __be32 *ranges; | ||
| 715 | int len; | ||
| 716 | int led = fdt_path_offset(initial_boot_params, alias_prop); | ||
| 717 | |||
| 718 | base_ptr = octeon_bootinfo->led_display_base_addr; | ||
| 719 | if (base_ptr == 0) | ||
| 720 | goto no_led; | ||
| 721 | /* Find CS0 region. */ | ||
| 722 | for (cs = 0; cs < 8; cs++) { | ||
| 723 | mio_boot_reg_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(cs)); | ||
| 724 | region_base = mio_boot_reg_cfg.s.base << 16; | ||
| 725 | region_size = (mio_boot_reg_cfg.s.size + 1) << 16; | ||
| 726 | if (mio_boot_reg_cfg.s.en && base_ptr >= region_base | ||
| 727 | && base_ptr < region_base + region_size) | ||
| 728 | break; | ||
| 729 | } | ||
| 730 | |||
| 731 | if (cs > 7) | ||
| 732 | goto no_led; | ||
| 733 | |||
| 734 | new_reg[0] = cpu_to_be32(cs); | ||
| 735 | new_reg[1] = cpu_to_be32(0x20); | ||
| 736 | new_reg[2] = cpu_to_be32(0x20); | ||
| 737 | new_reg[3] = cpu_to_be32(cs); | ||
| 738 | new_reg[4] = cpu_to_be32(0); | ||
| 739 | new_reg[5] = cpu_to_be32(0x20); | ||
| 740 | fdt_setprop_inplace(initial_boot_params, led, | ||
| 741 | "reg", new_reg, sizeof(new_reg)); | ||
| 742 | |||
| 743 | bootbus = fdt_parent_offset(initial_boot_params, led); | ||
| 744 | if (bootbus < 0) | ||
| 745 | goto no_led; | ||
| 746 | ranges = fdt_getprop_w(initial_boot_params, bootbus, "ranges", &len); | ||
| 747 | if (!ranges || len < (5 * 8 * sizeof(__be32))) | ||
| 748 | goto no_led; | ||
| 749 | |||
| 750 | ranges[(cs * 5) + 2] = cpu_to_be32(region_base >> 32); | ||
| 751 | ranges[(cs * 5) + 3] = cpu_to_be32(region_base & 0xffffffff); | ||
| 752 | ranges[(cs * 5) + 4] = cpu_to_be32(region_size); | ||
| 753 | goto end_led; | ||
| 754 | |||
| 755 | no_led: | ||
| 756 | fdt_nop_node(initial_boot_params, led); | ||
| 757 | end_led: | ||
| 758 | ; | ||
| 759 | } | ||
| 760 | |||
| 761 | /* OHCI/UHCI USB */ | ||
| 762 | alias_prop = fdt_getprop(initial_boot_params, aliases, | ||
| 763 | "uctl", NULL); | ||
| 764 | if (alias_prop) { | ||
| 765 | int uctl = fdt_path_offset(initial_boot_params, alias_prop); | ||
| 766 | |||
| 767 | if (uctl >= 0 && (!OCTEON_IS_MODEL(OCTEON_CN6XXX) || | ||
| 768 | octeon_bootinfo->board_type == CVMX_BOARD_TYPE_NIC2E)) { | ||
| 769 | pr_debug("Deleting uctl\n"); | ||
| 770 | fdt_nop_node(initial_boot_params, uctl); | ||
| 771 | fdt_nop_property(initial_boot_params, aliases, "uctl"); | ||
| 772 | } else if (octeon_bootinfo->board_type == CVMX_BOARD_TYPE_NIC10E || | ||
| 773 | octeon_bootinfo->board_type == CVMX_BOARD_TYPE_NIC4E) { | ||
| 774 | /* Missing "refclk-type" defaults to crystal. */ | ||
| 775 | fdt_nop_property(initial_boot_params, uctl, "refclk-type"); | ||
| 776 | } | ||
| 777 | } | ||
| 778 | |||
| 779 | return 0; | ||
| 780 | } | ||
| 781 | |||
| 782 | static int __init octeon_publish_devices(void) | ||
| 783 | { | ||
| 784 | return of_platform_bus_probe(NULL, octeon_ids, NULL); | ||
| 785 | } | ||
| 786 | device_initcall(octeon_publish_devices); | ||
| 787 | |||
| 443 | MODULE_AUTHOR("David Daney <ddaney@caviumnetworks.com>"); | 788 | MODULE_AUTHOR("David Daney <ddaney@caviumnetworks.com>"); |
| 444 | MODULE_LICENSE("GPL"); | 789 | MODULE_LICENSE("GPL"); |
| 445 | MODULE_DESCRIPTION("Platform driver for Octeon SOC"); | 790 | MODULE_DESCRIPTION("Platform driver for Octeon SOC"); |
diff --git a/arch/mips/cavium-octeon/octeon_3xxx.dts b/arch/mips/cavium-octeon/octeon_3xxx.dts new file mode 100644 index 000000000000..f28b2d0fde22 --- /dev/null +++ b/arch/mips/cavium-octeon/octeon_3xxx.dts | |||
| @@ -0,0 +1,571 @@ | |||
| 1 | /dts-v1/; | ||
| 2 | /* | ||
| 3 | * OCTEON 3XXX, 5XXX, 63XX device tree skeleton. | ||
| 4 | * | ||
| 5 | * This device tree is pruned and patched by early boot code before | ||
| 6 | * use. Because of this, it contains a super-set of the available | ||
| 7 | * devices and properties. | ||
| 8 | */ | ||
| 9 | / { | ||
| 10 | compatible = "cavium,octeon-3860"; | ||
| 11 | #address-cells = <2>; | ||
| 12 | #size-cells = <2>; | ||
| 13 | interrupt-parent = <&ciu>; | ||
| 14 | |||
| 15 | soc@0 { | ||
| 16 | compatible = "simple-bus"; | ||
| 17 | #address-cells = <2>; | ||
| 18 | #size-cells = <2>; | ||
| 19 | ranges; /* Direct mapping */ | ||
| 20 | |||
| 21 | ciu: interrupt-controller@1070000000000 { | ||
| 22 | compatible = "cavium,octeon-3860-ciu"; | ||
| 23 | interrupt-controller; | ||
| 24 | /* Interrupts are specified by two parts: | ||
| 25 | * 1) Controller register (0 or 1) | ||
| 26 | * 2) Bit within the register (0..63) | ||
| 27 | */ | ||
| 28 | #interrupt-cells = <2>; | ||
| 29 | reg = <0x10700 0x00000000 0x0 0x7000>; | ||
| 30 | }; | ||
| 31 | |||
| 32 | gpio: gpio-controller@1070000000800 { | ||
| 33 | #gpio-cells = <2>; | ||
| 34 | compatible = "cavium,octeon-3860-gpio"; | ||
| 35 | reg = <0x10700 0x00000800 0x0 0x100>; | ||
| 36 | gpio-controller; | ||
| 37 | /* Interrupts are specified by two parts: | ||
| 38 | * 1) GPIO pin number (0..15) | ||
| 39 | * 2) Triggering (1 - edge rising | ||
| 40 | * 2 - edge falling | ||
| 41 | * 4 - level active high | ||
| 42 | * 8 - level active low) | ||
| 43 | */ | ||
| 44 | interrupt-controller; | ||
| 45 | #interrupt-cells = <2>; | ||
| 46 | /* The GPIO pin connect to 16 consecutive CUI bits */ | ||
| 47 | interrupts = <0 16>, <0 17>, <0 18>, <0 19>, | ||
| 48 | <0 20>, <0 21>, <0 22>, <0 23>, | ||
| 49 | <0 24>, <0 25>, <0 26>, <0 27>, | ||
| 50 | <0 28>, <0 29>, <0 30>, <0 31>; | ||
| 51 | }; | ||
| 52 | |||
| 53 | smi0: mdio@1180000001800 { | ||
| 54 | compatible = "cavium,octeon-3860-mdio"; | ||
| 55 | #address-cells = <1>; | ||
| 56 | #size-cells = <0>; | ||
| 57 | reg = <0x11800 0x00001800 0x0 0x40>; | ||
| 58 | |||
| 59 | phy0: ethernet-phy@0 { | ||
| 60 | compatible = "marvell,88e1118"; | ||
| 61 | marvell,reg-init = | ||
| 62 | /* Fix rx and tx clock transition timing */ | ||
| 63 | <2 0x15 0xffcf 0>, /* Reg 2,21 Clear bits 4, 5 */ | ||
| 64 | /* Adjust LED drive. */ | ||
| 65 | <3 0x11 0 0x442a>, /* Reg 3,17 <- 0442a */ | ||
| 66 | /* irq, blink-activity, blink-link */ | ||
| 67 | <3 0x10 0 0x0242>; /* Reg 3,16 <- 0x0242 */ | ||
| 68 | reg = <0>; | ||
| 69 | }; | ||
| 70 | |||
| 71 | phy1: ethernet-phy@1 { | ||
| 72 | compatible = "marvell,88e1118"; | ||
| 73 | marvell,reg-init = | ||
| 74 | /* Fix rx and tx clock transition timing */ | ||
| 75 | <2 0x15 0xffcf 0>, /* Reg 2,21 Clear bits 4, 5 */ | ||
| 76 | /* Adjust LED drive. */ | ||
| 77 | <3 0x11 0 0x442a>, /* Reg 3,17 <- 0442a */ | ||
| 78 | /* irq, blink-activity, blink-link */ | ||
| 79 | <3 0x10 0 0x0242>; /* Reg 3,16 <- 0x0242 */ | ||
| 80 | reg = <1>; | ||
| 81 | }; | ||
| 82 | |||
| 83 | phy2: ethernet-phy@2 { | ||
| 84 | reg = <2>; | ||
| 85 | compatible = "marvell,88e1149r"; | ||
| 86 | marvell,reg-init = <3 0x10 0 0x5777>, | ||
| 87 | <3 0x11 0 0x00aa>, | ||
| 88 | <3 0x12 0 0x4105>, | ||
| 89 | <3 0x13 0 0x0a60>; | ||
| 90 | }; | ||
| 91 | phy3: ethernet-phy@3 { | ||
| 92 | reg = <3>; | ||
| 93 | compatible = "marvell,88e1149r"; | ||
| 94 | marvell,reg-init = <3 0x10 0 0x5777>, | ||
| 95 | <3 0x11 0 0x00aa>, | ||
| 96 | <3 0x12 0 0x4105>, | ||
| 97 | <3 0x13 0 0x0a60>; | ||
| 98 | }; | ||
| 99 | phy4: ethernet-phy@4 { | ||
| 100 | reg = <4>; | ||
| 101 | compatible = "marvell,88e1149r"; | ||
| 102 | marvell,reg-init = <3 0x10 0 0x5777>, | ||
| 103 | <3 0x11 0 0x00aa>, | ||
| 104 | <3 0x12 0 0x4105>, | ||
| 105 | <3 0x13 0 0x0a60>; | ||
| 106 | }; | ||
| 107 | phy5: ethernet-phy@5 { | ||
| 108 | reg = <5>; | ||
| 109 | compatible = "marvell,88e1149r"; | ||
| 110 | marvell,reg-init = <3 0x10 0 0x5777>, | ||
| 111 | <3 0x11 0 0x00aa>, | ||
| 112 | <3 0x12 0 0x4105>, | ||
| 113 | <3 0x13 0 0x0a60>; | ||
| 114 | }; | ||
| 115 | |||
| 116 | phy6: ethernet-phy@6 { | ||
| 117 | reg = <6>; | ||
| 118 | compatible = "marvell,88e1149r"; | ||
| 119 | marvell,reg-init = <3 0x10 0 0x5777>, | ||
| 120 | <3 0x11 0 0x00aa>, | ||
| 121 | <3 0x12 0 0x4105>, | ||
| 122 | <3 0x13 0 0x0a60>; | ||
| 123 | }; | ||
| 124 | phy7: ethernet-phy@7 { | ||
| 125 | reg = <7>; | ||
| 126 | compatible = "marvell,88e1149r"; | ||
| 127 | marvell,reg-init = <3 0x10 0 0x5777>, | ||
| 128 | <3 0x11 0 0x00aa>, | ||
| 129 | <3 0x12 0 0x4105>, | ||
| 130 | <3 0x13 0 0x0a60>; | ||
| 131 | }; | ||
| 132 | phy8: ethernet-phy@8 { | ||
| 133 | reg = <8>; | ||
| 134 | compatible = "marvell,88e1149r"; | ||
| 135 | marvell,reg-init = <3 0x10 0 0x5777>, | ||
| 136 | <3 0x11 0 0x00aa>, | ||
| 137 | <3 0x12 0 0x4105>, | ||
| 138 | <3 0x13 0 0x0a60>; | ||
| 139 | }; | ||
| 140 | phy9: ethernet-phy@9 { | ||
| 141 | reg = <9>; | ||
| 142 | compatible = "marvell,88e1149r"; | ||
| 143 | marvell,reg-init = <3 0x10 0 0x5777>, | ||
| 144 | <3 0x11 0 0x00aa>, | ||
| 145 | <3 0x12 0 0x4105>, | ||
| 146 | <3 0x13 0 0x0a60>; | ||
| 147 | }; | ||
| 148 | }; | ||
| 149 | |||
| 150 | smi1: mdio@1180000001900 { | ||
| 151 | compatible = "cavium,octeon-3860-mdio"; | ||
| 152 | #address-cells = <1>; | ||
| 153 | #size-cells = <0>; | ||
| 154 | reg = <0x11800 0x00001900 0x0 0x40>; | ||
| 155 | |||
| 156 | phy100: ethernet-phy@1 { | ||
| 157 | reg = <1>; | ||
| 158 | compatible = "marvell,88e1149r"; | ||
| 159 | marvell,reg-init = <3 0x10 0 0x5777>, | ||
| 160 | <3 0x11 0 0x00aa>, | ||
| 161 | <3 0x12 0 0x4105>, | ||
| 162 | <3 0x13 0 0x0a60>; | ||
| 163 | interrupt-parent = <&gpio>; | ||
| 164 | interrupts = <12 8>; /* Pin 12, active low */ | ||
| 165 | }; | ||
| 166 | phy101: ethernet-phy@2 { | ||
| 167 | reg = <2>; | ||
| 168 | compatible = "marvell,88e1149r"; | ||
| 169 | marvell,reg-init = <3 0x10 0 0x5777>, | ||
| 170 | <3 0x11 0 0x00aa>, | ||
| 171 | <3 0x12 0 0x4105>, | ||
| 172 | <3 0x13 0 0x0a60>; | ||
| 173 | interrupt-parent = <&gpio>; | ||
| 174 | interrupts = <12 8>; /* Pin 12, active low */ | ||
| 175 | }; | ||
| 176 | phy102: ethernet-phy@3 { | ||
| 177 | reg = <3>; | ||
| 178 | compatible = "marvell,88e1149r"; | ||
| 179 | marvell,reg-init = <3 0x10 0 0x5777>, | ||
| 180 | <3 0x11 0 0x00aa>, | ||
| 181 | <3 0x12 0 0x4105>, | ||
| 182 | <3 0x13 0 0x0a60>; | ||
| 183 | interrupt-parent = <&gpio>; | ||
| 184 | interrupts = <12 8>; /* Pin 12, active low */ | ||
| 185 | }; | ||
| 186 | phy103: ethernet-phy@4 { | ||
| 187 | reg = <4>; | ||
| 188 | compatible = "marvell,88e1149r"; | ||
| 189 | marvell,reg-init = <3 0x10 0 0x5777>, | ||
| 190 | <3 0x11 0 0x00aa>, | ||
| 191 | <3 0x12 0 0x4105>, | ||
| 192 | <3 0x13 0 0x0a60>; | ||
| 193 | interrupt-parent = <&gpio>; | ||
| 194 | interrupts = <12 8>; /* Pin 12, active low */ | ||
| 195 | }; | ||
| 196 | }; | ||
| 197 | |||
| 198 | mix0: ethernet@1070000100000 { | ||
| 199 | compatible = "cavium,octeon-5750-mix"; | ||
| 200 | reg = <0x10700 0x00100000 0x0 0x100>, /* MIX */ | ||
| 201 | <0x11800 0xE0000000 0x0 0x300>, /* AGL */ | ||
| 202 | <0x11800 0xE0000400 0x0 0x400>, /* AGL_SHARED */ | ||
| 203 | <0x11800 0xE0002000 0x0 0x8>; /* AGL_PRT_CTL */ | ||
| 204 | cell-index = <0>; | ||
| 205 | interrupts = <0 62>, <1 46>; | ||
| 206 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 207 | phy-handle = <&phy0>; | ||
| 208 | }; | ||
| 209 | |||
| 210 | mix1: ethernet@1070000100800 { | ||
| 211 | compatible = "cavium,octeon-5750-mix"; | ||
| 212 | reg = <0x10700 0x00100800 0x0 0x100>, /* MIX */ | ||
| 213 | <0x11800 0xE0000800 0x0 0x300>, /* AGL */ | ||
| 214 | <0x11800 0xE0000400 0x0 0x400>, /* AGL_SHARED */ | ||
| 215 | <0x11800 0xE0002008 0x0 0x8>; /* AGL_PRT_CTL */ | ||
| 216 | cell-index = <1>; | ||
| 217 | interrupts = <1 18>, < 1 46>; | ||
| 218 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 219 | phy-handle = <&phy1>; | ||
| 220 | }; | ||
| 221 | |||
| 222 | pip: pip@11800a0000000 { | ||
| 223 | compatible = "cavium,octeon-3860-pip"; | ||
| 224 | #address-cells = <1>; | ||
| 225 | #size-cells = <0>; | ||
| 226 | reg = <0x11800 0xa0000000 0x0 0x2000>; | ||
| 227 | |||
| 228 | interface@0 { | ||
| 229 | compatible = "cavium,octeon-3860-pip-interface"; | ||
| 230 | #address-cells = <1>; | ||
| 231 | #size-cells = <0>; | ||
| 232 | reg = <0>; /* interface */ | ||
| 233 | |||
| 234 | ethernet@0 { | ||
| 235 | compatible = "cavium,octeon-3860-pip-port"; | ||
| 236 | reg = <0x0>; /* Port */ | ||
| 237 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 238 | phy-handle = <&phy2>; | ||
| 239 | cavium,alt-phy-handle = <&phy100>; | ||
| 240 | }; | ||
| 241 | ethernet@1 { | ||
| 242 | compatible = "cavium,octeon-3860-pip-port"; | ||
| 243 | reg = <0x1>; /* Port */ | ||
| 244 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 245 | phy-handle = <&phy3>; | ||
| 246 | cavium,alt-phy-handle = <&phy101>; | ||
| 247 | }; | ||
| 248 | ethernet@2 { | ||
| 249 | compatible = "cavium,octeon-3860-pip-port"; | ||
| 250 | reg = <0x2>; /* Port */ | ||
| 251 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 252 | phy-handle = <&phy4>; | ||
| 253 | cavium,alt-phy-handle = <&phy102>; | ||
| 254 | }; | ||
| 255 | ethernet@3 { | ||
| 256 | compatible = "cavium,octeon-3860-pip-port"; | ||
| 257 | reg = <0x3>; /* Port */ | ||
| 258 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 259 | phy-handle = <&phy5>; | ||
| 260 | cavium,alt-phy-handle = <&phy103>; | ||
| 261 | }; | ||
| 262 | ethernet@4 { | ||
| 263 | compatible = "cavium,octeon-3860-pip-port"; | ||
| 264 | reg = <0x4>; /* Port */ | ||
| 265 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 266 | }; | ||
| 267 | ethernet@5 { | ||
| 268 | compatible = "cavium,octeon-3860-pip-port"; | ||
| 269 | reg = <0x5>; /* Port */ | ||
| 270 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 271 | }; | ||
| 272 | ethernet@6 { | ||
| 273 | compatible = "cavium,octeon-3860-pip-port"; | ||
| 274 | reg = <0x6>; /* Port */ | ||
| 275 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 276 | }; | ||
| 277 | ethernet@7 { | ||
| 278 | compatible = "cavium,octeon-3860-pip-port"; | ||
| 279 | reg = <0x7>; /* Port */ | ||
| 280 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 281 | }; | ||
| 282 | ethernet@8 { | ||
| 283 | compatible = "cavium,octeon-3860-pip-port"; | ||
| 284 | reg = <0x8>; /* Port */ | ||
| 285 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 286 | }; | ||
| 287 | ethernet@9 { | ||
| 288 | compatible = "cavium,octeon-3860-pip-port"; | ||
| 289 | reg = <0x9>; /* Port */ | ||
| 290 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 291 | }; | ||
| 292 | ethernet@a { | ||
| 293 | compatible = "cavium,octeon-3860-pip-port"; | ||
| 294 | reg = <0xa>; /* Port */ | ||
| 295 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 296 | }; | ||
| 297 | ethernet@b { | ||
| 298 | compatible = "cavium,octeon-3860-pip-port"; | ||
| 299 | reg = <0xb>; /* Port */ | ||
| 300 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 301 | }; | ||
| 302 | ethernet@c { | ||
| 303 | compatible = "cavium,octeon-3860-pip-port"; | ||
| 304 | reg = <0xc>; /* Port */ | ||
| 305 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 306 | }; | ||
| 307 | ethernet@d { | ||
| 308 | compatible = "cavium,octeon-3860-pip-port"; | ||
| 309 | reg = <0xd>; /* Port */ | ||
| 310 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 311 | }; | ||
| 312 | ethernet@e { | ||
| 313 | compatible = "cavium,octeon-3860-pip-port"; | ||
| 314 | reg = <0xe>; /* Port */ | ||
| 315 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 316 | }; | ||
| 317 | ethernet@f { | ||
| 318 | compatible = "cavium,octeon-3860-pip-port"; | ||
| 319 | reg = <0xf>; /* Port */ | ||
| 320 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 321 | }; | ||
| 322 | }; | ||
| 323 | |||
| 324 | interface@1 { | ||
| 325 | compatible = "cavium,octeon-3860-pip-interface"; | ||
| 326 | #address-cells = <1>; | ||
| 327 | #size-cells = <0>; | ||
| 328 | reg = <1>; /* interface */ | ||
| 329 | |||
| 330 | ethernet@0 { | ||
| 331 | compatible = "cavium,octeon-3860-pip-port"; | ||
| 332 | reg = <0x0>; /* Port */ | ||
| 333 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 334 | phy-handle = <&phy6>; | ||
| 335 | }; | ||
| 336 | ethernet@1 { | ||
| 337 | compatible = "cavium,octeon-3860-pip-port"; | ||
| 338 | reg = <0x1>; /* Port */ | ||
| 339 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 340 | phy-handle = <&phy7>; | ||
| 341 | }; | ||
| 342 | ethernet@2 { | ||
| 343 | compatible = "cavium,octeon-3860-pip-port"; | ||
| 344 | reg = <0x2>; /* Port */ | ||
| 345 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 346 | phy-handle = <&phy8>; | ||
| 347 | }; | ||
| 348 | ethernet@3 { | ||
| 349 | compatible = "cavium,octeon-3860-pip-port"; | ||
| 350 | reg = <0x3>; /* Port */ | ||
| 351 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 352 | phy-handle = <&phy9>; | ||
| 353 | }; | ||
| 354 | }; | ||
| 355 | }; | ||
| 356 | |||
| 357 | twsi0: i2c@1180000001000 { | ||
| 358 | #address-cells = <1>; | ||
| 359 | #size-cells = <0>; | ||
| 360 | compatible = "cavium,octeon-3860-twsi"; | ||
| 361 | reg = <0x11800 0x00001000 0x0 0x200>; | ||
| 362 | interrupts = <0 45>; | ||
| 363 | clock-frequency = <100000>; | ||
| 364 | |||
| 365 | rtc@68 { | ||
| 366 | compatible = "dallas,ds1337"; | ||
| 367 | reg = <0x68>; | ||
| 368 | }; | ||
| 369 | tmp@4c { | ||
| 370 | compatible = "ti,tmp421"; | ||
| 371 | reg = <0x4c>; | ||
| 372 | }; | ||
| 373 | }; | ||
| 374 | |||
| 375 | twsi1: i2c@1180000001200 { | ||
| 376 | #address-cells = <1>; | ||
| 377 | #size-cells = <0>; | ||
| 378 | compatible = "cavium,octeon-3860-twsi"; | ||
| 379 | reg = <0x11800 0x00001200 0x0 0x200>; | ||
| 380 | interrupts = <0 59>; | ||
| 381 | clock-frequency = <100000>; | ||
| 382 | }; | ||
| 383 | |||
| 384 | uart0: serial@1180000000800 { | ||
| 385 | compatible = "cavium,octeon-3860-uart","ns16550"; | ||
| 386 | reg = <0x11800 0x00000800 0x0 0x400>; | ||
| 387 | clock-frequency = <0>; | ||
| 388 | current-speed = <115200>; | ||
| 389 | reg-shift = <3>; | ||
| 390 | interrupts = <0 34>; | ||
| 391 | }; | ||
| 392 | |||
| 393 | uart1: serial@1180000000c00 { | ||
| 394 | compatible = "cavium,octeon-3860-uart","ns16550"; | ||
| 395 | reg = <0x11800 0x00000c00 0x0 0x400>; | ||
| 396 | clock-frequency = <0>; | ||
| 397 | current-speed = <115200>; | ||
| 398 | reg-shift = <3>; | ||
| 399 | interrupts = <0 35>; | ||
| 400 | }; | ||
| 401 | |||
| 402 | uart2: serial@1180000000400 { | ||
| 403 | compatible = "cavium,octeon-3860-uart","ns16550"; | ||
| 404 | reg = <0x11800 0x00000400 0x0 0x400>; | ||
| 405 | clock-frequency = <0>; | ||
| 406 | current-speed = <115200>; | ||
| 407 | reg-shift = <3>; | ||
| 408 | interrupts = <1 16>; | ||
| 409 | }; | ||
| 410 | |||
| 411 | bootbus: bootbus@1180000000000 { | ||
| 412 | compatible = "cavium,octeon-3860-bootbus"; | ||
| 413 | reg = <0x11800 0x00000000 0x0 0x200>; | ||
| 414 | /* The chip select number and offset */ | ||
| 415 | #address-cells = <2>; | ||
| 416 | /* The size of the chip select region */ | ||
| 417 | #size-cells = <1>; | ||
| 418 | ranges = <0 0 0x0 0x1f400000 0xc00000>, | ||
| 419 | <1 0 0x10000 0x30000000 0>, | ||
| 420 | <2 0 0x10000 0x40000000 0>, | ||
| 421 | <3 0 0x10000 0x50000000 0>, | ||
| 422 | <4 0 0x0 0x1d020000 0x10000>, | ||
| 423 | <5 0 0x0 0x1d040000 0x10000>, | ||
| 424 | <6 0 0x0 0x1d050000 0x10000>, | ||
| 425 | <7 0 0x10000 0x90000000 0>; | ||
| 426 | |||
| 427 | cavium,cs-config@0 { | ||
| 428 | compatible = "cavium,octeon-3860-bootbus-config"; | ||
| 429 | cavium,cs-index = <0>; | ||
| 430 | cavium,t-adr = <20>; | ||
| 431 | cavium,t-ce = <60>; | ||
| 432 | cavium,t-oe = <60>; | ||
| 433 | cavium,t-we = <45>; | ||
| 434 | cavium,t-rd-hld = <35>; | ||
| 435 | cavium,t-wr-hld = <45>; | ||
| 436 | cavium,t-pause = <0>; | ||
| 437 | cavium,t-wait = <0>; | ||
| 438 | cavium,t-page = <35>; | ||
| 439 | cavium,t-rd-dly = <0>; | ||
| 440 | |||
| 441 | cavium,pages = <0>; | ||
| 442 | cavium,bus-width = <8>; | ||
| 443 | }; | ||
| 444 | cavium,cs-config@4 { | ||
| 445 | compatible = "cavium,octeon-3860-bootbus-config"; | ||
| 446 | cavium,cs-index = <4>; | ||
| 447 | cavium,t-adr = <320>; | ||
| 448 | cavium,t-ce = <320>; | ||
| 449 | cavium,t-oe = <320>; | ||
| 450 | cavium,t-we = <320>; | ||
| 451 | cavium,t-rd-hld = <320>; | ||
| 452 | cavium,t-wr-hld = <320>; | ||
| 453 | cavium,t-pause = <320>; | ||
| 454 | cavium,t-wait = <320>; | ||
| 455 | cavium,t-page = <320>; | ||
| 456 | cavium,t-rd-dly = <0>; | ||
| 457 | |||
| 458 | cavium,pages = <0>; | ||
| 459 | cavium,bus-width = <8>; | ||
| 460 | }; | ||
| 461 | cavium,cs-config@5 { | ||
| 462 | compatible = "cavium,octeon-3860-bootbus-config"; | ||
| 463 | cavium,cs-index = <5>; | ||
| 464 | cavium,t-adr = <5>; | ||
| 465 | cavium,t-ce = <300>; | ||
| 466 | cavium,t-oe = <125>; | ||
| 467 | cavium,t-we = <150>; | ||
| 468 | cavium,t-rd-hld = <100>; | ||
| 469 | cavium,t-wr-hld = <30>; | ||
| 470 | cavium,t-pause = <0>; | ||
| 471 | cavium,t-wait = <30>; | ||
| 472 | cavium,t-page = <320>; | ||
| 473 | cavium,t-rd-dly = <0>; | ||
| 474 | |||
| 475 | cavium,pages = <0>; | ||
| 476 | cavium,bus-width = <16>; | ||
| 477 | }; | ||
| 478 | cavium,cs-config@6 { | ||
| 479 | compatible = "cavium,octeon-3860-bootbus-config"; | ||
| 480 | cavium,cs-index = <6>; | ||
| 481 | cavium,t-adr = <5>; | ||
| 482 | cavium,t-ce = <300>; | ||
| 483 | cavium,t-oe = <270>; | ||
| 484 | cavium,t-we = <150>; | ||
| 485 | cavium,t-rd-hld = <100>; | ||
| 486 | cavium,t-wr-hld = <70>; | ||
| 487 | cavium,t-pause = <0>; | ||
| 488 | cavium,t-wait = <0>; | ||
| 489 | cavium,t-page = <320>; | ||
| 490 | cavium,t-rd-dly = <0>; | ||
| 491 | |||
| 492 | cavium,pages = <0>; | ||
| 493 | cavium,wait-mode; | ||
| 494 | cavium,bus-width = <16>; | ||
| 495 | }; | ||
| 496 | |||
| 497 | flash0: nor@0,0 { | ||
| 498 | compatible = "cfi-flash"; | ||
| 499 | reg = <0 0 0x800000>; | ||
| 500 | #address-cells = <1>; | ||
| 501 | #size-cells = <1>; | ||
| 502 | }; | ||
| 503 | |||
| 504 | led0: led-display@4,0 { | ||
| 505 | compatible = "avago,hdsp-253x"; | ||
| 506 | reg = <4 0x20 0x20>, <4 0 0x20>; | ||
| 507 | }; | ||
| 508 | |||
| 509 | cf0: compact-flash@5,0 { | ||
| 510 | compatible = "cavium,ebt3000-compact-flash"; | ||
| 511 | reg = <5 0 0x10000>, <6 0 0x10000>; | ||
| 512 | cavium,bus-width = <16>; | ||
| 513 | cavium,true-ide; | ||
| 514 | cavium,dma-engine-handle = <&dma0>; | ||
| 515 | }; | ||
| 516 | }; | ||
| 517 | |||
| 518 | dma0: dma-engine@1180000000100 { | ||
| 519 | compatible = "cavium,octeon-5750-bootbus-dma"; | ||
| 520 | reg = <0x11800 0x00000100 0x0 0x8>; | ||
| 521 | interrupts = <0 63>; | ||
| 522 | }; | ||
| 523 | dma1: dma-engine@1180000000108 { | ||
| 524 | compatible = "cavium,octeon-5750-bootbus-dma"; | ||
| 525 | reg = <0x11800 0x00000108 0x0 0x8>; | ||
| 526 | interrupts = <0 63>; | ||
| 527 | }; | ||
| 528 | |||
| 529 | uctl: uctl@118006f000000 { | ||
| 530 | compatible = "cavium,octeon-6335-uctl"; | ||
| 531 | reg = <0x11800 0x6f000000 0x0 0x100>; | ||
| 532 | ranges; /* Direct mapping */ | ||
| 533 | #address-cells = <2>; | ||
| 534 | #size-cells = <2>; | ||
| 535 | /* 12MHz, 24MHz and 48MHz allowed */ | ||
| 536 | refclk-frequency = <12000000>; | ||
| 537 | /* Either "crystal" or "external" */ | ||
| 538 | refclk-type = "crystal"; | ||
| 539 | |||
| 540 | ehci@16f0000000000 { | ||
| 541 | compatible = "cavium,octeon-6335-ehci","usb-ehci"; | ||
| 542 | reg = <0x16f00 0x00000000 0x0 0x100>; | ||
| 543 | interrupts = <0 56>; | ||
| 544 | big-endian-regs; | ||
| 545 | }; | ||
| 546 | ohci@16f0000000400 { | ||
| 547 | compatible = "cavium,octeon-6335-ohci","usb-ohci"; | ||
| 548 | reg = <0x16f00 0x00000400 0x0 0x100>; | ||
| 549 | interrupts = <0 56>; | ||
| 550 | big-endian-regs; | ||
| 551 | }; | ||
| 552 | }; | ||
| 553 | }; | ||
| 554 | |||
| 555 | aliases { | ||
| 556 | mix0 = &mix0; | ||
| 557 | mix1 = &mix1; | ||
| 558 | pip = &pip; | ||
| 559 | smi0 = &smi0; | ||
| 560 | smi1 = &smi1; | ||
| 561 | twsi0 = &twsi0; | ||
| 562 | twsi1 = &twsi1; | ||
| 563 | uart0 = &uart0; | ||
| 564 | uart1 = &uart1; | ||
| 565 | uart2 = &uart2; | ||
| 566 | flash0 = &flash0; | ||
| 567 | cf0 = &cf0; | ||
| 568 | uctl = &uctl; | ||
| 569 | led0 = &led0; | ||
| 570 | }; | ||
| 571 | }; | ||
diff --git a/arch/mips/cavium-octeon/octeon_68xx.dts b/arch/mips/cavium-octeon/octeon_68xx.dts new file mode 100644 index 000000000000..1839468932b6 --- /dev/null +++ b/arch/mips/cavium-octeon/octeon_68xx.dts | |||
| @@ -0,0 +1,625 @@ | |||
| 1 | /dts-v1/; | ||
| 2 | /* | ||
| 3 | * OCTEON 68XX device tree skeleton. | ||
| 4 | * | ||
| 5 | * This device tree is pruned and patched by early boot code before | ||
| 6 | * use. Because of this, it contains a super-set of the available | ||
| 7 | * devices and properties. | ||
| 8 | */ | ||
| 9 | / { | ||
| 10 | compatible = "cavium,octeon-6880"; | ||
| 11 | #address-cells = <2>; | ||
| 12 | #size-cells = <2>; | ||
| 13 | interrupt-parent = <&ciu2>; | ||
| 14 | |||
| 15 | soc@0 { | ||
| 16 | compatible = "simple-bus"; | ||
| 17 | #address-cells = <2>; | ||
| 18 | #size-cells = <2>; | ||
| 19 | ranges; /* Direct mapping */ | ||
| 20 | |||
| 21 | ciu2: interrupt-controller@1070100000000 { | ||
| 22 | compatible = "cavium,octeon-6880-ciu2"; | ||
| 23 | interrupt-controller; | ||
| 24 | /* Interrupts are specified by two parts: | ||
| 25 | * 1) Controller register (0 or 7) | ||
| 26 | * 2) Bit within the register (0..63) | ||
| 27 | */ | ||
| 28 | #address-cells = <0>; | ||
| 29 | #interrupt-cells = <2>; | ||
| 30 | reg = <0x10701 0x00000000 0x0 0x4000000>; | ||
| 31 | }; | ||
| 32 | |||
| 33 | gpio: gpio-controller@1070000000800 { | ||
| 34 | #gpio-cells = <2>; | ||
| 35 | compatible = "cavium,octeon-3860-gpio"; | ||
| 36 | reg = <0x10700 0x00000800 0x0 0x100>; | ||
| 37 | gpio-controller; | ||
| 38 | /* Interrupts are specified by two parts: | ||
| 39 | * 1) GPIO pin number (0..15) | ||
| 40 | * 2) Triggering (1 - edge rising | ||
| 41 | * 2 - edge falling | ||
| 42 | * 4 - level active high | ||
| 43 | * 8 - level active low) | ||
| 44 | */ | ||
| 45 | interrupt-controller; | ||
| 46 | #interrupt-cells = <2>; | ||
| 47 | /* The GPIO pins connect to 16 consecutive CUI bits */ | ||
| 48 | interrupts = <7 0>, <7 1>, <7 2>, <7 3>, | ||
| 49 | <7 4>, <7 5>, <7 6>, <7 7>, | ||
| 50 | <7 8>, <7 9>, <7 10>, <7 11>, | ||
| 51 | <7 12>, <7 13>, <7 14>, <7 15>; | ||
| 52 | }; | ||
| 53 | |||
| 54 | smi0: mdio@1180000003800 { | ||
| 55 | compatible = "cavium,octeon-3860-mdio"; | ||
| 56 | #address-cells = <1>; | ||
| 57 | #size-cells = <0>; | ||
| 58 | reg = <0x11800 0x00003800 0x0 0x40>; | ||
| 59 | |||
| 60 | phy0: ethernet-phy@6 { | ||
| 61 | compatible = "marvell,88e1118"; | ||
| 62 | marvell,reg-init = | ||
| 63 | /* Fix rx and tx clock transition timing */ | ||
| 64 | <2 0x15 0xffcf 0>, /* Reg 2,21 Clear bits 4, 5 */ | ||
| 65 | /* Adjust LED drive. */ | ||
| 66 | <3 0x11 0 0x442a>, /* Reg 3,17 <- 0442a */ | ||
| 67 | /* irq, blink-activity, blink-link */ | ||
| 68 | <3 0x10 0 0x0242>; /* Reg 3,16 <- 0x0242 */ | ||
| 69 | reg = <6>; | ||
| 70 | }; | ||
| 71 | |||
| 72 | phy1: ethernet-phy@1 { | ||
| 73 | cavium,qlm-trim = "4,sgmii"; | ||
| 74 | reg = <1>; | ||
| 75 | compatible = "marvell,88e1149r"; | ||
| 76 | marvell,reg-init = <3 0x10 0 0x5777>, | ||
| 77 | <3 0x11 0 0x00aa>, | ||
| 78 | <3 0x12 0 0x4105>, | ||
| 79 | <3 0x13 0 0x0a60>; | ||
| 80 | }; | ||
| 81 | phy2: ethernet-phy@2 { | ||
| 82 | cavium,qlm-trim = "4,sgmii"; | ||
| 83 | reg = <2>; | ||
| 84 | compatible = "marvell,88e1149r"; | ||
| 85 | marvell,reg-init = <3 0x10 0 0x5777>, | ||
| 86 | <3 0x11 0 0x00aa>, | ||
| 87 | <3 0x12 0 0x4105>, | ||
| 88 | <3 0x13 0 0x0a60>; | ||
| 89 | }; | ||
| 90 | phy3: ethernet-phy@3 { | ||
| 91 | cavium,qlm-trim = "4,sgmii"; | ||
| 92 | reg = <3>; | ||
| 93 | compatible = "marvell,88e1149r"; | ||
| 94 | marvell,reg-init = <3 0x10 0 0x5777>, | ||
| 95 | <3 0x11 0 0x00aa>, | ||
| 96 | <3 0x12 0 0x4105>, | ||
| 97 | <3 0x13 0 0x0a60>; | ||
| 98 | }; | ||
| 99 | phy4: ethernet-phy@4 { | ||
| 100 | cavium,qlm-trim = "4,sgmii"; | ||
| 101 | reg = <4>; | ||
| 102 | compatible = "marvell,88e1149r"; | ||
| 103 | marvell,reg-init = <3 0x10 0 0x5777>, | ||
| 104 | <3 0x11 0 0x00aa>, | ||
| 105 | <3 0x12 0 0x4105>, | ||
| 106 | <3 0x13 0 0x0a60>; | ||
| 107 | }; | ||
| 108 | }; | ||
| 109 | |||
| 110 | smi1: mdio@1180000003880 { | ||
| 111 | compatible = "cavium,octeon-3860-mdio"; | ||
| 112 | #address-cells = <1>; | ||
| 113 | #size-cells = <0>; | ||
| 114 | reg = <0x11800 0x00003880 0x0 0x40>; | ||
| 115 | |||
| 116 | phy41: ethernet-phy@1 { | ||
| 117 | cavium,qlm-trim = "0,sgmii"; | ||
| 118 | reg = <1>; | ||
| 119 | compatible = "marvell,88e1149r"; | ||
| 120 | marvell,reg-init = <3 0x10 0 0x5777>, | ||
| 121 | <3 0x11 0 0x00aa>, | ||
| 122 | <3 0x12 0 0x4105>, | ||
| 123 | <3 0x13 0 0x0a60>; | ||
| 124 | }; | ||
| 125 | phy42: ethernet-phy@2 { | ||
| 126 | cavium,qlm-trim = "0,sgmii"; | ||
| 127 | reg = <2>; | ||
| 128 | compatible = "marvell,88e1149r"; | ||
| 129 | marvell,reg-init = <3 0x10 0 0x5777>, | ||
| 130 | <3 0x11 0 0x00aa>, | ||
| 131 | <3 0x12 0 0x4105>, | ||
| 132 | <3 0x13 0 0x0a60>; | ||
| 133 | }; | ||
| 134 | phy43: ethernet-phy@3 { | ||
| 135 | cavium,qlm-trim = "0,sgmii"; | ||
| 136 | reg = <3>; | ||
| 137 | compatible = "marvell,88e1149r"; | ||
| 138 | marvell,reg-init = <3 0x10 0 0x5777>, | ||
| 139 | <3 0x11 0 0x00aa>, | ||
| 140 | <3 0x12 0 0x4105>, | ||
| 141 | <3 0x13 0 0x0a60>; | ||
| 142 | }; | ||
| 143 | phy44: ethernet-phy@4 { | ||
| 144 | cavium,qlm-trim = "0,sgmii"; | ||
| 145 | reg = <4>; | ||
| 146 | compatible = "marvell,88e1149r"; | ||
| 147 | marvell,reg-init = <3 0x10 0 0x5777>, | ||
| 148 | <3 0x11 0 0x00aa>, | ||
| 149 | <3 0x12 0 0x4105>, | ||
| 150 | <3 0x13 0 0x0a60>; | ||
| 151 | }; | ||
| 152 | }; | ||
| 153 | |||
| 154 | smi2: mdio@1180000003900 { | ||
| 155 | compatible = "cavium,octeon-3860-mdio"; | ||
| 156 | #address-cells = <1>; | ||
| 157 | #size-cells = <0>; | ||
| 158 | reg = <0x11800 0x00003900 0x0 0x40>; | ||
| 159 | |||
| 160 | phy21: ethernet-phy@1 { | ||
| 161 | cavium,qlm-trim = "2,sgmii"; | ||
| 162 | reg = <1>; | ||
| 163 | compatible = "marvell,88e1149r"; | ||
| 164 | marvell,reg-init = <3 0x10 0 0x5777>, | ||
| 165 | <3 0x11 0 0x00aa>, | ||
| 166 | <3 0x12 0 0x4105>, | ||
| 167 | <3 0x13 0 0x0a60>; | ||
| 168 | }; | ||
| 169 | phy22: ethernet-phy@2 { | ||
| 170 | cavium,qlm-trim = "2,sgmii"; | ||
| 171 | reg = <2>; | ||
| 172 | compatible = "marvell,88e1149r"; | ||
| 173 | marvell,reg-init = <3 0x10 0 0x5777>, | ||
| 174 | <3 0x11 0 0x00aa>, | ||
| 175 | <3 0x12 0 0x4105>, | ||
| 176 | <3 0x13 0 0x0a60>; | ||
| 177 | }; | ||
| 178 | phy23: ethernet-phy@3 { | ||
| 179 | cavium,qlm-trim = "2,sgmii"; | ||
| 180 | reg = <3>; | ||
| 181 | compatible = "marvell,88e1149r"; | ||
| 182 | marvell,reg-init = <3 0x10 0 0x5777>, | ||
| 183 | <3 0x11 0 0x00aa>, | ||
| 184 | <3 0x12 0 0x4105>, | ||
| 185 | <3 0x13 0 0x0a60>; | ||
| 186 | }; | ||
| 187 | phy24: ethernet-phy@4 { | ||
| 188 | cavium,qlm-trim = "2,sgmii"; | ||
| 189 | reg = <4>; | ||
| 190 | compatible = "marvell,88e1149r"; | ||
| 191 | marvell,reg-init = <3 0x10 0 0x5777>, | ||
| 192 | <3 0x11 0 0x00aa>, | ||
| 193 | <3 0x12 0 0x4105>, | ||
| 194 | <3 0x13 0 0x0a60>; | ||
| 195 | }; | ||
| 196 | }; | ||
| 197 | |||
| 198 | smi3: mdio@1180000003980 { | ||
| 199 | compatible = "cavium,octeon-3860-mdio"; | ||
| 200 | #address-cells = <1>; | ||
| 201 | #size-cells = <0>; | ||
| 202 | reg = <0x11800 0x00003980 0x0 0x40>; | ||
| 203 | |||
| 204 | phy11: ethernet-phy@1 { | ||
| 205 | cavium,qlm-trim = "3,sgmii"; | ||
| 206 | reg = <1>; | ||
| 207 | compatible = "marvell,88e1149r"; | ||
| 208 | marvell,reg-init = <3 0x10 0 0x5777>, | ||
| 209 | <3 0x11 0 0x00aa>, | ||
| 210 | <3 0x12 0 0x4105>, | ||
| 211 | <3 0x13 0 0x0a60>; | ||
| 212 | }; | ||
| 213 | phy12: ethernet-phy@2 { | ||
| 214 | cavium,qlm-trim = "3,sgmii"; | ||
| 215 | reg = <2>; | ||
| 216 | compatible = "marvell,88e1149r"; | ||
| 217 | marvell,reg-init = <3 0x10 0 0x5777>, | ||
| 218 | <3 0x11 0 0x00aa>, | ||
| 219 | <3 0x12 0 0x4105>, | ||
| 220 | <3 0x13 0 0x0a60>; | ||
| 221 | }; | ||
| 222 | phy13: ethernet-phy@3 { | ||
| 223 | cavium,qlm-trim = "3,sgmii"; | ||
| 224 | reg = <3>; | ||
| 225 | compatible = "marvell,88e1149r"; | ||
| 226 | marvell,reg-init = <3 0x10 0 0x5777>, | ||
| 227 | <3 0x11 0 0x00aa>, | ||
| 228 | <3 0x12 0 0x4105>, | ||
| 229 | <3 0x13 0 0x0a60>; | ||
| 230 | }; | ||
| 231 | phy14: ethernet-phy@4 { | ||
| 232 | cavium,qlm-trim = "3,sgmii"; | ||
| 233 | reg = <4>; | ||
| 234 | compatible = "marvell,88e1149r"; | ||
| 235 | marvell,reg-init = <3 0x10 0 0x5777>, | ||
| 236 | <3 0x11 0 0x00aa>, | ||
| 237 | <3 0x12 0 0x4105>, | ||
| 238 | <3 0x13 0 0x0a60>; | ||
| 239 | }; | ||
| 240 | }; | ||
| 241 | |||
| 242 | mix0: ethernet@1070000100000 { | ||
| 243 | compatible = "cavium,octeon-5750-mix"; | ||
| 244 | reg = <0x10700 0x00100000 0x0 0x100>, /* MIX */ | ||
| 245 | <0x11800 0xE0000000 0x0 0x300>, /* AGL */ | ||
| 246 | <0x11800 0xE0000400 0x0 0x400>, /* AGL_SHARED */ | ||
| 247 | <0x11800 0xE0002000 0x0 0x8>; /* AGL_PRT_CTL */ | ||
| 248 | cell-index = <0>; | ||
| 249 | interrupts = <6 40>, <6 32>; | ||
| 250 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 251 | phy-handle = <&phy0>; | ||
| 252 | }; | ||
| 253 | |||
| 254 | pip: pip@11800a0000000 { | ||
| 255 | compatible = "cavium,octeon-3860-pip"; | ||
| 256 | #address-cells = <1>; | ||
| 257 | #size-cells = <0>; | ||
| 258 | reg = <0x11800 0xa0000000 0x0 0x2000>; | ||
| 259 | |||
| 260 | interface@4 { | ||
| 261 | compatible = "cavium,octeon-3860-pip-interface"; | ||
| 262 | #address-cells = <1>; | ||
| 263 | #size-cells = <0>; | ||
| 264 | reg = <0x4>; /* interface */ | ||
| 265 | |||
| 266 | ethernet@0 { | ||
| 267 | compatible = "cavium,octeon-3860-pip-port"; | ||
| 268 | reg = <0x0>; /* Port */ | ||
| 269 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 270 | phy-handle = <&phy1>; | ||
| 271 | }; | ||
| 272 | ethernet@1 { | ||
| 273 | compatible = "cavium,octeon-3860-pip-port"; | ||
| 274 | reg = <0x1>; /* Port */ | ||
| 275 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 276 | phy-handle = <&phy2>; | ||
| 277 | }; | ||
| 278 | ethernet@2 { | ||
| 279 | compatible = "cavium,octeon-3860-pip-port"; | ||
| 280 | reg = <0x2>; /* Port */ | ||
| 281 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 282 | phy-handle = <&phy3>; | ||
| 283 | }; | ||
| 284 | ethernet@3 { | ||
| 285 | compatible = "cavium,octeon-3860-pip-port"; | ||
| 286 | reg = <0x3>; /* Port */ | ||
| 287 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 288 | phy-handle = <&phy4>; | ||
| 289 | }; | ||
| 290 | }; | ||
| 291 | |||
| 292 | interface@3 { | ||
| 293 | compatible = "cavium,octeon-3860-pip-interface"; | ||
| 294 | #address-cells = <1>; | ||
| 295 | #size-cells = <0>; | ||
| 296 | reg = <0x3>; /* interface */ | ||
| 297 | |||
| 298 | ethernet@0 { | ||
| 299 | compatible = "cavium,octeon-3860-pip-port"; | ||
| 300 | reg = <0x0>; /* Port */ | ||
| 301 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 302 | phy-handle = <&phy11>; | ||
| 303 | }; | ||
| 304 | ethernet@1 { | ||
| 305 | compatible = "cavium,octeon-3860-pip-port"; | ||
| 306 | reg = <0x1>; /* Port */ | ||
| 307 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 308 | phy-handle = <&phy12>; | ||
| 309 | }; | ||
| 310 | ethernet@2 { | ||
| 311 | compatible = "cavium,octeon-3860-pip-port"; | ||
| 312 | reg = <0x2>; /* Port */ | ||
| 313 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 314 | phy-handle = <&phy13>; | ||
| 315 | }; | ||
| 316 | ethernet@3 { | ||
| 317 | compatible = "cavium,octeon-3860-pip-port"; | ||
| 318 | reg = <0x3>; /* Port */ | ||
| 319 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 320 | phy-handle = <&phy14>; | ||
| 321 | }; | ||
| 322 | }; | ||
| 323 | |||
| 324 | interface@2 { | ||
| 325 | compatible = "cavium,octeon-3860-pip-interface"; | ||
| 326 | #address-cells = <1>; | ||
| 327 | #size-cells = <0>; | ||
| 328 | reg = <0x2>; /* interface */ | ||
| 329 | |||
| 330 | ethernet@0 { | ||
| 331 | compatible = "cavium,octeon-3860-pip-port"; | ||
| 332 | reg = <0x0>; /* Port */ | ||
| 333 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 334 | phy-handle = <&phy21>; | ||
| 335 | }; | ||
| 336 | ethernet@1 { | ||
| 337 | compatible = "cavium,octeon-3860-pip-port"; | ||
| 338 | reg = <0x1>; /* Port */ | ||
| 339 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 340 | phy-handle = <&phy22>; | ||
| 341 | }; | ||
| 342 | ethernet@2 { | ||
| 343 | compatible = "cavium,octeon-3860-pip-port"; | ||
| 344 | reg = <0x2>; /* Port */ | ||
| 345 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 346 | phy-handle = <&phy23>; | ||
| 347 | }; | ||
| 348 | ethernet@3 { | ||
| 349 | compatible = "cavium,octeon-3860-pip-port"; | ||
| 350 | reg = <0x3>; /* Port */ | ||
| 351 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 352 | phy-handle = <&phy24>; | ||
| 353 | }; | ||
| 354 | }; | ||
| 355 | |||
| 356 | interface@1 { | ||
| 357 | compatible = "cavium,octeon-3860-pip-interface"; | ||
| 358 | #address-cells = <1>; | ||
| 359 | #size-cells = <0>; | ||
| 360 | reg = <0x1>; /* interface */ | ||
| 361 | |||
| 362 | ethernet@0 { | ||
| 363 | compatible = "cavium,octeon-3860-pip-port"; | ||
| 364 | reg = <0x0>; /* Port */ | ||
| 365 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 366 | }; | ||
| 367 | }; | ||
| 368 | |||
| 369 | interface@0 { | ||
| 370 | compatible = "cavium,octeon-3860-pip-interface"; | ||
| 371 | #address-cells = <1>; | ||
| 372 | #size-cells = <0>; | ||
| 373 | reg = <0x0>; /* interface */ | ||
| 374 | |||
| 375 | ethernet@0 { | ||
| 376 | compatible = "cavium,octeon-3860-pip-port"; | ||
| 377 | reg = <0x0>; /* Port */ | ||
| 378 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 379 | phy-handle = <&phy41>; | ||
| 380 | }; | ||
| 381 | ethernet@1 { | ||
| 382 | compatible = "cavium,octeon-3860-pip-port"; | ||
| 383 | reg = <0x1>; /* Port */ | ||
| 384 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 385 | phy-handle = <&phy42>; | ||
| 386 | }; | ||
| 387 | ethernet@2 { | ||
| 388 | compatible = "cavium,octeon-3860-pip-port"; | ||
| 389 | reg = <0x2>; /* Port */ | ||
| 390 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 391 | phy-handle = <&phy43>; | ||
| 392 | }; | ||
| 393 | ethernet@3 { | ||
| 394 | compatible = "cavium,octeon-3860-pip-port"; | ||
| 395 | reg = <0x3>; /* Port */ | ||
| 396 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 397 | phy-handle = <&phy44>; | ||
| 398 | }; | ||
| 399 | }; | ||
| 400 | }; | ||
| 401 | |||
| 402 | twsi0: i2c@1180000001000 { | ||
| 403 | #address-cells = <1>; | ||
| 404 | #size-cells = <0>; | ||
| 405 | compatible = "cavium,octeon-3860-twsi"; | ||
| 406 | reg = <0x11800 0x00001000 0x0 0x200>; | ||
| 407 | interrupts = <3 32>; | ||
| 408 | clock-frequency = <100000>; | ||
| 409 | |||
| 410 | rtc@68 { | ||
| 411 | compatible = "dallas,ds1337"; | ||
| 412 | reg = <0x68>; | ||
| 413 | }; | ||
| 414 | tmp@4c { | ||
| 415 | compatible = "ti,tmp421"; | ||
| 416 | reg = <0x4c>; | ||
| 417 | }; | ||
| 418 | }; | ||
| 419 | |||
| 420 | twsi1: i2c@1180000001200 { | ||
| 421 | #address-cells = <1>; | ||
| 422 | #size-cells = <0>; | ||
| 423 | compatible = "cavium,octeon-3860-twsi"; | ||
| 424 | reg = <0x11800 0x00001200 0x0 0x200>; | ||
| 425 | interrupts = <3 33>; | ||
| 426 | clock-frequency = <100000>; | ||
| 427 | }; | ||
| 428 | |||
| 429 | uart0: serial@1180000000800 { | ||
| 430 | compatible = "cavium,octeon-3860-uart","ns16550"; | ||
| 431 | reg = <0x11800 0x00000800 0x0 0x400>; | ||
| 432 | clock-frequency = <0>; | ||
| 433 | current-speed = <115200>; | ||
| 434 | reg-shift = <3>; | ||
| 435 | interrupts = <3 36>; | ||
| 436 | }; | ||
| 437 | |||
| 438 | uart1: serial@1180000000c00 { | ||
| 439 | compatible = "cavium,octeon-3860-uart","ns16550"; | ||
| 440 | reg = <0x11800 0x00000c00 0x0 0x400>; | ||
| 441 | clock-frequency = <0>; | ||
| 442 | current-speed = <115200>; | ||
| 443 | reg-shift = <3>; | ||
| 444 | interrupts = <3 37>; | ||
| 445 | }; | ||
| 446 | |||
| 447 | bootbus: bootbus@1180000000000 { | ||
| 448 | compatible = "cavium,octeon-3860-bootbus"; | ||
| 449 | reg = <0x11800 0x00000000 0x0 0x200>; | ||
| 450 | /* The chip select number and offset */ | ||
| 451 | #address-cells = <2>; | ||
| 452 | /* The size of the chip select region */ | ||
| 453 | #size-cells = <1>; | ||
| 454 | ranges = <0 0 0 0x1f400000 0xc00000>, | ||
| 455 | <1 0 0x10000 0x30000000 0>, | ||
| 456 | <2 0 0x10000 0x40000000 0>, | ||
| 457 | <3 0 0x10000 0x50000000 0>, | ||
| 458 | <4 0 0 0x1d020000 0x10000>, | ||
| 459 | <5 0 0 0x1d040000 0x10000>, | ||
| 460 | <6 0 0 0x1d050000 0x10000>, | ||
| 461 | <7 0 0x10000 0x90000000 0>; | ||
| 462 | |||
| 463 | cavium,cs-config@0 { | ||
| 464 | compatible = "cavium,octeon-3860-bootbus-config"; | ||
| 465 | cavium,cs-index = <0>; | ||
| 466 | cavium,t-adr = <10>; | ||
| 467 | cavium,t-ce = <50>; | ||
| 468 | cavium,t-oe = <50>; | ||
| 469 | cavium,t-we = <35>; | ||
| 470 | cavium,t-rd-hld = <25>; | ||
| 471 | cavium,t-wr-hld = <35>; | ||
| 472 | cavium,t-pause = <0>; | ||
| 473 | cavium,t-wait = <300>; | ||
| 474 | cavium,t-page = <25>; | ||
| 475 | cavium,t-rd-dly = <0>; | ||
| 476 | |||
| 477 | cavium,pages = <0>; | ||
| 478 | cavium,bus-width = <8>; | ||
| 479 | }; | ||
| 480 | cavium,cs-config@4 { | ||
| 481 | compatible = "cavium,octeon-3860-bootbus-config"; | ||
| 482 | cavium,cs-index = <4>; | ||
| 483 | cavium,t-adr = <320>; | ||
| 484 | cavium,t-ce = <320>; | ||
| 485 | cavium,t-oe = <320>; | ||
| 486 | cavium,t-we = <320>; | ||
| 487 | cavium,t-rd-hld = <320>; | ||
| 488 | cavium,t-wr-hld = <320>; | ||
| 489 | cavium,t-pause = <320>; | ||
| 490 | cavium,t-wait = <320>; | ||
| 491 | cavium,t-page = <320>; | ||
| 492 | cavium,t-rd-dly = <0>; | ||
| 493 | |||
| 494 | cavium,pages = <0>; | ||
| 495 | cavium,bus-width = <8>; | ||
| 496 | }; | ||
| 497 | cavium,cs-config@5 { | ||
| 498 | compatible = "cavium,octeon-3860-bootbus-config"; | ||
| 499 | cavium,cs-index = <5>; | ||
| 500 | cavium,t-adr = <0>; | ||
| 501 | cavium,t-ce = <300>; | ||
| 502 | cavium,t-oe = <125>; | ||
| 503 | cavium,t-we = <150>; | ||
| 504 | cavium,t-rd-hld = <100>; | ||
| 505 | cavium,t-wr-hld = <300>; | ||
| 506 | cavium,t-pause = <0>; | ||
| 507 | cavium,t-wait = <300>; | ||
| 508 | cavium,t-page = <310>; | ||
| 509 | cavium,t-rd-dly = <0>; | ||
| 510 | |||
| 511 | cavium,pages = <0>; | ||
| 512 | cavium,bus-width = <16>; | ||
| 513 | }; | ||
| 514 | cavium,cs-config@6 { | ||
| 515 | compatible = "cavium,octeon-3860-bootbus-config"; | ||
| 516 | cavium,cs-index = <6>; | ||
| 517 | cavium,t-adr = <0>; | ||
| 518 | cavium,t-ce = <30>; | ||
| 519 | cavium,t-oe = <125>; | ||
| 520 | cavium,t-we = <150>; | ||
| 521 | cavium,t-rd-hld = <100>; | ||
| 522 | cavium,t-wr-hld = <30>; | ||
| 523 | cavium,t-pause = <0>; | ||
| 524 | cavium,t-wait = <30>; | ||
| 525 | cavium,t-page = <310>; | ||
| 526 | cavium,t-rd-dly = <0>; | ||
| 527 | |||
| 528 | cavium,pages = <0>; | ||
| 529 | cavium,wait-mode; | ||
| 530 | cavium,bus-width = <16>; | ||
| 531 | }; | ||
| 532 | |||
| 533 | flash0: nor@0,0 { | ||
| 534 | compatible = "cfi-flash"; | ||
| 535 | reg = <0 0 0x800000>; | ||
| 536 | #address-cells = <1>; | ||
| 537 | #size-cells = <1>; | ||
| 538 | |||
| 539 | partition@0 { | ||
| 540 | label = "bootloader"; | ||
| 541 | reg = <0 0x200000>; | ||
| 542 | read-only; | ||
| 543 | }; | ||
| 544 | partition@200000 { | ||
| 545 | label = "kernel"; | ||
| 546 | reg = <0x200000 0x200000>; | ||
| 547 | }; | ||
| 548 | partition@400000 { | ||
| 549 | label = "cramfs"; | ||
| 550 | reg = <0x400000 0x3fe000>; | ||
| 551 | }; | ||
| 552 | partition@7fe000 { | ||
| 553 | label = "environment"; | ||
| 554 | reg = <0x7fe000 0x2000>; | ||
| 555 | read-only; | ||
| 556 | }; | ||
| 557 | }; | ||
| 558 | |||
| 559 | led0: led-display@4,0 { | ||
| 560 | compatible = "avago,hdsp-253x"; | ||
| 561 | reg = <4 0x20 0x20>, <4 0 0x20>; | ||
| 562 | }; | ||
| 563 | |||
| 564 | compact-flash@5,0 { | ||
| 565 | compatible = "cavium,ebt3000-compact-flash"; | ||
| 566 | reg = <5 0 0x10000>, <6 0 0x10000>; | ||
| 567 | cavium,bus-width = <16>; | ||
| 568 | cavium,true-ide; | ||
| 569 | cavium,dma-engine-handle = <&dma0>; | ||
| 570 | }; | ||
| 571 | }; | ||
| 572 | |||
| 573 | dma0: dma-engine@1180000000100 { | ||
| 574 | compatible = "cavium,octeon-5750-bootbus-dma"; | ||
| 575 | reg = <0x11800 0x00000100 0x0 0x8>; | ||
| 576 | interrupts = <0 63>; | ||
| 577 | }; | ||
| 578 | dma1: dma-engine@1180000000108 { | ||
| 579 | compatible = "cavium,octeon-5750-bootbus-dma"; | ||
| 580 | reg = <0x11800 0x00000108 0x0 0x8>; | ||
| 581 | interrupts = <0 63>; | ||
| 582 | }; | ||
| 583 | |||
| 584 | uctl: uctl@118006f000000 { | ||
| 585 | compatible = "cavium,octeon-6335-uctl"; | ||
| 586 | reg = <0x11800 0x6f000000 0x0 0x100>; | ||
| 587 | ranges; /* Direct mapping */ | ||
| 588 | #address-cells = <2>; | ||
| 589 | #size-cells = <2>; | ||
| 590 | /* 12MHz, 24MHz and 48MHz allowed */ | ||
| 591 | refclk-frequency = <12000000>; | ||
| 592 | /* Either "crystal" or "external" */ | ||
| 593 | refclk-type = "crystal"; | ||
| 594 | |||
| 595 | ehci@16f0000000000 { | ||
| 596 | compatible = "cavium,octeon-6335-ehci","usb-ehci"; | ||
| 597 | reg = <0x16f00 0x00000000 0x0 0x100>; | ||
| 598 | interrupts = <3 44>; | ||
| 599 | big-endian-regs; | ||
| 600 | }; | ||
| 601 | ohci@16f0000000400 { | ||
| 602 | compatible = "cavium,octeon-6335-ohci","usb-ohci"; | ||
| 603 | reg = <0x16f00 0x00000400 0x0 0x100>; | ||
| 604 | interrupts = <3 44>; | ||
| 605 | big-endian-regs; | ||
| 606 | }; | ||
| 607 | }; | ||
| 608 | }; | ||
| 609 | |||
| 610 | aliases { | ||
| 611 | mix0 = &mix0; | ||
| 612 | pip = &pip; | ||
| 613 | smi0 = &smi0; | ||
| 614 | smi1 = &smi1; | ||
| 615 | smi2 = &smi2; | ||
| 616 | smi3 = &smi3; | ||
| 617 | twsi0 = &twsi0; | ||
| 618 | twsi1 = &twsi1; | ||
| 619 | uart0 = &uart0; | ||
| 620 | uart1 = &uart1; | ||
| 621 | uctl = &uctl; | ||
| 622 | led0 = &led0; | ||
| 623 | flash0 = &flash0; | ||
| 624 | }; | ||
| 625 | }; | ||
diff --git a/arch/mips/cavium-octeon/serial.c b/arch/mips/cavium-octeon/serial.c index 057f0ae88c99..138b2216b4f8 100644 --- a/arch/mips/cavium-octeon/serial.c +++ b/arch/mips/cavium-octeon/serial.c | |||
| @@ -43,95 +43,67 @@ void octeon_serial_out(struct uart_port *up, int offset, int value) | |||
| 43 | cvmx_write_csr((uint64_t)(up->membase + (offset << 3)), (u8)value); | 43 | cvmx_write_csr((uint64_t)(up->membase + (offset << 3)), (u8)value); |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | /* | 46 | static int __devinit octeon_serial_probe(struct platform_device *pdev) |
| 47 | * Allocated in .bss, so it is all zeroed. | ||
| 48 | */ | ||
| 49 | #define OCTEON_MAX_UARTS 3 | ||
| 50 | static struct plat_serial8250_port octeon_uart8250_data[OCTEON_MAX_UARTS + 1]; | ||
| 51 | static struct platform_device octeon_uart8250_device = { | ||
| 52 | .name = "serial8250", | ||
| 53 | .id = PLAT8250_DEV_PLATFORM, | ||
| 54 | .dev = { | ||
| 55 | .platform_data = octeon_uart8250_data, | ||
| 56 | }, | ||
| 57 | }; | ||
| 58 | |||
| 59 | static void __init octeon_uart_set_common(struct plat_serial8250_port *p) | ||
| 60 | { | 47 | { |
| 61 | p->flags = ASYNC_SKIP_TEST | UPF_SHARE_IRQ | UPF_FIXED_TYPE; | 48 | int irq, res; |
| 62 | p->type = PORT_OCTEON; | 49 | struct resource *res_mem; |
| 63 | p->iotype = UPIO_MEM; | 50 | struct uart_port port; |
| 64 | p->regshift = 3; /* I/O addresses are every 8 bytes */ | 51 | |
| 52 | /* All adaptors have an irq. */ | ||
| 53 | irq = platform_get_irq(pdev, 0); | ||
| 54 | if (irq < 0) | ||
| 55 | return irq; | ||
| 56 | |||
| 57 | memset(&port, 0, sizeof(port)); | ||
| 58 | |||
| 59 | port.flags = ASYNC_SKIP_TEST | UPF_SHARE_IRQ | UPF_FIXED_TYPE; | ||
| 60 | port.type = PORT_OCTEON; | ||
| 61 | port.iotype = UPIO_MEM; | ||
| 62 | port.regshift = 3; | ||
| 63 | port.dev = &pdev->dev; | ||
| 64 | |||
| 65 | if (octeon_is_simulation()) | 65 | if (octeon_is_simulation()) |
| 66 | /* Make simulator output fast*/ | 66 | /* Make simulator output fast*/ |
| 67 | p->uartclk = 115200 * 16; | 67 | port.uartclk = 115200 * 16; |
| 68 | else | 68 | else |
| 69 | p->uartclk = octeon_get_io_clock_rate(); | 69 | port.uartclk = octeon_get_io_clock_rate(); |
| 70 | p->serial_in = octeon_serial_in; | ||
| 71 | p->serial_out = octeon_serial_out; | ||
| 72 | } | ||
| 73 | 70 | ||
| 74 | static int __init octeon_serial_init(void) | 71 | port.serial_in = octeon_serial_in; |
| 75 | { | 72 | port.serial_out = octeon_serial_out; |
| 76 | int enable_uart0; | 73 | port.irq = irq; |
| 77 | int enable_uart1; | ||
| 78 | int enable_uart2; | ||
| 79 | struct plat_serial8250_port *p; | ||
| 80 | |||
| 81 | #ifdef CONFIG_CAVIUM_OCTEON_2ND_KERNEL | ||
| 82 | /* | ||
| 83 | * If we are configured to run as the second of two kernels, | ||
| 84 | * disable uart0 and enable uart1. Uart0 is owned by the first | ||
| 85 | * kernel | ||
| 86 | */ | ||
| 87 | enable_uart0 = 0; | ||
| 88 | enable_uart1 = 1; | ||
| 89 | #else | ||
| 90 | /* | ||
| 91 | * We are configured for the first kernel. We'll enable uart0 | ||
| 92 | * if the bootloader told us to use 0, otherwise will enable | ||
| 93 | * uart 1. | ||
| 94 | */ | ||
| 95 | enable_uart0 = (octeon_get_boot_uart() == 0); | ||
| 96 | enable_uart1 = (octeon_get_boot_uart() == 1); | ||
| 97 | #ifdef CONFIG_KGDB | ||
| 98 | enable_uart1 = 1; | ||
| 99 | #endif | ||
| 100 | #endif | ||
| 101 | |||
| 102 | /* Right now CN52XX is the only chip with a third uart */ | ||
| 103 | enable_uart2 = OCTEON_IS_MODEL(OCTEON_CN52XX); | ||
| 104 | |||
| 105 | p = octeon_uart8250_data; | ||
| 106 | if (enable_uart0) { | ||
| 107 | /* Add a ttyS device for hardware uart 0 */ | ||
| 108 | octeon_uart_set_common(p); | ||
| 109 | p->membase = (void *) CVMX_MIO_UARTX_RBR(0); | ||
| 110 | p->mapbase = CVMX_MIO_UARTX_RBR(0) & ((1ull << 49) - 1); | ||
| 111 | p->irq = OCTEON_IRQ_UART0; | ||
| 112 | p++; | ||
| 113 | } | ||
| 114 | 74 | ||
| 115 | if (enable_uart1) { | 75 | res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 116 | /* Add a ttyS device for hardware uart 1 */ | 76 | if (res_mem == NULL) { |
| 117 | octeon_uart_set_common(p); | 77 | dev_err(&pdev->dev, "found no memory resource\n"); |
| 118 | p->membase = (void *) CVMX_MIO_UARTX_RBR(1); | 78 | return -ENXIO; |
| 119 | p->mapbase = CVMX_MIO_UARTX_RBR(1) & ((1ull << 49) - 1); | ||
| 120 | p->irq = OCTEON_IRQ_UART1; | ||
| 121 | p++; | ||
| 122 | } | ||
| 123 | if (enable_uart2) { | ||
| 124 | /* Add a ttyS device for hardware uart 2 */ | ||
| 125 | octeon_uart_set_common(p); | ||
| 126 | p->membase = (void *) CVMX_MIO_UART2_RBR; | ||
| 127 | p->mapbase = CVMX_MIO_UART2_RBR & ((1ull << 49) - 1); | ||
| 128 | p->irq = OCTEON_IRQ_UART2; | ||
| 129 | p++; | ||
| 130 | } | 79 | } |
| 80 | port.mapbase = res_mem->start; | ||
| 81 | port.membase = ioremap(res_mem->start, resource_size(res_mem)); | ||
| 131 | 82 | ||
| 132 | BUG_ON(p > &octeon_uart8250_data[OCTEON_MAX_UARTS]); | 83 | res = serial8250_register_port(&port); |
| 133 | 84 | ||
| 134 | return platform_device_register(&octeon_uart8250_device); | 85 | return res >= 0 ? 0 : res; |
| 135 | } | 86 | } |
| 136 | 87 | ||
| 137 | device_initcall(octeon_serial_init); | 88 | static struct of_device_id octeon_serial_match[] = { |
| 89 | { | ||
| 90 | .compatible = "cavium,octeon-3860-uart", | ||
| 91 | }, | ||
| 92 | {}, | ||
| 93 | }; | ||
| 94 | MODULE_DEVICE_TABLE(of, octeon_serial_match); | ||
| 95 | |||
| 96 | static struct platform_driver octeon_serial_driver = { | ||
| 97 | .probe = octeon_serial_probe, | ||
| 98 | .driver = { | ||
| 99 | .owner = THIS_MODULE, | ||
| 100 | .name = "octeon_serial", | ||
| 101 | .of_match_table = octeon_serial_match, | ||
| 102 | }, | ||
| 103 | }; | ||
| 104 | |||
| 105 | static int __init octeon_serial_init(void) | ||
| 106 | { | ||
| 107 | return platform_driver_register(&octeon_serial_driver); | ||
| 108 | } | ||
| 109 | late_initcall(octeon_serial_init); | ||
diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c index 260dc247c052..919b0fb7bb1a 100644 --- a/arch/mips/cavium-octeon/setup.c +++ b/arch/mips/cavium-octeon/setup.c | |||
| @@ -21,6 +21,8 @@ | |||
| 21 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
| 22 | #include <linux/serial_core.h> | 22 | #include <linux/serial_core.h> |
| 23 | #include <linux/serial_8250.h> | 23 | #include <linux/serial_8250.h> |
| 24 | #include <linux/of_fdt.h> | ||
| 25 | #include <linux/libfdt.h> | ||
| 24 | 26 | ||
| 25 | #include <asm/processor.h> | 27 | #include <asm/processor.h> |
| 26 | #include <asm/reboot.h> | 28 | #include <asm/reboot.h> |
| @@ -775,3 +777,46 @@ void prom_free_prom_memory(void) | |||
| 775 | } | 777 | } |
| 776 | #endif | 778 | #endif |
| 777 | } | 779 | } |
| 780 | |||
| 781 | int octeon_prune_device_tree(void); | ||
| 782 | |||
| 783 | extern const char __dtb_octeon_3xxx_begin; | ||
| 784 | extern const char __dtb_octeon_3xxx_end; | ||
| 785 | extern const char __dtb_octeon_68xx_begin; | ||
| 786 | extern const char __dtb_octeon_68xx_end; | ||
| 787 | void __init device_tree_init(void) | ||
| 788 | { | ||
| 789 | int dt_size; | ||
| 790 | struct boot_param_header *fdt; | ||
| 791 | bool do_prune; | ||
| 792 | |||
| 793 | if (octeon_bootinfo->minor_version >= 3 && octeon_bootinfo->fdt_addr) { | ||
| 794 | fdt = phys_to_virt(octeon_bootinfo->fdt_addr); | ||
| 795 | if (fdt_check_header(fdt)) | ||
| 796 | panic("Corrupt Device Tree passed to kernel."); | ||
| 797 | dt_size = be32_to_cpu(fdt->totalsize); | ||
| 798 | do_prune = false; | ||
| 799 | } else if (OCTEON_IS_MODEL(OCTEON_CN68XX)) { | ||
| 800 | fdt = (struct boot_param_header *)&__dtb_octeon_68xx_begin; | ||
| 801 | dt_size = &__dtb_octeon_68xx_end - &__dtb_octeon_68xx_begin; | ||
| 802 | do_prune = true; | ||
| 803 | } else { | ||
| 804 | fdt = (struct boot_param_header *)&__dtb_octeon_3xxx_begin; | ||
| 805 | dt_size = &__dtb_octeon_3xxx_end - &__dtb_octeon_3xxx_begin; | ||
| 806 | do_prune = true; | ||
| 807 | } | ||
| 808 | |||
| 809 | /* Copy the default tree from init memory. */ | ||
| 810 | initial_boot_params = early_init_dt_alloc_memory_arch(dt_size, 8); | ||
| 811 | if (initial_boot_params == NULL) | ||
| 812 | panic("Could not allocate initial_boot_params\n"); | ||
| 813 | memcpy(initial_boot_params, fdt, dt_size); | ||
| 814 | |||
| 815 | if (do_prune) { | ||
| 816 | octeon_prune_device_tree(); | ||
| 817 | pr_info("Using internal Device Tree.\n"); | ||
| 818 | } else { | ||
| 819 | pr_info("Using passed Device Tree.\n"); | ||
| 820 | } | ||
| 821 | unflatten_device_tree(); | ||
| 822 | } | ||
diff --git a/arch/mips/configs/ls1b_defconfig b/arch/mips/configs/ls1b_defconfig new file mode 100644 index 000000000000..80cff8bea8e8 --- /dev/null +++ b/arch/mips/configs/ls1b_defconfig | |||
| @@ -0,0 +1,109 @@ | |||
| 1 | CONFIG_MACH_LOONGSON1=y | ||
| 2 | CONFIG_PREEMPT=y | ||
| 3 | # CONFIG_SECCOMP is not set | ||
| 4 | CONFIG_EXPERIMENTAL=y | ||
| 5 | # CONFIG_LOCALVERSION_AUTO is not set | ||
| 6 | CONFIG_SYSVIPC=y | ||
| 7 | CONFIG_BSD_PROCESS_ACCT=y | ||
| 8 | CONFIG_BSD_PROCESS_ACCT_V3=y | ||
| 9 | CONFIG_HIGH_RES_TIMERS=y | ||
| 10 | CONFIG_IKCONFIG=y | ||
| 11 | CONFIG_IKCONFIG_PROC=y | ||
| 12 | CONFIG_LOG_BUF_SHIFT=16 | ||
| 13 | CONFIG_NAMESPACES=y | ||
| 14 | CONFIG_BLK_DEV_INITRD=y | ||
| 15 | CONFIG_RD_BZIP2=y | ||
| 16 | CONFIG_RD_LZMA=y | ||
| 17 | CONFIG_EXPERT=y | ||
| 18 | CONFIG_PERF_EVENTS=y | ||
| 19 | # CONFIG_COMPAT_BRK is not set | ||
| 20 | CONFIG_MODULES=y | ||
| 21 | CONFIG_MODULE_UNLOAD=y | ||
| 22 | CONFIG_MODVERSIONS=y | ||
| 23 | # CONFIG_LBDAF is not set | ||
| 24 | # CONFIG_BLK_DEV_BSG is not set | ||
| 25 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set | ||
| 26 | # CONFIG_SUSPEND is not set | ||
| 27 | CONFIG_NET=y | ||
| 28 | CONFIG_PACKET=y | ||
| 29 | CONFIG_UNIX=y | ||
| 30 | CONFIG_INET=y | ||
| 31 | CONFIG_IP_PNP=y | ||
| 32 | CONFIG_IP_PNP_DHCP=y | ||
| 33 | CONFIG_SYN_COOKIES=y | ||
| 34 | # CONFIG_INET_XFRM_MODE_TRANSPORT is not set | ||
| 35 | # CONFIG_INET_XFRM_MODE_TUNNEL is not set | ||
| 36 | # CONFIG_INET_XFRM_MODE_BEET is not set | ||
| 37 | # CONFIG_INET_DIAG is not set | ||
| 38 | # CONFIG_IPV6 is not set | ||
| 39 | # CONFIG_WIRELESS is not set | ||
| 40 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||
| 41 | CONFIG_DEVTMPFS=y | ||
| 42 | CONFIG_DEVTMPFS_MOUNT=y | ||
| 43 | # CONFIG_STANDALONE is not set | ||
| 44 | CONFIG_BLK_DEV_LOOP=y | ||
| 45 | CONFIG_SCSI=m | ||
| 46 | # CONFIG_SCSI_PROC_FS is not set | ||
| 47 | CONFIG_BLK_DEV_SD=m | ||
| 48 | # CONFIG_SCSI_LOWLEVEL is not set | ||
| 49 | CONFIG_NETDEVICES=y | ||
| 50 | # CONFIG_NET_VENDOR_BROADCOM is not set | ||
| 51 | # CONFIG_NET_VENDOR_CHELSIO is not set | ||
| 52 | # CONFIG_NET_VENDOR_INTEL is not set | ||
| 53 | # CONFIG_NET_VENDOR_MARVELL is not set | ||
| 54 | # CONFIG_NET_VENDOR_MICREL is not set | ||
| 55 | # CONFIG_NET_VENDOR_NATSEMI is not set | ||
| 56 | # CONFIG_NET_VENDOR_SEEQ is not set | ||
| 57 | # CONFIG_NET_VENDOR_SMSC is not set | ||
| 58 | CONFIG_STMMAC_ETH=y | ||
| 59 | CONFIG_STMMAC_DA=y | ||
| 60 | # CONFIG_NET_VENDOR_WIZNET is not set | ||
| 61 | # CONFIG_WLAN is not set | ||
| 62 | CONFIG_INPUT_EVDEV=y | ||
| 63 | # CONFIG_INPUT_KEYBOARD is not set | ||
| 64 | # CONFIG_INPUT_MOUSE is not set | ||
| 65 | # CONFIG_SERIO is not set | ||
| 66 | CONFIG_VT_HW_CONSOLE_BINDING=y | ||
| 67 | CONFIG_LEGACY_PTY_COUNT=8 | ||
| 68 | # CONFIG_DEVKMEM is not set | ||
| 69 | CONFIG_SERIAL_8250=y | ||
| 70 | CONFIG_SERIAL_8250_CONSOLE=y | ||
| 71 | # CONFIG_HW_RANDOM is not set | ||
| 72 | # CONFIG_HWMON is not set | ||
| 73 | # CONFIG_VGA_CONSOLE is not set | ||
| 74 | CONFIG_USB_HID=m | ||
| 75 | CONFIG_HID_GENERIC=m | ||
| 76 | CONFIG_USB=y | ||
| 77 | CONFIG_USB_ANNOUNCE_NEW_DEVICES=y | ||
| 78 | CONFIG_USB_EHCI_HCD=y | ||
| 79 | # CONFIG_USB_EHCI_TT_NEWSCHED is not set | ||
| 80 | CONFIG_USB_STORAGE=m | ||
| 81 | CONFIG_USB_SERIAL=m | ||
| 82 | CONFIG_USB_SERIAL_PL2303=m | ||
| 83 | CONFIG_RTC_CLASS=y | ||
| 84 | CONFIG_RTC_DRV_LOONGSON1=y | ||
| 85 | # CONFIG_IOMMU_SUPPORT is not set | ||
| 86 | CONFIG_EXT2_FS=y | ||
| 87 | CONFIG_EXT2_FS_XATTR=y | ||
| 88 | CONFIG_EXT2_FS_POSIX_ACL=y | ||
| 89 | CONFIG_EXT2_FS_SECURITY=y | ||
| 90 | CONFIG_EXT3_FS=y | ||
| 91 | CONFIG_EXT3_FS_POSIX_ACL=y | ||
| 92 | CONFIG_EXT3_FS_SECURITY=y | ||
| 93 | # CONFIG_DNOTIFY is not set | ||
| 94 | CONFIG_VFAT_FS=y | ||
| 95 | CONFIG_PROC_KCORE=y | ||
| 96 | CONFIG_TMPFS=y | ||
| 97 | CONFIG_TMPFS_POSIX_ACL=y | ||
| 98 | # CONFIG_MISC_FILESYSTEMS is not set | ||
| 99 | CONFIG_NFS_FS=y | ||
| 100 | CONFIG_ROOT_NFS=y | ||
| 101 | CONFIG_NLS_CODEPAGE_437=m | ||
| 102 | CONFIG_NLS_ISO8859_1=m | ||
| 103 | # CONFIG_ENABLE_WARN_DEPRECATED is not set | ||
| 104 | # CONFIG_ENABLE_MUST_CHECK is not set | ||
| 105 | CONFIG_MAGIC_SYSRQ=y | ||
| 106 | # CONFIG_SCHED_DEBUG is not set | ||
| 107 | # CONFIG_DEBUG_PREEMPT is not set | ||
| 108 | # CONFIG_FTRACE is not set | ||
| 109 | # CONFIG_EARLY_PRINTK is not set | ||
diff --git a/arch/mips/configs/nlm_xlr_defconfig b/arch/mips/configs/nlm_xlr_defconfig index d0b857d98c91..138f698d7c00 100644 --- a/arch/mips/configs/nlm_xlr_defconfig +++ b/arch/mips/configs/nlm_xlr_defconfig | |||
| @@ -367,6 +367,10 @@ CONFIG_SERIAL_8250_RSA=y | |||
| 367 | CONFIG_HW_RANDOM=y | 367 | CONFIG_HW_RANDOM=y |
| 368 | CONFIG_HW_RANDOM_TIMERIOMEM=m | 368 | CONFIG_HW_RANDOM_TIMERIOMEM=m |
| 369 | CONFIG_RAW_DRIVER=m | 369 | CONFIG_RAW_DRIVER=m |
| 370 | CONFIG_I2C=y | ||
| 371 | CONFIG_I2C_XLR=y | ||
| 372 | CONFIG_RTC_CLASS=y | ||
| 373 | CONFIG_RTC_DRV_DS1374=y | ||
| 370 | # CONFIG_HWMON is not set | 374 | # CONFIG_HWMON is not set |
| 371 | # CONFIG_VGA_CONSOLE is not set | 375 | # CONFIG_VGA_CONSOLE is not set |
| 372 | # CONFIG_HID_SUPPORT is not set | 376 | # CONFIG_HID_SUPPORT is not set |
diff --git a/arch/mips/dec/prom/memory.c b/arch/mips/dec/prom/memory.c index e95ff3054ff6..8c62316f22f4 100644 --- a/arch/mips/dec/prom/memory.c +++ b/arch/mips/dec/prom/memory.c | |||
| @@ -101,7 +101,7 @@ void __init prom_free_prom_memory(void) | |||
| 101 | * the first page reserved for the exception handlers. | 101 | * the first page reserved for the exception handlers. |
| 102 | */ | 102 | */ |
| 103 | 103 | ||
| 104 | #if defined(CONFIG_DECLANCE) || defined(CONFIG_DECLANCE_MODULE) | 104 | #if IS_ENABLED(CONFIG_DECLANCE) |
| 105 | /* | 105 | /* |
| 106 | * Leave 128 KB reserved for Lance memory for | 106 | * Leave 128 KB reserved for Lance memory for |
| 107 | * IOASIC DECstations. | 107 | * IOASIC DECstations. |
diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h index 95e40c1e8ed1..f21b7c04e95a 100644 --- a/arch/mips/include/asm/cpu.h +++ b/arch/mips/include/asm/cpu.h | |||
| @@ -197,6 +197,7 @@ | |||
| 197 | #define PRID_REV_VR4181A 0x0070 /* Same as VR4122 */ | 197 | #define PRID_REV_VR4181A 0x0070 /* Same as VR4122 */ |
| 198 | #define PRID_REV_VR4130 0x0080 | 198 | #define PRID_REV_VR4130 0x0080 |
| 199 | #define PRID_REV_34K_V1_0_2 0x0022 | 199 | #define PRID_REV_34K_V1_0_2 0x0022 |
| 200 | #define PRID_REV_LOONGSON1B 0x0020 | ||
| 200 | #define PRID_REV_LOONGSON2E 0x0002 | 201 | #define PRID_REV_LOONGSON2E 0x0002 |
| 201 | #define PRID_REV_LOONGSON2F 0x0003 | 202 | #define PRID_REV_LOONGSON2F 0x0003 |
| 202 | 203 | ||
| @@ -261,7 +262,7 @@ enum cpu_type_enum { | |||
| 261 | */ | 262 | */ |
| 262 | CPU_4KC, CPU_4KEC, CPU_4KSC, CPU_24K, CPU_34K, CPU_1004K, CPU_74K, | 263 | CPU_4KC, CPU_4KEC, CPU_4KSC, CPU_24K, CPU_34K, CPU_1004K, CPU_74K, |
| 263 | CPU_ALCHEMY, CPU_PR4450, CPU_BMIPS32, CPU_BMIPS3300, CPU_BMIPS4350, | 264 | CPU_ALCHEMY, CPU_PR4450, CPU_BMIPS32, CPU_BMIPS3300, CPU_BMIPS4350, |
| 264 | CPU_BMIPS4380, CPU_BMIPS5000, CPU_JZRISC, CPU_M14KC, | 265 | CPU_BMIPS4380, CPU_BMIPS5000, CPU_JZRISC, CPU_LOONGSON1, CPU_M14KC, |
| 265 | 266 | ||
| 266 | /* | 267 | /* |
| 267 | * MIPS64 class processors | 268 | * MIPS64 class processors |
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h index 5b8d15bb5fe8..e104ddb694a8 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | * compile time if only one CPU support is enabled (idea stolen from | 9 | * compile time if only one CPU support is enabled (idea stolen from |
| 10 | * arm mach-types) | 10 | * arm mach-types) |
| 11 | */ | 11 | */ |
| 12 | #define BCM6328_CPU_ID 0x6328 | ||
| 12 | #define BCM6338_CPU_ID 0x6338 | 13 | #define BCM6338_CPU_ID 0x6338 |
| 13 | #define BCM6345_CPU_ID 0x6345 | 14 | #define BCM6345_CPU_ID 0x6345 |
| 14 | #define BCM6348_CPU_ID 0x6348 | 15 | #define BCM6348_CPU_ID 0x6348 |
| @@ -20,6 +21,19 @@ u16 __bcm63xx_get_cpu_id(void); | |||
| 20 | u16 bcm63xx_get_cpu_rev(void); | 21 | u16 bcm63xx_get_cpu_rev(void); |
| 21 | unsigned int bcm63xx_get_cpu_freq(void); | 22 | unsigned int bcm63xx_get_cpu_freq(void); |
| 22 | 23 | ||
| 24 | #ifdef CONFIG_BCM63XX_CPU_6328 | ||
| 25 | # ifdef bcm63xx_get_cpu_id | ||
| 26 | # undef bcm63xx_get_cpu_id | ||
| 27 | # define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id() | ||
| 28 | # define BCMCPU_RUNTIME_DETECT | ||
| 29 | # else | ||
| 30 | # define bcm63xx_get_cpu_id() BCM6328_CPU_ID | ||
| 31 | # endif | ||
| 32 | # define BCMCPU_IS_6328() (bcm63xx_get_cpu_id() == BCM6328_CPU_ID) | ||
| 33 | #else | ||
| 34 | # define BCMCPU_IS_6328() (0) | ||
| 35 | #endif | ||
| 36 | |||
| 23 | #ifdef CONFIG_BCM63XX_CPU_6338 | 37 | #ifdef CONFIG_BCM63XX_CPU_6338 |
| 24 | # ifdef bcm63xx_get_cpu_id | 38 | # ifdef bcm63xx_get_cpu_id |
| 25 | # undef bcm63xx_get_cpu_id | 39 | # undef bcm63xx_get_cpu_id |
| @@ -102,13 +116,13 @@ enum bcm63xx_regs_set { | |||
| 102 | RSET_UART1, | 116 | RSET_UART1, |
| 103 | RSET_GPIO, | 117 | RSET_GPIO, |
| 104 | RSET_SPI, | 118 | RSET_SPI, |
| 105 | RSET_SPI2, | ||
| 106 | RSET_UDC0, | 119 | RSET_UDC0, |
| 107 | RSET_OHCI0, | 120 | RSET_OHCI0, |
| 108 | RSET_OHCI_PRIV, | 121 | RSET_OHCI_PRIV, |
| 109 | RSET_USBH_PRIV, | 122 | RSET_USBH_PRIV, |
| 110 | RSET_MPI, | 123 | RSET_MPI, |
| 111 | RSET_PCMCIA, | 124 | RSET_PCMCIA, |
| 125 | RSET_PCIE, | ||
| 112 | RSET_DSL, | 126 | RSET_DSL, |
| 113 | RSET_ENET0, | 127 | RSET_ENET0, |
| 114 | RSET_ENET1, | 128 | RSET_ENET1, |
| @@ -130,11 +144,17 @@ enum bcm63xx_regs_set { | |||
| 130 | RSET_PCMDMA, | 144 | RSET_PCMDMA, |
| 131 | RSET_PCMDMAC, | 145 | RSET_PCMDMAC, |
| 132 | RSET_PCMDMAS, | 146 | RSET_PCMDMAS, |
| 147 | RSET_RNG, | ||
| 148 | RSET_MISC | ||
| 133 | }; | 149 | }; |
| 134 | 150 | ||
| 135 | #define RSET_DSL_LMEM_SIZE (64 * 1024 * 4) | 151 | #define RSET_DSL_LMEM_SIZE (64 * 1024 * 4) |
| 136 | #define RSET_DSL_SIZE 4096 | 152 | #define RSET_DSL_SIZE 4096 |
| 137 | #define RSET_WDT_SIZE 12 | 153 | #define RSET_WDT_SIZE 12 |
| 154 | #define BCM_6338_RSET_SPI_SIZE 64 | ||
| 155 | #define BCM_6348_RSET_SPI_SIZE 64 | ||
| 156 | #define BCM_6358_RSET_SPI_SIZE 1804 | ||
| 157 | #define BCM_6368_RSET_SPI_SIZE 1804 | ||
| 138 | #define RSET_ENET_SIZE 2048 | 158 | #define RSET_ENET_SIZE 2048 |
| 139 | #define RSET_ENETDMA_SIZE 2048 | 159 | #define RSET_ENETDMA_SIZE 2048 |
| 140 | #define RSET_ENETSW_SIZE 65536 | 160 | #define RSET_ENETSW_SIZE 65536 |
| @@ -149,8 +169,53 @@ enum bcm63xx_regs_set { | |||
| 149 | #define RSET_XTMDMA_SIZE 256 | 169 | #define RSET_XTMDMA_SIZE 256 |
| 150 | #define RSET_XTMDMAC_SIZE(chans) (16 * (chans)) | 170 | #define RSET_XTMDMAC_SIZE(chans) (16 * (chans)) |
| 151 | #define RSET_XTMDMAS_SIZE(chans) (16 * (chans)) | 171 | #define RSET_XTMDMAS_SIZE(chans) (16 * (chans)) |
| 172 | #define RSET_RNG_SIZE 20 | ||
| 152 | 173 | ||
| 153 | /* | 174 | /* |
| 175 | * 6328 register sets base address | ||
| 176 | */ | ||
| 177 | #define BCM_6328_DSL_LMEM_BASE (0xdeadbeef) | ||
| 178 | #define BCM_6328_PERF_BASE (0xb0000000) | ||
| 179 | #define BCM_6328_TIMER_BASE (0xb0000040) | ||
| 180 | #define BCM_6328_WDT_BASE (0xb000005c) | ||
| 181 | #define BCM_6328_UART0_BASE (0xb0000100) | ||
| 182 | #define BCM_6328_UART1_BASE (0xb0000120) | ||
| 183 | #define BCM_6328_GPIO_BASE (0xb0000080) | ||
| 184 | #define BCM_6328_SPI_BASE (0xdeadbeef) | ||
| 185 | #define BCM_6328_UDC0_BASE (0xdeadbeef) | ||
| 186 | #define BCM_6328_USBDMA_BASE (0xdeadbeef) | ||
| 187 | #define BCM_6328_OHCI0_BASE (0xdeadbeef) | ||
| 188 | #define BCM_6328_OHCI_PRIV_BASE (0xdeadbeef) | ||
| 189 | #define BCM_6328_USBH_PRIV_BASE (0xdeadbeef) | ||
| 190 | #define BCM_6328_MPI_BASE (0xdeadbeef) | ||
| 191 | #define BCM_6328_PCMCIA_BASE (0xdeadbeef) | ||
| 192 | #define BCM_6328_PCIE_BASE (0xb0e40000) | ||
| 193 | #define BCM_6328_SDRAM_REGS_BASE (0xdeadbeef) | ||
| 194 | #define BCM_6328_DSL_BASE (0xb0001900) | ||
| 195 | #define BCM_6328_UBUS_BASE (0xdeadbeef) | ||
| 196 | #define BCM_6328_ENET0_BASE (0xdeadbeef) | ||
| 197 | #define BCM_6328_ENET1_BASE (0xdeadbeef) | ||
| 198 | #define BCM_6328_ENETDMA_BASE (0xb000d800) | ||
| 199 | #define BCM_6328_ENETDMAC_BASE (0xb000da00) | ||
| 200 | #define BCM_6328_ENETDMAS_BASE (0xb000dc00) | ||
| 201 | #define BCM_6328_ENETSW_BASE (0xb0e00000) | ||
| 202 | #define BCM_6328_EHCI0_BASE (0x10002500) | ||
| 203 | #define BCM_6328_SDRAM_BASE (0xdeadbeef) | ||
| 204 | #define BCM_6328_MEMC_BASE (0xdeadbeef) | ||
| 205 | #define BCM_6328_DDR_BASE (0xb0003000) | ||
| 206 | #define BCM_6328_M2M_BASE (0xdeadbeef) | ||
| 207 | #define BCM_6328_ATM_BASE (0xdeadbeef) | ||
| 208 | #define BCM_6328_XTM_BASE (0xdeadbeef) | ||
| 209 | #define BCM_6328_XTMDMA_BASE (0xb000b800) | ||
| 210 | #define BCM_6328_XTMDMAC_BASE (0xdeadbeef) | ||
| 211 | #define BCM_6328_XTMDMAS_BASE (0xdeadbeef) | ||
| 212 | #define BCM_6328_PCM_BASE (0xb000a800) | ||
| 213 | #define BCM_6328_PCMDMA_BASE (0xdeadbeef) | ||
| 214 | #define BCM_6328_PCMDMAC_BASE (0xdeadbeef) | ||
| 215 | #define BCM_6328_PCMDMAS_BASE (0xdeadbeef) | ||
| 216 | #define BCM_6328_RNG_BASE (0xdeadbeef) | ||
| 217 | #define BCM_6328_MISC_BASE (0xb0001800) | ||
| 218 | /* | ||
| 154 | * 6338 register sets base address | 219 | * 6338 register sets base address |
| 155 | */ | 220 | */ |
| 156 | #define BCM_6338_DSL_LMEM_BASE (0xfff00000) | 221 | #define BCM_6338_DSL_LMEM_BASE (0xfff00000) |
| @@ -162,7 +227,6 @@ enum bcm63xx_regs_set { | |||
| 162 | #define BCM_6338_UART1_BASE (0xdeadbeef) | 227 | #define BCM_6338_UART1_BASE (0xdeadbeef) |
| 163 | #define BCM_6338_GPIO_BASE (0xfffe0400) | 228 | #define BCM_6338_GPIO_BASE (0xfffe0400) |
| 164 | #define BCM_6338_SPI_BASE (0xfffe0c00) | 229 | #define BCM_6338_SPI_BASE (0xfffe0c00) |
| 165 | #define BCM_6338_SPI2_BASE (0xdeadbeef) | ||
| 166 | #define BCM_6338_UDC0_BASE (0xdeadbeef) | 230 | #define BCM_6338_UDC0_BASE (0xdeadbeef) |
| 167 | #define BCM_6338_USBDMA_BASE (0xfffe2400) | 231 | #define BCM_6338_USBDMA_BASE (0xfffe2400) |
| 168 | #define BCM_6338_OHCI0_BASE (0xdeadbeef) | 232 | #define BCM_6338_OHCI0_BASE (0xdeadbeef) |
| @@ -170,6 +234,7 @@ enum bcm63xx_regs_set { | |||
| 170 | #define BCM_6338_USBH_PRIV_BASE (0xdeadbeef) | 234 | #define BCM_6338_USBH_PRIV_BASE (0xdeadbeef) |
| 171 | #define BCM_6338_MPI_BASE (0xfffe3160) | 235 | #define BCM_6338_MPI_BASE (0xfffe3160) |
| 172 | #define BCM_6338_PCMCIA_BASE (0xdeadbeef) | 236 | #define BCM_6338_PCMCIA_BASE (0xdeadbeef) |
| 237 | #define BCM_6338_PCIE_BASE (0xdeadbeef) | ||
| 173 | #define BCM_6338_SDRAM_REGS_BASE (0xfffe3100) | 238 | #define BCM_6338_SDRAM_REGS_BASE (0xfffe3100) |
| 174 | #define BCM_6338_DSL_BASE (0xfffe1000) | 239 | #define BCM_6338_DSL_BASE (0xfffe1000) |
| 175 | #define BCM_6338_UBUS_BASE (0xdeadbeef) | 240 | #define BCM_6338_UBUS_BASE (0xdeadbeef) |
| @@ -193,6 +258,8 @@ enum bcm63xx_regs_set { | |||
| 193 | #define BCM_6338_PCMDMA_BASE (0xdeadbeef) | 258 | #define BCM_6338_PCMDMA_BASE (0xdeadbeef) |
| 194 | #define BCM_6338_PCMDMAC_BASE (0xdeadbeef) | 259 | #define BCM_6338_PCMDMAC_BASE (0xdeadbeef) |
| 195 | #define BCM_6338_PCMDMAS_BASE (0xdeadbeef) | 260 | #define BCM_6338_PCMDMAS_BASE (0xdeadbeef) |
| 261 | #define BCM_6338_RNG_BASE (0xdeadbeef) | ||
| 262 | #define BCM_6338_MISC_BASE (0xdeadbeef) | ||
| 196 | 263 | ||
| 197 | /* | 264 | /* |
| 198 | * 6345 register sets base address | 265 | * 6345 register sets base address |
| @@ -206,7 +273,6 @@ enum bcm63xx_regs_set { | |||
| 206 | #define BCM_6345_UART1_BASE (0xdeadbeef) | 273 | #define BCM_6345_UART1_BASE (0xdeadbeef) |
| 207 | #define BCM_6345_GPIO_BASE (0xfffe0400) | 274 | #define BCM_6345_GPIO_BASE (0xfffe0400) |
| 208 | #define BCM_6345_SPI_BASE (0xdeadbeef) | 275 | #define BCM_6345_SPI_BASE (0xdeadbeef) |
| 209 | #define BCM_6345_SPI2_BASE (0xdeadbeef) | ||
| 210 | #define BCM_6345_UDC0_BASE (0xdeadbeef) | 276 | #define BCM_6345_UDC0_BASE (0xdeadbeef) |
| 211 | #define BCM_6345_USBDMA_BASE (0xfffe2800) | 277 | #define BCM_6345_USBDMA_BASE (0xfffe2800) |
| 212 | #define BCM_6345_ENET0_BASE (0xfffe1800) | 278 | #define BCM_6345_ENET0_BASE (0xfffe1800) |
| @@ -216,6 +282,7 @@ enum bcm63xx_regs_set { | |||
| 216 | #define BCM_6345_ENETSW_BASE (0xdeadbeef) | 282 | #define BCM_6345_ENETSW_BASE (0xdeadbeef) |
| 217 | #define BCM_6345_PCMCIA_BASE (0xfffe2028) | 283 | #define BCM_6345_PCMCIA_BASE (0xfffe2028) |
| 218 | #define BCM_6345_MPI_BASE (0xfffe2000) | 284 | #define BCM_6345_MPI_BASE (0xfffe2000) |
| 285 | #define BCM_6345_PCIE_BASE (0xdeadbeef) | ||
| 219 | #define BCM_6345_OHCI0_BASE (0xfffe2100) | 286 | #define BCM_6345_OHCI0_BASE (0xfffe2100) |
| 220 | #define BCM_6345_OHCI_PRIV_BASE (0xfffe2200) | 287 | #define BCM_6345_OHCI_PRIV_BASE (0xfffe2200) |
| 221 | #define BCM_6345_USBH_PRIV_BASE (0xdeadbeef) | 288 | #define BCM_6345_USBH_PRIV_BASE (0xdeadbeef) |
| @@ -237,6 +304,8 @@ enum bcm63xx_regs_set { | |||
| 237 | #define BCM_6345_PCMDMA_BASE (0xdeadbeef) | 304 | #define BCM_6345_PCMDMA_BASE (0xdeadbeef) |
| 238 | #define BCM_6345_PCMDMAC_BASE (0xdeadbeef) | 305 | #define BCM_6345_PCMDMAC_BASE (0xdeadbeef) |
| 239 | #define BCM_6345_PCMDMAS_BASE (0xdeadbeef) | 306 | #define BCM_6345_PCMDMAS_BASE (0xdeadbeef) |
| 307 | #define BCM_6345_RNG_BASE (0xdeadbeef) | ||
| 308 | #define BCM_6345_MISC_BASE (0xdeadbeef) | ||
| 240 | 309 | ||
| 241 | /* | 310 | /* |
| 242 | * 6348 register sets base address | 311 | * 6348 register sets base address |
| @@ -249,13 +318,13 @@ enum bcm63xx_regs_set { | |||
| 249 | #define BCM_6348_UART1_BASE (0xdeadbeef) | 318 | #define BCM_6348_UART1_BASE (0xdeadbeef) |
| 250 | #define BCM_6348_GPIO_BASE (0xfffe0400) | 319 | #define BCM_6348_GPIO_BASE (0xfffe0400) |
| 251 | #define BCM_6348_SPI_BASE (0xfffe0c00) | 320 | #define BCM_6348_SPI_BASE (0xfffe0c00) |
| 252 | #define BCM_6348_SPI2_BASE (0xdeadbeef) | ||
| 253 | #define BCM_6348_UDC0_BASE (0xfffe1000) | 321 | #define BCM_6348_UDC0_BASE (0xfffe1000) |
| 254 | #define BCM_6348_OHCI0_BASE (0xfffe1b00) | 322 | #define BCM_6348_OHCI0_BASE (0xfffe1b00) |
| 255 | #define BCM_6348_OHCI_PRIV_BASE (0xfffe1c00) | 323 | #define BCM_6348_OHCI_PRIV_BASE (0xfffe1c00) |
| 256 | #define BCM_6348_USBH_PRIV_BASE (0xdeadbeef) | 324 | #define BCM_6348_USBH_PRIV_BASE (0xdeadbeef) |
| 257 | #define BCM_6348_MPI_BASE (0xfffe2000) | 325 | #define BCM_6348_MPI_BASE (0xfffe2000) |
| 258 | #define BCM_6348_PCMCIA_BASE (0xfffe2054) | 326 | #define BCM_6348_PCMCIA_BASE (0xfffe2054) |
| 327 | #define BCM_6348_PCIE_BASE (0xdeadbeef) | ||
| 259 | #define BCM_6348_SDRAM_REGS_BASE (0xfffe2300) | 328 | #define BCM_6348_SDRAM_REGS_BASE (0xfffe2300) |
| 260 | #define BCM_6348_M2M_BASE (0xfffe2800) | 329 | #define BCM_6348_M2M_BASE (0xfffe2800) |
| 261 | #define BCM_6348_DSL_BASE (0xfffe3000) | 330 | #define BCM_6348_DSL_BASE (0xfffe3000) |
| @@ -278,6 +347,8 @@ enum bcm63xx_regs_set { | |||
| 278 | #define BCM_6348_PCMDMA_BASE (0xdeadbeef) | 347 | #define BCM_6348_PCMDMA_BASE (0xdeadbeef) |
| 279 | #define BCM_6348_PCMDMAC_BASE (0xdeadbeef) | 348 | #define BCM_6348_PCMDMAC_BASE (0xdeadbeef) |
| 280 | #define BCM_6348_PCMDMAS_BASE (0xdeadbeef) | 349 | #define BCM_6348_PCMDMAS_BASE (0xdeadbeef) |
| 350 | #define BCM_6348_RNG_BASE (0xdeadbeef) | ||
| 351 | #define BCM_6348_MISC_BASE (0xdeadbeef) | ||
| 281 | 352 | ||
| 282 | /* | 353 | /* |
| 283 | * 6358 register sets base address | 354 | * 6358 register sets base address |
| @@ -289,14 +360,14 @@ enum bcm63xx_regs_set { | |||
| 289 | #define BCM_6358_UART0_BASE (0xfffe0100) | 360 | #define BCM_6358_UART0_BASE (0xfffe0100) |
| 290 | #define BCM_6358_UART1_BASE (0xfffe0120) | 361 | #define BCM_6358_UART1_BASE (0xfffe0120) |
| 291 | #define BCM_6358_GPIO_BASE (0xfffe0080) | 362 | #define BCM_6358_GPIO_BASE (0xfffe0080) |
| 292 | #define BCM_6358_SPI_BASE (0xdeadbeef) | 363 | #define BCM_6358_SPI_BASE (0xfffe0800) |
| 293 | #define BCM_6358_SPI2_BASE (0xfffe0800) | ||
| 294 | #define BCM_6358_UDC0_BASE (0xfffe0800) | 364 | #define BCM_6358_UDC0_BASE (0xfffe0800) |
| 295 | #define BCM_6358_OHCI0_BASE (0xfffe1400) | 365 | #define BCM_6358_OHCI0_BASE (0xfffe1400) |
| 296 | #define BCM_6358_OHCI_PRIV_BASE (0xdeadbeef) | 366 | #define BCM_6358_OHCI_PRIV_BASE (0xdeadbeef) |
| 297 | #define BCM_6358_USBH_PRIV_BASE (0xfffe1500) | 367 | #define BCM_6358_USBH_PRIV_BASE (0xfffe1500) |
| 298 | #define BCM_6358_MPI_BASE (0xfffe1000) | 368 | #define BCM_6358_MPI_BASE (0xfffe1000) |
| 299 | #define BCM_6358_PCMCIA_BASE (0xfffe1054) | 369 | #define BCM_6358_PCMCIA_BASE (0xfffe1054) |
| 370 | #define BCM_6358_PCIE_BASE (0xdeadbeef) | ||
| 300 | #define BCM_6358_SDRAM_REGS_BASE (0xfffe2300) | 371 | #define BCM_6358_SDRAM_REGS_BASE (0xfffe2300) |
| 301 | #define BCM_6358_M2M_BASE (0xdeadbeef) | 372 | #define BCM_6358_M2M_BASE (0xdeadbeef) |
| 302 | #define BCM_6358_DSL_BASE (0xfffe3000) | 373 | #define BCM_6358_DSL_BASE (0xfffe3000) |
| @@ -319,6 +390,8 @@ enum bcm63xx_regs_set { | |||
| 319 | #define BCM_6358_PCMDMA_BASE (0xfffe1800) | 390 | #define BCM_6358_PCMDMA_BASE (0xfffe1800) |
| 320 | #define BCM_6358_PCMDMAC_BASE (0xfffe1900) | 391 | #define BCM_6358_PCMDMAC_BASE (0xfffe1900) |
| 321 | #define BCM_6358_PCMDMAS_BASE (0xfffe1a00) | 392 | #define BCM_6358_PCMDMAS_BASE (0xfffe1a00) |
| 393 | #define BCM_6358_RNG_BASE (0xdeadbeef) | ||
| 394 | #define BCM_6358_MISC_BASE (0xdeadbeef) | ||
| 322 | 395 | ||
| 323 | 396 | ||
| 324 | /* | 397 | /* |
| @@ -331,14 +404,14 @@ enum bcm63xx_regs_set { | |||
| 331 | #define BCM_6368_UART0_BASE (0xb0000100) | 404 | #define BCM_6368_UART0_BASE (0xb0000100) |
| 332 | #define BCM_6368_UART1_BASE (0xb0000120) | 405 | #define BCM_6368_UART1_BASE (0xb0000120) |
| 333 | #define BCM_6368_GPIO_BASE (0xb0000080) | 406 | #define BCM_6368_GPIO_BASE (0xb0000080) |
| 334 | #define BCM_6368_SPI_BASE (0xdeadbeef) | 407 | #define BCM_6368_SPI_BASE (0xb0000800) |
| 335 | #define BCM_6368_SPI2_BASE (0xb0000800) | ||
| 336 | #define BCM_6368_UDC0_BASE (0xdeadbeef) | 408 | #define BCM_6368_UDC0_BASE (0xdeadbeef) |
| 337 | #define BCM_6368_OHCI0_BASE (0xb0001600) | 409 | #define BCM_6368_OHCI0_BASE (0xb0001600) |
| 338 | #define BCM_6368_OHCI_PRIV_BASE (0xdeadbeef) | 410 | #define BCM_6368_OHCI_PRIV_BASE (0xdeadbeef) |
| 339 | #define BCM_6368_USBH_PRIV_BASE (0xb0001700) | 411 | #define BCM_6368_USBH_PRIV_BASE (0xb0001700) |
| 340 | #define BCM_6368_MPI_BASE (0xb0001000) | 412 | #define BCM_6368_MPI_BASE (0xb0001000) |
| 341 | #define BCM_6368_PCMCIA_BASE (0xb0001054) | 413 | #define BCM_6368_PCMCIA_BASE (0xb0001054) |
| 414 | #define BCM_6368_PCIE_BASE (0xdeadbeef) | ||
| 342 | #define BCM_6368_SDRAM_REGS_BASE (0xdeadbeef) | 415 | #define BCM_6368_SDRAM_REGS_BASE (0xdeadbeef) |
| 343 | #define BCM_6368_M2M_BASE (0xdeadbeef) | 416 | #define BCM_6368_M2M_BASE (0xdeadbeef) |
| 344 | #define BCM_6368_DSL_BASE (0xdeadbeef) | 417 | #define BCM_6368_DSL_BASE (0xdeadbeef) |
| @@ -361,6 +434,8 @@ enum bcm63xx_regs_set { | |||
| 361 | #define BCM_6368_PCMDMA_BASE (0xb0005800) | 434 | #define BCM_6368_PCMDMA_BASE (0xb0005800) |
| 362 | #define BCM_6368_PCMDMAC_BASE (0xb0005a00) | 435 | #define BCM_6368_PCMDMAC_BASE (0xb0005a00) |
| 363 | #define BCM_6368_PCMDMAS_BASE (0xb0005c00) | 436 | #define BCM_6368_PCMDMAS_BASE (0xb0005c00) |
| 437 | #define BCM_6368_RNG_BASE (0xb0004180) | ||
| 438 | #define BCM_6368_MISC_BASE (0xdeadbeef) | ||
| 364 | 439 | ||
| 365 | 440 | ||
| 366 | extern const unsigned long *bcm63xx_regs_base; | 441 | extern const unsigned long *bcm63xx_regs_base; |
| @@ -379,13 +454,13 @@ extern const unsigned long *bcm63xx_regs_base; | |||
| 379 | __GEN_RSET_BASE(__cpu, UART1) \ | 454 | __GEN_RSET_BASE(__cpu, UART1) \ |
| 380 | __GEN_RSET_BASE(__cpu, GPIO) \ | 455 | __GEN_RSET_BASE(__cpu, GPIO) \ |
| 381 | __GEN_RSET_BASE(__cpu, SPI) \ | 456 | __GEN_RSET_BASE(__cpu, SPI) \ |
| 382 | __GEN_RSET_BASE(__cpu, SPI2) \ | ||
| 383 | __GEN_RSET_BASE(__cpu, UDC0) \ | 457 | __GEN_RSET_BASE(__cpu, UDC0) \ |
| 384 | __GEN_RSET_BASE(__cpu, OHCI0) \ | 458 | __GEN_RSET_BASE(__cpu, OHCI0) \ |
| 385 | __GEN_RSET_BASE(__cpu, OHCI_PRIV) \ | 459 | __GEN_RSET_BASE(__cpu, OHCI_PRIV) \ |
| 386 | __GEN_RSET_BASE(__cpu, USBH_PRIV) \ | 460 | __GEN_RSET_BASE(__cpu, USBH_PRIV) \ |
| 387 | __GEN_RSET_BASE(__cpu, MPI) \ | 461 | __GEN_RSET_BASE(__cpu, MPI) \ |
| 388 | __GEN_RSET_BASE(__cpu, PCMCIA) \ | 462 | __GEN_RSET_BASE(__cpu, PCMCIA) \ |
| 463 | __GEN_RSET_BASE(__cpu, PCIE) \ | ||
| 389 | __GEN_RSET_BASE(__cpu, DSL) \ | 464 | __GEN_RSET_BASE(__cpu, DSL) \ |
| 390 | __GEN_RSET_BASE(__cpu, ENET0) \ | 465 | __GEN_RSET_BASE(__cpu, ENET0) \ |
| 391 | __GEN_RSET_BASE(__cpu, ENET1) \ | 466 | __GEN_RSET_BASE(__cpu, ENET1) \ |
| @@ -407,6 +482,8 @@ extern const unsigned long *bcm63xx_regs_base; | |||
| 407 | __GEN_RSET_BASE(__cpu, PCMDMA) \ | 482 | __GEN_RSET_BASE(__cpu, PCMDMA) \ |
| 408 | __GEN_RSET_BASE(__cpu, PCMDMAC) \ | 483 | __GEN_RSET_BASE(__cpu, PCMDMAC) \ |
| 409 | __GEN_RSET_BASE(__cpu, PCMDMAS) \ | 484 | __GEN_RSET_BASE(__cpu, PCMDMAS) \ |
| 485 | __GEN_RSET_BASE(__cpu, RNG) \ | ||
| 486 | __GEN_RSET_BASE(__cpu, MISC) \ | ||
| 410 | } | 487 | } |
| 411 | 488 | ||
| 412 | #define __GEN_CPU_REGS_TABLE(__cpu) \ | 489 | #define __GEN_CPU_REGS_TABLE(__cpu) \ |
| @@ -418,13 +495,13 @@ extern const unsigned long *bcm63xx_regs_base; | |||
| 418 | [RSET_UART1] = BCM_## __cpu ##_UART1_BASE, \ | 495 | [RSET_UART1] = BCM_## __cpu ##_UART1_BASE, \ |
| 419 | [RSET_GPIO] = BCM_## __cpu ##_GPIO_BASE, \ | 496 | [RSET_GPIO] = BCM_## __cpu ##_GPIO_BASE, \ |
| 420 | [RSET_SPI] = BCM_## __cpu ##_SPI_BASE, \ | 497 | [RSET_SPI] = BCM_## __cpu ##_SPI_BASE, \ |
| 421 | [RSET_SPI2] = BCM_## __cpu ##_SPI2_BASE, \ | ||
| 422 | [RSET_UDC0] = BCM_## __cpu ##_UDC0_BASE, \ | 498 | [RSET_UDC0] = BCM_## __cpu ##_UDC0_BASE, \ |
| 423 | [RSET_OHCI0] = BCM_## __cpu ##_OHCI0_BASE, \ | 499 | [RSET_OHCI0] = BCM_## __cpu ##_OHCI0_BASE, \ |
| 424 | [RSET_OHCI_PRIV] = BCM_## __cpu ##_OHCI_PRIV_BASE, \ | 500 | [RSET_OHCI_PRIV] = BCM_## __cpu ##_OHCI_PRIV_BASE, \ |
| 425 | [RSET_USBH_PRIV] = BCM_## __cpu ##_USBH_PRIV_BASE, \ | 501 | [RSET_USBH_PRIV] = BCM_## __cpu ##_USBH_PRIV_BASE, \ |
| 426 | [RSET_MPI] = BCM_## __cpu ##_MPI_BASE, \ | 502 | [RSET_MPI] = BCM_## __cpu ##_MPI_BASE, \ |
| 427 | [RSET_PCMCIA] = BCM_## __cpu ##_PCMCIA_BASE, \ | 503 | [RSET_PCMCIA] = BCM_## __cpu ##_PCMCIA_BASE, \ |
| 504 | [RSET_PCIE] = BCM_## __cpu ##_PCIE_BASE, \ | ||
| 428 | [RSET_DSL] = BCM_## __cpu ##_DSL_BASE, \ | 505 | [RSET_DSL] = BCM_## __cpu ##_DSL_BASE, \ |
| 429 | [RSET_ENET0] = BCM_## __cpu ##_ENET0_BASE, \ | 506 | [RSET_ENET0] = BCM_## __cpu ##_ENET0_BASE, \ |
| 430 | [RSET_ENET1] = BCM_## __cpu ##_ENET1_BASE, \ | 507 | [RSET_ENET1] = BCM_## __cpu ##_ENET1_BASE, \ |
| @@ -446,6 +523,8 @@ extern const unsigned long *bcm63xx_regs_base; | |||
| 446 | [RSET_PCMDMA] = BCM_## __cpu ##_PCMDMA_BASE, \ | 523 | [RSET_PCMDMA] = BCM_## __cpu ##_PCMDMA_BASE, \ |
| 447 | [RSET_PCMDMAC] = BCM_## __cpu ##_PCMDMAC_BASE, \ | 524 | [RSET_PCMDMAC] = BCM_## __cpu ##_PCMDMAC_BASE, \ |
| 448 | [RSET_PCMDMAS] = BCM_## __cpu ##_PCMDMAS_BASE, \ | 525 | [RSET_PCMDMAS] = BCM_## __cpu ##_PCMDMAS_BASE, \ |
| 526 | [RSET_RNG] = BCM_## __cpu ##_RNG_BASE, \ | ||
| 527 | [RSET_MISC] = BCM_## __cpu ##_MISC_BASE, \ | ||
| 449 | 528 | ||
| 450 | 529 | ||
| 451 | static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set) | 530 | static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set) |
| @@ -453,6 +532,9 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set) | |||
| 453 | #ifdef BCMCPU_RUNTIME_DETECT | 532 | #ifdef BCMCPU_RUNTIME_DETECT |
| 454 | return bcm63xx_regs_base[set]; | 533 | return bcm63xx_regs_base[set]; |
| 455 | #else | 534 | #else |
| 535 | #ifdef CONFIG_BCM63XX_CPU_6328 | ||
| 536 | __GEN_RSET(6328) | ||
| 537 | #endif | ||
| 456 | #ifdef CONFIG_BCM63XX_CPU_6338 | 538 | #ifdef CONFIG_BCM63XX_CPU_6338 |
| 457 | __GEN_RSET(6338) | 539 | __GEN_RSET(6338) |
| 458 | #endif | 540 | #endif |
| @@ -478,6 +560,7 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set) | |||
| 478 | */ | 560 | */ |
| 479 | enum bcm63xx_irq { | 561 | enum bcm63xx_irq { |
| 480 | IRQ_TIMER = 0, | 562 | IRQ_TIMER = 0, |
| 563 | IRQ_SPI, | ||
| 481 | IRQ_UART0, | 564 | IRQ_UART0, |
| 482 | IRQ_UART1, | 565 | IRQ_UART1, |
| 483 | IRQ_DSL, | 566 | IRQ_DSL, |
| @@ -506,9 +589,51 @@ enum bcm63xx_irq { | |||
| 506 | }; | 589 | }; |
| 507 | 590 | ||
| 508 | /* | 591 | /* |
| 592 | * 6328 irqs | ||
| 593 | */ | ||
| 594 | #define BCM_6328_HIGH_IRQ_BASE (IRQ_INTERNAL_BASE + 32) | ||
| 595 | |||
| 596 | #define BCM_6328_TIMER_IRQ (IRQ_INTERNAL_BASE + 31) | ||
| 597 | #define BCM_6328_SPI_IRQ 0 | ||
| 598 | #define BCM_6328_UART0_IRQ (IRQ_INTERNAL_BASE + 28) | ||
| 599 | #define BCM_6328_UART1_IRQ (BCM_6328_HIGH_IRQ_BASE + 7) | ||
| 600 | #define BCM_6328_DSL_IRQ (IRQ_INTERNAL_BASE + 4) | ||
| 601 | #define BCM_6328_UDC0_IRQ 0 | ||
| 602 | #define BCM_6328_ENET0_IRQ 0 | ||
| 603 | #define BCM_6328_ENET1_IRQ 0 | ||
| 604 | #define BCM_6328_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 12) | ||
| 605 | #define BCM_6328_OHCI0_IRQ (IRQ_INTERNAL_BASE + 9) | ||
| 606 | #define BCM_6328_EHCI0_IRQ (IRQ_INTERNAL_BASE + 10) | ||
| 607 | #define BCM_6328_PCMCIA_IRQ 0 | ||
| 608 | #define BCM_6328_ENET0_RXDMA_IRQ 0 | ||
| 609 | #define BCM_6328_ENET0_TXDMA_IRQ 0 | ||
| 610 | #define BCM_6328_ENET1_RXDMA_IRQ 0 | ||
| 611 | #define BCM_6328_ENET1_TXDMA_IRQ 0 | ||
| 612 | #define BCM_6328_PCI_IRQ (IRQ_INTERNAL_BASE + 23) | ||
| 613 | #define BCM_6328_ATM_IRQ 0 | ||
| 614 | #define BCM_6328_ENETSW_RXDMA0_IRQ (BCM_6328_HIGH_IRQ_BASE + 0) | ||
| 615 | #define BCM_6328_ENETSW_RXDMA1_IRQ (BCM_6328_HIGH_IRQ_BASE + 1) | ||
| 616 | #define BCM_6328_ENETSW_RXDMA2_IRQ (BCM_6328_HIGH_IRQ_BASE + 2) | ||
| 617 | #define BCM_6328_ENETSW_RXDMA3_IRQ (BCM_6328_HIGH_IRQ_BASE + 3) | ||
| 618 | #define BCM_6328_ENETSW_TXDMA0_IRQ (BCM_6328_HIGH_IRQ_BASE + 4) | ||
| 619 | #define BCM_6328_ENETSW_TXDMA1_IRQ (BCM_6328_HIGH_IRQ_BASE + 5) | ||
| 620 | #define BCM_6328_ENETSW_TXDMA2_IRQ (BCM_6328_HIGH_IRQ_BASE + 6) | ||
| 621 | #define BCM_6328_ENETSW_TXDMA3_IRQ (BCM_6328_HIGH_IRQ_BASE + 7) | ||
| 622 | #define BCM_6328_XTM_IRQ (BCM_6328_HIGH_IRQ_BASE + 31) | ||
| 623 | #define BCM_6328_XTM_DMA0_IRQ (BCM_6328_HIGH_IRQ_BASE + 11) | ||
| 624 | |||
| 625 | #define BCM_6328_PCM_DMA0_IRQ (IRQ_INTERNAL_BASE + 2) | ||
| 626 | #define BCM_6328_PCM_DMA1_IRQ (IRQ_INTERNAL_BASE + 3) | ||
| 627 | #define BCM_6328_EXT_IRQ0 (IRQ_INTERNAL_BASE + 24) | ||
| 628 | #define BCM_6328_EXT_IRQ1 (IRQ_INTERNAL_BASE + 25) | ||
| 629 | #define BCM_6328_EXT_IRQ2 (IRQ_INTERNAL_BASE + 26) | ||
| 630 | #define BCM_6328_EXT_IRQ3 (IRQ_INTERNAL_BASE + 27) | ||
| 631 | |||
| 632 | /* | ||
| 509 | * 6338 irqs | 633 | * 6338 irqs |
| 510 | */ | 634 | */ |
| 511 | #define BCM_6338_TIMER_IRQ (IRQ_INTERNAL_BASE + 0) | 635 | #define BCM_6338_TIMER_IRQ (IRQ_INTERNAL_BASE + 0) |
| 636 | #define BCM_6338_SPI_IRQ (IRQ_INTERNAL_BASE + 1) | ||
| 512 | #define BCM_6338_UART0_IRQ (IRQ_INTERNAL_BASE + 2) | 637 | #define BCM_6338_UART0_IRQ (IRQ_INTERNAL_BASE + 2) |
| 513 | #define BCM_6338_UART1_IRQ 0 | 638 | #define BCM_6338_UART1_IRQ 0 |
| 514 | #define BCM_6338_DSL_IRQ (IRQ_INTERNAL_BASE + 5) | 639 | #define BCM_6338_DSL_IRQ (IRQ_INTERNAL_BASE + 5) |
| @@ -539,6 +664,7 @@ enum bcm63xx_irq { | |||
| 539 | * 6345 irqs | 664 | * 6345 irqs |
| 540 | */ | 665 | */ |
| 541 | #define BCM_6345_TIMER_IRQ (IRQ_INTERNAL_BASE + 0) | 666 | #define BCM_6345_TIMER_IRQ (IRQ_INTERNAL_BASE + 0) |
| 667 | #define BCM_6345_SPI_IRQ 0 | ||
| 542 | #define BCM_6345_UART0_IRQ (IRQ_INTERNAL_BASE + 2) | 668 | #define BCM_6345_UART0_IRQ (IRQ_INTERNAL_BASE + 2) |
| 543 | #define BCM_6345_UART1_IRQ 0 | 669 | #define BCM_6345_UART1_IRQ 0 |
| 544 | #define BCM_6345_DSL_IRQ (IRQ_INTERNAL_BASE + 3) | 670 | #define BCM_6345_DSL_IRQ (IRQ_INTERNAL_BASE + 3) |
| @@ -569,6 +695,7 @@ enum bcm63xx_irq { | |||
| 569 | * 6348 irqs | 695 | * 6348 irqs |
| 570 | */ | 696 | */ |
| 571 | #define BCM_6348_TIMER_IRQ (IRQ_INTERNAL_BASE + 0) | 697 | #define BCM_6348_TIMER_IRQ (IRQ_INTERNAL_BASE + 0) |
| 698 | #define BCM_6348_SPI_IRQ (IRQ_INTERNAL_BASE + 1) | ||
| 572 | #define BCM_6348_UART0_IRQ (IRQ_INTERNAL_BASE + 2) | 699 | #define BCM_6348_UART0_IRQ (IRQ_INTERNAL_BASE + 2) |
| 573 | #define BCM_6348_UART1_IRQ 0 | 700 | #define BCM_6348_UART1_IRQ 0 |
| 574 | #define BCM_6348_DSL_IRQ (IRQ_INTERNAL_BASE + 4) | 701 | #define BCM_6348_DSL_IRQ (IRQ_INTERNAL_BASE + 4) |
| @@ -599,6 +726,7 @@ enum bcm63xx_irq { | |||
| 599 | * 6358 irqs | 726 | * 6358 irqs |
| 600 | */ | 727 | */ |
| 601 | #define BCM_6358_TIMER_IRQ (IRQ_INTERNAL_BASE + 0) | 728 | #define BCM_6358_TIMER_IRQ (IRQ_INTERNAL_BASE + 0) |
| 729 | #define BCM_6358_SPI_IRQ (IRQ_INTERNAL_BASE + 1) | ||
| 602 | #define BCM_6358_UART0_IRQ (IRQ_INTERNAL_BASE + 2) | 730 | #define BCM_6358_UART0_IRQ (IRQ_INTERNAL_BASE + 2) |
| 603 | #define BCM_6358_UART1_IRQ (IRQ_INTERNAL_BASE + 3) | 731 | #define BCM_6358_UART1_IRQ (IRQ_INTERNAL_BASE + 3) |
| 604 | #define BCM_6358_DSL_IRQ (IRQ_INTERNAL_BASE + 29) | 732 | #define BCM_6358_DSL_IRQ (IRQ_INTERNAL_BASE + 29) |
| @@ -638,6 +766,7 @@ enum bcm63xx_irq { | |||
| 638 | #define BCM_6368_HIGH_IRQ_BASE (IRQ_INTERNAL_BASE + 32) | 766 | #define BCM_6368_HIGH_IRQ_BASE (IRQ_INTERNAL_BASE + 32) |
| 639 | 767 | ||
| 640 | #define BCM_6368_TIMER_IRQ (IRQ_INTERNAL_BASE + 0) | 768 | #define BCM_6368_TIMER_IRQ (IRQ_INTERNAL_BASE + 0) |
| 769 | #define BCM_6368_SPI_IRQ (IRQ_INTERNAL_BASE + 1) | ||
| 641 | #define BCM_6368_UART0_IRQ (IRQ_INTERNAL_BASE + 2) | 770 | #define BCM_6368_UART0_IRQ (IRQ_INTERNAL_BASE + 2) |
| 642 | #define BCM_6368_UART1_IRQ (IRQ_INTERNAL_BASE + 3) | 771 | #define BCM_6368_UART1_IRQ (IRQ_INTERNAL_BASE + 3) |
| 643 | #define BCM_6368_DSL_IRQ (IRQ_INTERNAL_BASE + 4) | 772 | #define BCM_6368_DSL_IRQ (IRQ_INTERNAL_BASE + 4) |
| @@ -677,6 +806,7 @@ extern const int *bcm63xx_irqs; | |||
| 677 | 806 | ||
| 678 | #define __GEN_CPU_IRQ_TABLE(__cpu) \ | 807 | #define __GEN_CPU_IRQ_TABLE(__cpu) \ |
| 679 | [IRQ_TIMER] = BCM_## __cpu ##_TIMER_IRQ, \ | 808 | [IRQ_TIMER] = BCM_## __cpu ##_TIMER_IRQ, \ |
| 809 | [IRQ_SPI] = BCM_## __cpu ##_SPI_IRQ, \ | ||
| 680 | [IRQ_UART0] = BCM_## __cpu ##_UART0_IRQ, \ | 810 | [IRQ_UART0] = BCM_## __cpu ##_UART0_IRQ, \ |
| 681 | [IRQ_UART1] = BCM_## __cpu ##_UART1_IRQ, \ | 811 | [IRQ_UART1] = BCM_## __cpu ##_UART1_IRQ, \ |
| 682 | [IRQ_DSL] = BCM_## __cpu ##_DSL_IRQ, \ | 812 | [IRQ_DSL] = BCM_## __cpu ##_DSL_IRQ, \ |
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_flash.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_flash.h new file mode 100644 index 000000000000..354b8481ec4a --- /dev/null +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_flash.h | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | #ifndef __BCM63XX_FLASH_H | ||
| 2 | #define __BCM63XX_FLASH_H | ||
| 3 | |||
| 4 | enum { | ||
| 5 | BCM63XX_FLASH_TYPE_PARALLEL, | ||
| 6 | BCM63XX_FLASH_TYPE_SERIAL, | ||
| 7 | BCM63XX_FLASH_TYPE_NAND, | ||
| 8 | }; | ||
| 9 | |||
| 10 | int __init bcm63xx_flash_register(void); | ||
| 11 | |||
| 12 | #endif /* __BCM63XX_FLASH_H */ | ||
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h new file mode 100644 index 000000000000..7d98dbe5d4b5 --- /dev/null +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h | |||
| @@ -0,0 +1,89 @@ | |||
| 1 | #ifndef BCM63XX_DEV_SPI_H | ||
| 2 | #define BCM63XX_DEV_SPI_H | ||
| 3 | |||
| 4 | #include <linux/types.h> | ||
| 5 | #include <bcm63xx_io.h> | ||
| 6 | #include <bcm63xx_regs.h> | ||
| 7 | |||
| 8 | int __init bcm63xx_spi_register(void); | ||
| 9 | |||
| 10 | struct bcm63xx_spi_pdata { | ||
| 11 | unsigned int fifo_size; | ||
| 12 | int bus_num; | ||
| 13 | int num_chipselect; | ||
| 14 | u32 speed_hz; | ||
| 15 | }; | ||
| 16 | |||
| 17 | enum bcm63xx_regs_spi { | ||
| 18 | SPI_CMD, | ||
| 19 | SPI_INT_STATUS, | ||
| 20 | SPI_INT_MASK_ST, | ||
| 21 | SPI_INT_MASK, | ||
| 22 | SPI_ST, | ||
| 23 | SPI_CLK_CFG, | ||
| 24 | SPI_FILL_BYTE, | ||
| 25 | SPI_MSG_TAIL, | ||
| 26 | SPI_RX_TAIL, | ||
| 27 | SPI_MSG_CTL, | ||
| 28 | SPI_MSG_DATA, | ||
| 29 | SPI_RX_DATA, | ||
| 30 | }; | ||
| 31 | |||
| 32 | #define __GEN_SPI_RSET_BASE(__cpu, __rset) \ | ||
| 33 | case SPI_## __rset: \ | ||
| 34 | return SPI_## __cpu ##_## __rset; | ||
| 35 | |||
| 36 | #define __GEN_SPI_RSET(__cpu) \ | ||
| 37 | switch (reg) { \ | ||
| 38 | __GEN_SPI_RSET_BASE(__cpu, CMD) \ | ||
| 39 | __GEN_SPI_RSET_BASE(__cpu, INT_STATUS) \ | ||
| 40 | __GEN_SPI_RSET_BASE(__cpu, INT_MASK_ST) \ | ||
| 41 | __GEN_SPI_RSET_BASE(__cpu, INT_MASK) \ | ||
| 42 | __GEN_SPI_RSET_BASE(__cpu, ST) \ | ||
| 43 | __GEN_SPI_RSET_BASE(__cpu, CLK_CFG) \ | ||
| 44 | __GEN_SPI_RSET_BASE(__cpu, FILL_BYTE) \ | ||
| 45 | __GEN_SPI_RSET_BASE(__cpu, MSG_TAIL) \ | ||
| 46 | __GEN_SPI_RSET_BASE(__cpu, RX_TAIL) \ | ||
| 47 | __GEN_SPI_RSET_BASE(__cpu, MSG_CTL) \ | ||
| 48 | __GEN_SPI_RSET_BASE(__cpu, MSG_DATA) \ | ||
| 49 | __GEN_SPI_RSET_BASE(__cpu, RX_DATA) \ | ||
| 50 | } | ||
| 51 | |||
| 52 | #define __GEN_SPI_REGS_TABLE(__cpu) \ | ||
| 53 | [SPI_CMD] = SPI_## __cpu ##_CMD, \ | ||
| 54 | [SPI_INT_STATUS] = SPI_## __cpu ##_INT_STATUS, \ | ||
| 55 | [SPI_INT_MASK_ST] = SPI_## __cpu ##_INT_MASK_ST, \ | ||
| 56 | [SPI_INT_MASK] = SPI_## __cpu ##_INT_MASK, \ | ||
| 57 | [SPI_ST] = SPI_## __cpu ##_ST, \ | ||
| 58 | [SPI_CLK_CFG] = SPI_## __cpu ##_CLK_CFG, \ | ||
| 59 | [SPI_FILL_BYTE] = SPI_## __cpu ##_FILL_BYTE, \ | ||
| 60 | [SPI_MSG_TAIL] = SPI_## __cpu ##_MSG_TAIL, \ | ||
| 61 | [SPI_RX_TAIL] = SPI_## __cpu ##_RX_TAIL, \ | ||
| 62 | [SPI_MSG_CTL] = SPI_## __cpu ##_MSG_CTL, \ | ||
| 63 | [SPI_MSG_DATA] = SPI_## __cpu ##_MSG_DATA, \ | ||
| 64 | [SPI_RX_DATA] = SPI_## __cpu ##_RX_DATA, | ||
| 65 | |||
| 66 | static inline unsigned long bcm63xx_spireg(enum bcm63xx_regs_spi reg) | ||
| 67 | { | ||
| 68 | #ifdef BCMCPU_RUNTIME_DETECT | ||
| 69 | extern const unsigned long *bcm63xx_regs_spi; | ||
| 70 | |||
| 71 | return bcm63xx_regs_spi[reg]; | ||
| 72 | #else | ||
| 73 | #ifdef CONFIG_BCM63XX_CPU_6338 | ||
| 74 | __GEN_SPI_RSET(6338) | ||
| 75 | #endif | ||
| 76 | #ifdef CONFIG_BCM63XX_CPU_6348 | ||
| 77 | __GEN_SPI_RSET(6348) | ||
| 78 | #endif | ||
| 79 | #ifdef CONFIG_BCM63XX_CPU_6358 | ||
| 80 | __GEN_SPI_RSET(6358) | ||
| 81 | #endif | ||
| 82 | #ifdef CONFIG_BCM63XX_CPU_6368 | ||
| 83 | __GEN_SPI_RSET(6368) | ||
| 84 | #endif | ||
| 85 | #endif | ||
| 86 | return 0; | ||
| 87 | } | ||
| 88 | |||
| 89 | #endif /* BCM63XX_DEV_SPI_H */ | ||
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h index 1d7dd96aa460..0a9891f7580d 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h | |||
| @@ -9,6 +9,8 @@ int __init bcm63xx_gpio_init(void); | |||
| 9 | static inline unsigned long bcm63xx_gpio_count(void) | 9 | static inline unsigned long bcm63xx_gpio_count(void) |
| 10 | { | 10 | { |
| 11 | switch (bcm63xx_get_cpu_id()) { | 11 | switch (bcm63xx_get_cpu_id()) { |
| 12 | case BCM6328_CPU_ID: | ||
| 13 | return 32; | ||
| 12 | case BCM6358_CPU_ID: | 14 | case BCM6358_CPU_ID: |
| 13 | return 40; | 15 | return 40; |
| 14 | case BCM6338_CPU_ID: | 16 | case BCM6338_CPU_ID: |
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h index 72477a6441dd..9203d90e610c 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h | |||
| @@ -40,6 +40,10 @@ | |||
| 40 | #define BCM_CB_MEM_END_PA (BCM_CB_MEM_BASE_PA + \ | 40 | #define BCM_CB_MEM_END_PA (BCM_CB_MEM_BASE_PA + \ |
| 41 | BCM_CB_MEM_SIZE - 1) | 41 | BCM_CB_MEM_SIZE - 1) |
| 42 | 42 | ||
| 43 | #define BCM_PCIE_MEM_BASE_PA 0x10f00000 | ||
| 44 | #define BCM_PCIE_MEM_SIZE (16 * 1024 * 1024) | ||
| 45 | #define BCM_PCIE_MEM_END_PA (BCM_PCIE_MEM_BASE_PA + \ | ||
| 46 | BCM_PCIE_MEM_SIZE - 1) | ||
| 43 | 47 | ||
| 44 | /* | 48 | /* |
| 45 | * Internal registers are accessed through KSEG3 | 49 | * Internal registers are accessed through KSEG3 |
| @@ -85,11 +89,15 @@ | |||
| 85 | #define bcm_mpi_writel(v, o) bcm_rset_writel(RSET_MPI, (v), (o)) | 89 | #define bcm_mpi_writel(v, o) bcm_rset_writel(RSET_MPI, (v), (o)) |
| 86 | #define bcm_pcmcia_readl(o) bcm_rset_readl(RSET_PCMCIA, (o)) | 90 | #define bcm_pcmcia_readl(o) bcm_rset_readl(RSET_PCMCIA, (o)) |
| 87 | #define bcm_pcmcia_writel(v, o) bcm_rset_writel(RSET_PCMCIA, (v), (o)) | 91 | #define bcm_pcmcia_writel(v, o) bcm_rset_writel(RSET_PCMCIA, (v), (o)) |
| 92 | #define bcm_pcie_readl(o) bcm_rset_readl(RSET_PCIE, (o)) | ||
| 93 | #define bcm_pcie_writel(v, o) bcm_rset_writel(RSET_PCIE, (v), (o)) | ||
| 88 | #define bcm_sdram_readl(o) bcm_rset_readl(RSET_SDRAM, (o)) | 94 | #define bcm_sdram_readl(o) bcm_rset_readl(RSET_SDRAM, (o)) |
| 89 | #define bcm_sdram_writel(v, o) bcm_rset_writel(RSET_SDRAM, (v), (o)) | 95 | #define bcm_sdram_writel(v, o) bcm_rset_writel(RSET_SDRAM, (v), (o)) |
| 90 | #define bcm_memc_readl(o) bcm_rset_readl(RSET_MEMC, (o)) | 96 | #define bcm_memc_readl(o) bcm_rset_readl(RSET_MEMC, (o)) |
| 91 | #define bcm_memc_writel(v, o) bcm_rset_writel(RSET_MEMC, (v), (o)) | 97 | #define bcm_memc_writel(v, o) bcm_rset_writel(RSET_MEMC, (v), (o)) |
| 92 | #define bcm_ddr_readl(o) bcm_rset_readl(RSET_DDR, (o)) | 98 | #define bcm_ddr_readl(o) bcm_rset_readl(RSET_DDR, (o)) |
| 93 | #define bcm_ddr_writel(v, o) bcm_rset_writel(RSET_DDR, (v), (o)) | 99 | #define bcm_ddr_writel(v, o) bcm_rset_writel(RSET_DDR, (v), (o)) |
| 100 | #define bcm_misc_readl(o) bcm_rset_readl(RSET_MISC, (o)) | ||
| 101 | #define bcm_misc_writel(v, o) bcm_rset_writel(RSET_MISC, (v), (o)) | ||
| 94 | 102 | ||
| 95 | #endif /* ! BCM63XX_IO_H_ */ | 103 | #endif /* ! BCM63XX_IO_H_ */ |
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h index fdcd78ca1b03..4ccc2a748aff 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | |||
| @@ -15,6 +15,30 @@ | |||
| 15 | /* Clock Control register */ | 15 | /* Clock Control register */ |
| 16 | #define PERF_CKCTL_REG 0x4 | 16 | #define PERF_CKCTL_REG 0x4 |
| 17 | 17 | ||
| 18 | #define CKCTL_6328_PHYMIPS_EN (1 << 0) | ||
| 19 | #define CKCTL_6328_ADSL_QPROC_EN (1 << 1) | ||
| 20 | #define CKCTL_6328_ADSL_AFE_EN (1 << 2) | ||
| 21 | #define CKCTL_6328_ADSL_EN (1 << 3) | ||
| 22 | #define CKCTL_6328_MIPS_EN (1 << 4) | ||
| 23 | #define CKCTL_6328_SAR_EN (1 << 5) | ||
| 24 | #define CKCTL_6328_PCM_EN (1 << 6) | ||
| 25 | #define CKCTL_6328_USBD_EN (1 << 7) | ||
| 26 | #define CKCTL_6328_USBH_EN (1 << 8) | ||
| 27 | #define CKCTL_6328_HSSPI_EN (1 << 9) | ||
| 28 | #define CKCTL_6328_PCIE_EN (1 << 10) | ||
| 29 | #define CKCTL_6328_ROBOSW_EN (1 << 11) | ||
| 30 | |||
| 31 | #define CKCTL_6328_ALL_SAFE_EN (CKCTL_6328_PHYMIPS_EN | \ | ||
| 32 | CKCTL_6328_ADSL_QPROC_EN | \ | ||
| 33 | CKCTL_6328_ADSL_AFE_EN | \ | ||
| 34 | CKCTL_6328_ADSL_EN | \ | ||
| 35 | CKCTL_6328_SAR_EN | \ | ||
| 36 | CKCTL_6328_PCM_EN | \ | ||
| 37 | CKCTL_6328_USBD_EN | \ | ||
| 38 | CKCTL_6328_USBH_EN | \ | ||
| 39 | CKCTL_6328_ROBOSW_EN | \ | ||
| 40 | CKCTL_6328_PCIE_EN) | ||
| 41 | |||
| 18 | #define CKCTL_6338_ADSLPHY_EN (1 << 0) | 42 | #define CKCTL_6338_ADSLPHY_EN (1 << 0) |
| 19 | #define CKCTL_6338_MPI_EN (1 << 1) | 43 | #define CKCTL_6338_MPI_EN (1 << 1) |
| 20 | #define CKCTL_6338_DRAM_EN (1 << 2) | 44 | #define CKCTL_6338_DRAM_EN (1 << 2) |
| @@ -90,35 +114,36 @@ | |||
| 90 | #define CKCTL_6368_PHYMIPS_EN (1 << 6) | 114 | #define CKCTL_6368_PHYMIPS_EN (1 << 6) |
| 91 | #define CKCTL_6368_SWPKT_USB_EN (1 << 7) | 115 | #define CKCTL_6368_SWPKT_USB_EN (1 << 7) |
| 92 | #define CKCTL_6368_SWPKT_SAR_EN (1 << 8) | 116 | #define CKCTL_6368_SWPKT_SAR_EN (1 << 8) |
| 93 | #define CKCTL_6368_SPI_CLK_EN (1 << 9) | 117 | #define CKCTL_6368_SPI_EN (1 << 9) |
| 94 | #define CKCTL_6368_USBD_CLK_EN (1 << 10) | 118 | #define CKCTL_6368_USBD_EN (1 << 10) |
| 95 | #define CKCTL_6368_SAR_CLK_EN (1 << 11) | 119 | #define CKCTL_6368_SAR_EN (1 << 11) |
| 96 | #define CKCTL_6368_ROBOSW_CLK_EN (1 << 12) | 120 | #define CKCTL_6368_ROBOSW_EN (1 << 12) |
| 97 | #define CKCTL_6368_UTOPIA_CLK_EN (1 << 13) | 121 | #define CKCTL_6368_UTOPIA_EN (1 << 13) |
| 98 | #define CKCTL_6368_PCM_CLK_EN (1 << 14) | 122 | #define CKCTL_6368_PCM_EN (1 << 14) |
| 99 | #define CKCTL_6368_USBH_CLK_EN (1 << 15) | 123 | #define CKCTL_6368_USBH_EN (1 << 15) |
| 100 | #define CKCTL_6368_DISABLE_GLESS_EN (1 << 16) | 124 | #define CKCTL_6368_DISABLE_GLESS_EN (1 << 16) |
| 101 | #define CKCTL_6368_NAND_CLK_EN (1 << 17) | 125 | #define CKCTL_6368_NAND_EN (1 << 17) |
| 102 | #define CKCTL_6368_IPSEC_CLK_EN (1 << 18) | 126 | #define CKCTL_6368_IPSEC_EN (1 << 18) |
| 103 | 127 | ||
| 104 | #define CKCTL_6368_ALL_SAFE_EN (CKCTL_6368_SWPKT_USB_EN | \ | 128 | #define CKCTL_6368_ALL_SAFE_EN (CKCTL_6368_SWPKT_USB_EN | \ |
| 105 | CKCTL_6368_SWPKT_SAR_EN | \ | 129 | CKCTL_6368_SWPKT_SAR_EN | \ |
| 106 | CKCTL_6368_SPI_CLK_EN | \ | 130 | CKCTL_6368_SPI_EN | \ |
| 107 | CKCTL_6368_USBD_CLK_EN | \ | 131 | CKCTL_6368_USBD_EN | \ |
| 108 | CKCTL_6368_SAR_CLK_EN | \ | 132 | CKCTL_6368_SAR_EN | \ |
| 109 | CKCTL_6368_ROBOSW_CLK_EN | \ | 133 | CKCTL_6368_ROBOSW_EN | \ |
| 110 | CKCTL_6368_UTOPIA_CLK_EN | \ | 134 | CKCTL_6368_UTOPIA_EN | \ |
| 111 | CKCTL_6368_PCM_CLK_EN | \ | 135 | CKCTL_6368_PCM_EN | \ |
| 112 | CKCTL_6368_USBH_CLK_EN | \ | 136 | CKCTL_6368_USBH_EN | \ |
| 113 | CKCTL_6368_DISABLE_GLESS_EN | \ | 137 | CKCTL_6368_DISABLE_GLESS_EN | \ |
| 114 | CKCTL_6368_NAND_CLK_EN | \ | 138 | CKCTL_6368_NAND_EN | \ |
| 115 | CKCTL_6368_IPSEC_CLK_EN) | 139 | CKCTL_6368_IPSEC_EN) |
| 116 | 140 | ||
| 117 | /* System PLL Control register */ | 141 | /* System PLL Control register */ |
| 118 | #define PERF_SYS_PLL_CTL_REG 0x8 | 142 | #define PERF_SYS_PLL_CTL_REG 0x8 |
| 119 | #define SYS_PLL_SOFT_RESET 0x1 | 143 | #define SYS_PLL_SOFT_RESET 0x1 |
| 120 | 144 | ||
| 121 | /* Interrupt Mask register */ | 145 | /* Interrupt Mask register */ |
| 146 | #define PERF_IRQMASK_6328_REG 0x20 | ||
| 122 | #define PERF_IRQMASK_6338_REG 0xc | 147 | #define PERF_IRQMASK_6338_REG 0xc |
| 123 | #define PERF_IRQMASK_6345_REG 0xc | 148 | #define PERF_IRQMASK_6345_REG 0xc |
| 124 | #define PERF_IRQMASK_6348_REG 0xc | 149 | #define PERF_IRQMASK_6348_REG 0xc |
| @@ -126,6 +151,7 @@ | |||
| 126 | #define PERF_IRQMASK_6368_REG 0x20 | 151 | #define PERF_IRQMASK_6368_REG 0x20 |
| 127 | 152 | ||
| 128 | /* Interrupt Status register */ | 153 | /* Interrupt Status register */ |
| 154 | #define PERF_IRQSTAT_6328_REG 0x28 | ||
| 129 | #define PERF_IRQSTAT_6338_REG 0x10 | 155 | #define PERF_IRQSTAT_6338_REG 0x10 |
| 130 | #define PERF_IRQSTAT_6345_REG 0x10 | 156 | #define PERF_IRQSTAT_6345_REG 0x10 |
| 131 | #define PERF_IRQSTAT_6348_REG 0x10 | 157 | #define PERF_IRQSTAT_6348_REG 0x10 |
| @@ -133,6 +159,7 @@ | |||
| 133 | #define PERF_IRQSTAT_6368_REG 0x28 | 159 | #define PERF_IRQSTAT_6368_REG 0x28 |
| 134 | 160 | ||
| 135 | /* External Interrupt Configuration register */ | 161 | /* External Interrupt Configuration register */ |
| 162 | #define PERF_EXTIRQ_CFG_REG_6328 0x18 | ||
| 136 | #define PERF_EXTIRQ_CFG_REG_6338 0x14 | 163 | #define PERF_EXTIRQ_CFG_REG_6338 0x14 |
| 137 | #define PERF_EXTIRQ_CFG_REG_6348 0x14 | 164 | #define PERF_EXTIRQ_CFG_REG_6348 0x14 |
| 138 | #define PERF_EXTIRQ_CFG_REG_6358 0x14 | 165 | #define PERF_EXTIRQ_CFG_REG_6358 0x14 |
| @@ -162,8 +189,21 @@ | |||
| 162 | 189 | ||
| 163 | /* Soft Reset register */ | 190 | /* Soft Reset register */ |
| 164 | #define PERF_SOFTRESET_REG 0x28 | 191 | #define PERF_SOFTRESET_REG 0x28 |
| 192 | #define PERF_SOFTRESET_6328_REG 0x10 | ||
| 165 | #define PERF_SOFTRESET_6368_REG 0x10 | 193 | #define PERF_SOFTRESET_6368_REG 0x10 |
| 166 | 194 | ||
| 195 | #define SOFTRESET_6328_SPI_MASK (1 << 0) | ||
| 196 | #define SOFTRESET_6328_EPHY_MASK (1 << 1) | ||
| 197 | #define SOFTRESET_6328_SAR_MASK (1 << 2) | ||
| 198 | #define SOFTRESET_6328_ENETSW_MASK (1 << 3) | ||
| 199 | #define SOFTRESET_6328_USBS_MASK (1 << 4) | ||
| 200 | #define SOFTRESET_6328_USBH_MASK (1 << 5) | ||
| 201 | #define SOFTRESET_6328_PCM_MASK (1 << 6) | ||
| 202 | #define SOFTRESET_6328_PCIE_CORE_MASK (1 << 7) | ||
| 203 | #define SOFTRESET_6328_PCIE_MASK (1 << 8) | ||
| 204 | #define SOFTRESET_6328_PCIE_EXT_MASK (1 << 9) | ||
| 205 | #define SOFTRESET_6328_PCIE_HARD_MASK (1 << 10) | ||
| 206 | |||
| 167 | #define SOFTRESET_6338_SPI_MASK (1 << 0) | 207 | #define SOFTRESET_6338_SPI_MASK (1 << 0) |
| 168 | #define SOFTRESET_6338_ENET_MASK (1 << 2) | 208 | #define SOFTRESET_6338_ENET_MASK (1 << 2) |
| 169 | #define SOFTRESET_6338_USBH_MASK (1 << 3) | 209 | #define SOFTRESET_6338_USBH_MASK (1 << 3) |
| @@ -307,6 +347,8 @@ | |||
| 307 | /* Watchdog reset length register */ | 347 | /* Watchdog reset length register */ |
| 308 | #define WDT_RSTLEN_REG 0x8 | 348 | #define WDT_RSTLEN_REG 0x8 |
| 309 | 349 | ||
| 350 | /* Watchdog soft reset register (BCM6328 only) */ | ||
| 351 | #define WDT_SOFTRESET_REG 0xc | ||
| 310 | 352 | ||
| 311 | /************************************************************************* | 353 | /************************************************************************* |
| 312 | * _REG relative to RSET_UARTx | 354 | * _REG relative to RSET_UARTx |
| @@ -507,6 +549,15 @@ | |||
| 507 | #define GPIO_BASEMODE_6368_MASK 0x7 | 549 | #define GPIO_BASEMODE_6368_MASK 0x7 |
| 508 | /* those bits must be kept as read in gpio basemode register*/ | 550 | /* those bits must be kept as read in gpio basemode register*/ |
| 509 | 551 | ||
| 552 | #define GPIO_STRAPBUS_REG 0x40 | ||
| 553 | #define STRAPBUS_6358_BOOT_SEL_PARALLEL (1 << 1) | ||
| 554 | #define STRAPBUS_6358_BOOT_SEL_SERIAL (0 << 1) | ||
| 555 | #define STRAPBUS_6368_BOOT_SEL_MASK 0x3 | ||
| 556 | #define STRAPBUS_6368_BOOT_SEL_NAND 0 | ||
| 557 | #define STRAPBUS_6368_BOOT_SEL_SERIAL 1 | ||
| 558 | #define STRAPBUS_6368_BOOT_SEL_PARALLEL 3 | ||
| 559 | |||
| 560 | |||
| 510 | /************************************************************************* | 561 | /************************************************************************* |
| 511 | * _REG relative to RSET_ENET | 562 | * _REG relative to RSET_ENET |
| 512 | *************************************************************************/ | 563 | *************************************************************************/ |
| @@ -924,6 +975,8 @@ | |||
| 924 | * _REG relative to RSET_DDR | 975 | * _REG relative to RSET_DDR |
| 925 | *************************************************************************/ | 976 | *************************************************************************/ |
| 926 | 977 | ||
| 978 | #define DDR_CSEND_REG 0x8 | ||
| 979 | |||
| 927 | #define DDR_DMIPSPLLCFG_REG 0x18 | 980 | #define DDR_DMIPSPLLCFG_REG 0x18 |
| 928 | #define DMIPSPLLCFG_M1_SHIFT 0 | 981 | #define DMIPSPLLCFG_M1_SHIFT 0 |
| 929 | #define DMIPSPLLCFG_M1_MASK (0xff << DMIPSPLLCFG_M1_SHIFT) | 982 | #define DMIPSPLLCFG_M1_MASK (0xff << DMIPSPLLCFG_M1_SHIFT) |
| @@ -973,4 +1026,201 @@ | |||
| 973 | #define M2M_SRCID_REG(x) ((x) * 0x40 + 0x14) | 1026 | #define M2M_SRCID_REG(x) ((x) * 0x40 + 0x14) |
| 974 | #define M2M_DSTID_REG(x) ((x) * 0x40 + 0x18) | 1027 | #define M2M_DSTID_REG(x) ((x) * 0x40 + 0x18) |
| 975 | 1028 | ||
| 1029 | /************************************************************************* | ||
| 1030 | * _REG relative to RSET_RNG | ||
| 1031 | *************************************************************************/ | ||
| 1032 | |||
| 1033 | #define RNG_CTRL 0x00 | ||
| 1034 | #define RNG_EN (1 << 0) | ||
| 1035 | |||
| 1036 | #define RNG_STAT 0x04 | ||
| 1037 | #define RNG_AVAIL_MASK (0xff000000) | ||
| 1038 | |||
| 1039 | #define RNG_DATA 0x08 | ||
| 1040 | #define RNG_THRES 0x0c | ||
| 1041 | #define RNG_MASK 0x10 | ||
| 1042 | |||
| 1043 | /************************************************************************* | ||
| 1044 | * _REG relative to RSET_SPI | ||
| 1045 | *************************************************************************/ | ||
| 1046 | |||
| 1047 | /* BCM 6338 SPI core */ | ||
| 1048 | #define SPI_6338_CMD 0x00 /* 16-bits register */ | ||
| 1049 | #define SPI_6338_INT_STATUS 0x02 | ||
| 1050 | #define SPI_6338_INT_MASK_ST 0x03 | ||
| 1051 | #define SPI_6338_INT_MASK 0x04 | ||
| 1052 | #define SPI_6338_ST 0x05 | ||
| 1053 | #define SPI_6338_CLK_CFG 0x06 | ||
| 1054 | #define SPI_6338_FILL_BYTE 0x07 | ||
| 1055 | #define SPI_6338_MSG_TAIL 0x09 | ||
| 1056 | #define SPI_6338_RX_TAIL 0x0b | ||
| 1057 | #define SPI_6338_MSG_CTL 0x40 | ||
| 1058 | #define SPI_6338_MSG_DATA 0x41 | ||
| 1059 | #define SPI_6338_MSG_DATA_SIZE 0x3f | ||
| 1060 | #define SPI_6338_RX_DATA 0x80 | ||
| 1061 | #define SPI_6338_RX_DATA_SIZE 0x3f | ||
| 1062 | |||
| 1063 | /* BCM 6348 SPI core */ | ||
| 1064 | #define SPI_6348_CMD 0x00 /* 16-bits register */ | ||
| 1065 | #define SPI_6348_INT_STATUS 0x02 | ||
| 1066 | #define SPI_6348_INT_MASK_ST 0x03 | ||
| 1067 | #define SPI_6348_INT_MASK 0x04 | ||
| 1068 | #define SPI_6348_ST 0x05 | ||
| 1069 | #define SPI_6348_CLK_CFG 0x06 | ||
| 1070 | #define SPI_6348_FILL_BYTE 0x07 | ||
| 1071 | #define SPI_6348_MSG_TAIL 0x09 | ||
| 1072 | #define SPI_6348_RX_TAIL 0x0b | ||
| 1073 | #define SPI_6348_MSG_CTL 0x40 | ||
| 1074 | #define SPI_6348_MSG_DATA 0x41 | ||
| 1075 | #define SPI_6348_MSG_DATA_SIZE 0x3f | ||
| 1076 | #define SPI_6348_RX_DATA 0x80 | ||
| 1077 | #define SPI_6348_RX_DATA_SIZE 0x3f | ||
| 1078 | |||
| 1079 | /* BCM 6358 SPI core */ | ||
| 1080 | #define SPI_6358_MSG_CTL 0x00 /* 16-bits register */ | ||
| 1081 | #define SPI_6358_MSG_DATA 0x02 | ||
| 1082 | #define SPI_6358_MSG_DATA_SIZE 0x21e | ||
| 1083 | #define SPI_6358_RX_DATA 0x400 | ||
| 1084 | #define SPI_6358_RX_DATA_SIZE 0x220 | ||
| 1085 | #define SPI_6358_CMD 0x700 /* 16-bits register */ | ||
| 1086 | #define SPI_6358_INT_STATUS 0x702 | ||
| 1087 | #define SPI_6358_INT_MASK_ST 0x703 | ||
| 1088 | #define SPI_6358_INT_MASK 0x704 | ||
| 1089 | #define SPI_6358_ST 0x705 | ||
| 1090 | #define SPI_6358_CLK_CFG 0x706 | ||
| 1091 | #define SPI_6358_FILL_BYTE 0x707 | ||
| 1092 | #define SPI_6358_MSG_TAIL 0x709 | ||
| 1093 | #define SPI_6358_RX_TAIL 0x70B | ||
| 1094 | |||
| 1095 | /* BCM 6358 SPI core */ | ||
| 1096 | #define SPI_6368_MSG_CTL 0x00 /* 16-bits register */ | ||
| 1097 | #define SPI_6368_MSG_DATA 0x02 | ||
| 1098 | #define SPI_6368_MSG_DATA_SIZE 0x21e | ||
| 1099 | #define SPI_6368_RX_DATA 0x400 | ||
| 1100 | #define SPI_6368_RX_DATA_SIZE 0x220 | ||
| 1101 | #define SPI_6368_CMD 0x700 /* 16-bits register */ | ||
| 1102 | #define SPI_6368_INT_STATUS 0x702 | ||
| 1103 | #define SPI_6368_INT_MASK_ST 0x703 | ||
| 1104 | #define SPI_6368_INT_MASK 0x704 | ||
| 1105 | #define SPI_6368_ST 0x705 | ||
| 1106 | #define SPI_6368_CLK_CFG 0x706 | ||
| 1107 | #define SPI_6368_FILL_BYTE 0x707 | ||
| 1108 | #define SPI_6368_MSG_TAIL 0x709 | ||
| 1109 | #define SPI_6368_RX_TAIL 0x70B | ||
| 1110 | |||
| 1111 | /* Shared SPI definitions */ | ||
| 1112 | |||
| 1113 | /* Message configuration */ | ||
| 1114 | #define SPI_FD_RW 0x00 | ||
| 1115 | #define SPI_HD_W 0x01 | ||
| 1116 | #define SPI_HD_R 0x02 | ||
| 1117 | #define SPI_BYTE_CNT_SHIFT 0 | ||
| 1118 | #define SPI_MSG_TYPE_SHIFT 14 | ||
| 1119 | |||
| 1120 | /* Command */ | ||
| 1121 | #define SPI_CMD_NOOP 0x00 | ||
| 1122 | #define SPI_CMD_SOFT_RESET 0x01 | ||
| 1123 | #define SPI_CMD_HARD_RESET 0x02 | ||
| 1124 | #define SPI_CMD_START_IMMEDIATE 0x03 | ||
| 1125 | #define SPI_CMD_COMMAND_SHIFT 0 | ||
| 1126 | #define SPI_CMD_COMMAND_MASK 0x000f | ||
| 1127 | #define SPI_CMD_DEVICE_ID_SHIFT 4 | ||
| 1128 | #define SPI_CMD_PREPEND_BYTE_CNT_SHIFT 8 | ||
| 1129 | #define SPI_CMD_ONE_BYTE_SHIFT 11 | ||
| 1130 | #define SPI_CMD_ONE_WIRE_SHIFT 12 | ||
| 1131 | #define SPI_DEV_ID_0 0 | ||
| 1132 | #define SPI_DEV_ID_1 1 | ||
| 1133 | #define SPI_DEV_ID_2 2 | ||
| 1134 | #define SPI_DEV_ID_3 3 | ||
| 1135 | |||
| 1136 | /* Interrupt mask */ | ||
| 1137 | #define SPI_INTR_CMD_DONE 0x01 | ||
| 1138 | #define SPI_INTR_RX_OVERFLOW 0x02 | ||
| 1139 | #define SPI_INTR_TX_UNDERFLOW 0x04 | ||
| 1140 | #define SPI_INTR_TX_OVERFLOW 0x08 | ||
| 1141 | #define SPI_INTR_RX_UNDERFLOW 0x10 | ||
| 1142 | #define SPI_INTR_CLEAR_ALL 0x1f | ||
| 1143 | |||
| 1144 | /* Status */ | ||
| 1145 | #define SPI_RX_EMPTY 0x02 | ||
| 1146 | #define SPI_CMD_BUSY 0x04 | ||
| 1147 | #define SPI_SERIAL_BUSY 0x08 | ||
| 1148 | |||
| 1149 | /* Clock configuration */ | ||
| 1150 | #define SPI_CLK_20MHZ 0x00 | ||
| 1151 | #define SPI_CLK_0_391MHZ 0x01 | ||
| 1152 | #define SPI_CLK_0_781MHZ 0x02 /* default */ | ||
| 1153 | #define SPI_CLK_1_563MHZ 0x03 | ||
| 1154 | #define SPI_CLK_3_125MHZ 0x04 | ||
| 1155 | #define SPI_CLK_6_250MHZ 0x05 | ||
| 1156 | #define SPI_CLK_12_50MHZ 0x06 | ||
| 1157 | #define SPI_CLK_MASK 0x07 | ||
| 1158 | #define SPI_SSOFFTIME_MASK 0x38 | ||
| 1159 | #define SPI_SSOFFTIME_SHIFT 3 | ||
| 1160 | #define SPI_BYTE_SWAP 0x80 | ||
| 1161 | |||
| 1162 | /************************************************************************* | ||
| 1163 | * _REG relative to RSET_MISC | ||
| 1164 | *************************************************************************/ | ||
| 1165 | #define MISC_SERDES_CTRL_REG 0x0 | ||
| 1166 | #define SERDES_PCIE_EN (1 << 0) | ||
| 1167 | #define SERDES_PCIE_EXD_EN (1 << 15) | ||
| 1168 | |||
| 1169 | #define MISC_STRAPBUS_6328_REG 0x240 | ||
| 1170 | #define STRAPBUS_6328_FCVO_SHIFT 7 | ||
| 1171 | #define STRAPBUS_6328_FCVO_MASK (0x1f << STRAPBUS_6328_FCVO_SHIFT) | ||
| 1172 | #define STRAPBUS_6328_BOOT_SEL_SERIAL (1 << 28) | ||
| 1173 | #define STRAPBUS_6328_BOOT_SEL_NAND (0 << 28) | ||
| 1174 | |||
| 1175 | /************************************************************************* | ||
| 1176 | * _REG relative to RSET_PCIE | ||
| 1177 | *************************************************************************/ | ||
| 1178 | |||
| 1179 | #define PCIE_CONFIG2_REG 0x408 | ||
| 1180 | #define CONFIG2_BAR1_SIZE_EN 1 | ||
| 1181 | #define CONFIG2_BAR1_SIZE_MASK 0xf | ||
| 1182 | |||
| 1183 | #define PCIE_IDVAL3_REG 0x43c | ||
| 1184 | #define IDVAL3_CLASS_CODE_MASK 0xffffff | ||
| 1185 | #define IDVAL3_SUBCLASS_SHIFT 8 | ||
| 1186 | #define IDVAL3_CLASS_SHIFT 16 | ||
| 1187 | |||
| 1188 | #define PCIE_DLSTATUS_REG 0x1048 | ||
| 1189 | #define DLSTATUS_PHYLINKUP (1 << 13) | ||
| 1190 | |||
| 1191 | #define PCIE_BRIDGE_OPT1_REG 0x2820 | ||
| 1192 | #define OPT1_RD_BE_OPT_EN (1 << 7) | ||
| 1193 | #define OPT1_RD_REPLY_BE_FIX_EN (1 << 9) | ||
| 1194 | #define OPT1_PCIE_BRIDGE_HOLE_DET_EN (1 << 11) | ||
| 1195 | #define OPT1_L1_INT_STATUS_MASK_POL (1 << 12) | ||
| 1196 | |||
| 1197 | #define PCIE_BRIDGE_OPT2_REG 0x2824 | ||
| 1198 | #define OPT2_UBUS_UR_DECODE_DIS (1 << 2) | ||
| 1199 | #define OPT2_TX_CREDIT_CHK_EN (1 << 4) | ||
| 1200 | #define OPT2_CFG_TYPE1_BD_SEL (1 << 7) | ||
| 1201 | #define OPT2_CFG_TYPE1_BUS_NO_SHIFT 16 | ||
| 1202 | #define OPT2_CFG_TYPE1_BUS_NO_MASK (0xff << OPT2_CFG_TYPE1_BUS_NO_SHIFT) | ||
| 1203 | |||
| 1204 | #define PCIE_BRIDGE_BAR0_BASEMASK_REG 0x2828 | ||
| 1205 | #define PCIE_BRIDGE_BAR1_BASEMASK_REG 0x2830 | ||
| 1206 | #define BASEMASK_REMAP_EN (1 << 0) | ||
| 1207 | #define BASEMASK_SWAP_EN (1 << 1) | ||
| 1208 | #define BASEMASK_MASK_SHIFT 4 | ||
| 1209 | #define BASEMASK_MASK_MASK (0xfff << BASEMASK_MASK_SHIFT) | ||
| 1210 | #define BASEMASK_BASE_SHIFT 20 | ||
| 1211 | #define BASEMASK_BASE_MASK (0xfff << BASEMASK_BASE_SHIFT) | ||
| 1212 | |||
| 1213 | #define PCIE_BRIDGE_BAR0_REBASE_ADDR_REG 0x282c | ||
| 1214 | #define PCIE_BRIDGE_BAR1_REBASE_ADDR_REG 0x2834 | ||
| 1215 | #define REBASE_ADDR_BASE_SHIFT 20 | ||
| 1216 | #define REBASE_ADDR_BASE_MASK (0xfff << REBASE_ADDR_BASE_SHIFT) | ||
| 1217 | |||
| 1218 | #define PCIE_BRIDGE_RC_INT_MASK_REG 0x2854 | ||
| 1219 | #define PCIE_RC_INT_A (1 << 0) | ||
| 1220 | #define PCIE_RC_INT_B (1 << 1) | ||
| 1221 | #define PCIE_RC_INT_C (1 << 2) | ||
| 1222 | #define PCIE_RC_INT_D (1 << 3) | ||
| 1223 | |||
| 1224 | #define PCIE_DEVICE_OFFSET 0x8000 | ||
| 1225 | |||
| 976 | #endif /* BCM63XX_REGS_H_ */ | 1226 | #endif /* BCM63XX_REGS_H_ */ |
diff --git a/arch/mips/include/asm/mach-bcm63xx/ioremap.h b/arch/mips/include/asm/mach-bcm63xx/ioremap.h index ef94ba73646e..30931c42379d 100644 --- a/arch/mips/include/asm/mach-bcm63xx/ioremap.h +++ b/arch/mips/include/asm/mach-bcm63xx/ioremap.h | |||
| @@ -18,6 +18,7 @@ static inline int is_bcm63xx_internal_registers(phys_t offset) | |||
| 18 | if (offset >= 0xfff00000) | 18 | if (offset >= 0xfff00000) |
| 19 | return 1; | 19 | return 1; |
| 20 | break; | 20 | break; |
| 21 | case BCM6328_CPU_ID: | ||
| 21 | case BCM6368_CPU_ID: | 22 | case BCM6368_CPU_ID: |
| 22 | if (offset >= 0xb0000000 && offset < 0xb1000000) | 23 | if (offset >= 0xb0000000 && offset < 0xb1000000) |
| 23 | return 1; | 24 | return 1; |
diff --git a/arch/mips/include/asm/mach-cavium-octeon/irq.h b/arch/mips/include/asm/mach-cavium-octeon/irq.h index 5b05f186e395..418992042f6f 100644 --- a/arch/mips/include/asm/mach-cavium-octeon/irq.h +++ b/arch/mips/include/asm/mach-cavium-octeon/irq.h | |||
| @@ -41,61 +41,26 @@ enum octeon_irq { | |||
| 41 | OCTEON_IRQ_TWSI, | 41 | OCTEON_IRQ_TWSI, |
| 42 | OCTEON_IRQ_TWSI2, | 42 | OCTEON_IRQ_TWSI2, |
| 43 | OCTEON_IRQ_RML, | 43 | OCTEON_IRQ_RML, |
| 44 | OCTEON_IRQ_TRACE0, | ||
| 45 | OCTEON_IRQ_GMX_DRP0 = OCTEON_IRQ_TRACE0 + 4, | ||
| 46 | OCTEON_IRQ_IPD_DRP = OCTEON_IRQ_GMX_DRP0 + 5, | ||
| 47 | OCTEON_IRQ_KEY_ZERO, | ||
| 48 | OCTEON_IRQ_TIMER0, | 44 | OCTEON_IRQ_TIMER0, |
| 49 | OCTEON_IRQ_TIMER1, | 45 | OCTEON_IRQ_TIMER1, |
| 50 | OCTEON_IRQ_TIMER2, | 46 | OCTEON_IRQ_TIMER2, |
| 51 | OCTEON_IRQ_TIMER3, | 47 | OCTEON_IRQ_TIMER3, |
| 52 | OCTEON_IRQ_USB0, | 48 | OCTEON_IRQ_USB0, |
| 53 | OCTEON_IRQ_USB1, | 49 | OCTEON_IRQ_USB1, |
| 54 | OCTEON_IRQ_PCM, | ||
| 55 | OCTEON_IRQ_MPI, | ||
| 56 | OCTEON_IRQ_POWIQ, | ||
| 57 | OCTEON_IRQ_IPDPPTHR, | ||
| 58 | OCTEON_IRQ_MII0, | 50 | OCTEON_IRQ_MII0, |
| 59 | OCTEON_IRQ_MII1, | 51 | OCTEON_IRQ_MII1, |
| 60 | OCTEON_IRQ_BOOTDMA, | 52 | OCTEON_IRQ_BOOTDMA, |
| 61 | 53 | #ifndef CONFIG_PCI_MSI | |
| 62 | OCTEON_IRQ_NAND, | 54 | OCTEON_IRQ_LAST = 127 |
| 63 | OCTEON_IRQ_MIO, /* Summary of MIO_BOOT_ERR */ | 55 | #endif |
| 64 | OCTEON_IRQ_IOB, /* Summary of IOB_INT_SUM */ | ||
| 65 | OCTEON_IRQ_FPA, /* Summary of FPA_INT_SUM */ | ||
| 66 | OCTEON_IRQ_POW, /* Summary of POW_ECC_ERR */ | ||
| 67 | OCTEON_IRQ_L2C, /* Summary of L2C_INT_STAT */ | ||
| 68 | OCTEON_IRQ_IPD, /* Summary of IPD_INT_SUM */ | ||
| 69 | OCTEON_IRQ_PIP, /* Summary of PIP_INT_REG */ | ||
| 70 | OCTEON_IRQ_PKO, /* Summary of PKO_REG_ERROR */ | ||
| 71 | OCTEON_IRQ_ZIP, /* Summary of ZIP_ERROR */ | ||
| 72 | OCTEON_IRQ_TIM, /* Summary of TIM_REG_ERROR */ | ||
| 73 | OCTEON_IRQ_RAD, /* Summary of RAD_REG_ERROR */ | ||
| 74 | OCTEON_IRQ_KEY, /* Summary of KEY_INT_SUM */ | ||
| 75 | OCTEON_IRQ_DFA, /* Summary of DFA */ | ||
| 76 | OCTEON_IRQ_USBCTL, /* Summary of USBN0_INT_SUM */ | ||
| 77 | OCTEON_IRQ_SLI, /* Summary of SLI_INT_SUM */ | ||
| 78 | OCTEON_IRQ_DPI, /* Summary of DPI_INT_SUM */ | ||
| 79 | OCTEON_IRQ_AGX0, /* Summary of GMX0*+PCS0_INT*_REG */ | ||
| 80 | OCTEON_IRQ_AGL = OCTEON_IRQ_AGX0 + 5, | ||
| 81 | OCTEON_IRQ_PTP, | ||
| 82 | OCTEON_IRQ_PEM0, | ||
| 83 | OCTEON_IRQ_PEM1, | ||
| 84 | OCTEON_IRQ_SRIO0, | ||
| 85 | OCTEON_IRQ_SRIO1, | ||
| 86 | OCTEON_IRQ_LMC0, | ||
| 87 | OCTEON_IRQ_DFM = OCTEON_IRQ_LMC0 + 4, /* Summary of DFM */ | ||
| 88 | OCTEON_IRQ_RST, | ||
| 89 | }; | 56 | }; |
| 90 | 57 | ||
| 91 | #ifdef CONFIG_PCI_MSI | 58 | #ifdef CONFIG_PCI_MSI |
| 92 | /* 152 - 407 represent the MSI interrupts 0-255 */ | 59 | /* 256 - 511 represent the MSI interrupts 0-255 */ |
| 93 | #define OCTEON_IRQ_MSI_BIT0 (OCTEON_IRQ_RST + 1) | 60 | #define OCTEON_IRQ_MSI_BIT0 (256) |
| 94 | 61 | ||
| 95 | #define OCTEON_IRQ_MSI_LAST (OCTEON_IRQ_MSI_BIT0 + 255) | 62 | #define OCTEON_IRQ_MSI_LAST (OCTEON_IRQ_MSI_BIT0 + 255) |
| 96 | #define OCTEON_IRQ_LAST (OCTEON_IRQ_MSI_LAST + 1) | 63 | #define OCTEON_IRQ_LAST (OCTEON_IRQ_MSI_LAST + 1) |
| 97 | #else | ||
| 98 | #define OCTEON_IRQ_LAST (OCTEON_IRQ_RST + 1) | ||
| 99 | #endif | 64 | #endif |
| 100 | 65 | ||
| 101 | #endif | 66 | #endif |
diff --git a/arch/mips/include/asm/mach-jz4740/jz4740_nand.h b/arch/mips/include/asm/mach-jz4740/jz4740_nand.h index bb5b9a4e29c8..986982db7c38 100644 --- a/arch/mips/include/asm/mach-jz4740/jz4740_nand.h +++ b/arch/mips/include/asm/mach-jz4740/jz4740_nand.h | |||
| @@ -19,6 +19,8 @@ | |||
| 19 | #include <linux/mtd/nand.h> | 19 | #include <linux/mtd/nand.h> |
| 20 | #include <linux/mtd/partitions.h> | 20 | #include <linux/mtd/partitions.h> |
| 21 | 21 | ||
| 22 | #define JZ_NAND_NUM_BANKS 4 | ||
| 23 | |||
| 22 | struct jz_nand_platform_data { | 24 | struct jz_nand_platform_data { |
| 23 | int num_partitions; | 25 | int num_partitions; |
| 24 | struct mtd_partition *partitions; | 26 | struct mtd_partition *partitions; |
| @@ -27,6 +29,8 @@ struct jz_nand_platform_data { | |||
| 27 | 29 | ||
| 28 | unsigned int busy_gpio; | 30 | unsigned int busy_gpio; |
| 29 | 31 | ||
| 32 | unsigned char banks[JZ_NAND_NUM_BANKS]; | ||
| 33 | |||
| 30 | void (*ident_callback)(struct platform_device *, struct nand_chip *, | 34 | void (*ident_callback)(struct platform_device *, struct nand_chip *, |
| 31 | struct mtd_partition **, int *num_partitions); | 35 | struct mtd_partition **, int *num_partitions); |
| 32 | }; | 36 | }; |
diff --git a/arch/mips/include/asm/mach-loongson/loongson.h b/arch/mips/include/asm/mach-loongson/loongson.h index 1e29b9dd1d73..06367c37e1b2 100644 --- a/arch/mips/include/asm/mach-loongson/loongson.h +++ b/arch/mips/include/asm/mach-loongson/loongson.h | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include <linux/io.h> | 14 | #include <linux/io.h> |
| 15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
| 16 | #include <linux/irq.h> | 16 | #include <linux/irq.h> |
| 17 | #include <linux/kconfig.h> | ||
| 17 | 18 | ||
| 18 | /* loongson internal northbridge initialization */ | 19 | /* loongson internal northbridge initialization */ |
| 19 | extern void bonito_irq_init(void); | 20 | extern void bonito_irq_init(void); |
| @@ -66,7 +67,7 @@ extern int mach_i8259_irq(void); | |||
| 66 | #include <linux/interrupt.h> | 67 | #include <linux/interrupt.h> |
| 67 | static inline void do_perfcnt_IRQ(void) | 68 | static inline void do_perfcnt_IRQ(void) |
| 68 | { | 69 | { |
| 69 | #if defined(CONFIG_OPROFILE) || defined(CONFIG_OPROFILE_MODULE) | 70 | #if IS_ENABLED(CONFIG_OPROFILE) |
| 70 | do_IRQ(LOONGSON2_PERFCNT_IRQ); | 71 | do_IRQ(LOONGSON2_PERFCNT_IRQ); |
| 71 | #endif | 72 | #endif |
| 72 | } | 73 | } |
diff --git a/arch/mips/include/asm/mach-loongson1/irq.h b/arch/mips/include/asm/mach-loongson1/irq.h new file mode 100644 index 000000000000..da96ed42f733 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson1/irq.h | |||
| @@ -0,0 +1,73 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com> | ||
| 3 | * | ||
| 4 | * IRQ mappings for Loongson 1 | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify it | ||
| 7 | * under the terms of the GNU General Public License as published by the | ||
| 8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 9 | * option) any later version. | ||
| 10 | */ | ||
| 11 | |||
| 12 | |||
| 13 | #ifndef __ASM_MACH_LOONGSON1_IRQ_H | ||
| 14 | #define __ASM_MACH_LOONGSON1_IRQ_H | ||
| 15 | |||
| 16 | /* | ||
| 17 | * CPU core Interrupt Numbers | ||
| 18 | */ | ||
| 19 | #define MIPS_CPU_IRQ_BASE 0 | ||
| 20 | #define MIPS_CPU_IRQ(x) (MIPS_CPU_IRQ_BASE + (x)) | ||
| 21 | |||
| 22 | #define SOFTINT0_IRQ MIPS_CPU_IRQ(0) | ||
| 23 | #define SOFTINT1_IRQ MIPS_CPU_IRQ(1) | ||
| 24 | #define INT0_IRQ MIPS_CPU_IRQ(2) | ||
| 25 | #define INT1_IRQ MIPS_CPU_IRQ(3) | ||
| 26 | #define INT2_IRQ MIPS_CPU_IRQ(4) | ||
| 27 | #define INT3_IRQ MIPS_CPU_IRQ(5) | ||
| 28 | #define INT4_IRQ MIPS_CPU_IRQ(6) | ||
| 29 | #define TIMER_IRQ MIPS_CPU_IRQ(7) /* cpu timer */ | ||
| 30 | |||
| 31 | #define MIPS_CPU_IRQS (MIPS_CPU_IRQ(7) + 1 - MIPS_CPU_IRQ_BASE) | ||
| 32 | |||
| 33 | /* | ||
| 34 | * INT0~3 Interrupt Numbers | ||
| 35 | */ | ||
| 36 | #define LS1X_IRQ_BASE MIPS_CPU_IRQS | ||
| 37 | #define LS1X_IRQ(n, x) (LS1X_IRQ_BASE + (n << 5) + (x)) | ||
| 38 | |||
| 39 | #define LS1X_UART0_IRQ LS1X_IRQ(0, 2) | ||
| 40 | #define LS1X_UART1_IRQ LS1X_IRQ(0, 3) | ||
| 41 | #define LS1X_UART2_IRQ LS1X_IRQ(0, 4) | ||
| 42 | #define LS1X_UART3_IRQ LS1X_IRQ(0, 5) | ||
| 43 | #define LS1X_CAN0_IRQ LS1X_IRQ(0, 6) | ||
| 44 | #define LS1X_CAN1_IRQ LS1X_IRQ(0, 7) | ||
| 45 | #define LS1X_SPI0_IRQ LS1X_IRQ(0, 8) | ||
| 46 | #define LS1X_SPI1_IRQ LS1X_IRQ(0, 9) | ||
| 47 | #define LS1X_AC97_IRQ LS1X_IRQ(0, 10) | ||
| 48 | #define LS1X_DMA0_IRQ LS1X_IRQ(0, 13) | ||
| 49 | #define LS1X_DMA1_IRQ LS1X_IRQ(0, 14) | ||
| 50 | #define LS1X_DMA2_IRQ LS1X_IRQ(0, 15) | ||
| 51 | #define LS1X_PWM0_IRQ LS1X_IRQ(0, 17) | ||
| 52 | #define LS1X_PWM1_IRQ LS1X_IRQ(0, 18) | ||
| 53 | #define LS1X_PWM2_IRQ LS1X_IRQ(0, 19) | ||
| 54 | #define LS1X_PWM3_IRQ LS1X_IRQ(0, 20) | ||
| 55 | #define LS1X_RTC_INT0_IRQ LS1X_IRQ(0, 21) | ||
| 56 | #define LS1X_RTC_INT1_IRQ LS1X_IRQ(0, 22) | ||
| 57 | #define LS1X_RTC_INT2_IRQ LS1X_IRQ(0, 23) | ||
| 58 | #define LS1X_TOY_INT0_IRQ LS1X_IRQ(0, 24) | ||
| 59 | #define LS1X_TOY_INT1_IRQ LS1X_IRQ(0, 25) | ||
| 60 | #define LS1X_TOY_INT2_IRQ LS1X_IRQ(0, 26) | ||
| 61 | #define LS1X_RTC_TICK_IRQ LS1X_IRQ(0, 27) | ||
| 62 | #define LS1X_TOY_TICK_IRQ LS1X_IRQ(0, 28) | ||
| 63 | |||
| 64 | #define LS1X_EHCI_IRQ LS1X_IRQ(1, 0) | ||
| 65 | #define LS1X_OHCI_IRQ LS1X_IRQ(1, 1) | ||
| 66 | #define LS1X_GMAC0_IRQ LS1X_IRQ(1, 2) | ||
| 67 | #define LS1X_GMAC1_IRQ LS1X_IRQ(1, 3) | ||
| 68 | |||
| 69 | #define LS1X_IRQS (LS1X_IRQ(4, 31) + 1 - LS1X_IRQ_BASE) | ||
| 70 | |||
| 71 | #define NR_IRQS (MIPS_CPU_IRQS + LS1X_IRQS) | ||
| 72 | |||
| 73 | #endif /* __ASM_MACH_LOONGSON1_IRQ_H */ | ||
diff --git a/arch/mips/include/asm/mach-loongson1/loongson1.h b/arch/mips/include/asm/mach-loongson1/loongson1.h new file mode 100644 index 000000000000..4e18e88cebbf --- /dev/null +++ b/arch/mips/include/asm/mach-loongson1/loongson1.h | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com> | ||
| 3 | * | ||
| 4 | * Register mappings for Loongson 1 | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify it | ||
| 7 | * under the terms of the GNU General Public License as published by the | ||
| 8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 9 | * option) any later version. | ||
| 10 | */ | ||
| 11 | |||
| 12 | |||
| 13 | #ifndef __ASM_MACH_LOONGSON1_LOONGSON1_H | ||
| 14 | #define __ASM_MACH_LOONGSON1_LOONGSON1_H | ||
| 15 | |||
| 16 | #define DEFAULT_MEMSIZE 256 /* If no memsize provided */ | ||
| 17 | |||
| 18 | /* Loongson 1 Register Bases */ | ||
| 19 | #define LS1X_INTC_BASE 0x1fd01040 | ||
| 20 | #define LS1X_EHCI_BASE 0x1fe00000 | ||
| 21 | #define LS1X_OHCI_BASE 0x1fe08000 | ||
| 22 | #define LS1X_GMAC0_BASE 0x1fe10000 | ||
| 23 | #define LS1X_GMAC1_BASE 0x1fe20000 | ||
| 24 | |||
| 25 | #define LS1X_UART0_BASE 0x1fe40000 | ||
| 26 | #define LS1X_UART1_BASE 0x1fe44000 | ||
| 27 | #define LS1X_UART2_BASE 0x1fe48000 | ||
| 28 | #define LS1X_UART3_BASE 0x1fe4c000 | ||
| 29 | #define LS1X_CAN0_BASE 0x1fe50000 | ||
| 30 | #define LS1X_CAN1_BASE 0x1fe54000 | ||
| 31 | #define LS1X_I2C0_BASE 0x1fe58000 | ||
| 32 | #define LS1X_I2C1_BASE 0x1fe68000 | ||
| 33 | #define LS1X_I2C2_BASE 0x1fe70000 | ||
| 34 | #define LS1X_PWM_BASE 0x1fe5c000 | ||
| 35 | #define LS1X_WDT_BASE 0x1fe5c060 | ||
| 36 | #define LS1X_RTC_BASE 0x1fe64000 | ||
| 37 | #define LS1X_AC97_BASE 0x1fe74000 | ||
| 38 | #define LS1X_NAND_BASE 0x1fe78000 | ||
| 39 | #define LS1X_CLK_BASE 0x1fe78030 | ||
| 40 | |||
| 41 | #include <regs-clk.h> | ||
| 42 | #include <regs-wdt.h> | ||
| 43 | |||
| 44 | #endif /* __ASM_MACH_LOONGSON1_LOONGSON1_H */ | ||
diff --git a/arch/mips/include/asm/mach-loongson1/platform.h b/arch/mips/include/asm/mach-loongson1/platform.h new file mode 100644 index 000000000000..2f171617bade --- /dev/null +++ b/arch/mips/include/asm/mach-loongson1/platform.h | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com> | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License as published by the | ||
| 6 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 7 | * option) any later version. | ||
| 8 | */ | ||
| 9 | |||
| 10 | |||
| 11 | #ifndef __ASM_MACH_LOONGSON1_PLATFORM_H | ||
| 12 | #define __ASM_MACH_LOONGSON1_PLATFORM_H | ||
| 13 | |||
| 14 | #include <linux/platform_device.h> | ||
| 15 | |||
| 16 | extern struct platform_device ls1x_uart_device; | ||
| 17 | extern struct platform_device ls1x_eth0_device; | ||
| 18 | extern struct platform_device ls1x_ehci_device; | ||
| 19 | extern struct platform_device ls1x_rtc_device; | ||
| 20 | |||
| 21 | void ls1x_serial_setup(void); | ||
| 22 | |||
| 23 | #endif /* __ASM_MACH_LOONGSON1_PLATFORM_H */ | ||
diff --git a/arch/mips/include/asm/mach-loongson1/prom.h b/arch/mips/include/asm/mach-loongson1/prom.h new file mode 100644 index 000000000000..b871dc41b8d9 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson1/prom.h | |||
| @@ -0,0 +1,24 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com> | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License as published by the | ||
| 6 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 7 | * option) any later version. | ||
| 8 | */ | ||
| 9 | |||
| 10 | #ifndef __ASM_MACH_LOONGSON1_PROM_H | ||
| 11 | #define __ASM_MACH_LOONGSON1_PROM_H | ||
| 12 | |||
| 13 | #include <linux/io.h> | ||
| 14 | #include <linux/init.h> | ||
| 15 | #include <linux/irq.h> | ||
| 16 | |||
| 17 | /* environment arguments from bootloader */ | ||
| 18 | extern unsigned long memsize, highmemsize; | ||
| 19 | |||
| 20 | /* loongson-specific command line, env and memory initialization */ | ||
| 21 | extern char *prom_getenv(char *name); | ||
| 22 | extern void __init prom_init_cmdline(void); | ||
| 23 | |||
| 24 | #endif /* __ASM_MACH_LOONGSON1_PROM_H */ | ||
diff --git a/arch/mips/include/asm/mach-loongson1/regs-clk.h b/arch/mips/include/asm/mach-loongson1/regs-clk.h new file mode 100644 index 000000000000..8efa7fb9f73a --- /dev/null +++ b/arch/mips/include/asm/mach-loongson1/regs-clk.h | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com> | ||
| 3 | * | ||
| 4 | * Loongson 1 Clock Register Definitions. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify it | ||
| 7 | * under the terms of the GNU General Public License as published by the | ||
| 8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 9 | * option) any later version. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #ifndef __ASM_MACH_LOONGSON1_REGS_CLK_H | ||
| 13 | #define __ASM_MACH_LOONGSON1_REGS_CLK_H | ||
| 14 | |||
| 15 | #define LS1X_CLK_REG(x) \ | ||
| 16 | ((void __iomem *)KSEG1ADDR(LS1X_CLK_BASE + (x))) | ||
| 17 | |||
| 18 | #define LS1X_CLK_PLL_FREQ LS1X_CLK_REG(0x0) | ||
| 19 | #define LS1X_CLK_PLL_DIV LS1X_CLK_REG(0x4) | ||
| 20 | |||
| 21 | /* Clock PLL Divisor Register Bits */ | ||
| 22 | #define DIV_DC_EN (0x1 << 31) | ||
| 23 | #define DIV_DC (0x1f << 26) | ||
| 24 | #define DIV_CPU_EN (0x1 << 25) | ||
| 25 | #define DIV_CPU (0x1f << 20) | ||
| 26 | #define DIV_DDR_EN (0x1 << 19) | ||
| 27 | #define DIV_DDR (0x1f << 14) | ||
| 28 | |||
| 29 | #define DIV_DC_SHIFT 26 | ||
| 30 | #define DIV_CPU_SHIFT 20 | ||
| 31 | #define DIV_DDR_SHIFT 14 | ||
| 32 | |||
| 33 | #endif /* __ASM_MACH_LOONGSON1_REGS_CLK_H */ | ||
diff --git a/arch/mips/include/asm/mach-loongson1/regs-wdt.h b/arch/mips/include/asm/mach-loongson1/regs-wdt.h new file mode 100644 index 000000000000..f897de68c527 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson1/regs-wdt.h | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com> | ||
| 3 | * | ||
| 4 | * Loongson 1 watchdog register definitions. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify it | ||
| 7 | * under the terms of the GNU General Public License as published by the | ||
| 8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 9 | * option) any later version. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #ifndef __ASM_MACH_LOONGSON1_REGS_WDT_H | ||
| 13 | #define __ASM_MACH_LOONGSON1_REGS_WDT_H | ||
| 14 | |||
| 15 | #define LS1X_WDT_REG(x) \ | ||
| 16 | ((void __iomem *)KSEG1ADDR(LS1X_WDT_BASE + (x))) | ||
| 17 | |||
| 18 | #define LS1X_WDT_EN LS1X_WDT_REG(0x0) | ||
| 19 | #define LS1X_WDT_SET LS1X_WDT_REG(0x4) | ||
| 20 | #define LS1X_WDT_TIMER LS1X_WDT_REG(0x8) | ||
| 21 | |||
| 22 | #endif /* __ASM_MACH_LOONGSON1_REGS_WDT_H */ | ||
diff --git a/arch/mips/include/asm/mach-loongson1/war.h b/arch/mips/include/asm/mach-loongson1/war.h new file mode 100644 index 000000000000..e3680a8fb349 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson1/war.h | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | /* | ||
| 2 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 3 | * License. See the file "COPYING" in the main directory of this archive | ||
| 4 | * for more details. | ||
| 5 | * | ||
| 6 | * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org> | ||
| 7 | */ | ||
| 8 | #ifndef __ASM_MACH_LOONGSON1_WAR_H | ||
| 9 | #define __ASM_MACH_LOONGSON1_WAR_H | ||
| 10 | |||
| 11 | #define R4600_V1_INDEX_ICACHEOP_WAR 0 | ||
| 12 | #define R4600_V1_HIT_CACHEOP_WAR 0 | ||
| 13 | #define R4600_V2_HIT_CACHEOP_WAR 0 | ||
| 14 | #define R5432_CP0_INTERRUPT_WAR 0 | ||
| 15 | #define BCM1250_M3_WAR 0 | ||
| 16 | #define SIBYTE_1956_WAR 0 | ||
| 17 | #define MIPS4K_ICACHE_REFILL_WAR 0 | ||
| 18 | #define MIPS_CACHE_SYNC_WAR 0 | ||
| 19 | #define TX49XX_ICACHE_INDEX_INV_WAR 0 | ||
| 20 | #define RM9000_CDEX_SMP_WAR 0 | ||
| 21 | #define ICACHE_REFILLS_WORKAROUND_WAR 0 | ||
| 22 | #define R10000_LLSC_WAR 0 | ||
| 23 | #define MIPS34K_MISSED_ITLB_WAR 0 | ||
| 24 | |||
| 25 | #endif /* __ASM_MACH_LOONGSON1_WAR_H */ | ||
diff --git a/arch/mips/include/asm/mach-netlogic/cpu-feature-overrides.h b/arch/mips/include/asm/mach-netlogic/cpu-feature-overrides.h index d193fb68cf27..966db4be377c 100644 --- a/arch/mips/include/asm/mach-netlogic/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-netlogic/cpu-feature-overrides.h | |||
| @@ -48,7 +48,6 @@ | |||
| 48 | #define cpu_has_userlocal 1 | 48 | #define cpu_has_userlocal 1 |
| 49 | #define cpu_has_mips32r2 1 | 49 | #define cpu_has_mips32r2 1 |
| 50 | #define cpu_has_mips64r2 1 | 50 | #define cpu_has_mips64r2 1 |
| 51 | #define cpu_has_dc_aliases 1 | ||
| 52 | #else | 51 | #else |
| 53 | #error "Unknown Netlogic CPU" | 52 | #error "Unknown Netlogic CPU" |
| 54 | #endif | 53 | #endif |
diff --git a/arch/mips/include/asm/mach-tx49xx/mangle-port.h b/arch/mips/include/asm/mach-tx49xx/mangle-port.h index 5e6912fdd0ed..490867b03c8f 100644 --- a/arch/mips/include/asm/mach-tx49xx/mangle-port.h +++ b/arch/mips/include/asm/mach-tx49xx/mangle-port.h | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | #define ioswabb(a, x) (x) | 9 | #define ioswabb(a, x) (x) |
| 10 | #define __mem_ioswabb(a, x) (x) | 10 | #define __mem_ioswabb(a, x) (x) |
| 11 | #if defined(CONFIG_TOSHIBA_RBTX4939) && \ | 11 | #if defined(CONFIG_TOSHIBA_RBTX4939) && \ |
| 12 | (defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)) && \ | 12 | IS_ENABLED(CONFIG_SMC91X) && \ |
| 13 | defined(__BIG_ENDIAN) | 13 | defined(__BIG_ENDIAN) |
| 14 | #define NEEDS_TXX9_IOSWABW | 14 | #define NEEDS_TXX9_IOSWABW |
| 15 | extern u16 (*ioswabw)(volatile u16 *a, u16 x); | 15 | extern u16 (*ioswabw)(volatile u16 *a, u16 x); |
diff --git a/arch/mips/include/asm/mipsmtregs.h b/arch/mips/include/asm/mipsmtregs.h index e71ff4c317f2..5b3cb8553e9a 100644 --- a/arch/mips/include/asm/mipsmtregs.h +++ b/arch/mips/include/asm/mipsmtregs.h | |||
| @@ -28,6 +28,9 @@ | |||
| 28 | #define read_c0_vpeconf0() __read_32bit_c0_register($1, 2) | 28 | #define read_c0_vpeconf0() __read_32bit_c0_register($1, 2) |
| 29 | #define write_c0_vpeconf0(val) __write_32bit_c0_register($1, 2, val) | 29 | #define write_c0_vpeconf0(val) __write_32bit_c0_register($1, 2, val) |
| 30 | 30 | ||
| 31 | #define read_c0_vpeconf1() __read_32bit_c0_register($1, 3) | ||
| 32 | #define write_c0_vpeconf1(val) __write_32bit_c0_register($1, 3, val) | ||
| 33 | |||
| 31 | #define read_c0_tcstatus() __read_32bit_c0_register($2, 1) | 34 | #define read_c0_tcstatus() __read_32bit_c0_register($2, 1) |
| 32 | #define write_c0_tcstatus(val) __write_32bit_c0_register($2, 1, val) | 35 | #define write_c0_tcstatus(val) __write_32bit_c0_register($2, 1, val) |
| 33 | 36 | ||
| @@ -124,6 +127,14 @@ | |||
| 124 | #define VPECONF0_XTC_SHIFT 21 | 127 | #define VPECONF0_XTC_SHIFT 21 |
| 125 | #define VPECONF0_XTC (_ULCAST_(0xff) << VPECONF0_XTC_SHIFT) | 128 | #define VPECONF0_XTC (_ULCAST_(0xff) << VPECONF0_XTC_SHIFT) |
| 126 | 129 | ||
| 130 | /* VPEConf1 fields (per VPE) */ | ||
| 131 | #define VPECONF1_NCP1_SHIFT 0 | ||
| 132 | #define VPECONF1_NCP1 (_ULCAST_(0xff) << VPECONF1_NCP1_SHIFT) | ||
| 133 | #define VPECONF1_NCP2_SHIFT 10 | ||
| 134 | #define VPECONF1_NCP2 (_ULCAST_(0xff) << VPECONF1_NCP2_SHIFT) | ||
| 135 | #define VPECONF1_NCX_SHIFT 20 | ||
| 136 | #define VPECONF1_NCX (_ULCAST_(0xff) << VPECONF1_NCX_SHIFT) | ||
| 137 | |||
| 127 | /* TCStatus fields (per TC) */ | 138 | /* TCStatus fields (per TC) */ |
| 128 | #define TCSTATUS_TASID (_ULCAST_(0xff)) | 139 | #define TCSTATUS_TASID (_ULCAST_(0xff)) |
| 129 | #define TCSTATUS_IXMT_SHIFT 10 | 140 | #define TCSTATUS_IXMT_SHIFT 10 |
| @@ -350,6 +361,8 @@ do { \ | |||
| 350 | #define write_vpe_c0_vpecontrol(val) mttc0(1, 1, val) | 361 | #define write_vpe_c0_vpecontrol(val) mttc0(1, 1, val) |
| 351 | #define read_vpe_c0_vpeconf0() mftc0(1, 2) | 362 | #define read_vpe_c0_vpeconf0() mftc0(1, 2) |
| 352 | #define write_vpe_c0_vpeconf0(val) mttc0(1, 2, val) | 363 | #define write_vpe_c0_vpeconf0(val) mttc0(1, 2, val) |
| 364 | #define read_vpe_c0_vpeconf1() mftc0(1, 3) | ||
| 365 | #define write_vpe_c0_vpeconf1(val) mttc0(1, 3, val) | ||
| 353 | #define read_vpe_c0_count() mftc0(9, 0) | 366 | #define read_vpe_c0_count() mftc0(9, 0) |
| 354 | #define write_vpe_c0_count(val) mttc0(9, 0, val) | 367 | #define write_vpe_c0_count(val) mttc0(9, 0, val) |
| 355 | #define read_vpe_c0_status() mftc0(12, 0) | 368 | #define read_vpe_c0_status() mftc0(12, 0) |
diff --git a/arch/mips/include/asm/module.h b/arch/mips/include/asm/module.h index 530008048c62..7531ecd654d6 100644 --- a/arch/mips/include/asm/module.h +++ b/arch/mips/include/asm/module.h | |||
| @@ -117,6 +117,8 @@ search_module_dbetables(unsigned long addr) | |||
| 117 | #define MODULE_PROC_FAMILY "RM9000 " | 117 | #define MODULE_PROC_FAMILY "RM9000 " |
| 118 | #elif defined CONFIG_CPU_SB1 | 118 | #elif defined CONFIG_CPU_SB1 |
| 119 | #define MODULE_PROC_FAMILY "SB1 " | 119 | #define MODULE_PROC_FAMILY "SB1 " |
| 120 | #elif defined CONFIG_CPU_LOONGSON1 | ||
| 121 | #define MODULE_PROC_FAMILY "LOONGSON1 " | ||
| 120 | #elif defined CONFIG_CPU_LOONGSON2 | 122 | #elif defined CONFIG_CPU_LOONGSON2 |
| 121 | #define MODULE_PROC_FAMILY "LOONGSON2 " | 123 | #define MODULE_PROC_FAMILY "LOONGSON2 " |
| 122 | #elif defined CONFIG_CPU_CAVIUM_OCTEON | 124 | #elif defined CONFIG_CPU_CAVIUM_OCTEON |
diff --git a/arch/mips/include/asm/netlogic/xlp-hal/cpucontrol.h b/arch/mips/include/asm/netlogic/xlp-hal/cpucontrol.h index bf7d41deb9be..7b63a6b722a0 100644 --- a/arch/mips/include/asm/netlogic/xlp-hal/cpucontrol.h +++ b/arch/mips/include/asm/netlogic/xlp-hal/cpucontrol.h | |||
| @@ -47,7 +47,9 @@ | |||
| 47 | #define CPU_BLOCKID_MAP 10 | 47 | #define CPU_BLOCKID_MAP 10 |
| 48 | 48 | ||
| 49 | #define LSU_DEFEATURE 0x304 | 49 | #define LSU_DEFEATURE 0x304 |
| 50 | #define LSU_CERRLOG_REGID 0x09 | 50 | #define LSU_DEBUG_ADDR 0x305 |
| 51 | #define LSU_DEBUG_DATA0 0x306 | ||
| 52 | #define LSU_CERRLOG_REGID 0x309 | ||
| 51 | #define SCHED_DEFEATURE 0x700 | 53 | #define SCHED_DEFEATURE 0x700 |
| 52 | 54 | ||
| 53 | /* Offsets of interest from the 'MAP' Block */ | 55 | /* Offsets of interest from the 'MAP' Block */ |
diff --git a/arch/mips/include/asm/netlogic/xlp-hal/iomap.h b/arch/mips/include/asm/netlogic/xlp-hal/iomap.h index 86cc3391e50c..2c63f9754640 100644 --- a/arch/mips/include/asm/netlogic/xlp-hal/iomap.h +++ b/arch/mips/include/asm/netlogic/xlp-hal/iomap.h | |||
| @@ -36,6 +36,9 @@ | |||
| 36 | #define __NLM_HAL_IOMAP_H__ | 36 | #define __NLM_HAL_IOMAP_H__ |
| 37 | 37 | ||
| 38 | #define XLP_DEFAULT_IO_BASE 0x18000000 | 38 | #define XLP_DEFAULT_IO_BASE 0x18000000 |
| 39 | #define XLP_DEFAULT_PCI_ECFG_BASE XLP_DEFAULT_IO_BASE | ||
| 40 | #define XLP_DEFAULT_PCI_CFG_BASE 0x1c000000 | ||
| 41 | |||
| 39 | #define NMI_BASE 0xbfc00000 | 42 | #define NMI_BASE 0xbfc00000 |
| 40 | #define XLP_IO_CLK 133333333 | 43 | #define XLP_IO_CLK 133333333 |
| 41 | 44 | ||
| @@ -129,7 +132,7 @@ | |||
| 129 | #define PCI_DEVICE_ID_NLM_PIC 0x1003 | 132 | #define PCI_DEVICE_ID_NLM_PIC 0x1003 |
| 130 | #define PCI_DEVICE_ID_NLM_PCIE 0x1004 | 133 | #define PCI_DEVICE_ID_NLM_PCIE 0x1004 |
| 131 | #define PCI_DEVICE_ID_NLM_EHCI 0x1007 | 134 | #define PCI_DEVICE_ID_NLM_EHCI 0x1007 |
| 132 | #define PCI_DEVICE_ID_NLM_ILK 0x1008 | 135 | #define PCI_DEVICE_ID_NLM_OHCI 0x1008 |
| 133 | #define PCI_DEVICE_ID_NLM_NAE 0x1009 | 136 | #define PCI_DEVICE_ID_NLM_NAE 0x1009 |
| 134 | #define PCI_DEVICE_ID_NLM_POE 0x100A | 137 | #define PCI_DEVICE_ID_NLM_POE 0x100A |
| 135 | #define PCI_DEVICE_ID_NLM_FMN 0x100B | 138 | #define PCI_DEVICE_ID_NLM_FMN 0x100B |
diff --git a/arch/mips/include/asm/netlogic/xlp-hal/pcibus.h b/arch/mips/include/asm/netlogic/xlp-hal/pcibus.h new file mode 100644 index 000000000000..66c323d1bd7d --- /dev/null +++ b/arch/mips/include/asm/netlogic/xlp-hal/pcibus.h | |||
| @@ -0,0 +1,76 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2003-2012 Broadcom Corporation | ||
| 3 | * All Rights Reserved | ||
| 4 | * | ||
| 5 | * This software is available to you under a choice of one of two | ||
| 6 | * licenses. You may choose to be licensed under the terms of the GNU | ||
| 7 | * General Public License (GPL) Version 2, available from the file | ||
| 8 | * COPYING in the main directory of this source tree, or the Broadcom | ||
| 9 | * license below: | ||
| 10 | * | ||
| 11 | * Redistribution and use in source and binary forms, with or without | ||
| 12 | * modification, are permitted provided that the following conditions | ||
| 13 | * are met: | ||
| 14 | * | ||
| 15 | * 1. Redistributions of source code must retain the above copyright | ||
| 16 | * notice, this list of conditions and the following disclaimer. | ||
| 17 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 18 | * notice, this list of conditions and the following disclaimer in | ||
| 19 | * the documentation and/or other materials provided with the | ||
| 20 | * distribution. | ||
| 21 | * | ||
| 22 | * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR | ||
| 23 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
| 24 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 25 | * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE | ||
| 26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
| 27 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
| 28 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
| 29 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
| 30 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE | ||
| 31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN | ||
| 32 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 33 | */ | ||
| 34 | |||
| 35 | #ifndef __NLM_HAL_PCIBUS_H__ | ||
| 36 | #define __NLM_HAL_PCIBUS_H__ | ||
| 37 | |||
| 38 | /* PCIE Memory and IO regions */ | ||
| 39 | #define PCIE_MEM_BASE 0xd0000000ULL | ||
| 40 | #define PCIE_MEM_LIMIT 0xdfffffffULL | ||
| 41 | #define PCIE_IO_BASE 0x14000000ULL | ||
| 42 | #define PCIE_IO_LIMIT 0x15ffffffULL | ||
| 43 | |||
| 44 | #define PCIE_BRIDGE_CMD 0x1 | ||
| 45 | #define PCIE_BRIDGE_MSI_CAP 0x14 | ||
| 46 | #define PCIE_BRIDGE_MSI_ADDRL 0x15 | ||
| 47 | #define PCIE_BRIDGE_MSI_ADDRH 0x16 | ||
| 48 | #define PCIE_BRIDGE_MSI_DATA 0x17 | ||
| 49 | |||
| 50 | /* XLP Global PCIE configuration space registers */ | ||
| 51 | #define PCIE_BYTE_SWAP_MEM_BASE 0x247 | ||
| 52 | #define PCIE_BYTE_SWAP_MEM_LIM 0x248 | ||
| 53 | #define PCIE_BYTE_SWAP_IO_BASE 0x249 | ||
| 54 | #define PCIE_BYTE_SWAP_IO_LIM 0x24A | ||
| 55 | #define PCIE_MSI_STATUS 0x25A | ||
| 56 | #define PCIE_MSI_EN 0x25B | ||
| 57 | #define PCIE_INT_EN0 0x261 | ||
| 58 | |||
| 59 | /* PCIE_MSI_EN */ | ||
| 60 | #define PCIE_MSI_VECTOR_INT_EN 0xFFFFFFFF | ||
| 61 | |||
| 62 | /* PCIE_INT_EN0 */ | ||
| 63 | #define PCIE_MSI_INT_EN (1 << 9) | ||
| 64 | |||
| 65 | #ifndef __ASSEMBLY__ | ||
| 66 | |||
| 67 | #define nlm_read_pcie_reg(b, r) nlm_read_reg(b, r) | ||
| 68 | #define nlm_write_pcie_reg(b, r, v) nlm_write_reg(b, r, v) | ||
| 69 | #define nlm_get_pcie_base(node, inst) \ | ||
| 70 | nlm_pcicfg_base(XLP_IO_PCIE_OFFSET(node, inst)) | ||
| 71 | #define nlm_get_pcie_regbase(node, inst) \ | ||
| 72 | (nlm_get_pcie_base(node, inst) + XLP_IO_PCI_HDRSZ) | ||
| 73 | |||
| 74 | int xlp_pcie_link_irt(int link); | ||
| 75 | #endif | ||
| 76 | #endif /* __NLM_HAL_PCIBUS_H__ */ | ||
diff --git a/arch/mips/include/asm/netlogic/xlp-hal/pic.h b/arch/mips/include/asm/netlogic/xlp-hal/pic.h index b6628f7ccf74..ad8b80233a63 100644 --- a/arch/mips/include/asm/netlogic/xlp-hal/pic.h +++ b/arch/mips/include/asm/netlogic/xlp-hal/pic.h | |||
| @@ -201,7 +201,11 @@ | |||
| 201 | #define PIC_NUM_USB_IRTS 6 | 201 | #define PIC_NUM_USB_IRTS 6 |
| 202 | #define PIC_IRT_USB_0_INDEX 115 | 202 | #define PIC_IRT_USB_0_INDEX 115 |
| 203 | #define PIC_IRT_EHCI_0_INDEX 115 | 203 | #define PIC_IRT_EHCI_0_INDEX 115 |
| 204 | #define PIC_IRT_OHCI_0_INDEX 116 | ||
| 205 | #define PIC_IRT_OHCI_1_INDEX 117 | ||
| 204 | #define PIC_IRT_EHCI_1_INDEX 118 | 206 | #define PIC_IRT_EHCI_1_INDEX 118 |
| 207 | #define PIC_IRT_OHCI_2_INDEX 119 | ||
| 208 | #define PIC_IRT_OHCI_3_INDEX 120 | ||
| 205 | #define PIC_IRT_USB_INDEX(num) ((num) + PIC_IRT_USB_0_INDEX) | 209 | #define PIC_IRT_USB_INDEX(num) ((num) + PIC_IRT_USB_0_INDEX) |
| 206 | /* 115 to 120 */ | 210 | /* 115 to 120 */ |
| 207 | #define PIC_IRT_GDX_INDEX 121 | 211 | #define PIC_IRT_GDX_INDEX 121 |
diff --git a/arch/mips/include/asm/netlogic/xlp-hal/usb.h b/arch/mips/include/asm/netlogic/xlp-hal/usb.h new file mode 100644 index 000000000000..a9cd350dfb6c --- /dev/null +++ b/arch/mips/include/asm/netlogic/xlp-hal/usb.h | |||
| @@ -0,0 +1,64 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2003-2012 Broadcom Corporation | ||
| 3 | * All Rights Reserved | ||
| 4 | * | ||
| 5 | * This software is available to you under a choice of one of two | ||
| 6 | * licenses. You may choose to be licensed under the terms of the GNU | ||
| 7 | * General Public License (GPL) Version 2, available from the file | ||
| 8 | * COPYING in the main directory of this source tree, or the Broadcom | ||
| 9 | * license below: | ||
| 10 | * | ||
| 11 | * Redistribution and use in source and binary forms, with or without | ||
| 12 | * modification, are permitted provided that the following conditions | ||
| 13 | * are met: | ||
| 14 | * | ||
| 15 | * 1. Redistributions of source code must retain the above copyright | ||
| 16 | * notice, this list of conditions and the following disclaimer. | ||
| 17 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 18 | * notice, this list of conditions and the following disclaimer in | ||
| 19 | * the documentation and/or other materials provided with the | ||
| 20 | * distribution. | ||
| 21 | * | ||
| 22 | * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR | ||
| 23 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
| 24 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 25 | * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE | ||
| 26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
| 27 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
| 28 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
| 29 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
| 30 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE | ||
| 31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN | ||
| 32 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 33 | */ | ||
| 34 | |||
| 35 | #ifndef __NLM_HAL_USB_H__ | ||
| 36 | #define __NLM_HAL_USB_H__ | ||
| 37 | |||
| 38 | #define USB_CTL_0 0x01 | ||
| 39 | #define USB_PHY_0 0x0A | ||
| 40 | #define USB_PHY_RESET 0x01 | ||
| 41 | #define USB_PHY_PORT_RESET_0 0x10 | ||
| 42 | #define USB_PHY_PORT_RESET_1 0x20 | ||
| 43 | #define USB_CONTROLLER_RESET 0x01 | ||
| 44 | #define USB_INT_STATUS 0x0E | ||
| 45 | #define USB_INT_EN 0x0F | ||
| 46 | #define USB_PHY_INTERRUPT_EN 0x01 | ||
| 47 | #define USB_OHCI_INTERRUPT_EN 0x02 | ||
| 48 | #define USB_OHCI_INTERRUPT1_EN 0x04 | ||
| 49 | #define USB_OHCI_INTERRUPT2_EN 0x08 | ||
| 50 | #define USB_CTRL_INTERRUPT_EN 0x10 | ||
| 51 | |||
| 52 | #ifndef __ASSEMBLY__ | ||
| 53 | |||
| 54 | #define nlm_read_usb_reg(b, r) nlm_read_reg(b, r) | ||
| 55 | #define nlm_write_usb_reg(b, r, v) nlm_write_reg(b, r, v) | ||
| 56 | #define nlm_get_usb_pcibase(node, inst) \ | ||
| 57 | nlm_pcicfg_base(XLP_IO_USB_OFFSET(node, inst)) | ||
| 58 | #define nlm_get_usb_hcd_base(node, inst) \ | ||
| 59 | nlm_xkphys_map_pcibar0(nlm_get_usb_pcibase(node, inst)) | ||
| 60 | #define nlm_get_usb_regbase(node, inst) \ | ||
| 61 | (nlm_get_usb_pcibase(node, inst) + XLP_IO_PCI_HDRSZ) | ||
| 62 | |||
| 63 | #endif | ||
| 64 | #endif /* __NLM_HAL_USB_H__ */ | ||
diff --git a/arch/mips/include/asm/netlogic/xlp-hal/xlp.h b/arch/mips/include/asm/netlogic/xlp-hal/xlp.h index 1540588e396d..7e47209327a5 100644 --- a/arch/mips/include/asm/netlogic/xlp-hal/xlp.h +++ b/arch/mips/include/asm/netlogic/xlp-hal/xlp.h | |||
| @@ -35,8 +35,21 @@ | |||
| 35 | #ifndef _NLM_HAL_XLP_H | 35 | #ifndef _NLM_HAL_XLP_H |
| 36 | #define _NLM_HAL_XLP_H | 36 | #define _NLM_HAL_XLP_H |
| 37 | 37 | ||
| 38 | #define PIC_UART_0_IRQ 17 | 38 | #define PIC_UART_0_IRQ 17 |
| 39 | #define PIC_UART_1_IRQ 18 | 39 | #define PIC_UART_1_IRQ 18 |
| 40 | #define PIC_PCIE_LINK_0_IRQ 19 | ||
| 41 | #define PIC_PCIE_LINK_1_IRQ 20 | ||
| 42 | #define PIC_PCIE_LINK_2_IRQ 21 | ||
| 43 | #define PIC_PCIE_LINK_3_IRQ 22 | ||
| 44 | #define PIC_EHCI_0_IRQ 23 | ||
| 45 | #define PIC_EHCI_1_IRQ 24 | ||
| 46 | #define PIC_OHCI_0_IRQ 25 | ||
| 47 | #define PIC_OHCI_1_IRQ 26 | ||
| 48 | #define PIC_OHCI_2_IRQ 27 | ||
| 49 | #define PIC_OHCI_3_IRQ 28 | ||
| 50 | #define PIC_MMC_IRQ 29 | ||
| 51 | #define PIC_I2C_0_IRQ 30 | ||
| 52 | #define PIC_I2C_1_IRQ 31 | ||
| 40 | 53 | ||
| 41 | #ifndef __ASSEMBLY__ | 54 | #ifndef __ASSEMBLY__ |
| 42 | 55 | ||
diff --git a/arch/mips/include/asm/netlogic/xlr/bridge.h b/arch/mips/include/asm/netlogic/xlr/bridge.h new file mode 100644 index 000000000000..2d02428c4f1b --- /dev/null +++ b/arch/mips/include/asm/netlogic/xlr/bridge.h | |||
| @@ -0,0 +1,104 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2003-2012 Broadcom Corporation | ||
| 3 | * All Rights Reserved | ||
| 4 | * | ||
| 5 | * This software is available to you under a choice of one of two | ||
| 6 | * licenses. You may choose to be licensed under the terms of the GNU | ||
| 7 | * General Public License (GPL) Version 2, available from the file | ||
| 8 | * COPYING in the main directory of this source tree, or the Broadcom | ||
| 9 | * license below: | ||
| 10 | * | ||
| 11 | * Redistribution and use in source and binary forms, with or without | ||
| 12 | * modification, are permitted provided that the following conditions | ||
| 13 | * are met: | ||
| 14 | * | ||
| 15 | * 1. Redistributions of source code must retain the above copyright | ||
| 16 | * notice, this list of conditions and the following disclaimer. | ||
| 17 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 18 | * notice, this list of conditions and the following disclaimer in | ||
| 19 | * the documentation and/or other materials provided with the | ||
| 20 | * distribution. | ||
| 21 | * | ||
| 22 | * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR | ||
| 23 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
| 24 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 25 | * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE | ||
| 26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
| 27 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
| 28 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
| 29 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
| 30 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE | ||
| 31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN | ||
| 32 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 33 | */ | ||
| 34 | #ifndef _ASM_NLM_BRIDGE_H_ | ||
| 35 | #define _ASM_NLM_BRIDGE_H_ | ||
| 36 | |||
| 37 | #define BRIDGE_DRAM_0_BAR 0 | ||
| 38 | #define BRIDGE_DRAM_1_BAR 1 | ||
| 39 | #define BRIDGE_DRAM_2_BAR 2 | ||
| 40 | #define BRIDGE_DRAM_3_BAR 3 | ||
| 41 | #define BRIDGE_DRAM_4_BAR 4 | ||
| 42 | #define BRIDGE_DRAM_5_BAR 5 | ||
| 43 | #define BRIDGE_DRAM_6_BAR 6 | ||
| 44 | #define BRIDGE_DRAM_7_BAR 7 | ||
| 45 | #define BRIDGE_DRAM_CHN_0_MTR_0_BAR 8 | ||
| 46 | #define BRIDGE_DRAM_CHN_0_MTR_1_BAR 9 | ||
| 47 | #define BRIDGE_DRAM_CHN_0_MTR_2_BAR 10 | ||
| 48 | #define BRIDGE_DRAM_CHN_0_MTR_3_BAR 11 | ||
| 49 | #define BRIDGE_DRAM_CHN_0_MTR_4_BAR 12 | ||
| 50 | #define BRIDGE_DRAM_CHN_0_MTR_5_BAR 13 | ||
| 51 | #define BRIDGE_DRAM_CHN_0_MTR_6_BAR 14 | ||
| 52 | #define BRIDGE_DRAM_CHN_0_MTR_7_BAR 15 | ||
| 53 | #define BRIDGE_DRAM_CHN_1_MTR_0_BAR 16 | ||
| 54 | #define BRIDGE_DRAM_CHN_1_MTR_1_BAR 17 | ||
| 55 | #define BRIDGE_DRAM_CHN_1_MTR_2_BAR 18 | ||
| 56 | #define BRIDGE_DRAM_CHN_1_MTR_3_BAR 19 | ||
| 57 | #define BRIDGE_DRAM_CHN_1_MTR_4_BAR 20 | ||
| 58 | #define BRIDGE_DRAM_CHN_1_MTR_5_BAR 21 | ||
| 59 | #define BRIDGE_DRAM_CHN_1_MTR_6_BAR 22 | ||
| 60 | #define BRIDGE_DRAM_CHN_1_MTR_7_BAR 23 | ||
| 61 | #define BRIDGE_CFG_BAR 24 | ||
| 62 | #define BRIDGE_PHNX_IO_BAR 25 | ||
| 63 | #define BRIDGE_FLASH_BAR 26 | ||
| 64 | #define BRIDGE_SRAM_BAR 27 | ||
| 65 | #define BRIDGE_HTMEM_BAR 28 | ||
| 66 | #define BRIDGE_HTINT_BAR 29 | ||
| 67 | #define BRIDGE_HTPIC_BAR 30 | ||
| 68 | #define BRIDGE_HTSM_BAR 31 | ||
| 69 | #define BRIDGE_HTIO_BAR 32 | ||
| 70 | #define BRIDGE_HTCFG_BAR 33 | ||
| 71 | #define BRIDGE_PCIXCFG_BAR 34 | ||
| 72 | #define BRIDGE_PCIXMEM_BAR 35 | ||
| 73 | #define BRIDGE_PCIXIO_BAR 36 | ||
| 74 | #define BRIDGE_DEVICE_MASK 37 | ||
| 75 | #define BRIDGE_AERR_INTR_LOG1 38 | ||
| 76 | #define BRIDGE_AERR_INTR_LOG2 39 | ||
| 77 | #define BRIDGE_AERR_INTR_LOG3 40 | ||
| 78 | #define BRIDGE_AERR_DEV_STAT 41 | ||
| 79 | #define BRIDGE_AERR1_LOG1 42 | ||
| 80 | #define BRIDGE_AERR1_LOG2 43 | ||
| 81 | #define BRIDGE_AERR1_LOG3 44 | ||
| 82 | #define BRIDGE_AERR1_DEV_STAT 45 | ||
| 83 | #define BRIDGE_AERR_INTR_EN 46 | ||
| 84 | #define BRIDGE_AERR_UPG 47 | ||
| 85 | #define BRIDGE_AERR_CLEAR 48 | ||
| 86 | #define BRIDGE_AERR1_CLEAR 49 | ||
| 87 | #define BRIDGE_SBE_COUNTS 50 | ||
| 88 | #define BRIDGE_DBE_COUNTS 51 | ||
| 89 | #define BRIDGE_BITERR_INT_EN 52 | ||
| 90 | |||
| 91 | #define BRIDGE_SYS2IO_CREDITS 53 | ||
| 92 | #define BRIDGE_EVNT_CNT_CTRL1 54 | ||
| 93 | #define BRIDGE_EVNT_COUNTER1 55 | ||
| 94 | #define BRIDGE_EVNT_CNT_CTRL2 56 | ||
| 95 | #define BRIDGE_EVNT_COUNTER2 57 | ||
| 96 | #define BRIDGE_RESERVED1 58 | ||
| 97 | |||
| 98 | #define BRIDGE_DEFEATURE 59 | ||
| 99 | #define BRIDGE_SCRATCH0 60 | ||
| 100 | #define BRIDGE_SCRATCH1 61 | ||
| 101 | #define BRIDGE_SCRATCH2 62 | ||
| 102 | #define BRIDGE_SCRATCH3 63 | ||
| 103 | |||
| 104 | #endif | ||
diff --git a/arch/mips/include/asm/netlogic/xlr/flash.h b/arch/mips/include/asm/netlogic/xlr/flash.h new file mode 100644 index 000000000000..f8aca5472b6c --- /dev/null +++ b/arch/mips/include/asm/netlogic/xlr/flash.h | |||
| @@ -0,0 +1,55 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2003-2012 Broadcom Corporation | ||
| 3 | * All Rights Reserved | ||
| 4 | * | ||
| 5 | * This software is available to you under a choice of one of two | ||
| 6 | * licenses. You may choose to be licensed under the terms of the GNU | ||
| 7 | * General Public License (GPL) Version 2, available from the file | ||
| 8 | * COPYING in the main directory of this source tree, or the Broadcom | ||
| 9 | * license below: | ||
| 10 | * | ||
| 11 | * Redistribution and use in source and binary forms, with or without | ||
| 12 | * modification, are permitted provided that the following conditions | ||
| 13 | * are met: | ||
| 14 | * | ||
| 15 | * 1. Redistributions of source code must retain the above copyright | ||
| 16 | * notice, this list of conditions and the following disclaimer. | ||
| 17 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 18 | * notice, this list of conditions and the following disclaimer in | ||
| 19 | * the documentation and/or other materials provided with the | ||
| 20 | * distribution. | ||
| 21 | * | ||
| 22 | * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR | ||
| 23 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
| 24 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 25 | * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE | ||
| 26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
| 27 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
| 28 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
| 29 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
| 30 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE | ||
| 31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN | ||
| 32 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 33 | */ | ||
| 34 | #ifndef _ASM_NLM_FLASH_H_ | ||
| 35 | #define _ASM_NLM_FLASH_H_ | ||
| 36 | |||
| 37 | #define FLASH_CSBASE_ADDR(cs) (cs) | ||
| 38 | #define FLASH_CSADDR_MASK(cs) (0x10 + (cs)) | ||
| 39 | #define FLASH_CSDEV_PARM(cs) (0x20 + (cs)) | ||
| 40 | #define FLASH_CSTIME_PARMA(cs) (0x30 + (cs)) | ||
| 41 | #define FLASH_CSTIME_PARMB(cs) (0x40 + (cs)) | ||
| 42 | |||
| 43 | #define FLASH_INT_MASK 0x50 | ||
| 44 | #define FLASH_INT_STATUS 0x60 | ||
| 45 | #define FLASH_ERROR_STATUS 0x70 | ||
| 46 | #define FLASH_ERROR_ADDR 0x80 | ||
| 47 | |||
| 48 | #define FLASH_NAND_CLE(cs) (0x90 + (cs)) | ||
| 49 | #define FLASH_NAND_ALE(cs) (0xa0 + (cs)) | ||
| 50 | |||
| 51 | #define FLASH_NAND_CSDEV_PARAM 0x000041e6 | ||
| 52 | #define FLASH_NAND_CSTIME_PARAMA 0x4f400e22 | ||
| 53 | #define FLASH_NAND_CSTIME_PARAMB 0x000083cf | ||
| 54 | |||
| 55 | #endif | ||
diff --git a/arch/mips/include/asm/netlogic/xlr/gpio.h b/arch/mips/include/asm/netlogic/xlr/gpio.h index 51f6ad4aeb14..8492e835b110 100644 --- a/arch/mips/include/asm/netlogic/xlr/gpio.h +++ b/arch/mips/include/asm/netlogic/xlr/gpio.h | |||
| @@ -35,39 +35,40 @@ | |||
| 35 | #ifndef _ASM_NLM_GPIO_H | 35 | #ifndef _ASM_NLM_GPIO_H |
| 36 | #define _ASM_NLM_GPIO_H | 36 | #define _ASM_NLM_GPIO_H |
| 37 | 37 | ||
| 38 | #define NETLOGIC_GPIO_INT_EN_REG 0 | 38 | #define GPIO_INT_EN_REG 0 |
| 39 | #define NETLOGIC_GPIO_INPUT_INVERSION_REG 1 | 39 | #define GPIO_INPUT_INVERSION_REG 1 |
| 40 | #define NETLOGIC_GPIO_IO_DIR_REG 2 | 40 | #define GPIO_IO_DIR_REG 2 |
| 41 | #define NETLOGIC_GPIO_IO_DATA_WR_REG 3 | 41 | #define GPIO_IO_DATA_WR_REG 3 |
| 42 | #define NETLOGIC_GPIO_IO_DATA_RD_REG 4 | 42 | #define GPIO_IO_DATA_RD_REG 4 |
| 43 | 43 | ||
| 44 | #define NETLOGIC_GPIO_SWRESET_REG 8 | 44 | #define GPIO_SWRESET_REG 8 |
| 45 | #define NETLOGIC_GPIO_DRAM1_CNTRL_REG 9 | 45 | #define GPIO_DRAM1_CNTRL_REG 9 |
| 46 | #define NETLOGIC_GPIO_DRAM1_RATIO_REG 10 | 46 | #define GPIO_DRAM1_RATIO_REG 10 |
| 47 | #define NETLOGIC_GPIO_DRAM1_RESET_REG 11 | 47 | #define GPIO_DRAM1_RESET_REG 11 |
| 48 | #define NETLOGIC_GPIO_DRAM1_STATUS_REG 12 | 48 | #define GPIO_DRAM1_STATUS_REG 12 |
| 49 | #define NETLOGIC_GPIO_DRAM2_CNTRL_REG 13 | 49 | #define GPIO_DRAM2_CNTRL_REG 13 |
| 50 | #define NETLOGIC_GPIO_DRAM2_RATIO_REG 14 | 50 | #define GPIO_DRAM2_RATIO_REG 14 |
| 51 | #define NETLOGIC_GPIO_DRAM2_RESET_REG 15 | 51 | #define GPIO_DRAM2_RESET_REG 15 |
| 52 | #define NETLOGIC_GPIO_DRAM2_STATUS_REG 16 | 52 | #define GPIO_DRAM2_STATUS_REG 16 |
| 53 | 53 | ||
| 54 | #define NETLOGIC_GPIO_PWRON_RESET_CFG_REG 21 | 54 | #define GPIO_PWRON_RESET_CFG_REG 21 |
| 55 | #define NETLOGIC_GPIO_BIST_ALL_GO_STATUS_REG 24 | 55 | #define GPIO_BIST_ALL_GO_STATUS_REG 24 |
| 56 | #define NETLOGIC_GPIO_BIST_CPU_GO_STATUS_REG 25 | 56 | #define GPIO_BIST_CPU_GO_STATUS_REG 25 |
| 57 | #define NETLOGIC_GPIO_BIST_DEV_GO_STATUS_REG 26 | 57 | #define GPIO_BIST_DEV_GO_STATUS_REG 26 |
| 58 | 58 | ||
| 59 | #define NETLOGIC_GPIO_FUSE_BANK_REG 35 | 59 | #define GPIO_FUSE_BANK_REG 35 |
| 60 | #define NETLOGIC_GPIO_CPU_RESET_REG 40 | 60 | #define GPIO_CPU_RESET_REG 40 |
| 61 | #define NETLOGIC_GPIO_RNG_REG 43 | 61 | #define GPIO_RNG_REG 43 |
| 62 | 62 | ||
| 63 | #define NETLOGIC_PWRON_RESET_PCMCIA_BOOT 17 | 63 | #define PWRON_RESET_PCMCIA_BOOT 17 |
| 64 | #define NETLOGIC_GPIO_LED_BITMAP 0x1700000 | ||
| 65 | #define NETLOGIC_GPIO_LED_0_SHIFT 20 | ||
| 66 | #define NETLOGIC_GPIO_LED_1_SHIFT 24 | ||
| 67 | 64 | ||
| 68 | #define NETLOGIC_GPIO_LED_OUTPUT_CODE_RESET 0x01 | 65 | #define GPIO_LED_BITMAP 0x1700000 |
| 69 | #define NETLOGIC_GPIO_LED_OUTPUT_CODE_HARD_RESET 0x02 | 66 | #define GPIO_LED_0_SHIFT 20 |
| 70 | #define NETLOGIC_GPIO_LED_OUTPUT_CODE_SOFT_RESET 0x03 | 67 | #define GPIO_LED_1_SHIFT 24 |
| 71 | #define NETLOGIC_GPIO_LED_OUTPUT_CODE_MAIN 0x04 | 68 | |
| 69 | #define GPIO_LED_OUTPUT_CODE_RESET 0x01 | ||
| 70 | #define GPIO_LED_OUTPUT_CODE_HARD_RESET 0x02 | ||
| 71 | #define GPIO_LED_OUTPUT_CODE_SOFT_RESET 0x03 | ||
| 72 | #define GPIO_LED_OUTPUT_CODE_MAIN 0x04 | ||
| 72 | 73 | ||
| 73 | #endif | 74 | #endif |
diff --git a/arch/mips/include/asm/octeon/cvmx-helper-fpa.h b/arch/mips/include/asm/octeon/cvmx-helper-fpa.h deleted file mode 100644 index 5ff8c93198de..000000000000 --- a/arch/mips/include/asm/octeon/cvmx-helper-fpa.h +++ /dev/null | |||
| @@ -1,64 +0,0 @@ | |||
| 1 | /***********************license start*************** | ||
| 2 | * Author: Cavium Networks | ||
| 3 | * | ||
| 4 | * Contact: support@caviumnetworks.com | ||
| 5 | * This file is part of the OCTEON SDK | ||
| 6 | * | ||
| 7 | * Copyright (c) 2003-2008 Cavium Networks | ||
| 8 | * | ||
| 9 | * This file is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License, Version 2, as | ||
| 11 | * published by the Free Software Foundation. | ||
| 12 | * | ||
| 13 | * This file is distributed in the hope that it will be useful, but | ||
| 14 | * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty | ||
| 15 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or | ||
| 16 | * NONINFRINGEMENT. See the GNU General Public License for more | ||
| 17 | * details. | ||
| 18 | * | ||
| 19 | * You should have received a copy of the GNU General Public License | ||
| 20 | * along with this file; if not, write to the Free Software | ||
| 21 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 22 | * or visit http://www.gnu.org/licenses/. | ||
| 23 | * | ||
| 24 | * This file may also be available under a different license from Cavium. | ||
| 25 | * Contact Cavium Networks for more information | ||
| 26 | ***********************license end**************************************/ | ||
| 27 | |||
| 28 | /** | ||
| 29 | * @file | ||
| 30 | * | ||
| 31 | * Helper functions for FPA setup. | ||
| 32 | * | ||
| 33 | */ | ||
| 34 | #ifndef __CVMX_HELPER_H_FPA__ | ||
| 35 | #define __CVMX_HELPER_H_FPA__ | ||
| 36 | |||
| 37 | /** | ||
| 38 | * Allocate memory and initialize the FPA pools using memory | ||
| 39 | * from cvmx-bootmem. Sizes of each element in the pools is | ||
| 40 | * controlled by the cvmx-config.h header file. Specifying | ||
| 41 | * zero for any parameter will cause that FPA pool to not be | ||
| 42 | * setup. This is useful if you aren't using some of the | ||
| 43 | * hardware and want to save memory. | ||
| 44 | * | ||
| 45 | * @packet_buffers: | ||
| 46 | * Number of packet buffers to allocate | ||
| 47 | * @work_queue_entries: | ||
| 48 | * Number of work queue entries | ||
| 49 | * @pko_buffers: | ||
| 50 | * PKO Command buffers. You should at minimum have two per | ||
| 51 | * each PKO queue. | ||
| 52 | * @tim_buffers: | ||
| 53 | * TIM ring buffer command queues. At least two per timer bucket | ||
| 54 | * is recommened. | ||
| 55 | * @dfa_buffers: | ||
| 56 | * DFA command buffer. A relatively small (32 for example) | ||
| 57 | * number should work. | ||
| 58 | * Returns Zero on success, non-zero if out of memory | ||
| 59 | */ | ||
| 60 | extern int cvmx_helper_initialize_fpa(int packet_buffers, | ||
| 61 | int work_queue_entries, int pko_buffers, | ||
| 62 | int tim_buffers, int dfa_buffers); | ||
| 63 | |||
| 64 | #endif /* __CVMX_HELPER_H__ */ | ||
diff --git a/arch/mips/include/asm/octeon/cvmx-helper.h b/arch/mips/include/asm/octeon/cvmx-helper.h index 3169cd79f2ac..0ac6b9f412be 100644 --- a/arch/mips/include/asm/octeon/cvmx-helper.h +++ b/arch/mips/include/asm/octeon/cvmx-helper.h | |||
| @@ -61,8 +61,6 @@ typedef union { | |||
| 61 | } s; | 61 | } s; |
| 62 | } cvmx_helper_link_info_t; | 62 | } cvmx_helper_link_info_t; |
| 63 | 63 | ||
| 64 | #include "cvmx-helper-fpa.h" | ||
| 65 | |||
| 66 | #include <asm/octeon/cvmx-helper-errata.h> | 64 | #include <asm/octeon/cvmx-helper-errata.h> |
| 67 | #include "cvmx-helper-loop.h" | 65 | #include "cvmx-helper-loop.h" |
| 68 | #include "cvmx-helper-npi.h" | 66 | #include "cvmx-helper-npi.h" |
diff --git a/arch/mips/include/asm/octeon/octeon.h b/arch/mips/include/asm/octeon/octeon.h index f72f768cd3a4..1e2486e23573 100644 --- a/arch/mips/include/asm/octeon/octeon.h +++ b/arch/mips/include/asm/octeon/octeon.h | |||
| @@ -215,11 +215,6 @@ struct octeon_cf_data { | |||
| 215 | int dma_engine; /* -1 for no DMA */ | 215 | int dma_engine; /* -1 for no DMA */ |
| 216 | }; | 216 | }; |
| 217 | 217 | ||
| 218 | struct octeon_i2c_data { | ||
| 219 | unsigned int sys_freq; | ||
| 220 | unsigned int i2c_freq; | ||
| 221 | }; | ||
| 222 | |||
| 223 | extern void octeon_write_lcd(const char *s); | 218 | extern void octeon_write_lcd(const char *s); |
| 224 | extern void octeon_check_cpu_bist(void); | 219 | extern void octeon_check_cpu_bist(void); |
| 225 | extern int octeon_get_boot_debug_flag(void); | 220 | extern int octeon_get_boot_debug_flag(void); |
diff --git a/arch/mips/include/asm/prom.h b/arch/mips/include/asm/prom.h index 7206d445bab8..8808bf548b99 100644 --- a/arch/mips/include/asm/prom.h +++ b/arch/mips/include/asm/prom.h | |||
| @@ -20,9 +20,6 @@ | |||
| 20 | extern int early_init_dt_scan_memory_arch(unsigned long node, | 20 | extern int early_init_dt_scan_memory_arch(unsigned long node, |
| 21 | const char *uname, int depth, void *data); | 21 | const char *uname, int depth, void *data); |
| 22 | 22 | ||
| 23 | extern int reserve_mem_mach(unsigned long addr, unsigned long size); | ||
| 24 | extern void free_mem_mach(unsigned long addr, unsigned long size); | ||
| 25 | |||
| 26 | extern void device_tree_init(void); | 23 | extern void device_tree_init(void); |
| 27 | 24 | ||
| 28 | static inline unsigned long pci_address_to_pio(phys_addr_t address) | 25 | static inline unsigned long pci_address_to_pio(phys_addr_t address) |
diff --git a/arch/mips/include/asm/smtc.h b/arch/mips/include/asm/smtc.h index c9736fc06325..8935426a56ab 100644 --- a/arch/mips/include/asm/smtc.h +++ b/arch/mips/include/asm/smtc.h | |||
| @@ -33,6 +33,12 @@ typedef long asiduse; | |||
| 33 | #endif | 33 | #endif |
| 34 | #endif | 34 | #endif |
| 35 | 35 | ||
| 36 | /* | ||
| 37 | * VPE Management information | ||
| 38 | */ | ||
| 39 | |||
| 40 | #define MAX_SMTC_VPES MAX_SMTC_TLBS /* FIXME: May not always be true. */ | ||
| 41 | |||
| 36 | extern asiduse smtc_live_asid[MAX_SMTC_TLBS][MAX_SMTC_ASIDS]; | 42 | extern asiduse smtc_live_asid[MAX_SMTC_TLBS][MAX_SMTC_ASIDS]; |
| 37 | 43 | ||
| 38 | struct mm_struct; | 44 | struct mm_struct; |
diff --git a/arch/mips/include/asm/uaccess.h b/arch/mips/include/asm/uaccess.h index 653a412c036c..3b92efef56d3 100644 --- a/arch/mips/include/asm/uaccess.h +++ b/arch/mips/include/asm/uaccess.h | |||
| @@ -687,7 +687,7 @@ extern size_t __copy_user(void *__to, const void *__from, size_t __n); | |||
| 687 | __MODULE_JAL(__copy_user) \ | 687 | __MODULE_JAL(__copy_user) \ |
| 688 | : "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r) \ | 688 | : "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r) \ |
| 689 | : \ | 689 | : \ |
| 690 | : "$8", "$9", "$10", "$11", "$12", "$15", "$24", "$31", \ | 690 | : "$8", "$9", "$10", "$11", "$12", "$14", "$15", "$24", "$31", \ |
| 691 | DADDI_SCRATCH, "memory"); \ | 691 | DADDI_SCRATCH, "memory"); \ |
| 692 | __cu_len_r; \ | 692 | __cu_len_r; \ |
| 693 | }) | 693 | }) |
| @@ -797,7 +797,7 @@ extern size_t __copy_user_inatomic(void *__to, const void *__from, size_t __n); | |||
| 797 | ".set\treorder" \ | 797 | ".set\treorder" \ |
| 798 | : "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r) \ | 798 | : "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r) \ |
| 799 | : \ | 799 | : \ |
| 800 | : "$8", "$9", "$10", "$11", "$12", "$15", "$24", "$31", \ | 800 | : "$8", "$9", "$10", "$11", "$12", "$14", "$15", "$24", "$31", \ |
| 801 | DADDI_SCRATCH, "memory"); \ | 801 | DADDI_SCRATCH, "memory"); \ |
| 802 | __cu_len_r; \ | 802 | __cu_len_r; \ |
| 803 | }) | 803 | }) |
| @@ -820,7 +820,7 @@ extern size_t __copy_user_inatomic(void *__to, const void *__from, size_t __n); | |||
| 820 | ".set\treorder" \ | 820 | ".set\treorder" \ |
| 821 | : "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r) \ | 821 | : "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r) \ |
| 822 | : \ | 822 | : \ |
| 823 | : "$8", "$9", "$10", "$11", "$12", "$15", "$24", "$31", \ | 823 | : "$8", "$9", "$10", "$11", "$12", "$14", "$15", "$24", "$31", \ |
| 824 | DADDI_SCRATCH, "memory"); \ | 824 | DADDI_SCRATCH, "memory"); \ |
| 825 | __cu_len_r; \ | 825 | __cu_len_r; \ |
| 826 | }) | 826 | }) |
diff --git a/arch/mips/include/asm/uasm.h b/arch/mips/include/asm/uasm.h index 440a21dab575..3d9f75f7ffc9 100644 --- a/arch/mips/include/asm/uasm.h +++ b/arch/mips/include/asm/uasm.h | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | * Copyright (C) 2004, 2005, 2006, 2008 Thiemo Seufer | 6 | * Copyright (C) 2004, 2005, 2006, 2008 Thiemo Seufer |
| 7 | * Copyright (C) 2005 Maciej W. Rozycki | 7 | * Copyright (C) 2005 Maciej W. Rozycki |
| 8 | * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org) | 8 | * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org) |
| 9 | * Copyright (C) 2012 MIPS Technologies, Inc. | ||
| 9 | */ | 10 | */ |
| 10 | 11 | ||
| 11 | #include <linux/types.h> | 12 | #include <linux/types.h> |
| @@ -62,8 +63,10 @@ void __uasminit uasm_i##op(u32 **buf, unsigned int a, signed int b) | |||
| 62 | 63 | ||
| 63 | Ip_u2u1s3(_addiu); | 64 | Ip_u2u1s3(_addiu); |
| 64 | Ip_u3u1u2(_addu); | 65 | Ip_u3u1u2(_addu); |
| 65 | Ip_u2u1u3(_andi); | ||
| 66 | Ip_u3u1u2(_and); | 66 | Ip_u3u1u2(_and); |
| 67 | Ip_u2u1u3(_andi); | ||
| 68 | Ip_u1u2s3(_bbit0); | ||
| 69 | Ip_u1u2s3(_bbit1); | ||
| 67 | Ip_u1u2s3(_beq); | 70 | Ip_u1u2s3(_beq); |
| 68 | Ip_u1u2s3(_beql); | 71 | Ip_u1u2s3(_beql); |
| 69 | Ip_u1s2(_bgez); | 72 | Ip_u1s2(_bgez); |
| @@ -72,55 +75,54 @@ Ip_u1s2(_bltz); | |||
| 72 | Ip_u1s2(_bltzl); | 75 | Ip_u1s2(_bltzl); |
| 73 | Ip_u1u2s3(_bne); | 76 | Ip_u1u2s3(_bne); |
| 74 | Ip_u2s3u1(_cache); | 77 | Ip_u2s3u1(_cache); |
| 75 | Ip_u1u2u3(_dmfc0); | ||
| 76 | Ip_u1u2u3(_dmtc0); | ||
| 77 | Ip_u2u1s3(_daddiu); | 78 | Ip_u2u1s3(_daddiu); |
| 78 | Ip_u3u1u2(_daddu); | 79 | Ip_u3u1u2(_daddu); |
| 80 | Ip_u2u1msbu3(_dins); | ||
| 81 | Ip_u2u1msbu3(_dinsm); | ||
| 82 | Ip_u1u2u3(_dmfc0); | ||
| 83 | Ip_u1u2u3(_dmtc0); | ||
| 84 | Ip_u2u1u3(_drotr); | ||
| 85 | Ip_u2u1u3(_drotr32); | ||
| 79 | Ip_u2u1u3(_dsll); | 86 | Ip_u2u1u3(_dsll); |
| 80 | Ip_u2u1u3(_dsll32); | 87 | Ip_u2u1u3(_dsll32); |
| 81 | Ip_u2u1u3(_dsra); | 88 | Ip_u2u1u3(_dsra); |
| 82 | Ip_u2u1u3(_dsrl); | 89 | Ip_u2u1u3(_dsrl); |
| 83 | Ip_u2u1u3(_dsrl32); | 90 | Ip_u2u1u3(_dsrl32); |
| 84 | Ip_u2u1u3(_drotr); | ||
| 85 | Ip_u2u1u3(_drotr32); | ||
| 86 | Ip_u3u1u2(_dsubu); | 91 | Ip_u3u1u2(_dsubu); |
| 87 | Ip_0(_eret); | 92 | Ip_0(_eret); |
| 88 | Ip_u1(_j); | 93 | Ip_u1(_j); |
| 89 | Ip_u1(_jal); | 94 | Ip_u1(_jal); |
| 90 | Ip_u1(_jr); | 95 | Ip_u1(_jr); |
| 91 | Ip_u2s3u1(_ld); | 96 | Ip_u2s3u1(_ld); |
| 97 | Ip_u3u1u2(_ldx); | ||
| 92 | Ip_u2s3u1(_ll); | 98 | Ip_u2s3u1(_ll); |
| 93 | Ip_u2s3u1(_lld); | 99 | Ip_u2s3u1(_lld); |
| 94 | Ip_u1s2(_lui); | 100 | Ip_u1s2(_lui); |
| 95 | Ip_u2s3u1(_lw); | 101 | Ip_u2s3u1(_lw); |
| 102 | Ip_u3u1u2(_lwx); | ||
| 96 | Ip_u1u2u3(_mfc0); | 103 | Ip_u1u2u3(_mfc0); |
| 97 | Ip_u1u2u3(_mtc0); | 104 | Ip_u1u2u3(_mtc0); |
| 98 | Ip_u2u1u3(_ori); | ||
| 99 | Ip_u3u1u2(_or); | 105 | Ip_u3u1u2(_or); |
| 106 | Ip_u2u1u3(_ori); | ||
| 100 | Ip_u2s3u1(_pref); | 107 | Ip_u2s3u1(_pref); |
| 101 | Ip_0(_rfe); | 108 | Ip_0(_rfe); |
| 109 | Ip_u2u1u3(_rotr); | ||
| 102 | Ip_u2s3u1(_sc); | 110 | Ip_u2s3u1(_sc); |
| 103 | Ip_u2s3u1(_scd); | 111 | Ip_u2s3u1(_scd); |
| 104 | Ip_u2s3u1(_sd); | 112 | Ip_u2s3u1(_sd); |
| 105 | Ip_u2u1u3(_sll); | 113 | Ip_u2u1u3(_sll); |
| 106 | Ip_u2u1u3(_sra); | 114 | Ip_u2u1u3(_sra); |
| 107 | Ip_u2u1u3(_srl); | 115 | Ip_u2u1u3(_srl); |
| 108 | Ip_u2u1u3(_rotr); | ||
| 109 | Ip_u3u1u2(_subu); | 116 | Ip_u3u1u2(_subu); |
| 110 | Ip_u2s3u1(_sw); | 117 | Ip_u2s3u1(_sw); |
| 118 | Ip_u1(_syscall); | ||
| 111 | Ip_0(_tlbp); | 119 | Ip_0(_tlbp); |
| 112 | Ip_0(_tlbr); | 120 | Ip_0(_tlbr); |
| 113 | Ip_0(_tlbwi); | 121 | Ip_0(_tlbwi); |
| 114 | Ip_0(_tlbwr); | 122 | Ip_0(_tlbwr); |
| 115 | Ip_u3u1u2(_xor); | 123 | Ip_u3u1u2(_xor); |
| 116 | Ip_u2u1u3(_xori); | 124 | Ip_u2u1u3(_xori); |
| 117 | Ip_u2u1msbu3(_dins); | 125 | |
| 118 | Ip_u2u1msbu3(_dinsm); | ||
| 119 | Ip_u1(_syscall); | ||
| 120 | Ip_u1u2s3(_bbit0); | ||
| 121 | Ip_u1u2s3(_bbit1); | ||
| 122 | Ip_u3u1u2(_lwx); | ||
| 123 | Ip_u3u1u2(_ldx); | ||
| 124 | 126 | ||
| 125 | /* Handle labels. */ | 127 | /* Handle labels. */ |
| 126 | struct uasm_label { | 128 | struct uasm_label { |
| @@ -145,37 +147,37 @@ static inline void __uasminit uasm_l##lb(struct uasm_label **lab, u32 *addr) \ | |||
| 145 | 147 | ||
| 146 | /* convenience macros for instructions */ | 148 | /* convenience macros for instructions */ |
| 147 | #ifdef CONFIG_64BIT | 149 | #ifdef CONFIG_64BIT |
| 150 | # define UASM_i_ADDIU(buf, rs, rt, val) uasm_i_daddiu(buf, rs, rt, val) | ||
| 151 | # define UASM_i_ADDU(buf, rs, rt, rd) uasm_i_daddu(buf, rs, rt, rd) | ||
| 152 | # define UASM_i_LL(buf, rs, rt, off) uasm_i_lld(buf, rs, rt, off) | ||
| 148 | # define UASM_i_LW(buf, rs, rt, off) uasm_i_ld(buf, rs, rt, off) | 153 | # define UASM_i_LW(buf, rs, rt, off) uasm_i_ld(buf, rs, rt, off) |
| 149 | # define UASM_i_SW(buf, rs, rt, off) uasm_i_sd(buf, rs, rt, off) | 154 | # define UASM_i_LWX(buf, rs, rt, rd) uasm_i_ldx(buf, rs, rt, rd) |
| 155 | # define UASM_i_MFC0(buf, rt, rd...) uasm_i_dmfc0(buf, rt, rd) | ||
| 156 | # define UASM_i_MTC0(buf, rt, rd...) uasm_i_dmtc0(buf, rt, rd) | ||
| 157 | # define UASM_i_ROTR(buf, rs, rt, sh) uasm_i_drotr(buf, rs, rt, sh) | ||
| 158 | # define UASM_i_SC(buf, rs, rt, off) uasm_i_scd(buf, rs, rt, off) | ||
| 150 | # define UASM_i_SLL(buf, rs, rt, sh) uasm_i_dsll(buf, rs, rt, sh) | 159 | # define UASM_i_SLL(buf, rs, rt, sh) uasm_i_dsll(buf, rs, rt, sh) |
| 151 | # define UASM_i_SRA(buf, rs, rt, sh) uasm_i_dsra(buf, rs, rt, sh) | 160 | # define UASM_i_SRA(buf, rs, rt, sh) uasm_i_dsra(buf, rs, rt, sh) |
| 152 | # define UASM_i_SRL(buf, rs, rt, sh) uasm_i_dsrl(buf, rs, rt, sh) | 161 | # define UASM_i_SRL(buf, rs, rt, sh) uasm_i_dsrl(buf, rs, rt, sh) |
| 153 | # define UASM_i_SRL_SAFE(buf, rs, rt, sh) uasm_i_dsrl_safe(buf, rs, rt, sh) | 162 | # define UASM_i_SRL_SAFE(buf, rs, rt, sh) uasm_i_dsrl_safe(buf, rs, rt, sh) |
| 154 | # define UASM_i_ROTR(buf, rs, rt, sh) uasm_i_drotr(buf, rs, rt, sh) | ||
| 155 | # define UASM_i_MFC0(buf, rt, rd...) uasm_i_dmfc0(buf, rt, rd) | ||
| 156 | # define UASM_i_MTC0(buf, rt, rd...) uasm_i_dmtc0(buf, rt, rd) | ||
| 157 | # define UASM_i_ADDIU(buf, rs, rt, val) uasm_i_daddiu(buf, rs, rt, val) | ||
| 158 | # define UASM_i_ADDU(buf, rs, rt, rd) uasm_i_daddu(buf, rs, rt, rd) | ||
| 159 | # define UASM_i_SUBU(buf, rs, rt, rd) uasm_i_dsubu(buf, rs, rt, rd) | 163 | # define UASM_i_SUBU(buf, rs, rt, rd) uasm_i_dsubu(buf, rs, rt, rd) |
| 160 | # define UASM_i_LL(buf, rs, rt, off) uasm_i_lld(buf, rs, rt, off) | 164 | # define UASM_i_SW(buf, rs, rt, off) uasm_i_sd(buf, rs, rt, off) |
| 161 | # define UASM_i_SC(buf, rs, rt, off) uasm_i_scd(buf, rs, rt, off) | ||
| 162 | # define UASM_i_LWX(buf, rs, rt, rd) uasm_i_ldx(buf, rs, rt, rd) | ||
| 163 | #else | 165 | #else |
| 166 | # define UASM_i_ADDIU(buf, rs, rt, val) uasm_i_addiu(buf, rs, rt, val) | ||
| 167 | # define UASM_i_ADDU(buf, rs, rt, rd) uasm_i_addu(buf, rs, rt, rd) | ||
| 168 | # define UASM_i_LL(buf, rs, rt, off) uasm_i_ll(buf, rs, rt, off) | ||
| 164 | # define UASM_i_LW(buf, rs, rt, off) uasm_i_lw(buf, rs, rt, off) | 169 | # define UASM_i_LW(buf, rs, rt, off) uasm_i_lw(buf, rs, rt, off) |
| 165 | # define UASM_i_SW(buf, rs, rt, off) uasm_i_sw(buf, rs, rt, off) | 170 | # define UASM_i_LWX(buf, rs, rt, rd) uasm_i_lwx(buf, rs, rt, rd) |
| 171 | # define UASM_i_MFC0(buf, rt, rd...) uasm_i_mfc0(buf, rt, rd) | ||
| 172 | # define UASM_i_MTC0(buf, rt, rd...) uasm_i_mtc0(buf, rt, rd) | ||
| 173 | # define UASM_i_ROTR(buf, rs, rt, sh) uasm_i_rotr(buf, rs, rt, sh) | ||
| 174 | # define UASM_i_SC(buf, rs, rt, off) uasm_i_sc(buf, rs, rt, off) | ||
| 166 | # define UASM_i_SLL(buf, rs, rt, sh) uasm_i_sll(buf, rs, rt, sh) | 175 | # define UASM_i_SLL(buf, rs, rt, sh) uasm_i_sll(buf, rs, rt, sh) |
| 167 | # define UASM_i_SRA(buf, rs, rt, sh) uasm_i_sra(buf, rs, rt, sh) | 176 | # define UASM_i_SRA(buf, rs, rt, sh) uasm_i_sra(buf, rs, rt, sh) |
| 168 | # define UASM_i_SRL(buf, rs, rt, sh) uasm_i_srl(buf, rs, rt, sh) | 177 | # define UASM_i_SRL(buf, rs, rt, sh) uasm_i_srl(buf, rs, rt, sh) |
| 169 | # define UASM_i_SRL_SAFE(buf, rs, rt, sh) uasm_i_srl(buf, rs, rt, sh) | 178 | # define UASM_i_SRL_SAFE(buf, rs, rt, sh) uasm_i_srl(buf, rs, rt, sh) |
| 170 | # define UASM_i_ROTR(buf, rs, rt, sh) uasm_i_rotr(buf, rs, rt, sh) | ||
| 171 | # define UASM_i_MFC0(buf, rt, rd...) uasm_i_mfc0(buf, rt, rd) | ||
| 172 | # define UASM_i_MTC0(buf, rt, rd...) uasm_i_mtc0(buf, rt, rd) | ||
| 173 | # define UASM_i_ADDIU(buf, rs, rt, val) uasm_i_addiu(buf, rs, rt, val) | ||
| 174 | # define UASM_i_ADDU(buf, rs, rt, rd) uasm_i_addu(buf, rs, rt, rd) | ||
| 175 | # define UASM_i_SUBU(buf, rs, rt, rd) uasm_i_subu(buf, rs, rt, rd) | 179 | # define UASM_i_SUBU(buf, rs, rt, rd) uasm_i_subu(buf, rs, rt, rd) |
| 176 | # define UASM_i_LL(buf, rs, rt, off) uasm_i_ll(buf, rs, rt, off) | 180 | # define UASM_i_SW(buf, rs, rt, off) uasm_i_sw(buf, rs, rt, off) |
| 177 | # define UASM_i_SC(buf, rs, rt, off) uasm_i_sc(buf, rs, rt, off) | ||
| 178 | # define UASM_i_LWX(buf, rs, rt, rd) uasm_i_lwx(buf, rs, rt, rd) | ||
| 179 | #endif | 181 | #endif |
| 180 | 182 | ||
| 181 | #define uasm_i_b(buf, off) uasm_i_beq(buf, 0, 0, off) | 183 | #define uasm_i_b(buf, off) uasm_i_beq(buf, 0, 0, off) |
| @@ -183,19 +185,10 @@ static inline void __uasminit uasm_l##lb(struct uasm_label **lab, u32 *addr) \ | |||
| 183 | #define uasm_i_beqzl(buf, rs, off) uasm_i_beql(buf, rs, 0, off) | 185 | #define uasm_i_beqzl(buf, rs, off) uasm_i_beql(buf, rs, 0, off) |
| 184 | #define uasm_i_bnez(buf, rs, off) uasm_i_bne(buf, rs, 0, off) | 186 | #define uasm_i_bnez(buf, rs, off) uasm_i_bne(buf, rs, 0, off) |
| 185 | #define uasm_i_bnezl(buf, rs, off) uasm_i_bnel(buf, rs, 0, off) | 187 | #define uasm_i_bnezl(buf, rs, off) uasm_i_bnel(buf, rs, 0, off) |
| 188 | #define uasm_i_ehb(buf) uasm_i_sll(buf, 0, 0, 3) | ||
| 186 | #define uasm_i_move(buf, a, b) UASM_i_ADDU(buf, a, 0, b) | 189 | #define uasm_i_move(buf, a, b) UASM_i_ADDU(buf, a, 0, b) |
| 187 | #define uasm_i_nop(buf) uasm_i_sll(buf, 0, 0, 0) | 190 | #define uasm_i_nop(buf) uasm_i_sll(buf, 0, 0, 0) |
| 188 | #define uasm_i_ssnop(buf) uasm_i_sll(buf, 0, 0, 1) | 191 | #define uasm_i_ssnop(buf) uasm_i_sll(buf, 0, 0, 1) |
| 189 | #define uasm_i_ehb(buf) uasm_i_sll(buf, 0, 0, 3) | ||
| 190 | |||
| 191 | static inline void uasm_i_dsrl_safe(u32 **p, unsigned int a1, | ||
| 192 | unsigned int a2, unsigned int a3) | ||
| 193 | { | ||
| 194 | if (a3 < 32) | ||
| 195 | uasm_i_dsrl(p, a1, a2, a3); | ||
| 196 | else | ||
| 197 | uasm_i_dsrl32(p, a1, a2, a3 - 32); | ||
| 198 | } | ||
| 199 | 192 | ||
| 200 | static inline void uasm_i_drotr_safe(u32 **p, unsigned int a1, | 193 | static inline void uasm_i_drotr_safe(u32 **p, unsigned int a1, |
| 201 | unsigned int a2, unsigned int a3) | 194 | unsigned int a2, unsigned int a3) |
| @@ -215,6 +208,15 @@ static inline void uasm_i_dsll_safe(u32 **p, unsigned int a1, | |||
| 215 | uasm_i_dsll32(p, a1, a2, a3 - 32); | 208 | uasm_i_dsll32(p, a1, a2, a3 - 32); |
| 216 | } | 209 | } |
| 217 | 210 | ||
| 211 | static inline void uasm_i_dsrl_safe(u32 **p, unsigned int a1, | ||
| 212 | unsigned int a2, unsigned int a3) | ||
| 213 | { | ||
| 214 | if (a3 < 32) | ||
| 215 | uasm_i_dsrl(p, a1, a2, a3); | ||
| 216 | else | ||
| 217 | uasm_i_dsrl32(p, a1, a2, a3 - 32); | ||
| 218 | } | ||
| 219 | |||
| 218 | /* Handle relocations. */ | 220 | /* Handle relocations. */ |
| 219 | struct uasm_reloc { | 221 | struct uasm_reloc { |
| 220 | u32 *addr; | 222 | u32 *addr; |
| @@ -234,16 +236,16 @@ void uasm_copy_handler(struct uasm_reloc *rel, struct uasm_label *lab, | |||
| 234 | int uasm_insn_has_bdelay(struct uasm_reloc *rel, u32 *addr); | 236 | int uasm_insn_has_bdelay(struct uasm_reloc *rel, u32 *addr); |
| 235 | 237 | ||
| 236 | /* Convenience functions for labeled branches. */ | 238 | /* Convenience functions for labeled branches. */ |
| 237 | void uasm_il_bltz(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid); | ||
| 238 | void uasm_il_b(u32 **p, struct uasm_reloc **r, int lid); | 239 | void uasm_il_b(u32 **p, struct uasm_reloc **r, int lid); |
| 240 | void uasm_il_bbit0(u32 **p, struct uasm_reloc **r, unsigned int reg, | ||
| 241 | unsigned int bit, int lid); | ||
| 242 | void uasm_il_bbit1(u32 **p, struct uasm_reloc **r, unsigned int reg, | ||
| 243 | unsigned int bit, int lid); | ||
| 239 | void uasm_il_beqz(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid); | 244 | void uasm_il_beqz(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid); |
| 240 | void uasm_il_beqzl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid); | 245 | void uasm_il_beqzl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid); |
| 246 | void uasm_il_bgezl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid); | ||
| 247 | void uasm_il_bgez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid); | ||
| 248 | void uasm_il_bltz(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid); | ||
| 241 | void uasm_il_bne(u32 **p, struct uasm_reloc **r, unsigned int reg1, | 249 | void uasm_il_bne(u32 **p, struct uasm_reloc **r, unsigned int reg1, |
| 242 | unsigned int reg2, int lid); | 250 | unsigned int reg2, int lid); |
| 243 | void uasm_il_bnez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid); | 251 | void uasm_il_bnez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid); |
| 244 | void uasm_il_bgezl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid); | ||
| 245 | void uasm_il_bgez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid); | ||
| 246 | void uasm_il_bbit0(u32 **p, struct uasm_reloc **r, unsigned int reg, | ||
| 247 | unsigned int bit, int lid); | ||
| 248 | void uasm_il_bbit1(u32 **p, struct uasm_reloc **r, unsigned int reg, | ||
| 249 | unsigned int bit, int lid); | ||
diff --git a/arch/mips/include/asm/unistd.h b/arch/mips/include/asm/unistd.h index d8dad5340ea3..bebbde01be92 100644 --- a/arch/mips/include/asm/unistd.h +++ b/arch/mips/include/asm/unistd.h | |||
| @@ -1034,7 +1034,6 @@ | |||
| 1034 | #ifndef __ASSEMBLY__ | 1034 | #ifndef __ASSEMBLY__ |
| 1035 | 1035 | ||
| 1036 | #define __ARCH_OMIT_COMPAT_SYS_GETDENTS64 | 1036 | #define __ARCH_OMIT_COMPAT_SYS_GETDENTS64 |
| 1037 | #define __ARCH_WANT_IPC_PARSE_VERSION | ||
| 1038 | #define __ARCH_WANT_OLD_READDIR | 1037 | #define __ARCH_WANT_OLD_READDIR |
| 1039 | #define __ARCH_WANT_SYS_ALARM | 1038 | #define __ARCH_WANT_SYS_ALARM |
| 1040 | #define __ARCH_WANT_SYS_GETHOSTNAME | 1039 | #define __ARCH_WANT_SYS_GETHOSTNAME |
diff --git a/arch/mips/jz4740/board-qi_lb60.c b/arch/mips/jz4740/board-qi_lb60.c index 9a91fe9de696..9a3d9de4d04e 100644 --- a/arch/mips/jz4740/board-qi_lb60.c +++ b/arch/mips/jz4740/board-qi_lb60.c | |||
| @@ -140,6 +140,7 @@ static void qi_lb60_nand_ident(struct platform_device *pdev, | |||
| 140 | static struct jz_nand_platform_data qi_lb60_nand_pdata = { | 140 | static struct jz_nand_platform_data qi_lb60_nand_pdata = { |
| 141 | .ident_callback = qi_lb60_nand_ident, | 141 | .ident_callback = qi_lb60_nand_ident, |
| 142 | .busy_gpio = 94, | 142 | .busy_gpio = 94, |
| 143 | .banks = { 1 }, | ||
| 143 | }; | 144 | }; |
| 144 | 145 | ||
| 145 | /* Keyboard*/ | 146 | /* Keyboard*/ |
diff --git a/arch/mips/jz4740/platform.c b/arch/mips/jz4740/platform.c index 10929e2bc6d8..e342ed4cbd43 100644 --- a/arch/mips/jz4740/platform.c +++ b/arch/mips/jz4740/platform.c | |||
| @@ -157,11 +157,29 @@ static struct resource jz4740_nand_resources[] = { | |||
| 157 | .flags = IORESOURCE_MEM, | 157 | .flags = IORESOURCE_MEM, |
| 158 | }, | 158 | }, |
| 159 | { | 159 | { |
| 160 | .name = "bank", | 160 | .name = "bank1", |
| 161 | .start = 0x18000000, | 161 | .start = 0x18000000, |
| 162 | .end = 0x180C0000 - 1, | 162 | .end = 0x180C0000 - 1, |
| 163 | .flags = IORESOURCE_MEM, | 163 | .flags = IORESOURCE_MEM, |
| 164 | }, | 164 | }, |
| 165 | { | ||
| 166 | .name = "bank2", | ||
| 167 | .start = 0x14000000, | ||
| 168 | .end = 0x140C0000 - 1, | ||
| 169 | .flags = IORESOURCE_MEM, | ||
| 170 | }, | ||
| 171 | { | ||
| 172 | .name = "bank3", | ||
| 173 | .start = 0x0C000000, | ||
| 174 | .end = 0x0C0C0000 - 1, | ||
| 175 | .flags = IORESOURCE_MEM, | ||
| 176 | }, | ||
| 177 | { | ||
| 178 | .name = "bank4", | ||
| 179 | .start = 0x08000000, | ||
| 180 | .end = 0x080C0000 - 1, | ||
| 181 | .flags = IORESOURCE_MEM, | ||
| 182 | }, | ||
| 165 | }; | 183 | }; |
| 166 | 184 | ||
| 167 | struct platform_device jz4740_nand_device = { | 185 | struct platform_device jz4740_nand_device = { |
diff --git a/arch/mips/jz4740/reset.c b/arch/mips/jz4740/reset.c index 5f1fb95c0d0d..6c0da5afcf17 100644 --- a/arch/mips/jz4740/reset.c +++ b/arch/mips/jz4740/reset.c | |||
| @@ -21,6 +21,9 @@ | |||
| 21 | #include <asm/mach-jz4740/base.h> | 21 | #include <asm/mach-jz4740/base.h> |
| 22 | #include <asm/mach-jz4740/timer.h> | 22 | #include <asm/mach-jz4740/timer.h> |
| 23 | 23 | ||
| 24 | #include "reset.h" | ||
| 25 | #include "clock.h" | ||
| 26 | |||
| 24 | static void jz4740_halt(void) | 27 | static void jz4740_halt(void) |
| 25 | { | 28 | { |
| 26 | while (1) { | 29 | while (1) { |
| @@ -53,21 +56,57 @@ static void jz4740_restart(char *command) | |||
| 53 | jz4740_halt(); | 56 | jz4740_halt(); |
| 54 | } | 57 | } |
| 55 | 58 | ||
| 56 | #define JZ_REG_RTC_CTRL 0x00 | 59 | #define JZ_REG_RTC_CTRL 0x00 |
| 57 | #define JZ_REG_RTC_HIBERNATE 0x20 | 60 | #define JZ_REG_RTC_HIBERNATE 0x20 |
| 61 | #define JZ_REG_RTC_WAKEUP_FILTER 0x24 | ||
| 62 | #define JZ_REG_RTC_RESET_COUNTER 0x28 | ||
| 58 | 63 | ||
| 59 | #define JZ_RTC_CTRL_WRDY BIT(7) | 64 | #define JZ_RTC_CTRL_WRDY BIT(7) |
| 65 | #define JZ_RTC_WAKEUP_FILTER_MASK 0x0000FFE0 | ||
| 66 | #define JZ_RTC_RESET_COUNTER_MASK 0x00000FE0 | ||
| 60 | 67 | ||
| 61 | static void jz4740_power_off(void) | 68 | static inline void jz4740_rtc_wait_ready(void __iomem *rtc_base) |
| 62 | { | 69 | { |
| 63 | void __iomem *rtc_base = ioremap(JZ4740_RTC_BASE_ADDR, 0x24); | ||
| 64 | uint32_t ctrl; | 70 | uint32_t ctrl; |
| 65 | 71 | ||
| 66 | do { | 72 | do { |
| 67 | ctrl = readl(rtc_base + JZ_REG_RTC_CTRL); | 73 | ctrl = readl(rtc_base + JZ_REG_RTC_CTRL); |
| 68 | } while (!(ctrl & JZ_RTC_CTRL_WRDY)); | 74 | } while (!(ctrl & JZ_RTC_CTRL_WRDY)); |
| 75 | } | ||
| 69 | 76 | ||
| 77 | static void jz4740_power_off(void) | ||
| 78 | { | ||
| 79 | void __iomem *rtc_base = ioremap(JZ4740_RTC_BASE_ADDR, 0x38); | ||
| 80 | unsigned long wakeup_filter_ticks; | ||
| 81 | unsigned long reset_counter_ticks; | ||
| 82 | |||
| 83 | /* | ||
| 84 | * Set minimum wakeup pin assertion time: 100 ms. | ||
| 85 | * Range is 0 to 2 sec if RTC is clocked at 32 kHz. | ||
| 86 | */ | ||
| 87 | wakeup_filter_ticks = (100 * jz4740_clock_bdata.rtc_rate) / 1000; | ||
| 88 | if (wakeup_filter_ticks < JZ_RTC_WAKEUP_FILTER_MASK) | ||
| 89 | wakeup_filter_ticks &= JZ_RTC_WAKEUP_FILTER_MASK; | ||
| 90 | else | ||
| 91 | wakeup_filter_ticks = JZ_RTC_WAKEUP_FILTER_MASK; | ||
| 92 | jz4740_rtc_wait_ready(rtc_base); | ||
| 93 | writel(wakeup_filter_ticks, rtc_base + JZ_REG_RTC_WAKEUP_FILTER); | ||
| 94 | |||
| 95 | /* | ||
| 96 | * Set reset pin low-level assertion time after wakeup: 60 ms. | ||
| 97 | * Range is 0 to 125 ms if RTC is clocked at 32 kHz. | ||
| 98 | */ | ||
| 99 | reset_counter_ticks = (60 * jz4740_clock_bdata.rtc_rate) / 1000; | ||
| 100 | if (reset_counter_ticks < JZ_RTC_RESET_COUNTER_MASK) | ||
| 101 | reset_counter_ticks &= JZ_RTC_RESET_COUNTER_MASK; | ||
| 102 | else | ||
| 103 | reset_counter_ticks = JZ_RTC_RESET_COUNTER_MASK; | ||
| 104 | jz4740_rtc_wait_ready(rtc_base); | ||
| 105 | writel(reset_counter_ticks, rtc_base + JZ_REG_RTC_RESET_COUNTER); | ||
| 106 | |||
| 107 | jz4740_rtc_wait_ready(rtc_base); | ||
| 70 | writel(1, rtc_base + JZ_REG_RTC_HIBERNATE); | 108 | writel(1, rtc_base + JZ_REG_RTC_HIBERNATE); |
| 109 | |||
| 71 | jz4740_halt(); | 110 | jz4740_halt(); |
| 72 | } | 111 | } |
| 73 | 112 | ||
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index f4630e1082ab..1b51046191e8 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c | |||
| @@ -190,6 +190,7 @@ void __init check_wait(void) | |||
| 190 | case CPU_CAVIUM_OCTEON_PLUS: | 190 | case CPU_CAVIUM_OCTEON_PLUS: |
| 191 | case CPU_CAVIUM_OCTEON2: | 191 | case CPU_CAVIUM_OCTEON2: |
| 192 | case CPU_JZRISC: | 192 | case CPU_JZRISC: |
| 193 | case CPU_LOONGSON1: | ||
| 193 | case CPU_XLR: | 194 | case CPU_XLR: |
| 194 | case CPU_XLP: | 195 | case CPU_XLP: |
| 195 | cpu_wait = r4k_wait; | 196 | cpu_wait = r4k_wait; |
| @@ -330,6 +331,154 @@ static inline void cpu_probe_vmbits(struct cpuinfo_mips *c) | |||
| 330 | #endif | 331 | #endif |
| 331 | } | 332 | } |
| 332 | 333 | ||
| 334 | static char unknown_isa[] __cpuinitdata = KERN_ERR \ | ||
| 335 | "Unsupported ISA type, c0.config0: %d."; | ||
| 336 | |||
| 337 | static inline unsigned int decode_config0(struct cpuinfo_mips *c) | ||
| 338 | { | ||
| 339 | unsigned int config0; | ||
| 340 | int isa; | ||
| 341 | |||
| 342 | config0 = read_c0_config(); | ||
| 343 | |||
| 344 | if (((config0 & MIPS_CONF_MT) >> 7) == 1) | ||
| 345 | c->options |= MIPS_CPU_TLB; | ||
| 346 | isa = (config0 & MIPS_CONF_AT) >> 13; | ||
| 347 | switch (isa) { | ||
| 348 | case 0: | ||
| 349 | switch ((config0 & MIPS_CONF_AR) >> 10) { | ||
| 350 | case 0: | ||
| 351 | c->isa_level = MIPS_CPU_ISA_M32R1; | ||
| 352 | break; | ||
| 353 | case 1: | ||
| 354 | c->isa_level = MIPS_CPU_ISA_M32R2; | ||
| 355 | break; | ||
| 356 | default: | ||
| 357 | goto unknown; | ||
| 358 | } | ||
| 359 | break; | ||
| 360 | case 2: | ||
| 361 | switch ((config0 & MIPS_CONF_AR) >> 10) { | ||
| 362 | case 0: | ||
| 363 | c->isa_level = MIPS_CPU_ISA_M64R1; | ||
| 364 | break; | ||
| 365 | case 1: | ||
| 366 | c->isa_level = MIPS_CPU_ISA_M64R2; | ||
| 367 | break; | ||
| 368 | default: | ||
| 369 | goto unknown; | ||
| 370 | } | ||
| 371 | break; | ||
| 372 | default: | ||
| 373 | goto unknown; | ||
| 374 | } | ||
| 375 | |||
| 376 | return config0 & MIPS_CONF_M; | ||
| 377 | |||
| 378 | unknown: | ||
| 379 | panic(unknown_isa, config0); | ||
| 380 | } | ||
| 381 | |||
| 382 | static inline unsigned int decode_config1(struct cpuinfo_mips *c) | ||
| 383 | { | ||
| 384 | unsigned int config1; | ||
| 385 | |||
| 386 | config1 = read_c0_config1(); | ||
| 387 | |||
| 388 | if (config1 & MIPS_CONF1_MD) | ||
| 389 | c->ases |= MIPS_ASE_MDMX; | ||
| 390 | if (config1 & MIPS_CONF1_WR) | ||
| 391 | c->options |= MIPS_CPU_WATCH; | ||
| 392 | if (config1 & MIPS_CONF1_CA) | ||
| 393 | c->ases |= MIPS_ASE_MIPS16; | ||
| 394 | if (config1 & MIPS_CONF1_EP) | ||
| 395 | c->options |= MIPS_CPU_EJTAG; | ||
| 396 | if (config1 & MIPS_CONF1_FP) { | ||
| 397 | c->options |= MIPS_CPU_FPU; | ||
| 398 | c->options |= MIPS_CPU_32FPR; | ||
| 399 | } | ||
| 400 | if (cpu_has_tlb) | ||
| 401 | c->tlbsize = ((config1 & MIPS_CONF1_TLBS) >> 25) + 1; | ||
| 402 | |||
| 403 | return config1 & MIPS_CONF_M; | ||
| 404 | } | ||
| 405 | |||
| 406 | static inline unsigned int decode_config2(struct cpuinfo_mips *c) | ||
| 407 | { | ||
| 408 | unsigned int config2; | ||
| 409 | |||
| 410 | config2 = read_c0_config2(); | ||
| 411 | |||
| 412 | if (config2 & MIPS_CONF2_SL) | ||
| 413 | c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT; | ||
| 414 | |||
| 415 | return config2 & MIPS_CONF_M; | ||
| 416 | } | ||
| 417 | |||
| 418 | static inline unsigned int decode_config3(struct cpuinfo_mips *c) | ||
| 419 | { | ||
| 420 | unsigned int config3; | ||
| 421 | |||
| 422 | config3 = read_c0_config3(); | ||
| 423 | |||
| 424 | if (config3 & MIPS_CONF3_SM) | ||
| 425 | c->ases |= MIPS_ASE_SMARTMIPS; | ||
| 426 | if (config3 & MIPS_CONF3_DSP) | ||
| 427 | c->ases |= MIPS_ASE_DSP; | ||
| 428 | if (config3 & MIPS_CONF3_VINT) | ||
| 429 | c->options |= MIPS_CPU_VINT; | ||
| 430 | if (config3 & MIPS_CONF3_VEIC) | ||
| 431 | c->options |= MIPS_CPU_VEIC; | ||
| 432 | if (config3 & MIPS_CONF3_MT) | ||
| 433 | c->ases |= MIPS_ASE_MIPSMT; | ||
| 434 | if (config3 & MIPS_CONF3_ULRI) | ||
| 435 | c->options |= MIPS_CPU_ULRI; | ||
| 436 | |||
| 437 | return config3 & MIPS_CONF_M; | ||
| 438 | } | ||
| 439 | |||
| 440 | static inline unsigned int decode_config4(struct cpuinfo_mips *c) | ||
| 441 | { | ||
| 442 | unsigned int config4; | ||
| 443 | |||
| 444 | config4 = read_c0_config4(); | ||
| 445 | |||
| 446 | if ((config4 & MIPS_CONF4_MMUEXTDEF) == MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT | ||
| 447 | && cpu_has_tlb) | ||
| 448 | c->tlbsize += (config4 & MIPS_CONF4_MMUSIZEEXT) * 0x40; | ||
| 449 | |||
| 450 | c->kscratch_mask = (config4 >> 16) & 0xff; | ||
| 451 | |||
| 452 | return config4 & MIPS_CONF_M; | ||
| 453 | } | ||
| 454 | |||
| 455 | static void __cpuinit decode_configs(struct cpuinfo_mips *c) | ||
| 456 | { | ||
| 457 | int ok; | ||
| 458 | |||
| 459 | /* MIPS32 or MIPS64 compliant CPU. */ | ||
| 460 | c->options = MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE | MIPS_CPU_COUNTER | | ||
| 461 | MIPS_CPU_DIVEC | MIPS_CPU_LLSC | MIPS_CPU_MCHECK; | ||
| 462 | |||
| 463 | c->scache.flags = MIPS_CACHE_NOT_PRESENT; | ||
| 464 | |||
| 465 | ok = decode_config0(c); /* Read Config registers. */ | ||
| 466 | BUG_ON(!ok); /* Arch spec violation! */ | ||
| 467 | if (ok) | ||
| 468 | ok = decode_config1(c); | ||
| 469 | if (ok) | ||
| 470 | ok = decode_config2(c); | ||
| 471 | if (ok) | ||
| 472 | ok = decode_config3(c); | ||
| 473 | if (ok) | ||
| 474 | ok = decode_config4(c); | ||
| 475 | |||
| 476 | mips_probe_watch_registers(c); | ||
| 477 | |||
| 478 | if (cpu_has_mips_r2) | ||
| 479 | c->core = read_c0_ebase() & 0x3ff; | ||
| 480 | } | ||
| 481 | |||
| 333 | #define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE \ | 482 | #define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE \ |
| 334 | | MIPS_CPU_COUNTER) | 483 | | MIPS_CPU_COUNTER) |
| 335 | 484 | ||
| @@ -638,155 +787,19 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) | |||
| 638 | MIPS_CPU_32FPR; | 787 | MIPS_CPU_32FPR; |
| 639 | c->tlbsize = 64; | 788 | c->tlbsize = 64; |
| 640 | break; | 789 | break; |
| 641 | } | 790 | case PRID_IMP_LOONGSON1: |
| 642 | } | 791 | decode_configs(c); |
| 643 | |||
| 644 | static char unknown_isa[] __cpuinitdata = KERN_ERR \ | ||
| 645 | "Unsupported ISA type, c0.config0: %d."; | ||
| 646 | 792 | ||
| 647 | static inline unsigned int decode_config0(struct cpuinfo_mips *c) | 793 | c->cputype = CPU_LOONGSON1; |
| 648 | { | ||
| 649 | unsigned int config0; | ||
| 650 | int isa; | ||
| 651 | 794 | ||
| 652 | config0 = read_c0_config(); | 795 | switch (c->processor_id & PRID_REV_MASK) { |
| 653 | 796 | case PRID_REV_LOONGSON1B: | |
| 654 | if (((config0 & MIPS_CONF_MT) >> 7) == 1) | 797 | __cpu_name[cpu] = "Loongson 1B"; |
| 655 | c->options |= MIPS_CPU_TLB; | ||
| 656 | isa = (config0 & MIPS_CONF_AT) >> 13; | ||
| 657 | switch (isa) { | ||
| 658 | case 0: | ||
| 659 | switch ((config0 & MIPS_CONF_AR) >> 10) { | ||
| 660 | case 0: | ||
| 661 | c->isa_level = MIPS_CPU_ISA_M32R1; | ||
| 662 | break; | ||
| 663 | case 1: | ||
| 664 | c->isa_level = MIPS_CPU_ISA_M32R2; | ||
| 665 | break; | 798 | break; |
| 666 | default: | ||
| 667 | goto unknown; | ||
| 668 | } | 799 | } |
| 669 | break; | ||
| 670 | case 2: | ||
| 671 | switch ((config0 & MIPS_CONF_AR) >> 10) { | ||
| 672 | case 0: | ||
| 673 | c->isa_level = MIPS_CPU_ISA_M64R1; | ||
| 674 | break; | ||
| 675 | case 1: | ||
| 676 | c->isa_level = MIPS_CPU_ISA_M64R2; | ||
| 677 | break; | ||
| 678 | default: | ||
| 679 | goto unknown; | ||
| 680 | } | ||
| 681 | break; | ||
| 682 | default: | ||
| 683 | goto unknown; | ||
| 684 | } | ||
| 685 | |||
| 686 | return config0 & MIPS_CONF_M; | ||
| 687 | |||
| 688 | unknown: | ||
| 689 | panic(unknown_isa, config0); | ||
| 690 | } | ||
| 691 | 800 | ||
| 692 | static inline unsigned int decode_config1(struct cpuinfo_mips *c) | 801 | break; |
| 693 | { | ||
| 694 | unsigned int config1; | ||
| 695 | |||
| 696 | config1 = read_c0_config1(); | ||
| 697 | |||
| 698 | if (config1 & MIPS_CONF1_MD) | ||
| 699 | c->ases |= MIPS_ASE_MDMX; | ||
| 700 | if (config1 & MIPS_CONF1_WR) | ||
| 701 | c->options |= MIPS_CPU_WATCH; | ||
| 702 | if (config1 & MIPS_CONF1_CA) | ||
| 703 | c->ases |= MIPS_ASE_MIPS16; | ||
| 704 | if (config1 & MIPS_CONF1_EP) | ||
| 705 | c->options |= MIPS_CPU_EJTAG; | ||
| 706 | if (config1 & MIPS_CONF1_FP) { | ||
| 707 | c->options |= MIPS_CPU_FPU; | ||
| 708 | c->options |= MIPS_CPU_32FPR; | ||
| 709 | } | 802 | } |
| 710 | if (cpu_has_tlb) | ||
| 711 | c->tlbsize = ((config1 & MIPS_CONF1_TLBS) >> 25) + 1; | ||
| 712 | |||
| 713 | return config1 & MIPS_CONF_M; | ||
| 714 | } | ||
| 715 | |||
| 716 | static inline unsigned int decode_config2(struct cpuinfo_mips *c) | ||
| 717 | { | ||
| 718 | unsigned int config2; | ||
| 719 | |||
| 720 | config2 = read_c0_config2(); | ||
| 721 | |||
| 722 | if (config2 & MIPS_CONF2_SL) | ||
| 723 | c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT; | ||
| 724 | |||
| 725 | return config2 & MIPS_CONF_M; | ||
| 726 | } | ||
| 727 | |||
| 728 | static inline unsigned int decode_config3(struct cpuinfo_mips *c) | ||
| 729 | { | ||
| 730 | unsigned int config3; | ||
| 731 | |||
| 732 | config3 = read_c0_config3(); | ||
| 733 | |||
| 734 | if (config3 & MIPS_CONF3_SM) | ||
| 735 | c->ases |= MIPS_ASE_SMARTMIPS; | ||
| 736 | if (config3 & MIPS_CONF3_DSP) | ||
| 737 | c->ases |= MIPS_ASE_DSP; | ||
| 738 | if (config3 & MIPS_CONF3_VINT) | ||
| 739 | c->options |= MIPS_CPU_VINT; | ||
| 740 | if (config3 & MIPS_CONF3_VEIC) | ||
| 741 | c->options |= MIPS_CPU_VEIC; | ||
| 742 | if (config3 & MIPS_CONF3_MT) | ||
| 743 | c->ases |= MIPS_ASE_MIPSMT; | ||
| 744 | if (config3 & MIPS_CONF3_ULRI) | ||
| 745 | c->options |= MIPS_CPU_ULRI; | ||
| 746 | |||
| 747 | return config3 & MIPS_CONF_M; | ||
| 748 | } | ||
| 749 | |||
| 750 | static inline unsigned int decode_config4(struct cpuinfo_mips *c) | ||
| 751 | { | ||
| 752 | unsigned int config4; | ||
| 753 | |||
| 754 | config4 = read_c0_config4(); | ||
| 755 | |||
| 756 | if ((config4 & MIPS_CONF4_MMUEXTDEF) == MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT | ||
| 757 | && cpu_has_tlb) | ||
| 758 | c->tlbsize += (config4 & MIPS_CONF4_MMUSIZEEXT) * 0x40; | ||
| 759 | |||
| 760 | c->kscratch_mask = (config4 >> 16) & 0xff; | ||
| 761 | |||
| 762 | return config4 & MIPS_CONF_M; | ||
| 763 | } | ||
| 764 | |||
| 765 | static void __cpuinit decode_configs(struct cpuinfo_mips *c) | ||
| 766 | { | ||
| 767 | int ok; | ||
| 768 | |||
| 769 | /* MIPS32 or MIPS64 compliant CPU. */ | ||
| 770 | c->options = MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE | MIPS_CPU_COUNTER | | ||
| 771 | MIPS_CPU_DIVEC | MIPS_CPU_LLSC | MIPS_CPU_MCHECK; | ||
| 772 | |||
| 773 | c->scache.flags = MIPS_CACHE_NOT_PRESENT; | ||
| 774 | |||
| 775 | ok = decode_config0(c); /* Read Config registers. */ | ||
| 776 | BUG_ON(!ok); /* Arch spec violation! */ | ||
| 777 | if (ok) | ||
| 778 | ok = decode_config1(c); | ||
| 779 | if (ok) | ||
| 780 | ok = decode_config2(c); | ||
| 781 | if (ok) | ||
| 782 | ok = decode_config3(c); | ||
| 783 | if (ok) | ||
| 784 | ok = decode_config4(c); | ||
| 785 | |||
| 786 | mips_probe_watch_registers(c); | ||
| 787 | |||
| 788 | if (cpu_has_mips_r2) | ||
| 789 | c->core = read_c0_ebase() & 0x3ff; | ||
| 790 | } | 803 | } |
| 791 | 804 | ||
| 792 | static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu) | 805 | static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu) |
diff --git a/arch/mips/kernel/kspd.c b/arch/mips/kernel/kspd.c index 84d0639e4580..b77f56bbb477 100644 --- a/arch/mips/kernel/kspd.c +++ b/arch/mips/kernel/kspd.c | |||
| @@ -323,7 +323,7 @@ static void sp_cleanup(void) | |||
| 323 | fdt = files_fdtable(files); | 323 | fdt = files_fdtable(files); |
| 324 | for (;;) { | 324 | for (;;) { |
| 325 | unsigned long set; | 325 | unsigned long set; |
| 326 | i = j * __NFDBITS; | 326 | i = j * BITS_PER_LONG; |
| 327 | if (i >= fdt->max_fds) | 327 | if (i >= fdt->max_fds) |
| 328 | break; | 328 | break; |
| 329 | set = fdt->open_fds[j++]; | 329 | set = fdt->open_fds[j++]; |
diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c index eb5e394a4650..2f28d3b55687 100644 --- a/arch/mips/kernel/perf_event_mipsxx.c +++ b/arch/mips/kernel/perf_event_mipsxx.c | |||
| @@ -1559,6 +1559,11 @@ init_hw_perf_events(void) | |||
| 1559 | mipspmu.general_event_map = &mipsxxcore_event_map; | 1559 | mipspmu.general_event_map = &mipsxxcore_event_map; |
| 1560 | mipspmu.cache_event_map = &mipsxxcore_cache_map; | 1560 | mipspmu.cache_event_map = &mipsxxcore_cache_map; |
| 1561 | break; | 1561 | break; |
| 1562 | case CPU_LOONGSON1: | ||
| 1563 | mipspmu.name = "mips/loongson1"; | ||
| 1564 | mipspmu.general_event_map = &mipsxxcore_event_map; | ||
| 1565 | mipspmu.cache_event_map = &mipsxxcore_cache_map; | ||
| 1566 | break; | ||
| 1562 | case CPU_CAVIUM_OCTEON: | 1567 | case CPU_CAVIUM_OCTEON: |
| 1563 | case CPU_CAVIUM_OCTEON_PLUS: | 1568 | case CPU_CAVIUM_OCTEON_PLUS: |
| 1564 | case CPU_CAVIUM_OCTEON2: | 1569 | case CPU_CAVIUM_OCTEON2: |
diff --git a/arch/mips/kernel/prom.c b/arch/mips/kernel/prom.c index f11b2bbb826d..028f6f837ef9 100644 --- a/arch/mips/kernel/prom.c +++ b/arch/mips/kernel/prom.c | |||
| @@ -35,16 +35,6 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size) | |||
| 35 | return add_memory_region(base, size, BOOT_MEM_RAM); | 35 | return add_memory_region(base, size, BOOT_MEM_RAM); |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | int __init reserve_mem_mach(unsigned long addr, unsigned long size) | ||
| 39 | { | ||
| 40 | return reserve_bootmem(addr, size, BOOTMEM_DEFAULT); | ||
| 41 | } | ||
| 42 | |||
| 43 | void __init free_mem_mach(unsigned long addr, unsigned long size) | ||
| 44 | { | ||
| 45 | return free_bootmem(addr, size); | ||
| 46 | } | ||
| 47 | |||
| 48 | void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) | 38 | void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) |
| 49 | { | 39 | { |
| 50 | return __alloc_bootmem(size, align, __pa(MAX_DMA_ADDRESS)); | 40 | return __alloc_bootmem(size, align, __pa(MAX_DMA_ADDRESS)); |
| @@ -77,25 +67,6 @@ void __init early_init_devtree(void *params) | |||
| 77 | of_scan_flat_dt(early_init_dt_scan_memory_arch, NULL); | 67 | of_scan_flat_dt(early_init_dt_scan_memory_arch, NULL); |
| 78 | } | 68 | } |
| 79 | 69 | ||
| 80 | void __init device_tree_init(void) | ||
| 81 | { | ||
| 82 | unsigned long base, size; | ||
| 83 | |||
| 84 | if (!initial_boot_params) | ||
| 85 | return; | ||
| 86 | |||
| 87 | base = virt_to_phys((void *)initial_boot_params); | ||
| 88 | size = be32_to_cpu(initial_boot_params->totalsize); | ||
| 89 | |||
| 90 | /* Before we do anything, lets reserve the dt blob */ | ||
| 91 | reserve_mem_mach(base, size); | ||
| 92 | |||
| 93 | unflatten_device_tree(); | ||
| 94 | |||
| 95 | /* free the space reserved for the dt blob */ | ||
| 96 | free_mem_mach(base, size); | ||
| 97 | } | ||
| 98 | |||
| 99 | void __init __dt_setup_arch(struct boot_param_header *bph) | 70 | void __init __dt_setup_arch(struct boot_param_header *bph) |
| 100 | { | 71 | { |
| 101 | if (be32_to_cpu(bph->magic) != OF_DT_HEADER) { | 72 | if (be32_to_cpu(bph->magic) != OF_DT_HEADER) { |
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 1268392f1d27..31637d8c8738 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c | |||
| @@ -102,7 +102,9 @@ asmlinkage __cpuinit void start_secondary(void) | |||
| 102 | 102 | ||
| 103 | #ifdef CONFIG_MIPS_MT_SMTC | 103 | #ifdef CONFIG_MIPS_MT_SMTC |
| 104 | /* Only do cpu_probe for first TC of CPU */ | 104 | /* Only do cpu_probe for first TC of CPU */ |
| 105 | if ((read_c0_tcbind() & TCBIND_CURTC) == 0) | 105 | if ((read_c0_tcbind() & TCBIND_CURTC) != 0) |
| 106 | __cpu_name[smp_processor_id()] = __cpu_name[0]; | ||
| 107 | else | ||
| 106 | #endif /* CONFIG_MIPS_MT_SMTC */ | 108 | #endif /* CONFIG_MIPS_MT_SMTC */ |
| 107 | cpu_probe(); | 109 | cpu_probe(); |
| 108 | cpu_report(); | 110 | cpu_report(); |
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index 15b5f3cfd20c..1d47843d3cc0 100644 --- a/arch/mips/kernel/smtc.c +++ b/arch/mips/kernel/smtc.c | |||
| @@ -86,6 +86,13 @@ struct smtc_ipi_q IPIQ[NR_CPUS]; | |||
| 86 | static struct smtc_ipi_q freeIPIq; | 86 | static struct smtc_ipi_q freeIPIq; |
| 87 | 87 | ||
| 88 | 88 | ||
| 89 | /* | ||
| 90 | * Number of FPU contexts for each VPE | ||
| 91 | */ | ||
| 92 | |||
| 93 | static int smtc_nconf1[MAX_SMTC_VPES]; | ||
| 94 | |||
| 95 | |||
| 89 | /* Forward declarations */ | 96 | /* Forward declarations */ |
| 90 | 97 | ||
| 91 | void ipi_decode(struct smtc_ipi *); | 98 | void ipi_decode(struct smtc_ipi *); |
| @@ -174,9 +181,9 @@ static int __init tintq(char *str) | |||
| 174 | 181 | ||
| 175 | __setup("tintq=", tintq); | 182 | __setup("tintq=", tintq); |
| 176 | 183 | ||
| 177 | static int imstuckcount[2][8]; | 184 | static int imstuckcount[MAX_SMTC_VPES][8]; |
| 178 | /* vpemask represents IM/IE bits of per-VPE Status registers, low-to-high */ | 185 | /* vpemask represents IM/IE bits of per-VPE Status registers, low-to-high */ |
| 179 | static int vpemask[2][8] = { | 186 | static int vpemask[MAX_SMTC_VPES][8] = { |
| 180 | {0, 0, 1, 0, 0, 0, 0, 1}, | 187 | {0, 0, 1, 0, 0, 0, 0, 1}, |
| 181 | {0, 0, 0, 0, 0, 0, 0, 1} | 188 | {0, 0, 0, 0, 0, 0, 0, 1} |
| 182 | }; | 189 | }; |
| @@ -331,6 +338,22 @@ int __init smtc_build_cpu_map(int start_cpu_slot) | |||
| 331 | 338 | ||
| 332 | static void smtc_tc_setup(int vpe, int tc, int cpu) | 339 | static void smtc_tc_setup(int vpe, int tc, int cpu) |
| 333 | { | 340 | { |
| 341 | static int cp1contexts[MAX_SMTC_VPES]; | ||
| 342 | |||
| 343 | /* | ||
| 344 | * Make a local copy of the available FPU contexts in order | ||
| 345 | * to keep track of TCs that can have one. | ||
| 346 | */ | ||
| 347 | if (tc == 1) | ||
| 348 | { | ||
| 349 | /* | ||
| 350 | * FIXME: Multi-core SMTC hasn't been tested and the | ||
| 351 | * maximum number of VPEs may change. | ||
| 352 | */ | ||
| 353 | cp1contexts[0] = smtc_nconf1[0] - 1; | ||
| 354 | cp1contexts[1] = smtc_nconf1[1]; | ||
| 355 | } | ||
| 356 | |||
| 334 | settc(tc); | 357 | settc(tc); |
| 335 | write_tc_c0_tchalt(TCHALT_H); | 358 | write_tc_c0_tchalt(TCHALT_H); |
| 336 | mips_ihb(); | 359 | mips_ihb(); |
| @@ -343,22 +366,29 @@ static void smtc_tc_setup(int vpe, int tc, int cpu) | |||
| 343 | * an active IPI queue. | 366 | * an active IPI queue. |
| 344 | */ | 367 | */ |
| 345 | write_tc_c0_tccontext((sizeof(struct smtc_ipi_q) * cpu) << 16); | 368 | write_tc_c0_tccontext((sizeof(struct smtc_ipi_q) * cpu) << 16); |
| 346 | /* Bind tc to vpe */ | 369 | |
| 370 | /* Bind TC to VPE. */ | ||
| 347 | write_tc_c0_tcbind(vpe); | 371 | write_tc_c0_tcbind(vpe); |
| 372 | |||
| 348 | /* In general, all TCs should have the same cpu_data indications. */ | 373 | /* In general, all TCs should have the same cpu_data indications. */ |
| 349 | memcpy(&cpu_data[cpu], &cpu_data[0], sizeof(struct cpuinfo_mips)); | 374 | memcpy(&cpu_data[cpu], &cpu_data[0], sizeof(struct cpuinfo_mips)); |
| 350 | /* For 34Kf, start with TC/CPU 0 as sole owner of single FPU context */ | 375 | |
| 351 | if (cpu_data[0].cputype == CPU_34K || | 376 | /* Check to see if there is a FPU context available for this TC. */ |
| 352 | cpu_data[0].cputype == CPU_1004K) | 377 | if (!cp1contexts[vpe]) |
| 353 | cpu_data[cpu].options &= ~MIPS_CPU_FPU; | 378 | cpu_data[cpu].options &= ~MIPS_CPU_FPU; |
| 379 | else | ||
| 380 | cp1contexts[vpe]--; | ||
| 381 | |||
| 382 | /* Store the TC and VPE into the cpu_data structure. */ | ||
| 354 | cpu_data[cpu].vpe_id = vpe; | 383 | cpu_data[cpu].vpe_id = vpe; |
| 355 | cpu_data[cpu].tc_id = tc; | 384 | cpu_data[cpu].tc_id = tc; |
| 356 | /* Multi-core SMTC hasn't been tested, but be prepared */ | 385 | |
| 386 | /* FIXME: Multi-core SMTC hasn't been tested, but be prepared. */ | ||
| 357 | cpu_data[cpu].core = (read_vpe_c0_ebase() >> 1) & 0xff; | 387 | cpu_data[cpu].core = (read_vpe_c0_ebase() >> 1) & 0xff; |
| 358 | } | 388 | } |
| 359 | 389 | ||
| 360 | /* | 390 | /* |
| 361 | * Tweak to get Count registes in as close a sync as possible. The | 391 | * Tweak to get Count registers synced as closely as possible. The |
| 362 | * value seems good for 34K-class cores. | 392 | * value seems good for 34K-class cores. |
| 363 | */ | 393 | */ |
| 364 | 394 | ||
| @@ -466,6 +496,24 @@ void smtc_prepare_cpus(int cpus) | |||
| 466 | smtc_configure_tlb(); | 496 | smtc_configure_tlb(); |
| 467 | 497 | ||
| 468 | for (tc = 0, vpe = 0 ; (vpe < nvpe) && (tc < ntc) ; vpe++) { | 498 | for (tc = 0, vpe = 0 ; (vpe < nvpe) && (tc < ntc) ; vpe++) { |
| 499 | /* Get number of CP1 contexts for each VPE. */ | ||
| 500 | if (tc == 0) | ||
| 501 | { | ||
| 502 | /* | ||
| 503 | * Do not call settc() for TC0 or the FPU context | ||
| 504 | * value will be incorrect. Besides, we know that | ||
| 505 | * we are TC0 anyway. | ||
| 506 | */ | ||
| 507 | smtc_nconf1[0] = ((read_vpe_c0_vpeconf1() & | ||
| 508 | VPECONF1_NCP1) >> VPECONF1_NCP1_SHIFT); | ||
| 509 | if (nvpe == 2) | ||
| 510 | { | ||
| 511 | settc(1); | ||
| 512 | smtc_nconf1[1] = ((read_vpe_c0_vpeconf1() & | ||
| 513 | VPECONF1_NCP1) >> VPECONF1_NCP1_SHIFT); | ||
| 514 | settc(0); | ||
| 515 | } | ||
| 516 | } | ||
| 469 | if (tcpervpe[vpe] == 0) | 517 | if (tcpervpe[vpe] == 0) |
| 470 | continue; | 518 | continue; |
| 471 | if (vpe != 0) | 519 | if (vpe != 0) |
| @@ -479,6 +527,18 @@ void smtc_prepare_cpus(int cpus) | |||
| 479 | */ | 527 | */ |
| 480 | if (tc != 0) { | 528 | if (tc != 0) { |
| 481 | smtc_tc_setup(vpe, tc, cpu); | 529 | smtc_tc_setup(vpe, tc, cpu); |
| 530 | if (vpe != 0) { | ||
| 531 | /* | ||
| 532 | * Set MVP bit (possibly again). Do it | ||
| 533 | * here to catch CPUs that have no TCs | ||
| 534 | * bound to the VPE at reset. In that | ||
| 535 | * case, a TC must be bound to the VPE | ||
| 536 | * before we can set VPEControl[MVP] | ||
| 537 | */ | ||
| 538 | write_vpe_c0_vpeconf0( | ||
| 539 | read_vpe_c0_vpeconf0() | | ||
| 540 | VPECONF0_MVP); | ||
| 541 | } | ||
| 482 | cpu++; | 542 | cpu++; |
| 483 | } | 543 | } |
| 484 | printk(" %d", tc); | 544 | printk(" %d", tc); |
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index c3c293543703..9be3df1fa8a4 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
| @@ -1253,6 +1253,7 @@ static inline void parity_protection_init(void) | |||
| 1253 | 1253 | ||
| 1254 | case CPU_5KC: | 1254 | case CPU_5KC: |
| 1255 | case CPU_5KE: | 1255 | case CPU_5KE: |
| 1256 | case CPU_LOONGSON1: | ||
| 1256 | write_c0_ecc(0x80000000); | 1257 | write_c0_ecc(0x80000000); |
| 1257 | back_to_back_c0_hazard(); | 1258 | back_to_back_c0_hazard(); |
| 1258 | /* Set the PE bit (bit 31) in the c0_errctl register. */ | 1259 | /* Set the PE bit (bit 31) in the c0_errctl register. */ |
diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile index 2a7c74fc15fc..399a50a541d4 100644 --- a/arch/mips/lib/Makefile +++ b/arch/mips/lib/Makefile | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | # Makefile for MIPS-specific library files.. | 2 | # Makefile for MIPS-specific library files.. |
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | lib-y += csum_partial.o delay.o memcpy.o memcpy-inatomic.o memset.o \ | 5 | lib-y += csum_partial.o delay.o memcpy.o memset.o \ |
| 6 | strlen_user.o strncpy_user.o strnlen_user.o uncached.o | 6 | strlen_user.o strncpy_user.o strnlen_user.o uncached.o |
| 7 | 7 | ||
| 8 | obj-y += iomap.o | 8 | obj-y += iomap.o |
diff --git a/arch/mips/lib/memcpy-inatomic.S b/arch/mips/lib/memcpy-inatomic.S deleted file mode 100644 index 68853a038d3f..000000000000 --- a/arch/mips/lib/memcpy-inatomic.S +++ /dev/null | |||
| @@ -1,451 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 3 | * License. See the file "COPYING" in the main directory of this archive | ||
| 4 | * for more details. | ||
| 5 | * | ||
| 6 | * Unified implementation of memcpy, memmove and the __copy_user backend. | ||
| 7 | * | ||
| 8 | * Copyright (C) 1998, 99, 2000, 01, 2002 Ralf Baechle (ralf@gnu.org) | ||
| 9 | * Copyright (C) 1999, 2000, 01, 2002 Silicon Graphics, Inc. | ||
| 10 | * Copyright (C) 2002 Broadcom, Inc. | ||
| 11 | * memcpy/copy_user author: Mark Vandevoorde | ||
| 12 | * Copyright (C) 2007 Maciej W. Rozycki | ||
| 13 | * | ||
| 14 | * Mnemonic names for arguments to memcpy/__copy_user | ||
| 15 | */ | ||
| 16 | |||
| 17 | /* | ||
| 18 | * Hack to resolve longstanding prefetch issue | ||
| 19 | * | ||
| 20 | * Prefetching may be fatal on some systems if we're prefetching beyond the | ||
| 21 | * end of memory on some systems. It's also a seriously bad idea on non | ||
| 22 | * dma-coherent systems. | ||
| 23 | */ | ||
| 24 | #ifdef CONFIG_DMA_NONCOHERENT | ||
| 25 | #undef CONFIG_CPU_HAS_PREFETCH | ||
| 26 | #endif | ||
| 27 | #ifdef CONFIG_MIPS_MALTA | ||
| 28 | #undef CONFIG_CPU_HAS_PREFETCH | ||
| 29 | #endif | ||
| 30 | |||
| 31 | #include <asm/asm.h> | ||
| 32 | #include <asm/asm-offsets.h> | ||
| 33 | #include <asm/regdef.h> | ||
| 34 | |||
| 35 | #define dst a0 | ||
| 36 | #define src a1 | ||
| 37 | #define len a2 | ||
| 38 | |||
| 39 | /* | ||
| 40 | * Spec | ||
| 41 | * | ||
| 42 | * memcpy copies len bytes from src to dst and sets v0 to dst. | ||
| 43 | * It assumes that | ||
| 44 | * - src and dst don't overlap | ||
| 45 | * - src is readable | ||
| 46 | * - dst is writable | ||
| 47 | * memcpy uses the standard calling convention | ||
| 48 | * | ||
| 49 | * __copy_user copies up to len bytes from src to dst and sets a2 (len) to | ||
| 50 | * the number of uncopied bytes due to an exception caused by a read or write. | ||
| 51 | * __copy_user assumes that src and dst don't overlap, and that the call is | ||
| 52 | * implementing one of the following: | ||
| 53 | * copy_to_user | ||
| 54 | * - src is readable (no exceptions when reading src) | ||
| 55 | * copy_from_user | ||
| 56 | * - dst is writable (no exceptions when writing dst) | ||
| 57 | * __copy_user uses a non-standard calling convention; see | ||
| 58 | * include/asm-mips/uaccess.h | ||
| 59 | * | ||
| 60 | * When an exception happens on a load, the handler must | ||
| 61 | # ensure that all of the destination buffer is overwritten to prevent | ||
| 62 | * leaking information to user mode programs. | ||
| 63 | */ | ||
| 64 | |||
| 65 | /* | ||
| 66 | * Implementation | ||
| 67 | */ | ||
| 68 | |||
| 69 | /* | ||
| 70 | * The exception handler for loads requires that: | ||
| 71 | * 1- AT contain the address of the byte just past the end of the source | ||
| 72 | * of the copy, | ||
| 73 | * 2- src_entry <= src < AT, and | ||
| 74 | * 3- (dst - src) == (dst_entry - src_entry), | ||
| 75 | * The _entry suffix denotes values when __copy_user was called. | ||
| 76 | * | ||
| 77 | * (1) is set up up by uaccess.h and maintained by not writing AT in copy_user | ||
| 78 | * (2) is met by incrementing src by the number of bytes copied | ||
| 79 | * (3) is met by not doing loads between a pair of increments of dst and src | ||
| 80 | * | ||
| 81 | * The exception handlers for stores adjust len (if necessary) and return. | ||
| 82 | * These handlers do not need to overwrite any data. | ||
| 83 | * | ||
| 84 | * For __rmemcpy and memmove an exception is always a kernel bug, therefore | ||
| 85 | * they're not protected. | ||
| 86 | */ | ||
| 87 | |||
| 88 | #define EXC(inst_reg,addr,handler) \ | ||
| 89 | 9: inst_reg, addr; \ | ||
| 90 | .section __ex_table,"a"; \ | ||
| 91 | PTR 9b, handler; \ | ||
| 92 | .previous | ||
| 93 | |||
| 94 | /* | ||
| 95 | * Only on the 64-bit kernel we can made use of 64-bit registers. | ||
| 96 | */ | ||
| 97 | #ifdef CONFIG_64BIT | ||
| 98 | #define USE_DOUBLE | ||
| 99 | #endif | ||
| 100 | |||
| 101 | #ifdef USE_DOUBLE | ||
| 102 | |||
| 103 | #define LOAD ld | ||
| 104 | #define LOADL ldl | ||
| 105 | #define LOADR ldr | ||
| 106 | #define STOREL sdl | ||
| 107 | #define STORER sdr | ||
| 108 | #define STORE sd | ||
| 109 | #define ADD daddu | ||
| 110 | #define SUB dsubu | ||
| 111 | #define SRL dsrl | ||
| 112 | #define SRA dsra | ||
| 113 | #define SLL dsll | ||
| 114 | #define SLLV dsllv | ||
| 115 | #define SRLV dsrlv | ||
| 116 | #define NBYTES 8 | ||
| 117 | #define LOG_NBYTES 3 | ||
| 118 | |||
| 119 | /* | ||
| 120 | * As we are sharing code base with the mips32 tree (which use the o32 ABI | ||
| 121 | * register definitions). We need to redefine the register definitions from | ||
| 122 | * the n64 ABI register naming to the o32 ABI register naming. | ||
| 123 | */ | ||
| 124 | #undef t0 | ||
| 125 | #undef t1 | ||
| 126 | #undef t2 | ||
| 127 | #undef t3 | ||
| 128 | #define t0 $8 | ||
| 129 | #define t1 $9 | ||
| 130 | #define t2 $10 | ||
| 131 | #define t3 $11 | ||
| 132 | #define t4 $12 | ||
| 133 | #define t5 $13 | ||
| 134 | #define t6 $14 | ||
| 135 | #define t7 $15 | ||
| 136 | |||
| 137 | #else | ||
| 138 | |||
| 139 | #define LOAD lw | ||
| 140 | #define LOADL lwl | ||
| 141 | #define LOADR lwr | ||
| 142 | #define STOREL swl | ||
| 143 | #define STORER swr | ||
| 144 | #define STORE sw | ||
| 145 | #define ADD addu | ||
| 146 | #define SUB subu | ||
| 147 | #define SRL srl | ||
| 148 | #define SLL sll | ||
| 149 | #define SRA sra | ||
| 150 | #define SLLV sllv | ||
| 151 | #define SRLV srlv | ||
| 152 | #define NBYTES 4 | ||
| 153 | #define LOG_NBYTES 2 | ||
| 154 | |||
| 155 | #endif /* USE_DOUBLE */ | ||
| 156 | |||
| 157 | #ifdef CONFIG_CPU_LITTLE_ENDIAN | ||
| 158 | #define LDFIRST LOADR | ||
| 159 | #define LDREST LOADL | ||
| 160 | #define STFIRST STORER | ||
| 161 | #define STREST STOREL | ||
| 162 | #define SHIFT_DISCARD SLLV | ||
| 163 | #else | ||
| 164 | #define LDFIRST LOADL | ||
| 165 | #define LDREST LOADR | ||
| 166 | #define STFIRST STOREL | ||
| 167 | #define STREST STORER | ||
| 168 | #define SHIFT_DISCARD SRLV | ||
| 169 | #endif | ||
| 170 | |||
| 171 | #define FIRST(unit) ((unit)*NBYTES) | ||
| 172 | #define REST(unit) (FIRST(unit)+NBYTES-1) | ||
| 173 | #define UNIT(unit) FIRST(unit) | ||
| 174 | |||
| 175 | #define ADDRMASK (NBYTES-1) | ||
| 176 | |||
| 177 | .text | ||
| 178 | .set noreorder | ||
| 179 | #ifndef CONFIG_CPU_DADDI_WORKAROUNDS | ||
| 180 | .set noat | ||
| 181 | #else | ||
| 182 | .set at=v1 | ||
| 183 | #endif | ||
| 184 | |||
| 185 | /* | ||
| 186 | * A combined memcpy/__copy_user | ||
| 187 | * __copy_user sets len to 0 for success; else to an upper bound of | ||
| 188 | * the number of uncopied bytes. | ||
| 189 | * memcpy sets v0 to dst. | ||
| 190 | */ | ||
| 191 | .align 5 | ||
| 192 | LEAF(__copy_user_inatomic) | ||
| 193 | /* | ||
| 194 | * Note: dst & src may be unaligned, len may be 0 | ||
| 195 | * Temps | ||
| 196 | */ | ||
| 197 | #define rem t8 | ||
| 198 | |||
| 199 | /* | ||
| 200 | * The "issue break"s below are very approximate. | ||
| 201 | * Issue delays for dcache fills will perturb the schedule, as will | ||
| 202 | * load queue full replay traps, etc. | ||
| 203 | * | ||
| 204 | * If len < NBYTES use byte operations. | ||
| 205 | */ | ||
| 206 | PREF( 0, 0(src) ) | ||
| 207 | PREF( 1, 0(dst) ) | ||
| 208 | sltu t2, len, NBYTES | ||
| 209 | and t1, dst, ADDRMASK | ||
| 210 | PREF( 0, 1*32(src) ) | ||
| 211 | PREF( 1, 1*32(dst) ) | ||
| 212 | bnez t2, .Lcopy_bytes_checklen | ||
| 213 | and t0, src, ADDRMASK | ||
| 214 | PREF( 0, 2*32(src) ) | ||
| 215 | PREF( 1, 2*32(dst) ) | ||
| 216 | bnez t1, .Ldst_unaligned | ||
| 217 | nop | ||
| 218 | bnez t0, .Lsrc_unaligned_dst_aligned | ||
| 219 | /* | ||
| 220 | * use delay slot for fall-through | ||
| 221 | * src and dst are aligned; need to compute rem | ||
| 222 | */ | ||
| 223 | .Lboth_aligned: | ||
| 224 | SRL t0, len, LOG_NBYTES+3 # +3 for 8 units/iter | ||
| 225 | beqz t0, .Lcleanup_both_aligned # len < 8*NBYTES | ||
| 226 | and rem, len, (8*NBYTES-1) # rem = len % (8*NBYTES) | ||
| 227 | PREF( 0, 3*32(src) ) | ||
| 228 | PREF( 1, 3*32(dst) ) | ||
| 229 | .align 4 | ||
| 230 | 1: | ||
| 231 | EXC( LOAD t0, UNIT(0)(src), .Ll_exc) | ||
| 232 | EXC( LOAD t1, UNIT(1)(src), .Ll_exc_copy) | ||
| 233 | EXC( LOAD t2, UNIT(2)(src), .Ll_exc_copy) | ||
| 234 | EXC( LOAD t3, UNIT(3)(src), .Ll_exc_copy) | ||
| 235 | SUB len, len, 8*NBYTES | ||
| 236 | EXC( LOAD t4, UNIT(4)(src), .Ll_exc_copy) | ||
| 237 | EXC( LOAD t7, UNIT(5)(src), .Ll_exc_copy) | ||
| 238 | STORE t0, UNIT(0)(dst) | ||
| 239 | STORE t1, UNIT(1)(dst) | ||
| 240 | EXC( LOAD t0, UNIT(6)(src), .Ll_exc_copy) | ||
| 241 | EXC( LOAD t1, UNIT(7)(src), .Ll_exc_copy) | ||
| 242 | ADD src, src, 8*NBYTES | ||
| 243 | ADD dst, dst, 8*NBYTES | ||
| 244 | STORE t2, UNIT(-6)(dst) | ||
| 245 | STORE t3, UNIT(-5)(dst) | ||
| 246 | STORE t4, UNIT(-4)(dst) | ||
| 247 | STORE t7, UNIT(-3)(dst) | ||
| 248 | STORE t0, UNIT(-2)(dst) | ||
| 249 | STORE t1, UNIT(-1)(dst) | ||
| 250 | PREF( 0, 8*32(src) ) | ||
| 251 | PREF( 1, 8*32(dst) ) | ||
| 252 | bne len, rem, 1b | ||
| 253 | nop | ||
| 254 | |||
| 255 | /* | ||
| 256 | * len == rem == the number of bytes left to copy < 8*NBYTES | ||
| 257 | */ | ||
| 258 | .Lcleanup_both_aligned: | ||
| 259 | beqz len, .Ldone | ||
| 260 | sltu t0, len, 4*NBYTES | ||
| 261 | bnez t0, .Lless_than_4units | ||
| 262 | and rem, len, (NBYTES-1) # rem = len % NBYTES | ||
| 263 | /* | ||
| 264 | * len >= 4*NBYTES | ||
| 265 | */ | ||
| 266 | EXC( LOAD t0, UNIT(0)(src), .Ll_exc) | ||
| 267 | EXC( LOAD t1, UNIT(1)(src), .Ll_exc_copy) | ||
| 268 | EXC( LOAD t2, UNIT(2)(src), .Ll_exc_copy) | ||
| 269 | EXC( LOAD t3, UNIT(3)(src), .Ll_exc_copy) | ||
| 270 | SUB len, len, 4*NBYTES | ||
| 271 | ADD src, src, 4*NBYTES | ||
| 272 | STORE t0, UNIT(0)(dst) | ||
| 273 | STORE t1, UNIT(1)(dst) | ||
| 274 | STORE t2, UNIT(2)(dst) | ||
| 275 | STORE t3, UNIT(3)(dst) | ||
| 276 | .set reorder /* DADDI_WAR */ | ||
| 277 | ADD dst, dst, 4*NBYTES | ||
| 278 | beqz len, .Ldone | ||
| 279 | .set noreorder | ||
| 280 | .Lless_than_4units: | ||
| 281 | /* | ||
| 282 | * rem = len % NBYTES | ||
| 283 | */ | ||
| 284 | beq rem, len, .Lcopy_bytes | ||
| 285 | nop | ||
| 286 | 1: | ||
| 287 | EXC( LOAD t0, 0(src), .Ll_exc) | ||
| 288 | ADD src, src, NBYTES | ||
| 289 | SUB len, len, NBYTES | ||
| 290 | STORE t0, 0(dst) | ||
| 291 | .set reorder /* DADDI_WAR */ | ||
| 292 | ADD dst, dst, NBYTES | ||
| 293 | bne rem, len, 1b | ||
| 294 | .set noreorder | ||
| 295 | |||
| 296 | /* | ||
| 297 | * src and dst are aligned, need to copy rem bytes (rem < NBYTES) | ||
| 298 | * A loop would do only a byte at a time with possible branch | ||
| 299 | * mispredicts. Can't do an explicit LOAD dst,mask,or,STORE | ||
| 300 | * because can't assume read-access to dst. Instead, use | ||
| 301 | * STREST dst, which doesn't require read access to dst. | ||
| 302 | * | ||
| 303 | * This code should perform better than a simple loop on modern, | ||
| 304 | * wide-issue mips processors because the code has fewer branches and | ||
| 305 | * more instruction-level parallelism. | ||
| 306 | */ | ||
| 307 | #define bits t2 | ||
| 308 | beqz len, .Ldone | ||
| 309 | ADD t1, dst, len # t1 is just past last byte of dst | ||
| 310 | li bits, 8*NBYTES | ||
| 311 | SLL rem, len, 3 # rem = number of bits to keep | ||
| 312 | EXC( LOAD t0, 0(src), .Ll_exc) | ||
| 313 | SUB bits, bits, rem # bits = number of bits to discard | ||
| 314 | SHIFT_DISCARD t0, t0, bits | ||
| 315 | STREST t0, -1(t1) | ||
| 316 | jr ra | ||
| 317 | move len, zero | ||
| 318 | .Ldst_unaligned: | ||
| 319 | /* | ||
| 320 | * dst is unaligned | ||
| 321 | * t0 = src & ADDRMASK | ||
| 322 | * t1 = dst & ADDRMASK; T1 > 0 | ||
| 323 | * len >= NBYTES | ||
| 324 | * | ||
| 325 | * Copy enough bytes to align dst | ||
| 326 | * Set match = (src and dst have same alignment) | ||
| 327 | */ | ||
| 328 | #define match rem | ||
| 329 | EXC( LDFIRST t3, FIRST(0)(src), .Ll_exc) | ||
| 330 | ADD t2, zero, NBYTES | ||
| 331 | EXC( LDREST t3, REST(0)(src), .Ll_exc_copy) | ||
| 332 | SUB t2, t2, t1 # t2 = number of bytes copied | ||
| 333 | xor match, t0, t1 | ||
| 334 | STFIRST t3, FIRST(0)(dst) | ||
| 335 | beq len, t2, .Ldone | ||
| 336 | SUB len, len, t2 | ||
| 337 | ADD dst, dst, t2 | ||
| 338 | beqz match, .Lboth_aligned | ||
| 339 | ADD src, src, t2 | ||
| 340 | |||
| 341 | .Lsrc_unaligned_dst_aligned: | ||
| 342 | SRL t0, len, LOG_NBYTES+2 # +2 for 4 units/iter | ||
| 343 | PREF( 0, 3*32(src) ) | ||
| 344 | beqz t0, .Lcleanup_src_unaligned | ||
| 345 | and rem, len, (4*NBYTES-1) # rem = len % 4*NBYTES | ||
| 346 | PREF( 1, 3*32(dst) ) | ||
| 347 | 1: | ||
| 348 | /* | ||
| 349 | * Avoid consecutive LD*'s to the same register since some mips | ||
| 350 | * implementations can't issue them in the same cycle. | ||
| 351 | * It's OK to load FIRST(N+1) before REST(N) because the two addresses | ||
| 352 | * are to the same unit (unless src is aligned, but it's not). | ||
| 353 | */ | ||
| 354 | EXC( LDFIRST t0, FIRST(0)(src), .Ll_exc) | ||
| 355 | EXC( LDFIRST t1, FIRST(1)(src), .Ll_exc_copy) | ||
| 356 | SUB len, len, 4*NBYTES | ||
| 357 | EXC( LDREST t0, REST(0)(src), .Ll_exc_copy) | ||
| 358 | EXC( LDREST t1, REST(1)(src), .Ll_exc_copy) | ||
| 359 | EXC( LDFIRST t2, FIRST(2)(src), .Ll_exc_copy) | ||
| 360 | EXC( LDFIRST t3, FIRST(3)(src), .Ll_exc_copy) | ||
| 361 | EXC( LDREST t2, REST(2)(src), .Ll_exc_copy) | ||
| 362 | EXC( LDREST t3, REST(3)(src), .Ll_exc_copy) | ||
| 363 | PREF( 0, 9*32(src) ) # 0 is PREF_LOAD (not streamed) | ||
| 364 | ADD src, src, 4*NBYTES | ||
| 365 | #ifdef CONFIG_CPU_SB1 | ||
| 366 | nop # improves slotting | ||
| 367 | #endif | ||
| 368 | STORE t0, UNIT(0)(dst) | ||
| 369 | STORE t1, UNIT(1)(dst) | ||
| 370 | STORE t2, UNIT(2)(dst) | ||
| 371 | STORE t3, UNIT(3)(dst) | ||
| 372 | PREF( 1, 9*32(dst) ) # 1 is PREF_STORE (not streamed) | ||
| 373 | .set reorder /* DADDI_WAR */ | ||
| 374 | ADD dst, dst, 4*NBYTES | ||
| 375 | bne len, rem, 1b | ||
| 376 | .set noreorder | ||
| 377 | |||
| 378 | .Lcleanup_src_unaligned: | ||
| 379 | beqz len, .Ldone | ||
| 380 | and rem, len, NBYTES-1 # rem = len % NBYTES | ||
| 381 | beq rem, len, .Lcopy_bytes | ||
| 382 | nop | ||
| 383 | 1: | ||
| 384 | EXC( LDFIRST t0, FIRST(0)(src), .Ll_exc) | ||
| 385 | EXC( LDREST t0, REST(0)(src), .Ll_exc_copy) | ||
| 386 | ADD src, src, NBYTES | ||
| 387 | SUB len, len, NBYTES | ||
| 388 | STORE t0, 0(dst) | ||
| 389 | .set reorder /* DADDI_WAR */ | ||
| 390 | ADD dst, dst, NBYTES | ||
| 391 | bne len, rem, 1b | ||
| 392 | .set noreorder | ||
| 393 | |||
| 394 | .Lcopy_bytes_checklen: | ||
| 395 | beqz len, .Ldone | ||
| 396 | nop | ||
| 397 | .Lcopy_bytes: | ||
| 398 | /* 0 < len < NBYTES */ | ||
| 399 | #define COPY_BYTE(N) \ | ||
| 400 | EXC( lb t0, N(src), .Ll_exc); \ | ||
| 401 | SUB len, len, 1; \ | ||
| 402 | beqz len, .Ldone; \ | ||
| 403 | sb t0, N(dst) | ||
| 404 | |||
| 405 | COPY_BYTE(0) | ||
| 406 | COPY_BYTE(1) | ||
| 407 | #ifdef USE_DOUBLE | ||
| 408 | COPY_BYTE(2) | ||
| 409 | COPY_BYTE(3) | ||
| 410 | COPY_BYTE(4) | ||
| 411 | COPY_BYTE(5) | ||
| 412 | #endif | ||
| 413 | EXC( lb t0, NBYTES-2(src), .Ll_exc) | ||
| 414 | SUB len, len, 1 | ||
| 415 | jr ra | ||
| 416 | sb t0, NBYTES-2(dst) | ||
| 417 | .Ldone: | ||
| 418 | jr ra | ||
| 419 | nop | ||
| 420 | END(__copy_user_inatomic) | ||
| 421 | |||
| 422 | .Ll_exc_copy: | ||
| 423 | /* | ||
| 424 | * Copy bytes from src until faulting load address (or until a | ||
| 425 | * lb faults) | ||
| 426 | * | ||
| 427 | * When reached by a faulting LDFIRST/LDREST, THREAD_BUADDR($28) | ||
| 428 | * may be more than a byte beyond the last address. | ||
| 429 | * Hence, the lb below may get an exception. | ||
| 430 | * | ||
| 431 | * Assumes src < THREAD_BUADDR($28) | ||
| 432 | */ | ||
| 433 | LOAD t0, TI_TASK($28) | ||
| 434 | nop | ||
| 435 | LOAD t0, THREAD_BUADDR(t0) | ||
| 436 | 1: | ||
| 437 | EXC( lb t1, 0(src), .Ll_exc) | ||
| 438 | ADD src, src, 1 | ||
| 439 | sb t1, 0(dst) # can't fault -- we're copy_from_user | ||
| 440 | .set reorder /* DADDI_WAR */ | ||
| 441 | ADD dst, dst, 1 | ||
| 442 | bne src, t0, 1b | ||
| 443 | .set noreorder | ||
| 444 | .Ll_exc: | ||
| 445 | LOAD t0, TI_TASK($28) | ||
| 446 | nop | ||
| 447 | LOAD t0, THREAD_BUADDR(t0) # t0 is just past last good address | ||
| 448 | nop | ||
| 449 | SUB len, AT, t0 # len number of uncopied bytes | ||
| 450 | jr ra | ||
| 451 | nop | ||
diff --git a/arch/mips/lib/memcpy.S b/arch/mips/lib/memcpy.S index 56a1f85a1ce8..65192c06781e 100644 --- a/arch/mips/lib/memcpy.S +++ b/arch/mips/lib/memcpy.S | |||
| @@ -183,6 +183,14 @@ | |||
| 183 | #endif | 183 | #endif |
| 184 | 184 | ||
| 185 | /* | 185 | /* |
| 186 | * t6 is used as a flag to note inatomic mode. | ||
| 187 | */ | ||
| 188 | LEAF(__copy_user_inatomic) | ||
| 189 | b __copy_user_common | ||
| 190 | li t6, 1 | ||
| 191 | END(__copy_user_inatomic) | ||
| 192 | |||
| 193 | /* | ||
| 186 | * A combined memcpy/__copy_user | 194 | * A combined memcpy/__copy_user |
| 187 | * __copy_user sets len to 0 for success; else to an upper bound of | 195 | * __copy_user sets len to 0 for success; else to an upper bound of |
| 188 | * the number of uncopied bytes. | 196 | * the number of uncopied bytes. |
| @@ -193,6 +201,8 @@ LEAF(memcpy) /* a0=dst a1=src a2=len */ | |||
| 193 | move v0, dst /* return value */ | 201 | move v0, dst /* return value */ |
| 194 | .L__memcpy: | 202 | .L__memcpy: |
| 195 | FEXPORT(__copy_user) | 203 | FEXPORT(__copy_user) |
| 204 | li t6, 0 /* not inatomic */ | ||
| 205 | __copy_user_common: | ||
| 196 | /* | 206 | /* |
| 197 | * Note: dst & src may be unaligned, len may be 0 | 207 | * Note: dst & src may be unaligned, len may be 0 |
| 198 | * Temps | 208 | * Temps |
| @@ -458,6 +468,7 @@ EXC( lb t1, 0(src), .Ll_exc) | |||
| 458 | LOAD t0, THREAD_BUADDR(t0) # t0 is just past last good address | 468 | LOAD t0, THREAD_BUADDR(t0) # t0 is just past last good address |
| 459 | nop | 469 | nop |
| 460 | SUB len, AT, t0 # len number of uncopied bytes | 470 | SUB len, AT, t0 # len number of uncopied bytes |
| 471 | bnez t6, .Ldone /* Skip the zeroing part if inatomic */ | ||
| 461 | /* | 472 | /* |
| 462 | * Here's where we rely on src and dst being incremented in tandem, | 473 | * Here's where we rely on src and dst being incremented in tandem, |
| 463 | * See (3) above. | 474 | * See (3) above. |
diff --git a/arch/mips/loongson1/Kconfig b/arch/mips/loongson1/Kconfig new file mode 100644 index 000000000000..237fa214de9f --- /dev/null +++ b/arch/mips/loongson1/Kconfig | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | if MACH_LOONGSON1 | ||
| 2 | |||
| 3 | choice | ||
| 4 | prompt "Machine Type" | ||
| 5 | |||
| 6 | config LOONGSON1_LS1B | ||
| 7 | bool "Loongson LS1B board" | ||
| 8 | select CEVT_R4K | ||
| 9 | select CSRC_R4K | ||
| 10 | select SYS_HAS_CPU_LOONGSON1B | ||
| 11 | select DMA_NONCOHERENT | ||
| 12 | select BOOT_ELF32 | ||
| 13 | select IRQ_CPU | ||
| 14 | select SYS_SUPPORTS_32BIT_KERNEL | ||
| 15 | select SYS_SUPPORTS_LITTLE_ENDIAN | ||
| 16 | select SYS_SUPPORTS_HIGHMEM | ||
| 17 | select SYS_HAS_EARLY_PRINTK | ||
| 18 | |||
| 19 | endchoice | ||
| 20 | |||
| 21 | endif # MACH_LOONGSON1 | ||
diff --git a/arch/mips/loongson1/Makefile b/arch/mips/loongson1/Makefile new file mode 100644 index 000000000000..9719c75886f5 --- /dev/null +++ b/arch/mips/loongson1/Makefile | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | # | ||
| 2 | # Common code for all Loongson 1 based systems | ||
| 3 | # | ||
| 4 | |||
| 5 | obj-$(CONFIG_MACH_LOONGSON1) += common/ | ||
| 6 | |||
| 7 | # | ||
| 8 | # Loongson LS1B board | ||
| 9 | # | ||
| 10 | |||
| 11 | obj-$(CONFIG_LOONGSON1_LS1B) += ls1b/ | ||
diff --git a/arch/mips/loongson1/Platform b/arch/mips/loongson1/Platform new file mode 100644 index 000000000000..99bdefe627af --- /dev/null +++ b/arch/mips/loongson1/Platform | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | cflags-$(CONFIG_CPU_LOONGSON1) += \ | ||
| 2 | $(call cc-option,-march=mips32r2,-mips32r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \ | ||
| 3 | -Wa,-mips32r2 -Wa,--trap | ||
| 4 | |||
| 5 | platform-$(CONFIG_MACH_LOONGSON1) += loongson1/ | ||
| 6 | cflags-$(CONFIG_MACH_LOONGSON1) += -I$(srctree)/arch/mips/include/asm/mach-loongson1 | ||
| 7 | load-$(CONFIG_LOONGSON1_LS1B) += 0xffffffff80100000 | ||
diff --git a/arch/mips/loongson1/common/Makefile b/arch/mips/loongson1/common/Makefile new file mode 100644 index 000000000000..b2797709ef5b --- /dev/null +++ b/arch/mips/loongson1/common/Makefile | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | # | ||
| 2 | # Makefile for common code of loongson1 based machines. | ||
| 3 | # | ||
| 4 | |||
| 5 | obj-y += clock.o irq.o platform.o prom.o reset.o setup.o | ||
diff --git a/arch/mips/loongson1/common/clock.c b/arch/mips/loongson1/common/clock.c new file mode 100644 index 000000000000..2d98fb030596 --- /dev/null +++ b/arch/mips/loongson1/common/clock.c | |||
| @@ -0,0 +1,165 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com> | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License as published by the | ||
| 6 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 7 | * option) any later version. | ||
| 8 | */ | ||
| 9 | |||
| 10 | #include <linux/module.h> | ||
| 11 | #include <linux/list.h> | ||
| 12 | #include <linux/mutex.h> | ||
| 13 | #include <linux/clk.h> | ||
| 14 | #include <linux/err.h> | ||
| 15 | #include <asm/clock.h> | ||
| 16 | #include <asm/time.h> | ||
| 17 | |||
| 18 | #include <loongson1.h> | ||
| 19 | |||
| 20 | static LIST_HEAD(clocks); | ||
| 21 | static DEFINE_MUTEX(clocks_mutex); | ||
| 22 | |||
| 23 | struct clk *clk_get(struct device *dev, const char *name) | ||
| 24 | { | ||
| 25 | struct clk *c; | ||
| 26 | struct clk *ret = NULL; | ||
| 27 | |||
| 28 | mutex_lock(&clocks_mutex); | ||
| 29 | list_for_each_entry(c, &clocks, node) { | ||
| 30 | if (!strcmp(c->name, name)) { | ||
| 31 | ret = c; | ||
| 32 | break; | ||
| 33 | } | ||
| 34 | } | ||
| 35 | mutex_unlock(&clocks_mutex); | ||
| 36 | |||
| 37 | return ret; | ||
| 38 | } | ||
| 39 | EXPORT_SYMBOL(clk_get); | ||
| 40 | |||
| 41 | unsigned long clk_get_rate(struct clk *clk) | ||
| 42 | { | ||
| 43 | return clk->rate; | ||
| 44 | } | ||
| 45 | EXPORT_SYMBOL(clk_get_rate); | ||
| 46 | |||
| 47 | static void pll_clk_init(struct clk *clk) | ||
| 48 | { | ||
| 49 | u32 pll; | ||
| 50 | |||
| 51 | pll = __raw_readl(LS1X_CLK_PLL_FREQ); | ||
| 52 | clk->rate = (12 + (pll & 0x3f)) * 33 / 2 | ||
| 53 | + ((pll >> 8) & 0x3ff) * 33 / 1024 / 2; | ||
| 54 | clk->rate *= 1000000; | ||
| 55 | } | ||
| 56 | |||
| 57 | static void cpu_clk_init(struct clk *clk) | ||
| 58 | { | ||
| 59 | u32 pll, ctrl; | ||
| 60 | |||
| 61 | pll = clk_get_rate(clk->parent); | ||
| 62 | ctrl = __raw_readl(LS1X_CLK_PLL_DIV) & DIV_CPU; | ||
| 63 | clk->rate = pll / (ctrl >> DIV_CPU_SHIFT); | ||
| 64 | } | ||
| 65 | |||
| 66 | static void ddr_clk_init(struct clk *clk) | ||
| 67 | { | ||
| 68 | u32 pll, ctrl; | ||
| 69 | |||
| 70 | pll = clk_get_rate(clk->parent); | ||
| 71 | ctrl = __raw_readl(LS1X_CLK_PLL_DIV) & DIV_DDR; | ||
| 72 | clk->rate = pll / (ctrl >> DIV_DDR_SHIFT); | ||
| 73 | } | ||
| 74 | |||
| 75 | static void dc_clk_init(struct clk *clk) | ||
| 76 | { | ||
| 77 | u32 pll, ctrl; | ||
| 78 | |||
| 79 | pll = clk_get_rate(clk->parent); | ||
| 80 | ctrl = __raw_readl(LS1X_CLK_PLL_DIV) & DIV_DC; | ||
| 81 | clk->rate = pll / (ctrl >> DIV_DC_SHIFT); | ||
| 82 | } | ||
| 83 | |||
| 84 | static struct clk_ops pll_clk_ops = { | ||
| 85 | .init = pll_clk_init, | ||
| 86 | }; | ||
| 87 | |||
| 88 | static struct clk_ops cpu_clk_ops = { | ||
| 89 | .init = cpu_clk_init, | ||
| 90 | }; | ||
| 91 | |||
| 92 | static struct clk_ops ddr_clk_ops = { | ||
| 93 | .init = ddr_clk_init, | ||
| 94 | }; | ||
| 95 | |||
| 96 | static struct clk_ops dc_clk_ops = { | ||
| 97 | .init = dc_clk_init, | ||
| 98 | }; | ||
| 99 | |||
| 100 | static struct clk pll_clk = { | ||
| 101 | .name = "pll", | ||
| 102 | .ops = &pll_clk_ops, | ||
| 103 | }; | ||
| 104 | |||
| 105 | static struct clk cpu_clk = { | ||
| 106 | .name = "cpu", | ||
| 107 | .parent = &pll_clk, | ||
| 108 | .ops = &cpu_clk_ops, | ||
| 109 | }; | ||
| 110 | |||
| 111 | static struct clk ddr_clk = { | ||
| 112 | .name = "ddr", | ||
| 113 | .parent = &pll_clk, | ||
| 114 | .ops = &ddr_clk_ops, | ||
| 115 | }; | ||
| 116 | |||
| 117 | static struct clk dc_clk = { | ||
| 118 | .name = "dc", | ||
| 119 | .parent = &pll_clk, | ||
| 120 | .ops = &dc_clk_ops, | ||
| 121 | }; | ||
| 122 | |||
| 123 | int clk_register(struct clk *clk) | ||
| 124 | { | ||
| 125 | mutex_lock(&clocks_mutex); | ||
| 126 | list_add(&clk->node, &clocks); | ||
| 127 | if (clk->ops->init) | ||
| 128 | clk->ops->init(clk); | ||
| 129 | mutex_unlock(&clocks_mutex); | ||
| 130 | |||
| 131 | return 0; | ||
| 132 | } | ||
| 133 | EXPORT_SYMBOL(clk_register); | ||
| 134 | |||
| 135 | static struct clk *ls1x_clks[] = { | ||
| 136 | &pll_clk, | ||
| 137 | &cpu_clk, | ||
| 138 | &ddr_clk, | ||
| 139 | &dc_clk, | ||
| 140 | }; | ||
| 141 | |||
| 142 | int __init ls1x_clock_init(void) | ||
| 143 | { | ||
| 144 | int i; | ||
| 145 | |||
| 146 | for (i = 0; i < ARRAY_SIZE(ls1x_clks); i++) | ||
| 147 | clk_register(ls1x_clks[i]); | ||
| 148 | |||
| 149 | return 0; | ||
| 150 | } | ||
| 151 | |||
| 152 | void __init plat_time_init(void) | ||
| 153 | { | ||
| 154 | struct clk *clk; | ||
| 155 | |||
| 156 | /* Initialize LS1X clocks */ | ||
| 157 | ls1x_clock_init(); | ||
| 158 | |||
| 159 | /* setup mips r4k timer */ | ||
| 160 | clk = clk_get(NULL, "cpu"); | ||
| 161 | if (IS_ERR(clk)) | ||
| 162 | panic("unable to get dc clock, err=%ld", PTR_ERR(clk)); | ||
| 163 | |||
| 164 | mips_hpt_frequency = clk_get_rate(clk) / 2; | ||
| 165 | } | ||
diff --git a/arch/mips/loongson1/common/irq.c b/arch/mips/loongson1/common/irq.c new file mode 100644 index 000000000000..41bc8ffe7bba --- /dev/null +++ b/arch/mips/loongson1/common/irq.c | |||
| @@ -0,0 +1,147 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com> | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License as published by the | ||
| 6 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 7 | * option) any later version. | ||
| 8 | */ | ||
| 9 | |||
| 10 | #include <linux/interrupt.h> | ||
| 11 | #include <linux/irq.h> | ||
| 12 | #include <asm/irq_cpu.h> | ||
| 13 | |||
| 14 | #include <loongson1.h> | ||
| 15 | #include <irq.h> | ||
| 16 | |||
| 17 | #define LS1X_INTC_REG(n, x) \ | ||
| 18 | ((void __iomem *)KSEG1ADDR(LS1X_INTC_BASE + (n * 0x18) + (x))) | ||
| 19 | |||
| 20 | #define LS1X_INTC_INTISR(n) LS1X_INTC_REG(n, 0x0) | ||
| 21 | #define LS1X_INTC_INTIEN(n) LS1X_INTC_REG(n, 0x4) | ||
| 22 | #define LS1X_INTC_INTSET(n) LS1X_INTC_REG(n, 0x8) | ||
| 23 | #define LS1X_INTC_INTCLR(n) LS1X_INTC_REG(n, 0xc) | ||
| 24 | #define LS1X_INTC_INTPOL(n) LS1X_INTC_REG(n, 0x10) | ||
| 25 | #define LS1X_INTC_INTEDGE(n) LS1X_INTC_REG(n, 0x14) | ||
| 26 | |||
| 27 | static void ls1x_irq_ack(struct irq_data *d) | ||
| 28 | { | ||
| 29 | unsigned int bit = (d->irq - LS1X_IRQ_BASE) & 0x1f; | ||
| 30 | unsigned int n = (d->irq - LS1X_IRQ_BASE) >> 5; | ||
| 31 | |||
| 32 | __raw_writel(__raw_readl(LS1X_INTC_INTCLR(n)) | ||
| 33 | | (1 << bit), LS1X_INTC_INTCLR(n)); | ||
| 34 | } | ||
| 35 | |||
| 36 | static void ls1x_irq_mask(struct irq_data *d) | ||
| 37 | { | ||
| 38 | unsigned int bit = (d->irq - LS1X_IRQ_BASE) & 0x1f; | ||
| 39 | unsigned int n = (d->irq - LS1X_IRQ_BASE) >> 5; | ||
| 40 | |||
| 41 | __raw_writel(__raw_readl(LS1X_INTC_INTIEN(n)) | ||
| 42 | & ~(1 << bit), LS1X_INTC_INTIEN(n)); | ||
| 43 | } | ||
| 44 | |||
| 45 | static void ls1x_irq_mask_ack(struct irq_data *d) | ||
| 46 | { | ||
| 47 | unsigned int bit = (d->irq - LS1X_IRQ_BASE) & 0x1f; | ||
| 48 | unsigned int n = (d->irq - LS1X_IRQ_BASE) >> 5; | ||
| 49 | |||
| 50 | __raw_writel(__raw_readl(LS1X_INTC_INTIEN(n)) | ||
| 51 | & ~(1 << bit), LS1X_INTC_INTIEN(n)); | ||
| 52 | __raw_writel(__raw_readl(LS1X_INTC_INTCLR(n)) | ||
| 53 | | (1 << bit), LS1X_INTC_INTCLR(n)); | ||
| 54 | } | ||
| 55 | |||
| 56 | static void ls1x_irq_unmask(struct irq_data *d) | ||
| 57 | { | ||
| 58 | unsigned int bit = (d->irq - LS1X_IRQ_BASE) & 0x1f; | ||
| 59 | unsigned int n = (d->irq - LS1X_IRQ_BASE) >> 5; | ||
| 60 | |||
| 61 | __raw_writel(__raw_readl(LS1X_INTC_INTIEN(n)) | ||
| 62 | | (1 << bit), LS1X_INTC_INTIEN(n)); | ||
| 63 | } | ||
| 64 | |||
| 65 | static struct irq_chip ls1x_irq_chip = { | ||
| 66 | .name = "LS1X-INTC", | ||
| 67 | .irq_ack = ls1x_irq_ack, | ||
| 68 | .irq_mask = ls1x_irq_mask, | ||
| 69 | .irq_mask_ack = ls1x_irq_mask_ack, | ||
| 70 | .irq_unmask = ls1x_irq_unmask, | ||
| 71 | }; | ||
| 72 | |||
| 73 | static void ls1x_irq_dispatch(int n) | ||
| 74 | { | ||
| 75 | u32 int_status, irq; | ||
| 76 | |||
| 77 | /* Get pending sources, masked by current enables */ | ||
| 78 | int_status = __raw_readl(LS1X_INTC_INTISR(n)) & | ||
| 79 | __raw_readl(LS1X_INTC_INTIEN(n)); | ||
| 80 | |||
| 81 | if (int_status) { | ||
| 82 | irq = LS1X_IRQ(n, __ffs(int_status)); | ||
| 83 | do_IRQ(irq); | ||
| 84 | } | ||
| 85 | } | ||
| 86 | |||
| 87 | asmlinkage void plat_irq_dispatch(void) | ||
| 88 | { | ||
| 89 | unsigned int pending; | ||
| 90 | |||
| 91 | pending = read_c0_cause() & read_c0_status() & ST0_IM; | ||
| 92 | |||
| 93 | if (pending & CAUSEF_IP7) | ||
| 94 | do_IRQ(TIMER_IRQ); | ||
| 95 | else if (pending & CAUSEF_IP2) | ||
| 96 | ls1x_irq_dispatch(0); /* INT0 */ | ||
| 97 | else if (pending & CAUSEF_IP3) | ||
| 98 | ls1x_irq_dispatch(1); /* INT1 */ | ||
| 99 | else if (pending & CAUSEF_IP4) | ||
| 100 | ls1x_irq_dispatch(2); /* INT2 */ | ||
| 101 | else if (pending & CAUSEF_IP5) | ||
| 102 | ls1x_irq_dispatch(3); /* INT3 */ | ||
| 103 | else if (pending & CAUSEF_IP6) | ||
| 104 | ls1x_irq_dispatch(4); /* INT4 */ | ||
| 105 | else | ||
| 106 | spurious_interrupt(); | ||
| 107 | |||
| 108 | } | ||
| 109 | |||
| 110 | struct irqaction cascade_irqaction = { | ||
| 111 | .handler = no_action, | ||
| 112 | .name = "cascade", | ||
| 113 | .flags = IRQF_NO_THREAD, | ||
| 114 | }; | ||
| 115 | |||
| 116 | static void __init ls1x_irq_init(int base) | ||
| 117 | { | ||
| 118 | int n; | ||
| 119 | |||
| 120 | /* Disable interrupts and clear pending, | ||
| 121 | * setup all IRQs as high level triggered | ||
| 122 | */ | ||
| 123 | for (n = 0; n < 4; n++) { | ||
| 124 | __raw_writel(0x0, LS1X_INTC_INTIEN(n)); | ||
| 125 | __raw_writel(0xffffffff, LS1X_INTC_INTCLR(n)); | ||
| 126 | __raw_writel(0xffffffff, LS1X_INTC_INTPOL(n)); | ||
| 127 | /* set DMA0, DMA1 and DMA2 to edge trigger */ | ||
| 128 | __raw_writel(n ? 0x0 : 0xe000, LS1X_INTC_INTEDGE(n)); | ||
| 129 | } | ||
| 130 | |||
| 131 | |||
| 132 | for (n = base; n < LS1X_IRQS; n++) { | ||
| 133 | irq_set_chip_and_handler(n, &ls1x_irq_chip, | ||
| 134 | handle_level_irq); | ||
| 135 | } | ||
| 136 | |||
| 137 | setup_irq(INT0_IRQ, &cascade_irqaction); | ||
| 138 | setup_irq(INT1_IRQ, &cascade_irqaction); | ||
| 139 | setup_irq(INT2_IRQ, &cascade_irqaction); | ||
| 140 | setup_irq(INT3_IRQ, &cascade_irqaction); | ||
| 141 | } | ||
| 142 | |||
| 143 | void __init arch_init_irq(void) | ||
| 144 | { | ||
| 145 | mips_cpu_irq_init(); | ||
| 146 | ls1x_irq_init(LS1X_IRQ_BASE); | ||
| 147 | } | ||
diff --git a/arch/mips/loongson1/common/platform.c b/arch/mips/loongson1/common/platform.c new file mode 100644 index 000000000000..e92d59c4bd78 --- /dev/null +++ b/arch/mips/loongson1/common/platform.c | |||
| @@ -0,0 +1,124 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com> | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License as published by the | ||
| 6 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 7 | * option) any later version. | ||
| 8 | */ | ||
| 9 | |||
| 10 | #include <linux/clk.h> | ||
| 11 | #include <linux/dma-mapping.h> | ||
| 12 | #include <linux/err.h> | ||
| 13 | #include <linux/phy.h> | ||
| 14 | #include <linux/serial_8250.h> | ||
| 15 | #include <linux/stmmac.h> | ||
| 16 | #include <asm-generic/sizes.h> | ||
| 17 | |||
| 18 | #include <loongson1.h> | ||
| 19 | |||
| 20 | #define LS1X_UART(_id) \ | ||
| 21 | { \ | ||
| 22 | .mapbase = LS1X_UART ## _id ## _BASE, \ | ||
| 23 | .irq = LS1X_UART ## _id ## _IRQ, \ | ||
| 24 | .iotype = UPIO_MEM, \ | ||
| 25 | .flags = UPF_IOREMAP | UPF_FIXED_TYPE, \ | ||
| 26 | .type = PORT_16550A, \ | ||
| 27 | } | ||
| 28 | |||
| 29 | static struct plat_serial8250_port ls1x_serial8250_port[] = { | ||
| 30 | LS1X_UART(0), | ||
| 31 | LS1X_UART(1), | ||
| 32 | LS1X_UART(2), | ||
| 33 | LS1X_UART(3), | ||
| 34 | {}, | ||
| 35 | }; | ||
| 36 | |||
| 37 | struct platform_device ls1x_uart_device = { | ||
| 38 | .name = "serial8250", | ||
| 39 | .id = PLAT8250_DEV_PLATFORM, | ||
| 40 | .dev = { | ||
| 41 | .platform_data = ls1x_serial8250_port, | ||
| 42 | }, | ||
| 43 | }; | ||
| 44 | |||
| 45 | void __init ls1x_serial_setup(void) | ||
| 46 | { | ||
| 47 | struct clk *clk; | ||
| 48 | struct plat_serial8250_port *p; | ||
| 49 | |||
| 50 | clk = clk_get(NULL, "dc"); | ||
| 51 | if (IS_ERR(clk)) | ||
| 52 | panic("unable to get dc clock, err=%ld", PTR_ERR(clk)); | ||
| 53 | |||
| 54 | for (p = ls1x_serial8250_port; p->flags != 0; ++p) | ||
| 55 | p->uartclk = clk_get_rate(clk); | ||
| 56 | } | ||
| 57 | |||
| 58 | /* Synopsys Ethernet GMAC */ | ||
| 59 | static struct resource ls1x_eth0_resources[] = { | ||
| 60 | [0] = { | ||
| 61 | .start = LS1X_GMAC0_BASE, | ||
| 62 | .end = LS1X_GMAC0_BASE + SZ_64K - 1, | ||
| 63 | .flags = IORESOURCE_MEM, | ||
| 64 | }, | ||
| 65 | [1] = { | ||
| 66 | .name = "macirq", | ||
| 67 | .start = LS1X_GMAC0_IRQ, | ||
| 68 | .flags = IORESOURCE_IRQ, | ||
| 69 | }, | ||
| 70 | }; | ||
| 71 | |||
| 72 | static struct stmmac_mdio_bus_data ls1x_mdio_bus_data = { | ||
| 73 | .bus_id = 0, | ||
| 74 | .phy_mask = 0, | ||
| 75 | }; | ||
| 76 | |||
| 77 | static struct plat_stmmacenet_data ls1x_eth_data = { | ||
| 78 | .bus_id = 0, | ||
| 79 | .phy_addr = -1, | ||
| 80 | .mdio_bus_data = &ls1x_mdio_bus_data, | ||
| 81 | .has_gmac = 1, | ||
| 82 | .tx_coe = 1, | ||
| 83 | }; | ||
| 84 | |||
| 85 | struct platform_device ls1x_eth0_device = { | ||
| 86 | .name = "stmmaceth", | ||
| 87 | .id = 0, | ||
| 88 | .num_resources = ARRAY_SIZE(ls1x_eth0_resources), | ||
| 89 | .resource = ls1x_eth0_resources, | ||
| 90 | .dev = { | ||
| 91 | .platform_data = &ls1x_eth_data, | ||
| 92 | }, | ||
| 93 | }; | ||
| 94 | |||
| 95 | /* USB EHCI */ | ||
| 96 | static u64 ls1x_ehci_dmamask = DMA_BIT_MASK(32); | ||
| 97 | |||
| 98 | static struct resource ls1x_ehci_resources[] = { | ||
| 99 | [0] = { | ||
| 100 | .start = LS1X_EHCI_BASE, | ||
| 101 | .end = LS1X_EHCI_BASE + SZ_32K - 1, | ||
| 102 | .flags = IORESOURCE_MEM, | ||
| 103 | }, | ||
| 104 | [1] = { | ||
| 105 | .start = LS1X_EHCI_IRQ, | ||
| 106 | .flags = IORESOURCE_IRQ, | ||
| 107 | }, | ||
| 108 | }; | ||
| 109 | |||
| 110 | struct platform_device ls1x_ehci_device = { | ||
| 111 | .name = "ls1x-ehci", | ||
| 112 | .id = -1, | ||
| 113 | .num_resources = ARRAY_SIZE(ls1x_ehci_resources), | ||
| 114 | .resource = ls1x_ehci_resources, | ||
| 115 | .dev = { | ||
| 116 | .dma_mask = &ls1x_ehci_dmamask, | ||
| 117 | }, | ||
| 118 | }; | ||
| 119 | |||
| 120 | /* Real Time Clock */ | ||
| 121 | struct platform_device ls1x_rtc_device = { | ||
| 122 | .name = "ls1x-rtc", | ||
| 123 | .id = -1, | ||
| 124 | }; | ||
diff --git a/arch/mips/loongson1/common/prom.c b/arch/mips/loongson1/common/prom.c new file mode 100644 index 000000000000..1f8e49f9886d --- /dev/null +++ b/arch/mips/loongson1/common/prom.c | |||
| @@ -0,0 +1,87 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com> | ||
| 3 | * | ||
| 4 | * Modified from arch/mips/pnx833x/common/prom.c. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify it | ||
| 7 | * under the terms of the GNU General Public License as published by the | ||
| 8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 9 | * option) any later version. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/serial_reg.h> | ||
| 13 | #include <asm/bootinfo.h> | ||
| 14 | |||
| 15 | #include <loongson1.h> | ||
| 16 | #include <prom.h> | ||
| 17 | |||
| 18 | int prom_argc; | ||
| 19 | char **prom_argv, **prom_envp; | ||
| 20 | unsigned long memsize, highmemsize; | ||
| 21 | |||
| 22 | char *prom_getenv(char *envname) | ||
| 23 | { | ||
| 24 | char **env = prom_envp; | ||
| 25 | int i; | ||
| 26 | |||
| 27 | i = strlen(envname); | ||
| 28 | |||
| 29 | while (*env) { | ||
| 30 | if (strncmp(envname, *env, i) == 0 && *(*env+i) == '=') | ||
| 31 | return *env + i + 1; | ||
| 32 | env++; | ||
| 33 | } | ||
| 34 | |||
| 35 | return 0; | ||
| 36 | } | ||
| 37 | |||
| 38 | static inline unsigned long env_or_default(char *env, unsigned long dfl) | ||
| 39 | { | ||
| 40 | char *str = prom_getenv(env); | ||
| 41 | return str ? simple_strtol(str, 0, 0) : dfl; | ||
| 42 | } | ||
| 43 | |||
| 44 | void __init prom_init_cmdline(void) | ||
| 45 | { | ||
| 46 | char *c = &(arcs_cmdline[0]); | ||
| 47 | int i; | ||
| 48 | |||
| 49 | for (i = 1; i < prom_argc; i++) { | ||
| 50 | strcpy(c, prom_argv[i]); | ||
| 51 | c += strlen(prom_argv[i]); | ||
| 52 | if (i < prom_argc-1) | ||
| 53 | *c++ = ' '; | ||
| 54 | } | ||
| 55 | *c = 0; | ||
| 56 | } | ||
| 57 | |||
| 58 | void __init prom_init(void) | ||
| 59 | { | ||
| 60 | prom_argc = fw_arg0; | ||
| 61 | prom_argv = (char **)fw_arg1; | ||
| 62 | prom_envp = (char **)fw_arg2; | ||
| 63 | |||
| 64 | prom_init_cmdline(); | ||
| 65 | |||
| 66 | memsize = env_or_default("memsize", DEFAULT_MEMSIZE); | ||
| 67 | highmemsize = env_or_default("highmemsize", 0x0); | ||
| 68 | } | ||
| 69 | |||
| 70 | void __init prom_free_prom_memory(void) | ||
| 71 | { | ||
| 72 | } | ||
| 73 | |||
| 74 | #define PORT(offset) (u8 *)(KSEG1ADDR(LS1X_UART0_BASE + offset)) | ||
| 75 | |||
| 76 | void __init prom_putchar(char c) | ||
| 77 | { | ||
| 78 | int timeout; | ||
| 79 | |||
| 80 | timeout = 1024; | ||
| 81 | |||
| 82 | while (((readb(PORT(UART_LSR)) & UART_LSR_THRE) == 0) | ||
| 83 | && (timeout-- > 0)) | ||
| 84 | ; | ||
| 85 | |||
| 86 | writeb(c, PORT(UART_TX)); | ||
| 87 | } | ||
diff --git a/arch/mips/loongson1/common/reset.c b/arch/mips/loongson1/common/reset.c new file mode 100644 index 000000000000..fb979a784eca --- /dev/null +++ b/arch/mips/loongson1/common/reset.c | |||
| @@ -0,0 +1,45 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com> | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License as published by the | ||
| 6 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 7 | * option) any later version. | ||
| 8 | */ | ||
| 9 | |||
| 10 | #include <linux/io.h> | ||
| 11 | #include <linux/pm.h> | ||
| 12 | #include <asm/reboot.h> | ||
| 13 | |||
| 14 | #include <loongson1.h> | ||
| 15 | |||
| 16 | static void ls1x_restart(char *command) | ||
| 17 | { | ||
| 18 | __raw_writel(0x1, LS1X_WDT_EN); | ||
| 19 | __raw_writel(0x5000000, LS1X_WDT_TIMER); | ||
| 20 | __raw_writel(0x1, LS1X_WDT_SET); | ||
| 21 | } | ||
| 22 | |||
| 23 | static void ls1x_halt(void) | ||
| 24 | { | ||
| 25 | while (1) { | ||
| 26 | if (cpu_wait) | ||
| 27 | cpu_wait(); | ||
| 28 | } | ||
| 29 | } | ||
| 30 | |||
| 31 | static void ls1x_power_off(void) | ||
| 32 | { | ||
| 33 | ls1x_halt(); | ||
| 34 | } | ||
| 35 | |||
| 36 | static int __init ls1x_reboot_setup(void) | ||
| 37 | { | ||
| 38 | _machine_restart = ls1x_restart; | ||
| 39 | _machine_halt = ls1x_halt; | ||
| 40 | pm_power_off = ls1x_power_off; | ||
| 41 | |||
| 42 | return 0; | ||
| 43 | } | ||
| 44 | |||
| 45 | arch_initcall(ls1x_reboot_setup); | ||
diff --git a/arch/mips/loongson1/common/setup.c b/arch/mips/loongson1/common/setup.c new file mode 100644 index 000000000000..62128cc27e68 --- /dev/null +++ b/arch/mips/loongson1/common/setup.c | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com> | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License as published by the | ||
| 6 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 7 | * option) any later version. | ||
| 8 | */ | ||
| 9 | |||
| 10 | #include <asm/bootinfo.h> | ||
| 11 | |||
| 12 | #include <prom.h> | ||
| 13 | |||
| 14 | void __init plat_mem_setup(void) | ||
| 15 | { | ||
| 16 | add_memory_region(0x0, (memsize << 20), BOOT_MEM_RAM); | ||
| 17 | } | ||
| 18 | |||
| 19 | const char *get_system_type(void) | ||
| 20 | { | ||
| 21 | unsigned int processor_id = (¤t_cpu_data)->processor_id; | ||
| 22 | |||
| 23 | switch (processor_id & PRID_REV_MASK) { | ||
| 24 | case PRID_REV_LOONGSON1B: | ||
| 25 | return "LOONGSON LS1B"; | ||
| 26 | default: | ||
| 27 | return "LOONGSON (unknown)"; | ||
| 28 | } | ||
| 29 | } | ||
diff --git a/arch/mips/loongson1/ls1b/Makefile b/arch/mips/loongson1/ls1b/Makefile new file mode 100644 index 000000000000..891eac482b82 --- /dev/null +++ b/arch/mips/loongson1/ls1b/Makefile | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | # | ||
| 2 | # Makefile for loongson1B based machines. | ||
| 3 | # | ||
| 4 | |||
| 5 | obj-y += board.o | ||
diff --git a/arch/mips/loongson1/ls1b/board.c b/arch/mips/loongson1/ls1b/board.c new file mode 100644 index 000000000000..295b1be893e3 --- /dev/null +++ b/arch/mips/loongson1/ls1b/board.c | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com> | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License as published by the | ||
| 6 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 7 | * option) any later version. | ||
| 8 | */ | ||
| 9 | |||
| 10 | #include <platform.h> | ||
| 11 | |||
| 12 | #include <linux/serial_8250.h> | ||
| 13 | #include <loongson1.h> | ||
| 14 | |||
| 15 | static struct platform_device *ls1b_platform_devices[] __initdata = { | ||
| 16 | &ls1x_uart_device, | ||
| 17 | &ls1x_eth0_device, | ||
| 18 | &ls1x_ehci_device, | ||
| 19 | &ls1x_rtc_device, | ||
| 20 | }; | ||
| 21 | |||
| 22 | static int __init ls1b_platform_init(void) | ||
| 23 | { | ||
| 24 | int err; | ||
| 25 | |||
| 26 | ls1x_serial_setup(); | ||
| 27 | |||
| 28 | err = platform_add_devices(ls1b_platform_devices, | ||
| 29 | ARRAY_SIZE(ls1b_platform_devices)); | ||
| 30 | return err; | ||
| 31 | } | ||
| 32 | |||
| 33 | arch_initcall(ls1b_platform_init); | ||
diff --git a/arch/mips/mm/uasm.c b/arch/mips/mm/uasm.c index 5fa185151fc8..64a28e819064 100644 --- a/arch/mips/mm/uasm.c +++ b/arch/mips/mm/uasm.c | |||
| @@ -58,18 +58,16 @@ enum fields { | |||
| 58 | 58 | ||
| 59 | enum opcode { | 59 | enum opcode { |
| 60 | insn_invalid, | 60 | insn_invalid, |
| 61 | insn_addu, insn_addiu, insn_and, insn_andi, insn_beq, | 61 | insn_addiu, insn_addu, insn_and, insn_andi, insn_bbit0, insn_bbit1, |
| 62 | insn_beql, insn_bgez, insn_bgezl, insn_bltz, insn_bltzl, | 62 | insn_beq, insn_beql, insn_bgez, insn_bgezl, insn_bltz, insn_bltzl, |
| 63 | insn_bne, insn_cache, insn_daddu, insn_daddiu, insn_dmfc0, | 63 | insn_bne, insn_cache, insn_daddiu, insn_daddu, insn_dins, insn_dinsm, |
| 64 | insn_dmtc0, insn_dsll, insn_dsll32, insn_dsra, insn_dsrl, | 64 | insn_dmfc0, insn_dmtc0, insn_drotr, insn_drotr32, insn_dsll, |
| 65 | insn_dsrl32, insn_drotr, insn_drotr32, insn_dsubu, insn_eret, | 65 | insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32, insn_dsubu, insn_eret, |
| 66 | insn_j, insn_jal, insn_jr, insn_ld, insn_ll, insn_lld, | 66 | insn_j, insn_jal, insn_jr, insn_ld, insn_ldx, insn_ll, insn_lld, |
| 67 | insn_lui, insn_lw, insn_mfc0, insn_mtc0, insn_or, insn_ori, | 67 | insn_lui, insn_lw, insn_lwx, insn_mfc0, insn_mtc0, insn_or, insn_ori, |
| 68 | insn_pref, insn_rfe, insn_sc, insn_scd, insn_sd, insn_sll, | 68 | insn_pref, insn_rfe, insn_rotr, insn_sc, insn_scd, insn_sd, insn_sll, |
| 69 | insn_sra, insn_srl, insn_rotr, insn_subu, insn_sw, insn_tlbp, | 69 | insn_sra, insn_srl, insn_subu, insn_sw, insn_syscall, insn_tlbp, |
| 70 | insn_tlbr, insn_tlbwi, insn_tlbwr, insn_xor, insn_xori, | 70 | insn_tlbr, insn_tlbwi, insn_tlbwr, insn_xor, insn_xori, |
| 71 | insn_dins, insn_dinsm, insn_syscall, insn_bbit0, insn_bbit1, | ||
| 72 | insn_lwx, insn_ldx | ||
| 73 | }; | 71 | }; |
| 74 | 72 | ||
| 75 | struct insn { | 73 | struct insn { |
| @@ -90,65 +88,65 @@ struct insn { | |||
| 90 | static struct insn insn_table[] __uasminitdata = { | 88 | static struct insn insn_table[] __uasminitdata = { |
| 91 | { insn_addiu, M(addiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | 89 | { insn_addiu, M(addiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, |
| 92 | { insn_addu, M(spec_op, 0, 0, 0, 0, addu_op), RS | RT | RD }, | 90 | { insn_addu, M(spec_op, 0, 0, 0, 0, addu_op), RS | RT | RD }, |
| 93 | { insn_and, M(spec_op, 0, 0, 0, 0, and_op), RS | RT | RD }, | ||
| 94 | { insn_andi, M(andi_op, 0, 0, 0, 0, 0), RS | RT | UIMM }, | 91 | { insn_andi, M(andi_op, 0, 0, 0, 0, 0), RS | RT | UIMM }, |
| 95 | { insn_beq, M(beq_op, 0, 0, 0, 0, 0), RS | RT | BIMM }, | 92 | { insn_and, M(spec_op, 0, 0, 0, 0, and_op), RS | RT | RD }, |
| 93 | { insn_bbit0, M(lwc2_op, 0, 0, 0, 0, 0), RS | RT | BIMM }, | ||
| 94 | { insn_bbit1, M(swc2_op, 0, 0, 0, 0, 0), RS | RT | BIMM }, | ||
| 96 | { insn_beql, M(beql_op, 0, 0, 0, 0, 0), RS | RT | BIMM }, | 95 | { insn_beql, M(beql_op, 0, 0, 0, 0, 0), RS | RT | BIMM }, |
| 97 | { insn_bgez, M(bcond_op, 0, bgez_op, 0, 0, 0), RS | BIMM }, | 96 | { insn_beq, M(beq_op, 0, 0, 0, 0, 0), RS | RT | BIMM }, |
| 98 | { insn_bgezl, M(bcond_op, 0, bgezl_op, 0, 0, 0), RS | BIMM }, | 97 | { insn_bgezl, M(bcond_op, 0, bgezl_op, 0, 0, 0), RS | BIMM }, |
| 99 | { insn_bltz, M(bcond_op, 0, bltz_op, 0, 0, 0), RS | BIMM }, | 98 | { insn_bgez, M(bcond_op, 0, bgez_op, 0, 0, 0), RS | BIMM }, |
| 100 | { insn_bltzl, M(bcond_op, 0, bltzl_op, 0, 0, 0), RS | BIMM }, | 99 | { insn_bltzl, M(bcond_op, 0, bltzl_op, 0, 0, 0), RS | BIMM }, |
| 100 | { insn_bltz, M(bcond_op, 0, bltz_op, 0, 0, 0), RS | BIMM }, | ||
| 101 | { insn_bne, M(bne_op, 0, 0, 0, 0, 0), RS | RT | BIMM }, | 101 | { insn_bne, M(bne_op, 0, 0, 0, 0, 0), RS | RT | BIMM }, |
| 102 | { insn_cache, M(cache_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | 102 | { insn_cache, M(cache_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, |
| 103 | { insn_daddiu, M(daddiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | 103 | { insn_daddiu, M(daddiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, |
| 104 | { insn_daddu, M(spec_op, 0, 0, 0, 0, daddu_op), RS | RT | RD }, | 104 | { insn_daddu, M(spec_op, 0, 0, 0, 0, daddu_op), RS | RT | RD }, |
| 105 | { insn_dinsm, M(spec3_op, 0, 0, 0, 0, dinsm_op), RS | RT | RD | RE }, | ||
| 106 | { insn_dins, M(spec3_op, 0, 0, 0, 0, dins_op), RS | RT | RD | RE }, | ||
| 105 | { insn_dmfc0, M(cop0_op, dmfc_op, 0, 0, 0, 0), RT | RD | SET}, | 107 | { insn_dmfc0, M(cop0_op, dmfc_op, 0, 0, 0, 0), RT | RD | SET}, |
| 106 | { insn_dmtc0, M(cop0_op, dmtc_op, 0, 0, 0, 0), RT | RD | SET}, | 108 | { insn_dmtc0, M(cop0_op, dmtc_op, 0, 0, 0, 0), RT | RD | SET}, |
| 107 | { insn_dsll, M(spec_op, 0, 0, 0, 0, dsll_op), RT | RD | RE }, | 109 | { insn_drotr32, M(spec_op, 1, 0, 0, 0, dsrl32_op), RT | RD | RE }, |
| 110 | { insn_drotr, M(spec_op, 1, 0, 0, 0, dsrl_op), RT | RD | RE }, | ||
| 108 | { insn_dsll32, M(spec_op, 0, 0, 0, 0, dsll32_op), RT | RD | RE }, | 111 | { insn_dsll32, M(spec_op, 0, 0, 0, 0, dsll32_op), RT | RD | RE }, |
| 112 | { insn_dsll, M(spec_op, 0, 0, 0, 0, dsll_op), RT | RD | RE }, | ||
| 109 | { insn_dsra, M(spec_op, 0, 0, 0, 0, dsra_op), RT | RD | RE }, | 113 | { insn_dsra, M(spec_op, 0, 0, 0, 0, dsra_op), RT | RD | RE }, |
| 110 | { insn_dsrl, M(spec_op, 0, 0, 0, 0, dsrl_op), RT | RD | RE }, | ||
| 111 | { insn_dsrl32, M(spec_op, 0, 0, 0, 0, dsrl32_op), RT | RD | RE }, | 114 | { insn_dsrl32, M(spec_op, 0, 0, 0, 0, dsrl32_op), RT | RD | RE }, |
| 112 | { insn_drotr, M(spec_op, 1, 0, 0, 0, dsrl_op), RT | RD | RE }, | 115 | { insn_dsrl, M(spec_op, 0, 0, 0, 0, dsrl_op), RT | RD | RE }, |
| 113 | { insn_drotr32, M(spec_op, 1, 0, 0, 0, dsrl32_op), RT | RD | RE }, | ||
| 114 | { insn_dsubu, M(spec_op, 0, 0, 0, 0, dsubu_op), RS | RT | RD }, | 116 | { insn_dsubu, M(spec_op, 0, 0, 0, 0, dsubu_op), RS | RT | RD }, |
| 115 | { insn_eret, M(cop0_op, cop_op, 0, 0, 0, eret_op), 0 }, | 117 | { insn_eret, M(cop0_op, cop_op, 0, 0, 0, eret_op), 0 }, |
| 116 | { insn_j, M(j_op, 0, 0, 0, 0, 0), JIMM }, | ||
| 117 | { insn_jal, M(jal_op, 0, 0, 0, 0, 0), JIMM }, | 118 | { insn_jal, M(jal_op, 0, 0, 0, 0, 0), JIMM }, |
| 119 | { insn_j, M(j_op, 0, 0, 0, 0, 0), JIMM }, | ||
| 118 | { insn_jr, M(spec_op, 0, 0, 0, 0, jr_op), RS }, | 120 | { insn_jr, M(spec_op, 0, 0, 0, 0, jr_op), RS }, |
| 119 | { insn_ld, M(ld_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | 121 | { insn_ld, M(ld_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, |
| 120 | { insn_ll, M(ll_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | 122 | { insn_ldx, M(spec3_op, 0, 0, 0, ldx_op, lx_op), RS | RT | RD }, |
| 121 | { insn_lld, M(lld_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | 123 | { insn_lld, M(lld_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, |
| 124 | { insn_ll, M(ll_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | ||
| 122 | { insn_lui, M(lui_op, 0, 0, 0, 0, 0), RT | SIMM }, | 125 | { insn_lui, M(lui_op, 0, 0, 0, 0, 0), RT | SIMM }, |
| 123 | { insn_lw, M(lw_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | 126 | { insn_lw, M(lw_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, |
| 127 | { insn_lwx, M(spec3_op, 0, 0, 0, lwx_op, lx_op), RS | RT | RD }, | ||
| 124 | { insn_mfc0, M(cop0_op, mfc_op, 0, 0, 0, 0), RT | RD | SET}, | 128 | { insn_mfc0, M(cop0_op, mfc_op, 0, 0, 0, 0), RT | RD | SET}, |
| 125 | { insn_mtc0, M(cop0_op, mtc_op, 0, 0, 0, 0), RT | RD | SET}, | 129 | { insn_mtc0, M(cop0_op, mtc_op, 0, 0, 0, 0), RT | RD | SET}, |
| 126 | { insn_or, M(spec_op, 0, 0, 0, 0, or_op), RS | RT | RD }, | ||
| 127 | { insn_ori, M(ori_op, 0, 0, 0, 0, 0), RS | RT | UIMM }, | 130 | { insn_ori, M(ori_op, 0, 0, 0, 0, 0), RS | RT | UIMM }, |
| 131 | { insn_or, M(spec_op, 0, 0, 0, 0, or_op), RS | RT | RD }, | ||
| 128 | { insn_pref, M(pref_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | 132 | { insn_pref, M(pref_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, |
| 129 | { insn_rfe, M(cop0_op, cop_op, 0, 0, 0, rfe_op), 0 }, | 133 | { insn_rfe, M(cop0_op, cop_op, 0, 0, 0, rfe_op), 0 }, |
| 130 | { insn_sc, M(sc_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | 134 | { insn_rotr, M(spec_op, 1, 0, 0, 0, srl_op), RT | RD | RE }, |
| 131 | { insn_scd, M(scd_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | 135 | { insn_scd, M(scd_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, |
| 136 | { insn_sc, M(sc_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | ||
| 132 | { insn_sd, M(sd_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | 137 | { insn_sd, M(sd_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, |
| 133 | { insn_sll, M(spec_op, 0, 0, 0, 0, sll_op), RT | RD | RE }, | 138 | { insn_sll, M(spec_op, 0, 0, 0, 0, sll_op), RT | RD | RE }, |
| 134 | { insn_sra, M(spec_op, 0, 0, 0, 0, sra_op), RT | RD | RE }, | 139 | { insn_sra, M(spec_op, 0, 0, 0, 0, sra_op), RT | RD | RE }, |
| 135 | { insn_srl, M(spec_op, 0, 0, 0, 0, srl_op), RT | RD | RE }, | 140 | { insn_srl, M(spec_op, 0, 0, 0, 0, srl_op), RT | RD | RE }, |
| 136 | { insn_rotr, M(spec_op, 1, 0, 0, 0, srl_op), RT | RD | RE }, | ||
| 137 | { insn_subu, M(spec_op, 0, 0, 0, 0, subu_op), RS | RT | RD }, | 141 | { insn_subu, M(spec_op, 0, 0, 0, 0, subu_op), RS | RT | RD }, |
| 138 | { insn_sw, M(sw_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | 142 | { insn_sw, M(sw_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, |
| 143 | { insn_syscall, M(spec_op, 0, 0, 0, 0, syscall_op), SCIMM}, | ||
| 139 | { insn_tlbp, M(cop0_op, cop_op, 0, 0, 0, tlbp_op), 0 }, | 144 | { insn_tlbp, M(cop0_op, cop_op, 0, 0, 0, tlbp_op), 0 }, |
| 140 | { insn_tlbr, M(cop0_op, cop_op, 0, 0, 0, tlbr_op), 0 }, | 145 | { insn_tlbr, M(cop0_op, cop_op, 0, 0, 0, tlbr_op), 0 }, |
| 141 | { insn_tlbwi, M(cop0_op, cop_op, 0, 0, 0, tlbwi_op), 0 }, | 146 | { insn_tlbwi, M(cop0_op, cop_op, 0, 0, 0, tlbwi_op), 0 }, |
| 142 | { insn_tlbwr, M(cop0_op, cop_op, 0, 0, 0, tlbwr_op), 0 }, | 147 | { insn_tlbwr, M(cop0_op, cop_op, 0, 0, 0, tlbwr_op), 0 }, |
| 143 | { insn_xor, M(spec_op, 0, 0, 0, 0, xor_op), RS | RT | RD }, | ||
| 144 | { insn_xori, M(xori_op, 0, 0, 0, 0, 0), RS | RT | UIMM }, | 148 | { insn_xori, M(xori_op, 0, 0, 0, 0, 0), RS | RT | UIMM }, |
| 145 | { insn_dins, M(spec3_op, 0, 0, 0, 0, dins_op), RS | RT | RD | RE }, | 149 | { insn_xor, M(spec_op, 0, 0, 0, 0, xor_op), RS | RT | RD }, |
| 146 | { insn_dinsm, M(spec3_op, 0, 0, 0, 0, dinsm_op), RS | RT | RD | RE }, | ||
| 147 | { insn_syscall, M(spec_op, 0, 0, 0, 0, syscall_op), SCIMM}, | ||
| 148 | { insn_bbit0, M(lwc2_op, 0, 0, 0, 0, 0), RS | RT | BIMM }, | ||
| 149 | { insn_bbit1, M(swc2_op, 0, 0, 0, 0, 0), RS | RT | BIMM }, | ||
| 150 | { insn_lwx, M(spec3_op, 0, 0, 0, lwx_op, lx_op), RS | RT | RD }, | ||
| 151 | { insn_ldx, M(spec3_op, 0, 0, 0, ldx_op, lx_op), RS | RT | RD }, | ||
| 152 | { insn_invalid, 0, 0 } | 150 | { insn_invalid, 0, 0 } |
| 153 | }; | 151 | }; |
| 154 | 152 | ||
diff --git a/arch/mips/netlogic/common/earlycons.c b/arch/mips/netlogic/common/earlycons.c index f193f7b3bd81..1902fa22d277 100644 --- a/arch/mips/netlogic/common/earlycons.c +++ b/arch/mips/netlogic/common/earlycons.c | |||
| @@ -54,7 +54,7 @@ void prom_putchar(char c) | |||
| 54 | #elif defined(CONFIG_CPU_XLR) | 54 | #elif defined(CONFIG_CPU_XLR) |
| 55 | uartbase = nlm_mmio_base(NETLOGIC_IO_UART_0_OFFSET); | 55 | uartbase = nlm_mmio_base(NETLOGIC_IO_UART_0_OFFSET); |
| 56 | #endif | 56 | #endif |
| 57 | while (nlm_read_reg(uartbase, UART_LSR) == 0) | 57 | while ((nlm_read_reg(uartbase, UART_LSR) & UART_LSR_THRE) == 0) |
| 58 | ; | 58 | ; |
| 59 | nlm_write_reg(uartbase, UART_TX, c); | 59 | nlm_write_reg(uartbase, UART_TX, c); |
| 60 | } | 60 | } |
diff --git a/arch/mips/netlogic/common/smpboot.S b/arch/mips/netlogic/common/smpboot.S index c138b1a6dec3..a13355cc97eb 100644 --- a/arch/mips/netlogic/common/smpboot.S +++ b/arch/mips/netlogic/common/smpboot.S | |||
| @@ -54,28 +54,68 @@ | |||
| 54 | XLP_IO_SYS_OFFSET(node) + XLP_IO_PCI_HDRSZ + \ | 54 | XLP_IO_SYS_OFFSET(node) + XLP_IO_PCI_HDRSZ + \ |
| 55 | SYS_CPU_NONCOHERENT_MODE * 4 | 55 | SYS_CPU_NONCOHERENT_MODE * 4 |
| 56 | 56 | ||
| 57 | .macro __config_lsu | 57 | #define XLP_AX_WORKAROUND /* enable Ax silicon workarounds */ |
| 58 | li t0, LSU_DEFEATURE | ||
| 59 | mfcr t1, t0 | ||
| 60 | 58 | ||
| 61 | lui t2, 0x4080 /* Enable Unaligned Access, L2HPE */ | 59 | /* Enable XLP features and workarounds in the LSU */ |
| 62 | or t1, t1, t2 | 60 | .macro xlp_config_lsu |
| 63 | li t2, ~0xe /* S1RCM */ | 61 | li t0, LSU_DEFEATURE |
| 62 | mfcr t1, t0 | ||
| 63 | |||
| 64 | lui t2, 0x4080 /* Enable Unaligned Access, L2HPE */ | ||
| 65 | or t1, t1, t2 | ||
| 66 | #ifdef XLP_AX_WORKAROUND | ||
| 67 | li t2, ~0xe /* S1RCM */ | ||
| 64 | and t1, t1, t2 | 68 | and t1, t1, t2 |
| 65 | mtcr t1, t0 | 69 | #endif |
| 70 | mtcr t1, t0 | ||
| 66 | 71 | ||
| 67 | li t0, SCHED_DEFEATURE | 72 | #ifdef XLP_AX_WORKAROUND |
| 68 | lui t1, 0x0100 /* Experimental: Disable BRU accepting ALU ops */ | 73 | li t0, SCHED_DEFEATURE |
| 69 | mtcr t1, t0 | 74 | lui t1, 0x0100 /* Disable BRU accepting ALU ops */ |
| 75 | mtcr t1, t0 | ||
| 76 | #endif | ||
| 77 | .endm | ||
| 78 | |||
| 79 | /* | ||
| 80 | * This is the code that will be copied to the reset entry point for | ||
| 81 | * XLR and XLP. The XLP cores start here when they are woken up. This | ||
| 82 | * is also the NMI entry point. | ||
| 83 | */ | ||
| 84 | .macro xlp_flush_l1_dcache | ||
| 85 | li t0, LSU_DEBUG_DATA0 | ||
| 86 | li t1, LSU_DEBUG_ADDR | ||
| 87 | li t2, 0 /* index */ | ||
| 88 | li t3, 0x1000 /* loop count */ | ||
| 89 | 1: | ||
| 90 | sll v0, t2, 5 | ||
| 91 | mtcr zero, t0 | ||
| 92 | ori v1, v0, 0x3 /* way0 | write_enable | write_active */ | ||
| 93 | mtcr v1, t1 | ||
| 94 | 2: | ||
| 95 | mfcr v1, t1 | ||
| 96 | andi v1, 0x1 /* wait for write_active == 0 */ | ||
| 97 | bnez v1, 2b | ||
| 98 | nop | ||
| 99 | mtcr zero, t0 | ||
| 100 | ori v1, v0, 0x7 /* way1 | write_enable | write_active */ | ||
| 101 | mtcr v1, t1 | ||
| 102 | 3: | ||
| 103 | mfcr v1, t1 | ||
| 104 | andi v1, 0x1 /* wait for write_active == 0 */ | ||
| 105 | bnez v1, 3b | ||
| 106 | nop | ||
| 107 | addi t2, 1 | ||
| 108 | bne t3, t2, 1b | ||
| 109 | nop | ||
| 70 | .endm | 110 | .endm |
| 71 | 111 | ||
| 72 | /* | 112 | /* |
| 73 | * The cores can come start when they are woken up. This is also the NMI | 113 | * The cores can come start when they are woken up. This is also the NMI |
| 74 | * entry, so check that first. | 114 | * entry, so check that first. |
| 75 | * | 115 | * |
| 76 | * The data corresponding to reset is stored at RESET_DATA_PHYS location, | 116 | * The data corresponding to reset/NMI is stored at RESET_DATA_PHYS |
| 77 | * this will have the thread mask (used when core is woken up) and the | 117 | * location, this will have the thread mask (used when core is woken up) |
| 78 | * current NMI handler in case we reached here for an NMI. | 118 | * and the current NMI handler in case we reached here for an NMI. |
| 79 | * | 119 | * |
| 80 | * When a core or thread is newly woken up, it loops in a 'wait'. When | 120 | * When a core or thread is newly woken up, it loops in a 'wait'. When |
| 81 | * the CPU really needs waking up, we send an NMI to it, with the NMI | 121 | * the CPU really needs waking up, we send an NMI to it, with the NMI |
| @@ -89,12 +129,12 @@ | |||
| 89 | FEXPORT(nlm_reset_entry) | 129 | FEXPORT(nlm_reset_entry) |
| 90 | dmtc0 k0, $22, 6 | 130 | dmtc0 k0, $22, 6 |
| 91 | dmtc0 k1, $22, 7 | 131 | dmtc0 k1, $22, 7 |
| 92 | mfc0 k0, CP0_STATUS | 132 | mfc0 k0, CP0_STATUS |
| 93 | li k1, 0x80000 | 133 | li k1, 0x80000 |
| 94 | and k1, k0, k1 | 134 | and k1, k0, k1 |
| 95 | beqz k1, 1f /* go to real reset entry */ | 135 | beqz k1, 1f /* go to real reset entry */ |
| 96 | nop | 136 | nop |
| 97 | li k1, CKSEG1ADDR(RESET_DATA_PHYS) /* NMI */ | 137 | li k1, CKSEG1ADDR(RESET_DATA_PHYS) /* NMI */ |
| 98 | ld k0, BOOT_NMI_HANDLER(k1) | 138 | ld k0, BOOT_NMI_HANDLER(k1) |
| 99 | jr k0 | 139 | jr k0 |
| 100 | nop | 140 | nop |
| @@ -114,21 +154,25 @@ FEXPORT(nlm_reset_entry) | |||
| 114 | li t2, SYS_CPU_COHERENT_BASE(0) | 154 | li t2, SYS_CPU_COHERENT_BASE(0) |
| 115 | add t2, t2, t3 /* t2 <- SYS offset for node */ | 155 | add t2, t2, t3 /* t2 <- SYS offset for node */ |
| 116 | lw t1, 0(t2) | 156 | lw t1, 0(t2) |
| 117 | and t1, t1, t0 | 157 | and t1, t1, t0 |
| 118 | sw t1, 0(t2) | 158 | sw t1, 0(t2) |
| 119 | 159 | ||
| 120 | /* read back to ensure complete */ | 160 | /* read back to ensure complete */ |
| 121 | lw t1, 0(t2) | 161 | lw t1, 0(t2) |
| 122 | sync | 162 | sync |
| 123 | 163 | ||
| 124 | /* Configure LSU on Non-0 Cores. */ | 164 | /* Configure LSU on Non-0 Cores. */ |
| 125 | __config_lsu | 165 | xlp_config_lsu |
| 166 | /* FALL THROUGH */ | ||
| 126 | 167 | ||
| 127 | /* | 168 | /* |
| 128 | * Wake up sibling threads from the initial thread in | 169 | * Wake up sibling threads from the initial thread in |
| 129 | * a core. | 170 | * a core. |
| 130 | */ | 171 | */ |
| 131 | EXPORT(nlm_boot_siblings) | 172 | EXPORT(nlm_boot_siblings) |
| 173 | /* core L1D flush before enable threads */ | ||
| 174 | xlp_flush_l1_dcache | ||
| 175 | /* Enable hw threads by writing to MAP_THREADMODE of the core */ | ||
| 132 | li t0, CKSEG1ADDR(RESET_DATA_PHYS) | 176 | li t0, CKSEG1ADDR(RESET_DATA_PHYS) |
| 133 | lw t1, BOOT_THREAD_MODE(t0) /* t1 <- thread mode */ | 177 | lw t1, BOOT_THREAD_MODE(t0) /* t1 <- thread mode */ |
| 134 | li t0, ((CPU_BLOCKID_MAP << 8) | MAP_THREADMODE) | 178 | li t0, ((CPU_BLOCKID_MAP << 8) | MAP_THREADMODE) |
| @@ -139,31 +183,28 @@ EXPORT(nlm_boot_siblings) | |||
| 139 | /* | 183 | /* |
| 140 | * The new hardware thread starts at the next instruction | 184 | * The new hardware thread starts at the next instruction |
| 141 | * For all the cases other than core 0 thread 0, we will | 185 | * For all the cases other than core 0 thread 0, we will |
| 142 | * jump to the secondary wait function. | 186 | * jump to the secondary wait function. |
| 143 | */ | 187 | */ |
| 144 | mfc0 v0, CP0_EBASE, 1 | 188 | mfc0 v0, CP0_EBASE, 1 |
| 145 | andi v0, 0x7f /* v0 <- node/core */ | 189 | andi v0, 0x7f /* v0 <- node/core */ |
| 146 | 190 | ||
| 147 | #if 1 | 191 | /* Init MMU in the first thread after changing THREAD_MODE |
| 148 | /* A0 errata - Write MMU_SETUP after changing thread mode register. */ | 192 | * register (Ax Errata?) |
| 193 | */ | ||
| 149 | andi v1, v0, 0x3 /* v1 <- thread id */ | 194 | andi v1, v0, 0x3 /* v1 <- thread id */ |
| 150 | bnez v1, 2f | 195 | bnez v1, 2f |
| 151 | nop | 196 | nop |
| 152 | 197 | ||
| 153 | li t0, MMU_SETUP | 198 | li t0, MMU_SETUP |
| 154 | li t1, 0 | 199 | li t1, 0 |
| 155 | mtcr t1, t0 | 200 | mtcr t1, t0 |
| 156 | ehb | 201 | _ehb |
| 157 | #endif | ||
| 158 | 202 | ||
| 159 | 2: beqz v0, 4f | 203 | 2: beqz v0, 4f /* boot cpu (cpuid == 0)? */ |
| 160 | nop | 204 | nop |
| 161 | 205 | ||
| 162 | /* setup status reg */ | 206 | /* setup status reg */ |
| 163 | mfc0 t1, CP0_STATUS | 207 | move t1, zero |
| 164 | li t0, ST0_BEV | ||
| 165 | or t1, t0 | ||
| 166 | xor t1, t0 | ||
| 167 | #ifdef CONFIG_64BIT | 208 | #ifdef CONFIG_64BIT |
| 168 | ori t1, ST0_KX | 209 | ori t1, ST0_KX |
| 169 | #endif | 210 | #endif |
| @@ -183,9 +224,9 @@ EXPORT(nlm_boot_siblings) | |||
| 183 | * For the boot CPU, we have to restore registers and | 224 | * For the boot CPU, we have to restore registers and |
| 184 | * return | 225 | * return |
| 185 | */ | 226 | */ |
| 186 | 4: dmfc0 t0, $4, 2 /* restore SP from UserLocal */ | 227 | 4: dmfc0 t0, $4, 2 /* restore SP from UserLocal */ |
| 187 | li t1, 0xfadebeef | 228 | li t1, 0xfadebeef |
| 188 | dmtc0 t1, $4, 2 /* restore SP from UserLocal */ | 229 | dmtc0 t1, $4, 2 /* restore SP from UserLocal */ |
| 189 | PTR_SUBU sp, t0, PT_SIZE | 230 | PTR_SUBU sp, t0, PT_SIZE |
| 190 | RESTORE_ALL | 231 | RESTORE_ALL |
| 191 | jr ra | 232 | jr ra |
| @@ -193,7 +234,7 @@ EXPORT(nlm_boot_siblings) | |||
| 193 | EXPORT(nlm_reset_entry_end) | 234 | EXPORT(nlm_reset_entry_end) |
| 194 | 235 | ||
| 195 | FEXPORT(xlp_boot_core0_siblings) /* "Master" cpu starts from here */ | 236 | FEXPORT(xlp_boot_core0_siblings) /* "Master" cpu starts from here */ |
| 196 | __config_lsu | 237 | xlp_config_lsu |
| 197 | dmtc0 sp, $4, 2 /* SP saved in UserLocal */ | 238 | dmtc0 sp, $4, 2 /* SP saved in UserLocal */ |
| 198 | SAVE_ALL | 239 | SAVE_ALL |
| 199 | sync | 240 | sync |
| @@ -210,6 +251,12 @@ FEXPORT(xlp_boot_core0_siblings) /* "Master" cpu starts from here */ | |||
| 210 | 251 | ||
| 211 | __CPUINIT | 252 | __CPUINIT |
| 212 | NESTED(nlm_boot_secondary_cpus, 16, sp) | 253 | NESTED(nlm_boot_secondary_cpus, 16, sp) |
| 254 | /* Initialize CP0 Status */ | ||
| 255 | move t1, zero | ||
| 256 | #ifdef CONFIG_64BIT | ||
| 257 | ori t1, ST0_KX | ||
| 258 | #endif | ||
| 259 | mtc0 t1, CP0_STATUS | ||
| 213 | PTR_LA t1, nlm_next_sp | 260 | PTR_LA t1, nlm_next_sp |
| 214 | PTR_L sp, 0(t1) | 261 | PTR_L sp, 0(t1) |
| 215 | PTR_LA t1, nlm_next_gp | 262 | PTR_LA t1, nlm_next_gp |
| @@ -234,36 +281,36 @@ END(nlm_boot_secondary_cpus) | |||
| 234 | */ | 281 | */ |
| 235 | __CPUINIT | 282 | __CPUINIT |
| 236 | NESTED(nlm_rmiboot_preboot, 16, sp) | 283 | NESTED(nlm_rmiboot_preboot, 16, sp) |
| 237 | mfc0 t0, $15, 1 # read ebase | 284 | mfc0 t0, $15, 1 /* read ebase */ |
| 238 | andi t0, 0x1f # t0 has the processor_id() | 285 | andi t0, 0x1f /* t0 has the processor_id() */ |
| 239 | andi t2, t0, 0x3 # thread no | 286 | andi t2, t0, 0x3 /* thread num */ |
| 240 | sll t0, 2 # offset in cpu array | 287 | sll t0, 2 /* offset in cpu array */ |
| 241 | 288 | ||
| 242 | PTR_LA t1, nlm_cpu_ready # mark CPU ready | 289 | PTR_LA t1, nlm_cpu_ready /* mark CPU ready */ |
| 243 | PTR_ADDU t1, t0 | 290 | PTR_ADDU t1, t0 |
| 244 | li t3, 1 | 291 | li t3, 1 |
| 245 | sw t3, 0(t1) | 292 | sw t3, 0(t1) |
| 246 | 293 | ||
| 247 | bnez t2, 1f # skip thread programming | 294 | bnez t2, 1f /* skip thread programming */ |
| 248 | nop # for non zero hw threads | 295 | nop /* for thread id != 0 */ |
| 249 | 296 | ||
| 250 | /* | 297 | /* |
| 251 | * MMU setup only for first thread in core | 298 | * XLR MMU setup only for first thread in core |
| 252 | */ | 299 | */ |
| 253 | li t0, 0x400 | 300 | li t0, 0x400 |
| 254 | mfcr t1, t0 | 301 | mfcr t1, t0 |
| 255 | li t2, 6 # XLR thread mode mask | 302 | li t2, 6 /* XLR thread mode mask */ |
| 256 | nor t3, t2, zero | 303 | nor t3, t2, zero |
| 257 | and t2, t1, t2 # t2 - current thread mode | 304 | and t2, t1, t2 /* t2 - current thread mode */ |
| 258 | li v0, CKSEG1ADDR(RESET_DATA_PHYS) | 305 | li v0, CKSEG1ADDR(RESET_DATA_PHYS) |
| 259 | lw v1, BOOT_THREAD_MODE(v0) # v1 - new thread mode | 306 | lw v1, BOOT_THREAD_MODE(v0) /* v1 - new thread mode */ |
| 260 | sll v1, 1 | 307 | sll v1, 1 |
| 261 | beq v1, t2, 1f # same as request value | 308 | beq v1, t2, 1f /* same as request value */ |
| 262 | nop # nothing to do */ | 309 | nop /* nothing to do */ |
| 263 | 310 | ||
| 264 | and t2, t1, t3 # mask out old thread mode | 311 | and t2, t1, t3 /* mask out old thread mode */ |
| 265 | or t1, t2, v1 # put in new value | 312 | or t1, t2, v1 /* put in new value */ |
| 266 | mtcr t1, t0 # update core control | 313 | mtcr t1, t0 /* update core control */ |
| 267 | 314 | ||
| 268 | 1: wait | 315 | 1: wait |
| 269 | j 1b | 316 | j 1b |
diff --git a/arch/mips/netlogic/xlp/Makefile b/arch/mips/netlogic/xlp/Makefile index b93ed83474ec..6b4b972218f0 100644 --- a/arch/mips/netlogic/xlp/Makefile +++ b/arch/mips/netlogic/xlp/Makefile | |||
| @@ -1,2 +1,4 @@ | |||
| 1 | obj-y += setup.o platform.o nlm_hal.o | 1 | obj-y += setup.o platform.o nlm_hal.o |
| 2 | obj-$(CONFIG_OF) += of.o | ||
| 2 | obj-$(CONFIG_SMP) += wakeup.o | 3 | obj-$(CONFIG_SMP) += wakeup.o |
| 4 | obj-$(CONFIG_USB) += usb-init.o | ||
diff --git a/arch/mips/netlogic/xlp/nlm_hal.c b/arch/mips/netlogic/xlp/nlm_hal.c index 9428e7125fed..6c65ac701912 100644 --- a/arch/mips/netlogic/xlp/nlm_hal.c +++ b/arch/mips/netlogic/xlp/nlm_hal.c | |||
| @@ -69,6 +69,32 @@ int nlm_irq_to_irt(int irq) | |||
| 69 | return PIC_IRT_UART_0_INDEX; | 69 | return PIC_IRT_UART_0_INDEX; |
| 70 | case PIC_UART_1_IRQ: | 70 | case PIC_UART_1_IRQ: |
| 71 | return PIC_IRT_UART_1_INDEX; | 71 | return PIC_IRT_UART_1_INDEX; |
| 72 | case PIC_PCIE_LINK_0_IRQ: | ||
| 73 | return PIC_IRT_PCIE_LINK_0_INDEX; | ||
| 74 | case PIC_PCIE_LINK_1_IRQ: | ||
| 75 | return PIC_IRT_PCIE_LINK_1_INDEX; | ||
| 76 | case PIC_PCIE_LINK_2_IRQ: | ||
| 77 | return PIC_IRT_PCIE_LINK_2_INDEX; | ||
| 78 | case PIC_PCIE_LINK_3_IRQ: | ||
| 79 | return PIC_IRT_PCIE_LINK_3_INDEX; | ||
| 80 | case PIC_EHCI_0_IRQ: | ||
| 81 | return PIC_IRT_EHCI_0_INDEX; | ||
| 82 | case PIC_EHCI_1_IRQ: | ||
| 83 | return PIC_IRT_EHCI_1_INDEX; | ||
| 84 | case PIC_OHCI_0_IRQ: | ||
| 85 | return PIC_IRT_OHCI_0_INDEX; | ||
| 86 | case PIC_OHCI_1_IRQ: | ||
| 87 | return PIC_IRT_OHCI_1_INDEX; | ||
| 88 | case PIC_OHCI_2_IRQ: | ||
| 89 | return PIC_IRT_OHCI_2_INDEX; | ||
| 90 | case PIC_OHCI_3_IRQ: | ||
| 91 | return PIC_IRT_OHCI_3_INDEX; | ||
| 92 | case PIC_MMC_IRQ: | ||
| 93 | return PIC_IRT_MMC_INDEX; | ||
| 94 | case PIC_I2C_0_IRQ: | ||
| 95 | return PIC_IRT_I2C_0_INDEX; | ||
| 96 | case PIC_I2C_1_IRQ: | ||
| 97 | return PIC_IRT_I2C_1_INDEX; | ||
| 72 | default: | 98 | default: |
| 73 | return -1; | 99 | return -1; |
| 74 | } | 100 | } |
| @@ -81,6 +107,32 @@ int nlm_irt_to_irq(int irt) | |||
| 81 | return PIC_UART_0_IRQ; | 107 | return PIC_UART_0_IRQ; |
| 82 | case PIC_IRT_UART_1_INDEX: | 108 | case PIC_IRT_UART_1_INDEX: |
| 83 | return PIC_UART_1_IRQ; | 109 | return PIC_UART_1_IRQ; |
| 110 | case PIC_IRT_PCIE_LINK_0_INDEX: | ||
| 111 | return PIC_PCIE_LINK_0_IRQ; | ||
| 112 | case PIC_IRT_PCIE_LINK_1_INDEX: | ||
| 113 | return PIC_PCIE_LINK_1_IRQ; | ||
| 114 | case PIC_IRT_PCIE_LINK_2_INDEX: | ||
| 115 | return PIC_PCIE_LINK_2_IRQ; | ||
| 116 | case PIC_IRT_PCIE_LINK_3_INDEX: | ||
| 117 | return PIC_PCIE_LINK_3_IRQ; | ||
| 118 | case PIC_IRT_EHCI_0_INDEX: | ||
| 119 | return PIC_EHCI_0_IRQ; | ||
| 120 | case PIC_IRT_EHCI_1_INDEX: | ||
| 121 | return PIC_EHCI_1_IRQ; | ||
| 122 | case PIC_IRT_OHCI_0_INDEX: | ||
| 123 | return PIC_OHCI_0_IRQ; | ||
| 124 | case PIC_IRT_OHCI_1_INDEX: | ||
| 125 | return PIC_OHCI_1_IRQ; | ||
| 126 | case PIC_IRT_OHCI_2_INDEX: | ||
| 127 | return PIC_OHCI_2_IRQ; | ||
| 128 | case PIC_IRT_OHCI_3_INDEX: | ||
| 129 | return PIC_OHCI_3_IRQ; | ||
| 130 | case PIC_IRT_MMC_INDEX: | ||
| 131 | return PIC_MMC_IRQ; | ||
| 132 | case PIC_IRT_I2C_0_INDEX: | ||
| 133 | return PIC_I2C_0_IRQ; | ||
| 134 | case PIC_IRT_I2C_1_INDEX: | ||
| 135 | return PIC_I2C_1_IRQ; | ||
| 84 | default: | 136 | default: |
| 85 | return -1; | 137 | return -1; |
| 86 | } | 138 | } |
diff --git a/arch/mips/netlogic/xlp/of.c b/arch/mips/netlogic/xlp/of.c new file mode 100644 index 000000000000..8e3921c0c201 --- /dev/null +++ b/arch/mips/netlogic/xlp/of.c | |||
| @@ -0,0 +1,34 @@ | |||
| 1 | #include <linux/bootmem.h> | ||
| 2 | #include <linux/init.h> | ||
| 3 | #include <linux/io.h> | ||
| 4 | #include <linux/of_fdt.h> | ||
| 5 | #include <asm/byteorder.h> | ||
| 6 | |||
| 7 | static int __init reserve_mem_mach(unsigned long addr, unsigned long size) | ||
| 8 | { | ||
| 9 | return reserve_bootmem(addr, size, BOOTMEM_DEFAULT); | ||
| 10 | } | ||
| 11 | |||
| 12 | void __init free_mem_mach(unsigned long addr, unsigned long size) | ||
| 13 | { | ||
| 14 | return free_bootmem(addr, size); | ||
| 15 | } | ||
| 16 | |||
| 17 | void __init device_tree_init(void) | ||
| 18 | { | ||
| 19 | unsigned long base, size; | ||
| 20 | |||
| 21 | if (!initial_boot_params) | ||
| 22 | return; | ||
| 23 | |||
| 24 | base = virt_to_phys((void *)initial_boot_params); | ||
| 25 | size = be32_to_cpu(initial_boot_params->totalsize); | ||
| 26 | |||
| 27 | /* Before we do anything, lets reserve the dt blob */ | ||
| 28 | reserve_mem_mach(base, size); | ||
| 29 | |||
| 30 | unflatten_device_tree(); | ||
| 31 | |||
| 32 | /* free the space reserved for the dt blob */ | ||
| 33 | free_mem_mach(base, size); | ||
| 34 | } | ||
diff --git a/arch/mips/netlogic/xlp/platform.c b/arch/mips/netlogic/xlp/platform.c index 1f5e4cba891d..2c510d585447 100644 --- a/arch/mips/netlogic/xlp/platform.c +++ b/arch/mips/netlogic/xlp/platform.c | |||
| @@ -53,7 +53,7 @@ | |||
| 53 | 53 | ||
| 54 | static unsigned int nlm_xlp_uart_in(struct uart_port *p, int offset) | 54 | static unsigned int nlm_xlp_uart_in(struct uart_port *p, int offset) |
| 55 | { | 55 | { |
| 56 | return nlm_read_reg(p->iobase, offset); | 56 | return nlm_read_reg(p->iobase, offset); |
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | static void nlm_xlp_uart_out(struct uart_port *p, int offset, int value) | 59 | static void nlm_xlp_uart_out(struct uart_port *p, int offset, int value) |
diff --git a/arch/mips/netlogic/xlp/setup.c b/arch/mips/netlogic/xlp/setup.c index b3df7c2aad1e..3dec9f28b65b 100644 --- a/arch/mips/netlogic/xlp/setup.c +++ b/arch/mips/netlogic/xlp/setup.c | |||
| @@ -41,6 +41,8 @@ | |||
| 41 | #include <asm/bootinfo.h> | 41 | #include <asm/bootinfo.h> |
| 42 | 42 | ||
| 43 | #include <linux/of_fdt.h> | 43 | #include <linux/of_fdt.h> |
| 44 | #include <linux/of_platform.h> | ||
| 45 | #include <linux/of_device.h> | ||
| 44 | 46 | ||
| 45 | #include <asm/netlogic/haldefs.h> | 47 | #include <asm/netlogic/haldefs.h> |
| 46 | #include <asm/netlogic/common.h> | 48 | #include <asm/netlogic/common.h> |
| @@ -109,3 +111,17 @@ void __init prom_init(void) | |||
| 109 | register_smp_ops(&nlm_smp_ops); | 111 | register_smp_ops(&nlm_smp_ops); |
| 110 | #endif | 112 | #endif |
| 111 | } | 113 | } |
| 114 | |||
| 115 | static struct of_device_id __initdata xlp_ids[] = { | ||
| 116 | { .compatible = "simple-bus", }, | ||
| 117 | {}, | ||
| 118 | }; | ||
| 119 | |||
| 120 | int __init xlp8xx_ds_publish_devices(void) | ||
| 121 | { | ||
| 122 | if (!of_have_populated_dt()) | ||
| 123 | return 0; | ||
| 124 | return of_platform_bus_probe(NULL, xlp_ids, NULL); | ||
| 125 | } | ||
| 126 | |||
| 127 | device_initcall(xlp8xx_ds_publish_devices); | ||
diff --git a/arch/mips/netlogic/xlp/usb-init.c b/arch/mips/netlogic/xlp/usb-init.c new file mode 100644 index 000000000000..dbe083a93538 --- /dev/null +++ b/arch/mips/netlogic/xlp/usb-init.c | |||
| @@ -0,0 +1,124 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2003-2012 Broadcom Corporation | ||
| 3 | * All Rights Reserved | ||
| 4 | * | ||
| 5 | * This software is available to you under a choice of one of two | ||
| 6 | * licenses. You may choose to be licensed under the terms of the GNU | ||
| 7 | * General Public License (GPL) Version 2, available from the file | ||
| 8 | * COPYING in the main directory of this source tree, or the Broadcom | ||
| 9 | * license below: | ||
| 10 | * | ||
| 11 | * Redistribution and use in source and binary forms, with or without | ||
| 12 | * modification, are permitted provided that the following conditions | ||
| 13 | * are met: | ||
| 14 | * | ||
| 15 | * 1. Redistributions of source code must retain the above copyright | ||
| 16 | * notice, this list of conditions and the following disclaimer. | ||
| 17 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 18 | * notice, this list of conditions and the following disclaimer in | ||
| 19 | * the documentation and/or other materials provided with the | ||
| 20 | * distribution. | ||
| 21 | * | ||
| 22 | * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR | ||
| 23 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
| 24 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 25 | * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE | ||
| 26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
| 27 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
| 28 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
| 29 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
| 30 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE | ||
| 31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN | ||
| 32 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 33 | */ | ||
| 34 | |||
| 35 | #include <linux/dma-mapping.h> | ||
| 36 | #include <linux/kernel.h> | ||
| 37 | #include <linux/delay.h> | ||
| 38 | #include <linux/init.h> | ||
| 39 | #include <linux/pci.h> | ||
| 40 | #include <linux/platform_device.h> | ||
| 41 | |||
| 42 | #include <asm/netlogic/haldefs.h> | ||
| 43 | #include <asm/netlogic/xlp-hal/iomap.h> | ||
| 44 | #include <asm/netlogic/xlp-hal/xlp.h> | ||
| 45 | #include <asm/netlogic/xlp-hal/usb.h> | ||
| 46 | |||
| 47 | static void nlm_usb_intr_en(int node, int port) | ||
| 48 | { | ||
| 49 | uint32_t val; | ||
| 50 | uint64_t port_addr; | ||
| 51 | |||
| 52 | port_addr = nlm_get_usb_regbase(node, port); | ||
| 53 | val = nlm_read_usb_reg(port_addr, USB_INT_EN); | ||
| 54 | val = USB_CTRL_INTERRUPT_EN | USB_OHCI_INTERRUPT_EN | | ||
| 55 | USB_OHCI_INTERRUPT1_EN | USB_CTRL_INTERRUPT_EN | | ||
| 56 | USB_OHCI_INTERRUPT_EN | USB_OHCI_INTERRUPT2_EN; | ||
| 57 | nlm_write_usb_reg(port_addr, USB_INT_EN, val); | ||
| 58 | } | ||
| 59 | |||
| 60 | static void nlm_usb_hw_reset(int node, int port) | ||
| 61 | { | ||
| 62 | uint64_t port_addr; | ||
| 63 | uint32_t val; | ||
| 64 | |||
| 65 | /* reset USB phy */ | ||
| 66 | port_addr = nlm_get_usb_regbase(node, port); | ||
| 67 | val = nlm_read_usb_reg(port_addr, USB_PHY_0); | ||
| 68 | val &= ~(USB_PHY_RESET | USB_PHY_PORT_RESET_0 | USB_PHY_PORT_RESET_1); | ||
| 69 | nlm_write_usb_reg(port_addr, USB_PHY_0, val); | ||
| 70 | |||
| 71 | mdelay(100); | ||
| 72 | val = nlm_read_usb_reg(port_addr, USB_CTL_0); | ||
| 73 | val &= ~(USB_CONTROLLER_RESET); | ||
| 74 | val |= 0x4; | ||
| 75 | nlm_write_usb_reg(port_addr, USB_CTL_0, val); | ||
| 76 | } | ||
| 77 | |||
| 78 | static int __init nlm_platform_usb_init(void) | ||
| 79 | { | ||
| 80 | pr_info("Initializing USB Interface\n"); | ||
| 81 | nlm_usb_hw_reset(0, 0); | ||
| 82 | nlm_usb_hw_reset(0, 3); | ||
| 83 | |||
| 84 | /* Enable PHY interrupts */ | ||
| 85 | nlm_usb_intr_en(0, 0); | ||
| 86 | nlm_usb_intr_en(0, 3); | ||
| 87 | |||
| 88 | return 0; | ||
| 89 | } | ||
| 90 | |||
| 91 | arch_initcall(nlm_platform_usb_init); | ||
| 92 | |||
| 93 | static u64 xlp_usb_dmamask = ~(u32)0; | ||
| 94 | |||
| 95 | /* Fixup the IRQ for USB devices which is exist on XLP SOC PCIE bus */ | ||
| 96 | static void nlm_usb_fixup_final(struct pci_dev *dev) | ||
| 97 | { | ||
| 98 | dev->dev.dma_mask = &xlp_usb_dmamask; | ||
| 99 | dev->dev.coherent_dma_mask = DMA_BIT_MASK(64); | ||
| 100 | switch (dev->devfn) { | ||
| 101 | case 0x10: | ||
| 102 | dev->irq = PIC_EHCI_0_IRQ; | ||
| 103 | break; | ||
| 104 | case 0x11: | ||
| 105 | dev->irq = PIC_OHCI_0_IRQ; | ||
| 106 | break; | ||
| 107 | case 0x12: | ||
| 108 | dev->irq = PIC_OHCI_1_IRQ; | ||
| 109 | break; | ||
| 110 | case 0x13: | ||
| 111 | dev->irq = PIC_EHCI_1_IRQ; | ||
| 112 | break; | ||
| 113 | case 0x14: | ||
| 114 | dev->irq = PIC_OHCI_2_IRQ; | ||
| 115 | break; | ||
| 116 | case 0x15: | ||
| 117 | dev->irq = PIC_OHCI_3_IRQ; | ||
| 118 | break; | ||
| 119 | } | ||
| 120 | } | ||
| 121 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_NETLOGIC, PCI_DEVICE_ID_NLM_EHCI, | ||
| 122 | nlm_usb_fixup_final); | ||
| 123 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_NETLOGIC, PCI_DEVICE_ID_NLM_OHCI, | ||
| 124 | nlm_usb_fixup_final); | ||
diff --git a/arch/mips/netlogic/xlr/Makefile b/arch/mips/netlogic/xlr/Makefile index f01e4d7a0600..c287dea87570 100644 --- a/arch/mips/netlogic/xlr/Makefile +++ b/arch/mips/netlogic/xlr/Makefile | |||
| @@ -1,2 +1,2 @@ | |||
| 1 | obj-y += setup.o platform.o | 1 | obj-y += setup.o platform.o platform-flash.o |
| 2 | obj-$(CONFIG_SMP) += wakeup.o | 2 | obj-$(CONFIG_SMP) += wakeup.o |
diff --git a/arch/mips/netlogic/xlr/platform-flash.c b/arch/mips/netlogic/xlr/platform-flash.c new file mode 100644 index 000000000000..340ab1601c42 --- /dev/null +++ b/arch/mips/netlogic/xlr/platform-flash.c | |||
| @@ -0,0 +1,220 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2011, Netlogic Microsystems. | ||
| 3 | * Copyright 2004, Matt Porter <mporter@kernel.crashing.org> | ||
| 4 | * | ||
| 5 | * This file is licensed under the terms of the GNU General Public | ||
| 6 | * License version 2. This program is licensed "as is" without any | ||
| 7 | * warranty of any kind, whether express or implied. | ||
| 8 | */ | ||
| 9 | |||
| 10 | #include <linux/device.h> | ||
| 11 | #include <linux/platform_device.h> | ||
| 12 | #include <linux/kernel.h> | ||
| 13 | #include <linux/init.h> | ||
| 14 | #include <linux/io.h> | ||
| 15 | #include <linux/delay.h> | ||
| 16 | #include <linux/ioport.h> | ||
| 17 | #include <linux/resource.h> | ||
| 18 | #include <linux/spi/flash.h> | ||
| 19 | |||
| 20 | #include <linux/mtd/mtd.h> | ||
| 21 | #include <linux/mtd/physmap.h> | ||
| 22 | #include <linux/mtd/nand.h> | ||
| 23 | #include <linux/mtd/partitions.h> | ||
| 24 | |||
| 25 | #include <asm/netlogic/haldefs.h> | ||
| 26 | #include <asm/netlogic/xlr/iomap.h> | ||
| 27 | #include <asm/netlogic/xlr/flash.h> | ||
| 28 | #include <asm/netlogic/xlr/bridge.h> | ||
| 29 | #include <asm/netlogic/xlr/gpio.h> | ||
| 30 | #include <asm/netlogic/xlr/xlr.h> | ||
| 31 | |||
| 32 | /* | ||
| 33 | * Default NOR partition layout | ||
| 34 | */ | ||
| 35 | static struct mtd_partition xlr_nor_parts[] = { | ||
| 36 | { | ||
| 37 | .name = "User FS", | ||
| 38 | .offset = 0x800000, | ||
| 39 | .size = MTDPART_SIZ_FULL, | ||
| 40 | } | ||
| 41 | }; | ||
| 42 | |||
| 43 | /* | ||
| 44 | * Default NAND partition layout | ||
| 45 | */ | ||
| 46 | static struct mtd_partition xlr_nand_parts[] = { | ||
| 47 | { | ||
| 48 | .name = "Root Filesystem", | ||
| 49 | .offset = 64 * 64 * 2048, | ||
| 50 | .size = 432 * 64 * 2048, | ||
| 51 | }, | ||
| 52 | { | ||
| 53 | .name = "Home Filesystem", | ||
| 54 | .offset = MTDPART_OFS_APPEND, | ||
| 55 | .size = MTDPART_SIZ_FULL, | ||
| 56 | }, | ||
| 57 | }; | ||
| 58 | |||
| 59 | /* Use PHYSMAP flash for NOR */ | ||
| 60 | struct physmap_flash_data xlr_nor_data = { | ||
| 61 | .width = 2, | ||
| 62 | .parts = xlr_nor_parts, | ||
| 63 | .nr_parts = ARRAY_SIZE(xlr_nor_parts), | ||
| 64 | }; | ||
| 65 | |||
| 66 | static struct resource xlr_nor_res[] = { | ||
| 67 | { | ||
| 68 | .flags = IORESOURCE_MEM, | ||
| 69 | }, | ||
| 70 | }; | ||
| 71 | |||
| 72 | static struct platform_device xlr_nor_dev = { | ||
| 73 | .name = "physmap-flash", | ||
| 74 | .dev = { | ||
| 75 | .platform_data = &xlr_nor_data, | ||
| 76 | }, | ||
| 77 | .num_resources = ARRAY_SIZE(xlr_nor_res), | ||
| 78 | .resource = xlr_nor_res, | ||
| 79 | }; | ||
| 80 | |||
| 81 | const char *xlr_part_probes[] = { "cmdlinepart", NULL }; | ||
| 82 | |||
| 83 | /* | ||
| 84 | * Use "gen_nand" driver for NAND flash | ||
| 85 | * | ||
| 86 | * There seems to be no way to store a private pointer containing | ||
| 87 | * platform specific info in gen_nand drivier. We will use a global | ||
| 88 | * struct for now, since we currently have only one NAND chip per board. | ||
| 89 | */ | ||
| 90 | struct xlr_nand_flash_priv { | ||
| 91 | int cs; | ||
| 92 | uint64_t flash_mmio; | ||
| 93 | }; | ||
| 94 | |||
| 95 | static struct xlr_nand_flash_priv nand_priv; | ||
| 96 | |||
| 97 | static void xlr_nand_ctrl(struct mtd_info *mtd, int cmd, | ||
| 98 | unsigned int ctrl) | ||
| 99 | { | ||
| 100 | if (ctrl & NAND_CLE) | ||
| 101 | nlm_write_reg(nand_priv.flash_mmio, | ||
| 102 | FLASH_NAND_CLE(nand_priv.cs), cmd); | ||
| 103 | else if (ctrl & NAND_ALE) | ||
| 104 | nlm_write_reg(nand_priv.flash_mmio, | ||
| 105 | FLASH_NAND_ALE(nand_priv.cs), cmd); | ||
| 106 | } | ||
| 107 | |||
| 108 | struct platform_nand_data xlr_nand_data = { | ||
| 109 | .chip = { | ||
| 110 | .nr_chips = 1, | ||
| 111 | .nr_partitions = ARRAY_SIZE(xlr_nand_parts), | ||
| 112 | .chip_delay = 50, | ||
| 113 | .partitions = xlr_nand_parts, | ||
| 114 | .part_probe_types = xlr_part_probes, | ||
| 115 | }, | ||
| 116 | .ctrl = { | ||
| 117 | .cmd_ctrl = xlr_nand_ctrl, | ||
| 118 | }, | ||
| 119 | }; | ||
| 120 | |||
| 121 | static struct resource xlr_nand_res[] = { | ||
| 122 | { | ||
| 123 | .flags = IORESOURCE_MEM, | ||
| 124 | }, | ||
| 125 | }; | ||
| 126 | |||
| 127 | static struct platform_device xlr_nand_dev = { | ||
| 128 | .name = "gen_nand", | ||
| 129 | .id = -1, | ||
| 130 | .num_resources = ARRAY_SIZE(xlr_nand_res), | ||
| 131 | .resource = xlr_nand_res, | ||
| 132 | .dev = { | ||
| 133 | .platform_data = &xlr_nand_data, | ||
| 134 | } | ||
| 135 | }; | ||
| 136 | |||
| 137 | /* | ||
| 138 | * XLR/XLS supports upto 8 devices on its FLASH interface. The value in | ||
| 139 | * FLASH_BAR (on the MEM/IO bridge) gives the base for mapping all the | ||
| 140 | * flash devices. | ||
| 141 | * Under this, each flash device has an offset and size given by the | ||
| 142 | * CSBASE_ADDR and CSBASE_MASK registers for the device. | ||
| 143 | * | ||
| 144 | * The CSBASE_ registers are expected to be setup by the bootloader. | ||
| 145 | */ | ||
| 146 | static void setup_flash_resource(uint64_t flash_mmio, | ||
| 147 | uint64_t flash_map_base, int cs, struct resource *res) | ||
| 148 | { | ||
| 149 | u32 base, mask; | ||
| 150 | |||
| 151 | base = nlm_read_reg(flash_mmio, FLASH_CSBASE_ADDR(cs)); | ||
| 152 | mask = nlm_read_reg(flash_mmio, FLASH_CSADDR_MASK(cs)); | ||
| 153 | |||
| 154 | res->start = flash_map_base + ((unsigned long)base << 16); | ||
| 155 | res->end = res->start + (mask + 1) * 64 * 1024; | ||
| 156 | } | ||
| 157 | |||
| 158 | static int __init xlr_flash_init(void) | ||
| 159 | { | ||
| 160 | uint64_t gpio_mmio, flash_mmio, flash_map_base; | ||
| 161 | u32 gpio_resetcfg, flash_bar; | ||
| 162 | int cs, boot_nand, boot_nor; | ||
| 163 | |||
| 164 | /* Flash address bits 39:24 is in bridge flash BAR */ | ||
| 165 | flash_bar = nlm_read_reg(nlm_io_base, BRIDGE_FLASH_BAR); | ||
| 166 | flash_map_base = (flash_bar & 0xffff0000) << 8; | ||
| 167 | |||
| 168 | gpio_mmio = nlm_mmio_base(NETLOGIC_IO_GPIO_OFFSET); | ||
| 169 | flash_mmio = nlm_mmio_base(NETLOGIC_IO_FLASH_OFFSET); | ||
| 170 | |||
| 171 | /* Get the chip reset config */ | ||
| 172 | gpio_resetcfg = nlm_read_reg(gpio_mmio, GPIO_PWRON_RESET_CFG_REG); | ||
| 173 | |||
| 174 | /* Check for boot flash type */ | ||
| 175 | boot_nor = boot_nand = 0; | ||
| 176 | if (nlm_chip_is_xls()) { | ||
| 177 | /* On XLS, check boot from NAND bit (GPIO reset reg bit 16) */ | ||
| 178 | if (gpio_resetcfg & (1 << 16)) | ||
| 179 | boot_nand = 1; | ||
| 180 | |||
| 181 | /* check boot from PCMCIA, (GPIO reset reg bit 15 */ | ||
| 182 | if ((gpio_resetcfg & (1 << 15)) == 0) | ||
| 183 | boot_nor = 1; /* not set, booted from NOR */ | ||
| 184 | } else { /* XLR */ | ||
| 185 | /* check boot from PCMCIA (bit 16 in GPIO reset on XLR) */ | ||
| 186 | if ((gpio_resetcfg & (1 << 16)) == 0) | ||
| 187 | boot_nor = 1; /* not set, booted from NOR */ | ||
| 188 | } | ||
| 189 | |||
| 190 | /* boot flash at chip select 0 */ | ||
| 191 | cs = 0; | ||
| 192 | |||
| 193 | if (boot_nand) { | ||
| 194 | nand_priv.cs = cs; | ||
| 195 | nand_priv.flash_mmio = flash_mmio; | ||
| 196 | setup_flash_resource(flash_mmio, flash_map_base, cs, | ||
| 197 | xlr_nand_res); | ||
| 198 | |||
| 199 | /* Initialize NAND flash at CS 0 */ | ||
| 200 | nlm_write_reg(flash_mmio, FLASH_CSDEV_PARM(cs), | ||
| 201 | FLASH_NAND_CSDEV_PARAM); | ||
| 202 | nlm_write_reg(flash_mmio, FLASH_CSTIME_PARMA(cs), | ||
| 203 | FLASH_NAND_CSTIME_PARAMA); | ||
| 204 | nlm_write_reg(flash_mmio, FLASH_CSTIME_PARMB(cs), | ||
| 205 | FLASH_NAND_CSTIME_PARAMB); | ||
| 206 | |||
| 207 | pr_info("ChipSelect %d: NAND Flash %pR\n", cs, xlr_nand_res); | ||
| 208 | return platform_device_register(&xlr_nand_dev); | ||
| 209 | } | ||
| 210 | |||
| 211 | if (boot_nor) { | ||
| 212 | setup_flash_resource(flash_mmio, flash_map_base, cs, | ||
| 213 | xlr_nor_res); | ||
| 214 | pr_info("ChipSelect %d: NOR Flash %pR\n", cs, xlr_nor_res); | ||
| 215 | return platform_device_register(&xlr_nor_dev); | ||
| 216 | } | ||
| 217 | return 0; | ||
| 218 | } | ||
| 219 | |||
| 220 | arch_initcall(xlr_flash_init); | ||
diff --git a/arch/mips/netlogic/xlr/platform.c b/arch/mips/netlogic/xlr/platform.c index eab64b45dffd..71b44d82621d 100644 --- a/arch/mips/netlogic/xlr/platform.c +++ b/arch/mips/netlogic/xlr/platform.c | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include <linux/resource.h> | 14 | #include <linux/resource.h> |
| 15 | #include <linux/serial_8250.h> | 15 | #include <linux/serial_8250.h> |
| 16 | #include <linux/serial_reg.h> | 16 | #include <linux/serial_reg.h> |
| 17 | #include <linux/i2c.h> | ||
| 17 | 18 | ||
| 18 | #include <asm/netlogic/haldefs.h> | 19 | #include <asm/netlogic/haldefs.h> |
| 19 | #include <asm/netlogic/xlr/iomap.h> | 20 | #include <asm/netlogic/xlr/iomap.h> |
| @@ -97,3 +98,142 @@ static int __init nlm_uart_init(void) | |||
| 97 | } | 98 | } |
| 98 | 99 | ||
| 99 | arch_initcall(nlm_uart_init); | 100 | arch_initcall(nlm_uart_init); |
| 101 | |||
| 102 | #ifdef CONFIG_USB | ||
| 103 | /* Platform USB devices, only on XLS chips */ | ||
| 104 | static u64 xls_usb_dmamask = ~(u32)0; | ||
| 105 | #define USB_PLATFORM_DEV(n, i, irq) \ | ||
| 106 | { \ | ||
| 107 | .name = n, \ | ||
| 108 | .id = i, \ | ||
| 109 | .num_resources = 2, \ | ||
| 110 | .dev = { \ | ||
| 111 | .dma_mask = &xls_usb_dmamask, \ | ||
| 112 | .coherent_dma_mask = 0xffffffff, \ | ||
| 113 | }, \ | ||
| 114 | .resource = (struct resource[]) { \ | ||
| 115 | { \ | ||
| 116 | .flags = IORESOURCE_MEM, \ | ||
| 117 | }, \ | ||
| 118 | { \ | ||
| 119 | .start = irq, \ | ||
| 120 | .end = irq, \ | ||
| 121 | .flags = IORESOURCE_IRQ, \ | ||
| 122 | }, \ | ||
| 123 | }, \ | ||
| 124 | } | ||
| 125 | |||
| 126 | static struct platform_device xls_usb_ehci_device = | ||
| 127 | USB_PLATFORM_DEV("ehci-xls", 0, PIC_USB_IRQ); | ||
| 128 | static struct platform_device xls_usb_ohci_device_0 = | ||
| 129 | USB_PLATFORM_DEV("ohci-xls-0", 1, PIC_USB_IRQ); | ||
| 130 | static struct platform_device xls_usb_ohci_device_1 = | ||
| 131 | USB_PLATFORM_DEV("ohci-xls-1", 2, PIC_USB_IRQ); | ||
| 132 | |||
| 133 | static struct platform_device *xls_platform_devices[] = { | ||
| 134 | &xls_usb_ehci_device, | ||
| 135 | &xls_usb_ohci_device_0, | ||
| 136 | &xls_usb_ohci_device_1, | ||
| 137 | }; | ||
| 138 | |||
| 139 | int xls_platform_usb_init(void) | ||
| 140 | { | ||
| 141 | uint64_t usb_mmio, gpio_mmio; | ||
| 142 | unsigned long memres; | ||
| 143 | uint32_t val; | ||
| 144 | |||
| 145 | if (!nlm_chip_is_xls()) | ||
| 146 | return 0; | ||
| 147 | |||
| 148 | gpio_mmio = nlm_mmio_base(NETLOGIC_IO_GPIO_OFFSET); | ||
| 149 | usb_mmio = nlm_mmio_base(NETLOGIC_IO_USB_1_OFFSET); | ||
| 150 | |||
| 151 | /* Clear Rogue Phy INTs */ | ||
| 152 | nlm_write_reg(usb_mmio, 49, 0x10000000); | ||
| 153 | /* Enable all interrupts */ | ||
| 154 | nlm_write_reg(usb_mmio, 50, 0x1f000000); | ||
| 155 | |||
| 156 | /* Enable ports */ | ||
| 157 | nlm_write_reg(usb_mmio, 1, 0x07000500); | ||
| 158 | |||
| 159 | val = nlm_read_reg(gpio_mmio, 21); | ||
| 160 | if (((val >> 22) & 0x01) == 0) { | ||
| 161 | pr_info("Detected USB Device mode - Not supported!\n"); | ||
| 162 | nlm_write_reg(usb_mmio, 0, 0x01000000); | ||
| 163 | return 0; | ||
| 164 | } | ||
| 165 | |||
| 166 | pr_info("Detected USB Host mode - Adding XLS USB devices.\n"); | ||
| 167 | /* Clear reset, host mode */ | ||
| 168 | nlm_write_reg(usb_mmio, 0, 0x02000000); | ||
| 169 | |||
| 170 | /* Memory resource for various XLS usb ports */ | ||
| 171 | usb_mmio = nlm_mmio_base(NETLOGIC_IO_USB_0_OFFSET); | ||
| 172 | memres = CPHYSADDR((unsigned long)usb_mmio); | ||
| 173 | xls_usb_ehci_device.resource[0].start = memres; | ||
| 174 | xls_usb_ehci_device.resource[0].end = memres + 0x400 - 1; | ||
| 175 | |||
| 176 | memres += 0x400; | ||
| 177 | xls_usb_ohci_device_0.resource[0].start = memres; | ||
| 178 | xls_usb_ohci_device_0.resource[0].end = memres + 0x400 - 1; | ||
| 179 | |||
| 180 | memres += 0x400; | ||
| 181 | xls_usb_ohci_device_1.resource[0].start = memres; | ||
| 182 | xls_usb_ohci_device_1.resource[0].end = memres + 0x400 - 1; | ||
| 183 | |||
| 184 | return platform_add_devices(xls_platform_devices, | ||
| 185 | ARRAY_SIZE(xls_platform_devices)); | ||
| 186 | } | ||
| 187 | |||
| 188 | arch_initcall(xls_platform_usb_init); | ||
| 189 | #endif | ||
| 190 | |||
| 191 | #ifdef CONFIG_I2C | ||
| 192 | static struct i2c_board_info nlm_i2c_board_info1[] __initdata = { | ||
| 193 | /* All XLR boards have this RTC and Max6657 Temp Chip */ | ||
| 194 | [0] = { | ||
| 195 | .type = "ds1374", | ||
| 196 | .addr = 0x68 | ||
| 197 | }, | ||
| 198 | [1] = { | ||
| 199 | .type = "lm90", | ||
| 200 | .addr = 0x4c | ||
| 201 | }, | ||
| 202 | }; | ||
| 203 | |||
| 204 | static struct resource i2c_resources[] = { | ||
| 205 | [0] = { | ||
| 206 | .start = 0, /* filled at init */ | ||
| 207 | .end = 0, | ||
| 208 | .flags = IORESOURCE_MEM, | ||
| 209 | }, | ||
| 210 | }; | ||
| 211 | |||
| 212 | static struct platform_device nlm_xlr_i2c_1 = { | ||
| 213 | .name = "xlr-i2cbus", | ||
| 214 | .id = 1, | ||
| 215 | .num_resources = 1, | ||
| 216 | .resource = i2c_resources, | ||
| 217 | }; | ||
| 218 | |||
| 219 | static int __init nlm_i2c_init(void) | ||
| 220 | { | ||
| 221 | int err = 0; | ||
| 222 | unsigned int offset; | ||
| 223 | |||
| 224 | /* I2C bus 0 does not have any useful devices, configure only bus 1 */ | ||
| 225 | offset = NETLOGIC_IO_I2C_1_OFFSET; | ||
| 226 | nlm_xlr_i2c_1.resource[0].start = CPHYSADDR(nlm_mmio_base(offset)); | ||
| 227 | nlm_xlr_i2c_1.resource[0].end = nlm_xlr_i2c_1.resource[0].start + 0xfff; | ||
| 228 | |||
| 229 | platform_device_register(&nlm_xlr_i2c_1); | ||
| 230 | |||
| 231 | err = i2c_register_board_info(1, nlm_i2c_board_info1, | ||
| 232 | ARRAY_SIZE(nlm_i2c_board_info1)); | ||
| 233 | if (err < 0) | ||
| 234 | pr_err("nlm-i2c: cannot register board I2C devices\n"); | ||
| 235 | return err; | ||
| 236 | } | ||
| 237 | |||
| 238 | arch_initcall(nlm_i2c_init); | ||
| 239 | #endif | ||
diff --git a/arch/mips/netlogic/xlr/setup.c b/arch/mips/netlogic/xlr/setup.c index c9d066dedc4e..81b1d311834f 100644 --- a/arch/mips/netlogic/xlr/setup.c +++ b/arch/mips/netlogic/xlr/setup.c | |||
| @@ -85,7 +85,7 @@ static void nlm_linux_exit(void) | |||
| 85 | 85 | ||
| 86 | gpiobase = nlm_mmio_base(NETLOGIC_IO_GPIO_OFFSET); | 86 | gpiobase = nlm_mmio_base(NETLOGIC_IO_GPIO_OFFSET); |
| 87 | /* trigger a chip reset by writing 1 to GPIO_SWRESET_REG */ | 87 | /* trigger a chip reset by writing 1 to GPIO_SWRESET_REG */ |
| 88 | nlm_write_reg(gpiobase, NETLOGIC_GPIO_SWRESET_REG, 1); | 88 | nlm_write_reg(gpiobase, GPIO_SWRESET_REG, 1); |
| 89 | for ( ; ; ) | 89 | for ( ; ; ) |
| 90 | cpu_wait(); | 90 | cpu_wait(); |
| 91 | } | 91 | } |
diff --git a/arch/mips/oprofile/common.c b/arch/mips/oprofile/common.c index b6e378211a2c..f80480a5a032 100644 --- a/arch/mips/oprofile/common.c +++ b/arch/mips/oprofile/common.c | |||
| @@ -85,6 +85,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) | |||
| 85 | case CPU_34K: | 85 | case CPU_34K: |
| 86 | case CPU_1004K: | 86 | case CPU_1004K: |
| 87 | case CPU_74K: | 87 | case CPU_74K: |
| 88 | case CPU_LOONGSON1: | ||
| 88 | case CPU_SB1: | 89 | case CPU_SB1: |
| 89 | case CPU_SB1A: | 90 | case CPU_SB1A: |
| 90 | case CPU_R10000: | 91 | case CPU_R10000: |
diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c index 4d80a856048d..28ea1a4cc576 100644 --- a/arch/mips/oprofile/op_model_mipsxx.c +++ b/arch/mips/oprofile/op_model_mipsxx.c | |||
| @@ -339,12 +339,6 @@ static int __init mipsxx_init(void) | |||
| 339 | break; | 339 | break; |
| 340 | 340 | ||
| 341 | case CPU_1004K: | 341 | case CPU_1004K: |
| 342 | #if 0 | ||
| 343 | /* FIXME: report as 34K for now */ | ||
| 344 | op_model_mipsxx_ops.cpu_type = "mips/1004K"; | ||
| 345 | break; | ||
| 346 | #endif | ||
| 347 | |||
| 348 | case CPU_34K: | 342 | case CPU_34K: |
| 349 | op_model_mipsxx_ops.cpu_type = "mips/34K"; | 343 | op_model_mipsxx_ops.cpu_type = "mips/34K"; |
| 350 | break; | 344 | break; |
| @@ -374,6 +368,10 @@ static int __init mipsxx_init(void) | |||
| 374 | op_model_mipsxx_ops.cpu_type = "mips/sb1"; | 368 | op_model_mipsxx_ops.cpu_type = "mips/sb1"; |
| 375 | break; | 369 | break; |
| 376 | 370 | ||
| 371 | case CPU_LOONGSON1: | ||
| 372 | op_model_mipsxx_ops.cpu_type = "mips/loongson1"; | ||
| 373 | break; | ||
| 374 | |||
| 377 | default: | 375 | default: |
| 378 | printk(KERN_ERR "Profiling unsupported for this CPU\n"); | 376 | printk(KERN_ERR "Profiling unsupported for this CPU\n"); |
| 379 | 377 | ||
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index c703f43a9914..e13a71cbc3c7 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile | |||
| @@ -59,6 +59,7 @@ obj-$(CONFIG_WR_PPMC) += fixup-wrppmc.o | |||
| 59 | obj-$(CONFIG_MIKROTIK_RB532) += pci-rc32434.o ops-rc32434.o fixup-rc32434.o | 59 | obj-$(CONFIG_MIKROTIK_RB532) += pci-rc32434.o ops-rc32434.o fixup-rc32434.o |
| 60 | obj-$(CONFIG_CPU_CAVIUM_OCTEON) += pci-octeon.o pcie-octeon.o | 60 | obj-$(CONFIG_CPU_CAVIUM_OCTEON) += pci-octeon.o pcie-octeon.o |
| 61 | obj-$(CONFIG_CPU_XLR) += pci-xlr.o | 61 | obj-$(CONFIG_CPU_XLR) += pci-xlr.o |
| 62 | obj-$(CONFIG_CPU_XLP) += pci-xlp.o | ||
| 62 | 63 | ||
| 63 | ifdef CONFIG_PCI_MSI | 64 | ifdef CONFIG_PCI_MSI |
| 64 | obj-$(CONFIG_CPU_CAVIUM_OCTEON) += msi-octeon.o | 65 | obj-$(CONFIG_CPU_CAVIUM_OCTEON) += msi-octeon.o |
diff --git a/arch/mips/pci/fixup-cobalt.c b/arch/mips/pci/fixup-cobalt.c index 9553b14002dd..3e7ce65d776c 100644 --- a/arch/mips/pci/fixup-cobalt.c +++ b/arch/mips/pci/fixup-cobalt.c | |||
| @@ -37,7 +37,7 @@ | |||
| 37 | #define VIA_COBALT_BRD_ID_REG 0x94 | 37 | #define VIA_COBALT_BRD_ID_REG 0x94 |
| 38 | #define VIA_COBALT_BRD_REG_to_ID(reg) ((unsigned char)(reg) >> 4) | 38 | #define VIA_COBALT_BRD_REG_to_ID(reg) ((unsigned char)(reg) >> 4) |
| 39 | 39 | ||
| 40 | static void qube_raq_galileo_early_fixup(struct pci_dev *dev) | 40 | static void __devinit qube_raq_galileo_early_fixup(struct pci_dev *dev) |
| 41 | { | 41 | { |
| 42 | if (dev->devfn == PCI_DEVFN(0, 0) && | 42 | if (dev->devfn == PCI_DEVFN(0, 0) && |
| 43 | (dev->class >> 8) == PCI_CLASS_MEMORY_OTHER) { | 43 | (dev->class >> 8) == PCI_CLASS_MEMORY_OTHER) { |
| @@ -51,7 +51,7 @@ static void qube_raq_galileo_early_fixup(struct pci_dev *dev) | |||
| 51 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_GT64111, | 51 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_GT64111, |
| 52 | qube_raq_galileo_early_fixup); | 52 | qube_raq_galileo_early_fixup); |
| 53 | 53 | ||
| 54 | static void qube_raq_via_bmIDE_fixup(struct pci_dev *dev) | 54 | static void __devinit qube_raq_via_bmIDE_fixup(struct pci_dev *dev) |
| 55 | { | 55 | { |
| 56 | unsigned short cfgword; | 56 | unsigned short cfgword; |
| 57 | unsigned char lt; | 57 | unsigned char lt; |
| @@ -74,7 +74,7 @@ static void qube_raq_via_bmIDE_fixup(struct pci_dev *dev) | |||
| 74 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, | 74 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, |
| 75 | qube_raq_via_bmIDE_fixup); | 75 | qube_raq_via_bmIDE_fixup); |
| 76 | 76 | ||
| 77 | static void qube_raq_galileo_fixup(struct pci_dev *dev) | 77 | static void __devinit qube_raq_galileo_fixup(struct pci_dev *dev) |
| 78 | { | 78 | { |
| 79 | if (dev->devfn != PCI_DEVFN(0, 0)) | 79 | if (dev->devfn != PCI_DEVFN(0, 0)) |
| 80 | return; | 80 | return; |
| @@ -129,7 +129,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_GT64111, | |||
| 129 | 129 | ||
| 130 | int cobalt_board_id; | 130 | int cobalt_board_id; |
| 131 | 131 | ||
| 132 | static void qube_raq_via_board_id_fixup(struct pci_dev *dev) | 132 | static void __devinit qube_raq_via_board_id_fixup(struct pci_dev *dev) |
| 133 | { | 133 | { |
| 134 | u8 id; | 134 | u8 id; |
| 135 | int retval; | 135 | int retval; |
diff --git a/arch/mips/pci/fixup-malta.c b/arch/mips/pci/fixup-malta.c index 70073c98ed32..819622f93e9c 100644 --- a/arch/mips/pci/fixup-malta.c +++ b/arch/mips/pci/fixup-malta.c | |||
| @@ -101,3 +101,17 @@ static void __devinit malta_piix_func1_fixup(struct pci_dev *pdev) | |||
| 101 | 101 | ||
| 102 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB, | 102 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB, |
| 103 | malta_piix_func1_fixup); | 103 | malta_piix_func1_fixup); |
| 104 | |||
| 105 | /* Enable PCI 2.1 compatibility in PIIX4 */ | ||
| 106 | static void __devinit quirk_dlcsetup(struct pci_dev *dev) | ||
| 107 | { | ||
| 108 | u8 odlc, ndlc; | ||
| 109 | |||
| 110 | (void) pci_read_config_byte(dev, 0x82, &odlc); | ||
| 111 | /* Enable passive releases and delayed transaction */ | ||
| 112 | ndlc = odlc | 7; | ||
| 113 | (void) pci_write_config_byte(dev, 0x82, ndlc); | ||
| 114 | } | ||
| 115 | |||
| 116 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0, | ||
| 117 | quirk_dlcsetup); | ||
diff --git a/arch/mips/pci/fixup-rc32434.c b/arch/mips/pci/fixup-rc32434.c index 3d86823d03a0..76bb1be99d43 100644 --- a/arch/mips/pci/fixup-rc32434.c +++ b/arch/mips/pci/fixup-rc32434.c | |||
| @@ -47,7 +47,7 @@ int __devinit pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |||
| 47 | return irq + GROUP4_IRQ_BASE + 4; | 47 | return irq + GROUP4_IRQ_BASE + 4; |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | static void rc32434_pci_early_fixup(struct pci_dev *dev) | 50 | static void __devinit rc32434_pci_early_fixup(struct pci_dev *dev) |
| 51 | { | 51 | { |
| 52 | if (PCI_SLOT(dev->devfn) == 6 && dev->bus->number == 0) { | 52 | if (PCI_SLOT(dev->devfn) == 6 && dev->bus->number == 0) { |
| 53 | /* disable prefetched memory range */ | 53 | /* disable prefetched memory range */ |
diff --git a/arch/mips/pci/ops-bcm63xx.c b/arch/mips/pci/ops-bcm63xx.c index 822ae179bc56..65c7bd100486 100644 --- a/arch/mips/pci/ops-bcm63xx.c +++ b/arch/mips/pci/ops-bcm63xx.c | |||
| @@ -411,7 +411,7 @@ struct pci_ops bcm63xx_cb_ops = { | |||
| 411 | * only one IO window, so it cannot be shared by PCI and cardbus, use | 411 | * only one IO window, so it cannot be shared by PCI and cardbus, use |
| 412 | * fixup to choose and detect unhandled configuration | 412 | * fixup to choose and detect unhandled configuration |
| 413 | */ | 413 | */ |
| 414 | static void bcm63xx_fixup(struct pci_dev *dev) | 414 | static void __devinit bcm63xx_fixup(struct pci_dev *dev) |
| 415 | { | 415 | { |
| 416 | static int io_window = -1; | 416 | static int io_window = -1; |
| 417 | int i, found, new_io_window; | 417 | int i, found, new_io_window; |
| @@ -465,3 +465,64 @@ static void bcm63xx_fixup(struct pci_dev *dev) | |||
| 465 | 465 | ||
| 466 | DECLARE_PCI_FIXUP_ENABLE(PCI_ANY_ID, PCI_ANY_ID, bcm63xx_fixup); | 466 | DECLARE_PCI_FIXUP_ENABLE(PCI_ANY_ID, PCI_ANY_ID, bcm63xx_fixup); |
| 467 | #endif | 467 | #endif |
| 468 | |||
| 469 | static int bcm63xx_pcie_can_access(struct pci_bus *bus, int devfn) | ||
| 470 | { | ||
| 471 | switch (bus->number) { | ||
| 472 | case PCIE_BUS_BRIDGE: | ||
| 473 | return (PCI_SLOT(devfn) == 0); | ||
| 474 | case PCIE_BUS_DEVICE: | ||
| 475 | if (PCI_SLOT(devfn) == 0) | ||
| 476 | return bcm_pcie_readl(PCIE_DLSTATUS_REG) | ||
| 477 | & DLSTATUS_PHYLINKUP; | ||
| 478 | default: | ||
| 479 | return false; | ||
| 480 | } | ||
| 481 | } | ||
| 482 | |||
| 483 | static int bcm63xx_pcie_read(struct pci_bus *bus, unsigned int devfn, | ||
| 484 | int where, int size, u32 *val) | ||
| 485 | { | ||
| 486 | u32 data; | ||
| 487 | u32 reg = where & ~3; | ||
| 488 | |||
| 489 | if (!bcm63xx_pcie_can_access(bus, devfn)) | ||
| 490 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 491 | |||
| 492 | if (bus->number == PCIE_BUS_DEVICE) | ||
| 493 | reg += PCIE_DEVICE_OFFSET; | ||
| 494 | |||
| 495 | data = bcm_pcie_readl(reg); | ||
| 496 | |||
| 497 | *val = postprocess_read(data, where, size); | ||
| 498 | |||
| 499 | return PCIBIOS_SUCCESSFUL; | ||
| 500 | |||
| 501 | } | ||
| 502 | |||
| 503 | static int bcm63xx_pcie_write(struct pci_bus *bus, unsigned int devfn, | ||
| 504 | int where, int size, u32 val) | ||
| 505 | { | ||
| 506 | u32 data; | ||
| 507 | u32 reg = where & ~3; | ||
| 508 | |||
| 509 | if (!bcm63xx_pcie_can_access(bus, devfn)) | ||
| 510 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 511 | |||
| 512 | if (bus->number == PCIE_BUS_DEVICE) | ||
| 513 | reg += PCIE_DEVICE_OFFSET; | ||
| 514 | |||
| 515 | |||
| 516 | data = bcm_pcie_readl(reg); | ||
| 517 | |||
| 518 | data = preprocess_write(data, val, where, size); | ||
| 519 | bcm_pcie_writel(data, reg); | ||
| 520 | |||
| 521 | return PCIBIOS_SUCCESSFUL; | ||
| 522 | } | ||
| 523 | |||
| 524 | |||
| 525 | struct pci_ops bcm63xx_pcie_ops = { | ||
| 526 | .read = bcm63xx_pcie_read, | ||
| 527 | .write = bcm63xx_pcie_write | ||
| 528 | }; | ||
diff --git a/arch/mips/pci/pci-bcm63xx.c b/arch/mips/pci/pci-bcm63xx.c index 39eb7c417e2f..8a48139d219c 100644 --- a/arch/mips/pci/pci-bcm63xx.c +++ b/arch/mips/pci/pci-bcm63xx.c | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | #include <linux/pci.h> | 10 | #include <linux/pci.h> |
| 11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
| 12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
| 13 | #include <linux/delay.h> | ||
| 13 | #include <asm/bootinfo.h> | 14 | #include <asm/bootinfo.h> |
| 14 | 15 | ||
| 15 | #include "pci-bcm63xx.h" | 16 | #include "pci-bcm63xx.h" |
| @@ -71,6 +72,26 @@ struct pci_controller bcm63xx_cb_controller = { | |||
| 71 | }; | 72 | }; |
| 72 | #endif | 73 | #endif |
| 73 | 74 | ||
| 75 | static struct resource bcm_pcie_mem_resource = { | ||
| 76 | .name = "bcm63xx PCIe memory space", | ||
| 77 | .start = BCM_PCIE_MEM_BASE_PA, | ||
| 78 | .end = BCM_PCIE_MEM_END_PA, | ||
| 79 | .flags = IORESOURCE_MEM, | ||
| 80 | }; | ||
| 81 | |||
| 82 | static struct resource bcm_pcie_io_resource = { | ||
| 83 | .name = "bcm63xx PCIe IO space", | ||
| 84 | .start = 0, | ||
| 85 | .end = 0, | ||
| 86 | .flags = 0, | ||
| 87 | }; | ||
| 88 | |||
| 89 | struct pci_controller bcm63xx_pcie_controller = { | ||
| 90 | .pci_ops = &bcm63xx_pcie_ops, | ||
| 91 | .io_resource = &bcm_pcie_io_resource, | ||
| 92 | .mem_resource = &bcm_pcie_mem_resource, | ||
| 93 | }; | ||
| 94 | |||
| 74 | static u32 bcm63xx_int_cfg_readl(u32 reg) | 95 | static u32 bcm63xx_int_cfg_readl(u32 reg) |
| 75 | { | 96 | { |
| 76 | u32 tmp; | 97 | u32 tmp; |
| @@ -94,17 +115,99 @@ static void bcm63xx_int_cfg_writel(u32 val, u32 reg) | |||
| 94 | 115 | ||
| 95 | void __iomem *pci_iospace_start; | 116 | void __iomem *pci_iospace_start; |
| 96 | 117 | ||
| 97 | static int __init bcm63xx_pci_init(void) | 118 | static void __init bcm63xx_reset_pcie(void) |
| 98 | { | 119 | { |
| 99 | unsigned int mem_size; | ||
| 100 | u32 val; | 120 | u32 val; |
| 101 | 121 | ||
| 102 | if (!BCMCPU_IS_6348() && !BCMCPU_IS_6358() && !BCMCPU_IS_6368()) | 122 | /* enable clock */ |
| 103 | return -ENODEV; | 123 | val = bcm_perf_readl(PERF_CKCTL_REG); |
| 124 | val |= CKCTL_6328_PCIE_EN; | ||
| 125 | bcm_perf_writel(val, PERF_CKCTL_REG); | ||
| 126 | |||
| 127 | /* enable SERDES */ | ||
| 128 | val = bcm_misc_readl(MISC_SERDES_CTRL_REG); | ||
| 129 | val |= SERDES_PCIE_EN | SERDES_PCIE_EXD_EN; | ||
| 130 | bcm_misc_writel(val, MISC_SERDES_CTRL_REG); | ||
| 131 | |||
| 132 | /* reset the PCIe core */ | ||
| 133 | val = bcm_perf_readl(PERF_SOFTRESET_6328_REG); | ||
| 134 | |||
| 135 | val &= ~SOFTRESET_6328_PCIE_MASK; | ||
| 136 | val &= ~SOFTRESET_6328_PCIE_CORE_MASK; | ||
| 137 | val &= ~SOFTRESET_6328_PCIE_HARD_MASK; | ||
| 138 | val &= ~SOFTRESET_6328_PCIE_EXT_MASK; | ||
| 139 | bcm_perf_writel(val, PERF_SOFTRESET_6328_REG); | ||
| 140 | mdelay(10); | ||
| 141 | |||
| 142 | val |= SOFTRESET_6328_PCIE_MASK; | ||
| 143 | val |= SOFTRESET_6328_PCIE_CORE_MASK; | ||
| 144 | val |= SOFTRESET_6328_PCIE_HARD_MASK; | ||
| 145 | bcm_perf_writel(val, PERF_SOFTRESET_6328_REG); | ||
| 146 | mdelay(10); | ||
| 147 | |||
| 148 | val |= SOFTRESET_6328_PCIE_EXT_MASK; | ||
| 149 | bcm_perf_writel(val, PERF_SOFTRESET_6328_REG); | ||
| 150 | mdelay(200); | ||
| 151 | } | ||
| 104 | 152 | ||
| 105 | if (!bcm63xx_pci_enabled) | 153 | static int __init bcm63xx_register_pcie(void) |
| 106 | return -ENODEV; | 154 | { |
| 155 | u32 val; | ||
| 107 | 156 | ||
| 157 | bcm63xx_reset_pcie(); | ||
| 158 | |||
| 159 | /* configure the PCIe bridge */ | ||
| 160 | val = bcm_pcie_readl(PCIE_BRIDGE_OPT1_REG); | ||
| 161 | val |= OPT1_RD_BE_OPT_EN; | ||
| 162 | val |= OPT1_RD_REPLY_BE_FIX_EN; | ||
| 163 | val |= OPT1_PCIE_BRIDGE_HOLE_DET_EN; | ||
| 164 | val |= OPT1_L1_INT_STATUS_MASK_POL; | ||
| 165 | bcm_pcie_writel(val, PCIE_BRIDGE_OPT1_REG); | ||
| 166 | |||
| 167 | /* setup the interrupts */ | ||
| 168 | val = bcm_pcie_readl(PCIE_BRIDGE_RC_INT_MASK_REG); | ||
| 169 | val |= PCIE_RC_INT_A | PCIE_RC_INT_B | PCIE_RC_INT_C | PCIE_RC_INT_D; | ||
| 170 | bcm_pcie_writel(val, PCIE_BRIDGE_RC_INT_MASK_REG); | ||
| 171 | |||
| 172 | val = bcm_pcie_readl(PCIE_BRIDGE_OPT2_REG); | ||
| 173 | /* enable credit checking and error checking */ | ||
| 174 | val |= OPT2_TX_CREDIT_CHK_EN; | ||
| 175 | val |= OPT2_UBUS_UR_DECODE_DIS; | ||
| 176 | |||
| 177 | /* set device bus/func for the pcie device */ | ||
| 178 | val |= (PCIE_BUS_DEVICE << OPT2_CFG_TYPE1_BUS_NO_SHIFT); | ||
| 179 | val |= OPT2_CFG_TYPE1_BD_SEL; | ||
| 180 | bcm_pcie_writel(val, PCIE_BRIDGE_OPT2_REG); | ||
| 181 | |||
| 182 | /* setup class code as bridge */ | ||
| 183 | val = bcm_pcie_readl(PCIE_IDVAL3_REG); | ||
| 184 | val &= ~IDVAL3_CLASS_CODE_MASK; | ||
| 185 | val |= (PCI_CLASS_BRIDGE_PCI << IDVAL3_SUBCLASS_SHIFT); | ||
| 186 | bcm_pcie_writel(val, PCIE_IDVAL3_REG); | ||
| 187 | |||
| 188 | /* disable bar1 size */ | ||
| 189 | val = bcm_pcie_readl(PCIE_CONFIG2_REG); | ||
| 190 | val &= ~CONFIG2_BAR1_SIZE_MASK; | ||
| 191 | bcm_pcie_writel(val, PCIE_CONFIG2_REG); | ||
| 192 | |||
| 193 | /* set bar0 to little endian */ | ||
| 194 | val = (BCM_PCIE_MEM_BASE_PA >> 20) << BASEMASK_BASE_SHIFT; | ||
| 195 | val |= (BCM_PCIE_MEM_BASE_PA >> 20) << BASEMASK_MASK_SHIFT; | ||
| 196 | val |= BASEMASK_REMAP_EN; | ||
| 197 | bcm_pcie_writel(val, PCIE_BRIDGE_BAR0_BASEMASK_REG); | ||
| 198 | |||
| 199 | val = (BCM_PCIE_MEM_BASE_PA >> 20) << REBASE_ADDR_BASE_SHIFT; | ||
| 200 | bcm_pcie_writel(val, PCIE_BRIDGE_BAR0_REBASE_ADDR_REG); | ||
| 201 | |||
| 202 | register_pci_controller(&bcm63xx_pcie_controller); | ||
| 203 | |||
| 204 | return 0; | ||
| 205 | } | ||
| 206 | |||
| 207 | static int __init bcm63xx_register_pci(void) | ||
| 208 | { | ||
| 209 | unsigned int mem_size; | ||
| 210 | u32 val; | ||
| 108 | /* | 211 | /* |
| 109 | * configuration access are done through IO space, remap 4 | 212 | * configuration access are done through IO space, remap 4 |
| 110 | * first bytes to access it from CPU. | 213 | * first bytes to access it from CPU. |
| @@ -221,4 +324,22 @@ static int __init bcm63xx_pci_init(void) | |||
| 221 | return 0; | 324 | return 0; |
| 222 | } | 325 | } |
| 223 | 326 | ||
| 327 | |||
| 328 | static int __init bcm63xx_pci_init(void) | ||
| 329 | { | ||
| 330 | if (!bcm63xx_pci_enabled) | ||
| 331 | return -ENODEV; | ||
| 332 | |||
| 333 | switch (bcm63xx_get_cpu_id()) { | ||
| 334 | case BCM6328_CPU_ID: | ||
| 335 | return bcm63xx_register_pcie(); | ||
| 336 | case BCM6348_CPU_ID: | ||
| 337 | case BCM6358_CPU_ID: | ||
| 338 | case BCM6368_CPU_ID: | ||
| 339 | return bcm63xx_register_pci(); | ||
| 340 | default: | ||
| 341 | return -ENODEV; | ||
| 342 | } | ||
| 343 | } | ||
| 344 | |||
| 224 | arch_initcall(bcm63xx_pci_init); | 345 | arch_initcall(bcm63xx_pci_init); |
diff --git a/arch/mips/pci/pci-bcm63xx.h b/arch/mips/pci/pci-bcm63xx.h index a6e594ef3d6a..e6736d558ac7 100644 --- a/arch/mips/pci/pci-bcm63xx.h +++ b/arch/mips/pci/pci-bcm63xx.h | |||
| @@ -13,11 +13,16 @@ | |||
| 13 | */ | 13 | */ |
| 14 | #define CARDBUS_PCI_IDSEL 0x8 | 14 | #define CARDBUS_PCI_IDSEL 0x8 |
| 15 | 15 | ||
| 16 | |||
| 17 | #define PCIE_BUS_BRIDGE 0 | ||
| 18 | #define PCIE_BUS_DEVICE 1 | ||
| 19 | |||
| 16 | /* | 20 | /* |
| 17 | * defined in ops-bcm63xx.c | 21 | * defined in ops-bcm63xx.c |
| 18 | */ | 22 | */ |
| 19 | extern struct pci_ops bcm63xx_pci_ops; | 23 | extern struct pci_ops bcm63xx_pci_ops; |
| 20 | extern struct pci_ops bcm63xx_cb_ops; | 24 | extern struct pci_ops bcm63xx_cb_ops; |
| 25 | extern struct pci_ops bcm63xx_pcie_ops; | ||
| 21 | 26 | ||
| 22 | /* | 27 | /* |
| 23 | * defined in pci-bcm63xx.c | 28 | * defined in pci-bcm63xx.c |
diff --git a/arch/mips/pci/pci-xlp.c b/arch/mips/pci/pci-xlp.c new file mode 100644 index 000000000000..140557a20488 --- /dev/null +++ b/arch/mips/pci/pci-xlp.c | |||
| @@ -0,0 +1,248 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2003-2012 Broadcom Corporation | ||
| 3 | * All Rights Reserved | ||
| 4 | * | ||
| 5 | * This software is available to you under a choice of one of two | ||
| 6 | * licenses. You may choose to be licensed under the terms of the GNU | ||
| 7 | * General Public License (GPL) Version 2, available from the file | ||
| 8 | * COPYING in the main directory of this source tree, or the Broadcom | ||
| 9 | * license below: | ||
| 10 | * | ||
| 11 | * Redistribution and use in source and binary forms, with or without | ||
| 12 | * modification, are permitted provided that the following conditions | ||
| 13 | * are met: | ||
| 14 | * | ||
| 15 | * 1. Redistributions of source code must retain the above copyright | ||
| 16 | * notice, this list of conditions and the following disclaimer. | ||
| 17 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 18 | * notice, this list of conditions and the following disclaimer in | ||
| 19 | * the documentation and/or other materials provided with the | ||
| 20 | * distribution. | ||
| 21 | * | ||
| 22 | * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR | ||
| 23 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
| 24 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 25 | * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE | ||
| 26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
| 27 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
| 28 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
| 29 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
| 30 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE | ||
| 31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN | ||
| 32 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 33 | */ | ||
| 34 | |||
| 35 | #include <linux/types.h> | ||
| 36 | #include <linux/pci.h> | ||
| 37 | #include <linux/kernel.h> | ||
| 38 | #include <linux/init.h> | ||
| 39 | #include <linux/msi.h> | ||
| 40 | #include <linux/mm.h> | ||
| 41 | #include <linux/irq.h> | ||
| 42 | #include <linux/irqdesc.h> | ||
| 43 | #include <linux/console.h> | ||
| 44 | |||
| 45 | #include <asm/io.h> | ||
| 46 | |||
| 47 | #include <asm/netlogic/interrupt.h> | ||
| 48 | #include <asm/netlogic/haldefs.h> | ||
| 49 | |||
| 50 | #include <asm/netlogic/xlp-hal/iomap.h> | ||
| 51 | #include <asm/netlogic/xlp-hal/pic.h> | ||
| 52 | #include <asm/netlogic/xlp-hal/xlp.h> | ||
| 53 | #include <asm/netlogic/xlp-hal/pcibus.h> | ||
| 54 | #include <asm/netlogic/xlp-hal/bridge.h> | ||
| 55 | |||
| 56 | static void *pci_config_base; | ||
| 57 | |||
| 58 | #define pci_cfg_addr(bus, devfn, off) (((bus) << 20) | ((devfn) << 12) | (off)) | ||
| 59 | |||
| 60 | /* PCI ops */ | ||
| 61 | static inline u32 pci_cfg_read_32bit(struct pci_bus *bus, unsigned int devfn, | ||
| 62 | int where) | ||
| 63 | { | ||
| 64 | u32 data; | ||
| 65 | u32 *cfgaddr; | ||
| 66 | |||
| 67 | cfgaddr = (u32 *)(pci_config_base + | ||
| 68 | pci_cfg_addr(bus->number, devfn, where & ~3)); | ||
| 69 | data = *cfgaddr; | ||
| 70 | return data; | ||
| 71 | } | ||
| 72 | |||
| 73 | static inline void pci_cfg_write_32bit(struct pci_bus *bus, unsigned int devfn, | ||
| 74 | int where, u32 data) | ||
| 75 | { | ||
| 76 | u32 *cfgaddr; | ||
| 77 | |||
| 78 | cfgaddr = (u32 *)(pci_config_base + | ||
| 79 | pci_cfg_addr(bus->number, devfn, where & ~3)); | ||
| 80 | *cfgaddr = data; | ||
| 81 | } | ||
| 82 | |||
| 83 | static int nlm_pcibios_read(struct pci_bus *bus, unsigned int devfn, | ||
| 84 | int where, int size, u32 *val) | ||
| 85 | { | ||
| 86 | u32 data; | ||
| 87 | |||
| 88 | if ((size == 2) && (where & 1)) | ||
| 89 | return PCIBIOS_BAD_REGISTER_NUMBER; | ||
| 90 | else if ((size == 4) && (where & 3)) | ||
| 91 | return PCIBIOS_BAD_REGISTER_NUMBER; | ||
| 92 | |||
| 93 | data = pci_cfg_read_32bit(bus, devfn, where); | ||
| 94 | |||
| 95 | if (size == 1) | ||
| 96 | *val = (data >> ((where & 3) << 3)) & 0xff; | ||
| 97 | else if (size == 2) | ||
| 98 | *val = (data >> ((where & 3) << 3)) & 0xffff; | ||
| 99 | else | ||
| 100 | *val = data; | ||
| 101 | |||
| 102 | return PCIBIOS_SUCCESSFUL; | ||
| 103 | } | ||
| 104 | |||
| 105 | |||
| 106 | static int nlm_pcibios_write(struct pci_bus *bus, unsigned int devfn, | ||
| 107 | int where, int size, u32 val) | ||
| 108 | { | ||
| 109 | u32 data; | ||
| 110 | |||
| 111 | if ((size == 2) && (where & 1)) | ||
| 112 | return PCIBIOS_BAD_REGISTER_NUMBER; | ||
| 113 | else if ((size == 4) && (where & 3)) | ||
| 114 | return PCIBIOS_BAD_REGISTER_NUMBER; | ||
| 115 | |||
| 116 | data = pci_cfg_read_32bit(bus, devfn, where); | ||
| 117 | |||
| 118 | if (size == 1) | ||
| 119 | data = (data & ~(0xff << ((where & 3) << 3))) | | ||
| 120 | (val << ((where & 3) << 3)); | ||
| 121 | else if (size == 2) | ||
| 122 | data = (data & ~(0xffff << ((where & 3) << 3))) | | ||
| 123 | (val << ((where & 3) << 3)); | ||
| 124 | else | ||
| 125 | data = val; | ||
| 126 | |||
| 127 | pci_cfg_write_32bit(bus, devfn, where, data); | ||
| 128 | |||
| 129 | return PCIBIOS_SUCCESSFUL; | ||
| 130 | } | ||
| 131 | |||
| 132 | struct pci_ops nlm_pci_ops = { | ||
| 133 | .read = nlm_pcibios_read, | ||
| 134 | .write = nlm_pcibios_write | ||
| 135 | }; | ||
| 136 | |||
| 137 | static struct resource nlm_pci_mem_resource = { | ||
| 138 | .name = "XLP PCI MEM", | ||
| 139 | .start = 0xd0000000UL, /* 256MB PCI mem @ 0xd000_0000 */ | ||
| 140 | .end = 0xdfffffffUL, | ||
| 141 | .flags = IORESOURCE_MEM, | ||
| 142 | }; | ||
| 143 | |||
| 144 | static struct resource nlm_pci_io_resource = { | ||
| 145 | .name = "XLP IO MEM", | ||
| 146 | .start = 0x14000000UL, /* 64MB PCI IO @ 0x1000_0000 */ | ||
| 147 | .end = 0x17ffffffUL, | ||
| 148 | .flags = IORESOURCE_IO, | ||
| 149 | }; | ||
| 150 | |||
| 151 | struct pci_controller nlm_pci_controller = { | ||
| 152 | .index = 0, | ||
| 153 | .pci_ops = &nlm_pci_ops, | ||
| 154 | .mem_resource = &nlm_pci_mem_resource, | ||
| 155 | .mem_offset = 0x00000000UL, | ||
| 156 | .io_resource = &nlm_pci_io_resource, | ||
| 157 | .io_offset = 0x00000000UL, | ||
| 158 | }; | ||
| 159 | |||
| 160 | static int get_irq_vector(const struct pci_dev *dev) | ||
| 161 | { | ||
| 162 | /* | ||
| 163 | * For XLP PCIe, there is an IRQ per Link, find out which | ||
| 164 | * link the device is on to assign interrupts | ||
| 165 | */ | ||
| 166 | if (dev->bus->self == NULL) | ||
| 167 | return 0; | ||
| 168 | |||
| 169 | switch (dev->bus->self->devfn) { | ||
| 170 | case 0x8: | ||
| 171 | return PIC_PCIE_LINK_0_IRQ; | ||
| 172 | case 0x9: | ||
| 173 | return PIC_PCIE_LINK_1_IRQ; | ||
| 174 | case 0xa: | ||
| 175 | return PIC_PCIE_LINK_2_IRQ; | ||
| 176 | case 0xb: | ||
| 177 | return PIC_PCIE_LINK_3_IRQ; | ||
| 178 | } | ||
| 179 | WARN(1, "Unexpected devfn %d\n", dev->bus->self->devfn); | ||
| 180 | return 0; | ||
| 181 | } | ||
| 182 | |||
| 183 | int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | ||
| 184 | { | ||
| 185 | return get_irq_vector(dev); | ||
| 186 | } | ||
| 187 | |||
| 188 | /* Do platform specific device initialization at pci_enable_device() time */ | ||
| 189 | int pcibios_plat_dev_init(struct pci_dev *dev) | ||
| 190 | { | ||
| 191 | return 0; | ||
| 192 | } | ||
| 193 | |||
| 194 | static int xlp_enable_pci_bswap(void) | ||
| 195 | { | ||
| 196 | uint64_t pciebase, sysbase; | ||
| 197 | int node, i; | ||
| 198 | u32 reg; | ||
| 199 | |||
| 200 | /* Chip-0 so node set to 0 */ | ||
| 201 | node = 0; | ||
| 202 | sysbase = nlm_get_bridge_regbase(node); | ||
| 203 | /* | ||
| 204 | * Enable byte swap in hardware. Program each link's PCIe SWAP regions | ||
| 205 | * from the link's address ranges. | ||
| 206 | */ | ||
| 207 | for (i = 0; i < 4; i++) { | ||
| 208 | pciebase = nlm_pcicfg_base(XLP_IO_PCIE_OFFSET(node, i)); | ||
| 209 | if (nlm_read_pci_reg(pciebase, 0) == 0xffffffff) | ||
| 210 | continue; | ||
| 211 | |||
| 212 | reg = nlm_read_bridge_reg(sysbase, BRIDGE_PCIEMEM_BASE0 + i); | ||
| 213 | nlm_write_pci_reg(pciebase, PCIE_BYTE_SWAP_MEM_BASE, reg); | ||
| 214 | |||
| 215 | reg = nlm_read_bridge_reg(sysbase, BRIDGE_PCIEMEM_LIMIT0 + i); | ||
| 216 | nlm_write_pci_reg(pciebase, PCIE_BYTE_SWAP_MEM_LIM, | ||
| 217 | reg | 0xfff); | ||
| 218 | |||
| 219 | reg = nlm_read_bridge_reg(sysbase, BRIDGE_PCIEIO_BASE0 + i); | ||
| 220 | nlm_write_pci_reg(pciebase, PCIE_BYTE_SWAP_IO_BASE, reg); | ||
| 221 | |||
| 222 | reg = nlm_read_bridge_reg(sysbase, BRIDGE_PCIEIO_LIMIT0 + i); | ||
| 223 | nlm_write_pci_reg(pciebase, PCIE_BYTE_SWAP_IO_LIM, reg | 0xfff); | ||
| 224 | } | ||
| 225 | return 0; | ||
| 226 | } | ||
| 227 | |||
| 228 | static int __init pcibios_init(void) | ||
| 229 | { | ||
| 230 | /* Firmware assigns PCI resources */ | ||
| 231 | pci_set_flags(PCI_PROBE_ONLY); | ||
| 232 | pci_config_base = ioremap(XLP_DEFAULT_PCI_ECFG_BASE, 64 << 20); | ||
| 233 | |||
| 234 | /* Extend IO port for memory mapped io */ | ||
| 235 | ioport_resource.start = 0; | ||
| 236 | ioport_resource.end = ~0; | ||
| 237 | |||
| 238 | xlp_enable_pci_bswap(); | ||
| 239 | set_io_port_base(CKSEG1); | ||
| 240 | nlm_pci_controller.io_map_base = CKSEG1; | ||
| 241 | |||
| 242 | register_pci_controller(&nlm_pci_controller); | ||
| 243 | pr_info("XLP PCIe Controller %pR%pR.\n", &nlm_pci_io_resource, | ||
| 244 | &nlm_pci_mem_resource); | ||
| 245 | |||
| 246 | return 0; | ||
| 247 | } | ||
| 248 | arch_initcall(pcibios_init); | ||
diff --git a/arch/mips/pci/pci-xlr.c b/arch/mips/pci/pci-xlr.c index 172af1cd5867..18af021d289a 100644 --- a/arch/mips/pci/pci-xlr.c +++ b/arch/mips/pci/pci-xlr.c | |||
| @@ -375,7 +375,3 @@ static int __init pcibios_init(void) | |||
| 375 | } | 375 | } |
| 376 | 376 | ||
| 377 | arch_initcall(pcibios_init); | 377 | arch_initcall(pcibios_init); |
| 378 | |||
| 379 | struct pci_fixup pcibios_fixups[] = { | ||
| 380 | {0} | ||
| 381 | }; | ||
diff --git a/arch/mips/pnx833x/stb22x/board.c b/arch/mips/pnx833x/stb22x/board.c index 644eb7c3210f..4b328ac43050 100644 --- a/arch/mips/pnx833x/stb22x/board.c +++ b/arch/mips/pnx833x/stb22x/board.c | |||
| @@ -91,7 +91,7 @@ void __init pnx833x_board_setup(void) | |||
| 91 | pnx833x_gpio_select_function_alt(32); | 91 | pnx833x_gpio_select_function_alt(32); |
| 92 | pnx833x_gpio_select_function_alt(33); | 92 | pnx833x_gpio_select_function_alt(33); |
| 93 | 93 | ||
| 94 | #if defined(CONFIG_MTD_NAND_PLATFORM) || defined(CONFIG_MTD_NAND_PLATFORM_MODULE) | 94 | #if IS_ENABLED(CONFIG_MTD_NAND_PLATFORM) |
| 95 | /* Setup MIU for NAND access on CS0... | 95 | /* Setup MIU for NAND access on CS0... |
| 96 | * | 96 | * |
| 97 | * (it seems that we must also configure CS1 for reliable operation, | 97 | * (it seems that we must also configure CS1 for reliable operation, |
| @@ -117,7 +117,7 @@ void __init pnx833x_board_setup(void) | |||
| 117 | pnx833x_gpio_select_output(5); | 117 | pnx833x_gpio_select_output(5); |
| 118 | pnx833x_gpio_write(1, 5); | 118 | pnx833x_gpio_write(1, 5); |
| 119 | 119 | ||
| 120 | #elif defined(CONFIG_MTD_CFI) || defined(CONFIG_MTD_CFI_MODULE) | 120 | #elif IS_ENABLED(CONFIG_MTD_CFI) |
| 121 | 121 | ||
| 122 | /* Set up MIU for 16-bit NOR access on CS0 and CS1... */ | 122 | /* Set up MIU for 16-bit NOR access on CS0 and CS1... */ |
| 123 | 123 | ||
diff --git a/arch/mips/sgi-ip27/ip27-memory.c b/arch/mips/sgi-ip27/ip27-memory.c index b105eca3c020..cd8fcab6b054 100644 --- a/arch/mips/sgi-ip27/ip27-memory.c +++ b/arch/mips/sgi-ip27/ip27-memory.c | |||
| @@ -401,6 +401,7 @@ static void __init node_mem_init(cnodeid_t node) | |||
| 401 | * Allocate the node data structures on the node first. | 401 | * Allocate the node data structures on the node first. |
| 402 | */ | 402 | */ |
| 403 | __node_data[node] = __va(slot_freepfn << PAGE_SHIFT); | 403 | __node_data[node] = __va(slot_freepfn << PAGE_SHIFT); |
| 404 | memset(__node_data[node], 0, PAGE_SIZE); | ||
| 404 | 405 | ||
| 405 | NODE_DATA(node)->bdata = &bootmem_node_data[node]; | 406 | NODE_DATA(node)->bdata = &bootmem_node_data[node]; |
| 406 | NODE_DATA(node)->node_start_pfn = start_pfn; | 407 | NODE_DATA(node)->node_start_pfn = start_pfn; |
diff --git a/arch/mips/txx9/generic/pci.c b/arch/mips/txx9/generic/pci.c index 125db323ab1e..4efd9185f294 100644 --- a/arch/mips/txx9/generic/pci.c +++ b/arch/mips/txx9/generic/pci.c | |||
| @@ -304,7 +304,7 @@ static void __devinit quirk_slc90e66_bridge(struct pci_dev *dev) | |||
| 304 | smsc_fdc37m81x_config_end(); | 304 | smsc_fdc37m81x_config_end(); |
| 305 | } | 305 | } |
| 306 | 306 | ||
| 307 | static void quirk_slc90e66_ide(struct pci_dev *dev) | 307 | static void __devinit quirk_slc90e66_ide(struct pci_dev *dev) |
| 308 | { | 308 | { |
| 309 | unsigned char dat; | 309 | unsigned char dat; |
| 310 | int regs[2] = {0x41, 0x43}; | 310 | int regs[2] = {0x41, 0x43}; |
| @@ -339,7 +339,7 @@ static void quirk_slc90e66_ide(struct pci_dev *dev) | |||
| 339 | } | 339 | } |
| 340 | #endif /* CONFIG_TOSHIBA_FPCIB0 */ | 340 | #endif /* CONFIG_TOSHIBA_FPCIB0 */ |
| 341 | 341 | ||
| 342 | static void tc35815_fixup(struct pci_dev *dev) | 342 | static void __devinit tc35815_fixup(struct pci_dev *dev) |
| 343 | { | 343 | { |
| 344 | /* This device may have PM registers but not they are not suported. */ | 344 | /* This device may have PM registers but not they are not suported. */ |
| 345 | if (dev->pm_cap) { | 345 | if (dev->pm_cap) { |
| @@ -348,7 +348,7 @@ static void tc35815_fixup(struct pci_dev *dev) | |||
| 348 | } | 348 | } |
| 349 | } | 349 | } |
| 350 | 350 | ||
| 351 | static void final_fixup(struct pci_dev *dev) | 351 | static void __devinit final_fixup(struct pci_dev *dev) |
| 352 | { | 352 | { |
| 353 | unsigned char bist; | 353 | unsigned char bist; |
| 354 | 354 | ||
diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c index ae77a7916c03..560fe8991753 100644 --- a/arch/mips/txx9/generic/setup.c +++ b/arch/mips/txx9/generic/setup.c | |||
| @@ -632,7 +632,7 @@ void __init txx9_physmap_flash_init(int no, unsigned long addr, | |||
| 632 | unsigned long size, | 632 | unsigned long size, |
| 633 | const struct physmap_flash_data *pdata) | 633 | const struct physmap_flash_data *pdata) |
| 634 | { | 634 | { |
| 635 | #if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) | 635 | #if IS_ENABLED(CONFIG_MTD_PHYSMAP) |
| 636 | struct resource res = { | 636 | struct resource res = { |
| 637 | .start = addr, | 637 | .start = addr, |
| 638 | .end = addr + size - 1, | 638 | .end = addr + size - 1, |
| @@ -670,8 +670,7 @@ void __init txx9_physmap_flash_init(int no, unsigned long addr, | |||
| 670 | void __init txx9_ndfmc_init(unsigned long baseaddr, | 670 | void __init txx9_ndfmc_init(unsigned long baseaddr, |
| 671 | const struct txx9ndfmc_platform_data *pdata) | 671 | const struct txx9ndfmc_platform_data *pdata) |
| 672 | { | 672 | { |
| 673 | #if defined(CONFIG_MTD_NAND_TXX9NDFMC) || \ | 673 | #if IS_ENABLED(CONFIG_MTD_NAND_TXX9NDFMC) |
| 674 | defined(CONFIG_MTD_NAND_TXX9NDFMC_MODULE) | ||
| 675 | struct resource res = { | 674 | struct resource res = { |
| 676 | .start = baseaddr, | 675 | .start = baseaddr, |
| 677 | .end = baseaddr + 0x1000 - 1, | 676 | .end = baseaddr + 0x1000 - 1, |
| @@ -687,7 +686,7 @@ void __init txx9_ndfmc_init(unsigned long baseaddr, | |||
| 687 | #endif | 686 | #endif |
| 688 | } | 687 | } |
| 689 | 688 | ||
| 690 | #if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) | 689 | #if IS_ENABLED(CONFIG_LEDS_GPIO) |
| 691 | static DEFINE_SPINLOCK(txx9_iocled_lock); | 690 | static DEFINE_SPINLOCK(txx9_iocled_lock); |
| 692 | 691 | ||
| 693 | #define TXX9_IOCLED_MAXLEDS 8 | 692 | #define TXX9_IOCLED_MAXLEDS 8 |
| @@ -810,7 +809,7 @@ void __init txx9_iocled_init(unsigned long baseaddr, | |||
| 810 | void __init txx9_dmac_init(int id, unsigned long baseaddr, int irq, | 809 | void __init txx9_dmac_init(int id, unsigned long baseaddr, int irq, |
| 811 | const struct txx9dmac_platform_data *pdata) | 810 | const struct txx9dmac_platform_data *pdata) |
| 812 | { | 811 | { |
| 813 | #if defined(CONFIG_TXX9_DMAC) || defined(CONFIG_TXX9_DMAC_MODULE) | 812 | #if IS_ENABLED(CONFIG_TXX9_DMAC) |
| 814 | struct resource res[] = { | 813 | struct resource res[] = { |
| 815 | { | 814 | { |
| 816 | .start = baseaddr, | 815 | .start = baseaddr, |
| @@ -866,8 +865,7 @@ void __init txx9_aclc_init(unsigned long baseaddr, int irq, | |||
| 866 | unsigned int dma_chan_out, | 865 | unsigned int dma_chan_out, |
| 867 | unsigned int dma_chan_in) | 866 | unsigned int dma_chan_in) |
| 868 | { | 867 | { |
| 869 | #if defined(CONFIG_SND_SOC_TXX9ACLC) || \ | 868 | #if IS_ENABLED(CONFIG_SND_SOC_TXX9ACLC) |
| 870 | defined(CONFIG_SND_SOC_TXX9ACLC_MODULE) | ||
| 871 | unsigned int dma_base = dmac_id * TXX9_DMA_MAX_NR_CHANNELS; | 869 | unsigned int dma_base = dmac_id * TXX9_DMA_MAX_NR_CHANNELS; |
| 872 | struct resource res[] = { | 870 | struct resource res[] = { |
| 873 | { | 871 | { |
diff --git a/arch/mips/txx9/generic/setup_tx4939.c b/arch/mips/txx9/generic/setup_tx4939.c index 6567895d1f59..5ff7a9584daf 100644 --- a/arch/mips/txx9/generic/setup_tx4939.c +++ b/arch/mips/txx9/generic/setup_tx4939.c | |||
| @@ -317,7 +317,7 @@ void __init tx4939_sio_init(unsigned int sclk, unsigned int cts_mask) | |||
| 317 | } | 317 | } |
| 318 | } | 318 | } |
| 319 | 319 | ||
| 320 | #if defined(CONFIG_TC35815) || defined(CONFIG_TC35815_MODULE) | 320 | #if IS_ENABLED(CONFIG_TC35815) |
| 321 | static u32 tx4939_get_eth_speed(struct net_device *dev) | 321 | static u32 tx4939_get_eth_speed(struct net_device *dev) |
| 322 | { | 322 | { |
| 323 | struct ethtool_cmd cmd; | 323 | struct ethtool_cmd cmd; |
diff --git a/arch/mips/txx9/rbtx4939/setup.c b/arch/mips/txx9/rbtx4939/setup.c index 2ad8973ba13d..e15641d93092 100644 --- a/arch/mips/txx9/rbtx4939/setup.c +++ b/arch/mips/txx9/rbtx4939/setup.c | |||
| @@ -40,8 +40,7 @@ static void __init rbtx4939_time_init(void) | |||
| 40 | tx4939_time_init(0); | 40 | tx4939_time_init(0); |
| 41 | } | 41 | } |
| 42 | 42 | ||
| 43 | #if defined(__BIG_ENDIAN) && \ | 43 | #if defined(__BIG_ENDIAN) && IS_ENABLED(CONFIG_SMC91X) |
| 44 | (defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)) | ||
| 45 | #define HAVE_RBTX4939_IOSWAB | 44 | #define HAVE_RBTX4939_IOSWAB |
| 46 | #define IS_CE1_ADDR(addr) \ | 45 | #define IS_CE1_ADDR(addr) \ |
| 47 | ((((unsigned long)(addr) - IO_BASE) & 0xfff00000) == TXX9_CE(1)) | 46 | ((((unsigned long)(addr) - IO_BASE) & 0xfff00000) == TXX9_CE(1)) |
| @@ -187,7 +186,7 @@ static void __init rbtx4939_update_ioc_pen(void) | |||
| 187 | 186 | ||
| 188 | #define RBTX4939_MAX_7SEGLEDS 8 | 187 | #define RBTX4939_MAX_7SEGLEDS 8 |
| 189 | 188 | ||
| 190 | #if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) | 189 | #if IS_ENABLED(CONFIG_LEDS_CLASS) |
| 191 | static u8 led_val[RBTX4939_MAX_7SEGLEDS]; | 190 | static u8 led_val[RBTX4939_MAX_7SEGLEDS]; |
| 192 | struct rbtx4939_led_data { | 191 | struct rbtx4939_led_data { |
| 193 | struct led_classdev cdev; | 192 | struct led_classdev cdev; |
| @@ -263,7 +262,7 @@ static inline void rbtx4939_led_setup(void) | |||
| 263 | 262 | ||
| 264 | static void __rbtx4939_7segled_putc(unsigned int pos, unsigned char val) | 263 | static void __rbtx4939_7segled_putc(unsigned int pos, unsigned char val) |
| 265 | { | 264 | { |
| 266 | #if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) | 265 | #if IS_ENABLED(CONFIG_LEDS_CLASS) |
| 267 | unsigned long flags; | 266 | unsigned long flags; |
| 268 | local_irq_save(flags); | 267 | local_irq_save(flags); |
| 269 | /* bit7: reserved for LED class */ | 268 | /* bit7: reserved for LED class */ |
| @@ -287,7 +286,7 @@ static void rbtx4939_7segled_putc(unsigned int pos, unsigned char val) | |||
| 287 | __rbtx4939_7segled_putc(pos, val); | 286 | __rbtx4939_7segled_putc(pos, val); |
| 288 | } | 287 | } |
| 289 | 288 | ||
| 290 | #if defined(CONFIG_MTD_RBTX4939) || defined(CONFIG_MTD_RBTX4939_MODULE) | 289 | #if IS_ENABLED(CONFIG_MTD_RBTX4939) |
| 291 | /* special mapping for boot rom */ | 290 | /* special mapping for boot rom */ |
| 292 | static unsigned long rbtx4939_flash_fixup_ofs(unsigned long ofs) | 291 | static unsigned long rbtx4939_flash_fixup_ofs(unsigned long ofs) |
| 293 | { | 292 | { |
| @@ -463,7 +462,7 @@ static void __init rbtx4939_device_init(void) | |||
| 463 | .flags = SMC91X_USE_16BIT, | 462 | .flags = SMC91X_USE_16BIT, |
| 464 | }; | 463 | }; |
| 465 | struct platform_device *pdev; | 464 | struct platform_device *pdev; |
| 466 | #if defined(CONFIG_TC35815) || defined(CONFIG_TC35815_MODULE) | 465 | #if IS_ENABLED(CONFIG_TC35815) |
| 467 | int i, j; | 466 | int i, j; |
| 468 | unsigned char ethaddr[2][6]; | 467 | unsigned char ethaddr[2][6]; |
| 469 | u8 bdipsw = readb(rbtx4939_bdipsw_addr) & 0x0f; | 468 | u8 bdipsw = readb(rbtx4939_bdipsw_addr) & 0x0f; |
diff --git a/arch/mn10300/Kconfig b/arch/mn10300/Kconfig index 687f9b4a2ed6..5cfb086b3903 100644 --- a/arch/mn10300/Kconfig +++ b/arch/mn10300/Kconfig | |||
| @@ -3,6 +3,7 @@ config MN10300 | |||
| 3 | select HAVE_OPROFILE | 3 | select HAVE_OPROFILE |
| 4 | select HAVE_GENERIC_HARDIRQS | 4 | select HAVE_GENERIC_HARDIRQS |
| 5 | select GENERIC_IRQ_SHOW | 5 | select GENERIC_IRQ_SHOW |
| 6 | select ARCH_WANT_IPC_PARSE_VERSION | ||
| 6 | select HAVE_ARCH_TRACEHOOK | 7 | select HAVE_ARCH_TRACEHOOK |
| 7 | select HAVE_ARCH_KGDB | 8 | select HAVE_ARCH_KGDB |
| 8 | select HAVE_NMI_WATCHDOG if MN10300_WD_TIMER | 9 | select HAVE_NMI_WATCHDOG if MN10300_WD_TIMER |
diff --git a/arch/mn10300/include/asm/ipc.h b/arch/mn10300/include/asm/ipc.h deleted file mode 100644 index a46e3d9c2a3f..000000000000 --- a/arch/mn10300/include/asm/ipc.h +++ /dev/null | |||
| @@ -1 +0,0 @@ | |||
| 1 | #include <asm-generic/ipc.h> | ||
diff --git a/arch/mn10300/include/asm/unistd.h b/arch/mn10300/include/asm/unistd.h index 9051f921cbc7..866eb14749d7 100644 --- a/arch/mn10300/include/asm/unistd.h +++ b/arch/mn10300/include/asm/unistd.h | |||
| @@ -358,7 +358,6 @@ | |||
| 358 | /* | 358 | /* |
| 359 | * specify the deprecated syscalls we want to support on this arch | 359 | * specify the deprecated syscalls we want to support on this arch |
| 360 | */ | 360 | */ |
| 361 | #define __ARCH_WANT_IPC_PARSE_VERSION | ||
| 362 | #define __ARCH_WANT_OLD_READDIR | 361 | #define __ARCH_WANT_OLD_READDIR |
| 363 | #define __ARCH_WANT_OLD_STAT | 362 | #define __ARCH_WANT_OLD_STAT |
| 364 | #define __ARCH_WANT_STAT64 | 363 | #define __ARCH_WANT_STAT64 |
diff --git a/arch/openrisc/include/asm/Kbuild b/arch/openrisc/include/asm/Kbuild index 3f35c38d7b64..0922959663a0 100644 --- a/arch/openrisc/include/asm/Kbuild +++ b/arch/openrisc/include/asm/Kbuild | |||
| @@ -13,7 +13,6 @@ generic-y += cacheflush.h | |||
| 13 | generic-y += checksum.h | 13 | generic-y += checksum.h |
| 14 | generic-y += cmpxchg.h | 14 | generic-y += cmpxchg.h |
| 15 | generic-y += cmpxchg-local.h | 15 | generic-y += cmpxchg-local.h |
| 16 | generic-y += cpumask.h | ||
| 17 | generic-y += cputime.h | 16 | generic-y += cputime.h |
| 18 | generic-y += current.h | 17 | generic-y += current.h |
| 19 | generic-y += device.h | 18 | generic-y += device.h |
| @@ -43,7 +42,6 @@ generic-y += percpu.h | |||
| 43 | generic-y += poll.h | 42 | generic-y += poll.h |
| 44 | generic-y += posix_types.h | 43 | generic-y += posix_types.h |
| 45 | generic-y += resource.h | 44 | generic-y += resource.h |
| 46 | generic-y += rmap.h | ||
| 47 | generic-y += scatterlist.h | 45 | generic-y += scatterlist.h |
| 48 | generic-y += sections.h | 46 | generic-y += sections.h |
| 49 | generic-y += segment.h | 47 | generic-y += segment.h |
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 9a5d3cdc3e12..352f416269ce 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
| @@ -115,11 +115,13 @@ config PPC | |||
| 115 | select HAVE_OPROFILE | 115 | select HAVE_OPROFILE |
| 116 | select HAVE_SYSCALL_WRAPPERS if PPC64 | 116 | select HAVE_SYSCALL_WRAPPERS if PPC64 |
| 117 | select GENERIC_ATOMIC64 if PPC32 | 117 | select GENERIC_ATOMIC64 if PPC32 |
| 118 | select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE | ||
| 118 | select HAVE_IRQ_WORK | 119 | select HAVE_IRQ_WORK |
| 119 | select HAVE_PERF_EVENTS | 120 | select HAVE_PERF_EVENTS |
| 120 | select HAVE_REGS_AND_STACK_ACCESS_API | 121 | select HAVE_REGS_AND_STACK_ACCESS_API |
| 121 | select HAVE_HW_BREAKPOINT if PERF_EVENTS && PPC_BOOK3S_64 | 122 | select HAVE_HW_BREAKPOINT if PERF_EVENTS && PPC_BOOK3S_64 |
| 122 | select HAVE_GENERIC_HARDIRQS | 123 | select HAVE_GENERIC_HARDIRQS |
| 124 | select ARCH_WANT_IPC_PARSE_VERSION | ||
| 123 | select SPARSE_IRQ | 125 | select SPARSE_IRQ |
| 124 | select IRQ_PER_CPU | 126 | select IRQ_PER_CPU |
| 125 | select IRQ_DOMAIN | 127 | select IRQ_DOMAIN |
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 950d1f7a5a39..159e94f4b22a 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile | |||
| @@ -149,7 +149,6 @@ core-$(CONFIG_KVM) += arch/powerpc/kvm/ | |||
| 149 | core-$(CONFIG_PERF_EVENTS) += arch/powerpc/perf/ | 149 | core-$(CONFIG_PERF_EVENTS) += arch/powerpc/perf/ |
| 150 | 150 | ||
| 151 | drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ | 151 | drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ |
| 152 | drivers-$(CONFIG_CRYPTO_DEV_NX) += drivers/crypto/nx/ | ||
| 153 | 152 | ||
| 154 | # Default to zImage, override when needed | 153 | # Default to zImage, override when needed |
| 155 | all: zImage | 154 | all: zImage |
diff --git a/arch/powerpc/boot/dts/p2020rdb-pc_32b.dts b/arch/powerpc/boot/dts/p2020rdb-pc_32b.dts index 852e5b27485d..57573bd52caa 100644 --- a/arch/powerpc/boot/dts/p2020rdb-pc_32b.dts +++ b/arch/powerpc/boot/dts/p2020rdb-pc_32b.dts | |||
| @@ -56,7 +56,7 @@ | |||
| 56 | ranges = <0x0 0x0 0xffe00000 0x100000>; | 56 | ranges = <0x0 0x0 0xffe00000 0x100000>; |
| 57 | }; | 57 | }; |
| 58 | 58 | ||
| 59 | pci0: pcie@ffe08000 { | 59 | pci2: pcie@ffe08000 { |
| 60 | reg = <0 0xffe08000 0 0x1000>; | 60 | reg = <0 0xffe08000 0 0x1000>; |
| 61 | status = "disabled"; | 61 | status = "disabled"; |
| 62 | }; | 62 | }; |
| @@ -76,7 +76,7 @@ | |||
| 76 | }; | 76 | }; |
| 77 | }; | 77 | }; |
| 78 | 78 | ||
| 79 | pci2: pcie@ffe0a000 { | 79 | pci0: pcie@ffe0a000 { |
| 80 | reg = <0 0xffe0a000 0 0x1000>; | 80 | reg = <0 0xffe0a000 0 0x1000>; |
| 81 | ranges = <0x2000000 0x0 0xe0000000 0 0x80000000 0x0 0x20000000 | 81 | ranges = <0x2000000 0x0 0xe0000000 0 0x80000000 0x0 0x20000000 |
| 82 | 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>; | 82 | 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>; |
diff --git a/arch/powerpc/boot/dts/p2020rdb-pc_36b.dts b/arch/powerpc/boot/dts/p2020rdb-pc_36b.dts index b5a56ca51cf7..470247ea68b4 100644 --- a/arch/powerpc/boot/dts/p2020rdb-pc_36b.dts +++ b/arch/powerpc/boot/dts/p2020rdb-pc_36b.dts | |||
| @@ -56,7 +56,7 @@ | |||
| 56 | ranges = <0x0 0xf 0xffe00000 0x100000>; | 56 | ranges = <0x0 0xf 0xffe00000 0x100000>; |
| 57 | }; | 57 | }; |
| 58 | 58 | ||
| 59 | pci0: pcie@fffe08000 { | 59 | pci2: pcie@fffe08000 { |
| 60 | reg = <0xf 0xffe08000 0 0x1000>; | 60 | reg = <0xf 0xffe08000 0 0x1000>; |
| 61 | status = "disabled"; | 61 | status = "disabled"; |
| 62 | }; | 62 | }; |
| @@ -76,7 +76,7 @@ | |||
| 76 | }; | 76 | }; |
| 77 | }; | 77 | }; |
| 78 | 78 | ||
| 79 | pci2: pcie@fffe0a000 { | 79 | pci0: pcie@fffe0a000 { |
| 80 | reg = <0xf 0xffe0a000 0 0x1000>; | 80 | reg = <0xf 0xffe0a000 0 0x1000>; |
| 81 | ranges = <0x2000000 0x0 0xe0000000 0xc 0x00000000 0x0 0x20000000 | 81 | ranges = <0x2000000 0x0 0xe0000000 0xc 0x00000000 0x0 0x20000000 |
| 82 | 0x1000000 0x0 0x00000000 0xf 0xffc00000 0x0 0x10000>; | 82 | 0x1000000 0x0 0x00000000 0xf 0xffc00000 0x0 0x10000>; |
diff --git a/arch/powerpc/boot/dts/p3041ds.dts b/arch/powerpc/boot/dts/p3041ds.dts index 22a215e94162..6cdcadc80c30 100644 --- a/arch/powerpc/boot/dts/p3041ds.dts +++ b/arch/powerpc/boot/dts/p3041ds.dts | |||
| @@ -58,7 +58,7 @@ | |||
| 58 | #size-cells = <1>; | 58 | #size-cells = <1>; |
| 59 | compatible = "spansion,s25sl12801"; | 59 | compatible = "spansion,s25sl12801"; |
| 60 | reg = <0>; | 60 | reg = <0>; |
| 61 | spi-max-frequency = <40000000>; /* input clock */ | 61 | spi-max-frequency = <35000000>; /* input clock */ |
| 62 | partition@u-boot { | 62 | partition@u-boot { |
| 63 | label = "u-boot"; | 63 | label = "u-boot"; |
| 64 | reg = <0x00000000 0x00100000>; | 64 | reg = <0x00000000 0x00100000>; |
diff --git a/arch/powerpc/configs/chroma_defconfig b/arch/powerpc/configs/chroma_defconfig index b1f9597fe312..29bb11ec6c64 100644 --- a/arch/powerpc/configs/chroma_defconfig +++ b/arch/powerpc/configs/chroma_defconfig | |||
| @@ -21,8 +21,8 @@ CONFIG_CGROUP_DEVICE=y | |||
| 21 | CONFIG_CPUSETS=y | 21 | CONFIG_CPUSETS=y |
| 22 | CONFIG_CGROUP_CPUACCT=y | 22 | CONFIG_CGROUP_CPUACCT=y |
| 23 | CONFIG_RESOURCE_COUNTERS=y | 23 | CONFIG_RESOURCE_COUNTERS=y |
| 24 | CONFIG_CGROUP_MEM_RES_CTLR=y | 24 | CONFIG_CGROUP_MEMCG=y |
| 25 | CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y | 25 | CONFIG_CGROUP_MEMCG_SWAP=y |
| 26 | CONFIG_NAMESPACES=y | 26 | CONFIG_NAMESPACES=y |
| 27 | CONFIG_RELAY=y | 27 | CONFIG_RELAY=y |
| 28 | CONFIG_BLK_DEV_INITRD=y | 28 | CONFIG_BLK_DEV_INITRD=y |
diff --git a/arch/powerpc/configs/g5_defconfig b/arch/powerpc/configs/g5_defconfig index 07b7f2af2dca..15130066e5e2 100644 --- a/arch/powerpc/configs/g5_defconfig +++ b/arch/powerpc/configs/g5_defconfig | |||
| @@ -1,10 +1,8 @@ | |||
| 1 | CONFIG_PPC64=y | ||
| 2 | CONFIG_ALTIVEC=y | ||
| 3 | CONFIG_SMP=y | ||
| 4 | CONFIG_NR_CPUS=4 | ||
| 5 | CONFIG_EXPERIMENTAL=y | 1 | CONFIG_EXPERIMENTAL=y |
| 6 | CONFIG_SYSVIPC=y | 2 | CONFIG_SYSVIPC=y |
| 7 | CONFIG_POSIX_MQUEUE=y | 3 | CONFIG_POSIX_MQUEUE=y |
| 4 | CONFIG_NO_HZ=y | ||
| 5 | CONFIG_HIGH_RES_TIMERS=y | ||
| 8 | CONFIG_IKCONFIG=y | 6 | CONFIG_IKCONFIG=y |
| 9 | CONFIG_IKCONFIG_PROC=y | 7 | CONFIG_IKCONFIG_PROC=y |
| 10 | CONFIG_BLK_DEV_INITRD=y | 8 | CONFIG_BLK_DEV_INITRD=y |
| @@ -15,16 +13,15 @@ CONFIG_MODULES=y | |||
| 15 | CONFIG_MODULE_UNLOAD=y | 13 | CONFIG_MODULE_UNLOAD=y |
| 16 | CONFIG_MODVERSIONS=y | 14 | CONFIG_MODVERSIONS=y |
| 17 | CONFIG_MODULE_SRCVERSION_ALL=y | 15 | CONFIG_MODULE_SRCVERSION_ALL=y |
| 18 | # CONFIG_PPC_PSERIES is not set | 16 | CONFIG_PARTITION_ADVANCED=y |
| 17 | CONFIG_MAC_PARTITION=y | ||
| 18 | CONFIG_SMP=y | ||
| 19 | CONFIG_NR_CPUS=4 | ||
| 20 | CONFIG_KEXEC=y | ||
| 21 | # CONFIG_RELOCATABLE is not set | ||
| 19 | CONFIG_CPU_FREQ=y | 22 | CONFIG_CPU_FREQ=y |
| 20 | CONFIG_CPU_FREQ_GOV_POWERSAVE=y | 23 | CONFIG_CPU_FREQ_GOV_POWERSAVE=y |
| 21 | CONFIG_CPU_FREQ_GOV_USERSPACE=y | 24 | CONFIG_CPU_FREQ_GOV_USERSPACE=y |
| 22 | CONFIG_CPU_FREQ_PMAC64=y | ||
| 23 | CONFIG_NO_HZ=y | ||
| 24 | CONFIG_HIGH_RES_TIMERS=y | ||
| 25 | CONFIG_KEXEC=y | ||
| 26 | CONFIG_IRQ_ALL_CPUS=y | ||
| 27 | # CONFIG_MIGRATION is not set | ||
| 28 | CONFIG_PCI_MSI=y | 25 | CONFIG_PCI_MSI=y |
| 29 | CONFIG_NET=y | 26 | CONFIG_NET=y |
| 30 | CONFIG_PACKET=y | 27 | CONFIG_PACKET=y |
| @@ -52,7 +49,6 @@ CONFIG_NF_CT_NETLINK=m | |||
| 52 | CONFIG_NF_CONNTRACK_IPV4=m | 49 | CONFIG_NF_CONNTRACK_IPV4=m |
| 53 | CONFIG_IP_NF_QUEUE=m | 50 | CONFIG_IP_NF_QUEUE=m |
| 54 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | 51 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" |
| 55 | CONFIG_PROC_DEVICETREE=y | ||
| 56 | CONFIG_BLK_DEV_LOOP=y | 52 | CONFIG_BLK_DEV_LOOP=y |
| 57 | CONFIG_BLK_DEV_NBD=m | 53 | CONFIG_BLK_DEV_NBD=m |
| 58 | CONFIG_BLK_DEV_RAM=y | 54 | CONFIG_BLK_DEV_RAM=y |
| @@ -60,8 +56,6 @@ CONFIG_BLK_DEV_RAM_SIZE=65536 | |||
| 60 | CONFIG_CDROM_PKTCDVD=m | 56 | CONFIG_CDROM_PKTCDVD=m |
| 61 | CONFIG_IDE=y | 57 | CONFIG_IDE=y |
| 62 | CONFIG_BLK_DEV_IDECD=y | 58 | CONFIG_BLK_DEV_IDECD=y |
| 63 | CONFIG_BLK_DEV_IDE_PMAC=y | ||
| 64 | CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST=y | ||
| 65 | CONFIG_BLK_DEV_SD=y | 59 | CONFIG_BLK_DEV_SD=y |
| 66 | CONFIG_CHR_DEV_ST=y | 60 | CONFIG_CHR_DEV_ST=y |
| 67 | CONFIG_BLK_DEV_SR=y | 61 | CONFIG_BLK_DEV_SR=y |
| @@ -85,33 +79,24 @@ CONFIG_DM_CRYPT=m | |||
| 85 | CONFIG_DM_SNAPSHOT=m | 79 | CONFIG_DM_SNAPSHOT=m |
| 86 | CONFIG_DM_MIRROR=m | 80 | CONFIG_DM_MIRROR=m |
| 87 | CONFIG_DM_ZERO=m | 81 | CONFIG_DM_ZERO=m |
| 88 | CONFIG_IEEE1394=y | 82 | CONFIG_MACINTOSH_DRIVERS=y |
| 89 | CONFIG_IEEE1394_OHCI1394=y | ||
| 90 | CONFIG_IEEE1394_SBP2=m | ||
| 91 | CONFIG_IEEE1394_ETH1394=m | ||
| 92 | CONFIG_IEEE1394_RAWIO=y | ||
| 93 | CONFIG_IEEE1394_VIDEO1394=m | ||
| 94 | CONFIG_IEEE1394_DV1394=m | ||
| 95 | CONFIG_ADB_PMU=y | ||
| 96 | CONFIG_PMAC_SMU=y | ||
| 97 | CONFIG_MAC_EMUMOUSEBTN=y | 83 | CONFIG_MAC_EMUMOUSEBTN=y |
| 98 | CONFIG_THERM_PM72=y | ||
| 99 | CONFIG_WINDFARM=y | ||
| 100 | CONFIG_WINDFARM_PM81=y | ||
| 101 | CONFIG_WINDFARM_PM91=y | ||
| 102 | CONFIG_WINDFARM_PM112=y | ||
| 103 | CONFIG_WINDFARM_PM121=y | ||
| 104 | CONFIG_NETDEVICES=y | 84 | CONFIG_NETDEVICES=y |
| 105 | CONFIG_DUMMY=m | ||
| 106 | CONFIG_BONDING=m | 85 | CONFIG_BONDING=m |
| 107 | CONFIG_TUN=m | 86 | CONFIG_DUMMY=m |
| 108 | CONFIG_NET_ETHERNET=y | ||
| 109 | CONFIG_MII=y | 87 | CONFIG_MII=y |
| 110 | CONFIG_SUNGEM=y | 88 | CONFIG_TUN=m |
| 111 | CONFIG_ACENIC=m | 89 | CONFIG_ACENIC=m |
| 112 | CONFIG_ACENIC_OMIT_TIGON_I=y | 90 | CONFIG_ACENIC_OMIT_TIGON_I=y |
| 113 | CONFIG_E1000=y | ||
| 114 | CONFIG_TIGON3=y | 91 | CONFIG_TIGON3=y |
| 92 | CONFIG_E1000=y | ||
| 93 | CONFIG_SUNGEM=y | ||
| 94 | CONFIG_PPP=m | ||
| 95 | CONFIG_PPP_BSDCOMP=m | ||
| 96 | CONFIG_PPP_DEFLATE=m | ||
| 97 | CONFIG_PPPOE=m | ||
| 98 | CONFIG_PPP_ASYNC=m | ||
| 99 | CONFIG_PPP_SYNC_TTY=m | ||
| 115 | CONFIG_USB_CATC=m | 100 | CONFIG_USB_CATC=m |
| 116 | CONFIG_USB_KAWETH=m | 101 | CONFIG_USB_KAWETH=m |
| 117 | CONFIG_USB_PEGASUS=m | 102 | CONFIG_USB_PEGASUS=m |
| @@ -121,36 +106,24 @@ CONFIG_USB_USBNET=m | |||
| 121 | # CONFIG_USB_NET_NET1080 is not set | 106 | # CONFIG_USB_NET_NET1080 is not set |
| 122 | # CONFIG_USB_NET_CDC_SUBSET is not set | 107 | # CONFIG_USB_NET_CDC_SUBSET is not set |
| 123 | # CONFIG_USB_NET_ZAURUS is not set | 108 | # CONFIG_USB_NET_ZAURUS is not set |
| 124 | CONFIG_PPP=m | ||
| 125 | CONFIG_PPP_ASYNC=m | ||
| 126 | CONFIG_PPP_SYNC_TTY=m | ||
| 127 | CONFIG_PPP_DEFLATE=m | ||
| 128 | CONFIG_PPP_BSDCOMP=m | ||
| 129 | CONFIG_PPPOE=m | ||
| 130 | # CONFIG_INPUT_MOUSEDEV_PSAUX is not set | 109 | # CONFIG_INPUT_MOUSEDEV_PSAUX is not set |
| 131 | CONFIG_INPUT_JOYDEV=m | 110 | CONFIG_INPUT_JOYDEV=m |
| 132 | CONFIG_INPUT_EVDEV=y | 111 | CONFIG_INPUT_EVDEV=y |
| 133 | # CONFIG_KEYBOARD_ATKBD is not set | ||
| 134 | # CONFIG_MOUSE_PS2 is not set | 112 | # CONFIG_MOUSE_PS2 is not set |
| 135 | # CONFIG_SERIO_I8042 is not set | ||
| 136 | # CONFIG_SERIO_SERPORT is not set | 113 | # CONFIG_SERIO_SERPORT is not set |
| 114 | CONFIG_VT_HW_CONSOLE_BINDING=y | ||
| 137 | # CONFIG_HW_RANDOM is not set | 115 | # CONFIG_HW_RANDOM is not set |
| 138 | CONFIG_GEN_RTC=y | 116 | CONFIG_GEN_RTC=y |
| 139 | CONFIG_RAW_DRIVER=y | 117 | CONFIG_RAW_DRIVER=y |
| 140 | CONFIG_I2C_CHARDEV=y | 118 | CONFIG_I2C_CHARDEV=y |
| 141 | # CONFIG_HWMON is not set | 119 | # CONFIG_HWMON is not set |
| 142 | CONFIG_AGP=m | 120 | CONFIG_AGP=y |
| 143 | CONFIG_AGP_UNINORTH=m | 121 | CONFIG_DRM=y |
| 122 | CONFIG_DRM_NOUVEAU=y | ||
| 144 | CONFIG_VIDEO_OUTPUT_CONTROL=m | 123 | CONFIG_VIDEO_OUTPUT_CONTROL=m |
| 145 | CONFIG_FB=y | ||
| 146 | CONFIG_FIRMWARE_EDID=y | 124 | CONFIG_FIRMWARE_EDID=y |
| 147 | CONFIG_FB_TILEBLITTING=y | 125 | CONFIG_FB_TILEBLITTING=y |
| 148 | CONFIG_FB_OF=y | ||
| 149 | CONFIG_FB_NVIDIA=y | ||
| 150 | CONFIG_FB_NVIDIA_I2C=y | ||
| 151 | CONFIG_FB_RADEON=y | 126 | CONFIG_FB_RADEON=y |
| 152 | # CONFIG_VGA_CONSOLE is not set | ||
| 153 | CONFIG_FRAMEBUFFER_CONSOLE=y | ||
| 154 | CONFIG_LOGO=y | 127 | CONFIG_LOGO=y |
| 155 | CONFIG_SOUND=m | 128 | CONFIG_SOUND=m |
| 156 | CONFIG_SND=m | 129 | CONFIG_SND=m |
| @@ -158,15 +131,7 @@ CONFIG_SND_SEQUENCER=m | |||
| 158 | CONFIG_SND_MIXER_OSS=m | 131 | CONFIG_SND_MIXER_OSS=m |
| 159 | CONFIG_SND_PCM_OSS=m | 132 | CONFIG_SND_PCM_OSS=m |
| 160 | CONFIG_SND_SEQUENCER_OSS=y | 133 | CONFIG_SND_SEQUENCER_OSS=y |
| 161 | CONFIG_SND_POWERMAC=m | ||
| 162 | CONFIG_SND_AOA=m | ||
| 163 | CONFIG_SND_AOA_FABRIC_LAYOUT=m | ||
| 164 | CONFIG_SND_AOA_ONYX=m | ||
| 165 | CONFIG_SND_AOA_TAS=m | ||
| 166 | CONFIG_SND_AOA_TOONIE=m | ||
| 167 | CONFIG_SND_USB_AUDIO=m | 134 | CONFIG_SND_USB_AUDIO=m |
| 168 | CONFIG_HID_PID=y | ||
| 169 | CONFIG_USB_HIDDEV=y | ||
| 170 | CONFIG_HID_GYRATION=y | 135 | CONFIG_HID_GYRATION=y |
| 171 | CONFIG_LOGITECH_FF=y | 136 | CONFIG_LOGITECH_FF=y |
| 172 | CONFIG_HID_PANTHERLORD=y | 137 | CONFIG_HID_PANTHERLORD=y |
| @@ -174,13 +139,12 @@ CONFIG_HID_PETALYNX=y | |||
| 174 | CONFIG_HID_SAMSUNG=y | 139 | CONFIG_HID_SAMSUNG=y |
| 175 | CONFIG_HID_SONY=y | 140 | CONFIG_HID_SONY=y |
| 176 | CONFIG_HID_SUNPLUS=y | 141 | CONFIG_HID_SUNPLUS=y |
| 142 | CONFIG_HID_PID=y | ||
| 143 | CONFIG_USB_HIDDEV=y | ||
| 177 | CONFIG_USB=y | 144 | CONFIG_USB=y |
| 178 | CONFIG_USB_DEVICEFS=y | ||
| 179 | CONFIG_USB_MON=y | 145 | CONFIG_USB_MON=y |
| 180 | CONFIG_USB_EHCI_HCD=y | 146 | CONFIG_USB_EHCI_HCD=y |
| 181 | # CONFIG_USB_EHCI_HCD_PPC_OF is not set | ||
| 182 | CONFIG_USB_OHCI_HCD=y | 147 | CONFIG_USB_OHCI_HCD=y |
| 183 | CONFIG_USB_OHCI_HCD_PPC_OF_BE=y | ||
| 184 | CONFIG_USB_ACM=m | 148 | CONFIG_USB_ACM=m |
| 185 | CONFIG_USB_PRINTER=y | 149 | CONFIG_USB_PRINTER=y |
| 186 | CONFIG_USB_STORAGE=y | 150 | CONFIG_USB_STORAGE=y |
| @@ -244,8 +208,6 @@ CONFIG_REISERFS_FS_POSIX_ACL=y | |||
| 244 | CONFIG_REISERFS_FS_SECURITY=y | 208 | CONFIG_REISERFS_FS_SECURITY=y |
| 245 | CONFIG_XFS_FS=m | 209 | CONFIG_XFS_FS=m |
| 246 | CONFIG_XFS_POSIX_ACL=y | 210 | CONFIG_XFS_POSIX_ACL=y |
| 247 | CONFIG_INOTIFY=y | ||
| 248 | CONFIG_AUTOFS_FS=m | ||
| 249 | CONFIG_ISO9660_FS=y | 211 | CONFIG_ISO9660_FS=y |
| 250 | CONFIG_JOLIET=y | 212 | CONFIG_JOLIET=y |
| 251 | CONFIG_ZISOFS=y | 213 | CONFIG_ZISOFS=y |
| @@ -259,14 +221,12 @@ CONFIG_HFS_FS=m | |||
| 259 | CONFIG_HFSPLUS_FS=m | 221 | CONFIG_HFSPLUS_FS=m |
| 260 | CONFIG_CRAMFS=y | 222 | CONFIG_CRAMFS=y |
| 261 | CONFIG_NFS_FS=y | 223 | CONFIG_NFS_FS=y |
| 262 | CONFIG_NFS_V3=y | ||
| 263 | CONFIG_NFS_V3_ACL=y | 224 | CONFIG_NFS_V3_ACL=y |
| 264 | CONFIG_NFS_V4=y | 225 | CONFIG_NFS_V4=y |
| 265 | CONFIG_NFSD=y | 226 | CONFIG_NFSD=y |
| 266 | CONFIG_NFSD_V3_ACL=y | 227 | CONFIG_NFSD_V3_ACL=y |
| 267 | CONFIG_NFSD_V4=y | 228 | CONFIG_NFSD_V4=y |
| 268 | CONFIG_CIFS=m | 229 | CONFIG_CIFS=m |
| 269 | CONFIG_PARTITION_ADVANCED=y | ||
| 270 | CONFIG_NLS_CODEPAGE_437=y | 230 | CONFIG_NLS_CODEPAGE_437=y |
| 271 | CONFIG_NLS_CODEPAGE_1250=y | 231 | CONFIG_NLS_CODEPAGE_1250=y |
| 272 | CONFIG_NLS_CODEPAGE_1251=y | 232 | CONFIG_NLS_CODEPAGE_1251=y |
| @@ -274,29 +234,23 @@ CONFIG_NLS_ASCII=y | |||
| 274 | CONFIG_NLS_ISO8859_1=y | 234 | CONFIG_NLS_ISO8859_1=y |
| 275 | CONFIG_NLS_ISO8859_15=y | 235 | CONFIG_NLS_ISO8859_15=y |
| 276 | CONFIG_NLS_UTF8=y | 236 | CONFIG_NLS_UTF8=y |
| 277 | CONFIG_CRC_T10DIF=y | ||
| 278 | CONFIG_LIBCRC32C=m | ||
| 279 | CONFIG_MAGIC_SYSRQ=y | 237 | CONFIG_MAGIC_SYSRQ=y |
| 238 | # CONFIG_UNUSED_SYMBOLS is not set | ||
| 280 | CONFIG_DEBUG_FS=y | 239 | CONFIG_DEBUG_FS=y |
| 281 | CONFIG_DEBUG_KERNEL=y | 240 | CONFIG_DEBUG_KERNEL=y |
| 282 | CONFIG_DEBUG_MUTEXES=y | 241 | CONFIG_DEBUG_MUTEXES=y |
| 283 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | ||
| 284 | CONFIG_LATENCYTOP=y | 242 | CONFIG_LATENCYTOP=y |
| 285 | CONFIG_SYSCTL_SYSCALL_CHECK=y | 243 | CONFIG_STRICT_DEVMEM=y |
| 286 | CONFIG_BOOTX_TEXT=y | ||
| 287 | CONFIG_CRYPTO_NULL=m | 244 | CONFIG_CRYPTO_NULL=m |
| 288 | CONFIG_CRYPTO_TEST=m | 245 | CONFIG_CRYPTO_TEST=m |
| 289 | CONFIG_CRYPTO_ECB=m | ||
| 290 | CONFIG_CRYPTO_PCBC=m | 246 | CONFIG_CRYPTO_PCBC=m |
| 291 | CONFIG_CRYPTO_HMAC=y | 247 | CONFIG_CRYPTO_HMAC=y |
| 292 | CONFIG_CRYPTO_MD4=m | ||
| 293 | CONFIG_CRYPTO_MICHAEL_MIC=m | 248 | CONFIG_CRYPTO_MICHAEL_MIC=m |
| 294 | CONFIG_CRYPTO_SHA256=m | 249 | CONFIG_CRYPTO_SHA256=m |
| 295 | CONFIG_CRYPTO_SHA512=m | 250 | CONFIG_CRYPTO_SHA512=m |
| 296 | CONFIG_CRYPTO_WP512=m | 251 | CONFIG_CRYPTO_WP512=m |
| 297 | CONFIG_CRYPTO_AES=m | 252 | CONFIG_CRYPTO_AES=m |
| 298 | CONFIG_CRYPTO_ANUBIS=m | 253 | CONFIG_CRYPTO_ANUBIS=m |
| 299 | CONFIG_CRYPTO_ARC4=m | ||
| 300 | CONFIG_CRYPTO_BLOWFISH=m | 254 | CONFIG_CRYPTO_BLOWFISH=m |
| 301 | CONFIG_CRYPTO_CAST5=m | 255 | CONFIG_CRYPTO_CAST5=m |
| 302 | CONFIG_CRYPTO_CAST6=m | 256 | CONFIG_CRYPTO_CAST6=m |
| @@ -306,3 +260,6 @@ CONFIG_CRYPTO_TEA=m | |||
| 306 | CONFIG_CRYPTO_TWOFISH=m | 260 | CONFIG_CRYPTO_TWOFISH=m |
| 307 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | 261 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
| 308 | # CONFIG_CRYPTO_HW is not set | 262 | # CONFIG_CRYPTO_HW is not set |
| 263 | # CONFIG_VIRTUALIZATION is not set | ||
| 264 | CONFIG_CRC_T10DIF=y | ||
| 265 | CONFIG_LIBCRC32C=m | ||
diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig index f2fe0c2b41e4..db27c82e0542 100644 --- a/arch/powerpc/configs/ppc64_defconfig +++ b/arch/powerpc/configs/ppc64_defconfig | |||
| @@ -279,7 +279,8 @@ CONFIG_HVC_RTAS=y | |||
| 279 | CONFIG_HVC_BEAT=y | 279 | CONFIG_HVC_BEAT=y |
| 280 | CONFIG_HVCS=m | 280 | CONFIG_HVCS=m |
| 281 | CONFIG_IBM_BSR=m | 281 | CONFIG_IBM_BSR=m |
| 282 | # CONFIG_HW_RANDOM is not set | 282 | CONFIG_HW_RANDOM=m |
| 283 | CONFIG_HW_RANDOM_PSERIES=m | ||
| 283 | CONFIG_RAW_DRIVER=y | 284 | CONFIG_RAW_DRIVER=y |
| 284 | CONFIG_I2C_CHARDEV=y | 285 | CONFIG_I2C_CHARDEV=y |
| 285 | CONFIG_I2C_AMD8111=y | 286 | CONFIG_I2C_AMD8111=y |
| @@ -485,7 +486,8 @@ CONFIG_CRYPTO_TEA=m | |||
| 485 | CONFIG_CRYPTO_TWOFISH=m | 486 | CONFIG_CRYPTO_TWOFISH=m |
| 486 | CONFIG_CRYPTO_LZO=m | 487 | CONFIG_CRYPTO_LZO=m |
| 487 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | 488 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
| 488 | # CONFIG_CRYPTO_HW is not set | 489 | CONFIG_CRYPTO_HW=y |
| 490 | CONFIG_CRYPTO_DEV_NX=m | ||
| 489 | CONFIG_VIRTUALIZATION=y | 491 | CONFIG_VIRTUALIZATION=y |
| 490 | CONFIG_KVM_BOOK3S_64=m | 492 | CONFIG_KVM_BOOK3S_64=m |
| 491 | CONFIG_KVM_BOOK3S_64_HV=y | 493 | CONFIG_KVM_BOOK3S_64_HV=y |
diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig index 187fb8d53605..1f65b3c9b59a 100644 --- a/arch/powerpc/configs/pseries_defconfig +++ b/arch/powerpc/configs/pseries_defconfig | |||
| @@ -226,7 +226,8 @@ CONFIG_HVC_CONSOLE=y | |||
| 226 | CONFIG_HVC_RTAS=y | 226 | CONFIG_HVC_RTAS=y |
| 227 | CONFIG_HVCS=m | 227 | CONFIG_HVCS=m |
| 228 | CONFIG_IBM_BSR=m | 228 | CONFIG_IBM_BSR=m |
| 229 | # CONFIG_HW_RANDOM is not set | 229 | CONFIG_HW_RANDOM=m |
| 230 | CONFIG_HW_RANDOM_PSERIES=m | ||
| 230 | CONFIG_GEN_RTC=y | 231 | CONFIG_GEN_RTC=y |
| 231 | CONFIG_RAW_DRIVER=y | 232 | CONFIG_RAW_DRIVER=y |
| 232 | CONFIG_MAX_RAW_DEVS=1024 | 233 | CONFIG_MAX_RAW_DEVS=1024 |
| @@ -367,7 +368,8 @@ CONFIG_CRYPTO_TEA=m | |||
| 367 | CONFIG_CRYPTO_TWOFISH=m | 368 | CONFIG_CRYPTO_TWOFISH=m |
| 368 | CONFIG_CRYPTO_LZO=m | 369 | CONFIG_CRYPTO_LZO=m |
| 369 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | 370 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
| 370 | # CONFIG_CRYPTO_HW is not set | 371 | CONFIG_CRYPTO_HW=y |
| 372 | CONFIG_CRYPTO_DEV_NX=m | ||
| 371 | CONFIG_VIRTUALIZATION=y | 373 | CONFIG_VIRTUALIZATION=y |
| 372 | CONFIG_KVM_BOOK3S_64=m | 374 | CONFIG_KVM_BOOK3S_64=m |
| 373 | CONFIG_KVM_BOOK3S_64_HV=y | 375 | CONFIG_KVM_BOOK3S_64_HV=y |
diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h index 62678e365ca0..78160874809a 100644 --- a/arch/powerpc/include/asm/dma-mapping.h +++ b/arch/powerpc/include/asm/dma-mapping.h | |||
| @@ -27,7 +27,10 @@ extern void *dma_direct_alloc_coherent(struct device *dev, size_t size, | |||
| 27 | extern void dma_direct_free_coherent(struct device *dev, size_t size, | 27 | extern void dma_direct_free_coherent(struct device *dev, size_t size, |
| 28 | void *vaddr, dma_addr_t dma_handle, | 28 | void *vaddr, dma_addr_t dma_handle, |
| 29 | struct dma_attrs *attrs); | 29 | struct dma_attrs *attrs); |
| 30 | 30 | extern int dma_direct_mmap_coherent(struct device *dev, | |
| 31 | struct vm_area_struct *vma, | ||
| 32 | void *cpu_addr, dma_addr_t handle, | ||
| 33 | size_t size, struct dma_attrs *attrs); | ||
| 31 | 34 | ||
| 32 | #ifdef CONFIG_NOT_COHERENT_CACHE | 35 | #ifdef CONFIG_NOT_COHERENT_CACHE |
| 33 | /* | 36 | /* |
| @@ -207,11 +210,8 @@ static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr) | |||
| 207 | #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) | 210 | #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) |
| 208 | #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) | 211 | #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) |
| 209 | 212 | ||
| 210 | extern int dma_mmap_coherent(struct device *, struct vm_area_struct *, | ||
| 211 | void *, dma_addr_t, size_t); | ||
| 212 | #define ARCH_HAS_DMA_MMAP_COHERENT | 213 | #define ARCH_HAS_DMA_MMAP_COHERENT |
| 213 | 214 | ||
| 214 | |||
| 215 | static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size, | 215 | static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size, |
| 216 | enum dma_data_direction direction) | 216 | enum dma_data_direction direction) |
| 217 | { | 217 | { |
diff --git a/arch/powerpc/include/asm/kmap_types.h b/arch/powerpc/include/asm/kmap_types.h index bca8fdcd2542..5acabbd7ac6f 100644 --- a/arch/powerpc/include/asm/kmap_types.h +++ b/arch/powerpc/include/asm/kmap_types.h | |||
| @@ -10,36 +10,7 @@ | |||
| 10 | * 2 of the License, or (at your option) any later version. | 10 | * 2 of the License, or (at your option) any later version. |
| 11 | */ | 11 | */ |
| 12 | 12 | ||
| 13 | enum km_type { | 13 | #define KM_TYPE_NR 16 |
| 14 | KM_BOUNCE_READ, | ||
| 15 | KM_SKB_SUNRPC_DATA, | ||
| 16 | KM_SKB_DATA_SOFTIRQ, | ||
| 17 | KM_USER0, | ||
| 18 | KM_USER1, | ||
| 19 | KM_BIO_SRC_IRQ, | ||
| 20 | KM_BIO_DST_IRQ, | ||
| 21 | KM_PTE0, | ||
| 22 | KM_PTE1, | ||
| 23 | KM_IRQ0, | ||
| 24 | KM_IRQ1, | ||
| 25 | KM_SOFTIRQ0, | ||
| 26 | KM_SOFTIRQ1, | ||
| 27 | KM_PPC_SYNC_PAGE, | ||
| 28 | KM_PPC_SYNC_ICACHE, | ||
| 29 | KM_KDB, | ||
| 30 | KM_TYPE_NR | ||
| 31 | }; | ||
| 32 | |||
| 33 | /* | ||
| 34 | * This is a temporary build fix that (so they say on lkml....) should no longer | ||
| 35 | * be required after 2.6.33, because of changes planned to the kmap code. | ||
| 36 | * Let's try to remove this cruft then. | ||
| 37 | */ | ||
| 38 | #ifdef CONFIG_DEBUG_HIGHMEM | ||
| 39 | #define KM_NMI (-1) | ||
| 40 | #define KM_NMI_PTE (-1) | ||
| 41 | #define KM_IRQ_PTE (-1) | ||
| 42 | #endif | ||
| 43 | 14 | ||
| 44 | #endif /* __KERNEL__ */ | 15 | #endif /* __KERNEL__ */ |
| 45 | #endif /* _ASM_POWERPC_KMAP_TYPES_H */ | 16 | #endif /* _ASM_POWERPC_KMAP_TYPES_H */ |
diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h index d3d1b5efd7eb..bd377a368611 100644 --- a/arch/powerpc/include/asm/unistd.h +++ b/arch/powerpc/include/asm/unistd.h | |||
| @@ -389,7 +389,6 @@ | |||
| 389 | #include <linux/compiler.h> | 389 | #include <linux/compiler.h> |
| 390 | #include <linux/linkage.h> | 390 | #include <linux/linkage.h> |
| 391 | 391 | ||
| 392 | #define __ARCH_WANT_IPC_PARSE_VERSION | ||
| 393 | #define __ARCH_WANT_OLD_READDIR | 392 | #define __ARCH_WANT_OLD_READDIR |
| 394 | #define __ARCH_WANT_STAT64 | 393 | #define __ARCH_WANT_STAT64 |
| 395 | #define __ARCH_WANT_SYS_ALARM | 394 | #define __ARCH_WANT_SYS_ALARM |
diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c index bcfdcd22c766..2d7bb8ced136 100644 --- a/arch/powerpc/kernel/dma-iommu.c +++ b/arch/powerpc/kernel/dma-iommu.c | |||
| @@ -109,6 +109,7 @@ static u64 dma_iommu_get_required_mask(struct device *dev) | |||
| 109 | struct dma_map_ops dma_iommu_ops = { | 109 | struct dma_map_ops dma_iommu_ops = { |
| 110 | .alloc = dma_iommu_alloc_coherent, | 110 | .alloc = dma_iommu_alloc_coherent, |
| 111 | .free = dma_iommu_free_coherent, | 111 | .free = dma_iommu_free_coherent, |
| 112 | .mmap = dma_direct_mmap_coherent, | ||
| 112 | .map_sg = dma_iommu_map_sg, | 113 | .map_sg = dma_iommu_map_sg, |
| 113 | .unmap_sg = dma_iommu_unmap_sg, | 114 | .unmap_sg = dma_iommu_unmap_sg, |
| 114 | .dma_supported = dma_iommu_dma_supported, | 115 | .dma_supported = dma_iommu_dma_supported, |
diff --git a/arch/powerpc/kernel/dma-swiotlb.c b/arch/powerpc/kernel/dma-swiotlb.c index 4ab88dafb235..46943651da23 100644 --- a/arch/powerpc/kernel/dma-swiotlb.c +++ b/arch/powerpc/kernel/dma-swiotlb.c | |||
| @@ -49,6 +49,7 @@ static u64 swiotlb_powerpc_get_required(struct device *dev) | |||
| 49 | struct dma_map_ops swiotlb_dma_ops = { | 49 | struct dma_map_ops swiotlb_dma_ops = { |
| 50 | .alloc = dma_direct_alloc_coherent, | 50 | .alloc = dma_direct_alloc_coherent, |
| 51 | .free = dma_direct_free_coherent, | 51 | .free = dma_direct_free_coherent, |
| 52 | .mmap = dma_direct_mmap_coherent, | ||
| 52 | .map_sg = swiotlb_map_sg_attrs, | 53 | .map_sg = swiotlb_map_sg_attrs, |
| 53 | .unmap_sg = swiotlb_unmap_sg_attrs, | 54 | .unmap_sg = swiotlb_unmap_sg_attrs, |
| 54 | .dma_supported = swiotlb_dma_supported, | 55 | .dma_supported = swiotlb_dma_supported, |
diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c index 289be751cd75..355b9d84b0f8 100644 --- a/arch/powerpc/kernel/dma.c +++ b/arch/powerpc/kernel/dma.c | |||
| @@ -67,6 +67,24 @@ void dma_direct_free_coherent(struct device *dev, size_t size, | |||
| 67 | #endif | 67 | #endif |
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | int dma_direct_mmap_coherent(struct device *dev, struct vm_area_struct *vma, | ||
| 71 | void *cpu_addr, dma_addr_t handle, size_t size, | ||
| 72 | struct dma_attrs *attrs) | ||
| 73 | { | ||
| 74 | unsigned long pfn; | ||
| 75 | |||
| 76 | #ifdef CONFIG_NOT_COHERENT_CACHE | ||
| 77 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | ||
| 78 | pfn = __dma_get_coherent_pfn((unsigned long)cpu_addr); | ||
| 79 | #else | ||
| 80 | pfn = page_to_pfn(virt_to_page(cpu_addr)); | ||
| 81 | #endif | ||
| 82 | return remap_pfn_range(vma, vma->vm_start, | ||
| 83 | pfn + vma->vm_pgoff, | ||
| 84 | vma->vm_end - vma->vm_start, | ||
| 85 | vma->vm_page_prot); | ||
| 86 | } | ||
| 87 | |||
| 70 | static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl, | 88 | static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl, |
| 71 | int nents, enum dma_data_direction direction, | 89 | int nents, enum dma_data_direction direction, |
| 72 | struct dma_attrs *attrs) | 90 | struct dma_attrs *attrs) |
| @@ -156,6 +174,7 @@ static inline void dma_direct_sync_single(struct device *dev, | |||
| 156 | struct dma_map_ops dma_direct_ops = { | 174 | struct dma_map_ops dma_direct_ops = { |
| 157 | .alloc = dma_direct_alloc_coherent, | 175 | .alloc = dma_direct_alloc_coherent, |
| 158 | .free = dma_direct_free_coherent, | 176 | .free = dma_direct_free_coherent, |
| 177 | .mmap = dma_direct_mmap_coherent, | ||
| 159 | .map_sg = dma_direct_map_sg, | 178 | .map_sg = dma_direct_map_sg, |
| 160 | .unmap_sg = dma_direct_unmap_sg, | 179 | .unmap_sg = dma_direct_unmap_sg, |
| 161 | .dma_supported = dma_direct_dma_supported, | 180 | .dma_supported = dma_direct_dma_supported, |
| @@ -219,20 +238,3 @@ static int __init dma_init(void) | |||
| 219 | } | 238 | } |
| 220 | fs_initcall(dma_init); | 239 | fs_initcall(dma_init); |
| 221 | 240 | ||
| 222 | int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma, | ||
| 223 | void *cpu_addr, dma_addr_t handle, size_t size) | ||
| 224 | { | ||
| 225 | unsigned long pfn; | ||
| 226 | |||
| 227 | #ifdef CONFIG_NOT_COHERENT_CACHE | ||
| 228 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | ||
| 229 | pfn = __dma_get_coherent_pfn((unsigned long)cpu_addr); | ||
| 230 | #else | ||
| 231 | pfn = page_to_pfn(virt_to_page(cpu_addr)); | ||
| 232 | #endif | ||
| 233 | return remap_pfn_range(vma, vma->vm_start, | ||
| 234 | pfn + vma->vm_pgoff, | ||
| 235 | vma->vm_end - vma->vm_start, | ||
| 236 | vma->vm_page_prot); | ||
| 237 | } | ||
| 238 | EXPORT_SYMBOL_GPL(dma_mmap_coherent); | ||
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index 5207d5a405e2..ead5016b02d0 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S | |||
| @@ -89,10 +89,14 @@ crit_transfer_to_handler: | |||
| 89 | mfspr r0,SPRN_SRR1 | 89 | mfspr r0,SPRN_SRR1 |
| 90 | stw r0,_SRR1(r11) | 90 | stw r0,_SRR1(r11) |
| 91 | 91 | ||
| 92 | /* set the stack limit to the current stack | ||
| 93 | * and set the limit to protect the thread_info | ||
| 94 | * struct | ||
| 95 | */ | ||
| 92 | mfspr r8,SPRN_SPRG_THREAD | 96 | mfspr r8,SPRN_SPRG_THREAD |
| 93 | lwz r0,KSP_LIMIT(r8) | 97 | lwz r0,KSP_LIMIT(r8) |
| 94 | stw r0,SAVED_KSP_LIMIT(r11) | 98 | stw r0,SAVED_KSP_LIMIT(r11) |
| 95 | CURRENT_THREAD_INFO(r0, r1) | 99 | rlwimi r0,r1,0,0,(31-THREAD_SHIFT) |
| 96 | stw r0,KSP_LIMIT(r8) | 100 | stw r0,KSP_LIMIT(r8) |
| 97 | /* fall through */ | 101 | /* fall through */ |
| 98 | #endif | 102 | #endif |
| @@ -109,10 +113,14 @@ crit_transfer_to_handler: | |||
| 109 | mfspr r0,SPRN_SRR1 | 113 | mfspr r0,SPRN_SRR1 |
| 110 | stw r0,crit_srr1@l(0) | 114 | stw r0,crit_srr1@l(0) |
| 111 | 115 | ||
| 116 | /* set the stack limit to the current stack | ||
| 117 | * and set the limit to protect the thread_info | ||
| 118 | * struct | ||
| 119 | */ | ||
| 112 | mfspr r8,SPRN_SPRG_THREAD | 120 | mfspr r8,SPRN_SPRG_THREAD |
| 113 | lwz r0,KSP_LIMIT(r8) | 121 | lwz r0,KSP_LIMIT(r8) |
| 114 | stw r0,saved_ksp_limit@l(0) | 122 | stw r0,saved_ksp_limit@l(0) |
| 115 | CURRENT_THREAD_INFO(r0, r1) | 123 | rlwimi r0,r1,0,0,(31-THREAD_SHIFT) |
| 116 | stw r0,KSP_LIMIT(r8) | 124 | stw r0,KSP_LIMIT(r8) |
| 117 | /* fall through */ | 125 | /* fall through */ |
| 118 | #endif | 126 | #endif |
diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c index 91b46b7f6f0d..1fb78561096a 100644 --- a/arch/powerpc/kernel/ftrace.c +++ b/arch/powerpc/kernel/ftrace.c | |||
| @@ -630,18 +630,17 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr) | |||
| 630 | return; | 630 | return; |
| 631 | } | 631 | } |
| 632 | 632 | ||
| 633 | if (ftrace_push_return_trace(old, self_addr, &trace.depth, 0) == -EBUSY) { | ||
| 634 | *parent = old; | ||
| 635 | return; | ||
| 636 | } | ||
| 637 | |||
| 638 | trace.func = self_addr; | 633 | trace.func = self_addr; |
| 634 | trace.depth = current->curr_ret_stack + 1; | ||
| 639 | 635 | ||
| 640 | /* Only trace if the calling function expects to */ | 636 | /* Only trace if the calling function expects to */ |
| 641 | if (!ftrace_graph_entry(&trace)) { | 637 | if (!ftrace_graph_entry(&trace)) { |
| 642 | current->curr_ret_stack--; | ||
| 643 | *parent = old; | 638 | *parent = old; |
| 639 | return; | ||
| 644 | } | 640 | } |
| 641 | |||
| 642 | if (ftrace_push_return_trace(old, self_addr, &trace.depth, 0) == -EBUSY) | ||
| 643 | *parent = old; | ||
| 645 | } | 644 | } |
| 646 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ | 645 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ |
| 647 | 646 | ||
diff --git a/arch/powerpc/kernel/rtas_flash.c b/arch/powerpc/kernel/rtas_flash.c index 4174b4b23246..2c0ee6405633 100644 --- a/arch/powerpc/kernel/rtas_flash.c +++ b/arch/powerpc/kernel/rtas_flash.c | |||
| @@ -709,7 +709,7 @@ static int __init rtas_flash_init(void) | |||
| 709 | 709 | ||
| 710 | if (rtas_token("ibm,update-flash-64-and-reboot") == | 710 | if (rtas_token("ibm,update-flash-64-and-reboot") == |
| 711 | RTAS_UNKNOWN_SERVICE) { | 711 | RTAS_UNKNOWN_SERVICE) { |
| 712 | printk(KERN_ERR "rtas_flash: no firmware flash support\n"); | 712 | pr_info("rtas_flash: no firmware flash support\n"); |
| 713 | return 1; | 713 | return 1; |
| 714 | } | 714 | } |
| 715 | 715 | ||
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index 3052a931f2b5..02b32216bbc3 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c | |||
| @@ -611,6 +611,7 @@ static u64 vio_dma_get_required_mask(struct device *dev) | |||
| 611 | struct dma_map_ops vio_dma_mapping_ops = { | 611 | struct dma_map_ops vio_dma_mapping_ops = { |
| 612 | .alloc = vio_dma_iommu_alloc_coherent, | 612 | .alloc = vio_dma_iommu_alloc_coherent, |
| 613 | .free = vio_dma_iommu_free_coherent, | 613 | .free = vio_dma_iommu_free_coherent, |
| 614 | .mmap = dma_direct_mmap_coherent, | ||
| 614 | .map_sg = vio_dma_iommu_map_sg, | 615 | .map_sg = vio_dma_iommu_map_sg, |
| 615 | .unmap_sg = vio_dma_iommu_unmap_sg, | 616 | .unmap_sg = vio_dma_iommu_unmap_sg, |
| 616 | .map_page = vio_dma_iommu_map_page, | 617 | .map_page = vio_dma_iommu_map_page, |
diff --git a/arch/powerpc/kvm/book3s_rmhandlers.S b/arch/powerpc/kvm/book3s_rmhandlers.S index ab523f3c1731..9ecf6e35cd8d 100644 --- a/arch/powerpc/kvm/book3s_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_rmhandlers.S | |||
| @@ -67,7 +67,6 @@ kvmppc_skip_Hinterrupt: | |||
| 67 | #elif defined(CONFIG_PPC_BOOK3S_32) | 67 | #elif defined(CONFIG_PPC_BOOK3S_32) |
| 68 | 68 | ||
| 69 | #define FUNC(name) name | 69 | #define FUNC(name) name |
| 70 | #define MTMSR_EERI(reg) mtmsr (reg) | ||
| 71 | 70 | ||
| 72 | .macro INTERRUPT_TRAMPOLINE intno | 71 | .macro INTERRUPT_TRAMPOLINE intno |
| 73 | 72 | ||
diff --git a/arch/powerpc/kvm/bookehv_interrupts.S b/arch/powerpc/kvm/bookehv_interrupts.S index d28c2d43ac1b..099fe8272b57 100644 --- a/arch/powerpc/kvm/bookehv_interrupts.S +++ b/arch/powerpc/kvm/bookehv_interrupts.S | |||
| @@ -50,8 +50,9 @@ | |||
| 50 | #define HOST_R2 (3 * LONGBYTES) | 50 | #define HOST_R2 (3 * LONGBYTES) |
| 51 | #define HOST_CR (4 * LONGBYTES) | 51 | #define HOST_CR (4 * LONGBYTES) |
| 52 | #define HOST_NV_GPRS (5 * LONGBYTES) | 52 | #define HOST_NV_GPRS (5 * LONGBYTES) |
| 53 | #define HOST_NV_GPR(n) (HOST_NV_GPRS + ((n - 14) * LONGBYTES)) | 53 | #define __HOST_NV_GPR(n) (HOST_NV_GPRS + ((n - 14) * LONGBYTES)) |
| 54 | #define HOST_MIN_STACK_SIZE (HOST_NV_GPR(31) + LONGBYTES) | 54 | #define HOST_NV_GPR(n) __HOST_NV_GPR(__REG_##n) |
| 55 | #define HOST_MIN_STACK_SIZE (HOST_NV_GPR(R31) + LONGBYTES) | ||
| 55 | #define HOST_STACK_SIZE ((HOST_MIN_STACK_SIZE + 15) & ~15) /* Align. */ | 56 | #define HOST_STACK_SIZE ((HOST_MIN_STACK_SIZE + 15) & ~15) /* Align. */ |
| 56 | #define HOST_STACK_LR (HOST_STACK_SIZE + LONGBYTES) /* In caller stack frame. */ | 57 | #define HOST_STACK_LR (HOST_STACK_SIZE + LONGBYTES) /* In caller stack frame. */ |
| 57 | 58 | ||
| @@ -410,24 +411,24 @@ heavyweight_exit: | |||
| 410 | PPC_STL r31, VCPU_GPR(R31)(r4) | 411 | PPC_STL r31, VCPU_GPR(R31)(r4) |
| 411 | 412 | ||
| 412 | /* Load host non-volatile register state from host stack. */ | 413 | /* Load host non-volatile register state from host stack. */ |
| 413 | PPC_LL r14, HOST_NV_GPR(r14)(r1) | 414 | PPC_LL r14, HOST_NV_GPR(R14)(r1) |
| 414 | PPC_LL r15, HOST_NV_GPR(r15)(r1) | 415 | PPC_LL r15, HOST_NV_GPR(R15)(r1) |
| 415 | PPC_LL r16, HOST_NV_GPR(r16)(r1) | 416 | PPC_LL r16, HOST_NV_GPR(R16)(r1) |
| 416 | PPC_LL r17, HOST_NV_GPR(r17)(r1) | 417 | PPC_LL r17, HOST_NV_GPR(R17)(r1) |
| 417 | PPC_LL r18, HOST_NV_GPR(r18)(r1) | 418 | PPC_LL r18, HOST_NV_GPR(R18)(r1) |
| 418 | PPC_LL r19, HOST_NV_GPR(r19)(r1) | 419 | PPC_LL r19, HOST_NV_GPR(R19)(r1) |
| 419 | PPC_LL r20, HOST_NV_GPR(r20)(r1) | 420 | PPC_LL r20, HOST_NV_GPR(R20)(r1) |
| 420 | PPC_LL r21, HOST_NV_GPR(r21)(r1) | 421 | PPC_LL r21, HOST_NV_GPR(R21)(r1) |
| 421 | PPC_LL r22, HOST_NV_GPR(r22)(r1) | 422 | PPC_LL r22, HOST_NV_GPR(R22)(r1) |
| 422 | PPC_LL r23, HOST_NV_GPR(r23)(r1) | 423 | PPC_LL r23, HOST_NV_GPR(R23)(r1) |
| 423 | PPC_LL r24, HOST_NV_GPR(r24)(r1) | 424 | PPC_LL r24, HOST_NV_GPR(R24)(r1) |
| 424 | PPC_LL r25, HOST_NV_GPR(r25)(r1) | 425 | PPC_LL r25, HOST_NV_GPR(R25)(r1) |
| 425 | PPC_LL r26, HOST_NV_GPR(r26)(r1) | 426 | PPC_LL r26, HOST_NV_GPR(R26)(r1) |
| 426 | PPC_LL r27, HOST_NV_GPR(r27)(r1) | 427 | PPC_LL r27, HOST_NV_GPR(R27)(r1) |
| 427 | PPC_LL r28, HOST_NV_GPR(r28)(r1) | 428 | PPC_LL r28, HOST_NV_GPR(R28)(r1) |
| 428 | PPC_LL r29, HOST_NV_GPR(r29)(r1) | 429 | PPC_LL r29, HOST_NV_GPR(R29)(r1) |
| 429 | PPC_LL r30, HOST_NV_GPR(r30)(r1) | 430 | PPC_LL r30, HOST_NV_GPR(R30)(r1) |
| 430 | PPC_LL r31, HOST_NV_GPR(r31)(r1) | 431 | PPC_LL r31, HOST_NV_GPR(R31)(r1) |
| 431 | 432 | ||
| 432 | /* Return to kvm_vcpu_run(). */ | 433 | /* Return to kvm_vcpu_run(). */ |
| 433 | mtlr r5 | 434 | mtlr r5 |
| @@ -453,24 +454,24 @@ _GLOBAL(__kvmppc_vcpu_run) | |||
| 453 | stw r5, HOST_CR(r1) | 454 | stw r5, HOST_CR(r1) |
| 454 | 455 | ||
| 455 | /* Save host non-volatile register state to stack. */ | 456 | /* Save host non-volatile register state to stack. */ |
| 456 | PPC_STL r14, HOST_NV_GPR(r14)(r1) | 457 | PPC_STL r14, HOST_NV_GPR(R14)(r1) |
| 457 | PPC_STL r15, HOST_NV_GPR(r15)(r1) | 458 | PPC_STL r15, HOST_NV_GPR(R15)(r1) |
| 458 | PPC_STL r16, HOST_NV_GPR(r16)(r1) | 459 | PPC_STL r16, HOST_NV_GPR(R16)(r1) |
| 459 | PPC_STL r17, HOST_NV_GPR(r17)(r1) | 460 | PPC_STL r17, HOST_NV_GPR(R17)(r1) |
| 460 | PPC_STL r18, HOST_NV_GPR(r18)(r1) | 461 | PPC_STL r18, HOST_NV_GPR(R18)(r1) |
| 461 | PPC_STL r19, HOST_NV_GPR(r19)(r1) | 462 | PPC_STL r19, HOST_NV_GPR(R19)(r1) |
| 462 | PPC_STL r20, HOST_NV_GPR(r20)(r1) | 463 | PPC_STL r20, HOST_NV_GPR(R20)(r1) |
| 463 | PPC_STL r21, HOST_NV_GPR(r21)(r1) | 464 | PPC_STL r21, HOST_NV_GPR(R21)(r1) |
| 464 | PPC_STL r22, HOST_NV_GPR(r22)(r1) | 465 | PPC_STL r22, HOST_NV_GPR(R22)(r1) |
| 465 | PPC_STL r23, HOST_NV_GPR(r23)(r1) | 466 | PPC_STL r23, HOST_NV_GPR(R23)(r1) |
| 466 | PPC_STL r24, HOST_NV_GPR(r24)(r1) | 467 | PPC_STL r24, HOST_NV_GPR(R24)(r1) |
| 467 | PPC_STL r25, HOST_NV_GPR(r25)(r1) | 468 | PPC_STL r25, HOST_NV_GPR(R25)(r1) |
| 468 | PPC_STL r26, HOST_NV_GPR(r26)(r1) | 469 | PPC_STL r26, HOST_NV_GPR(R26)(r1) |
| 469 | PPC_STL r27, HOST_NV_GPR(r27)(r1) | 470 | PPC_STL r27, HOST_NV_GPR(R27)(r1) |
| 470 | PPC_STL r28, HOST_NV_GPR(r28)(r1) | 471 | PPC_STL r28, HOST_NV_GPR(R28)(r1) |
| 471 | PPC_STL r29, HOST_NV_GPR(r29)(r1) | 472 | PPC_STL r29, HOST_NV_GPR(R29)(r1) |
| 472 | PPC_STL r30, HOST_NV_GPR(r30)(r1) | 473 | PPC_STL r30, HOST_NV_GPR(R30)(r1) |
| 473 | PPC_STL r31, HOST_NV_GPR(r31)(r1) | 474 | PPC_STL r31, HOST_NV_GPR(R31)(r1) |
| 474 | 475 | ||
| 475 | /* Load guest non-volatiles. */ | 476 | /* Load guest non-volatiles. */ |
| 476 | PPC_LL r14, VCPU_GPR(R14)(r4) | 477 | PPC_LL r14, VCPU_GPR(R14)(r4) |
diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c b/arch/powerpc/platforms/85xx/p1022_ds.c index 89ee02c54561..3c732acf331d 100644 --- a/arch/powerpc/platforms/85xx/p1022_ds.c +++ b/arch/powerpc/platforms/85xx/p1022_ds.c | |||
| @@ -208,6 +208,7 @@ static void p1022ds_set_monitor_port(enum fsl_diu_monitor_port port) | |||
| 208 | u8 __iomem *lbc_lcs0_ba = NULL; | 208 | u8 __iomem *lbc_lcs0_ba = NULL; |
| 209 | u8 __iomem *lbc_lcs1_ba = NULL; | 209 | u8 __iomem *lbc_lcs1_ba = NULL; |
| 210 | phys_addr_t cs0_addr, cs1_addr; | 210 | phys_addr_t cs0_addr, cs1_addr; |
| 211 | u32 br0, or0, br1, or1; | ||
| 211 | const __be32 *iprop; | 212 | const __be32 *iprop; |
| 212 | unsigned int num_laws; | 213 | unsigned int num_laws; |
| 213 | u8 b; | 214 | u8 b; |
| @@ -256,11 +257,70 @@ static void p1022ds_set_monitor_port(enum fsl_diu_monitor_port port) | |||
| 256 | } | 257 | } |
| 257 | num_laws = be32_to_cpup(iprop); | 258 | num_laws = be32_to_cpup(iprop); |
| 258 | 259 | ||
| 259 | cs0_addr = lbc_br_to_phys(ecm, num_laws, in_be32(&lbc->bank[0].br)); | 260 | /* |
| 260 | cs1_addr = lbc_br_to_phys(ecm, num_laws, in_be32(&lbc->bank[1].br)); | 261 | * Indirect mode requires both BR0 and BR1 to be set to "GPCM", |
| 262 | * otherwise writes to these addresses won't actually appear on the | ||
| 263 | * local bus, and so the PIXIS won't see them. | ||
| 264 | * | ||
| 265 | * In FCM mode, writes go to the NAND controller, which does not pass | ||
| 266 | * them to the localbus directly. So we force BR0 and BR1 into GPCM | ||
| 267 | * mode, since we don't care about what's behind the localbus any | ||
| 268 | * more. | ||
| 269 | */ | ||
| 270 | br0 = in_be32(&lbc->bank[0].br); | ||
| 271 | br1 = in_be32(&lbc->bank[1].br); | ||
| 272 | or0 = in_be32(&lbc->bank[0].or); | ||
| 273 | or1 = in_be32(&lbc->bank[1].or); | ||
| 274 | |||
| 275 | /* Make sure CS0 and CS1 are programmed */ | ||
| 276 | if (!(br0 & BR_V) || !(br1 & BR_V)) { | ||
| 277 | pr_err("p1022ds: CS0 and/or CS1 is not programmed\n"); | ||
| 278 | goto exit; | ||
| 279 | } | ||
| 280 | |||
| 281 | /* | ||
| 282 | * Use the existing BRx/ORx values if it's already GPCM. Otherwise, | ||
| 283 | * force the values to simple 32KB GPCM windows with the most | ||
| 284 | * conservative timing. | ||
| 285 | */ | ||
| 286 | if ((br0 & BR_MSEL) != BR_MS_GPCM) { | ||
| 287 | br0 = (br0 & BR_BA) | BR_V; | ||
| 288 | or0 = 0xFFFF8000 | 0xFF7; | ||
| 289 | out_be32(&lbc->bank[0].br, br0); | ||
| 290 | out_be32(&lbc->bank[0].or, or0); | ||
| 291 | } | ||
| 292 | if ((br1 & BR_MSEL) != BR_MS_GPCM) { | ||
| 293 | br1 = (br1 & BR_BA) | BR_V; | ||
| 294 | or1 = 0xFFFF8000 | 0xFF7; | ||
| 295 | out_be32(&lbc->bank[1].br, br1); | ||
| 296 | out_be32(&lbc->bank[1].or, or1); | ||
| 297 | } | ||
| 298 | |||
| 299 | cs0_addr = lbc_br_to_phys(ecm, num_laws, br0); | ||
| 300 | if (!cs0_addr) { | ||
| 301 | pr_err("p1022ds: could not determine physical address for CS0" | ||
| 302 | " (BR0=%08x)\n", br0); | ||
| 303 | goto exit; | ||
| 304 | } | ||
| 305 | cs1_addr = lbc_br_to_phys(ecm, num_laws, br1); | ||
| 306 | if (!cs0_addr) { | ||
| 307 | pr_err("p1022ds: could not determine physical address for CS1" | ||
| 308 | " (BR1=%08x)\n", br1); | ||
| 309 | goto exit; | ||
| 310 | } | ||
| 261 | 311 | ||
| 262 | lbc_lcs0_ba = ioremap(cs0_addr, 1); | 312 | lbc_lcs0_ba = ioremap(cs0_addr, 1); |
| 313 | if (!lbc_lcs0_ba) { | ||
| 314 | pr_err("p1022ds: could not ioremap CS0 address %llx\n", | ||
| 315 | (unsigned long long)cs0_addr); | ||
| 316 | goto exit; | ||
| 317 | } | ||
| 263 | lbc_lcs1_ba = ioremap(cs1_addr, 1); | 318 | lbc_lcs1_ba = ioremap(cs1_addr, 1); |
| 319 | if (!lbc_lcs1_ba) { | ||
| 320 | pr_err("p1022ds: could not ioremap CS1 address %llx\n", | ||
| 321 | (unsigned long long)cs1_addr); | ||
| 322 | goto exit; | ||
| 323 | } | ||
| 264 | 324 | ||
| 265 | /* Make sure we're in indirect mode first. */ | 325 | /* Make sure we're in indirect mode first. */ |
| 266 | if ((in_be32(&guts->pmuxcr) & PMUXCR_ELBCDIU_MASK) != | 326 | if ((in_be32(&guts->pmuxcr) & PMUXCR_ELBCDIU_MASK) != |
| @@ -419,18 +479,6 @@ void __init p1022_ds_pic_init(void) | |||
| 419 | 479 | ||
| 420 | #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE) | 480 | #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE) |
| 421 | 481 | ||
| 422 | /* | ||
| 423 | * Disables a node in the device tree. | ||
| 424 | * | ||
| 425 | * This function is called before kmalloc() is available, so the 'new' object | ||
| 426 | * should be allocated in the global area. The easiest way is to do that is | ||
| 427 | * to allocate one static local variable for each call to this function. | ||
| 428 | */ | ||
| 429 | static void __init disable_one_node(struct device_node *np, struct property *new) | ||
| 430 | { | ||
| 431 | prom_update_property(np, new); | ||
| 432 | } | ||
| 433 | |||
| 434 | /* TRUE if there is a "video=fslfb" command-line parameter. */ | 482 | /* TRUE if there is a "video=fslfb" command-line parameter. */ |
| 435 | static bool fslfb; | 483 | static bool fslfb; |
| 436 | 484 | ||
| @@ -493,28 +541,58 @@ static void __init p1022_ds_setup_arch(void) | |||
| 493 | diu_ops.valid_monitor_port = p1022ds_valid_monitor_port; | 541 | diu_ops.valid_monitor_port = p1022ds_valid_monitor_port; |
| 494 | 542 | ||
| 495 | /* | 543 | /* |
| 496 | * Disable the NOR flash node if there is video=fslfb... command-line | 544 | * Disable the NOR and NAND flash nodes if there is video=fslfb... |
| 497 | * parameter. When the DIU is active, NOR flash is unavailable, so we | 545 | * command-line parameter. When the DIU is active, the localbus is |
| 498 | * have to disable the node before the MTD driver loads. | 546 | * unavailable, so we have to disable these nodes before the MTD |
| 547 | * driver loads. | ||
| 499 | */ | 548 | */ |
| 500 | if (fslfb) { | 549 | if (fslfb) { |
| 501 | struct device_node *np = | 550 | struct device_node *np = |
| 502 | of_find_compatible_node(NULL, NULL, "fsl,p1022-elbc"); | 551 | of_find_compatible_node(NULL, NULL, "fsl,p1022-elbc"); |
| 503 | 552 | ||
| 504 | if (np) { | 553 | if (np) { |
| 505 | np = of_find_compatible_node(np, NULL, "cfi-flash"); | 554 | struct device_node *np2; |
| 506 | if (np) { | 555 | |
| 556 | of_node_get(np); | ||
| 557 | np2 = of_find_compatible_node(np, NULL, "cfi-flash"); | ||
| 558 | if (np2) { | ||
| 507 | static struct property nor_status = { | 559 | static struct property nor_status = { |
| 508 | .name = "status", | 560 | .name = "status", |
| 509 | .value = "disabled", | 561 | .value = "disabled", |
| 510 | .length = sizeof("disabled"), | 562 | .length = sizeof("disabled"), |
| 511 | }; | 563 | }; |
| 512 | 564 | ||
| 565 | /* | ||
| 566 | * prom_update_property() is called before | ||
| 567 | * kmalloc() is available, so the 'new' object | ||
| 568 | * should be allocated in the global area. | ||
| 569 | * The easiest way is to do that is to | ||
| 570 | * allocate one static local variable for each | ||
| 571 | * call to this function. | ||
| 572 | */ | ||
| 513 | pr_info("p1022ds: disabling %s node", | 573 | pr_info("p1022ds: disabling %s node", |
| 514 | np->full_name); | 574 | np2->full_name); |
| 515 | disable_one_node(np, &nor_status); | 575 | prom_update_property(np2, &nor_status); |
| 516 | of_node_put(np); | 576 | of_node_put(np2); |
| 517 | } | 577 | } |
| 578 | |||
| 579 | of_node_get(np); | ||
| 580 | np2 = of_find_compatible_node(np, NULL, | ||
| 581 | "fsl,elbc-fcm-nand"); | ||
| 582 | if (np2) { | ||
| 583 | static struct property nand_status = { | ||
| 584 | .name = "status", | ||
| 585 | .value = "disabled", | ||
| 586 | .length = sizeof("disabled"), | ||
| 587 | }; | ||
| 588 | |||
| 589 | pr_info("p1022ds: disabling %s node", | ||
| 590 | np2->full_name); | ||
| 591 | prom_update_property(np2, &nand_status); | ||
| 592 | of_node_put(np2); | ||
| 593 | } | ||
| 594 | |||
| 595 | of_node_put(np); | ||
| 518 | } | 596 | } |
| 519 | 597 | ||
| 520 | } | 598 | } |
diff --git a/arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h b/arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h index 60c9c0bd5ba2..2aa97ddb7b78 100644 --- a/arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h +++ b/arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright 2009-2010 Freescale Semiconductor, Inc | 2 | * Copyright 2009-2010, 2012 Freescale Semiconductor, Inc |
| 3 | * | 3 | * |
| 4 | * QorIQ based Cache Controller Memory Mapped Registers | 4 | * QorIQ based Cache Controller Memory Mapped Registers |
| 5 | * | 5 | * |
| @@ -91,7 +91,7 @@ struct mpc85xx_l2ctlr { | |||
| 91 | 91 | ||
| 92 | struct sram_parameters { | 92 | struct sram_parameters { |
| 93 | unsigned int sram_size; | 93 | unsigned int sram_size; |
| 94 | uint64_t sram_offset; | 94 | phys_addr_t sram_offset; |
| 95 | }; | 95 | }; |
| 96 | 96 | ||
| 97 | extern int instantiate_cache_sram(struct platform_device *dev, | 97 | extern int instantiate_cache_sram(struct platform_device *dev, |
diff --git a/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c b/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c index cedabd0f4bfe..68ac3aacb191 100644 --- a/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c +++ b/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright 2009-2010 Freescale Semiconductor, Inc. | 2 | * Copyright 2009-2010, 2012 Freescale Semiconductor, Inc. |
| 3 | * | 3 | * |
| 4 | * QorIQ (P1/P2) L2 controller init for Cache-SRAM instantiation | 4 | * QorIQ (P1/P2) L2 controller init for Cache-SRAM instantiation |
| 5 | * | 5 | * |
| @@ -31,24 +31,21 @@ static char *sram_size; | |||
| 31 | static char *sram_offset; | 31 | static char *sram_offset; |
| 32 | struct mpc85xx_l2ctlr __iomem *l2ctlr; | 32 | struct mpc85xx_l2ctlr __iomem *l2ctlr; |
| 33 | 33 | ||
| 34 | static long get_cache_sram_size(void) | 34 | static int get_cache_sram_params(struct sram_parameters *sram_params) |
| 35 | { | 35 | { |
| 36 | unsigned long val; | 36 | unsigned long long addr; |
| 37 | unsigned int size; | ||
| 37 | 38 | ||
| 38 | if (!sram_size || (strict_strtoul(sram_size, 0, &val) < 0)) | 39 | if (!sram_size || (kstrtouint(sram_size, 0, &size) < 0)) |
| 39 | return -EINVAL; | 40 | return -EINVAL; |
| 40 | 41 | ||
| 41 | return val; | 42 | if (!sram_offset || (kstrtoull(sram_offset, 0, &addr) < 0)) |
| 42 | } | ||
| 43 | |||
| 44 | static long get_cache_sram_offset(void) | ||
| 45 | { | ||
| 46 | unsigned long val; | ||
| 47 | |||
| 48 | if (!sram_offset || (strict_strtoul(sram_offset, 0, &val) < 0)) | ||
| 49 | return -EINVAL; | 43 | return -EINVAL; |
| 50 | 44 | ||
| 51 | return val; | 45 | sram_params->sram_offset = addr; |
| 46 | sram_params->sram_size = size; | ||
| 47 | |||
| 48 | return 0; | ||
| 52 | } | 49 | } |
| 53 | 50 | ||
| 54 | static int __init get_size_from_cmdline(char *str) | 51 | static int __init get_size_from_cmdline(char *str) |
| @@ -93,17 +90,9 @@ static int __devinit mpc85xx_l2ctlr_of_probe(struct platform_device *dev) | |||
| 93 | } | 90 | } |
| 94 | l2cache_size = *prop; | 91 | l2cache_size = *prop; |
| 95 | 92 | ||
| 96 | sram_params.sram_size = get_cache_sram_size(); | 93 | if (get_cache_sram_params(&sram_params)) { |
| 97 | if ((int)sram_params.sram_size <= 0) { | ||
| 98 | dev_err(&dev->dev, | ||
| 99 | "Entire L2 as cache, Aborting Cache-SRAM stuff\n"); | ||
| 100 | return -EINVAL; | ||
| 101 | } | ||
| 102 | |||
| 103 | sram_params.sram_offset = get_cache_sram_offset(); | ||
| 104 | if ((int64_t)sram_params.sram_offset <= 0) { | ||
| 105 | dev_err(&dev->dev, | 94 | dev_err(&dev->dev, |
| 106 | "Entire L2 as cache, provide a valid sram offset\n"); | 95 | "Entire L2 as cache, provide valid sram offset and size\n"); |
| 107 | return -EINVAL; | 96 | return -EINVAL; |
| 108 | } | 97 | } |
| 109 | 98 | ||
| @@ -125,14 +114,14 @@ static int __devinit mpc85xx_l2ctlr_of_probe(struct platform_device *dev) | |||
| 125 | * Write bits[0-17] to srbar0 | 114 | * Write bits[0-17] to srbar0 |
| 126 | */ | 115 | */ |
| 127 | out_be32(&l2ctlr->srbar0, | 116 | out_be32(&l2ctlr->srbar0, |
| 128 | sram_params.sram_offset & L2SRAM_BAR_MSK_LO18); | 117 | lower_32_bits(sram_params.sram_offset) & L2SRAM_BAR_MSK_LO18); |
| 129 | 118 | ||
| 130 | /* | 119 | /* |
| 131 | * Write bits[18-21] to srbare0 | 120 | * Write bits[18-21] to srbare0 |
| 132 | */ | 121 | */ |
| 133 | #ifdef CONFIG_PHYS_64BIT | 122 | #ifdef CONFIG_PHYS_64BIT |
| 134 | out_be32(&l2ctlr->srbarea0, | 123 | out_be32(&l2ctlr->srbarea0, |
| 135 | (sram_params.sram_offset >> 32) & L2SRAM_BARE_MSK_HI4); | 124 | upper_32_bits(sram_params.sram_offset) & L2SRAM_BARE_MSK_HI4); |
| 136 | #endif | 125 | #endif |
| 137 | 126 | ||
| 138 | clrsetbits_be32(&l2ctlr->ctl, L2CR_L2E, L2CR_L2FI); | 127 | clrsetbits_be32(&l2ctlr->ctl, L2CR_L2E, L2CR_L2FI); |
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index a39b4690c171..76de6b68487c 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig | |||
| @@ -85,10 +85,12 @@ config S390 | |||
| 85 | select HAVE_ARCH_MUTEX_CPU_RELAX | 85 | select HAVE_ARCH_MUTEX_CPU_RELAX |
| 86 | select HAVE_ARCH_JUMP_LABEL if !MARCH_G5 | 86 | select HAVE_ARCH_JUMP_LABEL if !MARCH_G5 |
| 87 | select ARCH_SAVE_PAGE_KEYS if HIBERNATION | 87 | select ARCH_SAVE_PAGE_KEYS if HIBERNATION |
| 88 | select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE | ||
| 88 | select HAVE_MEMBLOCK | 89 | select HAVE_MEMBLOCK |
| 89 | select HAVE_MEMBLOCK_NODE_MAP | 90 | select HAVE_MEMBLOCK_NODE_MAP |
| 90 | select HAVE_CMPXCHG_LOCAL | 91 | select HAVE_CMPXCHG_LOCAL |
| 91 | select ARCH_DISCARD_MEMBLOCK | 92 | select ARCH_DISCARD_MEMBLOCK |
| 93 | select BUILDTIME_EXTABLE_SORT | ||
| 92 | select ARCH_INLINE_SPIN_TRYLOCK | 94 | select ARCH_INLINE_SPIN_TRYLOCK |
| 93 | select ARCH_INLINE_SPIN_TRYLOCK_BH | 95 | select ARCH_INLINE_SPIN_TRYLOCK_BH |
| 94 | select ARCH_INLINE_SPIN_LOCK | 96 | select ARCH_INLINE_SPIN_LOCK |
| @@ -117,6 +119,7 @@ config S390 | |||
| 117 | select ARCH_INLINE_WRITE_UNLOCK_BH | 119 | select ARCH_INLINE_WRITE_UNLOCK_BH |
| 118 | select ARCH_INLINE_WRITE_UNLOCK_IRQ | 120 | select ARCH_INLINE_WRITE_UNLOCK_IRQ |
| 119 | select ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE | 121 | select ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE |
| 122 | select ARCH_WANT_IPC_PARSE_VERSION | ||
| 120 | select GENERIC_SMP_IDLE_THREAD | 123 | select GENERIC_SMP_IDLE_THREAD |
| 121 | select GENERIC_TIME_VSYSCALL | 124 | select GENERIC_TIME_VSYSCALL |
| 122 | select GENERIC_CLOCKEVENTS | 125 | select GENERIC_CLOCKEVENTS |
diff --git a/arch/s390/crypto/crypto_des.h b/arch/s390/crypto/crypto_des.h deleted file mode 100644 index 6210457ceebb..000000000000 --- a/arch/s390/crypto/crypto_des.h +++ /dev/null | |||
| @@ -1,18 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Cryptographic API. | ||
| 3 | * | ||
| 4 | * Function for checking keys for the DES and Tripple DES Encryption | ||
| 5 | * algorithms. | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License as published by | ||
| 9 | * the Free Software Foundation; either version 2 of the License, or | ||
| 10 | * (at your option) any later version. | ||
| 11 | * | ||
| 12 | */ | ||
| 13 | #ifndef __CRYPTO_DES_H__ | ||
| 14 | #define __CRYPTO_DES_H__ | ||
| 15 | |||
| 16 | extern int crypto_des_check_key(const u8*, unsigned int, u32*); | ||
| 17 | |||
| 18 | #endif /*__CRYPTO_DES_H__*/ | ||
diff --git a/arch/s390/defconfig b/arch/s390/defconfig index 37d2bf267964..f39cd710980b 100644 --- a/arch/s390/defconfig +++ b/arch/s390/defconfig | |||
| @@ -7,13 +7,16 @@ CONFIG_TASK_DELAY_ACCT=y | |||
| 7 | CONFIG_TASK_XACCT=y | 7 | CONFIG_TASK_XACCT=y |
| 8 | CONFIG_TASK_IO_ACCOUNTING=y | 8 | CONFIG_TASK_IO_ACCOUNTING=y |
| 9 | CONFIG_AUDIT=y | 9 | CONFIG_AUDIT=y |
| 10 | CONFIG_NO_HZ=y | ||
| 11 | CONFIG_HIGH_RES_TIMERS=y | ||
| 12 | CONFIG_RCU_FAST_NO_HZ=y | ||
| 10 | CONFIG_IKCONFIG=y | 13 | CONFIG_IKCONFIG=y |
| 11 | CONFIG_IKCONFIG_PROC=y | 14 | CONFIG_IKCONFIG_PROC=y |
| 12 | CONFIG_CGROUPS=y | 15 | CONFIG_CGROUPS=y |
| 13 | CONFIG_CPUSETS=y | 16 | CONFIG_CPUSETS=y |
| 14 | CONFIG_CGROUP_CPUACCT=y | 17 | CONFIG_CGROUP_CPUACCT=y |
| 15 | CONFIG_RESOURCE_COUNTERS=y | 18 | CONFIG_RESOURCE_COUNTERS=y |
| 16 | CONFIG_CGROUP_MEM_RES_CTLR=y | 19 | CONFIG_CGROUP_MEMCG=y |
| 17 | CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y | 20 | CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y |
| 18 | CONFIG_CGROUP_SCHED=y | 21 | CONFIG_CGROUP_SCHED=y |
| 19 | CONFIG_RT_GROUP_SCHED=y | 22 | CONFIG_RT_GROUP_SCHED=y |
| @@ -35,8 +38,6 @@ CONFIG_MODVERSIONS=y | |||
| 35 | CONFIG_PARTITION_ADVANCED=y | 38 | CONFIG_PARTITION_ADVANCED=y |
| 36 | CONFIG_IBM_PARTITION=y | 39 | CONFIG_IBM_PARTITION=y |
| 37 | CONFIG_DEFAULT_DEADLINE=y | 40 | CONFIG_DEFAULT_DEADLINE=y |
| 38 | CONFIG_NO_HZ=y | ||
| 39 | CONFIG_HIGH_RES_TIMERS=y | ||
| 40 | CONFIG_PREEMPT=y | 41 | CONFIG_PREEMPT=y |
| 41 | CONFIG_MEMORY_HOTPLUG=y | 42 | CONFIG_MEMORY_HOTPLUG=y |
| 42 | CONFIG_MEMORY_HOTREMOVE=y | 43 | CONFIG_MEMORY_HOTREMOVE=y |
diff --git a/arch/s390/include/asm/mmu_context.h b/arch/s390/include/asm/mmu_context.h index 5c63615f1349..b749c5733657 100644 --- a/arch/s390/include/asm/mmu_context.h +++ b/arch/s390/include/asm/mmu_context.h | |||
| @@ -11,7 +11,6 @@ | |||
| 11 | #include <asm/uaccess.h> | 11 | #include <asm/uaccess.h> |
| 12 | #include <asm/tlbflush.h> | 12 | #include <asm/tlbflush.h> |
| 13 | #include <asm/ctl_reg.h> | 13 | #include <asm/ctl_reg.h> |
| 14 | #include <asm-generic/mm_hooks.h> | ||
| 15 | 14 | ||
| 16 | static inline int init_new_context(struct task_struct *tsk, | 15 | static inline int init_new_context(struct task_struct *tsk, |
| 17 | struct mm_struct *mm) | 16 | struct mm_struct *mm) |
| @@ -58,7 +57,7 @@ static inline void update_mm(struct mm_struct *mm, struct task_struct *tsk) | |||
| 58 | pgd_t *pgd = mm->pgd; | 57 | pgd_t *pgd = mm->pgd; |
| 59 | 58 | ||
| 60 | S390_lowcore.user_asce = mm->context.asce_bits | __pa(pgd); | 59 | S390_lowcore.user_asce = mm->context.asce_bits | __pa(pgd); |
| 61 | if (user_mode != HOME_SPACE_MODE) { | 60 | if (addressing_mode != HOME_SPACE_MODE) { |
| 62 | /* Load primary space page table origin. */ | 61 | /* Load primary space page table origin. */ |
| 63 | asm volatile(LCTL_OPCODE" 1,1,%0\n" | 62 | asm volatile(LCTL_OPCODE" 1,1,%0\n" |
| 64 | : : "m" (S390_lowcore.user_asce) ); | 63 | : : "m" (S390_lowcore.user_asce) ); |
| @@ -91,4 +90,17 @@ static inline void activate_mm(struct mm_struct *prev, | |||
| 91 | switch_mm(prev, next, current); | 90 | switch_mm(prev, next, current); |
| 92 | } | 91 | } |
| 93 | 92 | ||
| 93 | static inline void arch_dup_mmap(struct mm_struct *oldmm, | ||
| 94 | struct mm_struct *mm) | ||
| 95 | { | ||
| 96 | #ifdef CONFIG_64BIT | ||
| 97 | if (oldmm->context.asce_limit < mm->context.asce_limit) | ||
| 98 | crst_table_downgrade(mm, oldmm->context.asce_limit); | ||
| 99 | #endif | ||
| 100 | } | ||
| 101 | |||
| 102 | static inline void arch_exit_mmap(struct mm_struct *mm) | ||
| 103 | { | ||
| 104 | } | ||
| 105 | |||
| 94 | #endif /* __S390_MMU_CONTEXT_H */ | 106 | #endif /* __S390_MMU_CONTEXT_H */ |
diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index c40fa91e38a8..11e4e3236937 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h | |||
| @@ -120,7 +120,9 @@ struct stack_frame { | |||
| 120 | regs->psw.mask = psw_user_bits | PSW_MASK_BA; \ | 120 | regs->psw.mask = psw_user_bits | PSW_MASK_BA; \ |
| 121 | regs->psw.addr = new_psw | PSW_ADDR_AMODE; \ | 121 | regs->psw.addr = new_psw | PSW_ADDR_AMODE; \ |
| 122 | regs->gprs[15] = new_stackp; \ | 122 | regs->gprs[15] = new_stackp; \ |
| 123 | __tlb_flush_mm(current->mm); \ | ||
| 123 | crst_table_downgrade(current->mm, 1UL << 31); \ | 124 | crst_table_downgrade(current->mm, 1UL << 31); \ |
| 125 | update_mm(current->mm, current); \ | ||
| 124 | } while (0) | 126 | } while (0) |
| 125 | 127 | ||
| 126 | /* Forward declaration, a strange C thing */ | 128 | /* Forward declaration, a strange C thing */ |
diff --git a/arch/s390/include/asm/setup.h b/arch/s390/include/asm/setup.h index 57e80534375a..e6859d16ee2d 100644 --- a/arch/s390/include/asm/setup.h +++ b/arch/s390/include/asm/setup.h | |||
| @@ -60,7 +60,7 @@ void create_mem_hole(struct mem_chunk memory_chunk[], unsigned long addr, | |||
| 60 | #define SECONDARY_SPACE_MODE 2 | 60 | #define SECONDARY_SPACE_MODE 2 |
| 61 | #define HOME_SPACE_MODE 3 | 61 | #define HOME_SPACE_MODE 3 |
| 62 | 62 | ||
| 63 | extern unsigned int user_mode; | 63 | extern unsigned int addressing_mode; |
| 64 | 64 | ||
| 65 | /* | 65 | /* |
| 66 | * Machine features detected in head.S | 66 | * Machine features detected in head.S |
diff --git a/arch/s390/include/asm/unistd.h b/arch/s390/include/asm/unistd.h index 2e37157ba6a9..6756e78f4808 100644 --- a/arch/s390/include/asm/unistd.h +++ b/arch/s390/include/asm/unistd.h | |||
| @@ -388,7 +388,6 @@ | |||
| 388 | #define __IGNORE_recvmmsg | 388 | #define __IGNORE_recvmmsg |
| 389 | #define __IGNORE_sendmmsg | 389 | #define __IGNORE_sendmmsg |
| 390 | 390 | ||
| 391 | #define __ARCH_WANT_IPC_PARSE_VERSION | ||
| 392 | #define __ARCH_WANT_OLD_READDIR | 391 | #define __ARCH_WANT_OLD_READDIR |
| 393 | #define __ARCH_WANT_SYS_ALARM | 392 | #define __ARCH_WANT_SYS_ALARM |
| 394 | #define __ARCH_WANT_SYS_GETHOSTNAME | 393 | #define __ARCH_WANT_SYS_GETHOSTNAME |
diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c index 21be961e8a43..ba500d8dc392 100644 --- a/arch/s390/kernel/debug.c +++ b/arch/s390/kernel/debug.c | |||
| @@ -110,6 +110,7 @@ struct debug_view debug_raw_view = { | |||
| 110 | NULL, | 110 | NULL, |
| 111 | NULL | 111 | NULL |
| 112 | }; | 112 | }; |
| 113 | EXPORT_SYMBOL(debug_raw_view); | ||
| 113 | 114 | ||
| 114 | struct debug_view debug_hex_ascii_view = { | 115 | struct debug_view debug_hex_ascii_view = { |
| 115 | "hex_ascii", | 116 | "hex_ascii", |
| @@ -119,6 +120,7 @@ struct debug_view debug_hex_ascii_view = { | |||
| 119 | NULL, | 120 | NULL, |
| 120 | NULL | 121 | NULL |
| 121 | }; | 122 | }; |
| 123 | EXPORT_SYMBOL(debug_hex_ascii_view); | ||
| 122 | 124 | ||
| 123 | static struct debug_view debug_level_view = { | 125 | static struct debug_view debug_level_view = { |
| 124 | "level", | 126 | "level", |
| @@ -155,6 +157,7 @@ struct debug_view debug_sprintf_view = { | |||
| 155 | NULL, | 157 | NULL, |
| 156 | NULL | 158 | NULL |
| 157 | }; | 159 | }; |
| 160 | EXPORT_SYMBOL(debug_sprintf_view); | ||
| 158 | 161 | ||
| 159 | /* used by dump analysis tools to determine version of debug feature */ | 162 | /* used by dump analysis tools to determine version of debug feature */ |
| 160 | static unsigned int __used debug_feature_version = __DEBUG_FEATURE_VERSION; | 163 | static unsigned int __used debug_feature_version = __DEBUG_FEATURE_VERSION; |
| @@ -730,6 +733,7 @@ debug_info_t *debug_register(const char *name, int pages_per_area, | |||
| 730 | return debug_register_mode(name, pages_per_area, nr_areas, buf_size, | 733 | return debug_register_mode(name, pages_per_area, nr_areas, buf_size, |
| 731 | S_IRUSR | S_IWUSR, 0, 0); | 734 | S_IRUSR | S_IWUSR, 0, 0); |
| 732 | } | 735 | } |
| 736 | EXPORT_SYMBOL(debug_register); | ||
| 733 | 737 | ||
| 734 | /* | 738 | /* |
| 735 | * debug_unregister: | 739 | * debug_unregister: |
| @@ -748,6 +752,7 @@ debug_unregister(debug_info_t * id) | |||
| 748 | out: | 752 | out: |
| 749 | return; | 753 | return; |
| 750 | } | 754 | } |
| 755 | EXPORT_SYMBOL(debug_unregister); | ||
| 751 | 756 | ||
| 752 | /* | 757 | /* |
| 753 | * debug_set_size: | 758 | * debug_set_size: |
| @@ -810,7 +815,7 @@ debug_set_level(debug_info_t* id, int new_level) | |||
| 810 | } | 815 | } |
| 811 | spin_unlock_irqrestore(&id->lock,flags); | 816 | spin_unlock_irqrestore(&id->lock,flags); |
| 812 | } | 817 | } |
| 813 | 818 | EXPORT_SYMBOL(debug_set_level); | |
| 814 | 819 | ||
| 815 | /* | 820 | /* |
| 816 | * proceed_active_entry: | 821 | * proceed_active_entry: |
| @@ -930,7 +935,7 @@ debug_stop_all(void) | |||
| 930 | if (debug_stoppable) | 935 | if (debug_stoppable) |
| 931 | debug_active = 0; | 936 | debug_active = 0; |
| 932 | } | 937 | } |
| 933 | 938 | EXPORT_SYMBOL(debug_stop_all); | |
| 934 | 939 | ||
| 935 | void debug_set_critical(void) | 940 | void debug_set_critical(void) |
| 936 | { | 941 | { |
| @@ -963,6 +968,7 @@ debug_event_common(debug_info_t * id, int level, const void *buf, int len) | |||
| 963 | 968 | ||
| 964 | return active; | 969 | return active; |
| 965 | } | 970 | } |
| 971 | EXPORT_SYMBOL(debug_event_common); | ||
| 966 | 972 | ||
| 967 | /* | 973 | /* |
| 968 | * debug_exception_common: | 974 | * debug_exception_common: |
| @@ -990,6 +996,7 @@ debug_entry_t | |||
| 990 | 996 | ||
| 991 | return active; | 997 | return active; |
| 992 | } | 998 | } |
| 999 | EXPORT_SYMBOL(debug_exception_common); | ||
| 993 | 1000 | ||
| 994 | /* | 1001 | /* |
| 995 | * counts arguments in format string for sprintf view | 1002 | * counts arguments in format string for sprintf view |
| @@ -1043,6 +1050,7 @@ debug_sprintf_event(debug_info_t* id, int level,char *string,...) | |||
| 1043 | 1050 | ||
| 1044 | return active; | 1051 | return active; |
| 1045 | } | 1052 | } |
| 1053 | EXPORT_SYMBOL(debug_sprintf_event); | ||
| 1046 | 1054 | ||
| 1047 | /* | 1055 | /* |
| 1048 | * debug_sprintf_exception: | 1056 | * debug_sprintf_exception: |
| @@ -1081,25 +1089,7 @@ debug_sprintf_exception(debug_info_t* id, int level,char *string,...) | |||
| 1081 | 1089 | ||
| 1082 | return active; | 1090 | return active; |
| 1083 | } | 1091 | } |
| 1084 | 1092 | EXPORT_SYMBOL(debug_sprintf_exception); | |
| 1085 | /* | ||
| 1086 | * debug_init: | ||
| 1087 | * - is called exactly once to initialize the debug feature | ||
| 1088 | */ | ||
| 1089 | |||
| 1090 | static int | ||
| 1091 | __init debug_init(void) | ||
| 1092 | { | ||
| 1093 | int rc = 0; | ||
| 1094 | |||
| 1095 | s390dbf_sysctl_header = register_sysctl_table(s390dbf_dir_table); | ||
| 1096 | mutex_lock(&debug_mutex); | ||
| 1097 | debug_debugfs_root_entry = debugfs_create_dir(DEBUG_DIR_ROOT,NULL); | ||
| 1098 | initialized = 1; | ||
| 1099 | mutex_unlock(&debug_mutex); | ||
| 1100 | |||
| 1101 | return rc; | ||
| 1102 | } | ||
| 1103 | 1093 | ||
| 1104 | /* | 1094 | /* |
| 1105 | * debug_register_view: | 1095 | * debug_register_view: |
| @@ -1147,6 +1137,7 @@ debug_register_view(debug_info_t * id, struct debug_view *view) | |||
| 1147 | out: | 1137 | out: |
| 1148 | return rc; | 1138 | return rc; |
| 1149 | } | 1139 | } |
| 1140 | EXPORT_SYMBOL(debug_register_view); | ||
| 1150 | 1141 | ||
| 1151 | /* | 1142 | /* |
| 1152 | * debug_unregister_view: | 1143 | * debug_unregister_view: |
| @@ -1176,6 +1167,7 @@ debug_unregister_view(debug_info_t * id, struct debug_view *view) | |||
| 1176 | out: | 1167 | out: |
| 1177 | return rc; | 1168 | return rc; |
| 1178 | } | 1169 | } |
| 1170 | EXPORT_SYMBOL(debug_unregister_view); | ||
| 1179 | 1171 | ||
| 1180 | static inline char * | 1172 | static inline char * |
| 1181 | debug_get_user_string(const char __user *user_buf, size_t user_len) | 1173 | debug_get_user_string(const char __user *user_buf, size_t user_len) |
| @@ -1485,6 +1477,7 @@ debug_dflt_header_fn(debug_info_t * id, struct debug_view *view, | |||
| 1485 | except_str, entry->id.fields.cpuid, (void *) caller); | 1477 | except_str, entry->id.fields.cpuid, (void *) caller); |
| 1486 | return rc; | 1478 | return rc; |
| 1487 | } | 1479 | } |
| 1480 | EXPORT_SYMBOL(debug_dflt_header_fn); | ||
| 1488 | 1481 | ||
| 1489 | /* | 1482 | /* |
| 1490 | * prints debug data sprintf-formated: | 1483 | * prints debug data sprintf-formated: |
| @@ -1533,33 +1526,16 @@ out: | |||
| 1533 | } | 1526 | } |
| 1534 | 1527 | ||
| 1535 | /* | 1528 | /* |
| 1536 | * clean up module | 1529 | * debug_init: |
| 1530 | * - is called exactly once to initialize the debug feature | ||
| 1537 | */ | 1531 | */ |
| 1538 | static void __exit debug_exit(void) | 1532 | static int __init debug_init(void) |
| 1539 | { | 1533 | { |
| 1540 | debugfs_remove(debug_debugfs_root_entry); | 1534 | s390dbf_sysctl_header = register_sysctl_table(s390dbf_dir_table); |
| 1541 | unregister_sysctl_table(s390dbf_sysctl_header); | 1535 | mutex_lock(&debug_mutex); |
| 1542 | return; | 1536 | debug_debugfs_root_entry = debugfs_create_dir(DEBUG_DIR_ROOT, NULL); |
| 1537 | initialized = 1; | ||
| 1538 | mutex_unlock(&debug_mutex); | ||
| 1539 | return 0; | ||
| 1543 | } | 1540 | } |
| 1544 | |||
| 1545 | /* | ||
| 1546 | * module definitions | ||
| 1547 | */ | ||
| 1548 | postcore_initcall(debug_init); | 1541 | postcore_initcall(debug_init); |
| 1549 | module_exit(debug_exit); | ||
| 1550 | MODULE_LICENSE("GPL"); | ||
| 1551 | |||
| 1552 | EXPORT_SYMBOL(debug_register); | ||
| 1553 | EXPORT_SYMBOL(debug_unregister); | ||
| 1554 | EXPORT_SYMBOL(debug_set_level); | ||
| 1555 | EXPORT_SYMBOL(debug_stop_all); | ||
| 1556 | EXPORT_SYMBOL(debug_register_view); | ||
| 1557 | EXPORT_SYMBOL(debug_unregister_view); | ||
| 1558 | EXPORT_SYMBOL(debug_event_common); | ||
| 1559 | EXPORT_SYMBOL(debug_exception_common); | ||
| 1560 | EXPORT_SYMBOL(debug_hex_ascii_view); | ||
| 1561 | EXPORT_SYMBOL(debug_raw_view); | ||
| 1562 | EXPORT_SYMBOL(debug_dflt_header_fn); | ||
| 1563 | EXPORT_SYMBOL(debug_sprintf_view); | ||
| 1564 | EXPORT_SYMBOL(debug_sprintf_exception); | ||
| 1565 | EXPORT_SYMBOL(debug_sprintf_event); | ||
diff --git a/arch/s390/kernel/dis.c b/arch/s390/kernel/dis.c index 1f6b428e2762..619c5d350726 100644 --- a/arch/s390/kernel/dis.c +++ b/arch/s390/kernel/dis.c | |||
| @@ -1531,7 +1531,7 @@ static int print_insn(char *buffer, unsigned char *code, unsigned long addr) | |||
| 1531 | 1531 | ||
| 1532 | void show_code(struct pt_regs *regs) | 1532 | void show_code(struct pt_regs *regs) |
| 1533 | { | 1533 | { |
| 1534 | char *mode = (regs->psw.mask & PSW_MASK_PSTATE) ? "User" : "Krnl"; | 1534 | char *mode = user_mode(regs) ? "User" : "Krnl"; |
| 1535 | unsigned char code[64]; | 1535 | unsigned char code[64]; |
| 1536 | char buffer[64], *ptr; | 1536 | char buffer[64], *ptr; |
| 1537 | mm_segment_t old_fs; | 1537 | mm_segment_t old_fs; |
| @@ -1540,7 +1540,7 @@ void show_code(struct pt_regs *regs) | |||
| 1540 | 1540 | ||
| 1541 | /* Get a snapshot of the 64 bytes surrounding the fault address. */ | 1541 | /* Get a snapshot of the 64 bytes surrounding the fault address. */ |
| 1542 | old_fs = get_fs(); | 1542 | old_fs = get_fs(); |
| 1543 | set_fs((regs->psw.mask & PSW_MASK_PSTATE) ? USER_DS : KERNEL_DS); | 1543 | set_fs(user_mode(regs) ? USER_DS : KERNEL_DS); |
| 1544 | for (start = 32; start && regs->psw.addr >= 34 - start; start -= 2) { | 1544 | for (start = 32; start && regs->psw.addr >= 34 - start; start -= 2) { |
| 1545 | addr = regs->psw.addr - 34 + start; | 1545 | addr = regs->psw.addr - 34 + start; |
| 1546 | if (__copy_from_user(code + start - 2, | 1546 | if (__copy_from_user(code + start - 2, |
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index bc95a8ebd9cc..83c3271c442b 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c | |||
| @@ -455,7 +455,6 @@ void __init startup_init(void) | |||
| 455 | init_kernel_storage_key(); | 455 | init_kernel_storage_key(); |
| 456 | lockdep_init(); | 456 | lockdep_init(); |
| 457 | lockdep_off(); | 457 | lockdep_off(); |
| 458 | sort_main_extable(); | ||
| 459 | setup_lowcore_early(); | 458 | setup_lowcore_early(); |
| 460 | setup_facility_list(); | 459 | setup_facility_list(); |
| 461 | detect_machine_type(); | 460 | detect_machine_type(); |
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index e64d141555ce..6ffcd3203215 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c | |||
| @@ -1583,7 +1583,7 @@ static struct kset *vmcmd_kset; | |||
| 1583 | 1583 | ||
| 1584 | static void vmcmd_run(struct shutdown_trigger *trigger) | 1584 | static void vmcmd_run(struct shutdown_trigger *trigger) |
| 1585 | { | 1585 | { |
| 1586 | char *cmd, *next_cmd; | 1586 | char *cmd; |
| 1587 | 1587 | ||
| 1588 | if (strcmp(trigger->name, ON_REIPL_STR) == 0) | 1588 | if (strcmp(trigger->name, ON_REIPL_STR) == 0) |
| 1589 | cmd = vmcmd_on_reboot; | 1589 | cmd = vmcmd_on_reboot; |
| @@ -1600,15 +1600,7 @@ static void vmcmd_run(struct shutdown_trigger *trigger) | |||
| 1600 | 1600 | ||
| 1601 | if (strlen(cmd) == 0) | 1601 | if (strlen(cmd) == 0) |
| 1602 | return; | 1602 | return; |
| 1603 | do { | 1603 | __cpcmd(cmd, NULL, 0, NULL); |
| 1604 | next_cmd = strchr(cmd, '\n'); | ||
| 1605 | if (next_cmd) { | ||
| 1606 | next_cmd[0] = 0; | ||
| 1607 | next_cmd += 1; | ||
| 1608 | } | ||
| 1609 | __cpcmd(cmd, NULL, 0, NULL); | ||
| 1610 | cmd = next_cmd; | ||
| 1611 | } while (cmd != NULL); | ||
| 1612 | } | 1604 | } |
| 1613 | 1605 | ||
| 1614 | static int vmcmd_init(void) | 1606 | static int vmcmd_init(void) |
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 743c0f32fe3b..f86c81e13c37 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
| @@ -302,8 +302,8 @@ static int __init parse_vmalloc(char *arg) | |||
| 302 | } | 302 | } |
| 303 | early_param("vmalloc", parse_vmalloc); | 303 | early_param("vmalloc", parse_vmalloc); |
| 304 | 304 | ||
| 305 | unsigned int user_mode = HOME_SPACE_MODE; | 305 | unsigned int addressing_mode = HOME_SPACE_MODE; |
| 306 | EXPORT_SYMBOL_GPL(user_mode); | 306 | EXPORT_SYMBOL_GPL(addressing_mode); |
| 307 | 307 | ||
| 308 | static int set_amode_primary(void) | 308 | static int set_amode_primary(void) |
| 309 | { | 309 | { |
| @@ -328,7 +328,7 @@ static int set_amode_primary(void) | |||
| 328 | */ | 328 | */ |
| 329 | static int __init early_parse_switch_amode(char *p) | 329 | static int __init early_parse_switch_amode(char *p) |
| 330 | { | 330 | { |
| 331 | user_mode = PRIMARY_SPACE_MODE; | 331 | addressing_mode = PRIMARY_SPACE_MODE; |
| 332 | return 0; | 332 | return 0; |
| 333 | } | 333 | } |
| 334 | early_param("switch_amode", early_parse_switch_amode); | 334 | early_param("switch_amode", early_parse_switch_amode); |
| @@ -336,9 +336,9 @@ early_param("switch_amode", early_parse_switch_amode); | |||
| 336 | static int __init early_parse_user_mode(char *p) | 336 | static int __init early_parse_user_mode(char *p) |
| 337 | { | 337 | { |
| 338 | if (p && strcmp(p, "primary") == 0) | 338 | if (p && strcmp(p, "primary") == 0) |
| 339 | user_mode = PRIMARY_SPACE_MODE; | 339 | addressing_mode = PRIMARY_SPACE_MODE; |
| 340 | else if (!p || strcmp(p, "home") == 0) | 340 | else if (!p || strcmp(p, "home") == 0) |
| 341 | user_mode = HOME_SPACE_MODE; | 341 | addressing_mode = HOME_SPACE_MODE; |
| 342 | else | 342 | else |
| 343 | return 1; | 343 | return 1; |
| 344 | return 0; | 344 | return 0; |
| @@ -347,7 +347,7 @@ early_param("user_mode", early_parse_user_mode); | |||
| 347 | 347 | ||
| 348 | static void setup_addressing_mode(void) | 348 | static void setup_addressing_mode(void) |
| 349 | { | 349 | { |
| 350 | if (user_mode == PRIMARY_SPACE_MODE) { | 350 | if (addressing_mode == PRIMARY_SPACE_MODE) { |
| 351 | if (set_amode_primary()) | 351 | if (set_amode_primary()) |
| 352 | pr_info("Address spaces switched, " | 352 | pr_info("Address spaces switched, " |
| 353 | "mvcos available\n"); | 353 | "mvcos available\n"); |
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index af2421a0f315..01775c04a90e 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c | |||
| @@ -185,7 +185,7 @@ void show_registers(struct pt_regs *regs) | |||
| 185 | { | 185 | { |
| 186 | char *mode; | 186 | char *mode; |
| 187 | 187 | ||
| 188 | mode = (regs->psw.mask & PSW_MASK_PSTATE) ? "User" : "Krnl"; | 188 | mode = user_mode(regs) ? "User" : "Krnl"; |
| 189 | printk("%s PSW : %p %p", | 189 | printk("%s PSW : %p %p", |
| 190 | mode, (void *) regs->psw.mask, | 190 | mode, (void *) regs->psw.mask, |
| 191 | (void *) regs->psw.addr); | 191 | (void *) regs->psw.addr); |
| @@ -225,7 +225,7 @@ void show_regs(struct pt_regs *regs) | |||
| 225 | (void *) current->thread.ksp); | 225 | (void *) current->thread.ksp); |
| 226 | show_registers(regs); | 226 | show_registers(regs); |
| 227 | /* Show stack backtrace if pt_regs is from kernel mode */ | 227 | /* Show stack backtrace if pt_regs is from kernel mode */ |
| 228 | if (!(regs->psw.mask & PSW_MASK_PSTATE)) | 228 | if (!user_mode(regs)) |
| 229 | show_trace(NULL, (unsigned long *) regs->gprs[15]); | 229 | show_trace(NULL, (unsigned long *) regs->gprs[15]); |
| 230 | show_last_breaking_event(regs); | 230 | show_last_breaking_event(regs); |
| 231 | } | 231 | } |
| @@ -300,7 +300,7 @@ static void __kprobes do_trap(struct pt_regs *regs, | |||
| 300 | regs->int_code, si_signo) == NOTIFY_STOP) | 300 | regs->int_code, si_signo) == NOTIFY_STOP) |
| 301 | return; | 301 | return; |
| 302 | 302 | ||
| 303 | if (regs->psw.mask & PSW_MASK_PSTATE) { | 303 | if (user_mode(regs)) { |
| 304 | info.si_signo = si_signo; | 304 | info.si_signo = si_signo; |
| 305 | info.si_errno = 0; | 305 | info.si_errno = 0; |
| 306 | info.si_code = si_code; | 306 | info.si_code = si_code; |
| @@ -341,7 +341,7 @@ void __kprobes do_per_trap(struct pt_regs *regs) | |||
| 341 | 341 | ||
| 342 | static void default_trap_handler(struct pt_regs *regs) | 342 | static void default_trap_handler(struct pt_regs *regs) |
| 343 | { | 343 | { |
| 344 | if (regs->psw.mask & PSW_MASK_PSTATE) { | 344 | if (user_mode(regs)) { |
| 345 | report_user_fault(regs, SIGSEGV); | 345 | report_user_fault(regs, SIGSEGV); |
| 346 | do_exit(SIGSEGV); | 346 | do_exit(SIGSEGV); |
| 347 | } else | 347 | } else |
| @@ -410,7 +410,7 @@ static void __kprobes illegal_op(struct pt_regs *regs) | |||
| 410 | 410 | ||
| 411 | location = get_psw_address(regs); | 411 | location = get_psw_address(regs); |
| 412 | 412 | ||
| 413 | if (regs->psw.mask & PSW_MASK_PSTATE) { | 413 | if (user_mode(regs)) { |
| 414 | if (get_user(*((__u16 *) opcode), (__u16 __user *) location)) | 414 | if (get_user(*((__u16 *) opcode), (__u16 __user *) location)) |
| 415 | return; | 415 | return; |
| 416 | if (*((__u16 *) opcode) == S390_BREAKPOINT_U16) { | 416 | if (*((__u16 *) opcode) == S390_BREAKPOINT_U16) { |
| @@ -478,7 +478,7 @@ void specification_exception(struct pt_regs *regs) | |||
| 478 | 478 | ||
| 479 | location = (__u16 __user *) get_psw_address(regs); | 479 | location = (__u16 __user *) get_psw_address(regs); |
| 480 | 480 | ||
| 481 | if (regs->psw.mask & PSW_MASK_PSTATE) { | 481 | if (user_mode(regs)) { |
| 482 | get_user(*((__u16 *) opcode), location); | 482 | get_user(*((__u16 *) opcode), location); |
| 483 | switch (opcode[0]) { | 483 | switch (opcode[0]) { |
| 484 | case 0x28: /* LDR Rx,Ry */ | 484 | case 0x28: /* LDR Rx,Ry */ |
| @@ -531,7 +531,7 @@ static void data_exception(struct pt_regs *regs) | |||
| 531 | asm volatile("stfpc %0" : "=m" (current->thread.fp_regs.fpc)); | 531 | asm volatile("stfpc %0" : "=m" (current->thread.fp_regs.fpc)); |
| 532 | 532 | ||
| 533 | #ifdef CONFIG_MATHEMU | 533 | #ifdef CONFIG_MATHEMU |
| 534 | else if (regs->psw.mask & PSW_MASK_PSTATE) { | 534 | else if (user_mode(regs)) { |
| 535 | __u8 opcode[6]; | 535 | __u8 opcode[6]; |
| 536 | get_user(*((__u16 *) opcode), location); | 536 | get_user(*((__u16 *) opcode), location); |
| 537 | switch (opcode[0]) { | 537 | switch (opcode[0]) { |
| @@ -598,7 +598,7 @@ static void data_exception(struct pt_regs *regs) | |||
| 598 | static void space_switch_exception(struct pt_regs *regs) | 598 | static void space_switch_exception(struct pt_regs *regs) |
| 599 | { | 599 | { |
| 600 | /* Set user psw back to home space mode. */ | 600 | /* Set user psw back to home space mode. */ |
| 601 | if (regs->psw.mask & PSW_MASK_PSTATE) | 601 | if (user_mode(regs)) |
| 602 | regs->psw.mask |= PSW_ASC_HOME; | 602 | regs->psw.mask |= PSW_ASC_HOME; |
| 603 | /* Send SIGILL. */ | 603 | /* Send SIGILL. */ |
| 604 | do_trap(regs, SIGILL, ILL_PRVOPC, "space switch event"); | 604 | do_trap(regs, SIGILL, ILL_PRVOPC, "space switch event"); |
diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c index ea5590fdca3b..9a19ca367c17 100644 --- a/arch/s390/kernel/vdso.c +++ b/arch/s390/kernel/vdso.c | |||
| @@ -84,7 +84,8 @@ struct vdso_data *vdso_data = &vdso_data_store.data; | |||
| 84 | */ | 84 | */ |
| 85 | static void vdso_init_data(struct vdso_data *vd) | 85 | static void vdso_init_data(struct vdso_data *vd) |
| 86 | { | 86 | { |
| 87 | vd->ectg_available = user_mode != HOME_SPACE_MODE && test_facility(31); | 87 | vd->ectg_available = |
| 88 | addressing_mode != HOME_SPACE_MODE && test_facility(31); | ||
| 88 | } | 89 | } |
| 89 | 90 | ||
| 90 | #ifdef CONFIG_64BIT | 91 | #ifdef CONFIG_64BIT |
| @@ -101,7 +102,7 @@ int vdso_alloc_per_cpu(struct _lowcore *lowcore) | |||
| 101 | 102 | ||
| 102 | lowcore->vdso_per_cpu_data = __LC_PASTE; | 103 | lowcore->vdso_per_cpu_data = __LC_PASTE; |
| 103 | 104 | ||
| 104 | if (user_mode == HOME_SPACE_MODE || !vdso_enabled) | 105 | if (addressing_mode == HOME_SPACE_MODE || !vdso_enabled) |
| 105 | return 0; | 106 | return 0; |
| 106 | 107 | ||
| 107 | segment_table = __get_free_pages(GFP_KERNEL, SEGMENT_ORDER); | 108 | segment_table = __get_free_pages(GFP_KERNEL, SEGMENT_ORDER); |
| @@ -146,7 +147,7 @@ void vdso_free_per_cpu(struct _lowcore *lowcore) | |||
| 146 | unsigned long segment_table, page_table, page_frame; | 147 | unsigned long segment_table, page_table, page_frame; |
| 147 | u32 *psal, *aste; | 148 | u32 *psal, *aste; |
| 148 | 149 | ||
| 149 | if (user_mode == HOME_SPACE_MODE || !vdso_enabled) | 150 | if (addressing_mode == HOME_SPACE_MODE || !vdso_enabled) |
| 150 | return; | 151 | return; |
| 151 | 152 | ||
| 152 | psal = (u32 *)(addr_t) lowcore->paste[4]; | 153 | psal = (u32 *)(addr_t) lowcore->paste[4]; |
| @@ -164,7 +165,7 @@ static void vdso_init_cr5(void) | |||
| 164 | { | 165 | { |
| 165 | unsigned long cr5; | 166 | unsigned long cr5; |
| 166 | 167 | ||
| 167 | if (user_mode == HOME_SPACE_MODE || !vdso_enabled) | 168 | if (addressing_mode == HOME_SPACE_MODE || !vdso_enabled) |
| 168 | return; | 169 | return; |
| 169 | cr5 = offsetof(struct _lowcore, paste); | 170 | cr5 = offsetof(struct _lowcore, paste); |
| 170 | __ctl_load(cr5, 5, 5); | 171 | __ctl_load(cr5, 5, 5); |
diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S index 21109c63eb12..de8fa9bbd35e 100644 --- a/arch/s390/kernel/vmlinux.lds.S +++ b/arch/s390/kernel/vmlinux.lds.S | |||
| @@ -45,7 +45,7 @@ SECTIONS | |||
| 45 | 45 | ||
| 46 | .dummy : { *(.dummy) } :data | 46 | .dummy : { *(.dummy) } :data |
| 47 | 47 | ||
| 48 | RODATA | 48 | RO_DATA_SECTION(PAGE_SIZE) |
| 49 | 49 | ||
| 50 | #ifdef CONFIG_SHARED_KERNEL | 50 | #ifdef CONFIG_SHARED_KERNEL |
| 51 | . = ALIGN(0x100000); /* VM shared segments are 1MB aligned */ | 51 | . = ALIGN(0x100000); /* VM shared segments are 1MB aligned */ |
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index 6a12d1bb6e09..6c013f544146 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c | |||
| @@ -49,6 +49,7 @@ | |||
| 49 | #define VM_FAULT_BADCONTEXT 0x010000 | 49 | #define VM_FAULT_BADCONTEXT 0x010000 |
| 50 | #define VM_FAULT_BADMAP 0x020000 | 50 | #define VM_FAULT_BADMAP 0x020000 |
| 51 | #define VM_FAULT_BADACCESS 0x040000 | 51 | #define VM_FAULT_BADACCESS 0x040000 |
| 52 | #define VM_FAULT_SIGNAL 0x080000 | ||
| 52 | 53 | ||
| 53 | static unsigned long store_indication; | 54 | static unsigned long store_indication; |
| 54 | 55 | ||
| @@ -110,7 +111,7 @@ static inline int user_space_fault(unsigned long trans_exc_code) | |||
| 110 | if (trans_exc_code == 2) | 111 | if (trans_exc_code == 2) |
| 111 | /* Access via secondary space, set_fs setting decides */ | 112 | /* Access via secondary space, set_fs setting decides */ |
| 112 | return current->thread.mm_segment.ar4; | 113 | return current->thread.mm_segment.ar4; |
| 113 | if (user_mode == HOME_SPACE_MODE) | 114 | if (addressing_mode == HOME_SPACE_MODE) |
| 114 | /* User space if the access has been done via home space. */ | 115 | /* User space if the access has been done via home space. */ |
| 115 | return trans_exc_code == 3; | 116 | return trans_exc_code == 3; |
| 116 | /* | 117 | /* |
| @@ -219,7 +220,7 @@ static noinline void do_fault_error(struct pt_regs *regs, int fault) | |||
| 219 | case VM_FAULT_BADACCESS: | 220 | case VM_FAULT_BADACCESS: |
| 220 | case VM_FAULT_BADMAP: | 221 | case VM_FAULT_BADMAP: |
| 221 | /* Bad memory access. Check if it is kernel or user space. */ | 222 | /* Bad memory access. Check if it is kernel or user space. */ |
| 222 | if (regs->psw.mask & PSW_MASK_PSTATE) { | 223 | if (user_mode(regs)) { |
| 223 | /* User mode accesses just cause a SIGSEGV */ | 224 | /* User mode accesses just cause a SIGSEGV */ |
| 224 | si_code = (fault == VM_FAULT_BADMAP) ? | 225 | si_code = (fault == VM_FAULT_BADMAP) ? |
| 225 | SEGV_MAPERR : SEGV_ACCERR; | 226 | SEGV_MAPERR : SEGV_ACCERR; |
| @@ -229,15 +230,19 @@ static noinline void do_fault_error(struct pt_regs *regs, int fault) | |||
| 229 | case VM_FAULT_BADCONTEXT: | 230 | case VM_FAULT_BADCONTEXT: |
| 230 | do_no_context(regs); | 231 | do_no_context(regs); |
| 231 | break; | 232 | break; |
| 233 | case VM_FAULT_SIGNAL: | ||
| 234 | if (!user_mode(regs)) | ||
| 235 | do_no_context(regs); | ||
| 236 | break; | ||
| 232 | default: /* fault & VM_FAULT_ERROR */ | 237 | default: /* fault & VM_FAULT_ERROR */ |
| 233 | if (fault & VM_FAULT_OOM) { | 238 | if (fault & VM_FAULT_OOM) { |
| 234 | if (!(regs->psw.mask & PSW_MASK_PSTATE)) | 239 | if (!user_mode(regs)) |
| 235 | do_no_context(regs); | 240 | do_no_context(regs); |
| 236 | else | 241 | else |
| 237 | pagefault_out_of_memory(); | 242 | pagefault_out_of_memory(); |
| 238 | } else if (fault & VM_FAULT_SIGBUS) { | 243 | } else if (fault & VM_FAULT_SIGBUS) { |
| 239 | /* Kernel mode? Handle exceptions or die */ | 244 | /* Kernel mode? Handle exceptions or die */ |
| 240 | if (!(regs->psw.mask & PSW_MASK_PSTATE)) | 245 | if (!user_mode(regs)) |
| 241 | do_no_context(regs); | 246 | do_no_context(regs); |
| 242 | else | 247 | else |
| 243 | do_sigbus(regs); | 248 | do_sigbus(regs); |
| @@ -286,7 +291,7 @@ static inline int do_exception(struct pt_regs *regs, int access) | |||
| 286 | 291 | ||
| 287 | address = trans_exc_code & __FAIL_ADDR_MASK; | 292 | address = trans_exc_code & __FAIL_ADDR_MASK; |
| 288 | perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address); | 293 | perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address); |
| 289 | flags = FAULT_FLAG_ALLOW_RETRY; | 294 | flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; |
| 290 | if (access == VM_WRITE || (trans_exc_code & store_indication) == 0x400) | 295 | if (access == VM_WRITE || (trans_exc_code & store_indication) == 0x400) |
| 291 | flags |= FAULT_FLAG_WRITE; | 296 | flags |= FAULT_FLAG_WRITE; |
| 292 | down_read(&mm->mmap_sem); | 297 | down_read(&mm->mmap_sem); |
| @@ -335,6 +340,11 @@ retry: | |||
| 335 | * the fault. | 340 | * the fault. |
| 336 | */ | 341 | */ |
| 337 | fault = handle_mm_fault(mm, vma, address, flags); | 342 | fault = handle_mm_fault(mm, vma, address, flags); |
| 343 | /* No reason to continue if interrupted by SIGKILL. */ | ||
| 344 | if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) { | ||
| 345 | fault = VM_FAULT_SIGNAL; | ||
| 346 | goto out; | ||
| 347 | } | ||
| 338 | if (unlikely(fault & VM_FAULT_ERROR)) | 348 | if (unlikely(fault & VM_FAULT_ERROR)) |
| 339 | goto out_up; | 349 | goto out_up; |
| 340 | 350 | ||
| @@ -426,7 +436,7 @@ void __kprobes do_asce_exception(struct pt_regs *regs) | |||
| 426 | } | 436 | } |
| 427 | 437 | ||
| 428 | /* User mode accesses just cause a SIGSEGV */ | 438 | /* User mode accesses just cause a SIGSEGV */ |
| 429 | if (regs->psw.mask & PSW_MASK_PSTATE) { | 439 | if (user_mode(regs)) { |
| 430 | do_sigsegv(regs, SEGV_MAPERR); | 440 | do_sigsegv(regs, SEGV_MAPERR); |
| 431 | return; | 441 | return; |
| 432 | } | 442 | } |
| @@ -441,6 +451,7 @@ int __handle_fault(unsigned long uaddr, unsigned long pgm_int_code, int write) | |||
| 441 | struct pt_regs regs; | 451 | struct pt_regs regs; |
| 442 | int access, fault; | 452 | int access, fault; |
| 443 | 453 | ||
| 454 | /* Emulate a uaccess fault from kernel mode. */ | ||
| 444 | regs.psw.mask = psw_kernel_bits | PSW_MASK_DAT | PSW_MASK_MCHECK; | 455 | regs.psw.mask = psw_kernel_bits | PSW_MASK_DAT | PSW_MASK_MCHECK; |
| 445 | if (!irqs_disabled()) | 456 | if (!irqs_disabled()) |
| 446 | regs.psw.mask |= PSW_MASK_IO | PSW_MASK_EXT; | 457 | regs.psw.mask |= PSW_MASK_IO | PSW_MASK_EXT; |
| @@ -450,12 +461,12 @@ int __handle_fault(unsigned long uaddr, unsigned long pgm_int_code, int write) | |||
| 450 | regs.int_parm_long = (uaddr & PAGE_MASK) | 2; | 461 | regs.int_parm_long = (uaddr & PAGE_MASK) | 2; |
| 451 | access = write ? VM_WRITE : VM_READ; | 462 | access = write ? VM_WRITE : VM_READ; |
| 452 | fault = do_exception(®s, access); | 463 | fault = do_exception(®s, access); |
| 453 | if (unlikely(fault)) { | 464 | /* |
| 454 | if (fault & VM_FAULT_OOM) | 465 | * Since the fault happened in kernel mode while performing a uaccess |
| 455 | return -EFAULT; | 466 | * all we need to do now is emulating a fixup in case "fault" is not |
| 456 | else if (fault & VM_FAULT_SIGBUS) | 467 | * zero. |
| 457 | do_sigbus(®s); | 468 | * For the calling uaccess functions this results always in -EFAULT. |
| 458 | } | 469 | */ |
| 459 | return fault ? -EFAULT : 0; | 470 | return fault ? -EFAULT : 0; |
| 460 | } | 471 | } |
| 461 | 472 | ||
diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c index 573384256c5c..c59a5efa58b1 100644 --- a/arch/s390/mm/mmap.c +++ b/arch/s390/mm/mmap.c | |||
| @@ -103,9 +103,15 @@ void arch_pick_mmap_layout(struct mm_struct *mm) | |||
| 103 | 103 | ||
| 104 | int s390_mmap_check(unsigned long addr, unsigned long len) | 104 | int s390_mmap_check(unsigned long addr, unsigned long len) |
| 105 | { | 105 | { |
| 106 | int rc; | ||
| 107 | |||
| 106 | if (!is_compat_task() && | 108 | if (!is_compat_task() && |
| 107 | len >= TASK_SIZE && TASK_SIZE < (1UL << 53)) | 109 | len >= TASK_SIZE && TASK_SIZE < (1UL << 53)) { |
| 108 | return crst_table_upgrade(current->mm, 1UL << 53); | 110 | rc = crst_table_upgrade(current->mm, 1UL << 53); |
| 111 | if (rc) | ||
| 112 | return rc; | ||
| 113 | update_mm(current->mm, current); | ||
| 114 | } | ||
| 109 | return 0; | 115 | return 0; |
| 110 | } | 116 | } |
| 111 | 117 | ||
| @@ -125,6 +131,7 @@ s390_get_unmapped_area(struct file *filp, unsigned long addr, | |||
| 125 | rc = crst_table_upgrade(mm, 1UL << 53); | 131 | rc = crst_table_upgrade(mm, 1UL << 53); |
| 126 | if (rc) | 132 | if (rc) |
| 127 | return (unsigned long) rc; | 133 | return (unsigned long) rc; |
| 134 | update_mm(mm, current); | ||
| 128 | area = arch_get_unmapped_area(filp, addr, len, pgoff, flags); | 135 | area = arch_get_unmapped_area(filp, addr, len, pgoff, flags); |
| 129 | } | 136 | } |
| 130 | return area; | 137 | return area; |
| @@ -147,6 +154,7 @@ s390_get_unmapped_area_topdown(struct file *filp, const unsigned long addr, | |||
| 147 | rc = crst_table_upgrade(mm, 1UL << 53); | 154 | rc = crst_table_upgrade(mm, 1UL << 53); |
| 148 | if (rc) | 155 | if (rc) |
| 149 | return (unsigned long) rc; | 156 | return (unsigned long) rc; |
| 157 | update_mm(mm, current); | ||
| 150 | area = arch_get_unmapped_area_topdown(filp, addr, len, | 158 | area = arch_get_unmapped_area_topdown(filp, addr, len, |
| 151 | pgoff, flags); | 159 | pgoff, flags); |
| 152 | } | 160 | } |
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 1cab221077cc..18df31d1f2c9 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c | |||
| @@ -85,7 +85,6 @@ repeat: | |||
| 85 | crst_table_free(mm, table); | 85 | crst_table_free(mm, table); |
| 86 | if (mm->context.asce_limit < limit) | 86 | if (mm->context.asce_limit < limit) |
| 87 | goto repeat; | 87 | goto repeat; |
| 88 | update_mm(mm, current); | ||
| 89 | return 0; | 88 | return 0; |
| 90 | } | 89 | } |
| 91 | 90 | ||
| @@ -93,9 +92,6 @@ void crst_table_downgrade(struct mm_struct *mm, unsigned long limit) | |||
| 93 | { | 92 | { |
| 94 | pgd_t *pgd; | 93 | pgd_t *pgd; |
| 95 | 94 | ||
| 96 | if (mm->context.asce_limit <= limit) | ||
| 97 | return; | ||
| 98 | __tlb_flush_mm(mm); | ||
| 99 | while (mm->context.asce_limit > limit) { | 95 | while (mm->context.asce_limit > limit) { |
| 100 | pgd = mm->pgd; | 96 | pgd = mm->pgd; |
| 101 | switch (pgd_val(*pgd) & _REGION_ENTRY_TYPE_MASK) { | 97 | switch (pgd_val(*pgd) & _REGION_ENTRY_TYPE_MASK) { |
| @@ -118,7 +114,6 @@ void crst_table_downgrade(struct mm_struct *mm, unsigned long limit) | |||
| 118 | mm->task_size = mm->context.asce_limit; | 114 | mm->task_size = mm->context.asce_limit; |
| 119 | crst_table_free(mm, (unsigned long *) pgd); | 115 | crst_table_free(mm, (unsigned long *) pgd); |
| 120 | } | 116 | } |
| 121 | update_mm(mm, current); | ||
| 122 | } | 117 | } |
| 123 | #endif | 118 | #endif |
| 124 | 119 | ||
| @@ -801,7 +796,7 @@ int s390_enable_sie(void) | |||
| 801 | struct mm_struct *mm, *old_mm; | 796 | struct mm_struct *mm, *old_mm; |
| 802 | 797 | ||
| 803 | /* Do we have switched amode? If no, we cannot do sie */ | 798 | /* Do we have switched amode? If no, we cannot do sie */ |
| 804 | if (user_mode == HOME_SPACE_MODE) | 799 | if (addressing_mode == HOME_SPACE_MODE) |
| 805 | return -EINVAL; | 800 | return -EINVAL; |
| 806 | 801 | ||
| 807 | /* Do we have pgstes? if yes, we are done */ | 802 | /* Do we have pgstes? if yes, we are done */ |
diff --git a/arch/s390/oprofile/backtrace.c b/arch/s390/oprofile/backtrace.c index c82f62fb9c28..8a6811b2cdb9 100644 --- a/arch/s390/oprofile/backtrace.c +++ b/arch/s390/oprofile/backtrace.c | |||
| @@ -58,7 +58,7 @@ void s390_backtrace(struct pt_regs * const regs, unsigned int depth) | |||
| 58 | unsigned long head; | 58 | unsigned long head; |
| 59 | struct stack_frame* head_sf; | 59 | struct stack_frame* head_sf; |
| 60 | 60 | ||
| 61 | if (user_mode (regs)) | 61 | if (user_mode(regs)) |
| 62 | return; | 62 | return; |
| 63 | 63 | ||
| 64 | head = regs->gprs[15]; | 64 | head = regs->gprs[15]; |
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index a24595d83ad6..36f5141e8041 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig | |||
| @@ -21,6 +21,7 @@ config SUPERH | |||
| 21 | select HAVE_KERNEL_LZMA | 21 | select HAVE_KERNEL_LZMA |
| 22 | select HAVE_KERNEL_XZ | 22 | select HAVE_KERNEL_XZ |
| 23 | select HAVE_KERNEL_LZO | 23 | select HAVE_KERNEL_LZO |
| 24 | select ARCH_WANT_IPC_PARSE_VERSION | ||
| 24 | select HAVE_SYSCALL_TRACEPOINTS | 25 | select HAVE_SYSCALL_TRACEPOINTS |
| 25 | select HAVE_REGS_AND_STACK_ACCESS_API | 26 | select HAVE_REGS_AND_STACK_ACCESS_API |
| 26 | select HAVE_GENERIC_HARDIRQS | 27 | select HAVE_GENERIC_HARDIRQS |
| @@ -50,6 +51,7 @@ config SUPERH32 | |||
| 50 | select HAVE_DYNAMIC_FTRACE | 51 | select HAVE_DYNAMIC_FTRACE |
| 51 | select HAVE_FUNCTION_TRACE_MCOUNT_TEST | 52 | select HAVE_FUNCTION_TRACE_MCOUNT_TEST |
| 52 | select HAVE_FTRACE_NMI_ENTER if DYNAMIC_FTRACE | 53 | select HAVE_FTRACE_NMI_ENTER if DYNAMIC_FTRACE |
| 54 | select ARCH_WANT_IPC_PARSE_VERSION | ||
| 53 | select HAVE_FUNCTION_GRAPH_TRACER | 55 | select HAVE_FUNCTION_GRAPH_TRACER |
| 54 | select HAVE_ARCH_KGDB | 56 | select HAVE_ARCH_KGDB |
| 55 | select HAVE_HW_BREAKPOINT | 57 | select HAVE_HW_BREAKPOINT |
diff --git a/arch/sh/configs/apsh4ad0a_defconfig b/arch/sh/configs/apsh4ad0a_defconfig index e7583484cc07..95ae23fcfdd6 100644 --- a/arch/sh/configs/apsh4ad0a_defconfig +++ b/arch/sh/configs/apsh4ad0a_defconfig | |||
| @@ -11,7 +11,7 @@ CONFIG_CGROUP_FREEZER=y | |||
| 11 | CONFIG_CGROUP_DEVICE=y | 11 | CONFIG_CGROUP_DEVICE=y |
| 12 | CONFIG_CGROUP_CPUACCT=y | 12 | CONFIG_CGROUP_CPUACCT=y |
| 13 | CONFIG_RESOURCE_COUNTERS=y | 13 | CONFIG_RESOURCE_COUNTERS=y |
| 14 | CONFIG_CGROUP_MEM_RES_CTLR=y | 14 | CONFIG_CGROUP_MEMCG=y |
| 15 | CONFIG_BLK_CGROUP=y | 15 | CONFIG_BLK_CGROUP=y |
| 16 | CONFIG_NAMESPACES=y | 16 | CONFIG_NAMESPACES=y |
| 17 | CONFIG_BLK_DEV_INITRD=y | 17 | CONFIG_BLK_DEV_INITRD=y |
diff --git a/arch/sh/configs/sdk7786_defconfig b/arch/sh/configs/sdk7786_defconfig index 8a7dd7b59c5c..76a76a295d74 100644 --- a/arch/sh/configs/sdk7786_defconfig +++ b/arch/sh/configs/sdk7786_defconfig | |||
| @@ -18,8 +18,8 @@ CONFIG_CPUSETS=y | |||
| 18 | # CONFIG_PROC_PID_CPUSET is not set | 18 | # CONFIG_PROC_PID_CPUSET is not set |
| 19 | CONFIG_CGROUP_CPUACCT=y | 19 | CONFIG_CGROUP_CPUACCT=y |
| 20 | CONFIG_RESOURCE_COUNTERS=y | 20 | CONFIG_RESOURCE_COUNTERS=y |
| 21 | CONFIG_CGROUP_MEM_RES_CTLR=y | 21 | CONFIG_CGROUP_MEMCG=y |
| 22 | CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y | 22 | CONFIG_CGROUP_MEMCG_SWAP=y |
| 23 | CONFIG_CGROUP_SCHED=y | 23 | CONFIG_CGROUP_SCHED=y |
| 24 | CONFIG_RT_GROUP_SCHED=y | 24 | CONFIG_RT_GROUP_SCHED=y |
| 25 | CONFIG_BLK_CGROUP=y | 25 | CONFIG_BLK_CGROUP=y |
diff --git a/arch/sh/configs/se7206_defconfig b/arch/sh/configs/se7206_defconfig index 72c3fad7383f..6bc30ab9fd18 100644 --- a/arch/sh/configs/se7206_defconfig +++ b/arch/sh/configs/se7206_defconfig | |||
| @@ -11,7 +11,7 @@ CONFIG_CGROUP_DEBUG=y | |||
| 11 | CONFIG_CGROUP_DEVICE=y | 11 | CONFIG_CGROUP_DEVICE=y |
| 12 | CONFIG_CGROUP_CPUACCT=y | 12 | CONFIG_CGROUP_CPUACCT=y |
| 13 | CONFIG_RESOURCE_COUNTERS=y | 13 | CONFIG_RESOURCE_COUNTERS=y |
| 14 | CONFIG_CGROUP_MEM_RES_CTLR=y | 14 | CONFIG_CGROUP_MEMCG=y |
| 15 | CONFIG_RELAY=y | 15 | CONFIG_RELAY=y |
| 16 | CONFIG_NAMESPACES=y | 16 | CONFIG_NAMESPACES=y |
| 17 | CONFIG_UTS_NS=y | 17 | CONFIG_UTS_NS=y |
diff --git a/arch/sh/configs/shx3_defconfig b/arch/sh/configs/shx3_defconfig index 6bb413036892..cd6c519f8fad 100644 --- a/arch/sh/configs/shx3_defconfig +++ b/arch/sh/configs/shx3_defconfig | |||
| @@ -13,7 +13,7 @@ CONFIG_CGROUP_FREEZER=y | |||
| 13 | CONFIG_CGROUP_DEVICE=y | 13 | CONFIG_CGROUP_DEVICE=y |
| 14 | CONFIG_CGROUP_CPUACCT=y | 14 | CONFIG_CGROUP_CPUACCT=y |
| 15 | CONFIG_RESOURCE_COUNTERS=y | 15 | CONFIG_RESOURCE_COUNTERS=y |
| 16 | CONFIG_CGROUP_MEM_RES_CTLR=y | 16 | CONFIG_CGROUP_MEMCG=y |
| 17 | CONFIG_RELAY=y | 17 | CONFIG_RELAY=y |
| 18 | CONFIG_NAMESPACES=y | 18 | CONFIG_NAMESPACES=y |
| 19 | CONFIG_UTS_NS=y | 19 | CONFIG_UTS_NS=y |
diff --git a/arch/sh/configs/urquell_defconfig b/arch/sh/configs/urquell_defconfig index 8bfa4d056d7a..d7f89be9f474 100644 --- a/arch/sh/configs/urquell_defconfig +++ b/arch/sh/configs/urquell_defconfig | |||
| @@ -15,8 +15,8 @@ CONFIG_CPUSETS=y | |||
| 15 | # CONFIG_PROC_PID_CPUSET is not set | 15 | # CONFIG_PROC_PID_CPUSET is not set |
| 16 | CONFIG_CGROUP_CPUACCT=y | 16 | CONFIG_CGROUP_CPUACCT=y |
| 17 | CONFIG_RESOURCE_COUNTERS=y | 17 | CONFIG_RESOURCE_COUNTERS=y |
| 18 | CONFIG_CGROUP_MEM_RES_CTLR=y | 18 | CONFIG_CGROUP_MEMCG=y |
| 19 | CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y | 19 | CONFIG_CGROUP_MEMCG_SWAP=y |
| 20 | CONFIG_CGROUP_SCHED=y | 20 | CONFIG_CGROUP_SCHED=y |
| 21 | CONFIG_RT_GROUP_SCHED=y | 21 | CONFIG_RT_GROUP_SCHED=y |
| 22 | CONFIG_BLK_DEV_INITRD=y | 22 | CONFIG_BLK_DEV_INITRD=y |
diff --git a/arch/sh/include/asm/unistd.h b/arch/sh/include/asm/unistd.h index e800a38c9f8d..7bc67076baac 100644 --- a/arch/sh/include/asm/unistd.h +++ b/arch/sh/include/asm/unistd.h | |||
| @@ -6,7 +6,6 @@ | |||
| 6 | # endif | 6 | # endif |
| 7 | 7 | ||
| 8 | # define __ARCH_WANT_SYS_RT_SIGSUSPEND | 8 | # define __ARCH_WANT_SYS_RT_SIGSUSPEND |
| 9 | # define __ARCH_WANT_IPC_PARSE_VERSION | ||
| 10 | # define __ARCH_WANT_OLD_READDIR | 9 | # define __ARCH_WANT_OLD_READDIR |
| 11 | # define __ARCH_WANT_OLD_STAT | 10 | # define __ARCH_WANT_OLD_STAT |
| 12 | # define __ARCH_WANT_STAT64 | 11 | # define __ARCH_WANT_STAT64 |
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index e74ff1377626..67f1f6f5f4e1 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig | |||
| @@ -27,6 +27,7 @@ config SPARC | |||
| 27 | select HAVE_ARCH_JUMP_LABEL | 27 | select HAVE_ARCH_JUMP_LABEL |
| 28 | select HAVE_GENERIC_HARDIRQS | 28 | select HAVE_GENERIC_HARDIRQS |
| 29 | select GENERIC_IRQ_SHOW | 29 | select GENERIC_IRQ_SHOW |
| 30 | select ARCH_WANT_IPC_PARSE_VERSION | ||
| 30 | select USE_GENERIC_SMP_HELPERS if SMP | 31 | select USE_GENERIC_SMP_HELPERS if SMP |
| 31 | select GENERIC_PCI_IOMAP | 32 | select GENERIC_PCI_IOMAP |
| 32 | select HAVE_NMI_WATCHDOG if SPARC64 | 33 | select HAVE_NMI_WATCHDOG if SPARC64 |
diff --git a/arch/sparc/include/asm/fixmap.h b/arch/sparc/include/asm/fixmap.h deleted file mode 100644 index f18fc0755adf..000000000000 --- a/arch/sparc/include/asm/fixmap.h +++ /dev/null | |||
| @@ -1,110 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * fixmap.h: compile-time virtual memory allocation | ||
| 3 | * | ||
| 4 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 5 | * License. See the file "COPYING" in the main directory of this archive | ||
| 6 | * for more details. | ||
| 7 | * | ||
| 8 | * Copyright (C) 1998 Ingo Molnar | ||
| 9 | * | ||
| 10 | * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999 | ||
| 11 | */ | ||
| 12 | |||
| 13 | #ifndef _ASM_FIXMAP_H | ||
| 14 | #define _ASM_FIXMAP_H | ||
| 15 | |||
| 16 | #include <linux/kernel.h> | ||
| 17 | #include <asm/page.h> | ||
| 18 | #ifdef CONFIG_HIGHMEM | ||
| 19 | #include <linux/threads.h> | ||
| 20 | #include <asm/kmap_types.h> | ||
| 21 | #endif | ||
| 22 | |||
| 23 | /* | ||
| 24 | * Here we define all the compile-time 'special' virtual | ||
| 25 | * addresses. The point is to have a constant address at | ||
| 26 | * compile time, but to set the physical address only | ||
| 27 | * in the boot process. We allocate these special addresses | ||
| 28 | * from the top of unused virtual memory (0xfd000000 - 1 page) backwards. | ||
| 29 | * Also this lets us do fail-safe vmalloc(), we | ||
| 30 | * can guarantee that these special addresses and | ||
| 31 | * vmalloc()-ed addresses never overlap. | ||
| 32 | * | ||
| 33 | * these 'compile-time allocated' memory buffers are | ||
| 34 | * fixed-size 4k pages. (or larger if used with an increment | ||
| 35 | * highger than 1) use fixmap_set(idx,phys) to associate | ||
| 36 | * physical memory with fixmap indices. | ||
| 37 | * | ||
| 38 | * TLB entries of such buffers will not be flushed across | ||
| 39 | * task switches. | ||
| 40 | */ | ||
| 41 | |||
| 42 | /* | ||
| 43 | * on UP currently we will have no trace of the fixmap mechanism, | ||
| 44 | * no page table allocations, etc. This might change in the | ||
| 45 | * future, say framebuffers for the console driver(s) could be | ||
| 46 | * fix-mapped? | ||
| 47 | */ | ||
| 48 | enum fixed_addresses { | ||
| 49 | FIX_HOLE, | ||
| 50 | #ifdef CONFIG_HIGHMEM | ||
| 51 | FIX_KMAP_BEGIN, | ||
| 52 | FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1, | ||
| 53 | #endif | ||
| 54 | __end_of_fixed_addresses | ||
| 55 | }; | ||
| 56 | |||
| 57 | extern void __set_fixmap (enum fixed_addresses idx, | ||
| 58 | unsigned long phys, pgprot_t flags); | ||
| 59 | |||
| 60 | #define set_fixmap(idx, phys) \ | ||
| 61 | __set_fixmap(idx, phys, PAGE_KERNEL) | ||
| 62 | /* | ||
| 63 | * Some hardware wants to get fixmapped without caching. | ||
| 64 | */ | ||
| 65 | #define set_fixmap_nocache(idx, phys) \ | ||
| 66 | __set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE) | ||
| 67 | /* | ||
| 68 | * used by vmalloc.c. | ||
| 69 | * | ||
| 70 | * Leave one empty page between IO pages at 0xfd000000 and | ||
| 71 | * the start of the fixmap. | ||
| 72 | */ | ||
| 73 | #define FIXADDR_TOP (0xfcfff000UL) | ||
| 74 | #define FIXADDR_SIZE ((__end_of_fixed_addresses) << PAGE_SHIFT) | ||
| 75 | #define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE) | ||
| 76 | |||
| 77 | #define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT)) | ||
| 78 | #define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT) | ||
| 79 | |||
| 80 | extern void __this_fixmap_does_not_exist(void); | ||
| 81 | |||
| 82 | /* | ||
| 83 | * 'index to address' translation. If anyone tries to use the idx | ||
| 84 | * directly without tranlation, we catch the bug with a NULL-deference | ||
| 85 | * kernel oops. Illegal ranges of incoming indices are caught too. | ||
| 86 | */ | ||
| 87 | static inline unsigned long fix_to_virt(const unsigned int idx) | ||
| 88 | { | ||
| 89 | /* | ||
| 90 | * this branch gets completely eliminated after inlining, | ||
| 91 | * except when someone tries to use fixaddr indices in an | ||
| 92 | * illegal way. (such as mixing up address types or using | ||
| 93 | * out-of-range indices). | ||
| 94 | * | ||
| 95 | * If it doesn't get removed, the linker will complain | ||
| 96 | * loudly with a reasonably clear error message.. | ||
| 97 | */ | ||
| 98 | if (idx >= __end_of_fixed_addresses) | ||
| 99 | __this_fixmap_does_not_exist(); | ||
| 100 | |||
| 101 | return __fix_to_virt(idx); | ||
| 102 | } | ||
| 103 | |||
| 104 | static inline unsigned long virt_to_fix(const unsigned long vaddr) | ||
| 105 | { | ||
| 106 | BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START); | ||
| 107 | return __virt_to_fix(vaddr); | ||
| 108 | } | ||
| 109 | |||
| 110 | #endif | ||
diff --git a/arch/sparc/include/asm/highmem.h b/arch/sparc/include/asm/highmem.h index 3b6e00dd96e5..4f9e15c757e2 100644 --- a/arch/sparc/include/asm/highmem.h +++ b/arch/sparc/include/asm/highmem.h | |||
| @@ -21,7 +21,6 @@ | |||
| 21 | #ifdef __KERNEL__ | 21 | #ifdef __KERNEL__ |
| 22 | 22 | ||
| 23 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
| 24 | #include <asm/fixmap.h> | ||
| 25 | #include <asm/vaddrs.h> | 24 | #include <asm/vaddrs.h> |
| 26 | #include <asm/kmap_types.h> | 25 | #include <asm/kmap_types.h> |
| 27 | #include <asm/pgtable.h> | 26 | #include <asm/pgtable.h> |
| @@ -29,7 +28,6 @@ | |||
| 29 | /* declarations for highmem.c */ | 28 | /* declarations for highmem.c */ |
| 30 | extern unsigned long highstart_pfn, highend_pfn; | 29 | extern unsigned long highstart_pfn, highend_pfn; |
| 31 | 30 | ||
| 32 | extern pte_t *kmap_pte; | ||
| 33 | extern pgprot_t kmap_prot; | 31 | extern pgprot_t kmap_prot; |
| 34 | extern pte_t *pkmap_page_table; | 32 | extern pte_t *pkmap_page_table; |
| 35 | 33 | ||
| @@ -72,7 +70,6 @@ static inline void kunmap(struct page *page) | |||
| 72 | 70 | ||
| 73 | extern void *kmap_atomic(struct page *page); | 71 | extern void *kmap_atomic(struct page *page); |
| 74 | extern void __kunmap_atomic(void *kvaddr); | 72 | extern void __kunmap_atomic(void *kvaddr); |
| 75 | extern struct page *kmap_atomic_to_page(void *vaddr); | ||
| 76 | 73 | ||
| 77 | #define flush_cache_kmaps() flush_cache_all() | 74 | #define flush_cache_kmaps() flush_cache_all() |
| 78 | 75 | ||
diff --git a/arch/sparc/include/asm/leon.h b/arch/sparc/include/asm/leon.h index 3375c6293893..15a716934e4d 100644 --- a/arch/sparc/include/asm/leon.h +++ b/arch/sparc/include/asm/leon.h | |||
| @@ -82,7 +82,6 @@ static inline unsigned long leon_load_reg(unsigned long paddr) | |||
| 82 | #define LEON_BYPASS_LOAD_PA(x) leon_load_reg((unsigned long)(x)) | 82 | #define LEON_BYPASS_LOAD_PA(x) leon_load_reg((unsigned long)(x)) |
| 83 | #define LEON_BYPASS_STORE_PA(x, v) leon_store_reg((unsigned long)(x), (unsigned long)(v)) | 83 | #define LEON_BYPASS_STORE_PA(x, v) leon_store_reg((unsigned long)(x), (unsigned long)(v)) |
| 84 | 84 | ||
| 85 | extern void leon_init(void); | ||
| 86 | extern void leon_switch_mm(void); | 85 | extern void leon_switch_mm(void); |
| 87 | extern void leon_init_IRQ(void); | 86 | extern void leon_init_IRQ(void); |
| 88 | 87 | ||
diff --git a/arch/sparc/include/asm/mmu_context_32.h b/arch/sparc/include/asm/mmu_context_32.h index 01456c900720..2df2a9be8f6d 100644 --- a/arch/sparc/include/asm/mmu_context_32.h +++ b/arch/sparc/include/asm/mmu_context_32.h | |||
| @@ -9,14 +9,12 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) | |||
| 9 | { | 9 | { |
| 10 | } | 10 | } |
| 11 | 11 | ||
| 12 | /* | 12 | /* Initialize a new mmu context. This is invoked when a new |
| 13 | * Initialize a new mmu context. This is invoked when a new | ||
| 14 | * address space instance (unique or shared) is instantiated. | 13 | * address space instance (unique or shared) is instantiated. |
| 15 | */ | 14 | */ |
| 16 | #define init_new_context(tsk, mm) (((mm)->context = NO_CONTEXT), 0) | 15 | int init_new_context(struct task_struct *tsk, struct mm_struct *mm); |
| 17 | 16 | ||
| 18 | /* | 17 | /* Destroy a dead context. This occurs when mmput drops the |
| 19 | * Destroy a dead context. This occurs when mmput drops the | ||
| 20 | * mm_users count to zero, the mmaps have been released, and | 18 | * mm_users count to zero, the mmaps have been released, and |
| 21 | * all the page tables have been flushed. Our job is to destroy | 19 | * all the page tables have been flushed. Our job is to destroy |
| 22 | * any remaining processor-specific state. | 20 | * any remaining processor-specific state. |
diff --git a/arch/sparc/include/asm/page_32.h b/arch/sparc/include/asm/page_32.h index fab78a308ebf..f82a1f36b655 100644 --- a/arch/sparc/include/asm/page_32.h +++ b/arch/sparc/include/asm/page_32.h | |||
| @@ -107,8 +107,7 @@ typedef unsigned long iopgprot_t; | |||
| 107 | 107 | ||
| 108 | typedef struct page *pgtable_t; | 108 | typedef struct page *pgtable_t; |
| 109 | 109 | ||
| 110 | extern unsigned long sparc_unmapped_base; | 110 | #define TASK_UNMAPPED_BASE 0x50000000 |
| 111 | #define TASK_UNMAPPED_BASE sparc_unmapped_base | ||
| 112 | 111 | ||
| 113 | #else /* !(__ASSEMBLY__) */ | 112 | #else /* !(__ASSEMBLY__) */ |
| 114 | 113 | ||
diff --git a/arch/sparc/include/asm/pgalloc_32.h b/arch/sparc/include/asm/pgalloc_32.h index e5b169b46d21..9b1c36de0f18 100644 --- a/arch/sparc/include/asm/pgalloc_32.h +++ b/arch/sparc/include/asm/pgalloc_32.h | |||
| @@ -11,28 +11,15 @@ | |||
| 11 | 11 | ||
| 12 | struct page; | 12 | struct page; |
| 13 | 13 | ||
| 14 | extern struct pgtable_cache_struct { | 14 | void *srmmu_get_nocache(int size, int align); |
| 15 | unsigned long *pgd_cache; | 15 | void srmmu_free_nocache(void *addr, int size); |
| 16 | unsigned long *pte_cache; | ||
| 17 | unsigned long pgtable_cache_sz; | ||
| 18 | unsigned long pgd_cache_sz; | ||
| 19 | } pgt_quicklists; | ||
| 20 | |||
| 21 | unsigned long srmmu_get_nocache(int size, int align); | ||
| 22 | void srmmu_free_nocache(unsigned long vaddr, int size); | ||
| 23 | |||
| 24 | #define pgd_quicklist (pgt_quicklists.pgd_cache) | ||
| 25 | #define pmd_quicklist ((unsigned long *)0) | ||
| 26 | #define pte_quicklist (pgt_quicklists.pte_cache) | ||
| 27 | #define pgtable_cache_size (pgt_quicklists.pgtable_cache_sz) | ||
| 28 | #define pgd_cache_size (pgt_quicklists.pgd_cache_sz) | ||
| 29 | 16 | ||
| 30 | #define check_pgt_cache() do { } while (0) | 17 | #define check_pgt_cache() do { } while (0) |
| 31 | 18 | ||
| 32 | pgd_t *get_pgd_fast(void); | 19 | pgd_t *get_pgd_fast(void); |
| 33 | static inline void free_pgd_fast(pgd_t *pgd) | 20 | static inline void free_pgd_fast(pgd_t *pgd) |
| 34 | { | 21 | { |
| 35 | srmmu_free_nocache((unsigned long)pgd, SRMMU_PGD_TABLE_SIZE); | 22 | srmmu_free_nocache(pgd, SRMMU_PGD_TABLE_SIZE); |
| 36 | } | 23 | } |
| 37 | 24 | ||
| 38 | #define pgd_free(mm, pgd) free_pgd_fast(pgd) | 25 | #define pgd_free(mm, pgd) free_pgd_fast(pgd) |
| @@ -50,13 +37,13 @@ static inline void pgd_set(pgd_t * pgdp, pmd_t * pmdp) | |||
| 50 | static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, | 37 | static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, |
| 51 | unsigned long address) | 38 | unsigned long address) |
| 52 | { | 39 | { |
| 53 | return (pmd_t *)srmmu_get_nocache(SRMMU_PMD_TABLE_SIZE, | 40 | return srmmu_get_nocache(SRMMU_PMD_TABLE_SIZE, |
| 54 | SRMMU_PMD_TABLE_SIZE); | 41 | SRMMU_PMD_TABLE_SIZE); |
| 55 | } | 42 | } |
| 56 | 43 | ||
| 57 | static inline void free_pmd_fast(pmd_t * pmd) | 44 | static inline void free_pmd_fast(pmd_t * pmd) |
| 58 | { | 45 | { |
| 59 | srmmu_free_nocache((unsigned long)pmd, SRMMU_PMD_TABLE_SIZE); | 46 | srmmu_free_nocache(pmd, SRMMU_PMD_TABLE_SIZE); |
| 60 | } | 47 | } |
| 61 | 48 | ||
| 62 | #define pmd_free(mm, pmd) free_pmd_fast(pmd) | 49 | #define pmd_free(mm, pmd) free_pmd_fast(pmd) |
| @@ -73,13 +60,13 @@ pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address); | |||
| 73 | static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, | 60 | static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, |
| 74 | unsigned long address) | 61 | unsigned long address) |
| 75 | { | 62 | { |
| 76 | return (pte_t *)srmmu_get_nocache(PTE_SIZE, PTE_SIZE); | 63 | return srmmu_get_nocache(PTE_SIZE, PTE_SIZE); |
| 77 | } | 64 | } |
| 78 | 65 | ||
| 79 | 66 | ||
| 80 | static inline void free_pte_fast(pte_t *pte) | 67 | static inline void free_pte_fast(pte_t *pte) |
| 81 | { | 68 | { |
| 82 | srmmu_free_nocache((unsigned long)pte, PTE_SIZE); | 69 | srmmu_free_nocache(pte, PTE_SIZE); |
| 83 | } | 70 | } |
| 84 | 71 | ||
| 85 | #define pte_free_kernel(mm, pte) free_pte_fast(pte) | 72 | #define pte_free_kernel(mm, pte) free_pte_fast(pte) |
diff --git a/arch/sparc/include/asm/pgtable_32.h b/arch/sparc/include/asm/pgtable_32.h index cbbbed5cb3aa..6fc13483f702 100644 --- a/arch/sparc/include/asm/pgtable_32.h +++ b/arch/sparc/include/asm/pgtable_32.h | |||
| @@ -52,8 +52,9 @@ extern unsigned long calc_highpages(void); | |||
| 52 | #define PAGE_READONLY SRMMU_PAGE_RDONLY | 52 | #define PAGE_READONLY SRMMU_PAGE_RDONLY |
| 53 | #define PAGE_KERNEL SRMMU_PAGE_KERNEL | 53 | #define PAGE_KERNEL SRMMU_PAGE_KERNEL |
| 54 | 54 | ||
| 55 | /* Top-level page directory */ | 55 | /* Top-level page directory - dummy used by init-mm. |
| 56 | extern pgd_t swapper_pg_dir[1024]; | 56 | * srmmu.c will assign the real one (which is dynamically sized) */ |
| 57 | #define swapper_pg_dir NULL | ||
| 57 | 58 | ||
| 58 | extern void paging_init(void); | 59 | extern void paging_init(void); |
| 59 | 60 | ||
| @@ -78,8 +79,6 @@ extern unsigned long ptr_in_current_pgd; | |||
| 78 | #define __S110 PAGE_SHARED | 79 | #define __S110 PAGE_SHARED |
| 79 | #define __S111 PAGE_SHARED | 80 | #define __S111 PAGE_SHARED |
| 80 | 81 | ||
| 81 | extern int num_contexts; | ||
| 82 | |||
| 83 | /* First physical page can be anywhere, the following is needed so that | 82 | /* First physical page can be anywhere, the following is needed so that |
| 84 | * va-->pa and vice versa conversions work properly without performance | 83 | * va-->pa and vice versa conversions work properly without performance |
| 85 | * hit for all __pa()/__va() operations. | 84 | * hit for all __pa()/__va() operations. |
| @@ -88,18 +87,11 @@ extern unsigned long phys_base; | |||
| 88 | extern unsigned long pfn_base; | 87 | extern unsigned long pfn_base; |
| 89 | 88 | ||
| 90 | /* | 89 | /* |
| 91 | * BAD_PAGETABLE is used when we need a bogus page-table, while | ||
| 92 | * BAD_PAGE is used for a bogus page. | ||
| 93 | * | ||
| 94 | * ZERO_PAGE is a global shared page that is always zero: used | 90 | * ZERO_PAGE is a global shared page that is always zero: used |
| 95 | * for zero-mapped memory areas etc.. | 91 | * for zero-mapped memory areas etc.. |
| 96 | */ | 92 | */ |
| 97 | extern pte_t * __bad_pagetable(void); | ||
| 98 | extern pte_t __bad_page(void); | ||
| 99 | extern unsigned long empty_zero_page; | 93 | extern unsigned long empty_zero_page; |
| 100 | 94 | ||
| 101 | #define BAD_PAGETABLE __bad_pagetable() | ||
| 102 | #define BAD_PAGE __bad_page() | ||
| 103 | #define ZERO_PAGE(vaddr) (virt_to_page(&empty_zero_page)) | 95 | #define ZERO_PAGE(vaddr) (virt_to_page(&empty_zero_page)) |
| 104 | 96 | ||
| 105 | /* | 97 | /* |
| @@ -398,36 +390,6 @@ static inline pte_t pgoff_to_pte(unsigned long pgoff) | |||
| 398 | */ | 390 | */ |
| 399 | #define PTE_FILE_MAX_BITS 24 | 391 | #define PTE_FILE_MAX_BITS 24 |
| 400 | 392 | ||
| 401 | /* | ||
| 402 | */ | ||
| 403 | struct ctx_list { | ||
| 404 | struct ctx_list *next; | ||
| 405 | struct ctx_list *prev; | ||
| 406 | unsigned int ctx_number; | ||
| 407 | struct mm_struct *ctx_mm; | ||
| 408 | }; | ||
| 409 | |||
| 410 | extern struct ctx_list *ctx_list_pool; /* Dynamically allocated */ | ||
| 411 | extern struct ctx_list ctx_free; /* Head of free list */ | ||
| 412 | extern struct ctx_list ctx_used; /* Head of used contexts list */ | ||
| 413 | |||
| 414 | #define NO_CONTEXT -1 | ||
| 415 | |||
| 416 | static inline void remove_from_ctx_list(struct ctx_list *entry) | ||
| 417 | { | ||
| 418 | entry->next->prev = entry->prev; | ||
| 419 | entry->prev->next = entry->next; | ||
| 420 | } | ||
| 421 | |||
| 422 | static inline void add_to_ctx_list(struct ctx_list *head, struct ctx_list *entry) | ||
| 423 | { | ||
| 424 | entry->next = head; | ||
| 425 | (entry->prev = head->prev)->next = entry; | ||
| 426 | head->prev = entry; | ||
| 427 | } | ||
| 428 | #define add_to_free_ctxlist(entry) add_to_ctx_list(&ctx_free, entry) | ||
| 429 | #define add_to_used_ctxlist(entry) add_to_ctx_list(&ctx_used, entry) | ||
| 430 | |||
| 431 | static inline unsigned long | 393 | static inline unsigned long |
| 432 | __get_phys (unsigned long addr) | 394 | __get_phys (unsigned long addr) |
| 433 | { | 395 | { |
diff --git a/arch/sparc/include/asm/unistd.h b/arch/sparc/include/asm/unistd.h index c7cb0af0eb59..fb2693464807 100644 --- a/arch/sparc/include/asm/unistd.h +++ b/arch/sparc/include/asm/unistd.h | |||
| @@ -423,7 +423,6 @@ | |||
| 423 | #endif | 423 | #endif |
| 424 | 424 | ||
| 425 | #ifdef __KERNEL__ | 425 | #ifdef __KERNEL__ |
| 426 | #define __ARCH_WANT_IPC_PARSE_VERSION | ||
| 427 | #define __ARCH_WANT_OLD_READDIR | 426 | #define __ARCH_WANT_OLD_READDIR |
| 428 | #define __ARCH_WANT_STAT64 | 427 | #define __ARCH_WANT_STAT64 |
| 429 | #define __ARCH_WANT_SYS_ALARM | 428 | #define __ARCH_WANT_SYS_ALARM |
diff --git a/arch/sparc/include/asm/vaddrs.h b/arch/sparc/include/asm/vaddrs.h index da6535d88a72..c3dbcf902034 100644 --- a/arch/sparc/include/asm/vaddrs.h +++ b/arch/sparc/include/asm/vaddrs.h | |||
| @@ -30,6 +30,28 @@ | |||
| 30 | */ | 30 | */ |
| 31 | #define SRMMU_NOCACHE_ALCRATIO 64 /* 256 pages per 64MB of system RAM */ | 31 | #define SRMMU_NOCACHE_ALCRATIO 64 /* 256 pages per 64MB of system RAM */ |
| 32 | 32 | ||
| 33 | #ifndef __ASSEMBLY__ | ||
| 34 | #include <asm/kmap_types.h> | ||
| 35 | |||
| 36 | enum fixed_addresses { | ||
| 37 | FIX_HOLE, | ||
| 38 | #ifdef CONFIG_HIGHMEM | ||
| 39 | FIX_KMAP_BEGIN, | ||
| 40 | FIX_KMAP_END = (KM_TYPE_NR * NR_CPUS), | ||
| 41 | #endif | ||
| 42 | __end_of_fixed_addresses | ||
| 43 | }; | ||
| 44 | #endif | ||
| 45 | |||
| 46 | /* Leave one empty page between IO pages at 0xfd000000 and | ||
| 47 | * the top of the fixmap. | ||
| 48 | */ | ||
| 49 | #define FIXADDR_TOP (0xfcfff000UL) | ||
| 50 | #define FIXADDR_SIZE ((FIX_KMAP_END + 1) << PAGE_SHIFT) | ||
| 51 | #define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE) | ||
| 52 | |||
| 53 | #define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT)) | ||
| 54 | |||
| 33 | #define SUN4M_IOBASE_VADDR 0xfd000000 /* Base for mapping pages */ | 55 | #define SUN4M_IOBASE_VADDR 0xfd000000 /* Base for mapping pages */ |
| 34 | #define IOBASE_VADDR 0xfe000000 | 56 | #define IOBASE_VADDR 0xfe000000 |
| 35 | #define IOBASE_END 0xfe600000 | 57 | #define IOBASE_END 0xfe600000 |
diff --git a/arch/sparc/kernel/head_32.S b/arch/sparc/kernel/head_32.S index afeb1d770303..3d92c0a8f6c4 100644 --- a/arch/sparc/kernel/head_32.S +++ b/arch/sparc/kernel/head_32.S | |||
| @@ -58,8 +58,6 @@ sun4e_notsup: | |||
| 58 | /* This was the only reasonable way I could think of to properly align | 58 | /* This was the only reasonable way I could think of to properly align |
| 59 | * these page-table data structures. | 59 | * these page-table data structures. |
| 60 | */ | 60 | */ |
| 61 | .globl swapper_pg_dir | ||
| 62 | swapper_pg_dir: .skip PAGE_SIZE | ||
| 63 | .globl empty_zero_page | 61 | .globl empty_zero_page |
| 64 | empty_zero_page: .skip PAGE_SIZE | 62 | empty_zero_page: .skip PAGE_SIZE |
| 65 | 63 | ||
diff --git a/arch/sparc/kernel/ldc.c b/arch/sparc/kernel/ldc.c index 435e406fdec3..81d92fc9983b 100644 --- a/arch/sparc/kernel/ldc.c +++ b/arch/sparc/kernel/ldc.c | |||
| @@ -1250,14 +1250,12 @@ int ldc_bind(struct ldc_channel *lp, const char *name) | |||
| 1250 | snprintf(lp->rx_irq_name, LDC_IRQ_NAME_MAX, "%s RX", name); | 1250 | snprintf(lp->rx_irq_name, LDC_IRQ_NAME_MAX, "%s RX", name); |
| 1251 | snprintf(lp->tx_irq_name, LDC_IRQ_NAME_MAX, "%s TX", name); | 1251 | snprintf(lp->tx_irq_name, LDC_IRQ_NAME_MAX, "%s TX", name); |
| 1252 | 1252 | ||
| 1253 | err = request_irq(lp->cfg.rx_irq, ldc_rx, | 1253 | err = request_irq(lp->cfg.rx_irq, ldc_rx, IRQF_DISABLED, |
| 1254 | IRQF_SAMPLE_RANDOM | IRQF_DISABLED, | ||
| 1255 | lp->rx_irq_name, lp); | 1254 | lp->rx_irq_name, lp); |
| 1256 | if (err) | 1255 | if (err) |
| 1257 | return err; | 1256 | return err; |
| 1258 | 1257 | ||
| 1259 | err = request_irq(lp->cfg.tx_irq, ldc_tx, | 1258 | err = request_irq(lp->cfg.tx_irq, ldc_tx, IRQF_DISABLED, |
| 1260 | IRQF_SAMPLE_RANDOM | IRQF_DISABLED, | ||
| 1261 | lp->tx_irq_name, lp); | 1259 | lp->tx_irq_name, lp); |
| 1262 | if (err) { | 1260 | if (err) { |
| 1263 | free_irq(lp->cfg.rx_irq, lp); | 1261 | free_irq(lp->cfg.rx_irq, lp); |
diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c index e34e2c40c060..f8b6eee40bde 100644 --- a/arch/sparc/kernel/leon_kernel.c +++ b/arch/sparc/kernel/leon_kernel.c | |||
| @@ -486,17 +486,6 @@ void __init leon_trans_init(struct device_node *dp) | |||
| 486 | } | 486 | } |
| 487 | } | 487 | } |
| 488 | 488 | ||
| 489 | void __initdata (*prom_amba_init)(struct device_node *dp, struct device_node ***nextp) = 0; | ||
| 490 | |||
| 491 | void __init leon_node_init(struct device_node *dp, struct device_node ***nextp) | ||
| 492 | { | ||
| 493 | if (prom_amba_init && | ||
| 494 | strcmp(dp->type, "ambapp") == 0 && | ||
| 495 | strcmp(dp->name, "ambapp0") == 0) { | ||
| 496 | prom_amba_init(dp, nextp); | ||
| 497 | } | ||
| 498 | } | ||
| 499 | |||
| 500 | #ifdef CONFIG_SMP | 489 | #ifdef CONFIG_SMP |
| 501 | void leon_clear_profile_irq(int cpu) | 490 | void leon_clear_profile_irq(int cpu) |
| 502 | { | 491 | { |
| @@ -522,8 +511,3 @@ void __init leon_init_IRQ(void) | |||
| 522 | sparc_config.clear_clock_irq = leon_clear_clock_irq; | 511 | sparc_config.clear_clock_irq = leon_clear_clock_irq; |
| 523 | sparc_config.load_profile_irq = leon_load_profile_irq; | 512 | sparc_config.load_profile_irq = leon_load_profile_irq; |
| 524 | } | 513 | } |
| 525 | |||
| 526 | void __init leon_init(void) | ||
| 527 | { | ||
| 528 | of_pdt_build_more = &leon_node_init; | ||
| 529 | } | ||
diff --git a/arch/sparc/kernel/process_32.c b/arch/sparc/kernel/process_32.c index cb36e82dcd5d..14006d8aca28 100644 --- a/arch/sparc/kernel/process_32.c +++ b/arch/sparc/kernel/process_32.c | |||
| @@ -333,9 +333,6 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, | |||
| 333 | put_psr(get_psr() | PSR_EF); | 333 | put_psr(get_psr() | PSR_EF); |
| 334 | fpsave(&p->thread.float_regs[0], &p->thread.fsr, | 334 | fpsave(&p->thread.float_regs[0], &p->thread.fsr, |
| 335 | &p->thread.fpqueue[0], &p->thread.fpqdepth); | 335 | &p->thread.fpqueue[0], &p->thread.fpqdepth); |
| 336 | #ifdef CONFIG_SMP | ||
| 337 | clear_thread_flag(TIF_USEDFPU); | ||
| 338 | #endif | ||
| 339 | } | 336 | } |
| 340 | 337 | ||
| 341 | /* | 338 | /* |
| @@ -413,6 +410,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, | |||
| 413 | #ifdef CONFIG_SMP | 410 | #ifdef CONFIG_SMP |
| 414 | /* FPU must be disabled on SMP. */ | 411 | /* FPU must be disabled on SMP. */ |
| 415 | childregs->psr &= ~PSR_EF; | 412 | childregs->psr &= ~PSR_EF; |
| 413 | clear_tsk_thread_flag(p, TIF_USEDFPU); | ||
| 416 | #endif | 414 | #endif |
| 417 | 415 | ||
| 418 | /* Set the return value for the child. */ | 416 | /* Set the return value for the child. */ |
diff --git a/arch/sparc/kernel/setup_32.c b/arch/sparc/kernel/setup_32.c index efe3e64bba38..38bf80a22f02 100644 --- a/arch/sparc/kernel/setup_32.c +++ b/arch/sparc/kernel/setup_32.c | |||
| @@ -371,7 +371,6 @@ void __init setup_arch(char **cmdline_p) | |||
| 371 | (*(linux_dbvec->teach_debugger))(); | 371 | (*(linux_dbvec->teach_debugger))(); |
| 372 | } | 372 | } |
| 373 | 373 | ||
| 374 | init_mm.context = (unsigned long) NO_CONTEXT; | ||
| 375 | init_task.thread.kregs = &fake_swapper_regs; | 374 | init_task.thread.kregs = &fake_swapper_regs; |
| 376 | 375 | ||
| 377 | /* Run-time patch instructions to match the cpu model */ | 376 | /* Run-time patch instructions to match the cpu model */ |
diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c index 275f74fd6f6a..0dc1f5786081 100644 --- a/arch/sparc/kernel/sys_sparc_64.c +++ b/arch/sparc/kernel/sys_sparc_64.c | |||
| @@ -66,23 +66,6 @@ static inline int invalid_64bit_range(unsigned long addr, unsigned long len) | |||
| 66 | return 0; | 66 | return 0; |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | /* Does start,end straddle the VA-space hole? */ | ||
| 70 | static inline int straddles_64bit_va_hole(unsigned long start, unsigned long end) | ||
| 71 | { | ||
| 72 | unsigned long va_exclude_start, va_exclude_end; | ||
| 73 | |||
| 74 | va_exclude_start = VA_EXCLUDE_START; | ||
| 75 | va_exclude_end = VA_EXCLUDE_END; | ||
| 76 | |||
| 77 | if (likely(start < va_exclude_start && end < va_exclude_start)) | ||
| 78 | return 0; | ||
| 79 | |||
| 80 | if (likely(start >= va_exclude_end && end >= va_exclude_end)) | ||
| 81 | return 0; | ||
| 82 | |||
| 83 | return 1; | ||
| 84 | } | ||
| 85 | |||
| 86 | /* These functions differ from the default implementations in | 69 | /* These functions differ from the default implementations in |
| 87 | * mm/mmap.c in two ways: | 70 | * mm/mmap.c in two ways: |
| 88 | * | 71 | * |
| @@ -487,7 +470,7 @@ SYSCALL_DEFINE6(sparc_ipc, unsigned int, call, int, first, unsigned long, second | |||
| 487 | switch (call) { | 470 | switch (call) { |
| 488 | case SHMAT: { | 471 | case SHMAT: { |
| 489 | ulong raddr; | 472 | ulong raddr; |
| 490 | err = do_shmat(first, ptr, (int)second, &raddr); | 473 | err = do_shmat(first, ptr, (int)second, &raddr, SHMLBA); |
| 491 | if (!err) { | 474 | if (!err) { |
| 492 | if (put_user(raddr, | 475 | if (put_user(raddr, |
| 493 | (ulong __user *) third)) | 476 | (ulong __user *) third)) |
diff --git a/arch/sparc/lib/NG2memcpy.S b/arch/sparc/lib/NG2memcpy.S index 0aed75653b50..03eadf66b0d3 100644 --- a/arch/sparc/lib/NG2memcpy.S +++ b/arch/sparc/lib/NG2memcpy.S | |||
| @@ -90,49 +90,49 @@ | |||
| 90 | faligndata %x7, %x8, %f14; | 90 | faligndata %x7, %x8, %f14; |
| 91 | 91 | ||
| 92 | #define FREG_MOVE_1(x0) \ | 92 | #define FREG_MOVE_1(x0) \ |
| 93 | fmovd %x0, %f0; | 93 | fsrc2 %x0, %f0; |
| 94 | #define FREG_MOVE_2(x0, x1) \ | 94 | #define FREG_MOVE_2(x0, x1) \ |
| 95 | fmovd %x0, %f0; \ | 95 | fsrc2 %x0, %f0; \ |
| 96 | fmovd %x1, %f2; | 96 | fsrc2 %x1, %f2; |
| 97 | #define FREG_MOVE_3(x0, x1, x2) \ | 97 | #define FREG_MOVE_3(x0, x1, x2) \ |
| 98 | fmovd %x0, %f0; \ | 98 | fsrc2 %x0, %f0; \ |
| 99 | fmovd %x1, %f2; \ | 99 | fsrc2 %x1, %f2; \ |
| 100 | fmovd %x2, %f4; | 100 | fsrc2 %x2, %f4; |
| 101 | #define FREG_MOVE_4(x0, x1, x2, x3) \ | 101 | #define FREG_MOVE_4(x0, x1, x2, x3) \ |
| 102 | fmovd %x0, %f0; \ | 102 | fsrc2 %x0, %f0; \ |
| 103 | fmovd %x1, %f2; \ | 103 | fsrc2 %x1, %f2; \ |
| 104 | fmovd %x2, %f4; \ | 104 | fsrc2 %x2, %f4; \ |
| 105 | fmovd %x3, %f6; | 105 | fsrc2 %x3, %f6; |
| 106 | #define FREG_MOVE_5(x0, x1, x2, x3, x4) \ | 106 | #define FREG_MOVE_5(x0, x1, x2, x3, x4) \ |
| 107 | fmovd %x0, %f0; \ | 107 | fsrc2 %x0, %f0; \ |
| 108 | fmovd %x1, %f2; \ | 108 | fsrc2 %x1, %f2; \ |
| 109 | fmovd %x2, %f4; \ | 109 | fsrc2 %x2, %f4; \ |
| 110 | fmovd %x3, %f6; \ | 110 | fsrc2 %x3, %f6; \ |
| 111 | fmovd %x4, %f8; | 111 | fsrc2 %x4, %f8; |
| 112 | #define FREG_MOVE_6(x0, x1, x2, x3, x4, x5) \ | 112 | #define FREG_MOVE_6(x0, x1, x2, x3, x4, x5) \ |
| 113 | fmovd %x0, %f0; \ | 113 | fsrc2 %x0, %f0; \ |
| 114 | fmovd %x1, %f2; \ | 114 | fsrc2 %x1, %f2; \ |
| 115 | fmovd %x2, %f4; \ | 115 | fsrc2 %x2, %f4; \ |
| 116 | fmovd %x3, %f6; \ | 116 | fsrc2 %x3, %f6; \ |
| 117 | fmovd %x4, %f8; \ | 117 | fsrc2 %x4, %f8; \ |
| 118 | fmovd %x5, %f10; | 118 | fsrc2 %x5, %f10; |
| 119 | #define FREG_MOVE_7(x0, x1, x2, x3, x4, x5, x6) \ | 119 | #define FREG_MOVE_7(x0, x1, x2, x3, x4, x5, x6) \ |
| 120 | fmovd %x0, %f0; \ | 120 | fsrc2 %x0, %f0; \ |
| 121 | fmovd %x1, %f2; \ | 121 | fsrc2 %x1, %f2; \ |
| 122 | fmovd %x2, %f4; \ | 122 | fsrc2 %x2, %f4; \ |
| 123 | fmovd %x3, %f6; \ | 123 | fsrc2 %x3, %f6; \ |
| 124 | fmovd %x4, %f8; \ | 124 | fsrc2 %x4, %f8; \ |
| 125 | fmovd %x5, %f10; \ | 125 | fsrc2 %x5, %f10; \ |
| 126 | fmovd %x6, %f12; | 126 | fsrc2 %x6, %f12; |
| 127 | #define FREG_MOVE_8(x0, x1, x2, x3, x4, x5, x6, x7) \ | 127 | #define FREG_MOVE_8(x0, x1, x2, x3, x4, x5, x6, x7) \ |
| 128 | fmovd %x0, %f0; \ | 128 | fsrc2 %x0, %f0; \ |
| 129 | fmovd %x1, %f2; \ | 129 | fsrc2 %x1, %f2; \ |
| 130 | fmovd %x2, %f4; \ | 130 | fsrc2 %x2, %f4; \ |
| 131 | fmovd %x3, %f6; \ | 131 | fsrc2 %x3, %f6; \ |
| 132 | fmovd %x4, %f8; \ | 132 | fsrc2 %x4, %f8; \ |
| 133 | fmovd %x5, %f10; \ | 133 | fsrc2 %x5, %f10; \ |
| 134 | fmovd %x6, %f12; \ | 134 | fsrc2 %x6, %f12; \ |
| 135 | fmovd %x7, %f14; | 135 | fsrc2 %x7, %f14; |
| 136 | #define FREG_LOAD_1(base, x0) \ | 136 | #define FREG_LOAD_1(base, x0) \ |
| 137 | EX_LD(LOAD(ldd, base + 0x00, %x0)) | 137 | EX_LD(LOAD(ldd, base + 0x00, %x0)) |
| 138 | #define FREG_LOAD_2(base, x0, x1) \ | 138 | #define FREG_LOAD_2(base, x0, x1) \ |
diff --git a/arch/sparc/lib/U1memcpy.S b/arch/sparc/lib/U1memcpy.S index bafd2fc07acb..b67142b7768e 100644 --- a/arch/sparc/lib/U1memcpy.S +++ b/arch/sparc/lib/U1memcpy.S | |||
| @@ -109,7 +109,7 @@ | |||
| 109 | #define UNEVEN_VISCHUNK_LAST(dest, f0, f1, left) \ | 109 | #define UNEVEN_VISCHUNK_LAST(dest, f0, f1, left) \ |
| 110 | subcc %left, 8, %left; \ | 110 | subcc %left, 8, %left; \ |
| 111 | bl,pn %xcc, 95f; \ | 111 | bl,pn %xcc, 95f; \ |
| 112 | fsrc1 %f0, %f1; | 112 | fsrc2 %f0, %f1; |
| 113 | 113 | ||
| 114 | #define UNEVEN_VISCHUNK(dest, f0, f1, left) \ | 114 | #define UNEVEN_VISCHUNK(dest, f0, f1, left) \ |
| 115 | UNEVEN_VISCHUNK_LAST(dest, f0, f1, left) \ | 115 | UNEVEN_VISCHUNK_LAST(dest, f0, f1, left) \ |
| @@ -201,7 +201,7 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ | |||
| 201 | andn %o1, (0x40 - 1), %o1 | 201 | andn %o1, (0x40 - 1), %o1 |
| 202 | and %g2, 7, %g2 | 202 | and %g2, 7, %g2 |
| 203 | andncc %g3, 0x7, %g3 | 203 | andncc %g3, 0x7, %g3 |
| 204 | fmovd %f0, %f2 | 204 | fsrc2 %f0, %f2 |
| 205 | sub %g3, 0x8, %g3 | 205 | sub %g3, 0x8, %g3 |
| 206 | sub %o2, %GLOBAL_SPARE, %o2 | 206 | sub %o2, %GLOBAL_SPARE, %o2 |
| 207 | 207 | ||
diff --git a/arch/sparc/lib/copy_page.S b/arch/sparc/lib/copy_page.S index b243d3b606ba..4d2df328e514 100644 --- a/arch/sparc/lib/copy_page.S +++ b/arch/sparc/lib/copy_page.S | |||
| @@ -34,10 +34,10 @@ | |||
| 34 | #endif | 34 | #endif |
| 35 | 35 | ||
| 36 | #define TOUCH(reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7) \ | 36 | #define TOUCH(reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7) \ |
| 37 | fmovd %reg0, %f48; fmovd %reg1, %f50; \ | 37 | fsrc2 %reg0, %f48; fsrc2 %reg1, %f50; \ |
| 38 | fmovd %reg2, %f52; fmovd %reg3, %f54; \ | 38 | fsrc2 %reg2, %f52; fsrc2 %reg3, %f54; \ |
| 39 | fmovd %reg4, %f56; fmovd %reg5, %f58; \ | 39 | fsrc2 %reg4, %f56; fsrc2 %reg5, %f58; \ |
| 40 | fmovd %reg6, %f60; fmovd %reg7, %f62; | 40 | fsrc2 %reg6, %f60; fsrc2 %reg7, %f62; |
| 41 | 41 | ||
| 42 | .text | 42 | .text |
| 43 | 43 | ||
| @@ -104,60 +104,60 @@ cheetah_copy_page_insn: | |||
| 104 | prefetch [%o1 + 0x140], #one_read | 104 | prefetch [%o1 + 0x140], #one_read |
| 105 | ldd [%o1 + 0x010], %f4 | 105 | ldd [%o1 + 0x010], %f4 |
| 106 | prefetch [%o1 + 0x180], #one_read | 106 | prefetch [%o1 + 0x180], #one_read |
| 107 | fmovd %f0, %f16 | 107 | fsrc2 %f0, %f16 |
| 108 | ldd [%o1 + 0x018], %f6 | 108 | ldd [%o1 + 0x018], %f6 |
| 109 | fmovd %f2, %f18 | 109 | fsrc2 %f2, %f18 |
| 110 | ldd [%o1 + 0x020], %f8 | 110 | ldd [%o1 + 0x020], %f8 |
| 111 | fmovd %f4, %f20 | 111 | fsrc2 %f4, %f20 |
| 112 | ldd [%o1 + 0x028], %f10 | 112 | ldd [%o1 + 0x028], %f10 |
| 113 | fmovd %f6, %f22 | 113 | fsrc2 %f6, %f22 |
| 114 | ldd [%o1 + 0x030], %f12 | 114 | ldd [%o1 + 0x030], %f12 |
| 115 | fmovd %f8, %f24 | 115 | fsrc2 %f8, %f24 |
| 116 | ldd [%o1 + 0x038], %f14 | 116 | ldd [%o1 + 0x038], %f14 |
| 117 | fmovd %f10, %f26 | 117 | fsrc2 %f10, %f26 |
| 118 | ldd [%o1 + 0x040], %f0 | 118 | ldd [%o1 + 0x040], %f0 |
| 119 | 1: ldd [%o1 + 0x048], %f2 | 119 | 1: ldd [%o1 + 0x048], %f2 |
| 120 | fmovd %f12, %f28 | 120 | fsrc2 %f12, %f28 |
| 121 | ldd [%o1 + 0x050], %f4 | 121 | ldd [%o1 + 0x050], %f4 |
| 122 | fmovd %f14, %f30 | 122 | fsrc2 %f14, %f30 |
| 123 | stda %f16, [%o0] ASI_BLK_P | 123 | stda %f16, [%o0] ASI_BLK_P |
| 124 | ldd [%o1 + 0x058], %f6 | 124 | ldd [%o1 + 0x058], %f6 |
| 125 | fmovd %f0, %f16 | 125 | fsrc2 %f0, %f16 |
| 126 | ldd [%o1 + 0x060], %f8 | 126 | ldd [%o1 + 0x060], %f8 |
| 127 | fmovd %f2, %f18 | 127 | fsrc2 %f2, %f18 |
| 128 | ldd [%o1 + 0x068], %f10 | 128 | ldd [%o1 + 0x068], %f10 |
| 129 | fmovd %f4, %f20 | 129 | fsrc2 %f4, %f20 |
| 130 | ldd [%o1 + 0x070], %f12 | 130 | ldd [%o1 + 0x070], %f12 |
| 131 | fmovd %f6, %f22 | 131 | fsrc2 %f6, %f22 |
| 132 | ldd [%o1 + 0x078], %f14 | 132 | ldd [%o1 + 0x078], %f14 |
| 133 | fmovd %f8, %f24 | 133 | fsrc2 %f8, %f24 |
| 134 | ldd [%o1 + 0x080], %f0 | 134 | ldd [%o1 + 0x080], %f0 |
| 135 | prefetch [%o1 + 0x180], #one_read | 135 | prefetch [%o1 + 0x180], #one_read |
| 136 | fmovd %f10, %f26 | 136 | fsrc2 %f10, %f26 |
| 137 | subcc %o2, 1, %o2 | 137 | subcc %o2, 1, %o2 |
| 138 | add %o0, 0x40, %o0 | 138 | add %o0, 0x40, %o0 |
| 139 | bne,pt %xcc, 1b | 139 | bne,pt %xcc, 1b |
| 140 | add %o1, 0x40, %o1 | 140 | add %o1, 0x40, %o1 |
| 141 | 141 | ||
| 142 | ldd [%o1 + 0x048], %f2 | 142 | ldd [%o1 + 0x048], %f2 |
| 143 | fmovd %f12, %f28 | 143 | fsrc2 %f12, %f28 |
| 144 | ldd [%o1 + 0x050], %f4 | 144 | ldd [%o1 + 0x050], %f4 |
| 145 | fmovd %f14, %f30 | 145 | fsrc2 %f14, %f30 |
| 146 | stda %f16, [%o0] ASI_BLK_P | 146 | stda %f16, [%o0] ASI_BLK_P |
| 147 | ldd [%o1 + 0x058], %f6 | 147 | ldd [%o1 + 0x058], %f6 |
| 148 | fmovd %f0, %f16 | 148 | fsrc2 %f0, %f16 |
| 149 | ldd [%o1 + 0x060], %f8 | 149 | ldd [%o1 + 0x060], %f8 |
| 150 | fmovd %f2, %f18 | 150 | fsrc2 %f2, %f18 |
| 151 | ldd [%o1 + 0x068], %f10 | 151 | ldd [%o1 + 0x068], %f10 |
| 152 | fmovd %f4, %f20 | 152 | fsrc2 %f4, %f20 |
| 153 | ldd [%o1 + 0x070], %f12 | 153 | ldd [%o1 + 0x070], %f12 |
| 154 | fmovd %f6, %f22 | 154 | fsrc2 %f6, %f22 |
| 155 | add %o0, 0x40, %o0 | 155 | add %o0, 0x40, %o0 |
| 156 | ldd [%o1 + 0x078], %f14 | 156 | ldd [%o1 + 0x078], %f14 |
| 157 | fmovd %f8, %f24 | 157 | fsrc2 %f8, %f24 |
| 158 | fmovd %f10, %f26 | 158 | fsrc2 %f10, %f26 |
| 159 | fmovd %f12, %f28 | 159 | fsrc2 %f12, %f28 |
| 160 | fmovd %f14, %f30 | 160 | fsrc2 %f14, %f30 |
| 161 | stda %f16, [%o0] ASI_BLK_P | 161 | stda %f16, [%o0] ASI_BLK_P |
| 162 | membar #Sync | 162 | membar #Sync |
| 163 | VISExitHalf | 163 | VISExitHalf |
diff --git a/arch/sparc/mm/fault_32.c b/arch/sparc/mm/fault_32.c index f46cf6be3370..77ac917be152 100644 --- a/arch/sparc/mm/fault_32.c +++ b/arch/sparc/mm/fault_32.c | |||
| @@ -32,24 +32,6 @@ | |||
| 32 | 32 | ||
| 33 | int show_unhandled_signals = 1; | 33 | int show_unhandled_signals = 1; |
| 34 | 34 | ||
| 35 | /* At boot time we determine these two values necessary for setting | ||
| 36 | * up the segment maps and page table entries (pte's). | ||
| 37 | */ | ||
| 38 | |||
| 39 | int num_contexts; | ||
| 40 | |||
| 41 | /* Return how much physical memory we have. */ | ||
| 42 | unsigned long probe_memory(void) | ||
| 43 | { | ||
| 44 | unsigned long total = 0; | ||
| 45 | int i; | ||
| 46 | |||
| 47 | for (i = 0; sp_banks[i].num_bytes; i++) | ||
| 48 | total += sp_banks[i].num_bytes; | ||
| 49 | |||
| 50 | return total; | ||
| 51 | } | ||
| 52 | |||
| 53 | static void unhandled_fault(unsigned long, struct task_struct *, | 35 | static void unhandled_fault(unsigned long, struct task_struct *, |
| 54 | struct pt_regs *) __attribute__ ((noreturn)); | 36 | struct pt_regs *) __attribute__ ((noreturn)); |
| 55 | 37 | ||
diff --git a/arch/sparc/mm/highmem.c b/arch/sparc/mm/highmem.c index 055c66cf1bf4..449f864f0cef 100644 --- a/arch/sparc/mm/highmem.c +++ b/arch/sparc/mm/highmem.c | |||
| @@ -22,13 +22,31 @@ | |||
| 22 | * shared by CPUs, and so precious, and establishing them requires IPI. | 22 | * shared by CPUs, and so precious, and establishing them requires IPI. |
| 23 | * Atomic kmaps are lightweight and we may have NCPUS more of them. | 23 | * Atomic kmaps are lightweight and we may have NCPUS more of them. |
| 24 | */ | 24 | */ |
| 25 | #include <linux/mm.h> | ||
| 26 | #include <linux/highmem.h> | 25 | #include <linux/highmem.h> |
| 27 | #include <linux/export.h> | 26 | #include <linux/export.h> |
| 28 | #include <asm/pgalloc.h> | 27 | #include <linux/mm.h> |
| 28 | |||
| 29 | #include <asm/cacheflush.h> | 29 | #include <asm/cacheflush.h> |
| 30 | #include <asm/tlbflush.h> | 30 | #include <asm/tlbflush.h> |
| 31 | #include <asm/fixmap.h> | 31 | #include <asm/pgalloc.h> |
| 32 | #include <asm/vaddrs.h> | ||
| 33 | |||
| 34 | pgprot_t kmap_prot; | ||
| 35 | |||
| 36 | static pte_t *kmap_pte; | ||
| 37 | |||
| 38 | void __init kmap_init(void) | ||
| 39 | { | ||
| 40 | unsigned long address; | ||
| 41 | pmd_t *dir; | ||
| 42 | |||
| 43 | address = __fix_to_virt(FIX_KMAP_BEGIN); | ||
| 44 | dir = pmd_offset(pgd_offset_k(address), address); | ||
| 45 | |||
| 46 | /* cache the first kmap pte */ | ||
| 47 | kmap_pte = pte_offset_kernel(dir, address); | ||
| 48 | kmap_prot = __pgprot(SRMMU_ET_PTE | SRMMU_PRIV | SRMMU_CACHE); | ||
| 49 | } | ||
| 32 | 50 | ||
| 33 | void *kmap_atomic(struct page *page) | 51 | void *kmap_atomic(struct page *page) |
| 34 | { | 52 | { |
| @@ -110,21 +128,3 @@ void __kunmap_atomic(void *kvaddr) | |||
| 110 | pagefault_enable(); | 128 | pagefault_enable(); |
| 111 | } | 129 | } |
| 112 | EXPORT_SYMBOL(__kunmap_atomic); | 130 | EXPORT_SYMBOL(__kunmap_atomic); |
| 113 | |||
| 114 | /* We may be fed a pagetable here by ptep_to_xxx and others. */ | ||
| 115 | struct page *kmap_atomic_to_page(void *ptr) | ||
| 116 | { | ||
| 117 | unsigned long idx, vaddr = (unsigned long)ptr; | ||
| 118 | pte_t *pte; | ||
| 119 | |||
| 120 | if (vaddr < SRMMU_NOCACHE_VADDR) | ||
| 121 | return virt_to_page(ptr); | ||
| 122 | if (vaddr < PKMAP_BASE) | ||
| 123 | return pfn_to_page(__nocache_pa(vaddr) >> PAGE_SHIFT); | ||
| 124 | BUG_ON(vaddr < FIXADDR_START); | ||
| 125 | BUG_ON(vaddr > FIXADDR_TOP); | ||
| 126 | |||
| 127 | idx = virt_to_fix(vaddr); | ||
| 128 | pte = kmap_pte - (idx - FIX_KMAP_BEGIN); | ||
| 129 | return pte_page(*pte); | ||
| 130 | } | ||
diff --git a/arch/sparc/mm/init_32.c b/arch/sparc/mm/init_32.c index ef5c779ec855..dde85ef1c56d 100644 --- a/arch/sparc/mm/init_32.c +++ b/arch/sparc/mm/init_32.c | |||
| @@ -45,9 +45,6 @@ unsigned long pfn_base; | |||
| 45 | EXPORT_SYMBOL(pfn_base); | 45 | EXPORT_SYMBOL(pfn_base); |
| 46 | 46 | ||
| 47 | struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS+1]; | 47 | struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS+1]; |
| 48 | unsigned long sparc_unmapped_base; | ||
| 49 | |||
| 50 | struct pgtable_cache_struct pgt_quicklists; | ||
| 51 | 48 | ||
| 52 | /* Initial ramdisk setup */ | 49 | /* Initial ramdisk setup */ |
| 53 | extern unsigned int sparc_ramdisk_image; | 50 | extern unsigned int sparc_ramdisk_image; |
| @@ -55,19 +52,6 @@ extern unsigned int sparc_ramdisk_size; | |||
| 55 | 52 | ||
| 56 | unsigned long highstart_pfn, highend_pfn; | 53 | unsigned long highstart_pfn, highend_pfn; |
| 57 | 54 | ||
| 58 | pte_t *kmap_pte; | ||
| 59 | pgprot_t kmap_prot; | ||
| 60 | |||
| 61 | #define kmap_get_fixmap_pte(vaddr) \ | ||
| 62 | pte_offset_kernel(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)) | ||
| 63 | |||
| 64 | void __init kmap_init(void) | ||
| 65 | { | ||
| 66 | /* cache the first kmap pte */ | ||
| 67 | kmap_pte = kmap_get_fixmap_pte(__fix_to_virt(FIX_KMAP_BEGIN)); | ||
| 68 | kmap_prot = __pgprot(SRMMU_ET_PTE | SRMMU_PRIV | SRMMU_CACHE); | ||
| 69 | } | ||
| 70 | |||
| 71 | void show_mem(unsigned int filter) | 55 | void show_mem(unsigned int filter) |
| 72 | { | 56 | { |
| 73 | printk("Mem-info:\n"); | 57 | printk("Mem-info:\n"); |
| @@ -76,33 +60,8 @@ void show_mem(unsigned int filter) | |||
| 76 | nr_swap_pages << (PAGE_SHIFT-10)); | 60 | nr_swap_pages << (PAGE_SHIFT-10)); |
| 77 | printk("%ld pages of RAM\n", totalram_pages); | 61 | printk("%ld pages of RAM\n", totalram_pages); |
| 78 | printk("%ld free pages\n", nr_free_pages()); | 62 | printk("%ld free pages\n", nr_free_pages()); |
| 79 | #if 0 /* undefined pgtable_cache_size, pgd_cache_size */ | ||
| 80 | printk("%ld pages in page table cache\n",pgtable_cache_size); | ||
| 81 | #ifndef CONFIG_SMP | ||
| 82 | if (sparc_cpu_model == sun4m || sparc_cpu_model == sun4d) | ||
| 83 | printk("%ld entries in page dir cache\n",pgd_cache_size); | ||
| 84 | #endif | ||
| 85 | #endif | ||
| 86 | } | 63 | } |
| 87 | 64 | ||
| 88 | void __init sparc_context_init(int numctx) | ||
| 89 | { | ||
| 90 | int ctx; | ||
| 91 | |||
| 92 | ctx_list_pool = __alloc_bootmem(numctx * sizeof(struct ctx_list), SMP_CACHE_BYTES, 0UL); | ||
| 93 | |||
| 94 | for(ctx = 0; ctx < numctx; ctx++) { | ||
| 95 | struct ctx_list *clist; | ||
| 96 | |||
| 97 | clist = (ctx_list_pool + ctx); | ||
| 98 | clist->ctx_number = ctx; | ||
| 99 | clist->ctx_mm = NULL; | ||
| 100 | } | ||
| 101 | ctx_free.next = ctx_free.prev = &ctx_free; | ||
| 102 | ctx_used.next = ctx_used.prev = &ctx_used; | ||
| 103 | for(ctx = 0; ctx < numctx; ctx++) | ||
| 104 | add_to_free_ctxlist(ctx_list_pool + ctx); | ||
| 105 | } | ||
| 106 | 65 | ||
| 107 | extern unsigned long cmdline_memory_size; | 66 | extern unsigned long cmdline_memory_size; |
| 108 | unsigned long last_valid_pfn; | 67 | unsigned long last_valid_pfn; |
| @@ -292,22 +251,7 @@ extern void device_scan(void); | |||
| 292 | 251 | ||
| 293 | void __init paging_init(void) | 252 | void __init paging_init(void) |
| 294 | { | 253 | { |
| 295 | switch(sparc_cpu_model) { | 254 | srmmu_paging_init(); |
| 296 | case sparc_leon: | ||
| 297 | leon_init(); | ||
| 298 | /* fall through */ | ||
| 299 | case sun4m: | ||
| 300 | case sun4d: | ||
| 301 | srmmu_paging_init(); | ||
| 302 | sparc_unmapped_base = 0x50000000; | ||
| 303 | break; | ||
| 304 | default: | ||
| 305 | prom_printf("paging_init: Cannot init paging on this Sparc\n"); | ||
| 306 | prom_printf("paging_init: sparc_cpu_model = %d\n", sparc_cpu_model); | ||
| 307 | prom_printf("paging_init: Halting...\n"); | ||
| 308 | prom_halt(); | ||
| 309 | } | ||
| 310 | |||
| 311 | prom_build_devicetree(); | 255 | prom_build_devicetree(); |
| 312 | of_fill_in_cpu_data(); | 256 | of_fill_in_cpu_data(); |
| 313 | device_scan(); | 257 | device_scan(); |
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c index 62e3f5773303..c38bb72e3e80 100644 --- a/arch/sparc/mm/srmmu.c +++ b/arch/sparc/mm/srmmu.c | |||
| @@ -8,45 +8,45 @@ | |||
| 8 | * Copyright (C) 1999,2000 Anton Blanchard (anton@samba.org) | 8 | * Copyright (C) 1999,2000 Anton Blanchard (anton@samba.org) |
| 9 | */ | 9 | */ |
| 10 | 10 | ||
| 11 | #include <linux/kernel.h> | 11 | #include <linux/seq_file.h> |
| 12 | #include <linux/mm.h> | ||
| 13 | #include <linux/vmalloc.h> | ||
| 14 | #include <linux/pagemap.h> | ||
| 15 | #include <linux/init.h> | ||
| 16 | #include <linux/spinlock.h> | 12 | #include <linux/spinlock.h> |
| 17 | #include <linux/bootmem.h> | 13 | #include <linux/bootmem.h> |
| 18 | #include <linux/fs.h> | 14 | #include <linux/pagemap.h> |
| 19 | #include <linux/seq_file.h> | 15 | #include <linux/vmalloc.h> |
| 20 | #include <linux/kdebug.h> | 16 | #include <linux/kdebug.h> |
| 17 | #include <linux/kernel.h> | ||
| 18 | #include <linux/init.h> | ||
| 21 | #include <linux/log2.h> | 19 | #include <linux/log2.h> |
| 22 | #include <linux/gfp.h> | 20 | #include <linux/gfp.h> |
| 21 | #include <linux/fs.h> | ||
| 22 | #include <linux/mm.h> | ||
| 23 | 23 | ||
| 24 | #include <asm/bitext.h> | 24 | #include <asm/mmu_context.h> |
| 25 | #include <asm/page.h> | 25 | #include <asm/cacheflush.h> |
| 26 | #include <asm/tlbflush.h> | ||
| 27 | #include <asm/io-unit.h> | ||
| 26 | #include <asm/pgalloc.h> | 28 | #include <asm/pgalloc.h> |
| 27 | #include <asm/pgtable.h> | 29 | #include <asm/pgtable.h> |
| 28 | #include <asm/io.h> | 30 | #include <asm/bitext.h> |
| 29 | #include <asm/vaddrs.h> | 31 | #include <asm/vaddrs.h> |
| 30 | #include <asm/traps.h> | ||
| 31 | #include <asm/smp.h> | ||
| 32 | #include <asm/mbus.h> | ||
| 33 | #include <asm/cache.h> | 32 | #include <asm/cache.h> |
| 33 | #include <asm/traps.h> | ||
| 34 | #include <asm/oplib.h> | 34 | #include <asm/oplib.h> |
| 35 | #include <asm/mbus.h> | ||
| 36 | #include <asm/page.h> | ||
| 35 | #include <asm/asi.h> | 37 | #include <asm/asi.h> |
| 36 | #include <asm/msi.h> | 38 | #include <asm/msi.h> |
| 37 | #include <asm/mmu_context.h> | 39 | #include <asm/smp.h> |
| 38 | #include <asm/io-unit.h> | 40 | #include <asm/io.h> |
| 39 | #include <asm/cacheflush.h> | ||
| 40 | #include <asm/tlbflush.h> | ||
| 41 | 41 | ||
| 42 | /* Now the cpu specific definitions. */ | 42 | /* Now the cpu specific definitions. */ |
| 43 | #include <asm/viking.h> | 43 | #include <asm/turbosparc.h> |
| 44 | #include <asm/mxcc.h> | ||
| 45 | #include <asm/ross.h> | ||
| 46 | #include <asm/tsunami.h> | 44 | #include <asm/tsunami.h> |
| 45 | #include <asm/viking.h> | ||
| 47 | #include <asm/swift.h> | 46 | #include <asm/swift.h> |
| 48 | #include <asm/turbosparc.h> | ||
| 49 | #include <asm/leon.h> | 47 | #include <asm/leon.h> |
| 48 | #include <asm/mxcc.h> | ||
| 49 | #include <asm/ross.h> | ||
| 50 | 50 | ||
| 51 | #include "srmmu.h" | 51 | #include "srmmu.h" |
| 52 | 52 | ||
| @@ -55,10 +55,6 @@ static unsigned int hwbug_bitmask; | |||
| 55 | int vac_cache_size; | 55 | int vac_cache_size; |
| 56 | int vac_line_size; | 56 | int vac_line_size; |
| 57 | 57 | ||
| 58 | struct ctx_list *ctx_list_pool; | ||
| 59 | struct ctx_list ctx_free; | ||
| 60 | struct ctx_list ctx_used; | ||
| 61 | |||
| 62 | extern struct resource sparc_iomap; | 58 | extern struct resource sparc_iomap; |
| 63 | 59 | ||
| 64 | extern unsigned long last_valid_pfn; | 60 | extern unsigned long last_valid_pfn; |
| @@ -136,8 +132,8 @@ void pmd_populate(struct mm_struct *mm, pmd_t *pmdp, struct page *ptep) | |||
| 136 | } | 132 | } |
| 137 | } | 133 | } |
| 138 | 134 | ||
| 139 | /* Find an entry in the third-level page table.. */ | 135 | /* Find an entry in the third-level page table.. */ |
| 140 | pte_t *pte_offset_kernel(pmd_t * dir, unsigned long address) | 136 | pte_t *pte_offset_kernel(pmd_t *dir, unsigned long address) |
| 141 | { | 137 | { |
| 142 | void *pte; | 138 | void *pte; |
| 143 | 139 | ||
| @@ -151,55 +147,61 @@ pte_t *pte_offset_kernel(pmd_t * dir, unsigned long address) | |||
| 151 | * align: bytes, number to align at. | 147 | * align: bytes, number to align at. |
| 152 | * Returns the virtual address of the allocated area. | 148 | * Returns the virtual address of the allocated area. |
| 153 | */ | 149 | */ |
| 154 | static unsigned long __srmmu_get_nocache(int size, int align) | 150 | static void *__srmmu_get_nocache(int size, int align) |
| 155 | { | 151 | { |
| 156 | int offset; | 152 | int offset; |
| 153 | unsigned long addr; | ||
| 157 | 154 | ||
| 158 | if (size < SRMMU_NOCACHE_BITMAP_SHIFT) { | 155 | if (size < SRMMU_NOCACHE_BITMAP_SHIFT) { |
| 159 | printk("Size 0x%x too small for nocache request\n", size); | 156 | printk(KERN_ERR "Size 0x%x too small for nocache request\n", |
| 157 | size); | ||
| 160 | size = SRMMU_NOCACHE_BITMAP_SHIFT; | 158 | size = SRMMU_NOCACHE_BITMAP_SHIFT; |
| 161 | } | 159 | } |
| 162 | if (size & (SRMMU_NOCACHE_BITMAP_SHIFT-1)) { | 160 | if (size & (SRMMU_NOCACHE_BITMAP_SHIFT - 1)) { |
| 163 | printk("Size 0x%x unaligned int nocache request\n", size); | 161 | printk(KERN_ERR "Size 0x%x unaligned int nocache request\n", |
| 164 | size += SRMMU_NOCACHE_BITMAP_SHIFT-1; | 162 | size); |
| 163 | size += SRMMU_NOCACHE_BITMAP_SHIFT - 1; | ||
| 165 | } | 164 | } |
| 166 | BUG_ON(align > SRMMU_NOCACHE_ALIGN_MAX); | 165 | BUG_ON(align > SRMMU_NOCACHE_ALIGN_MAX); |
| 167 | 166 | ||
| 168 | offset = bit_map_string_get(&srmmu_nocache_map, | 167 | offset = bit_map_string_get(&srmmu_nocache_map, |
| 169 | size >> SRMMU_NOCACHE_BITMAP_SHIFT, | 168 | size >> SRMMU_NOCACHE_BITMAP_SHIFT, |
| 170 | align >> SRMMU_NOCACHE_BITMAP_SHIFT); | 169 | align >> SRMMU_NOCACHE_BITMAP_SHIFT); |
| 171 | if (offset == -1) { | 170 | if (offset == -1) { |
| 172 | printk("srmmu: out of nocache %d: %d/%d\n", | 171 | printk(KERN_ERR "srmmu: out of nocache %d: %d/%d\n", |
| 173 | size, (int) srmmu_nocache_size, | 172 | size, (int) srmmu_nocache_size, |
| 174 | srmmu_nocache_map.used << SRMMU_NOCACHE_BITMAP_SHIFT); | 173 | srmmu_nocache_map.used << SRMMU_NOCACHE_BITMAP_SHIFT); |
| 175 | return 0; | 174 | return 0; |
| 176 | } | 175 | } |
| 177 | 176 | ||
| 178 | return (SRMMU_NOCACHE_VADDR + (offset << SRMMU_NOCACHE_BITMAP_SHIFT)); | 177 | addr = SRMMU_NOCACHE_VADDR + (offset << SRMMU_NOCACHE_BITMAP_SHIFT); |
| 178 | return (void *)addr; | ||
| 179 | } | 179 | } |
| 180 | 180 | ||
| 181 | unsigned long srmmu_get_nocache(int size, int align) | 181 | void *srmmu_get_nocache(int size, int align) |
| 182 | { | 182 | { |
| 183 | unsigned long tmp; | 183 | void *tmp; |
| 184 | 184 | ||
| 185 | tmp = __srmmu_get_nocache(size, align); | 185 | tmp = __srmmu_get_nocache(size, align); |
| 186 | 186 | ||
| 187 | if (tmp) | 187 | if (tmp) |
| 188 | memset((void *)tmp, 0, size); | 188 | memset(tmp, 0, size); |
| 189 | 189 | ||
| 190 | return tmp; | 190 | return tmp; |
| 191 | } | 191 | } |
| 192 | 192 | ||
| 193 | void srmmu_free_nocache(unsigned long vaddr, int size) | 193 | void srmmu_free_nocache(void *addr, int size) |
| 194 | { | 194 | { |
| 195 | unsigned long vaddr; | ||
| 195 | int offset; | 196 | int offset; |
| 196 | 197 | ||
| 198 | vaddr = (unsigned long)addr; | ||
| 197 | if (vaddr < SRMMU_NOCACHE_VADDR) { | 199 | if (vaddr < SRMMU_NOCACHE_VADDR) { |
| 198 | printk("Vaddr %lx is smaller than nocache base 0x%lx\n", | 200 | printk("Vaddr %lx is smaller than nocache base 0x%lx\n", |
| 199 | vaddr, (unsigned long)SRMMU_NOCACHE_VADDR); | 201 | vaddr, (unsigned long)SRMMU_NOCACHE_VADDR); |
| 200 | BUG(); | 202 | BUG(); |
| 201 | } | 203 | } |
| 202 | if (vaddr+size > srmmu_nocache_end) { | 204 | if (vaddr + size > srmmu_nocache_end) { |
| 203 | printk("Vaddr %lx is bigger than nocache end 0x%lx\n", | 205 | printk("Vaddr %lx is bigger than nocache end 0x%lx\n", |
| 204 | vaddr, srmmu_nocache_end); | 206 | vaddr, srmmu_nocache_end); |
| 205 | BUG(); | 207 | BUG(); |
| @@ -212,7 +214,7 @@ void srmmu_free_nocache(unsigned long vaddr, int size) | |||
| 212 | printk("Size 0x%x is too small\n", size); | 214 | printk("Size 0x%x is too small\n", size); |
| 213 | BUG(); | 215 | BUG(); |
| 214 | } | 216 | } |
| 215 | if (vaddr & (size-1)) { | 217 | if (vaddr & (size - 1)) { |
| 216 | printk("Vaddr %lx is not aligned to size 0x%x\n", vaddr, size); | 218 | printk("Vaddr %lx is not aligned to size 0x%x\n", vaddr, size); |
| 217 | BUG(); | 219 | BUG(); |
| 218 | } | 220 | } |
| @@ -226,13 +228,23 @@ void srmmu_free_nocache(unsigned long vaddr, int size) | |||
| 226 | static void srmmu_early_allocate_ptable_skeleton(unsigned long start, | 228 | static void srmmu_early_allocate_ptable_skeleton(unsigned long start, |
| 227 | unsigned long end); | 229 | unsigned long end); |
| 228 | 230 | ||
| 229 | extern unsigned long probe_memory(void); /* in fault.c */ | 231 | /* Return how much physical memory we have. */ |
| 232 | static unsigned long __init probe_memory(void) | ||
| 233 | { | ||
| 234 | unsigned long total = 0; | ||
| 235 | int i; | ||
| 236 | |||
| 237 | for (i = 0; sp_banks[i].num_bytes; i++) | ||
| 238 | total += sp_banks[i].num_bytes; | ||
| 239 | |||
| 240 | return total; | ||
| 241 | } | ||
| 230 | 242 | ||
| 231 | /* | 243 | /* |
| 232 | * Reserve nocache dynamically proportionally to the amount of | 244 | * Reserve nocache dynamically proportionally to the amount of |
| 233 | * system RAM. -- Tomas Szepe <szepe@pinerecords.com>, June 2002 | 245 | * system RAM. -- Tomas Szepe <szepe@pinerecords.com>, June 2002 |
| 234 | */ | 246 | */ |
| 235 | static void srmmu_nocache_calcsize(void) | 247 | static void __init srmmu_nocache_calcsize(void) |
| 236 | { | 248 | { |
| 237 | unsigned long sysmemavail = probe_memory() / 1024; | 249 | unsigned long sysmemavail = probe_memory() / 1024; |
| 238 | int srmmu_nocache_npages; | 250 | int srmmu_nocache_npages; |
| @@ -271,7 +283,7 @@ static void __init srmmu_nocache_init(void) | |||
| 271 | srmmu_nocache_bitmap = __alloc_bootmem(bitmap_bits >> 3, SMP_CACHE_BYTES, 0UL); | 283 | srmmu_nocache_bitmap = __alloc_bootmem(bitmap_bits >> 3, SMP_CACHE_BYTES, 0UL); |
| 272 | bit_map_init(&srmmu_nocache_map, srmmu_nocache_bitmap, bitmap_bits); | 284 | bit_map_init(&srmmu_nocache_map, srmmu_nocache_bitmap, bitmap_bits); |
| 273 | 285 | ||
| 274 | srmmu_swapper_pg_dir = (pgd_t *)__srmmu_get_nocache(SRMMU_PGD_TABLE_SIZE, SRMMU_PGD_TABLE_SIZE); | 286 | srmmu_swapper_pg_dir = __srmmu_get_nocache(SRMMU_PGD_TABLE_SIZE, SRMMU_PGD_TABLE_SIZE); |
| 275 | memset(__nocache_fix(srmmu_swapper_pg_dir), 0, SRMMU_PGD_TABLE_SIZE); | 287 | memset(__nocache_fix(srmmu_swapper_pg_dir), 0, SRMMU_PGD_TABLE_SIZE); |
| 276 | init_mm.pgd = srmmu_swapper_pg_dir; | 288 | init_mm.pgd = srmmu_swapper_pg_dir; |
| 277 | 289 | ||
| @@ -304,7 +316,7 @@ pgd_t *get_pgd_fast(void) | |||
| 304 | { | 316 | { |
| 305 | pgd_t *pgd = NULL; | 317 | pgd_t *pgd = NULL; |
| 306 | 318 | ||
| 307 | pgd = (pgd_t *)__srmmu_get_nocache(SRMMU_PGD_TABLE_SIZE, SRMMU_PGD_TABLE_SIZE); | 319 | pgd = __srmmu_get_nocache(SRMMU_PGD_TABLE_SIZE, SRMMU_PGD_TABLE_SIZE); |
| 308 | if (pgd) { | 320 | if (pgd) { |
| 309 | pgd_t *init = pgd_offset_k(0); | 321 | pgd_t *init = pgd_offset_k(0); |
| 310 | memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t)); | 322 | memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t)); |
| @@ -330,7 +342,7 @@ pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address) | |||
| 330 | 342 | ||
| 331 | if ((pte = (unsigned long)pte_alloc_one_kernel(mm, address)) == 0) | 343 | if ((pte = (unsigned long)pte_alloc_one_kernel(mm, address)) == 0) |
| 332 | return NULL; | 344 | return NULL; |
| 333 | page = pfn_to_page( __nocache_pa(pte) >> PAGE_SHIFT ); | 345 | page = pfn_to_page(__nocache_pa(pte) >> PAGE_SHIFT); |
| 334 | pgtable_page_ctor(page); | 346 | pgtable_page_ctor(page); |
| 335 | return page; | 347 | return page; |
| 336 | } | 348 | } |
| @@ -344,18 +356,50 @@ void pte_free(struct mm_struct *mm, pgtable_t pte) | |||
| 344 | if (p == 0) | 356 | if (p == 0) |
| 345 | BUG(); | 357 | BUG(); |
| 346 | p = page_to_pfn(pte) << PAGE_SHIFT; /* Physical address */ | 358 | p = page_to_pfn(pte) << PAGE_SHIFT; /* Physical address */ |
| 347 | p = (unsigned long) __nocache_va(p); /* Nocached virtual */ | 359 | |
| 348 | srmmu_free_nocache(p, PTE_SIZE); | 360 | /* free non cached virtual address*/ |
| 361 | srmmu_free_nocache(__nocache_va(p), PTE_SIZE); | ||
| 349 | } | 362 | } |
| 350 | 363 | ||
| 351 | /* | 364 | /* context handling - a dynamically sized pool is used */ |
| 352 | */ | 365 | #define NO_CONTEXT -1 |
| 366 | |||
| 367 | struct ctx_list { | ||
| 368 | struct ctx_list *next; | ||
| 369 | struct ctx_list *prev; | ||
| 370 | unsigned int ctx_number; | ||
| 371 | struct mm_struct *ctx_mm; | ||
| 372 | }; | ||
| 373 | |||
| 374 | static struct ctx_list *ctx_list_pool; | ||
| 375 | static struct ctx_list ctx_free; | ||
| 376 | static struct ctx_list ctx_used; | ||
| 377 | |||
| 378 | /* At boot time we determine the number of contexts */ | ||
| 379 | static int num_contexts; | ||
| 380 | |||
| 381 | static inline void remove_from_ctx_list(struct ctx_list *entry) | ||
| 382 | { | ||
| 383 | entry->next->prev = entry->prev; | ||
| 384 | entry->prev->next = entry->next; | ||
| 385 | } | ||
| 386 | |||
| 387 | static inline void add_to_ctx_list(struct ctx_list *head, struct ctx_list *entry) | ||
| 388 | { | ||
| 389 | entry->next = head; | ||
| 390 | (entry->prev = head->prev)->next = entry; | ||
| 391 | head->prev = entry; | ||
| 392 | } | ||
| 393 | #define add_to_free_ctxlist(entry) add_to_ctx_list(&ctx_free, entry) | ||
| 394 | #define add_to_used_ctxlist(entry) add_to_ctx_list(&ctx_used, entry) | ||
| 395 | |||
| 396 | |||
| 353 | static inline void alloc_context(struct mm_struct *old_mm, struct mm_struct *mm) | 397 | static inline void alloc_context(struct mm_struct *old_mm, struct mm_struct *mm) |
| 354 | { | 398 | { |
| 355 | struct ctx_list *ctxp; | 399 | struct ctx_list *ctxp; |
| 356 | 400 | ||
| 357 | ctxp = ctx_free.next; | 401 | ctxp = ctx_free.next; |
| 358 | if(ctxp != &ctx_free) { | 402 | if (ctxp != &ctx_free) { |
| 359 | remove_from_ctx_list(ctxp); | 403 | remove_from_ctx_list(ctxp); |
| 360 | add_to_used_ctxlist(ctxp); | 404 | add_to_used_ctxlist(ctxp); |
| 361 | mm->context = ctxp->ctx_number; | 405 | mm->context = ctxp->ctx_number; |
| @@ -363,9 +407,9 @@ static inline void alloc_context(struct mm_struct *old_mm, struct mm_struct *mm) | |||
| 363 | return; | 407 | return; |
| 364 | } | 408 | } |
| 365 | ctxp = ctx_used.next; | 409 | ctxp = ctx_used.next; |
| 366 | if(ctxp->ctx_mm == old_mm) | 410 | if (ctxp->ctx_mm == old_mm) |
| 367 | ctxp = ctxp->next; | 411 | ctxp = ctxp->next; |
| 368 | if(ctxp == &ctx_used) | 412 | if (ctxp == &ctx_used) |
| 369 | panic("out of mmu contexts"); | 413 | panic("out of mmu contexts"); |
| 370 | flush_cache_mm(ctxp->ctx_mm); | 414 | flush_cache_mm(ctxp->ctx_mm); |
| 371 | flush_tlb_mm(ctxp->ctx_mm); | 415 | flush_tlb_mm(ctxp->ctx_mm); |
| @@ -385,11 +429,31 @@ static inline void free_context(int context) | |||
| 385 | add_to_free_ctxlist(ctx_old); | 429 | add_to_free_ctxlist(ctx_old); |
| 386 | } | 430 | } |
| 387 | 431 | ||
| 432 | static void __init sparc_context_init(int numctx) | ||
| 433 | { | ||
| 434 | int ctx; | ||
| 435 | unsigned long size; | ||
| 436 | |||
| 437 | size = numctx * sizeof(struct ctx_list); | ||
| 438 | ctx_list_pool = __alloc_bootmem(size, SMP_CACHE_BYTES, 0UL); | ||
| 439 | |||
| 440 | for (ctx = 0; ctx < numctx; ctx++) { | ||
| 441 | struct ctx_list *clist; | ||
| 442 | |||
| 443 | clist = (ctx_list_pool + ctx); | ||
| 444 | clist->ctx_number = ctx; | ||
| 445 | clist->ctx_mm = NULL; | ||
| 446 | } | ||
| 447 | ctx_free.next = ctx_free.prev = &ctx_free; | ||
| 448 | ctx_used.next = ctx_used.prev = &ctx_used; | ||
| 449 | for (ctx = 0; ctx < numctx; ctx++) | ||
| 450 | add_to_free_ctxlist(ctx_list_pool + ctx); | ||
| 451 | } | ||
| 388 | 452 | ||
| 389 | void switch_mm(struct mm_struct *old_mm, struct mm_struct *mm, | 453 | void switch_mm(struct mm_struct *old_mm, struct mm_struct *mm, |
| 390 | struct task_struct *tsk) | 454 | struct task_struct *tsk) |
| 391 | { | 455 | { |
| 392 | if(mm->context == NO_CONTEXT) { | 456 | if (mm->context == NO_CONTEXT) { |
| 393 | spin_lock(&srmmu_context_spinlock); | 457 | spin_lock(&srmmu_context_spinlock); |
| 394 | alloc_context(old_mm, mm); | 458 | alloc_context(old_mm, mm); |
| 395 | spin_unlock(&srmmu_context_spinlock); | 459 | spin_unlock(&srmmu_context_spinlock); |
| @@ -407,7 +471,7 @@ void switch_mm(struct mm_struct *old_mm, struct mm_struct *mm, | |||
| 407 | 471 | ||
| 408 | /* Low level IO area allocation on the SRMMU. */ | 472 | /* Low level IO area allocation on the SRMMU. */ |
| 409 | static inline void srmmu_mapioaddr(unsigned long physaddr, | 473 | static inline void srmmu_mapioaddr(unsigned long physaddr, |
| 410 | unsigned long virt_addr, int bus_type) | 474 | unsigned long virt_addr, int bus_type) |
| 411 | { | 475 | { |
| 412 | pgd_t *pgdp; | 476 | pgd_t *pgdp; |
| 413 | pmd_t *pmdp; | 477 | pmd_t *pmdp; |
| @@ -420,8 +484,7 @@ static inline void srmmu_mapioaddr(unsigned long physaddr, | |||
| 420 | ptep = pte_offset_kernel(pmdp, virt_addr); | 484 | ptep = pte_offset_kernel(pmdp, virt_addr); |
| 421 | tmp = (physaddr >> 4) | SRMMU_ET_PTE; | 485 | tmp = (physaddr >> 4) | SRMMU_ET_PTE; |
| 422 | 486 | ||
| 423 | /* | 487 | /* I need to test whether this is consistent over all |
| 424 | * I need to test whether this is consistent over all | ||
| 425 | * sun4m's. The bus_type represents the upper 4 bits of | 488 | * sun4m's. The bus_type represents the upper 4 bits of |
| 426 | * 36-bit physical address on the I/O space lines... | 489 | * 36-bit physical address on the I/O space lines... |
| 427 | */ | 490 | */ |
| @@ -591,10 +654,10 @@ static void __init srmmu_early_allocate_ptable_skeleton(unsigned long start, | |||
| 591 | pmd_t *pmdp; | 654 | pmd_t *pmdp; |
| 592 | pte_t *ptep; | 655 | pte_t *ptep; |
| 593 | 656 | ||
| 594 | while(start < end) { | 657 | while (start < end) { |
| 595 | pgdp = pgd_offset_k(start); | 658 | pgdp = pgd_offset_k(start); |
| 596 | if (pgd_none(*(pgd_t *)__nocache_fix(pgdp))) { | 659 | if (pgd_none(*(pgd_t *)__nocache_fix(pgdp))) { |
| 597 | pmdp = (pmd_t *) __srmmu_get_nocache( | 660 | pmdp = __srmmu_get_nocache( |
| 598 | SRMMU_PMD_TABLE_SIZE, SRMMU_PMD_TABLE_SIZE); | 661 | SRMMU_PMD_TABLE_SIZE, SRMMU_PMD_TABLE_SIZE); |
| 599 | if (pmdp == NULL) | 662 | if (pmdp == NULL) |
| 600 | early_pgtable_allocfail("pmd"); | 663 | early_pgtable_allocfail("pmd"); |
| @@ -602,8 +665,8 @@ static void __init srmmu_early_allocate_ptable_skeleton(unsigned long start, | |||
| 602 | pgd_set(__nocache_fix(pgdp), pmdp); | 665 | pgd_set(__nocache_fix(pgdp), pmdp); |
| 603 | } | 666 | } |
| 604 | pmdp = pmd_offset(__nocache_fix(pgdp), start); | 667 | pmdp = pmd_offset(__nocache_fix(pgdp), start); |
| 605 | if(srmmu_pmd_none(*(pmd_t *)__nocache_fix(pmdp))) { | 668 | if (srmmu_pmd_none(*(pmd_t *)__nocache_fix(pmdp))) { |
| 606 | ptep = (pte_t *)__srmmu_get_nocache(PTE_SIZE, PTE_SIZE); | 669 | ptep = __srmmu_get_nocache(PTE_SIZE, PTE_SIZE); |
| 607 | if (ptep == NULL) | 670 | if (ptep == NULL) |
| 608 | early_pgtable_allocfail("pte"); | 671 | early_pgtable_allocfail("pte"); |
| 609 | memset(__nocache_fix(ptep), 0, PTE_SIZE); | 672 | memset(__nocache_fix(ptep), 0, PTE_SIZE); |
| @@ -622,18 +685,18 @@ static void __init srmmu_allocate_ptable_skeleton(unsigned long start, | |||
| 622 | pmd_t *pmdp; | 685 | pmd_t *pmdp; |
| 623 | pte_t *ptep; | 686 | pte_t *ptep; |
| 624 | 687 | ||
| 625 | while(start < end) { | 688 | while (start < end) { |
| 626 | pgdp = pgd_offset_k(start); | 689 | pgdp = pgd_offset_k(start); |
| 627 | if (pgd_none(*pgdp)) { | 690 | if (pgd_none(*pgdp)) { |
| 628 | pmdp = (pmd_t *)__srmmu_get_nocache(SRMMU_PMD_TABLE_SIZE, SRMMU_PMD_TABLE_SIZE); | 691 | pmdp = __srmmu_get_nocache(SRMMU_PMD_TABLE_SIZE, SRMMU_PMD_TABLE_SIZE); |
| 629 | if (pmdp == NULL) | 692 | if (pmdp == NULL) |
| 630 | early_pgtable_allocfail("pmd"); | 693 | early_pgtable_allocfail("pmd"); |
| 631 | memset(pmdp, 0, SRMMU_PMD_TABLE_SIZE); | 694 | memset(pmdp, 0, SRMMU_PMD_TABLE_SIZE); |
| 632 | pgd_set(pgdp, pmdp); | 695 | pgd_set(pgdp, pmdp); |
| 633 | } | 696 | } |
| 634 | pmdp = pmd_offset(pgdp, start); | 697 | pmdp = pmd_offset(pgdp, start); |
| 635 | if(srmmu_pmd_none(*pmdp)) { | 698 | if (srmmu_pmd_none(*pmdp)) { |
| 636 | ptep = (pte_t *) __srmmu_get_nocache(PTE_SIZE, | 699 | ptep = __srmmu_get_nocache(PTE_SIZE, |
| 637 | PTE_SIZE); | 700 | PTE_SIZE); |
| 638 | if (ptep == NULL) | 701 | if (ptep == NULL) |
| 639 | early_pgtable_allocfail("pte"); | 702 | early_pgtable_allocfail("pte"); |
| @@ -671,72 +734,76 @@ static inline unsigned long srmmu_probe(unsigned long vaddr) | |||
| 671 | static void __init srmmu_inherit_prom_mappings(unsigned long start, | 734 | static void __init srmmu_inherit_prom_mappings(unsigned long start, |
| 672 | unsigned long end) | 735 | unsigned long end) |
| 673 | { | 736 | { |
| 737 | unsigned long probed; | ||
| 738 | unsigned long addr; | ||
| 674 | pgd_t *pgdp; | 739 | pgd_t *pgdp; |
| 675 | pmd_t *pmdp; | 740 | pmd_t *pmdp; |
| 676 | pte_t *ptep; | 741 | pte_t *ptep; |
| 677 | int what = 0; /* 0 = normal-pte, 1 = pmd-level pte, 2 = pgd-level pte */ | 742 | int what; /* 0 = normal-pte, 1 = pmd-level pte, 2 = pgd-level pte */ |
| 678 | unsigned long prompte; | ||
| 679 | 743 | ||
| 680 | while(start <= end) { | 744 | while (start <= end) { |
| 681 | if (start == 0) | 745 | if (start == 0) |
| 682 | break; /* probably wrap around */ | 746 | break; /* probably wrap around */ |
| 683 | if(start == 0xfef00000) | 747 | if (start == 0xfef00000) |
| 684 | start = KADB_DEBUGGER_BEGVM; | 748 | start = KADB_DEBUGGER_BEGVM; |
| 685 | if(!(prompte = srmmu_probe(start))) { | 749 | probed = srmmu_probe(start); |
| 750 | if (!probed) { | ||
| 751 | /* continue probing until we find an entry */ | ||
| 686 | start += PAGE_SIZE; | 752 | start += PAGE_SIZE; |
| 687 | continue; | 753 | continue; |
| 688 | } | 754 | } |
| 689 | 755 | ||
| 690 | /* A red snapper, see what it really is. */ | 756 | /* A red snapper, see what it really is. */ |
| 691 | what = 0; | 757 | what = 0; |
| 692 | 758 | addr = start - PAGE_SIZE; | |
| 693 | if(!(start & ~(SRMMU_REAL_PMD_MASK))) { | 759 | |
| 694 | if(srmmu_probe((start-PAGE_SIZE) + SRMMU_REAL_PMD_SIZE) == prompte) | 760 | if (!(start & ~(SRMMU_REAL_PMD_MASK))) { |
| 761 | if (srmmu_probe(addr + SRMMU_REAL_PMD_SIZE) == probed) | ||
| 695 | what = 1; | 762 | what = 1; |
| 696 | } | 763 | } |
| 697 | 764 | ||
| 698 | if(!(start & ~(SRMMU_PGDIR_MASK))) { | 765 | if (!(start & ~(SRMMU_PGDIR_MASK))) { |
| 699 | if(srmmu_probe((start-PAGE_SIZE) + SRMMU_PGDIR_SIZE) == | 766 | if (srmmu_probe(addr + SRMMU_PGDIR_SIZE) == probed) |
| 700 | prompte) | ||
| 701 | what = 2; | 767 | what = 2; |
| 702 | } | 768 | } |
| 703 | 769 | ||
| 704 | pgdp = pgd_offset_k(start); | 770 | pgdp = pgd_offset_k(start); |
| 705 | if(what == 2) { | 771 | if (what == 2) { |
| 706 | *(pgd_t *)__nocache_fix(pgdp) = __pgd(prompte); | 772 | *(pgd_t *)__nocache_fix(pgdp) = __pgd(probed); |
| 707 | start += SRMMU_PGDIR_SIZE; | 773 | start += SRMMU_PGDIR_SIZE; |
| 708 | continue; | 774 | continue; |
| 709 | } | 775 | } |
| 710 | if (pgd_none(*(pgd_t *)__nocache_fix(pgdp))) { | 776 | if (pgd_none(*(pgd_t *)__nocache_fix(pgdp))) { |
| 711 | pmdp = (pmd_t *)__srmmu_get_nocache(SRMMU_PMD_TABLE_SIZE, SRMMU_PMD_TABLE_SIZE); | 777 | pmdp = __srmmu_get_nocache(SRMMU_PMD_TABLE_SIZE, |
| 778 | SRMMU_PMD_TABLE_SIZE); | ||
| 712 | if (pmdp == NULL) | 779 | if (pmdp == NULL) |
| 713 | early_pgtable_allocfail("pmd"); | 780 | early_pgtable_allocfail("pmd"); |
| 714 | memset(__nocache_fix(pmdp), 0, SRMMU_PMD_TABLE_SIZE); | 781 | memset(__nocache_fix(pmdp), 0, SRMMU_PMD_TABLE_SIZE); |
| 715 | pgd_set(__nocache_fix(pgdp), pmdp); | 782 | pgd_set(__nocache_fix(pgdp), pmdp); |
| 716 | } | 783 | } |
| 717 | pmdp = pmd_offset(__nocache_fix(pgdp), start); | 784 | pmdp = pmd_offset(__nocache_fix(pgdp), start); |
| 718 | if(srmmu_pmd_none(*(pmd_t *)__nocache_fix(pmdp))) { | 785 | if (srmmu_pmd_none(*(pmd_t *)__nocache_fix(pmdp))) { |
| 719 | ptep = (pte_t *) __srmmu_get_nocache(PTE_SIZE, | 786 | ptep = __srmmu_get_nocache(PTE_SIZE, PTE_SIZE); |
| 720 | PTE_SIZE); | ||
| 721 | if (ptep == NULL) | 787 | if (ptep == NULL) |
| 722 | early_pgtable_allocfail("pte"); | 788 | early_pgtable_allocfail("pte"); |
| 723 | memset(__nocache_fix(ptep), 0, PTE_SIZE); | 789 | memset(__nocache_fix(ptep), 0, PTE_SIZE); |
| 724 | pmd_set(__nocache_fix(pmdp), ptep); | 790 | pmd_set(__nocache_fix(pmdp), ptep); |
| 725 | } | 791 | } |
| 726 | if(what == 1) { | 792 | if (what == 1) { |
| 727 | /* | 793 | /* We bend the rule where all 16 PTPs in a pmd_t point |
| 728 | * We bend the rule where all 16 PTPs in a pmd_t point | ||
| 729 | * inside the same PTE page, and we leak a perfectly | 794 | * inside the same PTE page, and we leak a perfectly |
| 730 | * good hardware PTE piece. Alternatives seem worse. | 795 | * good hardware PTE piece. Alternatives seem worse. |
| 731 | */ | 796 | */ |
| 732 | unsigned int x; /* Index of HW PMD in soft cluster */ | 797 | unsigned int x; /* Index of HW PMD in soft cluster */ |
| 798 | unsigned long *val; | ||
| 733 | x = (start >> PMD_SHIFT) & 15; | 799 | x = (start >> PMD_SHIFT) & 15; |
| 734 | *(unsigned long *)__nocache_fix(&pmdp->pmdv[x]) = prompte; | 800 | val = &pmdp->pmdv[x]; |
| 801 | *(unsigned long *)__nocache_fix(val) = probed; | ||
| 735 | start += SRMMU_REAL_PMD_SIZE; | 802 | start += SRMMU_REAL_PMD_SIZE; |
| 736 | continue; | 803 | continue; |
| 737 | } | 804 | } |
| 738 | ptep = pte_offset_kernel(__nocache_fix(pmdp), start); | 805 | ptep = pte_offset_kernel(__nocache_fix(pmdp), start); |
| 739 | *(pte_t *)__nocache_fix(ptep) = __pte(prompte); | 806 | *(pte_t *)__nocache_fix(ptep) = __pte(probed); |
| 740 | start += PAGE_SIZE; | 807 | start += PAGE_SIZE; |
| 741 | } | 808 | } |
| 742 | } | 809 | } |
| @@ -765,18 +832,18 @@ static unsigned long __init map_spbank(unsigned long vbase, int sp_entry) | |||
| 765 | 832 | ||
| 766 | if (vstart < min_vaddr || vstart >= max_vaddr) | 833 | if (vstart < min_vaddr || vstart >= max_vaddr) |
| 767 | return vstart; | 834 | return vstart; |
| 768 | 835 | ||
| 769 | if (vend > max_vaddr || vend < min_vaddr) | 836 | if (vend > max_vaddr || vend < min_vaddr) |
| 770 | vend = max_vaddr; | 837 | vend = max_vaddr; |
| 771 | 838 | ||
| 772 | while(vstart < vend) { | 839 | while (vstart < vend) { |
| 773 | do_large_mapping(vstart, pstart); | 840 | do_large_mapping(vstart, pstart); |
| 774 | vstart += SRMMU_PGDIR_SIZE; pstart += SRMMU_PGDIR_SIZE; | 841 | vstart += SRMMU_PGDIR_SIZE; pstart += SRMMU_PGDIR_SIZE; |
| 775 | } | 842 | } |
| 776 | return vstart; | 843 | return vstart; |
| 777 | } | 844 | } |
| 778 | 845 | ||
| 779 | static inline void map_kernel(void) | 846 | static void __init map_kernel(void) |
| 780 | { | 847 | { |
| 781 | int i; | 848 | int i; |
| 782 | 849 | ||
| @@ -789,9 +856,6 @@ static inline void map_kernel(void) | |||
| 789 | } | 856 | } |
| 790 | } | 857 | } |
| 791 | 858 | ||
| 792 | /* Paging initialization on the Sparc Reference MMU. */ | ||
| 793 | extern void sparc_context_init(int); | ||
| 794 | |||
| 795 | void (*poke_srmmu)(void) __cpuinitdata = NULL; | 859 | void (*poke_srmmu)(void) __cpuinitdata = NULL; |
| 796 | 860 | ||
| 797 | extern unsigned long bootmem_init(unsigned long *pages_avail); | 861 | extern unsigned long bootmem_init(unsigned long *pages_avail); |
| @@ -806,6 +870,7 @@ void __init srmmu_paging_init(void) | |||
| 806 | pte_t *pte; | 870 | pte_t *pte; |
| 807 | unsigned long pages_avail; | 871 | unsigned long pages_avail; |
| 808 | 872 | ||
| 873 | init_mm.context = (unsigned long) NO_CONTEXT; | ||
| 809 | sparc_iomap.start = SUN4M_IOBASE_VADDR; /* 16MB of IOSPACE on all sun4m's. */ | 874 | sparc_iomap.start = SUN4M_IOBASE_VADDR; /* 16MB of IOSPACE on all sun4m's. */ |
| 810 | 875 | ||
| 811 | if (sparc_cpu_model == sun4d) | 876 | if (sparc_cpu_model == sun4d) |
| @@ -814,9 +879,9 @@ void __init srmmu_paging_init(void) | |||
| 814 | /* Find the number of contexts on the srmmu. */ | 879 | /* Find the number of contexts on the srmmu. */ |
| 815 | cpunode = prom_getchild(prom_root_node); | 880 | cpunode = prom_getchild(prom_root_node); |
| 816 | num_contexts = 0; | 881 | num_contexts = 0; |
| 817 | while(cpunode != 0) { | 882 | while (cpunode != 0) { |
| 818 | prom_getstring(cpunode, "device_type", node_str, sizeof(node_str)); | 883 | prom_getstring(cpunode, "device_type", node_str, sizeof(node_str)); |
| 819 | if(!strcmp(node_str, "cpu")) { | 884 | if (!strcmp(node_str, "cpu")) { |
| 820 | num_contexts = prom_getintdefault(cpunode, "mmu-nctx", 0x8); | 885 | num_contexts = prom_getintdefault(cpunode, "mmu-nctx", 0x8); |
| 821 | break; | 886 | break; |
| 822 | } | 887 | } |
| @@ -824,7 +889,7 @@ void __init srmmu_paging_init(void) | |||
| 824 | } | 889 | } |
| 825 | } | 890 | } |
| 826 | 891 | ||
| 827 | if(!num_contexts) { | 892 | if (!num_contexts) { |
| 828 | prom_printf("Something wrong, can't find cpu node in paging_init.\n"); | 893 | prom_printf("Something wrong, can't find cpu node in paging_init.\n"); |
| 829 | prom_halt(); | 894 | prom_halt(); |
| 830 | } | 895 | } |
| @@ -834,14 +899,14 @@ void __init srmmu_paging_init(void) | |||
| 834 | 899 | ||
| 835 | srmmu_nocache_calcsize(); | 900 | srmmu_nocache_calcsize(); |
| 836 | srmmu_nocache_init(); | 901 | srmmu_nocache_init(); |
| 837 | srmmu_inherit_prom_mappings(0xfe400000,(LINUX_OPPROM_ENDVM-PAGE_SIZE)); | 902 | srmmu_inherit_prom_mappings(0xfe400000, (LINUX_OPPROM_ENDVM - PAGE_SIZE)); |
| 838 | map_kernel(); | 903 | map_kernel(); |
| 839 | 904 | ||
| 840 | /* ctx table has to be physically aligned to its size */ | 905 | /* ctx table has to be physically aligned to its size */ |
| 841 | srmmu_context_table = (ctxd_t *)__srmmu_get_nocache(num_contexts*sizeof(ctxd_t), num_contexts*sizeof(ctxd_t)); | 906 | srmmu_context_table = __srmmu_get_nocache(num_contexts * sizeof(ctxd_t), num_contexts * sizeof(ctxd_t)); |
| 842 | srmmu_ctx_table_phys = (ctxd_t *)__nocache_pa((unsigned long)srmmu_context_table); | 907 | srmmu_ctx_table_phys = (ctxd_t *)__nocache_pa((unsigned long)srmmu_context_table); |
| 843 | 908 | ||
| 844 | for(i = 0; i < num_contexts; i++) | 909 | for (i = 0; i < num_contexts; i++) |
| 845 | srmmu_ctxd_set((ctxd_t *)__nocache_fix(&srmmu_context_table[i]), srmmu_swapper_pg_dir); | 910 | srmmu_ctxd_set((ctxd_t *)__nocache_fix(&srmmu_context_table[i]), srmmu_swapper_pg_dir); |
| 846 | 911 | ||
| 847 | flush_cache_all(); | 912 | flush_cache_all(); |
| @@ -897,7 +962,7 @@ void __init srmmu_paging_init(void) | |||
| 897 | 962 | ||
| 898 | void mmu_info(struct seq_file *m) | 963 | void mmu_info(struct seq_file *m) |
| 899 | { | 964 | { |
| 900 | seq_printf(m, | 965 | seq_printf(m, |
| 901 | "MMU type\t: %s\n" | 966 | "MMU type\t: %s\n" |
| 902 | "contexts\t: %d\n" | 967 | "contexts\t: %d\n" |
| 903 | "nocache total\t: %ld\n" | 968 | "nocache total\t: %ld\n" |
| @@ -908,10 +973,16 @@ void mmu_info(struct seq_file *m) | |||
| 908 | srmmu_nocache_map.used << SRMMU_NOCACHE_BITMAP_SHIFT); | 973 | srmmu_nocache_map.used << SRMMU_NOCACHE_BITMAP_SHIFT); |
| 909 | } | 974 | } |
| 910 | 975 | ||
| 976 | int init_new_context(struct task_struct *tsk, struct mm_struct *mm) | ||
| 977 | { | ||
| 978 | mm->context = NO_CONTEXT; | ||
| 979 | return 0; | ||
| 980 | } | ||
| 981 | |||
| 911 | void destroy_context(struct mm_struct *mm) | 982 | void destroy_context(struct mm_struct *mm) |
| 912 | { | 983 | { |
| 913 | 984 | ||
| 914 | if(mm->context != NO_CONTEXT) { | 985 | if (mm->context != NO_CONTEXT) { |
| 915 | flush_cache_mm(mm); | 986 | flush_cache_mm(mm); |
| 916 | srmmu_ctxd_set(&srmmu_context_table[mm->context], srmmu_swapper_pg_dir); | 987 | srmmu_ctxd_set(&srmmu_context_table[mm->context], srmmu_swapper_pg_dir); |
| 917 | flush_tlb_mm(mm); | 988 | flush_tlb_mm(mm); |
| @@ -941,13 +1012,12 @@ static void __init init_vac_layout(void) | |||
| 941 | #endif | 1012 | #endif |
| 942 | 1013 | ||
| 943 | nd = prom_getchild(prom_root_node); | 1014 | nd = prom_getchild(prom_root_node); |
| 944 | while((nd = prom_getsibling(nd)) != 0) { | 1015 | while ((nd = prom_getsibling(nd)) != 0) { |
| 945 | prom_getstring(nd, "device_type", node_str, sizeof(node_str)); | 1016 | prom_getstring(nd, "device_type", node_str, sizeof(node_str)); |
| 946 | if(!strcmp(node_str, "cpu")) { | 1017 | if (!strcmp(node_str, "cpu")) { |
| 947 | vac_line_size = prom_getint(nd, "cache-line-size"); | 1018 | vac_line_size = prom_getint(nd, "cache-line-size"); |
| 948 | if (vac_line_size == -1) { | 1019 | if (vac_line_size == -1) { |
| 949 | prom_printf("can't determine cache-line-size, " | 1020 | prom_printf("can't determine cache-line-size, halting.\n"); |
| 950 | "halting.\n"); | ||
| 951 | prom_halt(); | 1021 | prom_halt(); |
| 952 | } | 1022 | } |
| 953 | cache_lines = prom_getint(nd, "cache-nlines"); | 1023 | cache_lines = prom_getint(nd, "cache-nlines"); |
| @@ -958,9 +1028,9 @@ static void __init init_vac_layout(void) | |||
| 958 | 1028 | ||
| 959 | vac_cache_size = cache_lines * vac_line_size; | 1029 | vac_cache_size = cache_lines * vac_line_size; |
| 960 | #ifdef CONFIG_SMP | 1030 | #ifdef CONFIG_SMP |
| 961 | if(vac_cache_size > max_size) | 1031 | if (vac_cache_size > max_size) |
| 962 | max_size = vac_cache_size; | 1032 | max_size = vac_cache_size; |
| 963 | if(vac_line_size < min_line_size) | 1033 | if (vac_line_size < min_line_size) |
| 964 | min_line_size = vac_line_size; | 1034 | min_line_size = vac_line_size; |
| 965 | //FIXME: cpus not contiguous!! | 1035 | //FIXME: cpus not contiguous!! |
| 966 | cpu++; | 1036 | cpu++; |
| @@ -971,7 +1041,7 @@ static void __init init_vac_layout(void) | |||
| 971 | #endif | 1041 | #endif |
| 972 | } | 1042 | } |
| 973 | } | 1043 | } |
| 974 | if(nd == 0) { | 1044 | if (nd == 0) { |
| 975 | prom_printf("No CPU nodes found, halting.\n"); | 1045 | prom_printf("No CPU nodes found, halting.\n"); |
| 976 | prom_halt(); | 1046 | prom_halt(); |
| 977 | } | 1047 | } |
| @@ -1082,7 +1152,7 @@ static void __init init_swift(void) | |||
| 1082 | "=r" (swift_rev) : | 1152 | "=r" (swift_rev) : |
| 1083 | "r" (SWIFT_MASKID_ADDR), "i" (ASI_M_BYPASS)); | 1153 | "r" (SWIFT_MASKID_ADDR), "i" (ASI_M_BYPASS)); |
| 1084 | srmmu_name = "Fujitsu Swift"; | 1154 | srmmu_name = "Fujitsu Swift"; |
| 1085 | switch(swift_rev) { | 1155 | switch (swift_rev) { |
| 1086 | case 0x11: | 1156 | case 0x11: |
| 1087 | case 0x20: | 1157 | case 0x20: |
| 1088 | case 0x23: | 1158 | case 0x23: |
| @@ -1222,10 +1292,11 @@ static void __cpuinit poke_turbosparc(void) | |||
| 1222 | 1292 | ||
| 1223 | /* Clear any crap from the cache or else... */ | 1293 | /* Clear any crap from the cache or else... */ |
| 1224 | turbosparc_flush_cache_all(); | 1294 | turbosparc_flush_cache_all(); |
| 1225 | mreg &= ~(TURBOSPARC_ICENABLE | TURBOSPARC_DCENABLE); /* Temporarily disable I & D caches */ | 1295 | /* Temporarily disable I & D caches */ |
| 1296 | mreg &= ~(TURBOSPARC_ICENABLE | TURBOSPARC_DCENABLE); | ||
| 1226 | mreg &= ~(TURBOSPARC_PCENABLE); /* Don't check parity */ | 1297 | mreg &= ~(TURBOSPARC_PCENABLE); /* Don't check parity */ |
| 1227 | srmmu_set_mmureg(mreg); | 1298 | srmmu_set_mmureg(mreg); |
| 1228 | 1299 | ||
| 1229 | ccreg = turbosparc_get_ccreg(); | 1300 | ccreg = turbosparc_get_ccreg(); |
| 1230 | 1301 | ||
| 1231 | #ifdef TURBOSPARC_WRITEBACK | 1302 | #ifdef TURBOSPARC_WRITEBACK |
| @@ -1248,7 +1319,7 @@ static void __cpuinit poke_turbosparc(void) | |||
| 1248 | default: | 1319 | default: |
| 1249 | ccreg |= (TURBOSPARC_SCENABLE); | 1320 | ccreg |= (TURBOSPARC_SCENABLE); |
| 1250 | } | 1321 | } |
| 1251 | turbosparc_set_ccreg (ccreg); | 1322 | turbosparc_set_ccreg(ccreg); |
| 1252 | 1323 | ||
| 1253 | mreg |= (TURBOSPARC_ICENABLE | TURBOSPARC_DCENABLE); /* I & D caches on */ | 1324 | mreg |= (TURBOSPARC_ICENABLE | TURBOSPARC_DCENABLE); /* I & D caches on */ |
| 1254 | mreg |= (TURBOSPARC_ICSNOOP); /* Icache snooping on */ | 1325 | mreg |= (TURBOSPARC_ICSNOOP); /* Icache snooping on */ |
| @@ -1342,7 +1413,7 @@ static void __cpuinit poke_viking(void) | |||
| 1342 | unsigned long bpreg; | 1413 | unsigned long bpreg; |
| 1343 | 1414 | ||
| 1344 | mreg &= ~(VIKING_TCENABLE); | 1415 | mreg &= ~(VIKING_TCENABLE); |
| 1345 | if(smp_catch++) { | 1416 | if (smp_catch++) { |
| 1346 | /* Must disable mixed-cmd mode here for other cpu's. */ | 1417 | /* Must disable mixed-cmd mode here for other cpu's. */ |
| 1347 | bpreg = viking_get_bpreg(); | 1418 | bpreg = viking_get_bpreg(); |
| 1348 | bpreg &= ~(VIKING_ACTION_MIX); | 1419 | bpreg &= ~(VIKING_ACTION_MIX); |
| @@ -1411,7 +1482,7 @@ static void __init init_viking(void) | |||
| 1411 | unsigned long mreg = srmmu_get_mmureg(); | 1482 | unsigned long mreg = srmmu_get_mmureg(); |
| 1412 | 1483 | ||
| 1413 | /* Ahhh, the viking. SRMMU VLSI abortion number two... */ | 1484 | /* Ahhh, the viking. SRMMU VLSI abortion number two... */ |
| 1414 | if(mreg & VIKING_MMODE) { | 1485 | if (mreg & VIKING_MMODE) { |
| 1415 | srmmu_name = "TI Viking"; | 1486 | srmmu_name = "TI Viking"; |
| 1416 | viking_mxcc_present = 0; | 1487 | viking_mxcc_present = 0; |
| 1417 | msi_set_sync(); | 1488 | msi_set_sync(); |
| @@ -1467,8 +1538,8 @@ static void __init get_srmmu_type(void) | |||
| 1467 | } | 1538 | } |
| 1468 | 1539 | ||
| 1469 | /* Second, check for HyperSparc or Cypress. */ | 1540 | /* Second, check for HyperSparc or Cypress. */ |
| 1470 | if(mod_typ == 1) { | 1541 | if (mod_typ == 1) { |
| 1471 | switch(mod_rev) { | 1542 | switch (mod_rev) { |
| 1472 | case 7: | 1543 | case 7: |
| 1473 | /* UP or MP Hypersparc */ | 1544 | /* UP or MP Hypersparc */ |
| 1474 | init_hypersparc(); | 1545 | init_hypersparc(); |
| @@ -1488,9 +1559,8 @@ static void __init get_srmmu_type(void) | |||
| 1488 | } | 1559 | } |
| 1489 | return; | 1560 | return; |
| 1490 | } | 1561 | } |
| 1491 | 1562 | ||
| 1492 | /* | 1563 | /* Now Fujitsu TurboSparc. It might happen that it is |
| 1493 | * Now Fujitsu TurboSparc. It might happen that it is | ||
| 1494 | * in Swift emulation mode, so we will check later... | 1564 | * in Swift emulation mode, so we will check later... |
| 1495 | */ | 1565 | */ |
| 1496 | if (psr_typ == 0 && psr_vers == 5) { | 1566 | if (psr_typ == 0 && psr_vers == 5) { |
| @@ -1499,15 +1569,15 @@ static void __init get_srmmu_type(void) | |||
| 1499 | } | 1569 | } |
| 1500 | 1570 | ||
| 1501 | /* Next check for Fujitsu Swift. */ | 1571 | /* Next check for Fujitsu Swift. */ |
| 1502 | if(psr_typ == 0 && psr_vers == 4) { | 1572 | if (psr_typ == 0 && psr_vers == 4) { |
| 1503 | phandle cpunode; | 1573 | phandle cpunode; |
| 1504 | char node_str[128]; | 1574 | char node_str[128]; |
| 1505 | 1575 | ||
| 1506 | /* Look if it is not a TurboSparc emulating Swift... */ | 1576 | /* Look if it is not a TurboSparc emulating Swift... */ |
| 1507 | cpunode = prom_getchild(prom_root_node); | 1577 | cpunode = prom_getchild(prom_root_node); |
| 1508 | while((cpunode = prom_getsibling(cpunode)) != 0) { | 1578 | while ((cpunode = prom_getsibling(cpunode)) != 0) { |
| 1509 | prom_getstring(cpunode, "device_type", node_str, sizeof(node_str)); | 1579 | prom_getstring(cpunode, "device_type", node_str, sizeof(node_str)); |
| 1510 | if(!strcmp(node_str, "cpu")) { | 1580 | if (!strcmp(node_str, "cpu")) { |
| 1511 | if (!prom_getintdefault(cpunode, "psr-implementation", 1) && | 1581 | if (!prom_getintdefault(cpunode, "psr-implementation", 1) && |
| 1512 | prom_getintdefault(cpunode, "psr-version", 1) == 5) { | 1582 | prom_getintdefault(cpunode, "psr-version", 1) == 5) { |
| 1513 | init_turbosparc(); | 1583 | init_turbosparc(); |
| @@ -1516,13 +1586,13 @@ static void __init get_srmmu_type(void) | |||
| 1516 | break; | 1586 | break; |
| 1517 | } | 1587 | } |
| 1518 | } | 1588 | } |
| 1519 | 1589 | ||
| 1520 | init_swift(); | 1590 | init_swift(); |
| 1521 | return; | 1591 | return; |
| 1522 | } | 1592 | } |
| 1523 | 1593 | ||
| 1524 | /* Now the Viking family of srmmu. */ | 1594 | /* Now the Viking family of srmmu. */ |
| 1525 | if(psr_typ == 4 && | 1595 | if (psr_typ == 4 && |
| 1526 | ((psr_vers == 0) || | 1596 | ((psr_vers == 0) || |
| 1527 | ((psr_vers == 1) && (mod_typ == 0) && (mod_rev == 0)))) { | 1597 | ((psr_vers == 1) && (mod_typ == 0) && (mod_rev == 0)))) { |
| 1528 | init_viking(); | 1598 | init_viking(); |
| @@ -1530,7 +1600,7 @@ static void __init get_srmmu_type(void) | |||
| 1530 | } | 1600 | } |
| 1531 | 1601 | ||
| 1532 | /* Finally the Tsunami. */ | 1602 | /* Finally the Tsunami. */ |
| 1533 | if(psr_typ == 4 && psr_vers == 1 && (mod_typ || mod_rev)) { | 1603 | if (psr_typ == 4 && psr_vers == 1 && (mod_typ || mod_rev)) { |
| 1534 | init_tsunami(); | 1604 | init_tsunami(); |
| 1535 | return; | 1605 | return; |
| 1536 | } | 1606 | } |
diff --git a/arch/sparc/prom/init_32.c b/arch/sparc/prom/init_32.c index 26c64cea3c9c..9ac30c2b7dba 100644 --- a/arch/sparc/prom/init_32.c +++ b/arch/sparc/prom/init_32.c | |||
| @@ -27,13 +27,10 @@ EXPORT_SYMBOL(prom_root_node); | |||
| 27 | struct linux_nodeops *prom_nodeops; | 27 | struct linux_nodeops *prom_nodeops; |
| 28 | 28 | ||
| 29 | /* You must call prom_init() before you attempt to use any of the | 29 | /* You must call prom_init() before you attempt to use any of the |
| 30 | * routines in the prom library. It returns 0 on success, 1 on | 30 | * routines in the prom library. |
| 31 | * failure. It gets passed the pointer to the PROM vector. | 31 | * It gets passed the pointer to the PROM vector. |
| 32 | */ | 32 | */ |
| 33 | 33 | ||
| 34 | extern void prom_meminit(void); | ||
| 35 | extern void prom_ranges_init(void); | ||
| 36 | |||
| 37 | void __init prom_init(struct linux_romvec *rp) | 34 | void __init prom_init(struct linux_romvec *rp) |
| 38 | { | 35 | { |
| 39 | romvec = rp; | 36 | romvec = rp; |
diff --git a/arch/sparc/prom/init_64.c b/arch/sparc/prom/init_64.c index 5016c5e20575..d95db755828f 100644 --- a/arch/sparc/prom/init_64.c +++ b/arch/sparc/prom/init_64.c | |||
| @@ -22,8 +22,8 @@ int prom_stdout; | |||
| 22 | phandle prom_chosen_node; | 22 | phandle prom_chosen_node; |
| 23 | 23 | ||
| 24 | /* You must call prom_init() before you attempt to use any of the | 24 | /* You must call prom_init() before you attempt to use any of the |
| 25 | * routines in the prom library. It returns 0 on success, 1 on | 25 | * routines in the prom library. |
| 26 | * failure. It gets passed the pointer to the PROM vector. | 26 | * It gets passed the pointer to the PROM vector. |
| 27 | */ | 27 | */ |
| 28 | 28 | ||
| 29 | extern void prom_cif_init(void *, void *); | 29 | extern void prom_cif_init(void *, void *); |
diff --git a/arch/tile/configs/tilegx_defconfig b/arch/tile/configs/tilegx_defconfig index b8d99aca5431..0270620a1692 100644 --- a/arch/tile/configs/tilegx_defconfig +++ b/arch/tile/configs/tilegx_defconfig | |||
| @@ -18,8 +18,8 @@ CONFIG_CGROUP_DEVICE=y | |||
| 18 | CONFIG_CPUSETS=y | 18 | CONFIG_CPUSETS=y |
| 19 | CONFIG_CGROUP_CPUACCT=y | 19 | CONFIG_CGROUP_CPUACCT=y |
| 20 | CONFIG_RESOURCE_COUNTERS=y | 20 | CONFIG_RESOURCE_COUNTERS=y |
| 21 | CONFIG_CGROUP_MEM_RES_CTLR=y | 21 | CONFIG_CGROUP_MEMCG=y |
| 22 | CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y | 22 | CONFIG_CGROUP_MEMCG_SWAP=y |
| 23 | CONFIG_CGROUP_SCHED=y | 23 | CONFIG_CGROUP_SCHED=y |
| 24 | CONFIG_RT_GROUP_SCHED=y | 24 | CONFIG_RT_GROUP_SCHED=y |
| 25 | CONFIG_BLK_CGROUP=y | 25 | CONFIG_BLK_CGROUP=y |
diff --git a/arch/tile/configs/tilepro_defconfig b/arch/tile/configs/tilepro_defconfig index 2b1fd31894f1..c11de27a9bcb 100644 --- a/arch/tile/configs/tilepro_defconfig +++ b/arch/tile/configs/tilepro_defconfig | |||
| @@ -17,8 +17,8 @@ CONFIG_CGROUP_DEVICE=y | |||
| 17 | CONFIG_CPUSETS=y | 17 | CONFIG_CPUSETS=y |
| 18 | CONFIG_CGROUP_CPUACCT=y | 18 | CONFIG_CGROUP_CPUACCT=y |
| 19 | CONFIG_RESOURCE_COUNTERS=y | 19 | CONFIG_RESOURCE_COUNTERS=y |
| 20 | CONFIG_CGROUP_MEM_RES_CTLR=y | 20 | CONFIG_CGROUP_MEMCG=y |
| 21 | CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y | 21 | CONFIG_CGROUP_MEMCG_SWAP=y |
| 22 | CONFIG_CGROUP_SCHED=y | 22 | CONFIG_CGROUP_SCHED=y |
| 23 | CONFIG_RT_GROUP_SCHED=y | 23 | CONFIG_RT_GROUP_SCHED=y |
| 24 | CONFIG_BLK_CGROUP=y | 24 | CONFIG_BLK_CGROUP=y |
diff --git a/arch/tile/include/asm/Kbuild b/arch/tile/include/asm/Kbuild index fb7c65ae8de0..5bd71994452d 100644 --- a/arch/tile/include/asm/Kbuild +++ b/arch/tile/include/asm/Kbuild | |||
| @@ -16,7 +16,6 @@ generic-y += fb.h | |||
| 16 | generic-y += fcntl.h | 16 | generic-y += fcntl.h |
| 17 | generic-y += ioctl.h | 17 | generic-y += ioctl.h |
| 18 | generic-y += ioctls.h | 18 | generic-y += ioctls.h |
| 19 | generic-y += ipc.h | ||
| 20 | generic-y += ipcbuf.h | 19 | generic-y += ipcbuf.h |
| 21 | generic-y += irq_regs.h | 20 | generic-y += irq_regs.h |
| 22 | generic-y += kdebug.h | 21 | generic-y += kdebug.h |
diff --git a/arch/tile/include/asm/kmap_types.h b/arch/tile/include/asm/kmap_types.h index 3d0f20246260..92b28e3e9972 100644 --- a/arch/tile/include/asm/kmap_types.h +++ b/arch/tile/include/asm/kmap_types.h | |||
| @@ -23,35 +23,6 @@ | |||
| 23 | * adds 4MB of required address-space. For now we leave KM_TYPE_NR | 23 | * adds 4MB of required address-space. For now we leave KM_TYPE_NR |
| 24 | * set to depth 8. | 24 | * set to depth 8. |
| 25 | */ | 25 | */ |
| 26 | enum km_type { | 26 | #define KM_TYPE_NR 8 |
| 27 | KM_TYPE_NR = 8 | ||
| 28 | }; | ||
| 29 | |||
| 30 | /* | ||
| 31 | * We provide dummy definitions of all the stray values that used to be | ||
| 32 | * required for kmap_atomic() and no longer are. | ||
| 33 | */ | ||
| 34 | enum { | ||
| 35 | KM_BOUNCE_READ, | ||
| 36 | KM_SKB_SUNRPC_DATA, | ||
| 37 | KM_SKB_DATA_SOFTIRQ, | ||
| 38 | KM_USER0, | ||
| 39 | KM_USER1, | ||
| 40 | KM_BIO_SRC_IRQ, | ||
| 41 | KM_BIO_DST_IRQ, | ||
| 42 | KM_PTE0, | ||
| 43 | KM_PTE1, | ||
| 44 | KM_IRQ0, | ||
| 45 | KM_IRQ1, | ||
| 46 | KM_SOFTIRQ0, | ||
| 47 | KM_SOFTIRQ1, | ||
| 48 | KM_SYNC_ICACHE, | ||
| 49 | KM_SYNC_DCACHE, | ||
| 50 | KM_UML_USERCOPY, | ||
| 51 | KM_IRQ_PTE, | ||
| 52 | KM_NMI, | ||
| 53 | KM_NMI_PTE, | ||
| 54 | KM_KDB | ||
| 55 | }; | ||
| 56 | 27 | ||
| 57 | #endif /* _ASM_TILE_KMAP_TYPES_H */ | 28 | #endif /* _ASM_TILE_KMAP_TYPES_H */ |
diff --git a/arch/tile/kernel/pci.c b/arch/tile/kernel/pci.c index 0fdd99d0d8b7..33c10864d2f7 100644 --- a/arch/tile/kernel/pci.c +++ b/arch/tile/kernel/pci.c | |||
| @@ -369,7 +369,7 @@ int __init pcibios_init(void) | |||
| 369 | */ | 369 | */ |
| 370 | if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI && | 370 | if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI && |
| 371 | (PCI_SLOT(dev->devfn) == 0)) { | 371 | (PCI_SLOT(dev->devfn) == 0)) { |
| 372 | next_bus = dev->busn_res.end; | 372 | next_bus = dev->subordinate; |
| 373 | controllers[i].mem_resources[0] = | 373 | controllers[i].mem_resources[0] = |
| 374 | *next_bus->resource[0]; | 374 | *next_bus->resource[0]; |
| 375 | controllers[i].mem_resources[1] = | 375 | controllers[i].mem_resources[1] = |
diff --git a/arch/tile/kernel/pci_gx.c b/arch/tile/kernel/pci_gx.c index fa75264a82ae..0e213e35ffc3 100644 --- a/arch/tile/kernel/pci_gx.c +++ b/arch/tile/kernel/pci_gx.c | |||
| @@ -853,7 +853,7 @@ int __init pcibios_init(void) | |||
| 853 | bus = pci_scan_root_bus(NULL, next_busno, controller->ops, | 853 | bus = pci_scan_root_bus(NULL, next_busno, controller->ops, |
| 854 | controller, &resources); | 854 | controller, &resources); |
| 855 | controller->root_bus = bus; | 855 | controller->root_bus = bus; |
| 856 | next_busno = bus->subordinate + 1; | 856 | next_busno = bus->busn_res.end + 1; |
| 857 | 857 | ||
| 858 | } | 858 | } |
| 859 | 859 | ||
diff --git a/arch/tile/mm/highmem.c b/arch/tile/mm/highmem.c index ef8e5a62b6e3..347d123b14be 100644 --- a/arch/tile/mm/highmem.c +++ b/arch/tile/mm/highmem.c | |||
| @@ -93,7 +93,7 @@ static DEFINE_PER_CPU(struct kmap_amps, amps); | |||
| 93 | * If we examine it earlier we are exposed to a race where it looks | 93 | * If we examine it earlier we are exposed to a race where it looks |
| 94 | * writable earlier, but becomes immutable before we write the PTE. | 94 | * writable earlier, but becomes immutable before we write the PTE. |
| 95 | */ | 95 | */ |
| 96 | static void kmap_atomic_register(struct page *page, enum km_type type, | 96 | static void kmap_atomic_register(struct page *page, int type, |
| 97 | unsigned long va, pte_t *ptep, pte_t pteval) | 97 | unsigned long va, pte_t *ptep, pte_t pteval) |
| 98 | { | 98 | { |
| 99 | unsigned long flags; | 99 | unsigned long flags; |
diff --git a/arch/um/defconfig b/arch/um/defconfig index 7823ab12e6a4..fec0d5d27460 100644 --- a/arch/um/defconfig +++ b/arch/um/defconfig | |||
| @@ -155,10 +155,10 @@ CONFIG_CPUSETS=y | |||
| 155 | CONFIG_PROC_PID_CPUSET=y | 155 | CONFIG_PROC_PID_CPUSET=y |
| 156 | CONFIG_CGROUP_CPUACCT=y | 156 | CONFIG_CGROUP_CPUACCT=y |
| 157 | CONFIG_RESOURCE_COUNTERS=y | 157 | CONFIG_RESOURCE_COUNTERS=y |
| 158 | CONFIG_CGROUP_MEM_RES_CTLR=y | 158 | CONFIG_CGROUP_MEMCG=y |
| 159 | CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y | 159 | CONFIG_CGROUP_MEMCG_SWAP=y |
| 160 | # CONFIG_CGROUP_MEM_RES_CTLR_SWAP_ENABLED is not set | 160 | # CONFIG_CGROUP_MEMCG_SWAP_ENABLED is not set |
| 161 | # CONFIG_CGROUP_MEM_RES_CTLR_KMEM is not set | 161 | # CONFIG_CGROUP_MEMCG_KMEM is not set |
| 162 | CONFIG_CGROUP_SCHED=y | 162 | CONFIG_CGROUP_SCHED=y |
| 163 | CONFIG_FAIR_GROUP_SCHED=y | 163 | CONFIG_FAIR_GROUP_SCHED=y |
| 164 | # CONFIG_CFS_BANDWIDTH is not set | 164 | # CONFIG_CFS_BANDWIDTH is not set |
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index acfd0e0fd0c9..ac9d25c8dc01 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c | |||
| @@ -362,18 +362,18 @@ static irqreturn_t line_write_interrupt(int irq, void *data) | |||
| 362 | int line_setup_irq(int fd, int input, int output, struct line *line, void *data) | 362 | int line_setup_irq(int fd, int input, int output, struct line *line, void *data) |
| 363 | { | 363 | { |
| 364 | const struct line_driver *driver = line->driver; | 364 | const struct line_driver *driver = line->driver; |
| 365 | int err = 0, flags = IRQF_SHARED | IRQF_SAMPLE_RANDOM; | 365 | int err = 0; |
| 366 | 366 | ||
| 367 | if (input) | 367 | if (input) |
| 368 | err = um_request_irq(driver->read_irq, fd, IRQ_READ, | 368 | err = um_request_irq(driver->read_irq, fd, IRQ_READ, |
| 369 | line_interrupt, flags, | 369 | line_interrupt, IRQF_SHARED, |
| 370 | driver->read_irq_name, data); | 370 | driver->read_irq_name, data); |
| 371 | if (err) | 371 | if (err) |
| 372 | return err; | 372 | return err; |
| 373 | if (output) | 373 | if (output) |
| 374 | err = um_request_irq(driver->write_irq, fd, IRQ_WRITE, | 374 | err = um_request_irq(driver->write_irq, fd, IRQ_WRITE, |
| 375 | line_write_interrupt, flags, | 375 | line_write_interrupt, IRQF_SHARED, |
| 376 | driver->write_irq_name, data); | 376 | driver->write_irq_name, data); |
| 377 | return err; | 377 | return err; |
| 378 | } | 378 | } |
| 379 | 379 | ||
| @@ -779,8 +779,7 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty, | |||
| 779 | .stack = stack }); | 779 | .stack = stack }); |
| 780 | 780 | ||
| 781 | if (um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt, | 781 | if (um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt, |
| 782 | IRQF_SHARED | IRQF_SAMPLE_RANDOM, | 782 | IRQF_SHARED, "winch", winch) < 0) { |
| 783 | "winch", winch) < 0) { | ||
| 784 | printk(KERN_ERR "register_winch_irq - failed to register " | 783 | printk(KERN_ERR "register_winch_irq - failed to register " |
| 785 | "IRQ\n"); | 784 | "IRQ\n"); |
| 786 | goto out_free; | 785 | goto out_free; |
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index 43b39d61b538..664a60e8dfb4 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c | |||
| @@ -774,8 +774,7 @@ static int __init mconsole_init(void) | |||
| 774 | register_reboot_notifier(&reboot_notifier); | 774 | register_reboot_notifier(&reboot_notifier); |
| 775 | 775 | ||
| 776 | err = um_request_irq(MCONSOLE_IRQ, sock, IRQ_READ, mconsole_interrupt, | 776 | err = um_request_irq(MCONSOLE_IRQ, sock, IRQ_READ, mconsole_interrupt, |
| 777 | IRQF_SHARED | IRQF_SAMPLE_RANDOM, | 777 | IRQF_SHARED, "mconsole", (void *)sock); |
| 778 | "mconsole", (void *)sock); | ||
| 779 | if (err) { | 778 | if (err) { |
| 780 | printk(KERN_ERR "Failed to get IRQ for management console\n"); | 779 | printk(KERN_ERR "Failed to get IRQ for management console\n"); |
| 781 | goto out; | 780 | goto out; |
diff --git a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c index 11866ffd45a9..1d83d50236e1 100644 --- a/arch/um/drivers/port_kern.c +++ b/arch/um/drivers/port_kern.c | |||
| @@ -100,8 +100,7 @@ static int port_accept(struct port_list *port) | |||
| 100 | .port = port }); | 100 | .port = port }); |
| 101 | 101 | ||
| 102 | if (um_request_irq(TELNETD_IRQ, socket[0], IRQ_READ, pipe_interrupt, | 102 | if (um_request_irq(TELNETD_IRQ, socket[0], IRQ_READ, pipe_interrupt, |
| 103 | IRQF_SHARED | IRQF_SAMPLE_RANDOM, | 103 | IRQF_SHARED, "telnetd", conn)) { |
| 104 | "telnetd", conn)) { | ||
| 105 | printk(KERN_ERR "port_accept : failed to get IRQ for " | 104 | printk(KERN_ERR "port_accept : failed to get IRQ for " |
| 106 | "telnetd\n"); | 105 | "telnetd\n"); |
| 107 | goto out_free; | 106 | goto out_free; |
| @@ -184,8 +183,7 @@ void *port_data(int port_num) | |||
| 184 | } | 183 | } |
| 185 | 184 | ||
| 186 | if (um_request_irq(ACCEPT_IRQ, fd, IRQ_READ, port_interrupt, | 185 | if (um_request_irq(ACCEPT_IRQ, fd, IRQ_READ, port_interrupt, |
| 187 | IRQF_SHARED | IRQF_SAMPLE_RANDOM, | 186 | IRQF_SHARED, "port", port)) { |
| 188 | "port", port)) { | ||
| 189 | printk(KERN_ERR "Failed to get IRQ for port %d\n", port_num); | 187 | printk(KERN_ERR "Failed to get IRQ for port %d\n", port_num); |
| 190 | goto out_close; | 188 | goto out_close; |
| 191 | } | 189 | } |
diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c index b25296e6218a..e32c6aa6396f 100644 --- a/arch/um/drivers/random.c +++ b/arch/um/drivers/random.c | |||
| @@ -131,8 +131,7 @@ static int __init rng_init (void) | |||
| 131 | random_fd = err; | 131 | random_fd = err; |
| 132 | 132 | ||
| 133 | err = um_request_irq(RANDOM_IRQ, random_fd, IRQ_READ, random_interrupt, | 133 | err = um_request_irq(RANDOM_IRQ, random_fd, IRQ_READ, random_interrupt, |
| 134 | IRQF_SAMPLE_RANDOM, "random", | 134 | 0, "random", NULL); |
| 135 | NULL); | ||
| 136 | if (err) | 135 | if (err) |
| 137 | goto err_out_cleanup_hw; | 136 | goto err_out_cleanup_hw; |
| 138 | 137 | ||
diff --git a/arch/um/drivers/xterm_kern.c b/arch/um/drivers/xterm_kern.c index b68bbe269e01..e3031e69445d 100644 --- a/arch/um/drivers/xterm_kern.c +++ b/arch/um/drivers/xterm_kern.c | |||
| @@ -50,8 +50,7 @@ int xterm_fd(int socket, int *pid_out) | |||
| 50 | init_completion(&data->ready); | 50 | init_completion(&data->ready); |
| 51 | 51 | ||
| 52 | err = um_request_irq(XTERM_IRQ, socket, IRQ_READ, xterm_interrupt, | 52 | err = um_request_irq(XTERM_IRQ, socket, IRQ_READ, xterm_interrupt, |
| 53 | IRQF_SHARED | IRQF_SAMPLE_RANDOM, | 53 | IRQF_SHARED, "xterm", data); |
| 54 | "xterm", data); | ||
| 55 | if (err) { | 54 | if (err) { |
| 56 | printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, " | 55 | printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, " |
| 57 | "err = %d\n", err); | 56 | "err = %d\n", err); |
diff --git a/arch/um/include/asm/kmap_types.h b/arch/um/include/asm/kmap_types.h index 6c03acdb4405..2e0a6b1d8300 100644 --- a/arch/um/include/asm/kmap_types.h +++ b/arch/um/include/asm/kmap_types.h | |||
| @@ -8,22 +8,6 @@ | |||
| 8 | 8 | ||
| 9 | /* No more #include "asm/arch/kmap_types.h" ! */ | 9 | /* No more #include "asm/arch/kmap_types.h" ! */ |
| 10 | 10 | ||
| 11 | enum km_type { | 11 | #define KM_TYPE_NR 14 |
| 12 | KM_BOUNCE_READ, | ||
| 13 | KM_SKB_SUNRPC_DATA, | ||
| 14 | KM_SKB_DATA_SOFTIRQ, | ||
| 15 | KM_USER0, | ||
| 16 | KM_USER1, | ||
| 17 | KM_UML_USERCOPY, /* UML specific, for copy_*_user - used in do_op_one_page */ | ||
| 18 | KM_BIO_SRC_IRQ, | ||
| 19 | KM_BIO_DST_IRQ, | ||
| 20 | KM_PTE0, | ||
| 21 | KM_PTE1, | ||
| 22 | KM_IRQ0, | ||
| 23 | KM_IRQ1, | ||
| 24 | KM_SOFTIRQ0, | ||
| 25 | KM_SOFTIRQ1, | ||
| 26 | KM_TYPE_NR | ||
| 27 | }; | ||
| 28 | 12 | ||
| 29 | #endif | 13 | #endif |
diff --git a/arch/um/kernel/sigio.c b/arch/um/kernel/sigio.c index 2a1639255763..c88211139a51 100644 --- a/arch/um/kernel/sigio.c +++ b/arch/um/kernel/sigio.c | |||
| @@ -25,8 +25,7 @@ int write_sigio_irq(int fd) | |||
| 25 | int err; | 25 | int err; |
| 26 | 26 | ||
| 27 | err = um_request_irq(SIGIO_WRITE_IRQ, fd, IRQ_READ, sigio_interrupt, | 27 | err = um_request_irq(SIGIO_WRITE_IRQ, fd, IRQ_READ, sigio_interrupt, |
| 28 | IRQF_SAMPLE_RANDOM, "write sigio", | 28 | 0, "write sigio", NULL); |
| 29 | NULL); | ||
| 30 | if (err) { | 29 | if (err) { |
| 31 | printk(KERN_ERR "write_sigio_irq : um_request_irq failed, " | 30 | printk(KERN_ERR "write_sigio_irq : um_request_irq failed, " |
| 32 | "err = %d\n", err); | 31 | "err = %d\n", err); |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index c70684f859e1..ba2657c49217 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
| @@ -70,6 +70,7 @@ config X86 | |||
| 70 | select HAVE_ARCH_JUMP_LABEL | 70 | select HAVE_ARCH_JUMP_LABEL |
| 71 | select HAVE_TEXT_POKE_SMP | 71 | select HAVE_TEXT_POKE_SMP |
| 72 | select HAVE_GENERIC_HARDIRQS | 72 | select HAVE_GENERIC_HARDIRQS |
| 73 | select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE | ||
| 73 | select SPARSE_IRQ | 74 | select SPARSE_IRQ |
| 74 | select GENERIC_FIND_FIRST_BIT | 75 | select GENERIC_FIND_FIRST_BIT |
| 75 | select GENERIC_IRQ_PROBE | 76 | select GENERIC_IRQ_PROBE |
| @@ -84,6 +85,7 @@ config X86 | |||
| 84 | select GENERIC_IOMAP | 85 | select GENERIC_IOMAP |
| 85 | select DCACHE_WORD_ACCESS | 86 | select DCACHE_WORD_ACCESS |
| 86 | select GENERIC_SMP_IDLE_THREAD | 87 | select GENERIC_SMP_IDLE_THREAD |
| 88 | select ARCH_WANT_IPC_PARSE_VERSION if X86_32 | ||
| 87 | select HAVE_ARCH_SECCOMP_FILTER | 89 | select HAVE_ARCH_SECCOMP_FILTER |
| 88 | select BUILDTIME_EXTABLE_SORT | 90 | select BUILDTIME_EXTABLE_SORT |
| 89 | select GENERIC_CMOS_UPDATE | 91 | select GENERIC_CMOS_UPDATE |
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index e46c2147397f..b322f124ee3c 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug | |||
| @@ -129,6 +129,25 @@ config DOUBLEFAULT | |||
| 129 | option saves about 4k and might cause you much additional grey | 129 | option saves about 4k and might cause you much additional grey |
| 130 | hair. | 130 | hair. |
| 131 | 131 | ||
| 132 | config DEBUG_TLBFLUSH | ||
| 133 | bool "Set upper limit of TLB entries to flush one-by-one" | ||
| 134 | depends on DEBUG_KERNEL && (X86_64 || X86_INVLPG) | ||
| 135 | ---help--- | ||
| 136 | |||
| 137 | X86-only for now. | ||
| 138 | |||
| 139 | This option allows the user to tune the amount of TLB entries the | ||
| 140 | kernel flushes one-by-one instead of doing a full TLB flush. In | ||
| 141 | certain situations, the former is cheaper. This is controlled by the | ||
| 142 | tlb_flushall_shift knob under /sys/kernel/debug/x86. If you set it | ||
| 143 | to -1, the code flushes the whole TLB unconditionally. Otherwise, | ||
| 144 | for positive values of it, the kernel will use single TLB entry | ||
| 145 | invalidating instructions according to the following formula: | ||
| 146 | |||
| 147 | flush_entries <= active_tlb_entries / 2^tlb_flushall_shift | ||
| 148 | |||
| 149 | If in doubt, say "N". | ||
| 150 | |||
| 132 | config IOMMU_DEBUG | 151 | config IOMMU_DEBUG |
| 133 | bool "Enable IOMMU debugging" | 152 | bool "Enable IOMMU debugging" |
| 134 | depends on GART_IOMMU && DEBUG_KERNEL | 153 | depends on GART_IOMMU && DEBUG_KERNEL |
diff --git a/arch/x86/boot/compressed/cmdline.c b/arch/x86/boot/compressed/cmdline.c index cb62f786990d..10f6b1178c68 100644 --- a/arch/x86/boot/compressed/cmdline.c +++ b/arch/x86/boot/compressed/cmdline.c | |||
| @@ -1,5 +1,7 @@ | |||
| 1 | #include "misc.h" | 1 | #include "misc.h" |
| 2 | 2 | ||
| 3 | #ifdef CONFIG_EARLY_PRINTK | ||
| 4 | |||
| 3 | static unsigned long fs; | 5 | static unsigned long fs; |
| 4 | static inline void set_fs(unsigned long seg) | 6 | static inline void set_fs(unsigned long seg) |
| 5 | { | 7 | { |
| @@ -19,3 +21,5 @@ int cmdline_find_option_bool(const char *option) | |||
| 19 | { | 21 | { |
| 20 | return __cmdline_find_option_bool(real_mode->hdr.cmd_line_ptr, option); | 22 | return __cmdline_find_option_bool(real_mode->hdr.cmd_line_ptr, option); |
| 21 | } | 23 | } |
| 24 | |||
| 25 | #endif | ||
diff --git a/arch/x86/boot/compressed/early_serial_console.c b/arch/x86/boot/compressed/early_serial_console.c index 261e81fb9582..d3d003cb5481 100644 --- a/arch/x86/boot/compressed/early_serial_console.c +++ b/arch/x86/boot/compressed/early_serial_console.c | |||
| @@ -1,5 +1,9 @@ | |||
| 1 | #include "misc.h" | 1 | #include "misc.h" |
| 2 | 2 | ||
| 3 | #ifdef CONFIG_EARLY_PRINTK | ||
| 4 | |||
| 3 | int early_serial_base; | 5 | int early_serial_base; |
| 4 | 6 | ||
| 5 | #include "../early_serial_console.c" | 7 | #include "../early_serial_console.c" |
| 8 | |||
| 9 | #endif | ||
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index 4e85f5f85837..b3e0227df2c9 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c | |||
| @@ -729,32 +729,68 @@ fail: | |||
| 729 | * need to create one ourselves (usually the bootloader would create | 729 | * need to create one ourselves (usually the bootloader would create |
| 730 | * one for us). | 730 | * one for us). |
| 731 | */ | 731 | */ |
| 732 | static efi_status_t make_boot_params(struct boot_params *boot_params, | 732 | struct boot_params *make_boot_params(void *handle, efi_system_table_t *_table) |
| 733 | efi_loaded_image_t *image, | ||
| 734 | void *handle) | ||
| 735 | { | 733 | { |
| 736 | struct efi_info *efi = &boot_params->efi_info; | 734 | struct boot_params *boot_params; |
| 737 | struct apm_bios_info *bi = &boot_params->apm_bios_info; | 735 | struct sys_desc_table *sdt; |
| 738 | struct sys_desc_table *sdt = &boot_params->sys_desc_table; | 736 | struct apm_bios_info *bi; |
| 739 | struct e820entry *e820_map = &boot_params->e820_map[0]; | 737 | struct setup_header *hdr; |
| 740 | struct e820entry *prev = NULL; | 738 | struct efi_info *efi; |
| 741 | struct setup_header *hdr = &boot_params->hdr; | 739 | efi_loaded_image_t *image; |
| 742 | unsigned long size, key, desc_size, _size; | 740 | void *options; |
| 743 | efi_memory_desc_t *mem_map; | 741 | u32 load_options_size; |
| 744 | void *options = image->load_options; | 742 | efi_guid_t proto = LOADED_IMAGE_PROTOCOL_GUID; |
| 745 | u32 load_options_size = image->load_options_size / 2; /* ASCII */ | ||
| 746 | int options_size = 0; | 743 | int options_size = 0; |
| 747 | efi_status_t status; | 744 | efi_status_t status; |
| 748 | __u32 desc_version; | ||
| 749 | unsigned long cmdline; | 745 | unsigned long cmdline; |
| 750 | u8 nr_entries; | ||
| 751 | u16 *s2; | 746 | u16 *s2; |
| 752 | u8 *s1; | 747 | u8 *s1; |
| 753 | int i; | 748 | int i; |
| 754 | 749 | ||
| 750 | sys_table = _table; | ||
| 751 | |||
| 752 | /* Check if we were booted by the EFI firmware */ | ||
| 753 | if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) | ||
| 754 | return NULL; | ||
| 755 | |||
| 756 | status = efi_call_phys3(sys_table->boottime->handle_protocol, | ||
| 757 | handle, &proto, (void *)&image); | ||
| 758 | if (status != EFI_SUCCESS) { | ||
| 759 | efi_printk("Failed to get handle for LOADED_IMAGE_PROTOCOL\n"); | ||
| 760 | return NULL; | ||
| 761 | } | ||
| 762 | |||
| 763 | status = low_alloc(0x4000, 1, (unsigned long *)&boot_params); | ||
| 764 | if (status != EFI_SUCCESS) { | ||
| 765 | efi_printk("Failed to alloc lowmem for boot params\n"); | ||
| 766 | return NULL; | ||
| 767 | } | ||
| 768 | |||
| 769 | memset(boot_params, 0x0, 0x4000); | ||
| 770 | |||
| 771 | hdr = &boot_params->hdr; | ||
| 772 | efi = &boot_params->efi_info; | ||
| 773 | bi = &boot_params->apm_bios_info; | ||
| 774 | sdt = &boot_params->sys_desc_table; | ||
| 775 | |||
| 776 | /* Copy the second sector to boot_params */ | ||
| 777 | memcpy(&hdr->jump, image->image_base + 512, 512); | ||
| 778 | |||
| 779 | /* | ||
| 780 | * Fill out some of the header fields ourselves because the | ||
| 781 | * EFI firmware loader doesn't load the first sector. | ||
| 782 | */ | ||
| 783 | hdr->root_flags = 1; | ||
| 784 | hdr->vid_mode = 0xffff; | ||
| 785 | hdr->boot_flag = 0xAA55; | ||
| 786 | |||
| 787 | hdr->code32_start = (__u64)(unsigned long)image->image_base; | ||
| 788 | |||
| 755 | hdr->type_of_loader = 0x21; | 789 | hdr->type_of_loader = 0x21; |
| 756 | 790 | ||
| 757 | /* Convert unicode cmdline to ascii */ | 791 | /* Convert unicode cmdline to ascii */ |
| 792 | options = image->load_options; | ||
| 793 | load_options_size = image->load_options_size / 2; /* ASCII */ | ||
| 758 | cmdline = 0; | 794 | cmdline = 0; |
| 759 | s2 = (u16 *)options; | 795 | s2 = (u16 *)options; |
| 760 | 796 | ||
| @@ -791,18 +827,36 @@ static efi_status_t make_boot_params(struct boot_params *boot_params, | |||
| 791 | hdr->ramdisk_image = 0; | 827 | hdr->ramdisk_image = 0; |
| 792 | hdr->ramdisk_size = 0; | 828 | hdr->ramdisk_size = 0; |
| 793 | 829 | ||
| 794 | status = handle_ramdisks(image, hdr); | ||
| 795 | if (status != EFI_SUCCESS) | ||
| 796 | goto free_cmdline; | ||
| 797 | |||
| 798 | setup_graphics(boot_params); | ||
| 799 | |||
| 800 | /* Clear APM BIOS info */ | 830 | /* Clear APM BIOS info */ |
| 801 | memset(bi, 0, sizeof(*bi)); | 831 | memset(bi, 0, sizeof(*bi)); |
| 802 | 832 | ||
| 803 | memset(sdt, 0, sizeof(*sdt)); | 833 | memset(sdt, 0, sizeof(*sdt)); |
| 804 | 834 | ||
| 805 | memcpy(&efi->efi_loader_signature, EFI_LOADER_SIGNATURE, sizeof(__u32)); | 835 | status = handle_ramdisks(image, hdr); |
| 836 | if (status != EFI_SUCCESS) | ||
| 837 | goto fail2; | ||
| 838 | |||
| 839 | return boot_params; | ||
| 840 | fail2: | ||
| 841 | if (options_size) | ||
| 842 | low_free(options_size, hdr->cmd_line_ptr); | ||
| 843 | fail: | ||
| 844 | low_free(0x4000, (unsigned long)boot_params); | ||
| 845 | return NULL; | ||
| 846 | } | ||
| 847 | |||
| 848 | static efi_status_t exit_boot(struct boot_params *boot_params, | ||
| 849 | void *handle) | ||
| 850 | { | ||
| 851 | struct efi_info *efi = &boot_params->efi_info; | ||
| 852 | struct e820entry *e820_map = &boot_params->e820_map[0]; | ||
| 853 | struct e820entry *prev = NULL; | ||
| 854 | unsigned long size, key, desc_size, _size; | ||
| 855 | efi_memory_desc_t *mem_map; | ||
| 856 | efi_status_t status; | ||
| 857 | __u32 desc_version; | ||
| 858 | u8 nr_entries; | ||
| 859 | int i; | ||
| 806 | 860 | ||
| 807 | size = sizeof(*mem_map) * 32; | 861 | size = sizeof(*mem_map) * 32; |
| 808 | 862 | ||
| @@ -811,7 +865,7 @@ again: | |||
| 811 | _size = size; | 865 | _size = size; |
| 812 | status = low_alloc(size, 1, (unsigned long *)&mem_map); | 866 | status = low_alloc(size, 1, (unsigned long *)&mem_map); |
| 813 | if (status != EFI_SUCCESS) | 867 | if (status != EFI_SUCCESS) |
| 814 | goto free_cmdline; | 868 | return status; |
| 815 | 869 | ||
| 816 | status = efi_call_phys5(sys_table->boottime->get_memory_map, &size, | 870 | status = efi_call_phys5(sys_table->boottime->get_memory_map, &size, |
| 817 | mem_map, &key, &desc_size, &desc_version); | 871 | mem_map, &key, &desc_size, &desc_version); |
| @@ -823,6 +877,7 @@ again: | |||
| 823 | if (status != EFI_SUCCESS) | 877 | if (status != EFI_SUCCESS) |
| 824 | goto free_mem_map; | 878 | goto free_mem_map; |
| 825 | 879 | ||
| 880 | memcpy(&efi->efi_loader_signature, EFI_LOADER_SIGNATURE, sizeof(__u32)); | ||
| 826 | efi->efi_systab = (unsigned long)sys_table; | 881 | efi->efi_systab = (unsigned long)sys_table; |
| 827 | efi->efi_memdesc_size = desc_size; | 882 | efi->efi_memdesc_size = desc_size; |
| 828 | efi->efi_memdesc_version = desc_version; | 883 | efi->efi_memdesc_version = desc_version; |
| @@ -906,61 +961,13 @@ again: | |||
| 906 | 961 | ||
| 907 | free_mem_map: | 962 | free_mem_map: |
| 908 | low_free(_size, (unsigned long)mem_map); | 963 | low_free(_size, (unsigned long)mem_map); |
| 909 | free_cmdline: | ||
| 910 | if (options_size) | ||
| 911 | low_free(options_size, hdr->cmd_line_ptr); | ||
| 912 | fail: | ||
| 913 | return status; | 964 | return status; |
| 914 | } | 965 | } |
| 915 | 966 | ||
| 916 | /* | 967 | static efi_status_t relocate_kernel(struct setup_header *hdr) |
| 917 | * On success we return a pointer to a boot_params structure, and NULL | ||
| 918 | * on failure. | ||
| 919 | */ | ||
| 920 | struct boot_params *efi_main(void *handle, efi_system_table_t *_table) | ||
| 921 | { | 968 | { |
| 922 | struct boot_params *boot_params; | ||
| 923 | unsigned long start, nr_pages; | 969 | unsigned long start, nr_pages; |
| 924 | struct desc_ptr *gdt, *idt; | ||
| 925 | efi_loaded_image_t *image; | ||
| 926 | struct setup_header *hdr; | ||
| 927 | efi_status_t status; | 970 | efi_status_t status; |
| 928 | efi_guid_t proto = LOADED_IMAGE_PROTOCOL_GUID; | ||
| 929 | struct desc_struct *desc; | ||
| 930 | |||
| 931 | sys_table = _table; | ||
| 932 | |||
| 933 | /* Check if we were booted by the EFI firmware */ | ||
| 934 | if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) | ||
| 935 | goto fail; | ||
| 936 | |||
| 937 | status = efi_call_phys3(sys_table->boottime->handle_protocol, | ||
| 938 | handle, &proto, (void *)&image); | ||
| 939 | if (status != EFI_SUCCESS) { | ||
| 940 | efi_printk("Failed to get handle for LOADED_IMAGE_PROTOCOL\n"); | ||
| 941 | goto fail; | ||
| 942 | } | ||
| 943 | |||
| 944 | status = low_alloc(0x4000, 1, (unsigned long *)&boot_params); | ||
| 945 | if (status != EFI_SUCCESS) { | ||
| 946 | efi_printk("Failed to alloc lowmem for boot params\n"); | ||
| 947 | goto fail; | ||
| 948 | } | ||
| 949 | |||
| 950 | memset(boot_params, 0x0, 0x4000); | ||
| 951 | |||
| 952 | hdr = &boot_params->hdr; | ||
| 953 | |||
| 954 | /* Copy the second sector to boot_params */ | ||
| 955 | memcpy(&hdr->jump, image->image_base + 512, 512); | ||
| 956 | |||
| 957 | /* | ||
| 958 | * Fill out some of the header fields ourselves because the | ||
| 959 | * EFI firmware loader doesn't load the first sector. | ||
| 960 | */ | ||
| 961 | hdr->root_flags = 1; | ||
| 962 | hdr->vid_mode = 0xffff; | ||
| 963 | hdr->boot_flag = 0xAA55; | ||
| 964 | 971 | ||
| 965 | /* | 972 | /* |
| 966 | * The EFI firmware loader could have placed the kernel image | 973 | * The EFI firmware loader could have placed the kernel image |
| @@ -978,16 +985,40 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table) | |||
| 978 | if (status != EFI_SUCCESS) { | 985 | if (status != EFI_SUCCESS) { |
| 979 | status = low_alloc(hdr->init_size, hdr->kernel_alignment, | 986 | status = low_alloc(hdr->init_size, hdr->kernel_alignment, |
| 980 | &start); | 987 | &start); |
| 981 | if (status != EFI_SUCCESS) { | 988 | if (status != EFI_SUCCESS) |
| 982 | efi_printk("Failed to alloc mem for kernel\n"); | 989 | efi_printk("Failed to alloc mem for kernel\n"); |
| 983 | goto fail; | ||
| 984 | } | ||
| 985 | } | 990 | } |
| 986 | 991 | ||
| 992 | if (status == EFI_SUCCESS) | ||
| 993 | memcpy((void *)start, (void *)(unsigned long)hdr->code32_start, | ||
| 994 | hdr->init_size); | ||
| 995 | |||
| 996 | hdr->pref_address = hdr->code32_start; | ||
| 987 | hdr->code32_start = (__u32)start; | 997 | hdr->code32_start = (__u32)start; |
| 988 | hdr->pref_address = (__u64)(unsigned long)image->image_base; | ||
| 989 | 998 | ||
| 990 | memcpy((void *)start, image->image_base, image->image_size); | 999 | return status; |
| 1000 | } | ||
| 1001 | |||
| 1002 | /* | ||
| 1003 | * On success we return a pointer to a boot_params structure, and NULL | ||
| 1004 | * on failure. | ||
| 1005 | */ | ||
| 1006 | struct boot_params *efi_main(void *handle, efi_system_table_t *_table, | ||
| 1007 | struct boot_params *boot_params) | ||
| 1008 | { | ||
| 1009 | struct desc_ptr *gdt, *idt; | ||
| 1010 | efi_loaded_image_t *image; | ||
| 1011 | struct setup_header *hdr = &boot_params->hdr; | ||
| 1012 | efi_status_t status; | ||
| 1013 | struct desc_struct *desc; | ||
| 1014 | |||
| 1015 | sys_table = _table; | ||
| 1016 | |||
| 1017 | /* Check if we were booted by the EFI firmware */ | ||
| 1018 | if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) | ||
| 1019 | goto fail; | ||
| 1020 | |||
| 1021 | setup_graphics(boot_params); | ||
| 991 | 1022 | ||
| 992 | status = efi_call_phys3(sys_table->boottime->allocate_pool, | 1023 | status = efi_call_phys3(sys_table->boottime->allocate_pool, |
| 993 | EFI_LOADER_DATA, sizeof(*gdt), | 1024 | EFI_LOADER_DATA, sizeof(*gdt), |
| @@ -1015,7 +1046,18 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table) | |||
| 1015 | idt->size = 0; | 1046 | idt->size = 0; |
| 1016 | idt->address = 0; | 1047 | idt->address = 0; |
| 1017 | 1048 | ||
| 1018 | status = make_boot_params(boot_params, image, handle); | 1049 | /* |
| 1050 | * If the kernel isn't already loaded at the preferred load | ||
| 1051 | * address, relocate it. | ||
| 1052 | */ | ||
| 1053 | if (hdr->pref_address != hdr->code32_start) { | ||
| 1054 | status = relocate_kernel(hdr); | ||
| 1055 | |||
| 1056 | if (status != EFI_SUCCESS) | ||
| 1057 | goto fail; | ||
| 1058 | } | ||
| 1059 | |||
| 1060 | status = exit_boot(boot_params, handle); | ||
| 1019 | if (status != EFI_SUCCESS) | 1061 | if (status != EFI_SUCCESS) |
| 1020 | goto fail; | 1062 | goto fail; |
| 1021 | 1063 | ||
diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S index c85e3ac99bba..aa4aaf1b2380 100644 --- a/arch/x86/boot/compressed/head_32.S +++ b/arch/x86/boot/compressed/head_32.S | |||
| @@ -42,6 +42,16 @@ ENTRY(startup_32) | |||
| 42 | */ | 42 | */ |
| 43 | add $0x4, %esp | 43 | add $0x4, %esp |
| 44 | 44 | ||
| 45 | call make_boot_params | ||
| 46 | cmpl $0, %eax | ||
| 47 | je 1f | ||
| 48 | movl 0x4(%esp), %esi | ||
| 49 | movl (%esp), %ecx | ||
| 50 | pushl %eax | ||
| 51 | pushl %esi | ||
| 52 | pushl %ecx | ||
| 53 | |||
| 54 | .org 0x30,0x90 | ||
| 45 | call efi_main | 55 | call efi_main |
| 46 | cmpl $0, %eax | 56 | cmpl $0, %eax |
| 47 | movl %eax, %esi | 57 | movl %eax, %esi |
diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S index 87e03a13d8e3..2c4b171eec33 100644 --- a/arch/x86/boot/compressed/head_64.S +++ b/arch/x86/boot/compressed/head_64.S | |||
| @@ -209,6 +209,16 @@ ENTRY(startup_64) | |||
| 209 | .org 0x210 | 209 | .org 0x210 |
| 210 | mov %rcx, %rdi | 210 | mov %rcx, %rdi |
| 211 | mov %rdx, %rsi | 211 | mov %rdx, %rsi |
| 212 | pushq %rdi | ||
| 213 | pushq %rsi | ||
| 214 | call make_boot_params | ||
| 215 | cmpq $0,%rax | ||
| 216 | je 1f | ||
| 217 | mov %rax, %rdx | ||
| 218 | popq %rsi | ||
| 219 | popq %rdi | ||
| 220 | |||
| 221 | .org 0x230,0x90 | ||
| 212 | call efi_main | 222 | call efi_main |
| 213 | movq %rax,%rsi | 223 | movq %rax,%rsi |
| 214 | cmpq $0,%rax | 224 | cmpq $0,%rax |
diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c index 7116dcba0c9e..88f7ff6da404 100644 --- a/arch/x86/boot/compressed/misc.c +++ b/arch/x86/boot/compressed/misc.c | |||
| @@ -108,8 +108,6 @@ static void error(char *m); | |||
| 108 | * This is set up by the setup-routine at boot-time | 108 | * This is set up by the setup-routine at boot-time |
| 109 | */ | 109 | */ |
| 110 | struct boot_params *real_mode; /* Pointer to real-mode data */ | 110 | struct boot_params *real_mode; /* Pointer to real-mode data */ |
| 111 | static int quiet; | ||
| 112 | static int debug; | ||
| 113 | 111 | ||
| 114 | void *memset(void *s, int c, size_t n); | 112 | void *memset(void *s, int c, size_t n); |
| 115 | void *memcpy(void *dest, const void *src, size_t n); | 113 | void *memcpy(void *dest, const void *src, size_t n); |
| @@ -170,15 +168,11 @@ static void serial_putchar(int ch) | |||
| 170 | outb(ch, early_serial_base + TXR); | 168 | outb(ch, early_serial_base + TXR); |
| 171 | } | 169 | } |
| 172 | 170 | ||
| 173 | void __putstr(int error, const char *s) | 171 | void __putstr(const char *s) |
| 174 | { | 172 | { |
| 175 | int x, y, pos; | 173 | int x, y, pos; |
| 176 | char c; | 174 | char c; |
| 177 | 175 | ||
| 178 | #ifndef CONFIG_X86_VERBOSE_BOOTUP | ||
| 179 | if (!error) | ||
| 180 | return; | ||
| 181 | #endif | ||
| 182 | if (early_serial_base) { | 176 | if (early_serial_base) { |
| 183 | const char *str = s; | 177 | const char *str = s; |
| 184 | while (*str) { | 178 | while (*str) { |
| @@ -265,9 +259,9 @@ void *memcpy(void *dest, const void *src, size_t n) | |||
| 265 | 259 | ||
| 266 | static void error(char *x) | 260 | static void error(char *x) |
| 267 | { | 261 | { |
| 268 | __putstr(1, "\n\n"); | 262 | error_putstr("\n\n"); |
| 269 | __putstr(1, x); | 263 | error_putstr(x); |
| 270 | __putstr(1, "\n\n -- System halted"); | 264 | error_putstr("\n\n -- System halted"); |
| 271 | 265 | ||
| 272 | while (1) | 266 | while (1) |
| 273 | asm("hlt"); | 267 | asm("hlt"); |
| @@ -294,8 +288,7 @@ static void parse_elf(void *output) | |||
| 294 | return; | 288 | return; |
| 295 | } | 289 | } |
| 296 | 290 | ||
| 297 | if (!quiet) | 291 | debug_putstr("Parsing ELF... "); |
| 298 | putstr("Parsing ELF... "); | ||
| 299 | 292 | ||
| 300 | phdrs = malloc(sizeof(*phdrs) * ehdr.e_phnum); | 293 | phdrs = malloc(sizeof(*phdrs) * ehdr.e_phnum); |
| 301 | if (!phdrs) | 294 | if (!phdrs) |
| @@ -332,11 +325,6 @@ asmlinkage void decompress_kernel(void *rmode, memptr heap, | |||
| 332 | { | 325 | { |
| 333 | real_mode = rmode; | 326 | real_mode = rmode; |
| 334 | 327 | ||
| 335 | if (cmdline_find_option_bool("quiet")) | ||
| 336 | quiet = 1; | ||
| 337 | if (cmdline_find_option_bool("debug")) | ||
| 338 | debug = 1; | ||
| 339 | |||
| 340 | if (real_mode->screen_info.orig_video_mode == 7) { | 328 | if (real_mode->screen_info.orig_video_mode == 7) { |
| 341 | vidmem = (char *) 0xb0000; | 329 | vidmem = (char *) 0xb0000; |
| 342 | vidport = 0x3b4; | 330 | vidport = 0x3b4; |
| @@ -349,8 +337,7 @@ asmlinkage void decompress_kernel(void *rmode, memptr heap, | |||
| 349 | cols = real_mode->screen_info.orig_video_cols; | 337 | cols = real_mode->screen_info.orig_video_cols; |
| 350 | 338 | ||
| 351 | console_init(); | 339 | console_init(); |
| 352 | if (debug) | 340 | debug_putstr("early console in decompress_kernel\n"); |
| 353 | putstr("early console in decompress_kernel\n"); | ||
| 354 | 341 | ||
| 355 | free_mem_ptr = heap; /* Heap */ | 342 | free_mem_ptr = heap; /* Heap */ |
| 356 | free_mem_end_ptr = heap + BOOT_HEAP_SIZE; | 343 | free_mem_end_ptr = heap + BOOT_HEAP_SIZE; |
| @@ -369,11 +356,9 @@ asmlinkage void decompress_kernel(void *rmode, memptr heap, | |||
| 369 | error("Wrong destination address"); | 356 | error("Wrong destination address"); |
| 370 | #endif | 357 | #endif |
| 371 | 358 | ||
| 372 | if (!quiet) | 359 | debug_putstr("\nDecompressing Linux... "); |
| 373 | putstr("\nDecompressing Linux... "); | ||
| 374 | decompress(input_data, input_len, NULL, NULL, output, NULL, error); | 360 | decompress(input_data, input_len, NULL, NULL, output, NULL, error); |
| 375 | parse_elf(output); | 361 | parse_elf(output); |
| 376 | if (!quiet) | 362 | debug_putstr("done.\nBooting the kernel.\n"); |
| 377 | putstr("done.\nBooting the kernel.\n"); | ||
| 378 | return; | 363 | return; |
| 379 | } | 364 | } |
diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h index 3f19c81a6203..0e6dc0ee0eea 100644 --- a/arch/x86/boot/compressed/misc.h +++ b/arch/x86/boot/compressed/misc.h | |||
| @@ -24,9 +24,21 @@ | |||
| 24 | 24 | ||
| 25 | /* misc.c */ | 25 | /* misc.c */ |
| 26 | extern struct boot_params *real_mode; /* Pointer to real-mode data */ | 26 | extern struct boot_params *real_mode; /* Pointer to real-mode data */ |
| 27 | void __putstr(int error, const char *s); | 27 | void __putstr(const char *s); |
| 28 | #define putstr(__x) __putstr(0, __x) | 28 | #define error_putstr(__x) __putstr(__x) |
| 29 | #define puts(__x) __putstr(0, __x) | 29 | |
| 30 | #ifdef CONFIG_X86_VERBOSE_BOOTUP | ||
| 31 | |||
| 32 | #define debug_putstr(__x) __putstr(__x) | ||
| 33 | |||
| 34 | #else | ||
| 35 | |||
| 36 | static inline void debug_putstr(const char *s) | ||
| 37 | { } | ||
| 38 | |||
| 39 | #endif | ||
| 40 | |||
| 41 | #ifdef CONFIG_EARLY_PRINTK | ||
| 30 | 42 | ||
| 31 | /* cmdline.c */ | 43 | /* cmdline.c */ |
| 32 | int cmdline_find_option(const char *option, char *buffer, int bufsize); | 44 | int cmdline_find_option(const char *option, char *buffer, int bufsize); |
| @@ -36,4 +48,13 @@ int cmdline_find_option_bool(const char *option); | |||
| 36 | extern int early_serial_base; | 48 | extern int early_serial_base; |
| 37 | void console_init(void); | 49 | void console_init(void); |
| 38 | 50 | ||
| 51 | #else | ||
| 52 | |||
| 53 | /* early_serial_console.c */ | ||
| 54 | static const int early_serial_base; | ||
| 55 | static inline void console_init(void) | ||
| 56 | { } | ||
| 57 | |||
| 58 | #endif | ||
| 59 | |||
| 39 | #endif | 60 | #endif |
diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S index efe5acfc79c3..b4e15dd6786a 100644 --- a/arch/x86/boot/header.S +++ b/arch/x86/boot/header.S | |||
| @@ -283,7 +283,7 @@ _start: | |||
| 283 | # Part 2 of the header, from the old setup.S | 283 | # Part 2 of the header, from the old setup.S |
| 284 | 284 | ||
| 285 | .ascii "HdrS" # header signature | 285 | .ascii "HdrS" # header signature |
| 286 | .word 0x020a # header version number (>= 0x0105) | 286 | .word 0x020b # header version number (>= 0x0105) |
| 287 | # or else old loadlin-1.5 will fail) | 287 | # or else old loadlin-1.5 will fail) |
| 288 | .globl realmode_swtch | 288 | .globl realmode_swtch |
| 289 | realmode_swtch: .word 0, 0 # default_switch, SETUPSEG | 289 | realmode_swtch: .word 0, 0 # default_switch, SETUPSEG |
| @@ -401,18 +401,13 @@ pref_address: .quad LOAD_PHYSICAL_ADDR # preferred load addr | |||
| 401 | #define INIT_SIZE VO_INIT_SIZE | 401 | #define INIT_SIZE VO_INIT_SIZE |
| 402 | #endif | 402 | #endif |
| 403 | init_size: .long INIT_SIZE # kernel initialization size | 403 | init_size: .long INIT_SIZE # kernel initialization size |
| 404 | handover_offset: .long 0x30 # offset to the handover | ||
| 405 | # protocol entry point | ||
| 404 | 406 | ||
| 405 | # End of setup header ##################################################### | 407 | # End of setup header ##################################################### |
| 406 | 408 | ||
| 407 | .section ".entrytext", "ax" | 409 | .section ".entrytext", "ax" |
| 408 | start_of_setup: | 410 | start_of_setup: |
| 409 | #ifdef SAFE_RESET_DISK_CONTROLLER | ||
| 410 | # Reset the disk controller. | ||
| 411 | movw $0x0000, %ax # Reset disk controller | ||
| 412 | movb $0x80, %dl # All disks | ||
| 413 | int $0x13 | ||
| 414 | #endif | ||
| 415 | |||
| 416 | # Force %es = %ds | 411 | # Force %es = %ds |
| 417 | movw %ds, %ax | 412 | movw %ds, %ax |
| 418 | movw %ax, %es | 413 | movw %ax, %es |
diff --git a/arch/x86/crypto/Makefile b/arch/x86/crypto/Makefile index e191ac048b59..e908e5de82d3 100644 --- a/arch/x86/crypto/Makefile +++ b/arch/x86/crypto/Makefile | |||
| @@ -2,6 +2,9 @@ | |||
| 2 | # Arch-specific CryptoAPI modules. | 2 | # Arch-specific CryptoAPI modules. |
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | obj-$(CONFIG_CRYPTO_ABLK_HELPER_X86) += ablk_helper.o | ||
| 6 | obj-$(CONFIG_CRYPTO_GLUE_HELPER_X86) += glue_helper.o | ||
| 7 | |||
| 5 | obj-$(CONFIG_CRYPTO_AES_586) += aes-i586.o | 8 | obj-$(CONFIG_CRYPTO_AES_586) += aes-i586.o |
| 6 | obj-$(CONFIG_CRYPTO_TWOFISH_586) += twofish-i586.o | 9 | obj-$(CONFIG_CRYPTO_TWOFISH_586) += twofish-i586.o |
| 7 | obj-$(CONFIG_CRYPTO_SALSA20_586) += salsa20-i586.o | 10 | obj-$(CONFIG_CRYPTO_SALSA20_586) += salsa20-i586.o |
| @@ -12,8 +15,10 @@ obj-$(CONFIG_CRYPTO_CAMELLIA_X86_64) += camellia-x86_64.o | |||
| 12 | obj-$(CONFIG_CRYPTO_BLOWFISH_X86_64) += blowfish-x86_64.o | 15 | obj-$(CONFIG_CRYPTO_BLOWFISH_X86_64) += blowfish-x86_64.o |
| 13 | obj-$(CONFIG_CRYPTO_TWOFISH_X86_64) += twofish-x86_64.o | 16 | obj-$(CONFIG_CRYPTO_TWOFISH_X86_64) += twofish-x86_64.o |
| 14 | obj-$(CONFIG_CRYPTO_TWOFISH_X86_64_3WAY) += twofish-x86_64-3way.o | 17 | obj-$(CONFIG_CRYPTO_TWOFISH_X86_64_3WAY) += twofish-x86_64-3way.o |
| 18 | obj-$(CONFIG_CRYPTO_TWOFISH_AVX_X86_64) += twofish-avx-x86_64.o | ||
| 15 | obj-$(CONFIG_CRYPTO_SALSA20_X86_64) += salsa20-x86_64.o | 19 | obj-$(CONFIG_CRYPTO_SALSA20_X86_64) += salsa20-x86_64.o |
| 16 | obj-$(CONFIG_CRYPTO_SERPENT_SSE2_X86_64) += serpent-sse2-x86_64.o | 20 | obj-$(CONFIG_CRYPTO_SERPENT_SSE2_X86_64) += serpent-sse2-x86_64.o |
| 21 | obj-$(CONFIG_CRYPTO_SERPENT_AVX_X86_64) += serpent-avx-x86_64.o | ||
| 17 | obj-$(CONFIG_CRYPTO_AES_NI_INTEL) += aesni-intel.o | 22 | obj-$(CONFIG_CRYPTO_AES_NI_INTEL) += aesni-intel.o |
| 18 | obj-$(CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL) += ghash-clmulni-intel.o | 23 | obj-$(CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL) += ghash-clmulni-intel.o |
| 19 | 24 | ||
| @@ -30,16 +35,11 @@ camellia-x86_64-y := camellia-x86_64-asm_64.o camellia_glue.o | |||
| 30 | blowfish-x86_64-y := blowfish-x86_64-asm_64.o blowfish_glue.o | 35 | blowfish-x86_64-y := blowfish-x86_64-asm_64.o blowfish_glue.o |
| 31 | twofish-x86_64-y := twofish-x86_64-asm_64.o twofish_glue.o | 36 | twofish-x86_64-y := twofish-x86_64-asm_64.o twofish_glue.o |
| 32 | twofish-x86_64-3way-y := twofish-x86_64-asm_64-3way.o twofish_glue_3way.o | 37 | twofish-x86_64-3way-y := twofish-x86_64-asm_64-3way.o twofish_glue_3way.o |
| 38 | twofish-avx-x86_64-y := twofish-avx-x86_64-asm_64.o twofish_avx_glue.o | ||
| 33 | salsa20-x86_64-y := salsa20-x86_64-asm_64.o salsa20_glue.o | 39 | salsa20-x86_64-y := salsa20-x86_64-asm_64.o salsa20_glue.o |
| 34 | serpent-sse2-x86_64-y := serpent-sse2-x86_64-asm_64.o serpent_sse2_glue.o | 40 | serpent-sse2-x86_64-y := serpent-sse2-x86_64-asm_64.o serpent_sse2_glue.o |
| 41 | serpent-avx-x86_64-y := serpent-avx-x86_64-asm_64.o serpent_avx_glue.o | ||
| 35 | 42 | ||
| 36 | aesni-intel-y := aesni-intel_asm.o aesni-intel_glue.o fpu.o | 43 | aesni-intel-y := aesni-intel_asm.o aesni-intel_glue.o fpu.o |
| 37 | |||
| 38 | ghash-clmulni-intel-y := ghash-clmulni-intel_asm.o ghash-clmulni-intel_glue.o | 44 | ghash-clmulni-intel-y := ghash-clmulni-intel_asm.o ghash-clmulni-intel_glue.o |
| 39 | |||
| 40 | # enable AVX support only when $(AS) can actually assemble the instructions | ||
| 41 | ifeq ($(call as-instr,vpxor %xmm0$(comma)%xmm1$(comma)%xmm2,yes,no),yes) | ||
| 42 | AFLAGS_sha1_ssse3_asm.o += -DSHA1_ENABLE_AVX_SUPPORT | ||
| 43 | CFLAGS_sha1_ssse3_glue.o += -DSHA1_ENABLE_AVX_SUPPORT | ||
| 44 | endif | ||
| 45 | sha1-ssse3-y := sha1_ssse3_asm.o sha1_ssse3_glue.o | 45 | sha1-ssse3-y := sha1_ssse3_asm.o sha1_ssse3_glue.o |
diff --git a/arch/x86/crypto/ablk_helper.c b/arch/x86/crypto/ablk_helper.c new file mode 100644 index 000000000000..43282fe04a8b --- /dev/null +++ b/arch/x86/crypto/ablk_helper.c | |||
| @@ -0,0 +1,149 @@ | |||
| 1 | /* | ||
| 2 | * Shared async block cipher helpers | ||
| 3 | * | ||
| 4 | * Copyright (c) 2012 Jussi Kivilinna <jussi.kivilinna@mbnet.fi> | ||
| 5 | * | ||
| 6 | * Based on aesni-intel_glue.c by: | ||
| 7 | * Copyright (C) 2008, Intel Corp. | ||
| 8 | * Author: Huang Ying <ying.huang@intel.com> | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License as published by | ||
| 12 | * the Free Software Foundation; either version 2 of the License, or | ||
| 13 | * (at your option) any later version. | ||
| 14 | * | ||
| 15 | * This program is distributed in the hope that it will be useful, | ||
| 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 18 | * GNU General Public License for more details. | ||
| 19 | * | ||
| 20 | * You should have received a copy of the GNU General Public License | ||
| 21 | * along with this program; if not, write to the Free Software | ||
| 22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | ||
| 23 | * USA | ||
| 24 | * | ||
| 25 | */ | ||
| 26 | |||
| 27 | #include <linux/kernel.h> | ||
| 28 | #include <linux/crypto.h> | ||
| 29 | #include <linux/init.h> | ||
| 30 | #include <linux/module.h> | ||
| 31 | #include <crypto/algapi.h> | ||
| 32 | #include <crypto/cryptd.h> | ||
| 33 | #include <asm/i387.h> | ||
| 34 | #include <asm/crypto/ablk_helper.h> | ||
| 35 | |||
| 36 | int ablk_set_key(struct crypto_ablkcipher *tfm, const u8 *key, | ||
| 37 | unsigned int key_len) | ||
| 38 | { | ||
| 39 | struct async_helper_ctx *ctx = crypto_ablkcipher_ctx(tfm); | ||
| 40 | struct crypto_ablkcipher *child = &ctx->cryptd_tfm->base; | ||
| 41 | int err; | ||
| 42 | |||
| 43 | crypto_ablkcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK); | ||
| 44 | crypto_ablkcipher_set_flags(child, crypto_ablkcipher_get_flags(tfm) | ||
| 45 | & CRYPTO_TFM_REQ_MASK); | ||
| 46 | err = crypto_ablkcipher_setkey(child, key, key_len); | ||
| 47 | crypto_ablkcipher_set_flags(tfm, crypto_ablkcipher_get_flags(child) | ||
| 48 | & CRYPTO_TFM_RES_MASK); | ||
| 49 | return err; | ||
| 50 | } | ||
| 51 | EXPORT_SYMBOL_GPL(ablk_set_key); | ||
| 52 | |||
| 53 | int __ablk_encrypt(struct ablkcipher_request *req) | ||
| 54 | { | ||
| 55 | struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); | ||
| 56 | struct async_helper_ctx *ctx = crypto_ablkcipher_ctx(tfm); | ||
| 57 | struct blkcipher_desc desc; | ||
| 58 | |||
| 59 | desc.tfm = cryptd_ablkcipher_child(ctx->cryptd_tfm); | ||
| 60 | desc.info = req->info; | ||
| 61 | desc.flags = 0; | ||
| 62 | |||
| 63 | return crypto_blkcipher_crt(desc.tfm)->encrypt( | ||
| 64 | &desc, req->dst, req->src, req->nbytes); | ||
| 65 | } | ||
| 66 | EXPORT_SYMBOL_GPL(__ablk_encrypt); | ||
| 67 | |||
| 68 | int ablk_encrypt(struct ablkcipher_request *req) | ||
| 69 | { | ||
| 70 | struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); | ||
| 71 | struct async_helper_ctx *ctx = crypto_ablkcipher_ctx(tfm); | ||
| 72 | |||
| 73 | if (!irq_fpu_usable()) { | ||
| 74 | struct ablkcipher_request *cryptd_req = | ||
| 75 | ablkcipher_request_ctx(req); | ||
| 76 | |||
| 77 | memcpy(cryptd_req, req, sizeof(*req)); | ||
| 78 | ablkcipher_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base); | ||
| 79 | |||
| 80 | return crypto_ablkcipher_encrypt(cryptd_req); | ||
| 81 | } else { | ||
| 82 | return __ablk_encrypt(req); | ||
| 83 | } | ||
| 84 | } | ||
| 85 | EXPORT_SYMBOL_GPL(ablk_encrypt); | ||
| 86 | |||
| 87 | int ablk_decrypt(struct ablkcipher_request *req) | ||
| 88 | { | ||
| 89 | struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); | ||
| 90 | struct async_helper_ctx *ctx = crypto_ablkcipher_ctx(tfm); | ||
| 91 | |||
| 92 | if (!irq_fpu_usable()) { | ||
| 93 | struct ablkcipher_request *cryptd_req = | ||
| 94 | ablkcipher_request_ctx(req); | ||
| 95 | |||
| 96 | memcpy(cryptd_req, req, sizeof(*req)); | ||
| 97 | ablkcipher_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base); | ||
| 98 | |||
| 99 | return crypto_ablkcipher_decrypt(cryptd_req); | ||
| 100 | } else { | ||
| 101 | struct blkcipher_desc desc; | ||
| 102 | |||
| 103 | desc.tfm = cryptd_ablkcipher_child(ctx->cryptd_tfm); | ||
| 104 | desc.info = req->info; | ||
| 105 | desc.flags = 0; | ||
| 106 | |||
| 107 | return crypto_blkcipher_crt(desc.tfm)->decrypt( | ||
| 108 | &desc, req->dst, req->src, req->nbytes); | ||
| 109 | } | ||
| 110 | } | ||
| 111 | EXPORT_SYMBOL_GPL(ablk_decrypt); | ||
| 112 | |||
| 113 | void ablk_exit(struct crypto_tfm *tfm) | ||
| 114 | { | ||
| 115 | struct async_helper_ctx *ctx = crypto_tfm_ctx(tfm); | ||
| 116 | |||
| 117 | cryptd_free_ablkcipher(ctx->cryptd_tfm); | ||
| 118 | } | ||
| 119 | EXPORT_SYMBOL_GPL(ablk_exit); | ||
| 120 | |||
| 121 | int ablk_init_common(struct crypto_tfm *tfm, const char *drv_name) | ||
| 122 | { | ||
| 123 | struct async_helper_ctx *ctx = crypto_tfm_ctx(tfm); | ||
| 124 | struct cryptd_ablkcipher *cryptd_tfm; | ||
| 125 | |||
| 126 | cryptd_tfm = cryptd_alloc_ablkcipher(drv_name, 0, 0); | ||
| 127 | if (IS_ERR(cryptd_tfm)) | ||
| 128 | return PTR_ERR(cryptd_tfm); | ||
| 129 | |||
| 130 | ctx->cryptd_tfm = cryptd_tfm; | ||
| 131 | tfm->crt_ablkcipher.reqsize = sizeof(struct ablkcipher_request) + | ||
| 132 | crypto_ablkcipher_reqsize(&cryptd_tfm->base); | ||
| 133 | |||
| 134 | return 0; | ||
| 135 | } | ||
| 136 | EXPORT_SYMBOL_GPL(ablk_init_common); | ||
| 137 | |||
| 138 | int ablk_init(struct crypto_tfm *tfm) | ||
| 139 | { | ||
| 140 | char drv_name[CRYPTO_MAX_ALG_NAME]; | ||
| 141 | |||
| 142 | snprintf(drv_name, sizeof(drv_name), "__driver-%s", | ||
| 143 | crypto_tfm_alg_driver_name(tfm)); | ||
| 144 | |||
| 145 | return ablk_init_common(tfm, drv_name); | ||
| 146 | } | ||
| 147 | EXPORT_SYMBOL_GPL(ablk_init); | ||
| 148 | |||
| 149 | MODULE_LICENSE("GPL"); | ||
diff --git a/arch/x86/crypto/aes_glue.c b/arch/x86/crypto/aes_glue.c index 8efcf42a9d7e..59b37deb8c8d 100644 --- a/arch/x86/crypto/aes_glue.c +++ b/arch/x86/crypto/aes_glue.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | 5 | ||
| 6 | #include <linux/module.h> | 6 | #include <linux/module.h> |
| 7 | #include <crypto/aes.h> | 7 | #include <crypto/aes.h> |
| 8 | #include <asm/aes.h> | 8 | #include <asm/crypto/aes.h> |
| 9 | 9 | ||
| 10 | asmlinkage void aes_enc_blk(struct crypto_aes_ctx *ctx, u8 *out, const u8 *in); | 10 | asmlinkage void aes_enc_blk(struct crypto_aes_ctx *ctx, u8 *out, const u8 *in); |
| 11 | asmlinkage void aes_dec_blk(struct crypto_aes_ctx *ctx, u8 *out, const u8 *in); | 11 | asmlinkage void aes_dec_blk(struct crypto_aes_ctx *ctx, u8 *out, const u8 *in); |
diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c index ac7f5cd019e8..34fdcff4d2c8 100644 --- a/arch/x86/crypto/aesni-intel_glue.c +++ b/arch/x86/crypto/aesni-intel_glue.c | |||
| @@ -30,7 +30,8 @@ | |||
| 30 | #include <crypto/ctr.h> | 30 | #include <crypto/ctr.h> |
| 31 | #include <asm/cpu_device_id.h> | 31 | #include <asm/cpu_device_id.h> |
| 32 | #include <asm/i387.h> | 32 | #include <asm/i387.h> |
| 33 | #include <asm/aes.h> | 33 | #include <asm/crypto/aes.h> |
| 34 | #include <asm/crypto/ablk_helper.h> | ||
| 34 | #include <crypto/scatterwalk.h> | 35 | #include <crypto/scatterwalk.h> |
| 35 | #include <crypto/internal/aead.h> | 36 | #include <crypto/internal/aead.h> |
| 36 | #include <linux/workqueue.h> | 37 | #include <linux/workqueue.h> |
| @@ -52,10 +53,6 @@ | |||
| 52 | #define HAS_XTS | 53 | #define HAS_XTS |
| 53 | #endif | 54 | #endif |
| 54 | 55 | ||
| 55 | struct async_aes_ctx { | ||
| 56 | struct cryptd_ablkcipher *cryptd_tfm; | ||
| 57 | }; | ||
| 58 | |||
| 59 | /* This data is stored at the end of the crypto_tfm struct. | 56 | /* This data is stored at the end of the crypto_tfm struct. |
| 60 | * It's a type of per "session" data storage location. | 57 | * It's a type of per "session" data storage location. |
| 61 | * This needs to be 16 byte aligned. | 58 | * This needs to be 16 byte aligned. |
| @@ -377,87 +374,6 @@ static int ctr_crypt(struct blkcipher_desc *desc, | |||
| 377 | } | 374 | } |
| 378 | #endif | 375 | #endif |
| 379 | 376 | ||
| 380 | static int ablk_set_key(struct crypto_ablkcipher *tfm, const u8 *key, | ||
| 381 | unsigned int key_len) | ||
| 382 | { | ||
| 383 | struct async_aes_ctx *ctx = crypto_ablkcipher_ctx(tfm); | ||
| 384 | struct crypto_ablkcipher *child = &ctx->cryptd_tfm->base; | ||
| 385 | int err; | ||
| 386 | |||
| 387 | crypto_ablkcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK); | ||
| 388 | crypto_ablkcipher_set_flags(child, crypto_ablkcipher_get_flags(tfm) | ||
| 389 | & CRYPTO_TFM_REQ_MASK); | ||
| 390 | err = crypto_ablkcipher_setkey(child, key, key_len); | ||
| 391 | crypto_ablkcipher_set_flags(tfm, crypto_ablkcipher_get_flags(child) | ||
| 392 | & CRYPTO_TFM_RES_MASK); | ||
| 393 | return err; | ||
| 394 | } | ||
| 395 | |||
| 396 | static int ablk_encrypt(struct ablkcipher_request *req) | ||
| 397 | { | ||
| 398 | struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); | ||
| 399 | struct async_aes_ctx *ctx = crypto_ablkcipher_ctx(tfm); | ||
| 400 | |||
| 401 | if (!irq_fpu_usable()) { | ||
| 402 | struct ablkcipher_request *cryptd_req = | ||
| 403 | ablkcipher_request_ctx(req); | ||
| 404 | memcpy(cryptd_req, req, sizeof(*req)); | ||
| 405 | ablkcipher_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base); | ||
| 406 | return crypto_ablkcipher_encrypt(cryptd_req); | ||
| 407 | } else { | ||
| 408 | struct blkcipher_desc desc; | ||
| 409 | desc.tfm = cryptd_ablkcipher_child(ctx->cryptd_tfm); | ||
| 410 | desc.info = req->info; | ||
| 411 | desc.flags = 0; | ||
| 412 | return crypto_blkcipher_crt(desc.tfm)->encrypt( | ||
| 413 | &desc, req->dst, req->src, req->nbytes); | ||
| 414 | } | ||
| 415 | } | ||
| 416 | |||
| 417 | static int ablk_decrypt(struct ablkcipher_request *req) | ||
| 418 | { | ||
| 419 | struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); | ||
| 420 | struct async_aes_ctx *ctx = crypto_ablkcipher_ctx(tfm); | ||
| 421 | |||
| 422 | if (!irq_fpu_usable()) { | ||
| 423 | struct ablkcipher_request *cryptd_req = | ||
| 424 | ablkcipher_request_ctx(req); | ||
| 425 | memcpy(cryptd_req, req, sizeof(*req)); | ||
| 426 | ablkcipher_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base); | ||
| 427 | return crypto_ablkcipher_decrypt(cryptd_req); | ||
| 428 | } else { | ||
| 429 | struct blkcipher_desc desc; | ||
| 430 | desc.tfm = cryptd_ablkcipher_child(ctx->cryptd_tfm); | ||
| 431 | desc.info = req->info; | ||
| 432 | desc.flags = 0; | ||
| 433 | return crypto_blkcipher_crt(desc.tfm)->decrypt( | ||
| 434 | &desc, req->dst, req->src, req->nbytes); | ||
| 435 | } | ||
| 436 | } | ||
| 437 | |||
| 438 | static void ablk_exit(struct crypto_tfm *tfm) | ||
| 439 | { | ||
| 440 | struct async_aes_ctx *ctx = crypto_tfm_ctx(tfm); | ||
| 441 | |||
| 442 | cryptd_free_ablkcipher(ctx->cryptd_tfm); | ||
| 443 | } | ||
| 444 | |||
| 445 | static int ablk_init_common(struct crypto_tfm *tfm, const char *drv_name) | ||
| 446 | { | ||
| 447 | struct async_aes_ctx *ctx = crypto_tfm_ctx(tfm); | ||
| 448 | struct cryptd_ablkcipher *cryptd_tfm; | ||
| 449 | |||
| 450 | cryptd_tfm = cryptd_alloc_ablkcipher(drv_name, 0, 0); | ||
| 451 | if (IS_ERR(cryptd_tfm)) | ||
| 452 | return PTR_ERR(cryptd_tfm); | ||
| 453 | |||
| 454 | ctx->cryptd_tfm = cryptd_tfm; | ||
| 455 | tfm->crt_ablkcipher.reqsize = sizeof(struct ablkcipher_request) + | ||
| 456 | crypto_ablkcipher_reqsize(&cryptd_tfm->base); | ||
| 457 | |||
| 458 | return 0; | ||
| 459 | } | ||
| 460 | |||
| 461 | static int ablk_ecb_init(struct crypto_tfm *tfm) | 377 | static int ablk_ecb_init(struct crypto_tfm *tfm) |
| 462 | { | 378 | { |
| 463 | return ablk_init_common(tfm, "__driver-ecb-aes-aesni"); | 379 | return ablk_init_common(tfm, "__driver-ecb-aes-aesni"); |
| @@ -613,7 +529,7 @@ static int rfc4106_set_key(struct crypto_aead *parent, const u8 *key, | |||
| 613 | struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm); | 529 | struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm); |
| 614 | struct aesni_rfc4106_gcm_ctx *child_ctx = | 530 | struct aesni_rfc4106_gcm_ctx *child_ctx = |
| 615 | aesni_rfc4106_gcm_ctx_get(cryptd_child); | 531 | aesni_rfc4106_gcm_ctx_get(cryptd_child); |
| 616 | u8 *new_key_mem = NULL; | 532 | u8 *new_key_align, *new_key_mem = NULL; |
| 617 | 533 | ||
| 618 | if (key_len < 4) { | 534 | if (key_len < 4) { |
| 619 | crypto_tfm_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); | 535 | crypto_tfm_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); |
| @@ -637,9 +553,9 @@ static int rfc4106_set_key(struct crypto_aead *parent, const u8 *key, | |||
| 637 | if (!new_key_mem) | 553 | if (!new_key_mem) |
| 638 | return -ENOMEM; | 554 | return -ENOMEM; |
| 639 | 555 | ||
| 640 | new_key_mem = PTR_ALIGN(new_key_mem, AESNI_ALIGN); | 556 | new_key_align = PTR_ALIGN(new_key_mem, AESNI_ALIGN); |
| 641 | memcpy(new_key_mem, key, key_len); | 557 | memcpy(new_key_align, key, key_len); |
| 642 | key = new_key_mem; | 558 | key = new_key_align; |
| 643 | } | 559 | } |
| 644 | 560 | ||
| 645 | if (!irq_fpu_usable()) | 561 | if (!irq_fpu_usable()) |
| @@ -968,7 +884,7 @@ static struct crypto_alg aesni_algs[] = { { | |||
| 968 | .cra_priority = 400, | 884 | .cra_priority = 400, |
| 969 | .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, | 885 | .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, |
| 970 | .cra_blocksize = AES_BLOCK_SIZE, | 886 | .cra_blocksize = AES_BLOCK_SIZE, |
| 971 | .cra_ctxsize = sizeof(struct async_aes_ctx), | 887 | .cra_ctxsize = sizeof(struct async_helper_ctx), |
| 972 | .cra_alignmask = 0, | 888 | .cra_alignmask = 0, |
| 973 | .cra_type = &crypto_ablkcipher_type, | 889 | .cra_type = &crypto_ablkcipher_type, |
| 974 | .cra_module = THIS_MODULE, | 890 | .cra_module = THIS_MODULE, |
| @@ -989,7 +905,7 @@ static struct crypto_alg aesni_algs[] = { { | |||
| 989 | .cra_priority = 400, | 905 | .cra_priority = 400, |
| 990 | .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, | 906 | .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, |
| 991 | .cra_blocksize = AES_BLOCK_SIZE, | 907 | .cra_blocksize = AES_BLOCK_SIZE, |
| 992 | .cra_ctxsize = sizeof(struct async_aes_ctx), | 908 | .cra_ctxsize = sizeof(struct async_helper_ctx), |
| 993 | .cra_alignmask = 0, | 909 | .cra_alignmask = 0, |
| 994 | .cra_type = &crypto_ablkcipher_type, | 910 | .cra_type = &crypto_ablkcipher_type, |
| 995 | .cra_module = THIS_MODULE, | 911 | .cra_module = THIS_MODULE, |
| @@ -1033,7 +949,7 @@ static struct crypto_alg aesni_algs[] = { { | |||
| 1033 | .cra_priority = 400, | 949 | .cra_priority = 400, |
| 1034 | .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, | 950 | .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, |
| 1035 | .cra_blocksize = 1, | 951 | .cra_blocksize = 1, |
| 1036 | .cra_ctxsize = sizeof(struct async_aes_ctx), | 952 | .cra_ctxsize = sizeof(struct async_helper_ctx), |
| 1037 | .cra_alignmask = 0, | 953 | .cra_alignmask = 0, |
| 1038 | .cra_type = &crypto_ablkcipher_type, | 954 | .cra_type = &crypto_ablkcipher_type, |
| 1039 | .cra_module = THIS_MODULE, | 955 | .cra_module = THIS_MODULE, |
| @@ -1098,7 +1014,7 @@ static struct crypto_alg aesni_algs[] = { { | |||
| 1098 | .cra_priority = 400, | 1014 | .cra_priority = 400, |
| 1099 | .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, | 1015 | .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, |
| 1100 | .cra_blocksize = 1, | 1016 | .cra_blocksize = 1, |
| 1101 | .cra_ctxsize = sizeof(struct async_aes_ctx), | 1017 | .cra_ctxsize = sizeof(struct async_helper_ctx), |
| 1102 | .cra_alignmask = 0, | 1018 | .cra_alignmask = 0, |
| 1103 | .cra_type = &crypto_ablkcipher_type, | 1019 | .cra_type = &crypto_ablkcipher_type, |
| 1104 | .cra_module = THIS_MODULE, | 1020 | .cra_module = THIS_MODULE, |
| @@ -1126,7 +1042,7 @@ static struct crypto_alg aesni_algs[] = { { | |||
| 1126 | .cra_priority = 400, | 1042 | .cra_priority = 400, |
| 1127 | .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, | 1043 | .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, |
| 1128 | .cra_blocksize = AES_BLOCK_SIZE, | 1044 | .cra_blocksize = AES_BLOCK_SIZE, |
| 1129 | .cra_ctxsize = sizeof(struct async_aes_ctx), | 1045 | .cra_ctxsize = sizeof(struct async_helper_ctx), |
| 1130 | .cra_alignmask = 0, | 1046 | .cra_alignmask = 0, |
| 1131 | .cra_type = &crypto_ablkcipher_type, | 1047 | .cra_type = &crypto_ablkcipher_type, |
| 1132 | .cra_module = THIS_MODULE, | 1048 | .cra_module = THIS_MODULE, |
| @@ -1150,7 +1066,7 @@ static struct crypto_alg aesni_algs[] = { { | |||
| 1150 | .cra_priority = 400, | 1066 | .cra_priority = 400, |
| 1151 | .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, | 1067 | .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, |
| 1152 | .cra_blocksize = AES_BLOCK_SIZE, | 1068 | .cra_blocksize = AES_BLOCK_SIZE, |
| 1153 | .cra_ctxsize = sizeof(struct async_aes_ctx), | 1069 | .cra_ctxsize = sizeof(struct async_helper_ctx), |
| 1154 | .cra_alignmask = 0, | 1070 | .cra_alignmask = 0, |
| 1155 | .cra_type = &crypto_ablkcipher_type, | 1071 | .cra_type = &crypto_ablkcipher_type, |
| 1156 | .cra_module = THIS_MODULE, | 1072 | .cra_module = THIS_MODULE, |
| @@ -1174,7 +1090,7 @@ static struct crypto_alg aesni_algs[] = { { | |||
| 1174 | .cra_priority = 400, | 1090 | .cra_priority = 400, |
| 1175 | .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, | 1091 | .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, |
| 1176 | .cra_blocksize = AES_BLOCK_SIZE, | 1092 | .cra_blocksize = AES_BLOCK_SIZE, |
| 1177 | .cra_ctxsize = sizeof(struct async_aes_ctx), | 1093 | .cra_ctxsize = sizeof(struct async_helper_ctx), |
| 1178 | .cra_alignmask = 0, | 1094 | .cra_alignmask = 0, |
| 1179 | .cra_type = &crypto_ablkcipher_type, | 1095 | .cra_type = &crypto_ablkcipher_type, |
| 1180 | .cra_module = THIS_MODULE, | 1096 | .cra_module = THIS_MODULE, |
diff --git a/arch/x86/crypto/camellia_glue.c b/arch/x86/crypto/camellia_glue.c index 3306dc0b139e..eeb2b3b743e9 100644 --- a/arch/x86/crypto/camellia_glue.c +++ b/arch/x86/crypto/camellia_glue.c | |||
| @@ -5,10 +5,6 @@ | |||
| 5 | * | 5 | * |
| 6 | * Camellia parts based on code by: | 6 | * Camellia parts based on code by: |
| 7 | * Copyright (C) 2006 NTT (Nippon Telegraph and Telephone Corporation) | 7 | * Copyright (C) 2006 NTT (Nippon Telegraph and Telephone Corporation) |
| 8 | * CBC & ECB parts based on code (crypto/cbc.c,ecb.c) by: | ||
| 9 | * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au> | ||
| 10 | * CTR part based on code (crypto/ctr.c) by: | ||
| 11 | * (C) Copyright IBM Corp. 2007 - Joy Latten <latten@us.ibm.com> | ||
| 12 | * | 8 | * |
| 13 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
| 14 | * it under the terms of the GNU General Public License as published by | 10 | * it under the terms of the GNU General Public License as published by |
| @@ -34,9 +30,9 @@ | |||
| 34 | #include <linux/module.h> | 30 | #include <linux/module.h> |
| 35 | #include <linux/types.h> | 31 | #include <linux/types.h> |
| 36 | #include <crypto/algapi.h> | 32 | #include <crypto/algapi.h> |
| 37 | #include <crypto/b128ops.h> | ||
| 38 | #include <crypto/lrw.h> | 33 | #include <crypto/lrw.h> |
| 39 | #include <crypto/xts.h> | 34 | #include <crypto/xts.h> |
| 35 | #include <asm/crypto/glue_helper.h> | ||
| 40 | 36 | ||
| 41 | #define CAMELLIA_MIN_KEY_SIZE 16 | 37 | #define CAMELLIA_MIN_KEY_SIZE 16 |
| 42 | #define CAMELLIA_MAX_KEY_SIZE 32 | 38 | #define CAMELLIA_MAX_KEY_SIZE 32 |
| @@ -1312,307 +1308,128 @@ static int camellia_setkey(struct crypto_tfm *tfm, const u8 *in_key, | |||
| 1312 | &tfm->crt_flags); | 1308 | &tfm->crt_flags); |
| 1313 | } | 1309 | } |
| 1314 | 1310 | ||
| 1315 | static int ecb_crypt(struct blkcipher_desc *desc, struct blkcipher_walk *walk, | 1311 | static void camellia_decrypt_cbc_2way(void *ctx, u128 *dst, const u128 *src) |
| 1316 | void (*fn)(struct camellia_ctx *, u8 *, const u8 *), | ||
| 1317 | void (*fn_2way)(struct camellia_ctx *, u8 *, const u8 *)) | ||
| 1318 | { | 1312 | { |
| 1319 | struct camellia_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | 1313 | u128 iv = *src; |
| 1320 | unsigned int bsize = CAMELLIA_BLOCK_SIZE; | ||
| 1321 | unsigned int nbytes; | ||
| 1322 | int err; | ||
| 1323 | |||
| 1324 | err = blkcipher_walk_virt(desc, walk); | ||
| 1325 | |||
| 1326 | while ((nbytes = walk->nbytes)) { | ||
| 1327 | u8 *wsrc = walk->src.virt.addr; | ||
| 1328 | u8 *wdst = walk->dst.virt.addr; | ||
| 1329 | |||
| 1330 | /* Process two block batch */ | ||
| 1331 | if (nbytes >= bsize * 2) { | ||
| 1332 | do { | ||
| 1333 | fn_2way(ctx, wdst, wsrc); | ||
| 1334 | |||
| 1335 | wsrc += bsize * 2; | ||
| 1336 | wdst += bsize * 2; | ||
| 1337 | nbytes -= bsize * 2; | ||
| 1338 | } while (nbytes >= bsize * 2); | ||
| 1339 | |||
| 1340 | if (nbytes < bsize) | ||
| 1341 | goto done; | ||
| 1342 | } | ||
| 1343 | |||
| 1344 | /* Handle leftovers */ | ||
| 1345 | do { | ||
| 1346 | fn(ctx, wdst, wsrc); | ||
| 1347 | |||
| 1348 | wsrc += bsize; | ||
| 1349 | wdst += bsize; | ||
| 1350 | nbytes -= bsize; | ||
| 1351 | } while (nbytes >= bsize); | ||
| 1352 | |||
| 1353 | done: | ||
| 1354 | err = blkcipher_walk_done(desc, walk, nbytes); | ||
| 1355 | } | ||
| 1356 | |||
| 1357 | return err; | ||
| 1358 | } | ||
| 1359 | |||
| 1360 | static int ecb_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | ||
| 1361 | struct scatterlist *src, unsigned int nbytes) | ||
| 1362 | { | ||
| 1363 | struct blkcipher_walk walk; | ||
| 1364 | |||
| 1365 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
| 1366 | return ecb_crypt(desc, &walk, camellia_enc_blk, camellia_enc_blk_2way); | ||
| 1367 | } | ||
| 1368 | 1314 | ||
| 1369 | static int ecb_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | 1315 | camellia_dec_blk_2way(ctx, (u8 *)dst, (u8 *)src); |
| 1370 | struct scatterlist *src, unsigned int nbytes) | ||
| 1371 | { | ||
| 1372 | struct blkcipher_walk walk; | ||
| 1373 | |||
| 1374 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
| 1375 | return ecb_crypt(desc, &walk, camellia_dec_blk, camellia_dec_blk_2way); | ||
| 1376 | } | ||
| 1377 | 1316 | ||
| 1378 | static unsigned int __cbc_encrypt(struct blkcipher_desc *desc, | 1317 | u128_xor(&dst[1], &dst[1], &iv); |
| 1379 | struct blkcipher_walk *walk) | ||
| 1380 | { | ||
| 1381 | struct camellia_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
| 1382 | unsigned int bsize = CAMELLIA_BLOCK_SIZE; | ||
| 1383 | unsigned int nbytes = walk->nbytes; | ||
| 1384 | u128 *src = (u128 *)walk->src.virt.addr; | ||
| 1385 | u128 *dst = (u128 *)walk->dst.virt.addr; | ||
| 1386 | u128 *iv = (u128 *)walk->iv; | ||
| 1387 | |||
| 1388 | do { | ||
| 1389 | u128_xor(dst, src, iv); | ||
| 1390 | camellia_enc_blk(ctx, (u8 *)dst, (u8 *)dst); | ||
| 1391 | iv = dst; | ||
| 1392 | |||
| 1393 | src += 1; | ||
| 1394 | dst += 1; | ||
| 1395 | nbytes -= bsize; | ||
| 1396 | } while (nbytes >= bsize); | ||
| 1397 | |||
| 1398 | u128_xor((u128 *)walk->iv, (u128 *)walk->iv, iv); | ||
| 1399 | return nbytes; | ||
| 1400 | } | 1318 | } |
| 1401 | 1319 | ||
| 1402 | static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | 1320 | static void camellia_crypt_ctr(void *ctx, u128 *dst, const u128 *src, u128 *iv) |
| 1403 | struct scatterlist *src, unsigned int nbytes) | ||
| 1404 | { | 1321 | { |
| 1405 | struct blkcipher_walk walk; | 1322 | be128 ctrblk; |
| 1406 | int err; | ||
| 1407 | 1323 | ||
| 1408 | blkcipher_walk_init(&walk, dst, src, nbytes); | 1324 | if (dst != src) |
| 1409 | err = blkcipher_walk_virt(desc, &walk); | 1325 | *dst = *src; |
| 1410 | 1326 | ||
| 1411 | while ((nbytes = walk.nbytes)) { | 1327 | u128_to_be128(&ctrblk, iv); |
| 1412 | nbytes = __cbc_encrypt(desc, &walk); | 1328 | u128_inc(iv); |
| 1413 | err = blkcipher_walk_done(desc, &walk, nbytes); | ||
| 1414 | } | ||
| 1415 | 1329 | ||
| 1416 | return err; | 1330 | camellia_enc_blk_xor(ctx, (u8 *)dst, (u8 *)&ctrblk); |
| 1417 | } | 1331 | } |
| 1418 | 1332 | ||
| 1419 | static unsigned int __cbc_decrypt(struct blkcipher_desc *desc, | 1333 | static void camellia_crypt_ctr_2way(void *ctx, u128 *dst, const u128 *src, |
| 1420 | struct blkcipher_walk *walk) | 1334 | u128 *iv) |
| 1421 | { | 1335 | { |
| 1422 | struct camellia_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | 1336 | be128 ctrblks[2]; |
| 1423 | unsigned int bsize = CAMELLIA_BLOCK_SIZE; | ||
| 1424 | unsigned int nbytes = walk->nbytes; | ||
| 1425 | u128 *src = (u128 *)walk->src.virt.addr; | ||
| 1426 | u128 *dst = (u128 *)walk->dst.virt.addr; | ||
| 1427 | u128 ivs[2 - 1]; | ||
| 1428 | u128 last_iv; | ||
| 1429 | 1337 | ||
| 1430 | /* Start of the last block. */ | 1338 | if (dst != src) { |
| 1431 | src += nbytes / bsize - 1; | 1339 | dst[0] = src[0]; |
| 1432 | dst += nbytes / bsize - 1; | 1340 | dst[1] = src[1]; |
| 1433 | |||
| 1434 | last_iv = *src; | ||
| 1435 | |||
| 1436 | /* Process two block batch */ | ||
| 1437 | if (nbytes >= bsize * 2) { | ||
| 1438 | do { | ||
| 1439 | nbytes -= bsize * (2 - 1); | ||
| 1440 | src -= 2 - 1; | ||
| 1441 | dst -= 2 - 1; | ||
| 1442 | |||
| 1443 | ivs[0] = src[0]; | ||
| 1444 | |||
| 1445 | camellia_dec_blk_2way(ctx, (u8 *)dst, (u8 *)src); | ||
| 1446 | |||
| 1447 | u128_xor(dst + 1, dst + 1, ivs + 0); | ||
| 1448 | |||
| 1449 | nbytes -= bsize; | ||
| 1450 | if (nbytes < bsize) | ||
| 1451 | goto done; | ||
| 1452 | |||
| 1453 | u128_xor(dst, dst, src - 1); | ||
| 1454 | src -= 1; | ||
| 1455 | dst -= 1; | ||
| 1456 | } while (nbytes >= bsize * 2); | ||
| 1457 | |||
| 1458 | if (nbytes < bsize) | ||
| 1459 | goto done; | ||
| 1460 | } | 1341 | } |
| 1461 | 1342 | ||
| 1462 | /* Handle leftovers */ | 1343 | u128_to_be128(&ctrblks[0], iv); |
| 1463 | for (;;) { | 1344 | u128_inc(iv); |
| 1464 | camellia_dec_blk(ctx, (u8 *)dst, (u8 *)src); | 1345 | u128_to_be128(&ctrblks[1], iv); |
| 1465 | 1346 | u128_inc(iv); | |
| 1466 | nbytes -= bsize; | ||
| 1467 | if (nbytes < bsize) | ||
| 1468 | break; | ||
| 1469 | 1347 | ||
| 1470 | u128_xor(dst, dst, src - 1); | 1348 | camellia_enc_blk_xor_2way(ctx, (u8 *)dst, (u8 *)ctrblks); |
| 1471 | src -= 1; | ||
| 1472 | dst -= 1; | ||
| 1473 | } | ||
| 1474 | |||
| 1475 | done: | ||
| 1476 | u128_xor(dst, dst, (u128 *)walk->iv); | ||
| 1477 | *(u128 *)walk->iv = last_iv; | ||
| 1478 | |||
| 1479 | return nbytes; | ||
| 1480 | } | 1349 | } |
| 1481 | 1350 | ||
| 1482 | static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | 1351 | static const struct common_glue_ctx camellia_enc = { |
| 1483 | struct scatterlist *src, unsigned int nbytes) | 1352 | .num_funcs = 2, |
| 1484 | { | 1353 | .fpu_blocks_limit = -1, |
| 1485 | struct blkcipher_walk walk; | 1354 | |
| 1486 | int err; | 1355 | .funcs = { { |
| 1487 | 1356 | .num_blocks = 2, | |
| 1488 | blkcipher_walk_init(&walk, dst, src, nbytes); | 1357 | .fn_u = { .ecb = GLUE_FUNC_CAST(camellia_enc_blk_2way) } |
| 1489 | err = blkcipher_walk_virt(desc, &walk); | 1358 | }, { |
| 1359 | .num_blocks = 1, | ||
| 1360 | .fn_u = { .ecb = GLUE_FUNC_CAST(camellia_enc_blk) } | ||
| 1361 | } } | ||
| 1362 | }; | ||
| 1490 | 1363 | ||
| 1491 | while ((nbytes = walk.nbytes)) { | 1364 | static const struct common_glue_ctx camellia_ctr = { |
| 1492 | nbytes = __cbc_decrypt(desc, &walk); | 1365 | .num_funcs = 2, |
| 1493 | err = blkcipher_walk_done(desc, &walk, nbytes); | 1366 | .fpu_blocks_limit = -1, |
| 1494 | } | 1367 | |
| 1368 | .funcs = { { | ||
| 1369 | .num_blocks = 2, | ||
| 1370 | .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(camellia_crypt_ctr_2way) } | ||
| 1371 | }, { | ||
| 1372 | .num_blocks = 1, | ||
| 1373 | .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(camellia_crypt_ctr) } | ||
| 1374 | } } | ||
| 1375 | }; | ||
| 1495 | 1376 | ||
| 1496 | return err; | 1377 | static const struct common_glue_ctx camellia_dec = { |
| 1497 | } | 1378 | .num_funcs = 2, |
| 1379 | .fpu_blocks_limit = -1, | ||
| 1380 | |||
| 1381 | .funcs = { { | ||
| 1382 | .num_blocks = 2, | ||
| 1383 | .fn_u = { .ecb = GLUE_FUNC_CAST(camellia_dec_blk_2way) } | ||
| 1384 | }, { | ||
| 1385 | .num_blocks = 1, | ||
| 1386 | .fn_u = { .ecb = GLUE_FUNC_CAST(camellia_dec_blk) } | ||
| 1387 | } } | ||
| 1388 | }; | ||
| 1498 | 1389 | ||
| 1499 | static inline void u128_to_be128(be128 *dst, const u128 *src) | 1390 | static const struct common_glue_ctx camellia_dec_cbc = { |
| 1500 | { | 1391 | .num_funcs = 2, |
| 1501 | dst->a = cpu_to_be64(src->a); | 1392 | .fpu_blocks_limit = -1, |
| 1502 | dst->b = cpu_to_be64(src->b); | 1393 | |
| 1503 | } | 1394 | .funcs = { { |
| 1395 | .num_blocks = 2, | ||
| 1396 | .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(camellia_decrypt_cbc_2way) } | ||
| 1397 | }, { | ||
| 1398 | .num_blocks = 1, | ||
| 1399 | .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(camellia_dec_blk) } | ||
| 1400 | } } | ||
| 1401 | }; | ||
| 1504 | 1402 | ||
| 1505 | static inline void be128_to_u128(u128 *dst, const be128 *src) | 1403 | static int ecb_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, |
| 1404 | struct scatterlist *src, unsigned int nbytes) | ||
| 1506 | { | 1405 | { |
| 1507 | dst->a = be64_to_cpu(src->a); | 1406 | return glue_ecb_crypt_128bit(&camellia_enc, desc, dst, src, nbytes); |
| 1508 | dst->b = be64_to_cpu(src->b); | ||
| 1509 | } | 1407 | } |
| 1510 | 1408 | ||
| 1511 | static inline void u128_inc(u128 *i) | 1409 | static int ecb_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, |
| 1410 | struct scatterlist *src, unsigned int nbytes) | ||
| 1512 | { | 1411 | { |
| 1513 | i->b++; | 1412 | return glue_ecb_crypt_128bit(&camellia_dec, desc, dst, src, nbytes); |
| 1514 | if (!i->b) | ||
| 1515 | i->a++; | ||
| 1516 | } | 1413 | } |
| 1517 | 1414 | ||
| 1518 | static void ctr_crypt_final(struct blkcipher_desc *desc, | 1415 | static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, |
| 1519 | struct blkcipher_walk *walk) | 1416 | struct scatterlist *src, unsigned int nbytes) |
| 1520 | { | 1417 | { |
| 1521 | struct camellia_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | 1418 | return glue_cbc_encrypt_128bit(GLUE_FUNC_CAST(camellia_enc_blk), desc, |
| 1522 | u8 keystream[CAMELLIA_BLOCK_SIZE]; | 1419 | dst, src, nbytes); |
| 1523 | u8 *src = walk->src.virt.addr; | ||
| 1524 | u8 *dst = walk->dst.virt.addr; | ||
| 1525 | unsigned int nbytes = walk->nbytes; | ||
| 1526 | u128 ctrblk; | ||
| 1527 | |||
| 1528 | memcpy(keystream, src, nbytes); | ||
| 1529 | camellia_enc_blk_xor(ctx, keystream, walk->iv); | ||
| 1530 | memcpy(dst, keystream, nbytes); | ||
| 1531 | |||
| 1532 | be128_to_u128(&ctrblk, (be128 *)walk->iv); | ||
| 1533 | u128_inc(&ctrblk); | ||
| 1534 | u128_to_be128((be128 *)walk->iv, &ctrblk); | ||
| 1535 | } | 1420 | } |
| 1536 | 1421 | ||
| 1537 | static unsigned int __ctr_crypt(struct blkcipher_desc *desc, | 1422 | static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, |
| 1538 | struct blkcipher_walk *walk) | 1423 | struct scatterlist *src, unsigned int nbytes) |
| 1539 | { | 1424 | { |
| 1540 | struct camellia_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | 1425 | return glue_cbc_decrypt_128bit(&camellia_dec_cbc, desc, dst, src, |
| 1541 | unsigned int bsize = CAMELLIA_BLOCK_SIZE; | 1426 | nbytes); |
| 1542 | unsigned int nbytes = walk->nbytes; | ||
| 1543 | u128 *src = (u128 *)walk->src.virt.addr; | ||
| 1544 | u128 *dst = (u128 *)walk->dst.virt.addr; | ||
| 1545 | u128 ctrblk; | ||
| 1546 | be128 ctrblocks[2]; | ||
| 1547 | |||
| 1548 | be128_to_u128(&ctrblk, (be128 *)walk->iv); | ||
| 1549 | |||
| 1550 | /* Process two block batch */ | ||
| 1551 | if (nbytes >= bsize * 2) { | ||
| 1552 | do { | ||
| 1553 | if (dst != src) { | ||
| 1554 | dst[0] = src[0]; | ||
| 1555 | dst[1] = src[1]; | ||
| 1556 | } | ||
| 1557 | |||
| 1558 | /* create ctrblks for parallel encrypt */ | ||
| 1559 | u128_to_be128(&ctrblocks[0], &ctrblk); | ||
| 1560 | u128_inc(&ctrblk); | ||
| 1561 | u128_to_be128(&ctrblocks[1], &ctrblk); | ||
| 1562 | u128_inc(&ctrblk); | ||
| 1563 | |||
| 1564 | camellia_enc_blk_xor_2way(ctx, (u8 *)dst, | ||
| 1565 | (u8 *)ctrblocks); | ||
| 1566 | |||
| 1567 | src += 2; | ||
| 1568 | dst += 2; | ||
| 1569 | nbytes -= bsize * 2; | ||
| 1570 | } while (nbytes >= bsize * 2); | ||
| 1571 | |||
| 1572 | if (nbytes < bsize) | ||
| 1573 | goto done; | ||
| 1574 | } | ||
| 1575 | |||
| 1576 | /* Handle leftovers */ | ||
| 1577 | do { | ||
| 1578 | if (dst != src) | ||
| 1579 | *dst = *src; | ||
| 1580 | |||
| 1581 | u128_to_be128(&ctrblocks[0], &ctrblk); | ||
| 1582 | u128_inc(&ctrblk); | ||
| 1583 | |||
| 1584 | camellia_enc_blk_xor(ctx, (u8 *)dst, (u8 *)ctrblocks); | ||
| 1585 | |||
| 1586 | src += 1; | ||
| 1587 | dst += 1; | ||
| 1588 | nbytes -= bsize; | ||
| 1589 | } while (nbytes >= bsize); | ||
| 1590 | |||
| 1591 | done: | ||
| 1592 | u128_to_be128((be128 *)walk->iv, &ctrblk); | ||
| 1593 | return nbytes; | ||
| 1594 | } | 1427 | } |
| 1595 | 1428 | ||
| 1596 | static int ctr_crypt(struct blkcipher_desc *desc, struct scatterlist *dst, | 1429 | static int ctr_crypt(struct blkcipher_desc *desc, struct scatterlist *dst, |
| 1597 | struct scatterlist *src, unsigned int nbytes) | 1430 | struct scatterlist *src, unsigned int nbytes) |
| 1598 | { | 1431 | { |
| 1599 | struct blkcipher_walk walk; | 1432 | return glue_ctr_crypt_128bit(&camellia_ctr, desc, dst, src, nbytes); |
| 1600 | int err; | ||
| 1601 | |||
| 1602 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
| 1603 | err = blkcipher_walk_virt_block(desc, &walk, CAMELLIA_BLOCK_SIZE); | ||
| 1604 | |||
| 1605 | while ((nbytes = walk.nbytes) >= CAMELLIA_BLOCK_SIZE) { | ||
| 1606 | nbytes = __ctr_crypt(desc, &walk); | ||
| 1607 | err = blkcipher_walk_done(desc, &walk, nbytes); | ||
| 1608 | } | ||
| 1609 | |||
| 1610 | if (walk.nbytes) { | ||
| 1611 | ctr_crypt_final(desc, &walk); | ||
| 1612 | err = blkcipher_walk_done(desc, &walk, 0); | ||
| 1613 | } | ||
| 1614 | |||
| 1615 | return err; | ||
| 1616 | } | 1433 | } |
| 1617 | 1434 | ||
| 1618 | static void encrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) | 1435 | static void encrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) |
diff --git a/arch/x86/crypto/glue_helper.c b/arch/x86/crypto/glue_helper.c new file mode 100644 index 000000000000..4854f0f31e4f --- /dev/null +++ b/arch/x86/crypto/glue_helper.c | |||
| @@ -0,0 +1,307 @@ | |||
| 1 | /* | ||
| 2 | * Shared glue code for 128bit block ciphers | ||
| 3 | * | ||
| 4 | * Copyright (c) 2012 Jussi Kivilinna <jussi.kivilinna@mbnet.fi> | ||
| 5 | * | ||
| 6 | * CBC & ECB parts based on code (crypto/cbc.c,ecb.c) by: | ||
| 7 | * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au> | ||
| 8 | * CTR part based on code (crypto/ctr.c) by: | ||
| 9 | * (C) Copyright IBM Corp. 2007 - Joy Latten <latten@us.ibm.com> | ||
| 10 | * | ||
| 11 | * This program is free software; you can redistribute it and/or modify | ||
| 12 | * it under the terms of the GNU General Public License as published by | ||
| 13 | * the Free Software Foundation; either version 2 of the License, or | ||
| 14 | * (at your option) any later version. | ||
| 15 | * | ||
| 16 | * This program is distributed in the hope that it will be useful, | ||
| 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 19 | * GNU General Public License for more details. | ||
| 20 | * | ||
| 21 | * You should have received a copy of the GNU General Public License | ||
| 22 | * along with this program; if not, write to the Free Software | ||
| 23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | ||
| 24 | * USA | ||
| 25 | * | ||
| 26 | */ | ||
| 27 | |||
| 28 | #include <linux/module.h> | ||
| 29 | #include <crypto/b128ops.h> | ||
| 30 | #include <crypto/lrw.h> | ||
| 31 | #include <crypto/xts.h> | ||
| 32 | #include <asm/crypto/glue_helper.h> | ||
| 33 | #include <crypto/scatterwalk.h> | ||
| 34 | |||
| 35 | static int __glue_ecb_crypt_128bit(const struct common_glue_ctx *gctx, | ||
| 36 | struct blkcipher_desc *desc, | ||
| 37 | struct blkcipher_walk *walk) | ||
| 38 | { | ||
| 39 | void *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
| 40 | const unsigned int bsize = 128 / 8; | ||
| 41 | unsigned int nbytes, i, func_bytes; | ||
| 42 | bool fpu_enabled = false; | ||
| 43 | int err; | ||
| 44 | |||
| 45 | err = blkcipher_walk_virt(desc, walk); | ||
| 46 | |||
| 47 | while ((nbytes = walk->nbytes)) { | ||
| 48 | u8 *wsrc = walk->src.virt.addr; | ||
| 49 | u8 *wdst = walk->dst.virt.addr; | ||
| 50 | |||
| 51 | fpu_enabled = glue_fpu_begin(bsize, gctx->fpu_blocks_limit, | ||
| 52 | desc, fpu_enabled, nbytes); | ||
| 53 | |||
| 54 | for (i = 0; i < gctx->num_funcs; i++) { | ||
| 55 | func_bytes = bsize * gctx->funcs[i].num_blocks; | ||
| 56 | |||
| 57 | /* Process multi-block batch */ | ||
| 58 | if (nbytes >= func_bytes) { | ||
| 59 | do { | ||
| 60 | gctx->funcs[i].fn_u.ecb(ctx, wdst, | ||
| 61 | wsrc); | ||
| 62 | |||
| 63 | wsrc += func_bytes; | ||
| 64 | wdst += func_bytes; | ||
| 65 | nbytes -= func_bytes; | ||
| 66 | } while (nbytes >= func_bytes); | ||
| 67 | |||
| 68 | if (nbytes < bsize) | ||
| 69 | goto done; | ||
| 70 | } | ||
| 71 | } | ||
| 72 | |||
| 73 | done: | ||
| 74 | err = blkcipher_walk_done(desc, walk, nbytes); | ||
| 75 | } | ||
| 76 | |||
| 77 | glue_fpu_end(fpu_enabled); | ||
| 78 | return err; | ||
| 79 | } | ||
| 80 | |||
| 81 | int glue_ecb_crypt_128bit(const struct common_glue_ctx *gctx, | ||
| 82 | struct blkcipher_desc *desc, struct scatterlist *dst, | ||
| 83 | struct scatterlist *src, unsigned int nbytes) | ||
| 84 | { | ||
| 85 | struct blkcipher_walk walk; | ||
| 86 | |||
| 87 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
| 88 | return __glue_ecb_crypt_128bit(gctx, desc, &walk); | ||
| 89 | } | ||
| 90 | EXPORT_SYMBOL_GPL(glue_ecb_crypt_128bit); | ||
| 91 | |||
| 92 | static unsigned int __glue_cbc_encrypt_128bit(const common_glue_func_t fn, | ||
| 93 | struct blkcipher_desc *desc, | ||
| 94 | struct blkcipher_walk *walk) | ||
| 95 | { | ||
| 96 | void *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
| 97 | const unsigned int bsize = 128 / 8; | ||
| 98 | unsigned int nbytes = walk->nbytes; | ||
| 99 | u128 *src = (u128 *)walk->src.virt.addr; | ||
| 100 | u128 *dst = (u128 *)walk->dst.virt.addr; | ||
| 101 | u128 *iv = (u128 *)walk->iv; | ||
| 102 | |||
| 103 | do { | ||
| 104 | u128_xor(dst, src, iv); | ||
| 105 | fn(ctx, (u8 *)dst, (u8 *)dst); | ||
| 106 | iv = dst; | ||
| 107 | |||
| 108 | src += 1; | ||
| 109 | dst += 1; | ||
| 110 | nbytes -= bsize; | ||
| 111 | } while (nbytes >= bsize); | ||
| 112 | |||
| 113 | u128_xor((u128 *)walk->iv, (u128 *)walk->iv, iv); | ||
| 114 | return nbytes; | ||
| 115 | } | ||
| 116 | |||
| 117 | int glue_cbc_encrypt_128bit(const common_glue_func_t fn, | ||
| 118 | struct blkcipher_desc *desc, | ||
| 119 | struct scatterlist *dst, | ||
| 120 | struct scatterlist *src, unsigned int nbytes) | ||
| 121 | { | ||
| 122 | struct blkcipher_walk walk; | ||
| 123 | int err; | ||
| 124 | |||
| 125 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
| 126 | err = blkcipher_walk_virt(desc, &walk); | ||
| 127 | |||
| 128 | while ((nbytes = walk.nbytes)) { | ||
| 129 | nbytes = __glue_cbc_encrypt_128bit(fn, desc, &walk); | ||
| 130 | err = blkcipher_walk_done(desc, &walk, nbytes); | ||
| 131 | } | ||
| 132 | |||
| 133 | return err; | ||
| 134 | } | ||
| 135 | EXPORT_SYMBOL_GPL(glue_cbc_encrypt_128bit); | ||
| 136 | |||
| 137 | static unsigned int | ||
| 138 | __glue_cbc_decrypt_128bit(const struct common_glue_ctx *gctx, | ||
| 139 | struct blkcipher_desc *desc, | ||
| 140 | struct blkcipher_walk *walk) | ||
| 141 | { | ||
| 142 | void *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
| 143 | const unsigned int bsize = 128 / 8; | ||
| 144 | unsigned int nbytes = walk->nbytes; | ||
| 145 | u128 *src = (u128 *)walk->src.virt.addr; | ||
| 146 | u128 *dst = (u128 *)walk->dst.virt.addr; | ||
| 147 | u128 last_iv; | ||
| 148 | unsigned int num_blocks, func_bytes; | ||
| 149 | unsigned int i; | ||
| 150 | |||
| 151 | /* Start of the last block. */ | ||
| 152 | src += nbytes / bsize - 1; | ||
| 153 | dst += nbytes / bsize - 1; | ||
| 154 | |||
| 155 | last_iv = *src; | ||
| 156 | |||
| 157 | for (i = 0; i < gctx->num_funcs; i++) { | ||
| 158 | num_blocks = gctx->funcs[i].num_blocks; | ||
| 159 | func_bytes = bsize * num_blocks; | ||
| 160 | |||
| 161 | /* Process multi-block batch */ | ||
| 162 | if (nbytes >= func_bytes) { | ||
| 163 | do { | ||
| 164 | nbytes -= func_bytes - bsize; | ||
| 165 | src -= num_blocks - 1; | ||
| 166 | dst -= num_blocks - 1; | ||
| 167 | |||
| 168 | gctx->funcs[i].fn_u.cbc(ctx, dst, src); | ||
| 169 | |||
| 170 | nbytes -= bsize; | ||
| 171 | if (nbytes < bsize) | ||
| 172 | goto done; | ||
| 173 | |||
| 174 | u128_xor(dst, dst, src - 1); | ||
| 175 | src -= 1; | ||
| 176 | dst -= 1; | ||
| 177 | } while (nbytes >= func_bytes); | ||
| 178 | |||
| 179 | if (nbytes < bsize) | ||
| 180 | goto done; | ||
| 181 | } | ||
| 182 | } | ||
| 183 | |||
| 184 | done: | ||
| 185 | u128_xor(dst, dst, (u128 *)walk->iv); | ||
| 186 | *(u128 *)walk->iv = last_iv; | ||
| 187 | |||
| 188 | return nbytes; | ||
| 189 | } | ||
| 190 | |||
| 191 | int glue_cbc_decrypt_128bit(const struct common_glue_ctx *gctx, | ||
| 192 | struct blkcipher_desc *desc, | ||
| 193 | struct scatterlist *dst, | ||
| 194 | struct scatterlist *src, unsigned int nbytes) | ||
| 195 | { | ||
| 196 | const unsigned int bsize = 128 / 8; | ||
| 197 | bool fpu_enabled = false; | ||
| 198 | struct blkcipher_walk walk; | ||
| 199 | int err; | ||
| 200 | |||
| 201 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
| 202 | err = blkcipher_walk_virt(desc, &walk); | ||
| 203 | |||
| 204 | while ((nbytes = walk.nbytes)) { | ||
| 205 | fpu_enabled = glue_fpu_begin(bsize, gctx->fpu_blocks_limit, | ||
| 206 | desc, fpu_enabled, nbytes); | ||
| 207 | nbytes = __glue_cbc_decrypt_128bit(gctx, desc, &walk); | ||
| 208 | err = blkcipher_walk_done(desc, &walk, nbytes); | ||
| 209 | } | ||
| 210 | |||
| 211 | glue_fpu_end(fpu_enabled); | ||
| 212 | return err; | ||
| 213 | } | ||
| 214 | EXPORT_SYMBOL_GPL(glue_cbc_decrypt_128bit); | ||
| 215 | |||
| 216 | static void glue_ctr_crypt_final_128bit(const common_glue_ctr_func_t fn_ctr, | ||
| 217 | struct blkcipher_desc *desc, | ||
| 218 | struct blkcipher_walk *walk) | ||
| 219 | { | ||
| 220 | void *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
| 221 | u8 *src = (u8 *)walk->src.virt.addr; | ||
| 222 | u8 *dst = (u8 *)walk->dst.virt.addr; | ||
| 223 | unsigned int nbytes = walk->nbytes; | ||
| 224 | u128 ctrblk; | ||
| 225 | u128 tmp; | ||
| 226 | |||
| 227 | be128_to_u128(&ctrblk, (be128 *)walk->iv); | ||
| 228 | |||
| 229 | memcpy(&tmp, src, nbytes); | ||
| 230 | fn_ctr(ctx, &tmp, &tmp, &ctrblk); | ||
| 231 | memcpy(dst, &tmp, nbytes); | ||
| 232 | |||
| 233 | u128_to_be128((be128 *)walk->iv, &ctrblk); | ||
| 234 | } | ||
| 235 | EXPORT_SYMBOL_GPL(glue_ctr_crypt_final_128bit); | ||
| 236 | |||
| 237 | static unsigned int __glue_ctr_crypt_128bit(const struct common_glue_ctx *gctx, | ||
| 238 | struct blkcipher_desc *desc, | ||
| 239 | struct blkcipher_walk *walk) | ||
| 240 | { | ||
| 241 | const unsigned int bsize = 128 / 8; | ||
| 242 | void *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
| 243 | unsigned int nbytes = walk->nbytes; | ||
| 244 | u128 *src = (u128 *)walk->src.virt.addr; | ||
| 245 | u128 *dst = (u128 *)walk->dst.virt.addr; | ||
| 246 | u128 ctrblk; | ||
| 247 | unsigned int num_blocks, func_bytes; | ||
| 248 | unsigned int i; | ||
| 249 | |||
| 250 | be128_to_u128(&ctrblk, (be128 *)walk->iv); | ||
| 251 | |||
| 252 | /* Process multi-block batch */ | ||
| 253 | for (i = 0; i < gctx->num_funcs; i++) { | ||
| 254 | num_blocks = gctx->funcs[i].num_blocks; | ||
| 255 | func_bytes = bsize * num_blocks; | ||
| 256 | |||
| 257 | if (nbytes >= func_bytes) { | ||
| 258 | do { | ||
| 259 | gctx->funcs[i].fn_u.ctr(ctx, dst, src, &ctrblk); | ||
| 260 | |||
| 261 | src += num_blocks; | ||
| 262 | dst += num_blocks; | ||
| 263 | nbytes -= func_bytes; | ||
| 264 | } while (nbytes >= func_bytes); | ||
| 265 | |||
| 266 | if (nbytes < bsize) | ||
| 267 | goto done; | ||
| 268 | } | ||
| 269 | } | ||
| 270 | |||
| 271 | done: | ||
| 272 | u128_to_be128((be128 *)walk->iv, &ctrblk); | ||
| 273 | return nbytes; | ||
| 274 | } | ||
| 275 | |||
| 276 | int glue_ctr_crypt_128bit(const struct common_glue_ctx *gctx, | ||
| 277 | struct blkcipher_desc *desc, struct scatterlist *dst, | ||
| 278 | struct scatterlist *src, unsigned int nbytes) | ||
| 279 | { | ||
| 280 | const unsigned int bsize = 128 / 8; | ||
| 281 | bool fpu_enabled = false; | ||
| 282 | struct blkcipher_walk walk; | ||
| 283 | int err; | ||
| 284 | |||
| 285 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
| 286 | err = blkcipher_walk_virt_block(desc, &walk, bsize); | ||
| 287 | |||
| 288 | while ((nbytes = walk.nbytes) >= bsize) { | ||
| 289 | fpu_enabled = glue_fpu_begin(bsize, gctx->fpu_blocks_limit, | ||
| 290 | desc, fpu_enabled, nbytes); | ||
| 291 | nbytes = __glue_ctr_crypt_128bit(gctx, desc, &walk); | ||
| 292 | err = blkcipher_walk_done(desc, &walk, nbytes); | ||
| 293 | } | ||
| 294 | |||
| 295 | glue_fpu_end(fpu_enabled); | ||
| 296 | |||
| 297 | if (walk.nbytes) { | ||
| 298 | glue_ctr_crypt_final_128bit( | ||
| 299 | gctx->funcs[gctx->num_funcs - 1].fn_u.ctr, desc, &walk); | ||
| 300 | err = blkcipher_walk_done(desc, &walk, 0); | ||
| 301 | } | ||
| 302 | |||
| 303 | return err; | ||
| 304 | } | ||
| 305 | EXPORT_SYMBOL_GPL(glue_ctr_crypt_128bit); | ||
| 306 | |||
| 307 | MODULE_LICENSE("GPL"); | ||
diff --git a/arch/x86/crypto/serpent-avx-x86_64-asm_64.S b/arch/x86/crypto/serpent-avx-x86_64-asm_64.S new file mode 100644 index 000000000000..504106bf04a2 --- /dev/null +++ b/arch/x86/crypto/serpent-avx-x86_64-asm_64.S | |||
| @@ -0,0 +1,704 @@ | |||
| 1 | /* | ||
| 2 | * Serpent Cipher 8-way parallel algorithm (x86_64/AVX) | ||
| 3 | * | ||
| 4 | * Copyright (C) 2012 Johannes Goetzfried | ||
| 5 | * <Johannes.Goetzfried@informatik.stud.uni-erlangen.de> | ||
| 6 | * | ||
| 7 | * Based on arch/x86/crypto/serpent-sse2-x86_64-asm_64.S by | ||
| 8 | * Copyright (C) 2011 Jussi Kivilinna <jussi.kivilinna@mbnet.fi> | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License as published by | ||
| 12 | * the Free Software Foundation; either version 2 of the License, or | ||
| 13 | * (at your option) any later version. | ||
| 14 | * | ||
| 15 | * This program is distributed in the hope that it will be useful, | ||
| 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 18 | * GNU General Public License for more details. | ||
| 19 | * | ||
| 20 | * You should have received a copy of the GNU General Public License | ||
| 21 | * along with this program; if not, write to the Free Software | ||
| 22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | ||
| 23 | * USA | ||
| 24 | * | ||
| 25 | */ | ||
| 26 | |||
| 27 | .file "serpent-avx-x86_64-asm_64.S" | ||
| 28 | .text | ||
| 29 | |||
| 30 | #define CTX %rdi | ||
| 31 | |||
| 32 | /********************************************************************** | ||
| 33 | 8-way AVX serpent | ||
| 34 | **********************************************************************/ | ||
| 35 | #define RA1 %xmm0 | ||
| 36 | #define RB1 %xmm1 | ||
| 37 | #define RC1 %xmm2 | ||
| 38 | #define RD1 %xmm3 | ||
| 39 | #define RE1 %xmm4 | ||
| 40 | |||
| 41 | #define tp %xmm5 | ||
| 42 | |||
| 43 | #define RA2 %xmm6 | ||
| 44 | #define RB2 %xmm7 | ||
| 45 | #define RC2 %xmm8 | ||
| 46 | #define RD2 %xmm9 | ||
| 47 | #define RE2 %xmm10 | ||
| 48 | |||
| 49 | #define RNOT %xmm11 | ||
| 50 | |||
| 51 | #define RK0 %xmm12 | ||
| 52 | #define RK1 %xmm13 | ||
| 53 | #define RK2 %xmm14 | ||
| 54 | #define RK3 %xmm15 | ||
| 55 | |||
| 56 | |||
| 57 | #define S0_1(x0, x1, x2, x3, x4) \ | ||
| 58 | vpor x0, x3, tp; \ | ||
| 59 | vpxor x3, x0, x0; \ | ||
| 60 | vpxor x2, x3, x4; \ | ||
| 61 | vpxor RNOT, x4, x4; \ | ||
| 62 | vpxor x1, tp, x3; \ | ||
| 63 | vpand x0, x1, x1; \ | ||
| 64 | vpxor x4, x1, x1; \ | ||
| 65 | vpxor x0, x2, x2; | ||
| 66 | #define S0_2(x0, x1, x2, x3, x4) \ | ||
| 67 | vpxor x3, x0, x0; \ | ||
| 68 | vpor x0, x4, x4; \ | ||
| 69 | vpxor x2, x0, x0; \ | ||
| 70 | vpand x1, x2, x2; \ | ||
| 71 | vpxor x2, x3, x3; \ | ||
| 72 | vpxor RNOT, x1, x1; \ | ||
| 73 | vpxor x4, x2, x2; \ | ||
| 74 | vpxor x2, x1, x1; | ||
| 75 | |||
| 76 | #define S1_1(x0, x1, x2, x3, x4) \ | ||
| 77 | vpxor x0, x1, tp; \ | ||
| 78 | vpxor x3, x0, x0; \ | ||
| 79 | vpxor RNOT, x3, x3; \ | ||
| 80 | vpand tp, x1, x4; \ | ||
| 81 | vpor tp, x0, x0; \ | ||
| 82 | vpxor x2, x3, x3; \ | ||
| 83 | vpxor x3, x0, x0; \ | ||
| 84 | vpxor x3, tp, x1; | ||
| 85 | #define S1_2(x0, x1, x2, x3, x4) \ | ||
| 86 | vpxor x4, x3, x3; \ | ||
| 87 | vpor x4, x1, x1; \ | ||
| 88 | vpxor x2, x4, x4; \ | ||
| 89 | vpand x0, x2, x2; \ | ||
| 90 | vpxor x1, x2, x2; \ | ||
| 91 | vpor x0, x1, x1; \ | ||
| 92 | vpxor RNOT, x0, x0; \ | ||
| 93 | vpxor x2, x0, x0; \ | ||
| 94 | vpxor x1, x4, x4; | ||
| 95 | |||
| 96 | #define S2_1(x0, x1, x2, x3, x4) \ | ||
| 97 | vpxor RNOT, x3, x3; \ | ||
| 98 | vpxor x0, x1, x1; \ | ||
| 99 | vpand x2, x0, tp; \ | ||
| 100 | vpxor x3, tp, tp; \ | ||
| 101 | vpor x0, x3, x3; \ | ||
| 102 | vpxor x1, x2, x2; \ | ||
| 103 | vpxor x1, x3, x3; \ | ||
| 104 | vpand tp, x1, x1; | ||
| 105 | #define S2_2(x0, x1, x2, x3, x4) \ | ||
| 106 | vpxor x2, tp, tp; \ | ||
| 107 | vpand x3, x2, x2; \ | ||
| 108 | vpor x1, x3, x3; \ | ||
| 109 | vpxor RNOT, tp, tp; \ | ||
| 110 | vpxor tp, x3, x3; \ | ||
| 111 | vpxor tp, x0, x4; \ | ||
| 112 | vpxor x2, tp, x0; \ | ||
| 113 | vpor x2, x1, x1; | ||
| 114 | |||
| 115 | #define S3_1(x0, x1, x2, x3, x4) \ | ||
| 116 | vpxor x3, x1, tp; \ | ||
| 117 | vpor x0, x3, x3; \ | ||
| 118 | vpand x0, x1, x4; \ | ||
| 119 | vpxor x2, x0, x0; \ | ||
| 120 | vpxor tp, x2, x2; \ | ||
| 121 | vpand x3, tp, x1; \ | ||
| 122 | vpxor x3, x2, x2; \ | ||
| 123 | vpor x4, x0, x0; \ | ||
| 124 | vpxor x3, x4, x4; | ||
| 125 | #define S3_2(x0, x1, x2, x3, x4) \ | ||
| 126 | vpxor x0, x1, x1; \ | ||
| 127 | vpand x3, x0, x0; \ | ||
| 128 | vpand x4, x3, x3; \ | ||
| 129 | vpxor x2, x3, x3; \ | ||
| 130 | vpor x1, x4, x4; \ | ||
| 131 | vpand x1, x2, x2; \ | ||
| 132 | vpxor x3, x4, x4; \ | ||
| 133 | vpxor x3, x0, x0; \ | ||
| 134 | vpxor x2, x3, x3; | ||
| 135 | |||
| 136 | #define S4_1(x0, x1, x2, x3, x4) \ | ||
| 137 | vpand x0, x3, tp; \ | ||
| 138 | vpxor x3, x0, x0; \ | ||
| 139 | vpxor x2, tp, tp; \ | ||
| 140 | vpor x3, x2, x2; \ | ||
| 141 | vpxor x1, x0, x0; \ | ||
| 142 | vpxor tp, x3, x4; \ | ||
| 143 | vpor x0, x2, x2; \ | ||
| 144 | vpxor x1, x2, x2; | ||
| 145 | #define S4_2(x0, x1, x2, x3, x4) \ | ||
| 146 | vpand x0, x1, x1; \ | ||
| 147 | vpxor x4, x1, x1; \ | ||
| 148 | vpand x2, x4, x4; \ | ||
| 149 | vpxor tp, x2, x2; \ | ||
| 150 | vpxor x0, x4, x4; \ | ||
| 151 | vpor x1, tp, x3; \ | ||
| 152 | vpxor RNOT, x1, x1; \ | ||
| 153 | vpxor x0, x3, x3; | ||
| 154 | |||
| 155 | #define S5_1(x0, x1, x2, x3, x4) \ | ||
| 156 | vpor x0, x1, tp; \ | ||
| 157 | vpxor tp, x2, x2; \ | ||
| 158 | vpxor RNOT, x3, x3; \ | ||
| 159 | vpxor x0, x1, x4; \ | ||
| 160 | vpxor x2, x0, x0; \ | ||
| 161 | vpand x4, tp, x1; \ | ||
| 162 | vpor x3, x4, x4; \ | ||
| 163 | vpxor x0, x4, x4; | ||
| 164 | #define S5_2(x0, x1, x2, x3, x4) \ | ||
| 165 | vpand x3, x0, x0; \ | ||
| 166 | vpxor x3, x1, x1; \ | ||
| 167 | vpxor x2, x3, x3; \ | ||
| 168 | vpxor x1, x0, x0; \ | ||
| 169 | vpand x4, x2, x2; \ | ||
| 170 | vpxor x2, x1, x1; \ | ||
| 171 | vpand x0, x2, x2; \ | ||
| 172 | vpxor x2, x3, x3; | ||
| 173 | |||
| 174 | #define S6_1(x0, x1, x2, x3, x4) \ | ||
| 175 | vpxor x0, x3, x3; \ | ||
| 176 | vpxor x2, x1, tp; \ | ||
| 177 | vpxor x0, x2, x2; \ | ||
| 178 | vpand x3, x0, x0; \ | ||
| 179 | vpor x3, tp, tp; \ | ||
| 180 | vpxor RNOT, x1, x4; \ | ||
| 181 | vpxor tp, x0, x0; \ | ||
| 182 | vpxor x2, tp, x1; | ||
| 183 | #define S6_2(x0, x1, x2, x3, x4) \ | ||
| 184 | vpxor x4, x3, x3; \ | ||
| 185 | vpxor x0, x4, x4; \ | ||
| 186 | vpand x0, x2, x2; \ | ||
| 187 | vpxor x1, x4, x4; \ | ||
| 188 | vpxor x3, x2, x2; \ | ||
| 189 | vpand x1, x3, x3; \ | ||
| 190 | vpxor x0, x3, x3; \ | ||
| 191 | vpxor x2, x1, x1; | ||
| 192 | |||
| 193 | #define S7_1(x0, x1, x2, x3, x4) \ | ||
| 194 | vpxor RNOT, x1, tp; \ | ||
| 195 | vpxor RNOT, x0, x0; \ | ||
| 196 | vpand x2, tp, x1; \ | ||
| 197 | vpxor x3, x1, x1; \ | ||
| 198 | vpor tp, x3, x3; \ | ||
| 199 | vpxor x2, tp, x4; \ | ||
| 200 | vpxor x3, x2, x2; \ | ||
| 201 | vpxor x0, x3, x3; \ | ||
| 202 | vpor x1, x0, x0; | ||
| 203 | #define S7_2(x0, x1, x2, x3, x4) \ | ||
| 204 | vpand x0, x2, x2; \ | ||
| 205 | vpxor x4, x0, x0; \ | ||
| 206 | vpxor x3, x4, x4; \ | ||
| 207 | vpand x0, x3, x3; \ | ||
| 208 | vpxor x1, x4, x4; \ | ||
| 209 | vpxor x4, x2, x2; \ | ||
| 210 | vpxor x1, x3, x3; \ | ||
| 211 | vpor x0, x4, x4; \ | ||
| 212 | vpxor x1, x4, x4; | ||
| 213 | |||
| 214 | #define SI0_1(x0, x1, x2, x3, x4) \ | ||
| 215 | vpxor x0, x1, x1; \ | ||
| 216 | vpor x1, x3, tp; \ | ||
| 217 | vpxor x1, x3, x4; \ | ||
| 218 | vpxor RNOT, x0, x0; \ | ||
| 219 | vpxor tp, x2, x2; \ | ||
| 220 | vpxor x0, tp, x3; \ | ||
| 221 | vpand x1, x0, x0; \ | ||
| 222 | vpxor x2, x0, x0; | ||
| 223 | #define SI0_2(x0, x1, x2, x3, x4) \ | ||
| 224 | vpand x3, x2, x2; \ | ||
| 225 | vpxor x4, x3, x3; \ | ||
| 226 | vpxor x3, x2, x2; \ | ||
| 227 | vpxor x3, x1, x1; \ | ||
| 228 | vpand x0, x3, x3; \ | ||
| 229 | vpxor x0, x1, x1; \ | ||
| 230 | vpxor x2, x0, x0; \ | ||
| 231 | vpxor x3, x4, x4; | ||
| 232 | |||
| 233 | #define SI1_1(x0, x1, x2, x3, x4) \ | ||
| 234 | vpxor x3, x1, x1; \ | ||
| 235 | vpxor x2, x0, tp; \ | ||
| 236 | vpxor RNOT, x2, x2; \ | ||
| 237 | vpor x1, x0, x4; \ | ||
| 238 | vpxor x3, x4, x4; \ | ||
| 239 | vpand x1, x3, x3; \ | ||
| 240 | vpxor x2, x1, x1; \ | ||
| 241 | vpand x4, x2, x2; | ||
| 242 | #define SI1_2(x0, x1, x2, x3, x4) \ | ||
| 243 | vpxor x1, x4, x4; \ | ||
| 244 | vpor x3, x1, x1; \ | ||
| 245 | vpxor tp, x3, x3; \ | ||
| 246 | vpxor tp, x2, x2; \ | ||
| 247 | vpor x4, tp, x0; \ | ||
| 248 | vpxor x4, x2, x2; \ | ||
| 249 | vpxor x0, x1, x1; \ | ||
| 250 | vpxor x1, x4, x4; | ||
| 251 | |||
| 252 | #define SI2_1(x0, x1, x2, x3, x4) \ | ||
| 253 | vpxor x1, x2, x2; \ | ||
| 254 | vpxor RNOT, x3, tp; \ | ||
| 255 | vpor x2, tp, tp; \ | ||
| 256 | vpxor x3, x2, x2; \ | ||
| 257 | vpxor x0, x3, x4; \ | ||
| 258 | vpxor x1, tp, x3; \ | ||
| 259 | vpor x2, x1, x1; \ | ||
| 260 | vpxor x0, x2, x2; | ||
| 261 | #define SI2_2(x0, x1, x2, x3, x4) \ | ||
| 262 | vpxor x4, x1, x1; \ | ||
| 263 | vpor x3, x4, x4; \ | ||
| 264 | vpxor x3, x2, x2; \ | ||
| 265 | vpxor x2, x4, x4; \ | ||
| 266 | vpand x1, x2, x2; \ | ||
| 267 | vpxor x3, x2, x2; \ | ||
| 268 | vpxor x4, x3, x3; \ | ||
| 269 | vpxor x0, x4, x4; | ||
| 270 | |||
| 271 | #define SI3_1(x0, x1, x2, x3, x4) \ | ||
| 272 | vpxor x1, x2, x2; \ | ||
| 273 | vpand x2, x1, tp; \ | ||
| 274 | vpxor x0, tp, tp; \ | ||
| 275 | vpor x1, x0, x0; \ | ||
| 276 | vpxor x3, x1, x4; \ | ||
| 277 | vpxor x3, x0, x0; \ | ||
| 278 | vpor tp, x3, x3; \ | ||
| 279 | vpxor x2, tp, x1; | ||
| 280 | #define SI3_2(x0, x1, x2, x3, x4) \ | ||
| 281 | vpxor x3, x1, x1; \ | ||
| 282 | vpxor x2, x0, x0; \ | ||
| 283 | vpxor x3, x2, x2; \ | ||
| 284 | vpand x1, x3, x3; \ | ||
| 285 | vpxor x0, x1, x1; \ | ||
| 286 | vpand x2, x0, x0; \ | ||
| 287 | vpxor x3, x4, x4; \ | ||
| 288 | vpxor x0, x3, x3; \ | ||
| 289 | vpxor x1, x0, x0; | ||
| 290 | |||
| 291 | #define SI4_1(x0, x1, x2, x3, x4) \ | ||
| 292 | vpxor x3, x2, x2; \ | ||
| 293 | vpand x1, x0, tp; \ | ||
| 294 | vpxor x2, tp, tp; \ | ||
| 295 | vpor x3, x2, x2; \ | ||
| 296 | vpxor RNOT, x0, x4; \ | ||
| 297 | vpxor tp, x1, x1; \ | ||
| 298 | vpxor x2, tp, x0; \ | ||
| 299 | vpand x4, x2, x2; | ||
| 300 | #define SI4_2(x0, x1, x2, x3, x4) \ | ||
| 301 | vpxor x0, x2, x2; \ | ||
| 302 | vpor x4, x0, x0; \ | ||
| 303 | vpxor x3, x0, x0; \ | ||
| 304 | vpand x2, x3, x3; \ | ||
| 305 | vpxor x3, x4, x4; \ | ||
| 306 | vpxor x1, x3, x3; \ | ||
| 307 | vpand x0, x1, x1; \ | ||
| 308 | vpxor x1, x4, x4; \ | ||
| 309 | vpxor x3, x0, x0; | ||
| 310 | |||
| 311 | #define SI5_1(x0, x1, x2, x3, x4) \ | ||
| 312 | vpor x2, x1, tp; \ | ||
| 313 | vpxor x1, x2, x2; \ | ||
| 314 | vpxor x3, tp, tp; \ | ||
| 315 | vpand x1, x3, x3; \ | ||
| 316 | vpxor x3, x2, x2; \ | ||
| 317 | vpor x0, x3, x3; \ | ||
| 318 | vpxor RNOT, x0, x0; \ | ||
| 319 | vpxor x2, x3, x3; \ | ||
| 320 | vpor x0, x2, x2; | ||
| 321 | #define SI5_2(x0, x1, x2, x3, x4) \ | ||
| 322 | vpxor tp, x1, x4; \ | ||
| 323 | vpxor x4, x2, x2; \ | ||
| 324 | vpand x0, x4, x4; \ | ||
| 325 | vpxor tp, x0, x0; \ | ||
| 326 | vpxor x3, tp, x1; \ | ||
| 327 | vpand x2, x0, x0; \ | ||
| 328 | vpxor x3, x2, x2; \ | ||
| 329 | vpxor x2, x0, x0; \ | ||
| 330 | vpxor x4, x2, x2; \ | ||
| 331 | vpxor x3, x4, x4; | ||
| 332 | |||
| 333 | #define SI6_1(x0, x1, x2, x3, x4) \ | ||
| 334 | vpxor x2, x0, x0; \ | ||
| 335 | vpand x3, x0, tp; \ | ||
| 336 | vpxor x3, x2, x2; \ | ||
| 337 | vpxor x2, tp, tp; \ | ||
| 338 | vpxor x1, x3, x3; \ | ||
| 339 | vpor x0, x2, x2; \ | ||
| 340 | vpxor x3, x2, x2; \ | ||
| 341 | vpand tp, x3, x3; | ||
| 342 | #define SI6_2(x0, x1, x2, x3, x4) \ | ||
| 343 | vpxor RNOT, tp, tp; \ | ||
| 344 | vpxor x1, x3, x3; \ | ||
| 345 | vpand x2, x1, x1; \ | ||
| 346 | vpxor tp, x0, x4; \ | ||
| 347 | vpxor x4, x3, x3; \ | ||
| 348 | vpxor x2, x4, x4; \ | ||
| 349 | vpxor x1, tp, x0; \ | ||
| 350 | vpxor x0, x2, x2; | ||
| 351 | |||
| 352 | #define SI7_1(x0, x1, x2, x3, x4) \ | ||
| 353 | vpand x0, x3, tp; \ | ||
| 354 | vpxor x2, x0, x0; \ | ||
| 355 | vpor x3, x2, x2; \ | ||
| 356 | vpxor x1, x3, x4; \ | ||
| 357 | vpxor RNOT, x0, x0; \ | ||
| 358 | vpor tp, x1, x1; \ | ||
| 359 | vpxor x0, x4, x4; \ | ||
| 360 | vpand x2, x0, x0; \ | ||
| 361 | vpxor x1, x0, x0; | ||
| 362 | #define SI7_2(x0, x1, x2, x3, x4) \ | ||
| 363 | vpand x2, x1, x1; \ | ||
| 364 | vpxor x2, tp, x3; \ | ||
| 365 | vpxor x3, x4, x4; \ | ||
| 366 | vpand x3, x2, x2; \ | ||
| 367 | vpor x0, x3, x3; \ | ||
| 368 | vpxor x4, x1, x1; \ | ||
| 369 | vpxor x4, x3, x3; \ | ||
| 370 | vpand x0, x4, x4; \ | ||
| 371 | vpxor x2, x4, x4; | ||
| 372 | |||
| 373 | #define get_key(i, j, t) \ | ||
| 374 | vbroadcastss (4*(i)+(j))*4(CTX), t; | ||
| 375 | |||
| 376 | #define K2(x0, x1, x2, x3, x4, i) \ | ||
| 377 | get_key(i, 0, RK0); \ | ||
| 378 | get_key(i, 1, RK1); \ | ||
| 379 | get_key(i, 2, RK2); \ | ||
| 380 | get_key(i, 3, RK3); \ | ||
| 381 | vpxor RK0, x0 ## 1, x0 ## 1; \ | ||
| 382 | vpxor RK1, x1 ## 1, x1 ## 1; \ | ||
| 383 | vpxor RK2, x2 ## 1, x2 ## 1; \ | ||
| 384 | vpxor RK3, x3 ## 1, x3 ## 1; \ | ||
| 385 | vpxor RK0, x0 ## 2, x0 ## 2; \ | ||
| 386 | vpxor RK1, x1 ## 2, x1 ## 2; \ | ||
| 387 | vpxor RK2, x2 ## 2, x2 ## 2; \ | ||
| 388 | vpxor RK3, x3 ## 2, x3 ## 2; | ||
| 389 | |||
| 390 | #define LK2(x0, x1, x2, x3, x4, i) \ | ||
| 391 | vpslld $13, x0 ## 1, x4 ## 1; \ | ||
| 392 | vpsrld $(32 - 13), x0 ## 1, x0 ## 1; \ | ||
| 393 | vpor x4 ## 1, x0 ## 1, x0 ## 1; \ | ||
| 394 | vpxor x0 ## 1, x1 ## 1, x1 ## 1; \ | ||
| 395 | vpslld $3, x2 ## 1, x4 ## 1; \ | ||
| 396 | vpsrld $(32 - 3), x2 ## 1, x2 ## 1; \ | ||
| 397 | vpor x4 ## 1, x2 ## 1, x2 ## 1; \ | ||
| 398 | vpxor x2 ## 1, x1 ## 1, x1 ## 1; \ | ||
| 399 | vpslld $13, x0 ## 2, x4 ## 2; \ | ||
| 400 | vpsrld $(32 - 13), x0 ## 2, x0 ## 2; \ | ||
| 401 | vpor x4 ## 2, x0 ## 2, x0 ## 2; \ | ||
| 402 | vpxor x0 ## 2, x1 ## 2, x1 ## 2; \ | ||
| 403 | vpslld $3, x2 ## 2, x4 ## 2; \ | ||
| 404 | vpsrld $(32 - 3), x2 ## 2, x2 ## 2; \ | ||
| 405 | vpor x4 ## 2, x2 ## 2, x2 ## 2; \ | ||
| 406 | vpxor x2 ## 2, x1 ## 2, x1 ## 2; \ | ||
| 407 | vpslld $1, x1 ## 1, x4 ## 1; \ | ||
| 408 | vpsrld $(32 - 1), x1 ## 1, x1 ## 1; \ | ||
| 409 | vpor x4 ## 1, x1 ## 1, x1 ## 1; \ | ||
| 410 | vpslld $3, x0 ## 1, x4 ## 1; \ | ||
| 411 | vpxor x2 ## 1, x3 ## 1, x3 ## 1; \ | ||
| 412 | vpxor x4 ## 1, x3 ## 1, x3 ## 1; \ | ||
| 413 | get_key(i, 1, RK1); \ | ||
| 414 | vpslld $1, x1 ## 2, x4 ## 2; \ | ||
| 415 | vpsrld $(32 - 1), x1 ## 2, x1 ## 2; \ | ||
| 416 | vpor x4 ## 2, x1 ## 2, x1 ## 2; \ | ||
| 417 | vpslld $3, x0 ## 2, x4 ## 2; \ | ||
| 418 | vpxor x2 ## 2, x3 ## 2, x3 ## 2; \ | ||
| 419 | vpxor x4 ## 2, x3 ## 2, x3 ## 2; \ | ||
| 420 | get_key(i, 3, RK3); \ | ||
| 421 | vpslld $7, x3 ## 1, x4 ## 1; \ | ||
| 422 | vpsrld $(32 - 7), x3 ## 1, x3 ## 1; \ | ||
| 423 | vpor x4 ## 1, x3 ## 1, x3 ## 1; \ | ||
| 424 | vpslld $7, x1 ## 1, x4 ## 1; \ | ||
| 425 | vpxor x1 ## 1, x0 ## 1, x0 ## 1; \ | ||
| 426 | vpxor x3 ## 1, x0 ## 1, x0 ## 1; \ | ||
| 427 | vpxor x3 ## 1, x2 ## 1, x2 ## 1; \ | ||
| 428 | vpxor x4 ## 1, x2 ## 1, x2 ## 1; \ | ||
| 429 | get_key(i, 0, RK0); \ | ||
| 430 | vpslld $7, x3 ## 2, x4 ## 2; \ | ||
| 431 | vpsrld $(32 - 7), x3 ## 2, x3 ## 2; \ | ||
| 432 | vpor x4 ## 2, x3 ## 2, x3 ## 2; \ | ||
| 433 | vpslld $7, x1 ## 2, x4 ## 2; \ | ||
| 434 | vpxor x1 ## 2, x0 ## 2, x0 ## 2; \ | ||
| 435 | vpxor x3 ## 2, x0 ## 2, x0 ## 2; \ | ||
| 436 | vpxor x3 ## 2, x2 ## 2, x2 ## 2; \ | ||
| 437 | vpxor x4 ## 2, x2 ## 2, x2 ## 2; \ | ||
| 438 | get_key(i, 2, RK2); \ | ||
| 439 | vpxor RK1, x1 ## 1, x1 ## 1; \ | ||
| 440 | vpxor RK3, x3 ## 1, x3 ## 1; \ | ||
| 441 | vpslld $5, x0 ## 1, x4 ## 1; \ | ||
| 442 | vpsrld $(32 - 5), x0 ## 1, x0 ## 1; \ | ||
| 443 | vpor x4 ## 1, x0 ## 1, x0 ## 1; \ | ||
| 444 | vpslld $22, x2 ## 1, x4 ## 1; \ | ||
| 445 | vpsrld $(32 - 22), x2 ## 1, x2 ## 1; \ | ||
| 446 | vpor x4 ## 1, x2 ## 1, x2 ## 1; \ | ||
| 447 | vpxor RK0, x0 ## 1, x0 ## 1; \ | ||
| 448 | vpxor RK2, x2 ## 1, x2 ## 1; \ | ||
| 449 | vpxor RK1, x1 ## 2, x1 ## 2; \ | ||
| 450 | vpxor RK3, x3 ## 2, x3 ## 2; \ | ||
| 451 | vpslld $5, x0 ## 2, x4 ## 2; \ | ||
| 452 | vpsrld $(32 - 5), x0 ## 2, x0 ## 2; \ | ||
| 453 | vpor x4 ## 2, x0 ## 2, x0 ## 2; \ | ||
| 454 | vpslld $22, x2 ## 2, x4 ## 2; \ | ||
| 455 | vpsrld $(32 - 22), x2 ## 2, x2 ## 2; \ | ||
| 456 | vpor x4 ## 2, x2 ## 2, x2 ## 2; \ | ||
| 457 | vpxor RK0, x0 ## 2, x0 ## 2; \ | ||
| 458 | vpxor RK2, x2 ## 2, x2 ## 2; | ||
| 459 | |||
| 460 | #define KL2(x0, x1, x2, x3, x4, i) \ | ||
| 461 | vpxor RK0, x0 ## 1, x0 ## 1; \ | ||
| 462 | vpxor RK2, x2 ## 1, x2 ## 1; \ | ||
| 463 | vpsrld $5, x0 ## 1, x4 ## 1; \ | ||
| 464 | vpslld $(32 - 5), x0 ## 1, x0 ## 1; \ | ||
| 465 | vpor x4 ## 1, x0 ## 1, x0 ## 1; \ | ||
| 466 | vpxor RK3, x3 ## 1, x3 ## 1; \ | ||
| 467 | vpxor RK1, x1 ## 1, x1 ## 1; \ | ||
| 468 | vpsrld $22, x2 ## 1, x4 ## 1; \ | ||
| 469 | vpslld $(32 - 22), x2 ## 1, x2 ## 1; \ | ||
| 470 | vpor x4 ## 1, x2 ## 1, x2 ## 1; \ | ||
| 471 | vpxor x3 ## 1, x2 ## 1, x2 ## 1; \ | ||
| 472 | vpxor RK0, x0 ## 2, x0 ## 2; \ | ||
| 473 | vpxor RK2, x2 ## 2, x2 ## 2; \ | ||
| 474 | vpsrld $5, x0 ## 2, x4 ## 2; \ | ||
| 475 | vpslld $(32 - 5), x0 ## 2, x0 ## 2; \ | ||
| 476 | vpor x4 ## 2, x0 ## 2, x0 ## 2; \ | ||
| 477 | vpxor RK3, x3 ## 2, x3 ## 2; \ | ||
| 478 | vpxor RK1, x1 ## 2, x1 ## 2; \ | ||
| 479 | vpsrld $22, x2 ## 2, x4 ## 2; \ | ||
| 480 | vpslld $(32 - 22), x2 ## 2, x2 ## 2; \ | ||
| 481 | vpor x4 ## 2, x2 ## 2, x2 ## 2; \ | ||
| 482 | vpxor x3 ## 2, x2 ## 2, x2 ## 2; \ | ||
| 483 | vpxor x3 ## 1, x0 ## 1, x0 ## 1; \ | ||
| 484 | vpslld $7, x1 ## 1, x4 ## 1; \ | ||
| 485 | vpxor x1 ## 1, x0 ## 1, x0 ## 1; \ | ||
| 486 | vpxor x4 ## 1, x2 ## 1, x2 ## 1; \ | ||
| 487 | vpsrld $1, x1 ## 1, x4 ## 1; \ | ||
| 488 | vpslld $(32 - 1), x1 ## 1, x1 ## 1; \ | ||
| 489 | vpor x4 ## 1, x1 ## 1, x1 ## 1; \ | ||
| 490 | vpxor x3 ## 2, x0 ## 2, x0 ## 2; \ | ||
| 491 | vpslld $7, x1 ## 2, x4 ## 2; \ | ||
| 492 | vpxor x1 ## 2, x0 ## 2, x0 ## 2; \ | ||
| 493 | vpxor x4 ## 2, x2 ## 2, x2 ## 2; \ | ||
| 494 | vpsrld $1, x1 ## 2, x4 ## 2; \ | ||
| 495 | vpslld $(32 - 1), x1 ## 2, x1 ## 2; \ | ||
| 496 | vpor x4 ## 2, x1 ## 2, x1 ## 2; \ | ||
| 497 | vpsrld $7, x3 ## 1, x4 ## 1; \ | ||
| 498 | vpslld $(32 - 7), x3 ## 1, x3 ## 1; \ | ||
| 499 | vpor x4 ## 1, x3 ## 1, x3 ## 1; \ | ||
| 500 | vpxor x0 ## 1, x1 ## 1, x1 ## 1; \ | ||
| 501 | vpslld $3, x0 ## 1, x4 ## 1; \ | ||
| 502 | vpxor x4 ## 1, x3 ## 1, x3 ## 1; \ | ||
| 503 | vpsrld $7, x3 ## 2, x4 ## 2; \ | ||
| 504 | vpslld $(32 - 7), x3 ## 2, x3 ## 2; \ | ||
| 505 | vpor x4 ## 2, x3 ## 2, x3 ## 2; \ | ||
| 506 | vpxor x0 ## 2, x1 ## 2, x1 ## 2; \ | ||
| 507 | vpslld $3, x0 ## 2, x4 ## 2; \ | ||
| 508 | vpxor x4 ## 2, x3 ## 2, x3 ## 2; \ | ||
| 509 | vpsrld $13, x0 ## 1, x4 ## 1; \ | ||
| 510 | vpslld $(32 - 13), x0 ## 1, x0 ## 1; \ | ||
| 511 | vpor x4 ## 1, x0 ## 1, x0 ## 1; \ | ||
| 512 | vpxor x2 ## 1, x1 ## 1, x1 ## 1; \ | ||
| 513 | vpxor x2 ## 1, x3 ## 1, x3 ## 1; \ | ||
| 514 | vpsrld $3, x2 ## 1, x4 ## 1; \ | ||
| 515 | vpslld $(32 - 3), x2 ## 1, x2 ## 1; \ | ||
| 516 | vpor x4 ## 1, x2 ## 1, x2 ## 1; \ | ||
| 517 | vpsrld $13, x0 ## 2, x4 ## 2; \ | ||
| 518 | vpslld $(32 - 13), x0 ## 2, x0 ## 2; \ | ||
| 519 | vpor x4 ## 2, x0 ## 2, x0 ## 2; \ | ||
| 520 | vpxor x2 ## 2, x1 ## 2, x1 ## 2; \ | ||
| 521 | vpxor x2 ## 2, x3 ## 2, x3 ## 2; \ | ||
| 522 | vpsrld $3, x2 ## 2, x4 ## 2; \ | ||
| 523 | vpslld $(32 - 3), x2 ## 2, x2 ## 2; \ | ||
| 524 | vpor x4 ## 2, x2 ## 2, x2 ## 2; | ||
| 525 | |||
| 526 | #define S(SBOX, x0, x1, x2, x3, x4) \ | ||
| 527 | SBOX ## _1(x0 ## 1, x1 ## 1, x2 ## 1, x3 ## 1, x4 ## 1); \ | ||
| 528 | SBOX ## _2(x0 ## 1, x1 ## 1, x2 ## 1, x3 ## 1, x4 ## 1); \ | ||
| 529 | SBOX ## _1(x0 ## 2, x1 ## 2, x2 ## 2, x3 ## 2, x4 ## 2); \ | ||
| 530 | SBOX ## _2(x0 ## 2, x1 ## 2, x2 ## 2, x3 ## 2, x4 ## 2); | ||
| 531 | |||
| 532 | #define SP(SBOX, x0, x1, x2, x3, x4, i) \ | ||
| 533 | get_key(i, 0, RK0); \ | ||
| 534 | SBOX ## _1(x0 ## 1, x1 ## 1, x2 ## 1, x3 ## 1, x4 ## 1); \ | ||
| 535 | get_key(i, 2, RK2); \ | ||
| 536 | SBOX ## _2(x0 ## 1, x1 ## 1, x2 ## 1, x3 ## 1, x4 ## 1); \ | ||
| 537 | get_key(i, 3, RK3); \ | ||
| 538 | SBOX ## _1(x0 ## 2, x1 ## 2, x2 ## 2, x3 ## 2, x4 ## 2); \ | ||
| 539 | get_key(i, 1, RK1); \ | ||
| 540 | SBOX ## _2(x0 ## 2, x1 ## 2, x2 ## 2, x3 ## 2, x4 ## 2); \ | ||
| 541 | |||
| 542 | #define transpose_4x4(x0, x1, x2, x3, t0, t1, t2) \ | ||
| 543 | vpunpckldq x1, x0, t0; \ | ||
| 544 | vpunpckhdq x1, x0, t2; \ | ||
| 545 | vpunpckldq x3, x2, t1; \ | ||
| 546 | vpunpckhdq x3, x2, x3; \ | ||
| 547 | \ | ||
| 548 | vpunpcklqdq t1, t0, x0; \ | ||
| 549 | vpunpckhqdq t1, t0, x1; \ | ||
| 550 | vpunpcklqdq x3, t2, x2; \ | ||
| 551 | vpunpckhqdq x3, t2, x3; | ||
| 552 | |||
| 553 | #define read_blocks(in, x0, x1, x2, x3, t0, t1, t2) \ | ||
| 554 | vmovdqu (0*4*4)(in), x0; \ | ||
| 555 | vmovdqu (1*4*4)(in), x1; \ | ||
| 556 | vmovdqu (2*4*4)(in), x2; \ | ||
| 557 | vmovdqu (3*4*4)(in), x3; \ | ||
| 558 | \ | ||
| 559 | transpose_4x4(x0, x1, x2, x3, t0, t1, t2) | ||
| 560 | |||
| 561 | #define write_blocks(out, x0, x1, x2, x3, t0, t1, t2) \ | ||
| 562 | transpose_4x4(x0, x1, x2, x3, t0, t1, t2) \ | ||
| 563 | \ | ||
| 564 | vmovdqu x0, (0*4*4)(out); \ | ||
| 565 | vmovdqu x1, (1*4*4)(out); \ | ||
| 566 | vmovdqu x2, (2*4*4)(out); \ | ||
| 567 | vmovdqu x3, (3*4*4)(out); | ||
| 568 | |||
| 569 | #define xor_blocks(out, x0, x1, x2, x3, t0, t1, t2) \ | ||
| 570 | transpose_4x4(x0, x1, x2, x3, t0, t1, t2) \ | ||
| 571 | \ | ||
| 572 | vpxor (0*4*4)(out), x0, x0; \ | ||
| 573 | vmovdqu x0, (0*4*4)(out); \ | ||
| 574 | vpxor (1*4*4)(out), x1, x1; \ | ||
| 575 | vmovdqu x1, (1*4*4)(out); \ | ||
| 576 | vpxor (2*4*4)(out), x2, x2; \ | ||
| 577 | vmovdqu x2, (2*4*4)(out); \ | ||
| 578 | vpxor (3*4*4)(out), x3, x3; \ | ||
| 579 | vmovdqu x3, (3*4*4)(out); | ||
| 580 | |||
| 581 | .align 8 | ||
| 582 | .global __serpent_enc_blk_8way_avx | ||
| 583 | .type __serpent_enc_blk_8way_avx,@function; | ||
| 584 | |||
| 585 | __serpent_enc_blk_8way_avx: | ||
| 586 | /* input: | ||
| 587 | * %rdi: ctx, CTX | ||
| 588 | * %rsi: dst | ||
| 589 | * %rdx: src | ||
| 590 | * %rcx: bool, if true: xor output | ||
| 591 | */ | ||
| 592 | |||
| 593 | vpcmpeqd RNOT, RNOT, RNOT; | ||
| 594 | |||
| 595 | leaq (4*4*4)(%rdx), %rax; | ||
| 596 | read_blocks(%rdx, RA1, RB1, RC1, RD1, RK0, RK1, RK2); | ||
| 597 | read_blocks(%rax, RA2, RB2, RC2, RD2, RK0, RK1, RK2); | ||
| 598 | |||
| 599 | K2(RA, RB, RC, RD, RE, 0); | ||
| 600 | S(S0, RA, RB, RC, RD, RE); LK2(RC, RB, RD, RA, RE, 1); | ||
| 601 | S(S1, RC, RB, RD, RA, RE); LK2(RE, RD, RA, RC, RB, 2); | ||
| 602 | S(S2, RE, RD, RA, RC, RB); LK2(RB, RD, RE, RC, RA, 3); | ||
| 603 | S(S3, RB, RD, RE, RC, RA); LK2(RC, RA, RD, RB, RE, 4); | ||
| 604 | S(S4, RC, RA, RD, RB, RE); LK2(RA, RD, RB, RE, RC, 5); | ||
| 605 | S(S5, RA, RD, RB, RE, RC); LK2(RC, RA, RD, RE, RB, 6); | ||
| 606 | S(S6, RC, RA, RD, RE, RB); LK2(RD, RB, RA, RE, RC, 7); | ||
| 607 | S(S7, RD, RB, RA, RE, RC); LK2(RC, RA, RE, RD, RB, 8); | ||
| 608 | S(S0, RC, RA, RE, RD, RB); LK2(RE, RA, RD, RC, RB, 9); | ||
| 609 | S(S1, RE, RA, RD, RC, RB); LK2(RB, RD, RC, RE, RA, 10); | ||
| 610 | S(S2, RB, RD, RC, RE, RA); LK2(RA, RD, RB, RE, RC, 11); | ||
| 611 | S(S3, RA, RD, RB, RE, RC); LK2(RE, RC, RD, RA, RB, 12); | ||
| 612 | S(S4, RE, RC, RD, RA, RB); LK2(RC, RD, RA, RB, RE, 13); | ||
| 613 | S(S5, RC, RD, RA, RB, RE); LK2(RE, RC, RD, RB, RA, 14); | ||
| 614 | S(S6, RE, RC, RD, RB, RA); LK2(RD, RA, RC, RB, RE, 15); | ||
| 615 | S(S7, RD, RA, RC, RB, RE); LK2(RE, RC, RB, RD, RA, 16); | ||
| 616 | S(S0, RE, RC, RB, RD, RA); LK2(RB, RC, RD, RE, RA, 17); | ||
| 617 | S(S1, RB, RC, RD, RE, RA); LK2(RA, RD, RE, RB, RC, 18); | ||
| 618 | S(S2, RA, RD, RE, RB, RC); LK2(RC, RD, RA, RB, RE, 19); | ||
| 619 | S(S3, RC, RD, RA, RB, RE); LK2(RB, RE, RD, RC, RA, 20); | ||
| 620 | S(S4, RB, RE, RD, RC, RA); LK2(RE, RD, RC, RA, RB, 21); | ||
| 621 | S(S5, RE, RD, RC, RA, RB); LK2(RB, RE, RD, RA, RC, 22); | ||
| 622 | S(S6, RB, RE, RD, RA, RC); LK2(RD, RC, RE, RA, RB, 23); | ||
| 623 | S(S7, RD, RC, RE, RA, RB); LK2(RB, RE, RA, RD, RC, 24); | ||
| 624 | S(S0, RB, RE, RA, RD, RC); LK2(RA, RE, RD, RB, RC, 25); | ||
| 625 | S(S1, RA, RE, RD, RB, RC); LK2(RC, RD, RB, RA, RE, 26); | ||
| 626 | S(S2, RC, RD, RB, RA, RE); LK2(RE, RD, RC, RA, RB, 27); | ||
| 627 | S(S3, RE, RD, RC, RA, RB); LK2(RA, RB, RD, RE, RC, 28); | ||
| 628 | S(S4, RA, RB, RD, RE, RC); LK2(RB, RD, RE, RC, RA, 29); | ||
| 629 | S(S5, RB, RD, RE, RC, RA); LK2(RA, RB, RD, RC, RE, 30); | ||
| 630 | S(S6, RA, RB, RD, RC, RE); LK2(RD, RE, RB, RC, RA, 31); | ||
| 631 | S(S7, RD, RE, RB, RC, RA); K2(RA, RB, RC, RD, RE, 32); | ||
| 632 | |||
| 633 | leaq (4*4*4)(%rsi), %rax; | ||
| 634 | |||
| 635 | testb %cl, %cl; | ||
| 636 | jnz __enc_xor8; | ||
| 637 | |||
| 638 | write_blocks(%rsi, RA1, RB1, RC1, RD1, RK0, RK1, RK2); | ||
| 639 | write_blocks(%rax, RA2, RB2, RC2, RD2, RK0, RK1, RK2); | ||
| 640 | |||
| 641 | ret; | ||
| 642 | |||
| 643 | __enc_xor8: | ||
| 644 | xor_blocks(%rsi, RA1, RB1, RC1, RD1, RK0, RK1, RK2); | ||
| 645 | xor_blocks(%rax, RA2, RB2, RC2, RD2, RK0, RK1, RK2); | ||
| 646 | |||
| 647 | ret; | ||
| 648 | |||
| 649 | .align 8 | ||
| 650 | .global serpent_dec_blk_8way_avx | ||
| 651 | .type serpent_dec_blk_8way_avx,@function; | ||
| 652 | |||
| 653 | serpent_dec_blk_8way_avx: | ||
| 654 | /* input: | ||
| 655 | * %rdi: ctx, CTX | ||
| 656 | * %rsi: dst | ||
| 657 | * %rdx: src | ||
| 658 | */ | ||
| 659 | |||
| 660 | vpcmpeqd RNOT, RNOT, RNOT; | ||
| 661 | |||
| 662 | leaq (4*4*4)(%rdx), %rax; | ||
| 663 | read_blocks(%rdx, RA1, RB1, RC1, RD1, RK0, RK1, RK2); | ||
| 664 | read_blocks(%rax, RA2, RB2, RC2, RD2, RK0, RK1, RK2); | ||
| 665 | |||
| 666 | K2(RA, RB, RC, RD, RE, 32); | ||
| 667 | SP(SI7, RA, RB, RC, RD, RE, 31); KL2(RB, RD, RA, RE, RC, 31); | ||
| 668 | SP(SI6, RB, RD, RA, RE, RC, 30); KL2(RA, RC, RE, RB, RD, 30); | ||
| 669 | SP(SI5, RA, RC, RE, RB, RD, 29); KL2(RC, RD, RA, RE, RB, 29); | ||
| 670 | SP(SI4, RC, RD, RA, RE, RB, 28); KL2(RC, RA, RB, RE, RD, 28); | ||
| 671 | SP(SI3, RC, RA, RB, RE, RD, 27); KL2(RB, RC, RD, RE, RA, 27); | ||
| 672 | SP(SI2, RB, RC, RD, RE, RA, 26); KL2(RC, RA, RE, RD, RB, 26); | ||
| 673 | SP(SI1, RC, RA, RE, RD, RB, 25); KL2(RB, RA, RE, RD, RC, 25); | ||
| 674 | SP(SI0, RB, RA, RE, RD, RC, 24); KL2(RE, RC, RA, RB, RD, 24); | ||
| 675 | SP(SI7, RE, RC, RA, RB, RD, 23); KL2(RC, RB, RE, RD, RA, 23); | ||
| 676 | SP(SI6, RC, RB, RE, RD, RA, 22); KL2(RE, RA, RD, RC, RB, 22); | ||
| 677 | SP(SI5, RE, RA, RD, RC, RB, 21); KL2(RA, RB, RE, RD, RC, 21); | ||
| 678 | SP(SI4, RA, RB, RE, RD, RC, 20); KL2(RA, RE, RC, RD, RB, 20); | ||
| 679 | SP(SI3, RA, RE, RC, RD, RB, 19); KL2(RC, RA, RB, RD, RE, 19); | ||
| 680 | SP(SI2, RC, RA, RB, RD, RE, 18); KL2(RA, RE, RD, RB, RC, 18); | ||
| 681 | SP(SI1, RA, RE, RD, RB, RC, 17); KL2(RC, RE, RD, RB, RA, 17); | ||
| 682 | SP(SI0, RC, RE, RD, RB, RA, 16); KL2(RD, RA, RE, RC, RB, 16); | ||
| 683 | SP(SI7, RD, RA, RE, RC, RB, 15); KL2(RA, RC, RD, RB, RE, 15); | ||
| 684 | SP(SI6, RA, RC, RD, RB, RE, 14); KL2(RD, RE, RB, RA, RC, 14); | ||
| 685 | SP(SI5, RD, RE, RB, RA, RC, 13); KL2(RE, RC, RD, RB, RA, 13); | ||
| 686 | SP(SI4, RE, RC, RD, RB, RA, 12); KL2(RE, RD, RA, RB, RC, 12); | ||
| 687 | SP(SI3, RE, RD, RA, RB, RC, 11); KL2(RA, RE, RC, RB, RD, 11); | ||
| 688 | SP(SI2, RA, RE, RC, RB, RD, 10); KL2(RE, RD, RB, RC, RA, 10); | ||
| 689 | SP(SI1, RE, RD, RB, RC, RA, 9); KL2(RA, RD, RB, RC, RE, 9); | ||
| 690 | SP(SI0, RA, RD, RB, RC, RE, 8); KL2(RB, RE, RD, RA, RC, 8); | ||
| 691 | SP(SI7, RB, RE, RD, RA, RC, 7); KL2(RE, RA, RB, RC, RD, 7); | ||
| 692 | SP(SI6, RE, RA, RB, RC, RD, 6); KL2(RB, RD, RC, RE, RA, 6); | ||
| 693 | SP(SI5, RB, RD, RC, RE, RA, 5); KL2(RD, RA, RB, RC, RE, 5); | ||
| 694 | SP(SI4, RD, RA, RB, RC, RE, 4); KL2(RD, RB, RE, RC, RA, 4); | ||
| 695 | SP(SI3, RD, RB, RE, RC, RA, 3); KL2(RE, RD, RA, RC, RB, 3); | ||
| 696 | SP(SI2, RE, RD, RA, RC, RB, 2); KL2(RD, RB, RC, RA, RE, 2); | ||
| 697 | SP(SI1, RD, RB, RC, RA, RE, 1); KL2(RE, RB, RC, RA, RD, 1); | ||
| 698 | S(SI0, RE, RB, RC, RA, RD); K2(RC, RD, RB, RE, RA, 0); | ||
| 699 | |||
| 700 | leaq (4*4*4)(%rsi), %rax; | ||
| 701 | write_blocks(%rsi, RC1, RD1, RB1, RE1, RK0, RK1, RK2); | ||
| 702 | write_blocks(%rax, RC2, RD2, RB2, RE2, RK0, RK1, RK2); | ||
| 703 | |||
| 704 | ret; | ||
diff --git a/arch/x86/crypto/serpent_avx_glue.c b/arch/x86/crypto/serpent_avx_glue.c new file mode 100644 index 000000000000..b36bdac237eb --- /dev/null +++ b/arch/x86/crypto/serpent_avx_glue.c | |||
| @@ -0,0 +1,636 @@ | |||
| 1 | /* | ||
| 2 | * Glue Code for AVX assembler versions of Serpent Cipher | ||
| 3 | * | ||
| 4 | * Copyright (C) 2012 Johannes Goetzfried | ||
| 5 | * <Johannes.Goetzfried@informatik.stud.uni-erlangen.de> | ||
| 6 | * | ||
| 7 | * Glue code based on serpent_sse2_glue.c by: | ||
| 8 | * Copyright (C) 2011 Jussi Kivilinna <jussi.kivilinna@mbnet.fi> | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License as published by | ||
| 12 | * the Free Software Foundation; either version 2 of the License, or | ||
| 13 | * (at your option) any later version. | ||
| 14 | * | ||
| 15 | * This program is distributed in the hope that it will be useful, | ||
| 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 18 | * GNU General Public License for more details. | ||
| 19 | * | ||
| 20 | * You should have received a copy of the GNU General Public License | ||
| 21 | * along with this program; if not, write to the Free Software | ||
| 22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | ||
| 23 | * USA | ||
| 24 | * | ||
| 25 | */ | ||
| 26 | |||
| 27 | #include <linux/module.h> | ||
| 28 | #include <linux/hardirq.h> | ||
| 29 | #include <linux/types.h> | ||
| 30 | #include <linux/crypto.h> | ||
| 31 | #include <linux/err.h> | ||
| 32 | #include <crypto/algapi.h> | ||
| 33 | #include <crypto/serpent.h> | ||
| 34 | #include <crypto/cryptd.h> | ||
| 35 | #include <crypto/b128ops.h> | ||
| 36 | #include <crypto/ctr.h> | ||
| 37 | #include <crypto/lrw.h> | ||
| 38 | #include <crypto/xts.h> | ||
| 39 | #include <asm/xcr.h> | ||
| 40 | #include <asm/xsave.h> | ||
| 41 | #include <asm/crypto/serpent-avx.h> | ||
| 42 | #include <asm/crypto/ablk_helper.h> | ||
| 43 | #include <asm/crypto/glue_helper.h> | ||
| 44 | |||
| 45 | static void serpent_decrypt_cbc_xway(void *ctx, u128 *dst, const u128 *src) | ||
| 46 | { | ||
| 47 | u128 ivs[SERPENT_PARALLEL_BLOCKS - 1]; | ||
| 48 | unsigned int j; | ||
| 49 | |||
| 50 | for (j = 0; j < SERPENT_PARALLEL_BLOCKS - 1; j++) | ||
| 51 | ivs[j] = src[j]; | ||
| 52 | |||
| 53 | serpent_dec_blk_xway(ctx, (u8 *)dst, (u8 *)src); | ||
| 54 | |||
| 55 | for (j = 0; j < SERPENT_PARALLEL_BLOCKS - 1; j++) | ||
| 56 | u128_xor(dst + (j + 1), dst + (j + 1), ivs + j); | ||
| 57 | } | ||
| 58 | |||
| 59 | static void serpent_crypt_ctr(void *ctx, u128 *dst, const u128 *src, u128 *iv) | ||
| 60 | { | ||
| 61 | be128 ctrblk; | ||
| 62 | |||
| 63 | u128_to_be128(&ctrblk, iv); | ||
| 64 | u128_inc(iv); | ||
| 65 | |||
| 66 | __serpent_encrypt(ctx, (u8 *)&ctrblk, (u8 *)&ctrblk); | ||
| 67 | u128_xor(dst, src, (u128 *)&ctrblk); | ||
| 68 | } | ||
| 69 | |||
| 70 | static void serpent_crypt_ctr_xway(void *ctx, u128 *dst, const u128 *src, | ||
| 71 | u128 *iv) | ||
| 72 | { | ||
| 73 | be128 ctrblks[SERPENT_PARALLEL_BLOCKS]; | ||
| 74 | unsigned int i; | ||
| 75 | |||
| 76 | for (i = 0; i < SERPENT_PARALLEL_BLOCKS; i++) { | ||
| 77 | if (dst != src) | ||
| 78 | dst[i] = src[i]; | ||
| 79 | |||
| 80 | u128_to_be128(&ctrblks[i], iv); | ||
| 81 | u128_inc(iv); | ||
| 82 | } | ||
| 83 | |||
| 84 | serpent_enc_blk_xway_xor(ctx, (u8 *)dst, (u8 *)ctrblks); | ||
| 85 | } | ||
| 86 | |||
| 87 | static const struct common_glue_ctx serpent_enc = { | ||
| 88 | .num_funcs = 2, | ||
| 89 | .fpu_blocks_limit = SERPENT_PARALLEL_BLOCKS, | ||
| 90 | |||
| 91 | .funcs = { { | ||
| 92 | .num_blocks = SERPENT_PARALLEL_BLOCKS, | ||
| 93 | .fn_u = { .ecb = GLUE_FUNC_CAST(serpent_enc_blk_xway) } | ||
| 94 | }, { | ||
| 95 | .num_blocks = 1, | ||
| 96 | .fn_u = { .ecb = GLUE_FUNC_CAST(__serpent_encrypt) } | ||
| 97 | } } | ||
| 98 | }; | ||
| 99 | |||
| 100 | static const struct common_glue_ctx serpent_ctr = { | ||
| 101 | .num_funcs = 2, | ||
| 102 | .fpu_blocks_limit = SERPENT_PARALLEL_BLOCKS, | ||
| 103 | |||
| 104 | .funcs = { { | ||
| 105 | .num_blocks = SERPENT_PARALLEL_BLOCKS, | ||
| 106 | .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(serpent_crypt_ctr_xway) } | ||
| 107 | }, { | ||
| 108 | .num_blocks = 1, | ||
| 109 | .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(serpent_crypt_ctr) } | ||
| 110 | } } | ||
| 111 | }; | ||
| 112 | |||
| 113 | static const struct common_glue_ctx serpent_dec = { | ||
| 114 | .num_funcs = 2, | ||
| 115 | .fpu_blocks_limit = SERPENT_PARALLEL_BLOCKS, | ||
| 116 | |||
| 117 | .funcs = { { | ||
| 118 | .num_blocks = SERPENT_PARALLEL_BLOCKS, | ||
| 119 | .fn_u = { .ecb = GLUE_FUNC_CAST(serpent_dec_blk_xway) } | ||
| 120 | }, { | ||
| 121 | .num_blocks = 1, | ||
| 122 | .fn_u = { .ecb = GLUE_FUNC_CAST(__serpent_decrypt) } | ||
| 123 | } } | ||
| 124 | }; | ||
| 125 | |||
| 126 | static const struct common_glue_ctx serpent_dec_cbc = { | ||
| 127 | .num_funcs = 2, | ||
| 128 | .fpu_blocks_limit = SERPENT_PARALLEL_BLOCKS, | ||
| 129 | |||
| 130 | .funcs = { { | ||
| 131 | .num_blocks = SERPENT_PARALLEL_BLOCKS, | ||
| 132 | .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(serpent_decrypt_cbc_xway) } | ||
| 133 | }, { | ||
| 134 | .num_blocks = 1, | ||
| 135 | .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(__serpent_decrypt) } | ||
| 136 | } } | ||
| 137 | }; | ||
| 138 | |||
| 139 | static int ecb_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | ||
| 140 | struct scatterlist *src, unsigned int nbytes) | ||
| 141 | { | ||
| 142 | return glue_ecb_crypt_128bit(&serpent_enc, desc, dst, src, nbytes); | ||
| 143 | } | ||
| 144 | |||
| 145 | static int ecb_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | ||
| 146 | struct scatterlist *src, unsigned int nbytes) | ||
| 147 | { | ||
| 148 | return glue_ecb_crypt_128bit(&serpent_dec, desc, dst, src, nbytes); | ||
| 149 | } | ||
| 150 | |||
| 151 | static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | ||
| 152 | struct scatterlist *src, unsigned int nbytes) | ||
| 153 | { | ||
| 154 | return glue_cbc_encrypt_128bit(GLUE_FUNC_CAST(__serpent_encrypt), desc, | ||
| 155 | dst, src, nbytes); | ||
| 156 | } | ||
| 157 | |||
| 158 | static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | ||
| 159 | struct scatterlist *src, unsigned int nbytes) | ||
| 160 | { | ||
| 161 | return glue_cbc_decrypt_128bit(&serpent_dec_cbc, desc, dst, src, | ||
| 162 | nbytes); | ||
| 163 | } | ||
| 164 | |||
| 165 | static int ctr_crypt(struct blkcipher_desc *desc, struct scatterlist *dst, | ||
| 166 | struct scatterlist *src, unsigned int nbytes) | ||
| 167 | { | ||
| 168 | return glue_ctr_crypt_128bit(&serpent_ctr, desc, dst, src, nbytes); | ||
| 169 | } | ||
| 170 | |||
| 171 | static inline bool serpent_fpu_begin(bool fpu_enabled, unsigned int nbytes) | ||
| 172 | { | ||
| 173 | return glue_fpu_begin(SERPENT_BLOCK_SIZE, SERPENT_PARALLEL_BLOCKS, | ||
| 174 | NULL, fpu_enabled, nbytes); | ||
| 175 | } | ||
| 176 | |||
| 177 | static inline void serpent_fpu_end(bool fpu_enabled) | ||
| 178 | { | ||
| 179 | glue_fpu_end(fpu_enabled); | ||
| 180 | } | ||
| 181 | |||
| 182 | struct crypt_priv { | ||
| 183 | struct serpent_ctx *ctx; | ||
| 184 | bool fpu_enabled; | ||
| 185 | }; | ||
| 186 | |||
| 187 | static void encrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) | ||
| 188 | { | ||
| 189 | const unsigned int bsize = SERPENT_BLOCK_SIZE; | ||
| 190 | struct crypt_priv *ctx = priv; | ||
| 191 | int i; | ||
| 192 | |||
| 193 | ctx->fpu_enabled = serpent_fpu_begin(ctx->fpu_enabled, nbytes); | ||
| 194 | |||
| 195 | if (nbytes == bsize * SERPENT_PARALLEL_BLOCKS) { | ||
| 196 | serpent_enc_blk_xway(ctx->ctx, srcdst, srcdst); | ||
| 197 | return; | ||
| 198 | } | ||
| 199 | |||
| 200 | for (i = 0; i < nbytes / bsize; i++, srcdst += bsize) | ||
| 201 | __serpent_encrypt(ctx->ctx, srcdst, srcdst); | ||
| 202 | } | ||
| 203 | |||
| 204 | static void decrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) | ||
| 205 | { | ||
| 206 | const unsigned int bsize = SERPENT_BLOCK_SIZE; | ||
| 207 | struct crypt_priv *ctx = priv; | ||
| 208 | int i; | ||
| 209 | |||
| 210 | ctx->fpu_enabled = serpent_fpu_begin(ctx->fpu_enabled, nbytes); | ||
| 211 | |||
| 212 | if (nbytes == bsize * SERPENT_PARALLEL_BLOCKS) { | ||
| 213 | serpent_dec_blk_xway(ctx->ctx, srcdst, srcdst); | ||
| 214 | return; | ||
| 215 | } | ||
| 216 | |||
| 217 | for (i = 0; i < nbytes / bsize; i++, srcdst += bsize) | ||
| 218 | __serpent_decrypt(ctx->ctx, srcdst, srcdst); | ||
| 219 | } | ||
| 220 | |||
| 221 | struct serpent_lrw_ctx { | ||
| 222 | struct lrw_table_ctx lrw_table; | ||
| 223 | struct serpent_ctx serpent_ctx; | ||
| 224 | }; | ||
| 225 | |||
| 226 | static int lrw_serpent_setkey(struct crypto_tfm *tfm, const u8 *key, | ||
| 227 | unsigned int keylen) | ||
| 228 | { | ||
| 229 | struct serpent_lrw_ctx *ctx = crypto_tfm_ctx(tfm); | ||
| 230 | int err; | ||
| 231 | |||
| 232 | err = __serpent_setkey(&ctx->serpent_ctx, key, keylen - | ||
| 233 | SERPENT_BLOCK_SIZE); | ||
| 234 | if (err) | ||
| 235 | return err; | ||
| 236 | |||
| 237 | return lrw_init_table(&ctx->lrw_table, key + keylen - | ||
| 238 | SERPENT_BLOCK_SIZE); | ||
| 239 | } | ||
| 240 | |||
| 241 | static int lrw_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | ||
| 242 | struct scatterlist *src, unsigned int nbytes) | ||
| 243 | { | ||
| 244 | struct serpent_lrw_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
| 245 | be128 buf[SERPENT_PARALLEL_BLOCKS]; | ||
| 246 | struct crypt_priv crypt_ctx = { | ||
| 247 | .ctx = &ctx->serpent_ctx, | ||
| 248 | .fpu_enabled = false, | ||
| 249 | }; | ||
| 250 | struct lrw_crypt_req req = { | ||
| 251 | .tbuf = buf, | ||
| 252 | .tbuflen = sizeof(buf), | ||
| 253 | |||
| 254 | .table_ctx = &ctx->lrw_table, | ||
| 255 | .crypt_ctx = &crypt_ctx, | ||
| 256 | .crypt_fn = encrypt_callback, | ||
| 257 | }; | ||
| 258 | int ret; | ||
| 259 | |||
| 260 | desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; | ||
| 261 | ret = lrw_crypt(desc, dst, src, nbytes, &req); | ||
| 262 | serpent_fpu_end(crypt_ctx.fpu_enabled); | ||
| 263 | |||
| 264 | return ret; | ||
| 265 | } | ||
| 266 | |||
| 267 | static int lrw_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | ||
| 268 | struct scatterlist *src, unsigned int nbytes) | ||
| 269 | { | ||
| 270 | struct serpent_lrw_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
| 271 | be128 buf[SERPENT_PARALLEL_BLOCKS]; | ||
| 272 | struct crypt_priv crypt_ctx = { | ||
| 273 | .ctx = &ctx->serpent_ctx, | ||
| 274 | .fpu_enabled = false, | ||
| 275 | }; | ||
| 276 | struct lrw_crypt_req req = { | ||
| 277 | .tbuf = buf, | ||
| 278 | .tbuflen = sizeof(buf), | ||
| 279 | |||
| 280 | .table_ctx = &ctx->lrw_table, | ||
| 281 | .crypt_ctx = &crypt_ctx, | ||
| 282 | .crypt_fn = decrypt_callback, | ||
| 283 | }; | ||
| 284 | int ret; | ||
| 285 | |||
| 286 | desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; | ||
| 287 | ret = lrw_crypt(desc, dst, src, nbytes, &req); | ||
| 288 | serpent_fpu_end(crypt_ctx.fpu_enabled); | ||
| 289 | |||
| 290 | return ret; | ||
| 291 | } | ||
| 292 | |||
| 293 | static void lrw_exit_tfm(struct crypto_tfm *tfm) | ||
| 294 | { | ||
| 295 | struct serpent_lrw_ctx *ctx = crypto_tfm_ctx(tfm); | ||
| 296 | |||
| 297 | lrw_free_table(&ctx->lrw_table); | ||
| 298 | } | ||
| 299 | |||
| 300 | struct serpent_xts_ctx { | ||
| 301 | struct serpent_ctx tweak_ctx; | ||
| 302 | struct serpent_ctx crypt_ctx; | ||
| 303 | }; | ||
| 304 | |||
| 305 | static int xts_serpent_setkey(struct crypto_tfm *tfm, const u8 *key, | ||
| 306 | unsigned int keylen) | ||
| 307 | { | ||
| 308 | struct serpent_xts_ctx *ctx = crypto_tfm_ctx(tfm); | ||
| 309 | u32 *flags = &tfm->crt_flags; | ||
| 310 | int err; | ||
| 311 | |||
| 312 | /* key consists of keys of equal size concatenated, therefore | ||
| 313 | * the length must be even | ||
| 314 | */ | ||
| 315 | if (keylen % 2) { | ||
| 316 | *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; | ||
| 317 | return -EINVAL; | ||
| 318 | } | ||
| 319 | |||
| 320 | /* first half of xts-key is for crypt */ | ||
| 321 | err = __serpent_setkey(&ctx->crypt_ctx, key, keylen / 2); | ||
| 322 | if (err) | ||
| 323 | return err; | ||
| 324 | |||
| 325 | /* second half of xts-key is for tweak */ | ||
| 326 | return __serpent_setkey(&ctx->tweak_ctx, key + keylen / 2, keylen / 2); | ||
| 327 | } | ||
| 328 | |||
| 329 | static int xts_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | ||
| 330 | struct scatterlist *src, unsigned int nbytes) | ||
| 331 | { | ||
| 332 | struct serpent_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
| 333 | be128 buf[SERPENT_PARALLEL_BLOCKS]; | ||
| 334 | struct crypt_priv crypt_ctx = { | ||
| 335 | .ctx = &ctx->crypt_ctx, | ||
| 336 | .fpu_enabled = false, | ||
| 337 | }; | ||
| 338 | struct xts_crypt_req req = { | ||
| 339 | .tbuf = buf, | ||
| 340 | .tbuflen = sizeof(buf), | ||
| 341 | |||
| 342 | .tweak_ctx = &ctx->tweak_ctx, | ||
| 343 | .tweak_fn = XTS_TWEAK_CAST(__serpent_encrypt), | ||
| 344 | .crypt_ctx = &crypt_ctx, | ||
| 345 | .crypt_fn = encrypt_callback, | ||
| 346 | }; | ||
| 347 | int ret; | ||
| 348 | |||
| 349 | desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; | ||
| 350 | ret = xts_crypt(desc, dst, src, nbytes, &req); | ||
| 351 | serpent_fpu_end(crypt_ctx.fpu_enabled); | ||
| 352 | |||
| 353 | return ret; | ||
| 354 | } | ||
| 355 | |||
| 356 | static int xts_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | ||
| 357 | struct scatterlist *src, unsigned int nbytes) | ||
| 358 | { | ||
| 359 | struct serpent_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
| 360 | be128 buf[SERPENT_PARALLEL_BLOCKS]; | ||
| 361 | struct crypt_priv crypt_ctx = { | ||
| 362 | .ctx = &ctx->crypt_ctx, | ||
| 363 | .fpu_enabled = false, | ||
| 364 | }; | ||
| 365 | struct xts_crypt_req req = { | ||
| 366 | .tbuf = buf, | ||
| 367 | .tbuflen = sizeof(buf), | ||
| 368 | |||
| 369 | .tweak_ctx = &ctx->tweak_ctx, | ||
| 370 | .tweak_fn = XTS_TWEAK_CAST(__serpent_encrypt), | ||
| 371 | .crypt_ctx = &crypt_ctx, | ||
| 372 | .crypt_fn = decrypt_callback, | ||
| 373 | }; | ||
| 374 | int ret; | ||
| 375 | |||
| 376 | desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; | ||
| 377 | ret = xts_crypt(desc, dst, src, nbytes, &req); | ||
| 378 | serpent_fpu_end(crypt_ctx.fpu_enabled); | ||
| 379 | |||
| 380 | return ret; | ||
| 381 | } | ||
| 382 | |||
| 383 | static struct crypto_alg serpent_algs[10] = { { | ||
| 384 | .cra_name = "__ecb-serpent-avx", | ||
| 385 | .cra_driver_name = "__driver-ecb-serpent-avx", | ||
| 386 | .cra_priority = 0, | ||
| 387 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, | ||
| 388 | .cra_blocksize = SERPENT_BLOCK_SIZE, | ||
| 389 | .cra_ctxsize = sizeof(struct serpent_ctx), | ||
| 390 | .cra_alignmask = 0, | ||
| 391 | .cra_type = &crypto_blkcipher_type, | ||
| 392 | .cra_module = THIS_MODULE, | ||
| 393 | .cra_list = LIST_HEAD_INIT(serpent_algs[0].cra_list), | ||
| 394 | .cra_u = { | ||
| 395 | .blkcipher = { | ||
| 396 | .min_keysize = SERPENT_MIN_KEY_SIZE, | ||
| 397 | .max_keysize = SERPENT_MAX_KEY_SIZE, | ||
| 398 | .setkey = serpent_setkey, | ||
| 399 | .encrypt = ecb_encrypt, | ||
| 400 | .decrypt = ecb_decrypt, | ||
| 401 | }, | ||
| 402 | }, | ||
| 403 | }, { | ||
| 404 | .cra_name = "__cbc-serpent-avx", | ||
| 405 | .cra_driver_name = "__driver-cbc-serpent-avx", | ||
| 406 | .cra_priority = 0, | ||
| 407 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, | ||
| 408 | .cra_blocksize = SERPENT_BLOCK_SIZE, | ||
| 409 | .cra_ctxsize = sizeof(struct serpent_ctx), | ||
| 410 | .cra_alignmask = 0, | ||
| 411 | .cra_type = &crypto_blkcipher_type, | ||
| 412 | .cra_module = THIS_MODULE, | ||
| 413 | .cra_list = LIST_HEAD_INIT(serpent_algs[1].cra_list), | ||
| 414 | .cra_u = { | ||
| 415 | .blkcipher = { | ||
| 416 | .min_keysize = SERPENT_MIN_KEY_SIZE, | ||
| 417 | .max_keysize = SERPENT_MAX_KEY_SIZE, | ||
| 418 | .setkey = serpent_setkey, | ||
| 419 | .encrypt = cbc_encrypt, | ||
| 420 | .decrypt = cbc_decrypt, | ||
| 421 | }, | ||
| 422 | }, | ||
| 423 | }, { | ||
| 424 | .cra_name = "__ctr-serpent-avx", | ||
| 425 | .cra_driver_name = "__driver-ctr-serpent-avx", | ||
| 426 | .cra_priority = 0, | ||
| 427 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, | ||
| 428 | .cra_blocksize = 1, | ||
| 429 | .cra_ctxsize = sizeof(struct serpent_ctx), | ||
| 430 | .cra_alignmask = 0, | ||
| 431 | .cra_type = &crypto_blkcipher_type, | ||
| 432 | .cra_module = THIS_MODULE, | ||
| 433 | .cra_list = LIST_HEAD_INIT(serpent_algs[2].cra_list), | ||
| 434 | .cra_u = { | ||
| 435 | .blkcipher = { | ||
| 436 | .min_keysize = SERPENT_MIN_KEY_SIZE, | ||
| 437 | .max_keysize = SERPENT_MAX_KEY_SIZE, | ||
| 438 | .ivsize = SERPENT_BLOCK_SIZE, | ||
| 439 | .setkey = serpent_setkey, | ||
| 440 | .encrypt = ctr_crypt, | ||
| 441 | .decrypt = ctr_crypt, | ||
| 442 | }, | ||
| 443 | }, | ||
| 444 | }, { | ||
| 445 | .cra_name = "__lrw-serpent-avx", | ||
| 446 | .cra_driver_name = "__driver-lrw-serpent-avx", | ||
| 447 | .cra_priority = 0, | ||
| 448 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, | ||
| 449 | .cra_blocksize = SERPENT_BLOCK_SIZE, | ||
| 450 | .cra_ctxsize = sizeof(struct serpent_lrw_ctx), | ||
| 451 | .cra_alignmask = 0, | ||
| 452 | .cra_type = &crypto_blkcipher_type, | ||
| 453 | .cra_module = THIS_MODULE, | ||
| 454 | .cra_list = LIST_HEAD_INIT(serpent_algs[3].cra_list), | ||
| 455 | .cra_exit = lrw_exit_tfm, | ||
| 456 | .cra_u = { | ||
| 457 | .blkcipher = { | ||
| 458 | .min_keysize = SERPENT_MIN_KEY_SIZE + | ||
| 459 | SERPENT_BLOCK_SIZE, | ||
| 460 | .max_keysize = SERPENT_MAX_KEY_SIZE + | ||
| 461 | SERPENT_BLOCK_SIZE, | ||
| 462 | .ivsize = SERPENT_BLOCK_SIZE, | ||
| 463 | .setkey = lrw_serpent_setkey, | ||
| 464 | .encrypt = lrw_encrypt, | ||
| 465 | .decrypt = lrw_decrypt, | ||
| 466 | }, | ||
| 467 | }, | ||
| 468 | }, { | ||
| 469 | .cra_name = "__xts-serpent-avx", | ||
| 470 | .cra_driver_name = "__driver-xts-serpent-avx", | ||
| 471 | .cra_priority = 0, | ||
| 472 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, | ||
| 473 | .cra_blocksize = SERPENT_BLOCK_SIZE, | ||
| 474 | .cra_ctxsize = sizeof(struct serpent_xts_ctx), | ||
| 475 | .cra_alignmask = 0, | ||
| 476 | .cra_type = &crypto_blkcipher_type, | ||
| 477 | .cra_module = THIS_MODULE, | ||
| 478 | .cra_list = LIST_HEAD_INIT(serpent_algs[4].cra_list), | ||
| 479 | .cra_u = { | ||
| 480 | .blkcipher = { | ||
| 481 | .min_keysize = SERPENT_MIN_KEY_SIZE * 2, | ||
| 482 | .max_keysize = SERPENT_MAX_KEY_SIZE * 2, | ||
| 483 | .ivsize = SERPENT_BLOCK_SIZE, | ||
| 484 | .setkey = xts_serpent_setkey, | ||
| 485 | .encrypt = xts_encrypt, | ||
| 486 | .decrypt = xts_decrypt, | ||
| 487 | }, | ||
| 488 | }, | ||
| 489 | }, { | ||
| 490 | .cra_name = "ecb(serpent)", | ||
| 491 | .cra_driver_name = "ecb-serpent-avx", | ||
| 492 | .cra_priority = 500, | ||
| 493 | .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, | ||
| 494 | .cra_blocksize = SERPENT_BLOCK_SIZE, | ||
| 495 | .cra_ctxsize = sizeof(struct async_helper_ctx), | ||
| 496 | .cra_alignmask = 0, | ||
| 497 | .cra_type = &crypto_ablkcipher_type, | ||
| 498 | .cra_module = THIS_MODULE, | ||
| 499 | .cra_list = LIST_HEAD_INIT(serpent_algs[5].cra_list), | ||
| 500 | .cra_init = ablk_init, | ||
| 501 | .cra_exit = ablk_exit, | ||
| 502 | .cra_u = { | ||
| 503 | .ablkcipher = { | ||
| 504 | .min_keysize = SERPENT_MIN_KEY_SIZE, | ||
| 505 | .max_keysize = SERPENT_MAX_KEY_SIZE, | ||
| 506 | .setkey = ablk_set_key, | ||
| 507 | .encrypt = ablk_encrypt, | ||
| 508 | .decrypt = ablk_decrypt, | ||
| 509 | }, | ||
| 510 | }, | ||
| 511 | }, { | ||
| 512 | .cra_name = "cbc(serpent)", | ||
| 513 | .cra_driver_name = "cbc-serpent-avx", | ||
| 514 | .cra_priority = 500, | ||
| 515 | .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, | ||
| 516 | .cra_blocksize = SERPENT_BLOCK_SIZE, | ||
| 517 | .cra_ctxsize = sizeof(struct async_helper_ctx), | ||
| 518 | .cra_alignmask = 0, | ||
| 519 | .cra_type = &crypto_ablkcipher_type, | ||
| 520 | .cra_module = THIS_MODULE, | ||
| 521 | .cra_list = LIST_HEAD_INIT(serpent_algs[6].cra_list), | ||
| 522 | .cra_init = ablk_init, | ||
| 523 | .cra_exit = ablk_exit, | ||
| 524 | .cra_u = { | ||
| 525 | .ablkcipher = { | ||
| 526 | .min_keysize = SERPENT_MIN_KEY_SIZE, | ||
| 527 | .max_keysize = SERPENT_MAX_KEY_SIZE, | ||
| 528 | .ivsize = SERPENT_BLOCK_SIZE, | ||
| 529 | .setkey = ablk_set_key, | ||
| 530 | .encrypt = __ablk_encrypt, | ||
| 531 | .decrypt = ablk_decrypt, | ||
| 532 | }, | ||
| 533 | }, | ||
| 534 | }, { | ||
| 535 | .cra_name = "ctr(serpent)", | ||
| 536 | .cra_driver_name = "ctr-serpent-avx", | ||
| 537 | .cra_priority = 500, | ||
| 538 | .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, | ||
| 539 | .cra_blocksize = 1, | ||
| 540 | .cra_ctxsize = sizeof(struct async_helper_ctx), | ||
| 541 | .cra_alignmask = 0, | ||
| 542 | .cra_type = &crypto_ablkcipher_type, | ||
| 543 | .cra_module = THIS_MODULE, | ||
| 544 | .cra_list = LIST_HEAD_INIT(serpent_algs[7].cra_list), | ||
| 545 | .cra_init = ablk_init, | ||
| 546 | .cra_exit = ablk_exit, | ||
| 547 | .cra_u = { | ||
| 548 | .ablkcipher = { | ||
| 549 | .min_keysize = SERPENT_MIN_KEY_SIZE, | ||
| 550 | .max_keysize = SERPENT_MAX_KEY_SIZE, | ||
| 551 | .ivsize = SERPENT_BLOCK_SIZE, | ||
| 552 | .setkey = ablk_set_key, | ||
| 553 | .encrypt = ablk_encrypt, | ||
| 554 | .decrypt = ablk_encrypt, | ||
| 555 | .geniv = "chainiv", | ||
| 556 | }, | ||
| 557 | }, | ||
| 558 | }, { | ||
| 559 | .cra_name = "lrw(serpent)", | ||
| 560 | .cra_driver_name = "lrw-serpent-avx", | ||
| 561 | .cra_priority = 500, | ||
| 562 | .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, | ||
| 563 | .cra_blocksize = SERPENT_BLOCK_SIZE, | ||
| 564 | .cra_ctxsize = sizeof(struct async_helper_ctx), | ||
| 565 | .cra_alignmask = 0, | ||
| 566 | .cra_type = &crypto_ablkcipher_type, | ||
| 567 | .cra_module = THIS_MODULE, | ||
| 568 | .cra_list = LIST_HEAD_INIT(serpent_algs[8].cra_list), | ||
| 569 | .cra_init = ablk_init, | ||
| 570 | .cra_exit = ablk_exit, | ||
| 571 | .cra_u = { | ||
| 572 | .ablkcipher = { | ||
| 573 | .min_keysize = SERPENT_MIN_KEY_SIZE + | ||
| 574 | SERPENT_BLOCK_SIZE, | ||
| 575 | .max_keysize = SERPENT_MAX_KEY_SIZE + | ||
| 576 | SERPENT_BLOCK_SIZE, | ||
| 577 | .ivsize = SERPENT_BLOCK_SIZE, | ||
| 578 | .setkey = ablk_set_key, | ||
| 579 | .encrypt = ablk_encrypt, | ||
| 580 | .decrypt = ablk_decrypt, | ||
| 581 | }, | ||
| 582 | }, | ||
| 583 | }, { | ||
| 584 | .cra_name = "xts(serpent)", | ||
| 585 | .cra_driver_name = "xts-serpent-avx", | ||
| 586 | .cra_priority = 500, | ||
| 587 | .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, | ||
| 588 | .cra_blocksize = SERPENT_BLOCK_SIZE, | ||
| 589 | .cra_ctxsize = sizeof(struct async_helper_ctx), | ||
| 590 | .cra_alignmask = 0, | ||
| 591 | .cra_type = &crypto_ablkcipher_type, | ||
| 592 | .cra_module = THIS_MODULE, | ||
| 593 | .cra_list = LIST_HEAD_INIT(serpent_algs[9].cra_list), | ||
| 594 | .cra_init = ablk_init, | ||
| 595 | .cra_exit = ablk_exit, | ||
| 596 | .cra_u = { | ||
| 597 | .ablkcipher = { | ||
| 598 | .min_keysize = SERPENT_MIN_KEY_SIZE * 2, | ||
| 599 | .max_keysize = SERPENT_MAX_KEY_SIZE * 2, | ||
| 600 | .ivsize = SERPENT_BLOCK_SIZE, | ||
| 601 | .setkey = ablk_set_key, | ||
| 602 | .encrypt = ablk_encrypt, | ||
| 603 | .decrypt = ablk_decrypt, | ||
| 604 | }, | ||
| 605 | }, | ||
| 606 | } }; | ||
| 607 | |||
| 608 | static int __init serpent_init(void) | ||
| 609 | { | ||
| 610 | u64 xcr0; | ||
| 611 | |||
| 612 | if (!cpu_has_avx || !cpu_has_osxsave) { | ||
| 613 | printk(KERN_INFO "AVX instructions are not detected.\n"); | ||
| 614 | return -ENODEV; | ||
| 615 | } | ||
| 616 | |||
| 617 | xcr0 = xgetbv(XCR_XFEATURE_ENABLED_MASK); | ||
| 618 | if ((xcr0 & (XSTATE_SSE | XSTATE_YMM)) != (XSTATE_SSE | XSTATE_YMM)) { | ||
| 619 | printk(KERN_INFO "AVX detected but unusable.\n"); | ||
| 620 | return -ENODEV; | ||
| 621 | } | ||
| 622 | |||
| 623 | return crypto_register_algs(serpent_algs, ARRAY_SIZE(serpent_algs)); | ||
| 624 | } | ||
| 625 | |||
| 626 | static void __exit serpent_exit(void) | ||
| 627 | { | ||
| 628 | crypto_unregister_algs(serpent_algs, ARRAY_SIZE(serpent_algs)); | ||
| 629 | } | ||
| 630 | |||
| 631 | module_init(serpent_init); | ||
| 632 | module_exit(serpent_exit); | ||
| 633 | |||
| 634 | MODULE_DESCRIPTION("Serpent Cipher Algorithm, AVX optimized"); | ||
| 635 | MODULE_LICENSE("GPL"); | ||
| 636 | MODULE_ALIAS("serpent"); | ||
diff --git a/arch/x86/crypto/serpent_sse2_glue.c b/arch/x86/crypto/serpent_sse2_glue.c index 4b21be85e0a1..d679c8675f4a 100644 --- a/arch/x86/crypto/serpent_sse2_glue.c +++ b/arch/x86/crypto/serpent_sse2_glue.c | |||
| @@ -41,358 +41,145 @@ | |||
| 41 | #include <crypto/ctr.h> | 41 | #include <crypto/ctr.h> |
| 42 | #include <crypto/lrw.h> | 42 | #include <crypto/lrw.h> |
| 43 | #include <crypto/xts.h> | 43 | #include <crypto/xts.h> |
| 44 | #include <asm/i387.h> | 44 | #include <asm/crypto/serpent-sse2.h> |
| 45 | #include <asm/serpent.h> | 45 | #include <asm/crypto/ablk_helper.h> |
| 46 | #include <crypto/scatterwalk.h> | 46 | #include <asm/crypto/glue_helper.h> |
| 47 | #include <linux/workqueue.h> | ||
| 48 | #include <linux/spinlock.h> | ||
| 49 | |||
| 50 | struct async_serpent_ctx { | ||
| 51 | struct cryptd_ablkcipher *cryptd_tfm; | ||
| 52 | }; | ||
| 53 | 47 | ||
| 54 | static inline bool serpent_fpu_begin(bool fpu_enabled, unsigned int nbytes) | 48 | static void serpent_decrypt_cbc_xway(void *ctx, u128 *dst, const u128 *src) |
| 55 | { | ||
| 56 | if (fpu_enabled) | ||
| 57 | return true; | ||
| 58 | |||
| 59 | /* SSE2 is only used when chunk to be processed is large enough, so | ||
| 60 | * do not enable FPU until it is necessary. | ||
| 61 | */ | ||
| 62 | if (nbytes < SERPENT_BLOCK_SIZE * SERPENT_PARALLEL_BLOCKS) | ||
| 63 | return false; | ||
| 64 | |||
| 65 | kernel_fpu_begin(); | ||
| 66 | return true; | ||
| 67 | } | ||
| 68 | |||
| 69 | static inline void serpent_fpu_end(bool fpu_enabled) | ||
| 70 | { | 49 | { |
| 71 | if (fpu_enabled) | 50 | u128 ivs[SERPENT_PARALLEL_BLOCKS - 1]; |
| 72 | kernel_fpu_end(); | 51 | unsigned int j; |
| 73 | } | ||
| 74 | |||
| 75 | static int ecb_crypt(struct blkcipher_desc *desc, struct blkcipher_walk *walk, | ||
| 76 | bool enc) | ||
| 77 | { | ||
| 78 | bool fpu_enabled = false; | ||
| 79 | struct serpent_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
| 80 | const unsigned int bsize = SERPENT_BLOCK_SIZE; | ||
| 81 | unsigned int nbytes; | ||
| 82 | int err; | ||
| 83 | |||
| 84 | err = blkcipher_walk_virt(desc, walk); | ||
| 85 | desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; | ||
| 86 | |||
| 87 | while ((nbytes = walk->nbytes)) { | ||
| 88 | u8 *wsrc = walk->src.virt.addr; | ||
| 89 | u8 *wdst = walk->dst.virt.addr; | ||
| 90 | |||
| 91 | fpu_enabled = serpent_fpu_begin(fpu_enabled, nbytes); | ||
| 92 | |||
| 93 | /* Process multi-block batch */ | ||
| 94 | if (nbytes >= bsize * SERPENT_PARALLEL_BLOCKS) { | ||
| 95 | do { | ||
| 96 | if (enc) | ||
| 97 | serpent_enc_blk_xway(ctx, wdst, wsrc); | ||
| 98 | else | ||
| 99 | serpent_dec_blk_xway(ctx, wdst, wsrc); | ||
| 100 | |||
| 101 | wsrc += bsize * SERPENT_PARALLEL_BLOCKS; | ||
| 102 | wdst += bsize * SERPENT_PARALLEL_BLOCKS; | ||
| 103 | nbytes -= bsize * SERPENT_PARALLEL_BLOCKS; | ||
| 104 | } while (nbytes >= bsize * SERPENT_PARALLEL_BLOCKS); | ||
| 105 | |||
| 106 | if (nbytes < bsize) | ||
| 107 | goto done; | ||
| 108 | } | ||
| 109 | |||
| 110 | /* Handle leftovers */ | ||
| 111 | do { | ||
| 112 | if (enc) | ||
| 113 | __serpent_encrypt(ctx, wdst, wsrc); | ||
| 114 | else | ||
| 115 | __serpent_decrypt(ctx, wdst, wsrc); | ||
| 116 | |||
| 117 | wsrc += bsize; | ||
| 118 | wdst += bsize; | ||
| 119 | nbytes -= bsize; | ||
| 120 | } while (nbytes >= bsize); | ||
| 121 | |||
| 122 | done: | ||
| 123 | err = blkcipher_walk_done(desc, walk, nbytes); | ||
| 124 | } | ||
| 125 | 52 | ||
| 126 | serpent_fpu_end(fpu_enabled); | 53 | for (j = 0; j < SERPENT_PARALLEL_BLOCKS - 1; j++) |
| 127 | return err; | 54 | ivs[j] = src[j]; |
| 128 | } | ||
| 129 | 55 | ||
| 130 | static int ecb_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | 56 | serpent_dec_blk_xway(ctx, (u8 *)dst, (u8 *)src); |
| 131 | struct scatterlist *src, unsigned int nbytes) | ||
| 132 | { | ||
| 133 | struct blkcipher_walk walk; | ||
| 134 | 57 | ||
| 135 | blkcipher_walk_init(&walk, dst, src, nbytes); | 58 | for (j = 0; j < SERPENT_PARALLEL_BLOCKS - 1; j++) |
| 136 | return ecb_crypt(desc, &walk, true); | 59 | u128_xor(dst + (j + 1), dst + (j + 1), ivs + j); |
| 137 | } | 60 | } |
| 138 | 61 | ||
| 139 | static int ecb_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | 62 | static void serpent_crypt_ctr(void *ctx, u128 *dst, const u128 *src, u128 *iv) |
| 140 | struct scatterlist *src, unsigned int nbytes) | ||
| 141 | { | 63 | { |
| 142 | struct blkcipher_walk walk; | 64 | be128 ctrblk; |
| 143 | 65 | ||
| 144 | blkcipher_walk_init(&walk, dst, src, nbytes); | 66 | u128_to_be128(&ctrblk, iv); |
| 145 | return ecb_crypt(desc, &walk, false); | 67 | u128_inc(iv); |
| 146 | } | ||
| 147 | 68 | ||
| 148 | static unsigned int __cbc_encrypt(struct blkcipher_desc *desc, | 69 | __serpent_encrypt(ctx, (u8 *)&ctrblk, (u8 *)&ctrblk); |
| 149 | struct blkcipher_walk *walk) | 70 | u128_xor(dst, src, (u128 *)&ctrblk); |
| 150 | { | ||
| 151 | struct serpent_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
| 152 | const unsigned int bsize = SERPENT_BLOCK_SIZE; | ||
| 153 | unsigned int nbytes = walk->nbytes; | ||
| 154 | u128 *src = (u128 *)walk->src.virt.addr; | ||
| 155 | u128 *dst = (u128 *)walk->dst.virt.addr; | ||
| 156 | u128 *iv = (u128 *)walk->iv; | ||
| 157 | |||
| 158 | do { | ||
| 159 | u128_xor(dst, src, iv); | ||
| 160 | __serpent_encrypt(ctx, (u8 *)dst, (u8 *)dst); | ||
| 161 | iv = dst; | ||
| 162 | |||
| 163 | src += 1; | ||
| 164 | dst += 1; | ||
| 165 | nbytes -= bsize; | ||
| 166 | } while (nbytes >= bsize); | ||
| 167 | |||
| 168 | u128_xor((u128 *)walk->iv, (u128 *)walk->iv, iv); | ||
| 169 | return nbytes; | ||
| 170 | } | 71 | } |
| 171 | 72 | ||
| 172 | static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | 73 | static void serpent_crypt_ctr_xway(void *ctx, u128 *dst, const u128 *src, |
| 173 | struct scatterlist *src, unsigned int nbytes) | 74 | u128 *iv) |
| 174 | { | 75 | { |
| 175 | struct blkcipher_walk walk; | 76 | be128 ctrblks[SERPENT_PARALLEL_BLOCKS]; |
| 176 | int err; | 77 | unsigned int i; |
| 177 | 78 | ||
| 178 | blkcipher_walk_init(&walk, dst, src, nbytes); | 79 | for (i = 0; i < SERPENT_PARALLEL_BLOCKS; i++) { |
| 179 | err = blkcipher_walk_virt(desc, &walk); | 80 | if (dst != src) |
| 81 | dst[i] = src[i]; | ||
| 180 | 82 | ||
| 181 | while ((nbytes = walk.nbytes)) { | 83 | u128_to_be128(&ctrblks[i], iv); |
| 182 | nbytes = __cbc_encrypt(desc, &walk); | 84 | u128_inc(iv); |
| 183 | err = blkcipher_walk_done(desc, &walk, nbytes); | ||
| 184 | } | 85 | } |
| 185 | 86 | ||
| 186 | return err; | 87 | serpent_enc_blk_xway_xor(ctx, (u8 *)dst, (u8 *)ctrblks); |
| 187 | } | 88 | } |
| 188 | 89 | ||
| 189 | static unsigned int __cbc_decrypt(struct blkcipher_desc *desc, | 90 | static const struct common_glue_ctx serpent_enc = { |
| 190 | struct blkcipher_walk *walk) | 91 | .num_funcs = 2, |
| 191 | { | 92 | .fpu_blocks_limit = SERPENT_PARALLEL_BLOCKS, |
| 192 | struct serpent_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
| 193 | const unsigned int bsize = SERPENT_BLOCK_SIZE; | ||
| 194 | unsigned int nbytes = walk->nbytes; | ||
| 195 | u128 *src = (u128 *)walk->src.virt.addr; | ||
| 196 | u128 *dst = (u128 *)walk->dst.virt.addr; | ||
| 197 | u128 ivs[SERPENT_PARALLEL_BLOCKS - 1]; | ||
| 198 | u128 last_iv; | ||
| 199 | int i; | ||
| 200 | |||
| 201 | /* Start of the last block. */ | ||
| 202 | src += nbytes / bsize - 1; | ||
| 203 | dst += nbytes / bsize - 1; | ||
| 204 | |||
| 205 | last_iv = *src; | ||
| 206 | |||
| 207 | /* Process multi-block batch */ | ||
| 208 | if (nbytes >= bsize * SERPENT_PARALLEL_BLOCKS) { | ||
| 209 | do { | ||
| 210 | nbytes -= bsize * (SERPENT_PARALLEL_BLOCKS - 1); | ||
| 211 | src -= SERPENT_PARALLEL_BLOCKS - 1; | ||
| 212 | dst -= SERPENT_PARALLEL_BLOCKS - 1; | ||
| 213 | |||
| 214 | for (i = 0; i < SERPENT_PARALLEL_BLOCKS - 1; i++) | ||
| 215 | ivs[i] = src[i]; | ||
| 216 | |||
| 217 | serpent_dec_blk_xway(ctx, (u8 *)dst, (u8 *)src); | ||
| 218 | |||
| 219 | for (i = 0; i < SERPENT_PARALLEL_BLOCKS - 1; i++) | ||
| 220 | u128_xor(dst + (i + 1), dst + (i + 1), ivs + i); | ||
| 221 | |||
| 222 | nbytes -= bsize; | ||
| 223 | if (nbytes < bsize) | ||
| 224 | goto done; | ||
| 225 | 93 | ||
| 226 | u128_xor(dst, dst, src - 1); | 94 | .funcs = { { |
| 227 | src -= 1; | 95 | .num_blocks = SERPENT_PARALLEL_BLOCKS, |
| 228 | dst -= 1; | 96 | .fn_u = { .ecb = GLUE_FUNC_CAST(serpent_enc_blk_xway) } |
| 229 | } while (nbytes >= bsize * SERPENT_PARALLEL_BLOCKS); | 97 | }, { |
| 230 | 98 | .num_blocks = 1, | |
| 231 | if (nbytes < bsize) | 99 | .fn_u = { .ecb = GLUE_FUNC_CAST(__serpent_encrypt) } |
| 232 | goto done; | 100 | } } |
| 233 | } | 101 | }; |
| 234 | |||
| 235 | /* Handle leftovers */ | ||
| 236 | for (;;) { | ||
| 237 | __serpent_decrypt(ctx, (u8 *)dst, (u8 *)src); | ||
| 238 | |||
| 239 | nbytes -= bsize; | ||
| 240 | if (nbytes < bsize) | ||
| 241 | break; | ||
| 242 | 102 | ||
| 243 | u128_xor(dst, dst, src - 1); | 103 | static const struct common_glue_ctx serpent_ctr = { |
| 244 | src -= 1; | 104 | .num_funcs = 2, |
| 245 | dst -= 1; | 105 | .fpu_blocks_limit = SERPENT_PARALLEL_BLOCKS, |
| 246 | } | 106 | |
| 107 | .funcs = { { | ||
| 108 | .num_blocks = SERPENT_PARALLEL_BLOCKS, | ||
| 109 | .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(serpent_crypt_ctr_xway) } | ||
| 110 | }, { | ||
| 111 | .num_blocks = 1, | ||
| 112 | .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(serpent_crypt_ctr) } | ||
| 113 | } } | ||
| 114 | }; | ||
| 247 | 115 | ||
| 248 | done: | 116 | static const struct common_glue_ctx serpent_dec = { |
| 249 | u128_xor(dst, dst, (u128 *)walk->iv); | 117 | .num_funcs = 2, |
| 250 | *(u128 *)walk->iv = last_iv; | 118 | .fpu_blocks_limit = SERPENT_PARALLEL_BLOCKS, |
| 119 | |||
| 120 | .funcs = { { | ||
| 121 | .num_blocks = SERPENT_PARALLEL_BLOCKS, | ||
| 122 | .fn_u = { .ecb = GLUE_FUNC_CAST(serpent_dec_blk_xway) } | ||
| 123 | }, { | ||
| 124 | .num_blocks = 1, | ||
| 125 | .fn_u = { .ecb = GLUE_FUNC_CAST(__serpent_decrypt) } | ||
| 126 | } } | ||
| 127 | }; | ||
| 251 | 128 | ||
| 252 | return nbytes; | 129 | static const struct common_glue_ctx serpent_dec_cbc = { |
| 253 | } | 130 | .num_funcs = 2, |
| 131 | .fpu_blocks_limit = SERPENT_PARALLEL_BLOCKS, | ||
| 132 | |||
| 133 | .funcs = { { | ||
| 134 | .num_blocks = SERPENT_PARALLEL_BLOCKS, | ||
| 135 | .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(serpent_decrypt_cbc_xway) } | ||
| 136 | }, { | ||
| 137 | .num_blocks = 1, | ||
| 138 | .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(__serpent_decrypt) } | ||
| 139 | } } | ||
| 140 | }; | ||
| 254 | 141 | ||
| 255 | static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | 142 | static int ecb_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, |
| 256 | struct scatterlist *src, unsigned int nbytes) | 143 | struct scatterlist *src, unsigned int nbytes) |
| 257 | { | 144 | { |
| 258 | bool fpu_enabled = false; | 145 | return glue_ecb_crypt_128bit(&serpent_enc, desc, dst, src, nbytes); |
| 259 | struct blkcipher_walk walk; | ||
| 260 | int err; | ||
| 261 | |||
| 262 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
| 263 | err = blkcipher_walk_virt(desc, &walk); | ||
| 264 | desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; | ||
| 265 | |||
| 266 | while ((nbytes = walk.nbytes)) { | ||
| 267 | fpu_enabled = serpent_fpu_begin(fpu_enabled, nbytes); | ||
| 268 | nbytes = __cbc_decrypt(desc, &walk); | ||
| 269 | err = blkcipher_walk_done(desc, &walk, nbytes); | ||
| 270 | } | ||
| 271 | |||
| 272 | serpent_fpu_end(fpu_enabled); | ||
| 273 | return err; | ||
| 274 | } | 146 | } |
| 275 | 147 | ||
| 276 | static inline void u128_to_be128(be128 *dst, const u128 *src) | 148 | static int ecb_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, |
| 149 | struct scatterlist *src, unsigned int nbytes) | ||
| 277 | { | 150 | { |
| 278 | dst->a = cpu_to_be64(src->a); | 151 | return glue_ecb_crypt_128bit(&serpent_dec, desc, dst, src, nbytes); |
| 279 | dst->b = cpu_to_be64(src->b); | ||
| 280 | } | 152 | } |
| 281 | 153 | ||
| 282 | static inline void be128_to_u128(u128 *dst, const be128 *src) | 154 | static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, |
| 155 | struct scatterlist *src, unsigned int nbytes) | ||
| 283 | { | 156 | { |
| 284 | dst->a = be64_to_cpu(src->a); | 157 | return glue_cbc_encrypt_128bit(GLUE_FUNC_CAST(__serpent_encrypt), desc, |
| 285 | dst->b = be64_to_cpu(src->b); | 158 | dst, src, nbytes); |
| 286 | } | 159 | } |
| 287 | 160 | ||
| 288 | static inline void u128_inc(u128 *i) | 161 | static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, |
| 162 | struct scatterlist *src, unsigned int nbytes) | ||
| 289 | { | 163 | { |
| 290 | i->b++; | 164 | return glue_cbc_decrypt_128bit(&serpent_dec_cbc, desc, dst, src, |
| 291 | if (!i->b) | 165 | nbytes); |
| 292 | i->a++; | ||
| 293 | } | 166 | } |
| 294 | 167 | ||
| 295 | static void ctr_crypt_final(struct blkcipher_desc *desc, | 168 | static int ctr_crypt(struct blkcipher_desc *desc, struct scatterlist *dst, |
| 296 | struct blkcipher_walk *walk) | 169 | struct scatterlist *src, unsigned int nbytes) |
| 297 | { | 170 | { |
| 298 | struct serpent_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | 171 | return glue_ctr_crypt_128bit(&serpent_ctr, desc, dst, src, nbytes); |
| 299 | u8 *ctrblk = walk->iv; | ||
| 300 | u8 keystream[SERPENT_BLOCK_SIZE]; | ||
| 301 | u8 *src = walk->src.virt.addr; | ||
| 302 | u8 *dst = walk->dst.virt.addr; | ||
| 303 | unsigned int nbytes = walk->nbytes; | ||
| 304 | |||
| 305 | __serpent_encrypt(ctx, keystream, ctrblk); | ||
| 306 | crypto_xor(keystream, src, nbytes); | ||
| 307 | memcpy(dst, keystream, nbytes); | ||
| 308 | |||
| 309 | crypto_inc(ctrblk, SERPENT_BLOCK_SIZE); | ||
| 310 | } | 172 | } |
| 311 | 173 | ||
| 312 | static unsigned int __ctr_crypt(struct blkcipher_desc *desc, | 174 | static inline bool serpent_fpu_begin(bool fpu_enabled, unsigned int nbytes) |
| 313 | struct blkcipher_walk *walk) | ||
| 314 | { | 175 | { |
| 315 | struct serpent_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | 176 | return glue_fpu_begin(SERPENT_BLOCK_SIZE, SERPENT_PARALLEL_BLOCKS, |
| 316 | const unsigned int bsize = SERPENT_BLOCK_SIZE; | 177 | NULL, fpu_enabled, nbytes); |
| 317 | unsigned int nbytes = walk->nbytes; | ||
| 318 | u128 *src = (u128 *)walk->src.virt.addr; | ||
| 319 | u128 *dst = (u128 *)walk->dst.virt.addr; | ||
| 320 | u128 ctrblk; | ||
| 321 | be128 ctrblocks[SERPENT_PARALLEL_BLOCKS]; | ||
| 322 | int i; | ||
| 323 | |||
| 324 | be128_to_u128(&ctrblk, (be128 *)walk->iv); | ||
| 325 | |||
| 326 | /* Process multi-block batch */ | ||
| 327 | if (nbytes >= bsize * SERPENT_PARALLEL_BLOCKS) { | ||
| 328 | do { | ||
| 329 | /* create ctrblks for parallel encrypt */ | ||
| 330 | for (i = 0; i < SERPENT_PARALLEL_BLOCKS; i++) { | ||
| 331 | if (dst != src) | ||
| 332 | dst[i] = src[i]; | ||
| 333 | |||
| 334 | u128_to_be128(&ctrblocks[i], &ctrblk); | ||
| 335 | u128_inc(&ctrblk); | ||
| 336 | } | ||
| 337 | |||
| 338 | serpent_enc_blk_xway_xor(ctx, (u8 *)dst, | ||
| 339 | (u8 *)ctrblocks); | ||
| 340 | |||
| 341 | src += SERPENT_PARALLEL_BLOCKS; | ||
| 342 | dst += SERPENT_PARALLEL_BLOCKS; | ||
| 343 | nbytes -= bsize * SERPENT_PARALLEL_BLOCKS; | ||
| 344 | } while (nbytes >= bsize * SERPENT_PARALLEL_BLOCKS); | ||
| 345 | |||
| 346 | if (nbytes < bsize) | ||
| 347 | goto done; | ||
| 348 | } | ||
| 349 | |||
| 350 | /* Handle leftovers */ | ||
| 351 | do { | ||
| 352 | if (dst != src) | ||
| 353 | *dst = *src; | ||
| 354 | |||
| 355 | u128_to_be128(&ctrblocks[0], &ctrblk); | ||
| 356 | u128_inc(&ctrblk); | ||
| 357 | |||
| 358 | __serpent_encrypt(ctx, (u8 *)ctrblocks, (u8 *)ctrblocks); | ||
| 359 | u128_xor(dst, dst, (u128 *)ctrblocks); | ||
| 360 | |||
| 361 | src += 1; | ||
| 362 | dst += 1; | ||
| 363 | nbytes -= bsize; | ||
| 364 | } while (nbytes >= bsize); | ||
| 365 | |||
| 366 | done: | ||
| 367 | u128_to_be128((be128 *)walk->iv, &ctrblk); | ||
| 368 | return nbytes; | ||
| 369 | } | 178 | } |
| 370 | 179 | ||
| 371 | static int ctr_crypt(struct blkcipher_desc *desc, struct scatterlist *dst, | 180 | static inline void serpent_fpu_end(bool fpu_enabled) |
| 372 | struct scatterlist *src, unsigned int nbytes) | ||
| 373 | { | 181 | { |
| 374 | bool fpu_enabled = false; | 182 | glue_fpu_end(fpu_enabled); |
| 375 | struct blkcipher_walk walk; | ||
| 376 | int err; | ||
| 377 | |||
| 378 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
| 379 | err = blkcipher_walk_virt_block(desc, &walk, SERPENT_BLOCK_SIZE); | ||
| 380 | desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; | ||
| 381 | |||
| 382 | while ((nbytes = walk.nbytes) >= SERPENT_BLOCK_SIZE) { | ||
| 383 | fpu_enabled = serpent_fpu_begin(fpu_enabled, nbytes); | ||
| 384 | nbytes = __ctr_crypt(desc, &walk); | ||
| 385 | err = blkcipher_walk_done(desc, &walk, nbytes); | ||
| 386 | } | ||
| 387 | |||
| 388 | serpent_fpu_end(fpu_enabled); | ||
| 389 | |||
| 390 | if (walk.nbytes) { | ||
| 391 | ctr_crypt_final(desc, &walk); | ||
| 392 | err = blkcipher_walk_done(desc, &walk, 0); | ||
| 393 | } | ||
| 394 | |||
| 395 | return err; | ||
| 396 | } | 183 | } |
| 397 | 184 | ||
| 398 | struct crypt_priv { | 185 | struct crypt_priv { |
| @@ -596,106 +383,6 @@ static int xts_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | |||
| 596 | return ret; | 383 | return ret; |
| 597 | } | 384 | } |
| 598 | 385 | ||
| 599 | static int ablk_set_key(struct crypto_ablkcipher *tfm, const u8 *key, | ||
| 600 | unsigned int key_len) | ||
| 601 | { | ||
| 602 | struct async_serpent_ctx *ctx = crypto_ablkcipher_ctx(tfm); | ||
| 603 | struct crypto_ablkcipher *child = &ctx->cryptd_tfm->base; | ||
| 604 | int err; | ||
| 605 | |||
| 606 | crypto_ablkcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK); | ||
| 607 | crypto_ablkcipher_set_flags(child, crypto_ablkcipher_get_flags(tfm) | ||
| 608 | & CRYPTO_TFM_REQ_MASK); | ||
| 609 | err = crypto_ablkcipher_setkey(child, key, key_len); | ||
| 610 | crypto_ablkcipher_set_flags(tfm, crypto_ablkcipher_get_flags(child) | ||
| 611 | & CRYPTO_TFM_RES_MASK); | ||
| 612 | return err; | ||
| 613 | } | ||
| 614 | |||
| 615 | static int __ablk_encrypt(struct ablkcipher_request *req) | ||
| 616 | { | ||
| 617 | struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); | ||
| 618 | struct async_serpent_ctx *ctx = crypto_ablkcipher_ctx(tfm); | ||
| 619 | struct blkcipher_desc desc; | ||
| 620 | |||
| 621 | desc.tfm = cryptd_ablkcipher_child(ctx->cryptd_tfm); | ||
| 622 | desc.info = req->info; | ||
| 623 | desc.flags = 0; | ||
| 624 | |||
| 625 | return crypto_blkcipher_crt(desc.tfm)->encrypt( | ||
| 626 | &desc, req->dst, req->src, req->nbytes); | ||
| 627 | } | ||
| 628 | |||
| 629 | static int ablk_encrypt(struct ablkcipher_request *req) | ||
| 630 | { | ||
| 631 | struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); | ||
| 632 | struct async_serpent_ctx *ctx = crypto_ablkcipher_ctx(tfm); | ||
| 633 | |||
| 634 | if (!irq_fpu_usable()) { | ||
| 635 | struct ablkcipher_request *cryptd_req = | ||
| 636 | ablkcipher_request_ctx(req); | ||
| 637 | |||
| 638 | memcpy(cryptd_req, req, sizeof(*req)); | ||
| 639 | ablkcipher_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base); | ||
| 640 | |||
| 641 | return crypto_ablkcipher_encrypt(cryptd_req); | ||
| 642 | } else { | ||
| 643 | return __ablk_encrypt(req); | ||
| 644 | } | ||
| 645 | } | ||
| 646 | |||
| 647 | static int ablk_decrypt(struct ablkcipher_request *req) | ||
| 648 | { | ||
| 649 | struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); | ||
| 650 | struct async_serpent_ctx *ctx = crypto_ablkcipher_ctx(tfm); | ||
| 651 | |||
| 652 | if (!irq_fpu_usable()) { | ||
| 653 | struct ablkcipher_request *cryptd_req = | ||
| 654 | ablkcipher_request_ctx(req); | ||
| 655 | |||
| 656 | memcpy(cryptd_req, req, sizeof(*req)); | ||
| 657 | ablkcipher_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base); | ||
| 658 | |||
| 659 | return crypto_ablkcipher_decrypt(cryptd_req); | ||
| 660 | } else { | ||
| 661 | struct blkcipher_desc desc; | ||
| 662 | |||
| 663 | desc.tfm = cryptd_ablkcipher_child(ctx->cryptd_tfm); | ||
| 664 | desc.info = req->info; | ||
| 665 | desc.flags = 0; | ||
| 666 | |||
| 667 | return crypto_blkcipher_crt(desc.tfm)->decrypt( | ||
| 668 | &desc, req->dst, req->src, req->nbytes); | ||
| 669 | } | ||
| 670 | } | ||
| 671 | |||
| 672 | static void ablk_exit(struct crypto_tfm *tfm) | ||
| 673 | { | ||
| 674 | struct async_serpent_ctx *ctx = crypto_tfm_ctx(tfm); | ||
| 675 | |||
| 676 | cryptd_free_ablkcipher(ctx->cryptd_tfm); | ||
| 677 | } | ||
| 678 | |||
| 679 | static int ablk_init(struct crypto_tfm *tfm) | ||
| 680 | { | ||
| 681 | struct async_serpent_ctx *ctx = crypto_tfm_ctx(tfm); | ||
| 682 | struct cryptd_ablkcipher *cryptd_tfm; | ||
| 683 | char drv_name[CRYPTO_MAX_ALG_NAME]; | ||
| 684 | |||
| 685 | snprintf(drv_name, sizeof(drv_name), "__driver-%s", | ||
| 686 | crypto_tfm_alg_driver_name(tfm)); | ||
| 687 | |||
| 688 | cryptd_tfm = cryptd_alloc_ablkcipher(drv_name, 0, 0); | ||
| 689 | if (IS_ERR(cryptd_tfm)) | ||
| 690 | return PTR_ERR(cryptd_tfm); | ||
| 691 | |||
| 692 | ctx->cryptd_tfm = cryptd_tfm; | ||
| 693 | tfm->crt_ablkcipher.reqsize = sizeof(struct ablkcipher_request) + | ||
| 694 | crypto_ablkcipher_reqsize(&cryptd_tfm->base); | ||
| 695 | |||
| 696 | return 0; | ||
| 697 | } | ||
| 698 | |||
| 699 | static struct crypto_alg serpent_algs[10] = { { | 386 | static struct crypto_alg serpent_algs[10] = { { |
| 700 | .cra_name = "__ecb-serpent-sse2", | 387 | .cra_name = "__ecb-serpent-sse2", |
| 701 | .cra_driver_name = "__driver-ecb-serpent-sse2", | 388 | .cra_driver_name = "__driver-ecb-serpent-sse2", |
| @@ -808,7 +495,7 @@ static struct crypto_alg serpent_algs[10] = { { | |||
| 808 | .cra_priority = 400, | 495 | .cra_priority = 400, |
| 809 | .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, | 496 | .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, |
| 810 | .cra_blocksize = SERPENT_BLOCK_SIZE, | 497 | .cra_blocksize = SERPENT_BLOCK_SIZE, |
| 811 | .cra_ctxsize = sizeof(struct async_serpent_ctx), | 498 | .cra_ctxsize = sizeof(struct async_helper_ctx), |
| 812 | .cra_alignmask = 0, | 499 | .cra_alignmask = 0, |
| 813 | .cra_type = &crypto_ablkcipher_type, | 500 | .cra_type = &crypto_ablkcipher_type, |
| 814 | .cra_module = THIS_MODULE, | 501 | .cra_module = THIS_MODULE, |
| @@ -830,7 +517,7 @@ static struct crypto_alg serpent_algs[10] = { { | |||
| 830 | .cra_priority = 400, | 517 | .cra_priority = 400, |
| 831 | .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, | 518 | .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, |
| 832 | .cra_blocksize = SERPENT_BLOCK_SIZE, | 519 | .cra_blocksize = SERPENT_BLOCK_SIZE, |
| 833 | .cra_ctxsize = sizeof(struct async_serpent_ctx), | 520 | .cra_ctxsize = sizeof(struct async_helper_ctx), |
| 834 | .cra_alignmask = 0, | 521 | .cra_alignmask = 0, |
| 835 | .cra_type = &crypto_ablkcipher_type, | 522 | .cra_type = &crypto_ablkcipher_type, |
| 836 | .cra_module = THIS_MODULE, | 523 | .cra_module = THIS_MODULE, |
| @@ -853,7 +540,7 @@ static struct crypto_alg serpent_algs[10] = { { | |||
| 853 | .cra_priority = 400, | 540 | .cra_priority = 400, |
| 854 | .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, | 541 | .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, |
| 855 | .cra_blocksize = 1, | 542 | .cra_blocksize = 1, |
| 856 | .cra_ctxsize = sizeof(struct async_serpent_ctx), | 543 | .cra_ctxsize = sizeof(struct async_helper_ctx), |
| 857 | .cra_alignmask = 0, | 544 | .cra_alignmask = 0, |
| 858 | .cra_type = &crypto_ablkcipher_type, | 545 | .cra_type = &crypto_ablkcipher_type, |
| 859 | .cra_module = THIS_MODULE, | 546 | .cra_module = THIS_MODULE, |
| @@ -877,7 +564,7 @@ static struct crypto_alg serpent_algs[10] = { { | |||
| 877 | .cra_priority = 400, | 564 | .cra_priority = 400, |
| 878 | .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, | 565 | .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, |
| 879 | .cra_blocksize = SERPENT_BLOCK_SIZE, | 566 | .cra_blocksize = SERPENT_BLOCK_SIZE, |
| 880 | .cra_ctxsize = sizeof(struct async_serpent_ctx), | 567 | .cra_ctxsize = sizeof(struct async_helper_ctx), |
| 881 | .cra_alignmask = 0, | 568 | .cra_alignmask = 0, |
| 882 | .cra_type = &crypto_ablkcipher_type, | 569 | .cra_type = &crypto_ablkcipher_type, |
| 883 | .cra_module = THIS_MODULE, | 570 | .cra_module = THIS_MODULE, |
| @@ -902,7 +589,7 @@ static struct crypto_alg serpent_algs[10] = { { | |||
| 902 | .cra_priority = 400, | 589 | .cra_priority = 400, |
| 903 | .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, | 590 | .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, |
| 904 | .cra_blocksize = SERPENT_BLOCK_SIZE, | 591 | .cra_blocksize = SERPENT_BLOCK_SIZE, |
| 905 | .cra_ctxsize = sizeof(struct async_serpent_ctx), | 592 | .cra_ctxsize = sizeof(struct async_helper_ctx), |
| 906 | .cra_alignmask = 0, | 593 | .cra_alignmask = 0, |
| 907 | .cra_type = &crypto_ablkcipher_type, | 594 | .cra_type = &crypto_ablkcipher_type, |
| 908 | .cra_module = THIS_MODULE, | 595 | .cra_module = THIS_MODULE, |
diff --git a/arch/x86/crypto/sha1_ssse3_asm.S b/arch/x86/crypto/sha1_ssse3_asm.S index b2c2f57d70e8..49d6987a73d9 100644 --- a/arch/x86/crypto/sha1_ssse3_asm.S +++ b/arch/x86/crypto/sha1_ssse3_asm.S | |||
| @@ -468,7 +468,7 @@ W_PRECALC_SSSE3 | |||
| 468 | */ | 468 | */ |
| 469 | SHA1_VECTOR_ASM sha1_transform_ssse3 | 469 | SHA1_VECTOR_ASM sha1_transform_ssse3 |
| 470 | 470 | ||
| 471 | #ifdef SHA1_ENABLE_AVX_SUPPORT | 471 | #ifdef CONFIG_AS_AVX |
| 472 | 472 | ||
| 473 | .macro W_PRECALC_AVX | 473 | .macro W_PRECALC_AVX |
| 474 | 474 | ||
diff --git a/arch/x86/crypto/sha1_ssse3_glue.c b/arch/x86/crypto/sha1_ssse3_glue.c index f916499d0abe..4a11a9d72451 100644 --- a/arch/x86/crypto/sha1_ssse3_glue.c +++ b/arch/x86/crypto/sha1_ssse3_glue.c | |||
| @@ -35,7 +35,7 @@ | |||
| 35 | 35 | ||
| 36 | asmlinkage void sha1_transform_ssse3(u32 *digest, const char *data, | 36 | asmlinkage void sha1_transform_ssse3(u32 *digest, const char *data, |
| 37 | unsigned int rounds); | 37 | unsigned int rounds); |
| 38 | #ifdef SHA1_ENABLE_AVX_SUPPORT | 38 | #ifdef CONFIG_AS_AVX |
| 39 | asmlinkage void sha1_transform_avx(u32 *digest, const char *data, | 39 | asmlinkage void sha1_transform_avx(u32 *digest, const char *data, |
| 40 | unsigned int rounds); | 40 | unsigned int rounds); |
| 41 | #endif | 41 | #endif |
| @@ -184,7 +184,7 @@ static struct shash_alg alg = { | |||
| 184 | } | 184 | } |
| 185 | }; | 185 | }; |
| 186 | 186 | ||
| 187 | #ifdef SHA1_ENABLE_AVX_SUPPORT | 187 | #ifdef CONFIG_AS_AVX |
| 188 | static bool __init avx_usable(void) | 188 | static bool __init avx_usable(void) |
| 189 | { | 189 | { |
| 190 | u64 xcr0; | 190 | u64 xcr0; |
| @@ -209,7 +209,7 @@ static int __init sha1_ssse3_mod_init(void) | |||
| 209 | if (cpu_has_ssse3) | 209 | if (cpu_has_ssse3) |
| 210 | sha1_transform_asm = sha1_transform_ssse3; | 210 | sha1_transform_asm = sha1_transform_ssse3; |
| 211 | 211 | ||
| 212 | #ifdef SHA1_ENABLE_AVX_SUPPORT | 212 | #ifdef CONFIG_AS_AVX |
| 213 | /* allow AVX to override SSSE3, it's a little faster */ | 213 | /* allow AVX to override SSSE3, it's a little faster */ |
| 214 | if (avx_usable()) | 214 | if (avx_usable()) |
| 215 | sha1_transform_asm = sha1_transform_avx; | 215 | sha1_transform_asm = sha1_transform_avx; |
diff --git a/arch/x86/crypto/twofish-avx-x86_64-asm_64.S b/arch/x86/crypto/twofish-avx-x86_64-asm_64.S new file mode 100644 index 000000000000..35f45574390d --- /dev/null +++ b/arch/x86/crypto/twofish-avx-x86_64-asm_64.S | |||
| @@ -0,0 +1,300 @@ | |||
| 1 | /* | ||
| 2 | * Twofish Cipher 8-way parallel algorithm (AVX/x86_64) | ||
| 3 | * | ||
| 4 | * Copyright (C) 2012 Johannes Goetzfried | ||
| 5 | * <Johannes.Goetzfried@informatik.stud.uni-erlangen.de> | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License as published by | ||
| 9 | * the Free Software Foundation; either version 2 of the License, or | ||
| 10 | * (at your option) any later version. | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | ||
| 20 | * USA | ||
| 21 | * | ||
| 22 | */ | ||
| 23 | |||
| 24 | .file "twofish-avx-x86_64-asm_64.S" | ||
| 25 | .text | ||
| 26 | |||
| 27 | /* structure of crypto context */ | ||
| 28 | #define s0 0 | ||
| 29 | #define s1 1024 | ||
| 30 | #define s2 2048 | ||
| 31 | #define s3 3072 | ||
| 32 | #define w 4096 | ||
| 33 | #define k 4128 | ||
| 34 | |||
| 35 | /********************************************************************** | ||
| 36 | 8-way AVX twofish | ||
| 37 | **********************************************************************/ | ||
| 38 | #define CTX %rdi | ||
| 39 | |||
| 40 | #define RA1 %xmm0 | ||
| 41 | #define RB1 %xmm1 | ||
| 42 | #define RC1 %xmm2 | ||
| 43 | #define RD1 %xmm3 | ||
| 44 | |||
| 45 | #define RA2 %xmm4 | ||
| 46 | #define RB2 %xmm5 | ||
| 47 | #define RC2 %xmm6 | ||
| 48 | #define RD2 %xmm7 | ||
| 49 | |||
| 50 | #define RX %xmm8 | ||
| 51 | #define RY %xmm9 | ||
| 52 | |||
| 53 | #define RK1 %xmm10 | ||
| 54 | #define RK2 %xmm11 | ||
| 55 | |||
| 56 | #define RID1 %rax | ||
| 57 | #define RID1b %al | ||
| 58 | #define RID2 %rbx | ||
| 59 | #define RID2b %bl | ||
| 60 | |||
| 61 | #define RGI1 %rdx | ||
| 62 | #define RGI1bl %dl | ||
| 63 | #define RGI1bh %dh | ||
| 64 | #define RGI2 %rcx | ||
| 65 | #define RGI2bl %cl | ||
| 66 | #define RGI2bh %ch | ||
| 67 | |||
| 68 | #define RGS1 %r8 | ||
| 69 | #define RGS1d %r8d | ||
| 70 | #define RGS2 %r9 | ||
| 71 | #define RGS2d %r9d | ||
| 72 | #define RGS3 %r10 | ||
| 73 | #define RGS3d %r10d | ||
| 74 | |||
| 75 | |||
| 76 | #define lookup_32bit(t0, t1, t2, t3, src, dst) \ | ||
| 77 | movb src ## bl, RID1b; \ | ||
| 78 | movb src ## bh, RID2b; \ | ||
| 79 | movl t0(CTX, RID1, 4), dst ## d; \ | ||
| 80 | xorl t1(CTX, RID2, 4), dst ## d; \ | ||
| 81 | shrq $16, src; \ | ||
| 82 | movb src ## bl, RID1b; \ | ||
| 83 | movb src ## bh, RID2b; \ | ||
| 84 | xorl t2(CTX, RID1, 4), dst ## d; \ | ||
| 85 | xorl t3(CTX, RID2, 4), dst ## d; | ||
| 86 | |||
| 87 | #define G(a, x, t0, t1, t2, t3) \ | ||
| 88 | vmovq a, RGI1; \ | ||
| 89 | vpsrldq $8, a, x; \ | ||
| 90 | vmovq x, RGI2; \ | ||
| 91 | \ | ||
| 92 | lookup_32bit(t0, t1, t2, t3, RGI1, RGS1); \ | ||
| 93 | shrq $16, RGI1; \ | ||
| 94 | lookup_32bit(t0, t1, t2, t3, RGI1, RGS2); \ | ||
| 95 | shlq $32, RGS2; \ | ||
| 96 | orq RGS1, RGS2; \ | ||
| 97 | \ | ||
| 98 | lookup_32bit(t0, t1, t2, t3, RGI2, RGS1); \ | ||
| 99 | shrq $16, RGI2; \ | ||
| 100 | lookup_32bit(t0, t1, t2, t3, RGI2, RGS3); \ | ||
| 101 | shlq $32, RGS3; \ | ||
| 102 | orq RGS1, RGS3; \ | ||
| 103 | \ | ||
| 104 | vmovq RGS2, x; \ | ||
| 105 | vpinsrq $1, RGS3, x, x; | ||
| 106 | |||
| 107 | #define encround(a, b, c, d, x, y) \ | ||
| 108 | G(a, x, s0, s1, s2, s3); \ | ||
| 109 | G(b, y, s1, s2, s3, s0); \ | ||
| 110 | vpaddd x, y, x; \ | ||
| 111 | vpaddd y, x, y; \ | ||
| 112 | vpaddd x, RK1, x; \ | ||
| 113 | vpaddd y, RK2, y; \ | ||
| 114 | vpxor x, c, c; \ | ||
| 115 | vpsrld $1, c, x; \ | ||
| 116 | vpslld $(32 - 1), c, c; \ | ||
| 117 | vpor c, x, c; \ | ||
| 118 | vpslld $1, d, x; \ | ||
| 119 | vpsrld $(32 - 1), d, d; \ | ||
| 120 | vpor d, x, d; \ | ||
| 121 | vpxor d, y, d; | ||
| 122 | |||
| 123 | #define decround(a, b, c, d, x, y) \ | ||
| 124 | G(a, x, s0, s1, s2, s3); \ | ||
| 125 | G(b, y, s1, s2, s3, s0); \ | ||
| 126 | vpaddd x, y, x; \ | ||
| 127 | vpaddd y, x, y; \ | ||
| 128 | vpaddd y, RK2, y; \ | ||
| 129 | vpxor d, y, d; \ | ||
| 130 | vpsrld $1, d, y; \ | ||
| 131 | vpslld $(32 - 1), d, d; \ | ||
| 132 | vpor d, y, d; \ | ||
| 133 | vpslld $1, c, y; \ | ||
| 134 | vpsrld $(32 - 1), c, c; \ | ||
| 135 | vpor c, y, c; \ | ||
| 136 | vpaddd x, RK1, x; \ | ||
| 137 | vpxor x, c, c; | ||
| 138 | |||
| 139 | #define encrypt_round(n, a, b, c, d) \ | ||
| 140 | vbroadcastss (k+4*(2*(n)))(CTX), RK1; \ | ||
| 141 | vbroadcastss (k+4*(2*(n)+1))(CTX), RK2; \ | ||
| 142 | encround(a ## 1, b ## 1, c ## 1, d ## 1, RX, RY); \ | ||
| 143 | encround(a ## 2, b ## 2, c ## 2, d ## 2, RX, RY); | ||
| 144 | |||
| 145 | #define decrypt_round(n, a, b, c, d) \ | ||
| 146 | vbroadcastss (k+4*(2*(n)))(CTX), RK1; \ | ||
| 147 | vbroadcastss (k+4*(2*(n)+1))(CTX), RK2; \ | ||
| 148 | decround(a ## 1, b ## 1, c ## 1, d ## 1, RX, RY); \ | ||
| 149 | decround(a ## 2, b ## 2, c ## 2, d ## 2, RX, RY); | ||
| 150 | |||
| 151 | #define encrypt_cycle(n) \ | ||
| 152 | encrypt_round((2*n), RA, RB, RC, RD); \ | ||
| 153 | encrypt_round(((2*n) + 1), RC, RD, RA, RB); | ||
| 154 | |||
| 155 | #define decrypt_cycle(n) \ | ||
| 156 | decrypt_round(((2*n) + 1), RC, RD, RA, RB); \ | ||
| 157 | decrypt_round((2*n), RA, RB, RC, RD); | ||
| 158 | |||
| 159 | |||
| 160 | #define transpose_4x4(x0, x1, x2, x3, t0, t1, t2) \ | ||
| 161 | vpunpckldq x1, x0, t0; \ | ||
| 162 | vpunpckhdq x1, x0, t2; \ | ||
| 163 | vpunpckldq x3, x2, t1; \ | ||
| 164 | vpunpckhdq x3, x2, x3; \ | ||
| 165 | \ | ||
| 166 | vpunpcklqdq t1, t0, x0; \ | ||
| 167 | vpunpckhqdq t1, t0, x1; \ | ||
| 168 | vpunpcklqdq x3, t2, x2; \ | ||
| 169 | vpunpckhqdq x3, t2, x3; | ||
| 170 | |||
| 171 | #define inpack_blocks(in, x0, x1, x2, x3, wkey, t0, t1, t2) \ | ||
| 172 | vpxor (0*4*4)(in), wkey, x0; \ | ||
| 173 | vpxor (1*4*4)(in), wkey, x1; \ | ||
| 174 | vpxor (2*4*4)(in), wkey, x2; \ | ||
| 175 | vpxor (3*4*4)(in), wkey, x3; \ | ||
| 176 | \ | ||
| 177 | transpose_4x4(x0, x1, x2, x3, t0, t1, t2) | ||
| 178 | |||
| 179 | #define outunpack_blocks(out, x0, x1, x2, x3, wkey, t0, t1, t2) \ | ||
| 180 | transpose_4x4(x0, x1, x2, x3, t0, t1, t2) \ | ||
| 181 | \ | ||
| 182 | vpxor x0, wkey, x0; \ | ||
| 183 | vmovdqu x0, (0*4*4)(out); \ | ||
| 184 | vpxor x1, wkey, x1; \ | ||
| 185 | vmovdqu x1, (1*4*4)(out); \ | ||
| 186 | vpxor x2, wkey, x2; \ | ||
| 187 | vmovdqu x2, (2*4*4)(out); \ | ||
| 188 | vpxor x3, wkey, x3; \ | ||
| 189 | vmovdqu x3, (3*4*4)(out); | ||
| 190 | |||
| 191 | #define outunpack_xor_blocks(out, x0, x1, x2, x3, wkey, t0, t1, t2) \ | ||
| 192 | transpose_4x4(x0, x1, x2, x3, t0, t1, t2) \ | ||
| 193 | \ | ||
| 194 | vpxor x0, wkey, x0; \ | ||
| 195 | vpxor (0*4*4)(out), x0, x0; \ | ||
| 196 | vmovdqu x0, (0*4*4)(out); \ | ||
| 197 | vpxor x1, wkey, x1; \ | ||
| 198 | vpxor (1*4*4)(out), x1, x1; \ | ||
| 199 | vmovdqu x1, (1*4*4)(out); \ | ||
| 200 | vpxor x2, wkey, x2; \ | ||
| 201 | vpxor (2*4*4)(out), x2, x2; \ | ||
| 202 | vmovdqu x2, (2*4*4)(out); \ | ||
| 203 | vpxor x3, wkey, x3; \ | ||
| 204 | vpxor (3*4*4)(out), x3, x3; \ | ||
| 205 | vmovdqu x3, (3*4*4)(out); | ||
| 206 | |||
| 207 | .align 8 | ||
| 208 | .global __twofish_enc_blk_8way | ||
| 209 | .type __twofish_enc_blk_8way,@function; | ||
| 210 | |||
| 211 | __twofish_enc_blk_8way: | ||
| 212 | /* input: | ||
| 213 | * %rdi: ctx, CTX | ||
| 214 | * %rsi: dst | ||
| 215 | * %rdx: src | ||
| 216 | * %rcx: bool, if true: xor output | ||
| 217 | */ | ||
| 218 | |||
| 219 | pushq %rbx; | ||
| 220 | pushq %rcx; | ||
| 221 | |||
| 222 | vmovdqu w(CTX), RK1; | ||
| 223 | |||
| 224 | leaq (4*4*4)(%rdx), %rax; | ||
| 225 | inpack_blocks(%rdx, RA1, RB1, RC1, RD1, RK1, RX, RY, RK2); | ||
| 226 | inpack_blocks(%rax, RA2, RB2, RC2, RD2, RK1, RX, RY, RK2); | ||
| 227 | |||
| 228 | xorq RID1, RID1; | ||
| 229 | xorq RID2, RID2; | ||
| 230 | |||
| 231 | encrypt_cycle(0); | ||
| 232 | encrypt_cycle(1); | ||
| 233 | encrypt_cycle(2); | ||
| 234 | encrypt_cycle(3); | ||
| 235 | encrypt_cycle(4); | ||
| 236 | encrypt_cycle(5); | ||
| 237 | encrypt_cycle(6); | ||
| 238 | encrypt_cycle(7); | ||
| 239 | |||
| 240 | vmovdqu (w+4*4)(CTX), RK1; | ||
| 241 | |||
| 242 | popq %rcx; | ||
| 243 | popq %rbx; | ||
| 244 | |||
| 245 | leaq (4*4*4)(%rsi), %rax; | ||
| 246 | |||
| 247 | testb %cl, %cl; | ||
| 248 | jnz __enc_xor8; | ||
| 249 | |||
| 250 | outunpack_blocks(%rsi, RC1, RD1, RA1, RB1, RK1, RX, RY, RK2); | ||
| 251 | outunpack_blocks(%rax, RC2, RD2, RA2, RB2, RK1, RX, RY, RK2); | ||
| 252 | |||
| 253 | ret; | ||
| 254 | |||
| 255 | __enc_xor8: | ||
| 256 | outunpack_xor_blocks(%rsi, RC1, RD1, RA1, RB1, RK1, RX, RY, RK2); | ||
| 257 | outunpack_xor_blocks(%rax, RC2, RD2, RA2, RB2, RK1, RX, RY, RK2); | ||
| 258 | |||
| 259 | ret; | ||
| 260 | |||
| 261 | .align 8 | ||
| 262 | .global twofish_dec_blk_8way | ||
| 263 | .type twofish_dec_blk_8way,@function; | ||
| 264 | |||
| 265 | twofish_dec_blk_8way: | ||
| 266 | /* input: | ||
| 267 | * %rdi: ctx, CTX | ||
| 268 | * %rsi: dst | ||
| 269 | * %rdx: src | ||
| 270 | */ | ||
| 271 | |||
| 272 | pushq %rbx; | ||
| 273 | |||
| 274 | vmovdqu (w+4*4)(CTX), RK1; | ||
| 275 | |||
| 276 | leaq (4*4*4)(%rdx), %rax; | ||
| 277 | inpack_blocks(%rdx, RC1, RD1, RA1, RB1, RK1, RX, RY, RK2); | ||
| 278 | inpack_blocks(%rax, RC2, RD2, RA2, RB2, RK1, RX, RY, RK2); | ||
| 279 | |||
| 280 | xorq RID1, RID1; | ||
| 281 | xorq RID2, RID2; | ||
| 282 | |||
| 283 | decrypt_cycle(7); | ||
| 284 | decrypt_cycle(6); | ||
| 285 | decrypt_cycle(5); | ||
| 286 | decrypt_cycle(4); | ||
| 287 | decrypt_cycle(3); | ||
| 288 | decrypt_cycle(2); | ||
| 289 | decrypt_cycle(1); | ||
| 290 | decrypt_cycle(0); | ||
| 291 | |||
| 292 | vmovdqu (w)(CTX), RK1; | ||
| 293 | |||
| 294 | popq %rbx; | ||
| 295 | |||
| 296 | leaq (4*4*4)(%rsi), %rax; | ||
| 297 | outunpack_blocks(%rsi, RA1, RB1, RC1, RD1, RK1, RX, RY, RK2); | ||
| 298 | outunpack_blocks(%rax, RA2, RB2, RC2, RD2, RK1, RX, RY, RK2); | ||
| 299 | |||
| 300 | ret; | ||
diff --git a/arch/x86/crypto/twofish_avx_glue.c b/arch/x86/crypto/twofish_avx_glue.c new file mode 100644 index 000000000000..782b67ddaf6a --- /dev/null +++ b/arch/x86/crypto/twofish_avx_glue.c | |||
| @@ -0,0 +1,624 @@ | |||
| 1 | /* | ||
| 2 | * Glue Code for AVX assembler version of Twofish Cipher | ||
| 3 | * | ||
| 4 | * Copyright (C) 2012 Johannes Goetzfried | ||
| 5 | * <Johannes.Goetzfried@informatik.stud.uni-erlangen.de> | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License as published by | ||
| 9 | * the Free Software Foundation; either version 2 of the License, or | ||
| 10 | * (at your option) any later version. | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | ||
| 20 | * USA | ||
| 21 | * | ||
| 22 | */ | ||
| 23 | |||
| 24 | #include <linux/module.h> | ||
| 25 | #include <linux/hardirq.h> | ||
| 26 | #include <linux/types.h> | ||
| 27 | #include <linux/crypto.h> | ||
| 28 | #include <linux/err.h> | ||
| 29 | #include <crypto/algapi.h> | ||
| 30 | #include <crypto/twofish.h> | ||
| 31 | #include <crypto/cryptd.h> | ||
| 32 | #include <crypto/b128ops.h> | ||
| 33 | #include <crypto/ctr.h> | ||
| 34 | #include <crypto/lrw.h> | ||
| 35 | #include <crypto/xts.h> | ||
| 36 | #include <asm/i387.h> | ||
| 37 | #include <asm/xcr.h> | ||
| 38 | #include <asm/xsave.h> | ||
| 39 | #include <asm/crypto/twofish.h> | ||
| 40 | #include <asm/crypto/ablk_helper.h> | ||
| 41 | #include <asm/crypto/glue_helper.h> | ||
| 42 | #include <crypto/scatterwalk.h> | ||
| 43 | #include <linux/workqueue.h> | ||
| 44 | #include <linux/spinlock.h> | ||
| 45 | |||
| 46 | #define TWOFISH_PARALLEL_BLOCKS 8 | ||
| 47 | |||
| 48 | static inline void twofish_enc_blk_3way(struct twofish_ctx *ctx, u8 *dst, | ||
| 49 | const u8 *src) | ||
| 50 | { | ||
| 51 | __twofish_enc_blk_3way(ctx, dst, src, false); | ||
| 52 | } | ||
| 53 | |||
| 54 | /* 8-way parallel cipher functions */ | ||
| 55 | asmlinkage void __twofish_enc_blk_8way(struct twofish_ctx *ctx, u8 *dst, | ||
| 56 | const u8 *src, bool xor); | ||
| 57 | asmlinkage void twofish_dec_blk_8way(struct twofish_ctx *ctx, u8 *dst, | ||
| 58 | const u8 *src); | ||
| 59 | |||
| 60 | static inline void twofish_enc_blk_xway(struct twofish_ctx *ctx, u8 *dst, | ||
| 61 | const u8 *src) | ||
| 62 | { | ||
| 63 | __twofish_enc_blk_8way(ctx, dst, src, false); | ||
| 64 | } | ||
| 65 | |||
| 66 | static inline void twofish_enc_blk_xway_xor(struct twofish_ctx *ctx, u8 *dst, | ||
| 67 | const u8 *src) | ||
| 68 | { | ||
| 69 | __twofish_enc_blk_8way(ctx, dst, src, true); | ||
| 70 | } | ||
| 71 | |||
| 72 | static inline void twofish_dec_blk_xway(struct twofish_ctx *ctx, u8 *dst, | ||
| 73 | const u8 *src) | ||
| 74 | { | ||
| 75 | twofish_dec_blk_8way(ctx, dst, src); | ||
| 76 | } | ||
| 77 | |||
| 78 | static void twofish_dec_blk_cbc_xway(void *ctx, u128 *dst, const u128 *src) | ||
| 79 | { | ||
| 80 | u128 ivs[TWOFISH_PARALLEL_BLOCKS - 1]; | ||
| 81 | unsigned int j; | ||
| 82 | |||
| 83 | for (j = 0; j < TWOFISH_PARALLEL_BLOCKS - 1; j++) | ||
| 84 | ivs[j] = src[j]; | ||
| 85 | |||
| 86 | twofish_dec_blk_xway(ctx, (u8 *)dst, (u8 *)src); | ||
| 87 | |||
| 88 | for (j = 0; j < TWOFISH_PARALLEL_BLOCKS - 1; j++) | ||
| 89 | u128_xor(dst + (j + 1), dst + (j + 1), ivs + j); | ||
| 90 | } | ||
| 91 | |||
| 92 | static void twofish_enc_blk_ctr_xway(void *ctx, u128 *dst, const u128 *src, | ||
| 93 | u128 *iv) | ||
| 94 | { | ||
| 95 | be128 ctrblks[TWOFISH_PARALLEL_BLOCKS]; | ||
| 96 | unsigned int i; | ||
| 97 | |||
| 98 | for (i = 0; i < TWOFISH_PARALLEL_BLOCKS; i++) { | ||
| 99 | if (dst != src) | ||
| 100 | dst[i] = src[i]; | ||
| 101 | |||
| 102 | u128_to_be128(&ctrblks[i], iv); | ||
| 103 | u128_inc(iv); | ||
| 104 | } | ||
| 105 | |||
| 106 | twofish_enc_blk_xway_xor(ctx, (u8 *)dst, (u8 *)ctrblks); | ||
| 107 | } | ||
| 108 | |||
| 109 | static const struct common_glue_ctx twofish_enc = { | ||
| 110 | .num_funcs = 3, | ||
| 111 | .fpu_blocks_limit = TWOFISH_PARALLEL_BLOCKS, | ||
| 112 | |||
| 113 | .funcs = { { | ||
| 114 | .num_blocks = TWOFISH_PARALLEL_BLOCKS, | ||
| 115 | .fn_u = { .ecb = GLUE_FUNC_CAST(twofish_enc_blk_xway) } | ||
| 116 | }, { | ||
| 117 | .num_blocks = 3, | ||
| 118 | .fn_u = { .ecb = GLUE_FUNC_CAST(twofish_enc_blk_3way) } | ||
| 119 | }, { | ||
| 120 | .num_blocks = 1, | ||
| 121 | .fn_u = { .ecb = GLUE_FUNC_CAST(twofish_enc_blk) } | ||
| 122 | } } | ||
| 123 | }; | ||
| 124 | |||
| 125 | static const struct common_glue_ctx twofish_ctr = { | ||
| 126 | .num_funcs = 3, | ||
| 127 | .fpu_blocks_limit = TWOFISH_PARALLEL_BLOCKS, | ||
| 128 | |||
| 129 | .funcs = { { | ||
| 130 | .num_blocks = TWOFISH_PARALLEL_BLOCKS, | ||
| 131 | .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(twofish_enc_blk_ctr_xway) } | ||
| 132 | }, { | ||
| 133 | .num_blocks = 3, | ||
| 134 | .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(twofish_enc_blk_ctr_3way) } | ||
| 135 | }, { | ||
| 136 | .num_blocks = 1, | ||
| 137 | .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(twofish_enc_blk_ctr) } | ||
| 138 | } } | ||
| 139 | }; | ||
| 140 | |||
| 141 | static const struct common_glue_ctx twofish_dec = { | ||
| 142 | .num_funcs = 3, | ||
| 143 | .fpu_blocks_limit = TWOFISH_PARALLEL_BLOCKS, | ||
| 144 | |||
| 145 | .funcs = { { | ||
| 146 | .num_blocks = TWOFISH_PARALLEL_BLOCKS, | ||
| 147 | .fn_u = { .ecb = GLUE_FUNC_CAST(twofish_dec_blk_xway) } | ||
| 148 | }, { | ||
| 149 | .num_blocks = 3, | ||
| 150 | .fn_u = { .ecb = GLUE_FUNC_CAST(twofish_dec_blk_3way) } | ||
| 151 | }, { | ||
| 152 | .num_blocks = 1, | ||
| 153 | .fn_u = { .ecb = GLUE_FUNC_CAST(twofish_dec_blk) } | ||
| 154 | } } | ||
| 155 | }; | ||
| 156 | |||
| 157 | static const struct common_glue_ctx twofish_dec_cbc = { | ||
| 158 | .num_funcs = 3, | ||
| 159 | .fpu_blocks_limit = TWOFISH_PARALLEL_BLOCKS, | ||
| 160 | |||
| 161 | .funcs = { { | ||
| 162 | .num_blocks = TWOFISH_PARALLEL_BLOCKS, | ||
| 163 | .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(twofish_dec_blk_cbc_xway) } | ||
| 164 | }, { | ||
| 165 | .num_blocks = 3, | ||
| 166 | .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(twofish_dec_blk_cbc_3way) } | ||
| 167 | }, { | ||
| 168 | .num_blocks = 1, | ||
| 169 | .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(twofish_dec_blk) } | ||
| 170 | } } | ||
| 171 | }; | ||
| 172 | |||
| 173 | static int ecb_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | ||
| 174 | struct scatterlist *src, unsigned int nbytes) | ||
| 175 | { | ||
| 176 | return glue_ecb_crypt_128bit(&twofish_enc, desc, dst, src, nbytes); | ||
| 177 | } | ||
| 178 | |||
| 179 | static int ecb_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | ||
| 180 | struct scatterlist *src, unsigned int nbytes) | ||
| 181 | { | ||
| 182 | return glue_ecb_crypt_128bit(&twofish_dec, desc, dst, src, nbytes); | ||
| 183 | } | ||
| 184 | |||
| 185 | static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | ||
| 186 | struct scatterlist *src, unsigned int nbytes) | ||
| 187 | { | ||
| 188 | return glue_cbc_encrypt_128bit(GLUE_FUNC_CAST(twofish_enc_blk), desc, | ||
| 189 | dst, src, nbytes); | ||
| 190 | } | ||
| 191 | |||
| 192 | static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | ||
| 193 | struct scatterlist *src, unsigned int nbytes) | ||
| 194 | { | ||
| 195 | return glue_cbc_decrypt_128bit(&twofish_dec_cbc, desc, dst, src, | ||
| 196 | nbytes); | ||
| 197 | } | ||
| 198 | |||
| 199 | static int ctr_crypt(struct blkcipher_desc *desc, struct scatterlist *dst, | ||
| 200 | struct scatterlist *src, unsigned int nbytes) | ||
| 201 | { | ||
| 202 | return glue_ctr_crypt_128bit(&twofish_ctr, desc, dst, src, nbytes); | ||
| 203 | } | ||
| 204 | |||
| 205 | static inline bool twofish_fpu_begin(bool fpu_enabled, unsigned int nbytes) | ||
| 206 | { | ||
| 207 | return glue_fpu_begin(TF_BLOCK_SIZE, TWOFISH_PARALLEL_BLOCKS, NULL, | ||
| 208 | fpu_enabled, nbytes); | ||
| 209 | } | ||
| 210 | |||
| 211 | static inline void twofish_fpu_end(bool fpu_enabled) | ||
| 212 | { | ||
| 213 | glue_fpu_end(fpu_enabled); | ||
| 214 | } | ||
| 215 | |||
| 216 | struct crypt_priv { | ||
| 217 | struct twofish_ctx *ctx; | ||
| 218 | bool fpu_enabled; | ||
| 219 | }; | ||
| 220 | |||
| 221 | static void encrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) | ||
| 222 | { | ||
| 223 | const unsigned int bsize = TF_BLOCK_SIZE; | ||
| 224 | struct crypt_priv *ctx = priv; | ||
| 225 | int i; | ||
| 226 | |||
| 227 | ctx->fpu_enabled = twofish_fpu_begin(ctx->fpu_enabled, nbytes); | ||
| 228 | |||
| 229 | if (nbytes == bsize * TWOFISH_PARALLEL_BLOCKS) { | ||
| 230 | twofish_enc_blk_xway(ctx->ctx, srcdst, srcdst); | ||
| 231 | return; | ||
| 232 | } | ||
| 233 | |||
| 234 | for (i = 0; i < nbytes / (bsize * 3); i++, srcdst += bsize * 3) | ||
| 235 | twofish_enc_blk_3way(ctx->ctx, srcdst, srcdst); | ||
| 236 | |||
| 237 | nbytes %= bsize * 3; | ||
| 238 | |||
| 239 | for (i = 0; i < nbytes / bsize; i++, srcdst += bsize) | ||
| 240 | twofish_enc_blk(ctx->ctx, srcdst, srcdst); | ||
| 241 | } | ||
| 242 | |||
| 243 | static void decrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) | ||
| 244 | { | ||
| 245 | const unsigned int bsize = TF_BLOCK_SIZE; | ||
| 246 | struct crypt_priv *ctx = priv; | ||
| 247 | int i; | ||
| 248 | |||
| 249 | ctx->fpu_enabled = twofish_fpu_begin(ctx->fpu_enabled, nbytes); | ||
| 250 | |||
| 251 | if (nbytes == bsize * TWOFISH_PARALLEL_BLOCKS) { | ||
| 252 | twofish_dec_blk_xway(ctx->ctx, srcdst, srcdst); | ||
| 253 | return; | ||
| 254 | } | ||
| 255 | |||
| 256 | for (i = 0; i < nbytes / (bsize * 3); i++, srcdst += bsize * 3) | ||
| 257 | twofish_dec_blk_3way(ctx->ctx, srcdst, srcdst); | ||
| 258 | |||
| 259 | nbytes %= bsize * 3; | ||
| 260 | |||
| 261 | for (i = 0; i < nbytes / bsize; i++, srcdst += bsize) | ||
| 262 | twofish_dec_blk(ctx->ctx, srcdst, srcdst); | ||
| 263 | } | ||
| 264 | |||
| 265 | static int lrw_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | ||
| 266 | struct scatterlist *src, unsigned int nbytes) | ||
| 267 | { | ||
| 268 | struct twofish_lrw_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
| 269 | be128 buf[TWOFISH_PARALLEL_BLOCKS]; | ||
| 270 | struct crypt_priv crypt_ctx = { | ||
| 271 | .ctx = &ctx->twofish_ctx, | ||
| 272 | .fpu_enabled = false, | ||
| 273 | }; | ||
| 274 | struct lrw_crypt_req req = { | ||
| 275 | .tbuf = buf, | ||
| 276 | .tbuflen = sizeof(buf), | ||
| 277 | |||
| 278 | .table_ctx = &ctx->lrw_table, | ||
| 279 | .crypt_ctx = &crypt_ctx, | ||
| 280 | .crypt_fn = encrypt_callback, | ||
| 281 | }; | ||
| 282 | int ret; | ||
| 283 | |||
| 284 | desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; | ||
| 285 | ret = lrw_crypt(desc, dst, src, nbytes, &req); | ||
| 286 | twofish_fpu_end(crypt_ctx.fpu_enabled); | ||
| 287 | |||
| 288 | return ret; | ||
| 289 | } | ||
| 290 | |||
| 291 | static int lrw_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | ||
| 292 | struct scatterlist *src, unsigned int nbytes) | ||
| 293 | { | ||
| 294 | struct twofish_lrw_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
| 295 | be128 buf[TWOFISH_PARALLEL_BLOCKS]; | ||
| 296 | struct crypt_priv crypt_ctx = { | ||
| 297 | .ctx = &ctx->twofish_ctx, | ||
| 298 | .fpu_enabled = false, | ||
| 299 | }; | ||
| 300 | struct lrw_crypt_req req = { | ||
| 301 | .tbuf = buf, | ||
| 302 | .tbuflen = sizeof(buf), | ||
| 303 | |||
| 304 | .table_ctx = &ctx->lrw_table, | ||
| 305 | .crypt_ctx = &crypt_ctx, | ||
| 306 | .crypt_fn = decrypt_callback, | ||
| 307 | }; | ||
| 308 | int ret; | ||
| 309 | |||
| 310 | desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; | ||
| 311 | ret = lrw_crypt(desc, dst, src, nbytes, &req); | ||
| 312 | twofish_fpu_end(crypt_ctx.fpu_enabled); | ||
| 313 | |||
| 314 | return ret; | ||
| 315 | } | ||
| 316 | |||
| 317 | static int xts_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | ||
| 318 | struct scatterlist *src, unsigned int nbytes) | ||
| 319 | { | ||
| 320 | struct twofish_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
| 321 | be128 buf[TWOFISH_PARALLEL_BLOCKS]; | ||
| 322 | struct crypt_priv crypt_ctx = { | ||
| 323 | .ctx = &ctx->crypt_ctx, | ||
| 324 | .fpu_enabled = false, | ||
| 325 | }; | ||
| 326 | struct xts_crypt_req req = { | ||
| 327 | .tbuf = buf, | ||
| 328 | .tbuflen = sizeof(buf), | ||
| 329 | |||
| 330 | .tweak_ctx = &ctx->tweak_ctx, | ||
| 331 | .tweak_fn = XTS_TWEAK_CAST(twofish_enc_blk), | ||
| 332 | .crypt_ctx = &crypt_ctx, | ||
| 333 | .crypt_fn = encrypt_callback, | ||
| 334 | }; | ||
| 335 | int ret; | ||
| 336 | |||
| 337 | desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; | ||
| 338 | ret = xts_crypt(desc, dst, src, nbytes, &req); | ||
| 339 | twofish_fpu_end(crypt_ctx.fpu_enabled); | ||
| 340 | |||
| 341 | return ret; | ||
| 342 | } | ||
| 343 | |||
| 344 | static int xts_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | ||
| 345 | struct scatterlist *src, unsigned int nbytes) | ||
| 346 | { | ||
| 347 | struct twofish_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
| 348 | be128 buf[TWOFISH_PARALLEL_BLOCKS]; | ||
| 349 | struct crypt_priv crypt_ctx = { | ||
| 350 | .ctx = &ctx->crypt_ctx, | ||
| 351 | .fpu_enabled = false, | ||
| 352 | }; | ||
| 353 | struct xts_crypt_req req = { | ||
| 354 | .tbuf = buf, | ||
| 355 | .tbuflen = sizeof(buf), | ||
| 356 | |||
| 357 | .tweak_ctx = &ctx->tweak_ctx, | ||
| 358 | .tweak_fn = XTS_TWEAK_CAST(twofish_enc_blk), | ||
| 359 | .crypt_ctx = &crypt_ctx, | ||
| 360 | .crypt_fn = decrypt_callback, | ||
| 361 | }; | ||
| 362 | int ret; | ||
| 363 | |||
| 364 | desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; | ||
| 365 | ret = xts_crypt(desc, dst, src, nbytes, &req); | ||
| 366 | twofish_fpu_end(crypt_ctx.fpu_enabled); | ||
| 367 | |||
| 368 | return ret; | ||
| 369 | } | ||
| 370 | |||
| 371 | static struct crypto_alg twofish_algs[10] = { { | ||
| 372 | .cra_name = "__ecb-twofish-avx", | ||
| 373 | .cra_driver_name = "__driver-ecb-twofish-avx", | ||
| 374 | .cra_priority = 0, | ||
| 375 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, | ||
| 376 | .cra_blocksize = TF_BLOCK_SIZE, | ||
| 377 | .cra_ctxsize = sizeof(struct twofish_ctx), | ||
| 378 | .cra_alignmask = 0, | ||
| 379 | .cra_type = &crypto_blkcipher_type, | ||
| 380 | .cra_module = THIS_MODULE, | ||
| 381 | .cra_list = LIST_HEAD_INIT(twofish_algs[0].cra_list), | ||
| 382 | .cra_u = { | ||
| 383 | .blkcipher = { | ||
| 384 | .min_keysize = TF_MIN_KEY_SIZE, | ||
| 385 | .max_keysize = TF_MAX_KEY_SIZE, | ||
| 386 | .setkey = twofish_setkey, | ||
| 387 | .encrypt = ecb_encrypt, | ||
| 388 | .decrypt = ecb_decrypt, | ||
| 389 | }, | ||
| 390 | }, | ||
| 391 | }, { | ||
| 392 | .cra_name = "__cbc-twofish-avx", | ||
| 393 | .cra_driver_name = "__driver-cbc-twofish-avx", | ||
| 394 | .cra_priority = 0, | ||
| 395 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, | ||
| 396 | .cra_blocksize = TF_BLOCK_SIZE, | ||
| 397 | .cra_ctxsize = sizeof(struct twofish_ctx), | ||
| 398 | .cra_alignmask = 0, | ||
| 399 | .cra_type = &crypto_blkcipher_type, | ||
| 400 | .cra_module = THIS_MODULE, | ||
| 401 | .cra_list = LIST_HEAD_INIT(twofish_algs[1].cra_list), | ||
| 402 | .cra_u = { | ||
| 403 | .blkcipher = { | ||
| 404 | .min_keysize = TF_MIN_KEY_SIZE, | ||
| 405 | .max_keysize = TF_MAX_KEY_SIZE, | ||
| 406 | .setkey = twofish_setkey, | ||
| 407 | .encrypt = cbc_encrypt, | ||
| 408 | .decrypt = cbc_decrypt, | ||
| 409 | }, | ||
| 410 | }, | ||
| 411 | }, { | ||
| 412 | .cra_name = "__ctr-twofish-avx", | ||
| 413 | .cra_driver_name = "__driver-ctr-twofish-avx", | ||
| 414 | .cra_priority = 0, | ||
| 415 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, | ||
| 416 | .cra_blocksize = 1, | ||
| 417 | .cra_ctxsize = sizeof(struct twofish_ctx), | ||
| 418 | .cra_alignmask = 0, | ||
| 419 | .cra_type = &crypto_blkcipher_type, | ||
| 420 | .cra_module = THIS_MODULE, | ||
| 421 | .cra_list = LIST_HEAD_INIT(twofish_algs[2].cra_list), | ||
| 422 | .cra_u = { | ||
| 423 | .blkcipher = { | ||
| 424 | .min_keysize = TF_MIN_KEY_SIZE, | ||
| 425 | .max_keysize = TF_MAX_KEY_SIZE, | ||
| 426 | .ivsize = TF_BLOCK_SIZE, | ||
| 427 | .setkey = twofish_setkey, | ||
| 428 | .encrypt = ctr_crypt, | ||
| 429 | .decrypt = ctr_crypt, | ||
| 430 | }, | ||
| 431 | }, | ||
| 432 | }, { | ||
| 433 | .cra_name = "__lrw-twofish-avx", | ||
| 434 | .cra_driver_name = "__driver-lrw-twofish-avx", | ||
| 435 | .cra_priority = 0, | ||
| 436 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, | ||
| 437 | .cra_blocksize = TF_BLOCK_SIZE, | ||
| 438 | .cra_ctxsize = sizeof(struct twofish_lrw_ctx), | ||
| 439 | .cra_alignmask = 0, | ||
| 440 | .cra_type = &crypto_blkcipher_type, | ||
| 441 | .cra_module = THIS_MODULE, | ||
| 442 | .cra_list = LIST_HEAD_INIT(twofish_algs[3].cra_list), | ||
| 443 | .cra_exit = lrw_twofish_exit_tfm, | ||
| 444 | .cra_u = { | ||
| 445 | .blkcipher = { | ||
| 446 | .min_keysize = TF_MIN_KEY_SIZE + | ||
| 447 | TF_BLOCK_SIZE, | ||
| 448 | .max_keysize = TF_MAX_KEY_SIZE + | ||
| 449 | TF_BLOCK_SIZE, | ||
| 450 | .ivsize = TF_BLOCK_SIZE, | ||
| 451 | .setkey = lrw_twofish_setkey, | ||
| 452 | .encrypt = lrw_encrypt, | ||
| 453 | .decrypt = lrw_decrypt, | ||
| 454 | }, | ||
| 455 | }, | ||
| 456 | }, { | ||
| 457 | .cra_name = "__xts-twofish-avx", | ||
| 458 | .cra_driver_name = "__driver-xts-twofish-avx", | ||
| 459 | .cra_priority = 0, | ||
| 460 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, | ||
| 461 | .cra_blocksize = TF_BLOCK_SIZE, | ||
| 462 | .cra_ctxsize = sizeof(struct twofish_xts_ctx), | ||
| 463 | .cra_alignmask = 0, | ||
| 464 | .cra_type = &crypto_blkcipher_type, | ||
| 465 | .cra_module = THIS_MODULE, | ||
| 466 | .cra_list = LIST_HEAD_INIT(twofish_algs[4].cra_list), | ||
| 467 | .cra_u = { | ||
| 468 | .blkcipher = { | ||
| 469 | .min_keysize = TF_MIN_KEY_SIZE * 2, | ||
| 470 | .max_keysize = TF_MAX_KEY_SIZE * 2, | ||
| 471 | .ivsize = TF_BLOCK_SIZE, | ||
| 472 | .setkey = xts_twofish_setkey, | ||
| 473 | .encrypt = xts_encrypt, | ||
| 474 | .decrypt = xts_decrypt, | ||
| 475 | }, | ||
| 476 | }, | ||
| 477 | }, { | ||
| 478 | .cra_name = "ecb(twofish)", | ||
| 479 | .cra_driver_name = "ecb-twofish-avx", | ||
| 480 | .cra_priority = 400, | ||
| 481 | .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, | ||
| 482 | .cra_blocksize = TF_BLOCK_SIZE, | ||
| 483 | .cra_ctxsize = sizeof(struct async_helper_ctx), | ||
| 484 | .cra_alignmask = 0, | ||
| 485 | .cra_type = &crypto_ablkcipher_type, | ||
| 486 | .cra_module = THIS_MODULE, | ||
| 487 | .cra_list = LIST_HEAD_INIT(twofish_algs[5].cra_list), | ||
| 488 | .cra_init = ablk_init, | ||
| 489 | .cra_exit = ablk_exit, | ||
| 490 | .cra_u = { | ||
| 491 | .ablkcipher = { | ||
| 492 | .min_keysize = TF_MIN_KEY_SIZE, | ||
| 493 | .max_keysize = TF_MAX_KEY_SIZE, | ||
| 494 | .setkey = ablk_set_key, | ||
| 495 | .encrypt = ablk_encrypt, | ||
| 496 | .decrypt = ablk_decrypt, | ||
| 497 | }, | ||
| 498 | }, | ||
| 499 | }, { | ||
| 500 | .cra_name = "cbc(twofish)", | ||
| 501 | .cra_driver_name = "cbc-twofish-avx", | ||
| 502 | .cra_priority = 400, | ||
| 503 | .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, | ||
| 504 | .cra_blocksize = TF_BLOCK_SIZE, | ||
| 505 | .cra_ctxsize = sizeof(struct async_helper_ctx), | ||
| 506 | .cra_alignmask = 0, | ||
| 507 | .cra_type = &crypto_ablkcipher_type, | ||
| 508 | .cra_module = THIS_MODULE, | ||
| 509 | .cra_list = LIST_HEAD_INIT(twofish_algs[6].cra_list), | ||
| 510 | .cra_init = ablk_init, | ||
| 511 | .cra_exit = ablk_exit, | ||
| 512 | .cra_u = { | ||
| 513 | .ablkcipher = { | ||
| 514 | .min_keysize = TF_MIN_KEY_SIZE, | ||
| 515 | .max_keysize = TF_MAX_KEY_SIZE, | ||
| 516 | .ivsize = TF_BLOCK_SIZE, | ||
| 517 | .setkey = ablk_set_key, | ||
| 518 | .encrypt = __ablk_encrypt, | ||
| 519 | .decrypt = ablk_decrypt, | ||
| 520 | }, | ||
| 521 | }, | ||
| 522 | }, { | ||
| 523 | .cra_name = "ctr(twofish)", | ||
| 524 | .cra_driver_name = "ctr-twofish-avx", | ||
| 525 | .cra_priority = 400, | ||
| 526 | .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, | ||
| 527 | .cra_blocksize = 1, | ||
| 528 | .cra_ctxsize = sizeof(struct async_helper_ctx), | ||
| 529 | .cra_alignmask = 0, | ||
| 530 | .cra_type = &crypto_ablkcipher_type, | ||
| 531 | .cra_module = THIS_MODULE, | ||
| 532 | .cra_list = LIST_HEAD_INIT(twofish_algs[7].cra_list), | ||
| 533 | .cra_init = ablk_init, | ||
| 534 | .cra_exit = ablk_exit, | ||
| 535 | .cra_u = { | ||
| 536 | .ablkcipher = { | ||
| 537 | .min_keysize = TF_MIN_KEY_SIZE, | ||
| 538 | .max_keysize = TF_MAX_KEY_SIZE, | ||
| 539 | .ivsize = TF_BLOCK_SIZE, | ||
| 540 | .setkey = ablk_set_key, | ||
| 541 | .encrypt = ablk_encrypt, | ||
| 542 | .decrypt = ablk_encrypt, | ||
| 543 | .geniv = "chainiv", | ||
| 544 | }, | ||
| 545 | }, | ||
| 546 | }, { | ||
| 547 | .cra_name = "lrw(twofish)", | ||
| 548 | .cra_driver_name = "lrw-twofish-avx", | ||
| 549 | .cra_priority = 400, | ||
| 550 | .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, | ||
| 551 | .cra_blocksize = TF_BLOCK_SIZE, | ||
| 552 | .cra_ctxsize = sizeof(struct async_helper_ctx), | ||
| 553 | .cra_alignmask = 0, | ||
| 554 | .cra_type = &crypto_ablkcipher_type, | ||
| 555 | .cra_module = THIS_MODULE, | ||
| 556 | .cra_list = LIST_HEAD_INIT(twofish_algs[8].cra_list), | ||
| 557 | .cra_init = ablk_init, | ||
| 558 | .cra_exit = ablk_exit, | ||
| 559 | .cra_u = { | ||
| 560 | .ablkcipher = { | ||
| 561 | .min_keysize = TF_MIN_KEY_SIZE + | ||
| 562 | TF_BLOCK_SIZE, | ||
| 563 | .max_keysize = TF_MAX_KEY_SIZE + | ||
| 564 | TF_BLOCK_SIZE, | ||
| 565 | .ivsize = TF_BLOCK_SIZE, | ||
| 566 | .setkey = ablk_set_key, | ||
| 567 | .encrypt = ablk_encrypt, | ||
| 568 | .decrypt = ablk_decrypt, | ||
| 569 | }, | ||
| 570 | }, | ||
| 571 | }, { | ||
| 572 | .cra_name = "xts(twofish)", | ||
| 573 | .cra_driver_name = "xts-twofish-avx", | ||
| 574 | .cra_priority = 400, | ||
| 575 | .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, | ||
| 576 | .cra_blocksize = TF_BLOCK_SIZE, | ||
| 577 | .cra_ctxsize = sizeof(struct async_helper_ctx), | ||
| 578 | .cra_alignmask = 0, | ||
| 579 | .cra_type = &crypto_ablkcipher_type, | ||
| 580 | .cra_module = THIS_MODULE, | ||
| 581 | .cra_list = LIST_HEAD_INIT(twofish_algs[9].cra_list), | ||
| 582 | .cra_init = ablk_init, | ||
| 583 | .cra_exit = ablk_exit, | ||
| 584 | .cra_u = { | ||
| 585 | .ablkcipher = { | ||
| 586 | .min_keysize = TF_MIN_KEY_SIZE * 2, | ||
| 587 | .max_keysize = TF_MAX_KEY_SIZE * 2, | ||
| 588 | .ivsize = TF_BLOCK_SIZE, | ||
| 589 | .setkey = ablk_set_key, | ||
| 590 | .encrypt = ablk_encrypt, | ||
| 591 | .decrypt = ablk_decrypt, | ||
| 592 | }, | ||
| 593 | }, | ||
| 594 | } }; | ||
| 595 | |||
| 596 | static int __init twofish_init(void) | ||
| 597 | { | ||
| 598 | u64 xcr0; | ||
| 599 | |||
| 600 | if (!cpu_has_avx || !cpu_has_osxsave) { | ||
| 601 | printk(KERN_INFO "AVX instructions are not detected.\n"); | ||
| 602 | return -ENODEV; | ||
| 603 | } | ||
| 604 | |||
| 605 | xcr0 = xgetbv(XCR_XFEATURE_ENABLED_MASK); | ||
| 606 | if ((xcr0 & (XSTATE_SSE | XSTATE_YMM)) != (XSTATE_SSE | XSTATE_YMM)) { | ||
| 607 | printk(KERN_INFO "AVX detected but unusable.\n"); | ||
| 608 | return -ENODEV; | ||
| 609 | } | ||
| 610 | |||
| 611 | return crypto_register_algs(twofish_algs, ARRAY_SIZE(twofish_algs)); | ||
| 612 | } | ||
| 613 | |||
| 614 | static void __exit twofish_exit(void) | ||
| 615 | { | ||
| 616 | crypto_unregister_algs(twofish_algs, ARRAY_SIZE(twofish_algs)); | ||
| 617 | } | ||
| 618 | |||
| 619 | module_init(twofish_init); | ||
| 620 | module_exit(twofish_exit); | ||
| 621 | |||
| 622 | MODULE_DESCRIPTION("Twofish Cipher Algorithm, AVX optimized"); | ||
| 623 | MODULE_LICENSE("GPL"); | ||
| 624 | MODULE_ALIAS("twofish"); | ||
diff --git a/arch/x86/crypto/twofish_glue_3way.c b/arch/x86/crypto/twofish_glue_3way.c index 922ab24cce31..15f9347316c8 100644 --- a/arch/x86/crypto/twofish_glue_3way.c +++ b/arch/x86/crypto/twofish_glue_3way.c | |||
| @@ -3,11 +3,6 @@ | |||
| 3 | * | 3 | * |
| 4 | * Copyright (c) 2011 Jussi Kivilinna <jussi.kivilinna@mbnet.fi> | 4 | * Copyright (c) 2011 Jussi Kivilinna <jussi.kivilinna@mbnet.fi> |
| 5 | * | 5 | * |
| 6 | * CBC & ECB parts based on code (crypto/cbc.c,ecb.c) by: | ||
| 7 | * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au> | ||
| 8 | * CTR part based on code (crypto/ctr.c) by: | ||
| 9 | * (C) Copyright IBM Corp. 2007 - Joy Latten <latten@us.ibm.com> | ||
| 10 | * | ||
| 11 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
| 12 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
| 13 | * the Free Software Foundation; either version 2 of the License, or | 8 | * the Free Software Foundation; either version 2 of the License, or |
| @@ -33,20 +28,13 @@ | |||
| 33 | #include <crypto/algapi.h> | 28 | #include <crypto/algapi.h> |
| 34 | #include <crypto/twofish.h> | 29 | #include <crypto/twofish.h> |
| 35 | #include <crypto/b128ops.h> | 30 | #include <crypto/b128ops.h> |
| 31 | #include <asm/crypto/twofish.h> | ||
| 32 | #include <asm/crypto/glue_helper.h> | ||
| 36 | #include <crypto/lrw.h> | 33 | #include <crypto/lrw.h> |
| 37 | #include <crypto/xts.h> | 34 | #include <crypto/xts.h> |
| 38 | 35 | ||
| 39 | /* regular block cipher functions from twofish_x86_64 module */ | 36 | EXPORT_SYMBOL_GPL(__twofish_enc_blk_3way); |
| 40 | asmlinkage void twofish_enc_blk(struct twofish_ctx *ctx, u8 *dst, | 37 | EXPORT_SYMBOL_GPL(twofish_dec_blk_3way); |
| 41 | const u8 *src); | ||
| 42 | asmlinkage void twofish_dec_blk(struct twofish_ctx *ctx, u8 *dst, | ||
| 43 | const u8 *src); | ||
| 44 | |||
| 45 | /* 3-way parallel cipher functions */ | ||
| 46 | asmlinkage void __twofish_enc_blk_3way(struct twofish_ctx *ctx, u8 *dst, | ||
| 47 | const u8 *src, bool xor); | ||
| 48 | asmlinkage void twofish_dec_blk_3way(struct twofish_ctx *ctx, u8 *dst, | ||
| 49 | const u8 *src); | ||
| 50 | 38 | ||
| 51 | static inline void twofish_enc_blk_3way(struct twofish_ctx *ctx, u8 *dst, | 39 | static inline void twofish_enc_blk_3way(struct twofish_ctx *ctx, u8 *dst, |
| 52 | const u8 *src) | 40 | const u8 *src) |
| @@ -60,311 +48,139 @@ static inline void twofish_enc_blk_xor_3way(struct twofish_ctx *ctx, u8 *dst, | |||
| 60 | __twofish_enc_blk_3way(ctx, dst, src, true); | 48 | __twofish_enc_blk_3way(ctx, dst, src, true); |
| 61 | } | 49 | } |
| 62 | 50 | ||
| 63 | static int ecb_crypt(struct blkcipher_desc *desc, struct blkcipher_walk *walk, | 51 | void twofish_dec_blk_cbc_3way(void *ctx, u128 *dst, const u128 *src) |
| 64 | void (*fn)(struct twofish_ctx *, u8 *, const u8 *), | ||
| 65 | void (*fn_3way)(struct twofish_ctx *, u8 *, const u8 *)) | ||
| 66 | { | ||
| 67 | struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
| 68 | unsigned int bsize = TF_BLOCK_SIZE; | ||
| 69 | unsigned int nbytes; | ||
| 70 | int err; | ||
| 71 | |||
| 72 | err = blkcipher_walk_virt(desc, walk); | ||
| 73 | |||
| 74 | while ((nbytes = walk->nbytes)) { | ||
| 75 | u8 *wsrc = walk->src.virt.addr; | ||
| 76 | u8 *wdst = walk->dst.virt.addr; | ||
| 77 | |||
| 78 | /* Process three block batch */ | ||
| 79 | if (nbytes >= bsize * 3) { | ||
| 80 | do { | ||
| 81 | fn_3way(ctx, wdst, wsrc); | ||
| 82 | |||
| 83 | wsrc += bsize * 3; | ||
| 84 | wdst += bsize * 3; | ||
| 85 | nbytes -= bsize * 3; | ||
| 86 | } while (nbytes >= bsize * 3); | ||
| 87 | |||
| 88 | if (nbytes < bsize) | ||
| 89 | goto done; | ||
| 90 | } | ||
| 91 | |||
| 92 | /* Handle leftovers */ | ||
| 93 | do { | ||
| 94 | fn(ctx, wdst, wsrc); | ||
| 95 | |||
| 96 | wsrc += bsize; | ||
| 97 | wdst += bsize; | ||
| 98 | nbytes -= bsize; | ||
| 99 | } while (nbytes >= bsize); | ||
| 100 | |||
| 101 | done: | ||
| 102 | err = blkcipher_walk_done(desc, walk, nbytes); | ||
| 103 | } | ||
| 104 | |||
| 105 | return err; | ||
| 106 | } | ||
| 107 | |||
| 108 | static int ecb_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | ||
| 109 | struct scatterlist *src, unsigned int nbytes) | ||
| 110 | { | 52 | { |
| 111 | struct blkcipher_walk walk; | 53 | u128 ivs[2]; |
| 112 | 54 | ||
| 113 | blkcipher_walk_init(&walk, dst, src, nbytes); | 55 | ivs[0] = src[0]; |
| 114 | return ecb_crypt(desc, &walk, twofish_enc_blk, twofish_enc_blk_3way); | 56 | ivs[1] = src[1]; |
| 115 | } | ||
| 116 | 57 | ||
| 117 | static int ecb_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | 58 | twofish_dec_blk_3way(ctx, (u8 *)dst, (u8 *)src); |
| 118 | struct scatterlist *src, unsigned int nbytes) | ||
| 119 | { | ||
| 120 | struct blkcipher_walk walk; | ||
| 121 | 59 | ||
| 122 | blkcipher_walk_init(&walk, dst, src, nbytes); | 60 | u128_xor(&dst[1], &dst[1], &ivs[0]); |
| 123 | return ecb_crypt(desc, &walk, twofish_dec_blk, twofish_dec_blk_3way); | 61 | u128_xor(&dst[2], &dst[2], &ivs[1]); |
| 124 | } | 62 | } |
| 63 | EXPORT_SYMBOL_GPL(twofish_dec_blk_cbc_3way); | ||
| 125 | 64 | ||
| 126 | static unsigned int __cbc_encrypt(struct blkcipher_desc *desc, | 65 | void twofish_enc_blk_ctr(void *ctx, u128 *dst, const u128 *src, u128 *iv) |
| 127 | struct blkcipher_walk *walk) | ||
| 128 | { | ||
| 129 | struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
| 130 | unsigned int bsize = TF_BLOCK_SIZE; | ||
| 131 | unsigned int nbytes = walk->nbytes; | ||
| 132 | u128 *src = (u128 *)walk->src.virt.addr; | ||
| 133 | u128 *dst = (u128 *)walk->dst.virt.addr; | ||
| 134 | u128 *iv = (u128 *)walk->iv; | ||
| 135 | |||
| 136 | do { | ||
| 137 | u128_xor(dst, src, iv); | ||
| 138 | twofish_enc_blk(ctx, (u8 *)dst, (u8 *)dst); | ||
| 139 | iv = dst; | ||
| 140 | |||
| 141 | src += 1; | ||
| 142 | dst += 1; | ||
| 143 | nbytes -= bsize; | ||
| 144 | } while (nbytes >= bsize); | ||
| 145 | |||
| 146 | u128_xor((u128 *)walk->iv, (u128 *)walk->iv, iv); | ||
| 147 | return nbytes; | ||
| 148 | } | ||
| 149 | |||
| 150 | static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | ||
| 151 | struct scatterlist *src, unsigned int nbytes) | ||
| 152 | { | 66 | { |
| 153 | struct blkcipher_walk walk; | 67 | be128 ctrblk; |
| 154 | int err; | ||
| 155 | 68 | ||
| 156 | blkcipher_walk_init(&walk, dst, src, nbytes); | 69 | if (dst != src) |
| 157 | err = blkcipher_walk_virt(desc, &walk); | 70 | *dst = *src; |
| 158 | 71 | ||
| 159 | while ((nbytes = walk.nbytes)) { | 72 | u128_to_be128(&ctrblk, iv); |
| 160 | nbytes = __cbc_encrypt(desc, &walk); | 73 | u128_inc(iv); |
| 161 | err = blkcipher_walk_done(desc, &walk, nbytes); | ||
| 162 | } | ||
| 163 | 74 | ||
| 164 | return err; | 75 | twofish_enc_blk(ctx, (u8 *)&ctrblk, (u8 *)&ctrblk); |
| 76 | u128_xor(dst, dst, (u128 *)&ctrblk); | ||
| 165 | } | 77 | } |
| 78 | EXPORT_SYMBOL_GPL(twofish_enc_blk_ctr); | ||
| 166 | 79 | ||
| 167 | static unsigned int __cbc_decrypt(struct blkcipher_desc *desc, | 80 | void twofish_enc_blk_ctr_3way(void *ctx, u128 *dst, const u128 *src, |
| 168 | struct blkcipher_walk *walk) | 81 | u128 *iv) |
| 169 | { | 82 | { |
| 170 | struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | 83 | be128 ctrblks[3]; |
| 171 | unsigned int bsize = TF_BLOCK_SIZE; | ||
| 172 | unsigned int nbytes = walk->nbytes; | ||
| 173 | u128 *src = (u128 *)walk->src.virt.addr; | ||
| 174 | u128 *dst = (u128 *)walk->dst.virt.addr; | ||
| 175 | u128 ivs[3 - 1]; | ||
| 176 | u128 last_iv; | ||
| 177 | |||
| 178 | /* Start of the last block. */ | ||
| 179 | src += nbytes / bsize - 1; | ||
| 180 | dst += nbytes / bsize - 1; | ||
| 181 | |||
| 182 | last_iv = *src; | ||
| 183 | |||
| 184 | /* Process three block batch */ | ||
| 185 | if (nbytes >= bsize * 3) { | ||
| 186 | do { | ||
| 187 | nbytes -= bsize * (3 - 1); | ||
| 188 | src -= 3 - 1; | ||
| 189 | dst -= 3 - 1; | ||
| 190 | |||
| 191 | ivs[0] = src[0]; | ||
| 192 | ivs[1] = src[1]; | ||
| 193 | |||
| 194 | twofish_dec_blk_3way(ctx, (u8 *)dst, (u8 *)src); | ||
| 195 | |||
| 196 | u128_xor(dst + 1, dst + 1, ivs + 0); | ||
| 197 | u128_xor(dst + 2, dst + 2, ivs + 1); | ||
| 198 | |||
| 199 | nbytes -= bsize; | ||
| 200 | if (nbytes < bsize) | ||
| 201 | goto done; | ||
| 202 | |||
| 203 | u128_xor(dst, dst, src - 1); | ||
| 204 | src -= 1; | ||
| 205 | dst -= 1; | ||
| 206 | } while (nbytes >= bsize * 3); | ||
| 207 | |||
| 208 | if (nbytes < bsize) | ||
| 209 | goto done; | ||
| 210 | } | ||
| 211 | |||
| 212 | /* Handle leftovers */ | ||
| 213 | for (;;) { | ||
| 214 | twofish_dec_blk(ctx, (u8 *)dst, (u8 *)src); | ||
| 215 | |||
| 216 | nbytes -= bsize; | ||
| 217 | if (nbytes < bsize) | ||
| 218 | break; | ||
| 219 | 84 | ||
| 220 | u128_xor(dst, dst, src - 1); | 85 | if (dst != src) { |
| 221 | src -= 1; | 86 | dst[0] = src[0]; |
| 222 | dst -= 1; | 87 | dst[1] = src[1]; |
| 88 | dst[2] = src[2]; | ||
| 223 | } | 89 | } |
| 224 | 90 | ||
| 225 | done: | 91 | u128_to_be128(&ctrblks[0], iv); |
| 226 | u128_xor(dst, dst, (u128 *)walk->iv); | 92 | u128_inc(iv); |
| 227 | *(u128 *)walk->iv = last_iv; | 93 | u128_to_be128(&ctrblks[1], iv); |
| 94 | u128_inc(iv); | ||
| 95 | u128_to_be128(&ctrblks[2], iv); | ||
| 96 | u128_inc(iv); | ||
| 228 | 97 | ||
| 229 | return nbytes; | 98 | twofish_enc_blk_xor_3way(ctx, (u8 *)dst, (u8 *)ctrblks); |
| 230 | } | 99 | } |
| 100 | EXPORT_SYMBOL_GPL(twofish_enc_blk_ctr_3way); | ||
| 101 | |||
| 102 | static const struct common_glue_ctx twofish_enc = { | ||
| 103 | .num_funcs = 2, | ||
| 104 | .fpu_blocks_limit = -1, | ||
| 105 | |||
| 106 | .funcs = { { | ||
| 107 | .num_blocks = 3, | ||
| 108 | .fn_u = { .ecb = GLUE_FUNC_CAST(twofish_enc_blk_3way) } | ||
| 109 | }, { | ||
| 110 | .num_blocks = 1, | ||
| 111 | .fn_u = { .ecb = GLUE_FUNC_CAST(twofish_enc_blk) } | ||
| 112 | } } | ||
| 113 | }; | ||
| 231 | 114 | ||
| 232 | static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | 115 | static const struct common_glue_ctx twofish_ctr = { |
| 233 | struct scatterlist *src, unsigned int nbytes) | 116 | .num_funcs = 2, |
| 234 | { | 117 | .fpu_blocks_limit = -1, |
| 235 | struct blkcipher_walk walk; | 118 | |
| 236 | int err; | 119 | .funcs = { { |
| 237 | 120 | .num_blocks = 3, | |
| 238 | blkcipher_walk_init(&walk, dst, src, nbytes); | 121 | .fn_u = { .ecb = GLUE_FUNC_CAST(twofish_enc_blk_ctr_3way) } |
| 239 | err = blkcipher_walk_virt(desc, &walk); | 122 | }, { |
| 123 | .num_blocks = 1, | ||
| 124 | .fn_u = { .ecb = GLUE_FUNC_CAST(twofish_enc_blk_ctr) } | ||
| 125 | } } | ||
| 126 | }; | ||
| 240 | 127 | ||
| 241 | while ((nbytes = walk.nbytes)) { | 128 | static const struct common_glue_ctx twofish_dec = { |
| 242 | nbytes = __cbc_decrypt(desc, &walk); | 129 | .num_funcs = 2, |
| 243 | err = blkcipher_walk_done(desc, &walk, nbytes); | 130 | .fpu_blocks_limit = -1, |
| 244 | } | 131 | |
| 132 | .funcs = { { | ||
| 133 | .num_blocks = 3, | ||
| 134 | .fn_u = { .ecb = GLUE_FUNC_CAST(twofish_dec_blk_3way) } | ||
| 135 | }, { | ||
| 136 | .num_blocks = 1, | ||
| 137 | .fn_u = { .ecb = GLUE_FUNC_CAST(twofish_dec_blk) } | ||
| 138 | } } | ||
| 139 | }; | ||
| 245 | 140 | ||
| 246 | return err; | 141 | static const struct common_glue_ctx twofish_dec_cbc = { |
| 247 | } | 142 | .num_funcs = 2, |
| 143 | .fpu_blocks_limit = -1, | ||
| 144 | |||
| 145 | .funcs = { { | ||
| 146 | .num_blocks = 3, | ||
| 147 | .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(twofish_dec_blk_cbc_3way) } | ||
| 148 | }, { | ||
| 149 | .num_blocks = 1, | ||
| 150 | .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(twofish_dec_blk) } | ||
| 151 | } } | ||
| 152 | }; | ||
| 248 | 153 | ||
| 249 | static inline void u128_to_be128(be128 *dst, const u128 *src) | 154 | static int ecb_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, |
| 155 | struct scatterlist *src, unsigned int nbytes) | ||
| 250 | { | 156 | { |
| 251 | dst->a = cpu_to_be64(src->a); | 157 | return glue_ecb_crypt_128bit(&twofish_enc, desc, dst, src, nbytes); |
| 252 | dst->b = cpu_to_be64(src->b); | ||
| 253 | } | 158 | } |
| 254 | 159 | ||
| 255 | static inline void be128_to_u128(u128 *dst, const be128 *src) | 160 | static int ecb_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, |
| 161 | struct scatterlist *src, unsigned int nbytes) | ||
| 256 | { | 162 | { |
| 257 | dst->a = be64_to_cpu(src->a); | 163 | return glue_ecb_crypt_128bit(&twofish_dec, desc, dst, src, nbytes); |
| 258 | dst->b = be64_to_cpu(src->b); | ||
| 259 | } | 164 | } |
| 260 | 165 | ||
| 261 | static inline void u128_inc(u128 *i) | 166 | static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, |
| 167 | struct scatterlist *src, unsigned int nbytes) | ||
| 262 | { | 168 | { |
| 263 | i->b++; | 169 | return glue_cbc_encrypt_128bit(GLUE_FUNC_CAST(twofish_enc_blk), desc, |
| 264 | if (!i->b) | 170 | dst, src, nbytes); |
| 265 | i->a++; | ||
| 266 | } | 171 | } |
| 267 | 172 | ||
| 268 | static void ctr_crypt_final(struct blkcipher_desc *desc, | 173 | static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, |
| 269 | struct blkcipher_walk *walk) | 174 | struct scatterlist *src, unsigned int nbytes) |
| 270 | { | 175 | { |
| 271 | struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | 176 | return glue_cbc_decrypt_128bit(&twofish_dec_cbc, desc, dst, src, |
| 272 | u8 *ctrblk = walk->iv; | 177 | nbytes); |
| 273 | u8 keystream[TF_BLOCK_SIZE]; | ||
| 274 | u8 *src = walk->src.virt.addr; | ||
| 275 | u8 *dst = walk->dst.virt.addr; | ||
| 276 | unsigned int nbytes = walk->nbytes; | ||
| 277 | |||
| 278 | twofish_enc_blk(ctx, keystream, ctrblk); | ||
| 279 | crypto_xor(keystream, src, nbytes); | ||
| 280 | memcpy(dst, keystream, nbytes); | ||
| 281 | |||
| 282 | crypto_inc(ctrblk, TF_BLOCK_SIZE); | ||
| 283 | } | ||
| 284 | |||
| 285 | static unsigned int __ctr_crypt(struct blkcipher_desc *desc, | ||
| 286 | struct blkcipher_walk *walk) | ||
| 287 | { | ||
| 288 | struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
| 289 | unsigned int bsize = TF_BLOCK_SIZE; | ||
| 290 | unsigned int nbytes = walk->nbytes; | ||
| 291 | u128 *src = (u128 *)walk->src.virt.addr; | ||
| 292 | u128 *dst = (u128 *)walk->dst.virt.addr; | ||
| 293 | u128 ctrblk; | ||
| 294 | be128 ctrblocks[3]; | ||
| 295 | |||
| 296 | be128_to_u128(&ctrblk, (be128 *)walk->iv); | ||
| 297 | |||
| 298 | /* Process three block batch */ | ||
| 299 | if (nbytes >= bsize * 3) { | ||
| 300 | do { | ||
| 301 | if (dst != src) { | ||
| 302 | dst[0] = src[0]; | ||
| 303 | dst[1] = src[1]; | ||
| 304 | dst[2] = src[2]; | ||
| 305 | } | ||
| 306 | |||
| 307 | /* create ctrblks for parallel encrypt */ | ||
| 308 | u128_to_be128(&ctrblocks[0], &ctrblk); | ||
| 309 | u128_inc(&ctrblk); | ||
| 310 | u128_to_be128(&ctrblocks[1], &ctrblk); | ||
| 311 | u128_inc(&ctrblk); | ||
| 312 | u128_to_be128(&ctrblocks[2], &ctrblk); | ||
| 313 | u128_inc(&ctrblk); | ||
| 314 | |||
| 315 | twofish_enc_blk_xor_3way(ctx, (u8 *)dst, | ||
| 316 | (u8 *)ctrblocks); | ||
| 317 | |||
| 318 | src += 3; | ||
| 319 | dst += 3; | ||
| 320 | nbytes -= bsize * 3; | ||
| 321 | } while (nbytes >= bsize * 3); | ||
| 322 | |||
| 323 | if (nbytes < bsize) | ||
| 324 | goto done; | ||
| 325 | } | ||
| 326 | |||
| 327 | /* Handle leftovers */ | ||
| 328 | do { | ||
| 329 | if (dst != src) | ||
| 330 | *dst = *src; | ||
| 331 | |||
| 332 | u128_to_be128(&ctrblocks[0], &ctrblk); | ||
| 333 | u128_inc(&ctrblk); | ||
| 334 | |||
| 335 | twofish_enc_blk(ctx, (u8 *)ctrblocks, (u8 *)ctrblocks); | ||
| 336 | u128_xor(dst, dst, (u128 *)ctrblocks); | ||
| 337 | |||
| 338 | src += 1; | ||
| 339 | dst += 1; | ||
| 340 | nbytes -= bsize; | ||
| 341 | } while (nbytes >= bsize); | ||
| 342 | |||
| 343 | done: | ||
| 344 | u128_to_be128((be128 *)walk->iv, &ctrblk); | ||
| 345 | return nbytes; | ||
| 346 | } | 178 | } |
| 347 | 179 | ||
| 348 | static int ctr_crypt(struct blkcipher_desc *desc, struct scatterlist *dst, | 180 | static int ctr_crypt(struct blkcipher_desc *desc, struct scatterlist *dst, |
| 349 | struct scatterlist *src, unsigned int nbytes) | 181 | struct scatterlist *src, unsigned int nbytes) |
| 350 | { | 182 | { |
| 351 | struct blkcipher_walk walk; | 183 | return glue_ctr_crypt_128bit(&twofish_ctr, desc, dst, src, nbytes); |
| 352 | int err; | ||
| 353 | |||
| 354 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
| 355 | err = blkcipher_walk_virt_block(desc, &walk, TF_BLOCK_SIZE); | ||
| 356 | |||
| 357 | while ((nbytes = walk.nbytes) >= TF_BLOCK_SIZE) { | ||
| 358 | nbytes = __ctr_crypt(desc, &walk); | ||
| 359 | err = blkcipher_walk_done(desc, &walk, nbytes); | ||
| 360 | } | ||
| 361 | |||
| 362 | if (walk.nbytes) { | ||
| 363 | ctr_crypt_final(desc, &walk); | ||
| 364 | err = blkcipher_walk_done(desc, &walk, 0); | ||
| 365 | } | ||
| 366 | |||
| 367 | return err; | ||
| 368 | } | 184 | } |
| 369 | 185 | ||
| 370 | static void encrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) | 186 | static void encrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) |
| @@ -397,13 +213,8 @@ static void decrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) | |||
| 397 | twofish_dec_blk(ctx, srcdst, srcdst); | 213 | twofish_dec_blk(ctx, srcdst, srcdst); |
| 398 | } | 214 | } |
| 399 | 215 | ||
| 400 | struct twofish_lrw_ctx { | 216 | int lrw_twofish_setkey(struct crypto_tfm *tfm, const u8 *key, |
| 401 | struct lrw_table_ctx lrw_table; | 217 | unsigned int keylen) |
| 402 | struct twofish_ctx twofish_ctx; | ||
| 403 | }; | ||
| 404 | |||
| 405 | static int lrw_twofish_setkey(struct crypto_tfm *tfm, const u8 *key, | ||
| 406 | unsigned int keylen) | ||
| 407 | { | 218 | { |
| 408 | struct twofish_lrw_ctx *ctx = crypto_tfm_ctx(tfm); | 219 | struct twofish_lrw_ctx *ctx = crypto_tfm_ctx(tfm); |
| 409 | int err; | 220 | int err; |
| @@ -415,6 +226,7 @@ static int lrw_twofish_setkey(struct crypto_tfm *tfm, const u8 *key, | |||
| 415 | 226 | ||
| 416 | return lrw_init_table(&ctx->lrw_table, key + keylen - TF_BLOCK_SIZE); | 227 | return lrw_init_table(&ctx->lrw_table, key + keylen - TF_BLOCK_SIZE); |
| 417 | } | 228 | } |
| 229 | EXPORT_SYMBOL_GPL(lrw_twofish_setkey); | ||
| 418 | 230 | ||
| 419 | static int lrw_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | 231 | static int lrw_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, |
| 420 | struct scatterlist *src, unsigned int nbytes) | 232 | struct scatterlist *src, unsigned int nbytes) |
| @@ -450,20 +262,16 @@ static int lrw_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | |||
| 450 | return lrw_crypt(desc, dst, src, nbytes, &req); | 262 | return lrw_crypt(desc, dst, src, nbytes, &req); |
| 451 | } | 263 | } |
| 452 | 264 | ||
| 453 | static void lrw_exit_tfm(struct crypto_tfm *tfm) | 265 | void lrw_twofish_exit_tfm(struct crypto_tfm *tfm) |
| 454 | { | 266 | { |
| 455 | struct twofish_lrw_ctx *ctx = crypto_tfm_ctx(tfm); | 267 | struct twofish_lrw_ctx *ctx = crypto_tfm_ctx(tfm); |
| 456 | 268 | ||
| 457 | lrw_free_table(&ctx->lrw_table); | 269 | lrw_free_table(&ctx->lrw_table); |
| 458 | } | 270 | } |
| 271 | EXPORT_SYMBOL_GPL(lrw_twofish_exit_tfm); | ||
| 459 | 272 | ||
| 460 | struct twofish_xts_ctx { | 273 | int xts_twofish_setkey(struct crypto_tfm *tfm, const u8 *key, |
| 461 | struct twofish_ctx tweak_ctx; | 274 | unsigned int keylen) |
| 462 | struct twofish_ctx crypt_ctx; | ||
| 463 | }; | ||
| 464 | |||
| 465 | static int xts_twofish_setkey(struct crypto_tfm *tfm, const u8 *key, | ||
| 466 | unsigned int keylen) | ||
| 467 | { | 275 | { |
| 468 | struct twofish_xts_ctx *ctx = crypto_tfm_ctx(tfm); | 276 | struct twofish_xts_ctx *ctx = crypto_tfm_ctx(tfm); |
| 469 | u32 *flags = &tfm->crt_flags; | 277 | u32 *flags = &tfm->crt_flags; |
| @@ -486,6 +294,7 @@ static int xts_twofish_setkey(struct crypto_tfm *tfm, const u8 *key, | |||
| 486 | return __twofish_setkey(&ctx->tweak_ctx, key + keylen / 2, keylen / 2, | 294 | return __twofish_setkey(&ctx->tweak_ctx, key + keylen / 2, keylen / 2, |
| 487 | flags); | 295 | flags); |
| 488 | } | 296 | } |
| 297 | EXPORT_SYMBOL_GPL(xts_twofish_setkey); | ||
| 489 | 298 | ||
| 490 | static int xts_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | 299 | static int xts_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, |
| 491 | struct scatterlist *src, unsigned int nbytes) | 300 | struct scatterlist *src, unsigned int nbytes) |
| @@ -596,7 +405,7 @@ static struct crypto_alg tf_algs[5] = { { | |||
| 596 | .cra_type = &crypto_blkcipher_type, | 405 | .cra_type = &crypto_blkcipher_type, |
| 597 | .cra_module = THIS_MODULE, | 406 | .cra_module = THIS_MODULE, |
| 598 | .cra_list = LIST_HEAD_INIT(tf_algs[3].cra_list), | 407 | .cra_list = LIST_HEAD_INIT(tf_algs[3].cra_list), |
| 599 | .cra_exit = lrw_exit_tfm, | 408 | .cra_exit = lrw_twofish_exit_tfm, |
| 600 | .cra_u = { | 409 | .cra_u = { |
| 601 | .blkcipher = { | 410 | .blkcipher = { |
| 602 | .min_keysize = TF_MIN_KEY_SIZE + TF_BLOCK_SIZE, | 411 | .min_keysize = TF_MIN_KEY_SIZE + TF_BLOCK_SIZE, |
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index 3ea51a84a0e4..f34261296ffb 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h | |||
| @@ -546,7 +546,7 @@ static inline const struct cpumask *online_target_cpus(void) | |||
| 546 | return cpu_online_mask; | 546 | return cpu_online_mask; |
| 547 | } | 547 | } |
| 548 | 548 | ||
| 549 | DECLARE_EARLY_PER_CPU(u16, x86_bios_cpu_apicid); | 549 | DECLARE_EARLY_PER_CPU_READ_MOSTLY(u16, x86_bios_cpu_apicid); |
| 550 | 550 | ||
| 551 | 551 | ||
| 552 | static inline unsigned int read_apic_id(void) | 552 | static inline unsigned int read_apic_id(void) |
diff --git a/arch/x86/include/asm/bootparam.h b/arch/x86/include/asm/bootparam.h index eb45aa6b1f27..2ad874cb661c 100644 --- a/arch/x86/include/asm/bootparam.h +++ b/arch/x86/include/asm/bootparam.h | |||
| @@ -66,6 +66,7 @@ struct setup_header { | |||
| 66 | __u64 setup_data; | 66 | __u64 setup_data; |
| 67 | __u64 pref_address; | 67 | __u64 pref_address; |
| 68 | __u32 init_size; | 68 | __u32 init_size; |
| 69 | __u32 handover_offset; | ||
| 69 | } __attribute__((packed)); | 70 | } __attribute__((packed)); |
| 70 | 71 | ||
| 71 | struct sys_desc_table { | 72 | struct sys_desc_table { |
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index f91e80f4f180..6b7ee5ff6820 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h | |||
| @@ -207,6 +207,8 @@ | |||
| 207 | #define X86_FEATURE_ERMS (9*32+ 9) /* Enhanced REP MOVSB/STOSB */ | 207 | #define X86_FEATURE_ERMS (9*32+ 9) /* Enhanced REP MOVSB/STOSB */ |
| 208 | #define X86_FEATURE_INVPCID (9*32+10) /* Invalidate Processor Context ID */ | 208 | #define X86_FEATURE_INVPCID (9*32+10) /* Invalidate Processor Context ID */ |
| 209 | #define X86_FEATURE_RTM (9*32+11) /* Restricted Transactional Memory */ | 209 | #define X86_FEATURE_RTM (9*32+11) /* Restricted Transactional Memory */ |
| 210 | #define X86_FEATURE_RDSEED (9*32+18) /* The RDSEED instruction */ | ||
| 211 | #define X86_FEATURE_ADX (9*32+19) /* The ADCX and ADOX instructions */ | ||
| 210 | 212 | ||
| 211 | #if defined(__KERNEL__) && !defined(__ASSEMBLY__) | 213 | #if defined(__KERNEL__) && !defined(__ASSEMBLY__) |
| 212 | 214 | ||
diff --git a/arch/x86/include/asm/crypto/ablk_helper.h b/arch/x86/include/asm/crypto/ablk_helper.h new file mode 100644 index 000000000000..4f93df50c23e --- /dev/null +++ b/arch/x86/include/asm/crypto/ablk_helper.h | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | /* | ||
| 2 | * Shared async block cipher helpers | ||
| 3 | */ | ||
| 4 | |||
| 5 | #ifndef _CRYPTO_ABLK_HELPER_H | ||
| 6 | #define _CRYPTO_ABLK_HELPER_H | ||
| 7 | |||
| 8 | #include <linux/crypto.h> | ||
| 9 | #include <linux/kernel.h> | ||
| 10 | #include <crypto/cryptd.h> | ||
| 11 | |||
| 12 | struct async_helper_ctx { | ||
| 13 | struct cryptd_ablkcipher *cryptd_tfm; | ||
| 14 | }; | ||
| 15 | |||
| 16 | extern int ablk_set_key(struct crypto_ablkcipher *tfm, const u8 *key, | ||
| 17 | unsigned int key_len); | ||
| 18 | |||
| 19 | extern int __ablk_encrypt(struct ablkcipher_request *req); | ||
| 20 | |||
| 21 | extern int ablk_encrypt(struct ablkcipher_request *req); | ||
| 22 | |||
| 23 | extern int ablk_decrypt(struct ablkcipher_request *req); | ||
| 24 | |||
| 25 | extern void ablk_exit(struct crypto_tfm *tfm); | ||
| 26 | |||
| 27 | extern int ablk_init_common(struct crypto_tfm *tfm, const char *drv_name); | ||
| 28 | |||
| 29 | extern int ablk_init(struct crypto_tfm *tfm); | ||
| 30 | |||
| 31 | #endif /* _CRYPTO_ABLK_HELPER_H */ | ||
diff --git a/arch/x86/include/asm/aes.h b/arch/x86/include/asm/crypto/aes.h index 80545a1cbe39..80545a1cbe39 100644 --- a/arch/x86/include/asm/aes.h +++ b/arch/x86/include/asm/crypto/aes.h | |||
diff --git a/arch/x86/include/asm/crypto/glue_helper.h b/arch/x86/include/asm/crypto/glue_helper.h new file mode 100644 index 000000000000..3e408bddc96f --- /dev/null +++ b/arch/x86/include/asm/crypto/glue_helper.h | |||
| @@ -0,0 +1,115 @@ | |||
| 1 | /* | ||
| 2 | * Shared glue code for 128bit block ciphers | ||
| 3 | */ | ||
| 4 | |||
| 5 | #ifndef _CRYPTO_GLUE_HELPER_H | ||
| 6 | #define _CRYPTO_GLUE_HELPER_H | ||
| 7 | |||
| 8 | #include <linux/kernel.h> | ||
| 9 | #include <linux/crypto.h> | ||
| 10 | #include <asm/i387.h> | ||
| 11 | #include <crypto/b128ops.h> | ||
| 12 | |||
| 13 | typedef void (*common_glue_func_t)(void *ctx, u8 *dst, const u8 *src); | ||
| 14 | typedef void (*common_glue_cbc_func_t)(void *ctx, u128 *dst, const u128 *src); | ||
| 15 | typedef void (*common_glue_ctr_func_t)(void *ctx, u128 *dst, const u128 *src, | ||
| 16 | u128 *iv); | ||
| 17 | |||
| 18 | #define GLUE_FUNC_CAST(fn) ((common_glue_func_t)(fn)) | ||
| 19 | #define GLUE_CBC_FUNC_CAST(fn) ((common_glue_cbc_func_t)(fn)) | ||
| 20 | #define GLUE_CTR_FUNC_CAST(fn) ((common_glue_ctr_func_t)(fn)) | ||
| 21 | |||
| 22 | struct common_glue_func_entry { | ||
| 23 | unsigned int num_blocks; /* number of blocks that @fn will process */ | ||
| 24 | union { | ||
| 25 | common_glue_func_t ecb; | ||
| 26 | common_glue_cbc_func_t cbc; | ||
| 27 | common_glue_ctr_func_t ctr; | ||
| 28 | } fn_u; | ||
| 29 | }; | ||
| 30 | |||
| 31 | struct common_glue_ctx { | ||
| 32 | unsigned int num_funcs; | ||
| 33 | int fpu_blocks_limit; /* -1 means fpu not needed at all */ | ||
| 34 | |||
| 35 | /* | ||
| 36 | * First funcs entry must have largest num_blocks and last funcs entry | ||
| 37 | * must have num_blocks == 1! | ||
| 38 | */ | ||
| 39 | struct common_glue_func_entry funcs[]; | ||
| 40 | }; | ||
| 41 | |||
| 42 | static inline bool glue_fpu_begin(unsigned int bsize, int fpu_blocks_limit, | ||
| 43 | struct blkcipher_desc *desc, | ||
| 44 | bool fpu_enabled, unsigned int nbytes) | ||
| 45 | { | ||
| 46 | if (likely(fpu_blocks_limit < 0)) | ||
| 47 | return false; | ||
| 48 | |||
| 49 | if (fpu_enabled) | ||
| 50 | return true; | ||
| 51 | |||
| 52 | /* | ||
| 53 | * Vector-registers are only used when chunk to be processed is large | ||
| 54 | * enough, so do not enable FPU until it is necessary. | ||
| 55 | */ | ||
| 56 | if (nbytes < bsize * (unsigned int)fpu_blocks_limit) | ||
| 57 | return false; | ||
| 58 | |||
| 59 | if (desc) { | ||
| 60 | /* prevent sleeping if FPU is in use */ | ||
| 61 | desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; | ||
| 62 | } | ||
| 63 | |||
| 64 | kernel_fpu_begin(); | ||
| 65 | return true; | ||
| 66 | } | ||
| 67 | |||
| 68 | static inline void glue_fpu_end(bool fpu_enabled) | ||
| 69 | { | ||
| 70 | if (fpu_enabled) | ||
| 71 | kernel_fpu_end(); | ||
| 72 | } | ||
| 73 | |||
| 74 | static inline void u128_to_be128(be128 *dst, const u128 *src) | ||
| 75 | { | ||
| 76 | dst->a = cpu_to_be64(src->a); | ||
| 77 | dst->b = cpu_to_be64(src->b); | ||
| 78 | } | ||
| 79 | |||
| 80 | static inline void be128_to_u128(u128 *dst, const be128 *src) | ||
| 81 | { | ||
| 82 | dst->a = be64_to_cpu(src->a); | ||
| 83 | dst->b = be64_to_cpu(src->b); | ||
| 84 | } | ||
| 85 | |||
| 86 | static inline void u128_inc(u128 *i) | ||
| 87 | { | ||
| 88 | i->b++; | ||
| 89 | if (!i->b) | ||
| 90 | i->a++; | ||
| 91 | } | ||
| 92 | |||
| 93 | extern int glue_ecb_crypt_128bit(const struct common_glue_ctx *gctx, | ||
| 94 | struct blkcipher_desc *desc, | ||
| 95 | struct scatterlist *dst, | ||
| 96 | struct scatterlist *src, unsigned int nbytes); | ||
| 97 | |||
| 98 | extern int glue_cbc_encrypt_128bit(const common_glue_func_t fn, | ||
| 99 | struct blkcipher_desc *desc, | ||
| 100 | struct scatterlist *dst, | ||
| 101 | struct scatterlist *src, | ||
| 102 | unsigned int nbytes); | ||
| 103 | |||
| 104 | extern int glue_cbc_decrypt_128bit(const struct common_glue_ctx *gctx, | ||
| 105 | struct blkcipher_desc *desc, | ||
| 106 | struct scatterlist *dst, | ||
| 107 | struct scatterlist *src, | ||
| 108 | unsigned int nbytes); | ||
| 109 | |||
| 110 | extern int glue_ctr_crypt_128bit(const struct common_glue_ctx *gctx, | ||
| 111 | struct blkcipher_desc *desc, | ||
| 112 | struct scatterlist *dst, | ||
| 113 | struct scatterlist *src, unsigned int nbytes); | ||
| 114 | |||
| 115 | #endif /* _CRYPTO_GLUE_HELPER_H */ | ||
diff --git a/arch/x86/include/asm/crypto/serpent-avx.h b/arch/x86/include/asm/crypto/serpent-avx.h new file mode 100644 index 000000000000..432deedd2945 --- /dev/null +++ b/arch/x86/include/asm/crypto/serpent-avx.h | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | #ifndef ASM_X86_SERPENT_AVX_H | ||
| 2 | #define ASM_X86_SERPENT_AVX_H | ||
| 3 | |||
| 4 | #include <linux/crypto.h> | ||
| 5 | #include <crypto/serpent.h> | ||
| 6 | |||
| 7 | #define SERPENT_PARALLEL_BLOCKS 8 | ||
| 8 | |||
| 9 | asmlinkage void __serpent_enc_blk_8way_avx(struct serpent_ctx *ctx, u8 *dst, | ||
| 10 | const u8 *src, bool xor); | ||
| 11 | asmlinkage void serpent_dec_blk_8way_avx(struct serpent_ctx *ctx, u8 *dst, | ||
| 12 | const u8 *src); | ||
| 13 | |||
| 14 | static inline void serpent_enc_blk_xway(struct serpent_ctx *ctx, u8 *dst, | ||
| 15 | const u8 *src) | ||
| 16 | { | ||
| 17 | __serpent_enc_blk_8way_avx(ctx, dst, src, false); | ||
| 18 | } | ||
| 19 | |||
| 20 | static inline void serpent_enc_blk_xway_xor(struct serpent_ctx *ctx, u8 *dst, | ||
| 21 | const u8 *src) | ||
| 22 | { | ||
| 23 | __serpent_enc_blk_8way_avx(ctx, dst, src, true); | ||
| 24 | } | ||
| 25 | |||
| 26 | static inline void serpent_dec_blk_xway(struct serpent_ctx *ctx, u8 *dst, | ||
| 27 | const u8 *src) | ||
| 28 | { | ||
| 29 | serpent_dec_blk_8way_avx(ctx, dst, src); | ||
| 30 | } | ||
| 31 | |||
| 32 | #endif | ||
diff --git a/arch/x86/include/asm/serpent.h b/arch/x86/include/asm/crypto/serpent-sse2.h index d3ef63fe0c81..e6e77dffbdab 100644 --- a/arch/x86/include/asm/serpent.h +++ b/arch/x86/include/asm/crypto/serpent-sse2.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | #ifndef ASM_X86_SERPENT_H | 1 | #ifndef ASM_X86_SERPENT_SSE2_H |
| 2 | #define ASM_X86_SERPENT_H | 2 | #define ASM_X86_SERPENT_SSE2_H |
| 3 | 3 | ||
| 4 | #include <linux/crypto.h> | 4 | #include <linux/crypto.h> |
| 5 | #include <crypto/serpent.h> | 5 | #include <crypto/serpent.h> |
diff --git a/arch/x86/include/asm/crypto/twofish.h b/arch/x86/include/asm/crypto/twofish.h new file mode 100644 index 000000000000..9d2c514bd5f9 --- /dev/null +++ b/arch/x86/include/asm/crypto/twofish.h | |||
| @@ -0,0 +1,46 @@ | |||
| 1 | #ifndef ASM_X86_TWOFISH_H | ||
| 2 | #define ASM_X86_TWOFISH_H | ||
| 3 | |||
| 4 | #include <linux/crypto.h> | ||
| 5 | #include <crypto/twofish.h> | ||
| 6 | #include <crypto/lrw.h> | ||
| 7 | #include <crypto/b128ops.h> | ||
| 8 | |||
| 9 | struct twofish_lrw_ctx { | ||
| 10 | struct lrw_table_ctx lrw_table; | ||
| 11 | struct twofish_ctx twofish_ctx; | ||
| 12 | }; | ||
| 13 | |||
| 14 | struct twofish_xts_ctx { | ||
| 15 | struct twofish_ctx tweak_ctx; | ||
| 16 | struct twofish_ctx crypt_ctx; | ||
| 17 | }; | ||
| 18 | |||
| 19 | /* regular block cipher functions from twofish_x86_64 module */ | ||
| 20 | asmlinkage void twofish_enc_blk(struct twofish_ctx *ctx, u8 *dst, | ||
| 21 | const u8 *src); | ||
| 22 | asmlinkage void twofish_dec_blk(struct twofish_ctx *ctx, u8 *dst, | ||
| 23 | const u8 *src); | ||
| 24 | |||
| 25 | /* 3-way parallel cipher functions */ | ||
| 26 | asmlinkage void __twofish_enc_blk_3way(struct twofish_ctx *ctx, u8 *dst, | ||
| 27 | const u8 *src, bool xor); | ||
| 28 | asmlinkage void twofish_dec_blk_3way(struct twofish_ctx *ctx, u8 *dst, | ||
| 29 | const u8 *src); | ||
| 30 | |||
| 31 | /* helpers from twofish_x86_64-3way module */ | ||
| 32 | extern void twofish_dec_blk_cbc_3way(void *ctx, u128 *dst, const u128 *src); | ||
| 33 | extern void twofish_enc_blk_ctr(void *ctx, u128 *dst, const u128 *src, | ||
| 34 | u128 *iv); | ||
| 35 | extern void twofish_enc_blk_ctr_3way(void *ctx, u128 *dst, const u128 *src, | ||
| 36 | u128 *iv); | ||
| 37 | |||
| 38 | extern int lrw_twofish_setkey(struct crypto_tfm *tfm, const u8 *key, | ||
| 39 | unsigned int keylen); | ||
| 40 | |||
| 41 | extern void lrw_twofish_exit_tfm(struct crypto_tfm *tfm); | ||
| 42 | |||
| 43 | extern int xts_twofish_setkey(struct crypto_tfm *tfm, const u8 *key, | ||
| 44 | unsigned int keylen); | ||
| 45 | |||
| 46 | #endif /* ASM_X86_TWOFISH_H */ | ||
diff --git a/arch/x86/include/asm/entry_arch.h b/arch/x86/include/asm/entry_arch.h index 0baa628e330c..40afa0005c69 100644 --- a/arch/x86/include/asm/entry_arch.h +++ b/arch/x86/include/asm/entry_arch.h | |||
| @@ -15,15 +15,6 @@ BUILD_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR) | |||
| 15 | BUILD_INTERRUPT(call_function_single_interrupt,CALL_FUNCTION_SINGLE_VECTOR) | 15 | BUILD_INTERRUPT(call_function_single_interrupt,CALL_FUNCTION_SINGLE_VECTOR) |
| 16 | BUILD_INTERRUPT(irq_move_cleanup_interrupt,IRQ_MOVE_CLEANUP_VECTOR) | 16 | BUILD_INTERRUPT(irq_move_cleanup_interrupt,IRQ_MOVE_CLEANUP_VECTOR) |
| 17 | BUILD_INTERRUPT(reboot_interrupt,REBOOT_VECTOR) | 17 | BUILD_INTERRUPT(reboot_interrupt,REBOOT_VECTOR) |
| 18 | |||
| 19 | .irp idx,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, \ | ||
| 20 | 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 | ||
| 21 | .if NUM_INVALIDATE_TLB_VECTORS > \idx | ||
| 22 | BUILD_INTERRUPT3(invalidate_interrupt\idx, | ||
| 23 | (INVALIDATE_TLB_VECTOR_START)+\idx, | ||
| 24 | smp_invalidate_interrupt) | ||
| 25 | .endif | ||
| 26 | .endr | ||
| 27 | #endif | 18 | #endif |
| 28 | 19 | ||
| 29 | BUILD_INTERRUPT(x86_platform_ipi, X86_PLATFORM_IPI_VECTOR) | 20 | BUILD_INTERRUPT(x86_platform_ipi, X86_PLATFORM_IPI_VECTOR) |
diff --git a/arch/x86/include/asm/irq_vectors.h b/arch/x86/include/asm/irq_vectors.h index 4b4448761e88..1508e518c7e3 100644 --- a/arch/x86/include/asm/irq_vectors.h +++ b/arch/x86/include/asm/irq_vectors.h | |||
| @@ -119,17 +119,6 @@ | |||
| 119 | */ | 119 | */ |
| 120 | #define LOCAL_TIMER_VECTOR 0xef | 120 | #define LOCAL_TIMER_VECTOR 0xef |
| 121 | 121 | ||
| 122 | /* up to 32 vectors used for spreading out TLB flushes: */ | ||
| 123 | #if NR_CPUS <= 32 | ||
| 124 | # define NUM_INVALIDATE_TLB_VECTORS (NR_CPUS) | ||
| 125 | #else | ||
| 126 | # define NUM_INVALIDATE_TLB_VECTORS (32) | ||
| 127 | #endif | ||
| 128 | |||
| 129 | #define INVALIDATE_TLB_VECTOR_END (0xee) | ||
| 130 | #define INVALIDATE_TLB_VECTOR_START \ | ||
| 131 | (INVALIDATE_TLB_VECTOR_END-NUM_INVALIDATE_TLB_VECTORS+1) | ||
| 132 | |||
| 133 | #define NR_VECTORS 256 | 122 | #define NR_VECTORS 256 |
| 134 | 123 | ||
| 135 | #define FPU_IRQ 13 | 124 | #define FPU_IRQ 13 |
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h index 0b47ddb6f00b..a0facf3908d7 100644 --- a/arch/x86/include/asm/paravirt.h +++ b/arch/x86/include/asm/paravirt.h | |||
| @@ -360,9 +360,10 @@ static inline void __flush_tlb_single(unsigned long addr) | |||
| 360 | 360 | ||
| 361 | static inline void flush_tlb_others(const struct cpumask *cpumask, | 361 | static inline void flush_tlb_others(const struct cpumask *cpumask, |
| 362 | struct mm_struct *mm, | 362 | struct mm_struct *mm, |
| 363 | unsigned long va) | 363 | unsigned long start, |
| 364 | unsigned long end) | ||
| 364 | { | 365 | { |
| 365 | PVOP_VCALL3(pv_mmu_ops.flush_tlb_others, cpumask, mm, va); | 366 | PVOP_VCALL4(pv_mmu_ops.flush_tlb_others, cpumask, mm, start, end); |
| 366 | } | 367 | } |
| 367 | 368 | ||
| 368 | static inline int paravirt_pgd_alloc(struct mm_struct *mm) | 369 | static inline int paravirt_pgd_alloc(struct mm_struct *mm) |
diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h index 8613cbb7ba41..142236ed83af 100644 --- a/arch/x86/include/asm/paravirt_types.h +++ b/arch/x86/include/asm/paravirt_types.h | |||
| @@ -248,7 +248,8 @@ struct pv_mmu_ops { | |||
| 248 | void (*flush_tlb_single)(unsigned long addr); | 248 | void (*flush_tlb_single)(unsigned long addr); |
| 249 | void (*flush_tlb_others)(const struct cpumask *cpus, | 249 | void (*flush_tlb_others)(const struct cpumask *cpus, |
| 250 | struct mm_struct *mm, | 250 | struct mm_struct *mm, |
| 251 | unsigned long va); | 251 | unsigned long start, |
| 252 | unsigned long end); | ||
| 252 | 253 | ||
| 253 | /* Hooks for allocating and freeing a pagetable top-level */ | 254 | /* Hooks for allocating and freeing a pagetable top-level */ |
| 254 | int (*pgd_alloc)(struct mm_struct *mm); | 255 | int (*pgd_alloc)(struct mm_struct *mm); |
diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h index d9b8e3f7f42a..1104afaba52b 100644 --- a/arch/x86/include/asm/percpu.h +++ b/arch/x86/include/asm/percpu.h | |||
| @@ -551,6 +551,12 @@ DECLARE_PER_CPU(unsigned long, this_cpu_off); | |||
| 551 | { [0 ... NR_CPUS-1] = _initvalue }; \ | 551 | { [0 ... NR_CPUS-1] = _initvalue }; \ |
| 552 | __typeof__(_type) *_name##_early_ptr __refdata = _name##_early_map | 552 | __typeof__(_type) *_name##_early_ptr __refdata = _name##_early_map |
| 553 | 553 | ||
| 554 | #define DEFINE_EARLY_PER_CPU_READ_MOSTLY(_type, _name, _initvalue) \ | ||
| 555 | DEFINE_PER_CPU_READ_MOSTLY(_type, _name) = _initvalue; \ | ||
| 556 | __typeof__(_type) _name##_early_map[NR_CPUS] __initdata = \ | ||
| 557 | { [0 ... NR_CPUS-1] = _initvalue }; \ | ||
| 558 | __typeof__(_type) *_name##_early_ptr __refdata = _name##_early_map | ||
| 559 | |||
| 554 | #define EXPORT_EARLY_PER_CPU_SYMBOL(_name) \ | 560 | #define EXPORT_EARLY_PER_CPU_SYMBOL(_name) \ |
| 555 | EXPORT_PER_CPU_SYMBOL(_name) | 561 | EXPORT_PER_CPU_SYMBOL(_name) |
| 556 | 562 | ||
| @@ -559,6 +565,11 @@ DECLARE_PER_CPU(unsigned long, this_cpu_off); | |||
| 559 | extern __typeof__(_type) *_name##_early_ptr; \ | 565 | extern __typeof__(_type) *_name##_early_ptr; \ |
| 560 | extern __typeof__(_type) _name##_early_map[] | 566 | extern __typeof__(_type) _name##_early_map[] |
| 561 | 567 | ||
| 568 | #define DECLARE_EARLY_PER_CPU_READ_MOSTLY(_type, _name) \ | ||
| 569 | DECLARE_PER_CPU_READ_MOSTLY(_type, _name); \ | ||
| 570 | extern __typeof__(_type) *_name##_early_ptr; \ | ||
| 571 | extern __typeof__(_type) _name##_early_map[] | ||
| 572 | |||
| 562 | #define early_per_cpu_ptr(_name) (_name##_early_ptr) | 573 | #define early_per_cpu_ptr(_name) (_name##_early_ptr) |
| 563 | #define early_per_cpu_map(_name, _idx) (_name##_early_map[_idx]) | 574 | #define early_per_cpu_map(_name, _idx) (_name##_early_map[_idx]) |
| 564 | #define early_per_cpu(_name, _cpu) \ | 575 | #define early_per_cpu(_name, _cpu) \ |
| @@ -570,12 +581,18 @@ DECLARE_PER_CPU(unsigned long, this_cpu_off); | |||
| 570 | #define DEFINE_EARLY_PER_CPU(_type, _name, _initvalue) \ | 581 | #define DEFINE_EARLY_PER_CPU(_type, _name, _initvalue) \ |
| 571 | DEFINE_PER_CPU(_type, _name) = _initvalue | 582 | DEFINE_PER_CPU(_type, _name) = _initvalue |
| 572 | 583 | ||
| 584 | #define DEFINE_EARLY_PER_CPU_READ_MOSTLY(_type, _name, _initvalue) \ | ||
| 585 | DEFINE_PER_CPU_READ_MOSTLY(_type, _name) = _initvalue | ||
| 586 | |||
| 573 | #define EXPORT_EARLY_PER_CPU_SYMBOL(_name) \ | 587 | #define EXPORT_EARLY_PER_CPU_SYMBOL(_name) \ |
| 574 | EXPORT_PER_CPU_SYMBOL(_name) | 588 | EXPORT_PER_CPU_SYMBOL(_name) |
| 575 | 589 | ||
| 576 | #define DECLARE_EARLY_PER_CPU(_type, _name) \ | 590 | #define DECLARE_EARLY_PER_CPU(_type, _name) \ |
| 577 | DECLARE_PER_CPU(_type, _name) | 591 | DECLARE_PER_CPU(_type, _name) |
| 578 | 592 | ||
| 593 | #define DECLARE_EARLY_PER_CPU_READ_MOSTLY(_type, _name) \ | ||
| 594 | DECLARE_PER_CPU_READ_MOSTLY(_type, _name) | ||
| 595 | |||
| 579 | #define early_per_cpu(_name, _cpu) per_cpu(_name, _cpu) | 596 | #define early_per_cpu(_name, _cpu) per_cpu(_name, _cpu) |
| 580 | #define early_per_cpu_ptr(_name) NULL | 597 | #define early_per_cpu_ptr(_name) NULL |
| 581 | /* no early_per_cpu_map() */ | 598 | /* no early_per_cpu_map() */ |
diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h index c78f14a0df00..dab39350e51e 100644 --- a/arch/x86/include/asm/perf_event.h +++ b/arch/x86/include/asm/perf_event.h | |||
| @@ -234,7 +234,7 @@ extern struct perf_guest_switch_msr *perf_guest_get_msrs(int *nr); | |||
| 234 | extern void perf_get_x86_pmu_capability(struct x86_pmu_capability *cap); | 234 | extern void perf_get_x86_pmu_capability(struct x86_pmu_capability *cap); |
| 235 | extern void perf_check_microcode(void); | 235 | extern void perf_check_microcode(void); |
| 236 | #else | 236 | #else |
| 237 | static inline perf_guest_switch_msr *perf_guest_get_msrs(int *nr) | 237 | static inline struct perf_guest_switch_msr *perf_guest_get_msrs(int *nr) |
| 238 | { | 238 | { |
| 239 | *nr = 0; | 239 | *nr = 0; |
| 240 | return NULL; | 240 | return NULL; |
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 39bc5777211a..d048cad9bcad 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h | |||
| @@ -61,6 +61,19 @@ static inline void *current_text_addr(void) | |||
| 61 | # define ARCH_MIN_MMSTRUCT_ALIGN 0 | 61 | # define ARCH_MIN_MMSTRUCT_ALIGN 0 |
| 62 | #endif | 62 | #endif |
| 63 | 63 | ||
| 64 | enum tlb_infos { | ||
| 65 | ENTRIES, | ||
| 66 | NR_INFO | ||
| 67 | }; | ||
| 68 | |||
| 69 | extern u16 __read_mostly tlb_lli_4k[NR_INFO]; | ||
| 70 | extern u16 __read_mostly tlb_lli_2m[NR_INFO]; | ||
| 71 | extern u16 __read_mostly tlb_lli_4m[NR_INFO]; | ||
| 72 | extern u16 __read_mostly tlb_lld_4k[NR_INFO]; | ||
| 73 | extern u16 __read_mostly tlb_lld_2m[NR_INFO]; | ||
| 74 | extern u16 __read_mostly tlb_lld_4m[NR_INFO]; | ||
| 75 | extern s8 __read_mostly tlb_flushall_shift; | ||
| 76 | |||
| 64 | /* | 77 | /* |
| 65 | * CPU type and hardware bug flags. Kept separately for each CPU. | 78 | * CPU type and hardware bug flags. Kept separately for each CPU. |
| 66 | * Members of this structure are referenced in head.S, so think twice | 79 | * Members of this structure are referenced in head.S, so think twice |
diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h index 2ffa95dc2333..4f19a1526037 100644 --- a/arch/x86/include/asm/smp.h +++ b/arch/x86/include/asm/smp.h | |||
| @@ -31,12 +31,12 @@ static inline bool cpu_has_ht_siblings(void) | |||
| 31 | return has_siblings; | 31 | return has_siblings; |
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | DECLARE_PER_CPU(cpumask_var_t, cpu_sibling_map); | 34 | DECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_sibling_map); |
| 35 | DECLARE_PER_CPU(cpumask_var_t, cpu_core_map); | 35 | DECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_core_map); |
| 36 | /* cpus sharing the last level cache: */ | 36 | /* cpus sharing the last level cache: */ |
| 37 | DECLARE_PER_CPU(cpumask_var_t, cpu_llc_shared_map); | 37 | DECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_llc_shared_map); |
| 38 | DECLARE_PER_CPU(u16, cpu_llc_id); | 38 | DECLARE_PER_CPU_READ_MOSTLY(u16, cpu_llc_id); |
| 39 | DECLARE_PER_CPU(int, cpu_number); | 39 | DECLARE_PER_CPU_READ_MOSTLY(int, cpu_number); |
| 40 | 40 | ||
| 41 | static inline struct cpumask *cpu_sibling_mask(int cpu) | 41 | static inline struct cpumask *cpu_sibling_mask(int cpu) |
| 42 | { | 42 | { |
| @@ -53,10 +53,10 @@ static inline struct cpumask *cpu_llc_shared_mask(int cpu) | |||
| 53 | return per_cpu(cpu_llc_shared_map, cpu); | 53 | return per_cpu(cpu_llc_shared_map, cpu); |
| 54 | } | 54 | } |
| 55 | 55 | ||
| 56 | DECLARE_EARLY_PER_CPU(u16, x86_cpu_to_apicid); | 56 | DECLARE_EARLY_PER_CPU_READ_MOSTLY(u16, x86_cpu_to_apicid); |
| 57 | DECLARE_EARLY_PER_CPU(u16, x86_bios_cpu_apicid); | 57 | DECLARE_EARLY_PER_CPU_READ_MOSTLY(u16, x86_bios_cpu_apicid); |
| 58 | #if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86_32) | 58 | #if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86_32) |
| 59 | DECLARE_EARLY_PER_CPU(int, x86_cpu_to_logical_apicid); | 59 | DECLARE_EARLY_PER_CPU_READ_MOSTLY(int, x86_cpu_to_logical_apicid); |
| 60 | #endif | 60 | #endif |
| 61 | 61 | ||
| 62 | /* Static state in head.S used to set up a CPU */ | 62 | /* Static state in head.S used to set up a CPU */ |
diff --git a/arch/x86/include/asm/tlb.h b/arch/x86/include/asm/tlb.h index 829215fef9ee..4fef20773b8f 100644 --- a/arch/x86/include/asm/tlb.h +++ b/arch/x86/include/asm/tlb.h | |||
| @@ -4,7 +4,14 @@ | |||
| 4 | #define tlb_start_vma(tlb, vma) do { } while (0) | 4 | #define tlb_start_vma(tlb, vma) do { } while (0) |
| 5 | #define tlb_end_vma(tlb, vma) do { } while (0) | 5 | #define tlb_end_vma(tlb, vma) do { } while (0) |
| 6 | #define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0) | 6 | #define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0) |
| 7 | #define tlb_flush(tlb) flush_tlb_mm((tlb)->mm) | 7 | |
| 8 | #define tlb_flush(tlb) \ | ||
| 9 | { \ | ||
| 10 | if (tlb->fullmm == 0) \ | ||
| 11 | flush_tlb_mm_range(tlb->mm, tlb->start, tlb->end, 0UL); \ | ||
| 12 | else \ | ||
| 13 | flush_tlb_mm_range(tlb->mm, 0UL, TLB_FLUSH_ALL, 0UL); \ | ||
| 14 | } | ||
| 8 | 15 | ||
| 9 | #include <asm-generic/tlb.h> | 16 | #include <asm-generic/tlb.h> |
| 10 | 17 | ||
diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h index 36a1a2ab87d2..74a44333545a 100644 --- a/arch/x86/include/asm/tlbflush.h +++ b/arch/x86/include/asm/tlbflush.h | |||
| @@ -73,14 +73,10 @@ static inline void __flush_tlb_one(unsigned long addr) | |||
| 73 | * - flush_tlb_page(vma, vmaddr) flushes one page | 73 | * - flush_tlb_page(vma, vmaddr) flushes one page |
| 74 | * - flush_tlb_range(vma, start, end) flushes a range of pages | 74 | * - flush_tlb_range(vma, start, end) flushes a range of pages |
| 75 | * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages | 75 | * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages |
| 76 | * - flush_tlb_others(cpumask, mm, va) flushes TLBs on other cpus | 76 | * - flush_tlb_others(cpumask, mm, start, end) flushes TLBs on other cpus |
| 77 | * | 77 | * |
| 78 | * ..but the i386 has somewhat limited tlb flushing capabilities, | 78 | * ..but the i386 has somewhat limited tlb flushing capabilities, |
| 79 | * and page-granular flushes are available only on i486 and up. | 79 | * and page-granular flushes are available only on i486 and up. |
| 80 | * | ||
| 81 | * x86-64 can only flush individual pages or full VMs. For a range flush | ||
| 82 | * we always do the full VM. Might be worth trying if for a small | ||
| 83 | * range a few INVLPGs in a row are a win. | ||
| 84 | */ | 80 | */ |
| 85 | 81 | ||
| 86 | #ifndef CONFIG_SMP | 82 | #ifndef CONFIG_SMP |
| @@ -109,9 +105,17 @@ static inline void flush_tlb_range(struct vm_area_struct *vma, | |||
| 109 | __flush_tlb(); | 105 | __flush_tlb(); |
| 110 | } | 106 | } |
| 111 | 107 | ||
| 108 | static inline void flush_tlb_mm_range(struct mm_struct *mm, | ||
| 109 | unsigned long start, unsigned long end, unsigned long vmflag) | ||
| 110 | { | ||
| 111 | if (mm == current->active_mm) | ||
| 112 | __flush_tlb(); | ||
| 113 | } | ||
| 114 | |||
| 112 | static inline void native_flush_tlb_others(const struct cpumask *cpumask, | 115 | static inline void native_flush_tlb_others(const struct cpumask *cpumask, |
| 113 | struct mm_struct *mm, | 116 | struct mm_struct *mm, |
| 114 | unsigned long va) | 117 | unsigned long start, |
| 118 | unsigned long end) | ||
| 115 | { | 119 | { |
| 116 | } | 120 | } |
| 117 | 121 | ||
| @@ -119,27 +123,35 @@ static inline void reset_lazy_tlbstate(void) | |||
| 119 | { | 123 | { |
| 120 | } | 124 | } |
| 121 | 125 | ||
| 126 | static inline void flush_tlb_kernel_range(unsigned long start, | ||
| 127 | unsigned long end) | ||
| 128 | { | ||
| 129 | flush_tlb_all(); | ||
| 130 | } | ||
| 131 | |||
| 122 | #else /* SMP */ | 132 | #else /* SMP */ |
| 123 | 133 | ||
| 124 | #include <asm/smp.h> | 134 | #include <asm/smp.h> |
| 125 | 135 | ||
| 126 | #define local_flush_tlb() __flush_tlb() | 136 | #define local_flush_tlb() __flush_tlb() |
| 127 | 137 | ||
| 138 | #define flush_tlb_mm(mm) flush_tlb_mm_range(mm, 0UL, TLB_FLUSH_ALL, 0UL) | ||
| 139 | |||
| 140 | #define flush_tlb_range(vma, start, end) \ | ||
| 141 | flush_tlb_mm_range(vma->vm_mm, start, end, vma->vm_flags) | ||
| 142 | |||
| 128 | extern void flush_tlb_all(void); | 143 | extern void flush_tlb_all(void); |
| 129 | extern void flush_tlb_current_task(void); | 144 | extern void flush_tlb_current_task(void); |
| 130 | extern void flush_tlb_mm(struct mm_struct *); | ||
| 131 | extern void flush_tlb_page(struct vm_area_struct *, unsigned long); | 145 | extern void flush_tlb_page(struct vm_area_struct *, unsigned long); |
| 146 | extern void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start, | ||
| 147 | unsigned long end, unsigned long vmflag); | ||
| 148 | extern void flush_tlb_kernel_range(unsigned long start, unsigned long end); | ||
| 132 | 149 | ||
| 133 | #define flush_tlb() flush_tlb_current_task() | 150 | #define flush_tlb() flush_tlb_current_task() |
| 134 | 151 | ||
| 135 | static inline void flush_tlb_range(struct vm_area_struct *vma, | ||
| 136 | unsigned long start, unsigned long end) | ||
| 137 | { | ||
| 138 | flush_tlb_mm(vma->vm_mm); | ||
| 139 | } | ||
| 140 | |||
| 141 | void native_flush_tlb_others(const struct cpumask *cpumask, | 152 | void native_flush_tlb_others(const struct cpumask *cpumask, |
| 142 | struct mm_struct *mm, unsigned long va); | 153 | struct mm_struct *mm, |
| 154 | unsigned long start, unsigned long end); | ||
| 143 | 155 | ||
| 144 | #define TLBSTATE_OK 1 | 156 | #define TLBSTATE_OK 1 |
| 145 | #define TLBSTATE_LAZY 2 | 157 | #define TLBSTATE_LAZY 2 |
| @@ -159,13 +171,8 @@ static inline void reset_lazy_tlbstate(void) | |||
| 159 | #endif /* SMP */ | 171 | #endif /* SMP */ |
| 160 | 172 | ||
| 161 | #ifndef CONFIG_PARAVIRT | 173 | #ifndef CONFIG_PARAVIRT |
| 162 | #define flush_tlb_others(mask, mm, va) native_flush_tlb_others(mask, mm, va) | 174 | #define flush_tlb_others(mask, mm, start, end) \ |
| 175 | native_flush_tlb_others(mask, mm, start, end) | ||
| 163 | #endif | 176 | #endif |
| 164 | 177 | ||
| 165 | static inline void flush_tlb_kernel_range(unsigned long start, | ||
| 166 | unsigned long end) | ||
| 167 | { | ||
| 168 | flush_tlb_all(); | ||
| 169 | } | ||
| 170 | |||
| 171 | #endif /* _ASM_X86_TLBFLUSH_H */ | 178 | #endif /* _ASM_X86_TLBFLUSH_H */ |
diff --git a/arch/x86/include/asm/unistd.h b/arch/x86/include/asm/unistd.h index 4437001d8e3d..0d9776e9e2dc 100644 --- a/arch/x86/include/asm/unistd.h +++ b/arch/x86/include/asm/unistd.h | |||
| @@ -15,7 +15,6 @@ | |||
| 15 | # ifdef CONFIG_X86_32 | 15 | # ifdef CONFIG_X86_32 |
| 16 | 16 | ||
| 17 | # include <asm/unistd_32.h> | 17 | # include <asm/unistd_32.h> |
| 18 | # define __ARCH_WANT_IPC_PARSE_VERSION | ||
| 19 | # define __ARCH_WANT_STAT64 | 18 | # define __ARCH_WANT_STAT64 |
| 20 | # define __ARCH_WANT_SYS_IPC | 19 | # define __ARCH_WANT_SYS_IPC |
| 21 | # define __ARCH_WANT_SYS_OLD_MMAP | 20 | # define __ARCH_WANT_SYS_OLD_MMAP |
diff --git a/arch/x86/include/asm/uv/uv.h b/arch/x86/include/asm/uv/uv.h index 3bb9491b7659..b47c2a82ff15 100644 --- a/arch/x86/include/asm/uv/uv.h +++ b/arch/x86/include/asm/uv/uv.h | |||
| @@ -15,7 +15,8 @@ extern void uv_nmi_init(void); | |||
| 15 | extern void uv_system_init(void); | 15 | extern void uv_system_init(void); |
| 16 | extern const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, | 16 | extern const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, |
| 17 | struct mm_struct *mm, | 17 | struct mm_struct *mm, |
| 18 | unsigned long va, | 18 | unsigned long start, |
| 19 | unsigned end, | ||
| 19 | unsigned int cpu); | 20 | unsigned int cpu); |
| 20 | 21 | ||
| 21 | #else /* X86_UV */ | 22 | #else /* X86_UV */ |
| @@ -26,7 +27,7 @@ static inline void uv_cpu_init(void) { } | |||
| 26 | static inline void uv_system_init(void) { } | 27 | static inline void uv_system_init(void) { } |
| 27 | static inline const struct cpumask * | 28 | static inline const struct cpumask * |
| 28 | uv_flush_tlb_others(const struct cpumask *cpumask, struct mm_struct *mm, | 29 | uv_flush_tlb_others(const struct cpumask *cpumask, struct mm_struct *mm, |
| 29 | unsigned long va, unsigned int cpu) | 30 | unsigned long start, unsigned long end, unsigned int cpu) |
| 30 | { return cpumask; } | 31 | { return cpumask; } |
| 31 | 32 | ||
| 32 | #endif /* X86_UV */ | 33 | #endif /* X86_UV */ |
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 98e24131ff3a..24deb3082328 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c | |||
| @@ -75,8 +75,8 @@ physid_mask_t phys_cpu_present_map; | |||
| 75 | /* | 75 | /* |
| 76 | * Map cpu index to physical APIC ID | 76 | * Map cpu index to physical APIC ID |
| 77 | */ | 77 | */ |
| 78 | DEFINE_EARLY_PER_CPU(u16, x86_cpu_to_apicid, BAD_APICID); | 78 | DEFINE_EARLY_PER_CPU_READ_MOSTLY(u16, x86_cpu_to_apicid, BAD_APICID); |
| 79 | DEFINE_EARLY_PER_CPU(u16, x86_bios_cpu_apicid, BAD_APICID); | 79 | DEFINE_EARLY_PER_CPU_READ_MOSTLY(u16, x86_bios_cpu_apicid, BAD_APICID); |
| 80 | EXPORT_EARLY_PER_CPU_SYMBOL(x86_cpu_to_apicid); | 80 | EXPORT_EARLY_PER_CPU_SYMBOL(x86_cpu_to_apicid); |
| 81 | EXPORT_EARLY_PER_CPU_SYMBOL(x86_bios_cpu_apicid); | 81 | EXPORT_EARLY_PER_CPU_SYMBOL(x86_bios_cpu_apicid); |
| 82 | 82 | ||
| @@ -88,7 +88,7 @@ EXPORT_EARLY_PER_CPU_SYMBOL(x86_bios_cpu_apicid); | |||
| 88 | * used for the mapping. This is where the behaviors of x86_64 and 32 | 88 | * used for the mapping. This is where the behaviors of x86_64 and 32 |
| 89 | * actually diverge. Let's keep it ugly for now. | 89 | * actually diverge. Let's keep it ugly for now. |
| 90 | */ | 90 | */ |
| 91 | DEFINE_EARLY_PER_CPU(int, x86_cpu_to_logical_apicid, BAD_APICID); | 91 | DEFINE_EARLY_PER_CPU_READ_MOSTLY(int, x86_cpu_to_logical_apicid, BAD_APICID); |
| 92 | 92 | ||
| 93 | /* | 93 | /* |
| 94 | * Knob to control our willingness to enable the local APIC. | 94 | * Knob to control our willingness to enable the local APIC. |
diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile index bac4c3804cc7..d30a6a9a0121 100644 --- a/arch/x86/kernel/cpu/Makefile +++ b/arch/x86/kernel/cpu/Makefile | |||
| @@ -14,7 +14,7 @@ CFLAGS_common.o := $(nostackp) | |||
| 14 | 14 | ||
| 15 | obj-y := intel_cacheinfo.o scattered.o topology.o | 15 | obj-y := intel_cacheinfo.o scattered.o topology.o |
| 16 | obj-y += proc.o capflags.o powerflags.o common.o | 16 | obj-y += proc.o capflags.o powerflags.o common.o |
| 17 | obj-y += vmware.o hypervisor.o sched.o mshyperv.o | 17 | obj-y += vmware.o hypervisor.o mshyperv.o |
| 18 | obj-y += rdrand.o | 18 | obj-y += rdrand.o |
| 19 | obj-y += match.o | 19 | obj-y += match.o |
| 20 | 20 | ||
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 5bbc082c47ad..46d8786d655e 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
| @@ -452,6 +452,35 @@ void __cpuinit cpu_detect_cache_sizes(struct cpuinfo_x86 *c) | |||
| 452 | c->x86_cache_size = l2size; | 452 | c->x86_cache_size = l2size; |
| 453 | } | 453 | } |
| 454 | 454 | ||
| 455 | u16 __read_mostly tlb_lli_4k[NR_INFO]; | ||
| 456 | u16 __read_mostly tlb_lli_2m[NR_INFO]; | ||
| 457 | u16 __read_mostly tlb_lli_4m[NR_INFO]; | ||
| 458 | u16 __read_mostly tlb_lld_4k[NR_INFO]; | ||
| 459 | u16 __read_mostly tlb_lld_2m[NR_INFO]; | ||
| 460 | u16 __read_mostly tlb_lld_4m[NR_INFO]; | ||
| 461 | |||
| 462 | /* | ||
| 463 | * tlb_flushall_shift shows the balance point in replacing cr3 write | ||
| 464 | * with multiple 'invlpg'. It will do this replacement when | ||
| 465 | * flush_tlb_lines <= active_lines/2^tlb_flushall_shift. | ||
| 466 | * If tlb_flushall_shift is -1, means the replacement will be disabled. | ||
| 467 | */ | ||
| 468 | s8 __read_mostly tlb_flushall_shift = -1; | ||
| 469 | |||
| 470 | void __cpuinit cpu_detect_tlb(struct cpuinfo_x86 *c) | ||
| 471 | { | ||
| 472 | if (this_cpu->c_detect_tlb) | ||
| 473 | this_cpu->c_detect_tlb(c); | ||
| 474 | |||
| 475 | printk(KERN_INFO "Last level iTLB entries: 4KB %d, 2MB %d, 4MB %d\n" \ | ||
| 476 | "Last level dTLB entries: 4KB %d, 2MB %d, 4MB %d\n" \ | ||
| 477 | "tlb_flushall_shift is 0x%x\n", | ||
| 478 | tlb_lli_4k[ENTRIES], tlb_lli_2m[ENTRIES], | ||
| 479 | tlb_lli_4m[ENTRIES], tlb_lld_4k[ENTRIES], | ||
| 480 | tlb_lld_2m[ENTRIES], tlb_lld_4m[ENTRIES], | ||
| 481 | tlb_flushall_shift); | ||
| 482 | } | ||
| 483 | |||
| 455 | void __cpuinit detect_ht(struct cpuinfo_x86 *c) | 484 | void __cpuinit detect_ht(struct cpuinfo_x86 *c) |
| 456 | { | 485 | { |
| 457 | #ifdef CONFIG_X86_HT | 486 | #ifdef CONFIG_X86_HT |
| @@ -911,6 +940,8 @@ void __init identify_boot_cpu(void) | |||
| 911 | #else | 940 | #else |
| 912 | vgetcpu_set_mode(); | 941 | vgetcpu_set_mode(); |
| 913 | #endif | 942 | #endif |
| 943 | if (boot_cpu_data.cpuid_level >= 2) | ||
| 944 | cpu_detect_tlb(&boot_cpu_data); | ||
| 914 | } | 945 | } |
| 915 | 946 | ||
| 916 | void __cpuinit identify_secondary_cpu(struct cpuinfo_x86 *c) | 947 | void __cpuinit identify_secondary_cpu(struct cpuinfo_x86 *c) |
diff --git a/arch/x86/kernel/cpu/cpu.h b/arch/x86/kernel/cpu/cpu.h index 8bacc7826fb3..4041c24ae7db 100644 --- a/arch/x86/kernel/cpu/cpu.h +++ b/arch/x86/kernel/cpu/cpu.h | |||
| @@ -20,10 +20,19 @@ struct cpu_dev { | |||
| 20 | void (*c_bsp_init)(struct cpuinfo_x86 *); | 20 | void (*c_bsp_init)(struct cpuinfo_x86 *); |
| 21 | void (*c_init)(struct cpuinfo_x86 *); | 21 | void (*c_init)(struct cpuinfo_x86 *); |
| 22 | void (*c_identify)(struct cpuinfo_x86 *); | 22 | void (*c_identify)(struct cpuinfo_x86 *); |
| 23 | void (*c_detect_tlb)(struct cpuinfo_x86 *); | ||
| 23 | unsigned int (*c_size_cache)(struct cpuinfo_x86 *, unsigned int); | 24 | unsigned int (*c_size_cache)(struct cpuinfo_x86 *, unsigned int); |
| 24 | int c_x86_vendor; | 25 | int c_x86_vendor; |
| 25 | }; | 26 | }; |
| 26 | 27 | ||
| 28 | struct _tlb_table { | ||
| 29 | unsigned char descriptor; | ||
| 30 | char tlb_type; | ||
| 31 | unsigned int entries; | ||
| 32 | /* unsigned int ways; */ | ||
| 33 | char info[128]; | ||
| 34 | }; | ||
| 35 | |||
| 27 | #define cpu_dev_register(cpu_devX) \ | 36 | #define cpu_dev_register(cpu_devX) \ |
| 28 | static const struct cpu_dev *const __cpu_dev_##cpu_devX __used \ | 37 | static const struct cpu_dev *const __cpu_dev_##cpu_devX __used \ |
| 29 | __attribute__((__section__(".x86_cpu_dev.init"))) = \ | 38 | __attribute__((__section__(".x86_cpu_dev.init"))) = \ |
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 3e6ff6cbf42a..0a4ce2980a5a 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c | |||
| @@ -491,6 +491,181 @@ static unsigned int __cpuinit intel_size_cache(struct cpuinfo_x86 *c, unsigned i | |||
| 491 | } | 491 | } |
| 492 | #endif | 492 | #endif |
| 493 | 493 | ||
| 494 | #define TLB_INST_4K 0x01 | ||
| 495 | #define TLB_INST_4M 0x02 | ||
| 496 | #define TLB_INST_2M_4M 0x03 | ||
| 497 | |||
| 498 | #define TLB_INST_ALL 0x05 | ||
| 499 | #define TLB_INST_1G 0x06 | ||
| 500 | |||
| 501 | #define TLB_DATA_4K 0x11 | ||
| 502 | #define TLB_DATA_4M 0x12 | ||
| 503 | #define TLB_DATA_2M_4M 0x13 | ||
| 504 | #define TLB_DATA_4K_4M 0x14 | ||
| 505 | |||
| 506 | #define TLB_DATA_1G 0x16 | ||
| 507 | |||
| 508 | #define TLB_DATA0_4K 0x21 | ||
| 509 | #define TLB_DATA0_4M 0x22 | ||
| 510 | #define TLB_DATA0_2M_4M 0x23 | ||
| 511 | |||
| 512 | #define STLB_4K 0x41 | ||
| 513 | |||
| 514 | static const struct _tlb_table intel_tlb_table[] __cpuinitconst = { | ||
| 515 | { 0x01, TLB_INST_4K, 32, " TLB_INST 4 KByte pages, 4-way set associative" }, | ||
| 516 | { 0x02, TLB_INST_4M, 2, " TLB_INST 4 MByte pages, full associative" }, | ||
| 517 | { 0x03, TLB_DATA_4K, 64, " TLB_DATA 4 KByte pages, 4-way set associative" }, | ||
| 518 | { 0x04, TLB_DATA_4M, 8, " TLB_DATA 4 MByte pages, 4-way set associative" }, | ||
| 519 | { 0x05, TLB_DATA_4M, 32, " TLB_DATA 4 MByte pages, 4-way set associative" }, | ||
| 520 | { 0x0b, TLB_INST_4M, 4, " TLB_INST 4 MByte pages, 4-way set associative" }, | ||
| 521 | { 0x4f, TLB_INST_4K, 32, " TLB_INST 4 KByte pages */" }, | ||
| 522 | { 0x50, TLB_INST_ALL, 64, " TLB_INST 4 KByte and 2-MByte or 4-MByte pages" }, | ||
| 523 | { 0x51, TLB_INST_ALL, 128, " TLB_INST 4 KByte and 2-MByte or 4-MByte pages" }, | ||
| 524 | { 0x52, TLB_INST_ALL, 256, " TLB_INST 4 KByte and 2-MByte or 4-MByte pages" }, | ||
| 525 | { 0x55, TLB_INST_2M_4M, 7, " TLB_INST 2-MByte or 4-MByte pages, fully associative" }, | ||
| 526 | { 0x56, TLB_DATA0_4M, 16, " TLB_DATA0 4 MByte pages, 4-way set associative" }, | ||
| 527 | { 0x57, TLB_DATA0_4K, 16, " TLB_DATA0 4 KByte pages, 4-way associative" }, | ||
| 528 | { 0x59, TLB_DATA0_4K, 16, " TLB_DATA0 4 KByte pages, fully associative" }, | ||
| 529 | { 0x5a, TLB_DATA0_2M_4M, 32, " TLB_DATA0 2-MByte or 4 MByte pages, 4-way set associative" }, | ||
| 530 | { 0x5b, TLB_DATA_4K_4M, 64, " TLB_DATA 4 KByte and 4 MByte pages" }, | ||
| 531 | { 0x5c, TLB_DATA_4K_4M, 128, " TLB_DATA 4 KByte and 4 MByte pages" }, | ||
| 532 | { 0x5d, TLB_DATA_4K_4M, 256, " TLB_DATA 4 KByte and 4 MByte pages" }, | ||
| 533 | { 0xb0, TLB_INST_4K, 128, " TLB_INST 4 KByte pages, 4-way set associative" }, | ||
| 534 | { 0xb1, TLB_INST_2M_4M, 4, " TLB_INST 2M pages, 4-way, 8 entries or 4M pages, 4-way entries" }, | ||
| 535 | { 0xb2, TLB_INST_4K, 64, " TLB_INST 4KByte pages, 4-way set associative" }, | ||
| 536 | { 0xb3, TLB_DATA_4K, 128, " TLB_DATA 4 KByte pages, 4-way set associative" }, | ||
| 537 | { 0xb4, TLB_DATA_4K, 256, " TLB_DATA 4 KByte pages, 4-way associative" }, | ||
| 538 | { 0xba, TLB_DATA_4K, 64, " TLB_DATA 4 KByte pages, 4-way associative" }, | ||
| 539 | { 0xc0, TLB_DATA_4K_4M, 8, " TLB_DATA 4 KByte and 4 MByte pages, 4-way associative" }, | ||
| 540 | { 0xca, STLB_4K, 512, " STLB 4 KByte pages, 4-way associative" }, | ||
| 541 | { 0x00, 0, 0 } | ||
| 542 | }; | ||
| 543 | |||
| 544 | static void __cpuinit intel_tlb_lookup(const unsigned char desc) | ||
| 545 | { | ||
| 546 | unsigned char k; | ||
| 547 | if (desc == 0) | ||
| 548 | return; | ||
| 549 | |||
| 550 | /* look up this descriptor in the table */ | ||
| 551 | for (k = 0; intel_tlb_table[k].descriptor != desc && \ | ||
| 552 | intel_tlb_table[k].descriptor != 0; k++) | ||
| 553 | ; | ||
| 554 | |||
| 555 | if (intel_tlb_table[k].tlb_type == 0) | ||
| 556 | return; | ||
| 557 | |||
| 558 | switch (intel_tlb_table[k].tlb_type) { | ||
| 559 | case STLB_4K: | ||
| 560 | if (tlb_lli_4k[ENTRIES] < intel_tlb_table[k].entries) | ||
| 561 | tlb_lli_4k[ENTRIES] = intel_tlb_table[k].entries; | ||
| 562 | if (tlb_lld_4k[ENTRIES] < intel_tlb_table[k].entries) | ||
| 563 | tlb_lld_4k[ENTRIES] = intel_tlb_table[k].entries; | ||
| 564 | break; | ||
| 565 | case TLB_INST_ALL: | ||
| 566 | if (tlb_lli_4k[ENTRIES] < intel_tlb_table[k].entries) | ||
| 567 | tlb_lli_4k[ENTRIES] = intel_tlb_table[k].entries; | ||
| 568 | if (tlb_lli_2m[ENTRIES] < intel_tlb_table[k].entries) | ||
| 569 | tlb_lli_2m[ENTRIES] = intel_tlb_table[k].entries; | ||
| 570 | if (tlb_lli_4m[ENTRIES] < intel_tlb_table[k].entries) | ||
| 571 | tlb_lli_4m[ENTRIES] = intel_tlb_table[k].entries; | ||
| 572 | break; | ||
| 573 | case TLB_INST_4K: | ||
| 574 | if (tlb_lli_4k[ENTRIES] < intel_tlb_table[k].entries) | ||
| 575 | tlb_lli_4k[ENTRIES] = intel_tlb_table[k].entries; | ||
| 576 | break; | ||
| 577 | case TLB_INST_4M: | ||
| 578 | if (tlb_lli_4m[ENTRIES] < intel_tlb_table[k].entries) | ||
| 579 | tlb_lli_4m[ENTRIES] = intel_tlb_table[k].entries; | ||
| 580 | break; | ||
| 581 | case TLB_INST_2M_4M: | ||
| 582 | if (tlb_lli_2m[ENTRIES] < intel_tlb_table[k].entries) | ||
| 583 | tlb_lli_2m[ENTRIES] = intel_tlb_table[k].entries; | ||
| 584 | if (tlb_lli_4m[ENTRIES] < intel_tlb_table[k].entries) | ||
| 585 | tlb_lli_4m[ENTRIES] = intel_tlb_table[k].entries; | ||
| 586 | break; | ||
| 587 | case TLB_DATA_4K: | ||
| 588 | case TLB_DATA0_4K: | ||
| 589 | if (tlb_lld_4k[ENTRIES] < intel_tlb_table[k].entries) | ||
| 590 | tlb_lld_4k[ENTRIES] = intel_tlb_table[k].entries; | ||
| 591 | break; | ||
| 592 | case TLB_DATA_4M: | ||
| 593 | case TLB_DATA0_4M: | ||
| 594 | if (tlb_lld_4m[ENTRIES] < intel_tlb_table[k].entries) | ||
| 595 | tlb_lld_4m[ENTRIES] = intel_tlb_table[k].entries; | ||
| 596 | break; | ||
| 597 | case TLB_DATA_2M_4M: | ||
| 598 | case TLB_DATA0_2M_4M: | ||
| 599 | if (tlb_lld_2m[ENTRIES] < intel_tlb_table[k].entries) | ||
| 600 | tlb_lld_2m[ENTRIES] = intel_tlb_table[k].entries; | ||
| 601 | if (tlb_lld_4m[ENTRIES] < intel_tlb_table[k].entries) | ||
| 602 | tlb_lld_4m[ENTRIES] = intel_tlb_table[k].entries; | ||
| 603 | break; | ||
| 604 | case TLB_DATA_4K_4M: | ||
| 605 | if (tlb_lld_4k[ENTRIES] < intel_tlb_table[k].entries) | ||
| 606 | tlb_lld_4k[ENTRIES] = intel_tlb_table[k].entries; | ||
| 607 | if (tlb_lld_4m[ENTRIES] < intel_tlb_table[k].entries) | ||
| 608 | tlb_lld_4m[ENTRIES] = intel_tlb_table[k].entries; | ||
| 609 | break; | ||
| 610 | } | ||
| 611 | } | ||
| 612 | |||
| 613 | static void __cpuinit intel_tlb_flushall_shift_set(struct cpuinfo_x86 *c) | ||
| 614 | { | ||
| 615 | if (!cpu_has_invlpg) { | ||
| 616 | tlb_flushall_shift = -1; | ||
| 617 | return; | ||
| 618 | } | ||
| 619 | switch ((c->x86 << 8) + c->x86_model) { | ||
| 620 | case 0x60f: /* original 65 nm celeron/pentium/core2/xeon, "Merom"/"Conroe" */ | ||
| 621 | case 0x616: /* single-core 65 nm celeron/core2solo "Merom-L"/"Conroe-L" */ | ||
| 622 | case 0x617: /* current 45 nm celeron/core2/xeon "Penryn"/"Wolfdale" */ | ||
| 623 | case 0x61d: /* six-core 45 nm xeon "Dunnington" */ | ||
| 624 | tlb_flushall_shift = -1; | ||
| 625 | break; | ||
| 626 | case 0x61a: /* 45 nm nehalem, "Bloomfield" */ | ||
| 627 | case 0x61e: /* 45 nm nehalem, "Lynnfield" */ | ||
| 628 | case 0x625: /* 32 nm nehalem, "Clarkdale" */ | ||
| 629 | case 0x62c: /* 32 nm nehalem, "Gulftown" */ | ||
| 630 | case 0x62e: /* 45 nm nehalem-ex, "Beckton" */ | ||
| 631 | case 0x62f: /* 32 nm Xeon E7 */ | ||
| 632 | tlb_flushall_shift = 6; | ||
| 633 | break; | ||
| 634 | case 0x62a: /* SandyBridge */ | ||
| 635 | case 0x62d: /* SandyBridge, "Romely-EP" */ | ||
| 636 | tlb_flushall_shift = 5; | ||
| 637 | break; | ||
| 638 | case 0x63a: /* Ivybridge */ | ||
| 639 | tlb_flushall_shift = 1; | ||
| 640 | break; | ||
| 641 | default: | ||
| 642 | tlb_flushall_shift = 6; | ||
| 643 | } | ||
| 644 | } | ||
| 645 | |||
| 646 | static void __cpuinit intel_detect_tlb(struct cpuinfo_x86 *c) | ||
| 647 | { | ||
| 648 | int i, j, n; | ||
| 649 | unsigned int regs[4]; | ||
| 650 | unsigned char *desc = (unsigned char *)regs; | ||
| 651 | /* Number of times to iterate */ | ||
| 652 | n = cpuid_eax(2) & 0xFF; | ||
| 653 | |||
| 654 | for (i = 0 ; i < n ; i++) { | ||
| 655 | cpuid(2, ®s[0], ®s[1], ®s[2], ®s[3]); | ||
| 656 | |||
| 657 | /* If bit 31 is set, this is an unknown format */ | ||
| 658 | for (j = 0 ; j < 3 ; j++) | ||
| 659 | if (regs[j] & (1 << 31)) | ||
| 660 | regs[j] = 0; | ||
| 661 | |||
| 662 | /* Byte 0 is level count, not a descriptor */ | ||
| 663 | for (j = 1 ; j < 16 ; j++) | ||
| 664 | intel_tlb_lookup(desc[j]); | ||
| 665 | } | ||
| 666 | intel_tlb_flushall_shift_set(c); | ||
| 667 | } | ||
| 668 | |||
| 494 | static const struct cpu_dev __cpuinitconst intel_cpu_dev = { | 669 | static const struct cpu_dev __cpuinitconst intel_cpu_dev = { |
| 495 | .c_vendor = "Intel", | 670 | .c_vendor = "Intel", |
| 496 | .c_ident = { "GenuineIntel" }, | 671 | .c_ident = { "GenuineIntel" }, |
| @@ -546,6 +721,7 @@ static const struct cpu_dev __cpuinitconst intel_cpu_dev = { | |||
| 546 | }, | 721 | }, |
| 547 | .c_size_cache = intel_size_cache, | 722 | .c_size_cache = intel_size_cache, |
| 548 | #endif | 723 | #endif |
| 724 | .c_detect_tlb = intel_detect_tlb, | ||
| 549 | .c_early_init = early_init_intel, | 725 | .c_early_init = early_init_intel, |
| 550 | .c_init = init_intel, | 726 | .c_init = init_intel, |
| 551 | .c_x86_vendor = X86_VENDOR_INTEL, | 727 | .c_x86_vendor = X86_VENDOR_INTEL, |
diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h index a15df4be151f..821d53b696d1 100644 --- a/arch/x86/kernel/cpu/perf_event.h +++ b/arch/x86/kernel/cpu/perf_event.h | |||
| @@ -374,7 +374,7 @@ struct x86_pmu { | |||
| 374 | /* | 374 | /* |
| 375 | * Intel DebugStore bits | 375 | * Intel DebugStore bits |
| 376 | */ | 376 | */ |
| 377 | int bts :1, | 377 | unsigned int bts :1, |
| 378 | bts_active :1, | 378 | bts_active :1, |
| 379 | pebs :1, | 379 | pebs :1, |
| 380 | pebs_active :1, | 380 | pebs_active :1, |
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 7a8b9d0abcaa..382366977d4c 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c | |||
| @@ -138,6 +138,84 @@ static u64 intel_pmu_event_map(int hw_event) | |||
| 138 | return intel_perfmon_event_map[hw_event]; | 138 | return intel_perfmon_event_map[hw_event]; |
| 139 | } | 139 | } |
| 140 | 140 | ||
| 141 | #define SNB_DMND_DATA_RD (1ULL << 0) | ||
| 142 | #define SNB_DMND_RFO (1ULL << 1) | ||
| 143 | #define SNB_DMND_IFETCH (1ULL << 2) | ||
| 144 | #define SNB_DMND_WB (1ULL << 3) | ||
| 145 | #define SNB_PF_DATA_RD (1ULL << 4) | ||
| 146 | #define SNB_PF_RFO (1ULL << 5) | ||
| 147 | #define SNB_PF_IFETCH (1ULL << 6) | ||
| 148 | #define SNB_LLC_DATA_RD (1ULL << 7) | ||
| 149 | #define SNB_LLC_RFO (1ULL << 8) | ||
| 150 | #define SNB_LLC_IFETCH (1ULL << 9) | ||
| 151 | #define SNB_BUS_LOCKS (1ULL << 10) | ||
| 152 | #define SNB_STRM_ST (1ULL << 11) | ||
| 153 | #define SNB_OTHER (1ULL << 15) | ||
| 154 | #define SNB_RESP_ANY (1ULL << 16) | ||
| 155 | #define SNB_NO_SUPP (1ULL << 17) | ||
| 156 | #define SNB_LLC_HITM (1ULL << 18) | ||
| 157 | #define SNB_LLC_HITE (1ULL << 19) | ||
| 158 | #define SNB_LLC_HITS (1ULL << 20) | ||
| 159 | #define SNB_LLC_HITF (1ULL << 21) | ||
| 160 | #define SNB_LOCAL (1ULL << 22) | ||
| 161 | #define SNB_REMOTE (0xffULL << 23) | ||
| 162 | #define SNB_SNP_NONE (1ULL << 31) | ||
| 163 | #define SNB_SNP_NOT_NEEDED (1ULL << 32) | ||
| 164 | #define SNB_SNP_MISS (1ULL << 33) | ||
| 165 | #define SNB_NO_FWD (1ULL << 34) | ||
| 166 | #define SNB_SNP_FWD (1ULL << 35) | ||
| 167 | #define SNB_HITM (1ULL << 36) | ||
| 168 | #define SNB_NON_DRAM (1ULL << 37) | ||
| 169 | |||
| 170 | #define SNB_DMND_READ (SNB_DMND_DATA_RD|SNB_LLC_DATA_RD) | ||
| 171 | #define SNB_DMND_WRITE (SNB_DMND_RFO|SNB_LLC_RFO) | ||
| 172 | #define SNB_DMND_PREFETCH (SNB_PF_DATA_RD|SNB_PF_RFO) | ||
| 173 | |||
| 174 | #define SNB_SNP_ANY (SNB_SNP_NONE|SNB_SNP_NOT_NEEDED| \ | ||
| 175 | SNB_SNP_MISS|SNB_NO_FWD|SNB_SNP_FWD| \ | ||
| 176 | SNB_HITM) | ||
| 177 | |||
| 178 | #define SNB_DRAM_ANY (SNB_LOCAL|SNB_REMOTE|SNB_SNP_ANY) | ||
| 179 | #define SNB_DRAM_REMOTE (SNB_REMOTE|SNB_SNP_ANY) | ||
| 180 | |||
| 181 | #define SNB_L3_ACCESS SNB_RESP_ANY | ||
| 182 | #define SNB_L3_MISS (SNB_DRAM_ANY|SNB_NON_DRAM) | ||
| 183 | |||
| 184 | static __initconst const u64 snb_hw_cache_extra_regs | ||
| 185 | [PERF_COUNT_HW_CACHE_MAX] | ||
| 186 | [PERF_COUNT_HW_CACHE_OP_MAX] | ||
| 187 | [PERF_COUNT_HW_CACHE_RESULT_MAX] = | ||
| 188 | { | ||
| 189 | [ C(LL ) ] = { | ||
| 190 | [ C(OP_READ) ] = { | ||
| 191 | [ C(RESULT_ACCESS) ] = SNB_DMND_READ|SNB_L3_ACCESS, | ||
| 192 | [ C(RESULT_MISS) ] = SNB_DMND_READ|SNB_L3_MISS, | ||
| 193 | }, | ||
| 194 | [ C(OP_WRITE) ] = { | ||
| 195 | [ C(RESULT_ACCESS) ] = SNB_DMND_WRITE|SNB_L3_ACCESS, | ||
| 196 | [ C(RESULT_MISS) ] = SNB_DMND_WRITE|SNB_L3_MISS, | ||
| 197 | }, | ||
| 198 | [ C(OP_PREFETCH) ] = { | ||
| 199 | [ C(RESULT_ACCESS) ] = SNB_DMND_PREFETCH|SNB_L3_ACCESS, | ||
| 200 | [ C(RESULT_MISS) ] = SNB_DMND_PREFETCH|SNB_L3_MISS, | ||
| 201 | }, | ||
| 202 | }, | ||
| 203 | [ C(NODE) ] = { | ||
| 204 | [ C(OP_READ) ] = { | ||
| 205 | [ C(RESULT_ACCESS) ] = SNB_DMND_READ|SNB_DRAM_ANY, | ||
| 206 | [ C(RESULT_MISS) ] = SNB_DMND_READ|SNB_DRAM_REMOTE, | ||
| 207 | }, | ||
| 208 | [ C(OP_WRITE) ] = { | ||
| 209 | [ C(RESULT_ACCESS) ] = SNB_DMND_WRITE|SNB_DRAM_ANY, | ||
| 210 | [ C(RESULT_MISS) ] = SNB_DMND_WRITE|SNB_DRAM_REMOTE, | ||
| 211 | }, | ||
| 212 | [ C(OP_PREFETCH) ] = { | ||
| 213 | [ C(RESULT_ACCESS) ] = SNB_DMND_PREFETCH|SNB_DRAM_ANY, | ||
| 214 | [ C(RESULT_MISS) ] = SNB_DMND_PREFETCH|SNB_DRAM_REMOTE, | ||
| 215 | }, | ||
| 216 | }, | ||
| 217 | }; | ||
| 218 | |||
| 141 | static __initconst const u64 snb_hw_cache_event_ids | 219 | static __initconst const u64 snb_hw_cache_event_ids |
| 142 | [PERF_COUNT_HW_CACHE_MAX] | 220 | [PERF_COUNT_HW_CACHE_MAX] |
| 143 | [PERF_COUNT_HW_CACHE_OP_MAX] | 221 | [PERF_COUNT_HW_CACHE_OP_MAX] |
| @@ -235,16 +313,16 @@ static __initconst const u64 snb_hw_cache_event_ids | |||
| 235 | }, | 313 | }, |
| 236 | [ C(NODE) ] = { | 314 | [ C(NODE) ] = { |
| 237 | [ C(OP_READ) ] = { | 315 | [ C(OP_READ) ] = { |
| 238 | [ C(RESULT_ACCESS) ] = -1, | 316 | [ C(RESULT_ACCESS) ] = 0x01b7, |
| 239 | [ C(RESULT_MISS) ] = -1, | 317 | [ C(RESULT_MISS) ] = 0x01b7, |
| 240 | }, | 318 | }, |
| 241 | [ C(OP_WRITE) ] = { | 319 | [ C(OP_WRITE) ] = { |
| 242 | [ C(RESULT_ACCESS) ] = -1, | 320 | [ C(RESULT_ACCESS) ] = 0x01b7, |
| 243 | [ C(RESULT_MISS) ] = -1, | 321 | [ C(RESULT_MISS) ] = 0x01b7, |
| 244 | }, | 322 | }, |
| 245 | [ C(OP_PREFETCH) ] = { | 323 | [ C(OP_PREFETCH) ] = { |
| 246 | [ C(RESULT_ACCESS) ] = -1, | 324 | [ C(RESULT_ACCESS) ] = 0x01b7, |
| 247 | [ C(RESULT_MISS) ] = -1, | 325 | [ C(RESULT_MISS) ] = 0x01b7, |
| 248 | }, | 326 | }, |
| 249 | }, | 327 | }, |
| 250 | 328 | ||
| @@ -1964,6 +2042,8 @@ __init int intel_pmu_init(void) | |||
| 1964 | case 58: /* IvyBridge */ | 2042 | case 58: /* IvyBridge */ |
| 1965 | memcpy(hw_cache_event_ids, snb_hw_cache_event_ids, | 2043 | memcpy(hw_cache_event_ids, snb_hw_cache_event_ids, |
| 1966 | sizeof(hw_cache_event_ids)); | 2044 | sizeof(hw_cache_event_ids)); |
| 2045 | memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs, | ||
| 2046 | sizeof(hw_cache_extra_regs)); | ||
| 1967 | 2047 | ||
| 1968 | intel_pmu_lbr_init_snb(); | 2048 | intel_pmu_lbr_init_snb(); |
| 1969 | 2049 | ||
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c index 19faffc60886..7563fda9f033 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c | |||
| @@ -18,6 +18,7 @@ static struct event_constraint constraint_empty = | |||
| 18 | EVENT_CONSTRAINT(0, 0, 0); | 18 | EVENT_CONSTRAINT(0, 0, 0); |
| 19 | 19 | ||
| 20 | DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7"); | 20 | DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7"); |
| 21 | DEFINE_UNCORE_FORMAT_ATTR(event_ext, event, "config:0-7,21"); | ||
| 21 | DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15"); | 22 | DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15"); |
| 22 | DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18"); | 23 | DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18"); |
| 23 | DEFINE_UNCORE_FORMAT_ATTR(tid_en, tid_en, "config:19"); | 24 | DEFINE_UNCORE_FORMAT_ATTR(tid_en, tid_en, "config:19"); |
| @@ -33,10 +34,81 @@ DEFINE_UNCORE_FORMAT_ATTR(filter_tid, filter_tid, "config1:0-4"); | |||
| 33 | DEFINE_UNCORE_FORMAT_ATTR(filter_nid, filter_nid, "config1:10-17"); | 34 | DEFINE_UNCORE_FORMAT_ATTR(filter_nid, filter_nid, "config1:10-17"); |
| 34 | DEFINE_UNCORE_FORMAT_ATTR(filter_state, filter_state, "config1:18-22"); | 35 | DEFINE_UNCORE_FORMAT_ATTR(filter_state, filter_state, "config1:18-22"); |
| 35 | DEFINE_UNCORE_FORMAT_ATTR(filter_opc, filter_opc, "config1:23-31"); | 36 | DEFINE_UNCORE_FORMAT_ATTR(filter_opc, filter_opc, "config1:23-31"); |
| 36 | DEFINE_UNCORE_FORMAT_ATTR(filter_brand0, filter_brand0, "config1:0-7"); | 37 | DEFINE_UNCORE_FORMAT_ATTR(filter_band0, filter_band0, "config1:0-7"); |
| 37 | DEFINE_UNCORE_FORMAT_ATTR(filter_brand1, filter_brand1, "config1:8-15"); | 38 | DEFINE_UNCORE_FORMAT_ATTR(filter_band1, filter_band1, "config1:8-15"); |
| 38 | DEFINE_UNCORE_FORMAT_ATTR(filter_brand2, filter_brand2, "config1:16-23"); | 39 | DEFINE_UNCORE_FORMAT_ATTR(filter_band2, filter_band2, "config1:16-23"); |
| 39 | DEFINE_UNCORE_FORMAT_ATTR(filter_brand3, filter_brand3, "config1:24-31"); | 40 | DEFINE_UNCORE_FORMAT_ATTR(filter_band3, filter_band3, "config1:24-31"); |
| 41 | |||
| 42 | static u64 uncore_msr_read_counter(struct intel_uncore_box *box, struct perf_event *event) | ||
| 43 | { | ||
| 44 | u64 count; | ||
| 45 | |||
| 46 | rdmsrl(event->hw.event_base, count); | ||
| 47 | |||
| 48 | return count; | ||
| 49 | } | ||
| 50 | |||
| 51 | /* | ||
| 52 | * generic get constraint function for shared match/mask registers. | ||
| 53 | */ | ||
| 54 | static struct event_constraint * | ||
| 55 | uncore_get_constraint(struct intel_uncore_box *box, struct perf_event *event) | ||
| 56 | { | ||
| 57 | struct intel_uncore_extra_reg *er; | ||
| 58 | struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; | ||
| 59 | struct hw_perf_event_extra *reg2 = &event->hw.branch_reg; | ||
| 60 | unsigned long flags; | ||
| 61 | bool ok = false; | ||
| 62 | |||
| 63 | /* | ||
| 64 | * reg->alloc can be set due to existing state, so for fake box we | ||
| 65 | * need to ignore this, otherwise we might fail to allocate proper | ||
| 66 | * fake state for this extra reg constraint. | ||
| 67 | */ | ||
| 68 | if (reg1->idx == EXTRA_REG_NONE || | ||
| 69 | (!uncore_box_is_fake(box) && reg1->alloc)) | ||
| 70 | return NULL; | ||
| 71 | |||
| 72 | er = &box->shared_regs[reg1->idx]; | ||
| 73 | raw_spin_lock_irqsave(&er->lock, flags); | ||
| 74 | if (!atomic_read(&er->ref) || | ||
| 75 | (er->config1 == reg1->config && er->config2 == reg2->config)) { | ||
| 76 | atomic_inc(&er->ref); | ||
| 77 | er->config1 = reg1->config; | ||
| 78 | er->config2 = reg2->config; | ||
| 79 | ok = true; | ||
| 80 | } | ||
| 81 | raw_spin_unlock_irqrestore(&er->lock, flags); | ||
| 82 | |||
| 83 | if (ok) { | ||
| 84 | if (!uncore_box_is_fake(box)) | ||
| 85 | reg1->alloc = 1; | ||
| 86 | return NULL; | ||
| 87 | } | ||
| 88 | |||
| 89 | return &constraint_empty; | ||
| 90 | } | ||
| 91 | |||
| 92 | static void uncore_put_constraint(struct intel_uncore_box *box, struct perf_event *event) | ||
| 93 | { | ||
| 94 | struct intel_uncore_extra_reg *er; | ||
| 95 | struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; | ||
| 96 | |||
| 97 | /* | ||
| 98 | * Only put constraint if extra reg was actually allocated. Also | ||
| 99 | * takes care of event which do not use an extra shared reg. | ||
| 100 | * | ||
| 101 | * Also, if this is a fake box we shouldn't touch any event state | ||
| 102 | * (reg->alloc) and we don't care about leaving inconsistent box | ||
| 103 | * state either since it will be thrown out. | ||
| 104 | */ | ||
| 105 | if (uncore_box_is_fake(box) || !reg1->alloc) | ||
| 106 | return; | ||
| 107 | |||
| 108 | er = &box->shared_regs[reg1->idx]; | ||
| 109 | atomic_dec(&er->ref); | ||
| 110 | reg1->alloc = 0; | ||
| 111 | } | ||
| 40 | 112 | ||
| 41 | /* Sandy Bridge-EP uncore support */ | 113 | /* Sandy Bridge-EP uncore support */ |
| 42 | static struct intel_uncore_type snbep_uncore_cbox; | 114 | static struct intel_uncore_type snbep_uncore_cbox; |
| @@ -64,18 +136,15 @@ static void snbep_uncore_pci_enable_box(struct intel_uncore_box *box) | |||
| 64 | pci_write_config_dword(pdev, box_ctl, config); | 136 | pci_write_config_dword(pdev, box_ctl, config); |
| 65 | } | 137 | } |
| 66 | 138 | ||
| 67 | static void snbep_uncore_pci_enable_event(struct intel_uncore_box *box, | 139 | static void snbep_uncore_pci_enable_event(struct intel_uncore_box *box, struct perf_event *event) |
| 68 | struct perf_event *event) | ||
| 69 | { | 140 | { |
| 70 | struct pci_dev *pdev = box->pci_dev; | 141 | struct pci_dev *pdev = box->pci_dev; |
| 71 | struct hw_perf_event *hwc = &event->hw; | 142 | struct hw_perf_event *hwc = &event->hw; |
| 72 | 143 | ||
| 73 | pci_write_config_dword(pdev, hwc->config_base, hwc->config | | 144 | pci_write_config_dword(pdev, hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN); |
| 74 | SNBEP_PMON_CTL_EN); | ||
| 75 | } | 145 | } |
| 76 | 146 | ||
| 77 | static void snbep_uncore_pci_disable_event(struct intel_uncore_box *box, | 147 | static void snbep_uncore_pci_disable_event(struct intel_uncore_box *box, struct perf_event *event) |
| 78 | struct perf_event *event) | ||
| 79 | { | 148 | { |
| 80 | struct pci_dev *pdev = box->pci_dev; | 149 | struct pci_dev *pdev = box->pci_dev; |
| 81 | struct hw_perf_event *hwc = &event->hw; | 150 | struct hw_perf_event *hwc = &event->hw; |
| @@ -83,8 +152,7 @@ static void snbep_uncore_pci_disable_event(struct intel_uncore_box *box, | |||
| 83 | pci_write_config_dword(pdev, hwc->config_base, hwc->config); | 152 | pci_write_config_dword(pdev, hwc->config_base, hwc->config); |
| 84 | } | 153 | } |
| 85 | 154 | ||
| 86 | static u64 snbep_uncore_pci_read_counter(struct intel_uncore_box *box, | 155 | static u64 snbep_uncore_pci_read_counter(struct intel_uncore_box *box, struct perf_event *event) |
| 87 | struct perf_event *event) | ||
| 88 | { | 156 | { |
| 89 | struct pci_dev *pdev = box->pci_dev; | 157 | struct pci_dev *pdev = box->pci_dev; |
| 90 | struct hw_perf_event *hwc = &event->hw; | 158 | struct hw_perf_event *hwc = &event->hw; |
| @@ -92,14 +160,15 @@ static u64 snbep_uncore_pci_read_counter(struct intel_uncore_box *box, | |||
| 92 | 160 | ||
| 93 | pci_read_config_dword(pdev, hwc->event_base, (u32 *)&count); | 161 | pci_read_config_dword(pdev, hwc->event_base, (u32 *)&count); |
| 94 | pci_read_config_dword(pdev, hwc->event_base + 4, (u32 *)&count + 1); | 162 | pci_read_config_dword(pdev, hwc->event_base + 4, (u32 *)&count + 1); |
| 163 | |||
| 95 | return count; | 164 | return count; |
| 96 | } | 165 | } |
| 97 | 166 | ||
| 98 | static void snbep_uncore_pci_init_box(struct intel_uncore_box *box) | 167 | static void snbep_uncore_pci_init_box(struct intel_uncore_box *box) |
| 99 | { | 168 | { |
| 100 | struct pci_dev *pdev = box->pci_dev; | 169 | struct pci_dev *pdev = box->pci_dev; |
| 101 | pci_write_config_dword(pdev, SNBEP_PCI_PMON_BOX_CTL, | 170 | |
| 102 | SNBEP_PMON_BOX_CTL_INT); | 171 | pci_write_config_dword(pdev, SNBEP_PCI_PMON_BOX_CTL, SNBEP_PMON_BOX_CTL_INT); |
| 103 | } | 172 | } |
| 104 | 173 | ||
| 105 | static void snbep_uncore_msr_disable_box(struct intel_uncore_box *box) | 174 | static void snbep_uncore_msr_disable_box(struct intel_uncore_box *box) |
| @@ -112,7 +181,6 @@ static void snbep_uncore_msr_disable_box(struct intel_uncore_box *box) | |||
| 112 | rdmsrl(msr, config); | 181 | rdmsrl(msr, config); |
| 113 | config |= SNBEP_PMON_BOX_CTL_FRZ; | 182 | config |= SNBEP_PMON_BOX_CTL_FRZ; |
| 114 | wrmsrl(msr, config); | 183 | wrmsrl(msr, config); |
| 115 | return; | ||
| 116 | } | 184 | } |
| 117 | } | 185 | } |
| 118 | 186 | ||
| @@ -126,12 +194,10 @@ static void snbep_uncore_msr_enable_box(struct intel_uncore_box *box) | |||
| 126 | rdmsrl(msr, config); | 194 | rdmsrl(msr, config); |
| 127 | config &= ~SNBEP_PMON_BOX_CTL_FRZ; | 195 | config &= ~SNBEP_PMON_BOX_CTL_FRZ; |
| 128 | wrmsrl(msr, config); | 196 | wrmsrl(msr, config); |
| 129 | return; | ||
| 130 | } | 197 | } |
| 131 | } | 198 | } |
| 132 | 199 | ||
| 133 | static void snbep_uncore_msr_enable_event(struct intel_uncore_box *box, | 200 | static void snbep_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event) |
| 134 | struct perf_event *event) | ||
| 135 | { | 201 | { |
| 136 | struct hw_perf_event *hwc = &event->hw; | 202 | struct hw_perf_event *hwc = &event->hw; |
| 137 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; | 203 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; |
| @@ -150,68 +216,15 @@ static void snbep_uncore_msr_disable_event(struct intel_uncore_box *box, | |||
| 150 | wrmsrl(hwc->config_base, hwc->config); | 216 | wrmsrl(hwc->config_base, hwc->config); |
| 151 | } | 217 | } |
| 152 | 218 | ||
| 153 | static u64 snbep_uncore_msr_read_counter(struct intel_uncore_box *box, | ||
| 154 | struct perf_event *event) | ||
| 155 | { | ||
| 156 | struct hw_perf_event *hwc = &event->hw; | ||
| 157 | u64 count; | ||
| 158 | |||
| 159 | rdmsrl(hwc->event_base, count); | ||
| 160 | return count; | ||
| 161 | } | ||
| 162 | |||
| 163 | static void snbep_uncore_msr_init_box(struct intel_uncore_box *box) | 219 | static void snbep_uncore_msr_init_box(struct intel_uncore_box *box) |
| 164 | { | 220 | { |
| 165 | unsigned msr = uncore_msr_box_ctl(box); | 221 | unsigned msr = uncore_msr_box_ctl(box); |
| 222 | |||
| 166 | if (msr) | 223 | if (msr) |
| 167 | wrmsrl(msr, SNBEP_PMON_BOX_CTL_INT); | 224 | wrmsrl(msr, SNBEP_PMON_BOX_CTL_INT); |
| 168 | } | 225 | } |
| 169 | 226 | ||
| 170 | static struct event_constraint * | 227 | static int snbep_uncore_hw_config(struct intel_uncore_box *box, struct perf_event *event) |
| 171 | snbep_uncore_get_constraint(struct intel_uncore_box *box, | ||
| 172 | struct perf_event *event) | ||
| 173 | { | ||
| 174 | struct intel_uncore_extra_reg *er; | ||
| 175 | struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; | ||
| 176 | unsigned long flags; | ||
| 177 | bool ok = false; | ||
| 178 | |||
| 179 | if (reg1->idx == EXTRA_REG_NONE || (box->phys_id >= 0 && reg1->alloc)) | ||
| 180 | return NULL; | ||
| 181 | |||
| 182 | er = &box->shared_regs[reg1->idx]; | ||
| 183 | raw_spin_lock_irqsave(&er->lock, flags); | ||
| 184 | if (!atomic_read(&er->ref) || er->config1 == reg1->config) { | ||
| 185 | atomic_inc(&er->ref); | ||
| 186 | er->config1 = reg1->config; | ||
| 187 | ok = true; | ||
| 188 | } | ||
| 189 | raw_spin_unlock_irqrestore(&er->lock, flags); | ||
| 190 | |||
| 191 | if (ok) { | ||
| 192 | if (box->phys_id >= 0) | ||
| 193 | reg1->alloc = 1; | ||
| 194 | return NULL; | ||
| 195 | } | ||
| 196 | return &constraint_empty; | ||
| 197 | } | ||
| 198 | |||
| 199 | static void snbep_uncore_put_constraint(struct intel_uncore_box *box, | ||
| 200 | struct perf_event *event) | ||
| 201 | { | ||
| 202 | struct intel_uncore_extra_reg *er; | ||
| 203 | struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; | ||
| 204 | |||
| 205 | if (box->phys_id < 0 || !reg1->alloc) | ||
| 206 | return; | ||
| 207 | |||
| 208 | er = &box->shared_regs[reg1->idx]; | ||
| 209 | atomic_dec(&er->ref); | ||
| 210 | reg1->alloc = 0; | ||
| 211 | } | ||
| 212 | |||
| 213 | static int snbep_uncore_hw_config(struct intel_uncore_box *box, | ||
| 214 | struct perf_event *event) | ||
| 215 | { | 228 | { |
| 216 | struct hw_perf_event *hwc = &event->hw; | 229 | struct hw_perf_event *hwc = &event->hw; |
| 217 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; | 230 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; |
| @@ -221,14 +234,16 @@ static int snbep_uncore_hw_config(struct intel_uncore_box *box, | |||
| 221 | SNBEP_CBO_MSR_OFFSET * box->pmu->pmu_idx; | 234 | SNBEP_CBO_MSR_OFFSET * box->pmu->pmu_idx; |
| 222 | reg1->config = event->attr.config1 & | 235 | reg1->config = event->attr.config1 & |
| 223 | SNBEP_CB0_MSR_PMON_BOX_FILTER_MASK; | 236 | SNBEP_CB0_MSR_PMON_BOX_FILTER_MASK; |
| 224 | } else if (box->pmu->type == &snbep_uncore_pcu) { | ||
| 225 | reg1->reg = SNBEP_PCU_MSR_PMON_BOX_FILTER; | ||
| 226 | reg1->config = event->attr.config1 & | ||
| 227 | SNBEP_PCU_MSR_PMON_BOX_FILTER_MASK; | ||
| 228 | } else { | 237 | } else { |
| 229 | return 0; | 238 | if (box->pmu->type == &snbep_uncore_pcu) { |
| 239 | reg1->reg = SNBEP_PCU_MSR_PMON_BOX_FILTER; | ||
| 240 | reg1->config = event->attr.config1 & SNBEP_PCU_MSR_PMON_BOX_FILTER_MASK; | ||
| 241 | } else { | ||
| 242 | return 0; | ||
| 243 | } | ||
| 230 | } | 244 | } |
| 231 | reg1->idx = 0; | 245 | reg1->idx = 0; |
| 246 | |||
| 232 | return 0; | 247 | return 0; |
| 233 | } | 248 | } |
| 234 | 249 | ||
| @@ -272,10 +287,19 @@ static struct attribute *snbep_uncore_pcu_formats_attr[] = { | |||
| 272 | &format_attr_thresh5.attr, | 287 | &format_attr_thresh5.attr, |
| 273 | &format_attr_occ_invert.attr, | 288 | &format_attr_occ_invert.attr, |
| 274 | &format_attr_occ_edge.attr, | 289 | &format_attr_occ_edge.attr, |
| 275 | &format_attr_filter_brand0.attr, | 290 | &format_attr_filter_band0.attr, |
| 276 | &format_attr_filter_brand1.attr, | 291 | &format_attr_filter_band1.attr, |
| 277 | &format_attr_filter_brand2.attr, | 292 | &format_attr_filter_band2.attr, |
| 278 | &format_attr_filter_brand3.attr, | 293 | &format_attr_filter_band3.attr, |
| 294 | NULL, | ||
| 295 | }; | ||
| 296 | |||
| 297 | static struct attribute *snbep_uncore_qpi_formats_attr[] = { | ||
| 298 | &format_attr_event_ext.attr, | ||
| 299 | &format_attr_umask.attr, | ||
| 300 | &format_attr_edge.attr, | ||
| 301 | &format_attr_inv.attr, | ||
| 302 | &format_attr_thresh8.attr, | ||
| 279 | NULL, | 303 | NULL, |
| 280 | }; | 304 | }; |
| 281 | 305 | ||
| @@ -314,15 +338,20 @@ static struct attribute_group snbep_uncore_pcu_format_group = { | |||
| 314 | .attrs = snbep_uncore_pcu_formats_attr, | 338 | .attrs = snbep_uncore_pcu_formats_attr, |
| 315 | }; | 339 | }; |
| 316 | 340 | ||
| 341 | static struct attribute_group snbep_uncore_qpi_format_group = { | ||
| 342 | .name = "format", | ||
| 343 | .attrs = snbep_uncore_qpi_formats_attr, | ||
| 344 | }; | ||
| 345 | |||
| 317 | static struct intel_uncore_ops snbep_uncore_msr_ops = { | 346 | static struct intel_uncore_ops snbep_uncore_msr_ops = { |
| 318 | .init_box = snbep_uncore_msr_init_box, | 347 | .init_box = snbep_uncore_msr_init_box, |
| 319 | .disable_box = snbep_uncore_msr_disable_box, | 348 | .disable_box = snbep_uncore_msr_disable_box, |
| 320 | .enable_box = snbep_uncore_msr_enable_box, | 349 | .enable_box = snbep_uncore_msr_enable_box, |
| 321 | .disable_event = snbep_uncore_msr_disable_event, | 350 | .disable_event = snbep_uncore_msr_disable_event, |
| 322 | .enable_event = snbep_uncore_msr_enable_event, | 351 | .enable_event = snbep_uncore_msr_enable_event, |
| 323 | .read_counter = snbep_uncore_msr_read_counter, | 352 | .read_counter = uncore_msr_read_counter, |
| 324 | .get_constraint = snbep_uncore_get_constraint, | 353 | .get_constraint = uncore_get_constraint, |
| 325 | .put_constraint = snbep_uncore_put_constraint, | 354 | .put_constraint = uncore_put_constraint, |
| 326 | .hw_config = snbep_uncore_hw_config, | 355 | .hw_config = snbep_uncore_hw_config, |
| 327 | }; | 356 | }; |
| 328 | 357 | ||
| @@ -485,8 +514,13 @@ static struct intel_uncore_type snbep_uncore_qpi = { | |||
| 485 | .num_counters = 4, | 514 | .num_counters = 4, |
| 486 | .num_boxes = 2, | 515 | .num_boxes = 2, |
| 487 | .perf_ctr_bits = 48, | 516 | .perf_ctr_bits = 48, |
| 517 | .perf_ctr = SNBEP_PCI_PMON_CTR0, | ||
| 518 | .event_ctl = SNBEP_PCI_PMON_CTL0, | ||
| 519 | .event_mask = SNBEP_QPI_PCI_PMON_RAW_EVENT_MASK, | ||
| 520 | .box_ctl = SNBEP_PCI_PMON_BOX_CTL, | ||
| 521 | .ops = &snbep_uncore_pci_ops, | ||
| 488 | .event_descs = snbep_uncore_qpi_events, | 522 | .event_descs = snbep_uncore_qpi_events, |
| 489 | SNBEP_UNCORE_PCI_COMMON_INIT(), | 523 | .format_group = &snbep_uncore_qpi_format_group, |
| 490 | }; | 524 | }; |
| 491 | 525 | ||
| 492 | 526 | ||
| @@ -603,10 +637,8 @@ static void snbep_pci2phy_map_init(void) | |||
| 603 | } | 637 | } |
| 604 | /* end of Sandy Bridge-EP uncore support */ | 638 | /* end of Sandy Bridge-EP uncore support */ |
| 605 | 639 | ||
| 606 | |||
| 607 | /* Sandy Bridge uncore support */ | 640 | /* Sandy Bridge uncore support */ |
| 608 | static void snb_uncore_msr_enable_event(struct intel_uncore_box *box, | 641 | static void snb_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event) |
| 609 | struct perf_event *event) | ||
| 610 | { | 642 | { |
| 611 | struct hw_perf_event *hwc = &event->hw; | 643 | struct hw_perf_event *hwc = &event->hw; |
| 612 | 644 | ||
| @@ -616,20 +648,11 @@ static void snb_uncore_msr_enable_event(struct intel_uncore_box *box, | |||
| 616 | wrmsrl(hwc->config_base, SNB_UNC_CTL_EN); | 648 | wrmsrl(hwc->config_base, SNB_UNC_CTL_EN); |
| 617 | } | 649 | } |
| 618 | 650 | ||
| 619 | static void snb_uncore_msr_disable_event(struct intel_uncore_box *box, | 651 | static void snb_uncore_msr_disable_event(struct intel_uncore_box *box, struct perf_event *event) |
| 620 | struct perf_event *event) | ||
| 621 | { | 652 | { |
| 622 | wrmsrl(event->hw.config_base, 0); | 653 | wrmsrl(event->hw.config_base, 0); |
| 623 | } | 654 | } |
| 624 | 655 | ||
| 625 | static u64 snb_uncore_msr_read_counter(struct intel_uncore_box *box, | ||
| 626 | struct perf_event *event) | ||
| 627 | { | ||
| 628 | u64 count; | ||
| 629 | rdmsrl(event->hw.event_base, count); | ||
| 630 | return count; | ||
| 631 | } | ||
| 632 | |||
| 633 | static void snb_uncore_msr_init_box(struct intel_uncore_box *box) | 656 | static void snb_uncore_msr_init_box(struct intel_uncore_box *box) |
| 634 | { | 657 | { |
| 635 | if (box->pmu->pmu_idx == 0) { | 658 | if (box->pmu->pmu_idx == 0) { |
| @@ -648,15 +671,15 @@ static struct attribute *snb_uncore_formats_attr[] = { | |||
| 648 | }; | 671 | }; |
| 649 | 672 | ||
| 650 | static struct attribute_group snb_uncore_format_group = { | 673 | static struct attribute_group snb_uncore_format_group = { |
| 651 | .name = "format", | 674 | .name = "format", |
| 652 | .attrs = snb_uncore_formats_attr, | 675 | .attrs = snb_uncore_formats_attr, |
| 653 | }; | 676 | }; |
| 654 | 677 | ||
| 655 | static struct intel_uncore_ops snb_uncore_msr_ops = { | 678 | static struct intel_uncore_ops snb_uncore_msr_ops = { |
| 656 | .init_box = snb_uncore_msr_init_box, | 679 | .init_box = snb_uncore_msr_init_box, |
| 657 | .disable_event = snb_uncore_msr_disable_event, | 680 | .disable_event = snb_uncore_msr_disable_event, |
| 658 | .enable_event = snb_uncore_msr_enable_event, | 681 | .enable_event = snb_uncore_msr_enable_event, |
| 659 | .read_counter = snb_uncore_msr_read_counter, | 682 | .read_counter = uncore_msr_read_counter, |
| 660 | }; | 683 | }; |
| 661 | 684 | ||
| 662 | static struct event_constraint snb_uncore_cbox_constraints[] = { | 685 | static struct event_constraint snb_uncore_cbox_constraints[] = { |
| @@ -697,12 +720,10 @@ static void nhm_uncore_msr_disable_box(struct intel_uncore_box *box) | |||
| 697 | 720 | ||
| 698 | static void nhm_uncore_msr_enable_box(struct intel_uncore_box *box) | 721 | static void nhm_uncore_msr_enable_box(struct intel_uncore_box *box) |
| 699 | { | 722 | { |
| 700 | wrmsrl(NHM_UNC_PERF_GLOBAL_CTL, | 723 | wrmsrl(NHM_UNC_PERF_GLOBAL_CTL, NHM_UNC_GLOBAL_CTL_EN_PC_ALL | NHM_UNC_GLOBAL_CTL_EN_FC); |
| 701 | NHM_UNC_GLOBAL_CTL_EN_PC_ALL | NHM_UNC_GLOBAL_CTL_EN_FC); | ||
| 702 | } | 724 | } |
| 703 | 725 | ||
| 704 | static void nhm_uncore_msr_enable_event(struct intel_uncore_box *box, | 726 | static void nhm_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event) |
| 705 | struct perf_event *event) | ||
| 706 | { | 727 | { |
| 707 | struct hw_perf_event *hwc = &event->hw; | 728 | struct hw_perf_event *hwc = &event->hw; |
| 708 | 729 | ||
| @@ -744,7 +765,7 @@ static struct intel_uncore_ops nhm_uncore_msr_ops = { | |||
| 744 | .enable_box = nhm_uncore_msr_enable_box, | 765 | .enable_box = nhm_uncore_msr_enable_box, |
| 745 | .disable_event = snb_uncore_msr_disable_event, | 766 | .disable_event = snb_uncore_msr_disable_event, |
| 746 | .enable_event = nhm_uncore_msr_enable_event, | 767 | .enable_event = nhm_uncore_msr_enable_event, |
| 747 | .read_counter = snb_uncore_msr_read_counter, | 768 | .read_counter = uncore_msr_read_counter, |
| 748 | }; | 769 | }; |
| 749 | 770 | ||
| 750 | static struct intel_uncore_type nhm_uncore = { | 771 | static struct intel_uncore_type nhm_uncore = { |
| @@ -769,8 +790,1041 @@ static struct intel_uncore_type *nhm_msr_uncores[] = { | |||
| 769 | }; | 790 | }; |
| 770 | /* end of Nehalem uncore support */ | 791 | /* end of Nehalem uncore support */ |
| 771 | 792 | ||
| 772 | static void uncore_assign_hw_event(struct intel_uncore_box *box, | 793 | /* Nehalem-EX uncore support */ |
| 773 | struct perf_event *event, int idx) | 794 | #define __BITS_VALUE(x, i, n) ((typeof(x))(((x) >> ((i) * (n))) & \ |
| 795 | ((1ULL << (n)) - 1))) | ||
| 796 | |||
| 797 | DEFINE_UNCORE_FORMAT_ATTR(event5, event, "config:1-5"); | ||
| 798 | DEFINE_UNCORE_FORMAT_ATTR(counter, counter, "config:6-7"); | ||
| 799 | DEFINE_UNCORE_FORMAT_ATTR(mm_cfg, mm_cfg, "config:63"); | ||
| 800 | DEFINE_UNCORE_FORMAT_ATTR(match, match, "config1:0-63"); | ||
| 801 | DEFINE_UNCORE_FORMAT_ATTR(mask, mask, "config2:0-63"); | ||
| 802 | |||
| 803 | static void nhmex_uncore_msr_init_box(struct intel_uncore_box *box) | ||
| 804 | { | ||
| 805 | wrmsrl(NHMEX_U_MSR_PMON_GLOBAL_CTL, NHMEX_U_PMON_GLOBAL_EN_ALL); | ||
| 806 | } | ||
| 807 | |||
| 808 | static void nhmex_uncore_msr_disable_box(struct intel_uncore_box *box) | ||
| 809 | { | ||
| 810 | unsigned msr = uncore_msr_box_ctl(box); | ||
| 811 | u64 config; | ||
| 812 | |||
| 813 | if (msr) { | ||
| 814 | rdmsrl(msr, config); | ||
| 815 | config &= ~((1ULL << uncore_num_counters(box)) - 1); | ||
| 816 | /* WBox has a fixed counter */ | ||
| 817 | if (uncore_msr_fixed_ctl(box)) | ||
| 818 | config &= ~NHMEX_W_PMON_GLOBAL_FIXED_EN; | ||
| 819 | wrmsrl(msr, config); | ||
| 820 | } | ||
| 821 | } | ||
| 822 | |||
| 823 | static void nhmex_uncore_msr_enable_box(struct intel_uncore_box *box) | ||
| 824 | { | ||
| 825 | unsigned msr = uncore_msr_box_ctl(box); | ||
| 826 | u64 config; | ||
| 827 | |||
| 828 | if (msr) { | ||
| 829 | rdmsrl(msr, config); | ||
| 830 | config |= (1ULL << uncore_num_counters(box)) - 1; | ||
| 831 | /* WBox has a fixed counter */ | ||
| 832 | if (uncore_msr_fixed_ctl(box)) | ||
| 833 | config |= NHMEX_W_PMON_GLOBAL_FIXED_EN; | ||
| 834 | wrmsrl(msr, config); | ||
| 835 | } | ||
| 836 | } | ||
| 837 | |||
| 838 | static void nhmex_uncore_msr_disable_event(struct intel_uncore_box *box, struct perf_event *event) | ||
| 839 | { | ||
| 840 | wrmsrl(event->hw.config_base, 0); | ||
| 841 | } | ||
| 842 | |||
| 843 | static void nhmex_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event) | ||
| 844 | { | ||
| 845 | struct hw_perf_event *hwc = &event->hw; | ||
| 846 | |||
| 847 | if (hwc->idx >= UNCORE_PMC_IDX_FIXED) | ||
| 848 | wrmsrl(hwc->config_base, NHMEX_PMON_CTL_EN_BIT0); | ||
| 849 | else if (box->pmu->type->event_mask & NHMEX_PMON_CTL_EN_BIT0) | ||
| 850 | wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT22); | ||
| 851 | else | ||
| 852 | wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT0); | ||
| 853 | } | ||
| 854 | |||
| 855 | #define NHMEX_UNCORE_OPS_COMMON_INIT() \ | ||
| 856 | .init_box = nhmex_uncore_msr_init_box, \ | ||
| 857 | .disable_box = nhmex_uncore_msr_disable_box, \ | ||
| 858 | .enable_box = nhmex_uncore_msr_enable_box, \ | ||
| 859 | .disable_event = nhmex_uncore_msr_disable_event, \ | ||
| 860 | .read_counter = uncore_msr_read_counter | ||
| 861 | |||
| 862 | static struct intel_uncore_ops nhmex_uncore_ops = { | ||
| 863 | NHMEX_UNCORE_OPS_COMMON_INIT(), | ||
| 864 | .enable_event = nhmex_uncore_msr_enable_event, | ||
| 865 | }; | ||
| 866 | |||
| 867 | static struct attribute *nhmex_uncore_ubox_formats_attr[] = { | ||
| 868 | &format_attr_event.attr, | ||
| 869 | &format_attr_edge.attr, | ||
| 870 | NULL, | ||
| 871 | }; | ||
| 872 | |||
| 873 | static struct attribute_group nhmex_uncore_ubox_format_group = { | ||
| 874 | .name = "format", | ||
| 875 | .attrs = nhmex_uncore_ubox_formats_attr, | ||
| 876 | }; | ||
| 877 | |||
| 878 | static struct intel_uncore_type nhmex_uncore_ubox = { | ||
| 879 | .name = "ubox", | ||
| 880 | .num_counters = 1, | ||
| 881 | .num_boxes = 1, | ||
| 882 | .perf_ctr_bits = 48, | ||
| 883 | .event_ctl = NHMEX_U_MSR_PMON_EV_SEL, | ||
| 884 | .perf_ctr = NHMEX_U_MSR_PMON_CTR, | ||
| 885 | .event_mask = NHMEX_U_PMON_RAW_EVENT_MASK, | ||
| 886 | .box_ctl = NHMEX_U_MSR_PMON_GLOBAL_CTL, | ||
| 887 | .ops = &nhmex_uncore_ops, | ||
| 888 | .format_group = &nhmex_uncore_ubox_format_group | ||
| 889 | }; | ||
| 890 | |||
| 891 | static struct attribute *nhmex_uncore_cbox_formats_attr[] = { | ||
| 892 | &format_attr_event.attr, | ||
| 893 | &format_attr_umask.attr, | ||
| 894 | &format_attr_edge.attr, | ||
| 895 | &format_attr_inv.attr, | ||
| 896 | &format_attr_thresh8.attr, | ||
| 897 | NULL, | ||
| 898 | }; | ||
| 899 | |||
| 900 | static struct attribute_group nhmex_uncore_cbox_format_group = { | ||
| 901 | .name = "format", | ||
| 902 | .attrs = nhmex_uncore_cbox_formats_attr, | ||
| 903 | }; | ||
| 904 | |||
| 905 | static struct intel_uncore_type nhmex_uncore_cbox = { | ||
| 906 | .name = "cbox", | ||
| 907 | .num_counters = 6, | ||
| 908 | .num_boxes = 8, | ||
| 909 | .perf_ctr_bits = 48, | ||
| 910 | .event_ctl = NHMEX_C0_MSR_PMON_EV_SEL0, | ||
| 911 | .perf_ctr = NHMEX_C0_MSR_PMON_CTR0, | ||
| 912 | .event_mask = NHMEX_PMON_RAW_EVENT_MASK, | ||
| 913 | .box_ctl = NHMEX_C0_MSR_PMON_GLOBAL_CTL, | ||
| 914 | .msr_offset = NHMEX_C_MSR_OFFSET, | ||
| 915 | .pair_ctr_ctl = 1, | ||
| 916 | .ops = &nhmex_uncore_ops, | ||
| 917 | .format_group = &nhmex_uncore_cbox_format_group | ||
| 918 | }; | ||
| 919 | |||
| 920 | static struct uncore_event_desc nhmex_uncore_wbox_events[] = { | ||
| 921 | INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0"), | ||
| 922 | { /* end: all zeroes */ }, | ||
| 923 | }; | ||
| 924 | |||
| 925 | static struct intel_uncore_type nhmex_uncore_wbox = { | ||
| 926 | .name = "wbox", | ||
| 927 | .num_counters = 4, | ||
| 928 | .num_boxes = 1, | ||
| 929 | .perf_ctr_bits = 48, | ||
| 930 | .event_ctl = NHMEX_W_MSR_PMON_CNT0, | ||
| 931 | .perf_ctr = NHMEX_W_MSR_PMON_EVT_SEL0, | ||
| 932 | .fixed_ctr = NHMEX_W_MSR_PMON_FIXED_CTR, | ||
| 933 | .fixed_ctl = NHMEX_W_MSR_PMON_FIXED_CTL, | ||
| 934 | .event_mask = NHMEX_PMON_RAW_EVENT_MASK, | ||
| 935 | .box_ctl = NHMEX_W_MSR_GLOBAL_CTL, | ||
| 936 | .pair_ctr_ctl = 1, | ||
| 937 | .event_descs = nhmex_uncore_wbox_events, | ||
| 938 | .ops = &nhmex_uncore_ops, | ||
| 939 | .format_group = &nhmex_uncore_cbox_format_group | ||
| 940 | }; | ||
| 941 | |||
| 942 | static int nhmex_bbox_hw_config(struct intel_uncore_box *box, struct perf_event *event) | ||
| 943 | { | ||
| 944 | struct hw_perf_event *hwc = &event->hw; | ||
| 945 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; | ||
| 946 | struct hw_perf_event_extra *reg2 = &hwc->branch_reg; | ||
| 947 | int ctr, ev_sel; | ||
| 948 | |||
| 949 | ctr = (hwc->config & NHMEX_B_PMON_CTR_MASK) >> | ||
| 950 | NHMEX_B_PMON_CTR_SHIFT; | ||
| 951 | ev_sel = (hwc->config & NHMEX_B_PMON_CTL_EV_SEL_MASK) >> | ||
| 952 | NHMEX_B_PMON_CTL_EV_SEL_SHIFT; | ||
| 953 | |||
| 954 | /* events that do not use the match/mask registers */ | ||
| 955 | if ((ctr == 0 && ev_sel > 0x3) || (ctr == 1 && ev_sel > 0x6) || | ||
| 956 | (ctr == 2 && ev_sel != 0x4) || ctr == 3) | ||
| 957 | return 0; | ||
| 958 | |||
| 959 | if (box->pmu->pmu_idx == 0) | ||
| 960 | reg1->reg = NHMEX_B0_MSR_MATCH; | ||
| 961 | else | ||
| 962 | reg1->reg = NHMEX_B1_MSR_MATCH; | ||
| 963 | reg1->idx = 0; | ||
| 964 | reg1->config = event->attr.config1; | ||
| 965 | reg2->config = event->attr.config2; | ||
| 966 | return 0; | ||
| 967 | } | ||
| 968 | |||
| 969 | static void nhmex_bbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event) | ||
| 970 | { | ||
| 971 | struct hw_perf_event *hwc = &event->hw; | ||
| 972 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; | ||
| 973 | struct hw_perf_event_extra *reg2 = &hwc->branch_reg; | ||
| 974 | |||
| 975 | if (reg1->idx != EXTRA_REG_NONE) { | ||
| 976 | wrmsrl(reg1->reg, reg1->config); | ||
| 977 | wrmsrl(reg1->reg + 1, reg2->config); | ||
| 978 | } | ||
| 979 | wrmsrl(hwc->config_base, NHMEX_PMON_CTL_EN_BIT0 | | ||
| 980 | (hwc->config & NHMEX_B_PMON_CTL_EV_SEL_MASK)); | ||
| 981 | } | ||
| 982 | |||
| 983 | /* | ||
| 984 | * The Bbox has 4 counters, but each counter monitors different events. | ||
| 985 | * Use bits 6-7 in the event config to select counter. | ||
| 986 | */ | ||
| 987 | static struct event_constraint nhmex_uncore_bbox_constraints[] = { | ||
| 988 | EVENT_CONSTRAINT(0 , 1, 0xc0), | ||
| 989 | EVENT_CONSTRAINT(0x40, 2, 0xc0), | ||
| 990 | EVENT_CONSTRAINT(0x80, 4, 0xc0), | ||
| 991 | EVENT_CONSTRAINT(0xc0, 8, 0xc0), | ||
| 992 | EVENT_CONSTRAINT_END, | ||
| 993 | }; | ||
| 994 | |||
| 995 | static struct attribute *nhmex_uncore_bbox_formats_attr[] = { | ||
| 996 | &format_attr_event5.attr, | ||
| 997 | &format_attr_counter.attr, | ||
| 998 | &format_attr_match.attr, | ||
| 999 | &format_attr_mask.attr, | ||
| 1000 | NULL, | ||
| 1001 | }; | ||
| 1002 | |||
| 1003 | static struct attribute_group nhmex_uncore_bbox_format_group = { | ||
| 1004 | .name = "format", | ||
| 1005 | .attrs = nhmex_uncore_bbox_formats_attr, | ||
| 1006 | }; | ||
| 1007 | |||
| 1008 | static struct intel_uncore_ops nhmex_uncore_bbox_ops = { | ||
| 1009 | NHMEX_UNCORE_OPS_COMMON_INIT(), | ||
| 1010 | .enable_event = nhmex_bbox_msr_enable_event, | ||
| 1011 | .hw_config = nhmex_bbox_hw_config, | ||
| 1012 | .get_constraint = uncore_get_constraint, | ||
| 1013 | .put_constraint = uncore_put_constraint, | ||
| 1014 | }; | ||
| 1015 | |||
| 1016 | static struct intel_uncore_type nhmex_uncore_bbox = { | ||
| 1017 | .name = "bbox", | ||
| 1018 | .num_counters = 4, | ||
| 1019 | .num_boxes = 2, | ||
| 1020 | .perf_ctr_bits = 48, | ||
| 1021 | .event_ctl = NHMEX_B0_MSR_PMON_CTL0, | ||
| 1022 | .perf_ctr = NHMEX_B0_MSR_PMON_CTR0, | ||
| 1023 | .event_mask = NHMEX_B_PMON_RAW_EVENT_MASK, | ||
| 1024 | .box_ctl = NHMEX_B0_MSR_PMON_GLOBAL_CTL, | ||
| 1025 | .msr_offset = NHMEX_B_MSR_OFFSET, | ||
| 1026 | .pair_ctr_ctl = 1, | ||
| 1027 | .num_shared_regs = 1, | ||
| 1028 | .constraints = nhmex_uncore_bbox_constraints, | ||
| 1029 | .ops = &nhmex_uncore_bbox_ops, | ||
| 1030 | .format_group = &nhmex_uncore_bbox_format_group | ||
| 1031 | }; | ||
| 1032 | |||
| 1033 | static int nhmex_sbox_hw_config(struct intel_uncore_box *box, struct perf_event *event) | ||
| 1034 | { | ||
| 1035 | struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; | ||
| 1036 | struct hw_perf_event_extra *reg2 = &event->hw.branch_reg; | ||
| 1037 | |||
| 1038 | if (event->attr.config & NHMEX_S_PMON_MM_CFG_EN) { | ||
| 1039 | reg1->config = event->attr.config1; | ||
| 1040 | reg2->config = event->attr.config2; | ||
| 1041 | } else { | ||
| 1042 | reg1->config = ~0ULL; | ||
| 1043 | reg2->config = ~0ULL; | ||
| 1044 | } | ||
| 1045 | |||
| 1046 | if (box->pmu->pmu_idx == 0) | ||
| 1047 | reg1->reg = NHMEX_S0_MSR_MM_CFG; | ||
| 1048 | else | ||
| 1049 | reg1->reg = NHMEX_S1_MSR_MM_CFG; | ||
| 1050 | |||
| 1051 | reg1->idx = 0; | ||
| 1052 | |||
| 1053 | return 0; | ||
| 1054 | } | ||
| 1055 | |||
| 1056 | static void nhmex_sbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event) | ||
| 1057 | { | ||
| 1058 | struct hw_perf_event *hwc = &event->hw; | ||
| 1059 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; | ||
| 1060 | struct hw_perf_event_extra *reg2 = &hwc->branch_reg; | ||
| 1061 | |||
| 1062 | wrmsrl(reg1->reg, 0); | ||
| 1063 | if (reg1->config != ~0ULL || reg2->config != ~0ULL) { | ||
| 1064 | wrmsrl(reg1->reg + 1, reg1->config); | ||
| 1065 | wrmsrl(reg1->reg + 2, reg2->config); | ||
| 1066 | wrmsrl(reg1->reg, NHMEX_S_PMON_MM_CFG_EN); | ||
| 1067 | } | ||
| 1068 | wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT22); | ||
| 1069 | } | ||
| 1070 | |||
| 1071 | static struct attribute *nhmex_uncore_sbox_formats_attr[] = { | ||
| 1072 | &format_attr_event.attr, | ||
| 1073 | &format_attr_umask.attr, | ||
| 1074 | &format_attr_edge.attr, | ||
| 1075 | &format_attr_inv.attr, | ||
| 1076 | &format_attr_thresh8.attr, | ||
| 1077 | &format_attr_mm_cfg.attr, | ||
| 1078 | &format_attr_match.attr, | ||
| 1079 | &format_attr_mask.attr, | ||
| 1080 | NULL, | ||
| 1081 | }; | ||
| 1082 | |||
| 1083 | static struct attribute_group nhmex_uncore_sbox_format_group = { | ||
| 1084 | .name = "format", | ||
| 1085 | .attrs = nhmex_uncore_sbox_formats_attr, | ||
| 1086 | }; | ||
| 1087 | |||
| 1088 | static struct intel_uncore_ops nhmex_uncore_sbox_ops = { | ||
| 1089 | NHMEX_UNCORE_OPS_COMMON_INIT(), | ||
| 1090 | .enable_event = nhmex_sbox_msr_enable_event, | ||
| 1091 | .hw_config = nhmex_sbox_hw_config, | ||
| 1092 | .get_constraint = uncore_get_constraint, | ||
| 1093 | .put_constraint = uncore_put_constraint, | ||
| 1094 | }; | ||
| 1095 | |||
| 1096 | static struct intel_uncore_type nhmex_uncore_sbox = { | ||
| 1097 | .name = "sbox", | ||
| 1098 | .num_counters = 4, | ||
| 1099 | .num_boxes = 2, | ||
| 1100 | .perf_ctr_bits = 48, | ||
| 1101 | .event_ctl = NHMEX_S0_MSR_PMON_CTL0, | ||
| 1102 | .perf_ctr = NHMEX_S0_MSR_PMON_CTR0, | ||
| 1103 | .event_mask = NHMEX_PMON_RAW_EVENT_MASK, | ||
| 1104 | .box_ctl = NHMEX_S0_MSR_PMON_GLOBAL_CTL, | ||
| 1105 | .msr_offset = NHMEX_S_MSR_OFFSET, | ||
| 1106 | .pair_ctr_ctl = 1, | ||
| 1107 | .num_shared_regs = 1, | ||
| 1108 | .ops = &nhmex_uncore_sbox_ops, | ||
| 1109 | .format_group = &nhmex_uncore_sbox_format_group | ||
| 1110 | }; | ||
| 1111 | |||
| 1112 | enum { | ||
| 1113 | EXTRA_REG_NHMEX_M_FILTER, | ||
| 1114 | EXTRA_REG_NHMEX_M_DSP, | ||
| 1115 | EXTRA_REG_NHMEX_M_ISS, | ||
| 1116 | EXTRA_REG_NHMEX_M_MAP, | ||
| 1117 | EXTRA_REG_NHMEX_M_MSC_THR, | ||
| 1118 | EXTRA_REG_NHMEX_M_PGT, | ||
| 1119 | EXTRA_REG_NHMEX_M_PLD, | ||
| 1120 | EXTRA_REG_NHMEX_M_ZDP_CTL_FVC, | ||
| 1121 | }; | ||
| 1122 | |||
| 1123 | static struct extra_reg nhmex_uncore_mbox_extra_regs[] = { | ||
| 1124 | MBOX_INC_SEL_EXTAR_REG(0x0, DSP), | ||
| 1125 | MBOX_INC_SEL_EXTAR_REG(0x4, MSC_THR), | ||
| 1126 | MBOX_INC_SEL_EXTAR_REG(0x5, MSC_THR), | ||
| 1127 | MBOX_INC_SEL_EXTAR_REG(0x9, ISS), | ||
| 1128 | /* event 0xa uses two extra registers */ | ||
| 1129 | MBOX_INC_SEL_EXTAR_REG(0xa, ISS), | ||
| 1130 | MBOX_INC_SEL_EXTAR_REG(0xa, PLD), | ||
| 1131 | MBOX_INC_SEL_EXTAR_REG(0xb, PLD), | ||
| 1132 | /* events 0xd ~ 0x10 use the same extra register */ | ||
| 1133 | MBOX_INC_SEL_EXTAR_REG(0xd, ZDP_CTL_FVC), | ||
| 1134 | MBOX_INC_SEL_EXTAR_REG(0xe, ZDP_CTL_FVC), | ||
| 1135 | MBOX_INC_SEL_EXTAR_REG(0xf, ZDP_CTL_FVC), | ||
| 1136 | MBOX_INC_SEL_EXTAR_REG(0x10, ZDP_CTL_FVC), | ||
| 1137 | MBOX_INC_SEL_EXTAR_REG(0x16, PGT), | ||
| 1138 | MBOX_SET_FLAG_SEL_EXTRA_REG(0x0, DSP), | ||
| 1139 | MBOX_SET_FLAG_SEL_EXTRA_REG(0x1, ISS), | ||
| 1140 | MBOX_SET_FLAG_SEL_EXTRA_REG(0x5, PGT), | ||
| 1141 | MBOX_SET_FLAG_SEL_EXTRA_REG(0x6, MAP), | ||
| 1142 | EVENT_EXTRA_END | ||
| 1143 | }; | ||
| 1144 | |||
| 1145 | static bool nhmex_mbox_get_shared_reg(struct intel_uncore_box *box, int idx, u64 config) | ||
| 1146 | { | ||
| 1147 | struct intel_uncore_extra_reg *er; | ||
| 1148 | unsigned long flags; | ||
| 1149 | bool ret = false; | ||
| 1150 | u64 mask; | ||
| 1151 | |||
| 1152 | if (idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC) { | ||
| 1153 | er = &box->shared_regs[idx]; | ||
| 1154 | raw_spin_lock_irqsave(&er->lock, flags); | ||
| 1155 | if (!atomic_read(&er->ref) || er->config == config) { | ||
| 1156 | atomic_inc(&er->ref); | ||
| 1157 | er->config = config; | ||
| 1158 | ret = true; | ||
| 1159 | } | ||
| 1160 | raw_spin_unlock_irqrestore(&er->lock, flags); | ||
| 1161 | |||
| 1162 | return ret; | ||
| 1163 | } | ||
| 1164 | /* | ||
| 1165 | * The ZDP_CTL_FVC MSR has 4 fields which are used to control | ||
| 1166 | * events 0xd ~ 0x10. Besides these 4 fields, there are additional | ||
| 1167 | * fields which are shared. | ||
| 1168 | */ | ||
| 1169 | idx -= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC; | ||
| 1170 | if (WARN_ON_ONCE(idx >= 4)) | ||
| 1171 | return false; | ||
| 1172 | |||
| 1173 | /* mask of the shared fields */ | ||
| 1174 | mask = NHMEX_M_PMON_ZDP_CTL_FVC_MASK; | ||
| 1175 | er = &box->shared_regs[EXTRA_REG_NHMEX_M_ZDP_CTL_FVC]; | ||
| 1176 | |||
| 1177 | raw_spin_lock_irqsave(&er->lock, flags); | ||
| 1178 | /* add mask of the non-shared field if it's in use */ | ||
| 1179 | if (__BITS_VALUE(atomic_read(&er->ref), idx, 8)) | ||
| 1180 | mask |= NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx); | ||
| 1181 | |||
| 1182 | if (!atomic_read(&er->ref) || !((er->config ^ config) & mask)) { | ||
| 1183 | atomic_add(1 << (idx * 8), &er->ref); | ||
| 1184 | mask = NHMEX_M_PMON_ZDP_CTL_FVC_MASK | | ||
| 1185 | NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx); | ||
| 1186 | er->config &= ~mask; | ||
| 1187 | er->config |= (config & mask); | ||
| 1188 | ret = true; | ||
| 1189 | } | ||
| 1190 | raw_spin_unlock_irqrestore(&er->lock, flags); | ||
| 1191 | |||
| 1192 | return ret; | ||
| 1193 | } | ||
| 1194 | |||
| 1195 | static void nhmex_mbox_put_shared_reg(struct intel_uncore_box *box, int idx) | ||
| 1196 | { | ||
| 1197 | struct intel_uncore_extra_reg *er; | ||
| 1198 | |||
| 1199 | if (idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC) { | ||
| 1200 | er = &box->shared_regs[idx]; | ||
| 1201 | atomic_dec(&er->ref); | ||
| 1202 | return; | ||
| 1203 | } | ||
| 1204 | |||
| 1205 | idx -= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC; | ||
| 1206 | er = &box->shared_regs[EXTRA_REG_NHMEX_M_ZDP_CTL_FVC]; | ||
| 1207 | atomic_sub(1 << (idx * 8), &er->ref); | ||
| 1208 | } | ||
| 1209 | |||
| 1210 | u64 nhmex_mbox_alter_er(struct perf_event *event, int new_idx, bool modify) | ||
| 1211 | { | ||
| 1212 | struct hw_perf_event *hwc = &event->hw; | ||
| 1213 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; | ||
| 1214 | int idx, orig_idx = __BITS_VALUE(reg1->idx, 0, 8); | ||
| 1215 | u64 config = reg1->config; | ||
| 1216 | |||
| 1217 | /* get the non-shared control bits and shift them */ | ||
| 1218 | idx = orig_idx - EXTRA_REG_NHMEX_M_ZDP_CTL_FVC; | ||
| 1219 | config &= NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx); | ||
| 1220 | if (new_idx > orig_idx) { | ||
| 1221 | idx = new_idx - orig_idx; | ||
| 1222 | config <<= 3 * idx; | ||
| 1223 | } else { | ||
| 1224 | idx = orig_idx - new_idx; | ||
| 1225 | config >>= 3 * idx; | ||
| 1226 | } | ||
| 1227 | |||
| 1228 | /* add the shared control bits back */ | ||
| 1229 | config |= NHMEX_M_PMON_ZDP_CTL_FVC_MASK & reg1->config; | ||
| 1230 | if (modify) { | ||
| 1231 | /* adjust the main event selector */ | ||
| 1232 | if (new_idx > orig_idx) | ||
| 1233 | hwc->config += idx << NHMEX_M_PMON_CTL_INC_SEL_SHIFT; | ||
| 1234 | else | ||
| 1235 | hwc->config -= idx << NHMEX_M_PMON_CTL_INC_SEL_SHIFT; | ||
| 1236 | reg1->config = config; | ||
| 1237 | reg1->idx = ~0xff | new_idx; | ||
| 1238 | } | ||
| 1239 | return config; | ||
| 1240 | } | ||
| 1241 | |||
| 1242 | static struct event_constraint * | ||
| 1243 | nhmex_mbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event) | ||
| 1244 | { | ||
| 1245 | struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; | ||
| 1246 | struct hw_perf_event_extra *reg2 = &event->hw.branch_reg; | ||
| 1247 | int i, idx[2], alloc = 0; | ||
| 1248 | u64 config1 = reg1->config; | ||
| 1249 | |||
| 1250 | idx[0] = __BITS_VALUE(reg1->idx, 0, 8); | ||
| 1251 | idx[1] = __BITS_VALUE(reg1->idx, 1, 8); | ||
| 1252 | again: | ||
| 1253 | for (i = 0; i < 2; i++) { | ||
| 1254 | if (!uncore_box_is_fake(box) && (reg1->alloc & (0x1 << i))) | ||
| 1255 | idx[i] = 0xff; | ||
| 1256 | |||
| 1257 | if (idx[i] == 0xff) | ||
| 1258 | continue; | ||
| 1259 | |||
| 1260 | if (!nhmex_mbox_get_shared_reg(box, idx[i], | ||
| 1261 | __BITS_VALUE(config1, i, 32))) | ||
| 1262 | goto fail; | ||
| 1263 | alloc |= (0x1 << i); | ||
| 1264 | } | ||
| 1265 | |||
| 1266 | /* for the match/mask registers */ | ||
| 1267 | if ((uncore_box_is_fake(box) || !reg2->alloc) && | ||
| 1268 | !nhmex_mbox_get_shared_reg(box, reg2->idx, reg2->config)) | ||
| 1269 | goto fail; | ||
| 1270 | |||
| 1271 | /* | ||
| 1272 | * If it's a fake box -- as per validate_{group,event}() we | ||
| 1273 | * shouldn't touch event state and we can avoid doing so | ||
| 1274 | * since both will only call get_event_constraints() once | ||
| 1275 | * on each event, this avoids the need for reg->alloc. | ||
| 1276 | */ | ||
| 1277 | if (!uncore_box_is_fake(box)) { | ||
| 1278 | if (idx[0] != 0xff && idx[0] != __BITS_VALUE(reg1->idx, 0, 8)) | ||
| 1279 | nhmex_mbox_alter_er(event, idx[0], true); | ||
| 1280 | reg1->alloc |= alloc; | ||
| 1281 | reg2->alloc = 1; | ||
| 1282 | } | ||
| 1283 | return NULL; | ||
| 1284 | fail: | ||
| 1285 | if (idx[0] != 0xff && !(alloc & 0x1) && | ||
| 1286 | idx[0] >= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC) { | ||
| 1287 | /* | ||
| 1288 | * events 0xd ~ 0x10 are functional identical, but are | ||
| 1289 | * controlled by different fields in the ZDP_CTL_FVC | ||
| 1290 | * register. If we failed to take one field, try the | ||
| 1291 | * rest 3 choices. | ||
| 1292 | */ | ||
| 1293 | BUG_ON(__BITS_VALUE(reg1->idx, 1, 8) != 0xff); | ||
| 1294 | idx[0] -= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC; | ||
| 1295 | idx[0] = (idx[0] + 1) % 4; | ||
| 1296 | idx[0] += EXTRA_REG_NHMEX_M_ZDP_CTL_FVC; | ||
| 1297 | if (idx[0] != __BITS_VALUE(reg1->idx, 0, 8)) { | ||
| 1298 | config1 = nhmex_mbox_alter_er(event, idx[0], false); | ||
| 1299 | goto again; | ||
| 1300 | } | ||
| 1301 | } | ||
| 1302 | |||
| 1303 | if (alloc & 0x1) | ||
| 1304 | nhmex_mbox_put_shared_reg(box, idx[0]); | ||
| 1305 | if (alloc & 0x2) | ||
| 1306 | nhmex_mbox_put_shared_reg(box, idx[1]); | ||
| 1307 | return &constraint_empty; | ||
| 1308 | } | ||
| 1309 | |||
| 1310 | static void nhmex_mbox_put_constraint(struct intel_uncore_box *box, struct perf_event *event) | ||
| 1311 | { | ||
| 1312 | struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; | ||
| 1313 | struct hw_perf_event_extra *reg2 = &event->hw.branch_reg; | ||
| 1314 | |||
| 1315 | if (uncore_box_is_fake(box)) | ||
| 1316 | return; | ||
| 1317 | |||
| 1318 | if (reg1->alloc & 0x1) | ||
| 1319 | nhmex_mbox_put_shared_reg(box, __BITS_VALUE(reg1->idx, 0, 8)); | ||
| 1320 | if (reg1->alloc & 0x2) | ||
| 1321 | nhmex_mbox_put_shared_reg(box, __BITS_VALUE(reg1->idx, 1, 8)); | ||
| 1322 | reg1->alloc = 0; | ||
| 1323 | |||
| 1324 | if (reg2->alloc) { | ||
| 1325 | nhmex_mbox_put_shared_reg(box, reg2->idx); | ||
| 1326 | reg2->alloc = 0; | ||
| 1327 | } | ||
| 1328 | } | ||
| 1329 | |||
| 1330 | static int nhmex_mbox_extra_reg_idx(struct extra_reg *er) | ||
| 1331 | { | ||
| 1332 | if (er->idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC) | ||
| 1333 | return er->idx; | ||
| 1334 | return er->idx + (er->event >> NHMEX_M_PMON_CTL_INC_SEL_SHIFT) - 0xd; | ||
| 1335 | } | ||
| 1336 | |||
| 1337 | static int nhmex_mbox_hw_config(struct intel_uncore_box *box, struct perf_event *event) | ||
| 1338 | { | ||
| 1339 | struct intel_uncore_type *type = box->pmu->type; | ||
| 1340 | struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; | ||
| 1341 | struct hw_perf_event_extra *reg2 = &event->hw.branch_reg; | ||
| 1342 | struct extra_reg *er; | ||
| 1343 | unsigned msr; | ||
| 1344 | int reg_idx = 0; | ||
| 1345 | |||
| 1346 | if (WARN_ON_ONCE(reg1->idx != -1)) | ||
| 1347 | return -EINVAL; | ||
| 1348 | /* | ||
| 1349 | * The mbox events may require 2 extra MSRs at the most. But only | ||
| 1350 | * the lower 32 bits in these MSRs are significant, so we can use | ||
| 1351 | * config1 to pass two MSRs' config. | ||
| 1352 | */ | ||
| 1353 | for (er = nhmex_uncore_mbox_extra_regs; er->msr; er++) { | ||
| 1354 | if (er->event != (event->hw.config & er->config_mask)) | ||
| 1355 | continue; | ||
| 1356 | if (event->attr.config1 & ~er->valid_mask) | ||
| 1357 | return -EINVAL; | ||
| 1358 | if (er->idx == __BITS_VALUE(reg1->idx, 0, 8) || | ||
| 1359 | er->idx == __BITS_VALUE(reg1->idx, 1, 8)) | ||
| 1360 | continue; | ||
| 1361 | if (WARN_ON_ONCE(reg_idx >= 2)) | ||
| 1362 | return -EINVAL; | ||
| 1363 | |||
| 1364 | msr = er->msr + type->msr_offset * box->pmu->pmu_idx; | ||
| 1365 | if (WARN_ON_ONCE(msr >= 0xffff || er->idx >= 0xff)) | ||
| 1366 | return -EINVAL; | ||
| 1367 | |||
| 1368 | /* always use the 32~63 bits to pass the PLD config */ | ||
| 1369 | if (er->idx == EXTRA_REG_NHMEX_M_PLD) | ||
| 1370 | reg_idx = 1; | ||
| 1371 | |||
| 1372 | reg1->idx &= ~(0xff << (reg_idx * 8)); | ||
| 1373 | reg1->reg &= ~(0xffff << (reg_idx * 16)); | ||
| 1374 | reg1->idx |= nhmex_mbox_extra_reg_idx(er) << (reg_idx * 8); | ||
| 1375 | reg1->reg |= msr << (reg_idx * 16); | ||
| 1376 | reg1->config = event->attr.config1; | ||
| 1377 | reg_idx++; | ||
| 1378 | } | ||
| 1379 | /* use config2 to pass the filter config */ | ||
| 1380 | reg2->idx = EXTRA_REG_NHMEX_M_FILTER; | ||
| 1381 | if (event->attr.config2 & NHMEX_M_PMON_MM_CFG_EN) | ||
| 1382 | reg2->config = event->attr.config2; | ||
| 1383 | else | ||
| 1384 | reg2->config = ~0ULL; | ||
| 1385 | if (box->pmu->pmu_idx == 0) | ||
| 1386 | reg2->reg = NHMEX_M0_MSR_PMU_MM_CFG; | ||
| 1387 | else | ||
| 1388 | reg2->reg = NHMEX_M1_MSR_PMU_MM_CFG; | ||
| 1389 | |||
| 1390 | return 0; | ||
| 1391 | } | ||
| 1392 | |||
| 1393 | static u64 nhmex_mbox_shared_reg_config(struct intel_uncore_box *box, int idx) | ||
| 1394 | { | ||
| 1395 | struct intel_uncore_extra_reg *er; | ||
| 1396 | unsigned long flags; | ||
| 1397 | u64 config; | ||
| 1398 | |||
| 1399 | if (idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC) | ||
| 1400 | return box->shared_regs[idx].config; | ||
| 1401 | |||
| 1402 | er = &box->shared_regs[EXTRA_REG_NHMEX_M_ZDP_CTL_FVC]; | ||
| 1403 | raw_spin_lock_irqsave(&er->lock, flags); | ||
| 1404 | config = er->config; | ||
| 1405 | raw_spin_unlock_irqrestore(&er->lock, flags); | ||
| 1406 | return config; | ||
| 1407 | } | ||
| 1408 | |||
| 1409 | static void nhmex_mbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event) | ||
| 1410 | { | ||
| 1411 | struct hw_perf_event *hwc = &event->hw; | ||
| 1412 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; | ||
| 1413 | struct hw_perf_event_extra *reg2 = &hwc->branch_reg; | ||
| 1414 | int idx; | ||
| 1415 | |||
| 1416 | idx = __BITS_VALUE(reg1->idx, 0, 8); | ||
| 1417 | if (idx != 0xff) | ||
| 1418 | wrmsrl(__BITS_VALUE(reg1->reg, 0, 16), | ||
| 1419 | nhmex_mbox_shared_reg_config(box, idx)); | ||
| 1420 | idx = __BITS_VALUE(reg1->idx, 1, 8); | ||
| 1421 | if (idx != 0xff) | ||
| 1422 | wrmsrl(__BITS_VALUE(reg1->reg, 1, 16), | ||
| 1423 | nhmex_mbox_shared_reg_config(box, idx)); | ||
| 1424 | |||
| 1425 | wrmsrl(reg2->reg, 0); | ||
| 1426 | if (reg2->config != ~0ULL) { | ||
| 1427 | wrmsrl(reg2->reg + 1, | ||
| 1428 | reg2->config & NHMEX_M_PMON_ADDR_MATCH_MASK); | ||
| 1429 | wrmsrl(reg2->reg + 2, NHMEX_M_PMON_ADDR_MASK_MASK & | ||
| 1430 | (reg2->config >> NHMEX_M_PMON_ADDR_MASK_SHIFT)); | ||
| 1431 | wrmsrl(reg2->reg, NHMEX_M_PMON_MM_CFG_EN); | ||
| 1432 | } | ||
| 1433 | |||
| 1434 | wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT0); | ||
| 1435 | } | ||
| 1436 | |||
| 1437 | DEFINE_UNCORE_FORMAT_ATTR(count_mode, count_mode, "config:2-3"); | ||
| 1438 | DEFINE_UNCORE_FORMAT_ATTR(storage_mode, storage_mode, "config:4-5"); | ||
| 1439 | DEFINE_UNCORE_FORMAT_ATTR(wrap_mode, wrap_mode, "config:6"); | ||
| 1440 | DEFINE_UNCORE_FORMAT_ATTR(flag_mode, flag_mode, "config:7"); | ||
| 1441 | DEFINE_UNCORE_FORMAT_ATTR(inc_sel, inc_sel, "config:9-13"); | ||
| 1442 | DEFINE_UNCORE_FORMAT_ATTR(set_flag_sel, set_flag_sel, "config:19-21"); | ||
| 1443 | DEFINE_UNCORE_FORMAT_ATTR(filter_cfg, filter_cfg, "config2:63"); | ||
| 1444 | DEFINE_UNCORE_FORMAT_ATTR(filter_match, filter_match, "config2:0-33"); | ||
| 1445 | DEFINE_UNCORE_FORMAT_ATTR(filter_mask, filter_mask, "config2:34-61"); | ||
| 1446 | DEFINE_UNCORE_FORMAT_ATTR(dsp, dsp, "config1:0-31"); | ||
| 1447 | DEFINE_UNCORE_FORMAT_ATTR(thr, thr, "config1:0-31"); | ||
| 1448 | DEFINE_UNCORE_FORMAT_ATTR(fvc, fvc, "config1:0-31"); | ||
| 1449 | DEFINE_UNCORE_FORMAT_ATTR(pgt, pgt, "config1:0-31"); | ||
| 1450 | DEFINE_UNCORE_FORMAT_ATTR(map, map, "config1:0-31"); | ||
| 1451 | DEFINE_UNCORE_FORMAT_ATTR(iss, iss, "config1:0-31"); | ||
| 1452 | DEFINE_UNCORE_FORMAT_ATTR(pld, pld, "config1:32-63"); | ||
| 1453 | |||
| 1454 | static struct attribute *nhmex_uncore_mbox_formats_attr[] = { | ||
| 1455 | &format_attr_count_mode.attr, | ||
| 1456 | &format_attr_storage_mode.attr, | ||
| 1457 | &format_attr_wrap_mode.attr, | ||
| 1458 | &format_attr_flag_mode.attr, | ||
| 1459 | &format_attr_inc_sel.attr, | ||
| 1460 | &format_attr_set_flag_sel.attr, | ||
| 1461 | &format_attr_filter_cfg.attr, | ||
| 1462 | &format_attr_filter_match.attr, | ||
| 1463 | &format_attr_filter_mask.attr, | ||
| 1464 | &format_attr_dsp.attr, | ||
| 1465 | &format_attr_thr.attr, | ||
| 1466 | &format_attr_fvc.attr, | ||
| 1467 | &format_attr_pgt.attr, | ||
| 1468 | &format_attr_map.attr, | ||
| 1469 | &format_attr_iss.attr, | ||
| 1470 | &format_attr_pld.attr, | ||
| 1471 | NULL, | ||
| 1472 | }; | ||
| 1473 | |||
| 1474 | static struct attribute_group nhmex_uncore_mbox_format_group = { | ||
| 1475 | .name = "format", | ||
| 1476 | .attrs = nhmex_uncore_mbox_formats_attr, | ||
| 1477 | }; | ||
| 1478 | |||
| 1479 | static struct uncore_event_desc nhmex_uncore_mbox_events[] = { | ||
| 1480 | INTEL_UNCORE_EVENT_DESC(bbox_cmds_read, "inc_sel=0xd,fvc=0x2800"), | ||
| 1481 | INTEL_UNCORE_EVENT_DESC(bbox_cmds_write, "inc_sel=0xd,fvc=0x2820"), | ||
| 1482 | { /* end: all zeroes */ }, | ||
| 1483 | }; | ||
| 1484 | |||
| 1485 | static struct intel_uncore_ops nhmex_uncore_mbox_ops = { | ||
| 1486 | NHMEX_UNCORE_OPS_COMMON_INIT(), | ||
| 1487 | .enable_event = nhmex_mbox_msr_enable_event, | ||
| 1488 | .hw_config = nhmex_mbox_hw_config, | ||
| 1489 | .get_constraint = nhmex_mbox_get_constraint, | ||
| 1490 | .put_constraint = nhmex_mbox_put_constraint, | ||
| 1491 | }; | ||
| 1492 | |||
| 1493 | static struct intel_uncore_type nhmex_uncore_mbox = { | ||
| 1494 | .name = "mbox", | ||
| 1495 | .num_counters = 6, | ||
| 1496 | .num_boxes = 2, | ||
| 1497 | .perf_ctr_bits = 48, | ||
| 1498 | .event_ctl = NHMEX_M0_MSR_PMU_CTL0, | ||
| 1499 | .perf_ctr = NHMEX_M0_MSR_PMU_CNT0, | ||
| 1500 | .event_mask = NHMEX_M_PMON_RAW_EVENT_MASK, | ||
| 1501 | .box_ctl = NHMEX_M0_MSR_GLOBAL_CTL, | ||
| 1502 | .msr_offset = NHMEX_M_MSR_OFFSET, | ||
| 1503 | .pair_ctr_ctl = 1, | ||
| 1504 | .num_shared_regs = 8, | ||
| 1505 | .event_descs = nhmex_uncore_mbox_events, | ||
| 1506 | .ops = &nhmex_uncore_mbox_ops, | ||
| 1507 | .format_group = &nhmex_uncore_mbox_format_group, | ||
| 1508 | }; | ||
| 1509 | |||
| 1510 | void nhmex_rbox_alter_er(struct intel_uncore_box *box, struct perf_event *event) | ||
| 1511 | { | ||
| 1512 | struct hw_perf_event *hwc = &event->hw; | ||
| 1513 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; | ||
| 1514 | int port; | ||
| 1515 | |||
| 1516 | /* adjust the main event selector */ | ||
| 1517 | if (reg1->idx % 2) { | ||
| 1518 | reg1->idx--; | ||
| 1519 | hwc->config -= 1 << NHMEX_R_PMON_CTL_EV_SEL_SHIFT; | ||
| 1520 | } else { | ||
| 1521 | reg1->idx++; | ||
| 1522 | hwc->config += 1 << NHMEX_R_PMON_CTL_EV_SEL_SHIFT; | ||
| 1523 | } | ||
| 1524 | |||
| 1525 | /* adjust address or config of extra register */ | ||
| 1526 | port = reg1->idx / 6 + box->pmu->pmu_idx * 4; | ||
| 1527 | switch (reg1->idx % 6) { | ||
| 1528 | case 0: | ||
| 1529 | reg1->reg = NHMEX_R_MSR_PORTN_IPERF_CFG0(port); | ||
| 1530 | break; | ||
| 1531 | case 1: | ||
| 1532 | reg1->reg = NHMEX_R_MSR_PORTN_IPERF_CFG1(port); | ||
| 1533 | break; | ||
| 1534 | case 2: | ||
| 1535 | /* the 8~15 bits to the 0~7 bits */ | ||
| 1536 | reg1->config >>= 8; | ||
| 1537 | break; | ||
| 1538 | case 3: | ||
| 1539 | /* the 0~7 bits to the 8~15 bits */ | ||
| 1540 | reg1->config <<= 8; | ||
| 1541 | break; | ||
| 1542 | case 4: | ||
| 1543 | reg1->reg = NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(port); | ||
| 1544 | break; | ||
| 1545 | case 5: | ||
| 1546 | reg1->reg = NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(port); | ||
| 1547 | break; | ||
| 1548 | }; | ||
| 1549 | } | ||
| 1550 | |||
| 1551 | /* | ||
| 1552 | * Each rbox has 4 event set which monitor PQI port 0~3 or 4~7. | ||
| 1553 | * An event set consists of 6 events, the 3rd and 4th events in | ||
| 1554 | * an event set use the same extra register. So an event set uses | ||
| 1555 | * 5 extra registers. | ||
| 1556 | */ | ||
| 1557 | static struct event_constraint * | ||
| 1558 | nhmex_rbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event) | ||
| 1559 | { | ||
| 1560 | struct hw_perf_event *hwc = &event->hw; | ||
| 1561 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; | ||
| 1562 | struct hw_perf_event_extra *reg2 = &hwc->branch_reg; | ||
| 1563 | struct intel_uncore_extra_reg *er; | ||
| 1564 | unsigned long flags; | ||
| 1565 | int idx, er_idx; | ||
| 1566 | u64 config1; | ||
| 1567 | bool ok = false; | ||
| 1568 | |||
| 1569 | if (!uncore_box_is_fake(box) && reg1->alloc) | ||
| 1570 | return NULL; | ||
| 1571 | |||
| 1572 | idx = reg1->idx % 6; | ||
| 1573 | config1 = reg1->config; | ||
| 1574 | again: | ||
| 1575 | er_idx = idx; | ||
| 1576 | /* the 3rd and 4th events use the same extra register */ | ||
| 1577 | if (er_idx > 2) | ||
| 1578 | er_idx--; | ||
| 1579 | er_idx += (reg1->idx / 6) * 5; | ||
| 1580 | |||
| 1581 | er = &box->shared_regs[er_idx]; | ||
| 1582 | raw_spin_lock_irqsave(&er->lock, flags); | ||
| 1583 | if (idx < 2) { | ||
| 1584 | if (!atomic_read(&er->ref) || er->config == reg1->config) { | ||
| 1585 | atomic_inc(&er->ref); | ||
| 1586 | er->config = reg1->config; | ||
| 1587 | ok = true; | ||
| 1588 | } | ||
| 1589 | } else if (idx == 2 || idx == 3) { | ||
| 1590 | /* | ||
| 1591 | * these two events use different fields in a extra register, | ||
| 1592 | * the 0~7 bits and the 8~15 bits respectively. | ||
| 1593 | */ | ||
| 1594 | u64 mask = 0xff << ((idx - 2) * 8); | ||
| 1595 | if (!__BITS_VALUE(atomic_read(&er->ref), idx - 2, 8) || | ||
| 1596 | !((er->config ^ config1) & mask)) { | ||
| 1597 | atomic_add(1 << ((idx - 2) * 8), &er->ref); | ||
| 1598 | er->config &= ~mask; | ||
| 1599 | er->config |= config1 & mask; | ||
| 1600 | ok = true; | ||
| 1601 | } | ||
| 1602 | } else { | ||
| 1603 | if (!atomic_read(&er->ref) || | ||
| 1604 | (er->config == (hwc->config >> 32) && | ||
| 1605 | er->config1 == reg1->config && | ||
| 1606 | er->config2 == reg2->config)) { | ||
| 1607 | atomic_inc(&er->ref); | ||
| 1608 | er->config = (hwc->config >> 32); | ||
| 1609 | er->config1 = reg1->config; | ||
| 1610 | er->config2 = reg2->config; | ||
| 1611 | ok = true; | ||
| 1612 | } | ||
| 1613 | } | ||
| 1614 | raw_spin_unlock_irqrestore(&er->lock, flags); | ||
| 1615 | |||
| 1616 | if (!ok) { | ||
| 1617 | /* | ||
| 1618 | * The Rbox events are always in pairs. The paired | ||
| 1619 | * events are functional identical, but use different | ||
| 1620 | * extra registers. If we failed to take an extra | ||
| 1621 | * register, try the alternative. | ||
| 1622 | */ | ||
| 1623 | if (idx % 2) | ||
| 1624 | idx--; | ||
| 1625 | else | ||
| 1626 | idx++; | ||
| 1627 | if (idx != reg1->idx % 6) { | ||
| 1628 | if (idx == 2) | ||
| 1629 | config1 >>= 8; | ||
| 1630 | else if (idx == 3) | ||
| 1631 | config1 <<= 8; | ||
| 1632 | goto again; | ||
| 1633 | } | ||
| 1634 | } else { | ||
| 1635 | if (!uncore_box_is_fake(box)) { | ||
| 1636 | if (idx != reg1->idx % 6) | ||
| 1637 | nhmex_rbox_alter_er(box, event); | ||
| 1638 | reg1->alloc = 1; | ||
| 1639 | } | ||
| 1640 | return NULL; | ||
| 1641 | } | ||
| 1642 | return &constraint_empty; | ||
| 1643 | } | ||
| 1644 | |||
| 1645 | static void nhmex_rbox_put_constraint(struct intel_uncore_box *box, struct perf_event *event) | ||
| 1646 | { | ||
| 1647 | struct intel_uncore_extra_reg *er; | ||
| 1648 | struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; | ||
| 1649 | int idx, er_idx; | ||
| 1650 | |||
| 1651 | if (uncore_box_is_fake(box) || !reg1->alloc) | ||
| 1652 | return; | ||
| 1653 | |||
| 1654 | idx = reg1->idx % 6; | ||
| 1655 | er_idx = idx; | ||
| 1656 | if (er_idx > 2) | ||
| 1657 | er_idx--; | ||
| 1658 | er_idx += (reg1->idx / 6) * 5; | ||
| 1659 | |||
| 1660 | er = &box->shared_regs[er_idx]; | ||
| 1661 | if (idx == 2 || idx == 3) | ||
| 1662 | atomic_sub(1 << ((idx - 2) * 8), &er->ref); | ||
| 1663 | else | ||
| 1664 | atomic_dec(&er->ref); | ||
| 1665 | |||
| 1666 | reg1->alloc = 0; | ||
| 1667 | } | ||
| 1668 | |||
| 1669 | static int nhmex_rbox_hw_config(struct intel_uncore_box *box, struct perf_event *event) | ||
| 1670 | { | ||
| 1671 | struct hw_perf_event *hwc = &event->hw; | ||
| 1672 | struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; | ||
| 1673 | struct hw_perf_event_extra *reg2 = &event->hw.branch_reg; | ||
| 1674 | int port, idx; | ||
| 1675 | |||
| 1676 | idx = (event->hw.config & NHMEX_R_PMON_CTL_EV_SEL_MASK) >> | ||
| 1677 | NHMEX_R_PMON_CTL_EV_SEL_SHIFT; | ||
| 1678 | if (idx >= 0x18) | ||
| 1679 | return -EINVAL; | ||
| 1680 | |||
| 1681 | reg1->idx = idx; | ||
| 1682 | reg1->config = event->attr.config1; | ||
| 1683 | |||
| 1684 | port = idx / 6 + box->pmu->pmu_idx * 4; | ||
| 1685 | idx %= 6; | ||
| 1686 | switch (idx) { | ||
| 1687 | case 0: | ||
| 1688 | reg1->reg = NHMEX_R_MSR_PORTN_IPERF_CFG0(port); | ||
| 1689 | break; | ||
| 1690 | case 1: | ||
| 1691 | reg1->reg = NHMEX_R_MSR_PORTN_IPERF_CFG1(port); | ||
| 1692 | break; | ||
| 1693 | case 2: | ||
| 1694 | case 3: | ||
| 1695 | reg1->reg = NHMEX_R_MSR_PORTN_QLX_CFG(port); | ||
| 1696 | break; | ||
| 1697 | case 4: | ||
| 1698 | case 5: | ||
| 1699 | if (idx == 4) | ||
| 1700 | reg1->reg = NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(port); | ||
| 1701 | else | ||
| 1702 | reg1->reg = NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(port); | ||
| 1703 | reg2->config = event->attr.config2; | ||
| 1704 | hwc->config |= event->attr.config & (~0ULL << 32); | ||
| 1705 | break; | ||
| 1706 | }; | ||
| 1707 | return 0; | ||
| 1708 | } | ||
| 1709 | |||
| 1710 | static u64 nhmex_rbox_shared_reg_config(struct intel_uncore_box *box, int idx) | ||
| 1711 | { | ||
| 1712 | struct intel_uncore_extra_reg *er; | ||
| 1713 | unsigned long flags; | ||
| 1714 | u64 config; | ||
| 1715 | |||
| 1716 | er = &box->shared_regs[idx]; | ||
| 1717 | |||
| 1718 | raw_spin_lock_irqsave(&er->lock, flags); | ||
| 1719 | config = er->config; | ||
| 1720 | raw_spin_unlock_irqrestore(&er->lock, flags); | ||
| 1721 | |||
| 1722 | return config; | ||
| 1723 | } | ||
| 1724 | |||
| 1725 | static void nhmex_rbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event) | ||
| 1726 | { | ||
| 1727 | struct hw_perf_event *hwc = &event->hw; | ||
| 1728 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; | ||
| 1729 | struct hw_perf_event_extra *reg2 = &hwc->branch_reg; | ||
| 1730 | int idx, er_idx; | ||
| 1731 | |||
| 1732 | idx = reg1->idx % 6; | ||
| 1733 | er_idx = idx; | ||
| 1734 | if (er_idx > 2) | ||
| 1735 | er_idx--; | ||
| 1736 | er_idx += (reg1->idx / 6) * 5; | ||
| 1737 | |||
| 1738 | switch (idx) { | ||
| 1739 | case 0: | ||
| 1740 | case 1: | ||
| 1741 | wrmsrl(reg1->reg, reg1->config); | ||
| 1742 | break; | ||
| 1743 | case 2: | ||
| 1744 | case 3: | ||
| 1745 | wrmsrl(reg1->reg, nhmex_rbox_shared_reg_config(box, er_idx)); | ||
| 1746 | break; | ||
| 1747 | case 4: | ||
| 1748 | case 5: | ||
| 1749 | wrmsrl(reg1->reg, reg1->config); | ||
| 1750 | wrmsrl(reg1->reg + 1, hwc->config >> 32); | ||
| 1751 | wrmsrl(reg1->reg + 2, reg2->config); | ||
| 1752 | break; | ||
| 1753 | }; | ||
| 1754 | |||
| 1755 | wrmsrl(hwc->config_base, NHMEX_PMON_CTL_EN_BIT0 | | ||
| 1756 | (hwc->config & NHMEX_R_PMON_CTL_EV_SEL_MASK)); | ||
| 1757 | } | ||
| 1758 | |||
| 1759 | DEFINE_UNCORE_FORMAT_ATTR(xbr_match, xbr_match, "config:32-63"); | ||
| 1760 | DEFINE_UNCORE_FORMAT_ATTR(xbr_mm_cfg, xbr_mm_cfg, "config1:0-63"); | ||
| 1761 | DEFINE_UNCORE_FORMAT_ATTR(xbr_mask, xbr_mask, "config2:0-63"); | ||
| 1762 | DEFINE_UNCORE_FORMAT_ATTR(qlx_cfg, qlx_cfg, "config1:0-15"); | ||
| 1763 | DEFINE_UNCORE_FORMAT_ATTR(iperf_cfg, iperf_cfg, "config1:0-31"); | ||
| 1764 | |||
| 1765 | static struct attribute *nhmex_uncore_rbox_formats_attr[] = { | ||
| 1766 | &format_attr_event5.attr, | ||
| 1767 | &format_attr_xbr_mm_cfg.attr, | ||
| 1768 | &format_attr_xbr_match.attr, | ||
| 1769 | &format_attr_xbr_mask.attr, | ||
| 1770 | &format_attr_qlx_cfg.attr, | ||
| 1771 | &format_attr_iperf_cfg.attr, | ||
| 1772 | NULL, | ||
| 1773 | }; | ||
| 1774 | |||
| 1775 | static struct attribute_group nhmex_uncore_rbox_format_group = { | ||
| 1776 | .name = "format", | ||
| 1777 | .attrs = nhmex_uncore_rbox_formats_attr, | ||
| 1778 | }; | ||
| 1779 | |||
| 1780 | static struct uncore_event_desc nhmex_uncore_rbox_events[] = { | ||
| 1781 | INTEL_UNCORE_EVENT_DESC(qpi0_flit_send, "event=0x0,iperf_cfg=0x80000000"), | ||
| 1782 | INTEL_UNCORE_EVENT_DESC(qpi1_filt_send, "event=0x6,iperf_cfg=0x80000000"), | ||
| 1783 | INTEL_UNCORE_EVENT_DESC(qpi0_idle_filt, "event=0x0,iperf_cfg=0x40000000"), | ||
| 1784 | INTEL_UNCORE_EVENT_DESC(qpi1_idle_filt, "event=0x6,iperf_cfg=0x40000000"), | ||
| 1785 | INTEL_UNCORE_EVENT_DESC(qpi0_date_response, "event=0x0,iperf_cfg=0xc4"), | ||
| 1786 | INTEL_UNCORE_EVENT_DESC(qpi1_date_response, "event=0x6,iperf_cfg=0xc4"), | ||
| 1787 | { /* end: all zeroes */ }, | ||
| 1788 | }; | ||
| 1789 | |||
| 1790 | static struct intel_uncore_ops nhmex_uncore_rbox_ops = { | ||
| 1791 | NHMEX_UNCORE_OPS_COMMON_INIT(), | ||
| 1792 | .enable_event = nhmex_rbox_msr_enable_event, | ||
| 1793 | .hw_config = nhmex_rbox_hw_config, | ||
| 1794 | .get_constraint = nhmex_rbox_get_constraint, | ||
| 1795 | .put_constraint = nhmex_rbox_put_constraint, | ||
| 1796 | }; | ||
| 1797 | |||
| 1798 | static struct intel_uncore_type nhmex_uncore_rbox = { | ||
| 1799 | .name = "rbox", | ||
| 1800 | .num_counters = 8, | ||
| 1801 | .num_boxes = 2, | ||
| 1802 | .perf_ctr_bits = 48, | ||
| 1803 | .event_ctl = NHMEX_R_MSR_PMON_CTL0, | ||
| 1804 | .perf_ctr = NHMEX_R_MSR_PMON_CNT0, | ||
| 1805 | .event_mask = NHMEX_R_PMON_RAW_EVENT_MASK, | ||
| 1806 | .box_ctl = NHMEX_R_MSR_GLOBAL_CTL, | ||
| 1807 | .msr_offset = NHMEX_R_MSR_OFFSET, | ||
| 1808 | .pair_ctr_ctl = 1, | ||
| 1809 | .num_shared_regs = 20, | ||
| 1810 | .event_descs = nhmex_uncore_rbox_events, | ||
| 1811 | .ops = &nhmex_uncore_rbox_ops, | ||
| 1812 | .format_group = &nhmex_uncore_rbox_format_group | ||
| 1813 | }; | ||
| 1814 | |||
| 1815 | static struct intel_uncore_type *nhmex_msr_uncores[] = { | ||
| 1816 | &nhmex_uncore_ubox, | ||
| 1817 | &nhmex_uncore_cbox, | ||
| 1818 | &nhmex_uncore_bbox, | ||
| 1819 | &nhmex_uncore_sbox, | ||
| 1820 | &nhmex_uncore_mbox, | ||
| 1821 | &nhmex_uncore_rbox, | ||
| 1822 | &nhmex_uncore_wbox, | ||
| 1823 | NULL, | ||
| 1824 | }; | ||
| 1825 | /* end of Nehalem-EX uncore support */ | ||
| 1826 | |||
| 1827 | static void uncore_assign_hw_event(struct intel_uncore_box *box, struct perf_event *event, int idx) | ||
| 774 | { | 1828 | { |
| 775 | struct hw_perf_event *hwc = &event->hw; | 1829 | struct hw_perf_event *hwc = &event->hw; |
| 776 | 1830 | ||
| @@ -787,8 +1841,7 @@ static void uncore_assign_hw_event(struct intel_uncore_box *box, | |||
| 787 | hwc->event_base = uncore_perf_ctr(box, hwc->idx); | 1841 | hwc->event_base = uncore_perf_ctr(box, hwc->idx); |
| 788 | } | 1842 | } |
| 789 | 1843 | ||
| 790 | static void uncore_perf_event_update(struct intel_uncore_box *box, | 1844 | static void uncore_perf_event_update(struct intel_uncore_box *box, struct perf_event *event) |
| 791 | struct perf_event *event) | ||
| 792 | { | 1845 | { |
| 793 | u64 prev_count, new_count, delta; | 1846 | u64 prev_count, new_count, delta; |
| 794 | int shift; | 1847 | int shift; |
| @@ -858,14 +1911,12 @@ static void uncore_pmu_init_hrtimer(struct intel_uncore_box *box) | |||
| 858 | box->hrtimer.function = uncore_pmu_hrtimer; | 1911 | box->hrtimer.function = uncore_pmu_hrtimer; |
| 859 | } | 1912 | } |
| 860 | 1913 | ||
| 861 | struct intel_uncore_box *uncore_alloc_box(struct intel_uncore_type *type, | 1914 | struct intel_uncore_box *uncore_alloc_box(struct intel_uncore_type *type, int cpu) |
| 862 | int cpu) | ||
| 863 | { | 1915 | { |
| 864 | struct intel_uncore_box *box; | 1916 | struct intel_uncore_box *box; |
| 865 | int i, size; | 1917 | int i, size; |
| 866 | 1918 | ||
| 867 | size = sizeof(*box) + type->num_shared_regs * | 1919 | size = sizeof(*box) + type->num_shared_regs * sizeof(struct intel_uncore_extra_reg); |
| 868 | sizeof(struct intel_uncore_extra_reg); | ||
| 869 | 1920 | ||
| 870 | box = kmalloc_node(size, GFP_KERNEL | __GFP_ZERO, cpu_to_node(cpu)); | 1921 | box = kmalloc_node(size, GFP_KERNEL | __GFP_ZERO, cpu_to_node(cpu)); |
| 871 | if (!box) | 1922 | if (!box) |
| @@ -915,12 +1966,11 @@ static struct intel_uncore_box *uncore_event_to_box(struct perf_event *event) | |||
| 915 | * perf core schedules event on the basis of cpu, uncore events are | 1966 | * perf core schedules event on the basis of cpu, uncore events are |
| 916 | * collected by one of the cpus inside a physical package. | 1967 | * collected by one of the cpus inside a physical package. |
| 917 | */ | 1968 | */ |
| 918 | return uncore_pmu_to_box(uncore_event_to_pmu(event), | 1969 | return uncore_pmu_to_box(uncore_event_to_pmu(event), smp_processor_id()); |
| 919 | smp_processor_id()); | ||
| 920 | } | 1970 | } |
| 921 | 1971 | ||
| 922 | static int uncore_collect_events(struct intel_uncore_box *box, | 1972 | static int |
| 923 | struct perf_event *leader, bool dogrp) | 1973 | uncore_collect_events(struct intel_uncore_box *box, struct perf_event *leader, bool dogrp) |
| 924 | { | 1974 | { |
| 925 | struct perf_event *event; | 1975 | struct perf_event *event; |
| 926 | int n, max_count; | 1976 | int n, max_count; |
| @@ -952,8 +2002,7 @@ static int uncore_collect_events(struct intel_uncore_box *box, | |||
| 952 | } | 2002 | } |
| 953 | 2003 | ||
| 954 | static struct event_constraint * | 2004 | static struct event_constraint * |
| 955 | uncore_get_event_constraint(struct intel_uncore_box *box, | 2005 | uncore_get_event_constraint(struct intel_uncore_box *box, struct perf_event *event) |
| 956 | struct perf_event *event) | ||
| 957 | { | 2006 | { |
| 958 | struct intel_uncore_type *type = box->pmu->type; | 2007 | struct intel_uncore_type *type = box->pmu->type; |
| 959 | struct event_constraint *c; | 2008 | struct event_constraint *c; |
| @@ -977,15 +2026,13 @@ uncore_get_event_constraint(struct intel_uncore_box *box, | |||
| 977 | return &type->unconstrainted; | 2026 | return &type->unconstrainted; |
| 978 | } | 2027 | } |
| 979 | 2028 | ||
| 980 | static void uncore_put_event_constraint(struct intel_uncore_box *box, | 2029 | static void uncore_put_event_constraint(struct intel_uncore_box *box, struct perf_event *event) |
| 981 | struct perf_event *event) | ||
| 982 | { | 2030 | { |
| 983 | if (box->pmu->type->ops->put_constraint) | 2031 | if (box->pmu->type->ops->put_constraint) |
| 984 | box->pmu->type->ops->put_constraint(box, event); | 2032 | box->pmu->type->ops->put_constraint(box, event); |
| 985 | } | 2033 | } |
| 986 | 2034 | ||
| 987 | static int uncore_assign_events(struct intel_uncore_box *box, | 2035 | static int uncore_assign_events(struct intel_uncore_box *box, int assign[], int n) |
| 988 | int assign[], int n) | ||
| 989 | { | 2036 | { |
| 990 | unsigned long used_mask[BITS_TO_LONGS(UNCORE_PMC_IDX_MAX)]; | 2037 | unsigned long used_mask[BITS_TO_LONGS(UNCORE_PMC_IDX_MAX)]; |
| 991 | struct event_constraint *c, *constraints[UNCORE_PMC_IDX_MAX]; | 2038 | struct event_constraint *c, *constraints[UNCORE_PMC_IDX_MAX]; |
| @@ -1407,8 +2454,7 @@ static bool pcidrv_registered; | |||
| 1407 | /* | 2454 | /* |
| 1408 | * add a pci uncore device | 2455 | * add a pci uncore device |
| 1409 | */ | 2456 | */ |
| 1410 | static int __devinit uncore_pci_add(struct intel_uncore_type *type, | 2457 | static int __devinit uncore_pci_add(struct intel_uncore_type *type, struct pci_dev *pdev) |
| 1411 | struct pci_dev *pdev) | ||
| 1412 | { | 2458 | { |
| 1413 | struct intel_uncore_pmu *pmu; | 2459 | struct intel_uncore_pmu *pmu; |
| 1414 | struct intel_uncore_box *box; | 2460 | struct intel_uncore_box *box; |
| @@ -1485,6 +2531,7 @@ static int __devinit uncore_pci_probe(struct pci_dev *pdev, | |||
| 1485 | struct intel_uncore_type *type; | 2531 | struct intel_uncore_type *type; |
| 1486 | 2532 | ||
| 1487 | type = (struct intel_uncore_type *)id->driver_data; | 2533 | type = (struct intel_uncore_type *)id->driver_data; |
| 2534 | |||
| 1488 | return uncore_pci_add(type, pdev); | 2535 | return uncore_pci_add(type, pdev); |
| 1489 | } | 2536 | } |
| 1490 | 2537 | ||
| @@ -1612,8 +2659,8 @@ static int __cpuinit uncore_cpu_prepare(int cpu, int phys_id) | |||
| 1612 | return 0; | 2659 | return 0; |
| 1613 | } | 2660 | } |
| 1614 | 2661 | ||
| 1615 | static void __cpuinit uncore_change_context(struct intel_uncore_type **uncores, | 2662 | static void __cpuinit |
| 1616 | int old_cpu, int new_cpu) | 2663 | uncore_change_context(struct intel_uncore_type **uncores, int old_cpu, int new_cpu) |
| 1617 | { | 2664 | { |
| 1618 | struct intel_uncore_type *type; | 2665 | struct intel_uncore_type *type; |
| 1619 | struct intel_uncore_pmu *pmu; | 2666 | struct intel_uncore_pmu *pmu; |
| @@ -1694,8 +2741,8 @@ static void __cpuinit uncore_event_init_cpu(int cpu) | |||
| 1694 | uncore_change_context(pci_uncores, -1, cpu); | 2741 | uncore_change_context(pci_uncores, -1, cpu); |
| 1695 | } | 2742 | } |
| 1696 | 2743 | ||
| 1697 | static int __cpuinit uncore_cpu_notifier(struct notifier_block *self, | 2744 | static int |
| 1698 | unsigned long action, void *hcpu) | 2745 | __cpuinit uncore_cpu_notifier(struct notifier_block *self, unsigned long action, void *hcpu) |
| 1699 | { | 2746 | { |
| 1700 | unsigned int cpu = (long)hcpu; | 2747 | unsigned int cpu = (long)hcpu; |
| 1701 | 2748 | ||
| @@ -1732,12 +2779,12 @@ static int __cpuinit uncore_cpu_notifier(struct notifier_block *self, | |||
| 1732 | } | 2779 | } |
| 1733 | 2780 | ||
| 1734 | static struct notifier_block uncore_cpu_nb __cpuinitdata = { | 2781 | static struct notifier_block uncore_cpu_nb __cpuinitdata = { |
| 1735 | .notifier_call = uncore_cpu_notifier, | 2782 | .notifier_call = uncore_cpu_notifier, |
| 1736 | /* | 2783 | /* |
| 1737 | * to migrate uncore events, our notifier should be executed | 2784 | * to migrate uncore events, our notifier should be executed |
| 1738 | * before perf core's notifier. | 2785 | * before perf core's notifier. |
| 1739 | */ | 2786 | */ |
| 1740 | .priority = CPU_PRI_PERF + 1, | 2787 | .priority = CPU_PRI_PERF + 1, |
| 1741 | }; | 2788 | }; |
| 1742 | 2789 | ||
| 1743 | static void __init uncore_cpu_setup(void *dummy) | 2790 | static void __init uncore_cpu_setup(void *dummy) |
| @@ -1767,6 +2814,9 @@ static int __init uncore_cpu_init(void) | |||
| 1767 | snbep_uncore_cbox.num_boxes = max_cores; | 2814 | snbep_uncore_cbox.num_boxes = max_cores; |
| 1768 | msr_uncores = snbep_msr_uncores; | 2815 | msr_uncores = snbep_msr_uncores; |
| 1769 | break; | 2816 | break; |
| 2817 | case 46: | ||
| 2818 | msr_uncores = nhmex_msr_uncores; | ||
| 2819 | break; | ||
| 1770 | default: | 2820 | default: |
| 1771 | return 0; | 2821 | return 0; |
| 1772 | } | 2822 | } |
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.h b/arch/x86/kernel/cpu/perf_event_intel_uncore.h index b13e9ea81def..f3851892e077 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.h +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.h | |||
| @@ -5,8 +5,6 @@ | |||
| 5 | #include "perf_event.h" | 5 | #include "perf_event.h" |
| 6 | 6 | ||
| 7 | #define UNCORE_PMU_NAME_LEN 32 | 7 | #define UNCORE_PMU_NAME_LEN 32 |
| 8 | #define UNCORE_BOX_HASH_SIZE 8 | ||
| 9 | |||
| 10 | #define UNCORE_PMU_HRTIMER_INTERVAL (60 * NSEC_PER_SEC) | 8 | #define UNCORE_PMU_HRTIMER_INTERVAL (60 * NSEC_PER_SEC) |
| 11 | 9 | ||
| 12 | #define UNCORE_FIXED_EVENT 0xff | 10 | #define UNCORE_FIXED_EVENT 0xff |
| @@ -115,6 +113,10 @@ | |||
| 115 | SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT | \ | 113 | SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT | \ |
| 116 | SNBEP_PCU_MSR_PMON_CTL_OCC_EDGE_DET) | 114 | SNBEP_PCU_MSR_PMON_CTL_OCC_EDGE_DET) |
| 117 | 115 | ||
| 116 | #define SNBEP_QPI_PCI_PMON_RAW_EVENT_MASK \ | ||
| 117 | (SNBEP_PMON_RAW_EVENT_MASK | \ | ||
| 118 | SNBEP_PMON_CTL_EV_SEL_EXT) | ||
| 119 | |||
| 118 | /* SNB-EP pci control register */ | 120 | /* SNB-EP pci control register */ |
| 119 | #define SNBEP_PCI_PMON_BOX_CTL 0xf4 | 121 | #define SNBEP_PCI_PMON_BOX_CTL 0xf4 |
| 120 | #define SNBEP_PCI_PMON_CTL0 0xd8 | 122 | #define SNBEP_PCI_PMON_CTL0 0xd8 |
| @@ -158,6 +160,193 @@ | |||
| 158 | #define SNBEP_PCU_MSR_CORE_C3_CTR 0x3fc | 160 | #define SNBEP_PCU_MSR_CORE_C3_CTR 0x3fc |
| 159 | #define SNBEP_PCU_MSR_CORE_C6_CTR 0x3fd | 161 | #define SNBEP_PCU_MSR_CORE_C6_CTR 0x3fd |
| 160 | 162 | ||
| 163 | /* NHM-EX event control */ | ||
| 164 | #define NHMEX_PMON_CTL_EV_SEL_MASK 0x000000ff | ||
| 165 | #define NHMEX_PMON_CTL_UMASK_MASK 0x0000ff00 | ||
| 166 | #define NHMEX_PMON_CTL_EN_BIT0 (1 << 0) | ||
| 167 | #define NHMEX_PMON_CTL_EDGE_DET (1 << 18) | ||
| 168 | #define NHMEX_PMON_CTL_PMI_EN (1 << 20) | ||
| 169 | #define NHMEX_PMON_CTL_EN_BIT22 (1 << 22) | ||
| 170 | #define NHMEX_PMON_CTL_INVERT (1 << 23) | ||
| 171 | #define NHMEX_PMON_CTL_TRESH_MASK 0xff000000 | ||
| 172 | #define NHMEX_PMON_RAW_EVENT_MASK (NHMEX_PMON_CTL_EV_SEL_MASK | \ | ||
| 173 | NHMEX_PMON_CTL_UMASK_MASK | \ | ||
| 174 | NHMEX_PMON_CTL_EDGE_DET | \ | ||
| 175 | NHMEX_PMON_CTL_INVERT | \ | ||
| 176 | NHMEX_PMON_CTL_TRESH_MASK) | ||
| 177 | |||
| 178 | /* NHM-EX Ubox */ | ||
| 179 | #define NHMEX_U_MSR_PMON_GLOBAL_CTL 0xc00 | ||
| 180 | #define NHMEX_U_MSR_PMON_CTR 0xc11 | ||
| 181 | #define NHMEX_U_MSR_PMON_EV_SEL 0xc10 | ||
| 182 | |||
| 183 | #define NHMEX_U_PMON_GLOBAL_EN (1 << 0) | ||
| 184 | #define NHMEX_U_PMON_GLOBAL_PMI_CORE_SEL 0x0000001e | ||
| 185 | #define NHMEX_U_PMON_GLOBAL_EN_ALL (1 << 28) | ||
| 186 | #define NHMEX_U_PMON_GLOBAL_RST_ALL (1 << 29) | ||
| 187 | #define NHMEX_U_PMON_GLOBAL_FRZ_ALL (1 << 31) | ||
| 188 | |||
| 189 | #define NHMEX_U_PMON_RAW_EVENT_MASK \ | ||
| 190 | (NHMEX_PMON_CTL_EV_SEL_MASK | \ | ||
| 191 | NHMEX_PMON_CTL_EDGE_DET) | ||
| 192 | |||
| 193 | /* NHM-EX Cbox */ | ||
| 194 | #define NHMEX_C0_MSR_PMON_GLOBAL_CTL 0xd00 | ||
| 195 | #define NHMEX_C0_MSR_PMON_CTR0 0xd11 | ||
| 196 | #define NHMEX_C0_MSR_PMON_EV_SEL0 0xd10 | ||
| 197 | #define NHMEX_C_MSR_OFFSET 0x20 | ||
| 198 | |||
| 199 | /* NHM-EX Bbox */ | ||
| 200 | #define NHMEX_B0_MSR_PMON_GLOBAL_CTL 0xc20 | ||
| 201 | #define NHMEX_B0_MSR_PMON_CTR0 0xc31 | ||
| 202 | #define NHMEX_B0_MSR_PMON_CTL0 0xc30 | ||
| 203 | #define NHMEX_B_MSR_OFFSET 0x40 | ||
| 204 | #define NHMEX_B0_MSR_MATCH 0xe45 | ||
| 205 | #define NHMEX_B0_MSR_MASK 0xe46 | ||
| 206 | #define NHMEX_B1_MSR_MATCH 0xe4d | ||
| 207 | #define NHMEX_B1_MSR_MASK 0xe4e | ||
| 208 | |||
| 209 | #define NHMEX_B_PMON_CTL_EN (1 << 0) | ||
| 210 | #define NHMEX_B_PMON_CTL_EV_SEL_SHIFT 1 | ||
| 211 | #define NHMEX_B_PMON_CTL_EV_SEL_MASK \ | ||
| 212 | (0x1f << NHMEX_B_PMON_CTL_EV_SEL_SHIFT) | ||
| 213 | #define NHMEX_B_PMON_CTR_SHIFT 6 | ||
| 214 | #define NHMEX_B_PMON_CTR_MASK \ | ||
| 215 | (0x3 << NHMEX_B_PMON_CTR_SHIFT) | ||
| 216 | #define NHMEX_B_PMON_RAW_EVENT_MASK \ | ||
| 217 | (NHMEX_B_PMON_CTL_EV_SEL_MASK | \ | ||
| 218 | NHMEX_B_PMON_CTR_MASK) | ||
| 219 | |||
| 220 | /* NHM-EX Sbox */ | ||
| 221 | #define NHMEX_S0_MSR_PMON_GLOBAL_CTL 0xc40 | ||
| 222 | #define NHMEX_S0_MSR_PMON_CTR0 0xc51 | ||
| 223 | #define NHMEX_S0_MSR_PMON_CTL0 0xc50 | ||
| 224 | #define NHMEX_S_MSR_OFFSET 0x80 | ||
| 225 | #define NHMEX_S0_MSR_MM_CFG 0xe48 | ||
| 226 | #define NHMEX_S0_MSR_MATCH 0xe49 | ||
| 227 | #define NHMEX_S0_MSR_MASK 0xe4a | ||
| 228 | #define NHMEX_S1_MSR_MM_CFG 0xe58 | ||
| 229 | #define NHMEX_S1_MSR_MATCH 0xe59 | ||
| 230 | #define NHMEX_S1_MSR_MASK 0xe5a | ||
| 231 | |||
| 232 | #define NHMEX_S_PMON_MM_CFG_EN (0x1ULL << 63) | ||
| 233 | |||
| 234 | /* NHM-EX Mbox */ | ||
| 235 | #define NHMEX_M0_MSR_GLOBAL_CTL 0xca0 | ||
| 236 | #define NHMEX_M0_MSR_PMU_DSP 0xca5 | ||
| 237 | #define NHMEX_M0_MSR_PMU_ISS 0xca6 | ||
| 238 | #define NHMEX_M0_MSR_PMU_MAP 0xca7 | ||
| 239 | #define NHMEX_M0_MSR_PMU_MSC_THR 0xca8 | ||
| 240 | #define NHMEX_M0_MSR_PMU_PGT 0xca9 | ||
| 241 | #define NHMEX_M0_MSR_PMU_PLD 0xcaa | ||
| 242 | #define NHMEX_M0_MSR_PMU_ZDP_CTL_FVC 0xcab | ||
| 243 | #define NHMEX_M0_MSR_PMU_CTL0 0xcb0 | ||
| 244 | #define NHMEX_M0_MSR_PMU_CNT0 0xcb1 | ||
| 245 | #define NHMEX_M_MSR_OFFSET 0x40 | ||
| 246 | #define NHMEX_M0_MSR_PMU_MM_CFG 0xe54 | ||
| 247 | #define NHMEX_M1_MSR_PMU_MM_CFG 0xe5c | ||
| 248 | |||
| 249 | #define NHMEX_M_PMON_MM_CFG_EN (1ULL << 63) | ||
| 250 | #define NHMEX_M_PMON_ADDR_MATCH_MASK 0x3ffffffffULL | ||
| 251 | #define NHMEX_M_PMON_ADDR_MASK_MASK 0x7ffffffULL | ||
| 252 | #define NHMEX_M_PMON_ADDR_MASK_SHIFT 34 | ||
| 253 | |||
| 254 | #define NHMEX_M_PMON_CTL_EN (1 << 0) | ||
| 255 | #define NHMEX_M_PMON_CTL_PMI_EN (1 << 1) | ||
| 256 | #define NHMEX_M_PMON_CTL_COUNT_MODE_SHIFT 2 | ||
| 257 | #define NHMEX_M_PMON_CTL_COUNT_MODE_MASK \ | ||
| 258 | (0x3 << NHMEX_M_PMON_CTL_COUNT_MODE_SHIFT) | ||
| 259 | #define NHMEX_M_PMON_CTL_STORAGE_MODE_SHIFT 4 | ||
| 260 | #define NHMEX_M_PMON_CTL_STORAGE_MODE_MASK \ | ||
| 261 | (0x3 << NHMEX_M_PMON_CTL_STORAGE_MODE_SHIFT) | ||
| 262 | #define NHMEX_M_PMON_CTL_WRAP_MODE (1 << 6) | ||
| 263 | #define NHMEX_M_PMON_CTL_FLAG_MODE (1 << 7) | ||
| 264 | #define NHMEX_M_PMON_CTL_INC_SEL_SHIFT 9 | ||
| 265 | #define NHMEX_M_PMON_CTL_INC_SEL_MASK \ | ||
| 266 | (0x1f << NHMEX_M_PMON_CTL_INC_SEL_SHIFT) | ||
| 267 | #define NHMEX_M_PMON_CTL_SET_FLAG_SEL_SHIFT 19 | ||
| 268 | #define NHMEX_M_PMON_CTL_SET_FLAG_SEL_MASK \ | ||
| 269 | (0x7 << NHMEX_M_PMON_CTL_SET_FLAG_SEL_SHIFT) | ||
| 270 | #define NHMEX_M_PMON_RAW_EVENT_MASK \ | ||
| 271 | (NHMEX_M_PMON_CTL_COUNT_MODE_MASK | \ | ||
| 272 | NHMEX_M_PMON_CTL_STORAGE_MODE_MASK | \ | ||
| 273 | NHMEX_M_PMON_CTL_WRAP_MODE | \ | ||
| 274 | NHMEX_M_PMON_CTL_FLAG_MODE | \ | ||
| 275 | NHMEX_M_PMON_CTL_INC_SEL_MASK | \ | ||
| 276 | NHMEX_M_PMON_CTL_SET_FLAG_SEL_MASK) | ||
| 277 | |||
| 278 | |||
| 279 | #define NHMEX_M_PMON_ZDP_CTL_FVC_FVID_MASK 0x1f | ||
| 280 | #define NHMEX_M_PMON_ZDP_CTL_FVC_BCMD_MASK (0x7 << 5) | ||
| 281 | #define NHMEX_M_PMON_ZDP_CTL_FVC_RSP_MASK (0x7 << 8) | ||
| 282 | #define NHMEX_M_PMON_ZDP_CTL_FVC_PBOX_INIT_ERR (1 << 23) | ||
| 283 | #define NHMEX_M_PMON_ZDP_CTL_FVC_MASK \ | ||
| 284 | (NHMEX_M_PMON_ZDP_CTL_FVC_FVID_MASK | \ | ||
| 285 | NHMEX_M_PMON_ZDP_CTL_FVC_BCMD_MASK | \ | ||
| 286 | NHMEX_M_PMON_ZDP_CTL_FVC_RSP_MASK | \ | ||
| 287 | NHMEX_M_PMON_ZDP_CTL_FVC_PBOX_INIT_ERR) | ||
| 288 | #define NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(n) (0x7 << (11 + 3 * (n))) | ||
| 289 | |||
| 290 | /* | ||
| 291 | * use the 9~13 bits to select event If the 7th bit is not set, | ||
| 292 | * otherwise use the 19~21 bits to select event. | ||
| 293 | */ | ||
| 294 | #define MBOX_INC_SEL(x) ((x) << NHMEX_M_PMON_CTL_INC_SEL_SHIFT) | ||
| 295 | #define MBOX_SET_FLAG_SEL(x) (((x) << NHMEX_M_PMON_CTL_SET_FLAG_SEL_SHIFT) | \ | ||
| 296 | NHMEX_M_PMON_CTL_FLAG_MODE) | ||
| 297 | #define MBOX_INC_SEL_MASK (NHMEX_M_PMON_CTL_INC_SEL_MASK | \ | ||
| 298 | NHMEX_M_PMON_CTL_FLAG_MODE) | ||
| 299 | #define MBOX_SET_FLAG_SEL_MASK (NHMEX_M_PMON_CTL_SET_FLAG_SEL_MASK | \ | ||
| 300 | NHMEX_M_PMON_CTL_FLAG_MODE) | ||
| 301 | #define MBOX_INC_SEL_EXTAR_REG(c, r) \ | ||
| 302 | EVENT_EXTRA_REG(MBOX_INC_SEL(c), NHMEX_M0_MSR_PMU_##r, \ | ||
| 303 | MBOX_INC_SEL_MASK, (u64)-1, NHMEX_M_##r) | ||
| 304 | #define MBOX_SET_FLAG_SEL_EXTRA_REG(c, r) \ | ||
| 305 | EVENT_EXTRA_REG(MBOX_SET_FLAG_SEL(c), NHMEX_M0_MSR_PMU_##r, \ | ||
| 306 | MBOX_SET_FLAG_SEL_MASK, \ | ||
| 307 | (u64)-1, NHMEX_M_##r) | ||
| 308 | |||
| 309 | /* NHM-EX Rbox */ | ||
| 310 | #define NHMEX_R_MSR_GLOBAL_CTL 0xe00 | ||
| 311 | #define NHMEX_R_MSR_PMON_CTL0 0xe10 | ||
| 312 | #define NHMEX_R_MSR_PMON_CNT0 0xe11 | ||
| 313 | #define NHMEX_R_MSR_OFFSET 0x20 | ||
| 314 | |||
| 315 | #define NHMEX_R_MSR_PORTN_QLX_CFG(n) \ | ||
| 316 | ((n) < 4 ? (0xe0c + (n)) : (0xe2c + (n) - 4)) | ||
| 317 | #define NHMEX_R_MSR_PORTN_IPERF_CFG0(n) (0xe04 + (n)) | ||
| 318 | #define NHMEX_R_MSR_PORTN_IPERF_CFG1(n) (0xe24 + (n)) | ||
| 319 | #define NHMEX_R_MSR_PORTN_XBR_OFFSET(n) \ | ||
| 320 | (((n) < 4 ? 0 : 0x10) + (n) * 4) | ||
| 321 | #define NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(n) \ | ||
| 322 | (0xe60 + NHMEX_R_MSR_PORTN_XBR_OFFSET(n)) | ||
| 323 | #define NHMEX_R_MSR_PORTN_XBR_SET1_MATCH(n) \ | ||
| 324 | (NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(n) + 1) | ||
| 325 | #define NHMEX_R_MSR_PORTN_XBR_SET1_MASK(n) \ | ||
| 326 | (NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(n) + 2) | ||
| 327 | #define NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(n) \ | ||
| 328 | (0xe70 + NHMEX_R_MSR_PORTN_XBR_OFFSET(n)) | ||
| 329 | #define NHMEX_R_MSR_PORTN_XBR_SET2_MATCH(n) \ | ||
| 330 | (NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(n) + 1) | ||
| 331 | #define NHMEX_R_MSR_PORTN_XBR_SET2_MASK(n) \ | ||
| 332 | (NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(n) + 2) | ||
| 333 | |||
| 334 | #define NHMEX_R_PMON_CTL_EN (1 << 0) | ||
| 335 | #define NHMEX_R_PMON_CTL_EV_SEL_SHIFT 1 | ||
| 336 | #define NHMEX_R_PMON_CTL_EV_SEL_MASK \ | ||
| 337 | (0x1f << NHMEX_R_PMON_CTL_EV_SEL_SHIFT) | ||
| 338 | #define NHMEX_R_PMON_CTL_PMI_EN (1 << 6) | ||
| 339 | #define NHMEX_R_PMON_RAW_EVENT_MASK NHMEX_R_PMON_CTL_EV_SEL_MASK | ||
| 340 | |||
| 341 | /* NHM-EX Wbox */ | ||
| 342 | #define NHMEX_W_MSR_GLOBAL_CTL 0xc80 | ||
| 343 | #define NHMEX_W_MSR_PMON_CNT0 0xc90 | ||
| 344 | #define NHMEX_W_MSR_PMON_EVT_SEL0 0xc91 | ||
| 345 | #define NHMEX_W_MSR_PMON_FIXED_CTR 0x394 | ||
| 346 | #define NHMEX_W_MSR_PMON_FIXED_CTL 0x395 | ||
| 347 | |||
| 348 | #define NHMEX_W_PMON_GLOBAL_FIXED_EN (1ULL << 31) | ||
| 349 | |||
| 161 | struct intel_uncore_ops; | 350 | struct intel_uncore_ops; |
| 162 | struct intel_uncore_pmu; | 351 | struct intel_uncore_pmu; |
| 163 | struct intel_uncore_box; | 352 | struct intel_uncore_box; |
| @@ -178,6 +367,7 @@ struct intel_uncore_type { | |||
| 178 | unsigned msr_offset; | 367 | unsigned msr_offset; |
| 179 | unsigned num_shared_regs:8; | 368 | unsigned num_shared_regs:8; |
| 180 | unsigned single_fixed:1; | 369 | unsigned single_fixed:1; |
| 370 | unsigned pair_ctr_ctl:1; | ||
| 181 | struct event_constraint unconstrainted; | 371 | struct event_constraint unconstrainted; |
| 182 | struct event_constraint *constraints; | 372 | struct event_constraint *constraints; |
| 183 | struct intel_uncore_pmu *pmus; | 373 | struct intel_uncore_pmu *pmus; |
| @@ -213,7 +403,7 @@ struct intel_uncore_pmu { | |||
| 213 | 403 | ||
| 214 | struct intel_uncore_extra_reg { | 404 | struct intel_uncore_extra_reg { |
| 215 | raw_spinlock_t lock; | 405 | raw_spinlock_t lock; |
| 216 | u64 config1; | 406 | u64 config, config1, config2; |
| 217 | atomic_t ref; | 407 | atomic_t ref; |
| 218 | }; | 408 | }; |
| 219 | 409 | ||
| @@ -323,14 +513,16 @@ unsigned uncore_msr_fixed_ctr(struct intel_uncore_box *box) | |||
| 323 | static inline | 513 | static inline |
| 324 | unsigned uncore_msr_event_ctl(struct intel_uncore_box *box, int idx) | 514 | unsigned uncore_msr_event_ctl(struct intel_uncore_box *box, int idx) |
| 325 | { | 515 | { |
| 326 | return idx + box->pmu->type->event_ctl + | 516 | return box->pmu->type->event_ctl + |
| 517 | (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) + | ||
| 327 | box->pmu->type->msr_offset * box->pmu->pmu_idx; | 518 | box->pmu->type->msr_offset * box->pmu->pmu_idx; |
| 328 | } | 519 | } |
| 329 | 520 | ||
| 330 | static inline | 521 | static inline |
| 331 | unsigned uncore_msr_perf_ctr(struct intel_uncore_box *box, int idx) | 522 | unsigned uncore_msr_perf_ctr(struct intel_uncore_box *box, int idx) |
| 332 | { | 523 | { |
| 333 | return idx + box->pmu->type->perf_ctr + | 524 | return box->pmu->type->perf_ctr + |
| 525 | (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) + | ||
| 334 | box->pmu->type->msr_offset * box->pmu->pmu_idx; | 526 | box->pmu->type->msr_offset * box->pmu->pmu_idx; |
| 335 | } | 527 | } |
| 336 | 528 | ||
| @@ -422,3 +614,8 @@ static inline void uncore_box_init(struct intel_uncore_box *box) | |||
| 422 | box->pmu->type->ops->init_box(box); | 614 | box->pmu->type->ops->init_box(box); |
| 423 | } | 615 | } |
| 424 | } | 616 | } |
| 617 | |||
| 618 | static inline bool uncore_box_is_fake(struct intel_uncore_box *box) | ||
| 619 | { | ||
| 620 | return (box->phys_id < 0); | ||
| 621 | } | ||
diff --git a/arch/x86/kernel/cpu/sched.c b/arch/x86/kernel/cpu/sched.c deleted file mode 100644 index a640ae5ad201..000000000000 --- a/arch/x86/kernel/cpu/sched.c +++ /dev/null | |||
| @@ -1,55 +0,0 @@ | |||
| 1 | #include <linux/sched.h> | ||
| 2 | #include <linux/math64.h> | ||
| 3 | #include <linux/percpu.h> | ||
| 4 | #include <linux/irqflags.h> | ||
| 5 | |||
| 6 | #include <asm/cpufeature.h> | ||
| 7 | #include <asm/processor.h> | ||
| 8 | |||
| 9 | #ifdef CONFIG_SMP | ||
| 10 | |||
| 11 | static DEFINE_PER_CPU(struct aperfmperf, old_perf_sched); | ||
| 12 | |||
| 13 | static unsigned long scale_aperfmperf(void) | ||
| 14 | { | ||
| 15 | struct aperfmperf val, *old = &__get_cpu_var(old_perf_sched); | ||
| 16 | unsigned long ratio, flags; | ||
| 17 | |||
| 18 | local_irq_save(flags); | ||
| 19 | get_aperfmperf(&val); | ||
| 20 | local_irq_restore(flags); | ||
| 21 | |||
| 22 | ratio = calc_aperfmperf_ratio(old, &val); | ||
| 23 | *old = val; | ||
| 24 | |||
| 25 | return ratio; | ||
| 26 | } | ||
| 27 | |||
| 28 | unsigned long arch_scale_freq_power(struct sched_domain *sd, int cpu) | ||
| 29 | { | ||
| 30 | /* | ||
| 31 | * do aperf/mperf on the cpu level because it includes things | ||
| 32 | * like turbo mode, which are relevant to full cores. | ||
| 33 | */ | ||
| 34 | if (boot_cpu_has(X86_FEATURE_APERFMPERF)) | ||
| 35 | return scale_aperfmperf(); | ||
| 36 | |||
| 37 | /* | ||
| 38 | * maybe have something cpufreq here | ||
| 39 | */ | ||
| 40 | |||
| 41 | return default_scale_freq_power(sd, cpu); | ||
| 42 | } | ||
| 43 | |||
| 44 | unsigned long arch_scale_smt_power(struct sched_domain *sd, int cpu) | ||
| 45 | { | ||
| 46 | /* | ||
| 47 | * aperf/mperf already includes the smt gain | ||
| 48 | */ | ||
| 49 | if (boot_cpu_has(X86_FEATURE_APERFMPERF)) | ||
| 50 | return SCHED_LOAD_SCALE; | ||
| 51 | |||
| 52 | return default_scale_smt_power(sd, cpu); | ||
| 53 | } | ||
| 54 | |||
| 55 | #endif | ||
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 41857970517f..ed858e9e9a74 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c | |||
| @@ -944,7 +944,7 @@ void __init e820_reserve_resources(void) | |||
| 944 | for (i = 0; i < e820_saved.nr_map; i++) { | 944 | for (i = 0; i < e820_saved.nr_map; i++) { |
| 945 | struct e820entry *entry = &e820_saved.map[i]; | 945 | struct e820entry *entry = &e820_saved.map[i]; |
| 946 | firmware_map_add_early(entry->addr, | 946 | firmware_map_add_early(entry->addr, |
| 947 | entry->addr + entry->size - 1, | 947 | entry->addr + entry->size, |
| 948 | e820_type_to_string(entry->type)); | 948 | e820_type_to_string(entry->type)); |
| 949 | } | 949 | } |
| 950 | } | 950 | } |
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 111f6bbd8b38..69babd8c834f 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S | |||
| @@ -1048,24 +1048,6 @@ apicinterrupt LOCAL_TIMER_VECTOR \ | |||
| 1048 | apicinterrupt X86_PLATFORM_IPI_VECTOR \ | 1048 | apicinterrupt X86_PLATFORM_IPI_VECTOR \ |
| 1049 | x86_platform_ipi smp_x86_platform_ipi | 1049 | x86_platform_ipi smp_x86_platform_ipi |
| 1050 | 1050 | ||
| 1051 | #ifdef CONFIG_SMP | ||
| 1052 | ALIGN | ||
| 1053 | INTR_FRAME | ||
| 1054 | .irp idx,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, \ | ||
| 1055 | 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 | ||
| 1056 | .if NUM_INVALIDATE_TLB_VECTORS > \idx | ||
| 1057 | ENTRY(invalidate_interrupt\idx) | ||
| 1058 | pushq_cfi $~(INVALIDATE_TLB_VECTOR_START+\idx) | ||
| 1059 | jmp .Lcommon_invalidate_interrupt0 | ||
| 1060 | CFI_ADJUST_CFA_OFFSET -8 | ||
| 1061 | END(invalidate_interrupt\idx) | ||
| 1062 | .endif | ||
| 1063 | .endr | ||
| 1064 | CFI_ENDPROC | ||
| 1065 | apicinterrupt INVALIDATE_TLB_VECTOR_START, \ | ||
| 1066 | invalidate_interrupt0, smp_invalidate_interrupt | ||
| 1067 | #endif | ||
| 1068 | |||
| 1069 | apicinterrupt THRESHOLD_APIC_VECTOR \ | 1051 | apicinterrupt THRESHOLD_APIC_VECTOR \ |
| 1070 | threshold_interrupt smp_threshold_interrupt | 1052 | threshold_interrupt smp_threshold_interrupt |
| 1071 | apicinterrupt THERMAL_APIC_VECTOR \ | 1053 | apicinterrupt THERMAL_APIC_VECTOR \ |
diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c index 252981afd6c4..6e03b0d69138 100644 --- a/arch/x86/kernel/irqinit.c +++ b/arch/x86/kernel/irqinit.c | |||
| @@ -171,79 +171,6 @@ static void __init smp_intr_init(void) | |||
| 171 | */ | 171 | */ |
| 172 | alloc_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt); | 172 | alloc_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt); |
| 173 | 173 | ||
| 174 | /* IPIs for invalidation */ | ||
| 175 | #define ALLOC_INVTLB_VEC(NR) \ | ||
| 176 | alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+NR, \ | ||
| 177 | invalidate_interrupt##NR) | ||
| 178 | |||
| 179 | switch (NUM_INVALIDATE_TLB_VECTORS) { | ||
| 180 | default: | ||
| 181 | ALLOC_INVTLB_VEC(31); | ||
| 182 | case 31: | ||
| 183 | ALLOC_INVTLB_VEC(30); | ||
| 184 | case 30: | ||
| 185 | ALLOC_INVTLB_VEC(29); | ||
| 186 | case 29: | ||
| 187 | ALLOC_INVTLB_VEC(28); | ||
| 188 | case 28: | ||
| 189 | ALLOC_INVTLB_VEC(27); | ||
| 190 | case 27: | ||
| 191 | ALLOC_INVTLB_VEC(26); | ||
| 192 | case 26: | ||
| 193 | ALLOC_INVTLB_VEC(25); | ||
| 194 | case 25: | ||
| 195 | ALLOC_INVTLB_VEC(24); | ||
| 196 | case 24: | ||
| 197 | ALLOC_INVTLB_VEC(23); | ||
| 198 | case 23: | ||
| 199 | ALLOC_INVTLB_VEC(22); | ||
| 200 | case 22: | ||
| 201 | ALLOC_INVTLB_VEC(21); | ||
| 202 | case 21: | ||
| 203 | ALLOC_INVTLB_VEC(20); | ||
| 204 | case 20: | ||
| 205 | ALLOC_INVTLB_VEC(19); | ||
| 206 | case 19: | ||
| 207 | ALLOC_INVTLB_VEC(18); | ||
| 208 | case 18: | ||
| 209 | ALLOC_INVTLB_VEC(17); | ||
| 210 | case 17: | ||
| 211 | ALLOC_INVTLB_VEC(16); | ||
| 212 | case 16: | ||
| 213 | ALLOC_INVTLB_VEC(15); | ||
| 214 | case 15: | ||
| 215 | ALLOC_INVTLB_VEC(14); | ||
| 216 | case 14: | ||
| 217 | ALLOC_INVTLB_VEC(13); | ||
| 218 | case 13: | ||
| 219 | ALLOC_INVTLB_VEC(12); | ||
| 220 | case 12: | ||
| 221 | ALLOC_INVTLB_VEC(11); | ||
| 222 | case 11: | ||
| 223 | ALLOC_INVTLB_VEC(10); | ||
| 224 | case 10: | ||
| 225 | ALLOC_INVTLB_VEC(9); | ||
| 226 | case 9: | ||
| 227 | ALLOC_INVTLB_VEC(8); | ||
| 228 | case 8: | ||
| 229 | ALLOC_INVTLB_VEC(7); | ||
| 230 | case 7: | ||
| 231 | ALLOC_INVTLB_VEC(6); | ||
| 232 | case 6: | ||
| 233 | ALLOC_INVTLB_VEC(5); | ||
| 234 | case 5: | ||
| 235 | ALLOC_INVTLB_VEC(4); | ||
| 236 | case 4: | ||
| 237 | ALLOC_INVTLB_VEC(3); | ||
| 238 | case 3: | ||
| 239 | ALLOC_INVTLB_VEC(2); | ||
| 240 | case 2: | ||
| 241 | ALLOC_INVTLB_VEC(1); | ||
| 242 | case 1: | ||
| 243 | ALLOC_INVTLB_VEC(0); | ||
| 244 | break; | ||
| 245 | } | ||
| 246 | |||
| 247 | /* IPI for generic function call */ | 174 | /* IPI for generic function call */ |
| 248 | alloc_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt); | 175 | alloc_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt); |
| 249 | 176 | ||
diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c index 5a98aa272184..5cdff0357746 100644 --- a/arch/x86/kernel/setup_percpu.c +++ b/arch/x86/kernel/setup_percpu.c | |||
| @@ -21,7 +21,7 @@ | |||
| 21 | #include <asm/cpu.h> | 21 | #include <asm/cpu.h> |
| 22 | #include <asm/stackprotector.h> | 22 | #include <asm/stackprotector.h> |
| 23 | 23 | ||
| 24 | DEFINE_PER_CPU(int, cpu_number); | 24 | DEFINE_PER_CPU_READ_MOSTLY(int, cpu_number); |
| 25 | EXPORT_PER_CPU_SYMBOL(cpu_number); | 25 | EXPORT_PER_CPU_SYMBOL(cpu_number); |
| 26 | 26 | ||
| 27 | #ifdef CONFIG_X86_64 | 27 | #ifdef CONFIG_X86_64 |
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index c1a310fb8309..7c5a8c314c02 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
| @@ -106,17 +106,17 @@ int smp_num_siblings = 1; | |||
| 106 | EXPORT_SYMBOL(smp_num_siblings); | 106 | EXPORT_SYMBOL(smp_num_siblings); |
| 107 | 107 | ||
| 108 | /* Last level cache ID of each logical CPU */ | 108 | /* Last level cache ID of each logical CPU */ |
| 109 | DEFINE_PER_CPU(u16, cpu_llc_id) = BAD_APICID; | 109 | DEFINE_PER_CPU_READ_MOSTLY(u16, cpu_llc_id) = BAD_APICID; |
| 110 | 110 | ||
| 111 | /* representing HT siblings of each logical CPU */ | 111 | /* representing HT siblings of each logical CPU */ |
| 112 | DEFINE_PER_CPU(cpumask_var_t, cpu_sibling_map); | 112 | DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_sibling_map); |
| 113 | EXPORT_PER_CPU_SYMBOL(cpu_sibling_map); | 113 | EXPORT_PER_CPU_SYMBOL(cpu_sibling_map); |
| 114 | 114 | ||
| 115 | /* representing HT and core siblings of each logical CPU */ | 115 | /* representing HT and core siblings of each logical CPU */ |
| 116 | DEFINE_PER_CPU(cpumask_var_t, cpu_core_map); | 116 | DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_core_map); |
| 117 | EXPORT_PER_CPU_SYMBOL(cpu_core_map); | 117 | EXPORT_PER_CPU_SYMBOL(cpu_core_map); |
| 118 | 118 | ||
| 119 | DEFINE_PER_CPU(cpumask_var_t, cpu_llc_shared_map); | 119 | DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_llc_shared_map); |
| 120 | 120 | ||
| 121 | /* Per CPU bogomips and other parameters */ | 121 | /* Per CPU bogomips and other parameters */ |
| 122 | DEFINE_PER_CPU_SHARED_ALIGNED(struct cpuinfo_x86, cpu_info); | 122 | DEFINE_PER_CPU_SHARED_ALIGNED(struct cpuinfo_x86, cpu_info); |
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index a718e0d23503..931930a96160 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c | |||
| @@ -919,11 +919,13 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages, | |||
| 919 | 919 | ||
| 920 | /* | 920 | /* |
| 921 | * On success we use clflush, when the CPU supports it to | 921 | * On success we use clflush, when the CPU supports it to |
| 922 | * avoid the wbindv. If the CPU does not support it and in the | 922 | * avoid the wbindv. If the CPU does not support it, in the |
| 923 | * error case we fall back to cpa_flush_all (which uses | 923 | * error case, and during early boot (for EFI) we fall back |
| 924 | * wbindv): | 924 | * to cpa_flush_all (which uses wbinvd): |
| 925 | */ | 925 | */ |
| 926 | if (!ret && cpu_has_clflush) { | 926 | if (early_boot_irqs_disabled) |
| 927 | __cpa_flush_all((void *)(long)cache); | ||
| 928 | else if (!ret && cpu_has_clflush) { | ||
| 927 | if (cpa.flags & (CPA_PAGES_ARRAY | CPA_ARRAY)) { | 929 | if (cpa.flags & (CPA_PAGES_ARRAY | CPA_ARRAY)) { |
| 928 | cpa_flush_array(addr, numpages, cache, | 930 | cpa_flush_array(addr, numpages, cache, |
| 929 | cpa.flags, pages); | 931 | cpa.flags, pages); |
diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c index 5e57e113b72c..613cd83e8c0c 100644 --- a/arch/x86/mm/tlb.c +++ b/arch/x86/mm/tlb.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include <asm/cache.h> | 12 | #include <asm/cache.h> |
| 13 | #include <asm/apic.h> | 13 | #include <asm/apic.h> |
| 14 | #include <asm/uv/uv.h> | 14 | #include <asm/uv/uv.h> |
| 15 | #include <linux/debugfs.h> | ||
| 15 | 16 | ||
| 16 | DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate) | 17 | DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate) |
| 17 | = { &init_mm, 0, }; | 18 | = { &init_mm, 0, }; |
| @@ -27,33 +28,14 @@ DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate) | |||
| 27 | * | 28 | * |
| 28 | * More scalable flush, from Andi Kleen | 29 | * More scalable flush, from Andi Kleen |
| 29 | * | 30 | * |
| 30 | * To avoid global state use 8 different call vectors. | 31 | * Implement flush IPI by CALL_FUNCTION_VECTOR, Alex Shi |
| 31 | * Each CPU uses a specific vector to trigger flushes on other | ||
| 32 | * CPUs. Depending on the received vector the target CPUs look into | ||
| 33 | * the right array slot for the flush data. | ||
| 34 | * | ||
| 35 | * With more than 8 CPUs they are hashed to the 8 available | ||
| 36 | * vectors. The limited global vector space forces us to this right now. | ||
| 37 | * In future when interrupts are split into per CPU domains this could be | ||
| 38 | * fixed, at the cost of triggering multiple IPIs in some cases. | ||
| 39 | */ | 32 | */ |
| 40 | 33 | ||
| 41 | union smp_flush_state { | 34 | struct flush_tlb_info { |
| 42 | struct { | 35 | struct mm_struct *flush_mm; |
| 43 | struct mm_struct *flush_mm; | 36 | unsigned long flush_start; |
| 44 | unsigned long flush_va; | 37 | unsigned long flush_end; |
| 45 | raw_spinlock_t tlbstate_lock; | 38 | }; |
| 46 | DECLARE_BITMAP(flush_cpumask, NR_CPUS); | ||
| 47 | }; | ||
| 48 | char pad[INTERNODE_CACHE_BYTES]; | ||
| 49 | } ____cacheline_internodealigned_in_smp; | ||
| 50 | |||
| 51 | /* State is put into the per CPU data section, but padded | ||
| 52 | to a full cache line because other CPUs can access it and we don't | ||
| 53 | want false sharing in the per cpu data segment. */ | ||
| 54 | static union smp_flush_state flush_state[NUM_INVALIDATE_TLB_VECTORS]; | ||
| 55 | |||
| 56 | static DEFINE_PER_CPU_READ_MOSTLY(int, tlb_vector_offset); | ||
| 57 | 39 | ||
| 58 | /* | 40 | /* |
| 59 | * We cannot call mmdrop() because we are in interrupt context, | 41 | * We cannot call mmdrop() because we are in interrupt context, |
| @@ -72,28 +54,25 @@ void leave_mm(int cpu) | |||
| 72 | EXPORT_SYMBOL_GPL(leave_mm); | 54 | EXPORT_SYMBOL_GPL(leave_mm); |
| 73 | 55 | ||
| 74 | /* | 56 | /* |
| 75 | * | ||
| 76 | * The flush IPI assumes that a thread switch happens in this order: | 57 | * The flush IPI assumes that a thread switch happens in this order: |
| 77 | * [cpu0: the cpu that switches] | 58 | * [cpu0: the cpu that switches] |
| 78 | * 1) switch_mm() either 1a) or 1b) | 59 | * 1) switch_mm() either 1a) or 1b) |
| 79 | * 1a) thread switch to a different mm | 60 | * 1a) thread switch to a different mm |
| 80 | * 1a1) cpu_clear(cpu, old_mm->cpu_vm_mask); | 61 | * 1a1) set cpu_tlbstate to TLBSTATE_OK |
| 81 | * Stop ipi delivery for the old mm. This is not synchronized with | 62 | * Now the tlb flush NMI handler flush_tlb_func won't call leave_mm |
| 82 | * the other cpus, but smp_invalidate_interrupt ignore flush ipis | 63 | * if cpu0 was in lazy tlb mode. |
| 83 | * for the wrong mm, and in the worst case we perform a superfluous | 64 | * 1a2) update cpu active_mm |
| 84 | * tlb flush. | ||
| 85 | * 1a2) set cpu mmu_state to TLBSTATE_OK | ||
| 86 | * Now the smp_invalidate_interrupt won't call leave_mm if cpu0 | ||
| 87 | * was in lazy tlb mode. | ||
| 88 | * 1a3) update cpu active_mm | ||
| 89 | * Now cpu0 accepts tlb flushes for the new mm. | 65 | * Now cpu0 accepts tlb flushes for the new mm. |
| 90 | * 1a4) cpu_set(cpu, new_mm->cpu_vm_mask); | 66 | * 1a3) cpu_set(cpu, new_mm->cpu_vm_mask); |
| 91 | * Now the other cpus will send tlb flush ipis. | 67 | * Now the other cpus will send tlb flush ipis. |
| 92 | * 1a4) change cr3. | 68 | * 1a4) change cr3. |
| 69 | * 1a5) cpu_clear(cpu, old_mm->cpu_vm_mask); | ||
| 70 | * Stop ipi delivery for the old mm. This is not synchronized with | ||
| 71 | * the other cpus, but flush_tlb_func ignore flush ipis for the wrong | ||
| 72 | * mm, and in the worst case we perform a superfluous tlb flush. | ||
| 93 | * 1b) thread switch without mm change | 73 | * 1b) thread switch without mm change |
| 94 | * cpu active_mm is correct, cpu0 already handles | 74 | * cpu active_mm is correct, cpu0 already handles flush ipis. |
| 95 | * flush ipis. | 75 | * 1b1) set cpu_tlbstate to TLBSTATE_OK |
| 96 | * 1b1) set cpu mmu_state to TLBSTATE_OK | ||
| 97 | * 1b2) test_and_set the cpu bit in cpu_vm_mask. | 76 | * 1b2) test_and_set the cpu bit in cpu_vm_mask. |
| 98 | * Atomically set the bit [other cpus will start sending flush ipis], | 77 | * Atomically set the bit [other cpus will start sending flush ipis], |
| 99 | * and test the bit. | 78 | * and test the bit. |
| @@ -106,174 +85,62 @@ EXPORT_SYMBOL_GPL(leave_mm); | |||
| 106 | * runs in kernel space, the cpu could load tlb entries for user space | 85 | * runs in kernel space, the cpu could load tlb entries for user space |
| 107 | * pages. | 86 | * pages. |
| 108 | * | 87 | * |
| 109 | * The good news is that cpu mmu_state is local to each cpu, no | 88 | * The good news is that cpu_tlbstate is local to each cpu, no |
| 110 | * write/read ordering problems. | 89 | * write/read ordering problems. |
| 111 | */ | 90 | */ |
| 112 | 91 | ||
| 113 | /* | 92 | /* |
| 114 | * TLB flush IPI: | 93 | * TLB flush funcation: |
| 115 | * | ||
| 116 | * 1) Flush the tlb entries if the cpu uses the mm that's being flushed. | 94 | * 1) Flush the tlb entries if the cpu uses the mm that's being flushed. |
| 117 | * 2) Leave the mm if we are in the lazy tlb mode. | 95 | * 2) Leave the mm if we are in the lazy tlb mode. |
| 118 | * | ||
| 119 | * Interrupts are disabled. | ||
| 120 | */ | ||
| 121 | |||
| 122 | /* | ||
| 123 | * FIXME: use of asmlinkage is not consistent. On x86_64 it's noop | ||
| 124 | * but still used for documentation purpose but the usage is slightly | ||
| 125 | * inconsistent. On x86_32, asmlinkage is regparm(0) but interrupt | ||
| 126 | * entry calls in with the first parameter in %eax. Maybe define | ||
| 127 | * intrlinkage? | ||
| 128 | */ | 96 | */ |
| 129 | #ifdef CONFIG_X86_64 | 97 | static void flush_tlb_func(void *info) |
| 130 | asmlinkage | ||
| 131 | #endif | ||
| 132 | void smp_invalidate_interrupt(struct pt_regs *regs) | ||
| 133 | { | 98 | { |
| 134 | unsigned int cpu; | 99 | struct flush_tlb_info *f = info; |
| 135 | unsigned int sender; | ||
| 136 | union smp_flush_state *f; | ||
| 137 | |||
| 138 | cpu = smp_processor_id(); | ||
| 139 | /* | ||
| 140 | * orig_rax contains the negated interrupt vector. | ||
| 141 | * Use that to determine where the sender put the data. | ||
| 142 | */ | ||
| 143 | sender = ~regs->orig_ax - INVALIDATE_TLB_VECTOR_START; | ||
| 144 | f = &flush_state[sender]; | ||
| 145 | |||
| 146 | if (!cpumask_test_cpu(cpu, to_cpumask(f->flush_cpumask))) | ||
| 147 | goto out; | ||
| 148 | /* | ||
| 149 | * This was a BUG() but until someone can quote me the | ||
| 150 | * line from the intel manual that guarantees an IPI to | ||
| 151 | * multiple CPUs is retried _only_ on the erroring CPUs | ||
| 152 | * its staying as a return | ||
| 153 | * | ||
| 154 | * BUG(); | ||
| 155 | */ | ||
| 156 | |||
| 157 | if (f->flush_mm == this_cpu_read(cpu_tlbstate.active_mm)) { | ||
| 158 | if (this_cpu_read(cpu_tlbstate.state) == TLBSTATE_OK) { | ||
| 159 | if (f->flush_va == TLB_FLUSH_ALL) | ||
| 160 | local_flush_tlb(); | ||
| 161 | else | ||
| 162 | __flush_tlb_one(f->flush_va); | ||
| 163 | } else | ||
| 164 | leave_mm(cpu); | ||
| 165 | } | ||
| 166 | out: | ||
| 167 | ack_APIC_irq(); | ||
| 168 | smp_mb__before_clear_bit(); | ||
| 169 | cpumask_clear_cpu(cpu, to_cpumask(f->flush_cpumask)); | ||
| 170 | smp_mb__after_clear_bit(); | ||
| 171 | inc_irq_stat(irq_tlb_count); | ||
| 172 | } | ||
| 173 | 100 | ||
| 174 | static void flush_tlb_others_ipi(const struct cpumask *cpumask, | 101 | if (f->flush_mm != this_cpu_read(cpu_tlbstate.active_mm)) |
| 175 | struct mm_struct *mm, unsigned long va) | 102 | return; |
| 176 | { | 103 | |
| 177 | unsigned int sender; | 104 | if (this_cpu_read(cpu_tlbstate.state) == TLBSTATE_OK) { |
| 178 | union smp_flush_state *f; | 105 | if (f->flush_end == TLB_FLUSH_ALL || !cpu_has_invlpg) |
| 179 | 106 | local_flush_tlb(); | |
| 180 | /* Caller has disabled preemption */ | 107 | else if (!f->flush_end) |
| 181 | sender = this_cpu_read(tlb_vector_offset); | 108 | __flush_tlb_single(f->flush_start); |
| 182 | f = &flush_state[sender]; | 109 | else { |
| 183 | 110 | unsigned long addr; | |
| 184 | if (nr_cpu_ids > NUM_INVALIDATE_TLB_VECTORS) | 111 | addr = f->flush_start; |
| 185 | raw_spin_lock(&f->tlbstate_lock); | 112 | while (addr < f->flush_end) { |
| 186 | 113 | __flush_tlb_single(addr); | |
| 187 | f->flush_mm = mm; | 114 | addr += PAGE_SIZE; |
| 188 | f->flush_va = va; | 115 | } |
| 189 | if (cpumask_andnot(to_cpumask(f->flush_cpumask), cpumask, cpumask_of(smp_processor_id()))) { | 116 | } |
| 190 | /* | 117 | } else |
| 191 | * We have to send the IPI only to | 118 | leave_mm(smp_processor_id()); |
| 192 | * CPUs affected. | ||
| 193 | */ | ||
| 194 | apic->send_IPI_mask(to_cpumask(f->flush_cpumask), | ||
| 195 | INVALIDATE_TLB_VECTOR_START + sender); | ||
| 196 | |||
| 197 | while (!cpumask_empty(to_cpumask(f->flush_cpumask))) | ||
| 198 | cpu_relax(); | ||
| 199 | } | ||
| 200 | 119 | ||
| 201 | f->flush_mm = NULL; | ||
| 202 | f->flush_va = 0; | ||
| 203 | if (nr_cpu_ids > NUM_INVALIDATE_TLB_VECTORS) | ||
| 204 | raw_spin_unlock(&f->tlbstate_lock); | ||
| 205 | } | 120 | } |
| 206 | 121 | ||
| 207 | void native_flush_tlb_others(const struct cpumask *cpumask, | 122 | void native_flush_tlb_others(const struct cpumask *cpumask, |
| 208 | struct mm_struct *mm, unsigned long va) | 123 | struct mm_struct *mm, unsigned long start, |
| 124 | unsigned long end) | ||
| 209 | { | 125 | { |
| 126 | struct flush_tlb_info info; | ||
| 127 | info.flush_mm = mm; | ||
| 128 | info.flush_start = start; | ||
| 129 | info.flush_end = end; | ||
| 130 | |||
| 210 | if (is_uv_system()) { | 131 | if (is_uv_system()) { |
| 211 | unsigned int cpu; | 132 | unsigned int cpu; |
| 212 | 133 | ||
| 213 | cpu = smp_processor_id(); | 134 | cpu = smp_processor_id(); |
| 214 | cpumask = uv_flush_tlb_others(cpumask, mm, va, cpu); | 135 | cpumask = uv_flush_tlb_others(cpumask, mm, start, end, cpu); |
| 215 | if (cpumask) | 136 | if (cpumask) |
| 216 | flush_tlb_others_ipi(cpumask, mm, va); | 137 | smp_call_function_many(cpumask, flush_tlb_func, |
| 138 | &info, 1); | ||
| 217 | return; | 139 | return; |
| 218 | } | 140 | } |
| 219 | flush_tlb_others_ipi(cpumask, mm, va); | 141 | smp_call_function_many(cpumask, flush_tlb_func, &info, 1); |
| 220 | } | 142 | } |
| 221 | 143 | ||
| 222 | static void __cpuinit calculate_tlb_offset(void) | ||
| 223 | { | ||
| 224 | int cpu, node, nr_node_vecs, idx = 0; | ||
| 225 | /* | ||
| 226 | * we are changing tlb_vector_offset for each CPU in runtime, but this | ||
| 227 | * will not cause inconsistency, as the write is atomic under X86. we | ||
| 228 | * might see more lock contentions in a short time, but after all CPU's | ||
| 229 | * tlb_vector_offset are changed, everything should go normal | ||
| 230 | * | ||
| 231 | * Note: if NUM_INVALIDATE_TLB_VECTORS % nr_online_nodes !=0, we might | ||
| 232 | * waste some vectors. | ||
| 233 | **/ | ||
| 234 | if (nr_online_nodes > NUM_INVALIDATE_TLB_VECTORS) | ||
| 235 | nr_node_vecs = 1; | ||
| 236 | else | ||
| 237 | nr_node_vecs = NUM_INVALIDATE_TLB_VECTORS/nr_online_nodes; | ||
| 238 | |||
| 239 | for_each_online_node(node) { | ||
| 240 | int node_offset = (idx % NUM_INVALIDATE_TLB_VECTORS) * | ||
| 241 | nr_node_vecs; | ||
| 242 | int cpu_offset = 0; | ||
| 243 | for_each_cpu(cpu, cpumask_of_node(node)) { | ||
| 244 | per_cpu(tlb_vector_offset, cpu) = node_offset + | ||
| 245 | cpu_offset; | ||
| 246 | cpu_offset++; | ||
| 247 | cpu_offset = cpu_offset % nr_node_vecs; | ||
| 248 | } | ||
| 249 | idx++; | ||
| 250 | } | ||
| 251 | } | ||
| 252 | |||
| 253 | static int __cpuinit tlb_cpuhp_notify(struct notifier_block *n, | ||
| 254 | unsigned long action, void *hcpu) | ||
| 255 | { | ||
| 256 | switch (action & 0xf) { | ||
| 257 | case CPU_ONLINE: | ||
| 258 | case CPU_DEAD: | ||
| 259 | calculate_tlb_offset(); | ||
| 260 | } | ||
| 261 | return NOTIFY_OK; | ||
| 262 | } | ||
| 263 | |||
| 264 | static int __cpuinit init_smp_flush(void) | ||
| 265 | { | ||
| 266 | int i; | ||
| 267 | |||
| 268 | for (i = 0; i < ARRAY_SIZE(flush_state); i++) | ||
| 269 | raw_spin_lock_init(&flush_state[i].tlbstate_lock); | ||
| 270 | |||
| 271 | calculate_tlb_offset(); | ||
| 272 | hotcpu_notifier(tlb_cpuhp_notify, 0); | ||
| 273 | return 0; | ||
| 274 | } | ||
| 275 | core_initcall(init_smp_flush); | ||
| 276 | |||
| 277 | void flush_tlb_current_task(void) | 144 | void flush_tlb_current_task(void) |
| 278 | { | 145 | { |
| 279 | struct mm_struct *mm = current->mm; | 146 | struct mm_struct *mm = current->mm; |
| @@ -282,27 +149,91 @@ void flush_tlb_current_task(void) | |||
| 282 | 149 | ||
| 283 | local_flush_tlb(); | 150 | local_flush_tlb(); |
| 284 | if (cpumask_any_but(mm_cpumask(mm), smp_processor_id()) < nr_cpu_ids) | 151 | if (cpumask_any_but(mm_cpumask(mm), smp_processor_id()) < nr_cpu_ids) |
| 285 | flush_tlb_others(mm_cpumask(mm), mm, TLB_FLUSH_ALL); | 152 | flush_tlb_others(mm_cpumask(mm), mm, 0UL, TLB_FLUSH_ALL); |
| 286 | preempt_enable(); | 153 | preempt_enable(); |
| 287 | } | 154 | } |
| 288 | 155 | ||
| 289 | void flush_tlb_mm(struct mm_struct *mm) | 156 | /* |
| 157 | * It can find out the THP large page, or | ||
| 158 | * HUGETLB page in tlb_flush when THP disabled | ||
| 159 | */ | ||
| 160 | static inline unsigned long has_large_page(struct mm_struct *mm, | ||
| 161 | unsigned long start, unsigned long end) | ||
| 162 | { | ||
| 163 | pgd_t *pgd; | ||
| 164 | pud_t *pud; | ||
| 165 | pmd_t *pmd; | ||
| 166 | unsigned long addr = ALIGN(start, HPAGE_SIZE); | ||
| 167 | for (; addr < end; addr += HPAGE_SIZE) { | ||
| 168 | pgd = pgd_offset(mm, addr); | ||
| 169 | if (likely(!pgd_none(*pgd))) { | ||
| 170 | pud = pud_offset(pgd, addr); | ||
| 171 | if (likely(!pud_none(*pud))) { | ||
| 172 | pmd = pmd_offset(pud, addr); | ||
| 173 | if (likely(!pmd_none(*pmd))) | ||
| 174 | if (pmd_large(*pmd)) | ||
| 175 | return addr; | ||
| 176 | } | ||
| 177 | } | ||
| 178 | } | ||
| 179 | return 0; | ||
| 180 | } | ||
| 181 | |||
| 182 | void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start, | ||
| 183 | unsigned long end, unsigned long vmflag) | ||
| 290 | { | 184 | { |
| 185 | unsigned long addr; | ||
| 186 | unsigned act_entries, tlb_entries = 0; | ||
| 187 | |||
| 291 | preempt_disable(); | 188 | preempt_disable(); |
| 189 | if (current->active_mm != mm) | ||
| 190 | goto flush_all; | ||
| 292 | 191 | ||
| 293 | if (current->active_mm == mm) { | 192 | if (!current->mm) { |
| 294 | if (current->mm) | 193 | leave_mm(smp_processor_id()); |
| 194 | goto flush_all; | ||
| 195 | } | ||
| 196 | |||
| 197 | if (end == TLB_FLUSH_ALL || tlb_flushall_shift == -1 | ||
| 198 | || vmflag == VM_HUGETLB) { | ||
| 199 | local_flush_tlb(); | ||
| 200 | goto flush_all; | ||
| 201 | } | ||
| 202 | |||
| 203 | /* In modern CPU, last level tlb used for both data/ins */ | ||
| 204 | if (vmflag & VM_EXEC) | ||
| 205 | tlb_entries = tlb_lli_4k[ENTRIES]; | ||
| 206 | else | ||
| 207 | tlb_entries = tlb_lld_4k[ENTRIES]; | ||
| 208 | /* Assume all of TLB entries was occupied by this task */ | ||
| 209 | act_entries = mm->total_vm > tlb_entries ? tlb_entries : mm->total_vm; | ||
| 210 | |||
| 211 | /* tlb_flushall_shift is on balance point, details in commit log */ | ||
| 212 | if ((end - start) >> PAGE_SHIFT > act_entries >> tlb_flushall_shift) | ||
| 213 | local_flush_tlb(); | ||
| 214 | else { | ||
| 215 | if (has_large_page(mm, start, end)) { | ||
| 295 | local_flush_tlb(); | 216 | local_flush_tlb(); |
| 296 | else | 217 | goto flush_all; |
| 297 | leave_mm(smp_processor_id()); | 218 | } |
| 219 | /* flush range by one by one 'invlpg' */ | ||
| 220 | for (addr = start; addr < end; addr += PAGE_SIZE) | ||
| 221 | __flush_tlb_single(addr); | ||
| 222 | |||
| 223 | if (cpumask_any_but(mm_cpumask(mm), | ||
| 224 | smp_processor_id()) < nr_cpu_ids) | ||
| 225 | flush_tlb_others(mm_cpumask(mm), mm, start, end); | ||
| 226 | preempt_enable(); | ||
| 227 | return; | ||
| 298 | } | 228 | } |
| 299 | if (cpumask_any_but(mm_cpumask(mm), smp_processor_id()) < nr_cpu_ids) | ||
| 300 | flush_tlb_others(mm_cpumask(mm), mm, TLB_FLUSH_ALL); | ||
| 301 | 229 | ||
| 230 | flush_all: | ||
| 231 | if (cpumask_any_but(mm_cpumask(mm), smp_processor_id()) < nr_cpu_ids) | ||
| 232 | flush_tlb_others(mm_cpumask(mm), mm, 0UL, TLB_FLUSH_ALL); | ||
| 302 | preempt_enable(); | 233 | preempt_enable(); |
| 303 | } | 234 | } |
| 304 | 235 | ||
| 305 | void flush_tlb_page(struct vm_area_struct *vma, unsigned long va) | 236 | void flush_tlb_page(struct vm_area_struct *vma, unsigned long start) |
| 306 | { | 237 | { |
| 307 | struct mm_struct *mm = vma->vm_mm; | 238 | struct mm_struct *mm = vma->vm_mm; |
| 308 | 239 | ||
| @@ -310,13 +241,13 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long va) | |||
| 310 | 241 | ||
| 311 | if (current->active_mm == mm) { | 242 | if (current->active_mm == mm) { |
| 312 | if (current->mm) | 243 | if (current->mm) |
| 313 | __flush_tlb_one(va); | 244 | __flush_tlb_one(start); |
| 314 | else | 245 | else |
| 315 | leave_mm(smp_processor_id()); | 246 | leave_mm(smp_processor_id()); |
| 316 | } | 247 | } |
| 317 | 248 | ||
| 318 | if (cpumask_any_but(mm_cpumask(mm), smp_processor_id()) < nr_cpu_ids) | 249 | if (cpumask_any_but(mm_cpumask(mm), smp_processor_id()) < nr_cpu_ids) |
| 319 | flush_tlb_others(mm_cpumask(mm), mm, va); | 250 | flush_tlb_others(mm_cpumask(mm), mm, start, 0UL); |
| 320 | 251 | ||
| 321 | preempt_enable(); | 252 | preempt_enable(); |
| 322 | } | 253 | } |
| @@ -332,3 +263,83 @@ void flush_tlb_all(void) | |||
| 332 | { | 263 | { |
| 333 | on_each_cpu(do_flush_tlb_all, NULL, 1); | 264 | on_each_cpu(do_flush_tlb_all, NULL, 1); |
| 334 | } | 265 | } |
| 266 | |||
| 267 | static void do_kernel_range_flush(void *info) | ||
| 268 | { | ||
| 269 | struct flush_tlb_info *f = info; | ||
| 270 | unsigned long addr; | ||
| 271 | |||
| 272 | /* flush range by one by one 'invlpg' */ | ||
| 273 | for (addr = f->flush_start; addr < f->flush_end; addr += PAGE_SIZE) | ||
| 274 | __flush_tlb_single(addr); | ||
| 275 | } | ||
| 276 | |||
| 277 | void flush_tlb_kernel_range(unsigned long start, unsigned long end) | ||
| 278 | { | ||
| 279 | unsigned act_entries; | ||
| 280 | struct flush_tlb_info info; | ||
| 281 | |||
| 282 | /* In modern CPU, last level tlb used for both data/ins */ | ||
| 283 | act_entries = tlb_lld_4k[ENTRIES]; | ||
| 284 | |||
| 285 | /* Balance as user space task's flush, a bit conservative */ | ||
| 286 | if (end == TLB_FLUSH_ALL || tlb_flushall_shift == -1 || | ||
| 287 | (end - start) >> PAGE_SHIFT > act_entries >> tlb_flushall_shift) | ||
| 288 | |||
| 289 | on_each_cpu(do_flush_tlb_all, NULL, 1); | ||
| 290 | else { | ||
| 291 | info.flush_start = start; | ||
| 292 | info.flush_end = end; | ||
| 293 | on_each_cpu(do_kernel_range_flush, &info, 1); | ||
| 294 | } | ||
| 295 | } | ||
| 296 | |||
| 297 | #ifdef CONFIG_DEBUG_TLBFLUSH | ||
| 298 | static ssize_t tlbflush_read_file(struct file *file, char __user *user_buf, | ||
| 299 | size_t count, loff_t *ppos) | ||
| 300 | { | ||
| 301 | char buf[32]; | ||
| 302 | unsigned int len; | ||
| 303 | |||
| 304 | len = sprintf(buf, "%hd\n", tlb_flushall_shift); | ||
| 305 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
| 306 | } | ||
| 307 | |||
| 308 | static ssize_t tlbflush_write_file(struct file *file, | ||
| 309 | const char __user *user_buf, size_t count, loff_t *ppos) | ||
| 310 | { | ||
| 311 | char buf[32]; | ||
| 312 | ssize_t len; | ||
| 313 | s8 shift; | ||
| 314 | |||
| 315 | len = min(count, sizeof(buf) - 1); | ||
| 316 | if (copy_from_user(buf, user_buf, len)) | ||
| 317 | return -EFAULT; | ||
| 318 | |||
| 319 | buf[len] = '\0'; | ||
| 320 | if (kstrtos8(buf, 0, &shift)) | ||
| 321 | return -EINVAL; | ||
| 322 | |||
| 323 | if (shift > 64) | ||
| 324 | return -EINVAL; | ||
| 325 | |||
| 326 | tlb_flushall_shift = shift; | ||
| 327 | return count; | ||
| 328 | } | ||
| 329 | |||
| 330 | static const struct file_operations fops_tlbflush = { | ||
| 331 | .read = tlbflush_read_file, | ||
| 332 | .write = tlbflush_write_file, | ||
| 333 | .llseek = default_llseek, | ||
| 334 | }; | ||
| 335 | |||
| 336 | static int __cpuinit create_tlb_flushall_shift(void) | ||
| 337 | { | ||
| 338 | if (cpu_has_invlpg) { | ||
| 339 | debugfs_create_file("tlb_flushall_shift", S_IRUSR | S_IWUSR, | ||
| 340 | arch_debugfs_dir, NULL, &fops_tlbflush); | ||
| 341 | } | ||
| 342 | return 0; | ||
| 343 | } | ||
| 344 | late_initcall(create_tlb_flushall_shift); | ||
| 345 | #endif | ||
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index 92660edaa1e7..2dc29f51e75a 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c | |||
| @@ -234,22 +234,7 @@ static efi_status_t __init phys_efi_set_virtual_address_map( | |||
| 234 | return status; | 234 | return status; |
| 235 | } | 235 | } |
| 236 | 236 | ||
| 237 | static efi_status_t __init phys_efi_get_time(efi_time_t *tm, | 237 | static int efi_set_rtc_mmss(unsigned long nowtime) |
| 238 | efi_time_cap_t *tc) | ||
| 239 | { | ||
| 240 | unsigned long flags; | ||
| 241 | efi_status_t status; | ||
| 242 | |||
| 243 | spin_lock_irqsave(&rtc_lock, flags); | ||
| 244 | efi_call_phys_prelog(); | ||
| 245 | status = efi_call_phys2(efi_phys.get_time, virt_to_phys(tm), | ||
| 246 | virt_to_phys(tc)); | ||
| 247 | efi_call_phys_epilog(); | ||
| 248 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
| 249 | return status; | ||
| 250 | } | ||
| 251 | |||
| 252 | int efi_set_rtc_mmss(unsigned long nowtime) | ||
| 253 | { | 238 | { |
| 254 | int real_seconds, real_minutes; | 239 | int real_seconds, real_minutes; |
| 255 | efi_status_t status; | 240 | efi_status_t status; |
| @@ -278,7 +263,7 @@ int efi_set_rtc_mmss(unsigned long nowtime) | |||
| 278 | return 0; | 263 | return 0; |
| 279 | } | 264 | } |
| 280 | 265 | ||
| 281 | unsigned long efi_get_time(void) | 266 | static unsigned long efi_get_time(void) |
| 282 | { | 267 | { |
| 283 | efi_status_t status; | 268 | efi_status_t status; |
| 284 | efi_time_t eft; | 269 | efi_time_t eft; |
| @@ -621,18 +606,13 @@ static int __init efi_runtime_init(void) | |||
| 621 | } | 606 | } |
| 622 | /* | 607 | /* |
| 623 | * We will only need *early* access to the following | 608 | * We will only need *early* access to the following |
| 624 | * two EFI runtime services before set_virtual_address_map | 609 | * EFI runtime service before set_virtual_address_map |
| 625 | * is invoked. | 610 | * is invoked. |
| 626 | */ | 611 | */ |
| 627 | efi_phys.get_time = (efi_get_time_t *)runtime->get_time; | ||
| 628 | efi_phys.set_virtual_address_map = | 612 | efi_phys.set_virtual_address_map = |
| 629 | (efi_set_virtual_address_map_t *) | 613 | (efi_set_virtual_address_map_t *) |
| 630 | runtime->set_virtual_address_map; | 614 | runtime->set_virtual_address_map; |
| 631 | /* | 615 | |
| 632 | * Make efi_get_time can be called before entering | ||
| 633 | * virtual mode. | ||
| 634 | */ | ||
| 635 | efi.get_time = phys_efi_get_time; | ||
| 636 | early_iounmap(runtime, sizeof(efi_runtime_services_t)); | 616 | early_iounmap(runtime, sizeof(efi_runtime_services_t)); |
| 637 | 617 | ||
| 638 | return 0; | 618 | return 0; |
| @@ -720,12 +700,10 @@ void __init efi_init(void) | |||
| 720 | efi_enabled = 0; | 700 | efi_enabled = 0; |
| 721 | return; | 701 | return; |
| 722 | } | 702 | } |
| 723 | #ifdef CONFIG_X86_32 | ||
| 724 | if (efi_native) { | 703 | if (efi_native) { |
| 725 | x86_platform.get_wallclock = efi_get_time; | 704 | x86_platform.get_wallclock = efi_get_time; |
| 726 | x86_platform.set_wallclock = efi_set_rtc_mmss; | 705 | x86_platform.set_wallclock = efi_set_rtc_mmss; |
| 727 | } | 706 | } |
| 728 | #endif | ||
| 729 | 707 | ||
| 730 | #if EFI_DEBUG | 708 | #if EFI_DEBUG |
| 731 | print_efi_memmap(); | 709 | print_efi_memmap(); |
diff --git a/arch/x86/platform/uv/tlb_uv.c b/arch/x86/platform/uv/tlb_uv.c index 71b5d5a07d7b..b8b3a37c80cd 100644 --- a/arch/x86/platform/uv/tlb_uv.c +++ b/arch/x86/platform/uv/tlb_uv.c | |||
| @@ -1055,8 +1055,8 @@ static int set_distrib_bits(struct cpumask *flush_mask, struct bau_control *bcp, | |||
| 1055 | * done. The returned pointer is valid till preemption is re-enabled. | 1055 | * done. The returned pointer is valid till preemption is re-enabled. |
| 1056 | */ | 1056 | */ |
| 1057 | const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, | 1057 | const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, |
| 1058 | struct mm_struct *mm, unsigned long va, | 1058 | struct mm_struct *mm, unsigned long start, |
| 1059 | unsigned int cpu) | 1059 | unsigned end, unsigned int cpu) |
| 1060 | { | 1060 | { |
| 1061 | int locals = 0; | 1061 | int locals = 0; |
| 1062 | int remotes = 0; | 1062 | int remotes = 0; |
| @@ -1113,7 +1113,7 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, | |||
| 1113 | 1113 | ||
| 1114 | record_send_statistics(stat, locals, hubs, remotes, bau_desc); | 1114 | record_send_statistics(stat, locals, hubs, remotes, bau_desc); |
| 1115 | 1115 | ||
| 1116 | bau_desc->payload.address = va; | 1116 | bau_desc->payload.address = start; |
| 1117 | bau_desc->payload.sending_cpu = cpu; | 1117 | bau_desc->payload.sending_cpu = cpu; |
| 1118 | /* | 1118 | /* |
| 1119 | * uv_flush_send_and_wait returns 0 if all cpu's were messaged, | 1119 | * uv_flush_send_and_wait returns 0 if all cpu's were messaged, |
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index 27336dfcda8e..b65a76133f4f 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c | |||
| @@ -1256,7 +1256,8 @@ static void xen_flush_tlb_single(unsigned long addr) | |||
| 1256 | } | 1256 | } |
| 1257 | 1257 | ||
| 1258 | static void xen_flush_tlb_others(const struct cpumask *cpus, | 1258 | static void xen_flush_tlb_others(const struct cpumask *cpus, |
| 1259 | struct mm_struct *mm, unsigned long va) | 1259 | struct mm_struct *mm, unsigned long start, |
| 1260 | unsigned long end) | ||
| 1260 | { | 1261 | { |
| 1261 | struct { | 1262 | struct { |
| 1262 | struct mmuext_op op; | 1263 | struct mmuext_op op; |
| @@ -1268,7 +1269,7 @@ static void xen_flush_tlb_others(const struct cpumask *cpus, | |||
| 1268 | } *args; | 1269 | } *args; |
| 1269 | struct multicall_space mcs; | 1270 | struct multicall_space mcs; |
| 1270 | 1271 | ||
| 1271 | trace_xen_mmu_flush_tlb_others(cpus, mm, va); | 1272 | trace_xen_mmu_flush_tlb_others(cpus, mm, start, end); |
| 1272 | 1273 | ||
| 1273 | if (cpumask_empty(cpus)) | 1274 | if (cpumask_empty(cpus)) |
| 1274 | return; /* nothing to do */ | 1275 | return; /* nothing to do */ |
| @@ -1281,11 +1282,10 @@ static void xen_flush_tlb_others(const struct cpumask *cpus, | |||
| 1281 | cpumask_and(to_cpumask(args->mask), cpus, cpu_online_mask); | 1282 | cpumask_and(to_cpumask(args->mask), cpus, cpu_online_mask); |
| 1282 | cpumask_clear_cpu(smp_processor_id(), to_cpumask(args->mask)); | 1283 | cpumask_clear_cpu(smp_processor_id(), to_cpumask(args->mask)); |
| 1283 | 1284 | ||
| 1284 | if (va == TLB_FLUSH_ALL) { | 1285 | args->op.cmd = MMUEXT_TLB_FLUSH_MULTI; |
| 1285 | args->op.cmd = MMUEXT_TLB_FLUSH_MULTI; | 1286 | if (start != TLB_FLUSH_ALL && (end - start) <= PAGE_SIZE) { |
| 1286 | } else { | ||
| 1287 | args->op.cmd = MMUEXT_INVLPG_MULTI; | 1287 | args->op.cmd = MMUEXT_INVLPG_MULTI; |
| 1288 | args->op.arg1.linear_addr = va; | 1288 | args->op.arg1.linear_addr = start; |
| 1289 | } | 1289 | } |
| 1290 | 1290 | ||
| 1291 | MULTI_mmuext_op(mcs.mc, &args->op, 1, NULL, DOMID_SELF); | 1291 | MULTI_mmuext_op(mcs.mc, &args->op, 1, NULL, DOMID_SELF); |
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 8a3f8351f438..8ed64cfae4ff 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig | |||
| @@ -7,6 +7,7 @@ config ZONE_DMA | |||
| 7 | config XTENSA | 7 | config XTENSA |
| 8 | def_bool y | 8 | def_bool y |
| 9 | select HAVE_IDE | 9 | select HAVE_IDE |
| 10 | select GENERIC_ATOMIC64 | ||
| 10 | select HAVE_GENERIC_HARDIRQS | 11 | select HAVE_GENERIC_HARDIRQS |
| 11 | select GENERIC_IRQ_SHOW | 12 | select GENERIC_IRQ_SHOW |
| 12 | select GENERIC_CPU_DEVICES | 13 | select GENERIC_CPU_DEVICES |
diff --git a/arch/xtensa/include/asm/cpumask.h b/arch/xtensa/include/asm/cpumask.h deleted file mode 100644 index ebeede397db3..000000000000 --- a/arch/xtensa/include/asm/cpumask.h +++ /dev/null | |||
| @@ -1,16 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * include/asm-xtensa/cpumask.h | ||
| 3 | * | ||
| 4 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 5 | * License. See the file "COPYING" in the main directory of this archive | ||
| 6 | * for more details. | ||
| 7 | * | ||
| 8 | * Copyright (C) 2001 - 2005 Tensilica Inc. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #ifndef _XTENSA_CPUMASK_H | ||
| 12 | #define _XTENSA_CPUMASK_H | ||
| 13 | |||
| 14 | #include <asm-generic/cpumask.h> | ||
| 15 | |||
| 16 | #endif /* _XTENSA_CPUMASK_H */ | ||
diff --git a/arch/xtensa/include/asm/rmap.h b/arch/xtensa/include/asm/rmap.h deleted file mode 100644 index 649588b7e9ad..000000000000 --- a/arch/xtensa/include/asm/rmap.h +++ /dev/null | |||
| @@ -1,16 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * include/asm-xtensa/rmap.h | ||
| 3 | * | ||
| 4 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 5 | * License. See the file "COPYING" in the main directory of this archive | ||
| 6 | * for more details. | ||
| 7 | * | ||
| 8 | * Copyright (C) 2001 - 2005 Tensilica Inc. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #ifndef _XTENSA_RMAP_H | ||
| 12 | #define _XTENSA_RMAP_H | ||
| 13 | |||
| 14 | #include <asm-generic/rmap.h> | ||
| 15 | |||
| 16 | #endif | ||
diff --git a/arch/xtensa/kernel/syscall.c b/arch/xtensa/kernel/syscall.c index 816e6d0d686c..05b3f093d5d7 100644 --- a/arch/xtensa/kernel/syscall.c +++ b/arch/xtensa/kernel/syscall.c | |||
| @@ -44,7 +44,7 @@ asmlinkage long xtensa_shmat(int shmid, char __user *shmaddr, int shmflg) | |||
| 44 | unsigned long ret; | 44 | unsigned long ret; |
| 45 | long err; | 45 | long err; |
| 46 | 46 | ||
| 47 | err = do_shmat(shmid, shmaddr, shmflg, &ret); | 47 | err = do_shmat(shmid, shmaddr, shmflg, &ret, SHMLBA); |
| 48 | if (err) | 48 | if (err) |
| 49 | return err; | 49 | return err; |
| 50 | return (long)ret; | 50 | return (long)ret; |
diff --git a/arch/xtensa/mm/fault.c b/arch/xtensa/mm/fault.c index b17885a0b508..5a74c53bc69c 100644 --- a/arch/xtensa/mm/fault.c +++ b/arch/xtensa/mm/fault.c | |||
| @@ -44,6 +44,7 @@ void do_page_fault(struct pt_regs *regs) | |||
| 44 | 44 | ||
| 45 | int is_write, is_exec; | 45 | int is_write, is_exec; |
| 46 | int fault; | 46 | int fault; |
| 47 | unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; | ||
| 47 | 48 | ||
| 48 | info.si_code = SEGV_MAPERR; | 49 | info.si_code = SEGV_MAPERR; |
| 49 | 50 | ||
| @@ -71,6 +72,7 @@ void do_page_fault(struct pt_regs *regs) | |||
| 71 | address, exccause, regs->pc, is_write? "w":"", is_exec? "x":""); | 72 | address, exccause, regs->pc, is_write? "w":"", is_exec? "x":""); |
| 72 | #endif | 73 | #endif |
| 73 | 74 | ||
| 75 | retry: | ||
| 74 | down_read(&mm->mmap_sem); | 76 | down_read(&mm->mmap_sem); |
| 75 | vma = find_vma(mm, address); | 77 | vma = find_vma(mm, address); |
| 76 | 78 | ||
| @@ -93,6 +95,7 @@ good_area: | |||
| 93 | if (is_write) { | 95 | if (is_write) { |
| 94 | if (!(vma->vm_flags & VM_WRITE)) | 96 | if (!(vma->vm_flags & VM_WRITE)) |
| 95 | goto bad_area; | 97 | goto bad_area; |
| 98 | flags |= FAULT_FLAG_WRITE; | ||
| 96 | } else if (is_exec) { | 99 | } else if (is_exec) { |
| 97 | if (!(vma->vm_flags & VM_EXEC)) | 100 | if (!(vma->vm_flags & VM_EXEC)) |
| 98 | goto bad_area; | 101 | goto bad_area; |
| @@ -104,7 +107,11 @@ good_area: | |||
| 104 | * make sure we exit gracefully rather than endlessly redo | 107 | * make sure we exit gracefully rather than endlessly redo |
| 105 | * the fault. | 108 | * the fault. |
| 106 | */ | 109 | */ |
| 107 | fault = handle_mm_fault(mm, vma, address, is_write ? FAULT_FLAG_WRITE : 0); | 110 | fault = handle_mm_fault(mm, vma, address, flags); |
| 111 | |||
| 112 | if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) | ||
| 113 | return; | ||
| 114 | |||
| 108 | if (unlikely(fault & VM_FAULT_ERROR)) { | 115 | if (unlikely(fault & VM_FAULT_ERROR)) { |
| 109 | if (fault & VM_FAULT_OOM) | 116 | if (fault & VM_FAULT_OOM) |
| 110 | goto out_of_memory; | 117 | goto out_of_memory; |
| @@ -112,10 +119,22 @@ good_area: | |||
| 112 | goto do_sigbus; | 119 | goto do_sigbus; |
| 113 | BUG(); | 120 | BUG(); |
| 114 | } | 121 | } |
| 115 | if (fault & VM_FAULT_MAJOR) | 122 | if (flags & FAULT_FLAG_ALLOW_RETRY) { |
| 116 | current->maj_flt++; | 123 | if (fault & VM_FAULT_MAJOR) |
| 117 | else | 124 | current->maj_flt++; |
| 118 | current->min_flt++; | 125 | else |
| 126 | current->min_flt++; | ||
| 127 | if (fault & VM_FAULT_RETRY) { | ||
| 128 | flags &= ~FAULT_FLAG_ALLOW_RETRY; | ||
| 129 | |||
| 130 | /* No need to up_read(&mm->mmap_sem) as we would | ||
| 131 | * have already released it in __lock_page_or_retry | ||
| 132 | * in mm/filemap.c. | ||
| 133 | */ | ||
| 134 | |||
| 135 | goto retry; | ||
| 136 | } | ||
| 137 | } | ||
| 119 | 138 | ||
| 120 | up_read(&mm->mmap_sem); | 139 | up_read(&mm->mmap_sem); |
| 121 | return; | 140 | return; |
