summaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/Kconfig21
-rw-r--r--arch/powerpc/Kconfig.debug16
-rw-r--r--arch/powerpc/boot/Makefile7
-rw-r--r--arch/powerpc/boot/dts/mpc8349emds.dts16
-rw-r--r--arch/powerpc/boot/flatdevtree.h46
-rw-r--r--arch/powerpc/boot/main.c250
-rw-r--r--arch/powerpc/boot/of.c (renamed from arch/powerpc/boot/prom.c)144
-rw-r--r--arch/powerpc/boot/ops.h100
-rw-r--r--arch/powerpc/boot/prom.h41
-rw-r--r--arch/powerpc/boot/stdio.c4
-rw-r--r--arch/powerpc/boot/stdio.h8
-rw-r--r--arch/powerpc/boot/types.h23
-rw-r--r--arch/powerpc/configs/maple_defconfig2
-rw-r--r--arch/powerpc/kernel/Makefile4
-rw-r--r--arch/powerpc/kernel/asm-offsets.c17
-rw-r--r--arch/powerpc/kernel/btext.c24
-rw-r--r--arch/powerpc/kernel/cpu_setup_ppc970.S (renamed from arch/powerpc/kernel/cpu_setup_power4.S)103
-rw-r--r--arch/powerpc/kernel/cputable.c21
-rw-r--r--arch/powerpc/kernel/crash_dump.c2
-rw-r--r--arch/powerpc/kernel/dma_64.c65
-rw-r--r--arch/powerpc/kernel/entry_64.S8
-rw-r--r--arch/powerpc/kernel/head_64.S54
-rw-r--r--arch/powerpc/kernel/ibmebus.c6
-rw-r--r--arch/powerpc/kernel/io.c131
-rw-r--r--arch/powerpc/kernel/irq.c5
-rw-r--r--arch/powerpc/kernel/legacy_serial.c35
-rw-r--r--arch/powerpc/kernel/lparcfg.c30
-rw-r--r--arch/powerpc/kernel/machine_kexec_64.c10
-rw-r--r--arch/powerpc/kernel/misc.S159
-rw-r--r--arch/powerpc/kernel/of_device.c24
-rw-r--r--arch/powerpc/kernel/paca.c15
-rw-r--r--arch/powerpc/kernel/pci_32.c39
-rw-r--r--arch/powerpc/kernel/pci_64.c67
-rw-r--r--arch/powerpc/kernel/pci_dn.c13
-rw-r--r--arch/powerpc/kernel/ppc_ksyms.c19
-rw-r--r--arch/powerpc/kernel/prom.c44
-rw-r--r--arch/powerpc/kernel/prom_init.c10
-rw-r--r--arch/powerpc/kernel/prom_parse.c90
-rw-r--r--arch/powerpc/kernel/rtas-proc.c25
-rw-r--r--arch/powerpc/kernel/rtas.c47
-rw-r--r--arch/powerpc/kernel/rtas_pci.c28
-rw-r--r--arch/powerpc/kernel/setup-common.c32
-rw-r--r--arch/powerpc/kernel/setup_32.c4
-rw-r--r--arch/powerpc/kernel/setup_64.c28
-rw-r--r--arch/powerpc/kernel/swsusp_32.S4
-rw-r--r--arch/powerpc/kernel/sys_ppc32.c2
-rw-r--r--arch/powerpc/kernel/sysfs.c9
-rw-r--r--arch/powerpc/kernel/time.c17
-rw-r--r--arch/powerpc/kernel/traps.c25
-rw-r--r--arch/powerpc/kernel/vio.c16
-rw-r--r--arch/powerpc/lib/Makefile1
-rw-r--r--arch/powerpc/lib/e2a.c116
-rw-r--r--arch/powerpc/lib/locks.c27
-rw-r--r--arch/powerpc/mm/fault.c4
-rw-r--r--arch/powerpc/mm/mem.c51
-rw-r--r--arch/powerpc/mm/numa.c190
-rw-r--r--arch/powerpc/mm/slb.c37
-rw-r--r--arch/powerpc/mm/tlb_64.c1
-rw-r--r--arch/powerpc/platforms/83xx/mpc834x_itx.c4
-rw-r--r--arch/powerpc/platforms/83xx/mpc834x_sys.c4
-rw-r--r--arch/powerpc/platforms/83xx/pci.c4
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_ads.c4
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_cds.c4
-rw-r--r--arch/powerpc/platforms/85xx/pci.c4
-rw-r--r--arch/powerpc/platforms/86xx/mpc86xx_hpcn.c4
-rw-r--r--arch/powerpc/platforms/86xx/pci.c4
-rw-r--r--arch/powerpc/platforms/Makefile1
-rw-r--r--arch/powerpc/platforms/cell/cbe_regs.c8
-rw-r--r--arch/powerpc/platforms/cell/interrupt.c25
-rw-r--r--arch/powerpc/platforms/cell/iommu.c22
-rw-r--r--arch/powerpc/platforms/cell/setup.c4
-rw-r--r--arch/powerpc/platforms/cell/smp.c4
-rw-r--r--arch/powerpc/platforms/cell/spider-pic.c10
-rw-r--r--arch/powerpc/platforms/cell/spu_base.c18
-rw-r--r--arch/powerpc/platforms/cell/spufs/inode.c3
-rw-r--r--arch/powerpc/platforms/chrp/nvram.c5
-rw-r--r--arch/powerpc/platforms/chrp/pci.c53
-rw-r--r--arch/powerpc/platforms/chrp/setup.c48
-rw-r--r--arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c8
-rw-r--r--arch/powerpc/platforms/iseries/Kconfig8
-rw-r--r--arch/powerpc/platforms/iseries/dt.c45
-rw-r--r--arch/powerpc/platforms/iseries/hvlpconfig.c13
-rw-r--r--arch/powerpc/platforms/iseries/iommu.c19
-rw-r--r--arch/powerpc/platforms/iseries/it_exp_vpd_panel.h51
-rw-r--r--arch/powerpc/platforms/iseries/it_lp_naca.h80
-rw-r--r--arch/powerpc/platforms/iseries/lpardata.c6
-rw-r--r--arch/powerpc/platforms/iseries/lpevents.c2
-rw-r--r--arch/powerpc/platforms/iseries/main_store.h126
-rw-r--r--arch/powerpc/platforms/iseries/pci.c289
-rw-r--r--arch/powerpc/platforms/iseries/setup.c1
-rw-r--r--arch/powerpc/platforms/iseries/viopath.c28
-rw-r--r--arch/powerpc/platforms/iseries/vpdinfo.c22
-rw-r--r--arch/powerpc/platforms/maple/pci.c70
-rw-r--r--arch/powerpc/platforms/maple/setup.c27
-rw-r--r--arch/powerpc/platforms/pasemi/Makefile1
-rw-r--r--arch/powerpc/platforms/pasemi/pasemi.h8
-rw-r--r--arch/powerpc/platforms/pasemi/pci.c198
-rw-r--r--arch/powerpc/platforms/pasemi/setup.c188
-rw-r--r--arch/powerpc/platforms/pasemi/time.c29
-rw-r--r--arch/powerpc/platforms/powermac/backlight.c3
-rw-r--r--arch/powerpc/platforms/powermac/cpufreq_32.c23
-rw-r--r--arch/powerpc/platforms/powermac/cpufreq_64.c29
-rw-r--r--arch/powerpc/platforms/powermac/feature.c30
-rw-r--r--arch/powerpc/platforms/powermac/low_i2c.c24
-rw-r--r--arch/powerpc/platforms/powermac/nvram.c4
-rw-r--r--arch/powerpc/platforms/powermac/pci.c37
-rw-r--r--arch/powerpc/platforms/powermac/pfunc_base.c2
-rw-r--r--arch/powerpc/platforms/powermac/pfunc_core.c5
-rw-r--r--arch/powerpc/platforms/powermac/setup.c18
-rw-r--r--arch/powerpc/platforms/powermac/smp.c9
-rw-r--r--arch/powerpc/platforms/powermac/udbg_scc.c10
-rw-r--r--arch/powerpc/platforms/pseries/Makefile1
-rw-r--r--arch/powerpc/platforms/pseries/eeh.c96
-rw-r--r--arch/powerpc/platforms/pseries/eeh_cache.c17
-rw-r--r--arch/powerpc/platforms/pseries/eeh_driver.c112
-rw-r--r--arch/powerpc/platforms/pseries/eeh_event.c4
-rw-r--r--arch/powerpc/platforms/pseries/firmware.c2
-rw-r--r--arch/powerpc/platforms/pseries/hvCall.S273
-rw-r--r--arch/powerpc/platforms/pseries/hvCall_inst.c129
-rw-r--r--arch/powerpc/platforms/pseries/hvconsole.c5
-rw-r--r--arch/powerpc/platforms/pseries/iommu.c13
-rw-r--r--arch/powerpc/platforms/pseries/lpar.c46
-rw-r--r--arch/powerpc/platforms/pseries/nvram.c5
-rw-r--r--arch/powerpc/platforms/pseries/pci.c2
-rw-r--r--arch/powerpc/platforms/pseries/plpar_wrappers.h107
-rw-r--r--arch/powerpc/platforms/pseries/ras.c6
-rw-r--r--arch/powerpc/platforms/pseries/rtasd.c4
-rw-r--r--arch/powerpc/platforms/pseries/setup.c48
-rw-r--r--arch/powerpc/platforms/pseries/smp.c12
-rw-r--r--arch/powerpc/platforms/pseries/xics.c44
-rw-r--r--arch/powerpc/sysdev/fsl_soc.c28
-rw-r--r--arch/powerpc/sysdev/fsl_soc.h2
-rw-r--r--arch/powerpc/sysdev/i8259.c2
-rw-r--r--arch/powerpc/sysdev/ipic.c42
-rw-r--r--arch/powerpc/sysdev/mmio_nvram.c4
-rw-r--r--arch/powerpc/sysdev/mpic.c2
-rw-r--r--arch/powerpc/sysdev/tsi108_pci.c4
-rw-r--r--arch/powerpc/xmon/xmon.c10
138 files changed, 3070 insertions, 1933 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 694b0c63ee5..a0dd1b0ee48 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -417,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
@@ -436,7 +447,8 @@ config PPC_IBM_CELL_BLADE
select UDBG_RTAS_CONSOLE
config UDBG_RTAS_CONSOLE
- bool
+ bool "RTAS based debug console"
+ depends on PPC_RTAS
default n
config XICS
@@ -719,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
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index e29ef77d3b0..5ad149b47e3 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"
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index d961bfeed05..e73774136b5 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/mpc8349emds.dts b/arch/powerpc/boot/dts/mpc8349emds.dts
index 12f5dbf3055..efceb343265 100644
--- a/arch/powerpc/boot/dts/mpc8349emds.dts
+++ b/arch/powerpc/boot/dts/mpc8349emds.dts
@@ -214,10 +214,10 @@
b800 0 0 4 700 15 8
/* IDSEL 0x18 */
- b000 0 0 1 700 15 8
- b000 0 0 2 700 16 8
- b000 0 0 3 700 17 8
- b000 0 0 4 700 14 8>;
+ 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>;
@@ -274,10 +274,10 @@
b800 0 0 4 700 15 8
/* IDSEL 0x18 */
- b000 0 0 1 700 15 8
- b000 0 0 2 700 16 8
- b000 0 0 3 700 17 8
- b000 0 0 4 700 14 8>;
+ 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>;
diff --git a/arch/powerpc/boot/flatdevtree.h b/arch/powerpc/boot/flatdevtree.h
new file mode 100644
index 00000000000..761c8dc8400
--- /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 b66634c9ea3..d719bb9333d 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 fa0057736f6..fd99f789a37 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 00000000000..135eb4bb03b
--- /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 a57b184c564..00000000000
--- 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 b5aa522f8b7..6d5f6382e1c 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 eb9e16c87ae..73b8a91bfb3 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 00000000000..79d26e70867
--- /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/maple_defconfig b/arch/powerpc/configs/maple_defconfig
index 2860be106f4..62ba66091a1 100644
--- a/arch/powerpc/configs/maple_defconfig
+++ b/arch/powerpc/configs/maple_defconfig
@@ -496,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
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 7d32ad0194a..8b133afbdc2 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
@@ -51,7 +51,7 @@ extra-$(CONFIG_8xx) := head_8xx.o
extra-y += vmlinux.lds
obj-y += time.o prom.o traps.o setup-common.o \
- udbg.o misc.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
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 7ee84968087..d06f378597b 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -40,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) \
@@ -136,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 */
@@ -159,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]));
@@ -240,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/btext.c b/arch/powerpc/kernel/btext.c
index f4e5e14ee2b..995fcef156f 100644
--- a/arch/powerpc/kernel/btext.c
+++ b/arch/powerpc/kernel/btext.c
@@ -158,35 +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, "linux,bootx-width", NULL);
+ prop = get_property(np, "linux,bootx-width", NULL);
if (prop == NULL)
- prop = (u32 *)get_property(np, "width", NULL);
+ prop = get_property(np, "width", NULL);
if (prop == NULL)
return -EINVAL;
width = *prop;
- prop = (u32 *)get_property(np, "linux,bootx-height", NULL);
+ prop = get_property(np, "linux,bootx-height", NULL);
if (prop == NULL)
- prop = (u32 *)get_property(np, "height", NULL);
+ prop = get_property(np, "height", NULL);
if (prop == NULL)
return -EINVAL;
height = *prop;
- prop = (u32 *)get_property(np, "linux,bootx-depth", NULL);
+ prop = get_property(np, "linux,bootx-depth", NULL);
if (prop == NULL)
- prop = (u32 *)get_property(np, "depth", NULL);
+ prop = get_property(np, "depth", NULL);
if (prop == NULL)
return -EINVAL;
depth = *prop;
pitch = width * ((depth + 7) / 8);
- prop = (u32 *)get_property(np, "linux,bootx-linebytes", NULL);
+ prop = get_property(np, "linux,bootx-linebytes", NULL);
if (prop == NULL)
- prop = (u32 *)get_property(np, "linebytes", 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;
@@ -214,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/cpu_setup_power4.S b/arch/powerpc/kernel/cpu_setup_ppc970.S
index 76e97aa71c4..652594891d5 100644
--- a/arch/powerpc/kernel/cpu_setup_power4.S
+++ b/arch/powerpc/kernel/cpu_setup_ppc970.S
@@ -16,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
@@ -72,23 +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 */
- 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
- blr
-
/* Definitions for the table use to save CPU states */
#define CS_HID0 0
#define CS_HID1 8
@@ -103,33 +71,30 @@ 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 */
- 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: /* skip if not running in HV mode */
+_GLOBAL(__setup_cpu_ppc970)
+ /* Do nothing if not running in HV mode */
mfmsr r0
rldicl. r0,r0,4,63
- beq 2f
+ 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)
/* Save HID0,1,4 and 5 */
mfspr r3,SPRN_HID0
@@ -141,35 +106,19 @@ _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)
-
- /* 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: /* skip if not running in HV mode */
+_GLOBAL(__restore_cpu_ppc970)
+ /* Do nothing if not running in HV mode */
mfmsr r0
rldicl. r0,r0,4,63
beqlr
+ LOAD_REG_IMMEDIATE(r5,cpu_state_storage)
/* Before accessing memory, we make sure rm_ci is clear */
li r0,0
mfspr r3,SPRN_HID4
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 272e43622fd..190a57e2076 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -39,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...
@@ -55,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)
@@ -184,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",
@@ -199,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",
@@ -214,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",
@@ -280,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,
@@ -929,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_dump.c b/arch/powerpc/kernel/crash_dump.c
index 371973be8d7..2f6f5a7bc69 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 36aaa7663f0..6c168f6ea14 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_64.S b/arch/powerpc/kernel/entry_64.S
index 54d9f5cdaab..2cd872b5283 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -375,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/head_64.S b/arch/powerpc/kernel/head_64.S
index 6ff3cf50608..3065b472b95 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -132,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
@@ -1484,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.
@@ -1522,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)
@@ -1611,7 +1622,16 @@ _GLOBAL(__start_initialization_multiplatform)
bl .enable_64b_mode
/* Setup some critical 970 SPRs before switching MMU off */
- bl .__970_cpu_preinit
+ 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)
@@ -1728,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 */
@@ -1782,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
@@ -1932,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. */
diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c
index 68e5ab0443d..124dbcba94a 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>");
diff --git a/arch/powerpc/kernel/io.c b/arch/powerpc/kernel/io.c
new file mode 100644
index 00000000000..e98180686b3
--- /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/irq.c b/arch/powerpc/kernel/irq.c
index 12c5971d656..b4432332341 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -52,6 +52,7 @@
#include <linux/radix-tree.h>
#include <linux/mutex.h>
#include <linux/bootmem.h>
+#include <linux/pci.h>
#include <asm/uaccess.h>
#include <asm/system.h>
@@ -875,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;}
@@ -888,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/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c
index 40a39291861..5e6ddfa474c 100644
--- a/arch/powerpc/kernel/legacy_serial.c
+++ b/arch/powerpc/kernel/legacy_serial.c
@@ -39,16 +39,17 @@ static int __init add_legacy_port(struct device_node *np, int want_index,
phys_addr_t taddr, unsigned long irq,
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)
@@ -113,7 +114,7 @@ static int __init add_legacy_soc_port(struct device_node *np,
struct device_node *soc_dev)
{
u64 addr;
- u32 *addrp;
+ const u32 *addrp;
upf_t flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ;
struct device_node *tsi = of_get_parent(np);
@@ -144,15 +145,15 @@ static int __init add_legacy_soc_port(struct device_node *np,
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;
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;
@@ -163,7 +164,7 @@ 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')
@@ -188,7 +189,7 @@ static int __init add_legacy_pci_port(struct device_node *np,
struct device_node *pci_dev)
{
u64 addr, base;
- u32 *addrp;
+ const u32 *addrp;
unsigned int flags;
int iotype, index = -1, lindex = 0;
@@ -227,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;
}
@@ -285,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)
@@ -491,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");
@@ -513,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;
@@ -525,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 23f34daa044..41c05dcd68f 100644
--- a/arch/powerpc/kernel/lparcfg.c
+++ b/arch/powerpc/kernel/lparcfg.c
@@ -32,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>
@@ -183,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");
@@ -194,8 +199,12 @@ 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];
+
+ rc = plpar_hcall(H_PIC, retbuf);
+
+ *pool_idle_time = retbuf[0];
+ *num_procs = retbuf[1];
if (rc != H_AUTHORITY)
log_plpar_hcall_return(rc, "H_PIC");
@@ -310,12 +319,11 @@ static int pseries_lparcfg_data(struct seq_file *m, void *v)
int partition_potential_processors;
int partition_active_processors;
struct device_node *rtas_node;
- int *lrdrp = NULL;
+ 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;
@@ -520,7 +528,8 @@ static int lparcfg_data(struct seq_file *m, void *v)
const char *model = "";
const char *system_id = "";
const char *tmp;
- unsigned int *lp_index_ptr, lp_index = 0;
+ const unsigned int *lp_index_ptr;
+ unsigned int lp_index = 0;
seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS);
@@ -540,8 +549,7 @@ static int lparcfg_data(struct seq_file *m, void *v)
if (firmware_has_feature(FW_FEATURE_ISERIES))
system_id += 4;
}
- lp_index_ptr = (unsigned int *)
- get_property(rootdn, "ibm,partition-no", NULL);
+ lp_index_ptr = get_property(rootdn, "ibm,partition-no", NULL);
if (lp_index_ptr)
lp_index = *lp_index_ptr;
}
diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c
index be58985c768..a24b09c2771 100644
--- a/arch/powerpc/kernel/machine_kexec_64.c
+++ b/arch/powerpc/kernel/machine_kexec_64.c
@@ -31,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;
@@ -72,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;
diff --git a/arch/powerpc/kernel/misc.S b/arch/powerpc/kernel/misc.S
index f770805f121..330c9dc7db8 100644
--- a/arch/powerpc/kernel/misc.S
+++ b/arch/powerpc/kernel/misc.S
@@ -43,162 +43,3 @@ _GLOBAL(add_reloc_offset)
add r3,r3,r5
mtlr r0
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)
- sync
- 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-
- sync
-00: lbzu r5,1(r4)
- stb r5,0(r3)
- bdnz 00b
- sync
- blr
-
-_GLOBAL(_insw)
- sync
- 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-
- sync
-00: lhzu r5,2(r4)
- sthbrx r5,0,r3
- bdnz 00b
- sync
- blr
-
-_GLOBAL(_insl)
- sync
- 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-
- sync
-00: lwzu r5,4(r4)
- stwbrx r5,0,r3
- bdnz 00b
- sync
- blr
-
-#ifdef CONFIG_PPC32
-_GLOBAL(__ide_mm_insw)
-#endif
-_GLOBAL(_insw_ns)
- sync
- 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
-
-#ifdef CONFIG_PPC32
-_GLOBAL(__ide_mm_outsw)
-#endif
-_GLOBAL(_outsw_ns)
- cmpwi 0,r5,0
- mtctr r5
- subi r4,r4,2
- blelr-
- sync
-00: lhzu r5,2(r4)
- sth r5,0(r3)
- bdnz 00b
- sync
- blr
-
-#ifdef CONFIG_PPC32
-_GLOBAL(__ide_mm_insl)
-#endif
-_GLOBAL(_insl_ns)
- sync
- 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
-
-#ifdef CONFIG_PPC32
-_GLOBAL(__ide_mm_outsl)
-#endif
-_GLOBAL(_outsl_ns)
- cmpwi 0,r5,0
- mtctr r5
- subi r4,r4,4
- blelr-
- sync
-00: lwzu r5,4(r4)
- stw r5,0(r3)
- bdnz 00b
- sync
- blr
-
diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c
index 3262b73a3a6..397c83eda20 100644
--- a/arch/powerpc/kernel/of_device.c
+++ b/arch/powerpc/kernel/of_device.c
@@ -189,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;
@@ -221,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 c68741fed14..55f1a25085c 100644
--- a/arch/powerpc/kernel/paca.c
+++ b/arch/powerpc/kernel/paca.c
@@ -17,6 +17,7 @@
#include <asm/lppaca.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
@@ -45,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.
@@ -59,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 09b1e1bbb29..9b49f8691d2 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -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 */
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 138134c8c17..c1b1e14775e 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -185,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;
@@ -226,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);
}
@@ -283,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;
@@ -315,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);
@@ -418,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;
@@ -426,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", &reglen);
+ reg = get_property(child, "reg", &reglen);
if (reg == NULL || reglen < 20)
continue;
devfn = (reg[0] >> 8) & 0xff;
@@ -450,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;
@@ -459,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);
@@ -929,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");
@@ -976,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;
@@ -994,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;
diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c
index 1c18953514c..68df018dae0 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/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
index 39d3bfcabcd..807193a3c78 100644
--- a/arch/powerpc/kernel/ppc_ksyms.c
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -91,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
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index a1787ffb631..eb913f80bfb 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -757,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);
}
@@ -942,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);
@@ -958,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);
@@ -1034,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) {
@@ -1449,7 +1434,7 @@ 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);
@@ -1466,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:
@@ -1528,7 +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.
*/
-void *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;
@@ -1658,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) {
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index 4394e545f9f..b91761639d9 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -2033,16 +2033,22 @@ static void __init fixup_device_tree_maple(void)
#endif
#ifdef CONFIG_PPC_CHRP
-/* Pegasos lacks the "ranges" property in the isa node */
+/* 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;
@@ -2054,7 +2060,7 @@ static void __init fixup_device_tree_chrp(void)
isa_ranges[0] = 0x1;
isa_ranges[1] = 0x0;
- isa_ranges[2] = 0x01006000;
+ isa_ranges[2] = rloc;
isa_ranges[3] = 0x0;
isa_ranges[4] = 0x0;
isa_ranges[5] = 0x00010000;
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
index a10825a5dfe..603dff3ad62 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,7 +35,7 @@ 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
@@ -46,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);
};
@@ -65,7 +66,8 @@ 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;
@@ -93,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;
}
@@ -118,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;
@@ -143,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];
@@ -178,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;
@@ -203,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];
@@ -268,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;
@@ -285,7 +287,7 @@ 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_number(addr, na);
memset(addr, 0, pna * 4);
@@ -328,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;
@@ -405,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;
@@ -425,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;
@@ -443,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;
@@ -467,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;
@@ -485,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)
{
@@ -516,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;
@@ -530,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;
@@ -541,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++);
@@ -576,13 +579,13 @@ static struct device_node *of_irq_dflt_pic;
static struct device_node *of_irq_find_parent(struct device_node *child)
{
struct device_node *p;
- phandle *parp;
+ const phandle *parp;
if (!of_node_get(child))
return NULL;
do {
- parp = (phandle *)get_property(child, "interrupt-parent", NULL);
+ parp = get_property(child, "interrupt-parent", NULL);
if (parp == NULL)
p = of_get_parent(child);
else {
@@ -639,11 +642,11 @@ void of_irq_map_init(unsigned int flags)
}
-int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 ointsize,
- u32 *addr, struct of_irq *out_irq)
+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;
- u32 *tmp, *imap, *imask;
+ const u32 *tmp, *imap, *imask;
u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
int imaplen, match, i;
@@ -657,7 +660,7 @@ int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 ointsize,
* is none, we are nice and just walk up the tree
*/
do {
- tmp = (u32 *)get_property(ipar, "#interrupt-cells", NULL);
+ tmp = get_property(ipar, "#interrupt-cells", NULL);
if (tmp != NULL) {
intsize = *tmp;
break;
@@ -681,7 +684,7 @@ int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 ointsize,
*/
old = of_node_get(ipar);
do {
- tmp = (u32 *)get_property(old, "#address-cells", NULL);
+ tmp = get_property(old, "#address-cells", NULL);
tnode = of_get_parent(old);
of_node_put(old);
old = tnode;
@@ -708,7 +711,7 @@ int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 ointsize,
}
/* Now look for an interrupt-map */
- imap = (u32 *)get_property(ipar, "interrupt-map", &imaplen);
+ imap = get_property(ipar, "interrupt-map", &imaplen);
/* No interrupt map, check for an interrupt parent */
if (imap == NULL) {
DBG(" -> no map, getting parent\n");
@@ -718,7 +721,7 @@ int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 ointsize,
imaplen /= sizeof(u32);
/* Look for a mask */
- imask = (u32 *)get_property(ipar, "interrupt-map-mask", NULL);
+ 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.
@@ -765,14 +768,14 @@ int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 ointsize,
/* Get #interrupt-cells and #address-cells of new
* parent
*/
- tmp = (u32 *)get_property(newpar, "#interrupt-cells",
+ tmp = get_property(newpar, "#interrupt-cells",
NULL);
if (tmp == NULL) {
DBG(" -> parent lacks #interrupt-cells !\n");
goto fail;
}
newintsize = *tmp;
- tmp = (u32 *)get_property(newpar, "#address-cells",
+ tmp = get_property(newpar, "#address-cells",
NULL);
newaddrsize = (tmp == NULL) ? 0 : *tmp;
@@ -818,14 +821,14 @@ EXPORT_SYMBOL_GPL(of_irq_map_raw);
static int of_irq_map_oldworld(struct device_node *device, int index,
struct of_irq *out_irq)
{
- u32 *ints;
+ const u32 *ints;
int intlen;
/*
* Old machines just have a list of interrupt numbers
* and no interrupt-controller nodes.
*/
- ints = (u32 *) get_property(device, "AAPL,interrupts", &intlen);
+ ints = get_property(device, "AAPL,interrupts", &intlen);
if (ints == NULL)
return -EINVAL;
intlen /= sizeof(u32);
@@ -850,7 +853,8 @@ static int of_irq_map_oldworld(struct device_node *device, int index,
int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq)
{
struct device_node *p;
- u32 *intspec, *tmp, intsize, intlen, *addr;
+ const u32 *intspec, *tmp, *addr;
+ u32 intsize, intlen;
int res;
DBG("of_irq_map_one: dev=%s, index=%d\n", device->full_name, index);
@@ -860,13 +864,13 @@ int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq
return of_irq_map_oldworld(device, index, out_irq);
/* Get the interrupts property */
- intspec = (u32 *)get_property(device, "interrupts", &intlen);
+ intspec = get_property(device, "interrupts", &intlen);
if (intspec == NULL)
return -EINVAL;
intlen /= sizeof(u32);
/* Get the reg property (if any) */
- addr = (u32 *)get_property(device, "reg", NULL);
+ addr = get_property(device, "reg", NULL);
/* Look for the interrupt parent. */
p = of_irq_find_parent(device);
@@ -874,7 +878,7 @@ int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq
return -EINVAL;
/* Get size of interrupt specifier */
- tmp = (u32 *)get_property(p, "#interrupt-cells", NULL);
+ tmp = get_property(p, "#interrupt-cells", NULL);
if (tmp == NULL) {
of_node_put(p);
return -EINVAL;
diff --git a/arch/powerpc/kernel/rtas-proc.c b/arch/powerpc/kernel/rtas-proc.c
index 9c9ad1fa9cc..2fe82abf1c5 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 77f1e06d208..6ef80d4e38d 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -177,10 +177,12 @@ void __init udbg_init_rtas_console(void)
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? */
@@ -191,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");
@@ -293,10 +295,10 @@ 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);
@@ -626,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;
@@ -687,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);
@@ -845,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
@@ -909,6 +913,11 @@ int __init early_init_dt_scan_rtas(unsigned long node,
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 */
diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c
index cda02265732..b4a0de79c06 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;
}
@@ -325,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 499c3861074..0af3fc1bdcc 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -304,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;
@@ -366,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 */
}
@@ -395,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;
@@ -444,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 */
@@ -452,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 e0df2ba1ab9..79a17795d17 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -67,10 +67,6 @@ int have_of = 1;
dev_t boot_dev;
#endif /* CONFIG_PPC_MULTIPLATFORM */
-#ifdef CONFIG_MAGIC_SYSRQ
-unsigned long SYSRQ_KEY = 0x54;
-#endif /* CONFIG_MAGIC_SYSRQ */
-
#ifdef CONFIG_VGA_CONSOLE
unsigned long vgacon_remap_base;
#endif
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index fd1785e4c9b..962ad5ebc76 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -56,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>
@@ -79,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);
@@ -94,11 +93,6 @@ int dcache_bsize;
int icache_bsize;
int ucache_bsize;
-#ifdef CONFIG_MAGIC_SYSRQ
-unsigned long SYSRQ_KEY;
-#endif /* CONFIG_MAGIC_SYSRQ */
-
-
#ifdef CONFIG_SMP
static int smt_enabled_cmdline;
@@ -107,7 +101,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)
@@ -116,7 +110,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"))
@@ -293,7 +287,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;
@@ -308,10 +302,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)
@@ -325,10 +319,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)
diff --git a/arch/powerpc/kernel/swsusp_32.S b/arch/powerpc/kernel/swsusp_32.S
index 7369f9a6ad2..69e8f86aa4f 100644
--- a/arch/powerpc/kernel/swsusp_32.S
+++ b/arch/powerpc/kernel/swsusp_32.S
@@ -159,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 2e292863e98..5e391fc2534 100644
--- a/arch/powerpc/kernel/sys_ppc32.c
+++ b/arch/powerpc/kernel/sys_ppc32.c
@@ -740,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 fec228cd016..406f308ddea 100644
--- a/arch/powerpc/kernel/sysfs.c
+++ b/arch/powerpc/kernel/sysfs.c
@@ -60,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))
@@ -70,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;
@@ -231,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);
}
@@ -273,7 +272,7 @@ 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 */
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index a124499e65d..8b278d85ca4 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -117,8 +117,6 @@ unsigned tb_to_ns_shift;
struct gettimeofday_struct do_gtod;
-extern unsigned long wall_jiffies;
-
extern struct timezone sys_tz;
static long timezone_offset;
@@ -693,7 +691,7 @@ void timer_interrupt(struct pt_regs * regs)
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(regs);
+ do_timer(1);
timer_recalc_offset(tb_last_jiffy);
timer_check_rtc();
}
@@ -816,11 +814,6 @@ int do_settimeofday(struct timespec *tv)
/*
* Subtract off the number of nanoseconds since the
* beginning of the last tick.
- * Note that since we don't increment jiffies_64 anywhere other
- * than in do_timer (since we don't have a lost tick problem),
- * wall_jiffies will always be the same as jiffies,
- * and therefore the (jiffies - wall_jiffies) computation
- * has been removed.
*/
tb_delta = tb_ticks_since(tb_last_jiffy);
tb_delta = mulhdu(tb_delta, do_gtod.varp->tb_to_xs); /* in xsec */
@@ -860,19 +853,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);
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 9b352bd0a46..d9f10f2fc37 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -598,6 +598,9 @@ static void parse_fpe(struct pt_regs *regs)
#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;
@@ -666,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;
@@ -703,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/vio.c b/arch/powerpc/kernel/vio.c
index fad8580f908..cb87e71eec6 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,7 +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;
+ const unsigned int *unit_address;
/* we need the 'device_type' property, in order to match with drivers */
if (of_node->type == NULL) {
@@ -227,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__,
@@ -249,7 +249,7 @@ struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node)
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;
@@ -423,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)
@@ -431,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;
@@ -493,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/lib/Makefile b/arch/powerpc/lib/Makefile
index ff709645824..336dd191f76 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/e2a.c b/arch/powerpc/lib/e2a.c
deleted file mode 100644
index 4b72ed8fd50..00000000000
--- 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 077bed7dc52..80b482ca30d 100644
--- a/arch/powerpc/lib/locks.c
+++ b/arch/powerpc/lib/locks.c
@@ -23,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)
{
@@ -39,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);
}
/*
@@ -69,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/mm/fault.c b/arch/powerpc/mm/fault.c
index 78a0d59903e..e8fa50624b7 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -333,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;
}
@@ -386,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/mem.c b/arch/powerpc/mm/mem.c
index eebd8b83a6b..16fe027bbc1 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -256,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++)
@@ -277,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;
}
@@ -288,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 */
@@ -307,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/numa.c b/arch/powerpc/mm/numa.c
index fbe23933f73..43c272075e1 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;
@@ -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);
}
@@ -633,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,
@@ -670,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++) {
@@ -713,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)
@@ -787,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/slb.c b/arch/powerpc/mm/slb.c
index de0c8842415..d3733912adb 100644
--- a/arch/powerpc/mm/slb.c
+++ b/arch/powerpc/mm/slb.c
@@ -22,6 +22,8 @@
#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)
@@ -50,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))
@@ -77,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"
@@ -209,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/tlb_64.c b/arch/powerpc/mm/tlb_64.c
index f6eef78efd2..b58baa65c4a 100644
--- a/arch/powerpc/mm/tlb_64.c
+++ b/arch/powerpc/mm/tlb_64.c
@@ -146,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/platforms/83xx/mpc834x_itx.c b/arch/powerpc/platforms/83xx/mpc834x_itx.c
index cf3967a66fb..969fbb6d8c4 100644
--- a/arch/powerpc/platforms/83xx/mpc834x_itx.c
+++ b/arch/powerpc/platforms/83xx/mpc834x_itx.c
@@ -60,8 +60,8 @@ static void __init mpc834x_itx_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
diff --git a/arch/powerpc/platforms/83xx/mpc834x_sys.c b/arch/powerpc/platforms/83xx/mpc834x_sys.c
index 32df239d1c4..677196187a4 100644
--- a/arch/powerpc/platforms/83xx/mpc834x_sys.c
+++ b/arch/powerpc/platforms/83xx/mpc834x_sys.c
@@ -57,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
diff --git a/arch/powerpc/platforms/83xx/pci.c b/arch/powerpc/platforms/83xx/pci.c
index 5d84a9ccd10..4557ac5255c 100644
--- a/arch/powerpc/platforms/83xx/pci.c
+++ b/arch/powerpc/platforms/83xx/pci.c
@@ -59,7 +59,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();
@@ -69,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);
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
index 9d2acfbbecc..cae6b73357d 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_ads.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
@@ -121,9 +121,9 @@ static void __init mpc85xx_ads_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
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
index 1d357d32a29..4c1fede6470 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
@@ -241,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
diff --git a/arch/powerpc/platforms/85xx/pci.c b/arch/powerpc/platforms/85xx/pci.c
index 1d51f3242ab..05930eeb6e7 100644
--- a/arch/powerpc/platforms/85xx/pci.c
+++ b/arch/powerpc/platforms/85xx/pci.c
@@ -41,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();
@@ -51,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);
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
index 5e583cf3878..b637e8157f7 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
+++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
@@ -347,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
diff --git a/arch/powerpc/platforms/86xx/pci.c b/arch/powerpc/platforms/86xx/pci.c
index a8c8f0a4405..481e18ed5be 100644
--- a/arch/powerpc/platforms/86xx/pci.c
+++ b/arch/powerpc/platforms/86xx/pci.c
@@ -153,7 +153,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 has_address = 0;
int primary = 0;
@@ -163,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);
diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile
index 5cf46dc5789..e58fa953a50 100644
--- a/arch/powerpc/platforms/Makefile
+++ b/arch/powerpc/platforms/Makefile
@@ -13,5 +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/cbe_regs.c b/arch/powerpc/platforms/cell/cbe_regs.c
index ce696c1cca7..3f3859d12e0 100644
--- a/arch/powerpc/platforms/cell/cbe_regs.c
+++ b/arch/powerpc/platforms/cell/cbe_regs.c
@@ -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;
@@ -114,13 +114,11 @@ void __init cbe_regs_init(void)
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 d7bbb61109f..6b57a47c5d3 100644
--- a/arch/powerpc/platforms/cell/interrupt.c
+++ b/arch/powerpc/platforms/cell/interrupt.c
@@ -89,17 +89,17 @@ static struct irq_chip iic_chip = {
/* Get an IRQ number from the pending state register of the IIC */
static unsigned int iic_get_irq(struct pt_regs *regs)
{
- struct cbe_iic_pending_bits pending;
- struct iic *iic;
-
- iic = &__get_cpu_var(iic);
- *(unsigned long *) &pending =
- in_be64((unsigned long __iomem *) &iic->regs->pending_destr);
- iic->eoi_stack[++iic->eoi_ptr] = pending.prio;
- BUG_ON(iic->eoi_ptr > 15);
+ struct cbe_iic_pending_bits pending;
+ struct iic *iic;
+
+ iic = &__get_cpu_var(iic);
+ *(unsigned long *) &pending =
+ in_be64((unsigned long __iomem *) &iic->regs->pending_destr);
+ 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));
+ iic_pending_to_hwnum(pending));
return NO_IRQ;
}
@@ -250,16 +250,15 @@ static int __init setup_iic(void)
struct resource r0, r1;
struct irq_host *host;
int found = 0;
- u32 *np;
+ 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 = (u32 *)get_property(dn, "ibm,interrupt-server-ranges",
- NULL);
- if (np == NULL) {
+ 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;
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index a35004e14c6..d2b20eba5b8 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/setup.c b/arch/powerpc/platforms/cell/setup.c
index 282987d6d4a..22c228a49c3 100644
--- a/arch/powerpc/platforms/cell/setup.c
+++ b/arch/powerpc/platforms/cell/setup.c
@@ -150,10 +150,6 @@ static int __init cell_probe(void)
!of_flat_dt_is_compatible(root, "IBM,CPBW-1.0"))
return 0;
-#ifdef CONFIG_UDBG_RTAS_CONSOLE
- udbg_init_rtas_console();
-#endif
-
hpte_init_native();
return 1;
diff --git a/arch/powerpc/platforms/cell/smp.c b/arch/powerpc/platforms/cell/smp.c
index 46aef064074..1c0acbad742 100644
--- a/arch/powerpc/platforms/cell/smp.c
+++ b/arch/powerpc/platforms/cell/smp.c
@@ -57,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
@@ -74,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 15217bb0402..742a03282b4 100644
--- a/arch/powerpc/platforms/cell/spider-pic.c
+++ b/arch/powerpc/platforms/cell/spider-pic.c
@@ -240,7 +240,7 @@ static void spider_irq_cascade(unsigned int irq, struct irq_desc *desc,
static unsigned int __init spider_find_cascade_and_node(struct spider_pic *pic)
{
unsigned int virq;
- u32 *imap, *tmp;
+ const u32 *imap, *tmp;
int imaplen, intsize, unit;
struct device_node *iic;
struct irq_host *iic_host;
@@ -258,25 +258,25 @@ static unsigned int __init spider_find_cascade_and_node(struct spider_pic *pic)
#endif
/* Now do the horrible hacks */
- tmp = (u32 *)get_property(pic->of_node, "#interrupt-cells", NULL);
+ tmp = get_property(pic->of_node, "#interrupt-cells", NULL);
if (tmp == NULL)
return NO_IRQ;
intsize = *tmp;
- imap = (u32 *)get_property(pic->of_node, "interrupt-map", &imaplen);
+ 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 = (u32 *)get_property(iic, "#interrupt-cells", NULL);
+ 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 = (u32 *)get_property(iic, "ibm,interrupt-server-ranges", NULL);
+ tmp = get_property(iic, "ibm,interrupt-server-ranges", NULL);
if (tmp == NULL) {
of_node_put(iic);
return NO_IRQ;
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
index d06042deb02..3bd36d46ab4 100644
--- a/arch/powerpc/platforms/cell/spu_base.c
+++ b/arch/powerpc/platforms/cell/spu_base.c
@@ -488,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;
}
@@ -500,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;
@@ -511,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;
@@ -531,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;
@@ -570,14 +570,14 @@ static int __init spu_map_interrupts(struct spu *spu, struct device_node *np)
{
struct irq_host *host;
unsigned int isrc;
- u32 *tmp;
+ const u32 *tmp;
host = iic_get_irq_host(spu->node);
if (host == NULL)
return -ENODEV;
/* Get the interrupt source from the device-tree */
- tmp = (u32 *)get_property(np, "isrc", NULL);
+ tmp = get_property(np, "isrc", NULL);
if (!tmp)
return -ENODEV;
spu->isrc = isrc = tmp[0];
@@ -593,7 +593,7 @@ static int __init spu_map_interrupts(struct spu *spu, struct device_node *np)
static int __init spu_map_device(struct spu *spu, struct device_node *node)
{
- char *prop;
+ const char *prop;
int ret;
ret = -ENODEV;
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index 7b4572805db..3950ddccb2c 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/chrp/nvram.c b/arch/powerpc/platforms/chrp/nvram.c
index 150f67d6f90..0dd4a64757d 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 6802cdc3168..0f4340506c7 100644
--- a/arch/powerpc/platforms/chrp/pci.c
+++ b/arch/powerpc/platforms/chrp/pci.c
@@ -214,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;
@@ -246,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);
@@ -257,7 +257,7 @@ 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 %llx", (unsigned long long)r.start);
printk("\n");
@@ -289,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);
@@ -299,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);
}
}
+}
+
+/* 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;
- /* Do not fixup interrupts from OF tree on pegasos */
- if (is_pegasos)
- ppc_md.pcibios_fixup = NULL;
+ /* 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 9c08ff32229..488dbd9b51a 100644
--- a/arch/powerpc/platforms/chrp/setup.c
+++ b/arch/powerpc/platforms/chrp/setup.c
@@ -74,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
@@ -92,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;
@@ -214,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;
@@ -229,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;
@@ -245,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)
@@ -328,7 +352,7 @@ static void __init chrp_find_openpic(void)
struct device_node *np, *root;
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;
@@ -338,8 +362,7 @@ static void __init chrp_find_openpic(void)
return;
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)) {
@@ -356,7 +379,7 @@ static void __init chrp_find_openpic(void)
printk(KERN_INFO "OpenPIC at %lx\n", opaddr);
- 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
@@ -442,8 +465,8 @@ static void __init chrp_find_8259(void)
* 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;
@@ -502,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();
@@ -520,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
diff --git a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
index 5d393eb9493..e4f2b9df5e1 100644
--- a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
+++ b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
@@ -95,7 +95,7 @@ void mpc7448_hpc2_fixup_irq(struct pci_dev *dev)
{
struct pci_controller *hose;
struct device_node *node;
- unsigned int *interrupt;
+ const unsigned int *interrupt;
int busnr;
int len;
u8 slot;
@@ -112,7 +112,7 @@ void mpc7448_hpc2_fixup_irq(struct pci_dev *dev)
if (!node)
printk(KERN_ERR "No pci node found\n");
- interrupt = (unsigned int *) get_property(node, "interrupt-map", &len);
+ 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)
@@ -141,9 +141,9 @@ static void __init mpc7448_hpc2_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
diff --git a/arch/powerpc/platforms/iseries/Kconfig b/arch/powerpc/platforms/iseries/Kconfig
index 3d957a30c8c..887b68804e6 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 d194140c1eb..e305deee7f4 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;
@@ -298,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/hvlpconfig.c b/arch/powerpc/platforms/iseries/hvlpconfig.c
index 663a1affb4b..f0475f0b185 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 e3bd2015f2c..f4cbbcf8773 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/it_exp_vpd_panel.h b/arch/powerpc/platforms/iseries/it_exp_vpd_panel.h
new file mode 100644
index 00000000000..6de9097b7f5
--- /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 00000000000..9bbf5898681
--- /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 a7769445d6c..8162049bb04 100644
--- a/arch/powerpc/platforms/iseries/lpardata.c
+++ b/arch/powerpc/platforms/iseries/lpardata.c
@@ -13,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"
@@ -27,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.
@@ -127,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 2a9f81ea27d..98c1c2440aa 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
diff --git a/arch/powerpc/platforms/iseries/main_store.h b/arch/powerpc/platforms/iseries/main_store.h
index 74f6889f834..1a7a3f50e40 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 35bcc98111f..3eb12065df2 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/setup.c b/arch/powerpc/platforms/iseries/setup.c
index c9605d773a7..7f1953066ff 100644
--- a/arch/powerpc/platforms/iseries/setup.c
+++ b/arch/powerpc/platforms/iseries/setup.c
@@ -59,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"
diff --git a/arch/powerpc/platforms/iseries/viopath.c b/arch/powerpc/platforms/iseries/viopath.c
index 622a30149b4..9baa4ee8259 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 23a6d1e5b42..9f83878a0c2 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 63a1670d3bf..c3aa46b8e2b 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);
diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c
index 57567dfb981..fe6b9bff61b 100644
--- a/arch/powerpc/platforms/maple/setup.c
+++ b/arch/powerpc/platforms/maple/setup.c
@@ -99,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();
@@ -113,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");
@@ -129,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();
@@ -143,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");
@@ -211,7 +205,7 @@ static void __init maple_init_early(void)
static void __init maple_init_IRQ(void)
{
struct device_node *root, *np, *mpic_node = NULL;
- unsigned int *opprop;
+ const unsigned int *opprop;
unsigned long openpic_addr = 0;
int naddr, n, i, opplen, has_isus = 0;
struct mpic *mpic;
@@ -241,8 +235,7 @@ static void __init maple_init_IRQ(void)
/* Find address list in /platform-open-pic */
root = of_find_node_by_path("/");
naddr = prom_n_addr_cells(root);
- opprop = (unsigned int *) get_property(root, "platform-open-pic",
- &opplen);
+ opprop = get_property(root, "platform-open-pic", &opplen);
if (opprop != 0) {
openpic_addr = of_read_number(opprop, naddr);
has_isus = (opplen > naddr);
diff --git a/arch/powerpc/platforms/pasemi/Makefile b/arch/powerpc/platforms/pasemi/Makefile
new file mode 100644
index 00000000000..1be1a993c5f
--- /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 00000000000..fd71d72736b
--- /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 00000000000..4679c523041
--- /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 00000000000..628482671c1
--- /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 00000000000..9bd410b8fec
--- /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 d6641549105..afa593a8544 100644
--- a/arch/powerpc/platforms/powermac/backlight.c
+++ b/arch/powerpc/platforms/powermac/backlight.c
@@ -60,7 +60,8 @@ int pmac_has_backlight_type(const char *type)
struct device_node* bk_node = find_devices("backlight");
if (bk_node) {
- char *prop = get_property(bk_node, "backlight-control", NULL);
+ const char *prop = get_property(bk_node,
+ "backlight-control", NULL);
if (prop && strncmp(prop, type, strlen(type)) == 0)
return 1;
}
diff --git a/arch/powerpc/platforms/powermac/cpufreq_32.c b/arch/powerpc/platforms/powermac/cpufreq_32.c
index 62926248bdb..c2b6b4134f6 100644
--- a/arch/powerpc/platforms/powermac/cpufreq_32.c
+++ b/arch/powerpc/platforms/powermac/cpufreq_32.c
@@ -421,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)
@@ -497,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
@@ -519,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;
@@ -562,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;
@@ -571,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;
@@ -611,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;
@@ -650,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;
@@ -661,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 7b1156ea534..9d22361a26d 100644
--- a/arch/powerpc/platforms/powermac/cpufreq_64.c
+++ b/arch/powerpc/platforms/powermac/cpufreq_64.c
@@ -89,7 +89,7 @@ static DEFINE_MUTEX(g5_switch_mutex);
#ifdef CONFIG_PMAC_SMU
-static u32 *g5_pmode_data;
+static const u32 *g5_pmode_data;
static int g5_pmode_max;
static struct smu_sdbp_fvt *g5_fvt_table; /* table of op. points */
@@ -104,7 +104,7 @@ static void g5_smu_switch_volt(int speed_mode)
{
struct smu_simple_cmd cmd;
- DECLARE_COMPLETION(comp);
+ DECLARE_COMPLETION_ONSTACK(comp);
smu_queue_simple(&cmd, SMU_CMD_POWER_COMMAND, 8, smu_done_complete,
&comp, 'V', 'S', 'L', 'E', 'W',
0xff, g5_fvt_cur+1, speed_mode);
@@ -391,7 +391,8 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus)
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;
@@ -409,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"))
@@ -422,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;
@@ -434,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;
@@ -442,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);
@@ -493,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;
@@ -541,8 +541,8 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus)
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;
@@ -563,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;
@@ -573,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"))
@@ -637,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;
diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c
index f8313bf9a9f..e49621be664 100644
--- a/arch/powerpc/platforms/powermac/feature.c
+++ b/arch/powerpc/platforms/powermac/feature.c
@@ -1058,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) {
@@ -1087,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;
@@ -1096,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)
@@ -1507,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) {
@@ -2408,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];
@@ -2536,7 +2536,7 @@ found:
*/
static void __init probe_uninorth(void)
{
- u32 *addrp;
+ const u32 *addrp;
phys_addr_t address;
unsigned long actrl;
@@ -2555,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);
@@ -2596,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;
@@ -2639,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)
@@ -2652,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",
@@ -2695,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 8677f50c258..c2c7cf75dd5 100644
--- a/arch/powerpc/platforms/powermac/low_i2c.c
+++ b/arch/powerpc/platforms/powermac/low_i2c.c
@@ -477,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) {
@@ -490,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);
@@ -504,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;
@@ -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 6a36ea9bf67..692945c1491 100644
--- a/arch/powerpc/platforms/powermac/nvram.c
+++ b/arch/powerpc/platforms/powermac/nvram.c
@@ -195,7 +195,7 @@ static void pmu_nvram_complete(struct adb_request *req)
static unsigned char pmu_nvram_read_byte(int addr)
{
struct adb_request req;
- DECLARE_COMPLETION(req_complete);
+ DECLARE_COMPLETION_ONSTACK(req_complete);
req.arg = system_state == SYSTEM_RUNNING ? &req_complete : NULL;
if (pmu_request(&req, pmu_nvram_complete, 3, PMU_READ_NVRAM,
@@ -211,7 +211,7 @@ static unsigned char pmu_nvram_read_byte(int addr)
static void pmu_nvram_write_byte(int addr, unsigned char val)
{
struct adb_request req;
- DECLARE_COMPLETION(req_complete);
+ DECLARE_COMPLETION_ONSTACK(req_complete);
req.arg = system_state == SYSTEM_RUNNING ? &req_complete : NULL;
if (pmu_request(&req, pmu_nvram_complete, 4, PMU_WRITE_NVRAM,
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c
index 205d0447116..9923adc5248 100644
--- a/arch/powerpc/platforms/powermac/pci.c
+++ b/arch/powerpc/platforms/powermac/pci.c
@@ -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;
@@ -686,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;
@@ -898,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);
@@ -907,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);
diff --git a/arch/powerpc/platforms/powermac/pfunc_base.c b/arch/powerpc/platforms/powermac/pfunc_base.c
index aacfa59595d..ee3b223ab17 100644
--- a/arch/powerpc/platforms/powermac/pfunc_base.c
+++ b/arch/powerpc/platforms/powermac/pfunc_base.c
@@ -114,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;
diff --git a/arch/powerpc/platforms/powermac/pfunc_core.c b/arch/powerpc/platforms/powermac/pfunc_core.c
index b117adbf957..7651f278615 100644
--- a/arch/powerpc/platforms/powermac/pfunc_core.c
+++ b/arch/powerpc/platforms/powermac/pfunc_core.c
@@ -813,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/setup.c b/arch/powerpc/platforms/powermac/setup.c
index 31a9da769fa..824a618396a 100644
--- a/arch/powerpc/platforms/powermac/setup.c
+++ b/arch/powerpc/platforms/powermac/setup.c
@@ -116,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;
@@ -134,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) {
@@ -163,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) {
@@ -254,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;
@@ -277,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));
@@ -287,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. */
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index 827b7121ffb..1949b657b09 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -548,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 */
@@ -562,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) {
@@ -702,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/udbg_scc.c b/arch/powerpc/platforms/powermac/udbg_scc.c
index 37e5b1eff91..ce1a235855f 100644
--- a/arch/powerpc/platforms/powermac/udbg_scc.c
+++ b/arch/powerpc/platforms/powermac/udbg_scc.c
@@ -68,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");
@@ -81,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;) {
@@ -96,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 e5e0ff46690..997243a91be 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 32eaddfa547..84bc8f7e17e 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 c37a8497c60..b6b462d3c60 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);
}
/**
diff --git a/arch/powerpc/platforms/pseries/eeh_driver.c b/arch/powerpc/platforms/pseries/eeh_driver.c
index aaad2c0afcb..c2bc9904f1c 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;
@@ -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 45ccc687e57..13707745131 100644
--- a/arch/powerpc/platforms/pseries/eeh_event.c
+++ b/arch/powerpc/platforms/pseries/eeh_event.c
@@ -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 c01d8f0cbe6..1c7b2baa5f7 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 c9ff547f9d2..c00cfed7af2 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 00000000000..446e17d162a
--- /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 a72a987f1d4..3f6a89b0981 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 d67af2c6575..bbf2e34dc35 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -267,13 +267,12 @@ static void iommu_table_setparms(struct pci_controller *phb,
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);
@@ -315,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;
@@ -415,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);
@@ -519,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));
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index 3aeb4069904..1820a0b0a8c 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -48,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);
@@ -204,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;
@@ -228,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];
@@ -254,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,
@@ -277,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, "
@@ -302,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");
diff --git a/arch/powerpc/platforms/pseries/nvram.c b/arch/powerpc/platforms/pseries/nvram.c
index 18abfb1f4e2..64163cecdf9 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 e97e67f5e07..410a6bcc4ca 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 3bd1b3e0600..3eb7b294d92 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 c7ffde1a614..311ed1993fc 100644
--- a/arch/powerpc/platforms/pseries/ras.c
+++ b/arch/powerpc/platforms/pseries/ras.c
@@ -79,7 +79,7 @@ static void request_ras_irqs(struct device_node *np,
{
int i, index, count = 0;
struct of_irq oirq;
- u32 *opicprop;
+ const u32 *opicprop;
unsigned int opicplen;
unsigned int virqs[16];
@@ -87,7 +87,7 @@ static void request_ras_irqs(struct device_node *np,
* map those interrupts using the default interrupt host and default
* trigger
*/
- opicprop = (u32 *)get_property(np, "open-pic-interrupt", &opicplen);
+ opicprop = get_property(np, "open-pic-interrupt", &opicplen);
if (opicprop) {
opicplen /= sizeof(u32);
for (i = 0; i < opicplen; i++) {
@@ -337,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 2e4e04042d8..8ca2612221d 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 31867a701fc..8ed36214045 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -133,9 +133,9 @@ void pseries_8259_cascade(unsigned int irq, struct irq_desc *desc,
static void __init pseries_mpic_init_IRQ(void)
{
struct device_node *np, *old, *cascade = NULL;
- unsigned int *addrp;
+ const unsigned int *addrp;
unsigned long intack = 0;
- unsigned int *opprop;
+ const unsigned int *opprop;
unsigned long openpic_addr = 0;
unsigned int cascade_irq;
int naddr, n, i, opplen;
@@ -143,7 +143,7 @@ static void __init pseries_mpic_init_IRQ(void)
np = of_find_node_by_path("/");
naddr = prom_n_addr_cells(np);
- opprop = (unsigned int *) get_property(np, "platform-open-pic", &opplen);
+ opprop = get_property(np, "platform-open-pic", &opplen);
if (opprop != 0) {
openpic_addr = of_read_number(opprop, naddr);
printk(KERN_DEBUG "OpenPIC addr: %lx\n", openpic_addr);
@@ -192,7 +192,7 @@ static void __init pseries_mpic_init_IRQ(void)
break;
if (strcmp(np->name, "pci") != 0)
continue;
- addrp = (u32 *)get_property(np, "8259-interrupt-acknowledge",
+ addrp = get_property(np, "8259-interrupt-acknowledge",
NULL);
if (addrp == NULL)
continue;
@@ -223,23 +223,37 @@ static void pseries_lpar_enable_pmcs(void)
}
#ifdef CONFIG_KEXEC
-static void pseries_kexec_cpu_down_mpic(int crash_shutdown, int secondary)
-{
- mpic_teardown_this_cpu(secondary);
-}
-
-static void pseries_kexec_cpu_down_xics(int crash_shutdown, int secondary)
+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());
+ 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());
- if (unregister_vpa(hard_smp_processor_id(), vpa)) {
+ 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 */
@@ -247,11 +261,11 @@ static void pseries_kexec_cpu_down_xics(int crash_shutdown, int secondary)
static void __init pseries_discover_pic(void)
{
struct device_node *np;
- char *typep;
+ const char *typep;
for (np = NULL; (np = of_find_node_by_name(np,
"interrupt-controller"));) {
- typep = (char *)get_property(np, "compatible", NULL);
+ 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;
@@ -401,6 +415,12 @@ static int pSeries_check_legacy_ioport(unsigned int baseport)
return -ENODEV;
of_node_put(np);
break;
+ case PARALLEL_BASE:
+ np = of_find_node_by_type(NULL, "parallel");
+ if (np == NULL)
+ return -ENODEV;
+ of_node_put(np);
+ break;
}
return 0;
}
diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c
index ac61098ff40..c6624b8a0e7 100644
--- a/arch/powerpc/platforms/pseries/smp.c
+++ b/arch/powerpc/platforms/pseries/smp.c
@@ -62,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
@@ -145,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;
@@ -205,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;
@@ -270,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;
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index e9886302572..253972e5479 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -34,6 +34,7 @@
#include <asm/i8259.h>
#include "xics.h"
+#include "plpar_wrappers.h"
#define XICS_IPI 2
#define XICS_IRQ_SPURIOUS 0
@@ -110,27 +111,6 @@ static inline void direct_qirr_info(int n_cpu, u8 value)
/* LPAR low level accessors */
-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 inline unsigned int lpar_xirr_info_get(int n_cpu)
{
unsigned long lpar_rc;
@@ -590,14 +570,14 @@ static void __init xics_init_one_node(struct device_node *np,
unsigned int *indx)
{
unsigned int ilen;
- u32 *ireg;
+ const u32 *ireg;
/* 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 = (u32 *)get_property(np, "ibm,interrupt-server-ranges", NULL);
+ ireg = 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 ..
@@ -609,7 +589,7 @@ static void __init xics_init_one_node(struct device_node *np,
*/
*indx = *ireg;
}
- ireg = (u32 *)get_property(np, "reg", &ilen);
+ ireg = get_property(np, "reg", &ilen);
if (!ireg)
panic("xics_init_IRQ: can't find interrupt reg property");
@@ -635,7 +615,7 @@ static void __init xics_setup_8259_cascade(void)
{
struct device_node *np, *old, *found = NULL;
int cascade, naddr;
- u32 *addrp;
+ const u32 *addrp;
unsigned long intack = 0;
for_each_node_by_type(np, "interrupt-controller")
@@ -661,7 +641,7 @@ static void __init xics_setup_8259_cascade(void)
break;
if (strcmp(np->name, "pci") != 0)
continue;
- addrp = (u32 *)get_property(np, "8259-interrupt-acknowledge", NULL);
+ addrp = get_property(np, "8259-interrupt-acknowledge", NULL);
if (addrp == NULL)
continue;
naddr = prom_n_addr_cells(np);
@@ -680,7 +660,8 @@ void __init xics_init_IRQ(void)
{
int i;
struct device_node *np;
- u32 *ireg, ilen, indx = 0;
+ u32 ilen, indx = 0;
+ const u32 *ireg;
int found = 0;
ppc64_boot_msg(0x20, "XICS Init");
@@ -705,18 +686,17 @@ void __init xics_init_IRQ(void)
for (np = of_find_node_by_type(NULL, "cpu");
np;
np = of_find_node_by_type(np, "cpu")) {
- ireg = (u32 *)get_property(np, "reg", &ilen);
+ ireg = get_property(np, "reg", &ilen);
if (ireg && ireg[0] == get_hard_smp_processor_id(boot_cpuid)) {
- ireg = (u32 *)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];
/* take last element */
default_distrib_server = ireg[i-1];
}
- ireg = (u32 *)get_property(np,
+ ireg = get_property(np,
"ibm,interrupt-server#-size", NULL);
if (ireg)
interrupt_server_size = *ireg;
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index ef10bcf2d94..92ba378b799 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -41,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);
};
@@ -85,7 +85,7 @@ static int __init gfar_mdio_of_init(void)
mdio_data.irq[k] = -1;
while ((child = of_get_next_child(np, child)) != NULL) {
- u32 *id = get_property(child, "reg", NULL);
+ const u32 *id = get_property(child, "reg", NULL);
mdio_data.irq[*id] = irq_of_parse_and_map(child, 0);
}
@@ -124,10 +124,10 @@ 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));
@@ -193,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) {
@@ -203,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);
@@ -247,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));
@@ -298,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");
@@ -315,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;
@@ -355,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;
@@ -383,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));
@@ -431,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));
diff --git a/arch/powerpc/sysdev/fsl_soc.h b/arch/powerpc/sysdev/fsl_soc.h
index c433d3f39ed..5a3dd480d2f 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 9855820b954..26a6a3becd6 100644
--- a/arch/powerpc/sysdev/i8259.c
+++ b/arch/powerpc/sysdev/i8259.c
@@ -224,7 +224,7 @@ static struct irq_host_ops i8259_host_ops = {
.xlate = i8259_host_xlate,
};
-/****
+/**
* 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)
diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c
index 70e707785d4..0251b7c68d0 100644
--- a/arch/powerpc/sysdev/ipic.c
+++ b/arch/powerpc/sysdev/ipic.c
@@ -210,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,
@@ -218,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,
@@ -226,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,
@@ -234,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,
@@ -242,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,
@@ -250,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,
@@ -258,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,
@@ -266,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,
@@ -274,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,
diff --git a/arch/powerpc/sysdev/mmio_nvram.c b/arch/powerpc/sysdev/mmio_nvram.c
index 615350d46b5..ff23f5a4d4b 100644
--- a/arch/powerpc/sysdev/mmio_nvram.c
+++ b/arch/powerpc/sysdev/mmio_nvram.c
@@ -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 b604926401f..723972bb5bd 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -339,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;
diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c
index 2ab06ed3ae7..c28f69bef8e 100644
--- a/arch/powerpc/sysdev/tsi108_pci.c
+++ b/arch/powerpc/sysdev/tsi108_pci.c
@@ -194,7 +194,7 @@ int __init tsi108_setup_pci(struct device_node *dev)
int len;
struct pci_controller *hose;
struct resource rsrc;
- int *bus_range;
+ const int *bus_range;
int primary = 0, has_address = 0;
/* PCI Config mapping */
@@ -207,7 +207,7 @@ int __init tsi108_setup_pci(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);
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 179b10ced8c..8adad1444a5 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -137,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);
@@ -736,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());