diff options
137 files changed, 8141 insertions, 1065 deletions
diff --git a/Documentation/powerpc/dts-bindings/fsl/diu.txt b/Documentation/powerpc/dts-bindings/fsl/diu.txt index deb35de70988..b66cb6d31d69 100644 --- a/Documentation/powerpc/dts-bindings/fsl/diu.txt +++ b/Documentation/powerpc/dts-bindings/fsl/diu.txt | |||
| @@ -4,10 +4,17 @@ The Freescale DIU is a LCD controller, with proper hardware, it can also | |||
| 4 | drive DVI monitors. | 4 | drive DVI monitors. |
| 5 | 5 | ||
| 6 | Required properties: | 6 | Required properties: |
| 7 | - compatible : should be "fsl-diu". | 7 | - compatible : should be "fsl,diu" or "fsl,mpc5121-diu". |
| 8 | - reg : should contain at least address and length of the DIU register | 8 | - reg : should contain at least address and length of the DIU register |
| 9 | set. | 9 | set. |
| 10 | - Interrupts : one DIU interrupt should be describe here. | 10 | - interrupts : one DIU interrupt should be described here. |
| 11 | - interrupt-parent : the phandle for the interrupt controller that | ||
| 12 | services interrupts for this device. | ||
| 13 | |||
| 14 | Optional properties: | ||
| 15 | - edid : verbatim EDID data block describing attached display. | ||
| 16 | Data from the detailed timing descriptor will be used to | ||
| 17 | program the display controller. | ||
| 11 | 18 | ||
| 12 | Example (MPC8610HPCD): | 19 | Example (MPC8610HPCD): |
| 13 | display@2c000 { | 20 | display@2c000 { |
| @@ -16,3 +23,12 @@ Example (MPC8610HPCD): | |||
| 16 | interrupts = <72 2>; | 23 | interrupts = <72 2>; |
| 17 | interrupt-parent = <&mpic>; | 24 | interrupt-parent = <&mpic>; |
| 18 | }; | 25 | }; |
| 26 | |||
| 27 | Example for MPC5121: | ||
| 28 | display@2100 { | ||
| 29 | compatible = "fsl,mpc5121-diu"; | ||
| 30 | reg = <0x2100 0x100>; | ||
| 31 | interrupts = <64 0x8>; | ||
| 32 | interrupt-parent = <&ipic>; | ||
| 33 | edid = [edid-data]; | ||
| 34 | }; | ||
diff --git a/Documentation/powerpc/dts-bindings/fsl/i2c.txt b/Documentation/powerpc/dts-bindings/fsl/i2c.txt index 50da20310585..1eacd6b20ed5 100644 --- a/Documentation/powerpc/dts-bindings/fsl/i2c.txt +++ b/Documentation/powerpc/dts-bindings/fsl/i2c.txt | |||
| @@ -20,6 +20,7 @@ Recommended properties : | |||
| 20 | - fsl,preserve-clocking : boolean; if defined, the clock settings | 20 | - fsl,preserve-clocking : boolean; if defined, the clock settings |
| 21 | from the bootloader are preserved (not touched). | 21 | from the bootloader are preserved (not touched). |
| 22 | - clock-frequency : desired I2C bus clock frequency in Hz. | 22 | - clock-frequency : desired I2C bus clock frequency in Hz. |
| 23 | - fsl,timeout : I2C bus timeout in microseconds. | ||
| 23 | 24 | ||
| 24 | Examples : | 25 | Examples : |
| 25 | 26 | ||
| @@ -59,4 +60,5 @@ Examples : | |||
| 59 | interrupts = <43 2>; | 60 | interrupts = <43 2>; |
| 60 | interrupt-parent = <&mpic>; | 61 | interrupt-parent = <&mpic>; |
| 61 | clock-frequency = <400000>; | 62 | clock-frequency = <400000>; |
| 63 | fsl,timeout = <10000>; | ||
| 62 | }; | 64 | }; |
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 2031a2846865..e4545f85ee9f 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
| @@ -141,6 +141,7 @@ config PPC | |||
| 141 | select GENERIC_ATOMIC64 if PPC32 | 141 | select GENERIC_ATOMIC64 if PPC32 |
| 142 | select HAVE_PERF_EVENTS | 142 | select HAVE_PERF_EVENTS |
| 143 | select HAVE_REGS_AND_STACK_ACCESS_API | 143 | select HAVE_REGS_AND_STACK_ACCESS_API |
| 144 | select HAVE_HW_BREAKPOINT if PERF_EVENTS && PPC_BOOK3S_64 | ||
| 144 | 145 | ||
| 145 | config EARLY_PRINTK | 146 | config EARLY_PRINTK |
| 146 | bool | 147 | bool |
| @@ -218,7 +219,7 @@ config ARCH_HIBERNATION_POSSIBLE | |||
| 218 | config ARCH_SUSPEND_POSSIBLE | 219 | config ARCH_SUSPEND_POSSIBLE |
| 219 | def_bool y | 220 | def_bool y |
| 220 | depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200 || PPC_83xx || \ | 221 | depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200 || PPC_83xx || \ |
| 221 | PPC_85xx || PPC_86xx | 222 | PPC_85xx || PPC_86xx || PPC_PSERIES |
| 222 | 223 | ||
| 223 | config PPC_DCR_NATIVE | 224 | config PPC_DCR_NATIVE |
| 224 | bool | 225 | bool |
| @@ -351,7 +352,7 @@ config ARCH_ENABLE_MEMORY_HOTREMOVE | |||
| 351 | 352 | ||
| 352 | config KEXEC | 353 | config KEXEC |
| 353 | bool "kexec system call (EXPERIMENTAL)" | 354 | bool "kexec system call (EXPERIMENTAL)" |
| 354 | depends on (PPC_BOOK3S || (FSL_BOOKE && !SMP)) && EXPERIMENTAL | 355 | depends on (PPC_BOOK3S || FSL_BOOKE) && EXPERIMENTAL |
| 355 | help | 356 | help |
| 356 | kexec is a system call that implements the ability to shutdown your | 357 | 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 | 358 | current kernel, and to start another kernel. It is like a reboot |
| @@ -368,8 +369,8 @@ config KEXEC | |||
| 368 | 369 | ||
| 369 | config CRASH_DUMP | 370 | config CRASH_DUMP |
| 370 | bool "Build a kdump crash kernel" | 371 | bool "Build a kdump crash kernel" |
| 371 | depends on PPC64 || 6xx | 372 | depends on PPC64 || 6xx || FSL_BOOKE |
| 372 | select RELOCATABLE if PPC64 | 373 | select RELOCATABLE if PPC64 || FSL_BOOKE |
| 373 | help | 374 | help |
| 374 | Build a kernel suitable for use as a kdump capture kernel. | 375 | Build a kernel suitable for use as a kdump capture kernel. |
| 375 | The same kernel binary can be used as production kernel and dump | 376 | The same kernel binary can be used as production kernel and dump |
| @@ -668,7 +669,7 @@ config NEED_SG_DMA_LENGTH | |||
| 668 | 669 | ||
| 669 | config GENERIC_ISA_DMA | 670 | config GENERIC_ISA_DMA |
| 670 | bool | 671 | bool |
| 671 | depends on PPC64 || POWER4 || 6xx && !CPM2 | 672 | depends on ISA_DMA_API |
| 672 | default y | 673 | default y |
| 673 | 674 | ||
| 674 | config PPC_INDIRECT_PCI | 675 | config PPC_INDIRECT_PCI |
| @@ -897,7 +898,7 @@ config KERNEL_START_BOOL | |||
| 897 | config KERNEL_START | 898 | config KERNEL_START |
| 898 | hex "Virtual address of kernel base" if KERNEL_START_BOOL | 899 | hex "Virtual address of kernel base" if KERNEL_START_BOOL |
| 899 | default PAGE_OFFSET if PAGE_OFFSET_BOOL | 900 | default PAGE_OFFSET if PAGE_OFFSET_BOOL |
| 900 | default "0xc2000000" if CRASH_DUMP | 901 | default "0xc2000000" if CRASH_DUMP && !RELOCATABLE |
| 901 | default "0xc0000000" | 902 | default "0xc0000000" |
| 902 | 903 | ||
| 903 | config PHYSICAL_START_BOOL | 904 | config PHYSICAL_START_BOOL |
| @@ -910,7 +911,7 @@ config PHYSICAL_START_BOOL | |||
| 910 | 911 | ||
| 911 | config PHYSICAL_START | 912 | config PHYSICAL_START |
| 912 | hex "Physical address where the kernel is loaded" if PHYSICAL_START_BOOL | 913 | hex "Physical address where the kernel is loaded" if PHYSICAL_START_BOOL |
| 913 | default "0x02000000" if PPC_STD_MMU && CRASH_DUMP | 914 | default "0x02000000" if PPC_STD_MMU && CRASH_DUMP && !RELOCATABLE |
| 914 | default "0x00000000" | 915 | default "0x00000000" |
| 915 | 916 | ||
| 916 | config PHYSICAL_ALIGN | 917 | config PHYSICAL_ALIGN |
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/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/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/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/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/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/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..3033c1b30745 100644 --- a/arch/powerpc/include/asm/topology.h +++ b/arch/powerpc/include/asm/topology.h | |||
| @@ -87,6 +87,9 @@ static inline int pcibus_to_node(struct pci_bus *bus) | |||
| 87 | .balance_interval = 1, \ | 87 | .balance_interval = 1, \ |
| 88 | } | 88 | } |
| 89 | 89 | ||
| 90 | extern int __node_distance(int, int); | ||
| 91 | #define node_distance(a, b) __node_distance(a, b) | ||
| 92 | |||
| 90 | extern void __init dump_numa_cpu_topology(void); | 93 | extern void __init dump_numa_cpu_topology(void); |
| 91 | 94 | ||
| 92 | extern int sysfs_add_device_to_node(struct sys_device *dev, int nid); | 95 | extern 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..77d831a1cc32 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile | |||
| @@ -34,9 +34,10 @@ 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 |
| @@ -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/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/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..8f96d3198905 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c | |||
| @@ -64,6 +64,8 @@ | |||
| 64 | #include <asm/ptrace.h> | 64 | #include <asm/ptrace.h> |
| 65 | #include <asm/machdep.h> | 65 | #include <asm/machdep.h> |
| 66 | #include <asm/udbg.h> | 66 | #include <asm/udbg.h> |
| 67 | #include <asm/dbell.h> | ||
| 68 | |||
| 67 | #ifdef CONFIG_PPC64 | 69 | #ifdef CONFIG_PPC64 |
| 68 | #include <asm/paca.h> | 70 | #include <asm/paca.h> |
| 69 | #include <asm/firmware.h> | 71 | #include <asm/firmware.h> |
| @@ -153,14 +155,28 @@ notrace void raw_local_irq_restore(unsigned long en) | |||
| 153 | if (get_hard_enabled()) | 155 | if (get_hard_enabled()) |
| 154 | return; | 156 | return; |
| 155 | 157 | ||
| 158 | #if defined(CONFIG_BOOKE) && defined(CONFIG_SMP) | ||
| 159 | /* Check for pending doorbell interrupts and resend to ourself */ | ||
| 160 | doorbell_check_self(); | ||
| 161 | #endif | ||
| 162 | |||
| 156 | /* | 163 | /* |
| 157 | * Need to hard-enable interrupts here. Since currently disabled, | 164 | * Need to hard-enable interrupts here. Since currently disabled, |
| 158 | * no need to take further asm precautions against preemption; but | 165 | * no need to take further asm precautions against preemption; but |
| 159 | * use local_paca instead of get_paca() to avoid preemption checking. | 166 | * use local_paca instead of get_paca() to avoid preemption checking. |
| 160 | */ | 167 | */ |
| 161 | local_paca->hard_enabled = en; | 168 | local_paca->hard_enabled = en; |
| 169 | |||
| 170 | #ifndef CONFIG_BOOKE | ||
| 171 | /* On server, re-trigger the decrementer if it went negative since | ||
| 172 | * some processors only trigger on edge transitions of the sign bit. | ||
| 173 | * | ||
| 174 | * BookE has a level sensitive decrementer (latches in TSR) so we | ||
| 175 | * don't need that | ||
| 176 | */ | ||
| 162 | if ((int)mfspr(SPRN_DEC) < 0) | 177 | if ((int)mfspr(SPRN_DEC) < 0) |
| 163 | mtspr(SPRN_DEC, 1); | 178 | mtspr(SPRN_DEC, 1); |
| 179 | #endif /* CONFIG_BOOKE */ | ||
| 164 | 180 | ||
| 165 | /* | 181 | /* |
| 166 | * Force the delivery of pending soft-disabled interrupts on PS3. | 182 | * Force the delivery of pending soft-disabled interrupts on PS3. |
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/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/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/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..70decd8068ca 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; |
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..e1c5cd6650b1 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, |
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_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_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/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/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/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/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/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/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..79bd3e89dbaf 100644 --- a/arch/powerpc/platforms/powermac/feature.c +++ b/arch/powerpc/platforms/powermac/feature.c | |||
| @@ -2191,7 +2191,11 @@ static struct pmac_mb_def pmac_mb_defs[] = { | |||
| 2191 | PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, | 2191 | PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, |
| 2192 | PMAC_MB_MAY_SLEEP, | 2192 | PMAC_MB_MAY_SLEEP, |
| 2193 | }, | 2193 | }, |
| 2194 | { "iMac,1", "iMac (first generation)", | 2194 | { "PowerMac10,2", "Mac mini (Late 2005)", |
| 2195 | PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, | ||
| 2196 | PMAC_MB_MAY_SLEEP, | ||
| 2197 | }, | ||
| 2198 | { "iMac,1", "iMac (first generation)", | ||
| 2195 | PMAC_TYPE_ORIG_IMAC, paddington_features, | 2199 | PMAC_TYPE_ORIG_IMAC, paddington_features, |
| 2196 | 0 | 2200 | 0 |
| 2197 | }, | 2201 | }, |
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/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_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/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/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 |
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index 35cca4c7fb18..fa27d1676ee5 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c | |||
| @@ -194,7 +194,7 @@ static int __init hvc_console_setup(struct console *co, char *options) | |||
| 194 | return 0; | 194 | return 0; |
| 195 | } | 195 | } |
| 196 | 196 | ||
| 197 | static struct console hvc_con_driver = { | 197 | static struct console hvc_console = { |
| 198 | .name = "hvc", | 198 | .name = "hvc", |
| 199 | .write = hvc_console_print, | 199 | .write = hvc_console_print, |
| 200 | .device = hvc_console_device, | 200 | .device = hvc_console_device, |
| @@ -220,7 +220,7 @@ static struct console hvc_con_driver = { | |||
| 220 | */ | 220 | */ |
| 221 | static int __init hvc_console_init(void) | 221 | static int __init hvc_console_init(void) |
| 222 | { | 222 | { |
| 223 | register_console(&hvc_con_driver); | 223 | register_console(&hvc_console); |
| 224 | return 0; | 224 | return 0; |
| 225 | } | 225 | } |
| 226 | console_initcall(hvc_console_init); | 226 | console_initcall(hvc_console_init); |
| @@ -276,8 +276,8 @@ int hvc_instantiate(uint32_t vtermno, int index, const struct hv_ops *ops) | |||
| 276 | * now (setup won't fail at this point). It's ok to just | 276 | * now (setup won't fail at this point). It's ok to just |
| 277 | * call register again if previously .setup failed. | 277 | * call register again if previously .setup failed. |
| 278 | */ | 278 | */ |
| 279 | if (index == hvc_con_driver.index) | 279 | if (index == hvc_console.index) |
| 280 | register_console(&hvc_con_driver); | 280 | register_console(&hvc_console); |
| 281 | 281 | ||
| 282 | return 0; | 282 | return 0; |
| 283 | } | 283 | } |
| @@ -641,7 +641,7 @@ int hvc_poll(struct hvc_struct *hp) | |||
| 641 | } | 641 | } |
| 642 | for (i = 0; i < n; ++i) { | 642 | for (i = 0; i < n; ++i) { |
| 643 | #ifdef CONFIG_MAGIC_SYSRQ | 643 | #ifdef CONFIG_MAGIC_SYSRQ |
| 644 | if (hp->index == hvc_con_driver.index) { | 644 | if (hp->index == hvc_console.index) { |
| 645 | /* Handle the SysRq Hack */ | 645 | /* Handle the SysRq Hack */ |
| 646 | /* XXX should support a sequence */ | 646 | /* XXX should support a sequence */ |
| 647 | if (buf[i] == '\x0f') { /* ^O */ | 647 | if (buf[i] == '\x0f') { /* ^O */ |
| @@ -909,7 +909,7 @@ static void __exit hvc_exit(void) | |||
| 909 | tty_unregister_driver(hvc_driver); | 909 | tty_unregister_driver(hvc_driver); |
| 910 | /* return tty_struct instances allocated in hvc_init(). */ | 910 | /* return tty_struct instances allocated in hvc_init(). */ |
| 911 | put_tty_driver(hvc_driver); | 911 | put_tty_driver(hvc_driver); |
| 912 | unregister_console(&hvc_con_driver); | 912 | unregister_console(&hvc_console); |
| 913 | } | 913 | } |
| 914 | } | 914 | } |
| 915 | module_exit(hvc_exit); | 915 | module_exit(hvc_exit); |
diff --git a/drivers/char/hvsi.c b/drivers/char/hvsi.c index d4b14ff1c4c1..1f4b6de65a2d 100644 --- a/drivers/char/hvsi.c +++ b/drivers/char/hvsi.c | |||
| @@ -1255,7 +1255,7 @@ static int __init hvsi_console_setup(struct console *console, char *options) | |||
| 1255 | return 0; | 1255 | return 0; |
| 1256 | } | 1256 | } |
| 1257 | 1257 | ||
| 1258 | static struct console hvsi_con_driver = { | 1258 | static struct console hvsi_console = { |
| 1259 | .name = "hvsi", | 1259 | .name = "hvsi", |
| 1260 | .write = hvsi_console_print, | 1260 | .write = hvsi_console_print, |
| 1261 | .device = hvsi_console_device, | 1261 | .device = hvsi_console_device, |
| @@ -1308,7 +1308,7 @@ static int __init hvsi_console_init(void) | |||
| 1308 | } | 1308 | } |
| 1309 | 1309 | ||
| 1310 | if (hvsi_count) | 1310 | if (hvsi_count) |
| 1311 | register_console(&hvsi_con_driver); | 1311 | register_console(&hvsi_console); |
| 1312 | return 0; | 1312 | return 0; |
| 1313 | } | 1313 | } |
| 1314 | console_initcall(hvsi_console_init); | 1314 | console_initcall(hvsi_console_init); |
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index df00eb1f11f9..54247d475fc3 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c | |||
| @@ -63,6 +63,7 @@ struct mpc_i2c { | |||
| 63 | wait_queue_head_t queue; | 63 | wait_queue_head_t queue; |
| 64 | struct i2c_adapter adap; | 64 | struct i2c_adapter adap; |
| 65 | int irq; | 65 | int irq; |
| 66 | u32 real_clk; | ||
| 66 | }; | 67 | }; |
| 67 | 68 | ||
| 68 | struct mpc_i2c_divider { | 69 | struct mpc_i2c_divider { |
| @@ -96,20 +97,23 @@ static irqreturn_t mpc_i2c_isr(int irq, void *dev_id) | |||
| 96 | /* Sometimes 9th clock pulse isn't generated, and slave doesn't release | 97 | /* Sometimes 9th clock pulse isn't generated, and slave doesn't release |
| 97 | * the bus, because it wants to send ACK. | 98 | * the bus, because it wants to send ACK. |
| 98 | * Following sequence of enabling/disabling and sending start/stop generates | 99 | * Following sequence of enabling/disabling and sending start/stop generates |
| 99 | * the pulse, so it's all OK. | 100 | * the 9 pulses, so it's all OK. |
| 100 | */ | 101 | */ |
| 101 | static void mpc_i2c_fixup(struct mpc_i2c *i2c) | 102 | static void mpc_i2c_fixup(struct mpc_i2c *i2c) |
| 102 | { | 103 | { |
| 103 | writeccr(i2c, 0); | 104 | int k; |
| 104 | udelay(30); | 105 | u32 delay_val = 1000000 / i2c->real_clk + 1; |
| 105 | writeccr(i2c, CCR_MEN); | 106 | |
| 106 | udelay(30); | 107 | if (delay_val < 2) |
| 107 | writeccr(i2c, CCR_MSTA | CCR_MTX); | 108 | delay_val = 2; |
| 108 | udelay(30); | 109 | |
| 109 | writeccr(i2c, CCR_MSTA | CCR_MTX | CCR_MEN); | 110 | for (k = 9; k; k--) { |
| 110 | udelay(30); | 111 | writeccr(i2c, 0); |
| 111 | writeccr(i2c, CCR_MEN); | 112 | writeccr(i2c, CCR_MSTA | CCR_MTX | CCR_MEN); |
| 112 | udelay(30); | 113 | udelay(delay_val); |
| 114 | writeccr(i2c, CCR_MEN); | ||
| 115 | udelay(delay_val << 1); | ||
| 116 | } | ||
| 113 | } | 117 | } |
| 114 | 118 | ||
| 115 | static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing) | 119 | static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing) |
| @@ -190,15 +194,18 @@ static const struct mpc_i2c_divider mpc_i2c_dividers_52xx[] __devinitconst = { | |||
| 190 | }; | 194 | }; |
| 191 | 195 | ||
| 192 | static int __devinit mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock, | 196 | static int __devinit mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock, |
| 193 | int prescaler) | 197 | int prescaler, u32 *real_clk) |
| 194 | { | 198 | { |
| 195 | const struct mpc_i2c_divider *div = NULL; | 199 | const struct mpc_i2c_divider *div = NULL; |
| 196 | unsigned int pvr = mfspr(SPRN_PVR); | 200 | unsigned int pvr = mfspr(SPRN_PVR); |
| 197 | u32 divider; | 201 | u32 divider; |
| 198 | int i; | 202 | int i; |
| 199 | 203 | ||
| 200 | if (clock == MPC_I2C_CLOCK_LEGACY) | 204 | if (clock == MPC_I2C_CLOCK_LEGACY) { |
| 205 | /* see below - default fdr = 0x3f -> div = 2048 */ | ||
| 206 | *real_clk = mpc5xxx_get_bus_frequency(node) / 2048; | ||
| 201 | return -EINVAL; | 207 | return -EINVAL; |
| 208 | } | ||
| 202 | 209 | ||
| 203 | /* Determine divider value */ | 210 | /* Determine divider value */ |
| 204 | divider = mpc5xxx_get_bus_frequency(node) / clock; | 211 | divider = mpc5xxx_get_bus_frequency(node) / clock; |
| @@ -216,7 +223,8 @@ static int __devinit mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock, | |||
| 216 | break; | 223 | break; |
| 217 | } | 224 | } |
| 218 | 225 | ||
| 219 | return div ? (int)div->fdr : -EINVAL; | 226 | *real_clk = mpc5xxx_get_bus_frequency(node) / div->divider; |
| 227 | return (int)div->fdr; | ||
| 220 | } | 228 | } |
| 221 | 229 | ||
| 222 | static void __devinit mpc_i2c_setup_52xx(struct device_node *node, | 230 | static void __devinit mpc_i2c_setup_52xx(struct device_node *node, |
| @@ -231,13 +239,14 @@ static void __devinit mpc_i2c_setup_52xx(struct device_node *node, | |||
| 231 | return; | 239 | return; |
| 232 | } | 240 | } |
| 233 | 241 | ||
| 234 | ret = mpc_i2c_get_fdr_52xx(node, clock, prescaler); | 242 | ret = mpc_i2c_get_fdr_52xx(node, clock, prescaler, &i2c->real_clk); |
| 235 | fdr = (ret >= 0) ? ret : 0x3f; /* backward compatibility */ | 243 | fdr = (ret >= 0) ? ret : 0x3f; /* backward compatibility */ |
| 236 | 244 | ||
| 237 | writeb(fdr & 0xff, i2c->base + MPC_I2C_FDR); | 245 | writeb(fdr & 0xff, i2c->base + MPC_I2C_FDR); |
| 238 | 246 | ||
| 239 | if (ret >= 0) | 247 | if (ret >= 0) |
| 240 | dev_info(i2c->dev, "clock %d Hz (fdr=%d)\n", clock, fdr); | 248 | dev_info(i2c->dev, "clock %u Hz (fdr=%d)\n", i2c->real_clk, |
| 249 | fdr); | ||
| 241 | } | 250 | } |
| 242 | #else /* !(CONFIG_PPC_MPC52xx || CONFIG_PPC_MPC512x) */ | 251 | #else /* !(CONFIG_PPC_MPC52xx || CONFIG_PPC_MPC512x) */ |
| 243 | static void __devinit mpc_i2c_setup_52xx(struct device_node *node, | 252 | static void __devinit mpc_i2c_setup_52xx(struct device_node *node, |
| @@ -334,14 +343,17 @@ static u32 __devinit mpc_i2c_get_sec_cfg_8xxx(void) | |||
| 334 | } | 343 | } |
| 335 | 344 | ||
| 336 | static int __devinit mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock, | 345 | static int __devinit mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock, |
| 337 | u32 prescaler) | 346 | u32 prescaler, u32 *real_clk) |
| 338 | { | 347 | { |
| 339 | const struct mpc_i2c_divider *div = NULL; | 348 | const struct mpc_i2c_divider *div = NULL; |
| 340 | u32 divider; | 349 | u32 divider; |
| 341 | int i; | 350 | int i; |
| 342 | 351 | ||
| 343 | if (clock == MPC_I2C_CLOCK_LEGACY) | 352 | if (clock == MPC_I2C_CLOCK_LEGACY) { |
| 353 | /* see below - default fdr = 0x1031 -> div = 16 * 3072 */ | ||
| 354 | *real_clk = fsl_get_sys_freq() / prescaler / (16 * 3072); | ||
| 344 | return -EINVAL; | 355 | return -EINVAL; |
| 356 | } | ||
| 345 | 357 | ||
| 346 | /* Determine proper divider value */ | 358 | /* Determine proper divider value */ |
| 347 | if (of_device_is_compatible(node, "fsl,mpc8544-i2c")) | 359 | if (of_device_is_compatible(node, "fsl,mpc8544-i2c")) |
| @@ -364,6 +376,7 @@ static int __devinit mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock, | |||
| 364 | break; | 376 | break; |
| 365 | } | 377 | } |
| 366 | 378 | ||
| 379 | *real_clk = fsl_get_sys_freq() / prescaler / div->divider; | ||
| 367 | return div ? (int)div->fdr : -EINVAL; | 380 | return div ? (int)div->fdr : -EINVAL; |
| 368 | } | 381 | } |
| 369 | 382 | ||
| @@ -380,7 +393,7 @@ static void __devinit mpc_i2c_setup_8xxx(struct device_node *node, | |||
| 380 | return; | 393 | return; |
| 381 | } | 394 | } |
| 382 | 395 | ||
| 383 | ret = mpc_i2c_get_fdr_8xxx(node, clock, prescaler); | 396 | ret = mpc_i2c_get_fdr_8xxx(node, clock, prescaler, &i2c->real_clk); |
| 384 | fdr = (ret >= 0) ? ret : 0x1031; /* backward compatibility */ | 397 | fdr = (ret >= 0) ? ret : 0x1031; /* backward compatibility */ |
| 385 | 398 | ||
| 386 | writeb(fdr & 0xff, i2c->base + MPC_I2C_FDR); | 399 | writeb(fdr & 0xff, i2c->base + MPC_I2C_FDR); |
| @@ -388,7 +401,7 @@ static void __devinit mpc_i2c_setup_8xxx(struct device_node *node, | |||
| 388 | 401 | ||
| 389 | if (ret >= 0) | 402 | if (ret >= 0) |
| 390 | dev_info(i2c->dev, "clock %d Hz (dfsrr=%d fdr=%d)\n", | 403 | dev_info(i2c->dev, "clock %d Hz (dfsrr=%d fdr=%d)\n", |
| 391 | clock, fdr >> 8, fdr & 0xff); | 404 | i2c->real_clk, fdr >> 8, fdr & 0xff); |
| 392 | } | 405 | } |
| 393 | 406 | ||
| 394 | #else /* !CONFIG_FSL_SOC */ | 407 | #else /* !CONFIG_FSL_SOC */ |
| @@ -500,10 +513,14 @@ static int mpc_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) | |||
| 500 | return -EINTR; | 513 | return -EINTR; |
| 501 | } | 514 | } |
| 502 | if (time_after(jiffies, orig_jiffies + HZ)) { | 515 | if (time_after(jiffies, orig_jiffies + HZ)) { |
| 516 | u8 status = readb(i2c->base + MPC_I2C_SR); | ||
| 517 | |||
| 503 | dev_dbg(i2c->dev, "timeout\n"); | 518 | dev_dbg(i2c->dev, "timeout\n"); |
| 504 | if (readb(i2c->base + MPC_I2C_SR) == | 519 | if ((status & (CSR_MCF | CSR_MBB | CSR_RXAK)) != 0) { |
| 505 | (CSR_MCF | CSR_MBB | CSR_RXAK)) | 520 | writeb(status & ~CSR_MAL, |
| 521 | i2c->base + MPC_I2C_SR); | ||
| 506 | mpc_i2c_fixup(i2c); | 522 | mpc_i2c_fixup(i2c); |
| 523 | } | ||
| 507 | return -EIO; | 524 | return -EIO; |
| 508 | } | 525 | } |
| 509 | schedule(); | 526 | schedule(); |
| @@ -595,6 +612,14 @@ static int __devinit fsl_i2c_probe(struct of_device *op, | |||
| 595 | mpc_i2c_setup_8xxx(op->dev.of_node, i2c, clock, 0); | 612 | mpc_i2c_setup_8xxx(op->dev.of_node, i2c, clock, 0); |
| 596 | } | 613 | } |
| 597 | 614 | ||
| 615 | prop = of_get_property(op->dev.of_node, "fsl,timeout", &plen); | ||
| 616 | if (prop && plen == sizeof(u32)) { | ||
| 617 | mpc_ops.timeout = *prop * HZ / 1000000; | ||
| 618 | if (mpc_ops.timeout < 5) | ||
| 619 | mpc_ops.timeout = 5; | ||
| 620 | } | ||
| 621 | dev_info(i2c->dev, "timeout %u us\n", mpc_ops.timeout * 1000000 / HZ); | ||
| 622 | |||
| 598 | dev_set_drvdata(&op->dev, i2c); | 623 | dev_set_drvdata(&op->dev, i2c); |
| 599 | 624 | ||
| 600 | i2c->adap = mpc_ops; | 625 | i2c->adap = mpc_ops; |
diff --git a/drivers/input/serio/i8042-io.h b/drivers/input/serio/i8042-io.h index 847f4aad7ed5..5d48bb66aa73 100644 --- a/drivers/input/serio/i8042-io.h +++ b/drivers/input/serio/i8042-io.h | |||
| @@ -27,6 +27,11 @@ | |||
| 27 | #include <asm/irq.h> | 27 | #include <asm/irq.h> |
| 28 | #elif defined(CONFIG_SH_CAYMAN) | 28 | #elif defined(CONFIG_SH_CAYMAN) |
| 29 | #include <asm/irq.h> | 29 | #include <asm/irq.h> |
| 30 | #elif defined(CONFIG_PPC) | ||
| 31 | extern int of_i8042_kbd_irq; | ||
| 32 | extern int of_i8042_aux_irq; | ||
| 33 | # define I8042_KBD_IRQ of_i8042_kbd_irq | ||
| 34 | # define I8042_AUX_IRQ of_i8042_aux_irq | ||
| 30 | #else | 35 | #else |
| 31 | # define I8042_KBD_IRQ 1 | 36 | # define I8042_KBD_IRQ 1 |
| 32 | # define I8042_AUX_IRQ 12 | 37 | # define I8042_AUX_IRQ 12 |
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig index f22bc9f05ddb..6629d09f3b38 100644 --- a/drivers/mtd/maps/Kconfig +++ b/drivers/mtd/maps/Kconfig | |||
| @@ -321,7 +321,7 @@ config MTD_CFI_FLAGADM | |||
| 321 | 321 | ||
| 322 | config MTD_REDWOOD | 322 | config MTD_REDWOOD |
| 323 | tristate "CFI Flash devices mapped on IBM Redwood" | 323 | tristate "CFI Flash devices mapped on IBM Redwood" |
| 324 | depends on MTD_CFI && ( REDWOOD_4 || REDWOOD_5 || REDWOOD_6 ) | 324 | depends on MTD_CFI |
| 325 | help | 325 | help |
| 326 | This enables access routines for the flash chips on the IBM | 326 | This enables access routines for the flash chips on the IBM |
| 327 | Redwood board. If you have one of these boards and would like to | 327 | Redwood board. If you have one of these boards and would like to |
diff --git a/drivers/mtd/maps/redwood.c b/drivers/mtd/maps/redwood.c index 933c0b63b016..d2c9db00db0c 100644 --- a/drivers/mtd/maps/redwood.c +++ b/drivers/mtd/maps/redwood.c | |||
| @@ -22,8 +22,6 @@ | |||
| 22 | 22 | ||
| 23 | #include <asm/io.h> | 23 | #include <asm/io.h> |
| 24 | 24 | ||
| 25 | #if !defined (CONFIG_REDWOOD_6) | ||
| 26 | |||
| 27 | #define WINDOW_ADDR 0xffc00000 | 25 | #define WINDOW_ADDR 0xffc00000 |
| 28 | #define WINDOW_SIZE 0x00400000 | 26 | #define WINDOW_SIZE 0x00400000 |
| 29 | 27 | ||
| @@ -69,47 +67,6 @@ static struct mtd_partition redwood_flash_partitions[] = { | |||
| 69 | } | 67 | } |
| 70 | }; | 68 | }; |
| 71 | 69 | ||
| 72 | #else /* CONFIG_REDWOOD_6 */ | ||
| 73 | /* FIXME: the window is bigger - armin */ | ||
| 74 | #define WINDOW_ADDR 0xff800000 | ||
| 75 | #define WINDOW_SIZE 0x00800000 | ||
| 76 | |||
| 77 | #define RW_PART0_OF 0 | ||
| 78 | #define RW_PART0_SZ 0x400000 /* 4 MiB data */ | ||
| 79 | #define RW_PART1_OF RW_PART0_OF + RW_PART0_SZ | ||
| 80 | #define RW_PART1_SZ 0x10000 /* 64K VPD */ | ||
| 81 | #define RW_PART2_OF RW_PART1_OF + RW_PART1_SZ | ||
| 82 | #define RW_PART2_SZ 0x400000 - (0x10000 + 0x20000) | ||
| 83 | #define RW_PART3_OF RW_PART2_OF + RW_PART2_SZ | ||
| 84 | #define RW_PART3_SZ 0x20000 | ||
| 85 | |||
| 86 | static struct mtd_partition redwood_flash_partitions[] = { | ||
| 87 | { | ||
| 88 | .name = "Redwood filesystem", | ||
| 89 | .offset = RW_PART0_OF, | ||
| 90 | .size = RW_PART0_SZ | ||
| 91 | }, | ||
| 92 | { | ||
| 93 | .name = "Redwood OpenBIOS Vital Product Data", | ||
| 94 | .offset = RW_PART1_OF, | ||
| 95 | .size = RW_PART1_SZ, | ||
| 96 | .mask_flags = MTD_WRITEABLE /* force read-only */ | ||
| 97 | }, | ||
| 98 | { | ||
| 99 | .name = "Redwood kernel", | ||
| 100 | .offset = RW_PART2_OF, | ||
| 101 | .size = RW_PART2_SZ | ||
| 102 | }, | ||
| 103 | { | ||
| 104 | .name = "Redwood OpenBIOS", | ||
| 105 | .offset = RW_PART3_OF, | ||
| 106 | .size = RW_PART3_SZ, | ||
| 107 | .mask_flags = MTD_WRITEABLE /* force read-only */ | ||
| 108 | } | ||
| 109 | }; | ||
| 110 | |||
| 111 | #endif /* CONFIG_REDWOOD_6 */ | ||
| 112 | |||
| 113 | struct map_info redwood_flash_map = { | 70 | struct map_info redwood_flash_map = { |
| 114 | .name = "IBM Redwood", | 71 | .name = "IBM Redwood", |
| 115 | .size = WINDOW_SIZE, | 72 | .size = WINDOW_SIZE, |
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 23c13180ff14..5a6895320b48 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
| @@ -914,7 +914,7 @@ config SMC91X | |||
| 914 | tristate "SMC 91C9x/91C1xxx support" | 914 | tristate "SMC 91C9x/91C1xxx support" |
| 915 | select CRC32 | 915 | select CRC32 |
| 916 | select MII | 916 | select MII |
| 917 | depends on ARM || REDWOOD_5 || REDWOOD_6 || M32R || SUPERH || \ | 917 | depends on ARM || M32R || SUPERH || \ |
| 918 | MIPS || BLACKFIN || MN10300 || COLDFIRE | 918 | MIPS || BLACKFIN || MN10300 || COLDFIRE |
| 919 | help | 919 | help |
| 920 | This is a driver for SMC's 91x series of Ethernet chipsets, | 920 | This is a driver for SMC's 91x series of Ethernet chipsets, |
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h index 8d2772cc42f2..ee747919a766 100644 --- a/drivers/net/smc91x.h +++ b/drivers/net/smc91x.h | |||
| @@ -83,43 +83,6 @@ static inline void SMC_outw(u16 val, void __iomem *ioaddr, int reg) | |||
| 83 | } | 83 | } |
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | #elif defined(CONFIG_REDWOOD_5) || defined(CONFIG_REDWOOD_6) | ||
| 87 | |||
| 88 | /* We can only do 16-bit reads and writes in the static memory space. */ | ||
| 89 | #define SMC_CAN_USE_8BIT 0 | ||
| 90 | #define SMC_CAN_USE_16BIT 1 | ||
| 91 | #define SMC_CAN_USE_32BIT 0 | ||
| 92 | #define SMC_NOWAIT 1 | ||
| 93 | |||
| 94 | #define SMC_IO_SHIFT 0 | ||
| 95 | |||
| 96 | #define SMC_inw(a, r) in_be16((volatile u16 *)((a) + (r))) | ||
| 97 | #define SMC_outw(v, a, r) out_be16((volatile u16 *)((a) + (r)), v) | ||
| 98 | #define SMC_insw(a, r, p, l) \ | ||
| 99 | do { \ | ||
| 100 | unsigned long __port = (a) + (r); \ | ||
| 101 | u16 *__p = (u16 *)(p); \ | ||
| 102 | int __l = (l); \ | ||
| 103 | insw(__port, __p, __l); \ | ||
| 104 | while (__l > 0) { \ | ||
| 105 | *__p = swab16(*__p); \ | ||
| 106 | __p++; \ | ||
| 107 | __l--; \ | ||
| 108 | } \ | ||
| 109 | } while (0) | ||
| 110 | #define SMC_outsw(a, r, p, l) \ | ||
| 111 | do { \ | ||
| 112 | unsigned long __port = (a) + (r); \ | ||
| 113 | u16 *__p = (u16 *)(p); \ | ||
| 114 | int __l = (l); \ | ||
| 115 | while (__l > 0) { \ | ||
| 116 | /* Believe it or not, the swab isn't needed. */ \ | ||
| 117 | outw( /* swab16 */ (*__p++), __port); \ | ||
| 118 | __l--; \ | ||
| 119 | } \ | ||
| 120 | } while (0) | ||
| 121 | #define SMC_IRQ_FLAGS (0) | ||
| 122 | |||
| 123 | #elif defined(CONFIG_SA1100_PLEB) | 86 | #elif defined(CONFIG_SA1100_PLEB) |
| 124 | /* We can only do 16-bit reads and writes in the static memory space. */ | 87 | /* We can only do 16-bit reads and writes in the static memory space. */ |
| 125 | #define SMC_CAN_USE_8BIT 1 | 88 | #define SMC_CAN_USE_8BIT 1 |
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c index 84a35f699016..1a88b363005c 100644 --- a/drivers/serial/mpc52xx_uart.c +++ b/drivers/serial/mpc52xx_uart.c | |||
| @@ -113,7 +113,9 @@ struct psc_ops { | |||
| 113 | unsigned char (*read_char)(struct uart_port *port); | 113 | unsigned char (*read_char)(struct uart_port *port); |
| 114 | void (*cw_disable_ints)(struct uart_port *port); | 114 | void (*cw_disable_ints)(struct uart_port *port); |
| 115 | void (*cw_restore_ints)(struct uart_port *port); | 115 | void (*cw_restore_ints)(struct uart_port *port); |
| 116 | unsigned long (*getuartclk)(void *p); | 116 | unsigned int (*set_baudrate)(struct uart_port *port, |
| 117 | struct ktermios *new, | ||
| 118 | struct ktermios *old); | ||
| 117 | int (*clock)(struct uart_port *port, int enable); | 119 | int (*clock)(struct uart_port *port, int enable); |
| 118 | int (*fifoc_init)(void); | 120 | int (*fifoc_init)(void); |
| 119 | void (*fifoc_uninit)(void); | 121 | void (*fifoc_uninit)(void); |
| @@ -121,6 +123,16 @@ struct psc_ops { | |||
| 121 | irqreturn_t (*handle_irq)(struct uart_port *port); | 123 | irqreturn_t (*handle_irq)(struct uart_port *port); |
| 122 | }; | 124 | }; |
| 123 | 125 | ||
| 126 | /* setting the prescaler and divisor reg is common for all chips */ | ||
| 127 | static inline void mpc52xx_set_divisor(struct mpc52xx_psc __iomem *psc, | ||
| 128 | u16 prescaler, unsigned int divisor) | ||
| 129 | { | ||
| 130 | /* select prescaler */ | ||
| 131 | out_be16(&psc->mpc52xx_psc_clock_select, prescaler); | ||
| 132 | out_8(&psc->ctur, divisor >> 8); | ||
| 133 | out_8(&psc->ctlr, divisor & 0xff); | ||
| 134 | } | ||
| 135 | |||
| 124 | #ifdef CONFIG_PPC_MPC52xx | 136 | #ifdef CONFIG_PPC_MPC52xx |
| 125 | #define FIFO_52xx(port) ((struct mpc52xx_psc_fifo __iomem *)(PSC(port)+1)) | 137 | #define FIFO_52xx(port) ((struct mpc52xx_psc_fifo __iomem *)(PSC(port)+1)) |
| 126 | static void mpc52xx_psc_fifo_init(struct uart_port *port) | 138 | static void mpc52xx_psc_fifo_init(struct uart_port *port) |
| @@ -128,9 +140,6 @@ static void mpc52xx_psc_fifo_init(struct uart_port *port) | |||
| 128 | struct mpc52xx_psc __iomem *psc = PSC(port); | 140 | struct mpc52xx_psc __iomem *psc = PSC(port); |
| 129 | struct mpc52xx_psc_fifo __iomem *fifo = FIFO_52xx(port); | 141 | struct mpc52xx_psc_fifo __iomem *fifo = FIFO_52xx(port); |
| 130 | 142 | ||
| 131 | /* /32 prescaler */ | ||
| 132 | out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00); | ||
| 133 | |||
| 134 | out_8(&fifo->rfcntl, 0x00); | 143 | out_8(&fifo->rfcntl, 0x00); |
| 135 | out_be16(&fifo->rfalarm, 0x1ff); | 144 | out_be16(&fifo->rfalarm, 0x1ff); |
| 136 | out_8(&fifo->tfcntl, 0x07); | 145 | out_8(&fifo->tfcntl, 0x07); |
| @@ -219,15 +228,47 @@ static void mpc52xx_psc_cw_restore_ints(struct uart_port *port) | |||
| 219 | out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask); | 228 | out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask); |
| 220 | } | 229 | } |
| 221 | 230 | ||
| 222 | /* Search for bus-frequency property in this node or a parent */ | 231 | static unsigned int mpc5200_psc_set_baudrate(struct uart_port *port, |
| 223 | static unsigned long mpc52xx_getuartclk(void *p) | 232 | struct ktermios *new, |
| 233 | struct ktermios *old) | ||
| 224 | { | 234 | { |
| 225 | /* | 235 | unsigned int baud; |
| 226 | * 5200 UARTs have a / 32 prescaler | 236 | unsigned int divisor; |
| 227 | * but the generic serial code assumes 16 | 237 | |
| 228 | * so return ipb freq / 2 | 238 | /* The 5200 has a fixed /32 prescaler, uartclk contains the ipb freq */ |
| 229 | */ | 239 | baud = uart_get_baud_rate(port, new, old, |
| 230 | return mpc5xxx_get_bus_frequency(p) / 2; | 240 | port->uartclk / (32 * 0xffff) + 1, |
| 241 | port->uartclk / 32); | ||
| 242 | divisor = (port->uartclk + 16 * baud) / (32 * baud); | ||
| 243 | |||
| 244 | /* enable the /32 prescaler and set the divisor */ | ||
| 245 | mpc52xx_set_divisor(PSC(port), 0xdd00, divisor); | ||
| 246 | return baud; | ||
| 247 | } | ||
| 248 | |||
| 249 | static unsigned int mpc5200b_psc_set_baudrate(struct uart_port *port, | ||
| 250 | struct ktermios *new, | ||
| 251 | struct ktermios *old) | ||
| 252 | { | ||
| 253 | unsigned int baud; | ||
| 254 | unsigned int divisor; | ||
| 255 | u16 prescaler; | ||
| 256 | |||
| 257 | /* The 5200B has a selectable /4 or /32 prescaler, uartclk contains the | ||
| 258 | * ipb freq */ | ||
| 259 | baud = uart_get_baud_rate(port, new, old, | ||
| 260 | port->uartclk / (32 * 0xffff) + 1, | ||
| 261 | port->uartclk / 4); | ||
| 262 | divisor = (port->uartclk + 2 * baud) / (4 * baud); | ||
| 263 | |||
| 264 | /* select the proper prescaler and set the divisor */ | ||
| 265 | if (divisor > 0xffff) { | ||
| 266 | divisor = (divisor + 4) / 8; | ||
| 267 | prescaler = 0xdd00; /* /32 */ | ||
| 268 | } else | ||
| 269 | prescaler = 0xff00; /* /4 */ | ||
| 270 | mpc52xx_set_divisor(PSC(port), prescaler, divisor); | ||
| 271 | return baud; | ||
| 231 | } | 272 | } |
| 232 | 273 | ||
| 233 | static void mpc52xx_psc_get_irq(struct uart_port *port, struct device_node *np) | 274 | static void mpc52xx_psc_get_irq(struct uart_port *port, struct device_node *np) |
| @@ -258,7 +299,28 @@ static struct psc_ops mpc52xx_psc_ops = { | |||
| 258 | .read_char = mpc52xx_psc_read_char, | 299 | .read_char = mpc52xx_psc_read_char, |
| 259 | .cw_disable_ints = mpc52xx_psc_cw_disable_ints, | 300 | .cw_disable_ints = mpc52xx_psc_cw_disable_ints, |
| 260 | .cw_restore_ints = mpc52xx_psc_cw_restore_ints, | 301 | .cw_restore_ints = mpc52xx_psc_cw_restore_ints, |
| 261 | .getuartclk = mpc52xx_getuartclk, | 302 | .set_baudrate = mpc5200_psc_set_baudrate, |
| 303 | .get_irq = mpc52xx_psc_get_irq, | ||
| 304 | .handle_irq = mpc52xx_psc_handle_irq, | ||
| 305 | }; | ||
| 306 | |||
| 307 | static struct psc_ops mpc5200b_psc_ops = { | ||
| 308 | .fifo_init = mpc52xx_psc_fifo_init, | ||
| 309 | .raw_rx_rdy = mpc52xx_psc_raw_rx_rdy, | ||
| 310 | .raw_tx_rdy = mpc52xx_psc_raw_tx_rdy, | ||
| 311 | .rx_rdy = mpc52xx_psc_rx_rdy, | ||
| 312 | .tx_rdy = mpc52xx_psc_tx_rdy, | ||
| 313 | .tx_empty = mpc52xx_psc_tx_empty, | ||
| 314 | .stop_rx = mpc52xx_psc_stop_rx, | ||
| 315 | .start_tx = mpc52xx_psc_start_tx, | ||
| 316 | .stop_tx = mpc52xx_psc_stop_tx, | ||
| 317 | .rx_clr_irq = mpc52xx_psc_rx_clr_irq, | ||
| 318 | .tx_clr_irq = mpc52xx_psc_tx_clr_irq, | ||
| 319 | .write_char = mpc52xx_psc_write_char, | ||
| 320 | .read_char = mpc52xx_psc_read_char, | ||
| 321 | .cw_disable_ints = mpc52xx_psc_cw_disable_ints, | ||
| 322 | .cw_restore_ints = mpc52xx_psc_cw_restore_ints, | ||
| 323 | .set_baudrate = mpc5200b_psc_set_baudrate, | ||
| 262 | .get_irq = mpc52xx_psc_get_irq, | 324 | .get_irq = mpc52xx_psc_get_irq, |
| 263 | .handle_irq = mpc52xx_psc_handle_irq, | 325 | .handle_irq = mpc52xx_psc_handle_irq, |
| 264 | }; | 326 | }; |
| @@ -392,9 +454,35 @@ static void mpc512x_psc_cw_restore_ints(struct uart_port *port) | |||
| 392 | out_be32(&FIFO_512x(port)->rximr, port->read_status_mask & 0x7f); | 454 | out_be32(&FIFO_512x(port)->rximr, port->read_status_mask & 0x7f); |
| 393 | } | 455 | } |
| 394 | 456 | ||
| 395 | static unsigned long mpc512x_getuartclk(void *p) | 457 | static unsigned int mpc512x_psc_set_baudrate(struct uart_port *port, |
| 458 | struct ktermios *new, | ||
| 459 | struct ktermios *old) | ||
| 396 | { | 460 | { |
| 397 | return mpc5xxx_get_bus_frequency(p); | 461 | unsigned int baud; |
| 462 | unsigned int divisor; | ||
| 463 | |||
| 464 | /* | ||
| 465 | * The "MPC5121e Microcontroller Reference Manual, Rev. 3" says on | ||
| 466 | * pg. 30-10 that the chip supports a /32 and a /10 prescaler. | ||
| 467 | * Furthermore, it states that "After reset, the prescaler by 10 | ||
| 468 | * for the UART mode is selected", but the reset register value is | ||
| 469 | * 0x0000 which means a /32 prescaler. This is wrong. | ||
| 470 | * | ||
| 471 | * In reality using /32 prescaler doesn't work, as it is not supported! | ||
| 472 | * Use /16 or /10 prescaler, see "MPC5121e Hardware Design Guide", | ||
| 473 | * Chapter 4.1 PSC in UART Mode. | ||
| 474 | * Calculate with a /16 prescaler here. | ||
| 475 | */ | ||
| 476 | |||
| 477 | /* uartclk contains the ips freq */ | ||
| 478 | baud = uart_get_baud_rate(port, new, old, | ||
| 479 | port->uartclk / (16 * 0xffff) + 1, | ||
| 480 | port->uartclk / 16); | ||
| 481 | divisor = (port->uartclk + 8 * baud) / (16 * baud); | ||
| 482 | |||
| 483 | /* enable the /16 prescaler and set the divisor */ | ||
| 484 | mpc52xx_set_divisor(PSC(port), 0xdd00, divisor); | ||
| 485 | return baud; | ||
| 398 | } | 486 | } |
| 399 | 487 | ||
| 400 | /* Init PSC FIFO Controller */ | 488 | /* Init PSC FIFO Controller */ |
| @@ -498,7 +586,7 @@ static struct psc_ops mpc512x_psc_ops = { | |||
| 498 | .read_char = mpc512x_psc_read_char, | 586 | .read_char = mpc512x_psc_read_char, |
| 499 | .cw_disable_ints = mpc512x_psc_cw_disable_ints, | 587 | .cw_disable_ints = mpc512x_psc_cw_disable_ints, |
| 500 | .cw_restore_ints = mpc512x_psc_cw_restore_ints, | 588 | .cw_restore_ints = mpc512x_psc_cw_restore_ints, |
| 501 | .getuartclk = mpc512x_getuartclk, | 589 | .set_baudrate = mpc512x_psc_set_baudrate, |
| 502 | .clock = mpc512x_psc_clock, | 590 | .clock = mpc512x_psc_clock, |
| 503 | .fifoc_init = mpc512x_psc_fifoc_init, | 591 | .fifoc_init = mpc512x_psc_fifoc_init, |
| 504 | .fifoc_uninit = mpc512x_psc_fifoc_uninit, | 592 | .fifoc_uninit = mpc512x_psc_fifoc_uninit, |
| @@ -666,8 +754,8 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new, | |||
| 666 | struct mpc52xx_psc __iomem *psc = PSC(port); | 754 | struct mpc52xx_psc __iomem *psc = PSC(port); |
| 667 | unsigned long flags; | 755 | unsigned long flags; |
| 668 | unsigned char mr1, mr2; | 756 | unsigned char mr1, mr2; |
| 669 | unsigned short ctr; | 757 | unsigned int j; |
| 670 | unsigned int j, baud, quot; | 758 | unsigned int baud; |
| 671 | 759 | ||
| 672 | /* Prepare what we're gonna write */ | 760 | /* Prepare what we're gonna write */ |
| 673 | mr1 = 0; | 761 | mr1 = 0; |
| @@ -704,16 +792,9 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new, | |||
| 704 | mr2 |= MPC52xx_PSC_MODE_TXCTS; | 792 | mr2 |= MPC52xx_PSC_MODE_TXCTS; |
| 705 | } | 793 | } |
| 706 | 794 | ||
| 707 | baud = uart_get_baud_rate(port, new, old, 0, port->uartclk/16); | ||
| 708 | quot = uart_get_divisor(port, baud); | ||
| 709 | ctr = quot & 0xffff; | ||
| 710 | |||
| 711 | /* Get the lock */ | 795 | /* Get the lock */ |
| 712 | spin_lock_irqsave(&port->lock, flags); | 796 | spin_lock_irqsave(&port->lock, flags); |
| 713 | 797 | ||
| 714 | /* Update the per-port timeout */ | ||
| 715 | uart_update_timeout(port, new->c_cflag, baud); | ||
| 716 | |||
| 717 | /* Do our best to flush TX & RX, so we don't lose anything */ | 798 | /* Do our best to flush TX & RX, so we don't lose anything */ |
| 718 | /* But we don't wait indefinitely ! */ | 799 | /* But we don't wait indefinitely ! */ |
| 719 | j = 5000000; /* Maximum wait */ | 800 | j = 5000000; /* Maximum wait */ |
| @@ -737,8 +818,10 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new, | |||
| 737 | out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1); | 818 | out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1); |
| 738 | out_8(&psc->mode, mr1); | 819 | out_8(&psc->mode, mr1); |
| 739 | out_8(&psc->mode, mr2); | 820 | out_8(&psc->mode, mr2); |
| 740 | out_8(&psc->ctur, ctr >> 8); | 821 | baud = psc_ops->set_baudrate(port, new, old); |
| 741 | out_8(&psc->ctlr, ctr & 0xff); | 822 | |
| 823 | /* Update the per-port timeout */ | ||
| 824 | uart_update_timeout(port, new->c_cflag, baud); | ||
| 742 | 825 | ||
| 743 | if (UART_ENABLE_MS(port, new->c_cflag)) | 826 | if (UART_ENABLE_MS(port, new->c_cflag)) |
| 744 | mpc52xx_uart_enable_ms(port); | 827 | mpc52xx_uart_enable_ms(port); |
| @@ -1118,7 +1201,7 @@ mpc52xx_console_setup(struct console *co, char *options) | |||
| 1118 | return ret; | 1201 | return ret; |
| 1119 | } | 1202 | } |
| 1120 | 1203 | ||
| 1121 | uartclk = psc_ops->getuartclk(np); | 1204 | uartclk = mpc5xxx_get_bus_frequency(np); |
| 1122 | if (uartclk == 0) { | 1205 | if (uartclk == 0) { |
| 1123 | pr_debug("Could not find uart clock frequency!\n"); | 1206 | pr_debug("Could not find uart clock frequency!\n"); |
| 1124 | return -EINVAL; | 1207 | return -EINVAL; |
| @@ -1201,6 +1284,7 @@ static struct uart_driver mpc52xx_uart_driver = { | |||
| 1201 | 1284 | ||
| 1202 | static struct of_device_id mpc52xx_uart_of_match[] = { | 1285 | static struct of_device_id mpc52xx_uart_of_match[] = { |
| 1203 | #ifdef CONFIG_PPC_MPC52xx | 1286 | #ifdef CONFIG_PPC_MPC52xx |
| 1287 | { .compatible = "fsl,mpc5200b-psc-uart", .data = &mpc5200b_psc_ops, }, | ||
| 1204 | { .compatible = "fsl,mpc5200-psc-uart", .data = &mpc52xx_psc_ops, }, | 1288 | { .compatible = "fsl,mpc5200-psc-uart", .data = &mpc52xx_psc_ops, }, |
| 1205 | /* binding used by old lite5200 device trees: */ | 1289 | /* binding used by old lite5200 device trees: */ |
| 1206 | { .compatible = "mpc5200-psc-uart", .data = &mpc52xx_psc_ops, }, | 1290 | { .compatible = "mpc5200-psc-uart", .data = &mpc52xx_psc_ops, }, |
| @@ -1233,7 +1317,10 @@ mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match) | |||
| 1233 | pr_debug("Found %s assigned to ttyPSC%x\n", | 1317 | pr_debug("Found %s assigned to ttyPSC%x\n", |
| 1234 | mpc52xx_uart_nodes[idx]->full_name, idx); | 1318 | mpc52xx_uart_nodes[idx]->full_name, idx); |
| 1235 | 1319 | ||
| 1236 | uartclk = psc_ops->getuartclk(op->dev.of_node); | 1320 | /* set the uart clock to the input clock of the psc, the different |
| 1321 | * prescalers are taken into account in the set_baudrate() methods | ||
| 1322 | * of the respective chip */ | ||
| 1323 | uartclk = mpc5xxx_get_bus_frequency(op->dev.of_node); | ||
| 1237 | if (uartclk == 0) { | 1324 | if (uartclk == 0) { |
| 1238 | dev_dbg(&op->dev, "Could not find uart clock frequency!\n"); | 1325 | dev_dbg(&op->dev, "Could not find uart clock frequency!\n"); |
| 1239 | return -EINVAL; | 1326 | return -EINVAL; |
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 9e711a1d0d97..7b11ea68c80e 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
| @@ -1871,6 +1871,7 @@ config FB_MBX_DEBUG | |||
| 1871 | config FB_FSL_DIU | 1871 | config FB_FSL_DIU |
| 1872 | tristate "Freescale DIU framebuffer support" | 1872 | tristate "Freescale DIU framebuffer support" |
| 1873 | depends on FB && FSL_SOC | 1873 | depends on FB && FSL_SOC |
| 1874 | select FB_MODE_HELPERS | ||
| 1874 | select FB_CFB_FILLRECT | 1875 | select FB_CFB_FILLRECT |
| 1875 | select FB_CFB_COPYAREA | 1876 | select FB_CFB_COPYAREA |
| 1876 | select FB_CFB_IMAGEBLIT | 1877 | select FB_CFB_IMAGEBLIT |
diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c index 27455ce298b7..e38ad2224540 100644 --- a/drivers/video/fsl-diu-fb.c +++ b/drivers/video/fsl-diu-fb.c | |||
| @@ -34,7 +34,8 @@ | |||
| 34 | #include <linux/of_platform.h> | 34 | #include <linux/of_platform.h> |
| 35 | 35 | ||
| 36 | #include <sysdev/fsl_soc.h> | 36 | #include <sysdev/fsl_soc.h> |
| 37 | #include "fsl-diu-fb.h" | 37 | #include <linux/fsl-diu-fb.h> |
| 38 | #include "edid.h" | ||
| 38 | 39 | ||
| 39 | /* | 40 | /* |
| 40 | * These parameters give default parameters | 41 | * These parameters give default parameters |
| @@ -217,6 +218,7 @@ struct mfb_info { | |||
| 217 | int x_aoi_d; /* aoi display x offset to physical screen */ | 218 | int x_aoi_d; /* aoi display x offset to physical screen */ |
| 218 | int y_aoi_d; /* aoi display y offset to physical screen */ | 219 | int y_aoi_d; /* aoi display y offset to physical screen */ |
| 219 | struct fsl_diu_data *parent; | 220 | struct fsl_diu_data *parent; |
| 221 | u8 *edid_data; | ||
| 220 | }; | 222 | }; |
| 221 | 223 | ||
| 222 | 224 | ||
| @@ -317,6 +319,17 @@ static void fsl_diu_free(void *virt, size_t size) | |||
| 317 | free_pages_exact(virt, size); | 319 | free_pages_exact(virt, size); |
| 318 | } | 320 | } |
| 319 | 321 | ||
| 322 | /* | ||
| 323 | * Workaround for failed writing desc register of planes. | ||
| 324 | * Needed with MPC5121 DIU rev 2.0 silicon. | ||
| 325 | */ | ||
| 326 | void wr_reg_wa(u32 *reg, u32 val) | ||
| 327 | { | ||
| 328 | do { | ||
| 329 | out_be32(reg, val); | ||
| 330 | } while (in_be32(reg) != val); | ||
| 331 | } | ||
| 332 | |||
| 320 | static int fsl_diu_enable_panel(struct fb_info *info) | 333 | static int fsl_diu_enable_panel(struct fb_info *info) |
| 321 | { | 334 | { |
| 322 | struct mfb_info *pmfbi, *cmfbi, *mfbi = info->par; | 335 | struct mfb_info *pmfbi, *cmfbi, *mfbi = info->par; |
| @@ -330,7 +343,7 @@ static int fsl_diu_enable_panel(struct fb_info *info) | |||
| 330 | switch (mfbi->index) { | 343 | switch (mfbi->index) { |
| 331 | case 0: /* plane 0 */ | 344 | case 0: /* plane 0 */ |
| 332 | if (hw->desc[0] != ad->paddr) | 345 | if (hw->desc[0] != ad->paddr) |
| 333 | out_be32(&hw->desc[0], ad->paddr); | 346 | wr_reg_wa(&hw->desc[0], ad->paddr); |
| 334 | break; | 347 | break; |
| 335 | case 1: /* plane 1 AOI 0 */ | 348 | case 1: /* plane 1 AOI 0 */ |
| 336 | cmfbi = machine_data->fsl_diu_info[2]->par; | 349 | cmfbi = machine_data->fsl_diu_info[2]->par; |
| @@ -340,7 +353,7 @@ static int fsl_diu_enable_panel(struct fb_info *info) | |||
| 340 | cpu_to_le32(cmfbi->ad->paddr); | 353 | cpu_to_le32(cmfbi->ad->paddr); |
| 341 | else | 354 | else |
| 342 | ad->next_ad = 0; | 355 | ad->next_ad = 0; |
| 343 | out_be32(&hw->desc[1], ad->paddr); | 356 | wr_reg_wa(&hw->desc[1], ad->paddr); |
| 344 | } | 357 | } |
| 345 | break; | 358 | break; |
| 346 | case 3: /* plane 2 AOI 0 */ | 359 | case 3: /* plane 2 AOI 0 */ |
| @@ -351,14 +364,14 @@ static int fsl_diu_enable_panel(struct fb_info *info) | |||
| 351 | cpu_to_le32(cmfbi->ad->paddr); | 364 | cpu_to_le32(cmfbi->ad->paddr); |
| 352 | else | 365 | else |
| 353 | ad->next_ad = 0; | 366 | ad->next_ad = 0; |
| 354 | out_be32(&hw->desc[2], ad->paddr); | 367 | wr_reg_wa(&hw->desc[2], ad->paddr); |
| 355 | } | 368 | } |
| 356 | break; | 369 | break; |
| 357 | case 2: /* plane 1 AOI 1 */ | 370 | case 2: /* plane 1 AOI 1 */ |
| 358 | pmfbi = machine_data->fsl_diu_info[1]->par; | 371 | pmfbi = machine_data->fsl_diu_info[1]->par; |
| 359 | ad->next_ad = 0; | 372 | ad->next_ad = 0; |
| 360 | if (hw->desc[1] == machine_data->dummy_ad->paddr) | 373 | if (hw->desc[1] == machine_data->dummy_ad->paddr) |
| 361 | out_be32(&hw->desc[1], ad->paddr); | 374 | wr_reg_wa(&hw->desc[1], ad->paddr); |
| 362 | else /* AOI0 open */ | 375 | else /* AOI0 open */ |
| 363 | pmfbi->ad->next_ad = cpu_to_le32(ad->paddr); | 376 | pmfbi->ad->next_ad = cpu_to_le32(ad->paddr); |
| 364 | break; | 377 | break; |
| @@ -366,7 +379,7 @@ static int fsl_diu_enable_panel(struct fb_info *info) | |||
| 366 | pmfbi = machine_data->fsl_diu_info[3]->par; | 379 | pmfbi = machine_data->fsl_diu_info[3]->par; |
| 367 | ad->next_ad = 0; | 380 | ad->next_ad = 0; |
| 368 | if (hw->desc[2] == machine_data->dummy_ad->paddr) | 381 | if (hw->desc[2] == machine_data->dummy_ad->paddr) |
| 369 | out_be32(&hw->desc[2], ad->paddr); | 382 | wr_reg_wa(&hw->desc[2], ad->paddr); |
| 370 | else /* AOI0 was open */ | 383 | else /* AOI0 was open */ |
| 371 | pmfbi->ad->next_ad = cpu_to_le32(ad->paddr); | 384 | pmfbi->ad->next_ad = cpu_to_le32(ad->paddr); |
| 372 | break; | 385 | break; |
| @@ -390,27 +403,24 @@ static int fsl_diu_disable_panel(struct fb_info *info) | |||
| 390 | switch (mfbi->index) { | 403 | switch (mfbi->index) { |
| 391 | case 0: /* plane 0 */ | 404 | case 0: /* plane 0 */ |
| 392 | if (hw->desc[0] != machine_data->dummy_ad->paddr) | 405 | if (hw->desc[0] != machine_data->dummy_ad->paddr) |
| 393 | out_be32(&hw->desc[0], | 406 | wr_reg_wa(&hw->desc[0], machine_data->dummy_ad->paddr); |
| 394 | machine_data->dummy_ad->paddr); | ||
| 395 | break; | 407 | break; |
| 396 | case 1: /* plane 1 AOI 0 */ | 408 | case 1: /* plane 1 AOI 0 */ |
| 397 | cmfbi = machine_data->fsl_diu_info[2]->par; | 409 | cmfbi = machine_data->fsl_diu_info[2]->par; |
| 398 | if (cmfbi->count > 0) /* AOI1 is open */ | 410 | if (cmfbi->count > 0) /* AOI1 is open */ |
| 399 | out_be32(&hw->desc[1], cmfbi->ad->paddr); | 411 | wr_reg_wa(&hw->desc[1], cmfbi->ad->paddr); |
| 400 | /* move AOI1 to the first */ | 412 | /* move AOI1 to the first */ |
| 401 | else /* AOI1 was closed */ | 413 | else /* AOI1 was closed */ |
| 402 | out_be32(&hw->desc[1], | 414 | wr_reg_wa(&hw->desc[1], machine_data->dummy_ad->paddr); |
| 403 | machine_data->dummy_ad->paddr); | ||
| 404 | /* close AOI 0 */ | 415 | /* close AOI 0 */ |
| 405 | break; | 416 | break; |
| 406 | case 3: /* plane 2 AOI 0 */ | 417 | case 3: /* plane 2 AOI 0 */ |
| 407 | cmfbi = machine_data->fsl_diu_info[4]->par; | 418 | cmfbi = machine_data->fsl_diu_info[4]->par; |
| 408 | if (cmfbi->count > 0) /* AOI1 is open */ | 419 | if (cmfbi->count > 0) /* AOI1 is open */ |
| 409 | out_be32(&hw->desc[2], cmfbi->ad->paddr); | 420 | wr_reg_wa(&hw->desc[2], cmfbi->ad->paddr); |
| 410 | /* move AOI1 to the first */ | 421 | /* move AOI1 to the first */ |
| 411 | else /* AOI1 was closed */ | 422 | else /* AOI1 was closed */ |
| 412 | out_be32(&hw->desc[2], | 423 | wr_reg_wa(&hw->desc[2], machine_data->dummy_ad->paddr); |
| 413 | machine_data->dummy_ad->paddr); | ||
| 414 | /* close AOI 0 */ | 424 | /* close AOI 0 */ |
| 415 | break; | 425 | break; |
| 416 | case 2: /* plane 1 AOI 1 */ | 426 | case 2: /* plane 1 AOI 1 */ |
| @@ -421,7 +431,7 @@ static int fsl_diu_disable_panel(struct fb_info *info) | |||
| 421 | /* AOI0 is open, must be the first */ | 431 | /* AOI0 is open, must be the first */ |
| 422 | pmfbi->ad->next_ad = 0; | 432 | pmfbi->ad->next_ad = 0; |
| 423 | } else /* AOI1 is the first in the chain */ | 433 | } else /* AOI1 is the first in the chain */ |
| 424 | out_be32(&hw->desc[1], machine_data->dummy_ad->paddr); | 434 | wr_reg_wa(&hw->desc[1], machine_data->dummy_ad->paddr); |
| 425 | /* close AOI 1 */ | 435 | /* close AOI 1 */ |
| 426 | break; | 436 | break; |
| 427 | case 4: /* plane 2 AOI 1 */ | 437 | case 4: /* plane 2 AOI 1 */ |
| @@ -432,7 +442,7 @@ static int fsl_diu_disable_panel(struct fb_info *info) | |||
| 432 | /* AOI0 is open, must be the first */ | 442 | /* AOI0 is open, must be the first */ |
| 433 | pmfbi->ad->next_ad = 0; | 443 | pmfbi->ad->next_ad = 0; |
| 434 | } else /* AOI1 is the first in the chain */ | 444 | } else /* AOI1 is the first in the chain */ |
| 435 | out_be32(&hw->desc[2], machine_data->dummy_ad->paddr); | 445 | wr_reg_wa(&hw->desc[2], machine_data->dummy_ad->paddr); |
| 436 | /* close AOI 1 */ | 446 | /* close AOI 1 */ |
| 437 | break; | 447 | break; |
| 438 | default: | 448 | default: |
| @@ -1100,6 +1110,10 @@ static int fsl_diu_open(struct fb_info *info, int user) | |||
| 1100 | struct mfb_info *mfbi = info->par; | 1110 | struct mfb_info *mfbi = info->par; |
| 1101 | int res = 0; | 1111 | int res = 0; |
| 1102 | 1112 | ||
| 1113 | /* free boot splash memory on first /dev/fb0 open */ | ||
| 1114 | if (!mfbi->index && diu_ops.release_bootmem) | ||
| 1115 | diu_ops.release_bootmem(); | ||
| 1116 | |||
| 1103 | spin_lock(&diu_lock); | 1117 | spin_lock(&diu_lock); |
| 1104 | mfbi->count++; | 1118 | mfbi->count++; |
| 1105 | if (mfbi->count == 1) { | 1119 | if (mfbi->count == 1) { |
| @@ -1173,18 +1187,30 @@ static int __devinit install_fb(struct fb_info *info) | |||
| 1173 | int rc; | 1187 | int rc; |
| 1174 | struct mfb_info *mfbi = info->par; | 1188 | struct mfb_info *mfbi = info->par; |
| 1175 | const char *aoi_mode, *init_aoi_mode = "320x240"; | 1189 | const char *aoi_mode, *init_aoi_mode = "320x240"; |
| 1190 | struct fb_videomode *db = fsl_diu_mode_db; | ||
| 1191 | unsigned int dbsize = ARRAY_SIZE(fsl_diu_mode_db); | ||
| 1192 | int has_default_mode = 1; | ||
| 1176 | 1193 | ||
| 1177 | if (init_fbinfo(info)) | 1194 | if (init_fbinfo(info)) |
| 1178 | return -EINVAL; | 1195 | return -EINVAL; |
| 1179 | 1196 | ||
| 1180 | if (mfbi->index == 0) /* plane 0 */ | 1197 | if (mfbi->index == 0) { /* plane 0 */ |
| 1198 | if (mfbi->edid_data) { | ||
| 1199 | /* Now build modedb from EDID */ | ||
| 1200 | fb_edid_to_monspecs(mfbi->edid_data, &info->monspecs); | ||
| 1201 | fb_videomode_to_modelist(info->monspecs.modedb, | ||
| 1202 | info->monspecs.modedb_len, | ||
| 1203 | &info->modelist); | ||
| 1204 | db = info->monspecs.modedb; | ||
| 1205 | dbsize = info->monspecs.modedb_len; | ||
| 1206 | } | ||
| 1181 | aoi_mode = fb_mode; | 1207 | aoi_mode = fb_mode; |
| 1182 | else | 1208 | } else { |
| 1183 | aoi_mode = init_aoi_mode; | 1209 | aoi_mode = init_aoi_mode; |
| 1210 | } | ||
| 1184 | pr_debug("mode used = %s\n", aoi_mode); | 1211 | pr_debug("mode used = %s\n", aoi_mode); |
| 1185 | rc = fb_find_mode(&info->var, info, aoi_mode, fsl_diu_mode_db, | 1212 | rc = fb_find_mode(&info->var, info, aoi_mode, db, dbsize, |
| 1186 | ARRAY_SIZE(fsl_diu_mode_db), &fsl_diu_default_mode, default_bpp); | 1213 | &fsl_diu_default_mode, default_bpp); |
| 1187 | |||
| 1188 | switch (rc) { | 1214 | switch (rc) { |
| 1189 | case 1: | 1215 | case 1: |
| 1190 | pr_debug("using mode specified in @mode\n"); | 1216 | pr_debug("using mode specified in @mode\n"); |
| @@ -1202,10 +1228,50 @@ static int __devinit install_fb(struct fb_info *info) | |||
| 1202 | default: | 1228 | default: |
| 1203 | pr_debug("rc = %d\n", rc); | 1229 | pr_debug("rc = %d\n", rc); |
| 1204 | pr_debug("failed to find mode\n"); | 1230 | pr_debug("failed to find mode\n"); |
| 1205 | return -EINVAL; | 1231 | /* |
| 1232 | * For plane 0 we continue and look into | ||
| 1233 | * driver's internal modedb. | ||
| 1234 | */ | ||
| 1235 | if (mfbi->index == 0 && mfbi->edid_data) | ||
| 1236 | has_default_mode = 0; | ||
| 1237 | else | ||
| 1238 | return -EINVAL; | ||
| 1206 | break; | 1239 | break; |
| 1207 | } | 1240 | } |
| 1208 | 1241 | ||
| 1242 | if (!has_default_mode) { | ||
| 1243 | rc = fb_find_mode(&info->var, info, aoi_mode, fsl_diu_mode_db, | ||
| 1244 | ARRAY_SIZE(fsl_diu_mode_db), | ||
| 1245 | &fsl_diu_default_mode, | ||
| 1246 | default_bpp); | ||
| 1247 | if (rc > 0 && rc < 5) | ||
| 1248 | has_default_mode = 1; | ||
| 1249 | } | ||
| 1250 | |||
| 1251 | /* Still not found, use preferred mode from database if any */ | ||
| 1252 | if (!has_default_mode && info->monspecs.modedb) { | ||
| 1253 | struct fb_monspecs *specs = &info->monspecs; | ||
| 1254 | struct fb_videomode *modedb = &specs->modedb[0]; | ||
| 1255 | |||
| 1256 | /* | ||
| 1257 | * Get preferred timing. If not found, | ||
| 1258 | * first mode in database will be used. | ||
| 1259 | */ | ||
| 1260 | if (specs->misc & FB_MISC_1ST_DETAIL) { | ||
| 1261 | int i; | ||
| 1262 | |||
| 1263 | for (i = 0; i < specs->modedb_len; i++) { | ||
| 1264 | if (specs->modedb[i].flag & FB_MODE_IS_FIRST) { | ||
| 1265 | modedb = &specs->modedb[i]; | ||
| 1266 | break; | ||
| 1267 | } | ||
| 1268 | } | ||
| 1269 | } | ||
| 1270 | |||
| 1271 | info->var.bits_per_pixel = default_bpp; | ||
| 1272 | fb_videomode_to_var(&info->var, modedb); | ||
| 1273 | } | ||
| 1274 | |||
| 1209 | pr_debug("xres_virtual %d\n", info->var.xres_virtual); | 1275 | pr_debug("xres_virtual %d\n", info->var.xres_virtual); |
| 1210 | pr_debug("bits_per_pixel %d\n", info->var.bits_per_pixel); | 1276 | pr_debug("bits_per_pixel %d\n", info->var.bits_per_pixel); |
| 1211 | 1277 | ||
| @@ -1244,6 +1310,9 @@ static void uninstall_fb(struct fb_info *info) | |||
| 1244 | if (!mfbi->registered) | 1310 | if (!mfbi->registered) |
| 1245 | return; | 1311 | return; |
| 1246 | 1312 | ||
| 1313 | if (mfbi->index == 0) | ||
| 1314 | kfree(mfbi->edid_data); | ||
| 1315 | |||
| 1247 | unregister_framebuffer(info); | 1316 | unregister_framebuffer(info); |
| 1248 | unmap_video_memory(info); | 1317 | unmap_video_memory(info); |
| 1249 | if (&info->cmap) | 1318 | if (&info->cmap) |
| @@ -1427,6 +1496,7 @@ static int __devinit fsl_diu_probe(struct of_device *ofdev, | |||
| 1427 | int ret, i, error = 0; | 1496 | int ret, i, error = 0; |
| 1428 | struct resource res; | 1497 | struct resource res; |
| 1429 | struct fsl_diu_data *machine_data; | 1498 | struct fsl_diu_data *machine_data; |
| 1499 | int diu_mode; | ||
| 1430 | 1500 | ||
| 1431 | machine_data = kzalloc(sizeof(struct fsl_diu_data), GFP_KERNEL); | 1501 | machine_data = kzalloc(sizeof(struct fsl_diu_data), GFP_KERNEL); |
| 1432 | if (!machine_data) | 1502 | if (!machine_data) |
| @@ -1443,6 +1513,17 @@ static int __devinit fsl_diu_probe(struct of_device *ofdev, | |||
| 1443 | mfbi = machine_data->fsl_diu_info[i]->par; | 1513 | mfbi = machine_data->fsl_diu_info[i]->par; |
| 1444 | memcpy(mfbi, &mfb_template[i], sizeof(struct mfb_info)); | 1514 | memcpy(mfbi, &mfb_template[i], sizeof(struct mfb_info)); |
| 1445 | mfbi->parent = machine_data; | 1515 | mfbi->parent = machine_data; |
| 1516 | |||
| 1517 | if (mfbi->index == 0) { | ||
| 1518 | const u8 *prop; | ||
| 1519 | int len; | ||
| 1520 | |||
| 1521 | /* Get EDID */ | ||
| 1522 | prop = of_get_property(np, "edid", &len); | ||
| 1523 | if (prop && len == EDID_LENGTH) | ||
| 1524 | mfbi->edid_data = kmemdup(prop, EDID_LENGTH, | ||
| 1525 | GFP_KERNEL); | ||
| 1526 | } | ||
| 1446 | } | 1527 | } |
| 1447 | 1528 | ||
| 1448 | ret = of_address_to_resource(np, 0, &res); | 1529 | ret = of_address_to_resource(np, 0, &res); |
| @@ -1463,7 +1544,9 @@ static int __devinit fsl_diu_probe(struct of_device *ofdev, | |||
| 1463 | goto error2; | 1544 | goto error2; |
| 1464 | } | 1545 | } |
| 1465 | 1546 | ||
| 1466 | out_be32(&dr.diu_reg->diu_mode, 0); /* disable DIU anyway*/ | 1547 | diu_mode = in_be32(&dr.diu_reg->diu_mode); |
| 1548 | if (diu_mode != MFB_MODE1) | ||
| 1549 | out_be32(&dr.diu_reg->diu_mode, 0); /* disable DIU */ | ||
| 1467 | 1550 | ||
| 1468 | /* Get the IRQ of the DIU */ | 1551 | /* Get the IRQ of the DIU */ |
| 1469 | machine_data->irq = irq_of_parse_and_map(np, 0); | 1552 | machine_data->irq = irq_of_parse_and_map(np, 0); |
| @@ -1511,7 +1594,13 @@ static int __devinit fsl_diu_probe(struct of_device *ofdev, | |||
| 1511 | machine_data->dummy_ad->offset_xyd = 0; | 1594 | machine_data->dummy_ad->offset_xyd = 0; |
| 1512 | machine_data->dummy_ad->next_ad = 0; | 1595 | machine_data->dummy_ad->next_ad = 0; |
| 1513 | 1596 | ||
| 1514 | out_be32(&dr.diu_reg->desc[0], machine_data->dummy_ad->paddr); | 1597 | /* |
| 1598 | * Let DIU display splash screen if it was pre-initialized | ||
| 1599 | * by the bootloader, set dummy area descriptor otherwise. | ||
| 1600 | */ | ||
| 1601 | if (diu_mode != MFB_MODE1) | ||
| 1602 | out_be32(&dr.diu_reg->desc[0], machine_data->dummy_ad->paddr); | ||
| 1603 | |||
| 1515 | out_be32(&dr.diu_reg->desc[1], machine_data->dummy_ad->paddr); | 1604 | out_be32(&dr.diu_reg->desc[1], machine_data->dummy_ad->paddr); |
| 1516 | out_be32(&dr.diu_reg->desc[2], machine_data->dummy_ad->paddr); | 1605 | out_be32(&dr.diu_reg->desc[2], machine_data->dummy_ad->paddr); |
| 1517 | 1606 | ||
diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c index 574dc54e12d4..29b5daacc217 100644 --- a/drivers/video/xilinxfb.c +++ b/drivers/video/xilinxfb.c | |||
| @@ -485,6 +485,8 @@ static int __devexit xilinxfb_of_remove(struct of_device *op) | |||
| 485 | /* Match table for of_platform binding */ | 485 | /* Match table for of_platform binding */ |
| 486 | static struct of_device_id xilinxfb_of_match[] __devinitdata = { | 486 | static struct of_device_id xilinxfb_of_match[] __devinitdata = { |
| 487 | { .compatible = "xlnx,xps-tft-1.00.a", }, | 487 | { .compatible = "xlnx,xps-tft-1.00.a", }, |
| 488 | { .compatible = "xlnx,xps-tft-2.00.a", }, | ||
| 489 | { .compatible = "xlnx,xps-tft-2.01.a", }, | ||
| 488 | { .compatible = "xlnx,plb-tft-cntlr-ref-1.00.a", }, | 490 | { .compatible = "xlnx,plb-tft-cntlr-ref-1.00.a", }, |
| 489 | { .compatible = "xlnx,plb-dvi-cntlr-ref-1.00.c", }, | 491 | { .compatible = "xlnx,plb-dvi-cntlr-ref-1.00.c", }, |
| 490 | {}, | 492 | {}, |
diff --git a/drivers/video/fsl-diu-fb.h b/include/linux/fsl-diu-fb.h index fc295d7ea463..fc295d7ea463 100644 --- a/drivers/video/fsl-diu-fb.h +++ b/include/linux/fsl-diu-fb.h | |||
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index e69612cace61..33145408f045 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
| @@ -2264,6 +2264,7 @@ | |||
| 2264 | #define PCI_DEVICE_ID_TDI_EHCI 0x0101 | 2264 | #define PCI_DEVICE_ID_TDI_EHCI 0x0101 |
| 2265 | 2265 | ||
| 2266 | #define PCI_VENDOR_ID_FREESCALE 0x1957 | 2266 | #define PCI_VENDOR_ID_FREESCALE 0x1957 |
| 2267 | #define PCI_DEVICE_ID_MPC8308 0xc006 | ||
| 2267 | #define PCI_DEVICE_ID_MPC8315E 0x00b4 | 2268 | #define PCI_DEVICE_ID_MPC8315E 0x00b4 |
| 2268 | #define PCI_DEVICE_ID_MPC8315 0x00b5 | 2269 | #define PCI_DEVICE_ID_MPC8315 0x00b5 |
| 2269 | #define PCI_DEVICE_ID_MPC8314E 0x00b6 | 2270 | #define PCI_DEVICE_ID_MPC8314E 0x00b6 |
diff --git a/kernel/hw_breakpoint.c b/kernel/hw_breakpoint.c index 7a56b22e0602..71ed3ce29e12 100644 --- a/kernel/hw_breakpoint.c +++ b/kernel/hw_breakpoint.c | |||
| @@ -242,6 +242,17 @@ toggle_bp_slot(struct perf_event *bp, bool enable, enum bp_type_idx type, | |||
| 242 | } | 242 | } |
| 243 | 243 | ||
| 244 | /* | 244 | /* |
| 245 | * Function to perform processor-specific cleanup during unregistration | ||
| 246 | */ | ||
| 247 | __weak void arch_unregister_hw_breakpoint(struct perf_event *bp) | ||
| 248 | { | ||
| 249 | /* | ||
| 250 | * A weak stub function here for those archs that don't define | ||
| 251 | * it inside arch/.../kernel/hw_breakpoint.c | ||
| 252 | */ | ||
| 253 | } | ||
| 254 | |||
| 255 | /* | ||
| 245 | * Contraints to check before allowing this new breakpoint counter: | 256 | * Contraints to check before allowing this new breakpoint counter: |
| 246 | * | 257 | * |
| 247 | * == Non-pinned counter == (Considered as pinned for now) | 258 | * == Non-pinned counter == (Considered as pinned for now) |
| @@ -339,6 +350,7 @@ void release_bp_slot(struct perf_event *bp) | |||
| 339 | { | 350 | { |
| 340 | mutex_lock(&nr_bp_mutex); | 351 | mutex_lock(&nr_bp_mutex); |
| 341 | 352 | ||
| 353 | arch_unregister_hw_breakpoint(bp); | ||
| 342 | __release_bp_slot(bp); | 354 | __release_bp_slot(bp); |
| 343 | 355 | ||
| 344 | mutex_unlock(&nr_bp_mutex); | 356 | mutex_unlock(&nr_bp_mutex); |
