diff options
Diffstat (limited to 'arch')
106 files changed, 2204 insertions, 575 deletions
diff --git a/arch/Kconfig b/arch/Kconfig index 54ffd0f9df21..8e9e3246b2b4 100644 --- a/arch/Kconfig +++ b/arch/Kconfig | |||
| @@ -113,6 +113,25 @@ config HAVE_EFFICIENT_UNALIGNED_ACCESS | |||
| 113 | See Documentation/unaligned-memory-access.txt for more | 113 | See Documentation/unaligned-memory-access.txt for more |
| 114 | information on the topic of unaligned memory accesses. | 114 | information on the topic of unaligned memory accesses. |
| 115 | 115 | ||
| 116 | config ARCH_USE_BUILTIN_BSWAP | ||
| 117 | bool | ||
| 118 | help | ||
| 119 | Modern versions of GCC (since 4.4) have builtin functions | ||
| 120 | for handling byte-swapping. Using these, instead of the old | ||
| 121 | inline assembler that the architecture code provides in the | ||
| 122 | __arch_bswapXX() macros, allows the compiler to see what's | ||
| 123 | happening and offers more opportunity for optimisation. In | ||
| 124 | particular, the compiler will be able to combine the byteswap | ||
| 125 | with a nearby load or store and use load-and-swap or | ||
| 126 | store-and-swap instructions if the architecture has them. It | ||
| 127 | should almost *never* result in code which is worse than the | ||
| 128 | hand-coded assembler in <asm/swab.h>. But just in case it | ||
| 129 | does, the use of the builtins is optional. | ||
| 130 | |||
| 131 | Any architecture with load-and-swap or store-and-swap | ||
| 132 | instructions should set this. And it shouldn't hurt to set it | ||
| 133 | on architectures that don't have such instructions. | ||
| 134 | |||
| 116 | config HAVE_SYSCALL_WRAPPERS | 135 | config HAVE_SYSCALL_WRAPPERS |
| 117 | bool | 136 | bool |
| 118 | 137 | ||
diff --git a/arch/arm/boot/dts/spear13xx.dtsi b/arch/arm/boot/dts/spear13xx.dtsi index 009096d1d2c3..b4ca60f4eb42 100644 --- a/arch/arm/boot/dts/spear13xx.dtsi +++ b/arch/arm/boot/dts/spear13xx.dtsi | |||
| @@ -73,7 +73,7 @@ | |||
| 73 | 400000 | 73 | 400000 |
| 74 | 500000 | 74 | 500000 |
| 75 | 600000 >; | 75 | 600000 >; |
| 76 | status = "disable"; | 76 | status = "disabled"; |
| 77 | }; | 77 | }; |
| 78 | 78 | ||
| 79 | ahb { | 79 | ahb { |
| @@ -118,15 +118,15 @@ | |||
| 118 | compatible = "st,spear600-fsmc-nand"; | 118 | compatible = "st,spear600-fsmc-nand"; |
| 119 | #address-cells = <1>; | 119 | #address-cells = <1>; |
| 120 | #size-cells = <1>; | 120 | #size-cells = <1>; |
| 121 | reg = <0xb0000000 0x1000 /* FSMC Register */ | 121 | reg = <0xb0000000 0x1000 /* FSMC Register*/ |
| 122 | 0xb0800000 0x0010>; /* NAND Base */ | 122 | 0xb0800000 0x0010 /* NAND Base DATA */ |
| 123 | reg-names = "fsmc_regs", "nand_data"; | 123 | 0xb0820000 0x0010 /* NAND Base ADDR */ |
| 124 | 0xb0810000 0x0010>; /* NAND Base CMD */ | ||
| 125 | reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd"; | ||
| 124 | interrupts = <0 20 0x4 | 126 | interrupts = <0 20 0x4 |
| 125 | 0 21 0x4 | 127 | 0 21 0x4 |
| 126 | 0 22 0x4 | 128 | 0 22 0x4 |
| 127 | 0 23 0x4>; | 129 | 0 23 0x4>; |
| 128 | st,ale-off = <0x20000>; | ||
| 129 | st,cle-off = <0x10000>; | ||
| 130 | st,mode = <2>; | 130 | st,mode = <2>; |
| 131 | status = "disabled"; | 131 | status = "disabled"; |
| 132 | }; | 132 | }; |
| @@ -144,7 +144,7 @@ | |||
| 144 | compatible = "st,pcm-audio"; | 144 | compatible = "st,pcm-audio"; |
| 145 | #address-cells = <0>; | 145 | #address-cells = <0>; |
| 146 | #size-cells = <0>; | 146 | #size-cells = <0>; |
| 147 | status = "disable"; | 147 | status = "disabled"; |
| 148 | }; | 148 | }; |
| 149 | 149 | ||
| 150 | smi: flash@ea000000 { | 150 | smi: flash@ea000000 { |
diff --git a/arch/arm/boot/dts/spear300.dtsi b/arch/arm/boot/dts/spear300.dtsi index 090adc656015..f79b3dfaabe6 100644 --- a/arch/arm/boot/dts/spear300.dtsi +++ b/arch/arm/boot/dts/spear300.dtsi | |||
| @@ -38,10 +38,10 @@ | |||
| 38 | #address-cells = <1>; | 38 | #address-cells = <1>; |
| 39 | #size-cells = <1>; | 39 | #size-cells = <1>; |
| 40 | reg = <0x94000000 0x1000 /* FSMC Register */ | 40 | reg = <0x94000000 0x1000 /* FSMC Register */ |
| 41 | 0x80000000 0x0010>; /* NAND Base */ | 41 | 0x80000000 0x0010 /* NAND Base DATA */ |
| 42 | reg-names = "fsmc_regs", "nand_data"; | 42 | 0x80020000 0x0010 /* NAND Base ADDR */ |
| 43 | st,ale-off = <0x20000>; | 43 | 0x80010000 0x0010>; /* NAND Base CMD */ |
| 44 | st,cle-off = <0x10000>; | 44 | reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd"; |
| 45 | status = "disabled"; | 45 | status = "disabled"; |
| 46 | }; | 46 | }; |
| 47 | 47 | ||
diff --git a/arch/arm/boot/dts/spear310.dtsi b/arch/arm/boot/dts/spear310.dtsi index e814e5e97083..ab45b8c81982 100644 --- a/arch/arm/boot/dts/spear310.dtsi +++ b/arch/arm/boot/dts/spear310.dtsi | |||
| @@ -33,10 +33,10 @@ | |||
| 33 | #address-cells = <1>; | 33 | #address-cells = <1>; |
| 34 | #size-cells = <1>; | 34 | #size-cells = <1>; |
| 35 | reg = <0x44000000 0x1000 /* FSMC Register */ | 35 | reg = <0x44000000 0x1000 /* FSMC Register */ |
| 36 | 0x40000000 0x0010>; /* NAND Base */ | 36 | 0x40000000 0x0010 /* NAND Base DATA */ |
| 37 | reg-names = "fsmc_regs", "nand_data"; | 37 | 0x40020000 0x0010 /* NAND Base ADDR */ |
| 38 | st,ale-off = <0x10000>; | 38 | 0x40010000 0x0010>; /* NAND Base CMD */ |
| 39 | st,cle-off = <0x20000>; | 39 | reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd"; |
| 40 | status = "disabled"; | 40 | status = "disabled"; |
| 41 | }; | 41 | }; |
| 42 | 42 | ||
diff --git a/arch/arm/boot/dts/spear320.dtsi b/arch/arm/boot/dts/spear320.dtsi index c056a84deabf..caa5520b1fd4 100644 --- a/arch/arm/boot/dts/spear320.dtsi +++ b/arch/arm/boot/dts/spear320.dtsi | |||
| @@ -40,10 +40,10 @@ | |||
| 40 | #address-cells = <1>; | 40 | #address-cells = <1>; |
| 41 | #size-cells = <1>; | 41 | #size-cells = <1>; |
| 42 | reg = <0x4c000000 0x1000 /* FSMC Register */ | 42 | reg = <0x4c000000 0x1000 /* FSMC Register */ |
| 43 | 0x50000000 0x0010>; /* NAND Base */ | 43 | 0x50000000 0x0010 /* NAND Base DATA */ |
| 44 | reg-names = "fsmc_regs", "nand_data"; | 44 | 0x50020000 0x0010 /* NAND Base ADDR */ |
| 45 | st,ale-off = <0x20000>; | 45 | 0x50010000 0x0010>; /* NAND Base CMD */ |
| 46 | st,cle-off = <0x10000>; | 46 | reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd"; |
| 47 | status = "disabled"; | 47 | status = "disabled"; |
| 48 | }; | 48 | }; |
| 49 | 49 | ||
diff --git a/arch/arm/boot/dts/spear600.dtsi b/arch/arm/boot/dts/spear600.dtsi index e051dde5181f..19f99dc4115e 100644 --- a/arch/arm/boot/dts/spear600.dtsi +++ b/arch/arm/boot/dts/spear600.dtsi | |||
| @@ -76,10 +76,10 @@ | |||
| 76 | #address-cells = <1>; | 76 | #address-cells = <1>; |
| 77 | #size-cells = <1>; | 77 | #size-cells = <1>; |
| 78 | reg = <0xd1800000 0x1000 /* FSMC Register */ | 78 | reg = <0xd1800000 0x1000 /* FSMC Register */ |
| 79 | 0xd2000000 0x4000>; /* NAND Base */ | 79 | 0xd2000000 0x0010 /* NAND Base DATA */ |
| 80 | reg-names = "fsmc_regs", "nand_data"; | 80 | 0xd2020000 0x0010 /* NAND Base ADDR */ |
| 81 | st,ale-off = <0x20000>; | 81 | 0xd2010000 0x0010>; /* NAND Base CMD */ |
| 82 | st,cle-off = <0x10000>; | 82 | reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd"; |
| 83 | status = "disabled"; | 83 | status = "disabled"; |
| 84 | }; | 84 | }; |
| 85 | 85 | ||
diff --git a/arch/arm/configs/nhk8815_defconfig b/arch/arm/configs/nhk8815_defconfig index 240b25eea565..86cfd2959c47 100644 --- a/arch/arm/configs/nhk8815_defconfig +++ b/arch/arm/configs/nhk8815_defconfig | |||
| @@ -57,7 +57,7 @@ CONFIG_MTD_CHAR=y | |||
| 57 | CONFIG_MTD_BLOCK=y | 57 | CONFIG_MTD_BLOCK=y |
| 58 | CONFIG_MTD_NAND=y | 58 | CONFIG_MTD_NAND=y |
| 59 | CONFIG_MTD_NAND_ECC_SMC=y | 59 | CONFIG_MTD_NAND_ECC_SMC=y |
| 60 | CONFIG_MTD_NAND_NOMADIK=y | 60 | CONFIG_MTD_NAND_FSMC=y |
| 61 | CONFIG_MTD_ONENAND=y | 61 | CONFIG_MTD_ONENAND=y |
| 62 | CONFIG_MTD_ONENAND_VERIFY_WRITE=y | 62 | CONFIG_MTD_ONENAND_VERIFY_WRITE=y |
| 63 | CONFIG_MTD_ONENAND_GENERIC=y | 63 | CONFIG_MTD_ONENAND_GENERIC=y |
diff --git a/arch/arm/include/uapi/asm/unistd.h b/arch/arm/include/uapi/asm/unistd.h index ac03bdb4ae44..4da7cde70b5d 100644 --- a/arch/arm/include/uapi/asm/unistd.h +++ b/arch/arm/include/uapi/asm/unistd.h | |||
| @@ -405,6 +405,7 @@ | |||
| 405 | #define __NR_process_vm_readv (__NR_SYSCALL_BASE+376) | 405 | #define __NR_process_vm_readv (__NR_SYSCALL_BASE+376) |
| 406 | #define __NR_process_vm_writev (__NR_SYSCALL_BASE+377) | 406 | #define __NR_process_vm_writev (__NR_SYSCALL_BASE+377) |
| 407 | /* 378 for kcmp */ | 407 | /* 378 for kcmp */ |
| 408 | #define __NR_finit_module (__NR_SYSCALL_BASE+379) | ||
| 408 | 409 | ||
| 409 | /* | 410 | /* |
| 410 | * This may need to be greater than __NR_last_syscall+1 in order to | 411 | * This may need to be greater than __NR_last_syscall+1 in order to |
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S index 5935b6a02e6e..a4fda4e7a372 100644 --- a/arch/arm/kernel/calls.S +++ b/arch/arm/kernel/calls.S | |||
| @@ -388,6 +388,7 @@ | |||
| 388 | CALL(sys_process_vm_readv) | 388 | CALL(sys_process_vm_readv) |
| 389 | CALL(sys_process_vm_writev) | 389 | CALL(sys_process_vm_writev) |
| 390 | CALL(sys_ni_syscall) /* reserved for sys_kcmp */ | 390 | CALL(sys_ni_syscall) /* reserved for sys_kcmp */ |
| 391 | CALL(sys_finit_module) | ||
| 391 | #ifndef syscalls_counted | 392 | #ifndef syscalls_counted |
| 392 | .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls | 393 | .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls |
| 393 | #define syscalls_counted | 394 | #define syscalls_counted |
diff --git a/arch/arm/mach-nomadik/board-nhk8815.c b/arch/arm/mach-nomadik/board-nhk8815.c index 5ccdf53c5a9d..98167a4319f7 100644 --- a/arch/arm/mach-nomadik/board-nhk8815.c +++ b/arch/arm/mach-nomadik/board-nhk8815.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <linux/gpio.h> | 19 | #include <linux/gpio.h> |
| 20 | #include <linux/mtd/mtd.h> | 20 | #include <linux/mtd/mtd.h> |
| 21 | #include <linux/mtd/nand.h> | 21 | #include <linux/mtd/nand.h> |
| 22 | #include <linux/mtd/fsmc.h> | ||
| 22 | #include <linux/mtd/onenand.h> | 23 | #include <linux/mtd/onenand.h> |
| 23 | #include <linux/mtd/partitions.h> | 24 | #include <linux/mtd/partitions.h> |
| 24 | #include <linux/i2c.h> | 25 | #include <linux/i2c.h> |
| @@ -33,7 +34,6 @@ | |||
| 33 | #include <asm/mach/arch.h> | 34 | #include <asm/mach/arch.h> |
| 34 | #include <asm/mach/flash.h> | 35 | #include <asm/mach/flash.h> |
| 35 | #include <asm/mach/time.h> | 36 | #include <asm/mach/time.h> |
| 36 | #include <mach/fsmc.h> | ||
| 37 | #include <mach/irqs.h> | 37 | #include <mach/irqs.h> |
| 38 | 38 | ||
| 39 | #include "cpu-8815.h" | 39 | #include "cpu-8815.h" |
| @@ -42,39 +42,34 @@ | |||
| 42 | #define SRC_CR_INIT_MASK 0x00007fff | 42 | #define SRC_CR_INIT_MASK 0x00007fff |
| 43 | #define SRC_CR_INIT_VAL 0x2aaa8000 | 43 | #define SRC_CR_INIT_VAL 0x2aaa8000 |
| 44 | 44 | ||
| 45 | #define ALE_OFF 0x1000000 | ||
| 46 | #define CLE_OFF 0x800000 | ||
| 47 | |||
| 45 | /* These addresses span 16MB, so use three individual pages */ | 48 | /* These addresses span 16MB, so use three individual pages */ |
| 46 | static struct resource nhk8815_nand_resources[] = { | 49 | static struct resource nhk8815_nand_resources[] = { |
| 47 | { | 50 | { |
| 51 | .name = "nand_data", | ||
| 52 | .start = 0x40000000, | ||
| 53 | .end = 0x40000000 + SZ_16K - 1, | ||
| 54 | .flags = IORESOURCE_MEM, | ||
| 55 | }, { | ||
| 48 | .name = "nand_addr", | 56 | .name = "nand_addr", |
| 49 | .start = NAND_IO_ADDR, | 57 | .start = 0x40000000 + ALE_OFF, |
| 50 | .end = NAND_IO_ADDR + 0xfff, | 58 | .end = 0x40000000 +ALE_OFF + SZ_16K - 1, |
| 51 | .flags = IORESOURCE_MEM, | 59 | .flags = IORESOURCE_MEM, |
| 52 | }, { | 60 | }, { |
| 53 | .name = "nand_cmd", | 61 | .name = "nand_cmd", |
| 54 | .start = NAND_IO_CMD, | 62 | .start = 0x40000000 + CLE_OFF, |
| 55 | .end = NAND_IO_CMD + 0xfff, | 63 | .end = 0x40000000 + CLE_OFF + SZ_16K - 1, |
| 56 | .flags = IORESOURCE_MEM, | 64 | .flags = IORESOURCE_MEM, |
| 57 | }, { | 65 | }, { |
| 58 | .name = "nand_data", | 66 | .name = "fsmc_regs", |
| 59 | .start = NAND_IO_DATA, | 67 | .start = NOMADIK_FSMC_BASE, |
| 60 | .end = NAND_IO_DATA + 0xfff, | 68 | .end = NOMADIK_FSMC_BASE + SZ_4K - 1, |
| 61 | .flags = IORESOURCE_MEM, | 69 | .flags = IORESOURCE_MEM, |
| 62 | } | 70 | }, |
| 63 | }; | 71 | }; |
| 64 | 72 | ||
| 65 | static int nhk8815_nand_init(void) | ||
| 66 | { | ||
| 67 | /* FSMC setup for nand chip select (8-bit nand in 8815NHK) */ | ||
| 68 | writel(0x0000000E, FSMC_PCR(0)); | ||
| 69 | writel(0x000D0A00, FSMC_PMEM(0)); | ||
| 70 | writel(0x00100A00, FSMC_PATT(0)); | ||
| 71 | |||
| 72 | /* enable access to the chip select area */ | ||
| 73 | writel(readl(FSMC_PCR(0)) | 0x04, FSMC_PCR(0)); | ||
| 74 | |||
| 75 | return 0; | ||
| 76 | } | ||
| 77 | |||
| 78 | /* | 73 | /* |
| 79 | * These partitions are the same as those used in the 2.6.20 release | 74 | * These partitions are the same as those used in the 2.6.20 release |
| 80 | * shipped by the vendor; the first two partitions are mandated | 75 | * shipped by the vendor; the first two partitions are mandated |
| @@ -108,20 +103,28 @@ static struct mtd_partition nhk8815_partitions[] = { | |||
| 108 | } | 103 | } |
| 109 | }; | 104 | }; |
| 110 | 105 | ||
| 111 | static struct nomadik_nand_platform_data nhk8815_nand_data = { | 106 | static struct fsmc_nand_timings nhk8815_nand_timings = { |
| 112 | .parts = nhk8815_partitions, | 107 | .thiz = 0, |
| 113 | .nparts = ARRAY_SIZE(nhk8815_partitions), | 108 | .thold = 0x10, |
| 114 | .options = NAND_COPYBACK | NAND_CACHEPRG | NAND_NO_PADDING, | 109 | .twait = 0x0A, |
| 115 | .init = nhk8815_nand_init, | 110 | .tset = 0, |
| 111 | }; | ||
| 112 | |||
| 113 | static struct fsmc_nand_platform_data nhk8815_nand_platform_data = { | ||
| 114 | .nand_timings = &nhk8815_nand_timings, | ||
| 115 | .partitions = nhk8815_partitions, | ||
| 116 | .nr_partitions = ARRAY_SIZE(nhk8815_partitions), | ||
| 117 | .width = FSMC_NAND_BW8, | ||
| 116 | }; | 118 | }; |
| 117 | 119 | ||
| 118 | static struct platform_device nhk8815_nand_device = { | 120 | static struct platform_device nhk8815_nand_device = { |
| 119 | .name = "nomadik_nand", | 121 | .name = "fsmc-nand", |
| 120 | .dev = { | 122 | .id = -1, |
| 121 | .platform_data = &nhk8815_nand_data, | 123 | .resource = nhk8815_nand_resources, |
| 124 | .num_resources = ARRAY_SIZE(nhk8815_nand_resources), | ||
| 125 | .dev = { | ||
| 126 | .platform_data = &nhk8815_nand_platform_data, | ||
| 122 | }, | 127 | }, |
| 123 | .resource = nhk8815_nand_resources, | ||
| 124 | .num_resources = ARRAY_SIZE(nhk8815_nand_resources), | ||
| 125 | }; | 128 | }; |
| 126 | 129 | ||
| 127 | /* These are the partitions for the OneNand device, different from above */ | 130 | /* These are the partitions for the OneNand device, different from above */ |
| @@ -176,6 +179,10 @@ static struct platform_device nhk8815_onenand_device = { | |||
| 176 | .num_resources = ARRAY_SIZE(nhk8815_onenand_resource), | 179 | .num_resources = ARRAY_SIZE(nhk8815_onenand_resource), |
| 177 | }; | 180 | }; |
| 178 | 181 | ||
| 182 | /* bus control reg. and bus timing reg. for CS0..CS3 */ | ||
| 183 | #define FSMC_BCR(x) (NOMADIK_FSMC_VA + (x << 3)) | ||
| 184 | #define FSMC_BTR(x) (NOMADIK_FSMC_VA + (x << 3) + 0x04) | ||
| 185 | |||
| 179 | static void __init nhk8815_onenand_init(void) | 186 | static void __init nhk8815_onenand_init(void) |
| 180 | { | 187 | { |
| 181 | #ifdef CONFIG_MTD_ONENAND | 188 | #ifdef CONFIG_MTD_ONENAND |
diff --git a/arch/arm/mach-nomadik/include/mach/fsmc.h b/arch/arm/mach-nomadik/include/mach/fsmc.h deleted file mode 100644 index 8c2c05183685..000000000000 --- a/arch/arm/mach-nomadik/include/mach/fsmc.h +++ /dev/null | |||
| @@ -1,29 +0,0 @@ | |||
| 1 | |||
| 2 | /* Definitions for the Nomadik FSMC "Flexible Static Memory controller" */ | ||
| 3 | |||
| 4 | #ifndef __ASM_ARCH_FSMC_H | ||
| 5 | #define __ASM_ARCH_FSMC_H | ||
| 6 | |||
| 7 | #include <mach/hardware.h> | ||
| 8 | /* | ||
| 9 | * Register list | ||
| 10 | */ | ||
| 11 | |||
| 12 | /* bus control reg. and bus timing reg. for CS0..CS3 */ | ||
| 13 | #define FSMC_BCR(x) (NOMADIK_FSMC_VA + (x << 3)) | ||
| 14 | #define FSMC_BTR(x) (NOMADIK_FSMC_VA + (x << 3) + 0x04) | ||
| 15 | |||
| 16 | /* PC-card and NAND: | ||
| 17 | * PCR = control register | ||
| 18 | * PMEM = memory timing | ||
| 19 | * PATT = attribute timing | ||
| 20 | * PIO = I/O timing | ||
| 21 | * PECCR = ECC result | ||
| 22 | */ | ||
| 23 | #define FSMC_PCR(x) (NOMADIK_FSMC_VA + ((2 + x) << 5) + 0x00) | ||
| 24 | #define FSMC_PMEM(x) (NOMADIK_FSMC_VA + ((2 + x) << 5) + 0x08) | ||
| 25 | #define FSMC_PATT(x) (NOMADIK_FSMC_VA + ((2 + x) << 5) + 0x0c) | ||
| 26 | #define FSMC_PIO(x) (NOMADIK_FSMC_VA + ((2 + x) << 5) + 0x10) | ||
| 27 | #define FSMC_PECCR(x) (NOMADIK_FSMC_VA + ((2 + x) << 5) + 0x14) | ||
| 28 | |||
| 29 | #endif /* __ASM_ARCH_FSMC_H */ | ||
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c index 60529e0b3d67..cf07e289b4ea 100644 --- a/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c | |||
| @@ -256,6 +256,11 @@ static struct spi_board_info rx51_peripherals_spi_board_info[] __initdata = { | |||
| 256 | }, | 256 | }, |
| 257 | }; | 257 | }; |
| 258 | 258 | ||
| 259 | static struct platform_device rx51_battery_device = { | ||
| 260 | .name = "rx51-battery", | ||
| 261 | .id = -1, | ||
| 262 | }; | ||
| 263 | |||
| 259 | static void rx51_charger_set_power(bool on) | 264 | static void rx51_charger_set_power(bool on) |
| 260 | { | 265 | { |
| 261 | gpio_set_value(RX51_USB_TRANSCEIVER_RST_GPIO, on); | 266 | gpio_set_value(RX51_USB_TRANSCEIVER_RST_GPIO, on); |
| @@ -277,6 +282,7 @@ static void __init rx51_charger_init(void) | |||
| 277 | WARN_ON(gpio_request_one(RX51_USB_TRANSCEIVER_RST_GPIO, | 282 | WARN_ON(gpio_request_one(RX51_USB_TRANSCEIVER_RST_GPIO, |
| 278 | GPIOF_OUT_INIT_HIGH, "isp1704_reset")); | 283 | GPIOF_OUT_INIT_HIGH, "isp1704_reset")); |
| 279 | 284 | ||
| 285 | platform_device_register(&rx51_battery_device); | ||
| 280 | platform_device_register(&rx51_charger_device); | 286 | platform_device_register(&rx51_charger_device); |
| 281 | } | 287 | } |
| 282 | 288 | ||
diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c index 12f3994c43db..8b204ae69002 100644 --- a/arch/arm/mach-u300/core.c +++ b/arch/arm/mach-u300/core.c | |||
| @@ -250,6 +250,18 @@ static struct resource rtc_resources[] = { | |||
| 250 | */ | 250 | */ |
| 251 | static struct resource fsmc_resources[] = { | 251 | static struct resource fsmc_resources[] = { |
| 252 | { | 252 | { |
| 253 | .name = "nand_addr", | ||
| 254 | .start = U300_NAND_CS0_PHYS_BASE + PLAT_NAND_ALE, | ||
| 255 | .end = U300_NAND_CS0_PHYS_BASE + PLAT_NAND_ALE + SZ_16K - 1, | ||
| 256 | .flags = IORESOURCE_MEM, | ||
| 257 | }, | ||
| 258 | { | ||
| 259 | .name = "nand_cmd", | ||
| 260 | .start = U300_NAND_CS0_PHYS_BASE + PLAT_NAND_CLE, | ||
| 261 | .end = U300_NAND_CS0_PHYS_BASE + PLAT_NAND_CLE + SZ_16K - 1, | ||
| 262 | .flags = IORESOURCE_MEM, | ||
| 263 | }, | ||
| 264 | { | ||
| 253 | .name = "nand_data", | 265 | .name = "nand_data", |
| 254 | .start = U300_NAND_CS0_PHYS_BASE, | 266 | .start = U300_NAND_CS0_PHYS_BASE, |
| 255 | .end = U300_NAND_CS0_PHYS_BASE + SZ_16K - 1, | 267 | .end = U300_NAND_CS0_PHYS_BASE + SZ_16K - 1, |
| @@ -1492,8 +1504,6 @@ static struct fsmc_nand_platform_data nand_platform_data = { | |||
| 1492 | .nr_partitions = ARRAY_SIZE(u300_partitions), | 1504 | .nr_partitions = ARRAY_SIZE(u300_partitions), |
| 1493 | .options = NAND_SKIP_BBTSCAN, | 1505 | .options = NAND_SKIP_BBTSCAN, |
| 1494 | .width = FSMC_NAND_BW8, | 1506 | .width = FSMC_NAND_BW8, |
| 1495 | .ale_off = PLAT_NAND_ALE, | ||
| 1496 | .cle_off = PLAT_NAND_CLE, | ||
| 1497 | }; | 1507 | }; |
| 1498 | 1508 | ||
| 1499 | static struct platform_device nand_device = { | 1509 | static struct platform_device nand_device = { |
diff --git a/arch/cris/kernel/module.c b/arch/cris/kernel/module.c index 37400f5869e6..51123f985eb5 100644 --- a/arch/cris/kernel/module.c +++ b/arch/cris/kernel/module.c | |||
| @@ -32,8 +32,6 @@ | |||
| 32 | #ifdef CONFIG_ETRAX_KMALLOCED_MODULES | 32 | #ifdef CONFIG_ETRAX_KMALLOCED_MODULES |
| 33 | void *module_alloc(unsigned long size) | 33 | void *module_alloc(unsigned long size) |
| 34 | { | 34 | { |
| 35 | if (size == 0) | ||
| 36 | return NULL; | ||
| 37 | return kmalloc(size, GFP_KERNEL); | 35 | return kmalloc(size, GFP_KERNEL); |
| 38 | } | 36 | } |
| 39 | 37 | ||
diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c index 5e34ccf39a49..2a625fb063e1 100644 --- a/arch/parisc/kernel/module.c +++ b/arch/parisc/kernel/module.c | |||
| @@ -214,8 +214,6 @@ static inline int reassemble_22(int as22) | |||
| 214 | 214 | ||
| 215 | void *module_alloc(unsigned long size) | 215 | void *module_alloc(unsigned long size) |
| 216 | { | 216 | { |
| 217 | if (size == 0) | ||
| 218 | return NULL; | ||
| 219 | /* using RWX means less protection for modules, but it's | 217 | /* using RWX means less protection for modules, but it's |
| 220 | * easier than trying to map the text, data, init_text and | 218 | * easier than trying to map the text, data, init_text and |
| 221 | * init_data correctly */ | 219 | * init_data correctly */ |
diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h index cec8aae5cbf8..97909d3b1d7b 100644 --- a/arch/powerpc/include/asm/systbl.h +++ b/arch/powerpc/include/asm/systbl.h | |||
| @@ -356,3 +356,4 @@ COMPAT_SYS_SPU(sendmmsg) | |||
| 356 | SYSCALL_SPU(setns) | 356 | SYSCALL_SPU(setns) |
| 357 | COMPAT_SYS(process_vm_readv) | 357 | COMPAT_SYS(process_vm_readv) |
| 358 | COMPAT_SYS(process_vm_writev) | 358 | COMPAT_SYS(process_vm_writev) |
| 359 | SYSCALL(finit_module) | ||
diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h index bcbbe413c606..29365e15ed7c 100644 --- a/arch/powerpc/include/asm/unistd.h +++ b/arch/powerpc/include/asm/unistd.h | |||
| @@ -12,7 +12,7 @@ | |||
| 12 | #include <uapi/asm/unistd.h> | 12 | #include <uapi/asm/unistd.h> |
| 13 | 13 | ||
| 14 | 14 | ||
| 15 | #define __NR_syscalls 353 | 15 | #define __NR_syscalls 354 |
| 16 | 16 | ||
| 17 | #define __NR__exit __NR_exit | 17 | #define __NR__exit __NR_exit |
| 18 | #define NR_syscalls __NR_syscalls | 18 | #define NR_syscalls __NR_syscalls |
diff --git a/arch/powerpc/include/uapi/asm/unistd.h b/arch/powerpc/include/uapi/asm/unistd.h index 380b5d37a904..8c478c6c6b1e 100644 --- a/arch/powerpc/include/uapi/asm/unistd.h +++ b/arch/powerpc/include/uapi/asm/unistd.h | |||
| @@ -375,6 +375,7 @@ | |||
| 375 | #define __NR_setns 350 | 375 | #define __NR_setns 350 |
| 376 | #define __NR_process_vm_readv 351 | 376 | #define __NR_process_vm_readv 351 |
| 377 | #define __NR_process_vm_writev 352 | 377 | #define __NR_process_vm_writev 352 |
| 378 | #define __NR_finit_module 353 | ||
| 378 | 379 | ||
| 379 | 380 | ||
| 380 | #endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */ | 381 | #endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */ |
diff --git a/arch/sparc/kernel/module.c b/arch/sparc/kernel/module.c index f1ddc0d23679..4435488ebe25 100644 --- a/arch/sparc/kernel/module.c +++ b/arch/sparc/kernel/module.c | |||
| @@ -43,10 +43,6 @@ void *module_alloc(unsigned long size) | |||
| 43 | { | 43 | { |
| 44 | void *ret; | 44 | void *ret; |
| 45 | 45 | ||
| 46 | /* We handle the zero case fine, unlike vmalloc */ | ||
| 47 | if (size == 0) | ||
| 48 | return NULL; | ||
| 49 | |||
| 50 | ret = module_map(size); | 46 | ret = module_map(size); |
| 51 | if (ret) | 47 | if (ret) |
| 52 | memset(ret, 0, size); | 48 | memset(ret, 0, size); |
diff --git a/arch/tile/kernel/module.c b/arch/tile/kernel/module.c index 243ffebe38d6..4918d91bc3a6 100644 --- a/arch/tile/kernel/module.c +++ b/arch/tile/kernel/module.c | |||
| @@ -42,8 +42,6 @@ void *module_alloc(unsigned long size) | |||
| 42 | int i = 0; | 42 | int i = 0; |
| 43 | int npages; | 43 | int npages; |
| 44 | 44 | ||
| 45 | if (size == 0) | ||
| 46 | return NULL; | ||
| 47 | npages = (size + PAGE_SIZE - 1) / PAGE_SIZE; | 45 | npages = (size + PAGE_SIZE - 1) / PAGE_SIZE; |
| 48 | pages = kmalloc(npages * sizeof(struct page *), GFP_KERNEL); | 46 | pages = kmalloc(npages * sizeof(struct page *), GFP_KERNEL); |
| 49 | if (pages == NULL) | 47 | if (pages == NULL) |
diff --git a/arch/unicore32/kernel/module.c b/arch/unicore32/kernel/module.c index 8fbe8577f5e6..16bd1495b934 100644 --- a/arch/unicore32/kernel/module.c +++ b/arch/unicore32/kernel/module.c | |||
| @@ -27,9 +27,6 @@ void *module_alloc(unsigned long size) | |||
| 27 | struct vm_struct *area; | 27 | struct vm_struct *area; |
| 28 | 28 | ||
| 29 | size = PAGE_ALIGN(size); | 29 | size = PAGE_ALIGN(size); |
| 30 | if (!size) | ||
| 31 | return NULL; | ||
| 32 | |||
| 33 | area = __get_vm_area(size, VM_ALLOC, MODULES_VADDR, MODULES_END); | 30 | area = __get_vm_area(size, VM_ALLOC, MODULES_VADDR, MODULES_END); |
| 34 | if (!area) | 31 | if (!area) |
| 35 | return NULL; | 32 | return NULL; |
diff --git a/arch/x86/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c index fbd895562292..3286a92e662a 100644 --- a/arch/x86/kernel/cpu/proc.c +++ b/arch/x86/kernel/cpu/proc.c | |||
| @@ -26,11 +26,6 @@ static void show_cpuinfo_core(struct seq_file *m, struct cpuinfo_x86 *c, | |||
| 26 | #ifdef CONFIG_X86_32 | 26 | #ifdef CONFIG_X86_32 |
| 27 | static void show_cpuinfo_misc(struct seq_file *m, struct cpuinfo_x86 *c) | 27 | static void show_cpuinfo_misc(struct seq_file *m, struct cpuinfo_x86 *c) |
| 28 | { | 28 | { |
| 29 | /* | ||
| 30 | * We use exception 16 if we have hardware math and we've either seen | ||
| 31 | * it or the CPU claims it is internal | ||
| 32 | */ | ||
| 33 | int fpu_exception = c->hard_math && (ignore_fpu_irq || cpu_has_fpu); | ||
| 34 | seq_printf(m, | 29 | seq_printf(m, |
| 35 | "fdiv_bug\t: %s\n" | 30 | "fdiv_bug\t: %s\n" |
| 36 | "hlt_bug\t\t: %s\n" | 31 | "hlt_bug\t\t: %s\n" |
| @@ -45,7 +40,7 @@ static void show_cpuinfo_misc(struct seq_file *m, struct cpuinfo_x86 *c) | |||
| 45 | c->f00f_bug ? "yes" : "no", | 40 | c->f00f_bug ? "yes" : "no", |
| 46 | c->coma_bug ? "yes" : "no", | 41 | c->coma_bug ? "yes" : "no", |
| 47 | c->hard_math ? "yes" : "no", | 42 | c->hard_math ? "yes" : "no", |
| 48 | fpu_exception ? "yes" : "no", | 43 | c->hard_math ? "yes" : "no", |
| 49 | c->cpuid_level, | 44 | c->cpuid_level, |
| 50 | c->wp_works_ok ? "yes" : "no"); | 45 | c->wp_works_ok ? "yes" : "no"); |
| 51 | } | 46 | } |
diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c index 6e03b0d69138..7dc4e459c2b3 100644 --- a/arch/x86/kernel/irqinit.c +++ b/arch/x86/kernel/irqinit.c | |||
| @@ -42,39 +42,6 @@ | |||
| 42 | * (these are usually mapped into the 0x30-0xff vector range) | 42 | * (these are usually mapped into the 0x30-0xff vector range) |
| 43 | */ | 43 | */ |
| 44 | 44 | ||
| 45 | #ifdef CONFIG_X86_32 | ||
| 46 | /* | ||
| 47 | * Note that on a 486, we don't want to do a SIGFPE on an irq13 | ||
| 48 | * as the irq is unreliable, and exception 16 works correctly | ||
| 49 | * (ie as explained in the intel literature). On a 386, you | ||
| 50 | * can't use exception 16 due to bad IBM design, so we have to | ||
| 51 | * rely on the less exact irq13. | ||
| 52 | * | ||
| 53 | * Careful.. Not only is IRQ13 unreliable, but it is also | ||
| 54 | * leads to races. IBM designers who came up with it should | ||
| 55 | * be shot. | ||
| 56 | */ | ||
| 57 | |||
| 58 | static irqreturn_t math_error_irq(int cpl, void *dev_id) | ||
| 59 | { | ||
| 60 | outb(0, 0xF0); | ||
| 61 | if (ignore_fpu_irq || !boot_cpu_data.hard_math) | ||
| 62 | return IRQ_NONE; | ||
| 63 | math_error(get_irq_regs(), 0, X86_TRAP_MF); | ||
| 64 | return IRQ_HANDLED; | ||
| 65 | } | ||
| 66 | |||
| 67 | /* | ||
| 68 | * New motherboards sometimes make IRQ 13 be a PCI interrupt, | ||
| 69 | * so allow interrupt sharing. | ||
| 70 | */ | ||
| 71 | static struct irqaction fpu_irq = { | ||
| 72 | .handler = math_error_irq, | ||
| 73 | .name = "fpu", | ||
| 74 | .flags = IRQF_NO_THREAD, | ||
| 75 | }; | ||
| 76 | #endif | ||
| 77 | |||
| 78 | /* | 45 | /* |
| 79 | * IRQ2 is cascade interrupt to second interrupt controller | 46 | * IRQ2 is cascade interrupt to second interrupt controller |
| 80 | */ | 47 | */ |
| @@ -242,13 +209,6 @@ void __init native_init_IRQ(void) | |||
| 242 | setup_irq(2, &irq2); | 209 | setup_irq(2, &irq2); |
| 243 | 210 | ||
| 244 | #ifdef CONFIG_X86_32 | 211 | #ifdef CONFIG_X86_32 |
| 245 | /* | ||
| 246 | * External FPU? Set up irq13 if so, for | ||
| 247 | * original braindamaged IBM FERR coupling. | ||
| 248 | */ | ||
| 249 | if (boot_cpu_data.hard_math && !cpu_has_fpu) | ||
| 250 | setup_irq(FPU_IRQ, &fpu_irq); | ||
| 251 | |||
| 252 | irq_ctx_init(smp_processor_id()); | 212 | irq_ctx_init(smp_processor_id()); |
| 253 | #endif | 213 | #endif |
| 254 | } | 214 | } |
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index eb8586693e0b..ecffca11f4e9 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c | |||
| @@ -69,9 +69,6 @@ | |||
| 69 | 69 | ||
| 70 | asmlinkage int system_call(void); | 70 | asmlinkage int system_call(void); |
| 71 | 71 | ||
| 72 | /* Do we ignore FPU interrupts ? */ | ||
| 73 | char ignore_fpu_irq; | ||
| 74 | |||
| 75 | /* | 72 | /* |
| 76 | * The IDT has to be page-aligned to simplify the Pentium | 73 | * The IDT has to be page-aligned to simplify the Pentium |
| 77 | * F0 0F bug workaround. | 74 | * F0 0F bug workaround. |
| @@ -564,9 +561,6 @@ void math_error(struct pt_regs *regs, int error_code, int trapnr) | |||
| 564 | 561 | ||
| 565 | dotraplinkage void do_coprocessor_error(struct pt_regs *regs, long error_code) | 562 | dotraplinkage void do_coprocessor_error(struct pt_regs *regs, long error_code) |
| 566 | { | 563 | { |
| 567 | #ifdef CONFIG_X86_32 | ||
| 568 | ignore_fpu_irq = 1; | ||
| 569 | #endif | ||
| 570 | exception_enter(regs); | 564 | exception_enter(regs); |
| 571 | math_error(regs, error_code, X86_TRAP_MF); | 565 | math_error(regs, error_code, X86_TRAP_MF); |
| 572 | exception_exit(regs); | 566 | exception_exit(regs); |
diff --git a/arch/x86/syscalls/syscall_32.tbl b/arch/x86/syscalls/syscall_32.tbl index ee3c220ee500..05f404f53f59 100644 --- a/arch/x86/syscalls/syscall_32.tbl +++ b/arch/x86/syscalls/syscall_32.tbl | |||
| @@ -356,3 +356,4 @@ | |||
| 356 | 347 i386 process_vm_readv sys_process_vm_readv compat_sys_process_vm_readv | 356 | 347 i386 process_vm_readv sys_process_vm_readv compat_sys_process_vm_readv |
| 357 | 348 i386 process_vm_writev sys_process_vm_writev compat_sys_process_vm_writev | 357 | 348 i386 process_vm_writev sys_process_vm_writev compat_sys_process_vm_writev |
| 358 | 349 i386 kcmp sys_kcmp | 358 | 349 i386 kcmp sys_kcmp |
| 359 | 350 i386 finit_module sys_finit_module | ||
diff --git a/arch/x86/syscalls/syscall_64.tbl b/arch/x86/syscalls/syscall_64.tbl index a582bfed95bb..7c58c84b7bc8 100644 --- a/arch/x86/syscalls/syscall_64.tbl +++ b/arch/x86/syscalls/syscall_64.tbl | |||
| @@ -319,6 +319,7 @@ | |||
| 319 | 310 64 process_vm_readv sys_process_vm_readv | 319 | 310 64 process_vm_readv sys_process_vm_readv |
| 320 | 311 64 process_vm_writev sys_process_vm_writev | 320 | 311 64 process_vm_writev sys_process_vm_writev |
| 321 | 312 common kcmp sys_kcmp | 321 | 312 common kcmp sys_kcmp |
| 322 | 313 common finit_module sys_finit_module | ||
| 322 | 323 | ||
| 323 | # | 324 | # |
| 324 | # x32-specific system call numbers start at 512 to avoid cache impact | 325 | # x32-specific system call numbers start at 512 to avoid cache impact |
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 2481f267be29..73d34e77c39c 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig | |||
| @@ -17,6 +17,7 @@ config XTENSA | |||
| 17 | select GENERIC_KERNEL_EXECVE | 17 | select GENERIC_KERNEL_EXECVE |
| 18 | select ARCH_WANT_OPTIONAL_GPIOLIB | 18 | select ARCH_WANT_OPTIONAL_GPIOLIB |
| 19 | select CLONE_BACKWARDS | 19 | select CLONE_BACKWARDS |
| 20 | select IRQ_DOMAIN | ||
| 20 | help | 21 | help |
| 21 | Xtensa processors are 32-bit RISC machines designed by Tensilica | 22 | Xtensa processors are 32-bit RISC machines designed by Tensilica |
| 22 | primarily for embedded systems. These processors are both | 23 | primarily for embedded systems. These processors are both |
| @@ -150,6 +151,15 @@ config XTENSA_PLATFORM_S6105 | |||
| 150 | select SERIAL_CONSOLE | 151 | select SERIAL_CONSOLE |
| 151 | select NO_IOPORT | 152 | select NO_IOPORT |
| 152 | 153 | ||
| 154 | config XTENSA_PLATFORM_XTFPGA | ||
| 155 | bool "XTFPGA" | ||
| 156 | select SERIAL_CONSOLE | ||
| 157 | select ETHOC | ||
| 158 | select XTENSA_CALIBRATE_CCOUNT | ||
| 159 | help | ||
| 160 | XTFPGA is the name of Tensilica board family (LX60, LX110, LX200, ML605). | ||
| 161 | This hardware is capable of running a full Linux distribution. | ||
| 162 | |||
| 153 | endchoice | 163 | endchoice |
| 154 | 164 | ||
| 155 | 165 | ||
| @@ -177,6 +187,17 @@ config CMDLINE | |||
| 177 | time by entering them here. As a minimum, you should specify the | 187 | time by entering them here. As a minimum, you should specify the |
| 178 | memory size and the root device (e.g., mem=64M root=/dev/nfs). | 188 | memory size and the root device (e.g., mem=64M root=/dev/nfs). |
| 179 | 189 | ||
| 190 | config USE_OF | ||
| 191 | bool "Flattened Device Tree support" | ||
| 192 | select OF | ||
| 193 | select OF_EARLY_FLATTREE | ||
| 194 | help | ||
| 195 | Include support for flattened device tree machine descriptions. | ||
| 196 | |||
| 197 | config BUILTIN_DTB | ||
| 198 | string "DTB to build into the kernel image" | ||
| 199 | depends on OF | ||
| 200 | |||
| 180 | source "mm/Kconfig" | 201 | source "mm/Kconfig" |
| 181 | 202 | ||
| 182 | source "drivers/pcmcia/Kconfig" | 203 | source "drivers/pcmcia/Kconfig" |
diff --git a/arch/xtensa/Kconfig.debug b/arch/xtensa/Kconfig.debug index 11c585295dd7..a34010e0e51c 100644 --- a/arch/xtensa/Kconfig.debug +++ b/arch/xtensa/Kconfig.debug | |||
| @@ -2,6 +2,26 @@ menu "Kernel hacking" | |||
| 2 | 2 | ||
| 3 | source "lib/Kconfig.debug" | 3 | source "lib/Kconfig.debug" |
| 4 | 4 | ||
| 5 | endmenu | 5 | config LD_NO_RELAX |
| 6 | bool "Disable linker relaxation" | ||
| 7 | default n | ||
| 8 | help | ||
| 9 | Enable this function to disable link-time optimizations. | ||
| 10 | The default linker behavior is to combine identical literal | ||
| 11 | values to reduce code size and remove unnecessary overhead from | ||
| 12 | assembler-generated 'longcall' sequences. | ||
| 13 | Enabling this option improves the link time but increases the | ||
| 14 | code size, and possibly execution time. | ||
| 15 | |||
| 16 | config S32C1I_SELFTEST | ||
| 17 | bool "Perform S32C1I instruction self-test at boot" | ||
| 18 | default y | ||
| 19 | help | ||
| 20 | Enable this option to test S32C1I instruction behavior at boot. | ||
| 21 | Correct operation of this instruction requires some cooperation from hardware | ||
| 22 | external to the processor (such as bus bridge, bus fabric, or memory controller). | ||
| 23 | It is easy to make wrong hardware configuration, this test should catch it early. | ||
| 6 | 24 | ||
| 25 | Say 'N' on stable hardware. | ||
| 7 | 26 | ||
| 27 | endmenu | ||
diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile index bb5ba61723f7..0aa72702f179 100644 --- a/arch/xtensa/Makefile +++ b/arch/xtensa/Makefile | |||
| @@ -38,6 +38,7 @@ endif | |||
| 38 | platform-$(CONFIG_XTENSA_PLATFORM_XT2000) := xt2000 | 38 | platform-$(CONFIG_XTENSA_PLATFORM_XT2000) := xt2000 |
| 39 | platform-$(CONFIG_XTENSA_PLATFORM_ISS) := iss | 39 | platform-$(CONFIG_XTENSA_PLATFORM_ISS) := iss |
| 40 | platform-$(CONFIG_XTENSA_PLATFORM_S6105) := s6105 | 40 | platform-$(CONFIG_XTENSA_PLATFORM_S6105) := s6105 |
| 41 | platform-$(CONFIG_XTENSA_PLATFORM_XTFPGA) := xtfpga | ||
| 41 | 42 | ||
| 42 | PLATFORM = $(platform-y) | 43 | PLATFORM = $(platform-y) |
| 43 | export PLATFORM | 44 | export PLATFORM |
| @@ -49,6 +50,17 @@ KBUILD_CFLAGS += -pipe -mlongcalls | |||
| 49 | 50 | ||
| 50 | KBUILD_CFLAGS += $(call cc-option,-mforce-no-pic,) | 51 | KBUILD_CFLAGS += $(call cc-option,-mforce-no-pic,) |
| 51 | 52 | ||
| 53 | ifneq ($(CONFIG_LD_NO_RELAX),) | ||
| 54 | LDFLAGS := --no-relax | ||
| 55 | endif | ||
| 56 | |||
| 57 | ifeq ($(shell echo -e __XTENSA_EB__ | $(CC) -E - | grep -v "\#"),1) | ||
| 58 | CHECKFLAGS += -D__XTENSA_EB__ | ||
| 59 | endif | ||
| 60 | ifeq ($(shell echo -e __XTENSA_EL__ | $(CC) -E - | grep -v "\#"),1) | ||
| 61 | CHECKFLAGS += -D__XTENSA_EL__ | ||
| 62 | endif | ||
| 63 | |||
| 52 | vardirs := $(patsubst %,arch/xtensa/variants/%/,$(variant-y)) | 64 | vardirs := $(patsubst %,arch/xtensa/variants/%/,$(variant-y)) |
| 53 | plfdirs := $(patsubst %,arch/xtensa/platforms/%/,$(platform-y)) | 65 | plfdirs := $(patsubst %,arch/xtensa/platforms/%/,$(platform-y)) |
| 54 | 66 | ||
| @@ -75,6 +87,10 @@ core-y += $(buildvar) $(buildplf) | |||
| 75 | 87 | ||
| 76 | libs-y += arch/xtensa/lib/ $(LIBGCC) | 88 | libs-y += arch/xtensa/lib/ $(LIBGCC) |
| 77 | 89 | ||
| 90 | ifneq ($(CONFIG_BUILTIN_DTB),"") | ||
| 91 | core-$(CONFIG_OF) += arch/xtensa/boot/ | ||
| 92 | endif | ||
| 93 | |||
| 78 | boot := arch/xtensa/boot | 94 | boot := arch/xtensa/boot |
| 79 | 95 | ||
| 80 | all: zImage | 96 | all: zImage |
| @@ -84,7 +100,9 @@ bzImage : zImage | |||
| 84 | zImage: vmlinux | 100 | zImage: vmlinux |
| 85 | $(Q)$(MAKE) $(build)=$(boot) $@ | 101 | $(Q)$(MAKE) $(build)=$(boot) $@ |
| 86 | 102 | ||
| 103 | %.dtb: | ||
| 104 | $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ | ||
| 105 | |||
| 87 | define archhelp | 106 | define archhelp |
| 88 | @echo '* zImage - Compressed kernel image (arch/xtensa/boot/images/zImage.*)' | 107 | @echo '* zImage - Compressed kernel image (arch/xtensa/boot/images/zImage.*)' |
| 89 | endef | 108 | endef |
| 90 | |||
diff --git a/arch/xtensa/boot/Makefile b/arch/xtensa/boot/Makefile index 4018f8994196..818647e815d7 100644 --- a/arch/xtensa/boot/Makefile +++ b/arch/xtensa/boot/Makefile | |||
| @@ -22,12 +22,35 @@ subdir-y := lib | |||
| 22 | # Subdirs for the boot loader(s) | 22 | # Subdirs for the boot loader(s) |
| 23 | 23 | ||
| 24 | bootdir-$(CONFIG_XTENSA_PLATFORM_ISS) += boot-elf | 24 | bootdir-$(CONFIG_XTENSA_PLATFORM_ISS) += boot-elf |
| 25 | bootdir-$(CONFIG_XTENSA_PLATFORM_XT2000) += boot-redboot boot-elf | 25 | bootdir-$(CONFIG_XTENSA_PLATFORM_XT2000) += boot-redboot boot-elf boot-uboot |
| 26 | bootdir-$(CONFIG_XTENSA_PLATFORM_XTFPGA) += boot-redboot boot-elf boot-uboot | ||
| 26 | 27 | ||
| 27 | 28 | ||
| 29 | BUILTIN_DTB := $(patsubst "%",%,$(CONFIG_BUILTIN_DTB)).dtb.o | ||
| 30 | ifneq ($(CONFIG_BUILTIN_DTB),"") | ||
| 31 | obj-$(CONFIG_OF) += $(BUILTIN_DTB) | ||
| 32 | endif | ||
| 33 | |||
| 34 | # Rule to build device tree blobs | ||
| 35 | $(obj)/%.dtb: $(src)/dts/%.dts FORCE | ||
| 36 | $(call if_changed_dep,dtc) | ||
| 37 | |||
| 38 | clean-files := *.dtb.S | ||
| 39 | |||
| 28 | zImage Image: $(bootdir-y) | 40 | zImage Image: $(bootdir-y) |
| 29 | 41 | ||
| 30 | $(bootdir-y): $(addprefix $(obj)/,$(subdir-y)) \ | 42 | $(bootdir-y): $(addprefix $(obj)/,$(subdir-y)) \ |
| 31 | $(addprefix $(obj)/,$(host-progs)) | 43 | $(addprefix $(obj)/,$(host-progs)) |
| 32 | $(Q)$(MAKE) $(build)=$(obj)/$@ $(MAKECMDGOALS) | 44 | $(Q)$(MAKE) $(build)=$(obj)/$@ $(MAKECMDGOALS) |
| 33 | 45 | ||
| 46 | OBJCOPYFLAGS = --strip-all -R .comment -R .note.gnu.build-id -O binary | ||
| 47 | |||
| 48 | vmlinux.bin: vmlinux FORCE | ||
| 49 | $(call if_changed,objcopy) | ||
| 50 | |||
| 51 | vmlinux.bin.gz: vmlinux.bin FORCE | ||
| 52 | $(call if_changed,gzip) | ||
| 53 | |||
| 54 | boot-elf: vmlinux.bin | ||
| 55 | boot-redboot: vmlinux.bin.gz | ||
| 56 | boot-uboot: vmlinux.bin.gz | ||
diff --git a/arch/xtensa/boot/boot-elf/Makefile b/arch/xtensa/boot/boot-elf/Makefile index f10992b89027..1fe01b78c124 100644 --- a/arch/xtensa/boot/boot-elf/Makefile +++ b/arch/xtensa/boot/boot-elf/Makefile | |||
| @@ -4,9 +4,6 @@ | |||
| 4 | # for more details. | 4 | # for more details. |
| 5 | # | 5 | # |
| 6 | 6 | ||
| 7 | GZIP = gzip | ||
| 8 | GZIP_FLAGS = -v9fc | ||
| 9 | |||
| 10 | ifeq ($(BIG_ENDIAN),1) | 7 | ifeq ($(BIG_ENDIAN),1) |
| 11 | OBJCOPY_ARGS := -O elf32-xtensa-be | 8 | OBJCOPY_ARGS := -O elf32-xtensa-be |
| 12 | else | 9 | else |
| @@ -20,18 +17,17 @@ boot-y := bootstrap.o | |||
| 20 | 17 | ||
| 21 | OBJS := $(addprefix $(obj)/,$(boot-y)) | 18 | OBJS := $(addprefix $(obj)/,$(boot-y)) |
| 22 | 19 | ||
| 23 | vmlinux.tmp: vmlinux | 20 | $(obj)/Image.o: vmlinux.bin $(OBJS) |
| 24 | $(OBJCOPY) --strip-all -R .comment -R .note.gnu.build-id -O binary \ | 21 | $(Q)$(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ |
| 25 | $^ $@ | 22 | --add-section image=vmlinux.bin \ |
| 26 | |||
| 27 | Image: vmlinux.tmp $(OBJS) arch/$(ARCH)/boot/boot-elf/boot.lds | ||
| 28 | $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ | ||
| 29 | --add-section image=vmlinux.tmp \ | ||
| 30 | --set-section-flags image=contents,alloc,load,load,data \ | 23 | --set-section-flags image=contents,alloc,load,load,data \ |
| 31 | $(OBJS) $@.tmp | 24 | $(OBJS) $@ |
| 32 | $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) \ | ||
| 33 | -T arch/$(ARCH)/boot/boot-elf/boot.lds \ | ||
| 34 | -o arch/$(ARCH)/boot/$@.elf $@.tmp | ||
| 35 | 25 | ||
| 36 | zImage: Image | 26 | $(obj)/../Image.elf: $(obj)/Image.o $(obj)/boot.lds |
| 27 | $(Q)$(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) \ | ||
| 28 | -T $(obj)/boot.lds \ | ||
| 29 | --build-id=none \ | ||
| 30 | -o $@ $(obj)/Image.o | ||
| 31 | $(Q)$(kecho) ' Kernel: $@ is ready' | ||
| 37 | 32 | ||
| 33 | zImage: $(obj)/../Image.elf | ||
diff --git a/arch/xtensa/boot/boot-redboot/Makefile b/arch/xtensa/boot/boot-redboot/Makefile index 25a78c6b1530..8be8b9436981 100644 --- a/arch/xtensa/boot/boot-redboot/Makefile +++ b/arch/xtensa/boot/boot-redboot/Makefile | |||
| @@ -4,8 +4,6 @@ | |||
| 4 | # for more details. | 4 | # for more details. |
| 5 | # | 5 | # |
| 6 | 6 | ||
| 7 | GZIP = gzip | ||
| 8 | GZIP_FLAGS = -v9fc | ||
| 9 | ifeq ($(BIG_ENDIAN),1) | 7 | ifeq ($(BIG_ENDIAN),1) |
| 10 | OBJCOPY_ARGS := -O elf32-xtensa-be | 8 | OBJCOPY_ARGS := -O elf32-xtensa-be |
| 11 | else | 9 | else |
| @@ -21,17 +19,17 @@ LIBS := arch/xtensa/boot/lib/lib.a arch/xtensa/lib/lib.a | |||
| 21 | 19 | ||
| 22 | LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name) | 20 | LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name) |
| 23 | 21 | ||
| 24 | vmlinux.tmp: vmlinux | 22 | $(obj)/zImage.o: vmlinux.bin.gz $(OBJS) |
| 25 | $(OBJCOPY) --strip-all -R .comment -R .note.gnu.build-id -O binary \ | 23 | $(Q)$(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ |
| 26 | $^ $@ | 24 | --add-section image=vmlinux.bin.gz \ |
| 25 | --set-section-flags image=contents,alloc,load,load,data \ | ||
| 26 | $(OBJS) $@ | ||
| 27 | 27 | ||
| 28 | vmlinux.tmp.gz: vmlinux.tmp | 28 | $(obj)/zImage.elf: $(obj)/zImage.o $(LIBS) |
| 29 | $(GZIP) $(GZIP_FLAGS) $^ > $@ | 29 | $(Q)$(LD) $(LD_ARGS) -o $@ $^ -L/xtensa-elf/lib $(LIBGCC) |
| 30 | 30 | ||
| 31 | zImage: vmlinux.tmp.gz $(OBJS) $(LIBS) | 31 | $(obj)/../zImage.redboot: $(obj)/zImage.elf |
| 32 | $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ | 32 | $(Q)$(OBJCOPY) -S -O binary $< $@ |
| 33 | --add-section image=vmlinux.tmp.gz \ | 33 | $(Q)$(kecho) ' Kernel: $@ is ready' |
| 34 | --set-section-flags image=contents,alloc,load,load,data \ | 34 | |
| 35 | $(OBJS) $@.tmp | 35 | zImage: $(obj)/../zImage.redboot |
| 36 | $(LD) $(LD_ARGS) -o $@.elf $@.tmp $(LIBS) -L/xtensa-elf/lib $(LIBGCC) | ||
| 37 | $(OBJCOPY) -S -O binary $@.elf arch/$(ARCH)/boot/$@.redboot | ||
diff --git a/arch/xtensa/boot/boot-uboot/Makefile b/arch/xtensa/boot/boot-uboot/Makefile new file mode 100644 index 000000000000..bfbf8af582f1 --- /dev/null +++ b/arch/xtensa/boot/boot-uboot/Makefile | |||
| @@ -0,0 +1,14 @@ | |||
| 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 | |||
| 7 | UIMAGE_LOADADDR = 0xd0001000 | ||
| 8 | UIMAGE_COMPRESSION = gzip | ||
| 9 | |||
| 10 | $(obj)/../uImage: vmlinux.bin.gz FORCE | ||
| 11 | $(call if_changed,uimage) | ||
| 12 | $(Q)$(kecho) ' Kernel: $@ is ready' | ||
| 13 | |||
| 14 | zImage: $(obj)/../uImage | ||
diff --git a/arch/xtensa/boot/dts/lx60.dts b/arch/xtensa/boot/dts/lx60.dts new file mode 100644 index 000000000000..2eab3658e1bd --- /dev/null +++ b/arch/xtensa/boot/dts/lx60.dts | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | /dts-v1/; | ||
| 2 | /include/ "xtfpga.dtsi" | ||
| 3 | /include/ "xtfpga-flash-4m.dtsi" | ||
| 4 | |||
| 5 | / { | ||
| 6 | compatible = "xtensa,lx60"; | ||
| 7 | memory@0 { | ||
| 8 | device_type = "memory"; | ||
| 9 | reg = <0x00000000 0x04000000>; | ||
| 10 | }; | ||
| 11 | }; | ||
diff --git a/arch/xtensa/boot/dts/ml605.dts b/arch/xtensa/boot/dts/ml605.dts new file mode 100644 index 000000000000..6ed51d6554e6 --- /dev/null +++ b/arch/xtensa/boot/dts/ml605.dts | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | /dts-v1/; | ||
| 2 | /include/ "xtfpga.dtsi" | ||
| 3 | /include/ "xtfpga-flash-16m.dtsi" | ||
| 4 | |||
| 5 | / { | ||
| 6 | compatible = "xtensa,ml605"; | ||
| 7 | memory@0 { | ||
| 8 | device_type = "memory"; | ||
| 9 | reg = <0x00000000 0x08000000>; | ||
| 10 | }; | ||
| 11 | }; | ||
diff --git a/arch/xtensa/boot/dts/xtfpga-flash-16m.dtsi b/arch/xtensa/boot/dts/xtfpga-flash-16m.dtsi new file mode 100644 index 000000000000..e5703c7beeb6 --- /dev/null +++ b/arch/xtensa/boot/dts/xtfpga-flash-16m.dtsi | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | / { | ||
| 2 | flash: flash@f8000000 { | ||
| 3 | #address-cells = <1>; | ||
| 4 | #size-cells = <1>; | ||
| 5 | compatible = "cfi-flash"; | ||
| 6 | reg = <0xf8000000 0x01000000>; | ||
| 7 | bank-width = <2>; | ||
| 8 | device-width = <2>; | ||
| 9 | partition@0x0 { | ||
| 10 | label = "boot loader area"; | ||
| 11 | reg = <0x00000000 0x00400000>; | ||
| 12 | }; | ||
| 13 | partition@0x400000 { | ||
| 14 | label = "kernel image"; | ||
| 15 | reg = <0x00400000 0x00600000>; | ||
| 16 | }; | ||
| 17 | partition@0xa00000 { | ||
| 18 | label = "data"; | ||
| 19 | reg = <0x00a00000 0x005e0000>; | ||
| 20 | }; | ||
| 21 | partition@0xfe0000 { | ||
| 22 | label = "boot environment"; | ||
| 23 | reg = <0x00fe0000 0x00020000>; | ||
| 24 | }; | ||
| 25 | }; | ||
| 26 | }; | ||
diff --git a/arch/xtensa/boot/dts/xtfpga-flash-4m.dtsi b/arch/xtensa/boot/dts/xtfpga-flash-4m.dtsi new file mode 100644 index 000000000000..6f9c10d6b689 --- /dev/null +++ b/arch/xtensa/boot/dts/xtfpga-flash-4m.dtsi | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | / { | ||
| 2 | flash: flash@f8000000 { | ||
| 3 | #address-cells = <1>; | ||
| 4 | #size-cells = <1>; | ||
| 5 | compatible = "cfi-flash"; | ||
| 6 | reg = <0xf8000000 0x00400000>; | ||
| 7 | bank-width = <2>; | ||
| 8 | device-width = <2>; | ||
| 9 | partition@0x0 { | ||
| 10 | label = "boot loader area"; | ||
| 11 | reg = <0x00000000 0x003f0000>; | ||
| 12 | }; | ||
| 13 | partition@0x3f0000 { | ||
| 14 | label = "boot environment"; | ||
| 15 | reg = <0x003f0000 0x00010000>; | ||
| 16 | }; | ||
| 17 | }; | ||
| 18 | }; | ||
diff --git a/arch/xtensa/boot/dts/xtfpga.dtsi b/arch/xtensa/boot/dts/xtfpga.dtsi new file mode 100644 index 000000000000..7eda6ecf7eef --- /dev/null +++ b/arch/xtensa/boot/dts/xtfpga.dtsi | |||
| @@ -0,0 +1,56 @@ | |||
| 1 | / { | ||
| 2 | compatible = "xtensa,xtfpga"; | ||
| 3 | #address-cells = <1>; | ||
| 4 | #size-cells = <1>; | ||
| 5 | interrupt-parent = <&pic>; | ||
| 6 | |||
| 7 | chosen { | ||
| 8 | bootargs = "earlycon=uart8250,mmio32,0xfd050020,115200n8 console=ttyS0,115200n8 ip=dhcp root=/dev/nfs rw debug"; | ||
| 9 | }; | ||
| 10 | |||
| 11 | memory@0 { | ||
| 12 | device_type = "memory"; | ||
| 13 | reg = <0x00000000 0x06000000>; | ||
| 14 | }; | ||
| 15 | |||
| 16 | cpus { | ||
| 17 | #address-cells = <1>; | ||
| 18 | #size-cells = <0>; | ||
| 19 | cpu@0 { | ||
| 20 | compatible = "xtensa,cpu"; | ||
| 21 | reg = <0>; | ||
| 22 | /* Filled in by platform_setup from FPGA register | ||
| 23 | * clock-frequency = <100000000>; | ||
| 24 | */ | ||
| 25 | }; | ||
| 26 | }; | ||
| 27 | |||
| 28 | pic: pic { | ||
| 29 | compatible = "xtensa,pic"; | ||
| 30 | /* one cell: internal irq number, | ||
| 31 | * two cells: second cell == 0: internal irq number | ||
| 32 | * second cell == 1: external irq number | ||
| 33 | */ | ||
| 34 | #interrupt-cells = <2>; | ||
| 35 | interrupt-controller; | ||
| 36 | }; | ||
| 37 | |||
| 38 | serial0: serial@fd050020 { | ||
| 39 | device_type = "serial"; | ||
| 40 | compatible = "ns16550a"; | ||
| 41 | no-loopback-test; | ||
| 42 | reg = <0xfd050020 0x20>; | ||
| 43 | reg-shift = <2>; | ||
| 44 | interrupts = <0 1>; /* external irq 0 */ | ||
| 45 | /* Filled in by platform_setup from FPGA register | ||
| 46 | * clock-frequency = <100000000>; | ||
| 47 | */ | ||
| 48 | }; | ||
| 49 | |||
| 50 | enet0: ethoc@fd030000 { | ||
| 51 | compatible = "opencores,ethoc"; | ||
| 52 | reg = <0xfd030000 0x4000 0xfd800000 0x4000>; | ||
| 53 | interrupts = <1 1>; /* external irq 1 */ | ||
| 54 | local-mac-address = [00 50 c2 13 6f 00]; | ||
| 55 | }; | ||
| 56 | }; | ||
diff --git a/arch/xtensa/include/asm/atomic.h b/arch/xtensa/include/asm/atomic.h index 24f50cada70c..c3f289174c10 100644 --- a/arch/xtensa/include/asm/atomic.h +++ b/arch/xtensa/include/asm/atomic.h | |||
| @@ -66,19 +66,35 @@ | |||
| 66 | */ | 66 | */ |
| 67 | static inline void atomic_add(int i, atomic_t * v) | 67 | static inline void atomic_add(int i, atomic_t * v) |
| 68 | { | 68 | { |
| 69 | unsigned int vval; | 69 | #if XCHAL_HAVE_S32C1I |
| 70 | 70 | unsigned long tmp; | |
| 71 | __asm__ __volatile__( | 71 | int result; |
| 72 | "rsil a15, "__stringify(LOCKLEVEL)"\n\t" | 72 | |
| 73 | "l32i %0, %2, 0 \n\t" | 73 | __asm__ __volatile__( |
| 74 | "add %0, %0, %1 \n\t" | 74 | "1: l32i %1, %3, 0\n" |
| 75 | "s32i %0, %2, 0 \n\t" | 75 | " wsr %1, scompare1\n" |
| 76 | "wsr a15, ps \n\t" | 76 | " add %0, %1, %2\n" |
| 77 | "rsync \n" | 77 | " s32c1i %0, %3, 0\n" |
| 78 | : "=&a" (vval) | 78 | " bne %0, %1, 1b\n" |
| 79 | : "a" (i), "a" (v) | 79 | : "=&a" (result), "=&a" (tmp) |
| 80 | : "a15", "memory" | 80 | : "a" (i), "a" (v) |
| 81 | ); | 81 | : "memory" |
| 82 | ); | ||
| 83 | #else | ||
| 84 | unsigned int vval; | ||
| 85 | |||
| 86 | __asm__ __volatile__( | ||
| 87 | " rsil a15, "__stringify(LOCKLEVEL)"\n" | ||
| 88 | " l32i %0, %2, 0\n" | ||
| 89 | " add %0, %0, %1\n" | ||
| 90 | " s32i %0, %2, 0\n" | ||
| 91 | " wsr a15, ps\n" | ||
| 92 | " rsync\n" | ||
| 93 | : "=&a" (vval) | ||
| 94 | : "a" (i), "a" (v) | ||
| 95 | : "a15", "memory" | ||
| 96 | ); | ||
| 97 | #endif | ||
| 82 | } | 98 | } |
| 83 | 99 | ||
| 84 | /** | 100 | /** |
| @@ -90,19 +106,35 @@ static inline void atomic_add(int i, atomic_t * v) | |||
| 90 | */ | 106 | */ |
| 91 | static inline void atomic_sub(int i, atomic_t *v) | 107 | static inline void atomic_sub(int i, atomic_t *v) |
| 92 | { | 108 | { |
| 93 | unsigned int vval; | 109 | #if XCHAL_HAVE_S32C1I |
| 94 | 110 | unsigned long tmp; | |
| 95 | __asm__ __volatile__( | 111 | int result; |
| 96 | "rsil a15, "__stringify(LOCKLEVEL)"\n\t" | 112 | |
| 97 | "l32i %0, %2, 0 \n\t" | 113 | __asm__ __volatile__( |
| 98 | "sub %0, %0, %1 \n\t" | 114 | "1: l32i %1, %3, 0\n" |
| 99 | "s32i %0, %2, 0 \n\t" | 115 | " wsr %1, scompare1\n" |
| 100 | "wsr a15, ps \n\t" | 116 | " sub %0, %1, %2\n" |
| 101 | "rsync \n" | 117 | " s32c1i %0, %3, 0\n" |
| 102 | : "=&a" (vval) | 118 | " bne %0, %1, 1b\n" |
| 103 | : "a" (i), "a" (v) | 119 | : "=&a" (result), "=&a" (tmp) |
| 104 | : "a15", "memory" | 120 | : "a" (i), "a" (v) |
| 105 | ); | 121 | : "memory" |
| 122 | ); | ||
| 123 | #else | ||
| 124 | unsigned int vval; | ||
| 125 | |||
| 126 | __asm__ __volatile__( | ||
| 127 | " rsil a15, "__stringify(LOCKLEVEL)"\n" | ||
| 128 | " l32i %0, %2, 0\n" | ||
| 129 | " sub %0, %0, %1\n" | ||
| 130 | " s32i %0, %2, 0\n" | ||
| 131 | " wsr a15, ps\n" | ||
| 132 | " rsync\n" | ||
| 133 | : "=&a" (vval) | ||
| 134 | : "a" (i), "a" (v) | ||
| 135 | : "a15", "memory" | ||
| 136 | ); | ||
| 137 | #endif | ||
| 106 | } | 138 | } |
| 107 | 139 | ||
| 108 | /* | 140 | /* |
| @@ -111,40 +143,78 @@ static inline void atomic_sub(int i, atomic_t *v) | |||
| 111 | 143 | ||
| 112 | static inline int atomic_add_return(int i, atomic_t * v) | 144 | static inline int atomic_add_return(int i, atomic_t * v) |
| 113 | { | 145 | { |
| 114 | unsigned int vval; | 146 | #if XCHAL_HAVE_S32C1I |
| 115 | 147 | unsigned long tmp; | |
| 116 | __asm__ __volatile__( | 148 | int result; |
| 117 | "rsil a15,"__stringify(LOCKLEVEL)"\n\t" | 149 | |
| 118 | "l32i %0, %2, 0 \n\t" | 150 | __asm__ __volatile__( |
| 119 | "add %0, %0, %1 \n\t" | 151 | "1: l32i %1, %3, 0\n" |
| 120 | "s32i %0, %2, 0 \n\t" | 152 | " wsr %1, scompare1\n" |
| 121 | "wsr a15, ps \n\t" | 153 | " add %0, %1, %2\n" |
| 122 | "rsync \n" | 154 | " s32c1i %0, %3, 0\n" |
| 123 | : "=&a" (vval) | 155 | " bne %0, %1, 1b\n" |
| 124 | : "a" (i), "a" (v) | 156 | " add %0, %0, %2\n" |
| 125 | : "a15", "memory" | 157 | : "=&a" (result), "=&a" (tmp) |
| 126 | ); | 158 | : "a" (i), "a" (v) |
| 127 | 159 | : "memory" | |
| 128 | return vval; | 160 | ); |
| 161 | |||
| 162 | return result; | ||
| 163 | #else | ||
| 164 | unsigned int vval; | ||
| 165 | |||
| 166 | __asm__ __volatile__( | ||
| 167 | " rsil a15,"__stringify(LOCKLEVEL)"\n" | ||
| 168 | " l32i %0, %2, 0\n" | ||
| 169 | " add %0, %0, %1\n" | ||
| 170 | " s32i %0, %2, 0\n" | ||
| 171 | " wsr a15, ps\n" | ||
| 172 | " rsync\n" | ||
| 173 | : "=&a" (vval) | ||
| 174 | : "a" (i), "a" (v) | ||
| 175 | : "a15", "memory" | ||
| 176 | ); | ||
| 177 | |||
| 178 | return vval; | ||
| 179 | #endif | ||
| 129 | } | 180 | } |
| 130 | 181 | ||
| 131 | static inline int atomic_sub_return(int i, atomic_t * v) | 182 | static inline int atomic_sub_return(int i, atomic_t * v) |
| 132 | { | 183 | { |
| 133 | unsigned int vval; | 184 | #if XCHAL_HAVE_S32C1I |
| 134 | 185 | unsigned long tmp; | |
| 135 | __asm__ __volatile__( | 186 | int result; |
| 136 | "rsil a15,"__stringify(LOCKLEVEL)"\n\t" | 187 | |
| 137 | "l32i %0, %2, 0 \n\t" | 188 | __asm__ __volatile__( |
| 138 | "sub %0, %0, %1 \n\t" | 189 | "1: l32i %1, %3, 0\n" |
| 139 | "s32i %0, %2, 0 \n\t" | 190 | " wsr %1, scompare1\n" |
| 140 | "wsr a15, ps \n\t" | 191 | " sub %0, %1, %2\n" |
| 141 | "rsync \n" | 192 | " s32c1i %0, %3, 0\n" |
| 142 | : "=&a" (vval) | 193 | " bne %0, %1, 1b\n" |
| 143 | : "a" (i), "a" (v) | 194 | " sub %0, %0, %2\n" |
| 144 | : "a15", "memory" | 195 | : "=&a" (result), "=&a" (tmp) |
| 145 | ); | 196 | : "a" (i), "a" (v) |
| 146 | 197 | : "memory" | |
| 147 | return vval; | 198 | ); |
| 199 | |||
| 200 | return result; | ||
| 201 | #else | ||
| 202 | unsigned int vval; | ||
| 203 | |||
| 204 | __asm__ __volatile__( | ||
| 205 | " rsil a15,"__stringify(LOCKLEVEL)"\n" | ||
| 206 | " l32i %0, %2, 0\n" | ||
| 207 | " sub %0, %0, %1\n" | ||
| 208 | " s32i %0, %2, 0\n" | ||
| 209 | " wsr a15, ps\n" | ||
| 210 | " rsync\n" | ||
| 211 | : "=&a" (vval) | ||
| 212 | : "a" (i), "a" (v) | ||
| 213 | : "a15", "memory" | ||
| 214 | ); | ||
| 215 | |||
| 216 | return vval; | ||
| 217 | #endif | ||
| 148 | } | 218 | } |
| 149 | 219 | ||
| 150 | /** | 220 | /** |
| @@ -251,38 +321,70 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u) | |||
| 251 | 321 | ||
| 252 | static inline void atomic_clear_mask(unsigned int mask, atomic_t *v) | 322 | static inline void atomic_clear_mask(unsigned int mask, atomic_t *v) |
| 253 | { | 323 | { |
| 254 | unsigned int all_f = -1; | 324 | #if XCHAL_HAVE_S32C1I |
| 255 | unsigned int vval; | 325 | unsigned long tmp; |
| 256 | 326 | int result; | |
| 257 | __asm__ __volatile__( | 327 | |
| 258 | "rsil a15,"__stringify(LOCKLEVEL)"\n\t" | 328 | __asm__ __volatile__( |
| 259 | "l32i %0, %2, 0 \n\t" | 329 | "1: l32i %1, %3, 0\n" |
| 260 | "xor %1, %4, %3 \n\t" | 330 | " wsr %1, scompare1\n" |
| 261 | "and %0, %0, %4 \n\t" | 331 | " and %0, %1, %2\n" |
| 262 | "s32i %0, %2, 0 \n\t" | 332 | " s32c1i %0, %3, 0\n" |
| 263 | "wsr a15, ps \n\t" | 333 | " bne %0, %1, 1b\n" |
| 264 | "rsync \n" | 334 | : "=&a" (result), "=&a" (tmp) |
| 265 | : "=&a" (vval), "=a" (mask) | 335 | : "a" (~mask), "a" (v) |
| 266 | : "a" (v), "a" (all_f), "1" (mask) | 336 | : "memory" |
| 267 | : "a15", "memory" | 337 | ); |
| 268 | ); | 338 | #else |
| 339 | unsigned int all_f = -1; | ||
| 340 | unsigned int vval; | ||
| 341 | |||
| 342 | __asm__ __volatile__( | ||
| 343 | " rsil a15,"__stringify(LOCKLEVEL)"\n" | ||
| 344 | " l32i %0, %2, 0\n" | ||
| 345 | " xor %1, %4, %3\n" | ||
| 346 | " and %0, %0, %4\n" | ||
| 347 | " s32i %0, %2, 0\n" | ||
| 348 | " wsr a15, ps\n" | ||
| 349 | " rsync\n" | ||
| 350 | : "=&a" (vval), "=a" (mask) | ||
| 351 | : "a" (v), "a" (all_f), "1" (mask) | ||
| 352 | : "a15", "memory" | ||
| 353 | ); | ||
| 354 | #endif | ||
| 269 | } | 355 | } |
| 270 | 356 | ||
| 271 | static inline void atomic_set_mask(unsigned int mask, atomic_t *v) | 357 | static inline void atomic_set_mask(unsigned int mask, atomic_t *v) |
| 272 | { | 358 | { |
| 273 | unsigned int vval; | 359 | #if XCHAL_HAVE_S32C1I |
| 274 | 360 | unsigned long tmp; | |
| 275 | __asm__ __volatile__( | 361 | int result; |
| 276 | "rsil a15,"__stringify(LOCKLEVEL)"\n\t" | 362 | |
| 277 | "l32i %0, %2, 0 \n\t" | 363 | __asm__ __volatile__( |
| 278 | "or %0, %0, %1 \n\t" | 364 | "1: l32i %1, %3, 0\n" |
| 279 | "s32i %0, %2, 0 \n\t" | 365 | " wsr %1, scompare1\n" |
| 280 | "wsr a15, ps \n\t" | 366 | " or %0, %1, %2\n" |
| 281 | "rsync \n" | 367 | " s32c1i %0, %3, 0\n" |
| 282 | : "=&a" (vval) | 368 | " bne %0, %1, 1b\n" |
| 283 | : "a" (mask), "a" (v) | 369 | : "=&a" (result), "=&a" (tmp) |
| 284 | : "a15", "memory" | 370 | : "a" (mask), "a" (v) |
| 285 | ); | 371 | : "memory" |
| 372 | ); | ||
| 373 | #else | ||
| 374 | unsigned int vval; | ||
| 375 | |||
| 376 | __asm__ __volatile__( | ||
| 377 | " rsil a15,"__stringify(LOCKLEVEL)"\n" | ||
| 378 | " l32i %0, %2, 0\n" | ||
| 379 | " or %0, %0, %1\n" | ||
| 380 | " s32i %0, %2, 0\n" | ||
| 381 | " wsr a15, ps\n" | ||
| 382 | " rsync\n" | ||
| 383 | : "=&a" (vval) | ||
| 384 | : "a" (mask), "a" (v) | ||
| 385 | : "a15", "memory" | ||
| 386 | ); | ||
| 387 | #endif | ||
| 286 | } | 388 | } |
| 287 | 389 | ||
| 288 | /* Atomic operations are already serializing */ | 390 | /* Atomic operations are already serializing */ |
| @@ -294,4 +396,3 @@ static inline void atomic_set_mask(unsigned int mask, atomic_t *v) | |||
| 294 | #endif /* __KERNEL__ */ | 396 | #endif /* __KERNEL__ */ |
| 295 | 397 | ||
| 296 | #endif /* _XTENSA_ATOMIC_H */ | 398 | #endif /* _XTENSA_ATOMIC_H */ |
| 297 | |||
diff --git a/arch/xtensa/include/asm/barrier.h b/arch/xtensa/include/asm/barrier.h index 55707a8009d3..ef021677d536 100644 --- a/arch/xtensa/include/asm/barrier.h +++ b/arch/xtensa/include/asm/barrier.h | |||
| @@ -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) 2001 - 2005 Tensilica Inc. | 6 | * Copyright (C) 2001 - 2012 Tensilica Inc. |
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | #ifndef _XTENSA_SYSTEM_H | 9 | #ifndef _XTENSA_SYSTEM_H |
| @@ -12,8 +12,8 @@ | |||
| 12 | #define smp_read_barrier_depends() do { } while(0) | 12 | #define smp_read_barrier_depends() do { } while(0) |
| 13 | #define read_barrier_depends() do { } while(0) | 13 | #define read_barrier_depends() do { } while(0) |
| 14 | 14 | ||
| 15 | #define mb() barrier() | 15 | #define mb() ({ __asm__ __volatile__("memw" : : : "memory"); }) |
| 16 | #define rmb() mb() | 16 | #define rmb() barrier() |
| 17 | #define wmb() mb() | 17 | #define wmb() mb() |
| 18 | 18 | ||
| 19 | #ifdef CONFIG_SMP | 19 | #ifdef CONFIG_SMP |
diff --git a/arch/xtensa/include/asm/bitops.h b/arch/xtensa/include/asm/bitops.h index 5270197ddd36..84afe58d5d37 100644 --- a/arch/xtensa/include/asm/bitops.h +++ b/arch/xtensa/include/asm/bitops.h | |||
| @@ -29,7 +29,6 @@ | |||
| 29 | #define smp_mb__before_clear_bit() barrier() | 29 | #define smp_mb__before_clear_bit() barrier() |
| 30 | #define smp_mb__after_clear_bit() barrier() | 30 | #define smp_mb__after_clear_bit() barrier() |
| 31 | 31 | ||
| 32 | #include <asm-generic/bitops/atomic.h> | ||
| 33 | #include <asm-generic/bitops/non-atomic.h> | 32 | #include <asm-generic/bitops/non-atomic.h> |
| 34 | 33 | ||
| 35 | #if XCHAL_HAVE_NSA | 34 | #if XCHAL_HAVE_NSA |
| @@ -104,6 +103,132 @@ static inline unsigned long __fls(unsigned long word) | |||
| 104 | #endif | 103 | #endif |
| 105 | 104 | ||
| 106 | #include <asm-generic/bitops/fls64.h> | 105 | #include <asm-generic/bitops/fls64.h> |
| 106 | |||
| 107 | #if XCHAL_HAVE_S32C1I | ||
| 108 | |||
| 109 | static inline void set_bit(unsigned int bit, volatile unsigned long *p) | ||
| 110 | { | ||
| 111 | unsigned long tmp, value; | ||
| 112 | unsigned long mask = 1UL << (bit & 31); | ||
| 113 | |||
| 114 | p += bit >> 5; | ||
| 115 | |||
| 116 | __asm__ __volatile__( | ||
| 117 | "1: l32i %1, %3, 0\n" | ||
| 118 | " wsr %1, scompare1\n" | ||
| 119 | " or %0, %1, %2\n" | ||
| 120 | " s32c1i %0, %3, 0\n" | ||
| 121 | " bne %0, %1, 1b\n" | ||
| 122 | : "=&a" (tmp), "=&a" (value) | ||
| 123 | : "a" (mask), "a" (p) | ||
| 124 | : "memory"); | ||
| 125 | } | ||
| 126 | |||
| 127 | static inline void clear_bit(unsigned int bit, volatile unsigned long *p) | ||
| 128 | { | ||
| 129 | unsigned long tmp, value; | ||
| 130 | unsigned long mask = 1UL << (bit & 31); | ||
| 131 | |||
| 132 | p += bit >> 5; | ||
| 133 | |||
| 134 | __asm__ __volatile__( | ||
| 135 | "1: l32i %1, %3, 0\n" | ||
| 136 | " wsr %1, scompare1\n" | ||
| 137 | " and %0, %1, %2\n" | ||
| 138 | " s32c1i %0, %3, 0\n" | ||
| 139 | " bne %0, %1, 1b\n" | ||
| 140 | : "=&a" (tmp), "=&a" (value) | ||
| 141 | : "a" (~mask), "a" (p) | ||
| 142 | : "memory"); | ||
| 143 | } | ||
| 144 | |||
| 145 | static inline void change_bit(unsigned int bit, volatile unsigned long *p) | ||
| 146 | { | ||
| 147 | unsigned long tmp, value; | ||
| 148 | unsigned long mask = 1UL << (bit & 31); | ||
| 149 | |||
| 150 | p += bit >> 5; | ||
| 151 | |||
| 152 | __asm__ __volatile__( | ||
| 153 | "1: l32i %1, %3, 0\n" | ||
| 154 | " wsr %1, scompare1\n" | ||
| 155 | " xor %0, %1, %2\n" | ||
| 156 | " s32c1i %0, %3, 0\n" | ||
| 157 | " bne %0, %1, 1b\n" | ||
| 158 | : "=&a" (tmp), "=&a" (value) | ||
| 159 | : "a" (mask), "a" (p) | ||
| 160 | : "memory"); | ||
| 161 | } | ||
| 162 | |||
| 163 | static inline int | ||
| 164 | test_and_set_bit(unsigned int bit, volatile unsigned long *p) | ||
| 165 | { | ||
| 166 | unsigned long tmp, value; | ||
| 167 | unsigned long mask = 1UL << (bit & 31); | ||
| 168 | |||
| 169 | p += bit >> 5; | ||
| 170 | |||
| 171 | __asm__ __volatile__( | ||
| 172 | "1: l32i %1, %3, 0\n" | ||
| 173 | " wsr %1, scompare1\n" | ||
| 174 | " or %0, %1, %2\n" | ||
| 175 | " s32c1i %0, %3, 0\n" | ||
| 176 | " bne %0, %1, 1b\n" | ||
| 177 | : "=&a" (tmp), "=&a" (value) | ||
| 178 | : "a" (mask), "a" (p) | ||
| 179 | : "memory"); | ||
| 180 | |||
| 181 | return tmp & mask; | ||
| 182 | } | ||
| 183 | |||
| 184 | static inline int | ||
| 185 | test_and_clear_bit(unsigned int bit, volatile unsigned long *p) | ||
| 186 | { | ||
| 187 | unsigned long tmp, value; | ||
| 188 | unsigned long mask = 1UL << (bit & 31); | ||
| 189 | |||
| 190 | p += bit >> 5; | ||
| 191 | |||
| 192 | __asm__ __volatile__( | ||
| 193 | "1: l32i %1, %3, 0\n" | ||
| 194 | " wsr %1, scompare1\n" | ||
| 195 | " and %0, %1, %2\n" | ||
| 196 | " s32c1i %0, %3, 0\n" | ||
| 197 | " bne %0, %1, 1b\n" | ||
| 198 | : "=&a" (tmp), "=&a" (value) | ||
| 199 | : "a" (~mask), "a" (p) | ||
| 200 | : "memory"); | ||
| 201 | |||
| 202 | return tmp & mask; | ||
| 203 | } | ||
| 204 | |||
| 205 | static inline int | ||
| 206 | test_and_change_bit(unsigned int bit, volatile unsigned long *p) | ||
| 207 | { | ||
| 208 | unsigned long tmp, value; | ||
| 209 | unsigned long mask = 1UL << (bit & 31); | ||
| 210 | |||
| 211 | p += bit >> 5; | ||
| 212 | |||
| 213 | __asm__ __volatile__( | ||
| 214 | "1: l32i %1, %3, 0\n" | ||
| 215 | " wsr %1, scompare1\n" | ||
| 216 | " xor %0, %1, %2\n" | ||
| 217 | " s32c1i %0, %3, 0\n" | ||
| 218 | " bne %0, %1, 1b\n" | ||
| 219 | : "=&a" (tmp), "=&a" (value) | ||
| 220 | : "a" (mask), "a" (p) | ||
| 221 | : "memory"); | ||
| 222 | |||
| 223 | return tmp & mask; | ||
| 224 | } | ||
| 225 | |||
| 226 | #else | ||
| 227 | |||
| 228 | #include <asm-generic/bitops/atomic.h> | ||
| 229 | |||
| 230 | #endif /* XCHAL_HAVE_S32C1I */ | ||
| 231 | |||
| 107 | #include <asm-generic/bitops/find.h> | 232 | #include <asm-generic/bitops/find.h> |
| 108 | #include <asm-generic/bitops/le.h> | 233 | #include <asm-generic/bitops/le.h> |
| 109 | 234 | ||
diff --git a/arch/xtensa/include/asm/bootparam.h b/arch/xtensa/include/asm/bootparam.h index 9983f2c1b7ee..0c25799facab 100644 --- a/arch/xtensa/include/asm/bootparam.h +++ b/arch/xtensa/include/asm/bootparam.h | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #define BP_TAG_MEMORY 0x1003 /* memory addr and size (bp_meminfo) */ | 22 | #define BP_TAG_MEMORY 0x1003 /* memory addr and size (bp_meminfo) */ |
| 23 | #define BP_TAG_SERIAL_BAUSRATE 0x1004 /* baud rate of current console. */ | 23 | #define BP_TAG_SERIAL_BAUSRATE 0x1004 /* baud rate of current console. */ |
| 24 | #define BP_TAG_SERIAL_PORT 0x1005 /* serial device of current console */ | 24 | #define BP_TAG_SERIAL_PORT 0x1005 /* serial device of current console */ |
| 25 | #define BP_TAG_FDT 0x1006 /* flat device tree addr */ | ||
| 25 | 26 | ||
| 26 | #define BP_TAG_FIRST 0x7B0B /* first tag with a version number */ | 27 | #define BP_TAG_FIRST 0x7B0B /* first tag with a version number */ |
| 27 | #define BP_TAG_LAST 0x7E0B /* last tag */ | 28 | #define BP_TAG_LAST 0x7E0B /* last tag */ |
| @@ -31,15 +32,15 @@ | |||
| 31 | /* All records are aligned to 4 bytes */ | 32 | /* All records are aligned to 4 bytes */ |
| 32 | 33 | ||
| 33 | typedef struct bp_tag { | 34 | typedef struct bp_tag { |
| 34 | unsigned short id; /* tag id */ | 35 | unsigned short id; /* tag id */ |
| 35 | unsigned short size; /* size of this record excluding the structure*/ | 36 | unsigned short size; /* size of this record excluding the structure*/ |
| 36 | unsigned long data[0]; /* data */ | 37 | unsigned long data[0]; /* data */ |
| 37 | } bp_tag_t; | 38 | } bp_tag_t; |
| 38 | 39 | ||
| 39 | typedef struct meminfo { | 40 | typedef struct meminfo { |
| 40 | unsigned long type; | 41 | unsigned long type; |
| 41 | unsigned long start; | 42 | unsigned long start; |
| 42 | unsigned long end; | 43 | unsigned long end; |
| 43 | } meminfo_t; | 44 | } meminfo_t; |
| 44 | 45 | ||
| 45 | #define SYSMEM_BANKS_MAX 5 | 46 | #define SYSMEM_BANKS_MAX 5 |
| @@ -48,14 +49,11 @@ typedef struct meminfo { | |||
| 48 | #define MEMORY_TYPE_NONE 0x2000 | 49 | #define MEMORY_TYPE_NONE 0x2000 |
| 49 | 50 | ||
| 50 | typedef struct sysmem_info { | 51 | typedef struct sysmem_info { |
| 51 | int nr_banks; | 52 | int nr_banks; |
| 52 | meminfo_t bank[SYSMEM_BANKS_MAX]; | 53 | meminfo_t bank[SYSMEM_BANKS_MAX]; |
| 53 | } sysmem_info_t; | 54 | } sysmem_info_t; |
| 54 | 55 | ||
| 55 | extern sysmem_info_t sysmem; | 56 | extern sysmem_info_t sysmem; |
| 56 | 57 | ||
| 57 | #endif | 58 | #endif |
| 58 | #endif | 59 | #endif |
| 59 | |||
| 60 | |||
| 61 | |||
diff --git a/arch/xtensa/include/asm/cacheasm.h b/arch/xtensa/include/asm/cacheasm.h index 2c20a58f94cd..60e18773ecb8 100644 --- a/arch/xtensa/include/asm/cacheasm.h +++ b/arch/xtensa/include/asm/cacheasm.h | |||
| @@ -174,4 +174,3 @@ | |||
| 174 | __loop_cache_page \ar \as ihi XCHAL_ICACHE_LINEWIDTH | 174 | __loop_cache_page \ar \as ihi XCHAL_ICACHE_LINEWIDTH |
| 175 | 175 | ||
| 176 | .endm | 176 | .endm |
| 177 | |||
diff --git a/arch/xtensa/include/asm/cacheflush.h b/arch/xtensa/include/asm/cacheflush.h index 569fec4f9a20..127cd48883c4 100644 --- a/arch/xtensa/include/asm/cacheflush.h +++ b/arch/xtensa/include/asm/cacheflush.h | |||
| @@ -104,7 +104,8 @@ static inline void __invalidate_icache_page_alias(unsigned long virt, | |||
| 104 | #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 | 104 | #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 |
| 105 | extern void flush_dcache_page(struct page*); | 105 | extern void flush_dcache_page(struct page*); |
| 106 | extern void flush_cache_range(struct vm_area_struct*, ulong, ulong); | 106 | extern void flush_cache_range(struct vm_area_struct*, ulong, ulong); |
| 107 | extern void flush_cache_page(struct vm_area_struct*, unsigned long, unsigned long); | 107 | extern void flush_cache_page(struct vm_area_struct*, |
| 108 | unsigned long, unsigned long); | ||
| 108 | 109 | ||
| 109 | #else | 110 | #else |
| 110 | 111 | ||
diff --git a/arch/xtensa/include/asm/checksum.h b/arch/xtensa/include/asm/checksum.h index e4d831a30772..aed7ad68ca46 100644 --- a/arch/xtensa/include/asm/checksum.h +++ b/arch/xtensa/include/asm/checksum.h | |||
| @@ -36,8 +36,9 @@ asmlinkage __wsum csum_partial(const void *buff, int len, __wsum sum); | |||
| 36 | * better 64-bit) boundary | 36 | * better 64-bit) boundary |
| 37 | */ | 37 | */ |
| 38 | 38 | ||
| 39 | asmlinkage __wsum csum_partial_copy_generic(const void *src, void *dst, int len, __wsum sum, | 39 | asmlinkage __wsum csum_partial_copy_generic(const void *src, void *dst, |
| 40 | int *src_err_ptr, int *dst_err_ptr); | 40 | int len, __wsum sum, |
| 41 | int *src_err_ptr, int *dst_err_ptr); | ||
| 41 | 42 | ||
| 42 | /* | 43 | /* |
| 43 | * Note: when you get a NULL pointer exception here this means someone | 44 | * Note: when you get a NULL pointer exception here this means someone |
| @@ -54,7 +55,7 @@ __wsum csum_partial_copy_nocheck(const void *src, void *dst, | |||
| 54 | 55 | ||
| 55 | static inline | 56 | static inline |
| 56 | __wsum csum_partial_copy_from_user(const void __user *src, void *dst, | 57 | __wsum csum_partial_copy_from_user(const void __user *src, void *dst, |
| 57 | int len, __wsum sum, int *err_ptr) | 58 | int len, __wsum sum, int *err_ptr) |
| 58 | { | 59 | { |
| 59 | return csum_partial_copy_generic((__force const void *)src, dst, | 60 | return csum_partial_copy_generic((__force const void *)src, dst, |
| 60 | len, sum, err_ptr, NULL); | 61 | len, sum, err_ptr, NULL); |
| @@ -112,7 +113,8 @@ static __inline__ __sum16 ip_fast_csum(const void *iph, unsigned int ihl) | |||
| 112 | /* Since the input registers which are loaded with iph and ihl | 113 | /* Since the input registers which are loaded with iph and ihl |
| 113 | are modified, we must also specify them as outputs, or gcc | 114 | are modified, we must also specify them as outputs, or gcc |
| 114 | will assume they contain their original values. */ | 115 | will assume they contain their original values. */ |
| 115 | : "=r" (sum), "=r" (iph), "=r" (ihl), "=&r" (tmp), "=&r" (endaddr) | 116 | : "=r" (sum), "=r" (iph), "=r" (ihl), "=&r" (tmp), |
| 117 | "=&r" (endaddr) | ||
| 116 | : "1" (iph), "2" (ihl) | 118 | : "1" (iph), "2" (ihl) |
| 117 | : "memory"); | 119 | : "memory"); |
| 118 | 120 | ||
| @@ -168,7 +170,7 @@ static __inline__ __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, | |||
| 168 | 170 | ||
| 169 | static __inline__ __sum16 ip_compute_csum(const void *buff, int len) | 171 | static __inline__ __sum16 ip_compute_csum(const void *buff, int len) |
| 170 | { | 172 | { |
| 171 | return csum_fold (csum_partial(buff, len, 0)); | 173 | return csum_fold (csum_partial(buff, len, 0)); |
| 172 | } | 174 | } |
| 173 | 175 | ||
| 174 | #define _HAVE_ARCH_IPV6_CSUM | 176 | #define _HAVE_ARCH_IPV6_CSUM |
| @@ -238,11 +240,12 @@ static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr, | |||
| 238 | * Copy and checksum to user | 240 | * Copy and checksum to user |
| 239 | */ | 241 | */ |
| 240 | #define HAVE_CSUM_COPY_USER | 242 | #define HAVE_CSUM_COPY_USER |
| 241 | static __inline__ __wsum csum_and_copy_to_user(const void *src, void __user *dst, | 243 | static __inline__ __wsum csum_and_copy_to_user(const void *src, |
| 242 | int len, __wsum sum, int *err_ptr) | 244 | void __user *dst, int len, |
| 245 | __wsum sum, int *err_ptr) | ||
| 243 | { | 246 | { |
| 244 | if (access_ok(VERIFY_WRITE, dst, len)) | 247 | if (access_ok(VERIFY_WRITE, dst, len)) |
| 245 | return csum_partial_copy_generic(src, dst, len, sum, NULL, err_ptr); | 248 | return csum_partial_copy_generic(src,dst,len,sum,NULL,err_ptr); |
| 246 | 249 | ||
| 247 | if (len) | 250 | if (len) |
| 248 | *err_ptr = -EFAULT; | 251 | *err_ptr = -EFAULT; |
diff --git a/arch/xtensa/include/asm/cmpxchg.h b/arch/xtensa/include/asm/cmpxchg.h index 64dad04a9d27..d9ab131bc1aa 100644 --- a/arch/xtensa/include/asm/cmpxchg.h +++ b/arch/xtensa/include/asm/cmpxchg.h | |||
| @@ -22,17 +22,30 @@ | |||
| 22 | static inline unsigned long | 22 | static inline unsigned long |
| 23 | __cmpxchg_u32(volatile int *p, int old, int new) | 23 | __cmpxchg_u32(volatile int *p, int old, int new) |
| 24 | { | 24 | { |
| 25 | __asm__ __volatile__("rsil a15, "__stringify(LOCKLEVEL)"\n\t" | 25 | #if XCHAL_HAVE_S32C1I |
| 26 | "l32i %0, %1, 0 \n\t" | 26 | __asm__ __volatile__( |
| 27 | "bne %0, %2, 1f \n\t" | 27 | " wsr %2, scompare1\n" |
| 28 | "s32i %3, %1, 0 \n\t" | 28 | " s32c1i %0, %1, 0\n" |
| 29 | "1: \n\t" | 29 | : "+a" (new) |
| 30 | "wsr a15, ps \n\t" | 30 | : "a" (p), "a" (old) |
| 31 | "rsync \n\t" | 31 | : "memory" |
| 32 | : "=&a" (old) | 32 | ); |
| 33 | : "a" (p), "a" (old), "r" (new) | 33 | |
| 34 | : "a15", "memory"); | 34 | return new; |
| 35 | return old; | 35 | #else |
| 36 | __asm__ __volatile__( | ||
| 37 | " rsil a15, "__stringify(LOCKLEVEL)"\n" | ||
| 38 | " l32i %0, %1, 0\n" | ||
| 39 | " bne %0, %2, 1f\n" | ||
| 40 | " s32i %3, %1, 0\n" | ||
| 41 | "1:\n" | ||
| 42 | " wsr a15, ps\n" | ||
| 43 | " rsync\n" | ||
| 44 | : "=&a" (old) | ||
| 45 | : "a" (p), "a" (old), "r" (new) | ||
| 46 | : "a15", "memory"); | ||
| 47 | return old; | ||
| 48 | #endif | ||
| 36 | } | 49 | } |
| 37 | /* This function doesn't exist, so you'll get a linker error | 50 | /* This function doesn't exist, so you'll get a linker error |
| 38 | * if something tries to do an invalid cmpxchg(). */ | 51 | * if something tries to do an invalid cmpxchg(). */ |
| @@ -93,19 +106,36 @@ static inline unsigned long __cmpxchg_local(volatile void *ptr, | |||
| 93 | 106 | ||
| 94 | static inline unsigned long xchg_u32(volatile int * m, unsigned long val) | 107 | static inline unsigned long xchg_u32(volatile int * m, unsigned long val) |
| 95 | { | 108 | { |
| 96 | unsigned long tmp; | 109 | #if XCHAL_HAVE_S32C1I |
| 97 | __asm__ __volatile__("rsil a15, "__stringify(LOCKLEVEL)"\n\t" | 110 | unsigned long tmp, result; |
| 98 | "l32i %0, %1, 0 \n\t" | 111 | __asm__ __volatile__( |
| 99 | "s32i %2, %1, 0 \n\t" | 112 | "1: l32i %1, %2, 0\n" |
| 100 | "wsr a15, ps \n\t" | 113 | " mov %0, %3\n" |
| 101 | "rsync \n\t" | 114 | " wsr %1, scompare1\n" |
| 102 | : "=&a" (tmp) | 115 | " s32c1i %0, %2, 0\n" |
| 103 | : "a" (m), "a" (val) | 116 | " bne %0, %1, 1b\n" |
| 104 | : "a15", "memory"); | 117 | : "=&a" (result), "=&a" (tmp) |
| 105 | return tmp; | 118 | : "a" (m), "a" (val) |
| 119 | : "memory" | ||
| 120 | ); | ||
| 121 | return result; | ||
| 122 | #else | ||
| 123 | unsigned long tmp; | ||
| 124 | __asm__ __volatile__( | ||
| 125 | " rsil a15, "__stringify(LOCKLEVEL)"\n" | ||
| 126 | " l32i %0, %1, 0\n" | ||
| 127 | " s32i %2, %1, 0\n" | ||
| 128 | " wsr a15, ps\n" | ||
| 129 | " rsync\n" | ||
| 130 | : "=&a" (tmp) | ||
| 131 | : "a" (m), "a" (val) | ||
| 132 | : "a15", "memory"); | ||
| 133 | return tmp; | ||
| 134 | #endif | ||
| 106 | } | 135 | } |
| 107 | 136 | ||
| 108 | #define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) | 137 | #define xchg(ptr,x) \ |
| 138 | ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) | ||
| 109 | 139 | ||
| 110 | /* | 140 | /* |
| 111 | * This only works if the compiler isn't horribly bad at optimizing. | 141 | * This only works if the compiler isn't horribly bad at optimizing. |
diff --git a/arch/xtensa/include/asm/current.h b/arch/xtensa/include/asm/current.h index 8d1eb5d78649..47e46dcf5d49 100644 --- a/arch/xtensa/include/asm/current.h +++ b/arch/xtensa/include/asm/current.h | |||
| @@ -30,7 +30,7 @@ static inline struct task_struct *get_current(void) | |||
| 30 | 30 | ||
| 31 | #define GET_CURRENT(reg,sp) \ | 31 | #define GET_CURRENT(reg,sp) \ |
| 32 | GET_THREAD_INFO(reg,sp); \ | 32 | GET_THREAD_INFO(reg,sp); \ |
| 33 | l32i reg, reg, TI_TASK \ | 33 | l32i reg, reg, TI_TASK \ |
| 34 | 34 | ||
| 35 | #endif | 35 | #endif |
| 36 | 36 | ||
diff --git a/arch/xtensa/include/asm/delay.h b/arch/xtensa/include/asm/delay.h index 58c0a4fd4003..61fc5faeb46c 100644 --- a/arch/xtensa/include/asm/delay.h +++ b/arch/xtensa/include/asm/delay.h | |||
| @@ -19,9 +19,9 @@ extern unsigned long loops_per_jiffy; | |||
| 19 | 19 | ||
| 20 | static inline void __delay(unsigned long loops) | 20 | static inline void __delay(unsigned long loops) |
| 21 | { | 21 | { |
| 22 | /* 2 cycles per loop. */ | 22 | /* 2 cycles per loop. */ |
| 23 | __asm__ __volatile__ ("1: addi %0, %0, -2; bgeui %0, 2, 1b" | 23 | __asm__ __volatile__ ("1: addi %0, %0, -2; bgeui %0, 2, 1b" |
| 24 | : "=r" (loops) : "0" (loops)); | 24 | : "=r" (loops) : "0" (loops)); |
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | static __inline__ u32 xtensa_get_ccount(void) | 27 | static __inline__ u32 xtensa_get_ccount(void) |
| @@ -46,4 +46,3 @@ static __inline__ void udelay (unsigned long usecs) | |||
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | #endif | 48 | #endif |
| 49 | |||
diff --git a/arch/xtensa/include/asm/dma-mapping.h b/arch/xtensa/include/asm/dma-mapping.h index 492c95790ad5..4acb5feba1fb 100644 --- a/arch/xtensa/include/asm/dma-mapping.h +++ b/arch/xtensa/include/asm/dma-mapping.h | |||
| @@ -16,6 +16,8 @@ | |||
| 16 | #include <linux/mm.h> | 16 | #include <linux/mm.h> |
| 17 | #include <linux/scatterlist.h> | 17 | #include <linux/scatterlist.h> |
| 18 | 18 | ||
| 19 | #define DMA_ERROR_CODE (~(dma_addr_t)0x0) | ||
| 20 | |||
| 19 | /* | 21 | /* |
| 20 | * DMA-consistent mapping functions. | 22 | * DMA-consistent mapping functions. |
| 21 | */ | 23 | */ |
| @@ -98,8 +100,8 @@ dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, | |||
| 98 | } | 100 | } |
| 99 | 101 | ||
| 100 | static inline void | 102 | static inline void |
| 101 | dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size, | 103 | dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, |
| 102 | enum dma_data_direction direction) | 104 | size_t size, enum dma_data_direction direction) |
| 103 | { | 105 | { |
| 104 | consistent_sync((void *)bus_to_virt(dma_handle), size, direction); | 106 | consistent_sync((void *)bus_to_virt(dma_handle), size, direction); |
| 105 | } | 107 | } |
diff --git a/arch/xtensa/include/asm/elf.h b/arch/xtensa/include/asm/elf.h index 5293312bc6a4..264d5fa450d8 100644 --- a/arch/xtensa/include/asm/elf.h +++ b/arch/xtensa/include/asm/elf.h | |||
| @@ -168,11 +168,11 @@ extern void xtensa_elf_core_copy_regs (xtensa_gregset_t *, struct pt_regs *); | |||
| 168 | */ | 168 | */ |
| 169 | 169 | ||
| 170 | #define ELF_PLAT_INIT(_r, load_addr) \ | 170 | #define ELF_PLAT_INIT(_r, load_addr) \ |
| 171 | do { _r->areg[0]=0; /*_r->areg[1]=0;*/ _r->areg[2]=0; _r->areg[3]=0; \ | 171 | do { _r->areg[0]=0; /*_r->areg[1]=0;*/ _r->areg[2]=0; _r->areg[3]=0; \ |
| 172 | _r->areg[4]=0; _r->areg[5]=0; _r->areg[6]=0; _r->areg[7]=0; \ | 172 | _r->areg[4]=0; _r->areg[5]=0; _r->areg[6]=0; _r->areg[7]=0; \ |
| 173 | _r->areg[8]=0; _r->areg[9]=0; _r->areg[10]=0; _r->areg[11]=0; \ | 173 | _r->areg[8]=0; _r->areg[9]=0; _r->areg[10]=0; _r->areg[11]=0; \ |
| 174 | _r->areg[12]=0; _r->areg[13]=0; _r->areg[14]=0; _r->areg[15]=0; \ | 174 | _r->areg[12]=0; _r->areg[13]=0; _r->areg[14]=0; _r->areg[15]=0; \ |
| 175 | } while (0) | 175 | } while (0) |
| 176 | 176 | ||
| 177 | typedef struct { | 177 | typedef struct { |
| 178 | xtregs_opt_t opt; | 178 | xtregs_opt_t opt; |
diff --git a/arch/xtensa/include/asm/highmem.h b/arch/xtensa/include/asm/highmem.h index 0a046ca5a687..80be15124697 100644 --- a/arch/xtensa/include/asm/highmem.h +++ b/arch/xtensa/include/asm/highmem.h | |||
| @@ -14,4 +14,3 @@ | |||
| 14 | extern void flush_cache_kmaps(void); | 14 | extern void flush_cache_kmaps(void); |
| 15 | 15 | ||
| 16 | #endif | 16 | #endif |
| 17 | |||
diff --git a/arch/xtensa/include/asm/initialize_mmu.h b/arch/xtensa/include/asm/initialize_mmu.h new file mode 100644 index 000000000000..e1f8ba4061ed --- /dev/null +++ b/arch/xtensa/include/asm/initialize_mmu.h | |||
| @@ -0,0 +1,55 @@ | |||
| 1 | /* | ||
| 2 | * arch/xtensa/include/asm/initialize_mmu.h | ||
| 3 | * | ||
| 4 | * Initializes MMU: | ||
| 5 | * | ||
| 6 | * For the new V3 MMU we remap the TLB from virtual == physical | ||
| 7 | * to the standard Linux mapping used in earlier MMU's. | ||
| 8 | * | ||
| 9 | * The the MMU we also support a new configuration register that | ||
| 10 | * specifies how the S32C1I instruction operates with the cache | ||
| 11 | * controller. | ||
| 12 | * | ||
| 13 | * This file is subject to the terms and conditions of the GNU General | ||
| 14 | * Public License. See the file "COPYING" in the main directory of | ||
| 15 | * this archive for more details. | ||
| 16 | * | ||
| 17 | * Copyright (C) 2008 - 2012 Tensilica, Inc. | ||
| 18 | * | ||
| 19 | * Marc Gauthier <marc@tensilica.com> | ||
| 20 | * Pete Delaney <piet@tensilica.com> | ||
| 21 | */ | ||
| 22 | |||
| 23 | #ifndef _XTENSA_INITIALIZE_MMU_H | ||
| 24 | #define _XTENSA_INITIALIZE_MMU_H | ||
| 25 | |||
| 26 | #ifdef __ASSEMBLY__ | ||
| 27 | |||
| 28 | #define XTENSA_HWVERSION_RC_2009_0 230000 | ||
| 29 | |||
| 30 | .macro initialize_mmu | ||
| 31 | |||
| 32 | #if XCHAL_HAVE_S32C1I && (XCHAL_HW_MIN_VERSION >= XTENSA_HWVERSION_RC_2009_0) | ||
| 33 | /* | ||
| 34 | * We Have Atomic Operation Control (ATOMCTL) Register; Initialize it. | ||
| 35 | * For details see Documentation/xtensa/atomctl.txt | ||
| 36 | */ | ||
| 37 | #if XCHAL_DCACHE_IS_COHERENT | ||
| 38 | movi a3, 0x25 /* For SMP/MX -- internal for writeback, | ||
| 39 | * RCW otherwise | ||
| 40 | */ | ||
| 41 | #else | ||
| 42 | movi a3, 0x29 /* non-MX -- Most cores use Std Memory | ||
| 43 | * Controlers which usually can't use RCW | ||
| 44 | */ | ||
| 45 | #endif | ||
| 46 | wsr a3, atomctl | ||
| 47 | #endif /* XCHAL_HAVE_S32C1I && | ||
| 48 | * (XCHAL_HW_MIN_VERSION >= XTENSA_HWVERSION_RC_2009_0) | ||
| 49 | */ | ||
| 50 | |||
| 51 | .endm | ||
| 52 | |||
| 53 | #endif /*__ASSEMBLY__*/ | ||
| 54 | |||
| 55 | #endif /* _XTENSA_INITIALIZE_MMU_H */ | ||
diff --git a/arch/xtensa/include/asm/mmu_context.h b/arch/xtensa/include/asm/mmu_context.h index feb10af96519..d43525a286bb 100644 --- a/arch/xtensa/include/asm/mmu_context.h +++ b/arch/xtensa/include/asm/mmu_context.h | |||
| @@ -107,7 +107,7 @@ activate_mm(struct mm_struct *prev, struct mm_struct *next) | |||
| 107 | 107 | ||
| 108 | 108 | ||
| 109 | static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, | 109 | static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, |
| 110 | struct task_struct *tsk) | 110 | struct task_struct *tsk) |
| 111 | { | 111 | { |
| 112 | unsigned long asid = asid_cache; | 112 | unsigned long asid = asid_cache; |
| 113 | 113 | ||
diff --git a/arch/xtensa/include/asm/nommu_context.h b/arch/xtensa/include/asm/nommu_context.h index 599e7a2e729d..3407cf7989b7 100644 --- a/arch/xtensa/include/asm/nommu_context.h +++ b/arch/xtensa/include/asm/nommu_context.h | |||
| @@ -2,7 +2,7 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) | |||
| 2 | { | 2 | { |
| 3 | } | 3 | } |
| 4 | 4 | ||
| 5 | static inline int init_new_context(struct task_struct *tsk, struct mm_struct *mm) | 5 | static inline int init_new_context(struct task_struct *tsk,struct mm_struct *mm) |
| 6 | { | 6 | { |
| 7 | return 0; | 7 | return 0; |
| 8 | } | 8 | } |
diff --git a/arch/xtensa/include/asm/page.h b/arch/xtensa/include/asm/page.h index 7a5591a71f85..47f582333f6b 100644 --- a/arch/xtensa/include/asm/page.h +++ b/arch/xtensa/include/asm/page.h | |||
| @@ -29,19 +29,19 @@ | |||
| 29 | * PAGE_SHIFT determines the page size | 29 | * PAGE_SHIFT determines the page size |
| 30 | */ | 30 | */ |
| 31 | 31 | ||
| 32 | #define PAGE_SHIFT 12 | 32 | #define PAGE_SHIFT 12 |
| 33 | #define PAGE_SIZE (__XTENSA_UL_CONST(1) << PAGE_SHIFT) | 33 | #define PAGE_SIZE (__XTENSA_UL_CONST(1) << PAGE_SHIFT) |
| 34 | #define PAGE_MASK (~(PAGE_SIZE-1)) | 34 | #define PAGE_MASK (~(PAGE_SIZE-1)) |
| 35 | 35 | ||
| 36 | #ifdef CONFIG_MMU | 36 | #ifdef CONFIG_MMU |
| 37 | #define PAGE_OFFSET XCHAL_KSEG_CACHED_VADDR | 37 | #define PAGE_OFFSET XCHAL_KSEG_CACHED_VADDR |
| 38 | #define MAX_MEM_PFN XCHAL_KSEG_SIZE | 38 | #define MAX_MEM_PFN XCHAL_KSEG_SIZE |
| 39 | #else | 39 | #else |
| 40 | #define PAGE_OFFSET 0 | 40 | #define PAGE_OFFSET 0 |
| 41 | #define MAX_MEM_PFN (PLATFORM_DEFAULT_MEM_START + PLATFORM_DEFAULT_MEM_SIZE) | 41 | #define MAX_MEM_PFN (PLATFORM_DEFAULT_MEM_START + PLATFORM_DEFAULT_MEM_SIZE) |
| 42 | #endif | 42 | #endif |
| 43 | 43 | ||
| 44 | #define PGTABLE_START 0x80000000 | 44 | #define PGTABLE_START 0x80000000 |
| 45 | 45 | ||
| 46 | /* | 46 | /* |
| 47 | * Cache aliasing: | 47 | * Cache aliasing: |
| @@ -161,7 +161,9 @@ extern void copy_user_page(void*, void*, unsigned long, struct page*); | |||
| 161 | 161 | ||
| 162 | #define __pa(x) ((unsigned long) (x) - PAGE_OFFSET) | 162 | #define __pa(x) ((unsigned long) (x) - PAGE_OFFSET) |
| 163 | #define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET)) | 163 | #define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET)) |
| 164 | #define pfn_valid(pfn) ((pfn) >= ARCH_PFN_OFFSET && ((pfn) - ARCH_PFN_OFFSET) < max_mapnr) | 164 | #define pfn_valid(pfn) \ |
| 165 | ((pfn) >= ARCH_PFN_OFFSET && ((pfn) - ARCH_PFN_OFFSET) < max_mapnr) | ||
| 166 | |||
| 165 | #ifdef CONFIG_DISCONTIGMEM | 167 | #ifdef CONFIG_DISCONTIGMEM |
| 166 | # error CONFIG_DISCONTIGMEM not supported | 168 | # error CONFIG_DISCONTIGMEM not supported |
| 167 | #endif | 169 | #endif |
diff --git a/arch/xtensa/include/asm/pci-bridge.h b/arch/xtensa/include/asm/pci-bridge.h index 00fcbd7c534a..0b68c76ec1e6 100644 --- a/arch/xtensa/include/asm/pci-bridge.h +++ b/arch/xtensa/include/asm/pci-bridge.h | |||
| @@ -35,7 +35,7 @@ struct pci_space { | |||
| 35 | struct pci_controller { | 35 | struct pci_controller { |
| 36 | int index; /* used for pci_controller_num */ | 36 | int index; /* used for pci_controller_num */ |
| 37 | struct pci_controller *next; | 37 | struct pci_controller *next; |
| 38 | struct pci_bus *bus; | 38 | struct pci_bus *bus; |
| 39 | void *arch_data; | 39 | void *arch_data; |
| 40 | 40 | ||
| 41 | int first_busno; | 41 | int first_busno; |
diff --git a/arch/xtensa/include/asm/pci.h b/arch/xtensa/include/asm/pci.h index 05244f07dd31..614be031a79a 100644 --- a/arch/xtensa/include/asm/pci.h +++ b/arch/xtensa/include/asm/pci.h | |||
| @@ -53,7 +53,7 @@ struct pci_dev; | |||
| 53 | 53 | ||
| 54 | /* Map a range of PCI memory or I/O space for a device into user space */ | 54 | /* Map a range of PCI memory or I/O space for a device into user space */ |
| 55 | int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma, | 55 | int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma, |
| 56 | enum pci_mmap_state mmap_state, int write_combine); | 56 | enum pci_mmap_state mmap_state, int write_combine); |
| 57 | 57 | ||
| 58 | /* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */ | 58 | /* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */ |
| 59 | #define HAVE_PCI_MMAP 1 | 59 | #define HAVE_PCI_MMAP 1 |
diff --git a/arch/xtensa/include/asm/pgalloc.h b/arch/xtensa/include/asm/pgalloc.h index 40cf9bceda2c..cf914c8c249a 100644 --- a/arch/xtensa/include/asm/pgalloc.h +++ b/arch/xtensa/include/asm/pgalloc.h | |||
| @@ -42,7 +42,7 @@ static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) | |||
| 42 | 42 | ||
| 43 | extern struct kmem_cache *pgtable_cache; | 43 | extern struct kmem_cache *pgtable_cache; |
| 44 | 44 | ||
| 45 | static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, | 45 | static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, |
| 46 | unsigned long address) | 46 | unsigned long address) |
| 47 | { | 47 | { |
| 48 | return kmem_cache_alloc(pgtable_cache, GFP_KERNEL|__GFP_REPEAT); | 48 | return kmem_cache_alloc(pgtable_cache, GFP_KERNEL|__GFP_REPEAT); |
diff --git a/arch/xtensa/include/asm/pgtable.h b/arch/xtensa/include/asm/pgtable.h index b03c043ce75b..c90ea5bfa1b4 100644 --- a/arch/xtensa/include/asm/pgtable.h +++ b/arch/xtensa/include/asm/pgtable.h | |||
| @@ -284,7 +284,7 @@ struct vm_area_struct; | |||
| 284 | 284 | ||
| 285 | static inline int | 285 | static inline int |
| 286 | ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, | 286 | ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, |
| 287 | pte_t *ptep) | 287 | pte_t *ptep) |
| 288 | { | 288 | { |
| 289 | pte_t pte = *ptep; | 289 | pte_t pte = *ptep; |
| 290 | if (!pte_young(pte)) | 290 | if (!pte_young(pte)) |
| @@ -304,8 +304,8 @@ ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) | |||
| 304 | static inline void | 304 | static inline void |
| 305 | ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep) | 305 | ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep) |
| 306 | { | 306 | { |
| 307 | pte_t pte = *ptep; | 307 | pte_t pte = *ptep; |
| 308 | update_pte(ptep, pte_wrprotect(pte)); | 308 | update_pte(ptep, pte_wrprotect(pte)); |
| 309 | } | 309 | } |
| 310 | 310 | ||
| 311 | /* to find an entry in a kernel page-table-directory */ | 311 | /* to find an entry in a kernel page-table-directory */ |
| @@ -399,7 +399,7 @@ extern void update_mmu_cache(struct vm_area_struct * vma, | |||
| 399 | */ | 399 | */ |
| 400 | 400 | ||
| 401 | #define io_remap_pfn_range(vma,from,pfn,size,prot) \ | 401 | #define io_remap_pfn_range(vma,from,pfn,size,prot) \ |
| 402 | remap_pfn_range(vma, from, pfn, size, prot) | 402 | remap_pfn_range(vma, from, pfn, size, prot) |
| 403 | 403 | ||
| 404 | typedef pte_t *pte_addr_t; | 404 | typedef pte_t *pte_addr_t; |
| 405 | 405 | ||
diff --git a/arch/xtensa/include/asm/platform.h b/arch/xtensa/include/asm/platform.h index 7d936e58e9be..ec098b68fb9a 100644 --- a/arch/xtensa/include/asm/platform.h +++ b/arch/xtensa/include/asm/platform.h | |||
| @@ -75,4 +75,3 @@ extern int platform_pcibios_fixup (void); | |||
| 75 | extern void platform_calibrate_ccount (void); | 75 | extern void platform_calibrate_ccount (void); |
| 76 | 76 | ||
| 77 | #endif /* _XTENSA_PLATFORM_H */ | 77 | #endif /* _XTENSA_PLATFORM_H */ |
| 78 | |||
diff --git a/arch/xtensa/include/asm/processor.h b/arch/xtensa/include/asm/processor.h index 2d630e7399ca..e5fb6b0abdf4 100644 --- a/arch/xtensa/include/asm/processor.h +++ b/arch/xtensa/include/asm/processor.h | |||
| @@ -89,7 +89,7 @@ | |||
| 89 | #define MAKE_PC_FROM_RA(ra,sp) (((ra) & 0x3fffffff) | ((sp) & 0xc0000000)) | 89 | #define MAKE_PC_FROM_RA(ra,sp) (((ra) & 0x3fffffff) | ((sp) & 0xc0000000)) |
| 90 | 90 | ||
| 91 | typedef struct { | 91 | typedef struct { |
| 92 | unsigned long seg; | 92 | unsigned long seg; |
| 93 | } mm_segment_t; | 93 | } mm_segment_t; |
| 94 | 94 | ||
| 95 | struct thread_struct { | 95 | struct thread_struct { |
| @@ -145,10 +145,10 @@ struct thread_struct { | |||
| 145 | * set_thread_state in signal.c depends on it. | 145 | * set_thread_state in signal.c depends on it. |
| 146 | */ | 146 | */ |
| 147 | #define USER_PS_VALUE ((1 << PS_WOE_BIT) | \ | 147 | #define USER_PS_VALUE ((1 << PS_WOE_BIT) | \ |
| 148 | (1 << PS_CALLINC_SHIFT) | \ | 148 | (1 << PS_CALLINC_SHIFT) | \ |
| 149 | (USER_RING << PS_RING_SHIFT) | \ | 149 | (USER_RING << PS_RING_SHIFT) | \ |
| 150 | (1 << PS_UM_BIT) | \ | 150 | (1 << PS_UM_BIT) | \ |
| 151 | (1 << PS_EXCM_BIT)) | 151 | (1 << PS_EXCM_BIT)) |
| 152 | 152 | ||
| 153 | /* Clearing a0 terminates the backtrace. */ | 153 | /* Clearing a0 terminates the backtrace. */ |
| 154 | #define start_thread(regs, new_pc, new_sp) \ | 154 | #define start_thread(regs, new_pc, new_sp) \ |
diff --git a/arch/xtensa/include/asm/prom.h b/arch/xtensa/include/asm/prom.h new file mode 100644 index 000000000000..f3d7cd2c0de7 --- /dev/null +++ b/arch/xtensa/include/asm/prom.h | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | #ifndef _XTENSA_ASM_PROM_H | ||
| 2 | #define _XTENSA_ASM_PROM_H | ||
| 3 | |||
| 4 | #define HAVE_ARCH_DEVTREE_FIXUPS | ||
| 5 | |||
| 6 | #endif /* _XTENSA_ASM_PROM_H */ | ||
diff --git a/arch/xtensa/include/asm/ptrace.h b/arch/xtensa/include/asm/ptrace.h index da21c17f23aa..58bf6fd3f913 100644 --- a/arch/xtensa/include/asm/ptrace.h +++ b/arch/xtensa/include/asm/ptrace.h | |||
| @@ -37,7 +37,7 @@ struct pt_regs { | |||
| 37 | unsigned long windowstart; /* 52 */ | 37 | unsigned long windowstart; /* 52 */ |
| 38 | unsigned long syscall; /* 56 */ | 38 | unsigned long syscall; /* 56 */ |
| 39 | unsigned long icountlevel; /* 60 */ | 39 | unsigned long icountlevel; /* 60 */ |
| 40 | int reserved[1]; /* 64 */ | 40 | unsigned long scompare1; /* 64 */ |
| 41 | 41 | ||
| 42 | /* Additional configurable registers that are used by the compiler. */ | 42 | /* Additional configurable registers that are used by the compiler. */ |
| 43 | xtregs_opt_t xtregs_opt; | 43 | xtregs_opt_t xtregs_opt; |
| @@ -55,7 +55,7 @@ struct pt_regs { | |||
| 55 | 55 | ||
| 56 | # define arch_has_single_step() (1) | 56 | # define arch_has_single_step() (1) |
| 57 | # define task_pt_regs(tsk) ((struct pt_regs*) \ | 57 | # define task_pt_regs(tsk) ((struct pt_regs*) \ |
| 58 | (task_stack_page(tsk) + KERNEL_STACK_SIZE - (XCHAL_NUM_AREGS-16)*4) - 1) | 58 | (task_stack_page(tsk) + KERNEL_STACK_SIZE - (XCHAL_NUM_AREGS-16)*4) - 1) |
| 59 | # define user_mode(regs) (((regs)->ps & 0x00000020)!=0) | 59 | # define user_mode(regs) (((regs)->ps & 0x00000020)!=0) |
| 60 | # define instruction_pointer(regs) ((regs)->pc) | 60 | # define instruction_pointer(regs) ((regs)->pc) |
| 61 | 61 | ||
diff --git a/arch/xtensa/include/asm/regs.h b/arch/xtensa/include/asm/regs.h index 8a8aa61ccc8d..76096a4e5b8d 100644 --- a/arch/xtensa/include/asm/regs.h +++ b/arch/xtensa/include/asm/regs.h | |||
| @@ -52,6 +52,10 @@ | |||
| 52 | #define EXCCAUSE_SPECULATION 7 | 52 | #define EXCCAUSE_SPECULATION 7 |
| 53 | #define EXCCAUSE_PRIVILEGED 8 | 53 | #define EXCCAUSE_PRIVILEGED 8 |
| 54 | #define EXCCAUSE_UNALIGNED 9 | 54 | #define EXCCAUSE_UNALIGNED 9 |
| 55 | #define EXCCAUSE_INSTR_DATA_ERROR 12 | ||
| 56 | #define EXCCAUSE_LOAD_STORE_DATA_ERROR 13 | ||
| 57 | #define EXCCAUSE_INSTR_ADDR_ERROR 14 | ||
| 58 | #define EXCCAUSE_LOAD_STORE_ADDR_ERROR 15 | ||
| 55 | #define EXCCAUSE_ITLB_MISS 16 | 59 | #define EXCCAUSE_ITLB_MISS 16 |
| 56 | #define EXCCAUSE_ITLB_MULTIHIT 17 | 60 | #define EXCCAUSE_ITLB_MULTIHIT 17 |
| 57 | #define EXCCAUSE_ITLB_PRIVILEGE 18 | 61 | #define EXCCAUSE_ITLB_PRIVILEGE 18 |
| @@ -105,4 +109,3 @@ | |||
| 105 | #define DEBUGCAUSE_ICOUNT_BIT 0 /* ICOUNT would incr. to zero */ | 109 | #define DEBUGCAUSE_ICOUNT_BIT 0 /* ICOUNT would incr. to zero */ |
| 106 | 110 | ||
| 107 | #endif /* _XTENSA_SPECREG_H */ | 111 | #endif /* _XTENSA_SPECREG_H */ |
| 108 | |||
diff --git a/arch/xtensa/include/asm/spinlock.h b/arch/xtensa/include/asm/spinlock.h index 8ff23649581b..03975906b36f 100644 --- a/arch/xtensa/include/asm/spinlock.h +++ b/arch/xtensa/include/asm/spinlock.h | |||
| @@ -11,6 +11,192 @@ | |||
| 11 | #ifndef _XTENSA_SPINLOCK_H | 11 | #ifndef _XTENSA_SPINLOCK_H |
| 12 | #define _XTENSA_SPINLOCK_H | 12 | #define _XTENSA_SPINLOCK_H |
| 13 | 13 | ||
| 14 | #include <linux/spinlock.h> | 14 | /* |
| 15 | * spinlock | ||
| 16 | * | ||
| 17 | * There is at most one owner of a spinlock. There are not different | ||
| 18 | * types of spinlock owners like there are for rwlocks (see below). | ||
| 19 | * | ||
| 20 | * When trying to obtain a spinlock, the function "spins" forever, or busy- | ||
| 21 | * waits, until the lock is obtained. When spinning, presumably some other | ||
| 22 | * owner will soon give up the spinlock making it available to others. Use | ||
| 23 | * the trylock functions to avoid spinning forever. | ||
| 24 | * | ||
| 25 | * possible values: | ||
| 26 | * | ||
| 27 | * 0 nobody owns the spinlock | ||
| 28 | * 1 somebody owns the spinlock | ||
| 29 | */ | ||
| 30 | |||
| 31 | #define __raw_spin_is_locked(x) ((x)->slock != 0) | ||
| 32 | #define __raw_spin_unlock_wait(lock) \ | ||
| 33 | do { while (__raw_spin_is_locked(lock)) cpu_relax(); } while (0) | ||
| 34 | |||
| 35 | #define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock) | ||
| 36 | |||
| 37 | static inline void __raw_spin_lock(raw_spinlock_t *lock) | ||
| 38 | { | ||
| 39 | unsigned long tmp; | ||
| 40 | |||
| 41 | __asm__ __volatile__( | ||
| 42 | " movi %0, 0\n" | ||
| 43 | " wsr %0, scompare1\n" | ||
| 44 | "1: movi %0, 1\n" | ||
| 45 | " s32c1i %0, %1, 0\n" | ||
| 46 | " bnez %0, 1b\n" | ||
| 47 | : "=&a" (tmp) | ||
| 48 | : "a" (&lock->slock) | ||
| 49 | : "memory"); | ||
| 50 | } | ||
| 51 | |||
| 52 | /* Returns 1 if the lock is obtained, 0 otherwise. */ | ||
| 53 | |||
| 54 | static inline int __raw_spin_trylock(raw_spinlock_t *lock) | ||
| 55 | { | ||
| 56 | unsigned long tmp; | ||
| 57 | |||
| 58 | __asm__ __volatile__( | ||
| 59 | " movi %0, 0\n" | ||
| 60 | " wsr %0, scompare1\n" | ||
| 61 | " movi %0, 1\n" | ||
| 62 | " s32c1i %0, %1, 0\n" | ||
| 63 | : "=&a" (tmp) | ||
| 64 | : "a" (&lock->slock) | ||
| 65 | : "memory"); | ||
| 66 | |||
| 67 | return tmp == 0 ? 1 : 0; | ||
| 68 | } | ||
| 69 | |||
| 70 | static inline void __raw_spin_unlock(raw_spinlock_t *lock) | ||
| 71 | { | ||
| 72 | unsigned long tmp; | ||
| 73 | |||
| 74 | __asm__ __volatile__( | ||
| 75 | " movi %0, 0\n" | ||
| 76 | " s32ri %0, %1, 0\n" | ||
| 77 | : "=&a" (tmp) | ||
| 78 | : "a" (&lock->slock) | ||
| 79 | : "memory"); | ||
| 80 | } | ||
| 81 | |||
| 82 | /* | ||
| 83 | * rwlock | ||
| 84 | * | ||
| 85 | * Read-write locks are really a more flexible spinlock. They allow | ||
| 86 | * multiple readers but only one writer. Write ownership is exclusive | ||
| 87 | * (i.e., all other readers and writers are blocked from ownership while | ||
| 88 | * there is a write owner). These rwlocks are unfair to writers. Writers | ||
| 89 | * can be starved for an indefinite time by readers. | ||
| 90 | * | ||
| 91 | * possible values: | ||
| 92 | * | ||
| 93 | * 0 nobody owns the rwlock | ||
| 94 | * >0 one or more readers own the rwlock | ||
| 95 | * (the positive value is the actual number of readers) | ||
| 96 | * 0x80000000 one writer owns the rwlock, no other writers, no readers | ||
| 97 | */ | ||
| 98 | |||
| 99 | #define __raw_write_can_lock(x) ((x)->lock == 0) | ||
| 100 | |||
| 101 | static inline void __raw_write_lock(raw_rwlock_t *rw) | ||
| 102 | { | ||
| 103 | unsigned long tmp; | ||
| 104 | |||
| 105 | __asm__ __volatile__( | ||
| 106 | " movi %0, 0\n" | ||
| 107 | " wsr %0, scompare1\n" | ||
| 108 | "1: movi %0, 1\n" | ||
| 109 | " slli %0, %0, 31\n" | ||
| 110 | " s32c1i %0, %1, 0\n" | ||
| 111 | " bnez %0, 1b\n" | ||
| 112 | : "=&a" (tmp) | ||
| 113 | : "a" (&rw->lock) | ||
| 114 | : "memory"); | ||
| 115 | } | ||
| 116 | |||
| 117 | /* Returns 1 if the lock is obtained, 0 otherwise. */ | ||
| 118 | |||
| 119 | static inline int __raw_write_trylock(raw_rwlock_t *rw) | ||
| 120 | { | ||
| 121 | unsigned long tmp; | ||
| 122 | |||
| 123 | __asm__ __volatile__( | ||
| 124 | " movi %0, 0\n" | ||
| 125 | " wsr %0, scompare1\n" | ||
| 126 | " movi %0, 1\n" | ||
| 127 | " slli %0, %0, 31\n" | ||
| 128 | " s32c1i %0, %1, 0\n" | ||
| 129 | : "=&a" (tmp) | ||
| 130 | : "a" (&rw->lock) | ||
| 131 | : "memory"); | ||
| 132 | |||
| 133 | return tmp == 0 ? 1 : 0; | ||
| 134 | } | ||
| 135 | |||
| 136 | static inline void __raw_write_unlock(raw_rwlock_t *rw) | ||
| 137 | { | ||
| 138 | unsigned long tmp; | ||
| 139 | |||
| 140 | __asm__ __volatile__( | ||
| 141 | " movi %0, 0\n" | ||
| 142 | " s32ri %0, %1, 0\n" | ||
| 143 | : "=&a" (tmp) | ||
| 144 | : "a" (&rw->lock) | ||
| 145 | : "memory"); | ||
| 146 | } | ||
| 147 | |||
| 148 | static inline void __raw_read_lock(raw_rwlock_t *rw) | ||
| 149 | { | ||
| 150 | unsigned long tmp; | ||
| 151 | unsigned long result; | ||
| 152 | |||
| 153 | __asm__ __volatile__( | ||
| 154 | "1: l32i %1, %2, 0\n" | ||
| 155 | " bltz %1, 1b\n" | ||
| 156 | " wsr %1, scompare1\n" | ||
| 157 | " addi %0, %1, 1\n" | ||
| 158 | " s32c1i %0, %2, 0\n" | ||
| 159 | " bne %0, %1, 1b\n" | ||
| 160 | : "=&a" (result), "=&a" (tmp) | ||
| 161 | : "a" (&rw->lock) | ||
| 162 | : "memory"); | ||
| 163 | } | ||
| 164 | |||
| 165 | /* Returns 1 if the lock is obtained, 0 otherwise. */ | ||
| 166 | |||
| 167 | static inline int __raw_read_trylock(raw_rwlock_t *rw) | ||
| 168 | { | ||
| 169 | unsigned long result; | ||
| 170 | unsigned long tmp; | ||
| 171 | |||
| 172 | __asm__ __volatile__( | ||
| 173 | " l32i %1, %2, 0\n" | ||
| 174 | " addi %0, %1, 1\n" | ||
| 175 | " bltz %0, 1f\n" | ||
| 176 | " wsr %1, scompare1\n" | ||
| 177 | " s32c1i %0, %2, 0\n" | ||
| 178 | " sub %0, %0, %1\n" | ||
| 179 | "1:\n" | ||
| 180 | : "=&a" (result), "=&a" (tmp) | ||
| 181 | : "a" (&rw->lock) | ||
| 182 | : "memory"); | ||
| 183 | |||
| 184 | return result == 0; | ||
| 185 | } | ||
| 186 | |||
| 187 | static inline void __raw_read_unlock(raw_rwlock_t *rw) | ||
| 188 | { | ||
| 189 | unsigned long tmp1, tmp2; | ||
| 190 | |||
| 191 | __asm__ __volatile__( | ||
| 192 | "1: l32i %1, %2, 0\n" | ||
| 193 | " addi %0, %1, -1\n" | ||
| 194 | " wsr %1, scompare1\n" | ||
| 195 | " s32c1i %0, %2, 0\n" | ||
| 196 | " bne %0, %1, 1b\n" | ||
| 197 | : "=&a" (tmp1), "=&a" (tmp2) | ||
| 198 | : "a" (&rw->lock) | ||
| 199 | : "memory"); | ||
| 200 | } | ||
| 15 | 201 | ||
| 16 | #endif /* _XTENSA_SPINLOCK_H */ | 202 | #endif /* _XTENSA_SPINLOCK_H */ |
diff --git a/arch/xtensa/include/asm/syscall.h b/arch/xtensa/include/asm/syscall.h index b00c928d4cce..8d5e47fad095 100644 --- a/arch/xtensa/include/asm/syscall.h +++ b/arch/xtensa/include/asm/syscall.h | |||
| @@ -25,9 +25,10 @@ asmlinkage long xtensa_fadvise64_64(int, int, | |||
| 25 | /* Should probably move to linux/syscalls.h */ | 25 | /* Should probably move to linux/syscalls.h */ |
| 26 | struct pollfd; | 26 | struct pollfd; |
| 27 | asmlinkage long sys_pselect6(int n, fd_set __user *inp, fd_set __user *outp, | 27 | asmlinkage long sys_pselect6(int n, fd_set __user *inp, fd_set __user *outp, |
| 28 | fd_set __user *exp, struct timespec __user *tsp, void __user *sig); | 28 | fd_set __user *exp, struct timespec __user *tsp, |
| 29 | void __user *sig); | ||
| 29 | asmlinkage long sys_ppoll(struct pollfd __user *ufds, unsigned int nfds, | 30 | asmlinkage long sys_ppoll(struct pollfd __user *ufds, unsigned int nfds, |
| 30 | struct timespec __user *tsp, const sigset_t __user *sigmask, | 31 | struct timespec __user *tsp, |
| 31 | size_t sigsetsize); | 32 | const sigset_t __user *sigmask, |
| 32 | asmlinkage long sys_rt_sigsuspend(sigset_t __user *unewset, | 33 | size_t sigsetsize); |
| 33 | size_t sigsetsize); | 34 | asmlinkage long sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize); |
diff --git a/arch/xtensa/include/asm/traps.h b/arch/xtensa/include/asm/traps.h new file mode 100644 index 000000000000..54f70440185e --- /dev/null +++ b/arch/xtensa/include/asm/traps.h | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | /* | ||
| 2 | * arch/xtensa/include/asm/traps.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) 2012 Tensilica Inc. | ||
| 9 | */ | ||
| 10 | #ifndef _XTENSA_TRAPS_H | ||
| 11 | #define _XTENSA_TRAPS_H | ||
| 12 | |||
| 13 | #include <asm/ptrace.h> | ||
| 14 | |||
| 15 | /* | ||
| 16 | * handler must be either of the following: | ||
| 17 | * void (*)(struct pt_regs *regs); | ||
| 18 | * void (*)(struct pt_regs *regs, unsigned long exccause); | ||
| 19 | */ | ||
| 20 | extern void * __init trap_set_handler(int cause, void *handler); | ||
| 21 | extern void do_unhandled(struct pt_regs *regs, unsigned long exccause); | ||
| 22 | |||
| 23 | #endif /* _XTENSA_TRAPS_H */ | ||
diff --git a/arch/xtensa/include/asm/uaccess.h b/arch/xtensa/include/asm/uaccess.h index 6e4bb3b791ab..fd686dc45d1a 100644 --- a/arch/xtensa/include/asm/uaccess.h +++ b/arch/xtensa/include/asm/uaccess.h | |||
| @@ -180,7 +180,8 @@ | |||
| 180 | #define segment_eq(a,b) ((a).seg == (b).seg) | 180 | #define segment_eq(a,b) ((a).seg == (b).seg) |
| 181 | 181 | ||
| 182 | #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS)) | 182 | #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS)) |
| 183 | #define __user_ok(addr,size) (((size) <= TASK_SIZE)&&((addr) <= TASK_SIZE-(size))) | 183 | #define __user_ok(addr,size) \ |
| 184 | (((size) <= TASK_SIZE)&&((addr) <= TASK_SIZE-(size))) | ||
| 184 | #define __access_ok(addr,size) (__kernel_ok || __user_ok((addr),(size))) | 185 | #define __access_ok(addr,size) (__kernel_ok || __user_ok((addr),(size))) |
| 185 | #define access_ok(type,addr,size) __access_ok((unsigned long)(addr),(size)) | 186 | #define access_ok(type,addr,size) __access_ok((unsigned long)(addr),(size)) |
| 186 | 187 | ||
| @@ -234,10 +235,10 @@ do { \ | |||
| 234 | int __cb; \ | 235 | int __cb; \ |
| 235 | retval = 0; \ | 236 | retval = 0; \ |
| 236 | switch (size) { \ | 237 | switch (size) { \ |
| 237 | case 1: __put_user_asm(x,ptr,retval,1,"s8i",__cb); break; \ | 238 | case 1: __put_user_asm(x,ptr,retval,1,"s8i",__cb); break; \ |
| 238 | case 2: __put_user_asm(x,ptr,retval,2,"s16i",__cb); break; \ | 239 | case 2: __put_user_asm(x,ptr,retval,2,"s16i",__cb); break; \ |
| 239 | case 4: __put_user_asm(x,ptr,retval,4,"s32i",__cb); break; \ | 240 | case 4: __put_user_asm(x,ptr,retval,4,"s32i",__cb); break; \ |
| 240 | case 8: { \ | 241 | case 8: { \ |
| 241 | __typeof__(*ptr) __v64 = x; \ | 242 | __typeof__(*ptr) __v64 = x; \ |
| 242 | retval = __copy_to_user(ptr,&__v64,8); \ | 243 | retval = __copy_to_user(ptr,&__v64,8); \ |
| 243 | break; \ | 244 | break; \ |
| @@ -291,7 +292,7 @@ do { \ | |||
| 291 | * __check_align_* macros still work. | 292 | * __check_align_* macros still work. |
| 292 | */ | 293 | */ |
| 293 | #define __put_user_asm(x, addr, err, align, insn, cb) \ | 294 | #define __put_user_asm(x, addr, err, align, insn, cb) \ |
| 294 | __asm__ __volatile__( \ | 295 | __asm__ __volatile__( \ |
| 295 | __check_align_##align \ | 296 | __check_align_##align \ |
| 296 | "1: "insn" %2, %3, 0 \n" \ | 297 | "1: "insn" %2, %3, 0 \n" \ |
| 297 | "2: \n" \ | 298 | "2: \n" \ |
| @@ -301,8 +302,8 @@ do { \ | |||
| 301 | " .long 2b \n" \ | 302 | " .long 2b \n" \ |
| 302 | "5: \n" \ | 303 | "5: \n" \ |
| 303 | " l32r %1, 4b \n" \ | 304 | " l32r %1, 4b \n" \ |
| 304 | " movi %0, %4 \n" \ | 305 | " movi %0, %4 \n" \ |
| 305 | " jx %1 \n" \ | 306 | " jx %1 \n" \ |
| 306 | " .previous \n" \ | 307 | " .previous \n" \ |
| 307 | " .section __ex_table,\"a\" \n" \ | 308 | " .section __ex_table,\"a\" \n" \ |
| 308 | " .long 1b, 5b \n" \ | 309 | " .long 1b, 5b \n" \ |
| @@ -334,13 +335,13 @@ extern long __get_user_bad(void); | |||
| 334 | do { \ | 335 | do { \ |
| 335 | int __cb; \ | 336 | int __cb; \ |
| 336 | retval = 0; \ | 337 | retval = 0; \ |
| 337 | switch (size) { \ | 338 | switch (size) { \ |
| 338 | case 1: __get_user_asm(x,ptr,retval,1,"l8ui",__cb); break; \ | 339 | case 1: __get_user_asm(x,ptr,retval,1,"l8ui",__cb); break; \ |
| 339 | case 2: __get_user_asm(x,ptr,retval,2,"l16ui",__cb); break; \ | 340 | case 2: __get_user_asm(x,ptr,retval,2,"l16ui",__cb); break; \ |
| 340 | case 4: __get_user_asm(x,ptr,retval,4,"l32i",__cb); break; \ | 341 | case 4: __get_user_asm(x,ptr,retval,4,"l32i",__cb); break; \ |
| 341 | case 8: retval = __copy_from_user(&x,ptr,8); break; \ | 342 | case 8: retval = __copy_from_user(&x,ptr,8); break; \ |
| 342 | default: (x) = __get_user_bad(); \ | 343 | default: (x) = __get_user_bad(); \ |
| 343 | } \ | 344 | } \ |
| 344 | } while (0) | 345 | } while (0) |
| 345 | 346 | ||
| 346 | 347 | ||
| @@ -349,7 +350,7 @@ do { \ | |||
| 349 | * __check_align_* macros still work. | 350 | * __check_align_* macros still work. |
| 350 | */ | 351 | */ |
| 351 | #define __get_user_asm(x, addr, err, align, insn, cb) \ | 352 | #define __get_user_asm(x, addr, err, align, insn, cb) \ |
| 352 | __asm__ __volatile__( \ | 353 | __asm__ __volatile__( \ |
| 353 | __check_align_##align \ | 354 | __check_align_##align \ |
| 354 | "1: "insn" %2, %3, 0 \n" \ | 355 | "1: "insn" %2, %3, 0 \n" \ |
| 355 | "2: \n" \ | 356 | "2: \n" \ |
| @@ -360,8 +361,8 @@ do { \ | |||
| 360 | "5: \n" \ | 361 | "5: \n" \ |
| 361 | " l32r %1, 4b \n" \ | 362 | " l32r %1, 4b \n" \ |
| 362 | " movi %2, 0 \n" \ | 363 | " movi %2, 0 \n" \ |
| 363 | " movi %0, %4 \n" \ | 364 | " movi %0, %4 \n" \ |
| 364 | " jx %1 \n" \ | 365 | " jx %1 \n" \ |
| 365 | " .previous \n" \ | 366 | " .previous \n" \ |
| 366 | " .section __ex_table,\"a\" \n" \ | 367 | " .section __ex_table,\"a\" \n" \ |
| 367 | " .long 1b, 5b \n" \ | 368 | " .long 1b, 5b \n" \ |
| @@ -421,8 +422,10 @@ __generic_copy_from_user(void *to, const void *from, unsigned long n) | |||
| 421 | 422 | ||
| 422 | #define copy_to_user(to,from,n) __generic_copy_to_user((to),(from),(n)) | 423 | #define copy_to_user(to,from,n) __generic_copy_to_user((to),(from),(n)) |
| 423 | #define copy_from_user(to,from,n) __generic_copy_from_user((to),(from),(n)) | 424 | #define copy_from_user(to,from,n) __generic_copy_from_user((to),(from),(n)) |
| 424 | #define __copy_to_user(to,from,n) __generic_copy_to_user_nocheck((to),(from),(n)) | 425 | #define __copy_to_user(to,from,n) \ |
| 425 | #define __copy_from_user(to,from,n) __generic_copy_from_user_nocheck((to),(from),(n)) | 426 | __generic_copy_to_user_nocheck((to),(from),(n)) |
| 427 | #define __copy_from_user(to,from,n) \ | ||
| 428 | __generic_copy_from_user_nocheck((to),(from),(n)) | ||
| 426 | #define __copy_to_user_inatomic __copy_to_user | 429 | #define __copy_to_user_inatomic __copy_to_user |
| 427 | #define __copy_from_user_inatomic __copy_from_user | 430 | #define __copy_from_user_inatomic __copy_from_user |
| 428 | 431 | ||
diff --git a/arch/xtensa/kernel/Makefile b/arch/xtensa/kernel/Makefile index f36cef5a62ff..c3a59d992ac0 100644 --- a/arch/xtensa/kernel/Makefile +++ b/arch/xtensa/kernel/Makefile | |||
| @@ -23,13 +23,13 @@ obj-$(CONFIG_MODULES) += xtensa_ksyms.o module.o | |||
| 23 | # | 23 | # |
| 24 | # Replicate rules in scripts/Makefile.build | 24 | # Replicate rules in scripts/Makefile.build |
| 25 | 25 | ||
| 26 | sed-y = -e 's/\*(\(\.[a-z]*it\|\.ref\|\)\.text)/*(\1.literal \1.text)/g' \ | 26 | sed-y = -e 's/\*(\(\.[a-z]*it\|\.ref\|\)\.text)/*(\1.literal \1.text)/g' \ |
| 27 | -e 's/\.text\.unlikely/.literal.unlikely .text.unlikely/g' \ | 27 | -e 's/\.text\.unlikely/.literal.unlikely .text.unlikely/g' \ |
| 28 | -e 's/\*(\(\.text\.[a-z]*\))/*(\1.literal \1)/g' | 28 | -e 's/\*(\(\.text\.[a-z]*\))/*(\1.literal \1)/g' |
| 29 | 29 | ||
| 30 | quiet_cmd__cpp_lds_S = LDS $@ | 30 | quiet_cmd__cpp_lds_S = LDS $@ |
| 31 | cmd__cpp_lds_S = $(CPP) $(cpp_flags) -P -C -Uxtensa -D__ASSEMBLY__ $< \ | 31 | cmd__cpp_lds_S = $(CPP) $(cpp_flags) -P -C -Uxtensa -D__ASSEMBLY__ $< \ |
| 32 | | sed $(sed-y) >$@ | 32 | | sed $(sed-y) >$@ |
| 33 | 33 | ||
| 34 | $(obj)/vmlinux.lds: $(src)/vmlinux.lds.S FORCE | 34 | $(obj)/vmlinux.lds: $(src)/vmlinux.lds.S FORCE |
| 35 | $(call if_changed_dep,_cpp_lds_S) | 35 | $(call if_changed_dep,_cpp_lds_S) |
diff --git a/arch/xtensa/kernel/align.S b/arch/xtensa/kernel/align.S index 934ae58e2c79..aa2e87b8566a 100644 --- a/arch/xtensa/kernel/align.S +++ b/arch/xtensa/kernel/align.S | |||
| @@ -442,7 +442,7 @@ ENTRY(fast_unaligned) | |||
| 442 | mov a1, a2 | 442 | mov a1, a2 |
| 443 | 443 | ||
| 444 | rsr a0, ps | 444 | rsr a0, ps |
| 445 | bbsi.l a2, PS_UM_BIT, 1f # jump if user mode | 445 | bbsi.l a2, PS_UM_BIT, 1f # jump if user mode |
| 446 | 446 | ||
| 447 | movi a0, _kernel_exception | 447 | movi a0, _kernel_exception |
| 448 | jx a0 | 448 | jx a0 |
| @@ -450,6 +450,6 @@ ENTRY(fast_unaligned) | |||
| 450 | 1: movi a0, _user_exception | 450 | 1: movi a0, _user_exception |
| 451 | jx a0 | 451 | jx a0 |
| 452 | 452 | ||
| 453 | ENDPROC(fast_unaligned) | ||
| 453 | 454 | ||
| 454 | #endif /* XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION */ | 455 | #endif /* XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION */ |
| 455 | |||
diff --git a/arch/xtensa/kernel/asm-offsets.c b/arch/xtensa/kernel/asm-offsets.c index 7dc3f9157185..0701fad170db 100644 --- a/arch/xtensa/kernel/asm-offsets.c +++ b/arch/xtensa/kernel/asm-offsets.c | |||
| @@ -41,6 +41,7 @@ int main(void) | |||
| 41 | DEFINE(PT_SAR, offsetof (struct pt_regs, sar)); | 41 | DEFINE(PT_SAR, offsetof (struct pt_regs, sar)); |
| 42 | DEFINE(PT_ICOUNTLEVEL, offsetof (struct pt_regs, icountlevel)); | 42 | DEFINE(PT_ICOUNTLEVEL, offsetof (struct pt_regs, icountlevel)); |
| 43 | DEFINE(PT_SYSCALL, offsetof (struct pt_regs, syscall)); | 43 | DEFINE(PT_SYSCALL, offsetof (struct pt_regs, syscall)); |
| 44 | DEFINE(PT_SCOMPARE1, offsetof(struct pt_regs, scompare1)); | ||
| 44 | DEFINE(PT_AREG, offsetof (struct pt_regs, areg[0])); | 45 | DEFINE(PT_AREG, offsetof (struct pt_regs, areg[0])); |
| 45 | DEFINE(PT_AREG0, offsetof (struct pt_regs, areg[0])); | 46 | DEFINE(PT_AREG0, offsetof (struct pt_regs, areg[0])); |
| 46 | DEFINE(PT_AREG1, offsetof (struct pt_regs, areg[1])); | 47 | DEFINE(PT_AREG1, offsetof (struct pt_regs, areg[1])); |
| @@ -91,7 +92,8 @@ int main(void) | |||
| 91 | #endif | 92 | #endif |
| 92 | DEFINE(THREAD_XTREGS_USER, offsetof (struct thread_info, xtregs_user)); | 93 | DEFINE(THREAD_XTREGS_USER, offsetof (struct thread_info, xtregs_user)); |
| 93 | DEFINE(XTREGS_USER_SIZE, sizeof(xtregs_user_t)); | 94 | DEFINE(XTREGS_USER_SIZE, sizeof(xtregs_user_t)); |
| 94 | DEFINE(THREAD_CURRENT_DS, offsetof (struct task_struct, thread.current_ds)); | 95 | DEFINE(THREAD_CURRENT_DS, offsetof (struct task_struct, \ |
| 96 | thread.current_ds)); | ||
| 95 | 97 | ||
| 96 | /* struct mm_struct */ | 98 | /* struct mm_struct */ |
| 97 | DEFINE(MM_USERS, offsetof(struct mm_struct, mm_users)); | 99 | DEFINE(MM_USERS, offsetof(struct mm_struct, mm_users)); |
| @@ -108,4 +110,3 @@ int main(void) | |||
| 108 | 110 | ||
| 109 | return 0; | 111 | return 0; |
| 110 | } | 112 | } |
| 111 | |||
diff --git a/arch/xtensa/kernel/coprocessor.S b/arch/xtensa/kernel/coprocessor.S index 54c3be313bfa..647657484866 100644 --- a/arch/xtensa/kernel/coprocessor.S +++ b/arch/xtensa/kernel/coprocessor.S | |||
| @@ -43,10 +43,13 @@ | |||
| 43 | /* IO protection is currently unsupported. */ | 43 | /* IO protection is currently unsupported. */ |
| 44 | 44 | ||
| 45 | ENTRY(fast_io_protect) | 45 | ENTRY(fast_io_protect) |
| 46 | |||
| 46 | wsr a0, excsave1 | 47 | wsr a0, excsave1 |
| 47 | movi a0, unrecoverable_exception | 48 | movi a0, unrecoverable_exception |
| 48 | callx0 a0 | 49 | callx0 a0 |
| 49 | 50 | ||
| 51 | ENDPROC(fast_io_protect) | ||
| 52 | |||
| 50 | #if XTENSA_HAVE_COPROCESSORS | 53 | #if XTENSA_HAVE_COPROCESSORS |
| 51 | 54 | ||
| 52 | /* | 55 | /* |
| @@ -139,6 +142,7 @@ ENTRY(fast_io_protect) | |||
| 139 | */ | 142 | */ |
| 140 | 143 | ||
| 141 | ENTRY(coprocessor_save) | 144 | ENTRY(coprocessor_save) |
| 145 | |||
| 142 | entry a1, 32 | 146 | entry a1, 32 |
| 143 | s32i a0, a1, 0 | 147 | s32i a0, a1, 0 |
| 144 | movi a0, .Lsave_cp_regs_jump_table | 148 | movi a0, .Lsave_cp_regs_jump_table |
| @@ -150,7 +154,10 @@ ENTRY(coprocessor_save) | |||
| 150 | 1: l32i a0, a1, 0 | 154 | 1: l32i a0, a1, 0 |
| 151 | retw | 155 | retw |
| 152 | 156 | ||
| 157 | ENDPROC(coprocessor_save) | ||
| 158 | |||
| 153 | ENTRY(coprocessor_load) | 159 | ENTRY(coprocessor_load) |
| 160 | |||
| 154 | entry a1, 32 | 161 | entry a1, 32 |
| 155 | s32i a0, a1, 0 | 162 | s32i a0, a1, 0 |
| 156 | movi a0, .Lload_cp_regs_jump_table | 163 | movi a0, .Lload_cp_regs_jump_table |
| @@ -162,8 +169,10 @@ ENTRY(coprocessor_load) | |||
| 162 | 1: l32i a0, a1, 0 | 169 | 1: l32i a0, a1, 0 |
| 163 | retw | 170 | retw |
| 164 | 171 | ||
| 172 | ENDPROC(coprocessor_load) | ||
| 173 | |||
| 165 | /* | 174 | /* |
| 166 | * coprocessor_flush(struct task_info*, index) | 175 | * coprocessor_flush(struct task_info*, index) |
| 167 | * a2 a3 | 176 | * a2 a3 |
| 168 | * coprocessor_restore(struct task_info*, index) | 177 | * coprocessor_restore(struct task_info*, index) |
| 169 | * a2 a3 | 178 | * a2 a3 |
| @@ -178,6 +187,7 @@ ENTRY(coprocessor_load) | |||
| 178 | 187 | ||
| 179 | 188 | ||
| 180 | ENTRY(coprocessor_flush) | 189 | ENTRY(coprocessor_flush) |
| 190 | |||
| 181 | entry a1, 32 | 191 | entry a1, 32 |
| 182 | s32i a0, a1, 0 | 192 | s32i a0, a1, 0 |
| 183 | movi a0, .Lsave_cp_regs_jump_table | 193 | movi a0, .Lsave_cp_regs_jump_table |
| @@ -191,6 +201,8 @@ ENTRY(coprocessor_flush) | |||
| 191 | 1: l32i a0, a1, 0 | 201 | 1: l32i a0, a1, 0 |
| 192 | retw | 202 | retw |
| 193 | 203 | ||
| 204 | ENDPROC(coprocessor_flush) | ||
| 205 | |||
| 194 | ENTRY(coprocessor_restore) | 206 | ENTRY(coprocessor_restore) |
| 195 | entry a1, 32 | 207 | entry a1, 32 |
| 196 | s32i a0, a1, 0 | 208 | s32i a0, a1, 0 |
| @@ -205,6 +217,8 @@ ENTRY(coprocessor_restore) | |||
| 205 | 1: l32i a0, a1, 0 | 217 | 1: l32i a0, a1, 0 |
| 206 | retw | 218 | retw |
| 207 | 219 | ||
| 220 | ENDPROC(coprocessor_restore) | ||
| 221 | |||
| 208 | /* | 222 | /* |
| 209 | * Entry condition: | 223 | * Entry condition: |
| 210 | * | 224 | * |
| @@ -220,10 +234,12 @@ ENTRY(coprocessor_restore) | |||
| 220 | */ | 234 | */ |
| 221 | 235 | ||
| 222 | ENTRY(fast_coprocessor_double) | 236 | ENTRY(fast_coprocessor_double) |
| 237 | |||
| 223 | wsr a0, excsave1 | 238 | wsr a0, excsave1 |
| 224 | movi a0, unrecoverable_exception | 239 | movi a0, unrecoverable_exception |
| 225 | callx0 a0 | 240 | callx0 a0 |
| 226 | 241 | ||
| 242 | ENDPROC(fast_coprocessor_double) | ||
| 227 | 243 | ||
| 228 | ENTRY(fast_coprocessor) | 244 | ENTRY(fast_coprocessor) |
| 229 | 245 | ||
| @@ -327,9 +343,14 @@ ENTRY(fast_coprocessor) | |||
| 327 | 343 | ||
| 328 | rfe | 344 | rfe |
| 329 | 345 | ||
| 346 | ENDPROC(fast_coprocessor) | ||
| 347 | |||
| 330 | .data | 348 | .data |
| 349 | |||
| 331 | ENTRY(coprocessor_owner) | 350 | ENTRY(coprocessor_owner) |
| 351 | |||
| 332 | .fill XCHAL_CP_MAX, 4, 0 | 352 | .fill XCHAL_CP_MAX, 4, 0 |
| 333 | 353 | ||
| 334 | #endif /* XTENSA_HAVE_COPROCESSORS */ | 354 | END(coprocessor_owner) |
| 335 | 355 | ||
| 356 | #endif /* XTENSA_HAVE_COPROCESSORS */ | ||
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S index 90bfc1dbc13d..3777fec85e7c 100644 --- a/arch/xtensa/kernel/entry.S +++ b/arch/xtensa/kernel/entry.S | |||
| @@ -219,6 +219,7 @@ _user_exception: | |||
| 219 | 219 | ||
| 220 | j common_exception | 220 | j common_exception |
| 221 | 221 | ||
| 222 | ENDPROC(user_exception) | ||
| 222 | 223 | ||
| 223 | /* | 224 | /* |
| 224 | * First-level exit handler for kernel exceptions | 225 | * First-level exit handler for kernel exceptions |
| @@ -371,6 +372,13 @@ common_exception: | |||
| 371 | s32i a2, a1, PT_LBEG | 372 | s32i a2, a1, PT_LBEG |
| 372 | s32i a3, a1, PT_LEND | 373 | s32i a3, a1, PT_LEND |
| 373 | 374 | ||
| 375 | /* Save SCOMPARE1 */ | ||
| 376 | |||
| 377 | #if XCHAL_HAVE_S32C1I | ||
| 378 | rsr a2, scompare1 | ||
| 379 | s32i a2, a1, PT_SCOMPARE1 | ||
| 380 | #endif | ||
| 381 | |||
| 374 | /* Save optional registers. */ | 382 | /* Save optional registers. */ |
| 375 | 383 | ||
| 376 | save_xtregs_opt a1 a2 a4 a5 a6 a7 PT_XTREGS_OPT | 384 | save_xtregs_opt a1 a2 a4 a5 a6 a7 PT_XTREGS_OPT |
| @@ -432,6 +440,12 @@ common_exception_return: | |||
| 432 | 440 | ||
| 433 | load_xtregs_opt a1 a2 a4 a5 a6 a7 PT_XTREGS_OPT | 441 | load_xtregs_opt a1 a2 a4 a5 a6 a7 PT_XTREGS_OPT |
| 434 | 442 | ||
| 443 | /* Restore SCOMPARE1 */ | ||
| 444 | |||
| 445 | #if XCHAL_HAVE_S32C1I | ||
| 446 | l32i a2, a1, PT_SCOMPARE1 | ||
| 447 | wsr a2, scompare1 | ||
| 448 | #endif | ||
| 435 | wsr a3, ps /* disable interrupts */ | 449 | wsr a3, ps /* disable interrupts */ |
| 436 | 450 | ||
| 437 | _bbci.l a3, PS_UM_BIT, kernel_exception_exit | 451 | _bbci.l a3, PS_UM_BIT, kernel_exception_exit |
| @@ -641,6 +655,8 @@ common_exception_exit: | |||
| 641 | l32i a1, a1, PT_AREG1 | 655 | l32i a1, a1, PT_AREG1 |
| 642 | rfde | 656 | rfde |
| 643 | 657 | ||
| 658 | ENDPROC(kernel_exception) | ||
| 659 | |||
| 644 | /* | 660 | /* |
| 645 | * Debug exception handler. | 661 | * Debug exception handler. |
| 646 | * | 662 | * |
| @@ -701,6 +717,7 @@ ENTRY(debug_exception) | |||
| 701 | /* Debug exception while in exception mode. */ | 717 | /* Debug exception while in exception mode. */ |
| 702 | 1: j 1b // FIXME!! | 718 | 1: j 1b // FIXME!! |
| 703 | 719 | ||
| 720 | ENDPROC(debug_exception) | ||
| 704 | 721 | ||
| 705 | /* | 722 | /* |
| 706 | * We get here in case of an unrecoverable exception. | 723 | * We get here in case of an unrecoverable exception. |
| @@ -751,6 +768,7 @@ ENTRY(unrecoverable_exception) | |||
| 751 | 768 | ||
| 752 | 1: j 1b | 769 | 1: j 1b |
| 753 | 770 | ||
| 771 | ENDPROC(unrecoverable_exception) | ||
| 754 | 772 | ||
| 755 | /* -------------------------- FAST EXCEPTION HANDLERS ----------------------- */ | 773 | /* -------------------------- FAST EXCEPTION HANDLERS ----------------------- */ |
| 756 | 774 | ||
| @@ -856,7 +874,7 @@ ENTRY(fast_alloca) | |||
| 856 | 874 | ||
| 857 | _bnei a0, 1, 1f # no 'movsp a1, ax': jump | 875 | _bnei a0, 1, 1f # no 'movsp a1, ax': jump |
| 858 | 876 | ||
| 859 | /* Move the save area. This implies the use of the L32E | 877 | /* Move the save area. This implies the use of the L32E |
| 860 | * and S32E instructions, because this move must be done with | 878 | * and S32E instructions, because this move must be done with |
| 861 | * the user's PS.RING privilege levels, not with ring 0 | 879 | * the user's PS.RING privilege levels, not with ring 0 |
| 862 | * (kernel's) privileges currently active with PS.EXCM | 880 | * (kernel's) privileges currently active with PS.EXCM |
| @@ -929,6 +947,7 @@ ENTRY(fast_alloca) | |||
| 929 | l32i a2, a2, PT_AREG2 | 947 | l32i a2, a2, PT_AREG2 |
| 930 | rfe | 948 | rfe |
| 931 | 949 | ||
| 950 | ENDPROC(fast_alloca) | ||
| 932 | 951 | ||
| 933 | /* | 952 | /* |
| 934 | * fast system calls. | 953 | * fast system calls. |
| @@ -966,6 +985,8 @@ ENTRY(fast_syscall_kernel) | |||
| 966 | 985 | ||
| 967 | j kernel_exception | 986 | j kernel_exception |
| 968 | 987 | ||
| 988 | ENDPROC(fast_syscall_kernel) | ||
| 989 | |||
| 969 | ENTRY(fast_syscall_user) | 990 | ENTRY(fast_syscall_user) |
| 970 | 991 | ||
| 971 | /* Skip syscall. */ | 992 | /* Skip syscall. */ |
| @@ -983,19 +1004,21 @@ ENTRY(fast_syscall_user) | |||
| 983 | 1004 | ||
| 984 | j user_exception | 1005 | j user_exception |
| 985 | 1006 | ||
| 986 | ENTRY(fast_syscall_unrecoverable) | 1007 | ENDPROC(fast_syscall_user) |
| 987 | 1008 | ||
| 988 | /* Restore all states. */ | 1009 | ENTRY(fast_syscall_unrecoverable) |
| 989 | 1010 | ||
| 990 | l32i a0, a2, PT_AREG0 # restore a0 | 1011 | /* Restore all states. */ |
| 991 | xsr a2, depc # restore a2, depc | ||
| 992 | rsr a3, excsave1 | ||
| 993 | 1012 | ||
| 994 | wsr a0, excsave1 | 1013 | l32i a0, a2, PT_AREG0 # restore a0 |
| 995 | movi a0, unrecoverable_exception | 1014 | xsr a2, depc # restore a2, depc |
| 996 | callx0 a0 | 1015 | rsr a3, excsave1 |
| 997 | 1016 | ||
| 1017 | wsr a0, excsave1 | ||
| 1018 | movi a0, unrecoverable_exception | ||
| 1019 | callx0 a0 | ||
| 998 | 1020 | ||
| 1021 | ENDPROC(fast_syscall_unrecoverable) | ||
| 999 | 1022 | ||
| 1000 | /* | 1023 | /* |
| 1001 | * sysxtensa syscall handler | 1024 | * sysxtensa syscall handler |
| @@ -1101,7 +1124,7 @@ CATCH | |||
| 1101 | movi a2, -EINVAL | 1124 | movi a2, -EINVAL |
| 1102 | rfe | 1125 | rfe |
| 1103 | 1126 | ||
| 1104 | 1127 | ENDPROC(fast_syscall_xtensa) | |
| 1105 | 1128 | ||
| 1106 | 1129 | ||
| 1107 | /* fast_syscall_spill_registers. | 1130 | /* fast_syscall_spill_registers. |
| @@ -1160,6 +1183,8 @@ ENTRY(fast_syscall_spill_registers) | |||
| 1160 | movi a2, 0 | 1183 | movi a2, 0 |
| 1161 | rfe | 1184 | rfe |
| 1162 | 1185 | ||
| 1186 | ENDPROC(fast_syscall_spill_registers) | ||
| 1187 | |||
| 1163 | /* Fixup handler. | 1188 | /* Fixup handler. |
| 1164 | * | 1189 | * |
| 1165 | * We get here if the spill routine causes an exception, e.g. tlb miss. | 1190 | * We get here if the spill routine causes an exception, e.g. tlb miss. |
| @@ -1228,9 +1253,9 @@ fast_syscall_spill_registers_fixup: | |||
| 1228 | 1253 | ||
| 1229 | movi a3, exc_table | 1254 | movi a3, exc_table |
| 1230 | rsr a0, exccause | 1255 | rsr a0, exccause |
| 1231 | addx4 a0, a0, a3 # find entry in table | 1256 | addx4 a0, a0, a3 # find entry in table |
| 1232 | l32i a0, a0, EXC_TABLE_FAST_USER # load handler | 1257 | l32i a0, a0, EXC_TABLE_FAST_USER # load handler |
| 1233 | jx a0 | 1258 | jx a0 |
| 1234 | 1259 | ||
| 1235 | fast_syscall_spill_registers_fixup_return: | 1260 | fast_syscall_spill_registers_fixup_return: |
| 1236 | 1261 | ||
| @@ -1432,7 +1457,7 @@ ENTRY(_spill_registers) | |||
| 1432 | rsr a0, ps | 1457 | rsr a0, ps |
| 1433 | _bbci.l a0, PS_UM_BIT, 1f | 1458 | _bbci.l a0, PS_UM_BIT, 1f |
| 1434 | 1459 | ||
| 1435 | /* User space: Setup a dummy frame and kill application. | 1460 | /* User space: Setup a dummy frame and kill application. |
| 1436 | * Note: We assume EXC_TABLE_KSTK contains a valid stack pointer. | 1461 | * Note: We assume EXC_TABLE_KSTK contains a valid stack pointer. |
| 1437 | */ | 1462 | */ |
| 1438 | 1463 | ||
| @@ -1464,6 +1489,8 @@ ENTRY(_spill_registers) | |||
| 1464 | callx0 a0 # should not return | 1489 | callx0 a0 # should not return |
| 1465 | 1: j 1b | 1490 | 1: j 1b |
| 1466 | 1491 | ||
| 1492 | ENDPROC(_spill_registers) | ||
| 1493 | |||
| 1467 | #ifdef CONFIG_MMU | 1494 | #ifdef CONFIG_MMU |
| 1468 | /* | 1495 | /* |
| 1469 | * We should never get here. Bail out! | 1496 | * We should never get here. Bail out! |
| @@ -1475,6 +1502,8 @@ ENTRY(fast_second_level_miss_double_kernel) | |||
| 1475 | callx0 a0 # should not return | 1502 | callx0 a0 # should not return |
| 1476 | 1: j 1b | 1503 | 1: j 1b |
| 1477 | 1504 | ||
| 1505 | ENDPROC(fast_second_level_miss_double_kernel) | ||
| 1506 | |||
| 1478 | /* First-level entry handler for user, kernel, and double 2nd-level | 1507 | /* First-level entry handler for user, kernel, and double 2nd-level |
| 1479 | * TLB miss exceptions. Note that for now, user and kernel miss | 1508 | * TLB miss exceptions. Note that for now, user and kernel miss |
| 1480 | * exceptions share the same entry point and are handled identically. | 1509 | * exceptions share the same entry point and are handled identically. |
| @@ -1682,6 +1711,7 @@ ENTRY(fast_second_level_miss) | |||
| 1682 | j _kernel_exception | 1711 | j _kernel_exception |
| 1683 | 1: j _user_exception | 1712 | 1: j _user_exception |
| 1684 | 1713 | ||
| 1714 | ENDPROC(fast_second_level_miss) | ||
| 1685 | 1715 | ||
| 1686 | /* | 1716 | /* |
| 1687 | * StoreProhibitedException | 1717 | * StoreProhibitedException |
| @@ -1777,6 +1807,9 @@ ENTRY(fast_store_prohibited) | |||
| 1777 | bbsi.l a2, PS_UM_BIT, 1f | 1807 | bbsi.l a2, PS_UM_BIT, 1f |
| 1778 | j _kernel_exception | 1808 | j _kernel_exception |
| 1779 | 1: j _user_exception | 1809 | 1: j _user_exception |
| 1810 | |||
| 1811 | ENDPROC(fast_store_prohibited) | ||
| 1812 | |||
| 1780 | #endif /* CONFIG_MMU */ | 1813 | #endif /* CONFIG_MMU */ |
| 1781 | 1814 | ||
| 1782 | /* | 1815 | /* |
| @@ -1787,6 +1820,7 @@ ENTRY(fast_store_prohibited) | |||
| 1787 | */ | 1820 | */ |
| 1788 | 1821 | ||
| 1789 | ENTRY(system_call) | 1822 | ENTRY(system_call) |
| 1823 | |||
| 1790 | entry a1, 32 | 1824 | entry a1, 32 |
| 1791 | 1825 | ||
| 1792 | /* regs->syscall = regs->areg[2] */ | 1826 | /* regs->syscall = regs->areg[2] */ |
| @@ -1831,6 +1865,8 @@ ENTRY(system_call) | |||
| 1831 | callx4 a4 | 1865 | callx4 a4 |
| 1832 | retw | 1866 | retw |
| 1833 | 1867 | ||
| 1868 | ENDPROC(system_call) | ||
| 1869 | |||
| 1834 | 1870 | ||
| 1835 | /* | 1871 | /* |
| 1836 | * Task switch. | 1872 | * Task switch. |
| @@ -1899,6 +1935,7 @@ ENTRY(_switch_to) | |||
| 1899 | 1935 | ||
| 1900 | retw | 1936 | retw |
| 1901 | 1937 | ||
| 1938 | ENDPROC(_switch_to) | ||
| 1902 | 1939 | ||
| 1903 | ENTRY(ret_from_fork) | 1940 | ENTRY(ret_from_fork) |
| 1904 | 1941 | ||
| @@ -1914,6 +1951,8 @@ ENTRY(ret_from_fork) | |||
| 1914 | 1951 | ||
| 1915 | j common_exception_return | 1952 | j common_exception_return |
| 1916 | 1953 | ||
| 1954 | ENDPROC(ret_from_fork) | ||
| 1955 | |||
| 1917 | /* | 1956 | /* |
| 1918 | * Kernel thread creation helper | 1957 | * Kernel thread creation helper |
| 1919 | * On entry, set up by copy_thread: a2 = thread_fn, a3 = thread_fn arg | 1958 | * On entry, set up by copy_thread: a2 = thread_fn, a3 = thread_fn arg |
diff --git a/arch/xtensa/kernel/head.S b/arch/xtensa/kernel/head.S index bdc50788f35e..91d9095284de 100644 --- a/arch/xtensa/kernel/head.S +++ b/arch/xtensa/kernel/head.S | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <asm/processor.h> | 18 | #include <asm/processor.h> |
| 19 | #include <asm/page.h> | 19 | #include <asm/page.h> |
| 20 | #include <asm/cacheasm.h> | 20 | #include <asm/cacheasm.h> |
| 21 | #include <asm/initialize_mmu.h> | ||
| 21 | 22 | ||
| 22 | #include <linux/init.h> | 23 | #include <linux/init.h> |
| 23 | #include <linux/linkage.h> | 24 | #include <linux/linkage.h> |
| @@ -47,16 +48,19 @@ | |||
| 47 | */ | 48 | */ |
| 48 | 49 | ||
| 49 | __HEAD | 50 | __HEAD |
| 50 | .globl _start | 51 | ENTRY(_start) |
| 51 | _start: _j 2f | 52 | |
| 53 | _j 2f | ||
| 52 | .align 4 | 54 | .align 4 |
| 53 | 1: .word _startup | 55 | 1: .word _startup |
| 54 | 2: l32r a0, 1b | 56 | 2: l32r a0, 1b |
| 55 | jx a0 | 57 | jx a0 |
| 56 | 58 | ||
| 59 | ENDPROC(_start) | ||
| 60 | |||
| 57 | .section .init.text, "ax" | 61 | .section .init.text, "ax" |
| 58 | .align 4 | 62 | |
| 59 | _startup: | 63 | ENTRY(_startup) |
| 60 | 64 | ||
| 61 | /* Disable interrupts and exceptions. */ | 65 | /* Disable interrupts and exceptions. */ |
| 62 | 66 | ||
| @@ -107,7 +111,7 @@ _startup: | |||
| 107 | /* Disable all timers. */ | 111 | /* Disable all timers. */ |
| 108 | 112 | ||
| 109 | .set _index, 0 | 113 | .set _index, 0 |
| 110 | .rept XCHAL_NUM_TIMERS - 1 | 114 | .rept XCHAL_NUM_TIMERS |
| 111 | wsr a0, SREG_CCOMPARE + _index | 115 | wsr a0, SREG_CCOMPARE + _index |
| 112 | .set _index, _index + 1 | 116 | .set _index, _index + 1 |
| 113 | .endr | 117 | .endr |
| @@ -120,7 +124,7 @@ _startup: | |||
| 120 | 124 | ||
| 121 | /* Disable coprocessors. */ | 125 | /* Disable coprocessors. */ |
| 122 | 126 | ||
| 123 | #if XCHAL_CP_NUM > 0 | 127 | #if XCHAL_HAVE_CP |
| 124 | wsr a0, cpenable | 128 | wsr a0, cpenable |
| 125 | #endif | 129 | #endif |
| 126 | 130 | ||
| @@ -152,6 +156,8 @@ _startup: | |||
| 152 | 156 | ||
| 153 | isync | 157 | isync |
| 154 | 158 | ||
| 159 | initialize_mmu | ||
| 160 | |||
| 155 | /* Unpack data sections | 161 | /* Unpack data sections |
| 156 | * | 162 | * |
| 157 | * The linker script used to build the Linux kernel image | 163 | * The linker script used to build the Linux kernel image |
| @@ -230,6 +236,7 @@ _startup: | |||
| 230 | should_never_return: | 236 | should_never_return: |
| 231 | j should_never_return | 237 | j should_never_return |
| 232 | 238 | ||
| 239 | ENDPROC(_startup) | ||
| 233 | 240 | ||
| 234 | /* | 241 | /* |
| 235 | * BSS section | 242 | * BSS section |
| @@ -239,6 +246,8 @@ __PAGE_ALIGNED_BSS | |||
| 239 | #ifdef CONFIG_MMU | 246 | #ifdef CONFIG_MMU |
| 240 | ENTRY(swapper_pg_dir) | 247 | ENTRY(swapper_pg_dir) |
| 241 | .fill PAGE_SIZE, 1, 0 | 248 | .fill PAGE_SIZE, 1, 0 |
| 249 | END(swapper_pg_dir) | ||
| 242 | #endif | 250 | #endif |
| 243 | ENTRY(empty_zero_page) | 251 | ENTRY(empty_zero_page) |
| 244 | .fill PAGE_SIZE, 1, 0 | 252 | .fill PAGE_SIZE, 1, 0 |
| 253 | END(empty_zero_page) | ||
diff --git a/arch/xtensa/kernel/irq.c b/arch/xtensa/kernel/irq.c index a6ce3e563739..6f4f9749cff7 100644 --- a/arch/xtensa/kernel/irq.c +++ b/arch/xtensa/kernel/irq.c | |||
| @@ -18,6 +18,8 @@ | |||
| 18 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
| 19 | #include <linux/irq.h> | 19 | #include <linux/irq.h> |
| 20 | #include <linux/kernel_stat.h> | 20 | #include <linux/kernel_stat.h> |
| 21 | #include <linux/irqdomain.h> | ||
| 22 | #include <linux/of.h> | ||
| 21 | 23 | ||
| 22 | #include <asm/uaccess.h> | 24 | #include <asm/uaccess.h> |
| 23 | #include <asm/platform.h> | 25 | #include <asm/platform.h> |
| @@ -26,19 +28,22 @@ static unsigned int cached_irq_mask; | |||
| 26 | 28 | ||
| 27 | atomic_t irq_err_count; | 29 | atomic_t irq_err_count; |
| 28 | 30 | ||
| 31 | static struct irq_domain *root_domain; | ||
| 32 | |||
| 29 | /* | 33 | /* |
| 30 | * do_IRQ handles all normal device IRQ's (the special | 34 | * do_IRQ handles all normal device IRQ's (the special |
| 31 | * SMP cross-CPU interrupts have their own specific | 35 | * SMP cross-CPU interrupts have their own specific |
| 32 | * handlers). | 36 | * handlers). |
| 33 | */ | 37 | */ |
| 34 | 38 | ||
| 35 | asmlinkage void do_IRQ(int irq, struct pt_regs *regs) | 39 | asmlinkage void do_IRQ(int hwirq, struct pt_regs *regs) |
| 36 | { | 40 | { |
| 37 | struct pt_regs *old_regs = set_irq_regs(regs); | 41 | struct pt_regs *old_regs = set_irq_regs(regs); |
| 42 | int irq = irq_find_mapping(root_domain, hwirq); | ||
| 38 | 43 | ||
| 39 | if (irq >= NR_IRQS) { | 44 | if (hwirq >= NR_IRQS) { |
| 40 | printk(KERN_EMERG "%s: cannot handle IRQ %d\n", | 45 | printk(KERN_EMERG "%s: cannot handle IRQ %d\n", |
| 41 | __func__, irq); | 46 | __func__, hwirq); |
| 42 | } | 47 | } |
| 43 | 48 | ||
| 44 | irq_enter(); | 49 | irq_enter(); |
| @@ -71,40 +76,39 @@ int arch_show_interrupts(struct seq_file *p, int prec) | |||
| 71 | 76 | ||
| 72 | static void xtensa_irq_mask(struct irq_data *d) | 77 | static void xtensa_irq_mask(struct irq_data *d) |
| 73 | { | 78 | { |
| 74 | cached_irq_mask &= ~(1 << d->irq); | 79 | cached_irq_mask &= ~(1 << d->hwirq); |
| 75 | set_sr (cached_irq_mask, intenable); | 80 | set_sr (cached_irq_mask, intenable); |
| 76 | } | 81 | } |
| 77 | 82 | ||
| 78 | static void xtensa_irq_unmask(struct irq_data *d) | 83 | static void xtensa_irq_unmask(struct irq_data *d) |
| 79 | { | 84 | { |
| 80 | cached_irq_mask |= 1 << d->irq; | 85 | cached_irq_mask |= 1 << d->hwirq; |
| 81 | set_sr (cached_irq_mask, intenable); | 86 | set_sr (cached_irq_mask, intenable); |
| 82 | } | 87 | } |
| 83 | 88 | ||
| 84 | static void xtensa_irq_enable(struct irq_data *d) | 89 | static void xtensa_irq_enable(struct irq_data *d) |
| 85 | { | 90 | { |
| 86 | variant_irq_enable(d->irq); | 91 | variant_irq_enable(d->hwirq); |
| 87 | xtensa_irq_unmask(d); | 92 | xtensa_irq_unmask(d); |
| 88 | } | 93 | } |
| 89 | 94 | ||
| 90 | static void xtensa_irq_disable(struct irq_data *d) | 95 | static void xtensa_irq_disable(struct irq_data *d) |
| 91 | { | 96 | { |
| 92 | xtensa_irq_mask(d); | 97 | xtensa_irq_mask(d); |
| 93 | variant_irq_disable(d->irq); | 98 | variant_irq_disable(d->hwirq); |
| 94 | } | 99 | } |
| 95 | 100 | ||
| 96 | static void xtensa_irq_ack(struct irq_data *d) | 101 | static void xtensa_irq_ack(struct irq_data *d) |
| 97 | { | 102 | { |
| 98 | set_sr(1 << d->irq, intclear); | 103 | set_sr(1 << d->hwirq, intclear); |
| 99 | } | 104 | } |
| 100 | 105 | ||
| 101 | static int xtensa_irq_retrigger(struct irq_data *d) | 106 | static int xtensa_irq_retrigger(struct irq_data *d) |
| 102 | { | 107 | { |
| 103 | set_sr (1 << d->irq, INTSET); | 108 | set_sr(1 << d->hwirq, intset); |
| 104 | return 1; | 109 | return 1; |
| 105 | } | 110 | } |
| 106 | 111 | ||
| 107 | |||
| 108 | static struct irq_chip xtensa_irq_chip = { | 112 | static struct irq_chip xtensa_irq_chip = { |
| 109 | .name = "xtensa", | 113 | .name = "xtensa", |
| 110 | .irq_enable = xtensa_irq_enable, | 114 | .irq_enable = xtensa_irq_enable, |
| @@ -115,37 +119,99 @@ static struct irq_chip xtensa_irq_chip = { | |||
| 115 | .irq_retrigger = xtensa_irq_retrigger, | 119 | .irq_retrigger = xtensa_irq_retrigger, |
| 116 | }; | 120 | }; |
| 117 | 121 | ||
| 118 | void __init init_IRQ(void) | 122 | static int xtensa_irq_map(struct irq_domain *d, unsigned int irq, |
| 123 | irq_hw_number_t hw) | ||
| 119 | { | 124 | { |
| 120 | int index; | 125 | u32 mask = 1 << hw; |
| 121 | 126 | ||
| 122 | for (index = 0; index < XTENSA_NR_IRQS; index++) { | 127 | if (mask & XCHAL_INTTYPE_MASK_SOFTWARE) { |
| 123 | int mask = 1 << index; | 128 | irq_set_chip_and_handler_name(irq, &xtensa_irq_chip, |
| 124 | 129 | handle_simple_irq, "level"); | |
| 125 | if (mask & XCHAL_INTTYPE_MASK_SOFTWARE) | 130 | irq_set_status_flags(irq, IRQ_LEVEL); |
| 126 | irq_set_chip_and_handler(index, &xtensa_irq_chip, | 131 | } else if (mask & XCHAL_INTTYPE_MASK_EXTERN_EDGE) { |
| 127 | handle_simple_irq); | 132 | irq_set_chip_and_handler_name(irq, &xtensa_irq_chip, |
| 133 | handle_edge_irq, "edge"); | ||
| 134 | irq_clear_status_flags(irq, IRQ_LEVEL); | ||
| 135 | } else if (mask & XCHAL_INTTYPE_MASK_EXTERN_LEVEL) { | ||
| 136 | irq_set_chip_and_handler_name(irq, &xtensa_irq_chip, | ||
| 137 | handle_level_irq, "level"); | ||
| 138 | irq_set_status_flags(irq, IRQ_LEVEL); | ||
| 139 | } else if (mask & XCHAL_INTTYPE_MASK_TIMER) { | ||
| 140 | irq_set_chip_and_handler_name(irq, &xtensa_irq_chip, | ||
| 141 | handle_edge_irq, "edge"); | ||
| 142 | irq_clear_status_flags(irq, IRQ_LEVEL); | ||
| 143 | } else {/* XCHAL_INTTYPE_MASK_WRITE_ERROR */ | ||
| 144 | /* XCHAL_INTTYPE_MASK_NMI */ | ||
| 145 | |||
| 146 | irq_set_chip_and_handler_name(irq, &xtensa_irq_chip, | ||
| 147 | handle_level_irq, "level"); | ||
| 148 | irq_set_status_flags(irq, IRQ_LEVEL); | ||
| 149 | } | ||
| 150 | return 0; | ||
| 151 | } | ||
| 128 | 152 | ||
| 129 | else if (mask & XCHAL_INTTYPE_MASK_EXTERN_EDGE) | 153 | static unsigned map_ext_irq(unsigned ext_irq) |
| 130 | irq_set_chip_and_handler(index, &xtensa_irq_chip, | 154 | { |
| 131 | handle_edge_irq); | 155 | unsigned mask = XCHAL_INTTYPE_MASK_EXTERN_EDGE | |
| 156 | XCHAL_INTTYPE_MASK_EXTERN_LEVEL; | ||
| 157 | unsigned i; | ||
| 132 | 158 | ||
| 133 | else if (mask & XCHAL_INTTYPE_MASK_EXTERN_LEVEL) | 159 | for (i = 0; mask; ++i, mask >>= 1) { |
| 134 | irq_set_chip_and_handler(index, &xtensa_irq_chip, | 160 | if ((mask & 1) && ext_irq-- == 0) |
| 135 | handle_level_irq); | 161 | return i; |
| 162 | } | ||
| 163 | return XCHAL_NUM_INTERRUPTS; | ||
| 164 | } | ||
| 136 | 165 | ||
| 137 | else if (mask & XCHAL_INTTYPE_MASK_TIMER) | 166 | /* |
| 138 | irq_set_chip_and_handler(index, &xtensa_irq_chip, | 167 | * Device Tree IRQ specifier translation function which works with one or |
| 139 | handle_edge_irq); | 168 | * two cell bindings. First cell value maps directly to the hwirq number. |
| 169 | * Second cell if present specifies whether hwirq number is external (1) or | ||
| 170 | * internal (0). | ||
| 171 | */ | ||
| 172 | int xtensa_irq_domain_xlate(struct irq_domain *d, struct device_node *ctrlr, | ||
| 173 | const u32 *intspec, unsigned int intsize, | ||
| 174 | unsigned long *out_hwirq, unsigned int *out_type) | ||
| 175 | { | ||
| 176 | if (WARN_ON(intsize < 1 || intsize > 2)) | ||
| 177 | return -EINVAL; | ||
| 178 | if (intsize == 2 && intspec[1] == 1) { | ||
| 179 | unsigned int_irq = map_ext_irq(intspec[0]); | ||
| 180 | if (int_irq < XCHAL_NUM_INTERRUPTS) | ||
| 181 | *out_hwirq = int_irq; | ||
| 182 | else | ||
| 183 | return -EINVAL; | ||
| 184 | } else { | ||
| 185 | *out_hwirq = intspec[0]; | ||
| 186 | } | ||
| 187 | *out_type = IRQ_TYPE_NONE; | ||
| 188 | return 0; | ||
| 189 | } | ||
| 140 | 190 | ||
| 141 | else /* XCHAL_INTTYPE_MASK_WRITE_ERROR */ | 191 | static const struct irq_domain_ops xtensa_irq_domain_ops = { |
| 142 | /* XCHAL_INTTYPE_MASK_NMI */ | 192 | .xlate = xtensa_irq_domain_xlate, |
| 193 | .map = xtensa_irq_map, | ||
| 194 | }; | ||
| 143 | 195 | ||
| 144 | irq_set_chip_and_handler(index, &xtensa_irq_chip, | 196 | void __init init_IRQ(void) |
| 145 | handle_level_irq); | 197 | { |
| 146 | } | 198 | struct device_node *intc = NULL; |
| 147 | 199 | ||
| 148 | cached_irq_mask = 0; | 200 | cached_irq_mask = 0; |
| 201 | set_sr(~0, intclear); | ||
| 202 | |||
| 203 | #ifdef CONFIG_OF | ||
| 204 | /* The interrupt controller device node is mandatory */ | ||
| 205 | intc = of_find_compatible_node(NULL, NULL, "xtensa,pic"); | ||
| 206 | BUG_ON(!intc); | ||
| 207 | |||
| 208 | root_domain = irq_domain_add_linear(intc, NR_IRQS, | ||
| 209 | &xtensa_irq_domain_ops, NULL); | ||
| 210 | #else | ||
| 211 | root_domain = irq_domain_add_legacy(intc, NR_IRQS, 0, 0, | ||
| 212 | &xtensa_irq_domain_ops, NULL); | ||
| 213 | #endif | ||
| 214 | irq_set_default_host(root_domain); | ||
| 149 | 215 | ||
| 150 | variant_init_irq(); | 216 | variant_init_irq(); |
| 151 | } | 217 | } |
diff --git a/arch/xtensa/kernel/module.c b/arch/xtensa/kernel/module.c index 451dda928c93..b715237bae61 100644 --- a/arch/xtensa/kernel/module.c +++ b/arch/xtensa/kernel/module.c | |||
| @@ -53,7 +53,7 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, | |||
| 53 | struct module *mod) | 53 | struct module *mod) |
| 54 | { | 54 | { |
| 55 | unsigned int i; | 55 | unsigned int i; |
| 56 | Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr; | 56 | Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr; |
| 57 | Elf32_Sym *sym; | 57 | Elf32_Sym *sym; |
| 58 | unsigned char *location; | 58 | unsigned char *location; |
| 59 | uint32_t value; | 59 | uint32_t value; |
diff --git a/arch/xtensa/kernel/platform.c b/arch/xtensa/kernel/platform.c index 97230e46cbe7..44bf21c3769a 100644 --- a/arch/xtensa/kernel/platform.c +++ b/arch/xtensa/kernel/platform.c | |||
| @@ -44,4 +44,3 @@ _F(void, calibrate_ccount, (void), | |||
| 44 | ccount_per_jiffy = 10 * (1000000UL/HZ); | 44 | ccount_per_jiffy = 10 * (1000000UL/HZ); |
| 45 | }); | 45 | }); |
| 46 | #endif | 46 | #endif |
| 47 | |||
diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c index 1accf28da5f5..0dd5784416d3 100644 --- a/arch/xtensa/kernel/process.c +++ b/arch/xtensa/kernel/process.c | |||
| @@ -108,7 +108,7 @@ void coprocessor_flush_all(struct thread_info *ti) | |||
| 108 | 108 | ||
| 109 | void cpu_idle(void) | 109 | void cpu_idle(void) |
| 110 | { | 110 | { |
| 111 | local_irq_enable(); | 111 | local_irq_enable(); |
| 112 | 112 | ||
| 113 | /* endless idle loop with no priority at all */ | 113 | /* endless idle loop with no priority at all */ |
| 114 | while (1) { | 114 | while (1) { |
diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c index 33eea4c16f12..61fb2e9e9035 100644 --- a/arch/xtensa/kernel/ptrace.c +++ b/arch/xtensa/kernel/ptrace.c | |||
| @@ -154,7 +154,7 @@ int ptrace_setxregs(struct task_struct *child, void __user *uregs) | |||
| 154 | coprocessor_flush_all(ti); | 154 | coprocessor_flush_all(ti); |
| 155 | coprocessor_release_all(ti); | 155 | coprocessor_release_all(ti); |
| 156 | 156 | ||
| 157 | ret |= __copy_from_user(&ti->xtregs_cp, &xtregs->cp0, | 157 | ret |= __copy_from_user(&ti->xtregs_cp, &xtregs->cp0, |
| 158 | sizeof(xtregs_coprocessor_t)); | 158 | sizeof(xtregs_coprocessor_t)); |
| 159 | #endif | 159 | #endif |
| 160 | ret |= __copy_from_user(®s->xtregs_opt, &xtregs->opt, | 160 | ret |= __copy_from_user(®s->xtregs_opt, &xtregs->opt, |
| @@ -343,4 +343,3 @@ void do_syscall_trace_leave(struct pt_regs *regs) | |||
| 343 | && (current->ptrace & PT_PTRACED)) | 343 | && (current->ptrace & PT_PTRACED)) |
| 344 | do_syscall_trace(); | 344 | do_syscall_trace(); |
| 345 | } | 345 | } |
| 346 | |||
diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c index b237988ba6d7..24c1a57abb40 100644 --- a/arch/xtensa/kernel/setup.c +++ b/arch/xtensa/kernel/setup.c | |||
| @@ -22,6 +22,11 @@ | |||
| 22 | #include <linux/bootmem.h> | 22 | #include <linux/bootmem.h> |
| 23 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
| 24 | 24 | ||
| 25 | #ifdef CONFIG_OF | ||
| 26 | #include <linux/of_fdt.h> | ||
| 27 | #include <linux/of_platform.h> | ||
| 28 | #endif | ||
| 29 | |||
| 25 | #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE) | 30 | #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE) |
| 26 | # include <linux/console.h> | 31 | # include <linux/console.h> |
| 27 | #endif | 32 | #endif |
| @@ -42,6 +47,7 @@ | |||
| 42 | #include <asm/page.h> | 47 | #include <asm/page.h> |
| 43 | #include <asm/setup.h> | 48 | #include <asm/setup.h> |
| 44 | #include <asm/param.h> | 49 | #include <asm/param.h> |
| 50 | #include <asm/traps.h> | ||
| 45 | 51 | ||
| 46 | #include <platform/hardware.h> | 52 | #include <platform/hardware.h> |
| 47 | 53 | ||
| @@ -64,6 +70,11 @@ int initrd_is_mapped = 0; | |||
| 64 | extern int initrd_below_start_ok; | 70 | extern int initrd_below_start_ok; |
| 65 | #endif | 71 | #endif |
| 66 | 72 | ||
| 73 | #ifdef CONFIG_OF | ||
| 74 | extern u32 __dtb_start[]; | ||
| 75 | void *dtb_start = __dtb_start; | ||
| 76 | #endif | ||
| 77 | |||
| 67 | unsigned char aux_device_present; | 78 | unsigned char aux_device_present; |
| 68 | extern unsigned long loops_per_jiffy; | 79 | extern unsigned long loops_per_jiffy; |
| 69 | 80 | ||
| @@ -83,6 +94,8 @@ extern void init_mmu(void); | |||
| 83 | static inline void init_mmu(void) { } | 94 | static inline void init_mmu(void) { } |
| 84 | #endif | 95 | #endif |
| 85 | 96 | ||
| 97 | extern int mem_reserve(unsigned long, unsigned long, int); | ||
| 98 | extern void bootmem_init(void); | ||
| 86 | extern void zones_init(void); | 99 | extern void zones_init(void); |
| 87 | 100 | ||
| 88 | /* | 101 | /* |
| @@ -104,28 +117,33 @@ typedef struct tagtable { | |||
| 104 | 117 | ||
| 105 | /* parse current tag */ | 118 | /* parse current tag */ |
| 106 | 119 | ||
| 107 | static int __init parse_tag_mem(const bp_tag_t *tag) | 120 | static int __init add_sysmem_bank(unsigned long type, unsigned long start, |
| 121 | unsigned long end) | ||
| 108 | { | 122 | { |
| 109 | meminfo_t *mi = (meminfo_t*)(tag->data); | ||
| 110 | |||
| 111 | if (mi->type != MEMORY_TYPE_CONVENTIONAL) | ||
| 112 | return -1; | ||
| 113 | |||
| 114 | if (sysmem.nr_banks >= SYSMEM_BANKS_MAX) { | 123 | if (sysmem.nr_banks >= SYSMEM_BANKS_MAX) { |
| 115 | printk(KERN_WARNING | 124 | printk(KERN_WARNING |
| 116 | "Ignoring memory bank 0x%08lx size %ldKB\n", | 125 | "Ignoring memory bank 0x%08lx size %ldKB\n", |
| 117 | (unsigned long)mi->start, | 126 | start, end - start); |
| 118 | (unsigned long)mi->end - (unsigned long)mi->start); | ||
| 119 | return -EINVAL; | 127 | return -EINVAL; |
| 120 | } | 128 | } |
| 121 | sysmem.bank[sysmem.nr_banks].type = mi->type; | 129 | sysmem.bank[sysmem.nr_banks].type = type; |
| 122 | sysmem.bank[sysmem.nr_banks].start = PAGE_ALIGN(mi->start); | 130 | sysmem.bank[sysmem.nr_banks].start = PAGE_ALIGN(start); |
| 123 | sysmem.bank[sysmem.nr_banks].end = mi->end & PAGE_MASK; | 131 | sysmem.bank[sysmem.nr_banks].end = end & PAGE_MASK; |
| 124 | sysmem.nr_banks++; | 132 | sysmem.nr_banks++; |
| 125 | 133 | ||
| 126 | return 0; | 134 | return 0; |
| 127 | } | 135 | } |
| 128 | 136 | ||
| 137 | static int __init parse_tag_mem(const bp_tag_t *tag) | ||
| 138 | { | ||
| 139 | meminfo_t *mi = (meminfo_t *)(tag->data); | ||
| 140 | |||
| 141 | if (mi->type != MEMORY_TYPE_CONVENTIONAL) | ||
| 142 | return -1; | ||
| 143 | |||
| 144 | return add_sysmem_bank(mi->type, mi->start, mi->end); | ||
| 145 | } | ||
| 146 | |||
| 129 | __tagtable(BP_TAG_MEMORY, parse_tag_mem); | 147 | __tagtable(BP_TAG_MEMORY, parse_tag_mem); |
| 130 | 148 | ||
| 131 | #ifdef CONFIG_BLK_DEV_INITRD | 149 | #ifdef CONFIG_BLK_DEV_INITRD |
| @@ -142,12 +160,31 @@ static int __init parse_tag_initrd(const bp_tag_t* tag) | |||
| 142 | 160 | ||
| 143 | __tagtable(BP_TAG_INITRD, parse_tag_initrd); | 161 | __tagtable(BP_TAG_INITRD, parse_tag_initrd); |
| 144 | 162 | ||
| 163 | #ifdef CONFIG_OF | ||
| 164 | |||
| 165 | static int __init parse_tag_fdt(const bp_tag_t *tag) | ||
| 166 | { | ||
| 167 | dtb_start = (void *)(tag->data[0]); | ||
| 168 | return 0; | ||
| 169 | } | ||
| 170 | |||
| 171 | __tagtable(BP_TAG_FDT, parse_tag_fdt); | ||
| 172 | |||
| 173 | void __init early_init_dt_setup_initrd_arch(unsigned long start, | ||
| 174 | unsigned long end) | ||
| 175 | { | ||
| 176 | initrd_start = (void *)__va(start); | ||
| 177 | initrd_end = (void *)__va(end); | ||
| 178 | initrd_below_start_ok = 1; | ||
| 179 | } | ||
| 180 | |||
| 181 | #endif /* CONFIG_OF */ | ||
| 182 | |||
| 145 | #endif /* CONFIG_BLK_DEV_INITRD */ | 183 | #endif /* CONFIG_BLK_DEV_INITRD */ |
| 146 | 184 | ||
| 147 | static int __init parse_tag_cmdline(const bp_tag_t* tag) | 185 | static int __init parse_tag_cmdline(const bp_tag_t* tag) |
| 148 | { | 186 | { |
| 149 | strncpy(command_line, (char*)(tag->data), COMMAND_LINE_SIZE); | 187 | strlcpy(command_line, (char *)(tag->data), COMMAND_LINE_SIZE); |
| 150 | command_line[COMMAND_LINE_SIZE - 1] = '\0'; | ||
| 151 | return 0; | 188 | return 0; |
| 152 | } | 189 | } |
| 153 | 190 | ||
| @@ -185,6 +222,58 @@ static int __init parse_bootparam(const bp_tag_t* tag) | |||
| 185 | return 0; | 222 | return 0; |
| 186 | } | 223 | } |
| 187 | 224 | ||
| 225 | #ifdef CONFIG_OF | ||
| 226 | |||
| 227 | void __init early_init_dt_add_memory_arch(u64 base, u64 size) | ||
| 228 | { | ||
| 229 | size &= PAGE_MASK; | ||
| 230 | add_sysmem_bank(MEMORY_TYPE_CONVENTIONAL, base, base + size); | ||
| 231 | } | ||
| 232 | |||
| 233 | void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) | ||
| 234 | { | ||
| 235 | return __alloc_bootmem(size, align, 0); | ||
| 236 | } | ||
| 237 | |||
| 238 | void __init early_init_devtree(void *params) | ||
| 239 | { | ||
| 240 | /* Setup flat device-tree pointer */ | ||
| 241 | initial_boot_params = params; | ||
| 242 | |||
| 243 | /* Retrieve various informations from the /chosen node of the | ||
| 244 | * device-tree, including the platform type, initrd location and | ||
| 245 | * size, TCE reserve, and more ... | ||
| 246 | */ | ||
| 247 | if (!command_line[0]) | ||
| 248 | of_scan_flat_dt(early_init_dt_scan_chosen, command_line); | ||
| 249 | |||
| 250 | /* Scan memory nodes and rebuild MEMBLOCKs */ | ||
| 251 | of_scan_flat_dt(early_init_dt_scan_root, NULL); | ||
| 252 | if (sysmem.nr_banks == 0) | ||
| 253 | of_scan_flat_dt(early_init_dt_scan_memory, NULL); | ||
| 254 | } | ||
| 255 | |||
| 256 | static void __init copy_devtree(void) | ||
| 257 | { | ||
| 258 | void *alloc = early_init_dt_alloc_memory_arch( | ||
| 259 | be32_to_cpu(initial_boot_params->totalsize), 0); | ||
| 260 | if (alloc) { | ||
| 261 | memcpy(alloc, initial_boot_params, | ||
| 262 | be32_to_cpu(initial_boot_params->totalsize)); | ||
| 263 | initial_boot_params = alloc; | ||
| 264 | } | ||
| 265 | } | ||
| 266 | |||
| 267 | static int __init xtensa_device_probe(void) | ||
| 268 | { | ||
| 269 | of_platform_populate(NULL, NULL, NULL, NULL); | ||
| 270 | return 0; | ||
| 271 | } | ||
| 272 | |||
| 273 | device_initcall(xtensa_device_probe); | ||
| 274 | |||
| 275 | #endif /* CONFIG_OF */ | ||
| 276 | |||
| 188 | /* | 277 | /* |
| 189 | * Initialize architecture. (Early stage) | 278 | * Initialize architecture. (Early stage) |
| 190 | */ | 279 | */ |
| @@ -193,14 +282,14 @@ void __init init_arch(bp_tag_t *bp_start) | |||
| 193 | { | 282 | { |
| 194 | sysmem.nr_banks = 0; | 283 | sysmem.nr_banks = 0; |
| 195 | 284 | ||
| 196 | #ifdef CONFIG_CMDLINE_BOOL | ||
| 197 | strcpy(command_line, default_command_line); | ||
| 198 | #endif | ||
| 199 | |||
| 200 | /* Parse boot parameters */ | 285 | /* Parse boot parameters */ |
| 201 | 286 | ||
| 202 | if (bp_start) | 287 | if (bp_start) |
| 203 | parse_bootparam(bp_start); | 288 | parse_bootparam(bp_start); |
| 289 | |||
| 290 | #ifdef CONFIG_OF | ||
| 291 | early_init_devtree(dtb_start); | ||
| 292 | #endif | ||
| 204 | 293 | ||
| 205 | if (sysmem.nr_banks == 0) { | 294 | if (sysmem.nr_banks == 0) { |
| 206 | sysmem.nr_banks = 1; | 295 | sysmem.nr_banks = 1; |
| @@ -209,6 +298,11 @@ void __init init_arch(bp_tag_t *bp_start) | |||
| 209 | + PLATFORM_DEFAULT_MEM_SIZE; | 298 | + PLATFORM_DEFAULT_MEM_SIZE; |
| 210 | } | 299 | } |
| 211 | 300 | ||
| 301 | #ifdef CONFIG_CMDLINE_BOOL | ||
| 302 | if (!command_line[0]) | ||
| 303 | strlcpy(command_line, default_command_line, COMMAND_LINE_SIZE); | ||
| 304 | #endif | ||
| 305 | |||
| 212 | /* Early hook for platforms */ | 306 | /* Early hook for platforms */ |
| 213 | 307 | ||
| 214 | platform_init(bp_start); | 308 | platform_init(bp_start); |
| @@ -235,15 +329,130 @@ extern char _UserExceptionVector_text_end; | |||
| 235 | extern char _DoubleExceptionVector_literal_start; | 329 | extern char _DoubleExceptionVector_literal_start; |
| 236 | extern char _DoubleExceptionVector_text_end; | 330 | extern char _DoubleExceptionVector_text_end; |
| 237 | 331 | ||
| 238 | void __init setup_arch(char **cmdline_p) | 332 | |
| 333 | #ifdef CONFIG_S32C1I_SELFTEST | ||
| 334 | #if XCHAL_HAVE_S32C1I | ||
| 335 | |||
| 336 | static int __initdata rcw_word, rcw_probe_pc, rcw_exc; | ||
| 337 | |||
| 338 | /* | ||
| 339 | * Basic atomic compare-and-swap, that records PC of S32C1I for probing. | ||
| 340 | * | ||
| 341 | * If *v == cmp, set *v = set. Return previous *v. | ||
| 342 | */ | ||
| 343 | static inline int probed_compare_swap(int *v, int cmp, int set) | ||
| 344 | { | ||
| 345 | int tmp; | ||
| 346 | |||
| 347 | __asm__ __volatile__( | ||
| 348 | " movi %1, 1f\n" | ||
| 349 | " s32i %1, %4, 0\n" | ||
| 350 | " wsr %2, scompare1\n" | ||
| 351 | "1: s32c1i %0, %3, 0\n" | ||
| 352 | : "=a" (set), "=&a" (tmp) | ||
| 353 | : "a" (cmp), "a" (v), "a" (&rcw_probe_pc), "0" (set) | ||
| 354 | : "memory" | ||
| 355 | ); | ||
| 356 | return set; | ||
| 357 | } | ||
| 358 | |||
| 359 | /* Handle probed exception */ | ||
| 360 | |||
| 361 | void __init do_probed_exception(struct pt_regs *regs, unsigned long exccause) | ||
| 362 | { | ||
| 363 | if (regs->pc == rcw_probe_pc) { /* exception on s32c1i ? */ | ||
| 364 | regs->pc += 3; /* skip the s32c1i instruction */ | ||
| 365 | rcw_exc = exccause; | ||
| 366 | } else { | ||
| 367 | do_unhandled(regs, exccause); | ||
| 368 | } | ||
| 369 | } | ||
| 370 | |||
| 371 | /* Simple test of S32C1I (soc bringup assist) */ | ||
| 372 | |||
| 373 | void __init check_s32c1i(void) | ||
| 374 | { | ||
| 375 | int n, cause1, cause2; | ||
| 376 | void *handbus, *handdata, *handaddr; /* temporarily saved handlers */ | ||
| 377 | |||
| 378 | rcw_probe_pc = 0; | ||
| 379 | handbus = trap_set_handler(EXCCAUSE_LOAD_STORE_ERROR, | ||
| 380 | do_probed_exception); | ||
| 381 | handdata = trap_set_handler(EXCCAUSE_LOAD_STORE_DATA_ERROR, | ||
| 382 | do_probed_exception); | ||
| 383 | handaddr = trap_set_handler(EXCCAUSE_LOAD_STORE_ADDR_ERROR, | ||
| 384 | do_probed_exception); | ||
| 385 | |||
| 386 | /* First try an S32C1I that does not store: */ | ||
| 387 | rcw_exc = 0; | ||
| 388 | rcw_word = 1; | ||
| 389 | n = probed_compare_swap(&rcw_word, 0, 2); | ||
| 390 | cause1 = rcw_exc; | ||
| 391 | |||
| 392 | /* took exception? */ | ||
| 393 | if (cause1 != 0) { | ||
| 394 | /* unclean exception? */ | ||
| 395 | if (n != 2 || rcw_word != 1) | ||
| 396 | panic("S32C1I exception error"); | ||
| 397 | } else if (rcw_word != 1 || n != 1) { | ||
| 398 | panic("S32C1I compare error"); | ||
| 399 | } | ||
| 400 | |||
| 401 | /* Then an S32C1I that stores: */ | ||
| 402 | rcw_exc = 0; | ||
| 403 | rcw_word = 0x1234567; | ||
| 404 | n = probed_compare_swap(&rcw_word, 0x1234567, 0xabcde); | ||
| 405 | cause2 = rcw_exc; | ||
| 406 | |||
| 407 | if (cause2 != 0) { | ||
| 408 | /* unclean exception? */ | ||
| 409 | if (n != 0xabcde || rcw_word != 0x1234567) | ||
| 410 | panic("S32C1I exception error (b)"); | ||
| 411 | } else if (rcw_word != 0xabcde || n != 0x1234567) { | ||
| 412 | panic("S32C1I store error"); | ||
| 413 | } | ||
| 414 | |||
| 415 | /* Verify consistency of exceptions: */ | ||
| 416 | if (cause1 || cause2) { | ||
| 417 | pr_warn("S32C1I took exception %d, %d\n", cause1, cause2); | ||
| 418 | /* If emulation of S32C1I upon bus error gets implemented, | ||
| 419 | we can get rid of this panic for single core (not SMP) */ | ||
| 420 | panic("S32C1I exceptions not currently supported"); | ||
| 421 | } | ||
| 422 | if (cause1 != cause2) | ||
| 423 | panic("inconsistent S32C1I exceptions"); | ||
| 424 | |||
| 425 | trap_set_handler(EXCCAUSE_LOAD_STORE_ERROR, handbus); | ||
| 426 | trap_set_handler(EXCCAUSE_LOAD_STORE_DATA_ERROR, handdata); | ||
| 427 | trap_set_handler(EXCCAUSE_LOAD_STORE_ADDR_ERROR, handaddr); | ||
| 428 | } | ||
| 429 | |||
| 430 | #else /* XCHAL_HAVE_S32C1I */ | ||
| 431 | |||
| 432 | /* This condition should not occur with a commercially deployed processor. | ||
| 433 | Display reminder for early engr test or demo chips / FPGA bitstreams */ | ||
| 434 | void __init check_s32c1i(void) | ||
| 435 | { | ||
| 436 | pr_warn("Processor configuration lacks atomic compare-and-swap support!\n"); | ||
| 437 | } | ||
| 438 | |||
| 439 | #endif /* XCHAL_HAVE_S32C1I */ | ||
| 440 | #else /* CONFIG_S32C1I_SELFTEST */ | ||
| 441 | |||
| 442 | void __init check_s32c1i(void) | ||
| 239 | { | 443 | { |
| 240 | extern int mem_reserve(unsigned long, unsigned long, int); | 444 | } |
| 241 | extern void bootmem_init(void); | 445 | |
| 446 | #endif /* CONFIG_S32C1I_SELFTEST */ | ||
| 242 | 447 | ||
| 243 | memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); | 448 | |
| 244 | boot_command_line[COMMAND_LINE_SIZE-1] = '\0'; | 449 | void __init setup_arch(char **cmdline_p) |
| 450 | { | ||
| 451 | strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); | ||
| 245 | *cmdline_p = command_line; | 452 | *cmdline_p = command_line; |
| 246 | 453 | ||
| 454 | check_s32c1i(); | ||
| 455 | |||
| 247 | /* Reserve some memory regions */ | 456 | /* Reserve some memory regions */ |
| 248 | 457 | ||
| 249 | #ifdef CONFIG_BLK_DEV_INITRD | 458 | #ifdef CONFIG_BLK_DEV_INITRD |
| @@ -251,7 +460,7 @@ void __init setup_arch(char **cmdline_p) | |||
| 251 | initrd_is_mapped = mem_reserve(__pa(initrd_start), | 460 | initrd_is_mapped = mem_reserve(__pa(initrd_start), |
| 252 | __pa(initrd_end), 0); | 461 | __pa(initrd_end), 0); |
| 253 | initrd_below_start_ok = 1; | 462 | initrd_below_start_ok = 1; |
| 254 | } else { | 463 | } else { |
| 255 | initrd_start = 0; | 464 | initrd_start = 0; |
| 256 | } | 465 | } |
| 257 | #endif | 466 | #endif |
| @@ -275,8 +484,12 @@ void __init setup_arch(char **cmdline_p) | |||
| 275 | 484 | ||
| 276 | bootmem_init(); | 485 | bootmem_init(); |
| 277 | 486 | ||
| 278 | platform_setup(cmdline_p); | 487 | #ifdef CONFIG_OF |
| 488 | copy_devtree(); | ||
| 489 | unflatten_device_tree(); | ||
| 490 | #endif | ||
| 279 | 491 | ||
| 492 | platform_setup(cmdline_p); | ||
| 280 | 493 | ||
| 281 | paging_init(); | 494 | paging_init(); |
| 282 | zones_init(); | 495 | zones_init(); |
| @@ -326,7 +539,7 @@ c_show(struct seq_file *f, void *slot) | |||
| 326 | "core ID\t\t: " XCHAL_CORE_ID "\n" | 539 | "core ID\t\t: " XCHAL_CORE_ID "\n" |
| 327 | "build ID\t: 0x%x\n" | 540 | "build ID\t: 0x%x\n" |
| 328 | "byte order\t: %s\n" | 541 | "byte order\t: %s\n" |
| 329 | "cpu MHz\t\t: %lu.%02lu\n" | 542 | "cpu MHz\t\t: %lu.%02lu\n" |
| 330 | "bogomips\t: %lu.%02lu\n", | 543 | "bogomips\t: %lu.%02lu\n", |
| 331 | XCHAL_BUILD_UNIQUE_ID, | 544 | XCHAL_BUILD_UNIQUE_ID, |
| 332 | XCHAL_HAVE_BE ? "big" : "little", | 545 | XCHAL_HAVE_BE ? "big" : "little", |
| @@ -381,6 +594,9 @@ c_show(struct seq_file *f, void *slot) | |||
| 381 | #if XCHAL_HAVE_FP | 594 | #if XCHAL_HAVE_FP |
| 382 | "fpu " | 595 | "fpu " |
| 383 | #endif | 596 | #endif |
| 597 | #if XCHAL_HAVE_S32C1I | ||
| 598 | "s32c1i " | ||
| 599 | #endif | ||
| 384 | "\n"); | 600 | "\n"); |
| 385 | 601 | ||
| 386 | /* Registers. */ | 602 | /* Registers. */ |
| @@ -412,7 +628,7 @@ c_show(struct seq_file *f, void *slot) | |||
| 412 | "icache size\t: %d\n" | 628 | "icache size\t: %d\n" |
| 413 | "icache flags\t: " | 629 | "icache flags\t: " |
| 414 | #if XCHAL_ICACHE_LINE_LOCKABLE | 630 | #if XCHAL_ICACHE_LINE_LOCKABLE |
| 415 | "lock" | 631 | "lock " |
| 416 | #endif | 632 | #endif |
| 417 | "\n" | 633 | "\n" |
| 418 | "dcache line size: %d\n" | 634 | "dcache line size: %d\n" |
| @@ -420,10 +636,10 @@ c_show(struct seq_file *f, void *slot) | |||
| 420 | "dcache size\t: %d\n" | 636 | "dcache size\t: %d\n" |
| 421 | "dcache flags\t: " | 637 | "dcache flags\t: " |
| 422 | #if XCHAL_DCACHE_IS_WRITEBACK | 638 | #if XCHAL_DCACHE_IS_WRITEBACK |
| 423 | "writeback" | 639 | "writeback " |
| 424 | #endif | 640 | #endif |
| 425 | #if XCHAL_DCACHE_LINE_LOCKABLE | 641 | #if XCHAL_DCACHE_LINE_LOCKABLE |
| 426 | "lock" | 642 | "lock " |
| 427 | #endif | 643 | #endif |
| 428 | "\n", | 644 | "\n", |
| 429 | XCHAL_ICACHE_LINESIZE, | 645 | XCHAL_ICACHE_LINESIZE, |
| @@ -465,4 +681,3 @@ const struct seq_operations cpuinfo_op = | |||
| 465 | }; | 681 | }; |
| 466 | 682 | ||
| 467 | #endif /* CONFIG_PROC_FS */ | 683 | #endif /* CONFIG_PROC_FS */ |
| 468 | |||
diff --git a/arch/xtensa/kernel/signal.c b/arch/xtensa/kernel/signal.c index 63c566f627bc..de34d6be91cd 100644 --- a/arch/xtensa/kernel/signal.c +++ b/arch/xtensa/kernel/signal.c | |||
| @@ -212,7 +212,7 @@ restore_sigcontext(struct pt_regs *regs, struct rt_sigframe __user *frame) | |||
| 212 | if (err) | 212 | if (err) |
| 213 | return err; | 213 | return err; |
| 214 | 214 | ||
| 215 | /* The signal handler may have used coprocessors in which | 215 | /* The signal handler may have used coprocessors in which |
| 216 | * case they are still enabled. We disable them to force a | 216 | * case they are still enabled. We disable them to force a |
| 217 | * reloading of the original task's CP state by the lazy | 217 | * reloading of the original task's CP state by the lazy |
| 218 | * context-switching mechanisms of CP exception handling. | 218 | * context-switching mechanisms of CP exception handling. |
| @@ -396,7 +396,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
| 396 | */ | 396 | */ |
| 397 | 397 | ||
| 398 | /* Set up registers for signal handler */ | 398 | /* Set up registers for signal handler */ |
| 399 | start_thread(regs, (unsigned long) ka->sa.sa_handler, | 399 | start_thread(regs, (unsigned long) ka->sa.sa_handler, |
| 400 | (unsigned long) frame); | 400 | (unsigned long) frame); |
| 401 | 401 | ||
| 402 | /* Set up a stack frame for a call4 | 402 | /* Set up a stack frame for a call4 |
| @@ -424,9 +424,9 @@ give_sigsegv: | |||
| 424 | return -EFAULT; | 424 | return -EFAULT; |
| 425 | } | 425 | } |
| 426 | 426 | ||
| 427 | asmlinkage long xtensa_sigaltstack(const stack_t __user *uss, | 427 | asmlinkage long xtensa_sigaltstack(const stack_t __user *uss, |
| 428 | stack_t __user *uoss, | 428 | stack_t __user *uoss, |
| 429 | long a2, long a3, long a4, long a5, | 429 | long a2, long a3, long a4, long a5, |
| 430 | struct pt_regs *regs) | 430 | struct pt_regs *regs) |
| 431 | { | 431 | { |
| 432 | return do_sigaltstack(uss, uoss, regs->areg[1]); | 432 | return do_sigaltstack(uss, uoss, regs->areg[1]); |
diff --git a/arch/xtensa/kernel/syscall.c b/arch/xtensa/kernel/syscall.c index 5702065f472a..54fa8425cee2 100644 --- a/arch/xtensa/kernel/syscall.c +++ b/arch/xtensa/kernel/syscall.c | |||
| @@ -52,4 +52,3 @@ asmlinkage long xtensa_fadvise64_64(int fd, int advice, | |||
| 52 | { | 52 | { |
| 53 | return sys_fadvise64_64(fd, offset, len, advice); | 53 | return sys_fadvise64_64(fd, offset, len, advice); |
| 54 | } | 54 | } |
| 55 | |||
diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c index ac62f9cf1e10..ffb474104311 100644 --- a/arch/xtensa/kernel/time.c +++ b/arch/xtensa/kernel/time.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #include <linux/irq.h> | 22 | #include <linux/irq.h> |
| 23 | #include <linux/profile.h> | 23 | #include <linux/profile.h> |
| 24 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
| 25 | #include <linux/irqdomain.h> | ||
| 25 | 26 | ||
| 26 | #include <asm/timex.h> | 27 | #include <asm/timex.h> |
| 27 | #include <asm/platform.h> | 28 | #include <asm/platform.h> |
| @@ -31,7 +32,7 @@ unsigned long ccount_per_jiffy; /* per 1/HZ */ | |||
| 31 | unsigned long nsec_per_ccount; /* nsec per ccount increment */ | 32 | unsigned long nsec_per_ccount; /* nsec per ccount increment */ |
| 32 | #endif | 33 | #endif |
| 33 | 34 | ||
| 34 | static cycle_t ccount_read(void) | 35 | static cycle_t ccount_read(struct clocksource *cs) |
| 35 | { | 36 | { |
| 36 | return (cycle_t)get_ccount(); | 37 | return (cycle_t)get_ccount(); |
| 37 | } | 38 | } |
| @@ -52,6 +53,7 @@ static struct irqaction timer_irqaction = { | |||
| 52 | 53 | ||
| 53 | void __init time_init(void) | 54 | void __init time_init(void) |
| 54 | { | 55 | { |
| 56 | unsigned int irq; | ||
| 55 | #ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT | 57 | #ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT |
| 56 | printk("Calibrating CPU frequency "); | 58 | printk("Calibrating CPU frequency "); |
| 57 | platform_calibrate_ccount(); | 59 | platform_calibrate_ccount(); |
| @@ -62,7 +64,8 @@ void __init time_init(void) | |||
| 62 | 64 | ||
| 63 | /* Initialize the linux timer interrupt. */ | 65 | /* Initialize the linux timer interrupt. */ |
| 64 | 66 | ||
| 65 | setup_irq(LINUX_TIMER_INT, &timer_irqaction); | 67 | irq = irq_create_mapping(NULL, LINUX_TIMER_INT); |
| 68 | setup_irq(irq, &timer_irqaction); | ||
| 66 | set_linux_timer(get_ccount() + CCOUNT_PER_JIFFY); | 69 | set_linux_timer(get_ccount() + CCOUNT_PER_JIFFY); |
| 67 | } | 70 | } |
| 68 | 71 | ||
diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c index 5caf2b64d43a..01e0111bf787 100644 --- a/arch/xtensa/kernel/traps.c +++ b/arch/xtensa/kernel/traps.c | |||
| @@ -293,6 +293,17 @@ do_debug(struct pt_regs *regs) | |||
| 293 | } | 293 | } |
| 294 | 294 | ||
| 295 | 295 | ||
| 296 | /* Set exception C handler - for temporary use when probing exceptions */ | ||
| 297 | |||
| 298 | void * __init trap_set_handler(int cause, void *handler) | ||
| 299 | { | ||
| 300 | unsigned long *entry = &exc_table[EXC_TABLE_DEFAULT / 4 + cause]; | ||
| 301 | void *previous = (void *)*entry; | ||
| 302 | *entry = (unsigned long)handler; | ||
| 303 | return previous; | ||
| 304 | } | ||
| 305 | |||
| 306 | |||
| 296 | /* | 307 | /* |
| 297 | * Initialize dispatch tables. | 308 | * Initialize dispatch tables. |
| 298 | * | 309 | * |
| @@ -397,7 +408,8 @@ static inline void spill_registers(void) | |||
| 397 | "wsr a13, sar\n\t" | 408 | "wsr a13, sar\n\t" |
| 398 | "wsr a14, ps\n\t" | 409 | "wsr a14, ps\n\t" |
| 399 | :: "a" (&a0), "a" (&ps) | 410 | :: "a" (&a0), "a" (&ps) |
| 400 | : "a2", "a3", "a4", "a7", "a11", "a12", "a13", "a14", "a15", "memory"); | 411 | : "a2", "a3", "a4", "a7", "a11", "a12", "a13", "a14", "a15", |
| 412 | "memory"); | ||
| 401 | } | 413 | } |
| 402 | 414 | ||
| 403 | void show_trace(struct task_struct *task, unsigned long *sp) | 415 | void show_trace(struct task_struct *task, unsigned long *sp) |
| @@ -452,7 +464,7 @@ void show_stack(struct task_struct *task, unsigned long *sp) | |||
| 452 | 464 | ||
| 453 | if (!sp) | 465 | if (!sp) |
| 454 | sp = stack_pointer(task); | 466 | sp = stack_pointer(task); |
| 455 | stack = sp; | 467 | stack = sp; |
| 456 | 468 | ||
| 457 | printk("\nStack: "); | 469 | printk("\nStack: "); |
| 458 | 470 | ||
| @@ -523,5 +535,3 @@ void die(const char * str, struct pt_regs * regs, long err) | |||
| 523 | 535 | ||
| 524 | do_exit(err); | 536 | do_exit(err); |
| 525 | } | 537 | } |
| 526 | |||
| 527 | |||
diff --git a/arch/xtensa/kernel/vectors.S b/arch/xtensa/kernel/vectors.S index 4462c1e595c2..68df35f66ce3 100644 --- a/arch/xtensa/kernel/vectors.S +++ b/arch/xtensa/kernel/vectors.S | |||
| @@ -79,6 +79,8 @@ ENTRY(_UserExceptionVector) | |||
| 79 | l32i a0, a0, EXC_TABLE_FAST_USER # load handler | 79 | l32i a0, a0, EXC_TABLE_FAST_USER # load handler |
| 80 | jx a0 | 80 | jx a0 |
| 81 | 81 | ||
| 82 | ENDPROC(_UserExceptionVector) | ||
| 83 | |||
| 82 | /* | 84 | /* |
| 83 | * Kernel exception vector. (Exceptions with PS.UM == 0, PS.EXCM == 0) | 85 | * Kernel exception vector. (Exceptions with PS.UM == 0, PS.EXCM == 0) |
| 84 | * | 86 | * |
| @@ -103,6 +105,7 @@ ENTRY(_KernelExceptionVector) | |||
| 103 | l32i a0, a0, EXC_TABLE_FAST_KERNEL # load handler address | 105 | l32i a0, a0, EXC_TABLE_FAST_KERNEL # load handler address |
| 104 | jx a0 | 106 | jx a0 |
| 105 | 107 | ||
| 108 | ENDPROC(_KernelExceptionVector) | ||
| 106 | 109 | ||
| 107 | /* | 110 | /* |
| 108 | * Double exception vector (Exceptions with PS.EXCM == 1) | 111 | * Double exception vector (Exceptions with PS.EXCM == 1) |
| @@ -225,7 +228,13 @@ ENTRY(_DoubleExceptionVector) | |||
| 225 | /* Window overflow/underflow exception. Get stack pointer. */ | 228 | /* Window overflow/underflow exception. Get stack pointer. */ |
| 226 | 229 | ||
| 227 | mov a3, a2 | 230 | mov a3, a2 |
| 228 | movi a2, exc_table | 231 | /* This explicit literal and the following references to it are made |
| 232 | * in order to fit DoubleExceptionVector.literals into the available | ||
| 233 | * 16-byte gap before DoubleExceptionVector.text in the absence of | ||
| 234 | * link time relaxation. See kernel/vmlinux.lds.S | ||
| 235 | */ | ||
| 236 | .literal .Lexc_table, exc_table | ||
| 237 | l32r a2, .Lexc_table | ||
| 229 | l32i a2, a2, EXC_TABLE_KSTK | 238 | l32i a2, a2, EXC_TABLE_KSTK |
| 230 | 239 | ||
| 231 | /* Check for overflow/underflow exception, jump if overflow. */ | 240 | /* Check for overflow/underflow exception, jump if overflow. */ |
| @@ -255,7 +264,7 @@ ENTRY(_DoubleExceptionVector) | |||
| 255 | s32i a0, a2, PT_AREG0 | 264 | s32i a0, a2, PT_AREG0 |
| 256 | 265 | ||
| 257 | wsr a3, excsave1 # save a3 | 266 | wsr a3, excsave1 # save a3 |
| 258 | movi a3, exc_table | 267 | l32r a3, .Lexc_table |
| 259 | 268 | ||
| 260 | rsr a0, exccause | 269 | rsr a0, exccause |
| 261 | s32i a0, a2, PT_DEPC # mark it as a regular exception | 270 | s32i a0, a2, PT_DEPC # mark it as a regular exception |
| @@ -267,7 +276,7 @@ ENTRY(_DoubleExceptionVector) | |||
| 267 | 276 | ||
| 268 | /* a0: depc, a1: a1, a2: a2, a3: trashed, depc: a0, excsave1: a3 */ | 277 | /* a0: depc, a1: a1, a2: a2, a3: trashed, depc: a0, excsave1: a3 */ |
| 269 | 278 | ||
| 270 | movi a3, exc_table | 279 | l32r a3, .Lexc_table |
| 271 | s32i a2, a3, EXC_TABLE_DOUBLE_SAVE # temporary variable | 280 | s32i a2, a3, EXC_TABLE_DOUBLE_SAVE # temporary variable |
| 272 | 281 | ||
| 273 | /* Enter critical section. */ | 282 | /* Enter critical section. */ |
| @@ -296,7 +305,7 @@ ENTRY(_DoubleExceptionVector) | |||
| 296 | 305 | ||
| 297 | /* a0: avail, a1: a1, a2: kstk, a3: avail, depc: a2, excsave: a3 */ | 306 | /* a0: avail, a1: a1, a2: kstk, a3: avail, depc: a2, excsave: a3 */ |
| 298 | 307 | ||
| 299 | movi a3, exc_table | 308 | l32r a3, .Lexc_table |
| 300 | rsr a0, exccause | 309 | rsr a0, exccause |
| 301 | addx4 a0, a0, a3 | 310 | addx4 a0, a0, a3 |
| 302 | l32i a0, a0, EXC_TABLE_FAST_USER | 311 | l32i a0, a0, EXC_TABLE_FAST_USER |
| @@ -338,6 +347,7 @@ ENTRY(_DoubleExceptionVector) | |||
| 338 | 347 | ||
| 339 | .end literal_prefix | 348 | .end literal_prefix |
| 340 | 349 | ||
| 350 | ENDPROC(_DoubleExceptionVector) | ||
| 341 | 351 | ||
| 342 | /* | 352 | /* |
| 343 | * Debug interrupt vector | 353 | * Debug interrupt vector |
| @@ -349,9 +359,11 @@ ENTRY(_DoubleExceptionVector) | |||
| 349 | .section .DebugInterruptVector.text, "ax" | 359 | .section .DebugInterruptVector.text, "ax" |
| 350 | 360 | ||
| 351 | ENTRY(_DebugInterruptVector) | 361 | ENTRY(_DebugInterruptVector) |
| 362 | |||
| 352 | xsr a0, SREG_EXCSAVE + XCHAL_DEBUGLEVEL | 363 | xsr a0, SREG_EXCSAVE + XCHAL_DEBUGLEVEL |
| 353 | jx a0 | 364 | jx a0 |
| 354 | 365 | ||
| 366 | ENDPROC(_DebugInterruptVector) | ||
| 355 | 367 | ||
| 356 | 368 | ||
| 357 | /* Window overflow and underflow handlers. | 369 | /* Window overflow and underflow handlers. |
| @@ -363,38 +375,43 @@ ENTRY(_DebugInterruptVector) | |||
| 363 | * we try to access any page that would cause a page fault early. | 375 | * we try to access any page that would cause a page fault early. |
| 364 | */ | 376 | */ |
| 365 | 377 | ||
| 378 | #define ENTRY_ALIGN64(name) \ | ||
| 379 | .globl name; \ | ||
| 380 | .align 64; \ | ||
| 381 | name: | ||
| 382 | |||
| 366 | .section .WindowVectors.text, "ax" | 383 | .section .WindowVectors.text, "ax" |
| 367 | 384 | ||
| 368 | 385 | ||
| 369 | /* 4-Register Window Overflow Vector (Handler) */ | 386 | /* 4-Register Window Overflow Vector (Handler) */ |
| 370 | 387 | ||
| 371 | .align 64 | 388 | ENTRY_ALIGN64(_WindowOverflow4) |
| 372 | .global _WindowOverflow4 | 389 | |
| 373 | _WindowOverflow4: | ||
| 374 | s32e a0, a5, -16 | 390 | s32e a0, a5, -16 |
| 375 | s32e a1, a5, -12 | 391 | s32e a1, a5, -12 |
| 376 | s32e a2, a5, -8 | 392 | s32e a2, a5, -8 |
| 377 | s32e a3, a5, -4 | 393 | s32e a3, a5, -4 |
| 378 | rfwo | 394 | rfwo |
| 379 | 395 | ||
| 396 | ENDPROC(_WindowOverflow4) | ||
| 397 | |||
| 380 | 398 | ||
| 381 | /* 4-Register Window Underflow Vector (Handler) */ | 399 | /* 4-Register Window Underflow Vector (Handler) */ |
| 382 | 400 | ||
| 383 | .align 64 | 401 | ENTRY_ALIGN64(_WindowUnderflow4) |
| 384 | .global _WindowUnderflow4 | 402 | |
| 385 | _WindowUnderflow4: | ||
| 386 | l32e a0, a5, -16 | 403 | l32e a0, a5, -16 |
| 387 | l32e a1, a5, -12 | 404 | l32e a1, a5, -12 |
| 388 | l32e a2, a5, -8 | 405 | l32e a2, a5, -8 |
| 389 | l32e a3, a5, -4 | 406 | l32e a3, a5, -4 |
| 390 | rfwu | 407 | rfwu |
| 391 | 408 | ||
| 409 | ENDPROC(_WindowUnderflow4) | ||
| 392 | 410 | ||
| 393 | /* 8-Register Window Overflow Vector (Handler) */ | 411 | /* 8-Register Window Overflow Vector (Handler) */ |
| 394 | 412 | ||
| 395 | .align 64 | 413 | ENTRY_ALIGN64(_WindowOverflow8) |
| 396 | .global _WindowOverflow8 | 414 | |
| 397 | _WindowOverflow8: | ||
| 398 | s32e a0, a9, -16 | 415 | s32e a0, a9, -16 |
| 399 | l32e a0, a1, -12 | 416 | l32e a0, a1, -12 |
| 400 | s32e a2, a9, -8 | 417 | s32e a2, a9, -8 |
| @@ -406,11 +423,12 @@ _WindowOverflow8: | |||
| 406 | s32e a7, a0, -20 | 423 | s32e a7, a0, -20 |
| 407 | rfwo | 424 | rfwo |
| 408 | 425 | ||
| 426 | ENDPROC(_WindowOverflow8) | ||
| 427 | |||
| 409 | /* 8-Register Window Underflow Vector (Handler) */ | 428 | /* 8-Register Window Underflow Vector (Handler) */ |
| 410 | 429 | ||
| 411 | .align 64 | 430 | ENTRY_ALIGN64(_WindowUnderflow8) |
| 412 | .global _WindowUnderflow8 | 431 | |
| 413 | _WindowUnderflow8: | ||
| 414 | l32e a1, a9, -12 | 432 | l32e a1, a9, -12 |
| 415 | l32e a0, a9, -16 | 433 | l32e a0, a9, -16 |
| 416 | l32e a7, a1, -12 | 434 | l32e a7, a1, -12 |
| @@ -422,12 +440,12 @@ _WindowUnderflow8: | |||
| 422 | l32e a7, a7, -20 | 440 | l32e a7, a7, -20 |
| 423 | rfwu | 441 | rfwu |
| 424 | 442 | ||
| 443 | ENDPROC(_WindowUnderflow8) | ||
| 425 | 444 | ||
| 426 | /* 12-Register Window Overflow Vector (Handler) */ | 445 | /* 12-Register Window Overflow Vector (Handler) */ |
| 427 | 446 | ||
| 428 | .align 64 | 447 | ENTRY_ALIGN64(_WindowOverflow12) |
| 429 | .global _WindowOverflow12 | 448 | |
| 430 | _WindowOverflow12: | ||
| 431 | s32e a0, a13, -16 | 449 | s32e a0, a13, -16 |
| 432 | l32e a0, a1, -12 | 450 | l32e a0, a1, -12 |
| 433 | s32e a1, a13, -12 | 451 | s32e a1, a13, -12 |
| @@ -443,11 +461,12 @@ _WindowOverflow12: | |||
| 443 | s32e a11, a0, -20 | 461 | s32e a11, a0, -20 |
| 444 | rfwo | 462 | rfwo |
| 445 | 463 | ||
| 464 | ENDPROC(_WindowOverflow12) | ||
| 465 | |||
| 446 | /* 12-Register Window Underflow Vector (Handler) */ | 466 | /* 12-Register Window Underflow Vector (Handler) */ |
| 447 | 467 | ||
| 448 | .align 64 | 468 | ENTRY_ALIGN64(_WindowUnderflow12) |
| 449 | .global _WindowUnderflow12 | 469 | |
| 450 | _WindowUnderflow12: | ||
| 451 | l32e a1, a13, -12 | 470 | l32e a1, a13, -12 |
| 452 | l32e a0, a13, -16 | 471 | l32e a0, a13, -16 |
| 453 | l32e a11, a1, -12 | 472 | l32e a11, a1, -12 |
| @@ -463,6 +482,6 @@ _WindowUnderflow12: | |||
| 463 | l32e a11, a11, -20 | 482 | l32e a11, a11, -20 |
| 464 | rfwu | 483 | rfwu |
| 465 | 484 | ||
| 466 | .text | 485 | ENDPROC(_WindowUnderflow12) |
| 467 | |||
| 468 | 486 | ||
| 487 | .text | ||
diff --git a/arch/xtensa/lib/checksum.S b/arch/xtensa/lib/checksum.S index df397f932d0e..4eb573d2720e 100644 --- a/arch/xtensa/lib/checksum.S +++ b/arch/xtensa/lib/checksum.S | |||
| @@ -41,10 +41,11 @@ | |||
| 41 | 41 | ||
| 42 | .text | 42 | .text |
| 43 | ENTRY(csum_partial) | 43 | ENTRY(csum_partial) |
| 44 | /* | 44 | |
| 45 | * Experiments with Ethernet and SLIP connections show that buf | 45 | /* |
| 46 | * is aligned on either a 2-byte or 4-byte boundary. | 46 | * Experiments with Ethernet and SLIP connections show that buf |
| 47 | */ | 47 | * is aligned on either a 2-byte or 4-byte boundary. |
| 48 | */ | ||
| 48 | entry sp, 32 | 49 | entry sp, 32 |
| 49 | extui a5, a2, 0, 2 | 50 | extui a5, a2, 0, 2 |
| 50 | bnez a5, 8f /* branch if 2-byte aligned */ | 51 | bnez a5, 8f /* branch if 2-byte aligned */ |
| @@ -170,7 +171,7 @@ ENTRY(csum_partial) | |||
| 170 | 3: | 171 | 3: |
| 171 | j 5b /* branch to handle the remaining byte */ | 172 | j 5b /* branch to handle the remaining byte */ |
| 172 | 173 | ||
| 173 | 174 | ENDPROC(csum_partial) | |
| 174 | 175 | ||
| 175 | /* | 176 | /* |
| 176 | * Copy from ds while checksumming, otherwise like csum_partial | 177 | * Copy from ds while checksumming, otherwise like csum_partial |
| @@ -211,6 +212,7 @@ unsigned int csum_partial_copy_generic (const char *src, char *dst, int len, | |||
| 211 | */ | 212 | */ |
| 212 | 213 | ||
| 213 | ENTRY(csum_partial_copy_generic) | 214 | ENTRY(csum_partial_copy_generic) |
| 215 | |||
| 214 | entry sp, 32 | 216 | entry sp, 32 |
| 215 | mov a12, a3 | 217 | mov a12, a3 |
| 216 | mov a11, a4 | 218 | mov a11, a4 |
| @@ -367,6 +369,8 @@ DST( s8i a8, a3, 1 ) | |||
| 367 | 6: | 369 | 6: |
| 368 | j 4b /* process the possible trailing odd byte */ | 370 | j 4b /* process the possible trailing odd byte */ |
| 369 | 371 | ||
| 372 | ENDPROC(csum_partial_copy_generic) | ||
| 373 | |||
| 370 | 374 | ||
| 371 | # Exception handler: | 375 | # Exception handler: |
| 372 | .section .fixup, "ax" | 376 | .section .fixup, "ax" |
| @@ -406,4 +410,3 @@ DST( s8i a8, a3, 1 ) | |||
| 406 | retw | 410 | retw |
| 407 | 411 | ||
| 408 | .previous | 412 | .previous |
| 409 | |||
diff --git a/arch/xtensa/lib/memcopy.S b/arch/xtensa/lib/memcopy.S index c48b80acb5f0..b1c219acabe7 100644 --- a/arch/xtensa/lib/memcopy.S +++ b/arch/xtensa/lib/memcopy.S | |||
| @@ -210,8 +210,10 @@ memcpy: | |||
| 210 | _beqz a4, .Ldone # avoid loading anything for zero-length copies | 210 | _beqz a4, .Ldone # avoid loading anything for zero-length copies |
| 211 | # copy 16 bytes per iteration for word-aligned dst and unaligned src | 211 | # copy 16 bytes per iteration for word-aligned dst and unaligned src |
| 212 | ssa8 a3 # set shift amount from byte offset | 212 | ssa8 a3 # set shift amount from byte offset |
| 213 | #define SIM_CHECKS_ALIGNMENT 1 /* set to 1 when running on ISS (simulator) with the | 213 | |
| 214 | lint or ferret client, or 0 to save a few cycles */ | 214 | /* set to 1 when running on ISS (simulator) with the |
| 215 | lint or ferret client, or 0 to save a few cycles */ | ||
| 216 | #define SIM_CHECKS_ALIGNMENT 1 | ||
| 215 | #if XCHAL_UNALIGNED_LOAD_EXCEPTION || SIM_CHECKS_ALIGNMENT | 217 | #if XCHAL_UNALIGNED_LOAD_EXCEPTION || SIM_CHECKS_ALIGNMENT |
| 216 | and a11, a3, a8 # save unalignment offset for below | 218 | and a11, a3, a8 # save unalignment offset for below |
| 217 | sub a3, a3, a11 # align a3 | 219 | sub a3, a3, a11 # align a3 |
diff --git a/arch/xtensa/lib/pci-auto.c b/arch/xtensa/lib/pci-auto.c index a71733ae1193..34d05abbd921 100644 --- a/arch/xtensa/lib/pci-auto.c +++ b/arch/xtensa/lib/pci-auto.c | |||
| @@ -241,8 +241,8 @@ int __init pciauto_bus_scan(struct pci_controller *pci_ctrl, int current_bus) | |||
| 241 | unsigned char header_type; | 241 | unsigned char header_type; |
| 242 | struct pci_dev *dev = &pciauto_dev; | 242 | struct pci_dev *dev = &pciauto_dev; |
| 243 | 243 | ||
| 244 | pciauto_dev.bus = &pciauto_bus; | 244 | pciauto_dev.bus = &pciauto_bus; |
| 245 | pciauto_dev.sysdata = pci_ctrl; | 245 | pciauto_dev.sysdata = pci_ctrl; |
| 246 | pciauto_bus.ops = pci_ctrl->ops; | 246 | pciauto_bus.ops = pci_ctrl->ops; |
| 247 | 247 | ||
| 248 | /* | 248 | /* |
| @@ -345,8 +345,3 @@ int __init pciauto_bus_scan(struct pci_controller *pci_ctrl, int current_bus) | |||
| 345 | } | 345 | } |
| 346 | return sub_bus; | 346 | return sub_bus; |
| 347 | } | 347 | } |
| 348 | |||
| 349 | |||
| 350 | |||
| 351 | |||
| 352 | |||
diff --git a/arch/xtensa/lib/strncpy_user.S b/arch/xtensa/lib/strncpy_user.S index 9f603cdaaa68..1ad0ecf45368 100644 --- a/arch/xtensa/lib/strncpy_user.S +++ b/arch/xtensa/lib/strncpy_user.S | |||
| @@ -166,7 +166,7 @@ __strncpy_user: | |||
| 166 | retw | 166 | retw |
| 167 | .Lz1: # byte 1 is zero | 167 | .Lz1: # byte 1 is zero |
| 168 | #ifdef __XTENSA_EB__ | 168 | #ifdef __XTENSA_EB__ |
| 169 | extui a9, a9, 16, 16 | 169 | extui a9, a9, 16, 16 |
| 170 | #endif /* __XTENSA_EB__ */ | 170 | #endif /* __XTENSA_EB__ */ |
| 171 | EX(s16i, a9, a11, 0, fixup_s) | 171 | EX(s16i, a9, a11, 0, fixup_s) |
| 172 | addi a11, a11, 1 # advance dst pointer | 172 | addi a11, a11, 1 # advance dst pointer |
| @@ -174,7 +174,7 @@ __strncpy_user: | |||
| 174 | retw | 174 | retw |
| 175 | .Lz2: # byte 2 is zero | 175 | .Lz2: # byte 2 is zero |
| 176 | #ifdef __XTENSA_EB__ | 176 | #ifdef __XTENSA_EB__ |
| 177 | extui a9, a9, 16, 16 | 177 | extui a9, a9, 16, 16 |
| 178 | #endif /* __XTENSA_EB__ */ | 178 | #endif /* __XTENSA_EB__ */ |
| 179 | EX(s16i, a9, a11, 0, fixup_s) | 179 | EX(s16i, a9, a11, 0, fixup_s) |
| 180 | movi a9, 0 | 180 | movi a9, 0 |
diff --git a/arch/xtensa/lib/strnlen_user.S b/arch/xtensa/lib/strnlen_user.S index 23f2a89816a1..4c03b1e581e9 100644 --- a/arch/xtensa/lib/strnlen_user.S +++ b/arch/xtensa/lib/strnlen_user.S | |||
| @@ -145,4 +145,3 @@ __strnlen_user: | |||
| 145 | lenfixup: | 145 | lenfixup: |
| 146 | movi a2, 0 | 146 | movi a2, 0 |
| 147 | retw | 147 | retw |
| 148 | |||
diff --git a/arch/xtensa/lib/usercopy.S b/arch/xtensa/lib/usercopy.S index 46d60314bb16..ace1892a875e 100644 --- a/arch/xtensa/lib/usercopy.S +++ b/arch/xtensa/lib/usercopy.S | |||
| @@ -318,4 +318,3 @@ l_fixup: | |||
| 318 | /* Ignore memset return value in a6. */ | 318 | /* Ignore memset return value in a6. */ |
| 319 | /* a2 still contains bytes not copied. */ | 319 | /* a2 still contains bytes not copied. */ |
| 320 | retw | 320 | retw |
| 321 | |||
diff --git a/arch/xtensa/mm/cache.c b/arch/xtensa/mm/cache.c index 85df4655d326..81edeab82d17 100644 --- a/arch/xtensa/mm/cache.c +++ b/arch/xtensa/mm/cache.c | |||
| @@ -118,7 +118,7 @@ void flush_dcache_page(struct page *page) | |||
| 118 | * For now, flush the whole cache. FIXME?? | 118 | * For now, flush the whole cache. FIXME?? |
| 119 | */ | 119 | */ |
| 120 | 120 | ||
| 121 | void flush_cache_range(struct vm_area_struct* vma, | 121 | void flush_cache_range(struct vm_area_struct* vma, |
| 122 | unsigned long start, unsigned long end) | 122 | unsigned long start, unsigned long end) |
| 123 | { | 123 | { |
| 124 | __flush_invalidate_dcache_all(); | 124 | __flush_invalidate_dcache_all(); |
| @@ -133,7 +133,7 @@ void flush_cache_range(struct vm_area_struct* vma, | |||
| 133 | */ | 133 | */ |
| 134 | 134 | ||
| 135 | void flush_cache_page(struct vm_area_struct* vma, unsigned long address, | 135 | void flush_cache_page(struct vm_area_struct* vma, unsigned long address, |
| 136 | unsigned long pfn) | 136 | unsigned long pfn) |
| 137 | { | 137 | { |
| 138 | /* Note that we have to use the 'alias' address to avoid multi-hit */ | 138 | /* Note that we have to use the 'alias' address to avoid multi-hit */ |
| 139 | 139 | ||
| @@ -166,14 +166,14 @@ update_mmu_cache(struct vm_area_struct * vma, unsigned long addr, pte_t *ptep) | |||
| 166 | 166 | ||
| 167 | if (!PageReserved(page) && test_bit(PG_arch_1, &page->flags)) { | 167 | if (!PageReserved(page) && test_bit(PG_arch_1, &page->flags)) { |
| 168 | 168 | ||
| 169 | unsigned long vaddr = TLBTEMP_BASE_1 + (addr & DCACHE_ALIAS_MASK); | ||
| 170 | unsigned long paddr = (unsigned long) page_address(page); | 169 | unsigned long paddr = (unsigned long) page_address(page); |
| 171 | unsigned long phys = page_to_phys(page); | 170 | unsigned long phys = page_to_phys(page); |
| 171 | unsigned long tmp = TLBTEMP_BASE_1 + (addr & DCACHE_ALIAS_MASK); | ||
| 172 | 172 | ||
| 173 | __flush_invalidate_dcache_page(paddr); | 173 | __flush_invalidate_dcache_page(paddr); |
| 174 | 174 | ||
| 175 | __flush_invalidate_dcache_page_alias(vaddr, phys); | 175 | __flush_invalidate_dcache_page_alias(tmp, phys); |
| 176 | __invalidate_icache_page_alias(vaddr, phys); | 176 | __invalidate_icache_page_alias(tmp, phys); |
| 177 | 177 | ||
| 178 | clear_bit(PG_arch_1, &page->flags); | 178 | clear_bit(PG_arch_1, &page->flags); |
| 179 | } | 179 | } |
| @@ -195,7 +195,7 @@ update_mmu_cache(struct vm_area_struct * vma, unsigned long addr, pte_t *ptep) | |||
| 195 | 195 | ||
| 196 | #if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK | 196 | #if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK |
| 197 | 197 | ||
| 198 | void copy_to_user_page(struct vm_area_struct *vma, struct page *page, | 198 | void copy_to_user_page(struct vm_area_struct *vma, struct page *page, |
| 199 | unsigned long vaddr, void *dst, const void *src, | 199 | unsigned long vaddr, void *dst, const void *src, |
| 200 | unsigned long len) | 200 | unsigned long len) |
| 201 | { | 201 | { |
| @@ -205,8 +205,8 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page, | |||
| 205 | /* Flush and invalidate user page if aliased. */ | 205 | /* Flush and invalidate user page if aliased. */ |
| 206 | 206 | ||
| 207 | if (alias) { | 207 | if (alias) { |
| 208 | unsigned long temp = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK); | 208 | unsigned long t = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK); |
| 209 | __flush_invalidate_dcache_page_alias(temp, phys); | 209 | __flush_invalidate_dcache_page_alias(t, phys); |
| 210 | } | 210 | } |
| 211 | 211 | ||
| 212 | /* Copy data */ | 212 | /* Copy data */ |
| @@ -219,12 +219,11 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page, | |||
| 219 | */ | 219 | */ |
| 220 | 220 | ||
| 221 | if (alias) { | 221 | if (alias) { |
| 222 | unsigned long temp = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK); | 222 | unsigned long t = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK); |
| 223 | 223 | ||
| 224 | __flush_invalidate_dcache_range((unsigned long) dst, len); | 224 | __flush_invalidate_dcache_range((unsigned long) dst, len); |
| 225 | if ((vma->vm_flags & VM_EXEC) != 0) { | 225 | if ((vma->vm_flags & VM_EXEC) != 0) |
| 226 | __invalidate_icache_page_alias(temp, phys); | 226 | __invalidate_icache_page_alias(t, phys); |
| 227 | } | ||
| 228 | 227 | ||
| 229 | } else if ((vma->vm_flags & VM_EXEC) != 0) { | 228 | } else if ((vma->vm_flags & VM_EXEC) != 0) { |
| 230 | __flush_dcache_range((unsigned long)dst,len); | 229 | __flush_dcache_range((unsigned long)dst,len); |
| @@ -245,8 +244,8 @@ extern void copy_from_user_page(struct vm_area_struct *vma, struct page *page, | |||
| 245 | */ | 244 | */ |
| 246 | 245 | ||
| 247 | if (alias) { | 246 | if (alias) { |
| 248 | unsigned long temp = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK); | 247 | unsigned long t = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK); |
| 249 | __flush_invalidate_dcache_page_alias(temp, phys); | 248 | __flush_invalidate_dcache_page_alias(t, phys); |
| 250 | } | 249 | } |
| 251 | 250 | ||
| 252 | memcpy(dst, src, len); | 251 | memcpy(dst, src, len); |
diff --git a/arch/xtensa/mm/fault.c b/arch/xtensa/mm/fault.c index 245b08f7eaf4..4b7bc8db170f 100644 --- a/arch/xtensa/mm/fault.c +++ b/arch/xtensa/mm/fault.c | |||
| @@ -254,4 +254,3 @@ bad_page_fault(struct pt_regs *regs, unsigned long address, int sig) | |||
| 254 | die("Oops", regs, sig); | 254 | die("Oops", regs, sig); |
| 255 | do_exit(sig); | 255 | do_exit(sig); |
| 256 | } | 256 | } |
| 257 | |||
diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c index db955179da2d..7a5156ffebb6 100644 --- a/arch/xtensa/mm/init.c +++ b/arch/xtensa/mm/init.c | |||
| @@ -75,15 +75,15 @@ int __init mem_reserve(unsigned long start, unsigned long end, int must_exist) | |||
| 75 | sysmem.nr_banks++; | 75 | sysmem.nr_banks++; |
| 76 | } | 76 | } |
| 77 | sysmem.bank[i].end = start; | 77 | sysmem.bank[i].end = start; |
| 78 | |||
| 79 | } else if (end < sysmem.bank[i].end) { | ||
| 80 | sysmem.bank[i].start = end; | ||
| 81 | |||
| 78 | } else { | 82 | } else { |
| 79 | if (end < sysmem.bank[i].end) | 83 | /* remove entry */ |
| 80 | sysmem.bank[i].start = end; | 84 | sysmem.nr_banks--; |
| 81 | else { | 85 | sysmem.bank[i].start = sysmem.bank[sysmem.nr_banks].start; |
| 82 | /* remove entry */ | 86 | sysmem.bank[i].end = sysmem.bank[sysmem.nr_banks].end; |
| 83 | sysmem.nr_banks--; | ||
| 84 | sysmem.bank[i].start = sysmem.bank[sysmem.nr_banks].start; | ||
| 85 | sysmem.bank[i].end = sysmem.bank[sysmem.nr_banks].end; | ||
| 86 | } | ||
| 87 | } | 87 | } |
| 88 | return -1; | 88 | return -1; |
| 89 | } | 89 | } |
diff --git a/arch/xtensa/mm/misc.S b/arch/xtensa/mm/misc.S index b048406d8756..d97ed1ba7b0a 100644 --- a/arch/xtensa/mm/misc.S +++ b/arch/xtensa/mm/misc.S | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | */ | 29 | */ |
| 30 | 30 | ||
| 31 | ENTRY(clear_page) | 31 | ENTRY(clear_page) |
| 32 | |||
| 32 | entry a1, 16 | 33 | entry a1, 16 |
| 33 | 34 | ||
| 34 | movi a3, 0 | 35 | movi a3, 0 |
| @@ -45,6 +46,8 @@ ENTRY(clear_page) | |||
| 45 | 46 | ||
| 46 | retw | 47 | retw |
| 47 | 48 | ||
| 49 | ENDPROC(clear_page) | ||
| 50 | |||
| 48 | /* | 51 | /* |
| 49 | * copy_page and copy_user_page are the same for non-cache-aliased configs. | 52 | * copy_page and copy_user_page are the same for non-cache-aliased configs. |
| 50 | * | 53 | * |
| @@ -53,6 +56,7 @@ ENTRY(clear_page) | |||
| 53 | */ | 56 | */ |
| 54 | 57 | ||
| 55 | ENTRY(copy_page) | 58 | ENTRY(copy_page) |
| 59 | |||
| 56 | entry a1, 16 | 60 | entry a1, 16 |
| 57 | 61 | ||
| 58 | __loopi a2, a4, PAGE_SIZE, 32 | 62 | __loopi a2, a4, PAGE_SIZE, 32 |
| @@ -84,6 +88,8 @@ ENTRY(copy_page) | |||
| 84 | 88 | ||
| 85 | retw | 89 | retw |
| 86 | 90 | ||
| 91 | ENDPROC(copy_page) | ||
| 92 | |||
| 87 | #ifdef CONFIG_MMU | 93 | #ifdef CONFIG_MMU |
| 88 | /* | 94 | /* |
| 89 | * If we have to deal with cache aliasing, we use temporary memory mappings | 95 | * If we have to deal with cache aliasing, we use temporary memory mappings |
| @@ -109,6 +115,7 @@ ENTRY(__tlbtemp_mapping_start) | |||
| 109 | */ | 115 | */ |
| 110 | 116 | ||
| 111 | ENTRY(clear_user_page) | 117 | ENTRY(clear_user_page) |
| 118 | |||
| 112 | entry a1, 32 | 119 | entry a1, 32 |
| 113 | 120 | ||
| 114 | /* Mark page dirty and determine alias. */ | 121 | /* Mark page dirty and determine alias. */ |
| @@ -164,6 +171,8 @@ ENTRY(clear_user_page) | |||
| 164 | 171 | ||
| 165 | retw | 172 | retw |
| 166 | 173 | ||
| 174 | ENDPROC(clear_user_page) | ||
| 175 | |||
| 167 | /* | 176 | /* |
| 168 | * copy_page_user (void *to, void *from, unsigned long vaddr, struct page *page) | 177 | * copy_page_user (void *to, void *from, unsigned long vaddr, struct page *page) |
| 169 | * a2 a3 a4 a5 | 178 | * a2 a3 a4 a5 |
| @@ -171,7 +180,7 @@ ENTRY(clear_user_page) | |||
| 171 | 180 | ||
| 172 | ENTRY(copy_user_page) | 181 | ENTRY(copy_user_page) |
| 173 | 182 | ||
| 174 | entry a1, 32 | 183 | entry a1, 32 |
| 175 | 184 | ||
| 176 | /* Mark page dirty and determine alias for destination. */ | 185 | /* Mark page dirty and determine alias for destination. */ |
| 177 | 186 | ||
| @@ -262,6 +271,8 @@ ENTRY(copy_user_page) | |||
| 262 | 271 | ||
| 263 | retw | 272 | retw |
| 264 | 273 | ||
| 274 | ENDPROC(copy_user_page) | ||
| 275 | |||
| 265 | #endif | 276 | #endif |
| 266 | 277 | ||
| 267 | #if (DCACHE_WAY_SIZE > PAGE_SIZE) | 278 | #if (DCACHE_WAY_SIZE > PAGE_SIZE) |
| @@ -272,6 +283,7 @@ ENTRY(copy_user_page) | |||
| 272 | */ | 283 | */ |
| 273 | 284 | ||
| 274 | ENTRY(__flush_invalidate_dcache_page_alias) | 285 | ENTRY(__flush_invalidate_dcache_page_alias) |
| 286 | |||
| 275 | entry sp, 16 | 287 | entry sp, 16 |
| 276 | 288 | ||
| 277 | movi a7, 0 # required for exception handler | 289 | movi a7, 0 # required for exception handler |
| @@ -287,6 +299,7 @@ ENTRY(__flush_invalidate_dcache_page_alias) | |||
| 287 | 299 | ||
| 288 | retw | 300 | retw |
| 289 | 301 | ||
| 302 | ENDPROC(__flush_invalidate_dcache_page_alias) | ||
| 290 | #endif | 303 | #endif |
| 291 | 304 | ||
| 292 | ENTRY(__tlbtemp_mapping_itlb) | 305 | ENTRY(__tlbtemp_mapping_itlb) |
| @@ -294,6 +307,7 @@ ENTRY(__tlbtemp_mapping_itlb) | |||
| 294 | #if (ICACHE_WAY_SIZE > PAGE_SIZE) | 307 | #if (ICACHE_WAY_SIZE > PAGE_SIZE) |
| 295 | 308 | ||
| 296 | ENTRY(__invalidate_icache_page_alias) | 309 | ENTRY(__invalidate_icache_page_alias) |
| 310 | |||
| 297 | entry sp, 16 | 311 | entry sp, 16 |
| 298 | 312 | ||
| 299 | addi a6, a3, (PAGE_KERNEL_EXEC | _PAGE_HW_WRITE) | 313 | addi a6, a3, (PAGE_KERNEL_EXEC | _PAGE_HW_WRITE) |
| @@ -307,11 +321,14 @@ ENTRY(__invalidate_icache_page_alias) | |||
| 307 | isync | 321 | isync |
| 308 | retw | 322 | retw |
| 309 | 323 | ||
| 324 | ENDPROC(__invalidate_icache_page_alias) | ||
| 325 | |||
| 310 | #endif | 326 | #endif |
| 311 | 327 | ||
| 312 | /* End of special treatment in tlb miss exception */ | 328 | /* End of special treatment in tlb miss exception */ |
| 313 | 329 | ||
| 314 | ENTRY(__tlbtemp_mapping_end) | 330 | ENTRY(__tlbtemp_mapping_end) |
| 331 | |||
| 315 | #endif /* CONFIG_MMU | 332 | #endif /* CONFIG_MMU |
| 316 | 333 | ||
| 317 | /* | 334 | /* |
| @@ -319,6 +336,7 @@ ENTRY(__tlbtemp_mapping_end) | |||
| 319 | */ | 336 | */ |
| 320 | 337 | ||
| 321 | ENTRY(__invalidate_icache_page) | 338 | ENTRY(__invalidate_icache_page) |
| 339 | |||
| 322 | entry sp, 16 | 340 | entry sp, 16 |
| 323 | 341 | ||
| 324 | ___invalidate_icache_page a2 a3 | 342 | ___invalidate_icache_page a2 a3 |
| @@ -326,11 +344,14 @@ ENTRY(__invalidate_icache_page) | |||
| 326 | 344 | ||
| 327 | retw | 345 | retw |
| 328 | 346 | ||
| 347 | ENDPROC(__invalidate_icache_page) | ||
| 348 | |||
| 329 | /* | 349 | /* |
| 330 | * void __invalidate_dcache_page(ulong start) | 350 | * void __invalidate_dcache_page(ulong start) |
| 331 | */ | 351 | */ |
| 332 | 352 | ||
| 333 | ENTRY(__invalidate_dcache_page) | 353 | ENTRY(__invalidate_dcache_page) |
| 354 | |||
| 334 | entry sp, 16 | 355 | entry sp, 16 |
| 335 | 356 | ||
| 336 | ___invalidate_dcache_page a2 a3 | 357 | ___invalidate_dcache_page a2 a3 |
| @@ -338,11 +359,14 @@ ENTRY(__invalidate_dcache_page) | |||
| 338 | 359 | ||
| 339 | retw | 360 | retw |
| 340 | 361 | ||
| 362 | ENDPROC(__invalidate_dcache_page) | ||
| 363 | |||
| 341 | /* | 364 | /* |
| 342 | * void __flush_invalidate_dcache_page(ulong start) | 365 | * void __flush_invalidate_dcache_page(ulong start) |
| 343 | */ | 366 | */ |
| 344 | 367 | ||
| 345 | ENTRY(__flush_invalidate_dcache_page) | 368 | ENTRY(__flush_invalidate_dcache_page) |
| 369 | |||
| 346 | entry sp, 16 | 370 | entry sp, 16 |
| 347 | 371 | ||
| 348 | ___flush_invalidate_dcache_page a2 a3 | 372 | ___flush_invalidate_dcache_page a2 a3 |
| @@ -350,11 +374,14 @@ ENTRY(__flush_invalidate_dcache_page) | |||
| 350 | dsync | 374 | dsync |
| 351 | retw | 375 | retw |
| 352 | 376 | ||
| 377 | ENDPROC(__flush_invalidate_dcache_page) | ||
| 378 | |||
| 353 | /* | 379 | /* |
| 354 | * void __flush_dcache_page(ulong start) | 380 | * void __flush_dcache_page(ulong start) |
| 355 | */ | 381 | */ |
| 356 | 382 | ||
| 357 | ENTRY(__flush_dcache_page) | 383 | ENTRY(__flush_dcache_page) |
| 384 | |||
| 358 | entry sp, 16 | 385 | entry sp, 16 |
| 359 | 386 | ||
| 360 | ___flush_dcache_page a2 a3 | 387 | ___flush_dcache_page a2 a3 |
| @@ -362,11 +389,14 @@ ENTRY(__flush_dcache_page) | |||
| 362 | dsync | 389 | dsync |
| 363 | retw | 390 | retw |
| 364 | 391 | ||
| 392 | ENDPROC(__flush_dcache_page) | ||
| 393 | |||
| 365 | /* | 394 | /* |
| 366 | * void __invalidate_icache_range(ulong start, ulong size) | 395 | * void __invalidate_icache_range(ulong start, ulong size) |
| 367 | */ | 396 | */ |
| 368 | 397 | ||
| 369 | ENTRY(__invalidate_icache_range) | 398 | ENTRY(__invalidate_icache_range) |
| 399 | |||
| 370 | entry sp, 16 | 400 | entry sp, 16 |
| 371 | 401 | ||
| 372 | ___invalidate_icache_range a2 a3 a4 | 402 | ___invalidate_icache_range a2 a3 a4 |
| @@ -374,11 +404,14 @@ ENTRY(__invalidate_icache_range) | |||
| 374 | 404 | ||
| 375 | retw | 405 | retw |
| 376 | 406 | ||
| 407 | ENDPROC(__invalidate_icache_range) | ||
| 408 | |||
| 377 | /* | 409 | /* |
| 378 | * void __flush_invalidate_dcache_range(ulong start, ulong size) | 410 | * void __flush_invalidate_dcache_range(ulong start, ulong size) |
| 379 | */ | 411 | */ |
| 380 | 412 | ||
| 381 | ENTRY(__flush_invalidate_dcache_range) | 413 | ENTRY(__flush_invalidate_dcache_range) |
| 414 | |||
| 382 | entry sp, 16 | 415 | entry sp, 16 |
| 383 | 416 | ||
| 384 | ___flush_invalidate_dcache_range a2 a3 a4 | 417 | ___flush_invalidate_dcache_range a2 a3 a4 |
| @@ -386,11 +419,14 @@ ENTRY(__flush_invalidate_dcache_range) | |||
| 386 | 419 | ||
| 387 | retw | 420 | retw |
| 388 | 421 | ||
| 422 | ENDPROC(__flush_invalidate_dcache_range) | ||
| 423 | |||
| 389 | /* | 424 | /* |
| 390 | * void _flush_dcache_range(ulong start, ulong size) | 425 | * void _flush_dcache_range(ulong start, ulong size) |
| 391 | */ | 426 | */ |
| 392 | 427 | ||
| 393 | ENTRY(__flush_dcache_range) | 428 | ENTRY(__flush_dcache_range) |
| 429 | |||
| 394 | entry sp, 16 | 430 | entry sp, 16 |
| 395 | 431 | ||
| 396 | ___flush_dcache_range a2 a3 a4 | 432 | ___flush_dcache_range a2 a3 a4 |
| @@ -398,22 +434,28 @@ ENTRY(__flush_dcache_range) | |||
| 398 | 434 | ||
| 399 | retw | 435 | retw |
| 400 | 436 | ||
| 437 | ENDPROC(__flush_dcache_range) | ||
| 438 | |||
| 401 | /* | 439 | /* |
| 402 | * void _invalidate_dcache_range(ulong start, ulong size) | 440 | * void _invalidate_dcache_range(ulong start, ulong size) |
| 403 | */ | 441 | */ |
| 404 | 442 | ||
| 405 | ENTRY(__invalidate_dcache_range) | 443 | ENTRY(__invalidate_dcache_range) |
| 444 | |||
| 406 | entry sp, 16 | 445 | entry sp, 16 |
| 407 | 446 | ||
| 408 | ___invalidate_dcache_range a2 a3 a4 | 447 | ___invalidate_dcache_range a2 a3 a4 |
| 409 | 448 | ||
| 410 | retw | 449 | retw |
| 411 | 450 | ||
| 451 | ENDPROC(__invalidate_dcache_range) | ||
| 452 | |||
| 412 | /* | 453 | /* |
| 413 | * void _invalidate_icache_all(void) | 454 | * void _invalidate_icache_all(void) |
| 414 | */ | 455 | */ |
| 415 | 456 | ||
| 416 | ENTRY(__invalidate_icache_all) | 457 | ENTRY(__invalidate_icache_all) |
| 458 | |||
| 417 | entry sp, 16 | 459 | entry sp, 16 |
| 418 | 460 | ||
| 419 | ___invalidate_icache_all a2 a3 | 461 | ___invalidate_icache_all a2 a3 |
| @@ -421,11 +463,14 @@ ENTRY(__invalidate_icache_all) | |||
| 421 | 463 | ||
| 422 | retw | 464 | retw |
| 423 | 465 | ||
| 466 | ENDPROC(__invalidate_icache_all) | ||
| 467 | |||
| 424 | /* | 468 | /* |
| 425 | * void _flush_invalidate_dcache_all(void) | 469 | * void _flush_invalidate_dcache_all(void) |
| 426 | */ | 470 | */ |
| 427 | 471 | ||
| 428 | ENTRY(__flush_invalidate_dcache_all) | 472 | ENTRY(__flush_invalidate_dcache_all) |
| 473 | |||
| 429 | entry sp, 16 | 474 | entry sp, 16 |
| 430 | 475 | ||
| 431 | ___flush_invalidate_dcache_all a2 a3 | 476 | ___flush_invalidate_dcache_all a2 a3 |
| @@ -433,11 +478,14 @@ ENTRY(__flush_invalidate_dcache_all) | |||
| 433 | 478 | ||
| 434 | retw | 479 | retw |
| 435 | 480 | ||
| 481 | ENDPROC(__flush_invalidate_dcache_all) | ||
| 482 | |||
| 436 | /* | 483 | /* |
| 437 | * void _invalidate_dcache_all(void) | 484 | * void _invalidate_dcache_all(void) |
| 438 | */ | 485 | */ |
| 439 | 486 | ||
| 440 | ENTRY(__invalidate_dcache_all) | 487 | ENTRY(__invalidate_dcache_all) |
| 488 | |||
| 441 | entry sp, 16 | 489 | entry sp, 16 |
| 442 | 490 | ||
| 443 | ___invalidate_dcache_all a2 a3 | 491 | ___invalidate_dcache_all a2 a3 |
| @@ -445,3 +493,4 @@ ENTRY(__invalidate_dcache_all) | |||
| 445 | 493 | ||
| 446 | retw | 494 | retw |
| 447 | 495 | ||
| 496 | ENDPROC(__invalidate_dcache_all) | ||
diff --git a/arch/xtensa/mm/mmu.c b/arch/xtensa/mm/mmu.c index ca81654f3ec2..0f77f9d3bb8b 100644 --- a/arch/xtensa/mm/mmu.c +++ b/arch/xtensa/mm/mmu.c | |||
| @@ -37,7 +37,7 @@ void __init init_mmu(void) | |||
| 37 | 37 | ||
| 38 | /* Set rasid register to a known value. */ | 38 | /* Set rasid register to a known value. */ |
| 39 | 39 | ||
| 40 | set_rasid_register(ASID_USER_FIRST); | 40 | set_rasid_register(ASID_INSERT(ASID_USER_FIRST)); |
| 41 | 41 | ||
| 42 | /* Set PTEVADDR special register to the start of the page | 42 | /* Set PTEVADDR special register to the start of the page |
| 43 | * table, which is in kernel mappable space (ie. not | 43 | * table, which is in kernel mappable space (ie. not |
diff --git a/arch/xtensa/mm/tlb.c b/arch/xtensa/mm/tlb.c index e2700b21395b..5411aa67c68e 100644 --- a/arch/xtensa/mm/tlb.c +++ b/arch/xtensa/mm/tlb.c | |||
| @@ -63,7 +63,7 @@ void flush_tlb_all (void) | |||
| 63 | void flush_tlb_mm(struct mm_struct *mm) | 63 | void flush_tlb_mm(struct mm_struct *mm) |
| 64 | { | 64 | { |
| 65 | if (mm == current->active_mm) { | 65 | if (mm == current->active_mm) { |
| 66 | int flags; | 66 | unsigned long flags; |
| 67 | local_save_flags(flags); | 67 | local_save_flags(flags); |
| 68 | __get_new_mmu_context(mm); | 68 | __get_new_mmu_context(mm); |
| 69 | __load_mmu_context(mm); | 69 | __load_mmu_context(mm); |
| @@ -82,7 +82,7 @@ void flush_tlb_mm(struct mm_struct *mm) | |||
| 82 | #endif | 82 | #endif |
| 83 | 83 | ||
| 84 | void flush_tlb_range (struct vm_area_struct *vma, | 84 | void flush_tlb_range (struct vm_area_struct *vma, |
| 85 | unsigned long start, unsigned long end) | 85 | unsigned long start, unsigned long end) |
| 86 | { | 86 | { |
| 87 | struct mm_struct *mm = vma->vm_mm; | 87 | struct mm_struct *mm = vma->vm_mm; |
| 88 | unsigned long flags; | 88 | unsigned long flags; |
| @@ -100,7 +100,7 @@ void flush_tlb_range (struct vm_area_struct *vma, | |||
| 100 | int oldpid = get_rasid_register(); | 100 | int oldpid = get_rasid_register(); |
| 101 | set_rasid_register (ASID_INSERT(mm->context)); | 101 | set_rasid_register (ASID_INSERT(mm->context)); |
| 102 | start &= PAGE_MASK; | 102 | start &= PAGE_MASK; |
| 103 | if (vma->vm_flags & VM_EXEC) | 103 | if (vma->vm_flags & VM_EXEC) |
| 104 | while(start < end) { | 104 | while(start < end) { |
| 105 | invalidate_itlb_mapping(start); | 105 | invalidate_itlb_mapping(start); |
| 106 | invalidate_dtlb_mapping(start); | 106 | invalidate_dtlb_mapping(start); |
| @@ -130,7 +130,7 @@ void flush_tlb_page (struct vm_area_struct *vma, unsigned long page) | |||
| 130 | 130 | ||
| 131 | local_save_flags(flags); | 131 | local_save_flags(flags); |
| 132 | 132 | ||
| 133 | oldpid = get_rasid_register(); | 133 | oldpid = get_rasid_register(); |
| 134 | 134 | ||
| 135 | if (vma->vm_flags & VM_EXEC) | 135 | if (vma->vm_flags & VM_EXEC) |
| 136 | invalidate_itlb_mapping(page); | 136 | invalidate_itlb_mapping(page); |
| @@ -140,4 +140,3 @@ void flush_tlb_page (struct vm_area_struct *vma, unsigned long page) | |||
| 140 | 140 | ||
| 141 | local_irq_restore(flags); | 141 | local_irq_restore(flags); |
| 142 | } | 142 | } |
| 143 | |||
diff --git a/arch/xtensa/platforms/iss/include/platform/serial.h b/arch/xtensa/platforms/iss/include/platform/serial.h index e69de29bb2d1..16aec542d435 100644 --- a/arch/xtensa/platforms/iss/include/platform/serial.h +++ b/arch/xtensa/platforms/iss/include/platform/serial.h | |||
| @@ -0,0 +1,15 @@ | |||
| 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) 2012 Tensilica Inc. | ||
| 7 | */ | ||
| 8 | |||
| 9 | #ifndef __ASM_XTENSA_ISS_SERIAL_H | ||
| 10 | #define __ASM_XTENSA_ISS_SERIAL_H | ||
| 11 | |||
| 12 | /* Have no meaning on ISS, but needed for 8250_early.c */ | ||
| 13 | #define BASE_BAUD 0 | ||
| 14 | |||
| 15 | #endif /* __ASM_XTENSA_ISS_SERIAL_H */ | ||
diff --git a/arch/xtensa/platforms/iss/include/platform/simcall.h b/arch/xtensa/platforms/iss/include/platform/simcall.h index bd78192e2fc9..b5a4edf02d76 100644 --- a/arch/xtensa/platforms/iss/include/platform/simcall.h +++ b/arch/xtensa/platforms/iss/include/platform/simcall.h | |||
| @@ -74,13 +74,12 @@ static inline int __simc(int a, int b, int c, int d, int e, int f) | |||
| 74 | "mov %1, a3\n" | 74 | "mov %1, a3\n" |
| 75 | : "=a" (ret), "=a" (errno), "+r"(a1), "+r"(b1) | 75 | : "=a" (ret), "=a" (errno), "+r"(a1), "+r"(b1) |
| 76 | : "r"(c1), "r"(d1), "r"(e1), "r"(f1) | 76 | : "r"(c1), "r"(d1), "r"(e1), "r"(f1) |
| 77 | : ); | 77 | : "memory"); |
| 78 | return ret; | 78 | return ret; |
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | static inline int simc_open(const char *file, int flags, int mode) | 81 | static inline int simc_open(const char *file, int flags, int mode) |
| 82 | { | 82 | { |
| 83 | wmb(); | ||
| 84 | return __simc(SYS_open, (int) file, flags, mode, 0, 0); | 83 | return __simc(SYS_open, (int) file, flags, mode, 0, 0); |
| 85 | } | 84 | } |
| 86 | 85 | ||
| @@ -91,19 +90,16 @@ static inline int simc_close(int fd) | |||
| 91 | 90 | ||
| 92 | static inline int simc_ioctl(int fd, int request, void *arg) | 91 | static inline int simc_ioctl(int fd, int request, void *arg) |
| 93 | { | 92 | { |
| 94 | wmb(); | ||
| 95 | return __simc(SYS_ioctl, fd, request, (int) arg, 0, 0); | 93 | return __simc(SYS_ioctl, fd, request, (int) arg, 0, 0); |
| 96 | } | 94 | } |
| 97 | 95 | ||
| 98 | static inline int simc_read(int fd, void *buf, size_t count) | 96 | static inline int simc_read(int fd, void *buf, size_t count) |
| 99 | { | 97 | { |
| 100 | rmb(); | ||
| 101 | return __simc(SYS_read, fd, (int) buf, count, 0, 0); | 98 | return __simc(SYS_read, fd, (int) buf, count, 0, 0); |
| 102 | } | 99 | } |
| 103 | 100 | ||
| 104 | static inline int simc_write(int fd, const void *buf, size_t count) | 101 | static inline int simc_write(int fd, const void *buf, size_t count) |
| 105 | { | 102 | { |
| 106 | wmb(); | ||
| 107 | return __simc(SYS_write, fd, (int) buf, count, 0, 0); | 103 | return __simc(SYS_write, fd, (int) buf, count, 0, 0); |
| 108 | } | 104 | } |
| 109 | 105 | ||
| @@ -111,7 +107,6 @@ static inline int simc_poll(int fd) | |||
| 111 | { | 107 | { |
| 112 | struct timeval tv = { .tv_sec = 0, .tv_usec = 0 }; | 108 | struct timeval tv = { .tv_sec = 0, .tv_usec = 0 }; |
| 113 | 109 | ||
| 114 | wmb(); | ||
| 115 | return __simc(SYS_select_one, fd, XTISS_SELECT_ONE_READ, (int)&tv, | 110 | return __simc(SYS_select_one, fd, XTISS_SELECT_ONE_READ, (int)&tv, |
| 116 | 0, 0); | 111 | 0, 0); |
| 117 | } | 112 | } |
diff --git a/arch/xtensa/platforms/xtfpga/Makefile b/arch/xtensa/platforms/xtfpga/Makefile new file mode 100644 index 000000000000..b9ae206340cd --- /dev/null +++ b/arch/xtensa/platforms/xtfpga/Makefile | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | # Makefile for the Tensilica xtavnet Emulation Board | ||
| 2 | # | ||
| 3 | # Note! Dependencies are done automagically by 'make dep', which also | ||
| 4 | # removes any old dependencies. DON'T put your own dependencies here | ||
| 5 | # unless it's something special (ie not a .c file). | ||
| 6 | # | ||
| 7 | # Note 2! The CFLAGS definitions are in the main makefile... | ||
| 8 | |||
| 9 | obj-y = setup.o lcd.o | ||
diff --git a/arch/xtensa/platforms/xtfpga/include/platform/hardware.h b/arch/xtensa/platforms/xtfpga/include/platform/hardware.h new file mode 100644 index 000000000000..4416773cbde5 --- /dev/null +++ b/arch/xtensa/platforms/xtfpga/include/platform/hardware.h | |||
| @@ -0,0 +1,69 @@ | |||
| 1 | /* | ||
| 2 | * arch/xtensa/platform/xtavnet/include/platform/hardware.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) 2006 Tensilica Inc. | ||
| 9 | */ | ||
| 10 | |||
| 11 | /* | ||
| 12 | * This file contains the hardware configuration of the XTAVNET boards. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #ifndef __XTENSA_XTAVNET_HARDWARE_H | ||
| 16 | #define __XTENSA_XTAVNET_HARDWARE_H | ||
| 17 | |||
| 18 | /* By default NO_IRQ is defined to 0 in Linux, but we use the | ||
| 19 | interrupt 0 for UART... */ | ||
| 20 | #define NO_IRQ -1 | ||
| 21 | |||
| 22 | /* Memory configuration. */ | ||
| 23 | |||
| 24 | #define PLATFORM_DEFAULT_MEM_START 0x00000000 | ||
| 25 | #define PLATFORM_DEFAULT_MEM_SIZE 0x04000000 | ||
| 26 | |||
| 27 | /* Interrupt configuration. */ | ||
| 28 | |||
| 29 | #define PLATFORM_NR_IRQS 10 | ||
| 30 | |||
| 31 | /* Default assignment of LX60 devices to external interrupts. */ | ||
| 32 | |||
| 33 | #ifdef CONFIG_ARCH_HAS_SMP | ||
| 34 | #define DUART16552_INTNUM XCHAL_EXTINT3_NUM | ||
| 35 | #define OETH_IRQ XCHAL_EXTINT4_NUM | ||
| 36 | #else | ||
| 37 | #define DUART16552_INTNUM XCHAL_EXTINT0_NUM | ||
| 38 | #define OETH_IRQ XCHAL_EXTINT1_NUM | ||
| 39 | #endif | ||
| 40 | |||
| 41 | /* | ||
| 42 | * Device addresses and parameters. | ||
| 43 | */ | ||
| 44 | |||
| 45 | /* UART */ | ||
| 46 | #define DUART16552_PADDR (XCHAL_KIO_PADDR + 0x0D050020) | ||
| 47 | /* LCD instruction and data addresses. */ | ||
| 48 | #define LCD_INSTR_ADDR ((char *)IOADDR(0x0D040000)) | ||
| 49 | #define LCD_DATA_ADDR ((char *)IOADDR(0x0D040004)) | ||
| 50 | |||
| 51 | /* Misc. */ | ||
| 52 | #define XTFPGA_FPGAREGS_VADDR IOADDR(0x0D020000) | ||
| 53 | /* Clock frequency in Hz (read-only): */ | ||
| 54 | #define XTFPGA_CLKFRQ_VADDR (XTFPGA_FPGAREGS_VADDR + 0x04) | ||
| 55 | /* Setting of 8 DIP switches: */ | ||
| 56 | #define DIP_SWITCHES_VADDR (XTFPGA_FPGAREGS_VADDR + 0x0C) | ||
| 57 | /* Software reset (write 0xdead): */ | ||
| 58 | #define XTFPGA_SWRST_VADDR (XTFPGA_FPGAREGS_VADDR + 0x10) | ||
| 59 | |||
| 60 | /* OpenCores Ethernet controller: */ | ||
| 61 | /* regs + RX/TX descriptors */ | ||
| 62 | #define OETH_REGS_PADDR (XCHAL_KIO_PADDR + 0x0D030000) | ||
| 63 | #define OETH_REGS_SIZE 0x1000 | ||
| 64 | #define OETH_SRAMBUFF_PADDR (XCHAL_KIO_PADDR + 0x0D800000) | ||
| 65 | |||
| 66 | /* 5*rx buffs + 5*tx buffs */ | ||
| 67 | #define OETH_SRAMBUFF_SIZE (5 * 0x600 + 5 * 0x600) | ||
| 68 | |||
| 69 | #endif /* __XTENSA_XTAVNET_HARDWARE_H */ | ||
diff --git a/arch/xtensa/platforms/xtfpga/include/platform/lcd.h b/arch/xtensa/platforms/xtfpga/include/platform/lcd.h new file mode 100644 index 000000000000..0e435645af5a --- /dev/null +++ b/arch/xtensa/platforms/xtfpga/include/platform/lcd.h | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | /* | ||
| 2 | * arch/xtensa/platform/xtavnet/include/platform/lcd.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, 2006 Tensilica Inc. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #ifndef __XTENSA_XTAVNET_LCD_H | ||
| 12 | #define __XTENSA_XTAVNET_LCD_H | ||
| 13 | |||
| 14 | /* Display string STR at position POS on the LCD. */ | ||
| 15 | void lcd_disp_at_pos(char *str, unsigned char pos); | ||
| 16 | |||
| 17 | /* Shift the contents of the LCD display left or right. */ | ||
| 18 | void lcd_shiftleft(void); | ||
| 19 | void lcd_shiftright(void); | ||
| 20 | #endif | ||
diff --git a/arch/xtensa/platforms/xtfpga/include/platform/serial.h b/arch/xtensa/platforms/xtfpga/include/platform/serial.h new file mode 100644 index 000000000000..14d8f7beebfd --- /dev/null +++ b/arch/xtensa/platforms/xtfpga/include/platform/serial.h | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | /* | ||
| 2 | * arch/xtensa/platform/xtavnet/include/platform/serial.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, 2006 Tensilica Inc. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #ifndef __ASM_XTENSA_XTAVNET_SERIAL_H | ||
| 12 | #define __ASM_XTENSA_XTAVNET_SERIAL_H | ||
| 13 | |||
| 14 | #include <platform/hardware.h> | ||
| 15 | |||
| 16 | #define BASE_BAUD (*(long *)XTFPGA_CLKFRQ_VADDR / 16) | ||
| 17 | |||
| 18 | #endif /* __ASM_XTENSA_XTAVNET_SERIAL_H */ | ||
diff --git a/arch/xtensa/platforms/xtfpga/lcd.c b/arch/xtensa/platforms/xtfpga/lcd.c new file mode 100644 index 000000000000..2872301598df --- /dev/null +++ b/arch/xtensa/platforms/xtfpga/lcd.c | |||
| @@ -0,0 +1,76 @@ | |||
| 1 | /* | ||
| 2 | * Driver for the LCD display on the Tensilica LX60 Board. | ||
| 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, 2006 Tensilica Inc. | ||
| 9 | */ | ||
| 10 | |||
| 11 | /* | ||
| 12 | * | ||
| 13 | * FIXME: this code is from the examples from the LX60 user guide. | ||
| 14 | * | ||
| 15 | * The lcd_pause function does busy waiting, which is probably not | ||
| 16 | * great. Maybe the code could be changed to use kernel timers, or | ||
| 17 | * change the hardware to not need to wait. | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <linux/init.h> | ||
| 21 | #include <linux/io.h> | ||
| 22 | |||
| 23 | #include <platform/hardware.h> | ||
| 24 | #include <platform/lcd.h> | ||
| 25 | #include <linux/delay.h> | ||
| 26 | |||
| 27 | #define LCD_PAUSE_ITERATIONS 4000 | ||
| 28 | #define LCD_CLEAR 0x1 | ||
| 29 | #define LCD_DISPLAY_ON 0xc | ||
| 30 | |||
| 31 | /* 8bit and 2 lines display */ | ||
| 32 | #define LCD_DISPLAY_MODE8BIT 0x38 | ||
| 33 | #define LCD_DISPLAY_POS 0x80 | ||
| 34 | #define LCD_SHIFT_LEFT 0x18 | ||
| 35 | #define LCD_SHIFT_RIGHT 0x1c | ||
| 36 | |||
| 37 | static int __init lcd_init(void) | ||
| 38 | { | ||
| 39 | *LCD_INSTR_ADDR = LCD_DISPLAY_MODE8BIT; | ||
| 40 | mdelay(5); | ||
| 41 | *LCD_INSTR_ADDR = LCD_DISPLAY_MODE8BIT; | ||
| 42 | udelay(200); | ||
| 43 | *LCD_INSTR_ADDR = LCD_DISPLAY_MODE8BIT; | ||
| 44 | udelay(50); | ||
| 45 | *LCD_INSTR_ADDR = LCD_DISPLAY_ON; | ||
| 46 | udelay(50); | ||
| 47 | *LCD_INSTR_ADDR = LCD_CLEAR; | ||
| 48 | mdelay(10); | ||
| 49 | lcd_disp_at_pos("XTENSA LINUX", 0); | ||
| 50 | return 0; | ||
| 51 | } | ||
| 52 | |||
| 53 | void lcd_disp_at_pos(char *str, unsigned char pos) | ||
| 54 | { | ||
| 55 | *LCD_INSTR_ADDR = LCD_DISPLAY_POS | pos; | ||
| 56 | udelay(100); | ||
| 57 | while (*str != 0) { | ||
| 58 | *LCD_DATA_ADDR = *str; | ||
| 59 | udelay(200); | ||
| 60 | str++; | ||
| 61 | } | ||
| 62 | } | ||
| 63 | |||
| 64 | void lcd_shiftleft(void) | ||
| 65 | { | ||
| 66 | *LCD_INSTR_ADDR = LCD_SHIFT_LEFT; | ||
| 67 | udelay(50); | ||
| 68 | } | ||
| 69 | |||
| 70 | void lcd_shiftright(void) | ||
| 71 | { | ||
| 72 | *LCD_INSTR_ADDR = LCD_SHIFT_RIGHT; | ||
| 73 | udelay(50); | ||
| 74 | } | ||
| 75 | |||
| 76 | arch_initcall(lcd_init); | ||
diff --git a/arch/xtensa/platforms/xtfpga/setup.c b/arch/xtensa/platforms/xtfpga/setup.c new file mode 100644 index 000000000000..4b9951a4569d --- /dev/null +++ b/arch/xtensa/platforms/xtfpga/setup.c | |||
| @@ -0,0 +1,301 @@ | |||
| 1 | /* | ||
| 2 | * | ||
| 3 | * arch/xtensa/platform/xtavnet/setup.c | ||
| 4 | * | ||
| 5 | * ... | ||
| 6 | * | ||
| 7 | * Authors: Chris Zankel <chris@zankel.net> | ||
| 8 | * Joe Taylor <joe@tensilica.com> | ||
| 9 | * | ||
| 10 | * Copyright 2001 - 2006 Tensilica Inc. | ||
| 11 | * | ||
| 12 | * This program is free software; you can redistribute it and/or modify it | ||
| 13 | * under the terms of the GNU General Public License as published by the | ||
| 14 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 15 | * option) any later version. | ||
| 16 | * | ||
| 17 | */ | ||
| 18 | #include <linux/stddef.h> | ||
| 19 | #include <linux/kernel.h> | ||
| 20 | #include <linux/init.h> | ||
| 21 | #include <linux/errno.h> | ||
| 22 | #include <linux/reboot.h> | ||
| 23 | #include <linux/kdev_t.h> | ||
| 24 | #include <linux/types.h> | ||
| 25 | #include <linux/major.h> | ||
| 26 | #include <linux/console.h> | ||
| 27 | #include <linux/delay.h> | ||
| 28 | #include <linux/of.h> | ||
| 29 | |||
| 30 | #include <asm/timex.h> | ||
| 31 | #include <asm/processor.h> | ||
| 32 | #include <asm/platform.h> | ||
| 33 | #include <asm/bootparam.h> | ||
| 34 | #include <platform/lcd.h> | ||
| 35 | #include <platform/hardware.h> | ||
| 36 | |||
| 37 | void platform_halt(void) | ||
| 38 | { | ||
| 39 | lcd_disp_at_pos(" HALT ", 0); | ||
| 40 | local_irq_disable(); | ||
| 41 | while (1) | ||
| 42 | cpu_relax(); | ||
| 43 | } | ||
| 44 | |||
| 45 | void platform_power_off(void) | ||
| 46 | { | ||
| 47 | lcd_disp_at_pos("POWEROFF", 0); | ||
| 48 | local_irq_disable(); | ||
| 49 | while (1) | ||
| 50 | cpu_relax(); | ||
| 51 | } | ||
| 52 | |||
| 53 | void platform_restart(void) | ||
| 54 | { | ||
| 55 | /* Flush and reset the mmu, simulate a processor reset, and | ||
| 56 | * jump to the reset vector. */ | ||
| 57 | |||
| 58 | |||
| 59 | __asm__ __volatile__ ("movi a2, 15\n\t" | ||
| 60 | "wsr a2, icountlevel\n\t" | ||
| 61 | "movi a2, 0\n\t" | ||
| 62 | "wsr a2, icount\n\t" | ||
| 63 | "wsr a2, ibreakenable\n\t" | ||
| 64 | "wsr a2, lcount\n\t" | ||
| 65 | "movi a2, 0x1f\n\t" | ||
| 66 | "wsr a2, ps\n\t" | ||
| 67 | "isync\n\t" | ||
| 68 | "jx %0\n\t" | ||
| 69 | : | ||
| 70 | : "a" (XCHAL_RESET_VECTOR_VADDR) | ||
| 71 | : "a2" | ||
| 72 | ); | ||
| 73 | |||
| 74 | /* control never gets here */ | ||
| 75 | } | ||
| 76 | |||
| 77 | void __init platform_setup(char **cmdline) | ||
| 78 | { | ||
| 79 | } | ||
| 80 | |||
| 81 | #ifdef CONFIG_OF | ||
| 82 | |||
| 83 | static void __init update_clock_frequency(struct device_node *node) | ||
| 84 | { | ||
| 85 | struct property *newfreq; | ||
| 86 | u32 freq; | ||
| 87 | |||
| 88 | if (!of_property_read_u32(node, "clock-frequency", &freq) && freq != 0) | ||
| 89 | return; | ||
| 90 | |||
| 91 | newfreq = kzalloc(sizeof(*newfreq) + sizeof(u32), GFP_KERNEL); | ||
| 92 | if (!newfreq) | ||
| 93 | return; | ||
| 94 | newfreq->value = newfreq + 1; | ||
| 95 | newfreq->length = sizeof(freq); | ||
| 96 | newfreq->name = kstrdup("clock-frequency", GFP_KERNEL); | ||
| 97 | if (!newfreq->name) { | ||
| 98 | kfree(newfreq); | ||
| 99 | return; | ||
| 100 | } | ||
| 101 | |||
| 102 | *(u32 *)newfreq->value = cpu_to_be32(*(u32 *)XTFPGA_CLKFRQ_VADDR); | ||
| 103 | prom_update_property(node, newfreq); | ||
| 104 | } | ||
| 105 | |||
| 106 | #define MAC_LEN 6 | ||
| 107 | static void __init update_local_mac(struct device_node *node) | ||
| 108 | { | ||
| 109 | struct property *newmac; | ||
| 110 | const u8* macaddr; | ||
| 111 | int prop_len; | ||
| 112 | |||
| 113 | macaddr = of_get_property(node, "local-mac-address", &prop_len); | ||
| 114 | if (macaddr == NULL || prop_len != MAC_LEN) | ||
| 115 | return; | ||
| 116 | |||
| 117 | newmac = kzalloc(sizeof(*newmac) + MAC_LEN, GFP_KERNEL); | ||
| 118 | if (newmac == NULL) | ||
| 119 | return; | ||
| 120 | |||
| 121 | newmac->value = newmac + 1; | ||
| 122 | newmac->length = MAC_LEN; | ||
| 123 | newmac->name = kstrdup("local-mac-address", GFP_KERNEL); | ||
| 124 | if (newmac->name == NULL) { | ||
| 125 | kfree(newmac); | ||
| 126 | return; | ||
| 127 | } | ||
| 128 | |||
| 129 | memcpy(newmac->value, macaddr, MAC_LEN); | ||
| 130 | ((u8*)newmac->value)[5] = (*(u32*)DIP_SWITCHES_VADDR) & 0x3f; | ||
| 131 | prom_update_property(node, newmac); | ||
| 132 | } | ||
| 133 | |||
| 134 | static int __init machine_setup(void) | ||
| 135 | { | ||
| 136 | struct device_node *serial; | ||
| 137 | struct device_node *eth = NULL; | ||
| 138 | |||
| 139 | for_each_compatible_node(serial, NULL, "ns16550a") | ||
| 140 | update_clock_frequency(serial); | ||
| 141 | |||
| 142 | if ((eth = of_find_compatible_node(eth, NULL, "opencores,ethoc"))) | ||
| 143 | update_local_mac(eth); | ||
| 144 | return 0; | ||
| 145 | } | ||
| 146 | arch_initcall(machine_setup); | ||
| 147 | |||
| 148 | #endif | ||
| 149 | |||
| 150 | /* early initialization */ | ||
| 151 | |||
| 152 | void __init platform_init(bp_tag_t *first) | ||
| 153 | { | ||
| 154 | } | ||
| 155 | |||
| 156 | /* Heartbeat. */ | ||
| 157 | |||
| 158 | void platform_heartbeat(void) | ||
| 159 | { | ||
| 160 | } | ||
| 161 | |||
| 162 | #ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT | ||
| 163 | |||
| 164 | void platform_calibrate_ccount(void) | ||
| 165 | { | ||
| 166 | long clk_freq = 0; | ||
| 167 | #ifdef CONFIG_OF | ||
| 168 | struct device_node *cpu = | ||
| 169 | of_find_compatible_node(NULL, NULL, "xtensa,cpu"); | ||
| 170 | if (cpu) { | ||
| 171 | u32 freq; | ||
| 172 | update_clock_frequency(cpu); | ||
| 173 | if (!of_property_read_u32(cpu, "clock-frequency", &freq)) | ||
| 174 | clk_freq = freq; | ||
| 175 | } | ||
| 176 | #endif | ||
| 177 | if (!clk_freq) | ||
| 178 | clk_freq = *(long *)XTFPGA_CLKFRQ_VADDR; | ||
| 179 | |||
| 180 | ccount_per_jiffy = clk_freq / HZ; | ||
| 181 | nsec_per_ccount = 1000000000UL / clk_freq; | ||
| 182 | } | ||
| 183 | |||
| 184 | #endif | ||
| 185 | |||
| 186 | #ifndef CONFIG_OF | ||
| 187 | |||
| 188 | #include <linux/serial_8250.h> | ||
| 189 | #include <linux/if.h> | ||
| 190 | #include <net/ethoc.h> | ||
| 191 | |||
| 192 | /*---------------------------------------------------------------------------- | ||
| 193 | * Ethernet -- OpenCores Ethernet MAC (ethoc driver) | ||
| 194 | */ | ||
| 195 | |||
| 196 | static struct resource ethoc_res[] __initdata = { | ||
| 197 | [0] = { /* register space */ | ||
| 198 | .start = OETH_REGS_PADDR, | ||
| 199 | .end = OETH_REGS_PADDR + OETH_REGS_SIZE - 1, | ||
| 200 | .flags = IORESOURCE_MEM, | ||
| 201 | }, | ||
| 202 | [1] = { /* buffer space */ | ||
| 203 | .start = OETH_SRAMBUFF_PADDR, | ||
| 204 | .end = OETH_SRAMBUFF_PADDR + OETH_SRAMBUFF_SIZE - 1, | ||
| 205 | .flags = IORESOURCE_MEM, | ||
| 206 | }, | ||
| 207 | [2] = { /* IRQ number */ | ||
| 208 | .start = OETH_IRQ, | ||
| 209 | .end = OETH_IRQ, | ||
| 210 | .flags = IORESOURCE_IRQ, | ||
| 211 | }, | ||
| 212 | }; | ||
| 213 | |||
| 214 | static struct ethoc_platform_data ethoc_pdata __initdata = { | ||
| 215 | /* | ||
| 216 | * The MAC address for these boards is 00:50:c2:13:6f:xx. | ||
| 217 | * The last byte (here as zero) is read from the DIP switches on the | ||
| 218 | * board. | ||
| 219 | */ | ||
| 220 | .hwaddr = { 0x00, 0x50, 0xc2, 0x13, 0x6f, 0 }, | ||
| 221 | .phy_id = -1, | ||
| 222 | }; | ||
| 223 | |||
| 224 | static struct platform_device ethoc_device __initdata = { | ||
| 225 | .name = "ethoc", | ||
| 226 | .id = -1, | ||
| 227 | .num_resources = ARRAY_SIZE(ethoc_res), | ||
| 228 | .resource = ethoc_res, | ||
| 229 | .dev = { | ||
| 230 | .platform_data = ðoc_pdata, | ||
| 231 | }, | ||
| 232 | }; | ||
| 233 | |||
| 234 | /*---------------------------------------------------------------------------- | ||
| 235 | * UART | ||
| 236 | */ | ||
| 237 | |||
| 238 | static struct resource serial_resource __initdata = { | ||
| 239 | .start = DUART16552_PADDR, | ||
| 240 | .end = DUART16552_PADDR + 0x1f, | ||
| 241 | .flags = IORESOURCE_MEM, | ||
| 242 | }; | ||
| 243 | |||
| 244 | static struct plat_serial8250_port serial_platform_data[] __initdata = { | ||
| 245 | [0] = { | ||
| 246 | .mapbase = DUART16552_PADDR, | ||
| 247 | .irq = DUART16552_INTNUM, | ||
| 248 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | | ||
| 249 | UPF_IOREMAP, | ||
| 250 | .iotype = UPIO_MEM32, | ||
| 251 | .regshift = 2, | ||
| 252 | .uartclk = 0, /* set in xtavnet_init() */ | ||
| 253 | }, | ||
| 254 | { }, | ||
| 255 | }; | ||
| 256 | |||
| 257 | static struct platform_device xtavnet_uart __initdata = { | ||
| 258 | .name = "serial8250", | ||
| 259 | .id = PLAT8250_DEV_PLATFORM, | ||
| 260 | .dev = { | ||
| 261 | .platform_data = serial_platform_data, | ||
| 262 | }, | ||
| 263 | .num_resources = 1, | ||
| 264 | .resource = &serial_resource, | ||
| 265 | }; | ||
| 266 | |||
| 267 | /* platform devices */ | ||
| 268 | static struct platform_device *platform_devices[] __initdata = { | ||
| 269 | ðoc_device, | ||
| 270 | &xtavnet_uart, | ||
| 271 | }; | ||
| 272 | |||
| 273 | |||
| 274 | static int __init xtavnet_init(void) | ||
| 275 | { | ||
| 276 | /* Ethernet MAC address. */ | ||
| 277 | ethoc_pdata.hwaddr[5] = *(u32 *)DIP_SWITCHES_VADDR; | ||
| 278 | |||
| 279 | /* Clock rate varies among FPGA bitstreams; board specific FPGA register | ||
| 280 | * reports the actual clock rate. | ||
| 281 | */ | ||
| 282 | serial_platform_data[0].uartclk = *(long *)XTFPGA_CLKFRQ_VADDR; | ||
| 283 | |||
| 284 | |||
| 285 | /* register platform devices */ | ||
| 286 | platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); | ||
| 287 | |||
| 288 | /* ETHOC driver is a bit quiet; at least display Ethernet MAC, so user | ||
| 289 | * knows whether they set it correctly on the DIP switches. | ||
| 290 | */ | ||
| 291 | pr_info("XTFPGA: Ethernet MAC %pM\n", ethoc_pdata.hwaddr); | ||
| 292 | |||
| 293 | return 0; | ||
| 294 | } | ||
| 295 | |||
| 296 | /* | ||
| 297 | * Register to be done during do_initcalls(). | ||
| 298 | */ | ||
| 299 | arch_initcall(xtavnet_init); | ||
| 300 | |||
| 301 | #endif /* CONFIG_OF */ | ||
diff --git a/arch/xtensa/variants/s6000/gpio.c b/arch/xtensa/variants/s6000/gpio.c index b89541ba39ab..da9e85c13b08 100644 --- a/arch/xtensa/variants/s6000/gpio.c +++ b/arch/xtensa/variants/s6000/gpio.c | |||
| @@ -164,7 +164,7 @@ static void demux_irqs(unsigned int irq, struct irq_desc *desc) | |||
| 164 | int cirq; | 164 | int cirq; |
| 165 | 165 | ||
| 166 | chip->irq_mask(&desc->irq_data); | 166 | chip->irq_mask(&desc->irq_data); |
| 167 | chip->irq_ack(&desc->irq_data)); | 167 | chip->irq_ack(&desc->irq_data); |
| 168 | pending = readb(S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_MIS) & *mask; | 168 | pending = readb(S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_MIS) & *mask; |
| 169 | cirq = IRQ_BASE - 1; | 169 | cirq = IRQ_BASE - 1; |
| 170 | while (pending) { | 170 | while (pending) { |
| @@ -173,7 +173,7 @@ static void demux_irqs(unsigned int irq, struct irq_desc *desc) | |||
| 173 | pending >>= n; | 173 | pending >>= n; |
| 174 | generic_handle_irq(cirq); | 174 | generic_handle_irq(cirq); |
| 175 | } | 175 | } |
| 176 | chip->irq_unmask(&desc->irq_data)); | 176 | chip->irq_unmask(&desc->irq_data); |
| 177 | } | 177 | } |
| 178 | 178 | ||
| 179 | extern const signed char *platform_irq_mappings[XTENSA_NR_IRQS]; | 179 | extern const signed char *platform_irq_mappings[XTENSA_NR_IRQS]; |
