From a84195f36e373001e6eed2e95a5dc1994cf30480 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 18 Aug 2005 19:35:21 +0200 Subject: [PATCH 01/14] [PATCH] ppc64: fix IPI on bpa_iic This fixes a severe bug in the bpa_iic driver that caused all sorts of problems. We had been using incorrect priority values for inter processor interrupts, which resulted in always doing CALL_FUNCTION instead of RESCHEDULE or DEBUGGER_BREAK. The symptoms cured by this patch include bad performance on SMP systems spurious kernel panics in the IPI code. Signed-off-by: Arnd Bergmann Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/bpa_iic.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/arch/ppc64/kernel/bpa_iic.c b/arch/ppc64/kernel/bpa_iic.c index c8f3dc3fad70..0aaa878e19d3 100644 --- a/arch/ppc64/kernel/bpa_iic.c +++ b/arch/ppc64/kernel/bpa_iic.c @@ -205,6 +205,18 @@ static struct iic_regs __iomem *find_iic(int cpu) } #ifdef CONFIG_SMP + +/* Use the highest interrupt priorities for IPI */ +static inline int iic_ipi_to_irq(int ipi) +{ + return IIC_IPI_OFFSET + IIC_NUM_IPIS - 1 - ipi; +} + +static inline int iic_irq_to_ipi(int irq) +{ + return IIC_NUM_IPIS - 1 - (irq - IIC_IPI_OFFSET); +} + void iic_setup_cpu(void) { out_be64(&__get_cpu_var(iic).regs->prio, 0xff); @@ -212,18 +224,20 @@ void iic_setup_cpu(void) void iic_cause_IPI(int cpu, int mesg) { - out_be64(&per_cpu(iic, cpu).regs->generate, mesg); + out_be64(&per_cpu(iic, cpu).regs->generate, (IIC_NUM_IPIS - 1 - mesg) << 4); } static irqreturn_t iic_ipi_action(int irq, void *dev_id, struct pt_regs *regs) { - - smp_message_recv(irq - IIC_IPI_OFFSET, regs); + smp_message_recv(iic_irq_to_ipi(irq), regs); return IRQ_HANDLED; } -static void iic_request_ipi(int irq, const char *name) +static void iic_request_ipi(int ipi, const char *name) { + int irq; + + irq = iic_ipi_to_irq(ipi); /* IPIs are marked SA_INTERRUPT as they must run with irqs * disabled */ get_irq_desc(irq)->handler = &iic_pic; @@ -233,10 +247,10 @@ static void iic_request_ipi(int irq, const char *name) void iic_request_IPIs(void) { - iic_request_ipi(IIC_IPI_OFFSET + PPC_MSG_CALL_FUNCTION, "IPI-call"); - iic_request_ipi(IIC_IPI_OFFSET + PPC_MSG_RESCHEDULE, "IPI-resched"); + iic_request_ipi(PPC_MSG_CALL_FUNCTION, "IPI-call"); + iic_request_ipi(PPC_MSG_RESCHEDULE, "IPI-resched"); #ifdef CONFIG_DEBUGGER - iic_request_ipi(IIC_IPI_OFFSET + PPC_MSG_DEBUGGER_BREAK, "IPI-debug"); + iic_request_ipi(PPC_MSG_DEBUGGER_BREAK, "IPI-debug"); #endif /* CONFIG_DEBUGGER */ } #endif /* CONFIG_SMP */ From 34b5233f379847097a1925a02b62f129c407c1e4 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Tue, 6 Sep 2005 21:00:02 +1000 Subject: [PATCH 02/14] [PATCH] ppc64: Fix oops for !CONFIG_NUMA The SPARSEMEM EXTREME code (802f192e4a600f7ef84ca25c8b818c8830acef5a) that went in yesterday broke PPC64 for !CONFIG_NUMA. The problem is that (free|reserve)_bootmem don't take a page number as their first argument, they take an address. Ruh roh. Booted on P5 LPAR, iSeries and G5. Signed-off-by: Michael Ellerman Signed-off-by: Paul Mackerras --- arch/ppc64/mm/init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/ppc64/mm/init.c b/arch/ppc64/mm/init.c index a14ab87df491..c2157c9c3acb 100644 --- a/arch/ppc64/mm/init.c +++ b/arch/ppc64/mm/init.c @@ -554,12 +554,12 @@ void __init do_init_bootmem(void) * present. */ for (i=0; i < lmb.memory.cnt; i++) - free_bootmem(lmb_start_pfn(&lmb.memory, i), + free_bootmem(lmb.memory.region[i].base, lmb_size_bytes(&lmb.memory, i)); /* reserve the sections we're already using */ for (i=0; i < lmb.reserved.cnt; i++) - reserve_bootmem(lmb_start_pfn(&lmb.reserved, i), + reserve_bootmem(lmb.reserved.region[i].base, lmb_size_bytes(&lmb.reserved, i)); for (i=0; i < lmb.memory.cnt; i++) From 38c0ff06d5ba05b6fbf18652c49747ad320aaeb0 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Wed, 7 Sep 2005 19:52:38 +1000 Subject: [PATCH 03/14] [PATCH] ppc64: iSeries early printk breakage The earlier commit 8d9273918635f0301368c01b56c03a6f339e8d51 (Consolidate early console and PPCDBG code) broke iSeries because it caused unregister_console(&udbg_console) to be called unconditionally. iSeries never registers the udbg_console. This just reverts part of the change. Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/udbg.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/ppc64/kernel/udbg.c b/arch/ppc64/kernel/udbg.c index ed6766e21f5a..d49c3613c8ec 100644 --- a/arch/ppc64/kernel/udbg.c +++ b/arch/ppc64/kernel/udbg.c @@ -158,14 +158,20 @@ static struct console udbg_console = { .index = -1, }; +static int early_console_initialized; + void __init disable_early_printk(void) { + if (!early_console_initialized) + return; unregister_console(&udbg_console); + early_console_initialized = 0; } /* called by setup_system */ void register_early_udbg_console(void) { + early_console_initialized = 1; register_console(&udbg_console); } From a37c8875a764b4decf941859f4a2c63e1e86c8fa Mon Sep 17 00:00:00 2001 From: "jdl@freescale.com" Date: Wed, 7 Sep 2005 15:27:09 -0500 Subject: [PATCH 04/14] [PATCH] powerpc: Standardize on _ASM_POWERPC header symbol prefix Standardize on _ASM_POWERPC_... prefix for all #include exclusion symbols. Fixup all the non-compilers. Signed-off-by: Jon Loeliger Signed-off-by: Kumar Gala Signed-off-by: Paul Mackerras --- include/asm-powerpc/8253pit.h | 8 ++++---- include/asm-powerpc/agp.h | 8 +++----- include/asm-powerpc/bugs.h | 6 +++--- include/asm-powerpc/errno.h | 6 +++--- include/asm-powerpc/ioctl.h | 6 +++--- include/asm-powerpc/ioctls.h | 6 +++--- include/asm-powerpc/linkage.h | 6 +++--- include/asm-powerpc/mc146818rtc.h | 6 +++--- include/asm-powerpc/mman.h | 6 +++--- include/asm-powerpc/module.h | 6 +++--- include/asm-powerpc/namei.h | 14 +++++++------- include/asm-powerpc/poll.h | 6 +++--- include/asm-powerpc/sembuf.h | 6 +++--- include/asm-powerpc/shmbuf.h | 6 +++--- include/asm-powerpc/shmparam.h | 6 +++--- include/asm-powerpc/siginfo.h | 6 +++--- include/asm-powerpc/socket.h | 6 +++--- include/asm-powerpc/sockios.h | 6 +++--- include/asm-powerpc/string.h | 6 +++--- include/asm-powerpc/termbits.h | 6 +++--- include/asm-powerpc/termios.h | 6 +++--- include/asm-powerpc/unaligned.h | 9 +++++---- 22 files changed, 73 insertions(+), 74 deletions(-) diff --git a/include/asm-powerpc/8253pit.h b/include/asm-powerpc/8253pit.h index 862708a749b0..b70d6e53b303 100644 --- a/include/asm-powerpc/8253pit.h +++ b/include/asm-powerpc/8253pit.h @@ -1,10 +1,10 @@ +#ifndef _ASM_POWERPC_8253PIT_H +#define _ASM_POWERPC_8253PIT_H + /* * 8253/8254 Programmable Interval Timer */ -#ifndef _8253PIT_H -#define _8253PIT_H - #define PIT_TICK_RATE 1193182UL -#endif +#endif /* _ASM_POWERPC_8253PIT_H */ diff --git a/include/asm-powerpc/agp.h b/include/asm-powerpc/agp.h index ca9e423307f4..885b4631a6cf 100644 --- a/include/asm-powerpc/agp.h +++ b/include/asm-powerpc/agp.h @@ -1,10 +1,8 @@ -#ifndef AGP_H -#define AGP_H 1 +#ifndef _ASM_POWERPC_AGP_H +#define _ASM_POWERPC_AGP_H #include -/* nothing much needed here */ - #define map_page_into_agp(page) #define unmap_page_from_agp(page) #define flush_agp_mappings() @@ -20,4 +18,4 @@ #define free_gatt_pages(table, order) \ free_pages((unsigned long)(table), (order)) -#endif +#endif /* _ASM_POWERPC_AGP_H */ diff --git a/include/asm-powerpc/bugs.h b/include/asm-powerpc/bugs.h index 310187d0e33a..f5caee8558bf 100644 --- a/include/asm-powerpc/bugs.h +++ b/include/asm-powerpc/bugs.h @@ -1,5 +1,5 @@ -#ifndef _POWERPC_BUGS_H -#define _POWERPC_BUGS_H +#ifndef _ASM_POWERPC_BUGS_H +#define _ASM_POWERPC_BUGS_H /* * This program is free software; you can redistribute it and/or @@ -15,4 +15,4 @@ extern void check_bugs(void); -#endif /* _POWERPC_BUGS_H */ +#endif /* _ASM_POWERPC_BUGS_H */ diff --git a/include/asm-powerpc/errno.h b/include/asm-powerpc/errno.h index 19f20bd41ae6..8c145fd17d86 100644 --- a/include/asm-powerpc/errno.h +++ b/include/asm-powerpc/errno.h @@ -1,5 +1,5 @@ -#ifndef _PPC_ERRNO_H -#define _PPC_ERRNO_H +#ifndef _ASM_POWERPC_ERRNO_H +#define _ASM_POWERPC_ERRNO_H #include @@ -8,4 +8,4 @@ #define _LAST_ERRNO 516 -#endif +#endif /* _ASM_POWERPC_ERRNO_H */ diff --git a/include/asm-powerpc/ioctl.h b/include/asm-powerpc/ioctl.h index 93c6acfdd0fd..8eb99848c402 100644 --- a/include/asm-powerpc/ioctl.h +++ b/include/asm-powerpc/ioctl.h @@ -1,5 +1,5 @@ -#ifndef _PPC_IOCTL_H -#define _PPC_IOCTL_H +#ifndef _ASM_POWERPC_IOCTL_H +#define _ASM_POWERPC_IOCTL_H /* @@ -66,4 +66,4 @@ extern unsigned int __invalid_size_argument_for_IOC; #define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT) #define IOCSIZE_SHIFT (_IOC_SIZESHIFT) -#endif +#endif /* _ASM_POWERPC_IOCTL_H */ diff --git a/include/asm-powerpc/ioctls.h b/include/asm-powerpc/ioctls.h index f5b7f2b055e7..5b94ff489b8b 100644 --- a/include/asm-powerpc/ioctls.h +++ b/include/asm-powerpc/ioctls.h @@ -1,5 +1,5 @@ -#ifndef _ASM_PPC_IOCTLS_H -#define _ASM_PPC_IOCTLS_H +#ifndef _ASM_POWERPC_IOCTLS_H +#define _ASM_POWERPC_IOCTLS_H #include @@ -104,4 +104,4 @@ #define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ #define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ -#endif /* _ASM_PPC_IOCTLS_H */ +#endif /* _ASM_POWERPC_IOCTLS_H */ diff --git a/include/asm-powerpc/linkage.h b/include/asm-powerpc/linkage.h index 291c2d01c44f..e1c4ac1cc4ba 100644 --- a/include/asm-powerpc/linkage.h +++ b/include/asm-powerpc/linkage.h @@ -1,6 +1,6 @@ -#ifndef __ASM_LINKAGE_H -#define __ASM_LINKAGE_H +#ifndef _ASM_POWERPC_LINKAGE_H +#define _ASM_POWERPC_LINKAGE_H /* Nothing to see here... */ -#endif +#endif /* _ASM_POWERPC_LINKAGE_H */ diff --git a/include/asm-powerpc/mc146818rtc.h b/include/asm-powerpc/mc146818rtc.h index a5619a2a1393..f2741c8b59a1 100644 --- a/include/asm-powerpc/mc146818rtc.h +++ b/include/asm-powerpc/mc146818rtc.h @@ -1,5 +1,5 @@ -#ifndef _POWERPC_MC146818RTC_H -#define _POWERPC_MC146818RTC_H +#ifndef _ASM_POWERPC_MC146818RTC_H +#define _ASM_POWERPC_MC146818RTC_H /* * Machine dependent access functions for RTC registers. @@ -33,4 +33,4 @@ outb_p((val),RTC_PORT(1)); \ }) #endif /* __KERNEL__ */ -#endif /* _POWERPC_MC146818RTC_H */ +#endif /* _ASM_POWERPC_MC146818RTC_H */ diff --git a/include/asm-powerpc/mman.h b/include/asm-powerpc/mman.h index f2d55988d749..f5e5342fcac5 100644 --- a/include/asm-powerpc/mman.h +++ b/include/asm-powerpc/mman.h @@ -1,5 +1,5 @@ -#ifndef _POWERPC_MMAN_H -#define _POWERPC_MMAN_H +#ifndef _ASM_POWERPC_MMAN_H +#define _ASM_POWERPC_MMAN_H /* * This program is free software; you can redistribute it and/or @@ -49,4 +49,4 @@ #define MAP_ANON MAP_ANONYMOUS #define MAP_FILE 0 -#endif /* _POWERPC_MMAN_H */ +#endif /* _ASM_POWERPC_MMAN_H */ diff --git a/include/asm-powerpc/module.h b/include/asm-powerpc/module.h index 4438f4fd6524..7ecd05e03051 100644 --- a/include/asm-powerpc/module.h +++ b/include/asm-powerpc/module.h @@ -1,5 +1,5 @@ -#ifndef _POWERPC_MODULE_H -#define _POWERPC_MODULE_H +#ifndef _ASM_POWERPC_MODULE_H +#define _ASM_POWERPC_MODULE_H /* * This program is free software; you can redistribute it and/or @@ -74,4 +74,4 @@ struct exception_table_entry; void sort_ex_table(struct exception_table_entry *start, struct exception_table_entry *finish); -#endif /* _POWERPC_MODULE_H */ +#endif /* _ASM_POWERPC_MODULE_H */ diff --git a/include/asm-powerpc/namei.h b/include/asm-powerpc/namei.h index 29c9ec832133..657443474a6a 100644 --- a/include/asm-powerpc/namei.h +++ b/include/asm-powerpc/namei.h @@ -1,14 +1,14 @@ +#ifndef _ASM_POWERPC_NAMEI_H +#define _ASM_POWERPC_NAMEI_H + +#ifdef __KERNEL__ + /* - * include/asm-ppc/namei.h * Adapted from include/asm-alpha/namei.h * * Included from fs/namei.c */ -#ifdef __KERNEL__ -#ifndef __PPC_NAMEI_H -#define __PPC_NAMEI_H - /* This dummy routine maybe changed to something useful * for /usr/gnemul/ emulation stuff. * Look at asm-sparc/namei.h for details. @@ -16,5 +16,5 @@ #define __emul_prefix() NULL -#endif /* __PPC_NAMEI_H */ -#endif /* __KERNEL__ */ +#endif /* __KERNEL__ */ +#endif /* _ASM_POWERPC_NAMEI_H */ diff --git a/include/asm-powerpc/poll.h b/include/asm-powerpc/poll.h index be5024913c62..edd2054da86b 100644 --- a/include/asm-powerpc/poll.h +++ b/include/asm-powerpc/poll.h @@ -1,5 +1,5 @@ -#ifndef __PPC_POLL_H -#define __PPC_POLL_H +#ifndef _ASM_POWERPC_POLL_H +#define _ASM_POWERPC_POLL_H #define POLLIN 0x0001 #define POLLPRI 0x0002 @@ -20,4 +20,4 @@ struct pollfd { short revents; }; -#endif +#endif /* _ASM_POWERPC_POLL_H */ diff --git a/include/asm-powerpc/sembuf.h b/include/asm-powerpc/sembuf.h index c98fc18fe805..99a41938ae3d 100644 --- a/include/asm-powerpc/sembuf.h +++ b/include/asm-powerpc/sembuf.h @@ -1,5 +1,5 @@ -#ifndef _POWERPC_SEMBUF_H -#define _POWERPC_SEMBUF_H +#ifndef _ASM_POWERPC_SEMBUF_H +#define _ASM_POWERPC_SEMBUF_H /* * This program is free software; you can redistribute it and/or @@ -33,4 +33,4 @@ struct semid64_ds { unsigned long __unused4; }; -#endif /* _POWERPC_SEMBUF_H */ +#endif /* _ASM_POWERPC_SEMBUF_H */ diff --git a/include/asm-powerpc/shmbuf.h b/include/asm-powerpc/shmbuf.h index 29632db3b178..dca582a4f68d 100644 --- a/include/asm-powerpc/shmbuf.h +++ b/include/asm-powerpc/shmbuf.h @@ -1,5 +1,5 @@ -#ifndef _POWERPC_SHMBUF_H -#define _POWERPC_SHMBUF_H +#ifndef _ASM_POWERPC_SHMBUF_H +#define _ASM_POWERPC_SHMBUF_H /* * This program is free software; you can redistribute it and/or @@ -56,4 +56,4 @@ struct shminfo64 { unsigned long __unused4; }; -#endif /* _POWERPC_SHMBUF_H */ +#endif /* _ASM_POWERPC_SHMBUF_H */ diff --git a/include/asm-powerpc/shmparam.h b/include/asm-powerpc/shmparam.h index d6250602ae64..5cda42a6d39e 100644 --- a/include/asm-powerpc/shmparam.h +++ b/include/asm-powerpc/shmparam.h @@ -1,6 +1,6 @@ -#ifndef _PPC_SHMPARAM_H -#define _PPC_SHMPARAM_H +#ifndef _ASM_POWERPC_SHMPARAM_H +#define _ASM_POWERPC_SHMPARAM_H #define SHMLBA PAGE_SIZE /* attach addr a multiple of this */ -#endif /* _PPC_SHMPARAM_H */ +#endif /* _ASM_POWERPC_SHMPARAM_H */ diff --git a/include/asm-powerpc/siginfo.h b/include/asm-powerpc/siginfo.h index ae70b8010b19..538ea8ef509b 100644 --- a/include/asm-powerpc/siginfo.h +++ b/include/asm-powerpc/siginfo.h @@ -1,5 +1,5 @@ -#ifndef _POWERPC_SIGINFO_H -#define _POWERPC_SIGINFO_H +#ifndef _ASM_POWERPC_SIGINFO_H +#define _ASM_POWERPC_SIGINFO_H /* * This program is free software; you can redistribute it and/or @@ -15,4 +15,4 @@ #include -#endif /* _POWERPC_SIGINFO_H */ +#endif /* _ASM_POWERPC_SIGINFO_H */ diff --git a/include/asm-powerpc/socket.h b/include/asm-powerpc/socket.h index 51a0cf5ee9f0..e4b8177d4acc 100644 --- a/include/asm-powerpc/socket.h +++ b/include/asm-powerpc/socket.h @@ -1,5 +1,5 @@ -#ifndef _POWERPC_SOCKET_H -#define _POWERPC_SOCKET_H +#ifndef _ASM_POWERPC_SOCKET_H +#define _ASM_POWERPC_SOCKET_H /* * This program is free software; you can redistribute it and/or @@ -56,4 +56,4 @@ #define SO_PEERSEC 31 -#endif /* _POWERPC_SOCKET_H */ +#endif /* _ASM_POWERPC_SOCKET_H */ diff --git a/include/asm-powerpc/sockios.h b/include/asm-powerpc/sockios.h index ef7ff664167e..590078d8ed28 100644 --- a/include/asm-powerpc/sockios.h +++ b/include/asm-powerpc/sockios.h @@ -1,5 +1,5 @@ -#ifndef _POWERPC_SOCKIOS_H -#define _POWERPC_SOCKIOS_H +#ifndef _ASM_POWERPC_SOCKIOS_H +#define _ASM_POWERPC_SOCKIOS_H /* * This program is free software; you can redistribute it and/or @@ -16,4 +16,4 @@ #define SIOCATMARK 0x8905 #define SIOCGSTAMP 0x8906 /* Get stamp */ -#endif /* _POWERPC_SOCKIOS_H */ +#endif /* _ASM_POWERPC_SOCKIOS_H */ diff --git a/include/asm-powerpc/string.h b/include/asm-powerpc/string.h index 225575997392..8606a696c088 100644 --- a/include/asm-powerpc/string.h +++ b/include/asm-powerpc/string.h @@ -1,5 +1,5 @@ -#ifndef _PPC_STRING_H_ -#define _PPC_STRING_H_ +#ifndef _ASM_POWERPC_STRING_H +#define _ASM_POWERPC_STRING_H #ifdef __KERNEL__ @@ -29,4 +29,4 @@ extern void * memchr(const void *,int,__kernel_size_t); #endif /* __KERNEL__ */ -#endif +#endif /* _ASM_POWERPC_STRING_H */ diff --git a/include/asm-powerpc/termbits.h b/include/asm-powerpc/termbits.h index 2c5bf85a8c3c..ebf6055481dc 100644 --- a/include/asm-powerpc/termbits.h +++ b/include/asm-powerpc/termbits.h @@ -1,5 +1,5 @@ -#ifndef _POWERPC_TERMBITS_H -#define _POWERPC_TERMBITS_H +#ifndef _ASM_POWERPC_TERMBITS_H +#define _ASM_POWERPC_TERMBITS_H /* * This program is free software; you can redistribute it and/or @@ -188,4 +188,4 @@ struct termios { #define TCSADRAIN 1 #define TCSAFLUSH 2 -#endif /* _POWERPC_TERMBITS_H */ +#endif /* _ASM_POWERPC_TERMBITS_H */ diff --git a/include/asm-powerpc/termios.h b/include/asm-powerpc/termios.h index 237533bb0e9f..c5b8e5358f83 100644 --- a/include/asm-powerpc/termios.h +++ b/include/asm-powerpc/termios.h @@ -1,5 +1,5 @@ -#ifndef _POWERPC_TERMIOS_H -#define _POWERPC_TERMIOS_H +#ifndef _ASM_POWERPC_TERMIOS_H +#define _ASM_POWERPC_TERMIOS_H /* * Liberally adapted from alpha/termios.h. In particular, the c_cc[] @@ -233,4 +233,4 @@ struct termio { #endif /* __KERNEL__ */ -#endif /* _POWERPC_TERMIOS_H */ +#endif /* _ASM_POWERPC_TERMIOS_H */ diff --git a/include/asm-powerpc/unaligned.h b/include/asm-powerpc/unaligned.h index 45520d9b85d1..6c95dfa2652f 100644 --- a/include/asm-powerpc/unaligned.h +++ b/include/asm-powerpc/unaligned.h @@ -1,6 +1,7 @@ +#ifndef _ASM_POWERPC_UNALIGNED_H +#define _ASM_POWERPC_UNALIGNED_H + #ifdef __KERNEL__ -#ifndef __PPC_UNALIGNED_H -#define __PPC_UNALIGNED_H /* * The PowerPC can do unaligned accesses itself in big endian mode. @@ -14,5 +15,5 @@ #define put_unaligned(val, ptr) ((void)( *(ptr) = (val) )) -#endif -#endif /* __KERNEL__ */ +#endif /* __KERNEL__ */ +#endif /* _ASM_POWERPC_UNALIGNED_H */ From 64807081e38703617cf9a5d71db14ea2b3e1cb04 Mon Sep 17 00:00:00 2001 From: "jdl@freescale.com" Date: Wed, 7 Sep 2005 15:56:20 -0500 Subject: [PATCH 05/14] [PATCH] powerpc: Make check_bugs() static inline Make check_bugs() static inline and remove it from syscalls.c. Signed-off-by: Jon Loeliger Signed-off-by: Kumar Gala Signed-off-by: Paul Mackerras --- arch/ppc/kernel/syscalls.c | 4 ---- arch/ppc64/kernel/syscalls.c | 4 ---- include/asm-powerpc/bugs.h | 2 +- 3 files changed, 1 insertion(+), 9 deletions(-) diff --git a/arch/ppc/kernel/syscalls.c b/arch/ppc/kernel/syscalls.c index 124313ce3c09..127f040de9de 100644 --- a/arch/ppc/kernel/syscalls.c +++ b/arch/ppc/kernel/syscalls.c @@ -41,10 +41,6 @@ #include #include -void -check_bugs(void) -{ -} /* * sys_ipc() is the de-multiplexer for the SysV IPC calls.. diff --git a/arch/ppc64/kernel/syscalls.c b/arch/ppc64/kernel/syscalls.c index a8cbb202b8cd..05f16633bd2c 100644 --- a/arch/ppc64/kernel/syscalls.c +++ b/arch/ppc64/kernel/syscalls.c @@ -46,10 +46,6 @@ extern unsigned long wall_jiffies; -void -check_bugs(void) -{ -} /* * sys_ipc() is the de-multiplexer for the SysV IPC calls.. diff --git a/include/asm-powerpc/bugs.h b/include/asm-powerpc/bugs.h index f5caee8558bf..42fdb73e3068 100644 --- a/include/asm-powerpc/bugs.h +++ b/include/asm-powerpc/bugs.h @@ -13,6 +13,6 @@ * architecture-dependent bugs. */ -extern void check_bugs(void); +static inline void check_bugs(void) { } #endif /* _ASM_POWERPC_BUGS_H */ From dd56fdf23dfa0127d512b73d4238dbd2b5a7c1eb Mon Sep 17 00:00:00 2001 From: "jdl@freescale.com" Date: Wed, 7 Sep 2005 15:59:48 -0500 Subject: [PATCH 06/14] [PATCH] powerpc: Merge a few more include files Merge a few asm-ppc and asm-ppc64 header files. Note: the merge of setup.h intentionally does not carry forward the m68k cruft. That means this patch continues to break the already broken amiga on the ppc32. Signed-off-by: Jon Loeliger Signed-off-by: Kumar Gala Signed-off-by: Paul Mackerras --- include/{asm-ppc => asm-powerpc}/msgbuf.h | 16 +++-- include/{asm-ppc => asm-powerpc}/param.h | 8 +-- include/asm-powerpc/setup.h | 9 +++ include/{asm-ppc => asm-powerpc}/timex.h | 39 ++++++++----- include/{asm-ppc64 => asm-powerpc}/topology.h | 9 +-- include/{asm-ppc => asm-powerpc}/user.h | 15 ++--- include/asm-ppc/setup.h | 14 ----- include/asm-ppc/topology.h | 6 -- include/asm-ppc64/msgbuf.h | 27 --------- include/asm-ppc64/param.h | 31 ---------- include/asm-ppc64/setup.h | 6 -- include/asm-ppc64/timex.h | 26 --------- include/asm-ppc64/user.h | 58 ------------------- 13 files changed, 62 insertions(+), 202 deletions(-) rename include/{asm-ppc => asm-powerpc}/msgbuf.h (64%) rename include/{asm-ppc => asm-powerpc}/param.h (70%) create mode 100644 include/asm-powerpc/setup.h rename include/{asm-ppc => asm-powerpc}/timex.h (53%) rename include/{asm-ppc64 => asm-powerpc}/topology.h (92%) rename include/{asm-ppc => asm-powerpc}/user.h (92%) delete mode 100644 include/asm-ppc/setup.h delete mode 100644 include/asm-ppc/topology.h delete mode 100644 include/asm-ppc64/msgbuf.h delete mode 100644 include/asm-ppc64/param.h delete mode 100644 include/asm-ppc64/setup.h delete mode 100644 include/asm-ppc64/timex.h delete mode 100644 include/asm-ppc64/user.h diff --git a/include/asm-ppc/msgbuf.h b/include/asm-powerpc/msgbuf.h similarity index 64% rename from include/asm-ppc/msgbuf.h rename to include/asm-powerpc/msgbuf.h index 1053452a9376..dd76743c7537 100644 --- a/include/asm-ppc/msgbuf.h +++ b/include/asm-powerpc/msgbuf.h @@ -1,17 +1,25 @@ -#ifndef _PPC_MSGBUF_H -#define _PPC_MSGBUF_H +#ifndef _ASM_POWERPC_MSGBUF_H +#define _ASM_POWERPC_MSGBUF_H /* - * The msqid64_ds structure for the PPC architecture. + * The msqid64_ds structure for the PowerPC architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. */ struct msqid64_ds { struct ipc64_perm msg_perm; +#ifndef __powerpc64__ unsigned int __unused1; +#endif __kernel_time_t msg_stime; /* last msgsnd time */ +#ifndef __powerpc64__ unsigned int __unused2; +#endif __kernel_time_t msg_rtime; /* last msgrcv time */ +#ifndef __powerpc64__ unsigned int __unused3; +#endif __kernel_time_t msg_ctime; /* last change time */ unsigned long msg_cbytes; /* current number of bytes on queue */ unsigned long msg_qnum; /* number of messages in queue */ @@ -22,4 +30,4 @@ struct msqid64_ds { unsigned long __unused5; }; -#endif /* _PPC_MSGBUF_H */ +#endif /* _ASM_POWERPC_MSGBUF_H */ diff --git a/include/asm-ppc/param.h b/include/asm-powerpc/param.h similarity index 70% rename from include/asm-ppc/param.h rename to include/asm-powerpc/param.h index 6198b1657a45..bdc724f70884 100644 --- a/include/asm-ppc/param.h +++ b/include/asm-powerpc/param.h @@ -1,10 +1,10 @@ -#ifndef _ASM_PPC_PARAM_H -#define _ASM_PPC_PARAM_H +#ifndef _ASM_POWERPC_PARAM_H +#define _ASM_POWERPC_PARAM_H #include #ifdef __KERNEL__ -#define HZ CONFIG_HZ /* internal timer frequency */ +#define HZ CONFIG_HZ /* internal kernel timer frequency */ #define USER_HZ 100 /* for user interfaces in "ticks" */ #define CLOCKS_PER_SEC (USER_HZ) /* frequency at which times() counts */ #endif /* __KERNEL__ */ @@ -21,4 +21,4 @@ #define MAXHOSTNAMELEN 64 /* max length of hostname */ -#endif +#endif /* _ASM_POWERPC_PARAM_H */ diff --git a/include/asm-powerpc/setup.h b/include/asm-powerpc/setup.h new file mode 100644 index 000000000000..3d9740aae018 --- /dev/null +++ b/include/asm-powerpc/setup.h @@ -0,0 +1,9 @@ +#ifndef _ASM_POWERPC_SETUP_H +#define _ASM_POWERPC_SETUP_H + +#ifdef __KERNEL__ + +#define COMMAND_LINE_SIZE 512 + +#endif /* __KERNEL__ */ +#endif /* _ASM_POWERPC_SETUP_H */ diff --git a/include/asm-ppc/timex.h b/include/asm-powerpc/timex.h similarity index 53% rename from include/asm-ppc/timex.h rename to include/asm-powerpc/timex.h index cffc8712077c..51c5b316be55 100644 --- a/include/asm-ppc/timex.h +++ b/include/asm-powerpc/timex.h @@ -1,11 +1,11 @@ -/* - * include/asm-ppc/timex.h - * - * ppc architecture timex specifications - */ +#ifndef _ASM_POWERPC_TIMEX_H +#define _ASM_POWERPC_TIMEX_H + #ifdef __KERNEL__ -#ifndef _ASMppc_TIMEX_H -#define _ASMppc_TIMEX_H + +/* + * PowerPC architecture timex specifications + */ #include #include @@ -14,14 +14,21 @@ typedef unsigned long cycles_t; -/* - * For the "cycle" counter we use the timebase lower half. - * Currently only used on SMP. - */ - static inline cycles_t get_cycles(void) { - cycles_t ret = 0; + cycles_t ret; + +#ifdef __powerpc64__ + + __asm__ __volatile__("mftb %0" : "=r" (ret) : ); + +#else + /* + * For the "cycle" counter we use the timebase lower half. + * Currently only used on SMP. + */ + + ret = 0; __asm__ __volatile__( "98: mftb %0\n" @@ -33,8 +40,10 @@ static inline cycles_t get_cycles(void) " .long 99b\n" ".previous" : "=r" (ret) : "i" (CPU_FTR_601)); +#endif + return ret; } -#endif -#endif /* __KERNEL__ */ +#endif /* __KERNEL__ */ +#endif /* _ASM_POWERPC_TIMEX_H */ diff --git a/include/asm-ppc64/topology.h b/include/asm-powerpc/topology.h similarity index 92% rename from include/asm-ppc64/topology.h rename to include/asm-powerpc/topology.h index 1e9b19073230..2512e3836bf4 100644 --- a/include/asm-ppc64/topology.h +++ b/include/asm-powerpc/topology.h @@ -1,11 +1,12 @@ -#ifndef _ASM_PPC64_TOPOLOGY_H -#define _ASM_PPC64_TOPOLOGY_H +#ifndef _ASM_POWERPC_TOPOLOGY_H +#define _ASM_POWERPC_TOPOLOGY_H #include -#include #ifdef CONFIG_NUMA +#include + static inline int cpu_to_node(int cpu) { int node; @@ -66,4 +67,4 @@ static inline int node_to_first_cpu(int node) #endif /* CONFIG_NUMA */ -#endif /* _ASM_PPC64_TOPOLOGY_H */ +#endif /* _ASM_POWERPC_TOPOLOGY_H */ diff --git a/include/asm-ppc/user.h b/include/asm-powerpc/user.h similarity index 92% rename from include/asm-ppc/user.h rename to include/asm-powerpc/user.h index d662b2151370..e59ade4b3dfb 100644 --- a/include/asm-ppc/user.h +++ b/include/asm-powerpc/user.h @@ -1,13 +1,14 @@ +#ifndef _ASM_POWERPC_USER_H +#define _ASM_POWERPC_USER_H + #ifdef __KERNEL__ -#ifndef _PPC_USER_H -#define _PPC_USER_H -/* Adapted from */ - -#include +#include #include /* + * Adapted from + * * Core file format: The core file is written in such a way that gdb * can understand it and provide useful information to the user (under * linux we use the `trad-core' bfd, NOT the osf-core). The file contents @@ -50,5 +51,5 @@ struct user { #define HOST_DATA_START_ADDR (u.start_data) #define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) -#endif /* _PPC_USER_H */ -#endif /* __KERNEL__ */ +#endif /* __KERNEL__ */ +#endif /* _ASM_POWERPC_USER_H */ diff --git a/include/asm-ppc/setup.h b/include/asm-ppc/setup.h deleted file mode 100644 index d2d19ee103df..000000000000 --- a/include/asm-ppc/setup.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifdef __KERNEL__ -#ifndef _PPC_SETUP_H -#define _PPC_SETUP_H - -#define m68k_num_memory num_memory -#define m68k_memory memory - -#include -/* We have a bigger command line buffer. */ -#undef COMMAND_LINE_SIZE -#define COMMAND_LINE_SIZE 512 - -#endif /* _PPC_SETUP_H */ -#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/topology.h b/include/asm-ppc/topology.h deleted file mode 100644 index 6a029bbba6e1..000000000000 --- a/include/asm-ppc/topology.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_PPC_TOPOLOGY_H -#define _ASM_PPC_TOPOLOGY_H - -#include - -#endif /* _ASM_PPC_TOPOLOGY_H */ diff --git a/include/asm-ppc64/msgbuf.h b/include/asm-ppc64/msgbuf.h deleted file mode 100644 index 31c1cbf133cc..000000000000 --- a/include/asm-ppc64/msgbuf.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef _PPC64_MSGBUF_H -#define _PPC64_MSGBUF_H - -/* - * The msqid64_ds structure for the PPC architecture. - * - * 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. - */ - -struct msqid64_ds { - struct ipc64_perm msg_perm; - __kernel_time_t msg_stime; /* last msgsnd time */ - __kernel_time_t msg_rtime; /* last msgrcv time */ - __kernel_time_t msg_ctime; /* last change time */ - unsigned long msg_cbytes; /* current number of bytes on queue */ - unsigned long msg_qnum; /* number of messages in queue */ - unsigned long msg_qbytes; /* max number of bytes on queue */ - __kernel_pid_t msg_lspid; /* pid of last msgsnd */ - __kernel_pid_t msg_lrpid; /* last receive pid */ - unsigned long __unused1; - unsigned long __unused2; -}; - -#endif /* _PPC64_MSGBUF_H */ diff --git a/include/asm-ppc64/param.h b/include/asm-ppc64/param.h deleted file mode 100644 index 76c212d475b3..000000000000 --- a/include/asm-ppc64/param.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef _ASM_PPC64_PARAM_H -#define _ASM_PPC64_PARAM_H - -#include - -/* - * 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. - */ - -#ifdef __KERNEL__ -# define HZ CONFIG_HZ /* Internal kernel timer frequency */ -# define USER_HZ 100 /* .. some user interfaces are in "ticks" */ -# define CLOCKS_PER_SEC (USER_HZ) /* like times() */ -#endif - -#ifndef HZ -#define HZ 100 -#endif - -#define EXEC_PAGESIZE 4096 - -#ifndef NOGROUP -#define NOGROUP (-1) -#endif - -#define MAXHOSTNAMELEN 64 /* max length of hostname */ - -#endif /* _ASM_PPC64_PARAM_H */ diff --git a/include/asm-ppc64/setup.h b/include/asm-ppc64/setup.h deleted file mode 100644 index b257b8348c73..000000000000 --- a/include/asm-ppc64/setup.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _PPC_SETUP_H -#define _PPC_SETUP_H - -#define COMMAND_LINE_SIZE 512 - -#endif /* _PPC_SETUP_H */ diff --git a/include/asm-ppc64/timex.h b/include/asm-ppc64/timex.h deleted file mode 100644 index 8db4da4064cd..000000000000 --- a/include/asm-ppc64/timex.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * linux/include/asm-ppc/timex.h - * - * PPC64 architecture timex specifications - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ -#ifndef _ASMPPC64_TIMEX_H -#define _ASMPPC64_TIMEX_H - -#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */ - -typedef unsigned long cycles_t; - -static inline cycles_t get_cycles(void) -{ - cycles_t ret; - - __asm__ __volatile__("mftb %0" : "=r" (ret) : ); - return ret; -} - -#endif diff --git a/include/asm-ppc64/user.h b/include/asm-ppc64/user.h deleted file mode 100644 index d7d6554a421f..000000000000 --- a/include/asm-ppc64/user.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef _PPC_USER_H -#define _PPC_USER_H - -/* Adapted from - * - * 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 -#include - -/* - * Core file format: The core file is written in such a way that gdb - * can understand it and provide useful information to the user (under - * linux we use the `trad-core' bfd, NOT the osf-core). The file contents - * are as follows: - * - * upage: 1 page consisting of a user struct that tells gdb - * what is present in the file. Directly after this is a - * copy of the task_struct, which is currently not used by gdb, - * but it may come in handy at some point. All of the registers - * are stored as part of the upage. The upage should always be - * only one page long. - * data: The data segment follows next. We use current->end_text to - * current->brk to pick up all of the user variables, plus any memory - * that may have been sbrk'ed. No attempt is made to determine if a - * page is demand-zero or if a page is totally unused, we just cover - * the entire range. All of the addresses are rounded in such a way - * that an integral number of pages is written. - * stack: We need the stack information in order to get a meaningful - * backtrace. We need to write the data from usp to - * current->start_stack, so we round each of these in order to be able - * to write an integer number of pages. - */ -struct user { - struct pt_regs regs; /* entire machine state */ - size_t u_tsize; /* text size (pages) */ - size_t u_dsize; /* data size (pages) */ - size_t u_ssize; /* stack size (pages) */ - unsigned long start_code; /* text starting address */ - unsigned long start_data; /* data starting address */ - unsigned long start_stack; /* stack starting address */ - long int signal; /* signal causing core dump */ - struct regs * u_ar0; /* help gdb find registers */ - unsigned long magic; /* identifies a core file */ - char u_comm[32]; /* user command name */ -}; - -#define NBPG PAGE_SIZE -#define UPAGES 1 -#define HOST_TEXT_START_ADDR (u.start_code) -#define HOST_DATA_START_ADDR (u.start_data) -#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) - -#endif /* _PPC_USER_H */ From a24c8481b6439cb151a4750cc278ea2df4fb0e53 Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Mon, 15 Aug 2005 13:59:13 -0700 Subject: [PATCH 07/14] [PATCH] ppc64: zimage build fix Signed-off-by: Geoff Levand Signed-off-by: Paul Mackerras --- arch/ppc64/Makefile | 21 ++++++++++++--------- arch/ppc64/boot/Makefile | 25 ++++++++++++++++++------- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/arch/ppc64/Makefile b/arch/ppc64/Makefile index 8189953a372c..a91daa324e88 100644 --- a/arch/ppc64/Makefile +++ b/arch/ppc64/Makefile @@ -89,11 +89,12 @@ drivers-$(CONFIG_OPROFILE) += arch/ppc64/oprofile/ boot := arch/ppc64/boot -boottarget-$(CONFIG_PPC_PSERIES) := zImage zImage.initrd -boottarget-$(CONFIG_PPC_MAPLE) := zImage zImage.initrd -boottarget-$(CONFIG_PPC_ISERIES) := vmlinux.sminitrd vmlinux.initrd vmlinux.sm -boottarget-$(CONFIG_PPC_BPA) := zImage zImage.initrd -$(boottarget-y): vmlinux +boottargets-$(CONFIG_PPC_PSERIES) += zImage zImage.initrd +boottargets-$(CONFIG_PPC_PMAC) += zImage.vmode zImage.initrd.vmode +boottargets-$(CONFIG_PPC_MAPLE) += zImage zImage.initrd +boottargets-$(CONFIG_PPC_ISERIES) += vmlinux.sminitrd vmlinux.initrd vmlinux.sm +boottargets-$(CONFIG_PPC_BPA) += zImage zImage.initrd +$(boottargets-y): vmlinux $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ bootimage-$(CONFIG_PPC_PSERIES) := $(boot)/zImage @@ -131,10 +132,12 @@ include3/asm: $(Q)ln -fsn $(srctree)/include/asm-powerpc include3/asm define archhelp - echo '* zImage - Compressed kernel image (arch/$(ARCH)/boot/zImage)' - echo ' zImage.initrd- Compressed kernel image with initrd attached,' - echo ' sourced from arch/$(ARCH)/boot/ramdisk.image.gz' - echo ' (arch/$(ARCH)/boot/zImage.initrd)' + echo ' zImage.vmode - Compressed kernel image (arch/$(ARCH)/boot/zImage.vmode)' + echo ' zImage.initrd.vmode - Compressed kernel image with initrd attached,' + echo ' sourced from arch/$(ARCH)/boot/ramdisk.image.gz' + echo ' (arch/$(ARCH)/boot/zImage.initrd.vmode)' + echo ' zImage - zImage for pSeries machines' + echo ' zImage.initrd - zImage with initrd for pSeries machines' endef CLEAN_FILES += include/asm-ppc64/offsets.h diff --git a/arch/ppc64/boot/Makefile b/arch/ppc64/boot/Makefile index 2c5f5e73d00c..d3567e47cbba 100644 --- a/arch/ppc64/boot/Makefile +++ b/arch/ppc64/boot/Makefile @@ -37,6 +37,9 @@ quiet_cmd_bootcc = BOOTCC $@ quiet_cmd_bootas = BOOTAS $@ cmd_bootas = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTAFLAGS) -c -o $@ $< +quiet_cmd_bootld = BOOTLD $@ + cmd_bootld = $(CROSS32LD) $(BOOTLFLAGS) -o $@ $(2) + $(patsubst %.c,%.o, $(filter %.c, $(src-boot))): %.o: %.c $(call if_changed_dep,bootcc) $(patsubst %.S,%.o, $(filter %.S, $(src-boot))): %.o: %.S @@ -53,7 +56,7 @@ src-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.c, $(section))) gz-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.gz, $(section))) hostprogs-y := addnote addRamDisk -targets += zImage zImage.initrd imagesize.c \ +targets += zImage.vmode zImage.initrd.vmode zImage zImage.initrd imagesize.c \ $(patsubst $(obj)/%,%, $(call obj-sec, $(required) $(initrd))) \ $(patsubst $(obj)/%,%, $(call src-sec, $(required) $(initrd))) \ $(patsubst $(obj)/%,%, $(call gz-sec, $(required) $(initrd))) \ @@ -75,8 +78,8 @@ addsection = $(CROSS32OBJCOPY) $(1) \ --add-section=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $(1)))=$(patsubst %.o,%.gz, $(1)) \ --set-section-flags=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $(1)))=$(OBJCOPYFLAGS) -quiet_cmd_addnote = ADDNOTE $@ - cmd_addnote = $(CROSS32LD) $(BOOTLFLAGS) -o $@ $(obj-boot) && $(obj)/addnote $@ +quiet_cmd_addnote = ADDNOTE $@ + cmd_addnote = $(obj)/addnote $@ $(call gz-sec, $(required)): $(obj)/kernel-%.gz: % FORCE $(call if_changed,gzip) @@ -91,12 +94,20 @@ $(call obj-sec, $(required) $(initrd)): $(obj)/kernel-%.o: $(obj)/kernel-%.c FOR $(call if_changed_dep,bootcc) $(call addsection, $@) -$(obj)/zImage: obj-boot += $(call obj-sec, $(required)) -$(obj)/zImage: $(call obj-sec, $(required)) $(obj-boot) $(obj)/addnote FORCE +$(obj)/zImage.vmode: obj-boot += $(call obj-sec, $(required)) +$(obj)/zImage.vmode: $(call obj-sec, $(required)) $(obj-boot) FORCE + $(call cmd,bootld,$(obj-boot)) + +$(obj)/zImage.initrd.vmode: obj-boot += $(call obj-sec, $(required) $(initrd)) +$(obj)/zImage.initrd.vmode: $(call obj-sec, $(required) $(initrd)) $(obj-boot) FORCE + $(call cmd,bootld,$(obj-boot)) + +$(obj)/zImage: $(obj)/zImage.vmode $(obj)/addnote FORCE + @cp -f $< $@ $(call if_changed,addnote) -$(obj)/zImage.initrd: obj-boot += $(call obj-sec, $(required) $(initrd)) -$(obj)/zImage.initrd: $(call obj-sec, $(required) $(initrd)) $(obj-boot) $(obj)/addnote FORCE +$(obj)/zImage.initrd: $(obj)/zImage.initrd.vmode $(obj)/addnote FORCE + @cp -f $< $@ $(call if_changed,addnote) $(obj)/imagesize.c: vmlinux.strip From e4df7671716f1fffb3437a7c1a14e3d2465fefef Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Wed, 10 Aug 2005 17:57:42 -0700 Subject: [PATCH 08/14] [PATCH] ppc64: makefile cleanup This patch cleans up the output generated by ppc64 builds. Signed-off-by: Geoff Levand Signed-off-by: Paul Mackerras --- arch/ppc64/boot/Makefile | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/arch/ppc64/boot/Makefile b/arch/ppc64/boot/Makefile index d3567e47cbba..33fdc8710891 100644 --- a/arch/ppc64/boot/Makefile +++ b/arch/ppc64/boot/Makefile @@ -66,7 +66,7 @@ extra-y := initrd.o quiet_cmd_ramdisk = RAMDISK $@ cmd_ramdisk = $(obj)/addRamDisk $(obj)/ramdisk.image.gz $< $@ -quiet_cmd_stripvm = STRIP $@ +quiet_cmd_stripvm = STRIP $@ cmd_stripvm = $(STRIP) -s $< -o $@ vmlinux.strip: vmlinux FORCE @@ -74,9 +74,17 @@ vmlinux.strip: vmlinux FORCE $(obj)/vmlinux.initrd: vmlinux.strip $(obj)/addRamDisk $(obj)/ramdisk.image.gz FORCE $(call if_changed,ramdisk) -addsection = $(CROSS32OBJCOPY) $(1) \ - --add-section=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $(1)))=$(patsubst %.o,%.gz, $(1)) \ - --set-section-flags=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $(1)))=$(OBJCOPYFLAGS) +quiet_cmd_addsection = ADDSEC $@ + cmd_addsection = $(CROSS32OBJCOPY) $@ \ + --add-section=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $@))=$(patsubst %.o,%.gz, $@) \ + --set-section-flags=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $@))=$(OBJCOPYFLAGS) + +quiet_cmd_imagesize = GENSIZE $@ + cmd_imagesize = ls -l vmlinux.strip | \ + awk '{printf "/* generated -- do not edit! */\n" "unsigned long vmlinux_filesize = %d;\n", $$5}' \ + > $(obj)/imagesize.c && \ + $(CROSS_COMPILE)nm -n vmlinux | tail -n 1 | \ + awk '{printf "unsigned long vmlinux_memsize = 0x%s;\n", substr($$1,8)}' >> $(obj)/imagesize.c quiet_cmd_addnote = ADDNOTE $@ cmd_addnote = $(obj)/addnote $@ @@ -88,11 +96,11 @@ $(obj)/kernel-initrd.gz: $(obj)/ramdisk.image.gz cp -f $(obj)/ramdisk.image.gz $@ $(call src-sec, $(required) $(initrd)): $(obj)/kernel-%.c: $(obj)/kernel-%.gz FORCE - touch $@ + @touch $@ $(call obj-sec, $(required) $(initrd)): $(obj)/kernel-%.o: $(obj)/kernel-%.c FORCE $(call if_changed_dep,bootcc) - $(call addsection, $@) + $(call cmd,addsection) $(obj)/zImage.vmode: obj-boot += $(call obj-sec, $(required)) $(obj)/zImage.vmode: $(call obj-sec, $(required)) $(obj-boot) FORCE @@ -111,13 +119,7 @@ $(obj)/zImage.initrd: $(obj)/zImage.initrd.vmode $(obj)/addnote FORCE $(call if_changed,addnote) $(obj)/imagesize.c: vmlinux.strip - @echo Generating $@ - ls -l vmlinux.strip | \ - awk '{printf "/* generated -- do not edit! */\n" \ - "unsigned long vmlinux_filesize = %d;\n", $$5}' > $(obj)/imagesize.c - $(CROSS_COMPILE)nm -n vmlinux | tail -n 1 | \ - awk '{printf "unsigned long vmlinux_memsize = 0x%s;\n", substr($$1,8)}' \ - >> $(obj)/imagesize.c + $(call cmd,imagesize) install: $(CONFIGURE) $(BOOTIMAGE) sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" "$(BOOTIMAGE)" From f9526785d8a03fd0e21f9cfc951adc03bde1c395 Mon Sep 17 00:00:00 2001 From: "jdl@freescale.com" Date: Thu, 8 Sep 2005 14:05:49 -0500 Subject: [PATCH 09/14] [PATCH] powerpc: Fix __power64__ typos that should be __powerpc64__ Fix __power64__ typo that should be __powerpc64__ instead. Signed-off-by: Jon Loeliger Signed-off-by: Kumar Gala Signed-off-by: Paul Mackerras --- include/asm-powerpc/shmbuf.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/asm-powerpc/shmbuf.h b/include/asm-powerpc/shmbuf.h index dca582a4f68d..8efa39698b6c 100644 --- a/include/asm-powerpc/shmbuf.h +++ b/include/asm-powerpc/shmbuf.h @@ -21,19 +21,19 @@ struct shmid64_ds { struct ipc64_perm shm_perm; /* operation perms */ -#ifndef __power64__ +#ifndef __powerpc64__ unsigned long __unused1; #endif __kernel_time_t shm_atime; /* last attach time */ -#ifndef __power64__ +#ifndef __powerpc64__ unsigned long __unused2; #endif __kernel_time_t shm_dtime; /* last detach time */ -#ifndef __power64__ +#ifndef __powerpc64__ unsigned long __unused3; #endif __kernel_time_t shm_ctime; /* last change time */ -#ifndef __power64__ +#ifndef __powerpc64__ unsigned long __unused4; #endif size_t shm_segsz; /* size of segment (bytes) */ From 3cc747e96480d4e26560e5bc59f2b9c9204ade0e Mon Sep 17 00:00:00 2001 From: Mark Bellon Date: Tue, 6 Sep 2005 15:50:02 -0700 Subject: [PATCH 10/14] [PATCH] PPC64: large INITRD causes kernel not to boot In PPC64 there are number of problems in arch/ppc64/boot/main.c that prevent a kernel from making use of a large (greater than ~16MB) INITRD. This is 64 bit architecture and really large INITRD images should be possible. Simply put the existing code has a fixed reservation (claim) address and once the kernel plus initrd image are large enough to pass this address all sorts of bad things occur. The fix is the dynamically establish the first claim address above the loaded kernel plus initrd (plus some "padding" and rounding). If PROG_START is defined this will be used as the minimum safe address - currently known to be 0x01400000 for the firmwares tested so far. Signed-off-by: Mark Bellon Signed-off-by: Paul Mackerras --- arch/ppc64/boot/main.c | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/arch/ppc64/boot/main.c b/arch/ppc64/boot/main.c index 99e68cfbe688..f7ec19a2d0b0 100644 --- a/arch/ppc64/boot/main.c +++ b/arch/ppc64/boot/main.c @@ -23,7 +23,8 @@ extern void flush_cache(void *, unsigned long); /* Value picked to match that used by yaboot */ #define PROG_START 0x01400000 -#define RAM_END (256<<20) // Fixme: use OF */ +#define RAM_END (512<<20) // Fixme: use OF */ +#define ONE_MB 0x100000 static char *avail_ram; static char *begin_avail, *end_avail; @@ -32,6 +33,7 @@ static unsigned int heap_use; static unsigned int heap_max; extern char _start[]; +extern char _end[]; extern char _vmlinux_start[]; extern char _vmlinux_end[]; extern char _initrd_start[]; @@ -58,13 +60,13 @@ typedef void (*kernel_entry_t)( unsigned long, #undef DEBUG -static unsigned long claim_base = PROG_START; +static unsigned long claim_base; static unsigned long try_claim(unsigned long size) { unsigned long addr = 0; - for(; claim_base < RAM_END; claim_base += 0x100000) { + for(; claim_base < RAM_END; claim_base += ONE_MB) { #ifdef DEBUG printf(" trying: 0x%08lx\n\r", claim_base); #endif @@ -95,7 +97,26 @@ void start(unsigned long a1, unsigned long a2, void *promptr) if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4) exit(); - printf("\n\rzImage starting: loaded at 0x%x\n\r", (unsigned)_start); + printf("\n\rzImage starting: loaded at 0x%lx\n\r", (unsigned long) _start); + + /* + * 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); + +#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 /* * Now we try to claim some memory for the kernel itself @@ -105,7 +126,7 @@ void start(unsigned long a1, unsigned long a2, void *promptr) * size... In practice we add 1Mb, that is enough, but we should really * consider fixing the Makefile to put a _raw_ kernel in there ! */ - vmlinux_memsize += 0x100000; + vmlinux_memsize += ONE_MB; printf("Allocating 0x%lx bytes for kernel ...\n\r", vmlinux_memsize); vmlinux.addr = try_claim(vmlinux_memsize); if (vmlinux.addr == 0) { From b28d2582ce8aafe531d909bb9c4dcf29189e786e Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Wed, 24 Aug 2005 11:56:56 -0500 Subject: [PATCH 11/14] [PATCH] ppc64: remove use of asm/segment.h Remove asm-ppc64/segment.h now that all users are gone. Signed-off-by: Kumar Gala Signed-off-by: Paul Mackerras --- include/asm-ppc64/segment.h | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 include/asm-ppc64/segment.h diff --git a/include/asm-ppc64/segment.h b/include/asm-ppc64/segment.h deleted file mode 100644 index d80fb68cc79e..000000000000 --- a/include/asm-ppc64/segment.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __PPC64_SEGMENT_H -#define __PPC64_SEGMENT_H - -/* Only here because we have some old header files that expect it.. */ - -#endif /* __PPC64_SEGMENT_H */ From 1635317facea3094ddf34082cd86797efb1d9f7e Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 6 Sep 2005 13:17:54 +1000 Subject: [PATCH 12/14] [PATCH] Separate pci bits out of struct device_node This patch pulls the PCI-related junk out of struct device_node and puts it in a separate structure, struct pci_dn. The device_node now just has a void * pointer in it, which points to a struct pci_dn for nodes that represent PCI devices. It could potentially be used in future for device-specific data for other sorts of devices, such as virtual I/O devices. Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/eeh.c | 55 +++++++++++++--------- arch/ppc64/kernel/iommu.c | 3 +- arch/ppc64/kernel/maple_pci.c | 4 +- arch/ppc64/kernel/pSeries_iommu.c | 72 ++++++++++++++++------------- arch/ppc64/kernel/pci.c | 6 ++- arch/ppc64/kernel/pci.h | 1 - arch/ppc64/kernel/pci_dn.c | 45 ++++++++++++------ arch/ppc64/kernel/pci_iommu.c | 2 +- arch/ppc64/kernel/pmac_feature.c | 8 ++-- arch/ppc64/kernel/pmac_pci.c | 6 +-- arch/ppc64/kernel/prom.c | 1 + arch/ppc64/kernel/rtas_pci.c | 39 +++++++++------- arch/ppc64/kernel/sys_ppc32.c | 4 +- arch/ppc64/kernel/u3_iommu.c | 4 +- drivers/pci/hotplug/rpadlpar_core.c | 20 ++++---- drivers/pci/hotplug/rpaphp_pci.c | 8 ++-- drivers/video/offb.c | 2 +- include/asm-ppc64/pci-bridge.h | 45 +++++++++++++++--- include/asm-ppc64/prom.h | 19 +------- 19 files changed, 208 insertions(+), 136 deletions(-) diff --git a/arch/ppc64/kernel/eeh.c b/arch/ppc64/kernel/eeh.c index 4c857a6516fc..ba93fd731222 100644 --- a/arch/ppc64/kernel/eeh.c +++ b/arch/ppc64/kernel/eeh.c @@ -254,6 +254,7 @@ pci_addr_cache_insert(struct pci_dev *dev, unsigned long alo, static void __pci_addr_cache_insert_device(struct pci_dev *dev) { struct device_node *dn; + struct pci_dn *pdn; int i; int inserted = 0; @@ -265,8 +266,9 @@ static void __pci_addr_cache_insert_device(struct pci_dev *dev) } /* Skip any devices for which EEH is not enabled. */ - if (!(dn->eeh_mode & EEH_MODE_SUPPORTED) || - dn->eeh_mode & EEH_MODE_NOCHECK) { + pdn = dn->data; + if (!(pdn->eeh_mode & EEH_MODE_SUPPORTED) || + pdn->eeh_mode & EEH_MODE_NOCHECK) { #ifdef DEBUG printk(KERN_INFO "PCI: skip building address cache for=%s\n", pci_name(dev)); @@ -415,6 +417,7 @@ int eeh_unregister_notifier(struct notifier_block *nb) static int read_slot_reset_state(struct device_node *dn, int rets[]) { int token, outputs; + struct pci_dn *pdn = dn->data; if (ibm_read_slot_reset_state2 != RTAS_UNKNOWN_SERVICE) { token = ibm_read_slot_reset_state2; @@ -424,8 +427,8 @@ static int read_slot_reset_state(struct device_node *dn, int rets[]) outputs = 3; } - return rtas_call(token, 3, outputs, rets, dn->eeh_config_addr, - BUID_HI(dn->phb->buid), BUID_LO(dn->phb->buid)); + return rtas_call(token, 3, outputs, rets, pdn->eeh_config_addr, + BUID_HI(pdn->phb->buid), BUID_LO(pdn->phb->buid)); } /** @@ -534,6 +537,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev) unsigned long flags; int rc, reset_state; struct eeh_event *event; + struct pci_dn *pdn; __get_cpu_var(total_mmio_ffs)++; @@ -542,14 +546,15 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev) if (!dn) return 0; + pdn = dn->data; /* Access to IO BARs might get this far and still not want checking. */ - if (!(dn->eeh_mode & EEH_MODE_SUPPORTED) || - dn->eeh_mode & EEH_MODE_NOCHECK) { + if (!pdn->eeh_capable || !(pdn->eeh_mode & EEH_MODE_SUPPORTED) || + pdn->eeh_mode & EEH_MODE_NOCHECK) { return 0; } - if (!dn->eeh_config_addr) { + if (!pdn->eeh_config_addr) { return 0; } @@ -557,7 +562,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev) * If we already have a pending isolation event for this * slot, we know it's bad already, we don't need to check... */ - if (dn->eeh_mode & EEH_MODE_ISOLATED) { + if (pdn->eeh_mode & EEH_MODE_ISOLATED) { atomic_inc(&eeh_fail_count); if (atomic_read(&eeh_fail_count) >= EEH_MAX_FAILS) { /* re-read the slot reset state */ @@ -582,7 +587,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev) } /* prevent repeated reports of this failure */ - dn->eeh_mode |= EEH_MODE_ISOLATED; + pdn->eeh_mode |= EEH_MODE_ISOLATED; reset_state = rets[0]; @@ -590,9 +595,9 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev) memset(slot_errbuf, 0, eeh_error_buf_size); rc = rtas_call(ibm_slot_error_detail, - 8, 1, NULL, dn->eeh_config_addr, - BUID_HI(dn->phb->buid), - BUID_LO(dn->phb->buid), NULL, 0, + 8, 1, NULL, pdn->eeh_config_addr, + BUID_HI(pdn->phb->buid), + BUID_LO(pdn->phb->buid), NULL, 0, virt_to_phys(slot_errbuf), eeh_error_buf_size, 1 /* Temporary Error */); @@ -679,8 +684,9 @@ static void *early_enable_eeh(struct device_node *dn, void *data) u32 *device_id = (u32 *)get_property(dn, "device-id", NULL); u32 *regs; int enable; + struct pci_dn *pdn = dn->data; - dn->eeh_mode = 0; + pdn->eeh_mode = 0; if (status && strcmp(status, "ok") != 0) return NULL; /* ignore devices with bad status */ @@ -691,7 +697,7 @@ static void *early_enable_eeh(struct device_node *dn, void *data) /* There is nothing to check on PCI to ISA bridges */ if (dn->type && !strcmp(dn->type, "isa")) { - dn->eeh_mode |= EEH_MODE_NOCHECK; + pdn->eeh_mode |= EEH_MODE_NOCHECK; return NULL; } @@ -708,7 +714,7 @@ static void *early_enable_eeh(struct device_node *dn, void *data) enable = 0; if (!enable) - dn->eeh_mode |= EEH_MODE_NOCHECK; + pdn->eeh_mode |= EEH_MODE_NOCHECK; /* 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. */ @@ -721,8 +727,8 @@ static void *early_enable_eeh(struct device_node *dn, void *data) EEH_ENABLE); if (ret == 0) { eeh_subsystem_enabled = 1; - dn->eeh_mode |= EEH_MODE_SUPPORTED; - dn->eeh_config_addr = regs[0]; + pdn->eeh_mode |= EEH_MODE_SUPPORTED; + pdn->eeh_config_addr = regs[0]; #ifdef DEBUG printk(KERN_DEBUG "EEH: %s: eeh enabled\n", dn->full_name); #endif @@ -730,10 +736,11 @@ static void *early_enable_eeh(struct device_node *dn, void *data) /* This device doesn't support EEH, but it may have an * EEH parent, in which case we mark it as supported. */ - if (dn->parent && (dn->parent->eeh_mode & EEH_MODE_SUPPORTED)) { + if (dn->parent && dn->parent->data + && (PCI_DN(dn->parent)->eeh_mode & EEH_MODE_SUPPORTED)) { /* Parent supports EEH. */ - dn->eeh_mode |= EEH_MODE_SUPPORTED; - dn->eeh_config_addr = dn->parent->eeh_config_addr; + pdn->eeh_mode |= EEH_MODE_SUPPORTED; + pdn->eeh_config_addr = PCI_DN(dn->parent)->eeh_config_addr; return NULL; } } @@ -790,11 +797,13 @@ void __init eeh_init(void) for (phb = of_find_node_by_name(NULL, "pci"); phb; phb = of_find_node_by_name(phb, "pci")) { unsigned long buid; + struct pci_dn *pci; buid = get_phb_buid(phb); - if (buid == 0) + if (buid == 0 || phb->data == NULL) continue; + pci = phb->data; info.buid_lo = BUID_LO(buid); info.buid_hi = BUID_HI(buid); traverse_pci_devices(phb, early_enable_eeh, &info); @@ -823,9 +832,9 @@ void eeh_add_device_early(struct device_node *dn) struct pci_controller *phb; struct eeh_early_enable_info info; - if (!dn) + if (!dn || !dn->data) return; - phb = dn->phb; + phb = PCI_DN(dn)->phb; if (NULL == phb || 0 == phb->buid) { printk(KERN_WARNING "EEH: Expected buid but found none\n"); return; diff --git a/arch/ppc64/kernel/iommu.c b/arch/ppc64/kernel/iommu.c index 845eebd1e28d..9032b6bfe036 100644 --- a/arch/ppc64/kernel/iommu.c +++ b/arch/ppc64/kernel/iommu.c @@ -438,7 +438,8 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl) void iommu_free_table(struct device_node *dn) { - struct iommu_table *tbl = dn->iommu_table; + struct pci_dn *pdn = dn->data; + struct iommu_table *tbl = pdn->iommu_table; unsigned long bitmap_sz, i; unsigned int order; diff --git a/arch/ppc64/kernel/maple_pci.c b/arch/ppc64/kernel/maple_pci.c index 53993999b265..5a8b4d8c2dd6 100644 --- a/arch/ppc64/kernel/maple_pci.c +++ b/arch/ppc64/kernel/maple_pci.c @@ -447,9 +447,9 @@ void __init maple_pci_init(void) */ if (u3_agp) { struct device_node *np = u3_agp->arch_data; - np->busno = 0xf0; + PCI_DN(np)->busno = 0xf0; for (np = np->child; np; np = np->sibling) - np->busno = 0xf0; + PCI_DN(np)->busno = 0xf0; } /* Tell pci.c to use the common resource allocation mecanism */ diff --git a/arch/ppc64/kernel/pSeries_iommu.c b/arch/ppc64/kernel/pSeries_iommu.c index 9d5e1e7fc389..f0fd7fbd6531 100644 --- a/arch/ppc64/kernel/pSeries_iommu.c +++ b/arch/ppc64/kernel/pSeries_iommu.c @@ -295,7 +295,7 @@ static void iommu_table_setparms_lpar(struct pci_controller *phb, struct iommu_table *tbl, unsigned int *dma_window) { - tbl->it_busno = dn->bussubno; + tbl->it_busno = PCI_DN(dn)->bussubno; /* TODO: Parse field size properties properly. */ tbl->it_size = (((unsigned long)dma_window[4] << 32) | @@ -311,6 +311,7 @@ static void iommu_table_setparms_lpar(struct pci_controller *phb, static void iommu_bus_setup_pSeries(struct pci_bus *bus) { struct device_node *dn, *pdn; + struct pci_dn *pci; struct iommu_table *tbl; DBG("iommu_bus_setup_pSeries, bus %p, bus->self %p\n", bus, bus->self); @@ -325,6 +326,7 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus) */ dn = pci_bus_to_OF_node(bus); + pci = dn->data; if (!bus->self) { /* Root bus */ @@ -341,18 +343,18 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus) * alltogether. This leaves 768MB for the window. */ DBG("PHB has io-hole, reserving 256MB\n"); - dn->phb->dma_window_size = 3 << 28; - dn->phb->dma_window_base_cur = 1 << 28; + pci->phb->dma_window_size = 3 << 28; + pci->phb->dma_window_base_cur = 1 << 28; } else { /* 1GB window by default */ - dn->phb->dma_window_size = 1 << 30; - dn->phb->dma_window_base_cur = 0; + pci->phb->dma_window_size = 1 << 30; + pci->phb->dma_window_base_cur = 0; } tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); - iommu_table_setparms(dn->phb, dn, tbl); - dn->iommu_table = iommu_init_table(tbl); + iommu_table_setparms(pci->phb, dn, tbl); + pci->iommu_table = iommu_init_table(tbl); } else { /* Do a 128MB table at root. This is used for the IDE * controller on some SMP-mode POWER4 machines. It @@ -363,16 +365,16 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus) * Allocate at offset 128MB to avoid having to deal * with ISA holes; 128MB table for IDE is plenty. */ - dn->phb->dma_window_size = 1 << 27; - dn->phb->dma_window_base_cur = 1 << 27; + pci->phb->dma_window_size = 1 << 27; + pci->phb->dma_window_base_cur = 1 << 27; tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); - iommu_table_setparms(dn->phb, dn, tbl); - dn->iommu_table = iommu_init_table(tbl); + iommu_table_setparms(pci->phb, dn, tbl); + pci->iommu_table = iommu_init_table(tbl); /* All child buses have 256MB tables */ - dn->phb->dma_window_size = 1 << 28; + pci->phb->dma_window_size = 1 << 28; } } else { pdn = pci_bus_to_OF_node(bus->parent); @@ -386,12 +388,12 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus) tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); - iommu_table_setparms(dn->phb, dn, tbl); + iommu_table_setparms(pci->phb, dn, tbl); - dn->iommu_table = iommu_init_table(tbl); + pci->iommu_table = iommu_init_table(tbl); } else { /* Lower than first child or under python, use parent table */ - dn->iommu_table = pdn->iommu_table; + pci->iommu_table = PCI_DN(pdn)->iommu_table; } } } @@ -401,6 +403,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 int *dma_window = NULL; DBG("iommu_bus_setup_pSeriesLP, bus %p, bus->self %p\n", bus, bus->self); @@ -419,22 +422,24 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus) return; } - if (!pdn->iommu_table) { + ppci = pdn->data; + if (!ppci->iommu_table) { /* Bussubno hasn't been copied yet. * Do it now because iommu_table_setparms_lpar needs it. */ - pdn->bussubno = bus->number; + + ppci->bussubno = bus->number; tbl = (struct iommu_table *)kmalloc(sizeof(struct iommu_table), GFP_KERNEL); - iommu_table_setparms_lpar(pdn->phb, pdn, tbl, dma_window); + iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window); - pdn->iommu_table = iommu_init_table(tbl); + ppci->iommu_table = iommu_init_table(tbl); } if (pdn != dn) - dn->iommu_table = pdn->iommu_table; + PCI_DN(dn)->iommu_table = ppci->iommu_table; } @@ -449,11 +454,11 @@ static void iommu_dev_setup_pSeries(struct pci_dev *dev) */ mydn = dn = pci_device_to_OF_node(dev); - while (dn && dn->iommu_table == NULL) + while (dn && dn->data && PCI_DN(dn)->iommu_table == NULL) dn = dn->parent; - if (dn) { - mydn->iommu_table = dn->iommu_table; + if (dn && dn->data) { + PCI_DN(mydn)->iommu_table = PCI_DN(dn)->iommu_table; } else { DBG("iommu_dev_setup_pSeries, dev %p (%s) has no iommu table\n", dev, dev->pretty_name); } @@ -463,10 +468,11 @@ static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long acti { int err = NOTIFY_OK; struct device_node *np = node; + struct pci_dn *pci = np->data; switch (action) { case PSERIES_RECONFIG_REMOVE: - if (np->iommu_table && + if (pci->iommu_table && get_property(np, "ibm,dma-window", NULL)) iommu_free_table(np); break; @@ -486,6 +492,7 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev) struct device_node *pdn, *dn; struct iommu_table *tbl; int *dma_window = NULL; + struct pci_dn *pci; DBG("iommu_dev_setup_pSeriesLP, dev %p (%s)\n", dev, dev->pretty_name); @@ -497,8 +504,10 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev) */ dn = pci_device_to_OF_node(dev); - for (pdn = dn; pdn && !pdn->iommu_table; pdn = pdn->parent) { - dma_window = (unsigned int *)get_property(pdn, "ibm,dma-window", NULL); + for (pdn = dn; pdn && pdn->data && !PCI_DN(pdn)->iommu_table; + pdn = pdn->parent) { + dma_window = (unsigned int *) + get_property(pdn, "ibm,dma-window", NULL); if (dma_window) break; } @@ -515,20 +524,21 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev) DBG("Found DMA window, allocating table\n"); } - if (!pdn->iommu_table) { + pci = pdn->data; + if (!pci->iommu_table) { /* iommu_table_setparms_lpar needs bussubno. */ - pdn->bussubno = pdn->phb->bus->number; + pci->bussubno = pci->phb->bus->number; tbl = (struct iommu_table *)kmalloc(sizeof(struct iommu_table), GFP_KERNEL); - iommu_table_setparms_lpar(pdn->phb, pdn, tbl, dma_window); + iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window); - pdn->iommu_table = iommu_init_table(tbl); + pci->iommu_table = iommu_init_table(tbl); } if (pdn != dn) - dn->iommu_table = pdn->iommu_table; + PCI_DN(dn)->iommu_table = pci->iommu_table; } static void iommu_bus_setup_null(struct pci_bus *b) { } diff --git a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c index b5ca7d8347e2..446b4654883f 100644 --- a/arch/ppc64/kernel/pci.c +++ b/arch/ppc64/kernel/pci.c @@ -837,9 +837,11 @@ int pcibios_scan_all_fns(struct pci_bus *bus, int devfn) * device tree. If they are then we need to scan all the * functions of this slot. */ - for (dn = busdn->child; dn; dn = dn->sibling) - if ((dn->devfn >> 3) == (devfn >> 3)) + for (dn = busdn->child; dn; dn = dn->sibling) { + struct pci_dn *pdn = dn->data; + if (pdn && (pdn->devfn >> 3) == (devfn >> 3)) return 1; + } return 0; } diff --git a/arch/ppc64/kernel/pci.h b/arch/ppc64/kernel/pci.h index 26be78b13af1..5eb2cc320566 100644 --- a/arch/ppc64/kernel/pci.h +++ b/arch/ppc64/kernel/pci.h @@ -34,7 +34,6 @@ void *traverse_pci_devices(struct device_node *start, traverse_func pre, void pci_devs_phb_init(void); void pci_devs_phb_init_dynamic(struct pci_controller *phb); -struct device_node *fetch_dev_dn(struct pci_dev *dev); /* PCI address cache management routines */ void pci_addr_cache_insert_device(struct pci_dev *dev); diff --git a/arch/ppc64/kernel/pci_dn.c b/arch/ppc64/kernel/pci_dn.c index ec345462afc3..a86389d07d57 100644 --- a/arch/ppc64/kernel/pci_dn.c +++ b/arch/ppc64/kernel/pci_dn.c @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include #include @@ -40,16 +42,26 @@ 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; + struct pci_dn *pdn; - dn->phb = phb; + if (phb->is_dynamic) + pdn = kmalloc(sizeof(*pdn), GFP_KERNEL); + else + pdn = alloc_bootmem(sizeof(*pdn)); + if (pdn == NULL) + return NULL; + memset(pdn, 0, sizeof(*pdn)); + dn->data = pdn; + pdn->node = dn; + pdn->phb = phb; regs = (u32 *)get_property(dn, "reg", NULL); if (regs) { /* First register entry is addr (00BBSS00) */ - dn->busno = (regs[0] >> 16) & 0xff; - dn->devfn = (regs[0] >> 8) & 0xff; + pdn->busno = (regs[0] >> 16) & 0xff; + pdn->devfn = (regs[0] >> 8) & 0xff; } - dn->pci_ext_config_space = (type && *type == 1); + pdn->pci_ext_config_space = (type && *type == 1); return NULL; } @@ -112,10 +124,15 @@ void *traverse_pci_devices(struct device_node *start, traverse_func pre, void __devinit pci_devs_phb_init_dynamic(struct pci_controller *phb) { struct device_node * dn = (struct device_node *) phb->arch_data; + struct pci_dn *pdn; /* PHB nodes themselves must not match */ - dn->devfn = dn->busno = -1; - dn->phb = phb; + update_dn_pci_info(dn, phb); + pdn = dn->data; + if (pdn) { + pdn->devfn = pdn->busno = -1; + pdn->phb = phb; + } /* Update dn->phb ptrs for new phb and children devices */ traverse_pci_devices(dn, update_dn_pci_info, phb); @@ -123,14 +140,17 @@ void __devinit pci_devs_phb_init_dynamic(struct pci_controller *phb) /* * Traversal func that looks for a value. - * If found, the device_node is returned (thus terminating the traversal). + * If found, the pci_dn is returned (thus terminating the traversal). */ static void *is_devfn_node(struct device_node *dn, void *data) { int busno = ((unsigned long)data >> 8) & 0xff; int devfn = ((unsigned long)data) & 0xff; + struct pci_dn *pci = dn->data; - return ((devfn == dn->devfn) && (busno == dn->busno)) ? dn : NULL; + if (pci && (devfn == pci->devfn) && (busno == pci->busno)) + return dn; + return NULL; } /* @@ -149,13 +169,10 @@ static void *is_devfn_node(struct device_node *dn, void *data) struct device_node *fetch_dev_dn(struct pci_dev *dev) { struct device_node *orig_dn = dev->sysdata; - struct pci_controller *phb = orig_dn->phb; /* assume same phb as orig_dn */ - struct device_node *phb_dn; struct device_node *dn; unsigned long searchval = (dev->bus->number << 8) | dev->devfn; - phb_dn = phb->arch_data; - dn = traverse_pci_devices(phb_dn, is_devfn_node, (void *)searchval); + dn = traverse_pci_devices(orig_dn, is_devfn_node, (void *)searchval); if (dn) dev->sysdata = dn; return dn; @@ -165,11 +182,13 @@ EXPORT_SYMBOL(fetch_dev_dn); static int pci_dn_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node) { struct device_node *np = node; + struct pci_dn *pci; int err = NOTIFY_OK; switch (action) { case PSERIES_RECONFIG_ADD: - update_dn_pci_info(np, np->parent->phb); + pci = np->parent->data; + update_dn_pci_info(np, pci->phb); break; default: err = NOTIFY_DONE; diff --git a/arch/ppc64/kernel/pci_iommu.c b/arch/ppc64/kernel/pci_iommu.c index ef0a62b916be..14647e09c9cd 100644 --- a/arch/ppc64/kernel/pci_iommu.c +++ b/arch/ppc64/kernel/pci_iommu.c @@ -66,7 +66,7 @@ static inline struct iommu_table *devnode_table(struct device *dev) #endif /* CONFIG_PPC_ISERIES */ #ifdef CONFIG_PPC_MULTIPLATFORM - return PCI_GET_DN(pdev)->iommu_table; + return PCI_DN(PCI_GET_DN(pdev))->iommu_table; #endif /* CONFIG_PPC_MULTIPLATFORM */ } diff --git a/arch/ppc64/kernel/pmac_feature.c b/arch/ppc64/kernel/pmac_feature.c index 98ed2bccab1a..eb4e6c3f694d 100644 --- a/arch/ppc64/kernel/pmac_feature.c +++ b/arch/ppc64/kernel/pmac_feature.c @@ -674,6 +674,7 @@ void __init pmac_check_ht_link(void) #if 0 /* Disabled for now */ u32 ufreq, freq, ucfg, cfg; struct device_node *pcix_node; + struct pci_dn *pdn; u8 px_bus, px_devfn; struct pci_controller *px_hose; @@ -687,9 +688,10 @@ void __init pmac_check_ht_link(void) printk("No PCI-X bridge found\n"); return; } - px_hose = pcix_node->phb; - px_bus = pcix_node->busno; - px_devfn = pcix_node->devfn; + pdn = pcix_node->data; + px_hose = pdn->phb; + px_bus = pdn->busno; + px_devfn = pdn->devfn; early_read_config_dword(px_hose, px_bus, px_devfn, 0xc4, &cfg); early_read_config_dword(px_hose, px_bus, px_devfn, 0xcc, &freq); diff --git a/arch/ppc64/kernel/pmac_pci.c b/arch/ppc64/kernel/pmac_pci.c index 71fe911ad183..d37bff2d7d40 100644 --- a/arch/ppc64/kernel/pmac_pci.c +++ b/arch/ppc64/kernel/pmac_pci.c @@ -242,7 +242,7 @@ static int u3_ht_skip_device(struct pci_controller *hose, else busdn = hose->arch_data; for (dn = busdn->child; dn; dn = dn->sibling) - if (dn->devfn == devfn) + if (dn->data && PCI_DN(dn)->devfn == devfn) break; if (dn == NULL) return -1; @@ -746,9 +746,9 @@ void __init pmac_pci_init(void) */ if (u3_agp) { struct device_node *np = u3_agp->arch_data; - np->busno = 0xf0; + PCI_DN(np)->busno = 0xf0; for (np = np->child; np; np = np->sibling) - np->busno = 0xf0; + PCI_DN(np)->busno = 0xf0; } pmac_check_ht_link(); diff --git a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c index 6ad5a8467f87..7035deb6de92 100644 --- a/arch/ppc64/kernel/prom.c +++ b/arch/ppc64/kernel/prom.c @@ -1733,6 +1733,7 @@ static void of_node_release(struct kref *kref) kfree(node->intrs); kfree(node->addrs); kfree(node->full_name); + kfree(node->data); kfree(node); } diff --git a/arch/ppc64/kernel/rtas_pci.c b/arch/ppc64/kernel/rtas_pci.c index 1dccadaddd1d..4a9719b48abe 100644 --- a/arch/ppc64/kernel/rtas_pci.c +++ b/arch/ppc64/kernel/rtas_pci.c @@ -48,7 +48,7 @@ static int write_pci_config; static int ibm_read_pci_config; static int ibm_write_pci_config; -static int config_access_valid(struct device_node *dn, int where) +static int config_access_valid(struct pci_dn *dn, int where) { if (where < 256) return 1; @@ -78,15 +78,17 @@ static int rtas_read_config(struct device_node *dn, int where, int size, u32 *va int returnval = -1; unsigned long buid, addr; int ret; + struct pci_dn *pdn; - if (!dn) + if (!dn || !dn->data) return PCIBIOS_DEVICE_NOT_FOUND; - if (!config_access_valid(dn, where)) + pdn = dn->data; + if (!config_access_valid(pdn, where)) return PCIBIOS_BAD_REGISTER_NUMBER; - addr = ((where & 0xf00) << 20) | (dn->busno << 16) | - (dn->devfn << 8) | (where & 0xff); - buid = dn->phb->buid; + addr = ((where & 0xf00) << 20) | (pdn->busno << 16) | + (pdn->devfn << 8) | (where & 0xff); + buid = pdn->phb->buid; if (buid) { ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval, addr, buid >> 32, buid & 0xffffffff, size); @@ -98,8 +100,8 @@ static int rtas_read_config(struct device_node *dn, int where, int size, u32 *va if (ret) return PCIBIOS_DEVICE_NOT_FOUND; - if (returnval == EEH_IO_ERROR_VALUE(size) - && eeh_dn_check_failure (dn, NULL)) + if (returnval == EEH_IO_ERROR_VALUE(size) && + eeh_dn_check_failure (dn, NULL)) return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_SUCCESSFUL; @@ -118,24 +120,28 @@ static int rtas_pci_read_config(struct pci_bus *bus, /* Search only direct children of the bus */ for (dn = busdn->child; dn; dn = dn->sibling) - if (dn->devfn == devfn && of_device_available(dn)) + if (dn->data && PCI_DN(dn)->devfn == devfn + && of_device_available(dn)) return rtas_read_config(dn, where, size, val); + return PCIBIOS_DEVICE_NOT_FOUND; } -static int rtas_write_config(struct device_node *dn, int where, int size, u32 val) +int rtas_write_config(struct device_node *dn, int where, int size, u32 val) { unsigned long buid, addr; int ret; + struct pci_dn *pdn; - if (!dn) + if (!dn || !dn->data) return PCIBIOS_DEVICE_NOT_FOUND; - if (!config_access_valid(dn, where)) + pdn = dn->data; + if (!config_access_valid(pdn, where)) return PCIBIOS_BAD_REGISTER_NUMBER; - addr = ((where & 0xf00) << 20) | (dn->busno << 16) | - (dn->devfn << 8) | (where & 0xff); - buid = dn->phb->buid; + addr = ((where & 0xf00) << 20) | (pdn->busno << 16) | + (pdn->devfn << 8) | (where & 0xff); + buid = pdn->phb->buid; if (buid) { ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr, buid >> 32, buid & 0xffffffff, size, (ulong) val); } else { @@ -161,7 +167,8 @@ static int rtas_pci_write_config(struct pci_bus *bus, /* Search only direct children of the bus */ for (dn = busdn->child; dn; dn = dn->sibling) - if (dn->devfn == devfn && of_device_available(dn)) + if (dn->data && PCI_DN(dn)->devfn == devfn + && of_device_available(dn)) return rtas_write_config(dn, where, size, val); return PCIBIOS_DEVICE_NOT_FOUND; } diff --git a/arch/ppc64/kernel/sys_ppc32.c b/arch/ppc64/kernel/sys_ppc32.c index 214914a95a50..57a6db7d7c9c 100644 --- a/arch/ppc64/kernel/sys_ppc32.c +++ b/arch/ppc64/kernel/sys_ppc32.c @@ -747,8 +747,8 @@ asmlinkage int sys32_pciconfig_iobase(u32 which, u32 in_bus, u32 in_devfn) if (bus == NULL || bus->sysdata == NULL) return -ENODEV; - hose_node = (struct device_node *)bus->sysdata; - hose = hose_node->phb; + hose_node = bus->sysdata; + hose = PCI_DN(hose_node)->phb; switch (which) { case IOBASE_BRIDGE_NUMBER: diff --git a/arch/ppc64/kernel/u3_iommu.c b/arch/ppc64/kernel/u3_iommu.c index b6e3bca4102d..41ea09cb9ac7 100644 --- a/arch/ppc64/kernel/u3_iommu.c +++ b/arch/ppc64/kernel/u3_iommu.c @@ -276,7 +276,7 @@ static void iommu_dev_setup_u3(struct pci_dev *dev) dn = pci_device_to_OF_node(dev); if (dn) - dn->iommu_table = &iommu_table_u3; + PCI_DN(dn)->iommu_table = &iommu_table_u3; } static void iommu_bus_setup_u3(struct pci_bus *bus) @@ -291,7 +291,7 @@ static void iommu_bus_setup_u3(struct pci_bus *bus) dn = pci_bus_to_OF_node(bus); if (dn) - dn->iommu_table = &iommu_table_u3; + PCI_DN(dn)->iommu_table = &iommu_table_u3; } static void iommu_dev_setup_null(struct pci_dev *dev) { } diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c index 4ada15111af0..ad1017da8656 100644 --- a/drivers/pci/hotplug/rpadlpar_core.c +++ b/drivers/pci/hotplug/rpadlpar_core.c @@ -134,7 +134,8 @@ static void rpadlpar_claim_one_bus(struct pci_bus *b) static int pci_add_secondary_bus(struct device_node *dn, struct pci_dev *bridge_dev) { - struct pci_controller *hose = dn->phb; + struct pci_dn *pdn = dn->data; + struct pci_controller *hose = pdn->phb; struct pci_bus *child; u8 sec_busno; @@ -159,7 +160,7 @@ static int pci_add_secondary_bus(struct device_node *dn, if (hose->last_busno < child->number) hose->last_busno = child->number; - dn->bussubno = child->number; + pdn->bussubno = child->number; /* ioremap() for child bus, which may or may not succeed */ remap_bus_range(child); @@ -183,11 +184,12 @@ static struct pci_dev *dlpar_find_new_dev(struct pci_bus *parent, static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn) { - struct pci_controller *hose = dn->phb; + struct pci_dn *pdn = dn->data; + struct pci_controller *hose = pdn->phb; struct pci_dev *dev = NULL; /* Scan phb bus for EADS device, adding new one to bus->devices */ - if (!pci_scan_single_device(hose->bus, dn->devfn)) { + if (!pci_scan_single_device(hose->bus, pdn->devfn)) { printk(KERN_ERR "%s: found no device on bus\n", __FUNCTION__); return NULL; } @@ -269,6 +271,7 @@ static int dlpar_remove_root_bus(struct pci_controller *phb) static int dlpar_remove_phb(char *drc_name, struct device_node *dn) { struct slot *slot; + struct pci_dn *pdn; int rc = 0; if (!rpaphp_find_pci_bus(dn)) @@ -285,12 +288,13 @@ static int dlpar_remove_phb(char *drc_name, struct device_node *dn) } } - BUG_ON(!dn->phb); - rc = dlpar_remove_root_bus(dn->phb); + pdn = dn->data; + BUG_ON(!pdn || !pdn->phb); + rc = dlpar_remove_root_bus(pdn->phb); if (rc < 0) return rc; - dn->phb = NULL; + pdn->phb = NULL; return 0; } @@ -299,7 +303,7 @@ static int dlpar_add_phb(char *drc_name, struct device_node *dn) { struct pci_controller *phb; - if (dn->phb) { + if (PCI_DN(dn)->phb) { /* PHB already exists */ return -EINVAL; } diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c index 17a0279ebcb9..49e4d10a6488 100644 --- a/drivers/pci/hotplug/rpaphp_pci.c +++ b/drivers/pci/hotplug/rpaphp_pci.c @@ -51,10 +51,12 @@ static struct pci_bus *find_bus_among_children(struct pci_bus *bus, struct pci_bus *rpaphp_find_pci_bus(struct device_node *dn) { - if (!dn->phb || !dn->phb->bus) + struct pci_dn *pdn = dn->data; + + if (!pdn || !pdn->phb || !pdn->phb->bus) return NULL; - return find_bus_among_children(dn->phb->bus, dn); + return find_bus_among_children(pdn->phb->bus, dn); } EXPORT_SYMBOL_GPL(rpaphp_find_pci_bus); @@ -229,7 +231,7 @@ rpaphp_pci_config_slot(struct pci_bus *bus) if (!dn || !dn->child) return NULL; - slotno = PCI_SLOT(dn->child->devfn); + slotno = PCI_SLOT(PCI_DN(dn->child)->devfn); /* pci_scan_slot should find all children */ num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0)); diff --git a/drivers/video/offb.c b/drivers/video/offb.c index 42a6591e863f..611922c0b22f 100644 --- a/drivers/video/offb.c +++ b/drivers/video/offb.c @@ -363,7 +363,7 @@ static void __init offb_init_nodriver(struct device_node *dp) address = (u_long) dp->addrs[i].address; #ifdef CONFIG_PPC64 - address += dp->phb->pci_mem_offset; + address += ((struct pci_dn *)dp->data)->phb->pci_mem_offset; #endif /* kludge for valkyrie */ diff --git a/include/asm-ppc64/pci-bridge.h b/include/asm-ppc64/pci-bridge.h index c4f9023ea5ed..6b4a5b1f695e 100644 --- a/include/asm-ppc64/pci-bridge.h +++ b/include/asm-ppc64/pci-bridge.h @@ -48,19 +48,52 @@ struct pci_controller { unsigned long dma_window_size; }; +/* + * PCI stuff, for nodes representing PCI devices, pointed to + * by device_node->data. + */ +struct pci_controller; +struct iommu_table; + +struct pci_dn { + int busno; /* for pci devices */ + int bussubno; /* for pci devices */ + int devfn; /* for pci devices */ + int eeh_mode; /* See eeh.h for possible EEH_MODEs */ + int eeh_config_addr; + int eeh_capable; /* from firmware */ + int eeh_check_count; /* # times driver ignored error */ + int eeh_freeze_count; /* # times this device froze up. */ + int eeh_is_bridge; /* device is pci-to-pci bridge */ + + int pci_ext_config_space; /* for pci devices */ + struct pci_controller *phb; /* for pci devices */ + struct iommu_table *iommu_table; /* for phb's or bridges */ + struct pci_dev *pcidev; /* back-pointer to the pci device */ + struct device_node *node; /* back-pointer to the device_node */ + u32 config_space[16]; /* saved PCI config space */ +}; + +/* Get the pointer to a device_node's pci_dn */ +#define PCI_DN(dn) ((struct pci_dn *) (dn)->data) + struct device_node *fetch_dev_dn(struct pci_dev *dev); -/* Get a device_node from a pci_dev. This code must be fast except in the case - * where the sysdata is incorrect and needs to be fixed up (hopefully just once) +/* Get a device_node from a pci_dev. This code must be fast except + * in the case where the sysdata is incorrect and needs to be fixed + * up (this will only happen once). + * In this case the sysdata will have been inherited from a PCI host + * bridge or a PCI-PCI bridge further up the tree, so it will point + * to a valid struct pci_dn, just not the one we want. */ static inline struct device_node *pci_device_to_OF_node(struct pci_dev *dev) { struct device_node *dn = dev->sysdata; + struct pci_dn *pdn = dn->data; - if (dn->devfn == dev->devfn && dn->busno == dev->bus->number) + if (pdn && pdn->devfn == dev->devfn && pdn->busno == dev->bus->number) return dn; /* fast path. sysdata is good */ - else - return fetch_dev_dn(dev); + return fetch_dev_dn(dev); } static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus) @@ -83,7 +116,7 @@ static inline struct pci_controller *pci_bus_to_host(struct pci_bus *bus) struct device_node *busdn = bus->sysdata; BUG_ON(busdn == NULL); - return busdn->phb; + return PCI_DN(busdn)->phb; } #endif diff --git a/include/asm-ppc64/prom.h b/include/asm-ppc64/prom.h index dc5330b39509..c02ec1d6b909 100644 --- a/include/asm-ppc64/prom.h +++ b/include/asm-ppc64/prom.h @@ -116,14 +116,6 @@ struct property { struct property *next; }; -/* NOTE: the device_node contains PCI specific info for pci devices. - * This perhaps could be hung off the device_node with another struct, - * but for now it is directly in the node. The phb ptr is a good - * indication of a real PCI node. Other nodes leave these fields zeroed. - */ -struct pci_controller; -struct iommu_table; - struct device_node { char *name; char *type; @@ -135,16 +127,6 @@ struct device_node { struct interrupt_info *intrs; char *full_name; - /* PCI stuff probably doesn't belong here */ - int busno; /* for pci devices */ - int bussubno; /* for pci devices */ - int devfn; /* for pci devices */ - int eeh_mode; /* See eeh.h for possible EEH_MODEs */ - int eeh_config_addr; - int pci_ext_config_space; /* for pci devices */ - struct pci_controller *phb; /* for pci devices */ - struct iommu_table *iommu_table; /* for phb's or bridges */ - struct property *properties; struct device_node *parent; struct device_node *child; @@ -154,6 +136,7 @@ struct device_node { struct proc_dir_entry *pde; /* this node's proc directory */ struct kref kref; unsigned long _flags; + void *data; }; extern struct device_node *of_chosen; From 766375362a1dcac63dc0c0fb61ce4143c8de63d9 Mon Sep 17 00:00:00 2001 From: Arthur Othieno Date: Sat, 20 Aug 2005 21:48:47 -0400 Subject: [PATCH 13/14] [PATCH] ppc64: Big-endian I/O memory accessors. I/O memory accessors. Big-endian version. For those busses/devices that do export big-endian I/O memory. Of notable relevance/reference: http://lwn.net/Articles/132804/ http://ozlabs.org/pipermail/linuxppc-embedded/2005-August/019798.html http://ozlabs.org/pipermail/linuxppc-embedded/2005-August/019752.html Signed-Off-By: Arthur Othieno Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/iomap.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/arch/ppc64/kernel/iomap.c b/arch/ppc64/kernel/iomap.c index 153cc8b0f136..95b0baf87522 100644 --- a/arch/ppc64/kernel/iomap.c +++ b/arch/ppc64/kernel/iomap.c @@ -22,13 +22,23 @@ unsigned int fastcall ioread16(void __iomem *addr) { return readw(addr); } +unsigned int fastcall ioread16be(void __iomem *addr) +{ + return in_be16(addr); +} unsigned int fastcall ioread32(void __iomem *addr) { return readl(addr); } +unsigned int fastcall ioread32be(void __iomem *addr) +{ + return in_be32(addr); +} EXPORT_SYMBOL(ioread8); EXPORT_SYMBOL(ioread16); +EXPORT_SYMBOL(ioread16be); EXPORT_SYMBOL(ioread32); +EXPORT_SYMBOL(ioread32be); void fastcall iowrite8(u8 val, void __iomem *addr) { @@ -38,13 +48,23 @@ void fastcall iowrite16(u16 val, void __iomem *addr) { writew(val, addr); } +void fastcall iowrite16be(u16 val, void __iomem *addr) +{ + out_be16(addr, val); +} void fastcall iowrite32(u32 val, void __iomem *addr) { writel(val, addr); } +void fastcall iowrite32be(u32 val, void __iomem *addr) +{ + out_be32(addr, val); +} EXPORT_SYMBOL(iowrite8); EXPORT_SYMBOL(iowrite16); +EXPORT_SYMBOL(iowrite16be); EXPORT_SYMBOL(iowrite32); +EXPORT_SYMBOL(iowrite32be); /* * These are the "repeat read/write" functions. Note the From b2ad7b5e8115582cdf5bbda065aa516c24d62c21 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Fri, 9 Sep 2005 23:02:36 +1000 Subject: [PATCH 14/14] Allow PCI config space syscalls to be used by 64-bit processes. The pciconfig_iobase, pciconfig_read and pciconfig_write system calls were only implemented for 32-bit processes; for 64-bit processes they returned an ENOSYS error. This allows them to be used by 64-bit processes as well. The X server uses pciconfig_iobase at least, and this change is necessary to allow a 64-bit X server to work on my G5. Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/misc.S | 6 ++-- arch/ppc64/kernel/pci.c | 60 +++++++++++++++++++++++++++++++++++ arch/ppc64/kernel/sys_ppc32.c | 55 +------------------------------- 3 files changed, 64 insertions(+), 57 deletions(-) diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S index 6d860c1d9fa0..c047663eb48d 100644 --- a/arch/ppc64/kernel/misc.S +++ b/arch/ppc64/kernel/misc.S @@ -1431,9 +1431,9 @@ _GLOBAL(sys_call_table) .llong .sys_ni_syscall /* 195 - 32bit only stat64 */ .llong .sys_ni_syscall /* 32bit only lstat64 */ .llong .sys_ni_syscall /* 32bit only fstat64 */ - .llong .sys_ni_syscall /* 32bit only pciconfig_read */ - .llong .sys_ni_syscall /* 32bit only pciconfig_write */ - .llong .sys_ni_syscall /* 32bit only pciconfig_iobase */ + .llong .sys_pciconfig_read + .llong .sys_pciconfig_write + .llong .sys_pciconfig_iobase /* 200 - pciconfig_iobase */ .llong .sys_ni_syscall /* reserved for MacOnLinux */ .llong .sys_getdents64 .llong .sys_pivot_root diff --git a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c index 446b4654883f..8447dcc2c2b3 100644 --- a/arch/ppc64/kernel/pci.c +++ b/arch/ppc64/kernel/pci.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -984,3 +985,62 @@ void pci_resource_to_user(const struct pci_dev *dev, int bar, } #endif /* CONFIG_PPC_MULTIPLATFORM */ + + +#define IOBASE_BRIDGE_NUMBER 0 +#define IOBASE_MEMORY 1 +#define IOBASE_IO 2 +#define IOBASE_ISA_IO 3 +#define IOBASE_ISA_MEM 4 + +long sys_pciconfig_iobase(long which, unsigned long in_bus, + unsigned long in_devfn) +{ + struct pci_controller* hose; + struct list_head *ln; + struct pci_bus *bus = NULL; + struct device_node *hose_node; + + /* Argh ! Please forgive me for that hack, but that's the + * simplest way to get existing XFree to not lockup on some + * G5 machines... So when something asks for bus 0 io base + * (bus 0 is HT root), we return the AGP one instead. + */ +#ifdef CONFIG_PPC_PMAC + if (systemcfg->platform == PLATFORM_POWERMAC && + machine_is_compatible("MacRISC4")) + if (in_bus == 0) + in_bus = 0xf0; +#endif /* CONFIG_PPC_PMAC */ + + /* That syscall isn't quite compatible with PCI domains, but it's + * used on pre-domains setup. We return the first match + */ + + for (ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) { + bus = pci_bus_b(ln); + if (in_bus >= bus->number && in_bus < (bus->number + bus->subordinate)) + break; + bus = NULL; + } + if (bus == NULL || bus->sysdata == NULL) + return -ENODEV; + + hose_node = (struct device_node *)bus->sysdata; + hose = PCI_DN(hose_node)->phb; + + switch (which) { + case IOBASE_BRIDGE_NUMBER: + return (long)hose->first_busno; + case IOBASE_MEMORY: + return (long)hose->pci_mem_offset; + case IOBASE_IO: + return (long)hose->io_base_phys; + case IOBASE_ISA_IO: + return (long)isa_io_base; + case IOBASE_ISA_MEM: + return -EINVAL; + } + + return -EOPNOTSUPP; +} diff --git a/arch/ppc64/kernel/sys_ppc32.c b/arch/ppc64/kernel/sys_ppc32.c index 57a6db7d7c9c..e93c13458910 100644 --- a/arch/ppc64/kernel/sys_ppc32.c +++ b/arch/ppc64/kernel/sys_ppc32.c @@ -708,62 +708,9 @@ asmlinkage int sys32_pciconfig_write(u32 bus, u32 dfn, u32 off, u32 len, u32 ubu compat_ptr(ubuf)); } -#define IOBASE_BRIDGE_NUMBER 0 -#define IOBASE_MEMORY 1 -#define IOBASE_IO 2 -#define IOBASE_ISA_IO 3 -#define IOBASE_ISA_MEM 4 - asmlinkage int sys32_pciconfig_iobase(u32 which, u32 in_bus, u32 in_devfn) { -#ifdef CONFIG_PCI - struct pci_controller* hose; - struct list_head *ln; - struct pci_bus *bus = NULL; - struct device_node *hose_node; - - /* Argh ! Please forgive me for that hack, but that's the - * simplest way to get existing XFree to not lockup on some - * G5 machines... So when something asks for bus 0 io base - * (bus 0 is HT root), we return the AGP one instead. - */ -#ifdef CONFIG_PPC_PMAC - if (systemcfg->platform == PLATFORM_POWERMAC && - machine_is_compatible("MacRISC4")) - if (in_bus == 0) - in_bus = 0xf0; -#endif /* CONFIG_PPC_PMAC */ - - /* That syscall isn't quite compatible with PCI domains, but it's - * used on pre-domains setup. We return the first match - */ - - for (ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) { - bus = pci_bus_b(ln); - if (in_bus >= bus->number && in_bus < (bus->number + bus->subordinate)) - break; - bus = NULL; - } - if (bus == NULL || bus->sysdata == NULL) - return -ENODEV; - - hose_node = bus->sysdata; - hose = PCI_DN(hose_node)->phb; - - switch (which) { - case IOBASE_BRIDGE_NUMBER: - return (long)hose->first_busno; - case IOBASE_MEMORY: - return (long)hose->pci_mem_offset; - case IOBASE_IO: - return (long)hose->io_base_phys; - case IOBASE_ISA_IO: - return (long)isa_io_base; - case IOBASE_ISA_MEM: - return -EINVAL; - } -#endif /* CONFIG_PCI */ - return -EOPNOTSUPP; + return sys_pciconfig_iobase(which, in_bus, in_devfn); }