diff options
Diffstat (limited to 'arch/powerpc')
279 files changed, 16612 insertions, 6247 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index e922a88b2bad..a0dd1b0ee483 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -30,6 +30,10 @@ config GENERIC_HARDIRQS bool default y +config IRQ_PER_CPU + bool + default y + config RWSEM_GENERIC_SPINLOCK bool @@ -91,6 +95,10 @@ config GENERIC_TBSYNC default y if PPC32 && SMP default n +config AUDIT_ARCH + bool + default y + config DEFAULT_UIMAGE bool help @@ -336,7 +344,7 @@ config PPC_ISERIES config EMBEDDED6xx bool "Embedded 6xx/7xx/7xxx-based board" - depends on PPC32 && BROKEN + depends on PPC32 && (BROKEN||BROKEN_ON_SMP) config APUS bool "Amiga-APUS" @@ -350,6 +358,7 @@ endchoice config PPC_PSERIES depends on PPC_MULTIPLATFORM && PPC64 bool "IBM pSeries & new (POWER5-based) iSeries" + select MPIC select PPC_I8259 select PPC_RTAS select RTAS_ERROR_LOGGING @@ -359,6 +368,7 @@ config PPC_PSERIES config PPC_CHRP bool "Common Hardware Reference Platform (CHRP) based machines" depends on PPC_MULTIPLATFORM && PPC32 + select MPIC select PPC_I8259 select PPC_INDIRECT_PCI select PPC_RTAS @@ -369,6 +379,7 @@ config PPC_CHRP config PPC_PMAC bool "Apple PowerMac based machines" depends on PPC_MULTIPLATFORM + select MPIC select PPC_INDIRECT_PCI if PPC32 select PPC_MPC106 if PPC32 default y @@ -376,6 +387,7 @@ config PPC_PMAC config PPC_PMAC64 bool depends on PPC_PMAC && POWER4 + select MPIC select U3_DART select MPIC_BROKEN_U3 select GENERIC_TBSYNC @@ -385,6 +397,7 @@ config PPC_PMAC64 config PPC_PREP bool "PowerPC Reference Platform (PReP) based machines" depends on PPC_MULTIPLATFORM && PPC32 && BROKEN + select MPIC select PPC_I8259 select PPC_INDIRECT_PCI select PPC_UDBG_16550 @@ -393,6 +406,7 @@ config PPC_PREP config PPC_MAPLE depends on PPC_MULTIPLATFORM && PPC64 bool "Maple 970FX Evaluation Board" + select MPIC select U3_DART select MPIC_BROKEN_U3 select GENERIC_TBSYNC @@ -403,6 +417,17 @@ config PPC_MAPLE This option enables support for the Maple 970FX Evaluation Board. For more informations, refer to <http://www.970eval.com> +config PPC_PASEMI + depends on PPC_MULTIPLATFORM && PPC64 + bool "PA Semi SoC-based platforms" + default n + select MPIC + select PPC_UDBG_16550 + select GENERIC_TBSYNC + help + This option enables support for PA Semi's PWRficient line + of SoC processors, including PA6T-1682M + config PPC_CELL bool default n @@ -413,12 +438,18 @@ config PPC_CELL_NATIVE default n config PPC_IBM_CELL_BLADE - bool " IBM Cell Blade" + bool "IBM Cell Blade" depends on PPC_MULTIPLATFORM && PPC64 select PPC_CELL_NATIVE select PPC_RTAS select MMIO_NVRAM select PPC_UDBG_16550 + select UDBG_RTAS_CONSOLE + +config UDBG_RTAS_CONSOLE + bool "RTAS based debug console" + depends on PPC_RTAS + default n config XICS depends on PPC_PSERIES @@ -430,11 +461,6 @@ config U3_DART depends on PPC_MULTIPLATFORM && PPC64 default n -config MPIC - depends on PPC_PSERIES || PPC_PMAC || PPC_MAPLE || PPC_CHRP - bool - default y - config PPC_RTAS bool default n @@ -494,7 +520,7 @@ config CPU_FREQ_PMAC config CPU_FREQ_PMAC64 bool "Support for some Apple G5s" - depends on CPU_FREQ && PMAC_SMU && PPC64 + depends on CPU_FREQ && PPC64 select CPU_FREQ_TABLE help This adds support for frequency switching on Apple iMac G5, @@ -557,6 +583,13 @@ config TAU_AVERAGE /proc/cpuinfo. If in doubt, say N here. + +config PPC_TODC + depends on EMBEDDED6xx + bool "Generic Time-of-day Clock (TODC) support" + ---help--- + This adds support for many TODC/RTC chips. + endmenu source arch/powerpc/platforms/embedded6xx/Kconfig @@ -618,16 +651,19 @@ config HOTPLUG_CPU Say N if you are unsure. +config ARCH_ENABLE_MEMORY_HOTPLUG + def_bool y + config KEXEC bool "kexec system call (EXPERIMENTAL)" depends on PPC_MULTIPLATFORM && EXPERIMENTAL help kexec is a system call that implements the ability to shutdown your current kernel, and to start another kernel. It is like a reboot - but it is indepedent of the system firmware. And like a reboot + but it is independent of the system firmware. And like a reboot you can start any kernel with it, not just Linux. - The name comes from the similiarity to the exec system call. + The name comes from the similarity to the exec system call. It is an ongoing process to be certain the hardware in a machine is properly shutdown, so do not be surprised if this code does not @@ -695,11 +731,10 @@ config ARCH_SPARSEMEM_DEFAULT def_bool y depends on SMP && PPC_PSERIES -source "mm/Kconfig" - -config HAVE_ARCH_EARLY_PFN_TO_NID +config ARCH_POPULATES_NODE_MAP def_bool y - depends on NEED_MULTIPLE_NODES + +source "mm/Kconfig" config ARCH_MEMORY_PROBE def_bool y @@ -792,9 +827,16 @@ config GENERIC_ISA_DMA depends on PPC64 || POWER4 || 6xx && !CPM2 default y +config MPIC + bool + default n + +config MPIC_WEIRD + bool + default n + config PPC_I8259 bool - default y if MPC8641_HPCN default n config PPC_INDIRECT_PCI @@ -817,8 +859,10 @@ config MCA bool config PCI - bool "PCI support" if 40x || CPM2 || PPC_83xx || PPC_85xx || PPC_86xx || PPC_MPC52xx || (EMBEDDED && PPC_ISERIES) - default y if !40x && !CPM2 && !8xx && !APUS && !PPC_83xx && !PPC_85xx && !PPC_86xx + bool "PCI support" if 40x || CPM2 || PPC_83xx || PPC_85xx || PPC_86xx \ + || PPC_MPC52xx || (EMBEDDED && PPC_ISERIES) || MPC7448HPC2 + default y if !40x && !CPM2 && !8xx && !APUS && !PPC_83xx \ + && !PPC_85xx && !PPC_86xx default PCI_PERMEDIA if !4xx && !CPM2 && !8xx && APUS default PCI_QSPAN if !4xx && !CPM2 && 8xx help diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug index c69006ae8246..5ad149b47e34 100644 --- a/arch/powerpc/Kconfig.debug +++ b/arch/powerpc/Kconfig.debug @@ -18,6 +18,20 @@ config DEBUG_STACK_USAGE This option will slow down process creation somewhat. +config HCALL_STATS + bool "Hypervisor call instrumentation" + depends on PPC_PSERIES && DEBUG_FS + help + Adds code to keep track of the number of hypervisor calls made and + the amount of time spent in hypervisor callsr. Wall time spent in + each call is always calculated, and if available CPU cycles spent + are also calculated. A directory named hcall_inst is added at the + root of the debugfs filesystem. Within the hcall_inst directory + are files that contain CPU specific call statistics. + + This option will add a small amount of overhead to all hypervisor + calls. + config DEBUGGER bool "Enable debugger hooks" depends on DEBUG_KERNEL @@ -74,6 +88,8 @@ config XMON very early during boot. 'xmon=on' will just enable the xmon debugger hooks. 'xmon=off' will disable the debugger hooks if CONFIG_XMON_DEFAULT is set. + xmon will print a backtrace on the very first invocation. + 'xmon=nobt' will disable this autobacktrace. config XMON_DEFAULT bool "Enable xmon by default" @@ -134,12 +150,19 @@ config PPC_EARLY_DEBUG_G5 help Select this to enable early debugging for Apple G5 machines. -config PPC_EARLY_DEBUG_RTAS +config PPC_EARLY_DEBUG_RTAS_PANEL bool "RTAS Panel" depends on PPC_RTAS help Select this to enable early debugging via the RTAS panel. +config PPC_EARLY_DEBUG_RTAS_CONSOLE + bool "RTAS Console" + depends on PPC_RTAS + select UDBG_RTAS_CONSOLE + help + Select this to enable early debugging via the RTAS console. + config PPC_EARLY_DEBUG_MAPLE bool "Maple real mode" depends on PPC_MAPLE diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index d961bfeed05f..e73774136b55 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -36,11 +36,16 @@ zliblinuxheader := zlib.h zconf.h zutil.h $(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader)) #$(addprefix $(obj)/,main.o): $(addprefix $(obj)/,zlib.h) -src-boot := crt0.S string.S prom.c stdio.c main.c div64.S +src-boot-$(CONFIG_PPC_MULTIPLATFORM) := of.c +src-boot := crt0.S string.S stdio.c main.c div64.S $(src-boot-y) src-boot += $(zlib) src-boot := $(addprefix $(obj)/, $(src-boot)) obj-boot := $(addsuffix .o, $(basename $(src-boot))) +ifeq ($(call cc-option-yn, -fstack-protector),y) +BOOTCFLAGS += -fno-stack-protector +endif + BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj) quiet_cmd_copy_zlib = COPY $@ diff --git a/arch/powerpc/boot/dts/mpc7448hpc2.dts b/arch/powerpc/boot/dts/mpc7448hpc2.dts new file mode 100644 index 000000000000..d7b985e6bd2f --- /dev/null +++ b/arch/powerpc/boot/dts/mpc7448hpc2.dts @@ -0,0 +1,190 @@ +/* + * MPC7448HPC2 (Taiga) board Device Tree Source + * + * Copyright 2006 Freescale Semiconductor Inc. + * 2006 Roy Zang <Roy Zang at freescale.com>. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + + +/ { + model = "mpc7448hpc2"; + compatible = "mpc74xx"; + #address-cells = <1>; + #size-cells = <1>; + linux,phandle = <100>; + + cpus { + #cpus = <1>; + #address-cells = <1>; + #size-cells =<0>; + linux,phandle = <200>; + + PowerPC,7448@0 { + device_type = "cpu"; + reg = <0>; + d-cache-line-size = <20>; // 32 bytes + i-cache-line-size = <20>; // 32 bytes + d-cache-size = <8000>; // L1, 32K bytes + i-cache-size = <8000>; // L1, 32K bytes + timebase-frequency = <0>; // 33 MHz, from uboot + clock-frequency = <0>; // From U-Boot + bus-frequency = <0>; // From U-Boot + 32-bit; + linux,phandle = <201>; + linux,boot-cpu; + }; + }; + + memory { + device_type = "memory"; + linux,phandle = <300>; + reg = <00000000 20000000 // DDR2 512M at 0 + >; + }; + + tsi108@c0000000 { + #address-cells = <1>; + #size-cells = <1>; + #interrupt-cells = <2>; + device_type = "tsi-bridge"; + ranges = <00000000 c0000000 00010000>; + reg = <c0000000 00010000>; + bus-frequency = <0>; + + i2c@7000 { + interrupt-parent = <7400>; + interrupts = <E 0>; + reg = <7000 400>; + device_type = "i2c"; + compatible = "tsi-i2c"; + }; + + mdio@6000 { + device_type = "mdio"; + compatible = "tsi-ethernet"; + + ethernet-phy@6000 { + linux,phandle = <6000>; + interrupt-parent = <7400>; + interrupts = <2 1>; + reg = <6000 50>; + phy-id = <8>; + device_type = "ethernet-phy"; + }; + + ethernet-phy@6400 { + linux,phandle = <6400>; + interrupt-parent = <7400>; + interrupts = <2 1>; + reg = <6000 50>; + phy-id = <9>; + device_type = "ethernet-phy"; + }; + + }; + + ethernet@6200 { + #size-cells = <0>; + device_type = "network"; + model = "TSI-ETH"; + compatible = "tsi-ethernet"; + reg = <6000 200>; + address = [ 00 06 D2 00 00 01 ]; + interrupts = <10 2>; + interrupt-parent = <7400>; + phy-handle = <6000>; + }; + + ethernet@6600 { + #address-cells = <1>; + #size-cells = <0>; + device_type = "network"; + model = "TSI-ETH"; + compatible = "tsi-ethernet"; + reg = <6400 200>; + address = [ 00 06 D2 00 00 02 ]; + interrupts = <11 2>; + interrupt-parent = <7400>; + phy-handle = <6400>; + }; + + serial@7808 { + device_type = "serial"; + compatible = "ns16550"; + reg = <7808 200>; + clock-frequency = <3f6b5a00>; + interrupts = <c 0>; + interrupt-parent = <7400>; + }; + + serial@7c08 { + device_type = "serial"; + compatible = "ns16550"; + reg = <7c08 200>; + clock-frequency = <3f6b5a00>; + interrupts = <d 0>; + interrupt-parent = <7400>; + }; + + pic@7400 { + linux,phandle = <7400>; + clock-frequency = <0>; + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <2>; + reg = <7400 400>; + built-in; + compatible = "chrp,open-pic"; + device_type = "open-pic"; + big-endian; + }; + pci@1000 { + compatible = "tsi10x"; + device_type = "pci"; + linux,phandle = <1000>; + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + reg = <1000 1000>; + bus-range = <0 0>; + ranges = <02000000 0 e0000000 e0000000 0 1A000000 + 01000000 0 00000000 fa000000 0 00010000>; + clock-frequency = <7f28154>; + interrupt-parent = <7400>; + interrupts = <17 2>; + interrupt-map-mask = <f800 0 0 7>; + interrupt-map = < + + /* IDSEL 0x11 */ + 0800 0 0 1 7400 24 0 + 0800 0 0 2 7400 25 0 + 0800 0 0 3 7400 26 0 + 0800 0 0 4 7400 27 0 + + /* IDSEL 0x12 */ + 1000 0 0 1 7400 25 0 + 1000 0 0 2 7400 26 0 + 1000 0 0 3 7400 27 0 + 1000 0 0 4 7400 24 0 + + /* IDSEL 0x13 */ + 1800 0 0 1 7400 26 0 + 1800 0 0 2 7400 27 0 + 1800 0 0 3 7400 24 0 + 1800 0 0 4 7400 25 0 + + /* IDSEL 0x14 */ + 2000 0 0 1 7400 27 0 + 2000 0 0 2 7400 24 0 + 2000 0 0 3 7400 25 0 + 2000 0 0 4 7400 26 0 + >; + }; + }; + +}; diff --git a/arch/powerpc/boot/dts/mpc8349emds.dts b/arch/powerpc/boot/dts/mpc8349emds.dts new file mode 100644 index 000000000000..efceb3432653 --- /dev/null +++ b/arch/powerpc/boot/dts/mpc8349emds.dts @@ -0,0 +1,328 @@ +/* + * MPC8349E MDS Device Tree Source + * + * Copyright 2005, 2006 Freescale Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +/ { + model = "MPC8349EMDS"; + compatible = "MPC834xMDS"; + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #cpus = <1>; + #address-cells = <1>; + #size-cells = <0>; + + PowerPC,8349@0 { + device_type = "cpu"; + reg = <0>; + d-cache-line-size = <20>; // 32 bytes + i-cache-line-size = <20>; // 32 bytes + d-cache-size = <8000>; // L1, 32K + i-cache-size = <8000>; // L1, 32K + timebase-frequency = <0>; // from bootloader + bus-frequency = <0>; // from bootloader + clock-frequency = <0>; // from bootloader + 32-bit; + }; + }; + + memory { + device_type = "memory"; + reg = <00000000 10000000>; // 256MB at 0 + }; + + soc8349@e0000000 { + #address-cells = <1>; + #size-cells = <1>; + #interrupt-cells = <2>; + device_type = "soc"; + ranges = <0 e0000000 00100000>; + reg = <e0000000 00000200>; + bus-frequency = <0>; + + wdt@200 { + device_type = "watchdog"; + compatible = "mpc83xx_wdt"; + reg = <200 100>; + }; + + i2c@3000 { + device_type = "i2c"; + compatible = "fsl-i2c"; + reg = <3000 100>; + interrupts = <e 8>; + interrupt-parent = <700>; + dfsrr; + }; + + i2c@3100 { + device_type = "i2c"; + compatible = "fsl-i2c"; + reg = <3100 100>; + interrupts = <f 8>; + interrupt-parent = <700>; + dfsrr; + }; + + spi@7000 { + device_type = "spi"; + compatible = "mpc83xx_spi"; + reg = <7000 1000>; + interrupts = <10 8>; + interrupt-parent = <700>; + mode = <0>; + }; + + /* phy type (ULPI or SERIAL) are only types supportted for MPH */ + /* port = 0 or 1 */ + usb@22000 { + device_type = "usb"; + compatible = "fsl-usb2-mph"; + reg = <22000 1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupt-parent = <700>; + interrupts = <27 2>; + phy_type = "ulpi"; + port1; + }; + /* phy type (ULPI, UTMI, UTMI_WIDE, SERIAL) */ + usb@23000 { + device_type = "usb"; + compatible = "fsl-usb2-dr"; + reg = <23000 1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupt-parent = <700>; + interrupts = <26 2>; + phy_type = "ulpi"; + }; + + mdio@24520 { + device_type = "mdio"; + compatible = "gianfar"; + reg = <24520 20>; + #address-cells = <1>; + #size-cells = <0>; + linux,phandle = <24520>; + ethernet-phy@0 { + linux,phandle = <2452000>; + interrupt-parent = <700>; + interrupts = <11 2>; + reg = <0>; + device_type = "ethernet-phy"; + }; + ethernet-phy@1 { + linux,phandle = <2452001>; + interrupt-parent = <700>; + interrupts = <12 2>; + reg = <1>; + device_type = "ethernet-phy"; + }; + }; + + ethernet@24000 { + device_type = "network"; + model = "TSEC"; + compatible = "gianfar"; + reg = <24000 1000>; + address = [ 00 00 00 00 00 00 ]; + local-mac-address = [ 00 00 00 00 00 00 ]; + interrupts = <20 8 21 8 22 8>; + interrupt-parent = <700>; + phy-handle = <2452000>; + }; + + ethernet@25000 { + #address-cells = <1>; + #size-cells = <0>; + device_type = "network"; + model = "TSEC"; + compatible = "gianfar"; + reg = <25000 1000>; + address = [ 00 00 00 00 00 00 ]; + local-mac-address = [ 00 00 00 00 00 00 ]; + interrupts = <23 8 24 8 25 8>; + interrupt-parent = <700>; + phy-handle = <2452001>; + }; + + serial@4500 { + device_type = "serial"; + compatible = "ns16550"; + reg = <4500 100>; + clock-frequency = <0>; + interrupts = <9 8>; + interrupt-parent = <700>; + }; + + serial@4600 { + device_type = "serial"; + compatible = "ns16550"; + reg = <4600 100>; + clock-frequency = <0>; + interrupts = <a 8>; + interrupt-parent = <700>; + }; + + pci@8500 { + interrupt-map-mask = <f800 0 0 7>; + interrupt-map = < + + /* IDSEL 0x11 */ + 8800 0 0 1 700 14 8 + 8800 0 0 2 700 15 8 + 8800 0 0 3 700 16 8 + 8800 0 0 4 700 17 8 + + /* IDSEL 0x12 */ + 9000 0 0 1 700 16 8 + 9000 0 0 2 700 17 8 + 9000 0 0 3 700 14 8 + 9000 0 0 4 700 15 8 + + /* IDSEL 0x13 */ + 9800 0 0 1 700 17 8 + 9800 0 0 2 700 14 8 + 9800 0 0 3 700 15 8 + 9800 0 0 4 700 16 8 + + /* IDSEL 0x15 */ + a800 0 0 1 700 14 8 + a800 0 0 2 700 15 8 + a800 0 0 3 700 16 8 + a800 0 0 4 700 17 8 + + /* IDSEL 0x16 */ + b000 0 0 1 700 17 8 + b000 0 0 2 700 14 8 + b000 0 0 3 700 15 8 + b000 0 0 4 700 16 8 + + /* IDSEL 0x17 */ + b800 0 0 1 700 16 8 + b800 0 0 2 700 17 8 + b800 0 0 3 700 14 8 + b800 0 0 4 700 15 8 + + /* IDSEL 0x18 */ + c000 0 0 1 700 15 8 + c000 0 0 2 700 16 8 + c000 0 0 3 700 17 8 + c000 0 0 4 700 14 8>; + interrupt-parent = <700>; + interrupts = <42 8>; + bus-range = <0 0>; + ranges = <02000000 0 a0000000 a0000000 0 10000000 + 42000000 0 80000000 80000000 0 10000000 + 01000000 0 00000000 e2000000 0 00100000>; + clock-frequency = <3f940aa>; + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + reg = <8500 100>; + compatible = "83xx"; + device_type = "pci"; + }; + + pci@8600 { + interrupt-map-mask = <f800 0 0 7>; + interrupt-map = < + + /* IDSEL 0x11 */ + 8800 0 0 1 700 14 8 + 8800 0 0 2 700 15 8 + 8800 0 0 3 700 16 8 + 8800 0 0 4 700 17 8 + + /* IDSEL 0x12 */ + 9000 0 0 1 700 16 8 + 9000 0 0 2 700 17 8 + 9000 0 0 3 700 14 8 + 9000 0 0 4 700 15 8 + + /* IDSEL 0x13 */ + 9800 0 0 1 700 17 8 + 9800 0 0 2 700 14 8 + 9800 0 0 3 700 15 8 + 9800 0 0 4 700 16 8 + + /* IDSEL 0x15 */ + a800 0 0 1 700 14 8 + a800 0 0 2 700 15 8 + a800 0 0 3 700 16 8 + a800 0 0 4 700 17 8 + + /* IDSEL 0x16 */ + b000 0 0 1 700 17 8 + b000 0 0 2 700 14 8 + b000 0 0 3 700 15 8 + b000 0 0 4 700 16 8 + + /* IDSEL 0x17 */ + b800 0 0 1 700 16 8 + b800 0 0 2 700 17 8 + b800 0 0 3 700 14 8 + b800 0 0 4 700 15 8 + + /* IDSEL 0x18 */ + c000 0 0 1 700 15 8 + c000 0 0 2 700 16 8 + c000 0 0 3 700 17 8 + c000 0 0 4 700 14 8>; + interrupt-parent = <700>; + interrupts = <42 8>; + bus-range = <0 0>; + ranges = <02000000 0 b0000000 b0000000 0 10000000 + 42000000 0 90000000 90000000 0 10000000 + 01000000 0 00000000 e2100000 0 00100000>; + clock-frequency = <3f940aa>; + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + reg = <8600 100>; + compatible = "83xx"; + device_type = "pci"; + }; + + /* May need to remove if on a part without crypto engine */ + crypto@30000 { + device_type = "crypto"; + model = "SEC2"; + compatible = "talitos"; + reg = <30000 10000>; + interrupts = <b 8>; + interrupt-parent = <700>; + num-channels = <4>; + channel-fifo-len = <18>; + exec-units-mask = <0000007e>; + /* desc mask is for rev2.0, + * we need runtime fixup for >2.0 */ + descriptor-types-mask = <01010ebf>; + }; + + /* IPIC + * interrupts cell = <intr #, sense> + * sense values match linux IORESOURCE_IRQ_* defines: + * sense == 8: Level, low assertion + * sense == 2: Edge, high-to-low change + */ + pic@700 { + linux,phandle = <700>; + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <2>; + reg = <700 100>; + built-in; + device_type = "ipic"; + }; + }; +}; diff --git a/arch/powerpc/boot/dts/mpc8540ads.dts b/arch/powerpc/boot/dts/mpc8540ads.dts new file mode 100644 index 000000000000..5f41c1f7a5f3 --- /dev/null +++ b/arch/powerpc/boot/dts/mpc8540ads.dts @@ -0,0 +1,257 @@ +/* + * MPC8540 ADS Device Tree Source + * + * Copyright 2006 Freescale Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + + +/ { + model = "MPC8540ADS"; + compatible = "MPC85xxADS"; + #address-cells = <1>; + #size-cells = <1>; + linux,phandle = <100>; + + cpus { + #cpus = <1>; + #address-cells = <1>; + #size-cells = <0>; + linux,phandle = <200>; + + PowerPC,8540@0 { + device_type = "cpu"; + reg = <0>; + d-cache-line-size = <20>; // 32 bytes + i-cache-line-size = <20>; // 32 bytes + d-cache-size = <8000>; // L1, 32K + i-cache-size = <8000>; // L1, 32K + timebase-frequency = <0>; // 33 MHz, from uboot + bus-frequency = <0>; // 166 MHz + clock-frequency = <0>; // 825 MHz, from uboot + 32-bit; + linux,phandle = <201>; + }; + }; + + memory { + device_type = "memory"; + linux,phandle = <300>; + reg = <00000000 08000000>; // 128M at 0x0 + }; + + soc8540@e0000000 { + #address-cells = <1>; + #size-cells = <1>; + #interrupt-cells = <2>; + device_type = "soc"; + ranges = <0 e0000000 00100000>; + reg = <e0000000 00100000>; // CCSRBAR 1M + bus-frequency = <0>; + + i2c@3000 { + device_type = "i2c"; + compatible = "fsl-i2c"; + reg = <3000 100>; + interrupts = <1b 2>; + interrupt-parent = <40000>; + dfsrr; + }; + + mdio@24520 { + #address-cells = <1>; + #size-cells = <0>; + device_type = "mdio"; + compatible = "gianfar"; + reg = <24520 20>; + linux,phandle = <24520>; + ethernet-phy@0 { + linux,phandle = <2452000>; + interrupt-parent = <40000>; + interrupts = <35 1>; + reg = <0>; + device_type = "ethernet-phy"; + }; + ethernet-phy@1 { + linux,phandle = <2452001>; + interrupt-parent = <40000>; + interrupts = <35 1>; + reg = <1>; + device_type = "ethernet-phy"; + }; + ethernet-phy@3 { + linux,phandle = <2452003>; + interrupt-parent = <40000>; + interrupts = <37 1>; + reg = <3>; + device_type = "ethernet-phy"; + }; + }; + + ethernet@24000 { + #address-cells = <1>; + #size-cells = <0>; + device_type = "network"; + model = "TSEC"; + compatible = "gianfar"; + reg = <24000 1000>; + address = [ 00 E0 0C 00 73 00 ]; + local-mac-address = [ 00 E0 0C 00 73 00 ]; + interrupts = <d 2 e 2 12 2>; + interrupt-parent = <40000>; + phy-handle = <2452000>; + }; + + ethernet@25000 { + #address-cells = <1>; + #size-cells = <0>; + device_type = "network"; + model = "TSEC"; + compatible = "gianfar"; + reg = <25000 1000>; + address = [ 00 E0 0C 00 73 01 ]; + local-mac-address = [ 00 E0 0C 00 73 01 ]; + interrupts = <13 2 14 2 18 2>; + interrupt-parent = <40000>; + phy-handle = <2452001>; + }; + + ethernet@26000 { + #address-cells = <1>; + #size-cells = <0>; + device_type = "network"; + model = "FEC"; + compatible = "gianfar"; + reg = <26000 1000>; + address = [ 00 E0 0C 00 73 02 ]; + local-mac-address = [ 00 E0 0C 00 73 02 ]; + interrupts = <19 2>; + interrupt-parent = <40000>; + phy-handle = <2452003>; + }; + + serial@4500 { + device_type = "serial"; + compatible = "ns16550"; + reg = <4500 100>; // reg base, size + clock-frequency = <0>; // should we fill in in uboot? + interrupts = <1a 2>; + interrupt-parent = <40000>; + }; + + serial@4600 { + device_type = "serial"; + compatible = "ns16550"; + reg = <4600 100>; // reg base, size + clock-frequency = <0>; // should we fill in in uboot? + interrupts = <1a 2>; + interrupt-parent = <40000>; + }; + pci@8000 { + linux,phandle = <8000>; + interrupt-map-mask = <f800 0 0 7>; + interrupt-map = < + + /* IDSEL 0x02 */ + 1000 0 0 1 40000 31 1 + 1000 0 0 2 40000 32 1 + 1000 0 0 3 40000 33 1 + 1000 0 0 4 40000 34 1 + + /* IDSEL 0x03 */ + 1800 0 0 1 40000 34 1 + 1800 0 0 2 40000 31 1 + 1800 0 0 3 40000 32 1 + 1800 0 0 4 40000 33 1 + + /* IDSEL 0x04 */ + 2000 0 0 1 40000 33 1 + 2000 0 0 2 40000 34 1 + 2000 0 0 3 40000 31 1 + 2000 0 0 4 40000 32 1 + + /* IDSEL 0x05 */ + 2800 0 0 1 40000 32 1 + 2800 0 0 2 40000 33 1 + 2800 0 0 3 40000 34 1 + 2800 0 0 4 40000 31 1 + + /* IDSEL 0x0c */ + 6000 0 0 1 40000 31 1 + 6000 0 0 2 40000 32 1 + 6000 0 0 3 40000 33 1 + 6000 0 0 4 40000 34 1 + + /* IDSEL 0x0d */ + 6800 0 0 1 40000 34 1 + 6800 0 0 2 40000 31 1 + 6800 0 0 3 40000 32 1 + 6800 0 0 4 40000 33 1 + + /* IDSEL 0x0e */ + 7000 0 0 1 40000 33 1 + 7000 0 0 2 40000 34 1 + 7000 0 0 3 40000 31 1 + 7000 0 0 4 40000 32 1 + + /* IDSEL 0x0f */ + 7800 0 0 1 40000 32 1 + 7800 0 0 2 40000 33 1 + 7800 0 0 3 40000 34 1 + 7800 0 0 4 40000 31 1 + + /* IDSEL 0x12 */ + 9000 0 0 1 40000 31 1 + 9000 0 0 2 40000 32 1 + 9000 0 0 3 40000 33 1 + 9000 0 0 4 40000 34 1 + + /* IDSEL 0x13 */ + 9800 0 0 1 40000 34 1 + 9800 0 0 2 40000 31 1 + 9800 0 0 3 40000 32 1 + 9800 0 0 4 40000 33 1 + + /* IDSEL 0x14 */ + a000 0 0 1 40000 33 1 + a000 0 0 2 40000 34 1 + a000 0 0 3 40000 31 1 + a000 0 0 4 40000 32 1 + + /* IDSEL 0x15 */ + a800 0 0 1 40000 32 1 + a800 0 0 2 40000 33 1 + a800 0 0 3 40000 34 1 + a800 0 0 4 40000 31 1>; + interrupt-parent = <40000>; + interrupts = <08 2>; + bus-range = <0 0>; + ranges = <02000000 0 80000000 80000000 0 20000000 + 01000000 0 00000000 e2000000 0 00100000>; + clock-frequency = <3f940aa>; + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + reg = <8000 1000>; + compatible = "85xx"; + device_type = "pci"; + }; + + pic@40000 { + linux,phandle = <40000>; + clock-frequency = <0>; + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <2>; + reg = <40000 40000>; + built-in; + compatible = "chrp,open-pic"; + device_type = "open-pic"; + big-endian; + }; + }; +}; diff --git a/arch/powerpc/boot/dts/mpc8541cds.dts b/arch/powerpc/boot/dts/mpc8541cds.dts new file mode 100644 index 000000000000..7be0bc659e1c --- /dev/null +++ b/arch/powerpc/boot/dts/mpc8541cds.dts @@ -0,0 +1,244 @@ +/* + * MPC8541 CDS Device Tree Source + * + * Copyright 2006 Freescale Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + + +/ { + model = "MPC8541CDS"; + compatible = "MPC85xxCDS"; + #address-cells = <1>; + #size-cells = <1>; + linux,phandle = <100>; + + cpus { + #cpus = <1>; + #address-cells = <1>; + #size-cells = <0>; + linux,phandle = <200>; + + PowerPC,8541@0 { + device_type = "cpu"; + reg = <0>; + d-cache-line-size = <20>; // 32 bytes + i-cache-line-size = <20>; // 32 bytes + d-cache-size = <8000>; // L1, 32K + i-cache-size = <8000>; // L1, 32K + timebase-frequency = <0>; // 33 MHz, from uboot + bus-frequency = <0>; // 166 MHz + clock-frequency = <0>; // 825 MHz, from uboot + 32-bit; + linux,phandle = <201>; + }; + }; + + memory { + device_type = "memory"; + linux,phandle = <300>; + reg = <00000000 08000000>; // 128M at 0x0 + }; + + soc8541@e0000000 { + #address-cells = <1>; + #size-cells = <1>; + #interrupt-cells = <2>; + device_type = "soc"; + ranges = <0 e0000000 00100000>; + reg = <e0000000 00100000>; // CCSRBAR 1M + bus-frequency = <0>; + + i2c@3000 { + device_type = "i2c"; + compatible = "fsl-i2c"; + reg = <3000 100>; + interrupts = <1b 2>; + interrupt-parent = <40000>; + dfsrr; + }; + + mdio@24520 { + #address-cells = <1>; + #size-cells = <0>; + device_type = "mdio"; + compatible = "gianfar"; + reg = <24520 20>; + linux,phandle = <24520>; + ethernet-phy@0 { + linux,phandle = <2452000>; + interrupt-parent = <40000>; + interrupts = <35 0>; + reg = <0>; + device_type = "ethernet-phy"; + }; + ethernet-phy@1 { + linux,phandle = <2452001>; + interrupt-parent = <40000>; + interrupts = <35 0>; + reg = <1>; + device_type = "ethernet-phy"; + }; + }; + + ethernet@24000 { + #address-cells = <1>; + #size-cells = <0>; + device_type = "network"; + model = "TSEC"; + compatible = "gianfar"; + reg = <24000 1000>; + local-mac-address = [ 00 E0 0C 00 73 00 ]; + interrupts = <d 2 e 2 12 2>; + interrupt-parent = <40000>; + phy-handle = <2452000>; + }; + + ethernet@25000 { + #address-cells = <1>; + #size-cells = <0>; + device_type = "network"; + model = "TSEC"; + compatible = "gianfar"; + reg = <25000 1000>; + local-mac-address = [ 00 E0 0C 00 73 01 ]; + interrupts = <13 2 14 2 18 2>; + interrupt-parent = <40000>; + phy-handle = <2452001>; + }; + + serial@4500 { + device_type = "serial"; + compatible = "ns16550"; + reg = <4500 100>; // reg base, size + clock-frequency = <0>; // should we fill in in uboot? + interrupts = <1a 2>; + interrupt-parent = <40000>; + }; + + serial@4600 { + device_type = "serial"; + compatible = "ns16550"; + reg = <4600 100>; // reg base, size + clock-frequency = <0>; // should we fill in in uboot? + interrupts = <1a 2>; + interrupt-parent = <40000>; + }; + + pci@8000 { + linux,phandle = <8000>; + interrupt-map-mask = <1f800 0 0 7>; + interrupt-map = < + + /* IDSEL 0x10 */ + 08000 0 0 1 40000 30 1 + 08000 0 0 2 40000 31 1 + 08000 0 0 3 40000 32 1 + 08000 0 0 4 40000 33 1 + + /* IDSEL 0x11 */ + 08800 0 0 1 40000 30 1 + 08800 0 0 2 40000 31 1 + 08800 0 0 3 40000 32 1 + 08800 0 0 4 40000 33 1 + + /* IDSEL 0x12 (Slot 1) */ + 09000 0 0 1 40000 30 1 + 09000 0 0 2 40000 31 1 + 09000 0 0 3 40000 32 1 + 09000 0 0 4 40000 33 1 + + /* IDSEL 0x13 (Slot 2) */ + 09800 0 0 1 40000 31 1 + 09800 0 0 2 40000 32 1 + 09800 0 0 3 40000 33 1 + 09800 0 0 4 40000 30 1 + + /* IDSEL 0x14 (Slot 3) */ + 0a000 0 0 1 40000 32 1 + 0a000 0 0 2 40000 33 1 + 0a000 0 0 3 40000 30 1 + 0a000 0 0 4 40000 31 1 + + /* IDSEL 0x15 (Slot 4) */ + 0a800 0 0 1 40000 33 1 + 0a800 0 0 2 40000 30 1 + 0a800 0 0 3 40000 31 1 + 0a800 0 0 4 40000 32 1 + + /* Bus 1 (Tundra Bridge) */ + /* IDSEL 0x12 (ISA bridge) */ + 19000 0 0 1 40000 30 1 + 19000 0 0 2 40000 31 1 + 19000 0 0 3 40000 32 1 + 19000 0 0 4 40000 33 1>; + interrupt-parent = <40000>; + interrupts = <08 2>; + bus-range = <0 0>; + ranges = <02000000 0 80000000 80000000 0 20000000 + 01000000 0 00000000 e2000000 0 00100000>; + clock-frequency = <3f940aa>; + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + reg = <8000 1000>; + compatible = "85xx"; + device_type = "pci"; + + i8259@19000 { + clock-frequency = <0>; + interrupt-controller; + device_type = "interrupt-controller"; + reg = <19000 0 0 0 1>; + #address-cells = <0>; + #interrupt-cells = <2>; + built-in; + compatible = "chrp,iic"; + big-endian; + interrupts = <1>; + interrupt-parent = <8000>; + }; + }; + + pci@9000 { + linux,phandle = <9000>; + interrupt-map-mask = <f800 0 0 7>; + interrupt-map = < + + /* IDSEL 0x15 */ + a800 0 0 1 40000 3b 1 + a800 0 0 2 40000 3b 1 + a800 0 0 3 40000 3b 1 + a800 0 0 4 40000 3b 1>; + interrupt-parent = <40000>; + interrupts = <09 2>; + bus-range = <0 0>; + ranges = <02000000 0 a0000000 a0000000 0 20000000 + 01000000 0 00000000 e3000000 0 00100000>; + clock-frequency = <3f940aa>; + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + reg = <9000 1000>; + compatible = "85xx"; + device_type = "pci"; + }; + + pic@40000 { + linux,phandle = <40000>; + clock-frequency = <0>; + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <2>; + reg = <40000 40000>; + built-in; + compatible = "chrp,open-pic"; + device_type = "open-pic"; + big-endian; + }; + }; +}; diff --git a/arch/powerpc/boot/dts/mpc8548cds.dts b/arch/powerpc/boot/dts/mpc8548cds.dts new file mode 100644 index 000000000000..893d7957c174 --- /dev/null +++ b/arch/powerpc/boot/dts/mpc8548cds.dts @@ -0,0 +1,287 @@ +/* + * MPC8555 CDS Device Tree Source + * + * Copyright 2006 Freescale Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + + +/ { + model = "MPC8548CDS"; + compatible = "MPC85xxCDS"; + #address-cells = <1>; + #size-cells = <1>; + linux,phandle = <100>; + + cpus { + #cpus = <1>; + #address-cells = <1>; + #size-cells = <0>; + linux,phandle = <200>; + + PowerPC,8548@0 { + device_type = "cpu"; + reg = <0>; + d-cache-line-size = <20>; // 32 bytes + i-cache-line-size = <20>; // 32 bytes + d-cache-size = <8000>; // L1, 32K + i-cache-size = <8000>; // L1, 32K + timebase-frequency = <0>; // 33 MHz, from uboot + bus-frequency = <0>; // 166 MHz + clock-frequency = <0>; // 825 MHz, from uboot + 32-bit; + linux,phandle = <201>; + }; + }; + + memory { + device_type = "memory"; + linux,phandle = <300>; + reg = <00000000 08000000>; // 128M at 0x0 + }; + + soc8548@e0000000 { + #address-cells = <1>; + #size-cells = <1>; + #interrupt-cells = <2>; + device_type = "soc"; + ranges = <0 e0000000 00100000>; + reg = <e0000000 00100000>; // CCSRBAR 1M + bus-frequency = <0>; + + i2c@3000 { + device_type = "i2c"; + compatible = "fsl-i2c"; + reg = <3000 100>; + interrupts = <1b 2>; + interrupt-parent = <40000>; + dfsrr; + }; + + mdio@24520 { + #address-cells = <1>; + #size-cells = <0>; + device_type = "mdio"; + compatible = "gianfar"; + reg = <24520 20>; + linux,phandle = <24520>; + ethernet-phy@0 { + linux,phandle = <2452000>; + interrupt-parent = <40000>; + interrupts = <35 0>; + reg = <0>; + device_type = "ethernet-phy"; + }; + ethernet-phy@1 { + linux,phandle = <2452001>; + interrupt-parent = <40000>; + interrupts = <35 0>; + reg = <1>; + device_type = "ethernet-phy"; + }; + + ethernet-phy@2 { + linux,phandle = <2452002>; + interrupt-parent = <40000>; + interrupts = <35 0>; + reg = <2>; + device_type = "ethernet-phy"; + }; + ethernet-phy@3 { + linux,phandle = <2452003>; + interrupt-parent = <40000>; + interrupts = <35 0>; + reg = <3>; + device_type = "ethernet-phy"; + }; + }; + + ethernet@24000 { + #address-cells = <1>; + #size-cells = <0>; + device_type = "network"; + model = "eTSEC"; + compatible = "gianfar"; + reg = <24000 1000>; + local-mac-address = [ 00 E0 0C 00 73 00 ]; + interrupts = <d 2 e 2 12 2>; + interrupt-parent = <40000>; + phy-handle = <2452000>; + }; + + ethernet@25000 { + #address-cells = <1>; + #size-cells = <0>; + device_type = "network"; + model = "eTSEC"; + compatible = "gianfar"; + reg = <25000 1000>; + local-mac-address = [ 00 E0 0C 00 73 01 ]; + interrupts = <13 2 14 2 18 2>; + interrupt-parent = <40000>; + phy-handle = <2452001>; + }; + + ethernet@26000 { + #address-cells = <1>; + #size-cells = <0>; + device_type = "network"; + model = "eTSEC"; + compatible = "gianfar"; + reg = <26000 1000>; + local-mac-address = [ 00 E0 0C 00 73 02 ]; + interrupts = <f 2 10 2 11 2>; + interrupt-parent = <40000>; + phy-handle = <2452001>; + }; + +/* eTSEC 4 is currently broken + ethernet@27000 { + #address-cells = <1>; + #size-cells = <0>; + device_type = "network"; + model = "eTSEC"; + compatible = "gianfar"; + reg = <27000 1000>; + local-mac-address = [ 00 E0 0C 00 73 03 ]; + interrupts = <15 2 16 2 17 2>; + interrupt-parent = <40000>; + phy-handle = <2452001>; + }; + */ + + serial@4500 { + device_type = "serial"; + compatible = "ns16550"; + reg = <4500 100>; // reg base, size + clock-frequency = <0>; // should we fill in in uboot? + interrupts = <1a 2>; + interrupt-parent = <40000>; + }; + + serial@4600 { + device_type = "serial"; + compatible = "ns16550"; + reg = <4600 100>; // reg base, size + clock-frequency = <0>; // should we fill in in uboot? + interrupts = <1a 2>; + interrupt-parent = <40000>; + }; + + pci@8000 { + linux,phandle = <8000>; + interrupt-map-mask = <1f800 0 0 7>; + interrupt-map = < + + /* IDSEL 0x10 */ + 08000 0 0 1 40000 30 1 + 08000 0 0 2 40000 31 1 + 08000 0 0 3 40000 32 1 + 08000 0 0 4 40000 33 1 + + /* IDSEL 0x11 */ + 08800 0 0 1 40000 30 1 + 08800 0 0 2 40000 31 1 + 08800 0 0 3 40000 32 1 + 08800 0 0 4 40000 33 1 + + /* IDSEL 0x12 (Slot 1) */ + 09000 0 0 1 40000 30 1 + 09000 0 0 2 40000 31 1 + 09000 0 0 3 40000 32 1 + 09000 0 0 4 40000 33 1 + + /* IDSEL 0x13 (Slot 2) */ + 09800 0 0 1 40000 31 1 + 09800 0 0 2 40000 32 1 + 09800 0 0 3 40000 33 1 + 09800 0 0 4 40000 30 1 + + /* IDSEL 0x14 (Slot 3) */ + 0a000 0 0 1 40000 32 1 + 0a000 0 0 2 40000 33 1 + 0a000 0 0 3 40000 30 1 + 0a000 0 0 4 40000 31 1 + + /* IDSEL 0x15 (Slot 4) */ + 0a800 0 0 1 40000 33 1 + 0a800 0 0 2 40000 30 1 + 0a800 0 0 3 40000 31 1 + 0a800 0 0 4 40000 32 1 + + /* Bus 1 (Tundra Bridge) */ + /* IDSEL 0x12 (ISA bridge) */ + 19000 0 0 1 40000 30 1 + 19000 0 0 2 40000 31 1 + 19000 0 0 3 40000 32 1 + 19000 0 0 4 40000 33 1>; + interrupt-parent = <40000>; + interrupts = <08 2>; + bus-range = <0 0>; + ranges = <02000000 0 80000000 80000000 0 20000000 + 01000000 0 00000000 e2000000 0 00100000>; + clock-frequency = <3f940aa>; + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + reg = <8000 1000>; + compatible = "85xx"; + device_type = "pci"; + + i8259@19000 { + clock-frequency = <0>; + interrupt-controller; + device_type = "interrupt-controller"; + reg = <19000 0 0 0 1>; + #address-cells = <0>; + #interrupt-cells = <2>; + built-in; + compatible = "chrp,iic"; + big-endian; + interrupts = <1>; + interrupt-parent = <8000>; + }; + }; + + pci@9000 { + linux,phandle = <9000>; + interrupt-map-mask = <f800 0 0 7>; + interrupt-map = < + + /* IDSEL 0x15 */ + a800 0 0 1 40000 3b 1 + a800 0 0 2 40000 3b 1 + a800 0 0 3 40000 3b 1 + a800 0 0 4 40000 3b 1>; + interrupt-parent = <40000>; + interrupts = <09 2>; + bus-range = <0 0>; + ranges = <02000000 0 a0000000 a0000000 0 20000000 + 01000000 0 00000000 e3000000 0 00100000>; + clock-frequency = <3f940aa>; + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + reg = <9000 1000>; + compatible = "85xx"; + device_type = "pci"; + }; + + pic@40000 { + linux,phandle = <40000>; + clock-frequency = <0>; + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <2>; + reg = <40000 40000>; + built-in; + compatible = "chrp,open-pic"; + device_type = "open-pic"; + big-endian; + }; + }; +}; diff --git a/arch/powerpc/boot/dts/mpc8555cds.dts b/arch/powerpc/boot/dts/mpc8555cds.dts new file mode 100644 index 000000000000..118f5a887651 --- /dev/null +++ b/arch/powerpc/boot/dts/mpc8555cds.dts @@ -0,0 +1,244 @@ +/* + * MPC8555 CDS Device Tree Source + * + * Copyright 2006 Freescale Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + + +/ { + model = "MPC8555CDS"; + compatible = "MPC85xxCDS"; + #address-cells = <1>; + #size-cells = <1>; + linux,phandle = <100>; + + cpus { + #cpus = <1>; + #address-cells = <1>; + #size-cells = <0>; + linux,phandle = <200>; + + PowerPC,8555@0 { + device_type = "cpu"; + reg = <0>; + d-cache-line-size = <20>; // 32 bytes + i-cache-line-size = <20>; // 32 bytes + d-cache-size = <8000>; // L1, 32K + i-cache-size = <8000>; // L1, 32K + timebase-frequency = <0>; // 33 MHz, from uboot + bus-frequency = <0>; // 166 MHz + clock-frequency = <0>; // 825 MHz, from uboot + 32-bit; + linux,phandle = <201>; + }; + }; + + memory { + device_type = "memory"; + linux,phandle = <300>; + reg = <00000000 08000000>; // 128M at 0x0 + }; + + soc8555@e0000000 { + #address-cells = <1>; + #size-cells = <1>; + #interrupt-cells = <2>; + device_type = "soc"; + ranges = <0 e0000000 00100000>; + reg = <e0000000 00100000>; // CCSRBAR 1M + bus-frequency = <0>; + + i2c@3000 { + device_type = "i2c"; + compatible = "fsl-i2c"; + reg = <3000 100>; + interrupts = <1b 2>; + interrupt-parent = <40000>; + dfsrr; + }; + + mdio@24520 { + #address-cells = <1>; + #size-cells = <0>; + device_type = "mdio"; + compatible = "gianfar"; + reg = <24520 20>; + linux,phandle = <24520>; + ethernet-phy@0 { + linux,phandle = <2452000>; + interrupt-parent = <40000>; + interrupts = <35 0>; + reg = <0>; + device_type = "ethernet-phy"; + }; + ethernet-phy@1 { + linux,phandle = <2452001>; + interrupt-parent = <40000>; + interrupts = <35 0>; + reg = <1>; + device_type = "ethernet-phy"; + }; + }; + + ethernet@24000 { + #address-cells = <1>; + #size-cells = <0>; + device_type = "network"; + model = "TSEC"; + compatible = "gianfar"; + reg = <24000 1000>; + local-mac-address = [ 00 E0 0C 00 73 00 ]; + interrupts = <0d 2 0e 2 12 2>; + interrupt-parent = <40000>; + phy-handle = <2452000>; + }; + + ethernet@25000 { + #address-cells = <1>; + #size-cells = <0>; + device_type = "network"; + model = "TSEC"; + compatible = "gianfar"; + reg = <25000 1000>; + local-mac-address = [ 00 E0 0C 00 73 01 ]; + interrupts = <13 2 14 2 18 2>; + interrupt-parent = <40000>; + phy-handle = <2452001>; + }; + + serial@4500 { + device_type = "serial"; + compatible = "ns16550"; + reg = <4500 100>; // reg base, size + clock-frequency = <0>; // should we fill in in uboot? + interrupts = <1a 2>; + interrupt-parent = <40000>; + }; + + serial@4600 { + device_type = "serial"; + compatible = "ns16550"; + reg = <4600 100>; // reg base, size + clock-frequency = <0>; // should we fill in in uboot? + interrupts = <1a 2>; + interrupt-parent = <40000>; + }; + + pci@8000 { + linux,phandle = <8000>; + interrupt-map-mask = <1f800 0 0 7>; + interrupt-map = < + + /* IDSEL 0x10 */ + 08000 0 0 1 40000 30 1 + 08000 0 0 2 40000 31 1 + 08000 0 0 3 40000 32 1 + 08000 0 0 4 40000 33 1 + + /* IDSEL 0x11 */ + 08800 0 0 1 40000 30 1 + 08800 0 0 2 40000 31 1 + 08800 0 0 3 40000 32 1 + 08800 0 0 4 40000 33 1 + + /* IDSEL 0x12 (Slot 1) */ + 09000 0 0 1 40000 30 1 + 09000 0 0 2 40000 31 1 + 09000 0 0 3 40000 32 1 + 09000 0 0 4 40000 33 1 + + /* IDSEL 0x13 (Slot 2) */ + 09800 0 0 1 40000 31 1 + 09800 0 0 2 40000 32 1 + 09800 0 0 3 40000 33 1 + 09800 0 0 4 40000 30 1 + + /* IDSEL 0x14 (Slot 3) */ + 0a000 0 0 1 40000 32 1 + 0a000 0 0 2 40000 33 1 + 0a000 0 0 3 40000 30 1 + 0a000 0 0 4 40000 31 1 + + /* IDSEL 0x15 (Slot 4) */ + 0a800 0 0 1 40000 33 1 + 0a800 0 0 2 40000 30 1 + 0a800 0 0 3 40000 31 1 + 0a800 0 0 4 40000 32 1 + + /* Bus 1 (Tundra Bridge) */ + /* IDSEL 0x12 (ISA bridge) */ + 19000 0 0 1 40000 30 1 + 19000 0 0 2 40000 31 1 + 19000 0 0 3 40000 32 1 + 19000 0 0 4 40000 33 1>; + interrupt-parent = <40000>; + interrupts = <08 2>; + bus-range = <0 0>; + ranges = <02000000 0 80000000 80000000 0 20000000 + 01000000 0 00000000 e2000000 0 00100000>; + clock-frequency = <3f940aa>; + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + reg = <8000 1000>; + compatible = "85xx"; + device_type = "pci"; + + i8259@19000 { + clock-frequency = <0>; + interrupt-controller; + device_type = "interrupt-controller"; + reg = <19000 0 0 0 1>; + #address-cells = <0>; + #interrupt-cells = <2>; + built-in; + compatible = "chrp,iic"; + big-endian; + interrupts = <1>; + interrupt-parent = <8000>; + }; + }; + + pci@9000 { + linux,phandle = <9000>; + interrupt-map-mask = <f800 0 0 7>; + interrupt-map = < + + /* IDSEL 0x15 */ + a800 0 0 1 40000 3b 1 + a800 0 0 2 40000 3b 1 + a800 0 0 3 40000 3b 1 + a800 0 0 4 40000 3b 1>; + interrupt-parent = <40000>; + interrupts = <09 2>; + bus-range = <0 0>; + ranges = <02000000 0 a0000000 a0000000 0 20000000 + 01000000 0 00000000 e3000000 0 00100000>; + clock-frequency = <3f940aa>; + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + reg = <9000 1000>; + compatible = "85xx"; + device_type = "pci"; + }; + + pic@40000 { + linux,phandle = <40000>; + clock-frequency = <0>; + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <2>; + reg = <40000 40000>; + built-in; + compatible = "chrp,open-pic"; + device_type = "open-pic"; + big-endian; + }; + }; +}; diff --git a/arch/powerpc/boot/dts/mpc8641_hpcn.dts b/arch/powerpc/boot/dts/mpc8641_hpcn.dts new file mode 100644 index 000000000000..f0c7731743ea --- /dev/null +++ b/arch/powerpc/boot/dts/mpc8641_hpcn.dts @@ -0,0 +1,339 @@ +/* + * MPC8641 HPCN Device Tree Source + * + * Copyright 2006 Freescale Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + + +/ { + model = "MPC8641HPCN"; + compatible = "mpc86xx"; + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #cpus = <2>; + #address-cells = <1>; + #size-cells = <0>; + + PowerPC,8641@0 { + device_type = "cpu"; + reg = <0>; + d-cache-line-size = <20>; // 32 bytes + i-cache-line-size = <20>; // 32 bytes + d-cache-size = <8000>; // L1, 32K + i-cache-size = <8000>; // L1, 32K + timebase-frequency = <0>; // 33 MHz, from uboot + bus-frequency = <0>; // From uboot + clock-frequency = <0>; // From uboot + 32-bit; + linux,boot-cpu; + }; + PowerPC,8641@1 { + device_type = "cpu"; + reg = <1>; + d-cache-line-size = <20>; // 32 bytes + i-cache-line-size = <20>; // 32 bytes + d-cache-size = <8000>; // L1, 32K + i-cache-size = <8000>; // L1, 32K + timebase-frequency = <0>; // 33 MHz, from uboot + bus-frequency = <0>; // From uboot + clock-frequency = <0>; // From uboot + 32-bit; + }; + }; + + memory { + device_type = "memory"; + reg = <00000000 40000000>; // 1G at 0x0 + }; + + soc8641@f8000000 { + #address-cells = <1>; + #size-cells = <1>; + #interrupt-cells = <2>; + device_type = "soc"; + ranges = <0 f8000000 00100000>; + reg = <f8000000 00100000>; // CCSRBAR 1M + bus-frequency = <0>; + + i2c@3000 { + device_type = "i2c"; + compatible = "fsl-i2c"; + reg = <3000 100>; + interrupts = <2b 2>; + interrupt-parent = <40000>; + dfsrr; + }; + + i2c@3100 { + device_type = "i2c"; + compatible = "fsl-i2c"; + reg = <3100 100>; + interrupts = <2b 2>; + interrupt-parent = <40000>; + dfsrr; + }; + + mdio@24520 { + #address-cells = <1>; + #size-cells = <0>; + device_type = "mdio"; + compatible = "gianfar"; + reg = <24520 20>; + linux,phandle = <24520>; + ethernet-phy@0 { + linux,phandle = <2452000>; + interrupt-parent = <40000>; + interrupts = <4a 1>; + reg = <0>; + device_type = "ethernet-phy"; + }; + ethernet-phy@1 { + linux,phandle = <2452001>; + interrupt-parent = <40000>; + interrupts = <4a 1>; + reg = <1>; + device_type = "ethernet-phy"; + }; + ethernet-phy@2 { + linux,phandle = <2452002>; + interrupt-parent = <40000>; + interrupts = <4a 1>; + reg = <2>; + device_type = "ethernet-phy"; + }; + ethernet-phy@3 { + linux,phandle = <2452003>; + interrupt-parent = <40000>; + interrupts = <4a 1>; + reg = <3>; + device_type = "ethernet-phy"; + }; + }; + + ethernet@24000 { + #address-cells = <1>; + #size-cells = <0>; + device_type = "network"; + model = "TSEC"; + compatible = "gianfar"; + reg = <24000 1000>; + mac-address = [ 00 E0 0C 00 73 00 ]; + interrupts = <1d 2 1e 2 22 2>; + interrupt-parent = <40000>; + phy-handle = <2452000>; + }; + + ethernet@25000 { + #address-cells = <1>; + #size-cells = <0>; + device_type = "network"; + model = "TSEC"; + compatible = "gianfar"; + reg = <25000 1000>; + mac-address = [ 00 E0 0C 00 73 01 ]; + interrupts = <23 2 24 2 28 2>; + interrupt-parent = <40000>; + phy-handle = <2452001>; + }; + + ethernet@26000 { + #address-cells = <1>; + #size-cells = <0>; + device_type = "network"; + model = "TSEC"; + compatible = "gianfar"; + reg = <26000 1000>; + mac-address = [ 00 E0 0C 00 02 FD ]; + interrupts = <1F 2 20 2 21 2>; + interrupt-parent = <40000>; + phy-handle = <2452002>; + }; + + ethernet@27000 { + #address-cells = <1>; + #size-cells = <0>; + device_type = "network"; + model = "TSEC"; + compatible = "gianfar"; + reg = <27000 1000>; + mac-address = [ 00 E0 0C 00 03 FD ]; + interrupts = <25 2 26 2 27 2>; + interrupt-parent = <40000>; + phy-handle = <2452003>; + }; + serial@4500 { + device_type = "serial"; + compatible = "ns16550"; + reg = <4500 100>; + clock-frequency = <0>; + interrupts = <2a 2>; + interrupt-parent = <40000>; + }; + + serial@4600 { + device_type = "serial"; + compatible = "ns16550"; + reg = <4600 100>; + clock-frequency = <0>; + interrupts = <1c 2>; + interrupt-parent = <40000>; + }; + + pci@8000 { + compatible = "86xx"; + device_type = "pci"; + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + reg = <8000 1000>; + bus-range = <0 fe>; + ranges = <02000000 0 80000000 80000000 0 20000000 + 01000000 0 00000000 e2000000 0 00100000>; + clock-frequency = <1fca055>; + interrupt-parent = <40000>; + interrupts = <18 2>; + interrupt-map-mask = <f800 0 0 7>; + interrupt-map = < + /* IDSEL 0x11 */ + 8800 0 0 1 4d0 3 2 + 8800 0 0 2 4d0 4 2 + 8800 0 0 3 4d0 5 2 + 8800 0 0 4 4d0 6 2 + + /* IDSEL 0x12 */ + 9000 0 0 1 4d0 4 2 + 9000 0 0 2 4d0 5 2 + 9000 0 0 3 4d0 6 2 + 9000 0 0 4 4d0 3 2 + + /* IDSEL 0x13 */ + 9800 0 0 1 4d0 0 0 + 9800 0 0 2 4d0 0 0 + 9800 0 0 3 4d0 0 0 + 9800 0 0 4 4d0 0 0 + + /* IDSEL 0x14 */ + a000 0 0 1 4d0 0 0 + a000 0 0 2 4d0 0 0 + a000 0 0 3 4d0 0 0 + a000 0 0 4 4d0 0 0 + + /* IDSEL 0x15 */ + a800 0 0 1 4d0 0 0 + a800 0 0 2 4d0 0 0 + a800 0 0 3 4d0 0 0 + a800 0 0 4 4d0 0 0 + + /* IDSEL 0x16 */ + b000 0 0 1 4d0 0 0 + b000 0 0 2 4d0 0 0 + b000 0 0 3 4d0 0 0 + b000 0 0 4 4d0 0 0 + + /* IDSEL 0x17 */ + b800 0 0 1 4d0 0 0 + b800 0 0 2 4d0 0 0 + b800 0 0 3 4d0 0 0 + b800 0 0 4 4d0 0 0 + + /* IDSEL 0x18 */ + c000 0 0 1 4d0 0 0 + c000 0 0 2 4d0 0 0 + c000 0 0 3 4d0 0 0 + c000 0 0 4 4d0 0 0 + + /* IDSEL 0x19 */ + c800 0 0 1 4d0 0 0 + c800 0 0 2 4d0 0 0 + c800 0 0 3 4d0 0 0 + c800 0 0 4 4d0 0 0 + + /* IDSEL 0x1a */ + d000 0 0 1 4d0 6 2 + d000 0 0 2 4d0 3 2 + d000 0 0 3 4d0 4 2 + d000 0 0 4 4d0 5 2 + + + /* IDSEL 0x1b */ + d800 0 0 1 4d0 5 2 + d800 0 0 2 4d0 0 0 + d800 0 0 3 4d0 0 0 + d800 0 0 4 4d0 0 0 + + /* IDSEL 0x1c */ + e000 0 0 1 4d0 9 2 + e000 0 0 2 4d0 a 2 + e000 0 0 3 4d0 c 2 + e000 0 0 4 4d0 7 2 + + /* IDSEL 0x1d */ + e800 0 0 1 4d0 9 2 + e800 0 0 2 4d0 a 2 + e800 0 0 3 4d0 b 2 + e800 0 0 4 4d0 0 0 + + /* IDSEL 0x1e */ + f000 0 0 1 4d0 c 2 + f000 0 0 2 4d0 0 0 + f000 0 0 3 4d0 0 0 + f000 0 0 4 4d0 0 0 + + /* IDSEL 0x1f */ + f800 0 0 1 4d0 6 2 + f800 0 0 2 4d0 0 0 + f800 0 0 3 4d0 0 0 + f800 0 0 4 4d0 0 0 + >; + i8259@4d0 { + linux,phandle = <4d0>; + clock-frequency = <0>; + interrupt-controller; + device_type = "interrupt-controller"; + #address-cells = <0>; + #interrupt-cells = <2>; + built-in; + compatible = "chrp,iic"; + big-endian; + interrupts = <49 2>; + interrupt-parent = <40000>; + }; + + }; + pic@40000 { + linux,phandle = <40000>; + clock-frequency = <0>; + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <2>; + reg = <40000 40000>; + built-in; + compatible = "chrp,open-pic"; + device_type = "open-pic"; + big-endian; + interrupts = < + 10 2 11 2 12 2 13 2 + 14 2 15 2 16 2 17 2 + 18 2 19 2 1a 2 1b 2 + 1c 2 1d 2 1e 2 1f 2 + 20 2 21 2 22 2 23 2 + 24 2 25 2 26 2 27 2 + 28 2 29 2 2a 2 2b 2 + 2c 2 2d 2 2e 2 2f 2 + 30 2 31 2 32 2 33 2 + 34 2 35 2 36 2 37 2 + 38 2 39 2 2a 2 3b 2 + 3c 2 3d 2 3e 2 3f 2 + 48 1 49 2 4a 1 + >; + interrupt-parent = <40000>; + }; + }; +}; diff --git a/arch/powerpc/boot/flatdevtree.h b/arch/powerpc/boot/flatdevtree.h new file mode 100644 index 000000000000..761c8dc84008 --- /dev/null +++ b/arch/powerpc/boot/flatdevtree.h @@ -0,0 +1,46 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef FLATDEVTREE_H +#define FLATDEVTREE_H + +#include "types.h" + +/* Definitions used by the flattened device tree */ +#define OF_DT_HEADER 0xd00dfeed /* marker */ +#define OF_DT_BEGIN_NODE 0x1 /* Start of node, full name */ +#define OF_DT_END_NODE 0x2 /* End node */ +#define OF_DT_PROP 0x3 /* Property: name off, size, content */ +#define OF_DT_NOP 0x4 /* nop */ +#define OF_DT_END 0x9 + +#define OF_DT_VERSION 0x10 + +struct boot_param_header { + u32 magic; /* magic word OF_DT_HEADER */ + u32 totalsize; /* total size of DT block */ + u32 off_dt_struct; /* offset to structure */ + u32 off_dt_strings; /* offset to strings */ + u32 off_mem_rsvmap; /* offset to memory reserve map */ + u32 version; /* format version */ + u32 last_comp_version; /* last compatible version */ + /* version 2 fields below */ + u32 boot_cpuid_phys; /* Physical CPU id we're booting on */ + /* version 3 fields below */ + u32 dt_strings_size; /* size of the DT strings block */ +}; + +#endif /* FLATDEVTREE_H */ diff --git a/arch/powerpc/boot/main.c b/arch/powerpc/boot/main.c index b66634c9ea34..d719bb9333d1 100644 --- a/arch/powerpc/boot/main.c +++ b/arch/powerpc/boot/main.c @@ -14,17 +14,12 @@ #include "page.h" #include "string.h" #include "stdio.h" -#include "prom.h" #include "zlib.h" +#include "ops.h" +#include "flatdevtree.h" extern void flush_cache(void *, unsigned long); - -/* Value picked to match that used by yaboot */ -#define PROG_START 0x01400000 /* only used on 64-bit systems */ -#define RAM_END (512<<20) /* Fixme: use OF */ -#define ONE_MB 0x100000 - extern char _start[]; extern char __bss_start[]; extern char _end[]; @@ -33,14 +28,6 @@ extern char _vmlinux_end[]; extern char _initrd_start[]; extern char _initrd_end[]; -/* A buffer that may be edited by tools operating on a zImage binary so as to - * edit the command line passed to vmlinux (by setting /chosen/bootargs). - * The buffer is put in it's own section so that tools may locate it easier. - */ -static char builtin_cmdline[512] - __attribute__((section("__builtin_cmdline"))); - - struct addr_range { unsigned long addr; unsigned long size; @@ -51,21 +38,16 @@ static struct addr_range vmlinuz; static struct addr_range initrd; static unsigned long elfoffset; +static int is_64bit; -static char scratch[46912]; /* scratch space for gunzip, from zlib_inflate_workspacesize() */ +/* scratch space for gunzip; 46912 is from zlib_inflate_workspacesize() */ +static char scratch[46912]; static char elfheader[256]; - -typedef void (*kernel_entry_t)( unsigned long, - unsigned long, - void *, - void *); - +typedef void (*kernel_entry_t)(unsigned long, unsigned long, void *); #undef DEBUG -static unsigned long claim_base; - #define HEAD_CRC 2 #define EXTRA_FIELD 4 #define ORIG_NAME 8 @@ -123,24 +105,6 @@ static void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) zlib_inflateEnd(&s); } -static unsigned long try_claim(unsigned long size) -{ - unsigned long addr = 0; - - for(; claim_base < RAM_END; claim_base += ONE_MB) { -#ifdef DEBUG - printf(" trying: 0x%08lx\n\r", claim_base); -#endif - addr = (unsigned long)claim(claim_base, size, 0); - if ((void *)addr != (void *)-1) - break; - } - if (addr == 0) - return 0; - claim_base = PAGE_ALIGN(claim_base + size); - return addr; -} - static int is_elf64(void *hdr) { Elf64_Ehdr *elf64 = hdr; @@ -169,16 +133,7 @@ static int is_elf64(void *hdr) vmlinux.size = (unsigned long)elf64ph->p_filesz + elfoffset; vmlinux.memsize = (unsigned long)elf64ph->p_memsz + elfoffset; -#if defined(PROG_START) - /* - * Maintain a "magic" minimum address. This keeps some older - * firmware platforms running. - */ - - if (claim_base < PROG_START) - claim_base = PROG_START; -#endif - + is_64bit = 1; return 1; } @@ -212,47 +167,9 @@ static int is_elf32(void *hdr) return 1; } -void export_cmdline(void* chosen_handle) -{ - int len; - char cmdline[2] = { 0, 0 }; - - if (builtin_cmdline[0] == 0) - return; - - len = getprop(chosen_handle, "bootargs", cmdline, sizeof(cmdline)); - if (len > 0 && cmdline[0] != 0) - return; - - setprop(chosen_handle, "bootargs", builtin_cmdline, - strlen(builtin_cmdline) + 1); -} - - -void start(unsigned long a1, unsigned long a2, void *promptr, void *sp) +static void prep_kernel(unsigned long *a1, unsigned long *a2) { int len; - kernel_entry_t kernel_entry; - - memset(__bss_start, 0, _end - __bss_start); - - prom = (int (*)(void *)) promptr; - chosen_handle = finddevice("/chosen"); - if (chosen_handle == (void *) -1) - exit(); - if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4) - exit(); - - printf("\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r", _start, sp); - - /* - * The first available claim_base must be above the end of the - * the loaded kernel wrapper file (_start to _end includes the - * initrd image if it is present) and rounded up to a nice - * 1 MB boundary for good measure. - */ - - claim_base = _ALIGN_UP((unsigned long)_end, ONE_MB); vmlinuz.addr = (unsigned long)_vmlinux_start; vmlinuz.size = (unsigned long)(_vmlinux_end - _vmlinux_start); @@ -263,43 +180,51 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp) gunzip(elfheader, sizeof(elfheader), (unsigned char *)vmlinuz.addr, &len); } else - memcpy(elfheader, (const void *)vmlinuz.addr, sizeof(elfheader)); + memcpy(elfheader, (const void *)vmlinuz.addr, + sizeof(elfheader)); if (!is_elf64(elfheader) && !is_elf32(elfheader)) { printf("Error: not a valid PPC32 or PPC64 ELF file!\n\r"); exit(); } + if (platform_ops.image_hdr) + platform_ops.image_hdr(elfheader); - /* We need to claim the memsize plus the file offset since gzip + /* We need to alloc the memsize plus the file offset since gzip * will expand the header (file offset), then the kernel, then * possible rubbish we don't care about. But the kernel bss must * be claimed (it will be zero'd by the kernel itself) */ printf("Allocating 0x%lx bytes for kernel ...\n\r", vmlinux.memsize); - vmlinux.addr = try_claim(vmlinux.memsize); + vmlinux.addr = (unsigned long)malloc(vmlinux.memsize); if (vmlinux.addr == 0) { printf("Can't allocate memory for kernel image !\n\r"); exit(); } /* - * Now we try to claim memory for the initrd (and copy it there) + * Now we try to alloc memory for the initrd (and copy it there) */ initrd.size = (unsigned long)(_initrd_end - _initrd_start); initrd.memsize = initrd.size; if ( initrd.size > 0 ) { - printf("Allocating 0x%lx bytes for initrd ...\n\r", initrd.size); - initrd.addr = try_claim(initrd.size); + printf("Allocating 0x%lx bytes for initrd ...\n\r", + initrd.size); + initrd.addr = (unsigned long)malloc((u32)initrd.size); if (initrd.addr == 0) { - printf("Can't allocate memory for initial ramdisk !\n\r"); + printf("Can't allocate memory for initial " + "ramdisk !\n\r"); exit(); } - a1 = initrd.addr; - a2 = initrd.size; - printf("initial ramdisk moving 0x%lx <- 0x%lx (0x%lx bytes)\n\r", - initrd.addr, (unsigned long)_initrd_start, initrd.size); - memmove((void *)initrd.addr, (void *)_initrd_start, initrd.size); - printf("initrd head: 0x%lx\n\r", *((unsigned long *)initrd.addr)); + *a1 = initrd.addr; + *a2 = initrd.size; + printf("initial ramdisk moving 0x%lx <- 0x%lx " + "(0x%lx bytes)\n\r", initrd.addr, + (unsigned long)_initrd_start, initrd.size); + memmove((void *)initrd.addr, (void *)_initrd_start, + initrd.size); + printf("initrd head: 0x%lx\n\r", + *((unsigned long *)initrd.addr)); } /* Eventually gunzip the kernel */ @@ -311,11 +236,10 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp) (unsigned char *)vmlinuz.addr, &len); printf("done 0x%lx bytes\n\r", len); } else { - memmove((void *)vmlinux.addr,(void *)vmlinuz.addr,vmlinuz.size); + memmove((void *)vmlinux.addr,(void *)vmlinuz.addr, + vmlinuz.size); } - export_cmdline(chosen_handle); - /* Skip over the ELF header */ #ifdef DEBUG printf("... skipping 0x%lx bytes of ELF header\n\r", @@ -324,23 +248,107 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp) vmlinux.addr += elfoffset; flush_cache((void *)vmlinux.addr, vmlinux.size); +} - kernel_entry = (kernel_entry_t)vmlinux.addr; -#ifdef DEBUG - printf( "kernel:\n\r" - " entry addr = 0x%lx\n\r" - " a1 = 0x%lx,\n\r" - " a2 = 0x%lx,\n\r" - " prom = 0x%lx,\n\r" - " bi_recs = 0x%lx,\n\r", - (unsigned long)kernel_entry, a1, a2, - (unsigned long)prom, NULL); -#endif +void __attribute__ ((weak)) ft_init(void *dt_blob) +{ +} - kernel_entry(a1, a2, prom, NULL); +/* A buffer that may be edited by tools operating on a zImage binary so as to + * edit the command line passed to vmlinux (by setting /chosen/bootargs). + * The buffer is put in it's own section so that tools may locate it easier. + */ +static char builtin_cmdline[COMMAND_LINE_SIZE] + __attribute__((__section__("__builtin_cmdline"))); - printf("Error: Linux kernel returned to zImage bootloader!\n\r"); +static void get_cmdline(char *buf, int size) +{ + void *devp; + int len = strlen(builtin_cmdline); - exit(); + buf[0] = '\0'; + + if (len > 0) { /* builtin_cmdline overrides dt's /chosen/bootargs */ + len = min(len, size-1); + strncpy(buf, builtin_cmdline, len); + buf[len] = '\0'; + } + else if ((devp = finddevice("/chosen"))) + getprop(devp, "bootargs", buf, size); +} + +static void set_cmdline(char *buf) +{ + void *devp; + + if ((devp = finddevice("/chosen"))) + setprop(devp, "bootargs", buf, strlen(buf) + 1); } +/* Section where ft can be tacked on after zImage is built */ +union blobspace { + struct boot_param_header hdr; + char space[8*1024]; +} dt_blob __attribute__((__section__("__builtin_ft"))); + +struct platform_ops platform_ops; +struct dt_ops dt_ops; +struct console_ops console_ops; + +void start(unsigned long a1, unsigned long a2, void *promptr, void *sp) +{ + int have_dt = 0; + kernel_entry_t kentry; + char cmdline[COMMAND_LINE_SIZE]; + + memset(__bss_start, 0, _end - __bss_start); + memset(&platform_ops, 0, sizeof(platform_ops)); + memset(&dt_ops, 0, sizeof(dt_ops)); + memset(&console_ops, 0, sizeof(console_ops)); + + /* Override the dt_ops and device tree if there was an flat dev + * tree attached to the zImage. + */ + if (dt_blob.hdr.magic == OF_DT_HEADER) { + have_dt = 1; + ft_init(&dt_blob); + } + + if (platform_init(promptr)) + exit(); + if (console_ops.open && (console_ops.open() < 0)) + exit(); + if (platform_ops.fixups) + platform_ops.fixups(); + + printf("\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r", + _start, sp); + + prep_kernel(&a1, &a2); + + /* If cmdline came from zimage wrapper or if we can edit the one + * in the dt, print it out and edit it, if possible. + */ + if ((strlen(builtin_cmdline) > 0) || console_ops.edit_cmdline) { + get_cmdline(cmdline, COMMAND_LINE_SIZE); + printf("\n\rLinux/PowerPC load: %s", cmdline); + if (console_ops.edit_cmdline) + console_ops.edit_cmdline(cmdline, COMMAND_LINE_SIZE); + printf("\n\r"); + set_cmdline(cmdline); + } + + if (console_ops.close) + console_ops.close(); + + kentry = (kernel_entry_t) vmlinux.addr; + if (have_dt) + kentry(dt_ops.ft_addr(), 0, NULL); + else + /* XXX initrd addr/size should be passed in properties */ + kentry(a1, a2, promptr); + + /* console closed so printf below may not work */ + printf("Error: Linux kernel returned to zImage boot wrapper!\n\r"); + exit(); +} diff --git a/arch/powerpc/boot/prom.c b/arch/powerpc/boot/of.c index fa0057736f6b..fd99f789a37b 100644 --- a/arch/powerpc/boot/prom.c +++ b/arch/powerpc/boot/of.c @@ -8,15 +8,29 @@ */ #include <stdarg.h> #include <stddef.h> +#include "types.h" +#include "elf.h" #include "string.h" #include "stdio.h" -#include "prom.h" +#include "page.h" +#include "ops.h" -int (*prom)(void *); -phandle chosen_handle; -ihandle stdout; +typedef void *ihandle; +typedef void *phandle; -int call_prom(const char *service, int nargs, int nret, ...) +extern char _end[]; + +/* Value picked to match that used by yaboot */ +#define PROG_START 0x01400000 /* only used on 64-bit systems */ +#define RAM_END (512<<20) /* Fixme: use OF */ +#define ONE_MB 0x100000 + +int (*prom) (void *); + + +static unsigned long claim_base; + +static int call_prom(const char *service, int nargs, int nret, ...) { int i; struct prom_args { @@ -45,7 +59,7 @@ int call_prom(const char *service, int nargs, int nret, ...) return (nret > 0)? args.args[nargs]: 0; } -int call_prom_ret(const char *service, int nargs, int nret, +static int call_prom_ret(const char *service, int nargs, int nret, unsigned int *rets, ...) { int i; @@ -79,11 +93,6 @@ int call_prom_ret(const char *service, int nargs, int nret, return (nret > 0)? args.args[nargs]: 0; } -int write(void *handle, void *ptr, int nb) -{ - return call_prom("write", 3, 1, handle, ptr, nb); -} - /* * Older OF's require that when claiming a specific range of addresses, * we claim the physical space in the /memory node and the virtual @@ -142,7 +151,7 @@ static int check_of_version(void) return 1; } -void *claim(unsigned long virt, unsigned long size, unsigned long align) +static void *claim(unsigned long virt, unsigned long size, unsigned long align) { int ret; unsigned int result; @@ -151,7 +160,7 @@ void *claim(unsigned long virt, unsigned long size, unsigned long align) need_map = check_of_version(); if (align || !need_map) return (void *) call_prom("claim", 3, 1, virt, size, align); - + ret = call_prom_ret("call-method", 5, 2, &result, "claim", memory, align, size, virt); if (ret != 0 || result == -1) @@ -163,3 +172,112 @@ void *claim(unsigned long virt, unsigned long size, unsigned long align) 0x12, size, virt, virt); return (void *) virt; } + +static void *of_try_claim(u32 size) +{ + unsigned long addr = 0; + static u8 first_time = 1; + + if (first_time) { + claim_base = _ALIGN_UP((unsigned long)_end, ONE_MB); + first_time = 0; + } + + for(; claim_base < RAM_END; claim_base += ONE_MB) { +#ifdef DEBUG + printf(" trying: 0x%08lx\n\r", claim_base); +#endif + addr = (unsigned long)claim(claim_base, size, 0); + if ((void *)addr != (void *)-1) + break; + } + if (addr == 0) + return NULL; + claim_base = PAGE_ALIGN(claim_base + size); + return (void *)addr; +} + +static void of_image_hdr(const void *hdr) +{ + const Elf64_Ehdr *elf64 = hdr; + + if (elf64->e_ident[EI_CLASS] == ELFCLASS64) { + /* + * Maintain a "magic" minimum address. This keeps some older + * firmware platforms running. + */ + if (claim_base < PROG_START) + claim_base = PROG_START; + } +} + +static void of_exit(void) +{ + call_prom("exit", 0, 0); +} + +/* + * OF device tree routines + */ +static void *of_finddevice(const char *name) +{ + return (phandle) call_prom("finddevice", 1, 1, name); +} + +static int of_getprop(const void *phandle, const char *name, void *buf, + const int buflen) +{ + return call_prom("getprop", 4, 1, phandle, name, buf, buflen); +} + +static int of_setprop(const void *phandle, const char *name, const void *buf, + const int buflen) +{ + return call_prom("setprop", 4, 1, phandle, name, buf, buflen); +} + +/* + * OF console routines + */ +static void *of_stdout_handle; + +static int of_console_open(void) +{ + void *devp; + + if (((devp = finddevice("/chosen")) != NULL) + && (getprop(devp, "stdout", &of_stdout_handle, + sizeof(of_stdout_handle)) + == sizeof(of_stdout_handle))) + return 0; + + return -1; +} + +static void of_console_write(char *buf, int len) +{ + call_prom("write", 3, 1, of_stdout_handle, buf, len); +} + +int platform_init(void *promptr) +{ + platform_ops.fixups = NULL; + platform_ops.image_hdr = of_image_hdr; + platform_ops.malloc = of_try_claim; + platform_ops.free = NULL; + platform_ops.exit = of_exit; + + dt_ops.finddevice = of_finddevice; + dt_ops.getprop = of_getprop; + dt_ops.setprop = of_setprop; + dt_ops.translate_addr = NULL; + + console_ops.open = of_console_open; + console_ops.write = of_console_write; + console_ops.edit_cmdline = NULL; + console_ops.close = NULL; + console_ops.data = NULL; + + prom = (int (*)(void *))promptr; + return 0; +} diff --git a/arch/powerpc/boot/ops.h b/arch/powerpc/boot/ops.h new file mode 100644 index 000000000000..135eb4bb03b4 --- /dev/null +++ b/arch/powerpc/boot/ops.h @@ -0,0 +1,100 @@ +/* + * Global definition of all the bootwrapper operations. + * + * Author: Mark A. Greer <mgreer@mvista.com> + * + * 2006 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ +#ifndef _PPC_BOOT_OPS_H_ +#define _PPC_BOOT_OPS_H_ + +#include "types.h" + +#define COMMAND_LINE_SIZE 512 +#define MAX_PATH_LEN 256 +#define MAX_PROP_LEN 256 /* What should this be? */ + +/* Platform specific operations */ +struct platform_ops { + void (*fixups)(void); + void (*image_hdr)(const void *); + void * (*malloc)(u32 size); + void (*free)(void *ptr, u32 size); + void (*exit)(void); +}; +extern struct platform_ops platform_ops; + +/* Device Tree operations */ +struct dt_ops { + void * (*finddevice)(const char *name); + int (*getprop)(const void *node, const char *name, void *buf, + const int buflen); + int (*setprop)(const void *node, const char *name, + const void *buf, const int buflen); + u64 (*translate_addr)(const char *path, const u32 *in_addr, + const u32 addr_len); + unsigned long (*ft_addr)(void); +}; +extern struct dt_ops dt_ops; + +/* Console operations */ +struct console_ops { + int (*open)(void); + void (*write)(char *buf, int len); + void (*edit_cmdline)(char *buf, int len); + void (*close)(void); + void *data; +}; +extern struct console_ops console_ops; + +/* Serial console operations */ +struct serial_console_data { + int (*open)(void); + void (*putc)(unsigned char c); + unsigned char (*getc)(void); + u8 (*tstc)(void); + void (*close)(void); +}; + +extern int platform_init(void *promptr); +extern void simple_alloc_init(void); +extern void ft_init(void *dt_blob); +extern int serial_console_init(void); + +static inline void *finddevice(const char *name) +{ + return (dt_ops.finddevice) ? dt_ops.finddevice(name) : NULL; +} + +static inline int getprop(void *devp, const char *name, void *buf, int buflen) +{ + return (dt_ops.getprop) ? dt_ops.getprop(devp, name, buf, buflen) : -1; +} + +static inline int setprop(void *devp, const char *name, void *buf, int buflen) +{ + return (dt_ops.setprop) ? dt_ops.setprop(devp, name, buf, buflen) : -1; +} + +static inline void *malloc(u32 size) +{ + return (platform_ops.malloc) ? platform_ops.malloc(size) : NULL; +} + +static inline void free(void *ptr, u32 size) +{ + if (platform_ops.free) + platform_ops.free(ptr, size); +} + +static inline void exit(void) +{ + if (platform_ops.exit) + platform_ops.exit(); + for(;;); +} + +#endif /* _PPC_BOOT_OPS_H_ */ diff --git a/arch/powerpc/boot/prom.h b/arch/powerpc/boot/prom.h deleted file mode 100644 index a57b184c564f..000000000000 --- a/arch/powerpc/boot/prom.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef _PPC_BOOT_PROM_H_ -#define _PPC_BOOT_PROM_H_ - -typedef void *phandle; -typedef void *ihandle; - -extern int (*prom) (void *); -extern phandle chosen_handle; -extern ihandle stdout; - -int call_prom(const char *service, int nargs, int nret, ...); -int call_prom_ret(const char *service, int nargs, int nret, - unsigned int *rets, ...); - -extern int write(void *handle, void *ptr, int nb); -extern void *claim(unsigned long virt, unsigned long size, unsigned long aln); - -static inline void exit(void) -{ - call_prom("exit", 0, 0); -} - -static inline phandle finddevice(const char *name) -{ - return (phandle) call_prom("finddevice", 1, 1, name); -} - -static inline int getprop(void *phandle, const char *name, - void *buf, int buflen) -{ - return call_prom("getprop", 4, 1, phandle, name, buf, buflen); -} - - -static inline int setprop(void *phandle, const char *name, - void *buf, int buflen) -{ - return call_prom("setprop", 4, 1, phandle, name, buf, buflen); -} - -#endif /* _PPC_BOOT_PROM_H_ */ diff --git a/arch/powerpc/boot/stdio.c b/arch/powerpc/boot/stdio.c index b5aa522f8b77..6d5f6382e1ce 100644 --- a/arch/powerpc/boot/stdio.c +++ b/arch/powerpc/boot/stdio.c @@ -10,7 +10,7 @@ #include <stddef.h> #include "string.h" #include "stdio.h" -#include "prom.h" +#include "ops.h" size_t strnlen(const char * s, size_t count) { @@ -320,6 +320,6 @@ printf(const char *fmt, ...) va_start(args, fmt); n = vsprintf(sprint_buf, fmt, args); va_end(args); - write(stdout, sprint_buf, n); + console_ops.write(sprint_buf, n); return n; } diff --git a/arch/powerpc/boot/stdio.h b/arch/powerpc/boot/stdio.h index eb9e16c87aef..73b8a91bfb34 100644 --- a/arch/powerpc/boot/stdio.h +++ b/arch/powerpc/boot/stdio.h @@ -1,8 +1,16 @@ #ifndef _PPC_BOOT_STDIO_H_ #define _PPC_BOOT_STDIO_H_ +#include <stdarg.h> + +#define ENOMEM 12 /* Out of Memory */ +#define EINVAL 22 /* Invalid argument */ +#define ENOSPC 28 /* No space left on device */ + extern int printf(const char *fmt, ...); +#define fprintf(fmt, args...) printf(args) + extern int sprintf(char *buf, const char *fmt, ...); extern int vsprintf(char *buf, const char *fmt, va_list args); diff --git a/arch/powerpc/boot/types.h b/arch/powerpc/boot/types.h new file mode 100644 index 000000000000..79d26e708677 --- /dev/null +++ b/arch/powerpc/boot/types.h @@ -0,0 +1,23 @@ +#ifndef _TYPES_H_ +#define _TYPES_H_ + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; +typedef unsigned long long u64; + +#define min(x,y) ({ \ + typeof(x) _x = (x); \ + typeof(y) _y = (y); \ + (void) (&_x == &_y); \ + _x < _y ? _x : _y; }) + +#define max(x,y) ({ \ + typeof(x) _x = (x); \ + typeof(y) _y = (y); \ + (void) (&_x == &_y); \ + _x > _y ? _x : _y; }) + +#endif /* _TYPES_H_ */ diff --git a/arch/powerpc/configs/cell_defconfig b/arch/powerpc/configs/cell_defconfig index b8b8d4675dc0..6fd9e7acec29 100644 --- a/arch/powerpc/configs/cell_defconfig +++ b/arch/powerpc/configs/cell_defconfig @@ -1,13 +1,14 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.17 -# Mon Jun 19 17:23:03 2006 +# Linux kernel version: 2.6.18-rc6 +# Sun Sep 10 10:20:32 2006 # CONFIG_PPC64=y CONFIG_64BIT=y CONFIG_PPC_MERGE=y CONFIG_MMU=y CONFIG_GENERIC_HARDIRQS=y +CONFIG_IRQ_PER_CPU=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y @@ -35,6 +36,7 @@ CONFIG_PPC_STD_MMU=y CONFIG_VIRT_CPU_ACCOUNTING=y CONFIG_SMP=y CONFIG_NR_CPUS=4 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # # Code maturity level options @@ -52,6 +54,7 @@ CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set CONFIG_IKCONFIG=y @@ -69,10 +72,12 @@ CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y +CONFIG_RT_MUTEXES=y CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 # CONFIG_SLOB is not set @@ -119,7 +124,7 @@ CONFIG_PPC_MULTIPLATFORM=y CONFIG_PPC_CELL=y CONFIG_PPC_CELL_NATIVE=y CONFIG_PPC_IBM_CELL_BLADE=y -CONFIG_PPC_SYSTEMSIM=y +CONFIG_UDBG_RTAS_CONSOLE=y # CONFIG_U3_DART is not set CONFIG_PPC_RTAS=y # CONFIG_RTAS_ERROR_LOGGING is not set @@ -130,6 +135,7 @@ CONFIG_MMIO_NVRAM=y # CONFIG_PPC_970_NAP is not set # CONFIG_CPU_FREQ is not set # CONFIG_WANT_EARLY_SERIAL is not set +# CONFIG_MPIC is not set # # Cell Broadband Engine options @@ -154,6 +160,7 @@ CONFIG_BINFMT_ELF=y CONFIG_BINFMT_MISC=m CONFIG_FORCE_MAX_ZONEORDER=13 # CONFIG_IOMMU_VMERGE is not set +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_KEXEC=y # CONFIG_CRASH_DUMP is not set CONFIG_IRQ_ALL_CPUS=y @@ -173,6 +180,7 @@ CONFIG_SPARSEMEM_EXTREME=y CONFIG_MEMORY_HOTPLUG=y CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_MIGRATION=y +CONFIG_RESOURCES_64BIT=y CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y CONFIG_ARCH_MEMORY_PROBE=y # CONFIG_PPC_64K_PAGES is not set @@ -187,6 +195,7 @@ CONFIG_ISA_DMA_API=y # Bus options # CONFIG_GENERIC_ISA_DMA=y +# CONFIG_MPIC_WEIRD is not set # CONFIG_PPC_I8259 is not set # CONFIG_PPC_INDIRECT_PCI is not set CONFIG_PCI=y @@ -235,6 +244,8 @@ CONFIG_SYN_COOKIES=y # CONFIG_INET_IPCOMP is not set # CONFIG_INET_XFRM_TUNNEL is not set CONFIG_INET_TUNNEL=y +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set @@ -252,7 +263,10 @@ CONFIG_INET6_ESP=m CONFIG_INET6_IPCOMP=m CONFIG_INET6_XFRM_TUNNEL=m CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=y +CONFIG_INET6_XFRM_MODE_TUNNEL=y CONFIG_IPV6_TUNNEL=m +# CONFIG_NETWORK_SECMARK is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set @@ -277,6 +291,7 @@ CONFIG_IP_NF_TFTP=m CONFIG_IP_NF_AMANDA=m # CONFIG_IP_NF_PPTP is not set # CONFIG_IP_NF_H323 is not set +# CONFIG_IP_NF_SIP is not set CONFIG_IP_NF_QUEUE=m # @@ -336,6 +351,7 @@ CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_FW_LOADER=y # CONFIG_DEBUG_DRIVER is not set +# CONFIG_SYS_HYPERVISOR is not set # # Connector - unified userspace <-> kernelspace linker @@ -372,6 +388,7 @@ CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=131072 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set @@ -449,8 +466,7 @@ CONFIG_MD_LINEAR=m CONFIG_MD_RAID0=m CONFIG_MD_RAID1=m # CONFIG_MD_RAID10 is not set -# CONFIG_MD_RAID5 is not set -# CONFIG_MD_RAID6 is not set +# CONFIG_MD_RAID456 is not set # CONFIG_MD_MULTIPATH is not set # CONFIG_MD_FAULTY is not set CONFIG_BLK_DEV_DM=m @@ -544,6 +560,7 @@ CONFIG_SPIDER_NET=m # CONFIG_CHELSIO_T1 is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set +# CONFIG_MYRI10GE is not set # # Token Ring devices @@ -620,6 +637,7 @@ CONFIG_SERIO_SERPORT=y CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set CONFIG_SERIAL_NONSTANDARD=y # CONFIG_COMPUTONE is not set # CONFIG_ROCKETPORT is not set @@ -680,6 +698,7 @@ CONFIG_WATCHDOG_RTAS=y # # CONFIG_PCIPCWATCHDOG is not set # CONFIG_WDTPCI is not set +# CONFIG_HW_RANDOM is not set CONFIG_GEN_RTC=y # CONFIG_GEN_RTC_X is not set # CONFIG_DTLK is not set @@ -725,6 +744,7 @@ CONFIG_I2C_ALGOBIT=y # CONFIG_I2C_I810 is not set # CONFIG_I2C_PIIX4 is not set # CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_OCORES is not set # CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_PROSAVAGE is not set # CONFIG_I2C_SAVAGE4 is not set @@ -761,7 +781,6 @@ CONFIG_I2C_ALGOBIT=y # # Dallas's 1-wire bus # -# CONFIG_W1 is not set # # Hardware Monitoring support @@ -787,6 +806,7 @@ CONFIG_VIDEO_V4L2=y # # Graphics support # +CONFIG_FIRMWARE_EDID=y # CONFIG_FB is not set # @@ -794,6 +814,7 @@ CONFIG_VIDEO_V4L2=y # # CONFIG_VGA_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -841,6 +862,7 @@ CONFIG_USB_ARCH_HAS_EHCI=y CONFIG_INFINIBAND=y CONFIG_INFINIBAND_USER_MAD=m CONFIG_INFINIBAND_USER_ACCESS=m +CONFIG_INFINIBAND_ADDR_TRANS=y CONFIG_INFINIBAND_MTHCA=m CONFIG_INFINIBAND_MTHCA_DEBUG=y CONFIG_INFINIBAND_IPOIB=m @@ -857,6 +879,19 @@ CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y # CONFIG_RTC_CLASS is not set # +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + +# # File systems # CONFIG_EXT2_FS=y @@ -877,6 +912,7 @@ CONFIG_FS_POSIX_ACL=y # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set @@ -1034,6 +1070,9 @@ CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=m CONFIG_ZLIB_DEFLATE=m +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_PLIST=y # # Instrumentation Support @@ -1046,14 +1085,19 @@ CONFIG_ZLIB_DEFLATE=m # # CONFIG_PRINTK_TIME is not set CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_KERNEL=y CONFIG_LOG_BUF_SHIFT=15 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set -CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set +CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_RWSEMS is not set CONFIG_DEBUG_SPINLOCK_SLEEP=y +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set CONFIG_DEBUG_FS=y @@ -1063,7 +1107,8 @@ CONFIG_DEBUG_FS=y # CONFIG_DEBUG_STACKOVERFLOW is not set # CONFIG_DEBUG_STACK_USAGE is not set CONFIG_DEBUGGER=y -# CONFIG_XMON is not set +CONFIG_XMON=y +CONFIG_XMON_DEFAULT=y CONFIG_IRQSTACKS=y # CONFIG_BOOTX_TEXT is not set # CONFIG_PPC_EARLY_DEBUG is not set diff --git a/arch/powerpc/configs/chrp32_defconfig b/arch/powerpc/configs/chrp32_defconfig new file mode 100644 index 000000000000..bbf2b5f8a8cb --- /dev/null +++ b/arch/powerpc/configs/chrp32_defconfig @@ -0,0 +1,1397 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.18-rc6 +# Sun Sep 10 10:22:54 2006 +# +# CONFIG_PPC64 is not set +CONFIG_PPC32=y +CONFIG_PPC_MERGE=y +CONFIG_MMU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_IRQ_PER_CPU=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_PPC=y +CONFIG_EARLY_PRINTK=y +CONFIG_GENERIC_NVRAM=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_PPC_OF=y +CONFIG_PPC_UDBG_16550=y +CONFIG_GENERIC_TBSYNC=y +# CONFIG_DEFAULT_UIMAGE is not set + +# +# Processor support +# +CONFIG_CLASSIC32=y +# CONFIG_PPC_52xx is not set +# CONFIG_PPC_82xx is not set +# CONFIG_PPC_83xx is not set +# CONFIG_PPC_85xx is not set +# CONFIG_PPC_86xx is not set +# CONFIG_40x is not set +# CONFIG_44x is not set +# CONFIG_8xx is not set +# CONFIG_E200 is not set +CONFIG_6xx=y +CONFIG_PPC_FPU=y +# CONFIG_ALTIVEC is not set +CONFIG_PPC_STD_MMU=y +CONFIG_PPC_STD_MMU_32=y +CONFIG_SMP=y +CONFIG_NR_CPUS=4 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +# CONFIG_CPUSETS is not set +# CONFIG_RELAY is not set +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_RT_MUTEXES=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SHMEM=y +CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y +CONFIG_STOP_MACHINE=y + +# +# Block layer +# +CONFIG_LBD=y +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# +# Platform support +# +CONFIG_PPC_MULTIPLATFORM=y +# CONFIG_PPC_ISERIES is not set +# CONFIG_EMBEDDED6xx is not set +# CONFIG_APUS is not set +CONFIG_PPC_CHRP=y +# CONFIG_PPC_PMAC is not set +# CONFIG_PPC_CELL is not set +# CONFIG_PPC_CELL_NATIVE is not set +# CONFIG_UDBG_RTAS_CONSOLE is not set +CONFIG_PPC_RTAS=y +# CONFIG_RTAS_ERROR_LOGGING is not set +CONFIG_RTAS_PROC=y +# CONFIG_MMIO_NVRAM is not set +CONFIG_PPC_MPC106=y +# CONFIG_PPC_970_NAP is not set +# CONFIG_CPU_FREQ is not set +# CONFIG_TAU is not set +# CONFIG_WANT_EARLY_SERIAL is not set +CONFIG_MPIC=y + +# +# Kernel options +# +CONFIG_HIGHMEM=y +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +CONFIG_PREEMPT_BKL=y +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_MISC=y +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +# CONFIG_KEXEC is not set +CONFIG_IRQ_ALL_CPUS=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_PROC_DEVICETREE=y +# CONFIG_CMDLINE_BOOL is not set +# CONFIG_PM is not set +CONFIG_SECCOMP=y +CONFIG_ISA_DMA_API=y + +# +# Bus options +# +CONFIG_ISA=y +CONFIG_GENERIC_ISA_DMA=y +# CONFIG_MPIC_WEIRD is not set +CONFIG_PPC_I8259=y +CONFIG_PPC_INDIRECT_PCI=y +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +# CONFIG_PCIEPORTBUS is not set +# CONFIG_PCI_DEBUG is not set + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# PCI Hotplug Support +# +# CONFIG_HOTPLUG_PCI is not set + +# +# Advanced setup +# +# CONFIG_ADVANCED_OPTIONS is not set + +# +# Default settings for advanced configuration options are used +# +CONFIG_HIGHMEM_START=0xfe000000 +CONFIG_LOWMEM_SIZE=0x30000000 +CONFIG_KERNEL_START=0xc0000000 +CONFIG_TASK_SIZE=0x80000000 +CONFIG_BOOT_LOAD=0x00800000 + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_NETDEBUG is not set +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_BIC=y + +# +# IP: Virtual Server Configuration +# +# CONFIG_IP_VS is not set +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set + +# +# Core Netfilter Configuration +# +# CONFIG_NETFILTER_NETLINK is not set +# CONFIG_NETFILTER_XTABLES is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +# CONFIG_IP_NF_CT_ACCT is not set +# CONFIG_IP_NF_CONNTRACK_MARK is not set +# CONFIG_IP_NF_CONNTRACK_EVENTS is not set +# CONFIG_IP_NF_CT_PROTO_SCTP is not set +CONFIG_IP_NF_FTP=m +CONFIG_IP_NF_IRC=m +# CONFIG_IP_NF_NETBIOS_NS is not set +CONFIG_IP_NF_TFTP=m +CONFIG_IP_NF_AMANDA=m +# CONFIG_IP_NF_PPTP is not set +# CONFIG_IP_NF_H323 is not set +# CONFIG_IP_NF_SIP is not set +# CONFIG_IP_NF_QUEUE is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +# CONFIG_STANDALONE is not set +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Block devices +# +CONFIG_BLK_DEV_FD=y +# CONFIG_BLK_DEV_XD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +CONFIG_BLK_DEV_INITRD=y +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=y +CONFIG_IDEDISK_MULTI_MODE=y +CONFIG_BLK_DEV_IDECD=y +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=y +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_IDEPCI_SHARE_IRQ=y +# CONFIG_BLK_DEV_OFFBOARD is not set +CONFIG_BLK_DEV_GENERIC=y +# CONFIG_BLK_DEV_OPTI621 is not set +CONFIG_BLK_DEV_SL82C105=y +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +CONFIG_IDEDMA_PCI_AUTO=y +# CONFIG_IDEDMA_ONLYDISK is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_CY82C693 is not set +# CONFIG_BLK_DEV_CS5520 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_HPT34X is not set +# CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_SC1200 is not set +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_IT821X is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +CONFIG_BLK_DEV_VIA82CXXX=y +# CONFIG_IDE_ARM is not set +# CONFIG_IDE_CHIPSETS is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_IVB is not set +CONFIG_IDEDMA_AUTO=y +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_ST=y +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_CHR_DEV_SG=y +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_CONSTANTS=y +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI Transport Attributes +# +CONFIG_SCSI_SPI_ATTRS=y +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set + +# +# SCSI low-level drivers +# +# CONFIG_ISCSI_TCP is not set +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_7000FASST is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AHA152X is not set +# CONFIG_SCSI_AHA1542 is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_SCSI_SATA is not set +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_NCR53C406A is not set +CONFIG_SCSI_SYM53C8XX_2=y +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0 +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +CONFIG_SCSI_SYM53C8XX_MMIO=y +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_LPFC is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_SPI is not set +# CONFIG_FUSION_FC is not set +# CONFIG_FUSION_SAS is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Macintosh device drivers +# +# CONFIG_WINDFARM is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# PHY device support +# +# CONFIG_PHYLIB is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set + +# +# Tulip family network device support +# +CONFIG_NET_TULIP=y +# CONFIG_DE2104X is not set +# CONFIG_TULIP is not set +CONFIG_DE4X5=y +# CONFIG_WINBOND_840 is not set +# CONFIG_DM9102 is not set +# CONFIG_ULI526X is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +CONFIG_PCNET32=y +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_AC3200 is not set +# CONFIG_APRICOT is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +# CONFIG_CS89x0 is not set +# CONFIG_DGRS is not set +# CONFIG_EEPRO100 is not set +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +CONFIG_8139CP=y +CONFIG_8139TOO=y +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_8139_OLD_RX_RESET is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +CONFIG_VIA_RHINE=y +# CONFIG_VIA_RHINE_MMIO is not set +# CONFIG_VIA_RHINE_NAPI is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +# CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set +CONFIG_MV643XX_ETH=y +# CONFIG_MV643XX_ETH_0 is not set +# CONFIG_MV643XX_ETH_1 is not set +# CONFIG_MV643XX_ETH_2 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_CHELSIO_T1 is not set +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set +# CONFIG_MYRI10GE is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_MPPE=m +CONFIG_PPPOE=m +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_INPORT is not set +# CONFIG_MOUSE_LOGIBM is not set +# CONFIG_MOUSE_PC110PAD is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +CONFIG_INPUT_MISC=y +# CONFIG_INPUT_PCSPKR is not set +CONFIG_INPUT_UINPUT=y + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_HVC_RTAS is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_HW_RANDOM is not set +CONFIG_NVRAM=y +CONFIG_GEN_RTC=y +# CONFIG_GEN_RTC_X is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set +# CONFIG_TELCLOCK is not set + +# +# I2C support +# +CONFIG_I2C=y +# CONFIG_I2C_CHARDEV is not set + +# +# I2C Algorithms +# +CONFIG_I2C_ALGOBIT=y +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_HYDRA is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_MPC is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_VOODOO3 is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_M41T00 is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set + +# +# Dallas's 1-wire bus +# + +# +# Hardware Monitoring support +# +# CONFIG_HWMON is not set +# CONFIG_HWMON_VID is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_V4L2=y + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set +# CONFIG_USB_DABUSB is not set + +# +# Graphics support +# +CONFIG_FIRMWARE_EDID=y +CONFIG_FB=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_MACMODES=y +# CONFIG_FB_BACKLIGHT is not set +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_TILEBLITTING=y +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_CYBER2000 is not set +CONFIG_FB_OF=y +# CONFIG_FB_CT65550 is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_VGA16 is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_RIVA is not set +CONFIG_FB_MATROX=y +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MYSTIQUE=y +CONFIG_FB_MATROX_G=y +# CONFIG_FB_MATROX_I2C is not set +# CONFIG_FB_MATROX_MULTIHEAD is not set +CONFIG_FB_RADEON=y +CONFIG_FB_RADEON_I2C=y +# CONFIG_FB_RADEON_DEBUG is not set +# CONFIG_FB_ATY128 is not set +CONFIG_FB_ATY=y +CONFIG_FB_ATY_CT=y +# CONFIG_FB_ATY_GENERIC_LCD is not set +CONFIG_FB_ATY_GX=y +# CONFIG_FB_SAVAGE is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set +CONFIG_FB_3DFX=y +# CONFIG_FB_3DFX_ACCEL is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +CONFIG_VGA_CONSOLE=y +# CONFIG_VGACON_SOFT_SCROLLBACK is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y + +# +# Logo configuration +# +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +CONFIG_USB_EHCI_HCD=m +# CONFIG_USB_EHCI_SPLIT_ISO is not set +# CONFIG_USB_EHCI_ROOT_HUB_TT is not set +# CONFIG_USB_EHCI_TT_NEWSCHED is not set +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +CONFIG_USB_UHCI_HCD=y +# CONFIG_USB_SL811_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=m +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=y +CONFIG_USB_HIDINPUT=y +# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_HID_FF is not set +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_ACECAD is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set +# CONFIG_USB_TOUCHSCREEN is not set +# CONFIG_USB_YEALINK is not set +# CONFIG_USB_XPAD is not set +# CONFIG_USB_ATI_REMOTE is not set +# CONFIG_USB_ATI_REMOTE2 is not set +# CONFIG_USB_KEYSPAN_REMOTE is not set +# CONFIG_USB_APPLETOUCH is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +CONFIG_USB_MON=y + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGETKIT is not set +# CONFIG_USB_PHIDGETSERVO is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TEST is not set + +# +# USB DSL modem support +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + +# +# InfiniBand support +# +# CONFIG_INFINIBAND is not set + +# +# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# + +# +# Real Time Clock +# +# CONFIG_RTC_CLASS is not set + +# +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +# CONFIG_NFS_FS is not set +# CONFIG_NFSD is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=m +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Library routines +# +CONFIG_CRC_CCITT=m +# CONFIG_CRC16 is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_PLIST=y + +# +# Instrumentation Support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_LOG_BUF_SHIFT=15 +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_RWSEMS is not set +CONFIG_DEBUG_SPINLOCK_SLEEP=y +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_HIGHMEM is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_DEBUG_VM is not set +CONFIG_FORCED_INLINING=y +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_DEBUGGER=y +CONFIG_XMON=y +CONFIG_XMON_DEFAULT=y +# CONFIG_BDI_SWITCH is not set +# CONFIG_BOOTX_TEXT is not set +# CONFIG_PPC_EARLY_DEBUG is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +CONFIG_CRYPTO_SHA1=m +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +CONFIG_CRYPTO_ARC4=m +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Hardware crypto devices +# diff --git a/arch/powerpc/configs/g5_defconfig b/arch/powerpc/configs/g5_defconfig index a45627547d03..4b9c2ed925f5 100644 --- a/arch/powerpc/configs/g5_defconfig +++ b/arch/powerpc/configs/g5_defconfig @@ -1,16 +1,18 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.17-rc1 -# Wed Apr 19 13:24:37 2006 +# Linux kernel version: 2.6.18-rc6 +# Sun Sep 10 10:22:55 2006 # CONFIG_PPC64=y CONFIG_64BIT=y CONFIG_PPC_MERGE=y CONFIG_MMU=y CONFIG_GENERIC_HARDIRQS=y +CONFIG_IRQ_PER_CPU=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_PPC=y CONFIG_EARLY_PRINTK=y CONFIG_COMPAT=y @@ -33,6 +35,7 @@ CONFIG_PPC_STD_MMU=y CONFIG_VIRT_CPU_ACCOUNTING=y CONFIG_SMP=y CONFIG_NR_CPUS=4 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # # Code maturity level options @@ -50,6 +53,7 @@ CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set CONFIG_IKCONFIG=y @@ -67,10 +71,12 @@ CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y +CONFIG_RT_MUTEXES=y CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 # CONFIG_SLOB is not set @@ -116,12 +122,15 @@ CONFIG_PPC_PMAC=y CONFIG_PPC_PMAC64=y # CONFIG_PPC_MAPLE is not set # CONFIG_PPC_CELL is not set +# CONFIG_PPC_CELL_NATIVE is not set +# CONFIG_PPC_IBM_CELL_BLADE is not set +# CONFIG_UDBG_RTAS_CONSOLE is not set CONFIG_U3_DART=y -CONFIG_MPIC=y # CONFIG_PPC_RTAS is not set # CONFIG_MMIO_NVRAM is not set CONFIG_MPIC_BROKEN_U3=y # CONFIG_PPC_MPC106 is not set +CONFIG_PPC_970_NAP=y CONFIG_CPU_FREQ=y CONFIG_CPU_FREQ_TABLE=y # CONFIG_CPU_FREQ_DEBUG is not set @@ -136,6 +145,7 @@ CONFIG_CPU_FREQ_GOV_USERSPACE=y # CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set CONFIG_CPU_FREQ_PMAC64=y # CONFIG_WANT_EARLY_SERIAL is not set +CONFIG_MPIC=y # # Kernel options @@ -153,6 +163,7 @@ CONFIG_BINFMT_ELF=y CONFIG_FORCE_MAX_ZONEORDER=13 CONFIG_IOMMU_VMERGE=y # CONFIG_HOTPLUG_CPU is not set +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_KEXEC=y # CONFIG_CRASH_DUMP is not set CONFIG_IRQ_ALL_CPUS=y @@ -168,6 +179,7 @@ CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_RESOURCES_64BIT=y # CONFIG_PPC_64K_PAGES is not set # CONFIG_SCHED_SMT is not set CONFIG_PROC_DEVICETREE=y @@ -180,10 +192,12 @@ CONFIG_ISA_DMA_API=y # Bus options # CONFIG_GENERIC_ISA_DMA=y +# CONFIG_MPIC_WEIRD is not set # CONFIG_PPC_I8259 is not set # CONFIG_PPC_INDIRECT_PCI is not set CONFIG_PCI=y CONFIG_PCI_DOMAINS=y +# CONFIG_PCIEPORTBUS is not set # CONFIG_PCI_DEBUG is not set # @@ -227,6 +241,8 @@ CONFIG_INET_ESP=m CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_TUNNEL=m CONFIG_INET_TUNNEL=y +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set @@ -239,6 +255,7 @@ CONFIG_TCP_CONG_BIC=y # CONFIG_IPV6 is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set @@ -263,6 +280,7 @@ CONFIG_IP_NF_TFTP=m CONFIG_IP_NF_AMANDA=m # CONFIG_IP_NF_PPTP is not set # CONFIG_IP_NF_H323 is not set +# CONFIG_IP_NF_SIP is not set CONFIG_IP_NF_QUEUE=m # @@ -318,6 +336,7 @@ CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_FW_LOADER=y # CONFIG_DEBUG_DRIVER is not set +# CONFIG_SYS_HYPERVISOR is not set # # Connector - unified userspace <-> kernelspace linker @@ -355,6 +374,7 @@ CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=65536 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 CONFIG_BLK_DEV_INITRD=y CONFIG_CDROM_PKTCDVD=m CONFIG_CDROM_PKTCDVD_BUFFERS=8 @@ -417,7 +437,6 @@ CONFIG_IDEDMA_PCI_AUTO=y CONFIG_BLK_DEV_IDE_PMAC=y CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST=y CONFIG_BLK_DEV_IDEDMA_PMAC=y -# CONFIG_BLK_DEV_IDE_PMAC_BLINK is not set # CONFIG_IDE_ARM is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_IVB is not set @@ -478,6 +497,7 @@ CONFIG_SCSI_SATA_SVW=y # CONFIG_SCSI_SATA_MV is not set # CONFIG_SCSI_SATA_NV is not set # CONFIG_SCSI_PDC_ADMA is not set +# CONFIG_SCSI_HPTIOP is not set # CONFIG_SCSI_SATA_QSTOR is not set # CONFIG_SCSI_SATA_PROMISE is not set # CONFIG_SCSI_SATA_SX4 is not set @@ -497,7 +517,6 @@ CONFIG_SCSI_SATA_SVW=y # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_SYM53C8XX_2 is not set # CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set # CONFIG_SCSI_QLA_FC is not set # CONFIG_SCSI_LPFC is not set @@ -514,9 +533,7 @@ CONFIG_MD_LINEAR=y CONFIG_MD_RAID0=y CONFIG_MD_RAID1=y CONFIG_MD_RAID10=m -CONFIG_MD_RAID5=y -# CONFIG_MD_RAID5_RESHAPE is not set -CONFIG_MD_RAID6=m +# CONFIG_MD_RAID456 is not set CONFIG_MD_MULTIPATH=m CONFIG_MD_FAULTY=m CONFIG_BLK_DEV_DM=y @@ -559,7 +576,6 @@ CONFIG_IEEE1394_OHCI1394=y # CONFIG_IEEE1394_VIDEO1394=m CONFIG_IEEE1394_SBP2=m -# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set CONFIG_IEEE1394_ETH1394=m CONFIG_IEEE1394_DV1394=m CONFIG_IEEE1394_RAWIO=y @@ -573,6 +589,7 @@ CONFIG_IEEE1394_RAWIO=y # Macintosh device drivers # CONFIG_ADB_PMU=y +# CONFIG_ADB_PMU_LED is not set CONFIG_PMAC_SMU=y CONFIG_THERM_PM72=y CONFIG_WINDFARM=y @@ -643,6 +660,7 @@ CONFIG_TIGON3=y # CONFIG_CHELSIO_T1 is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set +# CONFIG_MYRI10GE is not set # # Token Ring devices @@ -739,6 +757,7 @@ CONFIG_SERIO=y CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set # CONFIG_SERIAL_NONSTANDARD is not set # @@ -764,6 +783,7 @@ CONFIG_LEGACY_PTY_COUNT=256 # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_HW_RANDOM is not set CONFIG_GEN_RTC=y # CONFIG_GEN_RTC_X is not set # CONFIG_DTLK is not set @@ -774,6 +794,7 @@ CONFIG_GEN_RTC=y # Ftape, the floppy tape device driver # CONFIG_AGP=m +# CONFIG_AGP_SIS is not set # CONFIG_AGP_VIA is not set CONFIG_AGP_UNINORTH=m # CONFIG_DRM is not set @@ -813,6 +834,7 @@ CONFIG_I2C_ALGOBIT=y # CONFIG_I2C_PIIX4 is not set CONFIG_I2C_POWERMAC=y # CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_OCORES is not set # CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_PROSAVAGE is not set # CONFIG_I2C_SAVAGE4 is not set @@ -849,7 +871,6 @@ CONFIG_I2C_POWERMAC=y # # Dallas's 1-wire bus # -# CONFIG_W1 is not set # # Hardware Monitoring support @@ -865,6 +886,7 @@ CONFIG_I2C_POWERMAC=y # Multimedia devices # # CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices @@ -875,22 +897,19 @@ CONFIG_I2C_POWERMAC=y # # Graphics support # +CONFIG_FIRMWARE_EDID=y CONFIG_FB=y CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y CONFIG_FB_MACMODES=y -CONFIG_FB_FIRMWARE_EDID=y +# CONFIG_FB_BACKLIGHT is not set CONFIG_FB_MODE_HELPERS=y CONFIG_FB_TILEBLITTING=y # CONFIG_FB_CIRRUS is not set # CONFIG_FB_PM2 is not set # CONFIG_FB_CYBER2000 is not set CONFIG_FB_OF=y -# CONFIG_FB_CONTROL is not set -# CONFIG_FB_PLATINUM is not set -# CONFIG_FB_VALKYRIE is not set -# CONFIG_FB_CT65550 is not set # CONFIG_FB_ASILIANT is not set # CONFIG_FB_IMSTT is not set # CONFIG_FB_VGA16 is not set @@ -990,6 +1009,18 @@ CONFIG_SND_VERBOSE_PROCFS=y # CONFIG_SND_CMIPCI is not set # CONFIG_SND_CS4281 is not set # CONFIG_SND_CS46XX is not set +# CONFIG_SND_DARLA20 is not set +# CONFIG_SND_GINA20 is not set +# CONFIG_SND_LAYLA20 is not set +# CONFIG_SND_DARLA24 is not set +# CONFIG_SND_GINA24 is not set +# CONFIG_SND_LAYLA24 is not set +# CONFIG_SND_MONA is not set +# CONFIG_SND_MIA is not set +# CONFIG_SND_ECHO3G is not set +# CONFIG_SND_INDIGO is not set +# CONFIG_SND_INDIGOIO is not set +# CONFIG_SND_INDIGODJ is not set # CONFIG_SND_EMU10K1 is not set # CONFIG_SND_EMU10K1X is not set # CONFIG_SND_ENS1370 is not set @@ -1027,6 +1058,17 @@ CONFIG_SND_POWERMAC=m CONFIG_SND_POWERMAC_AUTO_DRC=y # +# Apple Onboard Audio driver +# +CONFIG_SND_AOA=m +CONFIG_SND_AOA_FABRIC_LAYOUT=m +CONFIG_SND_AOA_ONYX=m +CONFIG_SND_AOA_TAS=m +CONFIG_SND_AOA_TOONIE=m +CONFIG_SND_AOA_SOUNDBUS=m +CONFIG_SND_AOA_SOUNDBUS_I2S=m + +# # USB devices # CONFIG_SND_USB_AUDIO=m @@ -1060,6 +1102,7 @@ CONFIG_USB_DEVICEFS=y CONFIG_USB_EHCI_HCD=y # CONFIG_USB_EHCI_SPLIT_ISO is not set # CONFIG_USB_EHCI_ROOT_HUB_TT is not set +# CONFIG_USB_EHCI_TT_NEWSCHED is not set # CONFIG_USB_ISP116X_HCD is not set CONFIG_USB_OHCI_HCD=y # CONFIG_USB_OHCI_BIG_ENDIAN is not set @@ -1110,9 +1153,7 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_ACECAD is not set # CONFIG_USB_KBTAB is not set # CONFIG_USB_POWERMATE is not set -# CONFIG_USB_MTOUCH is not set -# CONFIG_USB_ITMTOUCH is not set -# CONFIG_USB_EGALAX is not set +# CONFIG_USB_TOUCHSCREEN is not set # CONFIG_USB_YEALINK is not set # CONFIG_USB_XPAD is not set # CONFIG_USB_ATI_REMOTE is not set @@ -1154,7 +1195,7 @@ CONFIG_USB_MON=y CONFIG_USB_SERIAL=m CONFIG_USB_SERIAL_GENERIC=y # CONFIG_USB_SERIAL_AIRPRIME is not set -# CONFIG_USB_SERIAL_ANYDATA is not set +# CONFIG_USB_SERIAL_ARK3116 is not set CONFIG_USB_SERIAL_BELKIN=m # CONFIG_USB_SERIAL_WHITEHEAT is not set CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m @@ -1162,6 +1203,7 @@ CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m CONFIG_USB_SERIAL_CYPRESS_M8=m CONFIG_USB_SERIAL_EMPEG=m CONFIG_USB_SERIAL_FTDI_SIO=m +# CONFIG_USB_SERIAL_FUNSOFT is not set CONFIG_USB_SERIAL_VISOR=m CONFIG_USB_SERIAL_IPAQ=m CONFIG_USB_SERIAL_IR=m @@ -1191,9 +1233,11 @@ CONFIG_USB_SERIAL_PL2303=m # CONFIG_USB_SERIAL_HP4X is not set CONFIG_USB_SERIAL_SAFE=m CONFIG_USB_SERIAL_SAFE_PADDED=y +# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set CONFIG_USB_SERIAL_TI=m CONFIG_USB_SERIAL_CYBERJACK=m CONFIG_USB_SERIAL_XIRCOM=m +# CONFIG_USB_SERIAL_OPTION is not set CONFIG_USB_SERIAL_OMNINET=m CONFIG_USB_EZUSB=y @@ -1207,10 +1251,12 @@ CONFIG_USB_EZUSB=y # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set # CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set # CONFIG_USB_PHIDGETKIT is not set # CONFIG_USB_PHIDGETSERVO is not set # CONFIG_USB_IDMOUSE is not set +CONFIG_USB_APPLEDISPLAY=m # CONFIG_USB_SISUSBVGA is not set # CONFIG_USB_LD is not set # CONFIG_USB_TEST is not set @@ -1235,6 +1281,14 @@ CONFIG_USB_EZUSB=y # CONFIG_NEW_LEDS is not set # +# LED drivers +# + +# +# LED Triggers +# + +# # InfiniBand support # # CONFIG_INFINIBAND is not set @@ -1249,6 +1303,19 @@ CONFIG_USB_EZUSB=y # CONFIG_RTC_CLASS is not set # +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + +# # File systems # CONFIG_EXT2_FS=y @@ -1273,7 +1340,6 @@ CONFIG_REISERFS_FS_SECURITY=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y CONFIG_XFS_FS=m -CONFIG_XFS_EXPORT=y # CONFIG_XFS_QUOTA is not set CONFIG_XFS_SECURITY=y CONFIG_XFS_POSIX_ACL=y @@ -1282,6 +1348,7 @@ CONFIG_XFS_POSIX_ACL=y # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set CONFIG_DNOTIFY=y CONFIG_AUTOFS_FS=m @@ -1363,7 +1430,9 @@ CONFIG_RPCSEC_GSS_KRB5=y # CONFIG_SMB_FS is not set CONFIG_CIFS=m # CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set # CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_DEBUG2 is not set # CONFIG_CIFS_EXPERIMENTAL is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -1444,6 +1513,9 @@ CONFIG_CRC32=y CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=m +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_PLIST=y # # Instrumentation Support @@ -1457,14 +1529,19 @@ CONFIG_OPROFILE=y # # CONFIG_PRINTK_TIME is not set CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_KERNEL=y CONFIG_LOG_BUF_SHIFT=17 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set -CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set +CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_RWSEMS is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set CONFIG_DEBUG_FS=y @@ -1476,11 +1553,7 @@ CONFIG_FORCED_INLINING=y # CONFIG_DEBUGGER is not set CONFIG_IRQSTACKS=y CONFIG_BOOTX_TEXT=y -# CONFIG_PPC_EARLY_DEBUG_LPAR is not set -# CONFIG_PPC_EARLY_DEBUG_G5 is not set -# CONFIG_PPC_EARLY_DEBUG_RTAS is not set -# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set -# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set +# CONFIG_PPC_EARLY_DEBUG is not set # # Security options diff --git a/arch/powerpc/configs/iseries_defconfig b/arch/powerpc/configs/iseries_defconfig index a95e455a1944..eb0885ea0731 100644 --- a/arch/powerpc/configs/iseries_defconfig +++ b/arch/powerpc/configs/iseries_defconfig @@ -1,16 +1,18 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.17-rc1 -# Wed Apr 19 11:46:44 2006 +# Linux kernel version: 2.6.18-rc6 +# Sun Sep 10 10:22:57 2006 # CONFIG_PPC64=y CONFIG_64BIT=y CONFIG_PPC_MERGE=y CONFIG_MMU=y CONFIG_GENERIC_HARDIRQS=y +CONFIG_IRQ_PER_CPU=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_PPC=y CONFIG_EARLY_PRINTK=y CONFIG_COMPAT=y @@ -34,6 +36,7 @@ CONFIG_PPC_STD_MMU=y CONFIG_VIRT_CPU_ACCOUNTING=y CONFIG_SMP=y CONFIG_NR_CPUS=32 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # # Code maturity level options @@ -51,6 +54,7 @@ CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set CONFIG_SYSCTL=y CONFIG_AUDIT=y CONFIG_AUDITSYSCALL=y @@ -69,10 +73,12 @@ CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y +CONFIG_RT_MUTEXES=y CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 # CONFIG_SLOB is not set @@ -113,12 +119,17 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" CONFIG_PPC_ISERIES=y # CONFIG_EMBEDDED6xx is not set # CONFIG_APUS is not set +# CONFIG_PPC_CELL is not set +# CONFIG_PPC_CELL_NATIVE is not set +# CONFIG_UDBG_RTAS_CONSOLE is not set # CONFIG_PPC_RTAS is not set # CONFIG_MMIO_NVRAM is not set CONFIG_IBMVIO=y # CONFIG_PPC_MPC106 is not set +# CONFIG_PPC_970_NAP is not set # CONFIG_CPU_FREQ is not set # CONFIG_WANT_EARLY_SERIAL is not set +# CONFIG_MPIC is not set # # Kernel options @@ -135,6 +146,7 @@ CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set CONFIG_FORCE_MAX_ZONEORDER=13 CONFIG_IOMMU_VMERGE=y +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_IRQ_ALL_CPUS=y CONFIG_LPARCFG=y # CONFIG_NUMA is not set @@ -149,6 +161,7 @@ CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_RESOURCES_64BIT=y # CONFIG_PPC_64K_PAGES is not set # CONFIG_SCHED_SMT is not set CONFIG_PROC_DEVICETREE=y @@ -160,10 +173,12 @@ CONFIG_ISA_DMA_API=y # Bus options # CONFIG_GENERIC_ISA_DMA=y +# CONFIG_MPIC_WEIRD is not set # CONFIG_PPC_I8259 is not set # CONFIG_PPC_INDIRECT_PCI is not set CONFIG_PCI=y CONFIG_PCI_DOMAINS=y +# CONFIG_PCIEPORTBUS is not set # CONFIG_PCI_DEBUG is not set # @@ -207,6 +222,8 @@ CONFIG_INET_ESP=m CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_TUNNEL=m CONFIG_INET_TUNNEL=y +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set @@ -219,6 +236,7 @@ CONFIG_TCP_CONG_BIC=y # CONFIG_IPV6 is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set @@ -246,9 +264,11 @@ CONFIG_NETFILTER_XT_MATCH_MARK=m # CONFIG_NETFILTER_XT_MATCH_POLICY is not set # CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set CONFIG_NETFILTER_XT_MATCH_REALM=m CONFIG_NETFILTER_XT_MATCH_SCTP=m CONFIG_NETFILTER_XT_MATCH_STATE=m +# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set CONFIG_NETFILTER_XT_MATCH_STRING=m CONFIG_NETFILTER_XT_MATCH_TCPMSS=m @@ -267,6 +287,7 @@ CONFIG_IP_NF_TFTP=m CONFIG_IP_NF_AMANDA=m # CONFIG_IP_NF_PPTP is not set # CONFIG_IP_NF_H323 is not set +# CONFIG_IP_NF_SIP is not set CONFIG_IP_NF_QUEUE=m CONFIG_IP_NF_IPTABLES=m CONFIG_IP_NF_MATCH_IPRANGE=m @@ -360,6 +381,7 @@ CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_FW_LOADER=m # CONFIG_DEBUG_DRIVER is not set +# CONFIG_SYS_HYPERVISOR is not set # # Connector - unified userspace <-> kernelspace linker @@ -396,6 +418,7 @@ CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=65536 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set @@ -453,6 +476,7 @@ CONFIG_SCSI_FC_ATTRS=y # CONFIG_MEGARAID_LEGACY is not set # CONFIG_MEGARAID_SAS is not set # CONFIG_SCSI_SATA is not set +# CONFIG_SCSI_HPTIOP is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_EATA is not set @@ -464,7 +488,6 @@ CONFIG_SCSI_IBMVSCSI=m # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_SYM53C8XX_2 is not set # CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set # CONFIG_SCSI_QLA_FC is not set # CONFIG_SCSI_LPFC is not set @@ -481,9 +504,7 @@ CONFIG_MD_LINEAR=y CONFIG_MD_RAID0=y CONFIG_MD_RAID1=y CONFIG_MD_RAID10=m -CONFIG_MD_RAID5=y -# CONFIG_MD_RAID5_RESHAPE is not set -CONFIG_MD_RAID6=m +# CONFIG_MD_RAID456 is not set CONFIG_MD_MULTIPATH=m CONFIG_MD_FAULTY=m CONFIG_BLK_DEV_DM=y @@ -596,6 +617,7 @@ CONFIG_E1000=m # CONFIG_CHELSIO_T1 is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set +# CONFIG_MYRI10GE is not set # # Token Ring devices @@ -706,6 +728,7 @@ CONFIG_LEGACY_PTY_COUNT=256 # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_HW_RANDOM is not set CONFIG_GEN_RTC=y # CONFIG_GEN_RTC_X is not set # CONFIG_DTLK is not set @@ -741,7 +764,6 @@ CONFIG_MAX_RAW_DEVS=256 # # Dallas's 1-wire bus # -# CONFIG_W1 is not set # # Hardware Monitoring support @@ -757,6 +779,7 @@ CONFIG_MAX_RAW_DEVS=256 # Multimedia devices # # CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices @@ -766,7 +789,9 @@ CONFIG_MAX_RAW_DEVS=256 # # Graphics support # +CONFIG_FIRMWARE_EDID=y # CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -801,6 +826,14 @@ CONFIG_USB_ARCH_HAS_EHCI=y # CONFIG_NEW_LEDS is not set # +# LED drivers +# + +# +# LED Triggers +# + +# # InfiniBand support # # CONFIG_INFINIBAND is not set @@ -815,6 +848,19 @@ CONFIG_USB_ARCH_HAS_EHCI=y # CONFIG_RTC_CLASS is not set # +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + +# # File systems # CONFIG_EXT2_FS=y @@ -843,7 +889,6 @@ CONFIG_JFS_SECURITY=y # CONFIG_JFS_STATISTICS is not set CONFIG_FS_POSIX_ACL=y CONFIG_XFS_FS=m -CONFIG_XFS_EXPORT=y # CONFIG_XFS_QUOTA is not set CONFIG_XFS_SECURITY=y CONFIG_XFS_POSIX_ACL=y @@ -852,6 +897,7 @@ CONFIG_XFS_POSIX_ACL=y # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set CONFIG_DNOTIFY=y CONFIG_AUTOFS_FS=m @@ -933,8 +979,10 @@ CONFIG_RPCSEC_GSS_SPKM3=m # CONFIG_SMB_FS is not set CONFIG_CIFS=m # CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set CONFIG_CIFS_XATTR=y CONFIG_CIFS_POSIX=y +# CONFIG_CIFS_DEBUG2 is not set # CONFIG_CIFS_EXPERIMENTAL is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -1013,10 +1061,12 @@ CONFIG_TEXTSEARCH=y CONFIG_TEXTSEARCH_KMP=m CONFIG_TEXTSEARCH_BM=m CONFIG_TEXTSEARCH_FSM=m +CONFIG_PLIST=y # # Instrumentation Support # +# CONFIG_PROFILING is not set # CONFIG_KPROBES is not set # @@ -1024,14 +1074,19 @@ CONFIG_TEXTSEARCH_FSM=m # # CONFIG_PRINTK_TIME is not set CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_KERNEL=y CONFIG_LOG_BUF_SHIFT=17 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_RWSEMS is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set CONFIG_DEBUG_FS=y @@ -1042,11 +1097,7 @@ CONFIG_DEBUG_STACKOVERFLOW=y CONFIG_DEBUG_STACK_USAGE=y # CONFIG_DEBUGGER is not set CONFIG_IRQSTACKS=y -# CONFIG_PPC_EARLY_DEBUG_LPAR is not set -# CONFIG_PPC_EARLY_DEBUG_G5 is not set -# CONFIG_PPC_EARLY_DEBUG_RTAS is not set -# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set -# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set +# CONFIG_PPC_EARLY_DEBUG is not set # # Security options diff --git a/arch/powerpc/configs/maple_defconfig b/arch/powerpc/configs/maple_defconfig index 80a0db43aeb7..62ba66091a13 100644 --- a/arch/powerpc/configs/maple_defconfig +++ b/arch/powerpc/configs/maple_defconfig @@ -1,15 +1,18 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.16-rc6 -# Wed Mar 15 16:19:54 2006 +# Linux kernel version: 2.6.18-rc6 +# Sun Sep 10 10:24:55 2006 # CONFIG_PPC64=y CONFIG_64BIT=y CONFIG_PPC_MERGE=y CONFIG_MMU=y CONFIG_GENERIC_HARDIRQS=y +CONFIG_IRQ_PER_CPU=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_PPC=y CONFIG_EARLY_PRINTK=y CONFIG_COMPAT=y @@ -29,8 +32,10 @@ CONFIG_POWER4=y CONFIG_PPC_FPU=y # CONFIG_ALTIVEC is not set CONFIG_PPC_STD_MMU=y +CONFIG_VIRT_CPU_ACCOUNTING=y CONFIG_SMP=y CONFIG_NR_CPUS=2 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # # Code maturity level options @@ -48,11 +53,13 @@ CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y # CONFIG_CPUSETS is not set +# CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" CONFIG_CC_OPTIMIZE_FOR_SIZE=y # CONFIG_EMBEDDED is not set @@ -64,14 +71,12 @@ CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y +CONFIG_RT_MUTEXES=y CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y -CONFIG_CC_ALIGN_FUNCTIONS=0 -CONFIG_CC_ALIGN_LABELS=0 -CONFIG_CC_ALIGN_LOOPS=0 -CONFIG_CC_ALIGN_JUMPS=0 CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 # CONFIG_SLOB is not set @@ -82,7 +87,6 @@ CONFIG_BASE_SMALL=0 CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set -CONFIG_OBSOLETE_MODPARM=y CONFIG_MODVERSIONS=y CONFIG_MODULE_SRCVERSION_ALL=y CONFIG_KMOD=y @@ -91,6 +95,7 @@ CONFIG_STOP_MACHINE=y # # Block layer # +# CONFIG_BLK_DEV_IO_TRACE is not set # # IO Schedulers @@ -116,14 +121,18 @@ CONFIG_PPC_MULTIPLATFORM=y # CONFIG_PPC_PMAC is not set CONFIG_PPC_MAPLE=y # CONFIG_PPC_CELL is not set +# CONFIG_PPC_CELL_NATIVE is not set +# CONFIG_PPC_IBM_CELL_BLADE is not set +# CONFIG_UDBG_RTAS_CONSOLE is not set CONFIG_U3_DART=y -CONFIG_MPIC=y # CONFIG_PPC_RTAS is not set # CONFIG_MMIO_NVRAM is not set CONFIG_MPIC_BROKEN_U3=y # CONFIG_PPC_MPC106 is not set +CONFIG_PPC_970_NAP=y # CONFIG_CPU_FREQ is not set # CONFIG_WANT_EARLY_SERIAL is not set +CONFIG_MPIC=y # # Kernel options @@ -140,6 +149,7 @@ CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set CONFIG_FORCE_MAX_ZONEORDER=13 CONFIG_IOMMU_VMERGE=y +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_KEXEC=y # CONFIG_CRASH_DUMP is not set CONFIG_IRQ_ALL_CPUS=y @@ -155,6 +165,7 @@ CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_RESOURCES_64BIT=y # CONFIG_PPC_64K_PAGES is not set # CONFIG_SCHED_SMT is not set CONFIG_PROC_DEVICETREE=y @@ -167,11 +178,12 @@ CONFIG_ISA_DMA_API=y # Bus options # CONFIG_GENERIC_ISA_DMA=y +# CONFIG_MPIC_WEIRD is not set # CONFIG_PPC_I8259 is not set # CONFIG_PPC_INDIRECT_PCI is not set CONFIG_PCI=y CONFIG_PCI_DOMAINS=y -CONFIG_PCI_LEGACY_PROC=y +# CONFIG_PCIEPORTBUS is not set # CONFIG_PCI_DEBUG is not set # @@ -197,6 +209,8 @@ CONFIG_NET=y CONFIG_PACKET=y CONFIG_PACKET_MMAP=y CONFIG_UNIX=y +CONFIG_XFRM=y +CONFIG_XFRM_USER=m # CONFIG_NET_KEY is not set CONFIG_INET=y CONFIG_IP_MULTICAST=y @@ -214,12 +228,18 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_INET_AH is not set # CONFIG_INET_ESP is not set # CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set # CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_BIC=y # CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set # @@ -274,6 +294,7 @@ CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set # CONFIG_DEBUG_DRIVER is not set +# CONFIG_SYS_HYPERVISOR is not set # # Connector - unified userspace <-> kernelspace linker @@ -310,6 +331,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # CONFIG_BLK_DEV_INITRD is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set @@ -474,7 +496,7 @@ CONFIG_E1000=y # CONFIG_SKY2 is not set # CONFIG_SK98LIN is not set # CONFIG_VIA_VELOCITY is not set -# CONFIG_TIGON3 is not set +CONFIG_TIGON3=y # CONFIG_BNX2 is not set # CONFIG_MV643XX_ETH is not set @@ -484,6 +506,7 @@ CONFIG_E1000=y # CONFIG_CHELSIO_T1 is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set +# CONFIG_MYRI10GE is not set # # Token Ring devices @@ -556,6 +579,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=1200 CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set # CONFIG_SERIAL_NONSTANDARD is not set # @@ -563,6 +587,7 @@ CONFIG_HW_CONSOLE=y # CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_PCI=y CONFIG_SERIAL_8250_NR_UARTS=4 CONFIG_SERIAL_8250_RUNTIME_UARTS=4 # CONFIG_SERIAL_8250_EXTENDED is not set @@ -586,7 +611,7 @@ CONFIG_LEGACY_PTY_COUNT=256 # Watchdog Cards # # CONFIG_WATCHDOG is not set -# CONFIG_RTC is not set +# CONFIG_HW_RANDOM is not set CONFIG_GEN_RTC=y # CONFIG_GEN_RTC_X is not set # CONFIG_DTLK is not set @@ -632,10 +657,10 @@ CONFIG_I2C_AMD8111=y # CONFIG_I2C_I810 is not set # CONFIG_I2C_PIIX4 is not set # CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_OCORES is not set # CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_PROSAVAGE is not set # CONFIG_I2C_SAVAGE4 is not set -# CONFIG_SCx200_ACB is not set # CONFIG_I2C_SIS5595 is not set # CONFIG_I2C_SIS630 is not set # CONFIG_I2C_SIS96X is not set @@ -654,9 +679,7 @@ CONFIG_I2C_AMD8111=y # CONFIG_SENSORS_PCF8574 is not set # CONFIG_SENSORS_PCA9539 is not set # CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_RTC8564 is not set # CONFIG_SENSORS_MAX6875 is not set -# CONFIG_RTC_X1205_I2C is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set @@ -671,7 +694,6 @@ CONFIG_I2C_AMD8111=y # # Dallas's 1-wire bus # -# CONFIG_W1 is not set # # Hardware Monitoring support @@ -684,22 +706,21 @@ CONFIG_I2C_AMD8111=y # # -# Multimedia Capabilities Port drivers -# - -# # Multimedia devices # # CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices # # CONFIG_DVB is not set +# CONFIG_USB_DABUSB is not set # # Graphics support # +CONFIG_FIRMWARE_EDID=y # CONFIG_FB is not set # @@ -707,6 +728,7 @@ CONFIG_I2C_AMD8111=y # # CONFIG_VGA_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -718,6 +740,7 @@ CONFIG_DUMMY_CONSOLE=y # CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y CONFIG_USB=y # CONFIG_USB_DEBUG is not set @@ -735,6 +758,7 @@ CONFIG_USB_DEVICEFS=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_SPLIT_ISO=y CONFIG_USB_EHCI_ROOT_HUB_TT=y +# CONFIG_USB_EHCI_TT_NEWSCHED is not set # CONFIG_USB_ISP116X_HCD is not set CONFIG_USB_OHCI_HCD=y # CONFIG_USB_OHCI_BIG_ENDIAN is not set @@ -771,9 +795,7 @@ CONFIG_USB_HIDINPUT=y # CONFIG_USB_ACECAD is not set # CONFIG_USB_KBTAB is not set # CONFIG_USB_POWERMATE is not set -# CONFIG_USB_MTOUCH is not set -# CONFIG_USB_ITMTOUCH is not set -# CONFIG_USB_EGALAX is not set +# CONFIG_USB_TOUCHSCREEN is not set # CONFIG_USB_YEALINK is not set # CONFIG_USB_XPAD is not set # CONFIG_USB_ATI_REMOTE is not set @@ -787,15 +809,6 @@ CONFIG_USB_HIDINPUT=y # CONFIG_USB_MDC800 is not set # -# USB Multimedia devices -# -# CONFIG_USB_DABUSB is not set - -# -# Video4Linux support is needed for USB Multimedia device support -# - -# # USB Network Adapters # # CONFIG_USB_CATC is not set @@ -816,7 +829,7 @@ CONFIG_USB_SERIAL=y # CONFIG_USB_SERIAL_CONSOLE is not set CONFIG_USB_SERIAL_GENERIC=y # CONFIG_USB_SERIAL_AIRPRIME is not set -# CONFIG_USB_SERIAL_ANYDATA is not set +# CONFIG_USB_SERIAL_ARK3116 is not set # CONFIG_USB_SERIAL_BELKIN is not set # CONFIG_USB_SERIAL_WHITEHEAT is not set # CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set @@ -824,6 +837,7 @@ CONFIG_USB_SERIAL_GENERIC=y CONFIG_USB_SERIAL_CYPRESS_M8=m # CONFIG_USB_SERIAL_EMPEG is not set # CONFIG_USB_SERIAL_FTDI_SIO is not set +# CONFIG_USB_SERIAL_FUNSOFT is not set # CONFIG_USB_SERIAL_VISOR is not set # CONFIG_USB_SERIAL_IPAQ is not set # CONFIG_USB_SERIAL_IR is not set @@ -848,12 +862,15 @@ CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y # CONFIG_USB_SERIAL_KLSI is not set # CONFIG_USB_SERIAL_KOBIL_SCT is not set # CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_NAVMAN is not set # CONFIG_USB_SERIAL_PL2303 is not set # CONFIG_USB_SERIAL_HP4X is not set # CONFIG_USB_SERIAL_SAFE is not set +# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set CONFIG_USB_SERIAL_TI=m # CONFIG_USB_SERIAL_CYBERJACK is not set # CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OPTION is not set # CONFIG_USB_SERIAL_OMNINET is not set CONFIG_USB_EZUSB=y @@ -867,10 +884,12 @@ CONFIG_USB_EZUSB=y # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set # CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set # CONFIG_USB_PHIDGETKIT is not set # CONFIG_USB_PHIDGETSERVO is not set # CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_APPLEDISPLAY is not set # CONFIG_USB_SISUSBVGA is not set # CONFIG_USB_LD is not set # CONFIG_USB_TEST is not set @@ -890,6 +909,19 @@ CONFIG_USB_EZUSB=y # CONFIG_MMC is not set # +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + +# # InfiniBand support # # CONFIG_INFINIBAND is not set @@ -899,6 +931,24 @@ CONFIG_USB_EZUSB=y # # +# Real Time Clock +# +# CONFIG_RTC_CLASS is not set + +# +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + +# # File systems # CONFIG_EXT2_FS=y @@ -917,6 +967,7 @@ CONFIG_FS_POSIX_ACL=y # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set @@ -949,7 +1000,6 @@ CONFIG_TMPFS=y CONFIG_HUGETLBFS=y CONFIG_HUGETLB_PAGE=y CONFIG_RAMFS=y -# CONFIG_RELAYFS_FS is not set # CONFIG_CONFIGFS_FS is not set # @@ -1067,6 +1117,7 @@ CONFIG_CRC_CCITT=y CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y +CONFIG_PLIST=y # # Instrumentation Support @@ -1079,14 +1130,20 @@ CONFIG_ZLIB_INFLATE=y # # CONFIG_PRINTK_TIME is not set CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_KERNEL=y CONFIG_LOG_BUF_SHIFT=17 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set CONFIG_DEBUG_SLAB=y -# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_SLAB_LEAK is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_RWSEMS is not set CONFIG_DEBUG_SPINLOCK_SLEEP=y +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set CONFIG_DEBUG_FS=y @@ -1100,11 +1157,7 @@ CONFIG_XMON=y CONFIG_XMON_DEFAULT=y # CONFIG_IRQSTACKS is not set CONFIG_BOOTX_TEXT=y -# CONFIG_PPC_EARLY_DEBUG_LPAR is not set -# CONFIG_PPC_EARLY_DEBUG_G5 is not set -# CONFIG_PPC_EARLY_DEBUG_RTAS is not set -# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set -# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set +# CONFIG_PPC_EARLY_DEBUG is not set # # Security options diff --git a/arch/powerpc/configs/mpc7448_hpc2_defconfig b/arch/powerpc/configs/mpc7448_hpc2_defconfig new file mode 100644 index 000000000000..719fba4eb421 --- /dev/null +++ b/arch/powerpc/configs/mpc7448_hpc2_defconfig @@ -0,0 +1,963 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.18-rc6 +# Sun Sep 10 10:26:55 2006 +# +# CONFIG_PPC64 is not set +CONFIG_PPC32=y +CONFIG_PPC_MERGE=y +CONFIG_MMU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_IRQ_PER_CPU=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_PPC=y +CONFIG_EARLY_PRINTK=y +CONFIG_GENERIC_NVRAM=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_PPC_OF=y +CONFIG_PPC_UDBG_16550=y +# CONFIG_GENERIC_TBSYNC is not set +CONFIG_DEFAULT_UIMAGE=y + +# +# Processor support +# +CONFIG_CLASSIC32=y +# CONFIG_PPC_52xx is not set +# CONFIG_PPC_82xx is not set +# CONFIG_PPC_83xx is not set +# CONFIG_PPC_85xx is not set +# CONFIG_PPC_86xx is not set +# CONFIG_40x is not set +# CONFIG_44x is not set +# CONFIG_8xx is not set +# CONFIG_E200 is not set +CONFIG_6xx=y +CONFIG_PPC_FPU=y +# CONFIG_ALTIVEC is not set +CONFIG_PPC_STD_MMU=y +CONFIG_PPC_STD_MMU_32=y +# CONFIG_SMP is not set +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +# CONFIG_RELAY is not set +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_EMBEDDED=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_RT_MUTEXES=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SHMEM=y +CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# Block layer +# +CONFIG_LBD=y +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# +# Platform support +# +# CONFIG_PPC_MULTIPLATFORM is not set +# CONFIG_PPC_ISERIES is not set +CONFIG_EMBEDDED6xx=y +# CONFIG_APUS is not set +# CONFIG_PPC_CELL is not set +# CONFIG_PPC_CELL_NATIVE is not set +# CONFIG_UDBG_RTAS_CONSOLE is not set +# CONFIG_PPC_RTAS is not set +# CONFIG_MMIO_NVRAM is not set +# CONFIG_PPC_MPC106 is not set +# CONFIG_PPC_970_NAP is not set +# CONFIG_CPU_FREQ is not set +# CONFIG_TAU is not set +# CONFIG_PPC_TODC is not set +# CONFIG_KATANA is not set +# CONFIG_WILLOW is not set +# CONFIG_CPCI690 is not set +# CONFIG_POWERPMC250 is not set +# CONFIG_CHESTNUT is not set +# CONFIG_SPRUCE is not set +# CONFIG_HDPU is not set +# CONFIG_EV64260 is not set +# CONFIG_LOPEC is not set +# CONFIG_MVME5100 is not set +# CONFIG_PPLUS is not set +# CONFIG_PRPMC750 is not set +# CONFIG_PRPMC800 is not set +# CONFIG_SANDPOINT is not set +CONFIG_MPC7448HPC2=y +# CONFIG_RADSTONE_PPC7D is not set +# CONFIG_PAL4 is not set +# CONFIG_GEMINI is not set +# CONFIG_EST8260 is not set +# CONFIG_SBC82xx is not set +# CONFIG_SBS8260 is not set +# CONFIG_RPX8260 is not set +# CONFIG_TQM8260 is not set +# CONFIG_ADS8272 is not set +# CONFIG_PQ2FADS is not set +# CONFIG_LITE5200 is not set +# CONFIG_EV64360 is not set +CONFIG_TSI108_BRIDGE=y +# CONFIG_WANT_EARLY_SERIAL is not set +CONFIG_MPIC=y + +# +# Kernel options +# +# CONFIG_HIGHMEM is not set +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_MISC=y +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_PROC_DEVICETREE=y +# CONFIG_CMDLINE_BOOL is not set +# CONFIG_PM is not set +# CONFIG_SECCOMP is not set +CONFIG_ISA_DMA_API=y + +# +# Bus options +# +CONFIG_GENERIC_ISA_DMA=y +CONFIG_MPIC_WEIRD=y +# CONFIG_PPC_I8259 is not set +# CONFIG_PPC_INDIRECT_PCI is not set +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +# CONFIG_PCIEPORTBUS is not set + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# PCI Hotplug Support +# +# CONFIG_HOTPLUG_PCI is not set + +# +# Advanced setup +# +# CONFIG_ADVANCED_OPTIONS is not set + +# +# Default settings for advanced configuration options are used +# +CONFIG_HIGHMEM_START=0xfe000000 +CONFIG_LOWMEM_SIZE=0x30000000 +CONFIG_KERNEL_START=0xc0000000 +CONFIG_TASK_SIZE=0x80000000 +CONFIG_BOOT_LOAD=0x00800000 + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_NETDEBUG is not set +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +CONFIG_XFRM=y +CONFIG_XFRM_USER=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_BIC=y +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=131072 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +CONFIG_BLK_DEV_INITRD=y +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI Transport Attributes +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set + +# +# SCSI low-level drivers +# +# CONFIG_ISCSI_TCP is not set +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set +CONFIG_SCSI_SATA=y +# CONFIG_SCSI_SATA_AHCI is not set +# CONFIG_SCSI_SATA_SVW is not set +# CONFIG_SCSI_ATA_PIIX is not set +CONFIG_SCSI_SATA_MV=y +# CONFIG_SCSI_SATA_NV is not set +# CONFIG_SCSI_PDC_ADMA is not set +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_SATA_QSTOR is not set +# CONFIG_SCSI_SATA_PROMISE is not set +# CONFIG_SCSI_SATA_SX4 is not set +# CONFIG_SCSI_SATA_SIL is not set +# CONFIG_SCSI_SATA_SIL24 is not set +# CONFIG_SCSI_SATA_SIS is not set +# CONFIG_SCSI_SATA_ULI is not set +# CONFIG_SCSI_SATA_VIA is not set +# CONFIG_SCSI_SATA_VITESSE is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_LPFC is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_SPI is not set +# CONFIG_FUSION_FC is not set +# CONFIG_FUSION_SAS is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Macintosh device drivers +# +# CONFIG_WINDFARM is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# PHY device support +# +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_FIXED_PHY is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +# CONFIG_DGRS is not set +# CONFIG_EEPRO100 is not set +CONFIG_E100=y +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +CONFIG_8139TOO=y +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_8139_OLD_RX_RESET is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +# CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_CHELSIO_T1 is not set +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set +# CONFIG_MYRI10GE is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_NVRAM is not set +CONFIG_GEN_RTC=y +# CONFIG_GEN_RTC_X is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set +# CONFIG_TELCLOCK is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set + +# +# Dallas's 1-wire bus +# + +# +# Hardware Monitoring support +# +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_V4L2=y + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FIRMWARE_EDID=y +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +# CONFIG_USB is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + +# +# InfiniBand support +# +# CONFIG_INFINIBAND is not set + +# +# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# + +# +# Real Time Clock +# +# CONFIG_RTC_CLASS is not set + +# +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_PLIST=y + +# +# Instrumentation Support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_DEBUG_FS is not set +# CONFIG_UNWIND_INFO is not set +# CONFIG_BOOTX_TEXT is not set +# CONFIG_PPC_EARLY_DEBUG is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# diff --git a/arch/powerpc/configs/mpc834x_itx_defconfig b/arch/powerpc/configs/mpc834x_itx_defconfig new file mode 100644 index 000000000000..8da6a47f0339 --- /dev/null +++ b/arch/powerpc/configs/mpc834x_itx_defconfig @@ -0,0 +1,1344 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.18-rc6 +# Sun Sep 10 10:28:05 2006 +# +# CONFIG_PPC64 is not set +CONFIG_PPC32=y +CONFIG_PPC_MERGE=y +CONFIG_MMU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_IRQ_PER_CPU=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_PPC=y +CONFIG_EARLY_PRINTK=y +CONFIG_GENERIC_NVRAM=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_PPC_OF=y +CONFIG_PPC_UDBG_16550=y +# CONFIG_GENERIC_TBSYNC is not set +CONFIG_DEFAULT_UIMAGE=y + +# +# Processor support +# +# CONFIG_CLASSIC32 is not set +# CONFIG_PPC_52xx is not set +# CONFIG_PPC_82xx is not set +CONFIG_PPC_83xx=y +# CONFIG_PPC_85xx is not set +# CONFIG_PPC_86xx is not set +# CONFIG_40x is not set +# CONFIG_44x is not set +# CONFIG_8xx is not set +# CONFIG_E200 is not set +CONFIG_6xx=y +CONFIG_83xx=y +CONFIG_PPC_FPU=y +CONFIG_PPC_STD_MMU=y +CONFIG_PPC_STD_MMU_32=y +# CONFIG_SMP is not set +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +# CONFIG_RELAY is not set +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_EMBEDDED=y +# CONFIG_KALLSYMS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_RT_MUTEXES=y +CONFIG_FUTEX=y +# CONFIG_EPOLL is not set +CONFIG_SHMEM=y +CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_KMOD is not set + +# +# Block layer +# +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_PPC_GEN550=y +# CONFIG_WANT_EARLY_SERIAL is not set + +# +# Platform support +# +# CONFIG_MPC834x_SYS is not set +CONFIG_MPC834x_ITX=y +CONFIG_MPC834x=y +# CONFIG_MPIC is not set + +# +# Kernel options +# +# CONFIG_HIGHMEM is not set +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_PROC_DEVICETREE=y +# CONFIG_CMDLINE_BOOL is not set +# CONFIG_PM is not set +CONFIG_SECCOMP=y +CONFIG_ISA_DMA_API=y + +# +# Bus options +# +CONFIG_GENERIC_ISA_DMA=y +# CONFIG_MPIC_WEIRD is not set +# CONFIG_PPC_I8259 is not set +CONFIG_PPC_INDIRECT_PCI=y +CONFIG_FSL_SOC=y +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +# CONFIG_PCIEPORTBUS is not set +# CONFIG_PCI_DEBUG is not set + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# PCI Hotplug Support +# +# CONFIG_HOTPLUG_PCI is not set + +# +# Advanced setup +# +# CONFIG_ADVANCED_OPTIONS is not set + +# +# Default settings for advanced configuration options are used +# +CONFIG_HIGHMEM_START=0xfe000000 +CONFIG_LOWMEM_SIZE=0x30000000 +CONFIG_KERNEL_START=0xc0000000 +CONFIG_TASK_SIZE=0x80000000 +CONFIG_BOOT_LOAD=0x00800000 + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_NETDEBUG is not set +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_BIC=y +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_PARTITIONS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +# CONFIG_MTD_BLOCK is not set +# CONFIG_MTD_BLOCK_RO is not set +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=0xfe000000 +CONFIG_MTD_PHYSMAP_LEN=0x1000000 +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_DATAFLASH is not set +# CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# OneNAND Flash Device Drivers +# +# CONFIG_MTD_ONENAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=32768 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +CONFIG_BLK_DEV_INITRD=y +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y +# CONFIG_BLK_DEV_IDE is not set +# CONFIG_BLK_DEV_HD_ONLY is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +CONFIG_CHR_DEV_SG=y +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI Transport Attributes +# +CONFIG_SCSI_SPI_ATTRS=y +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set + +# +# SCSI low-level drivers +# +# CONFIG_ISCSI_TCP is not set +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set +CONFIG_SCSI_SATA=y +# CONFIG_SCSI_SATA_AHCI is not set +# CONFIG_SCSI_SATA_SVW is not set +# CONFIG_SCSI_ATA_PIIX is not set +# CONFIG_SCSI_SATA_MV is not set +# CONFIG_SCSI_SATA_NV is not set +# CONFIG_SCSI_PDC_ADMA is not set +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_SATA_QSTOR is not set +# CONFIG_SCSI_SATA_PROMISE is not set +# CONFIG_SCSI_SATA_SX4 is not set +CONFIG_SCSI_SATA_SIL=y +# CONFIG_SCSI_SATA_SIL24 is not set +# CONFIG_SCSI_SATA_SIS is not set +# CONFIG_SCSI_SATA_ULI is not set +# CONFIG_SCSI_SATA_VIA is not set +# CONFIG_SCSI_SATA_VITESSE is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_LPFC is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Multi-device support (RAID and LVM) +# +CONFIG_MD=y +CONFIG_BLK_DEV_MD=y +CONFIG_MD_LINEAR=y +CONFIG_MD_RAID0=y +CONFIG_MD_RAID1=y +# CONFIG_MD_RAID10 is not set +# CONFIG_MD_RAID456 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_MD_FAULTY is not set +# CONFIG_BLK_DEV_DM is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_SPI is not set +# CONFIG_FUSION_FC is not set +# CONFIG_FUSION_SAS is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Macintosh device drivers +# +# CONFIG_WINDFARM is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# PHY device support +# +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +CONFIG_CICADA_PHY=y +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_FIXED_PHY is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +# CONFIG_DGRS is not set +# CONFIG_EEPRO100 is not set +CONFIG_E100=y +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +# CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set +CONFIG_GIANFAR=y +CONFIG_GFAR_NAPI=y + +# +# Ethernet (10000 Mbit) +# +# CONFIG_CHELSIO_T1 is not set +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set +# CONFIG_MYRI10GE is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_83xx_WDT=y + +# +# PCI-based Watchdog Cards +# +# CONFIG_PCIPCWATCHDOG is not set +# CONFIG_WDTPCI is not set + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +CONFIG_HW_RANDOM=y +# CONFIG_NVRAM is not set +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set +# CONFIG_TELCLOCK is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +# CONFIG_I2C_PIIX4 is not set +CONFIG_I2C_MPC=y +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_VOODOO3 is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_M41T00 is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# SPI support +# +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +CONFIG_SPI_BITBANG=y +CONFIG_SPI_MPC83xx=y + +# +# SPI Protocol Masters +# + +# +# Dallas's 1-wire bus +# + +# +# Hardware Monitoring support +# +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM70 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_VT8231 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_V4L2=y + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set +# CONFIG_USB_DABUSB is not set + +# +# Graphics support +# +CONFIG_FIRMWARE_EDID=y +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +CONFIG_USB_EHCI_HCD=y +# CONFIG_USB_EHCI_SPLIT_ISO is not set +# CONFIG_USB_EHCI_ROOT_HUB_TT is not set +# CONFIG_USB_EHCI_TT_NEWSCHED is not set +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +CONFIG_USB_UHCI_HCD=y +# CONFIG_USB_SL811_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Input Devices +# +# CONFIG_USB_HID is not set + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_ACECAD is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set +# CONFIG_USB_TOUCHSCREEN is not set +# CONFIG_USB_YEALINK is not set +# CONFIG_USB_XPAD is not set +# CONFIG_USB_ATI_REMOTE is not set +# CONFIG_USB_ATI_REMOTE2 is not set +# CONFIG_USB_KEYSPAN_REMOTE is not set +# CONFIG_USB_APPLETOUCH is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +CONFIG_USB_MON=y + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGETKIT is not set +# CONFIG_USB_PHIDGETSERVO is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TEST is not set + +# +# USB DSL modem support +# + +# +# USB Gadget Support +# +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG_FILES is not set +CONFIG_USB_GADGET_SELECTED=y +CONFIG_USB_GADGET_NET2280=y +CONFIG_USB_NET2280=y +# CONFIG_USB_GADGET_PXA2XX is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_ZERO is not set +CONFIG_USB_ETH=y +CONFIG_USB_ETH_RNDIS=y +# CONFIG_USB_GADGETFS is not set +# CONFIG_USB_FILE_STORAGE is not set +# CONFIG_USB_G_SERIAL is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + +# +# InfiniBand support +# +# CONFIG_INFINIBAND is not set + +# +# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# + +# +# Real Time Clock +# +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y + +# +# RTC drivers +# +# CONFIG_RTC_DRV_X1205 is not set +CONFIG_RTC_DRV_DS1307=y +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_TEST is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# DMA Engine support +# +CONFIG_DMA_ENGINE=y + +# +# DMA Clients +# +CONFIG_NET_DMA=y + +# +# DMA Devices +# +CONFIG_INTEL_IOATDMA=y + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +# CONFIG_MSDOS_PARTITION is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_PLIST=y + +# +# Instrumentation Support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +CONFIG_PRINTK_TIME=y +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_LOG_BUF_SHIFT=17 +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_RWSEMS is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_FS is not set +# CONFIG_DEBUG_VM is not set +CONFIG_FORCED_INLINING=y +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_DEBUGGER is not set +# CONFIG_BDI_SWITCH is not set +CONFIG_BOOTX_TEXT=y +CONFIG_SERIAL_TEXT_DEBUG=y +# CONFIG_PPC_EARLY_DEBUG is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Hardware crypto devices +# diff --git a/arch/powerpc/configs/mpc834x_sys_defconfig b/arch/powerpc/configs/mpc834x_mds_defconfig index 5078b0441d61..9eefab967898 100644 --- a/arch/powerpc/configs/mpc834x_sys_defconfig +++ b/arch/powerpc/configs/mpc834x_mds_defconfig @@ -1,15 +1,18 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.16-rc6 -# Wed Mar 15 16:19:56 2006 +# Linux kernel version: 2.6.18-rc6 +# Sun Sep 10 10:28:54 2006 # # CONFIG_PPC64 is not set CONFIG_PPC32=y CONFIG_PPC_MERGE=y CONFIG_MMU=y CONFIG_GENERIC_HARDIRQS=y +CONFIG_IRQ_PER_CPU=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_PPC=y CONFIG_EARLY_PRINTK=y CONFIG_GENERIC_NVRAM=y @@ -27,17 +30,19 @@ CONFIG_DEFAULT_UIMAGE=y # CONFIG_PPC_52xx is not set # CONFIG_PPC_82xx is not set CONFIG_PPC_83xx=y +# CONFIG_PPC_85xx is not set +# CONFIG_PPC_86xx is not set # CONFIG_40x is not set # CONFIG_44x is not set # CONFIG_8xx is not set # CONFIG_E200 is not set -# CONFIG_E500 is not set CONFIG_6xx=y CONFIG_83xx=y CONFIG_PPC_FPU=y CONFIG_PPC_STD_MMU=y CONFIG_PPC_STD_MMU_32=y # CONFIG_SMP is not set +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # # Code maturity level options @@ -55,9 +60,11 @@ CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set +# CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_EMBEDDED=y @@ -67,14 +74,12 @@ CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y +CONFIG_RT_MUTEXES=y CONFIG_FUTEX=y # CONFIG_EPOLL is not set CONFIG_SHMEM=y -CONFIG_CC_ALIGN_FUNCTIONS=0 -CONFIG_CC_ALIGN_LABELS=0 -CONFIG_CC_ALIGN_LOOPS=0 -CONFIG_CC_ALIGN_JUMPS=0 CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 # CONFIG_SLOB is not set @@ -85,7 +90,6 @@ CONFIG_BASE_SMALL=0 CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set -CONFIG_OBSOLETE_MODPARM=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set # CONFIG_KMOD is not set @@ -94,6 +98,8 @@ CONFIG_OBSOLETE_MODPARM=y # Block layer # # CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set # # IO Schedulers @@ -114,7 +120,9 @@ CONFIG_PPC_GEN550=y # Platform support # CONFIG_MPC834x_SYS=y +# CONFIG_MPC834x_ITX is not set CONFIG_MPC834x=y +# CONFIG_MPIC is not set # # Kernel options @@ -129,6 +137,7 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT is not set CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y @@ -138,10 +147,10 @@ CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set CONFIG_PROC_DEVICETREE=y # CONFIG_CMDLINE_BOOL is not set # CONFIG_PM is not set -# CONFIG_SOFTWARE_SUSPEND is not set CONFIG_SECCOMP=y CONFIG_ISA_DMA_API=y @@ -149,12 +158,13 @@ CONFIG_ISA_DMA_API=y # Bus options # CONFIG_GENERIC_ISA_DMA=y +# CONFIG_MPIC_WEIRD is not set # CONFIG_PPC_I8259 is not set CONFIG_PPC_INDIRECT_PCI=y CONFIG_FSL_SOC=y CONFIG_PCI=y CONFIG_PCI_DOMAINS=y -# CONFIG_PCI_LEGACY_PROC is not set +# CONFIG_PCIEPORTBUS is not set # # PCCARD (PCMCIA/CardBus) support @@ -192,6 +202,8 @@ CONFIG_NET=y CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y +CONFIG_XFRM=y +CONFIG_XFRM_USER=m # CONFIG_NET_KEY is not set CONFIG_INET=y CONFIG_IP_MULTICAST=y @@ -209,12 +221,18 @@ CONFIG_SYN_COOKIES=y # CONFIG_INET_AH is not set # CONFIG_INET_ESP is not set # CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set # CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_BIC=y # CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set # @@ -268,6 +286,7 @@ CONFIG_TCP_CONG_BIC=y CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set +# CONFIG_SYS_HYPERVISOR is not set # # Connector - unified userspace <-> kernelspace linker @@ -304,6 +323,7 @@ CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=32768 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set @@ -371,6 +391,9 @@ CONFIG_MARVELL_PHY=y # CONFIG_QSEMI_PHY is not set # CONFIG_LXT_PHY is not set # CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_FIXED_PHY is not set # # Ethernet (10 or 100Mbit) @@ -433,6 +456,7 @@ CONFIG_GIANFAR=y # CONFIG_CHELSIO_T1 is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set +# CONFIG_MYRI10GE is not set # # Token Ring devices @@ -507,6 +531,7 @@ CONFIG_INPUT=y # CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_PCI=y CONFIG_SERIAL_8250_NR_UARTS=4 CONFIG_SERIAL_8250_RUNTIME_UARTS=4 # CONFIG_SERIAL_8250_EXTENDED is not set @@ -543,6 +568,7 @@ CONFIG_83xx_WDT=y # # CONFIG_PCIPCWATCHDOG is not set # CONFIG_WDTPCI is not set +# CONFIG_HW_RANDOM is not set # CONFIG_NVRAM is not set CONFIG_GEN_RTC=y # CONFIG_GEN_RTC_X is not set @@ -589,10 +615,10 @@ CONFIG_I2C_CHARDEV=y # CONFIG_I2C_PIIX4 is not set CONFIG_I2C_MPC=y # CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_OCORES is not set # CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_PROSAVAGE is not set # CONFIG_I2C_SAVAGE4 is not set -# CONFIG_SCx200_ACB is not set # CONFIG_I2C_SIS5595 is not set # CONFIG_I2C_SIS630 is not set # CONFIG_I2C_SIS96X is not set @@ -611,10 +637,8 @@ CONFIG_I2C_MPC=y # CONFIG_SENSORS_PCF8574 is not set # CONFIG_SENSORS_PCA9539 is not set # CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_RTC8564 is not set # CONFIG_SENSORS_M41T00 is not set # CONFIG_SENSORS_MAX6875 is not set -# CONFIG_RTC_X1205_I2C is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set @@ -629,13 +653,13 @@ CONFIG_I2C_MPC=y # # Dallas's 1-wire bus # -# CONFIG_W1 is not set # # Hardware Monitoring support # CONFIG_HWMON=y # CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ABITUGURU is not set # CONFIG_SENSORS_ADM1021 is not set # CONFIG_SENSORS_ADM1025 is not set # CONFIG_SENSORS_ADM1026 is not set @@ -664,10 +688,12 @@ CONFIG_HWMON=y # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_SIS5595 is not set # CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set # CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_VIA686A is not set # CONFIG_SENSORS_VT8231 is not set # CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set # CONFIG_SENSORS_W83792D is not set # CONFIG_SENSORS_W83L785TS is not set # CONFIG_SENSORS_W83627HF is not set @@ -679,13 +705,10 @@ CONFIG_HWMON=y # # -# Multimedia Capabilities Port drivers -# - -# # Multimedia devices # # CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices @@ -695,7 +718,9 @@ CONFIG_HWMON=y # # Graphics support # +CONFIG_FIRMWARE_EDID=y # CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -707,6 +732,7 @@ CONFIG_HWMON=y # CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y # CONFIG_USB is not set # @@ -724,6 +750,19 @@ CONFIG_USB_ARCH_HAS_OHCI=y # CONFIG_MMC is not set # +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + +# # InfiniBand support # # CONFIG_INFINIBAND is not set @@ -733,6 +772,24 @@ CONFIG_USB_ARCH_HAS_OHCI=y # # +# Real Time Clock +# +# CONFIG_RTC_CLASS is not set + +# +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + +# # File systems # CONFIG_EXT2_FS=y @@ -753,6 +810,7 @@ CONFIG_FS_MBCACHE=y # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set @@ -781,7 +839,6 @@ CONFIG_SYSFS=y CONFIG_TMPFS=y # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y -# CONFIG_RELAYFS_FS is not set # CONFIG_CONFIGFS_FS is not set # @@ -854,6 +911,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_CRC16 is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set +CONFIG_PLIST=y # # Instrumentation Support @@ -865,15 +923,13 @@ CONFIG_CRC32=y # # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set # CONFIG_DEBUG_KERNEL is not set CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_DEBUG_FS is not set # CONFIG_BOOTX_TEXT is not set # CONFIG_SERIAL_TEXT_DEBUG is not set -# CONFIG_PPC_EARLY_DEBUG_LPAR is not set -# CONFIG_PPC_EARLY_DEBUG_G5 is not set -# CONFIG_PPC_EARLY_DEBUG_RTAS is not set -# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set -# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set +# CONFIG_PPC_EARLY_DEBUG is not set # # Security options diff --git a/arch/powerpc/configs/mpc8540_ads_defconfig b/arch/powerpc/configs/mpc8540_ads_defconfig index 7f0780f1aa39..67e7d0b5793d 100644 --- a/arch/powerpc/configs/mpc8540_ads_defconfig +++ b/arch/powerpc/configs/mpc8540_ads_defconfig @@ -1,16 +1,18 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.16 -# Mon Mar 27 23:37:36 2006 +# Linux kernel version: 2.6.18-rc6 +# Sun Sep 10 10:29:23 2006 # # CONFIG_PPC64 is not set CONFIG_PPC32=y CONFIG_PPC_MERGE=y CONFIG_MMU=y CONFIG_GENERIC_HARDIRQS=y +CONFIG_IRQ_PER_CPU=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_PPC=y CONFIG_EARLY_PRINTK=y CONFIG_GENERIC_NVRAM=y @@ -29,6 +31,7 @@ CONFIG_DEFAULT_UIMAGE=y # CONFIG_PPC_82xx is not set # CONFIG_PPC_83xx is not set CONFIG_PPC_85xx=y +# CONFIG_PPC_86xx is not set # CONFIG_40x is not set # CONFIG_44x is not set # CONFIG_8xx is not set @@ -39,6 +42,7 @@ CONFIG_BOOKE=y CONFIG_FSL_BOOKE=y # CONFIG_PHYS_64BIT is not set CONFIG_SPE=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # # Code maturity level options @@ -56,6 +60,7 @@ CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set @@ -71,10 +76,12 @@ CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y +CONFIG_RT_MUTEXES=y CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 # CONFIG_SLOB is not set @@ -103,15 +110,16 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" -CONFIG_MPIC=y # CONFIG_WANT_EARLY_SERIAL is not set # # Platform support # CONFIG_MPC8540_ADS=y +# CONFIG_MPC85xx_CDS is not set CONFIG_MPC8540=y CONFIG_PPC_INDIRECT_PCI_BE=y +CONFIG_MPIC=y # # Kernel options @@ -127,6 +135,7 @@ CONFIG_PREEMPT_NONE=y CONFIG_BINFMT_ELF=y CONFIG_BINFMT_MISC=y CONFIG_MATH_EMULATION=y +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y @@ -136,16 +145,17 @@ CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set CONFIG_PROC_DEVICETREE=y # CONFIG_CMDLINE_BOOL is not set # CONFIG_PM is not set -# CONFIG_SOFTWARE_SUSPEND is not set # CONFIG_SECCOMP is not set CONFIG_ISA_DMA_API=y # # Bus options # +# CONFIG_MPIC_WEIRD is not set # CONFIG_PPC_I8259 is not set CONFIG_PPC_INDIRECT_PCI=y CONFIG_FSL_SOC=y @@ -187,6 +197,8 @@ CONFIG_NET=y CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y +CONFIG_XFRM=y +CONFIG_XFRM_USER=y # CONFIG_NET_KEY is not set CONFIG_INET=y CONFIG_IP_MULTICAST=y @@ -204,12 +216,18 @@ CONFIG_SYN_COOKIES=y # CONFIG_INET_AH is not set # CONFIG_INET_ESP is not set # CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set # CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_BIC=y # CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set # @@ -264,6 +282,7 @@ CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set # CONFIG_DEBUG_DRIVER is not set +# CONFIG_SYS_HYPERVISOR is not set # # Connector - unified userspace <-> kernelspace linker @@ -295,6 +314,7 @@ CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=32768 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set @@ -355,6 +375,9 @@ CONFIG_PHYLIB=y # CONFIG_QSEMI_PHY is not set # CONFIG_LXT_PHY is not set # CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_FIXED_PHY is not set # # Ethernet (10 or 100Mbit) @@ -464,6 +487,7 @@ CONFIG_LEGACY_PTY_COUNT=256 # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_HW_RANDOM is not set # CONFIG_NVRAM is not set CONFIG_GEN_RTC=y # CONFIG_GEN_RTC_X is not set @@ -473,7 +497,6 @@ CONFIG_GEN_RTC=y # # Ftape, the floppy tape device driver # -# CONFIG_AGP is not set # CONFIG_RAW_DRIVER is not set # @@ -496,13 +519,13 @@ CONFIG_GEN_RTC=y # # Dallas's 1-wire bus # -# CONFIG_W1 is not set # # Hardware Monitoring support # CONFIG_HWMON=y # CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ABITUGURU is not set # CONFIG_SENSORS_F71805F is not set # CONFIG_HWMON_DEBUG_CHIP is not set @@ -514,6 +537,7 @@ CONFIG_HWMON=y # Multimedia devices # # CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices @@ -523,7 +547,9 @@ CONFIG_HWMON=y # # Graphics support # +CONFIG_FIRMWARE_EDID=y # CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -552,6 +578,19 @@ CONFIG_HWMON=y # CONFIG_MMC is not set # +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + +# # InfiniBand support # @@ -560,6 +599,24 @@ CONFIG_HWMON=y # # +# Real Time Clock +# +# CONFIG_RTC_CLASS is not set + +# +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + +# # File systems # CONFIG_EXT2_FS=y @@ -580,6 +637,7 @@ CONFIG_FS_MBCACHE=y # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set @@ -677,6 +735,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_CRC16 is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set +CONFIG_PLIST=y # # Instrumentation Support @@ -688,14 +747,19 @@ CONFIG_CRC32=y # # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_KERNEL=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set -CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set +CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_RWSEMS is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_FS is not set @@ -706,11 +770,7 @@ CONFIG_FORCED_INLINING=y # CONFIG_DEBUGGER is not set # CONFIG_BDI_SWITCH is not set # CONFIG_BOOTX_TEXT is not set -# CONFIG_PPC_EARLY_DEBUG_LPAR is not set -# CONFIG_PPC_EARLY_DEBUG_G5 is not set -# CONFIG_PPC_EARLY_DEBUG_RTAS is not set -# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set -# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set +# CONFIG_PPC_EARLY_DEBUG is not set # # Security options diff --git a/arch/powerpc/configs/mpc85xx_cds_defconfig b/arch/powerpc/configs/mpc85xx_cds_defconfig index 9bb022a523fe..72edf9f66829 100644 --- a/arch/powerpc/configs/mpc85xx_cds_defconfig +++ b/arch/powerpc/configs/mpc85xx_cds_defconfig @@ -1,16 +1,18 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.16 -# Sun Apr 2 11:23:42 2006 +# Linux kernel version: 2.6.18-rc6 +# Sun Sep 10 10:29:49 2006 # # CONFIG_PPC64 is not set CONFIG_PPC32=y CONFIG_PPC_MERGE=y CONFIG_MMU=y CONFIG_GENERIC_HARDIRQS=y +CONFIG_IRQ_PER_CPU=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_PPC=y CONFIG_EARLY_PRINTK=y CONFIG_GENERIC_NVRAM=y @@ -19,7 +21,7 @@ CONFIG_ARCH_MAY_HAVE_PC_FDC=y CONFIG_PPC_OF=y CONFIG_PPC_UDBG_16550=y # CONFIG_GENERIC_TBSYNC is not set -# CONFIG_DEFAULT_UIMAGE is not set +CONFIG_DEFAULT_UIMAGE=y # # Processor support @@ -29,6 +31,7 @@ CONFIG_PPC_UDBG_16550=y # CONFIG_PPC_82xx is not set # CONFIG_PPC_83xx is not set CONFIG_PPC_85xx=y +# CONFIG_PPC_86xx is not set # CONFIG_40x is not set # CONFIG_44x is not set # CONFIG_8xx is not set @@ -39,6 +42,7 @@ CONFIG_BOOKE=y CONFIG_FSL_BOOKE=y # CONFIG_PHYS_64BIT is not set CONFIG_SPE=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # # Code maturity level options @@ -56,6 +60,7 @@ CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set @@ -71,10 +76,12 @@ CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y +CONFIG_RT_MUTEXES=y CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 # CONFIG_SLOB is not set @@ -103,7 +110,6 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" -CONFIG_MPIC=y # CONFIG_WANT_EARLY_SERIAL is not set # @@ -113,6 +119,7 @@ CONFIG_MPIC=y CONFIG_MPC85xx_CDS=y CONFIG_MPC8540=y CONFIG_PPC_INDIRECT_PCI_BE=y +CONFIG_MPIC=y # # Kernel options @@ -128,6 +135,7 @@ CONFIG_PREEMPT_NONE=y CONFIG_BINFMT_ELF=y CONFIG_BINFMT_MISC=y CONFIG_MATH_EMULATION=y +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y @@ -137,21 +145,23 @@ CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set CONFIG_PROC_DEVICETREE=y # CONFIG_CMDLINE_BOOL is not set # CONFIG_PM is not set -# CONFIG_SOFTWARE_SUSPEND is not set # CONFIG_SECCOMP is not set CONFIG_ISA_DMA_API=y # # Bus options # -CONFIG_PPC_I8259=y +# CONFIG_MPIC_WEIRD is not set +# CONFIG_PPC_I8259 is not set CONFIG_PPC_INDIRECT_PCI=y CONFIG_FSL_SOC=y CONFIG_PCI=y CONFIG_PCI_DOMAINS=y +# CONFIG_PCIEPORTBUS is not set # CONFIG_PCI_DEBUG is not set # @@ -190,6 +200,8 @@ CONFIG_NET=y CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y +CONFIG_XFRM=y +CONFIG_XFRM_USER=y # CONFIG_NET_KEY is not set CONFIG_INET=y CONFIG_IP_MULTICAST=y @@ -209,6 +221,8 @@ CONFIG_SYN_COOKIES=y # CONFIG_INET_IPCOMP is not set # CONFIG_INET_XFRM_TUNNEL is not set # CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set @@ -216,6 +230,7 @@ CONFIG_TCP_CONG_BIC=y # CONFIG_IPV6 is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set # @@ -270,6 +285,7 @@ CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set # CONFIG_DEBUG_DRIVER is not set +# CONFIG_SYS_HYPERVISOR is not set # # Connector - unified userspace <-> kernelspace linker @@ -306,6 +322,7 @@ CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=32768 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set @@ -425,6 +442,9 @@ CONFIG_PHYLIB=y # CONFIG_QSEMI_PHY is not set # CONFIG_LXT_PHY is not set # CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_FIXED_PHY is not set # # Ethernet (10 or 100Mbit) @@ -470,6 +490,7 @@ CONFIG_GFAR_NAPI=y # CONFIG_CHELSIO_T1 is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set +# CONFIG_MYRI10GE is not set # # Token Ring devices @@ -568,6 +589,7 @@ CONFIG_LEGACY_PTY_COUNT=256 # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_HW_RANDOM is not set # CONFIG_NVRAM is not set CONFIG_GEN_RTC=y # CONFIG_GEN_RTC_X is not set @@ -602,13 +624,13 @@ CONFIG_GEN_RTC=y # # Dallas's 1-wire bus # -# CONFIG_W1 is not set # # Hardware Monitoring support # CONFIG_HWMON=y # CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ABITUGURU is not set # CONFIG_SENSORS_F71805F is not set # CONFIG_HWMON_DEBUG_CHIP is not set @@ -620,6 +642,7 @@ CONFIG_HWMON=y # Multimedia devices # # CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices @@ -629,7 +652,9 @@ CONFIG_HWMON=y # # Graphics support # +CONFIG_FIRMWARE_EDID=y # CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -664,6 +689,14 @@ CONFIG_USB_ARCH_HAS_EHCI=y # CONFIG_NEW_LEDS is not set # +# LED drivers +# + +# +# LED Triggers +# + +# # InfiniBand support # # CONFIG_INFINIBAND is not set @@ -678,6 +711,19 @@ CONFIG_USB_ARCH_HAS_EHCI=y # CONFIG_RTC_CLASS is not set # +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + +# # File systems # CONFIG_EXT2_FS=y @@ -698,6 +744,7 @@ CONFIG_FS_MBCACHE=y # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set @@ -795,6 +842,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_CRC16 is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set +CONFIG_PLIST=y # # Instrumentation Support @@ -806,14 +854,19 @@ CONFIG_CRC32=y # # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_KERNEL=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set -CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set +CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_RWSEMS is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_FS is not set @@ -824,11 +877,7 @@ CONFIG_FORCED_INLINING=y # CONFIG_DEBUGGER is not set # CONFIG_BDI_SWITCH is not set # CONFIG_BOOTX_TEXT is not set -# CONFIG_PPC_EARLY_DEBUG_LPAR is not set -# CONFIG_PPC_EARLY_DEBUG_G5 is not set -# CONFIG_PPC_EARLY_DEBUG_RTAS is not set -# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set -# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set +# CONFIG_PPC_EARLY_DEBUG is not set # # Security options diff --git a/arch/powerpc/configs/mpc8641_hpcn_defconfig b/arch/powerpc/configs/mpc8641_hpcn_defconfig index d7a30f9bc535..92a527fccf83 100644 --- a/arch/powerpc/configs/mpc8641_hpcn_defconfig +++ b/arch/powerpc/configs/mpc8641_hpcn_defconfig @@ -1,16 +1,18 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.17-rc3 -# Fri Jun 16 10:47:09 2006 +# Linux kernel version: 2.6.18-rc6 +# Sun Sep 10 10:30:15 2006 # # CONFIG_PPC64 is not set CONFIG_PPC32=y CONFIG_PPC_MERGE=y CONFIG_MMU=y CONFIG_GENERIC_HARDIRQS=y +CONFIG_IRQ_PER_CPU=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_PPC=y CONFIG_EARLY_PRINTK=y CONFIG_GENERIC_NVRAM=y @@ -41,6 +43,7 @@ CONFIG_PPC_STD_MMU=y CONFIG_PPC_STD_MMU_32=y CONFIG_SMP=y CONFIG_NR_CPUS=2 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # # Code maturity level options @@ -58,6 +61,7 @@ CONFIG_LOCALVERSION="" # CONFIG_SYSVIPC is not set # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set CONFIG_IKCONFIG=y @@ -75,10 +79,12 @@ CONFIG_PRINTK=y CONFIG_BUG=y # CONFIG_ELF_CORE is not set CONFIG_BASE_FULL=y +CONFIG_RT_MUTEXES=y CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y # CONFIG_SLAB is not set +CONFIG_VM_EVENT_COUNTERS=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 CONFIG_SLOB=y @@ -107,9 +113,9 @@ CONFIG_DEFAULT_DEADLINE=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="deadline" -CONFIG_MPIC=y # CONFIG_WANT_EARLY_SERIAL is not set CONFIG_PPC_INDIRECT_PCI_BE=y +CONFIG_MPIC=y # # Platform Support @@ -131,6 +137,7 @@ CONFIG_PREEMPT_NONE=y CONFIG_PREEMPT_BKL=y CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y # CONFIG_IRQ_ALL_CPUS is not set CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_SELECT_MEMORY_MODEL=y @@ -141,6 +148,7 @@ CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set CONFIG_PROC_DEVICETREE=y # CONFIG_CMDLINE_BOOL is not set # CONFIG_PM is not set @@ -151,11 +159,13 @@ CONFIG_ISA_DMA_API=y # Bus options # CONFIG_GENERIC_ISA_DMA=y +# CONFIG_MPIC_WEIRD is not set CONFIG_PPC_I8259=y CONFIG_PPC_INDIRECT_PCI=y CONFIG_FSL_SOC=y CONFIG_PCI=y CONFIG_PCI_DOMAINS=y +# CONFIG_PCIEPORTBUS is not set # CONFIG_PCI_DEBUG is not set # @@ -194,6 +204,8 @@ CONFIG_NET=y CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y +CONFIG_XFRM=y +CONFIG_XFRM_USER=y # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set @@ -212,6 +224,8 @@ CONFIG_IP_PNP_RARP=y # CONFIG_INET_IPCOMP is not set # CONFIG_INET_XFRM_TUNNEL is not set # CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set @@ -224,7 +238,10 @@ CONFIG_IPV6=y # CONFIG_INET6_IPCOMP is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set +CONFIG_INET6_XFRM_MODE_TRANSPORT=y +CONFIG_INET6_XFRM_MODE_TUNNEL=y # CONFIG_IPV6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set # @@ -279,6 +296,7 @@ CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_FW_LOADER=y # CONFIG_DEBUG_DRIVER is not set +# CONFIG_SYS_HYPERVISOR is not set # # Connector - unified userspace <-> kernelspace linker @@ -315,6 +333,7 @@ CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=131072 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set @@ -383,6 +402,8 @@ CONFIG_PHYLIB=y # CONFIG_LXT_PHY is not set # CONFIG_CICADA_PHY is not set CONFIG_VITESSE_PHY=y +# CONFIG_SMSC_PHY is not set +# CONFIG_FIXED_PHY is not set # # Ethernet (10 or 100Mbit) @@ -426,6 +447,7 @@ CONFIG_GIANFAR=y # CONFIG_CHELSIO_T1 is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set +# CONFIG_MYRI10GE is not set # # Token Ring devices @@ -500,6 +522,7 @@ CONFIG_SERIO_LIBPS2=y CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set # CONFIG_SERIAL_NONSTANDARD is not set # @@ -534,6 +557,7 @@ CONFIG_UNIX98_PTYS=y # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_HW_RANDOM is not set # CONFIG_NVRAM is not set # CONFIG_GEN_RTC is not set # CONFIG_DTLK is not set @@ -579,6 +603,7 @@ CONFIG_I2C=y # CONFIG_I2C_PIIX4 is not set CONFIG_I2C_MPC=y # CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_OCORES is not set # CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_PROSAVAGE is not set # CONFIG_I2C_SAVAGE4 is not set @@ -615,7 +640,6 @@ CONFIG_SENSORS_EEPROM=y # # Dallas's 1-wire bus # -# CONFIG_W1 is not set # # Hardware Monitoring support @@ -631,6 +655,7 @@ CONFIG_SENSORS_EEPROM=y # Multimedia devices # # CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices @@ -640,6 +665,7 @@ CONFIG_SENSORS_EEPROM=y # # Graphics support # +CONFIG_FIRMWARE_EDID=y # CONFIG_FB is not set # @@ -648,6 +674,7 @@ CONFIG_SENSORS_EEPROM=y CONFIG_VGA_CONSOLE=y # CONFIG_VGACON_SOFT_SCROLLBACK is not set CONFIG_DUMMY_CONSOLE=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -704,6 +731,19 @@ CONFIG_USB_ARCH_HAS_EHCI=y # CONFIG_RTC_CLASS is not set # +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + +# # File systems # CONFIG_EXT2_FS=y @@ -870,6 +910,7 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_CRC16 is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set +CONFIG_PLIST=y # # Instrumentation Support @@ -881,13 +922,18 @@ CONFIG_CRC32=y # # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_KERNEL=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set -# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_RWSEMS is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_HIGHMEM is not set # CONFIG_DEBUG_INFO is not set @@ -899,11 +945,7 @@ CONFIG_FORCED_INLINING=y # CONFIG_DEBUGGER is not set # CONFIG_BDI_SWITCH is not set # CONFIG_BOOTX_TEXT is not set -# CONFIG_PPC_EARLY_DEBUG_LPAR is not set -# CONFIG_PPC_EARLY_DEBUG_G5 is not set -# CONFIG_PPC_EARLY_DEBUG_RTAS is not set -# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set -# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set +# CONFIG_PPC_EARLY_DEBUG is not set # # Security options diff --git a/arch/powerpc/configs/pmac32_defconfig b/arch/powerpc/configs/pmac32_defconfig index addc79381c3b..6861dde7d77b 100644 --- a/arch/powerpc/configs/pmac32_defconfig +++ b/arch/powerpc/configs/pmac32_defconfig @@ -1,16 +1,18 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.17-rc5 -# Mon May 29 14:47:49 2006 +# Linux kernel version: 2.6.18-rc6 +# Sun Sep 10 10:30:23 2006 # # CONFIG_PPC64 is not set CONFIG_PPC32=y CONFIG_PPC_MERGE=y CONFIG_MMU=y CONFIG_GENERIC_HARDIRQS=y +CONFIG_IRQ_PER_CPU=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_PPC=y CONFIG_EARLY_PRINTK=y CONFIG_GENERIC_NVRAM=y @@ -29,6 +31,7 @@ CONFIG_CLASSIC32=y # CONFIG_PPC_82xx is not set # CONFIG_PPC_83xx is not set # CONFIG_PPC_85xx is not set +# CONFIG_PPC_86xx is not set # CONFIG_40x is not set # CONFIG_44x is not set # CONFIG_8xx is not set @@ -39,6 +42,7 @@ CONFIG_ALTIVEC=y CONFIG_PPC_STD_MMU=y CONFIG_PPC_STD_MMU_32=y # CONFIG_SMP is not set +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # # Code maturity level options @@ -56,6 +60,7 @@ CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set CONFIG_IKCONFIG=y @@ -72,10 +77,12 @@ CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y +CONFIG_RT_MUTEXES=y CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 # CONFIG_SLOB is not set @@ -119,7 +126,9 @@ CONFIG_PPC_MULTIPLATFORM=y # CONFIG_APUS is not set # CONFIG_PPC_CHRP is not set CONFIG_PPC_PMAC=y -CONFIG_MPIC=y +# CONFIG_PPC_CELL is not set +# CONFIG_PPC_CELL_NATIVE is not set +# CONFIG_UDBG_RTAS_CONSOLE is not set # CONFIG_PPC_RTAS is not set # CONFIG_MMIO_NVRAM is not set CONFIG_PPC_MPC106=y @@ -140,6 +149,7 @@ CONFIG_CPU_FREQ_PMAC=y CONFIG_PPC601_SYNC_FIX=y # CONFIG_TAU is not set # CONFIG_WANT_EARLY_SERIAL is not set +CONFIG_MPIC=y # # Kernel options @@ -154,6 +164,7 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT is not set CONFIG_BINFMT_ELF=y CONFIG_BINFMT_MISC=m +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y # CONFIG_KEXEC is not set CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_SELECT_MEMORY_MODEL=y @@ -164,6 +175,7 @@ CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set CONFIG_PROC_DEVICETREE=y # CONFIG_CMDLINE_BOOL is not set CONFIG_PM=y @@ -178,10 +190,12 @@ CONFIG_ISA_DMA_API=y # Bus options # CONFIG_GENERIC_ISA_DMA=y +# CONFIG_MPIC_WEIRD is not set # CONFIG_PPC_I8259 is not set CONFIG_PPC_INDIRECT_PCI=y CONFIG_PCI=y CONFIG_PCI_DOMAINS=y +# CONFIG_PCIEPORTBUS is not set # CONFIG_PCI_DEBUG is not set # @@ -256,6 +270,8 @@ CONFIG_INET_ESP=y # CONFIG_INET_IPCOMP is not set # CONFIG_INET_XFRM_TUNNEL is not set # CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set @@ -268,6 +284,7 @@ CONFIG_TCP_CONG_BIC=y # CONFIG_IPV6 is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set @@ -292,9 +309,11 @@ CONFIG_NETFILTER_XT_MATCH_MARK=m CONFIG_NETFILTER_XT_MATCH_POLICY=m CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set CONFIG_NETFILTER_XT_MATCH_REALM=m CONFIG_NETFILTER_XT_MATCH_SCTP=m CONFIG_NETFILTER_XT_MATCH_STATE=m +# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set CONFIG_NETFILTER_XT_MATCH_STRING=m CONFIG_NETFILTER_XT_MATCH_TCPMSS=m @@ -313,6 +332,7 @@ CONFIG_IP_NF_TFTP=m CONFIG_IP_NF_AMANDA=m CONFIG_IP_NF_PPTP=m CONFIG_IP_NF_H323=m +# CONFIG_IP_NF_SIP is not set # CONFIG_IP_NF_QUEUE is not set CONFIG_IP_NF_IPTABLES=m CONFIG_IP_NF_MATCH_IPRANGE=m @@ -457,6 +477,7 @@ CONFIG_IRTTY_SIR=m # CONFIG_ALI_FIR is not set # CONFIG_VLSI_FIR is not set # CONFIG_VIA_FIR is not set +# CONFIG_MCS_FIR is not set CONFIG_BT=m CONFIG_BT_L2CAP=m CONFIG_BT_SCO=m @@ -500,6 +521,7 @@ CONFIG_WIRELESS_EXT=y CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_FW_LOADER=y # CONFIG_DEBUG_DRIVER is not set +# CONFIG_SYS_HYPERVISOR is not set # # Connector - unified userspace <-> kernelspace linker @@ -539,6 +561,7 @@ CONFIG_BLK_DEV_UB=m CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set @@ -600,7 +623,6 @@ CONFIG_BLK_DEV_PDC202XX_NEW=y CONFIG_BLK_DEV_IDE_PMAC=y CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST=y CONFIG_BLK_DEV_IDEDMA_PMAC=y -CONFIG_BLK_DEV_IDE_PMAC_BLINK=y # CONFIG_IDE_ARM is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_IVB is not set @@ -661,6 +683,7 @@ CONFIG_SCSI_AIC7XXX_OLD=m # CONFIG_MEGARAID_LEGACY is not set # CONFIG_MEGARAID_SAS is not set # CONFIG_SCSI_SATA is not set +# CONFIG_SCSI_HPTIOP is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_EATA is not set @@ -705,9 +728,7 @@ CONFIG_MD_LINEAR=m CONFIG_MD_RAID0=m CONFIG_MD_RAID1=m CONFIG_MD_RAID10=m -CONFIG_MD_RAID5=m -CONFIG_MD_RAID5_RESHAPE=y -CONFIG_MD_RAID6=m +# CONFIG_MD_RAID456 is not set CONFIG_MD_MULTIPATH=m CONFIG_MD_FAULTY=m CONFIG_BLK_DEV_DM=m @@ -750,7 +771,6 @@ CONFIG_IEEE1394_OHCI1394=m # CONFIG_IEEE1394_VIDEO1394=m CONFIG_IEEE1394_SBP2=m -# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set # CONFIG_IEEE1394_ETH1394 is not set CONFIG_IEEE1394_DV1394=m CONFIG_IEEE1394_RAWIO=m @@ -766,9 +786,12 @@ CONFIG_IEEE1394_RAWIO=m CONFIG_ADB=y CONFIG_ADB_CUDA=y CONFIG_ADB_PMU=y +CONFIG_ADB_PMU_LED=y +CONFIG_ADB_PMU_LED_IDE=y CONFIG_PMAC_APM_EMU=m CONFIG_PMAC_MEDIABAY=y CONFIG_PMAC_BACKLIGHT=y +CONFIG_PMAC_BACKLIGHT_LEGACY=y CONFIG_INPUT_ADBHID=y CONFIG_MAC_EMUMOUSEBTN=y CONFIG_THERM_WINDTUNNEL=m @@ -858,6 +881,7 @@ CONFIG_PCNET32=y # CONFIG_CHELSIO_T1 is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set +# CONFIG_MYRI10GE is not set # # Token Ring devices @@ -908,6 +932,7 @@ CONFIG_APPLE_AIRPORT=m # Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support # CONFIG_PRISM54=m +# CONFIG_USB_ZD1201 is not set # CONFIG_HOSTAP is not set CONFIG_NET_WIRELESS=y @@ -998,6 +1023,7 @@ CONFIG_SERIO=y CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set # CONFIG_SERIAL_NONSTANDARD is not set # @@ -1029,6 +1055,7 @@ CONFIG_LEGACY_PTY_COUNT=256 # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_HW_RANDOM is not set CONFIG_NVRAM=y CONFIG_GEN_RTC=y # CONFIG_GEN_RTC_X is not set @@ -1040,6 +1067,7 @@ CONFIG_GEN_RTC=y # Ftape, the floppy tape device driver # CONFIG_AGP=m +# CONFIG_AGP_SIS is not set # CONFIG_AGP_VIA is not set CONFIG_AGP_UNINORTH=m CONFIG_DRM=m @@ -1092,6 +1120,7 @@ CONFIG_I2C_ALGOBIT=y CONFIG_I2C_POWERMAC=y # CONFIG_I2C_MPC is not set # CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_OCORES is not set # CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_PROSAVAGE is not set # CONFIG_I2C_SAVAGE4 is not set @@ -1156,12 +1185,13 @@ CONFIG_VIDEO_V4L2=y # # Graphics support # +# CONFIG_FIRMWARE_EDID is not set CONFIG_FB=y CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y CONFIG_FB_MACMODES=y -CONFIG_FB_FIRMWARE_EDID=y +CONFIG_FB_BACKLIGHT=y CONFIG_FB_MODE_HELPERS=y CONFIG_FB_TILEBLITTING=y # CONFIG_FB_CIRRUS is not set @@ -1178,6 +1208,7 @@ CONFIG_FB_IMSTT=y # CONFIG_FB_S1D13XXX is not set CONFIG_FB_NVIDIA=y CONFIG_FB_NVIDIA_I2C=y +CONFIG_FB_NVIDIA_BACKLIGHT=y # CONFIG_FB_RIVA is not set CONFIG_FB_MATROX=y CONFIG_FB_MATROX_MILLENIUM=y @@ -1187,12 +1218,15 @@ CONFIG_FB_MATROX_MYSTIQUE=y # CONFIG_FB_MATROX_MULTIHEAD is not set CONFIG_FB_RADEON=y CONFIG_FB_RADEON_I2C=y +CONFIG_FB_RADEON_BACKLIGHT=y # CONFIG_FB_RADEON_DEBUG is not set CONFIG_FB_ATY128=y +CONFIG_FB_ATY128_BACKLIGHT=y CONFIG_FB_ATY=y CONFIG_FB_ATY_CT=y # CONFIG_FB_ATY_GENERIC_LCD is not set CONFIG_FB_ATY_GX=y +CONFIG_FB_ATY_BACKLIGHT=y # CONFIG_FB_SAVAGE is not set # CONFIG_FB_SIS is not set # CONFIG_FB_NEOMAGIC is not set @@ -1221,7 +1255,11 @@ CONFIG_LOGO=y CONFIG_LOGO_LINUX_MONO=y CONFIG_LOGO_LINUX_VGA16=y CONFIG_LOGO_LINUX_CLUT224=y -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_DEVICE=y +CONFIG_LCD_CLASS_DEVICE=m +CONFIG_LCD_DEVICE=y # # Sound @@ -1278,6 +1316,18 @@ CONFIG_SND_DUMMY=m # CONFIG_SND_CMIPCI is not set # CONFIG_SND_CS4281 is not set # CONFIG_SND_CS46XX is not set +# CONFIG_SND_DARLA20 is not set +# CONFIG_SND_GINA20 is not set +# CONFIG_SND_LAYLA20 is not set +# CONFIG_SND_DARLA24 is not set +# CONFIG_SND_GINA24 is not set +# CONFIG_SND_LAYLA24 is not set +# CONFIG_SND_MONA is not set +# CONFIG_SND_MIA is not set +# CONFIG_SND_ECHO3G is not set +# CONFIG_SND_INDIGO is not set +# CONFIG_SND_INDIGOIO is not set +# CONFIG_SND_INDIGODJ is not set # CONFIG_SND_EMU10K1 is not set # CONFIG_SND_EMU10K1X is not set # CONFIG_SND_ENS1370 is not set @@ -1315,6 +1365,17 @@ CONFIG_SND_POWERMAC=m CONFIG_SND_POWERMAC_AUTO_DRC=y # +# Apple Onboard Audio driver +# +CONFIG_SND_AOA=m +CONFIG_SND_AOA_FABRIC_LAYOUT=m +CONFIG_SND_AOA_ONYX=m +CONFIG_SND_AOA_TAS=m +CONFIG_SND_AOA_TOONIE=m +CONFIG_SND_AOA_SOUNDBUS=m +CONFIG_SND_AOA_SOUNDBUS_I2S=m + +# # USB devices # CONFIG_SND_USB_AUDIO=m @@ -1355,6 +1416,7 @@ CONFIG_USB_DYNAMIC_MINORS=y CONFIG_USB_EHCI_HCD=m CONFIG_USB_EHCI_SPLIT_ISO=y CONFIG_USB_EHCI_ROOT_HUB_TT=y +# CONFIG_USB_EHCI_TT_NEWSCHED is not set # CONFIG_USB_ISP116X_HCD is not set CONFIG_USB_OHCI_HCD=y # CONFIG_USB_OHCI_BIG_ENDIAN is not set @@ -1431,7 +1493,6 @@ CONFIG_USB_NET_NET1080=m # CONFIG_USB_NET_RNDIS_HOST is not set # CONFIG_USB_NET_CDC_SUBSET is not set CONFIG_USB_NET_ZAURUS=m -# CONFIG_USB_ZD1201 is not set CONFIG_USB_MON=y # @@ -1444,7 +1505,6 @@ CONFIG_USB_MON=y CONFIG_USB_SERIAL=m # CONFIG_USB_SERIAL_GENERIC is not set # CONFIG_USB_SERIAL_AIRPRIME is not set -# CONFIG_USB_SERIAL_ANYDATA is not set # CONFIG_USB_SERIAL_ARK3116 is not set # CONFIG_USB_SERIAL_BELKIN is not set # CONFIG_USB_SERIAL_WHITEHEAT is not set @@ -1482,6 +1542,7 @@ CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y # CONFIG_USB_SERIAL_PL2303 is not set # CONFIG_USB_SERIAL_HP4X is not set # CONFIG_USB_SERIAL_SAFE is not set +# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set # CONFIG_USB_SERIAL_TI is not set # CONFIG_USB_SERIAL_CYBERJACK is not set # CONFIG_USB_SERIAL_XIRCOM is not set @@ -1499,10 +1560,12 @@ CONFIG_USB_EZUSB=y # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set # CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set # CONFIG_USB_PHIDGETKIT is not set # CONFIG_USB_PHIDGETSERVO is not set # CONFIG_USB_IDMOUSE is not set +CONFIG_USB_APPLEDISPLAY=m # CONFIG_USB_SISUSBVGA is not set # CONFIG_USB_LD is not set # CONFIG_USB_TEST is not set @@ -1524,7 +1587,8 @@ CONFIG_USB_EZUSB=y # # LED devices # -# CONFIG_NEW_LEDS is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y # # LED drivers @@ -1533,6 +1597,10 @@ CONFIG_USB_EZUSB=y # # LED Triggers # +CONFIG_LEDS_TRIGGERS=y +# CONFIG_LEDS_TRIGGER_TIMER is not set +CONFIG_LEDS_TRIGGER_IDE_DISK=y +# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set # # InfiniBand support @@ -1549,6 +1617,19 @@ CONFIG_USB_EZUSB=y # CONFIG_RTC_CLASS is not set # +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + +# # File systems # CONFIG_EXT2_FS=y @@ -1569,6 +1650,7 @@ CONFIG_FS_POSIX_ACL=y # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set @@ -1732,6 +1814,7 @@ CONFIG_TEXTSEARCH=y CONFIG_TEXTSEARCH_KMP=m CONFIG_TEXTSEARCH_BM=m CONFIG_TEXTSEARCH_FSM=m +CONFIG_PLIST=y # # Instrumentation Support @@ -1744,14 +1827,19 @@ CONFIG_OPROFILE=y # # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_KERNEL=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_RWSEMS is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_FS is not set @@ -1763,11 +1851,7 @@ CONFIG_XMON=y CONFIG_XMON_DEFAULT=y # CONFIG_BDI_SWITCH is not set CONFIG_BOOTX_TEXT=y -# CONFIG_PPC_EARLY_DEBUG_LPAR is not set -# CONFIG_PPC_EARLY_DEBUG_G5 is not set -# CONFIG_PPC_EARLY_DEBUG_RTAS is not set -# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set -# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set +# CONFIG_PPC_EARLY_DEBUG is not set # # Security options diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig index 395e49847788..7517d0c5303f 100644 --- a/arch/powerpc/configs/ppc64_defconfig +++ b/arch/powerpc/configs/ppc64_defconfig @@ -1,15 +1,18 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.16-rc2 -# Fri Feb 10 17:32:14 2006 +# Linux kernel version: 2.6.18-rc6 +# Sun Sep 10 10:45:11 2006 # CONFIG_PPC64=y CONFIG_64BIT=y CONFIG_PPC_MERGE=y CONFIG_MMU=y CONFIG_GENERIC_HARDIRQS=y +CONFIG_IRQ_PER_CPU=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_PPC=y CONFIG_EARLY_PRINTK=y CONFIG_COMPAT=y @@ -30,8 +33,10 @@ CONFIG_POWER4=y CONFIG_PPC_FPU=y CONFIG_ALTIVEC=y CONFIG_PPC_STD_MMU=y +CONFIG_VIRT_CPU_ACCOUNTING=y CONFIG_SMP=y CONFIG_NR_CPUS=32 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # # Code maturity level options @@ -49,11 +54,14 @@ CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_TASKSTATS=y +CONFIG_TASK_DELAY_ACCT=y CONFIG_SYSCTL=y # CONFIG_AUDIT is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_CPUSETS=y +CONFIG_RELAY=y CONFIG_INITRAMFS_SOURCE="" CONFIG_CC_OPTIMIZE_FOR_SIZE=y # CONFIG_EMBEDDED is not set @@ -65,14 +73,12 @@ CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y +CONFIG_RT_MUTEXES=y CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y -CONFIG_CC_ALIGN_FUNCTIONS=0 -CONFIG_CC_ALIGN_LABELS=0 -CONFIG_CC_ALIGN_LOOPS=0 -CONFIG_CC_ALIGN_JUMPS=0 CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 # CONFIG_SLOB is not set @@ -83,7 +89,6 @@ CONFIG_BASE_SMALL=0 CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set -CONFIG_OBSOLETE_MODPARM=y CONFIG_MODVERSIONS=y CONFIG_MODULE_SRCVERSION_ALL=y CONFIG_KMOD=y @@ -92,6 +97,7 @@ CONFIG_STOP_MACHINE=y # # Block layer # +CONFIG_BLK_DEV_IO_TRACE=y # # IO Schedulers @@ -117,19 +123,22 @@ CONFIG_PPC_PSERIES=y CONFIG_PPC_PMAC=y CONFIG_PPC_PMAC64=y CONFIG_PPC_MAPLE=y -# CONFIG_PPC_CELL is not set +CONFIG_PPC_CELL=y +CONFIG_PPC_CELL_NATIVE=y +CONFIG_PPC_IBM_CELL_BLADE=y +CONFIG_UDBG_RTAS_CONSOLE=y CONFIG_XICS=y CONFIG_U3_DART=y -CONFIG_MPIC=y CONFIG_PPC_RTAS=y CONFIG_RTAS_ERROR_LOGGING=y CONFIG_RTAS_PROC=y CONFIG_RTAS_FLASH=m -# CONFIG_MMIO_NVRAM is not set +CONFIG_MMIO_NVRAM=y CONFIG_MPIC_BROKEN_U3=y CONFIG_IBMVIO=y # CONFIG_IBMEBUS is not set # CONFIG_PPC_MPC106 is not set +CONFIG_PPC_970_NAP=y CONFIG_CPU_FREQ=y CONFIG_CPU_FREQ_TABLE=y # CONFIG_CPU_FREQ_DEBUG is not set @@ -144,6 +153,15 @@ CONFIG_CPU_FREQ_GOV_USERSPACE=y # CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set CONFIG_CPU_FREQ_PMAC64=y # CONFIG_WANT_EARLY_SERIAL is not set +CONFIG_MPIC=y + +# +# Cell Broadband Engine options +# +CONFIG_SPU_FS=m +CONFIG_SPU_BASE=y +CONFIG_SPUFS_MMAP=y +CONFIG_CBE_RAS=y # # Kernel options @@ -161,6 +179,7 @@ CONFIG_BINFMT_MISC=m CONFIG_FORCE_MAX_ZONEORDER=13 CONFIG_IOMMU_VMERGE=y CONFIG_HOTPLUG_CPU=y +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_KEXEC=y # CONFIG_CRASH_DUMP is not set CONFIG_IRQ_ALL_CPUS=y @@ -181,9 +200,10 @@ CONFIG_SPARSEMEM=y CONFIG_HAVE_MEMORY_PRESENT=y # CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPARSEMEM_EXTREME=y -# CONFIG_MEMORY_HOTPLUG is not set +CONFIG_MEMORY_HOTPLUG=y CONFIG_SPLIT_PTLOCK_CPUS=4 -CONFIG_MIGRATION=y +CONFIG_RESOURCES_64BIT=y +CONFIG_ARCH_MEMORY_PROBE=y # CONFIG_PPC_64K_PAGES is not set # CONFIG_SCHED_SMT is not set CONFIG_PROC_DEVICETREE=y @@ -196,11 +216,12 @@ CONFIG_ISA_DMA_API=y # Bus options # CONFIG_GENERIC_ISA_DMA=y +# CONFIG_MPIC_WEIRD is not set CONFIG_PPC_I8259=y # CONFIG_PPC_INDIRECT_PCI is not set CONFIG_PCI=y CONFIG_PCI_DOMAINS=y -# CONFIG_PCI_LEGACY_PROC is not set +# CONFIG_PCIEPORTBUS is not set # CONFIG_PCI_DEBUG is not set # @@ -247,7 +268,10 @@ CONFIG_SYN_COOKIES=y CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_IPCOMP=m +CONFIG_INET_XFRM_TUNNEL=m CONFIG_INET_TUNNEL=y +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set @@ -258,6 +282,9 @@ CONFIG_TCP_CONG_BIC=y # # CONFIG_IP_VS is not set # CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set @@ -284,6 +311,8 @@ CONFIG_IP_NF_IRC=m CONFIG_IP_NF_TFTP=m CONFIG_IP_NF_AMANDA=m # CONFIG_IP_NF_PPTP is not set +# CONFIG_IP_NF_H323 is not set +CONFIG_IP_NF_SIP=m CONFIG_IP_NF_QUEUE=m # @@ -339,6 +368,7 @@ CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_FW_LOADER=y # CONFIG_DEBUG_DRIVER is not set +# CONFIG_SYS_HYPERVISOR is not set # # Connector - unified userspace <-> kernelspace linker @@ -376,6 +406,7 @@ CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=65536 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set @@ -436,7 +467,6 @@ CONFIG_BLK_DEV_AMD74XX=y CONFIG_BLK_DEV_IDE_PMAC=y CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST=y CONFIG_BLK_DEV_IDEDMA_PMAC=y -# CONFIG_BLK_DEV_IDE_PMAC_BLINK is not set # CONFIG_IDE_ARM is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_IVB is not set @@ -497,6 +527,7 @@ CONFIG_SCSI_SATA_SVW=y # CONFIG_SCSI_SATA_MV is not set # CONFIG_SCSI_SATA_NV is not set # CONFIG_SCSI_PDC_ADMA is not set +# CONFIG_SCSI_HPTIOP is not set # CONFIG_SCSI_SATA_QSTOR is not set # CONFIG_SCSI_SATA_PROMISE is not set # CONFIG_SCSI_SATA_SX4 is not set @@ -519,11 +550,10 @@ CONFIG_SCSI_SYM53C8XX_2=y CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0 CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 -# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set +CONFIG_SCSI_SYM53C8XX_MMIO=y CONFIG_SCSI_IPR=y CONFIG_SCSI_IPR_TRACE=y CONFIG_SCSI_IPR_DUMP=y -# CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set # CONFIG_SCSI_QLA_FC is not set CONFIG_SCSI_LPFC=m @@ -540,8 +570,8 @@ CONFIG_MD_LINEAR=y CONFIG_MD_RAID0=y CONFIG_MD_RAID1=y CONFIG_MD_RAID10=y -CONFIG_MD_RAID5=y -CONFIG_MD_RAID6=m +CONFIG_MD_RAID456=y +CONFIG_MD_RAID5_RESHAPE=y CONFIG_MD_MULTIPATH=m CONFIG_MD_FAULTY=m CONFIG_BLK_DEV_DM=y @@ -585,7 +615,6 @@ CONFIG_IEEE1394_OHCI1394=y # CONFIG_IEEE1394_VIDEO1394=m CONFIG_IEEE1394_SBP2=m -# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set CONFIG_IEEE1394_ETH1394=m CONFIG_IEEE1394_DV1394=m CONFIG_IEEE1394_RAWIO=y @@ -599,6 +628,7 @@ CONFIG_IEEE1394_RAWIO=y # Macintosh device drivers # CONFIG_ADB_PMU=y +# CONFIG_ADB_PMU_LED is not set CONFIG_PMAC_SMU=y CONFIG_THERM_PM72=y CONFIG_WINDFARM=y @@ -682,6 +712,7 @@ CONFIG_E1000=y # CONFIG_VIA_VELOCITY is not set CONFIG_TIGON3=y # CONFIG_BNX2 is not set +CONFIG_SPIDER_NET=m # CONFIG_MV643XX_ETH is not set # @@ -691,6 +722,7 @@ CONFIG_TIGON3=y CONFIG_IXGB=m # CONFIG_IXGB_NAPI is not set # CONFIG_S2IO is not set +# CONFIG_MYRI10GE is not set # # Token Ring devices @@ -792,6 +824,7 @@ CONFIG_SERIO_LIBPS2=y CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set # CONFIG_SERIAL_NONSTANDARD is not set # @@ -799,6 +832,7 @@ CONFIG_HW_CONSOLE=y # CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_PCI=y CONFIG_SERIAL_8250_NR_UARTS=4 CONFIG_SERIAL_8250_RUNTIME_UARTS=4 # CONFIG_SERIAL_8250_EXTENDED is not set @@ -814,7 +848,9 @@ CONFIG_SERIAL_ICOM=m CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 +CONFIG_HVC_DRIVER=y CONFIG_HVC_CONSOLE=y +CONFIG_HVC_RTAS=y CONFIG_HVCS=m # @@ -826,7 +862,7 @@ CONFIG_HVCS=m # Watchdog Cards # # CONFIG_WATCHDOG is not set -# CONFIG_RTC is not set +# CONFIG_HW_RANDOM is not set CONFIG_GEN_RTC=y # CONFIG_GEN_RTC_X is not set # CONFIG_DTLK is not set @@ -874,10 +910,10 @@ CONFIG_I2C_AMD8111=y # CONFIG_I2C_PIIX4 is not set CONFIG_I2C_POWERMAC=y # CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_OCORES is not set # CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_PROSAVAGE is not set # CONFIG_I2C_SAVAGE4 is not set -# CONFIG_SCx200_ACB is not set # CONFIG_I2C_SIS5595 is not set # CONFIG_I2C_SIS630 is not set # CONFIG_I2C_SIS96X is not set @@ -896,9 +932,7 @@ CONFIG_I2C_POWERMAC=y # CONFIG_SENSORS_PCF8574 is not set # CONFIG_SENSORS_PCA9539 is not set # CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_RTC8564 is not set # CONFIG_SENSORS_MAX6875 is not set -# CONFIG_RTC_X1205_I2C is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set @@ -913,7 +947,6 @@ CONFIG_I2C_POWERMAC=y # # Dallas's 1-wire bus # -# CONFIG_W1 is not set # # Hardware Monitoring support @@ -926,37 +959,33 @@ CONFIG_I2C_POWERMAC=y # # -# Multimedia Capabilities Port drivers -# - -# # Multimedia devices # # CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices # # CONFIG_DVB is not set +# CONFIG_USB_DABUSB is not set # # Graphics support # +CONFIG_FIRMWARE_EDID=y CONFIG_FB=y CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y CONFIG_FB_MACMODES=y +# CONFIG_FB_BACKLIGHT is not set CONFIG_FB_MODE_HELPERS=y CONFIG_FB_TILEBLITTING=y # CONFIG_FB_CIRRUS is not set # CONFIG_FB_PM2 is not set # CONFIG_FB_CYBER2000 is not set CONFIG_FB_OF=y -# CONFIG_FB_CONTROL is not set -# CONFIG_FB_PLATINUM is not set -# CONFIG_FB_VALKYRIE is not set -# CONFIG_FB_CT65550 is not set # CONFIG_FB_ASILIANT is not set # CONFIG_FB_IMSTT is not set # CONFIG_FB_VGA16 is not set @@ -970,7 +999,6 @@ CONFIG_FB_MATROX_G=y CONFIG_FB_MATROX_I2C=m CONFIG_FB_MATROX_MAVEN=m CONFIG_FB_MATROX_MULTIHEAD=y -# CONFIG_FB_RADEON_OLD is not set CONFIG_FB_RADEON=y CONFIG_FB_RADEON_I2C=y # CONFIG_FB_RADEON_DEBUG is not set @@ -1025,9 +1053,11 @@ CONFIG_SND_SEQ_DUMMY=m CONFIG_SND_OSSEMUL=y CONFIG_SND_MIXER_OSS=m CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y CONFIG_SND_SEQUENCER_OSS=y # CONFIG_SND_DYNAMIC_MINORS is not set CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y # CONFIG_SND_VERBOSE_PRINTK is not set # CONFIG_SND_DEBUG is not set @@ -1044,6 +1074,7 @@ CONFIG_SND_SUPPORT_OLD_API=y # PCI devices # # CONFIG_SND_AD1889 is not set +# CONFIG_SND_ALS300 is not set # CONFIG_SND_ALS4000 is not set # CONFIG_SND_ALI5451 is not set # CONFIG_SND_ATIIXP is not set @@ -1057,6 +1088,18 @@ CONFIG_SND_SUPPORT_OLD_API=y # CONFIG_SND_CMIPCI is not set # CONFIG_SND_CS4281 is not set # CONFIG_SND_CS46XX is not set +# CONFIG_SND_DARLA20 is not set +# CONFIG_SND_GINA20 is not set +# CONFIG_SND_LAYLA20 is not set +# CONFIG_SND_DARLA24 is not set +# CONFIG_SND_GINA24 is not set +# CONFIG_SND_LAYLA24 is not set +# CONFIG_SND_MONA is not set +# CONFIG_SND_MIA is not set +# CONFIG_SND_ECHO3G is not set +# CONFIG_SND_INDIGO is not set +# CONFIG_SND_INDIGOIO is not set +# CONFIG_SND_INDIGODJ is not set # CONFIG_SND_EMU10K1 is not set # CONFIG_SND_EMU10K1X is not set # CONFIG_SND_ENS1370 is not set @@ -1076,6 +1119,7 @@ CONFIG_SND_SUPPORT_OLD_API=y # CONFIG_SND_MIXART is not set # CONFIG_SND_NM256 is not set # CONFIG_SND_PCXHR is not set +# CONFIG_SND_RIPTIDE is not set # CONFIG_SND_RME32 is not set # CONFIG_SND_RME96 is not set # CONFIG_SND_RME9652 is not set @@ -1093,6 +1137,17 @@ CONFIG_SND_POWERMAC=m CONFIG_SND_POWERMAC_AUTO_DRC=y # +# Apple Onboard Audio driver +# +CONFIG_SND_AOA=m +CONFIG_SND_AOA_FABRIC_LAYOUT=m +CONFIG_SND_AOA_ONYX=m +CONFIG_SND_AOA_TAS=m +CONFIG_SND_AOA_TOONIE=m +CONFIG_SND_AOA_SOUNDBUS=m +CONFIG_SND_AOA_SOUNDBUS_I2S=m + +# # USB devices # # CONFIG_SND_USB_AUDIO is not set @@ -1108,6 +1163,7 @@ CONFIG_SND_POWERMAC_AUTO_DRC=y # CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y CONFIG_USB=y # CONFIG_USB_DEBUG is not set @@ -1125,6 +1181,7 @@ CONFIG_USB_DEVICEFS=y CONFIG_USB_EHCI_HCD=y # CONFIG_USB_EHCI_SPLIT_ISO is not set # CONFIG_USB_EHCI_ROOT_HUB_TT is not set +CONFIG_USB_EHCI_TT_NEWSCHED=y # CONFIG_USB_ISP116X_HCD is not set CONFIG_USB_OHCI_HCD=y # CONFIG_USB_OHCI_BIG_ENDIAN is not set @@ -1135,7 +1192,6 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y # # USB Device Class drivers # -# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set # CONFIG_USB_ACM is not set # CONFIG_USB_PRINTER is not set @@ -1173,9 +1229,7 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_ACECAD is not set # CONFIG_USB_KBTAB is not set # CONFIG_USB_POWERMATE is not set -# CONFIG_USB_MTOUCH is not set -# CONFIG_USB_ITMTOUCH is not set -# CONFIG_USB_EGALAX is not set +# CONFIG_USB_TOUCHSCREEN is not set # CONFIG_USB_YEALINK is not set # CONFIG_USB_XPAD is not set # CONFIG_USB_ATI_REMOTE is not set @@ -1190,15 +1244,6 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_MICROTEK is not set # -# USB Multimedia devices -# -# CONFIG_USB_DABUSB is not set - -# -# Video4Linux support is needed for USB Multimedia device support -# - -# # USB Network Adapters # # CONFIG_USB_CATC is not set @@ -1227,10 +1272,12 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set # CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set # CONFIG_USB_PHIDGETKIT is not set # CONFIG_USB_PHIDGETSERVO is not set # CONFIG_USB_IDMOUSE is not set +CONFIG_USB_APPLEDISPLAY=m # CONFIG_USB_SISUSBVGA is not set # CONFIG_USB_LD is not set # CONFIG_USB_TEST is not set @@ -1250,23 +1297,53 @@ CONFIG_USB_HIDDEV=y # CONFIG_MMC is not set # +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + +# # InfiniBand support # CONFIG_INFINIBAND=m # CONFIG_INFINIBAND_USER_MAD is not set # CONFIG_INFINIBAND_USER_ACCESS is not set +CONFIG_INFINIBAND_ADDR_TRANS=y CONFIG_INFINIBAND_MTHCA=m -# CONFIG_INFINIBAND_MTHCA_DEBUG is not set +CONFIG_INFINIBAND_MTHCA_DEBUG=y CONFIG_INFINIBAND_IPOIB=m -# CONFIG_INFINIBAND_IPOIB_DEBUG is not set +CONFIG_INFINIBAND_IPOIB_DEBUG=y +# CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set # CONFIG_INFINIBAND_SRP is not set +CONFIG_INFINIBAND_ISER=m # -# SN Devices +# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) # # -# EDAC - error detection and reporting (RAS) +# Real Time Clock +# +# CONFIG_RTC_CLASS is not set + +# +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices # # @@ -1298,7 +1375,6 @@ CONFIG_JFS_SECURITY=y # CONFIG_JFS_STATISTICS is not set CONFIG_FS_POSIX_ACL=y CONFIG_XFS_FS=m -CONFIG_XFS_EXPORT=y # CONFIG_XFS_QUOTA is not set CONFIG_XFS_SECURITY=y CONFIG_XFS_POSIX_ACL=y @@ -1307,6 +1383,7 @@ CONFIG_XFS_POSIX_ACL=y # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set CONFIG_DNOTIFY=y CONFIG_AUTOFS_FS=y @@ -1342,7 +1419,6 @@ CONFIG_TMPFS=y CONFIG_HUGETLBFS=y CONFIG_HUGETLB_PAGE=y CONFIG_RAMFS=y -# CONFIG_RELAYFS_FS is not set # CONFIG_CONFIGFS_FS is not set # @@ -1388,8 +1464,10 @@ CONFIG_RPCSEC_GSS_SPKM3=m # CONFIG_SMB_FS is not set CONFIG_CIFS=m # CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set CONFIG_CIFS_XATTR=y CONFIG_CIFS_POSIX=y +# CONFIG_CIFS_DEBUG2 is not set # CONFIG_CIFS_EXPERIMENTAL is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -1470,6 +1548,9 @@ CONFIG_CRC32=y CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=m +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_PLIST=y # # Instrumentation Support @@ -1483,14 +1564,19 @@ CONFIG_OPROFILE=y # # CONFIG_PRINTK_TIME is not set CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_KERNEL=y CONFIG_LOG_BUF_SHIFT=17 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set -CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set +CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_RWSEMS is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set CONFIG_DEBUG_FS=y @@ -1504,11 +1590,7 @@ CONFIG_XMON=y # CONFIG_XMON_DEFAULT is not set CONFIG_IRQSTACKS=y CONFIG_BOOTX_TEXT=y -# CONFIG_PPC_EARLY_DEBUG_LPAR is not set -# CONFIG_PPC_EARLY_DEBUG_G5 is not set -# CONFIG_PPC_EARLY_DEBUG_RTAS is not set -# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set -# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set +# CONFIG_PPC_EARLY_DEBUG is not set # # Security options diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig index 31708ad4574e..a8cdf312e1b0 100644 --- a/arch/powerpc/configs/pseries_defconfig +++ b/arch/powerpc/configs/pseries_defconfig @@ -1,13 +1,14 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.17-rc4 -# Sun May 28 07:26:56 2006 +# Linux kernel version: 2.6.18-rc6 +# Sun Sep 10 10:45:12 2006 # CONFIG_PPC64=y CONFIG_64BIT=y CONFIG_PPC_MERGE=y CONFIG_MMU=y CONFIG_GENERIC_HARDIRQS=y +CONFIG_IRQ_PER_CPU=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y @@ -35,6 +36,7 @@ CONFIG_PPC_STD_MMU=y CONFIG_VIRT_CPU_ACCOUNTING=y CONFIG_SMP=y CONFIG_NR_CPUS=128 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # # Code maturity level options @@ -52,6 +54,7 @@ CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set CONFIG_SYSCTL=y CONFIG_AUDIT=y CONFIG_AUDITSYSCALL=y @@ -70,10 +73,12 @@ CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y +CONFIG_RT_MUTEXES=y CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 # CONFIG_SLOB is not set @@ -118,9 +123,11 @@ CONFIG_PPC_PSERIES=y # CONFIG_PPC_PMAC is not set # CONFIG_PPC_MAPLE is not set # CONFIG_PPC_CELL is not set +# CONFIG_PPC_CELL_NATIVE is not set +# CONFIG_PPC_IBM_CELL_BLADE is not set +# CONFIG_UDBG_RTAS_CONSOLE is not set CONFIG_XICS=y # CONFIG_U3_DART is not set -CONFIG_MPIC=y CONFIG_PPC_RTAS=y CONFIG_RTAS_ERROR_LOGGING=y CONFIG_RTAS_PROC=y @@ -132,6 +139,7 @@ CONFIG_IBMEBUS=y # CONFIG_PPC_970_NAP is not set # CONFIG_CPU_FREQ is not set # CONFIG_WANT_EARLY_SERIAL is not set +CONFIG_MPIC=y # # Kernel options @@ -149,6 +157,7 @@ CONFIG_BINFMT_MISC=m CONFIG_FORCE_MAX_ZONEORDER=13 CONFIG_IOMMU_VMERGE=y CONFIG_HOTPLUG_CPU=y +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_KEXEC=y # CONFIG_CRASH_DUMP is not set CONFIG_IRQ_ALL_CPUS=y @@ -173,6 +182,7 @@ CONFIG_SPARSEMEM_EXTREME=y # CONFIG_MEMORY_HOTPLUG is not set CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_MIGRATION=y +CONFIG_RESOURCES_64BIT=y CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y # CONFIG_PPC_64K_PAGES is not set CONFIG_SCHED_SMT=y @@ -186,10 +196,12 @@ CONFIG_ISA_DMA_API=y # Bus options # CONFIG_GENERIC_ISA_DMA=y +# CONFIG_MPIC_WEIRD is not set CONFIG_PPC_I8259=y # CONFIG_PPC_INDIRECT_PCI is not set CONFIG_PCI=y CONFIG_PCI_DOMAINS=y +# CONFIG_PCIEPORTBUS is not set # CONFIG_PCI_DEBUG is not set # @@ -238,6 +250,8 @@ CONFIG_INET_ESP=m CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_TUNNEL=m CONFIG_INET_TUNNEL=y +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set @@ -250,6 +264,7 @@ CONFIG_TCP_CONG_BIC=y # CONFIG_IPV6 is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set @@ -277,6 +292,7 @@ CONFIG_IP_NF_TFTP=m CONFIG_IP_NF_AMANDA=m # CONFIG_IP_NF_PPTP is not set # CONFIG_IP_NF_H323 is not set +# CONFIG_IP_NF_SIP is not set CONFIG_IP_NF_QUEUE=m # @@ -316,6 +332,7 @@ CONFIG_LLC=y # Network testing # # CONFIG_NET_PKTGEN is not set +# CONFIG_NET_TCPPROBE is not set # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set @@ -332,6 +349,7 @@ CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_FW_LOADER=y # CONFIG_DEBUG_DRIVER is not set +# CONFIG_SYS_HYPERVISOR is not set # # Connector - unified userspace <-> kernelspace linker @@ -352,6 +370,7 @@ CONFIG_PARPORT_PC=m # CONFIG_PARPORT_PC_FIFO is not set # CONFIG_PARPORT_PC_SUPERIO is not set # CONFIG_PARPORT_GSC is not set +# CONFIG_PARPORT_AX88796 is not set # CONFIG_PARPORT_1284 is not set # @@ -376,6 +395,7 @@ CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=65536 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set @@ -487,6 +507,7 @@ CONFIG_SCSI_SAS_ATTRS=m # CONFIG_MEGARAID_LEGACY is not set # CONFIG_MEGARAID_SAS is not set # CONFIG_SCSI_SATA is not set +# CONFIG_SCSI_HPTIOP is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_EATA is not set @@ -508,12 +529,6 @@ CONFIG_SCSI_IPR_TRACE=y CONFIG_SCSI_IPR_DUMP=y # CONFIG_SCSI_QLOGIC_1280 is not set CONFIG_SCSI_QLA_FC=m -CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE=y -CONFIG_SCSI_QLA21XX=m -CONFIG_SCSI_QLA22XX=m -CONFIG_SCSI_QLA2300=m -CONFIG_SCSI_QLA2322=m -CONFIG_SCSI_QLA24XX=m CONFIG_SCSI_LPFC=m # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set @@ -528,9 +543,7 @@ CONFIG_MD_LINEAR=y CONFIG_MD_RAID0=y CONFIG_MD_RAID1=y CONFIG_MD_RAID10=m -CONFIG_MD_RAID5=y -CONFIG_MD_RAID5_RESHAPE=y -CONFIG_MD_RAID6=m +# CONFIG_MD_RAID456 is not set CONFIG_MD_MULTIPATH=m CONFIG_MD_FAULTY=m CONFIG_BLK_DEV_DM=y @@ -651,6 +664,7 @@ CONFIG_IXGB=m # CONFIG_IXGB_NAPI is not set CONFIG_S2IO=m # CONFIG_S2IO_NAPI is not set +# CONFIG_MYRI10GE is not set # # Token Ring devices @@ -754,6 +768,7 @@ CONFIG_SERIO_LIBPS2=y CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set # CONFIG_SERIAL_NONSTANDARD is not set # @@ -793,6 +808,7 @@ CONFIG_HVCS=m # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_HW_RANDOM is not set CONFIG_GEN_RTC=y # CONFIG_GEN_RTC_X is not set # CONFIG_DTLK is not set @@ -839,6 +855,7 @@ CONFIG_I2C_ALGOBIT=y # CONFIG_I2C_I810 is not set # CONFIG_I2C_PIIX4 is not set # CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_OCORES is not set # CONFIG_I2C_PARPORT is not set # CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_PROSAVAGE is not set @@ -876,7 +893,6 @@ CONFIG_I2C_ALGOBIT=y # # Dallas's 1-wire bus # -# CONFIG_W1 is not set # # Hardware Monitoring support @@ -892,6 +908,7 @@ CONFIG_I2C_ALGOBIT=y # Multimedia devices # # CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices @@ -902,19 +919,19 @@ CONFIG_I2C_ALGOBIT=y # # Graphics support # +CONFIG_FIRMWARE_EDID=y CONFIG_FB=y CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y CONFIG_FB_MACMODES=y -CONFIG_FB_FIRMWARE_EDID=y +# CONFIG_FB_BACKLIGHT is not set CONFIG_FB_MODE_HELPERS=y CONFIG_FB_TILEBLITTING=y # CONFIG_FB_CIRRUS is not set # CONFIG_FB_PM2 is not set # CONFIG_FB_CYBER2000 is not set CONFIG_FB_OF=y -# CONFIG_FB_CT65550 is not set # CONFIG_FB_ASILIANT is not set # CONFIG_FB_IMSTT is not set # CONFIG_FB_VGA16 is not set @@ -993,6 +1010,7 @@ CONFIG_USB_DEVICEFS=y CONFIG_USB_EHCI_HCD=y # CONFIG_USB_EHCI_SPLIT_ISO is not set # CONFIG_USB_EHCI_ROOT_HUB_TT is not set +# CONFIG_USB_EHCI_TT_NEWSCHED is not set # CONFIG_USB_ISP116X_HCD is not set CONFIG_USB_OHCI_HCD=y # CONFIG_USB_OHCI_BIG_ENDIAN is not set @@ -1083,10 +1101,12 @@ CONFIG_USB_MON=y # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set # CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set # CONFIG_USB_PHIDGETKIT is not set # CONFIG_USB_PHIDGETSERVO is not set # CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_APPLEDISPLAY is not set # CONFIG_USB_SISUSBVGA is not set # CONFIG_USB_LD is not set # CONFIG_USB_TEST is not set @@ -1124,12 +1144,14 @@ CONFIG_USB_MON=y CONFIG_INFINIBAND=m CONFIG_INFINIBAND_USER_MAD=m CONFIG_INFINIBAND_USER_ACCESS=m +CONFIG_INFINIBAND_ADDR_TRANS=y CONFIG_INFINIBAND_MTHCA=m CONFIG_INFINIBAND_MTHCA_DEBUG=y CONFIG_INFINIBAND_IPOIB=m CONFIG_INFINIBAND_IPOIB_DEBUG=y # CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set CONFIG_INFINIBAND_SRP=m +# CONFIG_INFINIBAND_ISER is not set # # EDAC - error detection and reporting (RAS) (EXPERIMENTAL) @@ -1141,6 +1163,19 @@ CONFIG_INFINIBAND_SRP=m # CONFIG_RTC_CLASS is not set # +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + +# # File systems # CONFIG_EXT2_FS=y @@ -1169,15 +1204,16 @@ CONFIG_JFS_SECURITY=y # CONFIG_JFS_STATISTICS is not set CONFIG_FS_POSIX_ACL=y CONFIG_XFS_FS=m -CONFIG_XFS_EXPORT=y # CONFIG_XFS_QUOTA is not set CONFIG_XFS_SECURITY=y CONFIG_XFS_POSIX_ACL=y # CONFIG_XFS_RT is not set CONFIG_OCFS2_FS=m +CONFIG_OCFS2_DEBUG_MASKLOG=y # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set @@ -1259,8 +1295,10 @@ CONFIG_RPCSEC_GSS_SPKM3=m # CONFIG_SMB_FS is not set CONFIG_CIFS=m # CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set CONFIG_CIFS_XATTR=y CONFIG_CIFS_POSIX=y +# CONFIG_CIFS_DEBUG2 is not set # CONFIG_CIFS_EXPERIMENTAL is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -1326,6 +1364,9 @@ CONFIG_CRC32=y CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=m +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_PLIST=y # # Instrumentation Support @@ -1339,14 +1380,19 @@ CONFIG_KPROBES=y # # CONFIG_PRINTK_TIME is not set CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_KERNEL=y CONFIG_LOG_BUF_SHIFT=17 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_RWSEMS is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set CONFIG_DEBUG_FS=y diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 803858e86160..8b133afbdc20 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -16,7 +16,7 @@ obj-y := semaphore.o cputable.o ptrace.o syscalls.o \ obj-y += vdso32/ obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ signal_64.o ptrace32.o \ - paca.o cpu_setup_power4.o \ + paca.o cpu_setup_ppc970.o \ firmware.o sysfs.o obj-$(CONFIG_PPC64) += vdso64/ obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o @@ -50,7 +50,8 @@ extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o extra-$(CONFIG_8xx) := head_8xx.o extra-y += vmlinux.lds -obj-y += time.o prom.o traps.o setup-common.o udbg.o +obj-y += time.o prom.o traps.o setup-common.o \ + udbg.o misc.o io.o obj-$(CONFIG_PPC32) += entry_32.o setup_32.o misc_32.o obj-$(CONFIG_PPC64) += misc_64.o dma_64.o iommu.o obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o @@ -66,9 +67,11 @@ pci64-$(CONFIG_PPC64) += pci_64.o pci_dn.o pci_iommu.o \ pci_direct_iommu.o iomap.o pci32-$(CONFIG_PPC32) := pci_32.o obj-$(CONFIG_PCI) += $(pci64-y) $(pci32-y) -kexec-$(CONFIG_PPC64) := machine_kexec_64.o crash.o +kexec-$(CONFIG_PPC64) := machine_kexec_64.o kexec-$(CONFIG_PPC32) := machine_kexec_32.o -obj-$(CONFIG_KEXEC) += machine_kexec.o $(kexec-y) +obj-$(CONFIG_KEXEC) += machine_kexec.o crash.o $(kexec-y) +obj-$(CONFIG_AUDIT) += audit.o +obj64-$(CONFIG_AUDIT) += compat_audit.o ifeq ($(CONFIG_PPC_ISERIES),y) $(obj)/head_64.o: $(obj)/lparmap.s diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index ff2940548929..d06f378597bb 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -13,7 +13,6 @@ * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <linux/signal.h> #include <linux/sched.h> #include <linux/kernel.h> @@ -41,9 +40,10 @@ #ifdef CONFIG_PPC64 #include <asm/paca.h> #include <asm/lppaca.h> -#include <asm/iseries/hv_lp_event.h> #include <asm/cache.h> #include <asm/compat.h> +#include <asm/mmu.h> +#include <asm/hvcall.h> #endif #define DEFINE(sym, val) \ @@ -137,11 +137,18 @@ int main(void) DEFINE(PACA_STARTPURR, offsetof(struct paca_struct, startpurr)); DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time)); DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time)); + DEFINE(PACA_SLBSHADOWPTR, offsetof(struct paca_struct, slb_shadow_ptr)); + DEFINE(PACA_DATA_OFFSET, offsetof(struct paca_struct, data_offset)); + DEFINE(SLBSHADOW_STACKVSID, + offsetof(struct slb_shadow, save_area[SLB_NUM_BOLTED - 1].vsid)); + DEFINE(SLBSHADOW_STACKESID, + offsetof(struct slb_shadow, save_area[SLB_NUM_BOLTED - 1].esid)); DEFINE(LPPACASRR0, offsetof(struct lppaca, saved_srr0)); DEFINE(LPPACASRR1, offsetof(struct lppaca, saved_srr1)); DEFINE(LPPACAANYINT, offsetof(struct lppaca, int_dword.any_int)); DEFINE(LPPACADECRINT, offsetof(struct lppaca, int_dword.fields.decr_int)); + DEFINE(SLBSHADOW_SAVEAREA, offsetof(struct slb_shadow, save_area)); #endif /* CONFIG_PPC64 */ /* RTAS */ @@ -160,6 +167,12 @@ int main(void) /* Create extra stack space for SRR0 and SRR1 when calling prom/rtas. */ DEFINE(PROM_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16); DEFINE(RTAS_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16); + + /* hcall statistics */ + DEFINE(HCALL_STAT_SIZE, sizeof(struct hcall_stats)); + DEFINE(HCALL_STAT_CALLS, offsetof(struct hcall_stats, num_calls)); + DEFINE(HCALL_STAT_TB, offsetof(struct hcall_stats, tb_total)); + DEFINE(HCALL_STAT_PURR, offsetof(struct hcall_stats, purr_total)); #endif /* CONFIG_PPC64 */ DEFINE(GPR0, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[0])); DEFINE(GPR1, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[1])); @@ -241,6 +254,7 @@ int main(void) DEFINE(CPU_SPEC_PVR_VALUE, offsetof(struct cpu_spec, pvr_value)); DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features)); DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup)); + DEFINE(CPU_SPEC_RESTORE, offsetof(struct cpu_spec, cpu_restore)); #ifndef CONFIG_PPC64 DEFINE(pbe_address, offsetof(struct pbe, address)); diff --git a/arch/powerpc/kernel/audit.c b/arch/powerpc/kernel/audit.c new file mode 100644 index 000000000000..7fe5e6300e9a --- /dev/null +++ b/arch/powerpc/kernel/audit.c @@ -0,0 +1,66 @@ +#include <linux/init.h> +#include <linux/types.h> +#include <linux/audit.h> +#include <asm/unistd.h> + +static unsigned dir_class[] = { +#include <asm-generic/audit_dir_write.h> +~0U +}; + +static unsigned read_class[] = { +#include <asm-generic/audit_read.h> +~0U +}; + +static unsigned write_class[] = { +#include <asm-generic/audit_write.h> +~0U +}; + +static unsigned chattr_class[] = { +#include <asm-generic/audit_change_attr.h> +~0U +}; + +int audit_classify_syscall(int abi, unsigned syscall) +{ +#ifdef CONFIG_PPC64 + extern int ppc32_classify_syscall(unsigned); + if (abi == AUDIT_ARCH_PPC) + return ppc32_classify_syscall(syscall); +#endif + switch(syscall) { + case __NR_open: + return 2; + case __NR_openat: + return 3; + case __NR_socketcall: + return 4; + case __NR_execve: + return 5; + default: + return 0; + } +} + +static int __init audit_classes_init(void) +{ +#ifdef CONFIG_PPC64 + extern __u32 ppc32_dir_class[]; + extern __u32 ppc32_write_class[]; + extern __u32 ppc32_read_class[]; + extern __u32 ppc32_chattr_class[]; + audit_register_class(AUDIT_CLASS_WRITE_32, ppc32_write_class); + audit_register_class(AUDIT_CLASS_READ_32, ppc32_read_class); + audit_register_class(AUDIT_CLASS_DIR_WRITE_32, ppc32_dir_class); + audit_register_class(AUDIT_CLASS_CHATTR_32, ppc32_chattr_class); +#endif + audit_register_class(AUDIT_CLASS_WRITE, write_class); + audit_register_class(AUDIT_CLASS_READ, read_class); + audit_register_class(AUDIT_CLASS_DIR_WRITE, dir_class); + audit_register_class(AUDIT_CLASS_CHATTR, chattr_class); + return 0; +} + +__initcall(audit_classes_init); diff --git a/arch/powerpc/kernel/binfmt_elf32.c b/arch/powerpc/kernel/binfmt_elf32.c index 8ad6b0f33651..5cb58757e1b1 100644 --- a/arch/powerpc/kernel/binfmt_elf32.c +++ b/arch/powerpc/kernel/binfmt_elf32.c @@ -19,7 +19,6 @@ #include <asm/processor.h> #include <linux/module.h> -#include <linux/config.h> #include <linux/elfcore.h> #include <linux/compat.h> diff --git a/arch/powerpc/kernel/btext.c b/arch/powerpc/kernel/btext.c index 6223d39177cb..995fcef156fd 100644 --- a/arch/powerpc/kernel/btext.c +++ b/arch/powerpc/kernel/btext.c @@ -3,7 +3,6 @@ * * Benjamin Herrenschmidt <benh@kernel.crashing.org> */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/string.h> #include <linux/init.h> @@ -112,7 +111,7 @@ void __init btext_setup_display(int width, int height, int depth, int pitch, logicalDisplayBase = (unsigned char *)address; dispDeviceBase = (unsigned char *)address; dispDeviceRowBytes = pitch; - dispDeviceDepth = depth; + dispDeviceDepth = depth == 15 ? 16 : depth; dispDeviceRect[0] = dispDeviceRect[1] = 0; dispDeviceRect[2] = width; dispDeviceRect[3] = height; @@ -159,27 +158,35 @@ int btext_initialize(struct device_node *np) { unsigned int width, height, depth, pitch; unsigned long address = 0; - u32 *prop; + const u32 *prop; - prop = (u32 *)get_property(np, "width", NULL); + prop = get_property(np, "linux,bootx-width", NULL); + if (prop == NULL) + prop = get_property(np, "width", NULL); if (prop == NULL) return -EINVAL; width = *prop; - prop = (u32 *)get_property(np, "height", NULL); + prop = get_property(np, "linux,bootx-height", NULL); + if (prop == NULL) + prop = get_property(np, "height", NULL); if (prop == NULL) return -EINVAL; height = *prop; - prop = (u32 *)get_property(np, "depth", NULL); + prop = get_property(np, "linux,bootx-depth", NULL); + if (prop == NULL) + prop = get_property(np, "depth", NULL); if (prop == NULL) return -EINVAL; depth = *prop; pitch = width * ((depth + 7) / 8); - prop = (u32 *)get_property(np, "linebytes", NULL); + prop = get_property(np, "linux,bootx-linebytes", NULL); + if (prop == NULL) + prop = get_property(np, "linebytes", NULL); if (prop) pitch = *prop; if (pitch == 1) pitch = 0x1000; - prop = (u32 *)get_property(np, "address", NULL); + prop = get_property(np, "address", NULL); if (prop) address = *prop; @@ -195,7 +202,7 @@ int btext_initialize(struct device_node *np) g_max_loc_Y = height / 16; dispDeviceBase = (unsigned char *)address; dispDeviceRowBytes = pitch; - dispDeviceDepth = depth; + dispDeviceDepth = depth == 15 ? 16 : depth; dispDeviceRect[0] = dispDeviceRect[1] = 0; dispDeviceRect[2] = width; dispDeviceRect[3] = height; @@ -207,11 +214,11 @@ int btext_initialize(struct device_node *np) int __init btext_find_display(int allow_nonstdout) { - char *name; + const char *name; struct device_node *np = NULL; int rc = -ENODEV; - name = (char *)get_property(of_chosen, "linux,stdout-path", NULL); + name = get_property(of_chosen, "linux,stdout-path", NULL); if (name != NULL) { np = of_find_node_by_path(name); if (np != NULL) { diff --git a/arch/powerpc/kernel/compat_audit.c b/arch/powerpc/kernel/compat_audit.c new file mode 100644 index 000000000000..640d4bb29321 --- /dev/null +++ b/arch/powerpc/kernel/compat_audit.c @@ -0,0 +1,38 @@ +#undef __powerpc64__ +#include <asm/unistd.h> + +unsigned ppc32_dir_class[] = { +#include <asm-generic/audit_dir_write.h> +~0U +}; + +unsigned ppc32_chattr_class[] = { +#include <asm-generic/audit_change_attr.h> +~0U +}; + +unsigned ppc32_write_class[] = { +#include <asm-generic/audit_write.h> +~0U +}; + +unsigned ppc32_read_class[] = { +#include <asm-generic/audit_read.h> +~0U +}; + +int ppc32_classify_syscall(unsigned syscall) +{ + switch(syscall) { + case __NR_open: + return 2; + case __NR_openat: + return 3; + case __NR_socketcall: + return 4; + case __NR_execve: + return 5; + default: + return 1; + } +} diff --git a/arch/powerpc/kernel/cpu_setup_6xx.S b/arch/powerpc/kernel/cpu_setup_6xx.S index 365381fcb27c..8b4a4ee85eca 100644 --- a/arch/powerpc/kernel/cpu_setup_6xx.S +++ b/arch/powerpc/kernel/cpu_setup_6xx.S @@ -9,7 +9,6 @@ * */ -#include <linux/config.h> #include <asm/processor.h> #include <asm/page.h> #include <asm/cputable.h> diff --git a/arch/powerpc/kernel/cpu_setup_power4.S b/arch/powerpc/kernel/cpu_setup_ppc970.S index 271418308d53..652594891d58 100644 --- a/arch/powerpc/kernel/cpu_setup_power4.S +++ b/arch/powerpc/kernel/cpu_setup_ppc970.S @@ -9,7 +9,6 @@ * */ -#include <linux/config.h> #include <asm/processor.h> #include <asm/page.h> #include <asm/cputable.h> @@ -17,27 +16,12 @@ #include <asm/asm-offsets.h> #include <asm/cache.h> -_GLOBAL(__970_cpu_preinit) - /* - * Do nothing if not running in HV mode - */ +_GLOBAL(__cpu_preinit_ppc970) + /* Do nothing if not running in HV mode */ mfmsr r0 rldicl. r0,r0,4,63 beqlr - /* - * Deal only with PPC970 and PPC970FX. - */ - mfspr r0,SPRN_PVR - srwi r0,r0,16 - cmpwi r0,0x39 - beq 1f - cmpwi r0,0x3c - beq 1f - cmpwi r0,0x44 - bnelr -1: - /* Make sure HID4:rm_ci is off before MMU is turned off, that large * pages are enabled with HID4:61 and clear HID5:DCBZ_size and * HID5:DCBZ32_ill @@ -73,21 +57,6 @@ _GLOBAL(__970_cpu_preinit) isync blr -_GLOBAL(__setup_cpu_ppc970) - mfspr r0,SPRN_HID0 - li r11,5 /* clear DOZE and SLEEP */ - rldimi r0,r11,52,8 /* set NAP and DPM */ - mtspr SPRN_HID0,r0 - mfspr r0,SPRN_HID0 - mfspr r0,SPRN_HID0 - mfspr r0,SPRN_HID0 - mfspr r0,SPRN_HID0 - mfspr r0,SPRN_HID0 - mfspr r0,SPRN_HID0 - sync - isync - blr - /* Definitions for the table use to save CPU states */ #define CS_HID0 0 #define CS_HID1 8 @@ -102,30 +71,32 @@ cpu_state_storage: .balign L1_CACHE_BYTES,0 .text -/* Called in normal context to backup CPU 0 state. This - * does not include cache settings. This function is also - * called for machine sleep. This does not include the MMU - * setup, BATs, etc... but rather the "special" registers - * like HID0, HID1, HID4, etc... - */ -_GLOBAL(__save_cpu_setup) - /* Some CR fields are volatile, we back it up all */ - mfcr r7 - /* Get storage ptr */ +_GLOBAL(__setup_cpu_ppc970) + /* Do nothing if not running in HV mode */ + mfmsr r0 + rldicl. r0,r0,4,63 + beqlr + + mfspr r0,SPRN_HID0 + li r11,5 /* clear DOZE and SLEEP */ + rldimi r0,r11,52,8 /* set NAP and DPM */ + li r11,0 + rldimi r0,r11,32,31 /* clear EN_ATTN */ + mtspr SPRN_HID0,r0 + mfspr r0,SPRN_HID0 + mfspr r0,SPRN_HID0 + mfspr r0,SPRN_HID0 + mfspr r0,SPRN_HID0 + mfspr r0,SPRN_HID0 + mfspr r0,SPRN_HID0 + sync + isync + + /* Save away cpu state */ LOAD_REG_IMMEDIATE(r5,cpu_state_storage) - /* We only deal with 970 for now */ - mfspr r0,SPRN_PVR - srwi r0,r0,16 - cmpwi r0,0x39 - beq 1f - cmpwi r0,0x3c - beq 1f - cmpwi r0,0x44 - bne 2f - -1: /* Save HID0,1,4 and 5 */ + /* Save HID0,1,4 and 5 */ mfspr r3,SPRN_HID0 std r3,CS_HID0(r5) mfspr r3,SPRN_HID1 @@ -135,31 +106,20 @@ _GLOBAL(__save_cpu_setup) mfspr r3,SPRN_HID5 std r3,CS_HID5(r5) -2: - mtcr r7 blr /* Called with no MMU context (typically MSR:IR/DR off) to * restore CPU state as backed up by the previous * function. This does not include cache setting */ -_GLOBAL(__restore_cpu_setup) - /* Get storage ptr (FIXME when using anton reloc as we - * are running with translation disabled here - */ - LOAD_REG_IMMEDIATE(r5,cpu_state_storage) +_GLOBAL(__restore_cpu_ppc970) + /* Do nothing if not running in HV mode */ + mfmsr r0 + rldicl. r0,r0,4,63 + beqlr - /* We only deal with 970 for now */ - mfspr r0,SPRN_PVR - srwi r0,r0,16 - cmpwi r0,0x39 - beq 1f - cmpwi r0,0x3c - beq 1f - cmpwi r0,0x44 - bnelr - -1: /* Before accessing memory, we make sure rm_ci is clear */ + LOAD_REG_IMMEDIATE(r5,cpu_state_storage) + /* Before accessing memory, we make sure rm_ci is clear */ li r0,0 mfspr r3,SPRN_HID4 rldimi r3,r0,40,23 /* clear bit 23 (rm_ci) */ diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 1c114880dc05..190a57e20765 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -10,7 +10,6 @@ * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <linux/string.h> #include <linux/sched.h> #include <linux/threads.h> @@ -40,7 +39,10 @@ extern void __setup_cpu_7400(unsigned long offset, struct cpu_spec* spec); extern void __setup_cpu_7410(unsigned long offset, struct cpu_spec* spec); extern void __setup_cpu_745x(unsigned long offset, struct cpu_spec* spec); #endif /* CONFIG_PPC32 */ +#ifdef CONFIG_PPC64 extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec); +extern void __restore_cpu_ppc970(void); +#endif /* CONFIG_PPC64 */ /* This table only contains "desktop" CPUs, it need to be filled with embedded * ones as well... @@ -56,6 +58,9 @@ extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec); #define COMMON_USER_POWER6 (COMMON_USER_PPC64 | PPC_FEATURE_ARCH_2_05 |\ PPC_FEATURE_SMT | PPC_FEATURE_ICACHE_SNOOP | \ PPC_FEATURE_TRUE_LE) +#define COMMON_USER_PA6T (COMMON_USER_PPC64 | PPC_FEATURE_PA6T |\ + PPC_FEATURE_TRUE_LE | \ + PPC_FEATURE_HAS_ALTIVEC_COMP) #define COMMON_USER_BOOKE (PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | \ PPC_FEATURE_BOOKE) @@ -185,6 +190,7 @@ struct cpu_spec cpu_specs[] = { .dcache_bsize = 128, .num_pmcs = 8, .cpu_setup = __setup_cpu_ppc970, + .cpu_restore = __restore_cpu_ppc970, .oprofile_cpu_type = "ppc64/970", .oprofile_type = PPC_OPROFILE_POWER4, .platform = "ppc970", @@ -200,6 +206,7 @@ struct cpu_spec cpu_specs[] = { .dcache_bsize = 128, .num_pmcs = 8, .cpu_setup = __setup_cpu_ppc970, + .cpu_restore = __restore_cpu_ppc970, .oprofile_cpu_type = "ppc64/970", .oprofile_type = PPC_OPROFILE_POWER4, .platform = "ppc970", @@ -215,6 +222,7 @@ struct cpu_spec cpu_specs[] = { .dcache_bsize = 128, .num_pmcs = 8, .cpu_setup = __setup_cpu_ppc970, + .cpu_restore = __restore_cpu_ppc970, .oprofile_cpu_type = "ppc64/970", .oprofile_type = PPC_OPROFILE_POWER4, .platform = "ppc970", @@ -281,6 +289,17 @@ struct cpu_spec cpu_specs[] = { .dcache_bsize = 128, .platform = "ppc-cell-be", }, + { /* PA Semi PA6T */ + .pvr_mask = 0x7fff0000, + .pvr_value = 0x00900000, + .cpu_name = "PA6T", + .cpu_features = CPU_FTRS_PA6T, + .cpu_user_features = COMMON_USER_PA6T, + .icache_bsize = 64, + .dcache_bsize = 64, + .num_pmcs = 6, + .platform = "pa6t", + }, { /* default match */ .pvr_mask = 0x00000000, .pvr_value = 0x00000000, @@ -722,18 +741,6 @@ struct cpu_spec cpu_specs[] = { .oprofile_type = PPC_OPROFILE_G4, .platform = "ppc7450", }, - { /* 8641 */ - .pvr_mask = 0xffffffff, - .pvr_value = 0x80040010, - .cpu_name = "8641", - .cpu_features = CPU_FTRS_7447A, - .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP, - .icache_bsize = 32, - .dcache_bsize = 32, - .num_pmcs = 6, - .cpu_setup = __setup_cpu_745x - }, - { /* 82xx (8240, 8245, 8260 are all 603e cores) */ .pvr_mask = 0x7fff0000, .pvr_value = 0x00810000, @@ -942,6 +949,7 @@ struct cpu_spec cpu_specs[] = { PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, .icache_bsize = 32, .dcache_bsize = 32, + .platform = "ppc405", }, { /* 405EP */ .pvr_mask = 0xffff0000, diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c index dbcb85994f46..1af41f7616dc 100644 --- a/arch/powerpc/kernel/crash.c +++ b/arch/powerpc/kernel/crash.c @@ -24,9 +24,11 @@ #include <linux/init.h> #include <linux/irq.h> #include <linux/types.h> +#include <linux/irq.h> #include <asm/processor.h> #include <asm/machdep.h> +#include <asm/kexec.h> #include <asm/kdump.h> #include <asm/lmb.h> #include <asm/firmware.h> @@ -41,6 +43,8 @@ /* This keeps a track of which one is crashing cpu. */ int crashing_cpu = -1; +static cpumask_t cpus_in_crash = CPU_MASK_NONE; +cpumask_t cpus_in_sr = CPU_MASK_NONE; static u32 *append_elf_note(u32 *buf, char *name, unsigned type, void *data, size_t data_len) @@ -98,34 +102,72 @@ static void crash_save_this_cpu(struct pt_regs *regs, int cpu) } #ifdef CONFIG_SMP -static atomic_t waiting_for_crash_ipi; +static atomic_t enter_on_soft_reset = ATOMIC_INIT(0); void crash_ipi_callback(struct pt_regs *regs) { int cpu = smp_processor_id(); - if (cpu == crashing_cpu) - return; - if (!cpu_online(cpu)) return; + local_irq_disable(); + if (!cpu_isset(cpu, cpus_in_crash)) + crash_save_this_cpu(regs, cpu); + cpu_set(cpu, cpus_in_crash); + + /* + * Entered via soft-reset - could be the kdump + * process is invoked using soft-reset or user activated + * it if some CPU did not respond to an IPI. + * For soft-reset, the secondary CPU can enter this func + * twice. 1 - using IPI, and 2. soft-reset. + * Tell the kexec CPU that entered via soft-reset and ready + * to go down. + */ + if (cpu_isset(cpu, cpus_in_sr)) { + cpu_clear(cpu, cpus_in_sr); + atomic_inc(&enter_on_soft_reset); + } + + /* + * Starting the kdump boot. + * This barrier is needed to make sure that all CPUs are stopped. + * If not, soft-reset will be invoked to bring other CPUs. + */ + while (!cpu_isset(crashing_cpu, cpus_in_crash)) + cpu_relax(); + if (ppc_md.kexec_cpu_down) ppc_md.kexec_cpu_down(1, 1); - local_irq_disable(); - - crash_save_this_cpu(regs, cpu); - atomic_dec(&waiting_for_crash_ipi); +#ifdef CONFIG_PPC64 kexec_smp_wait(); +#else + for (;;); /* FIXME */ +#endif + /* NOTREACHED */ } -static void crash_kexec_prepare_cpus(void) +/* + * Wait until all CPUs are entered via soft-reset. + */ +static void crash_soft_reset_check(int cpu) +{ + unsigned int ncpus = num_online_cpus() - 1;/* Excluding the panic cpu */ + + cpu_clear(cpu, cpus_in_sr); + while (atomic_read(&enter_on_soft_reset) != ncpus) + cpu_relax(); +} + + +static void crash_kexec_prepare_cpus(int cpu) { unsigned int msecs; - atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1); + unsigned int ncpus = num_online_cpus() - 1;/* Excluding the panic cpu */ crash_send_ipi(crash_ipi_callback); smp_wmb(); @@ -133,14 +175,13 @@ static void crash_kexec_prepare_cpus(void) /* * FIXME: Until we will have the way to stop other CPUSs reliabally, * the crash CPU will send an IPI and wait for other CPUs to - * respond. If not, proceed the kexec boot even though we failed to - * capture other CPU states. + * respond. * Delay of at least 10 seconds. */ - printk(KERN_ALERT "Sending IPI to other cpus...\n"); + printk(KERN_EMERG "Sending IPI to other cpus...\n"); msecs = 10000; - while ((atomic_read(&waiting_for_crash_ipi) > 0) && (--msecs > 0)) { - barrier(); + while ((cpus_weight(cpus_in_crash) < ncpus) && (--msecs > 0)) { + cpu_relax(); mdelay(1); } @@ -149,18 +190,71 @@ static void crash_kexec_prepare_cpus(void) /* * FIXME: In case if we do not get all CPUs, one possibility: ask the * user to do soft reset such that we get all. - * IPI handler is already set by the panic cpu initially. Therefore, - * all cpus could invoke this handler from die() and the panic CPU - * will call machine_kexec() directly from this handler to do - * kexec boot. + * Soft-reset will be used until better mechanism is implemented. + */ + if (cpus_weight(cpus_in_crash) < ncpus) { + printk(KERN_EMERG "done waiting: %d cpu(s) not responding\n", + ncpus - cpus_weight(cpus_in_crash)); + printk(KERN_EMERG "Activate soft-reset to stop other cpu(s)\n"); + cpus_in_sr = CPU_MASK_NONE; + atomic_set(&enter_on_soft_reset, 0); + while (cpus_weight(cpus_in_crash) < ncpus) + cpu_relax(); + } + /* + * Make sure all CPUs are entered via soft-reset if the kdump is + * invoked using soft-reset. */ - if (atomic_read(&waiting_for_crash_ipi)) - printk(KERN_ALERT "done waiting: %d cpus not responding\n", - atomic_read(&waiting_for_crash_ipi)); + if (cpu_isset(cpu, cpus_in_sr)) + crash_soft_reset_check(cpu); /* Leave the IPI callback set */ } + +/* + * This function will be called by secondary cpus or by kexec cpu + * if soft-reset is activated to stop some CPUs. + */ +void crash_kexec_secondary(struct pt_regs *regs) +{ + int cpu = smp_processor_id(); + unsigned long flags; + int msecs = 5; + + local_irq_save(flags); + /* Wait 5ms if the kexec CPU is not entered yet. */ + while (crashing_cpu < 0) { + if (--msecs < 0) { + /* + * Either kdump image is not loaded or + * kdump process is not started - Probably xmon + * exited using 'x'(exit and recover) or + * kexec_should_crash() failed for all running tasks. + */ + cpu_clear(cpu, cpus_in_sr); + local_irq_restore(flags); + return; + } + mdelay(1); + cpu_relax(); + } + if (cpu == crashing_cpu) { + /* + * Panic CPU will enter this func only via soft-reset. + * Wait until all secondary CPUs entered and + * then start kexec boot. + */ + crash_soft_reset_check(cpu); + cpu_set(crashing_cpu, cpus_in_crash); + if (ppc_md.kexec_cpu_down) + ppc_md.kexec_cpu_down(1, 0); + machine_kexec(kexec_crash_image); + /* NOTREACHED */ + } + crash_ipi_callback(regs); +} + #else -static void crash_kexec_prepare_cpus(void) +static void crash_kexec_prepare_cpus(int cpu) { /* * move the secondarys to us so that we can copy @@ -168,9 +262,17 @@ static void crash_kexec_prepare_cpus(void) * * do this if kexec in setup.c ? */ +#ifdef CONFIG_PPC64 smp_release_cpus(); +#else + /* FIXME */ +#endif } +void crash_kexec_secondary(struct pt_regs *regs) +{ + cpus_in_sr = CPU_MASK_NONE; +} #endif void default_machine_crash_shutdown(struct pt_regs *regs) @@ -179,7 +281,7 @@ void default_machine_crash_shutdown(struct pt_regs *regs) /* * This function is only called after the system - * has paniced or is otherwise in a critical state. + * has panicked or is otherwise in a critical state. * The minimum amount of code to allow a kexec'd kernel * to run successfully needs to happen here. * @@ -190,23 +292,23 @@ void default_machine_crash_shutdown(struct pt_regs *regs) local_irq_disable(); for_each_irq(irq) { - struct irq_desc *desc = irq_descp(irq); + struct irq_desc *desc = irq_desc + irq; if (desc->status & IRQ_INPROGRESS) - desc->handler->end(irq); + desc->chip->eoi(irq); if (!(desc->status & IRQ_DISABLED)) - desc->handler->disable(irq); + desc->chip->disable(irq); } - if (ppc_md.kexec_cpu_down) - ppc_md.kexec_cpu_down(1, 0); - /* * Make a note of crashing cpu. Will be used in machine_kexec * such that another IPI will not be sent. */ crashing_cpu = smp_processor_id(); - crash_kexec_prepare_cpus(); crash_save_this_cpu(regs, crashing_cpu); + crash_kexec_prepare_cpus(crashing_cpu); + cpu_set(crashing_cpu, cpus_in_crash); + if (ppc_md.kexec_cpu_down) + ppc_md.kexec_cpu_down(1, 0); } diff --git a/arch/powerpc/kernel/crash_dump.c b/arch/powerpc/kernel/crash_dump.c index 371973be8d71..2f6f5a7bc69e 100644 --- a/arch/powerpc/kernel/crash_dump.c +++ b/arch/powerpc/kernel/crash_dump.c @@ -80,7 +80,7 @@ static int __init parse_savemaxmem(char *p) } __setup("savemaxmem=", parse_savemaxmem); -/* +/** * copy_oldmem_page - copy one page from "oldmem" * @pfn: page frame number to be copied * @buf: target memory address for the copy; this can be in kernel address diff --git a/arch/powerpc/kernel/dma_64.c b/arch/powerpc/kernel/dma_64.c index 36aaa7663f02..6c168f6ea142 100644 --- a/arch/powerpc/kernel/dma_64.c +++ b/arch/powerpc/kernel/dma_64.c @@ -35,10 +35,9 @@ int dma_supported(struct device *dev, u64 mask) { struct dma_mapping_ops *dma_ops = get_dma_ops(dev); - if (dma_ops) - return dma_ops->dma_supported(dev, mask); - BUG(); - return 0; + BUG_ON(!dma_ops); + + return dma_ops->dma_supported(dev, mask); } EXPORT_SYMBOL(dma_supported); @@ -66,10 +65,9 @@ void *dma_alloc_coherent(struct device *dev, size_t size, { struct dma_mapping_ops *dma_ops = get_dma_ops(dev); - if (dma_ops) - return dma_ops->alloc_coherent(dev, size, dma_handle, flag); - BUG(); - return NULL; + BUG_ON(!dma_ops); + + return dma_ops->alloc_coherent(dev, size, dma_handle, flag); } EXPORT_SYMBOL(dma_alloc_coherent); @@ -78,10 +76,9 @@ void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, { struct dma_mapping_ops *dma_ops = get_dma_ops(dev); - if (dma_ops) - dma_ops->free_coherent(dev, size, cpu_addr, dma_handle); - else - BUG(); + BUG_ON(!dma_ops); + + dma_ops->free_coherent(dev, size, cpu_addr, dma_handle); } EXPORT_SYMBOL(dma_free_coherent); @@ -90,10 +87,9 @@ dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, size_t size, { struct dma_mapping_ops *dma_ops = get_dma_ops(dev); - if (dma_ops) - return dma_ops->map_single(dev, cpu_addr, size, direction); - BUG(); - return (dma_addr_t)0; + BUG_ON(!dma_ops); + + return dma_ops->map_single(dev, cpu_addr, size, direction); } EXPORT_SYMBOL(dma_map_single); @@ -102,10 +98,9 @@ void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, { struct dma_mapping_ops *dma_ops = get_dma_ops(dev); - if (dma_ops) - dma_ops->unmap_single(dev, dma_addr, size, direction); - else - BUG(); + BUG_ON(!dma_ops); + + dma_ops->unmap_single(dev, dma_addr, size, direction); } EXPORT_SYMBOL(dma_unmap_single); @@ -115,11 +110,10 @@ dma_addr_t dma_map_page(struct device *dev, struct page *page, { struct dma_mapping_ops *dma_ops = get_dma_ops(dev); - if (dma_ops) - return dma_ops->map_single(dev, - (page_address(page) + offset), size, direction); - BUG(); - return (dma_addr_t)0; + BUG_ON(!dma_ops); + + return dma_ops->map_single(dev, page_address(page) + offset, size, + direction); } EXPORT_SYMBOL(dma_map_page); @@ -128,10 +122,9 @@ void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size, { struct dma_mapping_ops *dma_ops = get_dma_ops(dev); - if (dma_ops) - dma_ops->unmap_single(dev, dma_address, size, direction); - else - BUG(); + BUG_ON(!dma_ops); + + dma_ops->unmap_single(dev, dma_address, size, direction); } EXPORT_SYMBOL(dma_unmap_page); @@ -140,10 +133,9 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, { struct dma_mapping_ops *dma_ops = get_dma_ops(dev); - if (dma_ops) - return dma_ops->map_sg(dev, sg, nents, direction); - BUG(); - return 0; + BUG_ON(!dma_ops); + + return dma_ops->map_sg(dev, sg, nents, direction); } EXPORT_SYMBOL(dma_map_sg); @@ -152,9 +144,8 @@ void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries, { struct dma_mapping_ops *dma_ops = get_dma_ops(dev); - if (dma_ops) - dma_ops->unmap_sg(dev, sg, nhwentries, direction); - else - BUG(); + BUG_ON(!dma_ops); + + dma_ops->unmap_sg(dev, sg, nhwentries, direction); } EXPORT_SYMBOL(dma_unmap_sg); diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index 8866fd26c6b9..c03e829fee3c 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S @@ -19,7 +19,6 @@ * */ -#include <linux/config.h> #include <linux/errno.h> #include <linux/sys.h> #include <linux/threads.h> diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 221062c960c9..2cd872b5283b 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -18,7 +18,6 @@ * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <linux/errno.h> #include <asm/unistd.h> #include <asm/processor.h> @@ -376,6 +375,14 @@ BEGIN_FTR_SECTION ld r7,KSP_VSID(r4) /* Get new stack's VSID */ oris r0,r6,(SLB_ESID_V)@h ori r0,r0,(SLB_NUM_BOLTED-1)@l + + /* Update the last bolted SLB */ + ld r9,PACA_SLBSHADOWPTR(r13) + li r12,0 + std r12,SLBSHADOW_STACKESID(r9) /* Clear ESID */ + std r7,SLBSHADOW_STACKVSID(r9) /* Save VSID */ + std r0,SLBSHADOW_STACKESID(r9) /* Save ESID */ + slbie r6 slbie r6 /* Workaround POWER5 < DD2.1 issue */ slbmte r7,r0 diff --git a/arch/powerpc/kernel/firmware.c b/arch/powerpc/kernel/firmware.c index 0bfe9061720a..1679a70bbcad 100644 --- a/arch/powerpc/kernel/firmware.c +++ b/arch/powerpc/kernel/firmware.c @@ -13,7 +13,6 @@ * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <linux/module.h> #include <asm/firmware.h> diff --git a/arch/powerpc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S index 01f71200c603..821e152e093c 100644 --- a/arch/powerpc/kernel/fpu.S +++ b/arch/powerpc/kernel/fpu.S @@ -2,6 +2,11 @@ * FPU support code, moved here from head.S so that it can be used * by chips which use other head-whatever.S files. * + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu> + * Copyright (C) 1996 Paul Mackerras. + * Copyright (C) 1997 Dan Malek (dmalek@jlc.net). + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version @@ -9,7 +14,6 @@ * */ -#include <linux/config.h> #include <asm/reg.h> #include <asm/page.h> #include <asm/mmu.h> diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S index b25b25902d15..d88e182e40b3 100644 --- a/arch/powerpc/kernel/head_32.S +++ b/arch/powerpc/kernel/head_32.S @@ -22,7 +22,6 @@ * */ -#include <linux/config.h> #include <asm/reg.h> #include <asm/page.h> #include <asm/mmu.h> diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S index 47c7fa148c9a..accb39d49911 100644 --- a/arch/powerpc/kernel/head_44x.S +++ b/arch/powerpc/kernel/head_44x.S @@ -28,7 +28,6 @@ * option) any later version. */ -#include <linux/config.h> #include <asm/processor.h> #include <asm/page.h> #include <asm/mmu.h> diff --git a/arch/powerpc/kernel/head_4xx.S b/arch/powerpc/kernel/head_4xx.S index 2590e97f5539..adc7f8097cd4 100644 --- a/arch/powerpc/kernel/head_4xx.S +++ b/arch/powerpc/kernel/head_4xx.S @@ -31,7 +31,6 @@ * */ -#include <linux/config.h> #include <asm/processor.h> #include <asm/page.h> #include <asm/mmu.h> diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 831acbdf2592..3065b472b95d 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -21,7 +21,6 @@ * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <linux/threads.h> #include <asm/reg.h> #include <asm/page.h> @@ -85,34 +84,6 @@ END_FTR_SECTION(0, 1) /* Catch branch to 0 in real mode */ trap -#ifdef CONFIG_PPC_ISERIES - /* - * At offset 0x20, there is a pointer to iSeries LPAR data. - * This is required by the hypervisor - */ - . = 0x20 - .llong hvReleaseData-KERNELBASE - - /* - * At offset 0x28 and 0x30 are offsets to the mschunks_map - * array (used by the iSeries LPAR debugger to do translation - * between physical addresses and absolute addresses) and - * to the pidhash table (also used by the debugger) - */ - .llong mschunks_map-KERNELBASE - .llong 0 /* pidhash-KERNELBASE SFRXXX */ - - /* Offset 0x38 - Pointer to start of embedded System.map */ - .globl embedded_sysmap_start -embedded_sysmap_start: - .llong 0 - /* Offset 0x40 - Pointer to end of embedded System.map */ - .globl embedded_sysmap_end -embedded_sysmap_end: - .llong 0 - -#endif /* CONFIG_PPC_ISERIES */ - /* Secondary processors spin on this value until it goes to 1. */ .globl __secondary_hold_spinloop __secondary_hold_spinloop: @@ -124,6 +95,15 @@ __secondary_hold_spinloop: __secondary_hold_acknowledge: .llong 0x0 +#ifdef CONFIG_PPC_ISERIES + /* + * At offset 0x20, there is a pointer to iSeries LPAR data. + * This is required by the hypervisor + */ + . = 0x20 + .llong hvReleaseData-KERNELBASE +#endif /* CONFIG_PPC_ISERIES */ + . = 0x60 /* * The following code is used on pSeries to hold secondary processors @@ -152,7 +132,7 @@ _GLOBAL(__secondary_hold) bne 100b #if defined(CONFIG_SMP) || defined(CONFIG_KEXEC) - LOAD_REG_IMMEDIATE(r4, .pSeries_secondary_smp_init) + LOAD_REG_IMMEDIATE(r4, .generic_secondary_smp_init) mtctr r4 mr r3,r24 bctr @@ -211,6 +191,37 @@ exception_marker: ori reg,reg,(label)@l; /* virt addr of handler ... */ #endif +/* + * Equal to EXCEPTION_PROLOG_PSERIES, except that it forces 64bit mode. + * The firmware calls the registered system_reset_fwnmi and + * machine_check_fwnmi handlers in 32bit mode if the cpu happens to run + * a 32bit application at the time of the event. + * This firmware bug is present on POWER4 and JS20. + */ +#define EXCEPTION_PROLOG_PSERIES_FORCE_64BIT(area, label) \ + mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \ + std r9,area+EX_R9(r13); /* save r9 - r12 */ \ + std r10,area+EX_R10(r13); \ + std r11,area+EX_R11(r13); \ + std r12,area+EX_R12(r13); \ + mfspr r9,SPRN_SPRG1; \ + std r9,area+EX_R13(r13); \ + mfcr r9; \ + clrrdi r12,r13,32; /* get high part of &label */ \ + mfmsr r10; \ + /* force 64bit mode */ \ + li r11,5; /* MSR_SF_LG|MSR_ISF_LG */ \ + rldimi r10,r11,61,0; /* insert into top 3 bits */ \ + /* done 64bit mode */ \ + mfspr r11,SPRN_SRR0; /* save SRR0 */ \ + LOAD_HANDLER(r12,label) \ + ori r10,r10,MSR_IR|MSR_DR|MSR_RI; \ + mtspr SPRN_SRR0,r12; \ + mfspr r12,SPRN_SRR1; /* and SRR1 */ \ + mtspr SPRN_SRR1,r10; \ + rfid; \ + b . /* prevent speculative execution */ + #define EXCEPTION_PROLOG_PSERIES(area, label) \ mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \ std r9,area+EX_R9(r13); /* save r9 - r12 */ \ @@ -624,14 +635,14 @@ slb_miss_user_pseries: system_reset_fwnmi: HMT_MEDIUM mtspr SPRN_SPRG1,r13 /* save r13 */ - EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common) + EXCEPTION_PROLOG_PSERIES_FORCE_64BIT(PACA_EXGEN, system_reset_common) .globl machine_check_fwnmi .align 7 machine_check_fwnmi: HMT_MEDIUM mtspr SPRN_SPRG1,r13 /* save r13 */ - EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common) + EXCEPTION_PROLOG_PSERIES_FORCE_64BIT(PACA_EXMC, machine_check_common) #ifdef CONFIG_PPC_ISERIES /*** ISeries-LPAR interrupt handlers ***/ @@ -1473,19 +1484,17 @@ fwnmi_data_area: . = 0x8000 /* - * On pSeries, secondary processors spin in the following code. + * On pSeries and most other platforms, secondary processors spin + * in the following code. * At entry, r3 = this processor's number (physical cpu id) */ -_GLOBAL(pSeries_secondary_smp_init) +_GLOBAL(generic_secondary_smp_init) mr r24,r3 /* turn on 64-bit mode */ bl .enable_64b_mode isync - /* Copy some CPU settings from CPU 0 */ - bl .__restore_cpu_setup - /* Set up a paca value for this processor. Since we have the * physical cpu id in r24, we need to search the pacas to find * which logical id maps to our physical one. @@ -1511,15 +1520,28 @@ _GLOBAL(pSeries_secondary_smp_init) /* start. */ sync - /* Create a temp kernel stack for use before relocation is on. */ +#ifndef CONFIG_SMP + b 3b /* Never go on non-SMP */ +#else + cmpwi 0,r23,0 + beq 3b /* Loop until told to go */ + + /* See if we need to call a cpu state restore handler */ + LOAD_REG_IMMEDIATE(r23, cur_cpu_spec) + ld r23,0(r23) + ld r23,CPU_SPEC_RESTORE(r23) + cmpdi 0,r23,0 + beq 4f + ld r23,0(r23) + mtctr r23 + bctrl + +4: /* Create a temp kernel stack for use before relocation is on. */ ld r1,PACAEMERGSP(r13) subi r1,r1,STACK_FRAME_OVERHEAD - cmpwi 0,r23,0 -#ifdef CONFIG_SMP - bne .__secondary_start + b .__secondary_start #endif - b 3b /* Loop until told to go */ #ifdef CONFIG_PPC_ISERIES _STATIC(__start_initialization_iSeries) @@ -1600,10 +1622,16 @@ _GLOBAL(__start_initialization_multiplatform) bl .enable_64b_mode /* Setup some critical 970 SPRs before switching MMU off */ - bl .__970_cpu_preinit - - /* cpu # */ - li r24,0 + mfspr r0,SPRN_PVR + srwi r0,r0,16 + cmpwi r0,0x39 /* 970 */ + beq 1f + cmpwi r0,0x3c /* 970FX */ + beq 1f + cmpwi r0,0x44 /* 970MP */ + bne 2f +1: bl .__cpu_preinit_ppc970 +2: /* Switch off MMU if not already */ LOAD_REG_IMMEDIATE(r4, .__after_prom_start - KERNELBASE) @@ -1683,6 +1711,9 @@ _STATIC(__after_prom_start) /* i.e. where we are running */ /* the source addr */ + cmpdi r4,0 /* In some cases the loader may */ + beq .start_here_multiplatform /* have already put us at zero */ + /* so we can skip the copy. */ LOAD_REG_IMMEDIATE(r5,copy_to_here) /* # bytes of memory to copy */ sub r5,r5,r27 @@ -1717,7 +1748,7 @@ _STATIC(__after_prom_start) _GLOBAL(copy_and_flush) addi r5,r5,-8 addi r6,r6,-8 -4: li r0,16 /* Use the least common */ +4: li r0,8 /* Use the smallest common */ /* denominator cache line */ /* size. This results in */ /* extra cache line flushes */ @@ -1771,7 +1802,7 @@ _GLOBAL(pmac_secondary_start) isync /* Copy some CPU settings from CPU 0 */ - bl .__restore_cpu_setup + bl .__restore_cpu_ppc970 /* pSeries do that early though I don't think we really need it */ mfmsr r3 @@ -1921,12 +1952,6 @@ _STATIC(start_here_multiplatform) mr r5,r26 bl .identify_cpu - /* Save some low level config HIDs of CPU0 to be copied to - * other CPUs later on, or used for suspend/resume - */ - bl .__save_cpu_setup - sync - /* Do very early kernel initializations, including initial hash table, * stab and slb setup before we turn on relocation. */ @@ -1962,14 +1987,6 @@ _STATIC(start_here_common) li r3,0 bl .do_cpu_ftr_fixups - LOAD_REG_IMMEDIATE(r26, boot_cpuid) - lwz r26,0(r26) - - LOAD_REG_IMMEDIATE(r24, paca) /* Get base vaddr of paca array */ - mulli r13,r26,PACA_SIZE /* Calculate vaddr of right paca */ - add r13,r13,r24 /* for this processor. */ - mtspr SPRN_SPRG3,r13 - /* ptr to current */ LOAD_REG_IMMEDIATE(r4, init_task) std r4,PACACURRENT(r13) @@ -1995,17 +2012,6 @@ _STATIC(start_here_common) /* Not reached */ BUG_OPCODE -/* Put the paca pointer into r13 and SPRG3 */ -_GLOBAL(setup_boot_paca) - LOAD_REG_IMMEDIATE(r3, boot_cpuid) - lwz r3,0(r3) - LOAD_REG_IMMEDIATE(r4, paca) /* Get base vaddr of paca array */ - mulli r3,r3,PACA_SIZE /* Calculate vaddr of right paca */ - add r13,r3,r4 /* for this processor. */ - mtspr SPRN_SPRG3,r13 - - blr - /* * We put a few things here that have to be page-aligned. * This stuff goes at the beginning of the bss, which is page-aligned. diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index 28941f5ce673..901be47a02a9 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S @@ -19,7 +19,6 @@ * */ -#include <linux/config.h> #include <asm/processor.h> #include <asm/page.h> #include <asm/mmu.h> diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index dd86bbed7627..66877bdfe0b7 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S @@ -30,7 +30,6 @@ * option) any later version. */ -#include <linux/config.h> #include <linux/threads.h> #include <asm/processor.h> #include <asm/page.h> diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c index e47d40ac6f39..124dbcba94a8 100644 --- a/arch/powerpc/kernel/ibmebus.c +++ b/arch/powerpc/kernel/ibmebus.c @@ -167,7 +167,7 @@ static DEVICE_ATTR(name, S_IRUSR | S_IRGRP | S_IROTH, ibmebusdev_show_name, NULL); static struct ibmebus_dev* __devinit ibmebus_register_device_common( - struct ibmebus_dev *dev, char *name) + struct ibmebus_dev *dev, const char *name) { int err = 0; @@ -194,10 +194,10 @@ static struct ibmebus_dev* __devinit ibmebus_register_device_node( struct device_node *dn) { struct ibmebus_dev *dev; - char *loc_code; + const char *loc_code; int length; - loc_code = (char *)get_property(dn, "ibm,loc-code", NULL); + loc_code = get_property(dn, "ibm,loc-code", NULL); if (!loc_code) { printk(KERN_WARNING "%s: node %s missing 'ibm,loc-code'\n", __FUNCTION__, dn->name ? dn->name : "<unknown>"); @@ -323,13 +323,11 @@ int ibmebus_request_irq(struct ibmebus_dev *dev, unsigned long irq_flags, const char * devname, void *dev_id) { - unsigned int irq = virt_irq_create_mapping(ist); + unsigned int irq = irq_create_mapping(NULL, ist); if (irq == NO_IRQ) return -EINVAL; - irq = irq_offset_up(irq); - return request_irq(irq, handler, irq_flags, devname, dev_id); } @@ -337,12 +335,9 @@ EXPORT_SYMBOL(ibmebus_request_irq); void ibmebus_free_irq(struct ibmebus_dev *dev, u32 ist, void *dev_id) { - unsigned int irq = virt_irq_create_mapping(ist); + unsigned int irq = irq_find_mapping(NULL, ist); - irq = irq_offset_up(irq); free_irq(irq, dev_id); - - return; } EXPORT_SYMBOL(ibmebus_free_irq); diff --git a/arch/powerpc/kernel/idle.c b/arch/powerpc/kernel/idle.c index d491052c8e0c..4180c3998b39 100644 --- a/arch/powerpc/kernel/idle.c +++ b/arch/powerpc/kernel/idle.c @@ -19,7 +19,6 @@ * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <linux/sched.h> #include <linux/kernel.h> #include <linux/smp.h> diff --git a/arch/powerpc/kernel/idle_6xx.S b/arch/powerpc/kernel/idle_6xx.S index b45fa0e37212..01bcd52bbf8e 100644 --- a/arch/powerpc/kernel/idle_6xx.S +++ b/arch/powerpc/kernel/idle_6xx.S @@ -13,7 +13,6 @@ * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <linux/threads.h> #include <asm/reg.h> #include <asm/page.h> diff --git a/arch/powerpc/kernel/idle_power4.S b/arch/powerpc/kernel/idle_power4.S index d85c7c938eed..30de81da7b40 100644 --- a/arch/powerpc/kernel/idle_power4.S +++ b/arch/powerpc/kernel/idle_power4.S @@ -7,7 +7,6 @@ * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <linux/threads.h> #include <asm/processor.h> #include <asm/page.h> diff --git a/arch/powerpc/kernel/io.c b/arch/powerpc/kernel/io.c new file mode 100644 index 000000000000..e98180686b35 --- /dev/null +++ b/arch/powerpc/kernel/io.c @@ -0,0 +1,131 @@ +/* + * I/O string operations + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * Copyright (C) 2006 IBM Corporation + * + * Largely rewritten by Cort Dougan (cort@cs.nmt.edu) + * and Paul Mackerras. + * + * Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com) + * PPC64 updates by Dave Engebretsen (engebret@us.ibm.com) + * + * Rewritten in C by Stephen Rothwell. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/compiler.h> +#include <linux/module.h> + +#include <asm/io.h> +#include <asm/firmware.h> +#include <asm/bug.h> + +void _insb(volatile u8 __iomem *port, void *buf, long count) +{ + u8 *tbuf = buf; + u8 tmp; + + BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); + + if (unlikely(count <= 0)) + return; + asm volatile("sync"); + do { + tmp = *port; + asm volatile("eieio"); + *tbuf++ = tmp; + } while (--count != 0); + asm volatile("twi 0,%0,0; isync" : : "r" (tmp)); +} +EXPORT_SYMBOL(_insb); + +void _outsb(volatile u8 __iomem *port, const void *buf, long count) +{ + const u8 *tbuf = buf; + + BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); + + if (unlikely(count <= 0)) + return; + asm volatile("sync"); + do { + *port = *tbuf++; + } while (--count != 0); + asm volatile("sync"); +} +EXPORT_SYMBOL(_outsb); + +void _insw_ns(volatile u16 __iomem *port, void *buf, long count) +{ + u16 *tbuf = buf; + u16 tmp; + + BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); + + if (unlikely(count <= 0)) + return; + asm volatile("sync"); + do { + tmp = *port; + asm volatile("eieio"); + *tbuf++ = tmp; + } while (--count != 0); + asm volatile("twi 0,%0,0; isync" : : "r" (tmp)); +} +EXPORT_SYMBOL(_insw_ns); + +void _outsw_ns(volatile u16 __iomem *port, const void *buf, long count) +{ + const u16 *tbuf = buf; + + BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); + + if (unlikely(count <= 0)) + return; + asm volatile("sync"); + do { + *port = *tbuf++; + } while (--count != 0); + asm volatile("sync"); +} +EXPORT_SYMBOL(_outsw_ns); + +void _insl_ns(volatile u32 __iomem *port, void *buf, long count) +{ + u32 *tbuf = buf; + u32 tmp; + + BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); + + if (unlikely(count <= 0)) + return; + asm volatile("sync"); + do { + tmp = *port; + asm volatile("eieio"); + *tbuf++ = tmp; + } while (--count != 0); + asm volatile("twi 0,%0,0; isync" : : "r" (tmp)); +} +EXPORT_SYMBOL(_insl_ns); + +void _outsl_ns(volatile u32 __iomem *port, const void *buf, long count) +{ + const u32 *tbuf = buf; + + BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); + + if (unlikely(count <= 0)) + return; + asm volatile("sync"); + do { + *port = *tbuf++; + } while (--count != 0); + asm volatile("sync"); +} +EXPORT_SYMBOL(_outsl_ns); diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index 7cb77c20fc5d..ba0694071728 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c @@ -23,7 +23,6 @@ */ -#include <linux/config.h> #include <linux/init.h> #include <linux/types.h> #include <linux/slab.h> @@ -38,6 +37,7 @@ #include <asm/iommu.h> #include <asm/pci-bridge.h> #include <asm/machdep.h> +#include <asm/kdump.h> #define DBG(...) @@ -440,8 +440,37 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid) tbl->it_largehint = tbl->it_halfpoint; spin_lock_init(&tbl->it_lock); +#ifdef CONFIG_CRASH_DUMP + if (ppc_md.tce_get) { + unsigned long index, tceval; + unsigned long tcecount = 0; + + /* + * Reserve the existing mappings left by the first kernel. + */ + for (index = 0; index < tbl->it_size; index++) { + tceval = ppc_md.tce_get(tbl, index + tbl->it_offset); + /* + * Freed TCE entry contains 0x7fffffffffffffff on JS20 + */ + if (tceval && (tceval != 0x7fffffffffffffffUL)) { + __set_bit(index, tbl->it_map); + tcecount++; + } + } + if ((tbl->it_size - tcecount) < KDUMP_MIN_TCE_ENTRIES) { + printk(KERN_WARNING "TCE table is full; "); + printk(KERN_WARNING "freeing %d entries for the kdump boot\n", + KDUMP_MIN_TCE_ENTRIES); + for (index = tbl->it_size - KDUMP_MIN_TCE_ENTRIES; + index < tbl->it_size; index++) + __clear_bit(index, tbl->it_map); + } + } +#else /* Clear the hardware table in case firmware left allocations in it */ ppc_md.tce_free(tbl, tbl->it_offset, tbl->it_size); +#endif if (!welcomed) { printk(KERN_INFO "IOMMU table initialized, virtual merging %s\n", diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 40d4c14fde8f..b4432332341f 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -29,6 +29,8 @@ * to reduce code space and undefined function references. */ +#undef DEBUG + #include <linux/module.h> #include <linux/threads.h> #include <linux/kernel_stat.h> @@ -38,7 +40,6 @@ #include <linux/ioport.h> #include <linux/interrupt.h> #include <linux/timex.h> -#include <linux/config.h> #include <linux/init.h> #include <linux/slab.h> #include <linux/delay.h> @@ -47,6 +48,10 @@ #include <linux/cpumask.h> #include <linux/profile.h> #include <linux/bitops.h> +#include <linux/list.h> +#include <linux/radix-tree.h> +#include <linux/mutex.h> +#include <linux/bootmem.h> #include <linux/pci.h> #include <asm/uaccess.h> @@ -58,39 +63,38 @@ #include <asm/prom.h> #include <asm/ptrace.h> #include <asm/machdep.h> +#include <asm/udbg.h> #ifdef CONFIG_PPC_ISERIES #include <asm/paca.h> #endif int __irq_offset_value; -#ifdef CONFIG_PPC32 -EXPORT_SYMBOL(__irq_offset_value); -#endif - static int ppc_spurious_interrupts; #ifdef CONFIG_PPC32 -#define NR_MASK_WORDS ((NR_IRQS + 31) / 32) +EXPORT_SYMBOL(__irq_offset_value); +atomic_t ppc_n_lost_interrupts; +#ifndef CONFIG_PPC_MERGE +#define NR_MASK_WORDS ((NR_IRQS + 31) / 32) unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; -atomic_t ppc_n_lost_interrupts; +#endif #ifdef CONFIG_TAU_INT extern int tau_initialized; extern int tau_interrupts(int); #endif +#endif /* CONFIG_PPC32 */ #if defined(CONFIG_SMP) && !defined(CONFIG_PPC_MERGE) extern atomic_t ipi_recv; extern atomic_t ipi_sent; #endif -#endif /* CONFIG_PPC32 */ #ifdef CONFIG_PPC64 EXPORT_SYMBOL(irq_desc); int distribute_irqs = 1; -u64 ppc64_interrupt_controller; #endif /* CONFIG_PPC64 */ int show_interrupts(struct seq_file *p, void *v) @@ -120,8 +124,8 @@ int show_interrupts(struct seq_file *p, void *v) #else seq_printf(p, "%10u ", kstat_irqs(i)); #endif /* CONFIG_SMP */ - if (desc->handler) - seq_printf(p, " %s ", desc->handler->typename); + if (desc->chip) + seq_printf(p, " %s ", desc->chip->typename); else seq_puts(p, " None "); seq_printf(p, "%s", (desc->status & IRQ_LEVEL) ? "Level " : "Edge "); @@ -164,13 +168,13 @@ void fixup_irqs(cpumask_t map) if (irq_desc[irq].status & IRQ_PER_CPU) continue; - cpus_and(mask, irq_affinity[irq], map); + cpus_and(mask, irq_desc[irq].affinity, map); if (any_online_cpu(mask) == NR_CPUS) { printk("Breaking affinity for irq %i\n", irq); mask = map; } - if (irq_desc[irq].handler->set_affinity) - irq_desc[irq].handler->set_affinity(irq, mask); + if (irq_desc[irq].chip->set_affinity) + irq_desc[irq].chip->set_affinity(irq, mask); else if (irq_desc[irq].action && !(warned++)) printk("Cannot set affinity for irq %i\n", irq); } @@ -183,7 +187,7 @@ void fixup_irqs(cpumask_t map) void do_IRQ(struct pt_regs *regs) { - int irq; + unsigned int irq; #ifdef CONFIG_IRQSTACKS struct thread_info *curtp, *irqtp; #endif @@ -214,22 +218,26 @@ void do_IRQ(struct pt_regs *regs) */ irq = ppc_md.get_irq(regs); - if (irq >= 0) { + if (irq != NO_IRQ && irq != NO_IRQ_IGNORE) { #ifdef CONFIG_IRQSTACKS /* Switch to the irq stack to handle this */ curtp = current_thread_info(); irqtp = hardirq_ctx[smp_processor_id()]; if (curtp != irqtp) { + struct irq_desc *desc = irq_desc + irq; + void *handler = desc->handle_irq; + if (handler == NULL) + handler = &__do_IRQ; irqtp->task = curtp->task; irqtp->flags = 0; - call___do_IRQ(irq, regs, irqtp); + call_handle_irq(irq, desc, regs, irqtp, handler); irqtp->task = NULL; if (irqtp->flags) set_bits(irqtp->flags, &curtp->flags); } else #endif - __do_IRQ(irq, regs); - } else if (irq != -2) + generic_handle_irq(irq, regs); + } else if (irq != NO_IRQ_IGNORE) /* That's not SMP safe ... but who cares ? */ ppc_spurious_interrupts++; @@ -246,196 +254,619 @@ void do_IRQ(struct pt_regs *regs) void __init init_IRQ(void) { + ppc_md.init_IRQ(); #ifdef CONFIG_PPC64 - static int once = 0; + irq_ctx_init(); +#endif +} + + +#ifdef CONFIG_IRQSTACKS +struct thread_info *softirq_ctx[NR_CPUS] __read_mostly; +struct thread_info *hardirq_ctx[NR_CPUS] __read_mostly; + +void irq_ctx_init(void) +{ + struct thread_info *tp; + int i; + + for_each_possible_cpu(i) { + memset((void *)softirq_ctx[i], 0, THREAD_SIZE); + tp = softirq_ctx[i]; + tp->cpu = i; + tp->preempt_count = SOFTIRQ_OFFSET; + + memset((void *)hardirq_ctx[i], 0, THREAD_SIZE); + tp = hardirq_ctx[i]; + tp->cpu = i; + tp->preempt_count = HARDIRQ_OFFSET; + } +} + +static inline void do_softirq_onstack(void) +{ + struct thread_info *curtp, *irqtp; + + curtp = current_thread_info(); + irqtp = softirq_ctx[smp_processor_id()]; + irqtp->task = curtp->task; + call_do_softirq(irqtp); + irqtp->task = NULL; +} + +#else +#define do_softirq_onstack() __do_softirq() +#endif /* CONFIG_IRQSTACKS */ - if (once) +void do_softirq(void) +{ + unsigned long flags; + + if (in_interrupt()) return; - once++; + local_irq_save(flags); + + if (local_softirq_pending()) + do_softirq_onstack(); -#endif - ppc_md.init_IRQ(); -#ifdef CONFIG_PPC64 - irq_ctx_init(); -#endif + local_irq_restore(flags); } +EXPORT_SYMBOL(do_softirq); + -#ifdef CONFIG_PPC64 /* - * Virtual IRQ mapping code, used on systems with XICS interrupt controllers. + * IRQ controller and virtual interrupts */ -#define UNDEFINED_IRQ 0xffffffff -unsigned int virt_irq_to_real_map[NR_IRQS]; +#ifdef CONFIG_PPC_MERGE -/* - * Don't use virtual irqs 0, 1, 2 for devices. - * The pcnet32 driver considers interrupt numbers < 2 to be invalid, - * and 2 is the XICS IPI interrupt. - * We limit virtual irqs to __irq_offet_value less than virt_irq_max so - * that when we offset them we don't end up with an interrupt - * number >= virt_irq_max. - */ -#define MIN_VIRT_IRQ 3 +static LIST_HEAD(irq_hosts); +static spinlock_t irq_big_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_PER_CPU(unsigned int, irq_radix_reader); +static unsigned int irq_radix_writer; +struct irq_map_entry irq_map[NR_IRQS]; +static unsigned int irq_virq_count = NR_IRQS; +static struct irq_host *irq_default_host; + +struct irq_host *irq_alloc_host(unsigned int revmap_type, + unsigned int revmap_arg, + struct irq_host_ops *ops, + irq_hw_number_t inval_irq) +{ + struct irq_host *host; + unsigned int size = sizeof(struct irq_host); + unsigned int i; + unsigned int *rmap; + unsigned long flags; + + /* Allocate structure and revmap table if using linear mapping */ + if (revmap_type == IRQ_HOST_MAP_LINEAR) + size += revmap_arg * sizeof(unsigned int); + if (mem_init_done) + host = kzalloc(size, GFP_KERNEL); + else { + host = alloc_bootmem(size); + if (host) + memset(host, 0, size); + } + if (host == NULL) + return NULL; -unsigned int virt_irq_max; -static unsigned int max_virt_irq; -static unsigned int nr_virt_irqs; + /* Fill structure */ + host->revmap_type = revmap_type; + host->inval_irq = inval_irq; + host->ops = ops; -void -virt_irq_init(void) + spin_lock_irqsave(&irq_big_lock, flags); + + /* If it's a legacy controller, check for duplicates and + * mark it as allocated (we use irq 0 host pointer for that + */ + if (revmap_type == IRQ_HOST_MAP_LEGACY) { + if (irq_map[0].host != NULL) { + spin_unlock_irqrestore(&irq_big_lock, flags); + /* If we are early boot, we can't free the structure, + * too bad... + * this will be fixed once slab is made available early + * instead of the current cruft + */ + if (mem_init_done) + kfree(host); + return NULL; + } + irq_map[0].host = host; + } + + list_add(&host->link, &irq_hosts); + spin_unlock_irqrestore(&irq_big_lock, flags); + + /* Additional setups per revmap type */ + switch(revmap_type) { + case IRQ_HOST_MAP_LEGACY: + /* 0 is always the invalid number for legacy */ + host->inval_irq = 0; + /* setup us as the host for all legacy interrupts */ + for (i = 1; i < NUM_ISA_INTERRUPTS; i++) { + irq_map[i].hwirq = 0; + smp_wmb(); + irq_map[i].host = host; + smp_wmb(); + + /* Clear norequest flags */ + get_irq_desc(i)->status &= ~IRQ_NOREQUEST; + + /* Legacy flags are left to default at this point, + * one can then use irq_create_mapping() to + * explicitely change them + */ + ops->map(host, i, i); + } + break; + case IRQ_HOST_MAP_LINEAR: + rmap = (unsigned int *)(host + 1); + for (i = 0; i < revmap_arg; i++) + rmap[i] = IRQ_NONE; + host->revmap_data.linear.size = revmap_arg; + smp_wmb(); + host->revmap_data.linear.revmap = rmap; + break; + default: + break; + } + + pr_debug("irq: Allocated host of type %d @0x%p\n", revmap_type, host); + + return host; +} + +struct irq_host *irq_find_host(struct device_node *node) { - int i; + struct irq_host *h, *found = NULL; + unsigned long flags; - if ((virt_irq_max == 0) || (virt_irq_max > (NR_IRQS - 1))) - virt_irq_max = NR_IRQS - 1; - max_virt_irq = virt_irq_max - __irq_offset_value; - nr_virt_irqs = max_virt_irq - MIN_VIRT_IRQ + 1; + /* We might want to match the legacy controller last since + * it might potentially be set to match all interrupts in + * the absence of a device node. This isn't a problem so far + * yet though... + */ + spin_lock_irqsave(&irq_big_lock, flags); + list_for_each_entry(h, &irq_hosts, link) + if (h->ops->match == NULL || h->ops->match(h, node)) { + found = h; + break; + } + spin_unlock_irqrestore(&irq_big_lock, flags); + return found; +} +EXPORT_SYMBOL_GPL(irq_find_host); - for (i = 0; i < NR_IRQS; i++) - virt_irq_to_real_map[i] = UNDEFINED_IRQ; +void irq_set_default_host(struct irq_host *host) +{ + pr_debug("irq: Default host set to @0x%p\n", host); + + irq_default_host = host; } -/* Create a mapping for a real_irq if it doesn't already exist. - * Return the virtual irq as a convenience. +void irq_set_virq_count(unsigned int count) +{ + pr_debug("irq: Trying to set virq count to %d\n", count); + + BUG_ON(count < NUM_ISA_INTERRUPTS); + if (count < NR_IRQS) + irq_virq_count = count; +} + +/* radix tree not lockless safe ! we use a brlock-type mecanism + * for now, until we can use a lockless radix tree */ -int virt_irq_create_mapping(unsigned int real_irq) +static void irq_radix_wrlock(unsigned long *flags) { - unsigned int virq, first_virq; - static int warned; + unsigned int cpu, ok; - if (ppc64_interrupt_controller == IC_OPEN_PIC) - return real_irq; /* no mapping for openpic (for now) */ + spin_lock_irqsave(&irq_big_lock, *flags); + irq_radix_writer = 1; + smp_mb(); + do { + barrier(); + ok = 1; + for_each_possible_cpu(cpu) { + if (per_cpu(irq_radix_reader, cpu)) { + ok = 0; + break; + } + } + if (!ok) + cpu_relax(); + } while(!ok); +} - if (ppc64_interrupt_controller == IC_CELL_PIC) - return real_irq; /* no mapping for iic either */ +static void irq_radix_wrunlock(unsigned long flags) +{ + smp_wmb(); + irq_radix_writer = 0; + spin_unlock_irqrestore(&irq_big_lock, flags); +} - /* don't map interrupts < MIN_VIRT_IRQ */ - if (real_irq < MIN_VIRT_IRQ) { - virt_irq_to_real_map[real_irq] = real_irq; - return real_irq; +static void irq_radix_rdlock(unsigned long *flags) +{ + local_irq_save(*flags); + __get_cpu_var(irq_radix_reader) = 1; + smp_mb(); + if (likely(irq_radix_writer == 0)) + return; + __get_cpu_var(irq_radix_reader) = 0; + smp_wmb(); + spin_lock(&irq_big_lock); + __get_cpu_var(irq_radix_reader) = 1; + spin_unlock(&irq_big_lock); +} + +static void irq_radix_rdunlock(unsigned long flags) +{ + __get_cpu_var(irq_radix_reader) = 0; + local_irq_restore(flags); +} + + +unsigned int irq_create_mapping(struct irq_host *host, + irq_hw_number_t hwirq) +{ + unsigned int virq, hint; + + pr_debug("irq: irq_create_mapping(0x%p, 0x%lx)\n", host, hwirq); + + /* Look for default host if nececssary */ + if (host == NULL) + host = irq_default_host; + if (host == NULL) { + printk(KERN_WARNING "irq_create_mapping called for" + " NULL host, hwirq=%lx\n", hwirq); + WARN_ON(1); + return NO_IRQ; } + pr_debug("irq: -> using host @%p\n", host); - /* map to a number between MIN_VIRT_IRQ and max_virt_irq */ - virq = real_irq; - if (virq > max_virt_irq) - virq = (virq % nr_virt_irqs) + MIN_VIRT_IRQ; - - /* search for this number or a free slot */ - first_virq = virq; - while (virt_irq_to_real_map[virq] != UNDEFINED_IRQ) { - if (virt_irq_to_real_map[virq] == real_irq) - return virq; - if (++virq > max_virt_irq) - virq = MIN_VIRT_IRQ; - if (virq == first_virq) - goto nospace; /* oops, no free slots */ + /* Check if mapping already exist, if it does, call + * host->ops->map() to update the flags + */ + virq = irq_find_mapping(host, hwirq); + if (virq != IRQ_NONE) { + pr_debug("irq: -> existing mapping on virq %d\n", virq); + return virq; } - virt_irq_to_real_map[virq] = real_irq; + /* Get a virtual interrupt number */ + if (host->revmap_type == IRQ_HOST_MAP_LEGACY) { + /* Handle legacy */ + virq = (unsigned int)hwirq; + if (virq == 0 || virq >= NUM_ISA_INTERRUPTS) + return NO_IRQ; + return virq; + } else { + /* Allocate a virtual interrupt number */ + hint = hwirq % irq_virq_count; + virq = irq_alloc_virt(host, 1, hint); + if (virq == NO_IRQ) { + pr_debug("irq: -> virq allocation failed\n"); + return NO_IRQ; + } + } + pr_debug("irq: -> obtained virq %d\n", virq); + + /* Clear IRQ_NOREQUEST flag */ + get_irq_desc(virq)->status &= ~IRQ_NOREQUEST; + + /* map it */ + smp_wmb(); + irq_map[virq].hwirq = hwirq; + smp_mb(); + if (host->ops->map(host, virq, hwirq)) { + pr_debug("irq: -> mapping failed, freeing\n"); + irq_free_virt(virq, 1); + return NO_IRQ; + } return virq; +} +EXPORT_SYMBOL_GPL(irq_create_mapping); - nospace: - if (!warned) { - printk(KERN_CRIT "Interrupt table is full\n"); - printk(KERN_CRIT "Increase virt_irq_max (currently %d) " - "in your kernel sources and rebuild.\n", virt_irq_max); - warned = 1; +extern unsigned int irq_create_of_mapping(struct device_node *controller, + u32 *intspec, unsigned int intsize) +{ + struct irq_host *host; + irq_hw_number_t hwirq; + unsigned int type = IRQ_TYPE_NONE; + unsigned int virq; + + if (controller == NULL) + host = irq_default_host; + else + host = irq_find_host(controller); + if (host == NULL) { + printk(KERN_WARNING "irq: no irq host found for %s !\n", + controller->full_name); + return NO_IRQ; } - return NO_IRQ; + + /* If host has no translation, then we assume interrupt line */ + if (host->ops->xlate == NULL) + hwirq = intspec[0]; + else { + if (host->ops->xlate(host, controller, intspec, intsize, + &hwirq, &type)) + return NO_IRQ; + } + + /* Create mapping */ + virq = irq_create_mapping(host, hwirq); + if (virq == NO_IRQ) + return virq; + + /* Set type if specified and different than the current one */ + if (type != IRQ_TYPE_NONE && + type != (get_irq_desc(virq)->status & IRQF_TRIGGER_MASK)) + set_irq_type(virq, type); + return virq; } +EXPORT_SYMBOL_GPL(irq_create_of_mapping); -/* - * In most cases will get a hit on the very first slot checked in the - * virt_irq_to_real_map. Only when there are a large number of - * IRQs will this be expensive. - */ -unsigned int real_irq_to_virt_slowpath(unsigned int real_irq) +unsigned int irq_of_parse_and_map(struct device_node *dev, int index) { - unsigned int virq; - unsigned int first_virq; + struct of_irq oirq; - virq = real_irq; + if (of_irq_map_one(dev, index, &oirq)) + return NO_IRQ; - if (virq > max_virt_irq) - virq = (virq % nr_virt_irqs) + MIN_VIRT_IRQ; + return irq_create_of_mapping(oirq.controller, oirq.specifier, + oirq.size); +} +EXPORT_SYMBOL_GPL(irq_of_parse_and_map); - first_virq = virq; +void irq_dispose_mapping(unsigned int virq) +{ + struct irq_host *host = irq_map[virq].host; + irq_hw_number_t hwirq; + unsigned long flags; - do { - if (virt_irq_to_real_map[virq] == real_irq) - return virq; + WARN_ON (host == NULL); + if (host == NULL) + return; - virq++; + /* Never unmap legacy interrupts */ + if (host->revmap_type == IRQ_HOST_MAP_LEGACY) + return; - if (virq >= max_virt_irq) - virq = 0; + /* remove chip and handler */ + set_irq_chip_and_handler(virq, NULL, NULL); + + /* Make sure it's completed */ + synchronize_irq(virq); + + /* Tell the PIC about it */ + if (host->ops->unmap) + host->ops->unmap(host, virq); + smp_mb(); + + /* Clear reverse map */ + hwirq = irq_map[virq].hwirq; + switch(host->revmap_type) { + case IRQ_HOST_MAP_LINEAR: + if (hwirq < host->revmap_data.linear.size) + host->revmap_data.linear.revmap[hwirq] = IRQ_NONE; + break; + case IRQ_HOST_MAP_TREE: + /* Check if radix tree allocated yet */ + if (host->revmap_data.tree.gfp_mask == 0) + break; + irq_radix_wrlock(&flags); + radix_tree_delete(&host->revmap_data.tree, hwirq); + irq_radix_wrunlock(flags); + break; + } - } while (first_virq != virq); + /* Destroy map */ + smp_mb(); + irq_map[virq].hwirq = host->inval_irq; - return NO_IRQ; + /* Set some flags */ + get_irq_desc(virq)->status |= IRQ_NOREQUEST; + /* Free it */ + irq_free_virt(virq, 1); } -#endif /* CONFIG_PPC64 */ +EXPORT_SYMBOL_GPL(irq_dispose_mapping); -#ifdef CONFIG_IRQSTACKS -struct thread_info *softirq_ctx[NR_CPUS] __read_mostly; -struct thread_info *hardirq_ctx[NR_CPUS] __read_mostly; +unsigned int irq_find_mapping(struct irq_host *host, + irq_hw_number_t hwirq) +{ + unsigned int i; + unsigned int hint = hwirq % irq_virq_count; + + /* Look for default host if nececssary */ + if (host == NULL) + host = irq_default_host; + if (host == NULL) + return NO_IRQ; + + /* legacy -> bail early */ + if (host->revmap_type == IRQ_HOST_MAP_LEGACY) + return hwirq; + + /* Slow path does a linear search of the map */ + if (hint < NUM_ISA_INTERRUPTS) + hint = NUM_ISA_INTERRUPTS; + i = hint; + do { + if (irq_map[i].host == host && + irq_map[i].hwirq == hwirq) + return i; + i++; + if (i >= irq_virq_count) + i = NUM_ISA_INTERRUPTS; + } while(i != hint); + return NO_IRQ; +} +EXPORT_SYMBOL_GPL(irq_find_mapping); -void irq_ctx_init(void) + +unsigned int irq_radix_revmap(struct irq_host *host, + irq_hw_number_t hwirq) { - struct thread_info *tp; - int i; + struct radix_tree_root *tree; + struct irq_map_entry *ptr; + unsigned int virq; + unsigned long flags; - for_each_possible_cpu(i) { - memset((void *)softirq_ctx[i], 0, THREAD_SIZE); - tp = softirq_ctx[i]; - tp->cpu = i; - tp->preempt_count = SOFTIRQ_OFFSET; + WARN_ON(host->revmap_type != IRQ_HOST_MAP_TREE); - memset((void *)hardirq_ctx[i], 0, THREAD_SIZE); - tp = hardirq_ctx[i]; - tp->cpu = i; - tp->preempt_count = HARDIRQ_OFFSET; + /* Check if the radix tree exist yet. We test the value of + * the gfp_mask for that. Sneaky but saves another int in the + * structure. If not, we fallback to slow mode + */ + tree = &host->revmap_data.tree; + if (tree->gfp_mask == 0) + return irq_find_mapping(host, hwirq); + + /* Now try to resolve */ + irq_radix_rdlock(&flags); + ptr = radix_tree_lookup(tree, hwirq); + irq_radix_rdunlock(flags); + + /* Found it, return */ + if (ptr) { + virq = ptr - irq_map; + return virq; } + + /* If not there, try to insert it */ + virq = irq_find_mapping(host, hwirq); + if (virq != NO_IRQ) { + irq_radix_wrlock(&flags); + radix_tree_insert(tree, hwirq, &irq_map[virq]); + irq_radix_wrunlock(flags); + } + return virq; } -static inline void do_softirq_onstack(void) +unsigned int irq_linear_revmap(struct irq_host *host, + irq_hw_number_t hwirq) { - struct thread_info *curtp, *irqtp; + unsigned int *revmap; - curtp = current_thread_info(); - irqtp = softirq_ctx[smp_processor_id()]; - irqtp->task = curtp->task; - call_do_softirq(irqtp); - irqtp->task = NULL; + WARN_ON(host->revmap_type != IRQ_HOST_MAP_LINEAR); + + /* Check revmap bounds */ + if (unlikely(hwirq >= host->revmap_data.linear.size)) + return irq_find_mapping(host, hwirq); + + /* Check if revmap was allocated */ + revmap = host->revmap_data.linear.revmap; + if (unlikely(revmap == NULL)) + return irq_find_mapping(host, hwirq); + + /* Fill up revmap with slow path if no mapping found */ + if (unlikely(revmap[hwirq] == NO_IRQ)) + revmap[hwirq] = irq_find_mapping(host, hwirq); + + return revmap[hwirq]; } -#else -#define do_softirq_onstack() __do_softirq() -#endif /* CONFIG_IRQSTACKS */ +unsigned int irq_alloc_virt(struct irq_host *host, + unsigned int count, + unsigned int hint) +{ + unsigned long flags; + unsigned int i, j, found = NO_IRQ; + unsigned int limit = irq_virq_count - count; -void do_softirq(void) + if (count == 0 || count > (irq_virq_count - NUM_ISA_INTERRUPTS)) + return NO_IRQ; + + spin_lock_irqsave(&irq_big_lock, flags); + + /* Use hint for 1 interrupt if any */ + if (count == 1 && hint >= NUM_ISA_INTERRUPTS && + hint < irq_virq_count && irq_map[hint].host == NULL) { + found = hint; + goto hint_found; + } + + /* Look for count consecutive numbers in the allocatable + * (non-legacy) space + */ + for (i = NUM_ISA_INTERRUPTS; i <= limit; ) { + for (j = i; j < (i + count); j++) + if (irq_map[j].host != NULL) { + i = j + 1; + continue; + } + found = i; + break; + } + if (found == NO_IRQ) { + spin_unlock_irqrestore(&irq_big_lock, flags); + return NO_IRQ; + } + hint_found: + for (i = found; i < (found + count); i++) { + irq_map[i].hwirq = host->inval_irq; + smp_wmb(); + irq_map[i].host = host; + } + spin_unlock_irqrestore(&irq_big_lock, flags); + return found; +} + +void irq_free_virt(unsigned int virq, unsigned int count) { unsigned long flags; + unsigned int i; - if (in_interrupt()) - return; + WARN_ON (virq < NUM_ISA_INTERRUPTS); + WARN_ON (count == 0 || (virq + count) > irq_virq_count); - local_irq_save(flags); + spin_lock_irqsave(&irq_big_lock, flags); + for (i = virq; i < (virq + count); i++) { + struct irq_host *host; - if (local_softirq_pending()) { - account_system_vtime(current); - local_bh_disable(); - do_softirq_onstack(); - account_system_vtime(current); - __local_bh_enable(); + if (i < NUM_ISA_INTERRUPTS || + (virq + count) > irq_virq_count) + continue; + + host = irq_map[i].host; + irq_map[i].hwirq = host->inval_irq; + smp_wmb(); + irq_map[i].host = NULL; } + spin_unlock_irqrestore(&irq_big_lock, flags); +} - local_irq_restore(flags); +void irq_early_init(void) +{ + unsigned int i; + + for (i = 0; i < NR_IRQS; i++) + get_irq_desc(i)->status |= IRQ_NOREQUEST; } -EXPORT_SYMBOL(do_softirq); + +/* We need to create the radix trees late */ +static int irq_late_init(void) +{ + struct irq_host *h; + unsigned long flags; + + irq_radix_wrlock(&flags); + list_for_each_entry(h, &irq_hosts, link) { + if (h->revmap_type == IRQ_HOST_MAP_TREE) + INIT_RADIX_TREE(&h->revmap_data.tree, GFP_ATOMIC); + } + irq_radix_wrunlock(flags); + + return 0; +} +arch_initcall(irq_late_init); + +#endif /* CONFIG_PPC_MERGE */ #ifdef CONFIG_PCI_MSI int pci_enable_msi(struct pci_dev * pdev) @@ -445,12 +876,14 @@ int pci_enable_msi(struct pci_dev * pdev) else return -1; } +EXPORT_SYMBOL(pci_enable_msi); void pci_disable_msi(struct pci_dev * pdev) { if (ppc_md.disable_msi) ppc_md.disable_msi(pdev); } +EXPORT_SYMBOL(pci_disable_msi); void pci_scan_msi_device(struct pci_dev *dev) {} int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) {return -1;} @@ -458,6 +891,8 @@ void pci_disable_msix(struct pci_dev *dev) {} void msi_remove_pci_irq_vectors(struct pci_dev *dev) {} void disable_msi_mode(struct pci_dev *dev, int pos, int type) {} void pci_no_msi(void) {} +EXPORT_SYMBOL(pci_enable_msix); +EXPORT_SYMBOL(pci_disable_msix); #endif diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c index f78866367b70..cd65c367b8b6 100644 --- a/arch/powerpc/kernel/kprobes.c +++ b/arch/powerpc/kernel/kprobes.c @@ -26,7 +26,6 @@ * for PPC64 */ -#include <linux/config.h> #include <linux/kprobes.h> #include <linux/ptrace.h> #include <linux/preempt.h> @@ -62,6 +61,8 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) if (!ret) { memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); p->opcode = *p->addr; + flush_icache_range((unsigned long)p->ainsn.insn, + (unsigned long)p->ainsn.insn + sizeof(kprobe_opcode_t)); } return ret; diff --git a/arch/powerpc/kernel/l2cr_6xx.S b/arch/powerpc/kernel/l2cr_6xx.S index d7f4e982b539..858f28ac8a06 100644 --- a/arch/powerpc/kernel/l2cr_6xx.S +++ b/arch/powerpc/kernel/l2cr_6xx.S @@ -40,7 +40,6 @@ Author: Terry Greeniaus (tgree@phys.ualberta.ca) Please e-mail updates to this file to me, thanks! */ -#include <linux/config.h> #include <asm/processor.h> #include <asm/cputable.h> #include <asm/ppc_asm.h> diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c index 6e67b5b49ba1..5e6ddfa474c0 100644 --- a/arch/powerpc/kernel/legacy_serial.c +++ b/arch/powerpc/kernel/legacy_serial.c @@ -1,4 +1,3 @@ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/serial.h> #include <linux/serial_8250.h> @@ -29,6 +28,7 @@ static struct legacy_serial_info { struct device_node *np; unsigned int speed; unsigned int clock; + int irq_check_parent; phys_addr_t taddr; } legacy_serial_infos[MAX_LEGACY_SERIAL_PORTS]; static unsigned int legacy_serial_count; @@ -37,18 +37,19 @@ static int legacy_serial_console = -1; static int __init add_legacy_port(struct device_node *np, int want_index, int iotype, phys_addr_t base, phys_addr_t taddr, unsigned long irq, - upf_t flags) + upf_t flags, int irq_check_parent) { - u32 *clk, *spd, clock = BASE_BAUD * 16; + const u32 *clk, *spd; + u32 clock = BASE_BAUD * 16; int index; /* get clock freq. if present */ - clk = (u32 *)get_property(np, "clock-frequency", NULL); + clk = get_property(np, "clock-frequency", NULL); if (clk && *clk) clock = *clk; /* get default speed if present */ - spd = (u32 *)get_property(np, "current-speed", NULL); + spd = get_property(np, "current-speed", NULL); /* If we have a location index, then try to use it */ if (want_index >= 0 && want_index < MAX_LEGACY_SERIAL_PORTS) @@ -69,7 +70,7 @@ static int __init add_legacy_port(struct device_node *np, int want_index, if (legacy_serial_infos[index].np != 0) { /* if we still have some room, move it, else override */ if (legacy_serial_count < MAX_LEGACY_SERIAL_PORTS) { - printk(KERN_INFO "Moved legacy port %d -> %d\n", + printk(KERN_DEBUG "Moved legacy port %d -> %d\n", index, legacy_serial_count); legacy_serial_ports[legacy_serial_count] = legacy_serial_ports[index]; @@ -77,7 +78,7 @@ static int __init add_legacy_port(struct device_node *np, int want_index, legacy_serial_infos[index]; legacy_serial_count++; } else { - printk(KERN_INFO "Replacing legacy port %d\n", index); + printk(KERN_DEBUG "Replacing legacy port %d\n", index); } } @@ -96,10 +97,11 @@ static int __init add_legacy_port(struct device_node *np, int want_index, legacy_serial_infos[index].np = of_node_get(np); legacy_serial_infos[index].clock = clock; legacy_serial_infos[index].speed = spd ? *spd : 0; + legacy_serial_infos[index].irq_check_parent = irq_check_parent; - printk(KERN_INFO "Found legacy serial port %d for %s\n", + printk(KERN_DEBUG "Found legacy serial port %d for %s\n", index, np->full_name); - printk(KERN_INFO " %s=%llx, taddr=%llx, irq=%lx, clk=%d, speed=%d\n", + printk(KERN_DEBUG " %s=%llx, taddr=%llx, irq=%lx, clk=%d, speed=%d\n", (iotype == UPIO_PORT) ? "port" : "mem", (unsigned long long)base, (unsigned long long)taddr, irq, legacy_serial_ports[index].uartclk, @@ -111,9 +113,10 @@ static int __init add_legacy_port(struct device_node *np, int want_index, static int __init add_legacy_soc_port(struct device_node *np, struct device_node *soc_dev) { - phys_addr_t addr; - u32 *addrp; + u64 addr; + const u32 *addrp; upf_t flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ; + struct device_node *tsi = of_get_parent(np); /* We only support ports that have a clock frequency properly * encoded in the device-tree. @@ -127,23 +130,30 @@ static int __init add_legacy_soc_port(struct device_node *np, return -1; addr = of_translate_address(soc_dev, addrp); + if (addr == OF_BAD_ADDR) + return -1; /* Add port, irq will be dealt with later. We passed a translated * IO port value. It will be fixed up later along with the irq */ - return add_legacy_port(np, -1, UPIO_MEM, addr, addr, NO_IRQ, flags); + if (tsi && !strcmp(tsi->type, "tsi-bridge")) + return add_legacy_port(np, -1, UPIO_TSI, addr, addr, NO_IRQ, flags, 0); + else + return add_legacy_port(np, -1, UPIO_MEM, addr, addr, NO_IRQ, flags, 0); } static int __init add_legacy_isa_port(struct device_node *np, struct device_node *isa_brg) { - u32 *reg; - char *typep; + const u32 *reg; + const char *typep; int index = -1; - phys_addr_t taddr; + u64 taddr; + + DBG(" -> add_legacy_isa_port(%s)\n", np->full_name); /* Get the ISA port number */ - reg = (u32 *)get_property(np, "reg", NULL); + reg = get_property(np, "reg", NULL); if (reg == NULL) return -1; @@ -154,17 +164,23 @@ static int __init add_legacy_isa_port(struct device_node *np, /* Now look for an "ibm,aix-loc" property that gives us ordering * if any... */ - typep = (char *)get_property(np, "ibm,aix-loc", NULL); + typep = get_property(np, "ibm,aix-loc", NULL); /* If we have a location index, then use it */ if (typep && *typep == 'S') index = simple_strtol(typep+1, NULL, 0) - 1; - /* Translate ISA address */ + /* Translate ISA address. If it fails, we still register the port + * with no translated address so that it can be picked up as an IO + * port later by the serial driver + */ taddr = of_translate_address(np, reg); + if (taddr == OF_BAD_ADDR) + taddr = 0; /* Add port, irq will be dealt with later */ - return add_legacy_port(np, index, UPIO_PORT, reg[1], taddr, NO_IRQ, UPF_BOOT_AUTOCONF); + return add_legacy_port(np, index, UPIO_PORT, reg[1], taddr, + NO_IRQ, UPF_BOOT_AUTOCONF, 0); } @@ -172,11 +188,13 @@ static int __init add_legacy_isa_port(struct device_node *np, static int __init add_legacy_pci_port(struct device_node *np, struct device_node *pci_dev) { - phys_addr_t addr, base; - u32 *addrp; + u64 addr, base; + const u32 *addrp; unsigned int flags; int iotype, index = -1, lindex = 0; + DBG(" -> add_legacy_pci_port(%s)\n", np->full_name); + /* We only support ports that have a clock frequency properly * encoded in the device-tree (that is have an fcode). Anything * else can't be used that early and will be normally probed by @@ -195,6 +213,8 @@ static int __init add_legacy_pci_port(struct device_node *np, /* We only support BAR 0 for now */ iotype = (flags & IORESOURCE_MEM) ? UPIO_MEM : UPIO_PORT; addr = of_translate_address(pci_dev, addrp); + if (addr == OF_BAD_ADDR) + return -1; /* Set the IO base to the same as the translated address for MMIO, * or to the domain local IO base for PIO (it will be fixed up later) @@ -208,7 +228,7 @@ static int __init add_legacy_pci_port(struct device_node *np, * we get to their "reg" property */ if (np != pci_dev) { - u32 *reg = (u32 *)get_property(np, "reg", NULL); + const u32 *reg = get_property(np, "reg", NULL); if (reg && (*reg < 4)) index = lindex = *reg; } @@ -232,7 +252,8 @@ static int __init add_legacy_pci_port(struct device_node *np, /* Add port, irq will be dealt with later. We passed a translated * IO port value. It will be fixed up later along with the irq */ - return add_legacy_port(np, index, iotype, base, addr, NO_IRQ, UPF_BOOT_AUTOCONF); + return add_legacy_port(np, index, iotype, base, addr, NO_IRQ, + UPF_BOOT_AUTOCONF, np != pci_dev); } #endif @@ -265,13 +286,13 @@ static void __init setup_legacy_serial_console(int console) void __init find_legacy_serial_ports(void) { struct device_node *np, *stdout = NULL; - char *path; + const char *path; int index; DBG(" -> find_legacy_serial_port()\n"); /* Now find out if one of these is out firmware console */ - path = (char *)get_property(of_chosen, "linux,stdout-path", NULL); + path = get_property(of_chosen, "linux,stdout-path", NULL); if (path != NULL) { stdout = of_find_node_by_path(path); if (stdout) @@ -302,6 +323,17 @@ void __init find_legacy_serial_ports(void) of_node_put(isa); } + /* First fill our array with tsi-bridge ports */ + for (np = NULL; (np = of_find_compatible_node(np, "serial", "ns16550")) != NULL;) { + struct device_node *tsi = of_get_parent(np); + if (tsi && !strcmp(tsi->type, "tsi-bridge")) { + index = add_legacy_soc_port(np, np); + if (index >= 0 && np == stdout) + legacy_serial_console = index; + } + of_node_put(tsi); + } + #ifdef CONFIG_PCI /* Next, try to locate PCI ports */ for (np = NULL; (np = of_find_all_nodes(np));) { @@ -352,27 +384,22 @@ static void __init fixup_port_irq(int index, struct device_node *np, struct plat_serial8250_port *port) { + unsigned int virq; + DBG("fixup_port_irq(%d)\n", index); - /* Check for interrupts in that node */ - if (np->n_intrs > 0) { - port->irq = np->intrs[0].line; - DBG(" port %d (%s), irq=%d\n", - index, np->full_name, port->irq); - return; + virq = irq_of_parse_and_map(np, 0); + if (virq == NO_IRQ && legacy_serial_infos[index].irq_check_parent) { + np = of_get_parent(np); + if (np == NULL) + return; + virq = irq_of_parse_and_map(np, 0); + of_node_put(np); } - - /* Check for interrupts in the parent */ - np = of_get_parent(np); - if (np == NULL) + if (virq == NO_IRQ) return; - if (np->n_intrs > 0) { - port->irq = np->intrs[0].line; - DBG(" port %d (%s), irq=%d\n", - index, np->full_name, port->irq); - } - of_node_put(np); + port->irq = virq; } static void __init fixup_port_pio(int index, @@ -442,7 +469,7 @@ static int __init serial_dev_init(void) fixup_port_irq(i, np, port); if (port->iotype == UPIO_PORT) fixup_port_pio(i, np, port); - if (port->iotype == UPIO_MEM) + if ((port->iotype == UPIO_MEM) || (port->iotype == UPIO_TSI)) fixup_port_mmio(i, np, port); } @@ -465,8 +492,8 @@ static int __init check_legacy_serial_console(void) { struct device_node *prom_stdout = NULL; int speed = 0, offset = 0; - char *name; - u32 *spd; + const char *name; + const u32 *spd; DBG(" -> check_legacy_serial_console()\n"); @@ -487,7 +514,7 @@ static int __init check_legacy_serial_console(void) } /* We are getting a weird phandle from OF ... */ /* ... So use the full path instead */ - name = (char *)get_property(of_chosen, "linux,stdout-path", NULL); + name = get_property(of_chosen, "linux,stdout-path", NULL); if (name == NULL) { DBG(" no linux,stdout-path !\n"); return -ENODEV; @@ -499,12 +526,12 @@ static int __init check_legacy_serial_console(void) } DBG("stdout is %s\n", prom_stdout->full_name); - name = (char *)get_property(prom_stdout, "name", NULL); + name = get_property(prom_stdout, "name", NULL); if (!name) { DBG(" stdout package has no name !\n"); goto not_found; } - spd = (u32 *)get_property(prom_stdout, "current-speed", NULL); + spd = get_property(prom_stdout, "current-speed", NULL); if (spd) speed = *spd; diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c index c02deaab26c7..41c05dcd68f4 100644 --- a/arch/powerpc/kernel/lparcfg.c +++ b/arch/powerpc/kernel/lparcfg.c @@ -18,7 +18,6 @@ * keyword - value pairs that specify the configuration of the partition. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/types.h> #include <linux/errno.h> @@ -33,7 +32,6 @@ #include <asm/rtas.h> #include <asm/system.h> #include <asm/time.h> -#include <asm/iseries/it_exp_vpd_panel.h> #include <asm/prom.h> #include <asm/vdso_datapage.h> @@ -45,11 +43,9 @@ static struct proc_dir_entry *proc_ppc64_lparcfg; #define LPARCFG_BUFF_SIZE 4096 -#ifdef CONFIG_PPC_ISERIES - /* - * For iSeries legacy systems, the PPA purr function is available from the - * emulated_time_base field in the paca. + * Track sum of all purrs across all processors. This is used to further + * calculate usage values by different applications */ static unsigned long get_purr(void) { @@ -57,48 +53,31 @@ static unsigned long get_purr(void) int cpu; for_each_possible_cpu(cpu) { - sum_purr += lppaca[cpu].emulated_time_base; + if (firmware_has_feature(FW_FEATURE_ISERIES)) + sum_purr += lppaca[cpu].emulated_time_base; + else { + struct cpu_usage *cu; -#ifdef PURR_DEBUG - printk(KERN_INFO "get_purr for cpu (%d) has value (%ld) \n", - cpu, lppaca[cpu].emulated_time_base); -#endif + cu = &per_cpu(cpu_usage_array, cpu); + sum_purr += cu->current_tb; + } } return sum_purr; } -#define lparcfg_write NULL +#ifdef CONFIG_PPC_ISERIES /* * Methods used to fetch LPAR data when running on an iSeries platform. */ -static int lparcfg_data(struct seq_file *m, void *v) +static int iseries_lparcfg_data(struct seq_file *m, void *v) { - unsigned long pool_id, lp_index; + unsigned long pool_id; int shared, entitled_capacity, max_entitled_capacity; int processors, max_processors; unsigned long purr = get_purr(); - seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS); - shared = (int)(get_lppaca()->shared_proc); - seq_printf(m, "serial_number=%c%c%c%c%c%c%c\n", - e2a(xItExtVpdPanel.mfgID[2]), - e2a(xItExtVpdPanel.mfgID[3]), - e2a(xItExtVpdPanel.systemSerial[1]), - e2a(xItExtVpdPanel.systemSerial[2]), - e2a(xItExtVpdPanel.systemSerial[3]), - e2a(xItExtVpdPanel.systemSerial[4]), - e2a(xItExtVpdPanel.systemSerial[5])); - - seq_printf(m, "system_type=%c%c%c%c\n", - e2a(xItExtVpdPanel.machineType[0]), - e2a(xItExtVpdPanel.machineType[1]), - e2a(xItExtVpdPanel.machineType[2]), - e2a(xItExtVpdPanel.machineType[3])); - - lp_index = HvLpConfig_getLpIndex(); - seq_printf(m, "partition_id=%d\n", (int)lp_index); seq_printf(m, "system_active_processors=%d\n", (int)HvLpConfig_getSystemPhysicalProcessors()); @@ -137,6 +116,14 @@ static int lparcfg_data(struct seq_file *m, void *v) return 0; } + +#else /* CONFIG_PPC_ISERIES */ + +static int iseries_lparcfg_data(struct seq_file *m, void *v) +{ + return 0; +} + #endif /* CONFIG_PPC_ISERIES */ #ifdef CONFIG_PPC_PSERIES @@ -195,8 +182,14 @@ static unsigned int h_get_ppp(unsigned long *entitled, unsigned long *resource) { unsigned long rc; - rc = plpar_hcall_4out(H_GET_PPP, 0, 0, 0, 0, entitled, unallocated, - aggregation, resource); + unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; + + rc = plpar_hcall(H_GET_PPP, retbuf); + + *entitled = retbuf[0]; + *unallocated = retbuf[1]; + *aggregation = retbuf[2]; + *resource = retbuf[3]; log_plpar_hcall_return(rc, "H_GET_PPP"); @@ -206,27 +199,15 @@ static unsigned int h_get_ppp(unsigned long *entitled, static void h_pic(unsigned long *pool_idle_time, unsigned long *num_procs) { unsigned long rc; - unsigned long dummy; - rc = plpar_hcall(H_PIC, 0, 0, 0, 0, pool_idle_time, num_procs, &dummy); + unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; - if (rc != H_AUTHORITY) - log_plpar_hcall_return(rc, "H_PIC"); -} + rc = plpar_hcall(H_PIC, retbuf); -/* Track sum of all purrs across all processors. This is used to further */ -/* calculate usage values by different applications */ + *pool_idle_time = retbuf[0]; + *num_procs = retbuf[1]; -static unsigned long get_purr(void) -{ - unsigned long sum_purr = 0; - int cpu; - struct cpu_usage *cu; - - for_each_possible_cpu(cpu) { - cu = &per_cpu(cpu_usage_array, cpu); - sum_purr += cu->current_tb; - } - return sum_purr; + if (rc != H_AUTHORITY) + log_plpar_hcall_return(rc, "H_PIC"); } #define SPLPAR_CHARACTERISTICS_TOKEN 20 @@ -333,39 +314,16 @@ static int lparcfg_count_active_processors(void) return count; } -static int lparcfg_data(struct seq_file *m, void *v) +static int pseries_lparcfg_data(struct seq_file *m, void *v) { int partition_potential_processors; int partition_active_processors; - struct device_node *rootdn; - const char *model = ""; - const char *system_id = ""; - unsigned int *lp_index_ptr, lp_index = 0; struct device_node *rtas_node; - int *lrdrp = NULL; - - rootdn = find_path_device("/"); - if (rootdn) { - model = get_property(rootdn, "model", NULL); - system_id = get_property(rootdn, "system-id", NULL); - lp_index_ptr = (unsigned int *) - get_property(rootdn, "ibm,partition-no", NULL); - if (lp_index_ptr) - lp_index = *lp_index_ptr; - } - - seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS); - - seq_printf(m, "serial_number=%s\n", system_id); - - seq_printf(m, "system_type=%s\n", model); - - seq_printf(m, "partition_id=%d\n", (int)lp_index); + const int *lrdrp = NULL; rtas_node = find_path_device("/rtas"); if (rtas_node) - lrdrp = (int *)get_property(rtas_node, "ibm,lrdr-capacity", - NULL); + lrdrp = get_property(rtas_node, "ibm,lrdr-capacity", NULL); if (lrdrp == NULL) { partition_potential_processors = vdso_data->processorCount; @@ -549,8 +507,61 @@ out: return retval; } +#else /* CONFIG_PPC_PSERIES */ + +static int pseries_lparcfg_data(struct seq_file *m, void *v) +{ + return 0; +} + +static ssize_t lparcfg_write(struct file *file, const char __user * buf, + size_t count, loff_t * off) +{ + return count; +} + #endif /* CONFIG_PPC_PSERIES */ +static int lparcfg_data(struct seq_file *m, void *v) +{ + struct device_node *rootdn; + const char *model = ""; + const char *system_id = ""; + const char *tmp; + const unsigned int *lp_index_ptr; + unsigned int lp_index = 0; + + seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS); + + rootdn = find_path_device("/"); + if (rootdn) { + tmp = get_property(rootdn, "model", NULL); + if (tmp) { + model = tmp; + /* Skip "IBM," - see platforms/iseries/dt.c */ + if (firmware_has_feature(FW_FEATURE_ISERIES)) + model += 4; + } + tmp = get_property(rootdn, "system-id", NULL); + if (tmp) { + system_id = tmp; + /* Skip "IBM," - see platforms/iseries/dt.c */ + if (firmware_has_feature(FW_FEATURE_ISERIES)) + system_id += 4; + } + lp_index_ptr = get_property(rootdn, "ibm,partition-no", NULL); + if (lp_index_ptr) + lp_index = *lp_index_ptr; + } + seq_printf(m, "serial_number=%s\n", system_id); + seq_printf(m, "system_type=%s\n", model); + seq_printf(m, "partition_id=%d\n", (int)lp_index); + + if (firmware_has_feature(FW_FEATURE_ISERIES)) + return iseries_lparcfg_data(m, v); + return pseries_lparcfg_data(m, v); +} + static int lparcfg_open(struct inode *inode, struct file *file) { return single_open(file, lparcfg_data, NULL); @@ -569,7 +580,8 @@ int __init lparcfg_init(void) mode_t mode = S_IRUSR | S_IRGRP | S_IROTH; /* Allow writing if we have FW_FEATURE_SPLPAR */ - if (firmware_has_feature(FW_FEATURE_SPLPAR)) { + if (firmware_has_feature(FW_FEATURE_SPLPAR) && + !firmware_has_feature(FW_FEATURE_ISERIES)) { lparcfg_fops.write = lparcfg_write; mode |= S_IWUSR; } diff --git a/arch/powerpc/kernel/machine_kexec.c b/arch/powerpc/kernel/machine_kexec.c index a81ca1b841ec..e60a0c544d63 100644 --- a/arch/powerpc/kernel/machine_kexec.c +++ b/arch/powerpc/kernel/machine_kexec.c @@ -13,6 +13,7 @@ #include <linux/reboot.h> #include <linux/threads.h> #include <asm/machdep.h> +#include <asm/lmb.h> void machine_crash_shutdown(struct pt_regs *regs) { @@ -59,3 +60,58 @@ NORET_TYPE void machine_kexec(struct kimage *image) } for(;;); } + +static int __init early_parse_crashk(char *p) +{ + unsigned long size; + + if (!p) + return 1; + + size = memparse(p, &p); + + if (*p == '@') + crashk_res.start = memparse(p + 1, &p); + else + crashk_res.start = KDUMP_KERNELBASE; + + crashk_res.end = crashk_res.start + size - 1; + + return 0; +} +early_param("crashkernel", early_parse_crashk); + +void __init reserve_crashkernel(void) +{ + unsigned long size; + + if (crashk_res.start == 0) + return; + + /* We might have got these values via the command line or the + * device tree, either way sanitise them now. */ + + size = crashk_res.end - crashk_res.start + 1; + + if (crashk_res.start != KDUMP_KERNELBASE) + printk("Crash kernel location must be 0x%x\n", + KDUMP_KERNELBASE); + + crashk_res.start = KDUMP_KERNELBASE; + size = PAGE_ALIGN(size); + crashk_res.end = crashk_res.start + size - 1; + + /* Crash kernel trumps memory limit */ + if (memory_limit && memory_limit <= crashk_res.end) { + memory_limit = crashk_res.end + 1; + printk("Adjusted memory limit for crashkernel, now 0x%lx\n", + memory_limit); + } + + lmb_reserve(crashk_res.start, size); +} + +int overlaps_crashkernel(unsigned long start, unsigned long size) +{ + return (start + size) > crashk_res.start && start <= crashk_res.end; +} diff --git a/arch/powerpc/kernel/machine_kexec_32.c b/arch/powerpc/kernel/machine_kexec_32.c index 443606134dff..cbaa34196797 100644 --- a/arch/powerpc/kernel/machine_kexec_32.c +++ b/arch/powerpc/kernel/machine_kexec_32.c @@ -30,8 +30,8 @@ typedef NORET_TYPE void (*relocate_new_kernel_t)( */ void default_machine_kexec(struct kimage *image) { - const extern unsigned char relocate_new_kernel[]; - const extern unsigned int relocate_new_kernel_size; + extern const unsigned char relocate_new_kernel[]; + extern const unsigned int relocate_new_kernel_size; unsigned long page_list; unsigned long reboot_code_buffer, reboot_code_buffer_phys; relocate_new_kernel_t rnk; diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c index a8fa04ef27cd..a24b09c27718 100644 --- a/arch/powerpc/kernel/machine_kexec_64.c +++ b/arch/powerpc/kernel/machine_kexec_64.c @@ -10,7 +10,6 @@ */ -#include <linux/cpumask.h> #include <linux/kexec.h> #include <linux/smp.h> #include <linux/thread_info.h> @@ -21,7 +20,6 @@ #include <asm/machdep.h> #include <asm/cacheflush.h> #include <asm/paca.h> -#include <asm/lmb.h> #include <asm/mmu.h> #include <asm/sections.h> /* _end */ #include <asm/prom.h> @@ -33,8 +31,8 @@ int default_machine_kexec_prepare(struct kimage *image) unsigned long begin, end; /* limits of segment */ unsigned long low, high; /* limits of blocked memory range */ struct device_node *node; - unsigned long *basep; - unsigned int *sizep; + const unsigned long *basep; + const unsigned int *sizep; if (!ppc_md.hpte_clear_all) return -ENOENT; @@ -74,10 +72,8 @@ int default_machine_kexec_prepare(struct kimage *image) /* We also should not overwrite the tce tables */ for (node = of_find_node_by_type(NULL, "pci"); node != NULL; node = of_find_node_by_type(node, "pci")) { - basep = (unsigned long *)get_property(node, "linux,tce-base", - NULL); - sizep = (unsigned int *)get_property(node, "linux,tce-size", - NULL); + basep = get_property(node, "linux,tce-base", NULL); + sizep = get_property(node, "linux,tce-size", NULL); if (basep == NULL || sizep == NULL) continue; @@ -378,63 +374,10 @@ static void __init export_crashk_values(void) of_node_put(node); } -void __init kexec_setup(void) +static int __init kexec_setup(void) { export_htab_values(); export_crashk_values(); -} - -static int __init early_parse_crashk(char *p) -{ - unsigned long size; - - if (!p) - return 1; - - size = memparse(p, &p); - - if (*p == '@') - crashk_res.start = memparse(p + 1, &p); - else - crashk_res.start = KDUMP_KERNELBASE; - - crashk_res.end = crashk_res.start + size - 1; - return 0; } -early_param("crashkernel", early_parse_crashk); - -void __init reserve_crashkernel(void) -{ - unsigned long size; - - if (crashk_res.start == 0) - return; - - /* We might have got these values via the command line or the - * device tree, either way sanitise them now. */ - - size = crashk_res.end - crashk_res.start + 1; - - if (crashk_res.start != KDUMP_KERNELBASE) - printk("Crash kernel location must be 0x%x\n", - KDUMP_KERNELBASE); - - crashk_res.start = KDUMP_KERNELBASE; - size = PAGE_ALIGN(size); - crashk_res.end = crashk_res.start + size - 1; - - /* Crash kernel trumps memory limit */ - if (memory_limit && memory_limit <= crashk_res.end) { - memory_limit = crashk_res.end + 1; - printk("Adjusted memory limit for crashkernel, now 0x%lx\n", - memory_limit); - } - - lmb_reserve(crashk_res.start, size); -} - -int overlaps_crashkernel(unsigned long start, unsigned long size) -{ - return (start + size) > crashk_res.start && start <= crashk_res.end; -} +__initcall(kexec_setup); diff --git a/arch/powerpc/kernel/misc.S b/arch/powerpc/kernel/misc.S new file mode 100644 index 000000000000..330c9dc7db86 --- /dev/null +++ b/arch/powerpc/kernel/misc.S @@ -0,0 +1,45 @@ +/* + * This file contains miscellaneous low-level functions. + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * + * Largely rewritten by Cort Dougan (cort@cs.nmt.edu) + * and Paul Mackerras. + * + * Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com) + * PPC64 updates by Dave Engebretsen (engebret@us.ibm.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include <asm/ppc_asm.h> + + .text + +/* + * Returns (address we are running at) - (address we were linked at) + * for use before the text and data are mapped to KERNELBASE. + */ + +_GLOBAL(reloc_offset) + mflr r0 + bl 1f +1: mflr r3 + LOAD_REG_IMMEDIATE(r4,1b) + subf r3,r4,r3 + mtlr r0 + blr + +/* + * add_reloc_offset(x) returns x + reloc_offset(). + */ +_GLOBAL(add_reloc_offset) + mflr r0 + bl 1f +1: mflr r5 + LOAD_REG_IMMEDIATE(r4,1b) + subf r5,r4,r5 + add r3,r3,r5 + mtlr r0 + blr diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index 01d3916c4cb1..58758d883361 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S @@ -16,7 +16,6 @@ * */ -#include <linux/config.h> #include <linux/sys.h> #include <asm/unistd.h> #include <asm/errno.h> @@ -61,32 +60,6 @@ _GLOBAL(mulhdu) blr /* - * Returns (address we're running at) - (address we were linked at) - * for use before the text and data are mapped to KERNELBASE. - */ -_GLOBAL(reloc_offset) - mflr r0 - bl 1f -1: mflr r3 - LOAD_REG_IMMEDIATE(r4,1b) - subf r3,r4,r3 - mtlr r0 - blr - -/* - * add_reloc_offset(x) returns x + reloc_offset(). - */ -_GLOBAL(add_reloc_offset) - mflr r0 - bl 1f -1: mflr r5 - LOAD_REG_IMMEDIATE(r4,1b) - subf r5,r4,r5 - add r3,r3,r5 - mtlr r0 - blr - -/* * sub_reloc_offset(x) returns x - reloc_offset(). */ _GLOBAL(sub_reloc_offset) @@ -781,136 +754,6 @@ _GLOBAL(atomic_set_mask) blr /* - * I/O string operations - * - * insb(port, buf, len) - * outsb(port, buf, len) - * insw(port, buf, len) - * outsw(port, buf, len) - * insl(port, buf, len) - * outsl(port, buf, len) - * insw_ns(port, buf, len) - * outsw_ns(port, buf, len) - * insl_ns(port, buf, len) - * outsl_ns(port, buf, len) - * - * The *_ns versions don't do byte-swapping. - */ -_GLOBAL(_insb) - cmpwi 0,r5,0 - mtctr r5 - subi r4,r4,1 - blelr- -00: lbz r5,0(r3) - eieio - stbu r5,1(r4) - bdnz 00b - blr - -_GLOBAL(_outsb) - cmpwi 0,r5,0 - mtctr r5 - subi r4,r4,1 - blelr- -00: lbzu r5,1(r4) - stb r5,0(r3) - eieio - bdnz 00b - blr - -_GLOBAL(_insw) - cmpwi 0,r5,0 - mtctr r5 - subi r4,r4,2 - blelr- -00: lhbrx r5,0,r3 - eieio - sthu r5,2(r4) - bdnz 00b - blr - -_GLOBAL(_outsw) - cmpwi 0,r5,0 - mtctr r5 - subi r4,r4,2 - blelr- -00: lhzu r5,2(r4) - eieio - sthbrx r5,0,r3 - bdnz 00b - blr - -_GLOBAL(_insl) - cmpwi 0,r5,0 - mtctr r5 - subi r4,r4,4 - blelr- -00: lwbrx r5,0,r3 - eieio - stwu r5,4(r4) - bdnz 00b - blr - -_GLOBAL(_outsl) - cmpwi 0,r5,0 - mtctr r5 - subi r4,r4,4 - blelr- -00: lwzu r5,4(r4) - stwbrx r5,0,r3 - eieio - bdnz 00b - blr - -_GLOBAL(__ide_mm_insw) -_GLOBAL(_insw_ns) - cmpwi 0,r5,0 - mtctr r5 - subi r4,r4,2 - blelr- -00: lhz r5,0(r3) - eieio - sthu r5,2(r4) - bdnz 00b - blr - -_GLOBAL(__ide_mm_outsw) -_GLOBAL(_outsw_ns) - cmpwi 0,r5,0 - mtctr r5 - subi r4,r4,2 - blelr- -00: lhzu r5,2(r4) - sth r5,0(r3) - eieio - bdnz 00b - blr - -_GLOBAL(__ide_mm_insl) -_GLOBAL(_insl_ns) - cmpwi 0,r5,0 - mtctr r5 - subi r4,r4,4 - blelr- -00: lwz r5,0(r3) - eieio - stwu r5,4(r4) - bdnz 00b - blr - -_GLOBAL(__ide_mm_outsl) -_GLOBAL(_outsl_ns) - cmpwi 0,r5,0 - mtctr r5 - subi r4,r4,4 - blelr- -00: lwzu r5,4(r4) - stw r5,0(r3) - eieio - bdnz 00b - blr - -/* * Extended precision shifts. * * Updated to be valid for shift counts from 0 to 63 inclusive. diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S index e8883d42c43c..e3ed21cd3d94 100644 --- a/arch/powerpc/kernel/misc_64.S +++ b/arch/powerpc/kernel/misc_64.S @@ -1,14 +1,12 @@ /* - * arch/powerpc/kernel/misc64.S - * * This file contains miscellaneous low-level functions. * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * * Largely rewritten by Cort Dougan (cort@cs.nmt.edu) * and Paul Mackerras. * Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com) - * PPC64 updates by Dave Engebretsen (engebret@us.ibm.com) - * + * PPC64 updates by Dave Engebretsen (engebret@us.ibm.com) + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version @@ -16,7 +14,6 @@ * */ -#include <linux/config.h> #include <linux/sys.h> #include <asm/unistd.h> #include <asm/errno.h> @@ -30,41 +27,10 @@ .text -/* - * Returns (address we are running at) - (address we were linked at) - * for use before the text and data are mapped to KERNELBASE. - */ - -_GLOBAL(reloc_offset) - mflr r0 - bl 1f -1: mflr r3 - LOAD_REG_IMMEDIATE(r4,1b) - subf r3,r4,r3 - mtlr r0 - blr - -/* - * add_reloc_offset(x) returns x + reloc_offset(). - */ -_GLOBAL(add_reloc_offset) - mflr r0 - bl 1f -1: mflr r5 - LOAD_REG_IMMEDIATE(r4,1b) - subf r5,r4,r5 - add r3,r3,r5 - mtlr r0 - blr - _GLOBAL(get_msr) mfmsr r3 blr -_GLOBAL(get_dar) - mfdar r3 - blr - _GLOBAL(get_srr0) mfsrr0 r3 blr @@ -72,10 +38,6 @@ _GLOBAL(get_srr0) _GLOBAL(get_srr1) mfsrr1 r3 blr - -_GLOBAL(get_sp) - mr r3,r1 - blr #ifdef CONFIG_IRQSTACKS _GLOBAL(call_do_softirq) @@ -89,60 +51,20 @@ _GLOBAL(call_do_softirq) mtlr r0 blr -_GLOBAL(call___do_IRQ) +_GLOBAL(call_handle_irq) + ld r8,0(r7) mflr r0 std r0,16(r1) - stdu r1,THREAD_SIZE-112(r5) - mr r1,r5 - bl .__do_IRQ + mtctr r8 + stdu r1,THREAD_SIZE-112(r6) + mr r1,r6 + bctrl ld r1,0(r1) ld r0,16(r1) mtlr r0 blr #endif /* CONFIG_IRQSTACKS */ - /* - * To be called by C code which needs to do some operations with MMU - * disabled. Note that interrupts have to be disabled by the caller - * prior to calling us. The code called _MUST_ be in the RMO of course - * and part of the linear mapping as we don't attempt to translate the - * stack pointer at all. The function is called with the stack switched - * to this CPU emergency stack - * - * prototype is void *call_with_mmu_off(void *func, void *data); - * - * the called function is expected to be of the form - * - * void *called(void *data); - */ -_GLOBAL(call_with_mmu_off) - mflr r0 /* get link, save it on stackframe */ - std r0,16(r1) - mr r1,r5 /* save old stack ptr */ - ld r1,PACAEMERGSP(r13) /* get emerg. stack */ - subi r1,r1,STACK_FRAME_OVERHEAD - std r0,16(r1) /* save link on emerg. stack */ - std r5,0(r1) /* save old stack ptr in backchain */ - ld r3,0(r3) /* get to real function ptr (assume same TOC) */ - bl 2f /* we need LR to return, continue at label 2 */ - - ld r0,16(r1) /* we return here from the call, get LR and */ - ld r1,0(r1) /* .. old stack ptr */ - mtspr SPRN_SRR0,r0 /* and get back to virtual mode with these */ - mfmsr r4 - ori r4,r4,MSR_IR|MSR_DR - mtspr SPRN_SRR1,r4 - rfid - -2: mtspr SPRN_SRR0,r3 /* coming from above, enter real mode */ - mr r3,r4 /* get parameter */ - mfmsr r0 - ori r0,r0,MSR_IR|MSR_DR - xori r0,r0,MSR_IR|MSR_DR - mtspr SPRN_SRR1,r0 - rfid - - .section ".toc","aw" PPC64_CACHES: .tc ppc64_caches[TC],ppc64_caches @@ -323,144 +245,6 @@ _GLOBAL(__flush_dcache_icache) bdnz 1b isync blr - -/* - * I/O string operations - * - * insb(port, buf, len) - * outsb(port, buf, len) - * insw(port, buf, len) - * outsw(port, buf, len) - * insl(port, buf, len) - * outsl(port, buf, len) - * insw_ns(port, buf, len) - * outsw_ns(port, buf, len) - * insl_ns(port, buf, len) - * outsl_ns(port, buf, len) - * - * The *_ns versions don't do byte-swapping. - */ -_GLOBAL(_insb) - cmpwi 0,r5,0 - mtctr r5 - subi r4,r4,1 - blelr- -00: lbz r5,0(r3) - eieio - stbu r5,1(r4) - bdnz 00b - twi 0,r5,0 - isync - blr - -_GLOBAL(_outsb) - cmpwi 0,r5,0 - mtctr r5 - subi r4,r4,1 - blelr- -00: lbzu r5,1(r4) - stb r5,0(r3) - bdnz 00b - sync - blr - -_GLOBAL(_insw) - cmpwi 0,r5,0 - mtctr r5 - subi r4,r4,2 - blelr- -00: lhbrx r5,0,r3 - eieio - sthu r5,2(r4) - bdnz 00b - twi 0,r5,0 - isync - blr - -_GLOBAL(_outsw) - cmpwi 0,r5,0 - mtctr r5 - subi r4,r4,2 - blelr- -00: lhzu r5,2(r4) - sthbrx r5,0,r3 - bdnz 00b - sync - blr - -_GLOBAL(_insl) - cmpwi 0,r5,0 - mtctr r5 - subi r4,r4,4 - blelr- -00: lwbrx r5,0,r3 - eieio - stwu r5,4(r4) - bdnz 00b - twi 0,r5,0 - isync - blr - -_GLOBAL(_outsl) - cmpwi 0,r5,0 - mtctr r5 - subi r4,r4,4 - blelr- -00: lwzu r5,4(r4) - stwbrx r5,0,r3 - bdnz 00b - sync - blr - -/* _GLOBAL(ide_insw) now in drivers/ide/ide-iops.c */ -_GLOBAL(_insw_ns) - cmpwi 0,r5,0 - mtctr r5 - subi r4,r4,2 - blelr- -00: lhz r5,0(r3) - eieio - sthu r5,2(r4) - bdnz 00b - twi 0,r5,0 - isync - blr - -/* _GLOBAL(ide_outsw) now in drivers/ide/ide-iops.c */ -_GLOBAL(_outsw_ns) - cmpwi 0,r5,0 - mtctr r5 - subi r4,r4,2 - blelr- -00: lhzu r5,2(r4) - sth r5,0(r3) - bdnz 00b - sync - blr - -_GLOBAL(_insl_ns) - cmpwi 0,r5,0 - mtctr r5 - subi r4,r4,4 - blelr- -00: lwz r5,0(r3) - eieio - stwu r5,4(r4) - bdnz 00b - twi 0,r5,0 - isync - blr - -_GLOBAL(_outsl_ns) - cmpwi 0,r5,0 - mtctr r5 - subi r4,r4,4 - blelr- -00: lwzu r5,4(r4) - stw r5,0(r3) - bdnz 00b - sync - blr /* * identify_cpu and calls setup_cpu @@ -605,6 +389,7 @@ _GLOBAL(real_writeb) blr #endif /* defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE) */ +#ifdef CONFIG_CPU_FREQ_PMAC64 /* * SCOM access functions for 970 (FX only for now) * @@ -673,6 +458,7 @@ _GLOBAL(scom970_write) /* restore interrupts */ mtmsrd r5,1 blr +#endif /* CONFIG_CPU_FREQ_PMAC64 */ /* @@ -901,7 +687,7 @@ _GLOBAL(kexec_sequence) /* clear out hardware hash page table and tlb */ ld r5,0(r27) /* deref function descriptor */ mtctr r5 - bctrl /* ppc_md.hash_clear_all(void); */ + bctrl /* ppc_md.hpte_clear_all(void); */ /* * kexec image calling is: diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c index 9feeeef5a875..397c83eda20e 100644 --- a/arch/powerpc/kernel/of_device.c +++ b/arch/powerpc/kernel/of_device.c @@ -1,4 +1,3 @@ -#include <linux/config.h> #include <linux/string.h> #include <linux/kernel.h> #include <linux/init.h> @@ -190,27 +189,9 @@ void of_release_dev(struct device *dev) int of_device_register(struct of_device *ofdev) { int rc; - struct of_device **odprop; BUG_ON(ofdev->node == NULL); - odprop = (struct of_device **)get_property(ofdev->node, "linux,device", NULL); - if (!odprop) { - struct property *new_prop; - - new_prop = kmalloc(sizeof(struct property) + sizeof(struct of_device *), - GFP_KERNEL); - if (new_prop == NULL) - return -ENOMEM; - new_prop->name = "linux,device"; - new_prop->length = sizeof(sizeof(struct of_device *)); - new_prop->value = (unsigned char *)&new_prop[1]; - odprop = (struct of_device **)new_prop->value; - *odprop = NULL; - prom_add_property(ofdev->node, new_prop); - } - *odprop = ofdev; - rc = device_register(&ofdev->dev); if (rc) return rc; @@ -222,14 +203,8 @@ int of_device_register(struct of_device *ofdev) void of_device_unregister(struct of_device *ofdev) { - struct of_device **odprop; - device_remove_file(&ofdev->dev, &dev_attr_devspec); - odprop = (struct of_device **)get_property(ofdev->node, "linux,device", NULL); - if (odprop) - *odprop = NULL; - device_unregister(&ofdev->dev); } diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c index f505a8827e3e..55f1a25085cd 100644 --- a/arch/powerpc/kernel/paca.c +++ b/arch/powerpc/kernel/paca.c @@ -7,7 +7,6 @@ * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <linux/types.h> #include <linux/threads.h> #include <linux/module.h> @@ -16,9 +15,9 @@ #include <asm/ptrace.h> #include <asm/page.h> #include <asm/lppaca.h> -#include <asm/iseries/it_lp_queue.h> #include <asm/iseries/it_lp_reg_save.h> #include <asm/paca.h> +#include <asm/mmu.h> /* This symbol is provided by the linker - let it fill in the paca @@ -47,6 +46,17 @@ struct lppaca lppaca[] = { }, }; +/* + * 3 persistent SLBs are registered here. The buffer will be zero + * initially, hence will all be invaild until we actually write them. + */ +struct slb_shadow slb_shadow[] __cacheline_aligned = { + [0 ... (NR_CPUS-1)] = { + .persistent = SLB_NUM_BOLTED, + .buffer_length = sizeof(struct slb_shadow), + }, +}; + /* The Paca is an array with one entry per processor. Each contains an * lppaca, which contains the information shared between the * hypervisor and Linux. @@ -61,7 +71,8 @@ struct lppaca lppaca[] = { .lock_token = 0x8000, \ .paca_index = (number), /* Paca Index */ \ .kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL, \ - .hw_cpu_id = 0xffff, + .hw_cpu_id = 0xffff, \ + .slb_shadow_ptr = &slb_shadow[number], #ifdef CONFIG_PPC_ISERIES #define PACA_INIT_ISERIES(number) \ diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c index c858eb4bef17..9b49f8691d29 100644 --- a/arch/powerpc/kernel/pci_32.c +++ b/arch/powerpc/kernel/pci_32.c @@ -2,7 +2,6 @@ * Common pmac/prep/chrp pci routines. -- Cort */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/pci.h> #include <linux/delay.h> @@ -12,6 +11,7 @@ #include <linux/sched.h> #include <linux/errno.h> #include <linux/bootmem.h> +#include <linux/irq.h> #include <asm/processor.h> #include <asm/io.h> @@ -19,7 +19,6 @@ #include <asm/sections.h> #include <asm/pci-bridge.h> #include <asm/byteorder.h> -#include <asm/irq.h> #include <asm/uaccess.h> #include <asm/machdep.h> @@ -99,7 +98,7 @@ pcibios_fixup_resources(struct pci_dev *dev) if (!res->flags) continue; if (res->end == 0xffffffff) { - DBG("PCI:%s Resource %d [%08lx-%08lx] is unassigned\n", + DBG("PCI:%s Resource %d [%016llx-%016llx] is unassigned\n", pci_name(dev), i, res->start, res->end); res->end -= res->start; res->start = 0; @@ -117,7 +116,7 @@ pcibios_fixup_resources(struct pci_dev *dev) res->start += offset; res->end += offset; #ifdef DEBUG - printk("Fixup res %d (%lx) of dev %s: %lx -> %lx\n", + printk("Fixup res %d (%lx) of dev %s: %llx -> %llx\n", i, res->flags, pci_name(dev), res->start - offset, res->start); #endif @@ -173,18 +172,18 @@ EXPORT_SYMBOL(pcibios_bus_to_resource); * but we want to try to avoid allocating at 0x2900-0x2bff * which might have be mirrored at 0x0100-0x03ff.. */ -void pcibios_align_resource(void *data, struct resource *res, unsigned long size, - unsigned long align) +void pcibios_align_resource(void *data, struct resource *res, + resource_size_t size, resource_size_t align) { struct pci_dev *dev = data; if (res->flags & IORESOURCE_IO) { - unsigned long start = res->start; + resource_size_t start = res->start; if (size > 0x100) { printk(KERN_ERR "PCI: I/O Region %s/%d too large" - " (%ld bytes)\n", pci_name(dev), - dev->resource - res, size); + " (%lld bytes)\n", pci_name(dev), + dev->resource - res, (unsigned long long)size); } if (start & 0x300) { @@ -255,8 +254,8 @@ pcibios_allocate_bus_resources(struct list_head *bus_list) } } - DBG("PCI: bridge rsrc %lx..%lx (%lx), parent %p\n", - res->start, res->end, res->flags, pr); + DBG("PCI: bridge rsrc %llx..%llx (%lx), parent %p\n", + res->start, res->end, res->flags, pr); if (pr) { if (request_resource(pr, res) == 0) continue; @@ -306,7 +305,7 @@ reparent_resources(struct resource *parent, struct resource *res) *pp = NULL; for (p = res->child; p != NULL; p = p->sibling) { p->parent = res; - DBG(KERN_INFO "PCI: reparented %s [%lx..%lx] under %s\n", + DBG(KERN_INFO "PCI: reparented %s [%llx..%llx] under %s\n", p->name, p->start, p->end, res->name); } return 0; @@ -362,13 +361,14 @@ pci_relocate_bridge_resource(struct pci_bus *bus, int i) try = conflict->start - 1; } if (request_resource(pr, res)) { - DBG(KERN_ERR "PCI: huh? couldn't move to %lx..%lx\n", + DBG(KERN_ERR "PCI: huh? couldn't move to %llx..%llx\n", res->start, res->end); return -1; /* "can't happen" */ } update_bridge_base(bus, i); - printk(KERN_INFO "PCI: bridge %d resource %d moved to %lx..%lx\n", - bus->number, i, res->start, res->end); + printk(KERN_INFO "PCI: bridge %d resource %d moved to %llx..%llx\n", + bus->number, i, (unsigned long long)res->start, + (unsigned long long)res->end); return 0; } @@ -479,14 +479,14 @@ static inline void alloc_resource(struct pci_dev *dev, int idx) { struct resource *pr, *r = &dev->resource[idx]; - DBG("PCI:%s: Resource %d: %08lx-%08lx (f=%lx)\n", + DBG("PCI:%s: Resource %d: %016llx-%016llx (f=%lx)\n", pci_name(dev), idx, r->start, r->end, r->flags); pr = pci_find_parent_resource(dev, r); if (!pr || request_resource(pr, r) < 0) { printk(KERN_ERR "PCI: Cannot allocate resource region %d" " of device %s\n", idx, pci_name(dev)); if (pr) - DBG("PCI: parent is %p: %08lx-%08lx (f=%lx)\n", + DBG("PCI: parent is %p: %016llx-%016llx (f=%lx)\n", pr, pr->start, pr->end, pr->flags); /* We'll assign a new address later */ r->flags |= IORESOURCE_UNSET; @@ -633,12 +633,12 @@ pcibios_alloc_controller(void) static void make_one_node_map(struct device_node* node, u8 pci_bus) { - int *bus_range; + const int *bus_range; int len; if (pci_bus >= pci_bus_count) return; - bus_range = (int *) get_property(node, "bus-range", &len); + bus_range = get_property(node, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) { printk(KERN_WARNING "Can't get bus-range for %s, " "assuming it starts at 0\n", node->full_name); @@ -648,13 +648,13 @@ make_one_node_map(struct device_node* node, u8 pci_bus) for (node=node->child; node != 0;node = node->sibling) { struct pci_dev* dev; - unsigned int *class_code, *reg; + const unsigned int *class_code, *reg; - class_code = (unsigned int *) get_property(node, "class-code", NULL); + class_code = get_property(node, "class-code", NULL); if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) continue; - reg = (unsigned int *)get_property(node, "reg", NULL); + reg = get_property(node, "reg", NULL); if (!reg) continue; dev = pci_find_slot(pci_bus, ((reg[0] >> 8) & 0xff)); @@ -669,7 +669,7 @@ pcibios_make_OF_bus_map(void) { int i; struct pci_controller* hose; - u8* of_prop_map; + struct property *map_prop; pci_to_OF_bus_map = (u8*)kmalloc(pci_bus_count, GFP_KERNEL); if (!pci_to_OF_bus_map) { @@ -691,9 +691,12 @@ pcibios_make_OF_bus_map(void) continue; make_one_node_map(node, hose->first_busno); } - of_prop_map = get_property(find_path_device("/"), "pci-OF-bus-map", NULL); - if (of_prop_map) - memcpy(of_prop_map, pci_to_OF_bus_map, pci_bus_count); + map_prop = of_find_property(find_path_device("/"), + "pci-OF-bus-map", NULL); + if (map_prop) { + BUG_ON(pci_bus_count > map_prop->length); + memcpy(map_prop->value, pci_to_OF_bus_map, pci_bus_count); + } #ifdef DEBUG printk("PCI->OF bus map:\n"); for (i=0; i<pci_bus_count; i++) { @@ -712,7 +715,7 @@ scan_OF_pci_childs(struct device_node* node, pci_OF_scan_iterator filter, void* struct device_node* sub_node; for (; node != 0;node = node->sibling) { - unsigned int *class_code; + const unsigned int *class_code; if (filter(node, data)) return node; @@ -722,7 +725,7 @@ scan_OF_pci_childs(struct device_node* node, pci_OF_scan_iterator filter, void* * a fake root for all functions of a multi-function device, * we go down them as well. */ - class_code = (unsigned int *) get_property(node, "class-code", NULL); + class_code = get_property(node, "class-code", NULL); if ((!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) && strcmp(node->name, "multifunc-device")) @@ -737,10 +740,10 @@ scan_OF_pci_childs(struct device_node* node, pci_OF_scan_iterator filter, void* static int scan_OF_pci_childs_iterator(struct device_node* node, void* data) { - unsigned int *reg; + const unsigned int *reg; u8* fdata = (u8*)data; - reg = (unsigned int *) get_property(node, "reg", NULL); + reg = get_property(node, "reg", NULL); if (reg && ((reg[0] >> 8) & 0xff) == fdata[1] && ((reg[0] >> 16) & 0xff) == fdata[0]) return 1; @@ -841,7 +844,7 @@ find_OF_pci_device_filter(struct device_node* node, void* data) int pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn) { - unsigned int *reg; + const unsigned int *reg; struct pci_controller* hose; struct pci_dev* dev = NULL; @@ -854,7 +857,7 @@ pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn) if (!scan_OF_pci_childs(((struct device_node*)hose->arch_data)->child, find_OF_pci_device_filter, (void *)node)) return -ENODEV; - reg = (unsigned int *) get_property(node, "reg", NULL); + reg = get_property(node, "reg", NULL); if (!reg) return -ENODEV; *bus = (reg[0] >> 16) & 0xff; @@ -885,8 +888,8 @@ pci_process_bridge_OF_ranges(struct pci_controller *hose, struct device_node *dev, int primary) { static unsigned int static_lc_ranges[256] __initdata; - unsigned int *dt_ranges, *lc_ranges, *ranges, *prev; - unsigned int size; + const unsigned int *dt_ranges; + unsigned int *lc_ranges, *ranges, *prev, size; int rlen = 0, orig_rlen; int memno = 0; struct resource *res; @@ -897,7 +900,7 @@ pci_process_bridge_OF_ranges(struct pci_controller *hose, * that can have more than 3 ranges, fortunately using contiguous * addresses -- BenH */ - dt_ranges = (unsigned int *) get_property(dev, "ranges", &rlen); + dt_ranges = get_property(dev, "ranges", &rlen); if (!dt_ranges) return; /* Sanity check, though hopefully that never happens */ @@ -956,7 +959,7 @@ pci_process_bridge_OF_ranges(struct pci_controller *hose, res = &hose->io_resource; res->flags = IORESOURCE_IO; res->start = ranges[2]; - DBG("PCI: IO 0x%lx -> 0x%lx\n", + DBG("PCI: IO 0x%llx -> 0x%llx\n", res->start, res->start + size - 1); break; case 2: /* memory space */ @@ -978,7 +981,7 @@ pci_process_bridge_OF_ranges(struct pci_controller *hose, if(ranges[0] & 0x40000000) res->flags |= IORESOURCE_PREFETCH; res->start = ranges[na+2]; - DBG("PCI: MEM[%d] 0x%lx -> 0x%lx\n", memno, + DBG("PCI: MEM[%d] 0x%llx -> 0x%llx\n", memno, res->start, res->start + size - 1); } break; @@ -1074,7 +1077,7 @@ do_update_p2p_io_resource(struct pci_bus *bus, int enable_vga) DBG("Remapping Bus %d, bridge: %s\n", bus->number, pci_name(bridge)); res.start -= ((unsigned long) hose->io_base_virt - isa_io_base); res.end -= ((unsigned long) hose->io_base_virt - isa_io_base); - DBG(" IO window: %08lx-%08lx\n", res.start, res.end); + DBG(" IO window: %016llx-%016llx\n", res.start, res.end); /* Set up the top and bottom of the PCI I/O segment for this bus. */ pci_read_config_dword(bridge, PCI_IO_BASE, &l); @@ -1223,8 +1226,8 @@ do_fixup_p2p_level(struct pci_bus *bus) continue; if ((r->flags & IORESOURCE_IO) == 0) continue; - DBG("Trying to allocate from %08lx, size %08lx from parent" - " res %d: %08lx -> %08lx\n", + DBG("Trying to allocate from %016llx, size %016llx from parent" + " res %d: %016llx -> %016llx\n", res->start, res->end, i, r->start, r->end); if (allocate_resource(r, res, res->end + 1, res->start, max, @@ -1404,6 +1407,65 @@ pcibios_update_irq(struct pci_dev *dev, int irq) /* XXX FIXME - update OF device tree node interrupt property */ } +#ifdef CONFIG_PPC_MERGE +/* XXX This is a copy of the ppc64 version. This is temporary until we start + * merging the 2 PCI layers + */ +/* + * Reads the interrupt pin to determine if interrupt is use by card. + * If the interrupt is used, then gets the interrupt line from the + * openfirmware and sets it in the pci_dev and pci_config line. + */ +int pci_read_irq_line(struct pci_dev *pci_dev) +{ + struct of_irq oirq; + unsigned int virq; + + DBG("Try to map irq for %s...\n", pci_name(pci_dev)); + + /* Try to get a mapping from the device-tree */ + if (of_irq_map_pci(pci_dev, &oirq)) { + u8 line, pin; + + /* If that fails, lets fallback to what is in the config + * space and map that through the default controller. We + * also set the type to level low since that's what PCI + * interrupts are. If your platform does differently, then + * either provide a proper interrupt tree or don't use this + * function. + */ + if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_PIN, &pin)) + return -1; + if (pin == 0) + return -1; + if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_LINE, &line) || + line == 0xff) { + return -1; + } + DBG(" -> no map ! Using irq line %d from PCI config\n", line); + + virq = irq_create_mapping(NULL, line); + if (virq != NO_IRQ) + set_irq_type(virq, IRQ_TYPE_LEVEL_LOW); + } else { + DBG(" -> got one, spec %d cells (0x%08x...) on %s\n", + oirq.size, oirq.specifier[0], oirq.controller->full_name); + + virq = irq_create_of_mapping(oirq.controller, oirq.specifier, + oirq.size); + } + if(virq == NO_IRQ) { + DBG(" -> failed to map !\n"); + return -1; + } + pci_dev->irq = virq; + pci_write_config_byte(pci_dev, PCI_INTERRUPT_LINE, virq); + + return 0; +} +EXPORT_SYMBOL(pci_read_irq_line); +#endif /* CONFIG_PPC_MERGE */ + int pcibios_enable_device(struct pci_dev *dev, int mask) { u16 cmd, old_cmd; @@ -1574,8 +1636,8 @@ static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp, else prot |= _PAGE_GUARDED; - printk("PCI map for %s:%lx, prot: %lx\n", pci_name(dev), rp->start, - prot); + printk("PCI map for %s:%llx, prot: %lx\n", pci_name(dev), + (unsigned long long)rp->start, prot); return __pgprot(prot); } @@ -1654,7 +1716,6 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, return -EINVAL; vma->vm_pgoff = offset >> PAGE_SHIFT; - vma->vm_flags |= VM_SHM | VM_LOCKED | VM_IO; vma->vm_page_prot = __pci_mmap_set_pgprot(dev, rp, vma->vm_page_prot, mmap_state, write_combine); @@ -1756,7 +1817,7 @@ long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn) void pci_resource_to_user(const struct pci_dev *dev, int bar, const struct resource *rsrc, - u64 *start, u64 *end) + resource_size_t *start, resource_size_t *end) { struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); unsigned long offset = 0; diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index 5ad87c426bed..c1b1e14775e4 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c @@ -13,7 +13,6 @@ #undef DEBUG -#include <linux/config.h> #include <linux/kernel.h> #include <linux/pci.h> #include <linux/string.h> @@ -22,13 +21,13 @@ #include <linux/mm.h> #include <linux/list.h> #include <linux/syscalls.h> +#include <linux/irq.h> #include <asm/processor.h> #include <asm/io.h> #include <asm/prom.h> #include <asm/pci-bridge.h> #include <asm/byteorder.h> -#include <asm/irq.h> #include <asm/machdep.h> #include <asm/ppc-pci.h> @@ -138,11 +137,11 @@ EXPORT_SYMBOL(pcibios_bus_to_resource); * which might have be mirrored at 0x0100-0x03ff.. */ void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) + resource_size_t size, resource_size_t align) { struct pci_dev *dev = data; struct pci_controller *hose = pci_bus_to_host(dev->bus); - unsigned long start = res->start; + resource_size_t start = res->start; unsigned long alignto; if (res->flags & IORESOURCE_IO) { @@ -186,34 +185,6 @@ static void __devinit pci_setup_pci_controller(struct pci_controller *hose) spin_unlock(&hose_spinlock); } -static void add_linux_pci_domain(struct device_node *dev, - struct pci_controller *phb) -{ - struct property *of_prop; - unsigned int size; - - of_prop = (struct property *) - get_property(dev, "linux,pci-domain", &size); - if (of_prop != NULL) - return; - WARN_ON(of_prop && size < sizeof(int)); - if (of_prop && size < sizeof(int)) - of_prop = NULL; - size = sizeof(struct property) + sizeof(int); - if (of_prop == NULL) { - if (mem_init_done) - of_prop = kmalloc(size, GFP_KERNEL); - else - of_prop = alloc_bootmem(size); - } - memset(of_prop, 0, sizeof(struct property)); - of_prop->name = "linux,pci-domain"; - of_prop->length = sizeof(int); - of_prop->value = (unsigned char *)&of_prop[1]; - *((int *)of_prop->value) = phb->global_number; - prom_add_property(dev, of_prop); -} - struct pci_controller * pcibios_alloc_controller(struct device_node *dev) { struct pci_controller *phb; @@ -227,22 +198,13 @@ struct pci_controller * pcibios_alloc_controller(struct device_node *dev) pci_setup_pci_controller(phb); phb->arch_data = dev; phb->is_dynamic = mem_init_done; - if (dev) { + if (dev) PHB_SET_NODE(phb, of_node_to_nid(dev)); - add_linux_pci_domain(dev, phb); - } return phb; } void pcibios_free_controller(struct pci_controller *phb) { - if (phb->arch_data) { - struct device_node *np = phb->arch_data; - int *domain = (int *)get_property(np, - "linux,pci-domain", NULL); - if (domain) - *domain = -1; - } if (phb->is_dynamic) kfree(phb); } @@ -284,10 +246,10 @@ static void __init pcibios_claim_of_setup(void) #ifdef CONFIG_PPC_MULTIPLATFORM static u32 get_int_prop(struct device_node *np, const char *name, u32 def) { - u32 *prop; + const u32 *prop; int len; - prop = (u32 *) get_property(np, name, &len); + prop = get_property(np, name, &len); if (prop && len >= 4) return *prop; return def; @@ -316,10 +278,11 @@ static void pci_parse_of_addrs(struct device_node *node, struct pci_dev *dev) u64 base, size; unsigned int flags; struct resource *res; - u32 *addrs, i; + const u32 *addrs; + u32 i; int proplen; - addrs = (u32 *) get_property(node, "assigned-addresses", &proplen); + addrs = get_property(node, "assigned-addresses", &proplen); if (!addrs) return; DBG(" parse addresses (%d bytes) @ %p\n", proplen, addrs); @@ -399,12 +362,8 @@ struct pci_dev *of_create_pci_dev(struct device_node *node, } else { dev->hdr_type = PCI_HEADER_TYPE_NORMAL; dev->rom_base_reg = PCI_ROM_ADDRESS; + /* Maybe do a default OF mapping here */ dev->irq = NO_IRQ; - if (node->n_intrs > 0) { - dev->irq = node->intrs[0].line; - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, - dev->irq); - } } pci_parse_of_addrs(node, dev); @@ -423,7 +382,7 @@ void __devinit of_scan_bus(struct device_node *node, struct pci_bus *bus) { struct device_node *child = NULL; - u32 *reg; + const u32 *reg; int reglen, devfn; struct pci_dev *dev; @@ -431,7 +390,7 @@ void __devinit of_scan_bus(struct device_node *node, while ((child = of_get_next_child(node, child)) != NULL) { DBG(" * %s\n", child->full_name); - reg = (u32 *) get_property(child, "reg", ®len); + reg = get_property(child, "reg", ®len); if (reg == NULL || reglen < 20) continue; devfn = (reg[0] >> 8) & 0xff; @@ -455,7 +414,7 @@ void __devinit of_scan_pci_bridge(struct device_node *node, struct pci_dev *dev) { struct pci_bus *bus; - u32 *busrange, *ranges; + const u32 *busrange, *ranges; int len, i, mode; struct resource *res; unsigned int flags; @@ -464,13 +423,13 @@ void __devinit of_scan_pci_bridge(struct device_node *node, DBG("of_scan_pci_bridge(%s)\n", node->full_name); /* parse bus-range property */ - busrange = (u32 *) get_property(node, "bus-range", &len); + busrange = get_property(node, "bus-range", &len); if (busrange == NULL || len != 8) { printk(KERN_DEBUG "Can't get bus-range for PCI-PCI bridge %s\n", node->full_name); return; } - ranges = (u32 *) get_property(node, "ranges", &len); + ranges = get_property(node, "ranges", &len); if (ranges == NULL) { printk(KERN_DEBUG "Can't get ranges for PCI-PCI bridge %s\n", node->full_name); @@ -877,7 +836,6 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, return -EINVAL; vma->vm_pgoff = offset >> PAGE_SHIFT; - vma->vm_flags |= VM_SHM | VM_LOCKED | VM_IO; vma->vm_page_prot = __pci_mmap_set_pgprot(dev, rp, vma->vm_page_prot, mmap_state, write_combine); @@ -935,13 +893,13 @@ static void __devinit pci_process_ISA_OF_ranges(struct device_node *isa_node, unsigned int size; }; - struct isa_range *range; + const struct isa_range *range; unsigned long pci_addr; unsigned int isa_addr; unsigned int size; int rlen = 0; - range = (struct isa_range *) get_property(isa_node, "ranges", &rlen); + range = get_property(isa_node, "ranges", &rlen); if (range == NULL || (rlen < sizeof(struct isa_range))) { printk(KERN_ERR "no ISA ranges or unexpected isa range size," "mapping 64k\n"); @@ -982,7 +940,8 @@ static void __devinit pci_process_ISA_OF_ranges(struct device_node *isa_node, void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose, struct device_node *dev, int prim) { - unsigned int *ranges, pci_space; + const unsigned int *ranges; + unsigned int pci_space; unsigned long size; int rlen = 0; int memno = 0; @@ -1000,7 +959,7 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose, * (size depending on dev->n_addr_cells) * cells 4+5 or 5+6: the size of the range */ - ranges = (unsigned int *) get_property(dev, "ranges", &rlen); + ranges = get_property(dev, "ranges", &rlen); if (ranges == NULL) return; hose->io_base_phys = 0; @@ -1290,23 +1249,55 @@ EXPORT_SYMBOL(pcibios_fixup_bus); */ int pci_read_irq_line(struct pci_dev *pci_dev) { - u8 intpin; - struct device_node *node; + struct of_irq oirq; + unsigned int virq; - pci_read_config_byte(pci_dev, PCI_INTERRUPT_PIN, &intpin); - if (intpin == 0) - return 0; + DBG("Try to map irq for %s...\n", pci_name(pci_dev)); - node = pci_device_to_OF_node(pci_dev); - if (node == NULL) - return -1; +#ifdef DEBUG + memset(&oirq, 0xff, sizeof(oirq)); +#endif + /* Try to get a mapping from the device-tree */ + if (of_irq_map_pci(pci_dev, &oirq)) { + u8 line, pin; + + /* If that fails, lets fallback to what is in the config + * space and map that through the default controller. We + * also set the type to level low since that's what PCI + * interrupts are. If your platform does differently, then + * either provide a proper interrupt tree or don't use this + * function. + */ + if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_PIN, &pin)) + return -1; + if (pin == 0) + return -1; + if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_LINE, &line) || + line == 0xff) { + return -1; + } + DBG(" -> no map ! Using irq line %d from PCI config\n", line); + + virq = irq_create_mapping(NULL, line); + if (virq != NO_IRQ) + set_irq_type(virq, IRQ_TYPE_LEVEL_LOW); + } else { + DBG(" -> got one, spec %d cells (0x%08x 0x%08x...) on %s\n", + oirq.size, oirq.specifier[0], oirq.specifier[1], + oirq.controller->full_name); - if (node->n_intrs == 0) + virq = irq_create_of_mapping(oirq.controller, oirq.specifier, + oirq.size); + } + if(virq == NO_IRQ) { + DBG(" -> failed to map !\n"); return -1; + } - pci_dev->irq = node->intrs[0].line; + DBG(" -> mapped to linux irq %d\n", virq); - pci_write_config_byte(pci_dev, PCI_INTERRUPT_LINE, pci_dev->irq); + pci_dev->irq = virq; + pci_write_config_byte(pci_dev, PCI_INTERRUPT_LINE, virq); return 0; } diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c index 1c18953514c3..68df018dae0e 100644 --- a/arch/powerpc/kernel/pci_dn.c +++ b/arch/powerpc/kernel/pci_dn.c @@ -40,8 +40,8 @@ static void * __devinit update_dn_pci_info(struct device_node *dn, void *data) { struct pci_controller *phb = data; - int *type = (int *)get_property(dn, "ibm,pci-config-space-type", NULL); - u32 *regs; + const int *type = get_property(dn, "ibm,pci-config-space-type", NULL); + const u32 *regs; struct pci_dn *pdn; if (mem_init_done) @@ -54,14 +54,14 @@ static void * __devinit update_dn_pci_info(struct device_node *dn, void *data) dn->data = pdn; pdn->node = dn; pdn->phb = phb; - regs = (u32 *)get_property(dn, "reg", NULL); + regs = get_property(dn, "reg", NULL); if (regs) { /* First register entry is addr (00BBSS00) */ pdn->busno = (regs[0] >> 16) & 0xff; pdn->devfn = (regs[0] >> 8) & 0xff; } if (firmware_has_feature(FW_FEATURE_ISERIES)) { - u32 *busp = (u32 *)get_property(dn, "linux,subbus", NULL); + const u32 *busp = get_property(dn, "linux,subbus", NULL); if (busp) pdn->bussubno = *busp; } @@ -96,10 +96,11 @@ void *traverse_pci_devices(struct device_node *start, traverse_func pre, /* We started with a phb, iterate all childs */ for (dn = start->child; dn; dn = nextdn) { - u32 *classp, class; + const u32 *classp; + u32 class; nextdn = NULL; - classp = (u32 *)get_property(dn, "class-code", NULL); + classp = get_property(dn, "class-code", NULL); class = classp ? *classp : 0; if (pre && ((ret = pre(dn, data)) != NULL)) diff --git a/arch/powerpc/kernel/perfmon_fsl_booke.c b/arch/powerpc/kernel/perfmon_fsl_booke.c index 32455dfcc36b..bdc3977a7b06 100644 --- a/arch/powerpc/kernel/perfmon_fsl_booke.c +++ b/arch/powerpc/kernel/perfmon_fsl_booke.c @@ -21,7 +21,6 @@ #include <linux/user.h> #include <linux/a.out.h> #include <linux/interrupt.h> -#include <linux/config.h> #include <linux/init.h> #include <linux/module.h> #include <linux/prctl.h> diff --git a/arch/powerpc/kernel/pmc.c b/arch/powerpc/kernel/pmc.c index e6fb194fe537..a0a2efadeabf 100644 --- a/arch/powerpc/kernel/pmc.c +++ b/arch/powerpc/kernel/pmc.c @@ -12,7 +12,6 @@ * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <linux/errno.h> #include <linux/spinlock.h> #include <linux/module.h> diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index 4b052ae5dc34..807193a3c784 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c @@ -1,4 +1,3 @@ -#include <linux/config.h> #include <linux/module.h> #include <linux/threads.h> #include <linux/smp.h> @@ -6,7 +5,7 @@ #include <linux/elfcore.h> #include <linux/string.h> #include <linux/interrupt.h> -#include <linux/tty.h> +#include <linux/screen_info.h> #include <linux/vt_kern.h> #include <linux/nvram.h> #include <linux/console.h> @@ -92,25 +91,10 @@ EXPORT_SYMBOL(__copy_tofrom_user); EXPORT_SYMBOL(__clear_user); EXPORT_SYMBOL(__strncpy_from_user); EXPORT_SYMBOL(__strnlen_user); - -#ifndef __powerpc64__ -EXPORT_SYMBOL(__ide_mm_insl); -EXPORT_SYMBOL(__ide_mm_outsw); -EXPORT_SYMBOL(__ide_mm_insw); -EXPORT_SYMBOL(__ide_mm_outsl); +#ifdef CONFIG_PPC64 +EXPORT_SYMBOL(copy_4K_page); #endif -EXPORT_SYMBOL(_insb); -EXPORT_SYMBOL(_outsb); -EXPORT_SYMBOL(_insw); -EXPORT_SYMBOL(_outsw); -EXPORT_SYMBOL(_insl); -EXPORT_SYMBOL(_outsl); -EXPORT_SYMBOL(_insw_ns); -EXPORT_SYMBOL(_outsw_ns); -EXPORT_SYMBOL(_insl_ns); -EXPORT_SYMBOL(_outsl_ns); - #if defined(CONFIG_PPC32) && (defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)) EXPORT_SYMBOL(ppc_ide_md); #endif @@ -127,10 +111,6 @@ EXPORT_SYMBOL(pci_bus_mem_base_phys); EXPORT_SYMBOL(pci_bus_to_hose); #endif /* CONFIG_PCI */ -#ifdef CONFIG_NOT_COHERENT_CACHE -EXPORT_SYMBOL(flush_dcache_all); -#endif - EXPORT_SYMBOL(start_thread); EXPORT_SYMBOL(kernel_thread); diff --git a/arch/powerpc/kernel/proc_ppc64.c b/arch/powerpc/kernel/proc_ppc64.c index 2b87f82df135..f598cb519539 100644 --- a/arch/powerpc/kernel/proc_ppc64.c +++ b/arch/powerpc/kernel/proc_ppc64.c @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <linux/config.h> #include <linux/init.h> #include <linux/mm.h> #include <linux/proc_fs.h> @@ -115,8 +114,6 @@ static int page_map_mmap( struct file *file, struct vm_area_struct *vma ) { struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode); - vma->vm_flags |= VM_SHM | VM_LOCKED; - if ((vma->vm_end - vma->vm_start) > dp->size) return -EINVAL; diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index e4732459c485..a127a1e3c097 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -14,7 +14,6 @@ * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <linux/errno.h> #include <linux/sched.h> #include <linux/kernel.h> diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 483455c5bb02..eb913f80bfb1 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -16,7 +16,6 @@ #undef DEBUG #include <stdarg.h> -#include <linux/config.h> #include <linux/kernel.h> #include <linux/string.h> #include <linux/init.h> @@ -30,6 +29,8 @@ #include <linux/bitops.h> #include <linux/module.h> #include <linux/kexec.h> +#include <linux/debugfs.h> +#include <linux/irq.h> #include <asm/prom.h> #include <asm/rtas.h> @@ -86,424 +87,6 @@ static DEFINE_RWLOCK(devtree_lock); /* export that to outside world */ struct device_node *of_chosen; -struct device_node *dflt_interrupt_controller; -int num_interrupt_controllers; - -/* - * Wrapper for allocating memory for various data that needs to be - * attached to device nodes as they are processed at boot or when - * added to the device tree later (e.g. DLPAR). At boot there is - * already a region reserved so we just increment *mem_start by size; - * otherwise we call kmalloc. - */ -static void * prom_alloc(unsigned long size, unsigned long *mem_start) -{ - unsigned long tmp; - - if (!mem_start) - return kmalloc(size, GFP_KERNEL); - - tmp = *mem_start; - *mem_start += size; - return (void *)tmp; -} - -/* - * Find the device_node with a given phandle. - */ -static struct device_node * find_phandle(phandle ph) -{ - struct device_node *np; - - for (np = allnodes; np != 0; np = np->allnext) - if (np->linux_phandle == ph) - return np; - return NULL; -} - -/* - * Find the interrupt parent of a node. - */ -static struct device_node * __devinit intr_parent(struct device_node *p) -{ - phandle *parp; - - parp = (phandle *) get_property(p, "interrupt-parent", NULL); - if (parp == NULL) - return p->parent; - p = find_phandle(*parp); - if (p != NULL) - return p; - /* - * On a powermac booted with BootX, we don't get to know the - * phandles for any nodes, so find_phandle will return NULL. - * Fortunately these machines only have one interrupt controller - * so there isn't in fact any ambiguity. -- paulus - */ - if (num_interrupt_controllers == 1) - p = dflt_interrupt_controller; - return p; -} - -/* - * Find out the size of each entry of the interrupts property - * for a node. - */ -int __devinit prom_n_intr_cells(struct device_node *np) -{ - struct device_node *p; - unsigned int *icp; - - for (p = np; (p = intr_parent(p)) != NULL; ) { - icp = (unsigned int *) - get_property(p, "#interrupt-cells", NULL); - if (icp != NULL) - return *icp; - if (get_property(p, "interrupt-controller", NULL) != NULL - || get_property(p, "interrupt-map", NULL) != NULL) { - printk("oops, node %s doesn't have #interrupt-cells\n", - p->full_name); - return 1; - } - } -#ifdef DEBUG_IRQ - printk("prom_n_intr_cells failed for %s\n", np->full_name); -#endif - return 1; -} - -/* - * Map an interrupt from a device up to the platform interrupt - * descriptor. - */ -static int __devinit map_interrupt(unsigned int **irq, struct device_node **ictrler, - struct device_node *np, unsigned int *ints, - int nintrc) -{ - struct device_node *p, *ipar; - unsigned int *imap, *imask, *ip; - int i, imaplen, match; - int newintrc = 0, newaddrc = 0; - unsigned int *reg; - int naddrc; - - reg = (unsigned int *) get_property(np, "reg", NULL); - naddrc = prom_n_addr_cells(np); - p = intr_parent(np); - while (p != NULL) { - if (get_property(p, "interrupt-controller", NULL) != NULL) - /* this node is an interrupt controller, stop here */ - break; - imap = (unsigned int *) - get_property(p, "interrupt-map", &imaplen); - if (imap == NULL) { - p = intr_parent(p); - continue; - } - imask = (unsigned int *) - get_property(p, "interrupt-map-mask", NULL); - if (imask == NULL) { - printk("oops, %s has interrupt-map but no mask\n", - p->full_name); - return 0; - } - imaplen /= sizeof(unsigned int); - match = 0; - ipar = NULL; - while (imaplen > 0 && !match) { - /* check the child-interrupt field */ - match = 1; - for (i = 0; i < naddrc && match; ++i) - match = ((reg[i] ^ imap[i]) & imask[i]) == 0; - for (; i < naddrc + nintrc && match; ++i) - match = ((ints[i-naddrc] ^ imap[i]) & imask[i]) == 0; - imap += naddrc + nintrc; - imaplen -= naddrc + nintrc; - /* grab the interrupt parent */ - ipar = find_phandle((phandle) *imap++); - --imaplen; - if (ipar == NULL && num_interrupt_controllers == 1) - /* cope with BootX not giving us phandles */ - ipar = dflt_interrupt_controller; - if (ipar == NULL) { - printk("oops, no int parent %x in map of %s\n", - imap[-1], p->full_name); - return 0; - } - /* find the parent's # addr and intr cells */ - ip = (unsigned int *) - get_property(ipar, "#interrupt-cells", NULL); - if (ip == NULL) { - printk("oops, no #interrupt-cells on %s\n", - ipar->full_name); - return 0; - } - newintrc = *ip; - ip = (unsigned int *) - get_property(ipar, "#address-cells", NULL); - newaddrc = (ip == NULL)? 0: *ip; - imap += newaddrc + newintrc; - imaplen -= newaddrc + newintrc; - } - if (imaplen < 0) { - printk("oops, error decoding int-map on %s, len=%d\n", - p->full_name, imaplen); - return 0; - } - if (!match) { -#ifdef DEBUG_IRQ - printk("oops, no match in %s int-map for %s\n", - p->full_name, np->full_name); -#endif - return 0; - } - p = ipar; - naddrc = newaddrc; - nintrc = newintrc; - ints = imap - nintrc; - reg = ints - naddrc; - } - if (p == NULL) { -#ifdef DEBUG_IRQ - printk("hmmm, int tree for %s doesn't have ctrler\n", - np->full_name); -#endif - return 0; - } - *irq = ints; - *ictrler = p; - return nintrc; -} - -static unsigned char map_isa_senses[4] = { - IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE, - IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE, - IRQ_SENSE_EDGE | IRQ_POLARITY_NEGATIVE, - IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE -}; - -static unsigned char map_mpic_senses[4] = { - IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE, - IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE, - /* 2 seems to be used for the 8259 cascade... */ - IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE, - IRQ_SENSE_EDGE | IRQ_POLARITY_NEGATIVE, -}; - -static int __devinit finish_node_interrupts(struct device_node *np, - unsigned long *mem_start, - int measure_only) -{ - unsigned int *ints; - int intlen, intrcells, intrcount; - int i, j, n, sense; - unsigned int *irq, virq; - struct device_node *ic; - int trace = 0; - - //#define TRACE(fmt...) do { if (trace) { printk(fmt); mdelay(1000); } } while(0) -#define TRACE(fmt...) - - if (!strcmp(np->name, "smu-doorbell")) - trace = 1; - - TRACE("Finishing SMU doorbell ! num_interrupt_controllers = %d\n", - num_interrupt_controllers); - - if (num_interrupt_controllers == 0) { - /* - * Old machines just have a list of interrupt numbers - * and no interrupt-controller nodes. - */ - ints = (unsigned int *) get_property(np, "AAPL,interrupts", - &intlen); - /* XXX old interpret_pci_props looked in parent too */ - /* XXX old interpret_macio_props looked for interrupts - before AAPL,interrupts */ - if (ints == NULL) - ints = (unsigned int *) get_property(np, "interrupts", - &intlen); - if (ints == NULL) - return 0; - - np->n_intrs = intlen / sizeof(unsigned int); - np->intrs = prom_alloc(np->n_intrs * sizeof(np->intrs[0]), - mem_start); - if (!np->intrs) - return -ENOMEM; - if (measure_only) - return 0; - - for (i = 0; i < np->n_intrs; ++i) { - np->intrs[i].line = *ints++; - np->intrs[i].sense = IRQ_SENSE_LEVEL - | IRQ_POLARITY_NEGATIVE; - } - return 0; - } - - ints = (unsigned int *) get_property(np, "interrupts", &intlen); - TRACE("ints=%p, intlen=%d\n", ints, intlen); - if (ints == NULL) - return 0; - intrcells = prom_n_intr_cells(np); - intlen /= intrcells * sizeof(unsigned int); - TRACE("intrcells=%d, new intlen=%d\n", intrcells, intlen); - np->intrs = prom_alloc(intlen * sizeof(*(np->intrs)), mem_start); - if (!np->intrs) - return -ENOMEM; - - if (measure_only) - return 0; - - intrcount = 0; - for (i = 0; i < intlen; ++i, ints += intrcells) { - n = map_interrupt(&irq, &ic, np, ints, intrcells); - TRACE("map, irq=%d, ic=%p, n=%d\n", irq, ic, n); - if (n <= 0) - continue; - - /* don't map IRQ numbers under a cascaded 8259 controller */ - if (ic && device_is_compatible(ic, "chrp,iic")) { - np->intrs[intrcount].line = irq[0]; - sense = (n > 1)? (irq[1] & 3): 3; - np->intrs[intrcount].sense = map_isa_senses[sense]; - } else { - virq = virt_irq_create_mapping(irq[0]); - TRACE("virq=%d\n", virq); -#ifdef CONFIG_PPC64 - if (virq == NO_IRQ) { - printk(KERN_CRIT "Could not allocate interrupt" - " number for %s\n", np->full_name); - continue; - } -#endif - np->intrs[intrcount].line = irq_offset_up(virq); - sense = (n > 1)? (irq[1] & 3): 1; - - /* Apple uses bits in there in a different way, let's - * only keep the real sense bit on macs - */ - if (machine_is(powermac)) - sense &= 0x1; - np->intrs[intrcount].sense = map_mpic_senses[sense]; - } - -#ifdef CONFIG_PPC64 - /* We offset irq numbers for the u3 MPIC by 128 in PowerMac */ - if (machine_is(powermac) && ic && ic->parent) { - char *name = get_property(ic->parent, "name", NULL); - if (name && !strcmp(name, "u3")) - np->intrs[intrcount].line += 128; - else if (!(name && (!strcmp(name, "mac-io") || - !strcmp(name, "u4")))) - /* ignore other cascaded controllers, such as - the k2-sata-root */ - break; - } -#endif /* CONFIG_PPC64 */ - if (n > 2) { - printk("hmmm, got %d intr cells for %s:", n, - np->full_name); - for (j = 0; j < n; ++j) - printk(" %d", irq[j]); - printk("\n"); - } - ++intrcount; - } - np->n_intrs = intrcount; - - return 0; -} - -static int __devinit finish_node(struct device_node *np, - unsigned long *mem_start, - int measure_only) -{ - struct device_node *child; - int rc = 0; - - rc = finish_node_interrupts(np, mem_start, measure_only); - if (rc) - goto out; - - for (child = np->child; child != NULL; child = child->sibling) { - rc = finish_node(child, mem_start, measure_only); - if (rc) - goto out; - } -out: - return rc; -} - -static void __init scan_interrupt_controllers(void) -{ - struct device_node *np; - int n = 0; - char *name, *ic; - int iclen; - - for (np = allnodes; np != NULL; np = np->allnext) { - ic = get_property(np, "interrupt-controller", &iclen); - name = get_property(np, "name", NULL); - /* checking iclen makes sure we don't get a false - match on /chosen.interrupt_controller */ - if ((name != NULL - && strcmp(name, "interrupt-controller") == 0) - || (ic != NULL && iclen == 0 - && strcmp(name, "AppleKiwi"))) { - if (n == 0) - dflt_interrupt_controller = np; - ++n; - } - } - num_interrupt_controllers = n; -} - -/** - * finish_device_tree is called once things are running normally - * (i.e. with text and data mapped to the address they were linked at). - * It traverses the device tree and fills in some of the additional, - * fields in each node like {n_}addrs and {n_}intrs, the virt interrupt - * mapping is also initialized at this point. - */ -void __init finish_device_tree(void) -{ - unsigned long start, end, size = 0; - - DBG(" -> finish_device_tree\n"); - -#ifdef CONFIG_PPC64 - /* Initialize virtual IRQ map */ - virt_irq_init(); -#endif - scan_interrupt_controllers(); - - /* - * Finish device-tree (pre-parsing some properties etc...) - * We do this in 2 passes. One with "measure_only" set, which - * will only measure the amount of memory needed, then we can - * allocate that memory, and call finish_node again. However, - * we must be careful as most routines will fail nowadays when - * prom_alloc() returns 0, so we must make sure our first pass - * doesn't start at 0. We pre-initialize size to 16 for that - * reason and then remove those additional 16 bytes - */ - size = 16; - finish_node(allnodes, &size, 1); - size -= 16; - - if (0 == size) - end = start = 0; - else - end = start = (unsigned long)__va(lmb_alloc(size, 128)); - - finish_node(allnodes, &end, 0); - BUG_ON(end != start + size); - - DBG(" <- finish_device_tree\n"); -} - static inline char *find_flat_dt_string(u32 offset) { return ((char *)initial_boot_params) + @@ -952,6 +535,7 @@ static struct ibm_pa_feature { /* put this back once we know how to test if firmware does 64k IO */ {CPU_FTR_CI_LARGE_PAGE, 0, 1, 2, 0}, #endif + {CPU_FTR_REAL_LE, PPC_FEATURE_TRUE_LE, 5, 0, 0}, }; static void __init check_cpu_pa_features(unsigned long node) @@ -1124,24 +708,6 @@ static int __init early_init_dt_scan_chosen(unsigned long node, tce_alloc_end = *lprop; #endif -#ifdef CONFIG_PPC_RTAS - /* To help early debugging via the front panel, we retrieve a minimal - * set of RTAS infos now if available - */ - { - u64 *basep, *entryp, *sizep; - - basep = of_get_flat_dt_prop(node, "linux,rtas-base", NULL); - entryp = of_get_flat_dt_prop(node, "linux,rtas-entry", NULL); - sizep = of_get_flat_dt_prop(node, "linux,rtas-size", NULL); - if (basep && entryp && sizep) { - rtas.base = *basep; - rtas.entry = *entryp; - rtas.size = *sizep; - } - } -#endif /* CONFIG_PPC_RTAS */ - #ifdef CONFIG_KEXEC lprop = (u64*)of_get_flat_dt_prop(node, "linux,crashkernel-base", NULL); if (lprop) @@ -1191,24 +757,9 @@ static int __init early_init_dt_scan_root(unsigned long node, static unsigned long __init dt_mem_next_cell(int s, cell_t **cellp) { cell_t *p = *cellp; - unsigned long r; - /* Ignore more than 2 cells */ - while (s > sizeof(unsigned long) / 4) { - p++; - s--; - } - r = *p++; -#ifdef CONFIG_PPC64 - if (s > 1) { - r <<= 32; - r |= *(p++); - s--; - } -#endif - - *cellp = p; - return r; + *cellp = p + s; + return of_read_ulong(p, s); } @@ -1326,6 +877,11 @@ void __init early_init_devtree(void *params) /* Setup flat device-tree pointer */ initial_boot_params = params; +#ifdef CONFIG_PPC_RTAS + /* Some machines might need RTAS info for debugging, grab it now. */ + of_scan_flat_dt(early_init_dt_scan_rtas, NULL); +#endif + /* Retrieve various informations from the /chosen node of the * device-tree, including the platform type, initrd location and * size, TCE reserve, and more ... @@ -1371,11 +927,11 @@ void __init early_init_devtree(void *params) int prom_n_addr_cells(struct device_node* np) { - int* ip; + const int *ip; do { if (np->parent) np = np->parent; - ip = (int *) get_property(np, "#address-cells", NULL); + ip = get_property(np, "#address-cells", NULL); if (ip != NULL) return *ip; } while (np->parent); @@ -1387,11 +943,11 @@ EXPORT_SYMBOL(prom_n_addr_cells); int prom_n_size_cells(struct device_node* np) { - int* ip; + const int* ip; do { if (np->parent) np = np->parent; - ip = (int *) get_property(np, "#size-cells", NULL); + ip = get_property(np, "#size-cells", NULL); if (ip != NULL) return *ip; } while (np->parent); @@ -1401,27 +957,6 @@ prom_n_size_cells(struct device_node* np) EXPORT_SYMBOL(prom_n_size_cells); /** - * Work out the sense (active-low level / active-high edge) - * of each interrupt from the device tree. - */ -void __init prom_get_irq_senses(unsigned char *senses, int off, int max) -{ - struct device_node *np; - int i, j; - - /* default to level-triggered */ - memset(senses, IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE, max - off); - - for (np = allnodes; np != 0; np = np->allnext) { - for (j = 0; j < np->n_intrs; j++) { - i = np->intrs[j].line; - if (i >= off && i < max) - senses[i-off] = np->intrs[j].sense; - } - } -} - -/** * Construct and return a list of the device_nodes with a given name. */ struct device_node *find_devices(const char *name) @@ -1484,7 +1019,7 @@ int device_is_compatible(struct device_node *device, const char *compat) const char* cp; int cplen, l; - cp = (char *) get_property(device, "compatible", &cplen); + cp = get_property(device, "compatible", &cplen); if (cp == NULL) return 0; while (cplen > 0) { @@ -1820,7 +1355,6 @@ static void of_node_release(struct kref *kref) node->deadprops = NULL; } } - kfree(node->intrs); kfree(node->full_name); kfree(node->data); kfree(node); @@ -1893,20 +1427,14 @@ void of_detach_node(const struct device_node *np) #ifdef CONFIG_PPC_PSERIES /* * Fix up the uninitialized fields in a new device node: - * name, type, n_addrs, addrs, n_intrs, intrs, and pci-specific fields - * - * A lot of boot-time code is duplicated here, because functions such - * as finish_node_interrupts, interpret_pci_props, etc. cannot use the - * slab allocator. - * - * This should probably be split up into smaller chunks. + * name, type and pci-specific fields */ static int of_finish_dynamic_node(struct device_node *node) { struct device_node *parent = of_get_parent(node); int err = 0; - phandle *ibm_phandle; + const phandle *ibm_phandle; node->name = get_property(node, "name", NULL); node->type = get_property(node, "device_type", NULL); @@ -1923,8 +1451,7 @@ static int of_finish_dynamic_node(struct device_node *node) return -ENODEV; /* fix up new node's linux_phandle field */ - if ((ibm_phandle = (unsigned int *)get_property(node, - "ibm,phandle", NULL))) + if ((ibm_phandle = get_property(node, "ibm,phandle", NULL))) node->linux_phandle = *ibm_phandle; out: @@ -1940,8 +1467,6 @@ static int prom_reconfig_notifier(struct notifier_block *nb, switch (action) { case PSERIES_RECONFIG_ADD: err = of_finish_dynamic_node(node); - if (!err) - finish_node(node, NULL, 0); if (err < 0) { printk(KERN_ERR "finish_node returned %d\n", err); err = NOTIFY_BAD; @@ -1987,8 +1512,7 @@ struct property *of_find_property(struct device_node *np, const char *name, * Find a property with a given name for a given node * and return the value. */ -unsigned char *get_property(struct device_node *np, const char *name, - int *lenp) +const void *get_property(struct device_node *np, const char *name, int *lenp) { struct property *pp = of_find_property(np,name,lenp); return pp ? pp->value : NULL; @@ -2118,16 +1642,16 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread) hardid = get_hard_smp_processor_id(cpu); for_each_node_by_type(np, "cpu") { - u32 *intserv; + const u32 *intserv; unsigned int plen, t; /* Check for ibm,ppc-interrupt-server#s. If it doesn't exist * fallback to "reg" property and assume no threads */ - intserv = (u32 *)get_property(np, "ibm,ppc-interrupt-server#s", - &plen); + intserv = get_property(np, "ibm,ppc-interrupt-server#s", + &plen); if (intserv == NULL) { - u32 *reg = (u32 *)get_property(np, "reg", NULL); + const u32 *reg = get_property(np, "reg", NULL); if (reg == NULL) continue; if (*reg == hardid) { @@ -2148,3 +1672,27 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread) } return NULL; } + +#ifdef DEBUG +static struct debugfs_blob_wrapper flat_dt_blob; + +static int __init export_flat_device_tree(void) +{ + struct dentry *d; + + d = debugfs_create_dir("powerpc", NULL); + if (!d) + return 1; + + flat_dt_blob.data = initial_boot_params; + flat_dt_blob.size = initial_boot_params->totalsize; + + d = debugfs_create_blob("flat-device-tree", S_IFREG | S_IRUSR, + d, &flat_dt_blob); + if (!d) + return 1; + + return 0; +} +__initcall(export_flat_device_tree); +#endif diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 8c28eb0cbdac..b91761639d96 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -16,7 +16,6 @@ #undef DEBUG_PROM #include <stdarg.h> -#include <linux/config.h> #include <linux/kernel.h> #include <linux/string.h> #include <linux/init.h> @@ -558,7 +557,9 @@ unsigned long prom_memparse(const char *ptr, const char **retptr) static void __init early_cmdline_parse(void) { struct prom_t *_prom = &RELOC(prom); +#ifdef CONFIG_PPC64 const char *opt; +#endif char *p; int l = 0; @@ -645,13 +646,13 @@ static unsigned char ibm_architecture_vec[] = { 5 - 1, /* 5 option vectors */ /* option vector 1: processor architectures supported */ - 3 - 1, /* length */ + 3 - 2, /* length */ 0, /* don't ignore, don't halt */ OV1_PPC_2_00 | OV1_PPC_2_01 | OV1_PPC_2_02 | OV1_PPC_2_03 | OV1_PPC_2_04 | OV1_PPC_2_05, /* option vector 2: Open Firmware options supported */ - 34 - 1, /* length */ + 34 - 2, /* length */ OV2_REAL_MODE, 0, 0, W(0xffffffff), /* real_base */ @@ -665,16 +666,16 @@ static unsigned char ibm_architecture_vec[] = { 48, /* max log_2(hash table size) */ /* option vector 3: processor options supported */ - 3 - 1, /* length */ + 3 - 2, /* length */ 0, /* don't ignore, don't halt */ OV3_FP | OV3_VMX, /* option vector 4: IBM PAPR implementation */ - 2 - 1, /* length */ + 2 - 2, /* length */ 0, /* don't halt */ /* option vector 5: PAPR/OF options */ - 3 - 1, /* length */ + 3 - 2, /* length */ 0, /* don't ignore, don't halt */ OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES, }; @@ -988,7 +989,7 @@ static void reserve_mem(u64 base, u64 size) } /* - * Initialize memory allocation mecanism, parse "memory" nodes and + * Initialize memory allocation mechanism, parse "memory" nodes and * obtain that way the top of memory and RMO to setup out local allocator */ static void __init prom_init_mem(void) @@ -1991,12 +1992,22 @@ static void __init flatten_device_tree(void) static void __init fixup_device_tree_maple(void) { phandle isa; + u32 rloc = 0x01002000; /* IO space; PCI device = 4 */ u32 isa_ranges[6]; - - isa = call_prom("finddevice", 1, 1, ADDR("/ht@0/isa@4")); + char *name; + + name = "/ht@0/isa@4"; + isa = call_prom("finddevice", 1, 1, ADDR(name)); + if (!PHANDLE_VALID(isa)) { + name = "/ht@0/isa@6"; + isa = call_prom("finddevice", 1, 1, ADDR(name)); + rloc = 0x01003000; /* IO space; PCI device = 6 */ + } if (!PHANDLE_VALID(isa)) return; + if (prom_getproplen(isa, "ranges") != 12) + return; if (prom_getprop(isa, "ranges", isa_ranges, sizeof(isa_ranges)) == PROM_ERROR) return; @@ -2006,21 +2017,60 @@ static void __init fixup_device_tree_maple(void) isa_ranges[2] != 0x00010000) return; - prom_printf("fixing up bogus ISA range on Maple...\n"); + prom_printf("Fixing up bogus ISA range on Maple/Apache...\n"); isa_ranges[0] = 0x1; isa_ranges[1] = 0x0; - isa_ranges[2] = 0x01002000; /* IO space; PCI device = 4 */ + isa_ranges[2] = rloc; isa_ranges[3] = 0x0; isa_ranges[4] = 0x0; isa_ranges[5] = 0x00010000; - prom_setprop(isa, "/ht@0/isa@4", "ranges", + prom_setprop(isa, name, "ranges", isa_ranges, sizeof(isa_ranges)); } #else #define fixup_device_tree_maple() #endif +#ifdef CONFIG_PPC_CHRP +/* Pegasos and BriQ lacks the "ranges" property in the isa node */ +static void __init fixup_device_tree_chrp(void) +{ + phandle isa; + u32 isa_ranges[6]; + u32 rloc = 0x01006000; /* IO space; PCI device = 12 */ + char *name; + int rc; + + name = "/pci@80000000/isa@c"; + isa = call_prom("finddevice", 1, 1, ADDR(name)); + if (!PHANDLE_VALID(isa)) { + name = "/pci@ff500000/isa@6"; + isa = call_prom("finddevice", 1, 1, ADDR(name)); + rloc = 0x01003000; /* IO space; PCI device = 6 */ + } + if (!PHANDLE_VALID(isa)) + return; + + rc = prom_getproplen(isa, "ranges"); + if (rc != 0 && rc != PROM_ERROR) + return; + + prom_printf("Fixing up missing ISA range on Pegasos...\n"); + + isa_ranges[0] = 0x1; + isa_ranges[1] = 0x0; + isa_ranges[2] = rloc; + isa_ranges[3] = 0x0; + isa_ranges[4] = 0x0; + isa_ranges[5] = 0x00010000; + prom_setprop(isa, name, "ranges", + isa_ranges, sizeof(isa_ranges)); +} +#else +#define fixup_device_tree_chrp() +#endif + #if defined(CONFIG_PPC64) && defined(CONFIG_PPC_PMAC) static void __init fixup_device_tree_pmac(void) { @@ -2068,6 +2118,7 @@ static void __init fixup_device_tree_pmac(void) static void __init fixup_device_tree(void) { fixup_device_tree_maple(); + fixup_device_tree_chrp(); fixup_device_tree_pmac(); } diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c index 45df420383cc..603dff3ad62a 100644 --- a/arch/powerpc/kernel/prom_parse.c +++ b/arch/powerpc/kernel/prom_parse.c @@ -27,7 +27,7 @@ /* Debug utility */ #ifdef DEBUG -static void of_dump_addr(const char *s, u32 *addr, int na) +static void of_dump_addr(const char *s, const u32 *addr, int na) { printk("%s", s); while(na--) @@ -35,17 +35,9 @@ static void of_dump_addr(const char *s, u32 *addr, int na) printk("\n"); } #else -static void of_dump_addr(const char *s, u32 *addr, int na) { } +static void of_dump_addr(const char *s, const u32 *addr, int na) { } #endif -/* Read a big address */ -static inline u64 of_read_addr(u32 *cell, int size) -{ - u64 r = 0; - while (size--) - r = (r << 32) | *(cell++); - return r; -} /* Callbacks for bus specific translators */ struct of_bus { @@ -54,9 +46,10 @@ struct of_bus { int (*match)(struct device_node *parent); void (*count_cells)(struct device_node *child, int *addrc, int *sizec); - u64 (*map)(u32 *addr, u32 *range, int na, int ns, int pna); + u64 (*map)(u32 *addr, const u32 *range, + int na, int ns, int pna); int (*translate)(u32 *addr, u64 offset, int na); - unsigned int (*get_flags)(u32 *addr); + unsigned int (*get_flags)(const u32 *addr); }; @@ -73,13 +66,14 @@ static void of_bus_default_count_cells(struct device_node *dev, *sizec = prom_n_size_cells(dev); } -static u64 of_bus_default_map(u32 *addr, u32 *range, int na, int ns, int pna) +static u64 of_bus_default_map(u32 *addr, const u32 *range, + int na, int ns, int pna) { u64 cp, s, da; - cp = of_read_addr(range, na); - s = of_read_addr(range + na + pna, ns); - da = of_read_addr(addr, na); + cp = of_read_number(range, na); + s = of_read_number(range + na + pna, ns); + da = of_read_number(addr, na); DBG("OF: default map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da); @@ -91,7 +85,7 @@ static u64 of_bus_default_map(u32 *addr, u32 *range, int na, int ns, int pna) static int of_bus_default_translate(u32 *addr, u64 offset, int na) { - u64 a = of_read_addr(addr, na); + u64 a = of_read_number(addr, na); memset(addr, 0, na * 4); a += offset; if (na > 1) @@ -101,7 +95,7 @@ static int of_bus_default_translate(u32 *addr, u64 offset, int na) return 0; } -static unsigned int of_bus_default_get_flags(u32 *addr) +static unsigned int of_bus_default_get_flags(const u32 *addr) { return IORESOURCE_MEM; } @@ -126,7 +120,7 @@ static void of_bus_pci_count_cells(struct device_node *np, *sizec = 2; } -static u64 of_bus_pci_map(u32 *addr, u32 *range, int na, int ns, int pna) +static u64 of_bus_pci_map(u32 *addr, const u32 *range, int na, int ns, int pna) { u64 cp, s, da; @@ -135,9 +129,9 @@ static u64 of_bus_pci_map(u32 *addr, u32 *range, int na, int ns, int pna) return OF_BAD_ADDR; /* Read address values, skipping high cell */ - cp = of_read_addr(range + 1, na - 1); - s = of_read_addr(range + na + pna, ns); - da = of_read_addr(addr + 1, na - 1); + cp = of_read_number(range + 1, na - 1); + s = of_read_number(range + na + pna, ns); + da = of_read_number(addr + 1, na - 1); DBG("OF: PCI map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da); @@ -151,7 +145,7 @@ static int of_bus_pci_translate(u32 *addr, u64 offset, int na) return of_bus_default_translate(addr + 1, offset, na - 1); } -static unsigned int of_bus_pci_get_flags(u32 *addr) +static unsigned int of_bus_pci_get_flags(const u32 *addr) { unsigned int flags = 0; u32 w = addr[0]; @@ -186,7 +180,7 @@ static void of_bus_isa_count_cells(struct device_node *child, *sizec = 1; } -static u64 of_bus_isa_map(u32 *addr, u32 *range, int na, int ns, int pna) +static u64 of_bus_isa_map(u32 *addr, const u32 *range, int na, int ns, int pna) { u64 cp, s, da; @@ -195,9 +189,9 @@ static u64 of_bus_isa_map(u32 *addr, u32 *range, int na, int ns, int pna) return OF_BAD_ADDR; /* Read address values, skipping high cell */ - cp = of_read_addr(range + 1, na - 1); - s = of_read_addr(range + na + pna, ns); - da = of_read_addr(addr + 1, na - 1); + cp = of_read_number(range + 1, na - 1); + s = of_read_number(range + na + pna, ns); + da = of_read_number(addr + 1, na - 1); DBG("OF: ISA map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da); @@ -211,7 +205,7 @@ static int of_bus_isa_translate(u32 *addr, u64 offset, int na) return of_bus_default_translate(addr + 1, offset, na - 1); } -static unsigned int of_bus_isa_get_flags(u32 *addr) +static unsigned int of_bus_isa_get_flags(const u32 *addr) { unsigned int flags = 0; u32 w = addr[0]; @@ -276,7 +270,7 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus, struct of_bus *pbus, u32 *addr, int na, int ns, int pna) { - u32 *ranges; + const u32 *ranges; unsigned int rlen; int rone; u64 offset = OF_BAD_ADDR; @@ -293,9 +287,9 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus, * to translate addresses that aren't supposed to be translated in * the first place. --BenH. */ - ranges = (u32 *)get_property(parent, "ranges", &rlen); + ranges = get_property(parent, "ranges", &rlen); if (ranges == NULL || rlen == 0) { - offset = of_read_addr(addr, na); + offset = of_read_number(addr, na); memset(addr, 0, pna * 4); DBG("OF: no ranges, 1:1 translation\n"); goto finish; @@ -336,7 +330,7 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus, * that can be mapped to a cpu physical address). This is not really specified * that way, but this is traditionally the way IBM at least do things */ -u64 of_translate_address(struct device_node *dev, u32 *in_addr) +u64 of_translate_address(struct device_node *dev, const u32 *in_addr) { struct device_node *parent = NULL; struct of_bus *bus, *pbus; @@ -378,7 +372,7 @@ u64 of_translate_address(struct device_node *dev, u32 *in_addr) /* If root, we have finished */ if (parent == NULL) { DBG("OF: reached root node\n"); - result = of_read_addr(addr, na); + result = of_read_number(addr, na); break; } @@ -413,10 +407,10 @@ u64 of_translate_address(struct device_node *dev, u32 *in_addr) } EXPORT_SYMBOL(of_translate_address); -u32 *of_get_address(struct device_node *dev, int index, u64 *size, +const u32 *of_get_address(struct device_node *dev, int index, u64 *size, unsigned int *flags) { - u32 *prop; + const u32 *prop; unsigned int psize; struct device_node *parent; struct of_bus *bus; @@ -433,7 +427,7 @@ u32 *of_get_address(struct device_node *dev, int index, u64 *size, return NULL; /* Get "reg" or "assigned-addresses" property */ - prop = (u32 *)get_property(dev, bus->addresses, &psize); + prop = get_property(dev, bus->addresses, &psize); if (prop == NULL) return NULL; psize /= 4; @@ -442,7 +436,7 @@ u32 *of_get_address(struct device_node *dev, int index, u64 *size, for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++) if (i == index) { if (size) - *size = of_read_addr(prop + na, ns); + *size = of_read_number(prop + na, ns); if (flags) *flags = bus->get_flags(prop); return prop; @@ -451,10 +445,10 @@ u32 *of_get_address(struct device_node *dev, int index, u64 *size, } EXPORT_SYMBOL(of_get_address); -u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, +const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, unsigned int *flags) { - u32 *prop; + const u32 *prop; unsigned int psize; struct device_node *parent; struct of_bus *bus; @@ -475,7 +469,7 @@ u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, return NULL; /* Get "reg" or "assigned-addresses" property */ - prop = (u32 *)get_property(dev, bus->addresses, &psize); + prop = get_property(dev, bus->addresses, &psize); if (prop == NULL) return NULL; psize /= 4; @@ -484,7 +478,7 @@ u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++) if ((prop[0] & 0xff) == ((bar_no * 4) + PCI_BASE_ADDRESS_0)) { if (size) - *size = of_read_addr(prop + na, ns); + *size = of_read_number(prop + na, ns); if (flags) *flags = bus->get_flags(prop); return prop; @@ -493,7 +487,7 @@ u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, } EXPORT_SYMBOL(of_get_pci_address); -static int __of_address_to_resource(struct device_node *dev, u32 *addrp, +static int __of_address_to_resource(struct device_node *dev, const u32 *addrp, u64 size, unsigned int flags, struct resource *r) { @@ -524,7 +518,7 @@ static int __of_address_to_resource(struct device_node *dev, u32 *addrp, int of_address_to_resource(struct device_node *dev, int index, struct resource *r) { - u32 *addrp; + const u32 *addrp; u64 size; unsigned int flags; @@ -538,7 +532,7 @@ EXPORT_SYMBOL_GPL(of_address_to_resource); int of_pci_address_to_resource(struct device_node *dev, int bar, struct resource *r) { - u32 *addrp; + const u32 *addrp; u64 size; unsigned int flags; @@ -549,13 +543,14 @@ int of_pci_address_to_resource(struct device_node *dev, int bar, } EXPORT_SYMBOL_GPL(of_pci_address_to_resource); -void of_parse_dma_window(struct device_node *dn, unsigned char *dma_window_prop, +void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, unsigned long *busno, unsigned long *phys, unsigned long *size) { - u32 *dma_window, cells; - unsigned char *prop; + const u32 *dma_window; + u32 cells; + const unsigned char *prop; - dma_window = (u32 *)dma_window_prop; + dma_window = dma_window_prop; /* busno is always one cell */ *busno = *(dma_window++); @@ -565,11 +560,425 @@ void of_parse_dma_window(struct device_node *dn, unsigned char *dma_window_prop, prop = get_property(dn, "#address-cells", NULL); cells = prop ? *(u32 *)prop : prom_n_addr_cells(dn); - *phys = of_read_addr(dma_window, cells); + *phys = of_read_number(dma_window, cells); dma_window += cells; prop = get_property(dn, "ibm,#dma-size-cells", NULL); cells = prop ? *(u32 *)prop : prom_n_size_cells(dn); - *size = of_read_addr(dma_window, cells); + *size = of_read_number(dma_window, cells); +} + +/* + * Interrupt remapper + */ + +static unsigned int of_irq_workarounds; +static struct device_node *of_irq_dflt_pic; + +static struct device_node *of_irq_find_parent(struct device_node *child) +{ + struct device_node *p; + const phandle *parp; + + if (!of_node_get(child)) + return NULL; + + do { + parp = get_property(child, "interrupt-parent", NULL); + if (parp == NULL) + p = of_get_parent(child); + else { + if (of_irq_workarounds & OF_IMAP_NO_PHANDLE) + p = of_node_get(of_irq_dflt_pic); + else + p = of_find_node_by_phandle(*parp); + } + of_node_put(child); + child = p; + } while (p && get_property(p, "#interrupt-cells", NULL) == NULL); + + return p; +} + +/* This doesn't need to be called if you don't have any special workaround + * flags to pass + */ +void of_irq_map_init(unsigned int flags) +{ + of_irq_workarounds = flags; + + /* OldWorld, don't bother looking at other things */ + if (flags & OF_IMAP_OLDWORLD_MAC) + return; + + /* If we don't have phandles, let's try to locate a default interrupt + * controller (happens when booting with BootX). We do a first match + * here, hopefully, that only ever happens on machines with one + * controller. + */ + if (flags & OF_IMAP_NO_PHANDLE) { + struct device_node *np; + + for(np = NULL; (np = of_find_all_nodes(np)) != NULL;) { + if (get_property(np, "interrupt-controller", NULL) + == NULL) + continue; + /* Skip /chosen/interrupt-controller */ + if (strcmp(np->name, "chosen") == 0) + continue; + /* It seems like at least one person on this planet wants + * to use BootX on a machine with an AppleKiwi controller + * which happens to pretend to be an interrupt + * controller too. + */ + if (strcmp(np->name, "AppleKiwi") == 0) + continue; + /* I think we found one ! */ + of_irq_dflt_pic = np; + break; + } + } + +} + +int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize, + const u32 *addr, struct of_irq *out_irq) +{ + struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL; + const u32 *tmp, *imap, *imask; + u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0; + int imaplen, match, i; + + DBG("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...],ointsize=%d\n", + parent->full_name, intspec[0], intspec[1], ointsize); + + ipar = of_node_get(parent); + + /* First get the #interrupt-cells property of the current cursor + * that tells us how to interpret the passed-in intspec. If there + * is none, we are nice and just walk up the tree + */ + do { + tmp = get_property(ipar, "#interrupt-cells", NULL); + if (tmp != NULL) { + intsize = *tmp; + break; + } + tnode = ipar; + ipar = of_irq_find_parent(ipar); + of_node_put(tnode); + } while (ipar); + if (ipar == NULL) { + DBG(" -> no parent found !\n"); + goto fail; + } + + DBG("of_irq_map_raw: ipar=%s, size=%d\n", ipar->full_name, intsize); + + if (ointsize != intsize) + return -EINVAL; + + /* Look for this #address-cells. We have to implement the old linux + * trick of looking for the parent here as some device-trees rely on it + */ + old = of_node_get(ipar); + do { + tmp = get_property(old, "#address-cells", NULL); + tnode = of_get_parent(old); + of_node_put(old); + old = tnode; + } while(old && tmp == NULL); + of_node_put(old); + old = NULL; + addrsize = (tmp == NULL) ? 2 : *tmp; + + DBG(" -> addrsize=%d\n", addrsize); + + /* Now start the actual "proper" walk of the interrupt tree */ + while (ipar != NULL) { + /* Now check if cursor is an interrupt-controller and if it is + * then we are done + */ + if (get_property(ipar, "interrupt-controller", NULL) != NULL) { + DBG(" -> got it !\n"); + memcpy(out_irq->specifier, intspec, + intsize * sizeof(u32)); + out_irq->size = intsize; + out_irq->controller = ipar; + of_node_put(old); + return 0; + } + + /* Now look for an interrupt-map */ + imap = get_property(ipar, "interrupt-map", &imaplen); + /* No interrupt map, check for an interrupt parent */ + if (imap == NULL) { + DBG(" -> no map, getting parent\n"); + newpar = of_irq_find_parent(ipar); + goto skiplevel; + } + imaplen /= sizeof(u32); + + /* Look for a mask */ + imask = get_property(ipar, "interrupt-map-mask", NULL); + + /* If we were passed no "reg" property and we attempt to parse + * an interrupt-map, then #address-cells must be 0. + * Fail if it's not. + */ + if (addr == NULL && addrsize != 0) { + DBG(" -> no reg passed in when needed !\n"); + goto fail; + } + + /* Parse interrupt-map */ + match = 0; + while (imaplen > (addrsize + intsize + 1) && !match) { + /* Compare specifiers */ + match = 1; + for (i = 0; i < addrsize && match; ++i) { + u32 mask = imask ? imask[i] : 0xffffffffu; + match = ((addr[i] ^ imap[i]) & mask) == 0; + } + for (; i < (addrsize + intsize) && match; ++i) { + u32 mask = imask ? imask[i] : 0xffffffffu; + match = + ((intspec[i-addrsize] ^ imap[i]) & mask) == 0; + } + imap += addrsize + intsize; + imaplen -= addrsize + intsize; + + DBG(" -> match=%d (imaplen=%d)\n", match, imaplen); + + /* Get the interrupt parent */ + if (of_irq_workarounds & OF_IMAP_NO_PHANDLE) + newpar = of_node_get(of_irq_dflt_pic); + else + newpar = of_find_node_by_phandle((phandle)*imap); + imap++; + --imaplen; + + /* Check if not found */ + if (newpar == NULL) { + DBG(" -> imap parent not found !\n"); + goto fail; + } + + /* Get #interrupt-cells and #address-cells of new + * parent + */ + tmp = get_property(newpar, "#interrupt-cells", + NULL); + if (tmp == NULL) { + DBG(" -> parent lacks #interrupt-cells !\n"); + goto fail; + } + newintsize = *tmp; + tmp = get_property(newpar, "#address-cells", + NULL); + newaddrsize = (tmp == NULL) ? 0 : *tmp; + + DBG(" -> newintsize=%d, newaddrsize=%d\n", + newintsize, newaddrsize); + + /* Check for malformed properties */ + if (imaplen < (newaddrsize + newintsize)) + goto fail; + + imap += newaddrsize + newintsize; + imaplen -= newaddrsize + newintsize; + + DBG(" -> imaplen=%d\n", imaplen); + } + if (!match) + goto fail; + + of_node_put(old); + old = of_node_get(newpar); + addrsize = newaddrsize; + intsize = newintsize; + intspec = imap - intsize; + addr = intspec - addrsize; + + skiplevel: + /* Iterate again with new parent */ + DBG(" -> new parent: %s\n", newpar ? newpar->full_name : "<>"); + of_node_put(ipar); + ipar = newpar; + newpar = NULL; + } + fail: + of_node_put(ipar); + of_node_put(old); + of_node_put(newpar); + + return -EINVAL; +} +EXPORT_SYMBOL_GPL(of_irq_map_raw); + +#if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32) +static int of_irq_map_oldworld(struct device_node *device, int index, + struct of_irq *out_irq) +{ + const u32 *ints; + int intlen; + + /* + * Old machines just have a list of interrupt numbers + * and no interrupt-controller nodes. + */ + ints = get_property(device, "AAPL,interrupts", &intlen); + if (ints == NULL) + return -EINVAL; + intlen /= sizeof(u32); + + if (index >= intlen) + return -EINVAL; + + out_irq->controller = NULL; + out_irq->specifier[0] = ints[index]; + out_irq->size = 1; + + return 0; +} +#else /* defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32) */ +static int of_irq_map_oldworld(struct device_node *device, int index, + struct of_irq *out_irq) +{ + return -EINVAL; +} +#endif /* !(defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32)) */ + +int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq) +{ + struct device_node *p; + const u32 *intspec, *tmp, *addr; + u32 intsize, intlen; + int res; + + DBG("of_irq_map_one: dev=%s, index=%d\n", device->full_name, index); + + /* OldWorld mac stuff is "special", handle out of line */ + if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC) + return of_irq_map_oldworld(device, index, out_irq); + + /* Get the interrupts property */ + intspec = get_property(device, "interrupts", &intlen); + if (intspec == NULL) + return -EINVAL; + intlen /= sizeof(u32); + + /* Get the reg property (if any) */ + addr = get_property(device, "reg", NULL); + + /* Look for the interrupt parent. */ + p = of_irq_find_parent(device); + if (p == NULL) + return -EINVAL; + + /* Get size of interrupt specifier */ + tmp = get_property(p, "#interrupt-cells", NULL); + if (tmp == NULL) { + of_node_put(p); + return -EINVAL; + } + intsize = *tmp; + + DBG(" intsize=%d intlen=%d\n", intsize, intlen); + + /* Check index */ + if ((index + 1) * intsize > intlen) + return -EINVAL; + + /* Get new specifier and map it */ + res = of_irq_map_raw(p, intspec + index * intsize, intsize, + addr, out_irq); + of_node_put(p); + return res; +} +EXPORT_SYMBOL_GPL(of_irq_map_one); + +#ifdef CONFIG_PCI +static u8 of_irq_pci_swizzle(u8 slot, u8 pin) +{ + return (((pin - 1) + slot) % 4) + 1; +} + +int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq) +{ + struct device_node *dn, *ppnode; + struct pci_dev *ppdev; + u32 lspec; + u32 laddr[3]; + u8 pin; + int rc; + + /* Check if we have a device node, if yes, fallback to standard OF + * parsing + */ + dn = pci_device_to_OF_node(pdev); + if (dn) + return of_irq_map_one(dn, 0, out_irq); + + /* Ok, we don't, time to have fun. Let's start by building up an + * interrupt spec. we assume #interrupt-cells is 1, which is standard + * for PCI. If you do different, then don't use that routine. + */ + rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin); + if (rc != 0) + return rc; + /* No pin, exit */ + if (pin == 0) + return -ENODEV; + + /* Now we walk up the PCI tree */ + lspec = pin; + for (;;) { + /* Get the pci_dev of our parent */ + ppdev = pdev->bus->self; + + /* Ouch, it's a host bridge... */ + if (ppdev == NULL) { +#ifdef CONFIG_PPC64 + ppnode = pci_bus_to_OF_node(pdev->bus); +#else + struct pci_controller *host; + host = pci_bus_to_host(pdev->bus); + ppnode = host ? host->arch_data : NULL; +#endif + /* No node for host bridge ? give up */ + if (ppnode == NULL) + return -EINVAL; + } else + /* We found a P2P bridge, check if it has a node */ + ppnode = pci_device_to_OF_node(ppdev); + + /* Ok, we have found a parent with a device-node, hand over to + * the OF parsing code. + * We build a unit address from the linux device to be used for + * resolution. Note that we use the linux bus number which may + * not match your firmware bus numbering. + * Fortunately, in most cases, interrupt-map-mask doesn't include + * the bus number as part of the matching. + * You should still be careful about that though if you intend + * to rely on this function (you ship a firmware that doesn't + * create device nodes for all PCI devices). + */ + if (ppnode) + break; + + /* We can only get here if we hit a P2P bridge with no node, + * let's do standard swizzling and try again + */ + lspec = of_irq_pci_swizzle(PCI_SLOT(pdev->devfn), lspec); + pdev = ppdev; + } + + laddr[0] = (pdev->bus->number << 16) + | (pdev->devfn << 8); + laddr[1] = laddr[2] = 0; + return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq); } +EXPORT_SYMBOL_GPL(of_irq_map_pci); +#endif /* CONFIG_PCI */ diff --git a/arch/powerpc/kernel/ptrace-common.h b/arch/powerpc/kernel/ptrace-common.h index c42a860c8d25..8797ae737a7b 100644 --- a/arch/powerpc/kernel/ptrace-common.h +++ b/arch/powerpc/kernel/ptrace-common.h @@ -10,7 +10,6 @@ #ifndef _PPC64_PTRACE_COMMON_H #define _PPC64_PTRACE_COMMON_H -#include <linux/config.h> #include <asm/system.h> /* diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index 5563e2e7d89c..dea75d73f983 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c @@ -15,7 +15,6 @@ * this archive for more details. */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/mm.h> diff --git a/arch/powerpc/kernel/ptrace32.c b/arch/powerpc/kernel/ptrace32.c index 826ee3d056de..9b9a230349bc 100644 --- a/arch/powerpc/kernel/ptrace32.c +++ b/arch/powerpc/kernel/ptrace32.c @@ -17,7 +17,6 @@ * this archive for more details. */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/mm.h> diff --git a/arch/powerpc/kernel/rtas-proc.c b/arch/powerpc/kernel/rtas-proc.c index 9c9ad1fa9cce..2fe82abf1c52 100644 --- a/arch/powerpc/kernel/rtas-proc.c +++ b/arch/powerpc/kernel/rtas-proc.c @@ -246,12 +246,12 @@ struct file_operations ppc_rtas_rmo_buf_ops = { static int ppc_rtas_find_all_sensors(void); static void ppc_rtas_process_sensor(struct seq_file *m, - struct individual_sensor *s, int state, int error, char *loc); + struct individual_sensor *s, int state, int error, const char *loc); static char *ppc_rtas_process_error(int error); static void get_location_code(struct seq_file *m, - struct individual_sensor *s, char *loc); -static void check_location_string(struct seq_file *m, char *c); -static void check_location(struct seq_file *m, char *c); + struct individual_sensor *s, const char *loc); +static void check_location_string(struct seq_file *m, const char *c); +static void check_location(struct seq_file *m, const char *c); static int __init proc_rtas_init(void) { @@ -446,11 +446,11 @@ static int ppc_rtas_sensors_show(struct seq_file *m, void *v) for (i=0; i<sensors.quant; i++) { struct individual_sensor *p = &sensors.sensor[i]; char rstr[64]; - char *loc; + const char *loc; int llen, offs; sprintf (rstr, SENSOR_PREFIX"%04d", p->token); - loc = (char *) get_property(rtas_node, rstr, &llen); + loc = get_property(rtas_node, rstr, &llen); /* A sensor may have multiple instances */ for (j = 0, offs = 0; j <= p->quant; j++) { @@ -474,10 +474,10 @@ static int ppc_rtas_sensors_show(struct seq_file *m, void *v) static int ppc_rtas_find_all_sensors(void) { - unsigned int *utmp; + const unsigned int *utmp; int len, i; - utmp = (unsigned int *) get_property(rtas_node, "rtas-sensors", &len); + utmp = get_property(rtas_node, "rtas-sensors", &len); if (utmp == NULL) { printk (KERN_ERR "error: could not get rtas-sensors\n"); return 1; @@ -530,7 +530,7 @@ static char *ppc_rtas_process_error(int error) */ static void ppc_rtas_process_sensor(struct seq_file *m, - struct individual_sensor *s, int state, int error, char *loc) + struct individual_sensor *s, int state, int error, const char *loc) { /* Defined return vales */ const char * key_switch[] = { "Off\t", "Normal\t", "Secure\t", @@ -682,7 +682,7 @@ static void ppc_rtas_process_sensor(struct seq_file *m, /* ****************************************************************** */ -static void check_location(struct seq_file *m, char *c) +static void check_location(struct seq_file *m, const char *c) { switch (c[0]) { case LOC_PLANAR: @@ -719,7 +719,7 @@ static void check_location(struct seq_file *m, char *c) * ${LETTER}${NUMBER}[[-/]${LETTER}${NUMBER} [ ... ] ] * the '.' may be an abbrevation */ -static void check_location_string(struct seq_file *m, char *c) +static void check_location_string(struct seq_file *m, const char *c) { while (*c) { if (isalpha(*c) || *c == '.') @@ -733,7 +733,8 @@ static void check_location_string(struct seq_file *m, char *c) /* ****************************************************************** */ -static void get_location_code(struct seq_file *m, struct individual_sensor *s, char *loc) +static void get_location_code(struct seq_file *m, struct individual_sensor *s, + const char *loc) { if (!loc || !*loc) { seq_printf(m, "---");/* does not have a location */ diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index 17dc79198515..6ef80d4e38d3 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c @@ -38,16 +38,19 @@ struct rtas_t rtas = { .lock = SPIN_LOCK_UNLOCKED }; +EXPORT_SYMBOL(rtas); struct rtas_suspend_me_data { long waiting; struct rtas_args *args; }; -EXPORT_SYMBOL(rtas); - DEFINE_SPINLOCK(rtas_data_buf_lock); +EXPORT_SYMBOL(rtas_data_buf_lock); + char rtas_data_buf[RTAS_DATA_BUF_SIZE] __cacheline_aligned; +EXPORT_SYMBOL(rtas_data_buf); + unsigned long rtas_rmo_buf; /* @@ -106,18 +109,80 @@ static void call_rtas_display_status_delay(char c) } } -void __init udbg_init_rtas(void) +void __init udbg_init_rtas_panel(void) { udbg_putc = call_rtas_display_status_delay; } +#ifdef CONFIG_UDBG_RTAS_CONSOLE + +/* If you think you're dying before early_init_dt_scan_rtas() does its + * work, you can hard code the token values for your firmware here and + * hardcode rtas.base/entry etc. + */ +static unsigned int rtas_putchar_token = RTAS_UNKNOWN_SERVICE; +static unsigned int rtas_getchar_token = RTAS_UNKNOWN_SERVICE; + +static void udbg_rtascon_putc(char c) +{ + int tries; + + if (!rtas.base) + return; + + /* Add CRs before LFs */ + if (c == '\n') + udbg_rtascon_putc('\r'); + + /* if there is more than one character to be displayed, wait a bit */ + for (tries = 0; tries < 16; tries++) { + if (rtas_call(rtas_putchar_token, 1, 1, NULL, c) == 0) + break; + udelay(1000); + } +} + +static int udbg_rtascon_getc_poll(void) +{ + int c; + + if (!rtas.base) + return -1; + + if (rtas_call(rtas_getchar_token, 0, 2, &c)) + return -1; + + return c; +} + +static int udbg_rtascon_getc(void) +{ + int c; + + while ((c = udbg_rtascon_getc_poll()) == -1) + ; + + return c; +} + + +void __init udbg_init_rtas_console(void) +{ + udbg_putc = udbg_rtascon_putc; + udbg_getc = udbg_rtascon_getc; + udbg_getc_poll = udbg_rtascon_getc_poll; +} +#endif /* CONFIG_UDBG_RTAS_CONSOLE */ + void rtas_progress(char *s, unsigned short hex) { struct device_node *root; - int width, *p; + int width; + const int *p; char *os; static int display_character, set_indicator; - static int display_width, display_lines, *row_width, form_feed; + static int display_width, display_lines, form_feed; + const static int *row_width; static DEFINE_SPINLOCK(progress_lock); static int current_line; static int pending_newline = 0; /* did last write end with unprinted newline? */ @@ -128,16 +193,16 @@ void rtas_progress(char *s, unsigned short hex) if (display_width == 0) { display_width = 0x10; if ((root = find_path_device("/rtas"))) { - if ((p = (unsigned int *)get_property(root, + if ((p = get_property(root, "ibm,display-line-length", NULL))) display_width = *p; - if ((p = (unsigned int *)get_property(root, + if ((p = get_property(root, "ibm,form-feed", NULL))) form_feed = *p; - if ((p = (unsigned int *)get_property(root, + if ((p = get_property(root, "ibm,display-number-of-lines", NULL))) display_lines = *p; - row_width = (unsigned int *)get_property(root, + row_width = get_property(root, "ibm,display-truncation-length", NULL); } display_character = rtas_token("display-character"); @@ -230,12 +295,13 @@ EXPORT_SYMBOL(rtas_progress); /* needed by rtas_flash module */ int rtas_token(const char *service) { - int *tokp; + const int *tokp; if (rtas.dev == NULL) return RTAS_UNKNOWN_SERVICE; - tokp = (int *) get_property(rtas.dev, service, NULL); + tokp = get_property(rtas.dev, service, NULL); return tokp ? *tokp : RTAS_UNKNOWN_SERVICE; } +EXPORT_SYMBOL(rtas_token); #ifdef CONFIG_RTAS_ERROR_LOGGING /* @@ -328,7 +394,7 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...) char *buff_copy = NULL; int ret; - if (token == RTAS_UNKNOWN_SERVICE) + if (!rtas.entry || token == RTAS_UNKNOWN_SERVICE) return -1; /* Gotta do something different here, use global lock for now... */ @@ -369,6 +435,7 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...) } return ret; } +EXPORT_SYMBOL(rtas_call); /* For RTAS_BUSY (-2), delay for 1 millisecond. For an extended busy status * code of 990n, perform the hinted delay of 10^n (last digit) milliseconds. @@ -388,6 +455,7 @@ unsigned int rtas_busy_delay_time(int status) return ms; } +EXPORT_SYMBOL(rtas_busy_delay_time); /* For an RTAS busy status code, perform the hinted delay. */ unsigned int rtas_busy_delay(int status) @@ -401,6 +469,7 @@ unsigned int rtas_busy_delay(int status) return ms; } +EXPORT_SYMBOL(rtas_busy_delay); int rtas_error_rc(int rtas_rc) { @@ -446,6 +515,7 @@ int rtas_get_power_level(int powerdomain, int *level) return rtas_error_rc(rc); return rc; } +EXPORT_SYMBOL(rtas_get_power_level); int rtas_set_power_level(int powerdomain, int level, int *setlevel) { @@ -463,6 +533,7 @@ int rtas_set_power_level(int powerdomain, int level, int *setlevel) return rtas_error_rc(rc); return rc; } +EXPORT_SYMBOL(rtas_set_power_level); int rtas_get_sensor(int sensor, int index, int *state) { @@ -480,6 +551,7 @@ int rtas_get_sensor(int sensor, int index, int *state) return rtas_error_rc(rc); return rc; } +EXPORT_SYMBOL(rtas_get_sensor); int rtas_set_indicator(int indicator, int index, int new_value) { @@ -497,6 +569,28 @@ int rtas_set_indicator(int indicator, int index, int new_value) return rtas_error_rc(rc); return rc; } +EXPORT_SYMBOL(rtas_set_indicator); + +/* + * Ignoring RTAS extended delay + */ +int rtas_set_indicator_fast(int indicator, int index, int new_value) +{ + int rc; + int token = rtas_token("set-indicator"); + + if (token == RTAS_UNKNOWN_SERVICE) + return -ENOENT; + + rc = rtas_call(token, 3, 1, NULL, indicator, index, new_value); + + WARN_ON(rc == -2 || (rc >= 9900 && rc <= 9905)); + + if (rc < 0) + return rtas_error_rc(rc); + + return rc; +} void rtas_restart(char *cmd) { @@ -534,6 +628,9 @@ void rtas_os_term(char *str) { int status; + if (panic_timeout) + return; + if (RTAS_UNKNOWN_SERVICE == rtas_token("ibm,os-term")) return; @@ -595,15 +692,14 @@ static int rtas_ibm_suspend_me(struct rtas_args *args) int i; long state; long rc; - unsigned long dummy; - + unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; struct rtas_suspend_me_data data; /* Make sure the state is valid */ - rc = plpar_hcall(H_VASI_STATE, - ((u64)args->args[0] << 32) | args->args[1], - 0, 0, 0, - &state, &dummy, &dummy); + rc = plpar_hcall(H_VASI_STATE, retbuf, + ((u64)args->args[0] << 32) | args->args[1]); + + state = retbuf[0]; if (rc) { printk(KERN_ERR "rtas_ibm_suspend_me: vasi_state returned %ld\n",rc); @@ -753,15 +849,15 @@ void __init rtas_initialize(void) */ rtas.dev = of_find_node_by_name(NULL, "rtas"); if (rtas.dev) { - u32 *basep, *entryp; - u32 *sizep; + const u32 *basep, *entryp, *sizep; - basep = (u32 *)get_property(rtas.dev, "linux,rtas-base", NULL); - sizep = (u32 *)get_property(rtas.dev, "rtas-size", NULL); + basep = get_property(rtas.dev, "linux,rtas-base", NULL); + sizep = get_property(rtas.dev, "rtas-size", NULL); if (basep != NULL && sizep != NULL) { rtas.base = *basep; rtas.size = *sizep; - entryp = (u32 *)get_property(rtas.dev, "linux,rtas-entry", NULL); + entryp = get_property(rtas.dev, + "linux,rtas-entry", NULL); if (entryp == NULL) /* Ugh */ rtas.entry = rtas.base; else @@ -791,14 +887,39 @@ void __init rtas_initialize(void) #endif } +int __init early_init_dt_scan_rtas(unsigned long node, + const char *uname, int depth, void *data) +{ + u32 *basep, *entryp, *sizep; -EXPORT_SYMBOL(rtas_token); -EXPORT_SYMBOL(rtas_call); -EXPORT_SYMBOL(rtas_data_buf); -EXPORT_SYMBOL(rtas_data_buf_lock); -EXPORT_SYMBOL(rtas_busy_delay_time); -EXPORT_SYMBOL(rtas_busy_delay); -EXPORT_SYMBOL(rtas_get_sensor); -EXPORT_SYMBOL(rtas_get_power_level); -EXPORT_SYMBOL(rtas_set_power_level); -EXPORT_SYMBOL(rtas_set_indicator); + if (depth != 1 || strcmp(uname, "rtas") != 0) + return 0; + + basep = of_get_flat_dt_prop(node, "linux,rtas-base", NULL); + entryp = of_get_flat_dt_prop(node, "linux,rtas-entry", NULL); + sizep = of_get_flat_dt_prop(node, "rtas-size", NULL); + + if (basep && entryp && sizep) { + rtas.base = *basep; + rtas.entry = *entryp; + rtas.size = *sizep; + } + +#ifdef CONFIG_UDBG_RTAS_CONSOLE + basep = of_get_flat_dt_prop(node, "put-term-char", NULL); + if (basep) + rtas_putchar_token = *basep; + + basep = of_get_flat_dt_prop(node, "get-term-char", NULL); + if (basep) + rtas_getchar_token = *basep; + + if (rtas_putchar_token != RTAS_UNKNOWN_SERVICE && + rtas_getchar_token != RTAS_UNKNOWN_SERVICE) + udbg_init_rtas_console(); + +#endif + + /* break now */ + return 1; +} diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c index 6eb7e49b394a..b4a0de79c060 100644 --- a/arch/powerpc/kernel/rtas_pci.c +++ b/arch/powerpc/kernel/rtas_pci.c @@ -57,7 +57,7 @@ static inline int config_access_valid(struct pci_dn *dn, int where) static int of_device_available(struct device_node * dn) { - char * status; + const char *status; status = get_property(dn, "status", NULL); @@ -81,8 +81,7 @@ int rtas_read_config(struct pci_dn *pdn, int where, int size, u32 *val) if (!config_access_valid(pdn, where)) return PCIBIOS_BAD_REGISTER_NUMBER; - addr = ((where & 0xf00) << 20) | (pdn->busno << 16) | - (pdn->devfn << 8) | (where & 0xff); + addr = rtas_config_addr(pdn->busno, pdn->devfn, where); buid = pdn->phb->buid; if (buid) { ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval, @@ -134,8 +133,7 @@ int rtas_write_config(struct pci_dn *pdn, int where, int size, u32 val) if (!config_access_valid(pdn, where)) return PCIBIOS_BAD_REGISTER_NUMBER; - addr = ((where & 0xf00) << 20) | (pdn->busno << 16) | - (pdn->devfn << 8) | (where & 0xff); + addr = rtas_config_addr(pdn->busno, pdn->devfn, where); buid = pdn->phb->buid; if (buid) { ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr, @@ -178,7 +176,7 @@ struct pci_ops rtas_pci_ops = { int is_python(struct device_node *dev) { - char *model = (char *)get_property(dev, "model", NULL); + const char *model = get_property(dev, "model", NULL); if (model && strstr(model, "Python")) return 1; @@ -234,7 +232,7 @@ void __init init_pci_config_tokens (void) unsigned long __devinit get_phb_buid (struct device_node *phb) { int addr_cells; - unsigned int *buid_vals; + const unsigned int *buid_vals; unsigned int len; unsigned long buid; @@ -247,7 +245,7 @@ unsigned long __devinit get_phb_buid (struct device_node *phb) if (phb->parent->parent) return 0; - buid_vals = (unsigned int *) get_property(phb, "reg", &len); + buid_vals = get_property(phb, "reg", &len); if (buid_vals == NULL) return 0; @@ -264,10 +262,10 @@ unsigned long __devinit get_phb_buid (struct device_node *phb) static int phb_set_bus_ranges(struct device_node *dev, struct pci_controller *phb) { - int *bus_range; + const int *bus_range; unsigned int len; - bus_range = (int *) get_property(dev, "bus-range", &len); + bus_range = get_property(dev, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) { return 1; } @@ -297,19 +295,9 @@ unsigned long __init find_and_init_phbs(void) struct device_node *node; struct pci_controller *phb; unsigned int index; - unsigned int root_size_cells = 0; - unsigned int *opprop = NULL; struct device_node *root = of_find_node_by_path("/"); - if (ppc64_interrupt_controller == IC_OPEN_PIC) { - opprop = (unsigned int *)get_property(root, - "platform-open-pic", NULL); - } - - root_size_cells = prom_n_size_cells(root); - index = 0; - for (node = of_get_next_child(root, NULL); node != NULL; node = of_get_next_child(root, node)) { @@ -324,13 +312,6 @@ unsigned long __init find_and_init_phbs(void) setup_phb(node, phb); pci_process_bridge_OF_ranges(phb, node, 0); pci_setup_phb_io(phb, index == 0); -#ifdef CONFIG_PPC_PSERIES - /* XXX This code need serious fixing ... --BenH */ - if (ppc64_interrupt_controller == IC_OPEN_PIC && pSeries_mpic) { - int addr = root_size_cells * (index + 2) - 1; - mpic_assign_isu(pSeries_mpic, index, opprop[addr]); - } -#endif index++; } @@ -342,15 +323,15 @@ unsigned long __init find_and_init_phbs(void) * in chosen. */ if (of_chosen) { - int *prop; + const int *prop; - prop = (int *)get_property(of_chosen, "linux,pci-probe-only", - NULL); + prop = get_property(of_chosen, + "linux,pci-probe-only", NULL); if (prop) pci_probe_only = *prop; - prop = (int *)get_property(of_chosen, - "linux,pci-assign-all-buses", NULL); + prop = get_property(of_chosen, + "linux,pci-assign-all-buses", NULL); if (prop) pci_assign_all_buses = *prop; } diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index bd328123af75..0af3fc1bdcc9 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c @@ -12,7 +12,6 @@ #undef DEBUG -#include <linux/config.h> #include <linux/module.h> #include <linux/string.h> #include <linux/sched.h> @@ -27,7 +26,7 @@ #include <linux/ioport.h> #include <linux/console.h> #include <linux/utsname.h> -#include <linux/tty.h> +#include <linux/screen_info.h> #include <linux/root_dev.h> #include <linux/notifier.h> #include <linux/cpu.h> @@ -305,19 +304,21 @@ struct seq_operations cpuinfo_op = { void __init check_for_initrd(void) { #ifdef CONFIG_BLK_DEV_INITRD - unsigned long *prop; + const unsigned int *prop; + int len; DBG(" -> check_for_initrd()\n"); if (of_chosen) { - prop = (unsigned long *)get_property(of_chosen, - "linux,initrd-start", NULL); + prop = get_property(of_chosen, "linux,initrd-start", &len); if (prop != NULL) { - initrd_start = (unsigned long)__va(*prop); - prop = (unsigned long *)get_property(of_chosen, - "linux,initrd-end", NULL); + initrd_start = (unsigned long) + __va(of_read_ulong(prop, len / 4)); + prop = get_property(of_chosen, + "linux,initrd-end", &len); if (prop != NULL) { - initrd_end = (unsigned long)__va(*prop); + initrd_end = (unsigned long) + __va(of_read_ulong(prop, len / 4)); initrd_below_start_ok = 1; } else initrd_start = 0; @@ -367,15 +368,14 @@ void __init smp_setup_cpu_maps(void) int cpu = 0; while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) { - int *intserv; + const int *intserv; int j, len = sizeof(u32), nthreads = 1; - intserv = (int *)get_property(dn, "ibm,ppc-interrupt-server#s", - &len); + intserv = get_property(dn, "ibm,ppc-interrupt-server#s", &len); if (intserv) nthreads = len / sizeof(int); else { - intserv = (int *) get_property(dn, "reg", NULL); + intserv = get_property(dn, "reg", NULL); if (!intserv) intserv = &cpu; /* assume logical == phys */ } @@ -396,13 +396,12 @@ void __init smp_setup_cpu_maps(void) if (machine_is(pseries) && firmware_has_feature(FW_FEATURE_LPAR) && (dn = of_find_node_by_path("/rtas"))) { int num_addr_cell, num_size_cell, maxcpus; - unsigned int *ireg; + const unsigned int *ireg; num_addr_cell = prom_n_addr_cells(dn); num_size_cell = prom_n_size_cells(dn); - ireg = (unsigned int *) - get_property(dn, "ibm,lrdr-capacity", NULL); + ireg = get_property(dn, "ibm,lrdr-capacity", NULL); if (!ireg) goto out; @@ -445,6 +444,8 @@ void __init smp_setup_cpu_maps(void) int __initdata do_early_xmon; #ifdef CONFIG_XMON +extern int xmon_no_auto_backtrace; + static int __init early_xmon(char *p) { /* ensure xmon is enabled */ @@ -453,6 +454,8 @@ static int __init early_xmon(char *p) xmon_init(1); if (strncmp(p, "off", 3) == 0) xmon_init(0); + if (strncmp(p, "nobt", 4) == 0) + xmon_no_auto_backtrace = 1; if (strncmp(p, "early", 5) != 0) return 0; } diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index e5a44812441a..e0df2ba1ab9f 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -2,7 +2,6 @@ * Common prep/pmac/chrp boot and setup code. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/string.h> #include <linux/sched.h> @@ -52,7 +51,6 @@ extern void bootx_init(unsigned long r4, unsigned long phys); -boot_infos_t *boot_infos; struct ide_machdep_calls ppc_ide_md; int boot_cpuid; @@ -215,7 +213,7 @@ int __init ppc_init(void) /* register CPU devices */ for_each_possible_cpu(i) - register_cpu(&cpu_devices[i], i, NULL); + register_cpu(&cpu_devices[i], i); /* call platform init */ if (ppc_md.init != NULL) { @@ -241,7 +239,6 @@ void __init setup_arch(char **cmdline_p) ppc_md.init_early(); find_legacy_serial_ports(); - finish_device_tree(); smp_setup_cpu_maps(); diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 78f3a5fd43f6..00d6b8addd78 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -12,7 +12,6 @@ #undef DEBUG -#include <linux/config.h> #include <linux/module.h> #include <linux/string.h> #include <linux/sched.h> @@ -57,7 +56,6 @@ #include <asm/page.h> #include <asm/mmu.h> #include <asm/lmb.h> -#include <asm/iseries/it_lp_naca.h> #include <asm/firmware.h> #include <asm/xmon.h> #include <asm/udbg.h> @@ -80,10 +78,10 @@ u64 ppc64_pft_size; * before we've read this from the device tree. */ struct ppc64_caches ppc64_caches = { - .dline_size = 0x80, - .log_dline_size = 7, - .iline_size = 0x80, - .log_iline_size = 7 + .dline_size = 0x40, + .log_dline_size = 6, + .iline_size = 0x40, + .log_iline_size = 6 }; EXPORT_SYMBOL_GPL(ppc64_caches); @@ -108,7 +106,7 @@ static int smt_enabled_cmdline; static void check_smt_enabled(void) { struct device_node *dn; - char *smt_option; + const char *smt_option; /* Allow the command line to overrule the OF option */ if (smt_enabled_cmdline) @@ -117,7 +115,7 @@ static void check_smt_enabled(void) dn = of_find_node_by_path("/options"); if (dn) { - smt_option = (char *)get_property(dn, "ibm,smt-enabled", NULL); + smt_option = get_property(dn, "ibm,smt-enabled", NULL); if (smt_option) { if (!strcmp(smt_option, "on")) @@ -149,6 +147,13 @@ early_param("smt-enabled", early_smt_enabled); #define check_smt_enabled() #endif /* CONFIG_SMP */ +/* Put the paca pointer into r13 and SPRG3 */ +void __init setup_paca(int cpu) +{ + local_paca = &paca[cpu]; + mtspr(SPRN_SPRG3, local_paca); +} + /* * Early initialization entry point. This is called by head.S * with MMU translation disabled. We rely on the "feature" of @@ -170,6 +175,9 @@ early_param("smt-enabled", early_smt_enabled); void __init early_setup(unsigned long dt_ptr) { + /* Assume we're on cpu 0 for now. Don't write to the paca yet! */ + setup_paca(0); + /* Enable early debugging if any specified (see udbg.h) */ udbg_early_init(); @@ -183,7 +191,7 @@ void __init early_setup(unsigned long dt_ptr) early_init_devtree(__va(dt_ptr)); /* Now we know the logical id of our boot cpu, setup the paca. */ - setup_boot_paca(); + setup_paca(boot_cpuid); /* Fix up paca fields required for the boot cpu */ get_paca()->cpu_start = 1; @@ -284,7 +292,7 @@ static void __init initialize_cache_info(void) */ if ( num_cpus == 1 ) { - u32 *sizep, *lsizep; + const u32 *sizep, *lsizep; u32 size, lsize; const char *dc, *ic; @@ -299,10 +307,10 @@ static void __init initialize_cache_info(void) size = 0; lsize = cur_cpu_spec->dcache_bsize; - sizep = (u32 *)get_property(np, "d-cache-size", NULL); + sizep = get_property(np, "d-cache-size", NULL); if (sizep != NULL) size = *sizep; - lsizep = (u32 *) get_property(np, dc, NULL); + lsizep = get_property(np, dc, NULL); if (lsizep != NULL) lsize = *lsizep; if (sizep == 0 || lsizep == 0) @@ -316,10 +324,10 @@ static void __init initialize_cache_info(void) size = 0; lsize = cur_cpu_spec->icache_bsize; - sizep = (u32 *)get_property(np, "i-cache-size", NULL); + sizep = get_property(np, "i-cache-size", NULL); if (sizep != NULL) size = *sizep; - lsizep = (u32 *)get_property(np, ic, NULL); + lsizep = get_property(np, ic, NULL); if (lsizep != NULL) lsize = *lsizep; if (sizep == 0 || lsizep == 0) @@ -350,22 +358,17 @@ void __init setup_system(void) */ unflatten_device_tree(); -#ifdef CONFIG_KEXEC - kexec_setup(); /* requires unflattened device tree. */ -#endif - /* * Fill the ppc64_caches & systemcfg structures with informations - * retrieved from the device-tree. Need to be called before - * finish_device_tree() since the later requires some of the - * informations filled up here to properly parse the interrupt - * tree. - * It also sets up the cache line sizes which allows to call - * routines like flush_icache_range (used by the hash init - * later on). + * retrieved from the device-tree. */ initialize_cache_info(); + /* + * Initialize irq remapping subsystem + */ + irq_early_init(); + #ifdef CONFIG_PPC_RTAS /* * Initialize RTAS if available @@ -393,12 +396,6 @@ void __init setup_system(void) find_legacy_serial_ports(); /* - * "Finish" the device-tree, that is do the actual parsing of - * some of the properties like the interrupt map - */ - finish_device_tree(); - - /* * Initialize xmon */ #ifdef CONFIG_XMON_DEFAULT @@ -426,8 +423,6 @@ void __init setup_system(void) printk("-----------------------------------------------------\n"); printk("ppc64_pft_size = 0x%lx\n", ppc64_pft_size); - printk("ppc64_interrupt_controller = 0x%ld\n", - ppc64_interrupt_controller); printk("physicalMemorySize = 0x%lx\n", lmb_phys_mem_size()); printk("ppc64_caches.dcache_line_size = 0x%x\n", ppc64_caches.dline_size); diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index d73b25e22fca..320353f0926f 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -17,7 +17,6 @@ * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <linux/sched.h> #include <linux/mm.h> #include <linux/smp.h> diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index 6e75d7ab6d4d..f72e8e823d78 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -12,7 +12,6 @@ * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <linux/sched.h> #include <linux/mm.h> #include <linux/smp.h> diff --git a/arch/powerpc/kernel/smp-tbsync.c b/arch/powerpc/kernel/smp-tbsync.c index 9adef3bddad4..de59c6c31a5b 100644 --- a/arch/powerpc/kernel/smp-tbsync.c +++ b/arch/powerpc/kernel/smp-tbsync.c @@ -5,7 +5,6 @@ * */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/smp.h> @@ -46,8 +45,9 @@ void __devinit smp_generic_take_timebase(void) { int cmd; u64 tb; + unsigned long flags; - local_irq_disable(); + local_irq_save(flags); while (!running) barrier(); rmb(); @@ -71,7 +71,7 @@ void __devinit smp_generic_take_timebase(void) set_tb(tb >> 32, tb & 0xfffffffful); enter_contest(tbsync->mark, -1); } - local_irq_enable(); + local_irq_restore(flags); } static int __devinit start_contest(int cmd, long offset, int num) diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index c5d179d4f818..6a9bc9ce54e0 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -17,7 +17,6 @@ #undef DEBUG -#include <linux/config.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/sched.h> @@ -145,13 +144,15 @@ void smp_message_recv(int msg, struct pt_regs *regs) void smp_send_reschedule(int cpu) { - smp_ops->message_pass(cpu, PPC_MSG_RESCHEDULE); + if (likely(smp_ops)) + smp_ops->message_pass(cpu, PPC_MSG_RESCHEDULE); } #ifdef CONFIG_DEBUGGER void smp_send_debugger_break(int cpu) { - smp_ops->message_pass(cpu, PPC_MSG_DEBUGGER_BREAK); + if (likely(smp_ops)) + smp_ops->message_pass(cpu, PPC_MSG_DEBUGGER_BREAK); } #endif @@ -159,7 +160,7 @@ void smp_send_debugger_break(int cpu) void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *)) { crash_ipi_function_ptr = crash_ipi_callback; - if (crash_ipi_callback) { + if (crash_ipi_callback && smp_ops) { mb(); smp_ops->message_pass(MSG_ALL_BUT_SELF, PPC_MSG_DEBUGGER_BREAK); } @@ -221,6 +222,9 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic, /* Can deadlock when called with interrupts disabled */ WARN_ON(irqs_disabled()); + if (unlikely(smp_ops == NULL)) + return -1; + data.func = func; data.info = info; atomic_set(&data.started, 0); @@ -358,7 +362,10 @@ void __init smp_prepare_cpus(unsigned int max_cpus) smp_store_cpu_info(boot_cpuid); cpu_callin_map[boot_cpuid] = 1; - max_cpus = smp_ops->probe(); + if (smp_ops) + max_cpus = smp_ops->probe(); + else + max_cpus = 1; smp_space_timers(max_cpus); @@ -454,7 +461,7 @@ void generic_mach_cpu_die(void) static int __devinit cpu_enable(unsigned int cpu) { - if (smp_ops->cpu_enable) + if (smp_ops && smp_ops->cpu_enable) return smp_ops->cpu_enable(cpu); return -ENOSYS; @@ -468,7 +475,8 @@ int __devinit __cpu_up(unsigned int cpu) if (!cpu_enable(cpu)) return 0; - if (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu)) + if (smp_ops == NULL || + (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu))) return -EINVAL; /* Make sure callin-map entry is 0 (can be leftover a CPU @@ -569,7 +577,8 @@ void __init smp_cpus_done(unsigned int max_cpus) old_mask = current->cpus_allowed; set_cpus_allowed(current, cpumask_of_cpu(boot_cpuid)); - smp_ops->setup_cpu(boot_cpuid); + if (smp_ops) + smp_ops->setup_cpu(boot_cpuid); set_cpus_allowed(current, old_mask); diff --git a/arch/powerpc/kernel/swsusp_32.S b/arch/powerpc/kernel/swsusp_32.S index 69773cc1a85f..69e8f86aa4f8 100644 --- a/arch/powerpc/kernel/swsusp_32.S +++ b/arch/powerpc/kernel/swsusp_32.S @@ -1,4 +1,3 @@ -#include <linux/config.h> #include <linux/threads.h> #include <asm/processor.h> #include <asm/page.h> @@ -160,8 +159,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) isync /* Load ptr the list of pages to copy in r3 */ - lis r11,(pagedir_nosave - KERNELBASE)@h - ori r11,r11,pagedir_nosave@l + lis r11,(restore_pblist - KERNELBASE)@h + ori r11,r11,restore_pblist@l lwz r10,0(r11) /* Copy the pages. This is a very basic implementation, to diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c index ec274e688816..5e391fc25340 100644 --- a/arch/powerpc/kernel/sys_ppc32.c +++ b/arch/powerpc/kernel/sys_ppc32.c @@ -14,7 +14,6 @@ * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/fs.h> @@ -741,7 +740,7 @@ asmlinkage long compat_sys_umask(u32 mask) return sys_umask((int)mask); } -#ifdef CONFIG_SYSCTL +#ifdef CONFIG_SYSCTL_SYSCALL struct __sysctl_args32 { u32 name; int nlen; diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c index 5bc2585c8036..406f308ddead 100644 --- a/arch/powerpc/kernel/sysfs.c +++ b/arch/powerpc/kernel/sysfs.c @@ -1,4 +1,3 @@ -#include <linux/config.h> #include <linux/sysdev.h> #include <linux/cpu.h> #include <linux/smp.h> @@ -61,7 +60,7 @@ static int smt_snooze_cmdline; static int __init smt_setup(void) { struct device_node *options; - unsigned int *val; + const unsigned int *val; unsigned int cpu; if (!cpu_has_feature(CPU_FTR_SMT)) @@ -71,8 +70,7 @@ static int __init smt_setup(void) if (!options) return -ENODEV; - val = (unsigned int *)get_property(options, "ibm,smt-snooze-delay", - NULL); + val = get_property(options, "ibm,smt-snooze-delay", NULL); if (!smt_snooze_cmdline && val) { for_each_possible_cpu(cpu) per_cpu(smt_snooze_delay, cpu) = *val; @@ -232,7 +230,7 @@ static void register_cpu_online(unsigned int cpu) if (cur_cpu_spec->num_pmcs >= 8) sysdev_create_file(s, &attr_pmc8); - if (cpu_has_feature(CPU_FTR_SMT)) + if (cpu_has_feature(CPU_FTR_PURR)) sysdev_create_file(s, &attr_purr); } @@ -274,12 +272,12 @@ static void unregister_cpu_online(unsigned int cpu) if (cur_cpu_spec->num_pmcs >= 8) sysdev_remove_file(s, &attr_pmc8); - if (cpu_has_feature(CPU_FTR_SMT)) + if (cpu_has_feature(CPU_FTR_PURR)) sysdev_remove_file(s, &attr_purr); } #endif /* CONFIG_HOTPLUG_CPU */ -static int sysfs_cpu_notify(struct notifier_block *self, +static int __cpuinit sysfs_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) { unsigned int cpu = (unsigned int)(long)hcpu; @@ -297,30 +295,19 @@ static int sysfs_cpu_notify(struct notifier_block *self, return NOTIFY_OK; } -static struct notifier_block sysfs_cpu_nb = { +static struct notifier_block __cpuinitdata sysfs_cpu_nb = { .notifier_call = sysfs_cpu_notify, }; /* NUMA stuff */ #ifdef CONFIG_NUMA -static struct node node_devices[MAX_NUMNODES]; - static void register_nodes(void) { int i; - for (i = 0; i < MAX_NUMNODES; i++) { - if (node_online(i)) { - int p_node = parent_node(i); - struct node *parent = NULL; - - if (p_node != i) - parent = &node_devices[p_node]; - - register_node(&node_devices[i], i, parent); - } - } + for (i = 0; i < MAX_NUMNODES; i++) + register_one_node(i); } int sysfs_add_device_to_node(struct sys_device *dev, int nid) @@ -359,23 +346,13 @@ static SYSDEV_ATTR(physical_id, 0444, show_physical_id, NULL); static int __init topology_init(void) { int cpu; - struct node *parent = NULL; register_nodes(); - register_cpu_notifier(&sysfs_cpu_nb); for_each_possible_cpu(cpu) { struct cpu *c = &per_cpu(cpu_devices, cpu); -#ifdef CONFIG_NUMA - /* The node to which a cpu belongs can't be known - * until the cpu is made present. - */ - parent = NULL; - if (cpu_present(cpu)) - parent = &node_devices[cpu_to_node(cpu)]; -#endif /* * For now, we just see if the system supports making * the RTAS calls for CPU hotplug. But, there may be a @@ -387,7 +364,7 @@ static int __init topology_init(void) c->no_control = 1; if (cpu_online(cpu) || (c->no_control == 0)) { - register_cpu(c, cpu, parent); + register_cpu(c, cpu); sysdev_create_file(&c->sysdev, &attr_physical_id); } diff --git a/arch/powerpc/kernel/systbl.S b/arch/powerpc/kernel/systbl.S index ee75ccf1a802..579de70e0b4d 100644 --- a/arch/powerpc/kernel/systbl.S +++ b/arch/powerpc/kernel/systbl.S @@ -14,7 +14,6 @@ * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <asm/ppc_asm.h> #ifdef CONFIG_PPC64 diff --git a/arch/powerpc/kernel/tau_6xx.c b/arch/powerpc/kernel/tau_6xx.c index 26bd8ea35a4e..368a4934f7ee 100644 --- a/arch/powerpc/kernel/tau_6xx.c +++ b/arch/powerpc/kernel/tau_6xx.c @@ -11,7 +11,6 @@ * life in portables, and add a 'performance/watt' metric somewhere in /proc */ -#include <linux/config.h> #include <linux/errno.h> #include <linux/jiffies.h> #include <linux/kernel.h> diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index d20907561f46..71f71da98e7d 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -32,7 +32,6 @@ * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <linux/errno.h> #include <linux/module.h> #include <linux/sched.h> @@ -102,7 +101,7 @@ EXPORT_SYMBOL(tb_ticks_per_sec); /* for cputime_t conversions */ u64 tb_to_xs; unsigned tb_to_us; -#define TICKLEN_SCALE (SHIFT_SCALE - 10) +#define TICKLEN_SCALE TICK_LENGTH_SHIFT u64 last_tick_len; /* units are ns / 2^TICKLEN_SCALE */ u64 ticklen_to_xs; /* 0.64 fraction */ @@ -126,15 +125,8 @@ static long timezone_offset; unsigned long ppc_proc_freq; unsigned long ppc_tb_freq; -u64 tb_last_jiffy __cacheline_aligned_in_smp; -unsigned long tb_last_stamp; - -/* - * Note that on ppc32 this only stores the bottom 32 bits of - * the timebase value, but that's enough to tell when a jiffy - * has passed. - */ -DEFINE_PER_CPU(unsigned long, last_jiffy); +static u64 tb_last_jiffy __cacheline_aligned_in_smp; +static DEFINE_PER_CPU(u64, last_jiffy); #ifdef CONFIG_VIRT_CPU_ACCOUNTING /* @@ -418,7 +410,7 @@ static __inline__ void timer_check_rtc(void) /* * This version of gettimeofday has microsecond resolution. */ -static inline void __do_gettimeofday(struct timeval *tv, u64 tb_val) +static inline void __do_gettimeofday(struct timeval *tv) { unsigned long sec, usec; u64 tb_ticks, xsec; @@ -432,7 +424,12 @@ static inline void __do_gettimeofday(struct timeval *tv, u64 tb_val) * without a divide (and in fact, without a multiply) */ temp_varp = do_gtod.varp; - tb_ticks = tb_val - temp_varp->tb_orig_stamp; + + /* Sampling the time base must be done after loading + * do_gtod.varp in order to avoid racing with update_gtod. + */ + data_barrier(temp_varp); + tb_ticks = get_tb() - temp_varp->tb_orig_stamp; temp_tb_to_xs = temp_varp->tb_to_xs; temp_stamp_xsec = temp_varp->stamp_xsec; xsec = temp_stamp_xsec + mulhdu(tb_ticks, temp_tb_to_xs); @@ -454,7 +451,7 @@ void do_gettimeofday(struct timeval *tv) do { seq = read_seqbegin_irqsave(&xtime_lock, flags); sec = xtime.tv_sec; - nsec = xtime.tv_nsec + tb_ticks_since(tb_last_stamp); + nsec = xtime.tv_nsec + tb_ticks_since(tb_last_jiffy); } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); usec = nsec / 1000; while (usec >= 1000000) { @@ -465,7 +462,7 @@ void do_gettimeofday(struct timeval *tv) tv->tv_usec = usec; return; } - __do_gettimeofday(tv, get_tb()); + __do_gettimeofday(tv); } EXPORT_SYMBOL(do_gettimeofday); @@ -651,6 +648,7 @@ void timer_interrupt(struct pt_regs * regs) int next_dec; int cpu = smp_processor_id(); unsigned long ticks; + u64 tb_next_jiffy; #ifdef CONFIG_PPC32 if (atomic_read(&ppc_n_lost_interrupts) != 0) @@ -692,11 +690,13 @@ void timer_interrupt(struct pt_regs * regs) continue; write_seqlock(&xtime_lock); - tb_last_jiffy += tb_ticks_per_jiffy; - tb_last_stamp = per_cpu(last_jiffy, cpu); - do_timer(regs); - timer_recalc_offset(tb_last_jiffy); - timer_check_rtc(); + tb_next_jiffy = tb_last_jiffy + tb_ticks_per_jiffy; + if (per_cpu(last_jiffy, cpu) >= tb_next_jiffy) { + tb_last_jiffy = tb_next_jiffy; + do_timer(1); + timer_recalc_offset(tb_last_jiffy); + timer_check_rtc(); + } write_sequnlock(&xtime_lock); } @@ -741,7 +741,7 @@ void __init smp_space_timers(unsigned int max_cpus) int i; unsigned long half = tb_ticks_per_jiffy / 2; unsigned long offset = tb_ticks_per_jiffy / max_cpus; - unsigned long previous_tb = per_cpu(last_jiffy, boot_cpuid); + u64 previous_tb = per_cpu(last_jiffy, boot_cpuid); /* make sure tb > per_cpu(last_jiffy, cpu) for all cpus always */ previous_tb -= tb_ticks_per_jiffy; @@ -822,7 +822,7 @@ int do_settimeofday(struct timespec *tv) * and therefore the (jiffies - wall_jiffies) computation * has been removed. */ - tb_delta = tb_ticks_since(tb_last_stamp); + tb_delta = tb_ticks_since(tb_last_jiffy); tb_delta = mulhdu(tb_delta, do_gtod.varp->tb_to_xs); /* in xsec */ new_nsec -= SCALE_XSEC(tb_delta, 1000000000); @@ -860,19 +860,17 @@ EXPORT_SYMBOL(do_settimeofday); static int __init get_freq(char *name, int cells, unsigned long *val) { struct device_node *cpu; - unsigned int *fp; + const unsigned int *fp; int found = 0; /* The cpu node should have timebase and clock frequency properties */ cpu = of_find_node_by_type(NULL, "cpu"); if (cpu) { - fp = (unsigned int *)get_property(cpu, name, NULL); + fp = get_property(cpu, name, NULL); if (fp) { found = 1; - *val = 0; - while (cells--) - *val = (*val << 32) | *fp++; + *val = of_read_ulong(fp, cells); } of_node_put(cpu); @@ -942,8 +940,7 @@ void __init time_init(void) if (__USE_RTC()) { /* 601 processor: dec counts down by 128 every 128ns */ ppc_tb_freq = 1000000000; - tb_last_stamp = get_rtcl(); - tb_last_jiffy = tb_last_stamp; + tb_last_jiffy = get_rtcl(); } else { /* Normal PowerPC with timebase register */ ppc_md.calibrate_decr(); @@ -951,7 +948,7 @@ void __init time_init(void) ppc_tb_freq / 1000000, ppc_tb_freq % 1000000); printk(KERN_DEBUG "time_init: processor frequency = %lu.%.6lu MHz\n", ppc_proc_freq / 1000000, ppc_proc_freq % 1000000); - tb_last_stamp = tb_last_jiffy = get_tb(); + tb_last_jiffy = get_tb(); } tb_ticks_per_jiffy = ppc_tb_freq / HZ; @@ -1028,7 +1025,7 @@ void __init time_init(void) do_gtod.varp = &do_gtod.vars[0]; do_gtod.var_idx = 0; do_gtod.varp->tb_orig_stamp = tb_last_jiffy; - __get_cpu_var(last_jiffy) = tb_last_stamp; + __get_cpu_var(last_jiffy) = tb_last_jiffy; do_gtod.varp->stamp_xsec = (u64) xtime.tv_sec * XSEC_PER_SEC; do_gtod.tb_ticks_per_sec = tb_ticks_per_sec; do_gtod.varp->tb_to_xs = tb_to_xs; diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 91a6e04d9741..d9f10f2fc372 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -14,7 +14,6 @@ * This file handles the architecture-dependent parts of hardware exceptions */ -#include <linux/config.h> #include <linux/errno.h> #include <linux/sched.h> #include <linux/kernel.h> @@ -32,6 +31,7 @@ #include <linux/delay.h> #include <linux/kprobes.h> #include <linux/kexec.h> +#include <linux/backlight.h> #include <asm/kdebug.h> #include <asm/pgtable.h> @@ -51,6 +51,7 @@ #include <asm/firmware.h> #include <asm/processor.h> #endif +#include <asm/kexec.h> #ifdef CONFIG_PPC64 /* XXX */ #define _IO_BASE pci_io_base @@ -96,7 +97,7 @@ static DEFINE_SPINLOCK(die_lock); int die(const char *str, struct pt_regs *regs, long err) { - static int die_counter, crash_dump_start = 0; + static int die_counter; if (debugger(regs)) return 1; @@ -105,10 +106,18 @@ int die(const char *str, struct pt_regs *regs, long err) spin_lock_irq(&die_lock); bust_spinlocks(1); #ifdef CONFIG_PMAC_BACKLIGHT - if (machine_is(powermac)) { - set_backlight_enable(1); - set_backlight_level(BACKLIGHT_MAX); + mutex_lock(&pmac_backlight_mutex); + if (machine_is(powermac) && pmac_backlight) { + struct backlight_properties *props; + + down(&pmac_backlight->sem); + props = pmac_backlight->props; + props->brightness = props->max_brightness; + props->power = FB_BLANK_UNBLANK; + props->update_status(pmac_backlight); + up(&pmac_backlight->sem); } + mutex_unlock(&pmac_backlight_mutex); #endif printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter); #ifdef CONFIG_PREEMPT @@ -128,32 +137,19 @@ int die(const char *str, struct pt_regs *regs, long err) print_modules(); show_regs(regs); bust_spinlocks(0); + spin_unlock_irq(&die_lock); - if (!crash_dump_start && kexec_should_crash(current)) { - crash_dump_start = 1; - spin_unlock_irq(&die_lock); + if (kexec_should_crash(current) || + kexec_sr_activated(smp_processor_id())) crash_kexec(regs); - /* NOTREACHED */ - } - spin_unlock_irq(&die_lock); - if (crash_dump_start) - /* - * Only for soft-reset: Other CPUs will be responded to an IPI - * sent by first kexec CPU. - */ - for(;;) - ; + crash_kexec_secondary(regs); if (in_interrupt()) panic("Fatal exception in interrupt"); - if (panic_on_oops) { -#ifdef CONFIG_PPC64 - printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n"); - ssleep(5); -#endif + if (panic_on_oops) panic("Fatal exception"); - } + do_exit(err); return 0; @@ -206,8 +202,25 @@ void system_reset_exception(struct pt_regs *regs) return; } +#ifdef CONFIG_KEXEC + cpu_set(smp_processor_id(), cpus_in_sr); +#endif + die("System Reset", regs, SIGABRT); + /* + * Some CPUs when released from the debugger will execute this path. + * These CPUs entered the debugger via a soft-reset. If the CPU was + * hung before entering the debugger it will return to the hung + * state when exiting this function. This causes a problem in + * kdump since the hung CPU(s) will not respond to the IPI sent + * from kdump. To prevent the problem we call crash_kexec_secondary() + * here. If a kdump had not been initiated or we exit the debugger + * with the "exit and recover" command (x) crash_kexec_secondary() + * will return after 5ms and the CPU returns to its previous state. + */ + crash_kexec_secondary(regs); + /* Must die if the interrupt is not recoverable */ if (!(regs->msr & MSR_RI)) panic("Unrecoverable System Reset"); @@ -572,19 +585,22 @@ static void parse_fpe(struct pt_regs *regs) #define INST_MFSPR_PVR_MASK 0xfc1fffff #define INST_DCBA 0x7c0005ec -#define INST_DCBA_MASK 0x7c0007fe +#define INST_DCBA_MASK 0xfc0007fe #define INST_MCRXR 0x7c000400 -#define INST_MCRXR_MASK 0x7c0007fe +#define INST_MCRXR_MASK 0xfc0007fe #define INST_STRING 0x7c00042a -#define INST_STRING_MASK 0x7c0007fe -#define INST_STRING_GEN_MASK 0x7c00067e +#define INST_STRING_MASK 0xfc0007fe +#define INST_STRING_GEN_MASK 0xfc00067e #define INST_LSWI 0x7c0004aa #define INST_LSWX 0x7c00042a #define INST_STSWI 0x7c0005aa #define INST_STSWX 0x7c00052a +#define INST_POPCNTB 0x7c0000f4 +#define INST_POPCNTB_MASK 0xfc0007fe + static int emulate_string_inst(struct pt_regs *regs, u32 instword) { u8 rT = (instword >> 21) & 0x1f; @@ -653,6 +669,23 @@ static int emulate_string_inst(struct pt_regs *regs, u32 instword) return 0; } +static int emulate_popcntb_inst(struct pt_regs *regs, u32 instword) +{ + u32 ra,rs; + unsigned long tmp; + + ra = (instword >> 16) & 0x1f; + rs = (instword >> 21) & 0x1f; + + tmp = regs->gpr[rs]; + tmp = tmp - ((tmp >> 1) & 0x5555555555555555ULL); + tmp = (tmp & 0x3333333333333333ULL) + ((tmp >> 2) & 0x3333333333333333ULL); + tmp = (tmp + (tmp >> 4)) & 0x0f0f0f0f0f0f0f0fULL; + regs->gpr[ra] = tmp; + + return 0; +} + static int emulate_instruction(struct pt_regs *regs) { u32 instword; @@ -690,6 +723,11 @@ static int emulate_instruction(struct pt_regs *regs) if ((instword & INST_STRING_GEN_MASK) == INST_STRING) return emulate_string_inst(regs, instword); + /* Emulate the popcntb (Population Count Bytes) instruction. */ + if ((instword & INST_POPCNTB_MASK) == INST_POPCNTB) { + return emulate_popcntb_inst(regs, instword); + } + return -EINVAL; } diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c index 67d9fd9ae2b5..5730906b23d5 100644 --- a/arch/powerpc/kernel/udbg.c +++ b/arch/powerpc/kernel/udbg.c @@ -10,7 +10,6 @@ */ #include <stdarg.h> -#include <linux/config.h> #include <linux/types.h> #include <linux/sched.h> #include <linux/console.h> @@ -34,9 +33,12 @@ void __init udbg_early_init(void) #elif defined(CONFIG_PPC_EARLY_DEBUG_G5) /* For use on Apple G5 machines */ udbg_init_pmac_realmode(); -#elif defined(CONFIG_PPC_EARLY_DEBUG_RTAS) +#elif defined(CONFIG_PPC_EARLY_DEBUG_RTAS_PANEL) /* RTAS panel debug */ - udbg_init_rtas(); + udbg_init_rtas_panel(); +#elif defined(CONFIG_PPC_EARLY_DEBUG_RTAS_CONSOLE) + /* RTAS console debug */ + udbg_init_rtas_console(); #elif defined(CONFIG_PPC_EARLY_DEBUG_MAPLE) /* Maple real mode debug */ udbg_init_maple_realmode(); diff --git a/arch/powerpc/kernel/udbg_16550.c b/arch/powerpc/kernel/udbg_16550.c index 5d29dcca523c..2d17f2b8eda7 100644 --- a/arch/powerpc/kernel/udbg_16550.c +++ b/arch/powerpc/kernel/udbg_16550.c @@ -8,7 +8,6 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <linux/types.h> #include <asm/udbg.h> #include <asm/io.h> @@ -82,10 +81,14 @@ static int udbg_550_getc(void) void udbg_init_uart(void __iomem *comport, unsigned int speed, unsigned int clock) { - unsigned int dll, base_bauds = clock / 16; + unsigned int dll, base_bauds; + if (clock == 0) + clock = 1843200; if (speed == 0) speed = 9600; + + base_bauds = clock / 16; dll = base_bauds / speed; if (comport) { diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c index bc3e15be3087..1a7e19cdab39 100644 --- a/arch/powerpc/kernel/vdso.c +++ b/arch/powerpc/kernel/vdso.c @@ -8,7 +8,6 @@ * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/errno.h> #include <linux/sched.h> diff --git a/arch/powerpc/kernel/vdso32/Makefile b/arch/powerpc/kernel/vdso32/Makefile index 8a3bed5f143a..3726358faae8 100644 --- a/arch/powerpc/kernel/vdso32/Makefile +++ b/arch/powerpc/kernel/vdso32/Makefile @@ -14,7 +14,8 @@ obj-vdso32 := $(addprefix $(obj)/, $(obj-vdso32)) EXTRA_CFLAGS := -shared -s -fno-common -fno-builtin -EXTRA_CFLAGS += -nostdlib -Wl,-soname=linux-vdso32.so.1 +EXTRA_CFLAGS += -nostdlib -Wl,-soname=linux-vdso32.so.1 \ + $(call ld-option, -Wl$(comma)--hash-style=sysv) EXTRA_AFLAGS := -D__VDSO32__ -s obj-y += vdso32_wrapper.o diff --git a/arch/powerpc/kernel/vdso32/cacheflush.S b/arch/powerpc/kernel/vdso32/cacheflush.S index 09629aea3e47..9cb319992c38 100644 --- a/arch/powerpc/kernel/vdso32/cacheflush.S +++ b/arch/powerpc/kernel/vdso32/cacheflush.S @@ -9,7 +9,6 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <asm/processor.h> #include <asm/ppc_asm.h> #include <asm/vdso.h> diff --git a/arch/powerpc/kernel/vdso32/datapage.S b/arch/powerpc/kernel/vdso32/datapage.S index 4709f1d9542c..dc21e891d2e7 100644 --- a/arch/powerpc/kernel/vdso32/datapage.S +++ b/arch/powerpc/kernel/vdso32/datapage.S @@ -9,7 +9,6 @@ * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <asm/processor.h> #include <asm/ppc_asm.h> #include <asm/asm-offsets.h> diff --git a/arch/powerpc/kernel/vdso32/gettimeofday.S b/arch/powerpc/kernel/vdso32/gettimeofday.S index 7eebff03a041..05909f754307 100644 --- a/arch/powerpc/kernel/vdso32/gettimeofday.S +++ b/arch/powerpc/kernel/vdso32/gettimeofday.S @@ -10,7 +10,6 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <asm/processor.h> #include <asm/ppc_asm.h> #include <asm/vdso.h> diff --git a/arch/powerpc/kernel/vdso32/sigtramp.S b/arch/powerpc/kernel/vdso32/sigtramp.S index 0c6a37b29dde..68d49dd71dcc 100644 --- a/arch/powerpc/kernel/vdso32/sigtramp.S +++ b/arch/powerpc/kernel/vdso32/sigtramp.S @@ -10,7 +10,6 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <asm/processor.h> #include <asm/ppc_asm.h> #include <asm/unistd.h> diff --git a/arch/powerpc/kernel/vdso32/vdso32.lds.S b/arch/powerpc/kernel/vdso32/vdso32.lds.S index f4bad720cb0a..6187af2d54c3 100644 --- a/arch/powerpc/kernel/vdso32/vdso32.lds.S +++ b/arch/powerpc/kernel/vdso32/vdso32.lds.S @@ -14,6 +14,7 @@ SECTIONS { . = VDSO32_LBASE + SIZEOF_HEADERS; .hash : { *(.hash) } :text + .gnu.hash : { *(.gnu.hash) } .dynsym : { *(.dynsym) } .dynstr : { *(.dynstr) } .gnu.version : { *(.gnu.version) } diff --git a/arch/powerpc/kernel/vdso64/Makefile b/arch/powerpc/kernel/vdso64/Makefile index ab39988452cc..43af9b2a6f3b 100644 --- a/arch/powerpc/kernel/vdso64/Makefile +++ b/arch/powerpc/kernel/vdso64/Makefile @@ -8,7 +8,8 @@ targets := $(obj-vdso64) vdso64.so obj-vdso64 := $(addprefix $(obj)/, $(obj-vdso64)) EXTRA_CFLAGS := -shared -s -fno-common -fno-builtin -EXTRA_CFLAGS += -nostdlib -Wl,-soname=linux-vdso64.so.1 +EXTRA_CFLAGS += -nostdlib -Wl,-soname=linux-vdso64.so.1 \ + $(call ld-option, -Wl$(comma)--hash-style=sysv) EXTRA_AFLAGS := -D__VDSO64__ -s obj-y += vdso64_wrapper.o diff --git a/arch/powerpc/kernel/vdso64/cacheflush.S b/arch/powerpc/kernel/vdso64/cacheflush.S index cb4ae0a5edd0..66a36d3cc6ad 100644 --- a/arch/powerpc/kernel/vdso64/cacheflush.S +++ b/arch/powerpc/kernel/vdso64/cacheflush.S @@ -9,7 +9,6 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <asm/processor.h> #include <asm/ppc_asm.h> #include <asm/vdso.h> diff --git a/arch/powerpc/kernel/vdso64/datapage.S b/arch/powerpc/kernel/vdso64/datapage.S index 3b2dd7d0c1eb..79796de11737 100644 --- a/arch/powerpc/kernel/vdso64/datapage.S +++ b/arch/powerpc/kernel/vdso64/datapage.S @@ -9,7 +9,6 @@ * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <asm/processor.h> #include <asm/ppc_asm.h> #include <asm/asm-offsets.h> diff --git a/arch/powerpc/kernel/vdso64/gettimeofday.S b/arch/powerpc/kernel/vdso64/gettimeofday.S index 4ee871f1cadb..56e76ff5498f 100644 --- a/arch/powerpc/kernel/vdso64/gettimeofday.S +++ b/arch/powerpc/kernel/vdso64/gettimeofday.S @@ -11,7 +11,6 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <asm/processor.h> #include <asm/ppc_asm.h> #include <asm/vdso.h> diff --git a/arch/powerpc/kernel/vdso64/sigtramp.S b/arch/powerpc/kernel/vdso64/sigtramp.S index 7479edb101b8..17a83fa6dc52 100644 --- a/arch/powerpc/kernel/vdso64/sigtramp.S +++ b/arch/powerpc/kernel/vdso64/sigtramp.S @@ -10,7 +10,6 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <asm/processor.h> #include <asm/ppc_asm.h> #include <asm/unistd.h> diff --git a/arch/powerpc/kernel/vdso64/vdso64.lds.S b/arch/powerpc/kernel/vdso64/vdso64.lds.S index 4bdf224464ab..4a2b6dc0960c 100644 --- a/arch/powerpc/kernel/vdso64/vdso64.lds.S +++ b/arch/powerpc/kernel/vdso64/vdso64.lds.S @@ -12,6 +12,7 @@ SECTIONS { . = VDSO64_LBASE + SIZEOF_HEADERS; .hash : { *(.hash) } :text + .gnu.hash : { *(.gnu.hash) } .dynsym : { *(.dynsym) } .dynstr : { *(.dynstr) } .gnu.version : { *(.gnu.version) } diff --git a/arch/powerpc/kernel/vector.S b/arch/powerpc/kernel/vector.S index 9416b4ab92ec..49ac3d6e1399 100644 --- a/arch/powerpc/kernel/vector.S +++ b/arch/powerpc/kernel/vector.S @@ -1,4 +1,3 @@ -#include <linux/config.h> #include <asm/ppc_asm.h> #include <asm/reg.h> diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index cdf5867838a6..cb87e71eec66 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c @@ -77,7 +77,7 @@ static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev) } else #endif { - unsigned char *dma_window; + const unsigned char *dma_window; struct iommu_table *tbl; unsigned long offset, size; @@ -217,8 +217,7 @@ static void __devinit vio_dev_release(struct device *dev) struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node) { struct vio_dev *viodev; - unsigned int *unit_address; - unsigned int *irq_p; + const unsigned int *unit_address; /* we need the 'device_type' property, in order to match with drivers */ if (of_node->type == NULL) { @@ -228,7 +227,7 @@ struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node) return NULL; } - unit_address = (unsigned int *)get_property(of_node, "reg", NULL); + unit_address = get_property(of_node, "reg", NULL); if (unit_address == NULL) { printk(KERN_WARNING "%s: node %s missing 'reg'\n", __FUNCTION__, @@ -243,23 +242,14 @@ struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node) viodev->dev.platform_data = of_node_get(of_node); - viodev->irq = NO_IRQ; - irq_p = (unsigned int *)get_property(of_node, "interrupts", NULL); - if (irq_p) { - int virq = virt_irq_create_mapping(*irq_p); - if (virq == NO_IRQ) { - printk(KERN_ERR "Unable to allocate interrupt " - "number for %s\n", of_node->full_name); - } else - viodev->irq = irq_offset_up(virq); - } + viodev->irq = irq_of_parse_and_map(of_node, 0); snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%x", *unit_address); viodev->name = of_node->name; viodev->type = of_node->type; viodev->unit_address = *unit_address; if (firmware_has_feature(FW_FEATURE_ISERIES)) { - unit_address = (unsigned int *)get_property(of_node, + unit_address = get_property(of_node, "linux,unit_address", NULL); if (unit_address != NULL) viodev->unit_address = *unit_address; @@ -433,7 +423,7 @@ static int vio_hotplug(struct device *dev, char **envp, int num_envp, { const struct vio_dev *vio_dev = to_vio_dev(dev); struct device_node *dn = dev->platform_data; - char *cp; + const char *cp; int length; if (!num_envp) @@ -441,7 +431,7 @@ static int vio_hotplug(struct device *dev, char **envp, int num_envp, if (!dn) return -ENODEV; - cp = (char *)get_property(dn, "compatible", &length); + cp = get_property(dn, "compatible", &length); if (!cp) return -ENODEV; @@ -503,11 +493,11 @@ static struct vio_dev *vio_find_name(const char *kobj_name) */ struct vio_dev *vio_find_node(struct device_node *vnode) { - uint32_t *unit_address; + const uint32_t *unit_address; char kobj_name[BUS_ID_SIZE]; /* construct the kobject name from the device node */ - unit_address = (uint32_t *)get_property(vnode, "reg", NULL); + unit_address = get_property(vnode, "reg", NULL); if (!unit_address) return NULL; snprintf(kobj_name, BUS_ID_SIZE, "%x", *unit_address); diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S index 8b25953dc4f0..02665a02130d 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S @@ -1,4 +1,3 @@ -#include <linux/config.h> #ifdef CONFIG_PPC64 #include <asm/page.h> #define PROVIDE32(x) PROVIDE(__unused__##x) diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index ff7096458249..336dd191f768 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile @@ -14,7 +14,6 @@ endif obj-$(CONFIG_PPC64) += checksum_64.o copypage_64.o copyuser_64.o \ memcpy_64.o usercopy_64.o mem_64.o string.o \ strcase.o -obj-$(CONFIG_PPC_ISERIES) += e2a.o obj-$(CONFIG_XMON) += sstep.o ifeq ($(CONFIG_PPC64),y) diff --git a/arch/powerpc/lib/copy_32.S b/arch/powerpc/lib/copy_32.S index bee51414812e..c657de59abca 100644 --- a/arch/powerpc/lib/copy_32.S +++ b/arch/powerpc/lib/copy_32.S @@ -8,7 +8,6 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <asm/processor.h> #include <asm/cache.h> #include <asm/errno.h> diff --git a/arch/powerpc/lib/e2a.c b/arch/powerpc/lib/e2a.c deleted file mode 100644 index 4b72ed8fd50e..000000000000 --- a/arch/powerpc/lib/e2a.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * EBCDIC to ASCII conversion - * - * This function moved here from arch/powerpc/platforms/iseries/viopath.c - * - * (C) Copyright 2000-2004 IBM Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) anyu later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include <linux/module.h> - -unsigned char e2a(unsigned char x) -{ - switch (x) { - case 0xF0: - return '0'; - case 0xF1: - return '1'; - case 0xF2: - return '2'; - case 0xF3: - return '3'; - case 0xF4: - return '4'; - case 0xF5: - return '5'; - case 0xF6: - return '6'; - case 0xF7: - return '7'; - case 0xF8: - return '8'; - case 0xF9: - return '9'; - case 0xC1: - return 'A'; - case 0xC2: - return 'B'; - case 0xC3: - return 'C'; - case 0xC4: - return 'D'; - case 0xC5: - return 'E'; - case 0xC6: - return 'F'; - case 0xC7: - return 'G'; - case 0xC8: - return 'H'; - case 0xC9: - return 'I'; - case 0xD1: - return 'J'; - case 0xD2: - return 'K'; - case 0xD3: - return 'L'; - case 0xD4: - return 'M'; - case 0xD5: - return 'N'; - case 0xD6: - return 'O'; - case 0xD7: - return 'P'; - case 0xD8: - return 'Q'; - case 0xD9: - return 'R'; - case 0xE2: - return 'S'; - case 0xE3: - return 'T'; - case 0xE4: - return 'U'; - case 0xE5: - return 'V'; - case 0xE6: - return 'W'; - case 0xE7: - return 'X'; - case 0xE8: - return 'Y'; - case 0xE9: - return 'Z'; - } - return ' '; -} -EXPORT_SYMBOL(e2a); - -unsigned char* strne2a(unsigned char *dest, const unsigned char *src, size_t n) -{ - int i; - - n = strnlen(src, n); - - for (i = 0; i < n; i++) - dest[i] = e2a(src[i]); - - return dest; -} diff --git a/arch/powerpc/lib/locks.c b/arch/powerpc/lib/locks.c index 8362fa272ca5..80b482ca30df 100644 --- a/arch/powerpc/lib/locks.c +++ b/arch/powerpc/lib/locks.c @@ -12,7 +12,6 @@ * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/spinlock.h> #include <linux/module.h> @@ -24,6 +23,7 @@ #include <asm/hvcall.h> #include <asm/iseries/hv_call.h> #include <asm/smp.h> +#include <asm/firmware.h> void __spin_yield(raw_spinlock_t *lock) { @@ -40,13 +40,12 @@ void __spin_yield(raw_spinlock_t *lock) rmb(); if (lock->slock != lock_value) return; /* something has changed */ -#ifdef CONFIG_PPC_ISERIES - HvCall2(HvCallBaseYieldProcessor, HvCall_YieldToProc, - ((u64)holder_cpu << 32) | yield_count); -#else - plpar_hcall_norets(H_CONFER, get_hard_smp_processor_id(holder_cpu), - yield_count); -#endif + if (firmware_has_feature(FW_FEATURE_ISERIES)) + HvCall2(HvCallBaseYieldProcessor, HvCall_YieldToProc, + ((u64)holder_cpu << 32) | yield_count); + else + plpar_hcall_norets(H_CONFER, + get_hard_smp_processor_id(holder_cpu), yield_count); } /* @@ -70,13 +69,12 @@ void __rw_yield(raw_rwlock_t *rw) rmb(); if (rw->lock != lock_value) return; /* something has changed */ -#ifdef CONFIG_PPC_ISERIES - HvCall2(HvCallBaseYieldProcessor, HvCall_YieldToProc, - ((u64)holder_cpu << 32) | yield_count); -#else - plpar_hcall_norets(H_CONFER, get_hard_smp_processor_id(holder_cpu), - yield_count); -#endif + if (firmware_has_feature(FW_FEATURE_ISERIES)) + HvCall2(HvCallBaseYieldProcessor, HvCall_YieldToProc, + ((u64)holder_cpu << 32) | yield_count); + else + plpar_hcall_norets(H_CONFER, + get_hard_smp_processor_id(holder_cpu), yield_count); } #endif diff --git a/arch/powerpc/lib/memcpy_64.S b/arch/powerpc/lib/memcpy_64.S index fd66acfd3e3e..7173ba98f427 100644 --- a/arch/powerpc/lib/memcpy_64.S +++ b/arch/powerpc/lib/memcpy_64.S @@ -11,6 +11,7 @@ .align 7 _GLOBAL(memcpy) + std r3,48(r1) /* save destination pointer for return value */ mtcrf 0x01,r5 cmpldi cr1,r5,16 neg r6,r3 # LS 3 bits = # bytes to 8-byte dest bdry @@ -38,7 +39,7 @@ _GLOBAL(memcpy) stdu r9,16(r3) bdnz 1b 3: std r8,8(r3) - beqlr + beq 3f addi r3,r3,16 ld r9,8(r4) .Ldo_tail: @@ -53,7 +54,8 @@ _GLOBAL(memcpy) 2: bf cr7*4+3,3f rotldi r9,r9,8 stb r9,0(r3) -3: blr +3: ld r3,48(r1) /* return dest pointer */ + blr .Lsrc_unaligned: srdi r6,r5,3 @@ -115,7 +117,7 @@ _GLOBAL(memcpy) 5: srd r12,r9,r11 or r12,r8,r12 std r12,24(r3) - beqlr + beq 4f cmpwi cr1,r5,8 addi r3,r3,32 sld r9,r9,r10 @@ -167,4 +169,5 @@ _GLOBAL(memcpy) 3: bf cr7*4+3,4f lbz r0,0(r4) stb r0,0(r3) -4: blr +4: ld r3,48(r1) /* return dest pointer */ + blr diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c index c251d9936612..9590ba780b98 100644 --- a/arch/powerpc/lib/sstep.c +++ b/arch/powerpc/lib/sstep.c @@ -10,7 +10,6 @@ */ #include <linux/kernel.h> #include <linux/ptrace.h> -#include <linux/config.h> #include <asm/sstep.h> #include <asm/processor.h> diff --git a/arch/powerpc/lib/string.S b/arch/powerpc/lib/string.S index b9ca84ed8927..c4c622d8e6ac 100644 --- a/arch/powerpc/lib/string.S +++ b/arch/powerpc/lib/string.S @@ -8,7 +8,6 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <asm/processor.h> #include <asm/errno.h> #include <asm/ppc_asm.h> diff --git a/arch/powerpc/math-emu/math.c b/arch/powerpc/math-emu/math.c index 589153472761..69058b2873de 100644 --- a/arch/powerpc/math-emu/math.c +++ b/arch/powerpc/math-emu/math.c @@ -2,7 +2,6 @@ * Copyright (C) 1999 Eddie C. Dost (ecd@atecom.com) */ -#include <linux/config.h> #include <linux/types.h> #include <linux/sched.h> diff --git a/arch/powerpc/mm/44x_mmu.c b/arch/powerpc/mm/44x_mmu.c index 3d79ce281b67..0a0a0487b334 100644 --- a/arch/powerpc/mm/44x_mmu.c +++ b/arch/powerpc/mm/44x_mmu.c @@ -24,7 +24,6 @@ * */ -#include <linux/config.h> #include <linux/signal.h> #include <linux/sched.h> #include <linux/kernel.h> @@ -104,7 +103,7 @@ unsigned long __init mmu_mapin_ram(void) /* Determine number of entries necessary to cover lowmem */ pinned_tlbs = (unsigned int) - (_ALIGN(total_lowmem, PPC44x_PIN_SIZE) >> PPC44x_PIN_SHIFT); + (_ALIGN(total_lowmem, PPC_PIN_SIZE) >> PPC44x_PIN_SHIFT); /* Write upper watermark to save location */ tlb_44x_hwater = PPC44x_LOW_SLOT - pinned_tlbs; @@ -112,7 +111,7 @@ unsigned long __init mmu_mapin_ram(void) /* If necessary, set additional pinned TLBs */ if (pinned_tlbs > 1) for (i = (PPC44x_LOW_SLOT-(pinned_tlbs-1)); i < PPC44x_LOW_SLOT; i++) { - unsigned int phys_addr = (PPC44x_LOW_SLOT-i) * PPC44x_PIN_SIZE; + unsigned int phys_addr = (PPC44x_LOW_SLOT-i) * PPC_PIN_SIZE; ppc44x_pin_tlb(i, phys_addr+PAGE_OFFSET, phys_addr); } diff --git a/arch/powerpc/mm/4xx_mmu.c b/arch/powerpc/mm/4xx_mmu.c index 4d006aa1a0d1..838e09db71d9 100644 --- a/arch/powerpc/mm/4xx_mmu.c +++ b/arch/powerpc/mm/4xx_mmu.c @@ -21,7 +21,6 @@ * */ -#include <linux/config.h> #include <linux/signal.h> #include <linux/sched.h> #include <linux/kernel.h> diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c index fdbba4206d59..e8fa50624b70 100644 --- a/arch/powerpc/mm/fault.c +++ b/arch/powerpc/mm/fault.c @@ -15,7 +15,6 @@ * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <linux/signal.h> #include <linux/sched.h> #include <linux/kernel.h> @@ -40,6 +39,40 @@ #include <asm/kdebug.h> #include <asm/siginfo.h> +#ifdef CONFIG_KPROBES +ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); + +/* Hook to register for page fault notifications */ +int register_page_fault_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(¬ify_page_fault_chain, nb); +} + +int unregister_page_fault_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb); +} + +static inline int notify_page_fault(enum die_val val, const char *str, + struct pt_regs *regs, long err, int trap, int sig) +{ + struct die_args args = { + .regs = regs, + .str = str, + .err = err, + .trapnr = trap, + .signr = sig + }; + return atomic_notifier_call_chain(¬ify_page_fault_chain, val, &args); +} +#else +static inline int notify_page_fault(enum die_val val, const char *str, + struct pt_regs *regs, long err, int trap, int sig) +{ + return NOTIFY_DONE; +} +#endif + /* * Check whether the instruction at regs->nip is a store using * an update addressing form which will update r1. @@ -142,7 +175,7 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, is_write = error_code & ESR_DST; #endif /* CONFIG_4xx || CONFIG_BOOKE */ - if (notify_die(DIE_PAGE_FAULT, "page_fault", regs, error_code, + if (notify_page_fault(DIE_PAGE_FAULT, "page_fault", regs, error_code, 11, SIGSEGV) == NOTIFY_STOP) return 0; @@ -300,7 +333,7 @@ good_area: /* protection fault */ if (error_code & 0x08000000) goto bad_area; - if (!(vma->vm_flags & (VM_READ | VM_EXEC))) + if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE))) goto bad_area; } @@ -353,7 +386,7 @@ bad_area_nosemaphore: */ out_of_memory: up_read(&mm->mmap_sem); - if (current->pid == 1) { + if (is_init(current)) { yield(); down_read(&mm->mmap_sem); goto survive; diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c index 5d581bb3aa12..123da03ab118 100644 --- a/arch/powerpc/mm/fsl_booke_mmu.c +++ b/arch/powerpc/mm/fsl_booke_mmu.c @@ -26,7 +26,6 @@ * */ -#include <linux/config.h> #include <linux/signal.h> #include <linux/sched.h> #include <linux/kernel.h> diff --git a/arch/powerpc/mm/hash_low_32.S b/arch/powerpc/mm/hash_low_32.S index 94255beeecd3..bd68df5fa78a 100644 --- a/arch/powerpc/mm/hash_low_32.S +++ b/arch/powerpc/mm/hash_low_32.S @@ -21,7 +21,6 @@ * */ -#include <linux/config.h> #include <asm/reg.h> #include <asm/page.h> #include <asm/pgtable.h> diff --git a/arch/powerpc/mm/hash_low_64.S b/arch/powerpc/mm/hash_low_64.S index 52e914238959..9bc0a9c2b9bc 100644 --- a/arch/powerpc/mm/hash_low_64.S +++ b/arch/powerpc/mm/hash_low_64.S @@ -10,7 +10,6 @@ * described in the kernel's COPYING file. */ -#include <linux/config.h> #include <asm/reg.h> #include <asm/pgtable.h> #include <asm/mmu.h> diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c index a0f3cbd00d39..c90f124f3c71 100644 --- a/arch/powerpc/mm/hash_native_64.c +++ b/arch/powerpc/mm/hash_native_64.c @@ -520,7 +520,7 @@ static inline int tlb_batching_enabled(void) } #endif -void hpte_init_native(void) +void __init hpte_init_native(void) { ppc_md.hpte_invalidate = native_hpte_invalidate; ppc_md.hpte_updatepp = native_hpte_updatepp; @@ -530,5 +530,4 @@ void hpte_init_native(void) ppc_md.hpte_clear_all = native_hpte_clear; if (tlb_batching_enabled()) ppc_md.flush_hash_range = native_flush_hash_range; - htab_finish_init(); } diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index d03fd2b4445e..1915661c2c81 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c @@ -21,7 +21,6 @@ #undef DEBUG #undef DEBUG_LOW -#include <linux/config.h> #include <linux/spinlock.h> #include <linux/errno.h> #include <linux/sched.h> @@ -167,34 +166,12 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend, hash = hpt_hash(va, shift); hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP); - /* The crap below can be cleaned once ppd_md.probe() can - * set up the hash callbacks, thus we can just used the - * normal insert callback here. - */ -#ifdef CONFIG_PPC_ISERIES - if (machine_is(iseries)) - ret = iSeries_hpte_insert(hpteg, va, - paddr, - tmp_mode, - HPTE_V_BOLTED, - psize); - else -#endif -#ifdef CONFIG_PPC_PSERIES - if (machine_is(pseries) && firmware_has_feature(FW_FEATURE_LPAR)) - ret = pSeries_lpar_hpte_insert(hpteg, va, - paddr, - tmp_mode, - HPTE_V_BOLTED, - psize); - else -#endif -#ifdef CONFIG_PPC_MULTIPLATFORM - ret = native_hpte_insert(hpteg, va, - paddr, - tmp_mode, HPTE_V_BOLTED, - psize); -#endif + DBG("htab_bolt_mapping: calling %p\n", ppc_md.hpte_insert); + + BUG_ON(!ppc_md.hpte_insert); + ret = ppc_md.hpte_insert(hpteg, va, paddr, + tmp_mode, HPTE_V_BOLTED, psize); + if (ret < 0) break; } @@ -413,6 +390,41 @@ void create_section_mapping(unsigned long start, unsigned long end) } #endif /* CONFIG_MEMORY_HOTPLUG */ +static inline void make_bl(unsigned int *insn_addr, void *func) +{ + unsigned long funcp = *((unsigned long *)func); + int offset = funcp - (unsigned long)insn_addr; + + *insn_addr = (unsigned int)(0x48000001 | (offset & 0x03fffffc)); + flush_icache_range((unsigned long)insn_addr, 4+ + (unsigned long)insn_addr); +} + +static void __init htab_finish_init(void) +{ + extern unsigned int *htab_call_hpte_insert1; + extern unsigned int *htab_call_hpte_insert2; + extern unsigned int *htab_call_hpte_remove; + extern unsigned int *htab_call_hpte_updatepp; + +#ifdef CONFIG_PPC_64K_PAGES + extern unsigned int *ht64_call_hpte_insert1; + extern unsigned int *ht64_call_hpte_insert2; + extern unsigned int *ht64_call_hpte_remove; + extern unsigned int *ht64_call_hpte_updatepp; + + make_bl(ht64_call_hpte_insert1, ppc_md.hpte_insert); + make_bl(ht64_call_hpte_insert2, ppc_md.hpte_insert); + make_bl(ht64_call_hpte_remove, ppc_md.hpte_remove); + make_bl(ht64_call_hpte_updatepp, ppc_md.hpte_updatepp); +#endif /* CONFIG_PPC_64K_PAGES */ + + make_bl(htab_call_hpte_insert1, ppc_md.hpte_insert); + make_bl(htab_call_hpte_insert2, ppc_md.hpte_insert); + make_bl(htab_call_hpte_remove, ppc_md.hpte_remove); + make_bl(htab_call_hpte_updatepp, ppc_md.hpte_updatepp); +} + void __init htab_initialize(void) { unsigned long table; @@ -525,6 +537,8 @@ void __init htab_initialize(void) mmu_linear_psize)); } + htab_finish_init(); + DBG(" <- htab_initialize()\n"); } #undef KB @@ -787,16 +801,6 @@ void flush_hash_range(unsigned long number, int local) } } -static inline void make_bl(unsigned int *insn_addr, void *func) -{ - unsigned long funcp = *((unsigned long *)func); - int offset = funcp - (unsigned long)insn_addr; - - *insn_addr = (unsigned int)(0x48000001 | (offset & 0x03fffffc)); - flush_icache_range((unsigned long)insn_addr, 4+ - (unsigned long)insn_addr); -} - /* * low_hash_fault is called when we the low level hash code failed * to instert a PTE due to an hypervisor error @@ -815,28 +819,3 @@ void low_hash_fault(struct pt_regs *regs, unsigned long address) } bad_page_fault(regs, address, SIGBUS); } - -void __init htab_finish_init(void) -{ - extern unsigned int *htab_call_hpte_insert1; - extern unsigned int *htab_call_hpte_insert2; - extern unsigned int *htab_call_hpte_remove; - extern unsigned int *htab_call_hpte_updatepp; - -#ifdef CONFIG_PPC_64K_PAGES - extern unsigned int *ht64_call_hpte_insert1; - extern unsigned int *ht64_call_hpte_insert2; - extern unsigned int *ht64_call_hpte_remove; - extern unsigned int *ht64_call_hpte_updatepp; - - make_bl(ht64_call_hpte_insert1, ppc_md.hpte_insert); - make_bl(ht64_call_hpte_insert2, ppc_md.hpte_insert); - make_bl(ht64_call_hpte_remove, ppc_md.hpte_remove); - make_bl(ht64_call_hpte_updatepp, ppc_md.hpte_updatepp); -#endif /* CONFIG_PPC_64K_PAGES */ - - make_bl(htab_call_hpte_insert1, ppc_md.hpte_insert); - make_bl(htab_call_hpte_insert2, ppc_md.hpte_insert); - make_bl(htab_call_hpte_remove, ppc_md.hpte_remove); - make_bl(htab_call_hpte_updatepp, ppc_md.hpte_updatepp); -} diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index 266b8b2ceac9..5615acc29527 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -153,7 +153,7 @@ static void free_hugepte_range(struct mmu_gather *tlb, hugepd_t *hpdp) hpdp->pd = 0; tlb->need_flush = 1; pgtable_free_tlb(tlb, pgtable_free_cache(hugepte, HUGEPTE_CACHE_NUM, - HUGEPTE_TABLE_SIZE-1)); + PGF_CACHENUM_MASK)); } #ifdef CONFIG_PPC_64K_PAGES diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c index b57fb3a2b7bb..0e53ca8f02fb 100644 --- a/arch/powerpc/mm/init_32.c +++ b/arch/powerpc/mm/init_32.c @@ -18,7 +18,6 @@ * */ -#include <linux/config.h> #include <linux/module.h> #include <linux/sched.h> #include <linux/kernel.h> diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c index 9e30f968c184..3ff374697e34 100644 --- a/arch/powerpc/mm/init_64.c +++ b/arch/powerpc/mm/init_64.c @@ -22,7 +22,6 @@ #undef DEBUG -#include <linux/config.h> #include <linux/signal.h> #include <linux/sched.h> #include <linux/kernel.h> @@ -41,6 +40,7 @@ #include <linux/idr.h> #include <linux/nodemask.h> #include <linux/module.h> +#include <linux/poison.h> #include <asm/pgalloc.h> #include <asm/page.h> @@ -90,7 +90,7 @@ void free_initmem(void) addr = (unsigned long)__init_begin; for (; addr < (unsigned long)__init_end; addr += PAGE_SIZE) { - memset((void *)addr, 0xcc, PAGE_SIZE); + memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE); ClearPageReserved(virt_to_page(addr)); init_page_count(virt_to_page(addr)); free_page(addr); diff --git a/arch/powerpc/mm/lmb.c b/arch/powerpc/mm/lmb.c index 8b6f522655a6..716a2906a24d 100644 --- a/arch/powerpc/mm/lmb.c +++ b/arch/powerpc/mm/lmb.c @@ -10,7 +10,6 @@ * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/bitops.h> @@ -321,7 +320,8 @@ void __init lmb_enforce_memory_limit(unsigned long memory_limit) break; } - lmb.rmo_size = lmb.memory.region[0].size; + if (lmb.memory.region[0].size < lmb.rmo_size) + lmb.rmo_size = lmb.memory.region[0].size; /* And truncate any reserves above the limit also. */ for (i = 0; i < lmb.reserved.cnt; i++) { diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 69f3b9a20beb..16fe027bbc12 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -18,7 +18,6 @@ * */ -#include <linux/config.h> #include <linux/module.h> #include <linux/sched.h> #include <linux/kernel.h> @@ -114,15 +113,20 @@ void online_page(struct page *page) num_physpages++; } -int __devinit add_memory(u64 start, u64 size) +#ifdef CONFIG_NUMA +int memory_add_physaddr_to_nid(u64 start) +{ + return hot_add_scn_to_nid(start); +} +#endif + +int __devinit arch_add_memory(int nid, u64 start, u64 size) { struct pglist_data *pgdata; struct zone *zone; - int nid; unsigned long start_pfn = start >> PAGE_SHIFT; unsigned long nr_pages = size >> PAGE_SHIFT; - nid = hot_add_scn_to_nid(start); pgdata = NODE_DATA(nid); start = (unsigned long)__va(start); @@ -252,20 +256,22 @@ void __init do_init_bootmem(void) boot_mapsize = init_bootmem(start >> PAGE_SHIFT, total_pages); + /* Add active regions with valid PFNs */ + for (i = 0; i < lmb.memory.cnt; i++) { + unsigned long start_pfn, end_pfn; + start_pfn = lmb.memory.region[i].base >> PAGE_SHIFT; + end_pfn = start_pfn + lmb_size_pages(&lmb.memory, i); + add_active_range(0, start_pfn, end_pfn); + } + /* Add all physical memory to the bootmem map, mark each area * present. */ - for (i = 0; i < lmb.memory.cnt; i++) { - unsigned long base = lmb.memory.region[i].base; - unsigned long size = lmb_size_bytes(&lmb.memory, i); #ifdef CONFIG_HIGHMEM - if (base >= total_lowmem) - continue; - if (base + size > total_lowmem) - size = total_lowmem - base; + free_bootmem_with_active_regions(0, total_lowmem >> PAGE_SHIFT); +#else + free_bootmem_with_active_regions(0, max_pfn); #endif - free_bootmem(base, size); - } /* reserve the sections we're already using */ for (i = 0; i < lmb.reserved.cnt; i++) @@ -273,9 +279,8 @@ void __init do_init_bootmem(void) lmb_size_bytes(&lmb.reserved, i)); /* XXX need to clip this if using highmem? */ - for (i = 0; i < lmb.memory.cnt; i++) - memory_present(0, lmb_start_pfn(&lmb.memory, i), - lmb_end_pfn(&lmb.memory, i)); + sparse_memory_present_with_active_regions(0); + init_bootmem_done = 1; } @@ -284,10 +289,9 @@ void __init do_init_bootmem(void) */ void __init paging_init(void) { - unsigned long zones_size[MAX_NR_ZONES]; - unsigned long zholes_size[MAX_NR_ZONES]; unsigned long total_ram = lmb_phys_mem_size(); unsigned long top_of_ram = lmb_end_of_DRAM(); + unsigned long max_zone_pfns[MAX_NR_ZONES]; #ifdef CONFIG_HIGHMEM map_page(PKMAP_BASE, 0, 0); /* XXX gross */ @@ -303,26 +307,13 @@ void __init paging_init(void) top_of_ram, total_ram); printk(KERN_DEBUG "Memory hole size: %ldMB\n", (top_of_ram - total_ram) >> 20); - /* - * All pages are DMA-able so we put them all in the DMA zone. - */ - memset(zones_size, 0, sizeof(zones_size)); - memset(zholes_size, 0, sizeof(zholes_size)); - - zones_size[ZONE_DMA] = top_of_ram >> PAGE_SHIFT; - zholes_size[ZONE_DMA] = (top_of_ram - total_ram) >> PAGE_SHIFT; - #ifdef CONFIG_HIGHMEM - zones_size[ZONE_DMA] = total_lowmem >> PAGE_SHIFT; - zones_size[ZONE_HIGHMEM] = (total_memory - total_lowmem) >> PAGE_SHIFT; - zholes_size[ZONE_HIGHMEM] = (top_of_ram - total_ram) >> PAGE_SHIFT; + max_zone_pfns[0] = total_lowmem >> PAGE_SHIFT; + max_zone_pfns[1] = top_of_ram >> PAGE_SHIFT; #else - zones_size[ZONE_DMA] = top_of_ram >> PAGE_SHIFT; - zholes_size[ZONE_DMA] = (top_of_ram - total_ram) >> PAGE_SHIFT; -#endif /* CONFIG_HIGHMEM */ - - free_area_init_node(0, NODE_DATA(0), zones_size, - __pa(PAGE_OFFSET) >> PAGE_SHIFT, zholes_size); + max_zone_pfns[0] = top_of_ram >> PAGE_SHIFT; +#endif + free_area_init_nodes(max_zone_pfns); } #endif /* ! CONFIG_NEED_MULTIPLE_NODES */ diff --git a/arch/powerpc/mm/mmu_context_32.c b/arch/powerpc/mm/mmu_context_32.c index e326e4249e1a..792086b01000 100644 --- a/arch/powerpc/mm/mmu_context_32.c +++ b/arch/powerpc/mm/mmu_context_32.c @@ -23,7 +23,6 @@ * */ -#include <linux/config.h> #include <linux/mm.h> #include <linux/init.h> diff --git a/arch/powerpc/mm/mmu_context_64.c b/arch/powerpc/mm/mmu_context_64.c index 65d18dca266f..90a06ac02d5e 100644 --- a/arch/powerpc/mm/mmu_context_64.c +++ b/arch/powerpc/mm/mmu_context_64.c @@ -10,7 +10,6 @@ * */ -#include <linux/config.h> #include <linux/sched.h> #include <linux/kernel.h> #include <linux/errno.h> @@ -44,7 +43,9 @@ again: return err; if (index > MAX_CONTEXT) { + spin_lock(&mmu_context_lock); idr_remove(&mmu_context_idr, index); + spin_unlock(&mmu_context_lock); return -ENOMEM; } diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index aa98cb3b59d8..43c272075e1a 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -39,96 +39,6 @@ static bootmem_data_t __initdata plat_node_bdata[MAX_NUMNODES]; static int min_common_depth; static int n_mem_addr_cells, n_mem_size_cells; -/* - * We need somewhere to store start/end/node for each region until we have - * allocated the real node_data structures. - */ -#define MAX_REGIONS (MAX_LMB_REGIONS*2) -static struct { - unsigned long start_pfn; - unsigned long end_pfn; - int nid; -} init_node_data[MAX_REGIONS] __initdata; - -int __init early_pfn_to_nid(unsigned long pfn) -{ - unsigned int i; - - for (i = 0; init_node_data[i].end_pfn; i++) { - unsigned long start_pfn = init_node_data[i].start_pfn; - unsigned long end_pfn = init_node_data[i].end_pfn; - - if ((start_pfn <= pfn) && (pfn < end_pfn)) - return init_node_data[i].nid; - } - - return -1; -} - -void __init add_region(unsigned int nid, unsigned long start_pfn, - unsigned long pages) -{ - unsigned int i; - - dbg("add_region nid %d start_pfn 0x%lx pages 0x%lx\n", - nid, start_pfn, pages); - - for (i = 0; init_node_data[i].end_pfn; i++) { - if (init_node_data[i].nid != nid) - continue; - if (init_node_data[i].end_pfn == start_pfn) { - init_node_data[i].end_pfn += pages; - return; - } - if (init_node_data[i].start_pfn == (start_pfn + pages)) { - init_node_data[i].start_pfn -= pages; - return; - } - } - - /* - * Leave last entry NULL so we dont iterate off the end (we use - * entry.end_pfn to terminate the walk). - */ - if (i >= (MAX_REGIONS - 1)) { - printk(KERN_ERR "WARNING: too many memory regions in " - "numa code, truncating\n"); - return; - } - - init_node_data[i].start_pfn = start_pfn; - init_node_data[i].end_pfn = start_pfn + pages; - init_node_data[i].nid = nid; -} - -/* We assume init_node_data has no overlapping regions */ -void __init get_region(unsigned int nid, unsigned long *start_pfn, - unsigned long *end_pfn, unsigned long *pages_present) -{ - unsigned int i; - - *start_pfn = -1UL; - *end_pfn = *pages_present = 0; - - for (i = 0; init_node_data[i].end_pfn; i++) { - if (init_node_data[i].nid != nid) - continue; - - *pages_present += init_node_data[i].end_pfn - - init_node_data[i].start_pfn; - - if (init_node_data[i].start_pfn < *start_pfn) - *start_pfn = init_node_data[i].start_pfn; - - if (init_node_data[i].end_pfn > *end_pfn) - *end_pfn = init_node_data[i].end_pfn; - } - - /* We didnt find a matching region, return start/end as 0 */ - if (*start_pfn == -1UL) - *start_pfn = 0; -} - static void __cpuinit map_cpu_to_node(int cpu, int node) { numa_cpu_lookup_table[cpu] = node; @@ -159,12 +69,12 @@ static struct device_node * __cpuinit find_cpu_node(unsigned int cpu) { unsigned int hw_cpuid = get_hard_smp_processor_id(cpu); struct device_node *cpu_node = NULL; - unsigned int *interrupt_server, *reg; + const unsigned int *interrupt_server, *reg; int len; while ((cpu_node = of_find_node_by_type(cpu_node, "cpu")) != NULL) { /* Try interrupt server first */ - interrupt_server = (unsigned int *)get_property(cpu_node, + interrupt_server = get_property(cpu_node, "ibm,ppc-interrupt-server#s", &len); len = len / sizeof(u32); @@ -175,8 +85,7 @@ static struct device_node * __cpuinit find_cpu_node(unsigned int cpu) return cpu_node; } } else { - reg = (unsigned int *)get_property(cpu_node, - "reg", &len); + reg = get_property(cpu_node, "reg", &len); if (reg && (len > 0) && (reg[0] == hw_cpuid)) return cpu_node; } @@ -186,9 +95,9 @@ static struct device_node * __cpuinit find_cpu_node(unsigned int cpu) } /* must hold reference to node during call */ -static int *of_get_associativity(struct device_node *dev) +static const int *of_get_associativity(struct device_node *dev) { - return (unsigned int *)get_property(dev, "ibm,associativity", NULL); + return get_property(dev, "ibm,associativity", NULL); } /* Returns nid in the range [0..MAX_NUMNODES-1], or -1 if no useful numa @@ -197,7 +106,7 @@ static int *of_get_associativity(struct device_node *dev) static int of_node_to_nid_single(struct device_node *device) { int nid = -1; - unsigned int *tmp; + const unsigned int *tmp; if (min_common_depth == -1) goto out; @@ -255,7 +164,7 @@ EXPORT_SYMBOL_GPL(of_node_to_nid); static int __init find_min_common_depth(void) { int depth; - unsigned int *ref_points; + const unsigned int *ref_points; struct device_node *rtas_root; unsigned int len; @@ -270,7 +179,7 @@ static int __init find_min_common_depth(void) * configuration (should be all 0's) and the second is for a normal * NUMA configuration. */ - ref_points = (unsigned int *)get_property(rtas_root, + ref_points = get_property(rtas_root, "ibm,associativity-reference-points", &len); if ((len >= 1) && ref_points) { @@ -297,7 +206,7 @@ static void __init get_n_mem_cells(int *n_addr_cells, int *n_size_cells) of_node_put(memory); } -static unsigned long __devinit read_n_cells(int n, unsigned int **buf) +static unsigned long __devinit read_n_cells(int n, const unsigned int **buf) { unsigned long result = 0; @@ -334,7 +243,7 @@ out: return nid; } -static int cpu_numa_callback(struct notifier_block *nfb, +static int __cpuinit cpu_numa_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { @@ -435,15 +344,13 @@ static int __init parse_numa_properties(void) unsigned long size; int nid; int ranges; - unsigned int *memcell_buf; + const unsigned int *memcell_buf; unsigned int len; - memcell_buf = (unsigned int *)get_property(memory, + memcell_buf = get_property(memory, "linux,usable-memory", &len); if (!memcell_buf || len <= 0) - memcell_buf = - (unsigned int *)get_property(memory, "reg", - &len); + memcell_buf = get_property(memory, "reg", &len); if (!memcell_buf || len <= 0) continue; @@ -471,8 +378,8 @@ new_range: continue; } - add_region(nid, start >> PAGE_SHIFT, - size >> PAGE_SHIFT); + add_active_range(nid, start >> PAGE_SHIFT, + (start >> PAGE_SHIFT) + (size >> PAGE_SHIFT)); if (--ranges) goto new_range; @@ -485,6 +392,7 @@ static void __init setup_nonnuma(void) { unsigned long top_of_ram = lmb_end_of_DRAM(); unsigned long total_ram = lmb_phys_mem_size(); + unsigned long start_pfn, end_pfn; unsigned int i; printk(KERN_DEBUG "Top of RAM: 0x%lx, Total RAM: 0x%lx\n", @@ -492,9 +400,11 @@ static void __init setup_nonnuma(void) printk(KERN_DEBUG "Memory hole size: %ldMB\n", (top_of_ram - total_ram) >> 20); - for (i = 0; i < lmb.memory.cnt; ++i) - add_region(0, lmb.memory.region[i].base >> PAGE_SHIFT, - lmb_size_pages(&lmb.memory, i)); + for (i = 0; i < lmb.memory.cnt; ++i) { + start_pfn = lmb.memory.region[i].base >> PAGE_SHIFT; + end_pfn = start_pfn + lmb_size_pages(&lmb.memory, i); + add_active_range(0, start_pfn, end_pfn); + } node_set_online(0); } @@ -609,14 +519,15 @@ static void __init *careful_allocation(int nid, unsigned long size, return (void *)ret; } +static struct notifier_block __cpuinitdata ppc64_numa_nb = { + .notifier_call = cpu_numa_callback, + .priority = 1 /* Must run before sched domains notifier. */ +}; + void __init do_init_bootmem(void) { int nid; unsigned int i; - static struct notifier_block ppc64_numa_nb = { - .notifier_call = cpu_numa_callback, - .priority = 1 /* Must run before sched domains notifier. */ - }; min_low_pfn = 0; max_low_pfn = lmb_end_of_DRAM() >> PAGE_SHIFT; @@ -632,11 +543,11 @@ void __init do_init_bootmem(void) (void *)(unsigned long)boot_cpuid); for_each_online_node(nid) { - unsigned long start_pfn, end_pfn, pages_present; + unsigned long start_pfn, end_pfn; unsigned long bootmem_paddr; unsigned long bootmap_pages; - get_region(nid, &start_pfn, &end_pfn, &pages_present); + get_pfn_range_for_nid(nid, &start_pfn, &end_pfn); /* Allocate the node structure node local if possible */ NODE_DATA(nid) = careful_allocation(nid, @@ -669,19 +580,7 @@ void __init do_init_bootmem(void) init_bootmem_node(NODE_DATA(nid), bootmem_paddr >> PAGE_SHIFT, start_pfn, end_pfn); - /* Add free regions on this node */ - for (i = 0; init_node_data[i].end_pfn; i++) { - unsigned long start, end; - - if (init_node_data[i].nid != nid) - continue; - - start = init_node_data[i].start_pfn << PAGE_SHIFT; - end = init_node_data[i].end_pfn << PAGE_SHIFT; - - dbg("free_bootmem %lx %lx\n", start, end - start); - free_bootmem_node(NODE_DATA(nid), start, end - start); - } + free_bootmem_with_active_regions(nid, end_pfn); /* Mark reserved regions on this node */ for (i = 0; i < lmb.reserved.cnt; i++) { @@ -712,44 +611,16 @@ void __init do_init_bootmem(void) } } - /* Add regions into sparsemem */ - for (i = 0; init_node_data[i].end_pfn; i++) { - unsigned long start, end; - - if (init_node_data[i].nid != nid) - continue; - - start = init_node_data[i].start_pfn; - end = init_node_data[i].end_pfn; - - memory_present(nid, start, end); - } + sparse_memory_present_with_active_regions(nid); } } void __init paging_init(void) { - unsigned long zones_size[MAX_NR_ZONES]; - unsigned long zholes_size[MAX_NR_ZONES]; - int nid; - - memset(zones_size, 0, sizeof(zones_size)); - memset(zholes_size, 0, sizeof(zholes_size)); - - for_each_online_node(nid) { - unsigned long start_pfn, end_pfn, pages_present; - - get_region(nid, &start_pfn, &end_pfn, &pages_present); - - zones_size[ZONE_DMA] = end_pfn - start_pfn; - zholes_size[ZONE_DMA] = zones_size[ZONE_DMA] - pages_present; - - dbg("free_area_init node %d %lx %lx (hole: %lx)\n", nid, - zones_size[ZONE_DMA], start_pfn, zholes_size[ZONE_DMA]); - - free_area_init_node(nid, NODE_DATA(nid), zones_size, start_pfn, - zholes_size); - } + unsigned long max_zone_pfns[MAX_NR_ZONES] = { + lmb_end_of_DRAM() >> PAGE_SHIFT + }; + free_area_init_nodes(max_zone_pfns); } static int __init early_numa(char *p) @@ -786,10 +657,10 @@ int hot_add_scn_to_nid(unsigned long scn_addr) while ((memory = of_find_node_by_type(memory, "memory")) != NULL) { unsigned long start, size; int ranges; - unsigned int *memcell_buf; + const unsigned int *memcell_buf; unsigned int len; - memcell_buf = (unsigned int *)get_property(memory, "reg", &len); + memcell_buf = get_property(memory, "reg", &len); if (!memcell_buf || len <= 0) continue; diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c index 90628601fac7..8fcacb0239da 100644 --- a/arch/powerpc/mm/pgtable_32.c +++ b/arch/powerpc/mm/pgtable_32.c @@ -20,7 +20,6 @@ * */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/types.h> diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c index 7b278d83739e..b1da03165496 100644 --- a/arch/powerpc/mm/pgtable_64.c +++ b/arch/powerpc/mm/pgtable_64.c @@ -22,7 +22,6 @@ * */ -#include <linux/config.h> #include <linux/signal.h> #include <linux/sched.h> #include <linux/kernel.h> diff --git a/arch/powerpc/mm/ppc_mmu_32.c b/arch/powerpc/mm/ppc_mmu_32.c index 2ed43a493b31..7cceb2c44cb9 100644 --- a/arch/powerpc/mm/ppc_mmu_32.c +++ b/arch/powerpc/mm/ppc_mmu_32.c @@ -23,7 +23,6 @@ * */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/mm.h> #include <linux/init.h> diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c index 6a8bf6c6000e..d3733912adb4 100644 --- a/arch/powerpc/mm/slb.c +++ b/arch/powerpc/mm/slb.c @@ -16,13 +16,14 @@ #undef DEBUG -#include <linux/config.h> #include <asm/pgtable.h> #include <asm/mmu.h> #include <asm/mmu_context.h> #include <asm/paca.h> #include <asm/cputable.h> #include <asm/cacheflush.h> +#include <asm/smp.h> +#include <linux/compiler.h> #ifdef DEBUG #define DBG(fmt...) udbg_printf(fmt) @@ -51,9 +52,32 @@ static inline unsigned long mk_vsid_data(unsigned long ea, unsigned long flags) return (get_kernel_vsid(ea) << SLB_VSID_SHIFT) | flags; } -static inline void create_slbe(unsigned long ea, unsigned long flags, - unsigned long entry) +static inline void slb_shadow_update(unsigned long esid, unsigned long vsid, + unsigned long entry) { + /* + * Clear the ESID first so the entry is not valid while we are + * updating it. + */ + get_slb_shadow()->save_area[entry].esid = 0; + barrier(); + get_slb_shadow()->save_area[entry].vsid = vsid; + barrier(); + get_slb_shadow()->save_area[entry].esid = esid; + +} + +static inline void create_shadowed_slbe(unsigned long ea, unsigned long flags, + unsigned long entry) +{ + /* + * Updating the shadow buffer before writing the SLB ensures + * we don't get a stale entry here if we get preempted by PHYP + * between these two statements. + */ + slb_shadow_update(mk_esid_data(ea, entry), mk_vsid_data(ea, flags), + entry); + asm volatile("slbmte %0,%1" : : "r" (mk_vsid_data(ea, flags)), "r" (mk_esid_data(ea, entry)) @@ -78,6 +102,10 @@ void slb_flush_and_rebolt(void) if ((ksp_esid_data & ESID_MASK) == PAGE_OFFSET) ksp_esid_data &= ~SLB_ESID_V; + /* Only third entry (stack) may change here so only resave that */ + slb_shadow_update(ksp_esid_data, + mk_vsid_data(ksp_esid_data, lflags), 2); + /* We need to do this all in asm, so we're sure we don't touch * the stack between the slbia and rebolting it. */ asm volatile("isync\n" @@ -210,9 +238,9 @@ void slb_initialize(void) asm volatile("isync":::"memory"); asm volatile("slbmte %0,%0"::"r" (0) : "memory"); asm volatile("isync; slbia; isync":::"memory"); - create_slbe(PAGE_OFFSET, lflags, 0); + create_shadowed_slbe(PAGE_OFFSET, lflags, 0); - create_slbe(VMALLOC_START, vflags, 1); + create_shadowed_slbe(VMALLOC_START, vflags, 1); /* We don't bolt the stack for the time being - we're in boot, * so the stack is in the bolted segment. By the time it goes diff --git a/arch/powerpc/mm/slb_low.S b/arch/powerpc/mm/slb_low.S index 8548dcf8ef8b..dbc1abbde038 100644 --- a/arch/powerpc/mm/slb_low.S +++ b/arch/powerpc/mm/slb_low.S @@ -14,7 +14,6 @@ * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <asm/processor.h> #include <asm/ppc_asm.h> #include <asm/asm-offsets.h> diff --git a/arch/powerpc/mm/stab.c b/arch/powerpc/mm/stab.c index 691320c90b78..eeeacab548e6 100644 --- a/arch/powerpc/mm/stab.c +++ b/arch/powerpc/mm/stab.c @@ -12,7 +12,6 @@ * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <asm/pgtable.h> #include <asm/mmu.h> #include <asm/mmu_context.h> diff --git a/arch/powerpc/mm/tlb_32.c b/arch/powerpc/mm/tlb_32.c index 02eb23e036d5..925ff70be8ba 100644 --- a/arch/powerpc/mm/tlb_32.c +++ b/arch/powerpc/mm/tlb_32.c @@ -23,7 +23,6 @@ * */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/mm.h> #include <linux/init.h> diff --git a/arch/powerpc/mm/tlb_64.c b/arch/powerpc/mm/tlb_64.c index e7449b068c82..b58baa65c4a7 100644 --- a/arch/powerpc/mm/tlb_64.c +++ b/arch/powerpc/mm/tlb_64.c @@ -22,7 +22,6 @@ * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/mm.h> #include <linux/init.h> @@ -147,6 +146,7 @@ void hpte_update(struct mm_struct *mm, unsigned long addr, psize = mmu_huge_psize; #else BUG(); + psize = pte_pagesize_index(pte); /* shutup gcc */ #endif } else psize = pte_pagesize_index(pte); diff --git a/arch/powerpc/oprofile/common.c b/arch/powerpc/oprofile/common.c index 27ad56bd227e..fd0bbbe7a4de 100644 --- a/arch/powerpc/oprofile/common.c +++ b/arch/powerpc/oprofile/common.c @@ -94,7 +94,7 @@ static int op_powerpc_create_files(struct super_block *sb, struct dentry *root) for (i = 0; i < model->num_counters; ++i) { struct dentry *dir; - char buf[3]; + char buf[4]; snprintf(buf, sizeof buf, "%d", i); dir = oprofilefs_mkdir(sb, root, buf); diff --git a/arch/powerpc/platforms/83xx/Kconfig b/arch/powerpc/platforms/83xx/Kconfig index 7675e675dce1..5fe7b7faf45f 100644 --- a/arch/powerpc/platforms/83xx/Kconfig +++ b/arch/powerpc/platforms/83xx/Kconfig @@ -16,12 +16,21 @@ config MPC834x_SYS 3 PCI slots. The PIBs PCI initialization is the bootloader's responsiblilty. +config MPC834x_ITX + bool "Freescale MPC834x ITX" + select DEFAULT_UIMAGE + help + This option enables support for the MPC 834x ITX evaluation board. + + Be aware that PCI initialization is the bootloader's + responsiblilty. + endchoice config MPC834x bool select PPC_UDBG_16550 select PPC_INDIRECT_PCI - default y if MPC834x_SYS + default y if MPC834x_SYS || MPC834x_ITX endmenu diff --git a/arch/powerpc/platforms/83xx/Makefile b/arch/powerpc/platforms/83xx/Makefile index 5c72367441a8..9387a110d28a 100644 --- a/arch/powerpc/platforms/83xx/Makefile +++ b/arch/powerpc/platforms/83xx/Makefile @@ -4,3 +4,4 @@ obj-y := misc.o obj-$(CONFIG_PCI) += pci.o obj-$(CONFIG_MPC834x_SYS) += mpc834x_sys.o +obj-$(CONFIG_MPC834x_ITX) += mpc834x_itx.o diff --git a/arch/powerpc/platforms/83xx/misc.c b/arch/powerpc/platforms/83xx/misc.c index 1455bcef4892..f0c6df61faa9 100644 --- a/arch/powerpc/platforms/83xx/misc.c +++ b/arch/powerpc/platforms/83xx/misc.c @@ -9,7 +9,6 @@ * option) any later version. */ -#include <linux/config.h> #include <linux/stddef.h> #include <linux/kernel.h> diff --git a/arch/powerpc/platforms/83xx/mpc834x_itx.c b/arch/powerpc/platforms/83xx/mpc834x_itx.c new file mode 100644 index 000000000000..969fbb6d8c46 --- /dev/null +++ b/arch/powerpc/platforms/83xx/mpc834x_itx.c @@ -0,0 +1,125 @@ +/* + * arch/powerpc/platforms/83xx/mpc834x_itx.c + * + * MPC834x ITX board specific routines + * + * Maintainer: Kumar Gala <galak@kernel.crashing.org> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/config.h> +#include <linux/stddef.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/errno.h> +#include <linux/reboot.h> +#include <linux/pci.h> +#include <linux/kdev_t.h> +#include <linux/major.h> +#include <linux/console.h> +#include <linux/delay.h> +#include <linux/seq_file.h> +#include <linux/root_dev.h> + +#include <asm/system.h> +#include <asm/atomic.h> +#include <asm/time.h> +#include <asm/io.h> +#include <asm/machdep.h> +#include <asm/ipic.h> +#include <asm/bootinfo.h> +#include <asm/irq.h> +#include <asm/prom.h> +#include <asm/udbg.h> +#include <sysdev/fsl_soc.h> + +#include "mpc83xx.h" + +#include <platforms/83xx/mpc834x_sys.h> + +#ifndef CONFIG_PCI +unsigned long isa_io_base = 0; +unsigned long isa_mem_base = 0; +#endif + +/* ************************************************************************ + * + * Setup the architecture + * + */ +static void __init mpc834x_itx_setup_arch(void) +{ + struct device_node *np; + + if (ppc_md.progress) + ppc_md.progress("mpc834x_itx_setup_arch()", 0); + + np = of_find_node_by_type(NULL, "cpu"); + if (np != 0) { + const unsigned int *fp = + get_property(np, "clock-frequency", NULL); + if (fp != 0) + loops_per_jiffy = *fp / HZ; + else + loops_per_jiffy = 50000000 / HZ; + of_node_put(np); + } +#ifdef CONFIG_PCI + for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) + add_bridge(np); + + ppc_md.pci_exclude_device = mpc83xx_exclude_device; +#endif + +#ifdef CONFIG_ROOT_NFS + ROOT_DEV = Root_NFS; +#else + ROOT_DEV = Root_HDA1; +#endif +} + +void __init mpc834x_itx_init_IRQ(void) +{ + struct device_node *np; + + np = of_find_node_by_type(NULL, "ipic"); + if (!np) + return; + + ipic_init(np, 0); + + /* Initialize the default interrupt mapping priorities, + * in case the boot rom changed something on us. + */ + ipic_set_default_priority(); +} + +/* + * Called very early, MMU is off, device-tree isn't unflattened + */ +static int __init mpc834x_itx_probe(void) +{ + /* We always match for now, eventually we should look at the flat + dev tree to ensure this is the board we are suppose to run on + */ + return 1; +} + +define_machine(mpc834x_itx) { + .name = "MPC834x ITX", + .probe = mpc834x_itx_probe, + .setup_arch = mpc834x_itx_setup_arch, + .init_IRQ = mpc834x_itx_init_IRQ, + .get_irq = ipic_get_irq, + .restart = mpc83xx_restart, + .time_init = mpc83xx_time_init, + .calibrate_decr = generic_calibrate_decr, + .progress = udbg_progress, +#ifdef CONFIG_PCI + .pcibios_fixup = mpc83xx_pcibios_fixup, +#endif +}; diff --git a/arch/powerpc/platforms/83xx/mpc834x_itx.h b/arch/powerpc/platforms/83xx/mpc834x_itx.h new file mode 100644 index 000000000000..174ca4ef55f3 --- /dev/null +++ b/arch/powerpc/platforms/83xx/mpc834x_itx.h @@ -0,0 +1,23 @@ +/* + * arch/powerpc/platforms/83xx/mpc834x_itx.h + * + * MPC834X ITX common board definitions + * + * Maintainer: Kumar Gala <galak@kernel.crashing.org> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#ifndef __MACH_MPC83XX_ITX_H__ +#define __MACH_MPC83XX_ITX_H__ + +#define PIRQA MPC83xx_IRQ_EXT4 +#define PIRQB MPC83xx_IRQ_EXT5 +#define PIRQC MPC83xx_IRQ_EXT6 +#define PIRQD MPC83xx_IRQ_EXT7 + +#endif /* __MACH_MPC83XX_ITX_H__ */ diff --git a/arch/powerpc/platforms/83xx/mpc834x_sys.c b/arch/powerpc/platforms/83xx/mpc834x_sys.c index 7e789d2420ba..677196187a4e 100644 --- a/arch/powerpc/platforms/83xx/mpc834x_sys.c +++ b/arch/powerpc/platforms/83xx/mpc834x_sys.c @@ -11,7 +11,6 @@ * option) any later version. */ -#include <linux/config.h> #include <linux/stddef.h> #include <linux/kernel.h> #include <linux/init.h> @@ -44,33 +43,6 @@ unsigned long isa_io_base = 0; unsigned long isa_mem_base = 0; #endif -#ifdef CONFIG_PCI -static int -mpc83xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) -{ - static char pci_irq_table[][4] = - /* - * PCI IDSEL/INTPIN->INTLINE - * A B C D - */ - { - {PIRQA, PIRQB, PIRQC, PIRQD}, /* idsel 0x11 */ - {PIRQC, PIRQD, PIRQA, PIRQB}, /* idsel 0x12 */ - {PIRQD, PIRQA, PIRQB, PIRQC}, /* idsel 0x13 */ - {0, 0, 0, 0}, - {PIRQA, PIRQB, PIRQC, PIRQD}, /* idsel 0x15 */ - {PIRQD, PIRQA, PIRQB, PIRQC}, /* idsel 0x16 */ - {PIRQC, PIRQD, PIRQA, PIRQB}, /* idsel 0x17 */ - {PIRQB, PIRQC, PIRQD, PIRQA}, /* idsel 0x18 */ - {0, 0, 0, 0}, /* idsel 0x19 */ - {0, 0, 0, 0}, /* idsel 0x20 */ - }; - - const long min_idsel = 0x11, max_idsel = 0x20, irqs_per_slot = 4; - return PCI_IRQ_TABLE_LOOKUP; -} -#endif /* CONFIG_PCI */ - /* ************************************************************************ * * Setup the architecture @@ -85,8 +57,8 @@ static void __init mpc834x_sys_setup_arch(void) np = of_find_node_by_type(NULL, "cpu"); if (np != 0) { - unsigned int *fp = - (int *)get_property(np, "clock-frequency", NULL); + const unsigned int *fp = + get_property(np, "clock-frequency", NULL); if (fp != 0) loops_per_jiffy = *fp / HZ; else @@ -97,8 +69,6 @@ static void __init mpc834x_sys_setup_arch(void) for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) add_bridge(np); - ppc_md.pci_swizzle = common_swizzle; - ppc_md.pci_map_irq = mpc83xx_map_irq; ppc_md.pci_exclude_device = mpc83xx_exclude_device; #endif @@ -111,25 +81,13 @@ static void __init mpc834x_sys_setup_arch(void) void __init mpc834x_sys_init_IRQ(void) { - u8 senses[8] = { - 0, /* EXT 0 */ - IRQ_SENSE_LEVEL, /* EXT 1 */ - IRQ_SENSE_LEVEL, /* EXT 2 */ - 0, /* EXT 3 */ -#ifdef CONFIG_PCI - IRQ_SENSE_LEVEL, /* EXT 4 */ - IRQ_SENSE_LEVEL, /* EXT 5 */ - IRQ_SENSE_LEVEL, /* EXT 6 */ - IRQ_SENSE_LEVEL, /* EXT 7 */ -#else - 0, /* EXT 4 */ - 0, /* EXT 5 */ - 0, /* EXT 6 */ - 0, /* EXT 7 */ -#endif - }; + struct device_node *np; + + np = of_find_node_by_type(NULL, "ipic"); + if (!np) + return; - ipic_init(get_immrbase() + 0x00700, 0, 0, senses, 8); + ipic_init(np, 0); /* Initialize the default interrupt mapping priorities, * in case the boot rom changed something on us. @@ -179,4 +137,7 @@ define_machine(mpc834x_sys) { .time_init = mpc83xx_time_init, .calibrate_decr = generic_calibrate_decr, .progress = udbg_progress, +#ifdef CONFIG_PCI + .pcibios_fixup = mpc83xx_pcibios_fixup, +#endif }; diff --git a/arch/powerpc/platforms/83xx/mpc83xx.h b/arch/powerpc/platforms/83xx/mpc83xx.h index 01cae106912b..2c82bca9bfbb 100644 --- a/arch/powerpc/platforms/83xx/mpc83xx.h +++ b/arch/powerpc/platforms/83xx/mpc83xx.h @@ -11,6 +11,7 @@ extern int add_bridge(struct device_node *dev); extern int mpc83xx_exclude_device(u_char bus, u_char devfn); +extern void mpc83xx_pcibios_fixup(void); extern void mpc83xx_restart(char *cmd); extern long mpc83xx_time_init(void); diff --git a/arch/powerpc/platforms/83xx/pci.c b/arch/powerpc/platforms/83xx/pci.c index 16f7d3b30e1d..4557ac5255c1 100644 --- a/arch/powerpc/platforms/83xx/pci.c +++ b/arch/powerpc/platforms/83xx/pci.c @@ -9,7 +9,6 @@ * option) any later version. */ -#include <linux/config.h> #include <linux/stddef.h> #include <linux/kernel.h> #include <linux/init.h> @@ -46,12 +45,21 @@ int mpc83xx_exclude_device(u_char bus, u_char devfn) return PCIBIOS_SUCCESSFUL; } +void __init mpc83xx_pcibios_fixup(void) +{ + struct pci_dev *dev = NULL; + + /* map all the PCI irqs */ + for_each_pci_dev(dev) + pci_read_irq_line(dev); +} + int __init add_bridge(struct device_node *dev) { int len; struct pci_controller *hose; struct resource rsrc; - int *bus_range; + const int *bus_range; int primary = 1, has_address = 0; phys_addr_t immr = get_immrbase(); @@ -61,7 +69,7 @@ int __init add_bridge(struct device_node *dev) has_address = (of_address_to_resource(dev, 0, &rsrc) == 0); /* Get bus range if any */ - bus_range = (int *)get_property(dev, "bus-range", &len); + bus_range = get_property(dev, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) { printk(KERN_WARNING "Can't get bus-range for %s, assume" " bus 0\n", dev->full_name); @@ -91,9 +99,10 @@ int __init add_bridge(struct device_node *dev) mpc83xx_pci2_busno = hose->first_busno; } - printk(KERN_INFO "Found MPC83xx PCI host bridge at 0x%08lx. " + printk(KERN_INFO "Found MPC83xx PCI host bridge at 0x%016llx. " "Firmware bus number: %d->%d\n", - rsrc.start, hose->first_busno, hose->last_busno); + (unsigned long long)rsrc.start, hose->first_busno, + hose->last_busno); DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n", hose, hose->cfg_addr, hose->cfg_data); diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig index 454fc53289ab..c3268d9877e4 100644 --- a/arch/powerpc/platforms/85xx/Kconfig +++ b/arch/powerpc/platforms/85xx/Kconfig @@ -14,7 +14,6 @@ config MPC8540_ADS config MPC85xx_CDS bool "Freescale MPC85xx CDS" select DEFAULT_UIMAGE - select PPC_I8259 if PCI help This option enables support for the MPC85xx CDS board diff --git a/arch/powerpc/platforms/85xx/mpc8540_ads.h b/arch/powerpc/platforms/85xx/mpc8540_ads.h index f770cadb2080..c0d56d2bb5a5 100644 --- a/arch/powerpc/platforms/85xx/mpc8540_ads.h +++ b/arch/powerpc/platforms/85xx/mpc8540_ads.h @@ -17,7 +17,6 @@ #ifndef __MACH_MPC8540ADS_H__ #define __MACH_MPC8540ADS_H__ -#include <linux/config.h> #include <linux/initrd.h> #define BOARD_CCSRBAR ((uint)0xe0000000) diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/arch/powerpc/platforms/85xx/mpc85xx_ads.c index 5eeff370f5fc..cae6b73357d5 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_ads.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.c @@ -11,7 +11,6 @@ * option) any later version. */ -#include <linux/config.h> #include <linux/stddef.h> #include <linux/kernel.h> #include <linux/pci.h> @@ -38,79 +37,7 @@ unsigned long isa_io_base = 0; unsigned long isa_mem_base = 0; #endif -/* - * Internal interrupts are all Level Sensitive, and Positive Polarity - * - * Note: Likely, this table and the following function should be - * obtained and derived from the OF Device Tree. - */ -static u_char mpc85xx_ads_openpic_initsenses[] __initdata = { - MPC85XX_INTERNAL_IRQ_SENSES, - 0x0, /* External 0: */ -#if defined(CONFIG_PCI) - (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 1: PCI slot 0 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 2: PCI slot 1 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 3: PCI slot 2 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 4: PCI slot 3 */ -#else - 0x0, /* External 1: */ - 0x0, /* External 2: */ - 0x0, /* External 3: */ - 0x0, /* External 4: */ -#endif - (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 5: PHY */ - 0x0, /* External 6: */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 7: PHY */ - 0x0, /* External 8: */ - 0x0, /* External 9: */ - 0x0, /* External 10: */ - 0x0, /* External 11: */ -}; - #ifdef CONFIG_PCI -/* - * interrupt routing - */ - -int -mpc85xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) -{ - static char pci_irq_table[][4] = - /* - * This is little evil, but works around the fact - * that revA boards have IDSEL starting at 18 - * and others boards (older) start at 12 - * - * PCI IDSEL/INTPIN->INTLINE - * A B C D - */ - { - {PIRQA, PIRQB, PIRQC, PIRQD}, /* IDSEL 2 */ - {PIRQD, PIRQA, PIRQB, PIRQC}, - {PIRQC, PIRQD, PIRQA, PIRQB}, - {PIRQB, PIRQC, PIRQD, PIRQA}, /* IDSEL 5 */ - {0, 0, 0, 0}, /* -- */ - {0, 0, 0, 0}, /* -- */ - {0, 0, 0, 0}, /* -- */ - {0, 0, 0, 0}, /* -- */ - {0, 0, 0, 0}, /* -- */ - {0, 0, 0, 0}, /* -- */ - {PIRQA, PIRQB, PIRQC, PIRQD}, /* IDSEL 12 */ - {PIRQD, PIRQA, PIRQB, PIRQC}, - {PIRQC, PIRQD, PIRQA, PIRQB}, - {PIRQB, PIRQC, PIRQD, PIRQA}, /* IDSEL 15 */ - {0, 0, 0, 0}, /* -- */ - {0, 0, 0, 0}, /* -- */ - {PIRQA, PIRQB, PIRQC, PIRQD}, /* IDSEL 18 */ - {PIRQD, PIRQA, PIRQB, PIRQC}, - {PIRQC, PIRQD, PIRQA, PIRQB}, - {PIRQB, PIRQC, PIRQD, PIRQA}, /* IDSEL 21 */ - }; - - const long min_idsel = 2, max_idsel = 21, irqs_per_slot = 4; - return PCI_IRQ_TABLE_LOOKUP; -} - int mpc85xx_exclude_device(u_char bus, u_char devfn) { @@ -120,44 +47,63 @@ mpc85xx_exclude_device(u_char bus, u_char devfn) return PCIBIOS_SUCCESSFUL; } +void __init +mpc85xx_pcibios_fixup(void) +{ + struct pci_dev *dev = NULL; + + for_each_pci_dev(dev) + pci_read_irq_line(dev); +} #endif /* CONFIG_PCI */ void __init mpc85xx_ads_pic_init(void) { - struct mpic *mpic1; - phys_addr_t OpenPIC_PAddr; - - /* Determine the Physical Address of the OpenPIC regs */ - OpenPIC_PAddr = get_immrbase() + MPC85xx_OPENPIC_OFFSET; - - mpic1 = mpic_alloc(OpenPIC_PAddr, - MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, - 4, MPC85xx_OPENPIC_IRQ_OFFSET, 0, 250, - mpc85xx_ads_openpic_initsenses, - sizeof(mpc85xx_ads_openpic_initsenses), - " OpenPIC "); - BUG_ON(mpic1 == NULL); - mpic_assign_isu(mpic1, 0, OpenPIC_PAddr + 0x10200); - mpic_assign_isu(mpic1, 1, OpenPIC_PAddr + 0x10280); - mpic_assign_isu(mpic1, 2, OpenPIC_PAddr + 0x10300); - mpic_assign_isu(mpic1, 3, OpenPIC_PAddr + 0x10380); - mpic_assign_isu(mpic1, 4, OpenPIC_PAddr + 0x10400); - mpic_assign_isu(mpic1, 5, OpenPIC_PAddr + 0x10480); - mpic_assign_isu(mpic1, 6, OpenPIC_PAddr + 0x10500); - mpic_assign_isu(mpic1, 7, OpenPIC_PAddr + 0x10580); - - /* dummy mappings to get to 48 */ - mpic_assign_isu(mpic1, 8, OpenPIC_PAddr + 0x10600); - mpic_assign_isu(mpic1, 9, OpenPIC_PAddr + 0x10680); - mpic_assign_isu(mpic1, 10, OpenPIC_PAddr + 0x10700); - mpic_assign_isu(mpic1, 11, OpenPIC_PAddr + 0x10780); - - /* External ints */ - mpic_assign_isu(mpic1, 12, OpenPIC_PAddr + 0x10000); - mpic_assign_isu(mpic1, 13, OpenPIC_PAddr + 0x10080); - mpic_assign_isu(mpic1, 14, OpenPIC_PAddr + 0x10100); - mpic_init(mpic1); + struct mpic *mpic; + struct resource r; + struct device_node *np = NULL; + + np = of_find_node_by_type(np, "open-pic"); + + if (np == NULL) { + printk(KERN_ERR "Could not find open-pic node\n"); + return; + } + + if(of_address_to_resource(np, 0, &r)) { + printk(KERN_ERR "Could not map mpic register space\n"); + of_node_put(np); + return; + } + + mpic = mpic_alloc(np, r.start, + MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, + 4, 0, " OpenPIC "); + BUG_ON(mpic == NULL); + of_node_put(np); + + mpic_assign_isu(mpic, 0, r.start + 0x10200); + mpic_assign_isu(mpic, 1, r.start + 0x10280); + mpic_assign_isu(mpic, 2, r.start + 0x10300); + mpic_assign_isu(mpic, 3, r.start + 0x10380); + mpic_assign_isu(mpic, 4, r.start + 0x10400); + mpic_assign_isu(mpic, 5, r.start + 0x10480); + mpic_assign_isu(mpic, 6, r.start + 0x10500); + mpic_assign_isu(mpic, 7, r.start + 0x10580); + + /* Unused on this platform (leave room for 8548) */ + mpic_assign_isu(mpic, 8, r.start + 0x10600); + mpic_assign_isu(mpic, 9, r.start + 0x10680); + mpic_assign_isu(mpic, 10, r.start + 0x10700); + mpic_assign_isu(mpic, 11, r.start + 0x10780); + + /* External Interrupts */ + mpic_assign_isu(mpic, 12, r.start + 0x10000); + mpic_assign_isu(mpic, 13, r.start + 0x10080); + mpic_assign_isu(mpic, 14, r.start + 0x10100); + + mpic_init(mpic); } /* @@ -166,16 +112,18 @@ void __init mpc85xx_ads_pic_init(void) static void __init mpc85xx_ads_setup_arch(void) { struct device_node *cpu; +#ifdef CONFIG_PCI struct device_node *np; +#endif if (ppc_md.progress) ppc_md.progress("mpc85xx_ads_setup_arch()", 0); cpu = of_find_node_by_type(NULL, "cpu"); if (cpu != 0) { - unsigned int *fp; + const unsigned int *fp; - fp = (int *)get_property(cpu, "clock-frequency", NULL); + fp = get_property(cpu, "clock-frequency", NULL); if (fp != 0) loops_per_jiffy = *fp / HZ; else @@ -187,8 +135,7 @@ static void __init mpc85xx_ads_setup_arch(void) for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) add_bridge(np); - ppc_md.pci_swizzle = common_swizzle; - ppc_md.pci_map_irq = mpc85xx_map_irq; + ppc_md.pcibios_fixup = mpc85xx_pcibios_fixup; ppc_md.pci_exclude_device = mpc85xx_exclude_device; #endif diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c index 18e6e11f7020..4c1fede6470e 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c @@ -57,94 +57,8 @@ unsigned long isa_mem_base = 0; static int cds_pci_slot = 2; static volatile u8 *cadmus; -/* - * Internal interrupts are all Level Sensitive, and Positive Polarity - * - * Note: Likely, this table and the following function should be - * obtained and derived from the OF Device Tree. - */ -static u_char mpc85xx_cds_openpic_initsenses[] __initdata = { - MPC85XX_INTERNAL_IRQ_SENSES, -#if defined(CONFIG_PCI) - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Ext 0: PCI slot 0 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 1: PCI slot 1 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 2: PCI slot 2 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 3: PCI slot 3 */ -#else - 0x0, /* External 0: */ - 0x0, /* External 1: */ - 0x0, /* External 2: */ - 0x0, /* External 3: */ -#endif - (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 5: PHY */ - 0x0, /* External 6: */ - 0x0, /* External 7: */ - 0x0, /* External 8: */ - 0x0, /* External 9: */ - 0x0, /* External 10: */ -#ifdef CONFIG_PCI - (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 11: PCI2 slot 0 */ -#else - 0x0, /* External 11: */ -#endif -}; - #ifdef CONFIG_PCI -/* - * interrupt routing - */ -int -mpc85xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) -{ - struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); - - if (!hose->index) - { - /* Handle PCI1 interrupts */ - char pci_irq_table[][4] = - /* - * PCI IDSEL/INTPIN->INTLINE - * A B C D - */ - - /* Note IRQ assignment for slots is based on which slot the elysium is - * in -- in this setup elysium is in slot #2 (this PIRQA as first - * interrupt on slot */ - { - { 0, 1, 2, 3 }, /* 16 - PMC */ - { 0, 1, 2, 3 }, /* 17 P2P (Tsi320) */ - { 0, 1, 2, 3 }, /* 18 - Slot 1 */ - { 1, 2, 3, 0 }, /* 19 - Slot 2 */ - { 2, 3, 0, 1 }, /* 20 - Slot 3 */ - { 3, 0, 1, 2 }, /* 21 - Slot 4 */ - }; - - const long min_idsel = 16, max_idsel = 21, irqs_per_slot = 4; - int i, j; - - for (i = 0; i < 6; i++) - for (j = 0; j < 4; j++) - pci_irq_table[i][j] = - ((pci_irq_table[i][j] + 5 - - cds_pci_slot) & 0x3) + PIRQ0A; - - return PCI_IRQ_TABLE_LOOKUP; - } else { - /* Handle PCI2 interrupts (if we have one) */ - char pci_irq_table[][4] = - { - /* - * We only have one slot and one interrupt - * going to PIRQA - PIRQD */ - { PIRQ1A, PIRQ1A, PIRQ1A, PIRQ1A }, /* 21 - slot 0 */ - }; - - const long min_idsel = 21, max_idsel = 21, irqs_per_slot = 4; - - return PCI_IRQ_TABLE_LOOKUP; - } -} #define ARCADIA_HOST_BRIDGE_IDSEL 17 #define ARCADIA_2ND_BRIDGE_IDSEL 3 @@ -210,50 +124,104 @@ mpc85xx_cds_pcibios_fixup(void) pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 11); pci_dev_put(dev); } + + /* Now map all the PCI irqs */ + dev = NULL; + for_each_pci_dev(dev) + pci_read_irq_line(dev); +} + +#ifdef CONFIG_PPC_I8259 +#warning The i8259 PIC support is currently broken +static void mpc85xx_8259_cascade(unsigned int irq, struct + irq_desc *desc, struct pt_regs *regs) +{ + unsigned int cascade_irq = i8259_irq(regs); + + if (cascade_irq != NO_IRQ) + generic_handle_irq(cascade_irq, regs); + + desc->chip->eoi(irq); } +#endif /* PPC_I8259 */ #endif /* CONFIG_PCI */ void __init mpc85xx_cds_pic_init(void) { - struct mpic *mpic1; - phys_addr_t OpenPIC_PAddr; + struct mpic *mpic; + struct resource r; + struct device_node *np = NULL; + struct device_node *cascade_node = NULL; + int cascade_irq; - /* Determine the Physical Address of the OpenPIC regs */ - OpenPIC_PAddr = get_immrbase() + MPC85xx_OPENPIC_OFFSET; + np = of_find_node_by_type(np, "open-pic"); + + if (np == NULL) { + printk(KERN_ERR "Could not find open-pic node\n"); + return; + } - mpic1 = mpic_alloc(OpenPIC_PAddr, + if (of_address_to_resource(np, 0, &r)) { + printk(KERN_ERR "Failed to map mpic register space\n"); + of_node_put(np); + return; + } + + mpic = mpic_alloc(np, r.start, MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, - 4, MPC85xx_OPENPIC_IRQ_OFFSET, 0, 250, - mpc85xx_cds_openpic_initsenses, - sizeof(mpc85xx_cds_openpic_initsenses), " OpenPIC "); - BUG_ON(mpic1 == NULL); - mpic_assign_isu(mpic1, 0, OpenPIC_PAddr + 0x10200); - mpic_assign_isu(mpic1, 1, OpenPIC_PAddr + 0x10280); - mpic_assign_isu(mpic1, 2, OpenPIC_PAddr + 0x10300); - mpic_assign_isu(mpic1, 3, OpenPIC_PAddr + 0x10380); - mpic_assign_isu(mpic1, 4, OpenPIC_PAddr + 0x10400); - mpic_assign_isu(mpic1, 5, OpenPIC_PAddr + 0x10480); - mpic_assign_isu(mpic1, 6, OpenPIC_PAddr + 0x10500); - mpic_assign_isu(mpic1, 7, OpenPIC_PAddr + 0x10580); - - /* dummy mappings to get to 48 */ - mpic_assign_isu(mpic1, 8, OpenPIC_PAddr + 0x10600); - mpic_assign_isu(mpic1, 9, OpenPIC_PAddr + 0x10680); - mpic_assign_isu(mpic1, 10, OpenPIC_PAddr + 0x10700); - mpic_assign_isu(mpic1, 11, OpenPIC_PAddr + 0x10780); - - /* External ints */ - mpic_assign_isu(mpic1, 12, OpenPIC_PAddr + 0x10000); - mpic_assign_isu(mpic1, 13, OpenPIC_PAddr + 0x10080); - mpic_assign_isu(mpic1, 14, OpenPIC_PAddr + 0x10100); - - mpic_init(mpic1); + 4, 0, " OpenPIC "); + BUG_ON(mpic == NULL); + + /* Return the mpic node */ + of_node_put(np); + + mpic_assign_isu(mpic, 0, r.start + 0x10200); + mpic_assign_isu(mpic, 1, r.start + 0x10280); + mpic_assign_isu(mpic, 2, r.start + 0x10300); + mpic_assign_isu(mpic, 3, r.start + 0x10380); + mpic_assign_isu(mpic, 4, r.start + 0x10400); + mpic_assign_isu(mpic, 5, r.start + 0x10480); + mpic_assign_isu(mpic, 6, r.start + 0x10500); + mpic_assign_isu(mpic, 7, r.start + 0x10580); + + /* Used only for 8548 so far, but no harm in + * allocating them for everyone */ + mpic_assign_isu(mpic, 8, r.start + 0x10600); + mpic_assign_isu(mpic, 9, r.start + 0x10680); + mpic_assign_isu(mpic, 10, r.start + 0x10700); + mpic_assign_isu(mpic, 11, r.start + 0x10780); + + /* External Interrupts */ + mpic_assign_isu(mpic, 12, r.start + 0x10000); + mpic_assign_isu(mpic, 13, r.start + 0x10080); + mpic_assign_isu(mpic, 14, r.start + 0x10100); + + mpic_init(mpic); + +#ifdef CONFIG_PPC_I8259 + /* Initialize the i8259 controller */ + for_each_node_by_type(np, "interrupt-controller") + if (device_is_compatible(np, "chrp,iic")) { + cascade_node = np; + break; + } + + if (cascade_node == NULL) { + printk(KERN_DEBUG "Could not find i8259 PIC\n"); + return; + } -#ifdef CONFIG_PCI - mpic_setup_cascade(PIRQ0A, i8259_irq_cascade, NULL); + cascade_irq = irq_of_parse_and_map(cascade_node, 0); + if (cascade_irq == NO_IRQ) { + printk(KERN_ERR "Failed to map cascade interrupt\n"); + return; + } - i8259_init(0,0); -#endif + i8259_init(cascade_node, 0); + of_node_put(cascade_node); + + set_irq_chained_handler(cascade_irq, mpc85xx_8259_cascade); +#endif /* CONFIG_PPC_I8259 */ } @@ -273,9 +241,9 @@ mpc85xx_cds_setup_arch(void) cpu = of_find_node_by_type(NULL, "cpu"); if (cpu != 0) { - unsigned int *fp; + const unsigned int *fp; - fp = (int *)get_property(cpu, "clock-frequency", NULL); + fp = get_property(cpu, "clock-frequency", NULL); if (fp != 0) loops_per_jiffy = *fp / HZ; else @@ -298,8 +266,6 @@ mpc85xx_cds_setup_arch(void) add_bridge(np); ppc_md.pcibios_fixup = mpc85xx_cds_pcibios_fixup; - ppc_md.pci_swizzle = common_swizzle; - ppc_md.pci_map_irq = mpc85xx_map_irq; ppc_md.pci_exclude_device = mpc85xx_exclude_device; #endif diff --git a/arch/powerpc/platforms/85xx/pci.c b/arch/powerpc/platforms/85xx/pci.c index bad290110ed1..05930eeb6e7f 100644 --- a/arch/powerpc/platforms/85xx/pci.c +++ b/arch/powerpc/platforms/85xx/pci.c @@ -9,7 +9,6 @@ * option) any later version. */ -#include <linux/config.h> #include <linux/stddef.h> #include <linux/kernel.h> #include <linux/init.h> @@ -42,7 +41,7 @@ int __init add_bridge(struct device_node *dev) int len; struct pci_controller *hose; struct resource rsrc; - int *bus_range; + const int *bus_range; int primary = 1, has_address = 0; phys_addr_t immr = get_immrbase(); @@ -52,7 +51,7 @@ int __init add_bridge(struct device_node *dev) has_address = (of_address_to_resource(dev, 0, &rsrc) == 0); /* Get bus range if any */ - bus_range = (int *) get_property(dev, "bus-range", &len); + bus_range = get_property(dev, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) { printk(KERN_WARNING "Can't get bus-range for %s, assume" " bus 0\n", dev->full_name); @@ -79,9 +78,10 @@ int __init add_bridge(struct device_node *dev) mpc85xx_pci2_busno = hose->first_busno; } - printk(KERN_INFO "Found MPC85xx PCI host bridge at 0x%08lx. " + printk(KERN_INFO "Found MPC85xx PCI host bridge at 0x%016llx. " "Firmware bus number: %d->%d\n", - rsrc.start, hose->first_busno, hose->last_busno); + (unsigned long long)rsrc.start, hose->first_busno, + hose->last_busno); DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n", hose, hose->cfg_addr, hose->cfg_data); diff --git a/arch/powerpc/platforms/86xx/Kconfig b/arch/powerpc/platforms/86xx/Kconfig index 3a87863d2876..d1ecc0f9ab58 100644 --- a/arch/powerpc/platforms/86xx/Kconfig +++ b/arch/powerpc/platforms/86xx/Kconfig @@ -7,6 +7,7 @@ choice config MPC8641_HPCN bool "Freescale MPC8641 HPCN" + select PPC_I8259 help This option enables support for the MPC8641 HPCN board. @@ -28,9 +29,4 @@ config PPC_INDIRECT_PCI_BE depends on PPC_86xx default y -config PPC_STD_MMU - bool - depends on PPC_86xx - default y - endmenu diff --git a/arch/powerpc/platforms/86xx/Makefile b/arch/powerpc/platforms/86xx/Makefile index 7be796c5d5c9..476a6eeee710 100644 --- a/arch/powerpc/platforms/86xx/Makefile +++ b/arch/powerpc/platforms/86xx/Makefile @@ -2,9 +2,6 @@ # Makefile for the PowerPC 86xx linux kernel. # - -ifeq ($(CONFIG_PPC_86xx),y) obj-$(CONFIG_SMP) += mpc86xx_smp.o -endif obj-$(CONFIG_MPC8641_HPCN) += mpc86xx_hpcn.o obj-$(CONFIG_PCI) += pci.o mpc86xx_pcie.o diff --git a/arch/powerpc/platforms/86xx/mpc8641_hpcn.h b/arch/powerpc/platforms/86xx/mpc8641_hpcn.h index 5042253758b7..41e554c4af94 100644 --- a/arch/powerpc/platforms/86xx/mpc8641_hpcn.h +++ b/arch/powerpc/platforms/86xx/mpc8641_hpcn.h @@ -14,41 +14,8 @@ #ifndef __MPC8641_HPCN_H__ #define __MPC8641_HPCN_H__ -#include <linux/config.h> #include <linux/init.h> -/* PCI interrupt controller */ -#define PIRQA 3 -#define PIRQB 4 -#define PIRQC 5 -#define PIRQD 6 -#define PIRQ7 7 -#define PIRQE 9 -#define PIRQF 10 -#define PIRQG 11 -#define PIRQH 12 - -/* PCI-Express memory map */ -#define MPC86XX_PCIE_LOWER_IO 0x00000000 -#define MPC86XX_PCIE_UPPER_IO 0x00ffffff - -#define MPC86XX_PCIE_LOWER_MEM 0x80000000 -#define MPC86XX_PCIE_UPPER_MEM 0x9fffffff - -#define MPC86XX_PCIE_IO_BASE 0xe2000000 -#define MPC86XX_PCIE_MEM_OFFSET 0x00000000 - -#define MPC86XX_PCIE_IO_SIZE 0x01000000 - -#define PCIE1_CFG_ADDR_OFFSET (0x8000) -#define PCIE1_CFG_DATA_OFFSET (0x8004) - -#define PCIE2_CFG_ADDR_OFFSET (0x9000) -#define PCIE2_CFG_DATA_OFFSET (0x9004) - -#define MPC86xx_PCIE_OFFSET PCIE1_CFG_ADDR_OFFSET -#define MPC86xx_PCIE_SIZE (0x1000) - #define MPC86XX_RSTCR_OFFSET (0xe00b0) /* Reset Control Register */ #endif /* __MPC8641_HPCN_H__ */ diff --git a/arch/powerpc/platforms/86xx/mpc86xx.h b/arch/powerpc/platforms/86xx/mpc86xx.h index e3c9e4f417d3..2834462590b8 100644 --- a/arch/powerpc/platforms/86xx/mpc86xx.h +++ b/arch/powerpc/platforms/86xx/mpc86xx.h @@ -15,11 +15,13 @@ * mpc86xx_* files. Mostly for use by mpc86xx_setup(). */ -extern int __init add_bridge(struct device_node *dev); +extern int add_bridge(struct device_node *dev); -extern void __init setup_indirect_pcie(struct pci_controller *hose, +extern int mpc86xx_exclude_device(u_char bus, u_char devfn); + +extern void setup_indirect_pcie(struct pci_controller *hose, u32 cfg_addr, u32 cfg_data); -extern void __init setup_indirect_pcie_nomap(struct pci_controller *hose, +extern void setup_indirect_pcie_nomap(struct pci_controller *hose, void __iomem *cfg_addr, void __iomem *cfg_data); diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c index 483c21df181e..b637e8157f7b 100644 --- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c +++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c @@ -12,7 +12,6 @@ * option) any later version. */ -#include <linux/config.h> #include <linux/stddef.h> #include <linux/kernel.h> #include <linux/pci.h> @@ -36,6 +35,15 @@ #include <sysdev/fsl_soc.h> #include "mpc86xx.h" +#include "mpc8641_hpcn.h" + +#undef DEBUG + +#ifdef DEBUG +#define DBG(fmt...) do { printk(KERN_ERR fmt); } while(0) +#else +#define DBG(fmt...) do { } while(0) +#endif #ifndef CONFIG_PCI unsigned long isa_io_base = 0; @@ -44,159 +52,288 @@ unsigned long pci_dram_offset = 0; #endif -/* - * Internal interrupts are all Level Sensitive, and Positive Polarity - */ - -static u_char mpc86xx_hpcn_openpic_initsenses[] __initdata = { - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 0: Reserved */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 1: MCM */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 2: DDR DRAM */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 3: LBIU */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 4: DMA 0 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 5: DMA 1 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 6: DMA 2 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 7: DMA 3 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 8: PCIE1 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 9: PCIE2 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 10: Reserved */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 11: Reserved */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 12: DUART2 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 13: TSEC 1 Transmit */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 14: TSEC 1 Receive */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 15: TSEC 3 transmit */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 16: TSEC 3 receive */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 17: TSEC 3 error */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 18: TSEC 1 Receive/Transmit Error */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 19: TSEC 2 Transmit */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 20: TSEC 2 Receive */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 21: TSEC 4 transmit */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 22: TSEC 4 receive */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 23: TSEC 4 error */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 24: TSEC 2 Receive/Transmit Error */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 25: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 26: DUART1 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 27: I2C */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 28: Performance Monitor */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 29: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 30: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 31: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 32: SRIO error/write-port unit */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 33: SRIO outbound doorbell */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 34: SRIO inbound doorbell */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 35: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 36: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 37: SRIO outbound message unit 1 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 38: SRIO inbound message unit 1 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 39: SRIO outbound message unit 2 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 40: SRIO inbound message unit 2 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 41: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 42: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 43: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 44: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 45: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 46: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 47: Unused */ - 0x0, /* External 0: */ - 0x0, /* External 1: */ - 0x0, /* External 2: */ - 0x0, /* External 3: */ - 0x0, /* External 4: */ - 0x0, /* External 5: */ - 0x0, /* External 6: */ - 0x0, /* External 7: */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 8: Pixis FPGA */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* External 9: ULI 8259 INTR Cascade */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 10: Quad ETH PHY */ - 0x0, /* External 11: */ - 0x0, - 0x0, - 0x0, - 0x0, -}; - +#ifdef CONFIG_PCI +static void mpc86xx_8259_cascade(unsigned int irq, struct irq_desc *desc, + struct pt_regs *regs) +{ + unsigned int cascade_irq = i8259_irq(regs); + if (cascade_irq != NO_IRQ) + generic_handle_irq(cascade_irq, regs); + desc->chip->eoi(irq); +} +#endif /* CONFIG_PCI */ void __init mpc86xx_hpcn_init_irq(void) { struct mpic *mpic1; - phys_addr_t openpic_paddr; + struct device_node *np; + struct resource res; +#ifdef CONFIG_PCI + struct device_node *cascade_node = NULL; + int cascade_irq; +#endif - /* Determine the Physical Address of the OpenPIC regs */ - openpic_paddr = get_immrbase() + MPC86xx_OPENPIC_OFFSET; + /* Determine PIC address. */ + np = of_find_node_by_type(NULL, "open-pic"); + if (np == NULL) + return; + of_address_to_resource(np, 0, &res); /* Alloc mpic structure and per isu has 16 INT entries. */ - mpic1 = mpic_alloc(openpic_paddr, + mpic1 = mpic_alloc(np, res.start, MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, - 16, MPC86xx_OPENPIC_IRQ_OFFSET, 0, 250, - mpc86xx_hpcn_openpic_initsenses, - sizeof(mpc86xx_hpcn_openpic_initsenses), + 16, NR_IRQS - 4, " MPIC "); BUG_ON(mpic1 == NULL); + mpic_assign_isu(mpic1, 0, res.start + 0x10000); + /* 48 Internal Interrupts */ - mpic_assign_isu(mpic1, 0, openpic_paddr + 0x10200); - mpic_assign_isu(mpic1, 1, openpic_paddr + 0x10400); - mpic_assign_isu(mpic1, 2, openpic_paddr + 0x10600); + mpic_assign_isu(mpic1, 1, res.start + 0x10200); + mpic_assign_isu(mpic1, 2, res.start + 0x10400); + mpic_assign_isu(mpic1, 3, res.start + 0x10600); - /* 16 External interrupts */ - mpic_assign_isu(mpic1, 3, openpic_paddr + 0x10000); + /* 16 External interrupts + * Moving them from [0 - 15] to [64 - 79] + */ + mpic_assign_isu(mpic1, 4, res.start + 0x10000); mpic_init(mpic1); #ifdef CONFIG_PCI - mpic_setup_cascade(MPC86xx_IRQ_EXT9, i8259_irq_cascade, NULL); - i8259_init(0, I8259_OFFSET); + /* Initialize i8259 controller */ + for_each_node_by_type(np, "interrupt-controller") + if (device_is_compatible(np, "chrp,iic")) { + cascade_node = np; + break; + } + if (cascade_node == NULL) { + printk(KERN_DEBUG "mpc86xxhpcn: no ISA interrupt controller\n"); + return; + } + + cascade_irq = irq_of_parse_and_map(cascade_node, 0); + if (cascade_irq == NO_IRQ) { + printk(KERN_ERR "mpc86xxhpcn: failed to map cascade interrupt"); + return; + } + DBG("mpc86xxhpcn: cascade mapped to irq %d\n", cascade_irq); + + i8259_init(cascade_node, 0); + set_irq_chained_handler(cascade_irq, mpc86xx_8259_cascade); #endif } +#ifdef CONFIG_PCI +enum pirq{PIRQA = 8, PIRQB, PIRQC, PIRQD, PIRQE, PIRQF, PIRQG, PIRQH}; +const unsigned char uli1575_irq_route_table[16] = { + 0, /* 0: Reserved */ + 0x8, /* 1: 0b1000 */ + 0, /* 2: Reserved */ + 0x2, /* 3: 0b0010 */ + 0x4, /* 4: 0b0100 */ + 0x5, /* 5: 0b0101 */ + 0x7, /* 6: 0b0111 */ + 0x6, /* 7: 0b0110 */ + 0, /* 8: Reserved */ + 0x1, /* 9: 0b0001 */ + 0x3, /* 10: 0b0011 */ + 0x9, /* 11: 0b1001 */ + 0xb, /* 12: 0b1011 */ + 0, /* 13: Reserved */ + 0xd, /* 14, 0b1101 */ + 0xf, /* 15, 0b1111 */ +}; -#ifdef CONFIG_PCI -/* - * interrupt routing - */ +static int __devinit +get_pci_irq_from_of(struct pci_controller *hose, int slot, int pin) +{ + struct of_irq oirq; + u32 laddr[3]; + struct device_node *hosenode = hose ? hose->arch_data : NULL; + + if (!hosenode) return -EINVAL; + + laddr[0] = (hose->first_busno << 16) | (PCI_DEVFN(slot, 0) << 8); + laddr[1] = laddr[2] = 0; + of_irq_map_raw(hosenode, &pin, 1, laddr, &oirq); + DBG("mpc86xx_hpcn: pci irq addr %x, slot %d, pin %d, irq %d\n", + laddr[0], slot, pin, oirq.specifier[0]); + return oirq.specifier[0]; +} -int -mpc86xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +static void __devinit quirk_uli1575(struct pci_dev *dev) { - static char pci_irq_table[][4] = { - /* - * PCI IDSEL/INTPIN->INTLINE - * A B C D - */ - {PIRQA, PIRQB, PIRQC, PIRQD}, /* IDSEL 17 -- PCI Slot 1 */ - {PIRQB, PIRQC, PIRQD, PIRQA}, /* IDSEL 18 -- PCI Slot 2 */ - {0, 0, 0, 0}, /* IDSEL 19 */ - {0, 0, 0, 0}, /* IDSEL 20 */ - {0, 0, 0, 0}, /* IDSEL 21 */ - {0, 0, 0, 0}, /* IDSEL 22 */ - {0, 0, 0, 0}, /* IDSEL 23 */ - {0, 0, 0, 0}, /* IDSEL 24 */ - {0, 0, 0, 0}, /* IDSEL 25 */ - {PIRQD, PIRQA, PIRQB, PIRQC}, /* IDSEL 26 -- PCI Bridge*/ - {PIRQC, 0, 0, 0}, /* IDSEL 27 -- LAN */ - {PIRQE, PIRQF, PIRQH, PIRQ7}, /* IDSEL 28 -- USB 1.1 */ - {PIRQE, PIRQF, PIRQG, 0}, /* IDSEL 29 -- Audio & Modem */ - {PIRQH, 0, 0, 0}, /* IDSEL 30 -- LPC & PMU*/ - {PIRQD, 0, 0, 0}, /* IDSEL 31 -- ATA */ - }; - - const long min_idsel = 17, max_idsel = 31, irqs_per_slot = 4; - return PCI_IRQ_TABLE_LOOKUP + I8259_OFFSET; + unsigned short temp; + struct pci_controller *hose = pci_bus_to_host(dev->bus); + unsigned char irq2pin[16]; + unsigned long pirq_map_word = 0; + u32 irq; + int i; + + /* + * ULI1575 interrupts route setup + */ + memset(irq2pin, 0, 16); /* Initialize default value 0 */ + + /* + * PIRQA -> PIRQD mapping read from OF-tree + * + * interrupts for PCI slot0 -- PIRQA / PIRQB / PIRQC / PIRQD + * PCI slot1 -- PIRQB / PIRQC / PIRQD / PIRQA + */ + for (i = 0; i < 4; i++){ + irq = get_pci_irq_from_of(hose, 17, i + 1); + if (irq > 0 && irq < 16) + irq2pin[irq] = PIRQA + i; + else + printk(KERN_WARNING "ULI1575 device" + "(slot %d, pin %d) irq %d is invalid.\n", + 17, i, irq); + } + + /* + * PIRQE -> PIRQF mapping set manually + * + * IRQ pin IRQ# + * PIRQE ---- 9 + * PIRQF ---- 10 + * PIRQG ---- 11 + * PIRQH ---- 12 + */ + for (i = 0; i < 4; i++) irq2pin[i + 9] = PIRQE + i; + + /* Set IRQ-PIRQ Mapping to ULI1575 */ + for (i = 0; i < 16; i++) + if (irq2pin[i]) + pirq_map_word |= (uli1575_irq_route_table[i] & 0xf) + << ((irq2pin[i] - PIRQA) * 4); + + /* ULI1575 IRQ mapping conf register default value is 0xb9317542 */ + DBG("Setup ULI1575 IRQ mapping configuration register value = 0x%x\n", + pirq_map_word); + pci_write_config_dword(dev, 0x48, pirq_map_word); + +#define ULI1575_SET_DEV_IRQ(slot, pin, reg) \ + do { \ + int irq; \ + irq = get_pci_irq_from_of(hose, slot, pin); \ + if (irq > 0 && irq < 16) \ + pci_write_config_byte(dev, reg, irq2pin[irq]); \ + else \ + printk(KERN_WARNING "ULI1575 device" \ + "(slot %d, pin %d) irq %d is invalid.\n", \ + slot, pin, irq); \ + } while(0) + + /* USB 1.1 OHCI controller 1, slot 28, pin 1 */ + ULI1575_SET_DEV_IRQ(28, 1, 0x86); + + /* USB 1.1 OHCI controller 2, slot 28, pin 2 */ + ULI1575_SET_DEV_IRQ(28, 2, 0x87); + + /* USB 1.1 OHCI controller 3, slot 28, pin 3 */ + ULI1575_SET_DEV_IRQ(28, 3, 0x88); + + /* USB 2.0 controller, slot 28, pin 4 */ + irq = get_pci_irq_from_of(hose, 28, 4); + if (irq >= 0 && irq <=15) + pci_write_config_dword(dev, 0x74, uli1575_irq_route_table[irq]); + + /* Audio controller, slot 29, pin 1 */ + ULI1575_SET_DEV_IRQ(29, 1, 0x8a); + + /* Modem controller, slot 29, pin 2 */ + ULI1575_SET_DEV_IRQ(29, 2, 0x8b); + + /* HD audio controller, slot 29, pin 3 */ + ULI1575_SET_DEV_IRQ(29, 3, 0x8c); + + /* SMB interrupt: slot 30, pin 1 */ + ULI1575_SET_DEV_IRQ(30, 1, 0x8e); + + /* PMU ACPI SCI interrupt: slot 30, pin 2 */ + ULI1575_SET_DEV_IRQ(30, 2, 0x8f); + + /* Serial ATA interrupt: slot 31, pin 1 */ + ULI1575_SET_DEV_IRQ(31, 1, 0x8d); + + /* Primary PATA IDE IRQ: 14 + * Secondary PATA IDE IRQ: 15 + */ + pci_write_config_byte(dev, 0x44, 0x30 | uli1575_irq_route_table[14]); + pci_write_config_byte(dev, 0x75, uli1575_irq_route_table[15]); + + /* Set IRQ14 and IRQ15 to legacy IRQs */ + pci_read_config_word(dev, 0x46, &temp); + temp |= 0xc000; + pci_write_config_word(dev, 0x46, temp); + + /* Set i8259 interrupt trigger + * IRQ 3: Level + * IRQ 4: Level + * IRQ 5: Level + * IRQ 6: Level + * IRQ 7: Level + * IRQ 9: Level + * IRQ 10: Level + * IRQ 11: Level + * IRQ 12: Level + * IRQ 14: Edge + * IRQ 15: Edge + */ + outb(0xfa, 0x4d0); + outb(0x1e, 0x4d1); + +#undef ULI1575_SET_DEV_IRQ } +static void __devinit quirk_uli5288(struct pci_dev *dev) +{ + unsigned char c; + + pci_read_config_byte(dev,0x83,&c); + c |= 0x80; + pci_write_config_byte(dev, 0x83, c); + + pci_write_config_byte(dev, 0x09, 0x01); + pci_write_config_byte(dev, 0x0a, 0x06); + + pci_read_config_byte(dev,0x83,&c); + c &= 0x7f; + pci_write_config_byte(dev, 0x83, c); -int -mpc86xx_exclude_device(u_char bus, u_char devfn) + pci_read_config_byte(dev,0x84,&c); + c |= 0x01; + pci_write_config_byte(dev, 0x84, c); +} + +static void __devinit quirk_uli5229(struct pci_dev *dev) { -#if !defined(CONFIG_PCI) - if (bus == 0 && PCI_SLOT(devfn) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; -#endif + unsigned short temp; + pci_write_config_word(dev, 0x04, 0x0405); + pci_read_config_word(dev, 0x4a, &temp); + temp |= 0x1000; + pci_write_config_word(dev, 0x4a, temp); +} - return PCIBIOS_SUCCESSFUL; +static void __devinit early_uli5249(struct pci_dev *dev) +{ + unsigned char temp; + pci_write_config_word(dev, 0x04, 0x0007); + pci_read_config_byte(dev, 0x7c, &temp); + pci_write_config_byte(dev, 0x7c, 0x80); + pci_write_config_byte(dev, 0x09, 0x01); + pci_write_config_byte(dev, 0x7c, temp); + dev->class |= 0x1; } + +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1575, quirk_uli1575); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5288, quirk_uli5288); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5229, quirk_uli5229); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AL, 0x5249, early_uli5249); #endif /* CONFIG_PCI */ @@ -210,9 +347,9 @@ mpc86xx_hpcn_setup_arch(void) np = of_find_node_by_type(NULL, "cpu"); if (np != 0) { - unsigned int *fp; + const unsigned int *fp; - fp = (int *)get_property(np, "clock-frequency", NULL); + fp = get_property(np, "clock-frequency", NULL); if (fp != 0) loops_per_jiffy = *fp / HZ; else @@ -224,8 +361,6 @@ mpc86xx_hpcn_setup_arch(void) for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) add_bridge(np); - ppc_md.pci_swizzle = common_swizzle; - ppc_md.pci_map_irq = mpc86xx_map_irq; ppc_md.pci_exclude_device = mpc86xx_exclude_device; #endif @@ -264,6 +399,15 @@ mpc86xx_hpcn_show_cpuinfo(struct seq_file *m) } +void __init mpc86xx_hpcn_pcibios_fixup(void) +{ + struct pci_dev *dev = NULL; + + for_each_pci_dev(dev) + pci_read_irq_line(dev); +} + + /* * Called very early, device-tree isn't unflattened */ @@ -318,6 +462,7 @@ define_machine(mpc86xx_hpcn) { .setup_arch = mpc86xx_hpcn_setup_arch, .init_IRQ = mpc86xx_hpcn_init_irq, .show_cpuinfo = mpc86xx_hpcn_show_cpuinfo, + .pcibios_fixup = mpc86xx_hpcn_pcibios_fixup, .get_irq = mpic_get_irq, .restart = mpc86xx_restart, .time_init = mpc86xx_time_init, diff --git a/arch/powerpc/platforms/86xx/mpc86xx_smp.c b/arch/powerpc/platforms/86xx/mpc86xx_smp.c index 944ec4b71416..bb7fb41933ad 100644 --- a/arch/powerpc/platforms/86xx/mpc86xx_smp.c +++ b/arch/powerpc/platforms/86xx/mpc86xx_smp.c @@ -10,7 +10,6 @@ * option) any later version. */ -#include <linux/config.h> #include <linux/stddef.h> #include <linux/kernel.h> #include <linux/init.h> @@ -34,8 +33,8 @@ extern unsigned long __secondary_hold_acknowledge; static void __init smp_86xx_release_core(int nr) { - void *mcm_vaddr; - unsigned long vaddr, pcr; + __be32 __iomem *mcm_vaddr; + unsigned long pcr; if (nr < 0 || nr >= NR_CPUS) return; @@ -45,10 +44,9 @@ smp_86xx_release_core(int nr) */ mcm_vaddr = ioremap(get_immrbase() + MPC86xx_MCM_OFFSET, MPC86xx_MCM_SIZE); - vaddr = (unsigned long)mcm_vaddr + MCM_PORT_CONFIG_OFFSET; - pcr = in_be32((volatile unsigned *)vaddr); + pcr = in_be32(mcm_vaddr + (MCM_PORT_CONFIG_OFFSET >> 2)); pcr |= 1 << (nr + 24); - out_be32((volatile unsigned *)vaddr, pcr); + out_be32(mcm_vaddr + (MCM_PORT_CONFIG_OFFSET >> 2), pcr); } diff --git a/arch/powerpc/platforms/86xx/pci.c b/arch/powerpc/platforms/86xx/pci.c index 5180df7c75bc..481e18ed5be9 100644 --- a/arch/powerpc/platforms/86xx/pci.c +++ b/arch/powerpc/platforms/86xx/pci.c @@ -12,7 +12,6 @@ * option) any later version. */ -#include <linux/config.h> #include <linux/types.h> #include <linux/module.h> #include <linux/init.h> @@ -122,15 +121,12 @@ static void __init setup_pcie_atmu(struct pci_controller *hose, struct resource static void __init mpc86xx_setup_pcie(struct pci_controller *hose, u32 pcie_offset, u32 pcie_size) { - volatile struct ccsr_pex *pcie; u16 cmd; unsigned int temps; DBG("PCIE host controller register offset 0x%08x, size 0x%08x.\n", pcie_offset, pcie_size); - pcie = ioremap(pcie_offset, pcie_size); - early_read_config_word(hose, 0, 0, PCI_COMMAND, &cmd); cmd |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO; @@ -144,12 +140,20 @@ mpc86xx_setup_pcie(struct pci_controller *hose, u32 pcie_offset, u32 pcie_size) early_write_config_dword(hose, 0, 0, PCI_PRIMARY_BUS, temps); } +int mpc86xx_exclude_device(u_char bus, u_char devfn) +{ + if (bus == 0 && PCI_SLOT(devfn) == 0) + return PCIBIOS_DEVICE_NOT_FOUND; + + return PCIBIOS_SUCCESSFUL; +} + int __init add_bridge(struct device_node *dev) { int len; struct pci_controller *hose; struct resource rsrc; - int *bus_range; + const int *bus_range; int has_address = 0; int primary = 0; @@ -159,7 +163,7 @@ int __init add_bridge(struct device_node *dev) has_address = (of_address_to_resource(dev, 0, &rsrc) == 0); /* Get bus range if any */ - bus_range = (int *) get_property(dev, "bus-range", &len); + bus_range = get_property(dev, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) printk(KERN_WARNING "Can't get bus-range for %s, assume" " bus 0\n", dev->full_name); @@ -184,7 +188,8 @@ int __init add_bridge(struct device_node *dev) printk(KERN_INFO "Found MPC86xx PCIE host bridge at 0x%08lx. " "Firmware bus number: %d->%d\n", - rsrc.start, hose->first_busno, hose->last_busno); + (unsigned long) rsrc.start, + hose->first_busno, hose->last_busno); DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n", hose, hose->cfg_addr, hose->cfg_data); @@ -198,128 +203,3 @@ int __init add_bridge(struct device_node *dev) return 0; } - -static void __devinit quirk_ali1575(struct pci_dev *dev) -{ - unsigned short temp; - - /* - * ALI1575 interrupts route table setup: - * - * IRQ pin IRQ# - * PIRQA ---- 3 - * PIRQB ---- 4 - * PIRQC ---- 5 - * PIRQD ---- 6 - * PIRQE ---- 9 - * PIRQF ---- 10 - * PIRQG ---- 11 - * PIRQH ---- 12 - * - * interrupts for PCI slot0 -- PIRQA / PIRQB / PIRQC / PIRQD - * PCI slot1 -- PIRQB / PIRQC / PIRQD / PIRQA - */ - pci_write_config_dword(dev, 0x48, 0xb9317542); - - /* USB 1.1 OHCI controller 1, interrupt: PIRQE */ - pci_write_config_byte(dev, 0x86, 0x0c); - - /* USB 1.1 OHCI controller 2, interrupt: PIRQF */ - pci_write_config_byte(dev, 0x87, 0x0d); - - /* USB 1.1 OHCI controller 3, interrupt: PIRQH */ - pci_write_config_byte(dev, 0x88, 0x0f); - - /* USB 2.0 controller, interrupt: PIRQ7 */ - pci_write_config_byte(dev, 0x74, 0x06); - - /* Audio controller, interrupt: PIRQE */ - pci_write_config_byte(dev, 0x8a, 0x0c); - - /* Modem controller, interrupt: PIRQF */ - pci_write_config_byte(dev, 0x8b, 0x0d); - - /* HD audio controller, interrupt: PIRQG */ - pci_write_config_byte(dev, 0x8c, 0x0e); - - /* Serial ATA interrupt: PIRQD */ - pci_write_config_byte(dev, 0x8d, 0x0b); - - /* SMB interrupt: PIRQH */ - pci_write_config_byte(dev, 0x8e, 0x0f); - - /* PMU ACPI SCI interrupt: PIRQH */ - pci_write_config_byte(dev, 0x8f, 0x0f); - - /* Primary PATA IDE IRQ: 14 - * Secondary PATA IDE IRQ: 15 - */ - pci_write_config_byte(dev, 0x44, 0x3d); - pci_write_config_byte(dev, 0x75, 0x0f); - - /* Set IRQ14 and IRQ15 to legacy IRQs */ - pci_read_config_word(dev, 0x46, &temp); - temp |= 0xc000; - pci_write_config_word(dev, 0x46, temp); - - /* Set i8259 interrupt trigger - * IRQ 3: Level - * IRQ 4: Level - * IRQ 5: Level - * IRQ 6: Level - * IRQ 7: Level - * IRQ 9: Level - * IRQ 10: Level - * IRQ 11: Level - * IRQ 12: Level - * IRQ 14: Edge - * IRQ 15: Edge - */ - outb(0xfa, 0x4d0); - outb(0x1e, 0x4d1); -} - -static void __devinit quirk_uli5288(struct pci_dev *dev) -{ - unsigned char c; - - pci_read_config_byte(dev,0x83,&c); - c |= 0x80; - pci_write_config_byte(dev, 0x83, c); - - pci_write_config_byte(dev, 0x09, 0x01); - pci_write_config_byte(dev, 0x0a, 0x06); - - pci_read_config_byte(dev,0x83,&c); - c &= 0x7f; - pci_write_config_byte(dev, 0x83, c); - - pci_read_config_byte(dev,0x84,&c); - c |= 0x01; - pci_write_config_byte(dev, 0x84, c); -} - -static void __devinit quirk_uli5229(struct pci_dev *dev) -{ - unsigned short temp; - pci_write_config_word(dev, 0x04, 0x0405); - pci_read_config_word(dev, 0x4a, &temp); - temp |= 0x1000; - pci_write_config_word(dev, 0x4a, temp); -} - -static void __devinit early_uli5249(struct pci_dev *dev) -{ - unsigned char temp; - pci_write_config_word(dev, 0x04, 0x0007); - pci_read_config_byte(dev, 0x7c, &temp); - pci_write_config_byte(dev, 0x7c, 0x80); - pci_write_config_byte(dev, 0x09, 0x01); - pci_write_config_byte(dev, 0x7c, temp); - dev->class |= 0x1; -} - -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1575, quirk_ali1575); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5288, quirk_uli5288); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5229, quirk_uli5229); -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AL, 0x5249, early_uli5249); diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile index 292863694562..e58fa953a50b 100644 --- a/arch/powerpc/platforms/Makefile +++ b/arch/powerpc/platforms/Makefile @@ -13,4 +13,6 @@ obj-$(CONFIG_PPC_86xx) += 86xx/ obj-$(CONFIG_PPC_PSERIES) += pseries/ obj-$(CONFIG_PPC_ISERIES) += iseries/ obj-$(CONFIG_PPC_MAPLE) += maple/ +obj-$(CONFIG_PPC_PASEMI) += pasemi/ obj-$(CONFIG_PPC_CELL) += cell/ +obj-$(CONFIG_EMBEDDED6xx) += embedded6xx/ diff --git a/arch/powerpc/platforms/cell/Kconfig b/arch/powerpc/platforms/cell/Kconfig index 352bbbacde9a..0c8c7b6ab897 100644 --- a/arch/powerpc/platforms/cell/Kconfig +++ b/arch/powerpc/platforms/cell/Kconfig @@ -6,6 +6,7 @@ config SPU_FS default m depends on PPC_CELL select SPU_BASE + select MEMORY_HOTPLUG help The SPU file system is used to access Synergistic Processing Units on machines implementing the Broadband Processor @@ -18,7 +19,6 @@ config SPU_BASE config SPUFS_MMAP bool depends on SPU_FS && SPARSEMEM - select MEMORY_HOTPLUG default y config CBE_RAS diff --git a/arch/powerpc/platforms/cell/cbe_regs.c b/arch/powerpc/platforms/cell/cbe_regs.c index 2dfde61c8412..3f3859d12e00 100644 --- a/arch/powerpc/platforms/cell/cbe_regs.c +++ b/arch/powerpc/platforms/cell/cbe_regs.c @@ -89,7 +89,7 @@ void __init cbe_regs_init(void) struct device_node *cpu; /* Build local fast map of CPUs */ - for_each_cpu(i) + for_each_possible_cpu(i) cbe_thread_map[i].cpu_node = of_get_cpu_node(i, NULL); /* Find maps for each device tree CPU */ @@ -97,7 +97,7 @@ void __init cbe_regs_init(void) struct cbe_regs_map *map = &cbe_regs_maps[cbe_regs_map_count++]; /* That hack must die die die ! */ - struct address_prop { + const struct address_prop { unsigned long address; unsigned int len; } __attribute__((packed)) *prop; @@ -110,17 +110,15 @@ void __init cbe_regs_init(void) return; } map->cpu_node = cpu; - for_each_cpu(i) + for_each_possible_cpu(i) if (cbe_thread_map[i].cpu_node == cpu) cbe_thread_map[i].regs = map; - prop = (struct address_prop *)get_property(cpu, "pervasive", - NULL); + prop = get_property(cpu, "pervasive", NULL); if (prop != NULL) map->pmd_regs = ioremap(prop->address, prop->len); - prop = (struct address_prop *)get_property(cpu, "iic", - NULL); + prop = get_property(cpu, "iic", NULL); if (prop != NULL) map->iic_regs = ioremap(prop->address, prop->len); } diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c index f4e2d8805c9e..6b57a47c5d37 100644 --- a/arch/powerpc/platforms/cell/interrupt.c +++ b/arch/powerpc/platforms/cell/interrupt.c @@ -1,6 +1,9 @@ /* * Cell Internal Interrupt Controller * + * Copyright (C) 2006 Benjamin Herrenschmidt (benh@kernel.crashing.org) + * IBM, Corp. + * * (C) Copyright IBM Deutschland Entwicklung GmbH 2005 * * Author: Arnd Bergmann <arndb@de.ibm.com> @@ -20,17 +23,18 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include <linux/config.h> #include <linux/interrupt.h> #include <linux/irq.h> #include <linux/module.h> #include <linux/percpu.h> #include <linux/types.h> +#include <linux/ioport.h> #include <asm/io.h> #include <asm/pgtable.h> #include <asm/prom.h> #include <asm/ptrace.h> +#include <asm/machdep.h> #include "interrupt.h" #include "cbe_regs.h" @@ -38,231 +42,65 @@ struct iic { struct cbe_iic_thread_regs __iomem *regs; u8 target_id; + u8 eoi_stack[16]; + int eoi_ptr; + struct irq_host *host; }; static DEFINE_PER_CPU(struct iic, iic); +#define IIC_NODE_COUNT 2 +static struct irq_host *iic_hosts[IIC_NODE_COUNT]; -void iic_local_enable(void) +/* Convert between "pending" bits and hw irq number */ +static irq_hw_number_t iic_pending_to_hwnum(struct cbe_iic_pending_bits bits) { - struct iic *iic = &__get_cpu_var(iic); - u64 tmp; - - /* - * There seems to be a bug that is present in DD2.x CPUs - * and still only partially fixed in DD3.1. - * This bug causes a value written to the priority register - * not to make it there, resulting in a system hang unless we - * write it again. - * Masking with 0xf0 is done because the Cell BE does not - * implement the lower four bits of the interrupt priority, - * they always read back as zeroes, although future CPUs - * might implement different bits. - */ - do { - out_be64(&iic->regs->prio, 0xff); - tmp = in_be64(&iic->regs->prio); - } while ((tmp & 0xf0) != 0xf0); -} - -void iic_local_disable(void) -{ - out_be64(&__get_cpu_var(iic).regs->prio, 0x0); -} + unsigned char unit = bits.source & 0xf; -static unsigned int iic_startup(unsigned int irq) -{ - return 0; + if (bits.flags & CBE_IIC_IRQ_IPI) + return IIC_IRQ_IPI0 | (bits.prio >> 4); + else if (bits.class <= 3) + return (bits.class << 4) | unit; + else + return IIC_IRQ_INVALID; } -static void iic_enable(unsigned int irq) +static void iic_mask(unsigned int irq) { - iic_local_enable(); } -static void iic_disable(unsigned int irq) +static void iic_unmask(unsigned int irq) { } -static void iic_end(unsigned int irq) +static void iic_eoi(unsigned int irq) { - iic_local_enable(); + struct iic *iic = &__get_cpu_var(iic); + out_be64(&iic->regs->prio, iic->eoi_stack[--iic->eoi_ptr]); + BUG_ON(iic->eoi_ptr < 0); } -static struct hw_interrupt_type iic_pic = { +static struct irq_chip iic_chip = { .typename = " CELL-IIC ", - .startup = iic_startup, - .enable = iic_enable, - .disable = iic_disable, - .end = iic_end, + .mask = iic_mask, + .unmask = iic_unmask, + .eoi = iic_eoi, }; -static int iic_external_get_irq(struct cbe_iic_pending_bits pending) -{ - int irq; - unsigned char node, unit; - - node = pending.source >> 4; - unit = pending.source & 0xf; - irq = -1; - - /* - * This mapping is specific to the Cell Broadband - * Engine. We might need to get the numbers - * from the device tree to support future CPUs. - */ - switch (unit) { - case 0x00: - case 0x0b: - /* - * One of these units can be connected - * to an external interrupt controller. - */ - if (pending.class != 2) - break; - irq = IIC_EXT_OFFSET - + spider_get_irq(node) - + node * IIC_NODE_STRIDE; - break; - case 0x01 ... 0x04: - case 0x07 ... 0x0a: - /* - * These units are connected to the SPEs - */ - if (pending.class > 2) - break; - irq = IIC_SPE_OFFSET - + pending.class * IIC_CLASS_STRIDE - + node * IIC_NODE_STRIDE - + unit; - break; - } - if (irq == -1) - printk(KERN_WARNING "Unexpected interrupt class %02x, " - "source %02x, prio %02x, cpu %02x\n", pending.class, - pending.source, pending.prio, smp_processor_id()); - return irq; -} - /* Get an IRQ number from the pending state register of the IIC */ -int iic_get_irq(struct pt_regs *regs) +static unsigned int iic_get_irq(struct pt_regs *regs) { - struct iic *iic; - int irq; struct cbe_iic_pending_bits pending; + struct iic *iic; iic = &__get_cpu_var(iic); - *(unsigned long *) &pending = + *(unsigned long *) &pending = in_be64((unsigned long __iomem *) &iic->regs->pending_destr); - - irq = -1; - if (pending.flags & CBE_IIC_IRQ_VALID) { - if (pending.flags & CBE_IIC_IRQ_IPI) { - irq = IIC_IPI_OFFSET + (pending.prio >> 4); -/* - if (irq > 0x80) - printk(KERN_WARNING "Unexpected IPI prio %02x" - "on CPU %02x\n", pending.prio, - smp_processor_id()); -*/ - } else { - irq = iic_external_get_irq(pending); - } - } - return irq; -} - -/* hardcoded part to be compatible with older firmware */ - -static int setup_iic_hardcoded(void) -{ - struct device_node *np; - int nodeid, cpu; - unsigned long regs; - struct iic *iic; - - for_each_cpu(cpu) { - iic = &per_cpu(iic, cpu); - nodeid = cpu/2; - - for (np = of_find_node_by_type(NULL, "cpu"); - np; - np = of_find_node_by_type(np, "cpu")) { - if (nodeid == *(int *)get_property(np, "node-id", NULL)) - break; - } - - if (!np) { - printk(KERN_WARNING "IIC: CPU %d not found\n", cpu); - iic->regs = NULL; - iic->target_id = 0xff; - return -ENODEV; - } - - regs = *(long *)get_property(np, "iic", NULL); - - /* hack until we have decided on the devtree info */ - regs += 0x400; - if (cpu & 1) - regs += 0x20; - - printk(KERN_INFO "IIC for CPU %d at %lx\n", cpu, regs); - iic->regs = ioremap(regs, sizeof(struct cbe_iic_thread_regs)); - iic->target_id = (nodeid << 4) + ((cpu & 1) ? 0xf : 0xe); - } - - return 0; -} - -static int setup_iic(void) -{ - struct device_node *dn; - unsigned long *regs; - char *compatible; - unsigned *np, found = 0; - struct iic *iic = NULL; - - for (dn = NULL; (dn = of_find_node_by_name(dn, "interrupt-controller"));) { - compatible = (char *)get_property(dn, "compatible", NULL); - - if (!compatible) { - printk(KERN_WARNING "no compatible property found !\n"); - continue; - } - - if (strstr(compatible, "IBM,CBEA-Internal-Interrupt-Controller")) - regs = (unsigned long *)get_property(dn,"reg", NULL); - else - continue; - - if (!regs) - printk(KERN_WARNING "IIC: no reg property\n"); - - np = (unsigned int *)get_property(dn, "ibm,interrupt-server-ranges", NULL); - - if (!np) { - printk(KERN_WARNING "IIC: CPU association not found\n"); - iic->regs = NULL; - iic->target_id = 0xff; - return -ENODEV; - } - - iic = &per_cpu(iic, np[0]); - iic->regs = ioremap(regs[0], sizeof(struct cbe_iic_thread_regs)); - iic->target_id = ((np[0] & 2) << 3) + ((np[0] & 1) ? 0xf : 0xe); - printk("IIC for CPU %d at %lx mapped to %p\n", np[0], regs[0], iic->regs); - - iic = &per_cpu(iic, np[1]); - iic->regs = ioremap(regs[2], sizeof(struct cbe_iic_thread_regs)); - iic->target_id = ((np[1] & 2) << 3) + ((np[1] & 1) ? 0xf : 0xe); - printk("IIC for CPU %d at %lx mapped to %p\n", np[1], regs[2], iic->regs); - - found++; - } - - if (found) - return 0; - else - return -ENODEV; + iic->eoi_stack[++iic->eoi_ptr] = pending.prio; + BUG_ON(iic->eoi_ptr > 15); + if (pending.flags & CBE_IIC_IRQ_VALID) + return irq_linear_revmap(iic->host, + iic_pending_to_hwnum(pending)); + return NO_IRQ; } #ifdef CONFIG_SMP @@ -270,12 +108,12 @@ static int setup_iic(void) /* Use the highest interrupt priorities for IPI */ static inline int iic_ipi_to_irq(int ipi) { - return IIC_IPI_OFFSET + IIC_NUM_IPIS - 1 - ipi; + return IIC_IRQ_IPI0 + IIC_NUM_IPIS - 1 - ipi; } static inline int iic_irq_to_ipi(int irq) { - return IIC_NUM_IPIS - 1 - (irq - IIC_IPI_OFFSET); + return IIC_NUM_IPIS - 1 - (irq - IIC_IRQ_IPI0); } void iic_setup_cpu(void) @@ -294,22 +132,51 @@ u8 iic_get_target_id(int cpu) } EXPORT_SYMBOL_GPL(iic_get_target_id); +struct irq_host *iic_get_irq_host(int node) +{ + if (node < 0 || node >= IIC_NODE_COUNT) + return NULL; + return iic_hosts[node]; +} +EXPORT_SYMBOL_GPL(iic_get_irq_host); + + static irqreturn_t iic_ipi_action(int irq, void *dev_id, struct pt_regs *regs) { - smp_message_recv(iic_irq_to_ipi(irq), regs); + int ipi = (int)(long)dev_id; + + smp_message_recv(ipi, regs); + return IRQ_HANDLED; } static void iic_request_ipi(int ipi, const char *name) { - int irq; - - irq = iic_ipi_to_irq(ipi); - /* IPIs are marked SA_INTERRUPT as they must run with irqs - * disabled */ - get_irq_desc(irq)->handler = &iic_pic; - get_irq_desc(irq)->status |= IRQ_PER_CPU; - request_irq(irq, iic_ipi_action, SA_INTERRUPT, name, NULL); + int node, virq; + + for (node = 0; node < IIC_NODE_COUNT; node++) { + char *rname; + if (iic_hosts[node] == NULL) + continue; + virq = irq_create_mapping(iic_hosts[node], + iic_ipi_to_irq(ipi)); + if (virq == NO_IRQ) { + printk(KERN_ERR + "iic: failed to map IPI %s on node %d\n", + name, node); + continue; + } + rname = kzalloc(strlen(name) + 16, GFP_KERNEL); + if (rname) + sprintf(rname, "%s node %d", name, node); + else + rname = (char *)name; + if (request_irq(virq, iic_ipi_action, IRQF_DISABLED, + rname, (void *)(long)ipi)) + printk(KERN_ERR + "iic: failed to request IPI %s on node %d\n", + name, node); + } } void iic_request_IPIs(void) @@ -320,34 +187,118 @@ void iic_request_IPIs(void) iic_request_ipi(PPC_MSG_DEBUGGER_BREAK, "IPI-debug"); #endif /* CONFIG_DEBUGGER */ } + #endif /* CONFIG_SMP */ -static void iic_setup_spe_handlers(void) + +static int iic_host_match(struct irq_host *h, struct device_node *node) +{ + return h->host_data != NULL && node == h->host_data; +} + +static int iic_host_map(struct irq_host *h, unsigned int virq, + irq_hw_number_t hw) { - int be, isrc; + if (hw < IIC_IRQ_IPI0) + set_irq_chip_and_handler(virq, &iic_chip, handle_fasteoi_irq); + else + set_irq_chip_and_handler(virq, &iic_chip, handle_percpu_irq); + return 0; +} + +static int iic_host_xlate(struct irq_host *h, struct device_node *ct, + u32 *intspec, unsigned int intsize, + irq_hw_number_t *out_hwirq, unsigned int *out_flags) - /* Assume two threads per BE are present */ - for (be=0; be < num_present_cpus() / 2; be++) { - for (isrc = 0; isrc < IIC_CLASS_STRIDE * 3; isrc++) { - int irq = IIC_NODE_STRIDE * be + IIC_SPE_OFFSET + isrc; - get_irq_desc(irq)->handler = &iic_pic; +{ + /* Currently, we don't translate anything. That needs to be fixed as + * we get better defined device-trees. iic interrupts have to be + * explicitely mapped by whoever needs them + */ + return -ENODEV; +} + +static struct irq_host_ops iic_host_ops = { + .match = iic_host_match, + .map = iic_host_map, + .xlate = iic_host_xlate, +}; + +static void __init init_one_iic(unsigned int hw_cpu, unsigned long addr, + struct irq_host *host) +{ + /* XXX FIXME: should locate the linux CPU number from the HW cpu + * number properly. We are lucky for now + */ + struct iic *iic = &per_cpu(iic, hw_cpu); + + iic->regs = ioremap(addr, sizeof(struct cbe_iic_thread_regs)); + BUG_ON(iic->regs == NULL); + + iic->target_id = ((hw_cpu & 2) << 3) | ((hw_cpu & 1) ? 0xf : 0xe); + iic->eoi_stack[0] = 0xff; + iic->host = host; + out_be64(&iic->regs->prio, 0); + + printk(KERN_INFO "IIC for CPU %d at %lx mapped to %p, target id 0x%x\n", + hw_cpu, addr, iic->regs, iic->target_id); +} + +static int __init setup_iic(void) +{ + struct device_node *dn; + struct resource r0, r1; + struct irq_host *host; + int found = 0; + const u32 *np; + + for (dn = NULL; + (dn = of_find_node_by_name(dn,"interrupt-controller")) != NULL;) { + if (!device_is_compatible(dn, + "IBM,CBEA-Internal-Interrupt-Controller")) + continue; + np = get_property(dn, "ibm,interrupt-server-ranges", NULL); + if (np == NULL) { + printk(KERN_WARNING "IIC: CPU association not found\n"); + of_node_put(dn); + return -ENODEV; + } + if (of_address_to_resource(dn, 0, &r0) || + of_address_to_resource(dn, 1, &r1)) { + printk(KERN_WARNING "IIC: Can't resolve addresses\n"); + of_node_put(dn); + return -ENODEV; + } + host = NULL; + if (found < IIC_NODE_COUNT) { + host = irq_alloc_host(IRQ_HOST_MAP_LINEAR, + IIC_SOURCE_COUNT, + &iic_host_ops, + IIC_IRQ_INVALID); + iic_hosts[found] = host; + BUG_ON(iic_hosts[found] == NULL); + iic_hosts[found]->host_data = of_node_get(dn); + found++; } + init_one_iic(np[0], r0.start, host); + init_one_iic(np[1], r1.start, host); } + + if (found) + return 0; + else + return -ENODEV; } -void iic_init_IRQ(void) +void __init iic_init_IRQ(void) { - int cpu, irq_offset; - struct iic *iic; - + /* Discover and initialize iics */ if (setup_iic() < 0) - setup_iic_hardcoded(); + panic("IIC: Failed to initialize !\n"); - irq_offset = 0; - for_each_possible_cpu(cpu) { - iic = &per_cpu(iic, cpu); - if (iic->regs) - out_be64(&iic->regs->prio, 0xff); - } - iic_setup_spe_handlers(); + /* Set master interrupt handling function */ + ppc_md.get_irq = iic_get_irq; + + /* Enable on current CPU */ + iic_setup_cpu(); } diff --git a/arch/powerpc/platforms/cell/interrupt.h b/arch/powerpc/platforms/cell/interrupt.h index 799f77d98f96..5560a92ec3ab 100644 --- a/arch/powerpc/platforms/cell/interrupt.h +++ b/arch/powerpc/platforms/cell/interrupt.h @@ -37,27 +37,24 @@ */ enum { - IIC_EXT_OFFSET = 0x00, /* Start of south bridge IRQs */ - IIC_NUM_EXT = 0x40, /* Number of south bridge IRQs */ - IIC_SPE_OFFSET = 0x40, /* Start of SPE interrupts */ - IIC_CLASS_STRIDE = 0x10, /* SPE IRQs per class */ - IIC_IPI_OFFSET = 0x70, /* Start of IPI IRQs */ - IIC_NUM_IPIS = 0x10, /* IRQs reserved for IPI */ - IIC_NODE_STRIDE = 0x80, /* Total IRQs per node */ + IIC_IRQ_INVALID = 0xff, + IIC_IRQ_MAX = 0x3f, + IIC_IRQ_EXT_IOIF0 = 0x20, + IIC_IRQ_EXT_IOIF1 = 0x2b, + IIC_IRQ_IPI0 = 0x40, + IIC_NUM_IPIS = 0x10, /* IRQs reserved for IPI */ + IIC_SOURCE_COUNT = 0x50, }; extern void iic_init_IRQ(void); -extern int iic_get_irq(struct pt_regs *regs); extern void iic_cause_IPI(int cpu, int mesg); extern void iic_request_IPIs(void); extern void iic_setup_cpu(void); -extern void iic_local_enable(void); -extern void iic_local_disable(void); extern u8 iic_get_target_id(int cpu); +extern struct irq_host *iic_get_irq_host(int node); extern void spider_init_IRQ(void); -extern int spider_get_irq(int node); #endif #endif /* ASM_CELL_PIC_H */ diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c index a35004e14c69..d2b20eba5b87 100644 --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c @@ -308,15 +308,16 @@ static void cell_do_map_iommu(struct cell_iommu *iommu, static void iommu_devnode_setup(struct device_node *d) { - unsigned int *ioid; - unsigned long *dma_window, map_start, map_size, token; + const unsigned int *ioid; + unsigned long map_start, map_size, token; + const unsigned long *dma_window; struct cell_iommu *iommu; - ioid = (unsigned int *)get_property(d, "ioid", NULL); + ioid = get_property(d, "ioid", NULL); if (!ioid) pr_debug("No ioid entry found !\n"); - dma_window = (unsigned long *)get_property(d, "ibm,dma-window", NULL); + dma_window = get_property(d, "ibm,dma-window", NULL); if (!dma_window) pr_debug("No ibm,dma-window entry found !\n"); @@ -371,8 +372,9 @@ static int cell_map_iommu_hardcoded(int num_nodes) static int cell_map_iommu(void) { - unsigned int num_nodes = 0, *node_id; - unsigned long *base, *mmio_base; + unsigned int num_nodes = 0; + const unsigned int *node_id; + const unsigned long *base, *mmio_base; struct device_node *dn; struct cell_iommu *iommu = NULL; @@ -381,7 +383,7 @@ static int cell_map_iommu(void) for(dn = of_find_node_by_type(NULL, "cpu"); dn; dn = of_find_node_by_type(dn, "cpu")) { - node_id = (unsigned int *)get_property(dn, "node-id", NULL); + node_id = get_property(dn, "node-id", NULL); if (num_nodes < *node_id) num_nodes = *node_id; @@ -396,9 +398,9 @@ static int cell_map_iommu(void) dn; dn = of_find_node_by_type(dn, "cpu")) { - node_id = (unsigned int *)get_property(dn, "node-id", NULL); - base = (unsigned long *)get_property(dn, "ioc-cache", NULL); - mmio_base = (unsigned long *)get_property(dn, "ioc-translation", NULL); + node_id = get_property(dn, "node-id", NULL); + base = get_property(dn, "ioc-cache", NULL); + mmio_base = get_property(dn, "ioc-translation", NULL); if (!base || !mmio_base || !node_id) return cell_map_iommu_hardcoded(num_nodes); diff --git a/arch/powerpc/platforms/cell/pervasive.c b/arch/powerpc/platforms/cell/pervasive.c index 695ac4e1617e..9f2e4ed20a57 100644 --- a/arch/powerpc/platforms/cell/pervasive.c +++ b/arch/powerpc/platforms/cell/pervasive.c @@ -23,7 +23,6 @@ #undef DEBUG -#include <linux/config.h> #include <linux/interrupt.h> #include <linux/irq.h> #include <linux/percpu.h> diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c index 3d1831d331e5..22c228a49c33 100644 --- a/arch/powerpc/platforms/cell/setup.c +++ b/arch/powerpc/platforms/cell/setup.c @@ -14,7 +14,6 @@ */ #undef DEBUG -#include <linux/config.h> #include <linux/sched.h> #include <linux/kernel.h> #include <linux/mm.h> @@ -50,6 +49,7 @@ #include <asm/irq.h> #include <asm/spu.h> #include <asm/spu_priv1.h> +#include <asm/udbg.h> #include "interrupt.h" #include "iommu.h" @@ -80,10 +80,22 @@ static void cell_progress(char *s, unsigned short hex) printk("*** %04x : %s\n", hex, s ? s : ""); } +static void __init cell_pcibios_fixup(void) +{ + struct pci_dev *dev = NULL; + + for_each_pci_dev(dev) + pci_read_irq_line(dev); +} + +static void __init cell_init_irq(void) +{ + iic_init_IRQ(); + spider_init_IRQ(); +} + static void __init cell_setup_arch(void) { - ppc_md.init_IRQ = iic_init_IRQ; - ppc_md.get_irq = iic_get_irq; #ifdef CONFIG_SPU_BASE spu_priv1_ops = &spu_priv1_mmio_ops; #endif @@ -109,7 +121,6 @@ static void __init cell_setup_arch(void) /* Find and initialize PCI host bridges */ init_pci_config_tokens(); find_and_init_phbs(); - spider_init_IRQ(); cbe_pervasive_init(); #ifdef CONFIG_DUMMY_CONSOLE conswitchp = &dummy_con; @@ -125,12 +136,8 @@ static void __init cell_init_early(void) { DBG(" -> cell_init_early()\n"); - hpte_init_native(); - cell_init_iommu(); - ppc64_interrupt_controller = IC_CELL_PIC; - DBG(" <- cell_init_early()\n"); } @@ -139,11 +146,13 @@ static int __init cell_probe(void) { unsigned long root = of_get_flat_dt_root(); - if (of_flat_dt_is_compatible(root, "IBM,CBEA") || - of_flat_dt_is_compatible(root, "IBM,CPBW-1.0")) - return 1; + if (!of_flat_dt_is_compatible(root, "IBM,CBEA") && + !of_flat_dt_is_compatible(root, "IBM,CPBW-1.0")) + return 0; + + hpte_init_native(); - return 0; + return 1; } /* @@ -170,6 +179,8 @@ define_machine(cell) { .calibrate_decr = generic_calibrate_decr, .check_legacy_ioport = cell_check_legacy_ioport, .progress = cell_progress, + .init_IRQ = cell_init_irq, + .pcibios_fixup = cell_pcibios_fixup, #ifdef CONFIG_KEXEC .machine_kexec = default_machine_kexec, .machine_kexec_prepare = default_machine_kexec_prepare, diff --git a/arch/powerpc/platforms/cell/smp.c b/arch/powerpc/platforms/cell/smp.c index bdf6c5fe58c0..1c0acbad7425 100644 --- a/arch/powerpc/platforms/cell/smp.c +++ b/arch/powerpc/platforms/cell/smp.c @@ -14,7 +14,6 @@ #undef DEBUG -#include <linux/config.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/sched.h> @@ -58,7 +57,7 @@ */ static cpumask_t of_spin_map; -extern void pSeries_secondary_smp_init(unsigned long); +extern void generic_secondary_smp_init(unsigned long); /** * smp_startup_cpu() - start the given cpu @@ -75,7 +74,7 @@ static inline int __devinit smp_startup_cpu(unsigned int lcpu) { int status; unsigned long start_here = __pa((u32)*((unsigned long *) - pSeries_secondary_smp_init)); + generic_secondary_smp_init)); unsigned int pcpu; int start_cpu; diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c index 55cbdd77a62d..742a03282b44 100644 --- a/arch/powerpc/platforms/cell/spider-pic.c +++ b/arch/powerpc/platforms/cell/spider-pic.c @@ -22,6 +22,7 @@ #include <linux/interrupt.h> #include <linux/irq.h> +#include <linux/ioport.h> #include <asm/pgtable.h> #include <asm/prom.h> @@ -56,184 +57,323 @@ enum { REISWAITEN = 0x508, /* Reissue Wait Control*/ }; -static void __iomem *spider_pics[4]; +#define SPIDER_CHIP_COUNT 4 +#define SPIDER_SRC_COUNT 64 +#define SPIDER_IRQ_INVALID 63 -static void __iomem *spider_get_pic(int irq) -{ - int node = irq / IIC_NODE_STRIDE; - irq %= IIC_NODE_STRIDE; - - if (irq >= IIC_EXT_OFFSET && - irq < IIC_EXT_OFFSET + IIC_NUM_EXT && - spider_pics) - return spider_pics[node]; - return NULL; -} +struct spider_pic { + struct irq_host *host; + struct device_node *of_node; + void __iomem *regs; + unsigned int node_id; +}; +static struct spider_pic spider_pics[SPIDER_CHIP_COUNT]; -static int spider_get_nr(unsigned int irq) +static struct spider_pic *spider_virq_to_pic(unsigned int virq) { - return (irq % IIC_NODE_STRIDE) - IIC_EXT_OFFSET; + return irq_map[virq].host->host_data; } -static void __iomem *spider_get_irq_config(int irq) +static void __iomem *spider_get_irq_config(struct spider_pic *pic, + unsigned int src) { - void __iomem *pic; - pic = spider_get_pic(irq); - return pic + TIR_CFGA + 8 * spider_get_nr(irq); + return pic->regs + TIR_CFGA + 8 * src; } -static void spider_enable_irq(unsigned int irq) +static void spider_unmask_irq(unsigned int virq) { - int nodeid = (irq / IIC_NODE_STRIDE) * 0x10; - void __iomem *cfg = spider_get_irq_config(irq); - irq = spider_get_nr(irq); + struct spider_pic *pic = spider_virq_to_pic(virq); + void __iomem *cfg = spider_get_irq_config(pic, irq_map[virq].hwirq); - out_be32(cfg, (in_be32(cfg) & ~0xf0)| 0x3107000eu | nodeid); - out_be32(cfg + 4, in_be32(cfg + 4) | 0x00020000u | irq); + out_be32(cfg, in_be32(cfg) | 0x30000000u); } -static void spider_disable_irq(unsigned int irq) +static void spider_mask_irq(unsigned int virq) { - void __iomem *cfg = spider_get_irq_config(irq); - irq = spider_get_nr(irq); + struct spider_pic *pic = spider_virq_to_pic(virq); + void __iomem *cfg = spider_get_irq_config(pic, irq_map[virq].hwirq); out_be32(cfg, in_be32(cfg) & ~0x30000000u); } -static unsigned int spider_startup_irq(unsigned int irq) +static void spider_ack_irq(unsigned int virq) { - spider_enable_irq(irq); - return 0; -} + struct spider_pic *pic = spider_virq_to_pic(virq); + unsigned int src = irq_map[virq].hwirq; -static void spider_shutdown_irq(unsigned int irq) -{ - spider_disable_irq(irq); -} + /* Reset edge detection logic if necessary + */ + if (get_irq_desc(virq)->status & IRQ_LEVEL) + return; -static void spider_end_irq(unsigned int irq) -{ - spider_enable_irq(irq); + /* Only interrupts 47 to 50 can be set to edge */ + if (src < 47 || src > 50) + return; + + /* Perform the clear of the edge logic */ + out_be32(pic->regs + TIR_EDC, 0x100 | (src & 0xf)); } -static void spider_ack_irq(unsigned int irq) +static int spider_set_irq_type(unsigned int virq, unsigned int type) { - spider_disable_irq(irq); - iic_local_enable(); + unsigned int sense = type & IRQ_TYPE_SENSE_MASK; + struct spider_pic *pic = spider_virq_to_pic(virq); + unsigned int hw = irq_map[virq].hwirq; + void __iomem *cfg = spider_get_irq_config(pic, hw); + struct irq_desc *desc = get_irq_desc(virq); + u32 old_mask; + u32 ic; + + /* Note that only level high is supported for most interrupts */ + if (sense != IRQ_TYPE_NONE && sense != IRQ_TYPE_LEVEL_HIGH && + (hw < 47 || hw > 50)) + return -EINVAL; + + /* Decode sense type */ + switch(sense) { + case IRQ_TYPE_EDGE_RISING: + ic = 0x3; + break; + case IRQ_TYPE_EDGE_FALLING: + ic = 0x2; + break; + case IRQ_TYPE_LEVEL_LOW: + ic = 0x0; + break; + case IRQ_TYPE_LEVEL_HIGH: + case IRQ_TYPE_NONE: + ic = 0x1; + break; + default: + return -EINVAL; + } + + /* Update irq_desc */ + desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); + desc->status |= type & IRQ_TYPE_SENSE_MASK; + if (type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) + desc->status |= IRQ_LEVEL; + + /* Configure the source. One gross hack that was there before and + * that I've kept around is the priority to the BE which I set to + * be the same as the interrupt source number. I don't know wether + * that's supposed to make any kind of sense however, we'll have to + * decide that, but for now, I'm not changing the behaviour. + */ + old_mask = in_be32(cfg) & 0x30000000u; + out_be32(cfg, old_mask | (ic << 24) | (0x7 << 16) | + (pic->node_id << 4) | 0xe); + out_be32(cfg + 4, (0x2 << 16) | (hw & 0xff)); + + return 0; } -static struct hw_interrupt_type spider_pic = { +static struct irq_chip spider_pic = { .typename = " SPIDER ", - .startup = spider_startup_irq, - .shutdown = spider_shutdown_irq, - .enable = spider_enable_irq, - .disable = spider_disable_irq, + .unmask = spider_unmask_irq, + .mask = spider_mask_irq, .ack = spider_ack_irq, - .end = spider_end_irq, + .set_type = spider_set_irq_type, }; -int spider_get_irq(int node) +static int spider_host_match(struct irq_host *h, struct device_node *node) +{ + struct spider_pic *pic = h->host_data; + return node == pic->of_node; +} + +static int spider_host_map(struct irq_host *h, unsigned int virq, + irq_hw_number_t hw) { - unsigned long cs; - void __iomem *regs = spider_pics[node]; + set_irq_chip_and_handler(virq, &spider_pic, handle_level_irq); - cs = in_be32(regs + TIR_CS) >> 24; + /* Set default irq type */ + set_irq_type(virq, IRQ_TYPE_NONE); - if (cs == 63) - return -1; - else - return cs; + return 0; } -/* hardcoded part to be compatible with older firmware */ +static int spider_host_xlate(struct irq_host *h, struct device_node *ct, + u32 *intspec, unsigned int intsize, + irq_hw_number_t *out_hwirq, unsigned int *out_flags) -void spider_init_IRQ_hardcoded(void) { - int node; - long spiderpic; - long pics[] = { 0x24000008000, 0x34000008000 }; - int n; - - pr_debug("%s(%d): Using hardcoded defaults\n", __FUNCTION__, __LINE__); - - for (node = 0; node < num_present_cpus()/2; node++) { - spiderpic = pics[node]; - printk(KERN_DEBUG "SPIDER addr: %lx\n", spiderpic); - spider_pics[node] = ioremap(spiderpic, 0x800); - for (n = 0; n < IIC_NUM_EXT; n++) { - int irq = n + IIC_EXT_OFFSET + node * IIC_NODE_STRIDE; - get_irq_desc(irq)->handler = &spider_pic; - } - - /* do not mask any interrupts because of level */ - out_be32(spider_pics[node] + TIR_MSK, 0x0); - - /* disable edge detection clear */ - /* out_be32(spider_pics[node] + TIR_EDC, 0x0); */ - - /* enable interrupt packets to be output */ - out_be32(spider_pics[node] + TIR_PIEN, - in_be32(spider_pics[node] + TIR_PIEN) | 0x1); - - /* Enable the interrupt detection enable bit. Do this last! */ - out_be32(spider_pics[node] + TIR_DEN, - in_be32(spider_pics[node] + TIR_DEN) | 0x1); - } + /* Spider interrupts have 2 cells, first is the interrupt source, + * second, well, I don't know for sure yet ... We mask the top bits + * because old device-trees encode a node number in there + */ + *out_hwirq = intspec[0] & 0x3f; + *out_flags = IRQ_TYPE_LEVEL_HIGH; + return 0; } -void spider_init_IRQ(void) -{ - long spider_reg; - struct device_node *dn; - char *compatible; - int n, node = 0; - - for (dn = NULL; (dn = of_find_node_by_name(dn, "interrupt-controller"));) { - compatible = (char *)get_property(dn, "compatible", NULL); - - if (!compatible) - continue; - - if (strstr(compatible, "CBEA,platform-spider-pic")) - spider_reg = *(long *)get_property(dn,"reg", NULL); - else if (strstr(compatible, "sti,platform-spider-pic")) { - spider_init_IRQ_hardcoded(); - return; - } else - continue; +static struct irq_host_ops spider_host_ops = { + .match = spider_host_match, + .map = spider_host_map, + .xlate = spider_host_xlate, +}; - if (!spider_reg) - printk("interrupt controller does not have reg property !\n"); +static void spider_irq_cascade(unsigned int irq, struct irq_desc *desc, + struct pt_regs *regs) +{ + struct spider_pic *pic = desc->handler_data; + unsigned int cs, virq; - n = prom_n_addr_cells(dn); + cs = in_be32(pic->regs + TIR_CS) >> 24; + if (cs == SPIDER_IRQ_INVALID) + virq = NO_IRQ; + else + virq = irq_linear_revmap(pic->host, cs); + if (virq != NO_IRQ) + generic_handle_irq(virq, regs); + desc->chip->eoi(irq); +} - if ( n != 2) - printk("reg property with invalid number of elements \n"); +/* For hooking up the cascace we have a problem. Our device-tree is + * crap and we don't know on which BE iic interrupt we are hooked on at + * least not the "standard" way. We can reconstitute it based on two + * informations though: which BE node we are connected to and wether + * we are connected to IOIF0 or IOIF1. Right now, we really only care + * about the IBM cell blade and we know that its firmware gives us an + * interrupt-map property which is pretty strange. + */ +static unsigned int __init spider_find_cascade_and_node(struct spider_pic *pic) +{ + unsigned int virq; + const u32 *imap, *tmp; + int imaplen, intsize, unit; + struct device_node *iic; + struct irq_host *iic_host; + +#if 0 /* Enable that when we have a way to retreive the node as well */ + /* First, we check wether we have a real "interrupts" in the device + * tree in case the device-tree is ever fixed + */ + struct of_irq oirq; + if (of_irq_map_one(pic->of_node, 0, &oirq) == 0) { + virq = irq_create_of_mapping(oirq.controller, oirq.specifier, + oirq.size); + goto bail; + } +#endif + + /* Now do the horrible hacks */ + tmp = get_property(pic->of_node, "#interrupt-cells", NULL); + if (tmp == NULL) + return NO_IRQ; + intsize = *tmp; + imap = get_property(pic->of_node, "interrupt-map", &imaplen); + if (imap == NULL || imaplen < (intsize + 1)) + return NO_IRQ; + iic = of_find_node_by_phandle(imap[intsize]); + if (iic == NULL) + return NO_IRQ; + imap += intsize + 1; + tmp = get_property(iic, "#interrupt-cells", NULL); + if (tmp == NULL) + return NO_IRQ; + intsize = *tmp; + /* Assume unit is last entry of interrupt specifier */ + unit = imap[intsize - 1]; + /* Ok, we have a unit, now let's try to get the node */ + tmp = get_property(iic, "ibm,interrupt-server-ranges", NULL); + if (tmp == NULL) { + of_node_put(iic); + return NO_IRQ; + } + /* ugly as hell but works for now */ + pic->node_id = (*tmp) >> 1; + of_node_put(iic); + + /* Ok, now let's get cracking. You may ask me why I just didn't match + * the iic host from the iic OF node, but that way I'm still compatible + * with really really old old firmwares for which we don't have a node + */ + iic_host = iic_get_irq_host(pic->node_id); + if (iic_host == NULL) + return NO_IRQ; + /* Manufacture an IIC interrupt number of class 2 */ + virq = irq_create_mapping(iic_host, 0x20 | unit); + if (virq == NO_IRQ) + printk(KERN_ERR "spider_pic: failed to map cascade !"); + return virq; +} - spider_pics[node] = ioremap(spider_reg, 0x800); - printk("SPIDER addr: %lx with %i addr_cells mapped to %p\n", - spider_reg, n, spider_pics[node]); +static void __init spider_init_one(struct device_node *of_node, int chip, + unsigned long addr) +{ + struct spider_pic *pic = &spider_pics[chip]; + int i, virq; + + /* Map registers */ + pic->regs = ioremap(addr, 0x1000); + if (pic->regs == NULL) + panic("spider_pic: can't map registers !"); + + /* Allocate a host */ + pic->host = irq_alloc_host(IRQ_HOST_MAP_LINEAR, SPIDER_SRC_COUNT, + &spider_host_ops, SPIDER_IRQ_INVALID); + if (pic->host == NULL) + panic("spider_pic: can't allocate irq host !"); + pic->host->host_data = pic; + + /* Fill out other bits */ + pic->of_node = of_node_get(of_node); + + /* Go through all sources and disable them */ + for (i = 0; i < SPIDER_SRC_COUNT; i++) { + void __iomem *cfg = pic->regs + TIR_CFGA + 8 * i; + out_be32(cfg, in_be32(cfg) & ~0x30000000u); + } - for (n = 0; n < IIC_NUM_EXT; n++) { - int irq = n + IIC_EXT_OFFSET + node * IIC_NODE_STRIDE; - get_irq_desc(irq)->handler = &spider_pic; - } + /* do not mask any interrupts because of level */ + out_be32(pic->regs + TIR_MSK, 0x0); - /* do not mask any interrupts because of level */ - out_be32(spider_pics[node] + TIR_MSK, 0x0); + /* enable interrupt packets to be output */ + out_be32(pic->regs + TIR_PIEN, in_be32(pic->regs + TIR_PIEN) | 0x1); - /* disable edge detection clear */ - /* out_be32(spider_pics[node] + TIR_EDC, 0x0); */ + /* Hook up the cascade interrupt to the iic and nodeid */ + virq = spider_find_cascade_and_node(pic); + if (virq == NO_IRQ) + return; + set_irq_data(virq, pic); + set_irq_chained_handler(virq, spider_irq_cascade); - /* enable interrupt packets to be output */ - out_be32(spider_pics[node] + TIR_PIEN, - in_be32(spider_pics[node] + TIR_PIEN) | 0x1); + printk(KERN_INFO "spider_pic: node %d, addr: 0x%lx %s\n", + pic->node_id, addr, of_node->full_name); - /* Enable the interrupt detection enable bit. Do this last! */ - out_be32(spider_pics[node] + TIR_DEN, - in_be32(spider_pics[node] + TIR_DEN) | 0x1); + /* Enable the interrupt detection enable bit. Do this last! */ + out_be32(pic->regs + TIR_DEN, in_be32(pic->regs + TIR_DEN) | 0x1); +} - node++; +void __init spider_init_IRQ(void) +{ + struct resource r; + struct device_node *dn; + int chip = 0; + + /* XXX node numbers are totally bogus. We _hope_ we get the device + * nodes in the right order here but that's definitely not guaranteed, + * we need to get the node from the device tree instead. + * There is currently no proper property for it (but our whole + * device-tree is bogus anyway) so all we can do is pray or maybe test + * the address and deduce the node-id + */ + for (dn = NULL; + (dn = of_find_node_by_name(dn, "interrupt-controller"));) { + if (device_is_compatible(dn, "CBEA,platform-spider-pic")) { + if (of_address_to_resource(dn, 0, &r)) { + printk(KERN_WARNING "spider-pic: Failed\n"); + continue; + } + } else if (device_is_compatible(dn, "sti,platform-spider-pic") + && (chip < 2)) { + static long hard_coded_pics[] = + { 0x24000008000, 0x34000008000 }; + r.start = hard_coded_pics[chip]; + } else + continue; + spider_init_one(dn, chip++, r.start); } } diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index db82f503ba2c..3bd36d46ab4a 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c @@ -168,12 +168,12 @@ spu_irq_class_0_bottom(struct spu *spu) stat &= mask; - if (stat & 1) /* invalid MFC DMA */ - __spu_trap_invalid_dma(spu); - - if (stat & 2) /* invalid DMA alignment */ + if (stat & 1) /* invalid DMA alignment */ __spu_trap_dma_align(spu); + if (stat & 2) /* invalid MFC DMA */ + __spu_trap_invalid_dma(spu); + if (stat & 4) /* error on SPU */ __spu_trap_error(spu); @@ -264,51 +264,57 @@ spu_irq_class_2(int irq, void *data, struct pt_regs *regs) return stat ? IRQ_HANDLED : IRQ_NONE; } -static int -spu_request_irqs(struct spu *spu) +static int spu_request_irqs(struct spu *spu) { - int ret; - int irq_base; - - irq_base = IIC_NODE_STRIDE * spu->node + IIC_SPE_OFFSET; - - snprintf(spu->irq_c0, sizeof (spu->irq_c0), "spe%02d.0", spu->number); - ret = request_irq(irq_base + spu->isrc, - spu_irq_class_0, SA_INTERRUPT, spu->irq_c0, spu); - if (ret) - goto out; - - snprintf(spu->irq_c1, sizeof (spu->irq_c1), "spe%02d.1", spu->number); - ret = request_irq(irq_base + IIC_CLASS_STRIDE + spu->isrc, - spu_irq_class_1, SA_INTERRUPT, spu->irq_c1, spu); - if (ret) - goto out1; + int ret = 0; - snprintf(spu->irq_c2, sizeof (spu->irq_c2), "spe%02d.2", spu->number); - ret = request_irq(irq_base + 2*IIC_CLASS_STRIDE + spu->isrc, - spu_irq_class_2, SA_INTERRUPT, spu->irq_c2, spu); - if (ret) - goto out2; - goto out; + if (spu->irqs[0] != NO_IRQ) { + snprintf(spu->irq_c0, sizeof (spu->irq_c0), "spe%02d.0", + spu->number); + ret = request_irq(spu->irqs[0], spu_irq_class_0, + IRQF_DISABLED, + spu->irq_c0, spu); + if (ret) + goto bail0; + } + if (spu->irqs[1] != NO_IRQ) { + snprintf(spu->irq_c1, sizeof (spu->irq_c1), "spe%02d.1", + spu->number); + ret = request_irq(spu->irqs[1], spu_irq_class_1, + IRQF_DISABLED, + spu->irq_c1, spu); + if (ret) + goto bail1; + } + if (spu->irqs[2] != NO_IRQ) { + snprintf(spu->irq_c2, sizeof (spu->irq_c2), "spe%02d.2", + spu->number); + ret = request_irq(spu->irqs[2], spu_irq_class_2, + IRQF_DISABLED, + spu->irq_c2, spu); + if (ret) + goto bail2; + } + return 0; -out2: - free_irq(irq_base + IIC_CLASS_STRIDE + spu->isrc, spu); -out1: - free_irq(irq_base + spu->isrc, spu); -out: +bail2: + if (spu->irqs[1] != NO_IRQ) + free_irq(spu->irqs[1], spu); +bail1: + if (spu->irqs[0] != NO_IRQ) + free_irq(spu->irqs[0], spu); +bail0: return ret; } -static void -spu_free_irqs(struct spu *spu) +static void spu_free_irqs(struct spu *spu) { - int irq_base; - - irq_base = IIC_NODE_STRIDE * spu->node + IIC_SPE_OFFSET; - - free_irq(irq_base + spu->isrc, spu); - free_irq(irq_base + IIC_CLASS_STRIDE + spu->isrc, spu); - free_irq(irq_base + 2*IIC_CLASS_STRIDE + spu->isrc, spu); + if (spu->irqs[0] != NO_IRQ) + free_irq(spu->irqs[0], spu); + if (spu->irqs[1] != NO_IRQ) + free_irq(spu->irqs[1], spu); + if (spu->irqs[2] != NO_IRQ) + free_irq(spu->irqs[2], spu); } static LIST_HEAD(spu_list); @@ -482,10 +488,10 @@ int spu_irq_class_1_bottom(struct spu *spu) static int __init find_spu_node_id(struct device_node *spe) { - unsigned int *id; + const unsigned int *id; struct device_node *cpu; cpu = spe->parent->parent; - id = (unsigned int *)get_property(cpu, "node-id", NULL); + id = get_property(cpu, "node-id", NULL); return id ? *id : 0; } @@ -494,7 +500,7 @@ static int __init cell_spuprop_present(struct spu *spu, struct device_node *spe, { static DEFINE_MUTEX(add_spumem_mutex); - struct address_prop { + const struct address_prop { unsigned long address; unsigned int len; } __attribute__((packed)) *p; @@ -505,7 +511,7 @@ static int __init cell_spuprop_present(struct spu *spu, struct device_node *spe, struct zone *zone; int ret; - p = (void*)get_property(spe, prop, &proplen); + p = get_property(spe, prop, &proplen); WARN_ON(proplen != sizeof (*p)); start_pfn = p->address >> PAGE_SHIFT; @@ -525,12 +531,12 @@ static int __init cell_spuprop_present(struct spu *spu, struct device_node *spe, static void __iomem * __init map_spe_prop(struct spu *spu, struct device_node *n, const char *name) { - struct address_prop { + const struct address_prop { unsigned long address; unsigned int len; } __attribute__((packed)) *prop; - void *p; + const void *p; int proplen; void* ret = NULL; int err = 0; @@ -559,17 +565,38 @@ static void spu_unmap(struct spu *spu) iounmap((u8 __iomem *)spu->local_store); } +/* This function shall be abstracted for HV platforms */ +static int __init spu_map_interrupts(struct spu *spu, struct device_node *np) +{ + struct irq_host *host; + unsigned int isrc; + const u32 *tmp; + + host = iic_get_irq_host(spu->node); + if (host == NULL) + return -ENODEV; + + /* Get the interrupt source from the device-tree */ + tmp = get_property(np, "isrc", NULL); + if (!tmp) + return -ENODEV; + spu->isrc = isrc = tmp[0]; + + /* Now map interrupts of all 3 classes */ + spu->irqs[0] = irq_create_mapping(host, 0x00 | isrc); + spu->irqs[1] = irq_create_mapping(host, 0x10 | isrc); + spu->irqs[2] = irq_create_mapping(host, 0x20 | isrc); + + /* Right now, we only fail if class 2 failed */ + return spu->irqs[2] == NO_IRQ ? -EINVAL : 0; +} + static int __init spu_map_device(struct spu *spu, struct device_node *node) { - char *prop; + const char *prop; int ret; ret = -ENODEV; - prop = get_property(node, "isrc", NULL); - if (!prop) - goto out; - spu->isrc = *(unsigned int *)prop; - spu->name = get_property(node, "name", NULL); if (!spu->name) goto out; @@ -636,7 +663,8 @@ static int spu_create_sysdev(struct spu *spu) return ret; } - sysdev_create_file(&spu->sysdev, &attr_isrc); + if (spu->isrc != 0) + sysdev_create_file(&spu->sysdev, &attr_isrc); sysfs_add_device_to_node(&spu->sysdev, spu->nid); return 0; @@ -668,6 +696,9 @@ static int __init create_spu(struct device_node *spe) spu->nid = of_node_to_nid(spe); if (spu->nid == -1) spu->nid = 0; + ret = spu_map_interrupts(spu, spe); + if (ret) + goto out_unmap; spin_lock_init(&spu->register_lock); spu_mfc_sdr_set(spu, mfspr(SPRN_SDR1)); spu_mfc_sr1_set(spu, 0x33); diff --git a/arch/powerpc/platforms/cell/spufs/backing_ops.c b/arch/powerpc/platforms/cell/spufs/backing_ops.c index f1d35ddc9df3..2d22cd59d6fc 100644 --- a/arch/powerpc/platforms/cell/spufs/backing_ops.c +++ b/arch/powerpc/platforms/cell/spufs/backing_ops.c @@ -21,7 +21,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/errno.h> #include <linux/sched.h> diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index 80c02660e617..58e794f9da1b 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -204,7 +204,7 @@ static int spufs_cntl_mmap(struct file *file, struct vm_area_struct *vma) vma->vm_flags |= VM_RESERVED; vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) - | _PAGE_NO_CACHE); + | _PAGE_NO_CACHE | _PAGE_GUARDED); vma->vm_ops = &spufs_cntl_mmap_vmops; return 0; @@ -675,7 +675,7 @@ static int spufs_signal1_mmap(struct file *file, struct vm_area_struct *vma) vma->vm_flags |= VM_RESERVED; vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) - | _PAGE_NO_CACHE); + | _PAGE_NO_CACHE | _PAGE_GUARDED); vma->vm_ops = &spufs_signal1_mmap_vmops; return 0; @@ -762,7 +762,7 @@ static int spufs_signal2_mmap(struct file *file, struct vm_area_struct *vma) /* FIXME: */ vma->vm_flags |= VM_RESERVED; vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) - | _PAGE_NO_CACHE); + | _PAGE_NO_CACHE | _PAGE_GUARDED); vma->vm_ops = &spufs_signal2_mmap_vmops; return 0; @@ -850,7 +850,7 @@ static int spufs_mss_mmap(struct file *file, struct vm_area_struct *vma) vma->vm_flags |= VM_RESERVED; vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) - | _PAGE_NO_CACHE); + | _PAGE_NO_CACHE | _PAGE_GUARDED); vma->vm_ops = &spufs_mss_mmap_vmops; return 0; @@ -899,7 +899,7 @@ static int spufs_mfc_mmap(struct file *file, struct vm_area_struct *vma) vma->vm_flags |= VM_RESERVED; vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) - | _PAGE_NO_CACHE); + | _PAGE_NO_CACHE | _PAGE_GUARDED); vma->vm_ops = &spufs_mfc_mmap_vmops; return 0; @@ -1150,7 +1150,7 @@ static unsigned int spufs_mfc_poll(struct file *file,poll_table *wait) return mask; } -static int spufs_mfc_flush(struct file *file) +static int spufs_mfc_flush(struct file *file, fl_owner_t id) { struct spu_context *ctx = file->private_data; int ret; @@ -1176,7 +1176,7 @@ out: static int spufs_mfc_fsync(struct file *file, struct dentry *dentry, int datasync) { - return spufs_mfc_flush(file); + return spufs_mfc_flush(file, NULL); } static int spufs_mfc_fasync(int fd, struct file *file, int on) diff --git a/arch/powerpc/platforms/cell/spufs/hw_ops.c b/arch/powerpc/platforms/cell/spufs/hw_ops.c index ede2cac46b6d..c8670f519734 100644 --- a/arch/powerpc/platforms/cell/spufs/hw_ops.c +++ b/arch/powerpc/platforms/cell/spufs/hw_ops.c @@ -18,7 +18,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/errno.h> #include <linux/sched.h> diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index 7b4572805db9..3950ddccb2c8 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c @@ -82,7 +82,6 @@ spufs_new_inode(struct super_block *sb, int mode) inode->i_mode = mode; inode->i_uid = current->fsuid; inode->i_gid = current->fsgid; - inode->i_blksize = PAGE_CACHE_SIZE; inode->i_blocks = 0; inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; out: @@ -120,7 +119,7 @@ spufs_new_file(struct super_block *sb, struct dentry *dentry, ret = 0; inode->i_op = &spufs_file_iops; inode->i_fop = fops; - inode->u.generic_ip = SPUFS_I(inode)->i_ctx = get_spu_context(ctx); + inode->i_private = SPUFS_I(inode)->i_ctx = get_spu_context(ctx); d_add(dentry, inode); out: return ret; diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c index 3dcc5d8d66b9..1350294484b6 100644 --- a/arch/powerpc/platforms/cell/spufs/sched.c +++ b/arch/powerpc/platforms/cell/spufs/sched.c @@ -26,7 +26,6 @@ #undef DEBUG -#include <linux/config.h> #include <linux/module.h> #include <linux/errno.h> #include <linux/sched.h> diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c index b30e55dab832..9d9d82dd32ba 100644 --- a/arch/powerpc/platforms/cell/spufs/switch.c +++ b/arch/powerpc/platforms/cell/spufs/switch.c @@ -32,7 +32,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/errno.h> #include <linux/sched.h> @@ -464,7 +463,8 @@ static inline void wait_purge_complete(struct spu_state *csa, struct spu *spu) * Poll MFC_CNTL[Ps] until value '11' is read * (purge complete). */ - POLL_WHILE_FALSE(in_be64(&priv2->mfc_control_RW) & + POLL_WHILE_FALSE((in_be64(&priv2->mfc_control_RW) & + MFC_CNTL_PURGE_DMA_STATUS_MASK) == MFC_CNTL_PURGE_DMA_COMPLETE); } @@ -1028,7 +1028,8 @@ static inline void wait_suspend_mfc_complete(struct spu_state *csa, * Restore, Step 47. * Poll MFC_CNTL[Ss] until 11 is returned. */ - POLL_WHILE_FALSE(in_be64(&priv2->mfc_control_RW) & + POLL_WHILE_FALSE((in_be64(&priv2->mfc_control_RW) & + MFC_CNTL_SUSPEND_DMA_STATUS_MASK) == MFC_CNTL_SUSPEND_COMPLETE); } @@ -2100,7 +2101,7 @@ EXPORT_SYMBOL_GPL(spu_save); * @spu: pointer to SPU iomem structure. * * Perform harvest + restore, as we may not be coming - * from a previous succesful save operation, and the + * from a previous successful save operation, and the * hardware state is unknown. */ int spu_restore(struct spu_state *new, struct spu *spu) @@ -2203,7 +2204,7 @@ void spu_init_csa(struct spu_state *csa) memset(lscsa, 0, sizeof(struct spu_lscsa)); csa->lscsa = lscsa; - csa->register_lock = SPIN_LOCK_UNLOCKED; + spin_lock_init(&csa->register_lock); /* Set LS pages reserved to allow for user-space mapping. */ for (p = lscsa->ls; p < lscsa->ls + LS_SIZE; p += PAGE_SIZE) diff --git a/arch/powerpc/platforms/chrp/nvram.c b/arch/powerpc/platforms/chrp/nvram.c index 150f67d6f90c..0dd4a64757d9 100644 --- a/arch/powerpc/platforms/chrp/nvram.c +++ b/arch/powerpc/platforms/chrp/nvram.c @@ -67,13 +67,14 @@ static void chrp_nvram_write(int addr, unsigned char val) void __init chrp_nvram_init(void) { struct device_node *nvram; - unsigned int *nbytes_p, proplen; + const unsigned int *nbytes_p; + unsigned int proplen; nvram = of_find_node_by_type(NULL, "nvram"); if (nvram == NULL) return; - nbytes_p = (unsigned int *)get_property(nvram, "#bytes", &proplen); + nbytes_p = get_property(nvram, "#bytes", &proplen); if (nbytes_p == NULL || proplen != sizeof(unsigned int)) return; diff --git a/arch/powerpc/platforms/chrp/pci.c b/arch/powerpc/platforms/chrp/pci.c index ac224876ce59..0f4340506c75 100644 --- a/arch/powerpc/platforms/chrp/pci.c +++ b/arch/powerpc/platforms/chrp/pci.c @@ -2,7 +2,6 @@ * CHRP pci routines. */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/pci.h> #include <linux/delay.h> @@ -19,7 +18,6 @@ #include <asm/machdep.h> #include <asm/sections.h> #include <asm/pci-bridge.h> -#include <asm/open_pic.h> #include <asm/grackle.h> #include <asm/rtas.h> @@ -143,7 +141,7 @@ hydra_init(void) if (np == NULL || of_address_to_resource(np, 0, &r)) return 0; Hydra = ioremap(r.start, r.end-r.start); - printk("Hydra Mac I/O at %lx\n", r.start); + printk("Hydra Mac I/O at %llx\n", (unsigned long long)r.start); printk("Hydra Feature_Control was %x", in_le32(&Hydra->Feature_Control)); out_le32(&Hydra->Feature_Control, (HYDRA_FC_SCC_CELL_EN | @@ -162,15 +160,9 @@ void __init chrp_pcibios_fixup(void) { struct pci_dev *dev = NULL; - struct device_node *np; - /* PCI interrupts are controlled by the OpenPIC */ - for_each_pci_dev(dev) { - np = pci_device_to_OF_node(dev); - if ((np != 0) && (np->n_intrs > 0) && (np->intrs[0].line != 0)) - dev->irq = np->intrs[0].line; - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); - } + for_each_pci_dev(dev) + pci_read_irq_line(dev); } #define PRG_CL_RESET_VALID 0x00010000 @@ -222,11 +214,11 @@ void __init chrp_find_bridges(void) { struct device_node *dev; - int *bus_range; + const int *bus_range; int len, index = -1; struct pci_controller *hose; - unsigned int *dma; - char *model, *machine; + const unsigned int *dma; + const char *model, *machine; int is_longtrail = 0, is_mot = 0, is_pegasos = 0; struct device_node *root = find_path_device("/"); struct resource r; @@ -254,7 +246,7 @@ chrp_find_bridges(void) dev->full_name); continue; } - bus_range = (int *) get_property(dev, "bus-range", &len); + bus_range = get_property(dev, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) { printk(KERN_WARNING "Can't get bus-range for %s\n", dev->full_name); @@ -265,9 +257,9 @@ chrp_find_bridges(void) else printk(KERN_INFO "PCI buses %d..%d", bus_range[0], bus_range[1]); - printk(" controlled by %s", dev->type); + printk(" controlled by %s", dev->full_name); if (!is_longtrail) - printk(" at %lx", r.start); + printk(" at %llx", (unsigned long long)r.start); printk("\n"); hose = pcibios_alloc_controller(); @@ -297,6 +289,19 @@ chrp_find_bridges(void) setup_indirect_pci(hose, 0xfec00cf8, 0xfee00cfc); } else if (is_pegasos == 2) { setup_peg2(hose, dev); + } else if (!strncmp(model, "IBM,CPC710", 10)) { + setup_indirect_pci(hose, + r.start + 0x000f8000, + r.start + 0x000f8010); + if (index == 0) { + dma = get_property(dev, "system-dma-base",&len); + if (dma && len >= sizeof(*dma)) { + dma = (unsigned int *) + (((unsigned long)dma) + + len - sizeof(*dma)); + pci_dram_offset = *dma; + } + } } else { printk("No methods for %s (model %s), using RTAS\n", dev->full_name, model); @@ -307,15 +312,35 @@ chrp_find_bridges(void) /* check the first bridge for a property that we can use to set pci_dram_offset */ - dma = (unsigned int *) - get_property(dev, "ibm,dma-ranges", &len); + dma = get_property(dev, "ibm,dma-ranges", &len); if (index == 0 && dma != NULL && len >= 6 * sizeof(*dma)) { pci_dram_offset = dma[2] - dma[3]; printk("pci_dram_offset = %lx\n", pci_dram_offset); } } +} - /* Do not fixup interrupts from OF tree on pegasos */ - if (is_pegasos) - ppc_md.pcibios_fixup = NULL; +/* SL82C105 IDE Control/Status Register */ +#define SL82C105_IDECSR 0x40 + +/* Fixup for Winbond ATA quirk, required for briq */ +void chrp_pci_fixup_winbond_ata(struct pci_dev *sl82c105) +{ + u8 progif; + + /* If non-briq machines need that fixup too, please speak up */ + if (!machine_is(chrp) || _chrp_type != _CHRP_briq) + return; + + if ((sl82c105->class & 5) != 5) { + printk("W83C553: Switching SL82C105 IDE to PCI native mode\n"); + /* Enable SL82C105 PCI native IDE mode */ + pci_read_config_byte(sl82c105, PCI_CLASS_PROG, &progif); + pci_write_config_byte(sl82c105, PCI_CLASS_PROG, progif | 0x05); + sl82c105->class |= 0x05; + /* Disable SL82C105 second port */ + pci_write_config_word(sl82c105, SL82C105_IDECSR, 0x0003); + } } +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105, + chrp_pci_fixup_winbond_ata); diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c index 18d89f38796b..488dbd9b51ae 100644 --- a/arch/powerpc/platforms/chrp/setup.c +++ b/arch/powerpc/platforms/chrp/setup.c @@ -8,7 +8,6 @@ * bootup setup stuff.. */ -#include <linux/config.h> #include <linux/errno.h> #include <linux/sched.h> #include <linux/kernel.h> @@ -25,7 +24,7 @@ #include <linux/reboot.h> #include <linux/init.h> #include <linux/pci.h> -#include <linux/version.h> +#include <linux/utsrelease.h> #include <linux/adb.h> #include <linux/module.h> #include <linux/delay.h> @@ -60,7 +59,7 @@ void rtas_indicator_progress(char *, unsigned short); int _chrp_type; EXPORT_SYMBOL(_chrp_type); -struct mpic *chrp_mpic; +static struct mpic *chrp_mpic; /* Used for doing CHRP event-scans */ DEFINE_PER_CPU(struct timer_list, heartbeat_timer); @@ -75,6 +74,9 @@ extern irqreturn_t xmon_irq(int, void *, struct pt_regs *); extern unsigned long loops_per_jiffy; +/* To be replaced by RTAS when available */ +static unsigned int *briq_SPOR; + #ifdef CONFIG_SMP extern struct smp_ops_t chrp_smp_ops; #endif @@ -93,6 +95,15 @@ static const char *gg2_cachemodes[4] = { "Disabled", "Write-Through", "Copy-Back", "Transparent Mode" }; +static const char *chrp_names[] = { + "Unknown", + "","","", + "Motorola", + "IBM or Longtrail", + "Genesi Pegasos", + "Total Impact Briq" +}; + void chrp_show_cpuinfo(struct seq_file *m) { int i, sdramen; @@ -215,8 +226,7 @@ static void __init pegasos_set_l2cr(void) /* Enable L2 cache if needed */ np = find_type_devices("cpu"); if (np != NULL) { - unsigned int *l2cr = (unsigned int *) - get_property (np, "l2cr", NULL); + const unsigned int *l2cr = get_property(np, "l2cr", NULL); if (l2cr == NULL) { printk ("Pegasos l2cr : no cpu l2cr property found\n"); return; @@ -230,10 +240,18 @@ static void __init pegasos_set_l2cr(void) } } +static void briq_restart(char *cmd) +{ + local_irq_disable(); + if (briq_SPOR) + out_be32(briq_SPOR, 0); + for(;;); +} + void __init chrp_setup_arch(void) { struct device_node *root = find_path_device ("/"); - char *machine = NULL; + const char *machine = NULL; /* init to some ~sane value until calibrate_delay() runs */ loops_per_jiffy = 50000000/HZ; @@ -246,11 +264,16 @@ void __init chrp_setup_arch(void) _chrp_type = _CHRP_IBM; } else if (machine && strncmp(machine, "MOT", 3) == 0) { _chrp_type = _CHRP_Motorola; + } else if (machine && strncmp(machine, "TotalImpact,BRIQ-1", 18) == 0) { + _chrp_type = _CHRP_briq; + /* Map the SPOR register on briq and change the restart hook */ + briq_SPOR = (unsigned int *)ioremap(0xff0000e8, 4); + ppc_md.restart = briq_restart; } else { /* Let's assume it is an IBM chrp if all else fails */ _chrp_type = _CHRP_IBM; } - printk("chrp type = %x\n", _chrp_type); + printk("chrp type = %x [%s]\n", _chrp_type, chrp_names[_chrp_type]); rtas_initialize(); if (rtas_token("display-character") >= 0) @@ -292,10 +315,6 @@ void __init chrp_setup_arch(void) pci_create_OF_bus_map(); -#ifdef CONFIG_SMP - smp_ops = &chrp_smp_ops; -#endif /* CONFIG_SMP */ - /* * Print the banner, then scroll down so boot progress * can be printed. -- Cort @@ -316,27 +335,34 @@ chrp_event_scan(unsigned long unused) jiffies + event_scan_interval); } +static void chrp_8259_cascade(unsigned int irq, struct irq_desc *desc, + struct pt_regs *regs) +{ + unsigned int cascade_irq = i8259_irq(regs); + if (cascade_irq != NO_IRQ) + generic_handle_irq(cascade_irq, regs); + desc->chip->eoi(irq); +} + /* * Finds the open-pic node and sets up the mpic driver. */ static void __init chrp_find_openpic(void) { struct device_node *np, *root; - int len, i, j, irq_count; + int len, i, j; int isu_size, idu_size; - unsigned int *iranges, *opprop = NULL; + const unsigned int *iranges, *opprop = NULL; int oplen = 0; unsigned long opaddr; int na = 1; - unsigned char init_senses[NR_IRQS - NUM_8259_INTERRUPTS]; - np = find_type_devices("open-pic"); + np = of_find_node_by_type(NULL, "open-pic"); if (np == NULL) return; - root = find_path_device("/"); + root = of_find_node_by_path("/"); if (root) { - opprop = (unsigned int *) get_property - (root, "platform-open-pic", &oplen); + opprop = get_property(root, "platform-open-pic", &oplen); na = prom_n_addr_cells(root); } if (opprop && oplen >= na * sizeof(unsigned int)) { @@ -344,20 +370,16 @@ static void __init chrp_find_openpic(void) oplen /= na * sizeof(unsigned int); } else { struct resource r; - if (of_address_to_resource(np, 0, &r)) - return; + if (of_address_to_resource(np, 0, &r)) { + goto bail; + } opaddr = r.start; oplen = 0; } printk(KERN_INFO "OpenPIC at %lx\n", opaddr); - irq_count = NR_IRQS - NUM_ISA_INTERRUPTS - 4; /* leave room for IPIs */ - prom_get_irq_senses(init_senses, NUM_ISA_INTERRUPTS, NR_IRQS - 4); - /* i8259 cascade is always positive level */ - init_senses[0] = IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE; - - iranges = (unsigned int *) get_property(np, "interrupt-ranges", &len); + iranges = get_property(np, "interrupt-ranges", &len); if (iranges == NULL) len = 0; /* non-distributed mpic */ else @@ -383,15 +405,12 @@ static void __init chrp_find_openpic(void) if (len > 1) isu_size = iranges[3]; - chrp_mpic = mpic_alloc(opaddr, MPIC_PRIMARY, - isu_size, NUM_ISA_INTERRUPTS, irq_count, - NR_IRQS - 4, init_senses, irq_count, - " MPIC "); + chrp_mpic = mpic_alloc(np, opaddr, MPIC_PRIMARY, + isu_size, 0, " MPIC "); if (chrp_mpic == NULL) { printk(KERN_ERR "Failed to allocate MPIC structure\n"); - return; + goto bail; } - j = na - 1; for (i = 1; i < len; ++i) { iranges += 2; @@ -403,7 +422,10 @@ static void __init chrp_find_openpic(void) } mpic_init(chrp_mpic); - mpic_setup_cascade(NUM_ISA_INTERRUPTS, i8259_irq_cascade, NULL); + ppc_md.get_irq = mpic_get_irq; + bail: + of_node_put(root); + of_node_put(np); } #if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON) @@ -414,17 +436,37 @@ static struct irqaction xmon_irqaction = { }; #endif -void __init chrp_init_IRQ(void) +static void __init chrp_find_8259(void) { - struct device_node *np; + struct device_node *np, *pic = NULL; unsigned long chrp_int_ack = 0; -#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON) - struct device_node *kbd; -#endif + unsigned int cascade_irq; + + /* Look for cascade */ + for_each_node_by_type(np, "interrupt-controller") + if (device_is_compatible(np, "chrp,iic")) { + pic = np; + break; + } + /* Ok, 8259 wasn't found. We need to handle the case where + * we have a pegasos that claims to be chrp but doesn't have + * a proper interrupt tree + */ + if (pic == NULL && chrp_mpic != NULL) { + printk(KERN_ERR "i8259: Not found in device-tree" + " assuming no legacy interrupts\n"); + return; + } + /* Look for intack. In a perfect world, we would look for it on + * the ISA bus that holds the 8259 but heh... Works that way. If + * we ever see a problem, we can try to re-use the pSeries code here. + * Also, Pegasos-type platforms don't have a proper node to start + * from anyway + */ for (np = find_devices("pci"); np != NULL; np = np->next) { - unsigned int *addrp = (unsigned int *) - get_property(np, "8259-interrupt-acknowledge", NULL); + const unsigned int *addrp = get_property(np, + "8259-interrupt-acknowledge", NULL); if (addrp == NULL) continue; @@ -432,11 +474,37 @@ void __init chrp_init_IRQ(void) break; } if (np == NULL) - printk(KERN_ERR "Cannot find PCI interrupt acknowledge address\n"); + printk(KERN_WARNING "Cannot find PCI interrupt acknowledge" + " address, polling\n"); + + i8259_init(pic, chrp_int_ack); + if (ppc_md.get_irq == NULL) + ppc_md.get_irq = i8259_irq; + if (chrp_mpic != NULL) { + cascade_irq = irq_of_parse_and_map(pic, 0); + if (cascade_irq == NO_IRQ) + printk(KERN_ERR "i8259: failed to map cascade irq\n"); + else + set_irq_chained_handler(cascade_irq, + chrp_8259_cascade); + } +} +void __init chrp_init_IRQ(void) +{ +#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON) + struct device_node *kbd; +#endif chrp_find_openpic(); + chrp_find_8259(); - i8259_init(chrp_int_ack, 0); +#ifdef CONFIG_SMP + /* Pegasos has no MPIC, those ops would make it crash. It might be an + * option to move setting them to after we probe the PIC though + */ + if (chrp_mpic != NULL) + smp_ops = &chrp_smp_ops; +#endif /* CONFIG_SMP */ if (_chrp_type == _CHRP_Pegasos) ppc_md.get_irq = i8259_irq; @@ -457,7 +525,7 @@ void __init chrp_init2(void) { struct device_node *device; - unsigned int *p = NULL; + const unsigned int *p = NULL; #ifdef CONFIG_NVRAM chrp_nvram_init(); @@ -475,8 +543,7 @@ chrp_init2(void) */ device = find_devices("rtas"); if (device) - p = (unsigned int *) get_property - (device, "rtas-event-scan-rate", NULL); + p = get_property(device, "rtas-event-scan-rate", NULL); if (p && *p) { /* * Arrange to call chrp_event_scan at least *p times @@ -521,10 +588,6 @@ static int __init chrp_probe(void) DMA_MODE_READ = 0x44; DMA_MODE_WRITE = 0x48; isa_io_base = CHRP_ISA_IO_BASE; /* default value */ - ppc_do_canonicalize_irqs = 1; - - /* Assume we have an 8259... */ - __irq_offset_value = NUM_ISA_INTERRUPTS; return 1; } @@ -536,7 +599,6 @@ define_machine(chrp) { .init = chrp_init2, .show_cpuinfo = chrp_show_cpuinfo, .init_IRQ = chrp_init_IRQ, - .get_irq = mpic_get_irq, .pcibios_fixup = chrp_pcibios_fixup, .restart = rtas_restart, .power_off = rtas_power_off, diff --git a/arch/powerpc/platforms/chrp/smp.c b/arch/powerpc/platforms/chrp/smp.c index b616053bc331..1d2307e87c30 100644 --- a/arch/powerpc/platforms/chrp/smp.c +++ b/arch/powerpc/platforms/chrp/smp.c @@ -8,7 +8,6 @@ * */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/smp.h> @@ -30,7 +29,6 @@ #include <asm/smp.h> #include <asm/residual.h> #include <asm/time.h> -#include <asm/open_pic.h> #include <asm/machdep.h> #include <asm/smp.h> #include <asm/mpic.h> diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig b/arch/powerpc/platforms/embedded6xx/Kconfig index 4fdbc9ae876b..234a861870a8 100644 --- a/arch/powerpc/platforms/embedded6xx/Kconfig +++ b/arch/powerpc/platforms/embedded6xx/Kconfig @@ -74,6 +74,17 @@ config SANDPOINT Select SANDPOINT if configuring for a Motorola Sandpoint X3 (any flavor). +config MPC7448HPC2 + bool "Freescale MPC7448HPC2(Taiga)" + select TSI108_BRIDGE + select DEFAULT_UIMAGE + select PPC_UDBG_16550 + select MPIC + select MPIC_WEIRD + help + Select MPC7448HPC2 if configuring for Freescale MPC7448HPC2 (Taiga) + platform + config RADSTONE_PPC7D bool "Radstone Technology PPC7D board" select PPC_I8259 @@ -221,6 +232,11 @@ config MV64X60 select PPC_INDIRECT_PCI default y +config TSI108_BRIDGE + bool + depends on MPC7448HPC2 + default y + menu "Set bridge options" depends on MV64X60 diff --git a/arch/powerpc/platforms/embedded6xx/Makefile b/arch/powerpc/platforms/embedded6xx/Makefile new file mode 100644 index 000000000000..fa499fe59291 --- /dev/null +++ b/arch/powerpc/platforms/embedded6xx/Makefile @@ -0,0 +1,4 @@ +# +# Makefile for the 6xx/7xx/7xxxx linux kernel. +# +obj-$(CONFIG_MPC7448HPC2) += mpc7448_hpc2.o diff --git a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c new file mode 100644 index 000000000000..e4f2b9df5e17 --- /dev/null +++ b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c @@ -0,0 +1,310 @@ +/* + * mpc7448_hpc2.c + * + * Board setup routines for the Freescale mpc7448hpc2(taiga) platform + * + * Author: Jacob Pan + * jacob.pan@freescale.com + * Author: Xianghua Xiao + * x.xiao@freescale.com + * Maintainer: Roy Zang <tie-fei.zang@freescale.com> + * Add Flat Device Tree support fot mpc7448hpc2 board + * + * Copyright 2004-2006 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include <linux/config.h> +#include <linux/stddef.h> +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/kdev_t.h> +#include <linux/console.h> +#include <linux/delay.h> +#include <linux/irq.h> +#include <linux/ide.h> +#include <linux/seq_file.h> +#include <linux/root_dev.h> +#include <linux/serial.h> +#include <linux/tty.h> +#include <linux/serial_core.h> + +#include <asm/system.h> +#include <asm/time.h> +#include <asm/machdep.h> +#include <asm/prom.h> +#include <asm/udbg.h> +#include <asm/tsi108.h> +#include <asm/pci-bridge.h> +#include <asm/reg.h> +#include <mm/mmu_decl.h> +#include "mpc7448_hpc2.h" +#include <asm/tsi108_irq.h> +#include <asm/mpic.h> + +#undef DEBUG +#ifdef DEBUG +#define DBG(fmt...) do { printk(fmt); } while(0) +#else +#define DBG(fmt...) do { } while(0) +#endif + +#ifndef CONFIG_PCI +isa_io_base = MPC7448_HPC2_ISA_IO_BASE; +isa_mem_base = MPC7448_HPC2_ISA_MEM_BASE; +pci_dram_offset = MPC7448_HPC2_PCI_MEM_OFFSET; +#endif + +extern int tsi108_setup_pci(struct device_node *dev); +extern void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val); +extern void tsi108_pci_int_init(void); +extern void tsi108_irq_cascade(unsigned int irq, struct irq_desc *desc, + struct pt_regs *regs); + +int mpc7448_hpc2_exclude_device(u_char bus, u_char devfn) +{ + if (bus == 0 && PCI_SLOT(devfn) == 0) + return PCIBIOS_DEVICE_NOT_FOUND; + else + return PCIBIOS_SUCCESSFUL; +} + +/* + * find pci slot by devfn in interrupt map of OF tree + */ +u8 find_slot_by_devfn(unsigned int *interrupt_map, unsigned int devfn) +{ + int i; + unsigned int tmp; + for (i = 0; i < 4; i++){ + tmp = interrupt_map[i*4*7]; + if ((tmp >> 11) == (devfn >> 3)) + return i; + } + return i; +} + +/* + * Scans the interrupt map for pci device + */ +void mpc7448_hpc2_fixup_irq(struct pci_dev *dev) +{ + struct pci_controller *hose; + struct device_node *node; + const unsigned int *interrupt; + int busnr; + int len; + u8 slot; + u8 pin; + + /* Lookup the hose */ + busnr = dev->bus->number; + hose = pci_bus_to_hose(busnr); + if (!hose) + printk(KERN_ERR "No pci hose found\n"); + + /* Check it has an OF node associated */ + node = (struct device_node *) hose->arch_data; + if (!node) + printk(KERN_ERR "No pci node found\n"); + + interrupt = get_property(node, "interrupt-map", &len); + slot = find_slot_by_devfn(interrupt, dev->devfn); + pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); + if (pin == 0 || pin > 4) + pin = 1; + pin--; + dev->irq = interrupt[slot*4*7 + pin*7 + 5]; + DBG("TSI_PCI: dev->irq = 0x%x\n", dev->irq); +} +/* temporary pci irq map fixup*/ + +void __init mpc7448_hpc2_pcibios_fixup(void) +{ + struct pci_dev *dev = NULL; + for_each_pci_dev(dev) { + mpc7448_hpc2_fixup_irq(dev); + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + } +} + +static void __init mpc7448_hpc2_setup_arch(void) +{ + struct device_node *cpu; + struct device_node *np; + if (ppc_md.progress) + ppc_md.progress("mpc7448_hpc2_setup_arch():set_bridge", 0); + + cpu = of_find_node_by_type(NULL, "cpu"); + if (cpu != 0) { + const unsigned int *fp; + + fp = get_property(cpu, "clock-frequency", NULL); + if (fp != 0) + loops_per_jiffy = *fp / HZ; + else + loops_per_jiffy = 50000000 / HZ; + of_node_put(cpu); + } + tsi108_csr_vir_base = get_vir_csrbase(); + +#ifdef CONFIG_ROOT_NFS + ROOT_DEV = Root_NFS; +#else + ROOT_DEV = Root_HDA1; +#endif + +#ifdef CONFIG_BLK_DEV_INITRD + ROOT_DEV = Root_RAM0; +#endif + + /* setup PCI host bridge */ +#ifdef CONFIG_PCI + for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) + tsi108_setup_pci(np); + + ppc_md.pci_exclude_device = mpc7448_hpc2_exclude_device; + if (ppc_md.progress) + ppc_md.progress("tsi108: resources set", 0x100); +#endif + + printk(KERN_INFO "MPC7448HPC2 (TAIGA) Platform\n"); + printk(KERN_INFO + "Jointly ported by Freescale and Tundra Semiconductor\n"); + printk(KERN_INFO + "Enabling L2 cache then enabling the HID0 prefetch engine.\n"); +} + +/* + * Interrupt setup and service. Interrrupts on the mpc7448_hpc2 come + * from the four external INT pins, PCI interrupts are routed via + * PCI interrupt control registers, it generates internal IRQ23 + * + * Interrupt routing on the Taiga Board: + * TSI108:PB_INT[0] -> CPU0:INT# + * TSI108:PB_INT[1] -> CPU0:MCP# + * TSI108:PB_INT[2] -> N/C + * TSI108:PB_INT[3] -> N/C + */ +static void __init mpc7448_hpc2_init_IRQ(void) +{ + struct mpic *mpic; + phys_addr_t mpic_paddr = 0; + unsigned int cascade_pci_irq; + struct device_node *tsi_pci; + struct device_node *tsi_pic; + + tsi_pic = of_find_node_by_type(NULL, "open-pic"); + if (tsi_pic) { + unsigned int size; + void *prop = get_property(tsi_pic, "reg", &size); + mpic_paddr = of_translate_address(tsi_pic, prop); + } + + if (mpic_paddr == 0) { + printk("%s: No tsi108 PIC found !\n", __FUNCTION__); + return; + } + + DBG("%s: tsi108pic phys_addr = 0x%x\n", __FUNCTION__, + (u32) mpic_paddr); + + mpic = mpic_alloc(tsi_pic, mpic_paddr, + MPIC_PRIMARY | MPIC_BIG_ENDIAN | MPIC_WANTS_RESET | + MPIC_SPV_EOI | MPIC_NO_PTHROU_DIS | MPIC_REGSET_TSI108, + 0, /* num_sources used */ + 0, /* num_sources used */ + "Tsi108_PIC"); + + BUG_ON(mpic == NULL); /* XXXX */ + mpic_init(mpic); + + tsi_pci = of_find_node_by_type(NULL, "pci"); + if (tsi_pci == 0) { + printk("%s: No tsi108 pci node found !\n", __FUNCTION__); + return; + } + + cascade_pci_irq = irq_of_parse_and_map(tsi_pci, 0); + set_irq_data(cascade_pci_irq, mpic); + set_irq_chained_handler(cascade_pci_irq, tsi108_irq_cascade); + + tsi108_pci_int_init(); + + /* Configure MPIC outputs to CPU0 */ + tsi108_write_reg(TSI108_MPIC_OFFSET + 0x30c, 0); + of_node_put(tsi_pic); +} + +void mpc7448_hpc2_show_cpuinfo(struct seq_file *m) +{ + seq_printf(m, "vendor\t\t: Freescale Semiconductor\n"); + seq_printf(m, "machine\t\t: MPC7448hpc2\n"); +} + +void mpc7448_hpc2_restart(char *cmd) +{ + local_irq_disable(); + + /* Set exception prefix high - to the firmware */ + _nmask_and_or_msr(0, MSR_IP); + + for (;;) ; /* Spin until reset happens */ +} + +void mpc7448_hpc2_power_off(void) +{ + local_irq_disable(); + for (;;) ; /* No way to shut power off with software */ +} + +void mpc7448_hpc2_halt(void) +{ + mpc7448_hpc2_power_off(); +} + +/* + * Called very early, device-tree isn't unflattened + */ +static int __init mpc7448_hpc2_probe(void) +{ + unsigned long root = of_get_flat_dt_root(); + + if (!of_flat_dt_is_compatible(root, "mpc74xx")) + return 0; + return 1; +} + +static int mpc7448_machine_check_exception(struct pt_regs *regs) +{ + extern void tsi108_clear_pci_cfg_error(void); + const struct exception_table_entry *entry; + + /* Are we prepared to handle this fault */ + if ((entry = search_exception_tables(regs->nip)) != NULL) { + tsi108_clear_pci_cfg_error(); + regs->msr |= MSR_RI; + regs->nip = entry->fixup; + return 1; + } + return 0; + +} + +define_machine(mpc7448_hpc2){ + .name = "MPC7448 HPC2", + .probe = mpc7448_hpc2_probe, + .setup_arch = mpc7448_hpc2_setup_arch, + .init_IRQ = mpc7448_hpc2_init_IRQ, + .show_cpuinfo = mpc7448_hpc2_show_cpuinfo, + .get_irq = mpic_get_irq, + .pcibios_fixup = mpc7448_hpc2_pcibios_fixup, + .restart = mpc7448_hpc2_restart, + .calibrate_decr = generic_calibrate_decr, + .machine_check_exception= mpc7448_machine_check_exception, + .progress = udbg_progress, +}; diff --git a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.h b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.h new file mode 100644 index 000000000000..a543a5242e34 --- /dev/null +++ b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.h @@ -0,0 +1,26 @@ +/* + * mpc7448_hpc2.h + * + * Definitions for Freescale MPC7448_HPC2 platform + * + * Author: Jacob Pan + * jacob.pan@freescale.com + * Maintainer: Roy Zang <roy.zang@freescale.com> + * + * 2006 (c) Freescale Semiconductor, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ + +#ifndef __PPC_PLATFORMS_MPC7448_HPC2_H +#define __PPC_PLATFORMS_MPC7448_HPC2_H + +#include <asm/ppcboot.h> + +/* Base Addresses for the PCI bus + */ +#define MPC7448_HPC2_PCI_MEM_OFFSET (0x00000000) +#define MPC7448_HPC2_ISA_IO_BASE (0x00000000) +#define MPC7448_HPC2_ISA_MEM_BASE (0x00000000) +#endif /* __PPC_PLATFORMS_MPC7448_HPC2_H */ diff --git a/arch/powerpc/platforms/iseries/Kconfig b/arch/powerpc/platforms/iseries/Kconfig index 3d957a30c8c2..887b68804e6d 100644 --- a/arch/powerpc/platforms/iseries/Kconfig +++ b/arch/powerpc/platforms/iseries/Kconfig @@ -3,13 +3,17 @@ menu "iSeries device drivers" depends on PPC_ISERIES config VIOCONS - tristate "iSeries Virtual Console Support" + tristate "iSeries Virtual Console Support (Obsolete)" + help + This is the old virtual console driver for legacy iSeries. + You should use the iSeries Hypervisor Virtual Console + support instead. config VIODASD tristate "iSeries Virtual I/O disk support" help If you are running on an iSeries system and you want to use - virtual disks created and managed by OS/400, say Y. + virtual disks created and managed by OS/400, say Y. config VIOCD tristate "iSeries Virtual I/O CD support" diff --git a/arch/powerpc/platforms/iseries/dt.c b/arch/powerpc/platforms/iseries/dt.c index d3444aabe76e..e305deee7f44 100644 --- a/arch/powerpc/platforms/iseries/dt.c +++ b/arch/powerpc/platforms/iseries/dt.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2005-2006 Michael Ellerman, IBM Corporation + * Copyright (C) 2005-2006 Michael Ellerman, IBM Corporation + * Copyright (C) 2000-2004, IBM Corporation * * Description: * This file contains all the routines to build a flattened device @@ -33,13 +34,13 @@ #include <asm/iseries/hv_types.h> #include <asm/iseries/hv_lp_config.h> #include <asm/iseries/hv_call_xm.h> -#include <asm/iseries/it_exp_vpd_panel.h> #include <asm/udbg.h> #include "processor_vpd.h" #include "call_hpt.h" #include "call_pci.h" #include "pci.h" +#include "it_exp_vpd_panel.h" #ifdef DEBUG #define DBG(fmt...) udbg_printf(fmt) @@ -76,6 +77,43 @@ static char __initdata device_type_pci[] = "pci"; static char __initdata device_type_vdevice[] = "vdevice"; static char __initdata device_type_vscsi[] = "vscsi"; + +/* EBCDIC to ASCII conversion routines */ + +static unsigned char __init e2a(unsigned char x) +{ + switch (x) { + case 0x81 ... 0x89: + return x - 0x81 + 'a'; + case 0x91 ... 0x99: + return x - 0x91 + 'j'; + case 0xA2 ... 0xA9: + return x - 0xA2 + 's'; + case 0xC1 ... 0xC9: + return x - 0xC1 + 'A'; + case 0xD1 ... 0xD9: + return x - 0xD1 + 'J'; + case 0xE2 ... 0xE9: + return x - 0xE2 + 'S'; + case 0xF0 ... 0xF9: + return x - 0xF0 + '0'; + } + return ' '; +} + +static unsigned char * __init strne2a(unsigned char *dest, + const unsigned char *src, size_t n) +{ + int i; + + n = strnlen(src, n); + + for (i = 0; i < n; i++) + dest[i] = e2a(src[i]); + + return dest; +} + static struct iseries_flat_dt * __init dt_init(void) { struct iseries_flat_dt *dt; @@ -252,6 +290,7 @@ static void __init dt_model(struct iseries_flat_dt *dt) { char buf[16] = "IBM,"; + /* N.B. lparcfg.c knows about the "IBM," prefixes ... */ /* "IBM," + mfgId[2:3] + systemSerial[1:5] */ strne2a(buf + 4, xItExtVpdPanel.mfgID + 2, 2); strne2a(buf + 6, xItExtVpdPanel.systemSerial + 1, 5); @@ -264,6 +303,7 @@ static void __init dt_model(struct iseries_flat_dt *dt) dt_prop_str(dt, "model", buf); dt_prop_str(dt, "compatible", "IBM,iSeries"); + dt_prop_u32(dt, "ibm,partition-no", HvLpConfig_getLpIndex()); } static void __init dt_do_vdevice(struct iseries_flat_dt *dt, @@ -296,7 +336,8 @@ static void __init dt_vdevices(struct iseries_flat_dt *dt) dt_prop_u32(dt, "#address-cells", 1); dt_prop_u32(dt, "#size-cells", 0); - dt_do_vdevice(dt, "vty", reg, -1, device_type_serial, NULL, 1); + dt_do_vdevice(dt, "vty", reg, -1, device_type_serial, + "IBM,iSeries-vty", 1); reg++; dt_do_vdevice(dt, "v-scsi", reg, -1, device_type_vscsi, diff --git a/arch/powerpc/platforms/iseries/htab.c b/arch/powerpc/platforms/iseries/htab.c index 30bdcf3925d9..ed44dfceaa45 100644 --- a/arch/powerpc/platforms/iseries/htab.c +++ b/arch/powerpc/platforms/iseries/htab.c @@ -242,13 +242,11 @@ static void iSeries_hpte_invalidate(unsigned long slot, unsigned long va, local_irq_restore(flags); } -void hpte_init_iSeries(void) +void __init hpte_init_iSeries(void) { ppc_md.hpte_invalidate = iSeries_hpte_invalidate; ppc_md.hpte_updatepp = iSeries_hpte_updatepp; ppc_md.hpte_updateboltedpp = iSeries_hpte_updateboltedpp; ppc_md.hpte_insert = iSeries_hpte_insert; ppc_md.hpte_remove = iSeries_hpte_remove; - - htab_finish_init(); } diff --git a/arch/powerpc/platforms/iseries/hvlpconfig.c b/arch/powerpc/platforms/iseries/hvlpconfig.c index 663a1affb4bb..f0475f0b1853 100644 --- a/arch/powerpc/platforms/iseries/hvlpconfig.c +++ b/arch/powerpc/platforms/iseries/hvlpconfig.c @@ -18,9 +18,22 @@ #include <linux/module.h> #include <asm/iseries/hv_lp_config.h> +#include "it_lp_naca.h" HvLpIndex HvLpConfig_getLpIndex_outline(void) { return HvLpConfig_getLpIndex(); } EXPORT_SYMBOL(HvLpConfig_getLpIndex_outline); + +HvLpIndex HvLpConfig_getLpIndex(void) +{ + return itLpNaca.xLpIndex; +} +EXPORT_SYMBOL(HvLpConfig_getLpIndex); + +HvLpIndex HvLpConfig_getPrimaryLpIndex(void) +{ + return itLpNaca.xPrimaryLpIndex; +} +EXPORT_SYMBOL_GPL(HvLpConfig_getPrimaryLpIndex); diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c index e3bd2015f2c9..f4cbbcf8773a 100644 --- a/arch/powerpc/platforms/iseries/iommu.c +++ b/arch/powerpc/platforms/iseries/iommu.c @@ -88,6 +88,23 @@ static void tce_free_iSeries(struct iommu_table *tbl, long index, long npages) } /* + * Structure passed to HvCallXm_getTceTableParms + */ +struct iommu_table_cb { + unsigned long itc_busno; /* Bus number for this tce table */ + unsigned long itc_start; /* Will be NULL for secondary */ + unsigned long itc_totalsize; /* Size (in pages) of whole table */ + unsigned long itc_offset; /* Index into real tce table of the + start of our section */ + unsigned long itc_size; /* Size (in pages) of our section */ + unsigned long itc_index; /* Index of this tce table */ + unsigned short itc_maxtables; /* Max num of tables for partition */ + unsigned char itc_virtbus; /* Flag to indicate virtual bus */ + unsigned char itc_slotno; /* IOA Tce Slot Index */ + unsigned char itc_rsvd[4]; +}; + +/* * Call Hv with the architected data structure to get TCE table info. * info. Put the returned data into the Linux representation of the * TCE table data. @@ -162,7 +179,7 @@ void iommu_devnode_init_iSeries(struct device_node *dn) { struct iommu_table *tbl; struct pci_dn *pdn = PCI_DN(dn); - u32 *lsn = (u32 *)get_property(dn, "linux,logical-slot-number", NULL); + const u32 *lsn = get_property(dn, "linux,logical-slot-number", NULL); BUG_ON(lsn == NULL); diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c index 62bbbcf5ded3..e32446877e78 100644 --- a/arch/powerpc/platforms/iseries/irq.c +++ b/arch/powerpc/platforms/iseries/irq.c @@ -23,7 +23,6 @@ * Created, December 13, 2000 by Wayne Holm * End Change Activity */ -#include <linux/config.h> #include <linux/pci.h> #include <linux/init.h> #include <linux/threads.h> @@ -163,27 +162,6 @@ static void pci_event_handler(struct HvLpEvent *event, struct pt_regs *regs) printk(KERN_ERR "pci_event_handler: NULL event received\n"); } -/* - * This is called by init_IRQ. set in ppc_md.init_IRQ by iSeries_setup.c - * It must be called before the bus walk. - */ -void __init iSeries_init_IRQ(void) -{ - /* Register PCI event handler and open an event path */ - int ret; - - ret = HvLpEvent_registerHandler(HvLpEvent_Type_PciIo, - &pci_event_handler); - if (ret == 0) { - ret = HvLpEvent_openPath(HvLpEvent_Type_PciIo, 0); - if (ret != 0) - printk(KERN_ERR "iseries_init_IRQ: open event path " - "failed with rc 0x%x\n", ret); - } else - printk(KERN_ERR "iseries_init_IRQ: register handler " - "failed with rc 0x%x\n", ret); -} - #define REAL_IRQ_TO_SUBBUS(irq) (((irq) >> 14) & 0xff) #define REAL_IRQ_TO_BUS(irq) ((((irq) >> 6) & 0xff) + 1) #define REAL_IRQ_TO_IDSEL(irq) ((((irq) >> 3) & 7) + 1) @@ -197,7 +175,7 @@ static void iseries_enable_IRQ(unsigned int irq) { u32 bus, dev_id, function, mask; const u32 sub_bus = 0; - unsigned int rirq = virt_irq_to_real_map[irq]; + unsigned int rirq = (unsigned int)irq_map[irq].hwirq; /* The IRQ has already been locked by the caller */ bus = REAL_IRQ_TO_BUS(rirq); @@ -214,7 +192,7 @@ static unsigned int iseries_startup_IRQ(unsigned int irq) { u32 bus, dev_id, function, mask; const u32 sub_bus = 0; - unsigned int rirq = virt_irq_to_real_map[irq]; + unsigned int rirq = (unsigned int)irq_map[irq].hwirq; bus = REAL_IRQ_TO_BUS(rirq); function = REAL_IRQ_TO_FUNC(rirq); @@ -242,9 +220,9 @@ void __init iSeries_activate_IRQs() for_each_irq (irq) { irq_desc_t *desc = get_irq_desc(irq); - if (desc && desc->handler && desc->handler->startup) { + if (desc && desc->chip && desc->chip->startup) { spin_lock_irqsave(&desc->lock, flags); - desc->handler->startup(irq); + desc->chip->startup(irq); spin_unlock_irqrestore(&desc->lock, flags); } } @@ -255,7 +233,7 @@ static void iseries_shutdown_IRQ(unsigned int irq) { u32 bus, dev_id, function, mask; const u32 sub_bus = 0; - unsigned int rirq = virt_irq_to_real_map[irq]; + unsigned int rirq = (unsigned int)irq_map[irq].hwirq; /* irq should be locked by the caller */ bus = REAL_IRQ_TO_BUS(rirq); @@ -278,7 +256,7 @@ static void iseries_disable_IRQ(unsigned int irq) { u32 bus, dev_id, function, mask; const u32 sub_bus = 0; - unsigned int rirq = virt_irq_to_real_map[irq]; + unsigned int rirq = (unsigned int)irq_map[irq].hwirq; /* The IRQ has already been locked by the caller */ bus = REAL_IRQ_TO_BUS(rirq); @@ -292,19 +270,19 @@ static void iseries_disable_IRQ(unsigned int irq) static void iseries_end_IRQ(unsigned int irq) { - unsigned int rirq = virt_irq_to_real_map[irq]; + unsigned int rirq = (unsigned int)irq_map[irq].hwirq; HvCallPci_eoi(REAL_IRQ_TO_BUS(rirq), REAL_IRQ_TO_SUBBUS(rirq), (REAL_IRQ_TO_IDSEL(rirq) << 4) + REAL_IRQ_TO_FUNC(rirq)); } -static hw_irq_controller iSeries_IRQ_handler = { - .typename = "iSeries irq controller", - .startup = iseries_startup_IRQ, - .shutdown = iseries_shutdown_IRQ, - .enable = iseries_enable_IRQ, - .disable = iseries_disable_IRQ, - .end = iseries_end_IRQ +static struct irq_chip iseries_pic = { + .typename = "iSeries irq controller", + .startup = iseries_startup_IRQ, + .shutdown = iseries_shutdown_IRQ, + .unmask = iseries_enable_IRQ, + .mask = iseries_disable_IRQ, + .eoi = iseries_end_IRQ }; /* @@ -315,17 +293,14 @@ static hw_irq_controller iSeries_IRQ_handler = { int __init iSeries_allocate_IRQ(HvBusNumber bus, HvSubBusNumber sub_bus, u32 bsubbus) { - int virtirq; unsigned int realirq; u8 idsel = ISERIES_GET_DEVICE_FROM_SUBBUS(bsubbus); u8 function = ISERIES_GET_FUNCTION_FROM_SUBBUS(bsubbus); realirq = (((((sub_bus << 8) + (bus - 1)) << 3) + (idsel - 1)) << 3) + function; - virtirq = virt_irq_create_mapping(realirq); - irq_desc[virtirq].handler = &iSeries_IRQ_handler; - return virtirq; + return irq_create_mapping(NULL, realirq); } #endif /* CONFIG_PCI */ @@ -333,10 +308,9 @@ int __init iSeries_allocate_IRQ(HvBusNumber bus, /* * Get the next pending IRQ. */ -int iSeries_get_irq(struct pt_regs *regs) +unsigned int iSeries_get_irq(struct pt_regs *regs) { - /* -2 means ignore this interrupt */ - int irq = -2; + int irq = NO_IRQ_IGNORE; #ifdef CONFIG_SMP if (get_lppaca()->int_dword.fields.ipi_cnt) { @@ -359,9 +333,57 @@ int iSeries_get_irq(struct pt_regs *regs) } spin_unlock(&pending_irqs_lock); if (irq >= NR_IRQS) - irq = -2; + irq = NO_IRQ_IGNORE; } #endif return irq; } + +static int iseries_irq_host_map(struct irq_host *h, unsigned int virq, + irq_hw_number_t hw) +{ + set_irq_chip_and_handler(virq, &iseries_pic, handle_fasteoi_irq); + + return 0; +} + +static struct irq_host_ops iseries_irq_host_ops = { + .map = iseries_irq_host_map, +}; + +/* + * This is called by init_IRQ. set in ppc_md.init_IRQ by iSeries_setup.c + * It must be called before the bus walk. + */ +void __init iSeries_init_IRQ(void) +{ + /* Register PCI event handler and open an event path */ + struct irq_host *host; + int ret; + + /* + * The Hypervisor only allows us up to 256 interrupt + * sources (the irq number is passed in a u8). + */ + irq_set_virq_count(256); + + /* Create irq host. No need for a revmap since HV will give us + * back our virtual irq number + */ + host = irq_alloc_host(IRQ_HOST_MAP_NOMAP, 0, &iseries_irq_host_ops, 0); + BUG_ON(host == NULL); + irq_set_default_host(host); + + ret = HvLpEvent_registerHandler(HvLpEvent_Type_PciIo, + &pci_event_handler); + if (ret == 0) { + ret = HvLpEvent_openPath(HvLpEvent_Type_PciIo, 0); + if (ret != 0) + printk(KERN_ERR "iseries_init_IRQ: open event path " + "failed with rc 0x%x\n", ret); + } else + printk(KERN_ERR "iseries_init_IRQ: register handler " + "failed with rc 0x%x\n", ret); +} + diff --git a/arch/powerpc/platforms/iseries/irq.h b/arch/powerpc/platforms/iseries/irq.h index 188aa808abd7..1ee8985140e5 100644 --- a/arch/powerpc/platforms/iseries/irq.h +++ b/arch/powerpc/platforms/iseries/irq.h @@ -4,6 +4,6 @@ extern void iSeries_init_IRQ(void); extern int iSeries_allocate_IRQ(HvBusNumber, HvSubBusNumber, u32); extern void iSeries_activate_IRQs(void); -extern int iSeries_get_irq(struct pt_regs *); +extern unsigned int iSeries_get_irq(struct pt_regs *); #endif /* _ISERIES_IRQ_H */ diff --git a/arch/powerpc/platforms/iseries/it_exp_vpd_panel.h b/arch/powerpc/platforms/iseries/it_exp_vpd_panel.h new file mode 100644 index 000000000000..6de9097b7f57 --- /dev/null +++ b/arch/powerpc/platforms/iseries/it_exp_vpd_panel.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2002 Dave Boutcher IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef _PLATFORMS_ISERIES_IT_EXT_VPD_PANEL_H +#define _PLATFORMS_ISERIES_IT_EXT_VPD_PANEL_H + +/* + * This struct maps the panel information + * + * Warning: + * This data must match the architecture for the panel information + */ + +#include <asm/types.h> + +struct ItExtVpdPanel { + /* Definition of the Extended Vpd On Panel Data Area */ + char systemSerial[8]; + char mfgID[4]; + char reserved1[24]; + char machineType[4]; + char systemID[6]; + char somUniqueCnt[4]; + char serialNumberCount; + char reserved2[7]; + u16 bbu3; + u16 bbu2; + u16 bbu1; + char xLocationLabel[8]; + u8 xRsvd1[6]; + u16 xFrameId; + u8 xRsvd2[48]; +}; + +extern struct ItExtVpdPanel xItExtVpdPanel; + +#endif /* _PLATFORMS_ISERIES_IT_EXT_VPD_PANEL_H */ diff --git a/arch/powerpc/platforms/iseries/it_lp_naca.h b/arch/powerpc/platforms/iseries/it_lp_naca.h new file mode 100644 index 000000000000..9bbf58986819 --- /dev/null +++ b/arch/powerpc/platforms/iseries/it_lp_naca.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2001 Mike Corrigan IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef _PLATFORMS_ISERIES_IT_LP_NACA_H +#define _PLATFORMS_ISERIES_IT_LP_NACA_H + +#include <linux/types.h> + +/* + * This control block contains the data that is shared between the + * hypervisor (PLIC) and the OS. + */ + +struct ItLpNaca { +// CACHE_LINE_1 0x0000 - 0x007F Contains read-only data + u32 xDesc; // Eye catcher x00-x03 + u16 xSize; // Size of this class x04-x05 + u16 xIntHdlrOffset; // Offset to IntHdlr array x06-x07 + u8 xMaxIntHdlrEntries; // Number of entries in array x08-x08 + u8 xPrimaryLpIndex; // LP Index of Primary x09-x09 + u8 xServiceLpIndex; // LP Ind of Service Focal Pointx0A-x0A + u8 xLpIndex; // LP Index x0B-x0B + u16 xMaxLpQueues; // Number of allocated queues x0C-x0D + u16 xLpQueueOffset; // Offset to start of LP queues x0E-x0F + u8 xPirEnvironMode; // Piranha or hardware x10-x10 + u8 xPirConsoleMode; // Piranha console indicator x11-x11 + u8 xPirDasdMode; // Piranha dasd indicator x12-x12 + u8 xRsvd1_0[5]; // Reserved for Piranha related x13-x17 + u8 flags; // flags, see below x18-x1F + u8 xSpVpdFormat; // VPD areas are in CSP format ... + u8 xIntProcRatio; // Ratio of int procs to procs ... + u8 xRsvd1_2[5]; // Reserved ... + u16 xRsvd1_3; // Reserved x20-x21 + u16 xPlicVrmIndex; // VRM index of PLIC x22-x23 + u16 xMinSupportedSlicVrmInd;// Min supported OS VRM index x24-x25 + u16 xMinCompatableSlicVrmInd;// Min compatible OS VRM index x26-x27 + u64 xLoadAreaAddr; // ER address of load area x28-x2F + u32 xLoadAreaChunks; // Chunks for the load area x30-x33 + u32 xPaseSysCallCRMask; // Mask used to test CR before x34-x37 + // doing an ASR switch on PASE + // system call. + u64 xSlicSegmentTablePtr; // Pointer to Slic seg table. x38-x3f + u8 xRsvd1_4[64]; // x40-x7F + +// CACHE_LINE_2 0x0080 - 0x00FF Contains local read-write data + u8 xRsvd2_0[128]; // Reserved x00-x7F + +// CACHE_LINE_3-6 0x0100 - 0x02FF Contains LP Queue indicators +// NB: Padding required to keep xInterrruptHdlr at x300 which is required +// for v4r4 PLIC. + u8 xOldLpQueue[128]; // LP Queue needed for v4r4 100-17F + u8 xRsvd3_0[384]; // Reserved 180-2FF + +// CACHE_LINE_7-8 0x0300 - 0x03FF Contains the address of the OS interrupt +// handlers + u64 xInterruptHdlr[32]; // Interrupt handlers 300-x3FF +}; + +extern struct ItLpNaca itLpNaca; + +#define ITLPNACA_LPAR 0x80 /* Is LPAR installed on the system */ +#define ITLPNACA_PARTITIONED 0x40 /* Is the system partitioned */ +#define ITLPNACA_HWSYNCEDTBS 0x20 /* Hardware synced TBs */ +#define ITLPNACA_HMTINT 0x10 /* Utilize MHT for interrupts */ + +#endif /* _PLATFORMS_ISERIES_IT_LP_NACA_H */ diff --git a/arch/powerpc/platforms/iseries/lpardata.c b/arch/powerpc/platforms/iseries/lpardata.c index 438e2dba63b5..8162049bb04d 100644 --- a/arch/powerpc/platforms/iseries/lpardata.c +++ b/arch/powerpc/platforms/iseries/lpardata.c @@ -6,7 +6,6 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <linux/types.h> #include <linux/threads.h> #include <linux/module.h> @@ -14,12 +13,10 @@ #include <asm/processor.h> #include <asm/ptrace.h> #include <asm/abs_addr.h> -#include <asm/iseries/it_lp_naca.h> #include <asm/lppaca.h> #include <asm/iseries/it_lp_reg_save.h> #include <asm/paca.h> #include <asm/iseries/lpar_map.h> -#include <asm/iseries/it_exp_vpd_panel.h> #include <asm/iseries/it_lp_queue.h> #include "naca.h" @@ -28,6 +25,8 @@ #include "ipl_parms.h" #include "processor_vpd.h" #include "release_data.h" +#include "it_exp_vpd_panel.h" +#include "it_lp_naca.h" /* The HvReleaseData is the root of the information shared between * the hypervisor and Linux. @@ -128,14 +127,12 @@ struct ItLpNaca itLpNaca = { (u64)instruction_access_slb_iSeries /* 0x480 I-SLB */ } }; -EXPORT_SYMBOL(itLpNaca); /* May be filled in by the hypervisor so cannot end up in the BSS */ struct ItIplParmsReal xItIplParmsReal __attribute__((__section__(".data"))); /* May be filled in by the hypervisor so cannot end up in the BSS */ struct ItExtVpdPanel xItExtVpdPanel __attribute__((__section__(".data"))); -EXPORT_SYMBOL(xItExtVpdPanel); #define maxPhysicalProcessors 32 diff --git a/arch/powerpc/platforms/iseries/lpevents.c b/arch/powerpc/platforms/iseries/lpevents.c index 8ca7b9396355..98c1c2440aad 100644 --- a/arch/powerpc/platforms/iseries/lpevents.c +++ b/arch/powerpc/platforms/iseries/lpevents.c @@ -20,7 +20,7 @@ #include <asm/iseries/it_lp_queue.h> #include <asm/iseries/hv_lp_event.h> #include <asm/iseries/hv_call_event.h> -#include <asm/iseries/it_lp_naca.h> +#include "it_lp_naca.h" /* * The LpQueue is used to pass event data from the hypervisor to @@ -51,20 +51,21 @@ static unsigned lpEventHandlerPaths[HvLpEvent_Type_NumTypes]; static struct HvLpEvent * get_next_hvlpevent(void) { struct HvLpEvent * event; - event = (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr; + event = (struct HvLpEvent *)hvlpevent_queue.hq_current_event; if (hvlpevent_is_valid(event)) { /* rmb() needed only for weakly consistent machines (regatta) */ rmb(); /* Set pointer to next potential event */ - hvlpevent_queue.xSlicCurEventPtr += ((event->xSizeMinus1 + - LpEventAlign) / LpEventAlign) * LpEventAlign; + hvlpevent_queue.hq_current_event += ((event->xSizeMinus1 + + IT_LP_EVENT_ALIGN) / IT_LP_EVENT_ALIGN) * + IT_LP_EVENT_ALIGN; /* Wrap to beginning if no room at end */ - if (hvlpevent_queue.xSlicCurEventPtr > - hvlpevent_queue.xSlicLastValidEventPtr) { - hvlpevent_queue.xSlicCurEventPtr = - hvlpevent_queue.xSlicEventStackPtr; + if (hvlpevent_queue.hq_current_event > + hvlpevent_queue.hq_last_event) { + hvlpevent_queue.hq_current_event = + hvlpevent_queue.hq_event_stack; } } else { event = NULL; @@ -82,10 +83,10 @@ int hvlpevent_is_pending(void) if (smp_processor_id() >= spread_lpevents) return 0; - next_event = (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr; + next_event = (struct HvLpEvent *)hvlpevent_queue.hq_current_event; return hvlpevent_is_valid(next_event) || - hvlpevent_queue.xPlicOverflowIntPending; + hvlpevent_queue.hq_overflow_pending; } static void hvlpevent_clear_valid(struct HvLpEvent * event) @@ -95,18 +96,18 @@ static void hvlpevent_clear_valid(struct HvLpEvent * event) * ie. on 64-byte boundaries. */ struct HvLpEvent *tmp; - unsigned extra = ((event->xSizeMinus1 + LpEventAlign) / - LpEventAlign) - 1; + unsigned extra = ((event->xSizeMinus1 + IT_LP_EVENT_ALIGN) / + IT_LP_EVENT_ALIGN) - 1; switch (extra) { case 3: - tmp = (struct HvLpEvent*)((char*)event + 3 * LpEventAlign); + tmp = (struct HvLpEvent*)((char*)event + 3 * IT_LP_EVENT_ALIGN); hvlpevent_invalidate(tmp); case 2: - tmp = (struct HvLpEvent*)((char*)event + 2 * LpEventAlign); + tmp = (struct HvLpEvent*)((char*)event + 2 * IT_LP_EVENT_ALIGN); hvlpevent_invalidate(tmp); case 1: - tmp = (struct HvLpEvent*)((char*)event + 1 * LpEventAlign); + tmp = (struct HvLpEvent*)((char*)event + 1 * IT_LP_EVENT_ALIGN); hvlpevent_invalidate(tmp); } @@ -120,7 +121,7 @@ void process_hvlpevents(struct pt_regs *regs) struct HvLpEvent * event; /* If we have recursed, just return */ - if (!spin_trylock(&hvlpevent_queue.lock)) + if (!spin_trylock(&hvlpevent_queue.hq_lock)) return; for (;;) { @@ -148,17 +149,17 @@ void process_hvlpevents(struct pt_regs *regs) printk(KERN_INFO "Unexpected Lp Event type=%d\n", event->xType ); hvlpevent_clear_valid(event); - } else if (hvlpevent_queue.xPlicOverflowIntPending) + } else if (hvlpevent_queue.hq_overflow_pending) /* * No more valid events. If overflow events are * pending process them */ - HvCallEvent_getOverflowLpEvents(hvlpevent_queue.xIndex); + HvCallEvent_getOverflowLpEvents(hvlpevent_queue.hq_index); else break; } - spin_unlock(&hvlpevent_queue.lock); + spin_unlock(&hvlpevent_queue.hq_lock); } static int set_spread_lpevents(char *str) @@ -184,20 +185,20 @@ void setup_hvlpevent_queue(void) { void *eventStack; - spin_lock_init(&hvlpevent_queue.lock); + spin_lock_init(&hvlpevent_queue.hq_lock); /* Allocate a page for the Event Stack. */ - eventStack = alloc_bootmem_pages(LpEventStackSize); - memset(eventStack, 0, LpEventStackSize); + eventStack = alloc_bootmem_pages(IT_LP_EVENT_STACK_SIZE); + memset(eventStack, 0, IT_LP_EVENT_STACK_SIZE); /* Invoke the hypervisor to initialize the event stack */ - HvCallEvent_setLpEventStack(0, eventStack, LpEventStackSize); + HvCallEvent_setLpEventStack(0, eventStack, IT_LP_EVENT_STACK_SIZE); - hvlpevent_queue.xSlicEventStackPtr = (char *)eventStack; - hvlpevent_queue.xSlicCurEventPtr = (char *)eventStack; - hvlpevent_queue.xSlicLastValidEventPtr = (char *)eventStack + - (LpEventStackSize - LpEventMaxSize); - hvlpevent_queue.xIndex = 0; + hvlpevent_queue.hq_event_stack = eventStack; + hvlpevent_queue.hq_current_event = eventStack; + hvlpevent_queue.hq_last_event = (char *)eventStack + + (IT_LP_EVENT_STACK_SIZE - IT_LP_EVENT_MAX_SIZE); + hvlpevent_queue.hq_index = 0; } /* Register a handler for an LpEvent type */ diff --git a/arch/powerpc/platforms/iseries/main_store.h b/arch/powerpc/platforms/iseries/main_store.h index 74f6889f834f..1a7a3f50e40b 100644 --- a/arch/powerpc/platforms/iseries/main_store.h +++ b/arch/powerpc/platforms/iseries/main_store.h @@ -61,9 +61,9 @@ struct IoHriMainStoreSegment4 { }; /* Main Store VPD for Power4 */ -struct IoHriMainStoreChipInfo1 { - u32 chipMfgID __attribute((packed)); - char chipECLevel[4] __attribute((packed)); +struct __attribute((packed)) IoHriMainStoreChipInfo1 { + u32 chipMfgID; + char chipECLevel[4]; }; struct IoHriMainStoreVpdIdData { @@ -73,72 +73,72 @@ struct IoHriMainStoreVpdIdData { char serialNumber[12]; }; -struct IoHriMainStoreVpdFruData { - char fruLabel[8] __attribute((packed)); - u8 numberOfSlots __attribute((packed)); - u8 pluggingType __attribute((packed)); - u16 slotMapIndex __attribute((packed)); +struct __attribute((packed)) IoHriMainStoreVpdFruData { + char fruLabel[8]; + u8 numberOfSlots; + u8 pluggingType; + u16 slotMapIndex; }; -struct IoHriMainStoreAdrRangeBlock { - void *blockStart __attribute((packed)); - void *blockEnd __attribute((packed)); - u32 blockProcChipId __attribute((packed)); +struct __attribute((packed)) IoHriMainStoreAdrRangeBlock { + void *blockStart; + void *blockEnd; + u32 blockProcChipId; }; #define MaxAreaAdrRangeBlocks 4 -struct IoHriMainStoreArea4 { - u32 msVpdFormat __attribute((packed)); - u8 containedVpdType __attribute((packed)); - u8 reserved1 __attribute((packed)); - u16 reserved2 __attribute((packed)); - - u64 msExists __attribute((packed)); - u64 msFunctional __attribute((packed)); - - u32 memorySize __attribute((packed)); - u32 procNodeId __attribute((packed)); - - u32 numAdrRangeBlocks __attribute((packed)); - struct IoHriMainStoreAdrRangeBlock xAdrRangeBlock[MaxAreaAdrRangeBlocks] __attribute((packed)); - - struct IoHriMainStoreChipInfo1 chipInfo0 __attribute((packed)); - struct IoHriMainStoreChipInfo1 chipInfo1 __attribute((packed)); - struct IoHriMainStoreChipInfo1 chipInfo2 __attribute((packed)); - struct IoHriMainStoreChipInfo1 chipInfo3 __attribute((packed)); - struct IoHriMainStoreChipInfo1 chipInfo4 __attribute((packed)); - struct IoHriMainStoreChipInfo1 chipInfo5 __attribute((packed)); - struct IoHriMainStoreChipInfo1 chipInfo6 __attribute((packed)); - struct IoHriMainStoreChipInfo1 chipInfo7 __attribute((packed)); - - void *msRamAreaArray __attribute((packed)); - u32 msRamAreaArrayNumEntries __attribute((packed)); - u32 msRamAreaArrayEntrySize __attribute((packed)); - - u32 numaDimmExists __attribute((packed)); - u32 numaDimmFunctional __attribute((packed)); - void *numaDimmArray __attribute((packed)); - u32 numaDimmArrayNumEntries __attribute((packed)); - u32 numaDimmArrayEntrySize __attribute((packed)); - - struct IoHriMainStoreVpdIdData idData __attribute((packed)); - - u64 powerData __attribute((packed)); - u64 cardAssemblyPartNum __attribute((packed)); - u64 chipSerialNum __attribute((packed)); - - u64 reserved3 __attribute((packed)); - char reserved4[16] __attribute((packed)); - - struct IoHriMainStoreVpdFruData fruData __attribute((packed)); - - u8 vpdPortNum __attribute((packed)); - u8 reserved5 __attribute((packed)); - u8 frameId __attribute((packed)); - u8 rackUnit __attribute((packed)); - char asciiKeywordVpd[256] __attribute((packed)); - u32 reserved6 __attribute((packed)); +struct __attribute((packed)) IoHriMainStoreArea4 { + u32 msVpdFormat; + u8 containedVpdType; + u8 reserved1; + u16 reserved2; + + u64 msExists; + u64 msFunctional; + + u32 memorySize; + u32 procNodeId; + + u32 numAdrRangeBlocks; + struct IoHriMainStoreAdrRangeBlock xAdrRangeBlock[MaxAreaAdrRangeBlocks]; + + struct IoHriMainStoreChipInfo1 chipInfo0; + struct IoHriMainStoreChipInfo1 chipInfo1; + struct IoHriMainStoreChipInfo1 chipInfo2; + struct IoHriMainStoreChipInfo1 chipInfo3; + struct IoHriMainStoreChipInfo1 chipInfo4; + struct IoHriMainStoreChipInfo1 chipInfo5; + struct IoHriMainStoreChipInfo1 chipInfo6; + struct IoHriMainStoreChipInfo1 chipInfo7; + + void *msRamAreaArray; + u32 msRamAreaArrayNumEntries; + u32 msRamAreaArrayEntrySize; + + u32 numaDimmExists; + u32 numaDimmFunctional; + void *numaDimmArray; + u32 numaDimmArrayNumEntries; + u32 numaDimmArrayEntrySize; + + struct IoHriMainStoreVpdIdData idData; + + u64 powerData; + u64 cardAssemblyPartNum; + u64 chipSerialNum; + + u64 reserved3; + char reserved4[16]; + + struct IoHriMainStoreVpdFruData fruData; + + u8 vpdPortNum; + u8 reserved5; + u8 frameId; + u8 rackUnit; + char asciiKeywordVpd[256]; + u32 reserved6; }; diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c index 35bcc98111f5..3eb12065df23 100644 --- a/arch/powerpc/platforms/iseries/pci.c +++ b/arch/powerpc/platforms/iseries/pci.c @@ -34,6 +34,7 @@ #include <asm/pci-bridge.h> #include <asm/iommu.h> #include <asm/abs_addr.h> +#include <asm/firmware.h> #include <asm/iseries/hv_call_xm.h> #include <asm/iseries/mf.h> @@ -176,12 +177,12 @@ void iSeries_pcibios_init(void) } while ((node = of_get_next_child(root, node)) != NULL) { HvBusNumber bus; - u32 *busp; + const u32 *busp; if ((node->type == NULL) || (strcmp(node->type, "pci") != 0)) continue; - busp = (u32 *)get_property(node, "bus-range", NULL); + busp = get_property(node, "bus-range", NULL); if (busp == NULL) continue; bus = *busp; @@ -221,10 +222,9 @@ void __init iSeries_pci_final_fixup(void) if (node != NULL) { struct pci_dn *pdn = PCI_DN(node); - u32 *agent; + const u32 *agent; - agent = (u32 *)get_property(node, "linux,agent-id", - NULL); + agent = get_property(node, "linux,agent-id", NULL); if ((pdn != NULL) && (agent != NULL)) { u8 irq = iSeries_allocate_IRQ(pdn->busno, 0, pdn->bussubno); @@ -271,46 +271,6 @@ void pcibios_fixup_resources(struct pci_dev *pdev) } /* - * I/0 Memory copy MUST use mmio commands on iSeries - * To do; For performance, include the hv call directly - */ -void iSeries_memset_io(volatile void __iomem *dest, char c, size_t Count) -{ - u8 ByteValue = c; - long NumberOfBytes = Count; - - while (NumberOfBytes > 0) { - iSeries_Write_Byte(ByteValue, dest++); - -- NumberOfBytes; - } -} -EXPORT_SYMBOL(iSeries_memset_io); - -void iSeries_memcpy_toio(volatile void __iomem *dest, void *source, size_t count) -{ - char *src = source; - long NumberOfBytes = count; - - while (NumberOfBytes > 0) { - iSeries_Write_Byte(*src++, dest++); - -- NumberOfBytes; - } -} -EXPORT_SYMBOL(iSeries_memcpy_toio); - -void iSeries_memcpy_fromio(void *dest, const volatile void __iomem *src, size_t count) -{ - char *dst = dest; - long NumberOfBytes = count; - - while (NumberOfBytes > 0) { - *dst++ = iSeries_Read_Byte(src++); - -- NumberOfBytes; - } -} -EXPORT_SYMBOL(iSeries_memcpy_fromio); - -/* * Look down the chain to find the matching Device Device */ static struct device_node *find_Device_Node(int bus, int devfn) @@ -492,7 +452,7 @@ static inline struct device_node *xlate_iomm_address( * iSeries_Read_Word = Read Word (16 bit) * iSeries_Read_Long = Read Long (32 bit) */ -u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress) +static u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress) { u64 BarOffset; u64 dsa; @@ -519,9 +479,8 @@ u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress) return (u8)ret.value; } -EXPORT_SYMBOL(iSeries_Read_Byte); -u16 iSeries_Read_Word(const volatile void __iomem *IoAddress) +static u16 iSeries_Read_Word(const volatile void __iomem *IoAddress) { u64 BarOffset; u64 dsa; @@ -549,9 +508,8 @@ u16 iSeries_Read_Word(const volatile void __iomem *IoAddress) return swab16((u16)ret.value); } -EXPORT_SYMBOL(iSeries_Read_Word); -u32 iSeries_Read_Long(const volatile void __iomem *IoAddress) +static u32 iSeries_Read_Long(const volatile void __iomem *IoAddress) { u64 BarOffset; u64 dsa; @@ -579,7 +537,6 @@ u32 iSeries_Read_Long(const volatile void __iomem *IoAddress) return swab32((u32)ret.value); } -EXPORT_SYMBOL(iSeries_Read_Long); /* * Write MM I/O Instructions for the iSeries @@ -588,7 +545,7 @@ EXPORT_SYMBOL(iSeries_Read_Long); * iSeries_Write_Word = Write Word(16 bit) * iSeries_Write_Long = Write Long(32 bit) */ -void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress) +static void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress) { u64 BarOffset; u64 dsa; @@ -613,9 +570,8 @@ void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress) rc = HvCall4(HvCallPciBarStore8, dsa, BarOffset, data, 0); } while (CheckReturnCode("WWB", DevNode, &retry, rc) != 0); } -EXPORT_SYMBOL(iSeries_Write_Byte); -void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress) +static void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress) { u64 BarOffset; u64 dsa; @@ -640,9 +596,8 @@ void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress) rc = HvCall4(HvCallPciBarStore16, dsa, BarOffset, swab16(data), 0); } while (CheckReturnCode("WWW", DevNode, &retry, rc) != 0); } -EXPORT_SYMBOL(iSeries_Write_Word); -void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress) +static void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress) { u64 BarOffset; u64 dsa; @@ -667,4 +622,224 @@ void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress) rc = HvCall4(HvCallPciBarStore32, dsa, BarOffset, swab32(data), 0); } while (CheckReturnCode("WWL", DevNode, &retry, rc) != 0); } -EXPORT_SYMBOL(iSeries_Write_Long); + +extern unsigned char __raw_readb(const volatile void __iomem *addr) +{ + BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); + + return *(volatile unsigned char __force *)addr; +} +EXPORT_SYMBOL(__raw_readb); + +extern unsigned short __raw_readw(const volatile void __iomem *addr) +{ + BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); + + return *(volatile unsigned short __force *)addr; +} +EXPORT_SYMBOL(__raw_readw); + +extern unsigned int __raw_readl(const volatile void __iomem *addr) +{ + BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); + + return *(volatile unsigned int __force *)addr; +} +EXPORT_SYMBOL(__raw_readl); + +extern unsigned long __raw_readq(const volatile void __iomem *addr) +{ + BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); + + return *(volatile unsigned long __force *)addr; +} +EXPORT_SYMBOL(__raw_readq); + +extern void __raw_writeb(unsigned char v, volatile void __iomem *addr) +{ + BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); + + *(volatile unsigned char __force *)addr = v; +} +EXPORT_SYMBOL(__raw_writeb); + +extern void __raw_writew(unsigned short v, volatile void __iomem *addr) +{ + BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); + + *(volatile unsigned short __force *)addr = v; +} +EXPORT_SYMBOL(__raw_writew); + +extern void __raw_writel(unsigned int v, volatile void __iomem *addr) +{ + BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); + + *(volatile unsigned int __force *)addr = v; +} +EXPORT_SYMBOL(__raw_writel); + +extern void __raw_writeq(unsigned long v, volatile void __iomem *addr) +{ + BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); + + *(volatile unsigned long __force *)addr = v; +} +EXPORT_SYMBOL(__raw_writeq); + +int in_8(const volatile unsigned char __iomem *addr) +{ + if (firmware_has_feature(FW_FEATURE_ISERIES)) + return iSeries_Read_Byte(addr); + return __in_8(addr); +} +EXPORT_SYMBOL(in_8); + +void out_8(volatile unsigned char __iomem *addr, int val) +{ + if (firmware_has_feature(FW_FEATURE_ISERIES)) + iSeries_Write_Byte(val, addr); + else + __out_8(addr, val); +} +EXPORT_SYMBOL(out_8); + +int in_le16(const volatile unsigned short __iomem *addr) +{ + if (firmware_has_feature(FW_FEATURE_ISERIES)) + return iSeries_Read_Word(addr); + return __in_le16(addr); +} +EXPORT_SYMBOL(in_le16); + +int in_be16(const volatile unsigned short __iomem *addr) +{ + BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); + + return __in_be16(addr); +} +EXPORT_SYMBOL(in_be16); + +void out_le16(volatile unsigned short __iomem *addr, int val) +{ + if (firmware_has_feature(FW_FEATURE_ISERIES)) + iSeries_Write_Word(val, addr); + else + __out_le16(addr, val); +} +EXPORT_SYMBOL(out_le16); + +void out_be16(volatile unsigned short __iomem *addr, int val) +{ + BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); + + __out_be16(addr, val); +} +EXPORT_SYMBOL(out_be16); + +unsigned in_le32(const volatile unsigned __iomem *addr) +{ + if (firmware_has_feature(FW_FEATURE_ISERIES)) + return iSeries_Read_Long(addr); + return __in_le32(addr); +} +EXPORT_SYMBOL(in_le32); + +unsigned in_be32(const volatile unsigned __iomem *addr) +{ + BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); + + return __in_be32(addr); +} +EXPORT_SYMBOL(in_be32); + +void out_le32(volatile unsigned __iomem *addr, int val) +{ + if (firmware_has_feature(FW_FEATURE_ISERIES)) + iSeries_Write_Long(val, addr); + else + __out_le32(addr, val); +} +EXPORT_SYMBOL(out_le32); + +void out_be32(volatile unsigned __iomem *addr, int val) +{ + BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); + + __out_be32(addr, val); +} +EXPORT_SYMBOL(out_be32); + +unsigned long in_le64(const volatile unsigned long __iomem *addr) +{ + BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); + + return __in_le64(addr); +} +EXPORT_SYMBOL(in_le64); + +unsigned long in_be64(const volatile unsigned long __iomem *addr) +{ + BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); + + return __in_be64(addr); +} +EXPORT_SYMBOL(in_be64); + +void out_le64(volatile unsigned long __iomem *addr, unsigned long val) +{ + BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); + + __out_le64(addr, val); +} +EXPORT_SYMBOL(out_le64); + +void out_be64(volatile unsigned long __iomem *addr, unsigned long val) +{ + BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); + + __out_be64(addr, val); +} +EXPORT_SYMBOL(out_be64); + +void memset_io(volatile void __iomem *addr, int c, unsigned long n) +{ + if (firmware_has_feature(FW_FEATURE_ISERIES)) { + volatile char __iomem *d = addr; + + while (n-- > 0) { + iSeries_Write_Byte(c, d++); + } + } else + eeh_memset_io(addr, c, n); +} +EXPORT_SYMBOL(memset_io); + +void memcpy_fromio(void *dest, const volatile void __iomem *src, + unsigned long n) +{ + if (firmware_has_feature(FW_FEATURE_ISERIES)) { + char *d = dest; + const volatile char __iomem *s = src; + + while (n-- > 0) { + *d++ = iSeries_Read_Byte(s++); + } + } else + eeh_memcpy_fromio(dest, src, n); +} +EXPORT_SYMBOL(memcpy_fromio); + +void memcpy_toio(volatile void __iomem *dest, const void *src, unsigned long n) +{ + if (firmware_has_feature(FW_FEATURE_ISERIES)) { + const char *s = src; + volatile char __iomem *d = dest; + + while (n-- > 0) { + iSeries_Write_Byte(*s++, d++); + } + } else + eeh_memcpy_toio(dest, src, n); +} +EXPORT_SYMBOL(memcpy_toio); diff --git a/arch/powerpc/platforms/iseries/proc.c b/arch/powerpc/platforms/iseries/proc.c index e68b6b5fa89f..c241413629ac 100644 --- a/arch/powerpc/platforms/iseries/proc.c +++ b/arch/powerpc/platforms/iseries/proc.c @@ -24,7 +24,6 @@ #include <asm/processor.h> #include <asm/time.h> #include <asm/lppaca.h> -#include <asm/iseries/it_lp_queue.h> #include <asm/iseries/hv_call_xm.h> #include "processor_vpd.h" diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c index 617c724c4590..7f1953066ff8 100644 --- a/arch/powerpc/platforms/iseries/setup.c +++ b/arch/powerpc/platforms/iseries/setup.c @@ -16,7 +16,6 @@ #undef DEBUG -#include <linux/config.h> #include <linux/init.h> #include <linux/threads.h> #include <linux/smp.h> @@ -60,6 +59,7 @@ #include "irq.h" #include "vpd_areas.h" #include "processor_vpd.h" +#include "it_lp_naca.h" #include "main_store.h" #include "call_sm.h" #include "call_hpt.h" @@ -81,8 +81,6 @@ static void iSeries_pci_final_fixup(void) { } #endif extern int rd_size; /* Defined in drivers/block/rd.c */ -extern unsigned long embedded_sysmap_start; -extern unsigned long embedded_sysmap_end; extern unsigned long iSeries_recal_tb; extern unsigned long iSeries_recal_titan; @@ -297,8 +295,6 @@ static void __init iSeries_init_early(void) { DBG(" -> iSeries_init_early()\n"); - ppc64_interrupt_controller = IC_ISERIES; - #if defined(CONFIG_BLK_DEV_INITRD) /* * If the init RAM disk has been configured and there is @@ -321,11 +317,6 @@ static void __init iSeries_init_early(void) iSeries_recal_titan = HvCallXm_loadTod(); /* - * Initialize the hash table management pointers - */ - hpte_init_iSeries(); - - /* * Initialize the DMA/TCE management */ iommu_init_early_iSeries(); @@ -563,16 +554,6 @@ static void __init iSeries_fixup_klimit(void) if (naca.xRamDisk) klimit = KERNELBASE + (u64)naca.xRamDisk + (naca.xRamDiskSize * HW_PAGE_SIZE); - else { - /* - * No ram disk was included - check and see if there - * was an embedded system map. Change klimit to take - * into account any embedded system map - */ - if (embedded_sysmap_end) - klimit = KERNELBASE + ((embedded_sysmap_end + 4095) & - 0xfffffffffffff000); - } } static int __init iSeries_src_init(void) @@ -677,11 +658,7 @@ static int __init iseries_probe(void) powerpc_firmware_features |= FW_FEATURE_ISERIES; powerpc_firmware_features |= FW_FEATURE_LPAR; - /* - * The Hypervisor only allows us up to 256 interrupt - * sources (the irq number is passed in a u8). - */ - virt_irq_max = 255; + hpte_init_iSeries(); return 1; } diff --git a/arch/powerpc/platforms/iseries/smp.c b/arch/powerpc/platforms/iseries/smp.c index 6f9d407a709f..2eb095edb472 100644 --- a/arch/powerpc/platforms/iseries/smp.c +++ b/arch/powerpc/platforms/iseries/smp.c @@ -14,7 +14,6 @@ #undef DEBUG -#include <linux/config.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/sched.h> diff --git a/arch/powerpc/platforms/iseries/viopath.c b/arch/powerpc/platforms/iseries/viopath.c index 622a30149b48..9baa4ee82592 100644 --- a/arch/powerpc/platforms/iseries/viopath.c +++ b/arch/powerpc/platforms/iseries/viopath.c @@ -41,8 +41,8 @@ #include <asm/system.h> #include <asm/uaccess.h> +#include <asm/prom.h> #include <asm/iseries/hv_types.h> -#include <asm/iseries/it_exp_vpd_panel.h> #include <asm/iseries/hv_lp_event.h> #include <asm/iseries/hv_lp_config.h> #include <asm/iseries/mf.h> @@ -116,6 +116,8 @@ static int proc_viopath_show(struct seq_file *m, void *v) dma_addr_t handle; HvLpEvent_Rc hvrc; DECLARE_MUTEX_LOCKED(Semaphore); + struct device_node *node; + const char *sysid; buf = kmalloc(HW_PAGE_SIZE, GFP_KERNEL); if (!buf) @@ -143,20 +145,26 @@ static int proc_viopath_show(struct seq_file *m, void *v) buf[HW_PAGE_SIZE-1] = '\0'; seq_printf(m, "%s", buf); - seq_printf(m, "AVAILABLE_VETH=%x\n", vlanMap); - seq_printf(m, "SRLNBR=%c%c%c%c%c%c%c\n", - e2a(xItExtVpdPanel.mfgID[2]), - e2a(xItExtVpdPanel.mfgID[3]), - e2a(xItExtVpdPanel.systemSerial[1]), - e2a(xItExtVpdPanel.systemSerial[2]), - e2a(xItExtVpdPanel.systemSerial[3]), - e2a(xItExtVpdPanel.systemSerial[4]), - e2a(xItExtVpdPanel.systemSerial[5])); dma_unmap_single(iSeries_vio_dev, handle, HW_PAGE_SIZE, DMA_FROM_DEVICE); kfree(buf); + seq_printf(m, "AVAILABLE_VETH=%x\n", vlanMap); + + node = of_find_node_by_path("/"); + sysid = NULL; + if (node != NULL) + sysid = get_property(node, "system-id", NULL); + + if (sysid == NULL) + seq_printf(m, "SRLNBR=<UNKNOWN>\n"); + else + /* Skip "IBM," on front of serial number, see dt.c */ + seq_printf(m, "SRLNBR=%s\n", sysid + 4); + + of_node_put(node); + return 0; } diff --git a/arch/powerpc/platforms/iseries/vpdinfo.c b/arch/powerpc/platforms/iseries/vpdinfo.c index 23a6d1e5b429..9f83878a0c2e 100644 --- a/arch/powerpc/platforms/iseries/vpdinfo.c +++ b/arch/powerpc/platforms/iseries/vpdinfo.c @@ -188,7 +188,7 @@ static void __init iSeries_Parse_Vpd(u8 *VpdData, int VpdDataLen, { u8 *TagPtr = VpdData; int DataLen = VpdDataLen - 3; - u8 PhbId; + u8 PhbId = 0xff; while ((*TagPtr != VpdEndOfAreaTag) && (DataLen > 0)) { int AreaLen = *(TagPtr + 1) + (*(TagPtr + 2) * 256); @@ -205,15 +205,16 @@ static void __init iSeries_Parse_Vpd(u8 *VpdData, int VpdDataLen, } } -static void __init iSeries_Get_Location_Code(u16 bus, HvAgentId agent, +static int __init iSeries_Get_Location_Code(u16 bus, HvAgentId agent, u8 *frame, char card[4]) { + int status = 0; int BusVpdLen = 0; u8 *BusVpdPtr = kmalloc(BUS_VPDSIZE, GFP_KERNEL); if (BusVpdPtr == NULL) { printk("PCI: Bus VPD Buffer allocation failure.\n"); - return; + return 0; } BusVpdLen = HvCallPci_getBusVpd(bus, iseries_hv_addr(BusVpdPtr), BUS_VPDSIZE); @@ -228,8 +229,10 @@ static void __init iSeries_Get_Location_Code(u16 bus, HvAgentId agent, goto out_free; } iSeries_Parse_Vpd(BusVpdPtr, BusVpdLen, agent, frame, card); + status = 1; out_free: kfree(BusVpdPtr); + return status; } /* @@ -246,7 +249,7 @@ void __init iSeries_Device_Information(struct pci_dev *PciDev, int count) struct device_node *DevNode = PciDev->sysdata; struct pci_dn *pdn; u16 bus; - u8 frame; + u8 frame = 0; char card[4]; HvSubBusNumber subbus; HvAgentId agent; @@ -262,10 +265,11 @@ void __init iSeries_Device_Information(struct pci_dev *PciDev, int count) subbus = pdn->bussubno; agent = ISERIES_PCI_AGENTID(ISERIES_GET_DEVICE_FROM_SUBBUS(subbus), ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus)); - iSeries_Get_Location_Code(bus, agent, &frame, card); - printk("%d. PCI: Bus%3d, Device%3d, Vendor %04X Frame%3d, Card %4s ", - count, bus, PCI_SLOT(PciDev->devfn), PciDev->vendor, - frame, card); - printk("0x%04X\n", (int)(PciDev->class >> 8)); + if (iSeries_Get_Location_Code(bus, agent, &frame, card)) { + printk("%d. PCI: Bus%3d, Device%3d, Vendor %04X Frame%3d, " + "Card %4s 0x%04X\n", count, bus, + PCI_SLOT(PciDev->devfn), PciDev->vendor, frame, + card, (int)(PciDev->class >> 8)); + } } diff --git a/arch/powerpc/platforms/maple/pci.c b/arch/powerpc/platforms/maple/pci.c index 9a4efc0c3b29..c3aa46b8e2b9 100644 --- a/arch/powerpc/platforms/maple/pci.c +++ b/arch/powerpc/platforms/maple/pci.c @@ -38,16 +38,16 @@ static struct pci_controller *u3_agp, *u3_ht; static int __init fixup_one_level_bus_range(struct device_node *node, int higher) { for (; node != 0;node = node->sibling) { - int * bus_range; - unsigned int *class_code; + const int *bus_range; + const unsigned int *class_code; int len; /* For PCI<->PCI bridges or CardBus bridges, we go down */ - class_code = (unsigned int *) get_property(node, "class-code", NULL); + class_code = get_property(node, "class-code", NULL); if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) continue; - bus_range = (int *) get_property(node, "bus-range", &len); + bus_range = get_property(node, "bus-range", &len); if (bus_range != NULL && len > 2 * sizeof(int)) { if (bus_range[1] > higher) higher = bus_range[1]; @@ -65,30 +65,36 @@ static int __init fixup_one_level_bus_range(struct device_node *node, int higher */ static void __init fixup_bus_range(struct device_node *bridge) { - int * bus_range; + int *bus_range; + struct property *prop; int len; /* Lookup the "bus-range" property for the hose */ - bus_range = (int *) get_property(bridge, "bus-range", &len); - if (bus_range == NULL || len < 2 * sizeof(int)) { + prop = of_find_property(bridge, "bus-range", &len); + if (prop == NULL || prop->value == NULL || len < 2 * sizeof(int)) { printk(KERN_WARNING "Can't get bus-range for %s\n", bridge->full_name); return; } + bus_range = (int *)prop->value; bus_range[1] = fixup_one_level_bus_range(bridge->child, bus_range[1]); } -#define U3_AGP_CFA0(devfn, off) \ - ((1 << (unsigned long)PCI_SLOT(dev_fn)) \ - | (((unsigned long)PCI_FUNC(dev_fn)) << 8) \ - | (((unsigned long)(off)) & 0xFCUL)) +static unsigned long u3_agp_cfa0(u8 devfn, u8 off) +{ + return (1 << (unsigned long)PCI_SLOT(devfn)) | + ((unsigned long)PCI_FUNC(devfn) << 8) | + ((unsigned long)off & 0xFCUL); +} -#define U3_AGP_CFA1(bus, devfn, off) \ - ((((unsigned long)(bus)) << 16) \ - |(((unsigned long)(devfn)) << 8) \ - |(((unsigned long)(off)) & 0xFCUL) \ - |1UL) +static unsigned long u3_agp_cfa1(u8 bus, u8 devfn, u8 off) +{ + return ((unsigned long)bus << 16) | + ((unsigned long)devfn << 8) | + ((unsigned long)off & 0xFCUL) | + 1UL; +} static unsigned long u3_agp_cfg_access(struct pci_controller* hose, u8 bus, u8 dev_fn, u8 offset) @@ -98,9 +104,9 @@ static unsigned long u3_agp_cfg_access(struct pci_controller* hose, if (bus == hose->first_busno) { if (dev_fn < (11 << 3)) return 0; - caddr = U3_AGP_CFA0(dev_fn, offset); + caddr = u3_agp_cfa0(dev_fn, offset); } else - caddr = U3_AGP_CFA1(bus, dev_fn, offset); + caddr = u3_agp_cfa1(bus, dev_fn, offset); /* Uninorth will return garbage if we don't read back the value ! */ do { @@ -182,13 +188,15 @@ static struct pci_ops u3_agp_pci_ops = u3_agp_write_config }; +static unsigned long u3_ht_cfa0(u8 devfn, u8 off) +{ + return (devfn << 8) | off; +} -#define U3_HT_CFA0(devfn, off) \ - ((((unsigned long)devfn) << 8) | offset) -#define U3_HT_CFA1(bus, devfn, off) \ - (U3_HT_CFA0(devfn, off) \ - + (((unsigned long)bus) << 16) \ - + 0x01000000UL) +static unsigned long u3_ht_cfa1(u8 bus, u8 devfn, u8 off) +{ + return u3_ht_cfa0(devfn, off) + (bus << 16) + 0x01000000UL; +} static unsigned long u3_ht_cfg_access(struct pci_controller* hose, u8 bus, u8 devfn, u8 offset) @@ -196,9 +204,9 @@ static unsigned long u3_ht_cfg_access(struct pci_controller* hose, if (bus == hose->first_busno) { if (PCI_SLOT(devfn) == 0) return 0; - return ((unsigned long)hose->cfg_data) + U3_HT_CFA0(devfn, offset); + return ((unsigned long)hose->cfg_data) + u3_ht_cfa0(devfn, offset); } else - return ((unsigned long)hose->cfg_data) + U3_HT_CFA1(bus, devfn, offset); + return ((unsigned long)hose->cfg_data) + u3_ht_cfa1(bus, devfn, offset); } static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, @@ -211,6 +219,9 @@ static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, if (hose == NULL) return PCIBIOS_DEVICE_NOT_FOUND; + if (offset > 0xff) + return PCIBIOS_BAD_REGISTER_NUMBER; + addr = u3_ht_cfg_access(hose, bus->number, devfn, offset); if (!addr) return PCIBIOS_DEVICE_NOT_FOUND; @@ -243,6 +254,9 @@ static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn, if (hose == NULL) return PCIBIOS_DEVICE_NOT_FOUND; + if (offset > 0xff) + return PCIBIOS_BAD_REGISTER_NUMBER; + addr = u3_ht_cfg_access(hose, bus->number, devfn, offset); if (!addr) return PCIBIOS_DEVICE_NOT_FOUND; @@ -314,12 +328,12 @@ static int __init add_bridge(struct device_node *dev) int len; struct pci_controller *hose; char* disp_name; - int *bus_range; + const int *bus_range; int primary = 1; DBG("Adding PCI host bridge %s\n", dev->full_name); - bus_range = (int *) get_property(dev, "bus-range", &len); + bus_range = get_property(dev, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) { printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n", dev->full_name); @@ -376,9 +390,10 @@ static void __init maple_fixup_phb_resources(void) unsigned long offset = (unsigned long)hose->io_base_virt - pci_io_base; hose->io_resource.start += offset; hose->io_resource.end += offset; - printk(KERN_INFO "PCI Host %d, io start: %lx; io end: %lx\n", + printk(KERN_INFO "PCI Host %d, io start: %llx; io end: %llx\n", hose->global_number, - hose->io_resource.start, hose->io_resource.end); + (unsigned long long)hose->io_resource.start, + (unsigned long long)hose->io_resource.end); } } @@ -442,18 +457,23 @@ void __init maple_pci_init(void) int maple_pci_get_legacy_ide_irq(struct pci_dev *pdev, int channel) { struct device_node *np; - int irq = channel ? 15 : 14; + unsigned int defirq = channel ? 15 : 14; + unsigned int irq; if (pdev->vendor != PCI_VENDOR_ID_AMD || pdev->device != PCI_DEVICE_ID_AMD_8111_IDE) - return irq; + return defirq; np = pci_device_to_OF_node(pdev); if (np == NULL) - return irq; - if (np->n_intrs < 2) - return irq; - return np->intrs[channel & 0x1].line; + return defirq; + irq = irq_of_parse_and_map(np, channel & 0x1); + if (irq == NO_IRQ) { + printk("Failed to map onboard IDE interrupt for channel %d\n", + channel); + return defirq; + } + return irq; } /* XXX: To remove once all firmwares are ok */ diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c index a0505ea48a86..fe6b9bff61b9 100644 --- a/arch/powerpc/platforms/maple/setup.c +++ b/arch/powerpc/platforms/maple/setup.c @@ -11,9 +11,8 @@ * */ -#define DEBUG +#undef DEBUG -#include <linux/config.h> #include <linux/init.h> #include <linux/errno.h> #include <linux/sched.h> @@ -100,8 +99,7 @@ static unsigned long maple_find_nvram_base(void) static void maple_restart(char *cmd) { unsigned int maple_nvram_base; - unsigned int maple_nvram_offset; - unsigned int maple_nvram_command; + const unsigned int *maple_nvram_offset, *maple_nvram_command; struct device_node *sp; maple_nvram_base = maple_find_nvram_base(); @@ -114,14 +112,12 @@ static void maple_restart(char *cmd) printk(KERN_EMERG "Maple: Unable to find Service Processor\n"); goto fail; } - maple_nvram_offset = *(unsigned int*) get_property(sp, - "restart-addr", NULL); - maple_nvram_command = *(unsigned int*) get_property(sp, - "restart-value", NULL); + maple_nvram_offset = get_property(sp, "restart-addr", NULL); + maple_nvram_command = get_property(sp, "restart-value", NULL); of_node_put(sp); /* send command */ - outb_p(maple_nvram_command, maple_nvram_base + maple_nvram_offset); + outb_p(*maple_nvram_command, maple_nvram_base + *maple_nvram_offset); for (;;) ; fail: printk(KERN_EMERG "Maple: Manual Restart Required\n"); @@ -130,8 +126,7 @@ static void maple_restart(char *cmd) static void maple_power_off(void) { unsigned int maple_nvram_base; - unsigned int maple_nvram_offset; - unsigned int maple_nvram_command; + const unsigned int *maple_nvram_offset, *maple_nvram_command; struct device_node *sp; maple_nvram_base = maple_find_nvram_base(); @@ -144,14 +139,12 @@ static void maple_power_off(void) printk(KERN_EMERG "Maple: Unable to find Service Processor\n"); goto fail; } - maple_nvram_offset = *(unsigned int*) get_property(sp, - "power-off-addr", NULL); - maple_nvram_command = *(unsigned int*) get_property(sp, - "power-off-value", NULL); + maple_nvram_offset = get_property(sp, "power-off-addr", NULL); + maple_nvram_command = get_property(sp, "power-off-value", NULL); of_node_put(sp); /* send command */ - outb_p(maple_nvram_command, maple_nvram_base + maple_nvram_offset); + outb_p(*maple_nvram_command, maple_nvram_base + *maple_nvram_offset); for (;;) ; fail: printk(KERN_EMERG "Maple: Manual Power-Down Required\n"); @@ -199,55 +192,89 @@ static void __init maple_init_early(void) { DBG(" -> maple_init_early\n"); - /* Initialize hash table, from now on, we can take hash faults - * and call ioremap - */ - hpte_init_native(); - - /* Setup interrupt mapping options */ - ppc64_interrupt_controller = IC_OPEN_PIC; - iommu_init_early_dart(); DBG(" <- maple_init_early\n"); } - -static __init void maple_init_IRQ(void) +/* + * This is almost identical to pSeries and CHRP. We need to make that + * code generic at one point, with appropriate bits in the device-tree to + * identify the presence of an HT APIC + */ +static void __init maple_init_IRQ(void) { - struct device_node *root; - unsigned int *opprop; - unsigned long opic_addr; + struct device_node *root, *np, *mpic_node = NULL; + const unsigned int *opprop; + unsigned long openpic_addr = 0; + int naddr, n, i, opplen, has_isus = 0; struct mpic *mpic; - unsigned char senses[128]; - int n; + unsigned int flags = MPIC_PRIMARY; + + /* Locate MPIC in the device-tree. Note that there is a bug + * in Maple device-tree where the type of the controller is + * open-pic and not interrupt-controller + */ - DBG(" -> maple_init_IRQ\n"); + for_each_node_by_type(np, "interrupt-controller") + if (device_is_compatible(np, "open-pic")) { + mpic_node = np; + break; + } + if (mpic_node == NULL) + for_each_node_by_type(np, "open-pic") { + mpic_node = np; + break; + } + if (mpic_node == NULL) { + printk(KERN_ERR + "Failed to locate the MPIC interrupt controller\n"); + return; + } - /* XXX: Non standard, replace that with a proper openpic/mpic node - * in the device-tree. Find the Open PIC if present */ + /* Find address list in /platform-open-pic */ root = of_find_node_by_path("/"); - opprop = (unsigned int *) get_property(root, - "platform-open-pic", NULL); - if (opprop == 0) - panic("OpenPIC not found !\n"); - - n = prom_n_addr_cells(root); - for (opic_addr = 0; n > 0; --n) - opic_addr = (opic_addr << 32) + *opprop++; + naddr = prom_n_addr_cells(root); + opprop = get_property(root, "platform-open-pic", &opplen); + if (opprop != 0) { + openpic_addr = of_read_number(opprop, naddr); + has_isus = (opplen > naddr); + printk(KERN_DEBUG "OpenPIC addr: %lx, has ISUs: %d\n", + openpic_addr, has_isus); + } of_node_put(root); - /* Obtain sense values from device-tree */ - prom_get_irq_senses(senses, 0, 128); + BUG_ON(openpic_addr == 0); + + /* Check for a big endian MPIC */ + if (get_property(np, "big-endian", NULL) != NULL) + flags |= MPIC_BIG_ENDIAN; + + /* XXX Maple specific bits */ + flags |= MPIC_BROKEN_U3 | MPIC_WANTS_RESET; + /* All U3/U4 are big-endian, older SLOF firmware doesn't encode this */ + flags |= MPIC_BIG_ENDIAN; - mpic = mpic_alloc(opic_addr, - MPIC_PRIMARY | MPIC_BIG_ENDIAN | - MPIC_BROKEN_U3 | MPIC_WANTS_RESET, - 0, 0, 128, 128, senses, 128, "U3-MPIC"); + /* Setup the openpic driver. More device-tree junks, we hard code no + * ISUs for now. I'll have to revisit some stuffs with the folks doing + * the firmware for those + */ + mpic = mpic_alloc(mpic_node, openpic_addr, flags, + /*has_isus ? 16 :*/ 0, 0, " MPIC "); BUG_ON(mpic == NULL); - mpic_init(mpic); - DBG(" <- maple_init_IRQ\n"); + /* Add ISUs */ + opplen /= sizeof(u32); + for (n = 0, i = naddr; i < opplen; i += naddr, n++) { + unsigned long isuaddr = of_read_number(opprop + i, naddr); + mpic_assign_isu(mpic, n, isuaddr); + } + + /* All ISUs are setup, complete initialization */ + mpic_init(mpic); + ppc_md.get_irq = mpic_get_irq; + of_node_put(mpic_node); + of_node_put(root); } static void __init maple_progress(char *s, unsigned short hex) @@ -262,7 +289,9 @@ static void __init maple_progress(char *s, unsigned short hex) static int __init maple_probe(void) { unsigned long root = of_get_flat_dt_root(); - if (!of_flat_dt_is_compatible(root, "Momentum,Maple")) + + if (!of_flat_dt_is_compatible(root, "Momentum,Maple") && + !of_flat_dt_is_compatible(root, "Momentum,Apache")) return 0; /* * On U3, the DART (iommu) must be allocated now since it @@ -272,6 +301,8 @@ static int __init maple_probe(void) */ alloc_dart_table(); + hpte_init_native(); + return 1; } @@ -281,7 +312,6 @@ define_machine(maple_md) { .setup_arch = maple_setup_arch, .init_early = maple_init_early, .init_IRQ = maple_init_IRQ, - .get_irq = mpic_get_irq, .pcibios_fixup = maple_pcibios_fixup, .pci_get_legacy_ide_irq = maple_pci_get_legacy_ide_irq, .restart = maple_restart, diff --git a/arch/powerpc/platforms/maple/time.c b/arch/powerpc/platforms/maple/time.c index b9a2b3d4bf33..9f7579b38c72 100644 --- a/arch/powerpc/platforms/maple/time.c +++ b/arch/powerpc/platforms/maple/time.c @@ -11,7 +11,6 @@ #undef DEBUG -#include <linux/config.h> #include <linux/errno.h> #include <linux/sched.h> #include <linux/kernel.h> diff --git a/arch/powerpc/platforms/pasemi/Makefile b/arch/powerpc/platforms/pasemi/Makefile new file mode 100644 index 000000000000..1be1a993c5f5 --- /dev/null +++ b/arch/powerpc/platforms/pasemi/Makefile @@ -0,0 +1 @@ +obj-y += setup.o pci.o time.o diff --git a/arch/powerpc/platforms/pasemi/pasemi.h b/arch/powerpc/platforms/pasemi/pasemi.h new file mode 100644 index 000000000000..fd71d72736b2 --- /dev/null +++ b/arch/powerpc/platforms/pasemi/pasemi.h @@ -0,0 +1,8 @@ +#ifndef _PASEMI_PASEMI_H +#define _PASEMI_PASEMI_H + +extern unsigned long pas_get_boot_time(void); +extern void pas_pci_init(void); +extern void pas_pcibios_fixup(void); + +#endif /* _PASEMI_PASEMI_H */ diff --git a/arch/powerpc/platforms/pasemi/pci.c b/arch/powerpc/platforms/pasemi/pci.c new file mode 100644 index 000000000000..4679c5230413 --- /dev/null +++ b/arch/powerpc/platforms/pasemi/pci.c @@ -0,0 +1,198 @@ +/* + * Copyright (C) 2006 PA Semi, Inc + * + * Authors: Kip Walker, PA Semi + * Olof Johansson, PA Semi + * + * Maintained by: Olof Johansson <olof@lixom.net> + * + * Based on arch/powerpc/platforms/maple/pci.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include <linux/kernel.h> +#include <linux/pci.h> + +#include <asm/pci-bridge.h> +#include <asm/machdep.h> + +#include <asm/ppc-pci.h> + +#define PA_PXP_CFA(bus, devfn, off) (((bus) << 20) | ((devfn) << 12) | (off)) + +#define CONFIG_OFFSET_VALID(off) ((off) < 4096) + +static unsigned long pa_pxp_cfg_addr(struct pci_controller *hose, + u8 bus, u8 devfn, int offset) +{ + return ((unsigned long)hose->cfg_data) + PA_PXP_CFA(bus, devfn, offset); +} + +static int pa_pxp_read_config(struct pci_bus *bus, unsigned int devfn, + int offset, int len, u32 *val) +{ + struct pci_controller *hose; + unsigned long addr; + + hose = pci_bus_to_host(bus); + if (!hose) + return PCIBIOS_DEVICE_NOT_FOUND; + + if (!CONFIG_OFFSET_VALID(offset)) + return PCIBIOS_BAD_REGISTER_NUMBER; + + addr = pa_pxp_cfg_addr(hose, bus->number, devfn, offset); + + /* + * Note: the caller has already checked that offset is + * suitably aligned and that len is 1, 2 or 4. + */ + switch (len) { + case 1: + *val = in_8((u8 *)addr); + break; + case 2: + *val = in_le16((u16 *)addr); + break; + default: + *val = in_le32((u32 *)addr); + break; + } + + return PCIBIOS_SUCCESSFUL; +} + +static int pa_pxp_write_config(struct pci_bus *bus, unsigned int devfn, + int offset, int len, u32 val) +{ + struct pci_controller *hose; + unsigned long addr; + + hose = pci_bus_to_host(bus); + if (!hose) + return PCIBIOS_DEVICE_NOT_FOUND; + + if (!CONFIG_OFFSET_VALID(offset)) + return PCIBIOS_BAD_REGISTER_NUMBER; + + addr = pa_pxp_cfg_addr(hose, bus->number, devfn, offset); + + /* + * Note: the caller has already checked that offset is + * suitably aligned and that len is 1, 2 or 4. + */ + switch (len) { + case 1: + out_8((u8 *)addr, val); + (void) in_8((u8 *)addr); + break; + case 2: + out_le16((u16 *)addr, val); + (void) in_le16((u16 *)addr); + break; + default: + out_le32((u32 *)addr, val); + (void) in_le32((u32 *)addr); + break; + } + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops pa_pxp_ops = { + pa_pxp_read_config, + pa_pxp_write_config, +}; + +static void __init setup_pa_pxp(struct pci_controller *hose) +{ + hose->ops = &pa_pxp_ops; + hose->cfg_data = ioremap(0xe0000000, 0x10000000); +} + +static int __init add_bridge(struct device_node *dev) +{ + struct pci_controller *hose; + + pr_debug("Adding PCI host bridge %s\n", dev->full_name); + + hose = pcibios_alloc_controller(dev); + if (!hose) + return -ENOMEM; + + hose->first_busno = 0; + hose->last_busno = 0xff; + + setup_pa_pxp(hose); + + printk(KERN_INFO "Found PA-PXP PCI host bridge.\n"); + + /* Interpret the "ranges" property */ + /* This also maps the I/O region and sets isa_io/mem_base */ + pci_process_bridge_OF_ranges(hose, dev, 1); + pci_setup_phb_io(hose, 1); + + return 0; +} + + +void __init pas_pcibios_fixup(void) +{ + struct pci_dev *dev = NULL; + + for_each_pci_dev(dev) + pci_read_irq_line(dev); +} + +static void __init pas_fixup_phb_resources(void) +{ + struct pci_controller *hose, *tmp; + + list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { + unsigned long offset = (unsigned long)hose->io_base_virt - pci_io_base; + hose->io_resource.start += offset; + hose->io_resource.end += offset; + printk(KERN_INFO "PCI Host %d, io start: %lx; io end: %lx\n", + hose->global_number, + hose->io_resource.start, hose->io_resource.end); + } +} + + +void __init pas_pci_init(void) +{ + struct device_node *np, *root; + + root = of_find_node_by_path("/"); + if (!root) { + printk(KERN_CRIT "pas_pci_init: can't find root " + "of device tree\n"); + return; + } + + for (np = NULL; (np = of_get_next_child(root, np)) != NULL;) + if (np->name && !strcmp(np->name, "pxp") && !add_bridge(np)) + of_node_get(np); + + of_node_put(root); + + pas_fixup_phb_resources(); + + /* Setup the linkage between OF nodes and PHBs */ + pci_devs_phb_init(); + + /* Use the common resource allocation mechanism */ + pci_probe_only = 1; +} diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c new file mode 100644 index 000000000000..628482671c15 --- /dev/null +++ b/arch/powerpc/platforms/pasemi/setup.c @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2006 PA Semi, Inc + * + * Authors: Kip Walker, PA Semi + * Olof Johansson, PA Semi + * + * Maintained by: Olof Johansson <olof@lixom.net> + * + * Based on arch/powerpc/platforms/maple/setup.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/config.h> +#include <linux/errno.h> +#include <linux/kernel.h> +#include <linux/delay.h> +#include <linux/console.h> + +#include <asm/prom.h> +#include <asm/system.h> +#include <asm/iommu.h> +#include <asm/machdep.h> +#include <asm/mpic.h> +#include <asm/smp.h> +#include <asm/time.h> + +#include "pasemi.h" + +static void pas_restart(char *cmd) +{ + printk("restart unimplemented, looping...\n"); + for (;;) ; +} + +static void pas_power_off(void) +{ + printk("power off unimplemented, looping...\n"); + for (;;) ; +} + +static void pas_halt(void) +{ + pas_power_off(); +} + +#ifdef CONFIG_SMP +struct smp_ops_t pas_smp_ops = { + .probe = smp_mpic_probe, + .message_pass = smp_mpic_message_pass, + .kick_cpu = smp_generic_kick_cpu, + .setup_cpu = smp_mpic_setup_cpu, + .give_timebase = smp_generic_give_timebase, + .take_timebase = smp_generic_take_timebase, +}; +#endif /* CONFIG_SMP */ + +void __init pas_setup_arch(void) +{ +#ifdef CONFIG_SMP + /* Setup SMP callback */ + smp_ops = &pas_smp_ops; +#endif + /* Lookup PCI hosts */ + pas_pci_init(); + +#ifdef CONFIG_DUMMY_CONSOLE + conswitchp = &dummy_con; +#endif + + printk(KERN_DEBUG "Using default idle loop\n"); +} + +static void iommu_dev_setup_null(struct pci_dev *dev) { } +static void iommu_bus_setup_null(struct pci_bus *bus) { } + +static void __init pas_init_early(void) +{ + /* No iommu code yet */ + ppc_md.iommu_dev_setup = iommu_dev_setup_null; + ppc_md.iommu_bus_setup = iommu_bus_setup_null; + pci_direct_iommu_init(); +} + +/* No legacy IO on our parts */ +static int pas_check_legacy_ioport(unsigned int baseport) +{ + return -ENODEV; +} + +static __init void pas_init_IRQ(void) +{ + struct device_node *np; + struct device_node *root, *mpic_node; + unsigned long openpic_addr; + const unsigned int *opprop; + int naddr, opplen; + struct mpic *mpic; + + mpic_node = NULL; + + for_each_node_by_type(np, "interrupt-controller") + if (device_is_compatible(np, "open-pic")) { + mpic_node = np; + break; + } + if (!mpic_node) + for_each_node_by_type(np, "open-pic") { + mpic_node = np; + break; + } + if (!mpic_node) { + printk(KERN_ERR + "Failed to locate the MPIC interrupt controller\n"); + return; + } + + /* Find address list in /platform-open-pic */ + root = of_find_node_by_path("/"); + naddr = prom_n_addr_cells(root); + opprop = get_property(root, "platform-open-pic", &opplen); + if (!opprop) { + printk(KERN_ERR "No platform-open-pic property.\n"); + of_node_put(root); + return; + } + openpic_addr = of_read_number(opprop, naddr); + printk(KERN_DEBUG "OpenPIC addr: %lx\n", openpic_addr); + of_node_put(root); + + mpic = mpic_alloc(mpic_node, openpic_addr, MPIC_PRIMARY, 0, 0, + " PAS-OPIC "); + BUG_ON(!mpic); + + mpic_assign_isu(mpic, 0, openpic_addr + 0x10000); + mpic_init(mpic); + of_node_put(mpic_node); + of_node_put(root); +} + +static void __init pas_progress(char *s, unsigned short hex) +{ + printk("[%04x] : %s\n", hex, s ? s : ""); +} + + +/* + * Called very early, MMU is off, device-tree isn't unflattened + */ +static int __init pas_probe(void) +{ + unsigned long root = of_get_flat_dt_root(); + + if (!of_flat_dt_is_compatible(root, "PA6T-1682M")) + return 0; + + hpte_init_native(); + + return 1; +} + +define_machine(pas) { + .name = "PA Semi PA6T-1682M", + .probe = pas_probe, + .setup_arch = pas_setup_arch, + .init_early = pas_init_early, + .init_IRQ = pas_init_IRQ, + .get_irq = mpic_get_irq, + .pcibios_fixup = pas_pcibios_fixup, + .restart = pas_restart, + .power_off = pas_power_off, + .halt = pas_halt, + .get_boot_time = pas_get_boot_time, + .calibrate_decr = generic_calibrate_decr, + .check_legacy_ioport = pas_check_legacy_ioport, + .progress = pas_progress, +}; diff --git a/arch/powerpc/platforms/pasemi/time.c b/arch/powerpc/platforms/pasemi/time.c new file mode 100644 index 000000000000..9bd410b8fec6 --- /dev/null +++ b/arch/powerpc/platforms/pasemi/time.c @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2006 PA Semi, Inc + * + * Maintained by: Olof Johansson <olof@lixom.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/config.h> +#include <linux/time.h> + +#include <asm/time.h> + +unsigned long __init pas_get_boot_time(void) +{ + /* Let's just return a fake date right now */ + return mktime(2006, 1, 1, 12, 0, 0); +} diff --git a/arch/powerpc/platforms/powermac/backlight.c b/arch/powerpc/platforms/powermac/backlight.c index 8be2f7d071f0..afa593a8544a 100644 --- a/arch/powerpc/platforms/powermac/backlight.c +++ b/arch/powerpc/platforms/powermac/backlight.c @@ -3,200 +3,223 @@ * Contains support for the backlight. * * Copyright (C) 2000 Benjamin Herrenschmidt + * Copyright (C) 2006 Michael Hanselmann <linux-kernel@hansmi.ch> * */ -#include <linux/config.h> #include <linux/kernel.h> -#include <linux/module.h> -#include <linux/stddef.h> -#include <linux/reboot.h> -#include <linux/nvram.h> -#include <linux/console.h> -#include <asm/sections.h> -#include <asm/ptrace.h> -#include <asm/io.h> -#include <asm/pgtable.h> -#include <asm/system.h> +#include <linux/fb.h> +#include <linux/backlight.h> +#include <linux/adb.h> +#include <linux/pmu.h> +#include <asm/atomic.h> #include <asm/prom.h> -#include <asm/machdep.h> -#include <asm/nvram.h> #include <asm/backlight.h> -#include <linux/adb.h> -#include <linux/pmu.h> +#define OLD_BACKLIGHT_MAX 15 -static struct backlight_controller *backlighter; -static void* backlighter_data; -static int backlight_autosave; -static int backlight_level = BACKLIGHT_MAX; -static int backlight_enabled = 1; -static int backlight_req_level = -1; -static int backlight_req_enable = -1; +static void pmac_backlight_key_worker(void *data); +static void pmac_backlight_set_legacy_worker(void *data); -static void backlight_callback(void *); -static DECLARE_WORK(backlight_work, backlight_callback, NULL); +static DECLARE_WORK(pmac_backlight_key_work, pmac_backlight_key_worker, NULL); +static DECLARE_WORK(pmac_backlight_set_legacy_work, pmac_backlight_set_legacy_worker, NULL); -void register_backlight_controller(struct backlight_controller *ctrler, - void *data, char *type) -{ - struct device_node* bk_node; - char *prop; - int valid = 0; +/* Although these variables are used in interrupt context, it makes no sense to + * protect them. No user is able to produce enough key events per second and + * notice the errors that might happen. + */ +static int pmac_backlight_key_queued; +static int pmac_backlight_set_legacy_queued; - /* There's already a matching controller, bail out */ - if (backlighter != NULL) - return; +/* The via-pmu code allows the backlight to be grabbed, in which case the + * in-kernel control of the brightness needs to be disabled. This should + * only be used by really old PowerBooks. + */ +static atomic_t kernel_backlight_disabled = ATOMIC_INIT(0); + +/* Protect the pmac_backlight variable */ +DEFINE_MUTEX(pmac_backlight_mutex); + +/* Main backlight storage + * + * Backlight drivers in this variable are required to have the "props" + * attribute set and to have an update_status function. + * + * We can only store one backlight here, but since Apple laptops have only one + * internal display, it doesn't matter. Other backlight drivers can be used + * independently. + * + * Lock ordering: + * pmac_backlight_mutex (global, main backlight) + * pmac_backlight->sem (backlight class) + */ +struct backlight_device *pmac_backlight; + +int pmac_has_backlight_type(const char *type) +{ + struct device_node* bk_node = find_devices("backlight"); - bk_node = find_devices("backlight"); - -#ifdef CONFIG_ADB_PMU - /* Special case for the old PowerBook since I can't test on it */ - backlight_autosave = machine_is_compatible("AAPL,3400/2400") - || machine_is_compatible("AAPL,3500"); - if ((backlight_autosave - || machine_is_compatible("AAPL,PowerBook1998") - || machine_is_compatible("PowerBook1,1")) - && !strcmp(type, "pmu")) - valid = 1; -#endif if (bk_node) { - prop = get_property(bk_node, "backlight-control", NULL); - if (prop && !strncmp(prop, type, strlen(type))) - valid = 1; + const char *prop = get_property(bk_node, + "backlight-control", NULL); + if (prop && strncmp(prop, type, strlen(type)) == 0) + return 1; } - if (!valid) - return; - backlighter = ctrler; - backlighter_data = data; - - if (bk_node && !backlight_autosave) - prop = get_property(bk_node, "bklt", NULL); - else - prop = NULL; - if (prop) { - backlight_level = ((*prop)+1) >> 1; - if (backlight_level > BACKLIGHT_MAX) - backlight_level = BACKLIGHT_MAX; + + return 0; +} + +int pmac_backlight_curve_lookup(struct fb_info *info, int value) +{ + int level = (FB_BACKLIGHT_LEVELS - 1); + + if (info && info->bl_dev) { + int i, max = 0; + + /* Look for biggest value */ + for (i = 0; i < FB_BACKLIGHT_LEVELS; i++) + max = max((int)info->bl_curve[i], max); + + /* Look for nearest value */ + for (i = 0; i < FB_BACKLIGHT_LEVELS; i++) { + int diff = abs(info->bl_curve[i] - value); + if (diff < max) { + max = diff; + level = i; + } + } + } -#ifdef CONFIG_ADB_PMU - if (backlight_autosave) { - struct adb_request req; - pmu_request(&req, NULL, 2, 0xd9, 0); - while (!req.complete) - pmu_poll(); - backlight_level = req.reply[0] >> 4; + return level; +} + +static void pmac_backlight_key_worker(void *data) +{ + if (atomic_read(&kernel_backlight_disabled)) + return; + + mutex_lock(&pmac_backlight_mutex); + if (pmac_backlight) { + struct backlight_properties *props; + int brightness; + + down(&pmac_backlight->sem); + props = pmac_backlight->props; + + brightness = props->brightness + + ((pmac_backlight_key_queued?-1:1) * + (props->max_brightness / 15)); + + if (brightness < 0) + brightness = 0; + else if (brightness > props->max_brightness) + brightness = props->max_brightness; + + props->brightness = brightness; + props->update_status(pmac_backlight); + + up(&pmac_backlight->sem); } -#endif - acquire_console_sem(); - if (!backlighter->set_enable(1, backlight_level, data)) - backlight_enabled = 1; - release_console_sem(); - - printk(KERN_INFO "Registered \"%s\" backlight controller," - "level: %d/15\n", type, backlight_level); + mutex_unlock(&pmac_backlight_mutex); } -EXPORT_SYMBOL(register_backlight_controller); -void unregister_backlight_controller(struct backlight_controller - *ctrler, void *data) +/* This function is called in interrupt context */ +void pmac_backlight_key(int direction) { - /* We keep the current backlight level (for now) */ - if (ctrler == backlighter && data == backlighter_data) - backlighter = NULL; + if (atomic_read(&kernel_backlight_disabled)) + return; + + /* we can receive multiple interrupts here, but the scheduled work + * will run only once, with the last value + */ + pmac_backlight_key_queued = direction; + schedule_work(&pmac_backlight_key_work); } -EXPORT_SYMBOL(unregister_backlight_controller); -static int __set_backlight_enable(int enable) +static int __pmac_backlight_set_legacy_brightness(int brightness) { - int rc; - - if (!backlighter) - return -ENODEV; - acquire_console_sem(); - rc = backlighter->set_enable(enable, backlight_level, - backlighter_data); - if (!rc) - backlight_enabled = enable; - release_console_sem(); - return rc; + int error = -ENXIO; + + mutex_lock(&pmac_backlight_mutex); + if (pmac_backlight) { + struct backlight_properties *props; + + down(&pmac_backlight->sem); + props = pmac_backlight->props; + props->brightness = brightness * + (props->max_brightness + 1) / + (OLD_BACKLIGHT_MAX + 1); + + if (props->brightness > props->max_brightness) + props->brightness = props->max_brightness; + else if (props->brightness < 0) + props->brightness = 0; + + props->update_status(pmac_backlight); + up(&pmac_backlight->sem); + + error = 0; + } + mutex_unlock(&pmac_backlight_mutex); + + return error; } -int set_backlight_enable(int enable) + +static void pmac_backlight_set_legacy_worker(void *data) { - if (!backlighter) - return -ENODEV; - backlight_req_enable = enable; - schedule_work(&backlight_work); - return 0; + if (atomic_read(&kernel_backlight_disabled)) + return; + + __pmac_backlight_set_legacy_brightness(pmac_backlight_set_legacy_queued); } -EXPORT_SYMBOL(set_backlight_enable); +/* This function is called in interrupt context */ +void pmac_backlight_set_legacy_brightness_pmu(int brightness) { + if (atomic_read(&kernel_backlight_disabled)) + return; -int get_backlight_enable(void) -{ - if (!backlighter) - return -ENODEV; - return backlight_enabled; + pmac_backlight_set_legacy_queued = brightness; + schedule_work(&pmac_backlight_set_legacy_work); } -EXPORT_SYMBOL(get_backlight_enable); -static int __set_backlight_level(int level) +int pmac_backlight_set_legacy_brightness(int brightness) { - int rc = 0; - - if (!backlighter) - return -ENODEV; - if (level < BACKLIGHT_MIN) - level = BACKLIGHT_OFF; - if (level > BACKLIGHT_MAX) - level = BACKLIGHT_MAX; - acquire_console_sem(); - if (backlight_enabled) - rc = backlighter->set_level(level, backlighter_data); - if (!rc) - backlight_level = level; - release_console_sem(); - if (!rc && !backlight_autosave) { - level <<=1; - if (level & 0x10) - level |= 0x01; - // -- todo: save to property "bklt" - } - return rc; + return __pmac_backlight_set_legacy_brightness(brightness); } -int set_backlight_level(int level) + +int pmac_backlight_get_legacy_brightness() { - if (!backlighter) - return -ENODEV; - backlight_req_level = level; - schedule_work(&backlight_work); - return 0; -} + int result = -ENXIO; -EXPORT_SYMBOL(set_backlight_level); + mutex_lock(&pmac_backlight_mutex); + if (pmac_backlight) { + struct backlight_properties *props; -int get_backlight_level(void) + down(&pmac_backlight->sem); + props = pmac_backlight->props; + + result = props->brightness * + (OLD_BACKLIGHT_MAX + 1) / + (props->max_brightness + 1); + + up(&pmac_backlight->sem); + } + mutex_unlock(&pmac_backlight_mutex); + + return result; +} + +void pmac_backlight_disable() { - if (!backlighter) - return -ENODEV; - return backlight_level; + atomic_inc(&kernel_backlight_disabled); } -EXPORT_SYMBOL(get_backlight_level); -static void backlight_callback(void *dummy) +void pmac_backlight_enable() { - int level, enable; - - do { - level = backlight_req_level; - enable = backlight_req_enable; - mb(); - - if (level >= 0) - __set_backlight_level(level); - if (enable >= 0) - __set_backlight_enable(enable); - } while(cmpxchg(&backlight_req_level, level, -1) != level || - cmpxchg(&backlight_req_enable, enable, -1) != enable); + atomic_dec(&kernel_backlight_disabled); } + +EXPORT_SYMBOL_GPL(pmac_backlight); +EXPORT_SYMBOL_GPL(pmac_backlight_mutex); +EXPORT_SYMBOL_GPL(pmac_has_backlight_type); diff --git a/arch/powerpc/platforms/powermac/bootx_init.c b/arch/powerpc/platforms/powermac/bootx_init.c index eacbfd9beabc..9d73d0234c5d 100644 --- a/arch/powerpc/platforms/powermac/bootx_init.c +++ b/arch/powerpc/platforms/powermac/bootx_init.c @@ -9,11 +9,10 @@ * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/string.h> #include <linux/init.h> -#include <linux/version.h> +#include <linux/utsrelease.h> #include <asm/sections.h> #include <asm/prom.h> #include <asm/page.h> @@ -163,6 +162,8 @@ static void __init bootx_add_chosen_props(unsigned long base, { u32 val; + bootx_dt_add_prop("linux,bootx", NULL, 0, mem_end); + if (bootx_info->kernelParamsOffset) { char *args = (char *)((unsigned long)bootx_info) + bootx_info->kernelParamsOffset; @@ -180,10 +181,32 @@ static void __init bootx_add_chosen_props(unsigned long base, } static void __init bootx_add_display_props(unsigned long base, - unsigned long *mem_end) + unsigned long *mem_end, + int has_real_node) { - bootx_dt_add_prop("linux,boot-display", NULL, 0, mem_end); - bootx_dt_add_prop("linux,opened", NULL, 0, mem_end); + boot_infos_t *bi = bootx_info; + u32 tmp; + + if (has_real_node) { + bootx_dt_add_prop("linux,boot-display", NULL, 0, mem_end); + bootx_dt_add_prop("linux,opened", NULL, 0, mem_end); + } else + bootx_dt_add_prop("linux,bootx-noscreen", NULL, 0, mem_end); + + tmp = bi->dispDeviceDepth; + bootx_dt_add_prop("linux,bootx-depth", &tmp, 4, mem_end); + tmp = bi->dispDeviceRect[2] - bi->dispDeviceRect[0]; + bootx_dt_add_prop("linux,bootx-width", &tmp, 4, mem_end); + tmp = bi->dispDeviceRect[3] - bi->dispDeviceRect[1]; + bootx_dt_add_prop("linux,bootx-height", &tmp, 4, mem_end); + tmp = bi->dispDeviceRowBytes; + bootx_dt_add_prop("linux,bootx-linebytes", &tmp, 4, mem_end); + tmp = (u32)bi->dispDeviceBase; + if (tmp == 0) + tmp = (u32)bi->logicalDisplayBase; + tmp += bi->dispDeviceRect[1] * bi->dispDeviceRowBytes; + tmp += bi->dispDeviceRect[0] * ((bi->dispDeviceDepth + 7) / 8); + bootx_dt_add_prop("linux,bootx-addr", &tmp, 4, mem_end); } static void __init bootx_dt_add_string(char *s, unsigned long *mem_end) @@ -212,7 +235,7 @@ static void __init bootx_scan_dt_build_strings(unsigned long base, if (!strcmp(namep, "/chosen")) { DBG(" detected /chosen ! adding properties names !\n"); - bootx_dt_add_string("linux,platform", mem_end); + bootx_dt_add_string("linux,bootx", mem_end); bootx_dt_add_string("linux,stdout-path", mem_end); bootx_dt_add_string("linux,initrd-start", mem_end); bootx_dt_add_string("linux,initrd-end", mem_end); @@ -306,10 +329,13 @@ static void __init bootx_scan_dt_build_struct(unsigned long base, ppp = &pp->next; } - if (node == bootx_node_chosen) + if (node == bootx_node_chosen) { bootx_add_chosen_props(base, mem_end); - if (node == bootx_info->dispDeviceRegEntryOffset) - bootx_add_display_props(base, mem_end); + if (bootx_info->dispDeviceRegEntryOffset == 0) + bootx_add_display_props(base, mem_end, 0); + } + else if (node == bootx_info->dispDeviceRegEntryOffset) + bootx_add_display_props(base, mem_end, 1); /* do all our children */ cpp = &np->child; @@ -351,6 +377,14 @@ static unsigned long __init bootx_flatten_dt(unsigned long start) mem_end += 4; bootx_dt_strend = mem_end; bootx_scan_dt_build_strings(base, 4, &mem_end); + /* Add some strings */ + bootx_dt_add_string("linux,bootx-noscreen", &mem_end); + bootx_dt_add_string("linux,bootx-depth", &mem_end); + bootx_dt_add_string("linux,bootx-width", &mem_end); + bootx_dt_add_string("linux,bootx-height", &mem_end); + bootx_dt_add_string("linux,bootx-linebytes", &mem_end); + bootx_dt_add_string("linux,bootx-addr", &mem_end); + /* Wrap up strings */ hdr->off_dt_strings = bootx_dt_strbase - mem_start; hdr->dt_strings_size = bootx_dt_strend - bootx_dt_strbase; @@ -377,8 +411,15 @@ static unsigned long __init bootx_flatten_dt(unsigned long start) DBG("End of boot params: %x\n", mem_end); rsvmap[0] = mem_start; rsvmap[1] = mem_end; - rsvmap[2] = 0; - rsvmap[3] = 0; + if (bootx_info->ramDisk) { + rsvmap[2] = ((unsigned long)bootx_info) + bootx_info->ramDisk; + rsvmap[3] = rsvmap[2] + bootx_info->ramDiskSize; + rsvmap[4] = 0; + rsvmap[5] = 0; + } else { + rsvmap[2] = 0; + rsvmap[3] = 0; + } return (unsigned long)hdr; } @@ -444,7 +485,15 @@ void __init bootx_init(unsigned long r3, unsigned long r4) if (!BOOT_INFO_IS_V2_COMPATIBLE(bi)) bi->logicalDisplayBase = bi->dispDeviceBase; + /* Fixup depth 16 -> 15 as that's what MacOS calls 16bpp */ + if (bi->dispDeviceDepth == 16) + bi->dispDeviceDepth = 15; + + #ifdef CONFIG_BOOTX_TEXT + ptr = (unsigned long)bi->logicalDisplayBase; + ptr += bi->dispDeviceRect[1] * bi->dispDeviceRowBytes; + ptr += bi->dispDeviceRect[0] * ((bi->dispDeviceDepth + 7) / 8); btext_setup_display(bi->dispDeviceRect[2] - bi->dispDeviceRect[0], bi->dispDeviceRect[3] - bi->dispDeviceRect[1], bi->dispDeviceDepth, bi->dispDeviceRowBytes, @@ -478,6 +527,7 @@ void __init bootx_init(unsigned long r3, unsigned long r4) #ifdef CONFIG_BOOTX_TEXT btext_welcome(bi); #endif + /* New BootX enters kernel with MMU off, i/os are not allowed * here. This hack will have been done by the boostrap anyway. */ @@ -500,12 +550,12 @@ void __init bootx_init(unsigned long r3, unsigned long r4) */ if (bi->version < 5) { space = bi->deviceTreeOffset + bi->deviceTreeSize; - if (bi->ramDisk) + if (bi->ramDisk >= space) space = bi->ramDisk + bi->ramDiskSize; } else space = bi->totalParamsSize; - bootx_printf("Total space used by parameters & ramdisk: %x \n", space); + bootx_printf("Total space used by parameters & ramdisk: 0x%x \n", space); /* New BootX will have flushed all TLBs and enters kernel with * MMU switched OFF, so this should not be useful anymore. diff --git a/arch/powerpc/platforms/powermac/cache.S b/arch/powerpc/platforms/powermac/cache.S index fb977de6b704..6be1a4af3359 100644 --- a/arch/powerpc/platforms/powermac/cache.S +++ b/arch/powerpc/platforms/powermac/cache.S @@ -14,7 +14,6 @@ * */ -#include <linux/config.h> #include <asm/processor.h> #include <asm/ppc_asm.h> #include <asm/cputable.h> diff --git a/arch/powerpc/platforms/powermac/cpufreq_32.c b/arch/powerpc/platforms/powermac/cpufreq_32.c index af2a8f9f1222..c2b6b4134f68 100644 --- a/arch/powerpc/platforms/powermac/cpufreq_32.c +++ b/arch/powerpc/platforms/powermac/cpufreq_32.c @@ -13,7 +13,6 @@ * */ -#include <linux/config.h> #include <linux/module.h> #include <linux/types.h> #include <linux/errno.h> @@ -68,7 +67,7 @@ static unsigned int cur_freq; static unsigned int sleep_freq; /* - * Different models uses different mecanisms to switch the frequency + * Different models uses different mechanisms to switch the frequency */ static int (*set_speed_proc)(int low_speed); static unsigned int (*get_speed_proc)(void); @@ -268,7 +267,7 @@ static int pmu_set_cpu_speed(int low_speed) /* Make sure the decrementer won't interrupt us */ asm volatile("mtdec %0" : : "r" (0x7fffffff)); - /* Make sure any pending DEC interrupt occuring while we did + /* Make sure any pending DEC interrupt occurring while we did * the above didn't re-enable the DEC */ mb(); asm volatile("mtdec %0" : : "r" (0x7fffffff)); @@ -422,7 +421,7 @@ static int pmac_cpufreq_cpu_init(struct cpufreq_policy *policy) static u32 read_gpio(struct device_node *np) { - u32 *reg = (u32 *)get_property(np, "reg", NULL); + const u32 *reg = get_property(np, "reg", NULL); u32 offset; if (reg == NULL) @@ -498,7 +497,7 @@ static int pmac_cpufreq_init_MacRISC3(struct device_node *cpunode) "frequency-gpio"); struct device_node *slew_done_gpio_np = of_find_node_by_name(NULL, "slewing-done"); - u32 *value; + const u32 *value; /* * Check to see if it's GPIO driven or PMU only @@ -520,15 +519,15 @@ static int pmac_cpufreq_init_MacRISC3(struct device_node *cpunode) */ if (frequency_gpio && slew_done_gpio) { int lenp, rc; - u32 *freqs, *ratio; + const u32 *freqs, *ratio; - freqs = (u32 *)get_property(cpunode, "bus-frequencies", &lenp); + freqs = get_property(cpunode, "bus-frequencies", &lenp); lenp /= sizeof(u32); if (freqs == NULL || lenp != 2) { printk(KERN_ERR "cpufreq: bus-frequencies incorrect or missing\n"); return 1; } - ratio = (u32 *)get_property(cpunode, "processor-to-bus-ratio*2", NULL); + ratio = get_property(cpunode, "processor-to-bus-ratio*2", NULL); if (ratio == NULL) { printk(KERN_ERR "cpufreq: processor-to-bus-ratio*2 missing\n"); return 1; @@ -563,7 +562,7 @@ static int pmac_cpufreq_init_MacRISC3(struct device_node *cpunode) /* If we use the PMU, look for the min & max frequencies in the * device-tree */ - value = (u32 *)get_property(cpunode, "min-clock-frequency", NULL); + value = get_property(cpunode, "min-clock-frequency", NULL); if (!value) return 1; low_freq = (*value) / 1000; @@ -572,7 +571,7 @@ static int pmac_cpufreq_init_MacRISC3(struct device_node *cpunode) if (low_freq < 100000) low_freq *= 10; - value = (u32 *)get_property(cpunode, "max-clock-frequency", NULL); + value = get_property(cpunode, "max-clock-frequency", NULL); if (!value) return 1; hi_freq = (*value) / 1000; @@ -612,13 +611,14 @@ static int pmac_cpufreq_init_7447A(struct device_node *cpunode) static int pmac_cpufreq_init_750FX(struct device_node *cpunode) { struct device_node *volt_gpio_np; - u32 pvr, *value; + u32 pvr; + const u32 *value; if (get_property(cpunode, "dynamic-power-step", NULL) == NULL) return 1; hi_freq = cur_freq; - value = (u32 *)get_property(cpunode, "reduced-clock-frequency", NULL); + value = get_property(cpunode, "reduced-clock-frequency", NULL); if (!value) return 1; low_freq = (*value) / 1000; @@ -651,7 +651,7 @@ static int pmac_cpufreq_init_750FX(struct device_node *cpunode) static int __init pmac_cpufreq_setup(void) { struct device_node *cpunode; - u32 *value; + const u32 *value; if (strstr(cmd_line, "nocpufreq")) return 0; @@ -662,7 +662,7 @@ static int __init pmac_cpufreq_setup(void) goto out; /* Get current cpu clock freq */ - value = (u32 *)get_property(cpunode, "clock-frequency", NULL); + value = get_property(cpunode, "clock-frequency", NULL); if (!value) goto out; cur_freq = (*value) / 1000; diff --git a/arch/powerpc/platforms/powermac/cpufreq_64.c b/arch/powerpc/platforms/powermac/cpufreq_64.c index b57e465a1b71..d30466d74194 100644 --- a/arch/powerpc/platforms/powermac/cpufreq_64.c +++ b/arch/powerpc/platforms/powermac/cpufreq_64.c @@ -10,7 +10,8 @@ * that is iMac G5 and latest single CPU desktop. */ -#include <linux/config.h> +#undef DEBUG + #include <linux/module.h> #include <linux/types.h> #include <linux/errno.h> @@ -31,13 +32,7 @@ #include <asm/smu.h> #include <asm/pmac_pfunc.h> -#undef DEBUG - -#ifdef DEBUG -#define DBG(fmt...) printk(fmt) -#else -#define DBG(fmt...) -#endif +#define DBG(fmt...) pr_debug(fmt) /* see 970FX user manual */ @@ -83,8 +78,6 @@ static struct freq_attr* g5_cpu_freqs_attr[] = { /* Power mode data is an array of the 32 bits PCR values to use for * the various frequencies, retrieved from the device-tree */ -static u32 *g5_pmode_data; -static int g5_pmode_max; static int g5_pmode_cur; static void (*g5_switch_volt)(int speed_mode); @@ -94,6 +87,11 @@ static int (*g5_query_freq)(void); static DEFINE_MUTEX(g5_switch_mutex); +#ifdef CONFIG_PMAC_SMU + +static const u32 *g5_pmode_data; +static int g5_pmode_max; + static struct smu_sdbp_fvt *g5_fvt_table; /* table of op. points */ static int g5_fvt_count; /* number of op. points */ static int g5_fvt_cur; /* current op. point */ @@ -211,6 +209,16 @@ static int g5_scom_query_freq(void) } /* + * Fake voltage switching for platforms with missing support + */ + +static void g5_dummy_switch_volt(int speed_mode) +{ +} + +#endif /* CONFIG_PMAC_SMU */ + +/* * Platform function based voltage switching for PowerMac7,2 & 7,3 */ @@ -249,6 +257,9 @@ static int g5_pfunc_switch_freq(int speed_mode) struct pmf_args args; u32 done = 0; unsigned long timeout; + int rc; + + DBG("g5_pfunc_switch_freq(%d)\n", speed_mode); /* If frequency is going up, first ramp up the voltage */ if (speed_mode < g5_pmode_cur) @@ -256,9 +267,12 @@ static int g5_pfunc_switch_freq(int speed_mode) /* Do it */ if (speed_mode == CPUFREQ_HIGH) - pmf_call_one(pfunc_cpu_setfreq_high, NULL); + rc = pmf_call_one(pfunc_cpu_setfreq_high, NULL); else - pmf_call_one(pfunc_cpu_setfreq_low, NULL); + rc = pmf_call_one(pfunc_cpu_setfreq_low, NULL); + + if (rc) + printk(KERN_WARNING "cpufreq: pfunc switch error %d\n", rc); /* It's an irq GPIO so we should be able to just block here, * I'll do that later after I've properly tested the IRQ code for @@ -297,13 +311,6 @@ static int g5_pfunc_query_freq(void) return val ? CPUFREQ_HIGH : CPUFREQ_LOW; } -/* - * Fake voltage switching for platforms with missing support - */ - -static void g5_dummy_switch_volt(int speed_mode) -{ -} /* * Common interface to the cpufreq core @@ -376,13 +383,16 @@ static struct cpufreq_driver g5_cpufreq_driver = { }; +#ifdef CONFIG_PMAC_SMU + static int __init g5_neo2_cpufreq_init(struct device_node *cpus) { struct device_node *cpunode; unsigned int psize, ssize; unsigned long max_freq; char *freq_method, *volt_method; - u32 *valp, pvr_hi; + const u32 *valp; + u32 pvr_hi; int use_volts_vdnap = 0; int use_volts_smu = 0; int rc = -ENODEV; @@ -400,8 +410,7 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus) /* Get first CPU node */ for (cpunode = NULL; (cpunode = of_get_next_child(cpus, cpunode)) != NULL;) { - u32 *reg = - (u32 *)get_property(cpunode, "reg", NULL); + const u32 *reg = get_property(cpunode, "reg", NULL); if (reg == NULL || (*reg) != 0) continue; if (!strcmp(cpunode->type, "cpu")) @@ -413,7 +422,7 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus) } /* Check 970FX for now */ - valp = (u32 *)get_property(cpunode, "cpu-version", NULL); + valp = get_property(cpunode, "cpu-version", NULL); if (!valp) { DBG("No cpu-version property !\n"); goto bail_noprops; @@ -425,7 +434,7 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus) } /* Look for the powertune data in the device-tree */ - g5_pmode_data = (u32 *)get_property(cpunode, "power-mode-data",&psize); + g5_pmode_data = get_property(cpunode, "power-mode-data",&psize); if (!g5_pmode_data) { DBG("No power-mode-data !\n"); goto bail_noprops; @@ -433,7 +442,7 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus) g5_pmode_max = psize / sizeof(u32) - 1; if (use_volts_smu) { - struct smu_sdbp_header *shdr; + const struct smu_sdbp_header *shdr; /* Look for the FVT table */ shdr = smu_get_sdb_partition(SMU_SDB_FVT_ID, NULL); @@ -484,7 +493,7 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus) * half freq in this version. So far, I haven't yet seen a machine * supporting anything else. */ - valp = (u32 *)get_property(cpunode, "clock-frequency", NULL); + valp = get_property(cpunode, "clock-frequency", NULL); if (!valp) return -ENODEV; max_freq = (*valp)/1000; @@ -526,14 +535,20 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus) return rc; } +#endif /* CONFIG_PMAC_SMU */ + + static int __init g5_pm72_cpufreq_init(struct device_node *cpus) { struct device_node *cpuid = NULL, *hwclock = NULL, *cpunode = NULL; - u8 *eeprom = NULL; - u32 *valp; + const u8 *eeprom = NULL; + const u32 *valp; u64 max_freq, min_freq, ih, il; int has_volt = 1, rc = 0; + DBG("cpufreq: Initializing for PowerMac7,2, PowerMac7,3 and" + " RackMac3,1...\n"); + /* Get first CPU node */ for (cpunode = NULL; (cpunode = of_get_next_child(cpus, cpunode)) != NULL;) { @@ -548,7 +563,7 @@ static int __init g5_pm72_cpufreq_init(struct device_node *cpus) /* Lookup the cpuid eeprom node */ cpuid = of_find_node_by_path("/u3@0,f8000000/i2c@f8001000/cpuid@a0"); if (cpuid != NULL) - eeprom = (u8 *)get_property(cpuid, "cpuid", NULL); + eeprom = get_property(cpuid, "cpuid", NULL); if (eeprom == NULL) { printk(KERN_ERR "cpufreq: Can't find cpuid EEPROM !\n"); rc = -ENODEV; @@ -558,7 +573,8 @@ static int __init g5_pm72_cpufreq_init(struct device_node *cpus) /* Lookup the i2c hwclock */ for (hwclock = NULL; (hwclock = of_find_node_by_name(hwclock, "i2c-hwclock")) != NULL;){ - char *loc = get_property(hwclock, "hwctrl-location", NULL); + const char *loc = get_property(hwclock, + "hwctrl-location", NULL); if (loc == NULL) continue; if (strcmp(loc, "CPU CLOCK")) @@ -622,7 +638,7 @@ static int __init g5_pm72_cpufreq_init(struct device_node *cpus) */ /* Get max frequency from device-tree */ - valp = (u32 *)get_property(cpunode, "clock-frequency", NULL); + valp = get_property(cpunode, "clock-frequency", NULL); if (!valp) { printk(KERN_ERR "cpufreq: Can't find CPU frequency !\n"); rc = -ENODEV; @@ -637,6 +653,15 @@ static int __init g5_pm72_cpufreq_init(struct device_node *cpus) */ ih = *((u32 *)(eeprom + 0x10)); il = *((u32 *)(eeprom + 0x20)); + + /* Check for machines with no useful settings */ + if (il == ih) { + printk(KERN_WARNING "cpufreq: No low frequency mode available" + " on this model !\n"); + rc = -ENODEV; + goto bail; + } + min_freq = 0; if (ih != 0 && il != 0) min_freq = (max_freq * il) / ih; @@ -644,7 +669,7 @@ static int __init g5_pm72_cpufreq_init(struct device_node *cpus) /* Sanity check */ if (min_freq >= max_freq || min_freq < 1000) { printk(KERN_ERR "cpufreq: Can't calculate low frequency !\n"); - rc = -ENODEV; + rc = -ENXIO; goto bail; } g5_cpu_freqs[0].frequency = max_freq; @@ -691,16 +716,10 @@ static int __init g5_pm72_cpufreq_init(struct device_node *cpus) return rc; } -static int __init g5_rm31_cpufreq_init(struct device_node *cpus) -{ - /* NYI */ - return 0; -} - static int __init g5_cpufreq_init(void) { struct device_node *cpus; - int rc; + int rc = 0; cpus = of_find_node_by_path("/cpus"); if (cpus == NULL) { @@ -709,12 +728,13 @@ static int __init g5_cpufreq_init(void) } if (machine_is_compatible("PowerMac7,2") || - machine_is_compatible("PowerMac7,3")) + machine_is_compatible("PowerMac7,3") || + machine_is_compatible("RackMac3,1")) rc = g5_pm72_cpufreq_init(cpus); - else if (machine_is_compatible("RackMac3,1")) - rc = g5_rm31_cpufreq_init(cpus); +#ifdef CONFIG_PMAC_SMU else rc = g5_neo2_cpufreq_init(cpus); +#endif /* CONFIG_PMAC_SMU */ of_node_put(cpus); return rc; diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c index 85e00cb0006e..e49621be6640 100644 --- a/arch/powerpc/platforms/powermac/feature.c +++ b/arch/powerpc/platforms/powermac/feature.c @@ -16,7 +16,6 @@ * - Split split split... * */ -#include <linux/config.h> #include <linux/types.h> #include <linux/init.h> #include <linux/delay.h> @@ -1059,8 +1058,8 @@ core99_reset_cpu(struct device_node *node, long param, long value) if (np == NULL) return -ENODEV; for (np = np->child; np != NULL; np = np->sibling) { - u32 *num = (u32 *)get_property(np, "reg", NULL); - u32 *rst = (u32 *)get_property(np, "soft-reset", NULL); + const u32 *num = get_property(np, "reg", NULL); + const u32 *rst = get_property(np, "soft-reset", NULL); if (num == NULL || rst == NULL) continue; if (param == *num) { @@ -1088,7 +1087,7 @@ core99_usb_enable(struct device_node *node, long param, long value) { struct macio_chip *macio; unsigned long flags; - char *prop; + const char *prop; int number; u32 reg; @@ -1097,7 +1096,7 @@ core99_usb_enable(struct device_node *node, long param, long value) macio->type != macio_intrepid) return -ENODEV; - prop = (char *)get_property(node, "AAPL,clock-id", NULL); + prop = get_property(node, "AAPL,clock-id", NULL); if (!prop) return -ENODEV; if (strncmp(prop, "usb0u048", 8) == 0) @@ -1508,8 +1507,8 @@ static long g5_reset_cpu(struct device_node *node, long param, long value) if (np == NULL) return -ENODEV; for (np = np->child; np != NULL; np = np->sibling) { - u32 *num = (u32 *)get_property(np, "reg", NULL); - u32 *rst = (u32 *)get_property(np, "soft-reset", NULL); + const u32 *num = get_property(np, "reg", NULL); + const u32 *rst = get_property(np, "soft-reset", NULL); if (num == NULL || rst == NULL) continue; if (param == *num) { @@ -2409,7 +2408,7 @@ static int __init probe_motherboard(void) */ dt = find_devices("device-tree"); if (dt != NULL) - model = (const char *) get_property(dt, "model", NULL); + model = get_property(dt, "model", NULL); for(i=0; model && i<(sizeof(pmac_mb_defs)/sizeof(struct pmac_mb_def)); i++) { if (strcmp(model, pmac_mb_defs[i].model_string) == 0) { pmac_mb = pmac_mb_defs[i]; @@ -2537,7 +2536,7 @@ found: */ static void __init probe_uninorth(void) { - u32 *addrp; + const u32 *addrp; phys_addr_t address; unsigned long actrl; @@ -2556,7 +2555,7 @@ static void __init probe_uninorth(void) if (uninorth_node == NULL) return; - addrp = (u32 *)get_property(uninorth_node, "reg", NULL); + addrp = get_property(uninorth_node, "reg", NULL); if (addrp == NULL) return; address = of_translate_address(uninorth_node, addrp); @@ -2597,7 +2596,7 @@ static void __init probe_one_macio(const char *name, const char *compat, int typ struct device_node* node; int i; volatile u32 __iomem *base; - u32 *addrp, *revp; + const u32 *addrp, *revp; phys_addr_t addr; u64 size; @@ -2640,7 +2639,7 @@ static void __init probe_one_macio(const char *name, const char *compat, int typ return; } if (type == macio_keylargo || type == macio_keylargo2) { - u32 *did = (u32 *)get_property(node, "device-id", NULL); + const u32 *did = get_property(node, "device-id", NULL); if (*did == 0x00000025) type = macio_pangea; if (*did == 0x0000003e) @@ -2653,7 +2652,7 @@ static void __init probe_one_macio(const char *name, const char *compat, int typ macio_chips[i].base = base; macio_chips[i].flags = MACIO_FLAG_SCCB_ON | MACIO_FLAG_SCCB_ON; macio_chips[i].name = macio_names[type]; - revp = (u32 *)get_property(node, "revision-id", NULL); + revp = get_property(node, "revision-id", NULL); if (revp) macio_chips[i].rev = *revp; printk(KERN_INFO "Found a %s mac-io controller, rev: %d, mapped at 0x%p\n", @@ -2696,15 +2695,15 @@ static void __init initial_serial_shutdown(struct device_node *np) { int len; - struct slot_names_prop { + const struct slot_names_prop { int count; char name[1]; } *slots; - char *conn; + const char *conn; int port_type = PMAC_SCC_ASYNC; int modem = 0; - slots = (struct slot_names_prop *)get_property(np, "slot-names", &len); + slots = get_property(np, "slot-names", &len); conn = get_property(np, "AAPL,connector", &len); if (conn && (strcmp(conn, "infrared") == 0)) port_type = PMAC_SCC_IRDA; diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c index c896ce83d412..c2c7cf75dd5f 100644 --- a/arch/powerpc/platforms/powermac/low_i2c.c +++ b/arch/powerpc/platforms/powermac/low_i2c.c @@ -30,7 +30,6 @@ #undef DEBUG #undef DEBUG_LOW -#include <linux/config.h> #include <linux/types.h> #include <linux/sched.h> #include <linux/init.h> @@ -478,7 +477,8 @@ static int kw_i2c_xfer(struct pmac_i2c_bus *bus, u8 addrdir, int subsize, static struct pmac_i2c_host_kw *__init kw_i2c_host_init(struct device_node *np) { struct pmac_i2c_host_kw *host; - u32 *psteps, *prate, *addrp, steps; + const u32 *psteps, *prate, *addrp; + u32 steps; host = kzalloc(sizeof(struct pmac_i2c_host_kw), GFP_KERNEL); if (host == NULL) { @@ -491,7 +491,7 @@ static struct pmac_i2c_host_kw *__init kw_i2c_host_init(struct device_node *np) * on all i2c keywest nodes so far ... we would have to fallback * to macio parsing if that wasn't the case */ - addrp = (u32 *)get_property(np, "AAPL,address", NULL); + addrp = get_property(np, "AAPL,address", NULL); if (addrp == NULL) { printk(KERN_ERR "low_i2c: Can't find address for %s\n", np->full_name); @@ -505,13 +505,13 @@ static struct pmac_i2c_host_kw *__init kw_i2c_host_init(struct device_node *np) host->timeout_timer.function = kw_i2c_timeout; host->timeout_timer.data = (unsigned long)host; - psteps = (u32 *)get_property(np, "AAPL,address-step", NULL); + psteps = get_property(np, "AAPL,address-step", NULL); steps = psteps ? (*psteps) : 0x10; for (host->bsteps = 0; (steps & 0x01) == 0; host->bsteps++) steps >>= 1; /* Select interface rate */ host->speed = KW_I2C_MODE_25KHZ; - prate = (u32 *)get_property(np, "AAPL,i2c-rate", NULL); + prate = get_property(np, "AAPL,i2c-rate", NULL); if (prate) switch(*prate) { case 100: host->speed = KW_I2C_MODE_100KHZ; @@ -523,10 +523,11 @@ static struct pmac_i2c_host_kw *__init kw_i2c_host_init(struct device_node *np) host->speed = KW_I2C_MODE_25KHZ; break; } - if (np->n_intrs > 0) - host->irq = np->intrs[0].line; - else - host->irq = NO_IRQ; + host->irq = irq_of_parse_and_map(np, 0); + if (host->irq == NO_IRQ) + printk(KERN_WARNING + "low_i2c: Failed to map interrupt for %s\n", + np->full_name); host->base = ioremap((*addrp), 0x1000); if (host->base == NULL) { @@ -618,8 +619,8 @@ static void __init kw_i2c_probe(void) } else { for (child = NULL; (child = of_get_next_child(np, child)) != NULL;) { - u32 *reg = - (u32 *)get_property(child, "reg", NULL); + const u32 *reg = get_property(child, + "reg", NULL); if (reg == NULL) continue; kw_i2c_add(host, np, child, *reg); @@ -881,7 +882,7 @@ static void __init smu_i2c_probe(void) { struct device_node *controller, *busnode; struct pmac_i2c_bus *bus; - u32 *reg; + const u32 *reg; int sz; if (!smu_present()) @@ -904,7 +905,7 @@ static void __init smu_i2c_probe(void) if (strcmp(busnode->type, "i2c") && strcmp(busnode->type, "i2c-bus")) continue; - reg = (u32 *)get_property(busnode, "reg", NULL); + reg = get_property(busnode, "reg", NULL); if (reg == NULL) continue; @@ -948,9 +949,8 @@ struct pmac_i2c_bus *pmac_i2c_find_bus(struct device_node *node) list_for_each_entry(bus, &pmac_i2c_busses, link) { if (p == bus->busnode) { if (prev && bus->flags & pmac_i2c_multibus) { - u32 *reg; - reg = (u32 *)get_property(prev, "reg", - NULL); + const u32 *reg; + reg = get_property(prev, "reg", NULL); if (!reg) continue; if (((*reg) >> 8) != bus->channel) @@ -971,7 +971,7 @@ EXPORT_SYMBOL_GPL(pmac_i2c_find_bus); u8 pmac_i2c_get_dev_addr(struct device_node *device) { - u32 *reg = (u32 *)get_property(device, "reg", NULL); + const u32 *reg = get_property(device, "reg", NULL); if (reg == NULL) return 0; diff --git a/arch/powerpc/platforms/powermac/nvram.c b/arch/powerpc/platforms/powermac/nvram.c index 262f967b880a..6a36ea9bf673 100644 --- a/arch/powerpc/platforms/powermac/nvram.c +++ b/arch/powerpc/platforms/powermac/nvram.c @@ -8,7 +8,6 @@ * * Todo: - add support for the OF persistent properties */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/stddef.h> @@ -30,6 +29,8 @@ #include <asm/machdep.h> #include <asm/nvram.h> +#include "pmac.h" + #define DEBUG #ifdef DEBUG @@ -81,9 +82,6 @@ static int nvram_partitions[3]; // XXX Turn that into a sem static DEFINE_SPINLOCK(nv_lock); -extern int pmac_newworld; -extern int system_running; - static int (*core99_write_bank)(int bank, u8* datas); static int (*core99_erase_bank)(int bank); diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c index 80035853467b..9923adc5248e 100644 --- a/arch/powerpc/platforms/powermac/pci.c +++ b/arch/powerpc/platforms/powermac/pci.c @@ -16,6 +16,7 @@ #include <linux/string.h> #include <linux/init.h> #include <linux/bootmem.h> +#include <linux/irq.h> #include <asm/sections.h> #include <asm/io.h> @@ -24,10 +25,7 @@ #include <asm/machdep.h> #include <asm/pmac_feature.h> #include <asm/grackle.h> -#ifdef CONFIG_PPC64 -//#include <asm/iommu.h> #include <asm/ppc-pci.h> -#endif #undef DEBUG @@ -46,6 +44,8 @@ static int has_uninorth; static struct pci_controller *u3_agp; static struct pci_controller *u4_pcie; static struct pci_controller *u3_ht; +#else +static int has_second_ohare; #endif /* CONFIG_PPC64 */ extern u8 pci_cache_line_size; @@ -66,16 +66,16 @@ struct device_node *k2_skiplist[2]; static int __init fixup_one_level_bus_range(struct device_node *node, int higher) { for (; node != 0;node = node->sibling) { - int * bus_range; - unsigned int *class_code; + const int * bus_range; + const unsigned int *class_code; int len; /* For PCI<->PCI bridges or CardBus bridges, we go down */ - class_code = (unsigned int *) get_property(node, "class-code", NULL); + class_code = get_property(node, "class-code", NULL); if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) continue; - bus_range = (int *) get_property(node, "bus-range", &len); + bus_range = get_property(node, "bus-range", &len); if (bus_range != NULL && len > 2 * sizeof(int)) { if (bus_range[1] > higher) higher = bus_range[1]; @@ -93,13 +93,15 @@ static int __init fixup_one_level_bus_range(struct device_node *node, int higher */ static void __init fixup_bus_range(struct device_node *bridge) { - int * bus_range; - int len; + int *bus_range, len; + struct property *prop; /* Lookup the "bus-range" property for the hose */ - bus_range = (int *) get_property(bridge, "bus-range", &len); - if (bus_range == NULL || len < 2 * sizeof(int)) + prop = of_find_property(bridge, "bus-range", &len); + if (prop == NULL || prop->length < 2 * sizeof(int)) return; + + bus_range = (int *)prop->value; bus_range[1] = fixup_one_level_bus_range(bridge->child, bus_range[1]); } @@ -237,7 +239,7 @@ static struct pci_ops macrisc_pci_ops = static int chaos_validate_dev(struct pci_bus *bus, int devfn, int offset) { struct device_node *np; - u32 *vendor, *device; + const u32 *vendor, *device; if (offset >= 0x100) return PCIBIOS_BAD_REGISTER_NUMBER; @@ -245,8 +247,8 @@ static int chaos_validate_dev(struct pci_bus *bus, int devfn, int offset) if (np == NULL) return PCIBIOS_DEVICE_NOT_FOUND; - vendor = (u32 *)get_property(np, "vendor-id", NULL); - device = (u32 *)get_property(np, "device-id", NULL); + vendor = get_property(np, "vendor-id", NULL); + device = get_property(np, "device-id", NULL); if (vendor == NULL || device == NULL) return PCIBIOS_DEVICE_NOT_FOUND; @@ -647,6 +649,33 @@ static void __init init_p2pbridge(void) early_write_config_word(hose, bus, devfn, PCI_BRIDGE_CONTROL, val); } +static void __init init_second_ohare(void) +{ + struct device_node *np = of_find_node_by_name(NULL, "pci106b,7"); + unsigned char bus, devfn; + unsigned short cmd; + + if (np == NULL) + return; + + /* This must run before we initialize the PICs since the second + * ohare hosts a PIC that will be accessed there. + */ + if (pci_device_from_OF_node(np, &bus, &devfn) == 0) { + struct pci_controller* hose = + pci_find_hose_for_OF_device(np); + if (!hose) { + printk(KERN_ERR "Can't find PCI hose for OHare2 !\n"); + return; + } + early_read_config_word(hose, bus, devfn, PCI_COMMAND, &cmd); + cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; + cmd &= ~PCI_COMMAND_IO; + early_write_config_word(hose, bus, devfn, PCI_COMMAND, cmd); + } + has_second_ohare = 1; +} + /* * Some Apple desktop machines have a NEC PD720100A USB2 controller * on the motherboard. Open Firmware, on these, will disable the @@ -659,20 +688,21 @@ static void __init fixup_nec_usb2(void) for (nec = NULL; (nec = of_find_node_by_name(nec, "usb")) != NULL;) { struct pci_controller *hose; - u32 data, *prop; + u32 data; + const u32 *prop; u8 bus, devfn; - prop = (u32 *)get_property(nec, "vendor-id", NULL); + prop = get_property(nec, "vendor-id", NULL); if (prop == NULL) continue; if (0x1033 != *prop) continue; - prop = (u32 *)get_property(nec, "device-id", NULL); + prop = get_property(nec, "device-id", NULL); if (prop == NULL) continue; if (0x0035 != *prop) continue; - prop = (u32 *)get_property(nec, "reg", NULL); + prop = get_property(nec, "reg", NULL); if (prop == NULL) continue; devfn = (prop[0] >> 8) & 0xff; @@ -688,9 +718,6 @@ static void __init fixup_nec_usb2(void) " EHCI, fixing up...\n"); data &= ~1UL; early_write_config_dword(hose, bus, devfn, 0xe4, data); - early_write_config_byte(hose, bus, - devfn | 2, PCI_INTERRUPT_LINE, - nec->intrs[0].line); } } } @@ -874,7 +901,7 @@ static int __init add_bridge(struct device_node *dev) struct pci_controller *hose; struct resource rsrc; char *disp_name; - int *bus_range; + const int *bus_range; int primary = 1, has_address = 0; DBG("Adding PCI host bridge %s\n", dev->full_name); @@ -883,7 +910,7 @@ static int __init add_bridge(struct device_node *dev) has_address = (of_address_to_resource(dev, 0, &rsrc) == 0); /* Get bus range if any */ - bus_range = (int *) get_property(dev, "bus-range", &len); + bus_range = get_property(dev, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) { printk(KERN_WARNING "Can't get bus-range for %s, assume" " bus 0\n", dev->full_name); @@ -939,9 +966,10 @@ static int __init add_bridge(struct device_node *dev) disp_name = "Chaos"; primary = 0; } - printk(KERN_INFO "Found %s PCI host bridge at 0x%08lx. " + printk(KERN_INFO "Found %s PCI host bridge at 0x%016llx. " "Firmware bus number: %d->%d\n", - disp_name, rsrc.start, hose->first_busno, hose->last_busno); + disp_name, (unsigned long long)rsrc.start, hose->first_busno, + hose->last_busno); #endif /* CONFIG_PPC32 */ DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n", @@ -957,30 +985,30 @@ static int __init add_bridge(struct device_node *dev) return 0; } -static void __init pcibios_fixup_OF_interrupts(void) +void __init pmac_pcibios_fixup(void) { struct pci_dev* dev = NULL; - /* - * Open Firmware often doesn't initialize the - * PCI_INTERRUPT_LINE config register properly, so we - * should find the device node and apply the interrupt - * obtained from the OF device-tree - */ for_each_pci_dev(dev) { - struct device_node *node; - node = pci_device_to_OF_node(dev); - /* this is the node, see if it has interrupts */ - if (node && node->n_intrs > 0) - dev->irq = node->intrs[0].line; - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); - } -} + /* Read interrupt from the device-tree */ + pci_read_irq_line(dev); -void __init pmac_pcibios_fixup(void) -{ - /* Fixup interrupts according to OF tree */ - pcibios_fixup_OF_interrupts(); +#ifdef CONFIG_PPC32 + /* Fixup interrupt for the modem/ethernet combo controller. + * on machines with a second ohare chip. + * The number in the device tree (27) is bogus (correct for + * the ethernet-only board but not the combo ethernet/modem + * board). The real interrupt is 28 on the second controller + * -> 28+32 = 60. + */ + if (has_second_ohare && + dev->vendor == PCI_VENDOR_ID_DEC && + dev->device == PCI_DEVICE_ID_DEC_TULIP_PLUS) { + dev->irq = irq_create_mapping(NULL, 60); + set_irq_type(dev->irq, IRQ_TYPE_LEVEL_LOW); + } +#endif /* CONFIG_PPC32 */ + } } #ifdef CONFIG_PPC64 @@ -1070,6 +1098,7 @@ void __init pmac_pci_init(void) #else /* CONFIG_PPC64 */ init_p2pbridge(); + init_second_ohare(); fixup_nec_usb2(); /* We are still having some issues with the Xserve G4, enabling diff --git a/arch/powerpc/platforms/powermac/pfunc_base.c b/arch/powerpc/platforms/powermac/pfunc_base.c index a3bd3e728fa3..ee3b223ab17a 100644 --- a/arch/powerpc/platforms/powermac/pfunc_base.c +++ b/arch/powerpc/platforms/powermac/pfunc_base.c @@ -1,4 +1,3 @@ -#include <linux/config.h> #include <linux/types.h> #include <linux/init.h> #include <linux/delay.h> @@ -25,19 +24,18 @@ static irqreturn_t macio_gpio_irq(int irq, void *data, struct pt_regs *regs) static int macio_do_gpio_irq_enable(struct pmf_function *func) { - if (func->node->n_intrs < 1) + unsigned int irq = irq_of_parse_and_map(func->node, 0); + if (irq == NO_IRQ) return -EINVAL; - - return request_irq(func->node->intrs[0].line, macio_gpio_irq, 0, - func->node->name, func); + return request_irq(irq, macio_gpio_irq, 0, func->node->name, func); } static int macio_do_gpio_irq_disable(struct pmf_function *func) { - if (func->node->n_intrs < 1) + unsigned int irq = irq_of_parse_and_map(func->node, 0); + if (irq == NO_IRQ) return -EINVAL; - - free_irq(func->node->intrs[0].line, func); + free_irq(irq, func); return 0; } @@ -116,7 +114,7 @@ static void macio_gpio_init_one(struct macio_chip *macio) * we just create them all */ for (gp = NULL; (gp = of_get_next_child(gparent, gp)) != NULL;) { - u32 *reg = (u32 *)get_property(gp, "reg", NULL); + const u32 *reg = get_property(gp, "reg", NULL); unsigned long offset; if (reg == NULL) continue; @@ -258,7 +256,7 @@ static struct pmf_handlers macio_mmio_handlers = { .write_reg32 = macio_do_write_reg32, .read_reg32 = macio_do_read_reg32, .write_reg8 = macio_do_write_reg8, - .read_reg32 = macio_do_read_reg8, + .read_reg8 = macio_do_read_reg8, .read_reg32_msrx = macio_do_read_reg32_msrx, .read_reg8_msrx = macio_do_read_reg8_msrx, .write_reg32_slm = macio_do_write_reg32_slm, diff --git a/arch/powerpc/platforms/powermac/pfunc_core.c b/arch/powerpc/platforms/powermac/pfunc_core.c index 047f954a89eb..7651f278615a 100644 --- a/arch/powerpc/platforms/powermac/pfunc_core.c +++ b/arch/powerpc/platforms/powermac/pfunc_core.c @@ -5,7 +5,6 @@ * FIXME: LOCKING !!! */ -#include <linux/config.h> #include <linux/init.h> #include <linux/delay.h> #include <linux/kernel.h> @@ -546,7 +545,7 @@ struct pmf_device { }; static LIST_HEAD(pmf_devices); -static spinlock_t pmf_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(pmf_lock); static DEFINE_MUTEX(pmf_irq_mutex); static void pmf_release_device(struct kref *kref) @@ -814,14 +813,15 @@ struct pmf_function *__pmf_find_function(struct device_node *target, struct pmf_device *dev; struct pmf_function *func, *result = NULL; char fname[64]; - u32 *prop, ph; + const u32 *prop; + u32 ph; /* * Look for a "platform-*" function reference. If we can't find * one, then we fallback to a direct call attempt */ snprintf(fname, 63, "platform-%s", name); - prop = (u32 *)get_property(target, fname, NULL); + prop = get_property(target, fname, NULL); if (prop == NULL) goto find_it; ph = *prop; diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c index 18bf3011d1e3..39f7ddb554ea 100644 --- a/arch/powerpc/platforms/powermac/pic.c +++ b/arch/powerpc/platforms/powermac/pic.c @@ -15,7 +15,6 @@ * */ -#include <linux/config.h> #include <linux/stddef.h> #include <linux/init.h> #include <linux/sched.h> @@ -66,39 +65,36 @@ static u32 level_mask[4]; static DEFINE_SPINLOCK(pmac_pic_lock); -#define GATWICK_IRQ_POOL_SIZE 10 -static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE]; - #define NR_MASK_WORDS ((NR_IRQS + 31) / 32) static unsigned long ppc_lost_interrupts[NR_MASK_WORDS]; +static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; +static int pmac_irq_cascade = -1; +static struct irq_host *pmac_pic_host; -/* - * Mark an irq as "lost". This is only used on the pmac - * since it can lose interrupts (see pmac_set_irq_mask). - * -- Cort - */ -void __set_lost(unsigned long irq_nr, int nokick) +static void __pmac_retrigger(unsigned int irq_nr) { - if (!test_and_set_bit(irq_nr, ppc_lost_interrupts)) { + if (irq_nr >= max_real_irqs && pmac_irq_cascade > 0) { + __set_bit(irq_nr, ppc_lost_interrupts); + irq_nr = pmac_irq_cascade; + mb(); + } + if (!__test_and_set_bit(irq_nr, ppc_lost_interrupts)) { atomic_inc(&ppc_n_lost_interrupts); - if (!nokick) - set_dec(1); + set_dec(1); } } -static void pmac_mask_and_ack_irq(unsigned int irq_nr) +static void pmac_mask_and_ack_irq(unsigned int virq) { - unsigned long bit = 1UL << (irq_nr & 0x1f); - int i = irq_nr >> 5; + unsigned int src = irq_map[virq].hwirq; + unsigned long bit = 1UL << (src & 0x1f); + int i = src >> 5; unsigned long flags; - if ((unsigned)irq_nr >= max_irqs) - return; - - clear_bit(irq_nr, ppc_cached_irq_mask); - if (test_and_clear_bit(irq_nr, ppc_lost_interrupts)) - atomic_dec(&ppc_n_lost_interrupts); spin_lock_irqsave(&pmac_pic_lock, flags); + __clear_bit(src, ppc_cached_irq_mask); + if (__test_and_clear_bit(src, ppc_lost_interrupts)) + atomic_dec(&ppc_n_lost_interrupts); out_le32(&pmac_irq_hw[i]->enable, ppc_cached_irq_mask[i]); out_le32(&pmac_irq_hw[i]->ack, bit); do { @@ -110,16 +106,29 @@ static void pmac_mask_and_ack_irq(unsigned int irq_nr) spin_unlock_irqrestore(&pmac_pic_lock, flags); } -static void pmac_set_irq_mask(unsigned int irq_nr, int nokicklost) +static void pmac_ack_irq(unsigned int virq) +{ + unsigned int src = irq_map[virq].hwirq; + unsigned long bit = 1UL << (src & 0x1f); + int i = src >> 5; + unsigned long flags; + + spin_lock_irqsave(&pmac_pic_lock, flags); + if (__test_and_clear_bit(src, ppc_lost_interrupts)) + atomic_dec(&ppc_n_lost_interrupts); + out_le32(&pmac_irq_hw[i]->ack, bit); + (void)in_le32(&pmac_irq_hw[i]->ack); + spin_unlock_irqrestore(&pmac_pic_lock, flags); +} + +static void __pmac_set_irq_mask(unsigned int irq_nr, int nokicklost) { unsigned long bit = 1UL << (irq_nr & 0x1f); int i = irq_nr >> 5; - unsigned long flags; if ((unsigned)irq_nr >= max_irqs) return; - spin_lock_irqsave(&pmac_pic_lock, flags); /* enable unmasked interrupts */ out_le32(&pmac_irq_hw[i]->enable, ppc_cached_irq_mask[i]); @@ -136,71 +145,78 @@ static void pmac_set_irq_mask(unsigned int irq_nr, int nokicklost) * the bit in the flag register or request another interrupt. */ if (bit & ppc_cached_irq_mask[i] & in_le32(&pmac_irq_hw[i]->level)) - __set_lost((ulong)irq_nr, nokicklost); - spin_unlock_irqrestore(&pmac_pic_lock, flags); + __pmac_retrigger(irq_nr); } /* When an irq gets requested for the first client, if it's an * edge interrupt, we clear any previous one on the controller */ -static unsigned int pmac_startup_irq(unsigned int irq_nr) +static unsigned int pmac_startup_irq(unsigned int virq) { - unsigned long bit = 1UL << (irq_nr & 0x1f); - int i = irq_nr >> 5; + unsigned long flags; + unsigned int src = irq_map[virq].hwirq; + unsigned long bit = 1UL << (src & 0x1f); + int i = src >> 5; - if ((irq_desc[irq_nr].status & IRQ_LEVEL) == 0) + spin_lock_irqsave(&pmac_pic_lock, flags); + if ((irq_desc[virq].status & IRQ_LEVEL) == 0) out_le32(&pmac_irq_hw[i]->ack, bit); - set_bit(irq_nr, ppc_cached_irq_mask); - pmac_set_irq_mask(irq_nr, 0); + __set_bit(src, ppc_cached_irq_mask); + __pmac_set_irq_mask(src, 0); + spin_unlock_irqrestore(&pmac_pic_lock, flags); return 0; } -static void pmac_mask_irq(unsigned int irq_nr) +static void pmac_mask_irq(unsigned int virq) { - clear_bit(irq_nr, ppc_cached_irq_mask); - pmac_set_irq_mask(irq_nr, 0); - mb(); + unsigned long flags; + unsigned int src = irq_map[virq].hwirq; + + spin_lock_irqsave(&pmac_pic_lock, flags); + __clear_bit(src, ppc_cached_irq_mask); + __pmac_set_irq_mask(src, 1); + spin_unlock_irqrestore(&pmac_pic_lock, flags); } -static void pmac_unmask_irq(unsigned int irq_nr) +static void pmac_unmask_irq(unsigned int virq) { - set_bit(irq_nr, ppc_cached_irq_mask); - pmac_set_irq_mask(irq_nr, 0); + unsigned long flags; + unsigned int src = irq_map[virq].hwirq; + + spin_lock_irqsave(&pmac_pic_lock, flags); + __set_bit(src, ppc_cached_irq_mask); + __pmac_set_irq_mask(src, 0); + spin_unlock_irqrestore(&pmac_pic_lock, flags); } -static void pmac_end_irq(unsigned int irq_nr) +static int pmac_retrigger(unsigned int virq) { - if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS)) - && irq_desc[irq_nr].action) { - set_bit(irq_nr, ppc_cached_irq_mask); - pmac_set_irq_mask(irq_nr, 1); - } -} + unsigned long flags; + spin_lock_irqsave(&pmac_pic_lock, flags); + __pmac_retrigger(irq_map[virq].hwirq); + spin_unlock_irqrestore(&pmac_pic_lock, flags); + return 1; +} -struct hw_interrupt_type pmac_pic = { +static struct irq_chip pmac_pic = { .typename = " PMAC-PIC ", .startup = pmac_startup_irq, - .enable = pmac_unmask_irq, - .disable = pmac_mask_irq, - .ack = pmac_mask_and_ack_irq, - .end = pmac_end_irq, -}; - -struct hw_interrupt_type gatwick_pic = { - .typename = " GATWICK ", - .startup = pmac_startup_irq, - .enable = pmac_unmask_irq, - .disable = pmac_mask_irq, - .ack = pmac_mask_and_ack_irq, - .end = pmac_end_irq, + .mask = pmac_mask_irq, + .ack = pmac_ack_irq, + .mask_ack = pmac_mask_and_ack_irq, + .unmask = pmac_unmask_irq, + .retrigger = pmac_retrigger, }; static irqreturn_t gatwick_action(int cpl, void *dev_id, struct pt_regs *regs) { + unsigned long flags; int irq, bits; + int rc = IRQ_NONE; + spin_lock_irqsave(&pmac_pic_lock, flags); for (irq = max_irqs; (irq -= 32) >= max_real_irqs; ) { int i = irq >> 5; bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i]; @@ -210,17 +226,20 @@ static irqreturn_t gatwick_action(int cpl, void *dev_id, struct pt_regs *regs) if (bits == 0) continue; irq += __ilog2(bits); + spin_unlock_irqrestore(&pmac_pic_lock, flags); __do_IRQ(irq, regs); - return IRQ_HANDLED; + spin_lock_irqsave(&pmac_pic_lock, flags); + rc = IRQ_HANDLED; } - printk("gatwick irq not from gatwick pic\n"); - return IRQ_NONE; + spin_unlock_irqrestore(&pmac_pic_lock, flags); + return rc; } -static int pmac_get_irq(struct pt_regs *regs) +static unsigned int pmac_pic_get_irq(struct pt_regs *regs) { int irq; unsigned long bits = 0; + unsigned long flags; #ifdef CONFIG_SMP void psurge_smp_message_recv(struct pt_regs *); @@ -228,9 +247,10 @@ static int pmac_get_irq(struct pt_regs *regs) /* IPI's are a hack on the powersurge -- Cort */ if ( smp_processor_id() != 0 ) { psurge_smp_message_recv(regs); - return -2; /* ignore, already handled */ + return NO_IRQ_IGNORE; /* ignore, already handled */ } #endif /* CONFIG_SMP */ + spin_lock_irqsave(&pmac_pic_lock, flags); for (irq = max_real_irqs; (irq -= 32) >= 0; ) { int i = irq >> 5; bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i]; @@ -242,133 +262,10 @@ static int pmac_get_irq(struct pt_regs *regs) irq += __ilog2(bits); break; } - - return irq; -} - -/* This routine will fix some missing interrupt values in the device tree - * on the gatwick mac-io controller used by some PowerBooks - * - * Walking of OF nodes could use a bit more fixing up here, but it's not - * very important as this is all boot time code on static portions of the - * device-tree. - * - * However, the modifications done to "intrs" will have to be removed and - * replaced with proper updates of the "interrupts" properties or - * AAPL,interrupts, yet to be decided, once the dynamic parsing is there. - */ -static void __init pmac_fix_gatwick_interrupts(struct device_node *gw, - int irq_base) -{ - struct device_node *node; - int count; - - memset(gatwick_int_pool, 0, sizeof(gatwick_int_pool)); - count = 0; - for (node = NULL; (node = of_get_next_child(gw, node)) != NULL;) { - /* Fix SCC */ - if ((strcasecmp(node->name, "escc") == 0) && node->child) { - if (node->child->n_intrs < 3) { - node->child->intrs = &gatwick_int_pool[count]; - count += 3; - } - node->child->n_intrs = 3; - node->child->intrs[0].line = 15+irq_base; - node->child->intrs[1].line = 4+irq_base; - node->child->intrs[2].line = 5+irq_base; - printk(KERN_INFO "irq: fixed SCC on gatwick" - " (%d,%d,%d)\n", - node->child->intrs[0].line, - node->child->intrs[1].line, - node->child->intrs[2].line); - } - /* Fix media-bay & left SWIM */ - if (strcasecmp(node->name, "media-bay") == 0) { - struct device_node* ya_node; - - if (node->n_intrs == 0) - node->intrs = &gatwick_int_pool[count++]; - node->n_intrs = 1; - node->intrs[0].line = 29+irq_base; - printk(KERN_INFO "irq: fixed media-bay on gatwick" - " (%d)\n", node->intrs[0].line); - - ya_node = node->child; - while(ya_node) { - if (strcasecmp(ya_node->name, "floppy") == 0) { - if (ya_node->n_intrs < 2) { - ya_node->intrs = &gatwick_int_pool[count]; - count += 2; - } - ya_node->n_intrs = 2; - ya_node->intrs[0].line = 19+irq_base; - ya_node->intrs[1].line = 1+irq_base; - printk(KERN_INFO "irq: fixed floppy on second controller (%d,%d)\n", - ya_node->intrs[0].line, ya_node->intrs[1].line); - } - if (strcasecmp(ya_node->name, "ata4") == 0) { - if (ya_node->n_intrs < 2) { - ya_node->intrs = &gatwick_int_pool[count]; - count += 2; - } - ya_node->n_intrs = 2; - ya_node->intrs[0].line = 14+irq_base; - ya_node->intrs[1].line = 3+irq_base; - printk(KERN_INFO "irq: fixed ide on second controller (%d,%d)\n", - ya_node->intrs[0].line, ya_node->intrs[1].line); - } - ya_node = ya_node->sibling; - } - } - } - if (count > 10) { - printk("WARNING !! Gatwick interrupt pool overflow\n"); - printk(" GATWICK_IRQ_POOL_SIZE = %d\n", GATWICK_IRQ_POOL_SIZE); - printk(" requested = %d\n", count); - } -} - -/* - * The PowerBook 3400/2400/3500 can have a combo ethernet/modem - * card which includes an ohare chip that acts as a second interrupt - * controller. If we find this second ohare, set it up and fix the - * interrupt value in the device tree for the ethernet chip. - */ -static void __init enable_second_ohare(struct device_node *np) -{ - unsigned char bus, devfn; - unsigned short cmd; - struct device_node *ether; - - /* This code doesn't strictly belong here, it could be part of - * either the PCI initialisation or the feature code. It's kept - * here for historical reasons. - */ - if (pci_device_from_OF_node(np, &bus, &devfn) == 0) { - struct pci_controller* hose = - pci_find_hose_for_OF_device(np); - if (!hose) { - printk(KERN_ERR "Can't find PCI hose for OHare2 !\n"); - return; - } - early_read_config_word(hose, bus, devfn, PCI_COMMAND, &cmd); - cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; - cmd &= ~PCI_COMMAND_IO; - early_write_config_word(hose, bus, devfn, PCI_COMMAND, cmd); - } - - /* Fix interrupt for the modem/ethernet combo controller. The number - * in the device tree (27) is bogus (correct for the ethernet-only - * board but not the combo ethernet/modem board). - * The real interrupt is 28 on the second controller -> 28+32 = 60. - */ - ether = of_find_node_by_name(NULL, "pci1011,14"); - if (ether && ether->n_intrs > 0) { - ether->intrs[0].line = 60; - printk(KERN_INFO "irq: Fixed ethernet IRQ to %d\n", - ether->intrs[0].line); - } - of_node_put(ether); + spin_unlock_irqrestore(&pmac_pic_lock, flags); + if (unlikely(irq < 0)) + return NO_IRQ; + return irq_linear_revmap(pmac_pic_host, irq); } #ifdef CONFIG_XMON @@ -382,22 +279,66 @@ static struct irqaction xmon_action = { static struct irqaction gatwick_cascade_action = { .handler = gatwick_action, - .flags = SA_INTERRUPT, + .flags = IRQF_DISABLED, .mask = CPU_MASK_NONE, .name = "cascade", }; +static int pmac_pic_host_match(struct irq_host *h, struct device_node *node) +{ + /* We match all, we don't always have a node anyway */ + return 1; +} + +static int pmac_pic_host_map(struct irq_host *h, unsigned int virq, + irq_hw_number_t hw) +{ + struct irq_desc *desc = get_irq_desc(virq); + int level; + + if (hw >= max_irqs) + return -EINVAL; + + /* Mark level interrupts, set delayed disable for edge ones and set + * handlers + */ + level = !!(level_mask[hw >> 5] & (1UL << (hw & 0x1f))); + if (level) + desc->status |= IRQ_LEVEL; + else + desc->status |= IRQ_DELAYED_DISABLE; + set_irq_chip_and_handler(virq, &pmac_pic, level ? + handle_level_irq : handle_edge_irq); + return 0; +} + +static int pmac_pic_host_xlate(struct irq_host *h, struct device_node *ct, + u32 *intspec, unsigned int intsize, + irq_hw_number_t *out_hwirq, + unsigned int *out_flags) + +{ + *out_flags = IRQ_TYPE_NONE; + *out_hwirq = *intspec; + return 0; +} + +static struct irq_host_ops pmac_pic_host_ops = { + .match = pmac_pic_host_match, + .map = pmac_pic_host_map, + .xlate = pmac_pic_host_xlate, +}; + static void __init pmac_pic_probe_oldstyle(void) { int i; - int irq_cascade = -1; struct device_node *master = NULL; struct device_node *slave = NULL; u8 __iomem *addr; struct resource r; /* Set our get_irq function */ - ppc_md.get_irq = pmac_get_irq; + ppc_md.get_irq = pmac_pic_get_irq; /* * Find the interrupt controller type & node @@ -415,7 +356,6 @@ static void __init pmac_pic_probe_oldstyle(void) if (slave) { max_irqs = 64; level_mask[1] = OHARE_LEVEL_MASK; - enable_second_ohare(slave); } } else if ((master = of_find_node_by_name(NULL, "mac-io")) != NULL) { max_irqs = max_real_irqs = 64; @@ -439,14 +379,18 @@ static void __init pmac_pic_probe_oldstyle(void) max_irqs = 128; level_mask[2] = HEATHROW_LEVEL_MASK; level_mask[3] = 0; - pmac_fix_gatwick_interrupts(slave, max_real_irqs); } } BUG_ON(master == NULL); - /* Set the handler for the main PIC */ - for ( i = 0; i < max_real_irqs ; i++ ) - irq_desc[i].handler = &pmac_pic; + /* + * Allocate an irq host + */ + pmac_pic_host = irq_alloc_host(IRQ_HOST_MAP_LINEAR, max_irqs, + &pmac_pic_host_ops, + max_irqs); + BUG_ON(pmac_pic_host == NULL); + irq_set_default_host(pmac_pic_host); /* Get addresses of first controller if we have a node for it */ BUG_ON(of_address_to_resource(master, 0, &r)); @@ -473,39 +417,38 @@ static void __init pmac_pic_probe_oldstyle(void) pmac_irq_hw[i++] = (volatile struct pmac_irq_hw __iomem *) (addr + 0x10); - irq_cascade = slave->intrs[0].line; + pmac_irq_cascade = irq_of_parse_and_map(slave, 0); printk(KERN_INFO "irq: Found slave Apple PIC %s for %d irqs" " cascade: %d\n", slave->full_name, - max_irqs - max_real_irqs, irq_cascade); + max_irqs - max_real_irqs, pmac_irq_cascade); } of_node_put(slave); - /* disable all interrupts in all controllers */ + /* Disable all interrupts in all controllers */ for (i = 0; i * 32 < max_irqs; ++i) out_le32(&pmac_irq_hw[i]->enable, 0); - /* mark level interrupts */ - for (i = 0; i < max_irqs; i++) - if (level_mask[i >> 5] & (1UL << (i & 0x1f))) - irq_desc[i].status = IRQ_LEVEL; + /* Hookup cascade irq */ + if (slave && pmac_irq_cascade != NO_IRQ) + setup_irq(pmac_irq_cascade, &gatwick_cascade_action); - /* Setup handlers for secondary controller and hook cascade irq*/ - if (slave) { - for ( i = max_real_irqs ; i < max_irqs ; i++ ) - irq_desc[i].handler = &gatwick_pic; - setup_irq(irq_cascade, &gatwick_cascade_action); - } printk(KERN_INFO "irq: System has %d possible interrupts\n", max_irqs); #ifdef CONFIG_XMON - setup_irq(20, &xmon_action); + setup_irq(irq_create_mapping(NULL, 20), &xmon_action); #endif } #endif /* CONFIG_PPC32 */ -static int pmac_u3_cascade(struct pt_regs *regs, void *data) +static void pmac_u3_cascade(unsigned int irq, struct irq_desc *desc, + struct pt_regs *regs) { - return mpic_get_one_irq((struct mpic *)data, regs); + struct mpic *mpic = desc->handler_data; + + unsigned int cascade_irq = mpic_get_one_irq(mpic, regs); + if (cascade_irq != NO_IRQ) + generic_handle_irq(cascade_irq, regs); + desc->chip->eoi(irq); } static void __init pmac_pic_setup_mpic_nmi(struct mpic *mpic) @@ -515,21 +458,20 @@ static void __init pmac_pic_setup_mpic_nmi(struct mpic *mpic) int nmi_irq; pswitch = of_find_node_by_name(NULL, "programmer-switch"); - if (pswitch && pswitch->n_intrs) { - nmi_irq = pswitch->intrs[0].line; - mpic_irq_set_priority(nmi_irq, 9); - setup_irq(nmi_irq, &xmon_action); + if (pswitch) { + nmi_irq = irq_of_parse_and_map(pswitch, 0); + if (nmi_irq != NO_IRQ) { + mpic_irq_set_priority(nmi_irq, 9); + setup_irq(nmi_irq, &xmon_action); + } + of_node_put(pswitch); } - of_node_put(pswitch); #endif /* defined(CONFIG_XMON) && defined(CONFIG_PPC32) */ } static struct mpic * __init pmac_setup_one_mpic(struct device_node *np, int master) { - unsigned char senses[128]; - int offset = master ? 0 : 128; - int count = master ? 128 : 124; const char *name = master ? " MPIC 1 " : " MPIC 2 "; struct resource r; struct mpic *mpic; @@ -542,8 +484,6 @@ static struct mpic * __init pmac_setup_one_mpic(struct device_node *np, pmac_call_feature(PMAC_FTR_ENABLE_MPIC, np, 0, 0); - prom_get_irq_senses(senses, offset, offset + count); - flags |= MPIC_WANTS_RESET; if (get_property(np, "big-endian", NULL)) flags |= MPIC_BIG_ENDIAN; @@ -554,8 +494,7 @@ static struct mpic * __init pmac_setup_one_mpic(struct device_node *np, if (master && (flags & MPIC_BIG_ENDIAN)) flags |= MPIC_BROKEN_U3; - mpic = mpic_alloc(r.start, flags, 0, offset, count, master ? 252 : 0, - senses, count, name); + mpic = mpic_alloc(np, r.start, flags, 0, 0, name); if (mpic == NULL) return NULL; @@ -568,6 +507,7 @@ static int __init pmac_pic_probe_mpic(void) { struct mpic *mpic1, *mpic2; struct device_node *np, *master = NULL, *slave = NULL; + unsigned int cascade; /* We can have up to 2 MPICs cascaded */ for (np = NULL; (np = of_find_node_by_type(np, "open-pic")) @@ -604,16 +544,24 @@ static int __init pmac_pic_probe_mpic(void) of_node_put(master); /* No slave, let's go out */ - if (slave == NULL || slave->n_intrs < 1) + if (slave == NULL) return 0; + /* Get/Map slave interrupt */ + cascade = irq_of_parse_and_map(slave, 0); + if (cascade == NO_IRQ) { + printk(KERN_ERR "Failed to map cascade IRQ\n"); + return 0; + } + mpic2 = pmac_setup_one_mpic(slave, 0); if (mpic2 == NULL) { printk(KERN_ERR "Failed to setup slave MPIC\n"); of_node_put(slave); return 0; } - mpic_setup_cascade(slave->intrs[0].line, pmac_u3_cascade, mpic2); + set_irq_data(cascade, mpic2); + set_irq_chained_handler(cascade, pmac_u3_cascade); of_node_put(slave); return 0; @@ -622,6 +570,20 @@ static int __init pmac_pic_probe_mpic(void) void __init pmac_pic_init(void) { + unsigned int flags = 0; + + /* We configure the OF parsing based on our oldworld vs. newworld + * platform type and wether we were booted by BootX. + */ +#ifdef CONFIG_PPC32 + if (!pmac_newworld) + flags |= OF_IMAP_OLDWORLD_MAC; + if (get_property(of_chosen, "linux,bootx", NULL) != NULL) + flags |= OF_IMAP_NO_PHANDLE; +#endif /* CONFIG_PPC_32 */ + + of_irq_map_init(flags); + /* We first try to detect Apple's new Core99 chipset, since mac-io * is quite different on those machines and contains an IBM MPIC2. */ @@ -644,6 +606,7 @@ unsigned long sleep_save_mask[2]; /* This used to be passed by the PMU driver but that link got * broken with the new driver model. We use this tweak for now... + * We really want to do things differently though... */ static int pmacpic_find_viaint(void) { @@ -657,7 +620,7 @@ static int pmacpic_find_viaint(void) np = of_find_node_by_name(NULL, "via-pmu"); if (np == NULL) goto not_found; - viaint = np->intrs[0].line; + viaint = irq_of_parse_and_map(np, 0);; #endif /* CONFIG_ADB_PMU */ not_found: diff --git a/arch/powerpc/platforms/powermac/pmac.h b/arch/powerpc/platforms/powermac/pmac.h index 21c7b0f8f329..94e7b24b840b 100644 --- a/arch/powerpc/platforms/powermac/pmac.h +++ b/arch/powerpc/platforms/powermac/pmac.h @@ -12,6 +12,8 @@ struct rtc_time; +extern int pmac_newworld; + extern long pmac_time_init(void); extern unsigned long pmac_get_boot_time(void); extern void pmac_get_rtc_time(struct rtc_time *); diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index 9cc7db7a8bdc..824a618396ab 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c @@ -23,7 +23,6 @@ * bootup setup stuff.. */ -#include <linux/config.h> #include <linux/init.h> #include <linux/errno.h> #include <linux/sched.h> @@ -117,7 +116,7 @@ extern struct smp_ops_t core99_smp_ops; static void pmac_show_cpuinfo(struct seq_file *m) { struct device_node *np; - char *pp; + const char *pp; int plen; int mbmodel; unsigned int mbflags; @@ -135,12 +134,12 @@ static void pmac_show_cpuinfo(struct seq_file *m) seq_printf(m, "machine\t\t: "); np = of_find_node_by_path("/"); if (np != NULL) { - pp = (char *) get_property(np, "model", NULL); + pp = get_property(np, "model", NULL); if (pp != NULL) seq_printf(m, "%s\n", pp); else seq_printf(m, "PowerMac\n"); - pp = (char *) get_property(np, "compatible", &plen); + pp = get_property(np, "compatible", &plen); if (pp != NULL) { seq_printf(m, "motherboard\t:"); while (plen > 0) { @@ -164,10 +163,8 @@ static void pmac_show_cpuinfo(struct seq_file *m) if (np == NULL) np = of_find_node_by_type(NULL, "cache"); if (np != NULL) { - unsigned int *ic = (unsigned int *) - get_property(np, "i-cache-size", NULL); - unsigned int *dc = (unsigned int *) - get_property(np, "d-cache-size", NULL); + const unsigned int *ic = get_property(np, "i-cache-size", NULL); + const unsigned int *dc = get_property(np, "d-cache-size", NULL); seq_printf(m, "L2 cache\t:"); has_l2cache = 1; if (get_property(np, "cache-unified", NULL) != 0 && dc) { @@ -255,7 +252,7 @@ static void __init l2cr_init(void) if (np == 0) np = find_type_devices("cpu"); if (np != 0) { - unsigned int *l2cr = (unsigned int *) + const unsigned int *l2cr = get_property(np, "l2cr-value", NULL); if (l2cr != 0) { ppc_override_l2cr = 1; @@ -278,7 +275,7 @@ static void __init l2cr_init(void) static void __init pmac_setup_arch(void) { struct device_node *cpu, *ic; - int *fp; + const int *fp; unsigned long pvr; pvr = PVR_VER(mfspr(SPRN_PVR)); @@ -288,7 +285,7 @@ static void __init pmac_setup_arch(void) loops_per_jiffy = 50000000 / HZ; cpu = of_find_node_by_type(NULL, "cpu"); if (cpu != NULL) { - fp = (int *) get_property(cpu, "clock-frequency", NULL); + fp = get_property(cpu, "clock-frequency", NULL); if (fp != NULL) { if (pvr >= 0x30 && pvr < 0x80) /* PPC970 etc. */ @@ -600,13 +597,6 @@ pmac_halt(void) */ static void __init pmac_init_early(void) { -#ifdef CONFIG_PPC64 - /* Initialize hash table, from now on, we can take hash faults - * and call ioremap - */ - hpte_init_native(); -#endif - /* Enable early btext debug if requested */ if (strstr(cmd_line, "btextdbg")) { udbg_adb_init_early(); @@ -621,9 +611,6 @@ static void __init pmac_init_early(void) udbg_adb_init(!!strstr(cmd_line, "btextdbg")); #ifdef CONFIG_PPC64 - /* Setup interrupt mapping options */ - ppc64_interrupt_controller = IC_OPEN_PIC; - iommu_init_early_dart(); #endif } @@ -683,6 +670,8 @@ static int __init pmac_probe(void) * part of the cacheable linar mapping */ alloc_dart_table(); + + hpte_init_native(); #endif #ifdef CONFIG_PPC32 diff --git a/arch/powerpc/platforms/powermac/sleep.S b/arch/powerpc/platforms/powermac/sleep.S index 22b113d19b24..1174ca128efa 100644 --- a/arch/powerpc/platforms/powermac/sleep.S +++ b/arch/powerpc/platforms/powermac/sleep.S @@ -10,7 +10,6 @@ * */ -#include <linux/config.h> #include <asm/processor.h> #include <asm/page.h> #include <asm/ppc_asm.h> diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c index 1065d87fc279..1949b657b092 100644 --- a/arch/powerpc/platforms/powermac/smp.c +++ b/arch/powerpc/platforms/powermac/smp.c @@ -21,7 +21,6 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/smp.h> @@ -378,7 +377,7 @@ static void __init psurge_dual_sync_tb(int cpu_nr) static struct irqaction psurge_irqaction = { .handler = psurge_primary_intr, - .flags = SA_INTERRUPT, + .flags = IRQF_DISABLED, .mask = CPU_MASK_NONE, .name = "primary IPI", }; @@ -549,7 +548,7 @@ static void __init smp_core99_setup_i2c_hwsync(int ncpus) struct device_node *cc = NULL; struct device_node *p; const char *name = NULL; - u32 *reg; + const u32 *reg; int ok; /* Look for the clock chip */ @@ -563,7 +562,7 @@ static void __init smp_core99_setup_i2c_hwsync(int ncpus) pmac_tb_clock_chip_host = pmac_i2c_find_bus(cc); if (pmac_tb_clock_chip_host == NULL) continue; - reg = (u32 *)get_property(cc, "reg", NULL); + reg = get_property(cc, "reg", NULL); if (reg == NULL) continue; switch (*reg) { @@ -703,13 +702,12 @@ static void __init smp_core99_setup(int ncpus) /* GPIO based HW sync on ppc32 Core99 */ if (pmac_tb_freeze == NULL && !machine_is_compatible("MacRISC4")) { struct device_node *cpu; - u32 *tbprop = NULL; + const u32 *tbprop = NULL; core99_tb_gpio = KL_GPIO_TB_ENABLE; /* default value */ cpu = of_find_node_by_type(NULL, "cpu"); if (cpu != NULL) { - tbprop = (u32 *)get_property(cpu, "timebase-enable", - NULL); + tbprop = get_property(cpu, "timebase-enable", NULL); if (tbprop) core99_tb_gpio = *tbprop; of_node_put(cpu); diff --git a/arch/powerpc/platforms/powermac/time.c b/arch/powerpc/platforms/powermac/time.c index 890758aa9667..a4173906e945 100644 --- a/arch/powerpc/platforms/powermac/time.c +++ b/arch/powerpc/platforms/powermac/time.c @@ -9,7 +9,6 @@ * Copyright (C) 2003-2005 Benjamin Herrenschmidt. * */ -#include <linux/config.h> #include <linux/errno.h> #include <linux/sched.h> #include <linux/kernel.h> diff --git a/arch/powerpc/platforms/powermac/udbg_adb.c b/arch/powerpc/platforms/powermac/udbg_adb.c index 06c8265c2baf..6124e59e1038 100644 --- a/arch/powerpc/platforms/powermac/udbg_adb.c +++ b/arch/powerpc/platforms/powermac/udbg_adb.c @@ -1,4 +1,3 @@ -#include <linux/config.h> #include <linux/string.h> #include <linux/kernel.h> #include <linux/errno.h> diff --git a/arch/powerpc/platforms/powermac/udbg_scc.c b/arch/powerpc/platforms/powermac/udbg_scc.c index b4fa9f03b461..ce1a235855f7 100644 --- a/arch/powerpc/platforms/powermac/udbg_scc.c +++ b/arch/powerpc/platforms/powermac/udbg_scc.c @@ -8,7 +8,6 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <linux/types.h> #include <asm/udbg.h> #include <asm/processor.h> @@ -69,11 +68,11 @@ static unsigned char scc_inittab[] = { void udbg_scc_init(int force_scc) { - u32 *reg; + const u32 *reg; unsigned long addr; struct device_node *stdout = NULL, *escc = NULL, *macio = NULL; struct device_node *ch, *ch_def = NULL, *ch_a = NULL; - char *path; + const char *path; int i, x; escc = of_find_node_by_name(NULL, "escc"); @@ -82,7 +81,7 @@ void udbg_scc_init(int force_scc) macio = of_get_parent(escc); if (macio == NULL) goto bail; - path = (char *)get_property(of_chosen, "linux,stdout-path", NULL); + path = get_property(of_chosen, "linux,stdout-path", NULL); if (path != NULL) stdout = of_find_node_by_path(path); for (ch = NULL; (ch = of_get_next_child(escc, ch)) != NULL;) { @@ -97,13 +96,13 @@ void udbg_scc_init(int force_scc) ch = ch_def ? ch_def : ch_a; /* Get address within mac-io ASIC */ - reg = (u32 *)get_property(escc, "reg", NULL); + reg = get_property(escc, "reg", NULL); if (reg == NULL) goto bail; addr = reg[0]; /* Get address of mac-io PCI itself */ - reg = (u32 *)get_property(macio, "assigned-addresses", NULL); + reg = get_property(macio, "assigned-addresses", NULL); if (reg == NULL) goto bail; addr += reg[2]; diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile index e5e0ff466904..997243a91be8 100644 --- a/arch/powerpc/platforms/pseries/Makefile +++ b/arch/powerpc/platforms/pseries/Makefile @@ -12,3 +12,4 @@ obj-$(CONFIG_EEH) += eeh.o eeh_cache.o eeh_driver.o eeh_event.o obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o obj-$(CONFIG_HVCS) += hvcserver.o +obj-$(CONFIG_HCALL_STATS) += hvCall_inst.o diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c index 32eaddfa5470..84bc8f7e17ef 100644 --- a/arch/powerpc/platforms/pseries/eeh.c +++ b/arch/powerpc/platforms/pseries/eeh.c @@ -449,7 +449,11 @@ EXPORT_SYMBOL(eeh_check_failure); /* ------------------------------------------------------------- */ /* The code below deals with error recovery */ -/** Return negative value if a permanent error, else return +/** + * eeh_slot_availability - returns error status of slot + * @pdn pci device node + * + * Return negative value if a permanent error, else return * a number of milliseconds to wait until the PCI slot is * ready to be used. */ @@ -474,11 +478,42 @@ eeh_slot_availability(struct pci_dn *pdn) printk (KERN_ERR "EEH: Slot unavailable: rc=%d, rets=%d %d %d\n", rc, rets[0], rets[1], rets[2]); - return -1; + return -2; +} + +/** + * rtas_pci_enable - enable MMIO or DMA transfers for this slot + * @pdn pci device node + */ + +int +rtas_pci_enable(struct pci_dn *pdn, int function) +{ + int config_addr; + int rc; + + /* Use PE configuration address, if present */ + config_addr = pdn->eeh_config_addr; + if (pdn->eeh_pe_config_addr) + config_addr = pdn->eeh_pe_config_addr; + + rc = rtas_call(ibm_set_eeh_option, 4, 1, NULL, + config_addr, + BUID_HI(pdn->phb->buid), + BUID_LO(pdn->phb->buid), + function); + + if (rc) + printk(KERN_WARNING "EEH: Cannot enable function %d, err=%d dn=%s\n", + function, rc, pdn->node->full_name); + + return rc; } -/** rtas_pci_slot_reset raises/lowers the pci #RST line - * state: 1/0 to raise/lower the #RST +/** + * rtas_pci_slot_reset - raises/lowers the pci #RST line + * @pdn pci device node + * @state: 1/0 to raise/lower the #RST * * Clear the EEH-frozen condition on a slot. This routine * asserts the PCI #RST line if the 'state' argument is '1', @@ -511,24 +546,21 @@ rtas_pci_slot_reset(struct pci_dn *pdn, int state) BUID_HI(pdn->phb->buid), BUID_LO(pdn->phb->buid), state); - if (rc) { - printk (KERN_WARNING "EEH: Unable to reset the failed slot, (%d) #RST=%d dn=%s\n", + if (rc) + printk (KERN_WARNING "EEH: Unable to reset the failed slot," + " (%d) #RST=%d dn=%s\n", rc, state, pdn->node->full_name); - return; - } } -/** rtas_set_slot_reset -- assert the pci #RST line for 1/4 second - * dn -- device node to be reset. +/** + * rtas_set_slot_reset -- assert the pci #RST line for 1/4 second + * @pdn: pci device node to be reset. * * Return 0 if success, else a non-zero value. */ -int -rtas_set_slot_reset(struct pci_dn *pdn) +static void __rtas_set_slot_reset(struct pci_dn *pdn) { - int i, rc; - rtas_pci_slot_reset (pdn, 1); /* The PCI bus requires that the reset be held high for at least @@ -549,17 +581,33 @@ rtas_set_slot_reset(struct pci_dn *pdn) * up traffic. */ #define PCI_BUS_SETTLE_TIME_MSEC 1800 msleep (PCI_BUS_SETTLE_TIME_MSEC); +} + +int rtas_set_slot_reset(struct pci_dn *pdn) +{ + int i, rc; + + __rtas_set_slot_reset(pdn); /* Now double check with the firmware to make sure the device is * ready to be used; if not, wait for recovery. */ for (i=0; i<10; i++) { rc = eeh_slot_availability (pdn); - if (rc < 0) - printk (KERN_ERR "EEH: failed (%d) to reset slot %s\n", rc, pdn->node->full_name); if (rc == 0) return 0; - if (rc < 0) + + if (rc == -2) { + printk (KERN_ERR "EEH: failed (%d) to reset slot %s\n", + i, pdn->node->full_name); + __rtas_set_slot_reset(pdn); + continue; + } + + if (rc < 0) { + printk (KERN_ERR "EEH: unrecoverable slot failure %s\n", + pdn->node->full_name); return -1; + } msleep (rc+100); } @@ -582,6 +630,8 @@ rtas_set_slot_reset(struct pci_dn *pdn) /** * __restore_bars - Restore the Base Address Registers + * @pdn: pci device node + * * Loads the PCI configuration space base address registers, * the expansion ROM base address, the latency timer, and etc. * from the saved values in the device node. @@ -691,11 +741,11 @@ static void *early_enable_eeh(struct device_node *dn, void *data) { struct eeh_early_enable_info *info = data; int ret; - char *status = get_property(dn, "status", NULL); - u32 *class_code = (u32 *)get_property(dn, "class-code", NULL); - u32 *vendor_id = (u32 *)get_property(dn, "vendor-id", NULL); - u32 *device_id = (u32 *)get_property(dn, "device-id", NULL); - u32 *regs; + const char *status = get_property(dn, "status", NULL); + const u32 *class_code = get_property(dn, "class-code", NULL); + const u32 *vendor_id = get_property(dn, "vendor-id", NULL); + const u32 *device_id = get_property(dn, "device-id", NULL); + const u32 *regs; int enable; struct pci_dn *pdn = PCI_DN(dn); @@ -737,7 +787,7 @@ static void *early_enable_eeh(struct device_node *dn, void *data) /* Ok... see if this device supports EEH. Some do, some don't, * and the only way to find out is to check each and every one. */ - regs = (u32 *)get_property(dn, "reg", NULL); + regs = get_property(dn, "reg", NULL); if (regs) { /* First register entry is addr (00BBSS00) */ /* Try to enable eeh */ diff --git a/arch/powerpc/platforms/pseries/eeh_cache.c b/arch/powerpc/platforms/pseries/eeh_cache.c index 98c23aec85be..b6b462d3c604 100644 --- a/arch/powerpc/platforms/pseries/eeh_cache.c +++ b/arch/powerpc/platforms/pseries/eeh_cache.c @@ -157,6 +157,7 @@ pci_addr_cache_insert(struct pci_dev *dev, unsigned long alo, if (!piar) return NULL; + pci_dev_get(dev); piar->addr_lo = alo; piar->addr_hi = ahi; piar->pcidev = dev; @@ -178,7 +179,6 @@ static void __pci_addr_cache_insert_device(struct pci_dev *dev) struct device_node *dn; struct pci_dn *pdn; int i; - int inserted = 0; dn = pci_device_to_OF_node(dev); if (!dn) { @@ -197,9 +197,6 @@ static void __pci_addr_cache_insert_device(struct pci_dev *dev) return; } - /* The cache holds a reference to the device... */ - pci_dev_get(dev); - /* Walk resources on this device, poke them into the tree */ for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { unsigned long start = pci_resource_start(dev,i); @@ -212,12 +209,7 @@ static void __pci_addr_cache_insert_device(struct pci_dev *dev) if (start == 0 || ~start == 0 || end == 0 || ~end == 0) continue; pci_addr_cache_insert(dev, start, end, flags); - inserted = 1; } - - /* If there was nothing to add, the cache has no reference... */ - if (!inserted) - pci_dev_put(dev); } /** @@ -240,7 +232,6 @@ void pci_addr_cache_insert_device(struct pci_dev *dev) static inline void __pci_addr_cache_remove_device(struct pci_dev *dev) { struct rb_node *n; - int removed = 0; restart: n = rb_first(&pci_io_addr_cache_root.rb_root); @@ -250,16 +241,12 @@ restart: if (piar->pcidev == dev) { rb_erase(n, &pci_io_addr_cache_root.rb_root); - removed = 1; + pci_dev_put(piar->pcidev); kfree(piar); goto restart; } n = rb_next(n); } - - /* The cache no longer holds its reference to this device... */ - if (removed) - pci_dev_put(dev); } /** @@ -287,7 +274,7 @@ void pci_addr_cache_remove_device(struct pci_dev *dev) * find the pci device that corresponds to a given address. * This routine scans all pci busses to build the cache. * Must be run late in boot process, after the pci controllers - * have been scaned for devices (after all device resources are known). + * have been scanned for devices (after all device resources are known). */ void __init pci_addr_cache_build(void) { diff --git a/arch/powerpc/platforms/pseries/eeh_driver.c b/arch/powerpc/platforms/pseries/eeh_driver.c index 0ec9a5445b95..c2bc9904f1cb 100644 --- a/arch/powerpc/platforms/pseries/eeh_driver.c +++ b/arch/powerpc/platforms/pseries/eeh_driver.c @@ -77,8 +77,12 @@ static int irq_in_use(unsigned int irq) } /* ------------------------------------------------------- */ -/** eeh_report_error - report an EEH error to each device, - * collect up and merge the device responses. +/** + * eeh_report_error - report pci error to each device driver + * + * Report an EEH error to each device driver, collect up and + * merge the device driver responses. Cumulative response + * passed back in "userdata". */ static void eeh_report_error(struct pci_dev *dev, void *userdata) @@ -96,24 +100,49 @@ static void eeh_report_error(struct pci_dev *dev, void *userdata) PCI_DN(dn)->eeh_mode |= EEH_MODE_IRQ_DISABLED; disable_irq_nosync(dev->irq); } - if (!driver->err_handler) - return; - if (!driver->err_handler->error_detected) + if (!driver->err_handler || + !driver->err_handler->error_detected) return; rc = driver->err_handler->error_detected (dev, pci_channel_io_frozen); if (*res == PCI_ERS_RESULT_NONE) *res = rc; - if (*res == PCI_ERS_RESULT_NEED_RESET) return; if (*res == PCI_ERS_RESULT_DISCONNECT && rc == PCI_ERS_RESULT_NEED_RESET) *res = rc; } -/** eeh_report_reset -- tell this device that the pci slot - * has been reset. +/** + * eeh_report_mmio_enabled - tell drivers that MMIO has been enabled + * + * Report an EEH error to each device driver, collect up and + * merge the device driver responses. Cumulative response + * passed back in "userdata". + */ + +static void eeh_report_mmio_enabled(struct pci_dev *dev, void *userdata) +{ + enum pci_ers_result rc, *res = userdata; + struct pci_driver *driver = dev->driver; + + // dev->error_state = pci_channel_mmio_enabled; + + if (!driver || + !driver->err_handler || + !driver->err_handler->mmio_enabled) + return; + + rc = driver->err_handler->mmio_enabled (dev); + if (*res == PCI_ERS_RESULT_NONE) *res = rc; + if (*res == PCI_ERS_RESULT_DISCONNECT && + rc == PCI_ERS_RESULT_NEED_RESET) *res = rc; +} + +/** + * eeh_report_reset - tell device that slot has been reset */ static void eeh_report_reset(struct pci_dev *dev, void *userdata) { + enum pci_ers_result rc, *res = userdata; struct pci_driver *driver = dev->driver; struct device_node *dn = pci_device_to_OF_node(dev); @@ -124,14 +153,20 @@ static void eeh_report_reset(struct pci_dev *dev, void *userdata) PCI_DN(dn)->eeh_mode &= ~EEH_MODE_IRQ_DISABLED; enable_irq(dev->irq); } - if (!driver->err_handler) - return; - if (!driver->err_handler->slot_reset) + if (!driver->err_handler || + !driver->err_handler->slot_reset) return; - driver->err_handler->slot_reset(dev); + rc = driver->err_handler->slot_reset(dev); + if (*res == PCI_ERS_RESULT_NONE) *res = rc; + if (*res == PCI_ERS_RESULT_DISCONNECT && + rc == PCI_ERS_RESULT_NEED_RESET) *res = rc; } +/** + * eeh_report_resume - tell device to resume normal operations + */ + static void eeh_report_resume(struct pci_dev *dev, void *userdata) { struct pci_driver *driver = dev->driver; @@ -148,6 +183,13 @@ static void eeh_report_resume(struct pci_dev *dev, void *userdata) driver->err_handler->resume(dev); } +/** + * eeh_report_failure - tell device driver that device is dead. + * + * This informs the device driver that the device is permanently + * dead, and that no further recovery attempts will be made on it. + */ + static void eeh_report_failure(struct pci_dev *dev, void *userdata) { struct pci_driver *driver = dev->driver; @@ -175,7 +217,7 @@ static void eeh_report_failure(struct pci_dev *dev, void *userdata) * * pSeries systems will isolate a PCI slot if the PCI-Host * bridge detects address or data parity errors, DMA's - * occuring to wild addresses (which usually happen due to + * occurring to wild addresses (which usually happen due to * bugs in device drivers or in PCI adapter firmware). * Slot isolations also occur if #SERR, #PERR or other misc * PCI-related errors are detected. @@ -190,11 +232,11 @@ static void eeh_report_failure(struct pci_dev *dev, void *userdata) /** * eeh_reset_device() -- perform actual reset of a pci slot - * Args: bus: pointer to the pci bus structure corresponding + * @bus: pointer to the pci bus structure corresponding * to the isolated slot. A non-null value will * cause all devices under the bus to be removed * and then re-added. - * pe_dn: pointer to a "Partionable Endpoint" device node. + * @pe_dn: pointer to a "Partionable Endpoint" device node. * This is the top-level structure on which pci * bus resets can be performed. */ @@ -268,14 +310,14 @@ struct pci_dn * handle_eeh_events (struct eeh_event *event) if (!frozen_dn) { - location = (char *) get_property(event->dn, "ibm,loc-code", NULL); + location = get_property(event->dn, "ibm,loc-code", NULL); location = location ? location : "unknown"; printk(KERN_ERR "EEH: Error: Cannot find partition endpoint " "for location=%s pci addr=%s\n", location, pci_name(event->dev)); return NULL; } - location = (char *) get_property(frozen_dn, "ibm,loc-code", NULL); + location = get_property(frozen_dn, "ibm,loc-code", NULL); location = location ? location : "unknown"; /* There are two different styles for coming up with the PE. @@ -347,23 +389,43 @@ struct pci_dn * handle_eeh_events (struct eeh_event *event) goto hard_fail; } - /* If any device called out for a reset, then reset the slot */ - if (result == PCI_ERS_RESULT_NEED_RESET) { - rc = eeh_reset_device(frozen_pdn, NULL); - if (rc) - goto hard_fail; - pci_walk_bus(frozen_bus, eeh_report_reset, NULL); + /* If all devices reported they can proceed, then re-enable MMIO */ + if (result == PCI_ERS_RESULT_CAN_RECOVER) { + rc = rtas_pci_enable(frozen_pdn, EEH_THAW_MMIO); + + if (rc) { + result = PCI_ERS_RESULT_NEED_RESET; + } else { + result = PCI_ERS_RESULT_NONE; + pci_walk_bus(frozen_bus, eeh_report_mmio_enabled, &result); + } } - /* If all devices reported they can proceed, the re-enable PIO */ + /* If all devices reported they can proceed, then re-enable DMA */ if (result == PCI_ERS_RESULT_CAN_RECOVER) { - /* XXX Not supported; we brute-force reset the device */ + rc = rtas_pci_enable(frozen_pdn, EEH_THAW_DMA); + + if (rc) + result = PCI_ERS_RESULT_NEED_RESET; + } + + /* If any device has a hard failure, then shut off everything. */ + if (result == PCI_ERS_RESULT_DISCONNECT) + goto hard_fail; + + /* If any device called out for a reset, then reset the slot */ + if (result == PCI_ERS_RESULT_NEED_RESET) { rc = eeh_reset_device(frozen_pdn, NULL); if (rc) goto hard_fail; - pci_walk_bus(frozen_bus, eeh_report_reset, NULL); + result = PCI_ERS_RESULT_NONE; + pci_walk_bus(frozen_bus, eeh_report_reset, &result); } + /* All devices should claim they have recovered by now. */ + if (result != PCI_ERS_RESULT_RECOVERED) + goto hard_fail; + /* Tell all device drivers that they can resume operations */ pci_walk_bus(frozen_bus, eeh_report_resume, NULL); diff --git a/arch/powerpc/platforms/pseries/eeh_event.c b/arch/powerpc/platforms/pseries/eeh_event.c index 8f2d12935b99..137077451316 100644 --- a/arch/powerpc/platforms/pseries/eeh_event.c +++ b/arch/powerpc/platforms/pseries/eeh_event.c @@ -35,7 +35,7 @@ */ /* EEH event workqueue setup. */ -static spinlock_t eeh_eventlist_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(eeh_eventlist_lock); LIST_HEAD(eeh_eventlist); static void eeh_thread_launcher(void *); DECLARE_WORK(eeh_event_wq, eeh_thread_launcher, NULL); @@ -124,11 +124,11 @@ int eeh_send_failure_event (struct device_node *dn, { unsigned long flags; struct eeh_event *event; - char *location; + const char *location; if (!mem_init_done) { printk(KERN_ERR "EEH: event during early boot not handled\n"); - location = (char *) get_property(dn, "ibm,loc-code", NULL); + location = get_property(dn, "ibm,loc-code", NULL); printk(KERN_ERR "EEH: device node = %s\n", dn->full_name); printk(KERN_ERR "EEH: PCI location = %s\n", location); return 1; diff --git a/arch/powerpc/platforms/pseries/firmware.c b/arch/powerpc/platforms/pseries/firmware.c index c01d8f0cbe6d..1c7b2baa5f73 100644 --- a/arch/powerpc/platforms/pseries/firmware.c +++ b/arch/powerpc/platforms/pseries/firmware.c @@ -68,7 +68,7 @@ firmware_features_table[FIRMWARE_MAX_FEATURES] = { void __init fw_feature_init(void) { struct device_node *dn; - char *hypertas, *s; + const char *hypertas, *s; int len, i; DBG(" -> fw_feature_init()\n"); diff --git a/arch/powerpc/platforms/pseries/hvCall.S b/arch/powerpc/platforms/pseries/hvCall.S index c9ff547f9d25..c00cfed7af2c 100644 --- a/arch/powerpc/platforms/pseries/hvCall.S +++ b/arch/powerpc/platforms/pseries/hvCall.S @@ -1,7 +1,6 @@ /* * This file contains the generic code to perform a call to the * pSeries LPAR hypervisor. - * NOTE: this file will go away when we move to inline this work. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -11,217 +10,153 @@ #include <asm/hvcall.h> #include <asm/processor.h> #include <asm/ppc_asm.h> +#include <asm/asm-offsets.h> #define STK_PARM(i) (48 + ((i)-3)*8) - .text - -/* long plpar_hcall(unsigned long opcode, R3 - unsigned long arg1, R4 - unsigned long arg2, R5 - unsigned long arg3, R6 - unsigned long arg4, R7 - unsigned long *out1, R8 - unsigned long *out2, R9 - unsigned long *out3); R10 +#ifdef CONFIG_HCALL_STATS +/* + * precall must preserve all registers. use unused STK_PARM() + * areas to save snapshots and opcode. */ -_GLOBAL(plpar_hcall) - HMT_MEDIUM - - mfcr r0 - - std r8,STK_PARM(r8)(r1) /* Save out ptrs */ - std r9,STK_PARM(r9)(r1) - std r10,STK_PARM(r10)(r1) - - stw r0,8(r1) - - HVSC /* invoke the hypervisor */ - - lwz r0,8(r1) - - ld r8,STK_PARM(r8)(r1) /* Fetch r4-r6 ret args */ - ld r9,STK_PARM(r9)(r1) - ld r10,STK_PARM(r10)(r1) - std r4,0(r8) - std r5,0(r9) - std r6,0(r10) - - mtcrf 0xff,r0 - blr /* return r3 = status */ +#define HCALL_INST_PRECALL \ + std r3,STK_PARM(r3)(r1); /* save opcode */ \ + mftb r0; /* get timebase and */ \ + std r0,STK_PARM(r5)(r1); /* save for later */ \ +BEGIN_FTR_SECTION; \ + mfspr r0,SPRN_PURR; /* get PURR and */ \ + std r0,STK_PARM(r6)(r1); /* save for later */ \ +END_FTR_SECTION_IFCLR(CPU_FTR_PURR); + +/* + * postcall is performed immediately before function return which + * allows liberal use of volatile registers. + */ +#define HCALL_INST_POSTCALL \ + ld r4,STK_PARM(r3)(r1); /* validate opcode */ \ + cmpldi cr7,r4,MAX_HCALL_OPCODE; \ + bgt- cr7,1f; \ + \ + /* get time and PURR snapshots after hcall */ \ + mftb r7; /* timebase after */ \ +BEGIN_FTR_SECTION; \ + mfspr r8,SPRN_PURR; /* PURR after */ \ + ld r6,STK_PARM(r6)(r1); /* PURR before */ \ + subf r6,r6,r8; /* delta */ \ +END_FTR_SECTION_IFCLR(CPU_FTR_PURR); \ + ld r5,STK_PARM(r5)(r1); /* timebase before */ \ + subf r5,r5,r7; /* time delta */ \ + \ + /* calculate address of stat structure r4 = opcode */ \ + srdi r4,r4,2; /* index into array */ \ + mulli r4,r4,HCALL_STAT_SIZE; \ + LOAD_REG_ADDR(r7, per_cpu__hcall_stats); \ + add r4,r4,r7; \ + ld r7,PACA_DATA_OFFSET(r13); /* per cpu offset */ \ + add r4,r4,r7; \ + \ + /* update stats */ \ + ld r7,HCALL_STAT_CALLS(r4); /* count */ \ + addi r7,r7,1; \ + std r7,HCALL_STAT_CALLS(r4); \ + ld r7,HCALL_STAT_TB(r4); /* timebase */ \ + add r7,r7,r5; \ + std r7,HCALL_STAT_TB(r4); \ +BEGIN_FTR_SECTION; \ + ld r7,HCALL_STAT_PURR(r4); /* PURR */ \ + add r7,r7,r6; \ + std r7,HCALL_STAT_PURR(r4); \ +END_FTR_SECTION_IFCLR(CPU_FTR_PURR); \ +1: +#else +#define HCALL_INST_PRECALL +#define HCALL_INST_POSTCALL +#endif + .text -/* Simple interface with no output values (other than status) */ _GLOBAL(plpar_hcall_norets) HMT_MEDIUM mfcr r0 stw r0,8(r1) - HVSC /* invoke the hypervisor */ - - lwz r0,8(r1) - mtcrf 0xff,r0 - blr /* return r3 = status */ - - -/* long plpar_hcall_8arg_2ret(unsigned long opcode, R3 - unsigned long arg1, R4 - unsigned long arg2, R5 - unsigned long arg3, R6 - unsigned long arg4, R7 - unsigned long arg5, R8 - unsigned long arg6, R9 - unsigned long arg7, R10 - unsigned long arg8, 112(R1) - unsigned long *out1); 120(R1) - */ -_GLOBAL(plpar_hcall_8arg_2ret) - HMT_MEDIUM - - mfcr r0 - ld r11,STK_PARM(r11)(r1) /* put arg8 in R11 */ - stw r0,8(r1) + HCALL_INST_PRECALL HVSC /* invoke the hypervisor */ + HCALL_INST_POSTCALL + lwz r0,8(r1) - ld r10,STK_PARM(r12)(r1) /* Fetch r4 ret arg */ - std r4,0(r10) mtcrf 0xff,r0 blr /* return r3 = status */ - -/* long plpar_hcall_4out(unsigned long opcode, R3 - unsigned long arg1, R4 - unsigned long arg2, R5 - unsigned long arg3, R6 - unsigned long arg4, R7 - unsigned long *out1, R8 - unsigned long *out2, R9 - unsigned long *out3, R10 - unsigned long *out4); 112(R1) - */ -_GLOBAL(plpar_hcall_4out) +_GLOBAL(plpar_hcall) HMT_MEDIUM mfcr r0 stw r0,8(r1) - std r8,STK_PARM(r8)(r1) /* Save out ptrs */ - std r9,STK_PARM(r9)(r1) - std r10,STK_PARM(r10)(r1) - - HVSC /* invoke the hypervisor */ - - lwz r0,8(r1) + HCALL_INST_PRECALL - ld r8,STK_PARM(r8)(r1) /* Fetch r4-r7 ret args */ - ld r9,STK_PARM(r9)(r1) - ld r10,STK_PARM(r10)(r1) - ld r11,STK_PARM(r11)(r1) - std r4,0(r8) - std r5,0(r9) - std r6,0(r10) - std r7,0(r11) + std r4,STK_PARM(r4)(r1) /* Save ret buffer */ - mtcrf 0xff,r0 - blr /* return r3 = status */ - -/* plpar_hcall_7arg_7ret(unsigned long opcode, R3 - unsigned long arg1, R4 - unsigned long arg2, R5 - unsigned long arg3, R6 - unsigned long arg4, R7 - unsigned long arg5, R8 - unsigned long arg6, R9 - unsigned long arg7, R10 - unsigned long *out1, 112(R1) - unsigned long *out2, 110(R1) - unsigned long *out3, 108(R1) - unsigned long *out4, 106(R1) - unsigned long *out5, 104(R1) - unsigned long *out6, 102(R1) - unsigned long *out7); 100(R1) -*/ -_GLOBAL(plpar_hcall_7arg_7ret) - HMT_MEDIUM - - mfcr r0 - stw r0,8(r1) + mr r4,r5 + mr r5,r6 + mr r6,r7 + mr r7,r8 + mr r8,r9 + mr r9,r10 HVSC /* invoke the hypervisor */ - lwz r0,8(r1) + ld r12,STK_PARM(r4)(r1) + std r4, 0(r12) + std r5, 8(r12) + std r6, 16(r12) + std r7, 24(r12) - ld r11,STK_PARM(r11)(r1) /* Fetch r4 ret arg */ - std r4,0(r11) - ld r11,STK_PARM(r12)(r1) /* Fetch r5 ret arg */ - std r5,0(r11) - ld r11,STK_PARM(r13)(r1) /* Fetch r6 ret arg */ - std r6,0(r11) - ld r11,STK_PARM(r14)(r1) /* Fetch r7 ret arg */ - std r7,0(r11) - ld r11,STK_PARM(r15)(r1) /* Fetch r8 ret arg */ - std r8,0(r11) - ld r11,STK_PARM(r16)(r1) /* Fetch r9 ret arg */ - std r9,0(r11) - ld r11,STK_PARM(r17)(r1) /* Fetch r10 ret arg */ - std r10,0(r11) + HCALL_INST_POSTCALL + lwz r0,8(r1) mtcrf 0xff,r0 blr /* return r3 = status */ -/* plpar_hcall_9arg_9ret(unsigned long opcode, R3 - unsigned long arg1, R4 - unsigned long arg2, R5 - unsigned long arg3, R6 - unsigned long arg4, R7 - unsigned long arg5, R8 - unsigned long arg6, R9 - unsigned long arg7, R10 - unsigned long arg8, 112(R1) - unsigned long arg9, 110(R1) - unsigned long *out1, 108(R1) - unsigned long *out2, 106(R1) - unsigned long *out3, 104(R1) - unsigned long *out4, 102(R1) - unsigned long *out5, 100(R1) - unsigned long *out6, 98(R1) - unsigned long *out7); 96(R1) - unsigned long *out8, 94(R1) - unsigned long *out9, 92(R1) -*/ -_GLOBAL(plpar_hcall_9arg_9ret) +_GLOBAL(plpar_hcall9) HMT_MEDIUM mfcr r0 stw r0,8(r1) - ld r11,STK_PARM(r11)(r1) /* put arg8 in R11 */ - ld r12,STK_PARM(r12)(r1) /* put arg9 in R12 */ + HCALL_INST_PRECALL + + std r4,STK_PARM(r4)(r1) /* Save ret buffer */ + + mr r4,r5 + mr r5,r6 + mr r6,r7 + mr r7,r8 + mr r8,r9 + mr r9,r10 + ld r10,STK_PARM(r11)(r1) /* put arg7 in R10 */ + ld r11,STK_PARM(r12)(r1) /* put arg8 in R11 */ + ld r12,STK_PARM(r13)(r1) /* put arg9 in R12 */ HVSC /* invoke the hypervisor */ - ld r0,STK_PARM(r13)(r1) /* Fetch r4 ret arg */ - stdx r4,r0,r0 - ld r0,STK_PARM(r14)(r1) /* Fetch r5 ret arg */ - stdx r5,r0,r0 - ld r0,STK_PARM(r15)(r1) /* Fetch r6 ret arg */ - stdx r6,r0,r0 - ld r0,STK_PARM(r16)(r1) /* Fetch r7 ret arg */ - stdx r7,r0,r0 - ld r0,STK_PARM(r17)(r1) /* Fetch r8 ret arg */ - stdx r8,r0,r0 - ld r0,STK_PARM(r18)(r1) /* Fetch r9 ret arg */ - stdx r9,r0,r0 - ld r0,STK_PARM(r19)(r1) /* Fetch r10 ret arg */ - stdx r10,r0,r0 - ld r0,STK_PARM(r20)(r1) /* Fetch r11 ret arg */ - stdx r11,r0,r0 - ld r0,STK_PARM(r21)(r1) /* Fetch r12 ret arg */ - stdx r12,r0,r0 + ld r12,STK_PARM(r4)(r1) + std r4, 0(r12) + std r5, 8(r12) + std r6, 16(r12) + std r7, 24(r12) + std r8, 32(r12) + std r9, 40(r12) + std r10,48(r12) + std r11,56(r12) + std r12,64(r12) + + HCALL_INST_POSTCALL lwz r0,8(r1) mtcrf 0xff,r0 diff --git a/arch/powerpc/platforms/pseries/hvCall_inst.c b/arch/powerpc/platforms/pseries/hvCall_inst.c new file mode 100644 index 000000000000..446e17d162a5 --- /dev/null +++ b/arch/powerpc/platforms/pseries/hvCall_inst.c @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2006 Mike Kravetz IBM Corporation + * + * Hypervisor Call Instrumentation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/kernel.h> +#include <linux/percpu.h> +#include <linux/debugfs.h> +#include <linux/seq_file.h> +#include <linux/cpumask.h> +#include <asm/hvcall.h> +#include <asm/firmware.h> +#include <asm/cputable.h> + +DEFINE_PER_CPU(struct hcall_stats[HCALL_STAT_ARRAY_SIZE], hcall_stats); + +/* + * Routines for displaying the statistics in debugfs + */ +static void *hc_start(struct seq_file *m, loff_t *pos) +{ + if ((int)*pos < HCALL_STAT_ARRAY_SIZE) + return (void *)(unsigned long)(*pos + 1); + + return NULL; +} + +static void *hc_next(struct seq_file *m, void *p, loff_t * pos) +{ + ++*pos; + + return hc_start(m, pos); +} + +static void hc_stop(struct seq_file *m, void *p) +{ +} + +static int hc_show(struct seq_file *m, void *p) +{ + unsigned long h_num = (unsigned long)p; + struct hcall_stats *hs = (struct hcall_stats *)m->private; + + if (hs[h_num].num_calls) { + if (!cpu_has_feature(CPU_FTR_PURR)) + seq_printf(m, "%lu %lu %lu %lu\n", h_num<<2, + hs[h_num].num_calls, + hs[h_num].tb_total, + hs[h_num].purr_total); + else + seq_printf(m, "%lu %lu %lu\n", h_num<<2, + hs[h_num].num_calls, + hs[h_num].tb_total); + } + + return 0; +} + +static struct seq_operations hcall_inst_seq_ops = { + .start = hc_start, + .next = hc_next, + .stop = hc_stop, + .show = hc_show +}; + +static int hcall_inst_seq_open(struct inode *inode, struct file *file) +{ + int rc; + struct seq_file *seq; + + rc = seq_open(file, &hcall_inst_seq_ops); + seq = file->private_data; + seq->private = file->f_dentry->d_inode->i_private; + + return rc; +} + +static struct file_operations hcall_inst_seq_fops = { + .open = hcall_inst_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +#define HCALL_ROOT_DIR "hcall_inst" +#define CPU_NAME_BUF_SIZE 32 + +static int __init hcall_inst_init(void) +{ + struct dentry *hcall_root; + struct dentry *hcall_file; + char cpu_name_buf[CPU_NAME_BUF_SIZE]; + int cpu; + + if (!firmware_has_feature(FW_FEATURE_LPAR)) + return 0; + + hcall_root = debugfs_create_dir(HCALL_ROOT_DIR, NULL); + if (!hcall_root) + return -ENOMEM; + + for_each_possible_cpu(cpu) { + snprintf(cpu_name_buf, CPU_NAME_BUF_SIZE, "cpu%d", cpu); + hcall_file = debugfs_create_file(cpu_name_buf, S_IRUGO, + hcall_root, + per_cpu(hcall_stats, cpu), + &hcall_inst_seq_fops); + if (!hcall_file) + return -ENOMEM; + } + + return 0; +} +__initcall(hcall_inst_init); diff --git a/arch/powerpc/platforms/pseries/hvconsole.c b/arch/powerpc/platforms/pseries/hvconsole.c index a72a987f1d4d..3f6a89b09816 100644 --- a/arch/powerpc/platforms/pseries/hvconsole.c +++ b/arch/powerpc/platforms/pseries/hvconsole.c @@ -27,6 +27,7 @@ #include <linux/module.h> #include <asm/hvcall.h> #include <asm/hvconsole.h> +#include "plpar_wrappers.h" /** * hvc_get_chars - retrieve characters from firmware for denoted vterm adatper @@ -40,9 +41,9 @@ int hvc_get_chars(uint32_t vtermno, char *buf, int count) { unsigned long got; - if (plpar_hcall(H_GET_TERM_CHAR, vtermno, 0, 0, 0, &got, - (unsigned long *)buf, (unsigned long *)buf+1) == H_SUCCESS) + if (plpar_get_term_char(vtermno, &got, buf) == H_SUCCESS) return got; + return 0; } diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index d03a8b078f9d..bbf2e34dc358 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -24,7 +24,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <linux/config.h> #include <linux/init.h> #include <linux/types.h> #include <linux/slab.h> @@ -92,6 +91,15 @@ static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages) *(tcep++) = 0; } +static unsigned long tce_get_pseries(struct iommu_table *tbl, long index) +{ + u64 *tcep; + + index <<= TCE_PAGE_FACTOR; + tcep = ((u64 *)tbl->it_base) + index; + + return *tcep; +} static void tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages, unsigned long uaddr, @@ -235,18 +243,36 @@ static void tce_freemulti_pSeriesLP(struct iommu_table *tbl, long tcenum, long n } } +static unsigned long tce_get_pSeriesLP(struct iommu_table *tbl, long tcenum) +{ + u64 rc; + unsigned long tce_ret; + + tcenum <<= TCE_PAGE_FACTOR; + rc = plpar_tce_get((u64)tbl->it_index, (u64)tcenum << 12, &tce_ret); + + if (rc && printk_ratelimit()) { + printk("tce_get_pSeriesLP: plpar_tce_get failed. rc=%ld\n", + rc); + printk("\tindex = 0x%lx\n", (u64)tbl->it_index); + printk("\ttcenum = 0x%lx\n", (u64)tcenum); + show_stack(current, (unsigned long *)__get_SP()); + } + + return tce_ret; +} + static void iommu_table_setparms(struct pci_controller *phb, struct device_node *dn, struct iommu_table *tbl) { struct device_node *node; - unsigned long *basep; - unsigned int *sizep; + const unsigned long *basep, *sizep; node = (struct device_node *)phb->arch_data; - basep = (unsigned long *)get_property(node, "linux,tce-base", NULL); - sizep = (unsigned int *)get_property(node, "linux,tce-size", NULL); + basep = get_property(node, "linux,tce-base", NULL); + sizep = get_property(node, "linux,tce-size", NULL); if (basep == NULL || sizep == NULL) { printk(KERN_ERR "PCI_DMA: iommu_table_setparms: %s has " "missing tce entries !\n", dn->full_name); @@ -254,7 +280,10 @@ static void iommu_table_setparms(struct pci_controller *phb, } tbl->it_base = (unsigned long)__va(*basep); + +#ifndef CONFIG_CRASH_DUMP memset((void *)tbl->it_base, 0, *sizep); +#endif tbl->it_busno = phb->bus->number; @@ -285,7 +314,7 @@ static void iommu_table_setparms(struct pci_controller *phb, static void iommu_table_setparms_lpar(struct pci_controller *phb, struct device_node *dn, struct iommu_table *tbl, - unsigned char *dma_window) + const void *dma_window) { unsigned long offset, size; @@ -385,7 +414,7 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus) struct iommu_table *tbl; struct device_node *dn, *pdn; struct pci_dn *ppci; - unsigned char *dma_window = NULL; + const void *dma_window = NULL; DBG("iommu_bus_setup_pSeriesLP, bus %p, bus->self %p\n", bus, bus->self); @@ -489,7 +518,7 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev) { struct device_node *pdn, *dn; struct iommu_table *tbl; - unsigned char *dma_window = NULL; + const void *dma_window = NULL; struct pci_dn *pci; DBG("iommu_dev_setup_pSeriesLP, dev %p (%s)\n", dev, pci_name(dev)); @@ -560,11 +589,13 @@ void iommu_init_early_pSeries(void) ppc_md.tce_build = tce_build_pSeriesLP; ppc_md.tce_free = tce_free_pSeriesLP; } + ppc_md.tce_get = tce_get_pSeriesLP; ppc_md.iommu_bus_setup = iommu_bus_setup_pSeriesLP; ppc_md.iommu_dev_setup = iommu_dev_setup_pSeriesLP; } else { ppc_md.tce_build = tce_build_pSeries; ppc_md.tce_free = tce_free_pSeries; + ppc_md.tce_get = tce_get_pseries; ppc_md.iommu_bus_setup = iommu_bus_setup_pSeries; ppc_md.iommu_dev_setup = iommu_dev_setup_pSeries; } diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index 634b7d06d3cc..1820a0b0a8c6 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c @@ -21,7 +21,6 @@ #undef DEBUG_LOW -#include <linux/config.h> #include <linux/kernel.h> #include <linux/dma-mapping.h> #include <linux/console.h> @@ -49,13 +48,11 @@ #define DBG_LOW(fmt...) do { } while(0) #endif -/* in pSeries_hvCall.S */ +/* in hvCall.S */ EXPORT_SYMBOL(plpar_hcall); -EXPORT_SYMBOL(plpar_hcall_4out); +EXPORT_SYMBOL(plpar_hcall9); EXPORT_SYMBOL(plpar_hcall_norets); -EXPORT_SYMBOL(plpar_hcall_8arg_2ret); -EXPORT_SYMBOL(plpar_hcall_7arg_7ret); -EXPORT_SYMBOL(plpar_hcall_9arg_9ret); + extern void pSeries_find_serial_port(void); @@ -205,20 +202,20 @@ void __init udbg_init_debug_lpar(void) void __init find_udbg_vterm(void) { struct device_node *stdout_node; - u32 *termno; - char *name; + const u32 *termno; + const char *name; int add_console; /* find the boot console from /chosen/stdout */ if (!of_chosen) return; - name = (char *)get_property(of_chosen, "linux,stdout-path", NULL); + name = get_property(of_chosen, "linux,stdout-path", NULL); if (name == NULL) return; stdout_node = of_find_node_by_path(name); if (!stdout_node) return; - name = (char *)get_property(stdout_node, "name", NULL); + name = get_property(stdout_node, "name", NULL); if (!name) { printk(KERN_WARNING "stdout node missing 'name' property!\n"); goto out; @@ -229,7 +226,7 @@ void __init find_udbg_vterm(void) /* Check if it's a virtual terminal */ if (strncmp(name, "vty", 3) != 0) goto out; - termno = (u32 *)get_property(stdout_node, "reg", NULL); + termno = get_property(stdout_node, "reg", NULL); if (termno == NULL) goto out; vtermno = termno[0]; @@ -255,18 +252,34 @@ out: void vpa_init(int cpu) { int hwcpu = get_hard_smp_processor_id(cpu); - unsigned long vpa = __pa(&lppaca[cpu]); + unsigned long addr; long ret; if (cpu_has_feature(CPU_FTR_ALTIVEC)) lppaca[cpu].vmxregs_in_use = 1; - ret = register_vpa(hwcpu, vpa); + addr = __pa(&lppaca[cpu]); + ret = register_vpa(hwcpu, addr); - if (ret) + if (ret) { printk(KERN_ERR "WARNING: vpa_init: VPA registration for " "cpu %d (hw %d) of area %lx returns %ld\n", - cpu, hwcpu, vpa, ret); + cpu, hwcpu, addr, ret); + return; + } + /* + * PAPR says this feature is SLB-Buffer but firmware never + * reports that. All SPLPAR support SLB shadow buffer. + */ + addr = __pa(&slb_shadow[cpu]); + if (firmware_has_feature(FW_FEATURE_SPLPAR)) { + ret = register_slb_shadow(hwcpu, addr); + if (ret) + printk(KERN_ERR + "WARNING: vpa_init: SLB shadow buffer " + "registration for cpu %d (hw %d) of area %lx " + "returns %ld\n", cpu, hwcpu, addr, ret); + } } long pSeries_lpar_hpte_insert(unsigned long hpte_group, @@ -278,7 +291,6 @@ long pSeries_lpar_hpte_insert(unsigned long hpte_group, unsigned long flags; unsigned long slot; unsigned long hpte_v, hpte_r; - unsigned long dummy0, dummy1; if (!(vflags & HPTE_V_BOLTED)) DBG_LOW("hpte_insert(group=%lx, va=%016lx, pa=%016lx, " @@ -303,8 +315,7 @@ long pSeries_lpar_hpte_insert(unsigned long hpte_group, if (rflags & (_PAGE_GUARDED|_PAGE_NO_CACHE)) hpte_r &= ~_PAGE_COHERENT; - lpar_rc = plpar_hcall(H_ENTER, flags, hpte_group, hpte_v, - hpte_r, &slot, &dummy0, &dummy1); + lpar_rc = plpar_pte_enter(flags, hpte_group, hpte_v, hpte_r, &slot); if (unlikely(lpar_rc == H_PTEG_FULL)) { if (!(vflags & HPTE_V_BOLTED)) DBG_LOW(" full\n"); @@ -513,7 +524,7 @@ void pSeries_lpar_flush_hash_range(unsigned long number, int local) spin_unlock_irqrestore(&pSeries_lpar_tlbie_lock, flags); } -void hpte_init_lpar(void) +void __init hpte_init_lpar(void) { ppc_md.hpte_invalidate = pSeries_lpar_hpte_invalidate; ppc_md.hpte_updatepp = pSeries_lpar_hpte_updatepp; @@ -522,6 +533,4 @@ void hpte_init_lpar(void) ppc_md.hpte_remove = pSeries_lpar_hpte_remove; ppc_md.flush_hash_range = pSeries_lpar_flush_hash_range; ppc_md.hpte_clear_all = pSeries_lpar_hptab_clear; - - htab_finish_init(); } diff --git a/arch/powerpc/platforms/pseries/nvram.c b/arch/powerpc/platforms/pseries/nvram.c index 18abfb1f4e24..64163cecdf93 100644 --- a/arch/powerpc/platforms/pseries/nvram.c +++ b/arch/powerpc/platforms/pseries/nvram.c @@ -123,13 +123,14 @@ static ssize_t pSeries_nvram_get_size(void) int __init pSeries_nvram_init(void) { struct device_node *nvram; - unsigned int *nbytes_p, proplen; + const unsigned int *nbytes_p; + unsigned int proplen; nvram = of_find_node_by_type(NULL, "nvram"); if (nvram == NULL) return -ENODEV; - nbytes_p = (unsigned int *)get_property(nvram, "#bytes", &proplen); + nbytes_p = get_property(nvram, "#bytes", &proplen); if (nbytes_p == NULL || proplen != sizeof(unsigned int)) return -EIO; diff --git a/arch/powerpc/platforms/pseries/pci.c b/arch/powerpc/platforms/pseries/pci.c index e97e67f5e079..410a6bcc4ca0 100644 --- a/arch/powerpc/platforms/pseries/pci.c +++ b/arch/powerpc/platforms/pseries/pci.c @@ -60,7 +60,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_name_device); static void __devinit check_s7a(void) { struct device_node *root; - char *model; + const char *model; s7a_workaround = 0; root = of_find_node_by_path("/"); diff --git a/arch/powerpc/platforms/pseries/plpar_wrappers.h b/arch/powerpc/platforms/pseries/plpar_wrappers.h index 3bd1b3e06003..3eb7b294d92f 100644 --- a/arch/powerpc/platforms/pseries/plpar_wrappers.h +++ b/arch/powerpc/platforms/pseries/plpar_wrappers.h @@ -5,20 +5,17 @@ static inline long poll_pending(void) { - unsigned long dummy; - return plpar_hcall(H_POLL_PENDING, 0, 0, 0, 0, &dummy, &dummy, &dummy); + return plpar_hcall_norets(H_POLL_PENDING); } static inline long prod_processor(void) { - plpar_hcall_norets(H_PROD); - return 0; + return plpar_hcall_norets(H_PROD); } static inline long cede_processor(void) { - plpar_hcall_norets(H_CEDE); - return 0; + return plpar_hcall_norets(H_CEDE); } static inline long vpa_call(unsigned long flags, unsigned long cpu, @@ -40,23 +37,59 @@ static inline long register_vpa(unsigned long cpu, unsigned long vpa) return vpa_call(0x1, cpu, vpa); } +static inline long unregister_slb_shadow(unsigned long cpu, unsigned long vpa) +{ + return vpa_call(0x7, cpu, vpa); +} + +static inline long register_slb_shadow(unsigned long cpu, unsigned long vpa) +{ + return vpa_call(0x3, cpu, vpa); +} + extern void vpa_init(int cpu); +static inline long plpar_pte_enter(unsigned long flags, + unsigned long hpte_group, unsigned long hpte_v, + unsigned long hpte_r, unsigned long *slot) +{ + long rc; + unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; + + rc = plpar_hcall(H_ENTER, retbuf, flags, hpte_group, hpte_v, hpte_r); + + *slot = retbuf[0]; + + return rc; +} + static inline long plpar_pte_remove(unsigned long flags, unsigned long ptex, unsigned long avpn, unsigned long *old_pteh_ret, unsigned long *old_ptel_ret) { - unsigned long dummy; - return plpar_hcall(H_REMOVE, flags, ptex, avpn, 0, old_pteh_ret, - old_ptel_ret, &dummy); + long rc; + unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; + + rc = plpar_hcall(H_REMOVE, retbuf, flags, ptex, avpn); + + *old_pteh_ret = retbuf[0]; + *old_ptel_ret = retbuf[1]; + + return rc; } static inline long plpar_pte_read(unsigned long flags, unsigned long ptex, unsigned long *old_pteh_ret, unsigned long *old_ptel_ret) { - unsigned long dummy; - return plpar_hcall(H_READ, flags, ptex, 0, 0, old_pteh_ret, - old_ptel_ret, &dummy); + long rc; + unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; + + rc = plpar_hcall(H_READ, retbuf, flags, ptex); + + *old_pteh_ret = retbuf[0]; + *old_ptel_ret = retbuf[1]; + + return rc; } static inline long plpar_pte_protect(unsigned long flags, unsigned long ptex, @@ -68,9 +101,14 @@ static inline long plpar_pte_protect(unsigned long flags, unsigned long ptex, static inline long plpar_tce_get(unsigned long liobn, unsigned long ioba, unsigned long *tce_ret) { - unsigned long dummy; - return plpar_hcall(H_GET_TCE, liobn, ioba, 0, 0, tce_ret, &dummy, - &dummy); + long rc; + unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; + + rc = plpar_hcall(H_GET_TCE, retbuf, liobn, ioba); + + *tce_ret = retbuf[0]; + + return rc; } static inline long plpar_tce_put(unsigned long liobn, unsigned long ioba, @@ -94,9 +132,17 @@ static inline long plpar_tce_stuff(unsigned long liobn, unsigned long ioba, static inline long plpar_get_term_char(unsigned long termno, unsigned long *len_ret, char *buf_ret) { + long rc; + unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; unsigned long *lbuf = (unsigned long *)buf_ret; /* TODO: alignment? */ - return plpar_hcall(H_GET_TERM_CHAR, termno, 0, 0, 0, len_ret, - lbuf + 0, lbuf + 1); + + rc = plpar_hcall(H_GET_TERM_CHAR, retbuf, termno); + + *len_ret = retbuf[0]; + lbuf[0] = retbuf[1]; + lbuf[1] = retbuf[2]; + + return rc; } static inline long plpar_put_term_char(unsigned long termno, unsigned long len, @@ -107,4 +153,31 @@ static inline long plpar_put_term_char(unsigned long termno, unsigned long len, lbuf[1]); } +static inline long plpar_eoi(unsigned long xirr) +{ + return plpar_hcall_norets(H_EOI, xirr); +} + +static inline long plpar_cppr(unsigned long cppr) +{ + return plpar_hcall_norets(H_CPPR, cppr); +} + +static inline long plpar_ipi(unsigned long servernum, unsigned long mfrr) +{ + return plpar_hcall_norets(H_IPI, servernum, mfrr); +} + +static inline long plpar_xirr(unsigned long *xirr_ret) +{ + long rc; + unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; + + rc = plpar_hcall(H_XIRR, retbuf); + + *xirr_ret = retbuf[0]; + + return rc; +} + #endif /* _PSERIES_PLPAR_WRAPPERS_H */ diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c index 9639c66b453d..311ed1993fc0 100644 --- a/arch/powerpc/platforms/pseries/ras.c +++ b/arch/powerpc/platforms/pseries/ras.c @@ -72,32 +72,61 @@ static irqreturn_t ras_error_interrupt(int irq, void *dev_id, /* #define DEBUG */ -static void request_ras_irqs(struct device_node *np, char *propname, + +static void request_ras_irqs(struct device_node *np, irqreturn_t (*handler)(int, void *, struct pt_regs *), const char *name) { - unsigned int *ireg, len, i; - int virq, n_intr; - - ireg = (unsigned int *)get_property(np, propname, &len); - if (ireg == NULL) - return; - n_intr = prom_n_intr_cells(np); - len /= n_intr * sizeof(*ireg); - - for (i = 0; i < len; i++) { - virq = virt_irq_create_mapping(*ireg); - if (virq == NO_IRQ) { - printk(KERN_ERR "Unable to allocate interrupt " - "number for %s\n", np->full_name); - return; + int i, index, count = 0; + struct of_irq oirq; + const u32 *opicprop; + unsigned int opicplen; + unsigned int virqs[16]; + + /* Check for obsolete "open-pic-interrupt" property. If present, then + * map those interrupts using the default interrupt host and default + * trigger + */ + opicprop = get_property(np, "open-pic-interrupt", &opicplen); + if (opicprop) { + opicplen /= sizeof(u32); + for (i = 0; i < opicplen; i++) { + if (count > 15) + break; + virqs[count] = irq_create_mapping(NULL, *(opicprop++)); + if (virqs[count] == NO_IRQ) + printk(KERN_ERR "Unable to allocate interrupt " + "number for %s\n", np->full_name); + else + count++; + } - if (request_irq(irq_offset_up(virq), handler, 0, name, NULL)) { + } + /* Else use normal interrupt tree parsing */ + else { + /* First try to do a proper OF tree parsing */ + for (index = 0; of_irq_map_one(np, index, &oirq) == 0; + index++) { + if (count > 15) + break; + virqs[count] = irq_create_of_mapping(oirq.controller, + oirq.specifier, + oirq.size); + if (virqs[count] == NO_IRQ) + printk(KERN_ERR "Unable to allocate interrupt " + "number for %s\n", np->full_name); + else + count++; + } + } + + /* Now request them */ + for (i = 0; i < count; i++) { + if (request_irq(virqs[i], handler, 0, name, NULL)) { printk(KERN_ERR "Unable to request interrupt %d for " - "%s\n", irq_offset_up(virq), np->full_name); + "%s\n", virqs[i], np->full_name); return; } - ireg += n_intr; } } @@ -115,20 +144,14 @@ static int __init init_ras_IRQ(void) /* Internal Errors */ np = of_find_node_by_path("/event-sources/internal-errors"); if (np != NULL) { - request_ras_irqs(np, "open-pic-interrupt", ras_error_interrupt, - "RAS_ERROR"); - request_ras_irqs(np, "interrupts", ras_error_interrupt, - "RAS_ERROR"); + request_ras_irqs(np, ras_error_interrupt, "RAS_ERROR"); of_node_put(np); } /* EPOW Events */ np = of_find_node_by_path("/event-sources/epow-events"); if (np != NULL) { - request_ras_irqs(np, "open-pic-interrupt", ras_epow_interrupt, - "RAS_EPOW"); - request_ras_irqs(np, "interrupts", ras_epow_interrupt, - "RAS_EPOW"); + request_ras_irqs(np, ras_epow_interrupt, "RAS_EPOW"); of_node_put(np); } @@ -162,7 +185,7 @@ ras_epow_interrupt(int irq, void *dev_id, struct pt_regs * regs) status = rtas_call(ras_check_exception_token, 6, 1, NULL, RAS_VECTOR_OFFSET, - virt_irq_to_real(irq_offset_down(irq)), + irq_map[irq].hwirq, RTAS_EPOW_WARNING | RTAS_POWERMGM_EVENTS, critical, __pa(&ras_log_buf), rtas_get_error_log_max()); @@ -198,7 +221,7 @@ ras_error_interrupt(int irq, void *dev_id, struct pt_regs * regs) status = rtas_call(ras_check_exception_token, 6, 1, NULL, RAS_VECTOR_OFFSET, - virt_irq_to_real(irq_offset_down(irq)), + irq_map[irq].hwirq, RTAS_INTERNAL_ERROR, 1 /*Time Critical */, __pa(&ras_log_buf), rtas_get_error_log_max()); @@ -314,7 +337,7 @@ static int recover_mce(struct pt_regs *regs, struct rtas_error_log * err) err->disposition == RTAS_DISP_NOT_RECOVERED && err->target == RTAS_TARGET_MEMORY && err->type == RTAS_TYPE_ECC_UNCORR && - !(current->pid == 0 || current->pid == 1)) { + !(current->pid == 0 || is_init(current))) { /* Kill off a user process with an ECC error */ printk(KERN_ERR "MCE: uncorrectable ecc error for pid %d\n", current->pid); diff --git a/arch/powerpc/platforms/pseries/rtasd.c b/arch/powerpc/platforms/pseries/rtasd.c index 2e4e04042d85..8ca2612221d6 100644 --- a/arch/powerpc/platforms/pseries/rtasd.c +++ b/arch/powerpc/platforms/pseries/rtasd.c @@ -359,11 +359,11 @@ static int enable_surveillance(int timeout) static int get_eventscan_parms(void) { struct device_node *node; - int *ip; + const int *ip; node = of_find_node_by_path("/rtas"); - ip = (int *)get_property(node, "rtas-event-scan-rate", NULL); + ip = get_property(node, "rtas-event-scan-rate", NULL); if (ip == NULL) { printk(KERN_ERR "rtasd: no rtas-event-scan-rate\n"); of_node_put(node); diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 1e28518c6121..a6398fbe530d 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -18,7 +18,6 @@ #undef DEBUG -#include <linux/config.h> #include <linux/cpu.h> #include <linux/errno.h> #include <linux/sched.h> @@ -77,6 +76,9 @@ #define DBG(fmt...) #endif +/* move those away to a .h */ +extern void smp_init_pseries_mpic(void); +extern void smp_init_pseries_xics(void); extern void find_udbg_vterm(void); int fwnmi_active; /* TRUE if an FWNMI handler is present */ @@ -84,7 +86,7 @@ int fwnmi_active; /* TRUE if an FWNMI handler is present */ static void pseries_shared_idle_sleep(void); static void pseries_dedicated_idle_sleep(void); -struct mpic *pSeries_mpic; +static struct device_node *pSeries_mpic_node; static void pSeries_show_cpuinfo(struct seq_file *m) { @@ -119,71 +121,98 @@ static void __init fwnmi_init(void) fwnmi_active = 1; } -static void __init pSeries_init_mpic(void) +void pseries_8259_cascade(unsigned int irq, struct irq_desc *desc, + struct pt_regs *regs) { - unsigned int *addrp; - struct device_node *np; - unsigned long intack = 0; - - /* All ISUs are setup, complete initialization */ - mpic_init(pSeries_mpic); - - /* Check what kind of cascade ACK we have */ - if (!(np = of_find_node_by_name(NULL, "pci")) - || !(addrp = (unsigned int *) - get_property(np, "8259-interrupt-acknowledge", NULL))) - printk(KERN_ERR "Cannot find pci to get ack address\n"); - else - intack = addrp[prom_n_addr_cells(np)-1]; - of_node_put(np); - - /* Setup the legacy interrupts & controller */ - i8259_init(intack, 0); - - /* Hook cascade to mpic */ - mpic_setup_cascade(NUM_ISA_INTERRUPTS, i8259_irq_cascade, NULL); + unsigned int cascade_irq = i8259_irq(regs); + if (cascade_irq != NO_IRQ) + generic_handle_irq(cascade_irq, regs); + desc->chip->eoi(irq); } -static void __init pSeries_setup_mpic(void) +static void __init pseries_mpic_init_IRQ(void) { - unsigned int *opprop; + struct device_node *np, *old, *cascade = NULL; + const unsigned int *addrp; + unsigned long intack = 0; + const unsigned int *opprop; unsigned long openpic_addr = 0; - unsigned char senses[NR_IRQS - NUM_ISA_INTERRUPTS]; - struct device_node *root; - int irq_count; + unsigned int cascade_irq; + int naddr, n, i, opplen; + struct mpic *mpic; - /* Find the Open PIC if present */ - root = of_find_node_by_path("/"); - opprop = (unsigned int *) get_property(root, "platform-open-pic", NULL); + np = of_find_node_by_path("/"); + naddr = prom_n_addr_cells(np); + opprop = get_property(np, "platform-open-pic", &opplen); if (opprop != 0) { - int n = prom_n_addr_cells(root); - - for (openpic_addr = 0; n > 0; --n) - openpic_addr = (openpic_addr << 32) + *opprop++; + openpic_addr = of_read_number(opprop, naddr); printk(KERN_DEBUG "OpenPIC addr: %lx\n", openpic_addr); } - of_node_put(root); + of_node_put(np); BUG_ON(openpic_addr == 0); - /* Get the sense values from OF */ - prom_get_irq_senses(senses, NUM_ISA_INTERRUPTS, NR_IRQS); - /* Setup the openpic driver */ - irq_count = NR_IRQS - NUM_ISA_INTERRUPTS - 4; /* leave room for IPIs */ - pSeries_mpic = mpic_alloc(openpic_addr, MPIC_PRIMARY, - 16, 16, irq_count, /* isu size, irq offset, irq count */ - NR_IRQS - 4, /* ipi offset */ - senses, irq_count, /* sense & sense size */ - " MPIC "); + mpic = mpic_alloc(pSeries_mpic_node, openpic_addr, + MPIC_PRIMARY, + 16, 250, /* isu size, irq count */ + " MPIC "); + BUG_ON(mpic == NULL); + + /* Add ISUs */ + opplen /= sizeof(u32); + for (n = 0, i = naddr; i < opplen; i += naddr, n++) { + unsigned long isuaddr = of_read_number(opprop + i, naddr); + mpic_assign_isu(mpic, n, isuaddr); + } + + /* All ISUs are setup, complete initialization */ + mpic_init(mpic); + + /* Look for cascade */ + for_each_node_by_type(np, "interrupt-controller") + if (device_is_compatible(np, "chrp,iic")) { + cascade = np; + break; + } + if (cascade == NULL) + return; + + cascade_irq = irq_of_parse_and_map(cascade, 0); + if (cascade == NO_IRQ) { + printk(KERN_ERR "xics: failed to map cascade interrupt"); + return; + } + + /* Check ACK type */ + for (old = of_node_get(cascade); old != NULL ; old = np) { + np = of_get_parent(old); + of_node_put(old); + if (np == NULL) + break; + if (strcmp(np->name, "pci") != 0) + continue; + addrp = get_property(np, "8259-interrupt-acknowledge", + NULL); + if (addrp == NULL) + continue; + naddr = prom_n_addr_cells(np); + intack = addrp[naddr-1]; + if (naddr > 1) + intack |= ((unsigned long)addrp[naddr-2]) << 32; + } + if (intack) + printk(KERN_DEBUG "mpic: PCI 8259 intack at 0x%016lx\n", + intack); + i8259_init(cascade, intack); + of_node_put(cascade); + set_irq_chained_handler(cascade_irq, pseries_8259_cascade); } static void pseries_lpar_enable_pmcs(void) { unsigned long set, reset; - power4_enable_pmcs(); - set = 1UL << 63; reset = 0; plpar_hcall_norets(H_PERFMON, set, reset); @@ -193,23 +222,81 @@ static void pseries_lpar_enable_pmcs(void) get_lppaca()->pmcregs_in_use = 1; } -static void __init pSeries_setup_arch(void) +#ifdef CONFIG_KEXEC +static void pseries_kexec_cpu_down(int crash_shutdown, int secondary) { - /* Fixup ppc_md depending on the type of interrupt controller */ - if (ppc64_interrupt_controller == IC_OPEN_PIC) { - ppc_md.init_IRQ = pSeries_init_mpic; - ppc_md.get_irq = mpic_get_irq; - /* Allocate the mpic now, so that find_and_init_phbs() can - * fill the ISUs */ - pSeries_setup_mpic(); - } else { - ppc_md.init_IRQ = xics_init_IRQ; - ppc_md.get_irq = xics_get_irq; + /* Don't risk a hypervisor call if we're crashing */ + if (firmware_has_feature(FW_FEATURE_SPLPAR) && !crash_shutdown) { + unsigned long addr; + + addr = __pa(get_slb_shadow()); + if (unregister_slb_shadow(hard_smp_processor_id(), addr)) + printk("SLB shadow buffer deregistration of " + "cpu %u (hw_cpu_id %d) failed\n", + smp_processor_id(), + hard_smp_processor_id()); + + addr = __pa(get_lppaca()); + if (unregister_vpa(hard_smp_processor_id(), addr)) { + printk("VPA deregistration of cpu %u (hw_cpu_id %d) " + "failed\n", smp_processor_id(), + hard_smp_processor_id()); + } } +} +static void pseries_kexec_cpu_down_mpic(int crash_shutdown, int secondary) +{ + pseries_kexec_cpu_down(crash_shutdown, secondary); + mpic_teardown_this_cpu(secondary); +} + +static void pseries_kexec_cpu_down_xics(int crash_shutdown, int secondary) +{ + pseries_kexec_cpu_down(crash_shutdown, secondary); + xics_teardown_cpu(secondary); +} +#endif /* CONFIG_KEXEC */ + +static void __init pseries_discover_pic(void) +{ + struct device_node *np; + const char *typep; + + for (np = NULL; (np = of_find_node_by_name(np, + "interrupt-controller"));) { + typep = get_property(np, "compatible", NULL); + if (strstr(typep, "open-pic")) { + pSeries_mpic_node = of_node_get(np); + ppc_md.init_IRQ = pseries_mpic_init_IRQ; + ppc_md.get_irq = mpic_get_irq; +#ifdef CONFIG_KEXEC + ppc_md.kexec_cpu_down = pseries_kexec_cpu_down_mpic; +#endif #ifdef CONFIG_SMP - smp_init_pSeries(); + smp_init_pseries_mpic(); #endif + return; + } else if (strstr(typep, "ppc-xicp")) { + ppc_md.init_IRQ = xics_init_IRQ; +#ifdef CONFIG_KEXEC + ppc_md.kexec_cpu_down = pseries_kexec_cpu_down_xics; +#endif +#ifdef CONFIG_SMP + smp_init_pseries_xics(); +#endif + return; + } + } + printk(KERN_ERR "pSeries_discover_pic: failed to recognize" + " interrupt-controller\n"); +} + +static void __init pSeries_setup_arch(void) +{ + /* Discover PIC type and setup ppc_md accordingly */ + pseries_discover_pic(); + /* openpic global configuration register (64-bit format). */ /* openpic Interrupt Source Unit pointer (64-bit format). */ /* python0 facility area (mmio) (64-bit format) REAL address. */ @@ -261,41 +348,11 @@ static int __init pSeries_init_panel(void) } arch_initcall(pSeries_init_panel); -static void __init pSeries_discover_pic(void) -{ - struct device_node *np; - char *typep; - - /* - * Setup interrupt mapping options that are needed for finish_device_tree - * to properly parse the OF interrupt tree & do the virtual irq mapping - */ - __irq_offset_value = NUM_ISA_INTERRUPTS; - ppc64_interrupt_controller = IC_INVALID; - for (np = NULL; (np = of_find_node_by_name(np, "interrupt-controller"));) { - typep = (char *)get_property(np, "compatible", NULL); - if (strstr(typep, "open-pic")) { - ppc64_interrupt_controller = IC_OPEN_PIC; - break; - } else if (strstr(typep, "ppc-xicp")) { - ppc64_interrupt_controller = IC_PPC_XIC; - break; - } - } - if (ppc64_interrupt_controller == IC_INVALID) - printk("pSeries_discover_pic: failed to recognize" - " interrupt-controller\n"); - -} - static void pSeries_mach_cpu_die(void) { local_irq_disable(); idle_task_exit(); - /* Some hardware requires clearing the CPPR, while other hardware does not - * it is safe either way - */ - pSeriesLP_cppr_info(0, 0); + xics_teardown_cpu(0); rtas_stop_self(); /* Should never get here... */ BUG(); @@ -322,11 +379,6 @@ static void __init pSeries_init_early(void) DBG(" -> pSeries_init_early()\n"); fw_feature_init(); - - if (firmware_has_feature(FW_FEATURE_LPAR)) - hpte_init_lpar(); - else - hpte_init_native(); if (firmware_has_feature(FW_FEATURE_LPAR)) find_udbg_vterm(); @@ -338,8 +390,6 @@ static void __init pSeries_init_early(void) iommu_init_early_pSeries(); - pSeries_discover_pic(); - DBG(" <- pSeries_init_early()\n"); } @@ -384,6 +434,11 @@ static int __init pSeries_probe_hypertas(unsigned long node, if (of_get_flat_dt_prop(node, "ibm,hypertas-functions", NULL) != NULL) powerpc_firmware_features |= FW_FEATURE_LPAR; + if (firmware_has_feature(FW_FEATURE_LPAR)) + hpte_init_lpar(); + else + hpte_init_native(); + return 1; } @@ -458,7 +513,8 @@ static void pseries_dedicated_idle_sleep(void) } /* - * Cede if the other thread is not idle, so that it can + * If not SMT, cede processor. If CPU is running SMT + * cede if the other thread is not idle, so that it can * go single-threaded. If the other thread is idle, * we ask the hypervisor if it has pending work it * wants to do and cede if it does. Otherwise we keep @@ -471,7 +527,8 @@ static void pseries_dedicated_idle_sleep(void) * very low priority. The cede enables interrupts, which * doesn't matter here. */ - if (!lppaca[cpu ^ 1].idle || poll_pending() == H_PENDING) + if (!cpu_has_feature(CPU_FTR_SMT) || !lppaca[cpu ^ 1].idle + || poll_pending() == H_PENDING) cede_processor(); out: @@ -506,27 +563,6 @@ static int pSeries_pci_probe_mode(struct pci_bus *bus) return PCI_PROBE_NORMAL; } -#ifdef CONFIG_KEXEC -static void pseries_kexec_cpu_down(int crash_shutdown, int secondary) -{ - /* Don't risk a hypervisor call if we're crashing */ - if (firmware_has_feature(FW_FEATURE_SPLPAR) && !crash_shutdown) { - unsigned long vpa = __pa(get_lppaca()); - - if (unregister_vpa(hard_smp_processor_id(), vpa)) { - printk("VPA deregistration of cpu %u (hw_cpu_id %d) " - "failed\n", smp_processor_id(), - hard_smp_processor_id()); - } - } - - if (ppc64_interrupt_controller == IC_OPEN_PIC) - mpic_teardown_this_cpu(secondary); - else - xics_teardown_cpu(secondary); -} -#endif - define_machine(pseries) { .name = "pSeries", .probe = pSeries_probe, @@ -551,7 +587,6 @@ define_machine(pseries) { .system_reset_exception = pSeries_system_reset_exception, .machine_check_exception = pSeries_machine_check_exception, #ifdef CONFIG_KEXEC - .kexec_cpu_down = pseries_kexec_cpu_down, .machine_kexec = default_machine_kexec, .machine_kexec_prepare = default_machine_kexec_prepare, .machine_crash_shutdown = default_machine_crash_shutdown, diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c index 3cf78a6cd27c..c6624b8a0e77 100644 --- a/arch/powerpc/platforms/pseries/smp.c +++ b/arch/powerpc/platforms/pseries/smp.c @@ -14,7 +14,6 @@ #undef DEBUG -#include <linux/config.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/sched.h> @@ -63,7 +62,7 @@ */ static cpumask_t of_spin_map; -extern void pSeries_secondary_smp_init(unsigned long); +extern void generic_secondary_smp_init(unsigned long); #ifdef CONFIG_HOTPLUG_CPU @@ -146,9 +145,9 @@ static int pSeries_add_processor(struct device_node *np) unsigned int cpu; cpumask_t candidate_map, tmp = CPU_MASK_NONE; int err = -ENOSPC, len, nthreads, i; - u32 *intserv; + const u32 *intserv; - intserv = (u32 *)get_property(np, "ibm,ppc-interrupt-server#s", &len); + intserv = get_property(np, "ibm,ppc-interrupt-server#s", &len); if (!intserv) return 0; @@ -206,9 +205,9 @@ static void pSeries_remove_processor(struct device_node *np) { unsigned int cpu; int len, nthreads, i; - u32 *intserv; + const u32 *intserv; - intserv = (u32 *)get_property(np, "ibm,ppc-interrupt-server#s", &len); + intserv = get_property(np, "ibm,ppc-interrupt-server#s", &len); if (!intserv) return; @@ -271,7 +270,7 @@ static inline int __devinit smp_startup_cpu(unsigned int lcpu) { int status; unsigned long start_here = __pa((u32)*((unsigned long *) - pSeries_secondary_smp_init)); + generic_secondary_smp_init)); unsigned int pcpu; int start_cpu; @@ -417,27 +416,12 @@ static struct smp_ops_t pSeries_xics_smp_ops = { #endif /* This is called very early */ -void __init smp_init_pSeries(void) +static void __init smp_init_pseries(void) { int i; DBG(" -> smp_init_pSeries()\n"); - switch (ppc64_interrupt_controller) { -#ifdef CONFIG_MPIC - case IC_OPEN_PIC: - smp_ops = &pSeries_mpic_smp_ops; - break; -#endif -#ifdef CONFIG_XICS - case IC_PPC_XIC: - smp_ops = &pSeries_xics_smp_ops; - break; -#endif - default: - panic("Invalid interrupt controller"); - } - #ifdef CONFIG_HOTPLUG_CPU smp_ops->cpu_disable = pSeries_cpu_disable; smp_ops->cpu_die = pSeries_cpu_die; @@ -472,3 +456,18 @@ void __init smp_init_pSeries(void) DBG(" <- smp_init_pSeries()\n"); } +#ifdef CONFIG_MPIC +void __init smp_init_pseries_mpic(void) +{ + smp_ops = &pSeries_mpic_smp_ops; + + smp_init_pseries(); +} +#endif + +void __init smp_init_pseries_xics(void) +{ + smp_ops = &pSeries_xics_smp_ops; + + smp_init_pseries(); +} diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c index b14f9b5c114e..253972e5479f 100644 --- a/arch/powerpc/platforms/pseries/xics.c +++ b/arch/powerpc/platforms/pseries/xics.c @@ -8,7 +8,9 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> + +#undef DEBUG + #include <linux/types.h> #include <linux/threads.h> #include <linux/kernel.h> @@ -20,6 +22,7 @@ #include <linux/gfp.h> #include <linux/radix-tree.h> #include <linux/cpu.h> + #include <asm/firmware.h> #include <asm/prom.h> #include <asm/io.h> @@ -31,26 +34,7 @@ #include <asm/i8259.h> #include "xics.h" - -static unsigned int xics_startup(unsigned int irq); -static void xics_enable_irq(unsigned int irq); -static void xics_disable_irq(unsigned int irq); -static void xics_mask_and_ack_irq(unsigned int irq); -static void xics_end_irq(unsigned int irq); -static void xics_set_affinity(unsigned int irq_nr, cpumask_t cpumask); - -static struct hw_interrupt_type xics_pic = { - .typename = " XICS ", - .startup = xics_startup, - .enable = xics_enable_irq, - .disable = xics_disable_irq, - .ack = xics_mask_and_ack_irq, - .end = xics_end_irq, - .set_affinity = xics_set_affinity -}; - -/* This is used to map real irq numbers to virtual */ -static struct radix_tree_root irq_map = RADIX_TREE_INIT(GFP_ATOMIC); +#include "plpar_wrappers.h" #define XICS_IPI 2 #define XICS_IRQ_SPURIOUS 0 @@ -60,7 +44,7 @@ static struct radix_tree_root irq_map = RADIX_TREE_INIT(GFP_ATOMIC); /* * Mark IPIs as higher priority so we can take them inside interrupts that - * arent marked SA_INTERRUPT + * arent marked IRQF_DISABLED */ #define IPI_PRIORITY 4 @@ -82,12 +66,12 @@ struct xics_ipl { static struct xics_ipl __iomem *xics_per_cpu[NR_CPUS]; -static int xics_irq_8259_cascade = 0; -static int xics_irq_8259_cascade_real = 0; static unsigned int default_server = 0xFF; static unsigned int default_distrib_server = 0; static unsigned int interrupt_server_size = 8; +static struct irq_host *xics_host; + /* * XICS only has a single IPI, so encode the messages per CPU */ @@ -99,70 +83,35 @@ static int ibm_set_xive; static int ibm_int_on; static int ibm_int_off; -typedef struct { - int (*xirr_info_get)(int cpu); - void (*xirr_info_set)(int cpu, int val); - void (*cppr_info)(int cpu, u8 val); - void (*qirr_info)(int cpu, u8 val); -} xics_ops; +/* Direct HW low level accessors */ -/* SMP */ -static int pSeries_xirr_info_get(int n_cpu) +static inline unsigned int direct_xirr_info_get(int n_cpu) { return in_be32(&xics_per_cpu[n_cpu]->xirr.word); } -static void pSeries_xirr_info_set(int n_cpu, int value) +static inline void direct_xirr_info_set(int n_cpu, int value) { out_be32(&xics_per_cpu[n_cpu]->xirr.word, value); } -static void pSeries_cppr_info(int n_cpu, u8 value) +static inline void direct_cppr_info(int n_cpu, u8 value) { out_8(&xics_per_cpu[n_cpu]->xirr.bytes[0], value); } -static void pSeries_qirr_info(int n_cpu, u8 value) +static inline void direct_qirr_info(int n_cpu, u8 value) { out_8(&xics_per_cpu[n_cpu]->qirr.bytes[0], value); } -static xics_ops pSeries_ops = { - pSeries_xirr_info_get, - pSeries_xirr_info_set, - pSeries_cppr_info, - pSeries_qirr_info -}; - -static xics_ops *ops = &pSeries_ops; +/* LPAR low level accessors */ -/* LPAR */ - -static inline long plpar_eoi(unsigned long xirr) -{ - return plpar_hcall_norets(H_EOI, xirr); -} - -static inline long plpar_cppr(unsigned long cppr) -{ - return plpar_hcall_norets(H_CPPR, cppr); -} -static inline long plpar_ipi(unsigned long servernum, unsigned long mfrr) -{ - return plpar_hcall_norets(H_IPI, servernum, mfrr); -} - -static inline long plpar_xirr(unsigned long *xirr_ret) -{ - unsigned long dummy; - return plpar_hcall(H_XIRR, 0, 0, 0, 0, xirr_ret, &dummy, &dummy); -} - -static int pSeriesLP_xirr_info_get(int n_cpu) +static inline unsigned int lpar_xirr_info_get(int n_cpu) { unsigned long lpar_rc; unsigned long return_value; @@ -170,10 +119,10 @@ static int pSeriesLP_xirr_info_get(int n_cpu) lpar_rc = plpar_xirr(&return_value); if (lpar_rc != H_SUCCESS) panic(" bad return code xirr - rc = %lx \n", lpar_rc); - return (int)return_value; + return (unsigned int)return_value; } -static void pSeriesLP_xirr_info_set(int n_cpu, int value) +static inline void lpar_xirr_info_set(int n_cpu, int value) { unsigned long lpar_rc; unsigned long val64 = value & 0xffffffff; @@ -184,7 +133,7 @@ static void pSeriesLP_xirr_info_set(int n_cpu, int value) val64); } -void pSeriesLP_cppr_info(int n_cpu, u8 value) +static inline void lpar_cppr_info(int n_cpu, u8 value) { unsigned long lpar_rc; @@ -193,7 +142,7 @@ void pSeriesLP_cppr_info(int n_cpu, u8 value) panic("bad return code cppr - rc = %lx\n", lpar_rc); } -static void pSeriesLP_qirr_info(int n_cpu , u8 value) +static inline void lpar_qirr_info(int n_cpu , u8 value) { unsigned long lpar_rc; @@ -202,43 +151,16 @@ static void pSeriesLP_qirr_info(int n_cpu , u8 value) panic("bad return code qirr - rc = %lx\n", lpar_rc); } -xics_ops pSeriesLP_ops = { - pSeriesLP_xirr_info_get, - pSeriesLP_xirr_info_set, - pSeriesLP_cppr_info, - pSeriesLP_qirr_info -}; - -static unsigned int xics_startup(unsigned int virq) -{ - unsigned int irq; - - irq = irq_offset_down(virq); - if (radix_tree_insert(&irq_map, virt_irq_to_real(irq), - &virt_irq_to_real_map[irq]) == -ENOMEM) - printk(KERN_CRIT "Out of memory creating real -> virtual" - " IRQ mapping for irq %u (real 0x%x)\n", - virq, virt_irq_to_real(irq)); - xics_enable_irq(virq); - return 0; /* return value is ignored */ -} -static unsigned int real_irq_to_virt(unsigned int real_irq) -{ - unsigned int *ptr; +/* High level handlers and init code */ - ptr = radix_tree_lookup(&irq_map, real_irq); - if (ptr == NULL) - return NO_IRQ; - return ptr - virt_irq_to_real_map; -} #ifdef CONFIG_SMP -static int get_irq_server(unsigned int irq) +static int get_irq_server(unsigned int virq) { unsigned int server; /* For the moment only implement delivery to all cpus or one cpu */ - cpumask_t cpumask = irq_affinity[irq]; + cpumask_t cpumask = irq_desc[virq].affinity; cpumask_t tmp = CPU_MASK_NONE; if (!distribute_irqs) @@ -259,23 +181,28 @@ static int get_irq_server(unsigned int irq) } #else -static int get_irq_server(unsigned int irq) +static int get_irq_server(unsigned int virq) { return default_server; } #endif -static void xics_enable_irq(unsigned int virq) + +static void xics_unmask_irq(unsigned int virq) { unsigned int irq; int call_status; unsigned int server; - irq = virt_irq_to_real(irq_offset_down(virq)); - if (irq == XICS_IPI) + pr_debug("xics: unmask virq %d\n", virq); + + irq = (unsigned int)irq_map[virq].hwirq; + pr_debug(" -> map to hwirq 0x%x\n", irq); + if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS) return; server = get_irq_server(virq); + call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, server, DEFAULT_PRIORITY); if (call_status != 0) { @@ -294,7 +221,7 @@ static void xics_enable_irq(unsigned int virq) } } -static void xics_disable_real_irq(unsigned int irq) +static void xics_mask_real_irq(unsigned int irq) { int call_status; unsigned int server; @@ -319,75 +246,86 @@ static void xics_disable_real_irq(unsigned int irq) } } -static void xics_disable_irq(unsigned int virq) +static void xics_mask_irq(unsigned int virq) { unsigned int irq; - irq = virt_irq_to_real(irq_offset_down(virq)); - xics_disable_real_irq(irq); + pr_debug("xics: mask virq %d\n", virq); + + irq = (unsigned int)irq_map[virq].hwirq; + if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS) + return; + xics_mask_real_irq(irq); } -static void xics_end_irq(unsigned int irq) +static unsigned int xics_startup(unsigned int virq) +{ + unsigned int irq; + + /* force a reverse mapping of the interrupt so it gets in the cache */ + irq = (unsigned int)irq_map[virq].hwirq; + irq_radix_revmap(xics_host, irq); + + /* unmask it */ + xics_unmask_irq(virq); + return 0; +} + +static void xics_eoi_direct(unsigned int virq) { int cpu = smp_processor_id(); + unsigned int irq = (unsigned int)irq_map[virq].hwirq; iosync(); - ops->xirr_info_set(cpu, ((0xff << 24) | - (virt_irq_to_real(irq_offset_down(irq))))); - + direct_xirr_info_set(cpu, (0xff << 24) | irq); } -static void xics_mask_and_ack_irq(unsigned int irq) + +static void xics_eoi_lpar(unsigned int virq) { int cpu = smp_processor_id(); + unsigned int irq = (unsigned int)irq_map[virq].hwirq; - if (irq < irq_offset_value()) { - i8259_pic.ack(irq); - iosync(); - ops->xirr_info_set(cpu, ((0xff<<24) | - xics_irq_8259_cascade_real)); - iosync(); - } + iosync(); + lpar_xirr_info_set(cpu, (0xff << 24) | irq); } -int xics_get_irq(struct pt_regs *regs) +static inline unsigned int xics_remap_irq(unsigned int vec) { - unsigned int cpu = smp_processor_id(); - unsigned int vec; - int irq; + unsigned int irq; - vec = ops->xirr_info_get(cpu); - /* (vec >> 24) == old priority */ vec &= 0x00ffffff; - /* for sanity, this had better be < NR_IRQS - 16 */ - if (vec == xics_irq_8259_cascade_real) { - irq = i8259_irq(regs); - xics_end_irq(irq_offset_up(xics_irq_8259_cascade)); - } else if (vec == XICS_IRQ_SPURIOUS) { - irq = -1; - } else { - irq = real_irq_to_virt(vec); - if (irq == NO_IRQ) - irq = real_irq_to_virt_slowpath(vec); - if (irq == NO_IRQ) { - printk(KERN_ERR "Interrupt %u (real) is invalid," - " disabling it.\n", vec); - xics_disable_real_irq(vec); - } else - irq = irq_offset_up(irq); - } - return irq; + if (vec == XICS_IRQ_SPURIOUS) + return NO_IRQ; + irq = irq_radix_revmap(xics_host, vec); + if (likely(irq != NO_IRQ)) + return irq; + + printk(KERN_ERR "Interrupt %u (real) is invalid," + " disabling it.\n", vec); + xics_mask_real_irq(vec); + return NO_IRQ; } -#ifdef CONFIG_SMP +static unsigned int xics_get_irq_direct(struct pt_regs *regs) +{ + unsigned int cpu = smp_processor_id(); -static irqreturn_t xics_ipi_action(int irq, void *dev_id, struct pt_regs *regs) + return xics_remap_irq(direct_xirr_info_get(cpu)); +} + +static unsigned int xics_get_irq_lpar(struct pt_regs *regs) { - int cpu = smp_processor_id(); + unsigned int cpu = smp_processor_id(); - ops->qirr_info(cpu, 0xff); + return xics_remap_irq(lpar_xirr_info_get(cpu)); +} + +#ifdef CONFIG_SMP +static irqreturn_t xics_ipi_dispatch(int cpu, struct pt_regs *regs) +{ WARN_ON(cpu_is_offline(cpu)); while (xics_ipi_message[cpu].value) { @@ -419,18 +357,88 @@ static irqreturn_t xics_ipi_action(int irq, void *dev_id, struct pt_regs *regs) return IRQ_HANDLED; } +static irqreturn_t xics_ipi_action_direct(int irq, void *dev_id, struct pt_regs *regs) +{ + int cpu = smp_processor_id(); + + direct_qirr_info(cpu, 0xff); + + return xics_ipi_dispatch(cpu, regs); +} + +static irqreturn_t xics_ipi_action_lpar(int irq, void *dev_id, struct pt_regs *regs) +{ + int cpu = smp_processor_id(); + + lpar_qirr_info(cpu, 0xff); + + return xics_ipi_dispatch(cpu, regs); +} + void xics_cause_IPI(int cpu) { - ops->qirr_info(cpu, IPI_PRIORITY); + if (firmware_has_feature(FW_FEATURE_LPAR)) + lpar_qirr_info(cpu, IPI_PRIORITY); + else + direct_qirr_info(cpu, IPI_PRIORITY); } + #endif /* CONFIG_SMP */ +static void xics_set_cpu_priority(int cpu, unsigned char cppr) +{ + if (firmware_has_feature(FW_FEATURE_LPAR)) + lpar_cppr_info(cpu, cppr); + else + direct_cppr_info(cpu, cppr); + iosync(); +} + +static void xics_set_affinity(unsigned int virq, cpumask_t cpumask) +{ + unsigned int irq; + int status; + int xics_status[2]; + unsigned long newmask; + cpumask_t tmp = CPU_MASK_NONE; + + irq = (unsigned int)irq_map[virq].hwirq; + if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS) + return; + + status = rtas_call(ibm_get_xive, 1, 3, xics_status, irq); + + if (status) { + printk(KERN_ERR "xics_set_affinity: irq=%u ibm,get-xive " + "returns %d\n", irq, status); + return; + } + + /* For the moment only implement delivery to all cpus or one cpu */ + if (cpus_equal(cpumask, CPU_MASK_ALL)) { + newmask = default_distrib_server; + } else { + cpus_and(tmp, cpu_online_map, cpumask); + if (cpus_empty(tmp)) + return; + newmask = get_hard_smp_processor_id(first_cpu(tmp)); + } + + status = rtas_call(ibm_set_xive, 3, 1, NULL, + irq, newmask, xics_status[1]); + + if (status) { + printk(KERN_ERR "xics_set_affinity: irq=%u ibm,set-xive " + "returns %d\n", irq, status); + return; + } +} + void xics_setup_cpu(void) { int cpu = smp_processor_id(); - ops->cppr_info(cpu, 0xff); - iosync(); + xics_set_cpu_priority(cpu, 0xff); /* * Put the calling processor into the GIQ. This is really only @@ -439,76 +447,256 @@ void xics_setup_cpu(void) * * XXX: undo of teardown on kexec needs this too, as may hotplug */ - rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE, + rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE, (1UL << interrupt_server_size) - 1 - default_distrib_server, 1); } -void xics_init_IRQ(void) + +static struct irq_chip xics_pic_direct = { + .typename = " XICS ", + .startup = xics_startup, + .mask = xics_mask_irq, + .unmask = xics_unmask_irq, + .eoi = xics_eoi_direct, + .set_affinity = xics_set_affinity +}; + + +static struct irq_chip xics_pic_lpar = { + .typename = " XICS ", + .startup = xics_startup, + .mask = xics_mask_irq, + .unmask = xics_unmask_irq, + .eoi = xics_eoi_lpar, + .set_affinity = xics_set_affinity +}; + + +static int xics_host_match(struct irq_host *h, struct device_node *node) +{ + /* IBM machines have interrupt parents of various funky types for things + * like vdevices, events, etc... The trick we use here is to match + * everything here except the legacy 8259 which is compatible "chrp,iic" + */ + return !device_is_compatible(node, "chrp,iic"); +} + +static int xics_host_map_direct(struct irq_host *h, unsigned int virq, + irq_hw_number_t hw) +{ + pr_debug("xics: map_direct virq %d, hwirq 0x%lx\n", virq, hw); + + get_irq_desc(virq)->status |= IRQ_LEVEL; + set_irq_chip_and_handler(virq, &xics_pic_direct, handle_fasteoi_irq); + return 0; +} + +static int xics_host_map_lpar(struct irq_host *h, unsigned int virq, + irq_hw_number_t hw) +{ + pr_debug("xics: map_direct virq %d, hwirq 0x%lx\n", virq, hw); + + get_irq_desc(virq)->status |= IRQ_LEVEL; + set_irq_chip_and_handler(virq, &xics_pic_lpar, handle_fasteoi_irq); + return 0; +} + +static int xics_host_xlate(struct irq_host *h, struct device_node *ct, + u32 *intspec, unsigned int intsize, + irq_hw_number_t *out_hwirq, unsigned int *out_flags) + { + /* Current xics implementation translates everything + * to level. It is not technically right for MSIs but this + * is irrelevant at this point. We might get smarter in the future + */ + *out_hwirq = intspec[0]; + *out_flags = IRQ_TYPE_LEVEL_LOW; + + return 0; +} + +static struct irq_host_ops xics_host_direct_ops = { + .match = xics_host_match, + .map = xics_host_map_direct, + .xlate = xics_host_xlate, +}; + +static struct irq_host_ops xics_host_lpar_ops = { + .match = xics_host_match, + .map = xics_host_map_lpar, + .xlate = xics_host_xlate, +}; + +static void __init xics_init_host(void) +{ + struct irq_host_ops *ops; + + if (firmware_has_feature(FW_FEATURE_LPAR)) + ops = &xics_host_lpar_ops; + else + ops = &xics_host_direct_ops; + xics_host = irq_alloc_host(IRQ_HOST_MAP_TREE, 0, ops, + XICS_IRQ_SPURIOUS); + BUG_ON(xics_host == NULL); + irq_set_default_host(xics_host); +} + +static void __init xics_map_one_cpu(int hw_id, unsigned long addr, + unsigned long size) +{ +#ifdef CONFIG_SMP int i; - unsigned long intr_size = 0; - struct device_node *np; - uint *ireg, ilen, indx = 0; - unsigned long intr_base = 0; - struct xics_interrupt_node { - unsigned long addr; - unsigned long size; - } intnodes[NR_CPUS]; - ppc64_boot_msg(0x20, "XICS Init"); + /* This may look gross but it's good enough for now, we don't quite + * have a hard -> linux processor id matching. + */ + for_each_possible_cpu(i) { + if (!cpu_present(i)) + continue; + if (hw_id == get_hard_smp_processor_id(i)) { + xics_per_cpu[i] = ioremap(addr, size); + return; + } + } +#else + if (hw_id != 0) + return; + xics_per_cpu[0] = ioremap(addr, size); +#endif /* CONFIG_SMP */ +} - ibm_get_xive = rtas_token("ibm,get-xive"); - ibm_set_xive = rtas_token("ibm,set-xive"); - ibm_int_on = rtas_token("ibm,int-on"); - ibm_int_off = rtas_token("ibm,int-off"); +static void __init xics_init_one_node(struct device_node *np, + unsigned int *indx) +{ + unsigned int ilen; + const u32 *ireg; - np = of_find_node_by_type(NULL, "PowerPC-External-Interrupt-Presentation"); - if (!np) - panic("xics_init_IRQ: can't find interrupt presentation"); + /* This code does the theorically broken assumption that the interrupt + * server numbers are the same as the hard CPU numbers. + * This happens to be the case so far but we are playing with fire... + * should be fixed one of these days. -BenH. + */ + ireg = get_property(np, "ibm,interrupt-server-ranges", NULL); -nextnode: - ireg = (uint *)get_property(np, "ibm,interrupt-server-ranges", NULL); + /* Do that ever happen ? we'll know soon enough... but even good'old + * f80 does have that property .. + */ + WARN_ON(ireg == NULL); if (ireg) { /* * set node starting index for this node */ - indx = *ireg; + *indx = *ireg; } - - ireg = (uint *)get_property(np, "reg", &ilen); + ireg = get_property(np, "reg", &ilen); if (!ireg) panic("xics_init_IRQ: can't find interrupt reg property"); - while (ilen) { - intnodes[indx].addr = (unsigned long)*ireg++ << 32; - ilen -= sizeof(uint); - intnodes[indx].addr |= *ireg++; - ilen -= sizeof(uint); - intnodes[indx].size = (unsigned long)*ireg++ << 32; - ilen -= sizeof(uint); - intnodes[indx].size |= *ireg++; - ilen -= sizeof(uint); - indx++; - if (indx >= NR_CPUS) break; + while (ilen >= (4 * sizeof(u32))) { + unsigned long addr, size; + + /* XXX Use proper OF parsing code here !!! */ + addr = (unsigned long)*ireg++ << 32; + ilen -= sizeof(u32); + addr |= *ireg++; + ilen -= sizeof(u32); + size = (unsigned long)*ireg++ << 32; + ilen -= sizeof(u32); + size |= *ireg++; + ilen -= sizeof(u32); + xics_map_one_cpu(*indx, addr, size); + (*indx)++; } +} + + +static void __init xics_setup_8259_cascade(void) +{ + struct device_node *np, *old, *found = NULL; + int cascade, naddr; + const u32 *addrp; + unsigned long intack = 0; + + for_each_node_by_type(np, "interrupt-controller") + if (device_is_compatible(np, "chrp,iic")) { + found = np; + break; + } + if (found == NULL) { + printk(KERN_DEBUG "xics: no ISA interrupt controller\n"); + return; + } + cascade = irq_of_parse_and_map(found, 0); + if (cascade == NO_IRQ) { + printk(KERN_ERR "xics: failed to map cascade interrupt"); + return; + } + pr_debug("xics: cascade mapped to irq %d\n", cascade); + + for (old = of_node_get(found); old != NULL ; old = np) { + np = of_get_parent(old); + of_node_put(old); + if (np == NULL) + break; + if (strcmp(np->name, "pci") != 0) + continue; + addrp = get_property(np, "8259-interrupt-acknowledge", NULL); + if (addrp == NULL) + continue; + naddr = prom_n_addr_cells(np); + intack = addrp[naddr-1]; + if (naddr > 1) + intack |= ((unsigned long)addrp[naddr-2]) << 32; + } + if (intack) + printk(KERN_DEBUG "xics: PCI 8259 intack at 0x%016lx\n", intack); + i8259_init(found, intack); + of_node_put(found); + set_irq_chained_handler(cascade, pseries_8259_cascade); +} + +void __init xics_init_IRQ(void) +{ + int i; + struct device_node *np; + u32 ilen, indx = 0; + const u32 *ireg; + int found = 0; + + ppc64_boot_msg(0x20, "XICS Init"); + + ibm_get_xive = rtas_token("ibm,get-xive"); + ibm_set_xive = rtas_token("ibm,set-xive"); + ibm_int_on = rtas_token("ibm,int-on"); + ibm_int_off = rtas_token("ibm,int-off"); + + for_each_node_by_type(np, "PowerPC-External-Interrupt-Presentation") { + found = 1; + if (firmware_has_feature(FW_FEATURE_LPAR)) + break; + xics_init_one_node(np, &indx); + } + if (found == 0) + return; - np = of_find_node_by_type(np, "PowerPC-External-Interrupt-Presentation"); - if ((indx < NR_CPUS) && np) goto nextnode; + xics_init_host(); /* Find the server numbers for the boot cpu. */ for (np = of_find_node_by_type(NULL, "cpu"); np; np = of_find_node_by_type(np, "cpu")) { - ireg = (uint *)get_property(np, "reg", &ilen); + ireg = get_property(np, "reg", &ilen); if (ireg && ireg[0] == get_hard_smp_processor_id(boot_cpuid)) { - ireg = (uint *)get_property(np, "ibm,ppc-interrupt-gserver#s", - &ilen); + ireg = get_property(np, + "ibm,ppc-interrupt-gserver#s", &ilen); i = ilen / sizeof(int); if (ireg && i > 0) { default_server = ireg[0]; - default_distrib_server = ireg[i-1]; /* take last element */ + /* take last element */ + default_distrib_server = ireg[i-1]; } - ireg = (uint *)get_property(np, + ireg = get_property(np, "ibm,interrupt-server#-size", NULL); if (ireg) interrupt_server_size = *ireg; @@ -517,132 +705,56 @@ nextnode: } of_node_put(np); - intr_base = intnodes[0].addr; - intr_size = intnodes[0].size; - - np = of_find_node_by_type(NULL, "interrupt-controller"); - if (!np) { - printk(KERN_DEBUG "xics: no ISA interrupt controller\n"); - xics_irq_8259_cascade_real = -1; - xics_irq_8259_cascade = -1; - } else { - ireg = (uint *) get_property(np, "interrupts", NULL); - if (!ireg) - panic("xics_init_IRQ: can't find ISA interrupts property"); - - xics_irq_8259_cascade_real = *ireg; - xics_irq_8259_cascade - = virt_irq_create_mapping(xics_irq_8259_cascade_real); - i8259_init(0, 0); - of_node_put(np); - } - if (firmware_has_feature(FW_FEATURE_LPAR)) - ops = &pSeriesLP_ops; - else { -#ifdef CONFIG_SMP - for_each_possible_cpu(i) { - int hard_id; - - /* FIXME: Do this dynamically! --RR */ - if (!cpu_present(i)) - continue; - - hard_id = get_hard_smp_processor_id(i); - xics_per_cpu[i] = ioremap(intnodes[hard_id].addr, - intnodes[hard_id].size); - } -#else - xics_per_cpu[0] = ioremap(intr_base, intr_size); -#endif /* CONFIG_SMP */ - } - - for (i = irq_offset_value(); i < NR_IRQS; ++i) - get_irq_desc(i)->handler = &xics_pic; + ppc_md.get_irq = xics_get_irq_lpar; + else + ppc_md.get_irq = xics_get_irq_direct; xics_setup_cpu(); + xics_setup_8259_cascade(); + ppc64_boot_msg(0x21, "XICS Done"); } -/* - * We cant do this in init_IRQ because we need the memory subsystem up for - * request_irq() - */ -static int __init xics_setup_i8259(void) -{ - if (ppc64_interrupt_controller == IC_PPC_XIC && - xics_irq_8259_cascade != -1) { - if (request_irq(irq_offset_up(xics_irq_8259_cascade), - no_action, 0, "8259 cascade", NULL)) - printk(KERN_ERR "xics_setup_i8259: couldn't get 8259 " - "cascade\n"); - } - return 0; -} -arch_initcall(xics_setup_i8259); #ifdef CONFIG_SMP void xics_request_IPIs(void) { - virt_irq_to_real_map[XICS_IPI] = XICS_IPI; - - /* IPIs are marked SA_INTERRUPT as they must run with irqs disabled */ - request_irq(irq_offset_up(XICS_IPI), xics_ipi_action, SA_INTERRUPT, - "IPI", NULL); - get_irq_desc(irq_offset_up(XICS_IPI))->status |= IRQ_PER_CPU; -} -#endif - -static void xics_set_affinity(unsigned int virq, cpumask_t cpumask) -{ - unsigned int irq; - int status; - int xics_status[2]; - unsigned long newmask; - cpumask_t tmp = CPU_MASK_NONE; - - irq = virt_irq_to_real(irq_offset_down(virq)); - if (irq == XICS_IPI || irq == NO_IRQ) - return; - - status = rtas_call(ibm_get_xive, 1, 3, xics_status, irq); - - if (status) { - printk(KERN_ERR "xics_set_affinity: irq=%u ibm,get-xive " - "returns %d\n", irq, status); - return; - } + unsigned int ipi; - /* For the moment only implement delivery to all cpus or one cpu */ - if (cpus_equal(cpumask, CPU_MASK_ALL)) { - newmask = default_distrib_server; - } else { - cpus_and(tmp, cpu_online_map, cpumask); - if (cpus_empty(tmp)) - return; - newmask = get_hard_smp_processor_id(first_cpu(tmp)); - } - - status = rtas_call(ibm_set_xive, 3, 1, NULL, - irq, newmask, xics_status[1]); + ipi = irq_create_mapping(xics_host, XICS_IPI); + BUG_ON(ipi == NO_IRQ); - if (status) { - printk(KERN_ERR "xics_set_affinity: irq=%u ibm,set-xive " - "returns %d\n", irq, status); - return; - } + /* + * IPIs are marked IRQF_DISABLED as they must run with irqs + * disabled + */ + set_irq_handler(ipi, handle_percpu_irq); + if (firmware_has_feature(FW_FEATURE_LPAR)) + request_irq(ipi, xics_ipi_action_lpar, IRQF_DISABLED, + "IPI", NULL); + else + request_irq(ipi, xics_ipi_action_direct, IRQF_DISABLED, + "IPI", NULL); } +#endif /* CONFIG_SMP */ void xics_teardown_cpu(int secondary) { int cpu = smp_processor_id(); + unsigned int ipi; + struct irq_desc *desc; - ops->cppr_info(cpu, 0x00); - iosync(); + xics_set_cpu_priority(cpu, 0); - /* Clear IPI */ - ops->qirr_info(cpu, 0xff); + /* + * Clear IPI + */ + if (firmware_has_feature(FW_FEATURE_LPAR)) + lpar_qirr_info(cpu, 0xff); + else + direct_qirr_info(cpu, 0xff); /* * we need to EOI the IPI if we got here from kexec down IPI @@ -651,16 +763,22 @@ void xics_teardown_cpu(int secondary) * should we be flagging idle loop instead? * or creating some task to be scheduled? */ - ops->xirr_info_set(cpu, XICS_IPI); + + ipi = irq_find_mapping(xics_host, XICS_IPI); + if (ipi == XICS_IRQ_SPURIOUS) + return; + desc = get_irq_desc(ipi); + if (desc->chip && desc->chip->eoi) + desc->chip->eoi(ipi); /* * Some machines need to have at least one cpu in the GIQ, * so leave the master cpu in the group. */ if (secondary) - rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE, - (1UL << interrupt_server_size) - 1 - - default_distrib_server, 0); + rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE, + (1UL << interrupt_server_size) - 1 - + default_distrib_server, 0); } #ifdef CONFIG_HOTPLUG_CPU @@ -672,38 +790,36 @@ void xics_migrate_irqs_away(void) unsigned int irq, virq, cpu = smp_processor_id(); /* Reject any interrupt that was queued to us... */ - ops->cppr_info(cpu, 0); - iosync(); + xics_set_cpu_priority(cpu, 0); /* remove ourselves from the global interrupt queue */ - status = rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE, + status = rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE, (1UL << interrupt_server_size) - 1 - default_distrib_server, 0); WARN_ON(status < 0); /* Allow IPIs again... */ - ops->cppr_info(cpu, DEFAULT_PRIORITY); - iosync(); + xics_set_cpu_priority(cpu, DEFAULT_PRIORITY); for_each_irq(virq) { - irq_desc_t *desc; + struct irq_desc *desc; int xics_status[2]; unsigned long flags; /* We cant set affinity on ISA interrupts */ - if (virq < irq_offset_value()) + if (virq < NUM_ISA_INTERRUPTS) continue; - - desc = get_irq_desc(virq); - irq = virt_irq_to_real(irq_offset_down(virq)); - + if (irq_map[virq].host != xics_host) + continue; + irq = (unsigned int)irq_map[virq].hwirq; /* We need to get IPIs still. */ - if (irq == XICS_IPI || irq == NO_IRQ) + if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS) continue; + desc = get_irq_desc(virq); /* We only need to migrate enabled IRQS */ - if (desc == NULL || desc->handler == NULL + if (desc == NULL || desc->chip == NULL || desc->action == NULL - || desc->handler->set_affinity == NULL) + || desc->chip->set_affinity == NULL) continue; spin_lock_irqsave(&desc->lock, flags); @@ -728,8 +844,8 @@ void xics_migrate_irqs_away(void) virq, cpu); /* Reset affinity to all cpus */ - desc->handler->set_affinity(virq, CPU_MASK_ALL); - irq_affinity[virq] = CPU_MASK_ALL; + desc->chip->set_affinity(virq, CPU_MASK_ALL); + irq_desc[irq].affinity = CPU_MASK_ALL; unlock: spin_unlock_irqrestore(&desc->lock, flags); } diff --git a/arch/powerpc/platforms/pseries/xics.h b/arch/powerpc/platforms/pseries/xics.h index e14c70868f1d..6ee1055b0ffb 100644 --- a/arch/powerpc/platforms/pseries/xics.h +++ b/arch/powerpc/platforms/pseries/xics.h @@ -14,13 +14,12 @@ #include <linux/cache.h> -void xics_init_IRQ(void); -int xics_get_irq(struct pt_regs *); -void xics_setup_cpu(void); -void xics_teardown_cpu(int secondary); -void xics_cause_IPI(int cpu); -void xics_request_IPIs(void); -void xics_migrate_irqs_away(void); +extern void xics_init_IRQ(void); +extern void xics_setup_cpu(void); +extern void xics_teardown_cpu(int secondary); +extern void xics_cause_IPI(int cpu); +extern void xics_request_IPIs(void); +extern void xics_migrate_irqs_away(void); /* first argument is ignored for now*/ void pSeriesLP_cppr_info(int n_cpu, u8 value); @@ -31,4 +30,8 @@ struct xics_ipi_struct { extern struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned; +struct irq_desc; +extern void pseries_8259_cascade(unsigned int irq, struct irq_desc *desc, + struct pt_regs *regs); + #endif /* _POWERPC_KERNEL_XICS_H */ diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index cef95b023730..e5e999ea891a 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile @@ -4,11 +4,16 @@ endif obj-$(CONFIG_MPIC) += mpic.o obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o -obj-$(CONFIG_PPC_I8259) += i8259.o obj-$(CONFIG_PPC_MPC106) += grackle.o obj-$(CONFIG_BOOKE) += dcr.o obj-$(CONFIG_40x) += dcr.o obj-$(CONFIG_U3_DART) += dart_iommu.o obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o -obj-$(CONFIG_PPC_83xx) += ipic.o obj-$(CONFIG_FSL_SOC) += fsl_soc.o +obj-$(CONFIG_PPC_TODC) += todc.o +obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o + +ifeq ($(CONFIG_PPC_MERGE),y) +obj-$(CONFIG_PPC_I8259) += i8259.o +obj-$(CONFIG_PPC_83xx) += ipic.o +endif diff --git a/arch/powerpc/sysdev/dart.h b/arch/powerpc/sysdev/dart.h index c2d05763ccbe..1c8817c4835e 100644 --- a/arch/powerpc/sysdev/dart.h +++ b/arch/powerpc/sysdev/dart.h @@ -47,8 +47,12 @@ /* U4 registers */ #define DART_BASE_U4_BASE_MASK 0xffffff #define DART_BASE_U4_BASE_SHIFT 0 -#define DART_CNTL_U4_FLUSHTLB 0x20000000 #define DART_CNTL_U4_ENABLE 0x80000000 +#define DART_CNTL_U4_IONE 0x40000000 +#define DART_CNTL_U4_FLUSHTLB 0x20000000 +#define DART_CNTL_U4_IDLE 0x10000000 +#define DART_CNTL_U4_PAR_EN 0x08000000 +#define DART_CNTL_U4_IONE_MASK 0x07ffffff #define DART_SIZE_U4_SIZE_MASK 0x1fff #define DART_SIZE_U4_SIZE_SHIFT 0 diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c index 6232091cc72b..03b4477dd7f0 100644 --- a/arch/powerpc/sysdev/dart_iommu.c +++ b/arch/powerpc/sysdev/dart_iommu.c @@ -27,7 +27,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <linux/config.h> #include <linux/init.h> #include <linux/types.h> #include <linux/slab.h> @@ -101,8 +100,8 @@ retry: if (l == (1L << limit)) { if (limit < 4) { limit++; - reg = DART_IN(DART_CNTL); - reg &= ~inv_bit; + reg = DART_IN(DART_CNTL); + reg &= ~inv_bit; DART_OUT(DART_CNTL, reg); goto retry; } else @@ -111,11 +110,40 @@ retry: } } +static inline void dart_tlb_invalidate_one(unsigned long bus_rpn) +{ + unsigned int reg; + unsigned int l, limit; + + reg = DART_CNTL_U4_ENABLE | DART_CNTL_U4_IONE | + (bus_rpn & DART_CNTL_U4_IONE_MASK); + DART_OUT(DART_CNTL, reg); + + limit = 0; +wait_more: + l = 0; + while ((DART_IN(DART_CNTL) & DART_CNTL_U4_IONE) && l < (1L << limit)) { + rmb(); + l++; + } + + if (l == (1L << limit)) { + if (limit < 4) { + limit++; + goto wait_more; + } else + panic("DART: TLB did not flush after waiting a long " + "time. Buggy U4 ?"); + } +} + static void dart_flush(struct iommu_table *tbl) { - if (dart_dirty) + mb(); + if (dart_dirty) { dart_tlb_invalidate_all(); - dart_dirty = 0; + dart_dirty = 0; + } } static void dart_build(struct iommu_table *tbl, long index, @@ -124,6 +152,7 @@ static void dart_build(struct iommu_table *tbl, long index, { unsigned int *dp; unsigned int rpn; + long l; DBG("dart: build at: %lx, %lx, addr: %x\n", index, npages, uaddr); @@ -135,7 +164,8 @@ static void dart_build(struct iommu_table *tbl, long index, /* On U3, all memory is contigous, so we can move this * out of the loop. */ - while (npages--) { + l = npages; + while (l--) { rpn = virt_to_abs(uaddr) >> DART_PAGE_SHIFT; *(dp++) = DARTMAP_VALID | (rpn & DARTMAP_RPNMASK); @@ -143,7 +173,18 @@ static void dart_build(struct iommu_table *tbl, long index, uaddr += DART_PAGE_SIZE; } - dart_dirty = 1; + /* make sure all updates have reached memory */ + mb(); + in_be32((unsigned __iomem *)dp); + mb(); + + if (dart_is_u4) { + rpn = index; + while (npages--) + dart_tlb_invalidate_one(rpn++); + } else { + dart_dirty = 1; + } } diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c index 71a3275935ec..92ba378b7990 100644 --- a/arch/powerpc/sysdev/fsl_soc.c +++ b/arch/powerpc/sysdev/fsl_soc.c @@ -9,7 +9,6 @@ * option) any later version. */ -#include <linux/config.h> #include <linux/stddef.h> #include <linux/kernel.h> #include <linux/init.h> @@ -42,7 +41,7 @@ phys_addr_t get_immrbase(void) soc = of_find_node_by_type(NULL, "soc"); if (soc) { unsigned int size; - void *prop = get_property(soc, "reg", &size); + const void *prop = get_property(soc, "reg", &size); immrbase = of_translate_address(soc, prop); of_node_put(soc); }; @@ -86,11 +85,8 @@ static int __init gfar_mdio_of_init(void) mdio_data.irq[k] = -1; while ((child = of_get_next_child(np, child)) != NULL) { - if (child->n_intrs) { - u32 *id = - (u32 *) get_property(child, "reg", NULL); - mdio_data.irq[*id] = child->intrs[0].line; - } + const u32 *id = get_property(child, "reg", NULL); + mdio_data.irq[*id] = irq_of_parse_and_map(child, 0); } ret = @@ -128,10 +124,11 @@ static int __init gfar_of_init(void) struct resource r[4]; struct device_node *phy, *mdio; struct gianfar_platform_data gfar_data; - unsigned int *id; - char *model; - void *mac_addr; - phandle *ph; + const unsigned int *id; + const char *model; + const void *mac_addr; + const phandle *ph; + int n_res = 1; memset(r, 0, sizeof(r)); memset(&gfar_data, 0, sizeof(gfar_data)); @@ -140,8 +137,7 @@ static int __init gfar_of_init(void) if (ret) goto err; - r[1].start = np->intrs[0].line; - r[1].end = np->intrs[0].line; + r[1].start = r[1].end = irq_of_parse_and_map(np, 0); r[1].flags = IORESOURCE_IRQ; model = get_property(np, "model", NULL); @@ -151,27 +147,35 @@ static int __init gfar_of_init(void) r[1].name = gfar_tx_intr; r[2].name = gfar_rx_intr; - r[2].start = np->intrs[1].line; - r[2].end = np->intrs[1].line; + r[2].start = r[2].end = irq_of_parse_and_map(np, 1); r[2].flags = IORESOURCE_IRQ; r[3].name = gfar_err_intr; - r[3].start = np->intrs[2].line; - r[3].end = np->intrs[2].line; + r[3].start = r[3].end = irq_of_parse_and_map(np, 2); r[3].flags = IORESOURCE_IRQ; + + n_res += 2; } gfar_dev = platform_device_register_simple("fsl-gianfar", i, &r[0], - np->n_intrs + 1); + n_res + 1); if (IS_ERR(gfar_dev)) { ret = PTR_ERR(gfar_dev); goto err; } - mac_addr = get_property(np, "address", NULL); - memcpy(gfar_data.mac_addr, mac_addr, 6); + mac_addr = get_property(np, "local-mac-address", NULL); + if (mac_addr == NULL) + mac_addr = get_property(np, "mac-address", NULL); + if (mac_addr == NULL) { + /* Obsolete */ + mac_addr = get_property(np, "address", NULL); + } + + if (mac_addr) + memcpy(gfar_data.mac_addr, mac_addr, 6); if (model && !strcasecmp(model, "TSEC")) gfar_data.device_flags = @@ -189,7 +193,7 @@ static int __init gfar_of_init(void) FSL_GIANFAR_DEV_HAS_VLAN | FSL_GIANFAR_DEV_HAS_EXTENDED_HASH; - ph = (phandle *) get_property(np, "phy-handle", NULL); + ph = get_property(np, "phy-handle", NULL); phy = of_find_node_by_phandle(*ph); if (phy == NULL) { @@ -199,7 +203,7 @@ static int __init gfar_of_init(void) mdio = of_get_parent(phy); - id = (u32 *) get_property(phy, "reg", NULL); + id = get_property(phy, "reg", NULL); ret = of_address_to_resource(mdio, 0, &res); if (ret) { of_node_put(phy); @@ -243,7 +247,7 @@ static int __init fsl_i2c_of_init(void) i++) { struct resource r[2]; struct fsl_i2c_platform_data i2c_data; - unsigned char *flags = NULL; + const unsigned char *flags = NULL; memset(&r, 0, sizeof(r)); memset(&i2c_data, 0, sizeof(i2c_data)); @@ -252,8 +256,7 @@ static int __init fsl_i2c_of_init(void) if (ret) goto err; - r[1].start = np->intrs[0].line; - r[1].end = np->intrs[0].line; + r[1].start = r[1].end = irq_of_parse_and_map(np, 0); r[1].flags = IORESOURCE_IRQ; i2c_dev = platform_device_register_simple("fsl-i2c", i, r, 2); @@ -295,7 +298,7 @@ static int __init mpc83xx_wdt_init(void) struct resource r; struct device_node *soc, *np; struct platform_device *dev; - unsigned int *freq; + const unsigned int *freq; int ret; np = of_find_compatible_node(NULL, "watchdog", "mpc83xx_wdt"); @@ -312,7 +315,7 @@ static int __init mpc83xx_wdt_init(void) goto nosoc; } - freq = (unsigned int *)get_property(soc, "bus-frequency", NULL); + freq = get_property(soc, "bus-frequency", NULL); if (!freq) { ret = -ENODEV; goto err; @@ -352,7 +355,7 @@ nodev: arch_initcall(mpc83xx_wdt_init); #endif -static enum fsl_usb2_phy_modes determine_usb_phy(char * phy_type) +static enum fsl_usb2_phy_modes determine_usb_phy(const char *phy_type) { if (!phy_type) return FSL_USB2_PHY_NONE; @@ -380,7 +383,7 @@ static int __init fsl_usb_of_init(void) i++) { struct resource r[2]; struct fsl_usb2_platform_data usb_data; - unsigned char *prop = NULL; + const unsigned char *prop = NULL; memset(&r, 0, sizeof(r)); memset(&usb_data, 0, sizeof(usb_data)); @@ -389,8 +392,7 @@ static int __init fsl_usb_of_init(void) if (ret) goto err; - r[1].start = np->intrs[0].line; - r[1].end = np->intrs[0].line; + r[1].start = r[1].end = irq_of_parse_and_map(np, 0); r[1].flags = IORESOURCE_IRQ; usb_dev_mph = @@ -429,7 +431,7 @@ static int __init fsl_usb_of_init(void) i++) { struct resource r[2]; struct fsl_usb2_platform_data usb_data; - unsigned char *prop = NULL; + const unsigned char *prop = NULL; memset(&r, 0, sizeof(r)); memset(&usb_data, 0, sizeof(usb_data)); @@ -438,8 +440,7 @@ static int __init fsl_usb_of_init(void) if (ret) goto unreg_mph; - r[1].start = np->intrs[0].line; - r[1].end = np->intrs[0].line; + r[1].start = r[1].end = irq_of_parse_and_map(np, 0); r[1].flags = IORESOURCE_IRQ; usb_dev_dr = diff --git a/arch/powerpc/sysdev/fsl_soc.h b/arch/powerpc/sysdev/fsl_soc.h index c433d3f39edd..5a3dd480d2fd 100644 --- a/arch/powerpc/sysdev/fsl_soc.h +++ b/arch/powerpc/sysdev/fsl_soc.h @@ -2,6 +2,8 @@ #define __PPC_FSL_SOC_H #ifdef __KERNEL__ +#include <asm/mmu.h> + extern phys_addr_t get_immrbase(void); #endif diff --git a/arch/powerpc/sysdev/i8259.c b/arch/powerpc/sysdev/i8259.c index b7ac32fdd776..26a6a3becd66 100644 --- a/arch/powerpc/sysdev/i8259.c +++ b/arch/powerpc/sysdev/i8259.c @@ -6,11 +6,16 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ +#undef DEBUG + #include <linux/init.h> #include <linux/ioport.h> #include <linux/interrupt.h> +#include <linux/kernel.h> +#include <linux/delay.h> #include <asm/io.h> #include <asm/i8259.h> +#include <asm/prom.h> static volatile void __iomem *pci_intack; /* RO, gives us the irq vector */ @@ -20,7 +25,8 @@ static unsigned char cached_8259[2] = { 0xff, 0xff }; static DEFINE_SPINLOCK(i8259_lock); -static int i8259_pic_irq_offset; +static struct device_node *i8259_node; +static struct irq_host *i8259_host; /* * Acknowledge the IRQ using either the PCI host bridge's interrupt @@ -28,16 +34,18 @@ static int i8259_pic_irq_offset; * which is called. It should be noted that polling is broken on some * IBM and Motorola PReP boxes so we must use the int-ack feature on them. */ -int i8259_irq(struct pt_regs *regs) +unsigned int i8259_irq(struct pt_regs *regs) { int irq; - - spin_lock(&i8259_lock); + int lock = 0; /* Either int-ack or poll for the IRQ */ if (pci_intack) irq = readb(pci_intack); else { + spin_lock(&i8259_lock); + lock = 1; + /* Perform an interrupt acknowledge cycle on controller 1. */ outb(0x0C, 0x20); /* prepare for poll */ irq = inb(0x20) & 7; @@ -62,16 +70,13 @@ int i8259_irq(struct pt_regs *regs) if (!pci_intack) outb(0x0B, 0x20); /* ISR register */ if(~inb(0x20) & 0x80) - irq = -1; - } + irq = NO_IRQ; + } else if (irq == 0xff) + irq = NO_IRQ; - spin_unlock(&i8259_lock); - return irq + i8259_pic_irq_offset; -} - -int i8259_irq_cascade(struct pt_regs *regs, void *unused) -{ - return i8259_irq(regs); + if (lock) + spin_unlock(&i8259_lock); + return irq; } static void i8259_mask_and_ack_irq(unsigned int irq_nr) @@ -79,7 +84,6 @@ static void i8259_mask_and_ack_irq(unsigned int irq_nr) unsigned long flags; spin_lock_irqsave(&i8259_lock, flags); - irq_nr -= i8259_pic_irq_offset; if (irq_nr > 7) { cached_A1 |= 1 << (irq_nr-8); inb(0xA1); /* DUMMY */ @@ -105,8 +109,9 @@ static void i8259_mask_irq(unsigned int irq_nr) { unsigned long flags; + pr_debug("i8259_mask_irq(%d)\n", irq_nr); + spin_lock_irqsave(&i8259_lock, flags); - irq_nr -= i8259_pic_irq_offset; if (irq_nr < 8) cached_21 |= 1 << irq_nr; else @@ -119,8 +124,9 @@ static void i8259_unmask_irq(unsigned int irq_nr) { unsigned long flags; + pr_debug("i8259_unmask_irq(%d)\n", irq_nr); + spin_lock_irqsave(&i8259_lock, flags); - irq_nr -= i8259_pic_irq_offset; if (irq_nr < 8) cached_21 &= ~(1 << irq_nr); else @@ -129,19 +135,11 @@ static void i8259_unmask_irq(unsigned int irq_nr) spin_unlock_irqrestore(&i8259_lock, flags); } -static void i8259_end_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)) - && irq_desc[irq].action) - i8259_unmask_irq(irq); -} - -struct hw_interrupt_type i8259_pic = { - .typename = " i8259 ", - .enable = i8259_unmask_irq, - .disable = i8259_mask_irq, - .ack = i8259_mask_and_ack_irq, - .end = i8259_end_irq, +static struct irq_chip i8259_pic = { + .typename = " i8259 ", + .mask = i8259_mask_irq, + .unmask = i8259_unmask_irq, + .mask_ack = i8259_mask_and_ack_irq, }; static struct resource pic1_iores = { @@ -165,25 +163,84 @@ static struct resource pic_edgectrl_iores = { .flags = IORESOURCE_BUSY, }; -static struct irqaction i8259_irqaction = { - .handler = no_action, - .flags = SA_INTERRUPT, - .mask = CPU_MASK_NONE, - .name = "82c59 secondary cascade", +static int i8259_host_match(struct irq_host *h, struct device_node *node) +{ + return i8259_node == NULL || i8259_node == node; +} + +static int i8259_host_map(struct irq_host *h, unsigned int virq, + irq_hw_number_t hw) +{ + pr_debug("i8259_host_map(%d, 0x%lx)\n", virq, hw); + + /* We block the internal cascade */ + if (hw == 2) + get_irq_desc(virq)->status |= IRQ_NOREQUEST; + + /* We use the level handler only for now, we might want to + * be more cautious here but that works for now + */ + get_irq_desc(virq)->status |= IRQ_LEVEL; + set_irq_chip_and_handler(virq, &i8259_pic, handle_level_irq); + return 0; +} + +static void i8259_host_unmap(struct irq_host *h, unsigned int virq) +{ + /* Make sure irq is masked in hardware */ + i8259_mask_irq(virq); + + /* remove chip and handler */ + set_irq_chip_and_handler(virq, NULL, NULL); + + /* Make sure it's completed */ + synchronize_irq(virq); +} + +static int i8259_host_xlate(struct irq_host *h, struct device_node *ct, + u32 *intspec, unsigned int intsize, + irq_hw_number_t *out_hwirq, unsigned int *out_flags) +{ + static unsigned char map_isa_senses[4] = { + IRQ_TYPE_LEVEL_LOW, + IRQ_TYPE_LEVEL_HIGH, + IRQ_TYPE_EDGE_FALLING, + IRQ_TYPE_EDGE_RISING, + }; + + *out_hwirq = intspec[0]; + if (intsize > 1 && intspec[1] < 4) + *out_flags = map_isa_senses[intspec[1]]; + else + *out_flags = IRQ_TYPE_NONE; + + return 0; +} + +static struct irq_host_ops i8259_host_ops = { + .match = i8259_host_match, + .map = i8259_host_map, + .unmap = i8259_host_unmap, + .xlate = i8259_host_xlate, }; -/* - * i8259_init() - * intack_addr - PCI interrupt acknowledge (real) address which will return - * the active irq from the 8259 +/** + * i8259_init - Initialize the legacy controller + * @node: device node of the legacy PIC (can be NULL, but then, it will match + * all interrupts, so beware) + * @intack_addr: PCI interrupt acknowledge (real) address which will return + * the active irq from the 8259 */ -void __init i8259_init(unsigned long intack_addr, int offset) +void i8259_init(struct device_node *node, unsigned long intack_addr) { unsigned long flags; - int i; + /* initialize the controller */ spin_lock_irqsave(&i8259_lock, flags); - i8259_pic_irq_offset = offset; + + /* Mask all first */ + outb(0xff, 0xA1); + outb(0xff, 0x21); /* init master interrupt controller */ outb(0x11, 0x20); /* Start init sequence */ @@ -197,21 +254,36 @@ void __init i8259_init(unsigned long intack_addr, int offset) outb(0x02, 0xA1); /* edge triggered, Cascade (slave) on IRQ2 */ outb(0x01, 0xA1); /* Select 8086 mode */ + /* That thing is slow */ + udelay(100); + /* always read ISR */ outb(0x0B, 0x20); outb(0x0B, 0xA0); - /* Mask all interrupts */ + /* Unmask the internal cascade */ + cached_21 &= ~(1 << 2); + + /* Set interrupt masks */ outb(cached_A1, 0xA1); outb(cached_21, 0x21); spin_unlock_irqrestore(&i8259_lock, flags); - for (i = 0; i < NUM_ISA_INTERRUPTS; ++i) - irq_desc[offset + i].handler = &i8259_pic; + /* create a legacy host */ + if (node) + i8259_node = of_node_get(node); + i8259_host = irq_alloc_host(IRQ_HOST_MAP_LEGACY, 0, &i8259_host_ops, 0); + if (i8259_host == NULL) { + printk(KERN_ERR "i8259: failed to allocate irq host !\n"); + return; + } /* reserve our resources */ - setup_irq(offset + 2, &i8259_irqaction); + /* XXX should we continue doing that ? it seems to cause problems + * with further requesting of PCI IO resources for that range... + * need to look into it. + */ request_resource(&ioport_resource, &pic1_iores); request_resource(&ioport_resource, &pic2_iores); request_resource(&ioport_resource, &pic_edgectrl_iores); @@ -219,4 +291,5 @@ void __init i8259_init(unsigned long intack_addr, int offset) if (intack_addr != 0) pci_intack = ioremap(intack_addr, 1); + printk(KERN_INFO "i8259 legacy interrupt controller initialized\n"); } diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c index 8f01e0f1d847..0251b7c68d0e 100644 --- a/arch/powerpc/sysdev/ipic.c +++ b/arch/powerpc/sysdev/ipic.c @@ -19,15 +19,18 @@ #include <linux/sched.h> #include <linux/signal.h> #include <linux/sysdev.h> +#include <linux/device.h> +#include <linux/bootmem.h> +#include <linux/spinlock.h> #include <asm/irq.h> #include <asm/io.h> +#include <asm/prom.h> #include <asm/ipic.h> -#include <asm/mpc83xx.h> #include "ipic.h" -static struct ipic p_ipic; static struct ipic * primary_ipic; +static DEFINE_SPINLOCK(ipic_lock); static struct ipic_info ipic_info[] = { [9] = { @@ -207,7 +210,7 @@ static struct ipic_info ipic_info[] = { .prio_mask = 4, }, [64] = { - .pend = IPIC_SIPNR_H, + .pend = IPIC_SIPNR_L, .mask = IPIC_SIMSR_L, .prio = IPIC_SMPRR_A, .force = IPIC_SIFCR_L, @@ -215,7 +218,7 @@ static struct ipic_info ipic_info[] = { .prio_mask = 0, }, [65] = { - .pend = IPIC_SIPNR_H, + .pend = IPIC_SIPNR_L, .mask = IPIC_SIMSR_L, .prio = IPIC_SMPRR_A, .force = IPIC_SIFCR_L, @@ -223,7 +226,7 @@ static struct ipic_info ipic_info[] = { .prio_mask = 1, }, [66] = { - .pend = IPIC_SIPNR_H, + .pend = IPIC_SIPNR_L, .mask = IPIC_SIMSR_L, .prio = IPIC_SMPRR_A, .force = IPIC_SIFCR_L, @@ -231,7 +234,7 @@ static struct ipic_info ipic_info[] = { .prio_mask = 2, }, [67] = { - .pend = IPIC_SIPNR_H, + .pend = IPIC_SIPNR_L, .mask = IPIC_SIMSR_L, .prio = IPIC_SMPRR_A, .force = IPIC_SIFCR_L, @@ -239,7 +242,7 @@ static struct ipic_info ipic_info[] = { .prio_mask = 3, }, [68] = { - .pend = IPIC_SIPNR_H, + .pend = IPIC_SIPNR_L, .mask = IPIC_SIMSR_L, .prio = IPIC_SMPRR_B, .force = IPIC_SIFCR_L, @@ -247,7 +250,7 @@ static struct ipic_info ipic_info[] = { .prio_mask = 0, }, [69] = { - .pend = IPIC_SIPNR_H, + .pend = IPIC_SIPNR_L, .mask = IPIC_SIMSR_L, .prio = IPIC_SMPRR_B, .force = IPIC_SIFCR_L, @@ -255,7 +258,7 @@ static struct ipic_info ipic_info[] = { .prio_mask = 1, }, [70] = { - .pend = IPIC_SIPNR_H, + .pend = IPIC_SIPNR_L, .mask = IPIC_SIMSR_L, .prio = IPIC_SMPRR_B, .force = IPIC_SIFCR_L, @@ -263,7 +266,7 @@ static struct ipic_info ipic_info[] = { .prio_mask = 2, }, [71] = { - .pend = IPIC_SIPNR_H, + .pend = IPIC_SIPNR_L, .mask = IPIC_SIMSR_L, .prio = IPIC_SMPRR_B, .force = IPIC_SIFCR_L, @@ -271,91 +274,91 @@ static struct ipic_info ipic_info[] = { .prio_mask = 3, }, [72] = { - .pend = IPIC_SIPNR_H, + .pend = IPIC_SIPNR_L, .mask = IPIC_SIMSR_L, .prio = 0, .force = IPIC_SIFCR_L, .bit = 8, }, [73] = { - .pend = IPIC_SIPNR_H, + .pend = IPIC_SIPNR_L, .mask = IPIC_SIMSR_L, .prio = 0, .force = IPIC_SIFCR_L, .bit = 9, }, [74] = { - .pend = IPIC_SIPNR_H, + .pend = IPIC_SIPNR_L, .mask = IPIC_SIMSR_L, .prio = 0, .force = IPIC_SIFCR_L, .bit = 10, }, [75] = { - .pend = IPIC_SIPNR_H, + .pend = IPIC_SIPNR_L, .mask = IPIC_SIMSR_L, .prio = 0, .force = IPIC_SIFCR_L, .bit = 11, }, [76] = { - .pend = IPIC_SIPNR_H, + .pend = IPIC_SIPNR_L, .mask = IPIC_SIMSR_L, .prio = 0, .force = IPIC_SIFCR_L, .bit = 12, }, [77] = { - .pend = IPIC_SIPNR_H, + .pend = IPIC_SIPNR_L, .mask = IPIC_SIMSR_L, .prio = 0, .force = IPIC_SIFCR_L, .bit = 13, }, [78] = { - .pend = IPIC_SIPNR_H, + .pend = IPIC_SIPNR_L, .mask = IPIC_SIMSR_L, .prio = 0, .force = IPIC_SIFCR_L, .bit = 14, }, [79] = { - .pend = IPIC_SIPNR_H, + .pend = IPIC_SIPNR_L, .mask = IPIC_SIMSR_L, .prio = 0, .force = IPIC_SIFCR_L, .bit = 15, }, [80] = { - .pend = IPIC_SIPNR_H, + .pend = IPIC_SIPNR_L, .mask = IPIC_SIMSR_L, .prio = 0, .force = IPIC_SIFCR_L, .bit = 16, }, [84] = { - .pend = IPIC_SIPNR_H, + .pend = IPIC_SIPNR_L, .mask = IPIC_SIMSR_L, .prio = 0, .force = IPIC_SIFCR_L, .bit = 20, }, [85] = { - .pend = IPIC_SIPNR_H, + .pend = IPIC_SIPNR_L, .mask = IPIC_SIMSR_L, .prio = 0, .force = IPIC_SIFCR_L, .bit = 21, }, [90] = { - .pend = IPIC_SIPNR_H, + .pend = IPIC_SIPNR_L, .mask = IPIC_SIMSR_L, .prio = 0, .force = IPIC_SIFCR_L, .bit = 26, }, [91] = { - .pend = IPIC_SIPNR_H, + .pend = IPIC_SIPNR_L, .mask = IPIC_SIMSR_L, .prio = 0, .force = IPIC_SIFCR_L, @@ -373,74 +376,220 @@ static inline void ipic_write(volatile u32 __iomem *base, unsigned int reg, u32 out_be32(base + (reg >> 2), value); } -static inline struct ipic * ipic_from_irq(unsigned int irq) +static inline struct ipic * ipic_from_irq(unsigned int virq) { return primary_ipic; } -static void ipic_enable_irq(unsigned int irq) +#define ipic_irq_to_hw(virq) ((unsigned int)irq_map[virq].hwirq) + +static void ipic_unmask_irq(unsigned int virq) { - struct ipic *ipic = ipic_from_irq(irq); - unsigned int src = irq - ipic->irq_offset; + struct ipic *ipic = ipic_from_irq(virq); + unsigned int src = ipic_irq_to_hw(virq); + unsigned long flags; u32 temp; + spin_lock_irqsave(&ipic_lock, flags); + temp = ipic_read(ipic->regs, ipic_info[src].mask); temp |= (1 << (31 - ipic_info[src].bit)); ipic_write(ipic->regs, ipic_info[src].mask, temp); + + spin_unlock_irqrestore(&ipic_lock, flags); } -static void ipic_disable_irq(unsigned int irq) +static void ipic_mask_irq(unsigned int virq) { - struct ipic *ipic = ipic_from_irq(irq); - unsigned int src = irq - ipic->irq_offset; + struct ipic *ipic = ipic_from_irq(virq); + unsigned int src = ipic_irq_to_hw(virq); + unsigned long flags; u32 temp; + spin_lock_irqsave(&ipic_lock, flags); + temp = ipic_read(ipic->regs, ipic_info[src].mask); temp &= ~(1 << (31 - ipic_info[src].bit)); ipic_write(ipic->regs, ipic_info[src].mask, temp); + + spin_unlock_irqrestore(&ipic_lock, flags); } -static void ipic_disable_irq_and_ack(unsigned int irq) +static void ipic_ack_irq(unsigned int virq) { - struct ipic *ipic = ipic_from_irq(irq); - unsigned int src = irq - ipic->irq_offset; + struct ipic *ipic = ipic_from_irq(virq); + unsigned int src = ipic_irq_to_hw(virq); + unsigned long flags; u32 temp; - ipic_disable_irq(irq); + spin_lock_irqsave(&ipic_lock, flags); + + temp = ipic_read(ipic->regs, ipic_info[src].pend); + temp |= (1 << (31 - ipic_info[src].bit)); + ipic_write(ipic->regs, ipic_info[src].pend, temp); + + spin_unlock_irqrestore(&ipic_lock, flags); +} + +static void ipic_mask_irq_and_ack(unsigned int virq) +{ + struct ipic *ipic = ipic_from_irq(virq); + unsigned int src = ipic_irq_to_hw(virq); + unsigned long flags; + u32 temp; + + spin_lock_irqsave(&ipic_lock, flags); + + temp = ipic_read(ipic->regs, ipic_info[src].mask); + temp &= ~(1 << (31 - ipic_info[src].bit)); + ipic_write(ipic->regs, ipic_info[src].mask, temp); temp = ipic_read(ipic->regs, ipic_info[src].pend); temp |= (1 << (31 - ipic_info[src].bit)); ipic_write(ipic->regs, ipic_info[src].pend, temp); + + spin_unlock_irqrestore(&ipic_lock, flags); } -static void ipic_end_irq(unsigned int irq) +static int ipic_set_irq_type(unsigned int virq, unsigned int flow_type) { - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - ipic_enable_irq(irq); + struct ipic *ipic = ipic_from_irq(virq); + unsigned int src = ipic_irq_to_hw(virq); + struct irq_desc *desc = get_irq_desc(virq); + unsigned int vold, vnew, edibit; + + if (flow_type == IRQ_TYPE_NONE) + flow_type = IRQ_TYPE_LEVEL_LOW; + + /* ipic supports only low assertion and high-to-low change senses + */ + if (!(flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING))) { + printk(KERN_ERR "ipic: sense type 0x%x not supported\n", + flow_type); + return -EINVAL; + } + + desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); + desc->status |= flow_type & IRQ_TYPE_SENSE_MASK; + if (flow_type & IRQ_TYPE_LEVEL_LOW) { + desc->status |= IRQ_LEVEL; + set_irq_handler(virq, handle_level_irq); + } else { + set_irq_handler(virq, handle_edge_irq); + } + + /* only EXT IRQ senses are programmable on ipic + * internal IRQ senses are LEVEL_LOW + */ + if (src == IPIC_IRQ_EXT0) + edibit = 15; + else + if (src >= IPIC_IRQ_EXT1 && src <= IPIC_IRQ_EXT7) + edibit = (14 - (src - IPIC_IRQ_EXT1)); + else + return (flow_type & IRQ_TYPE_LEVEL_LOW) ? 0 : -EINVAL; + + vold = ipic_read(ipic->regs, IPIC_SECNR); + if ((flow_type & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_FALLING) { + vnew = vold | (1 << edibit); + } else { + vnew = vold & ~(1 << edibit); + } + if (vold != vnew) + ipic_write(ipic->regs, IPIC_SECNR, vnew); + return 0; } -struct hw_interrupt_type ipic = { - .typename = " IPIC ", - .enable = ipic_enable_irq, - .disable = ipic_disable_irq, - .ack = ipic_disable_irq_and_ack, - .end = ipic_end_irq, +static struct irq_chip ipic_irq_chip = { + .typename = " IPIC ", + .unmask = ipic_unmask_irq, + .mask = ipic_mask_irq, + .mask_ack = ipic_mask_irq_and_ack, + .ack = ipic_ack_irq, + .set_type = ipic_set_irq_type, }; -void __init ipic_init(phys_addr_t phys_addr, - unsigned int flags, - unsigned int irq_offset, - unsigned char *senses, - unsigned int senses_count) +static int ipic_host_match(struct irq_host *h, struct device_node *node) +{ + struct ipic *ipic = h->host_data; + + /* Exact match, unless ipic node is NULL */ + return ipic->of_node == NULL || ipic->of_node == node; +} + +static int ipic_host_map(struct irq_host *h, unsigned int virq, + irq_hw_number_t hw) { - u32 i, temp = 0; + struct ipic *ipic = h->host_data; + struct irq_chip *chip; + + /* Default chip */ + chip = &ipic->hc_irq; + + set_irq_chip_data(virq, ipic); + set_irq_chip_and_handler(virq, chip, handle_level_irq); - primary_ipic = &p_ipic; - primary_ipic->regs = ioremap(phys_addr, MPC83xx_IPIC_SIZE); + /* Set default irq type */ + set_irq_type(virq, IRQ_TYPE_NONE); - primary_ipic->irq_offset = irq_offset; + return 0; +} - ipic_write(primary_ipic->regs, IPIC_SICNR, 0x0); +static int ipic_host_xlate(struct irq_host *h, struct device_node *ct, + u32 *intspec, unsigned int intsize, + irq_hw_number_t *out_hwirq, unsigned int *out_flags) + +{ + /* interrupt sense values coming from the device tree equal either + * LEVEL_LOW (low assertion) or EDGE_FALLING (high-to-low change) + */ + *out_hwirq = intspec[0]; + if (intsize > 1) + *out_flags = intspec[1]; + else + *out_flags = IRQ_TYPE_NONE; + return 0; +} + +static struct irq_host_ops ipic_host_ops = { + .match = ipic_host_match, + .map = ipic_host_map, + .xlate = ipic_host_xlate, +}; + +void __init ipic_init(struct device_node *node, + unsigned int flags) +{ + struct ipic *ipic; + struct resource res; + u32 temp = 0, ret; + + ipic = alloc_bootmem(sizeof(struct ipic)); + if (ipic == NULL) + return; + + memset(ipic, 0, sizeof(struct ipic)); + ipic->of_node = node ? of_node_get(node) : NULL; + + ipic->irqhost = irq_alloc_host(IRQ_HOST_MAP_LINEAR, + NR_IPIC_INTS, + &ipic_host_ops, 0); + if (ipic->irqhost == NULL) { + of_node_put(node); + return; + } + + ret = of_address_to_resource(node, 0, &res); + if (ret) + return; + + ipic->regs = ioremap(res.start, res.end - res.start + 1); + + ipic->irqhost->host_data = ipic; + ipic->hc_irq = ipic_irq_chip; + + /* init hw */ + ipic_write(ipic->regs, IPIC_SICNR, 0x0); /* default priority scheme is grouped. If spread mode is required * configure SICFR accordingly */ @@ -453,49 +602,35 @@ void __init ipic_init(phys_addr_t phys_addr, if (flags & IPIC_SPREADMODE_MIX_B) temp |= SICFR_MPSB; - ipic_write(primary_ipic->regs, IPIC_SICNR, temp); + ipic_write(ipic->regs, IPIC_SICNR, temp); /* handle MCP route */ temp = 0; if (flags & IPIC_DISABLE_MCP_OUT) temp = SERCR_MCPR; - ipic_write(primary_ipic->regs, IPIC_SERCR, temp); + ipic_write(ipic->regs, IPIC_SERCR, temp); /* handle routing of IRQ0 to MCP */ - temp = ipic_read(primary_ipic->regs, IPIC_SEMSR); + temp = ipic_read(ipic->regs, IPIC_SEMSR); if (flags & IPIC_IRQ0_MCP) temp |= SEMSR_SIRQ0; else temp &= ~SEMSR_SIRQ0; - ipic_write(primary_ipic->regs, IPIC_SEMSR, temp); + ipic_write(ipic->regs, IPIC_SEMSR, temp); - for (i = 0 ; i < NR_IPIC_INTS ; i++) { - irq_desc[i+irq_offset].handler = &ipic; - irq_desc[i+irq_offset].status = IRQ_LEVEL; - } + primary_ipic = ipic; + irq_set_default_host(primary_ipic->irqhost); - temp = 0; - for (i = 0 ; i < senses_count ; i++) { - if ((senses[i] & IRQ_SENSE_MASK) == IRQ_SENSE_EDGE) { - temp |= 1 << (15 - i); - if (i != 0) - irq_desc[i + irq_offset + MPC83xx_IRQ_EXT1 - 1].status = 0; - else - irq_desc[irq_offset + MPC83xx_IRQ_EXT0].status = 0; - } - } - ipic_write(primary_ipic->regs, IPIC_SECNR, temp); - - printk ("IPIC (%d IRQ sources, %d External IRQs) at %p\n", NR_IPIC_INTS, - senses_count, primary_ipic->regs); + printk ("IPIC (%d IRQ sources) at %p\n", NR_IPIC_INTS, + primary_ipic->regs); } -int ipic_set_priority(unsigned int irq, unsigned int priority) +int ipic_set_priority(unsigned int virq, unsigned int priority) { - struct ipic *ipic = ipic_from_irq(irq); - unsigned int src = irq - ipic->irq_offset; + struct ipic *ipic = ipic_from_irq(virq); + unsigned int src = ipic_irq_to_hw(virq); u32 temp; if (priority > 7) @@ -520,10 +655,10 @@ int ipic_set_priority(unsigned int irq, unsigned int priority) return 0; } -void ipic_set_highest_priority(unsigned int irq) +void ipic_set_highest_priority(unsigned int virq) { - struct ipic *ipic = ipic_from_irq(irq); - unsigned int src = irq - ipic->irq_offset; + struct ipic *ipic = ipic_from_irq(virq); + unsigned int src = ipic_irq_to_hw(virq); u32 temp; temp = ipic_read(ipic->regs, IPIC_SICFR); @@ -537,37 +672,10 @@ void ipic_set_highest_priority(unsigned int irq) void ipic_set_default_priority(void) { - ipic_set_priority(MPC83xx_IRQ_TSEC1_TX, 0); - ipic_set_priority(MPC83xx_IRQ_TSEC1_RX, 1); - ipic_set_priority(MPC83xx_IRQ_TSEC1_ERROR, 2); - ipic_set_priority(MPC83xx_IRQ_TSEC2_TX, 3); - ipic_set_priority(MPC83xx_IRQ_TSEC2_RX, 4); - ipic_set_priority(MPC83xx_IRQ_TSEC2_ERROR, 5); - ipic_set_priority(MPC83xx_IRQ_USB2_DR, 6); - ipic_set_priority(MPC83xx_IRQ_USB2_MPH, 7); - - ipic_set_priority(MPC83xx_IRQ_UART1, 0); - ipic_set_priority(MPC83xx_IRQ_UART2, 1); - ipic_set_priority(MPC83xx_IRQ_SEC2, 2); - ipic_set_priority(MPC83xx_IRQ_IIC1, 5); - ipic_set_priority(MPC83xx_IRQ_IIC2, 6); - ipic_set_priority(MPC83xx_IRQ_SPI, 7); - ipic_set_priority(MPC83xx_IRQ_RTC_SEC, 0); - ipic_set_priority(MPC83xx_IRQ_PIT, 1); - ipic_set_priority(MPC83xx_IRQ_PCI1, 2); - ipic_set_priority(MPC83xx_IRQ_PCI2, 3); - ipic_set_priority(MPC83xx_IRQ_EXT0, 4); - ipic_set_priority(MPC83xx_IRQ_EXT1, 5); - ipic_set_priority(MPC83xx_IRQ_EXT2, 6); - ipic_set_priority(MPC83xx_IRQ_EXT3, 7); - ipic_set_priority(MPC83xx_IRQ_RTC_ALR, 0); - ipic_set_priority(MPC83xx_IRQ_MU, 1); - ipic_set_priority(MPC83xx_IRQ_SBA, 2); - ipic_set_priority(MPC83xx_IRQ_DMA, 3); - ipic_set_priority(MPC83xx_IRQ_EXT4, 4); - ipic_set_priority(MPC83xx_IRQ_EXT5, 5); - ipic_set_priority(MPC83xx_IRQ_EXT6, 6); - ipic_set_priority(MPC83xx_IRQ_EXT7, 7); + ipic_write(primary_ipic->regs, IPIC_SIPRR_A, IPIC_SIPRR_A_DEFAULT); + ipic_write(primary_ipic->regs, IPIC_SIPRR_D, IPIC_SIPRR_D_DEFAULT); + ipic_write(primary_ipic->regs, IPIC_SMPRR_A, IPIC_SMPRR_A_DEFAULT); + ipic_write(primary_ipic->regs, IPIC_SMPRR_B, IPIC_SMPRR_B_DEFAULT); } void ipic_enable_mcp(enum ipic_mcp_irq mcp_irq) @@ -600,17 +708,20 @@ void ipic_clear_mcp_status(u32 mask) ipic_write(primary_ipic->regs, IPIC_SERMR, mask); } -/* Return an interrupt vector or -1 if no interrupt is pending. */ -int ipic_get_irq(struct pt_regs *regs) +/* Return an interrupt vector or NO_IRQ if no interrupt is pending. */ +unsigned int ipic_get_irq(struct pt_regs *regs) { int irq; - irq = ipic_read(primary_ipic->regs, IPIC_SIVCR) & 0x7f; + BUG_ON(primary_ipic == NULL); + +#define IPIC_SIVCR_VECTOR_MASK 0x7f + irq = ipic_read(primary_ipic->regs, IPIC_SIVCR) & IPIC_SIVCR_VECTOR_MASK; if (irq == 0) /* 0 --> no irq is pending */ - irq = -1; + return NO_IRQ; - return irq; + return irq_linear_revmap(primary_ipic->irqhost, irq); } static struct sysdev_class ipic_sysclass = { diff --git a/arch/powerpc/sysdev/ipic.h b/arch/powerpc/sysdev/ipic.h index a60c9d18bb7f..c28e589877eb 100644 --- a/arch/powerpc/sysdev/ipic.h +++ b/arch/powerpc/sysdev/ipic.h @@ -15,7 +15,18 @@ #include <asm/ipic.h> -#define MPC83xx_IPIC_SIZE (0x00100) +#define NR_IPIC_INTS 128 + +/* External IRQS */ +#define IPIC_IRQ_EXT0 48 +#define IPIC_IRQ_EXT1 17 +#define IPIC_IRQ_EXT7 23 + +/* Default Priority Registers */ +#define IPIC_SIPRR_A_DEFAULT 0x05309770 +#define IPIC_SIPRR_D_DEFAULT 0x05309770 +#define IPIC_SMPRR_A_DEFAULT 0x05309770 +#define IPIC_SMPRR_B_DEFAULT 0x05309770 /* System Global Interrupt Configuration Register */ #define SICFR_IPSA 0x00010000 @@ -31,7 +42,15 @@ struct ipic { volatile u32 __iomem *regs; - unsigned int irq_offset; + + /* The remapper for this IPIC */ + struct irq_host *irqhost; + + /* The "linux" controller struct */ + struct irq_chip hc_irq; + + /* The device node of the interrupt controller */ + struct device_node *of_node; }; struct ipic_info { diff --git a/arch/powerpc/sysdev/mmio_nvram.c b/arch/powerpc/sysdev/mmio_nvram.c index 74e0d31a3559..ff23f5a4d4b9 100644 --- a/arch/powerpc/sysdev/mmio_nvram.c +++ b/arch/powerpc/sysdev/mmio_nvram.c @@ -32,7 +32,7 @@ static void __iomem *mmio_nvram_start; static long mmio_nvram_len; -static spinlock_t mmio_nvram_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(mmio_nvram_lock); static ssize_t mmio_nvram_read(char *buf, size_t count, loff_t *index) { @@ -80,7 +80,7 @@ static ssize_t mmio_nvram_get_size(void) int __init mmio_nvram_init(void) { struct device_node *nvram_node; - unsigned long *buffer; + const unsigned long *buffer; int proplen; unsigned long nvram_addr; int ret; @@ -91,7 +91,7 @@ int __init mmio_nvram_init(void) goto out; ret = -EIO; - buffer = (unsigned long *)get_property(nvram_node, "reg", &proplen); + buffer = get_property(nvram_node, "reg", &proplen); if (proplen != 2*sizeof(unsigned long)) goto out; diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index bffe50d02c99..723972bb5bd9 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -17,7 +17,6 @@ #undef DEBUG_IRQ #undef DEBUG_LOW -#include <linux/config.h> #include <linux/types.h> #include <linux/kernel.h> #include <linux/init.h> @@ -55,6 +54,94 @@ static DEFINE_SPINLOCK(mpic_lock); #endif #endif +#ifdef CONFIG_MPIC_WEIRD +static u32 mpic_infos[][MPIC_IDX_END] = { + [0] = { /* Original OpenPIC compatible MPIC */ + MPIC_GREG_BASE, + MPIC_GREG_FEATURE_0, + MPIC_GREG_GLOBAL_CONF_0, + MPIC_GREG_VENDOR_ID, + MPIC_GREG_IPI_VECTOR_PRI_0, + MPIC_GREG_IPI_STRIDE, + MPIC_GREG_SPURIOUS, + MPIC_GREG_TIMER_FREQ, + + MPIC_TIMER_BASE, + MPIC_TIMER_STRIDE, + MPIC_TIMER_CURRENT_CNT, + MPIC_TIMER_BASE_CNT, + MPIC_TIMER_VECTOR_PRI, + MPIC_TIMER_DESTINATION, + + MPIC_CPU_BASE, + MPIC_CPU_STRIDE, + MPIC_CPU_IPI_DISPATCH_0, + MPIC_CPU_IPI_DISPATCH_STRIDE, + MPIC_CPU_CURRENT_TASK_PRI, + MPIC_CPU_WHOAMI, + MPIC_CPU_INTACK, + MPIC_CPU_EOI, + + MPIC_IRQ_BASE, + MPIC_IRQ_STRIDE, + MPIC_IRQ_VECTOR_PRI, + MPIC_VECPRI_VECTOR_MASK, + MPIC_VECPRI_POLARITY_POSITIVE, + MPIC_VECPRI_POLARITY_NEGATIVE, + MPIC_VECPRI_SENSE_LEVEL, + MPIC_VECPRI_SENSE_EDGE, + MPIC_VECPRI_POLARITY_MASK, + MPIC_VECPRI_SENSE_MASK, + MPIC_IRQ_DESTINATION + }, + [1] = { /* Tsi108/109 PIC */ + TSI108_GREG_BASE, + TSI108_GREG_FEATURE_0, + TSI108_GREG_GLOBAL_CONF_0, + TSI108_GREG_VENDOR_ID, + TSI108_GREG_IPI_VECTOR_PRI_0, + TSI108_GREG_IPI_STRIDE, + TSI108_GREG_SPURIOUS, + TSI108_GREG_TIMER_FREQ, + + TSI108_TIMER_BASE, + TSI108_TIMER_STRIDE, + TSI108_TIMER_CURRENT_CNT, + TSI108_TIMER_BASE_CNT, + TSI108_TIMER_VECTOR_PRI, + TSI108_TIMER_DESTINATION, + + TSI108_CPU_BASE, + TSI108_CPU_STRIDE, + TSI108_CPU_IPI_DISPATCH_0, + TSI108_CPU_IPI_DISPATCH_STRIDE, + TSI108_CPU_CURRENT_TASK_PRI, + TSI108_CPU_WHOAMI, + TSI108_CPU_INTACK, + TSI108_CPU_EOI, + + TSI108_IRQ_BASE, + TSI108_IRQ_STRIDE, + TSI108_IRQ_VECTOR_PRI, + TSI108_VECPRI_VECTOR_MASK, + TSI108_VECPRI_POLARITY_POSITIVE, + TSI108_VECPRI_POLARITY_NEGATIVE, + TSI108_VECPRI_SENSE_LEVEL, + TSI108_VECPRI_SENSE_EDGE, + TSI108_VECPRI_POLARITY_MASK, + TSI108_VECPRI_SENSE_MASK, + TSI108_IRQ_DESTINATION + }, +}; + +#define MPIC_INFO(name) mpic->hw_set[MPIC_IDX_##name] + +#else /* CONFIG_MPIC_WEIRD */ + +#define MPIC_INFO(name) MPIC_##name + +#endif /* CONFIG_MPIC_WEIRD */ + /* * Register accessor functions */ @@ -81,7 +168,8 @@ static inline void _mpic_write(unsigned int be, volatile u32 __iomem *base, static inline u32 _mpic_ipi_read(struct mpic *mpic, unsigned int ipi) { unsigned int be = (mpic->flags & MPIC_BIG_ENDIAN) != 0; - unsigned int offset = MPIC_GREG_IPI_VECTOR_PRI_0 + (ipi * 0x10); + unsigned int offset = MPIC_INFO(GREG_IPI_VECTOR_PRI_0) + + (ipi * MPIC_INFO(GREG_IPI_STRIDE)); if (mpic->flags & MPIC_BROKEN_IPI) be = !be; @@ -90,7 +178,8 @@ static inline u32 _mpic_ipi_read(struct mpic *mpic, unsigned int ipi) static inline void _mpic_ipi_write(struct mpic *mpic, unsigned int ipi, u32 value) { - unsigned int offset = MPIC_GREG_IPI_VECTOR_PRI_0 + (ipi * 0x10); + unsigned int offset = MPIC_INFO(GREG_IPI_VECTOR_PRI_0) + + (ipi * MPIC_INFO(GREG_IPI_STRIDE)); _mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->gregs, offset, value); } @@ -101,8 +190,8 @@ static inline u32 _mpic_cpu_read(struct mpic *mpic, unsigned int reg) if (mpic->flags & MPIC_PRIMARY) cpu = hard_smp_processor_id(); - - return _mpic_read(mpic->flags & MPIC_BIG_ENDIAN, mpic->cpuregs[cpu], reg); + return _mpic_read(mpic->flags & MPIC_BIG_ENDIAN, + mpic->cpuregs[cpu], reg); } static inline void _mpic_cpu_write(struct mpic *mpic, unsigned int reg, u32 value) @@ -121,7 +210,7 @@ static inline u32 _mpic_irq_read(struct mpic *mpic, unsigned int src_no, unsigne unsigned int idx = src_no & mpic->isu_mask; return _mpic_read(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu], - reg + (idx * MPIC_IRQ_STRIDE)); + reg + (idx * MPIC_INFO(IRQ_STRIDE))); } static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no, @@ -131,7 +220,7 @@ static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no, unsigned int idx = src_no & mpic->isu_mask; _mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu], - reg + (idx * MPIC_IRQ_STRIDE), value); + reg + (idx * MPIC_INFO(IRQ_STRIDE)), value); } #define mpic_read(b,r) _mpic_read(mpic->flags & MPIC_BIG_ENDIAN,(b),(r)) @@ -157,8 +246,8 @@ static void __init mpic_test_broken_ipi(struct mpic *mpic) { u32 r; - mpic_write(mpic->gregs, MPIC_GREG_IPI_VECTOR_PRI_0, MPIC_VECPRI_MASK); - r = mpic_read(mpic->gregs, MPIC_GREG_IPI_VECTOR_PRI_0); + mpic_write(mpic->gregs, MPIC_INFO(GREG_IPI_VECTOR_PRI_0), MPIC_VECPRI_MASK); + r = mpic_read(mpic->gregs, MPIC_INFO(GREG_IPI_VECTOR_PRI_0)); if (r == le32_to_cpu(MPIC_VECPRI_MASK)) { printk(KERN_INFO "mpic: Detected reversed IPI registers\n"); @@ -205,7 +294,7 @@ static void mpic_startup_ht_interrupt(struct mpic *mpic, unsigned int source, if (fixup->base == NULL) return; - DBG("startup_ht_interrupt(%u, %u) index: %d\n", + DBG("startup_ht_interrupt(0x%x, 0x%x) index: %d\n", source, irqflags, fixup->index); spin_lock_irqsave(&mpic->fixup_lock, flags); /* Enable and configure */ @@ -228,7 +317,7 @@ static void mpic_shutdown_ht_interrupt(struct mpic *mpic, unsigned int source, if (fixup->base == NULL) return; - DBG("shutdown_ht_interrupt(%u, %u)\n", source, irqflags); + DBG("shutdown_ht_interrupt(0x%x, 0x%x)\n", source, irqflags); /* Disable */ spin_lock_irqsave(&mpic->fixup_lock, flags); @@ -250,7 +339,7 @@ static void __init mpic_scan_ht_pic(struct mpic *mpic, u8 __iomem *devbase, for (pos = readb(devbase + PCI_CAPABILITY_LIST); pos != 0; pos = readb(devbase + pos + PCI_CAP_LIST_NEXT)) { u8 id = readb(devbase + pos + PCI_CAP_LIST_ID); - if (id == PCI_CAP_ID_HT_IRQCONF) { + if (id == PCI_CAP_ID_HT) { id = readb(devbase + pos + 3); if (id == 0x80) break; @@ -338,30 +427,33 @@ static void __init mpic_scan_ht_pics(struct mpic *mpic) } } +#else /* CONFIG_MPIC_BROKEN_U3 */ + +static inline int mpic_is_ht_interrupt(struct mpic *mpic, unsigned int source) +{ + return 0; +} + +static void __init mpic_scan_ht_pics(struct mpic *mpic) +{ +} + #endif /* CONFIG_MPIC_BROKEN_U3 */ +#define mpic_irq_to_hw(virq) ((unsigned int)irq_map[virq].hwirq) + /* Find an mpic associated with a given linux interrupt */ static struct mpic *mpic_find(unsigned int irq, unsigned int *is_ipi) { - struct mpic *mpic = mpics; - - while(mpic) { - /* search IPIs first since they may override the main interrupts */ - if (irq >= mpic->ipi_offset && irq < (mpic->ipi_offset + 4)) { - if (is_ipi) - *is_ipi = 1; - return mpic; - } - if (irq >= mpic->irq_offset && - irq < (mpic->irq_offset + mpic->irq_count)) { - if (is_ipi) - *is_ipi = 0; - return mpic; - } - mpic = mpic -> next; - } - return NULL; + unsigned int src = mpic_irq_to_hw(irq); + + if (irq < NUM_ISA_INTERRUPTS) + return NULL; + if (is_ipi) + *is_ipi = (src >= MPIC_VEC_IPI_0 && src <= MPIC_VEC_IPI_3); + + return irq_desc[irq].chip_data; } /* Convert a cpu mask from logical to physical cpu numbers. */ @@ -379,29 +471,27 @@ static inline u32 mpic_physmask(u32 cpumask) /* Get the mpic structure from the IPI number */ static inline struct mpic * mpic_from_ipi(unsigned int ipi) { - return container_of(irq_desc[ipi].handler, struct mpic, hc_ipi); + return irq_desc[ipi].chip_data; } #endif /* Get the mpic structure from the irq number */ static inline struct mpic * mpic_from_irq(unsigned int irq) { - return container_of(irq_desc[irq].handler, struct mpic, hc_irq); + return irq_desc[irq].chip_data; } /* Send an EOI */ static inline void mpic_eoi(struct mpic *mpic) { - mpic_cpu_write(MPIC_CPU_EOI, 0); - (void)mpic_cpu_read(MPIC_CPU_WHOAMI); + mpic_cpu_write(MPIC_INFO(CPU_EOI), 0); + (void)mpic_cpu_read(MPIC_INFO(CPU_WHOAMI)); } #ifdef CONFIG_SMP static irqreturn_t mpic_ipi_action(int irq, void *dev_id, struct pt_regs *regs) { - struct mpic *mpic = dev_id; - - smp_message_recv(irq - mpic->ipi_offset, regs); + smp_message_recv(mpic_irq_to_hw(irq) - MPIC_VEC_IPI_0, regs); return IRQ_HANDLED; } #endif /* CONFIG_SMP */ @@ -411,63 +501,36 @@ static irqreturn_t mpic_ipi_action(int irq, void *dev_id, struct pt_regs *regs) */ -static void mpic_enable_irq(unsigned int irq) +static void mpic_unmask_irq(unsigned int irq) { unsigned int loops = 100000; struct mpic *mpic = mpic_from_irq(irq); - unsigned int src = irq - mpic->irq_offset; + unsigned int src = mpic_irq_to_hw(irq); DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, irq, src); - mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI, - mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & + mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI), + mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & ~MPIC_VECPRI_MASK); - /* make sure mask gets to controller before we return to user */ do { if (!loops--) { printk(KERN_ERR "mpic_enable_irq timeout\n"); break; } - } while(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK); - -#ifdef CONFIG_MPIC_BROKEN_U3 - if (mpic->flags & MPIC_BROKEN_U3) { - unsigned int src = irq - mpic->irq_offset; - if (mpic_is_ht_interrupt(mpic, src) && - (irq_desc[irq].status & IRQ_LEVEL)) - mpic_ht_end_irq(mpic, src); - } -#endif /* CONFIG_MPIC_BROKEN_U3 */ + } while(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & MPIC_VECPRI_MASK); } -static unsigned int mpic_startup_irq(unsigned int irq) -{ -#ifdef CONFIG_MPIC_BROKEN_U3 - struct mpic *mpic = mpic_from_irq(irq); - unsigned int src = irq - mpic->irq_offset; -#endif /* CONFIG_MPIC_BROKEN_U3 */ - - mpic_enable_irq(irq); - -#ifdef CONFIG_MPIC_BROKEN_U3 - if (mpic_is_ht_interrupt(mpic, src)) - mpic_startup_ht_interrupt(mpic, src, irq_desc[irq].status); -#endif /* CONFIG_MPIC_BROKEN_U3 */ - - return 0; -} - -static void mpic_disable_irq(unsigned int irq) +static void mpic_mask_irq(unsigned int irq) { unsigned int loops = 100000; struct mpic *mpic = mpic_from_irq(irq); - unsigned int src = irq - mpic->irq_offset; + unsigned int src = mpic_irq_to_hw(irq); DBG("%s: disable_irq: %d (src %d)\n", mpic->name, irq, src); - mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI, - mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) | + mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI), + mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) | MPIC_VECPRI_MASK); /* make sure mask gets to controller before we return to user */ @@ -476,26 +539,61 @@ static void mpic_disable_irq(unsigned int irq) printk(KERN_ERR "mpic_enable_irq timeout\n"); break; } - } while(!(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK)); + } while(!(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & MPIC_VECPRI_MASK)); } -static void mpic_shutdown_irq(unsigned int irq) +static void mpic_end_irq(unsigned int irq) { + struct mpic *mpic = mpic_from_irq(irq); + +#ifdef DEBUG_IRQ + DBG("%s: end_irq: %d\n", mpic->name, irq); +#endif + /* We always EOI on end_irq() even for edge interrupts since that + * should only lower the priority, the MPIC should have properly + * latched another edge interrupt coming in anyway + */ + + mpic_eoi(mpic); +} + #ifdef CONFIG_MPIC_BROKEN_U3 + +static void mpic_unmask_ht_irq(unsigned int irq) +{ struct mpic *mpic = mpic_from_irq(irq); - unsigned int src = irq - mpic->irq_offset; + unsigned int src = mpic_irq_to_hw(irq); - if (mpic_is_ht_interrupt(mpic, src)) - mpic_shutdown_ht_interrupt(mpic, src, irq_desc[irq].status); + mpic_unmask_irq(irq); -#endif /* CONFIG_MPIC_BROKEN_U3 */ + if (irq_desc[irq].status & IRQ_LEVEL) + mpic_ht_end_irq(mpic, src); +} - mpic_disable_irq(irq); +static unsigned int mpic_startup_ht_irq(unsigned int irq) +{ + struct mpic *mpic = mpic_from_irq(irq); + unsigned int src = mpic_irq_to_hw(irq); + + mpic_unmask_irq(irq); + mpic_startup_ht_interrupt(mpic, src, irq_desc[irq].status); + + return 0; } -static void mpic_end_irq(unsigned int irq) +static void mpic_shutdown_ht_irq(unsigned int irq) +{ + struct mpic *mpic = mpic_from_irq(irq); + unsigned int src = mpic_irq_to_hw(irq); + + mpic_shutdown_ht_interrupt(mpic, src, irq_desc[irq].status); + mpic_mask_irq(irq); +} + +static void mpic_end_ht_irq(unsigned int irq) { struct mpic *mpic = mpic_from_irq(irq); + unsigned int src = mpic_irq_to_hw(irq); #ifdef DEBUG_IRQ DBG("%s: end_irq: %d\n", mpic->name, irq); @@ -505,30 +603,24 @@ static void mpic_end_irq(unsigned int irq) * latched another edge interrupt coming in anyway */ -#ifdef CONFIG_MPIC_BROKEN_U3 - if (mpic->flags & MPIC_BROKEN_U3) { - unsigned int src = irq - mpic->irq_offset; - if (mpic_is_ht_interrupt(mpic, src) && - (irq_desc[irq].status & IRQ_LEVEL)) - mpic_ht_end_irq(mpic, src); - } -#endif /* CONFIG_MPIC_BROKEN_U3 */ - + if (irq_desc[irq].status & IRQ_LEVEL) + mpic_ht_end_irq(mpic, src); mpic_eoi(mpic); } +#endif /* !CONFIG_MPIC_BROKEN_U3 */ #ifdef CONFIG_SMP -static void mpic_enable_ipi(unsigned int irq) +static void mpic_unmask_ipi(unsigned int irq) { struct mpic *mpic = mpic_from_ipi(irq); - unsigned int src = irq - mpic->ipi_offset; + unsigned int src = mpic_irq_to_hw(irq) - MPIC_VEC_IPI_0; DBG("%s: enable_ipi: %d (ipi %d)\n", mpic->name, irq, src); mpic_ipi_write(src, mpic_ipi_read(src) & ~MPIC_VECPRI_MASK); } -static void mpic_disable_ipi(unsigned int irq) +static void mpic_mask_ipi(unsigned int irq) { /* NEVER disable an IPI... that's just plain wrong! */ } @@ -541,7 +633,7 @@ static void mpic_end_ipi(unsigned int irq) * IPIs are marked IRQ_PER_CPU. This has the side effect of * preventing the IRQ_PENDING/IRQ_INPROGRESS logic from * applying to them. We EOI them late to avoid re-entering. - * We mark IPI's with SA_INTERRUPT as they must run with + * We mark IPI's with IRQF_DISABLED as they must run with * irqs disabled. */ mpic_eoi(mpic); @@ -552,29 +644,211 @@ static void mpic_end_ipi(unsigned int irq) static void mpic_set_affinity(unsigned int irq, cpumask_t cpumask) { struct mpic *mpic = mpic_from_irq(irq); + unsigned int src = mpic_irq_to_hw(irq); cpumask_t tmp; cpus_and(tmp, cpumask, cpu_online_map); - mpic_irq_write(irq - mpic->irq_offset, MPIC_IRQ_DESTINATION, + mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION), mpic_physmask(cpus_addr(tmp)[0])); } +static unsigned int mpic_type_to_vecpri(struct mpic *mpic, unsigned int type) +{ + /* Now convert sense value */ + switch(type & IRQ_TYPE_SENSE_MASK) { + case IRQ_TYPE_EDGE_RISING: + return MPIC_INFO(VECPRI_SENSE_EDGE) | + MPIC_INFO(VECPRI_POLARITY_POSITIVE); + case IRQ_TYPE_EDGE_FALLING: + case IRQ_TYPE_EDGE_BOTH: + return MPIC_INFO(VECPRI_SENSE_EDGE) | + MPIC_INFO(VECPRI_POLARITY_NEGATIVE); + case IRQ_TYPE_LEVEL_HIGH: + return MPIC_INFO(VECPRI_SENSE_LEVEL) | + MPIC_INFO(VECPRI_POLARITY_POSITIVE); + case IRQ_TYPE_LEVEL_LOW: + default: + return MPIC_INFO(VECPRI_SENSE_LEVEL) | + MPIC_INFO(VECPRI_POLARITY_NEGATIVE); + } +} + +static int mpic_set_irq_type(unsigned int virq, unsigned int flow_type) +{ + struct mpic *mpic = mpic_from_irq(virq); + unsigned int src = mpic_irq_to_hw(virq); + struct irq_desc *desc = get_irq_desc(virq); + unsigned int vecpri, vold, vnew; + + DBG("mpic: set_irq_type(mpic:@%p,virq:%d,src:0x%x,type:0x%x)\n", + mpic, virq, src, flow_type); + + if (src >= mpic->irq_count) + return -EINVAL; + + if (flow_type == IRQ_TYPE_NONE) + if (mpic->senses && src < mpic->senses_count) + flow_type = mpic->senses[src]; + if (flow_type == IRQ_TYPE_NONE) + flow_type = IRQ_TYPE_LEVEL_LOW; + + desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); + desc->status |= flow_type & IRQ_TYPE_SENSE_MASK; + if (flow_type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) + desc->status |= IRQ_LEVEL; + + if (mpic_is_ht_interrupt(mpic, src)) + vecpri = MPIC_VECPRI_POLARITY_POSITIVE | + MPIC_VECPRI_SENSE_EDGE; + else + vecpri = mpic_type_to_vecpri(mpic, flow_type); + + vold = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)); + vnew = vold & ~(MPIC_INFO(VECPRI_POLARITY_MASK) | + MPIC_INFO(VECPRI_SENSE_MASK)); + vnew |= vecpri; + if (vold != vnew) + mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI), vnew); + + return 0; +} + +static struct irq_chip mpic_irq_chip = { + .mask = mpic_mask_irq, + .unmask = mpic_unmask_irq, + .eoi = mpic_end_irq, + .set_type = mpic_set_irq_type, +}; + +#ifdef CONFIG_SMP +static struct irq_chip mpic_ipi_chip = { + .mask = mpic_mask_ipi, + .unmask = mpic_unmask_ipi, + .eoi = mpic_end_ipi, +}; +#endif /* CONFIG_SMP */ + +#ifdef CONFIG_MPIC_BROKEN_U3 +static struct irq_chip mpic_irq_ht_chip = { + .startup = mpic_startup_ht_irq, + .shutdown = mpic_shutdown_ht_irq, + .mask = mpic_mask_irq, + .unmask = mpic_unmask_ht_irq, + .eoi = mpic_end_ht_irq, + .set_type = mpic_set_irq_type, +}; +#endif /* CONFIG_MPIC_BROKEN_U3 */ + + +static int mpic_host_match(struct irq_host *h, struct device_node *node) +{ + struct mpic *mpic = h->host_data; + + /* Exact match, unless mpic node is NULL */ + return mpic->of_node == NULL || mpic->of_node == node; +} + +static int mpic_host_map(struct irq_host *h, unsigned int virq, + irq_hw_number_t hw) +{ + struct mpic *mpic = h->host_data; + struct irq_chip *chip; + + DBG("mpic: map virq %d, hwirq 0x%lx\n", virq, hw); + + if (hw == MPIC_VEC_SPURRIOUS) + return -EINVAL; + +#ifdef CONFIG_SMP + else if (hw >= MPIC_VEC_IPI_0) { + WARN_ON(!(mpic->flags & MPIC_PRIMARY)); + + DBG("mpic: mapping as IPI\n"); + set_irq_chip_data(virq, mpic); + set_irq_chip_and_handler(virq, &mpic->hc_ipi, + handle_percpu_irq); + return 0; + } +#endif /* CONFIG_SMP */ + + if (hw >= mpic->irq_count) + return -EINVAL; + + /* Default chip */ + chip = &mpic->hc_irq; + +#ifdef CONFIG_MPIC_BROKEN_U3 + /* Check for HT interrupts, override vecpri */ + if (mpic_is_ht_interrupt(mpic, hw)) + chip = &mpic->hc_ht_irq; +#endif /* CONFIG_MPIC_BROKEN_U3 */ + + DBG("mpic: mapping to irq chip @%p\n", chip); + + set_irq_chip_data(virq, mpic); + set_irq_chip_and_handler(virq, chip, handle_fasteoi_irq); + + /* Set default irq type */ + set_irq_type(virq, IRQ_TYPE_NONE); + + return 0; +} + +static int mpic_host_xlate(struct irq_host *h, struct device_node *ct, + u32 *intspec, unsigned int intsize, + irq_hw_number_t *out_hwirq, unsigned int *out_flags) + +{ + static unsigned char map_mpic_senses[4] = { + IRQ_TYPE_EDGE_RISING, + IRQ_TYPE_LEVEL_LOW, + IRQ_TYPE_LEVEL_HIGH, + IRQ_TYPE_EDGE_FALLING, + }; + + *out_hwirq = intspec[0]; + if (intsize > 1) { + u32 mask = 0x3; + + /* Apple invented a new race of encoding on machines with + * an HT APIC. They encode, among others, the index within + * the HT APIC. We don't care about it here since thankfully, + * it appears that they have the APIC already properly + * configured, and thus our current fixup code that reads the + * APIC config works fine. However, we still need to mask out + * bits in the specifier to make sure we only get bit 0 which + * is the level/edge bit (the only sense bit exposed by Apple), + * as their bit 1 means something else. + */ + if (machine_is(powermac)) + mask = 0x1; + *out_flags = map_mpic_senses[intspec[1] & mask]; + } else + *out_flags = IRQ_TYPE_NONE; + + DBG("mpic: xlate (%d cells: 0x%08x 0x%08x) to line 0x%lx sense 0x%x\n", + intsize, intspec[0], intspec[1], *out_hwirq, *out_flags); + + return 0; +} + +static struct irq_host_ops mpic_host_ops = { + .match = mpic_host_match, + .map = mpic_host_map, + .xlate = mpic_host_xlate, +}; /* * Exported functions */ - -struct mpic * __init mpic_alloc(unsigned long phys_addr, +struct mpic * __init mpic_alloc(struct device_node *node, + unsigned long phys_addr, unsigned int flags, unsigned int isu_size, - unsigned int irq_offset, unsigned int irq_count, - unsigned int ipi_offset, - unsigned char *senses, - unsigned int senses_count, const char *name) { struct mpic *mpic; @@ -586,45 +860,55 @@ struct mpic * __init mpic_alloc(unsigned long phys_addr, if (mpic == NULL) return NULL; - memset(mpic, 0, sizeof(struct mpic)); mpic->name = name; + mpic->of_node = node ? of_node_get(node) : NULL; + mpic->irqhost = irq_alloc_host(IRQ_HOST_MAP_LINEAR, 256, + &mpic_host_ops, + MPIC_VEC_SPURRIOUS); + if (mpic->irqhost == NULL) { + of_node_put(node); + return NULL; + } + + mpic->irqhost->host_data = mpic; + mpic->hc_irq = mpic_irq_chip; mpic->hc_irq.typename = name; - mpic->hc_irq.startup = mpic_startup_irq; - mpic->hc_irq.shutdown = mpic_shutdown_irq; - mpic->hc_irq.enable = mpic_enable_irq; - mpic->hc_irq.disable = mpic_disable_irq; - mpic->hc_irq.end = mpic_end_irq; if (flags & MPIC_PRIMARY) mpic->hc_irq.set_affinity = mpic_set_affinity; +#ifdef CONFIG_MPIC_BROKEN_U3 + mpic->hc_ht_irq = mpic_irq_ht_chip; + mpic->hc_ht_irq.typename = name; + if (flags & MPIC_PRIMARY) + mpic->hc_ht_irq.set_affinity = mpic_set_affinity; +#endif /* CONFIG_MPIC_BROKEN_U3 */ #ifdef CONFIG_SMP + mpic->hc_ipi = mpic_ipi_chip; mpic->hc_ipi.typename = name; - mpic->hc_ipi.enable = mpic_enable_ipi; - mpic->hc_ipi.disable = mpic_disable_ipi; - mpic->hc_ipi.end = mpic_end_ipi; #endif /* CONFIG_SMP */ mpic->flags = flags; mpic->isu_size = isu_size; - mpic->irq_offset = irq_offset; mpic->irq_count = irq_count; - mpic->ipi_offset = ipi_offset; mpic->num_sources = 0; /* so far */ - mpic->senses = senses; - mpic->senses_count = senses_count; + +#ifdef CONFIG_MPIC_WEIRD + mpic->hw_set = mpic_infos[MPIC_GET_REGSET(flags)]; +#endif /* Map the global registers */ - mpic->gregs = ioremap(phys_addr + MPIC_GREG_BASE, 0x1000); - mpic->tmregs = mpic->gregs + ((MPIC_TIMER_BASE - MPIC_GREG_BASE) >> 2); + mpic->gregs = ioremap(phys_addr + MPIC_INFO(GREG_BASE), 0x1000); + mpic->tmregs = mpic->gregs + + ((MPIC_INFO(TIMER_BASE) - MPIC_INFO(GREG_BASE)) >> 2); BUG_ON(mpic->gregs == NULL); /* Reset */ if (flags & MPIC_WANTS_RESET) { - mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0, - mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0) + mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0), + mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0)) | MPIC_GREG_GCONF_RESET); - while( mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0) + while( mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0)) & MPIC_GREG_GCONF_RESET) mb(); } @@ -633,7 +917,7 @@ struct mpic * __init mpic_alloc(unsigned long phys_addr, * MPICs, num sources as well. On ISU MPICs, sources are counted * as ISUs are added */ - reg = mpic_read(mpic->gregs, MPIC_GREG_FEATURE_0); + reg = mpic_read(mpic->gregs, MPIC_INFO(GREG_FEATURE_0)); mpic->num_cpus = ((reg & MPIC_GREG_FEATURE_LAST_CPU_MASK) >> MPIC_GREG_FEATURE_LAST_CPU_SHIFT) + 1; if (isu_size == 0) @@ -642,16 +926,16 @@ struct mpic * __init mpic_alloc(unsigned long phys_addr, /* Map the per-CPU registers */ for (i = 0; i < mpic->num_cpus; i++) { - mpic->cpuregs[i] = ioremap(phys_addr + MPIC_CPU_BASE + - i * MPIC_CPU_STRIDE, 0x1000); + mpic->cpuregs[i] = ioremap(phys_addr + MPIC_INFO(CPU_BASE) + + i * MPIC_INFO(CPU_STRIDE), 0x1000); BUG_ON(mpic->cpuregs[i] == NULL); } /* Initialize main ISU if none provided */ if (mpic->isu_size == 0) { mpic->isu_size = mpic->num_sources; - mpic->isus[0] = ioremap(phys_addr + MPIC_IRQ_BASE, - MPIC_IRQ_STRIDE * mpic->isu_size); + mpic->isus[0] = ioremap(phys_addr + MPIC_INFO(IRQ_BASE), + MPIC_INFO(IRQ_STRIDE) * mpic->isu_size); BUG_ON(mpic->isus[0] == NULL); } mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1); @@ -680,8 +964,10 @@ struct mpic * __init mpic_alloc(unsigned long phys_addr, mpic->next = mpics; mpics = mpic; - if (flags & MPIC_PRIMARY) + if (flags & MPIC_PRIMARY) { mpic_primary = mpic; + irq_set_default_host(mpic->irqhost); + } return mpic; } @@ -693,31 +979,16 @@ void __init mpic_assign_isu(struct mpic *mpic, unsigned int isu_num, BUG_ON(isu_num >= MPIC_MAX_ISU); - mpic->isus[isu_num] = ioremap(phys_addr, MPIC_IRQ_STRIDE * mpic->isu_size); + mpic->isus[isu_num] = ioremap(phys_addr, + MPIC_INFO(IRQ_STRIDE) * mpic->isu_size); if ((isu_first + mpic->isu_size) > mpic->num_sources) mpic->num_sources = isu_first + mpic->isu_size; } -void __init mpic_setup_cascade(unsigned int irq, mpic_cascade_t handler, - void *data) +void __init mpic_set_default_senses(struct mpic *mpic, u8 *senses, int count) { - struct mpic *mpic = mpic_find(irq, NULL); - unsigned long flags; - - /* Synchronization here is a bit dodgy, so don't try to replace cascade - * interrupts on the fly too often ... but normally it's set up at boot. - */ - spin_lock_irqsave(&mpic_lock, flags); - if (mpic->cascade) - mpic_disable_irq(mpic->cascade_vec + mpic->irq_offset); - mpic->cascade = NULL; - wmb(); - mpic->cascade_vec = irq - mpic->irq_offset; - mpic->cascade_data = data; - wmb(); - mpic->cascade = handler; - mpic_enable_irq(irq); - spin_unlock_irqrestore(&mpic_lock, flags); + mpic->senses = senses; + mpic->senses_count = count; } void __init mpic_init(struct mpic *mpic) @@ -725,18 +996,25 @@ void __init mpic_init(struct mpic *mpic) int i; BUG_ON(mpic->num_sources == 0); + WARN_ON(mpic->num_sources > MPIC_VEC_IPI_0); + + /* Sanitize source count */ + if (mpic->num_sources > MPIC_VEC_IPI_0) + mpic->num_sources = MPIC_VEC_IPI_0; printk(KERN_INFO "mpic: Initializing for %d sources\n", mpic->num_sources); /* Set current processor priority to max */ - mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0xf); + mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0xf); /* Initialize timers: just disable them all */ for (i = 0; i < 4; i++) { mpic_write(mpic->tmregs, - i * MPIC_TIMER_STRIDE + MPIC_TIMER_DESTINATION, 0); + i * MPIC_INFO(TIMER_STRIDE) + + MPIC_INFO(TIMER_DESTINATION), 0); mpic_write(mpic->tmregs, - i * MPIC_TIMER_STRIDE + MPIC_TIMER_VECTOR_PRI, + i * MPIC_INFO(TIMER_STRIDE) + + MPIC_INFO(TIMER_VECTOR_PRI), MPIC_VECPRI_MASK | (MPIC_VEC_TIMER_0 + i)); } @@ -748,85 +1026,39 @@ void __init mpic_init(struct mpic *mpic) MPIC_VECPRI_MASK | (10 << MPIC_VECPRI_PRIORITY_SHIFT) | (MPIC_VEC_IPI_0 + i)); -#ifdef CONFIG_SMP - if (!(mpic->flags & MPIC_PRIMARY)) - continue; - irq_desc[mpic->ipi_offset+i].status |= IRQ_PER_CPU; - irq_desc[mpic->ipi_offset+i].handler = &mpic->hc_ipi; -#endif /* CONFIG_SMP */ } /* Initialize interrupt sources */ if (mpic->irq_count == 0) mpic->irq_count = mpic->num_sources; -#ifdef CONFIG_MPIC_BROKEN_U3 /* Do the HT PIC fixups on U3 broken mpic */ DBG("MPIC flags: %x\n", mpic->flags); if ((mpic->flags & MPIC_BROKEN_U3) && (mpic->flags & MPIC_PRIMARY)) - mpic_scan_ht_pics(mpic); -#endif /* CONFIG_MPIC_BROKEN_U3 */ + mpic_scan_ht_pics(mpic); for (i = 0; i < mpic->num_sources; i++) { /* start with vector = source number, and masked */ - u32 vecpri = MPIC_VECPRI_MASK | i | (8 << MPIC_VECPRI_PRIORITY_SHIFT); - int level = 0; + u32 vecpri = MPIC_VECPRI_MASK | i | + (8 << MPIC_VECPRI_PRIORITY_SHIFT); - /* if it's an IPI, we skip it */ - if ((mpic->irq_offset + i) >= (mpic->ipi_offset + i) && - (mpic->irq_offset + i) < (mpic->ipi_offset + i + 4)) - continue; - - /* do senses munging */ - if (mpic->senses && i < mpic->senses_count) { - if (mpic->senses[i] & IRQ_SENSE_LEVEL) - vecpri |= MPIC_VECPRI_SENSE_LEVEL; - if (mpic->senses[i] & IRQ_POLARITY_POSITIVE) - vecpri |= MPIC_VECPRI_POLARITY_POSITIVE; - } else - vecpri |= MPIC_VECPRI_SENSE_LEVEL; - - /* remember if it was a level interrupts */ - level = (vecpri & MPIC_VECPRI_SENSE_LEVEL); - - /* deal with broken U3 */ - if (mpic->flags & MPIC_BROKEN_U3) { -#ifdef CONFIG_MPIC_BROKEN_U3 - if (mpic_is_ht_interrupt(mpic, i)) { - vecpri &= ~(MPIC_VECPRI_SENSE_MASK | - MPIC_VECPRI_POLARITY_MASK); - vecpri |= MPIC_VECPRI_POLARITY_POSITIVE; - } -#else - printk(KERN_ERR "mpic: BROKEN_U3 set, but CONFIG doesn't match\n"); -#endif - } - - DBG("setup source %d, vecpri: %08x, level: %d\n", i, vecpri, - (level != 0)); - /* init hw */ - mpic_irq_write(i, MPIC_IRQ_VECTOR_PRI, vecpri); - mpic_irq_write(i, MPIC_IRQ_DESTINATION, + mpic_irq_write(i, MPIC_INFO(IRQ_VECTOR_PRI), vecpri); + mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION), 1 << hard_smp_processor_id()); - - /* init linux descriptors */ - if (i < mpic->irq_count) { - irq_desc[mpic->irq_offset+i].status = level ? IRQ_LEVEL : 0; - irq_desc[mpic->irq_offset+i].handler = &mpic->hc_irq; - } } /* Init spurrious vector */ - mpic_write(mpic->gregs, MPIC_GREG_SPURIOUS, MPIC_VEC_SPURRIOUS); + mpic_write(mpic->gregs, MPIC_INFO(GREG_SPURIOUS), MPIC_VEC_SPURRIOUS); - /* Disable 8259 passthrough */ - mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0, - mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0) - | MPIC_GREG_GCONF_8259_PTHROU_DIS); + /* Disable 8259 passthrough, if supported */ + if (!(mpic->flags & MPIC_NO_PTHROU_DIS)) + mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0), + mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0)) + | MPIC_GREG_GCONF_8259_PTHROU_DIS); /* Set current processor priority to 0 */ - mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0); + mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0); } void __init mpic_set_clk_ratio(struct mpic *mpic, u32 clock_ratio) @@ -841,33 +1073,37 @@ void __init mpic_set_clk_ratio(struct mpic *mpic, u32 clock_ratio) void __init mpic_set_serial_int(struct mpic *mpic, int enable) { + unsigned long flags; u32 v; + spin_lock_irqsave(&mpic_lock, flags); v = mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_1); if (enable) v |= MPIC_GREG_GLOBAL_CONF_1_SIE; else v &= ~MPIC_GREG_GLOBAL_CONF_1_SIE; mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_1, v); + spin_unlock_irqrestore(&mpic_lock, flags); } void mpic_irq_set_priority(unsigned int irq, unsigned int pri) { int is_ipi; struct mpic *mpic = mpic_find(irq, &is_ipi); + unsigned int src = mpic_irq_to_hw(irq); unsigned long flags; u32 reg; spin_lock_irqsave(&mpic_lock, flags); if (is_ipi) { - reg = mpic_ipi_read(irq - mpic->ipi_offset) & + reg = mpic_ipi_read(src - MPIC_VEC_IPI_0) & ~MPIC_VECPRI_PRIORITY_MASK; - mpic_ipi_write(irq - mpic->ipi_offset, + mpic_ipi_write(src - MPIC_VEC_IPI_0, reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT)); } else { - reg = mpic_irq_read(irq - mpic->irq_offset,MPIC_IRQ_VECTOR_PRI) + reg = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & ~MPIC_VECPRI_PRIORITY_MASK; - mpic_irq_write(irq - mpic->irq_offset, MPIC_IRQ_VECTOR_PRI, + mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI), reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT)); } spin_unlock_irqrestore(&mpic_lock, flags); @@ -877,14 +1113,15 @@ unsigned int mpic_irq_get_priority(unsigned int irq) { int is_ipi; struct mpic *mpic = mpic_find(irq, &is_ipi); + unsigned int src = mpic_irq_to_hw(irq); unsigned long flags; u32 reg; spin_lock_irqsave(&mpic_lock, flags); if (is_ipi) - reg = mpic_ipi_read(irq - mpic->ipi_offset); + reg = mpic_ipi_read(src = MPIC_VEC_IPI_0); else - reg = mpic_irq_read(irq - mpic->irq_offset, MPIC_IRQ_VECTOR_PRI); + reg = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)); spin_unlock_irqrestore(&mpic_lock, flags); return (reg & MPIC_VECPRI_PRIORITY_MASK) >> MPIC_VECPRI_PRIORITY_SHIFT; } @@ -906,16 +1143,16 @@ void mpic_setup_this_cpu(void) /* let the mpic know we want intrs. default affinity is 0xffffffff * until changed via /proc. That's how it's done on x86. If we want * it differently, then we should make sure we also change the default - * values of irq_affinity in irq.c. + * values of irq_desc[].affinity in irq.c. */ if (distribute_irqs) { for (i = 0; i < mpic->num_sources ; i++) - mpic_irq_write(i, MPIC_IRQ_DESTINATION, - mpic_irq_read(i, MPIC_IRQ_DESTINATION) | msk); + mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION), + mpic_irq_read(i, MPIC_INFO(IRQ_DESTINATION)) | msk); } /* Set current processor priority to 0 */ - mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0); + mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0); spin_unlock_irqrestore(&mpic_lock, flags); #endif /* CONFIG_SMP */ @@ -925,7 +1162,7 @@ int mpic_cpu_get_priority(void) { struct mpic *mpic = mpic_primary; - return mpic_cpu_read(MPIC_CPU_CURRENT_TASK_PRI); + return mpic_cpu_read(MPIC_INFO(CPU_CURRENT_TASK_PRI)); } void mpic_cpu_set_priority(int prio) @@ -933,7 +1170,7 @@ void mpic_cpu_set_priority(int prio) struct mpic *mpic = mpic_primary; prio &= MPIC_CPU_TASKPRI_MASK; - mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, prio); + mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), prio); } /* @@ -955,11 +1192,11 @@ void mpic_teardown_this_cpu(int secondary) /* let the mpic know we don't want intrs. */ for (i = 0; i < mpic->num_sources ; i++) - mpic_irq_write(i, MPIC_IRQ_DESTINATION, - mpic_irq_read(i, MPIC_IRQ_DESTINATION) & ~msk); + mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION), + mpic_irq_read(i, MPIC_INFO(IRQ_DESTINATION)) & ~msk); /* Set current processor priority to max */ - mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0xf); + mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0xf); spin_unlock_irqrestore(&mpic_lock, flags); } @@ -975,41 +1212,25 @@ void mpic_send_ipi(unsigned int ipi_no, unsigned int cpu_mask) DBG("%s: send_ipi(ipi_no: %d)\n", mpic->name, ipi_no); #endif - mpic_cpu_write(MPIC_CPU_IPI_DISPATCH_0 + ipi_no * 0x10, + mpic_cpu_write(MPIC_INFO(CPU_IPI_DISPATCH_0) + + ipi_no * MPIC_INFO(CPU_IPI_DISPATCH_STRIDE), mpic_physmask(cpu_mask & cpus_addr(cpu_online_map)[0])); } -int mpic_get_one_irq(struct mpic *mpic, struct pt_regs *regs) +unsigned int mpic_get_one_irq(struct mpic *mpic, struct pt_regs *regs) { - u32 irq; + u32 src; - irq = mpic_cpu_read(MPIC_CPU_INTACK) & MPIC_VECPRI_VECTOR_MASK; + src = mpic_cpu_read(MPIC_INFO(CPU_INTACK)) & MPIC_INFO(VECPRI_VECTOR_MASK); #ifdef DEBUG_LOW - DBG("%s: get_one_irq(): %d\n", mpic->name, irq); -#endif - if (mpic->cascade && irq == mpic->cascade_vec) { -#ifdef DEBUG_LOW - DBG("%s: cascading ...\n", mpic->name); -#endif - irq = mpic->cascade(regs, mpic->cascade_data); - mpic_eoi(mpic); - return irq; - } - if (unlikely(irq == MPIC_VEC_SPURRIOUS)) - return -1; - if (irq < MPIC_VEC_IPI_0) { -#ifdef DEBUG_IRQ - DBG("%s: irq %d\n", mpic->name, irq + mpic->irq_offset); -#endif - return irq + mpic->irq_offset; - } -#ifdef DEBUG_IPI - DBG("%s: ipi %d !\n", mpic->name, irq - MPIC_VEC_IPI_0); + DBG("%s: get_one_irq(): %d\n", mpic->name, src); #endif - return irq - MPIC_VEC_IPI_0 + mpic->ipi_offset; + if (unlikely(src == MPIC_VEC_SPURRIOUS)) + return NO_IRQ; + return irq_linear_revmap(mpic->irqhost, src); } -int mpic_get_irq(struct pt_regs *regs) +unsigned int mpic_get_irq(struct pt_regs *regs) { struct mpic *mpic = mpic_primary; @@ -1023,22 +1244,27 @@ int mpic_get_irq(struct pt_regs *regs) void mpic_request_ipis(void) { struct mpic *mpic = mpic_primary; - + int i; + static char *ipi_names[] = { + "IPI0 (call function)", + "IPI1 (reschedule)", + "IPI2 (unused)", + "IPI3 (debugger break)", + }; BUG_ON(mpic == NULL); - - printk("requesting IPIs ... \n"); - - /* IPIs are marked SA_INTERRUPT as they must run with irqs disabled */ - request_irq(mpic->ipi_offset+0, mpic_ipi_action, SA_INTERRUPT, - "IPI0 (call function)", mpic); - request_irq(mpic->ipi_offset+1, mpic_ipi_action, SA_INTERRUPT, - "IPI1 (reschedule)", mpic); - request_irq(mpic->ipi_offset+2, mpic_ipi_action, SA_INTERRUPT, - "IPI2 (unused)", mpic); - request_irq(mpic->ipi_offset+3, mpic_ipi_action, SA_INTERRUPT, - "IPI3 (debugger break)", mpic); - - printk("IPIs requested... \n"); + + printk(KERN_INFO "mpic: requesting IPIs ... \n"); + + for (i = 0; i < 4; i++) { + unsigned int vipi = irq_create_mapping(mpic->irqhost, + MPIC_VEC_IPI_0 + i); + if (vipi == NO_IRQ) { + printk(KERN_ERR "Failed to map IPI %d\n", i); + break; + } + request_irq(vipi, mpic_ipi_action, IRQF_DISABLED, + ipi_names[i], mpic); + } } void smp_mpic_message_pass(int target, int msg) diff --git a/arch/powerpc/sysdev/todc.c b/arch/powerpc/sysdev/todc.c new file mode 100644 index 000000000000..0a65980efb50 --- /dev/null +++ b/arch/powerpc/sysdev/todc.c @@ -0,0 +1,392 @@ +/* + * Time of Day Clock support for the M48T35, M48T37, M48T59, and MC146818 + * Real Time Clocks/Timekeepers. + * + * Author: Mark A. Greer <mgreer@mvista.com> + * + * 2001-2004 (c) MontaVista, Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ +#include <linux/errno.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/time.h> +#include <linux/timex.h> +#include <linux/bcd.h> +#include <linux/mc146818rtc.h> + +#include <asm/machdep.h> +#include <asm/io.h> +#include <asm/time.h> +#include <asm/todc.h> + +/* + * Depending on the hardware on your board and your board design, the + * RTC/NVRAM may be accessed either directly (like normal memory) or via + * address/data registers. If your board uses the direct method, set + * 'nvram_data' to the base address of your nvram and leave 'nvram_as0' and + * 'nvram_as1' NULL. If your board uses address/data regs to access nvram, + * set 'nvram_as0' to the address of the lower byte, set 'nvram_as1' to the + * address of the upper byte (leave NULL if using mc146818), and set + * 'nvram_data' to the address of the 8-bit data register. + * + * Note: Even though the documentation for the various RTC chips say that it + * take up to a second before it starts updating once the 'R' bit is + * cleared, they always seem to update even though we bang on it many + * times a second. This is true, except for the Dallas Semi 1746/1747 + * (possibly others). Those chips seem to have a real problem whenever + * we set the 'R' bit before reading them, they basically stop counting. + * --MAG + */ + +/* + * 'todc_info' should be initialized in your *_setup.c file to + * point to a fully initialized 'todc_info_t' structure. + * This structure holds all the register offsets for your particular + * TODC/RTC chip. + * TODC_ALLOC()/TODC_INIT() will allocate and initialize this table for you. + */ + +#ifdef RTC_FREQ_SELECT +#undef RTC_FREQ_SELECT +#define RTC_FREQ_SELECT control_b /* Register A */ +#endif + +#ifdef RTC_CONTROL +#undef RTC_CONTROL +#define RTC_CONTROL control_a /* Register B */ +#endif + +#ifdef RTC_INTR_FLAGS +#undef RTC_INTR_FLAGS +#define RTC_INTR_FLAGS watchdog /* Register C */ +#endif + +#ifdef RTC_VALID +#undef RTC_VALID +#define RTC_VALID interrupts /* Register D */ +#endif + +/* Access routines when RTC accessed directly (like normal memory) */ +u_char +todc_direct_read_val(int addr) +{ + return readb((void __iomem *)(todc_info->nvram_data + addr)); +} + +void +todc_direct_write_val(int addr, unsigned char val) +{ + writeb(val, (void __iomem *)(todc_info->nvram_data + addr)); + return; +} + +/* Access routines for accessing m48txx type chips via addr/data regs */ +u_char +todc_m48txx_read_val(int addr) +{ + outb(addr, todc_info->nvram_as0); + outb(addr>>todc_info->as0_bits, todc_info->nvram_as1); + return inb(todc_info->nvram_data); +} + +void +todc_m48txx_write_val(int addr, unsigned char val) +{ + outb(addr, todc_info->nvram_as0); + outb(addr>>todc_info->as0_bits, todc_info->nvram_as1); + outb(val, todc_info->nvram_data); + return; +} + +/* Access routines for accessing mc146818 type chips via addr/data regs */ +u_char +todc_mc146818_read_val(int addr) +{ + outb_p(addr, todc_info->nvram_as0); + return inb_p(todc_info->nvram_data); +} + +void +todc_mc146818_write_val(int addr, unsigned char val) +{ + outb_p(addr, todc_info->nvram_as0); + outb_p(val, todc_info->nvram_data); +} + + +/* + * Routines to make RTC chips with NVRAM buried behind an addr/data pair + * have the NVRAM and clock regs appear at the same level. + * The NVRAM will appear to start at addr 0 and the clock regs will appear + * to start immediately after the NVRAM (actually, start at offset + * todc_info->nvram_size). + */ +static inline u_char +todc_read_val(int addr) +{ + u_char val; + + if (todc_info->sw_flags & TODC_FLAG_2_LEVEL_NVRAM) { + if (addr < todc_info->nvram_size) { /* NVRAM */ + ppc_md.rtc_write_val(todc_info->nvram_addr_reg, addr); + val = ppc_md.rtc_read_val(todc_info->nvram_data_reg); + } else { /* Clock Reg */ + addr -= todc_info->nvram_size; + val = ppc_md.rtc_read_val(addr); + } + } else + val = ppc_md.rtc_read_val(addr); + + return val; +} + +static inline void +todc_write_val(int addr, u_char val) +{ + if (todc_info->sw_flags & TODC_FLAG_2_LEVEL_NVRAM) { + if (addr < todc_info->nvram_size) { /* NVRAM */ + ppc_md.rtc_write_val(todc_info->nvram_addr_reg, addr); + ppc_md.rtc_write_val(todc_info->nvram_data_reg, val); + } else { /* Clock Reg */ + addr -= todc_info->nvram_size; + ppc_md.rtc_write_val(addr, val); + } + } else + ppc_md.rtc_write_val(addr, val); +} + +/* + * TODC routines + * + * There is some ugly stuff in that there are assumptions for the mc146818. + * + * Assumptions: + * - todc_info->control_a has the offset as mc146818 Register B reg + * - todc_info->control_b has the offset as mc146818 Register A reg + * - m48txx control reg's write enable or 'W' bit is same as + * mc146818 Register B 'SET' bit (i.e., 0x80) + * + * These assumptions were made to make the code simpler. + */ +long __init +todc_time_init(void) +{ + u_char cntl_b; + + if (!ppc_md.rtc_read_val) + ppc_md.rtc_read_val = ppc_md.nvram_read_val; + if (!ppc_md.rtc_write_val) + ppc_md.rtc_write_val = ppc_md.nvram_write_val; + + cntl_b = todc_read_val(todc_info->control_b); + + if (todc_info->rtc_type == TODC_TYPE_MC146818) { + if ((cntl_b & 0x70) != 0x20) { + printk(KERN_INFO "TODC real-time-clock was stopped." + " Now starting..."); + cntl_b &= ~0x70; + cntl_b |= 0x20; + } + + todc_write_val(todc_info->control_b, cntl_b); + } else if (todc_info->rtc_type == TODC_TYPE_DS17285) { + u_char mode; + + mode = todc_read_val(TODC_TYPE_DS17285_CNTL_A); + /* Make sure countdown clear is not set */ + mode &= ~0x40; + /* Enable oscillator, extended register set */ + mode |= 0x30; + todc_write_val(TODC_TYPE_DS17285_CNTL_A, mode); + + } else if (todc_info->rtc_type == TODC_TYPE_DS1501) { + u_char month; + + todc_info->enable_read = TODC_DS1501_CNTL_B_TE; + todc_info->enable_write = TODC_DS1501_CNTL_B_TE; + + month = todc_read_val(todc_info->month); + + if ((month & 0x80) == 0x80) { + printk(KERN_INFO "TODC %s %s\n", + "real-time-clock was stopped.", + "Now starting..."); + month &= ~0x80; + todc_write_val(todc_info->month, month); + } + + cntl_b &= ~TODC_DS1501_CNTL_B_TE; + todc_write_val(todc_info->control_b, cntl_b); + } else { /* must be a m48txx type */ + u_char cntl_a; + + todc_info->enable_read = TODC_MK48TXX_CNTL_A_R; + todc_info->enable_write = TODC_MK48TXX_CNTL_A_W; + + cntl_a = todc_read_val(todc_info->control_a); + + /* Check & clear STOP bit in control B register */ + if (cntl_b & TODC_MK48TXX_DAY_CB) { + printk(KERN_INFO "TODC %s %s\n", + "real-time-clock was stopped.", + "Now starting..."); + + cntl_a |= todc_info->enable_write; + cntl_b &= ~TODC_MK48TXX_DAY_CB;/* Start Oscil */ + + todc_write_val(todc_info->control_a, cntl_a); + todc_write_val(todc_info->control_b, cntl_b); + } + + /* Make sure READ & WRITE bits are cleared. */ + cntl_a &= ~(todc_info->enable_write | todc_info->enable_read); + todc_write_val(todc_info->control_a, cntl_a); + } + + return 0; +} + +/* + * There is some ugly stuff in that there are assumptions that for a mc146818, + * the todc_info->control_a has the offset of the mc146818 Register B reg and + * that the register'ss 'SET' bit is the same as the m48txx's write enable + * bit in the control register of the m48txx (i.e., 0x80). + * + * It was done to make the code look simpler. + */ +void +todc_get_rtc_time(struct rtc_time *tm) +{ + uint year = 0, mon = 0, mday = 0, hour = 0, min = 0, sec = 0; + uint limit, i; + u_char save_control, uip = 0; + extern void GregorianDay(struct rtc_time *); + + spin_lock(&rtc_lock); + save_control = todc_read_val(todc_info->control_a); + + if (todc_info->rtc_type != TODC_TYPE_MC146818) { + limit = 1; + + switch (todc_info->rtc_type) { + case TODC_TYPE_DS1553: + case TODC_TYPE_DS1557: + case TODC_TYPE_DS1743: + case TODC_TYPE_DS1746: /* XXXX BAD HACK -> FIX */ + case TODC_TYPE_DS1747: + case TODC_TYPE_DS17285: + break; + default: + todc_write_val(todc_info->control_a, + (save_control | todc_info->enable_read)); + } + } else + limit = 100000000; + + for (i=0; i<limit; i++) { + if (todc_info->rtc_type == TODC_TYPE_MC146818) + uip = todc_read_val(todc_info->RTC_FREQ_SELECT); + + sec = todc_read_val(todc_info->seconds) & 0x7f; + min = todc_read_val(todc_info->minutes) & 0x7f; + hour = todc_read_val(todc_info->hours) & 0x3f; + mday = todc_read_val(todc_info->day_of_month) & 0x3f; + mon = todc_read_val(todc_info->month) & 0x1f; + year = todc_read_val(todc_info->year) & 0xff; + + if (todc_info->rtc_type == TODC_TYPE_MC146818) { + uip |= todc_read_val(todc_info->RTC_FREQ_SELECT); + if ((uip & RTC_UIP) == 0) + break; + } + } + + if (todc_info->rtc_type != TODC_TYPE_MC146818) { + switch (todc_info->rtc_type) { + case TODC_TYPE_DS1553: + case TODC_TYPE_DS1557: + case TODC_TYPE_DS1743: + case TODC_TYPE_DS1746: /* XXXX BAD HACK -> FIX */ + case TODC_TYPE_DS1747: + case TODC_TYPE_DS17285: + break; + default: + save_control &= ~(todc_info->enable_read); + todc_write_val(todc_info->control_a, save_control); + } + } + spin_unlock(&rtc_lock); + + if ((todc_info->rtc_type != TODC_TYPE_MC146818) + || ((save_control & RTC_DM_BINARY) == 0) + || RTC_ALWAYS_BCD) { + BCD_TO_BIN(sec); + BCD_TO_BIN(min); + BCD_TO_BIN(hour); + BCD_TO_BIN(mday); + BCD_TO_BIN(mon); + BCD_TO_BIN(year); + } + + if ((year + 1900) < 1970) { + year += 100; + } + + tm->tm_sec = sec; + tm->tm_min = min; + tm->tm_hour = hour; + tm->tm_mday = mday; + tm->tm_mon = mon; + tm->tm_year = year; + + GregorianDay(tm); +} + +int +todc_set_rtc_time(struct rtc_time *tm) +{ + u_char save_control, save_freq_select = 0; + + spin_lock(&rtc_lock); + save_control = todc_read_val(todc_info->control_a); + + /* Assuming MK48T59_RTC_CA_WRITE & RTC_SET are equal */ + todc_write_val(todc_info->control_a, + (save_control | todc_info->enable_write)); + save_control &= ~(todc_info->enable_write); /* in case it was set */ + + if (todc_info->rtc_type == TODC_TYPE_MC146818) { + save_freq_select = todc_read_val(todc_info->RTC_FREQ_SELECT); + todc_write_val(todc_info->RTC_FREQ_SELECT, + save_freq_select | RTC_DIV_RESET2); + } + + if ((todc_info->rtc_type != TODC_TYPE_MC146818) + || ((save_control & RTC_DM_BINARY) == 0) + || RTC_ALWAYS_BCD) { + BIN_TO_BCD(tm->tm_sec); + BIN_TO_BCD(tm->tm_min); + BIN_TO_BCD(tm->tm_hour); + BIN_TO_BCD(tm->tm_mon); + BIN_TO_BCD(tm->tm_mday); + BIN_TO_BCD(tm->tm_year); + } + + todc_write_val(todc_info->seconds, tm->tm_sec); + todc_write_val(todc_info->minutes, tm->tm_min); + todc_write_val(todc_info->hours, tm->tm_hour); + todc_write_val(todc_info->month, tm->tm_mon); + todc_write_val(todc_info->day_of_month, tm->tm_mday); + todc_write_val(todc_info->year, tm->tm_year); + + todc_write_val(todc_info->control_a, save_control); + + if (todc_info->rtc_type == TODC_TYPE_MC146818) + todc_write_val(todc_info->RTC_FREQ_SELECT, save_freq_select); + + spin_unlock(&rtc_lock); + return 0; +} diff --git a/arch/powerpc/sysdev/tsi108_dev.c b/arch/powerpc/sysdev/tsi108_dev.c new file mode 100644 index 000000000000..f3038461d4c0 --- /dev/null +++ b/arch/powerpc/sysdev/tsi108_dev.c @@ -0,0 +1,147 @@ +/* + * tsi108/109 device setup code + * + * Maintained by Roy Zang < tie-fei.zang@freescale.com > + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/config.h> +#include <linux/stddef.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/errno.h> +#include <linux/major.h> +#include <linux/delay.h> +#include <linux/irq.h> +#include <linux/module.h> +#include <linux/device.h> +#include <linux/platform_device.h> +#include <asm/tsi108.h> + +#include <asm/system.h> +#include <asm/atomic.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/prom.h> +#include <mm/mmu_decl.h> + +#undef DEBUG + +#ifdef DEBUG +#define DBG(fmt...) do { printk(fmt); } while(0) +#else +#define DBG(fmt...) do { } while(0) +#endif + +static phys_addr_t tsi108_csr_base = -1; + +phys_addr_t get_csrbase(void) +{ + struct device_node *tsi; + + if (tsi108_csr_base != -1) + return tsi108_csr_base; + + tsi = of_find_node_by_type(NULL, "tsi-bridge"); + if (tsi) { + unsigned int size; + void *prop = get_property(tsi, "reg", &size); + tsi108_csr_base = of_translate_address(tsi, prop); + of_node_put(tsi); + }; + return tsi108_csr_base; +} + +u32 get_vir_csrbase(void) +{ + return (u32) (ioremap(get_csrbase(), 0x10000)); +} + +EXPORT_SYMBOL(get_csrbase); +EXPORT_SYMBOL(get_vir_csrbase); + +static int __init tsi108_eth_of_init(void) +{ + struct device_node *np; + unsigned int i; + struct platform_device *tsi_eth_dev; + struct resource res; + int ret; + + for (np = NULL, i = 0; + (np = of_find_compatible_node(np, "network", "tsi-ethernet")) != NULL; + i++) { + struct resource r[2]; + struct device_node *phy; + hw_info tsi_eth_data; + unsigned int *id; + unsigned int *phy_id; + void *mac_addr; + phandle *ph; + + memset(r, 0, sizeof(r)); + memset(&tsi_eth_data, 0, sizeof(tsi_eth_data)); + + ret = of_address_to_resource(np, 0, &r[0]); + DBG("%s: name:start->end = %s:0x%lx-> 0x%lx\n", + __FUNCTION__,r[0].name, r[0].start, r[0].end); + if (ret) + goto err; + + r[1].name = "tx"; + r[1].start = irq_of_parse_and_map(np, 0); + r[1].end = irq_of_parse_and_map(np, 0); + r[1].flags = IORESOURCE_IRQ; + DBG("%s: name:start->end = %s:0x%lx-> 0x%lx\n", + __FUNCTION__,r[1].name, r[1].start, r[1].end); + + tsi_eth_dev = + platform_device_register_simple("tsi-ethernet", i, &r[0], + 1); + + if (IS_ERR(tsi_eth_dev)) { + ret = PTR_ERR(tsi_eth_dev); + goto err; + } + + mac_addr = get_property(np, "address", NULL); + memcpy(tsi_eth_data.mac_addr, mac_addr, 6); + + ph = (phandle *) get_property(np, "phy-handle", NULL); + phy = of_find_node_by_phandle(*ph); + + if (phy == NULL) { + ret = -ENODEV; + goto unreg; + } + + id = (u32 *) get_property(phy, "reg", NULL); + phy_id = (u32 *) get_property(phy, "phy-id", NULL); + ret = of_address_to_resource(phy, 0, &res); + if (ret) { + of_node_put(phy); + goto unreg; + } + tsi_eth_data.regs = r[0].start; + tsi_eth_data.phyregs = res.start; + tsi_eth_data.phy = *phy_id; + tsi_eth_data.irq_num = irq_of_parse_and_map(np, 0); + of_node_put(phy); + ret = + platform_device_add_data(tsi_eth_dev, &tsi_eth_data, + sizeof(hw_info)); + if (ret) + goto unreg; + } + return 0; +unreg: + platform_device_unregister(tsi_eth_dev); +err: + return ret; +} + +arch_initcall(tsi108_eth_of_init); diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c new file mode 100644 index 000000000000..c28f69bef8e2 --- /dev/null +++ b/arch/powerpc/sysdev/tsi108_pci.c @@ -0,0 +1,415 @@ +/* + * Common routines for Tundra Semiconductor TSI108 host bridge. + * + * 2004-2005 (c) Tundra Semiconductor Corp. + * Author: Alex Bounine (alexandreb@tundra.com) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/pci.h> +#include <linux/slab.h> +#include <linux/irq.h> +#include <linux/interrupt.h> + +#include <asm/byteorder.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/uaccess.h> +#include <asm/machdep.h> +#include <asm/pci-bridge.h> +#include <asm/tsi108.h> +#include <asm/tsi108_irq.h> +#include <asm/prom.h> + +#undef DEBUG +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + +#define tsi_mk_config_addr(bus, devfunc, offset) \ + ((((bus)<<16) | ((devfunc)<<8) | (offset & 0xfc)) + tsi108_pci_cfg_base) + +u32 tsi108_pci_cfg_base; +u32 tsi108_csr_vir_base; + +extern u32 get_vir_csrbase(void); +extern u32 tsi108_read_reg(u32 reg_offset); +extern void tsi108_write_reg(u32 reg_offset, u32 val); + +int +tsi108_direct_write_config(struct pci_bus *bus, unsigned int devfunc, + int offset, int len, u32 val) +{ + volatile unsigned char *cfg_addr; + + if (ppc_md.pci_exclude_device) + if (ppc_md.pci_exclude_device(bus->number, devfunc)) + return PCIBIOS_DEVICE_NOT_FOUND; + + cfg_addr = (unsigned char *)(tsi_mk_config_addr(bus->number, + devfunc, offset) | + (offset & 0x03)); + +#ifdef DEBUG + printk("PCI CFG write : "); + printk("%d:0x%x:0x%x ", bus->number, devfunc, offset); + printk("%d ADDR=0x%08x ", len, (uint) cfg_addr); + printk("data = 0x%08x\n", val); +#endif + + switch (len) { + case 1: + out_8((u8 *) cfg_addr, val); + break; + case 2: + out_le16((u16 *) cfg_addr, val); + break; + default: + out_le32((u32 *) cfg_addr, val); + break; + } + + return PCIBIOS_SUCCESSFUL; +} + +void tsi108_clear_pci_error(u32 pci_cfg_base) +{ + u32 err_stat, err_addr, pci_stat; + + /* + * Quietly clear PB and PCI error flags set as result + * of PCI/X configuration read requests. + */ + + /* Read PB Error Log Registers */ + + err_stat = tsi108_read_reg(TSI108_PB_OFFSET + TSI108_PB_ERRCS); + err_addr = tsi108_read_reg(TSI108_PB_OFFSET + TSI108_PB_AERR); + + if (err_stat & TSI108_PB_ERRCS_ES) { + /* Clear error flag */ + tsi108_write_reg(TSI108_PB_OFFSET + TSI108_PB_ERRCS, + TSI108_PB_ERRCS_ES); + + /* Clear read error reported in PB_ISR */ + tsi108_write_reg(TSI108_PB_OFFSET + TSI108_PB_ISR, + TSI108_PB_ISR_PBS_RD_ERR); + + /* Clear PCI/X bus cfg errors if applicable */ + if ((err_addr & 0xFF000000) == pci_cfg_base) { + pci_stat = + tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_CSR); + tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_CSR, + pci_stat); + } + } + + return; +} + +#define __tsi108_read_pci_config(x, addr, op) \ + __asm__ __volatile__( \ + " "op" %0,0,%1\n" \ + "1: eieio\n" \ + "2:\n" \ + ".section .fixup,\"ax\"\n" \ + "3: li %0,-1\n" \ + " b 2b\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 2\n" \ + " .long 1b,3b\n" \ + ".text" \ + : "=r"(x) : "r"(addr)) + +int +tsi108_direct_read_config(struct pci_bus *bus, unsigned int devfn, int offset, + int len, u32 * val) +{ + volatile unsigned char *cfg_addr; + u32 temp; + + if (ppc_md.pci_exclude_device) + if (ppc_md.pci_exclude_device(bus->number, devfn)) + return PCIBIOS_DEVICE_NOT_FOUND; + + cfg_addr = (unsigned char *)(tsi_mk_config_addr(bus->number, + devfn, + offset) | (offset & + 0x03)); + + switch (len) { + case 1: + __tsi108_read_pci_config(temp, cfg_addr, "lbzx"); + break; + case 2: + __tsi108_read_pci_config(temp, cfg_addr, "lhbrx"); + break; + default: + __tsi108_read_pci_config(temp, cfg_addr, "lwbrx"); + break; + } + + *val = temp; + +#ifdef DEBUG + if ((0xFFFFFFFF != temp) && (0xFFFF != temp) && (0xFF != temp)) { + printk("PCI CFG read : "); + printk("%d:0x%x:0x%x ", bus->number, devfn, offset); + printk("%d ADDR=0x%08x ", len, (uint) cfg_addr); + printk("data = 0x%x\n", *val); + } +#endif + return PCIBIOS_SUCCESSFUL; +} + +void tsi108_clear_pci_cfg_error(void) +{ + tsi108_clear_pci_error(TSI108_PCI_CFG_BASE_PHYS); +} + +static struct pci_ops tsi108_direct_pci_ops = { + tsi108_direct_read_config, + tsi108_direct_write_config +}; + +int __init tsi108_setup_pci(struct device_node *dev) +{ + int len; + struct pci_controller *hose; + struct resource rsrc; + const int *bus_range; + int primary = 0, has_address = 0; + + /* PCI Config mapping */ + tsi108_pci_cfg_base = (u32)ioremap(TSI108_PCI_CFG_BASE_PHYS, + TSI108_PCI_CFG_SIZE); + DBG("TSI_PCI: %s tsi108_pci_cfg_base=0x%x\n", __FUNCTION__, + tsi108_pci_cfg_base); + + /* Fetch host bridge registers address */ + has_address = (of_address_to_resource(dev, 0, &rsrc) == 0); + + /* Get bus range if any */ + bus_range = get_property(dev, "bus-range", &len); + if (bus_range == NULL || len < 2 * sizeof(int)) { + printk(KERN_WARNING "Can't get bus-range for %s, assume" + " bus 0\n", dev->full_name); + } + + hose = pcibios_alloc_controller(); + + if (!hose) { + printk("PCI Host bridge init failed\n"); + return -ENOMEM; + } + hose->arch_data = dev; + hose->set_cfg_type = 1; + + hose->first_busno = bus_range ? bus_range[0] : 0; + hose->last_busno = bus_range ? bus_range[1] : 0xff; + + (hose)->ops = &tsi108_direct_pci_ops; + + printk(KERN_INFO "Found tsi108 PCI host bridge at 0x%08x. " + "Firmware bus number: %d->%d\n", + rsrc.start, hose->first_busno, hose->last_busno); + + /* Interpret the "ranges" property */ + /* This also maps the I/O region and sets isa_io/mem_base */ + pci_process_bridge_OF_ranges(hose, dev, primary); + return 0; +} + +/* + * Low level utility functions + */ + +static void tsi108_pci_int_mask(u_int irq) +{ + u_int irp_cfg; + int int_line = (irq - IRQ_PCI_INTAD_BASE); + + irp_cfg = tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL); + mb(); + irp_cfg |= (1 << int_line); /* INTx_DIR = output */ + irp_cfg &= ~(3 << (8 + (int_line * 2))); /* INTx_TYPE = unused */ + tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL, irp_cfg); + mb(); + irp_cfg = tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL); +} + +static void tsi108_pci_int_unmask(u_int irq) +{ + u_int irp_cfg; + int int_line = (irq - IRQ_PCI_INTAD_BASE); + + irp_cfg = tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL); + mb(); + irp_cfg &= ~(1 << int_line); + irp_cfg |= (3 << (8 + (int_line * 2))); + tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL, irp_cfg); + mb(); +} + +static void init_pci_source(void) +{ + tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL, + 0x0000ff00); + tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE, + TSI108_PCI_IRP_ENABLE_P_INT); + mb(); +} + +static inline unsigned int get_pci_source(void) +{ + u_int temp = 0; + int irq = -1; + int i; + u_int pci_irp_stat; + static int mask = 0; + + /* Read PCI/X block interrupt status register */ + pci_irp_stat = tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_STAT); + mb(); + + if (pci_irp_stat & TSI108_PCI_IRP_STAT_P_INT) { + /* Process Interrupt from PCI bus INTA# - INTD# lines */ + temp = + tsi108_read_reg(TSI108_PCI_OFFSET + + TSI108_PCI_IRP_INTAD) & 0xf; + mb(); + for (i = 0; i < 4; i++, mask++) { + if (temp & (1 << mask % 4)) { + irq = IRQ_PCI_INTA + mask % 4; + mask++; + break; + } + } + + /* Disable interrupts from PCI block */ + temp = tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE); + tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE, + temp & ~TSI108_PCI_IRP_ENABLE_P_INT); + mb(); + (void)tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE); + mb(); + } +#ifdef DEBUG + else { + printk("TSI108_PIC: error in TSI108_PCI_IRP_STAT\n"); + pci_irp_stat = + tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_STAT); + temp = + tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_INTAD); + mb(); + printk(">> stat=0x%08x intad=0x%08x ", pci_irp_stat, temp); + temp = + tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL); + mb(); + printk("cfg_ctl=0x%08x ", temp); + temp = + tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE); + mb(); + printk("irp_enable=0x%08x\n", temp); + } +#endif /* end of DEBUG */ + + return irq; +} + + +/* + * Linux descriptor level callbacks + */ + +static void tsi108_pci_irq_enable(u_int irq) +{ + tsi108_pci_int_unmask(irq); +} + +static void tsi108_pci_irq_disable(u_int irq) +{ + tsi108_pci_int_mask(irq); +} + +static void tsi108_pci_irq_ack(u_int irq) +{ + tsi108_pci_int_mask(irq); +} + +static void tsi108_pci_irq_end(u_int irq) +{ + tsi108_pci_int_unmask(irq); + + /* Enable interrupts from PCI block */ + tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE, + tsi108_read_reg(TSI108_PCI_OFFSET + + TSI108_PCI_IRP_ENABLE) | + TSI108_PCI_IRP_ENABLE_P_INT); + mb(); +} + +/* + * Interrupt controller descriptor for cascaded PCI interrupt controller. + */ + +static struct irq_chip tsi108_pci_irq = { + .typename = "tsi108_PCI_int", + .mask = tsi108_pci_irq_disable, + .ack = tsi108_pci_irq_ack, + .end = tsi108_pci_irq_end, + .unmask = tsi108_pci_irq_enable, +}; + +/* + * Exported functions + */ + +/* + * The Tsi108 PCI interrupts initialization routine. + * + * The INTA# - INTD# interrupts on the PCI bus are reported by the PCI block + * to the MPIC using single interrupt source (IRQ_TSI108_PCI). Therefore the + * PCI block has to be treated as a cascaded interrupt controller connected + * to the MPIC. + */ + +void __init tsi108_pci_int_init(void) +{ + u_int i; + + DBG("Tsi108_pci_int_init: initializing PCI interrupts\n"); + + for (i = 0; i < NUM_PCI_IRQS; i++) { + irq_desc[i + IRQ_PCI_INTAD_BASE].chip = &tsi108_pci_irq; + irq_desc[i + IRQ_PCI_INTAD_BASE].status |= IRQ_LEVEL; + } + + init_pci_source(); +} + +void tsi108_irq_cascade(unsigned int irq, struct irq_desc *desc, + struct pt_regs *regs) +{ + unsigned int cascade_irq = get_pci_source(); + if (cascade_irq != NO_IRQ) + generic_handle_irq(cascade_irq, regs); + desc->chip->eoi(irq); +} diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 4735b41c113c..8adad1444a51 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -8,7 +8,6 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <linux/errno.h> #include <linux/sched.h> #include <linux/smp.h> @@ -26,9 +25,6 @@ #include <asm/prom.h> #include <asm/machdep.h> #include <asm/xmon.h> -#ifdef CONFIG_PMAC_BACKLIGHT -#include <asm/backlight.h> -#endif #include <asm/processor.h> #include <asm/pgtable.h> #include <asm/mmu.h> @@ -141,10 +137,14 @@ static void bootcmds(void); static void proccall(void); void dump_segments(void); static void symbol_lookup(void); +static void xmon_show_stack(unsigned long sp, unsigned long lr, + unsigned long pc); static void xmon_print_symbol(unsigned long address, const char *mid, const char *after); static const char *getvecname(unsigned long vec); +int xmon_no_auto_backtrace; + extern int print_insn_powerpc(unsigned long, unsigned long, int); extern void xmon_enter(void); @@ -740,6 +740,12 @@ cmds(struct pt_regs *excp) last_cmd = NULL; xmon_regs = excp; + + if (!xmon_no_auto_backtrace) { + xmon_no_auto_backtrace = 1; + xmon_show_stack(excp->gpr[1], excp->link, excp->nip); + } + for(;;) { #ifdef CONFIG_SMP printf("%x:", smp_processor_id()); |