diff options
| author | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-08-09 09:09:29 -0400 |
|---|---|---|
| committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-08-09 09:09:29 -0400 |
| commit | 054d5c9238f3c577ad51195c3ee7803613f322cc (patch) | |
| tree | ff7d9f5c0e0ddf14230ba28f28ef69a2c0a0debf /arch/powerpc | |
| parent | 11e4afb49b7fa1fc8e1ffd850c1806dd86a08204 (diff) | |
| parent | 2192482ee5ce5d5d4a6cec0c351b2d3a744606eb (diff) | |
Merge branch 'devel-stable' into devel
Diffstat (limited to 'arch/powerpc')
169 files changed, 8064 insertions, 2587 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 2031a2846865..e2bf40a2ce5a 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
| @@ -120,6 +120,8 @@ config ARCH_NO_VIRT_TO_BUS | |||
| 120 | config PPC | 120 | config PPC |
| 121 | bool | 121 | bool |
| 122 | default y | 122 | default y |
| 123 | select OF | ||
| 124 | select OF_FLATTREE | ||
| 123 | select HAVE_FTRACE_MCOUNT_RECORD | 125 | select HAVE_FTRACE_MCOUNT_RECORD |
| 124 | select HAVE_DYNAMIC_FTRACE | 126 | select HAVE_DYNAMIC_FTRACE |
| 125 | select HAVE_FUNCTION_TRACER | 127 | select HAVE_FUNCTION_TRACER |
| @@ -141,6 +143,7 @@ config PPC | |||
| 141 | select GENERIC_ATOMIC64 if PPC32 | 143 | select GENERIC_ATOMIC64 if PPC32 |
| 142 | select HAVE_PERF_EVENTS | 144 | select HAVE_PERF_EVENTS |
| 143 | select HAVE_REGS_AND_STACK_ACCESS_API | 145 | select HAVE_REGS_AND_STACK_ACCESS_API |
| 146 | select HAVE_HW_BREAKPOINT if PERF_EVENTS && PPC_BOOK3S_64 | ||
| 144 | 147 | ||
| 145 | config EARLY_PRINTK | 148 | config EARLY_PRINTK |
| 146 | bool | 149 | bool |
| @@ -172,10 +175,6 @@ config ARCH_MAY_HAVE_PC_FDC | |||
| 172 | config PPC_OF | 175 | config PPC_OF |
| 173 | def_bool y | 176 | def_bool y |
| 174 | 177 | ||
| 175 | config OF | ||
| 176 | def_bool y | ||
| 177 | select OF_FLATTREE | ||
| 178 | |||
| 179 | config PPC_UDBG_16550 | 178 | config PPC_UDBG_16550 |
| 180 | bool | 179 | bool |
| 181 | default n | 180 | default n |
| @@ -198,10 +197,6 @@ config SYS_SUPPORTS_APM_EMULATION | |||
| 198 | default y if PMAC_APM_EMU | 197 | default y if PMAC_APM_EMU |
| 199 | bool | 198 | bool |
| 200 | 199 | ||
| 201 | config DTC | ||
| 202 | bool | ||
| 203 | default y | ||
| 204 | |||
| 205 | config DEFAULT_UIMAGE | 200 | config DEFAULT_UIMAGE |
| 206 | bool | 201 | bool |
| 207 | help | 202 | help |
| @@ -218,7 +213,7 @@ config ARCH_HIBERNATION_POSSIBLE | |||
| 218 | config ARCH_SUSPEND_POSSIBLE | 213 | config ARCH_SUSPEND_POSSIBLE |
| 219 | def_bool y | 214 | def_bool y |
| 220 | depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200 || PPC_83xx || \ | 215 | depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200 || PPC_83xx || \ |
| 221 | PPC_85xx || PPC_86xx | 216 | PPC_85xx || PPC_86xx || PPC_PSERIES |
| 222 | 217 | ||
| 223 | config PPC_DCR_NATIVE | 218 | config PPC_DCR_NATIVE |
| 224 | bool | 219 | bool |
| @@ -351,7 +346,7 @@ config ARCH_ENABLE_MEMORY_HOTREMOVE | |||
| 351 | 346 | ||
| 352 | config KEXEC | 347 | config KEXEC |
| 353 | bool "kexec system call (EXPERIMENTAL)" | 348 | bool "kexec system call (EXPERIMENTAL)" |
| 354 | depends on (PPC_BOOK3S || (FSL_BOOKE && !SMP)) && EXPERIMENTAL | 349 | depends on (PPC_BOOK3S || FSL_BOOKE) && EXPERIMENTAL |
| 355 | help | 350 | help |
| 356 | kexec is a system call that implements the ability to shutdown your | 351 | kexec is a system call that implements the ability to shutdown your |
| 357 | current kernel, and to start another kernel. It is like a reboot | 352 | current kernel, and to start another kernel. It is like a reboot |
| @@ -368,8 +363,8 @@ config KEXEC | |||
| 368 | 363 | ||
| 369 | config CRASH_DUMP | 364 | config CRASH_DUMP |
| 370 | bool "Build a kdump crash kernel" | 365 | bool "Build a kdump crash kernel" |
| 371 | depends on PPC64 || 6xx | 366 | depends on PPC64 || 6xx || FSL_BOOKE |
| 372 | select RELOCATABLE if PPC64 | 367 | select RELOCATABLE if PPC64 || FSL_BOOKE |
| 373 | help | 368 | help |
| 374 | Build a kernel suitable for use as a kdump capture kernel. | 369 | Build a kernel suitable for use as a kdump capture kernel. |
| 375 | The same kernel binary can be used as production kernel and dump | 370 | The same kernel binary can be used as production kernel and dump |
| @@ -578,14 +573,6 @@ config SCHED_SMT | |||
| 578 | when dealing with POWER5 cpus at a cost of slightly increased | 573 | when dealing with POWER5 cpus at a cost of slightly increased |
| 579 | overhead in some places. If unsure say N here. | 574 | overhead in some places. If unsure say N here. |
| 580 | 575 | ||
| 581 | config PROC_DEVICETREE | ||
| 582 | bool "Support for device tree in /proc" | ||
| 583 | depends on PROC_FS | ||
| 584 | help | ||
| 585 | This option adds a device-tree directory under /proc which contains | ||
| 586 | an image of the device tree that the kernel copies from Open | ||
| 587 | Firmware or other boot firmware. If unsure, say Y here. | ||
| 588 | |||
| 589 | config CMDLINE_BOOL | 576 | config CMDLINE_BOOL |
| 590 | bool "Default bootloader kernel arguments" | 577 | bool "Default bootloader kernel arguments" |
| 591 | 578 | ||
| @@ -668,7 +655,7 @@ config NEED_SG_DMA_LENGTH | |||
| 668 | 655 | ||
| 669 | config GENERIC_ISA_DMA | 656 | config GENERIC_ISA_DMA |
| 670 | bool | 657 | bool |
| 671 | depends on PPC64 || POWER4 || 6xx && !CPM2 | 658 | depends on ISA_DMA_API |
| 672 | default y | 659 | default y |
| 673 | 660 | ||
| 674 | config PPC_INDIRECT_PCI | 661 | config PPC_INDIRECT_PCI |
| @@ -897,7 +884,7 @@ config KERNEL_START_BOOL | |||
| 897 | config KERNEL_START | 884 | config KERNEL_START |
| 898 | hex "Virtual address of kernel base" if KERNEL_START_BOOL | 885 | hex "Virtual address of kernel base" if KERNEL_START_BOOL |
| 899 | default PAGE_OFFSET if PAGE_OFFSET_BOOL | 886 | default PAGE_OFFSET if PAGE_OFFSET_BOOL |
| 900 | default "0xc2000000" if CRASH_DUMP | 887 | default "0xc2000000" if CRASH_DUMP && !RELOCATABLE |
| 901 | default "0xc0000000" | 888 | default "0xc0000000" |
| 902 | 889 | ||
| 903 | config PHYSICAL_START_BOOL | 890 | config PHYSICAL_START_BOOL |
| @@ -910,7 +897,7 @@ config PHYSICAL_START_BOOL | |||
| 910 | 897 | ||
| 911 | config PHYSICAL_START | 898 | config PHYSICAL_START |
| 912 | hex "Physical address where the kernel is loaded" if PHYSICAL_START_BOOL | 899 | hex "Physical address where the kernel is loaded" if PHYSICAL_START_BOOL |
| 913 | default "0x02000000" if PPC_STD_MMU && CRASH_DUMP | 900 | default "0x02000000" if PPC_STD_MMU && CRASH_DUMP && !RELOCATABLE |
| 914 | default "0x00000000" | 901 | default "0x00000000" |
| 915 | 902 | ||
| 916 | config PHYSICAL_ALIGN | 903 | config PHYSICAL_ALIGN |
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 77cfe7a29e25..5d42f5eae70f 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile | |||
| @@ -94,7 +94,7 @@ else | |||
| 94 | endif | 94 | endif |
| 95 | endif | 95 | endif |
| 96 | 96 | ||
| 97 | LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o | 97 | KBUILD_LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o |
| 98 | 98 | ||
| 99 | ifeq ($(CONFIG_TUNE_CELL),y) | 99 | ifeq ($(CONFIG_TUNE_CELL),y) |
| 100 | KBUILD_CFLAGS += $(call cc-option,-mtune=cell) | 100 | KBUILD_CFLAGS += $(call cc-option,-mtune=cell) |
diff --git a/arch/powerpc/boot/dts/canyonlands.dts b/arch/powerpc/boot/dts/canyonlands.dts index cd56bb5b347b..5806ef0b860b 100644 --- a/arch/powerpc/boot/dts/canyonlands.dts +++ b/arch/powerpc/boot/dts/canyonlands.dts | |||
| @@ -270,7 +270,7 @@ | |||
| 270 | clock-frequency = <0>; /* Filled in by U-Boot */ | 270 | clock-frequency = <0>; /* Filled in by U-Boot */ |
| 271 | current-speed = <0>; /* Filled in by U-Boot */ | 271 | current-speed = <0>; /* Filled in by U-Boot */ |
| 272 | interrupt-parent = <&UIC1>; | 272 | interrupt-parent = <&UIC1>; |
| 273 | interrupts = <0x1d 0x4>; | 273 | interrupts = <28 0x4>; |
| 274 | }; | 274 | }; |
| 275 | 275 | ||
| 276 | UART3: serial@ef600600 { | 276 | UART3: serial@ef600600 { |
| @@ -281,7 +281,7 @@ | |||
| 281 | clock-frequency = <0>; /* Filled in by U-Boot */ | 281 | clock-frequency = <0>; /* Filled in by U-Boot */ |
| 282 | current-speed = <0>; /* Filled in by U-Boot */ | 282 | current-speed = <0>; /* Filled in by U-Boot */ |
| 283 | interrupt-parent = <&UIC1>; | 283 | interrupt-parent = <&UIC1>; |
| 284 | interrupts = <0x1e 0x4>; | 284 | interrupts = <29 0x4>; |
| 285 | }; | 285 | }; |
| 286 | 286 | ||
| 287 | IIC0: i2c@ef600700 { | 287 | IIC0: i2c@ef600700 { |
diff --git a/arch/powerpc/boot/dts/glacier.dts b/arch/powerpc/boot/dts/glacier.dts index d62a4fb6f93c..e618fc4cbc9e 100644 --- a/arch/powerpc/boot/dts/glacier.dts +++ b/arch/powerpc/boot/dts/glacier.dts | |||
| @@ -259,7 +259,7 @@ | |||
| 259 | clock-frequency = <0>; /* Filled in by U-Boot */ | 259 | clock-frequency = <0>; /* Filled in by U-Boot */ |
| 260 | current-speed = <0>; /* Filled in by U-Boot */ | 260 | current-speed = <0>; /* Filled in by U-Boot */ |
| 261 | interrupt-parent = <&UIC1>; | 261 | interrupt-parent = <&UIC1>; |
| 262 | interrupts = <0x1d 0x4>; | 262 | interrupts = <28 0x4>; |
| 263 | }; | 263 | }; |
| 264 | 264 | ||
| 265 | UART3: serial@ef600600 { | 265 | UART3: serial@ef600600 { |
| @@ -270,7 +270,7 @@ | |||
| 270 | clock-frequency = <0>; /* Filled in by U-Boot */ | 270 | clock-frequency = <0>; /* Filled in by U-Boot */ |
| 271 | current-speed = <0>; /* Filled in by U-Boot */ | 271 | current-speed = <0>; /* Filled in by U-Boot */ |
| 272 | interrupt-parent = <&UIC1>; | 272 | interrupt-parent = <&UIC1>; |
| 273 | interrupts = <0x1e 0x4>; | 273 | interrupts = <29 0x4>; |
| 274 | }; | 274 | }; |
| 275 | 275 | ||
| 276 | IIC0: i2c@ef600700 { | 276 | IIC0: i2c@ef600700 { |
diff --git a/arch/powerpc/boot/dts/mpc8308rdb.dts b/arch/powerpc/boot/dts/mpc8308rdb.dts new file mode 100644 index 000000000000..a97eb2db5a18 --- /dev/null +++ b/arch/powerpc/boot/dts/mpc8308rdb.dts | |||
| @@ -0,0 +1,303 @@ | |||
| 1 | /* | ||
| 2 | * MPC8308RDB Device Tree Source | ||
| 3 | * | ||
| 4 | * Copyright 2009 Freescale Semiconductor Inc. | ||
| 5 | * Copyright 2010 Ilya Yanok, Emcraft Systems, yanok@emcraft.com | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify it | ||
| 8 | * under the terms of the GNU General Public License as published by the | ||
| 9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 10 | * option) any later version. | ||
| 11 | */ | ||
| 12 | |||
| 13 | /dts-v1/; | ||
| 14 | |||
| 15 | / { | ||
| 16 | compatible = "fsl,mpc8308rdb"; | ||
| 17 | #address-cells = <1>; | ||
| 18 | #size-cells = <1>; | ||
| 19 | |||
| 20 | aliases { | ||
| 21 | ethernet0 = &enet0; | ||
| 22 | ethernet1 = &enet1; | ||
| 23 | serial0 = &serial0; | ||
| 24 | serial1 = &serial1; | ||
| 25 | pci0 = &pci0; | ||
| 26 | }; | ||
| 27 | |||
| 28 | cpus { | ||
| 29 | #address-cells = <1>; | ||
| 30 | #size-cells = <0>; | ||
| 31 | |||
| 32 | PowerPC,8308@0 { | ||
| 33 | device_type = "cpu"; | ||
| 34 | reg = <0x0>; | ||
| 35 | d-cache-line-size = <32>; | ||
| 36 | i-cache-line-size = <32>; | ||
| 37 | d-cache-size = <16384>; | ||
| 38 | i-cache-size = <16384>; | ||
| 39 | timebase-frequency = <0>; // from bootloader | ||
| 40 | bus-frequency = <0>; // from bootloader | ||
| 41 | clock-frequency = <0>; // from bootloader | ||
| 42 | }; | ||
| 43 | }; | ||
| 44 | |||
| 45 | memory { | ||
| 46 | device_type = "memory"; | ||
| 47 | reg = <0x00000000 0x08000000>; // 128MB at 0 | ||
| 48 | }; | ||
| 49 | |||
| 50 | localbus@e0005000 { | ||
| 51 | #address-cells = <2>; | ||
| 52 | #size-cells = <1>; | ||
| 53 | compatible = "fsl,mpc8315-elbc", "fsl,elbc", "simple-bus"; | ||
| 54 | reg = <0xe0005000 0x1000>; | ||
| 55 | interrupts = <77 0x8>; | ||
| 56 | interrupt-parent = <&ipic>; | ||
| 57 | |||
| 58 | // CS0 and CS1 are swapped when | ||
| 59 | // booting from nand, but the | ||
| 60 | // addresses are the same. | ||
| 61 | ranges = <0x0 0x0 0xfe000000 0x00800000 | ||
| 62 | 0x1 0x0 0xe0600000 0x00002000 | ||
| 63 | 0x2 0x0 0xf0000000 0x00020000 | ||
| 64 | 0x3 0x0 0xfa000000 0x00008000>; | ||
| 65 | |||
| 66 | flash@0,0 { | ||
| 67 | #address-cells = <1>; | ||
| 68 | #size-cells = <1>; | ||
| 69 | compatible = "cfi-flash"; | ||
| 70 | reg = <0x0 0x0 0x800000>; | ||
| 71 | bank-width = <2>; | ||
| 72 | device-width = <1>; | ||
| 73 | |||
| 74 | u-boot@0 { | ||
| 75 | reg = <0x0 0x60000>; | ||
| 76 | read-only; | ||
| 77 | }; | ||
| 78 | env@60000 { | ||
| 79 | reg = <0x60000 0x10000>; | ||
| 80 | }; | ||
| 81 | env1@70000 { | ||
| 82 | reg = <0x70000 0x10000>; | ||
| 83 | }; | ||
| 84 | kernel@80000 { | ||
| 85 | reg = <0x80000 0x200000>; | ||
| 86 | }; | ||
| 87 | dtb@280000 { | ||
| 88 | reg = <0x280000 0x10000>; | ||
| 89 | }; | ||
| 90 | ramdisk@290000 { | ||
| 91 | reg = <0x290000 0x570000>; | ||
| 92 | }; | ||
| 93 | }; | ||
| 94 | |||
| 95 | nand@1,0 { | ||
| 96 | #address-cells = <1>; | ||
| 97 | #size-cells = <1>; | ||
| 98 | compatible = "fsl,mpc8315-fcm-nand", | ||
| 99 | "fsl,elbc-fcm-nand"; | ||
| 100 | reg = <0x1 0x0 0x2000>; | ||
| 101 | |||
| 102 | jffs2@0 { | ||
| 103 | reg = <0x0 0x2000000>; | ||
| 104 | }; | ||
| 105 | }; | ||
| 106 | }; | ||
| 107 | |||
| 108 | immr@e0000000 { | ||
| 109 | #address-cells = <1>; | ||
| 110 | #size-cells = <1>; | ||
| 111 | device_type = "soc"; | ||
| 112 | compatible = "fsl,mpc8315-immr", "simple-bus"; | ||
| 113 | ranges = <0 0xe0000000 0x00100000>; | ||
| 114 | reg = <0xe0000000 0x00000200>; | ||
| 115 | bus-frequency = <0>; | ||
| 116 | |||
| 117 | i2c@3000 { | ||
| 118 | #address-cells = <1>; | ||
| 119 | #size-cells = <0>; | ||
| 120 | cell-index = <0>; | ||
| 121 | compatible = "fsl-i2c"; | ||
| 122 | reg = <0x3000 0x100>; | ||
| 123 | interrupts = <14 0x8>; | ||
| 124 | interrupt-parent = <&ipic>; | ||
| 125 | dfsrr; | ||
| 126 | rtc@68 { | ||
| 127 | compatible = "dallas,ds1339"; | ||
| 128 | reg = <0x68>; | ||
| 129 | }; | ||
| 130 | }; | ||
| 131 | |||
| 132 | usb@23000 { | ||
| 133 | compatible = "fsl-usb2-dr"; | ||
| 134 | reg = <0x23000 0x1000>; | ||
| 135 | #address-cells = <1>; | ||
| 136 | #size-cells = <0>; | ||
| 137 | interrupt-parent = <&ipic>; | ||
| 138 | interrupts = <38 0x8>; | ||
| 139 | dr_mode = "peripheral"; | ||
| 140 | phy_type = "ulpi"; | ||
| 141 | }; | ||
| 142 | |||
| 143 | enet0: ethernet@24000 { | ||
| 144 | #address-cells = <1>; | ||
| 145 | #size-cells = <1>; | ||
| 146 | ranges = <0x0 0x24000 0x1000>; | ||
| 147 | |||
| 148 | cell-index = <0>; | ||
| 149 | device_type = "network"; | ||
| 150 | model = "eTSEC"; | ||
| 151 | compatible = "gianfar"; | ||
| 152 | reg = <0x24000 0x1000>; | ||
| 153 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 154 | interrupts = <32 0x8 33 0x8 34 0x8>; | ||
| 155 | interrupt-parent = <&ipic>; | ||
| 156 | tbi-handle = < &tbi0 >; | ||
| 157 | phy-handle = < &phy2 >; | ||
| 158 | fsl,magic-packet; | ||
| 159 | |||
| 160 | mdio@520 { | ||
| 161 | #address-cells = <1>; | ||
| 162 | #size-cells = <0>; | ||
| 163 | compatible = "fsl,gianfar-mdio"; | ||
| 164 | reg = <0x520 0x20>; | ||
| 165 | phy2: ethernet-phy@2 { | ||
| 166 | interrupt-parent = <&ipic>; | ||
| 167 | interrupts = <17 0x8>; | ||
| 168 | reg = <0x2>; | ||
| 169 | device_type = "ethernet-phy"; | ||
| 170 | }; | ||
| 171 | tbi0: tbi-phy@11 { | ||
| 172 | reg = <0x11>; | ||
| 173 | device_type = "tbi-phy"; | ||
| 174 | }; | ||
| 175 | }; | ||
| 176 | }; | ||
| 177 | |||
| 178 | enet1: ethernet@25000 { | ||
| 179 | #address-cells = <1>; | ||
| 180 | #size-cells = <1>; | ||
| 181 | cell-index = <1>; | ||
| 182 | device_type = "network"; | ||
| 183 | model = "eTSEC"; | ||
| 184 | compatible = "gianfar"; | ||
| 185 | reg = <0x25000 0x1000>; | ||
| 186 | ranges = <0x0 0x25000 0x1000>; | ||
| 187 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 188 | interrupts = <35 0x8 36 0x8 37 0x8>; | ||
| 189 | interrupt-parent = <&ipic>; | ||
| 190 | tbi-handle = < &tbi1 >; | ||
| 191 | /* Vitesse 7385 isn't on the MDIO bus */ | ||
| 192 | fixed-link = <1 1 1000 0 0>; | ||
| 193 | fsl,magic-packet; | ||
| 194 | |||
| 195 | mdio@520 { | ||
| 196 | #address-cells = <1>; | ||
| 197 | #size-cells = <0>; | ||
| 198 | compatible = "fsl,gianfar-tbi"; | ||
| 199 | reg = <0x520 0x20>; | ||
| 200 | |||
| 201 | tbi1: tbi-phy@11 { | ||
| 202 | reg = <0x11>; | ||
| 203 | device_type = "tbi-phy"; | ||
| 204 | }; | ||
| 205 | }; | ||
| 206 | }; | ||
| 207 | |||
| 208 | serial0: serial@4500 { | ||
| 209 | cell-index = <0>; | ||
| 210 | device_type = "serial"; | ||
| 211 | compatible = "ns16550"; | ||
| 212 | reg = <0x4500 0x100>; | ||
| 213 | clock-frequency = <133333333>; | ||
| 214 | interrupts = <9 0x8>; | ||
| 215 | interrupt-parent = <&ipic>; | ||
| 216 | }; | ||
| 217 | |||
| 218 | serial1: serial@4600 { | ||
| 219 | cell-index = <1>; | ||
| 220 | device_type = "serial"; | ||
| 221 | compatible = "ns16550"; | ||
| 222 | reg = <0x4600 0x100>; | ||
| 223 | clock-frequency = <133333333>; | ||
| 224 | interrupts = <10 0x8>; | ||
| 225 | interrupt-parent = <&ipic>; | ||
| 226 | }; | ||
| 227 | |||
| 228 | gpio@c00 { | ||
| 229 | #gpio-cells = <2>; | ||
| 230 | device_type = "gpio"; | ||
| 231 | compatible = "fsl,mpc8308-gpio", "fsl,mpc8349-gpio"; | ||
| 232 | reg = <0xc00 0x18>; | ||
| 233 | interrupts = <74 0x8>; | ||
| 234 | interrupt-parent = <&ipic>; | ||
| 235 | gpio-controller; | ||
| 236 | }; | ||
| 237 | |||
| 238 | /* IPIC | ||
| 239 | * interrupts cell = <intr #, sense> | ||
| 240 | * sense values match linux IORESOURCE_IRQ_* defines: | ||
| 241 | * sense == 8: Level, low assertion | ||
| 242 | * sense == 2: Edge, high-to-low change | ||
| 243 | */ | ||
| 244 | ipic: interrupt-controller@700 { | ||
| 245 | compatible = "fsl,ipic"; | ||
| 246 | interrupt-controller; | ||
| 247 | #address-cells = <0>; | ||
| 248 | #interrupt-cells = <2>; | ||
| 249 | reg = <0x700 0x100>; | ||
| 250 | device_type = "ipic"; | ||
| 251 | }; | ||
| 252 | |||
| 253 | ipic-msi@7c0 { | ||
| 254 | compatible = "fsl,ipic-msi"; | ||
| 255 | reg = <0x7c0 0x40>; | ||
| 256 | msi-available-ranges = <0x0 0x100>; | ||
| 257 | interrupts = < 0x43 0x8 | ||
| 258 | 0x4 0x8 | ||
| 259 | 0x51 0x8 | ||
| 260 | 0x52 0x8 | ||
| 261 | 0x56 0x8 | ||
| 262 | 0x57 0x8 | ||
| 263 | 0x58 0x8 | ||
| 264 | 0x59 0x8 >; | ||
| 265 | interrupt-parent = < &ipic >; | ||
| 266 | }; | ||
| 267 | |||
| 268 | }; | ||
| 269 | |||
| 270 | pci0: pcie@e0009000 { | ||
| 271 | #address-cells = <3>; | ||
| 272 | #size-cells = <2>; | ||
| 273 | #interrupt-cells = <1>; | ||
| 274 | device_type = "pci"; | ||
| 275 | compatible = "fsl,mpc8308-pcie", "fsl,mpc8314-pcie"; | ||
| 276 | reg = <0xe0009000 0x00001000 | ||
| 277 | 0xb0000000 0x01000000>; | ||
| 278 | ranges = <0x02000000 0 0xa0000000 0xa0000000 0 0x10000000 | ||
| 279 | 0x01000000 0 0x00000000 0xb1000000 0 0x00800000>; | ||
| 280 | bus-range = <0 0>; | ||
| 281 | interrupt-map-mask = <0xf800 0 0 7>; | ||
| 282 | interrupt-map = <0 0 0 1 &ipic 1 8 | ||
| 283 | 0 0 0 2 &ipic 1 8 | ||
| 284 | 0 0 0 3 &ipic 1 8 | ||
| 285 | 0 0 0 4 &ipic 1 8>; | ||
| 286 | interrupts = <0x1 0x8>; | ||
| 287 | interrupt-parent = <&ipic>; | ||
| 288 | clock-frequency = <0>; | ||
| 289 | |||
| 290 | pcie@0 { | ||
| 291 | #address-cells = <3>; | ||
| 292 | #size-cells = <2>; | ||
| 293 | device_type = "pci"; | ||
| 294 | reg = <0 0 0 0 0>; | ||
| 295 | ranges = <0x02000000 0 0xa0000000 | ||
| 296 | 0x02000000 0 0xa0000000 | ||
| 297 | 0 0x10000000 | ||
| 298 | 0x01000000 0 0x00000000 | ||
| 299 | 0x01000000 0 0x00000000 | ||
| 300 | 0 0x00800000>; | ||
| 301 | }; | ||
| 302 | }; | ||
| 303 | }; | ||
diff --git a/arch/powerpc/boot/dts/mpc8540ads.dts b/arch/powerpc/boot/dts/mpc8540ads.dts index 9dc292962a9a..8d1bf0fd9268 100644 --- a/arch/powerpc/boot/dts/mpc8540ads.dts +++ b/arch/powerpc/boot/dts/mpc8540ads.dts | |||
| @@ -71,14 +71,14 @@ | |||
| 71 | }; | 71 | }; |
| 72 | 72 | ||
| 73 | memory-controller@2000 { | 73 | memory-controller@2000 { |
| 74 | compatible = "fsl,8540-memory-controller"; | 74 | compatible = "fsl,mpc8540-memory-controller"; |
| 75 | reg = <0x2000 0x1000>; | 75 | reg = <0x2000 0x1000>; |
| 76 | interrupt-parent = <&mpic>; | 76 | interrupt-parent = <&mpic>; |
| 77 | interrupts = <18 2>; | 77 | interrupts = <18 2>; |
| 78 | }; | 78 | }; |
| 79 | 79 | ||
| 80 | L2: l2-cache-controller@20000 { | 80 | L2: l2-cache-controller@20000 { |
| 81 | compatible = "fsl,8540-l2-cache-controller"; | 81 | compatible = "fsl,mpc8540-l2-cache-controller"; |
| 82 | reg = <0x20000 0x1000>; | 82 | reg = <0x20000 0x1000>; |
| 83 | cache-line-size = <32>; // 32 bytes | 83 | cache-line-size = <32>; // 32 bytes |
| 84 | cache-size = <0x40000>; // L2, 256K | 84 | cache-size = <0x40000>; // L2, 256K |
diff --git a/arch/powerpc/boot/dts/mpc8541cds.dts b/arch/powerpc/boot/dts/mpc8541cds.dts index 9a3ad311aedf..87ff96549fac 100644 --- a/arch/powerpc/boot/dts/mpc8541cds.dts +++ b/arch/powerpc/boot/dts/mpc8541cds.dts | |||
| @@ -71,14 +71,14 @@ | |||
| 71 | }; | 71 | }; |
| 72 | 72 | ||
| 73 | memory-controller@2000 { | 73 | memory-controller@2000 { |
| 74 | compatible = "fsl,8541-memory-controller"; | 74 | compatible = "fsl,mpc8541-memory-controller"; |
| 75 | reg = <0x2000 0x1000>; | 75 | reg = <0x2000 0x1000>; |
| 76 | interrupt-parent = <&mpic>; | 76 | interrupt-parent = <&mpic>; |
| 77 | interrupts = <18 2>; | 77 | interrupts = <18 2>; |
| 78 | }; | 78 | }; |
| 79 | 79 | ||
| 80 | L2: l2-cache-controller@20000 { | 80 | L2: l2-cache-controller@20000 { |
| 81 | compatible = "fsl,8541-l2-cache-controller"; | 81 | compatible = "fsl,mpc8541-l2-cache-controller"; |
| 82 | reg = <0x20000 0x1000>; | 82 | reg = <0x20000 0x1000>; |
| 83 | cache-line-size = <32>; // 32 bytes | 83 | cache-line-size = <32>; // 32 bytes |
| 84 | cache-size = <0x40000>; // L2, 256K | 84 | cache-size = <0x40000>; // L2, 256K |
diff --git a/arch/powerpc/boot/dts/mpc8544ds.dts b/arch/powerpc/boot/dts/mpc8544ds.dts index 98e94b465662..d793968743c9 100644 --- a/arch/powerpc/boot/dts/mpc8544ds.dts +++ b/arch/powerpc/boot/dts/mpc8544ds.dts | |||
| @@ -73,14 +73,14 @@ | |||
| 73 | }; | 73 | }; |
| 74 | 74 | ||
| 75 | memory-controller@2000 { | 75 | memory-controller@2000 { |
| 76 | compatible = "fsl,8544-memory-controller"; | 76 | compatible = "fsl,mpc8544-memory-controller"; |
| 77 | reg = <0x2000 0x1000>; | 77 | reg = <0x2000 0x1000>; |
| 78 | interrupt-parent = <&mpic>; | 78 | interrupt-parent = <&mpic>; |
| 79 | interrupts = <18 2>; | 79 | interrupts = <18 2>; |
| 80 | }; | 80 | }; |
| 81 | 81 | ||
| 82 | L2: l2-cache-controller@20000 { | 82 | L2: l2-cache-controller@20000 { |
| 83 | compatible = "fsl,8544-l2-cache-controller"; | 83 | compatible = "fsl,mpc8544-l2-cache-controller"; |
| 84 | reg = <0x20000 0x1000>; | 84 | reg = <0x20000 0x1000>; |
| 85 | cache-line-size = <32>; // 32 bytes | 85 | cache-line-size = <32>; // 32 bytes |
| 86 | cache-size = <0x40000>; // L2, 256K | 86 | cache-size = <0x40000>; // L2, 256K |
diff --git a/arch/powerpc/boot/dts/mpc8548cds.dts b/arch/powerpc/boot/dts/mpc8548cds.dts index 0f5262452682..a17a5572fb73 100644 --- a/arch/powerpc/boot/dts/mpc8548cds.dts +++ b/arch/powerpc/boot/dts/mpc8548cds.dts | |||
| @@ -74,14 +74,14 @@ | |||
| 74 | }; | 74 | }; |
| 75 | 75 | ||
| 76 | memory-controller@2000 { | 76 | memory-controller@2000 { |
| 77 | compatible = "fsl,8548-memory-controller"; | 77 | compatible = "fsl,mpc8548-memory-controller"; |
| 78 | reg = <0x2000 0x1000>; | 78 | reg = <0x2000 0x1000>; |
| 79 | interrupt-parent = <&mpic>; | 79 | interrupt-parent = <&mpic>; |
| 80 | interrupts = <18 2>; | 80 | interrupts = <18 2>; |
| 81 | }; | 81 | }; |
| 82 | 82 | ||
| 83 | L2: l2-cache-controller@20000 { | 83 | L2: l2-cache-controller@20000 { |
| 84 | compatible = "fsl,8548-l2-cache-controller"; | 84 | compatible = "fsl,mpc8548-l2-cache-controller"; |
| 85 | reg = <0x20000 0x1000>; | 85 | reg = <0x20000 0x1000>; |
| 86 | cache-line-size = <32>; // 32 bytes | 86 | cache-line-size = <32>; // 32 bytes |
| 87 | cache-size = <0x80000>; // L2, 512K | 87 | cache-size = <0x80000>; // L2, 512K |
diff --git a/arch/powerpc/boot/dts/mpc8555cds.dts b/arch/powerpc/boot/dts/mpc8555cds.dts index 065b2f093de2..5c5614f9eb17 100644 --- a/arch/powerpc/boot/dts/mpc8555cds.dts +++ b/arch/powerpc/boot/dts/mpc8555cds.dts | |||
| @@ -71,14 +71,14 @@ | |||
| 71 | }; | 71 | }; |
| 72 | 72 | ||
| 73 | memory-controller@2000 { | 73 | memory-controller@2000 { |
| 74 | compatible = "fsl,8555-memory-controller"; | 74 | compatible = "fsl,mpc8555-memory-controller"; |
| 75 | reg = <0x2000 0x1000>; | 75 | reg = <0x2000 0x1000>; |
| 76 | interrupt-parent = <&mpic>; | 76 | interrupt-parent = <&mpic>; |
| 77 | interrupts = <18 2>; | 77 | interrupts = <18 2>; |
| 78 | }; | 78 | }; |
| 79 | 79 | ||
| 80 | L2: l2-cache-controller@20000 { | 80 | L2: l2-cache-controller@20000 { |
| 81 | compatible = "fsl,8555-l2-cache-controller"; | 81 | compatible = "fsl,mpc8555-l2-cache-controller"; |
| 82 | reg = <0x20000 0x1000>; | 82 | reg = <0x20000 0x1000>; |
| 83 | cache-line-size = <32>; // 32 bytes | 83 | cache-line-size = <32>; // 32 bytes |
| 84 | cache-size = <0x40000>; // L2, 256K | 84 | cache-size = <0x40000>; // L2, 256K |
diff --git a/arch/powerpc/boot/dts/mpc8560ads.dts b/arch/powerpc/boot/dts/mpc8560ads.dts index a5bb1ec70a5a..6e85e1ba0851 100644 --- a/arch/powerpc/boot/dts/mpc8560ads.dts +++ b/arch/powerpc/boot/dts/mpc8560ads.dts | |||
| @@ -71,14 +71,14 @@ | |||
| 71 | }; | 71 | }; |
| 72 | 72 | ||
| 73 | memory-controller@2000 { | 73 | memory-controller@2000 { |
| 74 | compatible = "fsl,8540-memory-controller"; | 74 | compatible = "fsl,mpc8540-memory-controller"; |
| 75 | reg = <0x2000 0x1000>; | 75 | reg = <0x2000 0x1000>; |
| 76 | interrupt-parent = <&mpic>; | 76 | interrupt-parent = <&mpic>; |
| 77 | interrupts = <18 2>; | 77 | interrupts = <18 2>; |
| 78 | }; | 78 | }; |
| 79 | 79 | ||
| 80 | L2: l2-cache-controller@20000 { | 80 | L2: l2-cache-controller@20000 { |
| 81 | compatible = "fsl,8540-l2-cache-controller"; | 81 | compatible = "fsl,mpc8540-l2-cache-controller"; |
| 82 | reg = <0x20000 0x1000>; | 82 | reg = <0x20000 0x1000>; |
| 83 | cache-line-size = <32>; // 32 bytes | 83 | cache-line-size = <32>; // 32 bytes |
| 84 | cache-size = <0x40000>; // L2, 256K | 84 | cache-size = <0x40000>; // L2, 256K |
diff --git a/arch/powerpc/boot/dts/mpc8568mds.dts b/arch/powerpc/boot/dts/mpc8568mds.dts index 92fb17876e7d..30cf0e098bb9 100644 --- a/arch/powerpc/boot/dts/mpc8568mds.dts +++ b/arch/powerpc/boot/dts/mpc8568mds.dts | |||
| @@ -124,14 +124,14 @@ | |||
| 124 | }; | 124 | }; |
| 125 | 125 | ||
| 126 | memory-controller@2000 { | 126 | memory-controller@2000 { |
| 127 | compatible = "fsl,8568-memory-controller"; | 127 | compatible = "fsl,mpc8568-memory-controller"; |
| 128 | reg = <0x2000 0x1000>; | 128 | reg = <0x2000 0x1000>; |
| 129 | interrupt-parent = <&mpic>; | 129 | interrupt-parent = <&mpic>; |
| 130 | interrupts = <18 2>; | 130 | interrupts = <18 2>; |
| 131 | }; | 131 | }; |
| 132 | 132 | ||
| 133 | L2: l2-cache-controller@20000 { | 133 | L2: l2-cache-controller@20000 { |
| 134 | compatible = "fsl,8568-l2-cache-controller"; | 134 | compatible = "fsl,mpc8568-l2-cache-controller"; |
| 135 | reg = <0x20000 0x1000>; | 135 | reg = <0x20000 0x1000>; |
| 136 | cache-line-size = <32>; // 32 bytes | 136 | cache-line-size = <32>; // 32 bytes |
| 137 | cache-size = <0x80000>; // L2, 512K | 137 | cache-size = <0x80000>; // L2, 512K |
diff --git a/arch/powerpc/boot/dts/p1021mds.dts b/arch/powerpc/boot/dts/p1021mds.dts index 7fad2df25981..ad5b85269004 100644 --- a/arch/powerpc/boot/dts/p1021mds.dts +++ b/arch/powerpc/boot/dts/p1021mds.dts | |||
| @@ -617,6 +617,7 @@ | |||
| 617 | bus-frequency = <0>; | 617 | bus-frequency = <0>; |
| 618 | fsl,qe-num-riscs = <1>; | 618 | fsl,qe-num-riscs = <1>; |
| 619 | fsl,qe-num-snums = <28>; | 619 | fsl,qe-num-snums = <28>; |
| 620 | status = "disabled"; /* no firmware loaded */ | ||
| 620 | 621 | ||
| 621 | qeic: interrupt-controller@80 { | 622 | qeic: interrupt-controller@80 { |
| 622 | interrupt-controller; | 623 | interrupt-controller; |
diff --git a/arch/powerpc/boot/dts/p1022ds.dts b/arch/powerpc/boot/dts/p1022ds.dts new file mode 100644 index 000000000000..8bcb10b92677 --- /dev/null +++ b/arch/powerpc/boot/dts/p1022ds.dts | |||
| @@ -0,0 +1,633 @@ | |||
| 1 | /* | ||
| 2 | * P1022 DS 36Bit Physical Address Map Device Tree Source | ||
| 3 | * | ||
| 4 | * Copyright 2010 Freescale Semiconductor, Inc. | ||
| 5 | * | ||
| 6 | * This file is licensed under the terms of the GNU General Public License | ||
| 7 | * version 2. This program is licensed "as is" without any warranty of any | ||
| 8 | * kind, whether express or implied. | ||
| 9 | */ | ||
| 10 | |||
| 11 | /dts-v1/; | ||
| 12 | / { | ||
| 13 | model = "fsl,P1022"; | ||
| 14 | compatible = "fsl,P1022DS"; | ||
| 15 | #address-cells = <2>; | ||
| 16 | #size-cells = <2>; | ||
| 17 | interrupt-parent = <&mpic>; | ||
| 18 | |||
| 19 | aliases { | ||
| 20 | ethernet0 = &enet0; | ||
| 21 | ethernet1 = &enet1; | ||
| 22 | serial0 = &serial0; | ||
| 23 | serial1 = &serial1; | ||
| 24 | pci0 = &pci0; | ||
| 25 | pci1 = &pci1; | ||
| 26 | pci2 = &pci2; | ||
| 27 | }; | ||
| 28 | |||
| 29 | cpus { | ||
| 30 | #address-cells = <1>; | ||
| 31 | #size-cells = <0>; | ||
| 32 | |||
| 33 | PowerPC,P1022@0 { | ||
| 34 | device_type = "cpu"; | ||
| 35 | reg = <0x0>; | ||
| 36 | next-level-cache = <&L2>; | ||
| 37 | }; | ||
| 38 | |||
| 39 | PowerPC,P1022@1 { | ||
| 40 | device_type = "cpu"; | ||
| 41 | reg = <0x1>; | ||
| 42 | next-level-cache = <&L2>; | ||
| 43 | }; | ||
| 44 | }; | ||
| 45 | |||
| 46 | memory { | ||
| 47 | device_type = "memory"; | ||
| 48 | }; | ||
| 49 | |||
| 50 | localbus@fffe05000 { | ||
| 51 | #address-cells = <2>; | ||
| 52 | #size-cells = <1>; | ||
| 53 | compatible = "fsl,p1022-elbc", "fsl,elbc", "simple-bus"; | ||
| 54 | reg = <0 0xffe05000 0 0x1000>; | ||
| 55 | interrupts = <19 2>; | ||
| 56 | |||
| 57 | ranges = <0x0 0x0 0xf 0xe8000000 0x08000000 | ||
| 58 | 0x1 0x0 0xf 0xe0000000 0x08000000 | ||
| 59 | 0x2 0x0 0x0 0xffa00000 0x00040000 | ||
| 60 | 0x3 0x0 0xf 0xffdf0000 0x00008000>; | ||
| 61 | |||
| 62 | nor@0,0 { | ||
| 63 | #address-cells = <1>; | ||
| 64 | #size-cells = <1>; | ||
| 65 | compatible = "cfi-flash"; | ||
| 66 | reg = <0x0 0x0 0x8000000>; | ||
| 67 | bank-width = <2>; | ||
| 68 | device-width = <1>; | ||
| 69 | |||
| 70 | partition@0 { | ||
| 71 | reg = <0x0 0x03000000>; | ||
| 72 | label = "ramdisk-nor"; | ||
| 73 | read-only; | ||
| 74 | }; | ||
| 75 | |||
| 76 | partition@3000000 { | ||
| 77 | reg = <0x03000000 0x00e00000>; | ||
| 78 | label = "diagnostic-nor"; | ||
| 79 | read-only; | ||
| 80 | }; | ||
| 81 | |||
| 82 | partition@3e00000 { | ||
| 83 | reg = <0x03e00000 0x00200000>; | ||
| 84 | label = "dink-nor"; | ||
| 85 | read-only; | ||
| 86 | }; | ||
| 87 | |||
| 88 | partition@4000000 { | ||
| 89 | reg = <0x04000000 0x00400000>; | ||
| 90 | label = "kernel-nor"; | ||
| 91 | read-only; | ||
| 92 | }; | ||
| 93 | |||
| 94 | partition@4400000 { | ||
| 95 | reg = <0x04400000 0x03b00000>; | ||
| 96 | label = "jffs2-nor"; | ||
| 97 | }; | ||
| 98 | |||
| 99 | partition@7f00000 { | ||
| 100 | reg = <0x07f00000 0x00080000>; | ||
| 101 | label = "dtb-nor"; | ||
| 102 | read-only; | ||
| 103 | }; | ||
| 104 | |||
| 105 | partition@7f80000 { | ||
| 106 | reg = <0x07f80000 0x00080000>; | ||
| 107 | label = "u-boot-nor"; | ||
| 108 | read-only; | ||
| 109 | }; | ||
| 110 | }; | ||
| 111 | |||
| 112 | nand@2,0 { | ||
| 113 | #address-cells = <1>; | ||
| 114 | #size-cells = <1>; | ||
| 115 | compatible = "fsl,elbc-fcm-nand"; | ||
| 116 | reg = <0x2 0x0 0x40000>; | ||
| 117 | |||
| 118 | partition@0 { | ||
| 119 | reg = <0x0 0x02000000>; | ||
| 120 | label = "u-boot-nand"; | ||
| 121 | read-only; | ||
| 122 | }; | ||
| 123 | |||
| 124 | partition@2000000 { | ||
| 125 | reg = <0x02000000 0x10000000>; | ||
| 126 | label = "jffs2-nand"; | ||
| 127 | }; | ||
| 128 | |||
| 129 | partition@12000000 { | ||
| 130 | reg = <0x12000000 0x10000000>; | ||
| 131 | label = "ramdisk-nand"; | ||
| 132 | read-only; | ||
| 133 | }; | ||
| 134 | |||
| 135 | partition@22000000 { | ||
| 136 | reg = <0x22000000 0x04000000>; | ||
| 137 | label = "kernel-nand"; | ||
| 138 | }; | ||
| 139 | |||
| 140 | partition@26000000 { | ||
| 141 | reg = <0x26000000 0x01000000>; | ||
| 142 | label = "dtb-nand"; | ||
| 143 | read-only; | ||
| 144 | }; | ||
| 145 | |||
| 146 | partition@27000000 { | ||
| 147 | reg = <0x27000000 0x19000000>; | ||
| 148 | label = "reserved-nand"; | ||
| 149 | }; | ||
| 150 | }; | ||
| 151 | }; | ||
| 152 | |||
| 153 | soc@fffe00000 { | ||
| 154 | #address-cells = <1>; | ||
| 155 | #size-cells = <1>; | ||
| 156 | device_type = "soc"; | ||
| 157 | compatible = "fsl,p1022-immr", "simple-bus"; | ||
| 158 | ranges = <0x0 0xf 0xffe00000 0x100000>; | ||
| 159 | bus-frequency = <0>; // Filled out by uboot. | ||
| 160 | |||
| 161 | ecm-law@0 { | ||
| 162 | compatible = "fsl,ecm-law"; | ||
| 163 | reg = <0x0 0x1000>; | ||
| 164 | fsl,num-laws = <12>; | ||
| 165 | }; | ||
| 166 | |||
| 167 | ecm@1000 { | ||
| 168 | compatible = "fsl,p1022-ecm", "fsl,ecm"; | ||
| 169 | reg = <0x1000 0x1000>; | ||
| 170 | interrupts = <16 2>; | ||
| 171 | }; | ||
| 172 | |||
| 173 | memory-controller@2000 { | ||
| 174 | compatible = "fsl,p1022-memory-controller"; | ||
| 175 | reg = <0x2000 0x1000>; | ||
| 176 | interrupts = <16 2>; | ||
| 177 | }; | ||
| 178 | |||
| 179 | i2c@3000 { | ||
| 180 | #address-cells = <1>; | ||
| 181 | #size-cells = <0>; | ||
| 182 | cell-index = <0>; | ||
| 183 | compatible = "fsl-i2c"; | ||
| 184 | reg = <0x3000 0x100>; | ||
| 185 | interrupts = <43 2>; | ||
| 186 | dfsrr; | ||
| 187 | }; | ||
| 188 | |||
| 189 | i2c@3100 { | ||
| 190 | #address-cells = <1>; | ||
| 191 | #size-cells = <0>; | ||
| 192 | cell-index = <1>; | ||
| 193 | compatible = "fsl-i2c"; | ||
| 194 | reg = <0x3100 0x100>; | ||
| 195 | interrupts = <43 2>; | ||
| 196 | dfsrr; | ||
| 197 | |||
| 198 | wm8776:codec@1a { | ||
| 199 | compatible = "wlf,wm8776"; | ||
| 200 | reg = <0x1a>; | ||
| 201 | /* MCLK source is a stand-alone oscillator */ | ||
| 202 | clock-frequency = <12288000>; | ||
| 203 | }; | ||
| 204 | }; | ||
| 205 | |||
| 206 | serial0: serial@4500 { | ||
| 207 | cell-index = <0>; | ||
| 208 | device_type = "serial"; | ||
| 209 | compatible = "ns16550"; | ||
| 210 | reg = <0x4500 0x100>; | ||
| 211 | clock-frequency = <0>; | ||
| 212 | interrupts = <42 2>; | ||
| 213 | }; | ||
| 214 | |||
| 215 | serial1: serial@4600 { | ||
| 216 | cell-index = <1>; | ||
| 217 | device_type = "serial"; | ||
| 218 | compatible = "ns16550"; | ||
| 219 | reg = <0x4600 0x100>; | ||
| 220 | clock-frequency = <0>; | ||
| 221 | interrupts = <42 2>; | ||
| 222 | }; | ||
| 223 | |||
| 224 | spi@7000 { | ||
| 225 | cell-index = <0>; | ||
| 226 | #address-cells = <1>; | ||
| 227 | #size-cells = <0>; | ||
| 228 | compatible = "fsl,espi"; | ||
| 229 | reg = <0x7000 0x1000>; | ||
| 230 | interrupts = <59 0x2>; | ||
| 231 | espi,num-ss-bits = <4>; | ||
| 232 | mode = "cpu"; | ||
| 233 | |||
| 234 | fsl_m25p80@0 { | ||
| 235 | #address-cells = <1>; | ||
| 236 | #size-cells = <1>; | ||
| 237 | compatible = "fsl,espi-flash"; | ||
| 238 | reg = <0>; | ||
| 239 | linux,modalias = "fsl_m25p80"; | ||
| 240 | spi-max-frequency = <40000000>; /* input clock */ | ||
| 241 | partition@0 { | ||
| 242 | label = "u-boot-spi"; | ||
| 243 | reg = <0x00000000 0x00100000>; | ||
| 244 | read-only; | ||
| 245 | }; | ||
| 246 | partition@100000 { | ||
| 247 | label = "kernel-spi"; | ||
| 248 | reg = <0x00100000 0x00500000>; | ||
| 249 | read-only; | ||
| 250 | }; | ||
| 251 | partition@600000 { | ||
| 252 | label = "dtb-spi"; | ||
| 253 | reg = <0x00600000 0x00100000>; | ||
| 254 | read-only; | ||
| 255 | }; | ||
| 256 | partition@700000 { | ||
| 257 | label = "file system-spi"; | ||
| 258 | reg = <0x00700000 0x00900000>; | ||
| 259 | }; | ||
| 260 | }; | ||
| 261 | }; | ||
| 262 | |||
| 263 | ssi@15000 { | ||
| 264 | compatible = "fsl,mpc8610-ssi"; | ||
| 265 | cell-index = <0>; | ||
| 266 | reg = <0x15000 0x100>; | ||
| 267 | interrupts = <75 2>; | ||
| 268 | fsl,mode = "i2s-slave"; | ||
| 269 | codec-handle = <&wm8776>; | ||
| 270 | fsl,playback-dma = <&dma00>; | ||
| 271 | fsl,capture-dma = <&dma01>; | ||
| 272 | fsl,fifo-depth = <16>; | ||
| 273 | }; | ||
| 274 | |||
| 275 | dma@c300 { | ||
| 276 | #address-cells = <1>; | ||
| 277 | #size-cells = <1>; | ||
| 278 | compatible = "fsl,eloplus-dma"; | ||
| 279 | reg = <0xc300 0x4>; | ||
| 280 | ranges = <0x0 0xc100 0x200>; | ||
| 281 | cell-index = <1>; | ||
| 282 | dma00: dma-channel@0 { | ||
| 283 | compatible = "fsl,eloplus-dma-channel"; | ||
| 284 | reg = <0x0 0x80>; | ||
| 285 | cell-index = <0>; | ||
| 286 | interrupts = <76 2>; | ||
| 287 | }; | ||
| 288 | dma01: dma-channel@80 { | ||
| 289 | compatible = "fsl,eloplus-dma-channel"; | ||
| 290 | reg = <0x80 0x80>; | ||
| 291 | cell-index = <1>; | ||
| 292 | interrupts = <77 2>; | ||
| 293 | }; | ||
| 294 | dma-channel@100 { | ||
| 295 | compatible = "fsl,eloplus-dma-channel"; | ||
| 296 | reg = <0x100 0x80>; | ||
| 297 | cell-index = <2>; | ||
| 298 | interrupts = <78 2>; | ||
| 299 | }; | ||
| 300 | dma-channel@180 { | ||
| 301 | compatible = "fsl,eloplus-dma-channel"; | ||
| 302 | reg = <0x180 0x80>; | ||
| 303 | cell-index = <3>; | ||
| 304 | interrupts = <79 2>; | ||
| 305 | }; | ||
| 306 | }; | ||
| 307 | |||
| 308 | gpio: gpio-controller@f000 { | ||
| 309 | #gpio-cells = <2>; | ||
| 310 | compatible = "fsl,mpc8572-gpio"; | ||
| 311 | reg = <0xf000 0x100>; | ||
| 312 | interrupts = <47 0x2>; | ||
| 313 | gpio-controller; | ||
| 314 | }; | ||
| 315 | |||
| 316 | L2: l2-cache-controller@20000 { | ||
| 317 | compatible = "fsl,p1022-l2-cache-controller"; | ||
| 318 | reg = <0x20000 0x1000>; | ||
| 319 | cache-line-size = <32>; // 32 bytes | ||
| 320 | cache-size = <0x40000>; // L2, 256K | ||
| 321 | interrupts = <16 2>; | ||
| 322 | }; | ||
| 323 | |||
| 324 | dma@21300 { | ||
| 325 | #address-cells = <1>; | ||
| 326 | #size-cells = <1>; | ||
| 327 | compatible = "fsl,eloplus-dma"; | ||
| 328 | reg = <0x21300 0x4>; | ||
| 329 | ranges = <0x0 0x21100 0x200>; | ||
| 330 | cell-index = <0>; | ||
| 331 | dma-channel@0 { | ||
| 332 | compatible = "fsl,eloplus-dma-channel"; | ||
| 333 | reg = <0x0 0x80>; | ||
| 334 | cell-index = <0>; | ||
| 335 | interrupts = <20 2>; | ||
| 336 | }; | ||
| 337 | dma-channel@80 { | ||
| 338 | compatible = "fsl,eloplus-dma-channel"; | ||
| 339 | reg = <0x80 0x80>; | ||
| 340 | cell-index = <1>; | ||
| 341 | interrupts = <21 2>; | ||
| 342 | }; | ||
| 343 | dma-channel@100 { | ||
| 344 | compatible = "fsl,eloplus-dma-channel"; | ||
| 345 | reg = <0x100 0x80>; | ||
| 346 | cell-index = <2>; | ||
| 347 | interrupts = <22 2>; | ||
| 348 | }; | ||
| 349 | dma-channel@180 { | ||
| 350 | compatible = "fsl,eloplus-dma-channel"; | ||
| 351 | reg = <0x180 0x80>; | ||
| 352 | cell-index = <3>; | ||
| 353 | interrupts = <23 2>; | ||
| 354 | }; | ||
| 355 | }; | ||
| 356 | |||
| 357 | usb@22000 { | ||
| 358 | #address-cells = <1>; | ||
| 359 | #size-cells = <0>; | ||
| 360 | compatible = "fsl-usb2-dr"; | ||
| 361 | reg = <0x22000 0x1000>; | ||
| 362 | interrupts = <28 0x2>; | ||
| 363 | phy_type = "ulpi"; | ||
| 364 | }; | ||
| 365 | |||
| 366 | mdio@24000 { | ||
| 367 | #address-cells = <1>; | ||
| 368 | #size-cells = <0>; | ||
| 369 | compatible = "fsl,etsec2-mdio"; | ||
| 370 | reg = <0x24000 0x1000 0xb0030 0x4>; | ||
| 371 | |||
| 372 | phy0: ethernet-phy@0 { | ||
| 373 | interrupts = <3 1>; | ||
| 374 | reg = <0x1>; | ||
| 375 | }; | ||
| 376 | phy1: ethernet-phy@1 { | ||
| 377 | interrupts = <9 1>; | ||
| 378 | reg = <0x2>; | ||
| 379 | }; | ||
| 380 | }; | ||
| 381 | |||
| 382 | mdio@25000 { | ||
| 383 | #address-cells = <1>; | ||
| 384 | #size-cells = <0>; | ||
| 385 | compatible = "fsl,etsec2-mdio"; | ||
| 386 | reg = <0x25000 0x1000 0xb1030 0x4>; | ||
| 387 | }; | ||
| 388 | |||
| 389 | enet0: ethernet@B0000 { | ||
| 390 | #address-cells = <1>; | ||
| 391 | #size-cells = <1>; | ||
| 392 | cell-index = <0>; | ||
| 393 | device_type = "network"; | ||
| 394 | model = "eTSEC"; | ||
| 395 | compatible = "fsl,etsec2"; | ||
| 396 | fsl,num_rx_queues = <0x8>; | ||
| 397 | fsl,num_tx_queues = <0x8>; | ||
| 398 | fsl,magic-packet; | ||
| 399 | fsl,wake-on-filer; | ||
| 400 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 401 | fixed-link = <1 1 1000 0 0>; | ||
| 402 | phy-handle = <&phy0>; | ||
| 403 | phy-connection-type = "rgmii-id"; | ||
| 404 | queue-group@0{ | ||
| 405 | #address-cells = <1>; | ||
| 406 | #size-cells = <1>; | ||
| 407 | reg = <0xB0000 0x1000>; | ||
| 408 | interrupts = <29 2 30 2 34 2>; | ||
| 409 | }; | ||
| 410 | queue-group@1{ | ||
| 411 | #address-cells = <1>; | ||
| 412 | #size-cells = <1>; | ||
| 413 | reg = <0xB4000 0x1000>; | ||
| 414 | interrupts = <17 2 18 2 24 2>; | ||
| 415 | }; | ||
| 416 | }; | ||
| 417 | |||
| 418 | enet1: ethernet@B1000 { | ||
| 419 | #address-cells = <1>; | ||
| 420 | #size-cells = <1>; | ||
| 421 | cell-index = <0>; | ||
| 422 | device_type = "network"; | ||
| 423 | model = "eTSEC"; | ||
| 424 | compatible = "fsl,etsec2"; | ||
| 425 | fsl,num_rx_queues = <0x8>; | ||
| 426 | fsl,num_tx_queues = <0x8>; | ||
| 427 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 428 | fixed-link = <1 1 1000 0 0>; | ||
| 429 | phy-handle = <&phy1>; | ||
| 430 | phy-connection-type = "rgmii-id"; | ||
| 431 | queue-group@0{ | ||
| 432 | #address-cells = <1>; | ||
| 433 | #size-cells = <1>; | ||
| 434 | reg = <0xB1000 0x1000>; | ||
| 435 | interrupts = <35 2 36 2 40 2>; | ||
| 436 | }; | ||
| 437 | queue-group@1{ | ||
| 438 | #address-cells = <1>; | ||
| 439 | #size-cells = <1>; | ||
| 440 | reg = <0xB5000 0x1000>; | ||
| 441 | interrupts = <51 2 52 2 67 2>; | ||
| 442 | }; | ||
| 443 | }; | ||
| 444 | |||
| 445 | sdhci@2e000 { | ||
| 446 | compatible = "fsl,p1022-esdhc", "fsl,esdhc"; | ||
| 447 | reg = <0x2e000 0x1000>; | ||
| 448 | interrupts = <72 0x2>; | ||
| 449 | fsl,sdhci-auto-cmd12; | ||
| 450 | /* Filled in by U-Boot */ | ||
| 451 | clock-frequency = <0>; | ||
| 452 | }; | ||
| 453 | |||
| 454 | crypto@30000 { | ||
| 455 | compatible = "fsl,sec3.3", "fsl,sec3.1", "fsl,sec3.0", | ||
| 456 | "fsl,sec2.4", "fsl,sec2.2", "fsl,sec2.1", | ||
| 457 | "fsl,sec2.0"; | ||
| 458 | reg = <0x30000 0x10000>; | ||
| 459 | interrupts = <45 2 58 2>; | ||
| 460 | fsl,num-channels = <4>; | ||
| 461 | fsl,channel-fifo-len = <24>; | ||
| 462 | fsl,exec-units-mask = <0x97c>; | ||
| 463 | fsl,descriptor-types-mask = <0x3a30abf>; | ||
| 464 | }; | ||
| 465 | |||
| 466 | sata@18000 { | ||
| 467 | compatible = "fsl,mpc8536-sata", "fsl,pq-sata"; | ||
| 468 | reg = <0x18000 0x1000>; | ||
| 469 | cell-index = <1>; | ||
| 470 | interrupts = <74 0x2>; | ||
| 471 | }; | ||
| 472 | |||
| 473 | sata@19000 { | ||
| 474 | compatible = "fsl,mpc8536-sata", "fsl,pq-sata"; | ||
| 475 | reg = <0x19000 0x1000>; | ||
| 476 | cell-index = <2>; | ||
| 477 | interrupts = <41 0x2>; | ||
| 478 | }; | ||
| 479 | |||
| 480 | power@e0070{ | ||
| 481 | compatible = "fsl,mpc8536-pmc", "fsl,mpc8548-pmc"; | ||
| 482 | reg = <0xe0070 0x20>; | ||
| 483 | }; | ||
| 484 | |||
| 485 | display@10000 { | ||
| 486 | compatible = "fsl,diu", "fsl,p1022-diu"; | ||
| 487 | reg = <0x10000 1000>; | ||
| 488 | interrupts = <64 2>; | ||
| 489 | }; | ||
| 490 | |||
| 491 | timer@41100 { | ||
| 492 | compatible = "fsl,mpic-global-timer"; | ||
| 493 | reg = <0x41100 0x204>; | ||
| 494 | interrupts = <0xf7 0x2>; | ||
| 495 | }; | ||
| 496 | |||
| 497 | mpic: pic@40000 { | ||
| 498 | interrupt-controller; | ||
| 499 | #address-cells = <0>; | ||
| 500 | #interrupt-cells = <2>; | ||
| 501 | reg = <0x40000 0x40000>; | ||
| 502 | compatible = "chrp,open-pic"; | ||
| 503 | device_type = "open-pic"; | ||
| 504 | }; | ||
| 505 | |||
| 506 | msi@41600 { | ||
| 507 | compatible = "fsl,p1022-msi", "fsl,mpic-msi"; | ||
| 508 | reg = <0x41600 0x80>; | ||
| 509 | msi-available-ranges = <0 0x100>; | ||
| 510 | interrupts = < | ||
| 511 | 0xe0 0 | ||
| 512 | 0xe1 0 | ||
| 513 | 0xe2 0 | ||
| 514 | 0xe3 0 | ||
| 515 | 0xe4 0 | ||
| 516 | 0xe5 0 | ||
| 517 | 0xe6 0 | ||
| 518 | 0xe7 0>; | ||
| 519 | }; | ||
| 520 | |||
| 521 | global-utilities@e0000 { //global utilities block | ||
| 522 | compatible = "fsl,p1022-guts"; | ||
| 523 | reg = <0xe0000 0x1000>; | ||
| 524 | fsl,has-rstcr; | ||
| 525 | }; | ||
| 526 | }; | ||
| 527 | |||
| 528 | pci0: pcie@fffe09000 { | ||
| 529 | compatible = "fsl,p1022-pcie"; | ||
| 530 | device_type = "pci"; | ||
| 531 | #interrupt-cells = <1>; | ||
| 532 | #size-cells = <2>; | ||
| 533 | #address-cells = <3>; | ||
| 534 | reg = <0xf 0xffe09000 0 0x1000>; | ||
| 535 | bus-range = <0 255>; | ||
| 536 | ranges = <0x2000000 0x0 0xa0000000 0xc 0x20000000 0x0 0x20000000 | ||
| 537 | 0x1000000 0x0 0x00000000 0xf 0xffc10000 0x0 0x10000>; | ||
| 538 | clock-frequency = <33333333>; | ||
| 539 | interrupts = <16 2>; | ||
| 540 | interrupt-map-mask = <0xf800 0 0 7>; | ||
| 541 | interrupt-map = < | ||
| 542 | /* IDSEL 0x0 */ | ||
| 543 | 0000 0 0 1 &mpic 4 1 | ||
| 544 | 0000 0 0 2 &mpic 5 1 | ||
| 545 | 0000 0 0 3 &mpic 6 1 | ||
| 546 | 0000 0 0 4 &mpic 7 1 | ||
| 547 | >; | ||
| 548 | pcie@0 { | ||
| 549 | reg = <0x0 0x0 0x0 0x0 0x0>; | ||
| 550 | #size-cells = <2>; | ||
| 551 | #address-cells = <3>; | ||
| 552 | device_type = "pci"; | ||
| 553 | ranges = <0x2000000 0x0 0xe0000000 | ||
| 554 | 0x2000000 0x0 0xe0000000 | ||
| 555 | 0x0 0x20000000 | ||
| 556 | |||
| 557 | 0x1000000 0x0 0x0 | ||
| 558 | 0x1000000 0x0 0x0 | ||
| 559 | 0x0 0x100000>; | ||
| 560 | }; | ||
| 561 | }; | ||
| 562 | |||
| 563 | pci1: pcie@fffe0a000 { | ||
| 564 | compatible = "fsl,p1022-pcie"; | ||
| 565 | device_type = "pci"; | ||
| 566 | #interrupt-cells = <1>; | ||
| 567 | #size-cells = <2>; | ||
| 568 | #address-cells = <3>; | ||
| 569 | reg = <0xf 0xffe0a000 0 0x1000>; | ||
| 570 | bus-range = <0 255>; | ||
| 571 | ranges = <0x2000000 0x0 0xc0000000 0xc 0x40000000 0x0 0x20000000 | ||
| 572 | 0x1000000 0x0 0x00000000 0xf 0xffc20000 0x0 0x10000>; | ||
| 573 | clock-frequency = <33333333>; | ||
| 574 | interrupts = <16 2>; | ||
| 575 | interrupt-map-mask = <0xf800 0 0 7>; | ||
| 576 | interrupt-map = < | ||
| 577 | /* IDSEL 0x0 */ | ||
| 578 | 0000 0 0 1 &mpic 0 1 | ||
| 579 | 0000 0 0 2 &mpic 1 1 | ||
| 580 | 0000 0 0 3 &mpic 2 1 | ||
| 581 | 0000 0 0 4 &mpic 3 1 | ||
| 582 | >; | ||
| 583 | pcie@0 { | ||
| 584 | reg = <0x0 0x0 0x0 0x0 0x0>; | ||
| 585 | #size-cells = <2>; | ||
| 586 | #address-cells = <3>; | ||
| 587 | device_type = "pci"; | ||
| 588 | ranges = <0x2000000 0x0 0xe0000000 | ||
| 589 | 0x2000000 0x0 0xe0000000 | ||
| 590 | 0x0 0x20000000 | ||
| 591 | |||
| 592 | 0x1000000 0x0 0x0 | ||
| 593 | 0x1000000 0x0 0x0 | ||
| 594 | 0x0 0x100000>; | ||
| 595 | }; | ||
| 596 | }; | ||
| 597 | |||
| 598 | |||
| 599 | pci2: pcie@fffe0b000 { | ||
| 600 | compatible = "fsl,p1022-pcie"; | ||
| 601 | device_type = "pci"; | ||
| 602 | #interrupt-cells = <1>; | ||
| 603 | #size-cells = <2>; | ||
| 604 | #address-cells = <3>; | ||
| 605 | reg = <0xf 0xffe0b000 0 0x1000>; | ||
| 606 | bus-range = <0 255>; | ||
| 607 | ranges = <0x2000000 0x0 0x80000000 0xc 0x00000000 0x0 0x20000000 | ||
| 608 | 0x1000000 0x0 0x00000000 0xf 0xffc00000 0x0 0x10000>; | ||
| 609 | clock-frequency = <33333333>; | ||
| 610 | interrupts = <16 2>; | ||
| 611 | interrupt-map-mask = <0xf800 0 0 7>; | ||
| 612 | interrupt-map = < | ||
| 613 | /* IDSEL 0x0 */ | ||
| 614 | 0000 0 0 1 &mpic 8 1 | ||
| 615 | 0000 0 0 2 &mpic 9 1 | ||
| 616 | 0000 0 0 3 &mpic 10 1 | ||
| 617 | 0000 0 0 4 &mpic 11 1 | ||
| 618 | >; | ||
| 619 | pcie@0 { | ||
| 620 | reg = <0x0 0x0 0x0 0x0 0x0>; | ||
| 621 | #size-cells = <2>; | ||
| 622 | #address-cells = <3>; | ||
| 623 | device_type = "pci"; | ||
| 624 | ranges = <0x2000000 0x0 0xe0000000 | ||
| 625 | 0x2000000 0x0 0xe0000000 | ||
| 626 | 0x0 0x20000000 | ||
| 627 | |||
| 628 | 0x1000000 0x0 0x0 | ||
| 629 | 0x1000000 0x0 0x0 | ||
| 630 | 0x0 0x100000>; | ||
| 631 | }; | ||
| 632 | }; | ||
| 633 | }; | ||
diff --git a/arch/powerpc/boot/dts/pdm360ng.dts b/arch/powerpc/boot/dts/pdm360ng.dts new file mode 100644 index 000000000000..94dfa5c9a7f9 --- /dev/null +++ b/arch/powerpc/boot/dts/pdm360ng.dts | |||
| @@ -0,0 +1,410 @@ | |||
| 1 | /* | ||
| 2 | * Device Tree Source for IFM PDM360NG. | ||
| 3 | * | ||
| 4 | * Copyright 2009 - 2010 DENX Software Engineering. | ||
| 5 | * Anatolij Gustschin <agust@denx.de> | ||
| 6 | * | ||
| 7 | * Based on MPC5121E ADS dts. | ||
| 8 | * Copyright 2008 Freescale Semiconductor Inc. | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify it | ||
| 11 | * under the terms of the GNU General Public License as published by the | ||
| 12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 13 | * option) any later version. | ||
| 14 | */ | ||
| 15 | |||
| 16 | /dts-v1/; | ||
| 17 | |||
| 18 | / { | ||
| 19 | model = "pdm360ng"; | ||
| 20 | compatible = "ifm,pdm360ng"; | ||
| 21 | #address-cells = <1>; | ||
| 22 | #size-cells = <1>; | ||
| 23 | interrupt-parent = <&ipic>; | ||
| 24 | |||
| 25 | aliases { | ||
| 26 | ethernet0 = ð0; | ||
| 27 | }; | ||
| 28 | |||
| 29 | cpus { | ||
| 30 | #address-cells = <1>; | ||
| 31 | #size-cells = <0>; | ||
| 32 | |||
| 33 | PowerPC,5121@0 { | ||
| 34 | device_type = "cpu"; | ||
| 35 | reg = <0>; | ||
| 36 | d-cache-line-size = <0x20>; // 32 bytes | ||
| 37 | i-cache-line-size = <0x20>; // 32 bytes | ||
| 38 | d-cache-size = <0x8000>; // L1, 32K | ||
| 39 | i-cache-size = <0x8000>; // L1, 32K | ||
| 40 | timebase-frequency = <49500000>;// 49.5 MHz (csb/4) | ||
| 41 | bus-frequency = <198000000>; // 198 MHz csb bus | ||
| 42 | clock-frequency = <396000000>; // 396 MHz ppc core | ||
| 43 | }; | ||
| 44 | }; | ||
| 45 | |||
| 46 | memory { | ||
| 47 | device_type = "memory"; | ||
| 48 | reg = <0x00000000 0x20000000>; // 512MB at 0 | ||
| 49 | }; | ||
| 50 | |||
| 51 | nfc@40000000 { | ||
| 52 | compatible = "fsl,mpc5121-nfc"; | ||
| 53 | reg = <0x40000000 0x100000>; | ||
| 54 | interrupts = <0x6 0x8>; | ||
| 55 | #address-cells = <0x1>; | ||
| 56 | #size-cells = <0x1>; | ||
| 57 | bank-width = <0x1>; | ||
| 58 | chips = <0x1>; | ||
| 59 | |||
| 60 | partition@0 { | ||
| 61 | label = "nand0"; | ||
| 62 | reg = <0x0 0x40000000>; | ||
| 63 | }; | ||
| 64 | }; | ||
| 65 | |||
| 66 | sram@50000000 { | ||
| 67 | compatible = "fsl,mpc5121-sram"; | ||
| 68 | reg = <0x50000000 0x20000>; // 128K at 0x50000000 | ||
| 69 | }; | ||
| 70 | |||
| 71 | localbus@80000020 { | ||
| 72 | compatible = "fsl,mpc5121-localbus"; | ||
| 73 | #address-cells = <2>; | ||
| 74 | #size-cells = <1>; | ||
| 75 | reg = <0x80000020 0x40>; | ||
| 76 | |||
| 77 | ranges = <0x0 0x0 0xf0000000 0x10000000 /* Flash */ | ||
| 78 | 0x2 0x0 0x50040000 0x00020000>; /* CS2: MRAM */ | ||
| 79 | |||
| 80 | flash@0,0 { | ||
| 81 | compatible = "amd,s29gl01gp", "cfi-flash"; | ||
| 82 | reg = <0 0x00000000 0x08000000 | ||
| 83 | 0 0x08000000 0x08000000>; | ||
| 84 | #address-cells = <1>; | ||
| 85 | #size-cells = <1>; | ||
| 86 | bank-width = <4>; | ||
| 87 | device-width = <2>; | ||
| 88 | |||
| 89 | partition@0 { | ||
| 90 | label = "u-boot"; | ||
| 91 | reg = <0x00000000 0x00080000>; | ||
| 92 | read-only; | ||
| 93 | }; | ||
| 94 | partition@80000 { | ||
| 95 | label = "environment"; | ||
| 96 | reg = <0x00080000 0x00080000>; | ||
| 97 | read-only; | ||
| 98 | }; | ||
| 99 | partition@100000 { | ||
| 100 | label = "splash-image"; | ||
| 101 | reg = <0x00100000 0x00080000>; | ||
| 102 | read-only; | ||
| 103 | }; | ||
| 104 | partition@180000 { | ||
| 105 | label = "device-tree"; | ||
| 106 | reg = <0x00180000 0x00040000>; | ||
| 107 | }; | ||
| 108 | partition@1c0000 { | ||
| 109 | label = "kernel"; | ||
| 110 | reg = <0x001c0000 0x00500000>; | ||
| 111 | }; | ||
| 112 | partition@6c0000 { | ||
| 113 | label = "filesystem"; | ||
| 114 | reg = <0x006c0000 0x07940000>; | ||
| 115 | }; | ||
| 116 | }; | ||
| 117 | |||
| 118 | mram0@2,0 { | ||
| 119 | compatible = "mtd-ram"; | ||
| 120 | reg = <2 0x00000 0x10000>; | ||
| 121 | bank-width = <2>; | ||
| 122 | }; | ||
| 123 | |||
| 124 | mram1@2,10000 { | ||
| 125 | compatible = "mtd-ram"; | ||
| 126 | reg = <2 0x010000 0x10000>; | ||
| 127 | bank-width = <2>; | ||
| 128 | }; | ||
| 129 | }; | ||
| 130 | |||
| 131 | soc@80000000 { | ||
| 132 | compatible = "fsl,mpc5121-immr"; | ||
| 133 | #address-cells = <1>; | ||
| 134 | #size-cells = <1>; | ||
| 135 | #interrupt-cells = <2>; | ||
| 136 | ranges = <0x0 0x80000000 0x400000>; | ||
| 137 | reg = <0x80000000 0x400000>; | ||
| 138 | bus-frequency = <66000000>; // 66 MHz ips bus | ||
| 139 | |||
| 140 | // IPIC | ||
| 141 | // interrupts cell = <intr #, sense> | ||
| 142 | // sense values match linux IORESOURCE_IRQ_* defines: | ||
| 143 | // sense == 8: Level, low assertion | ||
| 144 | // sense == 2: Edge, high-to-low change | ||
| 145 | // | ||
| 146 | ipic: interrupt-controller@c00 { | ||
| 147 | compatible = "fsl,mpc5121-ipic", "fsl,ipic"; | ||
| 148 | interrupt-controller; | ||
| 149 | #address-cells = <0>; | ||
| 150 | #interrupt-cells = <2>; | ||
| 151 | reg = <0xc00 0x100>; | ||
| 152 | }; | ||
| 153 | |||
| 154 | rtc@a00 { // Real time clock | ||
| 155 | compatible = "fsl,mpc5121-rtc"; | ||
| 156 | reg = <0xa00 0x100>; | ||
| 157 | interrupts = <79 0x8 80 0x8>; | ||
| 158 | }; | ||
| 159 | |||
| 160 | reset@e00 { // Reset module | ||
| 161 | compatible = "fsl,mpc5121-reset"; | ||
| 162 | reg = <0xe00 0x100>; | ||
| 163 | }; | ||
| 164 | |||
| 165 | clock@f00 { // Clock control | ||
| 166 | compatible = "fsl,mpc5121-clock"; | ||
| 167 | reg = <0xf00 0x100>; | ||
| 168 | }; | ||
| 169 | |||
| 170 | pmc@1000{ //Power Management Controller | ||
| 171 | compatible = "fsl,mpc5121-pmc"; | ||
| 172 | reg = <0x1000 0x100>; | ||
| 173 | interrupts = <83 0x2>; | ||
| 174 | }; | ||
| 175 | |||
| 176 | gpio@1100 { | ||
| 177 | compatible = "fsl,mpc5121-gpio"; | ||
| 178 | reg = <0x1100 0x100>; | ||
| 179 | interrupts = <78 0x8>; | ||
| 180 | }; | ||
| 181 | |||
| 182 | can@1300 { | ||
| 183 | compatible = "fsl,mpc5121-mscan"; | ||
| 184 | interrupts = <12 0x8>; | ||
| 185 | reg = <0x1300 0x80>; | ||
| 186 | }; | ||
| 187 | |||
| 188 | can@1380 { | ||
| 189 | compatible = "fsl,mpc5121-mscan"; | ||
| 190 | interrupts = <13 0x8>; | ||
| 191 | reg = <0x1380 0x80>; | ||
| 192 | }; | ||
| 193 | |||
| 194 | i2c@1700 { | ||
| 195 | #address-cells = <1>; | ||
| 196 | #size-cells = <0>; | ||
| 197 | compatible = "fsl,mpc5121-i2c"; | ||
| 198 | reg = <0x1700 0x20>; | ||
| 199 | interrupts = <0x9 0x8>; | ||
| 200 | fsl,preserve-clocking; | ||
| 201 | |||
| 202 | eeprom@50 { | ||
| 203 | compatible = "at,24c01"; | ||
| 204 | reg = <0x50>; | ||
| 205 | }; | ||
| 206 | |||
| 207 | rtc@68 { | ||
| 208 | compatible = "stm,m41t00"; | ||
| 209 | reg = <0x68>; | ||
| 210 | }; | ||
| 211 | }; | ||
| 212 | |||
| 213 | i2c@1740 { | ||
| 214 | #address-cells = <1>; | ||
| 215 | #size-cells = <0>; | ||
| 216 | compatible = "fsl,mpc5121-i2c"; | ||
| 217 | reg = <0x1740 0x20>; | ||
| 218 | interrupts = <0xb 0x8>; | ||
| 219 | fsl,preserve-clocking; | ||
| 220 | }; | ||
| 221 | |||
| 222 | i2ccontrol@1760 { | ||
| 223 | compatible = "fsl,mpc5121-i2c-ctrl"; | ||
| 224 | reg = <0x1760 0x8>; | ||
| 225 | }; | ||
| 226 | |||
| 227 | axe@2000 { | ||
| 228 | compatible = "fsl,mpc5121-axe"; | ||
| 229 | reg = <0x2000 0x100>; | ||
| 230 | interrupts = <42 0x8>; | ||
| 231 | }; | ||
| 232 | |||
| 233 | display@2100 { | ||
| 234 | compatible = "fsl,mpc5121-diu"; | ||
| 235 | reg = <0x2100 0x100>; | ||
| 236 | interrupts = <64 0x8>; | ||
| 237 | }; | ||
| 238 | |||
| 239 | can@2300 { | ||
| 240 | compatible = "fsl,mpc5121-mscan"; | ||
| 241 | interrupts = <90 0x8>; | ||
| 242 | reg = <0x2300 0x80>; | ||
| 243 | }; | ||
| 244 | |||
| 245 | can@2380 { | ||
| 246 | compatible = "fsl,mpc5121-mscan"; | ||
| 247 | interrupts = <91 0x8>; | ||
| 248 | reg = <0x2380 0x80>; | ||
| 249 | }; | ||
| 250 | |||
| 251 | viu@2400 { | ||
| 252 | compatible = "fsl,mpc5121-viu"; | ||
| 253 | reg = <0x2400 0x400>; | ||
| 254 | interrupts = <67 0x8>; | ||
| 255 | }; | ||
| 256 | |||
| 257 | mdio@2800 { | ||
| 258 | compatible = "fsl,mpc5121-fec-mdio"; | ||
| 259 | reg = <0x2800 0x200>; | ||
| 260 | #address-cells = <1>; | ||
| 261 | #size-cells = <0>; | ||
| 262 | phy: ethernet-phy@0 { | ||
| 263 | compatible = "smsc,lan8700"; | ||
| 264 | reg = <0x1f>; | ||
| 265 | }; | ||
| 266 | }; | ||
| 267 | |||
| 268 | eth0: ethernet@2800 { | ||
| 269 | compatible = "fsl,mpc5121-fec"; | ||
| 270 | reg = <0x2800 0x200>; | ||
| 271 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 272 | interrupts = <4 0x8>; | ||
| 273 | phy-handle = < &phy >; | ||
| 274 | }; | ||
| 275 | |||
| 276 | // USB1 using external ULPI PHY | ||
| 277 | usb@3000 { | ||
| 278 | compatible = "fsl,mpc5121-usb2-dr"; | ||
| 279 | reg = <0x3000 0x600>; | ||
| 280 | #address-cells = <1>; | ||
| 281 | #size-cells = <0>; | ||
| 282 | interrupts = <43 0x8>; | ||
| 283 | dr_mode = "host"; | ||
| 284 | phy_type = "ulpi"; | ||
| 285 | }; | ||
| 286 | |||
| 287 | // USB0 using internal UTMI PHY | ||
| 288 | usb@4000 { | ||
| 289 | compatible = "fsl,mpc5121-usb2-dr"; | ||
| 290 | reg = <0x4000 0x600>; | ||
| 291 | #address-cells = <1>; | ||
| 292 | #size-cells = <0>; | ||
| 293 | interrupts = <44 0x8>; | ||
| 294 | dr_mode = "otg"; | ||
| 295 | phy_type = "utmi_wide"; | ||
| 296 | fsl,invert-pwr-fault; | ||
| 297 | }; | ||
| 298 | |||
| 299 | // IO control | ||
| 300 | ioctl@a000 { | ||
| 301 | compatible = "fsl,mpc5121-ioctl"; | ||
| 302 | reg = <0xA000 0x1000>; | ||
| 303 | }; | ||
| 304 | |||
| 305 | // 512x PSCs are not 52xx PSCs compatible | ||
| 306 | serial@11000 { | ||
| 307 | compatible = "fsl,mpc5121-psc-uart", "fsl,mpc5121-psc"; | ||
| 308 | cell-index = <0>; | ||
| 309 | reg = <0x11000 0x100>; | ||
| 310 | interrupts = <40 0x8>; | ||
| 311 | fsl,rx-fifo-size = <16>; | ||
| 312 | fsl,tx-fifo-size = <16>; | ||
| 313 | }; | ||
| 314 | |||
| 315 | serial@11100 { | ||
| 316 | compatible = "fsl,mpc5121-psc-uart", "fsl,mpc5121-psc"; | ||
| 317 | cell-index = <1>; | ||
| 318 | reg = <0x11100 0x100>; | ||
| 319 | interrupts = <40 0x8>; | ||
| 320 | fsl,rx-fifo-size = <16>; | ||
| 321 | fsl,tx-fifo-size = <16>; | ||
| 322 | }; | ||
| 323 | |||
| 324 | serial@11200 { | ||
| 325 | compatible = "fsl,mpc5121-psc-uart", "fsl,mpc5121-psc"; | ||
| 326 | cell-index = <2>; | ||
| 327 | reg = <0x11200 0x100>; | ||
| 328 | interrupts = <40 0x8>; | ||
| 329 | fsl,rx-fifo-size = <16>; | ||
| 330 | fsl,tx-fifo-size = <16>; | ||
| 331 | }; | ||
| 332 | |||
| 333 | serial@11300 { | ||
| 334 | compatible = "fsl,mpc5121-psc-uart", "fsl,mpc5121-psc"; | ||
| 335 | cell-index = <3>; | ||
| 336 | reg = <0x11300 0x100>; | ||
| 337 | interrupts = <40 0x8>; | ||
| 338 | fsl,rx-fifo-size = <16>; | ||
| 339 | fsl,tx-fifo-size = <16>; | ||
| 340 | }; | ||
| 341 | |||
| 342 | serial@11400 { | ||
| 343 | compatible = "fsl,mpc5121-psc-uart", "fsl,mpc5121-psc"; | ||
| 344 | cell-index = <4>; | ||
| 345 | reg = <0x11400 0x100>; | ||
| 346 | interrupts = <40 0x8>; | ||
| 347 | fsl,rx-fifo-size = <16>; | ||
| 348 | fsl,tx-fifo-size = <16>; | ||
| 349 | }; | ||
| 350 | |||
| 351 | serial@11600 { | ||
| 352 | compatible = "fsl,mpc5121-psc-uart", "fsl,mpc5121-psc"; | ||
| 353 | cell-index = <6>; | ||
| 354 | reg = <0x11600 0x100>; | ||
| 355 | interrupts = <40 0x8>; | ||
| 356 | fsl,rx-fifo-size = <16>; | ||
| 357 | fsl,tx-fifo-size = <16>; | ||
| 358 | }; | ||
| 359 | |||
| 360 | serial@11800 { | ||
| 361 | compatible = "fsl,mpc5121-psc-uart", "fsl,mpc5121-psc"; | ||
| 362 | cell-index = <8>; | ||
| 363 | reg = <0x11800 0x100>; | ||
| 364 | interrupts = <40 0x8>; | ||
| 365 | fsl,rx-fifo-size = <16>; | ||
| 366 | fsl,tx-fifo-size = <16>; | ||
| 367 | }; | ||
| 368 | |||
| 369 | serial@11B00 { | ||
| 370 | compatible = "fsl,mpc5121-psc-uart", "fsl,mpc5121-psc"; | ||
| 371 | cell-index = <11>; | ||
| 372 | reg = <0x11B00 0x100>; | ||
| 373 | interrupts = <40 0x8>; | ||
| 374 | fsl,rx-fifo-size = <16>; | ||
| 375 | fsl,tx-fifo-size = <16>; | ||
| 376 | }; | ||
| 377 | |||
| 378 | pscfifo@11f00 { | ||
| 379 | compatible = "fsl,mpc5121-psc-fifo"; | ||
| 380 | reg = <0x11f00 0x100>; | ||
| 381 | interrupts = <40 0x8>; | ||
| 382 | }; | ||
| 383 | |||
| 384 | spi@11900 { | ||
| 385 | compatible = "fsl,mpc5121-psc-spi", "fsl,mpc5121-psc"; | ||
| 386 | cell-index = <9>; | ||
| 387 | #address-cells = <1>; | ||
| 388 | #size-cells = <0>; | ||
| 389 | reg = <0x11900 0x100>; | ||
| 390 | interrupts = <40 0x8>; | ||
| 391 | fsl,rx-fifo-size = <16>; | ||
| 392 | fsl,tx-fifo-size = <16>; | ||
| 393 | |||
| 394 | // 7845 touch screen controller | ||
| 395 | ts@0 { | ||
| 396 | compatible = "ti,ads7846"; | ||
| 397 | reg = <0x0>; | ||
| 398 | spi-max-frequency = <3000000>; | ||
| 399 | // pen irq is GPIO25 | ||
| 400 | interrupts = <78 0x8>; | ||
| 401 | }; | ||
| 402 | }; | ||
| 403 | |||
| 404 | dma@14000 { | ||
| 405 | compatible = "fsl,mpc5121-dma"; | ||
| 406 | reg = <0x14000 0x1800>; | ||
| 407 | interrupts = <65 0x8>; | ||
| 408 | }; | ||
| 409 | }; | ||
| 410 | }; | ||
diff --git a/arch/powerpc/boot/dts/stxssa8555.dts b/arch/powerpc/boot/dts/stxssa8555.dts new file mode 100644 index 000000000000..49efd44057d7 --- /dev/null +++ b/arch/powerpc/boot/dts/stxssa8555.dts | |||
| @@ -0,0 +1,380 @@ | |||
| 1 | /* | ||
| 2 | * MPC8555-based STx GP3 Device Tree Source | ||
| 3 | * | ||
| 4 | * Copyright 2006, 2008 Freescale Semiconductor Inc. | ||
| 5 | * | ||
| 6 | * Copyright 2010 Silicon Turnkey Express LLC. | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify it | ||
| 9 | * under the terms of the GNU General Public License as published by the | ||
| 10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 11 | * option) any later version. | ||
| 12 | */ | ||
| 13 | |||
| 14 | /dts-v1/; | ||
| 15 | |||
| 16 | / { | ||
| 17 | model = "stx,gp3"; | ||
| 18 | compatible = "stx,gp3-8560", "stx,gp3"; | ||
| 19 | #address-cells = <1>; | ||
| 20 | #size-cells = <1>; | ||
| 21 | |||
| 22 | aliases { | ||
| 23 | ethernet0 = &enet0; | ||
| 24 | ethernet1 = &enet1; | ||
| 25 | serial0 = &serial0; | ||
| 26 | serial1 = &serial1; | ||
| 27 | pci0 = &pci0; | ||
| 28 | }; | ||
| 29 | |||
| 30 | cpus { | ||
| 31 | #address-cells = <1>; | ||
| 32 | #size-cells = <0>; | ||
| 33 | |||
| 34 | PowerPC,8555@0 { | ||
| 35 | device_type = "cpu"; | ||
| 36 | reg = <0x0>; | ||
| 37 | d-cache-line-size = <32>; // 32 bytes | ||
| 38 | i-cache-line-size = <32>; // 32 bytes | ||
| 39 | d-cache-size = <0x8000>; // L1, 32K | ||
| 40 | i-cache-size = <0x8000>; // L1, 32K | ||
| 41 | timebase-frequency = <0>; // 33 MHz, from uboot | ||
| 42 | bus-frequency = <0>; // 166 MHz | ||
| 43 | clock-frequency = <0>; // 825 MHz, from uboot | ||
| 44 | next-level-cache = <&L2>; | ||
| 45 | }; | ||
| 46 | }; | ||
| 47 | |||
| 48 | memory { | ||
| 49 | device_type = "memory"; | ||
| 50 | reg = <0x00000000 0x10000000>; | ||
| 51 | }; | ||
| 52 | |||
| 53 | soc8555@e0000000 { | ||
| 54 | #address-cells = <1>; | ||
| 55 | #size-cells = <1>; | ||
| 56 | device_type = "soc"; | ||
| 57 | compatible = "simple-bus"; | ||
| 58 | ranges = <0x0 0xe0000000 0x100000>; | ||
| 59 | bus-frequency = <0>; | ||
| 60 | |||
| 61 | ecm-law@0 { | ||
| 62 | compatible = "fsl,ecm-law"; | ||
| 63 | reg = <0x0 0x1000>; | ||
| 64 | fsl,num-laws = <8>; | ||
| 65 | }; | ||
| 66 | |||
| 67 | ecm@1000 { | ||
| 68 | compatible = "fsl,mpc8555-ecm", "fsl,ecm"; | ||
| 69 | reg = <0x1000 0x1000>; | ||
| 70 | interrupts = <17 2>; | ||
| 71 | interrupt-parent = <&mpic>; | ||
| 72 | }; | ||
| 73 | |||
| 74 | memory-controller@2000 { | ||
| 75 | compatible = "fsl,mpc8555-memory-controller"; | ||
| 76 | reg = <0x2000 0x1000>; | ||
| 77 | interrupt-parent = <&mpic>; | ||
| 78 | interrupts = <18 2>; | ||
| 79 | }; | ||
| 80 | |||
| 81 | L2: l2-cache-controller@20000 { | ||
| 82 | compatible = "fsl,mpc8555-l2-cache-controller"; | ||
| 83 | reg = <0x20000 0x1000>; | ||
| 84 | cache-line-size = <32>; // 32 bytes | ||
| 85 | cache-size = <0x40000>; // L2, 256K | ||
| 86 | interrupt-parent = <&mpic>; | ||
| 87 | interrupts = <16 2>; | ||
| 88 | }; | ||
| 89 | |||
| 90 | i2c@3000 { | ||
| 91 | #address-cells = <1>; | ||
| 92 | #size-cells = <0>; | ||
| 93 | cell-index = <0>; | ||
| 94 | compatible = "fsl-i2c"; | ||
| 95 | reg = <0x3000 0x100>; | ||
| 96 | interrupts = <43 2>; | ||
| 97 | interrupt-parent = <&mpic>; | ||
| 98 | dfsrr; | ||
| 99 | }; | ||
| 100 | |||
| 101 | dma@21300 { | ||
| 102 | #address-cells = <1>; | ||
| 103 | #size-cells = <1>; | ||
| 104 | compatible = "fsl,mpc8555-dma", "fsl,eloplus-dma"; | ||
| 105 | reg = <0x21300 0x4>; | ||
| 106 | ranges = <0x0 0x21100 0x200>; | ||
| 107 | cell-index = <0>; | ||
| 108 | dma-channel@0 { | ||
| 109 | compatible = "fsl,mpc8555-dma-channel", | ||
| 110 | "fsl,eloplus-dma-channel"; | ||
| 111 | reg = <0x0 0x80>; | ||
| 112 | cell-index = <0>; | ||
| 113 | interrupt-parent = <&mpic>; | ||
| 114 | interrupts = <20 2>; | ||
| 115 | }; | ||
| 116 | dma-channel@80 { | ||
| 117 | compatible = "fsl,mpc8555-dma-channel", | ||
| 118 | "fsl,eloplus-dma-channel"; | ||
| 119 | reg = <0x80 0x80>; | ||
| 120 | cell-index = <1>; | ||
| 121 | interrupt-parent = <&mpic>; | ||
| 122 | interrupts = <21 2>; | ||
| 123 | }; | ||
| 124 | dma-channel@100 { | ||
| 125 | compatible = "fsl,mpc8555-dma-channel", | ||
| 126 | "fsl,eloplus-dma-channel"; | ||
| 127 | reg = <0x100 0x80>; | ||
| 128 | cell-index = <2>; | ||
| 129 | interrupt-parent = <&mpic>; | ||
| 130 | interrupts = <22 2>; | ||
| 131 | }; | ||
| 132 | dma-channel@180 { | ||
| 133 | compatible = "fsl,mpc8555-dma-channel", | ||
| 134 | "fsl,eloplus-dma-channel"; | ||
| 135 | reg = <0x180 0x80>; | ||
| 136 | cell-index = <3>; | ||
| 137 | interrupt-parent = <&mpic>; | ||
| 138 | interrupts = <23 2>; | ||
| 139 | }; | ||
| 140 | }; | ||
| 141 | |||
| 142 | enet0: ethernet@24000 { | ||
| 143 | #address-cells = <1>; | ||
| 144 | #size-cells = <1>; | ||
| 145 | cell-index = <0>; | ||
| 146 | device_type = "network"; | ||
| 147 | model = "TSEC"; | ||
| 148 | compatible = "gianfar"; | ||
| 149 | reg = <0x24000 0x1000>; | ||
| 150 | ranges = <0x0 0x24000 0x1000>; | ||
| 151 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 152 | interrupts = <29 2 30 2 34 2>; | ||
| 153 | interrupt-parent = <&mpic>; | ||
| 154 | tbi-handle = <&tbi0>; | ||
| 155 | phy-handle = <&phy0>; | ||
| 156 | |||
| 157 | mdio@520 { | ||
| 158 | #address-cells = <1>; | ||
| 159 | #size-cells = <0>; | ||
| 160 | compatible = "fsl,gianfar-mdio"; | ||
| 161 | reg = <0x520 0x20>; | ||
| 162 | |||
| 163 | phy0: ethernet-phy@2 { | ||
| 164 | interrupt-parent = <&mpic>; | ||
| 165 | interrupts = <5 1>; | ||
| 166 | reg = <0x2>; | ||
| 167 | device_type = "ethernet-phy"; | ||
| 168 | }; | ||
| 169 | phy1: ethernet-phy@4 { | ||
| 170 | interrupt-parent = <&mpic>; | ||
| 171 | interrupts = <5 1>; | ||
| 172 | reg = <0x4>; | ||
| 173 | device_type = "ethernet-phy"; | ||
| 174 | }; | ||
| 175 | tbi0: tbi-phy@11 { | ||
| 176 | reg = <0x11>; | ||
| 177 | device_type = "tbi-phy"; | ||
| 178 | }; | ||
| 179 | }; | ||
| 180 | }; | ||
| 181 | |||
| 182 | enet1: ethernet@25000 { | ||
| 183 | #address-cells = <1>; | ||
| 184 | #size-cells = <1>; | ||
| 185 | cell-index = <1>; | ||
| 186 | device_type = "network"; | ||
| 187 | model = "TSEC"; | ||
| 188 | compatible = "gianfar"; | ||
| 189 | reg = <0x25000 0x1000>; | ||
| 190 | ranges = <0x0 0x25000 0x1000>; | ||
| 191 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 192 | interrupts = <35 2 36 2 40 2>; | ||
| 193 | interrupt-parent = <&mpic>; | ||
| 194 | tbi-handle = <&tbi1>; | ||
| 195 | phy-handle = <&phy1>; | ||
| 196 | |||
| 197 | mdio@520 { | ||
| 198 | #address-cells = <1>; | ||
| 199 | #size-cells = <0>; | ||
| 200 | compatible = "fsl,gianfar-tbi"; | ||
| 201 | reg = <0x520 0x20>; | ||
| 202 | |||
| 203 | tbi1: tbi-phy@11 { | ||
| 204 | reg = <0x11>; | ||
| 205 | device_type = "tbi-phy"; | ||
| 206 | }; | ||
| 207 | }; | ||
| 208 | }; | ||
| 209 | |||
| 210 | serial0: serial@4500 { | ||
| 211 | cell-index = <0>; | ||
| 212 | device_type = "serial"; | ||
| 213 | compatible = "ns16550"; | ||
| 214 | reg = <0x4500 0x100>; // reg base, size | ||
| 215 | clock-frequency = <0>; // should we fill in in uboot? | ||
| 216 | interrupts = <42 2>; | ||
| 217 | interrupt-parent = <&mpic>; | ||
| 218 | }; | ||
| 219 | |||
| 220 | serial1: serial@4600 { | ||
| 221 | cell-index = <1>; | ||
| 222 | device_type = "serial"; | ||
| 223 | compatible = "ns16550"; | ||
| 224 | reg = <0x4600 0x100>; // reg base, size | ||
| 225 | clock-frequency = <0>; // should we fill in in uboot? | ||
| 226 | interrupts = <42 2>; | ||
| 227 | interrupt-parent = <&mpic>; | ||
| 228 | }; | ||
| 229 | |||
| 230 | crypto@30000 { | ||
| 231 | compatible = "fsl,sec2.0"; | ||
| 232 | reg = <0x30000 0x10000>; | ||
| 233 | interrupts = <45 2>; | ||
| 234 | interrupt-parent = <&mpic>; | ||
| 235 | fsl,num-channels = <4>; | ||
| 236 | fsl,channel-fifo-len = <24>; | ||
| 237 | fsl,exec-units-mask = <0x7e>; | ||
| 238 | fsl,descriptor-types-mask = <0x01010ebf>; | ||
| 239 | }; | ||
| 240 | |||
| 241 | mpic: pic@40000 { | ||
| 242 | interrupt-controller; | ||
| 243 | #address-cells = <0>; | ||
| 244 | #interrupt-cells = <2>; | ||
| 245 | reg = <0x40000 0x40000>; | ||
| 246 | compatible = "chrp,open-pic"; | ||
| 247 | device_type = "open-pic"; | ||
| 248 | }; | ||
| 249 | |||
| 250 | cpm@919c0 { | ||
| 251 | #address-cells = <1>; | ||
| 252 | #size-cells = <1>; | ||
| 253 | compatible = "fsl,mpc8555-cpm", "fsl,cpm2"; | ||
| 254 | reg = <0x919c0 0x30>; | ||
| 255 | ranges; | ||
| 256 | |||
| 257 | muram@80000 { | ||
| 258 | #address-cells = <1>; | ||
| 259 | #size-cells = <1>; | ||
| 260 | ranges = <0x0 0x80000 0x10000>; | ||
| 261 | |||
| 262 | data@0 { | ||
| 263 | compatible = "fsl,cpm-muram-data"; | ||
| 264 | reg = <0x0 0x2000 0x9000 0x1000>; | ||
| 265 | }; | ||
| 266 | }; | ||
| 267 | |||
| 268 | brg@919f0 { | ||
| 269 | compatible = "fsl,mpc8555-brg", | ||
| 270 | "fsl,cpm2-brg", | ||
| 271 | "fsl,cpm-brg"; | ||
| 272 | reg = <0x919f0 0x10 0x915f0 0x10>; | ||
| 273 | }; | ||
| 274 | |||
| 275 | cpmpic: pic@90c00 { | ||
| 276 | interrupt-controller; | ||
| 277 | #address-cells = <0>; | ||
| 278 | #interrupt-cells = <2>; | ||
| 279 | interrupts = <46 2>; | ||
| 280 | interrupt-parent = <&mpic>; | ||
| 281 | reg = <0x90c00 0x80>; | ||
| 282 | compatible = "fsl,mpc8555-cpm-pic", "fsl,cpm2-pic"; | ||
| 283 | }; | ||
| 284 | }; | ||
| 285 | }; | ||
| 286 | |||
| 287 | pci0: pci@e0008000 { | ||
| 288 | interrupt-map-mask = <0x1f800 0x0 0x0 0x7>; | ||
| 289 | interrupt-map = < | ||
| 290 | |||
| 291 | /* IDSEL 0x10 */ | ||
| 292 | 0x8000 0x0 0x0 0x1 &mpic 0x0 0x1 | ||
| 293 | 0x8000 0x0 0x0 0x2 &mpic 0x1 0x1 | ||
| 294 | 0x8000 0x0 0x0 0x3 &mpic 0x2 0x1 | ||
| 295 | 0x8000 0x0 0x0 0x4 &mpic 0x3 0x1 | ||
| 296 | |||
| 297 | /* IDSEL 0x11 */ | ||
| 298 | 0x8800 0x0 0x0 0x1 &mpic 0x0 0x1 | ||
| 299 | 0x8800 0x0 0x0 0x2 &mpic 0x1 0x1 | ||
| 300 | 0x8800 0x0 0x0 0x3 &mpic 0x2 0x1 | ||
| 301 | 0x8800 0x0 0x0 0x4 &mpic 0x3 0x1 | ||
| 302 | |||
| 303 | /* IDSEL 0x12 (Slot 1) */ | ||
| 304 | 0x9000 0x0 0x0 0x1 &mpic 0x0 0x1 | ||
| 305 | 0x9000 0x0 0x0 0x2 &mpic 0x1 0x1 | ||
| 306 | 0x9000 0x0 0x0 0x3 &mpic 0x2 0x1 | ||
| 307 | 0x9000 0x0 0x0 0x4 &mpic 0x3 0x1 | ||
| 308 | |||
| 309 | /* IDSEL 0x13 (Slot 2) */ | ||
| 310 | 0x9800 0x0 0x0 0x1 &mpic 0x1 0x1 | ||
| 311 | 0x9800 0x0 0x0 0x2 &mpic 0x2 0x1 | ||
| 312 | 0x9800 0x0 0x0 0x3 &mpic 0x3 0x1 | ||
| 313 | 0x9800 0x0 0x0 0x4 &mpic 0x0 0x1 | ||
| 314 | |||
| 315 | /* IDSEL 0x14 (Slot 3) */ | ||
| 316 | 0xa000 0x0 0x0 0x1 &mpic 0x2 0x1 | ||
| 317 | 0xa000 0x0 0x0 0x2 &mpic 0x3 0x1 | ||
| 318 | 0xa000 0x0 0x0 0x3 &mpic 0x0 0x1 | ||
| 319 | 0xa000 0x0 0x0 0x4 &mpic 0x1 0x1 | ||
| 320 | |||
| 321 | /* IDSEL 0x15 (Slot 4) */ | ||
| 322 | 0xa800 0x0 0x0 0x1 &mpic 0x3 0x1 | ||
| 323 | 0xa800 0x0 0x0 0x2 &mpic 0x0 0x1 | ||
| 324 | 0xa800 0x0 0x0 0x3 &mpic 0x1 0x1 | ||
| 325 | 0xa800 0x0 0x0 0x4 &mpic 0x2 0x1 | ||
| 326 | |||
| 327 | /* Bus 1 (Tundra Bridge) */ | ||
| 328 | /* IDSEL 0x12 (ISA bridge) */ | ||
| 329 | 0x19000 0x0 0x0 0x1 &mpic 0x0 0x1 | ||
| 330 | 0x19000 0x0 0x0 0x2 &mpic 0x1 0x1 | ||
| 331 | 0x19000 0x0 0x0 0x3 &mpic 0x2 0x1 | ||
| 332 | 0x19000 0x0 0x0 0x4 &mpic 0x3 0x1>; | ||
| 333 | interrupt-parent = <&mpic>; | ||
| 334 | interrupts = <24 2>; | ||
| 335 | bus-range = <0 0>; | ||
| 336 | ranges = <0x2000000 0x0 0x80000000 0x80000000 0x0 0x20000000 | ||
| 337 | 0x1000000 0x0 0x0 0xe2000000 0x0 0x100000>; | ||
| 338 | clock-frequency = <66666666>; | ||
| 339 | #interrupt-cells = <1>; | ||
| 340 | #size-cells = <2>; | ||
| 341 | #address-cells = <3>; | ||
| 342 | reg = <0xe0008000 0x1000>; | ||
| 343 | compatible = "fsl,mpc8540-pci"; | ||
| 344 | device_type = "pci"; | ||
| 345 | |||
| 346 | i8259@19000 { | ||
| 347 | interrupt-controller; | ||
| 348 | device_type = "interrupt-controller"; | ||
| 349 | reg = <0x19000 0x0 0x0 0x0 0x1>; | ||
| 350 | #address-cells = <0>; | ||
| 351 | #interrupt-cells = <2>; | ||
| 352 | compatible = "chrp,iic"; | ||
| 353 | interrupts = <1>; | ||
| 354 | interrupt-parent = <&pci0>; | ||
| 355 | }; | ||
| 356 | }; | ||
| 357 | |||
| 358 | pci1: pci@e0009000 { | ||
| 359 | interrupt-map-mask = <0xf800 0x0 0x0 0x7>; | ||
| 360 | interrupt-map = < | ||
| 361 | |||
| 362 | /* IDSEL 0x15 */ | ||
| 363 | 0xa800 0x0 0x0 0x1 &mpic 0xb 0x1 | ||
| 364 | 0xa800 0x0 0x0 0x2 &mpic 0xb 0x1 | ||
| 365 | 0xa800 0x0 0x0 0x3 &mpic 0xb 0x1 | ||
| 366 | 0xa800 0x0 0x0 0x4 &mpic 0xb 0x1>; | ||
| 367 | interrupt-parent = <&mpic>; | ||
| 368 | interrupts = <25 2>; | ||
| 369 | bus-range = <0 0>; | ||
| 370 | ranges = <0x2000000 0x0 0xa0000000 0xa0000000 0x0 0x20000000 | ||
| 371 | 0x1000000 0x0 0x0 0xe3000000 0x0 0x100000>; | ||
| 372 | clock-frequency = <66666666>; | ||
| 373 | #interrupt-cells = <1>; | ||
| 374 | #size-cells = <2>; | ||
| 375 | #address-cells = <3>; | ||
| 376 | reg = <0xe0009000 0x1000>; | ||
| 377 | compatible = "fsl,mpc8540-pci"; | ||
| 378 | device_type = "pci"; | ||
| 379 | }; | ||
| 380 | }; | ||
diff --git a/arch/powerpc/boot/dts/tqm8540.dts b/arch/powerpc/boot/dts/tqm8540.dts index 71347537b83e..15ca731bc24e 100644 --- a/arch/powerpc/boot/dts/tqm8540.dts +++ b/arch/powerpc/boot/dts/tqm8540.dts | |||
| @@ -289,7 +289,14 @@ | |||
| 289 | interrupt-map = < | 289 | interrupt-map = < |
| 290 | /* IDSEL 28 */ | 290 | /* IDSEL 28 */ |
| 291 | 0xe000 0 0 1 &mpic 2 1 | 291 | 0xe000 0 0 1 &mpic 2 1 |
| 292 | 0xe000 0 0 2 &mpic 3 1>; | 292 | 0xe000 0 0 2 &mpic 3 1 |
| 293 | 0xe000 0 0 3 &mpic 6 1 | ||
| 294 | 0xe000 0 0 4 &mpic 5 1 | ||
| 295 | |||
| 296 | /* IDSEL 11 */ | ||
| 297 | 0x5800 0 0 1 &mpic 6 1 | ||
| 298 | 0x5800 0 0 2 &mpic 5 1 | ||
| 299 | >; | ||
| 293 | 300 | ||
| 294 | interrupt-parent = <&mpic>; | 301 | interrupt-parent = <&mpic>; |
| 295 | interrupts = <24 2>; | 302 | interrupts = <24 2>; |
diff --git a/arch/powerpc/boot/dts/tqm8541.dts b/arch/powerpc/boot/dts/tqm8541.dts index b30f63753d41..f49d09181312 100644 --- a/arch/powerpc/boot/dts/tqm8541.dts +++ b/arch/powerpc/boot/dts/tqm8541.dts | |||
| @@ -311,7 +311,14 @@ | |||
| 311 | interrupt-map = < | 311 | interrupt-map = < |
| 312 | /* IDSEL 28 */ | 312 | /* IDSEL 28 */ |
| 313 | 0xe000 0 0 1 &mpic 2 1 | 313 | 0xe000 0 0 1 &mpic 2 1 |
| 314 | 0xe000 0 0 2 &mpic 3 1>; | 314 | 0xe000 0 0 2 &mpic 3 1 |
| 315 | 0xe000 0 0 3 &mpic 6 1 | ||
| 316 | 0xe000 0 0 4 &mpic 5 1 | ||
| 317 | |||
| 318 | /* IDSEL 11 */ | ||
| 319 | 0x5800 0 0 1 &mpic 6 1 | ||
| 320 | 0x5800 0 0 2 &mpic 5 1 | ||
| 321 | >; | ||
| 315 | 322 | ||
| 316 | interrupt-parent = <&mpic>; | 323 | interrupt-parent = <&mpic>; |
| 317 | interrupts = <24 2>; | 324 | interrupts = <24 2>; |
diff --git a/arch/powerpc/boot/dts/tqm8548-bigflash.dts b/arch/powerpc/boot/dts/tqm8548-bigflash.dts index 61f25e15fd66..5dbb36edb038 100644 --- a/arch/powerpc/boot/dts/tqm8548-bigflash.dts +++ b/arch/powerpc/boot/dts/tqm8548-bigflash.dts | |||
| @@ -442,7 +442,14 @@ | |||
| 442 | interrupt-map = < | 442 | interrupt-map = < |
| 443 | /* IDSEL 28 */ | 443 | /* IDSEL 28 */ |
| 444 | 0xe000 0 0 1 &mpic 2 1 | 444 | 0xe000 0 0 1 &mpic 2 1 |
| 445 | 0xe000 0 0 2 &mpic 3 1>; | 445 | 0xe000 0 0 2 &mpic 3 1 |
| 446 | 0xe000 0 0 3 &mpic 6 1 | ||
| 447 | 0xe000 0 0 4 &mpic 5 1 | ||
| 448 | |||
| 449 | /* IDSEL 11 */ | ||
| 450 | 0x5800 0 0 1 &mpic 6 1 | ||
| 451 | 0x5800 0 0 2 &mpic 5 1 | ||
| 452 | >; | ||
| 446 | 453 | ||
| 447 | interrupt-parent = <&mpic>; | 454 | interrupt-parent = <&mpic>; |
| 448 | interrupts = <24 2>; | 455 | interrupts = <24 2>; |
diff --git a/arch/powerpc/boot/dts/tqm8548.dts b/arch/powerpc/boot/dts/tqm8548.dts index 025759c7c955..a050ae427108 100644 --- a/arch/powerpc/boot/dts/tqm8548.dts +++ b/arch/powerpc/boot/dts/tqm8548.dts | |||
| @@ -442,7 +442,14 @@ | |||
| 442 | interrupt-map = < | 442 | interrupt-map = < |
| 443 | /* IDSEL 28 */ | 443 | /* IDSEL 28 */ |
| 444 | 0xe000 0 0 1 &mpic 2 1 | 444 | 0xe000 0 0 1 &mpic 2 1 |
| 445 | 0xe000 0 0 2 &mpic 3 1>; | 445 | 0xe000 0 0 2 &mpic 3 1 |
| 446 | 0xe000 0 0 3 &mpic 6 1 | ||
| 447 | 0xe000 0 0 4 &mpic 5 1 | ||
| 448 | |||
| 449 | /* IDSEL 11 */ | ||
| 450 | 0x5800 0 0 1 &mpic 6 1 | ||
| 451 | 0x5800 0 0 2 &mpic 5 1 | ||
| 452 | >; | ||
| 446 | 453 | ||
| 447 | interrupt-parent = <&mpic>; | 454 | interrupt-parent = <&mpic>; |
| 448 | interrupts = <24 2>; | 455 | interrupts = <24 2>; |
diff --git a/arch/powerpc/boot/dts/tqm8555.dts b/arch/powerpc/boot/dts/tqm8555.dts index 95e287381836..81bad8cd3756 100644 --- a/arch/powerpc/boot/dts/tqm8555.dts +++ b/arch/powerpc/boot/dts/tqm8555.dts | |||
| @@ -311,7 +311,14 @@ | |||
| 311 | interrupt-map = < | 311 | interrupt-map = < |
| 312 | /* IDSEL 28 */ | 312 | /* IDSEL 28 */ |
| 313 | 0xe000 0 0 1 &mpic 2 1 | 313 | 0xe000 0 0 1 &mpic 2 1 |
| 314 | 0xe000 0 0 2 &mpic 3 1>; | 314 | 0xe000 0 0 2 &mpic 3 1 |
| 315 | 0xe000 0 0 3 &mpic 6 1 | ||
| 316 | 0xe000 0 0 4 &mpic 5 1 | ||
| 317 | |||
| 318 | /* IDSEL 11 */ | ||
| 319 | 0x5800 0 0 1 &mpic 6 1 | ||
| 320 | 0x5800 0 0 2 &mpic 5 1 | ||
| 321 | >; | ||
| 315 | 322 | ||
| 316 | interrupt-parent = <&mpic>; | 323 | interrupt-parent = <&mpic>; |
| 317 | interrupts = <24 2>; | 324 | interrupts = <24 2>; |
diff --git a/arch/powerpc/boot/dts/tqm8560.dts b/arch/powerpc/boot/dts/tqm8560.dts index ff70580a8f4c..22ec39b5beeb 100644 --- a/arch/powerpc/boot/dts/tqm8560.dts +++ b/arch/powerpc/boot/dts/tqm8560.dts | |||
| @@ -382,7 +382,14 @@ | |||
| 382 | interrupt-map = < | 382 | interrupt-map = < |
| 383 | /* IDSEL 28 */ | 383 | /* IDSEL 28 */ |
| 384 | 0xe000 0 0 1 &mpic 2 1 | 384 | 0xe000 0 0 1 &mpic 2 1 |
| 385 | 0xe000 0 0 2 &mpic 3 1>; | 385 | 0xe000 0 0 2 &mpic 3 1 |
| 386 | 0xe000 0 0 3 &mpic 6 1 | ||
| 387 | 0xe000 0 0 4 &mpic 5 1 | ||
| 388 | |||
| 389 | /* IDSEL 11 */ | ||
| 390 | 0x5800 0 0 1 &mpic 6 1 | ||
| 391 | 0x5800 0 0 2 &mpic 5 1 | ||
| 392 | >; | ||
| 386 | 393 | ||
| 387 | interrupt-parent = <&mpic>; | 394 | interrupt-parent = <&mpic>; |
| 388 | interrupts = <24 2>; | 395 | interrupts = <24 2>; |
diff --git a/arch/powerpc/boot/dts/tqm8xx.dts b/arch/powerpc/boot/dts/tqm8xx.dts new file mode 100644 index 000000000000..f6da7ec49a8e --- /dev/null +++ b/arch/powerpc/boot/dts/tqm8xx.dts | |||
| @@ -0,0 +1,172 @@ | |||
| 1 | /* | ||
| 2 | * TQM8XX Device Tree Source | ||
| 3 | * | ||
| 4 | * Heiko Schocher <hs@denx.de> | ||
| 5 | * 2010 DENX Software Engineering GmbH | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify it | ||
| 8 | * under the terms of the GNU General Public License as published by the | ||
| 9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 10 | * option) any later version. | ||
| 11 | */ | ||
| 12 | |||
| 13 | /dts-v1/; | ||
| 14 | |||
| 15 | / { | ||
| 16 | model = "TQM8xx"; | ||
| 17 | compatible = "tqc,tqm8xx"; | ||
| 18 | #address-cells = <1>; | ||
| 19 | #size-cells = <1>; | ||
| 20 | |||
| 21 | aliases { | ||
| 22 | ethernet0 = ð0; | ||
| 23 | ethernet1 = ð1; | ||
| 24 | mdio1 = &phy1; | ||
| 25 | serial0 = &smc1; | ||
| 26 | }; | ||
| 27 | |||
| 28 | cpus { | ||
| 29 | #address-cells = <1>; | ||
| 30 | #size-cells = <0>; | ||
| 31 | |||
| 32 | PowerPC,860@0 { | ||
| 33 | device_type = "cpu"; | ||
| 34 | reg = <0x0>; | ||
| 35 | d-cache-line-size = <16>; // 16 bytes | ||
| 36 | i-cache-line-size = <16>; // 16 bytes | ||
| 37 | d-cache-size = <0x1000>; // L1, 4K | ||
| 38 | i-cache-size = <0x1000>; // L1, 4K | ||
| 39 | timebase-frequency = <0>; | ||
| 40 | bus-frequency = <0>; | ||
| 41 | clock-frequency = <0>; | ||
| 42 | interrupts = <15 2>; // decrementer interrupt | ||
| 43 | interrupt-parent = <&PIC>; | ||
| 44 | }; | ||
| 45 | }; | ||
| 46 | |||
| 47 | memory { | ||
| 48 | device_type = "memory"; | ||
| 49 | reg = <0x0 0x2000000>; | ||
| 50 | }; | ||
| 51 | |||
| 52 | localbus@fff00100 { | ||
| 53 | compatible = "fsl,mpc860-localbus", "fsl,pq1-localbus"; | ||
| 54 | #address-cells = <2>; | ||
| 55 | #size-cells = <1>; | ||
| 56 | reg = <0xfff00100 0x40>; | ||
| 57 | |||
| 58 | ranges = < | ||
| 59 | 0x0 0x0 0x40000000 0x800000 | ||
| 60 | >; | ||
| 61 | |||
| 62 | flash@0,0 { | ||
| 63 | compatible = "cfi-flash"; | ||
| 64 | reg = <0 0 0x800000>; | ||
| 65 | #address-cells = <1>; | ||
| 66 | #size-cells = <1>; | ||
| 67 | bank-width = <4>; | ||
| 68 | device-width = <2>; | ||
| 69 | }; | ||
| 70 | }; | ||
| 71 | |||
| 72 | soc@fff00000 { | ||
| 73 | #address-cells = <1>; | ||
| 74 | #size-cells = <1>; | ||
| 75 | device_type = "soc"; | ||
| 76 | ranges = <0x0 0xfff00000 0x00004000>; | ||
| 77 | |||
| 78 | phy1: mdio@e00 { | ||
| 79 | compatible = "fsl,mpc866-fec-mdio", "fsl,pq1-fec-mdio"; | ||
| 80 | reg = <0xe00 0x188>; | ||
| 81 | #address-cells = <1>; | ||
| 82 | #size-cells = <0>; | ||
| 83 | PHY: ethernet-phy@f { | ||
| 84 | reg = <0xf>; | ||
| 85 | device_type = "ethernet-phy"; | ||
| 86 | }; | ||
| 87 | }; | ||
| 88 | |||
| 89 | eth1: ethernet@e00 { | ||
| 90 | device_type = "network"; | ||
| 91 | compatible = "fsl,mpc866-fec-enet", | ||
| 92 | "fsl,pq1-fec-enet"; | ||
| 93 | reg = <0xe00 0x188>; | ||
| 94 | interrupts = <3 1>; | ||
| 95 | interrupt-parent = <&PIC>; | ||
| 96 | phy-handle = <&PHY>; | ||
| 97 | linux,network-index = <1>; | ||
| 98 | }; | ||
| 99 | |||
| 100 | PIC: pic@0 { | ||
| 101 | interrupt-controller; | ||
| 102 | #interrupt-cells = <2>; | ||
| 103 | reg = <0x0 0x24>; | ||
| 104 | compatible = "fsl,mpc860-pic", "fsl,pq1-pic"; | ||
| 105 | }; | ||
| 106 | |||
| 107 | cpm@9c0 { | ||
| 108 | #address-cells = <1>; | ||
| 109 | #size-cells = <1>; | ||
| 110 | compatible = "fsl,mpc860-cpm", "fsl,cpm1"; | ||
| 111 | ranges; | ||
| 112 | reg = <0x9c0 0x40>; | ||
| 113 | brg-frequency = <0>; | ||
| 114 | interrupts = <0 2>; // cpm error interrupt | ||
| 115 | interrupt-parent = <&CPM_PIC>; | ||
| 116 | |||
| 117 | muram@2000 { | ||
| 118 | #address-cells = <1>; | ||
| 119 | #size-cells = <1>; | ||
| 120 | ranges = <0x0 0x2000 0x2000>; | ||
| 121 | |||
| 122 | data@0 { | ||
| 123 | compatible = "fsl,cpm-muram-data"; | ||
| 124 | reg = <0x0 0x2000>; | ||
| 125 | }; | ||
| 126 | }; | ||
| 127 | |||
| 128 | brg@9f0 { | ||
| 129 | compatible = "fsl,mpc860-brg", | ||
| 130 | "fsl,cpm1-brg", | ||
| 131 | "fsl,cpm-brg"; | ||
| 132 | reg = <0x9f0 0x10>; | ||
| 133 | clock-frequency = <0>; | ||
| 134 | }; | ||
| 135 | |||
| 136 | CPM_PIC: pic@930 { | ||
| 137 | interrupt-controller; | ||
| 138 | #address-cells = <0>; | ||
| 139 | #interrupt-cells = <1>; | ||
| 140 | interrupts = <5 2 0 2>; | ||
| 141 | interrupt-parent = <&PIC>; | ||
| 142 | reg = <0x930 0x20>; | ||
| 143 | compatible = "fsl,mpc860-cpm-pic", | ||
| 144 | "fsl,cpm1-pic"; | ||
| 145 | }; | ||
| 146 | |||
| 147 | |||
| 148 | smc1: serial@a80 { | ||
| 149 | device_type = "serial"; | ||
| 150 | compatible = "fsl,mpc860-smc-uart", | ||
| 151 | "fsl,cpm1-smc-uart"; | ||
| 152 | reg = <0xa80 0x10 0x3e80 0x40>; | ||
| 153 | interrupts = <4>; | ||
| 154 | interrupt-parent = <&CPM_PIC>; | ||
| 155 | fsl,cpm-brg = <1>; | ||
| 156 | fsl,cpm-command = <0x90>; | ||
| 157 | }; | ||
| 158 | |||
| 159 | eth0: ethernet@a00 { | ||
| 160 | device_type = "network"; | ||
| 161 | compatible = "fsl,mpc860-scc-enet", | ||
| 162 | "fsl,cpm1-scc-enet"; | ||
| 163 | reg = <0xa00 0x18 0x3c00 0x100>; | ||
| 164 | interrupts = <30>; | ||
| 165 | interrupt-parent = <&CPM_PIC>; | ||
| 166 | fsl,cpm-command = <0000>; | ||
| 167 | linux,network-index = <0>; | ||
| 168 | fixed-link = <0 0 10 0 0>; | ||
| 169 | }; | ||
| 170 | }; | ||
| 171 | }; | ||
| 172 | }; | ||
diff --git a/arch/powerpc/configs/mpc85xx_defconfig b/arch/powerpc/configs/mpc85xx_defconfig index cfebef9f9123..d32f31a03f58 100644 --- a/arch/powerpc/configs/mpc85xx_defconfig +++ b/arch/powerpc/configs/mpc85xx_defconfig | |||
| @@ -19,7 +19,8 @@ CONFIG_E500=y | |||
| 19 | CONFIG_FSL_EMB_PERFMON=y | 19 | CONFIG_FSL_EMB_PERFMON=y |
| 20 | CONFIG_BOOKE=y | 20 | CONFIG_BOOKE=y |
| 21 | CONFIG_FSL_BOOKE=y | 21 | CONFIG_FSL_BOOKE=y |
| 22 | # CONFIG_PHYS_64BIT is not set | 22 | CONFIG_PTE_64BIT=y |
| 23 | CONFIG_PHYS_64BIT=y | ||
| 23 | CONFIG_SPE=y | 24 | CONFIG_SPE=y |
| 24 | CONFIG_PPC_MMU_NOHASH=y | 25 | CONFIG_PPC_MMU_NOHASH=y |
| 25 | CONFIG_PPC_MMU_NOHASH_32=y | 26 | CONFIG_PPC_MMU_NOHASH_32=y |
| @@ -28,7 +29,7 @@ CONFIG_PPC_BOOK3E_MMU=y | |||
| 28 | # CONFIG_SMP is not set | 29 | # CONFIG_SMP is not set |
| 29 | CONFIG_PPC32=y | 30 | CONFIG_PPC32=y |
| 30 | CONFIG_WORD_SIZE=32 | 31 | CONFIG_WORD_SIZE=32 |
| 31 | # CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set | 32 | CONFIG_ARCH_PHYS_ADDR_T_64BIT=y |
| 32 | CONFIG_MMU=y | 33 | CONFIG_MMU=y |
| 33 | CONFIG_GENERIC_CMOS_UPDATE=y | 34 | CONFIG_GENERIC_CMOS_UPDATE=y |
| 34 | CONFIG_GENERIC_TIME=y | 35 | CONFIG_GENERIC_TIME=y |
| @@ -239,6 +240,7 @@ CONFIG_MPC85xx_MDS=y | |||
| 239 | CONFIG_MPC8536_DS=y | 240 | CONFIG_MPC8536_DS=y |
| 240 | CONFIG_MPC85xx_DS=y | 241 | CONFIG_MPC85xx_DS=y |
| 241 | CONFIG_MPC85xx_RDB=y | 242 | CONFIG_MPC85xx_RDB=y |
| 243 | CONFIG_P1022_DS=y | ||
| 242 | CONFIG_SOCRATES=y | 244 | CONFIG_SOCRATES=y |
| 243 | CONFIG_KSI8560=y | 245 | CONFIG_KSI8560=y |
| 244 | CONFIG_XES_MPC85xx=y | 246 | CONFIG_XES_MPC85xx=y |
| @@ -311,7 +313,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y | |||
| 311 | CONFIG_PAGEFLAGS_EXTENDED=y | 313 | CONFIG_PAGEFLAGS_EXTENDED=y |
| 312 | CONFIG_SPLIT_PTLOCK_CPUS=4 | 314 | CONFIG_SPLIT_PTLOCK_CPUS=4 |
| 313 | CONFIG_MIGRATION=y | 315 | CONFIG_MIGRATION=y |
| 314 | # CONFIG_PHYS_ADDR_T_64BIT is not set | 316 | CONFIG_PHYS_ADDR_T_64BIT=y |
| 315 | CONFIG_ZONE_DMA_FLAG=1 | 317 | CONFIG_ZONE_DMA_FLAG=1 |
| 316 | CONFIG_BOUNCE=y | 318 | CONFIG_BOUNCE=y |
| 317 | CONFIG_VIRT_TO_BUS=y | 319 | CONFIG_VIRT_TO_BUS=y |
| @@ -321,7 +323,7 @@ CONFIG_PPC_4K_PAGES=y | |||
| 321 | # CONFIG_PPC_16K_PAGES is not set | 323 | # CONFIG_PPC_16K_PAGES is not set |
| 322 | # CONFIG_PPC_64K_PAGES is not set | 324 | # CONFIG_PPC_64K_PAGES is not set |
| 323 | # CONFIG_PPC_256K_PAGES is not set | 325 | # CONFIG_PPC_256K_PAGES is not set |
| 324 | CONFIG_FORCE_MAX_ZONEORDER=11 | 326 | CONFIG_FORCE_MAX_ZONEORDER=12 |
| 325 | CONFIG_PROC_DEVICETREE=y | 327 | CONFIG_PROC_DEVICETREE=y |
| 326 | # CONFIG_CMDLINE_BOOL is not set | 328 | # CONFIG_CMDLINE_BOOL is not set |
| 327 | CONFIG_EXTRA_TARGETS="" | 329 | CONFIG_EXTRA_TARGETS="" |
| @@ -1122,16 +1124,13 @@ CONFIG_VGA_CONSOLE=y | |||
| 1122 | # CONFIG_VGACON_SOFT_SCROLLBACK is not set | 1124 | # CONFIG_VGACON_SOFT_SCROLLBACK is not set |
| 1123 | CONFIG_DUMMY_CONSOLE=y | 1125 | CONFIG_DUMMY_CONSOLE=y |
| 1124 | CONFIG_SOUND=y | 1126 | CONFIG_SOUND=y |
| 1125 | CONFIG_SOUND_OSS_CORE=y | 1127 | # CONFIG_SOUND_OSS_CORE is not set |
| 1126 | CONFIG_SOUND_OSS_CORE_PRECLAIM=y | ||
| 1127 | CONFIG_SND=y | 1128 | CONFIG_SND=y |
| 1128 | CONFIG_SND_TIMER=y | 1129 | CONFIG_SND_TIMER=y |
| 1129 | CONFIG_SND_PCM=y | 1130 | CONFIG_SND_PCM=y |
| 1130 | # CONFIG_SND_SEQUENCER is not set | 1131 | # CONFIG_SND_SEQUENCER is not set |
| 1131 | CONFIG_SND_OSSEMUL=y | 1132 | # CONFIG_SND_MIXER_OSS is not set |
| 1132 | CONFIG_SND_MIXER_OSS=y | 1133 | # CONFIG_SND_PCM_OSS is not set |
| 1133 | CONFIG_SND_PCM_OSS=y | ||
| 1134 | CONFIG_SND_PCM_OSS_PLUGINS=y | ||
| 1135 | # CONFIG_SND_HRTIMER is not set | 1134 | # CONFIG_SND_HRTIMER is not set |
| 1136 | # CONFIG_SND_DYNAMIC_MINORS is not set | 1135 | # CONFIG_SND_DYNAMIC_MINORS is not set |
| 1137 | # CONFIG_SND_SUPPORT_OLD_API is not set | 1136 | # CONFIG_SND_SUPPORT_OLD_API is not set |
| @@ -1145,12 +1144,7 @@ CONFIG_SND_VMASTER=y | |||
| 1145 | # CONFIG_SND_SBAWE_SEQ is not set | 1144 | # CONFIG_SND_SBAWE_SEQ is not set |
| 1146 | # CONFIG_SND_EMU10K1_SEQ is not set | 1145 | # CONFIG_SND_EMU10K1_SEQ is not set |
| 1147 | CONFIG_SND_AC97_CODEC=y | 1146 | CONFIG_SND_AC97_CODEC=y |
| 1148 | CONFIG_SND_DRIVERS=y | 1147 | # CONFIG_SND_DRIVERS is not set |
| 1149 | # CONFIG_SND_DUMMY is not set | ||
| 1150 | # CONFIG_SND_MTPAV is not set | ||
| 1151 | # CONFIG_SND_SERIAL_U16550 is not set | ||
| 1152 | # CONFIG_SND_MPU401 is not set | ||
| 1153 | # CONFIG_SND_AC97_POWER_SAVE is not set | ||
| 1154 | CONFIG_SND_PCI=y | 1148 | CONFIG_SND_PCI=y |
| 1155 | # CONFIG_SND_AD1889 is not set | 1149 | # CONFIG_SND_AD1889 is not set |
| 1156 | # CONFIG_SND_ALS300 is not set | 1150 | # CONFIG_SND_ALS300 is not set |
| @@ -1218,12 +1212,8 @@ CONFIG_SND_INTEL8X0=y | |||
| 1218 | # CONFIG_SND_VIRTUOSO is not set | 1212 | # CONFIG_SND_VIRTUOSO is not set |
| 1219 | # CONFIG_SND_VX222 is not set | 1213 | # CONFIG_SND_VX222 is not set |
| 1220 | # CONFIG_SND_YMFPCI is not set | 1214 | # CONFIG_SND_YMFPCI is not set |
| 1221 | CONFIG_SND_PPC=y | 1215 | # CONFIG_SND_PPC is not set |
| 1222 | CONFIG_SND_USB=y | 1216 | # CONFIG_SND_USB is not set |
| 1223 | # CONFIG_SND_USB_AUDIO is not set | ||
| 1224 | # CONFIG_SND_USB_UA101 is not set | ||
| 1225 | # CONFIG_SND_USB_USX2Y is not set | ||
| 1226 | # CONFIG_SND_USB_CAIAQ is not set | ||
| 1227 | # CONFIG_SND_SOC is not set | 1217 | # CONFIG_SND_SOC is not set |
| 1228 | # CONFIG_SOUND_PRIME is not set | 1218 | # CONFIG_SOUND_PRIME is not set |
| 1229 | CONFIG_AC97_BUS=y | 1219 | CONFIG_AC97_BUS=y |
diff --git a/arch/powerpc/configs/mpc85xx_smp_defconfig b/arch/powerpc/configs/mpc85xx_smp_defconfig index f5451d80f19b..f93de10adcda 100644 --- a/arch/powerpc/configs/mpc85xx_smp_defconfig +++ b/arch/powerpc/configs/mpc85xx_smp_defconfig | |||
| @@ -19,7 +19,8 @@ CONFIG_E500=y | |||
| 19 | CONFIG_FSL_EMB_PERFMON=y | 19 | CONFIG_FSL_EMB_PERFMON=y |
| 20 | CONFIG_BOOKE=y | 20 | CONFIG_BOOKE=y |
| 21 | CONFIG_FSL_BOOKE=y | 21 | CONFIG_FSL_BOOKE=y |
| 22 | # CONFIG_PHYS_64BIT is not set | 22 | CONFIG_PTE_64BIT=y |
| 23 | CONFIG_PHYS_64BIT=y | ||
| 23 | CONFIG_SPE=y | 24 | CONFIG_SPE=y |
| 24 | CONFIG_PPC_MMU_NOHASH=y | 25 | CONFIG_PPC_MMU_NOHASH=y |
| 25 | CONFIG_PPC_MMU_NOHASH_32=y | 26 | CONFIG_PPC_MMU_NOHASH_32=y |
| @@ -29,7 +30,7 @@ CONFIG_SMP=y | |||
| 29 | CONFIG_NR_CPUS=8 | 30 | CONFIG_NR_CPUS=8 |
| 30 | CONFIG_PPC32=y | 31 | CONFIG_PPC32=y |
| 31 | CONFIG_WORD_SIZE=32 | 32 | CONFIG_WORD_SIZE=32 |
| 32 | # CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set | 33 | CONFIG_ARCH_PHYS_ADDR_T_64BIT=y |
| 33 | CONFIG_MMU=y | 34 | CONFIG_MMU=y |
| 34 | CONFIG_GENERIC_CMOS_UPDATE=y | 35 | CONFIG_GENERIC_CMOS_UPDATE=y |
| 35 | CONFIG_GENERIC_TIME=y | 36 | CONFIG_GENERIC_TIME=y |
| @@ -243,6 +244,7 @@ CONFIG_MPC85xx_MDS=y | |||
| 243 | CONFIG_MPC8536_DS=y | 244 | CONFIG_MPC8536_DS=y |
| 244 | CONFIG_MPC85xx_DS=y | 245 | CONFIG_MPC85xx_DS=y |
| 245 | CONFIG_MPC85xx_RDB=y | 246 | CONFIG_MPC85xx_RDB=y |
| 247 | CONFIG_P1022_DS=y | ||
| 246 | CONFIG_SOCRATES=y | 248 | CONFIG_SOCRATES=y |
| 247 | CONFIG_KSI8560=y | 249 | CONFIG_KSI8560=y |
| 248 | CONFIG_XES_MPC85xx=y | 250 | CONFIG_XES_MPC85xx=y |
| @@ -316,7 +318,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y | |||
| 316 | CONFIG_PAGEFLAGS_EXTENDED=y | 318 | CONFIG_PAGEFLAGS_EXTENDED=y |
| 317 | CONFIG_SPLIT_PTLOCK_CPUS=4 | 319 | CONFIG_SPLIT_PTLOCK_CPUS=4 |
| 318 | CONFIG_MIGRATION=y | 320 | CONFIG_MIGRATION=y |
| 319 | # CONFIG_PHYS_ADDR_T_64BIT is not set | 321 | CONFIG_PHYS_ADDR_T_64BIT=y |
| 320 | CONFIG_ZONE_DMA_FLAG=1 | 322 | CONFIG_ZONE_DMA_FLAG=1 |
| 321 | CONFIG_BOUNCE=y | 323 | CONFIG_BOUNCE=y |
| 322 | CONFIG_VIRT_TO_BUS=y | 324 | CONFIG_VIRT_TO_BUS=y |
| @@ -326,7 +328,7 @@ CONFIG_PPC_4K_PAGES=y | |||
| 326 | # CONFIG_PPC_16K_PAGES is not set | 328 | # CONFIG_PPC_16K_PAGES is not set |
| 327 | # CONFIG_PPC_64K_PAGES is not set | 329 | # CONFIG_PPC_64K_PAGES is not set |
| 328 | # CONFIG_PPC_256K_PAGES is not set | 330 | # CONFIG_PPC_256K_PAGES is not set |
| 329 | CONFIG_FORCE_MAX_ZONEORDER=11 | 331 | CONFIG_FORCE_MAX_ZONEORDER=12 |
| 330 | CONFIG_PROC_DEVICETREE=y | 332 | CONFIG_PROC_DEVICETREE=y |
| 331 | # CONFIG_CMDLINE_BOOL is not set | 333 | # CONFIG_CMDLINE_BOOL is not set |
| 332 | CONFIG_EXTRA_TARGETS="" | 334 | CONFIG_EXTRA_TARGETS="" |
| @@ -1127,16 +1129,13 @@ CONFIG_VGA_CONSOLE=y | |||
| 1127 | # CONFIG_VGACON_SOFT_SCROLLBACK is not set | 1129 | # CONFIG_VGACON_SOFT_SCROLLBACK is not set |
| 1128 | CONFIG_DUMMY_CONSOLE=y | 1130 | CONFIG_DUMMY_CONSOLE=y |
| 1129 | CONFIG_SOUND=y | 1131 | CONFIG_SOUND=y |
| 1130 | CONFIG_SOUND_OSS_CORE=y | 1132 | # CONFIG_SOUND_OSS_CORE is not set |
| 1131 | CONFIG_SOUND_OSS_CORE_PRECLAIM=y | ||
| 1132 | CONFIG_SND=y | 1133 | CONFIG_SND=y |
| 1133 | CONFIG_SND_TIMER=y | 1134 | CONFIG_SND_TIMER=y |
| 1134 | CONFIG_SND_PCM=y | 1135 | CONFIG_SND_PCM=y |
| 1135 | # CONFIG_SND_SEQUENCER is not set | 1136 | # CONFIG_SND_SEQUENCER is not set |
| 1136 | CONFIG_SND_OSSEMUL=y | 1137 | # CONFIG_SND_MIXER_OSS is not set |
| 1137 | CONFIG_SND_MIXER_OSS=y | 1138 | # CONFIG_SND_PCM_OSS is not set |
| 1138 | CONFIG_SND_PCM_OSS=y | ||
| 1139 | CONFIG_SND_PCM_OSS_PLUGINS=y | ||
| 1140 | # CONFIG_SND_HRTIMER is not set | 1139 | # CONFIG_SND_HRTIMER is not set |
| 1141 | # CONFIG_SND_DYNAMIC_MINORS is not set | 1140 | # CONFIG_SND_DYNAMIC_MINORS is not set |
| 1142 | # CONFIG_SND_SUPPORT_OLD_API is not set | 1141 | # CONFIG_SND_SUPPORT_OLD_API is not set |
| @@ -1150,12 +1149,7 @@ CONFIG_SND_VMASTER=y | |||
| 1150 | # CONFIG_SND_SBAWE_SEQ is not set | 1149 | # CONFIG_SND_SBAWE_SEQ is not set |
| 1151 | # CONFIG_SND_EMU10K1_SEQ is not set | 1150 | # CONFIG_SND_EMU10K1_SEQ is not set |
| 1152 | CONFIG_SND_AC97_CODEC=y | 1151 | CONFIG_SND_AC97_CODEC=y |
| 1153 | CONFIG_SND_DRIVERS=y | 1152 | # CONFIG_SND_DRIVERS is not set |
| 1154 | # CONFIG_SND_DUMMY is not set | ||
| 1155 | # CONFIG_SND_MTPAV is not set | ||
| 1156 | # CONFIG_SND_SERIAL_U16550 is not set | ||
| 1157 | # CONFIG_SND_MPU401 is not set | ||
| 1158 | # CONFIG_SND_AC97_POWER_SAVE is not set | ||
| 1159 | CONFIG_SND_PCI=y | 1153 | CONFIG_SND_PCI=y |
| 1160 | # CONFIG_SND_AD1889 is not set | 1154 | # CONFIG_SND_AD1889 is not set |
| 1161 | # CONFIG_SND_ALS300 is not set | 1155 | # CONFIG_SND_ALS300 is not set |
| @@ -1223,12 +1217,8 @@ CONFIG_SND_INTEL8X0=y | |||
| 1223 | # CONFIG_SND_VIRTUOSO is not set | 1217 | # CONFIG_SND_VIRTUOSO is not set |
| 1224 | # CONFIG_SND_VX222 is not set | 1218 | # CONFIG_SND_VX222 is not set |
| 1225 | # CONFIG_SND_YMFPCI is not set | 1219 | # CONFIG_SND_YMFPCI is not set |
| 1226 | CONFIG_SND_PPC=y | 1220 | # CONFIG_SND_PPC is not set |
| 1227 | CONFIG_SND_USB=y | 1221 | # CONFIG_SND_USB is not set |
| 1228 | # CONFIG_SND_USB_AUDIO is not set | ||
| 1229 | # CONFIG_SND_USB_UA101 is not set | ||
| 1230 | # CONFIG_SND_USB_USX2Y is not set | ||
| 1231 | # CONFIG_SND_USB_CAIAQ is not set | ||
| 1232 | # CONFIG_SND_SOC is not set | 1222 | # CONFIG_SND_SOC is not set |
| 1233 | # CONFIG_SOUND_PRIME is not set | 1223 | # CONFIG_SOUND_PRIME is not set |
| 1234 | CONFIG_AC97_BUS=y | 1224 | CONFIG_AC97_BUS=y |
diff --git a/arch/powerpc/configs/tqm8xx_defconfig b/arch/powerpc/configs/tqm8xx_defconfig new file mode 100644 index 000000000000..85e654b64874 --- /dev/null +++ b/arch/powerpc/configs/tqm8xx_defconfig | |||
| @@ -0,0 +1,934 @@ | |||
| 1 | # | ||
| 2 | # Automatically generated make config: don't edit | ||
| 3 | # Linux kernel version: 2.6.34-rc1 | ||
| 4 | # Tue Mar 23 08:22:15 2010 | ||
| 5 | # | ||
| 6 | # CONFIG_PPC64 is not set | ||
| 7 | |||
| 8 | # | ||
| 9 | # Processor support | ||
| 10 | # | ||
| 11 | # CONFIG_PPC_BOOK3S_32 is not set | ||
| 12 | # CONFIG_PPC_85xx is not set | ||
| 13 | CONFIG_PPC_8xx=y | ||
| 14 | # CONFIG_40x is not set | ||
| 15 | # CONFIG_44x is not set | ||
| 16 | # CONFIG_E200 is not set | ||
| 17 | CONFIG_8xx=y | ||
| 18 | CONFIG_PPC_MMU_NOHASH=y | ||
| 19 | CONFIG_PPC_MMU_NOHASH_32=y | ||
| 20 | # CONFIG_PPC_MM_SLICES is not set | ||
| 21 | CONFIG_NOT_COHERENT_CACHE=y | ||
| 22 | CONFIG_PPC32=y | ||
| 23 | CONFIG_WORD_SIZE=32 | ||
| 24 | # CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set | ||
| 25 | CONFIG_MMU=y | ||
| 26 | CONFIG_GENERIC_CMOS_UPDATE=y | ||
| 27 | CONFIG_GENERIC_TIME=y | ||
| 28 | CONFIG_GENERIC_TIME_VSYSCALL=y | ||
| 29 | CONFIG_GENERIC_CLOCKEVENTS=y | ||
| 30 | CONFIG_GENERIC_HARDIRQS=y | ||
| 31 | CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y | ||
| 32 | # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set | ||
| 33 | # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set | ||
| 34 | CONFIG_IRQ_PER_CPU=y | ||
| 35 | CONFIG_NR_IRQS=512 | ||
| 36 | CONFIG_STACKTRACE_SUPPORT=y | ||
| 37 | CONFIG_HAVE_LATENCYTOP_SUPPORT=y | ||
| 38 | CONFIG_TRACE_IRQFLAGS_SUPPORT=y | ||
| 39 | CONFIG_LOCKDEP_SUPPORT=y | ||
| 40 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y | ||
| 41 | CONFIG_ARCH_HAS_ILOG2_U32=y | ||
| 42 | CONFIG_GENERIC_HWEIGHT=y | ||
| 43 | CONFIG_GENERIC_FIND_NEXT_BIT=y | ||
| 44 | # CONFIG_ARCH_NO_VIRT_TO_BUS is not set | ||
| 45 | CONFIG_PPC=y | ||
| 46 | CONFIG_EARLY_PRINTK=y | ||
| 47 | CONFIG_GENERIC_NVRAM=y | ||
| 48 | CONFIG_SCHED_OMIT_FRAME_POINTER=y | ||
| 49 | CONFIG_ARCH_MAY_HAVE_PC_FDC=y | ||
| 50 | CONFIG_PPC_OF=y | ||
| 51 | CONFIG_OF=y | ||
| 52 | # CONFIG_PPC_UDBG_16550 is not set | ||
| 53 | # CONFIG_GENERIC_TBSYNC is not set | ||
| 54 | CONFIG_AUDIT_ARCH=y | ||
| 55 | CONFIG_GENERIC_BUG=y | ||
| 56 | CONFIG_DTC=y | ||
| 57 | # CONFIG_DEFAULT_UIMAGE is not set | ||
| 58 | CONFIG_ARCH_HIBERNATION_POSSIBLE=y | ||
| 59 | # CONFIG_PPC_DCR_NATIVE is not set | ||
| 60 | # CONFIG_PPC_DCR_MMIO is not set | ||
| 61 | CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y | ||
| 62 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" | ||
| 63 | CONFIG_CONSTRUCTORS=y | ||
| 64 | |||
| 65 | # | ||
| 66 | # General setup | ||
| 67 | # | ||
| 68 | CONFIG_EXPERIMENTAL=y | ||
| 69 | CONFIG_BROKEN_ON_SMP=y | ||
| 70 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
| 71 | CONFIG_LOCALVERSION="" | ||
| 72 | CONFIG_LOCALVERSION_AUTO=y | ||
| 73 | # CONFIG_SWAP is not set | ||
| 74 | CONFIG_SYSVIPC=y | ||
| 75 | CONFIG_SYSVIPC_SYSCTL=y | ||
| 76 | # CONFIG_POSIX_MQUEUE is not set | ||
| 77 | # CONFIG_BSD_PROCESS_ACCT is not set | ||
| 78 | # CONFIG_TASKSTATS is not set | ||
| 79 | # CONFIG_AUDIT is not set | ||
| 80 | |||
| 81 | # | ||
| 82 | # RCU Subsystem | ||
| 83 | # | ||
| 84 | CONFIG_TREE_RCU=y | ||
| 85 | # CONFIG_TREE_PREEMPT_RCU is not set | ||
| 86 | # CONFIG_TINY_RCU is not set | ||
| 87 | # CONFIG_RCU_TRACE is not set | ||
| 88 | CONFIG_RCU_FANOUT=32 | ||
| 89 | # CONFIG_RCU_FANOUT_EXACT is not set | ||
| 90 | # CONFIG_TREE_RCU_TRACE is not set | ||
| 91 | # CONFIG_IKCONFIG is not set | ||
| 92 | CONFIG_LOG_BUF_SHIFT=14 | ||
| 93 | # CONFIG_CGROUPS is not set | ||
| 94 | CONFIG_SYSFS_DEPRECATED=y | ||
| 95 | CONFIG_SYSFS_DEPRECATED_V2=y | ||
| 96 | # CONFIG_RELAY is not set | ||
| 97 | # CONFIG_NAMESPACES is not set | ||
| 98 | # CONFIG_BLK_DEV_INITRD is not set | ||
| 99 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
| 100 | CONFIG_SYSCTL=y | ||
| 101 | CONFIG_ANON_INODES=y | ||
| 102 | CONFIG_EMBEDDED=y | ||
| 103 | # CONFIG_SYSCTL_SYSCALL is not set | ||
| 104 | CONFIG_KALLSYMS=y | ||
| 105 | # CONFIG_KALLSYMS_ALL is not set | ||
| 106 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | ||
| 107 | CONFIG_HOTPLUG=y | ||
| 108 | CONFIG_PRINTK=y | ||
| 109 | CONFIG_BUG=y | ||
| 110 | # CONFIG_ELF_CORE is not set | ||
| 111 | # CONFIG_BASE_FULL is not set | ||
| 112 | # CONFIG_FUTEX is not set | ||
| 113 | CONFIG_EPOLL=y | ||
| 114 | CONFIG_SIGNALFD=y | ||
| 115 | CONFIG_TIMERFD=y | ||
| 116 | CONFIG_EVENTFD=y | ||
| 117 | CONFIG_SHMEM=y | ||
| 118 | CONFIG_AIO=y | ||
| 119 | CONFIG_HAVE_PERF_EVENTS=y | ||
| 120 | |||
| 121 | # | ||
| 122 | # Kernel Performance Events And Counters | ||
| 123 | # | ||
| 124 | # CONFIG_PERF_EVENTS is not set | ||
| 125 | # CONFIG_PERF_COUNTERS is not set | ||
| 126 | # CONFIG_VM_EVENT_COUNTERS is not set | ||
| 127 | CONFIG_SLUB_DEBUG=y | ||
| 128 | CONFIG_COMPAT_BRK=y | ||
| 129 | # CONFIG_SLAB is not set | ||
| 130 | CONFIG_SLUB=y | ||
| 131 | # CONFIG_SLOB is not set | ||
| 132 | # CONFIG_PROFILING is not set | ||
| 133 | CONFIG_HAVE_OPROFILE=y | ||
| 134 | # CONFIG_KPROBES is not set | ||
| 135 | CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y | ||
| 136 | CONFIG_HAVE_IOREMAP_PROT=y | ||
| 137 | CONFIG_HAVE_KPROBES=y | ||
| 138 | CONFIG_HAVE_KRETPROBES=y | ||
| 139 | CONFIG_HAVE_ARCH_TRACEHOOK=y | ||
| 140 | CONFIG_HAVE_DMA_ATTRS=y | ||
| 141 | CONFIG_HAVE_CLK=y | ||
| 142 | CONFIG_HAVE_DMA_API_DEBUG=y | ||
| 143 | |||
| 144 | # | ||
| 145 | # GCOV-based kernel profiling | ||
| 146 | # | ||
| 147 | # CONFIG_SLOW_WORK is not set | ||
| 148 | # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set | ||
| 149 | CONFIG_SLABINFO=y | ||
| 150 | CONFIG_BASE_SMALL=1 | ||
| 151 | CONFIG_MODULES=y | ||
| 152 | # CONFIG_MODULE_FORCE_LOAD is not set | ||
| 153 | CONFIG_MODULE_UNLOAD=y | ||
| 154 | # CONFIG_MODULE_FORCE_UNLOAD is not set | ||
| 155 | # CONFIG_MODVERSIONS is not set | ||
| 156 | CONFIG_MODULE_SRCVERSION_ALL=y | ||
| 157 | CONFIG_BLOCK=y | ||
| 158 | CONFIG_LBDAF=y | ||
| 159 | # CONFIG_BLK_DEV_BSG is not set | ||
| 160 | # CONFIG_BLK_DEV_INTEGRITY is not set | ||
| 161 | |||
| 162 | # | ||
| 163 | # IO Schedulers | ||
| 164 | # | ||
| 165 | CONFIG_IOSCHED_NOOP=y | ||
| 166 | CONFIG_IOSCHED_DEADLINE=y | ||
| 167 | # CONFIG_IOSCHED_CFQ is not set | ||
| 168 | CONFIG_DEFAULT_DEADLINE=y | ||
| 169 | # CONFIG_DEFAULT_CFQ is not set | ||
| 170 | # CONFIG_DEFAULT_NOOP is not set | ||
| 171 | CONFIG_DEFAULT_IOSCHED="deadline" | ||
| 172 | # CONFIG_INLINE_SPIN_TRYLOCK is not set | ||
| 173 | # CONFIG_INLINE_SPIN_TRYLOCK_BH is not set | ||
| 174 | # CONFIG_INLINE_SPIN_LOCK is not set | ||
| 175 | # CONFIG_INLINE_SPIN_LOCK_BH is not set | ||
| 176 | # CONFIG_INLINE_SPIN_LOCK_IRQ is not set | ||
| 177 | # CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set | ||
| 178 | CONFIG_INLINE_SPIN_UNLOCK=y | ||
| 179 | # CONFIG_INLINE_SPIN_UNLOCK_BH is not set | ||
| 180 | CONFIG_INLINE_SPIN_UNLOCK_IRQ=y | ||
| 181 | # CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set | ||
| 182 | # CONFIG_INLINE_READ_TRYLOCK is not set | ||
| 183 | # CONFIG_INLINE_READ_LOCK is not set | ||
| 184 | # CONFIG_INLINE_READ_LOCK_BH is not set | ||
| 185 | # CONFIG_INLINE_READ_LOCK_IRQ is not set | ||
| 186 | # CONFIG_INLINE_READ_LOCK_IRQSAVE is not set | ||
| 187 | CONFIG_INLINE_READ_UNLOCK=y | ||
| 188 | # CONFIG_INLINE_READ_UNLOCK_BH is not set | ||
| 189 | CONFIG_INLINE_READ_UNLOCK_IRQ=y | ||
| 190 | # CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set | ||
| 191 | # CONFIG_INLINE_WRITE_TRYLOCK is not set | ||
| 192 | # CONFIG_INLINE_WRITE_LOCK is not set | ||
| 193 | # CONFIG_INLINE_WRITE_LOCK_BH is not set | ||
| 194 | # CONFIG_INLINE_WRITE_LOCK_IRQ is not set | ||
| 195 | # CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set | ||
| 196 | CONFIG_INLINE_WRITE_UNLOCK=y | ||
| 197 | # CONFIG_INLINE_WRITE_UNLOCK_BH is not set | ||
| 198 | CONFIG_INLINE_WRITE_UNLOCK_IRQ=y | ||
| 199 | # CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set | ||
| 200 | # CONFIG_MUTEX_SPIN_ON_OWNER is not set | ||
| 201 | # CONFIG_FREEZER is not set | ||
| 202 | |||
| 203 | # | ||
| 204 | # Platform support | ||
| 205 | # | ||
| 206 | # CONFIG_PPC_CELL is not set | ||
| 207 | # CONFIG_PPC_CELL_NATIVE is not set | ||
| 208 | CONFIG_CPM1=y | ||
| 209 | # CONFIG_MPC8XXFADS is not set | ||
| 210 | # CONFIG_MPC86XADS is not set | ||
| 211 | # CONFIG_MPC885ADS is not set | ||
| 212 | # CONFIG_PPC_EP88XC is not set | ||
| 213 | # CONFIG_PPC_ADDER875 is not set | ||
| 214 | # CONFIG_PPC_MGSUVD is not set | ||
| 215 | CONFIG_TQM8XX=y | ||
| 216 | |||
| 217 | # | ||
| 218 | # MPC8xx CPM Options | ||
| 219 | # | ||
| 220 | |||
| 221 | # | ||
| 222 | # Generic MPC8xx Options | ||
| 223 | # | ||
| 224 | CONFIG_8xx_COPYBACK=y | ||
| 225 | # CONFIG_8xx_GPIO is not set | ||
| 226 | # CONFIG_8xx_CPU6 is not set | ||
| 227 | # CONFIG_8xx_CPU15 is not set | ||
| 228 | CONFIG_NO_UCODE_PATCH=y | ||
| 229 | # CONFIG_USB_SOF_UCODE_PATCH is not set | ||
| 230 | # CONFIG_I2C_SPI_UCODE_PATCH is not set | ||
| 231 | # CONFIG_I2C_SPI_SMC1_UCODE_PATCH is not set | ||
| 232 | # CONFIG_PQ2ADS is not set | ||
| 233 | # CONFIG_IPIC is not set | ||
| 234 | # CONFIG_MPIC is not set | ||
| 235 | # CONFIG_MPIC_WEIRD is not set | ||
| 236 | # CONFIG_PPC_I8259 is not set | ||
| 237 | # CONFIG_PPC_RTAS is not set | ||
| 238 | # CONFIG_MMIO_NVRAM is not set | ||
| 239 | # CONFIG_PPC_MPC106 is not set | ||
| 240 | # CONFIG_PPC_970_NAP is not set | ||
| 241 | # CONFIG_PPC_INDIRECT_IO is not set | ||
| 242 | # CONFIG_GENERIC_IOMAP is not set | ||
| 243 | # CONFIG_CPU_FREQ is not set | ||
| 244 | # CONFIG_QUICC_ENGINE is not set | ||
| 245 | # CONFIG_FSL_ULI1575 is not set | ||
| 246 | CONFIG_CPM=y | ||
| 247 | # CONFIG_SIMPLE_GPIO is not set | ||
| 248 | |||
| 249 | # | ||
| 250 | # Kernel options | ||
| 251 | # | ||
| 252 | # CONFIG_HIGHMEM is not set | ||
| 253 | CONFIG_TICK_ONESHOT=y | ||
| 254 | CONFIG_NO_HZ=y | ||
| 255 | CONFIG_HIGH_RES_TIMERS=y | ||
| 256 | CONFIG_GENERIC_CLOCKEVENTS_BUILD=y | ||
| 257 | CONFIG_HZ_100=y | ||
| 258 | # CONFIG_HZ_250 is not set | ||
| 259 | # CONFIG_HZ_300 is not set | ||
| 260 | # CONFIG_HZ_1000 is not set | ||
| 261 | CONFIG_HZ=100 | ||
| 262 | CONFIG_SCHED_HRTICK=y | ||
| 263 | CONFIG_PREEMPT_NONE=y | ||
| 264 | # CONFIG_PREEMPT_VOLUNTARY is not set | ||
| 265 | # CONFIG_PREEMPT is not set | ||
| 266 | CONFIG_BINFMT_ELF=y | ||
| 267 | # CONFIG_HAVE_AOUT is not set | ||
| 268 | # CONFIG_BINFMT_MISC is not set | ||
| 269 | # CONFIG_MATH_EMULATION is not set | ||
| 270 | CONFIG_8XX_MINIMAL_FPEMU=y | ||
| 271 | # CONFIG_IOMMU_HELPER is not set | ||
| 272 | # CONFIG_SWIOTLB is not set | ||
| 273 | CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y | ||
| 274 | CONFIG_ARCH_HAS_WALK_MEMORY=y | ||
| 275 | CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y | ||
| 276 | CONFIG_SPARSE_IRQ=y | ||
| 277 | CONFIG_MAX_ACTIVE_REGIONS=32 | ||
| 278 | CONFIG_ARCH_FLATMEM_ENABLE=y | ||
| 279 | CONFIG_ARCH_POPULATES_NODE_MAP=y | ||
| 280 | CONFIG_SELECT_MEMORY_MODEL=y | ||
| 281 | CONFIG_FLATMEM_MANUAL=y | ||
| 282 | # CONFIG_DISCONTIGMEM_MANUAL is not set | ||
| 283 | # CONFIG_SPARSEMEM_MANUAL is not set | ||
| 284 | CONFIG_FLATMEM=y | ||
| 285 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
| 286 | CONFIG_PAGEFLAGS_EXTENDED=y | ||
| 287 | CONFIG_SPLIT_PTLOCK_CPUS=4 | ||
| 288 | CONFIG_MIGRATION=y | ||
| 289 | # CONFIG_PHYS_ADDR_T_64BIT is not set | ||
| 290 | CONFIG_ZONE_DMA_FLAG=1 | ||
| 291 | CONFIG_BOUNCE=y | ||
| 292 | CONFIG_VIRT_TO_BUS=y | ||
| 293 | # CONFIG_KSM is not set | ||
| 294 | CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 | ||
| 295 | CONFIG_PPC_4K_PAGES=y | ||
| 296 | # CONFIG_PPC_16K_PAGES is not set | ||
| 297 | # CONFIG_PPC_64K_PAGES is not set | ||
| 298 | # CONFIG_PPC_256K_PAGES is not set | ||
| 299 | CONFIG_FORCE_MAX_ZONEORDER=11 | ||
| 300 | CONFIG_PROC_DEVICETREE=y | ||
| 301 | # CONFIG_CMDLINE_BOOL is not set | ||
| 302 | CONFIG_EXTRA_TARGETS="" | ||
| 303 | # CONFIG_PM is not set | ||
| 304 | # CONFIG_SECCOMP is not set | ||
| 305 | CONFIG_ISA_DMA_API=y | ||
| 306 | |||
| 307 | # | ||
| 308 | # Bus options | ||
| 309 | # | ||
| 310 | CONFIG_ZONE_DMA=y | ||
| 311 | CONFIG_NEED_DMA_MAP_STATE=y | ||
| 312 | CONFIG_FSL_SOC=y | ||
| 313 | # CONFIG_PCI is not set | ||
| 314 | # CONFIG_PCI_DOMAINS is not set | ||
| 315 | # CONFIG_PCI_SYSCALL is not set | ||
| 316 | # CONFIG_PCI_QSPAN is not set | ||
| 317 | # CONFIG_ARCH_SUPPORTS_MSI is not set | ||
| 318 | # CONFIG_PCCARD is not set | ||
| 319 | # CONFIG_HAS_RAPIDIO is not set | ||
| 320 | |||
| 321 | # | ||
| 322 | # Advanced setup | ||
| 323 | # | ||
| 324 | # CONFIG_ADVANCED_OPTIONS is not set | ||
| 325 | |||
| 326 | # | ||
| 327 | # Default settings for advanced configuration options are used | ||
| 328 | # | ||
| 329 | CONFIG_LOWMEM_SIZE=0x30000000 | ||
| 330 | CONFIG_PAGE_OFFSET=0xc0000000 | ||
| 331 | CONFIG_KERNEL_START=0xc0000000 | ||
| 332 | CONFIG_PHYSICAL_START=0x00000000 | ||
| 333 | CONFIG_TASK_SIZE=0x80000000 | ||
| 334 | CONFIG_CONSISTENT_SIZE=0x00200000 | ||
| 335 | CONFIG_NET=y | ||
| 336 | |||
| 337 | # | ||
| 338 | # Networking options | ||
| 339 | # | ||
| 340 | CONFIG_PACKET=y | ||
| 341 | CONFIG_UNIX=y | ||
| 342 | # CONFIG_NET_KEY is not set | ||
| 343 | CONFIG_INET=y | ||
| 344 | # CONFIG_IP_MULTICAST is not set | ||
| 345 | # CONFIG_IP_ADVANCED_ROUTER is not set | ||
| 346 | CONFIG_IP_FIB_HASH=y | ||
| 347 | CONFIG_IP_PNP=y | ||
| 348 | # CONFIG_IP_PNP_DHCP is not set | ||
| 349 | # CONFIG_IP_PNP_BOOTP is not set | ||
| 350 | # CONFIG_IP_PNP_RARP is not set | ||
| 351 | # CONFIG_NET_IPIP is not set | ||
| 352 | # CONFIG_NET_IPGRE is not set | ||
| 353 | # CONFIG_ARPD is not set | ||
| 354 | CONFIG_SYN_COOKIES=y | ||
| 355 | # CONFIG_INET_AH is not set | ||
| 356 | # CONFIG_INET_ESP is not set | ||
| 357 | # CONFIG_INET_IPCOMP is not set | ||
| 358 | # CONFIG_INET_XFRM_TUNNEL is not set | ||
| 359 | # CONFIG_INET_TUNNEL is not set | ||
| 360 | # CONFIG_INET_XFRM_MODE_TRANSPORT is not set | ||
| 361 | # CONFIG_INET_XFRM_MODE_TUNNEL is not set | ||
| 362 | # CONFIG_INET_XFRM_MODE_BEET is not set | ||
| 363 | # CONFIG_INET_LRO is not set | ||
| 364 | CONFIG_INET_DIAG=y | ||
| 365 | CONFIG_INET_TCP_DIAG=y | ||
| 366 | # CONFIG_TCP_CONG_ADVANCED is not set | ||
| 367 | CONFIG_TCP_CONG_CUBIC=y | ||
| 368 | CONFIG_DEFAULT_TCP_CONG="cubic" | ||
| 369 | # CONFIG_TCP_MD5SIG is not set | ||
| 370 | # CONFIG_IPV6 is not set | ||
| 371 | # CONFIG_NETWORK_SECMARK is not set | ||
| 372 | # CONFIG_NETFILTER is not set | ||
| 373 | # CONFIG_IP_DCCP is not set | ||
| 374 | # CONFIG_IP_SCTP is not set | ||
| 375 | # CONFIG_RDS is not set | ||
| 376 | # CONFIG_TIPC is not set | ||
| 377 | # CONFIG_ATM is not set | ||
| 378 | # CONFIG_BRIDGE is not set | ||
| 379 | # CONFIG_NET_DSA is not set | ||
| 380 | # CONFIG_VLAN_8021Q is not set | ||
| 381 | # CONFIG_DECNET is not set | ||
| 382 | # CONFIG_LLC2 is not set | ||
| 383 | # CONFIG_IPX is not set | ||
| 384 | # CONFIG_ATALK is not set | ||
| 385 | # CONFIG_X25 is not set | ||
| 386 | # CONFIG_LAPB is not set | ||
| 387 | # CONFIG_ECONET is not set | ||
| 388 | # CONFIG_WAN_ROUTER is not set | ||
| 389 | # CONFIG_PHONET is not set | ||
| 390 | # CONFIG_IEEE802154 is not set | ||
| 391 | # CONFIG_NET_SCHED is not set | ||
| 392 | # CONFIG_DCB is not set | ||
| 393 | |||
| 394 | # | ||
| 395 | # Network testing | ||
| 396 | # | ||
| 397 | # CONFIG_NET_PKTGEN is not set | ||
| 398 | # CONFIG_HAMRADIO is not set | ||
| 399 | # CONFIG_CAN is not set | ||
| 400 | # CONFIG_IRDA is not set | ||
| 401 | # CONFIG_BT is not set | ||
| 402 | # CONFIG_AF_RXRPC is not set | ||
| 403 | # CONFIG_WIRELESS is not set | ||
| 404 | # CONFIG_WIMAX is not set | ||
| 405 | # CONFIG_RFKILL is not set | ||
| 406 | # CONFIG_NET_9P is not set | ||
| 407 | |||
| 408 | # | ||
| 409 | # Device Drivers | ||
| 410 | # | ||
| 411 | |||
| 412 | # | ||
| 413 | # Generic Driver Options | ||
| 414 | # | ||
| 415 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||
| 416 | # CONFIG_DEVTMPFS is not set | ||
| 417 | CONFIG_STANDALONE=y | ||
| 418 | CONFIG_PREVENT_FIRMWARE_BUILD=y | ||
| 419 | # CONFIG_FW_LOADER is not set | ||
| 420 | # CONFIG_DEBUG_DRIVER is not set | ||
| 421 | # CONFIG_DEBUG_DEVRES is not set | ||
| 422 | # CONFIG_SYS_HYPERVISOR is not set | ||
| 423 | # CONFIG_CONNECTOR is not set | ||
| 424 | CONFIG_MTD=y | ||
| 425 | # CONFIG_MTD_DEBUG is not set | ||
| 426 | # CONFIG_MTD_TESTS is not set | ||
| 427 | CONFIG_MTD_CONCAT=y | ||
| 428 | CONFIG_MTD_PARTITIONS=y | ||
| 429 | # CONFIG_MTD_REDBOOT_PARTS is not set | ||
| 430 | CONFIG_MTD_CMDLINE_PARTS=y | ||
| 431 | CONFIG_MTD_OF_PARTS=y | ||
| 432 | # CONFIG_MTD_AR7_PARTS is not set | ||
| 433 | |||
| 434 | # | ||
| 435 | # User Modules And Translation Layers | ||
| 436 | # | ||
| 437 | CONFIG_MTD_CHAR=y | ||
| 438 | CONFIG_MTD_BLKDEVS=y | ||
| 439 | CONFIG_MTD_BLOCK=y | ||
| 440 | # CONFIG_FTL is not set | ||
| 441 | # CONFIG_NFTL is not set | ||
| 442 | # CONFIG_INFTL is not set | ||
| 443 | # CONFIG_RFD_FTL is not set | ||
| 444 | # CONFIG_SSFDC is not set | ||
| 445 | # CONFIG_MTD_OOPS is not set | ||
| 446 | |||
| 447 | # | ||
| 448 | # RAM/ROM/Flash chip drivers | ||
| 449 | # | ||
| 450 | CONFIG_MTD_CFI=y | ||
| 451 | # CONFIG_MTD_JEDECPROBE is not set | ||
| 452 | CONFIG_MTD_GEN_PROBE=y | ||
| 453 | # CONFIG_MTD_CFI_ADV_OPTIONS is not set | ||
| 454 | CONFIG_MTD_MAP_BANK_WIDTH_1=y | ||
| 455 | CONFIG_MTD_MAP_BANK_WIDTH_2=y | ||
| 456 | CONFIG_MTD_MAP_BANK_WIDTH_4=y | ||
| 457 | # CONFIG_MTD_MAP_BANK_WIDTH_8 is not set | ||
| 458 | # CONFIG_MTD_MAP_BANK_WIDTH_16 is not set | ||
| 459 | # CONFIG_MTD_MAP_BANK_WIDTH_32 is not set | ||
| 460 | CONFIG_MTD_CFI_I1=y | ||
| 461 | CONFIG_MTD_CFI_I2=y | ||
| 462 | # CONFIG_MTD_CFI_I4 is not set | ||
| 463 | # CONFIG_MTD_CFI_I8 is not set | ||
| 464 | CONFIG_MTD_CFI_INTELEXT=y | ||
| 465 | CONFIG_MTD_CFI_AMDSTD=y | ||
| 466 | # CONFIG_MTD_CFI_STAA is not set | ||
| 467 | CONFIG_MTD_CFI_UTIL=y | ||
| 468 | # CONFIG_MTD_RAM is not set | ||
| 469 | # CONFIG_MTD_ROM is not set | ||
| 470 | # CONFIG_MTD_ABSENT is not set | ||
| 471 | |||
| 472 | # | ||
| 473 | # Mapping drivers for chip access | ||
| 474 | # | ||
| 475 | # CONFIG_MTD_COMPLEX_MAPPINGS is not set | ||
| 476 | # CONFIG_MTD_PHYSMAP is not set | ||
| 477 | CONFIG_MTD_PHYSMAP_OF=y | ||
| 478 | # CONFIG_MTD_CFI_FLAGADM is not set | ||
| 479 | # CONFIG_MTD_PLATRAM is not set | ||
| 480 | |||
| 481 | # | ||
| 482 | # Self-contained MTD device drivers | ||
| 483 | # | ||
| 484 | # CONFIG_MTD_SLRAM is not set | ||
| 485 | # CONFIG_MTD_PHRAM is not set | ||
| 486 | # CONFIG_MTD_MTDRAM is not set | ||
| 487 | # CONFIG_MTD_BLOCK2MTD is not set | ||
| 488 | |||
| 489 | # | ||
| 490 | # Disk-On-Chip Device Drivers | ||
| 491 | # | ||
| 492 | # CONFIG_MTD_DOC2000 is not set | ||
| 493 | # CONFIG_MTD_DOC2001 is not set | ||
| 494 | # CONFIG_MTD_DOC2001PLUS is not set | ||
| 495 | # CONFIG_MTD_NAND is not set | ||
| 496 | # CONFIG_MTD_ONENAND is not set | ||
| 497 | |||
| 498 | # | ||
| 499 | # LPDDR flash memory drivers | ||
| 500 | # | ||
| 501 | # CONFIG_MTD_LPDDR is not set | ||
| 502 | |||
| 503 | # | ||
| 504 | # UBI - Unsorted block images | ||
| 505 | # | ||
| 506 | # CONFIG_MTD_UBI is not set | ||
| 507 | CONFIG_OF_FLATTREE=y | ||
| 508 | CONFIG_OF_DYNAMIC=y | ||
| 509 | CONFIG_OF_DEVICE=y | ||
| 510 | CONFIG_OF_MDIO=y | ||
| 511 | # CONFIG_PARPORT is not set | ||
| 512 | # CONFIG_BLK_DEV is not set | ||
| 513 | # CONFIG_MISC_DEVICES is not set | ||
| 514 | CONFIG_HAVE_IDE=y | ||
| 515 | # CONFIG_IDE is not set | ||
| 516 | |||
| 517 | # | ||
| 518 | # SCSI device support | ||
| 519 | # | ||
| 520 | # CONFIG_RAID_ATTRS is not set | ||
| 521 | # CONFIG_SCSI is not set | ||
| 522 | # CONFIG_SCSI_DMA is not set | ||
| 523 | # CONFIG_SCSI_NETLINK is not set | ||
| 524 | # CONFIG_ATA is not set | ||
| 525 | # CONFIG_MD is not set | ||
| 526 | # CONFIG_MACINTOSH_DRIVERS is not set | ||
| 527 | CONFIG_NETDEVICES=y | ||
| 528 | # CONFIG_DUMMY is not set | ||
| 529 | # CONFIG_BONDING is not set | ||
| 530 | # CONFIG_MACVLAN is not set | ||
| 531 | # CONFIG_EQUALIZER is not set | ||
| 532 | # CONFIG_TUN is not set | ||
| 533 | # CONFIG_VETH is not set | ||
| 534 | CONFIG_PHYLIB=y | ||
| 535 | |||
| 536 | # | ||
| 537 | # MII PHY device drivers | ||
| 538 | # | ||
| 539 | # CONFIG_MARVELL_PHY is not set | ||
| 540 | CONFIG_DAVICOM_PHY=y | ||
| 541 | # CONFIG_QSEMI_PHY is not set | ||
| 542 | # CONFIG_LXT_PHY is not set | ||
| 543 | # CONFIG_CICADA_PHY is not set | ||
| 544 | # CONFIG_VITESSE_PHY is not set | ||
| 545 | # CONFIG_SMSC_PHY is not set | ||
| 546 | # CONFIG_BROADCOM_PHY is not set | ||
| 547 | # CONFIG_ICPLUS_PHY is not set | ||
| 548 | # CONFIG_REALTEK_PHY is not set | ||
| 549 | # CONFIG_NATIONAL_PHY is not set | ||
| 550 | # CONFIG_STE10XP is not set | ||
| 551 | # CONFIG_LSI_ET1011C_PHY is not set | ||
| 552 | CONFIG_FIXED_PHY=y | ||
| 553 | # CONFIG_MDIO_BITBANG is not set | ||
| 554 | CONFIG_NET_ETHERNET=y | ||
| 555 | CONFIG_MII=y | ||
| 556 | # CONFIG_ETHOC is not set | ||
| 557 | # CONFIG_DNET is not set | ||
| 558 | # CONFIG_IBM_NEW_EMAC_ZMII is not set | ||
| 559 | # CONFIG_IBM_NEW_EMAC_RGMII is not set | ||
| 560 | # CONFIG_IBM_NEW_EMAC_TAH is not set | ||
| 561 | # CONFIG_IBM_NEW_EMAC_EMAC4 is not set | ||
| 562 | # CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set | ||
| 563 | # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set | ||
| 564 | # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set | ||
| 565 | # CONFIG_B44 is not set | ||
| 566 | # CONFIG_KS8842 is not set | ||
| 567 | # CONFIG_KS8851_MLL is not set | ||
| 568 | # CONFIG_XILINX_EMACLITE is not set | ||
| 569 | CONFIG_FS_ENET=y | ||
| 570 | CONFIG_FS_ENET_HAS_SCC=y | ||
| 571 | CONFIG_FS_ENET_HAS_FEC=y | ||
| 572 | CONFIG_FS_ENET_MDIO_FEC=y | ||
| 573 | # CONFIG_NETDEV_1000 is not set | ||
| 574 | # CONFIG_NETDEV_10000 is not set | ||
| 575 | # CONFIG_WLAN is not set | ||
| 576 | |||
| 577 | # | ||
| 578 | # Enable WiMAX (Networking options) to see the WiMAX drivers | ||
| 579 | # | ||
| 580 | # CONFIG_WAN is not set | ||
| 581 | # CONFIG_PPP is not set | ||
| 582 | # CONFIG_SLIP is not set | ||
| 583 | # CONFIG_NETCONSOLE is not set | ||
| 584 | # CONFIG_NETPOLL is not set | ||
| 585 | # CONFIG_NET_POLL_CONTROLLER is not set | ||
| 586 | # CONFIG_ISDN is not set | ||
| 587 | # CONFIG_PHONE is not set | ||
| 588 | |||
| 589 | # | ||
| 590 | # Input device support | ||
| 591 | # | ||
| 592 | # CONFIG_INPUT is not set | ||
| 593 | |||
| 594 | # | ||
| 595 | # Hardware I/O ports | ||
| 596 | # | ||
| 597 | # CONFIG_SERIO is not set | ||
| 598 | # CONFIG_GAMEPORT is not set | ||
| 599 | |||
| 600 | # | ||
| 601 | # Character devices | ||
| 602 | # | ||
| 603 | # CONFIG_VT is not set | ||
| 604 | CONFIG_DEVKMEM=y | ||
| 605 | # CONFIG_SERIAL_NONSTANDARD is not set | ||
| 606 | |||
| 607 | # | ||
| 608 | # Serial drivers | ||
| 609 | # | ||
| 610 | # CONFIG_SERIAL_8250 is not set | ||
| 611 | |||
| 612 | # | ||
| 613 | # Non-8250 serial port support | ||
| 614 | # | ||
| 615 | # CONFIG_SERIAL_UARTLITE is not set | ||
| 616 | CONFIG_SERIAL_CORE=y | ||
| 617 | CONFIG_SERIAL_CORE_CONSOLE=y | ||
| 618 | CONFIG_SERIAL_CPM=y | ||
| 619 | CONFIG_SERIAL_CPM_CONSOLE=y | ||
| 620 | # CONFIG_SERIAL_TIMBERDALE is not set | ||
| 621 | # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set | ||
| 622 | CONFIG_UNIX98_PTYS=y | ||
| 623 | # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set | ||
| 624 | # CONFIG_LEGACY_PTYS is not set | ||
| 625 | # CONFIG_HVC_UDBG is not set | ||
| 626 | # CONFIG_IPMI_HANDLER is not set | ||
| 627 | CONFIG_HW_RANDOM=y | ||
| 628 | # CONFIG_HW_RANDOM_TIMERIOMEM is not set | ||
| 629 | # CONFIG_NVRAM is not set | ||
| 630 | CONFIG_GEN_RTC=y | ||
| 631 | # CONFIG_GEN_RTC_X is not set | ||
| 632 | # CONFIG_R3964 is not set | ||
| 633 | # CONFIG_RAW_DRIVER is not set | ||
| 634 | # CONFIG_TCG_TPM is not set | ||
| 635 | # CONFIG_I2C is not set | ||
| 636 | # CONFIG_SPI is not set | ||
| 637 | |||
| 638 | # | ||
| 639 | # PPS support | ||
| 640 | # | ||
| 641 | # CONFIG_PPS is not set | ||
| 642 | CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y | ||
| 643 | # CONFIG_GPIOLIB is not set | ||
| 644 | # CONFIG_W1 is not set | ||
| 645 | # CONFIG_POWER_SUPPLY is not set | ||
| 646 | # CONFIG_HWMON is not set | ||
| 647 | # CONFIG_THERMAL is not set | ||
| 648 | # CONFIG_WATCHDOG is not set | ||
| 649 | CONFIG_SSB_POSSIBLE=y | ||
| 650 | |||
| 651 | # | ||
| 652 | # Sonics Silicon Backplane | ||
| 653 | # | ||
| 654 | # CONFIG_SSB is not set | ||
| 655 | |||
| 656 | # | ||
| 657 | # Multifunction device drivers | ||
| 658 | # | ||
| 659 | # CONFIG_MFD_CORE is not set | ||
| 660 | # CONFIG_MFD_SM501 is not set | ||
| 661 | # CONFIG_HTC_PASIC3 is not set | ||
| 662 | # CONFIG_MFD_TMIO is not set | ||
| 663 | # CONFIG_REGULATOR is not set | ||
| 664 | # CONFIG_MEDIA_SUPPORT is not set | ||
| 665 | |||
| 666 | # | ||
| 667 | # Graphics support | ||
| 668 | # | ||
| 669 | # CONFIG_VGASTATE is not set | ||
| 670 | # CONFIG_VIDEO_OUTPUT_CONTROL is not set | ||
| 671 | # CONFIG_FB is not set | ||
| 672 | # CONFIG_BACKLIGHT_LCD_SUPPORT is not set | ||
| 673 | |||
| 674 | # | ||
| 675 | # Display device support | ||
| 676 | # | ||
| 677 | # CONFIG_DISPLAY_SUPPORT is not set | ||
| 678 | # CONFIG_SOUND is not set | ||
| 679 | # CONFIG_USB_SUPPORT is not set | ||
| 680 | # CONFIG_MMC is not set | ||
| 681 | # CONFIG_MEMSTICK is not set | ||
| 682 | # CONFIG_NEW_LEDS is not set | ||
| 683 | # CONFIG_ACCESSIBILITY is not set | ||
| 684 | # CONFIG_EDAC is not set | ||
| 685 | # CONFIG_RTC_CLASS is not set | ||
| 686 | # CONFIG_DMADEVICES is not set | ||
| 687 | # CONFIG_AUXDISPLAY is not set | ||
| 688 | # CONFIG_UIO is not set | ||
| 689 | |||
| 690 | # | ||
| 691 | # TI VLYNQ | ||
| 692 | # | ||
| 693 | # CONFIG_STAGING is not set | ||
| 694 | |||
| 695 | # | ||
| 696 | # File systems | ||
| 697 | # | ||
| 698 | # CONFIG_EXT2_FS is not set | ||
| 699 | # CONFIG_EXT3_FS is not set | ||
| 700 | # CONFIG_EXT4_FS is not set | ||
| 701 | # CONFIG_REISERFS_FS is not set | ||
| 702 | # CONFIG_JFS_FS is not set | ||
| 703 | # CONFIG_FS_POSIX_ACL is not set | ||
| 704 | # CONFIG_XFS_FS is not set | ||
| 705 | # CONFIG_GFS2_FS is not set | ||
| 706 | # CONFIG_OCFS2_FS is not set | ||
| 707 | # CONFIG_BTRFS_FS is not set | ||
| 708 | # CONFIG_NILFS2_FS is not set | ||
| 709 | CONFIG_FILE_LOCKING=y | ||
| 710 | CONFIG_FSNOTIFY=y | ||
| 711 | # CONFIG_DNOTIFY is not set | ||
| 712 | # CONFIG_INOTIFY is not set | ||
| 713 | CONFIG_INOTIFY_USER=y | ||
| 714 | # CONFIG_QUOTA is not set | ||
| 715 | # CONFIG_AUTOFS_FS is not set | ||
| 716 | # CONFIG_AUTOFS4_FS is not set | ||
| 717 | # CONFIG_FUSE_FS is not set | ||
| 718 | |||
| 719 | # | ||
| 720 | # Caches | ||
| 721 | # | ||
| 722 | # CONFIG_FSCACHE is not set | ||
| 723 | |||
| 724 | # | ||
| 725 | # CD-ROM/DVD Filesystems | ||
| 726 | # | ||
| 727 | # CONFIG_ISO9660_FS is not set | ||
| 728 | # CONFIG_UDF_FS is not set | ||
| 729 | |||
| 730 | # | ||
| 731 | # DOS/FAT/NT Filesystems | ||
| 732 | # | ||
| 733 | # CONFIG_MSDOS_FS is not set | ||
| 734 | # CONFIG_VFAT_FS is not set | ||
| 735 | # CONFIG_NTFS_FS is not set | ||
| 736 | |||
| 737 | # | ||
| 738 | # Pseudo filesystems | ||
| 739 | # | ||
| 740 | CONFIG_PROC_FS=y | ||
| 741 | # CONFIG_PROC_KCORE is not set | ||
| 742 | CONFIG_PROC_SYSCTL=y | ||
| 743 | CONFIG_PROC_PAGE_MONITOR=y | ||
| 744 | CONFIG_SYSFS=y | ||
| 745 | CONFIG_TMPFS=y | ||
| 746 | # CONFIG_TMPFS_POSIX_ACL is not set | ||
| 747 | # CONFIG_HUGETLB_PAGE is not set | ||
| 748 | # CONFIG_CONFIGFS_FS is not set | ||
| 749 | CONFIG_MISC_FILESYSTEMS=y | ||
| 750 | # CONFIG_ADFS_FS is not set | ||
| 751 | # CONFIG_AFFS_FS is not set | ||
| 752 | # CONFIG_HFS_FS is not set | ||
| 753 | # CONFIG_HFSPLUS_FS is not set | ||
| 754 | # CONFIG_BEFS_FS is not set | ||
| 755 | # CONFIG_BFS_FS is not set | ||
| 756 | # CONFIG_EFS_FS is not set | ||
| 757 | # CONFIG_JFFS2_FS is not set | ||
| 758 | # CONFIG_LOGFS is not set | ||
| 759 | CONFIG_CRAMFS=y | ||
| 760 | # CONFIG_SQUASHFS is not set | ||
| 761 | # CONFIG_VXFS_FS is not set | ||
| 762 | # CONFIG_MINIX_FS is not set | ||
| 763 | # CONFIG_OMFS_FS is not set | ||
| 764 | # CONFIG_HPFS_FS is not set | ||
| 765 | # CONFIG_QNX4FS_FS is not set | ||
| 766 | # CONFIG_ROMFS_FS is not set | ||
| 767 | # CONFIG_SYSV_FS is not set | ||
| 768 | # CONFIG_UFS_FS is not set | ||
| 769 | CONFIG_NETWORK_FILESYSTEMS=y | ||
| 770 | CONFIG_NFS_FS=y | ||
| 771 | CONFIG_NFS_V3=y | ||
| 772 | # CONFIG_NFS_V3_ACL is not set | ||
| 773 | # CONFIG_NFS_V4 is not set | ||
| 774 | CONFIG_ROOT_NFS=y | ||
| 775 | # CONFIG_NFSD is not set | ||
| 776 | CONFIG_LOCKD=y | ||
| 777 | CONFIG_LOCKD_V4=y | ||
| 778 | CONFIG_NFS_COMMON=y | ||
| 779 | CONFIG_SUNRPC=y | ||
| 780 | # CONFIG_RPCSEC_GSS_KRB5 is not set | ||
| 781 | # CONFIG_RPCSEC_GSS_SPKM3 is not set | ||
| 782 | # CONFIG_SMB_FS is not set | ||
| 783 | # CONFIG_CIFS is not set | ||
| 784 | # CONFIG_NCP_FS is not set | ||
| 785 | # CONFIG_CODA_FS is not set | ||
| 786 | # CONFIG_AFS_FS is not set | ||
| 787 | |||
| 788 | # | ||
| 789 | # Partition Types | ||
| 790 | # | ||
| 791 | CONFIG_PARTITION_ADVANCED=y | ||
| 792 | # CONFIG_ACORN_PARTITION is not set | ||
| 793 | # CONFIG_OSF_PARTITION is not set | ||
| 794 | # CONFIG_AMIGA_PARTITION is not set | ||
| 795 | # CONFIG_ATARI_PARTITION is not set | ||
| 796 | # CONFIG_MAC_PARTITION is not set | ||
| 797 | CONFIG_MSDOS_PARTITION=y | ||
| 798 | # CONFIG_BSD_DISKLABEL is not set | ||
| 799 | # CONFIG_MINIX_SUBPARTITION is not set | ||
| 800 | # CONFIG_SOLARIS_X86_PARTITION is not set | ||
| 801 | # CONFIG_UNIXWARE_DISKLABEL is not set | ||
| 802 | # CONFIG_LDM_PARTITION is not set | ||
| 803 | # CONFIG_SGI_PARTITION is not set | ||
| 804 | # CONFIG_ULTRIX_PARTITION is not set | ||
| 805 | # CONFIG_SUN_PARTITION is not set | ||
| 806 | # CONFIG_KARMA_PARTITION is not set | ||
| 807 | # CONFIG_EFI_PARTITION is not set | ||
| 808 | # CONFIG_SYSV68_PARTITION is not set | ||
| 809 | # CONFIG_NLS is not set | ||
| 810 | # CONFIG_DLM is not set | ||
| 811 | # CONFIG_BINARY_PRINTF is not set | ||
| 812 | |||
| 813 | # | ||
| 814 | # Library routines | ||
| 815 | # | ||
| 816 | CONFIG_GENERIC_FIND_LAST_BIT=y | ||
| 817 | # CONFIG_CRC_CCITT is not set | ||
| 818 | # CONFIG_CRC16 is not set | ||
| 819 | # CONFIG_CRC_T10DIF is not set | ||
| 820 | # CONFIG_CRC_ITU_T is not set | ||
| 821 | # CONFIG_CRC32 is not set | ||
| 822 | # CONFIG_CRC7 is not set | ||
| 823 | # CONFIG_LIBCRC32C is not set | ||
| 824 | CONFIG_ZLIB_INFLATE=y | ||
| 825 | CONFIG_HAS_IOMEM=y | ||
| 826 | CONFIG_HAS_IOPORT=y | ||
| 827 | CONFIG_HAS_DMA=y | ||
| 828 | CONFIG_HAVE_LMB=y | ||
| 829 | CONFIG_NLATTR=y | ||
| 830 | CONFIG_GENERIC_ATOMIC64=y | ||
| 831 | |||
| 832 | # | ||
| 833 | # Kernel hacking | ||
| 834 | # | ||
| 835 | # CONFIG_PRINTK_TIME is not set | ||
| 836 | CONFIG_ENABLE_WARN_DEPRECATED=y | ||
| 837 | CONFIG_ENABLE_MUST_CHECK=y | ||
| 838 | CONFIG_FRAME_WARN=1024 | ||
| 839 | CONFIG_MAGIC_SYSRQ=y | ||
| 840 | # CONFIG_STRIP_ASM_SYMS is not set | ||
| 841 | # CONFIG_UNUSED_SYMBOLS is not set | ||
| 842 | # CONFIG_DEBUG_FS is not set | ||
| 843 | # CONFIG_HEADERS_CHECK is not set | ||
| 844 | CONFIG_DEBUG_KERNEL=y | ||
| 845 | # CONFIG_DEBUG_SHIRQ is not set | ||
| 846 | CONFIG_DETECT_SOFTLOCKUP=y | ||
| 847 | # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set | ||
| 848 | CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 | ||
| 849 | CONFIG_DETECT_HUNG_TASK=y | ||
| 850 | # CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set | ||
| 851 | CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 | ||
| 852 | CONFIG_SCHED_DEBUG=y | ||
| 853 | # CONFIG_SCHEDSTATS is not set | ||
| 854 | # CONFIG_TIMER_STATS is not set | ||
| 855 | # CONFIG_DEBUG_OBJECTS is not set | ||
| 856 | # CONFIG_SLUB_DEBUG_ON is not set | ||
| 857 | # CONFIG_SLUB_STATS is not set | ||
| 858 | # CONFIG_DEBUG_KMEMLEAK is not set | ||
| 859 | # CONFIG_DEBUG_SPINLOCK is not set | ||
| 860 | # CONFIG_DEBUG_MUTEXES is not set | ||
| 861 | # CONFIG_DEBUG_LOCK_ALLOC is not set | ||
| 862 | # CONFIG_PROVE_LOCKING is not set | ||
| 863 | # CONFIG_LOCK_STAT is not set | ||
| 864 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set | ||
| 865 | # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set | ||
| 866 | # CONFIG_DEBUG_KOBJECT is not set | ||
| 867 | CONFIG_DEBUG_BUGVERBOSE=y | ||
| 868 | CONFIG_DEBUG_INFO=y | ||
| 869 | # CONFIG_DEBUG_VM is not set | ||
| 870 | # CONFIG_DEBUG_WRITECOUNT is not set | ||
| 871 | # CONFIG_DEBUG_MEMORY_INIT is not set | ||
| 872 | # CONFIG_DEBUG_LIST is not set | ||
| 873 | # CONFIG_DEBUG_SG is not set | ||
| 874 | # CONFIG_DEBUG_NOTIFIERS is not set | ||
| 875 | # CONFIG_DEBUG_CREDENTIALS is not set | ||
| 876 | # CONFIG_RCU_TORTURE_TEST is not set | ||
| 877 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | ||
| 878 | # CONFIG_BACKTRACE_SELF_TEST is not set | ||
| 879 | # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set | ||
| 880 | # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set | ||
| 881 | # CONFIG_FAULT_INJECTION is not set | ||
| 882 | # CONFIG_LATENCYTOP is not set | ||
| 883 | # CONFIG_SYSCTL_SYSCALL_CHECK is not set | ||
| 884 | # CONFIG_DEBUG_PAGEALLOC is not set | ||
| 885 | CONFIG_HAVE_FUNCTION_TRACER=y | ||
| 886 | CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y | ||
| 887 | CONFIG_HAVE_DYNAMIC_FTRACE=y | ||
| 888 | CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y | ||
| 889 | CONFIG_TRACING_SUPPORT=y | ||
| 890 | CONFIG_FTRACE=y | ||
| 891 | # CONFIG_FUNCTION_TRACER is not set | ||
| 892 | # CONFIG_IRQSOFF_TRACER is not set | ||
| 893 | # CONFIG_SCHED_TRACER is not set | ||
| 894 | # CONFIG_ENABLE_DEFAULT_TRACERS is not set | ||
| 895 | # CONFIG_BOOT_TRACER is not set | ||
| 896 | CONFIG_BRANCH_PROFILE_NONE=y | ||
| 897 | # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set | ||
| 898 | # CONFIG_PROFILE_ALL_BRANCHES is not set | ||
| 899 | # CONFIG_STACK_TRACER is not set | ||
| 900 | # CONFIG_KMEMTRACE is not set | ||
| 901 | # CONFIG_WORKQUEUE_TRACER is not set | ||
| 902 | # CONFIG_BLK_DEV_IO_TRACE is not set | ||
| 903 | # CONFIG_DMA_API_DEBUG is not set | ||
| 904 | # CONFIG_SAMPLES is not set | ||
| 905 | CONFIG_HAVE_ARCH_KGDB=y | ||
| 906 | # CONFIG_KGDB is not set | ||
| 907 | # CONFIG_PPC_DISABLE_WERROR is not set | ||
| 908 | CONFIG_PPC_WERROR=y | ||
| 909 | CONFIG_PRINT_STACK_DEPTH=64 | ||
| 910 | # CONFIG_DEBUG_STACKOVERFLOW is not set | ||
| 911 | # CONFIG_DEBUG_STACK_USAGE is not set | ||
| 912 | # CONFIG_CODE_PATCHING_SELFTEST is not set | ||
| 913 | # CONFIG_FTR_FIXUP_SELFTEST is not set | ||
| 914 | # CONFIG_MSI_BITMAP_SELFTEST is not set | ||
| 915 | # CONFIG_XMON is not set | ||
| 916 | # CONFIG_IRQSTACKS is not set | ||
| 917 | # CONFIG_BDI_SWITCH is not set | ||
| 918 | # CONFIG_PPC_EARLY_DEBUG is not set | ||
| 919 | |||
| 920 | # | ||
| 921 | # Security options | ||
| 922 | # | ||
| 923 | # CONFIG_KEYS is not set | ||
| 924 | # CONFIG_SECURITY is not set | ||
| 925 | # CONFIG_SECURITYFS is not set | ||
| 926 | # CONFIG_DEFAULT_SECURITY_SELINUX is not set | ||
| 927 | # CONFIG_DEFAULT_SECURITY_SMACK is not set | ||
| 928 | # CONFIG_DEFAULT_SECURITY_TOMOYO is not set | ||
| 929 | CONFIG_DEFAULT_SECURITY_DAC=y | ||
| 930 | CONFIG_DEFAULT_SECURITY="" | ||
| 931 | # CONFIG_CRYPTO is not set | ||
| 932 | CONFIG_PPC_CLOCK=y | ||
| 933 | CONFIG_PPC_LIB_RHEAP=y | ||
| 934 | # CONFIG_VIRTUALIZATION is not set | ||
diff --git a/arch/powerpc/include/asm/abs_addr.h b/arch/powerpc/include/asm/abs_addr.h index 9a846efe6382..5ab0b71531be 100644 --- a/arch/powerpc/include/asm/abs_addr.h +++ b/arch/powerpc/include/asm/abs_addr.h | |||
| @@ -69,7 +69,7 @@ static inline unsigned long phys_to_abs(unsigned long pa) | |||
| 69 | * Legacy iSeries Hypervisor calls | 69 | * Legacy iSeries Hypervisor calls |
| 70 | */ | 70 | */ |
| 71 | #define iseries_hv_addr(virtaddr) \ | 71 | #define iseries_hv_addr(virtaddr) \ |
| 72 | (0x8000000000000000 | virt_to_abs(virtaddr)) | 72 | (0x8000000000000000UL | virt_to_abs(virtaddr)) |
| 73 | 73 | ||
| 74 | #endif /* __KERNEL__ */ | 74 | #endif /* __KERNEL__ */ |
| 75 | #endif /* _ASM_POWERPC_ABS_ADDR_H */ | 75 | #endif /* _ASM_POWERPC_ABS_ADDR_H */ |
diff --git a/arch/powerpc/include/asm/asm-compat.h b/arch/powerpc/include/asm/asm-compat.h index 2048a6aeea91..decad950f11a 100644 --- a/arch/powerpc/include/asm/asm-compat.h +++ b/arch/powerpc/include/asm/asm-compat.h | |||
| @@ -30,6 +30,7 @@ | |||
| 30 | #define PPC_STLCX stringify_in_c(stdcx.) | 30 | #define PPC_STLCX stringify_in_c(stdcx.) |
| 31 | #define PPC_CNTLZL stringify_in_c(cntlzd) | 31 | #define PPC_CNTLZL stringify_in_c(cntlzd) |
| 32 | #define PPC_LR_STKOFF 16 | 32 | #define PPC_LR_STKOFF 16 |
| 33 | #define PPC_MIN_STKFRM 112 | ||
| 33 | 34 | ||
| 34 | /* Move to CR, single-entry optimized version. Only available | 35 | /* Move to CR, single-entry optimized version. Only available |
| 35 | * on POWER4 and later. | 36 | * on POWER4 and later. |
| @@ -55,6 +56,7 @@ | |||
| 55 | #define PPC_CNTLZL stringify_in_c(cntlzw) | 56 | #define PPC_CNTLZL stringify_in_c(cntlzw) |
| 56 | #define PPC_MTOCRF stringify_in_c(mtcrf) | 57 | #define PPC_MTOCRF stringify_in_c(mtcrf) |
| 57 | #define PPC_LR_STKOFF 4 | 58 | #define PPC_LR_STKOFF 4 |
| 59 | #define PPC_MIN_STKFRM 16 | ||
| 58 | 60 | ||
| 59 | #endif | 61 | #endif |
| 60 | 62 | ||
diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h index b0b21134f61a..5e2e2cfcc81b 100644 --- a/arch/powerpc/include/asm/cputable.h +++ b/arch/powerpc/include/asm/cputable.h | |||
| @@ -517,6 +517,10 @@ static inline int cpu_has_feature(unsigned long feature) | |||
| 517 | & feature); | 517 | & feature); |
| 518 | } | 518 | } |
| 519 | 519 | ||
| 520 | #ifdef CONFIG_HAVE_HW_BREAKPOINT | ||
| 521 | #define HBP_NUM 1 | ||
| 522 | #endif /* CONFIG_HAVE_HW_BREAKPOINT */ | ||
| 523 | |||
| 520 | #endif /* !__ASSEMBLY__ */ | 524 | #endif /* !__ASSEMBLY__ */ |
| 521 | 525 | ||
| 522 | #endif /* __KERNEL__ */ | 526 | #endif /* __KERNEL__ */ |
diff --git a/arch/powerpc/include/asm/dbell.h b/arch/powerpc/include/asm/dbell.h index 501189a543d1..0893ab9343a6 100644 --- a/arch/powerpc/include/asm/dbell.h +++ b/arch/powerpc/include/asm/dbell.h | |||
| @@ -27,10 +27,10 @@ enum ppc_dbell { | |||
| 27 | PPC_G_DBELL_MC = 4, /* guest mcheck doorbell */ | 27 | PPC_G_DBELL_MC = 4, /* guest mcheck doorbell */ |
| 28 | }; | 28 | }; |
| 29 | 29 | ||
| 30 | #ifdef CONFIG_SMP | 30 | extern void doorbell_message_pass(int target, int msg); |
| 31 | extern unsigned long dbell_smp_message[NR_CPUS]; | 31 | extern void doorbell_exception(struct pt_regs *regs); |
| 32 | extern void smp_dbell_message_pass(int target, int msg); | 32 | extern void doorbell_check_self(void); |
| 33 | #endif | 33 | extern void doorbell_setup_this_cpu(void); |
| 34 | 34 | ||
| 35 | static inline void ppc_msgsnd(enum ppc_dbell type, u32 flags, u32 tag) | 35 | static inline void ppc_msgsnd(enum ppc_dbell type, u32 flags, u32 tag) |
| 36 | { | 36 | { |
diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h index 5119b7db3142..de03ca58db5d 100644 --- a/arch/powerpc/include/asm/hvcall.h +++ b/arch/powerpc/include/asm/hvcall.h | |||
| @@ -74,6 +74,7 @@ | |||
| 74 | #define H_NOT_ENOUGH_RESOURCES -44 | 74 | #define H_NOT_ENOUGH_RESOURCES -44 |
| 75 | #define H_R_STATE -45 | 75 | #define H_R_STATE -45 |
| 76 | #define H_RESCINDEND -46 | 76 | #define H_RESCINDEND -46 |
| 77 | #define H_MULTI_THREADS_ACTIVE -9005 | ||
| 77 | 78 | ||
| 78 | 79 | ||
| 79 | /* Long Busy is a condition that can be returned by the firmware | 80 | /* Long Busy is a condition that can be returned by the firmware |
diff --git a/arch/powerpc/include/asm/hw_breakpoint.h b/arch/powerpc/include/asm/hw_breakpoint.h new file mode 100644 index 000000000000..1c33ec17ca36 --- /dev/null +++ b/arch/powerpc/include/asm/hw_breakpoint.h | |||
| @@ -0,0 +1,74 @@ | |||
| 1 | /* | ||
| 2 | * PowerPC BookIII S hardware breakpoint definitions | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License as published by | ||
| 6 | * the Free Software Foundation; either version 2 of the License, or | ||
| 7 | * (at your option) any later version. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License | ||
| 15 | * along with this program; if not, write to the Free Software | ||
| 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 17 | * | ||
| 18 | * Copyright 2010, IBM Corporation. | ||
| 19 | * Author: K.Prasad <prasad@linux.vnet.ibm.com> | ||
| 20 | * | ||
| 21 | */ | ||
| 22 | |||
| 23 | #ifndef _PPC_BOOK3S_64_HW_BREAKPOINT_H | ||
| 24 | #define _PPC_BOOK3S_64_HW_BREAKPOINT_H | ||
| 25 | |||
| 26 | #ifdef __KERNEL__ | ||
| 27 | #ifdef CONFIG_HAVE_HW_BREAKPOINT | ||
| 28 | |||
| 29 | struct arch_hw_breakpoint { | ||
| 30 | bool extraneous_interrupt; | ||
| 31 | u8 len; /* length of the target data symbol */ | ||
| 32 | int type; | ||
| 33 | unsigned long address; | ||
| 34 | }; | ||
| 35 | |||
| 36 | #include <linux/kdebug.h> | ||
| 37 | #include <asm/reg.h> | ||
| 38 | #include <asm/system.h> | ||
| 39 | |||
| 40 | struct perf_event; | ||
| 41 | struct pmu; | ||
| 42 | struct perf_sample_data; | ||
| 43 | |||
| 44 | #define HW_BREAKPOINT_ALIGN 0x7 | ||
| 45 | /* Maximum permissible length of any HW Breakpoint */ | ||
| 46 | #define HW_BREAKPOINT_LEN 0x8 | ||
| 47 | |||
| 48 | extern int hw_breakpoint_slots(int type); | ||
| 49 | extern int arch_bp_generic_fields(int type, int *gen_bp_type); | ||
| 50 | extern int arch_check_bp_in_kernelspace(struct perf_event *bp); | ||
| 51 | extern int arch_validate_hwbkpt_settings(struct perf_event *bp); | ||
| 52 | extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused, | ||
| 53 | unsigned long val, void *data); | ||
| 54 | int arch_install_hw_breakpoint(struct perf_event *bp); | ||
| 55 | void arch_uninstall_hw_breakpoint(struct perf_event *bp); | ||
| 56 | void hw_breakpoint_pmu_read(struct perf_event *bp); | ||
| 57 | extern void flush_ptrace_hw_breakpoint(struct task_struct *tsk); | ||
| 58 | |||
| 59 | extern struct pmu perf_ops_bp; | ||
| 60 | extern void ptrace_triggered(struct perf_event *bp, int nmi, | ||
| 61 | struct perf_sample_data *data, struct pt_regs *regs); | ||
| 62 | static inline void hw_breakpoint_disable(void) | ||
| 63 | { | ||
| 64 | set_dabr(0); | ||
| 65 | } | ||
| 66 | extern void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs); | ||
| 67 | |||
| 68 | #else /* CONFIG_HAVE_HW_BREAKPOINT */ | ||
| 69 | static inline void hw_breakpoint_disable(void) { } | ||
| 70 | static inline void thread_change_pc(struct task_struct *tsk, | ||
| 71 | struct pt_regs *regs) { } | ||
| 72 | #endif /* CONFIG_HAVE_HW_BREAKPOINT */ | ||
| 73 | #endif /* __KERNEL__ */ | ||
| 74 | #endif /* _PPC_BOOK3S_64_HW_BREAKPOINT_H */ | ||
diff --git a/arch/powerpc/include/asm/irq.h b/arch/powerpc/include/asm/irq.h index ecba37a91749..67ab5fb7d153 100644 --- a/arch/powerpc/include/asm/irq.h +++ b/arch/powerpc/include/asm/irq.h | |||
| @@ -300,34 +300,6 @@ extern unsigned int irq_alloc_virt(struct irq_host *host, | |||
| 300 | */ | 300 | */ |
| 301 | extern void irq_free_virt(unsigned int virq, unsigned int count); | 301 | extern void irq_free_virt(unsigned int virq, unsigned int count); |
| 302 | 302 | ||
| 303 | |||
| 304 | /* -- OF helpers -- */ | ||
| 305 | |||
| 306 | /** | ||
| 307 | * irq_create_of_mapping - Map a hardware interrupt into linux virq space | ||
| 308 | * @controller: Device node of the interrupt controller | ||
| 309 | * @inspec: Interrupt specifier from the device-tree | ||
| 310 | * @intsize: Size of the interrupt specifier from the device-tree | ||
| 311 | * | ||
| 312 | * This function is identical to irq_create_mapping except that it takes | ||
| 313 | * as input informations straight from the device-tree (typically the results | ||
| 314 | * of the of_irq_map_*() functions. | ||
| 315 | */ | ||
| 316 | extern unsigned int irq_create_of_mapping(struct device_node *controller, | ||
| 317 | const u32 *intspec, unsigned int intsize); | ||
| 318 | |||
| 319 | /** | ||
| 320 | * irq_of_parse_and_map - Parse and Map an interrupt into linux virq space | ||
| 321 | * @device: Device node of the device whose interrupt is to be mapped | ||
| 322 | * @index: Index of the interrupt to map | ||
| 323 | * | ||
| 324 | * This function is a wrapper that chains of_irq_map_one() and | ||
| 325 | * irq_create_of_mapping() to make things easier to callers | ||
| 326 | */ | ||
| 327 | extern unsigned int irq_of_parse_and_map(struct device_node *dev, int index); | ||
| 328 | |||
| 329 | /* -- End OF helpers -- */ | ||
| 330 | |||
| 331 | /** | 303 | /** |
| 332 | * irq_early_init - Init irq remapping subsystem | 304 | * irq_early_init - Init irq remapping subsystem |
| 333 | */ | 305 | */ |
diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h index 9f0fc9e6ce0d..adc8e6cdf339 100644 --- a/arch/powerpc/include/asm/machdep.h +++ b/arch/powerpc/include/asm/machdep.h | |||
| @@ -266,6 +266,7 @@ struct machdep_calls { | |||
| 266 | void (*suspend_disable_irqs)(void); | 266 | void (*suspend_disable_irqs)(void); |
| 267 | void (*suspend_enable_irqs)(void); | 267 | void (*suspend_enable_irqs)(void); |
| 268 | #endif | 268 | #endif |
| 269 | int (*suspend_disable_cpu)(void); | ||
| 269 | 270 | ||
| 270 | #ifdef CONFIG_ARCH_CPU_PROBE_RELEASE | 271 | #ifdef CONFIG_ARCH_CPU_PROBE_RELEASE |
| 271 | ssize_t (*cpu_probe)(const char *, size_t); | 272 | ssize_t (*cpu_probe)(const char *, size_t); |
| @@ -277,6 +278,7 @@ extern void e500_idle(void); | |||
| 277 | extern void power4_idle(void); | 278 | extern void power4_idle(void); |
| 278 | extern void power4_cpu_offline_powersave(void); | 279 | extern void power4_cpu_offline_powersave(void); |
| 279 | extern void ppc6xx_idle(void); | 280 | extern void ppc6xx_idle(void); |
| 281 | extern void book3e_idle(void); | ||
| 280 | 282 | ||
| 281 | /* | 283 | /* |
| 282 | * ppc_md contains a copy of the machine description structure for the | 284 | * ppc_md contains a copy of the machine description structure for the |
| @@ -366,8 +368,5 @@ static inline void log_error(char *buf, unsigned int err_type, int fatal) | |||
| 366 | #define machine_late_initcall(mach,fn) __define_machine_initcall(mach,"7",fn,7) | 368 | #define machine_late_initcall(mach,fn) __define_machine_initcall(mach,"7",fn,7) |
| 367 | #define machine_late_initcall_sync(mach,fn) __define_machine_initcall(mach,"7s",fn,7s) | 369 | #define machine_late_initcall_sync(mach,fn) __define_machine_initcall(mach,"7s",fn,7s) |
| 368 | 370 | ||
| 369 | void generic_suspend_disable_irqs(void); | ||
| 370 | void generic_suspend_enable_irqs(void); | ||
| 371 | |||
| 372 | #endif /* __KERNEL__ */ | 371 | #endif /* __KERNEL__ */ |
| 373 | #endif /* _ASM_POWERPC_MACHDEP_H */ | 372 | #endif /* _ASM_POWERPC_MACHDEP_H */ |
diff --git a/arch/powerpc/include/asm/macio.h b/arch/powerpc/include/asm/macio.h index 675e159b5ef4..7ab82c825a03 100644 --- a/arch/powerpc/include/asm/macio.h +++ b/arch/powerpc/include/asm/macio.h | |||
| @@ -38,7 +38,7 @@ struct macio_dev | |||
| 38 | { | 38 | { |
| 39 | struct macio_bus *bus; /* macio bus this device is on */ | 39 | struct macio_bus *bus; /* macio bus this device is on */ |
| 40 | struct macio_dev *media_bay; /* Device is part of a media bay */ | 40 | struct macio_dev *media_bay; /* Device is part of a media bay */ |
| 41 | struct of_device ofdev; | 41 | struct platform_device ofdev; |
| 42 | struct device_dma_parameters dma_parms; /* ide needs that */ | 42 | struct device_dma_parameters dma_parms; /* ide needs that */ |
| 43 | int n_resources; | 43 | int n_resources; |
| 44 | struct resource resource[MACIO_DEV_COUNT_RESOURCES]; | 44 | struct resource resource[MACIO_DEV_COUNT_RESOURCES]; |
diff --git a/arch/powerpc/include/asm/mmu-book3e.h b/arch/powerpc/include/asm/mmu-book3e.h index 74695816205c..87a1d787c5b6 100644 --- a/arch/powerpc/include/asm/mmu-book3e.h +++ b/arch/powerpc/include/asm/mmu-book3e.h | |||
| @@ -193,6 +193,10 @@ struct mmu_psize_def | |||
| 193 | { | 193 | { |
| 194 | unsigned int shift; /* number of bits */ | 194 | unsigned int shift; /* number of bits */ |
| 195 | unsigned int enc; /* PTE encoding */ | 195 | unsigned int enc; /* PTE encoding */ |
| 196 | unsigned int ind; /* Corresponding indirect page size shift */ | ||
| 197 | unsigned int flags; | ||
| 198 | #define MMU_PAGE_SIZE_DIRECT 0x1 /* Supported as a direct size */ | ||
| 199 | #define MMU_PAGE_SIZE_INDIRECT 0x2 /* Supported as an indirect size */ | ||
| 196 | }; | 200 | }; |
| 197 | extern struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT]; | 201 | extern struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT]; |
| 198 | 202 | ||
diff --git a/arch/powerpc/include/asm/mpc5121.h b/arch/powerpc/include/asm/mpc5121.h index e6a30bb1d16a..8c0ab2ca689c 100644 --- a/arch/powerpc/include/asm/mpc5121.h +++ b/arch/powerpc/include/asm/mpc5121.h | |||
| @@ -21,4 +21,36 @@ struct mpc512x_reset_module { | |||
| 21 | u32 rcer; /* Reset Control Enable Register */ | 21 | u32 rcer; /* Reset Control Enable Register */ |
| 22 | }; | 22 | }; |
| 23 | 23 | ||
| 24 | /* | ||
| 25 | * Clock Control Module | ||
| 26 | */ | ||
| 27 | struct mpc512x_ccm { | ||
| 28 | u32 spmr; /* System PLL Mode Register */ | ||
| 29 | u32 sccr1; /* System Clock Control Register 1 */ | ||
| 30 | u32 sccr2; /* System Clock Control Register 2 */ | ||
| 31 | u32 scfr1; /* System Clock Frequency Register 1 */ | ||
| 32 | u32 scfr2; /* System Clock Frequency Register 2 */ | ||
| 33 | u32 scfr2s; /* System Clock Frequency Shadow Register 2 */ | ||
| 34 | u32 bcr; /* Bread Crumb Register */ | ||
| 35 | u32 p0ccr; /* PSC0 Clock Control Register */ | ||
| 36 | u32 p1ccr; /* PSC1 CCR */ | ||
| 37 | u32 p2ccr; /* PSC2 CCR */ | ||
| 38 | u32 p3ccr; /* PSC3 CCR */ | ||
| 39 | u32 p4ccr; /* PSC4 CCR */ | ||
| 40 | u32 p5ccr; /* PSC5 CCR */ | ||
| 41 | u32 p6ccr; /* PSC6 CCR */ | ||
| 42 | u32 p7ccr; /* PSC7 CCR */ | ||
| 43 | u32 p8ccr; /* PSC8 CCR */ | ||
| 44 | u32 p9ccr; /* PSC9 CCR */ | ||
| 45 | u32 p10ccr; /* PSC10 CCR */ | ||
| 46 | u32 p11ccr; /* PSC11 CCR */ | ||
| 47 | u32 spccr; /* SPDIF Clock Control Register */ | ||
| 48 | u32 cccr; /* CFM Clock Control Register */ | ||
| 49 | u32 dccr; /* DIU Clock Control Register */ | ||
| 50 | u32 m1ccr; /* MSCAN1 CCR */ | ||
| 51 | u32 m2ccr; /* MSCAN2 CCR */ | ||
| 52 | u32 m3ccr; /* MSCAN3 CCR */ | ||
| 53 | u32 m4ccr; /* MSCAN4 CCR */ | ||
| 54 | u8 res[0x98]; /* Reserved */ | ||
| 55 | }; | ||
| 24 | #endif /* __ASM_POWERPC_MPC5121_H__ */ | 56 | #endif /* __ASM_POWERPC_MPC5121_H__ */ |
diff --git a/arch/powerpc/include/asm/of_device.h b/arch/powerpc/include/asm/of_device.h deleted file mode 100644 index 444e97e2982e..000000000000 --- a/arch/powerpc/include/asm/of_device.h +++ /dev/null | |||
| @@ -1,27 +0,0 @@ | |||
| 1 | #ifndef _ASM_POWERPC_OF_DEVICE_H | ||
| 2 | #define _ASM_POWERPC_OF_DEVICE_H | ||
| 3 | #ifdef __KERNEL__ | ||
| 4 | |||
| 5 | #include <linux/device.h> | ||
| 6 | #include <linux/of.h> | ||
| 7 | |||
| 8 | /* | ||
| 9 | * The of_device is a kind of "base class" that is a superset of | ||
| 10 | * struct device for use by devices attached to an OF node and | ||
| 11 | * probed using OF properties. | ||
| 12 | */ | ||
| 13 | struct of_device | ||
| 14 | { | ||
| 15 | struct device dev; /* Generic device interface */ | ||
| 16 | struct pdev_archdata archdata; | ||
| 17 | }; | ||
| 18 | |||
| 19 | extern struct of_device *of_device_alloc(struct device_node *np, | ||
| 20 | const char *bus_id, | ||
| 21 | struct device *parent); | ||
| 22 | |||
| 23 | extern int of_device_uevent(struct device *dev, | ||
| 24 | struct kobj_uevent_env *env); | ||
| 25 | |||
| 26 | #endif /* __KERNEL__ */ | ||
| 27 | #endif /* _ASM_POWERPC_OF_DEVICE_H */ | ||
diff --git a/arch/powerpc/include/asm/of_platform.h b/arch/powerpc/include/asm/of_platform.h deleted file mode 100644 index d4aaa3489440..000000000000 --- a/arch/powerpc/include/asm/of_platform.h +++ /dev/null | |||
| @@ -1,29 +0,0 @@ | |||
| 1 | #ifndef _ASM_POWERPC_OF_PLATFORM_H | ||
| 2 | #define _ASM_POWERPC_OF_PLATFORM_H | ||
| 3 | /* | ||
| 4 | * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp. | ||
| 5 | * <benh@kernel.crashing.org> | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or | ||
| 8 | * modify it under the terms of the GNU General Public License | ||
| 9 | * as published by the Free Software Foundation; either version | ||
| 10 | * 2 of the License, or (at your option) any later version. | ||
| 11 | * | ||
| 12 | */ | ||
| 13 | |||
| 14 | /* Platform devices and busses creation */ | ||
| 15 | extern struct of_device *of_platform_device_create(struct device_node *np, | ||
| 16 | const char *bus_id, | ||
| 17 | struct device *parent); | ||
| 18 | /* pseudo "matches" value to not do deep probe */ | ||
| 19 | #define OF_NO_DEEP_PROBE ((struct of_device_id *)-1) | ||
| 20 | |||
| 21 | extern int of_platform_bus_probe(struct device_node *root, | ||
| 22 | const struct of_device_id *matches, | ||
| 23 | struct device *parent); | ||
| 24 | |||
| 25 | extern struct of_device *of_find_device_by_phandle(phandle ph); | ||
| 26 | |||
| 27 | extern void of_instantiate_rtc(void); | ||
| 28 | |||
| 29 | #endif /* _ASM_POWERPC_OF_PLATFORM_H */ | ||
diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h index 8ce7963ad41d..1ff6662f7faf 100644 --- a/arch/powerpc/include/asm/paca.h +++ b/arch/powerpc/include/asm/paca.h | |||
| @@ -146,7 +146,7 @@ struct paca_struct { | |||
| 146 | extern struct paca_struct *paca; | 146 | extern struct paca_struct *paca; |
| 147 | extern __initdata struct paca_struct boot_paca; | 147 | extern __initdata struct paca_struct boot_paca; |
| 148 | extern void initialise_paca(struct paca_struct *new_paca, int cpu); | 148 | extern void initialise_paca(struct paca_struct *new_paca, int cpu); |
| 149 | 149 | extern void setup_paca(struct paca_struct *new_paca); | |
| 150 | extern void allocate_pacas(void); | 150 | extern void allocate_pacas(void); |
| 151 | extern void free_unused_pacas(void); | 151 | extern void free_unused_pacas(void); |
| 152 | 152 | ||
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h index 76e1f313a58e..51e9e6f90d12 100644 --- a/arch/powerpc/include/asm/pci-bridge.h +++ b/arch/powerpc/include/asm/pci-bridge.h | |||
| @@ -303,13 +303,8 @@ extern void pcibios_free_controller(struct pci_controller *phb); | |||
| 303 | extern void pcibios_setup_phb_resources(struct pci_controller *hose); | 303 | extern void pcibios_setup_phb_resources(struct pci_controller *hose); |
| 304 | 304 | ||
| 305 | #ifdef CONFIG_PCI | 305 | #ifdef CONFIG_PCI |
| 306 | extern unsigned long pci_address_to_pio(phys_addr_t address); | ||
| 307 | extern int pcibios_vaddr_is_ioport(void __iomem *address); | 306 | extern int pcibios_vaddr_is_ioport(void __iomem *address); |
| 308 | #else | 307 | #else |
| 309 | static inline unsigned long pci_address_to_pio(phys_addr_t address) | ||
| 310 | { | ||
| 311 | return (unsigned long)-1; | ||
| 312 | } | ||
| 313 | static inline int pcibios_vaddr_is_ioport(void __iomem *address) | 308 | static inline int pcibios_vaddr_is_ioport(void __iomem *address) |
| 314 | { | 309 | { |
| 315 | return 0; | 310 | return 0; |
diff --git a/arch/powerpc/include/asm/percpu.h b/arch/powerpc/include/asm/percpu.h index f879252b7ea6..2cedefddba37 100644 --- a/arch/powerpc/include/asm/percpu.h +++ b/arch/powerpc/include/asm/percpu.h | |||
| @@ -1,7 +1,6 @@ | |||
| 1 | #ifndef _ASM_POWERPC_PERCPU_H_ | 1 | #ifndef _ASM_POWERPC_PERCPU_H_ |
| 2 | #define _ASM_POWERPC_PERCPU_H_ | 2 | #define _ASM_POWERPC_PERCPU_H_ |
| 3 | #ifdef __powerpc64__ | 3 | #ifdef __powerpc64__ |
| 4 | #include <linux/compiler.h> | ||
| 5 | 4 | ||
| 6 | /* | 5 | /* |
| 7 | * Same as asm-generic/percpu.h, except that we store the per cpu offset | 6 | * Same as asm-generic/percpu.h, except that we store the per cpu offset |
| @@ -12,9 +11,7 @@ | |||
| 12 | 11 | ||
| 13 | #include <asm/paca.h> | 12 | #include <asm/paca.h> |
| 14 | 13 | ||
| 15 | #define __per_cpu_offset(cpu) (paca[cpu].data_offset) | ||
| 16 | #define __my_cpu_offset local_paca->data_offset | 14 | #define __my_cpu_offset local_paca->data_offset |
| 17 | #define per_cpu_offset(x) (__per_cpu_offset(x)) | ||
| 18 | 15 | ||
| 19 | #endif /* CONFIG_SMP */ | 16 | #endif /* CONFIG_SMP */ |
| 20 | #endif /* __powerpc64__ */ | 17 | #endif /* __powerpc64__ */ |
diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h index d553bbeb726c..43adc8b819ed 100644 --- a/arch/powerpc/include/asm/ppc-opcode.h +++ b/arch/powerpc/include/asm/ppc-opcode.h | |||
| @@ -52,13 +52,17 @@ | |||
| 52 | #define PPC_INST_WAIT 0x7c00007c | 52 | #define PPC_INST_WAIT 0x7c00007c |
| 53 | #define PPC_INST_TLBIVAX 0x7c000624 | 53 | #define PPC_INST_TLBIVAX 0x7c000624 |
| 54 | #define PPC_INST_TLBSRX_DOT 0x7c0006a5 | 54 | #define PPC_INST_TLBSRX_DOT 0x7c0006a5 |
| 55 | #define PPC_INST_XXLOR 0xf0000510 | ||
| 55 | 56 | ||
| 56 | /* macros to insert fields into opcodes */ | 57 | /* macros to insert fields into opcodes */ |
| 57 | #define __PPC_RA(a) (((a) & 0x1f) << 16) | 58 | #define __PPC_RA(a) (((a) & 0x1f) << 16) |
| 58 | #define __PPC_RB(b) (((b) & 0x1f) << 11) | 59 | #define __PPC_RB(b) (((b) & 0x1f) << 11) |
| 59 | #define __PPC_RS(s) (((s) & 0x1f) << 21) | 60 | #define __PPC_RS(s) (((s) & 0x1f) << 21) |
| 60 | #define __PPC_RT(s) __PPC_RS(s) | 61 | #define __PPC_RT(s) __PPC_RS(s) |
| 62 | #define __PPC_XA(a) ((((a) & 0x1f) << 16) | (((a) & 0x20) >> 3)) | ||
| 63 | #define __PPC_XB(b) ((((b) & 0x1f) << 11) | (((b) & 0x20) >> 4)) | ||
| 61 | #define __PPC_XS(s) ((((s) & 0x1f) << 21) | (((s) & 0x20) >> 5)) | 64 | #define __PPC_XS(s) ((((s) & 0x1f) << 21) | (((s) & 0x20) >> 5)) |
| 65 | #define __PPC_XT(s) __PPC_XS(s) | ||
| 62 | #define __PPC_T_TLB(t) (((t) & 0x3) << 21) | 66 | #define __PPC_T_TLB(t) (((t) & 0x3) << 21) |
| 63 | #define __PPC_WC(w) (((w) & 0x3) << 21) | 67 | #define __PPC_WC(w) (((w) & 0x3) << 21) |
| 64 | /* | 68 | /* |
| @@ -106,9 +110,12 @@ | |||
| 106 | * the 128 bit load store instructions based on that. | 110 | * the 128 bit load store instructions based on that. |
| 107 | */ | 111 | */ |
| 108 | #define VSX_XX1(s, a, b) (__PPC_XS(s) | __PPC_RA(a) | __PPC_RB(b)) | 112 | #define VSX_XX1(s, a, b) (__PPC_XS(s) | __PPC_RA(a) | __PPC_RB(b)) |
| 113 | #define VSX_XX3(t, a, b) (__PPC_XT(t) | __PPC_XA(a) | __PPC_XB(b)) | ||
| 109 | #define STXVD2X(s, a, b) stringify_in_c(.long PPC_INST_STXVD2X | \ | 114 | #define STXVD2X(s, a, b) stringify_in_c(.long PPC_INST_STXVD2X | \ |
| 110 | VSX_XX1((s), (a), (b))) | 115 | VSX_XX1((s), (a), (b))) |
| 111 | #define LXVD2X(s, a, b) stringify_in_c(.long PPC_INST_LXVD2X | \ | 116 | #define LXVD2X(s, a, b) stringify_in_c(.long PPC_INST_LXVD2X | \ |
| 112 | VSX_XX1((s), (a), (b))) | 117 | VSX_XX1((s), (a), (b))) |
| 118 | #define XXLOR(t, a, b) stringify_in_c(.long PPC_INST_XXLOR | \ | ||
| 119 | VSX_XX3((t), (a), (b))) | ||
| 113 | 120 | ||
| 114 | #endif /* _ASM_POWERPC_PPC_OPCODE_H */ | 121 | #endif /* _ASM_POWERPC_PPC_OPCODE_H */ |
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index 7492fe8ad6e4..19c05b0f74be 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h | |||
| @@ -209,6 +209,14 @@ struct thread_struct { | |||
| 209 | #ifdef CONFIG_PPC64 | 209 | #ifdef CONFIG_PPC64 |
| 210 | unsigned long start_tb; /* Start purr when proc switched in */ | 210 | unsigned long start_tb; /* Start purr when proc switched in */ |
| 211 | unsigned long accum_tb; /* Total accumilated purr for process */ | 211 | unsigned long accum_tb; /* Total accumilated purr for process */ |
| 212 | #ifdef CONFIG_HAVE_HW_BREAKPOINT | ||
| 213 | struct perf_event *ptrace_bps[HBP_NUM]; | ||
| 214 | /* | ||
| 215 | * Helps identify source of single-step exception and subsequent | ||
| 216 | * hw-breakpoint enablement | ||
| 217 | */ | ||
| 218 | struct perf_event *last_hit_ubp; | ||
| 219 | #endif /* CONFIG_HAVE_HW_BREAKPOINT */ | ||
| 212 | #endif | 220 | #endif |
| 213 | unsigned long dabr; /* Data address breakpoint register */ | 221 | unsigned long dabr; /* Data address breakpoint register */ |
| 214 | #ifdef CONFIG_ALTIVEC | 222 | #ifdef CONFIG_ALTIVEC |
diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h index ddd408a93b5a..ae26f2efd089 100644 --- a/arch/powerpc/include/asm/prom.h +++ b/arch/powerpc/include/asm/prom.h | |||
| @@ -17,9 +17,6 @@ | |||
| 17 | * 2 of the License, or (at your option) any later version. | 17 | * 2 of the License, or (at your option) any later version. |
| 18 | */ | 18 | */ |
| 19 | #include <linux/types.h> | 19 | #include <linux/types.h> |
| 20 | #include <linux/of_fdt.h> | ||
| 21 | #include <linux/proc_fs.h> | ||
| 22 | #include <linux/platform_device.h> | ||
| 23 | #include <asm/irq.h> | 20 | #include <asm/irq.h> |
| 24 | #include <asm/atomic.h> | 21 | #include <asm/atomic.h> |
| 25 | 22 | ||
| @@ -43,49 +40,14 @@ extern void pci_create_OF_bus_map(void); | |||
| 43 | * OF address retreival & translation | 40 | * OF address retreival & translation |
| 44 | */ | 41 | */ |
| 45 | 42 | ||
| 46 | /* Translate an OF address block into a CPU physical address | ||
| 47 | */ | ||
| 48 | extern u64 of_translate_address(struct device_node *np, const u32 *addr); | ||
| 49 | |||
| 50 | /* Translate a DMA address from device space to CPU space */ | 43 | /* Translate a DMA address from device space to CPU space */ |
| 51 | extern u64 of_translate_dma_address(struct device_node *dev, | 44 | extern u64 of_translate_dma_address(struct device_node *dev, |
| 52 | const u32 *in_addr); | 45 | const u32 *in_addr); |
| 53 | 46 | ||
| 54 | /* Extract an address from a device, returns the region size and | ||
| 55 | * the address space flags too. The PCI version uses a BAR number | ||
| 56 | * instead of an absolute index | ||
| 57 | */ | ||
| 58 | extern const u32 *of_get_address(struct device_node *dev, int index, | ||
| 59 | u64 *size, unsigned int *flags); | ||
| 60 | #ifdef CONFIG_PCI | 47 | #ifdef CONFIG_PCI |
| 61 | extern const u32 *of_get_pci_address(struct device_node *dev, int bar_no, | 48 | extern unsigned long pci_address_to_pio(phys_addr_t address); |
| 62 | u64 *size, unsigned int *flags); | 49 | #define pci_address_to_pio pci_address_to_pio |
| 63 | #else | 50 | #endif /* CONFIG_PCI */ |
| 64 | static inline const u32 *of_get_pci_address(struct device_node *dev, | ||
| 65 | int bar_no, u64 *size, unsigned int *flags) | ||
| 66 | { | ||
| 67 | return NULL; | ||
| 68 | } | ||
| 69 | #endif /* CONFIG_PCI */ | ||
| 70 | |||
| 71 | /* Get an address as a resource. Note that if your address is | ||
| 72 | * a PIO address, the conversion will fail if the physical address | ||
| 73 | * can't be internally converted to an IO token with | ||
| 74 | * pci_address_to_pio(), that is because it's either called to early | ||
| 75 | * or it can't be matched to any host bridge IO space | ||
| 76 | */ | ||
| 77 | extern int of_address_to_resource(struct device_node *dev, int index, | ||
| 78 | struct resource *r); | ||
| 79 | #ifdef CONFIG_PCI | ||
| 80 | extern int of_pci_address_to_resource(struct device_node *dev, int bar, | ||
| 81 | struct resource *r); | ||
| 82 | #else | ||
| 83 | static inline int of_pci_address_to_resource(struct device_node *dev, int bar, | ||
| 84 | struct resource *r) | ||
| 85 | { | ||
| 86 | return -ENOSYS; | ||
| 87 | } | ||
| 88 | #endif /* CONFIG_PCI */ | ||
| 89 | 51 | ||
| 90 | /* Parse the ibm,dma-window property of an OF node into the busno, phys and | 52 | /* Parse the ibm,dma-window property of an OF node into the busno, phys and |
| 91 | * size parameters. | 53 | * size parameters. |
| @@ -104,69 +66,12 @@ struct device_node *of_find_next_cache_node(struct device_node *np); | |||
| 104 | /* Get the MAC address */ | 66 | /* Get the MAC address */ |
| 105 | extern const void *of_get_mac_address(struct device_node *np); | 67 | extern const void *of_get_mac_address(struct device_node *np); |
| 106 | 68 | ||
| 107 | /* | 69 | #ifdef CONFIG_NUMA |
| 108 | * OF interrupt mapping | 70 | extern int of_node_to_nid(struct device_node *device); |
| 109 | */ | 71 | #else |
| 110 | 72 | static inline int of_node_to_nid(struct device_node *device) { return 0; } | |
| 111 | /* This structure is returned when an interrupt is mapped. The controller | 73 | #endif |
| 112 | * field needs to be put() after use | 74 | #define of_node_to_nid of_node_to_nid |
| 113 | */ | ||
| 114 | |||
| 115 | #define OF_MAX_IRQ_SPEC 4 /* We handle specifiers of at most 4 cells */ | ||
| 116 | |||
| 117 | struct of_irq { | ||
| 118 | struct device_node *controller; /* Interrupt controller node */ | ||
| 119 | u32 size; /* Specifier size */ | ||
| 120 | u32 specifier[OF_MAX_IRQ_SPEC]; /* Specifier copy */ | ||
| 121 | }; | ||
| 122 | |||
| 123 | /** | ||
| 124 | * of_irq_map_init - Initialize the irq remapper | ||
| 125 | * @flags: flags defining workarounds to enable | ||
| 126 | * | ||
| 127 | * Some machines have bugs in the device-tree which require certain workarounds | ||
| 128 | * to be applied. Call this before any interrupt mapping attempts to enable | ||
| 129 | * those workarounds. | ||
| 130 | */ | ||
| 131 | #define OF_IMAP_OLDWORLD_MAC 0x00000001 | ||
| 132 | #define OF_IMAP_NO_PHANDLE 0x00000002 | ||
| 133 | |||
| 134 | extern void of_irq_map_init(unsigned int flags); | ||
| 135 | |||
| 136 | /** | ||
| 137 | * of_irq_map_raw - Low level interrupt tree parsing | ||
| 138 | * @parent: the device interrupt parent | ||
| 139 | * @intspec: interrupt specifier ("interrupts" property of the device) | ||
| 140 | * @ointsize: size of the passed in interrupt specifier | ||
| 141 | * @addr: address specifier (start of "reg" property of the device) | ||
| 142 | * @out_irq: structure of_irq filled by this function | ||
| 143 | * | ||
| 144 | * Returns 0 on success and a negative number on error | ||
| 145 | * | ||
| 146 | * This function is a low-level interrupt tree walking function. It | ||
| 147 | * can be used to do a partial walk with synthetized reg and interrupts | ||
| 148 | * properties, for example when resolving PCI interrupts when no device | ||
| 149 | * node exist for the parent. | ||
| 150 | * | ||
| 151 | */ | ||
| 152 | |||
| 153 | extern int of_irq_map_raw(struct device_node *parent, const u32 *intspec, | ||
| 154 | u32 ointsize, const u32 *addr, | ||
| 155 | struct of_irq *out_irq); | ||
| 156 | |||
| 157 | |||
| 158 | /** | ||
| 159 | * of_irq_map_one - Resolve an interrupt for a device | ||
| 160 | * @device: the device whose interrupt is to be resolved | ||
| 161 | * @index: index of the interrupt to resolve | ||
| 162 | * @out_irq: structure of_irq filled by this function | ||
| 163 | * | ||
| 164 | * This function resolves an interrupt, walking the tree, for a given | ||
| 165 | * device-tree node. It's the high level pendant to of_irq_map_raw(). | ||
| 166 | * It also implements the workarounds for OldWolrd Macs. | ||
| 167 | */ | ||
| 168 | extern int of_irq_map_one(struct device_node *device, int index, | ||
| 169 | struct of_irq *out_irq); | ||
| 170 | 75 | ||
| 171 | /** | 76 | /** |
| 172 | * of_irq_map_pci - Resolve the interrupt for a PCI device | 77 | * of_irq_map_pci - Resolve the interrupt for a PCI device |
| @@ -180,19 +85,19 @@ extern int of_irq_map_one(struct device_node *device, int index, | |||
| 180 | * resolving using the OF tree walking. | 85 | * resolving using the OF tree walking. |
| 181 | */ | 86 | */ |
| 182 | struct pci_dev; | 87 | struct pci_dev; |
| 88 | struct of_irq; | ||
| 183 | extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq); | 89 | extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq); |
| 184 | 90 | ||
| 185 | extern int of_irq_to_resource(struct device_node *dev, int index, | 91 | extern void of_instantiate_rtc(void); |
| 186 | struct resource *r); | ||
| 187 | 92 | ||
| 188 | /** | 93 | /* These includes are put at the bottom because they may contain things |
| 189 | * of_iomap - Maps the memory mapped IO for a given device_node | 94 | * that are overridden by this file. Ideally they shouldn't be included |
| 190 | * @device: the device whose io range will be mapped | 95 | * by this file, but there are a bunch of .c files that currently depend |
| 191 | * @index: index of the io range | 96 | * on it. Eventually they will be cleaned up. */ |
| 192 | * | 97 | #include <linux/of_fdt.h> |
| 193 | * Returns a pointer to the mapped memory | 98 | #include <linux/of_address.h> |
| 194 | */ | 99 | #include <linux/of_irq.h> |
| 195 | extern void __iomem *of_iomap(struct device_node *device, int index); | 100 | #include <linux/platform_device.h> |
| 196 | 101 | ||
| 197 | #endif /* __KERNEL__ */ | 102 | #endif /* __KERNEL__ */ |
| 198 | #endif /* _POWERPC_PROM_H */ | 103 | #endif /* _POWERPC_PROM_H */ |
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index d62fdf4e504b..d8be016d2ede 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h | |||
| @@ -890,7 +890,7 @@ | |||
| 890 | #ifndef __ASSEMBLY__ | 890 | #ifndef __ASSEMBLY__ |
| 891 | #define mfmsr() ({unsigned long rval; \ | 891 | #define mfmsr() ({unsigned long rval; \ |
| 892 | asm volatile("mfmsr %0" : "=r" (rval)); rval;}) | 892 | asm volatile("mfmsr %0" : "=r" (rval)); rval;}) |
| 893 | #ifdef CONFIG_PPC64 | 893 | #ifdef CONFIG_PPC_BOOK3S_64 |
| 894 | #define __mtmsrd(v, l) asm volatile("mtmsrd %0," __stringify(l) \ | 894 | #define __mtmsrd(v, l) asm volatile("mtmsrd %0," __stringify(l) \ |
| 895 | : : "r" (v) : "memory") | 895 | : : "r" (v) : "memory") |
| 896 | #define mtmsrd(v) __mtmsrd((v), 0) | 896 | #define mtmsrd(v) __mtmsrd((v), 0) |
diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h index 2360317179a9..667a498eaee1 100644 --- a/arch/powerpc/include/asm/reg_booke.h +++ b/arch/powerpc/include/asm/reg_booke.h | |||
| @@ -29,8 +29,8 @@ | |||
| 29 | #if defined(CONFIG_PPC_BOOK3E_64) | 29 | #if defined(CONFIG_PPC_BOOK3E_64) |
| 30 | #define MSR_ MSR_ME | MSR_CE | 30 | #define MSR_ MSR_ME | MSR_CE |
| 31 | #define MSR_KERNEL MSR_ | MSR_CM | 31 | #define MSR_KERNEL MSR_ | MSR_CM |
| 32 | #define MSR_USER32 MSR_ | MSR_PR | MSR_EE | 32 | #define MSR_USER32 MSR_ | MSR_PR | MSR_EE | MSR_DE |
| 33 | #define MSR_USER64 MSR_USER32 | MSR_CM | 33 | #define MSR_USER64 MSR_USER32 | MSR_CM | MSR_DE |
| 34 | #elif defined (CONFIG_40x) | 34 | #elif defined (CONFIG_40x) |
| 35 | #define MSR_KERNEL (MSR_ME|MSR_RI|MSR_IR|MSR_DR|MSR_CE) | 35 | #define MSR_KERNEL (MSR_ME|MSR_RI|MSR_IR|MSR_DR|MSR_CE) |
| 36 | #define MSR_USER (MSR_KERNEL|MSR_PR|MSR_EE) | 36 | #define MSR_USER (MSR_KERNEL|MSR_PR|MSR_EE) |
| @@ -62,6 +62,7 @@ | |||
| 62 | #define SPRN_TLB0PS 0x158 /* TLB 0 Page Size Register */ | 62 | #define SPRN_TLB0PS 0x158 /* TLB 0 Page Size Register */ |
| 63 | #define SPRN_MAS5_MAS6 0x15c /* MMU Assist Register 5 || 6 */ | 63 | #define SPRN_MAS5_MAS6 0x15c /* MMU Assist Register 5 || 6 */ |
| 64 | #define SPRN_MAS8_MAS1 0x15d /* MMU Assist Register 8 || 1 */ | 64 | #define SPRN_MAS8_MAS1 0x15d /* MMU Assist Register 8 || 1 */ |
| 65 | #define SPRN_EPTCFG 0x15e /* Embedded Page Table Config */ | ||
| 65 | #define SPRN_MAS7_MAS3 0x174 /* MMU Assist Register 7 || 3 */ | 66 | #define SPRN_MAS7_MAS3 0x174 /* MMU Assist Register 7 || 3 */ |
| 66 | #define SPRN_MAS0_MAS1 0x175 /* MMU Assist Register 0 || 1 */ | 67 | #define SPRN_MAS0_MAS1 0x175 /* MMU Assist Register 0 || 1 */ |
| 67 | #define SPRN_IVOR0 0x190 /* Interrupt Vector Offset Register 0 */ | 68 | #define SPRN_IVOR0 0x190 /* Interrupt Vector Offset Register 0 */ |
diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h index 20de73c36682..3d35f8ae377e 100644 --- a/arch/powerpc/include/asm/rtas.h +++ b/arch/powerpc/include/asm/rtas.h | |||
| @@ -63,6 +63,14 @@ struct rtas_t { | |||
| 63 | struct device_node *dev; /* virtual address pointer */ | 63 | struct device_node *dev; /* virtual address pointer */ |
| 64 | }; | 64 | }; |
| 65 | 65 | ||
| 66 | struct rtas_suspend_me_data { | ||
| 67 | atomic_t working; /* number of cpus accessing this struct */ | ||
| 68 | atomic_t done; | ||
| 69 | int token; /* ibm,suspend-me */ | ||
| 70 | atomic_t error; | ||
| 71 | struct completion *complete; /* wait on this until working == 0 */ | ||
| 72 | }; | ||
| 73 | |||
| 66 | /* RTAS event classes */ | 74 | /* RTAS event classes */ |
| 67 | #define RTAS_INTERNAL_ERROR 0x80000000 /* set bit 0 */ | 75 | #define RTAS_INTERNAL_ERROR 0x80000000 /* set bit 0 */ |
| 68 | #define RTAS_EPOW_WARNING 0x40000000 /* set bit 1 */ | 76 | #define RTAS_EPOW_WARNING 0x40000000 /* set bit 1 */ |
| @@ -137,6 +145,9 @@ struct rtas_t { | |||
| 137 | #define RTAS_TYPE_PMGM_CONFIG_CHANGE 0x70 | 145 | #define RTAS_TYPE_PMGM_CONFIG_CHANGE 0x70 |
| 138 | #define RTAS_TYPE_PMGM_SERVICE_PROC 0x71 | 146 | #define RTAS_TYPE_PMGM_SERVICE_PROC 0x71 |
| 139 | 147 | ||
| 148 | /* RTAS check-exception vector offset */ | ||
| 149 | #define RTAS_VECTOR_EXTERNAL_INTERRUPT 0x500 | ||
| 150 | |||
| 140 | struct rtas_error_log { | 151 | struct rtas_error_log { |
| 141 | unsigned long version:8; /* Architectural version */ | 152 | unsigned long version:8; /* Architectural version */ |
| 142 | unsigned long severity:3; /* Severity level of error */ | 153 | unsigned long severity:3; /* Severity level of error */ |
| @@ -174,6 +185,8 @@ extern int rtas_set_indicator(int indicator, int index, int new_value); | |||
| 174 | extern int rtas_set_indicator_fast(int indicator, int index, int new_value); | 185 | extern int rtas_set_indicator_fast(int indicator, int index, int new_value); |
| 175 | extern void rtas_progress(char *s, unsigned short hex); | 186 | extern void rtas_progress(char *s, unsigned short hex); |
| 176 | extern void rtas_initialize(void); | 187 | extern void rtas_initialize(void); |
| 188 | extern int rtas_suspend_cpu(struct rtas_suspend_me_data *data); | ||
| 189 | extern int rtas_suspend_last_cpu(struct rtas_suspend_me_data *data); | ||
| 177 | 190 | ||
| 178 | struct rtc_time; | 191 | struct rtc_time; |
| 179 | extern unsigned long rtas_get_boot_time(void); | 192 | extern unsigned long rtas_get_boot_time(void); |
diff --git a/arch/powerpc/include/asm/smu.h b/arch/powerpc/include/asm/smu.h index 7ae2753da565..e3bdada8c542 100644 --- a/arch/powerpc/include/asm/smu.h +++ b/arch/powerpc/include/asm/smu.h | |||
| @@ -457,8 +457,8 @@ extern void smu_poll(void); | |||
| 457 | */ | 457 | */ |
| 458 | extern int smu_init(void); | 458 | extern int smu_init(void); |
| 459 | extern int smu_present(void); | 459 | extern int smu_present(void); |
| 460 | struct of_device; | 460 | struct platform_device; |
| 461 | extern struct of_device *smu_get_ofdev(void); | 461 | extern struct platform_device *smu_get_ofdev(void); |
| 462 | 462 | ||
| 463 | 463 | ||
| 464 | /* | 464 | /* |
diff --git a/arch/powerpc/include/asm/time.h b/arch/powerpc/include/asm/time.h index 27ccb764fdab..dc779dfcf258 100644 --- a/arch/powerpc/include/asm/time.h +++ b/arch/powerpc/include/asm/time.h | |||
| @@ -28,16 +28,12 @@ | |||
| 28 | extern unsigned long tb_ticks_per_jiffy; | 28 | extern unsigned long tb_ticks_per_jiffy; |
| 29 | extern unsigned long tb_ticks_per_usec; | 29 | extern unsigned long tb_ticks_per_usec; |
| 30 | extern unsigned long tb_ticks_per_sec; | 30 | extern unsigned long tb_ticks_per_sec; |
| 31 | extern u64 tb_to_xs; | ||
| 32 | extern unsigned tb_to_us; | ||
| 33 | 31 | ||
| 34 | struct rtc_time; | 32 | struct rtc_time; |
| 35 | extern void to_tm(int tim, struct rtc_time * tm); | 33 | extern void to_tm(int tim, struct rtc_time * tm); |
| 36 | extern void GregorianDay(struct rtc_time *tm); | 34 | extern void GregorianDay(struct rtc_time *tm); |
| 37 | extern time_t last_rtc_update; | ||
| 38 | 35 | ||
| 39 | extern void generic_calibrate_decr(void); | 36 | extern void generic_calibrate_decr(void); |
| 40 | extern void wakeup_decrementer(void); | ||
| 41 | extern void snapshot_timebase(void); | 37 | extern void snapshot_timebase(void); |
| 42 | 38 | ||
| 43 | extern void set_dec_cpu6(unsigned int val); | 39 | extern void set_dec_cpu6(unsigned int val); |
| @@ -204,9 +200,6 @@ static inline unsigned long tb_ticks_since(unsigned long tstamp) | |||
| 204 | extern u64 mulhdu(u64, u64); | 200 | extern u64 mulhdu(u64, u64); |
| 205 | #endif | 201 | #endif |
| 206 | 202 | ||
| 207 | extern void smp_space_timers(unsigned int); | ||
| 208 | |||
| 209 | extern unsigned mulhwu_scale_factor(unsigned, unsigned); | ||
| 210 | extern void div128_by_32(u64 dividend_high, u64 dividend_low, | 203 | extern void div128_by_32(u64 dividend_high, u64 dividend_low, |
| 211 | unsigned divisor, struct div_result *dr); | 204 | unsigned divisor, struct div_result *dr); |
| 212 | 205 | ||
diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h index 32adf7280720..afe4aaa65c3b 100644 --- a/arch/powerpc/include/asm/topology.h +++ b/arch/powerpc/include/asm/topology.h | |||
| @@ -41,8 +41,6 @@ static inline int cpu_to_node(int cpu) | |||
| 41 | cpu_all_mask : \ | 41 | cpu_all_mask : \ |
| 42 | node_to_cpumask_map[node]) | 42 | node_to_cpumask_map[node]) |
| 43 | 43 | ||
| 44 | int of_node_to_nid(struct device_node *device); | ||
| 45 | |||
| 46 | struct pci_bus; | 44 | struct pci_bus; |
| 47 | #ifdef CONFIG_PCI | 45 | #ifdef CONFIG_PCI |
| 48 | extern int pcibus_to_node(struct pci_bus *bus); | 46 | extern int pcibus_to_node(struct pci_bus *bus); |
| @@ -87,6 +85,9 @@ static inline int pcibus_to_node(struct pci_bus *bus) | |||
| 87 | .balance_interval = 1, \ | 85 | .balance_interval = 1, \ |
| 88 | } | 86 | } |
| 89 | 87 | ||
| 88 | extern int __node_distance(int, int); | ||
| 89 | #define node_distance(a, b) __node_distance(a, b) | ||
| 90 | |||
| 90 | extern void __init dump_numa_cpu_topology(void); | 91 | extern void __init dump_numa_cpu_topology(void); |
| 91 | 92 | ||
| 92 | extern int sysfs_add_device_to_node(struct sys_device *dev, int nid); | 93 | extern int sysfs_add_device_to_node(struct sys_device *dev, int nid); |
| @@ -94,11 +95,6 @@ extern void sysfs_remove_device_from_node(struct sys_device *dev, int nid); | |||
| 94 | 95 | ||
| 95 | #else | 96 | #else |
| 96 | 97 | ||
| 97 | static inline int of_node_to_nid(struct device_node *device) | ||
| 98 | { | ||
| 99 | return 0; | ||
| 100 | } | ||
| 101 | |||
| 102 | static inline void dump_numa_cpu_topology(void) {} | 98 | static inline void dump_numa_cpu_topology(void) {} |
| 103 | 99 | ||
| 104 | static inline int sysfs_add_device_to_node(struct sys_device *dev, int nid) | 100 | static inline int sysfs_add_device_to_node(struct sys_device *dev, int nid) |
diff --git a/arch/powerpc/include/asm/vdso_datapage.h b/arch/powerpc/include/asm/vdso_datapage.h index 13c2c283e178..08679c5319b8 100644 --- a/arch/powerpc/include/asm/vdso_datapage.h +++ b/arch/powerpc/include/asm/vdso_datapage.h | |||
| @@ -85,6 +85,7 @@ struct vdso_data { | |||
| 85 | __s32 wtom_clock_sec; /* Wall to monotonic clock */ | 85 | __s32 wtom_clock_sec; /* Wall to monotonic clock */ |
| 86 | __s32 wtom_clock_nsec; | 86 | __s32 wtom_clock_nsec; |
| 87 | struct timespec stamp_xtime; /* xtime as at tb_orig_stamp */ | 87 | struct timespec stamp_xtime; /* xtime as at tb_orig_stamp */ |
| 88 | __u32 stamp_sec_fraction; /* fractional seconds of stamp_xtime */ | ||
| 88 | __u32 syscall_map_64[SYSCALL_MAP_SIZE]; /* map of syscalls */ | 89 | __u32 syscall_map_64[SYSCALL_MAP_SIZE]; /* map of syscalls */ |
| 89 | __u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */ | 90 | __u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */ |
| 90 | }; | 91 | }; |
| @@ -105,6 +106,7 @@ struct vdso_data { | |||
| 105 | __s32 wtom_clock_sec; /* Wall to monotonic clock */ | 106 | __s32 wtom_clock_sec; /* Wall to monotonic clock */ |
| 106 | __s32 wtom_clock_nsec; | 107 | __s32 wtom_clock_nsec; |
| 107 | struct timespec stamp_xtime; /* xtime as at tb_orig_stamp */ | 108 | struct timespec stamp_xtime; /* xtime as at tb_orig_stamp */ |
| 109 | __u32 stamp_sec_fraction; /* fractional seconds of stamp_xtime */ | ||
| 108 | __u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */ | 110 | __u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */ |
| 109 | __u32 dcache_block_size; /* L1 d-cache block size */ | 111 | __u32 dcache_block_size; /* L1 d-cache block size */ |
| 110 | __u32 icache_block_size; /* L1 i-cache block size */ | 112 | __u32 icache_block_size; /* L1 i-cache block size */ |
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 58d0572de6f9..1dda70129141 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile | |||
| @@ -34,13 +34,14 @@ obj-y += vdso32/ | |||
| 34 | obj-$(CONFIG_PPC64) += setup_64.o sys_ppc32.o \ | 34 | obj-$(CONFIG_PPC64) += setup_64.o sys_ppc32.o \ |
| 35 | signal_64.o ptrace32.o \ | 35 | signal_64.o ptrace32.o \ |
| 36 | paca.o nvram_64.o firmware.o | 36 | paca.o nvram_64.o firmware.o |
| 37 | obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o | ||
| 37 | obj-$(CONFIG_PPC_BOOK3S_64) += cpu_setup_ppc970.o cpu_setup_pa6t.o | 38 | obj-$(CONFIG_PPC_BOOK3S_64) += cpu_setup_ppc970.o cpu_setup_pa6t.o |
| 38 | obj64-$(CONFIG_RELOCATABLE) += reloc_64.o | 39 | obj64-$(CONFIG_RELOCATABLE) += reloc_64.o |
| 39 | obj-$(CONFIG_PPC_BOOK3E_64) += exceptions-64e.o | 40 | obj-$(CONFIG_PPC_BOOK3E_64) += exceptions-64e.o idle_book3e.o |
| 40 | obj-$(CONFIG_PPC64) += vdso64/ | 41 | obj-$(CONFIG_PPC64) += vdso64/ |
| 41 | obj-$(CONFIG_ALTIVEC) += vecemu.o | 42 | obj-$(CONFIG_ALTIVEC) += vecemu.o |
| 42 | obj-$(CONFIG_PPC_970_NAP) += idle_power4.o | 43 | obj-$(CONFIG_PPC_970_NAP) += idle_power4.o |
| 43 | obj-$(CONFIG_PPC_OF) += of_device.o of_platform.o prom_parse.o | 44 | obj-$(CONFIG_PPC_OF) += of_platform.o prom_parse.o |
| 44 | obj-$(CONFIG_PPC_CLOCK) += clock.o | 45 | obj-$(CONFIG_PPC_CLOCK) += clock.o |
| 45 | procfs-y := proc_powerpc.o | 46 | procfs-y := proc_powerpc.o |
| 46 | obj-$(CONFIG_PROC_FS) += $(procfs-y) | 47 | obj-$(CONFIG_PROC_FS) += $(procfs-y) |
| @@ -67,6 +68,7 @@ obj64-$(CONFIG_HIBERNATION) += swsusp_asm64.o | |||
| 67 | obj-$(CONFIG_MODULES) += module.o module_$(CONFIG_WORD_SIZE).o | 68 | obj-$(CONFIG_MODULES) += module.o module_$(CONFIG_WORD_SIZE).o |
| 68 | obj-$(CONFIG_44x) += cpu_setup_44x.o | 69 | obj-$(CONFIG_44x) += cpu_setup_44x.o |
| 69 | obj-$(CONFIG_FSL_BOOKE) += cpu_setup_fsl_booke.o dbell.o | 70 | obj-$(CONFIG_FSL_BOOKE) += cpu_setup_fsl_booke.o dbell.o |
| 71 | obj-$(CONFIG_PPC_BOOK3E_64) += dbell.o | ||
| 70 | 72 | ||
| 71 | extra-y := head_$(CONFIG_WORD_SIZE).o | 73 | extra-y := head_$(CONFIG_WORD_SIZE).o |
| 72 | extra-$(CONFIG_PPC_BOOK3E_32) := head_new_booke.o | 74 | extra-$(CONFIG_PPC_BOOK3E_32) := head_new_booke.o |
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 496cc5b3984f..1c0607ddccc0 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
| @@ -194,7 +194,6 @@ int main(void) | |||
| 194 | DEFINE(PACA_STARTSPURR, offsetof(struct paca_struct, startspurr)); | 194 | DEFINE(PACA_STARTSPURR, offsetof(struct paca_struct, startspurr)); |
| 195 | DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time)); | 195 | DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time)); |
| 196 | DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time)); | 196 | DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time)); |
| 197 | DEFINE(PACA_DATA_OFFSET, offsetof(struct paca_struct, data_offset)); | ||
| 198 | DEFINE(PACA_TRAP_SAVE, offsetof(struct paca_struct, trap_save)); | 197 | DEFINE(PACA_TRAP_SAVE, offsetof(struct paca_struct, trap_save)); |
| 199 | #ifdef CONFIG_KVM_BOOK3S_64_HANDLER | 198 | #ifdef CONFIG_KVM_BOOK3S_64_HANDLER |
| 200 | DEFINE(PACA_KVM_SVCPU, offsetof(struct paca_struct, shadow_vcpu)); | 199 | DEFINE(PACA_KVM_SVCPU, offsetof(struct paca_struct, shadow_vcpu)); |
| @@ -342,6 +341,7 @@ int main(void) | |||
| 342 | DEFINE(WTOM_CLOCK_SEC, offsetof(struct vdso_data, wtom_clock_sec)); | 341 | DEFINE(WTOM_CLOCK_SEC, offsetof(struct vdso_data, wtom_clock_sec)); |
| 343 | DEFINE(WTOM_CLOCK_NSEC, offsetof(struct vdso_data, wtom_clock_nsec)); | 342 | DEFINE(WTOM_CLOCK_NSEC, offsetof(struct vdso_data, wtom_clock_nsec)); |
| 344 | DEFINE(STAMP_XTIME, offsetof(struct vdso_data, stamp_xtime)); | 343 | DEFINE(STAMP_XTIME, offsetof(struct vdso_data, stamp_xtime)); |
| 344 | DEFINE(STAMP_SEC_FRAC, offsetof(struct vdso_data, stamp_sec_fraction)); | ||
| 345 | DEFINE(CFG_ICACHE_BLOCKSZ, offsetof(struct vdso_data, icache_block_size)); | 345 | DEFINE(CFG_ICACHE_BLOCKSZ, offsetof(struct vdso_data, icache_block_size)); |
| 346 | DEFINE(CFG_DCACHE_BLOCKSZ, offsetof(struct vdso_data, dcache_block_size)); | 346 | DEFINE(CFG_DCACHE_BLOCKSZ, offsetof(struct vdso_data, dcache_block_size)); |
| 347 | DEFINE(CFG_ICACHE_LOGBLOCKSZ, offsetof(struct vdso_data, icache_log_block_size)); | 347 | DEFINE(CFG_ICACHE_LOGBLOCKSZ, offsetof(struct vdso_data, icache_log_block_size)); |
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 87aa0f3c6047..65e2b4e10f97 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c | |||
| @@ -1364,10 +1364,10 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
| 1364 | .machine_check = machine_check_4xx, | 1364 | .machine_check = machine_check_4xx, |
| 1365 | .platform = "ppc405", | 1365 | .platform = "ppc405", |
| 1366 | }, | 1366 | }, |
| 1367 | { /* 405EX */ | 1367 | { /* 405EX Rev. A/B with Security */ |
| 1368 | .pvr_mask = 0xffff0004, | 1368 | .pvr_mask = 0xffff000f, |
| 1369 | .pvr_value = 0x12910004, | 1369 | .pvr_value = 0x12910007, |
| 1370 | .cpu_name = "405EX", | 1370 | .cpu_name = "405EX Rev. A/B", |
| 1371 | .cpu_features = CPU_FTRS_40X, | 1371 | .cpu_features = CPU_FTRS_40X, |
| 1372 | .cpu_user_features = PPC_FEATURE_32 | | 1372 | .cpu_user_features = PPC_FEATURE_32 | |
| 1373 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | 1373 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, |
| @@ -1377,10 +1377,114 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
| 1377 | .machine_check = machine_check_4xx, | 1377 | .machine_check = machine_check_4xx, |
| 1378 | .platform = "ppc405", | 1378 | .platform = "ppc405", |
| 1379 | }, | 1379 | }, |
| 1380 | { /* 405EXr */ | 1380 | { /* 405EX Rev. C without Security */ |
| 1381 | .pvr_mask = 0xffff0004, | 1381 | .pvr_mask = 0xffff000f, |
| 1382 | .pvr_value = 0x1291000d, | ||
| 1383 | .cpu_name = "405EX Rev. C", | ||
| 1384 | .cpu_features = CPU_FTRS_40X, | ||
| 1385 | .cpu_user_features = PPC_FEATURE_32 | | ||
| 1386 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | ||
| 1387 | .mmu_features = MMU_FTR_TYPE_40x, | ||
| 1388 | .icache_bsize = 32, | ||
| 1389 | .dcache_bsize = 32, | ||
| 1390 | .machine_check = machine_check_4xx, | ||
| 1391 | .platform = "ppc405", | ||
| 1392 | }, | ||
| 1393 | { /* 405EX Rev. C with Security */ | ||
| 1394 | .pvr_mask = 0xffff000f, | ||
| 1395 | .pvr_value = 0x1291000f, | ||
| 1396 | .cpu_name = "405EX Rev. C", | ||
| 1397 | .cpu_features = CPU_FTRS_40X, | ||
| 1398 | .cpu_user_features = PPC_FEATURE_32 | | ||
| 1399 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | ||
| 1400 | .mmu_features = MMU_FTR_TYPE_40x, | ||
| 1401 | .icache_bsize = 32, | ||
| 1402 | .dcache_bsize = 32, | ||
| 1403 | .machine_check = machine_check_4xx, | ||
| 1404 | .platform = "ppc405", | ||
| 1405 | }, | ||
| 1406 | { /* 405EX Rev. D without Security */ | ||
| 1407 | .pvr_mask = 0xffff000f, | ||
| 1408 | .pvr_value = 0x12910003, | ||
| 1409 | .cpu_name = "405EX Rev. D", | ||
| 1410 | .cpu_features = CPU_FTRS_40X, | ||
| 1411 | .cpu_user_features = PPC_FEATURE_32 | | ||
| 1412 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | ||
| 1413 | .mmu_features = MMU_FTR_TYPE_40x, | ||
| 1414 | .icache_bsize = 32, | ||
| 1415 | .dcache_bsize = 32, | ||
| 1416 | .machine_check = machine_check_4xx, | ||
| 1417 | .platform = "ppc405", | ||
| 1418 | }, | ||
| 1419 | { /* 405EX Rev. D with Security */ | ||
| 1420 | .pvr_mask = 0xffff000f, | ||
| 1421 | .pvr_value = 0x12910005, | ||
| 1422 | .cpu_name = "405EX Rev. D", | ||
| 1423 | .cpu_features = CPU_FTRS_40X, | ||
| 1424 | .cpu_user_features = PPC_FEATURE_32 | | ||
| 1425 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | ||
| 1426 | .mmu_features = MMU_FTR_TYPE_40x, | ||
| 1427 | .icache_bsize = 32, | ||
| 1428 | .dcache_bsize = 32, | ||
| 1429 | .machine_check = machine_check_4xx, | ||
| 1430 | .platform = "ppc405", | ||
| 1431 | }, | ||
| 1432 | { /* 405EXr Rev. A/B without Security */ | ||
| 1433 | .pvr_mask = 0xffff000f, | ||
| 1434 | .pvr_value = 0x12910001, | ||
| 1435 | .cpu_name = "405EXr Rev. A/B", | ||
| 1436 | .cpu_features = CPU_FTRS_40X, | ||
| 1437 | .cpu_user_features = PPC_FEATURE_32 | | ||
| 1438 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | ||
| 1439 | .mmu_features = MMU_FTR_TYPE_40x, | ||
| 1440 | .icache_bsize = 32, | ||
| 1441 | .dcache_bsize = 32, | ||
| 1442 | .machine_check = machine_check_4xx, | ||
| 1443 | .platform = "ppc405", | ||
| 1444 | }, | ||
| 1445 | { /* 405EXr Rev. C without Security */ | ||
| 1446 | .pvr_mask = 0xffff000f, | ||
| 1447 | .pvr_value = 0x12910009, | ||
| 1448 | .cpu_name = "405EXr Rev. C", | ||
| 1449 | .cpu_features = CPU_FTRS_40X, | ||
| 1450 | .cpu_user_features = PPC_FEATURE_32 | | ||
| 1451 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | ||
| 1452 | .mmu_features = MMU_FTR_TYPE_40x, | ||
| 1453 | .icache_bsize = 32, | ||
| 1454 | .dcache_bsize = 32, | ||
| 1455 | .machine_check = machine_check_4xx, | ||
| 1456 | .platform = "ppc405", | ||
| 1457 | }, | ||
| 1458 | { /* 405EXr Rev. C with Security */ | ||
| 1459 | .pvr_mask = 0xffff000f, | ||
| 1460 | .pvr_value = 0x1291000b, | ||
| 1461 | .cpu_name = "405EXr Rev. C", | ||
| 1462 | .cpu_features = CPU_FTRS_40X, | ||
| 1463 | .cpu_user_features = PPC_FEATURE_32 | | ||
| 1464 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | ||
| 1465 | .mmu_features = MMU_FTR_TYPE_40x, | ||
| 1466 | .icache_bsize = 32, | ||
| 1467 | .dcache_bsize = 32, | ||
| 1468 | .machine_check = machine_check_4xx, | ||
| 1469 | .platform = "ppc405", | ||
| 1470 | }, | ||
| 1471 | { /* 405EXr Rev. D without Security */ | ||
| 1472 | .pvr_mask = 0xffff000f, | ||
| 1382 | .pvr_value = 0x12910000, | 1473 | .pvr_value = 0x12910000, |
| 1383 | .cpu_name = "405EXr", | 1474 | .cpu_name = "405EXr Rev. D", |
| 1475 | .cpu_features = CPU_FTRS_40X, | ||
| 1476 | .cpu_user_features = PPC_FEATURE_32 | | ||
| 1477 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | ||
| 1478 | .mmu_features = MMU_FTR_TYPE_40x, | ||
| 1479 | .icache_bsize = 32, | ||
| 1480 | .dcache_bsize = 32, | ||
| 1481 | .machine_check = machine_check_4xx, | ||
| 1482 | .platform = "ppc405", | ||
| 1483 | }, | ||
| 1484 | { /* 405EXr Rev. D with Security */ | ||
| 1485 | .pvr_mask = 0xffff000f, | ||
| 1486 | .pvr_value = 0x12910002, | ||
| 1487 | .cpu_name = "405EXr Rev. D", | ||
| 1384 | .cpu_features = CPU_FTRS_40X, | 1488 | .cpu_features = CPU_FTRS_40X, |
| 1385 | .cpu_user_features = PPC_FEATURE_32 | | 1489 | .cpu_user_features = PPC_FEATURE_32 | |
| 1386 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | 1490 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, |
diff --git a/arch/powerpc/kernel/crash_dump.c b/arch/powerpc/kernel/crash_dump.c index 40f524643ba6..8e05c16344e4 100644 --- a/arch/powerpc/kernel/crash_dump.c +++ b/arch/powerpc/kernel/crash_dump.c | |||
| @@ -128,9 +128,9 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf, | |||
| 128 | if (!csize) | 128 | if (!csize) |
| 129 | return 0; | 129 | return 0; |
| 130 | 130 | ||
| 131 | csize = min(csize, PAGE_SIZE); | 131 | csize = min_t(size_t, csize, PAGE_SIZE); |
| 132 | 132 | ||
| 133 | if (pfn < max_pfn) { | 133 | if ((min_low_pfn < pfn) && (pfn < max_pfn)) { |
| 134 | vaddr = __va(pfn << PAGE_SHIFT); | 134 | vaddr = __va(pfn << PAGE_SHIFT); |
| 135 | csize = copy_oldmem_vaddr(vaddr, buf, csize, offset, userbuf); | 135 | csize = copy_oldmem_vaddr(vaddr, buf, csize, offset, userbuf); |
| 136 | } else { | 136 | } else { |
diff --git a/arch/powerpc/kernel/dbell.c b/arch/powerpc/kernel/dbell.c index 1493734cd871..3307a52d797f 100644 --- a/arch/powerpc/kernel/dbell.c +++ b/arch/powerpc/kernel/dbell.c | |||
| @@ -13,32 +13,88 @@ | |||
| 13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
| 14 | #include <linux/smp.h> | 14 | #include <linux/smp.h> |
| 15 | #include <linux/threads.h> | 15 | #include <linux/threads.h> |
| 16 | #include <linux/percpu.h> | ||
| 16 | 17 | ||
| 17 | #include <asm/dbell.h> | 18 | #include <asm/dbell.h> |
| 19 | #include <asm/irq_regs.h> | ||
| 18 | 20 | ||
| 19 | #ifdef CONFIG_SMP | 21 | #ifdef CONFIG_SMP |
| 20 | unsigned long dbell_smp_message[NR_CPUS]; | 22 | struct doorbell_cpu_info { |
| 23 | unsigned long messages; /* current messages bits */ | ||
| 24 | unsigned int tag; /* tag value */ | ||
| 25 | }; | ||
| 21 | 26 | ||
| 22 | void smp_dbell_message_pass(int target, int msg) | 27 | static DEFINE_PER_CPU(struct doorbell_cpu_info, doorbell_cpu_info); |
| 28 | |||
| 29 | void doorbell_setup_this_cpu(void) | ||
| 30 | { | ||
| 31 | struct doorbell_cpu_info *info = &__get_cpu_var(doorbell_cpu_info); | ||
| 32 | |||
| 33 | info->messages = 0; | ||
| 34 | info->tag = mfspr(SPRN_PIR) & 0x3fff; | ||
| 35 | } | ||
| 36 | |||
| 37 | void doorbell_message_pass(int target, int msg) | ||
| 23 | { | 38 | { |
| 39 | struct doorbell_cpu_info *info; | ||
| 24 | int i; | 40 | int i; |
| 25 | 41 | ||
| 26 | if(target < NR_CPUS) { | 42 | if (target < NR_CPUS) { |
| 27 | set_bit(msg, &dbell_smp_message[target]); | 43 | info = &per_cpu(doorbell_cpu_info, target); |
| 28 | ppc_msgsnd(PPC_DBELL, 0, target); | 44 | set_bit(msg, &info->messages); |
| 45 | ppc_msgsnd(PPC_DBELL, 0, info->tag); | ||
| 29 | } | 46 | } |
| 30 | else if(target == MSG_ALL_BUT_SELF) { | 47 | else if (target == MSG_ALL_BUT_SELF) { |
| 31 | for_each_online_cpu(i) { | 48 | for_each_online_cpu(i) { |
| 32 | if (i == smp_processor_id()) | 49 | if (i == smp_processor_id()) |
| 33 | continue; | 50 | continue; |
| 34 | set_bit(msg, &dbell_smp_message[i]); | 51 | info = &per_cpu(doorbell_cpu_info, i); |
| 35 | ppc_msgsnd(PPC_DBELL, 0, i); | 52 | set_bit(msg, &info->messages); |
| 53 | ppc_msgsnd(PPC_DBELL, 0, info->tag); | ||
| 36 | } | 54 | } |
| 37 | } | 55 | } |
| 38 | else { /* target == MSG_ALL */ | 56 | else { /* target == MSG_ALL */ |
| 39 | for_each_online_cpu(i) | 57 | for_each_online_cpu(i) { |
| 40 | set_bit(msg, &dbell_smp_message[i]); | 58 | info = &per_cpu(doorbell_cpu_info, i); |
| 59 | set_bit(msg, &info->messages); | ||
| 60 | } | ||
| 41 | ppc_msgsnd(PPC_DBELL, PPC_DBELL_MSG_BRDCAST, 0); | 61 | ppc_msgsnd(PPC_DBELL, PPC_DBELL_MSG_BRDCAST, 0); |
| 42 | } | 62 | } |
| 43 | } | 63 | } |
| 44 | #endif | 64 | |
| 65 | void doorbell_exception(struct pt_regs *regs) | ||
| 66 | { | ||
| 67 | struct pt_regs *old_regs = set_irq_regs(regs); | ||
| 68 | struct doorbell_cpu_info *info = &__get_cpu_var(doorbell_cpu_info); | ||
| 69 | int msg; | ||
| 70 | |||
| 71 | /* Warning: regs can be NULL when called from irq enable */ | ||
| 72 | |||
| 73 | if (!info->messages || (num_online_cpus() < 2)) | ||
| 74 | goto out; | ||
| 75 | |||
| 76 | for (msg = 0; msg < 4; msg++) | ||
| 77 | if (test_and_clear_bit(msg, &info->messages)) | ||
| 78 | smp_message_recv(msg); | ||
| 79 | |||
| 80 | out: | ||
| 81 | set_irq_regs(old_regs); | ||
| 82 | } | ||
| 83 | |||
| 84 | void doorbell_check_self(void) | ||
| 85 | { | ||
| 86 | struct doorbell_cpu_info *info = &__get_cpu_var(doorbell_cpu_info); | ||
| 87 | |||
| 88 | if (!info->messages) | ||
| 89 | return; | ||
| 90 | |||
| 91 | ppc_msgsnd(PPC_DBELL, 0, info->tag); | ||
| 92 | } | ||
| 93 | |||
| 94 | #else /* CONFIG_SMP */ | ||
| 95 | void doorbell_exception(struct pt_regs *regs) | ||
| 96 | { | ||
| 97 | printk(KERN_WARNING "Received doorbell on non-smp system\n"); | ||
| 98 | } | ||
| 99 | #endif /* CONFIG_SMP */ | ||
| 100 | |||
diff --git a/arch/powerpc/kernel/dma-swiotlb.c b/arch/powerpc/kernel/dma-swiotlb.c index 02f724f36753..4295e0b94b2d 100644 --- a/arch/powerpc/kernel/dma-swiotlb.c +++ b/arch/powerpc/kernel/dma-swiotlb.c | |||
| @@ -82,17 +82,9 @@ static struct notifier_block ppc_swiotlb_plat_bus_notifier = { | |||
| 82 | .priority = 0, | 82 | .priority = 0, |
| 83 | }; | 83 | }; |
| 84 | 84 | ||
| 85 | static struct notifier_block ppc_swiotlb_of_bus_notifier = { | ||
| 86 | .notifier_call = ppc_swiotlb_bus_notify, | ||
| 87 | .priority = 0, | ||
| 88 | }; | ||
| 89 | |||
| 90 | int __init swiotlb_setup_bus_notifier(void) | 85 | int __init swiotlb_setup_bus_notifier(void) |
| 91 | { | 86 | { |
| 92 | bus_register_notifier(&platform_bus_type, | 87 | bus_register_notifier(&platform_bus_type, |
| 93 | &ppc_swiotlb_plat_bus_notifier); | 88 | &ppc_swiotlb_plat_bus_notifier); |
| 94 | bus_register_notifier(&of_platform_bus_type, | ||
| 95 | &ppc_swiotlb_of_bus_notifier); | ||
| 96 | |||
| 97 | return 0; | 89 | return 0; |
| 98 | } | 90 | } |
diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S index 24dcc0ecf246..5c43063d2506 100644 --- a/arch/powerpc/kernel/exceptions-64e.S +++ b/arch/powerpc/kernel/exceptions-64e.S | |||
| @@ -191,6 +191,12 @@ exc_##n##_bad_stack: \ | |||
| 191 | sth r1,PACA_TRAP_SAVE(r13); /* store trap */ \ | 191 | sth r1,PACA_TRAP_SAVE(r13); /* store trap */ \ |
| 192 | b bad_stack_book3e; /* bad stack error */ | 192 | b bad_stack_book3e; /* bad stack error */ |
| 193 | 193 | ||
| 194 | /* WARNING: If you change the layout of this stub, make sure you chcek | ||
| 195 | * the debug exception handler which handles single stepping | ||
| 196 | * into exceptions from userspace, and the MM code in | ||
| 197 | * arch/powerpc/mm/tlb_nohash.c which patches the branch here | ||
| 198 | * and would need to be updated if that branch is moved | ||
| 199 | */ | ||
| 194 | #define EXCEPTION_STUB(loc, label) \ | 200 | #define EXCEPTION_STUB(loc, label) \ |
| 195 | . = interrupt_base_book3e + loc; \ | 201 | . = interrupt_base_book3e + loc; \ |
| 196 | nop; /* To make debug interrupts happy */ \ | 202 | nop; /* To make debug interrupts happy */ \ |
| @@ -204,11 +210,30 @@ exc_##n##_bad_stack: \ | |||
| 204 | lis r,TSR_FIS@h; \ | 210 | lis r,TSR_FIS@h; \ |
| 205 | mtspr SPRN_TSR,r | 211 | mtspr SPRN_TSR,r |
| 206 | 212 | ||
| 213 | /* Used by asynchronous interrupt that may happen in the idle loop. | ||
| 214 | * | ||
| 215 | * This check if the thread was in the idle loop, and if yes, returns | ||
| 216 | * to the caller rather than the PC. This is to avoid a race if | ||
| 217 | * interrupts happen before the wait instruction. | ||
| 218 | */ | ||
| 219 | #define CHECK_NAPPING() \ | ||
| 220 | clrrdi r11,r1,THREAD_SHIFT; \ | ||
| 221 | ld r10,TI_LOCAL_FLAGS(r11); \ | ||
| 222 | andi. r9,r10,_TLF_NAPPING; \ | ||
| 223 | beq+ 1f; \ | ||
| 224 | ld r8,_LINK(r1); \ | ||
| 225 | rlwinm r7,r10,0,~_TLF_NAPPING; \ | ||
| 226 | std r8,_NIP(r1); \ | ||
| 227 | std r7,TI_LOCAL_FLAGS(r11); \ | ||
| 228 | 1: | ||
| 229 | |||
| 230 | |||
| 207 | #define MASKABLE_EXCEPTION(trapnum, label, hdlr, ack) \ | 231 | #define MASKABLE_EXCEPTION(trapnum, label, hdlr, ack) \ |
| 208 | START_EXCEPTION(label); \ | 232 | START_EXCEPTION(label); \ |
| 209 | NORMAL_EXCEPTION_PROLOG(trapnum, PROLOG_ADDITION_MASKABLE) \ | 233 | NORMAL_EXCEPTION_PROLOG(trapnum, PROLOG_ADDITION_MASKABLE) \ |
| 210 | EXCEPTION_COMMON(trapnum, PACA_EXGEN, INTS_DISABLE_ALL) \ | 234 | EXCEPTION_COMMON(trapnum, PACA_EXGEN, INTS_DISABLE_ALL) \ |
| 211 | ack(r8); \ | 235 | ack(r8); \ |
| 236 | CHECK_NAPPING(); \ | ||
| 212 | addi r3,r1,STACK_FRAME_OVERHEAD; \ | 237 | addi r3,r1,STACK_FRAME_OVERHEAD; \ |
| 213 | bl hdlr; \ | 238 | bl hdlr; \ |
| 214 | b .ret_from_except_lite; | 239 | b .ret_from_except_lite; |
| @@ -246,11 +271,9 @@ interrupt_base_book3e: /* fake trap */ | |||
| 246 | EXCEPTION_STUB(0x1a0, watchdog) /* 0x09f0 */ | 271 | EXCEPTION_STUB(0x1a0, watchdog) /* 0x09f0 */ |
| 247 | EXCEPTION_STUB(0x1c0, data_tlb_miss) | 272 | EXCEPTION_STUB(0x1c0, data_tlb_miss) |
| 248 | EXCEPTION_STUB(0x1e0, instruction_tlb_miss) | 273 | EXCEPTION_STUB(0x1e0, instruction_tlb_miss) |
| 274 | EXCEPTION_STUB(0x280, doorbell) | ||
| 275 | EXCEPTION_STUB(0x2a0, doorbell_crit) | ||
| 249 | 276 | ||
| 250 | #if 0 | ||
| 251 | EXCEPTION_STUB(0x280, processor_doorbell) | ||
| 252 | EXCEPTION_STUB(0x220, processor_doorbell_crit) | ||
| 253 | #endif | ||
| 254 | .globl interrupt_end_book3e | 277 | .globl interrupt_end_book3e |
| 255 | interrupt_end_book3e: | 278 | interrupt_end_book3e: |
| 256 | 279 | ||
| @@ -259,6 +282,7 @@ interrupt_end_book3e: | |||
| 259 | CRIT_EXCEPTION_PROLOG(0x100, PROLOG_ADDITION_NONE) | 282 | CRIT_EXCEPTION_PROLOG(0x100, PROLOG_ADDITION_NONE) |
| 260 | // EXCEPTION_COMMON(0x100, PACA_EXCRIT, INTS_DISABLE_ALL) | 283 | // EXCEPTION_COMMON(0x100, PACA_EXCRIT, INTS_DISABLE_ALL) |
| 261 | // bl special_reg_save_crit | 284 | // bl special_reg_save_crit |
| 285 | // CHECK_NAPPING(); | ||
| 262 | // addi r3,r1,STACK_FRAME_OVERHEAD | 286 | // addi r3,r1,STACK_FRAME_OVERHEAD |
| 263 | // bl .critical_exception | 287 | // bl .critical_exception |
| 264 | // b ret_from_crit_except | 288 | // b ret_from_crit_except |
| @@ -270,6 +294,7 @@ interrupt_end_book3e: | |||
| 270 | // EXCEPTION_COMMON(0x200, PACA_EXMC, INTS_DISABLE_ALL) | 294 | // EXCEPTION_COMMON(0x200, PACA_EXMC, INTS_DISABLE_ALL) |
| 271 | // bl special_reg_save_mc | 295 | // bl special_reg_save_mc |
| 272 | // addi r3,r1,STACK_FRAME_OVERHEAD | 296 | // addi r3,r1,STACK_FRAME_OVERHEAD |
| 297 | // CHECK_NAPPING(); | ||
| 273 | // bl .machine_check_exception | 298 | // bl .machine_check_exception |
| 274 | // b ret_from_mc_except | 299 | // b ret_from_mc_except |
| 275 | b . | 300 | b . |
| @@ -340,6 +365,7 @@ interrupt_end_book3e: | |||
| 340 | CRIT_EXCEPTION_PROLOG(0x9f0, PROLOG_ADDITION_NONE) | 365 | CRIT_EXCEPTION_PROLOG(0x9f0, PROLOG_ADDITION_NONE) |
| 341 | // EXCEPTION_COMMON(0x9f0, PACA_EXCRIT, INTS_DISABLE_ALL) | 366 | // EXCEPTION_COMMON(0x9f0, PACA_EXCRIT, INTS_DISABLE_ALL) |
| 342 | // bl special_reg_save_crit | 367 | // bl special_reg_save_crit |
| 368 | // CHECK_NAPPING(); | ||
| 343 | // addi r3,r1,STACK_FRAME_OVERHEAD | 369 | // addi r3,r1,STACK_FRAME_OVERHEAD |
| 344 | // bl .unknown_exception | 370 | // bl .unknown_exception |
| 345 | // b ret_from_crit_except | 371 | // b ret_from_crit_except |
| @@ -428,6 +454,20 @@ interrupt_end_book3e: | |||
| 428 | kernel_dbg_exc: | 454 | kernel_dbg_exc: |
| 429 | b . /* NYI */ | 455 | b . /* NYI */ |
| 430 | 456 | ||
| 457 | /* Doorbell interrupt */ | ||
| 458 | MASKABLE_EXCEPTION(0x2070, doorbell, .doorbell_exception, ACK_NONE) | ||
| 459 | |||
| 460 | /* Doorbell critical Interrupt */ | ||
| 461 | START_EXCEPTION(doorbell_crit); | ||
| 462 | CRIT_EXCEPTION_PROLOG(0x2080, PROLOG_ADDITION_NONE) | ||
| 463 | // EXCEPTION_COMMON(0x2080, PACA_EXCRIT, INTS_DISABLE_ALL) | ||
| 464 | // bl special_reg_save_crit | ||
| 465 | // CHECK_NAPPING(); | ||
| 466 | // addi r3,r1,STACK_FRAME_OVERHEAD | ||
| 467 | // bl .doorbell_critical_exception | ||
| 468 | // b ret_from_crit_except | ||
| 469 | b . | ||
| 470 | |||
| 431 | 471 | ||
| 432 | /* | 472 | /* |
| 433 | * An interrupt came in while soft-disabled; clear EE in SRR1, | 473 | * An interrupt came in while soft-disabled; clear EE in SRR1, |
| @@ -563,6 +603,8 @@ BAD_STACK_TRAMPOLINE(0xd00) | |||
| 563 | BAD_STACK_TRAMPOLINE(0xe00) | 603 | BAD_STACK_TRAMPOLINE(0xe00) |
| 564 | BAD_STACK_TRAMPOLINE(0xf00) | 604 | BAD_STACK_TRAMPOLINE(0xf00) |
| 565 | BAD_STACK_TRAMPOLINE(0xf20) | 605 | BAD_STACK_TRAMPOLINE(0xf20) |
| 606 | BAD_STACK_TRAMPOLINE(0x2070) | ||
| 607 | BAD_STACK_TRAMPOLINE(0x2080) | ||
| 566 | 608 | ||
| 567 | .globl bad_stack_book3e | 609 | .globl bad_stack_book3e |
| 568 | bad_stack_book3e: | 610 | bad_stack_book3e: |
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 3e423fbad6bc..f53029a01554 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S | |||
| @@ -828,6 +828,7 @@ END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES) | |||
| 828 | 828 | ||
| 829 | /* We have a data breakpoint exception - handle it */ | 829 | /* We have a data breakpoint exception - handle it */ |
| 830 | handle_dabr_fault: | 830 | handle_dabr_fault: |
| 831 | bl .save_nvgprs | ||
| 831 | ld r4,_DAR(r1) | 832 | ld r4,_DAR(r1) |
| 832 | ld r5,_DSISR(r1) | 833 | ld r5,_DSISR(r1) |
| 833 | addi r3,r1,STACK_FRAME_OVERHEAD | 834 | addi r3,r1,STACK_FRAME_OVERHEAD |
diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c new file mode 100644 index 000000000000..5ecd0401cdb1 --- /dev/null +++ b/arch/powerpc/kernel/hw_breakpoint.c | |||
| @@ -0,0 +1,364 @@ | |||
| 1 | /* | ||
| 2 | * HW_breakpoint: a unified kernel/user-space hardware breakpoint facility, | ||
| 3 | * using the CPU's debug registers. Derived from | ||
| 4 | * "arch/x86/kernel/hw_breakpoint.c" | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 19 | * | ||
| 20 | * Copyright 2010 IBM Corporation | ||
| 21 | * Author: K.Prasad <prasad@linux.vnet.ibm.com> | ||
| 22 | * | ||
| 23 | */ | ||
| 24 | |||
| 25 | #include <linux/hw_breakpoint.h> | ||
| 26 | #include <linux/notifier.h> | ||
| 27 | #include <linux/kprobes.h> | ||
| 28 | #include <linux/percpu.h> | ||
| 29 | #include <linux/kernel.h> | ||
| 30 | #include <linux/module.h> | ||
| 31 | #include <linux/sched.h> | ||
| 32 | #include <linux/init.h> | ||
| 33 | #include <linux/smp.h> | ||
| 34 | |||
| 35 | #include <asm/hw_breakpoint.h> | ||
| 36 | #include <asm/processor.h> | ||
| 37 | #include <asm/sstep.h> | ||
| 38 | #include <asm/uaccess.h> | ||
| 39 | |||
| 40 | /* | ||
| 41 | * Stores the breakpoints currently in use on each breakpoint address | ||
| 42 | * register for every cpu | ||
| 43 | */ | ||
| 44 | static DEFINE_PER_CPU(struct perf_event *, bp_per_reg); | ||
| 45 | |||
| 46 | /* | ||
| 47 | * Returns total number of data or instruction breakpoints available. | ||
| 48 | */ | ||
| 49 | int hw_breakpoint_slots(int type) | ||
| 50 | { | ||
| 51 | if (type == TYPE_DATA) | ||
| 52 | return HBP_NUM; | ||
| 53 | return 0; /* no instruction breakpoints available */ | ||
| 54 | } | ||
| 55 | |||
| 56 | /* | ||
| 57 | * Install a perf counter breakpoint. | ||
| 58 | * | ||
| 59 | * We seek a free debug address register and use it for this | ||
| 60 | * breakpoint. | ||
| 61 | * | ||
| 62 | * Atomic: we hold the counter->ctx->lock and we only handle variables | ||
| 63 | * and registers local to this cpu. | ||
| 64 | */ | ||
| 65 | int arch_install_hw_breakpoint(struct perf_event *bp) | ||
| 66 | { | ||
| 67 | struct arch_hw_breakpoint *info = counter_arch_bp(bp); | ||
| 68 | struct perf_event **slot = &__get_cpu_var(bp_per_reg); | ||
| 69 | |||
| 70 | *slot = bp; | ||
| 71 | |||
| 72 | /* | ||
| 73 | * Do not install DABR values if the instruction must be single-stepped. | ||
| 74 | * If so, DABR will be populated in single_step_dabr_instruction(). | ||
| 75 | */ | ||
| 76 | if (current->thread.last_hit_ubp != bp) | ||
| 77 | set_dabr(info->address | info->type | DABR_TRANSLATION); | ||
| 78 | |||
| 79 | return 0; | ||
| 80 | } | ||
| 81 | |||
| 82 | /* | ||
| 83 | * Uninstall the breakpoint contained in the given counter. | ||
| 84 | * | ||
| 85 | * First we search the debug address register it uses and then we disable | ||
| 86 | * it. | ||
| 87 | * | ||
| 88 | * Atomic: we hold the counter->ctx->lock and we only handle variables | ||
| 89 | * and registers local to this cpu. | ||
| 90 | */ | ||
| 91 | void arch_uninstall_hw_breakpoint(struct perf_event *bp) | ||
| 92 | { | ||
| 93 | struct perf_event **slot = &__get_cpu_var(bp_per_reg); | ||
| 94 | |||
| 95 | if (*slot != bp) { | ||
| 96 | WARN_ONCE(1, "Can't find the breakpoint"); | ||
| 97 | return; | ||
| 98 | } | ||
| 99 | |||
| 100 | *slot = NULL; | ||
| 101 | set_dabr(0); | ||
| 102 | } | ||
| 103 | |||
| 104 | /* | ||
| 105 | * Perform cleanup of arch-specific counters during unregistration | ||
| 106 | * of the perf-event | ||
| 107 | */ | ||
| 108 | void arch_unregister_hw_breakpoint(struct perf_event *bp) | ||
| 109 | { | ||
| 110 | /* | ||
| 111 | * If the breakpoint is unregistered between a hw_breakpoint_handler() | ||
| 112 | * and the single_step_dabr_instruction(), then cleanup the breakpoint | ||
| 113 | * restoration variables to prevent dangling pointers. | ||
| 114 | */ | ||
| 115 | if (bp->ctx->task) | ||
| 116 | bp->ctx->task->thread.last_hit_ubp = NULL; | ||
| 117 | } | ||
| 118 | |||
| 119 | /* | ||
| 120 | * Check for virtual address in kernel space. | ||
| 121 | */ | ||
| 122 | int arch_check_bp_in_kernelspace(struct perf_event *bp) | ||
| 123 | { | ||
| 124 | struct arch_hw_breakpoint *info = counter_arch_bp(bp); | ||
| 125 | |||
| 126 | return is_kernel_addr(info->address); | ||
| 127 | } | ||
| 128 | |||
| 129 | int arch_bp_generic_fields(int type, int *gen_bp_type) | ||
| 130 | { | ||
| 131 | switch (type) { | ||
| 132 | case DABR_DATA_READ: | ||
| 133 | *gen_bp_type = HW_BREAKPOINT_R; | ||
| 134 | break; | ||
| 135 | case DABR_DATA_WRITE: | ||
| 136 | *gen_bp_type = HW_BREAKPOINT_W; | ||
| 137 | break; | ||
| 138 | case (DABR_DATA_WRITE | DABR_DATA_READ): | ||
| 139 | *gen_bp_type = (HW_BREAKPOINT_W | HW_BREAKPOINT_R); | ||
| 140 | break; | ||
| 141 | default: | ||
| 142 | return -EINVAL; | ||
| 143 | } | ||
| 144 | return 0; | ||
| 145 | } | ||
| 146 | |||
| 147 | /* | ||
| 148 | * Validate the arch-specific HW Breakpoint register settings | ||
| 149 | */ | ||
| 150 | int arch_validate_hwbkpt_settings(struct perf_event *bp) | ||
| 151 | { | ||
| 152 | int ret = -EINVAL; | ||
| 153 | struct arch_hw_breakpoint *info = counter_arch_bp(bp); | ||
| 154 | |||
| 155 | if (!bp) | ||
| 156 | return ret; | ||
| 157 | |||
| 158 | switch (bp->attr.bp_type) { | ||
| 159 | case HW_BREAKPOINT_R: | ||
| 160 | info->type = DABR_DATA_READ; | ||
| 161 | break; | ||
| 162 | case HW_BREAKPOINT_W: | ||
| 163 | info->type = DABR_DATA_WRITE; | ||
| 164 | break; | ||
| 165 | case HW_BREAKPOINT_R | HW_BREAKPOINT_W: | ||
| 166 | info->type = (DABR_DATA_READ | DABR_DATA_WRITE); | ||
| 167 | break; | ||
| 168 | default: | ||
| 169 | return ret; | ||
| 170 | } | ||
| 171 | |||
| 172 | info->address = bp->attr.bp_addr; | ||
| 173 | info->len = bp->attr.bp_len; | ||
| 174 | |||
| 175 | /* | ||
| 176 | * Since breakpoint length can be a maximum of HW_BREAKPOINT_LEN(8) | ||
| 177 | * and breakpoint addresses are aligned to nearest double-word | ||
| 178 | * HW_BREAKPOINT_ALIGN by rounding off to the lower address, the | ||
| 179 | * 'symbolsize' should satisfy the check below. | ||
| 180 | */ | ||
| 181 | if (info->len > | ||
| 182 | (HW_BREAKPOINT_LEN - (info->address & HW_BREAKPOINT_ALIGN))) | ||
| 183 | return -EINVAL; | ||
| 184 | return 0; | ||
| 185 | } | ||
| 186 | |||
| 187 | /* | ||
| 188 | * Restores the breakpoint on the debug registers. | ||
| 189 | * Invoke this function if it is known that the execution context is | ||
| 190 | * about to change to cause loss of MSR_SE settings. | ||
| 191 | */ | ||
| 192 | void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs) | ||
| 193 | { | ||
| 194 | struct arch_hw_breakpoint *info; | ||
| 195 | |||
| 196 | if (likely(!tsk->thread.last_hit_ubp)) | ||
| 197 | return; | ||
| 198 | |||
| 199 | info = counter_arch_bp(tsk->thread.last_hit_ubp); | ||
| 200 | regs->msr &= ~MSR_SE; | ||
| 201 | set_dabr(info->address | info->type | DABR_TRANSLATION); | ||
| 202 | tsk->thread.last_hit_ubp = NULL; | ||
| 203 | } | ||
| 204 | |||
| 205 | /* | ||
| 206 | * Handle debug exception notifications. | ||
| 207 | */ | ||
| 208 | int __kprobes hw_breakpoint_handler(struct die_args *args) | ||
| 209 | { | ||
| 210 | int rc = NOTIFY_STOP; | ||
| 211 | struct perf_event *bp; | ||
| 212 | struct pt_regs *regs = args->regs; | ||
| 213 | int stepped = 1; | ||
| 214 | struct arch_hw_breakpoint *info; | ||
| 215 | unsigned int instr; | ||
| 216 | unsigned long dar = regs->dar; | ||
| 217 | |||
| 218 | /* Disable breakpoints during exception handling */ | ||
| 219 | set_dabr(0); | ||
| 220 | |||
| 221 | /* | ||
| 222 | * The counter may be concurrently released but that can only | ||
| 223 | * occur from a call_rcu() path. We can then safely fetch | ||
| 224 | * the breakpoint, use its callback, touch its counter | ||
| 225 | * while we are in an rcu_read_lock() path. | ||
| 226 | */ | ||
| 227 | rcu_read_lock(); | ||
| 228 | |||
| 229 | bp = __get_cpu_var(bp_per_reg); | ||
| 230 | if (!bp) | ||
| 231 | goto out; | ||
| 232 | info = counter_arch_bp(bp); | ||
| 233 | |||
| 234 | /* | ||
| 235 | * Return early after invoking user-callback function without restoring | ||
| 236 | * DABR if the breakpoint is from ptrace which always operates in | ||
| 237 | * one-shot mode. The ptrace-ed process will receive the SIGTRAP signal | ||
| 238 | * generated in do_dabr(). | ||
| 239 | */ | ||
| 240 | if (bp->overflow_handler == ptrace_triggered) { | ||
| 241 | perf_bp_event(bp, regs); | ||
| 242 | rc = NOTIFY_DONE; | ||
| 243 | goto out; | ||
| 244 | } | ||
| 245 | |||
| 246 | /* | ||
| 247 | * Verify if dar lies within the address range occupied by the symbol | ||
| 248 | * being watched to filter extraneous exceptions. If it doesn't, | ||
| 249 | * we still need to single-step the instruction, but we don't | ||
| 250 | * generate an event. | ||
| 251 | */ | ||
| 252 | info->extraneous_interrupt = !((bp->attr.bp_addr <= dar) && | ||
| 253 | (dar - bp->attr.bp_addr < bp->attr.bp_len)); | ||
| 254 | |||
| 255 | /* Do not emulate user-space instructions, instead single-step them */ | ||
| 256 | if (user_mode(regs)) { | ||
| 257 | bp->ctx->task->thread.last_hit_ubp = bp; | ||
| 258 | regs->msr |= MSR_SE; | ||
| 259 | goto out; | ||
| 260 | } | ||
| 261 | |||
| 262 | stepped = 0; | ||
| 263 | instr = 0; | ||
| 264 | if (!__get_user_inatomic(instr, (unsigned int *) regs->nip)) | ||
| 265 | stepped = emulate_step(regs, instr); | ||
| 266 | |||
| 267 | /* | ||
| 268 | * emulate_step() could not execute it. We've failed in reliably | ||
| 269 | * handling the hw-breakpoint. Unregister it and throw a warning | ||
| 270 | * message to let the user know about it. | ||
| 271 | */ | ||
| 272 | if (!stepped) { | ||
| 273 | WARN(1, "Unable to handle hardware breakpoint. Breakpoint at " | ||
| 274 | "0x%lx will be disabled.", info->address); | ||
| 275 | perf_event_disable(bp); | ||
| 276 | goto out; | ||
| 277 | } | ||
| 278 | /* | ||
| 279 | * As a policy, the callback is invoked in a 'trigger-after-execute' | ||
| 280 | * fashion | ||
| 281 | */ | ||
| 282 | if (!info->extraneous_interrupt) | ||
| 283 | perf_bp_event(bp, regs); | ||
| 284 | |||
| 285 | set_dabr(info->address | info->type | DABR_TRANSLATION); | ||
| 286 | out: | ||
| 287 | rcu_read_unlock(); | ||
| 288 | return rc; | ||
| 289 | } | ||
| 290 | |||
| 291 | /* | ||
| 292 | * Handle single-step exceptions following a DABR hit. | ||
| 293 | */ | ||
| 294 | int __kprobes single_step_dabr_instruction(struct die_args *args) | ||
| 295 | { | ||
| 296 | struct pt_regs *regs = args->regs; | ||
| 297 | struct perf_event *bp = NULL; | ||
| 298 | struct arch_hw_breakpoint *bp_info; | ||
| 299 | |||
| 300 | bp = current->thread.last_hit_ubp; | ||
| 301 | /* | ||
| 302 | * Check if we are single-stepping as a result of a | ||
| 303 | * previous HW Breakpoint exception | ||
| 304 | */ | ||
| 305 | if (!bp) | ||
| 306 | return NOTIFY_DONE; | ||
| 307 | |||
| 308 | bp_info = counter_arch_bp(bp); | ||
| 309 | |||
| 310 | /* | ||
| 311 | * We shall invoke the user-defined callback function in the single | ||
| 312 | * stepping handler to confirm to 'trigger-after-execute' semantics | ||
| 313 | */ | ||
| 314 | if (!bp_info->extraneous_interrupt) | ||
| 315 | perf_bp_event(bp, regs); | ||
| 316 | |||
| 317 | set_dabr(bp_info->address | bp_info->type | DABR_TRANSLATION); | ||
| 318 | current->thread.last_hit_ubp = NULL; | ||
| 319 | |||
| 320 | /* | ||
| 321 | * If the process was being single-stepped by ptrace, let the | ||
| 322 | * other single-step actions occur (e.g. generate SIGTRAP). | ||
| 323 | */ | ||
| 324 | if (test_thread_flag(TIF_SINGLESTEP)) | ||
| 325 | return NOTIFY_DONE; | ||
| 326 | |||
| 327 | return NOTIFY_STOP; | ||
| 328 | } | ||
| 329 | |||
| 330 | /* | ||
| 331 | * Handle debug exception notifications. | ||
| 332 | */ | ||
| 333 | int __kprobes hw_breakpoint_exceptions_notify( | ||
| 334 | struct notifier_block *unused, unsigned long val, void *data) | ||
| 335 | { | ||
| 336 | int ret = NOTIFY_DONE; | ||
| 337 | |||
| 338 | switch (val) { | ||
| 339 | case DIE_DABR_MATCH: | ||
| 340 | ret = hw_breakpoint_handler(data); | ||
| 341 | break; | ||
| 342 | case DIE_SSTEP: | ||
| 343 | ret = single_step_dabr_instruction(data); | ||
| 344 | break; | ||
| 345 | } | ||
| 346 | |||
| 347 | return ret; | ||
| 348 | } | ||
| 349 | |||
| 350 | /* | ||
| 351 | * Release the user breakpoints used by ptrace | ||
| 352 | */ | ||
| 353 | void flush_ptrace_hw_breakpoint(struct task_struct *tsk) | ||
| 354 | { | ||
| 355 | struct thread_struct *t = &tsk->thread; | ||
| 356 | |||
| 357 | unregister_hw_breakpoint(t->ptrace_bps[0]); | ||
| 358 | t->ptrace_bps[0] = NULL; | ||
| 359 | } | ||
| 360 | |||
| 361 | void hw_breakpoint_pmu_read(struct perf_event *bp) | ||
| 362 | { | ||
| 363 | /* TODO */ | ||
| 364 | } | ||
diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c index 21266abfbda6..9b626cfffce1 100644 --- a/arch/powerpc/kernel/ibmebus.c +++ b/arch/powerpc/kernel/ibmebus.c | |||
| @@ -140,19 +140,19 @@ static struct dma_map_ops ibmebus_dma_ops = { | |||
| 140 | 140 | ||
| 141 | static int ibmebus_match_path(struct device *dev, void *data) | 141 | static int ibmebus_match_path(struct device *dev, void *data) |
| 142 | { | 142 | { |
| 143 | struct device_node *dn = to_of_device(dev)->dev.of_node; | 143 | struct device_node *dn = to_platform_device(dev)->dev.of_node; |
| 144 | return (dn->full_name && | 144 | return (dn->full_name && |
| 145 | (strcasecmp((char *)data, dn->full_name) == 0)); | 145 | (strcasecmp((char *)data, dn->full_name) == 0)); |
| 146 | } | 146 | } |
| 147 | 147 | ||
| 148 | static int ibmebus_match_node(struct device *dev, void *data) | 148 | static int ibmebus_match_node(struct device *dev, void *data) |
| 149 | { | 149 | { |
| 150 | return to_of_device(dev)->dev.of_node == data; | 150 | return to_platform_device(dev)->dev.of_node == data; |
| 151 | } | 151 | } |
| 152 | 152 | ||
| 153 | static int ibmebus_create_device(struct device_node *dn) | 153 | static int ibmebus_create_device(struct device_node *dn) |
| 154 | { | 154 | { |
| 155 | struct of_device *dev; | 155 | struct platform_device *dev; |
| 156 | int ret; | 156 | int ret; |
| 157 | 157 | ||
| 158 | dev = of_device_alloc(dn, NULL, &ibmebus_bus_device); | 158 | dev = of_device_alloc(dn, NULL, &ibmebus_bus_device); |
| @@ -298,7 +298,7 @@ static ssize_t ibmebus_store_remove(struct bus_type *bus, | |||
| 298 | 298 | ||
| 299 | if ((dev = bus_find_device(&ibmebus_bus_type, NULL, path, | 299 | if ((dev = bus_find_device(&ibmebus_bus_type, NULL, path, |
| 300 | ibmebus_match_path))) { | 300 | ibmebus_match_path))) { |
| 301 | of_device_unregister(to_of_device(dev)); | 301 | of_device_unregister(to_platform_device(dev)); |
| 302 | 302 | ||
| 303 | kfree(path); | 303 | kfree(path); |
| 304 | return count; | 304 | return count; |
diff --git a/arch/powerpc/kernel/idle_book3e.S b/arch/powerpc/kernel/idle_book3e.S new file mode 100644 index 000000000000..16c002d6bdf1 --- /dev/null +++ b/arch/powerpc/kernel/idle_book3e.S | |||
| @@ -0,0 +1,86 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2010 IBM Corp, Benjamin Herrenschmidt <benh@kernel.crashing.org> | ||
| 3 | * | ||
| 4 | * Generic idle routine for Book3E processors | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or | ||
| 7 | * modify it under the terms of the GNU General Public License | ||
| 8 | * as published by the Free Software Foundation; either version | ||
| 9 | * 2 of the License, or (at your option) any later version. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/threads.h> | ||
| 13 | #include <asm/reg.h> | ||
| 14 | #include <asm/ppc_asm.h> | ||
| 15 | #include <asm/asm-offsets.h> | ||
| 16 | #include <asm/ppc-opcode.h> | ||
| 17 | #include <asm/processor.h> | ||
| 18 | #include <asm/thread_info.h> | ||
| 19 | |||
| 20 | /* 64-bit version only for now */ | ||
| 21 | #ifdef CONFIG_PPC64 | ||
| 22 | |||
| 23 | _GLOBAL(book3e_idle) | ||
| 24 | /* Save LR for later */ | ||
| 25 | mflr r0 | ||
| 26 | std r0,16(r1) | ||
| 27 | |||
| 28 | /* Hard disable interrupts */ | ||
| 29 | wrteei 0 | ||
| 30 | |||
| 31 | /* Now check if an interrupt came in while we were soft disabled | ||
| 32 | * since we may otherwise lose it (doorbells etc...). We know | ||
| 33 | * that since PACAHARDIRQEN will have been cleared in that case. | ||
| 34 | */ | ||
| 35 | lbz r3,PACAHARDIRQEN(r13) | ||
| 36 | cmpwi cr0,r3,0 | ||
| 37 | beqlr | ||
| 38 | |||
| 39 | /* Now we are going to mark ourselves as soft and hard enables in | ||
| 40 | * order to be able to take interrupts while asleep. We inform lockdep | ||
| 41 | * of that. We don't actually turn interrupts on just yet tho. | ||
| 42 | */ | ||
| 43 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
| 44 | stdu r1,-128(r1) | ||
| 45 | bl .trace_hardirqs_on | ||
| 46 | #endif | ||
| 47 | li r0,1 | ||
| 48 | stb r0,PACASOFTIRQEN(r13) | ||
| 49 | stb r0,PACAHARDIRQEN(r13) | ||
| 50 | |||
| 51 | /* Interrupts will make use return to LR, so get something we want | ||
| 52 | * in there | ||
| 53 | */ | ||
| 54 | bl 1f | ||
| 55 | |||
| 56 | /* Hard disable interrupts again */ | ||
| 57 | wrteei 0 | ||
| 58 | |||
| 59 | /* Mark them off again in the PACA as well */ | ||
| 60 | li r0,0 | ||
| 61 | stb r0,PACASOFTIRQEN(r13) | ||
| 62 | stb r0,PACAHARDIRQEN(r13) | ||
| 63 | |||
| 64 | /* Tell lockdep about it */ | ||
| 65 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
| 66 | bl .trace_hardirqs_off | ||
| 67 | addi r1,r1,128 | ||
| 68 | #endif | ||
| 69 | ld r0,16(r1) | ||
| 70 | mtlr r0 | ||
| 71 | blr | ||
| 72 | |||
| 73 | 1: /* Let's set the _TLF_NAPPING flag so interrupts make us return | ||
| 74 | * to the right spot | ||
| 75 | */ | ||
| 76 | clrrdi r11,r1,THREAD_SHIFT | ||
| 77 | ld r10,TI_LOCAL_FLAGS(r11) | ||
| 78 | ori r10,r10,_TLF_NAPPING | ||
| 79 | std r10,TI_LOCAL_FLAGS(r11) | ||
| 80 | |||
| 81 | /* We can now re-enable hard interrupts and go to sleep */ | ||
| 82 | wrteei 1 | ||
| 83 | 1: PPC_WAIT(0) | ||
| 84 | b 1b | ||
| 85 | |||
| 86 | #endif /* CONFIG_PPC64 */ | ||
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 77be3d058a65..d3ce67cf03be 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c | |||
| @@ -53,6 +53,8 @@ | |||
| 53 | #include <linux/bootmem.h> | 53 | #include <linux/bootmem.h> |
| 54 | #include <linux/pci.h> | 54 | #include <linux/pci.h> |
| 55 | #include <linux/debugfs.h> | 55 | #include <linux/debugfs.h> |
| 56 | #include <linux/of.h> | ||
| 57 | #include <linux/of_irq.h> | ||
| 56 | 58 | ||
| 57 | #include <asm/uaccess.h> | 59 | #include <asm/uaccess.h> |
| 58 | #include <asm/system.h> | 60 | #include <asm/system.h> |
| @@ -64,6 +66,8 @@ | |||
| 64 | #include <asm/ptrace.h> | 66 | #include <asm/ptrace.h> |
| 65 | #include <asm/machdep.h> | 67 | #include <asm/machdep.h> |
| 66 | #include <asm/udbg.h> | 68 | #include <asm/udbg.h> |
| 69 | #include <asm/dbell.h> | ||
| 70 | |||
| 67 | #ifdef CONFIG_PPC64 | 71 | #ifdef CONFIG_PPC64 |
| 68 | #include <asm/paca.h> | 72 | #include <asm/paca.h> |
| 69 | #include <asm/firmware.h> | 73 | #include <asm/firmware.h> |
| @@ -153,14 +157,28 @@ notrace void raw_local_irq_restore(unsigned long en) | |||
| 153 | if (get_hard_enabled()) | 157 | if (get_hard_enabled()) |
| 154 | return; | 158 | return; |
| 155 | 159 | ||
| 160 | #if defined(CONFIG_BOOKE) && defined(CONFIG_SMP) | ||
| 161 | /* Check for pending doorbell interrupts and resend to ourself */ | ||
| 162 | doorbell_check_self(); | ||
| 163 | #endif | ||
| 164 | |||
| 156 | /* | 165 | /* |
| 157 | * Need to hard-enable interrupts here. Since currently disabled, | 166 | * Need to hard-enable interrupts here. Since currently disabled, |
| 158 | * no need to take further asm precautions against preemption; but | 167 | * no need to take further asm precautions against preemption; but |
| 159 | * use local_paca instead of get_paca() to avoid preemption checking. | 168 | * use local_paca instead of get_paca() to avoid preemption checking. |
| 160 | */ | 169 | */ |
| 161 | local_paca->hard_enabled = en; | 170 | local_paca->hard_enabled = en; |
| 171 | |||
| 172 | #ifndef CONFIG_BOOKE | ||
| 173 | /* On server, re-trigger the decrementer if it went negative since | ||
| 174 | * some processors only trigger on edge transitions of the sign bit. | ||
| 175 | * | ||
| 176 | * BookE has a level sensitive decrementer (latches in TSR) so we | ||
| 177 | * don't need that | ||
| 178 | */ | ||
| 162 | if ((int)mfspr(SPRN_DEC) < 0) | 179 | if ((int)mfspr(SPRN_DEC) < 0) |
| 163 | mtspr(SPRN_DEC, 1); | 180 | mtspr(SPRN_DEC, 1); |
| 181 | #endif /* CONFIG_BOOKE */ | ||
| 164 | 182 | ||
| 165 | /* | 183 | /* |
| 166 | * Force the delivery of pending soft-disabled interrupts on PS3. | 184 | * Force the delivery of pending soft-disabled interrupts on PS3. |
| @@ -804,18 +822,6 @@ unsigned int irq_create_of_mapping(struct device_node *controller, | |||
| 804 | } | 822 | } |
| 805 | EXPORT_SYMBOL_GPL(irq_create_of_mapping); | 823 | EXPORT_SYMBOL_GPL(irq_create_of_mapping); |
| 806 | 824 | ||
| 807 | unsigned int irq_of_parse_and_map(struct device_node *dev, int index) | ||
| 808 | { | ||
| 809 | struct of_irq oirq; | ||
| 810 | |||
| 811 | if (of_irq_map_one(dev, index, &oirq)) | ||
| 812 | return NO_IRQ; | ||
| 813 | |||
| 814 | return irq_create_of_mapping(oirq.controller, oirq.specifier, | ||
| 815 | oirq.size); | ||
| 816 | } | ||
| 817 | EXPORT_SYMBOL_GPL(irq_of_parse_and_map); | ||
| 818 | |||
| 819 | void irq_dispose_mapping(unsigned int virq) | 825 | void irq_dispose_mapping(unsigned int virq) |
| 820 | { | 826 | { |
| 821 | struct irq_host *host; | 827 | struct irq_host *host; |
diff --git a/arch/powerpc/kernel/kgdb.c b/arch/powerpc/kernel/kgdb.c index 82a7b228c81a..7f61a3ac787c 100644 --- a/arch/powerpc/kernel/kgdb.c +++ b/arch/powerpc/kernel/kgdb.c | |||
| @@ -129,7 +129,7 @@ static int kgdb_handle_breakpoint(struct pt_regs *regs) | |||
| 129 | return 0; | 129 | return 0; |
| 130 | 130 | ||
| 131 | if (*(u32 *) (regs->nip) == *(u32 *) (&arch_kgdb_ops.gdb_bpt_instr)) | 131 | if (*(u32 *) (regs->nip) == *(u32 *) (&arch_kgdb_ops.gdb_bpt_instr)) |
| 132 | regs->nip += 4; | 132 | regs->nip += BREAK_INSTR_SIZE; |
| 133 | 133 | ||
| 134 | return 1; | 134 | return 1; |
| 135 | } | 135 | } |
diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c index 035ada5443ee..c1fd0f9658fd 100644 --- a/arch/powerpc/kernel/legacy_serial.c +++ b/arch/powerpc/kernel/legacy_serial.c | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | #include <linux/serial_core.h> | 4 | #include <linux/serial_core.h> |
| 5 | #include <linux/console.h> | 5 | #include <linux/console.h> |
| 6 | #include <linux/pci.h> | 6 | #include <linux/pci.h> |
| 7 | #include <linux/of_address.h> | ||
| 7 | #include <linux/of_device.h> | 8 | #include <linux/of_device.h> |
| 8 | #include <asm/io.h> | 9 | #include <asm/io.h> |
| 9 | #include <asm/mmu.h> | 10 | #include <asm/mmu.h> |
diff --git a/arch/powerpc/kernel/machine_kexec.c b/arch/powerpc/kernel/machine_kexec.c index 89f005116aac..dd6c141f1662 100644 --- a/arch/powerpc/kernel/machine_kexec.c +++ b/arch/powerpc/kernel/machine_kexec.c | |||
| @@ -45,6 +45,18 @@ void machine_kexec_cleanup(struct kimage *image) | |||
| 45 | ppc_md.machine_kexec_cleanup(image); | 45 | ppc_md.machine_kexec_cleanup(image); |
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | void arch_crash_save_vmcoreinfo(void) | ||
| 49 | { | ||
| 50 | |||
| 51 | #ifdef CONFIG_NEED_MULTIPLE_NODES | ||
| 52 | VMCOREINFO_SYMBOL(node_data); | ||
| 53 | VMCOREINFO_LENGTH(node_data, MAX_NUMNODES); | ||
| 54 | #endif | ||
| 55 | #ifndef CONFIG_NEED_MULTIPLE_NODES | ||
| 56 | VMCOREINFO_SYMBOL(contig_page_data); | ||
| 57 | #endif | ||
| 58 | } | ||
| 59 | |||
| 48 | /* | 60 | /* |
| 49 | * Do not allocate memory (or fail in any way) in machine_kexec(). | 61 | * Do not allocate memory (or fail in any way) in machine_kexec(). |
| 50 | * We are past the point of no return, committed to rebooting now. | 62 | * We are past the point of no return, committed to rebooting now. |
| @@ -144,24 +156,24 @@ int overlaps_crashkernel(unsigned long start, unsigned long size) | |||
| 144 | } | 156 | } |
| 145 | 157 | ||
| 146 | /* Values we need to export to the second kernel via the device tree. */ | 158 | /* Values we need to export to the second kernel via the device tree. */ |
| 147 | static unsigned long kernel_end; | 159 | static phys_addr_t kernel_end; |
| 148 | static unsigned long crashk_size; | 160 | static phys_addr_t crashk_size; |
| 149 | 161 | ||
| 150 | static struct property kernel_end_prop = { | 162 | static struct property kernel_end_prop = { |
| 151 | .name = "linux,kernel-end", | 163 | .name = "linux,kernel-end", |
| 152 | .length = sizeof(unsigned long), | 164 | .length = sizeof(phys_addr_t), |
| 153 | .value = &kernel_end, | 165 | .value = &kernel_end, |
| 154 | }; | 166 | }; |
| 155 | 167 | ||
| 156 | static struct property crashk_base_prop = { | 168 | static struct property crashk_base_prop = { |
| 157 | .name = "linux,crashkernel-base", | 169 | .name = "linux,crashkernel-base", |
| 158 | .length = sizeof(unsigned long), | 170 | .length = sizeof(phys_addr_t), |
| 159 | .value = &crashk_res.start, | 171 | .value = &crashk_res.start, |
| 160 | }; | 172 | }; |
| 161 | 173 | ||
| 162 | static struct property crashk_size_prop = { | 174 | static struct property crashk_size_prop = { |
| 163 | .name = "linux,crashkernel-size", | 175 | .name = "linux,crashkernel-size", |
| 164 | .length = sizeof(unsigned long), | 176 | .length = sizeof(phys_addr_t), |
| 165 | .value = &crashk_size, | 177 | .value = &crashk_size, |
| 166 | }; | 178 | }; |
| 167 | 179 | ||
diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c index ed31a29c4ff7..583af70c4b14 100644 --- a/arch/powerpc/kernel/machine_kexec_64.c +++ b/arch/powerpc/kernel/machine_kexec_64.c | |||
| @@ -15,6 +15,8 @@ | |||
| 15 | #include <linux/thread_info.h> | 15 | #include <linux/thread_info.h> |
| 16 | #include <linux/init_task.h> | 16 | #include <linux/init_task.h> |
| 17 | #include <linux/errno.h> | 17 | #include <linux/errno.h> |
| 18 | #include <linux/kernel.h> | ||
| 19 | #include <linux/cpu.h> | ||
| 18 | 20 | ||
| 19 | #include <asm/page.h> | 21 | #include <asm/page.h> |
| 20 | #include <asm/current.h> | 22 | #include <asm/current.h> |
| @@ -25,6 +27,7 @@ | |||
| 25 | #include <asm/sections.h> /* _end */ | 27 | #include <asm/sections.h> /* _end */ |
| 26 | #include <asm/prom.h> | 28 | #include <asm/prom.h> |
| 27 | #include <asm/smp.h> | 29 | #include <asm/smp.h> |
| 30 | #include <asm/hw_breakpoint.h> | ||
| 28 | 31 | ||
| 29 | int default_machine_kexec_prepare(struct kimage *image) | 32 | int default_machine_kexec_prepare(struct kimage *image) |
| 30 | { | 33 | { |
| @@ -165,6 +168,7 @@ static void kexec_smp_down(void *arg) | |||
| 165 | while(kexec_all_irq_disabled == 0) | 168 | while(kexec_all_irq_disabled == 0) |
| 166 | cpu_relax(); | 169 | cpu_relax(); |
| 167 | mb(); /* make sure all irqs are disabled before this */ | 170 | mb(); /* make sure all irqs are disabled before this */ |
| 171 | hw_breakpoint_disable(); | ||
| 168 | /* | 172 | /* |
| 169 | * Now every CPU has IRQs off, we can clear out any pending | 173 | * Now every CPU has IRQs off, we can clear out any pending |
| 170 | * IPIs and be sure that no more will come in after this. | 174 | * IPIs and be sure that no more will come in after this. |
| @@ -180,8 +184,22 @@ static void kexec_prepare_cpus_wait(int wait_state) | |||
| 180 | { | 184 | { |
| 181 | int my_cpu, i, notified=-1; | 185 | int my_cpu, i, notified=-1; |
| 182 | 186 | ||
| 187 | hw_breakpoint_disable(); | ||
| 183 | my_cpu = get_cpu(); | 188 | my_cpu = get_cpu(); |
| 184 | /* Make sure each CPU has atleast made it to the state we need */ | 189 | /* Make sure each CPU has at least made it to the state we need. |
| 190 | * | ||
| 191 | * FIXME: There is a (slim) chance of a problem if not all of the CPUs | ||
| 192 | * are correctly onlined. If somehow we start a CPU on boot with RTAS | ||
| 193 | * start-cpu, but somehow that CPU doesn't write callin_cpu_map[] in | ||
| 194 | * time, the boot CPU will timeout. If it does eventually execute | ||
| 195 | * stuff, the secondary will start up (paca[].cpu_start was written) and | ||
| 196 | * get into a peculiar state. If the platform supports | ||
| 197 | * smp_ops->take_timebase(), the secondary CPU will probably be spinning | ||
| 198 | * in there. If not (i.e. pseries), the secondary will continue on and | ||
| 199 | * try to online itself/idle/etc. If it survives that, we need to find | ||
| 200 | * these possible-but-not-online-but-should-be CPUs and chaperone them | ||
| 201 | * into kexec_smp_wait(). | ||
| 202 | */ | ||
| 185 | for_each_online_cpu(i) { | 203 | for_each_online_cpu(i) { |
| 186 | if (i == my_cpu) | 204 | if (i == my_cpu) |
| 187 | continue; | 205 | continue; |
| @@ -189,9 +207,9 @@ static void kexec_prepare_cpus_wait(int wait_state) | |||
| 189 | while (paca[i].kexec_state < wait_state) { | 207 | while (paca[i].kexec_state < wait_state) { |
| 190 | barrier(); | 208 | barrier(); |
| 191 | if (i != notified) { | 209 | if (i != notified) { |
| 192 | printk( "kexec: waiting for cpu %d (physical" | 210 | printk(KERN_INFO "kexec: waiting for cpu %d " |
| 193 | " %d) to enter %i state\n", | 211 | "(physical %d) to enter %i state\n", |
| 194 | i, paca[i].hw_cpu_id, wait_state); | 212 | i, paca[i].hw_cpu_id, wait_state); |
| 195 | notified = i; | 213 | notified = i; |
| 196 | } | 214 | } |
| 197 | } | 215 | } |
| @@ -199,9 +217,32 @@ static void kexec_prepare_cpus_wait(int wait_state) | |||
| 199 | mb(); | 217 | mb(); |
| 200 | } | 218 | } |
| 201 | 219 | ||
| 202 | static void kexec_prepare_cpus(void) | 220 | /* |
| 221 | * We need to make sure each present CPU is online. The next kernel will scan | ||
| 222 | * the device tree and assume primary threads are online and query secondary | ||
| 223 | * threads via RTAS to online them if required. If we don't online primary | ||
| 224 | * threads, they will be stuck. However, we also online secondary threads as we | ||
| 225 | * may be using 'cede offline'. In this case RTAS doesn't see the secondary | ||
| 226 | * threads as offline -- and again, these CPUs will be stuck. | ||
| 227 | * | ||
| 228 | * So, we online all CPUs that should be running, including secondary threads. | ||
| 229 | */ | ||
| 230 | static void wake_offline_cpus(void) | ||
| 203 | { | 231 | { |
| 232 | int cpu = 0; | ||
| 204 | 233 | ||
| 234 | for_each_present_cpu(cpu) { | ||
| 235 | if (!cpu_online(cpu)) { | ||
| 236 | printk(KERN_INFO "kexec: Waking offline cpu %d.\n", | ||
| 237 | cpu); | ||
| 238 | cpu_up(cpu); | ||
| 239 | } | ||
| 240 | } | ||
| 241 | } | ||
| 242 | |||
| 243 | static void kexec_prepare_cpus(void) | ||
| 244 | { | ||
| 245 | wake_offline_cpus(); | ||
| 205 | smp_call_function(kexec_smp_down, NULL, /* wait */0); | 246 | smp_call_function(kexec_smp_down, NULL, /* wait */0); |
| 206 | local_irq_disable(); | 247 | local_irq_disable(); |
| 207 | mb(); /* make sure IRQs are disabled before we say they are */ | 248 | mb(); /* make sure IRQs are disabled before we say they are */ |
| @@ -215,7 +256,10 @@ static void kexec_prepare_cpus(void) | |||
| 215 | if (ppc_md.kexec_cpu_down) | 256 | if (ppc_md.kexec_cpu_down) |
| 216 | ppc_md.kexec_cpu_down(0, 0); | 257 | ppc_md.kexec_cpu_down(0, 0); |
| 217 | 258 | ||
| 218 | /* Before removing MMU mapings make sure all CPUs have entered real mode */ | 259 | /* |
| 260 | * Before removing MMU mappings make sure all CPUs have entered real | ||
| 261 | * mode: | ||
| 262 | */ | ||
| 219 | kexec_prepare_cpus_wait(KEXEC_STATE_REAL_MODE); | 263 | kexec_prepare_cpus_wait(KEXEC_STATE_REAL_MODE); |
| 220 | 264 | ||
| 221 | put_cpu(); | 265 | put_cpu(); |
| @@ -257,6 +301,12 @@ static void kexec_prepare_cpus(void) | |||
| 257 | static union thread_union kexec_stack __init_task_data = | 301 | static union thread_union kexec_stack __init_task_data = |
| 258 | { }; | 302 | { }; |
| 259 | 303 | ||
| 304 | /* | ||
| 305 | * For similar reasons to the stack above, the kexecing CPU needs to be on a | ||
| 306 | * static PACA; we switch to kexec_paca. | ||
| 307 | */ | ||
| 308 | struct paca_struct kexec_paca; | ||
| 309 | |||
| 260 | /* Our assembly helper, in kexec_stub.S */ | 310 | /* Our assembly helper, in kexec_stub.S */ |
| 261 | extern NORET_TYPE void kexec_sequence(void *newstack, unsigned long start, | 311 | extern NORET_TYPE void kexec_sequence(void *newstack, unsigned long start, |
| 262 | void *image, void *control, | 312 | void *image, void *control, |
| @@ -278,12 +328,28 @@ void default_machine_kexec(struct kimage *image) | |||
| 278 | if (crashing_cpu == -1) | 328 | if (crashing_cpu == -1) |
| 279 | kexec_prepare_cpus(); | 329 | kexec_prepare_cpus(); |
| 280 | 330 | ||
| 331 | pr_debug("kexec: Starting switchover sequence.\n"); | ||
| 332 | |||
| 281 | /* switch to a staticly allocated stack. Based on irq stack code. | 333 | /* switch to a staticly allocated stack. Based on irq stack code. |
| 282 | * XXX: the task struct will likely be invalid once we do the copy! | 334 | * XXX: the task struct will likely be invalid once we do the copy! |
| 283 | */ | 335 | */ |
| 284 | kexec_stack.thread_info.task = current_thread_info()->task; | 336 | kexec_stack.thread_info.task = current_thread_info()->task; |
| 285 | kexec_stack.thread_info.flags = 0; | 337 | kexec_stack.thread_info.flags = 0; |
| 286 | 338 | ||
| 339 | /* We need a static PACA, too; copy this CPU's PACA over and switch to | ||
| 340 | * it. Also poison per_cpu_offset to catch anyone using non-static | ||
| 341 | * data. | ||
| 342 | */ | ||
| 343 | memcpy(&kexec_paca, get_paca(), sizeof(struct paca_struct)); | ||
| 344 | kexec_paca.data_offset = 0xedeaddeadeeeeeeeUL; | ||
| 345 | paca = (struct paca_struct *)RELOC_HIDE(&kexec_paca, 0) - | ||
| 346 | kexec_paca.paca_index; | ||
| 347 | setup_paca(&kexec_paca); | ||
| 348 | |||
| 349 | /* XXX: If anyone does 'dynamic lppacas' this will also need to be | ||
| 350 | * switched to a static version! | ||
| 351 | */ | ||
| 352 | |||
| 287 | /* Some things are best done in assembly. Finding globals with | 353 | /* Some things are best done in assembly. Finding globals with |
| 288 | * a toc is easier in C, so pass in what we can. | 354 | * a toc is easier in C, so pass in what we can. |
| 289 | */ | 355 | */ |
diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c deleted file mode 100644 index df78e0236a02..000000000000 --- a/arch/powerpc/kernel/of_device.c +++ /dev/null | |||
| @@ -1,133 +0,0 @@ | |||
| 1 | #include <linux/string.h> | ||
| 2 | #include <linux/kernel.h> | ||
| 3 | #include <linux/of.h> | ||
| 4 | #include <linux/init.h> | ||
| 5 | #include <linux/module.h> | ||
| 6 | #include <linux/mod_devicetable.h> | ||
| 7 | #include <linux/slab.h> | ||
| 8 | #include <linux/of_device.h> | ||
| 9 | |||
| 10 | #include <asm/errno.h> | ||
| 11 | #include <asm/dcr.h> | ||
| 12 | |||
| 13 | static void of_device_make_bus_id(struct of_device *dev) | ||
| 14 | { | ||
| 15 | static atomic_t bus_no_reg_magic; | ||
| 16 | struct device_node *node = dev->dev.of_node; | ||
| 17 | const u32 *reg; | ||
| 18 | u64 addr; | ||
| 19 | int magic; | ||
| 20 | |||
| 21 | /* | ||
| 22 | * If it's a DCR based device, use 'd' for native DCRs | ||
| 23 | * and 'D' for MMIO DCRs. | ||
| 24 | */ | ||
| 25 | #ifdef CONFIG_PPC_DCR | ||
| 26 | reg = of_get_property(node, "dcr-reg", NULL); | ||
| 27 | if (reg) { | ||
| 28 | #ifdef CONFIG_PPC_DCR_NATIVE | ||
| 29 | dev_set_name(&dev->dev, "d%x.%s", *reg, node->name); | ||
| 30 | #else /* CONFIG_PPC_DCR_NATIVE */ | ||
| 31 | addr = of_translate_dcr_address(node, *reg, NULL); | ||
| 32 | if (addr != OF_BAD_ADDR) { | ||
| 33 | dev_set_name(&dev->dev, "D%llx.%s", | ||
| 34 | (unsigned long long)addr, node->name); | ||
| 35 | return; | ||
| 36 | } | ||
| 37 | #endif /* !CONFIG_PPC_DCR_NATIVE */ | ||
| 38 | } | ||
| 39 | #endif /* CONFIG_PPC_DCR */ | ||
| 40 | |||
| 41 | /* | ||
| 42 | * For MMIO, get the physical address | ||
| 43 | */ | ||
| 44 | reg = of_get_property(node, "reg", NULL); | ||
| 45 | if (reg) { | ||
| 46 | addr = of_translate_address(node, reg); | ||
| 47 | if (addr != OF_BAD_ADDR) { | ||
| 48 | dev_set_name(&dev->dev, "%llx.%s", | ||
| 49 | (unsigned long long)addr, node->name); | ||
| 50 | return; | ||
| 51 | } | ||
| 52 | } | ||
| 53 | |||
| 54 | /* | ||
| 55 | * No BusID, use the node name and add a globally incremented | ||
| 56 | * counter (and pray...) | ||
| 57 | */ | ||
| 58 | magic = atomic_add_return(1, &bus_no_reg_magic); | ||
| 59 | dev_set_name(&dev->dev, "%s.%d", node->name, magic - 1); | ||
| 60 | } | ||
| 61 | |||
| 62 | struct of_device *of_device_alloc(struct device_node *np, | ||
| 63 | const char *bus_id, | ||
| 64 | struct device *parent) | ||
| 65 | { | ||
| 66 | struct of_device *dev; | ||
| 67 | |||
| 68 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
| 69 | if (!dev) | ||
| 70 | return NULL; | ||
| 71 | |||
| 72 | dev->dev.of_node = of_node_get(np); | ||
| 73 | dev->dev.dma_mask = &dev->archdata.dma_mask; | ||
| 74 | dev->dev.parent = parent; | ||
| 75 | dev->dev.release = of_release_dev; | ||
| 76 | |||
| 77 | if (bus_id) | ||
| 78 | dev_set_name(&dev->dev, "%s", bus_id); | ||
| 79 | else | ||
| 80 | of_device_make_bus_id(dev); | ||
| 81 | |||
| 82 | return dev; | ||
| 83 | } | ||
| 84 | EXPORT_SYMBOL(of_device_alloc); | ||
| 85 | |||
| 86 | int of_device_uevent(struct device *dev, struct kobj_uevent_env *env) | ||
| 87 | { | ||
| 88 | struct of_device *ofdev; | ||
| 89 | const char *compat; | ||
| 90 | int seen = 0, cplen, sl; | ||
| 91 | |||
| 92 | if (!dev) | ||
| 93 | return -ENODEV; | ||
| 94 | |||
| 95 | ofdev = to_of_device(dev); | ||
| 96 | |||
| 97 | if (add_uevent_var(env, "OF_NAME=%s", ofdev->dev.of_node->name)) | ||
| 98 | return -ENOMEM; | ||
| 99 | |||
| 100 | if (add_uevent_var(env, "OF_TYPE=%s", ofdev->dev.of_node->type)) | ||
| 101 | return -ENOMEM; | ||
| 102 | |||
| 103 | /* Since the compatible field can contain pretty much anything | ||
| 104 | * it's not really legal to split it out with commas. We split it | ||
| 105 | * up using a number of environment variables instead. */ | ||
| 106 | |||
| 107 | compat = of_get_property(ofdev->dev.of_node, "compatible", &cplen); | ||
| 108 | while (compat && *compat && cplen > 0) { | ||
| 109 | if (add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat)) | ||
| 110 | return -ENOMEM; | ||
| 111 | |||
| 112 | sl = strlen (compat) + 1; | ||
| 113 | compat += sl; | ||
| 114 | cplen -= sl; | ||
| 115 | seen++; | ||
| 116 | } | ||
| 117 | |||
| 118 | if (add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen)) | ||
| 119 | return -ENOMEM; | ||
| 120 | |||
| 121 | /* modalias is trickier, we add it in 2 steps */ | ||
| 122 | if (add_uevent_var(env, "MODALIAS=")) | ||
| 123 | return -ENOMEM; | ||
| 124 | sl = of_device_get_modalias(ofdev, &env->buf[env->buflen-1], | ||
| 125 | sizeof(env->buf) - env->buflen); | ||
| 126 | if (sl >= (sizeof(env->buf) - env->buflen)) | ||
| 127 | return -ENOMEM; | ||
| 128 | env->buflen += sl; | ||
| 129 | |||
| 130 | return 0; | ||
| 131 | } | ||
| 132 | EXPORT_SYMBOL(of_device_uevent); | ||
| 133 | EXPORT_SYMBOL(of_device_get_modalias); | ||
diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c index 487a98851ba6..b2c363ef38ad 100644 --- a/arch/powerpc/kernel/of_platform.c +++ b/arch/powerpc/kernel/of_platform.c | |||
| @@ -28,207 +28,6 @@ | |||
| 28 | #include <asm/ppc-pci.h> | 28 | #include <asm/ppc-pci.h> |
| 29 | #include <asm/atomic.h> | 29 | #include <asm/atomic.h> |
| 30 | 30 | ||
| 31 | /* | ||
| 32 | * The list of OF IDs below is used for matching bus types in the | ||
| 33 | * system whose devices are to be exposed as of_platform_devices. | ||
| 34 | * | ||
| 35 | * This is the default list valid for most platforms. This file provides | ||
| 36 | * functions who can take an explicit list if necessary though | ||
| 37 | * | ||
| 38 | * The search is always performed recursively looking for children of | ||
| 39 | * the provided device_node and recursively if such a children matches | ||
| 40 | * a bus type in the list | ||
| 41 | */ | ||
| 42 | |||
| 43 | static const struct of_device_id of_default_bus_ids[] = { | ||
| 44 | { .type = "soc", }, | ||
| 45 | { .compatible = "soc", }, | ||
| 46 | { .type = "spider", }, | ||
| 47 | { .type = "axon", }, | ||
| 48 | { .type = "plb5", }, | ||
| 49 | { .type = "plb4", }, | ||
| 50 | { .type = "opb", }, | ||
| 51 | { .type = "ebc", }, | ||
| 52 | {}, | ||
| 53 | }; | ||
| 54 | |||
| 55 | struct bus_type of_platform_bus_type = { | ||
| 56 | .uevent = of_device_uevent, | ||
| 57 | }; | ||
| 58 | EXPORT_SYMBOL(of_platform_bus_type); | ||
| 59 | |||
| 60 | static int __init of_bus_driver_init(void) | ||
| 61 | { | ||
| 62 | return of_bus_type_init(&of_platform_bus_type, "of_platform"); | ||
| 63 | } | ||
| 64 | |||
| 65 | postcore_initcall(of_bus_driver_init); | ||
| 66 | |||
| 67 | struct of_device* of_platform_device_create(struct device_node *np, | ||
| 68 | const char *bus_id, | ||
| 69 | struct device *parent) | ||
| 70 | { | ||
| 71 | struct of_device *dev; | ||
| 72 | |||
| 73 | dev = of_device_alloc(np, bus_id, parent); | ||
| 74 | if (!dev) | ||
| 75 | return NULL; | ||
| 76 | |||
| 77 | dev->archdata.dma_mask = 0xffffffffUL; | ||
| 78 | dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); | ||
| 79 | |||
| 80 | dev->dev.bus = &of_platform_bus_type; | ||
| 81 | |||
| 82 | /* We do not fill the DMA ops for platform devices by default. | ||
| 83 | * This is currently the responsibility of the platform code | ||
| 84 | * to do such, possibly using a device notifier | ||
| 85 | */ | ||
| 86 | |||
| 87 | if (of_device_register(dev) != 0) { | ||
| 88 | of_device_free(dev); | ||
| 89 | return NULL; | ||
| 90 | } | ||
| 91 | |||
| 92 | return dev; | ||
| 93 | } | ||
| 94 | EXPORT_SYMBOL(of_platform_device_create); | ||
| 95 | |||
| 96 | |||
| 97 | |||
| 98 | /** | ||
| 99 | * of_platform_bus_create - Create an OF device for a bus node and all its | ||
| 100 | * children. Optionally recursively instanciate matching busses. | ||
| 101 | * @bus: device node of the bus to instanciate | ||
| 102 | * @matches: match table, NULL to use the default, OF_NO_DEEP_PROBE to | ||
| 103 | * disallow recursive creation of child busses | ||
| 104 | */ | ||
| 105 | static int of_platform_bus_create(const struct device_node *bus, | ||
| 106 | const struct of_device_id *matches, | ||
| 107 | struct device *parent) | ||
| 108 | { | ||
| 109 | struct device_node *child; | ||
| 110 | struct of_device *dev; | ||
| 111 | int rc = 0; | ||
| 112 | |||
| 113 | for_each_child_of_node(bus, child) { | ||
| 114 | pr_debug(" create child: %s\n", child->full_name); | ||
| 115 | dev = of_platform_device_create(child, NULL, parent); | ||
| 116 | if (dev == NULL) | ||
| 117 | rc = -ENOMEM; | ||
| 118 | else if (!of_match_node(matches, child)) | ||
| 119 | continue; | ||
| 120 | if (rc == 0) { | ||
| 121 | pr_debug(" and sub busses\n"); | ||
| 122 | rc = of_platform_bus_create(child, matches, &dev->dev); | ||
| 123 | } if (rc) { | ||
| 124 | of_node_put(child); | ||
| 125 | break; | ||
| 126 | } | ||
| 127 | } | ||
| 128 | return rc; | ||
| 129 | } | ||
| 130 | |||
| 131 | /** | ||
| 132 | * of_platform_bus_probe - Probe the device-tree for platform busses | ||
| 133 | * @root: parent of the first level to probe or NULL for the root of the tree | ||
| 134 | * @matches: match table, NULL to use the default | ||
| 135 | * @parent: parent to hook devices from, NULL for toplevel | ||
| 136 | * | ||
| 137 | * Note that children of the provided root are not instanciated as devices | ||
| 138 | * unless the specified root itself matches the bus list and is not NULL. | ||
| 139 | */ | ||
| 140 | |||
| 141 | int of_platform_bus_probe(struct device_node *root, | ||
| 142 | const struct of_device_id *matches, | ||
| 143 | struct device *parent) | ||
| 144 | { | ||
| 145 | struct device_node *child; | ||
| 146 | struct of_device *dev; | ||
| 147 | int rc = 0; | ||
| 148 | |||
| 149 | if (matches == NULL) | ||
| 150 | matches = of_default_bus_ids; | ||
| 151 | if (matches == OF_NO_DEEP_PROBE) | ||
| 152 | return -EINVAL; | ||
| 153 | if (root == NULL) | ||
| 154 | root = of_find_node_by_path("/"); | ||
| 155 | else | ||
| 156 | of_node_get(root); | ||
| 157 | |||
| 158 | pr_debug("of_platform_bus_probe()\n"); | ||
| 159 | pr_debug(" starting at: %s\n", root->full_name); | ||
| 160 | |||
| 161 | /* Do a self check of bus type, if there's a match, create | ||
| 162 | * children | ||
| 163 | */ | ||
| 164 | if (of_match_node(matches, root)) { | ||
| 165 | pr_debug(" root match, create all sub devices\n"); | ||
| 166 | dev = of_platform_device_create(root, NULL, parent); | ||
| 167 | if (dev == NULL) { | ||
| 168 | rc = -ENOMEM; | ||
| 169 | goto bail; | ||
| 170 | } | ||
| 171 | pr_debug(" create all sub busses\n"); | ||
| 172 | rc = of_platform_bus_create(root, matches, &dev->dev); | ||
| 173 | goto bail; | ||
| 174 | } | ||
| 175 | for_each_child_of_node(root, child) { | ||
| 176 | if (!of_match_node(matches, child)) | ||
| 177 | continue; | ||
| 178 | |||
| 179 | pr_debug(" match: %s\n", child->full_name); | ||
| 180 | dev = of_platform_device_create(child, NULL, parent); | ||
| 181 | if (dev == NULL) | ||
| 182 | rc = -ENOMEM; | ||
| 183 | else | ||
| 184 | rc = of_platform_bus_create(child, matches, &dev->dev); | ||
| 185 | if (rc) { | ||
| 186 | of_node_put(child); | ||
| 187 | break; | ||
| 188 | } | ||
| 189 | } | ||
| 190 | bail: | ||
| 191 | of_node_put(root); | ||
| 192 | return rc; | ||
| 193 | } | ||
| 194 | EXPORT_SYMBOL(of_platform_bus_probe); | ||
| 195 | |||
| 196 | static int of_dev_node_match(struct device *dev, void *data) | ||
| 197 | { | ||
| 198 | return to_of_device(dev)->dev.of_node == data; | ||
| 199 | } | ||
| 200 | |||
| 201 | struct of_device *of_find_device_by_node(struct device_node *np) | ||
| 202 | { | ||
| 203 | struct device *dev; | ||
| 204 | |||
| 205 | dev = bus_find_device(&of_platform_bus_type, | ||
| 206 | NULL, np, of_dev_node_match); | ||
| 207 | if (dev) | ||
| 208 | return to_of_device(dev); | ||
| 209 | return NULL; | ||
| 210 | } | ||
| 211 | EXPORT_SYMBOL(of_find_device_by_node); | ||
| 212 | |||
| 213 | static int of_dev_phandle_match(struct device *dev, void *data) | ||
| 214 | { | ||
| 215 | phandle *ph = data; | ||
| 216 | return to_of_device(dev)->dev.of_node->phandle == *ph; | ||
| 217 | } | ||
| 218 | |||
| 219 | struct of_device *of_find_device_by_phandle(phandle ph) | ||
| 220 | { | ||
| 221 | struct device *dev; | ||
| 222 | |||
| 223 | dev = bus_find_device(&of_platform_bus_type, | ||
| 224 | NULL, &ph, of_dev_phandle_match); | ||
| 225 | if (dev) | ||
| 226 | return to_of_device(dev); | ||
| 227 | return NULL; | ||
| 228 | } | ||
| 229 | EXPORT_SYMBOL(of_find_device_by_phandle); | ||
| 230 | |||
| 231 | |||
| 232 | #ifdef CONFIG_PPC_OF_PLATFORM_PCI | 31 | #ifdef CONFIG_PPC_OF_PLATFORM_PCI |
| 233 | 32 | ||
| 234 | /* The probing of PCI controllers from of_platform is currently | 33 | /* The probing of PCI controllers from of_platform is currently |
| @@ -237,7 +36,7 @@ EXPORT_SYMBOL(of_find_device_by_phandle); | |||
| 237 | * lacking some bits needed here. | 36 | * lacking some bits needed here. |
| 238 | */ | 37 | */ |
| 239 | 38 | ||
| 240 | static int __devinit of_pci_phb_probe(struct of_device *dev, | 39 | static int __devinit of_pci_phb_probe(struct platform_device *dev, |
| 241 | const struct of_device_id *match) | 40 | const struct of_device_id *match) |
| 242 | { | 41 | { |
| 243 | struct pci_controller *phb; | 42 | struct pci_controller *phb; |
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c index 139a773853f4..d0a26f1770fe 100644 --- a/arch/powerpc/kernel/paca.c +++ b/arch/powerpc/kernel/paca.c | |||
| @@ -105,6 +105,16 @@ void __init initialise_paca(struct paca_struct *new_paca, int cpu) | |||
| 105 | #endif /* CONFIG_PPC_STD_MMU_64 */ | 105 | #endif /* CONFIG_PPC_STD_MMU_64 */ |
| 106 | } | 106 | } |
| 107 | 107 | ||
| 108 | /* Put the paca pointer into r13 and SPRG_PACA */ | ||
| 109 | void setup_paca(struct paca_struct *new_paca) | ||
| 110 | { | ||
| 111 | local_paca = new_paca; | ||
| 112 | mtspr(SPRN_SPRG_PACA, local_paca); | ||
| 113 | #ifdef CONFIG_PPC_BOOK3E | ||
| 114 | mtspr(SPRN_SPRG_TLB_EXFRAME, local_paca->extlb); | ||
| 115 | #endif | ||
| 116 | } | ||
| 117 | |||
| 108 | static int __initdata paca_size; | 118 | static int __initdata paca_size; |
| 109 | 119 | ||
| 110 | void __init allocate_pacas(void) | 120 | void __init allocate_pacas(void) |
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 5b38f6ae2b29..9021c4ad4bbd 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <linux/string.h> | 21 | #include <linux/string.h> |
| 22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
| 23 | #include <linux/bootmem.h> | 23 | #include <linux/bootmem.h> |
| 24 | #include <linux/of_address.h> | ||
| 24 | #include <linux/mm.h> | 25 | #include <linux/mm.h> |
| 25 | #include <linux/list.h> | 26 | #include <linux/list.h> |
| 26 | #include <linux/syscalls.h> | 27 | #include <linux/syscalls.h> |
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 773424df828a..551f6713ff42 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c | |||
| @@ -37,6 +37,7 @@ | |||
| 37 | #include <linux/kernel_stat.h> | 37 | #include <linux/kernel_stat.h> |
| 38 | #include <linux/personality.h> | 38 | #include <linux/personality.h> |
| 39 | #include <linux/random.h> | 39 | #include <linux/random.h> |
| 40 | #include <linux/hw_breakpoint.h> | ||
| 40 | 41 | ||
| 41 | #include <asm/pgtable.h> | 42 | #include <asm/pgtable.h> |
| 42 | #include <asm/uaccess.h> | 43 | #include <asm/uaccess.h> |
| @@ -462,14 +463,42 @@ struct task_struct *__switch_to(struct task_struct *prev, | |||
| 462 | #ifdef CONFIG_PPC_ADV_DEBUG_REGS | 463 | #ifdef CONFIG_PPC_ADV_DEBUG_REGS |
| 463 | switch_booke_debug_regs(&new->thread); | 464 | switch_booke_debug_regs(&new->thread); |
| 464 | #else | 465 | #else |
| 466 | /* | ||
| 467 | * For PPC_BOOK3S_64, we use the hw-breakpoint interfaces that would | ||
| 468 | * schedule DABR | ||
| 469 | */ | ||
| 470 | #ifndef CONFIG_HAVE_HW_BREAKPOINT | ||
| 465 | if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr)) | 471 | if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr)) |
| 466 | set_dabr(new->thread.dabr); | 472 | set_dabr(new->thread.dabr); |
| 473 | #endif /* CONFIG_HAVE_HW_BREAKPOINT */ | ||
| 467 | #endif | 474 | #endif |
| 468 | 475 | ||
| 469 | 476 | ||
| 470 | new_thread = &new->thread; | 477 | new_thread = &new->thread; |
| 471 | old_thread = ¤t->thread; | 478 | old_thread = ¤t->thread; |
| 472 | 479 | ||
| 480 | #if defined(CONFIG_PPC_BOOK3E_64) | ||
| 481 | /* XXX Current Book3E code doesn't deal with kernel side DBCR0, | ||
| 482 | * we always hold the user values, so we set it now. | ||
| 483 | * | ||
| 484 | * However, we ensure the kernel MSR:DE is appropriately cleared too | ||
| 485 | * to avoid spurrious single step exceptions in the kernel. | ||
| 486 | * | ||
| 487 | * This will have to change to merge with the ppc32 code at some point, | ||
| 488 | * but I don't like much what ppc32 is doing today so there's some | ||
| 489 | * thinking needed there | ||
| 490 | */ | ||
| 491 | if ((new_thread->dbcr0 | old_thread->dbcr0) & DBCR0_IDM) { | ||
| 492 | u32 dbcr0; | ||
| 493 | |||
| 494 | mtmsr(mfmsr() & ~MSR_DE); | ||
| 495 | isync(); | ||
| 496 | dbcr0 = mfspr(SPRN_DBCR0); | ||
| 497 | dbcr0 = (dbcr0 & DBCR0_EDM) | new_thread->dbcr0; | ||
| 498 | mtspr(SPRN_DBCR0, dbcr0); | ||
| 499 | } | ||
| 500 | #endif /* CONFIG_PPC64_BOOK3E */ | ||
| 501 | |||
| 473 | #ifdef CONFIG_PPC64 | 502 | #ifdef CONFIG_PPC64 |
| 474 | /* | 503 | /* |
| 475 | * Collect processor utilization data per process | 504 | * Collect processor utilization data per process |
| @@ -642,7 +671,11 @@ void flush_thread(void) | |||
| 642 | { | 671 | { |
| 643 | discard_lazy_cpu_state(); | 672 | discard_lazy_cpu_state(); |
| 644 | 673 | ||
| 674 | #ifdef CONFIG_HAVE_HW_BREAKPOINTS | ||
| 675 | flush_ptrace_hw_breakpoint(current); | ||
| 676 | #else /* CONFIG_HAVE_HW_BREAKPOINTS */ | ||
| 645 | set_debug_reg_defaults(¤t->thread); | 677 | set_debug_reg_defaults(¤t->thread); |
| 678 | #endif /* CONFIG_HAVE_HW_BREAKPOINTS */ | ||
| 646 | } | 679 | } |
| 647 | 680 | ||
| 648 | void | 681 | void |
| @@ -660,6 +693,9 @@ void prepare_to_copy(struct task_struct *tsk) | |||
| 660 | flush_altivec_to_thread(current); | 693 | flush_altivec_to_thread(current); |
| 661 | flush_vsx_to_thread(current); | 694 | flush_vsx_to_thread(current); |
| 662 | flush_spe_to_thread(current); | 695 | flush_spe_to_thread(current); |
| 696 | #ifdef CONFIG_HAVE_HW_BREAKPOINT | ||
| 697 | flush_ptrace_hw_breakpoint(tsk); | ||
| 698 | #endif /* CONFIG_HAVE_HW_BREAKPOINT */ | ||
| 663 | } | 699 | } |
| 664 | 700 | ||
| 665 | /* | 701 | /* |
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 3b6f8ae9b8cc..941ff4dbc567 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c | |||
| @@ -311,6 +311,24 @@ static void __init prom_print_hex(unsigned long val) | |||
| 311 | call_prom("write", 3, 1, _prom->stdout, buf, nibbles); | 311 | call_prom("write", 3, 1, _prom->stdout, buf, nibbles); |
| 312 | } | 312 | } |
| 313 | 313 | ||
| 314 | /* max number of decimal digits in an unsigned long */ | ||
| 315 | #define UL_DIGITS 21 | ||
| 316 | static void __init prom_print_dec(unsigned long val) | ||
| 317 | { | ||
| 318 | int i, size; | ||
| 319 | char buf[UL_DIGITS+1]; | ||
| 320 | struct prom_t *_prom = &RELOC(prom); | ||
| 321 | |||
| 322 | for (i = UL_DIGITS-1; i >= 0; i--) { | ||
| 323 | buf[i] = (val % 10) + '0'; | ||
| 324 | val = val/10; | ||
| 325 | if (val == 0) | ||
| 326 | break; | ||
| 327 | } | ||
| 328 | /* shift stuff down */ | ||
| 329 | size = UL_DIGITS - i; | ||
| 330 | call_prom("write", 3, 1, _prom->stdout, buf+i, size); | ||
| 331 | } | ||
| 314 | 332 | ||
| 315 | static void __init prom_printf(const char *format, ...) | 333 | static void __init prom_printf(const char *format, ...) |
| 316 | { | 334 | { |
| @@ -350,6 +368,14 @@ static void __init prom_printf(const char *format, ...) | |||
| 350 | v = va_arg(args, unsigned long); | 368 | v = va_arg(args, unsigned long); |
| 351 | prom_print_hex(v); | 369 | prom_print_hex(v); |
| 352 | break; | 370 | break; |
| 371 | case 'l': | ||
| 372 | ++q; | ||
| 373 | if (*q == 'u') { /* '%lu' */ | ||
| 374 | ++q; | ||
| 375 | v = va_arg(args, unsigned long); | ||
| 376 | prom_print_dec(v); | ||
| 377 | } | ||
| 378 | break; | ||
| 353 | } | 379 | } |
| 354 | } | 380 | } |
| 355 | } | 381 | } |
| @@ -835,11 +861,11 @@ static int __init prom_count_smt_threads(void) | |||
| 835 | if (plen == PROM_ERROR) | 861 | if (plen == PROM_ERROR) |
| 836 | break; | 862 | break; |
| 837 | plen >>= 2; | 863 | plen >>= 2; |
| 838 | prom_debug("Found 0x%x smt threads per core\n", (unsigned long)plen); | 864 | prom_debug("Found %lu smt threads per core\n", (unsigned long)plen); |
| 839 | 865 | ||
| 840 | /* Sanity check */ | 866 | /* Sanity check */ |
| 841 | if (plen < 1 || plen > 64) { | 867 | if (plen < 1 || plen > 64) { |
| 842 | prom_printf("Threads per core 0x%x out of bounds, assuming 1\n", | 868 | prom_printf("Threads per core %lu out of bounds, assuming 1\n", |
| 843 | (unsigned long)plen); | 869 | (unsigned long)plen); |
| 844 | return 1; | 870 | return 1; |
| 845 | } | 871 | } |
| @@ -869,12 +895,12 @@ static void __init prom_send_capabilities(void) | |||
| 869 | cores = (u32 *)PTRRELOC(&ibm_architecture_vec[IBM_ARCH_VEC_NRCORES_OFFSET]); | 895 | cores = (u32 *)PTRRELOC(&ibm_architecture_vec[IBM_ARCH_VEC_NRCORES_OFFSET]); |
| 870 | if (*cores != NR_CPUS) { | 896 | if (*cores != NR_CPUS) { |
| 871 | prom_printf("WARNING ! " | 897 | prom_printf("WARNING ! " |
| 872 | "ibm_architecture_vec structure inconsistent: 0x%x !\n", | 898 | "ibm_architecture_vec structure inconsistent: %lu!\n", |
| 873 | *cores); | 899 | *cores); |
| 874 | } else { | 900 | } else { |
| 875 | *cores = DIV_ROUND_UP(NR_CPUS, prom_count_smt_threads()); | 901 | *cores = DIV_ROUND_UP(NR_CPUS, prom_count_smt_threads()); |
| 876 | prom_printf("Max number of cores passed to firmware: 0x%x\n", | 902 | prom_printf("Max number of cores passed to firmware: %lu (NR_CPUS = %lu)\n", |
| 877 | (unsigned long)*cores); | 903 | *cores, NR_CPUS); |
| 878 | } | 904 | } |
| 879 | 905 | ||
| 880 | /* try calling the ibm,client-architecture-support method */ | 906 | /* try calling the ibm,client-architecture-support method */ |
| @@ -1482,7 +1508,7 @@ static void __init prom_hold_cpus(void) | |||
| 1482 | reg = -1; | 1508 | reg = -1; |
| 1483 | prom_getprop(node, "reg", ®, sizeof(reg)); | 1509 | prom_getprop(node, "reg", ®, sizeof(reg)); |
| 1484 | 1510 | ||
| 1485 | prom_debug("cpu hw idx = 0x%x\n", reg); | 1511 | prom_debug("cpu hw idx = %lu\n", reg); |
| 1486 | 1512 | ||
| 1487 | /* Init the acknowledge var which will be reset by | 1513 | /* Init the acknowledge var which will be reset by |
| 1488 | * the secondary cpu when it awakens from its OF | 1514 | * the secondary cpu when it awakens from its OF |
| @@ -1492,7 +1518,7 @@ static void __init prom_hold_cpus(void) | |||
| 1492 | 1518 | ||
| 1493 | if (reg != _prom->cpu) { | 1519 | if (reg != _prom->cpu) { |
| 1494 | /* Primary Thread of non-boot cpu */ | 1520 | /* Primary Thread of non-boot cpu */ |
| 1495 | prom_printf("starting cpu hw idx %x... ", reg); | 1521 | prom_printf("starting cpu hw idx %lu... ", reg); |
| 1496 | call_prom("start-cpu", 3, 0, node, | 1522 | call_prom("start-cpu", 3, 0, node, |
| 1497 | secondary_hold, reg); | 1523 | secondary_hold, reg); |
| 1498 | 1524 | ||
| @@ -1507,7 +1533,7 @@ static void __init prom_hold_cpus(void) | |||
| 1507 | } | 1533 | } |
| 1508 | #ifdef CONFIG_SMP | 1534 | #ifdef CONFIG_SMP |
| 1509 | else | 1535 | else |
| 1510 | prom_printf("boot cpu hw idx %x\n", reg); | 1536 | prom_printf("boot cpu hw idx %lu\n", reg); |
| 1511 | #endif /* CONFIG_SMP */ | 1537 | #endif /* CONFIG_SMP */ |
| 1512 | } | 1538 | } |
| 1513 | 1539 | ||
| @@ -2420,7 +2446,7 @@ static void __init prom_find_boot_cpu(void) | |||
| 2420 | prom_getprop(cpu_pkg, "reg", &getprop_rval, sizeof(getprop_rval)); | 2446 | prom_getprop(cpu_pkg, "reg", &getprop_rval, sizeof(getprop_rval)); |
| 2421 | _prom->cpu = getprop_rval; | 2447 | _prom->cpu = getprop_rval; |
| 2422 | 2448 | ||
| 2423 | prom_debug("Booting CPU hw index = 0x%x\n", _prom->cpu); | 2449 | prom_debug("Booting CPU hw index = %lu\n", _prom->cpu); |
| 2424 | } | 2450 | } |
| 2425 | 2451 | ||
| 2426 | static void __init prom_check_initrd(unsigned long r3, unsigned long r4) | 2452 | static void __init prom_check_initrd(unsigned long r3, unsigned long r4) |
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c index 8362620c9e6f..88334af038e5 100644 --- a/arch/powerpc/kernel/prom_parse.c +++ b/arch/powerpc/kernel/prom_parse.c | |||
| @@ -6,232 +6,11 @@ | |||
| 6 | #include <linux/module.h> | 6 | #include <linux/module.h> |
| 7 | #include <linux/ioport.h> | 7 | #include <linux/ioport.h> |
| 8 | #include <linux/etherdevice.h> | 8 | #include <linux/etherdevice.h> |
| 9 | #include <linux/of_address.h> | ||
| 9 | #include <asm/prom.h> | 10 | #include <asm/prom.h> |
| 10 | #include <asm/pci-bridge.h> | 11 | #include <asm/pci-bridge.h> |
| 11 | 12 | ||
| 12 | #ifdef DEBUG | ||
| 13 | #define DBG(fmt...) do { printk(fmt); } while(0) | ||
| 14 | #else | ||
| 15 | #define DBG(fmt...) do { } while(0) | ||
| 16 | #endif | ||
| 17 | |||
| 18 | #ifdef CONFIG_PPC64 | ||
| 19 | #define PRu64 "%lx" | ||
| 20 | #else | ||
| 21 | #define PRu64 "%llx" | ||
| 22 | #endif | ||
| 23 | |||
| 24 | /* Max address size we deal with */ | ||
| 25 | #define OF_MAX_ADDR_CELLS 4 | ||
| 26 | #define OF_CHECK_COUNTS(na, ns) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \ | ||
| 27 | (ns) > 0) | ||
| 28 | |||
| 29 | static struct of_bus *of_match_bus(struct device_node *np); | ||
| 30 | static int __of_address_to_resource(struct device_node *dev, | ||
| 31 | const u32 *addrp, u64 size, unsigned int flags, | ||
| 32 | struct resource *r); | ||
| 33 | |||
| 34 | |||
| 35 | /* Debug utility */ | ||
| 36 | #ifdef DEBUG | ||
| 37 | static void of_dump_addr(const char *s, const u32 *addr, int na) | ||
| 38 | { | ||
| 39 | printk("%s", s); | ||
| 40 | while(na--) | ||
| 41 | printk(" %08x", *(addr++)); | ||
| 42 | printk("\n"); | ||
| 43 | } | ||
| 44 | #else | ||
| 45 | static void of_dump_addr(const char *s, const u32 *addr, int na) { } | ||
| 46 | #endif | ||
| 47 | |||
| 48 | |||
| 49 | /* Callbacks for bus specific translators */ | ||
| 50 | struct of_bus { | ||
| 51 | const char *name; | ||
| 52 | const char *addresses; | ||
| 53 | int (*match)(struct device_node *parent); | ||
| 54 | void (*count_cells)(struct device_node *child, | ||
| 55 | int *addrc, int *sizec); | ||
| 56 | u64 (*map)(u32 *addr, const u32 *range, | ||
| 57 | int na, int ns, int pna); | ||
| 58 | int (*translate)(u32 *addr, u64 offset, int na); | ||
| 59 | unsigned int (*get_flags)(const u32 *addr); | ||
| 60 | }; | ||
| 61 | |||
| 62 | |||
| 63 | /* | ||
| 64 | * Default translator (generic bus) | ||
| 65 | */ | ||
| 66 | |||
| 67 | static void of_bus_default_count_cells(struct device_node *dev, | ||
| 68 | int *addrc, int *sizec) | ||
| 69 | { | ||
| 70 | if (addrc) | ||
| 71 | *addrc = of_n_addr_cells(dev); | ||
| 72 | if (sizec) | ||
| 73 | *sizec = of_n_size_cells(dev); | ||
| 74 | } | ||
| 75 | |||
| 76 | static u64 of_bus_default_map(u32 *addr, const u32 *range, | ||
| 77 | int na, int ns, int pna) | ||
| 78 | { | ||
| 79 | u64 cp, s, da; | ||
| 80 | |||
| 81 | cp = of_read_number(range, na); | ||
| 82 | s = of_read_number(range + na + pna, ns); | ||
| 83 | da = of_read_number(addr, na); | ||
| 84 | |||
| 85 | DBG("OF: default map, cp="PRu64", s="PRu64", da="PRu64"\n", | ||
| 86 | cp, s, da); | ||
| 87 | |||
| 88 | if (da < cp || da >= (cp + s)) | ||
| 89 | return OF_BAD_ADDR; | ||
| 90 | return da - cp; | ||
| 91 | } | ||
| 92 | |||
| 93 | static int of_bus_default_translate(u32 *addr, u64 offset, int na) | ||
| 94 | { | ||
| 95 | u64 a = of_read_number(addr, na); | ||
| 96 | memset(addr, 0, na * 4); | ||
| 97 | a += offset; | ||
| 98 | if (na > 1) | ||
| 99 | addr[na - 2] = a >> 32; | ||
| 100 | addr[na - 1] = a & 0xffffffffu; | ||
| 101 | |||
| 102 | return 0; | ||
| 103 | } | ||
| 104 | |||
| 105 | static unsigned int of_bus_default_get_flags(const u32 *addr) | ||
| 106 | { | ||
| 107 | return IORESOURCE_MEM; | ||
| 108 | } | ||
| 109 | |||
| 110 | |||
| 111 | #ifdef CONFIG_PCI | 13 | #ifdef CONFIG_PCI |
| 112 | /* | ||
| 113 | * PCI bus specific translator | ||
| 114 | */ | ||
| 115 | |||
| 116 | static int of_bus_pci_match(struct device_node *np) | ||
| 117 | { | ||
| 118 | /* "vci" is for the /chaos bridge on 1st-gen PCI powermacs */ | ||
| 119 | return !strcmp(np->type, "pci") || !strcmp(np->type, "vci"); | ||
| 120 | } | ||
| 121 | |||
| 122 | static void of_bus_pci_count_cells(struct device_node *np, | ||
| 123 | int *addrc, int *sizec) | ||
| 124 | { | ||
| 125 | if (addrc) | ||
| 126 | *addrc = 3; | ||
| 127 | if (sizec) | ||
| 128 | *sizec = 2; | ||
| 129 | } | ||
| 130 | |||
| 131 | static unsigned int of_bus_pci_get_flags(const u32 *addr) | ||
| 132 | { | ||
| 133 | unsigned int flags = 0; | ||
| 134 | u32 w = addr[0]; | ||
| 135 | |||
| 136 | switch((w >> 24) & 0x03) { | ||
| 137 | case 0x01: | ||
| 138 | flags |= IORESOURCE_IO; | ||
| 139 | break; | ||
| 140 | case 0x02: /* 32 bits */ | ||
| 141 | case 0x03: /* 64 bits */ | ||
| 142 | flags |= IORESOURCE_MEM; | ||
| 143 | break; | ||
| 144 | } | ||
| 145 | if (w & 0x40000000) | ||
| 146 | flags |= IORESOURCE_PREFETCH; | ||
| 147 | return flags; | ||
| 148 | } | ||
| 149 | |||
| 150 | static u64 of_bus_pci_map(u32 *addr, const u32 *range, int na, int ns, int pna) | ||
| 151 | { | ||
| 152 | u64 cp, s, da; | ||
| 153 | unsigned int af, rf; | ||
| 154 | |||
| 155 | af = of_bus_pci_get_flags(addr); | ||
| 156 | rf = of_bus_pci_get_flags(range); | ||
| 157 | |||
| 158 | /* Check address type match */ | ||
| 159 | if ((af ^ rf) & (IORESOURCE_MEM | IORESOURCE_IO)) | ||
| 160 | return OF_BAD_ADDR; | ||
| 161 | |||
| 162 | /* Read address values, skipping high cell */ | ||
| 163 | cp = of_read_number(range + 1, na - 1); | ||
| 164 | s = of_read_number(range + na + pna, ns); | ||
| 165 | da = of_read_number(addr + 1, na - 1); | ||
| 166 | |||
| 167 | DBG("OF: PCI map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da); | ||
| 168 | |||
| 169 | if (da < cp || da >= (cp + s)) | ||
| 170 | return OF_BAD_ADDR; | ||
| 171 | return da - cp; | ||
| 172 | } | ||
| 173 | |||
| 174 | static int of_bus_pci_translate(u32 *addr, u64 offset, int na) | ||
| 175 | { | ||
| 176 | return of_bus_default_translate(addr + 1, offset, na - 1); | ||
| 177 | } | ||
| 178 | |||
| 179 | const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, | ||
| 180 | unsigned int *flags) | ||
| 181 | { | ||
| 182 | const u32 *prop; | ||
| 183 | unsigned int psize; | ||
| 184 | struct device_node *parent; | ||
| 185 | struct of_bus *bus; | ||
| 186 | int onesize, i, na, ns; | ||
| 187 | |||
| 188 | /* Get parent & match bus type */ | ||
| 189 | parent = of_get_parent(dev); | ||
| 190 | if (parent == NULL) | ||
| 191 | return NULL; | ||
| 192 | bus = of_match_bus(parent); | ||
| 193 | if (strcmp(bus->name, "pci")) { | ||
| 194 | of_node_put(parent); | ||
| 195 | return NULL; | ||
| 196 | } | ||
| 197 | bus->count_cells(dev, &na, &ns); | ||
| 198 | of_node_put(parent); | ||
| 199 | if (!OF_CHECK_COUNTS(na, ns)) | ||
| 200 | return NULL; | ||
| 201 | |||
| 202 | /* Get "reg" or "assigned-addresses" property */ | ||
| 203 | prop = of_get_property(dev, bus->addresses, &psize); | ||
| 204 | if (prop == NULL) | ||
| 205 | return NULL; | ||
| 206 | psize /= 4; | ||
| 207 | |||
| 208 | onesize = na + ns; | ||
| 209 | for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++) | ||
| 210 | if ((prop[0] & 0xff) == ((bar_no * 4) + PCI_BASE_ADDRESS_0)) { | ||
| 211 | if (size) | ||
| 212 | *size = of_read_number(prop + na, ns); | ||
| 213 | if (flags) | ||
| 214 | *flags = bus->get_flags(prop); | ||
| 215 | return prop; | ||
| 216 | } | ||
| 217 | return NULL; | ||
| 218 | } | ||
| 219 | EXPORT_SYMBOL(of_get_pci_address); | ||
| 220 | |||
| 221 | int of_pci_address_to_resource(struct device_node *dev, int bar, | ||
| 222 | struct resource *r) | ||
| 223 | { | ||
| 224 | const u32 *addrp; | ||
| 225 | u64 size; | ||
| 226 | unsigned int flags; | ||
| 227 | |||
| 228 | addrp = of_get_pci_address(dev, bar, &size, &flags); | ||
| 229 | if (addrp == NULL) | ||
| 230 | return -EINVAL; | ||
| 231 | return __of_address_to_resource(dev, addrp, size, flags, r); | ||
| 232 | } | ||
| 233 | EXPORT_SYMBOL_GPL(of_pci_address_to_resource); | ||
| 234 | |||
| 235 | int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq) | 14 | int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq) |
| 236 | { | 15 | { |
| 237 | struct device_node *dn, *ppnode; | 16 | struct device_node *dn, *ppnode; |
| @@ -313,345 +92,6 @@ int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq) | |||
| 313 | EXPORT_SYMBOL_GPL(of_irq_map_pci); | 92 | EXPORT_SYMBOL_GPL(of_irq_map_pci); |
| 314 | #endif /* CONFIG_PCI */ | 93 | #endif /* CONFIG_PCI */ |
| 315 | 94 | ||
| 316 | /* | ||
| 317 | * ISA bus specific translator | ||
| 318 | */ | ||
| 319 | |||
| 320 | static int of_bus_isa_match(struct device_node *np) | ||
| 321 | { | ||
| 322 | return !strcmp(np->name, "isa"); | ||
| 323 | } | ||
| 324 | |||
| 325 | static void of_bus_isa_count_cells(struct device_node *child, | ||
| 326 | int *addrc, int *sizec) | ||
| 327 | { | ||
| 328 | if (addrc) | ||
| 329 | *addrc = 2; | ||
| 330 | if (sizec) | ||
| 331 | *sizec = 1; | ||
| 332 | } | ||
| 333 | |||
| 334 | static u64 of_bus_isa_map(u32 *addr, const u32 *range, int na, int ns, int pna) | ||
| 335 | { | ||
| 336 | u64 cp, s, da; | ||
| 337 | |||
| 338 | /* Check address type match */ | ||
| 339 | if ((addr[0] ^ range[0]) & 0x00000001) | ||
| 340 | return OF_BAD_ADDR; | ||
| 341 | |||
| 342 | /* Read address values, skipping high cell */ | ||
| 343 | cp = of_read_number(range + 1, na - 1); | ||
| 344 | s = of_read_number(range + na + pna, ns); | ||
| 345 | da = of_read_number(addr + 1, na - 1); | ||
| 346 | |||
| 347 | DBG("OF: ISA map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da); | ||
| 348 | |||
| 349 | if (da < cp || da >= (cp + s)) | ||
| 350 | return OF_BAD_ADDR; | ||
| 351 | return da - cp; | ||
| 352 | } | ||
| 353 | |||
| 354 | static int of_bus_isa_translate(u32 *addr, u64 offset, int na) | ||
| 355 | { | ||
| 356 | return of_bus_default_translate(addr + 1, offset, na - 1); | ||
| 357 | } | ||
| 358 | |||
| 359 | static unsigned int of_bus_isa_get_flags(const u32 *addr) | ||
| 360 | { | ||
| 361 | unsigned int flags = 0; | ||
| 362 | u32 w = addr[0]; | ||
| 363 | |||
| 364 | if (w & 1) | ||
| 365 | flags |= IORESOURCE_IO; | ||
| 366 | else | ||
| 367 | flags |= IORESOURCE_MEM; | ||
| 368 | return flags; | ||
| 369 | } | ||
| 370 | |||
| 371 | |||
| 372 | /* | ||
| 373 | * Array of bus specific translators | ||
| 374 | */ | ||
| 375 | |||
| 376 | static struct of_bus of_busses[] = { | ||
| 377 | #ifdef CONFIG_PCI | ||
| 378 | /* PCI */ | ||
| 379 | { | ||
| 380 | .name = "pci", | ||
| 381 | .addresses = "assigned-addresses", | ||
| 382 | .match = of_bus_pci_match, | ||
| 383 | .count_cells = of_bus_pci_count_cells, | ||
| 384 | .map = of_bus_pci_map, | ||
| 385 | .translate = of_bus_pci_translate, | ||
| 386 | .get_flags = of_bus_pci_get_flags, | ||
| 387 | }, | ||
| 388 | #endif /* CONFIG_PCI */ | ||
| 389 | /* ISA */ | ||
| 390 | { | ||
| 391 | .name = "isa", | ||
| 392 | .addresses = "reg", | ||
| 393 | .match = of_bus_isa_match, | ||
| 394 | .count_cells = of_bus_isa_count_cells, | ||
| 395 | .map = of_bus_isa_map, | ||
| 396 | .translate = of_bus_isa_translate, | ||
| 397 | .get_flags = of_bus_isa_get_flags, | ||
| 398 | }, | ||
| 399 | /* Default */ | ||
| 400 | { | ||
| 401 | .name = "default", | ||
| 402 | .addresses = "reg", | ||
| 403 | .match = NULL, | ||
| 404 | .count_cells = of_bus_default_count_cells, | ||
| 405 | .map = of_bus_default_map, | ||
| 406 | .translate = of_bus_default_translate, | ||
| 407 | .get_flags = of_bus_default_get_flags, | ||
| 408 | }, | ||
| 409 | }; | ||
| 410 | |||
| 411 | static struct of_bus *of_match_bus(struct device_node *np) | ||
| 412 | { | ||
| 413 | int i; | ||
| 414 | |||
| 415 | for (i = 0; i < ARRAY_SIZE(of_busses); i ++) | ||
| 416 | if (!of_busses[i].match || of_busses[i].match(np)) | ||
| 417 | return &of_busses[i]; | ||
| 418 | BUG(); | ||
| 419 | return NULL; | ||
| 420 | } | ||
| 421 | |||
| 422 | static int of_translate_one(struct device_node *parent, struct of_bus *bus, | ||
| 423 | struct of_bus *pbus, u32 *addr, | ||
| 424 | int na, int ns, int pna, const char *rprop) | ||
| 425 | { | ||
| 426 | const u32 *ranges; | ||
| 427 | unsigned int rlen; | ||
| 428 | int rone; | ||
| 429 | u64 offset = OF_BAD_ADDR; | ||
| 430 | |||
| 431 | /* Normally, an absence of a "ranges" property means we are | ||
| 432 | * crossing a non-translatable boundary, and thus the addresses | ||
| 433 | * below the current not cannot be converted to CPU physical ones. | ||
| 434 | * Unfortunately, while this is very clear in the spec, it's not | ||
| 435 | * what Apple understood, and they do have things like /uni-n or | ||
| 436 | * /ht nodes with no "ranges" property and a lot of perfectly | ||
| 437 | * useable mapped devices below them. Thus we treat the absence of | ||
| 438 | * "ranges" as equivalent to an empty "ranges" property which means | ||
| 439 | * a 1:1 translation at that level. It's up to the caller not to try | ||
| 440 | * to translate addresses that aren't supposed to be translated in | ||
| 441 | * the first place. --BenH. | ||
| 442 | */ | ||
| 443 | ranges = of_get_property(parent, rprop, &rlen); | ||
| 444 | if (ranges == NULL || rlen == 0) { | ||
| 445 | offset = of_read_number(addr, na); | ||
| 446 | memset(addr, 0, pna * 4); | ||
| 447 | DBG("OF: no ranges, 1:1 translation\n"); | ||
| 448 | goto finish; | ||
| 449 | } | ||
| 450 | |||
| 451 | DBG("OF: walking ranges...\n"); | ||
| 452 | |||
| 453 | /* Now walk through the ranges */ | ||
| 454 | rlen /= 4; | ||
| 455 | rone = na + pna + ns; | ||
| 456 | for (; rlen >= rone; rlen -= rone, ranges += rone) { | ||
| 457 | offset = bus->map(addr, ranges, na, ns, pna); | ||
| 458 | if (offset != OF_BAD_ADDR) | ||
| 459 | break; | ||
| 460 | } | ||
| 461 | if (offset == OF_BAD_ADDR) { | ||
| 462 | DBG("OF: not found !\n"); | ||
| 463 | return 1; | ||
| 464 | } | ||
| 465 | memcpy(addr, ranges + na, 4 * pna); | ||
| 466 | |||
| 467 | finish: | ||
| 468 | of_dump_addr("OF: parent translation for:", addr, pna); | ||
| 469 | DBG("OF: with offset: "PRu64"\n", offset); | ||
| 470 | |||
| 471 | /* Translate it into parent bus space */ | ||
| 472 | return pbus->translate(addr, offset, pna); | ||
| 473 | } | ||
| 474 | |||
| 475 | |||
| 476 | /* | ||
| 477 | * Translate an address from the device-tree into a CPU physical address, | ||
| 478 | * this walks up the tree and applies the various bus mappings on the | ||
| 479 | * way. | ||
| 480 | * | ||
| 481 | * Note: We consider that crossing any level with #size-cells == 0 to mean | ||
| 482 | * that translation is impossible (that is we are not dealing with a value | ||
| 483 | * that can be mapped to a cpu physical address). This is not really specified | ||
| 484 | * that way, but this is traditionally the way IBM at least do things | ||
| 485 | */ | ||
| 486 | u64 __of_translate_address(struct device_node *dev, const u32 *in_addr, | ||
| 487 | const char *rprop) | ||
| 488 | { | ||
| 489 | struct device_node *parent = NULL; | ||
| 490 | struct of_bus *bus, *pbus; | ||
| 491 | u32 addr[OF_MAX_ADDR_CELLS]; | ||
| 492 | int na, ns, pna, pns; | ||
| 493 | u64 result = OF_BAD_ADDR; | ||
| 494 | |||
| 495 | DBG("OF: ** translation for device %s **\n", dev->full_name); | ||
| 496 | |||
| 497 | /* Increase refcount at current level */ | ||
| 498 | of_node_get(dev); | ||
| 499 | |||
| 500 | /* Get parent & match bus type */ | ||
| 501 | parent = of_get_parent(dev); | ||
| 502 | if (parent == NULL) | ||
| 503 | goto bail; | ||
| 504 | bus = of_match_bus(parent); | ||
| 505 | |||
| 506 | /* Cound address cells & copy address locally */ | ||
| 507 | bus->count_cells(dev, &na, &ns); | ||
| 508 | if (!OF_CHECK_COUNTS(na, ns)) { | ||
| 509 | printk(KERN_ERR "prom_parse: Bad cell count for %s\n", | ||
| 510 | dev->full_name); | ||
| 511 | goto bail; | ||
| 512 | } | ||
| 513 | memcpy(addr, in_addr, na * 4); | ||
| 514 | |||
| 515 | DBG("OF: bus is %s (na=%d, ns=%d) on %s\n", | ||
| 516 | bus->name, na, ns, parent->full_name); | ||
| 517 | of_dump_addr("OF: translating address:", addr, na); | ||
| 518 | |||
| 519 | /* Translate */ | ||
| 520 | for (;;) { | ||
| 521 | /* Switch to parent bus */ | ||
| 522 | of_node_put(dev); | ||
| 523 | dev = parent; | ||
| 524 | parent = of_get_parent(dev); | ||
| 525 | |||
| 526 | /* If root, we have finished */ | ||
| 527 | if (parent == NULL) { | ||
| 528 | DBG("OF: reached root node\n"); | ||
| 529 | result = of_read_number(addr, na); | ||
| 530 | break; | ||
| 531 | } | ||
| 532 | |||
| 533 | /* Get new parent bus and counts */ | ||
| 534 | pbus = of_match_bus(parent); | ||
| 535 | pbus->count_cells(dev, &pna, &pns); | ||
| 536 | if (!OF_CHECK_COUNTS(pna, pns)) { | ||
| 537 | printk(KERN_ERR "prom_parse: Bad cell count for %s\n", | ||
| 538 | dev->full_name); | ||
| 539 | break; | ||
| 540 | } | ||
| 541 | |||
| 542 | DBG("OF: parent bus is %s (na=%d, ns=%d) on %s\n", | ||
| 543 | pbus->name, pna, pns, parent->full_name); | ||
| 544 | |||
| 545 | /* Apply bus translation */ | ||
| 546 | if (of_translate_one(dev, bus, pbus, addr, na, ns, pna, rprop)) | ||
| 547 | break; | ||
| 548 | |||
| 549 | /* Complete the move up one level */ | ||
| 550 | na = pna; | ||
| 551 | ns = pns; | ||
| 552 | bus = pbus; | ||
| 553 | |||
| 554 | of_dump_addr("OF: one level translation:", addr, na); | ||
| 555 | } | ||
| 556 | bail: | ||
| 557 | of_node_put(parent); | ||
| 558 | of_node_put(dev); | ||
| 559 | |||
| 560 | return result; | ||
| 561 | } | ||
| 562 | |||
| 563 | u64 of_translate_address(struct device_node *dev, const u32 *in_addr) | ||
| 564 | { | ||
| 565 | return __of_translate_address(dev, in_addr, "ranges"); | ||
| 566 | } | ||
| 567 | EXPORT_SYMBOL(of_translate_address); | ||
| 568 | |||
| 569 | u64 of_translate_dma_address(struct device_node *dev, const u32 *in_addr) | ||
| 570 | { | ||
| 571 | return __of_translate_address(dev, in_addr, "dma-ranges"); | ||
| 572 | } | ||
| 573 | EXPORT_SYMBOL(of_translate_dma_address); | ||
| 574 | |||
| 575 | const u32 *of_get_address(struct device_node *dev, int index, u64 *size, | ||
| 576 | unsigned int *flags) | ||
| 577 | { | ||
| 578 | const u32 *prop; | ||
| 579 | unsigned int psize; | ||
| 580 | struct device_node *parent; | ||
| 581 | struct of_bus *bus; | ||
| 582 | int onesize, i, na, ns; | ||
| 583 | |||
| 584 | /* Get parent & match bus type */ | ||
| 585 | parent = of_get_parent(dev); | ||
| 586 | if (parent == NULL) | ||
| 587 | return NULL; | ||
| 588 | bus = of_match_bus(parent); | ||
| 589 | bus->count_cells(dev, &na, &ns); | ||
| 590 | of_node_put(parent); | ||
| 591 | if (!OF_CHECK_COUNTS(na, ns)) | ||
| 592 | return NULL; | ||
| 593 | |||
| 594 | /* Get "reg" or "assigned-addresses" property */ | ||
| 595 | prop = of_get_property(dev, bus->addresses, &psize); | ||
| 596 | if (prop == NULL) | ||
| 597 | return NULL; | ||
| 598 | psize /= 4; | ||
| 599 | |||
| 600 | onesize = na + ns; | ||
| 601 | for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++) | ||
| 602 | if (i == index) { | ||
| 603 | if (size) | ||
| 604 | *size = of_read_number(prop + na, ns); | ||
| 605 | if (flags) | ||
| 606 | *flags = bus->get_flags(prop); | ||
| 607 | return prop; | ||
| 608 | } | ||
| 609 | return NULL; | ||
| 610 | } | ||
| 611 | EXPORT_SYMBOL(of_get_address); | ||
| 612 | |||
| 613 | static int __of_address_to_resource(struct device_node *dev, const u32 *addrp, | ||
| 614 | u64 size, unsigned int flags, | ||
| 615 | struct resource *r) | ||
| 616 | { | ||
| 617 | u64 taddr; | ||
| 618 | |||
| 619 | if ((flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0) | ||
| 620 | return -EINVAL; | ||
| 621 | taddr = of_translate_address(dev, addrp); | ||
| 622 | if (taddr == OF_BAD_ADDR) | ||
| 623 | return -EINVAL; | ||
| 624 | memset(r, 0, sizeof(struct resource)); | ||
| 625 | if (flags & IORESOURCE_IO) { | ||
| 626 | unsigned long port; | ||
| 627 | port = pci_address_to_pio(taddr); | ||
| 628 | if (port == (unsigned long)-1) | ||
| 629 | return -EINVAL; | ||
| 630 | r->start = port; | ||
| 631 | r->end = port + size - 1; | ||
| 632 | } else { | ||
| 633 | r->start = taddr; | ||
| 634 | r->end = taddr + size - 1; | ||
| 635 | } | ||
| 636 | r->flags = flags; | ||
| 637 | r->name = dev->name; | ||
| 638 | return 0; | ||
| 639 | } | ||
| 640 | |||
| 641 | int of_address_to_resource(struct device_node *dev, int index, | ||
| 642 | struct resource *r) | ||
| 643 | { | ||
| 644 | const u32 *addrp; | ||
| 645 | u64 size; | ||
| 646 | unsigned int flags; | ||
| 647 | |||
| 648 | addrp = of_get_address(dev, index, &size, &flags); | ||
| 649 | if (addrp == NULL) | ||
| 650 | return -EINVAL; | ||
| 651 | return __of_address_to_resource(dev, addrp, size, flags, r); | ||
| 652 | } | ||
| 653 | EXPORT_SYMBOL_GPL(of_address_to_resource); | ||
| 654 | |||
| 655 | void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, | 95 | void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, |
| 656 | unsigned long *busno, unsigned long *phys, unsigned long *size) | 96 | unsigned long *busno, unsigned long *phys, unsigned long *size) |
| 657 | { | 97 | { |
| @@ -678,342 +118,6 @@ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, | |||
| 678 | *size = of_read_number(dma_window, cells); | 118 | *size = of_read_number(dma_window, cells); |
| 679 | } | 119 | } |
| 680 | 120 | ||
| 681 | /* | ||
| 682 | * Interrupt remapper | ||
| 683 | */ | ||
| 684 | |||
| 685 | static unsigned int of_irq_workarounds; | ||
| 686 | static struct device_node *of_irq_dflt_pic; | ||
| 687 | |||
| 688 | static struct device_node *of_irq_find_parent(struct device_node *child) | ||
| 689 | { | ||
| 690 | struct device_node *p; | ||
| 691 | const phandle *parp; | ||
| 692 | |||
| 693 | if (!of_node_get(child)) | ||
| 694 | return NULL; | ||
| 695 | |||
| 696 | do { | ||
| 697 | parp = of_get_property(child, "interrupt-parent", NULL); | ||
| 698 | if (parp == NULL) | ||
| 699 | p = of_get_parent(child); | ||
| 700 | else { | ||
| 701 | if (of_irq_workarounds & OF_IMAP_NO_PHANDLE) | ||
| 702 | p = of_node_get(of_irq_dflt_pic); | ||
| 703 | else | ||
| 704 | p = of_find_node_by_phandle(*parp); | ||
| 705 | } | ||
| 706 | of_node_put(child); | ||
| 707 | child = p; | ||
| 708 | } while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL); | ||
| 709 | |||
| 710 | return p; | ||
| 711 | } | ||
| 712 | |||
| 713 | /* This doesn't need to be called if you don't have any special workaround | ||
| 714 | * flags to pass | ||
| 715 | */ | ||
| 716 | void of_irq_map_init(unsigned int flags) | ||
| 717 | { | ||
| 718 | of_irq_workarounds = flags; | ||
| 719 | |||
| 720 | /* OldWorld, don't bother looking at other things */ | ||
| 721 | if (flags & OF_IMAP_OLDWORLD_MAC) | ||
| 722 | return; | ||
| 723 | |||
| 724 | /* If we don't have phandles, let's try to locate a default interrupt | ||
| 725 | * controller (happens when booting with BootX). We do a first match | ||
| 726 | * here, hopefully, that only ever happens on machines with one | ||
| 727 | * controller. | ||
| 728 | */ | ||
| 729 | if (flags & OF_IMAP_NO_PHANDLE) { | ||
| 730 | struct device_node *np; | ||
| 731 | |||
| 732 | for_each_node_with_property(np, "interrupt-controller") { | ||
| 733 | /* Skip /chosen/interrupt-controller */ | ||
| 734 | if (strcmp(np->name, "chosen") == 0) | ||
| 735 | continue; | ||
| 736 | /* It seems like at least one person on this planet wants | ||
| 737 | * to use BootX on a machine with an AppleKiwi controller | ||
| 738 | * which happens to pretend to be an interrupt | ||
| 739 | * controller too. | ||
| 740 | */ | ||
| 741 | if (strcmp(np->name, "AppleKiwi") == 0) | ||
| 742 | continue; | ||
| 743 | /* I think we found one ! */ | ||
| 744 | of_irq_dflt_pic = np; | ||
| 745 | break; | ||
| 746 | } | ||
| 747 | } | ||
| 748 | |||
| 749 | } | ||
| 750 | |||
| 751 | int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize, | ||
| 752 | const u32 *addr, struct of_irq *out_irq) | ||
| 753 | { | ||
| 754 | struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL; | ||
| 755 | const u32 *tmp, *imap, *imask; | ||
| 756 | u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0; | ||
| 757 | int imaplen, match, i; | ||
| 758 | |||
| 759 | DBG("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...],ointsize=%d\n", | ||
| 760 | parent->full_name, intspec[0], intspec[1], ointsize); | ||
| 761 | |||
| 762 | ipar = of_node_get(parent); | ||
| 763 | |||
| 764 | /* First get the #interrupt-cells property of the current cursor | ||
| 765 | * that tells us how to interpret the passed-in intspec. If there | ||
| 766 | * is none, we are nice and just walk up the tree | ||
| 767 | */ | ||
| 768 | do { | ||
| 769 | tmp = of_get_property(ipar, "#interrupt-cells", NULL); | ||
| 770 | if (tmp != NULL) { | ||
| 771 | intsize = *tmp; | ||
| 772 | break; | ||
| 773 | } | ||
| 774 | tnode = ipar; | ||
| 775 | ipar = of_irq_find_parent(ipar); | ||
| 776 | of_node_put(tnode); | ||
| 777 | } while (ipar); | ||
| 778 | if (ipar == NULL) { | ||
| 779 | DBG(" -> no parent found !\n"); | ||
| 780 | goto fail; | ||
| 781 | } | ||
| 782 | |||
| 783 | DBG("of_irq_map_raw: ipar=%s, size=%d\n", ipar->full_name, intsize); | ||
| 784 | |||
| 785 | if (ointsize != intsize) | ||
| 786 | return -EINVAL; | ||
| 787 | |||
| 788 | /* Look for this #address-cells. We have to implement the old linux | ||
| 789 | * trick of looking for the parent here as some device-trees rely on it | ||
| 790 | */ | ||
| 791 | old = of_node_get(ipar); | ||
| 792 | do { | ||
| 793 | tmp = of_get_property(old, "#address-cells", NULL); | ||
| 794 | tnode = of_get_parent(old); | ||
| 795 | of_node_put(old); | ||
| 796 | old = tnode; | ||
| 797 | } while(old && tmp == NULL); | ||
| 798 | of_node_put(old); | ||
| 799 | old = NULL; | ||
| 800 | addrsize = (tmp == NULL) ? 2 : *tmp; | ||
| 801 | |||
| 802 | DBG(" -> addrsize=%d\n", addrsize); | ||
| 803 | |||
| 804 | /* Now start the actual "proper" walk of the interrupt tree */ | ||
| 805 | while (ipar != NULL) { | ||
| 806 | /* Now check if cursor is an interrupt-controller and if it is | ||
| 807 | * then we are done | ||
| 808 | */ | ||
| 809 | if (of_get_property(ipar, "interrupt-controller", NULL) != | ||
| 810 | NULL) { | ||
| 811 | DBG(" -> got it !\n"); | ||
| 812 | memcpy(out_irq->specifier, intspec, | ||
| 813 | intsize * sizeof(u32)); | ||
| 814 | out_irq->size = intsize; | ||
| 815 | out_irq->controller = ipar; | ||
| 816 | of_node_put(old); | ||
| 817 | return 0; | ||
| 818 | } | ||
| 819 | |||
| 820 | /* Now look for an interrupt-map */ | ||
| 821 | imap = of_get_property(ipar, "interrupt-map", &imaplen); | ||
| 822 | /* No interrupt map, check for an interrupt parent */ | ||
| 823 | if (imap == NULL) { | ||
| 824 | DBG(" -> no map, getting parent\n"); | ||
| 825 | newpar = of_irq_find_parent(ipar); | ||
| 826 | goto skiplevel; | ||
| 827 | } | ||
| 828 | imaplen /= sizeof(u32); | ||
| 829 | |||
| 830 | /* Look for a mask */ | ||
| 831 | imask = of_get_property(ipar, "interrupt-map-mask", NULL); | ||
| 832 | |||
| 833 | /* If we were passed no "reg" property and we attempt to parse | ||
| 834 | * an interrupt-map, then #address-cells must be 0. | ||
| 835 | * Fail if it's not. | ||
| 836 | */ | ||
| 837 | if (addr == NULL && addrsize != 0) { | ||
| 838 | DBG(" -> no reg passed in when needed !\n"); | ||
| 839 | goto fail; | ||
| 840 | } | ||
| 841 | |||
| 842 | /* Parse interrupt-map */ | ||
| 843 | match = 0; | ||
| 844 | while (imaplen > (addrsize + intsize + 1) && !match) { | ||
| 845 | /* Compare specifiers */ | ||
| 846 | match = 1; | ||
| 847 | for (i = 0; i < addrsize && match; ++i) { | ||
| 848 | u32 mask = imask ? imask[i] : 0xffffffffu; | ||
| 849 | match = ((addr[i] ^ imap[i]) & mask) == 0; | ||
| 850 | } | ||
| 851 | for (; i < (addrsize + intsize) && match; ++i) { | ||
| 852 | u32 mask = imask ? imask[i] : 0xffffffffu; | ||
| 853 | match = | ||
| 854 | ((intspec[i-addrsize] ^ imap[i]) & mask) == 0; | ||
| 855 | } | ||
| 856 | imap += addrsize + intsize; | ||
| 857 | imaplen -= addrsize + intsize; | ||
| 858 | |||
| 859 | DBG(" -> match=%d (imaplen=%d)\n", match, imaplen); | ||
| 860 | |||
| 861 | /* Get the interrupt parent */ | ||
| 862 | if (of_irq_workarounds & OF_IMAP_NO_PHANDLE) | ||
| 863 | newpar = of_node_get(of_irq_dflt_pic); | ||
| 864 | else | ||
| 865 | newpar = of_find_node_by_phandle((phandle)*imap); | ||
| 866 | imap++; | ||
| 867 | --imaplen; | ||
| 868 | |||
| 869 | /* Check if not found */ | ||
| 870 | if (newpar == NULL) { | ||
| 871 | DBG(" -> imap parent not found !\n"); | ||
| 872 | goto fail; | ||
| 873 | } | ||
| 874 | |||
| 875 | /* Get #interrupt-cells and #address-cells of new | ||
| 876 | * parent | ||
| 877 | */ | ||
| 878 | tmp = of_get_property(newpar, "#interrupt-cells", NULL); | ||
| 879 | if (tmp == NULL) { | ||
| 880 | DBG(" -> parent lacks #interrupt-cells !\n"); | ||
| 881 | goto fail; | ||
| 882 | } | ||
| 883 | newintsize = *tmp; | ||
| 884 | tmp = of_get_property(newpar, "#address-cells", NULL); | ||
| 885 | newaddrsize = (tmp == NULL) ? 0 : *tmp; | ||
| 886 | |||
| 887 | DBG(" -> newintsize=%d, newaddrsize=%d\n", | ||
| 888 | newintsize, newaddrsize); | ||
| 889 | |||
| 890 | /* Check for malformed properties */ | ||
| 891 | if (imaplen < (newaddrsize + newintsize)) | ||
| 892 | goto fail; | ||
| 893 | |||
| 894 | imap += newaddrsize + newintsize; | ||
| 895 | imaplen -= newaddrsize + newintsize; | ||
| 896 | |||
| 897 | DBG(" -> imaplen=%d\n", imaplen); | ||
| 898 | } | ||
| 899 | if (!match) | ||
| 900 | goto fail; | ||
| 901 | |||
| 902 | of_node_put(old); | ||
| 903 | old = of_node_get(newpar); | ||
| 904 | addrsize = newaddrsize; | ||
| 905 | intsize = newintsize; | ||
| 906 | intspec = imap - intsize; | ||
| 907 | addr = intspec - addrsize; | ||
| 908 | |||
| 909 | skiplevel: | ||
| 910 | /* Iterate again with new parent */ | ||
| 911 | DBG(" -> new parent: %s\n", newpar ? newpar->full_name : "<>"); | ||
| 912 | of_node_put(ipar); | ||
| 913 | ipar = newpar; | ||
| 914 | newpar = NULL; | ||
| 915 | } | ||
| 916 | fail: | ||
| 917 | of_node_put(ipar); | ||
| 918 | of_node_put(old); | ||
| 919 | of_node_put(newpar); | ||
| 920 | |||
| 921 | return -EINVAL; | ||
| 922 | } | ||
| 923 | EXPORT_SYMBOL_GPL(of_irq_map_raw); | ||
| 924 | |||
| 925 | #if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32) | ||
| 926 | static int of_irq_map_oldworld(struct device_node *device, int index, | ||
| 927 | struct of_irq *out_irq) | ||
| 928 | { | ||
| 929 | const u32 *ints = NULL; | ||
| 930 | int intlen; | ||
| 931 | |||
| 932 | /* | ||
| 933 | * Old machines just have a list of interrupt numbers | ||
| 934 | * and no interrupt-controller nodes. We also have dodgy | ||
| 935 | * cases where the APPL,interrupts property is completely | ||
| 936 | * missing behind pci-pci bridges and we have to get it | ||
| 937 | * from the parent (the bridge itself, as apple just wired | ||
| 938 | * everything together on these) | ||
| 939 | */ | ||
| 940 | while (device) { | ||
| 941 | ints = of_get_property(device, "AAPL,interrupts", &intlen); | ||
| 942 | if (ints != NULL) | ||
| 943 | break; | ||
| 944 | device = device->parent; | ||
| 945 | if (device && strcmp(device->type, "pci") != 0) | ||
| 946 | break; | ||
| 947 | } | ||
| 948 | if (ints == NULL) | ||
| 949 | return -EINVAL; | ||
| 950 | intlen /= sizeof(u32); | ||
| 951 | |||
| 952 | if (index >= intlen) | ||
| 953 | return -EINVAL; | ||
| 954 | |||
| 955 | out_irq->controller = NULL; | ||
| 956 | out_irq->specifier[0] = ints[index]; | ||
| 957 | out_irq->size = 1; | ||
| 958 | |||
| 959 | return 0; | ||
| 960 | } | ||
| 961 | #else /* defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32) */ | ||
| 962 | static int of_irq_map_oldworld(struct device_node *device, int index, | ||
| 963 | struct of_irq *out_irq) | ||
| 964 | { | ||
| 965 | return -EINVAL; | ||
| 966 | } | ||
| 967 | #endif /* !(defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32)) */ | ||
| 968 | |||
| 969 | int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq) | ||
| 970 | { | ||
| 971 | struct device_node *p; | ||
| 972 | const u32 *intspec, *tmp, *addr; | ||
| 973 | u32 intsize, intlen; | ||
| 974 | int res = -EINVAL; | ||
| 975 | |||
| 976 | DBG("of_irq_map_one: dev=%s, index=%d\n", device->full_name, index); | ||
| 977 | |||
| 978 | /* OldWorld mac stuff is "special", handle out of line */ | ||
| 979 | if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC) | ||
| 980 | return of_irq_map_oldworld(device, index, out_irq); | ||
| 981 | |||
| 982 | /* Get the interrupts property */ | ||
| 983 | intspec = of_get_property(device, "interrupts", &intlen); | ||
| 984 | if (intspec == NULL) | ||
| 985 | return -EINVAL; | ||
| 986 | intlen /= sizeof(u32); | ||
| 987 | |||
| 988 | /* Get the reg property (if any) */ | ||
| 989 | addr = of_get_property(device, "reg", NULL); | ||
| 990 | |||
| 991 | /* Look for the interrupt parent. */ | ||
| 992 | p = of_irq_find_parent(device); | ||
| 993 | if (p == NULL) | ||
| 994 | return -EINVAL; | ||
| 995 | |||
| 996 | /* Get size of interrupt specifier */ | ||
| 997 | tmp = of_get_property(p, "#interrupt-cells", NULL); | ||
| 998 | if (tmp == NULL) | ||
| 999 | goto out; | ||
| 1000 | intsize = *tmp; | ||
| 1001 | |||
| 1002 | DBG(" intsize=%d intlen=%d\n", intsize, intlen); | ||
| 1003 | |||
| 1004 | /* Check index */ | ||
| 1005 | if ((index + 1) * intsize > intlen) | ||
| 1006 | goto out; | ||
| 1007 | |||
| 1008 | /* Get new specifier and map it */ | ||
| 1009 | res = of_irq_map_raw(p, intspec + index * intsize, intsize, | ||
| 1010 | addr, out_irq); | ||
| 1011 | out: | ||
| 1012 | of_node_put(p); | ||
| 1013 | return res; | ||
| 1014 | } | ||
| 1015 | EXPORT_SYMBOL_GPL(of_irq_map_one); | ||
| 1016 | |||
| 1017 | /** | 121 | /** |
| 1018 | * Search the device tree for the best MAC address to use. 'mac-address' is | 122 | * Search the device tree for the best MAC address to use. 'mac-address' is |
| 1019 | * checked first, because that is supposed to contain to "most recent" MAC | 123 | * checked first, because that is supposed to contain to "most recent" MAC |
| @@ -1051,29 +155,3 @@ const void *of_get_mac_address(struct device_node *np) | |||
| 1051 | return NULL; | 155 | return NULL; |
| 1052 | } | 156 | } |
| 1053 | EXPORT_SYMBOL(of_get_mac_address); | 157 | EXPORT_SYMBOL(of_get_mac_address); |
| 1054 | |||
| 1055 | int of_irq_to_resource(struct device_node *dev, int index, struct resource *r) | ||
| 1056 | { | ||
| 1057 | int irq = irq_of_parse_and_map(dev, index); | ||
| 1058 | |||
| 1059 | /* Only dereference the resource if both the | ||
| 1060 | * resource and the irq are valid. */ | ||
| 1061 | if (r && irq != NO_IRQ) { | ||
| 1062 | r->start = r->end = irq; | ||
| 1063 | r->flags = IORESOURCE_IRQ; | ||
| 1064 | } | ||
| 1065 | |||
| 1066 | return irq; | ||
| 1067 | } | ||
| 1068 | EXPORT_SYMBOL_GPL(of_irq_to_resource); | ||
| 1069 | |||
| 1070 | void __iomem *of_iomap(struct device_node *np, int index) | ||
| 1071 | { | ||
| 1072 | struct resource res; | ||
| 1073 | |||
| 1074 | if (of_address_to_resource(np, index, &res)) | ||
| 1075 | return NULL; | ||
| 1076 | |||
| 1077 | return ioremap(res.start, 1 + res.end - res.start); | ||
| 1078 | } | ||
| 1079 | EXPORT_SYMBOL(of_iomap); | ||
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index 7a0c0199ea28..11f3cd9c832f 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c | |||
| @@ -32,6 +32,8 @@ | |||
| 32 | #ifdef CONFIG_PPC32 | 32 | #ifdef CONFIG_PPC32 |
| 33 | #include <linux/module.h> | 33 | #include <linux/module.h> |
| 34 | #endif | 34 | #endif |
| 35 | #include <linux/hw_breakpoint.h> | ||
| 36 | #include <linux/perf_event.h> | ||
| 35 | 37 | ||
| 36 | #include <asm/uaccess.h> | 38 | #include <asm/uaccess.h> |
| 37 | #include <asm/page.h> | 39 | #include <asm/page.h> |
| @@ -866,9 +868,34 @@ void user_disable_single_step(struct task_struct *task) | |||
| 866 | clear_tsk_thread_flag(task, TIF_SINGLESTEP); | 868 | clear_tsk_thread_flag(task, TIF_SINGLESTEP); |
| 867 | } | 869 | } |
| 868 | 870 | ||
| 871 | #ifdef CONFIG_HAVE_HW_BREAKPOINT | ||
| 872 | void ptrace_triggered(struct perf_event *bp, int nmi, | ||
| 873 | struct perf_sample_data *data, struct pt_regs *regs) | ||
| 874 | { | ||
| 875 | struct perf_event_attr attr; | ||
| 876 | |||
| 877 | /* | ||
| 878 | * Disable the breakpoint request here since ptrace has defined a | ||
| 879 | * one-shot behaviour for breakpoint exceptions in PPC64. | ||
| 880 | * The SIGTRAP signal is generated automatically for us in do_dabr(). | ||
| 881 | * We don't have to do anything about that here | ||
| 882 | */ | ||
| 883 | attr = bp->attr; | ||
| 884 | attr.disabled = true; | ||
| 885 | modify_user_hw_breakpoint(bp, &attr); | ||
| 886 | } | ||
| 887 | #endif /* CONFIG_HAVE_HW_BREAKPOINT */ | ||
| 888 | |||
| 869 | int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, | 889 | int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, |
| 870 | unsigned long data) | 890 | unsigned long data) |
| 871 | { | 891 | { |
| 892 | #ifdef CONFIG_HAVE_HW_BREAKPOINT | ||
| 893 | int ret; | ||
| 894 | struct thread_struct *thread = &(task->thread); | ||
| 895 | struct perf_event *bp; | ||
| 896 | struct perf_event_attr attr; | ||
| 897 | #endif /* CONFIG_HAVE_HW_BREAKPOINT */ | ||
| 898 | |||
| 872 | /* For ppc64 we support one DABR and no IABR's at the moment (ppc64). | 899 | /* For ppc64 we support one DABR and no IABR's at the moment (ppc64). |
| 873 | * For embedded processors we support one DAC and no IAC's at the | 900 | * For embedded processors we support one DAC and no IAC's at the |
| 874 | * moment. | 901 | * moment. |
| @@ -896,6 +923,43 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, | |||
| 896 | /* Ensure breakpoint translation bit is set */ | 923 | /* Ensure breakpoint translation bit is set */ |
| 897 | if (data && !(data & DABR_TRANSLATION)) | 924 | if (data && !(data & DABR_TRANSLATION)) |
| 898 | return -EIO; | 925 | return -EIO; |
| 926 | #ifdef CONFIG_HAVE_HW_BREAKPOINT | ||
| 927 | bp = thread->ptrace_bps[0]; | ||
| 928 | if ((!data) || !(data & (DABR_DATA_WRITE | DABR_DATA_READ))) { | ||
| 929 | if (bp) { | ||
| 930 | unregister_hw_breakpoint(bp); | ||
| 931 | thread->ptrace_bps[0] = NULL; | ||
| 932 | } | ||
| 933 | return 0; | ||
| 934 | } | ||
| 935 | if (bp) { | ||
| 936 | attr = bp->attr; | ||
| 937 | attr.bp_addr = data & ~HW_BREAKPOINT_ALIGN; | ||
| 938 | arch_bp_generic_fields(data & | ||
| 939 | (DABR_DATA_WRITE | DABR_DATA_READ), | ||
| 940 | &attr.bp_type); | ||
| 941 | ret = modify_user_hw_breakpoint(bp, &attr); | ||
| 942 | if (ret) | ||
| 943 | return ret; | ||
| 944 | thread->ptrace_bps[0] = bp; | ||
| 945 | thread->dabr = data; | ||
| 946 | return 0; | ||
| 947 | } | ||
| 948 | |||
| 949 | /* Create a new breakpoint request if one doesn't exist already */ | ||
| 950 | hw_breakpoint_init(&attr); | ||
| 951 | attr.bp_addr = data & ~HW_BREAKPOINT_ALIGN; | ||
| 952 | arch_bp_generic_fields(data & (DABR_DATA_WRITE | DABR_DATA_READ), | ||
| 953 | &attr.bp_type); | ||
| 954 | |||
| 955 | thread->ptrace_bps[0] = bp = register_user_hw_breakpoint(&attr, | ||
| 956 | ptrace_triggered, task); | ||
| 957 | if (IS_ERR(bp)) { | ||
| 958 | thread->ptrace_bps[0] = NULL; | ||
| 959 | return PTR_ERR(bp); | ||
| 960 | } | ||
| 961 | |||
| 962 | #endif /* CONFIG_HAVE_HW_BREAKPOINT */ | ||
| 899 | 963 | ||
| 900 | /* Move contents to the DABR register */ | 964 | /* Move contents to the DABR register */ |
| 901 | task->thread.dabr = data; | 965 | task->thread.dabr = data; |
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index d0516dbee762..41048de3c6c3 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c | |||
| @@ -47,14 +47,6 @@ struct rtas_t rtas = { | |||
| 47 | }; | 47 | }; |
| 48 | EXPORT_SYMBOL(rtas); | 48 | EXPORT_SYMBOL(rtas); |
| 49 | 49 | ||
| 50 | struct rtas_suspend_me_data { | ||
| 51 | atomic_t working; /* number of cpus accessing this struct */ | ||
| 52 | atomic_t done; | ||
| 53 | int token; /* ibm,suspend-me */ | ||
| 54 | int error; | ||
| 55 | struct completion *complete; /* wait on this until working == 0 */ | ||
| 56 | }; | ||
| 57 | |||
| 58 | DEFINE_SPINLOCK(rtas_data_buf_lock); | 50 | DEFINE_SPINLOCK(rtas_data_buf_lock); |
| 59 | EXPORT_SYMBOL(rtas_data_buf_lock); | 51 | EXPORT_SYMBOL(rtas_data_buf_lock); |
| 60 | 52 | ||
| @@ -714,14 +706,53 @@ void rtas_os_term(char *str) | |||
| 714 | 706 | ||
| 715 | static int ibm_suspend_me_token = RTAS_UNKNOWN_SERVICE; | 707 | static int ibm_suspend_me_token = RTAS_UNKNOWN_SERVICE; |
| 716 | #ifdef CONFIG_PPC_PSERIES | 708 | #ifdef CONFIG_PPC_PSERIES |
| 717 | static void rtas_percpu_suspend_me(void *info) | 709 | static int __rtas_suspend_last_cpu(struct rtas_suspend_me_data *data, int wake_when_done) |
| 710 | { | ||
| 711 | u16 slb_size = mmu_slb_size; | ||
| 712 | int rc = H_MULTI_THREADS_ACTIVE; | ||
| 713 | int cpu; | ||
| 714 | |||
| 715 | slb_set_size(SLB_MIN_SIZE); | ||
| 716 | printk(KERN_DEBUG "calling ibm,suspend-me on cpu %i\n", smp_processor_id()); | ||
| 717 | |||
| 718 | while (rc == H_MULTI_THREADS_ACTIVE && !atomic_read(&data->done) && | ||
| 719 | !atomic_read(&data->error)) | ||
| 720 | rc = rtas_call(data->token, 0, 1, NULL); | ||
| 721 | |||
| 722 | if (rc || atomic_read(&data->error)) { | ||
| 723 | printk(KERN_DEBUG "ibm,suspend-me returned %d\n", rc); | ||
| 724 | slb_set_size(slb_size); | ||
| 725 | } | ||
| 726 | |||
| 727 | if (atomic_read(&data->error)) | ||
| 728 | rc = atomic_read(&data->error); | ||
| 729 | |||
| 730 | atomic_set(&data->error, rc); | ||
| 731 | |||
| 732 | if (wake_when_done) { | ||
| 733 | atomic_set(&data->done, 1); | ||
| 734 | |||
| 735 | for_each_online_cpu(cpu) | ||
| 736 | plpar_hcall_norets(H_PROD, get_hard_smp_processor_id(cpu)); | ||
| 737 | } | ||
| 738 | |||
| 739 | if (atomic_dec_return(&data->working) == 0) | ||
| 740 | complete(data->complete); | ||
| 741 | |||
| 742 | return rc; | ||
| 743 | } | ||
| 744 | |||
| 745 | int rtas_suspend_last_cpu(struct rtas_suspend_me_data *data) | ||
| 746 | { | ||
| 747 | atomic_inc(&data->working); | ||
| 748 | return __rtas_suspend_last_cpu(data, 0); | ||
| 749 | } | ||
| 750 | |||
| 751 | static int __rtas_suspend_cpu(struct rtas_suspend_me_data *data, int wake_when_done) | ||
| 718 | { | 752 | { |
| 719 | long rc = H_SUCCESS; | 753 | long rc = H_SUCCESS; |
| 720 | unsigned long msr_save; | 754 | unsigned long msr_save; |
| 721 | u16 slb_size = mmu_slb_size; | ||
| 722 | int cpu; | 755 | int cpu; |
| 723 | struct rtas_suspend_me_data *data = | ||
| 724 | (struct rtas_suspend_me_data *)info; | ||
| 725 | 756 | ||
| 726 | atomic_inc(&data->working); | 757 | atomic_inc(&data->working); |
| 727 | 758 | ||
| @@ -729,7 +760,7 @@ static void rtas_percpu_suspend_me(void *info) | |||
| 729 | msr_save = mfmsr(); | 760 | msr_save = mfmsr(); |
| 730 | mtmsr(msr_save & ~(MSR_EE)); | 761 | mtmsr(msr_save & ~(MSR_EE)); |
| 731 | 762 | ||
| 732 | while (rc == H_SUCCESS && !atomic_read(&data->done)) | 763 | while (rc == H_SUCCESS && !atomic_read(&data->done) && !atomic_read(&data->error)) |
| 733 | rc = plpar_hcall_norets(H_JOIN); | 764 | rc = plpar_hcall_norets(H_JOIN); |
| 734 | 765 | ||
| 735 | mtmsr(msr_save); | 766 | mtmsr(msr_save); |
| @@ -741,33 +772,37 @@ static void rtas_percpu_suspend_me(void *info) | |||
| 741 | /* All other cpus are in H_JOIN, this cpu does | 772 | /* All other cpus are in H_JOIN, this cpu does |
| 742 | * the suspend. | 773 | * the suspend. |
| 743 | */ | 774 | */ |
| 744 | slb_set_size(SLB_MIN_SIZE); | 775 | return __rtas_suspend_last_cpu(data, wake_when_done); |
| 745 | printk(KERN_DEBUG "calling ibm,suspend-me on cpu %i\n", | ||
| 746 | smp_processor_id()); | ||
| 747 | data->error = rtas_call(data->token, 0, 1, NULL); | ||
| 748 | |||
| 749 | if (data->error) { | ||
| 750 | printk(KERN_DEBUG "ibm,suspend-me returned %d\n", | ||
| 751 | data->error); | ||
| 752 | slb_set_size(slb_size); | ||
| 753 | } | ||
| 754 | } else { | 776 | } else { |
| 755 | printk(KERN_ERR "H_JOIN on cpu %i failed with rc = %ld\n", | 777 | printk(KERN_ERR "H_JOIN on cpu %i failed with rc = %ld\n", |
| 756 | smp_processor_id(), rc); | 778 | smp_processor_id(), rc); |
| 757 | data->error = rc; | 779 | atomic_set(&data->error, rc); |
| 758 | } | 780 | } |
| 759 | 781 | ||
| 760 | atomic_set(&data->done, 1); | 782 | if (wake_when_done) { |
| 783 | atomic_set(&data->done, 1); | ||
| 761 | 784 | ||
| 762 | /* This cpu did the suspend or got an error; in either case, | 785 | /* This cpu did the suspend or got an error; in either case, |
| 763 | * we need to prod all other other cpus out of join state. | 786 | * we need to prod all other other cpus out of join state. |
| 764 | * Extra prods are harmless. | 787 | * Extra prods are harmless. |
| 765 | */ | 788 | */ |
| 766 | for_each_online_cpu(cpu) | 789 | for_each_online_cpu(cpu) |
| 767 | plpar_hcall_norets(H_PROD, get_hard_smp_processor_id(cpu)); | 790 | plpar_hcall_norets(H_PROD, get_hard_smp_processor_id(cpu)); |
| 791 | } | ||
| 768 | out: | 792 | out: |
| 769 | if (atomic_dec_return(&data->working) == 0) | 793 | if (atomic_dec_return(&data->working) == 0) |
| 770 | complete(data->complete); | 794 | complete(data->complete); |
| 795 | return rc; | ||
| 796 | } | ||
| 797 | |||
| 798 | int rtas_suspend_cpu(struct rtas_suspend_me_data *data) | ||
| 799 | { | ||
| 800 | return __rtas_suspend_cpu(data, 0); | ||
| 801 | } | ||
| 802 | |||
| 803 | static void rtas_percpu_suspend_me(void *info) | ||
| 804 | { | ||
| 805 | __rtas_suspend_cpu((struct rtas_suspend_me_data *)info, 1); | ||
| 771 | } | 806 | } |
| 772 | 807 | ||
| 773 | static int rtas_ibm_suspend_me(struct rtas_args *args) | 808 | static int rtas_ibm_suspend_me(struct rtas_args *args) |
| @@ -802,22 +837,22 @@ static int rtas_ibm_suspend_me(struct rtas_args *args) | |||
| 802 | 837 | ||
| 803 | atomic_set(&data.working, 0); | 838 | atomic_set(&data.working, 0); |
| 804 | atomic_set(&data.done, 0); | 839 | atomic_set(&data.done, 0); |
| 840 | atomic_set(&data.error, 0); | ||
| 805 | data.token = rtas_token("ibm,suspend-me"); | 841 | data.token = rtas_token("ibm,suspend-me"); |
| 806 | data.error = 0; | ||
| 807 | data.complete = &done; | 842 | data.complete = &done; |
| 808 | 843 | ||
| 809 | /* Call function on all CPUs. One of us will make the | 844 | /* Call function on all CPUs. One of us will make the |
| 810 | * rtas call | 845 | * rtas call |
| 811 | */ | 846 | */ |
| 812 | if (on_each_cpu(rtas_percpu_suspend_me, &data, 0)) | 847 | if (on_each_cpu(rtas_percpu_suspend_me, &data, 0)) |
| 813 | data.error = -EINVAL; | 848 | atomic_set(&data.error, -EINVAL); |
| 814 | 849 | ||
| 815 | wait_for_completion(&done); | 850 | wait_for_completion(&done); |
| 816 | 851 | ||
| 817 | if (data.error != 0) | 852 | if (atomic_read(&data.error) != 0) |
| 818 | printk(KERN_ERR "Error doing global join\n"); | 853 | printk(KERN_ERR "Error doing global join\n"); |
| 819 | 854 | ||
| 820 | return data.error; | 855 | return atomic_read(&data.error); |
| 821 | } | 856 | } |
| 822 | #else /* CONFIG_PPC_PSERIES */ | 857 | #else /* CONFIG_PPC_PSERIES */ |
| 823 | static int rtas_ibm_suspend_me(struct rtas_args *args) | 858 | static int rtas_ibm_suspend_me(struct rtas_args *args) |
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index b7e6c7e193ae..15ade0d7bbb2 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c | |||
| @@ -94,6 +94,10 @@ struct screen_info screen_info = { | |||
| 94 | .orig_video_points = 16 | 94 | .orig_video_points = 16 |
| 95 | }; | 95 | }; |
| 96 | 96 | ||
| 97 | /* Variables required to store legacy IO irq routing */ | ||
| 98 | int of_i8042_kbd_irq; | ||
| 99 | int of_i8042_aux_irq; | ||
| 100 | |||
| 97 | #ifdef __DO_IRQ_CANON | 101 | #ifdef __DO_IRQ_CANON |
| 98 | /* XXX should go elsewhere eventually */ | 102 | /* XXX should go elsewhere eventually */ |
| 99 | int ppc_do_canonicalize_irqs; | 103 | int ppc_do_canonicalize_irqs; |
| @@ -575,6 +579,15 @@ int check_legacy_ioport(unsigned long base_port) | |||
| 575 | np = of_find_compatible_node(NULL, NULL, "pnpPNP,f03"); | 579 | np = of_find_compatible_node(NULL, NULL, "pnpPNP,f03"); |
| 576 | if (np) { | 580 | if (np) { |
| 577 | parent = of_get_parent(np); | 581 | parent = of_get_parent(np); |
| 582 | |||
| 583 | of_i8042_kbd_irq = irq_of_parse_and_map(parent, 0); | ||
| 584 | if (!of_i8042_kbd_irq) | ||
| 585 | of_i8042_kbd_irq = 1; | ||
| 586 | |||
| 587 | of_i8042_aux_irq = irq_of_parse_and_map(parent, 1); | ||
| 588 | if (!of_i8042_aux_irq) | ||
| 589 | of_i8042_aux_irq = 12; | ||
| 590 | |||
| 578 | of_node_put(np); | 591 | of_node_put(np); |
| 579 | np = parent; | 592 | np = parent; |
| 580 | break; | 593 | break; |
| @@ -701,16 +714,9 @@ static struct notifier_block ppc_dflt_plat_bus_notifier = { | |||
| 701 | .priority = INT_MAX, | 714 | .priority = INT_MAX, |
| 702 | }; | 715 | }; |
| 703 | 716 | ||
| 704 | static struct notifier_block ppc_dflt_of_bus_notifier = { | ||
| 705 | .notifier_call = ppc_dflt_bus_notify, | ||
| 706 | .priority = INT_MAX, | ||
| 707 | }; | ||
| 708 | |||
| 709 | static int __init setup_bus_notifier(void) | 717 | static int __init setup_bus_notifier(void) |
| 710 | { | 718 | { |
| 711 | bus_register_notifier(&platform_bus_type, &ppc_dflt_plat_bus_notifier); | 719 | bus_register_notifier(&platform_bus_type, &ppc_dflt_plat_bus_notifier); |
| 712 | bus_register_notifier(&of_platform_bus_type, &ppc_dflt_of_bus_notifier); | ||
| 713 | |||
| 714 | return 0; | 720 | return 0; |
| 715 | } | 721 | } |
| 716 | 722 | ||
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index d135f93cb0f6..1bee4b68fa45 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c | |||
| @@ -142,16 +142,6 @@ early_param("smt-enabled", early_smt_enabled); | |||
| 142 | #define check_smt_enabled() | 142 | #define check_smt_enabled() |
| 143 | #endif /* CONFIG_SMP */ | 143 | #endif /* CONFIG_SMP */ |
| 144 | 144 | ||
| 145 | /* Put the paca pointer into r13 and SPRG_PACA */ | ||
| 146 | static void __init setup_paca(struct paca_struct *new_paca) | ||
| 147 | { | ||
| 148 | local_paca = new_paca; | ||
| 149 | mtspr(SPRN_SPRG_PACA, local_paca); | ||
| 150 | #ifdef CONFIG_PPC_BOOK3E | ||
| 151 | mtspr(SPRN_SPRG_TLB_EXFRAME, local_paca->extlb); | ||
| 152 | #endif | ||
| 153 | } | ||
| 154 | |||
| 155 | /* | 145 | /* |
| 156 | * Early initialization entry point. This is called by head.S | 146 | * Early initialization entry point. This is called by head.S |
| 157 | * with MMU translation disabled. We rely on the "feature" of | 147 | * with MMU translation disabled. We rely on the "feature" of |
| @@ -600,6 +590,9 @@ static int pcpu_cpu_distance(unsigned int from, unsigned int to) | |||
| 600 | return REMOTE_DISTANCE; | 590 | return REMOTE_DISTANCE; |
| 601 | } | 591 | } |
| 602 | 592 | ||
| 593 | unsigned long __per_cpu_offset[NR_CPUS] __read_mostly; | ||
| 594 | EXPORT_SYMBOL(__per_cpu_offset); | ||
| 595 | |||
| 603 | void __init setup_per_cpu_areas(void) | 596 | void __init setup_per_cpu_areas(void) |
| 604 | { | 597 | { |
| 605 | const size_t dyn_size = PERCPU_MODULE_RESERVE + PERCPU_DYNAMIC_RESERVE; | 598 | const size_t dyn_size = PERCPU_MODULE_RESERVE + PERCPU_DYNAMIC_RESERVE; |
| @@ -624,8 +617,10 @@ void __init setup_per_cpu_areas(void) | |||
| 624 | panic("cannot initialize percpu area (err=%d)", rc); | 617 | panic("cannot initialize percpu area (err=%d)", rc); |
| 625 | 618 | ||
| 626 | delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start; | 619 | delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start; |
| 627 | for_each_possible_cpu(cpu) | 620 | for_each_possible_cpu(cpu) { |
| 628 | paca[cpu].data_offset = delta + pcpu_unit_offsets[cpu]; | 621 | __per_cpu_offset[cpu] = delta + pcpu_unit_offsets[cpu]; |
| 622 | paca[cpu].data_offset = __per_cpu_offset[cpu]; | ||
| 623 | } | ||
| 629 | } | 624 | } |
| 630 | #endif | 625 | #endif |
| 631 | 626 | ||
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c index a0afb555a7c9..7109f5b1baa8 100644 --- a/arch/powerpc/kernel/signal.c +++ b/arch/powerpc/kernel/signal.c | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | 11 | ||
| 12 | #include <linux/tracehook.h> | 12 | #include <linux/tracehook.h> |
| 13 | #include <linux/signal.h> | 13 | #include <linux/signal.h> |
| 14 | #include <asm/hw_breakpoint.h> | ||
| 14 | #include <asm/uaccess.h> | 15 | #include <asm/uaccess.h> |
| 15 | #include <asm/unistd.h> | 16 | #include <asm/unistd.h> |
| 16 | 17 | ||
| @@ -149,6 +150,8 @@ static int do_signal_pending(sigset_t *oldset, struct pt_regs *regs) | |||
| 149 | if (current->thread.dabr) | 150 | if (current->thread.dabr) |
| 150 | set_dabr(current->thread.dabr); | 151 | set_dabr(current->thread.dabr); |
| 151 | #endif | 152 | #endif |
| 153 | /* Re-enable the breakpoints for the signal stack */ | ||
| 154 | thread_change_pc(current, regs); | ||
| 152 | 155 | ||
| 153 | if (is32) { | 156 | if (is32) { |
| 154 | if (ka.sa.sa_flags & SA_SIGINFO) | 157 | if (ka.sa.sa_flags & SA_SIGINFO) |
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 5c196d1086d9..a61b3ddd7bb3 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c | |||
| @@ -288,8 +288,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
| 288 | max_cpus = NR_CPUS; | 288 | max_cpus = NR_CPUS; |
| 289 | else | 289 | else |
| 290 | max_cpus = 1; | 290 | max_cpus = 1; |
| 291 | |||
| 292 | smp_space_timers(max_cpus); | ||
| 293 | 291 | ||
| 294 | for_each_possible_cpu(cpu) | 292 | for_each_possible_cpu(cpu) |
| 295 | if (cpu != boot_cpuid) | 293 | if (cpu != boot_cpuid) |
| @@ -501,14 +499,6 @@ int __devinit start_secondary(void *unused) | |||
| 501 | current->active_mm = &init_mm; | 499 | current->active_mm = &init_mm; |
| 502 | 500 | ||
| 503 | smp_store_cpu_info(cpu); | 501 | smp_store_cpu_info(cpu); |
| 504 | |||
| 505 | #if defined(CONFIG_BOOKE) || defined(CONFIG_40x) | ||
| 506 | /* Clear any pending timer interrupts */ | ||
| 507 | mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS); | ||
| 508 | |||
| 509 | /* Enable decrementer interrupt */ | ||
| 510 | mtspr(SPRN_TCR, TCR_DIE); | ||
| 511 | #endif | ||
| 512 | set_dec(tb_ticks_per_jiffy); | 502 | set_dec(tb_ticks_per_jiffy); |
| 513 | preempt_disable(); | 503 | preempt_disable(); |
| 514 | cpu_callin_map[cpu] = 1; | 504 | cpu_callin_map[cpu] = 1; |
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 0441bbdadbd1..ccb8759c8532 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c | |||
| @@ -149,16 +149,6 @@ unsigned long tb_ticks_per_usec = 100; /* sane default */ | |||
| 149 | EXPORT_SYMBOL(tb_ticks_per_usec); | 149 | EXPORT_SYMBOL(tb_ticks_per_usec); |
| 150 | unsigned long tb_ticks_per_sec; | 150 | unsigned long tb_ticks_per_sec; |
| 151 | EXPORT_SYMBOL(tb_ticks_per_sec); /* for cputime_t conversions */ | 151 | EXPORT_SYMBOL(tb_ticks_per_sec); /* for cputime_t conversions */ |
| 152 | u64 tb_to_xs; | ||
| 153 | unsigned tb_to_us; | ||
| 154 | |||
| 155 | #define TICKLEN_SCALE NTP_SCALE_SHIFT | ||
| 156 | static u64 last_tick_len; /* units are ns / 2^TICKLEN_SCALE */ | ||
| 157 | static u64 ticklen_to_xs; /* 0.64 fraction */ | ||
| 158 | |||
| 159 | /* If last_tick_len corresponds to about 1/HZ seconds, then | ||
| 160 | last_tick_len << TICKLEN_SHIFT will be about 2^63. */ | ||
| 161 | #define TICKLEN_SHIFT (63 - 30 - TICKLEN_SCALE + SHIFT_HZ) | ||
| 162 | 152 | ||
| 163 | DEFINE_SPINLOCK(rtc_lock); | 153 | DEFINE_SPINLOCK(rtc_lock); |
| 164 | EXPORT_SYMBOL_GPL(rtc_lock); | 154 | EXPORT_SYMBOL_GPL(rtc_lock); |
| @@ -174,7 +164,6 @@ unsigned long ppc_proc_freq; | |||
| 174 | EXPORT_SYMBOL(ppc_proc_freq); | 164 | EXPORT_SYMBOL(ppc_proc_freq); |
| 175 | unsigned long ppc_tb_freq; | 165 | unsigned long ppc_tb_freq; |
| 176 | 166 | ||
| 177 | static u64 tb_last_jiffy __cacheline_aligned_in_smp; | ||
| 178 | static DEFINE_PER_CPU(u64, last_jiffy); | 167 | static DEFINE_PER_CPU(u64, last_jiffy); |
| 179 | 168 | ||
| 180 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 169 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
| @@ -423,30 +412,6 @@ void udelay(unsigned long usecs) | |||
| 423 | } | 412 | } |
| 424 | EXPORT_SYMBOL(udelay); | 413 | EXPORT_SYMBOL(udelay); |
| 425 | 414 | ||
| 426 | static inline void update_gtod(u64 new_tb_stamp, u64 new_stamp_xsec, | ||
| 427 | u64 new_tb_to_xs) | ||
| 428 | { | ||
| 429 | /* | ||
| 430 | * tb_update_count is used to allow the userspace gettimeofday code | ||
| 431 | * to assure itself that it sees a consistent view of the tb_to_xs and | ||
| 432 | * stamp_xsec variables. It reads the tb_update_count, then reads | ||
| 433 | * tb_to_xs and stamp_xsec and then reads tb_update_count again. If | ||
| 434 | * the two values of tb_update_count match and are even then the | ||
| 435 | * tb_to_xs and stamp_xsec values are consistent. If not, then it | ||
| 436 | * loops back and reads them again until this criteria is met. | ||
| 437 | * We expect the caller to have done the first increment of | ||
| 438 | * vdso_data->tb_update_count already. | ||
| 439 | */ | ||
| 440 | vdso_data->tb_orig_stamp = new_tb_stamp; | ||
| 441 | vdso_data->stamp_xsec = new_stamp_xsec; | ||
| 442 | vdso_data->tb_to_xs = new_tb_to_xs; | ||
| 443 | vdso_data->wtom_clock_sec = wall_to_monotonic.tv_sec; | ||
| 444 | vdso_data->wtom_clock_nsec = wall_to_monotonic.tv_nsec; | ||
| 445 | vdso_data->stamp_xtime = xtime; | ||
| 446 | smp_wmb(); | ||
| 447 | ++(vdso_data->tb_update_count); | ||
| 448 | } | ||
| 449 | |||
| 450 | #ifdef CONFIG_SMP | 415 | #ifdef CONFIG_SMP |
| 451 | unsigned long profile_pc(struct pt_regs *regs) | 416 | unsigned long profile_pc(struct pt_regs *regs) |
| 452 | { | 417 | { |
| @@ -470,7 +435,6 @@ EXPORT_SYMBOL(profile_pc); | |||
| 470 | 435 | ||
| 471 | static int __init iSeries_tb_recal(void) | 436 | static int __init iSeries_tb_recal(void) |
| 472 | { | 437 | { |
| 473 | struct div_result divres; | ||
| 474 | unsigned long titan, tb; | 438 | unsigned long titan, tb; |
| 475 | 439 | ||
| 476 | /* Make sure we only run on iSeries */ | 440 | /* Make sure we only run on iSeries */ |
| @@ -501,10 +465,7 @@ static int __init iSeries_tb_recal(void) | |||
| 501 | tb_ticks_per_jiffy = new_tb_ticks_per_jiffy; | 465 | tb_ticks_per_jiffy = new_tb_ticks_per_jiffy; |
| 502 | tb_ticks_per_sec = new_tb_ticks_per_sec; | 466 | tb_ticks_per_sec = new_tb_ticks_per_sec; |
| 503 | calc_cputime_factors(); | 467 | calc_cputime_factors(); |
| 504 | div128_by_32( XSEC_PER_SEC, 0, tb_ticks_per_sec, &divres ); | ||
| 505 | tb_to_xs = divres.result_low; | ||
| 506 | vdso_data->tb_ticks_per_sec = tb_ticks_per_sec; | 468 | vdso_data->tb_ticks_per_sec = tb_ticks_per_sec; |
| 507 | vdso_data->tb_to_xs = tb_to_xs; | ||
| 508 | setup_cputime_one_jiffy(); | 469 | setup_cputime_one_jiffy(); |
| 509 | } | 470 | } |
| 510 | else { | 471 | else { |
| @@ -667,27 +628,9 @@ void timer_interrupt(struct pt_regs * regs) | |||
| 667 | trace_timer_interrupt_exit(regs); | 628 | trace_timer_interrupt_exit(regs); |
| 668 | } | 629 | } |
| 669 | 630 | ||
| 670 | void wakeup_decrementer(void) | ||
| 671 | { | ||
| 672 | unsigned long ticks; | ||
| 673 | |||
| 674 | /* | ||
| 675 | * The timebase gets saved on sleep and restored on wakeup, | ||
| 676 | * so all we need to do is to reset the decrementer. | ||
| 677 | */ | ||
| 678 | ticks = tb_ticks_since(__get_cpu_var(last_jiffy)); | ||
| 679 | if (ticks < tb_ticks_per_jiffy) | ||
| 680 | ticks = tb_ticks_per_jiffy - ticks; | ||
| 681 | else | ||
| 682 | ticks = 1; | ||
| 683 | set_dec(ticks); | ||
| 684 | } | ||
| 685 | |||
| 686 | #ifdef CONFIG_SUSPEND | 631 | #ifdef CONFIG_SUSPEND |
| 687 | void generic_suspend_disable_irqs(void) | 632 | static void generic_suspend_disable_irqs(void) |
| 688 | { | 633 | { |
| 689 | preempt_disable(); | ||
| 690 | |||
| 691 | /* Disable the decrementer, so that it doesn't interfere | 634 | /* Disable the decrementer, so that it doesn't interfere |
| 692 | * with suspending. | 635 | * with suspending. |
| 693 | */ | 636 | */ |
| @@ -697,12 +640,9 @@ void generic_suspend_disable_irqs(void) | |||
| 697 | set_dec(0x7fffffff); | 640 | set_dec(0x7fffffff); |
| 698 | } | 641 | } |
| 699 | 642 | ||
| 700 | void generic_suspend_enable_irqs(void) | 643 | static void generic_suspend_enable_irqs(void) |
| 701 | { | 644 | { |
| 702 | wakeup_decrementer(); | ||
| 703 | |||
| 704 | local_irq_enable(); | 645 | local_irq_enable(); |
| 705 | preempt_enable(); | ||
| 706 | } | 646 | } |
| 707 | 647 | ||
| 708 | /* Overrides the weak version in kernel/power/main.c */ | 648 | /* Overrides the weak version in kernel/power/main.c */ |
| @@ -722,23 +662,6 @@ void arch_suspend_enable_irqs(void) | |||
| 722 | } | 662 | } |
| 723 | #endif | 663 | #endif |
| 724 | 664 | ||
| 725 | #ifdef CONFIG_SMP | ||
| 726 | void __init smp_space_timers(unsigned int max_cpus) | ||
| 727 | { | ||
| 728 | int i; | ||
| 729 | u64 previous_tb = per_cpu(last_jiffy, boot_cpuid); | ||
| 730 | |||
| 731 | /* make sure tb > per_cpu(last_jiffy, cpu) for all cpus always */ | ||
| 732 | previous_tb -= tb_ticks_per_jiffy; | ||
| 733 | |||
| 734 | for_each_possible_cpu(i) { | ||
| 735 | if (i == boot_cpuid) | ||
| 736 | continue; | ||
| 737 | per_cpu(last_jiffy, i) = previous_tb; | ||
| 738 | } | ||
| 739 | } | ||
| 740 | #endif | ||
| 741 | |||
| 742 | /* | 665 | /* |
| 743 | * Scheduler clock - returns current time in nanosec units. | 666 | * Scheduler clock - returns current time in nanosec units. |
| 744 | * | 667 | * |
| @@ -873,10 +796,37 @@ static cycle_t timebase_read(struct clocksource *cs) | |||
| 873 | return (cycle_t)get_tb(); | 796 | return (cycle_t)get_tb(); |
| 874 | } | 797 | } |
| 875 | 798 | ||
| 799 | static inline void update_gtod(u64 new_tb_stamp, u64 new_stamp_xsec, | ||
| 800 | u64 new_tb_to_xs, struct timespec *now, | ||
| 801 | u32 frac_sec) | ||
| 802 | { | ||
| 803 | /* | ||
| 804 | * tb_update_count is used to allow the userspace gettimeofday code | ||
| 805 | * to assure itself that it sees a consistent view of the tb_to_xs and | ||
| 806 | * stamp_xsec variables. It reads the tb_update_count, then reads | ||
| 807 | * tb_to_xs and stamp_xsec and then reads tb_update_count again. If | ||
| 808 | * the two values of tb_update_count match and are even then the | ||
| 809 | * tb_to_xs and stamp_xsec values are consistent. If not, then it | ||
| 810 | * loops back and reads them again until this criteria is met. | ||
| 811 | * We expect the caller to have done the first increment of | ||
| 812 | * vdso_data->tb_update_count already. | ||
| 813 | */ | ||
| 814 | vdso_data->tb_orig_stamp = new_tb_stamp; | ||
| 815 | vdso_data->stamp_xsec = new_stamp_xsec; | ||
| 816 | vdso_data->tb_to_xs = new_tb_to_xs; | ||
| 817 | vdso_data->wtom_clock_sec = wall_to_monotonic.tv_sec; | ||
| 818 | vdso_data->wtom_clock_nsec = wall_to_monotonic.tv_nsec; | ||
| 819 | vdso_data->stamp_xtime = *now; | ||
| 820 | vdso_data->stamp_sec_fraction = frac_sec; | ||
| 821 | smp_wmb(); | ||
| 822 | ++(vdso_data->tb_update_count); | ||
| 823 | } | ||
| 824 | |||
| 876 | void update_vsyscall(struct timespec *wall_time, struct clocksource *clock, | 825 | void update_vsyscall(struct timespec *wall_time, struct clocksource *clock, |
| 877 | u32 mult) | 826 | u32 mult) |
| 878 | { | 827 | { |
| 879 | u64 t2x, stamp_xsec; | 828 | u64 t2x, stamp_xsec; |
| 829 | u32 frac_sec; | ||
| 880 | 830 | ||
| 881 | if (clock != &clocksource_timebase) | 831 | if (clock != &clocksource_timebase) |
| 882 | return; | 832 | return; |
| @@ -888,10 +838,14 @@ void update_vsyscall(struct timespec *wall_time, struct clocksource *clock, | |||
| 888 | /* XXX this assumes clock->shift == 22 */ | 838 | /* XXX this assumes clock->shift == 22 */ |
| 889 | /* 4611686018 ~= 2^(20+64-22) / 1e9 */ | 839 | /* 4611686018 ~= 2^(20+64-22) / 1e9 */ |
| 890 | t2x = (u64) mult * 4611686018ULL; | 840 | t2x = (u64) mult * 4611686018ULL; |
| 891 | stamp_xsec = (u64) xtime.tv_nsec * XSEC_PER_SEC; | 841 | stamp_xsec = (u64) wall_time->tv_nsec * XSEC_PER_SEC; |
| 892 | do_div(stamp_xsec, 1000000000); | 842 | do_div(stamp_xsec, 1000000000); |
| 893 | stamp_xsec += (u64) xtime.tv_sec * XSEC_PER_SEC; | 843 | stamp_xsec += (u64) wall_time->tv_sec * XSEC_PER_SEC; |
| 894 | update_gtod(clock->cycle_last, stamp_xsec, t2x); | 844 | |
| 845 | BUG_ON(wall_time->tv_nsec >= NSEC_PER_SEC); | ||
| 846 | /* this is tv_nsec / 1e9 as a 0.32 fraction */ | ||
| 847 | frac_sec = ((u64) wall_time->tv_nsec * 18446744073ULL) >> 32; | ||
| 848 | update_gtod(clock->cycle_last, stamp_xsec, t2x, wall_time, frac_sec); | ||
| 895 | } | 849 | } |
| 896 | 850 | ||
| 897 | void update_vsyscall_tz(void) | 851 | void update_vsyscall_tz(void) |
| @@ -1007,15 +961,13 @@ void secondary_cpu_time_init(void) | |||
| 1007 | /* This function is only called on the boot processor */ | 961 | /* This function is only called on the boot processor */ |
| 1008 | void __init time_init(void) | 962 | void __init time_init(void) |
| 1009 | { | 963 | { |
| 1010 | unsigned long flags; | ||
| 1011 | struct div_result res; | 964 | struct div_result res; |
| 1012 | u64 scale, x; | 965 | u64 scale; |
| 1013 | unsigned shift; | 966 | unsigned shift; |
| 1014 | 967 | ||
| 1015 | if (__USE_RTC()) { | 968 | if (__USE_RTC()) { |
| 1016 | /* 601 processor: dec counts down by 128 every 128ns */ | 969 | /* 601 processor: dec counts down by 128 every 128ns */ |
| 1017 | ppc_tb_freq = 1000000000; | 970 | ppc_tb_freq = 1000000000; |
| 1018 | tb_last_jiffy = get_rtcl(); | ||
| 1019 | } else { | 971 | } else { |
| 1020 | /* Normal PowerPC with timebase register */ | 972 | /* Normal PowerPC with timebase register */ |
| 1021 | ppc_md.calibrate_decr(); | 973 | ppc_md.calibrate_decr(); |
| @@ -1023,50 +975,15 @@ void __init time_init(void) | |||
| 1023 | ppc_tb_freq / 1000000, ppc_tb_freq % 1000000); | 975 | ppc_tb_freq / 1000000, ppc_tb_freq % 1000000); |
| 1024 | printk(KERN_DEBUG "time_init: processor frequency = %lu.%.6lu MHz\n", | 976 | printk(KERN_DEBUG "time_init: processor frequency = %lu.%.6lu MHz\n", |
| 1025 | ppc_proc_freq / 1000000, ppc_proc_freq % 1000000); | 977 | ppc_proc_freq / 1000000, ppc_proc_freq % 1000000); |
| 1026 | tb_last_jiffy = get_tb(); | ||
| 1027 | } | 978 | } |
| 1028 | 979 | ||
| 1029 | tb_ticks_per_jiffy = ppc_tb_freq / HZ; | 980 | tb_ticks_per_jiffy = ppc_tb_freq / HZ; |
| 1030 | tb_ticks_per_sec = ppc_tb_freq; | 981 | tb_ticks_per_sec = ppc_tb_freq; |
| 1031 | tb_ticks_per_usec = ppc_tb_freq / 1000000; | 982 | tb_ticks_per_usec = ppc_tb_freq / 1000000; |
| 1032 | tb_to_us = mulhwu_scale_factor(ppc_tb_freq, 1000000); | ||
| 1033 | calc_cputime_factors(); | 983 | calc_cputime_factors(); |
| 1034 | setup_cputime_one_jiffy(); | 984 | setup_cputime_one_jiffy(); |
| 1035 | 985 | ||
| 1036 | /* | 986 | /* |
| 1037 | * Calculate the length of each tick in ns. It will not be | ||
| 1038 | * exactly 1e9/HZ unless ppc_tb_freq is divisible by HZ. | ||
| 1039 | * We compute 1e9 * tb_ticks_per_jiffy / ppc_tb_freq, | ||
| 1040 | * rounded up. | ||
| 1041 | */ | ||
| 1042 | x = (u64) NSEC_PER_SEC * tb_ticks_per_jiffy + ppc_tb_freq - 1; | ||
| 1043 | do_div(x, ppc_tb_freq); | ||
| 1044 | tick_nsec = x; | ||
| 1045 | last_tick_len = x << TICKLEN_SCALE; | ||
| 1046 | |||
| 1047 | /* | ||
| 1048 | * Compute ticklen_to_xs, which is a factor which gets multiplied | ||
| 1049 | * by (last_tick_len << TICKLEN_SHIFT) to get a tb_to_xs value. | ||
| 1050 | * It is computed as: | ||
| 1051 | * ticklen_to_xs = 2^N / (tb_ticks_per_jiffy * 1e9) | ||
| 1052 | * where N = 64 + 20 - TICKLEN_SCALE - TICKLEN_SHIFT | ||
| 1053 | * which turns out to be N = 51 - SHIFT_HZ. | ||
| 1054 | * This gives the result as a 0.64 fixed-point fraction. | ||
| 1055 | * That value is reduced by an offset amounting to 1 xsec per | ||
| 1056 | * 2^31 timebase ticks to avoid problems with time going backwards | ||
| 1057 | * by 1 xsec when we do timer_recalc_offset due to losing the | ||
| 1058 | * fractional xsec. That offset is equal to ppc_tb_freq/2^51 | ||
| 1059 | * since there are 2^20 xsec in a second. | ||
| 1060 | */ | ||
| 1061 | div128_by_32((1ULL << 51) - ppc_tb_freq, 0, | ||
| 1062 | tb_ticks_per_jiffy << SHIFT_HZ, &res); | ||
| 1063 | div128_by_32(res.result_high, res.result_low, NSEC_PER_SEC, &res); | ||
| 1064 | ticklen_to_xs = res.result_low; | ||
| 1065 | |||
| 1066 | /* Compute tb_to_xs from tick_nsec */ | ||
| 1067 | tb_to_xs = mulhdu(last_tick_len << TICKLEN_SHIFT, ticklen_to_xs); | ||
| 1068 | |||
| 1069 | /* | ||
| 1070 | * Compute scale factor for sched_clock. | 987 | * Compute scale factor for sched_clock. |
| 1071 | * The calibrate_decr() function has set tb_ticks_per_sec, | 988 | * The calibrate_decr() function has set tb_ticks_per_sec, |
| 1072 | * which is the timebase frequency. | 989 | * which is the timebase frequency. |
| @@ -1087,21 +1004,14 @@ void __init time_init(void) | |||
| 1087 | /* Save the current timebase to pretty up CONFIG_PRINTK_TIME */ | 1004 | /* Save the current timebase to pretty up CONFIG_PRINTK_TIME */ |
| 1088 | boot_tb = get_tb_or_rtc(); | 1005 | boot_tb = get_tb_or_rtc(); |
| 1089 | 1006 | ||
| 1090 | write_seqlock_irqsave(&xtime_lock, flags); | ||
| 1091 | |||
| 1092 | /* If platform provided a timezone (pmac), we correct the time */ | 1007 | /* If platform provided a timezone (pmac), we correct the time */ |
| 1093 | if (timezone_offset) { | 1008 | if (timezone_offset) { |
| 1094 | sys_tz.tz_minuteswest = -timezone_offset / 60; | 1009 | sys_tz.tz_minuteswest = -timezone_offset / 60; |
| 1095 | sys_tz.tz_dsttime = 0; | 1010 | sys_tz.tz_dsttime = 0; |
| 1096 | } | 1011 | } |
| 1097 | 1012 | ||
| 1098 | vdso_data->tb_orig_stamp = tb_last_jiffy; | ||
| 1099 | vdso_data->tb_update_count = 0; | 1013 | vdso_data->tb_update_count = 0; |
| 1100 | vdso_data->tb_ticks_per_sec = tb_ticks_per_sec; | 1014 | vdso_data->tb_ticks_per_sec = tb_ticks_per_sec; |
| 1101 | vdso_data->stamp_xsec = (u64) xtime.tv_sec * XSEC_PER_SEC; | ||
| 1102 | vdso_data->tb_to_xs = tb_to_xs; | ||
| 1103 | |||
| 1104 | write_sequnlock_irqrestore(&xtime_lock, flags); | ||
| 1105 | 1015 | ||
| 1106 | /* Start the decrementer on CPUs that have manual control | 1016 | /* Start the decrementer on CPUs that have manual control |
| 1107 | * such as BookE | 1017 | * such as BookE |
| @@ -1195,39 +1105,6 @@ void to_tm(int tim, struct rtc_time * tm) | |||
| 1195 | GregorianDay(tm); | 1105 | GregorianDay(tm); |
| 1196 | } | 1106 | } |
| 1197 | 1107 | ||
| 1198 | /* Auxiliary function to compute scaling factors */ | ||
| 1199 | /* Actually the choice of a timebase running at 1/4 the of the bus | ||
| 1200 | * frequency giving resolution of a few tens of nanoseconds is quite nice. | ||
| 1201 | * It makes this computation very precise (27-28 bits typically) which | ||
| 1202 | * is optimistic considering the stability of most processor clock | ||
| 1203 | * oscillators and the precision with which the timebase frequency | ||
| 1204 | * is measured but does not harm. | ||
| 1205 | */ | ||
| 1206 | unsigned mulhwu_scale_factor(unsigned inscale, unsigned outscale) | ||
| 1207 | { | ||
| 1208 | unsigned mlt=0, tmp, err; | ||
| 1209 | /* No concern for performance, it's done once: use a stupid | ||
| 1210 | * but safe and compact method to find the multiplier. | ||
| 1211 | */ | ||
| 1212 | |||
| 1213 | for (tmp = 1U<<31; tmp != 0; tmp >>= 1) { | ||
| 1214 | if (mulhwu(inscale, mlt|tmp) < outscale) | ||
| 1215 | mlt |= tmp; | ||
| 1216 | } | ||
| 1217 | |||
| 1218 | /* We might still be off by 1 for the best approximation. | ||
| 1219 | * A side effect of this is that if outscale is too large | ||
| 1220 | * the returned value will be zero. | ||
| 1221 | * Many corner cases have been checked and seem to work, | ||
| 1222 | * some might have been forgotten in the test however. | ||
| 1223 | */ | ||
| 1224 | |||
| 1225 | err = inscale * (mlt+1); | ||
| 1226 | if (err <= inscale/2) | ||
| 1227 | mlt++; | ||
| 1228 | return mlt; | ||
| 1229 | } | ||
| 1230 | |||
| 1231 | /* | 1108 | /* |
| 1232 | * Divide a 128-bit dividend by a 32-bit divisor, leaving a 128 bit | 1109 | * Divide a 128-bit dividend by a 32-bit divisor, leaving a 128 bit |
| 1233 | * result. | 1110 | * result. |
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 25fc33984c2b..a45a63c3a0c7 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c | |||
| @@ -55,9 +55,6 @@ | |||
| 55 | #endif | 55 | #endif |
| 56 | #include <asm/kexec.h> | 56 | #include <asm/kexec.h> |
| 57 | #include <asm/ppc-opcode.h> | 57 | #include <asm/ppc-opcode.h> |
| 58 | #ifdef CONFIG_FSL_BOOKE | ||
| 59 | #include <asm/dbell.h> | ||
| 60 | #endif | ||
| 61 | 58 | ||
| 62 | #if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC) | 59 | #if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC) |
| 63 | int (*__debugger)(struct pt_regs *regs) __read_mostly; | 60 | int (*__debugger)(struct pt_regs *regs) __read_mostly; |
| @@ -688,7 +685,7 @@ void RunModeException(struct pt_regs *regs) | |||
| 688 | 685 | ||
| 689 | void __kprobes single_step_exception(struct pt_regs *regs) | 686 | void __kprobes single_step_exception(struct pt_regs *regs) |
| 690 | { | 687 | { |
| 691 | regs->msr &= ~(MSR_SE | MSR_BE); /* Turn off 'trace' bits */ | 688 | clear_single_step(regs); |
| 692 | 689 | ||
| 693 | if (notify_die(DIE_SSTEP, "single_step", regs, 5, | 690 | if (notify_die(DIE_SSTEP, "single_step", regs, 5, |
| 694 | 5, SIGTRAP) == NOTIFY_STOP) | 691 | 5, SIGTRAP) == NOTIFY_STOP) |
| @@ -707,10 +704,8 @@ void __kprobes single_step_exception(struct pt_regs *regs) | |||
| 707 | */ | 704 | */ |
| 708 | static void emulate_single_step(struct pt_regs *regs) | 705 | static void emulate_single_step(struct pt_regs *regs) |
| 709 | { | 706 | { |
| 710 | if (single_stepping(regs)) { | 707 | if (single_stepping(regs)) |
| 711 | clear_single_step(regs); | 708 | single_step_exception(regs); |
| 712 | _exception(SIGTRAP, regs, TRAP_TRACE, 0); | ||
| 713 | } | ||
| 714 | } | 709 | } |
| 715 | 710 | ||
| 716 | static inline int __parse_fpscr(unsigned long fpscr) | 711 | static inline int __parse_fpscr(unsigned long fpscr) |
| @@ -1344,24 +1339,6 @@ void vsx_assist_exception(struct pt_regs *regs) | |||
| 1344 | #endif /* CONFIG_VSX */ | 1339 | #endif /* CONFIG_VSX */ |
| 1345 | 1340 | ||
| 1346 | #ifdef CONFIG_FSL_BOOKE | 1341 | #ifdef CONFIG_FSL_BOOKE |
| 1347 | |||
| 1348 | void doorbell_exception(struct pt_regs *regs) | ||
| 1349 | { | ||
| 1350 | #ifdef CONFIG_SMP | ||
| 1351 | int cpu = smp_processor_id(); | ||
| 1352 | int msg; | ||
| 1353 | |||
| 1354 | if (num_online_cpus() < 2) | ||
| 1355 | return; | ||
| 1356 | |||
| 1357 | for (msg = 0; msg < 4; msg++) | ||
| 1358 | if (test_and_clear_bit(msg, &dbell_smp_message[cpu])) | ||
| 1359 | smp_message_recv(msg); | ||
| 1360 | #else | ||
| 1361 | printk(KERN_WARNING "Received doorbell on non-smp system\n"); | ||
| 1362 | #endif | ||
| 1363 | } | ||
| 1364 | |||
| 1365 | void CacheLockingException(struct pt_regs *regs, unsigned long address, | 1342 | void CacheLockingException(struct pt_regs *regs, unsigned long address, |
| 1366 | unsigned long error_code) | 1343 | unsigned long error_code) |
| 1367 | { | 1344 | { |
diff --git a/arch/powerpc/kernel/vdso32/gettimeofday.S b/arch/powerpc/kernel/vdso32/gettimeofday.S index ee038d4bf252..4ee09ee2e836 100644 --- a/arch/powerpc/kernel/vdso32/gettimeofday.S +++ b/arch/powerpc/kernel/vdso32/gettimeofday.S | |||
| @@ -19,8 +19,10 @@ | |||
| 19 | /* Offset for the low 32-bit part of a field of long type */ | 19 | /* Offset for the low 32-bit part of a field of long type */ |
| 20 | #ifdef CONFIG_PPC64 | 20 | #ifdef CONFIG_PPC64 |
| 21 | #define LOPART 4 | 21 | #define LOPART 4 |
| 22 | #define TSPEC_TV_SEC TSPC64_TV_SEC+LOPART | ||
| 22 | #else | 23 | #else |
| 23 | #define LOPART 0 | 24 | #define LOPART 0 |
| 25 | #define TSPEC_TV_SEC TSPC32_TV_SEC | ||
| 24 | #endif | 26 | #endif |
| 25 | 27 | ||
| 26 | .text | 28 | .text |
| @@ -41,23 +43,11 @@ V_FUNCTION_BEGIN(__kernel_gettimeofday) | |||
| 41 | mr r9, r3 /* datapage ptr in r9 */ | 43 | mr r9, r3 /* datapage ptr in r9 */ |
| 42 | cmplwi r10,0 /* check if tv is NULL */ | 44 | cmplwi r10,0 /* check if tv is NULL */ |
| 43 | beq 3f | 45 | beq 3f |
| 44 | bl __do_get_xsec@local /* get xsec from tb & kernel */ | 46 | lis r7,1000000@ha /* load up USEC_PER_SEC */ |
| 45 | bne- 2f /* out of line -> do syscall */ | 47 | addi r7,r7,1000000@l /* so we get microseconds in r4 */ |
| 46 | 48 | bl __do_get_tspec@local /* get sec/usec from tb & kernel */ | |
| 47 | /* seconds are xsec >> 20 */ | 49 | stw r3,TVAL32_TV_SEC(r10) |
| 48 | rlwinm r5,r4,12,20,31 | 50 | stw r4,TVAL32_TV_USEC(r10) |
| 49 | rlwimi r5,r3,12,0,19 | ||
| 50 | stw r5,TVAL32_TV_SEC(r10) | ||
| 51 | |||
| 52 | /* get remaining xsec and convert to usec. we scale | ||
| 53 | * up remaining xsec by 12 bits and get the top 32 bits | ||
| 54 | * of the multiplication | ||
| 55 | */ | ||
| 56 | rlwinm r5,r4,12,0,19 | ||
| 57 | lis r6,1000000@h | ||
| 58 | ori r6,r6,1000000@l | ||
| 59 | mulhwu r5,r5,r6 | ||
| 60 | stw r5,TVAL32_TV_USEC(r10) | ||
| 61 | 51 | ||
| 62 | 3: cmplwi r11,0 /* check if tz is NULL */ | 52 | 3: cmplwi r11,0 /* check if tz is NULL */ |
| 63 | beq 1f | 53 | beq 1f |
| @@ -70,14 +60,6 @@ V_FUNCTION_BEGIN(__kernel_gettimeofday) | |||
| 70 | crclr cr0*4+so | 60 | crclr cr0*4+so |
| 71 | li r3,0 | 61 | li r3,0 |
| 72 | blr | 62 | blr |
| 73 | |||
| 74 | 2: | ||
| 75 | mtlr r12 | ||
| 76 | mr r3,r10 | ||
| 77 | mr r4,r11 | ||
| 78 | li r0,__NR_gettimeofday | ||
| 79 | sc | ||
| 80 | blr | ||
| 81 | .cfi_endproc | 63 | .cfi_endproc |
| 82 | V_FUNCTION_END(__kernel_gettimeofday) | 64 | V_FUNCTION_END(__kernel_gettimeofday) |
| 83 | 65 | ||
| @@ -100,7 +82,8 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime) | |||
| 100 | mr r11,r4 /* r11 saves tp */ | 82 | mr r11,r4 /* r11 saves tp */ |
| 101 | bl __get_datapage@local /* get data page */ | 83 | bl __get_datapage@local /* get data page */ |
| 102 | mr r9,r3 /* datapage ptr in r9 */ | 84 | mr r9,r3 /* datapage ptr in r9 */ |
| 103 | 85 | lis r7,NSEC_PER_SEC@h /* want nanoseconds */ | |
| 86 | ori r7,r7,NSEC_PER_SEC@l | ||
| 104 | 50: bl __do_get_tspec@local /* get sec/nsec from tb & kernel */ | 87 | 50: bl __do_get_tspec@local /* get sec/nsec from tb & kernel */ |
| 105 | bne cr1,80f /* not monotonic -> all done */ | 88 | bne cr1,80f /* not monotonic -> all done */ |
| 106 | 89 | ||
| @@ -198,83 +181,12 @@ V_FUNCTION_END(__kernel_clock_getres) | |||
| 198 | 181 | ||
| 199 | 182 | ||
| 200 | /* | 183 | /* |
| 201 | * This is the core of gettimeofday() & friends, it returns the xsec | 184 | * This is the core of clock_gettime() and gettimeofday(), |
| 202 | * value in r3 & r4 and expects the datapage ptr (non clobbered) | 185 | * it returns the current time in r3 (seconds) and r4. |
| 203 | * in r9. clobbers r0,r4,r5,r6,r7,r8. | 186 | * On entry, r7 gives the resolution of r4, either USEC_PER_SEC |
| 204 | * When returning, r8 contains the counter value that can be reused | 187 | * or NSEC_PER_SEC, giving r4 in microseconds or nanoseconds. |
| 205 | * by the monotonic clock implementation | ||
| 206 | */ | ||
| 207 | __do_get_xsec: | ||
| 208 | .cfi_startproc | ||
| 209 | /* Check for update count & load values. We use the low | ||
| 210 | * order 32 bits of the update count | ||
| 211 | */ | ||
| 212 | 1: lwz r8,(CFG_TB_UPDATE_COUNT+LOPART)(r9) | ||
| 213 | andi. r0,r8,1 /* pending update ? loop */ | ||
| 214 | bne- 1b | ||
| 215 | xor r0,r8,r8 /* create dependency */ | ||
| 216 | add r9,r9,r0 | ||
| 217 | |||
| 218 | /* Load orig stamp (offset to TB) */ | ||
| 219 | lwz r5,CFG_TB_ORIG_STAMP(r9) | ||
| 220 | lwz r6,(CFG_TB_ORIG_STAMP+4)(r9) | ||
| 221 | |||
| 222 | /* Get a stable TB value */ | ||
| 223 | 2: mftbu r3 | ||
| 224 | mftbl r4 | ||
| 225 | mftbu r0 | ||
| 226 | cmpl cr0,r3,r0 | ||
| 227 | bne- 2b | ||
| 228 | |||
| 229 | /* Substract tb orig stamp. If the high part is non-zero, we jump to | ||
| 230 | * the slow path which call the syscall. | ||
| 231 | * If it's ok, then we have our 32 bits tb_ticks value in r7 | ||
| 232 | */ | ||
| 233 | subfc r7,r6,r4 | ||
| 234 | subfe. r0,r5,r3 | ||
| 235 | bne- 3f | ||
| 236 | |||
| 237 | /* Load scale factor & do multiplication */ | ||
| 238 | lwz r5,CFG_TB_TO_XS(r9) /* load values */ | ||
| 239 | lwz r6,(CFG_TB_TO_XS+4)(r9) | ||
| 240 | mulhwu r4,r7,r5 | ||
| 241 | mulhwu r6,r7,r6 | ||
| 242 | mullw r0,r7,r5 | ||
| 243 | addc r6,r6,r0 | ||
| 244 | |||
| 245 | /* At this point, we have the scaled xsec value in r4 + XER:CA | ||
| 246 | * we load & add the stamp since epoch | ||
| 247 | */ | ||
| 248 | lwz r5,CFG_STAMP_XSEC(r9) | ||
| 249 | lwz r6,(CFG_STAMP_XSEC+4)(r9) | ||
| 250 | adde r4,r4,r6 | ||
| 251 | addze r3,r5 | ||
| 252 | |||
| 253 | /* We now have our result in r3,r4. We create a fake dependency | ||
| 254 | * on that result and re-check the counter | ||
| 255 | */ | ||
| 256 | or r6,r4,r3 | ||
| 257 | xor r0,r6,r6 | ||
| 258 | add r9,r9,r0 | ||
| 259 | lwz r0,(CFG_TB_UPDATE_COUNT+LOPART)(r9) | ||
| 260 | cmpl cr0,r8,r0 /* check if updated */ | ||
| 261 | bne- 1b | ||
| 262 | |||
| 263 | /* Warning ! The caller expects CR:EQ to be set to indicate a | ||
| 264 | * successful calculation (so it won't fallback to the syscall | ||
| 265 | * method). We have overriden that CR bit in the counter check, | ||
| 266 | * but fortunately, the loop exit condition _is_ CR:EQ set, so | ||
| 267 | * we can exit safely here. If you change this code, be careful | ||
| 268 | * of that side effect. | ||
| 269 | */ | ||
| 270 | 3: blr | ||
| 271 | .cfi_endproc | ||
| 272 | |||
| 273 | /* | ||
| 274 | * This is the core of clock_gettime(), it returns the current | ||
| 275 | * time in seconds and nanoseconds in r3 and r4. | ||
| 276 | * It expects the datapage ptr in r9 and doesn't clobber it. | 188 | * It expects the datapage ptr in r9 and doesn't clobber it. |
| 277 | * It clobbers r0, r5, r6, r10 and returns NSEC_PER_SEC in r7. | 189 | * It clobbers r0, r5 and r6. |
| 278 | * On return, r8 contains the counter value that can be reused. | 190 | * On return, r8 contains the counter value that can be reused. |
| 279 | * This clobbers cr0 but not any other cr field. | 191 | * This clobbers cr0 but not any other cr field. |
| 280 | */ | 192 | */ |
| @@ -297,70 +209,58 @@ __do_get_tspec: | |||
| 297 | 2: mftbu r3 | 209 | 2: mftbu r3 |
| 298 | mftbl r4 | 210 | mftbl r4 |
| 299 | mftbu r0 | 211 | mftbu r0 |
| 300 | cmpl cr0,r3,r0 | 212 | cmplw cr0,r3,r0 |
| 301 | bne- 2b | 213 | bne- 2b |
| 302 | 214 | ||
| 303 | /* Subtract tb orig stamp and shift left 12 bits. | 215 | /* Subtract tb orig stamp and shift left 12 bits. |
| 304 | */ | 216 | */ |
| 305 | subfc r7,r6,r4 | 217 | subfc r4,r6,r4 |
| 306 | subfe r0,r5,r3 | 218 | subfe r0,r5,r3 |
| 307 | slwi r0,r0,12 | 219 | slwi r0,r0,12 |
| 308 | rlwimi. r0,r7,12,20,31 | 220 | rlwimi. r0,r4,12,20,31 |
| 309 | slwi r7,r7,12 | 221 | slwi r4,r4,12 |
| 310 | 222 | ||
| 311 | /* Load scale factor & do multiplication */ | 223 | /* |
| 224 | * Load scale factor & do multiplication. | ||
| 225 | * We only use the high 32 bits of the tb_to_xs value. | ||
| 226 | * Even with a 1GHz timebase clock, the high 32 bits of | ||
| 227 | * tb_to_xs will be at least 4 million, so the error from | ||
| 228 | * ignoring the low 32 bits will be no more than 0.25ppm. | ||
| 229 | * The error will just make the clock run very very slightly | ||
| 230 | * slow until the next time the kernel updates the VDSO data, | ||
| 231 | * at which point the clock will catch up to the kernel's value, | ||
| 232 | * so there is no long-term error accumulation. | ||
| 233 | */ | ||
| 312 | lwz r5,CFG_TB_TO_XS(r9) /* load values */ | 234 | lwz r5,CFG_TB_TO_XS(r9) /* load values */ |
| 313 | lwz r6,(CFG_TB_TO_XS+4)(r9) | 235 | mulhwu r4,r4,r5 |
| 314 | mulhwu r3,r7,r6 | ||
| 315 | mullw r10,r7,r5 | ||
| 316 | mulhwu r4,r7,r5 | ||
| 317 | addc r10,r3,r10 | ||
| 318 | li r3,0 | 236 | li r3,0 |
| 319 | 237 | ||
| 320 | beq+ 4f /* skip high part computation if 0 */ | 238 | beq+ 4f /* skip high part computation if 0 */ |
| 321 | mulhwu r3,r0,r5 | 239 | mulhwu r3,r0,r5 |
| 322 | mullw r7,r0,r5 | 240 | mullw r5,r0,r5 |
| 323 | mulhwu r5,r0,r6 | ||
| 324 | mullw r6,r0,r6 | ||
| 325 | adde r4,r4,r7 | ||
| 326 | addze r3,r3 | ||
| 327 | addc r4,r4,r5 | 241 | addc r4,r4,r5 |
| 328 | addze r3,r3 | 242 | addze r3,r3 |
| 329 | addc r10,r10,r6 | 243 | 4: |
| 330 | 244 | /* At this point, we have seconds since the xtime stamp | |
| 331 | 4: addze r4,r4 /* add in carry */ | 245 | * as a 32.32 fixed-point number in r3 and r4. |
| 332 | lis r7,NSEC_PER_SEC@h | 246 | * Load & add the xtime stamp. |
| 333 | ori r7,r7,NSEC_PER_SEC@l | ||
| 334 | mulhwu r4,r4,r7 /* convert to nanoseconds */ | ||
| 335 | |||
| 336 | /* At this point, we have seconds & nanoseconds since the xtime | ||
| 337 | * stamp in r3+CA and r4. Load & add the xtime stamp. | ||
| 338 | */ | 247 | */ |
| 339 | #ifdef CONFIG_PPC64 | 248 | lwz r5,STAMP_XTIME+TSPEC_TV_SEC(r9) |
| 340 | lwz r5,STAMP_XTIME+TSPC64_TV_SEC+LOPART(r9) | 249 | lwz r6,STAMP_SEC_FRAC(r9) |
| 341 | lwz r6,STAMP_XTIME+TSPC64_TV_NSEC+LOPART(r9) | 250 | addc r4,r4,r6 |
| 342 | #else | ||
| 343 | lwz r5,STAMP_XTIME+TSPC32_TV_SEC(r9) | ||
| 344 | lwz r6,STAMP_XTIME+TSPC32_TV_NSEC(r9) | ||
| 345 | #endif | ||
| 346 | add r4,r4,r6 | ||
| 347 | adde r3,r3,r5 | 251 | adde r3,r3,r5 |
| 348 | 252 | ||
| 349 | /* We now have our result in r3,r4. We create a fake dependency | 253 | /* We create a fake dependency on the result in r3/r4 |
| 350 | * on that result and re-check the counter | 254 | * and re-check the counter |
| 351 | */ | 255 | */ |
| 352 | or r6,r4,r3 | 256 | or r6,r4,r3 |
| 353 | xor r0,r6,r6 | 257 | xor r0,r6,r6 |
| 354 | add r9,r9,r0 | 258 | add r9,r9,r0 |
| 355 | lwz r0,(CFG_TB_UPDATE_COUNT+LOPART)(r9) | 259 | lwz r0,(CFG_TB_UPDATE_COUNT+LOPART)(r9) |
| 356 | cmpl cr0,r8,r0 /* check if updated */ | 260 | cmplw cr0,r8,r0 /* check if updated */ |
| 357 | bne- 1b | 261 | bne- 1b |
| 358 | 262 | ||
| 359 | /* check for nanosecond overflow and adjust if necessary */ | 263 | mulhwu r4,r4,r7 /* convert to micro or nanoseconds */ |
| 360 | cmpw r4,r7 | ||
| 361 | bltlr /* all done if no overflow */ | ||
| 362 | subf r4,r7,r4 /* adjust if overflow */ | ||
| 363 | addi r3,r3,1 | ||
| 364 | 264 | ||
| 365 | blr | 265 | blr |
| 366 | .cfi_endproc | 266 | .cfi_endproc |
diff --git a/arch/powerpc/kernel/vdso64/gettimeofday.S b/arch/powerpc/kernel/vdso64/gettimeofday.S index 262cd5857a56..e97a9a0dc4ac 100644 --- a/arch/powerpc/kernel/vdso64/gettimeofday.S +++ b/arch/powerpc/kernel/vdso64/gettimeofday.S | |||
| @@ -33,18 +33,11 @@ V_FUNCTION_BEGIN(__kernel_gettimeofday) | |||
| 33 | bl V_LOCAL_FUNC(__get_datapage) /* get data page */ | 33 | bl V_LOCAL_FUNC(__get_datapage) /* get data page */ |
| 34 | cmpldi r11,0 /* check if tv is NULL */ | 34 | cmpldi r11,0 /* check if tv is NULL */ |
| 35 | beq 2f | 35 | beq 2f |
| 36 | bl V_LOCAL_FUNC(__do_get_xsec) /* get xsec from tb & kernel */ | 36 | lis r7,1000000@ha /* load up USEC_PER_SEC */ |
| 37 | lis r7,15 /* r7 = 1000000 = USEC_PER_SEC */ | 37 | addi r7,r7,1000000@l |
| 38 | ori r7,r7,16960 | 38 | bl V_LOCAL_FUNC(__do_get_tspec) /* get sec/us from tb & kernel */ |
| 39 | rldicl r5,r4,44,20 /* r5 = sec = xsec / XSEC_PER_SEC */ | 39 | std r4,TVAL64_TV_SEC(r11) /* store sec in tv */ |
| 40 | rldicr r6,r5,20,43 /* r6 = sec * XSEC_PER_SEC */ | 40 | std r5,TVAL64_TV_USEC(r11) /* store usec in tv */ |
| 41 | std r5,TVAL64_TV_SEC(r11) /* store sec in tv */ | ||
| 42 | subf r0,r6,r4 /* r0 = xsec = (xsec - r6) */ | ||
| 43 | mulld r0,r0,r7 /* usec = (xsec * USEC_PER_SEC) / | ||
| 44 | * XSEC_PER_SEC | ||
| 45 | */ | ||
| 46 | rldicl r0,r0,44,20 | ||
| 47 | std r0,TVAL64_TV_USEC(r11) /* store usec in tv */ | ||
| 48 | 2: cmpldi r10,0 /* check if tz is NULL */ | 41 | 2: cmpldi r10,0 /* check if tz is NULL */ |
| 49 | beq 1f | 42 | beq 1f |
| 50 | lwz r4,CFG_TZ_MINUTEWEST(r3)/* fill tz */ | 43 | lwz r4,CFG_TZ_MINUTEWEST(r3)/* fill tz */ |
| @@ -77,6 +70,8 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime) | |||
| 77 | .cfi_register lr,r12 | 70 | .cfi_register lr,r12 |
| 78 | mr r11,r4 /* r11 saves tp */ | 71 | mr r11,r4 /* r11 saves tp */ |
| 79 | bl V_LOCAL_FUNC(__get_datapage) /* get data page */ | 72 | bl V_LOCAL_FUNC(__get_datapage) /* get data page */ |
| 73 | lis r7,NSEC_PER_SEC@h /* want nanoseconds */ | ||
| 74 | ori r7,r7,NSEC_PER_SEC@l | ||
| 80 | 50: bl V_LOCAL_FUNC(__do_get_tspec) /* get time from tb & kernel */ | 75 | 50: bl V_LOCAL_FUNC(__do_get_tspec) /* get time from tb & kernel */ |
| 81 | bne cr1,80f /* if not monotonic, all done */ | 76 | bne cr1,80f /* if not monotonic, all done */ |
| 82 | 77 | ||
| @@ -171,49 +166,12 @@ V_FUNCTION_END(__kernel_clock_getres) | |||
| 171 | 166 | ||
| 172 | 167 | ||
| 173 | /* | 168 | /* |
| 174 | * This is the core of gettimeofday(), it returns the xsec | 169 | * This is the core of clock_gettime() and gettimeofday(), |
| 175 | * value in r4 and expects the datapage ptr (non clobbered) | 170 | * it returns the current time in r4 (seconds) and r5. |
| 176 | * in r3. clobbers r0,r4,r5,r6,r7,r8 | 171 | * On entry, r7 gives the resolution of r5, either USEC_PER_SEC |
| 177 | * When returning, r8 contains the counter value that can be reused | 172 | * or NSEC_PER_SEC, giving r5 in microseconds or nanoseconds. |
| 178 | */ | ||
| 179 | V_FUNCTION_BEGIN(__do_get_xsec) | ||
| 180 | .cfi_startproc | ||
| 181 | /* check for update count & load values */ | ||
| 182 | 1: ld r8,CFG_TB_UPDATE_COUNT(r3) | ||
| 183 | andi. r0,r8,1 /* pending update ? loop */ | ||
| 184 | bne- 1b | ||
| 185 | xor r0,r8,r8 /* create dependency */ | ||
| 186 | add r3,r3,r0 | ||
| 187 | |||
| 188 | /* Get TB & offset it. We use the MFTB macro which will generate | ||
| 189 | * workaround code for Cell. | ||
| 190 | */ | ||
| 191 | MFTB(r7) | ||
| 192 | ld r9,CFG_TB_ORIG_STAMP(r3) | ||
| 193 | subf r7,r9,r7 | ||
| 194 | |||
| 195 | /* Scale result */ | ||
| 196 | ld r5,CFG_TB_TO_XS(r3) | ||
| 197 | mulhdu r7,r7,r5 | ||
| 198 | |||
| 199 | /* Add stamp since epoch */ | ||
| 200 | ld r6,CFG_STAMP_XSEC(r3) | ||
| 201 | add r4,r6,r7 | ||
| 202 | |||
| 203 | xor r0,r4,r4 | ||
| 204 | add r3,r3,r0 | ||
| 205 | ld r0,CFG_TB_UPDATE_COUNT(r3) | ||
| 206 | cmpld cr0,r0,r8 /* check if updated */ | ||
| 207 | bne- 1b | ||
| 208 | blr | ||
| 209 | .cfi_endproc | ||
| 210 | V_FUNCTION_END(__do_get_xsec) | ||
| 211 | |||
| 212 | /* | ||
| 213 | * This is the core of clock_gettime(), it returns the current | ||
| 214 | * time in seconds and nanoseconds in r4 and r5. | ||
| 215 | * It expects the datapage ptr in r3 and doesn't clobber it. | 173 | * It expects the datapage ptr in r3 and doesn't clobber it. |
| 216 | * It clobbers r0 and r6 and returns NSEC_PER_SEC in r7. | 174 | * It clobbers r0, r6 and r9. |
| 217 | * On return, r8 contains the counter value that can be reused. | 175 | * On return, r8 contains the counter value that can be reused. |
| 218 | * This clobbers cr0 but not any other cr field. | 176 | * This clobbers cr0 but not any other cr field. |
| 219 | */ | 177 | */ |
| @@ -229,18 +187,18 @@ V_FUNCTION_BEGIN(__do_get_tspec) | |||
| 229 | /* Get TB & offset it. We use the MFTB macro which will generate | 187 | /* Get TB & offset it. We use the MFTB macro which will generate |
| 230 | * workaround code for Cell. | 188 | * workaround code for Cell. |
| 231 | */ | 189 | */ |
| 232 | MFTB(r7) | 190 | MFTB(r6) |
| 233 | ld r9,CFG_TB_ORIG_STAMP(r3) | 191 | ld r9,CFG_TB_ORIG_STAMP(r3) |
| 234 | subf r7,r9,r7 | 192 | subf r6,r9,r6 |
| 235 | 193 | ||
| 236 | /* Scale result */ | 194 | /* Scale result */ |
| 237 | ld r5,CFG_TB_TO_XS(r3) | 195 | ld r5,CFG_TB_TO_XS(r3) |
| 238 | sldi r7,r7,12 /* compute time since stamp_xtime */ | 196 | sldi r6,r6,12 /* compute time since stamp_xtime */ |
| 239 | mulhdu r6,r7,r5 /* in units of 2^-32 seconds */ | 197 | mulhdu r6,r6,r5 /* in units of 2^-32 seconds */ |
| 240 | 198 | ||
| 241 | /* Add stamp since epoch */ | 199 | /* Add stamp since epoch */ |
| 242 | ld r4,STAMP_XTIME+TSPC64_TV_SEC(r3) | 200 | ld r4,STAMP_XTIME+TSPC64_TV_SEC(r3) |
| 243 | ld r5,STAMP_XTIME+TSPC64_TV_NSEC(r3) | 201 | lwz r5,STAMP_SEC_FRAC(r3) |
| 244 | or r0,r4,r5 | 202 | or r0,r4,r5 |
| 245 | or r0,r0,r6 | 203 | or r0,r0,r6 |
| 246 | xor r0,r0,r0 | 204 | xor r0,r0,r0 |
| @@ -250,17 +208,11 @@ V_FUNCTION_BEGIN(__do_get_tspec) | |||
| 250 | bne- 1b /* reload if so */ | 208 | bne- 1b /* reload if so */ |
| 251 | 209 | ||
| 252 | /* convert to seconds & nanoseconds and add to stamp */ | 210 | /* convert to seconds & nanoseconds and add to stamp */ |
| 253 | lis r7,NSEC_PER_SEC@h | 211 | add r6,r6,r5 /* add on fractional seconds of xtime */ |
| 254 | ori r7,r7,NSEC_PER_SEC@l | 212 | mulhwu r5,r6,r7 /* compute micro or nanoseconds and */ |
| 255 | mulhwu r0,r6,r7 /* compute nanoseconds and */ | ||
| 256 | srdi r6,r6,32 /* seconds since stamp_xtime */ | 213 | srdi r6,r6,32 /* seconds since stamp_xtime */ |
| 257 | clrldi r0,r0,32 | 214 | clrldi r5,r5,32 |
| 258 | add r5,r5,r0 /* add nanoseconds together */ | ||
| 259 | cmpd r5,r7 /* overflow? */ | ||
| 260 | add r4,r4,r6 | 215 | add r4,r4,r6 |
| 261 | bltlr /* all done if no overflow */ | ||
| 262 | subf r5,r7,r5 /* if overflow, adjust */ | ||
| 263 | addi r4,r4,1 | ||
| 264 | blr | 216 | blr |
| 265 | .cfi_endproc | 217 | .cfi_endproc |
| 266 | V_FUNCTION_END(__do_get_tspec) | 218 | V_FUNCTION_END(__do_get_tspec) |
diff --git a/arch/powerpc/kvm/timing.c b/arch/powerpc/kvm/timing.c index 70378551c0cc..46fa04f12a9b 100644 --- a/arch/powerpc/kvm/timing.c +++ b/arch/powerpc/kvm/timing.c | |||
| @@ -182,7 +182,7 @@ static ssize_t kvmppc_exit_timing_write(struct file *file, | |||
| 182 | } | 182 | } |
| 183 | 183 | ||
| 184 | if (c == 'c') { | 184 | if (c == 'c') { |
| 185 | struct seq_file *seqf = (struct seq_file *)file->private_data; | 185 | struct seq_file *seqf = file->private_data; |
| 186 | struct kvm_vcpu *vcpu = seqf->private; | 186 | struct kvm_vcpu *vcpu = seqf->private; |
| 187 | /* Write does not affect our buffers previously generated with | 187 | /* Write does not affect our buffers previously generated with |
| 188 | * show. seq_file is locked here to prevent races of init with | 188 | * show. seq_file is locked here to prevent races of init with |
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index 111da1c03a11..5bb89c828070 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile | |||
| @@ -18,8 +18,9 @@ obj-$(CONFIG_HAS_IOMEM) += devres.o | |||
| 18 | 18 | ||
| 19 | obj-$(CONFIG_PPC64) += copypage_64.o copyuser_64.o \ | 19 | obj-$(CONFIG_PPC64) += copypage_64.o copyuser_64.o \ |
| 20 | memcpy_64.o usercopy_64.o mem_64.o string.o | 20 | memcpy_64.o usercopy_64.o mem_64.o string.o |
| 21 | obj-$(CONFIG_XMON) += sstep.o | 21 | obj-$(CONFIG_XMON) += sstep.o ldstfp.o |
| 22 | obj-$(CONFIG_KPROBES) += sstep.o | 22 | obj-$(CONFIG_KPROBES) += sstep.o ldstfp.o |
| 23 | obj-$(CONFIG_HAVE_HW_BREAKPOINT) += sstep.o ldstfp.o | ||
| 23 | 24 | ||
| 24 | ifeq ($(CONFIG_PPC64),y) | 25 | ifeq ($(CONFIG_PPC64),y) |
| 25 | obj-$(CONFIG_SMP) += locks.o | 26 | obj-$(CONFIG_SMP) += locks.o |
diff --git a/arch/powerpc/lib/ldstfp.S b/arch/powerpc/lib/ldstfp.S new file mode 100644 index 000000000000..f6448636baf5 --- /dev/null +++ b/arch/powerpc/lib/ldstfp.S | |||
| @@ -0,0 +1,375 @@ | |||
| 1 | /* | ||
| 2 | * Floating-point, VMX/Altivec and VSX loads and stores | ||
| 3 | * for use in instruction emulation. | ||
| 4 | * | ||
| 5 | * Copyright 2010 Paul Mackerras, IBM Corp. <paulus@au1.ibm.com> | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or | ||
| 8 | * modify it under the terms of the GNU General Public License | ||
| 9 | * as published by the Free Software Foundation; either version | ||
| 10 | * 2 of the License, or (at your option) any later version. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <asm/processor.h> | ||
| 14 | #include <asm/ppc_asm.h> | ||
| 15 | #include <asm/ppc-opcode.h> | ||
| 16 | #include <asm/reg.h> | ||
| 17 | #include <asm/asm-offsets.h> | ||
| 18 | #include <linux/errno.h> | ||
| 19 | |||
| 20 | #define STKFRM (PPC_MIN_STKFRM + 16) | ||
| 21 | |||
| 22 | .macro extab instr,handler | ||
| 23 | .section __ex_table,"a" | ||
| 24 | PPC_LONG \instr,\handler | ||
| 25 | .previous | ||
| 26 | .endm | ||
| 27 | |||
| 28 | .macro inst32 op | ||
| 29 | reg = 0 | ||
| 30 | .rept 32 | ||
| 31 | 20: \op reg,0,r4 | ||
| 32 | b 3f | ||
| 33 | extab 20b,99f | ||
| 34 | reg = reg + 1 | ||
| 35 | .endr | ||
| 36 | .endm | ||
| 37 | |||
| 38 | /* Get the contents of frN into fr0; N is in r3. */ | ||
| 39 | _GLOBAL(get_fpr) | ||
| 40 | mflr r0 | ||
| 41 | rlwinm r3,r3,3,0xf8 | ||
| 42 | bcl 20,31,1f | ||
| 43 | blr /* fr0 is already in fr0 */ | ||
| 44 | nop | ||
| 45 | reg = 1 | ||
| 46 | .rept 31 | ||
| 47 | fmr fr0,reg | ||
| 48 | blr | ||
| 49 | reg = reg + 1 | ||
| 50 | .endr | ||
| 51 | 1: mflr r5 | ||
| 52 | add r5,r3,r5 | ||
| 53 | mtctr r5 | ||
| 54 | mtlr r0 | ||
| 55 | bctr | ||
| 56 | |||
| 57 | /* Put the contents of fr0 into frN; N is in r3. */ | ||
| 58 | _GLOBAL(put_fpr) | ||
| 59 | mflr r0 | ||
| 60 | rlwinm r3,r3,3,0xf8 | ||
| 61 | bcl 20,31,1f | ||
| 62 | blr /* fr0 is already in fr0 */ | ||
| 63 | nop | ||
| 64 | reg = 1 | ||
| 65 | .rept 31 | ||
| 66 | fmr reg,fr0 | ||
| 67 | blr | ||
| 68 | reg = reg + 1 | ||
| 69 | .endr | ||
| 70 | 1: mflr r5 | ||
| 71 | add r5,r3,r5 | ||
| 72 | mtctr r5 | ||
| 73 | mtlr r0 | ||
| 74 | bctr | ||
| 75 | |||
| 76 | /* Load FP reg N from float at *p. N is in r3, p in r4. */ | ||
| 77 | _GLOBAL(do_lfs) | ||
| 78 | PPC_STLU r1,-STKFRM(r1) | ||
| 79 | mflr r0 | ||
| 80 | PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1) | ||
| 81 | mfmsr r6 | ||
| 82 | ori r7,r6,MSR_FP | ||
| 83 | cmpwi cr7,r3,0 | ||
| 84 | mtmsrd r7 | ||
| 85 | isync | ||
| 86 | beq cr7,1f | ||
| 87 | stfd fr0,STKFRM-16(r1) | ||
| 88 | 1: li r9,-EFAULT | ||
| 89 | 2: lfs fr0,0(r4) | ||
| 90 | li r9,0 | ||
| 91 | 3: bl put_fpr | ||
| 92 | beq cr7,4f | ||
| 93 | lfd fr0,STKFRM-16(r1) | ||
| 94 | 4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1) | ||
| 95 | mtlr r0 | ||
| 96 | mtmsrd r6 | ||
| 97 | isync | ||
| 98 | mr r3,r9 | ||
| 99 | addi r1,r1,STKFRM | ||
| 100 | blr | ||
| 101 | extab 2b,3b | ||
| 102 | |||
| 103 | /* Load FP reg N from double at *p. N is in r3, p in r4. */ | ||
| 104 | _GLOBAL(do_lfd) | ||
| 105 | PPC_STLU r1,-STKFRM(r1) | ||
| 106 | mflr r0 | ||
| 107 | PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1) | ||
| 108 | mfmsr r6 | ||
| 109 | ori r7,r6,MSR_FP | ||
| 110 | cmpwi cr7,r3,0 | ||
| 111 | mtmsrd r7 | ||
| 112 | isync | ||
| 113 | beq cr7,1f | ||
| 114 | stfd fr0,STKFRM-16(r1) | ||
| 115 | 1: li r9,-EFAULT | ||
| 116 | 2: lfd fr0,0(r4) | ||
| 117 | li r9,0 | ||
| 118 | 3: beq cr7,4f | ||
| 119 | bl put_fpr | ||
| 120 | lfd fr0,STKFRM-16(r1) | ||
| 121 | 4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1) | ||
| 122 | mtlr r0 | ||
| 123 | mtmsrd r6 | ||
| 124 | isync | ||
| 125 | mr r3,r9 | ||
| 126 | addi r1,r1,STKFRM | ||
| 127 | blr | ||
| 128 | extab 2b,3b | ||
| 129 | |||
| 130 | /* Store FP reg N to float at *p. N is in r3, p in r4. */ | ||
| 131 | _GLOBAL(do_stfs) | ||
| 132 | PPC_STLU r1,-STKFRM(r1) | ||
| 133 | mflr r0 | ||
| 134 | PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1) | ||
| 135 | mfmsr r6 | ||
| 136 | ori r7,r6,MSR_FP | ||
| 137 | cmpwi cr7,r3,0 | ||
| 138 | mtmsrd r7 | ||
| 139 | isync | ||
| 140 | beq cr7,1f | ||
| 141 | stfd fr0,STKFRM-16(r1) | ||
| 142 | bl get_fpr | ||
| 143 | 1: li r9,-EFAULT | ||
| 144 | 2: stfs fr0,0(r4) | ||
| 145 | li r9,0 | ||
| 146 | 3: beq cr7,4f | ||
| 147 | lfd fr0,STKFRM-16(r1) | ||
| 148 | 4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1) | ||
| 149 | mtlr r0 | ||
| 150 | mtmsrd r6 | ||
| 151 | isync | ||
| 152 | mr r3,r9 | ||
| 153 | addi r1,r1,STKFRM | ||
| 154 | blr | ||
| 155 | extab 2b,3b | ||
| 156 | |||
| 157 | /* Store FP reg N to double at *p. N is in r3, p in r4. */ | ||
| 158 | _GLOBAL(do_stfd) | ||
| 159 | PPC_STLU r1,-STKFRM(r1) | ||
| 160 | mflr r0 | ||
| 161 | PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1) | ||
| 162 | mfmsr r6 | ||
| 163 | ori r7,r6,MSR_FP | ||
| 164 | cmpwi cr7,r3,0 | ||
| 165 | mtmsrd r7 | ||
| 166 | isync | ||
| 167 | beq cr7,1f | ||
| 168 | stfd fr0,STKFRM-16(r1) | ||
| 169 | bl get_fpr | ||
| 170 | 1: li r9,-EFAULT | ||
| 171 | 2: stfd fr0,0(r4) | ||
| 172 | li r9,0 | ||
| 173 | 3: beq cr7,4f | ||
| 174 | lfd fr0,STKFRM-16(r1) | ||
| 175 | 4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1) | ||
| 176 | mtlr r0 | ||
| 177 | mtmsrd r6 | ||
| 178 | isync | ||
| 179 | mr r3,r9 | ||
| 180 | addi r1,r1,STKFRM | ||
| 181 | blr | ||
| 182 | extab 2b,3b | ||
| 183 | |||
| 184 | #ifdef CONFIG_ALTIVEC | ||
| 185 | /* Get the contents of vrN into vr0; N is in r3. */ | ||
| 186 | _GLOBAL(get_vr) | ||
| 187 | mflr r0 | ||
| 188 | rlwinm r3,r3,3,0xf8 | ||
| 189 | bcl 20,31,1f | ||
| 190 | blr /* vr0 is already in vr0 */ | ||
| 191 | nop | ||
| 192 | reg = 1 | ||
| 193 | .rept 31 | ||
| 194 | vor vr0,reg,reg /* assembler doesn't know vmr? */ | ||
| 195 | blr | ||
| 196 | reg = reg + 1 | ||
| 197 | .endr | ||
| 198 | 1: mflr r5 | ||
| 199 | add r5,r3,r5 | ||
| 200 | mtctr r5 | ||
| 201 | mtlr r0 | ||
| 202 | bctr | ||
| 203 | |||
| 204 | /* Put the contents of vr0 into vrN; N is in r3. */ | ||
| 205 | _GLOBAL(put_vr) | ||
| 206 | mflr r0 | ||
| 207 | rlwinm r3,r3,3,0xf8 | ||
| 208 | bcl 20,31,1f | ||
| 209 | blr /* vr0 is already in vr0 */ | ||
| 210 | nop | ||
| 211 | reg = 1 | ||
| 212 | .rept 31 | ||
| 213 | vor reg,vr0,vr0 | ||
| 214 | blr | ||
| 215 | reg = reg + 1 | ||
| 216 | .endr | ||
| 217 | 1: mflr r5 | ||
| 218 | add r5,r3,r5 | ||
| 219 | mtctr r5 | ||
| 220 | mtlr r0 | ||
| 221 | bctr | ||
| 222 | |||
| 223 | /* Load vector reg N from *p. N is in r3, p in r4. */ | ||
| 224 | _GLOBAL(do_lvx) | ||
| 225 | PPC_STLU r1,-STKFRM(r1) | ||
| 226 | mflr r0 | ||
| 227 | PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1) | ||
| 228 | mfmsr r6 | ||
| 229 | oris r7,r6,MSR_VEC@h | ||
| 230 | cmpwi cr7,r3,0 | ||
| 231 | li r8,STKFRM-16 | ||
| 232 | mtmsrd r7 | ||
| 233 | isync | ||
| 234 | beq cr7,1f | ||
| 235 | stvx vr0,r1,r8 | ||
| 236 | 1: li r9,-EFAULT | ||
| 237 | 2: lvx vr0,0,r4 | ||
| 238 | li r9,0 | ||
| 239 | 3: beq cr7,4f | ||
| 240 | bl put_vr | ||
| 241 | lvx vr0,r1,r8 | ||
| 242 | 4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1) | ||
| 243 | mtlr r0 | ||
| 244 | mtmsrd r6 | ||
| 245 | isync | ||
| 246 | mr r3,r9 | ||
| 247 | addi r1,r1,STKFRM | ||
| 248 | blr | ||
| 249 | extab 2b,3b | ||
| 250 | |||
| 251 | /* Store vector reg N to *p. N is in r3, p in r4. */ | ||
| 252 | _GLOBAL(do_stvx) | ||
| 253 | PPC_STLU r1,-STKFRM(r1) | ||
| 254 | mflr r0 | ||
| 255 | PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1) | ||
| 256 | mfmsr r6 | ||
| 257 | oris r7,r6,MSR_VEC@h | ||
| 258 | cmpwi cr7,r3,0 | ||
| 259 | li r8,STKFRM-16 | ||
| 260 | mtmsrd r7 | ||
| 261 | isync | ||
| 262 | beq cr7,1f | ||
| 263 | stvx vr0,r1,r8 | ||
| 264 | bl get_vr | ||
| 265 | 1: li r9,-EFAULT | ||
| 266 | 2: stvx vr0,0,r4 | ||
| 267 | li r9,0 | ||
| 268 | 3: beq cr7,4f | ||
| 269 | lvx vr0,r1,r8 | ||
| 270 | 4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1) | ||
| 271 | mtlr r0 | ||
| 272 | mtmsrd r6 | ||
| 273 | isync | ||
| 274 | mr r3,r9 | ||
| 275 | addi r1,r1,STKFRM | ||
| 276 | blr | ||
| 277 | extab 2b,3b | ||
| 278 | #endif /* CONFIG_ALTIVEC */ | ||
| 279 | |||
| 280 | #ifdef CONFIG_VSX | ||
| 281 | /* Get the contents of vsrN into vsr0; N is in r3. */ | ||
| 282 | _GLOBAL(get_vsr) | ||
| 283 | mflr r0 | ||
| 284 | rlwinm r3,r3,3,0x1f8 | ||
| 285 | bcl 20,31,1f | ||
| 286 | blr /* vsr0 is already in vsr0 */ | ||
| 287 | nop | ||
| 288 | reg = 1 | ||
| 289 | .rept 63 | ||
| 290 | XXLOR(0,reg,reg) | ||
| 291 | blr | ||
| 292 | reg = reg + 1 | ||
| 293 | .endr | ||
| 294 | 1: mflr r5 | ||
| 295 | add r5,r3,r5 | ||
| 296 | mtctr r5 | ||
| 297 | mtlr r0 | ||
| 298 | bctr | ||
| 299 | |||
| 300 | /* Put the contents of vsr0 into vsrN; N is in r3. */ | ||
| 301 | _GLOBAL(put_vsr) | ||
| 302 | mflr r0 | ||
| 303 | rlwinm r3,r3,3,0x1f8 | ||
| 304 | bcl 20,31,1f | ||
| 305 | blr /* vr0 is already in vr0 */ | ||
| 306 | nop | ||
| 307 | reg = 1 | ||
| 308 | .rept 63 | ||
| 309 | XXLOR(reg,0,0) | ||
| 310 | blr | ||
| 311 | reg = reg + 1 | ||
| 312 | .endr | ||
| 313 | 1: mflr r5 | ||
| 314 | add r5,r3,r5 | ||
| 315 | mtctr r5 | ||
| 316 | mtlr r0 | ||
| 317 | bctr | ||
| 318 | |||
| 319 | /* Load VSX reg N from vector doubleword *p. N is in r3, p in r4. */ | ||
| 320 | _GLOBAL(do_lxvd2x) | ||
| 321 | PPC_STLU r1,-STKFRM(r1) | ||
| 322 | mflr r0 | ||
| 323 | PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1) | ||
| 324 | mfmsr r6 | ||
| 325 | oris r7,r6,MSR_VSX@h | ||
| 326 | cmpwi cr7,r3,0 | ||
| 327 | li r8,STKFRM-16 | ||
| 328 | mtmsrd r7 | ||
| 329 | isync | ||
| 330 | beq cr7,1f | ||
| 331 | STXVD2X(0,r1,r8) | ||
| 332 | 1: li r9,-EFAULT | ||
| 333 | 2: LXVD2X(0,0,r4) | ||
| 334 | li r9,0 | ||
| 335 | 3: beq cr7,4f | ||
| 336 | bl put_vsr | ||
| 337 | LXVD2X(0,r1,r8) | ||
| 338 | 4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1) | ||
| 339 | mtlr r0 | ||
| 340 | mtmsrd r6 | ||
| 341 | isync | ||
| 342 | mr r3,r9 | ||
| 343 | addi r1,r1,STKFRM | ||
| 344 | blr | ||
| 345 | extab 2b,3b | ||
| 346 | |||
| 347 | /* Store VSX reg N to vector doubleword *p. N is in r3, p in r4. */ | ||
| 348 | _GLOBAL(do_stxvd2x) | ||
| 349 | PPC_STLU r1,-STKFRM(r1) | ||
| 350 | mflr r0 | ||
| 351 | PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1) | ||
| 352 | mfmsr r6 | ||
| 353 | oris r7,r6,MSR_VSX@h | ||
| 354 | cmpwi cr7,r3,0 | ||
| 355 | li r8,STKFRM-16 | ||
| 356 | mtmsrd r7 | ||
| 357 | isync | ||
| 358 | beq cr7,1f | ||
| 359 | STXVD2X(0,r1,r8) | ||
| 360 | bl get_vsr | ||
| 361 | 1: li r9,-EFAULT | ||
| 362 | 2: STXVD2X(0,0,r4) | ||
| 363 | li r9,0 | ||
| 364 | 3: beq cr7,4f | ||
| 365 | LXVD2X(0,r1,r8) | ||
| 366 | 4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1) | ||
| 367 | mtlr r0 | ||
| 368 | mtmsrd r6 | ||
| 369 | isync | ||
| 370 | mr r3,r9 | ||
| 371 | addi r1,r1,STKFRM | ||
| 372 | blr | ||
| 373 | extab 2b,3b | ||
| 374 | |||
| 375 | #endif /* CONFIG_VSX */ | ||
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c index 13b7d54f185b..e0a9858d537e 100644 --- a/arch/powerpc/lib/sstep.c +++ b/arch/powerpc/lib/sstep.c | |||
| @@ -13,6 +13,8 @@ | |||
| 13 | #include <linux/ptrace.h> | 13 | #include <linux/ptrace.h> |
| 14 | #include <asm/sstep.h> | 14 | #include <asm/sstep.h> |
| 15 | #include <asm/processor.h> | 15 | #include <asm/processor.h> |
| 16 | #include <asm/uaccess.h> | ||
| 17 | #include <asm/cputable.h> | ||
| 16 | 18 | ||
| 17 | extern char system_call_common[]; | 19 | extern char system_call_common[]; |
| 18 | 20 | ||
| @@ -23,6 +25,23 @@ extern char system_call_common[]; | |||
| 23 | #define MSR_MASK 0x87c0ffff | 25 | #define MSR_MASK 0x87c0ffff |
| 24 | #endif | 26 | #endif |
| 25 | 27 | ||
| 28 | /* Bits in XER */ | ||
| 29 | #define XER_SO 0x80000000U | ||
| 30 | #define XER_OV 0x40000000U | ||
| 31 | #define XER_CA 0x20000000U | ||
| 32 | |||
| 33 | /* | ||
| 34 | * Functions in ldstfp.S | ||
| 35 | */ | ||
| 36 | extern int do_lfs(int rn, unsigned long ea); | ||
| 37 | extern int do_lfd(int rn, unsigned long ea); | ||
| 38 | extern int do_stfs(int rn, unsigned long ea); | ||
| 39 | extern int do_stfd(int rn, unsigned long ea); | ||
| 40 | extern int do_lvx(int rn, unsigned long ea); | ||
| 41 | extern int do_stvx(int rn, unsigned long ea); | ||
| 42 | extern int do_lxvd2x(int rn, unsigned long ea); | ||
| 43 | extern int do_stxvd2x(int rn, unsigned long ea); | ||
| 44 | |||
| 26 | /* | 45 | /* |
| 27 | * Determine whether a conditional branch instruction would branch. | 46 | * Determine whether a conditional branch instruction would branch. |
| 28 | */ | 47 | */ |
| @@ -46,16 +65,499 @@ static int __kprobes branch_taken(unsigned int instr, struct pt_regs *regs) | |||
| 46 | return 1; | 65 | return 1; |
| 47 | } | 66 | } |
| 48 | 67 | ||
| 68 | |||
| 69 | static long __kprobes address_ok(struct pt_regs *regs, unsigned long ea, int nb) | ||
| 70 | { | ||
| 71 | if (!user_mode(regs)) | ||
| 72 | return 1; | ||
| 73 | return __access_ok(ea, nb, USER_DS); | ||
| 74 | } | ||
| 75 | |||
| 76 | /* | ||
| 77 | * Calculate effective address for a D-form instruction | ||
| 78 | */ | ||
| 79 | static unsigned long __kprobes dform_ea(unsigned int instr, struct pt_regs *regs) | ||
| 80 | { | ||
| 81 | int ra; | ||
| 82 | unsigned long ea; | ||
| 83 | |||
| 84 | ra = (instr >> 16) & 0x1f; | ||
| 85 | ea = (signed short) instr; /* sign-extend */ | ||
| 86 | if (ra) { | ||
| 87 | ea += regs->gpr[ra]; | ||
| 88 | if (instr & 0x04000000) /* update forms */ | ||
| 89 | regs->gpr[ra] = ea; | ||
| 90 | } | ||
| 91 | #ifdef __powerpc64__ | ||
| 92 | if (!(regs->msr & MSR_SF)) | ||
| 93 | ea &= 0xffffffffUL; | ||
| 94 | #endif | ||
| 95 | return ea; | ||
| 96 | } | ||
| 97 | |||
| 98 | #ifdef __powerpc64__ | ||
| 99 | /* | ||
| 100 | * Calculate effective address for a DS-form instruction | ||
| 101 | */ | ||
| 102 | static unsigned long __kprobes dsform_ea(unsigned int instr, struct pt_regs *regs) | ||
| 103 | { | ||
| 104 | int ra; | ||
| 105 | unsigned long ea; | ||
| 106 | |||
| 107 | ra = (instr >> 16) & 0x1f; | ||
| 108 | ea = (signed short) (instr & ~3); /* sign-extend */ | ||
| 109 | if (ra) { | ||
| 110 | ea += regs->gpr[ra]; | ||
| 111 | if ((instr & 3) == 1) /* update forms */ | ||
| 112 | regs->gpr[ra] = ea; | ||
| 113 | } | ||
| 114 | if (!(regs->msr & MSR_SF)) | ||
| 115 | ea &= 0xffffffffUL; | ||
| 116 | return ea; | ||
| 117 | } | ||
| 118 | #endif /* __powerpc64 */ | ||
| 119 | |||
| 120 | /* | ||
| 121 | * Calculate effective address for an X-form instruction | ||
| 122 | */ | ||
| 123 | static unsigned long __kprobes xform_ea(unsigned int instr, struct pt_regs *regs, | ||
| 124 | int do_update) | ||
| 125 | { | ||
| 126 | int ra, rb; | ||
| 127 | unsigned long ea; | ||
| 128 | |||
| 129 | ra = (instr >> 16) & 0x1f; | ||
| 130 | rb = (instr >> 11) & 0x1f; | ||
| 131 | ea = regs->gpr[rb]; | ||
| 132 | if (ra) { | ||
| 133 | ea += regs->gpr[ra]; | ||
| 134 | if (do_update) /* update forms */ | ||
| 135 | regs->gpr[ra] = ea; | ||
| 136 | } | ||
| 137 | #ifdef __powerpc64__ | ||
| 138 | if (!(regs->msr & MSR_SF)) | ||
| 139 | ea &= 0xffffffffUL; | ||
| 140 | #endif | ||
| 141 | return ea; | ||
| 142 | } | ||
| 143 | |||
| 144 | /* | ||
| 145 | * Return the largest power of 2, not greater than sizeof(unsigned long), | ||
| 146 | * such that x is a multiple of it. | ||
| 147 | */ | ||
| 148 | static inline unsigned long max_align(unsigned long x) | ||
| 149 | { | ||
| 150 | x |= sizeof(unsigned long); | ||
| 151 | return x & -x; /* isolates rightmost bit */ | ||
| 152 | } | ||
| 153 | |||
| 154 | |||
| 155 | static inline unsigned long byterev_2(unsigned long x) | ||
| 156 | { | ||
| 157 | return ((x >> 8) & 0xff) | ((x & 0xff) << 8); | ||
| 158 | } | ||
| 159 | |||
| 160 | static inline unsigned long byterev_4(unsigned long x) | ||
| 161 | { | ||
| 162 | return ((x >> 24) & 0xff) | ((x >> 8) & 0xff00) | | ||
| 163 | ((x & 0xff00) << 8) | ((x & 0xff) << 24); | ||
| 164 | } | ||
| 165 | |||
| 166 | #ifdef __powerpc64__ | ||
| 167 | static inline unsigned long byterev_8(unsigned long x) | ||
| 168 | { | ||
| 169 | return (byterev_4(x) << 32) | byterev_4(x >> 32); | ||
| 170 | } | ||
| 171 | #endif | ||
| 172 | |||
| 173 | static int __kprobes read_mem_aligned(unsigned long *dest, unsigned long ea, | ||
| 174 | int nb) | ||
| 175 | { | ||
| 176 | int err = 0; | ||
| 177 | unsigned long x = 0; | ||
| 178 | |||
| 179 | switch (nb) { | ||
| 180 | case 1: | ||
| 181 | err = __get_user(x, (unsigned char __user *) ea); | ||
| 182 | break; | ||
| 183 | case 2: | ||
| 184 | err = __get_user(x, (unsigned short __user *) ea); | ||
| 185 | break; | ||
| 186 | case 4: | ||
| 187 | err = __get_user(x, (unsigned int __user *) ea); | ||
| 188 | break; | ||
| 189 | #ifdef __powerpc64__ | ||
| 190 | case 8: | ||
| 191 | err = __get_user(x, (unsigned long __user *) ea); | ||
| 192 | break; | ||
| 193 | #endif | ||
| 194 | } | ||
| 195 | if (!err) | ||
| 196 | *dest = x; | ||
| 197 | return err; | ||
| 198 | } | ||
| 199 | |||
| 200 | static int __kprobes read_mem_unaligned(unsigned long *dest, unsigned long ea, | ||
| 201 | int nb, struct pt_regs *regs) | ||
| 202 | { | ||
| 203 | int err; | ||
| 204 | unsigned long x, b, c; | ||
| 205 | |||
| 206 | /* unaligned, do this in pieces */ | ||
| 207 | x = 0; | ||
| 208 | for (; nb > 0; nb -= c) { | ||
| 209 | c = max_align(ea); | ||
| 210 | if (c > nb) | ||
| 211 | c = max_align(nb); | ||
| 212 | err = read_mem_aligned(&b, ea, c); | ||
| 213 | if (err) | ||
| 214 | return err; | ||
| 215 | x = (x << (8 * c)) + b; | ||
| 216 | ea += c; | ||
| 217 | } | ||
| 218 | *dest = x; | ||
| 219 | return 0; | ||
| 220 | } | ||
| 221 | |||
| 222 | /* | ||
| 223 | * Read memory at address ea for nb bytes, return 0 for success | ||
| 224 | * or -EFAULT if an error occurred. | ||
| 225 | */ | ||
| 226 | static int __kprobes read_mem(unsigned long *dest, unsigned long ea, int nb, | ||
| 227 | struct pt_regs *regs) | ||
| 228 | { | ||
| 229 | if (!address_ok(regs, ea, nb)) | ||
| 230 | return -EFAULT; | ||
| 231 | if ((ea & (nb - 1)) == 0) | ||
| 232 | return read_mem_aligned(dest, ea, nb); | ||
| 233 | return read_mem_unaligned(dest, ea, nb, regs); | ||
| 234 | } | ||
| 235 | |||
| 236 | static int __kprobes write_mem_aligned(unsigned long val, unsigned long ea, | ||
| 237 | int nb) | ||
| 238 | { | ||
| 239 | int err = 0; | ||
| 240 | |||
| 241 | switch (nb) { | ||
| 242 | case 1: | ||
| 243 | err = __put_user(val, (unsigned char __user *) ea); | ||
| 244 | break; | ||
| 245 | case 2: | ||
| 246 | err = __put_user(val, (unsigned short __user *) ea); | ||
| 247 | break; | ||
| 248 | case 4: | ||
| 249 | err = __put_user(val, (unsigned int __user *) ea); | ||
| 250 | break; | ||
| 251 | #ifdef __powerpc64__ | ||
| 252 | case 8: | ||
| 253 | err = __put_user(val, (unsigned long __user *) ea); | ||
| 254 | break; | ||
| 255 | #endif | ||
| 256 | } | ||
| 257 | return err; | ||
| 258 | } | ||
| 259 | |||
| 260 | static int __kprobes write_mem_unaligned(unsigned long val, unsigned long ea, | ||
| 261 | int nb, struct pt_regs *regs) | ||
| 262 | { | ||
| 263 | int err; | ||
| 264 | unsigned long c; | ||
| 265 | |||
| 266 | /* unaligned or little-endian, do this in pieces */ | ||
| 267 | for (; nb > 0; nb -= c) { | ||
| 268 | c = max_align(ea); | ||
| 269 | if (c > nb) | ||
| 270 | c = max_align(nb); | ||
| 271 | err = write_mem_aligned(val >> (nb - c) * 8, ea, c); | ||
| 272 | if (err) | ||
| 273 | return err; | ||
| 274 | ++ea; | ||
| 275 | } | ||
| 276 | return 0; | ||
| 277 | } | ||
| 278 | |||
| 279 | /* | ||
| 280 | * Write memory at address ea for nb bytes, return 0 for success | ||
| 281 | * or -EFAULT if an error occurred. | ||
| 282 | */ | ||
| 283 | static int __kprobes write_mem(unsigned long val, unsigned long ea, int nb, | ||
| 284 | struct pt_regs *regs) | ||
| 285 | { | ||
| 286 | if (!address_ok(regs, ea, nb)) | ||
| 287 | return -EFAULT; | ||
| 288 | if ((ea & (nb - 1)) == 0) | ||
| 289 | return write_mem_aligned(val, ea, nb); | ||
| 290 | return write_mem_unaligned(val, ea, nb, regs); | ||
| 291 | } | ||
| 292 | |||
| 49 | /* | 293 | /* |
| 50 | * Emulate instructions that cause a transfer of control. | 294 | * Check the address and alignment, and call func to do the actual |
| 295 | * load or store. | ||
| 296 | */ | ||
| 297 | static int __kprobes do_fp_load(int rn, int (*func)(int, unsigned long), | ||
| 298 | unsigned long ea, int nb, | ||
| 299 | struct pt_regs *regs) | ||
| 300 | { | ||
| 301 | int err; | ||
| 302 | unsigned long val[sizeof(double) / sizeof(long)]; | ||
| 303 | unsigned long ptr; | ||
| 304 | |||
| 305 | if (!address_ok(regs, ea, nb)) | ||
| 306 | return -EFAULT; | ||
| 307 | if ((ea & 3) == 0) | ||
| 308 | return (*func)(rn, ea); | ||
| 309 | ptr = (unsigned long) &val[0]; | ||
| 310 | if (sizeof(unsigned long) == 8 || nb == 4) { | ||
| 311 | err = read_mem_unaligned(&val[0], ea, nb, regs); | ||
| 312 | ptr += sizeof(unsigned long) - nb; | ||
| 313 | } else { | ||
| 314 | /* reading a double on 32-bit */ | ||
| 315 | err = read_mem_unaligned(&val[0], ea, 4, regs); | ||
| 316 | if (!err) | ||
| 317 | err = read_mem_unaligned(&val[1], ea + 4, 4, regs); | ||
| 318 | } | ||
| 319 | if (err) | ||
| 320 | return err; | ||
| 321 | return (*func)(rn, ptr); | ||
| 322 | } | ||
| 323 | |||
| 324 | static int __kprobes do_fp_store(int rn, int (*func)(int, unsigned long), | ||
| 325 | unsigned long ea, int nb, | ||
| 326 | struct pt_regs *regs) | ||
| 327 | { | ||
| 328 | int err; | ||
| 329 | unsigned long val[sizeof(double) / sizeof(long)]; | ||
| 330 | unsigned long ptr; | ||
| 331 | |||
| 332 | if (!address_ok(regs, ea, nb)) | ||
| 333 | return -EFAULT; | ||
| 334 | if ((ea & 3) == 0) | ||
| 335 | return (*func)(rn, ea); | ||
| 336 | ptr = (unsigned long) &val[0]; | ||
| 337 | if (sizeof(unsigned long) == 8 || nb == 4) { | ||
| 338 | ptr += sizeof(unsigned long) - nb; | ||
| 339 | err = (*func)(rn, ptr); | ||
| 340 | if (err) | ||
| 341 | return err; | ||
| 342 | err = write_mem_unaligned(val[0], ea, nb, regs); | ||
| 343 | } else { | ||
| 344 | /* writing a double on 32-bit */ | ||
| 345 | err = (*func)(rn, ptr); | ||
| 346 | if (err) | ||
| 347 | return err; | ||
| 348 | err = write_mem_unaligned(val[0], ea, 4, regs); | ||
| 349 | if (!err) | ||
| 350 | err = write_mem_unaligned(val[1], ea + 4, 4, regs); | ||
| 351 | } | ||
| 352 | return err; | ||
| 353 | } | ||
| 354 | |||
| 355 | #ifdef CONFIG_ALTIVEC | ||
| 356 | /* For Altivec/VMX, no need to worry about alignment */ | ||
| 357 | static int __kprobes do_vec_load(int rn, int (*func)(int, unsigned long), | ||
| 358 | unsigned long ea, struct pt_regs *regs) | ||
| 359 | { | ||
| 360 | if (!address_ok(regs, ea & ~0xfUL, 16)) | ||
| 361 | return -EFAULT; | ||
| 362 | return (*func)(rn, ea); | ||
| 363 | } | ||
| 364 | |||
| 365 | static int __kprobes do_vec_store(int rn, int (*func)(int, unsigned long), | ||
| 366 | unsigned long ea, struct pt_regs *regs) | ||
| 367 | { | ||
| 368 | if (!address_ok(regs, ea & ~0xfUL, 16)) | ||
| 369 | return -EFAULT; | ||
| 370 | return (*func)(rn, ea); | ||
| 371 | } | ||
| 372 | #endif /* CONFIG_ALTIVEC */ | ||
| 373 | |||
| 374 | #ifdef CONFIG_VSX | ||
| 375 | static int __kprobes do_vsx_load(int rn, int (*func)(int, unsigned long), | ||
| 376 | unsigned long ea, struct pt_regs *regs) | ||
| 377 | { | ||
| 378 | int err; | ||
| 379 | unsigned long val[2]; | ||
| 380 | |||
| 381 | if (!address_ok(regs, ea, 16)) | ||
| 382 | return -EFAULT; | ||
| 383 | if ((ea & 3) == 0) | ||
| 384 | return (*func)(rn, ea); | ||
| 385 | err = read_mem_unaligned(&val[0], ea, 8, regs); | ||
| 386 | if (!err) | ||
| 387 | err = read_mem_unaligned(&val[1], ea + 8, 8, regs); | ||
| 388 | if (!err) | ||
| 389 | err = (*func)(rn, (unsigned long) &val[0]); | ||
| 390 | return err; | ||
| 391 | } | ||
| 392 | |||
| 393 | static int __kprobes do_vsx_store(int rn, int (*func)(int, unsigned long), | ||
| 394 | unsigned long ea, struct pt_regs *regs) | ||
| 395 | { | ||
| 396 | int err; | ||
| 397 | unsigned long val[2]; | ||
| 398 | |||
| 399 | if (!address_ok(regs, ea, 16)) | ||
| 400 | return -EFAULT; | ||
| 401 | if ((ea & 3) == 0) | ||
| 402 | return (*func)(rn, ea); | ||
| 403 | err = (*func)(rn, (unsigned long) &val[0]); | ||
| 404 | if (err) | ||
| 405 | return err; | ||
| 406 | err = write_mem_unaligned(val[0], ea, 8, regs); | ||
| 407 | if (!err) | ||
| 408 | err = write_mem_unaligned(val[1], ea + 8, 8, regs); | ||
| 409 | return err; | ||
| 410 | } | ||
| 411 | #endif /* CONFIG_VSX */ | ||
| 412 | |||
| 413 | #define __put_user_asmx(x, addr, err, op, cr) \ | ||
| 414 | __asm__ __volatile__( \ | ||
| 415 | "1: " op " %2,0,%3\n" \ | ||
| 416 | " mfcr %1\n" \ | ||
| 417 | "2:\n" \ | ||
| 418 | ".section .fixup,\"ax\"\n" \ | ||
| 419 | "3: li %0,%4\n" \ | ||
| 420 | " b 2b\n" \ | ||
| 421 | ".previous\n" \ | ||
| 422 | ".section __ex_table,\"a\"\n" \ | ||
| 423 | PPC_LONG_ALIGN "\n" \ | ||
| 424 | PPC_LONG "1b,3b\n" \ | ||
| 425 | ".previous" \ | ||
| 426 | : "=r" (err), "=r" (cr) \ | ||
| 427 | : "r" (x), "r" (addr), "i" (-EFAULT), "0" (err)) | ||
| 428 | |||
| 429 | #define __get_user_asmx(x, addr, err, op) \ | ||
| 430 | __asm__ __volatile__( \ | ||
| 431 | "1: "op" %1,0,%2\n" \ | ||
| 432 | "2:\n" \ | ||
| 433 | ".section .fixup,\"ax\"\n" \ | ||
| 434 | "3: li %0,%3\n" \ | ||
| 435 | " b 2b\n" \ | ||
| 436 | ".previous\n" \ | ||
| 437 | ".section __ex_table,\"a\"\n" \ | ||
| 438 | PPC_LONG_ALIGN "\n" \ | ||
| 439 | PPC_LONG "1b,3b\n" \ | ||
| 440 | ".previous" \ | ||
| 441 | : "=r" (err), "=r" (x) \ | ||
| 442 | : "r" (addr), "i" (-EFAULT), "0" (err)) | ||
| 443 | |||
| 444 | #define __cacheop_user_asmx(addr, err, op) \ | ||
| 445 | __asm__ __volatile__( \ | ||
| 446 | "1: "op" 0,%1\n" \ | ||
| 447 | "2:\n" \ | ||
| 448 | ".section .fixup,\"ax\"\n" \ | ||
| 449 | "3: li %0,%3\n" \ | ||
| 450 | " b 2b\n" \ | ||
| 451 | ".previous\n" \ | ||
| 452 | ".section __ex_table,\"a\"\n" \ | ||
| 453 | PPC_LONG_ALIGN "\n" \ | ||
| 454 | PPC_LONG "1b,3b\n" \ | ||
| 455 | ".previous" \ | ||
| 456 | : "=r" (err) \ | ||
| 457 | : "r" (addr), "i" (-EFAULT), "0" (err)) | ||
| 458 | |||
| 459 | static void __kprobes set_cr0(struct pt_regs *regs, int rd) | ||
| 460 | { | ||
| 461 | long val = regs->gpr[rd]; | ||
| 462 | |||
| 463 | regs->ccr = (regs->ccr & 0x0fffffff) | ((regs->xer >> 3) & 0x10000000); | ||
| 464 | #ifdef __powerpc64__ | ||
| 465 | if (!(regs->msr & MSR_SF)) | ||
| 466 | val = (int) val; | ||
| 467 | #endif | ||
| 468 | if (val < 0) | ||
| 469 | regs->ccr |= 0x80000000; | ||
| 470 | else if (val > 0) | ||
| 471 | regs->ccr |= 0x40000000; | ||
| 472 | else | ||
| 473 | regs->ccr |= 0x20000000; | ||
| 474 | } | ||
| 475 | |||
| 476 | static void __kprobes add_with_carry(struct pt_regs *regs, int rd, | ||
| 477 | unsigned long val1, unsigned long val2, | ||
| 478 | unsigned long carry_in) | ||
| 479 | { | ||
| 480 | unsigned long val = val1 + val2; | ||
| 481 | |||
| 482 | if (carry_in) | ||
| 483 | ++val; | ||
| 484 | regs->gpr[rd] = val; | ||
| 485 | #ifdef __powerpc64__ | ||
| 486 | if (!(regs->msr & MSR_SF)) { | ||
| 487 | val = (unsigned int) val; | ||
| 488 | val1 = (unsigned int) val1; | ||
| 489 | } | ||
| 490 | #endif | ||
| 491 | if (val < val1 || (carry_in && val == val1)) | ||
| 492 | regs->xer |= XER_CA; | ||
| 493 | else | ||
| 494 | regs->xer &= ~XER_CA; | ||
| 495 | } | ||
| 496 | |||
| 497 | static void __kprobes do_cmp_signed(struct pt_regs *regs, long v1, long v2, | ||
| 498 | int crfld) | ||
| 499 | { | ||
| 500 | unsigned int crval, shift; | ||
| 501 | |||
| 502 | crval = (regs->xer >> 31) & 1; /* get SO bit */ | ||
| 503 | if (v1 < v2) | ||
| 504 | crval |= 8; | ||
| 505 | else if (v1 > v2) | ||
| 506 | crval |= 4; | ||
| 507 | else | ||
| 508 | crval |= 2; | ||
| 509 | shift = (7 - crfld) * 4; | ||
| 510 | regs->ccr = (regs->ccr & ~(0xf << shift)) | (crval << shift); | ||
| 511 | } | ||
| 512 | |||
| 513 | static void __kprobes do_cmp_unsigned(struct pt_regs *regs, unsigned long v1, | ||
| 514 | unsigned long v2, int crfld) | ||
| 515 | { | ||
| 516 | unsigned int crval, shift; | ||
| 517 | |||
| 518 | crval = (regs->xer >> 31) & 1; /* get SO bit */ | ||
| 519 | if (v1 < v2) | ||
| 520 | crval |= 8; | ||
| 521 | else if (v1 > v2) | ||
| 522 | crval |= 4; | ||
| 523 | else | ||
| 524 | crval |= 2; | ||
| 525 | shift = (7 - crfld) * 4; | ||
| 526 | regs->ccr = (regs->ccr & ~(0xf << shift)) | (crval << shift); | ||
| 527 | } | ||
| 528 | |||
| 529 | /* | ||
| 530 | * Elements of 32-bit rotate and mask instructions. | ||
| 531 | */ | ||
| 532 | #define MASK32(mb, me) ((0xffffffffUL >> (mb)) + \ | ||
| 533 | ((signed long)-0x80000000L >> (me)) + ((me) >= (mb))) | ||
| 534 | #ifdef __powerpc64__ | ||
| 535 | #define MASK64_L(mb) (~0UL >> (mb)) | ||
| 536 | #define MASK64_R(me) ((signed long)-0x8000000000000000L >> (me)) | ||
| 537 | #define MASK64(mb, me) (MASK64_L(mb) + MASK64_R(me) + ((me) >= (mb))) | ||
| 538 | #define DATA32(x) (((x) & 0xffffffffUL) | (((x) & 0xffffffffUL) << 32)) | ||
| 539 | #else | ||
| 540 | #define DATA32(x) (x) | ||
| 541 | #endif | ||
| 542 | #define ROTATE(x, n) ((n) ? (((x) << (n)) | ((x) >> (8 * sizeof(long) - (n)))) : (x)) | ||
| 543 | |||
| 544 | /* | ||
| 545 | * Emulate instructions that cause a transfer of control, | ||
| 546 | * loads and stores, and a few other instructions. | ||
| 51 | * Returns 1 if the step was emulated, 0 if not, | 547 | * Returns 1 if the step was emulated, 0 if not, |
| 52 | * or -1 if the instruction is one that should not be stepped, | 548 | * or -1 if the instruction is one that should not be stepped, |
| 53 | * such as an rfid, or a mtmsrd that would clear MSR_RI. | 549 | * such as an rfid, or a mtmsrd that would clear MSR_RI. |
| 54 | */ | 550 | */ |
| 55 | int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) | 551 | int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) |
| 56 | { | 552 | { |
| 57 | unsigned int opcode, rs, rb, rd, spr; | 553 | unsigned int opcode, ra, rb, rd, spr, u; |
| 58 | unsigned long int imm; | 554 | unsigned long int imm; |
| 555 | unsigned long int val, val2; | ||
| 556 | unsigned long int ea; | ||
| 557 | unsigned int cr, mb, me, sh; | ||
| 558 | int err; | ||
| 559 | unsigned long old_ra; | ||
| 560 | long ival; | ||
| 59 | 561 | ||
| 60 | opcode = instr >> 26; | 562 | opcode = instr >> 26; |
| 61 | switch (opcode) { | 563 | switch (opcode) { |
| @@ -78,7 +580,13 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) | |||
| 78 | * entry code works. If that is changed, this will | 580 | * entry code works. If that is changed, this will |
| 79 | * need to be changed also. | 581 | * need to be changed also. |
| 80 | */ | 582 | */ |
| 583 | if (regs->gpr[0] == 0x1ebe && | ||
| 584 | cpu_has_feature(CPU_FTR_REAL_LE)) { | ||
| 585 | regs->msr ^= MSR_LE; | ||
| 586 | goto instr_done; | ||
| 587 | } | ||
| 81 | regs->gpr[9] = regs->gpr[13]; | 588 | regs->gpr[9] = regs->gpr[13]; |
| 589 | regs->gpr[10] = MSR_KERNEL; | ||
| 82 | regs->gpr[11] = regs->nip + 4; | 590 | regs->gpr[11] = regs->nip + 4; |
| 83 | regs->gpr[12] = regs->msr & MSR_MASK; | 591 | regs->gpr[12] = regs->msr & MSR_MASK; |
| 84 | regs->gpr[13] = (unsigned long) get_paca(); | 592 | regs->gpr[13] = (unsigned long) get_paca(); |
| @@ -102,9 +610,9 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) | |||
| 102 | regs->nip = imm; | 610 | regs->nip = imm; |
| 103 | return 1; | 611 | return 1; |
| 104 | case 19: | 612 | case 19: |
| 105 | switch (instr & 0x7fe) { | 613 | switch ((instr >> 1) & 0x3ff) { |
| 106 | case 0x20: /* bclr */ | 614 | case 16: /* bclr */ |
| 107 | case 0x420: /* bcctr */ | 615 | case 528: /* bcctr */ |
| 108 | imm = (instr & 0x400)? regs->ctr: regs->link; | 616 | imm = (instr & 0x400)? regs->ctr: regs->link; |
| 109 | regs->nip += 4; | 617 | regs->nip += 4; |
| 110 | if ((regs->msr & MSR_SF) == 0) { | 618 | if ((regs->msr & MSR_SF) == 0) { |
| @@ -116,30 +624,233 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) | |||
| 116 | if (branch_taken(instr, regs)) | 624 | if (branch_taken(instr, regs)) |
| 117 | regs->nip = imm; | 625 | regs->nip = imm; |
| 118 | return 1; | 626 | return 1; |
| 119 | case 0x24: /* rfid, scary */ | 627 | |
| 628 | case 18: /* rfid, scary */ | ||
| 120 | return -1; | 629 | return -1; |
| 630 | |||
| 631 | case 150: /* isync */ | ||
| 632 | isync(); | ||
| 633 | goto instr_done; | ||
| 634 | |||
| 635 | case 33: /* crnor */ | ||
| 636 | case 129: /* crandc */ | ||
| 637 | case 193: /* crxor */ | ||
| 638 | case 225: /* crnand */ | ||
| 639 | case 257: /* crand */ | ||
| 640 | case 289: /* creqv */ | ||
| 641 | case 417: /* crorc */ | ||
| 642 | case 449: /* cror */ | ||
| 643 | ra = (instr >> 16) & 0x1f; | ||
| 644 | rb = (instr >> 11) & 0x1f; | ||
| 645 | rd = (instr >> 21) & 0x1f; | ||
| 646 | ra = (regs->ccr >> (31 - ra)) & 1; | ||
| 647 | rb = (regs->ccr >> (31 - rb)) & 1; | ||
| 648 | val = (instr >> (6 + ra * 2 + rb)) & 1; | ||
| 649 | regs->ccr = (regs->ccr & ~(1UL << (31 - rd))) | | ||
| 650 | (val << (31 - rd)); | ||
| 651 | goto instr_done; | ||
| 652 | } | ||
| 653 | break; | ||
| 654 | case 31: | ||
| 655 | switch ((instr >> 1) & 0x3ff) { | ||
| 656 | case 598: /* sync */ | ||
| 657 | #ifdef __powerpc64__ | ||
| 658 | switch ((instr >> 21) & 3) { | ||
| 659 | case 1: /* lwsync */ | ||
| 660 | asm volatile("lwsync" : : : "memory"); | ||
| 661 | goto instr_done; | ||
| 662 | case 2: /* ptesync */ | ||
| 663 | asm volatile("ptesync" : : : "memory"); | ||
| 664 | goto instr_done; | ||
| 665 | } | ||
| 666 | #endif | ||
| 667 | mb(); | ||
| 668 | goto instr_done; | ||
| 669 | |||
| 670 | case 854: /* eieio */ | ||
| 671 | eieio(); | ||
| 672 | goto instr_done; | ||
| 673 | } | ||
| 674 | break; | ||
| 675 | } | ||
| 676 | |||
| 677 | /* Following cases refer to regs->gpr[], so we need all regs */ | ||
| 678 | if (!FULL_REGS(regs)) | ||
| 679 | return 0; | ||
| 680 | |||
| 681 | rd = (instr >> 21) & 0x1f; | ||
| 682 | ra = (instr >> 16) & 0x1f; | ||
| 683 | rb = (instr >> 11) & 0x1f; | ||
| 684 | |||
| 685 | switch (opcode) { | ||
| 686 | case 7: /* mulli */ | ||
| 687 | regs->gpr[rd] = regs->gpr[ra] * (short) instr; | ||
| 688 | goto instr_done; | ||
| 689 | |||
| 690 | case 8: /* subfic */ | ||
| 691 | imm = (short) instr; | ||
| 692 | add_with_carry(regs, rd, ~regs->gpr[ra], imm, 1); | ||
| 693 | goto instr_done; | ||
| 694 | |||
| 695 | case 10: /* cmpli */ | ||
| 696 | imm = (unsigned short) instr; | ||
| 697 | val = regs->gpr[ra]; | ||
| 698 | #ifdef __powerpc64__ | ||
| 699 | if ((rd & 1) == 0) | ||
| 700 | val = (unsigned int) val; | ||
| 701 | #endif | ||
| 702 | do_cmp_unsigned(regs, val, imm, rd >> 2); | ||
| 703 | goto instr_done; | ||
| 704 | |||
| 705 | case 11: /* cmpi */ | ||
| 706 | imm = (short) instr; | ||
| 707 | val = regs->gpr[ra]; | ||
| 708 | #ifdef __powerpc64__ | ||
| 709 | if ((rd & 1) == 0) | ||
| 710 | val = (int) val; | ||
| 711 | #endif | ||
| 712 | do_cmp_signed(regs, val, imm, rd >> 2); | ||
| 713 | goto instr_done; | ||
| 714 | |||
| 715 | case 12: /* addic */ | ||
| 716 | imm = (short) instr; | ||
| 717 | add_with_carry(regs, rd, regs->gpr[ra], imm, 0); | ||
| 718 | goto instr_done; | ||
| 719 | |||
| 720 | case 13: /* addic. */ | ||
| 721 | imm = (short) instr; | ||
| 722 | add_with_carry(regs, rd, regs->gpr[ra], imm, 0); | ||
| 723 | set_cr0(regs, rd); | ||
| 724 | goto instr_done; | ||
| 725 | |||
| 726 | case 14: /* addi */ | ||
| 727 | imm = (short) instr; | ||
| 728 | if (ra) | ||
| 729 | imm += regs->gpr[ra]; | ||
| 730 | regs->gpr[rd] = imm; | ||
| 731 | goto instr_done; | ||
| 732 | |||
| 733 | case 15: /* addis */ | ||
| 734 | imm = ((short) instr) << 16; | ||
| 735 | if (ra) | ||
| 736 | imm += regs->gpr[ra]; | ||
| 737 | regs->gpr[rd] = imm; | ||
| 738 | goto instr_done; | ||
| 739 | |||
| 740 | case 20: /* rlwimi */ | ||
| 741 | mb = (instr >> 6) & 0x1f; | ||
| 742 | me = (instr >> 1) & 0x1f; | ||
| 743 | val = DATA32(regs->gpr[rd]); | ||
| 744 | imm = MASK32(mb, me); | ||
| 745 | regs->gpr[ra] = (regs->gpr[ra] & ~imm) | (ROTATE(val, rb) & imm); | ||
| 746 | goto logical_done; | ||
| 747 | |||
| 748 | case 21: /* rlwinm */ | ||
| 749 | mb = (instr >> 6) & 0x1f; | ||
| 750 | me = (instr >> 1) & 0x1f; | ||
| 751 | val = DATA32(regs->gpr[rd]); | ||
| 752 | regs->gpr[ra] = ROTATE(val, rb) & MASK32(mb, me); | ||
| 753 | goto logical_done; | ||
| 754 | |||
| 755 | case 23: /* rlwnm */ | ||
| 756 | mb = (instr >> 6) & 0x1f; | ||
| 757 | me = (instr >> 1) & 0x1f; | ||
| 758 | rb = regs->gpr[rb] & 0x1f; | ||
| 759 | val = DATA32(regs->gpr[rd]); | ||
| 760 | regs->gpr[ra] = ROTATE(val, rb) & MASK32(mb, me); | ||
| 761 | goto logical_done; | ||
| 762 | |||
| 763 | case 24: /* ori */ | ||
| 764 | imm = (unsigned short) instr; | ||
| 765 | regs->gpr[ra] = regs->gpr[rd] | imm; | ||
| 766 | goto instr_done; | ||
| 767 | |||
| 768 | case 25: /* oris */ | ||
| 769 | imm = (unsigned short) instr; | ||
| 770 | regs->gpr[ra] = regs->gpr[rd] | (imm << 16); | ||
| 771 | goto instr_done; | ||
| 772 | |||
| 773 | case 26: /* xori */ | ||
| 774 | imm = (unsigned short) instr; | ||
| 775 | regs->gpr[ra] = regs->gpr[rd] ^ imm; | ||
| 776 | goto instr_done; | ||
| 777 | |||
| 778 | case 27: /* xoris */ | ||
| 779 | imm = (unsigned short) instr; | ||
| 780 | regs->gpr[ra] = regs->gpr[rd] ^ (imm << 16); | ||
| 781 | goto instr_done; | ||
| 782 | |||
| 783 | case 28: /* andi. */ | ||
| 784 | imm = (unsigned short) instr; | ||
| 785 | regs->gpr[ra] = regs->gpr[rd] & imm; | ||
| 786 | set_cr0(regs, ra); | ||
| 787 | goto instr_done; | ||
| 788 | |||
| 789 | case 29: /* andis. */ | ||
| 790 | imm = (unsigned short) instr; | ||
| 791 | regs->gpr[ra] = regs->gpr[rd] & (imm << 16); | ||
| 792 | set_cr0(regs, ra); | ||
| 793 | goto instr_done; | ||
| 794 | |||
| 795 | #ifdef __powerpc64__ | ||
| 796 | case 30: /* rld* */ | ||
| 797 | mb = ((instr >> 6) & 0x1f) | (instr & 0x20); | ||
| 798 | val = regs->gpr[rd]; | ||
| 799 | if ((instr & 0x10) == 0) { | ||
| 800 | sh = rb | ((instr & 2) << 4); | ||
| 801 | val = ROTATE(val, sh); | ||
| 802 | switch ((instr >> 2) & 3) { | ||
| 803 | case 0: /* rldicl */ | ||
| 804 | regs->gpr[ra] = val & MASK64_L(mb); | ||
| 805 | goto logical_done; | ||
| 806 | case 1: /* rldicr */ | ||
| 807 | regs->gpr[ra] = val & MASK64_R(mb); | ||
| 808 | goto logical_done; | ||
| 809 | case 2: /* rldic */ | ||
| 810 | regs->gpr[ra] = val & MASK64(mb, 63 - sh); | ||
| 811 | goto logical_done; | ||
| 812 | case 3: /* rldimi */ | ||
| 813 | imm = MASK64(mb, 63 - sh); | ||
| 814 | regs->gpr[ra] = (regs->gpr[ra] & ~imm) | | ||
| 815 | (val & imm); | ||
| 816 | goto logical_done; | ||
| 817 | } | ||
| 818 | } else { | ||
| 819 | sh = regs->gpr[rb] & 0x3f; | ||
| 820 | val = ROTATE(val, sh); | ||
| 821 | switch ((instr >> 1) & 7) { | ||
| 822 | case 0: /* rldcl */ | ||
| 823 | regs->gpr[ra] = val & MASK64_L(mb); | ||
| 824 | goto logical_done; | ||
| 825 | case 1: /* rldcr */ | ||
| 826 | regs->gpr[ra] = val & MASK64_R(mb); | ||
| 827 | goto logical_done; | ||
| 828 | } | ||
| 121 | } | 829 | } |
| 830 | #endif | ||
| 831 | |||
| 122 | case 31: | 832 | case 31: |
| 123 | rd = (instr >> 21) & 0x1f; | 833 | switch ((instr >> 1) & 0x3ff) { |
| 124 | switch (instr & 0x7fe) { | 834 | case 83: /* mfmsr */ |
| 125 | case 0xa6: /* mfmsr */ | 835 | if (regs->msr & MSR_PR) |
| 836 | break; | ||
| 126 | regs->gpr[rd] = regs->msr & MSR_MASK; | 837 | regs->gpr[rd] = regs->msr & MSR_MASK; |
| 127 | regs->nip += 4; | 838 | goto instr_done; |
| 128 | if ((regs->msr & MSR_SF) == 0) | 839 | case 146: /* mtmsr */ |
| 129 | regs->nip &= 0xffffffffUL; | 840 | if (regs->msr & MSR_PR) |
| 130 | return 1; | 841 | break; |
| 131 | case 0x124: /* mtmsr */ | ||
| 132 | imm = regs->gpr[rd]; | 842 | imm = regs->gpr[rd]; |
| 133 | if ((imm & MSR_RI) == 0) | 843 | if ((imm & MSR_RI) == 0) |
| 134 | /* can't step mtmsr that would clear MSR_RI */ | 844 | /* can't step mtmsr that would clear MSR_RI */ |
| 135 | return -1; | 845 | return -1; |
| 136 | regs->msr = imm; | 846 | regs->msr = imm; |
| 137 | regs->nip += 4; | 847 | goto instr_done; |
| 138 | return 1; | ||
| 139 | #ifdef CONFIG_PPC64 | 848 | #ifdef CONFIG_PPC64 |
| 140 | case 0x164: /* mtmsrd */ | 849 | case 178: /* mtmsrd */ |
| 141 | /* only MSR_EE and MSR_RI get changed if bit 15 set */ | 850 | /* only MSR_EE and MSR_RI get changed if bit 15 set */ |
| 142 | /* mtmsrd doesn't change MSR_HV and MSR_ME */ | 851 | /* mtmsrd doesn't change MSR_HV and MSR_ME */ |
| 852 | if (regs->msr & MSR_PR) | ||
| 853 | break; | ||
| 143 | imm = (instr & 0x10000)? 0x8002: 0xefffffffffffefffUL; | 854 | imm = (instr & 0x10000)? 0x8002: 0xefffffffffffefffUL; |
| 144 | imm = (regs->msr & MSR_MASK & ~imm) | 855 | imm = (regs->msr & MSR_MASK & ~imm) |
| 145 | | (regs->gpr[rd] & imm); | 856 | | (regs->gpr[rd] & imm); |
| @@ -147,57 +858,770 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) | |||
| 147 | /* can't step mtmsrd that would clear MSR_RI */ | 858 | /* can't step mtmsrd that would clear MSR_RI */ |
| 148 | return -1; | 859 | return -1; |
| 149 | regs->msr = imm; | 860 | regs->msr = imm; |
| 150 | regs->nip += 4; | 861 | goto instr_done; |
| 151 | if ((imm & MSR_SF) == 0) | ||
| 152 | regs->nip &= 0xffffffffUL; | ||
| 153 | return 1; | ||
| 154 | #endif | 862 | #endif |
| 155 | case 0x26: /* mfcr */ | 863 | case 19: /* mfcr */ |
| 156 | regs->gpr[rd] = regs->ccr; | 864 | regs->gpr[rd] = regs->ccr; |
| 157 | regs->gpr[rd] &= 0xffffffffUL; | 865 | regs->gpr[rd] &= 0xffffffffUL; |
| 158 | goto mtspr_out; | 866 | goto instr_done; |
| 159 | case 0x2a6: /* mfspr */ | 867 | |
| 868 | case 144: /* mtcrf */ | ||
| 869 | imm = 0xf0000000UL; | ||
| 870 | val = regs->gpr[rd]; | ||
| 871 | for (sh = 0; sh < 8; ++sh) { | ||
| 872 | if (instr & (0x80000 >> sh)) | ||
| 873 | regs->ccr = (regs->ccr & ~imm) | | ||
| 874 | (val & imm); | ||
| 875 | imm >>= 4; | ||
| 876 | } | ||
| 877 | goto instr_done; | ||
| 878 | |||
| 879 | case 339: /* mfspr */ | ||
| 160 | spr = (instr >> 11) & 0x3ff; | 880 | spr = (instr >> 11) & 0x3ff; |
| 161 | switch (spr) { | 881 | switch (spr) { |
| 162 | case 0x20: /* mfxer */ | 882 | case 0x20: /* mfxer */ |
| 163 | regs->gpr[rd] = regs->xer; | 883 | regs->gpr[rd] = regs->xer; |
| 164 | regs->gpr[rd] &= 0xffffffffUL; | 884 | regs->gpr[rd] &= 0xffffffffUL; |
| 165 | goto mtspr_out; | 885 | goto instr_done; |
| 166 | case 0x100: /* mflr */ | 886 | case 0x100: /* mflr */ |
| 167 | regs->gpr[rd] = regs->link; | 887 | regs->gpr[rd] = regs->link; |
| 168 | goto mtspr_out; | 888 | goto instr_done; |
| 169 | case 0x120: /* mfctr */ | 889 | case 0x120: /* mfctr */ |
| 170 | regs->gpr[rd] = regs->ctr; | 890 | regs->gpr[rd] = regs->ctr; |
| 171 | goto mtspr_out; | 891 | goto instr_done; |
| 172 | } | ||
| 173 | break; | ||
| 174 | case 0x378: /* orx */ | ||
| 175 | if (instr & 1) | ||
| 176 | break; | ||
| 177 | rs = (instr >> 21) & 0x1f; | ||
| 178 | rb = (instr >> 11) & 0x1f; | ||
| 179 | if (rs == rb) { /* mr */ | ||
| 180 | rd = (instr >> 16) & 0x1f; | ||
| 181 | regs->gpr[rd] = regs->gpr[rs]; | ||
| 182 | goto mtspr_out; | ||
| 183 | } | 892 | } |
| 184 | break; | 893 | break; |
| 185 | case 0x3a6: /* mtspr */ | 894 | |
| 895 | case 467: /* mtspr */ | ||
| 186 | spr = (instr >> 11) & 0x3ff; | 896 | spr = (instr >> 11) & 0x3ff; |
| 187 | switch (spr) { | 897 | switch (spr) { |
| 188 | case 0x20: /* mtxer */ | 898 | case 0x20: /* mtxer */ |
| 189 | regs->xer = (regs->gpr[rd] & 0xffffffffUL); | 899 | regs->xer = (regs->gpr[rd] & 0xffffffffUL); |
| 190 | goto mtspr_out; | 900 | goto instr_done; |
| 191 | case 0x100: /* mtlr */ | 901 | case 0x100: /* mtlr */ |
| 192 | regs->link = regs->gpr[rd]; | 902 | regs->link = regs->gpr[rd]; |
| 193 | goto mtspr_out; | 903 | goto instr_done; |
| 194 | case 0x120: /* mtctr */ | 904 | case 0x120: /* mtctr */ |
| 195 | regs->ctr = regs->gpr[rd]; | 905 | regs->ctr = regs->gpr[rd]; |
| 196 | mtspr_out: | 906 | goto instr_done; |
| 197 | regs->nip += 4; | ||
| 198 | return 1; | ||
| 199 | } | 907 | } |
| 908 | break; | ||
| 909 | |||
| 910 | /* | ||
| 911 | * Compare instructions | ||
| 912 | */ | ||
| 913 | case 0: /* cmp */ | ||
| 914 | val = regs->gpr[ra]; | ||
| 915 | val2 = regs->gpr[rb]; | ||
| 916 | #ifdef __powerpc64__ | ||
| 917 | if ((rd & 1) == 0) { | ||
| 918 | /* word (32-bit) compare */ | ||
| 919 | val = (int) val; | ||
| 920 | val2 = (int) val2; | ||
| 921 | } | ||
| 922 | #endif | ||
| 923 | do_cmp_signed(regs, val, val2, rd >> 2); | ||
| 924 | goto instr_done; | ||
| 925 | |||
| 926 | case 32: /* cmpl */ | ||
| 927 | val = regs->gpr[ra]; | ||
| 928 | val2 = regs->gpr[rb]; | ||
| 929 | #ifdef __powerpc64__ | ||
| 930 | if ((rd & 1) == 0) { | ||
| 931 | /* word (32-bit) compare */ | ||
| 932 | val = (unsigned int) val; | ||
| 933 | val2 = (unsigned int) val2; | ||
| 934 | } | ||
| 935 | #endif | ||
| 936 | do_cmp_unsigned(regs, val, val2, rd >> 2); | ||
| 937 | goto instr_done; | ||
| 938 | |||
| 939 | /* | ||
| 940 | * Arithmetic instructions | ||
| 941 | */ | ||
| 942 | case 8: /* subfc */ | ||
| 943 | add_with_carry(regs, rd, ~regs->gpr[ra], | ||
| 944 | regs->gpr[rb], 1); | ||
| 945 | goto arith_done; | ||
| 946 | #ifdef __powerpc64__ | ||
| 947 | case 9: /* mulhdu */ | ||
| 948 | asm("mulhdu %0,%1,%2" : "=r" (regs->gpr[rd]) : | ||
| 949 | "r" (regs->gpr[ra]), "r" (regs->gpr[rb])); | ||
| 950 | goto arith_done; | ||
| 951 | #endif | ||
| 952 | case 10: /* addc */ | ||
| 953 | add_with_carry(regs, rd, regs->gpr[ra], | ||
| 954 | regs->gpr[rb], 0); | ||
| 955 | goto arith_done; | ||
| 956 | |||
| 957 | case 11: /* mulhwu */ | ||
| 958 | asm("mulhwu %0,%1,%2" : "=r" (regs->gpr[rd]) : | ||
| 959 | "r" (regs->gpr[ra]), "r" (regs->gpr[rb])); | ||
| 960 | goto arith_done; | ||
| 961 | |||
| 962 | case 40: /* subf */ | ||
| 963 | regs->gpr[rd] = regs->gpr[rb] - regs->gpr[ra]; | ||
| 964 | goto arith_done; | ||
| 965 | #ifdef __powerpc64__ | ||
| 966 | case 73: /* mulhd */ | ||
| 967 | asm("mulhd %0,%1,%2" : "=r" (regs->gpr[rd]) : | ||
| 968 | "r" (regs->gpr[ra]), "r" (regs->gpr[rb])); | ||
| 969 | goto arith_done; | ||
| 970 | #endif | ||
| 971 | case 75: /* mulhw */ | ||
| 972 | asm("mulhw %0,%1,%2" : "=r" (regs->gpr[rd]) : | ||
| 973 | "r" (regs->gpr[ra]), "r" (regs->gpr[rb])); | ||
| 974 | goto arith_done; | ||
| 975 | |||
| 976 | case 104: /* neg */ | ||
| 977 | regs->gpr[rd] = -regs->gpr[ra]; | ||
| 978 | goto arith_done; | ||
| 979 | |||
| 980 | case 136: /* subfe */ | ||
| 981 | add_with_carry(regs, rd, ~regs->gpr[ra], regs->gpr[rb], | ||
| 982 | regs->xer & XER_CA); | ||
| 983 | goto arith_done; | ||
| 984 | |||
| 985 | case 138: /* adde */ | ||
| 986 | add_with_carry(regs, rd, regs->gpr[ra], regs->gpr[rb], | ||
| 987 | regs->xer & XER_CA); | ||
| 988 | goto arith_done; | ||
| 989 | |||
| 990 | case 200: /* subfze */ | ||
| 991 | add_with_carry(regs, rd, ~regs->gpr[ra], 0L, | ||
| 992 | regs->xer & XER_CA); | ||
| 993 | goto arith_done; | ||
| 994 | |||
| 995 | case 202: /* addze */ | ||
| 996 | add_with_carry(regs, rd, regs->gpr[ra], 0L, | ||
| 997 | regs->xer & XER_CA); | ||
| 998 | goto arith_done; | ||
| 999 | |||
| 1000 | case 232: /* subfme */ | ||
| 1001 | add_with_carry(regs, rd, ~regs->gpr[ra], -1L, | ||
| 1002 | regs->xer & XER_CA); | ||
| 1003 | goto arith_done; | ||
| 1004 | #ifdef __powerpc64__ | ||
| 1005 | case 233: /* mulld */ | ||
| 1006 | regs->gpr[rd] = regs->gpr[ra] * regs->gpr[rb]; | ||
| 1007 | goto arith_done; | ||
| 1008 | #endif | ||
| 1009 | case 234: /* addme */ | ||
| 1010 | add_with_carry(regs, rd, regs->gpr[ra], -1L, | ||
| 1011 | regs->xer & XER_CA); | ||
| 1012 | goto arith_done; | ||
| 1013 | |||
| 1014 | case 235: /* mullw */ | ||
| 1015 | regs->gpr[rd] = (unsigned int) regs->gpr[ra] * | ||
| 1016 | (unsigned int) regs->gpr[rb]; | ||
| 1017 | goto arith_done; | ||
| 1018 | |||
| 1019 | case 266: /* add */ | ||
| 1020 | regs->gpr[rd] = regs->gpr[ra] + regs->gpr[rb]; | ||
| 1021 | goto arith_done; | ||
| 1022 | #ifdef __powerpc64__ | ||
| 1023 | case 457: /* divdu */ | ||
| 1024 | regs->gpr[rd] = regs->gpr[ra] / regs->gpr[rb]; | ||
| 1025 | goto arith_done; | ||
| 1026 | #endif | ||
| 1027 | case 459: /* divwu */ | ||
| 1028 | regs->gpr[rd] = (unsigned int) regs->gpr[ra] / | ||
| 1029 | (unsigned int) regs->gpr[rb]; | ||
| 1030 | goto arith_done; | ||
| 1031 | #ifdef __powerpc64__ | ||
| 1032 | case 489: /* divd */ | ||
| 1033 | regs->gpr[rd] = (long int) regs->gpr[ra] / | ||
| 1034 | (long int) regs->gpr[rb]; | ||
| 1035 | goto arith_done; | ||
| 1036 | #endif | ||
| 1037 | case 491: /* divw */ | ||
| 1038 | regs->gpr[rd] = (int) regs->gpr[ra] / | ||
| 1039 | (int) regs->gpr[rb]; | ||
| 1040 | goto arith_done; | ||
| 1041 | |||
| 1042 | |||
| 1043 | /* | ||
| 1044 | * Logical instructions | ||
| 1045 | */ | ||
| 1046 | case 26: /* cntlzw */ | ||
| 1047 | asm("cntlzw %0,%1" : "=r" (regs->gpr[ra]) : | ||
| 1048 | "r" (regs->gpr[rd])); | ||
| 1049 | goto logical_done; | ||
| 1050 | #ifdef __powerpc64__ | ||
| 1051 | case 58: /* cntlzd */ | ||
| 1052 | asm("cntlzd %0,%1" : "=r" (regs->gpr[ra]) : | ||
| 1053 | "r" (regs->gpr[rd])); | ||
| 1054 | goto logical_done; | ||
| 1055 | #endif | ||
| 1056 | case 28: /* and */ | ||
| 1057 | regs->gpr[ra] = regs->gpr[rd] & regs->gpr[rb]; | ||
| 1058 | goto logical_done; | ||
| 1059 | |||
| 1060 | case 60: /* andc */ | ||
| 1061 | regs->gpr[ra] = regs->gpr[rd] & ~regs->gpr[rb]; | ||
| 1062 | goto logical_done; | ||
| 1063 | |||
| 1064 | case 124: /* nor */ | ||
| 1065 | regs->gpr[ra] = ~(regs->gpr[rd] | regs->gpr[rb]); | ||
| 1066 | goto logical_done; | ||
| 1067 | |||
| 1068 | case 284: /* xor */ | ||
| 1069 | regs->gpr[ra] = ~(regs->gpr[rd] ^ regs->gpr[rb]); | ||
| 1070 | goto logical_done; | ||
| 1071 | |||
| 1072 | case 316: /* xor */ | ||
| 1073 | regs->gpr[ra] = regs->gpr[rd] ^ regs->gpr[rb]; | ||
| 1074 | goto logical_done; | ||
| 1075 | |||
| 1076 | case 412: /* orc */ | ||
| 1077 | regs->gpr[ra] = regs->gpr[rd] | ~regs->gpr[rb]; | ||
| 1078 | goto logical_done; | ||
| 1079 | |||
| 1080 | case 444: /* or */ | ||
| 1081 | regs->gpr[ra] = regs->gpr[rd] | regs->gpr[rb]; | ||
| 1082 | goto logical_done; | ||
| 1083 | |||
| 1084 | case 476: /* nand */ | ||
| 1085 | regs->gpr[ra] = ~(regs->gpr[rd] & regs->gpr[rb]); | ||
| 1086 | goto logical_done; | ||
| 1087 | |||
| 1088 | case 922: /* extsh */ | ||
| 1089 | regs->gpr[ra] = (signed short) regs->gpr[rd]; | ||
| 1090 | goto logical_done; | ||
| 1091 | |||
| 1092 | case 954: /* extsb */ | ||
| 1093 | regs->gpr[ra] = (signed char) regs->gpr[rd]; | ||
| 1094 | goto logical_done; | ||
| 1095 | #ifdef __powerpc64__ | ||
| 1096 | case 986: /* extsw */ | ||
| 1097 | regs->gpr[ra] = (signed int) regs->gpr[rd]; | ||
| 1098 | goto logical_done; | ||
| 1099 | #endif | ||
| 1100 | |||
| 1101 | /* | ||
| 1102 | * Shift instructions | ||
| 1103 | */ | ||
| 1104 | case 24: /* slw */ | ||
| 1105 | sh = regs->gpr[rb] & 0x3f; | ||
| 1106 | if (sh < 32) | ||
| 1107 | regs->gpr[ra] = (regs->gpr[rd] << sh) & 0xffffffffUL; | ||
| 1108 | else | ||
| 1109 | regs->gpr[ra] = 0; | ||
| 1110 | goto logical_done; | ||
| 1111 | |||
| 1112 | case 536: /* srw */ | ||
| 1113 | sh = regs->gpr[rb] & 0x3f; | ||
| 1114 | if (sh < 32) | ||
| 1115 | regs->gpr[ra] = (regs->gpr[rd] & 0xffffffffUL) >> sh; | ||
| 1116 | else | ||
| 1117 | regs->gpr[ra] = 0; | ||
| 1118 | goto logical_done; | ||
| 1119 | |||
| 1120 | case 792: /* sraw */ | ||
| 1121 | sh = regs->gpr[rb] & 0x3f; | ||
| 1122 | ival = (signed int) regs->gpr[rd]; | ||
| 1123 | regs->gpr[ra] = ival >> (sh < 32 ? sh : 31); | ||
| 1124 | if (ival < 0 && (sh >= 32 || (ival & ((1 << sh) - 1)) != 0)) | ||
| 1125 | regs->xer |= XER_CA; | ||
| 1126 | else | ||
| 1127 | regs->xer &= ~XER_CA; | ||
| 1128 | goto logical_done; | ||
| 1129 | |||
| 1130 | case 824: /* srawi */ | ||
| 1131 | sh = rb; | ||
| 1132 | ival = (signed int) regs->gpr[rd]; | ||
| 1133 | regs->gpr[ra] = ival >> sh; | ||
| 1134 | if (ival < 0 && (ival & ((1 << sh) - 1)) != 0) | ||
| 1135 | regs->xer |= XER_CA; | ||
| 1136 | else | ||
| 1137 | regs->xer &= ~XER_CA; | ||
| 1138 | goto logical_done; | ||
| 1139 | |||
| 1140 | #ifdef __powerpc64__ | ||
| 1141 | case 27: /* sld */ | ||
| 1142 | sh = regs->gpr[rd] & 0x7f; | ||
| 1143 | if (sh < 64) | ||
| 1144 | regs->gpr[ra] = regs->gpr[rd] << sh; | ||
| 1145 | else | ||
| 1146 | regs->gpr[ra] = 0; | ||
| 1147 | goto logical_done; | ||
| 1148 | |||
| 1149 | case 539: /* srd */ | ||
| 1150 | sh = regs->gpr[rb] & 0x7f; | ||
| 1151 | if (sh < 64) | ||
| 1152 | regs->gpr[ra] = regs->gpr[rd] >> sh; | ||
| 1153 | else | ||
| 1154 | regs->gpr[ra] = 0; | ||
| 1155 | goto logical_done; | ||
| 1156 | |||
| 1157 | case 794: /* srad */ | ||
| 1158 | sh = regs->gpr[rb] & 0x7f; | ||
| 1159 | ival = (signed long int) regs->gpr[rd]; | ||
| 1160 | regs->gpr[ra] = ival >> (sh < 64 ? sh : 63); | ||
| 1161 | if (ival < 0 && (sh >= 64 || (ival & ((1 << sh) - 1)) != 0)) | ||
| 1162 | regs->xer |= XER_CA; | ||
| 1163 | else | ||
| 1164 | regs->xer &= ~XER_CA; | ||
| 1165 | goto logical_done; | ||
| 1166 | |||
| 1167 | case 826: /* sradi with sh_5 = 0 */ | ||
| 1168 | case 827: /* sradi with sh_5 = 1 */ | ||
| 1169 | sh = rb | ((instr & 2) << 4); | ||
| 1170 | ival = (signed long int) regs->gpr[rd]; | ||
| 1171 | regs->gpr[ra] = ival >> sh; | ||
| 1172 | if (ival < 0 && (ival & ((1 << sh) - 1)) != 0) | ||
| 1173 | regs->xer |= XER_CA; | ||
| 1174 | else | ||
| 1175 | regs->xer &= ~XER_CA; | ||
| 1176 | goto logical_done; | ||
| 1177 | #endif /* __powerpc64__ */ | ||
| 1178 | |||
| 1179 | /* | ||
| 1180 | * Cache instructions | ||
| 1181 | */ | ||
| 1182 | case 54: /* dcbst */ | ||
| 1183 | ea = xform_ea(instr, regs, 0); | ||
| 1184 | if (!address_ok(regs, ea, 8)) | ||
| 1185 | return 0; | ||
| 1186 | err = 0; | ||
| 1187 | __cacheop_user_asmx(ea, err, "dcbst"); | ||
| 1188 | if (err) | ||
| 1189 | return 0; | ||
| 1190 | goto instr_done; | ||
| 1191 | |||
| 1192 | case 86: /* dcbf */ | ||
| 1193 | ea = xform_ea(instr, regs, 0); | ||
| 1194 | if (!address_ok(regs, ea, 8)) | ||
| 1195 | return 0; | ||
| 1196 | err = 0; | ||
| 1197 | __cacheop_user_asmx(ea, err, "dcbf"); | ||
| 1198 | if (err) | ||
| 1199 | return 0; | ||
| 1200 | goto instr_done; | ||
| 1201 | |||
| 1202 | case 246: /* dcbtst */ | ||
| 1203 | if (rd == 0) { | ||
| 1204 | ea = xform_ea(instr, regs, 0); | ||
| 1205 | prefetchw((void *) ea); | ||
| 1206 | } | ||
| 1207 | goto instr_done; | ||
| 1208 | |||
| 1209 | case 278: /* dcbt */ | ||
| 1210 | if (rd == 0) { | ||
| 1211 | ea = xform_ea(instr, regs, 0); | ||
| 1212 | prefetch((void *) ea); | ||
| 1213 | } | ||
| 1214 | goto instr_done; | ||
| 1215 | |||
| 200 | } | 1216 | } |
| 1217 | break; | ||
| 201 | } | 1218 | } |
| 202 | return 0; | 1219 | |
| 1220 | /* | ||
| 1221 | * Following cases are for loads and stores, so bail out | ||
| 1222 | * if we're in little-endian mode. | ||
| 1223 | */ | ||
| 1224 | if (regs->msr & MSR_LE) | ||
| 1225 | return 0; | ||
| 1226 | |||
| 1227 | /* | ||
| 1228 | * Save register RA in case it's an update form load or store | ||
| 1229 | * and the access faults. | ||
| 1230 | */ | ||
| 1231 | old_ra = regs->gpr[ra]; | ||
| 1232 | |||
| 1233 | switch (opcode) { | ||
| 1234 | case 31: | ||
| 1235 | u = instr & 0x40; | ||
| 1236 | switch ((instr >> 1) & 0x3ff) { | ||
| 1237 | case 20: /* lwarx */ | ||
| 1238 | ea = xform_ea(instr, regs, 0); | ||
| 1239 | if (ea & 3) | ||
| 1240 | break; /* can't handle misaligned */ | ||
| 1241 | err = -EFAULT; | ||
| 1242 | if (!address_ok(regs, ea, 4)) | ||
| 1243 | goto ldst_done; | ||
| 1244 | err = 0; | ||
| 1245 | __get_user_asmx(val, ea, err, "lwarx"); | ||
| 1246 | if (!err) | ||
| 1247 | regs->gpr[rd] = val; | ||
| 1248 | goto ldst_done; | ||
| 1249 | |||
| 1250 | case 150: /* stwcx. */ | ||
| 1251 | ea = xform_ea(instr, regs, 0); | ||
| 1252 | if (ea & 3) | ||
| 1253 | break; /* can't handle misaligned */ | ||
| 1254 | err = -EFAULT; | ||
| 1255 | if (!address_ok(regs, ea, 4)) | ||
| 1256 | goto ldst_done; | ||
| 1257 | err = 0; | ||
| 1258 | __put_user_asmx(regs->gpr[rd], ea, err, "stwcx.", cr); | ||
| 1259 | if (!err) | ||
| 1260 | regs->ccr = (regs->ccr & 0x0fffffff) | | ||
| 1261 | (cr & 0xe0000000) | | ||
| 1262 | ((regs->xer >> 3) & 0x10000000); | ||
| 1263 | goto ldst_done; | ||
| 1264 | |||
| 1265 | #ifdef __powerpc64__ | ||
| 1266 | case 84: /* ldarx */ | ||
| 1267 | ea = xform_ea(instr, regs, 0); | ||
| 1268 | if (ea & 7) | ||
| 1269 | break; /* can't handle misaligned */ | ||
| 1270 | err = -EFAULT; | ||
| 1271 | if (!address_ok(regs, ea, 8)) | ||
| 1272 | goto ldst_done; | ||
| 1273 | err = 0; | ||
| 1274 | __get_user_asmx(val, ea, err, "ldarx"); | ||
| 1275 | if (!err) | ||
| 1276 | regs->gpr[rd] = val; | ||
| 1277 | goto ldst_done; | ||
| 1278 | |||
| 1279 | case 214: /* stdcx. */ | ||
| 1280 | ea = xform_ea(instr, regs, 0); | ||
| 1281 | if (ea & 7) | ||
| 1282 | break; /* can't handle misaligned */ | ||
| 1283 | err = -EFAULT; | ||
| 1284 | if (!address_ok(regs, ea, 8)) | ||
| 1285 | goto ldst_done; | ||
| 1286 | err = 0; | ||
| 1287 | __put_user_asmx(regs->gpr[rd], ea, err, "stdcx.", cr); | ||
| 1288 | if (!err) | ||
| 1289 | regs->ccr = (regs->ccr & 0x0fffffff) | | ||
| 1290 | (cr & 0xe0000000) | | ||
| 1291 | ((regs->xer >> 3) & 0x10000000); | ||
| 1292 | goto ldst_done; | ||
| 1293 | |||
| 1294 | case 21: /* ldx */ | ||
| 1295 | case 53: /* ldux */ | ||
| 1296 | err = read_mem(®s->gpr[rd], xform_ea(instr, regs, u), | ||
| 1297 | 8, regs); | ||
| 1298 | goto ldst_done; | ||
| 1299 | #endif | ||
| 1300 | |||
| 1301 | case 23: /* lwzx */ | ||
| 1302 | case 55: /* lwzux */ | ||
| 1303 | err = read_mem(®s->gpr[rd], xform_ea(instr, regs, u), | ||
| 1304 | 4, regs); | ||
| 1305 | goto ldst_done; | ||
| 1306 | |||
| 1307 | case 87: /* lbzx */ | ||
| 1308 | case 119: /* lbzux */ | ||
| 1309 | err = read_mem(®s->gpr[rd], xform_ea(instr, regs, u), | ||
| 1310 | 1, regs); | ||
| 1311 | goto ldst_done; | ||
| 1312 | |||
| 1313 | #ifdef CONFIG_ALTIVEC | ||
| 1314 | case 103: /* lvx */ | ||
| 1315 | case 359: /* lvxl */ | ||
| 1316 | if (!(regs->msr & MSR_VEC)) | ||
| 1317 | break; | ||
| 1318 | ea = xform_ea(instr, regs, 0); | ||
| 1319 | err = do_vec_load(rd, do_lvx, ea, regs); | ||
| 1320 | goto ldst_done; | ||
| 1321 | |||
| 1322 | case 231: /* stvx */ | ||
| 1323 | case 487: /* stvxl */ | ||
| 1324 | if (!(regs->msr & MSR_VEC)) | ||
| 1325 | break; | ||
| 1326 | ea = xform_ea(instr, regs, 0); | ||
| 1327 | err = do_vec_store(rd, do_stvx, ea, regs); | ||
| 1328 | goto ldst_done; | ||
| 1329 | #endif /* CONFIG_ALTIVEC */ | ||
| 1330 | |||
| 1331 | #ifdef __powerpc64__ | ||
| 1332 | case 149: /* stdx */ | ||
| 1333 | case 181: /* stdux */ | ||
| 1334 | val = regs->gpr[rd]; | ||
| 1335 | err = write_mem(val, xform_ea(instr, regs, u), 8, regs); | ||
| 1336 | goto ldst_done; | ||
| 1337 | #endif | ||
| 1338 | |||
| 1339 | case 151: /* stwx */ | ||
| 1340 | case 183: /* stwux */ | ||
| 1341 | val = regs->gpr[rd]; | ||
| 1342 | err = write_mem(val, xform_ea(instr, regs, u), 4, regs); | ||
| 1343 | goto ldst_done; | ||
| 1344 | |||
| 1345 | case 215: /* stbx */ | ||
| 1346 | case 247: /* stbux */ | ||
| 1347 | val = regs->gpr[rd]; | ||
| 1348 | err = write_mem(val, xform_ea(instr, regs, u), 1, regs); | ||
| 1349 | goto ldst_done; | ||
| 1350 | |||
| 1351 | case 279: /* lhzx */ | ||
| 1352 | case 311: /* lhzux */ | ||
| 1353 | err = read_mem(®s->gpr[rd], xform_ea(instr, regs, u), | ||
| 1354 | 2, regs); | ||
| 1355 | goto ldst_done; | ||
| 1356 | |||
| 1357 | #ifdef __powerpc64__ | ||
| 1358 | case 341: /* lwax */ | ||
| 1359 | case 373: /* lwaux */ | ||
| 1360 | err = read_mem(®s->gpr[rd], xform_ea(instr, regs, u), | ||
| 1361 | 4, regs); | ||
| 1362 | if (!err) | ||
| 1363 | regs->gpr[rd] = (signed int) regs->gpr[rd]; | ||
| 1364 | goto ldst_done; | ||
| 1365 | #endif | ||
| 1366 | |||
| 1367 | case 343: /* lhax */ | ||
| 1368 | case 375: /* lhaux */ | ||
| 1369 | err = read_mem(®s->gpr[rd], xform_ea(instr, regs, u), | ||
| 1370 | 2, regs); | ||
| 1371 | if (!err) | ||
| 1372 | regs->gpr[rd] = (signed short) regs->gpr[rd]; | ||
| 1373 | goto ldst_done; | ||
| 1374 | |||
| 1375 | case 407: /* sthx */ | ||
| 1376 | case 439: /* sthux */ | ||
| 1377 | val = regs->gpr[rd]; | ||
| 1378 | err = write_mem(val, xform_ea(instr, regs, u), 2, regs); | ||
| 1379 | goto ldst_done; | ||
| 1380 | |||
| 1381 | #ifdef __powerpc64__ | ||
| 1382 | case 532: /* ldbrx */ | ||
| 1383 | err = read_mem(&val, xform_ea(instr, regs, 0), 8, regs); | ||
| 1384 | if (!err) | ||
| 1385 | regs->gpr[rd] = byterev_8(val); | ||
| 1386 | goto ldst_done; | ||
| 1387 | |||
| 1388 | #endif | ||
| 1389 | |||
| 1390 | case 534: /* lwbrx */ | ||
| 1391 | err = read_mem(&val, xform_ea(instr, regs, 0), 4, regs); | ||
| 1392 | if (!err) | ||
| 1393 | regs->gpr[rd] = byterev_4(val); | ||
| 1394 | goto ldst_done; | ||
| 1395 | |||
| 1396 | case 535: /* lfsx */ | ||
| 1397 | case 567: /* lfsux */ | ||
| 1398 | if (!(regs->msr & MSR_FP)) | ||
| 1399 | break; | ||
| 1400 | ea = xform_ea(instr, regs, u); | ||
| 1401 | err = do_fp_load(rd, do_lfs, ea, 4, regs); | ||
| 1402 | goto ldst_done; | ||
| 1403 | |||
| 1404 | case 599: /* lfdx */ | ||
| 1405 | case 631: /* lfdux */ | ||
| 1406 | if (!(regs->msr & MSR_FP)) | ||
| 1407 | break; | ||
| 1408 | ea = xform_ea(instr, regs, u); | ||
| 1409 | err = do_fp_load(rd, do_lfd, ea, 8, regs); | ||
| 1410 | goto ldst_done; | ||
| 1411 | |||
| 1412 | case 663: /* stfsx */ | ||
| 1413 | case 695: /* stfsux */ | ||
| 1414 | if (!(regs->msr & MSR_FP)) | ||
| 1415 | break; | ||
| 1416 | ea = xform_ea(instr, regs, u); | ||
| 1417 | err = do_fp_store(rd, do_stfs, ea, 4, regs); | ||
| 1418 | goto ldst_done; | ||
| 1419 | |||
| 1420 | case 727: /* stfdx */ | ||
| 1421 | case 759: /* stfdux */ | ||
| 1422 | if (!(regs->msr & MSR_FP)) | ||
| 1423 | break; | ||
| 1424 | ea = xform_ea(instr, regs, u); | ||
| 1425 | err = do_fp_store(rd, do_stfd, ea, 8, regs); | ||
| 1426 | goto ldst_done; | ||
| 1427 | |||
| 1428 | #ifdef __powerpc64__ | ||
| 1429 | case 660: /* stdbrx */ | ||
| 1430 | val = byterev_8(regs->gpr[rd]); | ||
| 1431 | err = write_mem(val, xform_ea(instr, regs, 0), 8, regs); | ||
| 1432 | goto ldst_done; | ||
| 1433 | |||
| 1434 | #endif | ||
| 1435 | case 662: /* stwbrx */ | ||
| 1436 | val = byterev_4(regs->gpr[rd]); | ||
| 1437 | err = write_mem(val, xform_ea(instr, regs, 0), 4, regs); | ||
| 1438 | goto ldst_done; | ||
| 1439 | |||
| 1440 | case 790: /* lhbrx */ | ||
| 1441 | err = read_mem(&val, xform_ea(instr, regs, 0), 2, regs); | ||
| 1442 | if (!err) | ||
| 1443 | regs->gpr[rd] = byterev_2(val); | ||
| 1444 | goto ldst_done; | ||
| 1445 | |||
| 1446 | case 918: /* sthbrx */ | ||
| 1447 | val = byterev_2(regs->gpr[rd]); | ||
| 1448 | err = write_mem(val, xform_ea(instr, regs, 0), 2, regs); | ||
| 1449 | goto ldst_done; | ||
| 1450 | |||
| 1451 | #ifdef CONFIG_VSX | ||
| 1452 | case 844: /* lxvd2x */ | ||
| 1453 | case 876: /* lxvd2ux */ | ||
| 1454 | if (!(regs->msr & MSR_VSX)) | ||
| 1455 | break; | ||
| 1456 | rd |= (instr & 1) << 5; | ||
| 1457 | ea = xform_ea(instr, regs, u); | ||
| 1458 | err = do_vsx_load(rd, do_lxvd2x, ea, regs); | ||
| 1459 | goto ldst_done; | ||
| 1460 | |||
| 1461 | case 972: /* stxvd2x */ | ||
| 1462 | case 1004: /* stxvd2ux */ | ||
| 1463 | if (!(regs->msr & MSR_VSX)) | ||
| 1464 | break; | ||
| 1465 | rd |= (instr & 1) << 5; | ||
| 1466 | ea = xform_ea(instr, regs, u); | ||
| 1467 | err = do_vsx_store(rd, do_stxvd2x, ea, regs); | ||
| 1468 | goto ldst_done; | ||
| 1469 | |||
| 1470 | #endif /* CONFIG_VSX */ | ||
| 1471 | } | ||
| 1472 | break; | ||
| 1473 | |||
| 1474 | case 32: /* lwz */ | ||
| 1475 | case 33: /* lwzu */ | ||
| 1476 | err = read_mem(®s->gpr[rd], dform_ea(instr, regs), 4, regs); | ||
| 1477 | goto ldst_done; | ||
| 1478 | |||
| 1479 | case 34: /* lbz */ | ||
| 1480 | case 35: /* lbzu */ | ||
| 1481 | err = read_mem(®s->gpr[rd], dform_ea(instr, regs), 1, regs); | ||
| 1482 | goto ldst_done; | ||
| 1483 | |||
| 1484 | case 36: /* stw */ | ||
| 1485 | case 37: /* stwu */ | ||
| 1486 | val = regs->gpr[rd]; | ||
| 1487 | err = write_mem(val, dform_ea(instr, regs), 4, regs); | ||
| 1488 | goto ldst_done; | ||
| 1489 | |||
| 1490 | case 38: /* stb */ | ||
| 1491 | case 39: /* stbu */ | ||
| 1492 | val = regs->gpr[rd]; | ||
| 1493 | err = write_mem(val, dform_ea(instr, regs), 1, regs); | ||
| 1494 | goto ldst_done; | ||
| 1495 | |||
| 1496 | case 40: /* lhz */ | ||
| 1497 | case 41: /* lhzu */ | ||
| 1498 | err = read_mem(®s->gpr[rd], dform_ea(instr, regs), 2, regs); | ||
| 1499 | goto ldst_done; | ||
| 1500 | |||
| 1501 | case 42: /* lha */ | ||
| 1502 | case 43: /* lhau */ | ||
| 1503 | err = read_mem(®s->gpr[rd], dform_ea(instr, regs), 2, regs); | ||
| 1504 | if (!err) | ||
| 1505 | regs->gpr[rd] = (signed short) regs->gpr[rd]; | ||
| 1506 | goto ldst_done; | ||
| 1507 | |||
| 1508 | case 44: /* sth */ | ||
| 1509 | case 45: /* sthu */ | ||
| 1510 | val = regs->gpr[rd]; | ||
| 1511 | err = write_mem(val, dform_ea(instr, regs), 2, regs); | ||
| 1512 | goto ldst_done; | ||
| 1513 | |||
| 1514 | case 46: /* lmw */ | ||
| 1515 | ra = (instr >> 16) & 0x1f; | ||
| 1516 | if (ra >= rd) | ||
| 1517 | break; /* invalid form, ra in range to load */ | ||
| 1518 | ea = dform_ea(instr, regs); | ||
| 1519 | do { | ||
| 1520 | err = read_mem(®s->gpr[rd], ea, 4, regs); | ||
| 1521 | if (err) | ||
| 1522 | return 0; | ||
| 1523 | ea += 4; | ||
| 1524 | } while (++rd < 32); | ||
| 1525 | goto instr_done; | ||
| 1526 | |||
| 1527 | case 47: /* stmw */ | ||
| 1528 | ea = dform_ea(instr, regs); | ||
| 1529 | do { | ||
| 1530 | err = write_mem(regs->gpr[rd], ea, 4, regs); | ||
| 1531 | if (err) | ||
| 1532 | return 0; | ||
| 1533 | ea += 4; | ||
| 1534 | } while (++rd < 32); | ||
| 1535 | goto instr_done; | ||
| 1536 | |||
| 1537 | case 48: /* lfs */ | ||
| 1538 | case 49: /* lfsu */ | ||
| 1539 | if (!(regs->msr & MSR_FP)) | ||
| 1540 | break; | ||
| 1541 | ea = dform_ea(instr, regs); | ||
| 1542 | err = do_fp_load(rd, do_lfs, ea, 4, regs); | ||
| 1543 | goto ldst_done; | ||
| 1544 | |||
| 1545 | case 50: /* lfd */ | ||
| 1546 | case 51: /* lfdu */ | ||
| 1547 | if (!(regs->msr & MSR_FP)) | ||
| 1548 | break; | ||
| 1549 | ea = dform_ea(instr, regs); | ||
| 1550 | err = do_fp_load(rd, do_lfd, ea, 8, regs); | ||
| 1551 | goto ldst_done; | ||
| 1552 | |||
| 1553 | case 52: /* stfs */ | ||
| 1554 | case 53: /* stfsu */ | ||
| 1555 | if (!(regs->msr & MSR_FP)) | ||
| 1556 | break; | ||
| 1557 | ea = dform_ea(instr, regs); | ||
| 1558 | err = do_fp_store(rd, do_stfs, ea, 4, regs); | ||
| 1559 | goto ldst_done; | ||
| 1560 | |||
| 1561 | case 54: /* stfd */ | ||
| 1562 | case 55: /* stfdu */ | ||
| 1563 | if (!(regs->msr & MSR_FP)) | ||
| 1564 | break; | ||
| 1565 | ea = dform_ea(instr, regs); | ||
| 1566 | err = do_fp_store(rd, do_stfd, ea, 8, regs); | ||
| 1567 | goto ldst_done; | ||
| 1568 | |||
| 1569 | #ifdef __powerpc64__ | ||
| 1570 | case 58: /* ld[u], lwa */ | ||
| 1571 | switch (instr & 3) { | ||
| 1572 | case 0: /* ld */ | ||
| 1573 | err = read_mem(®s->gpr[rd], dsform_ea(instr, regs), | ||
| 1574 | 8, regs); | ||
| 1575 | goto ldst_done; | ||
| 1576 | case 1: /* ldu */ | ||
| 1577 | err = read_mem(®s->gpr[rd], dsform_ea(instr, regs), | ||
| 1578 | 8, regs); | ||
| 1579 | goto ldst_done; | ||
| 1580 | case 2: /* lwa */ | ||
| 1581 | err = read_mem(®s->gpr[rd], dsform_ea(instr, regs), | ||
| 1582 | 4, regs); | ||
| 1583 | if (!err) | ||
| 1584 | regs->gpr[rd] = (signed int) regs->gpr[rd]; | ||
| 1585 | goto ldst_done; | ||
| 1586 | } | ||
| 1587 | break; | ||
| 1588 | |||
| 1589 | case 62: /* std[u] */ | ||
| 1590 | val = regs->gpr[rd]; | ||
| 1591 | switch (instr & 3) { | ||
| 1592 | case 0: /* std */ | ||
| 1593 | err = write_mem(val, dsform_ea(instr, regs), 8, regs); | ||
| 1594 | goto ldst_done; | ||
| 1595 | case 1: /* stdu */ | ||
| 1596 | err = write_mem(val, dsform_ea(instr, regs), 8, regs); | ||
| 1597 | goto ldst_done; | ||
| 1598 | } | ||
| 1599 | break; | ||
| 1600 | #endif /* __powerpc64__ */ | ||
| 1601 | |||
| 1602 | } | ||
| 1603 | err = -EINVAL; | ||
| 1604 | |||
| 1605 | ldst_done: | ||
| 1606 | if (err) { | ||
| 1607 | regs->gpr[ra] = old_ra; | ||
| 1608 | return 0; /* invoke DSI if -EFAULT? */ | ||
| 1609 | } | ||
| 1610 | instr_done: | ||
| 1611 | regs->nip += 4; | ||
| 1612 | #ifdef __powerpc64__ | ||
| 1613 | if ((regs->msr & MSR_SF) == 0) | ||
| 1614 | regs->nip &= 0xffffffffUL; | ||
| 1615 | #endif | ||
| 1616 | return 1; | ||
| 1617 | |||
| 1618 | logical_done: | ||
| 1619 | if (instr & 1) | ||
| 1620 | set_cr0(regs, ra); | ||
| 1621 | goto instr_done; | ||
| 1622 | |||
| 1623 | arith_done: | ||
| 1624 | if (instr & 1) | ||
| 1625 | set_cr0(regs, rd); | ||
| 1626 | goto instr_done; | ||
| 203 | } | 1627 | } |
diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c index cdc7526e9c93..4b66a1ece6d8 100644 --- a/arch/powerpc/mm/fsl_booke_mmu.c +++ b/arch/powerpc/mm/fsl_booke_mmu.c | |||
| @@ -104,9 +104,10 @@ unsigned long p_mapped_by_tlbcam(phys_addr_t pa) | |||
| 104 | } | 104 | } |
| 105 | 105 | ||
| 106 | /* | 106 | /* |
| 107 | * Set up one of the I/D BAT (block address translation) register pairs. | 107 | * Set up a variable-size TLB entry (tlbcam). The parameters are not checked; |
| 108 | * The parameters are not checked; in particular size must be a power | 108 | * in particular size must be a power of 4 between 4k and 256M (or 1G, for cpus |
| 109 | * of 4 between 4k and 256M. | 109 | * that support extended page sizes). Note that while some cpus support a |
| 110 | * page size of 4G, we don't allow its use here. | ||
| 110 | */ | 111 | */ |
| 111 | static void settlbcam(int index, unsigned long virt, phys_addr_t phys, | 112 | static void settlbcam(int index, unsigned long virt, phys_addr_t phys, |
| 112 | unsigned long size, unsigned long flags, unsigned int pid) | 113 | unsigned long size, unsigned long flags, unsigned int pid) |
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index aa731af720c0..002878ccf90b 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c | |||
| @@ -42,6 +42,12 @@ EXPORT_SYMBOL(node_data); | |||
| 42 | 42 | ||
| 43 | static int min_common_depth; | 43 | static int min_common_depth; |
| 44 | static int n_mem_addr_cells, n_mem_size_cells; | 44 | static int n_mem_addr_cells, n_mem_size_cells; |
| 45 | static int form1_affinity; | ||
| 46 | |||
| 47 | #define MAX_DISTANCE_REF_POINTS 4 | ||
| 48 | static int distance_ref_points_depth; | ||
| 49 | static const unsigned int *distance_ref_points; | ||
| 50 | static int distance_lookup_table[MAX_NUMNODES][MAX_DISTANCE_REF_POINTS]; | ||
| 45 | 51 | ||
| 46 | /* | 52 | /* |
| 47 | * Allocate node_to_cpumask_map based on number of available nodes | 53 | * Allocate node_to_cpumask_map based on number of available nodes |
| @@ -204,6 +210,39 @@ static const u32 *of_get_usable_memory(struct device_node *memory) | |||
| 204 | return prop; | 210 | return prop; |
| 205 | } | 211 | } |
| 206 | 212 | ||
| 213 | int __node_distance(int a, int b) | ||
| 214 | { | ||
| 215 | int i; | ||
| 216 | int distance = LOCAL_DISTANCE; | ||
| 217 | |||
| 218 | if (!form1_affinity) | ||
| 219 | return distance; | ||
| 220 | |||
| 221 | for (i = 0; i < distance_ref_points_depth; i++) { | ||
| 222 | if (distance_lookup_table[a][i] == distance_lookup_table[b][i]) | ||
| 223 | break; | ||
| 224 | |||
| 225 | /* Double the distance for each NUMA level */ | ||
| 226 | distance *= 2; | ||
| 227 | } | ||
| 228 | |||
| 229 | return distance; | ||
| 230 | } | ||
| 231 | |||
| 232 | static void initialize_distance_lookup_table(int nid, | ||
| 233 | const unsigned int *associativity) | ||
| 234 | { | ||
| 235 | int i; | ||
| 236 | |||
| 237 | if (!form1_affinity) | ||
| 238 | return; | ||
| 239 | |||
| 240 | for (i = 0; i < distance_ref_points_depth; i++) { | ||
| 241 | distance_lookup_table[nid][i] = | ||
| 242 | associativity[distance_ref_points[i]]; | ||
| 243 | } | ||
| 244 | } | ||
| 245 | |||
| 207 | /* Returns nid in the range [0..MAX_NUMNODES-1], or -1 if no useful numa | 246 | /* Returns nid in the range [0..MAX_NUMNODES-1], or -1 if no useful numa |
| 208 | * info is found. | 247 | * info is found. |
| 209 | */ | 248 | */ |
| @@ -225,6 +264,10 @@ static int of_node_to_nid_single(struct device_node *device) | |||
| 225 | /* POWER4 LPAR uses 0xffff as invalid node */ | 264 | /* POWER4 LPAR uses 0xffff as invalid node */ |
| 226 | if (nid == 0xffff || nid >= MAX_NUMNODES) | 265 | if (nid == 0xffff || nid >= MAX_NUMNODES) |
| 227 | nid = -1; | 266 | nid = -1; |
| 267 | |||
| 268 | if (nid > 0 && tmp[0] >= distance_ref_points_depth) | ||
| 269 | initialize_distance_lookup_table(nid, tmp); | ||
| 270 | |||
| 228 | out: | 271 | out: |
| 229 | return nid; | 272 | return nid; |
| 230 | } | 273 | } |
| @@ -251,26 +294,10 @@ int of_node_to_nid(struct device_node *device) | |||
| 251 | } | 294 | } |
| 252 | EXPORT_SYMBOL_GPL(of_node_to_nid); | 295 | EXPORT_SYMBOL_GPL(of_node_to_nid); |
| 253 | 296 | ||
| 254 | /* | ||
| 255 | * In theory, the "ibm,associativity" property may contain multiple | ||
| 256 | * associativity lists because a resource may be multiply connected | ||
| 257 | * into the machine. This resource then has different associativity | ||
| 258 | * characteristics relative to its multiple connections. We ignore | ||
| 259 | * this for now. We also assume that all cpu and memory sets have | ||
| 260 | * their distances represented at a common level. This won't be | ||
| 261 | * true for hierarchical NUMA. | ||
| 262 | * | ||
| 263 | * In any case the ibm,associativity-reference-points should give | ||
| 264 | * the correct depth for a normal NUMA system. | ||
| 265 | * | ||
| 266 | * - Dave Hansen <haveblue@us.ibm.com> | ||
| 267 | */ | ||
| 268 | static int __init find_min_common_depth(void) | 297 | static int __init find_min_common_depth(void) |
| 269 | { | 298 | { |
| 270 | int depth, index; | 299 | int depth; |
| 271 | const unsigned int *ref_points; | ||
| 272 | struct device_node *rtas_root; | 300 | struct device_node *rtas_root; |
| 273 | unsigned int len; | ||
| 274 | struct device_node *chosen; | 301 | struct device_node *chosen; |
| 275 | const char *vec5; | 302 | const char *vec5; |
| 276 | 303 | ||
| @@ -280,18 +307,28 @@ static int __init find_min_common_depth(void) | |||
| 280 | return -1; | 307 | return -1; |
| 281 | 308 | ||
| 282 | /* | 309 | /* |
| 283 | * this property is 2 32-bit integers, each representing a level of | 310 | * This property is a set of 32-bit integers, each representing |
| 284 | * depth in the associativity nodes. The first is for an SMP | 311 | * an index into the ibm,associativity nodes. |
| 285 | * configuration (should be all 0's) and the second is for a normal | 312 | * |
| 286 | * NUMA configuration. | 313 | * With form 0 affinity the first integer is for an SMP configuration |
| 314 | * (should be all 0's) and the second is for a normal NUMA | ||
| 315 | * configuration. We have only one level of NUMA. | ||
| 316 | * | ||
| 317 | * With form 1 affinity the first integer is the most significant | ||
| 318 | * NUMA boundary and the following are progressively less significant | ||
| 319 | * boundaries. There can be more than one level of NUMA. | ||
| 287 | */ | 320 | */ |
| 288 | index = 1; | 321 | distance_ref_points = of_get_property(rtas_root, |
| 289 | ref_points = of_get_property(rtas_root, | 322 | "ibm,associativity-reference-points", |
| 290 | "ibm,associativity-reference-points", &len); | 323 | &distance_ref_points_depth); |
| 324 | |||
| 325 | if (!distance_ref_points) { | ||
| 326 | dbg("NUMA: ibm,associativity-reference-points not found.\n"); | ||
| 327 | goto err; | ||
| 328 | } | ||
| 329 | |||
| 330 | distance_ref_points_depth /= sizeof(int); | ||
| 291 | 331 | ||
| 292 | /* | ||
| 293 | * For form 1 affinity information we want the first field | ||
| 294 | */ | ||
| 295 | #define VEC5_AFFINITY_BYTE 5 | 332 | #define VEC5_AFFINITY_BYTE 5 |
| 296 | #define VEC5_AFFINITY 0x80 | 333 | #define VEC5_AFFINITY 0x80 |
| 297 | chosen = of_find_node_by_path("/chosen"); | 334 | chosen = of_find_node_by_path("/chosen"); |
| @@ -299,19 +336,38 @@ static int __init find_min_common_depth(void) | |||
| 299 | vec5 = of_get_property(chosen, "ibm,architecture-vec-5", NULL); | 336 | vec5 = of_get_property(chosen, "ibm,architecture-vec-5", NULL); |
| 300 | if (vec5 && (vec5[VEC5_AFFINITY_BYTE] & VEC5_AFFINITY)) { | 337 | if (vec5 && (vec5[VEC5_AFFINITY_BYTE] & VEC5_AFFINITY)) { |
| 301 | dbg("Using form 1 affinity\n"); | 338 | dbg("Using form 1 affinity\n"); |
| 302 | index = 0; | 339 | form1_affinity = 1; |
| 303 | } | 340 | } |
| 304 | } | 341 | } |
| 305 | 342 | ||
| 306 | if ((len >= 2 * sizeof(unsigned int)) && ref_points) { | 343 | if (form1_affinity) { |
| 307 | depth = ref_points[index]; | 344 | depth = distance_ref_points[0]; |
| 308 | } else { | 345 | } else { |
| 309 | dbg("NUMA: ibm,associativity-reference-points not found.\n"); | 346 | if (distance_ref_points_depth < 2) { |
| 310 | depth = -1; | 347 | printk(KERN_WARNING "NUMA: " |
| 348 | "short ibm,associativity-reference-points\n"); | ||
| 349 | goto err; | ||
| 350 | } | ||
| 351 | |||
| 352 | depth = distance_ref_points[1]; | ||
| 311 | } | 353 | } |
| 312 | of_node_put(rtas_root); | ||
| 313 | 354 | ||
| 355 | /* | ||
| 356 | * Warn and cap if the hardware supports more than | ||
| 357 | * MAX_DISTANCE_REF_POINTS domains. | ||
| 358 | */ | ||
| 359 | if (distance_ref_points_depth > MAX_DISTANCE_REF_POINTS) { | ||
| 360 | printk(KERN_WARNING "NUMA: distance array capped at " | ||
| 361 | "%d entries\n", MAX_DISTANCE_REF_POINTS); | ||
| 362 | distance_ref_points_depth = MAX_DISTANCE_REF_POINTS; | ||
| 363 | } | ||
| 364 | |||
| 365 | of_node_put(rtas_root); | ||
| 314 | return depth; | 366 | return depth; |
| 367 | |||
| 368 | err: | ||
| 369 | of_node_put(rtas_root); | ||
| 370 | return -1; | ||
| 315 | } | 371 | } |
| 316 | 372 | ||
| 317 | static void __init get_n_mem_cells(int *n_addr_cells, int *n_size_cells) | 373 | static void __init get_n_mem_cells(int *n_addr_cells, int *n_size_cells) |
diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c index ebc2f38eb381..2c7e801ab20b 100644 --- a/arch/powerpc/mm/pgtable.c +++ b/arch/powerpc/mm/pgtable.c | |||
| @@ -92,7 +92,6 @@ static void pte_free_rcu_callback(struct rcu_head *head) | |||
| 92 | 92 | ||
| 93 | static void pte_free_submit(struct pte_freelist_batch *batch) | 93 | static void pte_free_submit(struct pte_freelist_batch *batch) |
| 94 | { | 94 | { |
| 95 | INIT_RCU_HEAD(&batch->rcu); | ||
| 96 | call_rcu(&batch->rcu, pte_free_rcu_callback); | 95 | call_rcu(&batch->rcu, pte_free_rcu_callback); |
| 97 | } | 96 | } |
| 98 | 97 | ||
diff --git a/arch/powerpc/mm/tlb_hash32.c b/arch/powerpc/mm/tlb_hash32.c index 8aaa8b7eb324..690566b66e8e 100644 --- a/arch/powerpc/mm/tlb_hash32.c +++ b/arch/powerpc/mm/tlb_hash32.c | |||
| @@ -89,17 +89,6 @@ void tlb_flush(struct mmu_gather *tlb) | |||
| 89 | * -- Cort | 89 | * -- Cort |
| 90 | */ | 90 | */ |
| 91 | 91 | ||
| 92 | /* | ||
| 93 | * 750 SMP is a Bad Idea because the 750 doesn't broadcast all | ||
| 94 | * the cache operations on the bus. Hence we need to use an IPI | ||
| 95 | * to get the other CPU(s) to invalidate their TLBs. | ||
| 96 | */ | ||
| 97 | #ifdef CONFIG_SMP_750 | ||
| 98 | #define FINISH_FLUSH smp_send_tlb_invalidate(0) | ||
| 99 | #else | ||
| 100 | #define FINISH_FLUSH do { } while (0) | ||
| 101 | #endif | ||
| 102 | |||
| 103 | static void flush_range(struct mm_struct *mm, unsigned long start, | 92 | static void flush_range(struct mm_struct *mm, unsigned long start, |
| 104 | unsigned long end) | 93 | unsigned long end) |
| 105 | { | 94 | { |
| @@ -138,7 +127,6 @@ static void flush_range(struct mm_struct *mm, unsigned long start, | |||
| 138 | void flush_tlb_kernel_range(unsigned long start, unsigned long end) | 127 | void flush_tlb_kernel_range(unsigned long start, unsigned long end) |
| 139 | { | 128 | { |
| 140 | flush_range(&init_mm, start, end); | 129 | flush_range(&init_mm, start, end); |
| 141 | FINISH_FLUSH; | ||
| 142 | } | 130 | } |
| 143 | EXPORT_SYMBOL(flush_tlb_kernel_range); | 131 | EXPORT_SYMBOL(flush_tlb_kernel_range); |
| 144 | 132 | ||
| @@ -162,7 +150,6 @@ void flush_tlb_mm(struct mm_struct *mm) | |||
| 162 | */ | 150 | */ |
| 163 | for (mp = mm->mmap; mp != NULL; mp = mp->vm_next) | 151 | for (mp = mm->mmap; mp != NULL; mp = mp->vm_next) |
| 164 | flush_range(mp->vm_mm, mp->vm_start, mp->vm_end); | 152 | flush_range(mp->vm_mm, mp->vm_start, mp->vm_end); |
| 165 | FINISH_FLUSH; | ||
| 166 | } | 153 | } |
| 167 | EXPORT_SYMBOL(flush_tlb_mm); | 154 | EXPORT_SYMBOL(flush_tlb_mm); |
| 168 | 155 | ||
| @@ -179,7 +166,6 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr) | |||
| 179 | pmd = pmd_offset(pud_offset(pgd_offset(mm, vmaddr), vmaddr), vmaddr); | 166 | pmd = pmd_offset(pud_offset(pgd_offset(mm, vmaddr), vmaddr), vmaddr); |
| 180 | if (!pmd_none(*pmd)) | 167 | if (!pmd_none(*pmd)) |
| 181 | flush_hash_pages(mm->context.id, vmaddr, pmd_val(*pmd), 1); | 168 | flush_hash_pages(mm->context.id, vmaddr, pmd_val(*pmd), 1); |
| 182 | FINISH_FLUSH; | ||
| 183 | } | 169 | } |
| 184 | EXPORT_SYMBOL(flush_tlb_page); | 170 | EXPORT_SYMBOL(flush_tlb_page); |
| 185 | 171 | ||
| @@ -192,6 +178,5 @@ void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, | |||
| 192 | unsigned long end) | 178 | unsigned long end) |
| 193 | { | 179 | { |
| 194 | flush_range(vma->vm_mm, start, end); | 180 | flush_range(vma->vm_mm, start, end); |
| 195 | FINISH_FLUSH; | ||
| 196 | } | 181 | } |
| 197 | EXPORT_SYMBOL(flush_tlb_range); | 182 | EXPORT_SYMBOL(flush_tlb_range); |
diff --git a/arch/powerpc/mm/tlb_nohash.c b/arch/powerpc/mm/tlb_nohash.c index d8695b02a968..fe391e942521 100644 --- a/arch/powerpc/mm/tlb_nohash.c +++ b/arch/powerpc/mm/tlb_nohash.c | |||
| @@ -46,6 +46,7 @@ | |||
| 46 | struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT] = { | 46 | struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT] = { |
| 47 | [MMU_PAGE_4K] = { | 47 | [MMU_PAGE_4K] = { |
| 48 | .shift = 12, | 48 | .shift = 12, |
| 49 | .ind = 20, | ||
| 49 | .enc = BOOK3E_PAGESZ_4K, | 50 | .enc = BOOK3E_PAGESZ_4K, |
| 50 | }, | 51 | }, |
| 51 | [MMU_PAGE_16K] = { | 52 | [MMU_PAGE_16K] = { |
| @@ -54,6 +55,7 @@ struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT] = { | |||
| 54 | }, | 55 | }, |
| 55 | [MMU_PAGE_64K] = { | 56 | [MMU_PAGE_64K] = { |
| 56 | .shift = 16, | 57 | .shift = 16, |
| 58 | .ind = 28, | ||
| 57 | .enc = BOOK3E_PAGESZ_64K, | 59 | .enc = BOOK3E_PAGESZ_64K, |
| 58 | }, | 60 | }, |
| 59 | [MMU_PAGE_1M] = { | 61 | [MMU_PAGE_1M] = { |
| @@ -62,6 +64,7 @@ struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT] = { | |||
| 62 | }, | 64 | }, |
| 63 | [MMU_PAGE_16M] = { | 65 | [MMU_PAGE_16M] = { |
| 64 | .shift = 24, | 66 | .shift = 24, |
| 67 | .ind = 36, | ||
| 65 | .enc = BOOK3E_PAGESZ_16M, | 68 | .enc = BOOK3E_PAGESZ_16M, |
| 66 | }, | 69 | }, |
| 67 | [MMU_PAGE_256M] = { | 70 | [MMU_PAGE_256M] = { |
| @@ -344,16 +347,108 @@ void tlb_flush_pgtable(struct mmu_gather *tlb, unsigned long address) | |||
| 344 | } | 347 | } |
| 345 | } | 348 | } |
| 346 | 349 | ||
| 347 | /* | 350 | static void setup_page_sizes(void) |
| 348 | * Early initialization of the MMU TLB code | 351 | { |
| 349 | */ | 352 | unsigned int tlb0cfg = mfspr(SPRN_TLB0CFG); |
| 350 | static void __early_init_mmu(int boot_cpu) | 353 | unsigned int tlb0ps = mfspr(SPRN_TLB0PS); |
| 354 | unsigned int eptcfg = mfspr(SPRN_EPTCFG); | ||
| 355 | int i, psize; | ||
| 356 | |||
| 357 | /* Look for supported direct sizes */ | ||
| 358 | for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) { | ||
| 359 | struct mmu_psize_def *def = &mmu_psize_defs[psize]; | ||
| 360 | |||
| 361 | if (tlb0ps & (1U << (def->shift - 10))) | ||
| 362 | def->flags |= MMU_PAGE_SIZE_DIRECT; | ||
| 363 | } | ||
| 364 | |||
| 365 | /* Indirect page sizes supported ? */ | ||
| 366 | if ((tlb0cfg & TLBnCFG_IND) == 0) | ||
| 367 | goto no_indirect; | ||
| 368 | |||
| 369 | /* Now, we only deal with one IND page size for each | ||
| 370 | * direct size. Hopefully all implementations today are | ||
| 371 | * unambiguous, but we might want to be careful in the | ||
| 372 | * future. | ||
| 373 | */ | ||
| 374 | for (i = 0; i < 3; i++) { | ||
| 375 | unsigned int ps, sps; | ||
| 376 | |||
| 377 | sps = eptcfg & 0x1f; | ||
| 378 | eptcfg >>= 5; | ||
| 379 | ps = eptcfg & 0x1f; | ||
| 380 | eptcfg >>= 5; | ||
| 381 | if (!ps || !sps) | ||
| 382 | continue; | ||
| 383 | for (psize = 0; psize < MMU_PAGE_COUNT; psize++) { | ||
| 384 | struct mmu_psize_def *def = &mmu_psize_defs[psize]; | ||
| 385 | |||
| 386 | if (ps == (def->shift - 10)) | ||
| 387 | def->flags |= MMU_PAGE_SIZE_INDIRECT; | ||
| 388 | if (sps == (def->shift - 10)) | ||
| 389 | def->ind = ps + 10; | ||
| 390 | } | ||
| 391 | } | ||
| 392 | no_indirect: | ||
| 393 | |||
| 394 | /* Cleanup array and print summary */ | ||
| 395 | pr_info("MMU: Supported page sizes\n"); | ||
| 396 | for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) { | ||
| 397 | struct mmu_psize_def *def = &mmu_psize_defs[psize]; | ||
| 398 | const char *__page_type_names[] = { | ||
| 399 | "unsupported", | ||
| 400 | "direct", | ||
| 401 | "indirect", | ||
| 402 | "direct & indirect" | ||
| 403 | }; | ||
| 404 | if (def->flags == 0) { | ||
| 405 | def->shift = 0; | ||
| 406 | continue; | ||
| 407 | } | ||
| 408 | pr_info(" %8ld KB as %s\n", 1ul << (def->shift - 10), | ||
| 409 | __page_type_names[def->flags & 0x3]); | ||
| 410 | } | ||
| 411 | } | ||
| 412 | |||
| 413 | static void setup_mmu_htw(void) | ||
| 351 | { | 414 | { |
| 352 | extern unsigned int interrupt_base_book3e; | 415 | extern unsigned int interrupt_base_book3e; |
| 353 | extern unsigned int exc_data_tlb_miss_htw_book3e; | 416 | extern unsigned int exc_data_tlb_miss_htw_book3e; |
| 354 | extern unsigned int exc_instruction_tlb_miss_htw_book3e; | 417 | extern unsigned int exc_instruction_tlb_miss_htw_book3e; |
| 355 | 418 | ||
| 356 | unsigned int *ibase = &interrupt_base_book3e; | 419 | unsigned int *ibase = &interrupt_base_book3e; |
| 420 | |||
| 421 | /* Check if HW tablewalk is present, and if yes, enable it by: | ||
| 422 | * | ||
| 423 | * - patching the TLB miss handlers to branch to the | ||
| 424 | * one dedicates to it | ||
| 425 | * | ||
| 426 | * - setting the global book3e_htw_enabled | ||
| 427 | */ | ||
| 428 | unsigned int tlb0cfg = mfspr(SPRN_TLB0CFG); | ||
| 429 | |||
| 430 | if ((tlb0cfg & TLBnCFG_IND) && | ||
| 431 | (tlb0cfg & TLBnCFG_PT)) { | ||
| 432 | /* Our exceptions vectors start with a NOP and -then- a branch | ||
| 433 | * to deal with single stepping from userspace which stops on | ||
| 434 | * the second instruction. Thus we need to patch the second | ||
| 435 | * instruction of the exception, not the first one | ||
| 436 | */ | ||
| 437 | patch_branch(ibase + (0x1c0 / 4) + 1, | ||
| 438 | (unsigned long)&exc_data_tlb_miss_htw_book3e, 0); | ||
| 439 | patch_branch(ibase + (0x1e0 / 4) + 1, | ||
| 440 | (unsigned long)&exc_instruction_tlb_miss_htw_book3e, 0); | ||
| 441 | book3e_htw_enabled = 1; | ||
| 442 | } | ||
| 443 | pr_info("MMU: Book3E Page Tables %s\n", | ||
| 444 | book3e_htw_enabled ? "Enabled" : "Disabled"); | ||
| 445 | } | ||
| 446 | |||
| 447 | /* | ||
| 448 | * Early initialization of the MMU TLB code | ||
| 449 | */ | ||
| 450 | static void __early_init_mmu(int boot_cpu) | ||
| 451 | { | ||
| 357 | unsigned int mas4; | 452 | unsigned int mas4; |
| 358 | 453 | ||
| 359 | /* XXX This will have to be decided at runtime, but right | 454 | /* XXX This will have to be decided at runtime, but right |
| @@ -370,35 +465,17 @@ static void __early_init_mmu(int boot_cpu) | |||
| 370 | */ | 465 | */ |
| 371 | mmu_vmemmap_psize = MMU_PAGE_16M; | 466 | mmu_vmemmap_psize = MMU_PAGE_16M; |
| 372 | 467 | ||
| 373 | /* Check if HW tablewalk is present, and if yes, enable it by: | ||
| 374 | * | ||
| 375 | * - patching the TLB miss handlers to branch to the | ||
| 376 | * one dedicates to it | ||
| 377 | * | ||
| 378 | * - setting the global book3e_htw_enabled | ||
| 379 | * | ||
| 380 | * - Set MAS4:INDD and default page size | ||
| 381 | */ | ||
| 382 | |||
| 383 | /* XXX This code only checks for TLB 0 capabilities and doesn't | 468 | /* XXX This code only checks for TLB 0 capabilities and doesn't |
| 384 | * check what page size combos are supported by the HW. It | 469 | * check what page size combos are supported by the HW. It |
| 385 | * also doesn't handle the case where a separate array holds | 470 | * also doesn't handle the case where a separate array holds |
| 386 | * the IND entries from the array loaded by the PT. | 471 | * the IND entries from the array loaded by the PT. |
| 387 | */ | 472 | */ |
| 388 | if (boot_cpu) { | 473 | if (boot_cpu) { |
| 389 | unsigned int tlb0cfg = mfspr(SPRN_TLB0CFG); | 474 | /* Look for supported page sizes */ |
| 475 | setup_page_sizes(); | ||
| 390 | 476 | ||
| 391 | /* Check if HW loader is supported */ | 477 | /* Look for HW tablewalk support */ |
| 392 | if ((tlb0cfg & TLBnCFG_IND) && | 478 | setup_mmu_htw(); |
| 393 | (tlb0cfg & TLBnCFG_PT)) { | ||
| 394 | patch_branch(ibase + (0x1c0 / 4), | ||
| 395 | (unsigned long)&exc_data_tlb_miss_htw_book3e, 0); | ||
| 396 | patch_branch(ibase + (0x1e0 / 4), | ||
| 397 | (unsigned long)&exc_instruction_tlb_miss_htw_book3e, 0); | ||
| 398 | book3e_htw_enabled = 1; | ||
| 399 | } | ||
| 400 | pr_info("MMU: Book3E Page Tables %s\n", | ||
| 401 | book3e_htw_enabled ? "Enabled" : "Disabled"); | ||
| 402 | } | 479 | } |
| 403 | 480 | ||
| 404 | /* Set MAS4 based on page table setting */ | 481 | /* Set MAS4 based on page table setting */ |
diff --git a/arch/powerpc/oprofile/Makefile b/arch/powerpc/oprofile/Makefile index 73e1c2ca0552..e219ca43962d 100644 --- a/arch/powerpc/oprofile/Makefile +++ b/arch/powerpc/oprofile/Makefile | |||
| @@ -16,6 +16,6 @@ oprofile-y := $(DRIVER_OBJS) common.o backtrace.o | |||
| 16 | oprofile-$(CONFIG_OPROFILE_CELL) += op_model_cell.o \ | 16 | oprofile-$(CONFIG_OPROFILE_CELL) += op_model_cell.o \ |
| 17 | cell/spu_profiler.o cell/vma_map.o \ | 17 | cell/spu_profiler.o cell/vma_map.o \ |
| 18 | cell/spu_task_sync.o | 18 | cell/spu_task_sync.o |
| 19 | oprofile-$(CONFIG_PPC64) += op_model_rs64.o op_model_power4.o op_model_pa6t.o | 19 | oprofile-$(CONFIG_PPC_BOOK3S_64) += op_model_rs64.o op_model_power4.o op_model_pa6t.o |
| 20 | oprofile-$(CONFIG_FSL_EMB_PERFMON) += op_model_fsl_emb.o | 20 | oprofile-$(CONFIG_FSL_EMB_PERFMON) += op_model_fsl_emb.o |
| 21 | oprofile-$(CONFIG_6xx) += op_model_7450.o | 21 | oprofile-$(CONFIG_6xx) += op_model_7450.o |
diff --git a/arch/powerpc/oprofile/common.c b/arch/powerpc/oprofile/common.c index 21f16edf6c8d..d65e68f3cb25 100644 --- a/arch/powerpc/oprofile/common.c +++ b/arch/powerpc/oprofile/common.c | |||
| @@ -199,7 +199,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) | |||
| 199 | return -ENODEV; | 199 | return -ENODEV; |
| 200 | 200 | ||
| 201 | switch (cur_cpu_spec->oprofile_type) { | 201 | switch (cur_cpu_spec->oprofile_type) { |
| 202 | #ifdef CONFIG_PPC64 | 202 | #ifdef CONFIG_PPC_BOOK3S_64 |
| 203 | #ifdef CONFIG_OPROFILE_CELL | 203 | #ifdef CONFIG_OPROFILE_CELL |
| 204 | case PPC_OPROFILE_CELL: | 204 | case PPC_OPROFILE_CELL: |
| 205 | if (firmware_has_feature(FW_FEATURE_LPAR)) | 205 | if (firmware_has_feature(FW_FEATURE_LPAR)) |
diff --git a/arch/powerpc/platforms/40x/Kconfig b/arch/powerpc/platforms/40x/Kconfig index ec64264f7a50..b72176434ebe 100644 --- a/arch/powerpc/platforms/40x/Kconfig +++ b/arch/powerpc/platforms/40x/Kconfig | |||
| @@ -71,22 +71,6 @@ config MAKALU | |||
| 71 | help | 71 | help |
| 72 | This option enables support for the AMCC PPC405EX board. | 72 | This option enables support for the AMCC PPC405EX board. |
| 73 | 73 | ||
| 74 | #config REDWOOD_5 | ||
| 75 | # bool "Redwood-5" | ||
| 76 | # depends on 40x | ||
| 77 | # default n | ||
| 78 | # select STB03xxx | ||
| 79 | # help | ||
| 80 | # This option enables support for the IBM STB04 evaluation board. | ||
| 81 | |||
| 82 | #config REDWOOD_6 | ||
| 83 | # bool "Redwood-6" | ||
| 84 | # depends on 40x | ||
| 85 | # default n | ||
| 86 | # select STB03xxx | ||
| 87 | # help | ||
| 88 | # This option enables support for the IBM STBx25xx evaluation board. | ||
| 89 | |||
| 90 | #config SYCAMORE | 74 | #config SYCAMORE |
| 91 | # bool "Sycamore" | 75 | # bool "Sycamore" |
| 92 | # depends on 40x | 76 | # depends on 40x |
diff --git a/arch/powerpc/platforms/512x/Kconfig b/arch/powerpc/platforms/512x/Kconfig index 4dac9b0525a4..27b0651221d1 100644 --- a/arch/powerpc/platforms/512x/Kconfig +++ b/arch/powerpc/platforms/512x/Kconfig | |||
| @@ -1,32 +1,34 @@ | |||
| 1 | config PPC_MPC512x | 1 | config PPC_MPC512x |
| 2 | bool | 2 | bool "512x-based boards" |
| 3 | depends on 6xx | ||
| 3 | select FSL_SOC | 4 | select FSL_SOC |
| 4 | select IPIC | 5 | select IPIC |
| 5 | select PPC_CLOCK | 6 | select PPC_CLOCK |
| 6 | select PPC_PCI_CHOICE | 7 | select PPC_PCI_CHOICE |
| 7 | select FSL_PCI if PCI | 8 | select FSL_PCI if PCI |
| 8 | 9 | ||
| 9 | config PPC_MPC5121 | ||
| 10 | bool | ||
| 11 | select PPC_MPC512x | ||
| 12 | |||
| 13 | config MPC5121_ADS | 10 | config MPC5121_ADS |
| 14 | bool "Freescale MPC5121E ADS" | 11 | bool "Freescale MPC5121E ADS" |
| 15 | depends on 6xx | 12 | depends on PPC_MPC512x |
| 16 | select DEFAULT_UIMAGE | 13 | select DEFAULT_UIMAGE |
| 17 | select PPC_MPC5121 | ||
| 18 | select MPC5121_ADS_CPLD | 14 | select MPC5121_ADS_CPLD |
| 19 | help | 15 | help |
| 20 | This option enables support for the MPC5121E ADS board. | 16 | This option enables support for the MPC5121E ADS board. |
| 21 | 17 | ||
| 22 | config MPC5121_GENERIC | 18 | config MPC5121_GENERIC |
| 23 | bool "Generic support for simple MPC5121 based boards" | 19 | bool "Generic support for simple MPC5121 based boards" |
| 24 | depends on 6xx | 20 | depends on PPC_MPC512x |
| 25 | select DEFAULT_UIMAGE | 21 | select DEFAULT_UIMAGE |
| 26 | select PPC_MPC5121 | ||
| 27 | help | 22 | help |
| 28 | This option enables support for simple MPC5121 based boards | 23 | This option enables support for simple MPC5121 based boards |
| 29 | which do not need custom platform specific setup. | 24 | which do not need custom platform specific setup. |
| 30 | 25 | ||
| 31 | Compatible boards include: Protonic LVT base boards (ZANMCU | 26 | Compatible boards include: Protonic LVT base boards (ZANMCU |
| 32 | and VICVT2). | 27 | and VICVT2). |
| 28 | |||
| 29 | config PDM360NG | ||
| 30 | bool "ifm PDM360NG board" | ||
| 31 | depends on PPC_MPC512x | ||
| 32 | select DEFAULT_UIMAGE | ||
| 33 | help | ||
| 34 | This option enables support for the PDM360NG board. | ||
diff --git a/arch/powerpc/platforms/512x/Makefile b/arch/powerpc/platforms/512x/Makefile index 90be2f5717e6..4efc1c4b6fb5 100644 --- a/arch/powerpc/platforms/512x/Makefile +++ b/arch/powerpc/platforms/512x/Makefile | |||
| @@ -4,3 +4,4 @@ | |||
| 4 | obj-y += clock.o mpc512x_shared.o | 4 | obj-y += clock.o mpc512x_shared.o |
| 5 | obj-$(CONFIG_MPC5121_ADS) += mpc5121_ads.o mpc5121_ads_cpld.o | 5 | obj-$(CONFIG_MPC5121_ADS) += mpc5121_ads.o mpc5121_ads_cpld.o |
| 6 | obj-$(CONFIG_MPC5121_GENERIC) += mpc5121_generic.o | 6 | obj-$(CONFIG_MPC5121_GENERIC) += mpc5121_generic.o |
| 7 | obj-$(CONFIG_PDM360NG) += pdm360ng.o | ||
diff --git a/arch/powerpc/platforms/512x/clock.c b/arch/powerpc/platforms/512x/clock.c index 4c42246b86a7..5b243bd3eb3b 100644 --- a/arch/powerpc/platforms/512x/clock.c +++ b/arch/powerpc/platforms/512x/clock.c | |||
| @@ -292,6 +292,15 @@ static void diu_clk_calc(struct clk *clk) | |||
| 292 | clk->rate = rate; | 292 | clk->rate = rate; |
| 293 | } | 293 | } |
| 294 | 294 | ||
| 295 | static void viu_clk_calc(struct clk *clk) | ||
| 296 | { | ||
| 297 | unsigned long rate; | ||
| 298 | |||
| 299 | rate = sys_clk.rate; | ||
| 300 | rate /= 2; | ||
| 301 | clk->rate = rate; | ||
| 302 | } | ||
| 303 | |||
| 295 | static void half_clk_calc(struct clk *clk) | 304 | static void half_clk_calc(struct clk *clk) |
| 296 | { | 305 | { |
| 297 | clk->rate = clk->parent->rate / 2; | 306 | clk->rate = clk->parent->rate / 2; |
| @@ -412,6 +421,14 @@ static struct clk diu_clk = { | |||
| 412 | .calc = diu_clk_calc, | 421 | .calc = diu_clk_calc, |
| 413 | }; | 422 | }; |
| 414 | 423 | ||
| 424 | static struct clk viu_clk = { | ||
| 425 | .name = "viu_clk", | ||
| 426 | .flags = CLK_HAS_CTRL, | ||
| 427 | .reg = 1, | ||
| 428 | .bit = 18, | ||
| 429 | .calc = viu_clk_calc, | ||
| 430 | }; | ||
| 431 | |||
| 415 | static struct clk axe_clk = { | 432 | static struct clk axe_clk = { |
| 416 | .name = "axe_clk", | 433 | .name = "axe_clk", |
| 417 | .flags = CLK_HAS_CTRL, | 434 | .flags = CLK_HAS_CTRL, |
| @@ -535,6 +552,7 @@ struct clk *rate_clks[] = { | |||
| 535 | &ref_clk, | 552 | &ref_clk, |
| 536 | &sys_clk, | 553 | &sys_clk, |
| 537 | &diu_clk, | 554 | &diu_clk, |
| 555 | &viu_clk, | ||
| 538 | &csb_clk, | 556 | &csb_clk, |
| 539 | &e300_clk, | 557 | &e300_clk, |
| 540 | &ips_clk, | 558 | &ips_clk, |
| @@ -660,7 +678,7 @@ static void psc_clks_init(void) | |||
| 660 | { | 678 | { |
| 661 | struct device_node *np; | 679 | struct device_node *np; |
| 662 | const u32 *cell_index; | 680 | const u32 *cell_index; |
| 663 | struct of_device *ofdev; | 681 | struct platform_device *ofdev; |
| 664 | 682 | ||
| 665 | for_each_compatible_node(np, NULL, "fsl,mpc5121-psc") { | 683 | for_each_compatible_node(np, NULL, "fsl,mpc5121-psc") { |
| 666 | cell_index = of_get_property(np, "cell-index", NULL); | 684 | cell_index = of_get_property(np, "cell-index", NULL); |
diff --git a/arch/powerpc/platforms/512x/mpc5121_ads.c b/arch/powerpc/platforms/512x/mpc5121_ads.c index ee6ae129c25c..dcef6ade48e1 100644 --- a/arch/powerpc/platforms/512x/mpc5121_ads.c +++ b/arch/powerpc/platforms/512x/mpc5121_ads.c | |||
| @@ -42,6 +42,7 @@ static void __init mpc5121_ads_setup_arch(void) | |||
| 42 | for_each_compatible_node(np, "pci", "fsl,mpc5121-pci") | 42 | for_each_compatible_node(np, "pci", "fsl,mpc5121-pci") |
| 43 | mpc83xx_add_bridge(np); | 43 | mpc83xx_add_bridge(np); |
| 44 | #endif | 44 | #endif |
| 45 | mpc512x_setup_diu(); | ||
| 45 | } | 46 | } |
| 46 | 47 | ||
| 47 | static void __init mpc5121_ads_init_IRQ(void) | 48 | static void __init mpc5121_ads_init_IRQ(void) |
| @@ -65,6 +66,7 @@ define_machine(mpc5121_ads) { | |||
| 65 | .probe = mpc5121_ads_probe, | 66 | .probe = mpc5121_ads_probe, |
| 66 | .setup_arch = mpc5121_ads_setup_arch, | 67 | .setup_arch = mpc5121_ads_setup_arch, |
| 67 | .init = mpc512x_init, | 68 | .init = mpc512x_init, |
| 69 | .init_early = mpc512x_init_diu, | ||
| 68 | .init_IRQ = mpc5121_ads_init_IRQ, | 70 | .init_IRQ = mpc5121_ads_init_IRQ, |
| 69 | .get_irq = ipic_get_irq, | 71 | .get_irq = ipic_get_irq, |
| 70 | .calibrate_decr = generic_calibrate_decr, | 72 | .calibrate_decr = generic_calibrate_decr, |
diff --git a/arch/powerpc/platforms/512x/mpc5121_generic.c b/arch/powerpc/platforms/512x/mpc5121_generic.c index a6c0e3a2615d..e487eb06ec6b 100644 --- a/arch/powerpc/platforms/512x/mpc5121_generic.c +++ b/arch/powerpc/platforms/512x/mpc5121_generic.c | |||
| @@ -52,6 +52,8 @@ define_machine(mpc5121_generic) { | |||
| 52 | .name = "MPC5121 generic", | 52 | .name = "MPC5121 generic", |
| 53 | .probe = mpc5121_generic_probe, | 53 | .probe = mpc5121_generic_probe, |
| 54 | .init = mpc512x_init, | 54 | .init = mpc512x_init, |
| 55 | .init_early = mpc512x_init_diu, | ||
| 56 | .setup_arch = mpc512x_setup_diu, | ||
| 55 | .init_IRQ = mpc512x_init_IRQ, | 57 | .init_IRQ = mpc512x_init_IRQ, |
| 56 | .get_irq = ipic_get_irq, | 58 | .get_irq = ipic_get_irq, |
| 57 | .calibrate_decr = generic_calibrate_decr, | 59 | .calibrate_decr = generic_calibrate_decr, |
diff --git a/arch/powerpc/platforms/512x/mpc512x.h b/arch/powerpc/platforms/512x/mpc512x.h index b2daca0d1488..1ab6d11d0b19 100644 --- a/arch/powerpc/platforms/512x/mpc512x.h +++ b/arch/powerpc/platforms/512x/mpc512x.h | |||
| @@ -16,4 +16,6 @@ extern void __init mpc512x_init(void); | |||
| 16 | extern int __init mpc5121_clk_init(void); | 16 | extern int __init mpc5121_clk_init(void); |
| 17 | void __init mpc512x_declare_of_platform_devices(void); | 17 | void __init mpc512x_declare_of_platform_devices(void); |
| 18 | extern void mpc512x_restart(char *cmd); | 18 | extern void mpc512x_restart(char *cmd); |
| 19 | extern void mpc512x_init_diu(void); | ||
| 20 | extern void mpc512x_setup_diu(void); | ||
| 19 | #endif /* __MPC512X_H__ */ | 21 | #endif /* __MPC512X_H__ */ |
diff --git a/arch/powerpc/platforms/512x/mpc512x_shared.c b/arch/powerpc/platforms/512x/mpc512x_shared.c index 707e572b7c40..e41ebbdb3e12 100644 --- a/arch/powerpc/platforms/512x/mpc512x_shared.c +++ b/arch/powerpc/platforms/512x/mpc512x_shared.c | |||
| @@ -16,7 +16,11 @@ | |||
| 16 | #include <linux/io.h> | 16 | #include <linux/io.h> |
| 17 | #include <linux/irq.h> | 17 | #include <linux/irq.h> |
| 18 | #include <linux/of_platform.h> | 18 | #include <linux/of_platform.h> |
| 19 | #include <linux/fsl-diu-fb.h> | ||
| 20 | #include <linux/bootmem.h> | ||
| 21 | #include <sysdev/fsl_soc.h> | ||
| 19 | 22 | ||
| 23 | #include <asm/cacheflush.h> | ||
| 20 | #include <asm/machdep.h> | 24 | #include <asm/machdep.h> |
| 21 | #include <asm/ipic.h> | 25 | #include <asm/ipic.h> |
| 22 | #include <asm/prom.h> | 26 | #include <asm/prom.h> |
| @@ -54,6 +58,286 @@ void mpc512x_restart(char *cmd) | |||
| 54 | ; | 58 | ; |
| 55 | } | 59 | } |
| 56 | 60 | ||
| 61 | struct fsl_diu_shared_fb { | ||
| 62 | u8 gamma[0x300]; /* 32-bit aligned! */ | ||
| 63 | struct diu_ad ad0; /* 32-bit aligned! */ | ||
| 64 | phys_addr_t fb_phys; | ||
| 65 | size_t fb_len; | ||
| 66 | bool in_use; | ||
| 67 | }; | ||
| 68 | |||
| 69 | unsigned int mpc512x_get_pixel_format(unsigned int bits_per_pixel, | ||
| 70 | int monitor_port) | ||
| 71 | { | ||
| 72 | switch (bits_per_pixel) { | ||
| 73 | case 32: | ||
| 74 | return 0x88883316; | ||
| 75 | case 24: | ||
| 76 | return 0x88082219; | ||
| 77 | case 16: | ||
| 78 | return 0x65053118; | ||
| 79 | } | ||
| 80 | return 0x00000400; | ||
| 81 | } | ||
| 82 | |||
| 83 | void mpc512x_set_gamma_table(int monitor_port, char *gamma_table_base) | ||
| 84 | { | ||
| 85 | } | ||
| 86 | |||
| 87 | void mpc512x_set_monitor_port(int monitor_port) | ||
| 88 | { | ||
| 89 | } | ||
| 90 | |||
| 91 | #define DIU_DIV_MASK 0x000000ff | ||
| 92 | void mpc512x_set_pixel_clock(unsigned int pixclock) | ||
| 93 | { | ||
| 94 | unsigned long bestval, bestfreq, speed, busfreq; | ||
| 95 | unsigned long minpixclock, maxpixclock, pixval; | ||
| 96 | struct mpc512x_ccm __iomem *ccm; | ||
| 97 | struct device_node *np; | ||
| 98 | u32 temp; | ||
| 99 | long err; | ||
| 100 | int i; | ||
| 101 | |||
| 102 | np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-clock"); | ||
| 103 | if (!np) { | ||
| 104 | pr_err("Can't find clock control module.\n"); | ||
| 105 | return; | ||
| 106 | } | ||
| 107 | |||
| 108 | ccm = of_iomap(np, 0); | ||
| 109 | of_node_put(np); | ||
| 110 | if (!ccm) { | ||
| 111 | pr_err("Can't map clock control module reg.\n"); | ||
| 112 | return; | ||
| 113 | } | ||
| 114 | |||
| 115 | np = of_find_node_by_type(NULL, "cpu"); | ||
| 116 | if (np) { | ||
| 117 | const unsigned int *prop = | ||
| 118 | of_get_property(np, "bus-frequency", NULL); | ||
| 119 | |||
| 120 | of_node_put(np); | ||
| 121 | if (prop) { | ||
| 122 | busfreq = *prop; | ||
| 123 | } else { | ||
| 124 | pr_err("Can't get bus-frequency property\n"); | ||
| 125 | return; | ||
| 126 | } | ||
| 127 | } else { | ||
| 128 | pr_err("Can't find 'cpu' node.\n"); | ||
| 129 | return; | ||
| 130 | } | ||
| 131 | |||
| 132 | /* Pixel Clock configuration */ | ||
| 133 | pr_debug("DIU: Bus Frequency = %lu\n", busfreq); | ||
| 134 | speed = busfreq * 4; /* DIU_DIV ratio is 4 * CSB_CLK / DIU_CLK */ | ||
| 135 | |||
| 136 | /* Calculate the pixel clock with the smallest error */ | ||
| 137 | /* calculate the following in steps to avoid overflow */ | ||
| 138 | pr_debug("DIU pixclock in ps - %d\n", pixclock); | ||
| 139 | temp = (1000000000 / pixclock) * 1000; | ||
| 140 | pixclock = temp; | ||
| 141 | pr_debug("DIU pixclock freq - %u\n", pixclock); | ||
| 142 | |||
| 143 | temp = temp / 20; /* pixclock * 0.05 */ | ||
| 144 | pr_debug("deviation = %d\n", temp); | ||
| 145 | minpixclock = pixclock - temp; | ||
| 146 | maxpixclock = pixclock + temp; | ||
| 147 | pr_debug("DIU minpixclock - %lu\n", minpixclock); | ||
| 148 | pr_debug("DIU maxpixclock - %lu\n", maxpixclock); | ||
| 149 | pixval = speed/pixclock; | ||
| 150 | pr_debug("DIU pixval = %lu\n", pixval); | ||
| 151 | |||
| 152 | err = LONG_MAX; | ||
| 153 | bestval = pixval; | ||
| 154 | pr_debug("DIU bestval = %lu\n", bestval); | ||
| 155 | |||
| 156 | bestfreq = 0; | ||
| 157 | for (i = -1; i <= 1; i++) { | ||
| 158 | temp = speed / (pixval+i); | ||
| 159 | pr_debug("DIU test pixval i=%d, pixval=%lu, temp freq. = %u\n", | ||
| 160 | i, pixval, temp); | ||
| 161 | if ((temp < minpixclock) || (temp > maxpixclock)) | ||
| 162 | pr_debug("DIU exceeds monitor range (%lu to %lu)\n", | ||
| 163 | minpixclock, maxpixclock); | ||
| 164 | else if (abs(temp - pixclock) < err) { | ||
| 165 | pr_debug("Entered the else if block %d\n", i); | ||
| 166 | err = abs(temp - pixclock); | ||
| 167 | bestval = pixval + i; | ||
| 168 | bestfreq = temp; | ||
| 169 | } | ||
| 170 | } | ||
| 171 | |||
| 172 | pr_debug("DIU chose = %lx\n", bestval); | ||
| 173 | pr_debug("DIU error = %ld\n NomPixClk ", err); | ||
| 174 | pr_debug("DIU: Best Freq = %lx\n", bestfreq); | ||
| 175 | /* Modify DIU_DIV in CCM SCFR1 */ | ||
| 176 | temp = in_be32(&ccm->scfr1); | ||
| 177 | pr_debug("DIU: Current value of SCFR1: 0x%08x\n", temp); | ||
| 178 | temp &= ~DIU_DIV_MASK; | ||
| 179 | temp |= (bestval & DIU_DIV_MASK); | ||
| 180 | out_be32(&ccm->scfr1, temp); | ||
| 181 | pr_debug("DIU: Modified value of SCFR1: 0x%08x\n", temp); | ||
| 182 | iounmap(ccm); | ||
| 183 | } | ||
| 184 | |||
| 185 | ssize_t mpc512x_show_monitor_port(int monitor_port, char *buf) | ||
| 186 | { | ||
| 187 | return sprintf(buf, "0 - 5121 LCD\n"); | ||
| 188 | } | ||
| 189 | |||
| 190 | int mpc512x_set_sysfs_monitor_port(int val) | ||
| 191 | { | ||
| 192 | return 0; | ||
| 193 | } | ||
| 194 | |||
| 195 | static struct fsl_diu_shared_fb __attribute__ ((__aligned__(8))) diu_shared_fb; | ||
| 196 | |||
| 197 | #if defined(CONFIG_FB_FSL_DIU) || \ | ||
| 198 | defined(CONFIG_FB_FSL_DIU_MODULE) | ||
| 199 | static inline void mpc512x_free_bootmem(struct page *page) | ||
| 200 | { | ||
| 201 | __ClearPageReserved(page); | ||
| 202 | BUG_ON(PageTail(page)); | ||
| 203 | BUG_ON(atomic_read(&page->_count) > 1); | ||
| 204 | atomic_set(&page->_count, 1); | ||
| 205 | __free_page(page); | ||
| 206 | totalram_pages++; | ||
| 207 | } | ||
| 208 | |||
| 209 | void mpc512x_release_bootmem(void) | ||
| 210 | { | ||
| 211 | unsigned long addr = diu_shared_fb.fb_phys & PAGE_MASK; | ||
| 212 | unsigned long size = diu_shared_fb.fb_len; | ||
| 213 | unsigned long start, end; | ||
| 214 | |||
| 215 | if (diu_shared_fb.in_use) { | ||
| 216 | start = PFN_UP(addr); | ||
| 217 | end = PFN_DOWN(addr + size); | ||
| 218 | |||
| 219 | for (; start < end; start++) | ||
| 220 | mpc512x_free_bootmem(pfn_to_page(start)); | ||
| 221 | |||
| 222 | diu_shared_fb.in_use = false; | ||
| 223 | } | ||
| 224 | diu_ops.release_bootmem = NULL; | ||
| 225 | } | ||
| 226 | #endif | ||
| 227 | |||
| 228 | /* | ||
| 229 | * Check if DIU was pre-initialized. If so, perform steps | ||
| 230 | * needed to continue displaying through the whole boot process. | ||
| 231 | * Move area descriptor and gamma table elsewhere, they are | ||
| 232 | * destroyed by bootmem allocator otherwise. The frame buffer | ||
| 233 | * address range will be reserved in setup_arch() after bootmem | ||
| 234 | * allocator is up. | ||
| 235 | */ | ||
| 236 | void __init mpc512x_init_diu(void) | ||
| 237 | { | ||
| 238 | struct device_node *np; | ||
| 239 | struct diu __iomem *diu_reg; | ||
| 240 | phys_addr_t desc; | ||
| 241 | void __iomem *vaddr; | ||
| 242 | unsigned long mode, pix_fmt, res, bpp; | ||
| 243 | unsigned long dst; | ||
| 244 | |||
| 245 | np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-diu"); | ||
| 246 | if (!np) { | ||
| 247 | pr_err("No DIU node\n"); | ||
| 248 | return; | ||
| 249 | } | ||
| 250 | |||
| 251 | diu_reg = of_iomap(np, 0); | ||
| 252 | of_node_put(np); | ||
| 253 | if (!diu_reg) { | ||
| 254 | pr_err("Can't map DIU\n"); | ||
| 255 | return; | ||
| 256 | } | ||
| 257 | |||
| 258 | mode = in_be32(&diu_reg->diu_mode); | ||
| 259 | if (mode != MFB_MODE1) { | ||
| 260 | pr_info("%s: DIU OFF\n", __func__); | ||
| 261 | goto out; | ||
| 262 | } | ||
| 263 | |||
| 264 | desc = in_be32(&diu_reg->desc[0]); | ||
| 265 | vaddr = ioremap(desc, sizeof(struct diu_ad)); | ||
| 266 | if (!vaddr) { | ||
| 267 | pr_err("Can't map DIU area desc.\n"); | ||
| 268 | goto out; | ||
| 269 | } | ||
| 270 | memcpy(&diu_shared_fb.ad0, vaddr, sizeof(struct diu_ad)); | ||
| 271 | /* flush fb area descriptor */ | ||
| 272 | dst = (unsigned long)&diu_shared_fb.ad0; | ||
| 273 | flush_dcache_range(dst, dst + sizeof(struct diu_ad) - 1); | ||
| 274 | |||
| 275 | res = in_be32(&diu_reg->disp_size); | ||
| 276 | pix_fmt = in_le32(vaddr); | ||
| 277 | bpp = ((pix_fmt >> 16) & 0x3) + 1; | ||
| 278 | diu_shared_fb.fb_phys = in_le32(vaddr + 4); | ||
| 279 | diu_shared_fb.fb_len = ((res & 0xfff0000) >> 16) * (res & 0xfff) * bpp; | ||
| 280 | diu_shared_fb.in_use = true; | ||
| 281 | iounmap(vaddr); | ||
| 282 | |||
| 283 | desc = in_be32(&diu_reg->gamma); | ||
| 284 | vaddr = ioremap(desc, sizeof(diu_shared_fb.gamma)); | ||
| 285 | if (!vaddr) { | ||
| 286 | pr_err("Can't map DIU area desc.\n"); | ||
| 287 | diu_shared_fb.in_use = false; | ||
| 288 | goto out; | ||
| 289 | } | ||
| 290 | memcpy(&diu_shared_fb.gamma, vaddr, sizeof(diu_shared_fb.gamma)); | ||
| 291 | /* flush gamma table */ | ||
| 292 | dst = (unsigned long)&diu_shared_fb.gamma; | ||
| 293 | flush_dcache_range(dst, dst + sizeof(diu_shared_fb.gamma) - 1); | ||
| 294 | |||
| 295 | iounmap(vaddr); | ||
| 296 | out_be32(&diu_reg->gamma, virt_to_phys(&diu_shared_fb.gamma)); | ||
| 297 | out_be32(&diu_reg->desc[1], 0); | ||
| 298 | out_be32(&diu_reg->desc[2], 0); | ||
| 299 | out_be32(&diu_reg->desc[0], virt_to_phys(&diu_shared_fb.ad0)); | ||
| 300 | |||
| 301 | out: | ||
| 302 | iounmap(diu_reg); | ||
| 303 | } | ||
| 304 | |||
| 305 | void __init mpc512x_setup_diu(void) | ||
| 306 | { | ||
| 307 | int ret; | ||
| 308 | |||
| 309 | /* | ||
| 310 | * We do not allocate and configure new area for bitmap buffer | ||
| 311 | * because it would requere copying bitmap data (splash image) | ||
| 312 | * and so negatively affect boot time. Instead we reserve the | ||
| 313 | * already configured frame buffer area so that it won't be | ||
| 314 | * destroyed. The starting address of the area to reserve and | ||
| 315 | * also it's length is passed to reserve_bootmem(). It will be | ||
| 316 | * freed later on first open of fbdev, when splash image is not | ||
| 317 | * needed any more. | ||
| 318 | */ | ||
| 319 | if (diu_shared_fb.in_use) { | ||
| 320 | ret = reserve_bootmem(diu_shared_fb.fb_phys, | ||
| 321 | diu_shared_fb.fb_len, | ||
| 322 | BOOTMEM_EXCLUSIVE); | ||
| 323 | if (ret) { | ||
| 324 | pr_err("%s: reserve bootmem failed\n", __func__); | ||
| 325 | diu_shared_fb.in_use = false; | ||
| 326 | } | ||
| 327 | } | ||
| 328 | |||
| 329 | #if defined(CONFIG_FB_FSL_DIU) || \ | ||
| 330 | defined(CONFIG_FB_FSL_DIU_MODULE) | ||
| 331 | diu_ops.get_pixel_format = mpc512x_get_pixel_format; | ||
| 332 | diu_ops.set_gamma_table = mpc512x_set_gamma_table; | ||
| 333 | diu_ops.set_monitor_port = mpc512x_set_monitor_port; | ||
| 334 | diu_ops.set_pixel_clock = mpc512x_set_pixel_clock; | ||
| 335 | diu_ops.show_monitor_port = mpc512x_show_monitor_port; | ||
| 336 | diu_ops.set_sysfs_monitor_port = mpc512x_set_sysfs_monitor_port; | ||
| 337 | diu_ops.release_bootmem = mpc512x_release_bootmem; | ||
| 338 | #endif | ||
| 339 | } | ||
| 340 | |||
| 57 | void __init mpc512x_init_IRQ(void) | 341 | void __init mpc512x_init_IRQ(void) |
| 58 | { | 342 | { |
| 59 | struct device_node *np; | 343 | struct device_node *np; |
diff --git a/arch/powerpc/platforms/512x/pdm360ng.c b/arch/powerpc/platforms/512x/pdm360ng.c new file mode 100644 index 000000000000..0575e858291c --- /dev/null +++ b/arch/powerpc/platforms/512x/pdm360ng.c | |||
| @@ -0,0 +1,129 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2010 DENX Software Engineering | ||
| 3 | * | ||
| 4 | * Anatolij Gustschin, <agust@denx.de> | ||
| 5 | * | ||
| 6 | * PDM360NG board setup | ||
| 7 | * | ||
| 8 | * This is free software; you can redistribute it and/or modify it | ||
| 9 | * under the terms of the GNU General Public License as published by | ||
| 10 | * the Free Software Foundation; either version 2 of the License, or | ||
| 11 | * (at your option) any later version. | ||
| 12 | * | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <linux/kernel.h> | ||
| 16 | #include <linux/io.h> | ||
| 17 | #include <linux/of_platform.h> | ||
| 18 | |||
| 19 | #include <asm/machdep.h> | ||
| 20 | #include <asm/ipic.h> | ||
| 21 | |||
| 22 | #include "mpc512x.h" | ||
| 23 | |||
| 24 | #if defined(CONFIG_TOUCHSCREEN_ADS7846) || \ | ||
| 25 | defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) | ||
| 26 | #include <linux/interrupt.h> | ||
| 27 | #include <linux/spi/ads7846.h> | ||
| 28 | #include <linux/spi/spi.h> | ||
| 29 | #include <linux/notifier.h> | ||
| 30 | |||
| 31 | static void *pdm360ng_gpio_base; | ||
| 32 | |||
| 33 | static int pdm360ng_get_pendown_state(void) | ||
| 34 | { | ||
| 35 | u32 reg; | ||
| 36 | |||
| 37 | reg = in_be32(pdm360ng_gpio_base + 0xc); | ||
| 38 | if (reg & 0x40) | ||
| 39 | setbits32(pdm360ng_gpio_base + 0xc, 0x40); | ||
| 40 | |||
| 41 | reg = in_be32(pdm360ng_gpio_base + 0x8); | ||
| 42 | |||
| 43 | /* return 1 if pen is down */ | ||
| 44 | return (reg & 0x40) == 0; | ||
| 45 | } | ||
| 46 | |||
| 47 | static struct ads7846_platform_data pdm360ng_ads7846_pdata = { | ||
| 48 | .model = 7845, | ||
| 49 | .get_pendown_state = pdm360ng_get_pendown_state, | ||
| 50 | .irq_flags = IRQF_TRIGGER_LOW, | ||
| 51 | }; | ||
| 52 | |||
| 53 | static int __init pdm360ng_penirq_init(void) | ||
| 54 | { | ||
| 55 | struct device_node *np; | ||
| 56 | |||
| 57 | np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-gpio"); | ||
| 58 | if (!np) { | ||
| 59 | pr_err("%s: Can't find 'mpc5121-gpio' node\n", __func__); | ||
| 60 | return -ENODEV; | ||
| 61 | } | ||
| 62 | |||
| 63 | pdm360ng_gpio_base = of_iomap(np, 0); | ||
| 64 | of_node_put(np); | ||
| 65 | if (!pdm360ng_gpio_base) { | ||
| 66 | pr_err("%s: Can't map gpio regs.\n", __func__); | ||
| 67 | return -ENODEV; | ||
| 68 | } | ||
| 69 | out_be32(pdm360ng_gpio_base + 0xc, 0xffffffff); | ||
| 70 | setbits32(pdm360ng_gpio_base + 0x18, 0x2000); | ||
| 71 | setbits32(pdm360ng_gpio_base + 0x10, 0x40); | ||
| 72 | |||
| 73 | return 0; | ||
| 74 | } | ||
| 75 | |||
| 76 | static int pdm360ng_touchscreen_notifier_call(struct notifier_block *nb, | ||
| 77 | unsigned long event, void *__dev) | ||
| 78 | { | ||
| 79 | struct device *dev = __dev; | ||
| 80 | |||
| 81 | if ((event == BUS_NOTIFY_ADD_DEVICE) && | ||
| 82 | of_device_is_compatible(dev->of_node, "ti,ads7846")) { | ||
| 83 | dev->platform_data = &pdm360ng_ads7846_pdata; | ||
| 84 | return NOTIFY_OK; | ||
| 85 | } | ||
| 86 | return NOTIFY_DONE; | ||
| 87 | } | ||
| 88 | |||
| 89 | static struct notifier_block pdm360ng_touchscreen_nb = { | ||
| 90 | .notifier_call = pdm360ng_touchscreen_notifier_call, | ||
| 91 | }; | ||
| 92 | |||
| 93 | static void __init pdm360ng_touchscreen_init(void) | ||
| 94 | { | ||
| 95 | if (pdm360ng_penirq_init()) | ||
| 96 | return; | ||
| 97 | |||
| 98 | bus_register_notifier(&spi_bus_type, &pdm360ng_touchscreen_nb); | ||
| 99 | } | ||
| 100 | #else | ||
| 101 | static inline void __init pdm360ng_touchscreen_init(void) | ||
| 102 | { | ||
| 103 | } | ||
| 104 | #endif /* CONFIG_TOUCHSCREEN_ADS7846 */ | ||
| 105 | |||
| 106 | void __init pdm360ng_init(void) | ||
| 107 | { | ||
| 108 | mpc512x_init(); | ||
| 109 | pdm360ng_touchscreen_init(); | ||
| 110 | } | ||
| 111 | |||
| 112 | static int __init pdm360ng_probe(void) | ||
| 113 | { | ||
| 114 | unsigned long root = of_get_flat_dt_root(); | ||
| 115 | |||
| 116 | return of_flat_dt_is_compatible(root, "ifm,pdm360ng"); | ||
| 117 | } | ||
| 118 | |||
| 119 | define_machine(pdm360ng) { | ||
| 120 | .name = "PDM360NG", | ||
| 121 | .probe = pdm360ng_probe, | ||
| 122 | .setup_arch = mpc512x_setup_diu, | ||
| 123 | .init = pdm360ng_init, | ||
| 124 | .init_early = mpc512x_init_diu, | ||
| 125 | .init_IRQ = mpc512x_init_IRQ, | ||
| 126 | .get_irq = ipic_get_irq, | ||
| 127 | .calibrate_decr = generic_calibrate_decr, | ||
| 128 | .restart = mpc512x_restart, | ||
| 129 | }; | ||
diff --git a/arch/powerpc/platforms/52xx/lite5200.c b/arch/powerpc/platforms/52xx/lite5200.c index 6d584f4e3c9a..de55bc0584b5 100644 --- a/arch/powerpc/platforms/52xx/lite5200.c +++ b/arch/powerpc/platforms/52xx/lite5200.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
| 19 | #include <linux/pci.h> | 19 | #include <linux/pci.h> |
| 20 | #include <linux/of.h> | 20 | #include <linux/of.h> |
| 21 | #include <linux/of_address.h> | ||
| 21 | #include <linux/root_dev.h> | 22 | #include <linux/root_dev.h> |
| 22 | #include <linux/initrd.h> | 23 | #include <linux/initrd.h> |
| 23 | #include <asm/time.h> | 24 | #include <asm/time.h> |
diff --git a/arch/powerpc/platforms/52xx/lite5200_pm.c b/arch/powerpc/platforms/52xx/lite5200_pm.c index b5c753db125e..80234e5921f5 100644 --- a/arch/powerpc/platforms/52xx/lite5200_pm.c +++ b/arch/powerpc/platforms/52xx/lite5200_pm.c | |||
| @@ -216,9 +216,6 @@ static int lite5200_pm_enter(suspend_state_t state) | |||
| 216 | 216 | ||
| 217 | lite5200_restore_regs(); | 217 | lite5200_restore_regs(); |
| 218 | 218 | ||
| 219 | /* restart jiffies */ | ||
| 220 | wakeup_decrementer(); | ||
| 221 | |||
| 222 | iounmap(mbar); | 219 | iounmap(mbar); |
| 223 | return 0; | 220 | return 0; |
| 224 | } | 221 | } |
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c index ca5305a5bd61..0dad9a935eb5 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c | |||
| @@ -147,26 +147,25 @@ mpc52xx_wkup_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) | |||
| 147 | return 0; | 147 | return 0; |
| 148 | } | 148 | } |
| 149 | 149 | ||
| 150 | static int __devinit mpc52xx_wkup_gpiochip_probe(struct of_device *ofdev, | 150 | static int __devinit mpc52xx_wkup_gpiochip_probe(struct platform_device *ofdev, |
| 151 | const struct of_device_id *match) | 151 | const struct of_device_id *match) |
| 152 | { | 152 | { |
| 153 | struct mpc52xx_gpiochip *chip; | 153 | struct mpc52xx_gpiochip *chip; |
| 154 | struct mpc52xx_gpio_wkup __iomem *regs; | 154 | struct mpc52xx_gpio_wkup __iomem *regs; |
| 155 | struct of_gpio_chip *ofchip; | 155 | struct gpio_chip *gc; |
| 156 | int ret; | 156 | int ret; |
| 157 | 157 | ||
| 158 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | 158 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); |
| 159 | if (!chip) | 159 | if (!chip) |
| 160 | return -ENOMEM; | 160 | return -ENOMEM; |
| 161 | 161 | ||
| 162 | ofchip = &chip->mmchip.of_gc; | 162 | gc = &chip->mmchip.gc; |
| 163 | 163 | ||
| 164 | ofchip->gpio_cells = 2; | 164 | gc->ngpio = 8; |
| 165 | ofchip->gc.ngpio = 8; | 165 | gc->direction_input = mpc52xx_wkup_gpio_dir_in; |
| 166 | ofchip->gc.direction_input = mpc52xx_wkup_gpio_dir_in; | 166 | gc->direction_output = mpc52xx_wkup_gpio_dir_out; |
| 167 | ofchip->gc.direction_output = mpc52xx_wkup_gpio_dir_out; | 167 | gc->get = mpc52xx_wkup_gpio_get; |
| 168 | ofchip->gc.get = mpc52xx_wkup_gpio_get; | 168 | gc->set = mpc52xx_wkup_gpio_set; |
| 169 | ofchip->gc.set = mpc52xx_wkup_gpio_set; | ||
| 170 | 169 | ||
| 171 | ret = of_mm_gpiochip_add(ofdev->dev.of_node, &chip->mmchip); | 170 | ret = of_mm_gpiochip_add(ofdev->dev.of_node, &chip->mmchip); |
| 172 | if (ret) | 171 | if (ret) |
| @@ -180,7 +179,7 @@ static int __devinit mpc52xx_wkup_gpiochip_probe(struct of_device *ofdev, | |||
| 180 | return 0; | 179 | return 0; |
| 181 | } | 180 | } |
| 182 | 181 | ||
| 183 | static int mpc52xx_gpiochip_remove(struct of_device *ofdev) | 182 | static int mpc52xx_gpiochip_remove(struct platform_device *ofdev) |
| 184 | { | 183 | { |
| 185 | return -EBUSY; | 184 | return -EBUSY; |
| 186 | } | 185 | } |
| @@ -311,11 +310,11 @@ mpc52xx_simple_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) | |||
| 311 | return 0; | 310 | return 0; |
| 312 | } | 311 | } |
| 313 | 312 | ||
| 314 | static int __devinit mpc52xx_simple_gpiochip_probe(struct of_device *ofdev, | 313 | static int __devinit mpc52xx_simple_gpiochip_probe(struct platform_device *ofdev, |
| 315 | const struct of_device_id *match) | 314 | const struct of_device_id *match) |
| 316 | { | 315 | { |
| 317 | struct mpc52xx_gpiochip *chip; | 316 | struct mpc52xx_gpiochip *chip; |
| 318 | struct of_gpio_chip *ofchip; | 317 | struct gpio_chip *gc; |
| 319 | struct mpc52xx_gpio __iomem *regs; | 318 | struct mpc52xx_gpio __iomem *regs; |
| 320 | int ret; | 319 | int ret; |
| 321 | 320 | ||
| @@ -323,14 +322,13 @@ static int __devinit mpc52xx_simple_gpiochip_probe(struct of_device *ofdev, | |||
| 323 | if (!chip) | 322 | if (!chip) |
| 324 | return -ENOMEM; | 323 | return -ENOMEM; |
| 325 | 324 | ||
| 326 | ofchip = &chip->mmchip.of_gc; | 325 | gc = &chip->mmchip.gc; |
| 327 | 326 | ||
| 328 | ofchip->gpio_cells = 2; | 327 | gc->ngpio = 32; |
| 329 | ofchip->gc.ngpio = 32; | 328 | gc->direction_input = mpc52xx_simple_gpio_dir_in; |
| 330 | ofchip->gc.direction_input = mpc52xx_simple_gpio_dir_in; | 329 | gc->direction_output = mpc52xx_simple_gpio_dir_out; |
| 331 | ofchip->gc.direction_output = mpc52xx_simple_gpio_dir_out; | 330 | gc->get = mpc52xx_simple_gpio_get; |
| 332 | ofchip->gc.get = mpc52xx_simple_gpio_get; | 331 | gc->set = mpc52xx_simple_gpio_set; |
| 333 | ofchip->gc.set = mpc52xx_simple_gpio_set; | ||
| 334 | 332 | ||
| 335 | ret = of_mm_gpiochip_add(ofdev->dev.of_node, &chip->mmchip); | 333 | ret = of_mm_gpiochip_add(ofdev->dev.of_node, &chip->mmchip); |
| 336 | if (ret) | 334 | if (ret) |
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c index 46c93578cbf0..fea833e18ad5 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c | |||
| @@ -78,7 +78,7 @@ MODULE_LICENSE("GPL"); | |||
| 78 | * @dev: pointer to device structure | 78 | * @dev: pointer to device structure |
| 79 | * @regs: virtual address of GPT registers | 79 | * @regs: virtual address of GPT registers |
| 80 | * @lock: spinlock to coordinate between different functions. | 80 | * @lock: spinlock to coordinate between different functions. |
| 81 | * @of_gc: of_gpio_chip instance structure; used when GPIO is enabled | 81 | * @gc: gpio_chip instance structure; used when GPIO is enabled |
| 82 | * @irqhost: Pointer to irq_host instance; used when IRQ mode is supported | 82 | * @irqhost: Pointer to irq_host instance; used when IRQ mode is supported |
| 83 | * @wdt_mode: only relevant for gpt0: bit 0 (MPC52xx_GPT_CAN_WDT) indicates | 83 | * @wdt_mode: only relevant for gpt0: bit 0 (MPC52xx_GPT_CAN_WDT) indicates |
| 84 | * if the gpt may be used as wdt, bit 1 (MPC52xx_GPT_IS_WDT) indicates | 84 | * if the gpt may be used as wdt, bit 1 (MPC52xx_GPT_IS_WDT) indicates |
| @@ -94,7 +94,7 @@ struct mpc52xx_gpt_priv { | |||
| 94 | u8 wdt_mode; | 94 | u8 wdt_mode; |
| 95 | 95 | ||
| 96 | #if defined(CONFIG_GPIOLIB) | 96 | #if defined(CONFIG_GPIOLIB) |
| 97 | struct of_gpio_chip of_gc; | 97 | struct gpio_chip gc; |
| 98 | #endif | 98 | #endif |
| 99 | }; | 99 | }; |
| 100 | 100 | ||
| @@ -280,7 +280,7 @@ mpc52xx_gpt_irq_setup(struct mpc52xx_gpt_priv *gpt, struct device_node *node) | |||
| 280 | #if defined(CONFIG_GPIOLIB) | 280 | #if defined(CONFIG_GPIOLIB) |
| 281 | static inline struct mpc52xx_gpt_priv *gc_to_mpc52xx_gpt(struct gpio_chip *gc) | 281 | static inline struct mpc52xx_gpt_priv *gc_to_mpc52xx_gpt(struct gpio_chip *gc) |
| 282 | { | 282 | { |
| 283 | return container_of(to_of_gpio_chip(gc), struct mpc52xx_gpt_priv,of_gc); | 283 | return container_of(gc, struct mpc52xx_gpt_priv, gc); |
| 284 | } | 284 | } |
| 285 | 285 | ||
| 286 | static int mpc52xx_gpt_gpio_get(struct gpio_chip *gc, unsigned int gpio) | 286 | static int mpc52xx_gpt_gpio_get(struct gpio_chip *gc, unsigned int gpio) |
| @@ -336,28 +336,25 @@ mpc52xx_gpt_gpio_setup(struct mpc52xx_gpt_priv *gpt, struct device_node *node) | |||
| 336 | if (!of_find_property(node, "gpio-controller", NULL)) | 336 | if (!of_find_property(node, "gpio-controller", NULL)) |
| 337 | return; | 337 | return; |
| 338 | 338 | ||
| 339 | gpt->of_gc.gc.label = kstrdup(node->full_name, GFP_KERNEL); | 339 | gpt->gc.label = kstrdup(node->full_name, GFP_KERNEL); |
| 340 | if (!gpt->of_gc.gc.label) { | 340 | if (!gpt->gc.label) { |
| 341 | dev_err(gpt->dev, "out of memory\n"); | 341 | dev_err(gpt->dev, "out of memory\n"); |
| 342 | return; | 342 | return; |
| 343 | } | 343 | } |
| 344 | 344 | ||
| 345 | gpt->of_gc.gpio_cells = 2; | 345 | gpt->gc.ngpio = 1; |
| 346 | gpt->of_gc.gc.ngpio = 1; | 346 | gpt->gc.direction_input = mpc52xx_gpt_gpio_dir_in; |
| 347 | gpt->of_gc.gc.direction_input = mpc52xx_gpt_gpio_dir_in; | 347 | gpt->gc.direction_output = mpc52xx_gpt_gpio_dir_out; |
| 348 | gpt->of_gc.gc.direction_output = mpc52xx_gpt_gpio_dir_out; | 348 | gpt->gc.get = mpc52xx_gpt_gpio_get; |
| 349 | gpt->of_gc.gc.get = mpc52xx_gpt_gpio_get; | 349 | gpt->gc.set = mpc52xx_gpt_gpio_set; |
| 350 | gpt->of_gc.gc.set = mpc52xx_gpt_gpio_set; | 350 | gpt->gc.base = -1; |
| 351 | gpt->of_gc.gc.base = -1; | 351 | gpt->gc.of_node = node; |
| 352 | gpt->of_gc.xlate = of_gpio_simple_xlate; | ||
| 353 | node->data = &gpt->of_gc; | ||
| 354 | of_node_get(node); | ||
| 355 | 352 | ||
| 356 | /* Setup external pin in GPIO mode */ | 353 | /* Setup external pin in GPIO mode */ |
| 357 | clrsetbits_be32(&gpt->regs->mode, MPC52xx_GPT_MODE_MS_MASK, | 354 | clrsetbits_be32(&gpt->regs->mode, MPC52xx_GPT_MODE_MS_MASK, |
| 358 | MPC52xx_GPT_MODE_MS_GPIO); | 355 | MPC52xx_GPT_MODE_MS_GPIO); |
| 359 | 356 | ||
| 360 | rc = gpiochip_add(&gpt->of_gc.gc); | 357 | rc = gpiochip_add(&gpt->gc); |
| 361 | if (rc) | 358 | if (rc) |
| 362 | dev_err(gpt->dev, "gpiochip_add() failed; rc=%i\n", rc); | 359 | dev_err(gpt->dev, "gpiochip_add() failed; rc=%i\n", rc); |
| 363 | 360 | ||
| @@ -723,7 +720,7 @@ static inline int mpc52xx_gpt_wdt_setup(struct mpc52xx_gpt_priv *gpt, | |||
| 723 | /* --------------------------------------------------------------------- | 720 | /* --------------------------------------------------------------------- |
| 724 | * of_platform bus binding code | 721 | * of_platform bus binding code |
| 725 | */ | 722 | */ |
| 726 | static int __devinit mpc52xx_gpt_probe(struct of_device *ofdev, | 723 | static int __devinit mpc52xx_gpt_probe(struct platform_device *ofdev, |
| 727 | const struct of_device_id *match) | 724 | const struct of_device_id *match) |
| 728 | { | 725 | { |
| 729 | struct mpc52xx_gpt_priv *gpt; | 726 | struct mpc52xx_gpt_priv *gpt; |
| @@ -769,7 +766,7 @@ static int __devinit mpc52xx_gpt_probe(struct of_device *ofdev, | |||
| 769 | return 0; | 766 | return 0; |
| 770 | } | 767 | } |
| 771 | 768 | ||
| 772 | static int mpc52xx_gpt_remove(struct of_device *ofdev) | 769 | static int mpc52xx_gpt_remove(struct platform_device *ofdev) |
| 773 | { | 770 | { |
| 774 | return -EBUSY; | 771 | return -EBUSY; |
| 775 | } | 772 | } |
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c index e86aec644501..f4ac213c89c0 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c | |||
| @@ -436,8 +436,8 @@ void mpc52xx_lpbfifo_abort(struct mpc52xx_lpbfifo_request *req) | |||
| 436 | } | 436 | } |
| 437 | EXPORT_SYMBOL(mpc52xx_lpbfifo_abort); | 437 | EXPORT_SYMBOL(mpc52xx_lpbfifo_abort); |
| 438 | 438 | ||
| 439 | static int __devinit | 439 | static int __devinit mpc52xx_lpbfifo_probe(struct platform_device *op, |
| 440 | mpc52xx_lpbfifo_probe(struct of_device *op, const struct of_device_id *match) | 440 | const struct of_device_id *match) |
| 441 | { | 441 | { |
| 442 | struct resource res; | 442 | struct resource res; |
| 443 | int rc = -ENOMEM; | 443 | int rc = -ENOMEM; |
| @@ -507,7 +507,7 @@ mpc52xx_lpbfifo_probe(struct of_device *op, const struct of_device_id *match) | |||
| 507 | } | 507 | } |
| 508 | 508 | ||
| 509 | 509 | ||
| 510 | static int __devexit mpc52xx_lpbfifo_remove(struct of_device *op) | 510 | static int __devexit mpc52xx_lpbfifo_remove(struct platform_device *op) |
| 511 | { | 511 | { |
| 512 | if (lpbfifo.dev != &op->dev) | 512 | if (lpbfifo.dev != &op->dev) |
| 513 | return 0; | 513 | return 0; |
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pm.c b/arch/powerpc/platforms/52xx/mpc52xx_pm.c index 76722532bd95..568cef636275 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_pm.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_pm.c | |||
| @@ -171,9 +171,6 @@ int mpc52xx_pm_enter(suspend_state_t state) | |||
| 171 | /* restore SRAM */ | 171 | /* restore SRAM */ |
| 172 | memcpy(sram, saved_sram, sram_size); | 172 | memcpy(sram, saved_sram, sram_size); |
| 173 | 173 | ||
| 174 | /* restart jiffies */ | ||
| 175 | wakeup_decrementer(); | ||
| 176 | |||
| 177 | /* reenable interrupts in PIC */ | 174 | /* reenable interrupts in PIC */ |
| 178 | out_be32(&intr->main_mask, intr_main_mask); | 175 | out_be32(&intr->main_mask, intr_main_mask); |
| 179 | 176 | ||
diff --git a/arch/powerpc/platforms/82xx/ep8248e.c b/arch/powerpc/platforms/82xx/ep8248e.c index 9f2e52b36f91..1565e0446dc8 100644 --- a/arch/powerpc/platforms/82xx/ep8248e.c +++ b/arch/powerpc/platforms/82xx/ep8248e.c | |||
| @@ -111,7 +111,7 @@ static struct mdiobb_ctrl ep8248e_mdio_ctrl = { | |||
| 111 | .ops = &ep8248e_mdio_ops, | 111 | .ops = &ep8248e_mdio_ops, |
| 112 | }; | 112 | }; |
| 113 | 113 | ||
| 114 | static int __devinit ep8248e_mdio_probe(struct of_device *ofdev, | 114 | static int __devinit ep8248e_mdio_probe(struct platform_device *ofdev, |
| 115 | const struct of_device_id *match) | 115 | const struct of_device_id *match) |
| 116 | { | 116 | { |
| 117 | struct mii_bus *bus; | 117 | struct mii_bus *bus; |
| @@ -154,7 +154,7 @@ err_free_bus: | |||
| 154 | return ret; | 154 | return ret; |
| 155 | } | 155 | } |
| 156 | 156 | ||
| 157 | static int ep8248e_mdio_remove(struct of_device *ofdev) | 157 | static int ep8248e_mdio_remove(struct platform_device *ofdev) |
| 158 | { | 158 | { |
| 159 | BUG(); | 159 | BUG(); |
| 160 | return 0; | 160 | return 0; |
diff --git a/arch/powerpc/platforms/83xx/Kconfig b/arch/powerpc/platforms/83xx/Kconfig index f49a2548c5ff..021763a32c2f 100644 --- a/arch/powerpc/platforms/83xx/Kconfig +++ b/arch/powerpc/platforms/83xx/Kconfig | |||
| @@ -9,6 +9,14 @@ menuconfig PPC_83xx | |||
| 9 | 9 | ||
| 10 | if PPC_83xx | 10 | if PPC_83xx |
| 11 | 11 | ||
| 12 | config MPC830x_RDB | ||
| 13 | bool "Freescale MPC830x RDB" | ||
| 14 | select DEFAULT_UIMAGE | ||
| 15 | select PPC_MPC831x | ||
| 16 | select FSL_GTM | ||
| 17 | help | ||
| 18 | This option enables support for the MPC8308 RDB board. | ||
| 19 | |||
| 12 | config MPC831x_RDB | 20 | config MPC831x_RDB |
| 13 | bool "Freescale MPC831x RDB" | 21 | bool "Freescale MPC831x RDB" |
| 14 | select DEFAULT_UIMAGE | 22 | select DEFAULT_UIMAGE |
diff --git a/arch/powerpc/platforms/83xx/Makefile b/arch/powerpc/platforms/83xx/Makefile index e139c36572ec..6e8bbbbcfdf8 100644 --- a/arch/powerpc/platforms/83xx/Makefile +++ b/arch/powerpc/platforms/83xx/Makefile | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | obj-y := misc.o usb.o | 4 | obj-y := misc.o usb.o |
| 5 | obj-$(CONFIG_SUSPEND) += suspend.o suspend-asm.o | 5 | obj-$(CONFIG_SUSPEND) += suspend.o suspend-asm.o |
| 6 | obj-$(CONFIG_MCU_MPC8349EMITX) += mcu_mpc8349emitx.o | 6 | obj-$(CONFIG_MCU_MPC8349EMITX) += mcu_mpc8349emitx.o |
| 7 | obj-$(CONFIG_MPC830x_RDB) += mpc830x_rdb.o | ||
| 7 | obj-$(CONFIG_MPC831x_RDB) += mpc831x_rdb.o | 8 | obj-$(CONFIG_MPC831x_RDB) += mpc831x_rdb.o |
| 8 | obj-$(CONFIG_MPC832x_RDB) += mpc832x_rdb.o | 9 | obj-$(CONFIG_MPC832x_RDB) += mpc832x_rdb.o |
| 9 | obj-$(CONFIG_MPC834x_MDS) += mpc834x_mds.o | 10 | obj-$(CONFIG_MPC834x_MDS) += mpc834x_mds.o |
diff --git a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c index d119a7c1c17a..70798ac911ef 100644 --- a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c +++ b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c | |||
| @@ -35,9 +35,8 @@ | |||
| 35 | 35 | ||
| 36 | struct mcu { | 36 | struct mcu { |
| 37 | struct mutex lock; | 37 | struct mutex lock; |
| 38 | struct device_node *np; | ||
| 39 | struct i2c_client *client; | 38 | struct i2c_client *client; |
| 40 | struct of_gpio_chip of_gc; | 39 | struct gpio_chip gc; |
| 41 | u8 reg_ctrl; | 40 | u8 reg_ctrl; |
| 42 | }; | 41 | }; |
| 43 | 42 | ||
| @@ -56,8 +55,7 @@ static void mcu_power_off(void) | |||
| 56 | 55 | ||
| 57 | static void mcu_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) | 56 | static void mcu_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) |
| 58 | { | 57 | { |
| 59 | struct of_gpio_chip *of_gc = to_of_gpio_chip(gc); | 58 | struct mcu *mcu = container_of(gc, struct mcu, gc); |
| 60 | struct mcu *mcu = container_of(of_gc, struct mcu, of_gc); | ||
| 61 | u8 bit = 1 << (4 + gpio); | 59 | u8 bit = 1 << (4 + gpio); |
| 62 | 60 | ||
| 63 | mutex_lock(&mcu->lock); | 61 | mutex_lock(&mcu->lock); |
| @@ -79,9 +77,7 @@ static int mcu_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) | |||
| 79 | static int mcu_gpiochip_add(struct mcu *mcu) | 77 | static int mcu_gpiochip_add(struct mcu *mcu) |
| 80 | { | 78 | { |
| 81 | struct device_node *np; | 79 | struct device_node *np; |
| 82 | struct of_gpio_chip *of_gc = &mcu->of_gc; | 80 | struct gpio_chip *gc = &mcu->gc; |
| 83 | struct gpio_chip *gc = &of_gc->gc; | ||
| 84 | int ret; | ||
| 85 | 81 | ||
| 86 | np = of_find_compatible_node(NULL, NULL, "fsl,mcu-mpc8349emitx"); | 82 | np = of_find_compatible_node(NULL, NULL, "fsl,mcu-mpc8349emitx"); |
| 87 | if (!np) | 83 | if (!np) |
| @@ -94,32 +90,14 @@ static int mcu_gpiochip_add(struct mcu *mcu) | |||
| 94 | gc->base = -1; | 90 | gc->base = -1; |
| 95 | gc->set = mcu_gpio_set; | 91 | gc->set = mcu_gpio_set; |
| 96 | gc->direction_output = mcu_gpio_dir_out; | 92 | gc->direction_output = mcu_gpio_dir_out; |
| 97 | of_gc->gpio_cells = 2; | 93 | gc->of_node = np; |
| 98 | of_gc->xlate = of_gpio_simple_xlate; | ||
| 99 | 94 | ||
| 100 | np->data = of_gc; | 95 | return gpiochip_add(gc); |
| 101 | mcu->np = np; | ||
| 102 | |||
| 103 | /* | ||
| 104 | * We don't want to lose the node, its ->data and ->full_name... | ||
| 105 | * So, if succeeded, we don't put the node here. | ||
| 106 | */ | ||
| 107 | ret = gpiochip_add(gc); | ||
| 108 | if (ret) | ||
| 109 | of_node_put(np); | ||
| 110 | return ret; | ||
| 111 | } | 96 | } |
| 112 | 97 | ||
| 113 | static int mcu_gpiochip_remove(struct mcu *mcu) | 98 | static int mcu_gpiochip_remove(struct mcu *mcu) |
| 114 | { | 99 | { |
| 115 | int ret; | 100 | return gpiochip_remove(&mcu->gc); |
| 116 | |||
| 117 | ret = gpiochip_remove(&mcu->of_gc.gc); | ||
| 118 | if (ret) | ||
| 119 | return ret; | ||
| 120 | of_node_put(mcu->np); | ||
| 121 | |||
| 122 | return 0; | ||
| 123 | } | 101 | } |
| 124 | 102 | ||
| 125 | static int __devinit mcu_probe(struct i2c_client *client, | 103 | static int __devinit mcu_probe(struct i2c_client *client, |
| @@ -182,10 +160,16 @@ static const struct i2c_device_id mcu_ids[] = { | |||
| 182 | }; | 160 | }; |
| 183 | MODULE_DEVICE_TABLE(i2c, mcu_ids); | 161 | MODULE_DEVICE_TABLE(i2c, mcu_ids); |
| 184 | 162 | ||
| 163 | static struct of_device_id mcu_of_match_table[] __devinitdata = { | ||
| 164 | { .compatible = "fsl,mcu-mpc8349emitx", }, | ||
| 165 | { }, | ||
| 166 | }; | ||
| 167 | |||
| 185 | static struct i2c_driver mcu_driver = { | 168 | static struct i2c_driver mcu_driver = { |
| 186 | .driver = { | 169 | .driver = { |
| 187 | .name = "mcu-mpc8349emitx", | 170 | .name = "mcu-mpc8349emitx", |
| 188 | .owner = THIS_MODULE, | 171 | .owner = THIS_MODULE, |
| 172 | .of_match_table = mcu_of_match_table, | ||
| 189 | }, | 173 | }, |
| 190 | .probe = mcu_probe, | 174 | .probe = mcu_probe, |
| 191 | .remove = __devexit_p(mcu_remove), | 175 | .remove = __devexit_p(mcu_remove), |
diff --git a/arch/powerpc/platforms/83xx/mpc830x_rdb.c b/arch/powerpc/platforms/83xx/mpc830x_rdb.c new file mode 100644 index 000000000000..ac102ee9abe8 --- /dev/null +++ b/arch/powerpc/platforms/83xx/mpc830x_rdb.c | |||
| @@ -0,0 +1,94 @@ | |||
| 1 | /* | ||
| 2 | * arch/powerpc/platforms/83xx/mpc830x_rdb.c | ||
| 3 | * | ||
| 4 | * Description: MPC830x RDB board specific routines. | ||
| 5 | * This file is based on mpc831x_rdb.c | ||
| 6 | * | ||
| 7 | * Copyright (C) Freescale Semiconductor, Inc. 2009. All rights reserved. | ||
| 8 | * Copyright (C) 2010. Ilya Yanok, Emcraft Systems, yanok@emcraft.com | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify it | ||
| 11 | * under the terms of the GNU General Public License as published by the | ||
| 12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 13 | * option) any later version. | ||
| 14 | */ | ||
| 15 | |||
| 16 | #include <linux/pci.h> | ||
| 17 | #include <linux/of_platform.h> | ||
| 18 | #include <asm/time.h> | ||
| 19 | #include <asm/ipic.h> | ||
| 20 | #include <asm/udbg.h> | ||
| 21 | #include <sysdev/fsl_pci.h> | ||
| 22 | #include <sysdev/fsl_soc.h> | ||
| 23 | #include "mpc83xx.h" | ||
| 24 | |||
| 25 | /* | ||
| 26 | * Setup the architecture | ||
| 27 | */ | ||
| 28 | static void __init mpc830x_rdb_setup_arch(void) | ||
| 29 | { | ||
| 30 | #ifdef CONFIG_PCI | ||
| 31 | struct device_node *np; | ||
| 32 | #endif | ||
| 33 | |||
| 34 | if (ppc_md.progress) | ||
| 35 | ppc_md.progress("mpc830x_rdb_setup_arch()", 0); | ||
| 36 | |||
| 37 | #ifdef CONFIG_PCI | ||
| 38 | for_each_compatible_node(np, "pci", "fsl,mpc8308-pcie") | ||
| 39 | mpc83xx_add_bridge(np); | ||
| 40 | #endif | ||
| 41 | mpc831x_usb_cfg(); | ||
| 42 | } | ||
| 43 | |||
| 44 | static void __init mpc830x_rdb_init_IRQ(void) | ||
| 45 | { | ||
| 46 | struct device_node *np; | ||
| 47 | |||
| 48 | np = of_find_node_by_type(NULL, "ipic"); | ||
| 49 | if (!np) | ||
| 50 | return; | ||
| 51 | |||
| 52 | ipic_init(np, 0); | ||
| 53 | |||
| 54 | /* Initialize the default interrupt mapping priorities, | ||
| 55 | * in case the boot rom changed something on us. | ||
| 56 | */ | ||
| 57 | ipic_set_default_priority(); | ||
| 58 | } | ||
| 59 | |||
| 60 | /* | ||
| 61 | * Called very early, MMU is off, device-tree isn't unflattened | ||
| 62 | */ | ||
| 63 | static int __init mpc830x_rdb_probe(void) | ||
| 64 | { | ||
| 65 | unsigned long root = of_get_flat_dt_root(); | ||
| 66 | |||
| 67 | return of_flat_dt_is_compatible(root, "MPC8308RDB") || | ||
| 68 | of_flat_dt_is_compatible(root, "fsl,mpc8308rdb"); | ||
| 69 | } | ||
| 70 | |||
| 71 | static struct of_device_id __initdata of_bus_ids[] = { | ||
| 72 | { .compatible = "simple-bus" }, | ||
| 73 | { .compatible = "gianfar" }, | ||
| 74 | {}, | ||
| 75 | }; | ||
| 76 | |||
| 77 | static int __init declare_of_platform_devices(void) | ||
| 78 | { | ||
| 79 | of_platform_bus_probe(NULL, of_bus_ids, NULL); | ||
| 80 | return 0; | ||
| 81 | } | ||
| 82 | machine_device_initcall(mpc830x_rdb, declare_of_platform_devices); | ||
| 83 | |||
| 84 | define_machine(mpc830x_rdb) { | ||
| 85 | .name = "MPC830x RDB", | ||
| 86 | .probe = mpc830x_rdb_probe, | ||
| 87 | .setup_arch = mpc830x_rdb_setup_arch, | ||
| 88 | .init_IRQ = mpc830x_rdb_init_IRQ, | ||
| 89 | .get_irq = ipic_get_irq, | ||
| 90 | .restart = mpc83xx_restart, | ||
| 91 | .time_init = mpc83xx_time_init, | ||
| 92 | .calibrate_decr = generic_calibrate_decr, | ||
| 93 | .progress = udbg_progress, | ||
| 94 | }; | ||
diff --git a/arch/powerpc/platforms/83xx/suspend.c b/arch/powerpc/platforms/83xx/suspend.c index ebe6c3537209..75ae77f1af6a 100644 --- a/arch/powerpc/platforms/83xx/suspend.c +++ b/arch/powerpc/platforms/83xx/suspend.c | |||
| @@ -99,7 +99,7 @@ struct pmc_type { | |||
| 99 | int has_deep_sleep; | 99 | int has_deep_sleep; |
| 100 | }; | 100 | }; |
| 101 | 101 | ||
| 102 | static struct of_device *pmc_dev; | 102 | static struct platform_device *pmc_dev; |
| 103 | static int has_deep_sleep, deep_sleeping; | 103 | static int has_deep_sleep, deep_sleeping; |
| 104 | static int pmc_irq; | 104 | static int pmc_irq; |
| 105 | static struct mpc83xx_pmc __iomem *pmc_regs; | 105 | static struct mpc83xx_pmc __iomem *pmc_regs; |
| @@ -318,7 +318,7 @@ static struct platform_suspend_ops mpc83xx_suspend_ops = { | |||
| 318 | .end = mpc83xx_suspend_end, | 318 | .end = mpc83xx_suspend_end, |
| 319 | }; | 319 | }; |
| 320 | 320 | ||
| 321 | static int pmc_probe(struct of_device *ofdev, | 321 | static int pmc_probe(struct platform_device *ofdev, |
| 322 | const struct of_device_id *match) | 322 | const struct of_device_id *match) |
| 323 | { | 323 | { |
| 324 | struct device_node *np = ofdev->dev.of_node; | 324 | struct device_node *np = ofdev->dev.of_node; |
| @@ -396,7 +396,7 @@ out: | |||
| 396 | return ret; | 396 | return ret; |
| 397 | } | 397 | } |
| 398 | 398 | ||
| 399 | static int pmc_remove(struct of_device *ofdev) | 399 | static int pmc_remove(struct platform_device *ofdev) |
| 400 | { | 400 | { |
| 401 | return -EPERM; | 401 | return -EPERM; |
| 402 | }; | 402 | }; |
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig index 3a2ade2e443f..bea1f5905ad4 100644 --- a/arch/powerpc/platforms/85xx/Kconfig +++ b/arch/powerpc/platforms/85xx/Kconfig | |||
| @@ -65,6 +65,14 @@ config MPC85xx_RDB | |||
| 65 | help | 65 | help |
| 66 | This option enables support for the MPC85xx RDB (P2020 RDB) board | 66 | This option enables support for the MPC85xx RDB (P2020 RDB) board |
| 67 | 67 | ||
| 68 | config P1022_DS | ||
| 69 | bool "Freescale P1022 DS" | ||
| 70 | select DEFAULT_UIMAGE | ||
| 71 | select CONFIG_PHYS_64BIT # The DTS has 36-bit addresses | ||
| 72 | select SWIOTLB | ||
| 73 | help | ||
| 74 | This option enables support for the Freescale P1022DS reference board. | ||
| 75 | |||
| 68 | config SOCRATES | 76 | config SOCRATES |
| 69 | bool "Socrates" | 77 | bool "Socrates" |
| 70 | select DEFAULT_UIMAGE | 78 | select DEFAULT_UIMAGE |
diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile index 387c128f2c8c..a2ec3f8f4d06 100644 --- a/arch/powerpc/platforms/85xx/Makefile +++ b/arch/powerpc/platforms/85xx/Makefile | |||
| @@ -10,6 +10,7 @@ obj-$(CONFIG_MPC8536_DS) += mpc8536_ds.o | |||
| 10 | obj-$(CONFIG_MPC85xx_DS) += mpc85xx_ds.o | 10 | obj-$(CONFIG_MPC85xx_DS) += mpc85xx_ds.o |
| 11 | obj-$(CONFIG_MPC85xx_MDS) += mpc85xx_mds.o | 11 | obj-$(CONFIG_MPC85xx_MDS) += mpc85xx_mds.o |
| 12 | obj-$(CONFIG_MPC85xx_RDB) += mpc85xx_rdb.o | 12 | obj-$(CONFIG_MPC85xx_RDB) += mpc85xx_rdb.o |
| 13 | obj-$(CONFIG_P1022_DS) += p1022_ds.o | ||
| 13 | obj-$(CONFIG_P4080_DS) += p4080_ds.o corenet_ds.o | 14 | obj-$(CONFIG_P4080_DS) += p4080_ds.o corenet_ds.o |
| 14 | obj-$(CONFIG_STX_GP3) += stx_gp3.o | 15 | obj-$(CONFIG_STX_GP3) += stx_gp3.o |
| 15 | obj-$(CONFIG_TQM85xx) += tqm85xx.o | 16 | obj-$(CONFIG_TQM85xx) += tqm85xx.o |
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c index 494513682d70..da64be19d099 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c | |||
| @@ -158,51 +158,108 @@ static int mpc8568_mds_phy_fixups(struct phy_device *phydev) | |||
| 158 | extern void __init mpc85xx_smp_init(void); | 158 | extern void __init mpc85xx_smp_init(void); |
| 159 | #endif | 159 | #endif |
| 160 | 160 | ||
| 161 | static void __init mpc85xx_mds_setup_arch(void) | 161 | #ifdef CONFIG_QUICC_ENGINE |
| 162 | static struct of_device_id mpc85xx_qe_ids[] __initdata = { | ||
| 163 | { .type = "qe", }, | ||
| 164 | { .compatible = "fsl,qe", }, | ||
| 165 | { }, | ||
| 166 | }; | ||
| 167 | |||
| 168 | static void __init mpc85xx_publish_qe_devices(void) | ||
| 162 | { | 169 | { |
| 163 | struct device_node *np; | 170 | struct device_node *np; |
| 164 | static u8 __iomem *bcsr_regs = NULL; | ||
| 165 | #ifdef CONFIG_PCI | ||
| 166 | struct pci_controller *hose; | ||
| 167 | #endif | ||
| 168 | dma_addr_t max = 0xffffffff; | ||
| 169 | 171 | ||
| 170 | if (ppc_md.progress) | 172 | np = of_find_compatible_node(NULL, NULL, "fsl,qe"); |
| 171 | ppc_md.progress("mpc85xx_mds_setup_arch()", 0); | 173 | if (!of_device_is_available(np)) { |
| 174 | of_node_put(np); | ||
| 175 | return; | ||
| 176 | } | ||
| 177 | |||
| 178 | of_platform_bus_probe(NULL, mpc85xx_qe_ids, NULL); | ||
| 179 | } | ||
| 180 | |||
| 181 | static void __init mpc85xx_mds_reset_ucc_phys(void) | ||
| 182 | { | ||
| 183 | struct device_node *np; | ||
| 184 | static u8 __iomem *bcsr_regs; | ||
| 172 | 185 | ||
| 173 | /* Map BCSR area */ | 186 | /* Map BCSR area */ |
| 174 | np = of_find_node_by_name(NULL, "bcsr"); | 187 | np = of_find_node_by_name(NULL, "bcsr"); |
| 175 | if (np != NULL) { | 188 | if (!np) |
| 176 | struct resource res; | 189 | return; |
| 177 | 190 | ||
| 178 | of_address_to_resource(np, 0, &res); | 191 | bcsr_regs = of_iomap(np, 0); |
| 179 | bcsr_regs = ioremap(res.start, res.end - res.start +1); | 192 | of_node_put(np); |
| 180 | of_node_put(np); | 193 | if (!bcsr_regs) |
| 181 | } | 194 | return; |
| 182 | 195 | ||
| 183 | #ifdef CONFIG_PCI | 196 | if (machine_is(mpc8568_mds)) { |
| 184 | for_each_node_by_type(np, "pci") { | 197 | #define BCSR_UCC1_GETH_EN (0x1 << 7) |
| 185 | if (of_device_is_compatible(np, "fsl,mpc8540-pci") || | 198 | #define BCSR_UCC2_GETH_EN (0x1 << 7) |
| 186 | of_device_is_compatible(np, "fsl,mpc8548-pcie")) { | 199 | #define BCSR_UCC1_MODE_MSK (0x3 << 4) |
| 187 | struct resource rsrc; | 200 | #define BCSR_UCC2_MODE_MSK (0x3 << 0) |
| 188 | of_address_to_resource(np, 0, &rsrc); | ||
| 189 | if ((rsrc.start & 0xfffff) == 0x8000) | ||
| 190 | fsl_add_bridge(np, 1); | ||
| 191 | else | ||
| 192 | fsl_add_bridge(np, 0); | ||
| 193 | 201 | ||
| 194 | hose = pci_find_hose_for_OF_device(np); | 202 | /* Turn off UCC1 & UCC2 */ |
| 195 | max = min(max, hose->dma_window_base_cur + | 203 | clrbits8(&bcsr_regs[8], BCSR_UCC1_GETH_EN); |
| 196 | hose->dma_window_size); | 204 | clrbits8(&bcsr_regs[9], BCSR_UCC2_GETH_EN); |
| 205 | |||
| 206 | /* Mode is RGMII, all bits clear */ | ||
| 207 | clrbits8(&bcsr_regs[11], BCSR_UCC1_MODE_MSK | | ||
| 208 | BCSR_UCC2_MODE_MSK); | ||
| 209 | |||
| 210 | /* Turn UCC1 & UCC2 on */ | ||
| 211 | setbits8(&bcsr_regs[8], BCSR_UCC1_GETH_EN); | ||
| 212 | setbits8(&bcsr_regs[9], BCSR_UCC2_GETH_EN); | ||
| 213 | } else if (machine_is(mpc8569_mds)) { | ||
| 214 | #define BCSR7_UCC12_GETHnRST (0x1 << 2) | ||
| 215 | #define BCSR8_UEM_MARVELL_RST (0x1 << 1) | ||
| 216 | #define BCSR_UCC_RGMII (0x1 << 6) | ||
| 217 | #define BCSR_UCC_RTBI (0x1 << 5) | ||
| 218 | /* | ||
| 219 | * U-Boot mangles interrupt polarity for Marvell PHYs, | ||
| 220 | * so reset built-in and UEM Marvell PHYs, this puts | ||
| 221 | * the PHYs into their normal state. | ||
| 222 | */ | ||
| 223 | clrbits8(&bcsr_regs[7], BCSR7_UCC12_GETHnRST); | ||
| 224 | setbits8(&bcsr_regs[8], BCSR8_UEM_MARVELL_RST); | ||
| 225 | |||
| 226 | setbits8(&bcsr_regs[7], BCSR7_UCC12_GETHnRST); | ||
| 227 | clrbits8(&bcsr_regs[8], BCSR8_UEM_MARVELL_RST); | ||
| 228 | |||
| 229 | for (np = NULL; (np = of_find_compatible_node(np, | ||
| 230 | "network", | ||
| 231 | "ucc_geth")) != NULL;) { | ||
| 232 | const unsigned int *prop; | ||
| 233 | int ucc_num; | ||
| 234 | |||
| 235 | prop = of_get_property(np, "cell-index", NULL); | ||
| 236 | if (prop == NULL) | ||
| 237 | continue; | ||
| 238 | |||
| 239 | ucc_num = *prop - 1; | ||
| 240 | |||
| 241 | prop = of_get_property(np, "phy-connection-type", NULL); | ||
| 242 | if (prop == NULL) | ||
| 243 | continue; | ||
| 244 | |||
| 245 | if (strcmp("rtbi", (const char *)prop) == 0) | ||
| 246 | clrsetbits_8(&bcsr_regs[7 + ucc_num], | ||
| 247 | BCSR_UCC_RGMII, BCSR_UCC_RTBI); | ||
| 197 | } | 248 | } |
| 249 | } else if (machine_is(p1021_mds)) { | ||
| 250 | #define BCSR11_ENET_MICRST (0x1 << 5) | ||
| 251 | /* Reset Micrel PHY */ | ||
| 252 | clrbits8(&bcsr_regs[11], BCSR11_ENET_MICRST); | ||
| 253 | setbits8(&bcsr_regs[11], BCSR11_ENET_MICRST); | ||
| 198 | } | 254 | } |
| 199 | #endif | ||
| 200 | 255 | ||
| 201 | #ifdef CONFIG_SMP | 256 | iounmap(bcsr_regs); |
| 202 | mpc85xx_smp_init(); | 257 | } |
| 203 | #endif | 258 | |
| 259 | static void __init mpc85xx_mds_qe_init(void) | ||
| 260 | { | ||
| 261 | struct device_node *np; | ||
| 204 | 262 | ||
| 205 | #ifdef CONFIG_QUICC_ENGINE | ||
| 206 | np = of_find_compatible_node(NULL, NULL, "fsl,qe"); | 263 | np = of_find_compatible_node(NULL, NULL, "fsl,qe"); |
| 207 | if (!np) { | 264 | if (!np) { |
| 208 | np = of_find_node_by_name(NULL, "qe"); | 265 | np = of_find_node_by_name(NULL, "qe"); |
| @@ -210,6 +267,11 @@ static void __init mpc85xx_mds_setup_arch(void) | |||
| 210 | return; | 267 | return; |
| 211 | } | 268 | } |
| 212 | 269 | ||
| 270 | if (!of_device_is_available(np)) { | ||
| 271 | of_node_put(np); | ||
| 272 | return; | ||
| 273 | } | ||
| 274 | |||
| 213 | qe_reset(); | 275 | qe_reset(); |
| 214 | of_node_put(np); | 276 | of_node_put(np); |
| 215 | 277 | ||
| @@ -224,70 +286,7 @@ static void __init mpc85xx_mds_setup_arch(void) | |||
| 224 | par_io_of_config(ucc); | 286 | par_io_of_config(ucc); |
| 225 | } | 287 | } |
| 226 | 288 | ||
| 227 | if (bcsr_regs) { | 289 | mpc85xx_mds_reset_ucc_phys(); |
| 228 | if (machine_is(mpc8568_mds)) { | ||
| 229 | #define BCSR_UCC1_GETH_EN (0x1 << 7) | ||
| 230 | #define BCSR_UCC2_GETH_EN (0x1 << 7) | ||
| 231 | #define BCSR_UCC1_MODE_MSK (0x3 << 4) | ||
| 232 | #define BCSR_UCC2_MODE_MSK (0x3 << 0) | ||
| 233 | |||
| 234 | /* Turn off UCC1 & UCC2 */ | ||
| 235 | clrbits8(&bcsr_regs[8], BCSR_UCC1_GETH_EN); | ||
| 236 | clrbits8(&bcsr_regs[9], BCSR_UCC2_GETH_EN); | ||
| 237 | |||
| 238 | /* Mode is RGMII, all bits clear */ | ||
| 239 | clrbits8(&bcsr_regs[11], BCSR_UCC1_MODE_MSK | | ||
| 240 | BCSR_UCC2_MODE_MSK); | ||
| 241 | |||
| 242 | /* Turn UCC1 & UCC2 on */ | ||
| 243 | setbits8(&bcsr_regs[8], BCSR_UCC1_GETH_EN); | ||
| 244 | setbits8(&bcsr_regs[9], BCSR_UCC2_GETH_EN); | ||
| 245 | } else if (machine_is(mpc8569_mds)) { | ||
| 246 | #define BCSR7_UCC12_GETHnRST (0x1 << 2) | ||
| 247 | #define BCSR8_UEM_MARVELL_RST (0x1 << 1) | ||
| 248 | #define BCSR_UCC_RGMII (0x1 << 6) | ||
| 249 | #define BCSR_UCC_RTBI (0x1 << 5) | ||
| 250 | /* | ||
| 251 | * U-Boot mangles interrupt polarity for Marvell PHYs, | ||
| 252 | * so reset built-in and UEM Marvell PHYs, this puts | ||
| 253 | * the PHYs into their normal state. | ||
| 254 | */ | ||
| 255 | clrbits8(&bcsr_regs[7], BCSR7_UCC12_GETHnRST); | ||
| 256 | setbits8(&bcsr_regs[8], BCSR8_UEM_MARVELL_RST); | ||
| 257 | |||
| 258 | setbits8(&bcsr_regs[7], BCSR7_UCC12_GETHnRST); | ||
| 259 | clrbits8(&bcsr_regs[8], BCSR8_UEM_MARVELL_RST); | ||
| 260 | |||
| 261 | for (np = NULL; (np = of_find_compatible_node(np, | ||
| 262 | "network", | ||
| 263 | "ucc_geth")) != NULL;) { | ||
| 264 | const unsigned int *prop; | ||
| 265 | int ucc_num; | ||
| 266 | |||
| 267 | prop = of_get_property(np, "cell-index", NULL); | ||
| 268 | if (prop == NULL) | ||
| 269 | continue; | ||
| 270 | |||
| 271 | ucc_num = *prop - 1; | ||
| 272 | |||
| 273 | prop = of_get_property(np, "phy-connection-type", NULL); | ||
| 274 | if (prop == NULL) | ||
| 275 | continue; | ||
| 276 | |||
| 277 | if (strcmp("rtbi", (const char *)prop) == 0) | ||
| 278 | clrsetbits_8(&bcsr_regs[7 + ucc_num], | ||
| 279 | BCSR_UCC_RGMII, BCSR_UCC_RTBI); | ||
| 280 | } | ||
| 281 | |||
| 282 | } else if (machine_is(p1021_mds)) { | ||
| 283 | #define BCSR11_ENET_MICRST (0x1 << 5) | ||
| 284 | /* Reset Micrel PHY */ | ||
| 285 | clrbits8(&bcsr_regs[11], BCSR11_ENET_MICRST); | ||
| 286 | setbits8(&bcsr_regs[11], BCSR11_ENET_MICRST); | ||
| 287 | } | ||
| 288 | |||
| 289 | iounmap(bcsr_regs); | ||
| 290 | } | ||
| 291 | 290 | ||
| 292 | if (machine_is(p1021_mds)) { | 291 | if (machine_is(p1021_mds)) { |
| 293 | #define MPC85xx_PMUXCR_OFFSET 0x60 | 292 | #define MPC85xx_PMUXCR_OFFSET 0x60 |
| @@ -322,8 +321,72 @@ static void __init mpc85xx_mds_setup_arch(void) | |||
| 322 | } | 321 | } |
| 323 | 322 | ||
| 324 | } | 323 | } |
| 324 | } | ||
| 325 | |||
| 326 | static void __init mpc85xx_mds_qeic_init(void) | ||
| 327 | { | ||
| 328 | struct device_node *np; | ||
| 329 | |||
| 330 | np = of_find_compatible_node(NULL, NULL, "fsl,qe"); | ||
| 331 | if (!of_device_is_available(np)) { | ||
| 332 | of_node_put(np); | ||
| 333 | return; | ||
| 334 | } | ||
| 335 | |||
| 336 | np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic"); | ||
| 337 | if (!np) { | ||
| 338 | np = of_find_node_by_type(NULL, "qeic"); | ||
| 339 | if (!np) | ||
| 340 | return; | ||
| 341 | } | ||
| 342 | |||
| 343 | if (machine_is(p1021_mds)) | ||
| 344 | qe_ic_init(np, 0, qe_ic_cascade_low_mpic, | ||
| 345 | qe_ic_cascade_high_mpic); | ||
| 346 | else | ||
| 347 | qe_ic_init(np, 0, qe_ic_cascade_muxed_mpic, NULL); | ||
| 348 | of_node_put(np); | ||
| 349 | } | ||
| 350 | #else | ||
| 351 | static void __init mpc85xx_publish_qe_devices(void) { } | ||
| 352 | static void __init mpc85xx_mds_qe_init(void) { } | ||
| 353 | static void __init mpc85xx_mds_qeic_init(void) { } | ||
| 325 | #endif /* CONFIG_QUICC_ENGINE */ | 354 | #endif /* CONFIG_QUICC_ENGINE */ |
| 326 | 355 | ||
| 356 | static void __init mpc85xx_mds_setup_arch(void) | ||
| 357 | { | ||
| 358 | #ifdef CONFIG_PCI | ||
| 359 | struct pci_controller *hose; | ||
| 360 | #endif | ||
| 361 | dma_addr_t max = 0xffffffff; | ||
| 362 | |||
| 363 | if (ppc_md.progress) | ||
| 364 | ppc_md.progress("mpc85xx_mds_setup_arch()", 0); | ||
| 365 | |||
| 366 | #ifdef CONFIG_PCI | ||
| 367 | for_each_node_by_type(np, "pci") { | ||
| 368 | if (of_device_is_compatible(np, "fsl,mpc8540-pci") || | ||
| 369 | of_device_is_compatible(np, "fsl,mpc8548-pcie")) { | ||
| 370 | struct resource rsrc; | ||
| 371 | of_address_to_resource(np, 0, &rsrc); | ||
| 372 | if ((rsrc.start & 0xfffff) == 0x8000) | ||
| 373 | fsl_add_bridge(np, 1); | ||
| 374 | else | ||
| 375 | fsl_add_bridge(np, 0); | ||
| 376 | |||
| 377 | hose = pci_find_hose_for_OF_device(np); | ||
| 378 | max = min(max, hose->dma_window_base_cur + | ||
| 379 | hose->dma_window_size); | ||
| 380 | } | ||
| 381 | } | ||
| 382 | #endif | ||
| 383 | |||
| 384 | #ifdef CONFIG_SMP | ||
| 385 | mpc85xx_smp_init(); | ||
| 386 | #endif | ||
| 387 | |||
| 388 | mpc85xx_mds_qe_init(); | ||
| 389 | |||
| 327 | #ifdef CONFIG_SWIOTLB | 390 | #ifdef CONFIG_SWIOTLB |
| 328 | if (memblock_end_of_DRAM() > max) { | 391 | if (memblock_end_of_DRAM() > max) { |
| 329 | ppc_swiotlb_enable = 1; | 392 | ppc_swiotlb_enable = 1; |
| @@ -369,8 +432,6 @@ static struct of_device_id mpc85xx_ids[] = { | |||
| 369 | { .type = "soc", }, | 432 | { .type = "soc", }, |
| 370 | { .compatible = "soc", }, | 433 | { .compatible = "soc", }, |
| 371 | { .compatible = "simple-bus", }, | 434 | { .compatible = "simple-bus", }, |
| 372 | { .type = "qe", }, | ||
| 373 | { .compatible = "fsl,qe", }, | ||
| 374 | { .compatible = "gianfar", }, | 435 | { .compatible = "gianfar", }, |
| 375 | { .compatible = "fsl,rapidio-delta", }, | 436 | { .compatible = "fsl,rapidio-delta", }, |
| 376 | { .compatible = "fsl,mpc8548-guts", }, | 437 | { .compatible = "fsl,mpc8548-guts", }, |
| @@ -382,8 +443,6 @@ static struct of_device_id p1021_ids[] = { | |||
| 382 | { .type = "soc", }, | 443 | { .type = "soc", }, |
| 383 | { .compatible = "soc", }, | 444 | { .compatible = "soc", }, |
| 384 | { .compatible = "simple-bus", }, | 445 | { .compatible = "simple-bus", }, |
| 385 | { .type = "qe", }, | ||
| 386 | { .compatible = "fsl,qe", }, | ||
| 387 | { .compatible = "gianfar", }, | 446 | { .compatible = "gianfar", }, |
| 388 | {}, | 447 | {}, |
| 389 | }; | 448 | }; |
| @@ -395,16 +454,16 @@ static int __init mpc85xx_publish_devices(void) | |||
| 395 | if (machine_is(mpc8569_mds)) | 454 | if (machine_is(mpc8569_mds)) |
| 396 | simple_gpiochip_init("fsl,mpc8569mds-bcsr-gpio"); | 455 | simple_gpiochip_init("fsl,mpc8569mds-bcsr-gpio"); |
| 397 | 456 | ||
| 398 | /* Publish the QE devices */ | ||
| 399 | of_platform_bus_probe(NULL, mpc85xx_ids, NULL); | 457 | of_platform_bus_probe(NULL, mpc85xx_ids, NULL); |
| 458 | mpc85xx_publish_qe_devices(); | ||
| 400 | 459 | ||
| 401 | return 0; | 460 | return 0; |
| 402 | } | 461 | } |
| 403 | 462 | ||
| 404 | static int __init p1021_publish_devices(void) | 463 | static int __init p1021_publish_devices(void) |
| 405 | { | 464 | { |
| 406 | /* Publish the QE devices */ | ||
| 407 | of_platform_bus_probe(NULL, p1021_ids, NULL); | 465 | of_platform_bus_probe(NULL, p1021_ids, NULL); |
| 466 | mpc85xx_publish_qe_devices(); | ||
| 408 | 467 | ||
| 409 | return 0; | 468 | return 0; |
| 410 | } | 469 | } |
| @@ -441,21 +500,7 @@ static void __init mpc85xx_mds_pic_init(void) | |||
| 441 | of_node_put(np); | 500 | of_node_put(np); |
| 442 | 501 | ||
| 443 | mpic_init(mpic); | 502 | mpic_init(mpic); |
| 444 | 503 | mpc85xx_mds_qeic_init(); | |
| 445 | #ifdef CONFIG_QUICC_ENGINE | ||
| 446 | np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic"); | ||
| 447 | if (!np) { | ||
| 448 | np = of_find_node_by_type(NULL, "qeic"); | ||
| 449 | if (!np) | ||
| 450 | return; | ||
| 451 | } | ||
| 452 | if (machine_is(p1021_mds)) | ||
| 453 | qe_ic_init(np, 0, qe_ic_cascade_low_mpic, | ||
| 454 | qe_ic_cascade_high_mpic); | ||
| 455 | else | ||
| 456 | qe_ic_init(np, 0, qe_ic_cascade_muxed_mpic, NULL); | ||
| 457 | of_node_put(np); | ||
| 458 | #endif /* CONFIG_QUICC_ENGINE */ | ||
| 459 | } | 504 | } |
| 460 | 505 | ||
| 461 | static int __init mpc85xx_mds_probe(void) | 506 | static int __init mpc85xx_mds_probe(void) |
diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c b/arch/powerpc/platforms/85xx/p1022_ds.c new file mode 100644 index 000000000000..e1467c937450 --- /dev/null +++ b/arch/powerpc/platforms/85xx/p1022_ds.c | |||
| @@ -0,0 +1,148 @@ | |||
| 1 | /* | ||
| 2 | * P1022DS board specific routines | ||
| 3 | * | ||
| 4 | * Authors: Travis Wheatley <travis.wheatley@freescale.com> | ||
| 5 | * Dave Liu <daveliu@freescale.com> | ||
| 6 | * Timur Tabi <timur@freescale.com> | ||
| 7 | * | ||
| 8 | * Copyright 2010 Freescale Semiconductor, Inc. | ||
| 9 | * | ||
| 10 | * This file is taken from the Freescale P1022DS BSP, with modifications: | ||
| 11 | * 1) No DIU support (pending rewrite of DIU code) | ||
| 12 | * 2) No AMP support | ||
| 13 | * 3) No PCI endpoint support | ||
| 14 | * | ||
| 15 | * This file is licensed under the terms of the GNU General Public License | ||
| 16 | * version 2. This program is licensed "as is" without any warranty of any | ||
| 17 | * kind, whether express or implied. | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <linux/pci.h> | ||
| 21 | #include <linux/of_platform.h> | ||
| 22 | #include <linux/lmb.h> | ||
| 23 | |||
| 24 | #include <asm/mpic.h> | ||
| 25 | #include <asm/swiotlb.h> | ||
| 26 | |||
| 27 | #include <sysdev/fsl_soc.h> | ||
| 28 | #include <sysdev/fsl_pci.h> | ||
| 29 | |||
| 30 | void __init p1022_ds_pic_init(void) | ||
| 31 | { | ||
| 32 | struct mpic *mpic; | ||
| 33 | struct resource r; | ||
| 34 | struct device_node *np; | ||
| 35 | |||
| 36 | np = of_find_node_by_type(NULL, "open-pic"); | ||
| 37 | if (!np) { | ||
| 38 | pr_err("Could not find open-pic node\n"); | ||
| 39 | return; | ||
| 40 | } | ||
| 41 | |||
| 42 | if (of_address_to_resource(np, 0, &r)) { | ||
| 43 | pr_err("Failed to map mpic register space\n"); | ||
| 44 | of_node_put(np); | ||
| 45 | return; | ||
| 46 | } | ||
| 47 | |||
| 48 | mpic = mpic_alloc(np, r.start, | ||
| 49 | MPIC_PRIMARY | MPIC_WANTS_RESET | | ||
| 50 | MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | | ||
| 51 | MPIC_SINGLE_DEST_CPU, | ||
| 52 | 0, 256, " OpenPIC "); | ||
| 53 | |||
| 54 | BUG_ON(mpic == NULL); | ||
| 55 | of_node_put(np); | ||
| 56 | |||
| 57 | mpic_init(mpic); | ||
| 58 | } | ||
| 59 | |||
| 60 | #ifdef CONFIG_SMP | ||
| 61 | void __init mpc85xx_smp_init(void); | ||
| 62 | #endif | ||
| 63 | |||
| 64 | /* | ||
| 65 | * Setup the architecture | ||
| 66 | */ | ||
| 67 | static void __init p1022_ds_setup_arch(void) | ||
| 68 | { | ||
| 69 | #ifdef CONFIG_PCI | ||
| 70 | struct device_node *np; | ||
| 71 | #endif | ||
| 72 | dma_addr_t max = 0xffffffff; | ||
| 73 | |||
| 74 | if (ppc_md.progress) | ||
| 75 | ppc_md.progress("p1022_ds_setup_arch()", 0); | ||
| 76 | |||
| 77 | #ifdef CONFIG_PCI | ||
| 78 | for_each_compatible_node(np, "pci", "fsl,p1022-pcie") { | ||
| 79 | struct resource rsrc; | ||
| 80 | struct pci_controller *hose; | ||
| 81 | |||
| 82 | of_address_to_resource(np, 0, &rsrc); | ||
| 83 | |||
| 84 | if ((rsrc.start & 0xfffff) == 0x8000) | ||
| 85 | fsl_add_bridge(np, 1); | ||
| 86 | else | ||
| 87 | fsl_add_bridge(np, 0); | ||
| 88 | |||
| 89 | hose = pci_find_hose_for_OF_device(np); | ||
| 90 | max = min(max, hose->dma_window_base_cur + | ||
| 91 | hose->dma_window_size); | ||
| 92 | } | ||
| 93 | #endif | ||
| 94 | |||
| 95 | #ifdef CONFIG_SMP | ||
| 96 | mpc85xx_smp_init(); | ||
| 97 | #endif | ||
| 98 | |||
| 99 | #ifdef CONFIG_SWIOTLB | ||
| 100 | if (lmb_end_of_DRAM() > max) { | ||
| 101 | ppc_swiotlb_enable = 1; | ||
| 102 | set_pci_dma_ops(&swiotlb_dma_ops); | ||
| 103 | ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; | ||
| 104 | } | ||
| 105 | #endif | ||
| 106 | |||
| 107 | pr_info("Freescale P1022 DS reference board\n"); | ||
| 108 | } | ||
| 109 | |||
| 110 | static struct of_device_id __initdata p1022_ds_ids[] = { | ||
| 111 | { .type = "soc", }, | ||
| 112 | { .compatible = "soc", }, | ||
| 113 | { .compatible = "simple-bus", }, | ||
| 114 | { .compatible = "gianfar", }, | ||
| 115 | {}, | ||
| 116 | }; | ||
| 117 | |||
| 118 | static int __init p1022_ds_publish_devices(void) | ||
| 119 | { | ||
| 120 | return of_platform_bus_probe(NULL, p1022_ds_ids, NULL); | ||
| 121 | } | ||
| 122 | machine_device_initcall(p1022_ds, p1022_ds_publish_devices); | ||
| 123 | |||
| 124 | machine_arch_initcall(p1022_ds, swiotlb_setup_bus_notifier); | ||
| 125 | |||
| 126 | /* | ||
| 127 | * Called very early, device-tree isn't unflattened | ||
| 128 | */ | ||
| 129 | static int __init p1022_ds_probe(void) | ||
| 130 | { | ||
| 131 | unsigned long root = of_get_flat_dt_root(); | ||
| 132 | |||
| 133 | return of_flat_dt_is_compatible(root, "fsl,p1022ds"); | ||
| 134 | } | ||
| 135 | |||
| 136 | define_machine(p1022_ds) { | ||
| 137 | .name = "P1022 DS", | ||
| 138 | .probe = p1022_ds_probe, | ||
| 139 | .setup_arch = p1022_ds_setup_arch, | ||
| 140 | .init_IRQ = p1022_ds_pic_init, | ||
| 141 | #ifdef CONFIG_PCI | ||
| 142 | .pcibios_fixup_bus = fsl_pcibios_fixup_bus, | ||
| 143 | #endif | ||
| 144 | .get_irq = mpic_get_irq, | ||
| 145 | .restart = fsl_rstcr_restart, | ||
| 146 | .calibrate_decr = generic_calibrate_decr, | ||
| 147 | .progress = udbg_progress, | ||
| 148 | }; | ||
diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index a15f582300d8..a6b106557be4 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
| 16 | #include <linux/delay.h> | 16 | #include <linux/delay.h> |
| 17 | #include <linux/of.h> | 17 | #include <linux/of.h> |
| 18 | #include <linux/kexec.h> | ||
| 18 | 19 | ||
| 19 | #include <asm/machdep.h> | 20 | #include <asm/machdep.h> |
| 20 | #include <asm/pgtable.h> | 21 | #include <asm/pgtable.h> |
| @@ -24,6 +25,7 @@ | |||
| 24 | #include <asm/dbell.h> | 25 | #include <asm/dbell.h> |
| 25 | 26 | ||
| 26 | #include <sysdev/fsl_soc.h> | 27 | #include <sysdev/fsl_soc.h> |
| 28 | #include <sysdev/mpic.h> | ||
| 27 | 29 | ||
| 28 | extern void __early_start(void); | 30 | extern void __early_start(void); |
| 29 | 31 | ||
| @@ -99,12 +101,70 @@ static void __init | |||
| 99 | smp_85xx_setup_cpu(int cpu_nr) | 101 | smp_85xx_setup_cpu(int cpu_nr) |
| 100 | { | 102 | { |
| 101 | mpic_setup_this_cpu(); | 103 | mpic_setup_this_cpu(); |
| 104 | if (cpu_has_feature(CPU_FTR_DBELL)) | ||
| 105 | doorbell_setup_this_cpu(); | ||
| 102 | } | 106 | } |
| 103 | 107 | ||
| 104 | struct smp_ops_t smp_85xx_ops = { | 108 | struct smp_ops_t smp_85xx_ops = { |
| 105 | .kick_cpu = smp_85xx_kick_cpu, | 109 | .kick_cpu = smp_85xx_kick_cpu, |
| 110 | #ifdef CONFIG_KEXEC | ||
| 111 | .give_timebase = smp_generic_give_timebase, | ||
| 112 | .take_timebase = smp_generic_take_timebase, | ||
| 113 | #endif | ||
| 106 | }; | 114 | }; |
| 107 | 115 | ||
| 116 | #ifdef CONFIG_KEXEC | ||
| 117 | static int kexec_down_cpus = 0; | ||
| 118 | |||
| 119 | void mpc85xx_smp_kexec_cpu_down(int crash_shutdown, int secondary) | ||
| 120 | { | ||
| 121 | mpic_teardown_this_cpu(1); | ||
| 122 | |||
| 123 | /* When crashing, this gets called on all CPU's we only | ||
| 124 | * take down the non-boot cpus */ | ||
| 125 | if (smp_processor_id() != boot_cpuid) | ||
| 126 | { | ||
| 127 | local_irq_disable(); | ||
| 128 | kexec_down_cpus++; | ||
| 129 | |||
| 130 | while (1); | ||
| 131 | } | ||
| 132 | } | ||
| 133 | |||
| 134 | static void mpc85xx_smp_kexec_down(void *arg) | ||
| 135 | { | ||
| 136 | if (ppc_md.kexec_cpu_down) | ||
| 137 | ppc_md.kexec_cpu_down(0,1); | ||
| 138 | } | ||
| 139 | |||
| 140 | static void mpc85xx_smp_machine_kexec(struct kimage *image) | ||
| 141 | { | ||
| 142 | int timeout = 2000; | ||
| 143 | int i; | ||
| 144 | |||
| 145 | set_cpus_allowed(current, cpumask_of_cpu(boot_cpuid)); | ||
| 146 | |||
| 147 | smp_call_function(mpc85xx_smp_kexec_down, NULL, 0); | ||
| 148 | |||
| 149 | while ( (kexec_down_cpus != (num_online_cpus() - 1)) && | ||
| 150 | ( timeout > 0 ) ) | ||
| 151 | { | ||
| 152 | timeout--; | ||
| 153 | } | ||
| 154 | |||
| 155 | if ( !timeout ) | ||
| 156 | printk(KERN_ERR "Unable to bring down secondary cpu(s)"); | ||
| 157 | |||
| 158 | for (i = 0; i < num_present_cpus(); i++) | ||
| 159 | { | ||
| 160 | if ( i == smp_processor_id() ) continue; | ||
| 161 | mpic_reset_core(i); | ||
| 162 | } | ||
| 163 | |||
| 164 | default_machine_kexec(image); | ||
| 165 | } | ||
| 166 | #endif /* CONFIG_KEXEC */ | ||
| 167 | |||
| 108 | void __init mpc85xx_smp_init(void) | 168 | void __init mpc85xx_smp_init(void) |
| 109 | { | 169 | { |
| 110 | struct device_node *np; | 170 | struct device_node *np; |
| @@ -117,9 +177,14 @@ void __init mpc85xx_smp_init(void) | |||
| 117 | } | 177 | } |
| 118 | 178 | ||
| 119 | if (cpu_has_feature(CPU_FTR_DBELL)) | 179 | if (cpu_has_feature(CPU_FTR_DBELL)) |
| 120 | smp_85xx_ops.message_pass = smp_dbell_message_pass; | 180 | smp_85xx_ops.message_pass = doorbell_message_pass; |
| 121 | 181 | ||
| 122 | BUG_ON(!smp_85xx_ops.message_pass); | 182 | BUG_ON(!smp_85xx_ops.message_pass); |
| 123 | 183 | ||
| 124 | smp_ops = &smp_85xx_ops; | 184 | smp_ops = &smp_85xx_ops; |
| 185 | |||
| 186 | #ifdef CONFIG_KEXEC | ||
| 187 | ppc_md.kexec_cpu_down = mpc85xx_smp_kexec_cpu_down; | ||
| 188 | ppc_md.machine_kexec = mpc85xx_smp_machine_kexec; | ||
| 189 | #endif | ||
| 125 | } | 190 | } |
diff --git a/arch/powerpc/platforms/85xx/tqm85xx.c b/arch/powerpc/platforms/85xx/tqm85xx.c index 5b0ab9966e90..8f29bbce5360 100644 --- a/arch/powerpc/platforms/85xx/tqm85xx.c +++ b/arch/powerpc/platforms/85xx/tqm85xx.c | |||
| @@ -151,6 +151,27 @@ static void tqm85xx_show_cpuinfo(struct seq_file *m) | |||
| 151 | seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); | 151 | seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); |
| 152 | } | 152 | } |
| 153 | 153 | ||
| 154 | static void __init tqm85xx_ti1520_fixup(struct pci_dev *pdev) | ||
| 155 | { | ||
| 156 | unsigned int val; | ||
| 157 | |||
| 158 | /* Do not do the fixup on other platforms! */ | ||
| 159 | if (!machine_is(tqm85xx)) | ||
| 160 | return; | ||
| 161 | |||
| 162 | dev_info(&pdev->dev, "Using TI 1520 fixup on TQM85xx\n"); | ||
| 163 | |||
| 164 | /* | ||
| 165 | * Enable P2CCLK bit in system control register | ||
| 166 | * to enable CLOCK output to power chip | ||
| 167 | */ | ||
| 168 | pci_read_config_dword(pdev, 0x80, &val); | ||
| 169 | pci_write_config_dword(pdev, 0x80, val | (1 << 27)); | ||
| 170 | |||
| 171 | } | ||
| 172 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1520, | ||
| 173 | tqm85xx_ti1520_fixup); | ||
| 174 | |||
| 154 | static struct of_device_id __initdata of_bus_ids[] = { | 175 | static struct of_device_id __initdata of_bus_ids[] = { |
| 155 | { .compatible = "simple-bus", }, | 176 | { .compatible = "simple-bus", }, |
| 156 | { .compatible = "gianfar", }, | 177 | { .compatible = "gianfar", }, |
diff --git a/arch/powerpc/platforms/86xx/gef_gpio.c b/arch/powerpc/platforms/86xx/gef_gpio.c index b8cb08dbd89c..4ff7b1e7bbad 100644 --- a/arch/powerpc/platforms/86xx/gef_gpio.c +++ b/arch/powerpc/platforms/86xx/gef_gpio.c | |||
| @@ -118,12 +118,12 @@ static int __init gef_gpio_init(void) | |||
| 118 | } | 118 | } |
| 119 | 119 | ||
| 120 | /* Setup pointers to chip functions */ | 120 | /* Setup pointers to chip functions */ |
| 121 | gef_gpio_chip->of_gc.gpio_cells = 2; | 121 | gef_gpio_chip->gc.of_gpio_n_cells = 2; |
| 122 | gef_gpio_chip->of_gc.gc.ngpio = 19; | 122 | gef_gpio_chip->gc.ngpio = 19; |
| 123 | gef_gpio_chip->of_gc.gc.direction_input = gef_gpio_dir_in; | 123 | gef_gpio_chip->gc.direction_input = gef_gpio_dir_in; |
| 124 | gef_gpio_chip->of_gc.gc.direction_output = gef_gpio_dir_out; | 124 | gef_gpio_chip->gc.direction_output = gef_gpio_dir_out; |
| 125 | gef_gpio_chip->of_gc.gc.get = gef_gpio_get; | 125 | gef_gpio_chip->gc.get = gef_gpio_get; |
| 126 | gef_gpio_chip->of_gc.gc.set = gef_gpio_set; | 126 | gef_gpio_chip->gc.set = gef_gpio_set; |
| 127 | 127 | ||
| 128 | /* This function adds a memory mapped GPIO chip */ | 128 | /* This function adds a memory mapped GPIO chip */ |
| 129 | retval = of_mm_gpiochip_add(np, gef_gpio_chip); | 129 | retval = of_mm_gpiochip_add(np, gef_gpio_chip); |
| @@ -146,12 +146,12 @@ static int __init gef_gpio_init(void) | |||
| 146 | } | 146 | } |
| 147 | 147 | ||
| 148 | /* Setup pointers to chip functions */ | 148 | /* Setup pointers to chip functions */ |
| 149 | gef_gpio_chip->of_gc.gpio_cells = 2; | 149 | gef_gpio_chip->gc.of_gpio_n_cells = 2; |
| 150 | gef_gpio_chip->of_gc.gc.ngpio = 6; | 150 | gef_gpio_chip->gc.ngpio = 6; |
| 151 | gef_gpio_chip->of_gc.gc.direction_input = gef_gpio_dir_in; | 151 | gef_gpio_chip->gc.direction_input = gef_gpio_dir_in; |
| 152 | gef_gpio_chip->of_gc.gc.direction_output = gef_gpio_dir_out; | 152 | gef_gpio_chip->gc.direction_output = gef_gpio_dir_out; |
| 153 | gef_gpio_chip->of_gc.gc.get = gef_gpio_get; | 153 | gef_gpio_chip->gc.get = gef_gpio_get; |
| 154 | gef_gpio_chip->of_gc.gc.set = gef_gpio_set; | 154 | gef_gpio_chip->gc.set = gef_gpio_set; |
| 155 | 155 | ||
| 156 | /* This function adds a memory mapped GPIO chip */ | 156 | /* This function adds a memory mapped GPIO chip */ |
| 157 | retval = of_mm_gpiochip_add(np, gef_gpio_chip); | 157 | retval = of_mm_gpiochip_add(np, gef_gpio_chip); |
diff --git a/arch/powerpc/platforms/8xx/Kconfig b/arch/powerpc/platforms/8xx/Kconfig index 48a920a98e7b..dd35ce081cff 100644 --- a/arch/powerpc/platforms/8xx/Kconfig +++ b/arch/powerpc/platforms/8xx/Kconfig | |||
| @@ -55,6 +55,12 @@ config PPC_MGSUVD | |||
| 55 | help | 55 | help |
| 56 | This enables support for the Keymile MGSUVD board. | 56 | This enables support for the Keymile MGSUVD board. |
| 57 | 57 | ||
| 58 | config TQM8XX | ||
| 59 | bool "TQM8XX" | ||
| 60 | select CPM1 | ||
| 61 | help | ||
| 62 | support for the mpc8xx based boards from TQM. | ||
| 63 | |||
| 58 | endchoice | 64 | endchoice |
| 59 | 65 | ||
| 60 | menu "Freescale Ethernet driver platform-specific options" | 66 | menu "Freescale Ethernet driver platform-specific options" |
diff --git a/arch/powerpc/platforms/8xx/Makefile b/arch/powerpc/platforms/8xx/Makefile index bdbfd7496018..a491fe6b94fc 100644 --- a/arch/powerpc/platforms/8xx/Makefile +++ b/arch/powerpc/platforms/8xx/Makefile | |||
| @@ -7,3 +7,4 @@ obj-$(CONFIG_MPC86XADS) += mpc86xads_setup.o | |||
| 7 | obj-$(CONFIG_PPC_EP88XC) += ep88xc.o | 7 | obj-$(CONFIG_PPC_EP88XC) += ep88xc.o |
| 8 | obj-$(CONFIG_PPC_ADDER875) += adder875.o | 8 | obj-$(CONFIG_PPC_ADDER875) += adder875.o |
| 9 | obj-$(CONFIG_PPC_MGSUVD) += mgsuvd.o | 9 | obj-$(CONFIG_PPC_MGSUVD) += mgsuvd.o |
| 10 | obj-$(CONFIG_TQM8XX) += tqm8xx_setup.o | ||
diff --git a/arch/powerpc/platforms/8xx/tqm8xx_setup.c b/arch/powerpc/platforms/8xx/tqm8xx_setup.c new file mode 100644 index 000000000000..b71c650fbb11 --- /dev/null +++ b/arch/powerpc/platforms/8xx/tqm8xx_setup.c | |||
| @@ -0,0 +1,156 @@ | |||
| 1 | /* | ||
| 2 | * Platform setup for the MPC8xx based boards from TQM. | ||
| 3 | * | ||
| 4 | * Heiko Schocher <hs@denx.de> | ||
| 5 | * Copyright 2010 DENX Software Engineering GmbH | ||
| 6 | * | ||
| 7 | * based on: | ||
| 8 | * Vitaly Bordug <vbordug@ru.mvista.com> | ||
| 9 | * | ||
| 10 | * Copyright 2005 MontaVista Software Inc. | ||
| 11 | * | ||
| 12 | * Heavily modified by Scott Wood <scottwood@freescale.com> | ||
| 13 | * Copyright 2007 Freescale Semiconductor, Inc. | ||
| 14 | * | ||
| 15 | * This file is licensed under the terms of the GNU General Public License | ||
| 16 | * version 2. This program is licensed "as is" without any warranty of any | ||
| 17 | * kind, whether express or implied. | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <linux/init.h> | ||
| 21 | #include <linux/module.h> | ||
| 22 | #include <linux/param.h> | ||
| 23 | #include <linux/string.h> | ||
| 24 | #include <linux/ioport.h> | ||
| 25 | #include <linux/device.h> | ||
| 26 | #include <linux/delay.h> | ||
| 27 | |||
| 28 | #include <linux/fs_enet_pd.h> | ||
| 29 | #include <linux/fs_uart_pd.h> | ||
| 30 | #include <linux/fsl_devices.h> | ||
| 31 | #include <linux/mii.h> | ||
| 32 | #include <linux/of_platform.h> | ||
| 33 | |||
| 34 | #include <asm/delay.h> | ||
| 35 | #include <asm/io.h> | ||
| 36 | #include <asm/machdep.h> | ||
| 37 | #include <asm/page.h> | ||
| 38 | #include <asm/processor.h> | ||
| 39 | #include <asm/system.h> | ||
| 40 | #include <asm/time.h> | ||
| 41 | #include <asm/mpc8xx.h> | ||
| 42 | #include <asm/8xx_immap.h> | ||
| 43 | #include <asm/cpm1.h> | ||
| 44 | #include <asm/fs_pd.h> | ||
| 45 | #include <asm/udbg.h> | ||
| 46 | |||
| 47 | #include "mpc8xx.h" | ||
| 48 | |||
| 49 | struct cpm_pin { | ||
| 50 | int port, pin, flags; | ||
| 51 | }; | ||
| 52 | |||
| 53 | static struct __initdata cpm_pin tqm8xx_pins[] = { | ||
| 54 | /* SMC1 */ | ||
| 55 | {CPM_PORTB, 24, CPM_PIN_INPUT}, /* RX */ | ||
| 56 | {CPM_PORTB, 25, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* TX */ | ||
| 57 | |||
| 58 | /* SCC1 */ | ||
| 59 | {CPM_PORTA, 5, CPM_PIN_INPUT}, /* CLK1 */ | ||
| 60 | {CPM_PORTA, 7, CPM_PIN_INPUT}, /* CLK2 */ | ||
| 61 | {CPM_PORTA, 14, CPM_PIN_INPUT}, /* TX */ | ||
| 62 | {CPM_PORTA, 15, CPM_PIN_INPUT}, /* RX */ | ||
| 63 | {CPM_PORTC, 15, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* TENA */ | ||
| 64 | {CPM_PORTC, 10, CPM_PIN_INPUT | CPM_PIN_SECONDARY | CPM_PIN_GPIO}, | ||
| 65 | {CPM_PORTC, 11, CPM_PIN_INPUT | CPM_PIN_SECONDARY | CPM_PIN_GPIO}, | ||
| 66 | }; | ||
| 67 | |||
| 68 | static struct __initdata cpm_pin tqm8xx_fec_pins[] = { | ||
| 69 | /* MII */ | ||
| 70 | {CPM_PORTD, 3, CPM_PIN_OUTPUT}, | ||
| 71 | {CPM_PORTD, 4, CPM_PIN_OUTPUT}, | ||
| 72 | {CPM_PORTD, 5, CPM_PIN_OUTPUT}, | ||
| 73 | {CPM_PORTD, 6, CPM_PIN_OUTPUT}, | ||
| 74 | {CPM_PORTD, 7, CPM_PIN_OUTPUT}, | ||
| 75 | {CPM_PORTD, 8, CPM_PIN_OUTPUT}, | ||
| 76 | {CPM_PORTD, 9, CPM_PIN_OUTPUT}, | ||
| 77 | {CPM_PORTD, 10, CPM_PIN_OUTPUT}, | ||
| 78 | {CPM_PORTD, 11, CPM_PIN_OUTPUT}, | ||
| 79 | {CPM_PORTD, 12, CPM_PIN_OUTPUT}, | ||
| 80 | {CPM_PORTD, 13, CPM_PIN_OUTPUT}, | ||
| 81 | {CPM_PORTD, 14, CPM_PIN_OUTPUT}, | ||
| 82 | {CPM_PORTD, 15, CPM_PIN_OUTPUT}, | ||
| 83 | }; | ||
| 84 | |||
| 85 | static void __init init_pins(int n, struct cpm_pin *pin) | ||
| 86 | { | ||
| 87 | int i; | ||
| 88 | |||
| 89 | for (i = 0; i < n; i++) { | ||
| 90 | cpm1_set_pin(pin->port, pin->pin, pin->flags); | ||
| 91 | pin++; | ||
| 92 | } | ||
| 93 | } | ||
| 94 | |||
| 95 | static void __init init_ioports(void) | ||
| 96 | { | ||
| 97 | struct device_node *dnode; | ||
| 98 | struct property *prop; | ||
| 99 | int len; | ||
| 100 | |||
| 101 | init_pins(ARRAY_SIZE(tqm8xx_pins), &tqm8xx_pins[0]); | ||
| 102 | |||
| 103 | cpm1_clk_setup(CPM_CLK_SMC1, CPM_BRG1, CPM_CLK_RTX); | ||
| 104 | |||
| 105 | dnode = of_find_node_by_name(NULL, "aliases"); | ||
| 106 | if (dnode == NULL) | ||
| 107 | return; | ||
| 108 | prop = of_find_property(dnode, "ethernet1", &len); | ||
| 109 | if (prop == NULL) | ||
| 110 | return; | ||
| 111 | |||
| 112 | /* init FEC pins */ | ||
| 113 | init_pins(ARRAY_SIZE(tqm8xx_fec_pins), &tqm8xx_fec_pins[0]); | ||
| 114 | } | ||
| 115 | |||
| 116 | static void __init tqm8xx_setup_arch(void) | ||
| 117 | { | ||
| 118 | cpm_reset(); | ||
| 119 | init_ioports(); | ||
| 120 | } | ||
| 121 | |||
| 122 | static int __init tqm8xx_probe(void) | ||
| 123 | { | ||
| 124 | unsigned long node = of_get_flat_dt_root(); | ||
| 125 | |||
| 126 | return of_flat_dt_is_compatible(node, "tqc,tqm8xx"); | ||
| 127 | } | ||
| 128 | |||
| 129 | static struct of_device_id __initdata of_bus_ids[] = { | ||
| 130 | { .name = "soc", }, | ||
| 131 | { .name = "cpm", }, | ||
| 132 | { .name = "localbus", }, | ||
| 133 | { .compatible = "simple-bus" }, | ||
| 134 | {}, | ||
| 135 | }; | ||
| 136 | |||
| 137 | static int __init declare_of_platform_devices(void) | ||
| 138 | { | ||
| 139 | of_platform_bus_probe(NULL, of_bus_ids, NULL); | ||
| 140 | |||
| 141 | return 0; | ||
| 142 | } | ||
| 143 | machine_device_initcall(tqm8xx, declare_of_platform_devices); | ||
| 144 | |||
| 145 | define_machine(tqm8xx) { | ||
| 146 | .name = "TQM8xx", | ||
| 147 | .probe = tqm8xx_probe, | ||
| 148 | .setup_arch = tqm8xx_setup_arch, | ||
| 149 | .init_IRQ = mpc8xx_pics_init, | ||
| 150 | .get_irq = mpc8xx_get_irq, | ||
| 151 | .restart = mpc8xx_restart, | ||
| 152 | .calibrate_decr = mpc8xx_calibrate_decr, | ||
| 153 | .set_rtc_time = mpc8xx_set_rtc_time, | ||
| 154 | .get_rtc_time = mpc8xx_get_rtc_time, | ||
| 155 | .progress = udbg_progress, | ||
| 156 | }; | ||
diff --git a/arch/powerpc/platforms/amigaone/setup.c b/arch/powerpc/platforms/amigaone/setup.c index fb4eb0df054c..03aabc0e16ac 100644 --- a/arch/powerpc/platforms/amigaone/setup.c +++ b/arch/powerpc/platforms/amigaone/setup.c | |||
| @@ -13,12 +13,13 @@ | |||
| 13 | */ | 13 | */ |
| 14 | 14 | ||
| 15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
| 16 | #include <linux/of.h> | ||
| 17 | #include <linux/of_address.h> | ||
| 16 | #include <linux/seq_file.h> | 18 | #include <linux/seq_file.h> |
| 17 | #include <generated/utsrelease.h> | 19 | #include <generated/utsrelease.h> |
| 18 | 20 | ||
| 19 | #include <asm/machdep.h> | 21 | #include <asm/machdep.h> |
| 20 | #include <asm/cputable.h> | 22 | #include <asm/cputable.h> |
| 21 | #include <asm/prom.h> | ||
| 22 | #include <asm/pci-bridge.h> | 23 | #include <asm/pci-bridge.h> |
| 23 | #include <asm/i8259.h> | 24 | #include <asm/i8259.h> |
| 24 | #include <asm/time.h> | 25 | #include <asm/time.h> |
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c index 6257e5378615..97085530aa63 100644 --- a/arch/powerpc/platforms/cell/axon_msi.c +++ b/arch/powerpc/platforms/cell/axon_msi.c | |||
| @@ -328,7 +328,7 @@ static struct irq_host_ops msic_host_ops = { | |||
| 328 | .map = msic_host_map, | 328 | .map = msic_host_map, |
| 329 | }; | 329 | }; |
| 330 | 330 | ||
| 331 | static int axon_msi_shutdown(struct of_device *device) | 331 | static int axon_msi_shutdown(struct platform_device *device) |
| 332 | { | 332 | { |
| 333 | struct axon_msic *msic = dev_get_drvdata(&device->dev); | 333 | struct axon_msic *msic = dev_get_drvdata(&device->dev); |
| 334 | u32 tmp; | 334 | u32 tmp; |
| @@ -342,7 +342,7 @@ static int axon_msi_shutdown(struct of_device *device) | |||
| 342 | return 0; | 342 | return 0; |
| 343 | } | 343 | } |
| 344 | 344 | ||
| 345 | static int axon_msi_probe(struct of_device *device, | 345 | static int axon_msi_probe(struct platform_device *device, |
| 346 | const struct of_device_id *device_id) | 346 | const struct of_device_id *device_id) |
| 347 | { | 347 | { |
| 348 | struct device_node *dn = device->dev.of_node; | 348 | struct device_node *dn = device->dev.of_node; |
diff --git a/arch/powerpc/platforms/cell/beat_iommu.c b/arch/powerpc/platforms/cell/beat_iommu.c index 39d361c5c6d2..beec405eb6f8 100644 --- a/arch/powerpc/platforms/cell/beat_iommu.c +++ b/arch/powerpc/platforms/cell/beat_iommu.c | |||
| @@ -108,7 +108,7 @@ static int __init celleb_init_iommu(void) | |||
| 108 | celleb_init_direct_mapping(); | 108 | celleb_init_direct_mapping(); |
| 109 | set_pci_dma_ops(&dma_direct_ops); | 109 | set_pci_dma_ops(&dma_direct_ops); |
| 110 | ppc_md.pci_dma_dev_setup = celleb_pci_dma_dev_setup; | 110 | ppc_md.pci_dma_dev_setup = celleb_pci_dma_dev_setup; |
| 111 | bus_register_notifier(&of_platform_bus_type, &celleb_of_bus_notifier); | 111 | bus_register_notifier(&platform_bus_type, &celleb_of_bus_notifier); |
| 112 | 112 | ||
| 113 | return 0; | 113 | return 0; |
| 114 | } | 114 | } |
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c index 3712900471ba..58b13ce3847e 100644 --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c | |||
| @@ -1204,7 +1204,7 @@ static int __init cell_iommu_init(void) | |||
| 1204 | /* Register callbacks on OF platform device addition/removal | 1204 | /* Register callbacks on OF platform device addition/removal |
| 1205 | * to handle linking them to the right DMA operations | 1205 | * to handle linking them to the right DMA operations |
| 1206 | */ | 1206 | */ |
| 1207 | bus_register_notifier(&of_platform_bus_type, &cell_of_bus_notifier); | 1207 | bus_register_notifier(&platform_bus_type, &cell_of_bus_notifier); |
| 1208 | 1208 | ||
| 1209 | return 0; | 1209 | return 0; |
| 1210 | } | 1210 | } |
diff --git a/arch/powerpc/platforms/cell/qpace_setup.c b/arch/powerpc/platforms/cell/qpace_setup.c index c5ce02e84c8e..1b5749042756 100644 --- a/arch/powerpc/platforms/cell/qpace_setup.c +++ b/arch/powerpc/platforms/cell/qpace_setup.c | |||
| @@ -61,12 +61,24 @@ static void qpace_progress(char *s, unsigned short hex) | |||
| 61 | printk("*** %04x : %s\n", hex, s ? s : ""); | 61 | printk("*** %04x : %s\n", hex, s ? s : ""); |
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | static const struct of_device_id qpace_bus_ids[] __initdata = { | ||
| 65 | { .type = "soc", }, | ||
| 66 | { .compatible = "soc", }, | ||
| 67 | { .type = "spider", }, | ||
| 68 | { .type = "axon", }, | ||
| 69 | { .type = "plb5", }, | ||
| 70 | { .type = "plb4", }, | ||
| 71 | { .type = "opb", }, | ||
| 72 | { .type = "ebc", }, | ||
| 73 | {}, | ||
| 74 | }; | ||
| 75 | |||
| 64 | static int __init qpace_publish_devices(void) | 76 | static int __init qpace_publish_devices(void) |
| 65 | { | 77 | { |
| 66 | int node; | 78 | int node; |
| 67 | 79 | ||
| 68 | /* Publish OF platform devices for southbridge IOs */ | 80 | /* Publish OF platform devices for southbridge IOs */ |
| 69 | of_platform_bus_probe(NULL, NULL, NULL); | 81 | of_platform_bus_probe(NULL, qpace_bus_ids, NULL); |
| 70 | 82 | ||
| 71 | /* There is no device for the MIC memory controller, thus we create | 83 | /* There is no device for the MIC memory controller, thus we create |
| 72 | * a platform device for it to attach the EDAC driver to. | 84 | * a platform device for it to attach the EDAC driver to. |
diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c index 50385db586bd..691995761b3d 100644 --- a/arch/powerpc/platforms/cell/setup.c +++ b/arch/powerpc/platforms/cell/setup.c | |||
| @@ -141,6 +141,18 @@ static int __devinit cell_setup_phb(struct pci_controller *phb) | |||
| 141 | return 0; | 141 | return 0; |
| 142 | } | 142 | } |
| 143 | 143 | ||
| 144 | static const struct of_device_id cell_bus_ids[] __initdata = { | ||
| 145 | { .type = "soc", }, | ||
| 146 | { .compatible = "soc", }, | ||
| 147 | { .type = "spider", }, | ||
| 148 | { .type = "axon", }, | ||
| 149 | { .type = "plb5", }, | ||
| 150 | { .type = "plb4", }, | ||
| 151 | { .type = "opb", }, | ||
| 152 | { .type = "ebc", }, | ||
| 153 | {}, | ||
| 154 | }; | ||
| 155 | |||
| 144 | static int __init cell_publish_devices(void) | 156 | static int __init cell_publish_devices(void) |
| 145 | { | 157 | { |
| 146 | struct device_node *root = of_find_node_by_path("/"); | 158 | struct device_node *root = of_find_node_by_path("/"); |
| @@ -148,7 +160,7 @@ static int __init cell_publish_devices(void) | |||
| 148 | int node; | 160 | int node; |
| 149 | 161 | ||
| 150 | /* Publish OF platform devices for southbridge IOs */ | 162 | /* Publish OF platform devices for southbridge IOs */ |
| 151 | of_platform_bus_probe(NULL, NULL, NULL); | 163 | of_platform_bus_probe(NULL, cell_bus_ids, NULL); |
| 152 | 164 | ||
| 153 | /* On spider based blades, we need to manually create the OF | 165 | /* On spider based blades, we need to manually create the OF |
| 154 | * platform devices for the PCI host bridges | 166 | * platform devices for the PCI host bridges |
diff --git a/arch/powerpc/platforms/iseries/mf.c b/arch/powerpc/platforms/iseries/mf.c index d2c1d497846e..33e5fc7334fc 100644 --- a/arch/powerpc/platforms/iseries/mf.c +++ b/arch/powerpc/platforms/iseries/mf.c | |||
| @@ -30,6 +30,7 @@ | |||
| 30 | #include <linux/init.h> | 30 | #include <linux/init.h> |
| 31 | #include <linux/completion.h> | 31 | #include <linux/completion.h> |
| 32 | #include <linux/delay.h> | 32 | #include <linux/delay.h> |
| 33 | #include <linux/proc_fs.h> | ||
| 33 | #include <linux/dma-mapping.h> | 34 | #include <linux/dma-mapping.h> |
| 34 | #include <linux/bcd.h> | 35 | #include <linux/bcd.h> |
| 35 | #include <linux/rtc.h> | 36 | #include <linux/rtc.h> |
diff --git a/arch/powerpc/platforms/iseries/vio.c b/arch/powerpc/platforms/iseries/vio.c index 00b6730bc48f..b6db7cef83b4 100644 --- a/arch/powerpc/platforms/iseries/vio.c +++ b/arch/powerpc/platforms/iseries/vio.c | |||
| @@ -87,12 +87,11 @@ static struct device_node *new_node(const char *path, | |||
| 87 | 87 | ||
| 88 | if (!np) | 88 | if (!np) |
| 89 | return NULL; | 89 | return NULL; |
| 90 | np->full_name = kmalloc(strlen(path) + 1, GFP_KERNEL); | 90 | np->full_name = kstrdup(path, GFP_KERNEL); |
| 91 | if (!np->full_name) { | 91 | if (!np->full_name) { |
| 92 | kfree(np); | 92 | kfree(np); |
| 93 | return NULL; | 93 | return NULL; |
| 94 | } | 94 | } |
| 95 | strcpy(np->full_name, path); | ||
| 96 | of_node_set_flag(np, OF_DYNAMIC); | 95 | of_node_set_flag(np, OF_DYNAMIC); |
| 97 | kref_init(&np->kref); | 96 | kref_init(&np->kref); |
| 98 | np->parent = of_node_get(parent); | 97 | np->parent = of_node_get(parent); |
diff --git a/arch/powerpc/platforms/pasemi/gpio_mdio.c b/arch/powerpc/platforms/pasemi/gpio_mdio.c index 627ee089e75d..a5d907b5a4c2 100644 --- a/arch/powerpc/platforms/pasemi/gpio_mdio.c +++ b/arch/powerpc/platforms/pasemi/gpio_mdio.c | |||
| @@ -216,7 +216,7 @@ static int gpio_mdio_reset(struct mii_bus *bus) | |||
| 216 | } | 216 | } |
| 217 | 217 | ||
| 218 | 218 | ||
| 219 | static int __devinit gpio_mdio_probe(struct of_device *ofdev, | 219 | static int __devinit gpio_mdio_probe(struct platform_device *ofdev, |
| 220 | const struct of_device_id *match) | 220 | const struct of_device_id *match) |
| 221 | { | 221 | { |
| 222 | struct device *dev = &ofdev->dev; | 222 | struct device *dev = &ofdev->dev; |
| @@ -275,7 +275,7 @@ out: | |||
| 275 | } | 275 | } |
| 276 | 276 | ||
| 277 | 277 | ||
| 278 | static int gpio_mdio_remove(struct of_device *dev) | 278 | static int gpio_mdio_remove(struct platform_device *dev) |
| 279 | { | 279 | { |
| 280 | struct mii_bus *bus = dev_get_drvdata(&dev->dev); | 280 | struct mii_bus *bus = dev_get_drvdata(&dev->dev); |
| 281 | 281 | ||
diff --git a/arch/powerpc/platforms/powermac/cpufreq_32.c b/arch/powerpc/platforms/powermac/cpufreq_32.c index 1e9eba175ff0..415ca6d6b273 100644 --- a/arch/powerpc/platforms/powermac/cpufreq_32.c +++ b/arch/powerpc/platforms/powermac/cpufreq_32.c | |||
| @@ -310,8 +310,12 @@ static int pmu_set_cpu_speed(int low_speed) | |||
| 310 | /* Restore low level PMU operations */ | 310 | /* Restore low level PMU operations */ |
| 311 | pmu_unlock(); | 311 | pmu_unlock(); |
| 312 | 312 | ||
| 313 | /* Restore decrementer */ | 313 | /* |
| 314 | wakeup_decrementer(); | 314 | * Restore decrementer; we'll take a decrementer interrupt |
| 315 | * as soon as interrupts are re-enabled and the generic | ||
| 316 | * clockevents code will reprogram it with the right value. | ||
| 317 | */ | ||
| 318 | set_dec(1); | ||
| 315 | 319 | ||
| 316 | /* Restore interrupts */ | 320 | /* Restore interrupts */ |
| 317 | mpic_cpu_set_priority(pic_prio); | 321 | mpic_cpu_set_priority(pic_prio); |
diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c index 9e1b9fd75206..39df6ab1735a 100644 --- a/arch/powerpc/platforms/powermac/feature.c +++ b/arch/powerpc/platforms/powermac/feature.c | |||
| @@ -21,6 +21,8 @@ | |||
| 21 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
| 22 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
| 23 | #include <linux/sched.h> | 23 | #include <linux/sched.h> |
| 24 | #include <linux/of.h> | ||
| 25 | #include <linux/of_address.h> | ||
| 24 | #include <linux/spinlock.h> | 26 | #include <linux/spinlock.h> |
| 25 | #include <linux/adb.h> | 27 | #include <linux/adb.h> |
| 26 | #include <linux/pmu.h> | 28 | #include <linux/pmu.h> |
| @@ -2191,7 +2193,11 @@ static struct pmac_mb_def pmac_mb_defs[] = { | |||
| 2191 | PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, | 2193 | PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, |
| 2192 | PMAC_MB_MAY_SLEEP, | 2194 | PMAC_MB_MAY_SLEEP, |
| 2193 | }, | 2195 | }, |
| 2194 | { "iMac,1", "iMac (first generation)", | 2196 | { "PowerMac10,2", "Mac mini (Late 2005)", |
| 2197 | PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, | ||
| 2198 | PMAC_MB_MAY_SLEEP, | ||
| 2199 | }, | ||
| 2200 | { "iMac,1", "iMac (first generation)", | ||
| 2195 | PMAC_TYPE_ORIG_IMAC, paddington_features, | 2201 | PMAC_TYPE_ORIG_IMAC, paddington_features, |
| 2196 | 0 | 2202 | 0 |
| 2197 | }, | 2203 | }, |
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c index 630a533d0e59..890d5f72b198 100644 --- a/arch/powerpc/platforms/powermac/pic.c +++ b/arch/powerpc/platforms/powermac/pic.c | |||
| @@ -46,6 +46,10 @@ struct pmac_irq_hw { | |||
| 46 | unsigned int level; | 46 | unsigned int level; |
| 47 | }; | 47 | }; |
| 48 | 48 | ||
| 49 | /* Workaround flags for 32bit powermac machines */ | ||
| 50 | unsigned int of_irq_workarounds; | ||
| 51 | struct device_node *of_irq_dflt_pic; | ||
| 52 | |||
| 49 | /* Default addresses */ | 53 | /* Default addresses */ |
| 50 | static volatile struct pmac_irq_hw __iomem *pmac_irq_hw[4]; | 54 | static volatile struct pmac_irq_hw __iomem *pmac_irq_hw[4]; |
| 51 | 55 | ||
| @@ -428,6 +432,42 @@ static void __init pmac_pic_probe_oldstyle(void) | |||
| 428 | setup_irq(irq_create_mapping(NULL, 20), &xmon_action); | 432 | setup_irq(irq_create_mapping(NULL, 20), &xmon_action); |
| 429 | #endif | 433 | #endif |
| 430 | } | 434 | } |
| 435 | |||
| 436 | int of_irq_map_oldworld(struct device_node *device, int index, | ||
| 437 | struct of_irq *out_irq) | ||
| 438 | { | ||
| 439 | const u32 *ints = NULL; | ||
| 440 | int intlen; | ||
| 441 | |||
| 442 | /* | ||
| 443 | * Old machines just have a list of interrupt numbers | ||
| 444 | * and no interrupt-controller nodes. We also have dodgy | ||
| 445 | * cases where the APPL,interrupts property is completely | ||
| 446 | * missing behind pci-pci bridges and we have to get it | ||
| 447 | * from the parent (the bridge itself, as apple just wired | ||
| 448 | * everything together on these) | ||
| 449 | */ | ||
| 450 | while (device) { | ||
| 451 | ints = of_get_property(device, "AAPL,interrupts", &intlen); | ||
| 452 | if (ints != NULL) | ||
| 453 | break; | ||
| 454 | device = device->parent; | ||
| 455 | if (device && strcmp(device->type, "pci") != 0) | ||
| 456 | break; | ||
| 457 | } | ||
| 458 | if (ints == NULL) | ||
| 459 | return -EINVAL; | ||
| 460 | intlen /= sizeof(u32); | ||
| 461 | |||
| 462 | if (index >= intlen) | ||
| 463 | return -EINVAL; | ||
| 464 | |||
| 465 | out_irq->controller = NULL; | ||
| 466 | out_irq->specifier[0] = ints[index]; | ||
| 467 | out_irq->size = 1; | ||
| 468 | |||
| 469 | return 0; | ||
| 470 | } | ||
| 431 | #endif /* CONFIG_PPC32 */ | 471 | #endif /* CONFIG_PPC32 */ |
| 432 | 472 | ||
| 433 | static void pmac_u3_cascade(unsigned int irq, struct irq_desc *desc) | 473 | static void pmac_u3_cascade(unsigned int irq, struct irq_desc *desc) |
| @@ -559,19 +599,39 @@ static int __init pmac_pic_probe_mpic(void) | |||
| 559 | 599 | ||
| 560 | void __init pmac_pic_init(void) | 600 | void __init pmac_pic_init(void) |
| 561 | { | 601 | { |
| 562 | unsigned int flags = 0; | ||
| 563 | |||
| 564 | /* We configure the OF parsing based on our oldworld vs. newworld | 602 | /* We configure the OF parsing based on our oldworld vs. newworld |
| 565 | * platform type and wether we were booted by BootX. | 603 | * platform type and wether we were booted by BootX. |
| 566 | */ | 604 | */ |
| 567 | #ifdef CONFIG_PPC32 | 605 | #ifdef CONFIG_PPC32 |
| 568 | if (!pmac_newworld) | 606 | if (!pmac_newworld) |
| 569 | flags |= OF_IMAP_OLDWORLD_MAC; | 607 | of_irq_workarounds |= OF_IMAP_OLDWORLD_MAC; |
| 570 | if (of_get_property(of_chosen, "linux,bootx", NULL) != NULL) | 608 | if (of_get_property(of_chosen, "linux,bootx", NULL) != NULL) |
| 571 | flags |= OF_IMAP_NO_PHANDLE; | 609 | of_irq_workarounds |= OF_IMAP_NO_PHANDLE; |
| 572 | #endif /* CONFIG_PPC_32 */ | ||
| 573 | 610 | ||
| 574 | of_irq_map_init(flags); | 611 | /* If we don't have phandles on a newworld, then try to locate a |
| 612 | * default interrupt controller (happens when booting with BootX). | ||
| 613 | * We do a first match here, hopefully, that only ever happens on | ||
| 614 | * machines with one controller. | ||
| 615 | */ | ||
| 616 | if (pmac_newworld && (of_irq_workarounds & OF_IMAP_NO_PHANDLE)) { | ||
| 617 | struct device_node *np; | ||
| 618 | |||
| 619 | for_each_node_with_property(np, "interrupt-controller") { | ||
| 620 | /* Skip /chosen/interrupt-controller */ | ||
| 621 | if (strcmp(np->name, "chosen") == 0) | ||
| 622 | continue; | ||
| 623 | /* It seems like at least one person wants | ||
| 624 | * to use BootX on a machine with an AppleKiwi | ||
| 625 | * controller which happens to pretend to be an | ||
| 626 | * interrupt controller too. */ | ||
| 627 | if (strcmp(np->name, "AppleKiwi") == 0) | ||
| 628 | continue; | ||
| 629 | /* I think we found one ! */ | ||
| 630 | of_irq_dflt_pic = np; | ||
| 631 | break; | ||
| 632 | } | ||
| 633 | } | ||
| 634 | #endif /* CONFIG_PPC32 */ | ||
| 575 | 635 | ||
| 576 | /* We first try to detect Apple's new Core99 chipset, since mac-io | 636 | /* We first try to detect Apple's new Core99 chipset, since mac-io |
| 577 | * is quite different on those machines and contains an IBM MPIC2. | 637 | * is quite different on those machines and contains an IBM MPIC2. |
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile index 3dbef309bc8d..046ace9c4381 100644 --- a/arch/powerpc/platforms/pseries/Makefile +++ b/arch/powerpc/platforms/pseries/Makefile | |||
| @@ -26,3 +26,7 @@ obj-$(CONFIG_HCALL_STATS) += hvCall_inst.o | |||
| 26 | obj-$(CONFIG_PHYP_DUMP) += phyp_dump.o | 26 | obj-$(CONFIG_PHYP_DUMP) += phyp_dump.o |
| 27 | obj-$(CONFIG_CMM) += cmm.o | 27 | obj-$(CONFIG_CMM) += cmm.o |
| 28 | obj-$(CONFIG_DTL) += dtl.o | 28 | obj-$(CONFIG_DTL) += dtl.o |
| 29 | |||
| 30 | ifeq ($(CONFIG_PPC_PSERIES),y) | ||
| 31 | obj-$(CONFIG_SUSPEND) += suspend.o | ||
| 32 | endif | ||
diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c index d71e58584086..227c1c3d585e 100644 --- a/arch/powerpc/platforms/pseries/dlpar.c +++ b/arch/powerpc/platforms/pseries/dlpar.c | |||
| @@ -463,6 +463,7 @@ static int dlpar_offline_cpu(struct device_node *dn) | |||
| 463 | break; | 463 | break; |
| 464 | 464 | ||
| 465 | if (get_cpu_current_state(cpu) == CPU_STATE_ONLINE) { | 465 | if (get_cpu_current_state(cpu) == CPU_STATE_ONLINE) { |
| 466 | set_preferred_offline_state(cpu, CPU_STATE_OFFLINE); | ||
| 466 | cpu_maps_update_done(); | 467 | cpu_maps_update_done(); |
| 467 | rc = cpu_down(cpu); | 468 | rc = cpu_down(cpu); |
| 468 | if (rc) | 469 | if (rc) |
diff --git a/arch/powerpc/platforms/pseries/eeh_cache.c b/arch/powerpc/platforms/pseries/eeh_cache.c index 30b987b73c20..8ed0d2d0e1b5 100644 --- a/arch/powerpc/platforms/pseries/eeh_cache.c +++ b/arch/powerpc/platforms/pseries/eeh_cache.c | |||
| @@ -288,8 +288,7 @@ void __init pci_addr_cache_build(void) | |||
| 288 | 288 | ||
| 289 | spin_lock_init(&pci_io_addr_cache_root.piar_lock); | 289 | spin_lock_init(&pci_io_addr_cache_root.piar_lock); |
| 290 | 290 | ||
| 291 | while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { | 291 | for_each_pci_dev(dev) { |
| 292 | |||
| 293 | pci_addr_cache_insert_device(dev); | 292 | pci_addr_cache_insert_device(dev); |
| 294 | 293 | ||
| 295 | dn = pci_device_to_OF_node(dev); | 294 | dn = pci_device_to_OF_node(dev); |
diff --git a/arch/powerpc/platforms/pseries/event_sources.c b/arch/powerpc/platforms/pseries/event_sources.c index e889c9d9586a..2605c310166a 100644 --- a/arch/powerpc/platforms/pseries/event_sources.c +++ b/arch/powerpc/platforms/pseries/event_sources.c | |||
| @@ -41,9 +41,12 @@ void request_event_sources_irqs(struct device_node *np, | |||
| 41 | if (count > 15) | 41 | if (count > 15) |
| 42 | break; | 42 | break; |
| 43 | virqs[count] = irq_create_mapping(NULL, *(opicprop++)); | 43 | virqs[count] = irq_create_mapping(NULL, *(opicprop++)); |
| 44 | if (virqs[count] == NO_IRQ) | 44 | if (virqs[count] == NO_IRQ) { |
| 45 | printk(KERN_ERR "Unable to allocate interrupt " | 45 | pr_err("event-sources: Unable to allocate " |
| 46 | "number for %s\n", np->full_name); | 46 | "interrupt number for %s\n", |
| 47 | np->full_name); | ||
| 48 | WARN_ON(1); | ||
| 49 | } | ||
| 47 | else | 50 | else |
| 48 | count++; | 51 | count++; |
| 49 | 52 | ||
| @@ -59,9 +62,12 @@ void request_event_sources_irqs(struct device_node *np, | |||
| 59 | virqs[count] = irq_create_of_mapping(oirq.controller, | 62 | virqs[count] = irq_create_of_mapping(oirq.controller, |
| 60 | oirq.specifier, | 63 | oirq.specifier, |
| 61 | oirq.size); | 64 | oirq.size); |
| 62 | if (virqs[count] == NO_IRQ) | 65 | if (virqs[count] == NO_IRQ) { |
| 63 | printk(KERN_ERR "Unable to allocate interrupt " | 66 | pr_err("event-sources: Unable to allocate " |
| 64 | "number for %s\n", np->full_name); | 67 | "interrupt number for %s\n", |
| 68 | np->full_name); | ||
| 69 | WARN_ON(1); | ||
| 70 | } | ||
| 65 | else | 71 | else |
| 66 | count++; | 72 | count++; |
| 67 | } | 73 | } |
| @@ -70,8 +76,9 @@ void request_event_sources_irqs(struct device_node *np, | |||
| 70 | /* Now request them */ | 76 | /* Now request them */ |
| 71 | for (i = 0; i < count; i++) { | 77 | for (i = 0; i < count; i++) { |
| 72 | if (request_irq(virqs[i], handler, 0, name, NULL)) { | 78 | if (request_irq(virqs[i], handler, 0, name, NULL)) { |
| 73 | printk(KERN_ERR "Unable to request interrupt %d for " | 79 | pr_err("event-sources: Unable to request interrupt " |
| 74 | "%s\n", virqs[i], np->full_name); | 80 | "%d for %s\n", virqs[i], np->full_name); |
| 81 | WARN_ON(1); | ||
| 75 | return; | 82 | return; |
| 76 | } | 83 | } |
| 77 | } | 84 | } |
diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index 8f85f399ab9f..fd50ccd4bac1 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c | |||
| @@ -116,6 +116,9 @@ static void pseries_mach_cpu_die(void) | |||
| 116 | 116 | ||
| 117 | if (get_preferred_offline_state(cpu) == CPU_STATE_INACTIVE) { | 117 | if (get_preferred_offline_state(cpu) == CPU_STATE_INACTIVE) { |
| 118 | set_cpu_current_state(cpu, CPU_STATE_INACTIVE); | 118 | set_cpu_current_state(cpu, CPU_STATE_INACTIVE); |
| 119 | if (ppc_md.suspend_disable_cpu) | ||
| 120 | ppc_md.suspend_disable_cpu(); | ||
| 121 | |||
| 119 | cede_latency_hint = 2; | 122 | cede_latency_hint = 2; |
| 120 | 123 | ||
| 121 | get_lppaca()->idle = 1; | 124 | get_lppaca()->idle = 1; |
| @@ -190,12 +193,12 @@ static void pseries_cpu_die(unsigned int cpu) | |||
| 190 | 193 | ||
| 191 | if (get_preferred_offline_state(cpu) == CPU_STATE_INACTIVE) { | 194 | if (get_preferred_offline_state(cpu) == CPU_STATE_INACTIVE) { |
| 192 | cpu_status = 1; | 195 | cpu_status = 1; |
| 193 | for (tries = 0; tries < 1000; tries++) { | 196 | for (tries = 0; tries < 5000; tries++) { |
| 194 | if (get_cpu_current_state(cpu) == CPU_STATE_INACTIVE) { | 197 | if (get_cpu_current_state(cpu) == CPU_STATE_INACTIVE) { |
| 195 | cpu_status = 0; | 198 | cpu_status = 0; |
| 196 | break; | 199 | break; |
| 197 | } | 200 | } |
| 198 | cpu_relax(); | 201 | msleep(1); |
| 199 | } | 202 | } |
| 200 | } else if (get_preferred_offline_state(cpu) == CPU_STATE_OFFLINE) { | 203 | } else if (get_preferred_offline_state(cpu) == CPU_STATE_OFFLINE) { |
| 201 | 204 | ||
diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c index 41a3e9a039ed..a4fc6da87c2e 100644 --- a/arch/powerpc/platforms/pseries/ras.c +++ b/arch/powerpc/platforms/pseries/ras.c | |||
| @@ -61,7 +61,6 @@ static int ras_check_exception_token; | |||
| 61 | 61 | ||
| 62 | #define EPOW_SENSOR_TOKEN 9 | 62 | #define EPOW_SENSOR_TOKEN 9 |
| 63 | #define EPOW_SENSOR_INDEX 0 | 63 | #define EPOW_SENSOR_INDEX 0 |
| 64 | #define RAS_VECTOR_OFFSET 0x500 | ||
| 65 | 64 | ||
| 66 | static irqreturn_t ras_epow_interrupt(int irq, void *dev_id); | 65 | static irqreturn_t ras_epow_interrupt(int irq, void *dev_id); |
| 67 | static irqreturn_t ras_error_interrupt(int irq, void *dev_id); | 66 | static irqreturn_t ras_error_interrupt(int irq, void *dev_id); |
| @@ -121,7 +120,7 @@ static irqreturn_t ras_epow_interrupt(int irq, void *dev_id) | |||
| 121 | spin_lock(&ras_log_buf_lock); | 120 | spin_lock(&ras_log_buf_lock); |
| 122 | 121 | ||
| 123 | status = rtas_call(ras_check_exception_token, 6, 1, NULL, | 122 | status = rtas_call(ras_check_exception_token, 6, 1, NULL, |
| 124 | RAS_VECTOR_OFFSET, | 123 | RTAS_VECTOR_EXTERNAL_INTERRUPT, |
| 125 | irq_map[irq].hwirq, | 124 | irq_map[irq].hwirq, |
| 126 | RTAS_EPOW_WARNING | RTAS_POWERMGM_EVENTS, | 125 | RTAS_EPOW_WARNING | RTAS_POWERMGM_EVENTS, |
| 127 | critical, __pa(&ras_log_buf), | 126 | critical, __pa(&ras_log_buf), |
| @@ -156,7 +155,7 @@ static irqreturn_t ras_error_interrupt(int irq, void *dev_id) | |||
| 156 | spin_lock(&ras_log_buf_lock); | 155 | spin_lock(&ras_log_buf_lock); |
| 157 | 156 | ||
| 158 | status = rtas_call(ras_check_exception_token, 6, 1, NULL, | 157 | status = rtas_call(ras_check_exception_token, 6, 1, NULL, |
| 159 | RAS_VECTOR_OFFSET, | 158 | RTAS_VECTOR_EXTERNAL_INTERRUPT, |
| 160 | irq_map[irq].hwirq, | 159 | irq_map[irq].hwirq, |
| 161 | RTAS_INTERNAL_ERROR, 1 /*Time Critical */, | 160 | RTAS_INTERNAL_ERROR, 1 /*Time Critical */, |
| 162 | __pa(&ras_log_buf), | 161 | __pa(&ras_log_buf), |
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c index 1a58637bcea5..57ddbb43b33a 100644 --- a/arch/powerpc/platforms/pseries/reconfig.c +++ b/arch/powerpc/platforms/pseries/reconfig.c | |||
| @@ -118,12 +118,10 @@ static int pSeries_reconfig_add_node(const char *path, struct property *proplist | |||
| 118 | if (!np) | 118 | if (!np) |
| 119 | goto out_err; | 119 | goto out_err; |
| 120 | 120 | ||
| 121 | np->full_name = kmalloc(strlen(path) + 1, GFP_KERNEL); | 121 | np->full_name = kstrdup(path, GFP_KERNEL); |
| 122 | if (!np->full_name) | 122 | if (!np->full_name) |
| 123 | goto out_err; | 123 | goto out_err; |
| 124 | 124 | ||
| 125 | strcpy(np->full_name, path); | ||
| 126 | |||
| 127 | np->properties = proplist; | 125 | np->properties = proplist; |
| 128 | of_node_set_flag(np, OF_DYNAMIC); | 126 | of_node_set_flag(np, OF_DYNAMIC); |
| 129 | kref_init(&np->kref); | 127 | kref_init(&np->kref); |
diff --git a/arch/powerpc/platforms/pseries/suspend.c b/arch/powerpc/platforms/pseries/suspend.c new file mode 100644 index 000000000000..ed72098bb4e3 --- /dev/null +++ b/arch/powerpc/platforms/pseries/suspend.c | |||
| @@ -0,0 +1,214 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2010 Brian King IBM Corporation | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License as published by | ||
| 6 | * the Free Software Foundation; either version 2 of the License, or | ||
| 7 | * (at your option) any later version. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License | ||
| 15 | * along with this program; if not, write to the Free Software | ||
| 16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <linux/delay.h> | ||
| 20 | #include <linux/suspend.h> | ||
| 21 | #include <asm/firmware.h> | ||
| 22 | #include <asm/hvcall.h> | ||
| 23 | #include <asm/machdep.h> | ||
| 24 | #include <asm/mmu.h> | ||
| 25 | #include <asm/rtas.h> | ||
| 26 | |||
| 27 | static u64 stream_id; | ||
| 28 | static struct sys_device suspend_sysdev; | ||
| 29 | static DECLARE_COMPLETION(suspend_work); | ||
| 30 | static struct rtas_suspend_me_data suspend_data; | ||
| 31 | static atomic_t suspending; | ||
| 32 | |||
| 33 | /** | ||
| 34 | * pseries_suspend_begin - First phase of hibernation | ||
| 35 | * | ||
| 36 | * Check to ensure we are in a valid state to hibernate | ||
| 37 | * | ||
| 38 | * Return value: | ||
| 39 | * 0 on success / other on failure | ||
| 40 | **/ | ||
| 41 | static int pseries_suspend_begin(suspend_state_t state) | ||
| 42 | { | ||
| 43 | long vasi_state, rc; | ||
| 44 | unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; | ||
| 45 | |||
| 46 | /* Make sure the state is valid */ | ||
| 47 | rc = plpar_hcall(H_VASI_STATE, retbuf, stream_id); | ||
| 48 | |||
| 49 | vasi_state = retbuf[0]; | ||
| 50 | |||
| 51 | if (rc) { | ||
| 52 | pr_err("pseries_suspend_begin: vasi_state returned %ld\n",rc); | ||
| 53 | return rc; | ||
| 54 | } else if (vasi_state == H_VASI_ENABLED) { | ||
| 55 | return -EAGAIN; | ||
| 56 | } else if (vasi_state != H_VASI_SUSPENDING) { | ||
| 57 | pr_err("pseries_suspend_begin: vasi_state returned state %ld\n", | ||
| 58 | vasi_state); | ||
| 59 | return -EIO; | ||
| 60 | } | ||
| 61 | |||
| 62 | return 0; | ||
| 63 | } | ||
| 64 | |||
| 65 | /** | ||
| 66 | * pseries_suspend_cpu - Suspend a single CPU | ||
| 67 | * | ||
| 68 | * Makes the H_JOIN call to suspend the CPU | ||
| 69 | * | ||
| 70 | **/ | ||
| 71 | static int pseries_suspend_cpu(void) | ||
| 72 | { | ||
| 73 | if (atomic_read(&suspending)) | ||
| 74 | return rtas_suspend_cpu(&suspend_data); | ||
| 75 | return 0; | ||
| 76 | } | ||
| 77 | |||
| 78 | /** | ||
| 79 | * pseries_suspend_enter - Final phase of hibernation | ||
| 80 | * | ||
| 81 | * Return value: | ||
| 82 | * 0 on success / other on failure | ||
| 83 | **/ | ||
| 84 | static int pseries_suspend_enter(suspend_state_t state) | ||
| 85 | { | ||
| 86 | int rc = rtas_suspend_last_cpu(&suspend_data); | ||
| 87 | |||
| 88 | atomic_set(&suspending, 0); | ||
| 89 | atomic_set(&suspend_data.done, 1); | ||
| 90 | return rc; | ||
| 91 | } | ||
| 92 | |||
| 93 | /** | ||
| 94 | * pseries_prepare_late - Prepare to suspend all other CPUs | ||
| 95 | * | ||
| 96 | * Return value: | ||
| 97 | * 0 on success / other on failure | ||
| 98 | **/ | ||
| 99 | static int pseries_prepare_late(void) | ||
| 100 | { | ||
| 101 | atomic_set(&suspending, 1); | ||
| 102 | atomic_set(&suspend_data.working, 0); | ||
| 103 | atomic_set(&suspend_data.done, 0); | ||
| 104 | atomic_set(&suspend_data.error, 0); | ||
| 105 | suspend_data.complete = &suspend_work; | ||
| 106 | INIT_COMPLETION(suspend_work); | ||
| 107 | return 0; | ||
| 108 | } | ||
| 109 | |||
| 110 | /** | ||
| 111 | * store_hibernate - Initiate partition hibernation | ||
| 112 | * @classdev: sysdev class struct | ||
| 113 | * @attr: class device attribute struct | ||
| 114 | * @buf: buffer | ||
| 115 | * @count: buffer size | ||
| 116 | * | ||
| 117 | * Write the stream ID received from the HMC to this file | ||
| 118 | * to trigger hibernating the partition | ||
| 119 | * | ||
| 120 | * Return value: | ||
| 121 | * number of bytes printed to buffer / other on failure | ||
| 122 | **/ | ||
| 123 | static ssize_t store_hibernate(struct sysdev_class *classdev, | ||
| 124 | struct sysdev_class_attribute *attr, | ||
| 125 | const char *buf, size_t count) | ||
| 126 | { | ||
| 127 | int rc; | ||
| 128 | |||
| 129 | if (!capable(CAP_SYS_ADMIN)) | ||
| 130 | return -EPERM; | ||
| 131 | |||
| 132 | stream_id = simple_strtoul(buf, NULL, 16); | ||
| 133 | |||
| 134 | do { | ||
| 135 | rc = pseries_suspend_begin(PM_SUSPEND_MEM); | ||
| 136 | if (rc == -EAGAIN) | ||
| 137 | ssleep(1); | ||
| 138 | } while (rc == -EAGAIN); | ||
| 139 | |||
| 140 | if (!rc) | ||
| 141 | rc = pm_suspend(PM_SUSPEND_MEM); | ||
| 142 | |||
| 143 | stream_id = 0; | ||
| 144 | |||
| 145 | if (!rc) | ||
| 146 | rc = count; | ||
| 147 | return rc; | ||
| 148 | } | ||
| 149 | |||
| 150 | static SYSDEV_CLASS_ATTR(hibernate, S_IWUSR, NULL, store_hibernate); | ||
| 151 | |||
| 152 | static struct sysdev_class suspend_sysdev_class = { | ||
| 153 | .name = "power", | ||
| 154 | }; | ||
| 155 | |||
| 156 | static struct platform_suspend_ops pseries_suspend_ops = { | ||
| 157 | .valid = suspend_valid_only_mem, | ||
| 158 | .begin = pseries_suspend_begin, | ||
| 159 | .prepare_late = pseries_prepare_late, | ||
| 160 | .enter = pseries_suspend_enter, | ||
| 161 | }; | ||
| 162 | |||
| 163 | /** | ||
| 164 | * pseries_suspend_sysfs_register - Register with sysfs | ||
| 165 | * | ||
| 166 | * Return value: | ||
| 167 | * 0 on success / other on failure | ||
| 168 | **/ | ||
| 169 | static int pseries_suspend_sysfs_register(struct sys_device *sysdev) | ||
| 170 | { | ||
| 171 | int rc; | ||
| 172 | |||
| 173 | if ((rc = sysdev_class_register(&suspend_sysdev_class))) | ||
| 174 | return rc; | ||
| 175 | |||
| 176 | sysdev->id = 0; | ||
| 177 | sysdev->cls = &suspend_sysdev_class; | ||
| 178 | |||
| 179 | if ((rc = sysdev_class_create_file(&suspend_sysdev_class, &attr_hibernate))) | ||
| 180 | goto class_unregister; | ||
| 181 | |||
| 182 | return 0; | ||
| 183 | |||
| 184 | class_unregister: | ||
| 185 | sysdev_class_unregister(&suspend_sysdev_class); | ||
| 186 | return rc; | ||
| 187 | } | ||
| 188 | |||
| 189 | /** | ||
| 190 | * pseries_suspend_init - initcall for pSeries suspend | ||
| 191 | * | ||
| 192 | * Return value: | ||
| 193 | * 0 on success / other on failure | ||
| 194 | **/ | ||
| 195 | static int __init pseries_suspend_init(void) | ||
| 196 | { | ||
| 197 | int rc; | ||
| 198 | |||
| 199 | if (!machine_is(pseries) || !firmware_has_feature(FW_FEATURE_LPAR)) | ||
| 200 | return 0; | ||
| 201 | |||
| 202 | suspend_data.token = rtas_token("ibm,suspend-me"); | ||
| 203 | if (suspend_data.token == RTAS_UNKNOWN_SERVICE) | ||
| 204 | return 0; | ||
| 205 | |||
| 206 | if ((rc = pseries_suspend_sysfs_register(&suspend_sysdev))) | ||
| 207 | return rc; | ||
| 208 | |||
| 209 | ppc_md.suspend_disable_cpu = pseries_suspend_cpu; | ||
| 210 | suspend_set_ops(&pseries_suspend_ops); | ||
| 211 | return 0; | ||
| 212 | } | ||
| 213 | |||
| 214 | __initcall(pseries_suspend_init); | ||
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c index f19d19468393..5b22b07c8f67 100644 --- a/arch/powerpc/platforms/pseries/xics.c +++ b/arch/powerpc/platforms/pseries/xics.c | |||
| @@ -549,8 +549,6 @@ static irqreturn_t xics_ipi_dispatch(int cpu) | |||
| 549 | { | 549 | { |
| 550 | unsigned long *tgt = &per_cpu(xics_ipi_message, cpu); | 550 | unsigned long *tgt = &per_cpu(xics_ipi_message, cpu); |
| 551 | 551 | ||
| 552 | WARN_ON(cpu_is_offline(cpu)); | ||
| 553 | |||
| 554 | mb(); /* order mmio clearing qirr */ | 552 | mb(); /* order mmio clearing qirr */ |
| 555 | while (*tgt) { | 553 | while (*tgt) { |
| 556 | if (test_and_clear_bit(PPC_MSG_CALL_FUNCTION, tgt)) { | 554 | if (test_and_clear_bit(PPC_MSG_CALL_FUNCTION, tgt)) { |
diff --git a/arch/powerpc/sysdev/axonram.c b/arch/powerpc/sysdev/axonram.c index 402d2212162f..2659a60bd7b8 100644 --- a/arch/powerpc/sysdev/axonram.c +++ b/arch/powerpc/sysdev/axonram.c | |||
| @@ -60,7 +60,7 @@ | |||
| 60 | static int azfs_major, azfs_minor; | 60 | static int azfs_major, azfs_minor; |
| 61 | 61 | ||
| 62 | struct axon_ram_bank { | 62 | struct axon_ram_bank { |
| 63 | struct of_device *device; | 63 | struct platform_device *device; |
| 64 | struct gendisk *disk; | 64 | struct gendisk *disk; |
| 65 | unsigned int irq_id; | 65 | unsigned int irq_id; |
| 66 | unsigned long ph_addr; | 66 | unsigned long ph_addr; |
| @@ -72,7 +72,7 @@ struct axon_ram_bank { | |||
| 72 | static ssize_t | 72 | static ssize_t |
| 73 | axon_ram_sysfs_ecc(struct device *dev, struct device_attribute *attr, char *buf) | 73 | axon_ram_sysfs_ecc(struct device *dev, struct device_attribute *attr, char *buf) |
| 74 | { | 74 | { |
| 75 | struct of_device *device = to_of_device(dev); | 75 | struct platform_device *device = to_platform_device(dev); |
| 76 | struct axon_ram_bank *bank = device->dev.platform_data; | 76 | struct axon_ram_bank *bank = device->dev.platform_data; |
| 77 | 77 | ||
| 78 | BUG_ON(!bank); | 78 | BUG_ON(!bank); |
| @@ -90,7 +90,7 @@ static DEVICE_ATTR(ecc, S_IRUGO, axon_ram_sysfs_ecc, NULL); | |||
| 90 | static irqreturn_t | 90 | static irqreturn_t |
| 91 | axon_ram_irq_handler(int irq, void *dev) | 91 | axon_ram_irq_handler(int irq, void *dev) |
| 92 | { | 92 | { |
| 93 | struct of_device *device = dev; | 93 | struct platform_device *device = dev; |
| 94 | struct axon_ram_bank *bank = device->dev.platform_data; | 94 | struct axon_ram_bank *bank = device->dev.platform_data; |
| 95 | 95 | ||
| 96 | BUG_ON(!bank); | 96 | BUG_ON(!bank); |
| @@ -174,8 +174,8 @@ static const struct block_device_operations axon_ram_devops = { | |||
| 174 | * axon_ram_probe - probe() method for platform driver | 174 | * axon_ram_probe - probe() method for platform driver |
| 175 | * @device, @device_id: see of_platform_driver method | 175 | * @device, @device_id: see of_platform_driver method |
| 176 | */ | 176 | */ |
| 177 | static int | 177 | static int axon_ram_probe(struct platform_device *device, |
| 178 | axon_ram_probe(struct of_device *device, const struct of_device_id *device_id) | 178 | const struct of_device_id *device_id) |
| 179 | { | 179 | { |
| 180 | static int axon_ram_bank_id = -1; | 180 | static int axon_ram_bank_id = -1; |
| 181 | struct axon_ram_bank *bank; | 181 | struct axon_ram_bank *bank; |
| @@ -304,7 +304,7 @@ failed: | |||
| 304 | * @device: see of_platform_driver method | 304 | * @device: see of_platform_driver method |
| 305 | */ | 305 | */ |
| 306 | static int | 306 | static int |
| 307 | axon_ram_remove(struct of_device *device) | 307 | axon_ram_remove(struct platform_device *device) |
| 308 | { | 308 | { |
| 309 | struct axon_ram_bank *bank = device->dev.platform_data; | 309 | struct axon_ram_bank *bank = device->dev.platform_data; |
| 310 | 310 | ||
diff --git a/arch/powerpc/sysdev/bestcomm/bestcomm.c b/arch/powerpc/sysdev/bestcomm/bestcomm.c index a7c5c470af14..650256115064 100644 --- a/arch/powerpc/sysdev/bestcomm/bestcomm.c +++ b/arch/powerpc/sysdev/bestcomm/bestcomm.c | |||
| @@ -365,8 +365,8 @@ bcom_engine_cleanup(void) | |||
| 365 | /* OF platform driver */ | 365 | /* OF platform driver */ |
| 366 | /* ======================================================================== */ | 366 | /* ======================================================================== */ |
| 367 | 367 | ||
| 368 | static int __devinit | 368 | static int __devinit mpc52xx_bcom_probe(struct platform_device *op, |
| 369 | mpc52xx_bcom_probe(struct of_device *op, const struct of_device_id *match) | 369 | const struct of_device_id *match) |
| 370 | { | 370 | { |
| 371 | struct device_node *ofn_sram; | 371 | struct device_node *ofn_sram; |
| 372 | struct resource res_bcom; | 372 | struct resource res_bcom; |
| @@ -461,8 +461,7 @@ error_ofput: | |||
| 461 | } | 461 | } |
| 462 | 462 | ||
| 463 | 463 | ||
| 464 | static int | 464 | static int mpc52xx_bcom_remove(struct platform_device *op) |
| 465 | mpc52xx_bcom_remove(struct of_device *op) | ||
| 466 | { | 465 | { |
| 467 | /* Clean up the engine */ | 466 | /* Clean up the engine */ |
| 468 | bcom_engine_cleanup(); | 467 | bcom_engine_cleanup(); |
diff --git a/arch/powerpc/sysdev/bestcomm/sram.c b/arch/powerpc/sysdev/bestcomm/sram.c index 5d74ef7a651f..1225012a681a 100644 --- a/arch/powerpc/sysdev/bestcomm/sram.c +++ b/arch/powerpc/sysdev/bestcomm/sram.c | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | * kind, whether express or implied. | 11 | * kind, whether express or implied. |
| 12 | */ | 12 | */ |
| 13 | 13 | ||
| 14 | #include <linux/err.h> | ||
| 14 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
| 15 | #include <linux/module.h> | 16 | #include <linux/module.h> |
| 16 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c index 8d103ca6d6ab..00852124ff4a 100644 --- a/arch/powerpc/sysdev/cpm1.c +++ b/arch/powerpc/sysdev/cpm1.c | |||
| @@ -621,7 +621,6 @@ int cpm1_gpiochip_add16(struct device_node *np) | |||
| 621 | { | 621 | { |
| 622 | struct cpm1_gpio16_chip *cpm1_gc; | 622 | struct cpm1_gpio16_chip *cpm1_gc; |
| 623 | struct of_mm_gpio_chip *mm_gc; | 623 | struct of_mm_gpio_chip *mm_gc; |
| 624 | struct of_gpio_chip *of_gc; | ||
| 625 | struct gpio_chip *gc; | 624 | struct gpio_chip *gc; |
| 626 | 625 | ||
| 627 | cpm1_gc = kzalloc(sizeof(*cpm1_gc), GFP_KERNEL); | 626 | cpm1_gc = kzalloc(sizeof(*cpm1_gc), GFP_KERNEL); |
| @@ -631,11 +630,9 @@ int cpm1_gpiochip_add16(struct device_node *np) | |||
| 631 | spin_lock_init(&cpm1_gc->lock); | 630 | spin_lock_init(&cpm1_gc->lock); |
| 632 | 631 | ||
| 633 | mm_gc = &cpm1_gc->mm_gc; | 632 | mm_gc = &cpm1_gc->mm_gc; |
| 634 | of_gc = &mm_gc->of_gc; | 633 | gc = &mm_gc->gc; |
| 635 | gc = &of_gc->gc; | ||
| 636 | 634 | ||
| 637 | mm_gc->save_regs = cpm1_gpio16_save_regs; | 635 | mm_gc->save_regs = cpm1_gpio16_save_regs; |
| 638 | of_gc->gpio_cells = 2; | ||
| 639 | gc->ngpio = 16; | 636 | gc->ngpio = 16; |
| 640 | gc->direction_input = cpm1_gpio16_dir_in; | 637 | gc->direction_input = cpm1_gpio16_dir_in; |
| 641 | gc->direction_output = cpm1_gpio16_dir_out; | 638 | gc->direction_output = cpm1_gpio16_dir_out; |
| @@ -745,7 +742,6 @@ int cpm1_gpiochip_add32(struct device_node *np) | |||
| 745 | { | 742 | { |
| 746 | struct cpm1_gpio32_chip *cpm1_gc; | 743 | struct cpm1_gpio32_chip *cpm1_gc; |
| 747 | struct of_mm_gpio_chip *mm_gc; | 744 | struct of_mm_gpio_chip *mm_gc; |
| 748 | struct of_gpio_chip *of_gc; | ||
| 749 | struct gpio_chip *gc; | 745 | struct gpio_chip *gc; |
| 750 | 746 | ||
| 751 | cpm1_gc = kzalloc(sizeof(*cpm1_gc), GFP_KERNEL); | 747 | cpm1_gc = kzalloc(sizeof(*cpm1_gc), GFP_KERNEL); |
| @@ -755,11 +751,9 @@ int cpm1_gpiochip_add32(struct device_node *np) | |||
| 755 | spin_lock_init(&cpm1_gc->lock); | 751 | spin_lock_init(&cpm1_gc->lock); |
| 756 | 752 | ||
| 757 | mm_gc = &cpm1_gc->mm_gc; | 753 | mm_gc = &cpm1_gc->mm_gc; |
| 758 | of_gc = &mm_gc->of_gc; | 754 | gc = &mm_gc->gc; |
| 759 | gc = &of_gc->gc; | ||
| 760 | 755 | ||
| 761 | mm_gc->save_regs = cpm1_gpio32_save_regs; | 756 | mm_gc->save_regs = cpm1_gpio32_save_regs; |
| 762 | of_gc->gpio_cells = 2; | ||
| 763 | gc->ngpio = 32; | 757 | gc->ngpio = 32; |
| 764 | gc->direction_input = cpm1_gpio32_dir_in; | 758 | gc->direction_input = cpm1_gpio32_dir_in; |
| 765 | gc->direction_output = cpm1_gpio32_dir_out; | 759 | gc->direction_output = cpm1_gpio32_dir_out; |
diff --git a/arch/powerpc/sysdev/cpm_common.c b/arch/powerpc/sysdev/cpm_common.c index 88b9812c854f..2b69aa0315b3 100644 --- a/arch/powerpc/sysdev/cpm_common.c +++ b/arch/powerpc/sysdev/cpm_common.c | |||
| @@ -325,7 +325,6 @@ int cpm2_gpiochip_add32(struct device_node *np) | |||
| 325 | { | 325 | { |
| 326 | struct cpm2_gpio32_chip *cpm2_gc; | 326 | struct cpm2_gpio32_chip *cpm2_gc; |
| 327 | struct of_mm_gpio_chip *mm_gc; | 327 | struct of_mm_gpio_chip *mm_gc; |
| 328 | struct of_gpio_chip *of_gc; | ||
| 329 | struct gpio_chip *gc; | 328 | struct gpio_chip *gc; |
| 330 | 329 | ||
| 331 | cpm2_gc = kzalloc(sizeof(*cpm2_gc), GFP_KERNEL); | 330 | cpm2_gc = kzalloc(sizeof(*cpm2_gc), GFP_KERNEL); |
| @@ -335,11 +334,9 @@ int cpm2_gpiochip_add32(struct device_node *np) | |||
| 335 | spin_lock_init(&cpm2_gc->lock); | 334 | spin_lock_init(&cpm2_gc->lock); |
| 336 | 335 | ||
| 337 | mm_gc = &cpm2_gc->mm_gc; | 336 | mm_gc = &cpm2_gc->mm_gc; |
| 338 | of_gc = &mm_gc->of_gc; | 337 | gc = &mm_gc->gc; |
| 339 | gc = &of_gc->gc; | ||
| 340 | 338 | ||
| 341 | mm_gc->save_regs = cpm2_gpio32_save_regs; | 339 | mm_gc->save_regs = cpm2_gpio32_save_regs; |
| 342 | of_gc->gpio_cells = 2; | ||
| 343 | gc->ngpio = 32; | 340 | gc->ngpio = 32; |
| 344 | gc->direction_input = cpm2_gpio32_dir_in; | 341 | gc->direction_input = cpm2_gpio32_dir_in; |
| 345 | gc->direction_output = cpm2_gpio32_dir_out; | 342 | gc->direction_output = cpm2_gpio32_dir_out; |
diff --git a/arch/powerpc/sysdev/fsl_gtm.c b/arch/powerpc/sysdev/fsl_gtm.c index eca4545dd52e..7dd2885321ad 100644 --- a/arch/powerpc/sysdev/fsl_gtm.c +++ b/arch/powerpc/sysdev/fsl_gtm.c | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | */ | 14 | */ |
| 15 | 15 | ||
| 16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
| 17 | #include <linux/err.h> | ||
| 17 | #include <linux/errno.h> | 18 | #include <linux/errno.h> |
| 18 | #include <linux/list.h> | 19 | #include <linux/list.h> |
| 19 | #include <linux/io.h> | 20 | #include <linux/io.h> |
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index 962c2d8dd8d9..87991d3abbab 100644 --- a/arch/powerpc/sysdev/fsl_msi.c +++ b/arch/powerpc/sysdev/fsl_msi.c | |||
| @@ -250,7 +250,7 @@ unlock: | |||
| 250 | raw_spin_unlock(&desc->lock); | 250 | raw_spin_unlock(&desc->lock); |
| 251 | } | 251 | } |
| 252 | 252 | ||
| 253 | static int fsl_of_msi_remove(struct of_device *ofdev) | 253 | static int fsl_of_msi_remove(struct platform_device *ofdev) |
| 254 | { | 254 | { |
| 255 | struct fsl_msi *msi = ofdev->dev.platform_data; | 255 | struct fsl_msi *msi = ofdev->dev.platform_data; |
| 256 | int virq, i; | 256 | int virq, i; |
| @@ -274,7 +274,7 @@ static int fsl_of_msi_remove(struct of_device *ofdev) | |||
| 274 | return 0; | 274 | return 0; |
| 275 | } | 275 | } |
| 276 | 276 | ||
| 277 | static int __devinit fsl_of_msi_probe(struct of_device *dev, | 277 | static int __devinit fsl_of_msi_probe(struct platform_device *dev, |
| 278 | const struct of_device_id *match) | 278 | const struct of_device_id *match) |
| 279 | { | 279 | { |
| 280 | struct fsl_msi *msi; | 280 | struct fsl_msi *msi; |
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index 356c6a0e1b23..209384b6e039 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c | |||
| @@ -412,6 +412,7 @@ DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P4080, quirk_fsl_pcie_header); | |||
| 412 | #endif /* CONFIG_FSL_SOC_BOOKE || CONFIG_PPC_86xx */ | 412 | #endif /* CONFIG_FSL_SOC_BOOKE || CONFIG_PPC_86xx */ |
| 413 | 413 | ||
| 414 | #if defined(CONFIG_PPC_83xx) || defined(CONFIG_PPC_MPC512x) | 414 | #if defined(CONFIG_PPC_83xx) || defined(CONFIG_PPC_MPC512x) |
| 415 | DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8308, quirk_fsl_pcie_header); | ||
| 415 | DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8314E, quirk_fsl_pcie_header); | 416 | DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8314E, quirk_fsl_pcie_header); |
| 416 | DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8314, quirk_fsl_pcie_header); | 417 | DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8314, quirk_fsl_pcie_header); |
| 417 | DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8315E, quirk_fsl_pcie_header); | 418 | DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8315E, quirk_fsl_pcie_header); |
diff --git a/arch/powerpc/sysdev/fsl_pmc.c b/arch/powerpc/sysdev/fsl_pmc.c index 9082eb921ad9..44de8559c975 100644 --- a/arch/powerpc/sysdev/fsl_pmc.c +++ b/arch/powerpc/sysdev/fsl_pmc.c | |||
| @@ -58,7 +58,8 @@ static struct platform_suspend_ops pmc_suspend_ops = { | |||
| 58 | .enter = pmc_suspend_enter, | 58 | .enter = pmc_suspend_enter, |
| 59 | }; | 59 | }; |
| 60 | 60 | ||
| 61 | static int pmc_probe(struct of_device *ofdev, const struct of_device_id *id) | 61 | static int pmc_probe(struct platform_device *ofdev, |
| 62 | const struct of_device_id *id) | ||
| 62 | { | 63 | { |
| 63 | pmc_regs = of_iomap(ofdev->dev.of_node, 0); | 64 | pmc_regs = of_iomap(ofdev->dev.of_node, 0); |
| 64 | if (!pmc_regs) | 65 | if (!pmc_regs) |
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index 30e1626b2e85..8bd86530ee25 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c | |||
| @@ -1338,7 +1338,7 @@ static inline void fsl_rio_info(struct device *dev, u32 ccsr) | |||
| 1338 | * master port with system-specific info, and registers the | 1338 | * master port with system-specific info, and registers the |
| 1339 | * master port with the RapidIO subsystem. | 1339 | * master port with the RapidIO subsystem. |
| 1340 | */ | 1340 | */ |
| 1341 | int fsl_rio_setup(struct of_device *dev) | 1341 | int fsl_rio_setup(struct platform_device *dev) |
| 1342 | { | 1342 | { |
| 1343 | struct rio_ops *ops; | 1343 | struct rio_ops *ops; |
| 1344 | struct rio_mport *port; | 1344 | struct rio_mport *port; |
| @@ -1536,7 +1536,7 @@ err_ops: | |||
| 1536 | 1536 | ||
| 1537 | /* The probe function for RapidIO peer-to-peer network. | 1537 | /* The probe function for RapidIO peer-to-peer network. |
| 1538 | */ | 1538 | */ |
| 1539 | static int __devinit fsl_of_rio_rpn_probe(struct of_device *dev, | 1539 | static int __devinit fsl_of_rio_rpn_probe(struct platform_device *dev, |
| 1540 | const struct of_device_id *match) | 1540 | const struct of_device_id *match) |
| 1541 | { | 1541 | { |
| 1542 | int rc; | 1542 | int rc; |
diff --git a/arch/powerpc/sysdev/fsl_soc.h b/arch/powerpc/sysdev/fsl_soc.h index 42381bb6cd51..53609489a62b 100644 --- a/arch/powerpc/sysdev/fsl_soc.h +++ b/arch/powerpc/sysdev/fsl_soc.h | |||
| @@ -30,6 +30,7 @@ struct platform_diu_data_ops { | |||
| 30 | void (*set_pixel_clock) (unsigned int pixclock); | 30 | void (*set_pixel_clock) (unsigned int pixclock); |
| 31 | ssize_t (*show_monitor_port) (int monitor_port, char *buf); | 31 | ssize_t (*show_monitor_port) (int monitor_port, char *buf); |
| 32 | int (*set_sysfs_monitor_port) (int val); | 32 | int (*set_sysfs_monitor_port) (int val); |
| 33 | void (*release_bootmem) (void); | ||
| 33 | }; | 34 | }; |
| 34 | 35 | ||
| 35 | extern struct platform_diu_data_ops diu_ops; | 36 | extern struct platform_diu_data_ops diu_ops; |
diff --git a/arch/powerpc/sysdev/mpc8xxx_gpio.c b/arch/powerpc/sysdev/mpc8xxx_gpio.c index 83f519655fac..2b69084d0f0c 100644 --- a/arch/powerpc/sysdev/mpc8xxx_gpio.c +++ b/arch/powerpc/sysdev/mpc8xxx_gpio.c | |||
| @@ -257,7 +257,6 @@ static void __init mpc8xxx_add_controller(struct device_node *np) | |||
| 257 | { | 257 | { |
| 258 | struct mpc8xxx_gpio_chip *mpc8xxx_gc; | 258 | struct mpc8xxx_gpio_chip *mpc8xxx_gc; |
| 259 | struct of_mm_gpio_chip *mm_gc; | 259 | struct of_mm_gpio_chip *mm_gc; |
| 260 | struct of_gpio_chip *of_gc; | ||
| 261 | struct gpio_chip *gc; | 260 | struct gpio_chip *gc; |
| 262 | unsigned hwirq; | 261 | unsigned hwirq; |
| 263 | int ret; | 262 | int ret; |
| @@ -271,11 +270,9 @@ static void __init mpc8xxx_add_controller(struct device_node *np) | |||
| 271 | spin_lock_init(&mpc8xxx_gc->lock); | 270 | spin_lock_init(&mpc8xxx_gc->lock); |
| 272 | 271 | ||
| 273 | mm_gc = &mpc8xxx_gc->mm_gc; | 272 | mm_gc = &mpc8xxx_gc->mm_gc; |
| 274 | of_gc = &mm_gc->of_gc; | 273 | gc = &mm_gc->gc; |
| 275 | gc = &of_gc->gc; | ||
| 276 | 274 | ||
| 277 | mm_gc->save_regs = mpc8xxx_gpio_save_regs; | 275 | mm_gc->save_regs = mpc8xxx_gpio_save_regs; |
| 278 | of_gc->gpio_cells = 2; | ||
| 279 | gc->ngpio = MPC8XXX_GPIO_PINS; | 276 | gc->ngpio = MPC8XXX_GPIO_PINS; |
| 280 | gc->direction_input = mpc8xxx_gpio_dir_in; | 277 | gc->direction_input = mpc8xxx_gpio_dir_in; |
| 281 | gc->direction_output = mpc8xxx_gpio_dir_out; | 278 | gc->direction_output = mpc8xxx_gpio_dir_out; |
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 20b73c025a45..7c1342618a30 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c | |||
| @@ -1636,6 +1636,24 @@ void __devinit smp_mpic_setup_cpu(int cpu) | |||
| 1636 | { | 1636 | { |
| 1637 | mpic_setup_this_cpu(); | 1637 | mpic_setup_this_cpu(); |
| 1638 | } | 1638 | } |
| 1639 | |||
| 1640 | void mpic_reset_core(int cpu) | ||
| 1641 | { | ||
| 1642 | struct mpic *mpic = mpic_primary; | ||
| 1643 | u32 pir; | ||
| 1644 | int cpuid = get_hard_smp_processor_id(cpu); | ||
| 1645 | |||
| 1646 | /* Set target bit for core reset */ | ||
| 1647 | pir = mpic_read(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT)); | ||
| 1648 | pir |= (1 << cpuid); | ||
| 1649 | mpic_write(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT), pir); | ||
| 1650 | mpic_read(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT)); | ||
| 1651 | |||
| 1652 | /* Restore target bit after reset complete */ | ||
| 1653 | pir &= ~(1 << cpuid); | ||
| 1654 | mpic_write(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT), pir); | ||
| 1655 | mpic_read(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT)); | ||
| 1656 | } | ||
| 1639 | #endif /* CONFIG_SMP */ | 1657 | #endif /* CONFIG_SMP */ |
| 1640 | 1658 | ||
| 1641 | #ifdef CONFIG_PM | 1659 | #ifdef CONFIG_PM |
diff --git a/arch/powerpc/sysdev/mpic.h b/arch/powerpc/sysdev/mpic.h index eff433c322a0..e4a6df77b8d7 100644 --- a/arch/powerpc/sysdev/mpic.h +++ b/arch/powerpc/sysdev/mpic.h | |||
| @@ -37,5 +37,6 @@ static inline int mpic_pasemi_msi_init(struct mpic *mpic) | |||
| 37 | extern int mpic_set_irq_type(unsigned int virq, unsigned int flow_type); | 37 | extern int mpic_set_irq_type(unsigned int virq, unsigned int flow_type); |
| 38 | extern void mpic_set_vector(unsigned int virq, unsigned int vector); | 38 | extern void mpic_set_vector(unsigned int virq, unsigned int vector); |
| 39 | extern int mpic_set_affinity(unsigned int irq, const struct cpumask *cpumask); | 39 | extern int mpic_set_affinity(unsigned int irq, const struct cpumask *cpumask); |
| 40 | extern void mpic_reset_core(int cpu); | ||
| 40 | 41 | ||
| 41 | #endif /* _POWERPC_SYSDEV_MPIC_H */ | 42 | #endif /* _POWERPC_SYSDEV_MPIC_H */ |
diff --git a/arch/powerpc/sysdev/mv64x60_dev.c b/arch/powerpc/sysdev/mv64x60_dev.c index 31acd3b1718b..1398bc454999 100644 --- a/arch/powerpc/sysdev/mv64x60_dev.c +++ b/arch/powerpc/sysdev/mv64x60_dev.c | |||
| @@ -20,12 +20,7 @@ | |||
| 20 | 20 | ||
| 21 | #include <asm/prom.h> | 21 | #include <asm/prom.h> |
| 22 | 22 | ||
| 23 | /* | 23 | /* These functions provide the necessary setup for the mv64x60 drivers. */ |
| 24 | * These functions provide the necessary setup for the mv64x60 drivers. | ||
| 25 | * These drivers are unusual in that they work on both the MIPS and PowerPC | ||
| 26 | * architectures. Because of that, the drivers do not support the normal | ||
| 27 | * PowerPC of_platform_bus_type. They support platform_bus_type instead. | ||
| 28 | */ | ||
| 29 | 24 | ||
| 30 | static struct of_device_id __initdata of_mv64x60_devices[] = { | 25 | static struct of_device_id __initdata of_mv64x60_devices[] = { |
| 31 | { .compatible = "marvell,mv64306-devctrl", }, | 26 | { .compatible = "marvell,mv64306-devctrl", }, |
diff --git a/arch/powerpc/sysdev/pmi.c b/arch/powerpc/sysdev/pmi.c index d07137a07d75..24a0bb955b18 100644 --- a/arch/powerpc/sysdev/pmi.c +++ b/arch/powerpc/sysdev/pmi.c | |||
| @@ -43,7 +43,7 @@ struct pmi_data { | |||
| 43 | struct mutex msg_mutex; | 43 | struct mutex msg_mutex; |
| 44 | pmi_message_t msg; | 44 | pmi_message_t msg; |
| 45 | struct completion *completion; | 45 | struct completion *completion; |
| 46 | struct of_device *dev; | 46 | struct platform_device *dev; |
| 47 | int irq; | 47 | int irq; |
| 48 | u8 __iomem *pmi_reg; | 48 | u8 __iomem *pmi_reg; |
| 49 | struct work_struct work; | 49 | struct work_struct work; |
| @@ -121,7 +121,7 @@ static void pmi_notify_handlers(struct work_struct *work) | |||
| 121 | spin_unlock(&data->handler_spinlock); | 121 | spin_unlock(&data->handler_spinlock); |
| 122 | } | 122 | } |
| 123 | 123 | ||
| 124 | static int pmi_of_probe(struct of_device *dev, | 124 | static int pmi_of_probe(struct platform_device *dev, |
| 125 | const struct of_device_id *match) | 125 | const struct of_device_id *match) |
| 126 | { | 126 | { |
| 127 | struct device_node *np = dev->dev.of_node; | 127 | struct device_node *np = dev->dev.of_node; |
| @@ -185,7 +185,7 @@ out: | |||
| 185 | return rc; | 185 | return rc; |
| 186 | } | 186 | } |
| 187 | 187 | ||
| 188 | static int pmi_of_remove(struct of_device *dev) | 188 | static int pmi_of_remove(struct platform_device *dev) |
| 189 | { | 189 | { |
| 190 | struct pmi_handler *handler, *tmp; | 190 | struct pmi_handler *handler, *tmp; |
| 191 | 191 | ||
diff --git a/arch/powerpc/sysdev/ppc4xx_gpio.c b/arch/powerpc/sysdev/ppc4xx_gpio.c index 3812fc366bec..fc65ad1b3293 100644 --- a/arch/powerpc/sysdev/ppc4xx_gpio.c +++ b/arch/powerpc/sysdev/ppc4xx_gpio.c | |||
| @@ -181,7 +181,6 @@ static int __init ppc4xx_add_gpiochips(void) | |||
| 181 | int ret; | 181 | int ret; |
| 182 | struct ppc4xx_gpio_chip *ppc4xx_gc; | 182 | struct ppc4xx_gpio_chip *ppc4xx_gc; |
| 183 | struct of_mm_gpio_chip *mm_gc; | 183 | struct of_mm_gpio_chip *mm_gc; |
| 184 | struct of_gpio_chip *of_gc; | ||
| 185 | struct gpio_chip *gc; | 184 | struct gpio_chip *gc; |
| 186 | 185 | ||
| 187 | ppc4xx_gc = kzalloc(sizeof(*ppc4xx_gc), GFP_KERNEL); | 186 | ppc4xx_gc = kzalloc(sizeof(*ppc4xx_gc), GFP_KERNEL); |
| @@ -193,10 +192,8 @@ static int __init ppc4xx_add_gpiochips(void) | |||
| 193 | spin_lock_init(&ppc4xx_gc->lock); | 192 | spin_lock_init(&ppc4xx_gc->lock); |
| 194 | 193 | ||
| 195 | mm_gc = &ppc4xx_gc->mm_gc; | 194 | mm_gc = &ppc4xx_gc->mm_gc; |
| 196 | of_gc = &mm_gc->of_gc; | 195 | gc = &mm_gc->gc; |
| 197 | gc = &of_gc->gc; | ||
| 198 | 196 | ||
| 199 | of_gc->gpio_cells = 2; | ||
| 200 | gc->ngpio = 32; | 197 | gc->ngpio = 32; |
| 201 | gc->direction_input = ppc4xx_gpio_dir_in; | 198 | gc->direction_input = ppc4xx_gpio_dir_in; |
| 202 | gc->direction_output = ppc4xx_gpio_dir_out; | 199 | gc->direction_output = ppc4xx_gpio_dir_out; |
diff --git a/arch/powerpc/sysdev/qe_lib/gpio.c b/arch/powerpc/sysdev/qe_lib/gpio.c index dc8f8d618074..36bf845df127 100644 --- a/arch/powerpc/sysdev/qe_lib/gpio.c +++ b/arch/powerpc/sysdev/qe_lib/gpio.c | |||
| @@ -138,8 +138,8 @@ struct qe_pin { | |||
| 138 | struct qe_pin *qe_pin_request(struct device_node *np, int index) | 138 | struct qe_pin *qe_pin_request(struct device_node *np, int index) |
| 139 | { | 139 | { |
| 140 | struct qe_pin *qe_pin; | 140 | struct qe_pin *qe_pin; |
| 141 | struct device_node *gc; | 141 | struct device_node *gpio_np; |
| 142 | struct of_gpio_chip *of_gc = NULL; | 142 | struct gpio_chip *gc; |
| 143 | struct of_mm_gpio_chip *mm_gc; | 143 | struct of_mm_gpio_chip *mm_gc; |
| 144 | struct qe_gpio_chip *qe_gc; | 144 | struct qe_gpio_chip *qe_gc; |
| 145 | int err; | 145 | int err; |
| @@ -155,40 +155,40 @@ struct qe_pin *qe_pin_request(struct device_node *np, int index) | |||
| 155 | } | 155 | } |
| 156 | 156 | ||
| 157 | err = of_parse_phandles_with_args(np, "gpios", "#gpio-cells", index, | 157 | err = of_parse_phandles_with_args(np, "gpios", "#gpio-cells", index, |
| 158 | &gc, &gpio_spec); | 158 | &gpio_np, &gpio_spec); |
| 159 | if (err) { | 159 | if (err) { |
| 160 | pr_debug("%s: can't parse gpios property\n", __func__); | 160 | pr_debug("%s: can't parse gpios property\n", __func__); |
| 161 | goto err0; | 161 | goto err0; |
| 162 | } | 162 | } |
| 163 | 163 | ||
| 164 | if (!of_device_is_compatible(gc, "fsl,mpc8323-qe-pario-bank")) { | 164 | if (!of_device_is_compatible(gpio_np, "fsl,mpc8323-qe-pario-bank")) { |
| 165 | pr_debug("%s: tried to get a non-qe pin\n", __func__); | 165 | pr_debug("%s: tried to get a non-qe pin\n", __func__); |
| 166 | err = -EINVAL; | 166 | err = -EINVAL; |
| 167 | goto err1; | 167 | goto err1; |
| 168 | } | 168 | } |
| 169 | 169 | ||
| 170 | of_gc = gc->data; | 170 | gc = of_node_to_gpiochip(gpio_np); |
| 171 | if (!of_gc) { | 171 | if (!gc) { |
| 172 | pr_debug("%s: gpio controller %s isn't registered\n", | 172 | pr_debug("%s: gpio controller %s isn't registered\n", |
| 173 | np->full_name, gc->full_name); | 173 | np->full_name, gpio_np->full_name); |
| 174 | err = -ENODEV; | 174 | err = -ENODEV; |
| 175 | goto err1; | 175 | goto err1; |
| 176 | } | 176 | } |
| 177 | 177 | ||
| 178 | gpio_cells = of_get_property(gc, "#gpio-cells", &size); | 178 | gpio_cells = of_get_property(gpio_np, "#gpio-cells", &size); |
| 179 | if (!gpio_cells || size != sizeof(*gpio_cells) || | 179 | if (!gpio_cells || size != sizeof(*gpio_cells) || |
| 180 | *gpio_cells != of_gc->gpio_cells) { | 180 | *gpio_cells != gc->of_gpio_n_cells) { |
| 181 | pr_debug("%s: wrong #gpio-cells for %s\n", | 181 | pr_debug("%s: wrong #gpio-cells for %s\n", |
| 182 | np->full_name, gc->full_name); | 182 | np->full_name, gpio_np->full_name); |
| 183 | err = -EINVAL; | 183 | err = -EINVAL; |
| 184 | goto err1; | 184 | goto err1; |
| 185 | } | 185 | } |
| 186 | 186 | ||
| 187 | err = of_gc->xlate(of_gc, np, gpio_spec, NULL); | 187 | err = gc->of_xlate(gc, np, gpio_spec, NULL); |
| 188 | if (err < 0) | 188 | if (err < 0) |
| 189 | goto err1; | 189 | goto err1; |
| 190 | 190 | ||
| 191 | mm_gc = to_of_mm_gpio_chip(&of_gc->gc); | 191 | mm_gc = to_of_mm_gpio_chip(gc); |
| 192 | qe_gc = to_qe_gpio_chip(mm_gc); | 192 | qe_gc = to_qe_gpio_chip(mm_gc); |
| 193 | 193 | ||
| 194 | spin_lock_irqsave(&qe_gc->lock, flags); | 194 | spin_lock_irqsave(&qe_gc->lock, flags); |
| @@ -206,7 +206,7 @@ struct qe_pin *qe_pin_request(struct device_node *np, int index) | |||
| 206 | if (!err) | 206 | if (!err) |
| 207 | return qe_pin; | 207 | return qe_pin; |
| 208 | err1: | 208 | err1: |
| 209 | of_node_put(gc); | 209 | of_node_put(gpio_np); |
| 210 | err0: | 210 | err0: |
| 211 | kfree(qe_pin); | 211 | kfree(qe_pin); |
| 212 | pr_debug("%s failed with status %d\n", __func__, err); | 212 | pr_debug("%s failed with status %d\n", __func__, err); |
| @@ -307,7 +307,6 @@ static int __init qe_add_gpiochips(void) | |||
| 307 | int ret; | 307 | int ret; |
| 308 | struct qe_gpio_chip *qe_gc; | 308 | struct qe_gpio_chip *qe_gc; |
| 309 | struct of_mm_gpio_chip *mm_gc; | 309 | struct of_mm_gpio_chip *mm_gc; |
| 310 | struct of_gpio_chip *of_gc; | ||
| 311 | struct gpio_chip *gc; | 310 | struct gpio_chip *gc; |
| 312 | 311 | ||
| 313 | qe_gc = kzalloc(sizeof(*qe_gc), GFP_KERNEL); | 312 | qe_gc = kzalloc(sizeof(*qe_gc), GFP_KERNEL); |
| @@ -319,11 +318,9 @@ static int __init qe_add_gpiochips(void) | |||
| 319 | spin_lock_init(&qe_gc->lock); | 318 | spin_lock_init(&qe_gc->lock); |
| 320 | 319 | ||
| 321 | mm_gc = &qe_gc->mm_gc; | 320 | mm_gc = &qe_gc->mm_gc; |
| 322 | of_gc = &mm_gc->of_gc; | 321 | gc = &mm_gc->gc; |
| 323 | gc = &of_gc->gc; | ||
| 324 | 322 | ||
| 325 | mm_gc->save_regs = qe_gpio_save_regs; | 323 | mm_gc->save_regs = qe_gpio_save_regs; |
| 326 | of_gc->gpio_cells = 2; | ||
| 327 | gc->ngpio = QE_PIO_PINS; | 324 | gc->ngpio = QE_PIO_PINS; |
| 328 | gc->direction_input = qe_gpio_dir_in; | 325 | gc->direction_input = qe_gpio_dir_in; |
| 329 | gc->direction_output = qe_gpio_dir_out; | 326 | gc->direction_output = qe_gpio_dir_out; |
diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c index 093e0ae1a941..3da8014931c9 100644 --- a/arch/powerpc/sysdev/qe_lib/qe.c +++ b/arch/powerpc/sysdev/qe_lib/qe.c | |||
| @@ -651,14 +651,15 @@ unsigned int qe_get_num_of_snums(void) | |||
| 651 | EXPORT_SYMBOL(qe_get_num_of_snums); | 651 | EXPORT_SYMBOL(qe_get_num_of_snums); |
| 652 | 652 | ||
| 653 | #if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC_85xx) | 653 | #if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC_85xx) |
| 654 | static int qe_resume(struct of_device *ofdev) | 654 | static int qe_resume(struct platform_device *ofdev) |
| 655 | { | 655 | { |
| 656 | if (!qe_alive_during_sleep()) | 656 | if (!qe_alive_during_sleep()) |
| 657 | qe_reset(); | 657 | qe_reset(); |
| 658 | return 0; | 658 | return 0; |
| 659 | } | 659 | } |
| 660 | 660 | ||
| 661 | static int qe_probe(struct of_device *ofdev, const struct of_device_id *id) | 661 | static int qe_probe(struct platform_device *ofdev, |
| 662 | const struct of_device_id *id) | ||
| 662 | { | 663 | { |
| 663 | return 0; | 664 | return 0; |
| 664 | } | 665 | } |
diff --git a/arch/powerpc/sysdev/simple_gpio.c b/arch/powerpc/sysdev/simple_gpio.c index d5fb173e588c..b6defda5ccc9 100644 --- a/arch/powerpc/sysdev/simple_gpio.c +++ b/arch/powerpc/sysdev/simple_gpio.c | |||
| @@ -91,7 +91,6 @@ static int __init u8_simple_gpiochip_add(struct device_node *np) | |||
| 91 | int ret; | 91 | int ret; |
| 92 | struct u8_gpio_chip *u8_gc; | 92 | struct u8_gpio_chip *u8_gc; |
| 93 | struct of_mm_gpio_chip *mm_gc; | 93 | struct of_mm_gpio_chip *mm_gc; |
| 94 | struct of_gpio_chip *of_gc; | ||
| 95 | struct gpio_chip *gc; | 94 | struct gpio_chip *gc; |
| 96 | 95 | ||
| 97 | u8_gc = kzalloc(sizeof(*u8_gc), GFP_KERNEL); | 96 | u8_gc = kzalloc(sizeof(*u8_gc), GFP_KERNEL); |
| @@ -101,11 +100,9 @@ static int __init u8_simple_gpiochip_add(struct device_node *np) | |||
| 101 | spin_lock_init(&u8_gc->lock); | 100 | spin_lock_init(&u8_gc->lock); |
| 102 | 101 | ||
| 103 | mm_gc = &u8_gc->mm_gc; | 102 | mm_gc = &u8_gc->mm_gc; |
| 104 | of_gc = &mm_gc->of_gc; | 103 | gc = &mm_gc->gc; |
| 105 | gc = &of_gc->gc; | ||
| 106 | 104 | ||
| 107 | mm_gc->save_regs = u8_gpio_save_regs; | 105 | mm_gc->save_regs = u8_gpio_save_regs; |
| 108 | of_gc->gpio_cells = 2; | ||
| 109 | gc->ngpio = 8; | 106 | gc->ngpio = 8; |
| 110 | gc->direction_input = u8_gpio_dir_in; | 107 | gc->direction_input = u8_gpio_dir_in; |
| 111 | gc->direction_output = u8_gpio_dir_out; | 108 | gc->direction_output = u8_gpio_dir_out; |
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 8bad7d5f32af..0554445200bf 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c | |||
| @@ -155,6 +155,9 @@ static int do_spu_cmd(void); | |||
| 155 | #ifdef CONFIG_44x | 155 | #ifdef CONFIG_44x |
| 156 | static void dump_tlb_44x(void); | 156 | static void dump_tlb_44x(void); |
| 157 | #endif | 157 | #endif |
| 158 | #ifdef CONFIG_PPC_BOOK3E | ||
| 159 | static void dump_tlb_book3e(void); | ||
| 160 | #endif | ||
| 158 | 161 | ||
| 159 | static int xmon_no_auto_backtrace; | 162 | static int xmon_no_auto_backtrace; |
| 160 | 163 | ||
| @@ -888,6 +891,11 @@ cmds(struct pt_regs *excp) | |||
| 888 | dump_tlb_44x(); | 891 | dump_tlb_44x(); |
| 889 | break; | 892 | break; |
| 890 | #endif | 893 | #endif |
| 894 | #ifdef CONFIG_PPC_BOOK3E | ||
| 895 | case 'u': | ||
| 896 | dump_tlb_book3e(); | ||
| 897 | break; | ||
| 898 | #endif | ||
| 891 | default: | 899 | default: |
| 892 | printf("Unrecognized command: "); | 900 | printf("Unrecognized command: "); |
| 893 | do { | 901 | do { |
| @@ -2701,6 +2709,150 @@ static void dump_tlb_44x(void) | |||
| 2701 | } | 2709 | } |
| 2702 | #endif /* CONFIG_44x */ | 2710 | #endif /* CONFIG_44x */ |
| 2703 | 2711 | ||
| 2712 | #ifdef CONFIG_PPC_BOOK3E | ||
| 2713 | static void dump_tlb_book3e(void) | ||
| 2714 | { | ||
| 2715 | u32 mmucfg, pidmask, lpidmask; | ||
| 2716 | u64 ramask; | ||
| 2717 | int i, tlb, ntlbs, pidsz, lpidsz, rasz, lrat = 0; | ||
| 2718 | int mmu_version; | ||
| 2719 | static const char *pgsz_names[] = { | ||
| 2720 | " 1K", | ||
| 2721 | " 2K", | ||
| 2722 | " 4K", | ||
| 2723 | " 8K", | ||
| 2724 | " 16K", | ||
| 2725 | " 32K", | ||
| 2726 | " 64K", | ||
| 2727 | "128K", | ||
| 2728 | "256K", | ||
| 2729 | "512K", | ||
| 2730 | " 1M", | ||
| 2731 | " 2M", | ||
| 2732 | " 4M", | ||
| 2733 | " 8M", | ||
| 2734 | " 16M", | ||
| 2735 | " 32M", | ||
| 2736 | " 64M", | ||
| 2737 | "128M", | ||
| 2738 | "256M", | ||
| 2739 | "512M", | ||
| 2740 | " 1G", | ||
| 2741 | " 2G", | ||
| 2742 | " 4G", | ||
| 2743 | " 8G", | ||
| 2744 | " 16G", | ||
| 2745 | " 32G", | ||
| 2746 | " 64G", | ||
| 2747 | "128G", | ||
| 2748 | "256G", | ||
| 2749 | "512G", | ||
| 2750 | " 1T", | ||
| 2751 | " 2T", | ||
| 2752 | }; | ||
| 2753 | |||
| 2754 | /* Gather some infos about the MMU */ | ||
| 2755 | mmucfg = mfspr(SPRN_MMUCFG); | ||
| 2756 | mmu_version = (mmucfg & 3) + 1; | ||
| 2757 | ntlbs = ((mmucfg >> 2) & 3) + 1; | ||
| 2758 | pidsz = ((mmucfg >> 6) & 0x1f) + 1; | ||
| 2759 | lpidsz = (mmucfg >> 24) & 0xf; | ||
| 2760 | rasz = (mmucfg >> 16) & 0x7f; | ||
| 2761 | if ((mmu_version > 1) && (mmucfg & 0x10000)) | ||
| 2762 | lrat = 1; | ||
| 2763 | printf("Book3E MMU MAV=%d.0,%d TLBs,%d-bit PID,%d-bit LPID,%d-bit RA\n", | ||
| 2764 | mmu_version, ntlbs, pidsz, lpidsz, rasz); | ||
| 2765 | pidmask = (1ul << pidsz) - 1; | ||
| 2766 | lpidmask = (1ul << lpidsz) - 1; | ||
| 2767 | ramask = (1ull << rasz) - 1; | ||
| 2768 | |||
| 2769 | for (tlb = 0; tlb < ntlbs; tlb++) { | ||
| 2770 | u32 tlbcfg; | ||
| 2771 | int nent, assoc, new_cc = 1; | ||
| 2772 | printf("TLB %d:\n------\n", tlb); | ||
| 2773 | switch(tlb) { | ||
| 2774 | case 0: | ||
| 2775 | tlbcfg = mfspr(SPRN_TLB0CFG); | ||
| 2776 | break; | ||
| 2777 | case 1: | ||
| 2778 | tlbcfg = mfspr(SPRN_TLB1CFG); | ||
| 2779 | break; | ||
| 2780 | case 2: | ||
| 2781 | tlbcfg = mfspr(SPRN_TLB2CFG); | ||
| 2782 | break; | ||
| 2783 | case 3: | ||
| 2784 | tlbcfg = mfspr(SPRN_TLB3CFG); | ||
| 2785 | break; | ||
| 2786 | default: | ||
| 2787 | printf("Unsupported TLB number !\n"); | ||
| 2788 | continue; | ||
| 2789 | } | ||
| 2790 | nent = tlbcfg & 0xfff; | ||
| 2791 | assoc = (tlbcfg >> 24) & 0xff; | ||
| 2792 | for (i = 0; i < nent; i++) { | ||
| 2793 | u32 mas0 = MAS0_TLBSEL(tlb); | ||
| 2794 | u32 mas1 = MAS1_TSIZE(BOOK3E_PAGESZ_4K); | ||
| 2795 | u64 mas2 = 0; | ||
| 2796 | u64 mas7_mas3; | ||
| 2797 | int esel = i, cc = i; | ||
| 2798 | |||
| 2799 | if (assoc != 0) { | ||
| 2800 | cc = i / assoc; | ||
| 2801 | esel = i % assoc; | ||
| 2802 | mas2 = cc * 0x1000; | ||
| 2803 | } | ||
| 2804 | |||
| 2805 | mas0 |= MAS0_ESEL(esel); | ||
| 2806 | mtspr(SPRN_MAS0, mas0); | ||
| 2807 | mtspr(SPRN_MAS1, mas1); | ||
| 2808 | mtspr(SPRN_MAS2, mas2); | ||
| 2809 | asm volatile("tlbre 0,0,0" : : : "memory"); | ||
| 2810 | mas1 = mfspr(SPRN_MAS1); | ||
| 2811 | mas2 = mfspr(SPRN_MAS2); | ||
| 2812 | mas7_mas3 = mfspr(SPRN_MAS7_MAS3); | ||
| 2813 | if (assoc && (i % assoc) == 0) | ||
| 2814 | new_cc = 1; | ||
| 2815 | if (!(mas1 & MAS1_VALID)) | ||
| 2816 | continue; | ||
| 2817 | if (assoc == 0) | ||
| 2818 | printf("%04x- ", i); | ||
| 2819 | else if (new_cc) | ||
| 2820 | printf("%04x-%c", cc, 'A' + esel); | ||
| 2821 | else | ||
| 2822 | printf(" |%c", 'A' + esel); | ||
| 2823 | new_cc = 0; | ||
| 2824 | printf(" %016llx %04x %s %c%c AS%c", | ||
| 2825 | mas2 & ~0x3ffull, | ||
| 2826 | (mas1 >> 16) & 0x3fff, | ||
| 2827 | pgsz_names[(mas1 >> 7) & 0x1f], | ||
| 2828 | mas1 & MAS1_IND ? 'I' : ' ', | ||
| 2829 | mas1 & MAS1_IPROT ? 'P' : ' ', | ||
| 2830 | mas1 & MAS1_TS ? '1' : '0'); | ||
| 2831 | printf(" %c%c%c%c%c%c%c", | ||
| 2832 | mas2 & MAS2_X0 ? 'a' : ' ', | ||
| 2833 | mas2 & MAS2_X1 ? 'v' : ' ', | ||
| 2834 | mas2 & MAS2_W ? 'w' : ' ', | ||
| 2835 | mas2 & MAS2_I ? 'i' : ' ', | ||
| 2836 | mas2 & MAS2_M ? 'm' : ' ', | ||
| 2837 | mas2 & MAS2_G ? 'g' : ' ', | ||
| 2838 | mas2 & MAS2_E ? 'e' : ' '); | ||
| 2839 | printf(" %016llx", mas7_mas3 & ramask & ~0x7ffull); | ||
| 2840 | if (mas1 & MAS1_IND) | ||
| 2841 | printf(" %s\n", | ||
| 2842 | pgsz_names[(mas7_mas3 >> 1) & 0x1f]); | ||
| 2843 | else | ||
| 2844 | printf(" U%c%c%c S%c%c%c\n", | ||
| 2845 | mas7_mas3 & MAS3_UX ? 'x' : ' ', | ||
| 2846 | mas7_mas3 & MAS3_UW ? 'w' : ' ', | ||
| 2847 | mas7_mas3 & MAS3_UR ? 'r' : ' ', | ||
| 2848 | mas7_mas3 & MAS3_SX ? 'x' : ' ', | ||
| 2849 | mas7_mas3 & MAS3_SW ? 'w' : ' ', | ||
| 2850 | mas7_mas3 & MAS3_SR ? 'r' : ' '); | ||
| 2851 | } | ||
| 2852 | } | ||
| 2853 | } | ||
| 2854 | #endif /* CONFIG_PPC_BOOK3E */ | ||
| 2855 | |||
| 2704 | static void xmon_init(int enable) | 2856 | static void xmon_init(int enable) |
| 2705 | { | 2857 | { |
| 2706 | #ifdef CONFIG_PPC_ISERIES | 2858 | #ifdef CONFIG_PPC_ISERIES |
