summaryrefslogtreecommitdiffstats
path: root/arch/ppc
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2001-01-31 22:22:27 +0000
committerRalf Baechle <ralf@linux-mips.org>2001-01-31 22:22:27 +0000
commit825423e4c4f18289df2393951cfd2a7a31fc0464 (patch)
tree4ad80e981c3d9effa910d2247d118d254f9a5d09 /arch/ppc
parentc4693dc4856ab907a5c02187a8d398861bebfc7e (diff)
Merge with Linux 2.4.1.
Diffstat (limited to 'arch/ppc')
-rw-r--r--arch/ppc/8260_io/enet.c3
-rw-r--r--arch/ppc/8260_io/fcc_enet.c3
-rw-r--r--arch/ppc/8xx_io/enet.c4
-rw-r--r--arch/ppc/8xx_io/fec.c3
-rw-r--r--arch/ppc/Makefile3
-rw-r--r--arch/ppc/boot/Makefile28
-rw-r--r--arch/ppc/boot/vreset.c10
-rw-r--r--arch/ppc/chrpboot/Makefile10
-rw-r--r--arch/ppc/coffboot/Makefile7
-rw-r--r--arch/ppc/coffboot/coffmain.c62
-rw-r--r--arch/ppc/config.in108
-rw-r--r--arch/ppc/configs/apus_defconfig273
-rw-r--r--arch/ppc/configs/bseip_defconfig9
-rw-r--r--arch/ppc/configs/common_defconfig203
-rw-r--r--arch/ppc/configs/est8260_defconfig23
-rw-r--r--arch/ppc/configs/ibmchrp_defconfig636
-rw-r--r--arch/ppc/configs/mbx_defconfig9
-rw-r--r--arch/ppc/configs/oak_defconfig11
-rw-r--r--arch/ppc/configs/power3_defconfig662
-rw-r--r--arch/ppc/configs/rpxcllf_defconfig9
-rw-r--r--arch/ppc/configs/rpxlite_defconfig9
-rw-r--r--arch/ppc/configs/walnut_defconfig11
-rw-r--r--arch/ppc/defconfig203
-rw-r--r--arch/ppc/kernel/Makefile6
-rw-r--r--arch/ppc/kernel/apus_setup.c22
-rw-r--r--arch/ppc/kernel/chrp_pci.c630
-rw-r--r--arch/ppc/kernel/chrp_setup.c130
-rw-r--r--arch/ppc/kernel/entry.S17
-rw-r--r--arch/ppc/kernel/error_log.c183
-rw-r--r--arch/ppc/kernel/error_log.h95
-rw-r--r--arch/ppc/kernel/feature.c108
-rw-r--r--arch/ppc/kernel/galaxy_pci.c69
-rw-r--r--arch/ppc/kernel/hashtable.S53
-rw-r--r--arch/ppc/kernel/head.S97
-rw-r--r--arch/ppc/kernel/i8259.c33
-rw-r--r--arch/ppc/kernel/idle.c79
-rw-r--r--arch/ppc/kernel/indirect_pci.c148
-rw-r--r--arch/ppc/kernel/irq.c409
-rw-r--r--arch/ppc/kernel/local_irq.h3
-rw-r--r--arch/ppc/kernel/m8260_setup.c43
-rw-r--r--arch/ppc/kernel/m8xx_setup.c32
-rw-r--r--arch/ppc/kernel/misc.S220
-rw-r--r--arch/ppc/kernel/open_pic.c704
-rw-r--r--arch/ppc/kernel/open_pic.h42
-rw-r--r--arch/ppc/kernel/open_pic_defs.h328
-rw-r--r--arch/ppc/kernel/pci.c599
-rw-r--r--arch/ppc/kernel/pci.h46
-rw-r--r--arch/ppc/kernel/pmac_pci.c916
-rw-r--r--arch/ppc/kernel/pmac_pic.c148
-rw-r--r--arch/ppc/kernel/pmac_setup.c170
-rw-r--r--arch/ppc/kernel/pmac_time.c4
-rw-r--r--arch/ppc/kernel/ppc_asm.h6
-rw-r--r--arch/ppc/kernel/ppc_htab.c3
-rw-r--r--arch/ppc/kernel/ppc_ksyms.c46
-rw-r--r--arch/ppc/kernel/prep_nvram.c34
-rw-r--r--arch/ppc/kernel/prep_pci.c336
-rw-r--r--arch/ppc/kernel/prep_setup.c186
-rw-r--r--arch/ppc/kernel/proc_rtas.c784
-rw-r--r--arch/ppc/kernel/process.c17
-rw-r--r--arch/ppc/kernel/prom.c206
-rw-r--r--arch/ppc/kernel/setup.c51
-rw-r--r--arch/ppc/kernel/signal.c2
-rw-r--r--arch/ppc/kernel/smp.c1043
-rw-r--r--arch/ppc/kernel/time.c44
-rw-r--r--arch/ppc/kernel/traps.c36
-rw-r--r--arch/ppc/lib/Makefile2
-rw-r--r--arch/ppc/lib/locks.c5
-rw-r--r--arch/ppc/mm/fault.c19
-rw-r--r--arch/ppc/mm/init.c415
-rw-r--r--arch/ppc/xmon/start.c64
-rw-r--r--arch/ppc/xmon/xmon.c3
71 files changed, 7419 insertions, 3516 deletions
diff --git a/arch/ppc/8260_io/enet.c b/arch/ppc/8260_io/enet.c
index e1ff3c092..77b0eb279 100644
--- a/arch/ppc/8260_io/enet.c
+++ b/arch/ppc/8260_io/enet.c
@@ -633,6 +633,9 @@ int __init scc_enet_init(void)
/* Allocate some private information.
*/
cep = (struct scc_enet_private *)kmalloc(sizeof(*cep), GFP_KERNEL);
+ if (cep == NULL)
+ return -ENOMEM;
+
__clear_user(cep,sizeof(*cep));
spin_lock_init(&cep->lock);
diff --git a/arch/ppc/8260_io/fcc_enet.c b/arch/ppc/8260_io/fcc_enet.c
index da3991ae3..c8c31bd42 100644
--- a/arch/ppc/8260_io/fcc_enet.c
+++ b/arch/ppc/8260_io/fcc_enet.c
@@ -1082,6 +1082,9 @@ int __init fec_enet_init(void)
*/
cep = (struct fcc_enet_private *)
kmalloc(sizeof(*cep), GFP_KERNEL);
+ if (cep == NULL)
+ return -ENOMEM;
+
__clear_user(cep,sizeof(*cep));
spin_lock_init(&cep->lock);
cep->fip = fip;
diff --git a/arch/ppc/8xx_io/enet.c b/arch/ppc/8xx_io/enet.c
index b77cf32da..01eb2758b 100644
--- a/arch/ppc/8xx_io/enet.c
+++ b/arch/ppc/8xx_io/enet.c
@@ -652,7 +652,9 @@ int __init scc_enet_init(void)
/* Allocate some private information.
*/
cep = (struct scc_enet_private *)kmalloc(sizeof(*cep), GFP_KERNEL);
- /*memset(cep, 0, sizeof(*cep));*/
+ if (cep == NULL)
+ return -ENOMEM;
+
__clear_user(cep,sizeof(*cep));
spin_lock_init(&cep->lock);
diff --git a/arch/ppc/8xx_io/fec.c b/arch/ppc/8xx_io/fec.c
index 659576e8c..6e5e9e686 100644
--- a/arch/ppc/8xx_io/fec.c
+++ b/arch/ppc/8xx_io/fec.c
@@ -1459,6 +1459,9 @@ int __init fec_enet_init(void)
/* Allocate some private information.
*/
fep = (struct fec_enet_private *)kmalloc(sizeof(*fep), GFP_KERNEL);
+ if (fep == NULL)
+ return -ENOMEM;
+
__clear_user(fep,sizeof(*fep));
/* Create an Ethernet device instance.
diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile
index d4172ed4a..488766003 100644
--- a/arch/ppc/Makefile
+++ b/arch/ppc/Makefile
@@ -145,9 +145,6 @@ endif
clean_config:
rm -f .config arch/ppc/defconfig
-gemini_config: clean_config
- cp -f arch/ppc/configs/gemini_defconfig arch/ppc/defconfig
-
pmac_config: clean_config
cp -f arch/ppc/configs/pmac_defconfig arch/ppc/defconfig
diff --git a/arch/ppc/boot/Makefile b/arch/ppc/boot/Makefile
index 26961e8ea..32c2926a1 100644
--- a/arch/ppc/boot/Makefile
+++ b/arch/ppc/boot/Makefile
@@ -25,22 +25,12 @@ ZSZ = 0
IOFF = 0
ISZ = 0
-ifeq ($(CONFIG_ALL_PPC),y)
-CONFIG_PREP=y
-endif
-
ifeq ($(CONFIG_SMP),y)
TFTPIMAGE=/tftpboot/zImage.prep.smp$(MSIZE)
else
TFTPIMAGE=/tftpboot/zImage.prep$(MSIZE)
endif
-ifeq ($(CONFIG_SMP),y)
-TFTPSIMAGE=/tftpboot/sImage.smp
-else
-TFTPSIMAGE=/tftpboot/sImage
-endif
-
ifeq ($(CONFIG_PPC64BRIDGE),y)
MSIZE=.64
else
@@ -81,8 +71,8 @@ zvmlinux.initrd: zvmlinux
zvmlinux.initrd.tmp $@
rm zvmlinux.initrd.tmp
-zImage: zvmlinux mkprep sImage
-ifdef CONFIG_PREP
+zImage: zvmlinux mkprep
+ifdef CONFIG_ALL_PPC
./mkprep -pbp zvmlinux zImage
endif
ifdef CONFIG_APUS
@@ -90,13 +80,8 @@ ifdef CONFIG_APUS
gzip $(GZIP_FLAGS) vmapus
endif
-sImage: ../../../vmlinux
-ifdef CONFIG_GEMINI
- $(OBJCOPY) -I elf32-powerpc -O binary ../../../vmlinux sImage
-endif
-
zImage.initrd: zvmlinux.initrd mkprep
-ifdef CONFIG_PREP
+ifdef CONFIG_ALL_PPC
./mkprep -pbp zvmlinux.initrd zImage.initrd
endif
@@ -128,18 +113,15 @@ mkprep : mkprep.c
$(HOSTCC) -o mkprep mkprep.c
znetboot : zImage
-ifdef CONFIG_PREP
+ifdef CONFIG_ALL_PPC
cp zImage $(TFTPIMAGE)
endif
-ifdef CONFIG_GEMINI
- cp sImage $(TFTPSIMAGE)
-endif
znetboot.initrd : zImage.initrd
cp zImage.initrd $(TFTPIMAGE)
clean:
- rm -f vmlinux* zvmlinux* mkprep zImage* sImage*
+ rm -f vmlinux* zvmlinux* mkprep zImage*
fastdep:
$(TOPDIR)/scripts/mkdep *.[Sch] > .depend
diff --git a/arch/ppc/boot/vreset.c b/arch/ppc/boot/vreset.c
index c01361dc6..dfabd72e7 100644
--- a/arch/ppc/boot/vreset.c
+++ b/arch/ppc/boot/vreset.c
@@ -19,12 +19,16 @@
*/
#include "iso_font.h"
-#include <linux/delay.h>
extern char *vidmem;
extern int lines, cols;
-/* estimate for delay */
-unsigned long loops_per_sec = 50000000;;
+
+static void mdelay(int ms)
+{
+ for (; ms > 0; --ms)
+ udelay(1000);
+}
+
/*
* VGA Register
*/
diff --git a/arch/ppc/chrpboot/Makefile b/arch/ppc/chrpboot/Makefile
index f7ea3a3fa..9dbb7909d 100644
--- a/arch/ppc/chrpboot/Makefile
+++ b/arch/ppc/chrpboot/Makefile
@@ -23,11 +23,6 @@ LD_ARGS = -Ttext 0x00400000
OBJS = crt0.o start.o main.o misc.o ../coffboot/string.o ../coffboot/zlib.o image.o
LIBS = $(TOPDIR)/lib/lib.a
-ifeq ($(CONFIG_ALL_PPC),y)
-# yes, we want to build chrp stuff
-CONFIG_CHRP = y
-endif
-
ifeq ($(CONFIG_SMP),y)
TFTPIMAGE=/tftpboot/zImage.chrp.smp$(MSIZE)
else
@@ -37,10 +32,10 @@ endif
all: $(TOPDIR)/zImage
#
-# Only build anything here if we're configured for CHRP
+# Only build anything here if we're configured for ALL_PPC
# -- cort
#
-ifeq ($(CONFIG_CHRP),y)
+ifeq ($(CONFIG_ALL_PPC),y)
znetboot: zImage
cp zImage $(TFTPIMAGE)
@@ -96,6 +91,7 @@ vmlinux.coff.initrd:
clean:
rm -f piggyback note addnote $(OBJS) zImage
+ rm -f zImage.rs6k zImage.initrd zImage.initrd.rs6k
fastdep:
$(TOPDIR)/scripts/mkdep *.[Sch] > .depend
diff --git a/arch/ppc/coffboot/Makefile b/arch/ppc/coffboot/Makefile
index 494026e42..2835e1f89 100644
--- a/arch/ppc/coffboot/Makefile
+++ b/arch/ppc/coffboot/Makefile
@@ -20,18 +20,13 @@ else
MSIZE=
endif
-ifeq ($(CONFIG_ALL_PPC),y)
-# yes, we want to build pmac stuff
-CONFIG_PMAC = y
-endif
-
ifeq ($(CONFIG_SMP),y)
TFTPIMAGE=/tftpboot/zImage.pmac.smp$(MSIZE)
else
TFTPIMAGE=/tftpboot/zImage.pmac$(MSIZE)
endif
-ifeq ($(CONFIG_PMAC),y)
+ifeq ($(CONFIG_ALL_PPC),y)
chrpmain.o: chrpmain.c
$(CC) $(CFLAGS) -DSYSMAP_OFFSET=0 -DSYSMAP_SIZE=0 -c chrpmain.c
diff --git a/arch/ppc/coffboot/coffmain.c b/arch/ppc/coffboot/coffmain.c
index b76ba5976..49e769f22 100644
--- a/arch/ppc/coffboot/coffmain.c
+++ b/arch/ppc/coffboot/coffmain.c
@@ -22,11 +22,18 @@ void gunzip(void *, int, unsigned char *, int *);
#define get_32be(x) (*(unsigned *)(x))
#define RAM_START 0xc0000000
-#define PROG_START RAM_START
#define RAM_END (RAM_START + 0x800000) /* only 8M mapped with BATs */
+#define PROG_START RAM_START
+#define PROG_SIZE 0x00400000
+
+#define SCRATCH_SIZE (128 << 10)
+
char *avail_ram;
-char *end_avail;
+char *begin_avail, *end_avail;
+char *avail_high;
+unsigned int heap_use;
+unsigned int heap_max;
extern char _start[], _end[];
extern char image_data[];
@@ -34,6 +41,7 @@ extern int image_len;
extern char initrd_data[];
extern int initrd_len;
+char heap[SCRATCH_SIZE];
boot(int a1, int a2, void *prom)
{
@@ -58,16 +66,18 @@ boot(int a1, int a2, void *prom)
im = image_data;
len = image_len;
/* claim 3MB starting at 0 */
- claim(0, 3 << 20, 0);
+ claim(0, PROG_SIZE, 0);
dst = (void *) RAM_START;
if (im[0] == 0x1f && im[1] == 0x8b) {
- /* claim 512kB for scratch space */
- avail_ram = claim(0, 512 << 10, 0x10) + RAM_START;
- end_avail = avail_ram + (512 << 10);
- printf("avail_ram = %x\n", avail_ram);
+ /* claim some memory for scratch space */
+ begin_avail = avail_high = avail_ram = heap;
+ end_avail = heap + sizeof(heap);
+ printf("heap at 0x%x\n", avail_ram);
printf("gunzipping (0x%x <- 0x%x:0x%0x)...", dst, im, im+len);
- gunzip(dst, 3 << 20, im, &len);
+ gunzip(dst, PROG_SIZE, im, &len);
printf("done %u bytes\n", len);
+ printf("%u bytes of heap consumed, max in use %u\n",
+ avail_high - begin_avail, heap_max);
} else {
memmove(dst, im, len);
}
@@ -78,9 +88,6 @@ boot(int a1, int a2, void *prom)
sa = (unsigned long)PROG_START;
printf("start address = 0x%x\n", sa);
-#if 0
- pause();
-#endif
(*(void (*)())sa)(a1, a2, prom);
printf("returned?\n");
@@ -114,13 +121,33 @@ void make_bi_recs(unsigned long addr)
rec = (struct bi_record *)((unsigned long)rec + rec->size);
}
+struct memchunk {
+ unsigned int size;
+ struct memchunk *next;
+};
+
+static struct memchunk *freechunks;
+
void *zalloc(void *x, unsigned items, unsigned size)
{
- void *p = avail_ram;
+ void *p;
+ struct memchunk **mpp, *mp;
size *= items;
size = (size + 7) & -8;
+ heap_use += size;
+ if (heap_use > heap_max)
+ heap_max = heap_use;
+ for (mpp = &freechunks; (mp = *mpp) != 0; mpp = &mp->next) {
+ if (mp->size == size) {
+ *mpp = mp->next;
+ return mp;
+ }
+ }
+ p = avail_ram;
avail_ram += size;
+ if (avail_ram > avail_high)
+ avail_high = avail_ram;
if (avail_ram > end_avail) {
printf("oops... out of memory\n");
pause();
@@ -130,6 +157,17 @@ void *zalloc(void *x, unsigned items, unsigned size)
void zfree(void *x, void *addr, unsigned nb)
{
+ struct memchunk *mp = addr;
+
+ nb = (nb + 7) & -8;
+ heap_use -= nb;
+ if (avail_ram == addr + nb) {
+ avail_ram = addr;
+ return;
+ }
+ mp->size = nb;
+ mp->next = freechunks;
+ freechunks = mp;
}
#define HEAD_CRC 2
diff --git a/arch/ppc/config.in b/arch/ppc/config.in
index 34606f99a..3b4c2c141 100644
--- a/arch/ppc/config.in
+++ b/arch/ppc/config.in
@@ -24,21 +24,24 @@ mainmenu_option next_comment
comment 'Platform support'
define_bool CONFIG_PPC y
choice 'Processor Type' \
- "6xx/7xx/7400 CONFIG_6xx \
+ "6xx/7xx/74xx/8260 CONFIG_6xx \
4xx CONFIG_4xx \
POWER3 CONFIG_POWER3 \
POWER4 CONFIG_POWER4 \
- 8260 CONFIG_8260 \
8xx CONFIG_8xx" 6xx
+if [ "$CONFIG_6xx" = "y" ]; then
+ bool 'MPC8260 CPM Support' CONFIG_8260
+fi
+
if [ "$CONFIG_POWER3" = "y" -o "$CONFIG_POWER4" = "y" ]; then
define_bool CONFIG_PPC64BRIDGE y
define_bool CONFIG_ALL_PPC y
fi
-
+
if [ "$CONFIG_8260" = "y" ]; then
- define_bool CONFIG_6xx y
define_bool CONFIG_SERIAL_CONSOLE y
+ bool 'Support for EST8260' CONFIG_EST8260
fi
if [ "$CONFIG_4xx" = "y" ]; then
@@ -59,25 +62,32 @@ if [ "$CONFIG_8xx" = "y" ]; then
TQM860 CONFIG_TQM860 \
MBX CONFIG_MBX \
WinCept CONFIG_WINCEPT" RPX-Lite
+
+ if [ "$CONFIG_TQM8xxL" = "y" ]; then
+ bool 'FPS850 Mainboard' CONFIG_FPS850
+ fi
fi
-if [ "$CONFIG_6xx" = "y" ]; then
+
+if [ "$CONFIG_6xx" = "y" -a "$CONFIG_8260" = "n" ]; then
choice 'Machine Type' \
"PowerMac/PReP/MTX/CHRP CONFIG_ALL_PPC \
- Gemini CONFIG_GEMINI \
- EST8260 CONFIG_EST8260 \
APUS CONFIG_APUS" PowerMac/PReP/MTX/CHRP
fi
+if [ "$CONFIG_PPC64BRIDGE" != "y" ]; then
+ bool 'Workarounds for PPC601 bugs' CONFIG_PPC601_SYNC_FIX
+fi
+
if [ "$CONFIG_8xx" = "y" -o "$CONFIG_8260" = "y" ]; then
define_bool CONFIG_ALL_PPC n
fi
-if [ "$CONFIG_TQM8xxL" = "y" ]; then
- bool 'FPS850 Mainboard' CONFIG_FPS850
+bool 'Symmetric multi-processing support' CONFIG_SMP
+if [ "$CONFIG_SMP" = "y" ]; then
+ bool ' Distribute interrupts on all CPUs by default' CONFIG_IRQ_ALL_CPUS
fi
-bool 'Symmetric multi-processing support' CONFIG_SMP
-if [ "$CONFIG_6xx" = "y" ];then
+if [ "$CONFIG_6xx" = "y" -a "$CONFIG_8260" = "n" ];then
bool 'AltiVec Support' CONFIG_ALTIVEC
fi
@@ -106,14 +116,14 @@ define_bool CONFIG_MCA n
if [ "$CONFIG_APUS" = "y" -o "$CONFIG_4xx" = "y" -o \
"$CONFIG_8260" = "y" ]; then
- define_bool CONFIG_PCI n
+ define_bool CONFIG_PCI n
else
- if [ "$CONFIG_8xx" = "y" ]; then
- bool 'QSpan PCI' CONFIG_PCI_QSPAN
- define_bool CONFIG_PCI $CONFIG_PCI_QSPAN
- else
- define_bool CONFIG_PCI y
- fi
+ if [ "$CONFIG_8xx" = "y" ]; then
+ bool 'QSpan PCI' CONFIG_PCI_QSPAN
+ define_bool CONFIG_PCI $CONFIG_PCI_QSPAN
+ else
+ define_bool CONFIG_PCI y
+ fi
fi
bool 'Networking support' CONFIG_NET
@@ -123,40 +133,34 @@ bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
# only elf supported, a.out is not -- Cort
if [ "$CONFIG_PROC_FS" = "y" ]; then
- define_bool CONFIG_KCORE_ELF y
+ define_bool CONFIG_KCORE_ELF y
fi
define_bool CONFIG_BINFMT_ELF y
define_bool CONFIG_KERNEL_ELF y
tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
source drivers/pci/Config.in
-source drivers/zorro/Config.in
bool 'Support for hot-pluggable devices' CONFIG_HOTPLUG
if [ "$CONFIG_HOTPLUG" = "y" ]; then
- source drivers/pcmcia/Config.in
+ source drivers/pcmcia/Config.in
else
- define_bool CONFIG_PCMCIA n
+ define_bool CONFIG_PCMCIA n
fi
source drivers/parport/Config.in
if [ "$CONFIG_4xx" != "y" -a "$CONFIG_8xx" != "y" ]; then
- bool 'Support for VGA Console' CONFIG_VGA_CONSOLE
- bool 'Support for frame buffer devices' CONFIG_FB
- if [ "$CONFIG_FB" = "y" ]; then
- bool 'Backward compatibility mode for Xpmac' CONFIG_FB_COMPAT_XPMAC
- fi
-
tristate 'Support for /dev/rtc' CONFIG_PPC_RTC
- bool 'Support for Open Firmware device tree in /proc' CONFIG_PROC_DEVICETREE
- bool 'Support for early boot text console (BootX only)' CONFIG_BOOTX_TEXT
- bool 'Support for Motorola Hot Swap' CONFIG_MOTOROLA_HOTSWAP
fi
-if [ "$CONFIG_PREP" = "y" -o "$CONFIG_ALL_PPC" = "y" ]; then
- bool 'PReP bootloader kernel arguments' CONFIG_CMDLINE_BOOL
+if [ "$CONFIG_ALL_PPC" = "y" ]; then
+ bool 'Support for Open Firmware device tree in /proc' CONFIG_PROC_DEVICETREE
+ bool 'Support for RTAS (RunTime Abstraction Services) in /proc' CONFIG_PPC_RTAS
+ bool 'Support for early boot text console (BootX or OpenFirmware only)' CONFIG_BOOTX_TEXT
+ bool 'Support for PReP Residual Data' CONFIG_PREP_RESIDUAL
+ bool 'Default bootloader kernel arguments' CONFIG_CMDLINE_BOOL
if [ "$CONFIG_CMDLINE_BOOL" = "y" ] ; then
string 'Initial kernel command string' CONFIG_CMDLINE "console=ttyS0,9600 console=tty0 root=/dev/sda2"
fi
@@ -181,6 +185,7 @@ if [ "$CONFIG_APUS" = "y" ]; then
fi
bool 'Use power LED as a heartbeat' CONFIG_HEARTBEAT
bool '/proc/hardware support' CONFIG_PROC_HARDWARE
+ source drivers/zorro/Config.in
fi
endmenu
@@ -254,7 +259,13 @@ endmenu
mainmenu_option next_comment
comment 'Console drivers'
-source drivers/video/Config.in
+if [ "$CONFIG_4xx" != "y" -a "$CONFIG_8xx" != "y" ]; then
+ bool 'Support for VGA Console' CONFIG_VGA_CONSOLE
+fi
+ source drivers/video/Config.in
+if [ "$CONFIG_FB" = "y" -a "$CONFIG_ALL_PPC" = "y" ]; then
+ bool 'Backward compatibility mode for Xpmac' CONFIG_FB_COMPAT_XPMAC
+fi
endmenu
source drivers/input/Config.in
@@ -267,29 +278,26 @@ if [ "$CONFIG_ALL_PPC" = "y" ]; then
bool 'Support for CUDA based PowerMacs' CONFIG_ADB_CUDA
bool 'Support for PMU based PowerMacs' CONFIG_ADB_PMU
if [ "$CONFIG_ADB_PMU" = "y" ]; then
- bool ' Power management support for PowerBooks' CONFIG_PMAC_PBOOK
- # made a separate option since backlight may end up beeing used
- # on non-powerbook machines (but only on PMU based ones AFAIK)
- bool ' Backlight control for LCD screens' CONFIG_PMAC_BACKLIGHT
+ bool ' Power management support for PowerBooks' CONFIG_PMAC_PBOOK
+ # made a separate option since backlight may end up beeing used
+ # on non-powerbook machines (but only on PMU based ones AFAIK)
+ bool ' Backlight control for LCD screens' CONFIG_PMAC_BACKLIGHT
fi
bool 'Support for PowerMac floppy' CONFIG_MAC_FLOPPY
tristate 'Support for PowerMac serial ports' CONFIG_MAC_SERIAL
if [ "$CONFIG_MAC_SERIAL" = "y" ]; then
- bool ' Support for console on serial port' CONFIG_SERIAL_CONSOLE
+ bool ' Support for console on serial port' CONFIG_SERIAL_CONSOLE
fi
bool 'Apple Desktop Bus (ADB) support' CONFIG_ADB
if [ "$CONFIG_ADB" = "y" ]; then
- bool ' Include MacIO (CHRP) ADB driver' CONFIG_ADB_MACIO
- fi
-fi
-if [ "$CONFIG_ADB" = "y" ]; then
- dep_bool ' Use input layer for ADB devices' CONFIG_INPUT_ADBHID $CONFIG_INPUT
- if [ "$CONFIG_INPUT_ADBHID" = "y" ]; then
- define_bool CONFIG_MAC_HID y
- bool ' Support for ADB raw keycodes' CONFIG_MAC_ADBKEYCODES
- bool ' Support for mouse button 2+3 emulation' CONFIG_MAC_EMUMOUSEBTN
- else
- bool ' Support for ADB keyboard (old driver)' CONFIG_ADB_KEYBOARD
+ bool ' Include MacIO (CHRP) ADB driver' CONFIG_ADB_MACIO
+ dep_bool ' Use input layer for ADB devices' CONFIG_INPUT_ADBHID $CONFIG_INPUT
+ if [ "$CONFIG_INPUT_ADBHID" = "y" ]; then
+ bool ' Support for ADB raw keycodes' CONFIG_MAC_ADBKEYCODES
+ bool ' Support for mouse button 2+3 emulation' CONFIG_MAC_EMUMOUSEBTN
+ else
+ bool ' Support for ADB keyboard (old driver)' CONFIG_ADB_KEYBOARD
+ fi
fi
fi
endmenu
diff --git a/arch/ppc/configs/apus_defconfig b/arch/ppc/configs/apus_defconfig
index ed930fff2..69e25a9b3 100644
--- a/arch/ppc/configs/apus_defconfig
+++ b/arch/ppc/configs/apus_defconfig
@@ -11,9 +11,7 @@ CONFIG_EXPERIMENTAL=y
#
# Loadable module support
#
-CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
+# CONFIG_MODULES is not set
#
# Platform support
@@ -23,14 +21,14 @@ CONFIG_6xx=y
# CONFIG_4xx is not set
# CONFIG_POWER3 is not set
# CONFIG_POWER4 is not set
-# CONFIG_8260 is not set
# CONFIG_8xx is not set
-CONFIG_ALL_PPC=y
-# CONFIG_GEMINI is not set
-# CONFIG_EST8260 is not set
-# CONFIG_APUS is not set
+# CONFIG_8260 is not set
+# CONFIG_ALL_PPC is not set
+CONFIG_APUS=y
+CONFIG_PPC601_SYNC_FIX=y
# CONFIG_SMP is not set
# CONFIG_ALTIVEC is not set
+CONFIG_MACH_SPECIFIC=y
#
# General setup
@@ -38,8 +36,10 @@ CONFIG_ALL_PPC=y
# CONFIG_HIGHMEM is not set
# CONFIG_MOL is not set
# CONFIG_ISA is not set
+# CONFIG_EISA is not set
# CONFIG_SBUS is not set
-CONFIG_PCI=y
+# CONFIG_MCA is not set
+# CONFIG_PCI is not set
CONFIG_NET=y
CONFIG_SYSCTL=y
CONFIG_SYSVIPC=y
@@ -47,23 +47,35 @@ CONFIG_SYSVIPC=y
CONFIG_KCORE_ELF=y
CONFIG_BINFMT_ELF=y
CONFIG_KERNEL_ELF=y
-CONFIG_BINFMT_MISC=m
-# CONFIG_PCI_NAMES is not set
-# CONFIG_HOTPLUG is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_HOTPLUG=y
+
+#
+# PCMCIA/CardBus support
+#
# CONFIG_PCMCIA is not set
#
# Parallel port support
#
# CONFIG_PARPORT is not set
-# CONFIG_VGA_CONSOLE is not set
+CONFIG_PPC_RTC=y
+CONFIG_FB_CONSOLE=y
+CONFIG_AMIGA=y
+CONFIG_ZORRO=y
+CONFIG_AMIGAMOUSE=y
+CONFIG_ABSTRACT_CONSOLE=y
CONFIG_FB=y
-CONFIG_FB_COMPAT_XPMAC=y
-# CONFIG_PPC_RTC is not set
-CONFIG_PROC_DEVICETREE=y
-# CONFIG_BOOTX_TEXT is not set
-# CONFIG_MOTOROLA_HOTSWAP is not set
-# CONFIG_CMDLINE_BOOL is not set
+CONFIG_AMIGA_BUILTIN_SERIAL=y
+# CONFIG_M68K_PRINTER is not set
+CONFIG_GVPIOEXT=y
+# CONFIG_GVPIOEXT_LP is not set
+CONFIG_GVPIOEXT_PLIP=y
+CONFIG_MULTIFACE_III_TTY=y
+# CONFIG_SERIAL_CONSOLE is not set
+CONFIG_HEARTBEAT=y
+CONFIG_PROC_HARDWARE=y
+CONFIG_ZORRO_NAMES=y
#
# Memory Technology Devices (MTD)
@@ -80,12 +92,14 @@ CONFIG_PROC_DEVICETREE=y
# Block devices
#
# CONFIG_BLK_DEV_FD is not set
+CONFIG_AMIGA_FLOPPY=y
+CONFIG_AMIGA_Z2RAM=y
# CONFIG_BLK_DEV_XD is not set
# CONFIG_PARIDE is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_LOOP is not set
+CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_NBD is not set
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=4096
@@ -106,21 +120,17 @@ CONFIG_BLK_DEV_INITRD=y
#
# Networking options
#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK=y
-# CONFIG_RTNETLINK is not set
-# CONFIG_NETLINK_DEV is not set
+# CONFIG_PACKET is not set
+# CONFIG_NETLINK is not set
# CONFIG_NETFILTER is not set
# CONFIG_FILTER is not set
CONFIG_UNIX=y
CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
+# CONFIG_IP_MULTICAST is not set
# CONFIG_IP_ADVANCED_ROUTER is not set
# CONFIG_IP_PNP is not set
# CONFIG_NET_IPIP is not set
# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
# CONFIG_INET_ECN is not set
# CONFIG_SYN_COOKIES is not set
# CONFIG_IPV6 is not set
@@ -131,7 +141,7 @@ CONFIG_IP_MULTICAST=y
#
#
# CONFIG_IPX is not set
-CONFIG_ATALK=m
+# CONFIG_ATALK is not set
# CONFIG_DECNET is not set
# CONFIG_BRIDGE is not set
# CONFIG_X25 is not set
@@ -151,9 +161,48 @@ CONFIG_ATALK=m
#
# ATA/IDE/MFM/RLL support
#
-# CONFIG_IDE is not set
-# CONFIG_BLK_DEV_IDE_MODES is not set
+CONFIG_IDE=y
+
+#
+# IDE, ATA and ATAPI Block devices
+#
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
# CONFIG_BLK_DEV_HD is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
+# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
+# CONFIG_BLK_DEV_IDEDISK_IBM is not set
+# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
+# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
+# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
+# CONFIG_BLK_DEV_IDEDISK_WD is not set
+# CONFIG_BLK_DEV_COMMERIAL is not set
+# CONFIG_BLK_DEV_TIVO is not set
+# CONFIG_BLK_DEV_IDECS is not set
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
+# CONFIG_BLK_DEV_ISAPNP is not set
+CONFIG_BLK_DEV_GAYLE=y
+CONFIG_BLK_DEV_IDEDOUBLER=y
+CONFIG_BLK_DEV_BUDDHA=y
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_DMA_NONPCI is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
#
# SCSI support
@@ -165,7 +214,8 @@ CONFIG_SCSI=y
#
CONFIG_BLK_DEV_SD=y
CONFIG_SD_EXTRA_DEVS=40
-CONFIG_CHR_DEV_ST=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
CONFIG_BLK_DEV_SR=y
CONFIG_BLK_DEV_SR_VENDOR=y
CONFIG_SR_EXTRA_DEVS=2
@@ -176,29 +226,23 @@ CONFIG_SR_EXTRA_DEVS=2
#
# CONFIG_SCSI_DEBUG_QUEUES is not set
# CONFIG_SCSI_MULTI_LUN is not set
-CONFIG_SCSI_CONSTANTS=y
+# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set
#
# SCSI low-level drivers
#
-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_7000FASST is not set
# CONFIG_SCSI_ACARD is not set
# CONFIG_SCSI_AHA152X is not set
# CONFIG_SCSI_AHA1542 is not set
# CONFIG_SCSI_AHA1740 is not set
-CONFIG_SCSI_AIC7XXX=y
-# CONFIG_AIC7XXX_TCQ_ON_BY_DEFAULT is not set
-CONFIG_AIC7XXX_CMDS_PER_DEVICE=8
-CONFIG_AIC7XXX_PROC_STATS=y
-CONFIG_AIC7XXX_RESET_DELAY=15
+# CONFIG_SCSI_AIC7XXX is not set
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_IN2000 is not set
# CONFIG_SCSI_AM53C974 is not set
# CONFIG_SCSI_MEGARAID is not set
# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_CPQFCTS is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_DTC3280 is not set
# CONFIG_SCSI_EATA is not set
@@ -211,30 +255,18 @@ CONFIG_AIC7XXX_RESET_DELAY=15
# CONFIG_SCSI_INIA100 is not set
# CONFIG_SCSI_NCR53C406A is not set
# CONFIG_SCSI_NCR53C7xx is not set
-# CONFIG_SCSI_NCR53C8XX is not set
-# CONFIG_SCSI_SYM53C8XX is not set
# CONFIG_SCSI_PAS16 is not set
# CONFIG_SCSI_PCI2000 is not set
# CONFIG_SCSI_PCI2220I is not set
# CONFIG_SCSI_PSI240I is not set
# CONFIG_SCSI_QLOGIC_FAS is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
-# CONFIG_SCSI_QLOGIC_1280 is not set
# CONFIG_SCSI_SIM710 is not set
# CONFIG_SCSI_SYM53C416 is not set
-# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_T128 is not set
# CONFIG_SCSI_U14_34F is not set
# CONFIG_SCSI_DEBUG is not set
-CONFIG_SCSI_MESH=y
-CONFIG_SCSI_MESH_SYNC_RATE=5
-CONFIG_SCSI_MAC53C94=y
-
-#
-# IEEE 1394 (FireWire) support
-#
-# CONFIG_IEEE1394 is not set
+# CONFIG_SCSI_MESH is not set
+# CONFIG_SCSI_MAC53C94 is not set
#
# Network device support
@@ -245,34 +277,30 @@ CONFIG_NETDEVICES=y
# ARCnet devices
#
# CONFIG_ARCNET is not set
-
-#
-# Appletalk devices
-#
-# CONFIG_APPLETALK is not set
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
# CONFIG_NET_SB1000 is not set
#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
-CONFIG_MACE=y
-CONFIG_BMAC=y
+# CONFIG_MACE is not set
+# CONFIG_BMAC is not set
# CONFIG_GMAC is not set
-# CONFIG_NCR885E is not set
# CONFIG_OAKNET is not set
+CONFIG_ARIADNE=y
+# CONFIG_NE2K_ZORRO is not set
+CONFIG_A2065=y
+CONFIG_HYDRA=y
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_LANCE is not set
# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_NET_VENDOR_RACAL is not set
# CONFIG_AT1700 is not set
# CONFIG_DEPCA is not set
-# CONFIG_HP100 is not set
# CONFIG_NET_ISA is not set
# CONFIG_NET_PCI is not set
# CONFIG_NET_POCKET is not set
@@ -287,13 +315,16 @@ CONFIG_BMAC=y
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
CONFIG_PPP=y
-# CONFIG_PPP_MULTILINK is not set
-# CONFIG_PPP_ASYNC is not set
-# CONFIG_PPP_SYNC_TTY is not set
-# CONFIG_PPP_DEFLATE is not set
-# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_SYNC_TTY=y
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_BSDCOMP=y
# CONFIG_PPPOE is not set
-# CONFIG_SLIP is not set
+CONFIG_SLIP=y
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+# CONFIG_SLIP_MODE_SLIP6 is not set
#
# Wireless LAN (non-hamradio)
@@ -336,44 +367,47 @@ CONFIG_PPP=y
#
# Console drivers
#
+# CONFIG_VGA_CONSOLE is not set
#
# Frame-buffer support
#
CONFIG_FB=y
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_FB_RIVA is not set
-# CONFIG_FB_CLGEN is not set
-# CONFIG_FB_PM2 is not set
+CONFIG_FB_CLGEN=y
+CONFIG_FB_PM2=y
+CONFIG_FB_PM2_CVPPC=y
# CONFIG_FB_CYBER2000 is not set
-CONFIG_FB_OF=y
-CONFIG_FB_CONTROL=y
-CONFIG_FB_PLATINUM=y
-CONFIG_FB_VALKYRIE=y
-CONFIG_FB_CT65550=y
-CONFIG_FB_IMSTT=y
+CONFIG_FB_AMIGA=y
+CONFIG_FB_AMIGA_OCS=y
+CONFIG_FB_AMIGA_ECS=y
+CONFIG_FB_AMIGA_AGA=y
+CONFIG_FB_CYBER=y
+CONFIG_FB_VIRGE=y
+CONFIG_FB_RETINAZ3=y
+# CONFIG_FB_FM2 is not set
+# CONFIG_FB_OF is not set
+# CONFIG_FB_CONTROL is not set
+# CONFIG_FB_PLATINUM is not set
+# CONFIG_FB_VALKYRIE is not set
+# CONFIG_FB_CT65550 is not set
+# CONFIG_FB_IMSTT is not set
# CONFIG_FB_S3TRIO is not set
# CONFIG_FB_VGA16 is not set
-# CONFIG_FB_MATROX is not set
-CONFIG_FB_ATY=y
-# CONFIG_FB_ATY128 is not set
-# CONFIG_FB_3DFX is not set
-# CONFIG_FB_SIS is not set
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FBCON_ADVANCED is not set
+CONFIG_FBCON_MFB=y
CONFIG_FBCON_CFB8=y
CONFIG_FBCON_CFB16=y
CONFIG_FBCON_CFB24=y
CONFIG_FBCON_CFB32=y
-# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
-CONFIG_FBCON_FONTS=y
-# CONFIG_FONT_8x8 is not set
+CONFIG_FBCON_AFB=y
+CONFIG_FBCON_ILBM=y
+CONFIG_FBCON_FONTWIDTH8_ONLY=y
+# CONFIG_FBCON_FONTS is not set
+CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y
-CONFIG_FONT_SUN8x16=y
-CONFIG_FONT_SUN12x22=y
-# CONFIG_FONT_6x11 is not set
-# CONFIG_FONT_PEARL_8x8 is not set
-# CONFIG_FONT_ACORN_8x8 is not set
+CONFIG_FONT_PEARL_8x8=y
#
# Input core support
@@ -383,23 +417,17 @@ CONFIG_FONT_SUN12x22=y
#
# Macintosh device drivers
#
-# CONFIG_ADB_CUDA is not set
-# CONFIG_ADB_PMU is not set
-CONFIG_MAC_FLOPPY=y
-CONFIG_MAC_SERIAL=y
-# CONFIG_SERIAL_CONSOLE is not set
-# CONFIG_ADB is not set
#
# Character devices
#
CONFIG_VT=y
CONFIG_VT_CONSOLE=y
-CONFIG_SERIAL=m
+CONFIG_SERIAL=y
+# CONFIG_SERIAL_CONSOLE is not set
# CONFIG_SERIAL_EXTENDED is not set
# CONFIG_SERIAL_NONSTANDARD is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=256
+# CONFIG_UNIX98_PTYS is not set
#
# I2C support
@@ -427,7 +455,7 @@ CONFIG_UNIX98_PTY_COUNT=256
#
# CONFIG_WATCHDOG is not set
# CONFIG_INTEL_RNG is not set
-CONFIG_NVRAM=y
+# CONFIG_NVRAM is not set
# CONFIG_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
@@ -449,24 +477,24 @@ CONFIG_NVRAM=y
# File systems
#
# CONFIG_QUOTA is not set
-CONFIG_AUTOFS_FS=y
+# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
# CONFIG_ADFS_FS is not set
# CONFIG_ADFS_FS_RW is not set
-# CONFIG_AFFS_FS is not set
+CONFIG_AFFS_FS=y
CONFIG_HFS_FS=y
# CONFIG_BFS_FS is not set
-CONFIG_FAT_FS=m
-CONFIG_MSDOS_FS=m
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
# CONFIG_UMSDOS_FS is not set
-CONFIG_VFAT_FS=m
+CONFIG_VFAT_FS=y
# CONFIG_EFS_FS is not set
# CONFIG_JFFS_FS is not set
# CONFIG_CRAMFS is not set
# CONFIG_RAMFS is not set
CONFIG_ISO9660_FS=y
# CONFIG_JOLIET is not set
-# CONFIG_MINIX_FS is not set
+CONFIG_MINIX_FS=y
# CONFIG_NTFS_FS is not set
# CONFIG_NTFS_RW is not set
# CONFIG_HPFS_FS is not set
@@ -474,7 +502,7 @@ CONFIG_PROC_FS=y
# CONFIG_DEVFS_FS is not set
# CONFIG_DEVFS_MOUNT is not set
# CONFIG_DEVFS_DEBUG is not set
-CONFIG_DEVPTS_FS=y
+# CONFIG_DEVPTS_FS is not set
# CONFIG_QNX4FS_FS is not set
# CONFIG_QNX4FS_RW is not set
# CONFIG_ROMFS_FS is not set
@@ -493,7 +521,7 @@ CONFIG_EXT2_FS=y
CONFIG_NFS_FS=y
# CONFIG_NFS_V3 is not set
# CONFIG_ROOT_NFS is not set
-CONFIG_NFSD=y
+# CONFIG_NFSD is not set
# CONFIG_NFSD_V3 is not set
CONFIG_SUNRPC=y
CONFIG_LOCKD=y
@@ -505,8 +533,6 @@ CONFIG_LOCKD=y
# CONFIG_NCPFS_NFS_NS is not set
# CONFIG_NCPFS_OS2_NS is not set
# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_MOUNT_SUBDIR is not set
-# CONFIG_NCPFS_NDS_DOMAINS is not set
# CONFIG_NCPFS_NLS is not set
# CONFIG_NCPFS_EXTRAS is not set
@@ -514,14 +540,15 @@ CONFIG_LOCKD=y
# Partition Types
#
# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
+CONFIG_AMIGA_PARTITION=y
+# CONFIG_SMB_NLS is not set
CONFIG_NLS=y
#
# Native Language Support
#
CONFIG_NLS_DEFAULT="iso8859-1"
-CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_437 is not set
# CONFIG_NLS_CODEPAGE_737 is not set
# CONFIG_NLS_CODEPAGE_775 is not set
# CONFIG_NLS_CODEPAGE_850 is not set
@@ -541,7 +568,7 @@ CONFIG_NLS_CODEPAGE_437=y
# CONFIG_NLS_CODEPAGE_936 is not set
# CONFIG_NLS_CODEPAGE_949 is not set
# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_ISO8859_1 is not set
+CONFIG_NLS_ISO8859_1=y
# CONFIG_NLS_ISO8859_2 is not set
# CONFIG_NLS_ISO8859_3 is not set
# CONFIG_NLS_ISO8859_4 is not set
@@ -558,23 +585,7 @@ CONFIG_NLS_CODEPAGE_437=y
#
# Sound
#
-CONFIG_SOUND=y
-# CONFIG_DMASOUND_AWACS is not set
-# CONFIG_SOUND_CMPCI is not set
-# CONFIG_SOUND_EMU10K1 is not set
-# CONFIG_SOUND_FUSION is not set
-# CONFIG_SOUND_CS4281 is not set
-# CONFIG_SOUND_ES1370 is not set
-# CONFIG_SOUND_ES1371 is not set
-# CONFIG_SOUND_ESSSOLO1 is not set
-# CONFIG_SOUND_MAESTRO is not set
-# CONFIG_SOUND_SONICVIBES is not set
-# CONFIG_SOUND_TRIDENT is not set
-# CONFIG_SOUND_MSNDCLAS is not set
-# CONFIG_SOUND_MSNDPIN is not set
-# CONFIG_SOUND_VIA82CXXX is not set
-# CONFIG_SOUND_OSS is not set
-# CONFIG_SOUND_TVMIXER is not set
+# CONFIG_SOUND is not set
#
# USB support
diff --git a/arch/ppc/configs/bseip_defconfig b/arch/ppc/configs/bseip_defconfig
index f0ff611f4..82b7174bd 100644
--- a/arch/ppc/configs/bseip_defconfig
+++ b/arch/ppc/configs/bseip_defconfig
@@ -21,7 +21,6 @@ CONFIG_PPC=y
# CONFIG_4xx is not set
# CONFIG_POWER3 is not set
# CONFIG_POWER4 is not set
-# CONFIG_8260 is not set
CONFIG_8xx=y
CONFIG_SERIAL_CONSOLE=y
# CONFIG_RPXLITE is not set
@@ -32,6 +31,7 @@ CONFIG_BSEIP=y
# CONFIG_TQM860 is not set
# CONFIG_MBX is not set
# CONFIG_WINCEPT is not set
+CONFIG_PPC601_SYNC_FIX=y
# CONFIG_ALL_PPC is not set
# CONFIG_SMP is not set
CONFIG_MACH_SPECIFIC=y
@@ -43,7 +43,9 @@ CONFIG_MATH_EMULATION=y
# CONFIG_HIGHMEM is not set
# CONFIG_MOL is not set
# CONFIG_ISA is not set
+# CONFIG_EISA is not set
# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
# CONFIG_PCI_QSPAN is not set
# CONFIG_PCI is not set
CONFIG_NET=y
@@ -182,7 +184,6 @@ CONFIG_NET_ETHERNET=y
# CONFIG_MACE is not set
# CONFIG_BMAC is not set
# CONFIG_GMAC is not set
-# CONFIG_NCR885E is not set
# CONFIG_OAKNET is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_LANCE is not set
@@ -190,7 +191,6 @@ CONFIG_NET_ETHERNET=y
# CONFIG_NET_VENDOR_RACAL is not set
# CONFIG_AT1700 is not set
# CONFIG_DEPCA is not set
-# CONFIG_HP100 is not set
# CONFIG_NET_ISA is not set
# CONFIG_NET_PCI is not set
# CONFIG_NET_POCKET is not set
@@ -377,8 +377,6 @@ CONFIG_LOCKD=y
# CONFIG_NCPFS_NFS_NS is not set
# CONFIG_NCPFS_OS2_NS is not set
# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_MOUNT_SUBDIR is not set
-# CONFIG_NCPFS_NDS_DOMAINS is not set
# CONFIG_NCPFS_NLS is not set
# CONFIG_NCPFS_EXTRAS is not set
@@ -395,6 +393,7 @@ CONFIG_PARTITION_ADVANCED=y
# CONFIG_SGI_PARTITION is not set
# CONFIG_ULTRIX_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
+# CONFIG_SMB_NLS is not set
# CONFIG_NLS is not set
#
diff --git a/arch/ppc/configs/common_defconfig b/arch/ppc/configs/common_defconfig
index 5574ecbdb..210887de7 100644
--- a/arch/ppc/configs/common_defconfig
+++ b/arch/ppc/configs/common_defconfig
@@ -23,12 +23,11 @@ CONFIG_6xx=y
# CONFIG_4xx is not set
# CONFIG_POWER3 is not set
# CONFIG_POWER4 is not set
-# CONFIG_8260 is not set
# CONFIG_8xx is not set
+# CONFIG_8260 is not set
CONFIG_ALL_PPC=y
-# CONFIG_GEMINI is not set
-# CONFIG_EST8260 is not set
# CONFIG_APUS is not set
+CONFIG_PPC601_SYNC_FIX=y
# CONFIG_SMP is not set
CONFIG_ALTIVEC=y
@@ -36,9 +35,11 @@ CONFIG_ALTIVEC=y
# General setup
#
# CONFIG_HIGHMEM is not set
-# CONFIG_MOL is not set
+CONFIG_MOL=y
# CONFIG_ISA is not set
+# CONFIG_EISA is not set
# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
CONFIG_PCI=y
CONFIG_NET=y
CONFIG_SYSCTL=y
@@ -49,21 +50,24 @@ CONFIG_BINFMT_ELF=y
CONFIG_KERNEL_ELF=y
CONFIG_BINFMT_MISC=m
CONFIG_PCI_NAMES=y
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
+
+#
+# PCMCIA/CardBus support
+#
# CONFIG_PCMCIA is not set
#
# Parallel port support
#
# CONFIG_PARPORT is not set
-CONFIG_VGA_CONSOLE=y
-CONFIG_FB=y
-CONFIG_FB_COMPAT_XPMAC=y
CONFIG_PPC_RTC=y
CONFIG_PROC_DEVICETREE=y
+CONFIG_PPC_RTAS=y
CONFIG_BOOTX_TEXT=y
-# CONFIG_MOTOROLA_HOTSWAP is not set
-# CONFIG_CMDLINE_BOOL is not set
+CONFIG_PREP_RESIDUAL=y
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttyS0,9600 console=tty0 root=/dev/sda2"
#
# Memory Technology Devices (MTD)
@@ -79,7 +83,7 @@ CONFIG_BOOTX_TEXT=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
+CONFIG_BLK_DEV_FD=m
# CONFIG_BLK_DEV_XD is not set
# CONFIG_PARIDE is not set
# CONFIG_BLK_CPQ_DA is not set
@@ -111,7 +115,8 @@ CONFIG_PACKET=y
CONFIG_NETLINK=y
# CONFIG_RTNETLINK is not set
# CONFIG_NETLINK_DEV is not set
-# CONFIG_NETFILTER is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
# CONFIG_FILTER is not set
CONFIG_UNIX=y
CONFIG_INET=y
@@ -123,6 +128,34 @@ CONFIG_IP_MULTICAST=y
# CONFIG_IP_MROUTE is not set
# CONFIG_INET_ECN is not set
CONFIG_SYN_COOKIES=y
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+CONFIG_IP_NF_FTP=m
+# CONFIG_IP_NF_QUEUE is not set
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_LIMIT=m
+CONFIG_IP_NF_MATCH_MAC=m
+CONFIG_IP_NF_MATCH_MARK=m
+CONFIG_IP_NF_MATCH_MULTIPORT=m
+CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_STATE=m
+CONFIG_IP_NF_MATCH_UNCLEAN=m
+CONFIG_IP_NF_MATCH_OWNER=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_MIRROR=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+# CONFIG_IP_NF_MANGLE is not set
+# CONFIG_IP_NF_TARGET_LOG is not set
+CONFIG_IP_NF_COMPAT_IPCHAINS=m
+CONFIG_IP_NF_NAT_NEEDED=y
+# CONFIG_IP_NF_COMPAT_IPFWADM is not set
# CONFIG_IPV6 is not set
# CONFIG_KHTTPD is not set
# CONFIG_ATM is not set
@@ -239,6 +272,7 @@ CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
CONFIG_SD_EXTRA_DEVS=40
CONFIG_CHR_DEV_ST=y
+# CONFIG_CHR_DEV_OSST is not set
CONFIG_BLK_DEV_SR=y
CONFIG_BLK_DEV_SR_VENDOR=y
CONFIG_SR_EXTRA_DEVS=2
@@ -344,7 +378,6 @@ CONFIG_NET_ETHERNET=y
CONFIG_MACE=y
CONFIG_BMAC=y
CONFIG_GMAC=y
-# CONFIG_NCR885E is not set
# CONFIG_OAKNET is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_LANCE is not set
@@ -357,27 +390,28 @@ CONFIG_GMAC=y
CONFIG_NET_PCI=y
CONFIG_PCNET32=y
# CONFIG_ADAPTEC_STARFIRE is not set
-# CONFIG_AC3200 is not set
# CONFIG_APRICOT is not set
# CONFIG_CS89x0 is not set
-CONFIG_DE4X5=y
-# CONFIG_TULIP is not set
+CONFIG_TULIP=y
+CONFIG_DE4X5=m
# CONFIG_DGRS is not set
# CONFIG_DM9102 is not set
# CONFIG_EEPRO100 is not set
+# CONFIG_EEPRO100_PM is not set
# CONFIG_LNE390 is not set
# CONFIG_NATSEMI is not set
# CONFIG_NE2K_PCI is not set
# CONFIG_NE3210 is not set
# CONFIG_ES3210 is not set
-# CONFIG_RTL8129 is not set
# CONFIG_8139TOO is not set
+# CONFIG_RTL8129 is not set
# CONFIG_SIS900 is not set
# CONFIG_EPIC100 is not set
# CONFIG_SUNDANCE is not set
# CONFIG_TLAN is not set
# CONFIG_VIA_RHINE is not set
# CONFIG_WINBOND_840 is not set
+# CONFIG_HAPPYMEAL is not set
# CONFIG_NET_POCKET is not set
#
@@ -439,6 +473,7 @@ CONFIG_PPP_DEFLATE=y
#
# Console drivers
#
+CONFIG_VGA_CONSOLE=y
#
# Frame-buffer support
@@ -460,7 +495,8 @@ CONFIG_FB_IMSTT=y
CONFIG_FB_MATROX=y
CONFIG_FB_MATROX_MILLENIUM=y
CONFIG_FB_MATROX_MYSTIQUE=y
-CONFIG_FB_MATROX_G100=y
+# CONFIG_FB_MATROX_G100 is not set
+# CONFIG_FB_MATROX_G450 is not set
# CONFIG_FB_MATROX_MULTIHEAD is not set
CONFIG_FB_ATY=y
CONFIG_FB_ATY128=y
@@ -481,6 +517,7 @@ CONFIG_FONT_SUN12x22=y
# CONFIG_FONT_6x11 is not set
# CONFIG_FONT_PEARL_8x8 is not set
# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FB_COMPAT_XPMAC is not set
#
# Input core support
@@ -498,15 +535,13 @@ CONFIG_INPUT_EVDEV=y
#
CONFIG_ADB_CUDA=y
CONFIG_ADB_PMU=y
-CONFIG_PMAC_PBOOK=y
-CONFIG_PMAC_BACKLIGHT=y
-CONFIG_MAC_FLOPPY=y
-CONFIG_MAC_SERIAL=y
-# CONFIG_SERIAL_CONSOLE is not set
+# CONFIG_PMAC_PBOOK is not set
+# CONFIG_PMAC_BACKLIGHT is not set
+# CONFIG_MAC_FLOPPY is not set
+CONFIG_MAC_SERIAL=m
CONFIG_ADB=y
CONFIG_ADB_MACIO=y
CONFIG_INPUT_ADBHID=y
-CONFIG_MAC_HID=y
CONFIG_MAC_ADBKEYCODES=y
CONFIG_MAC_EMUMOUSEBTN=y
@@ -575,17 +610,17 @@ CONFIG_NVRAM=y
# File systems
#
# CONFIG_QUOTA is not set
-CONFIG_AUTOFS_FS=y
-CONFIG_AUTOFS4_FS=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
# CONFIG_ADFS_FS is not set
# CONFIG_ADFS_FS_RW is not set
# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
+CONFIG_HFS_FS=m
# CONFIG_BFS_FS is not set
-CONFIG_FAT_FS=y
-CONFIG_MSDOS_FS=y
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
# CONFIG_UMSDOS_FS is not set
-CONFIG_VFAT_FS=y
+CONFIG_VFAT_FS=m
# CONFIG_EFS_FS is not set
# CONFIG_JFFS_FS is not set
# CONFIG_CRAMFS is not set
@@ -631,8 +666,6 @@ CONFIG_LOCKD=y
# CONFIG_NCPFS_NFS_NS is not set
# CONFIG_NCPFS_OS2_NS is not set
# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_MOUNT_SUBDIR is not set
-# CONFIG_NCPFS_NDS_DOMAINS is not set
# CONFIG_NCPFS_NLS is not set
# CONFIG_NCPFS_EXTRAS is not set
@@ -652,6 +685,7 @@ CONFIG_MSDOS_PARTITION=y
# CONFIG_SGI_PARTITION is not set
# CONFIG_ULTRIX_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
+# CONFIG_SMB_NLS is not set
CONFIG_NLS=y
#
@@ -678,7 +712,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
# CONFIG_NLS_CODEPAGE_936 is not set
# CONFIG_NLS_CODEPAGE_949 is not set
# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_ISO8859_1 is not set
+CONFIG_NLS_ISO8859_1=m
# CONFIG_NLS_ISO8859_2 is not set
# CONFIG_NLS_ISO8859_3 is not set
# CONFIG_NLS_ISO8859_4 is not set
@@ -695,9 +729,9 @@ CONFIG_NLS_DEFAULT="iso8859-1"
#
# Sound
#
-CONFIG_SOUND=y
-CONFIG_DMASOUND_AWACS=y
-CONFIG_DMASOUND=y
+CONFIG_SOUND=m
+CONFIG_DMASOUND_AWACS=m
+CONFIG_DMASOUND=m
# CONFIG_SOUND_CMPCI is not set
# CONFIG_SOUND_EMU10K1 is not set
# CONFIG_SOUND_FUSION is not set
@@ -711,43 +745,14 @@ CONFIG_DMASOUND=y
# CONFIG_SOUND_MSNDCLAS is not set
# CONFIG_SOUND_MSNDPIN is not set
# CONFIG_SOUND_VIA82CXXX is not set
-CONFIG_SOUND_OSS=y
-# CONFIG_SOUND_TRACEINIT is not set
-# CONFIG_SOUND_DMAP is not set
-# CONFIG_SOUND_AD1816 is not set
-# CONFIG_SOUND_SGALAXY is not set
-# CONFIG_SOUND_ADLIB is not set
-# CONFIG_SOUND_ACI_MIXER is not set
-CONFIG_SOUND_CS4232=m
-# CONFIG_SOUND_SSCAPE is not set
-# CONFIG_SOUND_GUS is not set
-# CONFIG_SOUND_ICH is not set
-# CONFIG_SOUND_VMIDI is not set
-# CONFIG_SOUND_TRIX is not set
-# CONFIG_SOUND_MSS is not set
-# CONFIG_SOUND_MPU401 is not set
-# CONFIG_SOUND_NM256 is not set
-# CONFIG_SOUND_MAD16 is not set
-# CONFIG_SOUND_PAS is not set
-# CONFIG_PAS_JOYSTICK is not set
-# CONFIG_SOUND_PSS is not set
-# CONFIG_SOUND_SB is not set
-# CONFIG_SOUND_AWE32_SYNTH is not set
-# CONFIG_SOUND_WAVEFRONT is not set
-# CONFIG_SOUND_MAUI is not set
-# CONFIG_SOUND_YM3812 is not set
-# CONFIG_SOUND_OPL3SA1 is not set
-# CONFIG_SOUND_OPL3SA2 is not set
-# CONFIG_SOUND_YMPCI is not set
-# CONFIG_SOUND_UART6850 is not set
-# CONFIG_SOUND_AEDSP16 is not set
+# CONFIG_SOUND_OSS is not set
# CONFIG_SOUND_TVMIXER is not set
#
# USB support
#
CONFIG_USB=y
-CONFIG_USB_DEBUG=y
+# CONFIG_USB_DEBUG is not set
#
# Miscellaneous USB options
@@ -763,33 +768,69 @@ CONFIG_USB_DEVICEFS=y
CONFIG_USB_OHCI=y
#
-# USB Devices
+# USB Device Class drivers
#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_BLUETOOTH is not set
+# CONFIG_USB_STORAGE is not set
+CONFIG_USB_ACM=m
# CONFIG_USB_PRINTER is not set
+
+#
+# USB Human Interface Devices (HID)
+#
+CONFIG_USB_HID=y
+# CONFIG_USB_WACOM is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
# CONFIG_USB_SCANNER is not set
# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_AUDIO is not set
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_SERIAL is not set
+
+#
+# USB Multimedia devices
+#
# CONFIG_USB_IBMCAM is not set
# CONFIG_USB_OV511 is not set
-# CONFIG_USB_DC2XX is not set
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_STORAGE is not set
-# CONFIG_USB_USS720 is not set
+# CONFIG_USB_DSBR is not set
# CONFIG_USB_DABUSB is not set
+
+#
+# USB Network adaptors
+#
# CONFIG_USB_PLUSB is not set
# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_DSBR is not set
-# CONFIG_USB_BLUETOOTH is not set
# CONFIG_USB_NET1080 is not set
#
-# USB Human Interface Devices (HID)
+# USB port drivers
#
-CONFIG_USB_HID=y
-# CONFIG_USB_WACOM is not set
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=m
+# CONFIG_USB_SERIAL_DEBUG is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+CONFIG_USB_SERIAL_VISOR=m
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+
+#
+# USB misc drivers
+#
+# CONFIG_USB_RIO500 is not set
#
# Kernel hacking
diff --git a/arch/ppc/configs/est8260_defconfig b/arch/ppc/configs/est8260_defconfig
index afb972c03..a4a44f0ab 100644
--- a/arch/ppc/configs/est8260_defconfig
+++ b/arch/ppc/configs/est8260_defconfig
@@ -17,21 +17,17 @@ CONFIG_EXPERIMENTAL=y
# Platform support
#
CONFIG_PPC=y
-# CONFIG_6xx is not set
+CONFIG_6xx=y
# CONFIG_4xx is not set
# CONFIG_POWER3 is not set
# CONFIG_POWER4 is not set
-CONFIG_8260=y
# CONFIG_8xx is not set
-CONFIG_6xx=y
+CONFIG_8260=y
CONFIG_SERIAL_CONSOLE=y
-# CONFIG_ALL_PPC is not set
-# CONFIG_GEMINI is not set
CONFIG_EST8260=y
-# CONFIG_APUS is not set
+CONFIG_PPC601_SYNC_FIX=y
# CONFIG_ALL_PPC is not set
# CONFIG_SMP is not set
-# CONFIG_ALTIVEC is not set
CONFIG_MACH_SPECIFIC=y
#
@@ -40,7 +36,9 @@ CONFIG_MACH_SPECIFIC=y
# CONFIG_HIGHMEM is not set
# CONFIG_MOL is not set
# CONFIG_ISA is not set
+# CONFIG_EISA is not set
# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
# CONFIG_PCI is not set
CONFIG_NET=y
CONFIG_SYSCTL=y
@@ -57,12 +55,7 @@ CONFIG_KERNEL_ELF=y
# Parallel port support
#
# CONFIG_PARPORT is not set
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_FB is not set
# CONFIG_PPC_RTC is not set
-# CONFIG_PROC_DEVICETREE is not set
-# CONFIG_BOOTX_TEXT is not set
-# CONFIG_MOTOROLA_HOTSWAP is not set
#
# Memory Technology Devices (MTD)
@@ -184,7 +177,6 @@ CONFIG_NET_ETHERNET=y
# CONFIG_MACE is not set
# CONFIG_BMAC is not set
# CONFIG_GMAC is not set
-# CONFIG_NCR885E is not set
# CONFIG_OAKNET is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_LANCE is not set
@@ -192,7 +184,6 @@ CONFIG_NET_ETHERNET=y
# CONFIG_NET_VENDOR_RACAL is not set
# CONFIG_AT1700 is not set
# CONFIG_DEPCA is not set
-# CONFIG_HP100 is not set
# CONFIG_NET_ISA is not set
# CONFIG_NET_PCI is not set
# CONFIG_NET_POCKET is not set
@@ -250,6 +241,7 @@ CONFIG_NET_ETHERNET=y
#
# Console drivers
#
+# CONFIG_VGA_CONSOLE is not set
#
# Frame-buffer support
@@ -379,8 +371,6 @@ CONFIG_LOCKD=y
# CONFIG_NCPFS_NFS_NS is not set
# CONFIG_NCPFS_OS2_NS is not set
# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_MOUNT_SUBDIR is not set
-# CONFIG_NCPFS_NDS_DOMAINS is not set
# CONFIG_NCPFS_NLS is not set
# CONFIG_NCPFS_EXTRAS is not set
@@ -397,6 +387,7 @@ CONFIG_PARTITION_ADVANCED=y
# CONFIG_SGI_PARTITION is not set
# CONFIG_ULTRIX_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
+# CONFIG_SMB_NLS is not set
# CONFIG_NLS is not set
#
diff --git a/arch/ppc/configs/ibmchrp_defconfig b/arch/ppc/configs/ibmchrp_defconfig
new file mode 100644
index 000000000..652b94209
--- /dev/null
+++ b/arch/ppc/configs/ibmchrp_defconfig
@@ -0,0 +1,636 @@
+#
+# Automatically generated by make menuconfig: don't edit
+#
+# CONFIG_UID16 is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# Platform support
+#
+CONFIG_PPC=y
+CONFIG_6xx=y
+# CONFIG_4xx is not set
+# CONFIG_POWER3 is not set
+# CONFIG_POWER4 is not set
+# CONFIG_8260 is not set
+# CONFIG_8xx is not set
+CONFIG_ALL_PPC=y
+# CONFIG_GEMINI is not set
+# CONFIG_APUS is not set
+# CONFIG_PPC601_SYNC_FIX is not set
+# CONFIG_SMP is not set
+# CONFIG_ALTIVEC is not set
+
+#
+# General setup
+#
+CONFIG_HIGHMEM=y
+# CONFIG_MOL is not set
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_PCI=y
+CONFIG_NET=y
+CONFIG_SYSCTL=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_KCORE_ELF=y
+CONFIG_BINFMT_ELF=y
+CONFIG_KERNEL_ELF=y
+CONFIG_BINFMT_MISC=y
+CONFIG_PCI_NAMES=y
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+CONFIG_PPC_RTC=y
+CONFIG_PROC_DEVICETREE=y
+CONFIG_PPC_RTAS=y
+# CONFIG_BOOTX_TEXT is not set
+# CONFIG_PREP_RESIDUAL is not set
+# CONFIG_CMDLINE_BOOL is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+CONFIG_BLK_DEV_FD=y
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_BLK_DEV_LVM is not set
+# CONFIG_LVM_PROC_FS is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK=y
+# CONFIG_RTNETLINK is not set
+# CONFIG_NETLINK_DEV is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_INET_ECN is not set
+CONFIG_SYN_COOKIES=y
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+CONFIG_IP_NF_FTP=m
+# CONFIG_IP_NF_QUEUE is not set
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_LIMIT=m
+CONFIG_IP_NF_MATCH_MAC=m
+CONFIG_IP_NF_MATCH_MARK=m
+CONFIG_IP_NF_MATCH_MULTIPORT=m
+CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_STATE=m
+CONFIG_IP_NF_MATCH_UNCLEAN=m
+CONFIG_IP_NF_MATCH_OWNER=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_MIRROR=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+# CONFIG_IP_NF_MANGLE is not set
+# CONFIG_IP_NF_TARGET_LOG is not set
+CONFIG_IP_NF_COMPAT_IPCHAINS=m
+CONFIG_IP_NF_NAT_NEEDED=y
+# CONFIG_IP_NF_COMPAT_IPFWADM is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_SD_EXTRA_DEVS=40
+CONFIG_CHR_DEV_ST=y
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_SR_EXTRA_DEVS=2
+CONFIG_CHR_DEV_SG=y
+# CONFIG_SCSI_DEBUG_QUEUES is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_7000FASST is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AHA152X is not set
+# CONFIG_SCSI_AHA1542 is not set
+# CONFIG_SCSI_AHA1740 is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_AM53C974 is not set
+# CONFIG_SCSI_MEGARAID is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_CPQFCTS is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_EATA_DMA is not set
+# CONFIG_SCSI_EATA_PIO is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_NCR53C7xx is not set
+# CONFIG_SCSI_NCR53C8XX is not set
+CONFIG_SCSI_SYM53C8XX=y
+CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8
+CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32
+CONFIG_SCSI_NCR53C8XX_SYNC=20
+# CONFIG_SCSI_NCR53C8XX_PROFILE is not set
+# CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set
+# CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set
+# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_PCI2000 is not set
+# CONFIG_SCSI_PCI2220I is not set
+# CONFIG_SCSI_PSI240I is not set
+# CONFIG_SCSI_QLOGIC_FAS is not set
+# CONFIG_SCSI_QLOGIC_ISP is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_MESH is not set
+# CONFIG_SCSI_MAC53C94 is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+# CONFIG_NET_SB1000 is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MACE is not set
+# CONFIG_BMAC is not set
+# CONFIG_GMAC is not set
+# CONFIG_NCR885E is not set
+# CONFIG_OAKNET is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=y
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_TULIP is not set
+CONFIG_DE4X5=y
+# CONFIG_DGRS is not set
+# CONFIG_DM9102 is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_EEPRO100_PM is not set
+# CONFIG_LNE390 is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_NE3210 is not set
+# CONFIG_ES3210 is not set
+# CONFIG_8139TOO is not set
+# CONFIG_RTL8129 is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_WINBOND_840 is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+CONFIG_TR=y
+# CONFIG_IBMTR is not set
+CONFIG_IBMOL=y
+# CONFIG_IBMLS is not set
+# CONFIG_TMS380TR is not set
+# CONFIG_SMCTR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Console drivers
+#
+CONFIG_VGA_CONSOLE=y
+
+#
+# Frame-buffer support
+#
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_CLGEN is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+CONFIG_FB_OF=y
+# CONFIG_FB_CONTROL is not set
+# CONFIG_FB_PLATINUM is not set
+# CONFIG_FB_VALKYRIE is not set
+# CONFIG_FB_CT65550 is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_S3TRIO is not set
+# CONFIG_FB_VGA16 is not set
+CONFIG_FB_MATROX=y
+CONFIG_FB_MATROX_MILLENIUM=y
+CONFIG_FB_MATROX_MYSTIQUE=y
+CONFIG_FB_MATROX_G100=y
+# CONFIG_FB_MATROX_G450 is not set
+# CONFIG_FB_MATROX_MULTIHEAD is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_ATY128 is not set
+CONFIG_FB_3DFX=y
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FBCON_ADVANCED is not set
+CONFIG_FBCON_CFB8=y
+CONFIG_FBCON_CFB16=y
+CONFIG_FBCON_CFB24=y
+CONFIG_FBCON_CFB32=y
+# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
+CONFIG_FBCON_FONTS=y
+# CONFIG_FONT_8x8 is not set
+CONFIG_FONT_8x16=y
+CONFIG_FONT_SUN8x16=y
+CONFIG_FONT_SUN12x22=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FB_COMPAT_XPMAC is not set
+
+#
+# Input core support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_KEYBDEV=y
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+
+#
+# Macintosh device drivers
+#
+# CONFIG_ADB_CUDA is not set
+# CONFIG_ADB_PMU is not set
+# CONFIG_MAC_FLOPPY is not set
+# CONFIG_MAC_SERIAL is not set
+# CONFIG_ADB is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+CONFIG_BUSMOUSE=y
+# CONFIG_ATIXL_BUSMOUSE is not set
+# CONFIG_LOGIBUSMOUSE is not set
+# CONFIG_MS_BUSMOUSE is not set
+CONFIG_MOUSE=y
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
+
+#
+# Joysticks
+#
+# CONFIG_JOYSTICK is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
+CONFIG_NVRAM=y
+CONFIG_RTC=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+# CONFIG_UMSDOS_FS is not set
+CONFIG_VFAT_FS=m
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_RAMFS is not set
+CONFIG_ISO9660_FS=y
+# CONFIG_JOLIET is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+CONFIG_DEVFS_FS=y
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_SYSV_FS_WRITE is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_NFS_FS is not set
+# CONFIG_NFS_V3 is not set
+# CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+# CONFIG_SUNRPC is not set
+# CONFIG_LOCKD is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_SMB_NLS is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Kernel hacking
+#
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_KGDB is not set
+CONFIG_XMON=y
diff --git a/arch/ppc/configs/mbx_defconfig b/arch/ppc/configs/mbx_defconfig
index 6230f5877..81829327a 100644
--- a/arch/ppc/configs/mbx_defconfig
+++ b/arch/ppc/configs/mbx_defconfig
@@ -21,7 +21,6 @@ CONFIG_PPC=y
# CONFIG_4xx is not set
# CONFIG_POWER3 is not set
# CONFIG_POWER4 is not set
-# CONFIG_8260 is not set
CONFIG_8xx=y
CONFIG_SERIAL_CONSOLE=y
# CONFIG_RPXLITE is not set
@@ -32,6 +31,7 @@ CONFIG_SERIAL_CONSOLE=y
# CONFIG_TQM860 is not set
CONFIG_MBX=y
# CONFIG_WINCEPT is not set
+CONFIG_PPC601_SYNC_FIX=y
# CONFIG_ALL_PPC is not set
# CONFIG_SMP is not set
CONFIG_MACH_SPECIFIC=y
@@ -43,7 +43,9 @@ CONFIG_MATH_EMULATION=y
# CONFIG_HIGHMEM is not set
# CONFIG_MOL is not set
# CONFIG_ISA is not set
+# CONFIG_EISA is not set
# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
# CONFIG_PCI_QSPAN is not set
# CONFIG_PCI is not set
CONFIG_NET=y
@@ -176,7 +178,6 @@ CONFIG_NET_ETHERNET=y
# CONFIG_MACE is not set
# CONFIG_BMAC is not set
# CONFIG_GMAC is not set
-# CONFIG_NCR885E is not set
# CONFIG_OAKNET is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_LANCE is not set
@@ -184,7 +185,6 @@ CONFIG_NET_ETHERNET=y
# CONFIG_NET_VENDOR_RACAL is not set
# CONFIG_AT1700 is not set
# CONFIG_DEPCA is not set
-# CONFIG_HP100 is not set
# CONFIG_NET_ISA is not set
# CONFIG_NET_PCI is not set
# CONFIG_NET_POCKET is not set
@@ -370,8 +370,6 @@ CONFIG_LOCKD=y
# CONFIG_NCPFS_NFS_NS is not set
# CONFIG_NCPFS_OS2_NS is not set
# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_MOUNT_SUBDIR is not set
-# CONFIG_NCPFS_NDS_DOMAINS is not set
# CONFIG_NCPFS_NLS is not set
# CONFIG_NCPFS_EXTRAS is not set
@@ -388,6 +386,7 @@ CONFIG_PARTITION_ADVANCED=y
# CONFIG_SGI_PARTITION is not set
# CONFIG_ULTRIX_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
+# CONFIG_SMB_NLS is not set
# CONFIG_NLS is not set
#
diff --git a/arch/ppc/configs/oak_defconfig b/arch/ppc/configs/oak_defconfig
index f33966d35..d8f39c36e 100644
--- a/arch/ppc/configs/oak_defconfig
+++ b/arch/ppc/configs/oak_defconfig
@@ -12,7 +12,7 @@ CONFIG_EXPERIMENTAL=y
# Loadable module support
#
CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
+CONFIG_MODVERSIONS=y
CONFIG_KMOD=y
#
@@ -23,10 +23,10 @@ CONFIG_PPC=y
CONFIG_4xx=y
# CONFIG_POWER3 is not set
# CONFIG_POWER4 is not set
-# CONFIG_8260 is not set
# CONFIG_8xx is not set
CONFIG_OAK=y
# CONFIG_WALNUT is not set
+CONFIG_PPC601_SYNC_FIX=y
# CONFIG_SMP is not set
CONFIG_MACH_SPECIFIC=y
# CONFIG_MATH_EMULATION is not set
@@ -37,7 +37,9 @@ CONFIG_MACH_SPECIFIC=y
# CONFIG_HIGHMEM is not set
# CONFIG_MOL is not set
# CONFIG_ISA is not set
+# CONFIG_EISA is not set
# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
# CONFIG_PCI is not set
CONFIG_NET=y
CONFIG_SYSCTL=y
@@ -171,7 +173,6 @@ CONFIG_NET_ETHERNET=y
# CONFIG_MACE is not set
# CONFIG_BMAC is not set
# CONFIG_GMAC is not set
-# CONFIG_NCR885E is not set
CONFIG_OAKNET=y
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_LANCE is not set
@@ -179,7 +180,6 @@ CONFIG_OAKNET=y
# CONFIG_NET_VENDOR_RACAL is not set
# CONFIG_AT1700 is not set
# CONFIG_DEPCA is not set
-# CONFIG_HP100 is not set
# CONFIG_NET_ISA is not set
# CONFIG_NET_PCI is not set
# CONFIG_NET_POCKET is not set
@@ -366,8 +366,6 @@ CONFIG_LOCKD=y
# CONFIG_NCPFS_NFS_NS is not set
# CONFIG_NCPFS_OS2_NS is not set
# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_MOUNT_SUBDIR is not set
-# CONFIG_NCPFS_NDS_DOMAINS is not set
# CONFIG_NCPFS_NLS is not set
# CONFIG_NCPFS_EXTRAS is not set
@@ -376,6 +374,7 @@ CONFIG_LOCKD=y
#
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
# CONFIG_NLS is not set
#
diff --git a/arch/ppc/configs/power3_defconfig b/arch/ppc/configs/power3_defconfig
new file mode 100644
index 000000000..0deb9b5e8
--- /dev/null
+++ b/arch/ppc/configs/power3_defconfig
@@ -0,0 +1,662 @@
+#
+# Automatically generated by make menuconfig: don't edit
+#
+# CONFIG_UID16 is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# Platform support
+#
+CONFIG_PPC=y
+# CONFIG_6xx is not set
+# CONFIG_4xx is not set
+CONFIG_POWER3=y
+# CONFIG_POWER4 is not set
+# CONFIG_8xx is not set
+CONFIG_PPC64BRIDGE=y
+CONFIG_ALL_PPC=y
+CONFIG_SMP=y
+
+#
+# General setup
+#
+CONFIG_HIGHMEM=y
+# CONFIG_MOL is not set
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_PCI=y
+CONFIG_NET=y
+CONFIG_SYSCTL=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_KCORE_ELF=y
+CONFIG_BINFMT_ELF=y
+CONFIG_KERNEL_ELF=y
+CONFIG_BINFMT_MISC=y
+CONFIG_PCI_NAMES=y
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
+CONFIG_PARPORT_PC_FIFO=y
+# CONFIG_PARPORT_PC_SUPERIO is not set
+# CONFIG_PARPORT_AMIGA is not set
+# CONFIG_PARPORT_MFC3 is not set
+# CONFIG_PARPORT_ATARI is not set
+# CONFIG_PARPORT_SUNBPP is not set
+# CONFIG_PARPORT_OTHER is not set
+# CONFIG_PARPORT_1284 is not set
+# CONFIG_PPC_RTC is not set
+CONFIG_PROC_DEVICETREE=y
+CONFIG_PPC_RTAS=y
+# CONFIG_BOOTX_TEXT is not set
+# CONFIG_PREP_RESIDUAL is not set
+# CONFIG_CMDLINE_BOOL is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+CONFIG_BLK_DEV_FD=y
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=y
+CONFIG_MD_RAID0=y
+CONFIG_MD_RAID1=y
+CONFIG_MD_RAID5=y
+# CONFIG_MD_BOOT is not set
+# CONFIG_AUTODETECT_RAID is not set
+CONFIG_BLK_DEV_LVM=y
+CONFIG_LVM_PROC_FS=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK=y
+# CONFIG_RTNETLINK is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_INET_ECN is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_SD_EXTRA_DEVS=40
+CONFIG_CHR_DEV_ST=y
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_SR_EXTRA_DEVS=2
+CONFIG_CHR_DEV_SG=y
+# CONFIG_SCSI_DEBUG_QUEUES is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_7000FASST is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AHA152X is not set
+# CONFIG_SCSI_AHA1542 is not set
+# CONFIG_SCSI_AHA1740 is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_AM53C974 is not set
+# CONFIG_SCSI_MEGARAID is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_CPQFCTS is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_EATA_DMA is not set
+# CONFIG_SCSI_EATA_PIO is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_PPA is not set
+# CONFIG_SCSI_IMM is not set
+# CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_NCR53C7xx is not set
+# CONFIG_SCSI_NCR53C8XX is not set
+CONFIG_SCSI_SYM53C8XX=y
+CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8
+CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32
+CONFIG_SCSI_NCR53C8XX_SYNC=20
+# CONFIG_SCSI_NCR53C8XX_PROFILE is not set
+# CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set
+# CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set
+# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_PCI2000 is not set
+# CONFIG_SCSI_PCI2220I is not set
+# CONFIG_SCSI_PSI240I is not set
+# CONFIG_SCSI_QLOGIC_FAS is not set
+# CONFIG_SCSI_QLOGIC_ISP is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_MESH is not set
+# CONFIG_SCSI_MAC53C94 is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+# CONFIG_NET_SB1000 is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MACE is not set
+# CONFIG_BMAC is not set
+# CONFIG_GMAC is not set
+# CONFIG_OAKNET is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=y
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_TULIP is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_DGRS is not set
+# CONFIG_DM9102 is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_EEPRO100_PM is not set
+# CONFIG_LNE390 is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_NE3210 is not set
+# CONFIG_ES3210 is not set
+# CONFIG_8139TOO is not set
+# CONFIG_RTL8129 is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_WINBOND_840 is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+CONFIG_TR=y
+# CONFIG_IBMTR is not set
+CONFIG_IBMOL=y
+# CONFIG_IBMLS is not set
+# CONFIG_TMS380TR is not set
+# CONFIG_SMCTR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Console drivers
+#
+# CONFIG_VGA_CONSOLE is not set
+
+#
+# Frame-buffer support
+#
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_CLGEN is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+CONFIG_FB_OF=y
+# CONFIG_FB_CONTROL is not set
+# CONFIG_FB_PLATINUM is not set
+# CONFIG_FB_VALKYRIE is not set
+# CONFIG_FB_CT65550 is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_S3TRIO is not set
+# CONFIG_FB_VGA16 is not set
+CONFIG_FB_MATROX=y
+CONFIG_FB_MATROX_MILLENIUM=y
+CONFIG_FB_MATROX_MYSTIQUE=y
+CONFIG_FB_MATROX_G100=y
+CONFIG_FB_MATROX_I2C=y
+# CONFIG_FB_MATROX_MAVEN is not set
+# CONFIG_FB_MATROX_G450 is not set
+CONFIG_FB_MATROX_MULTIHEAD=y
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FBCON_ADVANCED is not set
+CONFIG_FBCON_CFB8=y
+CONFIG_FBCON_CFB16=y
+CONFIG_FBCON_CFB24=y
+CONFIG_FBCON_CFB32=y
+# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
+CONFIG_FBCON_FONTS=y
+# CONFIG_FONT_8x8 is not set
+CONFIG_FONT_8x16=y
+CONFIG_FONT_SUN8x16=y
+CONFIG_FONT_SUN12x22=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FB_COMPAT_XPMAC is not set
+
+#
+# Input core support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_KEYBDEV=y
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+
+#
+# Macintosh device drivers
+#
+# CONFIG_ADB_CUDA is not set
+# CONFIG_ADB_PMU is not set
+# CONFIG_MAC_FLOPPY is not set
+# CONFIG_MAC_SERIAL is not set
+# CONFIG_ADB is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=2048
+CONFIG_PRINTER=m
+# CONFIG_LP_CONSOLE is not set
+# CONFIG_PPDEV is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+CONFIG_I2C_ALGOBIT=y
+# CONFIG_I2C_PHILIPSPAR is not set
+# CONFIG_I2C_ELV is not set
+# CONFIG_I2C_VELLEMAN is not set
+CONFIG_I2C_ALGOPCF=y
+# CONFIG_I2C_ELEKTOR is not set
+CONFIG_I2C_CHARDEV=y
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+CONFIG_MOUSE=y
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
+
+#
+# Joysticks
+#
+# CONFIG_JOYSTICK is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
+CONFIG_NVRAM=y
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+# CONFIG_UMSDOS_FS is not set
+CONFIG_VFAT_FS=y
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_RAMFS is not set
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+# CONFIG_MINIX_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_SYSV_FS_WRITE is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_ROOT_NFS is not set
+CONFIG_NFSD=y
+# CONFIG_NFSD_V3 is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+# CONFIG_DMASOUND_AWACS is not set
+# CONFIG_SOUND_CMPCI is not set
+# CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_SOUND_FUSION is not set
+# CONFIG_SOUND_CS4281 is not set
+# CONFIG_SOUND_ES1370 is not set
+# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_ESSSOLO1 is not set
+# CONFIG_SOUND_MAESTRO is not set
+# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
+CONFIG_SOUND_OSS=y
+CONFIG_SOUND_TRACEINIT=y
+# CONFIG_SOUND_DMAP is not set
+# CONFIG_SOUND_AD1816 is not set
+# CONFIG_SOUND_SGALAXY is not set
+# CONFIG_SOUND_ADLIB is not set
+# CONFIG_SOUND_ACI_MIXER is not set
+CONFIG_SOUND_CS4232=m
+# CONFIG_SOUND_SSCAPE is not set
+# CONFIG_SOUND_GUS is not set
+# CONFIG_SOUND_ICH is not set
+# CONFIG_SOUND_VMIDI is not set
+# CONFIG_SOUND_TRIX is not set
+CONFIG_SOUND_MSS=m
+# CONFIG_SOUND_MPU401 is not set
+# CONFIG_SOUND_NM256 is not set
+# CONFIG_SOUND_MAD16 is not set
+# CONFIG_SOUND_PAS is not set
+# CONFIG_PAS_JOYSTICK is not set
+# CONFIG_SOUND_PSS is not set
+# CONFIG_SOUND_SB is not set
+# CONFIG_SOUND_AWE32_SYNTH is not set
+# CONFIG_SOUND_WAVEFRONT is not set
+# CONFIG_SOUND_MAUI is not set
+# CONFIG_SOUND_YM3812 is not set
+# CONFIG_SOUND_OPL3SA1 is not set
+# CONFIG_SOUND_OPL3SA2 is not set
+# CONFIG_SOUND_YMPCI is not set
+# CONFIG_SOUND_YMFPCI is not set
+# CONFIG_SOUND_UART6850 is not set
+# CONFIG_SOUND_AEDSP16 is not set
+CONFIG_SOUND_TVMIXER=y
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Kernel hacking
+#
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_KGDB is not set
+CONFIG_XMON=y
diff --git a/arch/ppc/configs/rpxcllf_defconfig b/arch/ppc/configs/rpxcllf_defconfig
index 78ee82230..258d3e79f 100644
--- a/arch/ppc/configs/rpxcllf_defconfig
+++ b/arch/ppc/configs/rpxcllf_defconfig
@@ -21,7 +21,6 @@ CONFIG_PPC=y
# CONFIG_4xx is not set
# CONFIG_POWER3 is not set
# CONFIG_POWER4 is not set
-# CONFIG_8260 is not set
CONFIG_8xx=y
CONFIG_SERIAL_CONSOLE=y
# CONFIG_RPXLITE is not set
@@ -32,6 +31,7 @@ CONFIG_RPXCLASSIC=y
# CONFIG_TQM860 is not set
# CONFIG_MBX is not set
# CONFIG_WINCEPT is not set
+CONFIG_PPC601_SYNC_FIX=y
# CONFIG_ALL_PPC is not set
# CONFIG_SMP is not set
CONFIG_MACH_SPECIFIC=y
@@ -43,7 +43,9 @@ CONFIG_MATH_EMULATION=y
# CONFIG_HIGHMEM is not set
# CONFIG_MOL is not set
# CONFIG_ISA is not set
+# CONFIG_EISA is not set
# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
# CONFIG_PCI_QSPAN is not set
# CONFIG_PCI is not set
CONFIG_NET=y
@@ -182,7 +184,6 @@ CONFIG_NET_ETHERNET=y
# CONFIG_MACE is not set
# CONFIG_BMAC is not set
# CONFIG_GMAC is not set
-# CONFIG_NCR885E is not set
# CONFIG_OAKNET is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_LANCE is not set
@@ -190,7 +191,6 @@ CONFIG_NET_ETHERNET=y
# CONFIG_NET_VENDOR_RACAL is not set
# CONFIG_AT1700 is not set
# CONFIG_DEPCA is not set
-# CONFIG_HP100 is not set
# CONFIG_NET_ISA is not set
# CONFIG_NET_PCI is not set
# CONFIG_NET_POCKET is not set
@@ -377,8 +377,6 @@ CONFIG_LOCKD=y
# CONFIG_NCPFS_NFS_NS is not set
# CONFIG_NCPFS_OS2_NS is not set
# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_MOUNT_SUBDIR is not set
-# CONFIG_NCPFS_NDS_DOMAINS is not set
# CONFIG_NCPFS_NLS is not set
# CONFIG_NCPFS_EXTRAS is not set
@@ -395,6 +393,7 @@ CONFIG_PARTITION_ADVANCED=y
# CONFIG_SGI_PARTITION is not set
# CONFIG_ULTRIX_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
+# CONFIG_SMB_NLS is not set
# CONFIG_NLS is not set
#
diff --git a/arch/ppc/configs/rpxlite_defconfig b/arch/ppc/configs/rpxlite_defconfig
index 741d9265f..df00f5ace 100644
--- a/arch/ppc/configs/rpxlite_defconfig
+++ b/arch/ppc/configs/rpxlite_defconfig
@@ -21,7 +21,6 @@ CONFIG_PPC=y
# CONFIG_4xx is not set
# CONFIG_POWER3 is not set
# CONFIG_POWER4 is not set
-# CONFIG_8260 is not set
CONFIG_8xx=y
CONFIG_SERIAL_CONSOLE=y
CONFIG_RPXLITE=y
@@ -32,6 +31,7 @@ CONFIG_RPXLITE=y
# CONFIG_TQM860 is not set
# CONFIG_MBX is not set
# CONFIG_WINCEPT is not set
+CONFIG_PPC601_SYNC_FIX=y
# CONFIG_ALL_PPC is not set
# CONFIG_SMP is not set
CONFIG_MACH_SPECIFIC=y
@@ -43,7 +43,9 @@ CONFIG_MATH_EMULATION=y
# CONFIG_HIGHMEM is not set
# CONFIG_MOL is not set
# CONFIG_ISA is not set
+# CONFIG_EISA is not set
# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
# CONFIG_PCI_QSPAN is not set
# CONFIG_PCI is not set
CONFIG_NET=y
@@ -182,7 +184,6 @@ CONFIG_NET_ETHERNET=y
# CONFIG_MACE is not set
# CONFIG_BMAC is not set
# CONFIG_GMAC is not set
-# CONFIG_NCR885E is not set
# CONFIG_OAKNET is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_LANCE is not set
@@ -190,7 +191,6 @@ CONFIG_NET_ETHERNET=y
# CONFIG_NET_VENDOR_RACAL is not set
# CONFIG_AT1700 is not set
# CONFIG_DEPCA is not set
-# CONFIG_HP100 is not set
# CONFIG_NET_ISA is not set
# CONFIG_NET_PCI is not set
# CONFIG_NET_POCKET is not set
@@ -377,8 +377,6 @@ CONFIG_LOCKD=y
# CONFIG_NCPFS_NFS_NS is not set
# CONFIG_NCPFS_OS2_NS is not set
# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_MOUNT_SUBDIR is not set
-# CONFIG_NCPFS_NDS_DOMAINS is not set
# CONFIG_NCPFS_NLS is not set
# CONFIG_NCPFS_EXTRAS is not set
@@ -395,6 +393,7 @@ CONFIG_PARTITION_ADVANCED=y
# CONFIG_SGI_PARTITION is not set
# CONFIG_ULTRIX_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
+# CONFIG_SMB_NLS is not set
# CONFIG_NLS is not set
#
diff --git a/arch/ppc/configs/walnut_defconfig b/arch/ppc/configs/walnut_defconfig
index c3e95c6ac..eef439fc2 100644
--- a/arch/ppc/configs/walnut_defconfig
+++ b/arch/ppc/configs/walnut_defconfig
@@ -12,7 +12,7 @@ CONFIG_EXPERIMENTAL=y
# Loadable module support
#
CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
+CONFIG_MODVERSIONS=y
CONFIG_KMOD=y
#
@@ -23,10 +23,10 @@ CONFIG_PPC=y
CONFIG_4xx=y
# CONFIG_POWER3 is not set
# CONFIG_POWER4 is not set
-# CONFIG_8260 is not set
# CONFIG_8xx is not set
# CONFIG_OAK is not set
CONFIG_WALNUT=y
+CONFIG_PPC601_SYNC_FIX=y
# CONFIG_SMP is not set
CONFIG_MACH_SPECIFIC=y
# CONFIG_MATH_EMULATION is not set
@@ -37,7 +37,9 @@ CONFIG_MACH_SPECIFIC=y
# CONFIG_HIGHMEM is not set
# CONFIG_MOL is not set
# CONFIG_ISA is not set
+# CONFIG_EISA is not set
# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
# CONFIG_PCI is not set
CONFIG_NET=y
CONFIG_SYSCTL=y
@@ -171,7 +173,6 @@ CONFIG_NET_ETHERNET=y
# CONFIG_MACE is not set
# CONFIG_BMAC is not set
# CONFIG_GMAC is not set
-# CONFIG_NCR885E is not set
# CONFIG_OAKNET is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_LANCE is not set
@@ -179,7 +180,6 @@ CONFIG_NET_ETHERNET=y
# CONFIG_NET_VENDOR_RACAL is not set
# CONFIG_AT1700 is not set
# CONFIG_DEPCA is not set
-# CONFIG_HP100 is not set
# CONFIG_NET_ISA is not set
# CONFIG_NET_PCI is not set
# CONFIG_NET_POCKET is not set
@@ -369,8 +369,6 @@ CONFIG_LOCKD=y
# CONFIG_NCPFS_NFS_NS is not set
# CONFIG_NCPFS_OS2_NS is not set
# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_MOUNT_SUBDIR is not set
-# CONFIG_NCPFS_NDS_DOMAINS is not set
# CONFIG_NCPFS_NLS is not set
# CONFIG_NCPFS_EXTRAS is not set
@@ -379,6 +377,7 @@ CONFIG_LOCKD=y
#
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
# CONFIG_NLS is not set
#
diff --git a/arch/ppc/defconfig b/arch/ppc/defconfig
index 5574ecbdb..210887de7 100644
--- a/arch/ppc/defconfig
+++ b/arch/ppc/defconfig
@@ -23,12 +23,11 @@ CONFIG_6xx=y
# CONFIG_4xx is not set
# CONFIG_POWER3 is not set
# CONFIG_POWER4 is not set
-# CONFIG_8260 is not set
# CONFIG_8xx is not set
+# CONFIG_8260 is not set
CONFIG_ALL_PPC=y
-# CONFIG_GEMINI is not set
-# CONFIG_EST8260 is not set
# CONFIG_APUS is not set
+CONFIG_PPC601_SYNC_FIX=y
# CONFIG_SMP is not set
CONFIG_ALTIVEC=y
@@ -36,9 +35,11 @@ CONFIG_ALTIVEC=y
# General setup
#
# CONFIG_HIGHMEM is not set
-# CONFIG_MOL is not set
+CONFIG_MOL=y
# CONFIG_ISA is not set
+# CONFIG_EISA is not set
# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
CONFIG_PCI=y
CONFIG_NET=y
CONFIG_SYSCTL=y
@@ -49,21 +50,24 @@ CONFIG_BINFMT_ELF=y
CONFIG_KERNEL_ELF=y
CONFIG_BINFMT_MISC=m
CONFIG_PCI_NAMES=y
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
+
+#
+# PCMCIA/CardBus support
+#
# CONFIG_PCMCIA is not set
#
# Parallel port support
#
# CONFIG_PARPORT is not set
-CONFIG_VGA_CONSOLE=y
-CONFIG_FB=y
-CONFIG_FB_COMPAT_XPMAC=y
CONFIG_PPC_RTC=y
CONFIG_PROC_DEVICETREE=y
+CONFIG_PPC_RTAS=y
CONFIG_BOOTX_TEXT=y
-# CONFIG_MOTOROLA_HOTSWAP is not set
-# CONFIG_CMDLINE_BOOL is not set
+CONFIG_PREP_RESIDUAL=y
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttyS0,9600 console=tty0 root=/dev/sda2"
#
# Memory Technology Devices (MTD)
@@ -79,7 +83,7 @@ CONFIG_BOOTX_TEXT=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
+CONFIG_BLK_DEV_FD=m
# CONFIG_BLK_DEV_XD is not set
# CONFIG_PARIDE is not set
# CONFIG_BLK_CPQ_DA is not set
@@ -111,7 +115,8 @@ CONFIG_PACKET=y
CONFIG_NETLINK=y
# CONFIG_RTNETLINK is not set
# CONFIG_NETLINK_DEV is not set
-# CONFIG_NETFILTER is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
# CONFIG_FILTER is not set
CONFIG_UNIX=y
CONFIG_INET=y
@@ -123,6 +128,34 @@ CONFIG_IP_MULTICAST=y
# CONFIG_IP_MROUTE is not set
# CONFIG_INET_ECN is not set
CONFIG_SYN_COOKIES=y
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+CONFIG_IP_NF_FTP=m
+# CONFIG_IP_NF_QUEUE is not set
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_LIMIT=m
+CONFIG_IP_NF_MATCH_MAC=m
+CONFIG_IP_NF_MATCH_MARK=m
+CONFIG_IP_NF_MATCH_MULTIPORT=m
+CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_STATE=m
+CONFIG_IP_NF_MATCH_UNCLEAN=m
+CONFIG_IP_NF_MATCH_OWNER=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_MIRROR=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+# CONFIG_IP_NF_MANGLE is not set
+# CONFIG_IP_NF_TARGET_LOG is not set
+CONFIG_IP_NF_COMPAT_IPCHAINS=m
+CONFIG_IP_NF_NAT_NEEDED=y
+# CONFIG_IP_NF_COMPAT_IPFWADM is not set
# CONFIG_IPV6 is not set
# CONFIG_KHTTPD is not set
# CONFIG_ATM is not set
@@ -239,6 +272,7 @@ CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
CONFIG_SD_EXTRA_DEVS=40
CONFIG_CHR_DEV_ST=y
+# CONFIG_CHR_DEV_OSST is not set
CONFIG_BLK_DEV_SR=y
CONFIG_BLK_DEV_SR_VENDOR=y
CONFIG_SR_EXTRA_DEVS=2
@@ -344,7 +378,6 @@ CONFIG_NET_ETHERNET=y
CONFIG_MACE=y
CONFIG_BMAC=y
CONFIG_GMAC=y
-# CONFIG_NCR885E is not set
# CONFIG_OAKNET is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_LANCE is not set
@@ -357,27 +390,28 @@ CONFIG_GMAC=y
CONFIG_NET_PCI=y
CONFIG_PCNET32=y
# CONFIG_ADAPTEC_STARFIRE is not set
-# CONFIG_AC3200 is not set
# CONFIG_APRICOT is not set
# CONFIG_CS89x0 is not set
-CONFIG_DE4X5=y
-# CONFIG_TULIP is not set
+CONFIG_TULIP=y
+CONFIG_DE4X5=m
# CONFIG_DGRS is not set
# CONFIG_DM9102 is not set
# CONFIG_EEPRO100 is not set
+# CONFIG_EEPRO100_PM is not set
# CONFIG_LNE390 is not set
# CONFIG_NATSEMI is not set
# CONFIG_NE2K_PCI is not set
# CONFIG_NE3210 is not set
# CONFIG_ES3210 is not set
-# CONFIG_RTL8129 is not set
# CONFIG_8139TOO is not set
+# CONFIG_RTL8129 is not set
# CONFIG_SIS900 is not set
# CONFIG_EPIC100 is not set
# CONFIG_SUNDANCE is not set
# CONFIG_TLAN is not set
# CONFIG_VIA_RHINE is not set
# CONFIG_WINBOND_840 is not set
+# CONFIG_HAPPYMEAL is not set
# CONFIG_NET_POCKET is not set
#
@@ -439,6 +473,7 @@ CONFIG_PPP_DEFLATE=y
#
# Console drivers
#
+CONFIG_VGA_CONSOLE=y
#
# Frame-buffer support
@@ -460,7 +495,8 @@ CONFIG_FB_IMSTT=y
CONFIG_FB_MATROX=y
CONFIG_FB_MATROX_MILLENIUM=y
CONFIG_FB_MATROX_MYSTIQUE=y
-CONFIG_FB_MATROX_G100=y
+# CONFIG_FB_MATROX_G100 is not set
+# CONFIG_FB_MATROX_G450 is not set
# CONFIG_FB_MATROX_MULTIHEAD is not set
CONFIG_FB_ATY=y
CONFIG_FB_ATY128=y
@@ -481,6 +517,7 @@ CONFIG_FONT_SUN12x22=y
# CONFIG_FONT_6x11 is not set
# CONFIG_FONT_PEARL_8x8 is not set
# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FB_COMPAT_XPMAC is not set
#
# Input core support
@@ -498,15 +535,13 @@ CONFIG_INPUT_EVDEV=y
#
CONFIG_ADB_CUDA=y
CONFIG_ADB_PMU=y
-CONFIG_PMAC_PBOOK=y
-CONFIG_PMAC_BACKLIGHT=y
-CONFIG_MAC_FLOPPY=y
-CONFIG_MAC_SERIAL=y
-# CONFIG_SERIAL_CONSOLE is not set
+# CONFIG_PMAC_PBOOK is not set
+# CONFIG_PMAC_BACKLIGHT is not set
+# CONFIG_MAC_FLOPPY is not set
+CONFIG_MAC_SERIAL=m
CONFIG_ADB=y
CONFIG_ADB_MACIO=y
CONFIG_INPUT_ADBHID=y
-CONFIG_MAC_HID=y
CONFIG_MAC_ADBKEYCODES=y
CONFIG_MAC_EMUMOUSEBTN=y
@@ -575,17 +610,17 @@ CONFIG_NVRAM=y
# File systems
#
# CONFIG_QUOTA is not set
-CONFIG_AUTOFS_FS=y
-CONFIG_AUTOFS4_FS=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
# CONFIG_ADFS_FS is not set
# CONFIG_ADFS_FS_RW is not set
# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
+CONFIG_HFS_FS=m
# CONFIG_BFS_FS is not set
-CONFIG_FAT_FS=y
-CONFIG_MSDOS_FS=y
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
# CONFIG_UMSDOS_FS is not set
-CONFIG_VFAT_FS=y
+CONFIG_VFAT_FS=m
# CONFIG_EFS_FS is not set
# CONFIG_JFFS_FS is not set
# CONFIG_CRAMFS is not set
@@ -631,8 +666,6 @@ CONFIG_LOCKD=y
# CONFIG_NCPFS_NFS_NS is not set
# CONFIG_NCPFS_OS2_NS is not set
# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_MOUNT_SUBDIR is not set
-# CONFIG_NCPFS_NDS_DOMAINS is not set
# CONFIG_NCPFS_NLS is not set
# CONFIG_NCPFS_EXTRAS is not set
@@ -652,6 +685,7 @@ CONFIG_MSDOS_PARTITION=y
# CONFIG_SGI_PARTITION is not set
# CONFIG_ULTRIX_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
+# CONFIG_SMB_NLS is not set
CONFIG_NLS=y
#
@@ -678,7 +712,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
# CONFIG_NLS_CODEPAGE_936 is not set
# CONFIG_NLS_CODEPAGE_949 is not set
# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_ISO8859_1 is not set
+CONFIG_NLS_ISO8859_1=m
# CONFIG_NLS_ISO8859_2 is not set
# CONFIG_NLS_ISO8859_3 is not set
# CONFIG_NLS_ISO8859_4 is not set
@@ -695,9 +729,9 @@ CONFIG_NLS_DEFAULT="iso8859-1"
#
# Sound
#
-CONFIG_SOUND=y
-CONFIG_DMASOUND_AWACS=y
-CONFIG_DMASOUND=y
+CONFIG_SOUND=m
+CONFIG_DMASOUND_AWACS=m
+CONFIG_DMASOUND=m
# CONFIG_SOUND_CMPCI is not set
# CONFIG_SOUND_EMU10K1 is not set
# CONFIG_SOUND_FUSION is not set
@@ -711,43 +745,14 @@ CONFIG_DMASOUND=y
# CONFIG_SOUND_MSNDCLAS is not set
# CONFIG_SOUND_MSNDPIN is not set
# CONFIG_SOUND_VIA82CXXX is not set
-CONFIG_SOUND_OSS=y
-# CONFIG_SOUND_TRACEINIT is not set
-# CONFIG_SOUND_DMAP is not set
-# CONFIG_SOUND_AD1816 is not set
-# CONFIG_SOUND_SGALAXY is not set
-# CONFIG_SOUND_ADLIB is not set
-# CONFIG_SOUND_ACI_MIXER is not set
-CONFIG_SOUND_CS4232=m
-# CONFIG_SOUND_SSCAPE is not set
-# CONFIG_SOUND_GUS is not set
-# CONFIG_SOUND_ICH is not set
-# CONFIG_SOUND_VMIDI is not set
-# CONFIG_SOUND_TRIX is not set
-# CONFIG_SOUND_MSS is not set
-# CONFIG_SOUND_MPU401 is not set
-# CONFIG_SOUND_NM256 is not set
-# CONFIG_SOUND_MAD16 is not set
-# CONFIG_SOUND_PAS is not set
-# CONFIG_PAS_JOYSTICK is not set
-# CONFIG_SOUND_PSS is not set
-# CONFIG_SOUND_SB is not set
-# CONFIG_SOUND_AWE32_SYNTH is not set
-# CONFIG_SOUND_WAVEFRONT is not set
-# CONFIG_SOUND_MAUI is not set
-# CONFIG_SOUND_YM3812 is not set
-# CONFIG_SOUND_OPL3SA1 is not set
-# CONFIG_SOUND_OPL3SA2 is not set
-# CONFIG_SOUND_YMPCI is not set
-# CONFIG_SOUND_UART6850 is not set
-# CONFIG_SOUND_AEDSP16 is not set
+# CONFIG_SOUND_OSS is not set
# CONFIG_SOUND_TVMIXER is not set
#
# USB support
#
CONFIG_USB=y
-CONFIG_USB_DEBUG=y
+# CONFIG_USB_DEBUG is not set
#
# Miscellaneous USB options
@@ -763,33 +768,69 @@ CONFIG_USB_DEVICEFS=y
CONFIG_USB_OHCI=y
#
-# USB Devices
+# USB Device Class drivers
#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_BLUETOOTH is not set
+# CONFIG_USB_STORAGE is not set
+CONFIG_USB_ACM=m
# CONFIG_USB_PRINTER is not set
+
+#
+# USB Human Interface Devices (HID)
+#
+CONFIG_USB_HID=y
+# CONFIG_USB_WACOM is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
# CONFIG_USB_SCANNER is not set
# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_AUDIO is not set
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_SERIAL is not set
+
+#
+# USB Multimedia devices
+#
# CONFIG_USB_IBMCAM is not set
# CONFIG_USB_OV511 is not set
-# CONFIG_USB_DC2XX is not set
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_STORAGE is not set
-# CONFIG_USB_USS720 is not set
+# CONFIG_USB_DSBR is not set
# CONFIG_USB_DABUSB is not set
+
+#
+# USB Network adaptors
+#
# CONFIG_USB_PLUSB is not set
# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_DSBR is not set
-# CONFIG_USB_BLUETOOTH is not set
# CONFIG_USB_NET1080 is not set
#
-# USB Human Interface Devices (HID)
+# USB port drivers
#
-CONFIG_USB_HID=y
-# CONFIG_USB_WACOM is not set
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=m
+# CONFIG_USB_SERIAL_DEBUG is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+CONFIG_USB_SERIAL_VISOR=m
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+
+#
+# USB misc drivers
+#
+# CONFIG_USB_RIO500 is not set
#
# Kernel hacking
diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile
index 4a9852612..545fce0cd 100644
--- a/arch/ppc/kernel/Makefile
+++ b/arch/ppc/kernel/Makefile
@@ -35,6 +35,7 @@ obj-$(CONFIG_PPC) := entry.o traps.o irq.o idle.o time.o misc.o \
process.o signal.o bitops.o ptrace.o \
ppc_htab.o semaphore.o syscalls.o \
align.o setup.o
+obj-$(CONFIG_MODULES) += ppc_ksyms.o
obj-$(CONFIG_POWER4) += xics.o
obj-$(CONFIG_PCI) += pci.o pci-dma.o
obj-$(CONFIG_KGDB) += ppc-stub.o
@@ -62,11 +63,8 @@ obj-$(CONFIG_ALL_PPC) += pmac_pic.o pmac_setup.o pmac_time.o prom.o \
feature.o pmac_pci.o chrp_setup.o \
chrp_time.o chrp_pci.o open_pic.o \
indirect_pci.o i8259.o prep_pci.o \
- prep_time.o prep_nvram.o ppc_ksyms.o \
- prep_setup.o
+ prep_time.o prep_nvram.o prep_setup.o
obj-$(CONFIG_PMAC_BACKLIGHT) += pmac_backlight.o
-obj-$(CONFIG_GEMINI) += gemini_prom.o gemini_pci.o gemini_setup.o \
- open_pic.o
obj-$(CONFIG_8260) += m8260_setup.o ppc8260_pic.o
diff --git a/arch/ppc/kernel/apus_setup.c b/arch/ppc/kernel/apus_setup.c
index 5979c9312..70a683d20 100644
--- a/arch/ppc/kernel/apus_setup.c
+++ b/arch/ppc/kernel/apus_setup.c
@@ -647,25 +647,6 @@ apus_ide_default_io_base(int index)
return 0;
}
-int
-apus_ide_check_region(ide_ioreg_t from, unsigned int extent)
-{
- return 0;
-}
-
-void
-apus_ide_request_region(ide_ioreg_t from,
- unsigned int extent,
- const char *name)
-{
-}
-
-void
-apus_ide_release_region(ide_ioreg_t from,
- unsigned int extent)
-{
-}
-
void
apus_ide_fix_driveid(struct hd_driveid *id)
{
@@ -1131,9 +1112,6 @@ void apus_init(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_ide_md.outsw = apus_ide_outsw;
ppc_ide_md.default_irq = apus_ide_default_irq;
ppc_ide_md.default_io_base = apus_ide_default_io_base;
- ppc_ide_md.ide_check_region = apus_ide_check_region;
- ppc_ide_md.ide_request_region = apus_ide_request_region;
- ppc_ide_md.ide_release_region = apus_ide_release_region;
ppc_ide_md.fix_driveid = apus_ide_fix_driveid;
ppc_ide_md.ide_init_hwif = apus_ide_init_hwif_ports;
diff --git a/arch/ppc/kernel/chrp_pci.c b/arch/ppc/kernel/chrp_pci.c
index 43b678861..914ed02ff 100644
--- a/arch/ppc/kernel/chrp_pci.c
+++ b/arch/ppc/kernel/chrp_pci.c
@@ -8,8 +8,8 @@
#include <linux/delay.h>
#include <linux/string.h>
#include <linux/init.h>
-#include <linux/openpic.h>
#include <linux/ide.h>
+#include <linux/bootmem.h>
#include <asm/io.h>
#include <asm/pgtable.h>
@@ -19,16 +19,19 @@
#include <asm/gg2.h>
#include <asm/machdep.h>
#include <asm/init.h>
+#include <asm/pci-bridge.h>
+#include "open_pic.h"
#include "pci.h"
+
#ifdef CONFIG_POWER4
-static unsigned long pci_address_offset(int, unsigned int);
+extern unsigned long pci_address_offset(int, unsigned int);
#endif /* CONFIG_POWER4 */
/* LongTrail */
-#define pci_config_addr(bus, dev, offset) \
-(GG2_PCI_CONFIG_BASE | ((bus)<<16) | ((dev)<<8) | (offset))
+#define pci_config_addr(dev, offset) \
+(GG2_PCI_CONFIG_BASE | ((dev->bus->number)<<16) | ((dev->devfn)<<8) | (offset))
volatile struct Hydra *Hydra = NULL;
@@ -37,205 +40,127 @@ volatile struct Hydra *Hydra = NULL;
* limit the bus number to 3 bits
*/
-int __chrp gg2_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned char *val)
-{
- if (bus > 7) {
- *val = 0xff;
- return PCIBIOS_DEVICE_NOT_FOUND;
- }
- *val = in_8((unsigned char *)pci_config_addr(bus, dev_fn, offset));
- return PCIBIOS_SUCCESSFUL;
+#define cfg_read(val, addr, type, op) *val = op((type)(addr))
+#define cfg_write(val, addr, type, op) op((type *)(addr), (val))
+
+#define cfg_read_bad(val, size) *val = bad_##size;
+#define cfg_write_bad(val, size)
+
+#define bad_byte 0xff
+#define bad_word 0xffff
+#define bad_dword 0xffffffffU
+
+#define GG2_PCI_OP(rw, size, type, op) \
+int __chrp gg2_##rw##_config_##size(struct pci_dev *dev, int off, type val) \
+{ \
+ if (dev->bus->number > 7) { \
+ cfg_##rw##_bad(val, size) \
+ return PCIBIOS_DEVICE_NOT_FOUND; \
+ } \
+ cfg_##rw(val, pci_config_addr(dev, off), type, op); \
+ return PCIBIOS_SUCCESSFUL; \
}
-int __chrp gg2_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned short *val)
-{
- if (bus > 7) {
- *val = 0xffff;
- return PCIBIOS_DEVICE_NOT_FOUND;
- }
- *val = in_le16((unsigned short *)pci_config_addr(bus, dev_fn, offset));
- return PCIBIOS_SUCCESSFUL;
-}
-
-
-int __chrp gg2_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned int *val)
-{
- if (bus > 7) {
- *val = 0xffffffff;
- return PCIBIOS_DEVICE_NOT_FOUND;
- }
- *val = in_le32((unsigned int *)pci_config_addr(bus, dev_fn, offset));
- return PCIBIOS_SUCCESSFUL;
-}
-
-int __chrp gg2_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned char val)
-{
- if (bus > 7)
- return PCIBIOS_DEVICE_NOT_FOUND;
- out_8((unsigned char *)pci_config_addr(bus, dev_fn, offset), val);
- return PCIBIOS_SUCCESSFUL;
-}
-
-int __chrp gg2_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned short val)
-{
- if (bus > 7)
- return PCIBIOS_DEVICE_NOT_FOUND;
- out_le16((unsigned short *)pci_config_addr(bus, dev_fn, offset), val);
- return PCIBIOS_SUCCESSFUL;
-}
+GG2_PCI_OP(read, byte, u8 *, in_8)
+GG2_PCI_OP(read, word, u16 *, in_le16)
+GG2_PCI_OP(read, dword, u32 *, in_le32)
+GG2_PCI_OP(write, byte, u8, out_8)
+GG2_PCI_OP(write, word, u16, out_le16)
+GG2_PCI_OP(write, dword, u32, out_le32)
-int __chrp gg2_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned int val)
+static struct pci_ops gg2_pci_ops =
{
- if (bus > 7)
- return PCIBIOS_DEVICE_NOT_FOUND;
- out_le32((unsigned int *)pci_config_addr(bus, dev_fn, offset), val);
- return PCIBIOS_SUCCESSFUL;
-}
+ gg2_read_config_byte,
+ gg2_read_config_word,
+ gg2_read_config_dword,
+ gg2_write_config_byte,
+ gg2_write_config_word,
+ gg2_write_config_dword
+};
-#define python_config_address(bus) (unsigned *)((0xfef00000+0xf8000)-(bus*0x100000))
-#define python_config_data(bus) ((0xfef00000+0xf8010)-(bus*0x100000))
-#define PYTHON_CFA(b, d, o) (0x80 | ((b<<6) << 8) | ((d) << 16) \
+/*
+ * Access functions for PCI config space on IBM "python" host bridges.
+ */
+#define PYTHON_CFA(b, d, o) (0x80 | ((b) << 8) | ((d) << 16) \
| (((o) & ~3) << 24))
-unsigned int python_busnr = 0;
-
-int __chrp python_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned char *val)
-{
- if (bus > python_busnr) {
- *val = 0xff;
- return PCIBIOS_DEVICE_NOT_FOUND;
- }
- out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset));
- *val = in_8((unsigned char *)python_config_data(bus) + (offset&3));
- return PCIBIOS_SUCCESSFUL;
-}
-int __chrp python_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned short *val)
-{
- if (bus > python_busnr) {
- *val = 0xffff;
- return PCIBIOS_DEVICE_NOT_FOUND;
- }
- out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset));
- *val = in_le16((unsigned short *)(python_config_data(bus) + (offset&3)));
- return PCIBIOS_SUCCESSFUL;
+#define PYTHON_PCI_OP(rw, size, type, op, mask) \
+int __chrp \
+python_##rw##_config_##size(struct pci_dev *dev, int offset, type val) \
+{ \
+ struct pci_controller *hose = dev->sysdata; \
+ \
+ out_be32(hose->cfg_addr, \
+ PYTHON_CFA(dev->bus->number, dev->devfn, offset)); \
+ cfg_##rw(val, hose->cfg_data + (offset & mask), type, op); \
+ return PCIBIOS_SUCCESSFUL; \
}
+PYTHON_PCI_OP(read, byte, u8 *, in_8, 3)
+PYTHON_PCI_OP(read, word, u16 *, in_le16, 2)
+PYTHON_PCI_OP(read, dword, u32 *, in_le32, 0)
+PYTHON_PCI_OP(write, byte, u8, out_8, 3)
+PYTHON_PCI_OP(write, word, u16, out_le16, 2)
+PYTHON_PCI_OP(write, dword, u32, out_le32, 0)
-int __chrp python_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned int *val)
-{
- if (bus > python_busnr) {
- *val = 0xffffffff;
- return PCIBIOS_DEVICE_NOT_FOUND;
- }
- out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset));
- *val = in_le32((unsigned *)python_config_data(bus));
- return PCIBIOS_SUCCESSFUL;
-}
-
-int __chrp python_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned char val)
+static struct pci_ops python_pci_ops =
{
- if (bus > python_busnr)
- return PCIBIOS_DEVICE_NOT_FOUND;
- out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset));
- out_8((volatile unsigned char *)python_config_data(bus) + (offset&3), val);
- return PCIBIOS_SUCCESSFUL;
-}
-
-int __chrp python_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned short val)
-{
- if (bus > python_busnr)
- return PCIBIOS_DEVICE_NOT_FOUND;
- out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset));
- out_le16((volatile unsigned short *)python_config_data(bus) + (offset&3),
- val);
- return PCIBIOS_SUCCESSFUL;
-}
-
-int __chrp python_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned int val)
-{
- if (bus > python_busnr)
- return PCIBIOS_DEVICE_NOT_FOUND;
- out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset));
- out_le32((unsigned *)python_config_data(bus) + (offset&3), val);
- return PCIBIOS_SUCCESSFUL;
-}
-
-
-int __chrp rtas_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned char *val)
-{
- unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16);
- unsigned long ret;
-
- if (call_rtas( "read-pci-config", 2, 2, &ret, addr, 1) != 0)
- return PCIBIOS_DEVICE_NOT_FOUND;
- *val = ret;
- return PCIBIOS_SUCCESSFUL;
-}
-
-int __chrp rtas_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned short *val)
-{
- unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16);
- unsigned long ret;
-
- if (call_rtas("read-pci-config", 2, 2, &ret, addr, 2) != 0)
- return PCIBIOS_DEVICE_NOT_FOUND;
- *val = ret;
- return PCIBIOS_SUCCESSFUL;
-}
-
-
-int __chrp rtas_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned int *val)
-{
- unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16);
- unsigned long ret;
+ python_read_config_byte,
+ python_read_config_word,
+ python_read_config_dword,
+ python_write_config_byte,
+ python_write_config_word,
+ python_write_config_dword
+};
- if (call_rtas("read-pci-config", 2, 2, &ret, addr, 4) != 0)
- return PCIBIOS_DEVICE_NOT_FOUND;
- *val = ret;
- return PCIBIOS_SUCCESSFUL;
+#ifdef CONFIG_POWER4
+/*
+ * Access functions for PCI config space using RTAS calls.
+ */
+#define RTAS_PCI_READ_OP(size, type, nbytes) \
+int __chrp \
+rtas_read_config_##size(struct pci_dev *dev, int offset, type val) \
+{ \
+ unsigned long addr = (offset & 0xff) | ((dev->devfn & 0xff) << 8) \
+ | ((dev->bus->number & 0xff) << 16); \
+ unsigned long ret = ~0UL; \
+ int rval; \
+ \
+ rval = call_rtas("read-pci-config", 2, 2, &ret, addr, nbytes); \
+ *val = ret; \
+ return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL; \
}
-int __chrp rtas_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned char val)
-{
- unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16);
- if ( call_rtas( "write-pci-config", 3, 1, NULL, addr, 1, (ulong)val ) != 0 )
- return PCIBIOS_DEVICE_NOT_FOUND;
- return PCIBIOS_SUCCESSFUL;
+#define RTAS_PCI_WRITE_OP(size, type, nbytes) \
+int __chrp \
+rtas_write_config_##size(struct pci_dev *dev, int offset, type val) \
+{ \
+ unsigned long addr = (offset & 0xff) | ((dev->devfn & 0xff) << 8) \
+ | ((dev->bus->number & 0xff) << 16); \
+ int rval; \
+ \
+ rval = call_rtas("write-pci-config", 3, 1, NULL, \
+ addr, nbytes, (ulong)val); \
+ return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL; \
}
-int __chrp rtas_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned short val)
-{
- unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16);
- if ( call_rtas( "write-pci-config", 3, 1, NULL, addr, 2, (ulong)val ) != 0 )
- return PCIBIOS_DEVICE_NOT_FOUND;
- return PCIBIOS_SUCCESSFUL;
-}
+RTAS_PCI_READ_OP(byte, u8 *, 1)
+RTAS_PCI_READ_OP(word, u16 *, 2)
+RTAS_PCI_READ_OP(dword, u32 *, 4)
+RTAS_PCI_WRITE_OP(byte, u8, 1)
+RTAS_PCI_WRITE_OP(word, u16, 2)
+RTAS_PCI_WRITE_OP(dword, u32, 4)
-int __chrp rtas_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned int val)
+static struct pci_ops rtas_pci_ops =
{
- unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16);
- if ( call_rtas( "write-pci-config", 3, 1, NULL, addr, 4, (ulong)val ) != 0 )
- return PCIBIOS_DEVICE_NOT_FOUND;
- return PCIBIOS_SUCCESSFUL;
-}
+ rtas_read_config_byte,
+ rtas_read_config_word,
+ rtas_read_config_dword,
+ rtas_write_config_byte,
+ rtas_write_config_word,
+ rtas_write_config_dword
+};
+#endif /* CONFIG_POWER4 */
/*
* Temporary fixes for PCI devices. These should be replaced by OF query
@@ -278,7 +203,7 @@ hydra_init(void)
HYDRA_FC_MPIC_ENABLE |
HYDRA_FC_SLOW_SCC_PCLK |
HYDRA_FC_MPIC_IS_MASTER));
- OpenPIC = (volatile struct OpenPIC *)&Hydra->OpenPIC;
+ OpenPIC_Addr = &Hydra->OpenPIC;
OpenPIC_InitSenses = hydra_openpic_initsenses;
OpenPIC_NumInitSenses = sizeof(hydra_openpic_initsenses);
return 1;
@@ -316,54 +241,25 @@ void __init
chrp_pcibios_fixup(void)
{
struct pci_dev *dev;
- int *brp;
struct device_node *np;
- extern struct pci_ops generic_pci_ops;
-
-#ifndef CONFIG_POWER4
- np = find_devices("device-tree");
- if (np != 0) {
- for (np = np->child; np != NULL; np = np->sibling) {
- if (np->type == NULL || strcmp(np->type, "pci") != 0)
- continue;
- if ((brp = (int *) get_property(np, "bus-range", NULL)) == 0)
- continue;
- if (brp[0] != 0) /* bus 0 is already done */
- pci_scan_bus(brp[0], &generic_pci_ops, NULL);
- }
- }
-#else
- /* XXX kludge for now because we can't properly handle
- physical addresses > 4GB. -- paulus */
- pci_scan_bus(0x1e, &generic_pci_ops, NULL);
-#endif /* CONFIG_POWER4 */
/* PCI interrupts are controlled by the OpenPIC */
pci_for_each_dev(dev) {
- np = find_pci_device_OFnode(dev->bus->number, dev->devfn);
+ np = pci_device_to_OF_node(dev);
if ((np != 0) && (np->n_intrs > 0) && (np->intrs[0].line != 0))
dev->irq = np->intrs[0].line;
- /* these need to be absolute addrs for OF and Matrox FB -- Cort */
- if ( dev->vendor == PCI_VENDOR_ID_MATROX )
- {
- if ( dev->resource[0].start < isa_mem_base )
- dev->resource[0].start += isa_mem_base;
- if ( dev->resource[1].start < isa_mem_base )
- dev->resource[1].start += isa_mem_base;
- }
+ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+
/* the F50 identifies the amd as a trident */
if ( (dev->vendor == PCI_VENDOR_ID_TRIDENT) &&
(dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET) )
{
dev->vendor = PCI_VENDOR_ID_AMD;
- pcibios_write_config_word(dev->bus->number,
- dev->devfn, PCI_VENDOR_ID, PCI_VENDOR_ID_AMD);
+ pci_write_config_word(dev, PCI_VENDOR_ID,
+ PCI_VENDOR_ID_AMD);
}
#ifdef CONFIG_POWER4
power4_fixup_dev(dev);
-#else
- if (dev->bus->number > 0 && python_busnr > 0)
- dev->resource[0].start += dev->bus->number*0x01000000;
#endif
}
}
@@ -402,86 +298,213 @@ static void __init gg2_pcibios_fixup_bus(struct pci_bus *bus)
bus->resource[1] = &gg2_resources.pci_mem;
}
-decl_config_access_method(grackle);
-decl_config_access_method(indirect);
-decl_config_access_method(rtas);
+static void process_bridge_ranges(struct pci_controller *hose,
+ struct device_node *dev, int index)
+{
+ unsigned int *ranges;
+ int rlen = 0;
+ int memno = 0;
+ struct resource *res;
+
+ hose->io_base_phys = 0;
+ ranges = (unsigned int *) get_property(dev, "ranges", &rlen);
+ while ((rlen -= 6 * sizeof(unsigned int)) >= 0) {
+ res = NULL;
+ switch (ranges[0] >> 24) {
+ case 1: /* I/O space */
+ if (ranges[2] != 0)
+ break;
+ hose->io_base_phys = ranges[3];
+ hose->io_base_virt = ioremap(ranges[3], ranges[5]);
+ if (index == 0) {
+ isa_io_base = (unsigned long) hose->io_base_virt;
+ printk("isa_io_base=%lx\n", isa_io_base);
+ }
+ res = &hose->io_resource;
+ res->flags = IORESOURCE_IO;
+ break;
+ case 2: /* memory space */
+ if (index == 0 && ranges[1] == 0 && ranges[2] == 0){
+ isa_mem_base = ranges[3];
+ printk("isa_mem_base=%lx\n", isa_mem_base);
+ }
+ if (memno == 0) {
+ hose->pci_mem_offset = ranges[3] - ranges[2];
+ printk("pci_mem_offset=%lx for this bridge\n",
+ hose->pci_mem_offset);
+ }
+ res = &hose->mem_resources[memno];
+ res->flags = IORESOURCE_MEM;
+ ++memno;
+ break;
+ }
+ if (res != NULL) {
+ res->name = dev->full_name;
+ res->start = ranges[3];
+ res->end = res->start + ranges[5] - 1;
+ res->parent = NULL;
+ res->sibling = NULL;
+ res->child = NULL;
+ }
+ ranges += 6;
+ }
+}
+
+/* this is largely modeled and stolen after the pmac_pci code -- tgall
+ */
+
+static void __init
+ibm_add_bridges(struct device_node *dev)
+{
+ int *bus_range;
+ int len, index = 0;
+ struct pci_controller *hose;
+ volatile unsigned char *cfg;
+ unsigned int *dma;
+#ifdef CONFIG_POWER3
+ unsigned long *opprop = (unsigned long *)
+ get_property(find_path_device("/"), "platform-open-pic", NULL);
+#endif
+
+ for(; dev != NULL; dev = dev->next, ++index) {
+ if (dev->n_addrs < 1) {
+ printk(KERN_WARNING "Can't use %s: no address\n",
+ dev->full_name);
+ continue;
+ }
+ bus_range = (int *) 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);
+ continue;
+ }
+ if (bus_range[1] == bus_range[0])
+ printk(KERN_INFO "PCI bus %d", bus_range[0]);
+ else
+ printk(KERN_INFO "PCI buses %d..%d",
+ bus_range[0], bus_range[1]);
+ printk(" controlled by %s at %x\n", dev->type,
+ dev->addrs[0].address);
+
+ hose = pcibios_alloc_controller();
+ if (!hose) {
+ printk("Can't allocate PCI controller structure for %s\n",
+ dev->full_name);
+ continue;
+ }
+ hose->arch_data = dev;
+ hose->first_busno = bus_range[0];
+ hose->last_busno = bus_range[1];
+ hose->ops = &python_pci_ops;
+
+ cfg = ioremap(dev->addrs[0].address + 0xf8000, 0x20);
+ hose->cfg_addr = (volatile unsigned int *) cfg;
+ hose->cfg_data = cfg + 0x10;
+
+ process_bridge_ranges(hose, dev, index);
+
+#ifdef CONFIG_POWER3
+ openpic_setup_ISU(index, opprop[index+1]);
+#endif /* CONFIG_POWER3 */
+
+ /* 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);
+ 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);
+ }
+ }
+}
+
+#ifdef CONFIG_POWER4
+void __init
+power4_add_bridge(void)
+{
+ struct pci_controller* hose;
+
+ hose = pcibios_alloc_controller();
+ if (!hose)
+ return;
+ hose->first_busno = 0;
+ hose->last_busno = 0xff;
+
+ hose->ops = &rtas_pci_ops;
+ pci_dram_offset = 0;
+}
+#endif /* CONFIG_POWER4 */
void __init
-chrp_setup_pci_ptrs(void)
+chrp_find_bridges(void)
{
struct device_node *py;
+ char *model, *name;
+ struct pci_controller* hose;
ppc_md.pcibios_fixup = chrp_pcibios_fixup;
+
#ifdef CONFIG_POWER4
- set_config_access_method(rtas);
- pci_dram_offset = 0;
+ power4_add_bridge();
#else /* CONFIG_POWER4 */
- if ( !strncmp("MOT",
- get_property(find_path_device("/"), "model", NULL),3) )
- {
- pci_dram_offset = 0;
- isa_mem_base = 0xf7000000;
- isa_io_base = 0xfe000000;
- set_config_access_method(grackle);
- }
- else
- {
- if ((py = find_compatible_devices("pci", "IBM,python")) != 0
- || (py = find_compatible_devices("pci", "IBM,python3.0")) != 0)
- {
- char *name = get_property(find_path_device("/"), "name", NULL);
-
- /* find out how many pythons */
- while ( (py = py->next) ) python_busnr++;
- set_config_access_method(python);
-
- /*
- * We base these values on the machine type but should
- * try to read them from the python controller itself.
- * -- Cort
- */
- if ( !strncmp("IBM,7025-F50", name, 12) )
- {
- pci_dram_offset = 0x80000000;
- isa_mem_base = 0xa0000000;
- isa_io_base = 0x88000000;
- } else if ( !strncmp("IBM,7043-260", name, 12)
- || !strncmp("IBM,7044-270", name, 12))
- {
- pci_dram_offset = 0x0;
- isa_mem_base = 0xc0000000;
- isa_io_base = 0xf8000000;
- }
- }
- else
- {
- if ( !strncmp("IBM,7043-150", get_property(find_path_device("/"), "name", NULL),12) ||
- !strncmp("IBM,7046-155", get_property(find_path_device("/"), "name", NULL),12) ||
- !strncmp("IBM,7046-B50", get_property(find_path_device("/"), "name", NULL),12) )
- {
- pci_dram_offset = 0;
- isa_mem_base = 0x80000000;
- isa_io_base = 0xfe000000;
- pci_config_address = (unsigned int *)0xfec00000;
- pci_config_data = (unsigned char *)0xfee00000;
- set_config_access_method(indirect);
- }
- else
- {
- /* LongTrail */
- pci_dram_offset = 0;
- isa_mem_base = 0xf7000000;
- isa_io_base = 0xf8000000;
- set_config_access_method(gg2);
- ppc_md.pcibios_fixup = gg2_pcibios_fixup;
- ppc_md.pcibios_fixup_bus = gg2_pcibios_fixup_bus;
- }
- }
+ model = get_property(find_path_device("/"), "model", NULL);
+ if (!strncmp("MOT", model, 3)) {
+ struct pci_controller* hose;
+
+ hose = pcibios_alloc_controller();
+ if (!hose)
+ return;
+ hose->first_busno = 0;
+ hose->last_busno = 0xff;
+ /* Check that please. This must be the root of the OF
+ * PCI tree (the root host bridge
+ */
+ hose->arch_data = find_devices("pci");
+ setup_grackle(hose, 0x20000);
+ return;
}
+
+ if ((py = find_compatible_devices("pci", "IBM,python")))
+ {
+ /* XXX xmon_init_scc needs this set and the BAT
+ set up in MMU_init */
+ ibm_add_bridges(find_devices("pci"));
+ return;
+ }
+
+
+ hose = pcibios_alloc_controller();
+ if (!hose)
+ return;
+ hose->first_busno = 0;
+ hose->last_busno = 0xff;
+ /* Check that please. This must be the root of the OF
+ * PCI tree (the root host bridge
+ */
+ hose->arch_data = find_devices("pci");
+ name = get_property(find_path_device("/"), "name", NULL);
+ if (!strncmp("IBM,7043-150", name, 12) ||
+ !strncmp("IBM,7046-155", name, 12) ||
+ !strncmp("IBM,7046-B50", name, 12) ) {
+ setup_grackle(hose, 0x01000000);
+ isa_mem_base = 0x80000000;
+ return;
+ }
+
+ /* LongTrail */
+ hose->ops = &gg2_pci_ops;
+ pci_dram_offset = 0;
+ isa_mem_base = 0xf7000000;
+ hose->io_base_phys = (unsigned long) 0xf8000000;
+ hose->io_base_virt = ioremap(hose->io_base_phys, 0x10000);
+ isa_io_base = (unsigned long) hose->io_base_virt;
+ ppc_md.pcibios_fixup = gg2_pcibios_fixup;
+ ppc_md.pcibios_fixup_bus = gg2_pcibios_fixup_bus;
#endif /* CONFIG_POWER4 */
}
#ifdef CONFIG_PPC64BRIDGE
+#ifdef CONFIG_POWER4
/*
* Hack alert!!!
* 64-bit machines like POWER3 and POWER4 have > 32 bit
@@ -490,9 +513,7 @@ chrp_setup_pci_ptrs(void)
* page table gives us into parts of the physical address
* space above 4GB so we can access the I/O devices.
*/
-
-#ifdef CONFIG_POWER4
-static unsigned long pci_address_offset(int busnr, unsigned int flags)
+unsigned long pci_address_offset(int busnr, unsigned int flags)
{
unsigned long offset = 0;
@@ -508,34 +529,5 @@ static unsigned long pci_address_offset(int busnr, unsigned int flags)
}
return offset;
}
-
-unsigned long phys_to_bus(unsigned long pa)
-{
- if (pa >= 0xf8000000)
- pa -= 0x38000000;
- else if (pa >= 0x80000000 && pa < 0xc0000000)
- pa += 0x40000000;
- return pa;
-}
-
-unsigned long bus_to_phys(unsigned int ba, int busnr)
-{
- return ba + pci_address_offset(busnr, IORESOURCE_MEM);
-}
-
-#else /* CONFIG_POWER4 */
-/*
- * For now assume I/O addresses are < 4GB and PCI bridges don't
- * remap addresses on POWER3 machines.
- */
-unsigned long phys_to_bus(unsigned long pa)
-{
- return pa;
-}
-
-unsigned long bus_to_phys(unsigned int ba, int busnr)
-{
- return ba;
-}
#endif /* CONFIG_POWER4 */
#endif /* CONFIG_PPC64BRIDGE */
diff --git a/arch/ppc/kernel/chrp_setup.c b/arch/ppc/kernel/chrp_setup.c
index ccc6621de..5682f3fad 100644
--- a/arch/ppc/kernel/chrp_setup.c
+++ b/arch/ppc/kernel/chrp_setup.c
@@ -30,7 +30,6 @@
#include <linux/ioport.h>
#include <linux/console.h>
#include <linux/pci.h>
-#include <linux/openpic.h>
#include <linux/version.h>
#include <linux/adb.h>
#include <linux/module.h>
@@ -50,21 +49,19 @@
#include <asm/hydra.h>
#include <asm/keyboard.h>
#include <asm/init.h>
-
#include <asm/time.h>
+
#include "local_irq.h"
#include "i8259.h"
#include "open_pic.h"
#include "xics.h"
-extern volatile unsigned char *chrp_int_ack_special;
-
unsigned long chrp_get_rtc_time(void);
int chrp_set_rtc_time(unsigned long nowtime);
void chrp_calibrate_decr(void);
long chrp_time_init(void);
-void chrp_setup_pci_ptrs(void);
+void chrp_find_bridges(void);
void chrp_event_scan(void);
void rtas_display_progress(char *, unsigned short);
void rtas_indicator_progress(char *, unsigned short);
@@ -92,7 +89,7 @@ kdev_t boot_dev;
extern PTE *Hash, *Hash_end;
extern unsigned long Hash_size, Hash_mask;
extern int probingmem;
-extern unsigned long loops_per_sec;
+extern unsigned long loops_per_jiffy;
extern int bootx_text_mapped;
static int max_width;
@@ -244,7 +241,7 @@ chrp_setup_arch(void)
struct device_node *device;
/* init to some ~sane value until calibrate_delay() runs */
- loops_per_sec = 50000000;
+ loops_per_jiffy = 50000000/HZ;
#ifdef CONFIG_BLK_DEV_INITRD
/* this is fine for chrp */
@@ -257,6 +254,9 @@ chrp_setup_arch(void)
ROOT_DEV = to_kdev_t(0x0802); /* sda2 (sda1 is for the kernel) */
printk("Boot arguments: %s\n", cmd_line);
+ /* Lookup PCI host bridges */
+ chrp_find_bridges();
+
#ifndef CONFIG_PPC64BRIDGE
/* PCI bridge config space access area -
* appears to be not in devtree on longtrail. */
@@ -266,11 +266,12 @@ chrp_setup_arch(void)
* -- Geert
*/
hydra_init(); /* Mac I/O */
+
#endif /* CONFIG_PPC64BRIDGE */
#ifndef CONFIG_POWER4
/* Some IBM machines don't have the hydra -- Cort */
- if ( !OpenPIC )
+ if ( !OpenPIC_Addr )
{
unsigned long *opprop;
@@ -279,7 +280,7 @@ chrp_setup_arch(void)
if (opprop != 0) {
printk("OpenPIC addrs: %lx %lx %lx\n",
opprop[0], opprop[1], opprop[2]);
- OpenPIC = ioremap(opprop[0], sizeof(struct OpenPIC));
+ OpenPIC_Addr = ioremap(opprop[0], 0x40000);
}
}
#endif
@@ -292,23 +293,17 @@ chrp_setup_arch(void)
conswitchp = &dummy_con;
#endif
-#ifndef CONFIG_PPC64BRIDGE
- pmac_find_bridges();
-#endif /* CONFIG_PPC64BRIDGE */
-
/* Get the event scan rate for the rtas so we know how
* often it expects a heartbeat. -- Cort
*/
- if ( rtas_data )
- {
+ if ( rtas_data ) {
struct property *p;
device = find_devices("rtas");
for ( p = device->properties;
p && strncmp(p->name, "rtas-event-scan-rate", 20);
p = p->next )
/* nothing */ ;
- if ( p && *(unsigned long *)p->value )
- {
+ if ( p && *(unsigned long *)p->value ) {
ppc_md.heartbeat = chrp_event_scan;
ppc_md.heartbeat_reset = (HZ/(*(unsigned long *)p->value)*30)-1;
ppc_md.heartbeat_count = 1;
@@ -365,79 +360,44 @@ chrp_irq_cannonicalize(u_int irq)
}
}
-int __chrp chrp_get_irq( struct pt_regs *regs )
-{
- int irq;
-
- irq = openpic_irq( smp_processor_id() );
- if (irq == IRQ_8259_CASCADE)
- {
- /*
- * This magic address generates a PCI IACK cycle.
- */
- if ( chrp_int_ack_special )
- irq = *chrp_int_ack_special;
- else
- irq = i8259_irq( smp_processor_id() );
- openpic_eoi( smp_processor_id() );
- }
- if (irq == OPENPIC_VEC_SPURIOUS)
- /*
- * Spurious interrupts should never be
- * acknowledged
- */
- irq = -1;
- /*
- * I would like to openpic_eoi here but there seem to be timing problems
- * between the openpic ack and the openpic eoi.
- * -- Cort
- */
- return irq;
-}
-
-void __chrp chrp_post_irq(struct pt_regs* regs, int irq)
-{
- /*
- * If it's an i8259 irq then we've already done the
- * openpic irq. So we just check to make sure the controller
- * is an openpic and if it is then eoi
- *
- * We do it this way since our irq_desc[irq].handler can change
- * with RTL and no longer be open_pic -- Cort
- */
- if ( irq >= open_pic_irq_offset)
- openpic_eoi( smp_processor_id() );
-}
-
void __init chrp_init_IRQ(void)
{
struct device_node *np;
int i;
unsigned long *addrp;
+ unsigned char* chrp_int_ack_special = 0;
+ unsigned char init_senses[NR_IRQS - NUM_8259_INTERRUPTS];
+ int nmi_irq = -1;
+#if defined(CONFIG_VT) && defined(CONFIG_ADB_KEYBOARD) && defined(XMON)
+ struct device_node *kbd;
+#endif
if (!(np = find_devices("pci"))
|| !(addrp = (unsigned long *)
get_property(np, "8259-interrupt-acknowledge", NULL)))
printk("Cannot find pci to get ack address\n");
else
- chrp_int_ack_special = (volatile unsigned char *)
- ioremap(*addrp, 1);
- open_pic_irq_offset = 16;
- for ( i = 16 ; i < NR_IRQS ; i++ )
- irq_desc[i].handler = &open_pic;
- openpic_init(1);
- enable_irq(IRQ_8259_CASCADE);
- for ( i = 0 ; i < 16 ; i++ )
+ chrp_int_ack_special = (unsigned char *)ioremap(*addrp, 1);
+ /* hydra still sets OpenPIC_InitSenses to a static set of values */
+ if (OpenPIC_InitSenses == NULL) {
+ prom_get_irq_senses(init_senses, NUM_8259_INTERRUPTS, NR_IRQS);
+ OpenPIC_InitSenses = init_senses;
+ OpenPIC_NumInitSenses = NR_IRQS - NUM_8259_INTERRUPTS;
+ }
+ openpic_init(1, NUM_8259_INTERRUPTS, chrp_int_ack_special, nmi_irq);
+ for ( i = 0 ; i < NUM_8259_INTERRUPTS ; i++ )
irq_desc[i].handler = &i8259_pic;
i8259_init();
-#ifdef CONFIG_XMON
- request_irq(openpic_to_irq(HYDRA_INT_ADB_NMI),
- xmon_irq, 0, "NMI", 0);
-#endif /* CONFIG_XMON */
-#ifdef CONFIG_SMP
- request_irq(openpic_to_irq(OPENPIC_VEC_IPI),
- openpic_ipi_action, 0, "IPI0", 0);
-#endif /* CONFIG_SMP */
+#if defined(CONFIG_VT) && defined(CONFIG_ADB_KEYBOARD) && defined(XMON)
+ /* see if there is a keyboard in the device tree
+ with a parent of type "adb" */
+ for (kbd = find_devices("keyboard"); kbd; kbd = kbd->next)
+ if (kbd->parent && kbd->parent->type
+ && strcmp(kbd->parent->type, "adb") == 0)
+ break;
+ if (kbd)
+ request_irq( HYDRA_INT_ADB_NMI, xmon_irq, 0, "XMON break", 0);
+#endif
}
void __init
@@ -556,12 +516,6 @@ chrp_ide_release_region(ide_ioreg_t from,
}
void __chrp
-chrp_ide_fix_driveid(struct hd_driveid *id)
-{
- ppc_generic_ide_fix_driveid(id);
-}
-
-void __chrp
chrp_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq)
{
ide_ioreg_t reg = data_port;
@@ -586,7 +540,6 @@ void __init
chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7)
{
- chrp_setup_pci_ptrs();
#ifdef CONFIG_BLK_DEV_INITRD
/* take care of initrd if we have one */
if ( r6 )
@@ -596,10 +549,10 @@ void __init
}
#endif /* CONFIG_BLK_DEV_INITRD */
- /* pci_dram_offset/isa_io_base/isa_mem_base set by setup_pci_ptrs() */
ISA_DMA_THRESHOLD = ~0L;
DMA_MODE_READ = 0x44;
DMA_MODE_WRITE = 0x48;
+ isa_io_base = CHRP_ISA_IO_BASE; /* default value */
ppc_md.setup_arch = chrp_setup_arch;
ppc_md.setup_residual = NULL;
@@ -607,8 +560,8 @@ void __init
ppc_md.irq_cannonicalize = chrp_irq_cannonicalize;
#ifndef CONFIG_POWER4
ppc_md.init_IRQ = chrp_init_IRQ;
- ppc_md.get_irq = chrp_get_irq;
- ppc_md.post_irq = chrp_post_irq;
+ ppc_md.get_irq = openpic_get_irq;
+ ppc_md.post_irq = NULL;
#else
ppc_md.init_IRQ = xics_init_IRQ;
ppc_md.get_irq = xics_get_irq;
@@ -669,11 +622,12 @@ void __init
ppc_ide_md.ide_check_region = chrp_ide_check_region;
ppc_ide_md.ide_request_region = chrp_ide_request_region;
ppc_ide_md.ide_release_region = chrp_ide_release_region;
- ppc_ide_md.fix_driveid = chrp_ide_fix_driveid;
+ ppc_ide_md.fix_driveid = ppc_generic_ide_fix_driveid;
ppc_ide_md.ide_init_hwif = chrp_ide_init_hwif_ports;
ppc_ide_md.io_base = _IO_BASE;
#endif
+
/*
* Print the banner, then scroll down so boot progress
* can be printed. -- Cort
diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S
index 89922aaab..93bb8ca00 100644
--- a/arch/ppc/kernel/entry.S
+++ b/arch/ppc/kernel/entry.S
@@ -234,7 +234,6 @@ _GLOBAL(_switch)
li r0,0x0ff0
stw r0,TRAP(r1)
stw r1,KSP(r3) /* Set old stack pointer */
- sync
tophys(r0,r4)
CLR_TOP32(r0)
mtspr SPRG3,r0 /* Update current THREAD phys addr */
@@ -251,7 +250,7 @@ _GLOBAL(_switch)
#endif
mtspr M_TWB,r9 /* Update MMU base address */
tlbia
- SYNC
+ sync
#endif /* CONFIG_8xx */
lwz r1,KSP(r4) /* Load new stack pointer */
/* save the old current 'last' for return value */
@@ -342,23 +341,23 @@ lost_irq_ret:
do_bottom_half_ret:
2: lwz r3,_MSR(r1) /* Returning to user mode? */
andi. r3,r3,MSR_PR
- beq+ restore /* if so, check need_resched and signals */
- .globl ret_to_user_hook
-ret_to_user_hook:
- nop
+ beq+ do_signal_ret /* if so, check need_resched and signals */
lwz r3,NEED_RESCHED(r2)
cmpi 0,r3,0 /* check need_resched flag */
beq+ 7f
bl schedule
7: lwz r5,SIGPENDING(r2) /* Check for pending unblocked signals */
cmpwi 0,r5,0
- beq+ restore
+ beq+ do_signal_ret
li r3,0
addi r4,r1,STACK_FRAME_OVERHEAD
MOL_HOOK_MMU(8,r8)
bl do_signal
.globl do_signal_ret
do_signal_ret:
+ .globl ret_to_user_hook
+ret_to_user_hook:
+ nop
restore:
lwz r3,_XER(r1)
mtspr XER,r3
@@ -372,7 +371,7 @@ restore:
*/
mfmsr r0 /* Get current interrupt state */
rlwinm r0,r0,0,17,15 /* clear MSR_EE in r0 */
- sync /* Some chip revs have problems here... */
+ SYNC /* Some chip revs have problems here... */
mtmsr r0 /* Update machine state */
/* if returning to user mode, set new sprg2 and save kernel SP */
@@ -468,7 +467,7 @@ enter_rtas:
andc r0,r9,r0
li r10,MSR_IR|MSR_DR|MSR_FE0|MSR_FE1|MSR_FP
andc r9,r0,r10
- sync /* disable interrupts so SRR0/1 */
+ SYNC /* disable interrupts so SRR0/1 */
mtmsr r0 /* don't get trashed */
mtlr r6
CLR_TOP32(r7)
diff --git a/arch/ppc/kernel/error_log.c b/arch/ppc/kernel/error_log.c
new file mode 100644
index 000000000..5ee750dda
--- /dev/null
+++ b/arch/ppc/kernel/error_log.c
@@ -0,0 +1,183 @@
+/*
+ * arch/ppc/kernel/error_log.c
+ *
+ * Copyright (c) 2000 Tilmann Bitterberg
+ * (tilmann@bitterberg.de)
+ *
+ * Error processing of errors found by rtas even-scan routine
+ * which is done with every heartbeat. (chrp_setup.c)
+ */
+
+#include <linux/sched.h>
+
+#include <asm/prom.h>
+
+#include "error_log.h"
+
+/* ****************************************************************** */
+/*
+ * EVENT-SCAN
+ * The whole stuff below here doesn't take any action when it found
+ * an error, it just prints as much information as possible and
+ * then its up to the user to decide what to do.
+ *
+ * Returns 0 if no errors were found
+ * Returns 1 if there may be more errors
+ */
+int ppc_rtas_errorlog_scan(void)
+{
+const char *_errlog_severity[] = {
+#ifdef VERBOSE_ERRORS
+ "No Error\n\t\
+Should require no further information",
+ "Event\n\t\
+This is not really an error, it is an event. I use events\n\t\
+to communicate with RTAS back and forth.",
+ "Warning\n\t\
+Indicates a non-state-losing error, either fully recovered\n\t\
+by RTAS or not needing recovery. Ignore it.",
+ "Error sync\n\t\
+May only be fatal to a certain program or thread. Recovery\n\t\
+and continuation is possible, if I only had a handler for\n\t\
+this. Less serious",
+ "Error\n\t\
+Less serious, but still causing a loss of data and state.\n\t\
+I can't tell you exactly what to do, You have to decide\n\t\
+with help from the target and initiator field, what kind\n\t\
+of further actions may take place.",
+ "Fatal\n\t\
+Represent a permanent hardware failure and I believe this\n\t\
+affects my overall performance and behaviour. I would not\n\t\
+attempt to continue normal operation."
+#else
+ "No Error",
+ "Event",
+ "Warning",
+ "Error sync",
+ "Error",
+ "Fatal"
+#endif /* VERBOSE_ERRORS */
+};
+
+#if 0 /* unused?? */
+const char *_errlog_disposition[] = {
+#ifdef VERBOSE_ERRORS
+ "Fully recovered\n\t\
+There was an error, but it is fully recovered by RTAS.",
+ "Limited recovery\n\t\
+RTAS was able to recover the state of the machine, but some\n\t\
+feature of the machine has been disabled or lost (for example\n\t\
+error checking) or performance may suffer.",
+ "Not recovered\n\t\
+Whether RTAS did not try to recover anything or recovery failed:\n\t\
+HOUSTON, WE HAVE A PROBLEM!"
+#else
+ "Fully recovered",
+ "Limited recovery",
+ "Not recovered"
+#endif /* VERBOSE_ERRORS */
+};
+#endif
+
+const char *_errlog_extended[] = {
+#ifdef VERBOSE_ERRORS
+ "Not present\n\t\
+Sad, the RTAS call didn't return an extended error log.",
+ "Present\n\t\
+The extended log is present and hopefully it contains a lot of\n\t\
+useful information, which leads to the solution of the problem."
+#else
+ "Not present",
+ "Present"
+#endif /* VERBOSE_ERRORS */
+};
+
+const char *_errlog_initiator[] = {
+ "Unknown or not applicable",
+ "CPU",
+ "PCI",
+ "ISA",
+ "Memory",
+ "Power management"
+};
+
+const char *_errlog_target[] = {
+ "Unknown or not applicable",
+ "CPU",
+ "PCI",
+ "ISA",
+ "Memory",
+ "Power management"
+};
+ rtas_error_log error_log;
+ char logdata[1024];
+ int error;
+#if 0 /* unused?? */
+ int retries = 0; /* if HW error, try 10 times */
+#endif
+
+ error = call_rtas ("event-scan", 4, 1, (unsigned long *)&error_log,
+ INTERNAL_ERROR | EPOW_WARNING,
+ 0, __pa(logdata), 1024);
+
+ if (error == 1) /* no errors found */
+ return 0;
+
+ if (error == -1) {
+ printk(KERN_ERR "Unable to get errors. Do you a favor and throw this box away\n");
+ return 0;
+ }
+ if (error_log.version != 1)
+ printk(KERN_WARNING "Unknown version (%d), please implement me\n",
+ error_log.version);
+
+ switch (error_log.disposition) {
+ case DISP_FULLY_RECOVERED:
+ /* there was an error, but everything is fine now */
+ return 0;
+ case DISP_NOT_RECOVERED:
+ printk("We have a really serious Problem!\n");
+ case DISP_LIMITED_RECOVERY:
+ printk("Error classification\n");
+ printk("Severity : %s\n",
+ ppc_rtas_errorlog_check_severity (error_log));
+ printk("Initiator : %s\n",
+ ppc_rtas_errorlog_check_initiator (error_log));
+ printk("Target : %s\n",
+ ppc_rtas_errorlog_check_target (error_log));
+ printk("Type : %s\n",
+ ppc_rtas_errorlog_check_type (error_log));
+ printk("Ext. log : %s\n",
+ ppc_rtas_errorlog_check_extended (error_log));
+ if (error_log.extended)
+ ppc_rtas_errorlog_disect_extended (logdata);
+ return 1;
+ default:
+ /* nothing */
+ break;
+ }
+ return 0;
+}
+/* ****************************************************************** */
+const char * ppc_rtas_errorlog_check_type (rtas_error_log error_log)
+{
+ const char *_errlog_type[] = {
+ "unknown type",
+ "too many tries failed",
+ "TCE error",
+ "RTAS device failed",
+ "target timed out",
+ "parity error on data", /* 5 */
+ "parity error on address",
+ "parity error on external cache",
+ "access to invalid address",
+ "uncorrectable ECC error",
+ "corrected ECC error" /* 10 */
+ };
+ if (error_log.type == TYPE_EPOW)
+ return "EPOW";
+ if (error_log.type >= TYPE_PMGM_POWER_SW_ON)
+ return "PowerMGM Event (not handled right now)";
+ return _errlog_type[error_log.type];
+}
+
diff --git a/arch/ppc/kernel/error_log.h b/arch/ppc/kernel/error_log.h
new file mode 100644
index 000000000..579fc3e0d
--- /dev/null
+++ b/arch/ppc/kernel/error_log.h
@@ -0,0 +1,95 @@
+#ifndef __ERROR_LOG_H__
+#define __ERROR_LOG_H__
+
+#define VERBOSE_ERRORS 1 /* Maybe I enlarge the kernel too much */
+#undef VERBOSE_ERRORS
+
+/* Event classes */
+/* XXX: Endianess correct? NOW*/
+#define INTERNAL_ERROR 0x80000000 /* set bit 0 */
+#define EPOW_WARNING 0x40000000 /* set bit 1 */
+#define POWERMGM_EVENTS 0x20000000 /* set bit 2 */
+
+/* event-scan returns */
+#define SEVERITY_FATAL 0x5
+#define SEVERITY_ERROR 0x4
+#define SEVERITY_ERROR_SYNC 0x3
+#define SEVERITY_WARNING 0x2
+#define SEVERITY_EVENT 0x1
+#define SEVERITY_NO_ERROR 0x0
+#define DISP_FULLY_RECOVERED 0x0
+#define DISP_LIMITED_RECOVERY 0x1
+#define DISP_NOT_RECOVERED 0x2
+#define PART_PRESENT 0x0
+#define PART_NOT_PRESENT 0x1
+#define INITIATOR_UNKNOWN 0x0
+#define INITIATOR_CPU 0x1
+#define INITIATOR_PCI 0x2
+#define INITIATOR_ISA 0x3
+#define INITIATOR_MEMORY 0x4
+#define INITIATOR_POWERMGM 0x5
+#define TARGET_UNKNOWN 0x0
+#define TARGET_CPU 0x1
+#define TARGET_PCI 0x2
+#define TARGET_ISA 0x3
+#define TARGET_MEMORY 0x4
+#define TARGET_POWERMGM 0x5
+#define TYPE_RETRY 0x01
+#define TYPE_TCE_ERR 0x02
+#define TYPE_INTERN_DEV_FAIL 0x03
+#define TYPE_TIMEOUT 0x04
+#define TYPE_DATA_PARITY 0x05
+#define TYPE_ADDR_PARITY 0x06
+#define TYPE_CACHE_PARITY 0x07
+#define TYPE_ADDR_INVALID 0x08
+#define TYPE_ECC_UNCORR 0x09
+#define TYPE_ECC_CORR 0x0a
+#define TYPE_EPOW 0x40
+/* I don't add PowerMGM events right now, this is a different topic */
+#define TYPE_PMGM_POWER_SW_ON 0x60
+#define TYPE_PMGM_POWER_SW_OFF 0x61
+#define TYPE_PMGM_LID_OPEN 0x62
+#define TYPE_PMGM_LID_CLOSE 0x63
+#define TYPE_PMGM_SLEEP_BTN 0x64
+#define TYPE_PMGM_WAKE_BTN 0x65
+#define TYPE_PMGM_BATTERY_WARN 0x66
+#define TYPE_PMGM_BATTERY_CRIT 0x67
+#define TYPE_PMGM_SWITCH_TO_BAT 0x68
+#define TYPE_PMGM_SWITCH_TO_AC 0x69
+#define TYPE_PMGM_KBD_OR_MOUSE 0x6a
+#define TYPE_PMGM_ENCLOS_OPEN 0x6b
+#define TYPE_PMGM_ENCLOS_CLOSED 0x6c
+#define TYPE_PMGM_RING_INDICATE 0x6d
+#define TYPE_PMGM_LAN_ATTENTION 0x6e
+#define TYPE_PMGM_TIME_ALARM 0x6f
+#define TYPE_PMGM_CONFIG_CHANGE 0x70
+#define TYPE_PMGM_SERVICE_PROC 0x71
+
+typedef struct _rtas_error_log {
+ unsigned long version:8; /* Architectural version */
+ unsigned long severity:3; /* Severity level of error */
+ unsigned long disposition:2; /* Degree of recovery */
+ unsigned long extended:1; /* extended log present? */
+ unsigned long /* reserved */ :2; /* Reserved for future use */
+ unsigned long initiator:4; /* Initiator of event */
+ unsigned long target:4; /* Target of failed operation */
+ unsigned long type:8; /* General event or error*/
+ unsigned long extended_log_length:32; /* length in bytes */
+} rtas_error_log;
+
+/* ****************************************************************** */
+#define ppc_rtas_errorlog_check_severity(x) \
+ (_errlog_severity[x.severity])
+#define ppc_rtas_errorlog_check_target(x) \
+ (_errlog_target[x.target])
+#define ppc_rtas_errorlog_check_initiator(x) \
+ (_errlog_initiator[x.initiator])
+#define ppc_rtas_errorlog_check_extended(x) \
+ (_errlog_extended[x.extended])
+#define ppc_rtas_errorlog_disect_extended(x) \
+ do { /* implement me */ } while(0)
+extern const char * ppc_rtas_errorlog_check_type (rtas_error_log error_log);
+extern int ppc_rtas_errorlog_scan(void);
+
+
+#endif /* __ERROR_LOG_H__ */
diff --git a/arch/ppc/kernel/feature.c b/arch/ppc/kernel/feature.c
index 57599917a..f22f4b163 100644
--- a/arch/ppc/kernel/feature.c
+++ b/arch/ppc/kernel/feature.c
@@ -238,12 +238,15 @@ feature_add_controller(struct device_node *controller_device, fbit* bits);
static struct feature_controller*
feature_lookup_controller(struct device_node *device);
+#ifdef CONFIG_PMAC_PBOOK
static void heathrow_prepare_for_sleep(struct feature_controller* ctrler);
static void heathrow_wakeup(struct feature_controller* ctrler);
-static void keylargo_init(void);
-static void uninorth_init(void);
static void core99_prepare_for_sleep(struct feature_controller* ctrler);
static void core99_wake_up(struct feature_controller* ctrler);
+#endif /* CONFIG_PMAC_PBOOK */
+
+static void keylargo_init(void);
+static void uninorth_init(void);
/* static variables */
static struct feature_controller controllers[MAX_FEATURE_CONTROLLERS];
@@ -255,6 +258,10 @@ static volatile u32* keylargo_base = NULL;
static int uninorth_rev;
static int keylargo_rev;
+/*
+ * WARNING ! This function is called early in setup_arch, neither the IO base
+ * nor the udelay calibration have been done yet
+ */
void
feature_init(void)
{
@@ -527,14 +534,31 @@ feature_set_usb_power(struct device_node* device, int power)
void
feature_set_firewire_power(struct device_node* device, int power)
{
+ if (!uninorth_base)
+ return;
+ if (power)
+ UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_FW);
+ else
+ UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_FW);
+ udelay(20);
+}
+
+#ifdef CONFIG_SMP
+void
+feature_core99_kick_cpu1(void)
+{
+ out_8((volatile u8 *)KL_FCR(KL_GPIO_KICK_CPU1), KL_GPIO_KICK_CPU1_UP);
+ udelay(1);
+ out_8((volatile u8 *)KL_FCR(KL_GPIO_KICK_CPU1), KL_GPIO_KICK_CPU1_DOWN);
}
+#endif /* CONFIG_SMP */
/* Initialize the Core99 UniNorth host bridge and memory controller
*/
static void
uninorth_init(void)
{
- struct device_node* gmac;
+ struct device_node* gmac, *fw;
unsigned long actrl;
/* Set the arbitrer QAck delay according to what Apple does
@@ -564,6 +588,11 @@ uninorth_init(void)
}
if (gmac)
feature_set_gmac_power(gmac, 0);
+
+ /* Kludge (enable FW before PCI probe) */
+ fw = find_devices("firewire");
+ if (fw && device_is_compatible(fw, "pci106b,18"))
+ feature_set_firewire_power(fw, 1);
}
/* Initialize the Core99 KeyLargo ASIC. Currently, we just make sure
@@ -576,6 +605,43 @@ keylargo_init(void)
}
#ifdef CONFIG_PMAC_PBOOK
+
+static u32 save_fcr[5];
+static u32 save_mbcr;
+
+static void
+heathrow_prepare_for_sleep(struct feature_controller* ctrler)
+{
+ save_mbcr = in_le32(FREG(ctrler, 0x34));
+ save_fcr[0] = in_le32(FREG(ctrler, 0x38));
+ save_fcr[1] = in_le32(FREG(ctrler, 0x3c));
+
+ out_le32(FREG(ctrler, 0x38), save_fcr[0] & ~HRW_IOBUS_ENABLE);
+}
+
+static void
+heathrow_wakeup(struct feature_controller* ctrler)
+{
+ out_le32(FREG(ctrler, 0x38), save_fcr[0]);
+ out_le32(FREG(ctrler, 0x3c), save_fcr[1]);
+ out_le32(FREG(ctrler, 0x34), save_mbcr);
+ mdelay(1);
+ out_le32(FREG(ctrler, 0x38), save_fcr[0] | HRW_IOBUS_ENABLE);
+ mdelay(1);
+}
+
+static void
+core99_prepare_for_sleep(struct feature_controller* ctrler)
+{
+ /* Not yet implemented */
+}
+
+static void
+core99_wake_up(struct feature_controller* ctrler)
+{
+ /* Not yet implemented */
+}
+
void
feature_prepare_for_sleep(void)
{
@@ -599,7 +665,6 @@ feature_prepare_for_sleep(void)
}
}
-
void
feature_wake_up(void)
{
@@ -622,39 +687,4 @@ feature_wake_up(void)
}
}
-static u32 save_fcr[5];
-static u32 save_mbcr;
-
-static void
-heathrow_prepare_for_sleep(struct feature_controller* ctrler)
-{
- save_mbcr = in_le32(FREG(ctrler, 0x34));
- save_fcr[0] = in_le32(FREG(ctrler, 0x38));
- save_fcr[1] = in_le32(FREG(ctrler, 0x3c));
-
- out_le32(FREG(ctrler, 0x38), save_fcr[0] & ~HRW_IOBUS_ENABLE);
-}
-
-static void
-heathrow_wakeup(struct feature_controller* ctrler)
-{
- out_le32(FREG(ctrler, 0x38), save_fcr[0]);
- out_le32(FREG(ctrler, 0x3c), save_fcr[1]);
- out_le32(FREG(ctrler, 0x34), save_mbcr);
- mdelay(1);
- out_le32(FREG(ctrler, 0x38), save_fcr[0] | HRW_IOBUS_ENABLE);
- mdelay(1);
-}
-
-static void
-core99_prepare_for_sleep(struct feature_controller* ctrler)
-{
- /* Not yet implemented */
-}
-
-static void
-core99_wake_up(struct feature_controller* ctrler)
-{
- /* Not yet implemented */
-}
#endif /* CONFIG_PMAC_PBOOK */
diff --git a/arch/ppc/kernel/galaxy_pci.c b/arch/ppc/kernel/galaxy_pci.c
index aeddd9a0e..36e7e14fb 100644
--- a/arch/ppc/kernel/galaxy_pci.c
+++ b/arch/ppc/kernel/galaxy_pci.c
@@ -36,67 +36,84 @@
/* Function Prototypes */
-decl_config_access_method(galaxy);
-
-
void __init
galaxy_pcibios_fixup(void)
{
}
-void __init
-galaxy_setup_pci_ptrs(void)
+static int
+galaxy_pcibios_read_config_byte(struct pci_controller* hose,
+ u8 bus, u8 dev, u8 offset, u8 *val)
{
- set_config_access_method(galaxy);
- ppc_md.pcibios_fixup = galaxy_pcibios_fixup;
+ return (PCIBIOS_SUCCESSFUL);
}
-int
-galaxy_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned char *val)
+static int
+galaxy_pcibios_read_config_word(struct pci_controller* hose,
+ u8 bus, u8 dev, u8 offset, u16 *val)
{
return (PCIBIOS_SUCCESSFUL);
}
-int
-galaxy_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned short *val)
+static int
+galaxy_pcibios_read_config_dword(struct pci_controller* hose,
+ u8 bus, u8 dev, u8 offset, u32 *val)
{
return (PCIBIOS_SUCCESSFUL);
}
-int
-galaxy_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned int *val)
+static int
+galaxy_pcibios_write_config_byte(struct pci_controller* hose,
+ u8 bus, u8 dev, u8 offset, u8 val)
{
return (PCIBIOS_SUCCESSFUL);
}
-int
-galaxy_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned char val)
+static int
+galaxy_pcibios_write_config_word(struct pci_controller* hose,
+ u8 bus, u8 dev, u8 offset, u16 val)
{
return (PCIBIOS_SUCCESSFUL);
}
-int
-galaxy_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned short val)
+static int
+galaxy_pcibios_write_config_dword(struct pci_controller* hose,
+ u8 bus, u8 dev, u8 offset, u32 val)
{
return (PCIBIOS_SUCCESSFUL);
}
-int
-galaxy_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned int val)
+static struct pci_controller_ops galaxy_pci_ops =
{
+ galaxy_pcibios_read_config_byte,
+ galaxy_pcibios_read_config_word,
+ galaxy_pcibios_read_config_dword,
+ galaxy_pcibios_write_config_byte,
+ galaxy_pcibios_write_config_word,
+ galaxy_pcibios_write_config_dword
+};
- return (PCIBIOS_SUCCESSFUL);
+void __init
+galaxy_find_bridges(void)
+{
+ struct pci_controller* hose;
+
+ set_config_access_method(galaxy);
+
+ ppc_md.pcibios_fixup = galaxy_pcibios_fixup;
+ hose = pcibios_alloc_controller();
+ if (!hose)
+ return;
+ hose->ops = &galaxy_pci_ops;
+ /* Todo ...
+ hose->cfg_data = ioremap(PCICFGDATA, ...);
+ hose->cfg_addr = ioremap(PCICFGADDR, ...);
+ */
}
diff --git a/arch/ppc/kernel/hashtable.S b/arch/ppc/kernel/hashtable.S
index 06b7c6f1d..8ea3cdc7a 100644
--- a/arch/ppc/kernel/hashtable.S
+++ b/arch/ppc/kernel/hashtable.S
@@ -56,7 +56,6 @@ hash_page:
#ifdef CONFIG_PPC64BRIDGE
mfmsr r0
clrldi r0,r0,1 /* make sure it's in 32-bit mode */
- sync
MTMSRD(r0)
isync
#endif
@@ -112,23 +111,31 @@ hash_page:
#endif
tophys(r2,r5)
rlwimi r2,r3,22,20,29 /* insert next 10 bits of address */
- lwz r6,0(r2) /* get linux-style pte */
ori r4,r4,1 /* set _PAGE_PRESENT bit in access */
+ rlwinm r5,r4,5,24,24 /* _PAGE_RW access -> _PAGE_DIRTY */
+ rlwimi r5,r4,7,22,22 /* _PAGE_RW -> _PAGE_HWWRITE */
+ ori r5,r5,0x100 /* set _PAGE_ACCESSED */
+retry:
+ lwz r6,0(r2) /* get linux-style pte */
andc. r0,r4,r6 /* check access & ~permission */
#ifdef CONFIG_SMP
bne- hash_page_out /* return if access not permitted */
#else
bnelr-
#endif
+ andc. r0,r5,r6 /* any bits not yet set? */
+ beq 2f
- ori r6,r6,0x100 /* set _PAGE_ACCESSED in pte */
- rlwinm r5,r4,5,24,24 /* _PAGE_RW access -> _PAGE_DIRTY */
- rlwimi r5,r4,7,22,22 /* _PAGE_RW -> _PAGE_HWWRITE */
- or r6,r6,r5
- stw r6,0(r2) /* update PTE (accessed/dirty bits) */
+ /* Update the linux PTE atomically */
+ lwarx r0,0,r2 /* refetch the pte and check */
+ cmpw 0,r0,r6 /* that it hasn't been changed */
+ bne- retry /* retry if it has */
+ or r6,r6,r5 /* set accessed/dirty bits */
+ stwcx. r6,0,r2 /* attempt to update PTE */
+ bne- retry /* retry if someone got there first */
/* Convert linux-style PTE to low word of PPC-style PTE */
- rlwinm r4,r6,32-9,31,31 /* _PAGE_HWWRITE -> PP lsb */
+2: rlwinm r4,r6,32-9,31,31 /* _PAGE_HWWRITE -> PP lsb */
rlwimi r6,r6,32-1,31,31 /* _PAGE_USER -> PP (both bits now) */
ori r4,r4,0xe04 /* clear out reserved bits */
andc r6,r6,r4 /* PP=2 or 0, when _PAGE_HWWRITE */
@@ -166,12 +173,16 @@ hash_page_patch_A:
rlwimi r4,r5,32-5,25-Hash_bits,24 /* (VSID & hash_mask) << 7 */
rlwinm r0,r3,32-5,25-Hash_bits,24 /* (PI & hash_mask) << 7 */
xor r4,r4,r0 /* make primary hash */
+ li r2,8 /* PTEs/group */
+#ifndef CONFIG_SMP
+ /* We don't do this for SMP - another cpu could have put in
+ the appropriate PTE since we took the exception. -- paulus. */
/* See whether it was a PTE not found exception or a
protection violation. */
andis. r0,r20,0x4000
- li r2,8 /* PTEs/group */
bne 10f /* no PTE: go look for an empty slot */
+#endif /* CONFIG_SMP */
tlbie r3 /* invalidate TLB entry */
/* Search the primary PTEG for a PTE whose 1st dword matches r5 */
@@ -263,7 +274,6 @@ found_empty:
std r5,0(r3)
found_slot:
std r6,8(r3)
- sync
#else /* CONFIG_SMP */
/*
@@ -311,12 +321,16 @@ hash_page_patch_A:
rlwimi r4,r5,32-1,26-Hash_bits,25 /* (VSID & hash_mask) << 6 */
rlwinm r0,r3,32-6,26-Hash_bits,25 /* (PI & hash_mask) << 6 */
xor r4,r4,r0 /* make primary hash */
+ li r2,8 /* PTEs/group */
+#ifndef CONFIG_SMP
+ /* We don't do this for SMP - another cpu could have put in
+ the appropriate PTE since we took the exception. -- paulus. */
/* See whether it was a PTE not found exception or a
protection violation. */
andis. r0,r20,0x4000
- li r2,8 /* PTEs/group */
bne 10f /* no PTE: go look for an empty slot */
+#endif /* CONFIG_SMP */
tlbie r3 /* invalidate TLB entry */
/* Search the primary PTEG for a PTE whose 1st word matches r5 */
@@ -394,7 +408,6 @@ found_empty:
stw r5,0(r3)
found_slot:
stw r6,4(r3)
- sync
#else /* CONFIG_SMP */
/*
@@ -428,6 +441,8 @@ found_slot:
#endif /* CONFIG_SMP */
#endif /* CONFIG_PPC64BRIDGE */
+ sync /* make sure pte updates get to memory */
+
/*
* Update the hash table miss count. We only want misses here
* that _are_ valid addresses and have a pte otherwise we don't
@@ -517,7 +532,7 @@ _GLOBAL(flush_hash_segments)
a hash table miss while we have the hash table locked,
or we'll get a deadlock. -paulus */
mfmsr r10
- sync
+ SYNC
rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */
mtmsr r0
SYNC
@@ -616,7 +631,7 @@ _GLOBAL(flush_hash_page)
a hash table miss while we have the hash table locked,
or we'll get a deadlock. -paulus */
mfmsr r10
- sync
+ SYNC
rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */
mtmsr r0
SYNC
@@ -628,10 +643,14 @@ _GLOBAL(flush_hash_page)
oris r8,r8,9
10: lwarx r7,0,r9
cmpi 0,r7,0
- bne- 10b
+ bne- 11f
stwcx. r8,0,r9
- bne- 10b
- eieio
+ beq+ 12f
+11: lwz r7,0(r9)
+ cmpi 0,r7,0
+ beq 10b
+ b 11b
+12: eieio
#endif
#ifndef CONFIG_PPC64BRIDGE
rlwinm r3,r3,11,1,20 /* put context into vsid */
diff --git a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S
index 71b5a96c5..f296d1606 100644
--- a/arch/ppc/kernel/head.S
+++ b/arch/ppc/kernel/head.S
@@ -149,6 +149,8 @@ __start:
mr r28,r6
mr r27,r7
li r24,0 /* cpu # */
+ /* N.B. prom_init clears the BSS even if it doesn't do
+ * anything else -- paulus. */
bl prom_init
#ifdef CONFIG_APUS
@@ -159,7 +161,6 @@ __start:
bl fix_mem_constants
#endif /* CONFIG_APUS */
-#ifndef CONFIG_GEMINI
/* Switch MMU off, clear BATs and flush TLB. At this point, r3 contains
* the physical address we are running at, returned by prom_init()
*/
@@ -167,7 +168,6 @@ __start:
__after_mmu_off:
bl clear_bats
bl flush_tlbs
-#endif
#ifndef CONFIG_POWER4
/* POWER4 doesn't have BATs */
@@ -290,6 +290,7 @@ label: \
addi r3,r1,STACK_FRAME_OVERHEAD; \
li r20,MSR_KERNEL; \
bl transfer_to_handler; \
+i##n: \
.long hdlr; \
.long ret_from_except
@@ -301,17 +302,13 @@ label: \
addi r3,r1,STACK_FRAME_OVERHEAD; \
li r20,MSR_KERNEL; \
bl transfer_to_handler; \
+i##n: \
.long hdlr; \
.long ret_from_except
/* System reset */
-#ifdef CONFIG_SMP /* MVME/MTX and gemini start the secondary here */
-#ifdef CONFIG_GEMINI
- . = 0x100
- b __secondary_start_gemini
-#else /* CONFIG_GEMINI */
+#ifdef CONFIG_SMP /* MVME/MTX start the secondary here */
STD_EXCEPTION(0x100, Reset, __secondary_start_psurge)
-#endif /* CONFIG_GEMINI */
#else
STD_EXCEPTION(0x100, Reset, UnknownException)
#endif
@@ -344,6 +341,7 @@ DataAccess:
li r20,MSR_KERNEL
rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
bl transfer_to_handler
+i0x300:
.long do_page_fault
.long ret_from_except
@@ -384,6 +382,7 @@ InstructionAccess:
li r20,MSR_KERNEL
rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
bl transfer_to_handler
+i0x400:
.long do_page_fault
.long ret_from_except
@@ -429,6 +428,7 @@ Alignment:
li r20,MSR_KERNEL
rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
bl transfer_to_handler
+i0x600:
.long AlignmentException
.long ret_from_except
@@ -441,6 +441,7 @@ ProgramCheck:
li r20,MSR_KERNEL
rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
bl transfer_to_handler
+i0x700:
.long ProgramCheckException
.long ret_from_except
@@ -452,6 +453,7 @@ FPUnavailable:
bne load_up_fpu /* if from user, just load it up */
li r20,MSR_KERNEL
bl transfer_to_handler /* if from kernel, take a trap */
+i0x800:
.long KernelFP
.long ret_from_except
@@ -575,7 +577,7 @@ InstructionAddressInvalid:
mfmsr r0 /* Restore "normal" registers */
xoris r0,r0,MSR_TGPR>>16
mtcrf 0x80,r3 /* Restore CR0 */
- sync /* Some chip revs have problems here... */
+ SYNC /* Some chip revs have problems here... */
mtmsr r0
b InstructionAccess
@@ -646,7 +648,7 @@ DataAddressInvalid:
mfmsr r0 /* Restore "normal" registers */
xoris r0,r0,MSR_TGPR>>16
mtcrf 0x80,r3 /* Restore CR0 */
- sync /* Some chip revs have problems here... */
+ SYNC /* Some chip revs have problems here... */
mtmsr r0
b DataAccess
@@ -843,7 +845,7 @@ load_up_fpu:
#endif /* CONFIG_PPC64BRIDGE */
SYNC
MTMSRD(r5) /* enable use of fpu now */
- SYNC
+ isync
/*
* For SMP, we don't do lazy FPU switching because it just gets too
* horrendously complex, especially when a task switches from one CPU
@@ -929,7 +931,7 @@ load_up_altivec:
oris r5,r5,MSR_VEC@h
SYNC
mtmsr r5 /* enable use of AltiVec now */
- SYNC
+ isync
/*
* For SMP, we don't do lazy AltiVec switching because it just gets too
* horrendously complex, especially when a task switches from one CPU
@@ -1023,7 +1025,7 @@ giveup_altivec:
oris r5,r5,MSR_VEC@h
SYNC
mtmsr r5 /* enable use of AltiVec now */
- SYNC
+ isync
cmpi 0,r3,0
beqlr- /* if no previous owner, done */
addi r3,r3,THREAD /* want THREAD of task */
@@ -1064,7 +1066,7 @@ giveup_fpu:
ori r5,r5,MSR_FP
SYNC
mtmsr r5 /* enable use of fpu now */
- SYNC
+ isync
cmpi 0,r3,0
beqlr- /* if no previous owner, done */
addi r3,r3,THREAD /* want THREAD of task */
@@ -1163,6 +1165,7 @@ fix_mem_constants:
icbi r0,r14 /* flush the icache line */
cmpw r12,r13
bne 1b
+ isync
/*
* Map the memory where the exception handlers will
@@ -1208,9 +1211,9 @@ apus_interrupt_entry:
mfmsr 20
xori r20,r20,MSR_DR
- sync
+ SYNC
mtmsr r20
- sync
+ isync
lis r4,APUS_IPL_EMU@h
@@ -1243,9 +1246,9 @@ apus_interrupt_entry:
mfmsr r20
xori r20,r20,MSR_DR
- sync
+ SYNC
mtmsr r20
- sync
+ isync
stw r3,(_CCR+4)(r21);
@@ -1263,28 +1266,24 @@ apus_interrupt_entry:
#endif /* CONFIG_APUS */
#ifdef CONFIG_SMP
-#ifdef CONFIG_GEMINI
- .globl __secondary_start_gemini
-__secondary_start_gemini:
- mfspr r4,HID0
- ori r4,r4,HID0_ICFI
- li r3,0
- ori r3,r3,HID0_ICE
- andc r4,r4,r3
- mtspr HID0,r4
- sync
- bl prom_init
- b __secondary_start
-#endif /* CONFIG_GEMINI */
-
.globl __secondary_start_psurge
__secondary_start_psurge:
li r24,1 /* cpu # */
+ b __secondary_start_psurge99
+ .globl __secondary_start_psurge2
+__secondary_start_psurge2:
+ li r24,2 /* cpu # */
+ b __secondary_start_psurge99
+ .globl __secondary_start_psurge3
+__secondary_start_psurge3:
+ li r24,3 /* cpu # */
+ b __secondary_start_psurge99
+__secondary_start_psurge99:
/* we come in here with IR=0 and DR=1, and DBAT 0
set to map the 0xf0000000 - 0xffffffff region */
mfmsr r0
rlwinm r0,r0,0,28,26 /* clear DR (0x10) */
- sync
+ SYNC
mtmsr r0
isync
@@ -1293,7 +1292,7 @@ __secondary_start:
#ifdef CONFIG_PPC64BRIDGE
mfmsr r0
clrldi r0,r0,1 /* make sure it's in 32-bit mode */
- sync
+ SYNC
MTMSRD(r0)
isync
#else
@@ -1445,21 +1444,6 @@ start_here:
li r3,0
mtspr SPRG2,r3 /* 0 => r1 has kernel sp */
- /* Clear out the BSS */
- lis r11,_end@ha
- addi r11,r11,_end@l
- lis r8,__bss_start@ha
- addi r8,r8,__bss_start@l
- subf r11,r8,r11
- addi r11,r11,3
- rlwinm. r11,r11,30,2,31
- beq 2f
- addi r8,r8,-4
- mtctr r11
- li r0,0
-3: stwu r0,4(r8)
- bdnz 3b
-2:
/* stack */
addi r1,r2,TASK_UNION_SIZE
li r0,0
@@ -1504,7 +1488,7 @@ start_here:
RFI
/* Load up the kernel context */
2:
- SYNC /* Force all PTE updates to finish */
+ sync /* Force all PTE updates to finish */
tlbia /* Clear all TLB entries */
sync /* wait for tlbia/tlbie to finish */
#ifdef CONFIG_SMP
@@ -1552,7 +1536,6 @@ _GLOBAL(set_context)
* -- Cort
*/
clear_bats:
-#if !defined(CONFIG_GEMINI)
li r20,0
mfspr r9,PVR
rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */
@@ -1576,10 +1559,8 @@ clear_bats:
mtspr IBAT2L,r20
mtspr IBAT3U,r20
mtspr IBAT3L,r20
-#endif /* !defined(CONFIG_GEMINI) */
blr
-#ifndef CONFIG_GEMINI
flush_tlbs:
lis r20, 0x40
1: addic. r20, r20, -0x1000
@@ -1598,7 +1579,6 @@ mmu_off:
mtspr SRR1,r3
sync
RFI
-#endif
#ifndef CONFIG_POWER4
/*
@@ -1745,3 +1725,12 @@ swapper_pg_dir:
.globl cmd_line
cmd_line:
.space 512
+
+ .globl intercept_table
+intercept_table:
+ .long 0, i0x100, i0x200, i0x300, i0x400, 0, i0x600, i0x700
+ .long i0x800, 0, 0, 0, 0, i0xd00, 0, 0
+ .long 0, 0, 0, i0x1300, 0, 0, 0, 0
+ .long 0, 0, 0, 0, 0, 0, 0, 0
+ .long 0, 0, 0, 0, 0, 0, 0, 0
+ .long 0, 0, 0, 0, 0, 0, 0, 0
diff --git a/arch/ppc/kernel/i8259.c b/arch/ppc/kernel/i8259.c
index bdb6ec844..7690d9091 100644
--- a/arch/ppc/kernel/i8259.c
+++ b/arch/ppc/kernel/i8259.c
@@ -10,12 +10,15 @@ unsigned char cached_8259[2] = { 0xff, 0xff };
#define cached_A1 (cached_8259[0])
#define cached_21 (cached_8259[1])
+spinlock_t i8259_lock = SPIN_LOCK_UNLOCKED;
+
int i8259_pic_irq_offset;
int i8259_irq(int cpu)
{
int irq;
+ spin_lock/*_irqsave*/(&i8259_lock/*, flags*/);
/*
* Perform an interrupt acknowledge cycle on controller 1
*/
@@ -40,14 +43,20 @@ int i8259_irq(int cpu)
* interrupt
*/
outb(0x0b, 0x20);
- if(~inb(0x20)&0x80)
+ if(~inb(0x20)&0x80) {
+ spin_unlock/*_irqrestore*/(&i8259_lock/*, flags*/);
return -1;
+ }
}
+ spin_unlock/*_irqrestore*/(&i8259_lock/*, flags*/);
return irq;
}
static void i8259_mask_and_ack_irq(unsigned int irq_nr)
{
+ unsigned long flags;
+
+ spin_lock_irqsave(&i8259_lock, flags);
if ( irq_nr >= i8259_pic_irq_offset )
irq_nr -= i8259_pic_irq_offset;
@@ -63,6 +72,7 @@ static void i8259_mask_and_ack_irq(unsigned int irq_nr)
outb(cached_21,0x21);
outb(0x20,0x20); /* Non-specific EOI */
}
+ spin_unlock_irqrestore(&i8259_lock, flags);
}
static void i8259_set_irq_mask(int irq_nr)
@@ -73,6 +83,9 @@ static void i8259_set_irq_mask(int irq_nr)
static void i8259_mask_irq(unsigned int irq_nr)
{
+ unsigned long flags;
+
+ spin_lock_irqsave(&i8259_lock, flags);
if ( irq_nr >= i8259_pic_irq_offset )
irq_nr -= i8259_pic_irq_offset;
if ( irq_nr < 8 )
@@ -80,11 +93,14 @@ static void i8259_mask_irq(unsigned int irq_nr)
else
cached_A1 |= 1 << (irq_nr-8);
i8259_set_irq_mask(irq_nr);
+ spin_unlock_irqrestore(&i8259_lock, flags);
}
static void i8259_unmask_irq(unsigned int irq_nr)
{
+ unsigned long flags;
+ spin_lock_irqsave(&i8259_lock, flags);
if ( irq_nr >= i8259_pic_irq_offset )
irq_nr -= i8259_pic_irq_offset;
if ( irq_nr < 8 )
@@ -92,6 +108,13 @@ static void i8259_unmask_irq(unsigned int irq_nr)
else
cached_A1 &= ~(1 << (irq_nr-8));
i8259_set_irq_mask(irq_nr);
+ spin_unlock_irqrestore(&i8259_lock, flags);
+}
+
+static void i8259_end_irq(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+ i8259_unmask_irq(irq);
}
struct hw_interrupt_type i8259_pic = {
@@ -101,11 +124,15 @@ struct hw_interrupt_type i8259_pic = {
i8259_unmask_irq,
i8259_mask_irq,
i8259_mask_and_ack_irq,
- 0
+ i8259_end_irq,
+ NULL
};
void __init i8259_init(void)
{
+ unsigned long flags;
+
+ spin_lock_irqsave(&i8259_lock, flags);
/* init master interrupt controller */
outb(0x11, 0x20); /* Start init sequence */
outb(0x00, 0x21); /* Vector base */
@@ -120,7 +147,7 @@ void __init i8259_init(void)
outb(0xFF, 0xA1); /* Mask all */
outb(cached_A1, 0xA1);
outb(cached_21, 0x21);
+ spin_unlock_irqrestore(&i8259_lock, flags);
request_irq( i8259_pic_irq_offset + 2, no_action, SA_INTERRUPT,
"82c59 secondary cascade", NULL );
- enable_irq(i8259_pic_irq_offset + 2); /* Enable cascade interrupt */
}
diff --git a/arch/ppc/kernel/idle.c b/arch/ppc/kernel/idle.c
index a363a0e34..6ca616979 100644
--- a/arch/ppc/kernel/idle.c
+++ b/arch/ppc/kernel/idle.c
@@ -47,24 +47,35 @@ atomic_t zeropage_calls; /* # zero'd pages request that've been made */
int idled(void)
{
+ int do_power_save = 0;
+
+ /* only sleep on the 603-family/750 processors */
+ switch (_get_PVR() >> 16) {
+ case 3: /* 603 */
+ case 6: /* 603e */
+ case 7: /* 603ev */
+ case 8: /* 750 */
+ case 12: /* 7400 */
+ do_power_save = 1;
+ }
+
/* endless loop with no priority at all */
current->nice = 20;
current->counter = -100;
init_idle();
for (;;)
{
- __sti();
-
- check_pgt_cache();
-
- /*if ( !current->need_resched && zero_paged_on ) zero_paged();*/
- if ( !current->need_resched && htab_reclaim_on ) htab_reclaim();
- if ( !current->need_resched ) power_save();
+ /*if ( !current->need_resched && zero_paged_on )
+ zero_paged();*/
+ if (!current->need_resched && htab_reclaim_on)
+ htab_reclaim();
+ if (do_power_save && !current->need_resched)
+ power_save();
-#ifdef CONFIG_SMP
- if (current->need_resched)
-#endif
+ if (current->need_resched) {
schedule();
+ check_pgt_cache();
+ }
}
return 0;
}
@@ -278,31 +289,31 @@ void zero_paged(void)
void power_save(void)
{
- unsigned long msr, hid0;
-
- /* only sleep on the 603-family/750 processors */
- switch (_get_PVR() >> 16) {
- case 3: /* 603 */
- case 6: /* 603e */
- case 7: /* 603ev */
- case 8: /* 750 */
- case 12: /* 7400 */
- save_flags(msr);
- __cli();
- if (!current->need_resched) {
- asm("mfspr %0,1008" : "=r" (hid0) :);
- hid0 &= ~(HID0_NAP | HID0_SLEEP | HID0_DOZE);
- hid0 |= (powersave_nap? HID0_NAP: HID0_DOZE) | HID0_DPM;
- asm("mtspr 1008,%0" : : "r" (hid0));
+ unsigned long hid0;
+ /*
+ * Disable interrupts to prevent a lost wakeup
+ * when going to sleep. This is necessary even with
+ * RTLinux since we are not guaranteed an interrupt
+ * didn't come in and is waiting for a __sti() before
+ * emulating one. This way, we really do hard disable.
+ *
+ * We assume that we're sti-ed when we come in here. We
+ * are in the idle loop so if we're cli-ed then it's a bug
+ * anyway.
+ * -- Cort
+ */
+ _nmask_and_or_msr(MSR_EE, 0);
+ if (!current->need_resched)
+ {
+ asm("mfspr %0,1008" : "=r" (hid0) :);
+ hid0 &= ~(HID0_NAP | HID0_SLEEP | HID0_DOZE);
+ hid0 |= (powersave_nap? HID0_NAP: HID0_DOZE) | HID0_DPM;
+ asm("mtspr 1008,%0" : : "r" (hid0));
- /* set the POW bit in the MSR, and enable interrupts
- * so we wake up sometime! */
- __sti(); /* this keeps rtl from getting confused -- Cort */
- _nmask_and_or_msr(0, MSR_POW | MSR_EE);
- }
- restore_flags(msr);
- default:
- return;
+ /* set the POW bit in the MSR, and enable interrupts
+ * so we wake up sometime! */
+ _nmask_and_or_msr(0, MSR_POW | MSR_EE);
}
+ _nmask_and_or_msr(0, MSR_EE);
}
diff --git a/arch/ppc/kernel/indirect_pci.c b/arch/ppc/kernel/indirect_pci.c
index 552c552dc..3ba335d1f 100644
--- a/arch/ppc/kernel/indirect_pci.c
+++ b/arch/ppc/kernel/indirect_pci.c
@@ -9,113 +9,59 @@
* 2 of the License, or (at your option) any later version.
*/
+#include <linux/kernel.h>
#include <linux/pci.h>
-#include <asm/io.h>
-#include <asm/system.h>
-
-unsigned int * pci_config_address;
-unsigned char * pci_config_data;
-
-int indirect_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned char *val)
-{
- unsigned long flags;
-
- save_flags(flags); cli();
-
- out_be32(pci_config_address,
- ((offset&0xfc)<<24) | (dev_fn<<16) | (bus<<8) | 0x80);
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
- *val= in_8(pci_config_data + (offset&3));
-
- restore_flags(flags);
- return PCIBIOS_SUCCESSFUL;
+#include <asm/init.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#include <asm/machdep.h>
+
+#include "pci.h"
+
+#define cfg_read(val, addr, type, op) *val = op((type)(addr))
+#define cfg_write(val, addr, type, op) op((type *)(addr), (val))
+
+#define INDIRECT_PCI_OP(rw, size, type, op, mask) \
+static int \
+indirect_##rw##_config_##size(struct pci_dev *dev, int offset, type val) \
+{ \
+ struct pci_controller *hose = dev->sysdata; \
+ \
+ out_be32(hose->cfg_addr, \
+ ((offset & 0xfc) << 24) | (dev->devfn << 16) \
+ | (dev->bus->number << 8) | 0x80); \
+ cfg_##rw(val, hose->cfg_data + (offset & mask), type, op); \
+ return PCIBIOS_SUCCESSFUL; \
}
-int indirect_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned short *val)
-{
- unsigned long flags;
-
- if (offset&1) return PCIBIOS_BAD_REGISTER_NUMBER;
-
- save_flags(flags); cli();
-
- out_be32(pci_config_address,
- ((offset&0xfc)<<24) | (dev_fn<<16) | (bus<<8) | 0x80);
+INDIRECT_PCI_OP(read, byte, u8 *, in_8, 3)
+INDIRECT_PCI_OP(read, word, u16 *, in_le16, 2)
+INDIRECT_PCI_OP(read, dword, u32 *, in_le32, 0)
+INDIRECT_PCI_OP(write, byte, u8, out_8, 3)
+INDIRECT_PCI_OP(write, word, u16, out_le16, 2)
+INDIRECT_PCI_OP(write, dword, u32, out_le32, 0)
- *val= in_le16((unsigned short *)(pci_config_data + (offset&3)));
-
- restore_flags(flags);
- return PCIBIOS_SUCCESSFUL;
-}
-
-int indirect_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned int *val)
+static struct pci_ops indirect_pci_ops =
{
- unsigned long flags;
-
- if (offset&3) return PCIBIOS_BAD_REGISTER_NUMBER;
-
- save_flags(flags); cli();
-
- out_be32(pci_config_address,
- ((offset&0xfc)<<24) | (dev_fn<<16) | (bus<<8) | 0x80);
-
- *val= in_le32((unsigned *)pci_config_data);
-
- restore_flags(flags);
- return PCIBIOS_SUCCESSFUL;
-}
-
-int indirect_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned char val)
+ indirect_read_config_byte,
+ indirect_read_config_word,
+ indirect_read_config_dword,
+ indirect_write_config_byte,
+ indirect_write_config_word,
+ indirect_write_config_dword
+};
+
+void __init
+setup_indirect_pci(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data)
{
- unsigned long flags;
-
- save_flags(flags); cli();
-
- out_be32(pci_config_address,
- ((offset&0xfc)<<24) | (dev_fn<<16) | (bus<<8) | 0x80);
-
- out_8(pci_config_data + (offset&3), val);
-
- restore_flags(flags);
- return PCIBIOS_SUCCESSFUL;
-}
-
-int indirect_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned short val)
-{
- unsigned long flags;
-
- if (offset&1) return PCIBIOS_BAD_REGISTER_NUMBER;
-
- save_flags(flags); cli();
-
- out_be32(pci_config_address,
- ((offset&0xfc)<<24) | (dev_fn<<16) | (bus<<8) | 0x80);
-
- out_le16((unsigned short *)(pci_config_data + (offset&3)), val);
-
- restore_flags(flags);
- return PCIBIOS_SUCCESSFUL;
+ hose->ops = &indirect_pci_ops;
+ hose->cfg_addr = (unsigned int *) ioremap(cfg_addr, 4);
+ hose->cfg_data = (unsigned char *) ioremap(cfg_data, 4);
}
-int indirect_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned int val)
-{
- unsigned long flags;
-
- if (offset&3) return PCIBIOS_BAD_REGISTER_NUMBER;
-
- save_flags(flags); cli();
-
- out_be32(pci_config_address,
- ((offset&0xfc)<<24) | (dev_fn<<16) | (bus<<8) | 0x80);
-
- out_le32((unsigned *)pci_config_data, val);
-
- restore_flags(flags);
- return PCIBIOS_SUCCESSFUL;
-}
diff --git a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c
index a0caa4a4c..02ff4d964 100644
--- a/arch/ppc/kernel/irq.c
+++ b/arch/ppc/kernel/irq.c
@@ -41,11 +41,11 @@
#include <linux/config.h>
#include <linux/init.h>
#include <linux/malloc.h>
-#include <linux/openpic.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/proc_fs.h>
+#include <linux/random.h>
#include <asm/uaccess.h>
#include <asm/bitops.h>
@@ -64,19 +64,22 @@
#include "local_irq.h"
-extern volatile unsigned long ipi_count;
+atomic_t ipi_recv;
+atomic_t ipi_sent;
void enable_irq(unsigned int irq_nr);
void disable_irq(unsigned int irq_nr);
-volatile unsigned char *chrp_int_ack_special;
+static void register_irq_proc (unsigned int irq);
#define MAXCOUNT 10000000
-irq_desc_t irq_desc[NR_IRQS];
+irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned =
+ { [0 ... NR_IRQS-1] = { 0, NULL, NULL, 0, SPIN_LOCK_UNLOCKED}};
+
int ppc_spurious_interrupts = 0;
struct irqaction *ppc_irq_action[NR_IRQS];
-unsigned int ppc_cached_irq_mask[NR_MASK_WORDS];
-unsigned int ppc_lost_interrupts[NR_MASK_WORDS];
+unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
+unsigned long ppc_lost_interrupts[NR_MASK_WORDS];
atomic_t ppc_n_lost_interrupts;
/* nasty hack for shared irq's since we need to do kmalloc calls but
@@ -115,52 +118,136 @@ void irq_kfree(void *ptr)
kfree(ptr);
}
+int
+setup_irq(unsigned int irq, struct irqaction * new)
+{
+ int shared = 0;
+ unsigned long flags;
+ struct irqaction *old, **p;
+ irq_desc_t *desc = irq_desc + irq;
+
+ /*
+ * Some drivers like serial.c use request_irq() heavily,
+ * so we have to be careful not to interfere with a
+ * running system.
+ */
+ if (new->flags & SA_SAMPLE_RANDOM) {
+ /*
+ * This function might sleep, we want to call it first,
+ * outside of the atomic block.
+ * Yes, this might clear the entropy pool if the wrong
+ * driver is attempted to be loaded, without actually
+ * installing a new handler, but is this really a problem,
+ * only the sysadmin is able to do this.
+ */
+ rand_initialize_irq(irq);
+ }
+
+ /*
+ * The following block of code has to be executed atomically
+ */
+ spin_lock_irqsave(&desc->lock,flags);
+ p = &desc->action;
+ if ((old = *p) != NULL) {
+ /* Can't share interrupts unless both agree to */
+ if (!(old->flags & new->flags & SA_SHIRQ)) {
+ spin_unlock_irqrestore(&desc->lock,flags);
+ return -EBUSY;
+ }
+
+ /* add new interrupt at end of irq queue */
+ do {
+ p = &old->next;
+ old = *p;
+ } while (old);
+ shared = 1;
+ }
+
+ *p = new;
+
+ if (!shared) {
+ desc->depth = 0;
+ desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING);
+ unmask_irq(irq);
+ }
+ spin_unlock_irqrestore(&desc->lock,flags);
+
+ register_irq_proc(irq);
+ return 0;
+}
+
+/* This could be promoted to a real free_irq() ... */
+static int
+do_free_irq(int irq, void* dev_id)
+{
+ irq_desc_t *desc;
+ struct irqaction **p;
+ unsigned long flags;
+
+ desc = irq_desc + irq;
+ spin_lock_irqsave(&desc->lock,flags);
+ p = &desc->action;
+ for (;;) {
+ struct irqaction * action = *p;
+ if (action) {
+ struct irqaction **pp = p;
+ p = &action->next;
+ if (action->dev_id != dev_id)
+ continue;
+
+ /* Found it - now remove it from the list of entries */
+ *pp = action->next;
+ if (!desc->action) {
+ desc->status |= IRQ_DISABLED;
+ mask_irq(irq);
+ }
+ spin_unlock_irqrestore(&desc->lock,flags);
+
+#ifdef CONFIG_SMP
+ /* Wait to make sure it's not being used on another CPU */
+ while (desc->status & IRQ_INPROGRESS)
+ barrier();
+#endif
+ irq_kfree(action);
+ return 0;
+ }
+ printk("Trying to free free IRQ%d\n",irq);
+ spin_unlock_irqrestore(&desc->lock,flags);
+ break;
+ }
+ return -ENOENT;
+}
+
#if (defined(CONFIG_8xx) || defined(CONFIG_8260))
/* Name change so we can catch standard drivers that potentially mess up
* the internal interrupt controller on 8xx and 8260. Just bear with me,
* I don't like this either and I am searching a better solution. For
* now, this is what I need. -- Dan
*/
-int request_8xxirq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+#define request_irq request_8xxirq
#elif defined(CONFIG_APUS)
-int request_sysirq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
-#else
-int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+#define request_irq request_sysirq
+#define free_irq sys_free_irq
#endif
+
+int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
unsigned long irqflags, const char * devname, void *dev_id)
{
- struct irqaction *old, **p, *action;
- unsigned long flags;
+ struct irqaction *action;
+ int retval;
if (irq >= NR_IRQS)
return -EINVAL;
if (!handler)
- {
- /* Free */
- p = &irq_desc[irq].action;
- while ((action = *p) != NULL && action->dev_id != dev_id)
- p = &action->next;
- if (action == NULL)
- return -ENOENT;
-
- /* Found it - now free it */
- save_flags(flags);
- cli();
- *p = action->next;
- if (irq_desc[irq].action == NULL)
- disable_irq(irq);
- restore_flags(flags);
- irq_kfree(action);
- return 0;
- }
+ /* We could implement really free_irq() instead of that... */
+ return do_free_irq(irq, dev_id);
action = (struct irqaction *)
irq_kmalloc(sizeof(struct irqaction), GFP_KERNEL);
- if (!action)
+ if (!action) {
+ printk(KERN_ERR "irq_kmalloc() failed for irq %d !\n", irq);
return -ENOMEM;
-
- save_flags(flags);
- cli();
+ }
action->handler = handler;
action->flags = irqflags;
@@ -168,57 +255,109 @@ int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *)
action->name = devname;
action->dev_id = dev_id;
action->next = NULL;
- enable_irq(irq);
- p = &irq_desc[irq].action;
-
- if ((old = *p) != NULL) {
- /* Can't share interrupts unless both agree to */
- if (!(old->flags & action->flags & SA_SHIRQ))
- return -EBUSY;
- /* add new interrupt at end of irq queue */
- do {
- p = &old->next;
- old = *p;
- } while (old);
- }
- *p = action;
-
- restore_flags(flags);
+ retval = setup_irq(irq, action);
+ if (retval)
+ kfree(action);
+
return 0;
}
-#ifdef CONFIG_APUS
-void sys_free_irq(unsigned int irq, void *dev_id)
-{
- sys_request_irq(irq, NULL, 0, NULL, dev_id);
-}
-#else
void free_irq(unsigned int irq, void *dev_id)
{
-#if (defined(CONFIG_8xx) || defined(CONFIG_8260))
- request_8xxirq(irq, NULL, 0, NULL, dev_id);
-#else
request_irq(irq, NULL, 0, NULL, dev_id);
-#endif
}
-#endif
-/* XXX should implement irq disable depth like on intel */
-void disable_irq_nosync(unsigned int irq_nr)
+/*
+ * Generic enable/disable code: this just calls
+ * down into the PIC-specific version for the actual
+ * hardware disable after having gotten the irq
+ * controller lock.
+ */
+
+/**
+ * disable_irq_nosync - disable an irq without waiting
+ * @irq: Interrupt to disable
+ *
+ * Disable the selected interrupt line. Disables of an interrupt
+ * stack. Unlike disable_irq(), this function does not ensure existing
+ * instances of the IRQ handler have completed before returning.
+ *
+ * This function may be called from IRQ context.
+ */
+
+ void disable_irq_nosync(unsigned int irq)
{
- mask_irq(irq_nr);
+ irq_desc_t *desc = irq_desc + irq;
+ unsigned long flags;
+
+ spin_lock_irqsave(&desc->lock, flags);
+ if (!desc->depth++) {
+ if (!(desc->status & IRQ_PER_CPU))
+ desc->status |= IRQ_DISABLED;
+ mask_irq(irq);
+ }
+ spin_unlock_irqrestore(&desc->lock, flags);
}
-void disable_irq(unsigned int irq_nr)
+/**
+ * disable_irq - disable an irq and wait for completion
+ * @irq: Interrupt to disable
+ *
+ * Disable the selected interrupt line. Disables of an interrupt
+ * stack. That is for two disables you need two enables. This
+ * function waits for any pending IRQ handlers for this interrupt
+ * to complete before returning. If you use this function while
+ * holding a resource the IRQ handler may need you will deadlock.
+ *
+ * This function may be called - with care - from IRQ context.
+ */
+
+void disable_irq(unsigned int irq)
{
- mask_irq(irq_nr);
- synchronize_irq();
+ disable_irq_nosync(irq);
+
+ if (!local_irq_count(smp_processor_id())) {
+ do {
+ barrier();
+ } while (irq_desc[irq].status & IRQ_INPROGRESS);
+ }
}
-void enable_irq(unsigned int irq_nr)
+/**
+ * enable_irq - enable interrupt handling on an irq
+ * @irq: Interrupt to enable
+ *
+ * Re-enables the processing of interrupts on this IRQ line
+ * providing no disable_irq calls are now in effect.
+ *
+ * This function may be called from IRQ context.
+ */
+
+void enable_irq(unsigned int irq)
{
- unmask_irq(irq_nr);
+ irq_desc_t *desc = irq_desc + irq;
+ unsigned long flags;
+
+ spin_lock_irqsave(&desc->lock, flags);
+ switch (desc->depth) {
+ case 1: {
+ unsigned int status = desc->status & ~IRQ_DISABLED;
+ desc->status = status;
+ if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
+ desc->status = status | IRQ_REPLAY;
+ hw_resend_irq(desc->handler,irq);
+ }
+ unmask_irq(irq);
+ /* fall-through */
+ }
+ default:
+ desc->depth--;
+ break;
+ case 0:
+ printk("enable_irq(%u) unbalanced\n", irq);
+ }
+ spin_unlock_irqrestore(&desc->lock, flags);
}
int get_irq_list(char *buf)
@@ -257,15 +396,41 @@ int get_irq_list(char *buf)
}
len += sprintf(buf+len, "\n");
}
+#ifdef CONFIG_TAU
+ len += sprintf(buf+len, "TAU: ");
+ for (j = 0; j < smp_num_cpus; j++)
+ len += sprintf(buf+len, "%10u ",
+ tau_interrupts(j));
+ len += sprintf(buf+len, "\n");
+#endif
#ifdef CONFIG_SMP
/* should this be per processor send/receive? */
- len += sprintf(buf+len, "IPI: %10lu\n", ipi_count);
+ len += sprintf(buf+len, "IPI (recv/sent): %10u/%u\n",
+ atomic_read(&ipi_recv), atomic_read(&ipi_sent));
#endif
len += sprintf(buf+len, "BAD: %10u\n", ppc_spurious_interrupts);
return len;
#endif /* CONFIG_APUS */
}
+static inline void
+handle_irq_event(int irq, struct pt_regs *regs, struct irqaction *action)
+{
+ int status = 0;
+
+ if (!(action->flags & SA_INTERRUPT))
+ __sti();
+
+ do {
+ status |= action->flags;
+ action->handler(irq, action->dev_id, regs);
+ action = action->next;
+ } while (action);
+ if (status & SA_SAMPLE_RANDOM)
+ add_interrupt_randomness(irq);
+ __cli();
+}
+
/*
* Eventually, this should take an array of interrupts and an array size
* so it can dispatch multiple interrupts.
@@ -275,33 +440,87 @@ void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq)
int status;
struct irqaction *action;
int cpu = smp_processor_id();
+ irq_desc_t *desc = irq_desc + irq;
- mask_and_ack_irq(irq);
- status = 0;
- action = irq_desc[irq].action;
kstat.irqs[cpu][irq]++;
- if (action && action->handler) {
- if (!(action->flags & SA_INTERRUPT))
- __sti();
- do {
- status |= action->flags;
- action->handler(irq, action->dev_id, regs);
- action = action->next;
- } while ( action );
- __cli();
- if (irq_desc[irq].handler) {
- if (irq_desc[irq].handler->end)
- irq_desc[irq].handler->end(irq);
- else if (irq_desc[irq].handler->enable)
- irq_desc[irq].handler->enable(irq);
+ spin_lock(&desc->lock);
+ ack_irq(irq);
+ /*
+ REPLAY is when Linux resends an IRQ that was dropped earlier
+ WAITING is used by probe to mark irqs that are being tested
+ */
+ status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
+ if (!(status & IRQ_PER_CPU))
+ status |= IRQ_PENDING; /* we _want_ to handle it */
+
+ /*
+ * If the IRQ is disabled for whatever reason, we cannot
+ * use the action we have.
+ */
+ action = NULL;
+ if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+ action = desc->action;
+ if (!action || !action->handler) {
+ ppc_spurious_interrupts++;
+ printk(KERN_DEBUG "Unhandled interrupt %x, disabled\n", irq);
+ /* We can't call disable_irq here, it would deadlock */
+ if (!desc->depth)
+ desc->depth = 1;
+ desc->status |= IRQ_DISABLED;
+ /* This is not a real spurrious interrupt, we
+ * have to eoi it, so we jump to out
+ */
+ mask_irq(irq);
+ goto out;
}
- } else {
- ppc_spurious_interrupts++;
- printk(KERN_DEBUG "Unhandled interrupt %x, disabled\n", irq);
- disable_irq(irq);
+ status &= ~IRQ_PENDING; /* we commit to handling */
+ if (!(status & IRQ_PER_CPU))
+ status |= IRQ_INPROGRESS; /* we are handling it */
+ }
+ desc->status = status;
+
+ /*
+ * If there is no IRQ handler or it was disabled, exit early.
+ Since we set PENDING, if another processor is handling
+ a different instance of this same irq, the other processor
+ will take care of it.
+ */
+ if (!action)
+ goto out;
+
+
+ /*
+ * Edge triggered interrupts need to remember
+ * pending events.
+ * This applies to any hw interrupts that allow a second
+ * instance of the same irq to arrive while we are in do_IRQ
+ * or in the handler. But the code here only handles the _second_
+ * instance of the irq, not the third or fourth. So it is mostly
+ * useful for irq hardware that does not mask cleanly in an
+ * SMP environment.
+ */
+ for (;;) {
+ spin_unlock(&desc->lock);
+ handle_irq_event(irq, regs, action);
+ spin_lock(&desc->lock);
+
+ if (!(desc->status & IRQ_PENDING))
+ break;
+ desc->status &= ~IRQ_PENDING;
+ }
+ desc->status &= ~IRQ_INPROGRESS;
+out:
+ /*
+ * The ->end() handler has to deal with interrupts which got
+ * disabled while the handler was running.
+ */
+ if (irq_desc[irq].handler) {
if (irq_desc[irq].handler->end)
irq_desc[irq].handler->end(irq);
+ else if (irq_desc[irq].handler->enable)
+ irq_desc[irq].handler->enable(irq);
}
+ spin_unlock(&desc->lock);
}
int do_IRQ(struct pt_regs *regs, int isfake)
@@ -320,6 +539,7 @@ int do_IRQ(struct pt_regs *regs, int isfake)
{
printk(KERN_DEBUG "Bogus interrupt %d from PC = %lx\n",
irq, regs->nip);
+ /* That's not SMP safe ... but who cares ? */
ppc_spurious_interrupts++;
}
goto out;
@@ -362,7 +582,7 @@ void __init init_IRQ(void)
#ifdef CONFIG_SMP
unsigned char global_irq_holder = NO_PROC_ID;
-unsigned volatile int global_irq_lock;
+unsigned volatile long global_irq_lock; /* pendantic :long for set_bit--RR*/
atomic_t global_irq_count;
atomic_t global_bh_count;
@@ -634,7 +854,11 @@ static struct proc_dir_entry * root_irq_dir;
static struct proc_dir_entry * irq_dir [NR_IRQS];
static struct proc_dir_entry * smp_affinity_entry [NR_IRQS];
+#ifdef CONFIG_IRQ_ALL_CPUS
unsigned int irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = 0xffffffff};
+#else /* CONFIG_IRQ_ALL_CPUS */
+unsigned int irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = 0x00000000};
+#endif /* CONFIG_IRQ_ALL_CPUS */
#define HEX_DIGITS 8
@@ -694,6 +918,7 @@ static int irq_affinity_write_proc (struct file *file, const char *buffer,
err = parse_hex_value(buffer, count, &new_value);
+/* Why is this disabled ? --BenH */
#if 0/*CONFIG_SMP*/
/*
* Do not allow disabling IRQs completely - it's a too easy
diff --git a/arch/ppc/kernel/local_irq.h b/arch/ppc/kernel/local_irq.h
index 5c616bbbd..319e3377c 100644
--- a/arch/ppc/kernel/local_irq.h
+++ b/arch/ppc/kernel/local_irq.h
@@ -15,8 +15,5 @@ void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq);
extern int ppc_spurious_interrupts;
extern int ppc_second_irq;
extern struct irqaction *ppc_irq_action[NR_IRQS];
-extern unsigned int ppc_cached_irq_mask[NR_MASK_WORDS];
-extern unsigned int ppc_lost_interrupts[NR_MASK_WORDS];
-extern atomic_t ppc_n_lost_interrupts;
#endif /* _PPC_KERNEL_LOCAL_IRQ_H */
diff --git a/arch/ppc/kernel/m8260_setup.c b/arch/ppc/kernel/m8260_setup.c
index 6e006a867..a55f5235d 100644
--- a/arch/ppc/kernel/m8260_setup.c
+++ b/arch/ppc/kernel/m8260_setup.c
@@ -62,7 +62,7 @@ extern void mackbd_leds(unsigned char leds);
extern void mackbd_init_hw(void);
#endif
-extern unsigned long loops_per_sec;
+extern unsigned long loops_per_jiffy;
unsigned char __res[sizeof(bd_t)];
unsigned long empty_zero_page[1024];
@@ -286,10 +286,7 @@ m8260_init(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_ide_md.outsw = m8xx_ide_outsw;
ppc_ide_md.default_irq = m8xx_ide_default_irq;
ppc_ide_md.default_io_base = m8xx_ide_default_io_base;
- ppc_ide_md.check_region = m8xx_ide_check_region;
- ppc_ide_md.request_region = m8xx_ide_request_region;
- ppc_ide_md.release_region = m8xx_ide_release_region;
- ppc_ide_md.fix_driveid = m8xx_ide_fix_driveid;
+ ppc_ide_md.fix_driveid = ppc_generic_ide_fix_driveid;
ppc_ide_md.ide_init_hwif = m8xx_ide_init_hwif_ports;
ppc_ide_md.ide_request_irq = m8xx_ide_request_irq;
@@ -297,13 +294,39 @@ m8260_init(unsigned long r3, unsigned long r4, unsigned long r5,
#endif
}
-void
+/*
+ * Copied from prom.c so I don't have include all of that crap.
+ * -- Dan
+ *
+ * prom_init() is called very early on, before the kernel text
+ * and data have been mapped to KERNELBASE. At this point the code
+ * is running at whatever address it has been loaded at, so
+ * references to extern and static variables must be relocated
+ * explicitly. The procedure reloc_offset() returns the address
+ * we're currently running at minus the address we were linked at.
+ * (Note that strings count as static variables.)
+ */
+extern unsigned long reloc_offset(void);
+#define PTRRELOC(x) ((typeof(x))((unsigned long)(x) + offset))
+
+__init
+unsigned long
prom_init(uint r3, uint r4, uint r5, uint r6)
{
- /* Nothing to do now, but we are called immediatedly upon
- * kernel start up with MMU disabled, so if there is
- * anything we need to do......
- */
+ unsigned long offset = reloc_offset();
+ unsigned long phys;
+ extern char __bss_start, _end;
+
+ /* First zero the BSS -- use memset, some arches don't have
+ * caches on yet */
+ memset_io(PTRRELOC(&__bss_start),0 , &_end - &__bss_start);
+
+ /* Default */
+ phys = offset + KERNELBASE;
+
+ /* We are done.
+ */
+ return phys;
}
/* Mainly for ksyms.
diff --git a/arch/ppc/kernel/m8xx_setup.c b/arch/ppc/kernel/m8xx_setup.c
index 7dc408a13..f9813fa75 100644
--- a/arch/ppc/kernel/m8xx_setup.c
+++ b/arch/ppc/kernel/m8xx_setup.c
@@ -63,8 +63,6 @@ extern void mackbd_leds(unsigned char leds);
extern void mackbd_init_hw(void);
#endif
-extern unsigned long loops_per_sec;
-
unsigned char __res[sizeof(bd_t)];
unsigned long empty_zero_page[1024];
@@ -344,25 +342,6 @@ m8xx_ide_default_io_base(int index)
}
int
-m8xx_ide_check_region(ide_ioreg_t from, unsigned int extent)
-{
- return 0;
-}
-
-void
-m8xx_ide_request_region(ide_ioreg_t from,
- unsigned int extent,
- const char *name)
-{
-}
-
-void
-m8xx_ide_release_region(ide_ioreg_t from,
- unsigned int extent)
-{
-}
-
-int
m8xx_ide_request_irq(unsigned int irq,
void (*handler)(int, void *, struct pt_regs *),
unsigned long flags,
@@ -376,12 +355,6 @@ m8xx_ide_request_irq(unsigned int irq,
#endif
}
-void
-m8xx_ide_fix_driveid(struct hd_driveid *id)
-{
- ppc_generic_ide_fix_driveid(id);
-}
-
/* We can use an external IDE controller or wire the IDE interface to
* the internal PCMCIA controller.
*/
@@ -515,10 +488,7 @@ m8xx_init(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_ide_md.outsw = m8xx_ide_outsw;
ppc_ide_md.default_irq = m8xx_ide_default_irq;
ppc_ide_md.default_io_base = m8xx_ide_default_io_base;
- ppc_ide_md.check_region = m8xx_ide_check_region;
- ppc_ide_md.request_region = m8xx_ide_request_region;
- ppc_ide_md.release_region = m8xx_ide_release_region;
- ppc_ide_md.fix_driveid = m8xx_ide_fix_driveid;
+ ppc_ide_md.fix_driveid = ppc_generic_ide_fix_driveid;
ppc_ide_md.ide_init_hwif = m8xx_ide_init_hwif_ports;
ppc_ide_md.ide_request_irq = m8xx_ide_request_irq;
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
index 94e1cd277..3f54003c7 100644
--- a/arch/ppc/kernel/misc.S
+++ b/arch/ppc/kernel/misc.S
@@ -37,6 +37,14 @@
.text
+ .align 5
+_GLOBAL(__delay)
+ cmpwi 0,r3,0
+ mtctr r3
+ beqlr
+1: bdnz 1b
+ blr
+
/*
* Returns (address we're running at) - (address we were linked at)
* for use before the text and data are mapped to KERNELBASE.
@@ -82,16 +90,16 @@ _GLOBAL(__no_use_restore_flags)
lwz r7,ppc_n_lost_interrupts@l(r7)
cmpi 0,r7,0 /* lost interrupts to process first? */
bne- do_lost_interrupts
-1: sync
+1: SYNC
mtmsr r3
- isync
+ SYNC
blr
_GLOBAL(__no_use_cli)
mfmsr r0 /* Get current interrupt state */
rlwinm r3,r0,16+1,32-1,31 /* Extract old value of 'EE' */
rlwinm r0,r0,0,17,15 /* clear MSR_EE in r0 */
- sync /* Some chip revs have problems here... */
+ SYNC /* Some chip revs have problems here... */
mtmsr r0 /* Update machine state */
blr /* Done */
@@ -102,7 +110,7 @@ _GLOBAL(__no_use_sti)
ori r3,r3,MSR_EE /* Turn on 'EE' bit */
cmpi 0,r4,0 /* lost interrupts to process first? */
bne- do_lost_interrupts
- sync /* Some chip revs have problems here... */
+ SYNC /* Some chip revs have problems here... */
mtmsr r3 /* Update machine state */
blr
@@ -121,7 +129,7 @@ _GLOBAL(do_lost_interrupts)
cmpi 0,r4,0
bne- 1b
lwz r3,8(r1)
- sync
+ SYNC
mtmsr r3
lwz r0,20(r1)
mtlr r0
@@ -137,8 +145,9 @@ _GLOBAL(do_lost_interrupts)
mfmsr r0 /* Get current msr */
andc r0,r0,r3 /* And off the bits set in r3 (first parm) */
or r0,r0,r4 /* Or on the bits in r4 (second parm) */
- sync /* Some chip revs have problems here... */
+ SYNC /* Some chip revs have problems here... */
mtmsr r0 /* Update machine state */
+ isync
blr /* Done */
@@ -148,7 +157,7 @@ _GLOBAL(do_lost_interrupts)
_GLOBAL(_tlbia)
#if defined(CONFIG_SMP)
mfmsr r10
- sync
+ SYNC
rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */
mtmsr r0
SYNC
@@ -161,7 +170,6 @@ _GLOBAL(_tlbia)
bne- 10b
stwcx. r8,0,r9
bne- 10b
- eieio
#endif /* CONFIG_SMP */
sync
tlbia
@@ -182,7 +190,7 @@ _GLOBAL(_tlbia)
_GLOBAL(_tlbie)
#if defined(CONFIG_SMP)
mfmsr r10
- sync
+ SYNC
rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */
mtmsr r0
SYNC
@@ -228,7 +236,7 @@ _GLOBAL(flush_instruction_cache)
ori r3,r3,HID0_ICFI
mtspr HID0,r3
#endif /* CONFIG_8xx */
- SYNC
+ isync
blr
/*
@@ -259,7 +267,6 @@ _GLOBAL(flush_icache_range)
2: icbi 0,r6
addi r6,r6,CACHE_LINE_SIZE
bdnz 2b
- sync
isync
blr
@@ -717,6 +724,8 @@ _GLOBAL(_get_SP)
mr r3,r1 /* Close enough */
blr
+#if 0
+/* isn't it just easier to use the mtspr/mfspr inline macros?? --Troy */
_GLOBAL(_get_THRM1)
mfspr r3,THRM1
blr
@@ -740,6 +749,7 @@ _GLOBAL(_set_THRM2)
_GLOBAL(_set_THRM3)
mtspr THRM3,r3
blr
+#endif
_GLOBAL(_get_PVR)
mfspr r3,PVR
@@ -755,6 +765,12 @@ _GLOBAL(_get_HID0)
mfspr r3,HID0
blr
+_GLOBAL(_set_HID0)
+ sync
+ mtspr HID0, r3
+ SYNC /* Handle erratas in some cases */
+ blr
+
_GLOBAL(_get_ICTC)
mfspr r3,ICTC
blr
@@ -763,7 +779,6 @@ _GLOBAL(_set_ICTC)
mtspr ICTC,r3
blr
-
/*
L2CR functions
Copyright © 1997-1998 by PowerLogix R & D, Inc.
@@ -785,6 +800,17 @@ _GLOBAL(_set_ICTC)
/*
Thur, Dec. 12, 1998.
- First public release, contributed by PowerLogix.
+ ***********
+ Sat, Aug. 7, 1999.
+ - Terry: Made sure code disabled interrupts before running. (Previously
+ it was assumed interrupts were already disabled).
+ - Terry: Updated for tentative G4 support. 4MB of memory is now flushed
+ instead of 2MB. (Prob. only 3 is necessary).
+ - Terry: Updated for workaround to HID0[DPM] processor bug
+ during global invalidates.
+ ***********
+ Thu, July 13, 2000.
+ - Terry: Added isync to correct for an errata.
Author: Terry Greeniaus (tgree@phys.ualberta.ca)
Please e-mail updates to this file to me, thanks!
@@ -823,82 +849,94 @@ _GLOBAL(_set_ICTC)
causes cache pushes from the L1 cache to go to the L2 cache
instead of to main memory.
*/
-
+/*
+ * Summary: this procedure ignores the L2I bit in the value passed in,
+ * flushes the cache if it was already enabled, always invalidates the
+ * cache, then enables the cache if the L2E bit is set in the value
+ * passed in.
+ * -- paulus.
+ */
_GLOBAL(_set_L2CR)
- /* Make sure this is a 750 chip */
+ /* Make sure this is a 750 or 7400 chip */
mfspr r4,PVR
rlwinm r4,r4,16,16,31
- cmplwi r4,0x0008
- beq thisIs750
- cmplwi r4,0x000c
- beq thisIs750
- li r3,-1
- blr
-
-thisIs750:
- /* Get the current enable bit of the L2CR into r4 */
- mfspr r4,L2CR
- mfmsr r7
-
- /* See if we want to perform a global inval this time. */
- rlwinm r6,r3,0,10,10 /* r6 contains the new invalidate bit */
- rlwinm. r5,r3,0,0,0 /* r5 contains the new enable bit */
- rlwinm r3,r3,0,11,9 /* Turn off the invalidate bit */
- rlwimi r3,r4,0,0,0 /* Keep the enable bit the same as it was. */
- bne dontDisableCache /* Only disable the cache if L2CRApply
- has the enable bit off */
-
-disableCache:
- /* Disable the cache. First, we turn off interrupts.
- An interrupt while we are flushing the cache could bring
- in data which may not get properly flushed. */
- rlwinm r4,r7,0,17,15 /* Turn off EE bit */
+ cmpwi r4,0x0008
+ cmpwi cr1,r4,0x000c
+ cror 2,2,4*cr1+2
+ bne 99f
+
+ /* Turn off interrupts and data relocation. */
+ mfmsr r7 /* Save MSR in r7 */
+ rlwinm r4,r7,0,17,15
+ rlwinm r4,r4,0,28,26 /* Turn off DR bit */
sync
mtmsr r4
- sync
+ isync
+
+ /* Get the current enable bit of the L2CR into r4 */
+ mfspr r4,L2CR
-/*
- Now, read the first 2MB of memory to put new data in the cache.
- (Actually we only need the size of the L2 cache plus the size
- of the L1 cache, but 2MB will cover everything just to be safe).
-*/
- lis r4,0x0001
+ /* Tweak some bits */
+ rlwinm r5,r3,0,0,0 /* r5 contains the new enable bit */
+ rlwinm r3,r3,0,11,9 /* Turn off the invalidate bit */
+ rlwinm r3,r3,0,1,31 /* Turn off the enable bit */
+
+ /* Check to see if we need to flush */
+ rlwinm. r4,r4,0,0,0
+ beq 2f
+
+ /* Flush the cache. First, read the first 4MB of memory (physical) to
+ * put new data in the cache. (Actually we only need
+ * the size of the L2 cache plus the size of the L1 cache, but 4MB will
+ * cover everything just to be safe).
+ */
+
+ /**** Might be a good idea to set L2DO here - to prevent instructions
+ from getting into the cache. But since we invalidate
+ the next time we enable the cache it doesn't really matter.
+ ****/
+
+ lis r4,0x0002
mtctr r4
- lis r4,KERNELBASE@h
-1: lwzx r0,r0,r4
- addi r4,r4,0x0020 /* Go to start of next cache line */
+ li r4,0
+1:
+ lwzx r0,r0,r4
+ addi r4,r4,32 /* Go to start of next cache line */
bdnz 1b
- /* Now, flush the first 2MB of memory */
- lis r4,0x0001
+ /* Now, flush the first 4MB of memory */
+ lis r4,0x0002
mtctr r4
- lis r4,KERNELBASE@h
+ li r4,0
sync
-2: dcbf r0,r4
- addi r4,r4,0x0020 /* Go to start of next cache line */
- bdnz 2b
-
- /* Turn off the L2CR enable bit. */
- rlwinm r3,r3,0,1,31
-
-dontDisableCache:
- /* Set up the L2CR configuration bits */
+1:
+ dcbf r0,r4
+ addi r4,r4,32 /* Go to start of next cache line */
+ bdnz 1b
+
+2:
+ /* Set up the L2CR configuration bits (and switch L2 off) */
sync
mtspr L2CR,r3
sync
- /* Reenable interrupts if necessary. */
- mtmsr r7
+ /* Before we perform the global invalidation, we must disable dynamic
+ * power management via HID0[DPM] to work around a processor bug where
+ * DPM can possibly interfere with the state machine in the processor
+ * that invalidates the L2 cache tags.
+ */
+ mfspr r8,HID0 /* Save HID0 in r8 */
+ rlwinm r4,r8,0,12,10 /* Turn off HID0[DPM] */
sync
-
- cmplwi r6,0
- beq noInval
-
+ mtspr HID0,r4 /* Disable DPM */
+ sync
+
/* Perform a global invalidation */
oris r3,r3,0x0020
sync
mtspr L2CR,r3
sync
+ isync /* For errata */
/* Wait for the invalidation to complete */
3: mfspr r3,L2CR
@@ -910,27 +948,38 @@ dontDisableCache:
mtspr L2CR,r3
sync
-noInval:
+ /* Restore HID0[DPM] to whatever it was before */
+ sync
+ mtspr 1008,r8
+ sync
+
/* See if we need to enable the cache */
cmplwi r5,0
- beqlr
+ beq 4f
/* Enable the cache */
oris r3,r3,0x8000
mtspr L2CR,r3
sync
+
+ /* Restore MSR (restores EE and DR bits to original state) */
+4: SYNC
+ mtmsr r7
+ isync
+ blr
+
+99: li r3,-1
blr
_GLOBAL(_get_L2CR)
/* Make sure this is a 750 chip */
mfspr r3,PVR
- rlwinm r3,r3,16,16,31
- cmplwi r3,0x0008
- beq 1f
- cmplwi r3,0x000c
+ srwi r3,r3,16
+ cmpwi r3,0x0008
+ cmpwi cr1,r3,0x000c
li r3,0
+ cror 2,2,4*cr1+2
bnelr
-1:
/* Return the L2CR contents */
mfspr r3,L2CR
blr
@@ -986,15 +1035,6 @@ _GLOBAL(cvt_df)
blr
#endif
-_GLOBAL(__clear_msr_me)
- mfmsr r0 /* Get current interrupt state */
- lis r3,0
- ori r3,r3,MSR_ME
- andc r0,r0,r3 /* Clears bit in (r4) */
- sync /* Some chip revs have problems here */
- mtmsr r0 /* Update machine state */
- blr
-
/*
* Create a kernel thread
* kernel_thread(fn, arg, flags)
@@ -1244,16 +1284,20 @@ _GLOBAL(sys_call_table)
.long sys_getrlimit /* 190 */
.long sys_ni_syscall /* 191 */ /* Unused */
.long sys_ni_syscall /* 192 - reserved - mmap2 */
- .long sys_ni_syscall /* 193 - reserved - truncate64 */
- .long sys_ni_syscall /* 194 - reserved - ftruncate64 */
- .long sys_ni_syscall /* 195 - reserved - stat64 */
- .long sys_ni_syscall /* 196 - reserved - lstat64 */
- .long sys_ni_syscall /* 197 - reserved - fstat64 */
+ .long sys_truncate64 /* 193 */
+ .long sys_ftruncate64 /* 194 */
+ .long sys_stat64 /* 195 */
+ .long sys_lstat64 /* 196 */
+ .long sys_fstat64 /* 197 */
.long sys_pciconfig_read /* 198 */
.long sys_pciconfig_write /* 199 */
.long sys_pciconfig_iobase /* 200 */
.long sys_ni_syscall /* 201 - reserved - MacOnLinux - new */
.long sys_getdents64 /* 202 */
+ .long sys_pivot_root /* 203 */
+ .long sys_fcntl64 /* 204 */
+ .long sys_madvise /* 205 */
+ .long sys_mincore /* 206 */
.rept NR_syscalls-(.-sys_call_table)/4
.long sys_ni_syscall
.endr
diff --git a/arch/ppc/kernel/open_pic.c b/arch/ppc/kernel/open_pic.c
index 5ca365b1c..0cbd4f553 100644
--- a/arch/ppc/kernel/open_pic.c
+++ b/arch/ppc/kernel/open_pic.c
@@ -1,5 +1,5 @@
/*
- * arch/ppc/kernel/openpic.c -- OpenPIC Interrupt Handling
+ * arch/ppc/kernel/open_pic.c -- OpenPIC Interrupt Handling
*
* Copyright (C) 1997 Geert Uytterhoeven
*
@@ -13,35 +13,38 @@
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/init.h>
-#include <linux/openpic.h>
+#include <linux/irq.h>
#include <asm/ptrace.h>
#include <asm/signal.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/prom.h>
+
#include "local_irq.h"
+#include "open_pic.h"
+#include "open_pic_defs.h"
-volatile struct OpenPIC *OpenPIC = NULL;
+void* OpenPIC_Addr;
+static volatile struct OpenPIC *OpenPIC = NULL;
u_int OpenPIC_NumInitSenses __initdata = 0;
u_char *OpenPIC_InitSenses __initdata = NULL;
-int open_pic_irq_offset;
extern int use_of_interrupt_tree;
-void chrp_mask_irq(unsigned int);
-void chrp_unmask_irq(unsigned int);
void find_ISUs(void);
static u_int NumProcessors;
static u_int NumSources;
-OpenPIC_Source *ISU;
-/*
- * We should use this if we have > 1 ISU.
- * We can just point each entry to the
- * appropriate source regs but it wastes a lot of space
- * so until we have >1 ISU I'll leave it unimplemented.
- * -- Cort
-OpenPIC_Source ISU[128];
-*/
+#ifdef CONFIG_POWER3
+static int NumISUs;
+#endif
+static int open_pic_irq_offset;
+static volatile unsigned char* chrp_int_ack_special;
+
+OpenPIC_SourcePtr ISU[OPENPIC_MAX_ISU];
+
+static void openpic_end_irq(unsigned int irq_nr);
+static void openpic_ack_irq(unsigned int irq_nr);
+static void openpic_set_affinity(unsigned int irq_nr, unsigned long cpumask);
struct hw_interrupt_type open_pic = {
" OpenPIC ",
@@ -49,45 +52,69 @@ struct hw_interrupt_type open_pic = {
NULL,
openpic_enable_irq,
openpic_disable_irq,
- 0,
+ openpic_ack_irq,
+ openpic_end_irq,
+ openpic_set_affinity
+};
+
+#ifdef CONFIG_SMP
+static void openpic_end_ipi(unsigned int irq_nr);
+static void openpic_ack_ipi(unsigned int irq_nr);
+static void openpic_enable_ipi(unsigned int irq_nr);
+static void openpic_disable_ipi(unsigned int irq_nr);
+
+struct hw_interrupt_type open_pic_ipi = {
+ " OpenPIC ",
+ NULL,
+ NULL,
+ openpic_enable_ipi,
+ openpic_disable_ipi,
+ openpic_ack_ipi,
+ openpic_end_ipi,
0
};
+#endif /* CONFIG_SMP */
/*
- * Accesses to the current processor's registers
+ * Accesses to the current processor's openpic registers
*/
-#ifndef __powerpc__
-#define THIS_CPU Private
-#define CHECK_THIS_CPU do {} while (0)
-#else
+#ifdef CONFIG_SMP
#define THIS_CPU Processor[cpu]
+#define DECL_THIS_CPU int cpu = smp_hw_index[smp_processor_id()]
#define CHECK_THIS_CPU check_arg_cpu(cpu)
-#endif
+#else
+#define THIS_CPU Processor[0]
+#define DECL_THIS_CPU
+#define CHECK_THIS_CPU
+#endif /* CONFIG_SMP */
#if 1
#define check_arg_ipi(ipi) \
if (ipi < 0 || ipi >= OPENPIC_NUM_IPI) \
- printk("openpic.c:%d: illegal ipi %d\n", __LINE__, ipi);
+ printk("open_pic.c:%d: illegal ipi %d\n", __LINE__, ipi);
#define check_arg_timer(timer) \
if (timer < 0 || timer >= OPENPIC_NUM_TIMERS) \
- printk("openpic.c:%d: illegal timer %d\n", __LINE__, timer);
+ printk("open_pic.c:%d: illegal timer %d\n", __LINE__, timer);
#define check_arg_vec(vec) \
if (vec < 0 || vec >= OPENPIC_NUM_VECTORS) \
- printk("openpic.c:%d: illegal vector %d\n", __LINE__, vec);
+ printk("open_pic.c:%d: illegal vector %d\n", __LINE__, vec);
#define check_arg_pri(pri) \
if (pri < 0 || pri >= OPENPIC_NUM_PRI) \
- printk("openpic.c:%d: illegal priority %d\n", __LINE__, pri);
+ printk("open_pic.c:%d: illegal priority %d\n", __LINE__, pri);
/*
- * I changed this to return to keep us from from trying to use irq #'s
- * that we're using for IPI's.
- * -- Cort
- */
+ * Print out a backtrace if it's out of range, since if it's larger than NR_IRQ's
+ * data has probably been corrupted and we're going to panic or deadlock later
+ * anyway --Troy
+ */
+extern unsigned long* _get_SP(void);
#define check_arg_irq(irq) \
- /*if (irq < 0 || irq >= (NumSources+open_pic_irq_offset)) \
- printk("openpic.c:%d: illegal irq %d\n", __LINE__, irq);*/
+ if (irq < open_pic_irq_offset || irq >= (NumSources+open_pic_irq_offset)){ \
+ printk("open_pic.c:%d: illegal irq %d\n", __LINE__, irq); \
+ print_backtrace(_get_SP()); }
#define check_arg_cpu(cpu) \
- if (cpu < 0 || cpu >= NumProcessors) \
- printk("openpic.c:%d: illegal cpu %d\n", __LINE__, cpu);
+ if (cpu < 0 || cpu >= NumProcessors){ \
+ printk("open_pic.c:%d: illegal cpu %d\n", __LINE__, cpu); \
+ print_backtrace(_get_SP()); }
#else
#define check_arg_ipi(ipi) do {} while (0)
#define check_arg_timer(timer) do {} while (0)
@@ -97,23 +124,10 @@ struct hw_interrupt_type open_pic = {
#define check_arg_cpu(cpu) do {} while (0)
#endif
-#ifdef CONFIG_SMP
-void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs)
-{
- smp_message_recv(cpl-OPENPIC_VEC_IPI, regs);
-}
-#endif /* CONFIG_SMP */
-
-#ifdef __i386__
-static inline u_int in_le32(volatile u_int *addr)
-{
- return *addr;
-}
-
-static inline void out_le32(volatile u_int *addr, u_int val)
-{
- *addr = val;
-}
+#ifdef CONFIG_POWER3
+ #define GET_ISU(source) ISU[(source) >> 4][(source) & 0xf]
+#else
+ #define GET_ISU(source) ISU[0][(source)]
#endif
u_int openpic_read(volatile u_int *addr)
@@ -156,22 +170,66 @@ static void openpic_safe_writefield(volatile u_int *addr, u_int mask,
u_int field)
{
openpic_setfield(addr, OPENPIC_MASK);
- /* wait until it's not in use */
- /* BenH: Is this code really enough ? I would rather check the result
- * and eventually retry ...
- */
while (openpic_read(addr) & OPENPIC_ACTIVITY);
openpic_writefield(addr, mask | OPENPIC_MASK, field | OPENPIC_MASK);
}
-void __init openpic_init(int main_pic)
+#ifdef CONFIG_SMP
+/* yes this is right ... bug, feature, you decide! -- tgall */
+u_int openpic_read_IPI(volatile u_int* addr)
+{
+ u_int val = 0;
+#ifdef CONFIG_POWER3
+ val = in_be32(addr);
+#else
+ val = in_le32(addr);
+#endif
+ return val;
+}
+
+/* because of the power3 be / le above, this is needed */
+inline void openpic_writefield_IPI(volatile u_int* addr, u_int mask, u_int field)
+{
+ u_int val = openpic_read_IPI(addr);
+ openpic_write(addr, (val & ~mask) | (field & mask));
+}
+
+static inline void openpic_clearfield_IPI(volatile u_int *addr, u_int mask)
+{
+ openpic_writefield_IPI(addr, mask, 0);
+}
+
+static inline void openpic_setfield_IPI(volatile u_int *addr, u_int mask)
+{
+ openpic_writefield_IPI(addr, mask, mask);
+}
+
+static void openpic_safe_writefield_IPI(volatile u_int *addr, u_int mask, u_int field)
+{
+ openpic_setfield_IPI(addr, OPENPIC_MASK);
+
+ /* wait until it's not in use */
+ /* BenH: Is this code really enough ? I would rather check the result
+ * and eventually retry ...
+ */
+ while(openpic_read_IPI(addr) & OPENPIC_ACTIVITY);
+
+ openpic_writefield_IPI(addr, mask | OPENPIC_MASK, field | OPENPIC_MASK);
+}
+#endif /* CONFIG_SMP */
+
+void __init openpic_init(int main_pic, int offset, unsigned char* chrp_ack,
+ int programmer_switch_irq)
{
u_int t, i;
u_int timerfreq;
const char *version;
- if (!OpenPIC)
- panic("No OpenPIC found");
+ if (!OpenPIC_Addr) {
+ printk("No OpenPIC found !\n");
+ return;
+ }
+ OpenPIC = (volatile struct OpenPIC *)OpenPIC_Addr;
if ( ppc_md.progress ) ppc_md.progress("openpic enter",0x122);
@@ -194,179 +252,180 @@ void __init openpic_init(int main_pic)
OPENPIC_FEATURE_LAST_PROCESSOR_SHIFT) + 1;
NumSources = ((t & OPENPIC_FEATURE_LAST_SOURCE_MASK) >>
OPENPIC_FEATURE_LAST_SOURCE_SHIFT) + 1;
- if ( _machine != _MACH_Pmac )
- {
- printk("OpenPIC Version %s (%d CPUs and %d IRQ sources) at %p\n", version,
- NumProcessors, NumSources, OpenPIC);
- timerfreq = openpic_read(&OpenPIC->Global.Timer_Frequency);
- printk("OpenPIC timer frequency is ");
- if (timerfreq)
- printk("%d MHz\n", timerfreq>>20);
- else
- printk("not set\n");
+ printk("OpenPIC Version %s (%d CPUs and %d IRQ sources) at %p\n",
+ version, NumProcessors, NumSources, OpenPIC);
+ timerfreq = openpic_read(&OpenPIC->Global.Timer_Frequency);
+ if (timerfreq)
+ printk("OpenPIC timer frequency is %d.%06d MHz\n",
+ timerfreq / 1000000, timerfreq % 1000000);
+
+ if (!main_pic)
+ return;
+
+ open_pic_irq_offset = offset;
+ chrp_int_ack_special = (volatile unsigned char*)chrp_ack;
+
+ /* Initialize timer interrupts */
+ if ( ppc_md.progress ) ppc_md.progress("openpic timer",0x3ba);
+ for (i = 0; i < OPENPIC_NUM_TIMERS; i++) {
+ /* Disabled, Priority 0 */
+ openpic_inittimer(i, 0, OPENPIC_VEC_TIMER+i+offset);
+ /* No processor */
+ openpic_maptimer(i, 0);
}
-
- if ( main_pic )
- {
- /* Initialize timer interrupts */
- if ( ppc_md.progress ) ppc_md.progress("openpic timer",0x3ba);
- for (i = 0; i < OPENPIC_NUM_TIMERS; i++) {
- /* Disabled, Priority 0 */
- openpic_inittimer(i, 0, OPENPIC_VEC_TIMER+i);
- /* No processor */
- openpic_maptimer(i, 0);
- }
-
- /* Initialize IPI interrupts */
- if ( ppc_md.progress ) ppc_md.progress("openpic ipi",0x3bb);
- for (i = 0; i < OPENPIC_NUM_IPI; i++) {
- /* Disabled, Priority 8 */
- openpic_initipi(i, 8, OPENPIC_VEC_IPI+i);
- }
- find_ISUs();
- if ( _machine != _MACH_Pmac )
- {
- /* Initialize external interrupts */
- if ( ppc_md.progress ) ppc_md.progress("openpic ext",0x3bc);
- /* SIOint (8259 cascade) is special */
- openpic_initirq(0, 8, open_pic_irq_offset, 1, 1);
- openpic_mapirq(0, 1<<0);
- for (i = 1; i < NumSources; i++) {
- /* Enabled, Priority 8 */
- openpic_initirq(i, 8, open_pic_irq_offset+i, 0,
- i < OpenPIC_NumInitSenses ? OpenPIC_InitSenses[i] : 1);
- /* Processor 0 */
- openpic_mapirq(i, 1<<0);
- }
- }
- else
- {
- /* Prevent any interrupt from occuring during initialisation.
- * Hum... I believe this is not necessary, Apple does that in
- * Darwin's PowerExpress code.
- */
- openpic_set_priority(0, 0xf);
-
- /* First disable all interrupts and map them to CPU 0 */
- for (i = 0; i < NumSources; i++) {
- openpic_disable_irq(i);
- openpic_mapirq(i, 1<<0);
- }
-
- /* If we use the device tree, then lookup all interrupts and
- * initialize them according to sense infos found in the tree
- */
- if (use_of_interrupt_tree) {
- struct device_node* np = find_all_nodes();
- while(np) {
- int j, pri;
- pri = strcmp(np->name, "programmer-switch") ? 2 : 7;
- for (j=0;j<np->n_intrs;j++) {
- openpic_initirq(np->intrs[j].line,
- pri,
- np->intrs[j].line,
- 0,
- np->intrs[j].sense);
- if (np->intrs[j].sense)
- irq_desc[np->intrs[j].line].status = IRQ_LEVEL;
- }
- np = np->next;
- }
- }
- }
-
- /* Initialize the spurious interrupt */
- if ( ppc_md.progress ) ppc_md.progress("openpic spurious",0x3bd);
- openpic_set_spurious(OPENPIC_VEC_SPURIOUS);
- if ( !(_machine & (_MACH_gemini|_MACH_Pmac)) )
- {
- if (request_irq(IRQ_8259_CASCADE, no_action, SA_INTERRUPT,
- "82c59 cascade", NULL))
- printk("Unable to get OpenPIC IRQ 0 for cascade\n");
- }
- openpic_set_priority(0, 0);
- openpic_disable_8259_pass_through();
+
+#ifdef CONFIG_SMP
+ /* Initialize IPI interrupts */
+ if ( ppc_md.progress ) ppc_md.progress("openpic ipi",0x3bb);
+ for (i = 0; i < OPENPIC_NUM_IPI; i++) {
+ /* Disabled, Priority 10..13 */
+ openpic_initipi(i, 10+i, OPENPIC_VEC_IPI+i+offset);
+ /* IPIs are per-CPU */
+ irq_desc[OPENPIC_VEC_IPI+i+offset].status |= IRQ_PER_CPU;
+ irq_desc[OPENPIC_VEC_IPI+i+offset].handler = &open_pic_ipi;
+ }
+#endif
+
+ find_ISUs();
+
+ /* Initialize external interrupts */
+ if (ppc_md.progress) ppc_md.progress("openpic ext",0x3bc);
+
+ openpic_set_priority(0xf);
+
+ /* SIOint (8259 cascade) is special */
+ if (offset) {
+ openpic_initirq(0, 8, offset, 1, 1);
+ openpic_mapirq(0, 1<<0);
+ }
+
+ /* Init all external sources */
+ for (i = 1; i < NumSources; i++) {
+ int pri, sense;
+
+ /* the bootloader may have left it enabled (bad !) */
+ openpic_disable_irq(i+offset);
+
+ pri = (i == programmer_switch_irq)? 9: 8;
+ sense = (i < OpenPIC_NumInitSenses)? OpenPIC_InitSenses[i]: 1;
+ if (sense)
+ irq_desc[i+offset].status = IRQ_LEVEL;
+
+ /* Enabled, Priority 8 or 9 */
+ openpic_initirq(i, pri, i+offset, !sense, sense);
+ /* Processor 0 */
+ openpic_mapirq(i, 1<<0);
}
- if ( ppc_md.progress ) ppc_md.progress("openpic exit",0x222);
+
+ /* Init descriptors */
+ for (i = offset; i < NumSources + offset; i++)
+ irq_desc[i].handler = &open_pic;
+
+ /* Initialize the spurious interrupt */
+ if (ppc_md.progress) ppc_md.progress("openpic spurious",0x3bd);
+ openpic_set_spurious(OPENPIC_VEC_SPURIOUS+offset);
+
+ /* Initialize the cascade */
+ if (offset) {
+ if (request_irq(offset, no_action, SA_INTERRUPT,
+ "82c59 cascade", NULL))
+ printk("Unable to get OpenPIC IRQ 0 for cascade\n");
+ }
+ openpic_set_priority(0);
+ openpic_disable_8259_pass_through();
+
+ if (ppc_md.progress) ppc_md.progress("openpic exit",0x222);
+}
+
+#ifdef CONFIG_POWER3
+void openpic_setup_ISU(int isu_num, unsigned long addr)
+{
+ if (isu_num >= OPENPIC_MAX_ISU)
+ return;
+ ISU[isu_num] = (OpenPIC_SourcePtr) ioremap(addr, 0x400);
+ if (isu_num >= NumISUs)
+ NumISUs = isu_num + 1;
}
+#endif
void find_ISUs(void)
{
-#ifdef CONFIG_PPC64BRIDGE
- /* hardcode this for now since the IBM 260 is the only thing with
- * a distributed openpic right now. -- Cort
+#ifdef CONFIG_POWER3
+ /* Use /interrupt-controller/reg and
+ * /interrupt-controller/interrupt-ranges from OF device tree
+ * the ISU array is setup in chrp_pci.c in ibm_add_bridges
+ * as a result
+ * -- tgall
+ */
+
+ /* basically each ISU is a bus, and this assumes that
+ * open_pic_isu_count interrupts per bus are possible
+ * ISU == Interrupt Source
*/
- ISU = (OpenPIC_Source *)0xfeff7c00;
- NumSources = 0x10;
+ NumSources = NumISUs * 0x10;
+
#else
/* for non-distributed OpenPIC implementations it's in the IDU -- Cort */
- ISU = (OpenPIC_Source *)OpenPIC->Source;
+ ISU[0] = (OpenPIC_Source *)OpenPIC->Source;
#endif
}
-void openpic_reset(void)
+static inline void openpic_reset(void)
{
openpic_setfield(&OpenPIC->Global.Global_Configuration0,
OPENPIC_CONFIG_RESET);
}
-void openpic_enable_8259_pass_through(void)
+static inline void openpic_enable_8259_pass_through(void)
{
openpic_clearfield(&OpenPIC->Global.Global_Configuration0,
OPENPIC_CONFIG_8259_PASSTHROUGH_DISABLE);
}
-void openpic_disable_8259_pass_through(void)
+static void openpic_disable_8259_pass_through(void)
{
openpic_setfield(&OpenPIC->Global.Global_Configuration0,
OPENPIC_CONFIG_8259_PASSTHROUGH_DISABLE);
}
-#ifndef __i386__
/*
* Find out the current interrupt
*/
-u_int openpic_irq(u_int cpu)
+static u_int openpic_irq(void)
{
u_int vec;
+ DECL_THIS_CPU;
- check_arg_cpu(cpu);
+ CHECK_THIS_CPU;
vec = openpic_readfield(&OpenPIC->THIS_CPU.Interrupt_Acknowledge,
OPENPIC_VECTOR_MASK);
return vec;
}
-#endif
-#ifndef __powerpc__
-void openpic_eoi(void)
-#else
-void openpic_eoi(u_int cpu)
-#endif
+static void openpic_eoi(void)
{
- check_arg_cpu(cpu);
+ DECL_THIS_CPU;
+
+ CHECK_THIS_CPU;
openpic_write(&OpenPIC->THIS_CPU.EOI, 0);
/* Handle PCI write posting */
(void)openpic_read(&OpenPIC->THIS_CPU.EOI);
}
-#ifndef __powerpc__
-u_int openpic_get_priority(void)
-#else
-u_int openpic_get_priority(u_int cpu)
-#endif
+static inline u_int openpic_get_priority(void)
{
+ DECL_THIS_CPU;
+
CHECK_THIS_CPU;
return openpic_readfield(&OpenPIC->THIS_CPU.Current_Task_Priority,
OPENPIC_CURRENT_TASK_PRIORITY_MASK);
}
-#ifndef __powerpc__
-void openpic_set_priority(u_int pri)
-#else
-void openpic_set_priority(u_int cpu, u_int pri)
-#endif
+static void openpic_set_priority(u_int pri)
{
+ DECL_THIS_CPU;
+
CHECK_THIS_CPU;
check_arg_pri(pri);
openpic_writefield(&OpenPIC->THIS_CPU.Current_Task_Priority,
@@ -376,24 +435,43 @@ void openpic_set_priority(u_int cpu, u_int pri)
/*
* Get/set the spurious vector
*/
-u_int openpic_get_spurious(void)
+static inline u_int openpic_get_spurious(void)
{
return openpic_readfield(&OpenPIC->Global.Spurious_Vector,
OPENPIC_VECTOR_MASK);
}
-void openpic_set_spurious(u_int vec)
+static void openpic_set_spurious(u_int vec)
{
check_arg_vec(vec);
openpic_writefield(&OpenPIC->Global.Spurious_Vector, OPENPIC_VECTOR_MASK,
vec);
}
+#ifdef CONFIG_SMP
+/*
+ * Convert a cpu mask from logical to physical cpu numbers.
+ */
+static inline u32 physmask(u32 cpumask)
+{
+ int i;
+ u32 mask = 0;
+
+ for (i = 0; i < smp_num_cpus; ++i, cpumask >>= 1)
+ mask |= (cpumask & 1) << smp_hw_index[i];
+ return mask;
+}
+#else
+#define physmask(cpumask) (cpumask)
+#endif
+
void openpic_init_processor(u_int cpumask)
{
- openpic_write(&OpenPIC->Global.Processor_Initialization, cpumask);
+ openpic_write(&OpenPIC->Global.Processor_Initialization,
+ physmask(cpumask));
}
+#ifdef CONFIG_SMP
/*
* Initialize an interprocessor interrupt (and disable it)
*
@@ -401,35 +479,55 @@ void openpic_init_processor(u_int cpumask)
* pri: interrupt source priority
* vec: the vector it will produce
*/
-void openpic_initipi(u_int ipi, u_int pri, u_int vec)
+static void __init openpic_initipi(u_int ipi, u_int pri, u_int vec)
{
- check_arg_timer(ipi);
+ check_arg_ipi(ipi);
check_arg_pri(pri);
check_arg_vec(vec);
- openpic_safe_writefield(&OpenPIC->Global.IPI_Vector_Priority(ipi),
+ openpic_safe_writefield_IPI(&OpenPIC->Global.IPI_Vector_Priority(ipi),
OPENPIC_PRIORITY_MASK | OPENPIC_VECTOR_MASK,
(pri << OPENPIC_PRIORITY_SHIFT) | vec);
}
/*
* Send an IPI to one or more CPUs
+ *
+ * Externally called, however, it takes an IPI number (0...OPENPIC_NUM_IPI)
+ * and not a system-wide interrupt number
*/
-#ifndef __powerpc__
void openpic_cause_IPI(u_int ipi, u_int cpumask)
-#else
-void openpic_cause_IPI(u_int cpu, u_int ipi, u_int cpumask)
-#endif
{
+ DECL_THIS_CPU;
+
CHECK_THIS_CPU;
check_arg_ipi(ipi);
- openpic_write(&OpenPIC->THIS_CPU.IPI_Dispatch(ipi), cpumask);
+ openpic_write(&OpenPIC->THIS_CPU.IPI_Dispatch(ipi),
+ physmask(cpumask));
}
-void openpic_enable_IPI(u_int ipi)
+void openpic_request_IPIs(void)
{
- check_arg_ipi(ipi);
- openpic_clearfield(&OpenPIC->Global.IPI_Vector_Priority(ipi),
- OPENPIC_MASK);
+ int i;
+
+ /*
+ * Make sure this matches what is defined in smp.c for
+ * smp_message_{pass|recv}() or what shows up in
+ * /proc/interrupts will be wrong!!! --Troy */
+
+ if (OpenPIC == NULL)
+ return;
+
+ request_irq(OPENPIC_VEC_IPI+open_pic_irq_offset,
+ openpic_ipi_action, 0, "IPI0 (call function)", 0);
+ request_irq(OPENPIC_VEC_IPI+open_pic_irq_offset+1,
+ openpic_ipi_action, 0, "IPI1 (reschedule)", 0);
+ request_irq(OPENPIC_VEC_IPI+open_pic_irq_offset+2,
+ openpic_ipi_action, 0, "IPI2 (invalidate tlb)", 0);
+ request_irq(OPENPIC_VEC_IPI+open_pic_irq_offset+3,
+ openpic_ipi_action, 0, "IPI3 (xmon break)", 0);
+
+ for ( i = 0; i < OPENPIC_NUM_IPI ; i++ )
+ openpic_enable_ipi(OPENPIC_VEC_IPI+open_pic_irq_offset+i);
}
/*
@@ -437,21 +535,31 @@ void openpic_enable_IPI(u_int ipi)
*
* Get IPI's working and start taking interrupts.
* -- Cort
- */
-void do_openpic_setup_cpu(void)
+ */
+static spinlock_t openpic_setup_lock __initdata = SPIN_LOCK_UNLOCKED;
+
+void __init do_openpic_setup_cpu(void)
{
int i;
-
- for ( i = 0; i < OPENPIC_NUM_IPI ; i++ )
- openpic_enable_IPI(i);
-#if 0
- /* let the openpic know we want intrs */
- for ( i = 0; i < NumSources ; i++ )
- openpic_mapirq(i, openpic_read(ISU[i].Destination)
- | (1<<smp_processor_id()) );
-#endif
- openpic_set_priority(smp_processor_id(), 0);
+ u32 msk = 1 << smp_hw_index[smp_processor_id()];
+
+ spin_lock(&openpic_setup_lock);
+
+#ifdef CONFIG_IRQ_ALL_CPUS
+ /* let the openpic know we want intrs. default affinity
+ * is 0xffffffff until changed via /proc
+ * That's how it's done on x86. If we want it differently, then
+ * we should make sure we also change the default values of irq_affinity
+ * in irq.c.
+ */
+ for (i = 0; i < NumSources ; i++)
+ openpic_mapirq(i, openpic_read(&GET_ISU(i).Destination) | msk);
+#endif /* CONFIG_IRQ_ALL_CPUS */
+ openpic_set_priority(0);
+
+ spin_unlock(&openpic_setup_lock);
}
+#endif /* CONFIG_SMP */
/*
* Initialize a timer interrupt (and disable it)
@@ -460,7 +568,7 @@ void do_openpic_setup_cpu(void)
* pri: interrupt source priority
* vec: the vector it will produce
*/
-void openpic_inittimer(u_int timer, u_int pri, u_int vec)
+static void __init openpic_inittimer(u_int timer, u_int pri, u_int vec)
{
check_arg_timer(timer);
check_arg_pri(pri);
@@ -473,37 +581,99 @@ void openpic_inittimer(u_int timer, u_int pri, u_int vec)
/*
* Map a timer interrupt to one or more CPUs
*/
-void openpic_maptimer(u_int timer, u_int cpumask)
+static void __init openpic_maptimer(u_int timer, u_int cpumask)
{
check_arg_timer(timer);
- openpic_write(&OpenPIC->Global.Timer[timer].Destination, cpumask);
+ openpic_write(&OpenPIC->Global.Timer[timer].Destination,
+ physmask(cpumask));
}
+
+/*
+ *
+ * All functions below take an offset'ed irq argument
+ *
+ */
+
+
/*
- * Enable/disable an interrupt source
+ * Enable/disable an external interrupt source
+ *
+ * Externally called, irq is an offseted system-wide interrupt number
*/
-void openpic_enable_irq(u_int irq)
+static void openpic_enable_irq(u_int irq)
{
check_arg_irq(irq);
- openpic_clearfield(&ISU[irq - open_pic_irq_offset].Vector_Priority, OPENPIC_MASK);
+
+ /*
+ * Never want to disable a timer or ipi irq
+ * (only want to disable irqs within an ISU).
+ */
+ if (((irq >= OPENPIC_VEC_IPI+open_pic_irq_offset) &&
+ (irq < OPENPIC_VEC_IPI+open_pic_irq_offset+OPENPIC_NUM_IPI)) ||
+ ((irq >= OPENPIC_VEC_TIMER+open_pic_irq_offset) &&
+ (irq < OPENPIC_VEC_TIMER+open_pic_irq_offset+OPENPIC_NUM_TIMERS)))
+ {
+ /* silently ignore the enable of the timer or ipi irq. */
+ return;
+ }
+
+
+ openpic_clearfield(&GET_ISU(irq - open_pic_irq_offset).Vector_Priority, OPENPIC_MASK);
/* make sure mask gets to controller before we return to user */
do {
mb(); /* sync is probably useless here */
- } while(openpic_readfield(&ISU[irq - open_pic_irq_offset].Vector_Priority,
+ } while(openpic_readfield(&GET_ISU(irq - open_pic_irq_offset).Vector_Priority,
OPENPIC_MASK));
}
-void openpic_disable_irq(u_int irq)
+static void openpic_disable_irq(u_int irq)
{
+ u32 vp;
+
check_arg_irq(irq);
- openpic_setfield(&ISU[irq - open_pic_irq_offset].Vector_Priority, OPENPIC_MASK);
+ /*
+ * Never want to disable a timer or ipi irq
+ * (only want to disable irqs within an ISU).
+ */
+ if (((irq >= OPENPIC_VEC_IPI+open_pic_irq_offset) &&
+ (irq < OPENPIC_VEC_IPI+open_pic_irq_offset+OPENPIC_NUM_IPI)) ||
+ ((irq >= OPENPIC_VEC_TIMER+open_pic_irq_offset) &&
+ (irq < OPENPIC_VEC_TIMER+open_pic_irq_offset+OPENPIC_NUM_TIMERS)))
+ {
+ panic("openpic_disable_irq - disabling non-ISU irq");
+ }
+
+
+ openpic_setfield(&GET_ISU(irq - open_pic_irq_offset).Vector_Priority, OPENPIC_MASK);
/* make sure mask gets to controller before we return to user */
do {
mb(); /* sync is probably useless here */
- } while(!openpic_readfield(&ISU[irq - open_pic_irq_offset].Vector_Priority,
- OPENPIC_MASK));
+ vp = openpic_readfield(&GET_ISU(irq - open_pic_irq_offset).Vector_Priority,
+ OPENPIC_MASK | OPENPIC_ACTIVITY);
+ } while((vp & OPENPIC_ACTIVITY) && !(vp & OPENPIC_MASK));
}
+#ifdef CONFIG_SMP
+/*
+ * Enable/disable an IPI interrupt source
+ *
+ * Externally called, irq is an offseted system-wide interrupt number
+ */
+void openpic_enable_ipi(u_int irq)
+{
+ irq -= (OPENPIC_VEC_IPI+open_pic_irq_offset);
+ check_arg_ipi(irq);
+ openpic_clearfield_IPI(&OpenPIC->Global.IPI_Vector_Priority(irq), OPENPIC_MASK);
+
+}
+void openpic_disable_ipi(u_int irq)
+{
+ /* NEVER disable an IPI... that's just plain wrong! */
+}
+
+#endif
+
/*
* Initialize an interrupt source (and disable it!)
*
@@ -513,12 +683,9 @@ void openpic_disable_irq(u_int irq)
* pol: polarity (1 for positive, 0 for negative)
* sense: 1 for level, 0 for edge
*/
-void openpic_initirq(u_int irq, u_int pri, u_int vec, int pol, int sense)
+static void openpic_initirq(u_int irq, u_int pri, u_int vec, int pol, int sense)
{
- check_arg_irq(irq);
- check_arg_pri(pri);
- check_arg_vec(vec);
- openpic_safe_writefield(&ISU[irq].Vector_Priority,
+ openpic_safe_writefield(&GET_ISU(irq).Vector_Priority,
OPENPIC_PRIORITY_MASK | OPENPIC_VECTOR_MASK |
OPENPIC_SENSE_MASK | OPENPIC_POLARITY_MASK,
(pri << OPENPIC_PRIORITY_SHIFT) | vec |
@@ -530,10 +697,9 @@ void openpic_initirq(u_int irq, u_int pri, u_int vec, int pol, int sense)
/*
* Map an interrupt source to one or more CPUs
*/
-void openpic_mapirq(u_int irq, u_int cpumask)
+static void openpic_mapirq(u_int irq, u_int physmask)
{
- check_arg_irq(irq);
- openpic_write(&ISU[irq].Destination, cpumask);
+ openpic_write(&GET_ISU(irq).Destination, physmask);
}
/*
@@ -541,10 +707,92 @@ void openpic_mapirq(u_int irq, u_int cpumask)
*
* sense: 1 for level, 0 for edge
*/
-void openpic_set_sense(u_int irq, int sense)
+static inline void openpic_set_sense(u_int irq, int sense)
{
- check_arg_irq(irq);
- openpic_safe_writefield(&ISU[irq].Vector_Priority,
+ openpic_safe_writefield(&GET_ISU(irq).Vector_Priority,
OPENPIC_SENSE_LEVEL,
(sense ? OPENPIC_SENSE_LEVEL : 0));
}
+
+/* No spinlocks, should not be necessary with the OpenPIC
+ * (1 register = 1 interrupt and we have the desc lock).
+ */
+static void openpic_ack_irq(unsigned int irq_nr)
+{
+#if 1 /* masking should be unnecessary, but I still get spurrious */
+ openpic_disable_irq(irq_nr);
+#endif
+ if ((irq_desc[irq_nr].status & IRQ_LEVEL) == 0)
+ openpic_eoi();
+}
+
+static void openpic_end_irq(unsigned int irq_nr)
+{
+ if ((irq_desc[irq_nr].status & IRQ_LEVEL) != 0)
+ openpic_eoi();
+
+#if 1 /* masking should be unnecessary, but I still get spurrious */
+ if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+ openpic_enable_irq(irq_nr);
+#endif
+}
+
+static void openpic_set_affinity(unsigned int irq_nr, unsigned long cpumask)
+{
+ openpic_mapirq(irq_nr - open_pic_irq_offset, physmask(cpumask));
+}
+
+#ifdef CONFIG_SMP
+static void openpic_ack_ipi(unsigned int irq_nr)
+{
+}
+
+static void openpic_end_ipi(unsigned int irq_nr)
+{
+ /* IPIs are marked IRQ_PER_CPU. This has the side effect of
+ * preventing the IRQ_PENDING/IRQ_INPROGRESS logic from
+ * applying to them. We EOI them late to avoid re-entering.
+ * however, I'm wondering if we could simply let them have the
+ * SA_INTERRUPT flag and let them execute with all interrupts OFF.
+ * This would have the side effect of either running cross-CPU
+ * functions with interrupts off, or we can re-enable them explicitely
+ * with a __sti() in smp_call_function_interrupt(), since
+ * smp_call_function() is protected by a spinlock.
+ * Or maybe we shouldn't set the IRQ_PER_CPU flag on cross-CPU
+ * function calls IPI at all but that would make a special case.
+ */
+ openpic_eoi();
+}
+
+static void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs)
+{
+ smp_message_recv(cpl-OPENPIC_VEC_IPI-open_pic_irq_offset, regs);
+}
+
+#endif /* CONFIG_SMP */
+
+/* This one may be merged with PReP and CHRP */
+int
+openpic_get_irq(struct pt_regs *regs)
+{
+ extern int i8259_irq(int cpu);
+
+ int irq = openpic_irq();
+
+ /* Management of the cascade should be moved out of here */
+ if (open_pic_irq_offset && irq == open_pic_irq_offset)
+ {
+ /*
+ * This magic address generates a PCI IACK cycle.
+ */
+ if ( chrp_int_ack_special )
+ irq = *chrp_int_ack_special;
+ else
+ irq = i8259_irq( smp_processor_id() );
+ openpic_eoi();
+ }
+ if (irq == OPENPIC_VEC_SPURIOUS + open_pic_irq_offset)
+ irq = -1;
+ return irq;
+}
+
diff --git a/arch/ppc/kernel/open_pic.h b/arch/ppc/kernel/open_pic.h
index 3e51ffba3..cf924ba3a 100644
--- a/arch/ppc/kernel/open_pic.h
+++ b/arch/ppc/kernel/open_pic.h
@@ -1,11 +1,45 @@
+/*
+ * arch/ppc/kernel/open_pic.h -- OpenPIC Interrupt Handling
+ *
+ * Copyright (C) 1997 Geert Uytterhoeven
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive
+ * for more details.
+ *
+ */
+
#ifndef _PPC_KERNEL_OPEN_PIC_H
#define _PPC_KERNEL_OPEN_PIC_H
+#include <linux/config.h>
+
+#define OPENPIC_SIZE 0x40000
+
+/* OpenPIC IRQ controller structure */
extern struct hw_interrupt_type open_pic;
-void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs);
-void openpic_enable_IPI(u_int ipi);
-void do_openpic_setup_cpu(void);
+/* OpenPIC IPI controller structure */
+#ifdef CONFIG_SMP
+extern struct hw_interrupt_type open_pic_ipi;
+#endif /* CONFIG_SMP */
+
+extern u_int OpenPIC_NumInitSenses;
+extern u_char *OpenPIC_InitSenses;
+extern void* OpenPIC_Addr;
+
+/* Exported functions */
+extern void openpic_init(int, int, unsigned char *, int);
+extern void openpic_request_IPIs(void);
+extern void do_openpic_setup_cpu(void);
+extern int openpic_get_irq(struct pt_regs *regs);
+extern void openpic_init_processor(u_int cpumask);
+extern void openpic_setup_ISU(int isu_num, unsigned long addr);
+extern void openpic_cause_IPI(u_int ipi, u_int cpumask);
-extern int open_pic_irq_offset;
+extern inline int openpic_to_irq(int irq)
+{
+ return irq += NUM_8259_INTERRUPTS;
+}
+/*extern int open_pic_irq_offset;*/
#endif /* _PPC_KERNEL_OPEN_PIC_H */
diff --git a/arch/ppc/kernel/open_pic_defs.h b/arch/ppc/kernel/open_pic_defs.h
new file mode 100644
index 000000000..fed4dd1cc
--- /dev/null
+++ b/arch/ppc/kernel/open_pic_defs.h
@@ -0,0 +1,328 @@
+/*
+ * linux/openpic.h -- OpenPIC definitions
+ *
+ * Copyright (C) 1997 Geert Uytterhoeven
+ *
+ * This file is based on the following documentation:
+ *
+ * The Open Programmable Interrupt Controller (PIC)
+ * Register Interface Specification Revision 1.2
+ *
+ * Issue Date: October 1995
+ *
+ * Issued jointly by Advanced Micro Devices and Cyrix Corporation
+ *
+ * AMD is a registered trademark of Advanced Micro Devices, Inc.
+ * Copyright (C) 1995, Advanced Micro Devices, Inc. and Cyrix, Inc.
+ * All Rights Reserved.
+ *
+ * To receive a copy of this documentation, send an email to openpic@amd.com.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _LINUX_OPENPIC_H
+#define _LINUX_OPENPIC_H
+
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+
+ /*
+ * OpenPIC supports up to 2048 interrupt sources and up to 32 processors
+ */
+
+#define OPENPIC_MAX_SOURCES 2048
+#define OPENPIC_MAX_PROCESSORS 32
+#define OPENPIC_MAX_ISU 16
+
+#define OPENPIC_NUM_TIMERS 4
+#define OPENPIC_NUM_IPI 4
+#define OPENPIC_NUM_PRI 16
+#define OPENPIC_NUM_VECTORS 256
+
+
+ /*
+ * Non-offset'ed vector numbers
+ */
+
+#define OPENPIC_VEC_TIMER 64 /* and up */
+#define OPENPIC_VEC_IPI 72 /* and up */
+#define OPENPIC_VEC_SPURIOUS 127
+
+
+ /*
+ * OpenPIC Registers are 32 bits and aligned on 128 bit boundaries
+ */
+
+typedef struct _OpenPIC_Reg {
+ u_int Reg; /* Little endian! */
+ char Pad[0xc];
+} OpenPIC_Reg;
+
+
+ /*
+ * Per Processor Registers
+ */
+
+typedef struct _OpenPIC_Processor {
+ /*
+ * Private Shadow Registers (for SLiC backwards compatibility)
+ */
+ u_int IPI0_Dispatch_Shadow; /* Write Only */
+ char Pad1[0x4];
+ u_int IPI0_Vector_Priority_Shadow; /* Read/Write */
+ char Pad2[0x34];
+ /*
+ * Interprocessor Interrupt Command Ports
+ */
+ OpenPIC_Reg _IPI_Dispatch[OPENPIC_NUM_IPI]; /* Write Only */
+ /*
+ * Current Task Priority Register
+ */
+ OpenPIC_Reg _Current_Task_Priority; /* Read/Write */
+ char Pad3[0x10];
+ /*
+ * Interrupt Acknowledge Register
+ */
+ OpenPIC_Reg _Interrupt_Acknowledge; /* Read Only */
+ /*
+ * End of Interrupt (EOI) Register
+ */
+ OpenPIC_Reg _EOI; /* Read/Write */
+ char Pad5[0xf40];
+} OpenPIC_Processor;
+
+
+ /*
+ * Timer Registers
+ */
+
+typedef struct _OpenPIC_Timer {
+ OpenPIC_Reg _Current_Count; /* Read Only */
+ OpenPIC_Reg _Base_Count; /* Read/Write */
+ OpenPIC_Reg _Vector_Priority; /* Read/Write */
+ OpenPIC_Reg _Destination; /* Read/Write */
+} OpenPIC_Timer;
+
+
+ /*
+ * Global Registers
+ */
+
+typedef struct _OpenPIC_Global {
+ /*
+ * Feature Reporting Registers
+ */
+ OpenPIC_Reg _Feature_Reporting0; /* Read Only */
+ OpenPIC_Reg _Feature_Reporting1; /* Future Expansion */
+ /*
+ * Global Configuration Registers
+ */
+ OpenPIC_Reg _Global_Configuration0; /* Read/Write */
+ OpenPIC_Reg _Global_Configuration1; /* Future Expansion */
+ /*
+ * Vendor Specific Registers
+ */
+ OpenPIC_Reg _Vendor_Specific[4];
+ /*
+ * Vendor Identification Register
+ */
+ OpenPIC_Reg _Vendor_Identification; /* Read Only */
+ /*
+ * Processor Initialization Register
+ */
+ OpenPIC_Reg _Processor_Initialization; /* Read/Write */
+ /*
+ * IPI Vector/Priority Registers
+ */
+ OpenPIC_Reg _IPI_Vector_Priority[OPENPIC_NUM_IPI]; /* Read/Write */
+ /*
+ * Spurious Vector Register
+ */
+ OpenPIC_Reg _Spurious_Vector; /* Read/Write */
+ /*
+ * Global Timer Registers
+ */
+ OpenPIC_Reg _Timer_Frequency; /* Read/Write */
+ OpenPIC_Timer Timer[OPENPIC_NUM_TIMERS];
+ char Pad1[0xee00];
+} OpenPIC_Global;
+
+
+ /*
+ * Interrupt Source Registers
+ */
+
+typedef struct _OpenPIC_Source {
+ OpenPIC_Reg _Vector_Priority; /* Read/Write */
+ OpenPIC_Reg _Destination; /* Read/Write */
+} OpenPIC_Source, *OpenPIC_SourcePtr;
+
+
+ /*
+ * OpenPIC Register Map
+ */
+
+struct OpenPIC {
+ char Pad1[0x1000];
+ /*
+ * Global Registers
+ */
+ OpenPIC_Global Global;
+ /*
+ * Interrupt Source Configuration Registers
+ */
+ OpenPIC_Source Source[OPENPIC_MAX_SOURCES];
+ /*
+ * Per Processor Registers
+ */
+ OpenPIC_Processor Processor[OPENPIC_MAX_PROCESSORS];
+};
+
+extern volatile struct OpenPIC *OpenPIC;
+
+
+ /*
+ * Current Task Priority Register
+ */
+
+#define OPENPIC_CURRENT_TASK_PRIORITY_MASK 0x0000000f
+
+ /*
+ * Who Am I Register
+ */
+
+#define OPENPIC_WHO_AM_I_ID_MASK 0x0000001f
+
+ /*
+ * Feature Reporting Register 0
+ */
+
+#define OPENPIC_FEATURE_LAST_SOURCE_MASK 0x07ff0000
+#define OPENPIC_FEATURE_LAST_SOURCE_SHIFT 16
+#define OPENPIC_FEATURE_LAST_PROCESSOR_MASK 0x00001f00
+#define OPENPIC_FEATURE_LAST_PROCESSOR_SHIFT 8
+#define OPENPIC_FEATURE_VERSION_MASK 0x000000ff
+
+ /*
+ * Global Configuration Register 0
+ */
+
+#define OPENPIC_CONFIG_RESET 0x80000000
+#define OPENPIC_CONFIG_8259_PASSTHROUGH_DISABLE 0x20000000
+#define OPENPIC_CONFIG_BASE_MASK 0x000fffff
+
+ /*
+ * Vendor Identification Register
+ */
+
+#define OPENPIC_VENDOR_ID_STEPPING_MASK 0x00ff0000
+#define OPENPIC_VENDOR_ID_STEPPING_SHIFT 16
+#define OPENPIC_VENDOR_ID_DEVICE_ID_MASK 0x0000ff00
+#define OPENPIC_VENDOR_ID_DEVICE_ID_SHIFT 8
+#define OPENPIC_VENDOR_ID_VENDOR_ID_MASK 0x000000ff
+
+ /*
+ * Vector/Priority Registers
+ */
+
+#define OPENPIC_MASK 0x80000000
+#define OPENPIC_ACTIVITY 0x40000000 /* Read Only */
+#define OPENPIC_PRIORITY_MASK 0x000f0000
+#define OPENPIC_PRIORITY_SHIFT 16
+#define OPENPIC_VECTOR_MASK 0x000000ff
+
+
+ /*
+ * Interrupt Source Registers
+ */
+
+#define OPENPIC_POLARITY_POSITIVE 0x00800000
+#define OPENPIC_POLARITY_NEGATIVE 0x00000000
+#define OPENPIC_POLARITY_MASK 0x00800000
+#define OPENPIC_SENSE_LEVEL 0x00400000
+#define OPENPIC_SENSE_EDGE 0x00000000
+#define OPENPIC_SENSE_MASK 0x00400000
+
+
+ /*
+ * Timer Registers
+ */
+
+#define OPENPIC_COUNT_MASK 0x7fffffff
+#define OPENPIC_TIMER_TOGGLE 0x80000000
+#define OPENPIC_TIMER_COUNT_INHIBIT 0x80000000
+
+
+ /*
+ * Aliases to make life simpler
+ */
+
+/* Per Processor Registers */
+#define IPI_Dispatch(i) _IPI_Dispatch[i].Reg
+#define Current_Task_Priority _Current_Task_Priority.Reg
+#define Interrupt_Acknowledge _Interrupt_Acknowledge.Reg
+#define EOI _EOI.Reg
+
+/* Global Registers */
+#define Feature_Reporting0 _Feature_Reporting0.Reg
+#define Feature_Reporting1 _Feature_Reporting1.Reg
+#define Global_Configuration0 _Global_Configuration0.Reg
+#define Global_Configuration1 _Global_Configuration1.Reg
+#define Vendor_Specific(i) _Vendor_Specific[i].Reg
+#define Vendor_Identification _Vendor_Identification.Reg
+#define Processor_Initialization _Processor_Initialization.Reg
+#define IPI_Vector_Priority(i) _IPI_Vector_Priority[i].Reg
+#define Spurious_Vector _Spurious_Vector.Reg
+#define Timer_Frequency _Timer_Frequency.Reg
+
+/* Timer Registers */
+#define Current_Count _Current_Count.Reg
+#define Base_Count _Base_Count.Reg
+#define Vector_Priority _Vector_Priority.Reg
+#define Destination _Destination.Reg
+
+/* Interrupt Source Registers */
+#define Vector_Priority _Vector_Priority.Reg
+#define Destination _Destination.Reg
+
+ /*
+ * Local (static) OpenPIC Operations
+ */
+
+
+/* Global Operations */
+static void openpic_reset(void);
+static void openpic_enable_8259_pass_through(void);
+static void openpic_disable_8259_pass_through(void);
+static u_int openpic_irq(void);
+static void openpic_eoi(void);
+static u_int openpic_get_priority(void);
+static void openpic_set_priority(u_int pri);
+static u_int openpic_get_spurious(void);
+static void openpic_set_spurious(u_int vector);
+
+#ifdef CONFIG_SMP
+/* Interprocessor Interrupts */
+static void openpic_initipi(u_int ipi, u_int pri, u_int vector);
+static void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs);
+#endif
+
+/* Timer Interrupts */
+static void openpic_inittimer(u_int timer, u_int pri, u_int vector);
+static void openpic_maptimer(u_int timer, u_int cpumask);
+
+/* Interrupt Sources */
+static void openpic_enable_irq(u_int irq);
+static void openpic_disable_irq(u_int irq);
+static void openpic_initirq(u_int irq, u_int pri, u_int vector, int polarity,
+ int is_level);
+static void openpic_mapirq(u_int irq, u_int cpumask);
+static void openpic_set_sense(u_int irq, int sense);
+
+#endif /* __KERNEL__ */
+
+#endif /* _LINUX_OPENPIC_H */
diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c
index 6d6f775f2..1e503fae4 100644
--- a/arch/ppc/kernel/pci.c
+++ b/arch/ppc/kernel/pci.c
@@ -3,15 +3,16 @@
* Common pmac/prep/chrp pci routines. -- Cort
*/
+#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/string.h>
#include <linux/init.h>
-#include <linux/openpic.h>
#include <linux/capability.h>
#include <linux/sched.h>
#include <linux/errno.h>
+#include <linux/bootmem.h>
#include <asm/processor.h>
#include <asm/io.h>
@@ -25,7 +26,7 @@
#include "pci.h"
-#undef DEBUG
+#define DEBUG
#ifdef DEBUG
#define DBG(x...) printk(x)
@@ -37,54 +38,44 @@ unsigned long isa_io_base = 0;
unsigned long isa_mem_base = 0;
unsigned long pci_dram_offset = 0;
-struct pci_fixup pcibios_fixups[] = {
- { 0 }
-};
+static u8* pci_to_OF_bus_map;
-int generic_pcibios_read_byte(struct pci_dev *dev, int where, u8 *val)
-{
- return ppc_md.pcibios_read_config_byte(dev->bus->number,dev->devfn,where,val);
-}
-int generic_pcibios_read_word(struct pci_dev *dev, int where, u16 *val)
-{
- return ppc_md.pcibios_read_config_word(dev->bus->number,dev->devfn,where,val);
-}
-int generic_pcibios_read_dword(struct pci_dev *dev, int where, u32 *val)
-{
- return ppc_md.pcibios_read_config_dword(dev->bus->number,dev->devfn,where,val);
-}
-int generic_pcibios_write_byte(struct pci_dev *dev, int where, u8 val)
-{
- return ppc_md.pcibios_write_config_byte(dev->bus->number,dev->devfn,where,val);
-}
-int generic_pcibios_write_word(struct pci_dev *dev, int where, u16 val)
-{
- return ppc_md.pcibios_write_config_word(dev->bus->number,dev->devfn,where,val);
-}
-int generic_pcibios_write_dword(struct pci_dev *dev, int where, u32 val)
-{
- return ppc_md.pcibios_write_config_dword(dev->bus->number,dev->devfn,where,val);
-}
+static void pcibios_fixup_resources(struct pci_dev* dev);
+#ifdef CONFIG_ALL_PPC
+static void pcibios_fixup_cardbus(struct pci_dev* dev);
+#endif
-struct pci_ops generic_pci_ops =
-{
- generic_pcibios_read_byte,
- generic_pcibios_read_word,
- generic_pcibios_read_dword,
- generic_pcibios_write_byte,
- generic_pcibios_write_word,
- generic_pcibios_write_dword
-};
+/* By default, we don't re-assign bus numbers. We do this only on
+ * some pmacs
+ */
+int pci_assign_all_busses;
+
+struct pci_controller* hose_head;
+struct pci_controller** hose_tail = &hose_head;
+static int pci_bus_count;
+struct pci_fixup pcibios_fixups[] = {
+ { PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources },
+#ifdef CONFIG_ALL_PPC
+ /* We should add per-machine fixup support in xxx_setup.c or xxx_pci.c */
+ { PCI_FIXUP_FINAL, PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1211, pcibios_fixup_cardbus },
+#endif /* CONFIG_ALL_PPC */
+ { 0 }
+};
-void pcibios_update_resource(struct pci_dev *dev, struct resource *root,
+void
+pcibios_update_resource(struct pci_dev *dev, struct resource *root,
struct resource *res, int resource)
{
u32 new, check;
int reg;
-
- new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
+ struct pci_controller* hose = dev->sysdata;
+
+ new = res->start;
+ if (hose && res->flags & IORESOURCE_MEM)
+ new -= hose->pci_mem_offset;
+ new |= (res->flags & PCI_REGION_FLAG_MASK);
if (resource < 6) {
reg = PCI_BASE_ADDRESS_0 + 4*resource;
} else if (resource == PCI_ROM_RESOURCE) {
@@ -104,6 +95,62 @@ void pcibios_update_resource(struct pci_dev *dev, struct resource *root,
}
}
+static void
+pcibios_fixup_resources(struct pci_dev* dev)
+{
+ struct pci_controller* hose =
+ (struct pci_controller *)dev->sysdata;
+ int i;
+ if (!hose) {
+ printk("No hose for PCI dev %x.%x !\n", dev->bus->number, dev->devfn >> 3);
+ return;
+ }
+ for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+ struct resource *res = dev->resource + i;
+ if (!res->start)
+ continue;
+ if (res->flags & IORESOURCE_MEM) {
+ res->start += hose->pci_mem_offset;
+ res->end += hose->pci_mem_offset;
+#ifdef DEBUG
+ printk("Fixup mem res, dev: %x.%x, res_start: %lx->%lx\n",
+ dev->bus->number, dev->devfn>>3, res->start-hose->pci_mem_offset,
+ res->start);
+#endif
+ }
+
+ if ((res->flags & IORESOURCE_IO)
+ && (unsigned long) hose->io_base_virt != isa_io_base) {
+ unsigned long offs = (unsigned long) hose->io_base_virt - isa_io_base;
+ res->start += offs;
+ res->end += offs;
+ printk("Fixup IO res, dev: %x.%x, res_start: %lx->%lx\n",
+ dev->bus->number, dev->devfn>>3,
+ res->start - offs, res->start);
+ }
+ }
+}
+
+#ifdef CONFIG_ALL_PPC
+static void
+pcibios_fixup_cardbus(struct pci_dev* dev)
+{
+ /*
+ * Fix the interrupt routing on the TI1211 chip on the 1999
+ * G3 powerbook, which doesn't get initialized properly by OF.
+ */
+ if (dev->vendor == PCI_VENDOR_ID_TI
+ && dev->device == PCI_DEVICE_ID_TI_1211) {
+ u32 val;
+ /* 0x8c == TI122X_IRQMUX, 2 says to route the INTA
+ signal out the MFUNC0 pin */
+ if (pci_read_config_dword(dev, 0x8c, &val) == 0
+ && val == 0)
+ pci_write_config_dword(dev, 0x8c, 2);
+ }
+}
+#endif /* CONFIG_ALL_PPC */
+
/*
* We need to avoid collisions with `mirrored' VGA ports
* and other strange ISA hardware, so we always want the
@@ -172,7 +219,8 @@ pcibios_align_resource(void *data, struct resource *res, unsigned long size)
* as well.
*/
-static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
+static void __init
+pcibios_allocate_bus_resources(struct list_head *bus_list)
{
struct list_head *ln;
struct pci_bus *bus;
@@ -197,7 +245,8 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
}
}
-static void __init pcibios_allocate_resources(int pass)
+static void __init
+pcibios_allocate_resources(int pass)
{
struct pci_dev *dev;
int idx, disabled;
@@ -250,7 +299,8 @@ static void __init pcibios_allocate_resources(int pass)
}
}
-static void __init pcibios_assign_resources(void)
+static void __init
+pcibios_assign_resources(void)
{
struct pci_dev *dev;
int idx;
@@ -278,7 +328,9 @@ static void __init pcibios_assign_resources(void)
* the BIOS forgot to do so or because we have decided the old
* address was unusable for some reason.
*/
- if (!r->start && r->end)
+ if (!r->start && r->end &&
+ (!ppc_md.pcibios_enable_device_hook ||
+ !ppc_md.pcibios_enable_device_hook(dev, 1)))
pci_assign_resource(dev, idx);
}
@@ -293,7 +345,8 @@ static void __init pcibios_assign_resources(void)
}
-int pcibios_enable_resources(struct pci_dev *dev)
+int
+pcibios_enable_resources(struct pci_dev *dev)
{
u16 cmd, old_cmd;
int idx;
@@ -321,18 +374,267 @@ int pcibios_enable_resources(struct pci_dev *dev)
return 0;
}
+struct pci_controller * __init
+pcibios_alloc_controller(void)
+{
+ struct pci_controller *hose;
+
+ hose = (struct pci_controller *)alloc_bootmem(sizeof(*hose));
+ memset(hose, 0, sizeof(struct pci_controller));
+
+ *hose_tail = hose;
+ hose_tail = &hose->next;
+
+ return hose;
+}
+static void
+make_one_node_map(struct device_node* node, u8 pci_bus)
+{
+ int *bus_range;
+ int len;
+
+ if (pci_bus >= pci_bus_count)
+ return;
+ bus_range = (int *) get_property(node, "bus-range", &len);
+ if (bus_range == NULL || len < 2 * sizeof(int)) {
+ printk(KERN_WARNING "Can't get bus-range for %s\n",
+ node->full_name);
+ return;
+ }
+ pci_to_OF_bus_map[pci_bus] = bus_range[0];
+
+ for (node=node->child; node != 0;node = node->sibling) {
+ struct pci_dev* dev;
+ unsigned int *class_code, *reg;
+
+ class_code = (unsigned int *) get_property(node, "class-code", 0);
+ 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", 0);
+ if (!reg)
+ continue;
+ dev = pci_find_slot(pci_bus, ((reg[0] >> 8) & 0xff));
+ if (!dev || !dev->subordinate)
+ continue;
+ make_one_node_map(node, dev->subordinate->number);
+ }
+}
+
+void
+pcibios_make_OF_bus_map(void)
+{
+ int i;
+ struct pci_controller* hose;
+ u8* of_prop_map;
+
+ pci_to_OF_bus_map = (u8*)kmalloc(pci_bus_count, GFP_KERNEL);
+ if (!pci_to_OF_bus_map) {
+ printk(KERN_ERR "Can't allocate OF bus map !\n");
+ return;
+ }
+
+ /* We fill the bus map with invalid values, that helps
+ * debugging.
+ */
+ for (i=0; i<pci_bus_count; i++)
+ pci_to_OF_bus_map[i] = 0xff;
+
+ /* For each hose, we begin searching bridges */
+ for(hose=hose_head; hose; hose=hose->next) {
+ struct device_node* node;
+ node = (struct device_node *)hose->arch_data;
+ if (!node)
+ continue;
+ make_one_node_map(node, hose->first_busno);
+ }
+ of_prop_map = get_property(find_path_device("/"), "pci-OF-bus-map", 0);
+ if (of_prop_map)
+ memcpy(of_prop_map, pci_to_OF_bus_map, pci_bus_count);
+#ifdef DEBUG
+ printk("PCI->OF bus map:\n");
+ for (i=0; i<pci_bus_count; i++) {
+ if (pci_to_OF_bus_map[i] == 0xff)
+ continue;
+ printk("%d -> %d\n", i, pci_to_OF_bus_map[i]);
+ }
+#endif
+}
-void __init pcibios_init(void)
+static struct device_node*
+scan_OF_childs_for_device(struct device_node* node, u8 bus, u8 dev_fn)
{
+ struct device_node* sub_node;
+
+ for (; node != 0;node = node->sibling) {
+ unsigned int *class_code, *reg;
+
+ reg = (unsigned int *) get_property(node, "reg", 0);
+ if (reg && ((reg[0] >> 8) & 0xff) == dev_fn
+ && ((reg[0] >> 16) & 0xff) == bus)
+ return node;
+
+ /* For PCI<->PCI bridges or CardBus bridges, we go down */
+ class_code = (unsigned int *) get_property(node, "class-code", 0);
+ if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
+ (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS))
+ continue;
+ sub_node = scan_OF_childs_for_device(node->child, bus, dev_fn);
+ if (sub_node)
+ return sub_node;
+ }
+ return NULL;
+}
+
+/*
+ * Scans the OF tree for a device node matching a PCI device
+ */
+struct device_node*
+pci_device_to_OF_node(struct pci_dev *dev)
+{
+ struct pci_controller *hose;
+ struct device_node *node;
+ int bus;
+
+ if (!have_of)
+ return NULL;
+
+ /* Lookup the hose */
+ bus = dev->bus->number;
+ hose = pci_bus_to_hose(bus);
+ if (!hose)
+ return NULL;
+
+ /* Check it has an OF node associated */
+ node = (struct device_node *) hose->arch_data;
+ if (!node)
+ return NULL;
+
+ /* Fixup bus number according to what OF think it is. */
+ if (pci_to_OF_bus_map)
+ bus = pci_to_OF_bus_map[bus];
+ if (bus == 0xff)
+ return NULL;
+
+ /* Now, lookup childs of the hose */
+ return scan_OF_childs_for_device(node->child, bus, dev->devfn);
+}
+
+/* This routine is meant to be used early during boot, when the
+ * PCI bus numbers have not yet been assigned, and you need to
+ * issue PCI config cycles to an OF device.
+ * It could also be used to "fix" RTAS config cycles if you want
+ * to set pci_assign_all_busses to 1 and still use RTAS for PCI
+ * config cycles.
+ */
+struct pci_controller*
+pci_find_hose_for_OF_device(struct device_node* node)
+{
+ if (!have_of)
+ return NULL;
+ while(node) {
+ struct pci_controller* hose;
+ for (hose=hose_head;hose;hose=hose->next)
+ if (hose->arch_data == node)
+ return hose;
+ node=node->parent;
+ }
+ return NULL;
+}
+
+/*
+ * Returns the PCI device matching a given OF node
+ */
+int
+pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn)
+{
+ unsigned int *reg;
+ int i;
+
+ if (!have_of)
+ return -ENODEV;
+ reg = (unsigned int *) get_property(node, "reg", 0);
+ if (!reg)
+ return -ENODEV;
+ *bus = (reg[0] >> 16) & 0xff;
+ for (i=0; pci_to_OF_bus_map && i<pci_bus_count; i++)
+ if (pci_to_OF_bus_map[i] == *bus) {
+ *bus = i;
+ break;
+ }
+ *devfn = ((reg[0] >> 8) & 0xff);
+ return 0;
+}
+
+void __init
+pcibios_init(void)
+{
+ struct pci_controller *hose;
+ struct pci_bus *bus;
+ int next_busno;
+
printk("PCI: Probing PCI hardware\n");
- pci_scan_bus(0, &generic_pci_ops, NULL);
+
+ /* Scan all of the recorded PCI controllers. */
+ for (next_busno = 0, hose = hose_head; hose; hose = hose->next) {
+ if (pci_assign_all_busses)
+ hose->first_busno = next_busno;
+ hose->last_busno = 0xff;
+ bus = pci_scan_bus(hose->first_busno, hose->ops, hose);
+ hose->bus = bus;
+ hose->last_busno = bus->subordinate;
+ if (pci_assign_all_busses || next_busno <= hose->last_busno)
+ next_busno = hose->last_busno+1;
+ }
+ pci_bus_count = next_busno;
+
+ /* OpenFirmware based machines need a map of OF bus
+ * numbers vs. kernel bus numbers since we may have to
+ * remap them.
+ */
+ if (pci_assign_all_busses && have_of)
+ pcibios_make_OF_bus_map();
+
+ /* Call machine dependant fixup */
if (ppc_md.pcibios_fixup)
ppc_md.pcibios_fixup();
+
+ /* Allocate and assign resources */
pcibios_allocate_bus_resources(&pci_root_buses);
pcibios_allocate_resources(0);
pcibios_allocate_resources(1);
pcibios_assign_resources();
+
+#ifdef CONFIG_BLK_DEV_IDE
+ /* OF fails to initialize IDE controllers on macs
+ * (and maybe other machines)
+ *
+ * This late fixup is done here since I want it to happen after
+ * resource assignement, and there's no "late-init" arch hook
+ *
+ * Ideally, this should be moved to the IDE layer, but we need
+ * to check specifically with Andre Hedrick how to do it cleanly
+ * since the common IDE code seem to care about the fact that the
+ * BIOS may have disabled a controller.
+ *
+ * -- BenH
+ */
+ if (_machine == _MACH_Pmac) {
+ struct pci_dev *dev;
+ pci_for_each_dev(dev)
+ {
+ if ((dev->class >> 16) == PCI_BASE_CLASS_STORAGE)
+ pci_enable_device(dev);
+ }
+ }
+#endif /* CONFIG_BLK_DEV_IDE */
+}
+
+int __init
+pcibios_assign_all_busses(void)
+{
+ return pci_assign_all_busses;
}
void __init
@@ -344,9 +646,16 @@ pcibios_fixup_pbus_ranges(struct pci_bus * bus, struct pbus_set_ranges_data * ra
ranges->mem_end -= bus->resource[1]->start;
}
+unsigned long resource_fixup(struct pci_dev * dev, struct resource * res,
+ unsigned long start, unsigned long size)
+{
+ return start;
+}
void __init pcibios_fixup_bus(struct pci_bus *bus)
{
+ pci_read_bridge_bases(bus);
+
if ( ppc_md.pcibios_fixup_bus )
ppc_md.pcibios_fixup_bus(bus);
}
@@ -370,6 +679,10 @@ int pcibios_enable_device(struct pci_dev *dev)
int idx;
struct resource *r;
+ if (ppc_md.pcibios_enable_device_hook)
+ if (ppc_md.pcibios_enable_device_hook(dev, 0))
+ return -EINVAL;
+
pci_read_config_word(dev, PCI_COMMAND, &cmd);
old_cmd = cmd;
for (idx=0; idx<6; idx++) {
@@ -391,37 +704,99 @@ int pcibios_enable_device(struct pci_dev *dev)
return 0;
}
-void *
-pci_dev_io_base(unsigned char bus, unsigned char devfn, int physical)
+struct pci_controller*
+pci_bus_to_hose(int bus)
{
- if (!ppc_md.pci_dev_io_base) {
- /* Please, someone fix this for non-pmac machines, we
- * need either the virtual or physical PCI IO base
- */
- return 0;
- }
- return ppc_md.pci_dev_io_base(bus, devfn, physical);
+ struct pci_controller* hose = hose_head;
+
+ for (; hose; hose = hose->next)
+ if (bus >= hose->first_busno && bus <= hose->last_busno)
+ return hose;
+ return NULL;
}
-void *
-pci_dev_mem_base(unsigned char bus, unsigned char devfn)
+void*
+pci_bus_io_base(unsigned int bus)
{
- /* Default memory base is 0 (1:1 mapping) */
- if (!ppc_md.pci_dev_mem_base) {
- /* Please, someone fix this for non-pmac machines.*/
+ struct pci_controller *hose;
+
+ hose = pci_bus_to_hose(bus);
+ if (!hose)
+ return NULL;
+ return hose->io_base_virt;
+}
+
+unsigned long
+pci_bus_io_base_phys(unsigned int bus)
+{
+ struct pci_controller *hose;
+
+ hose = pci_bus_to_hose(bus);
+ if (!hose)
return 0;
- }
- return ppc_md.pci_dev_mem_base(bus, devfn);
+ return hose->io_base_phys;
}
-/* Returns the root-bridge number (Uni-N number) of a device */
-int
-pci_dev_root_bridge(unsigned char bus, unsigned char devfn)
+unsigned long
+pci_bus_mem_base_phys(unsigned int bus)
{
- /* Defaults to 0 */
- if (!ppc_md.pci_dev_root_bridge)
+ struct pci_controller *hose;
+
+ hose = pci_bus_to_hose(bus);
+ if (!hose)
return 0;
- return ppc_md.pci_dev_root_bridge(bus, devfn);
+ return hose->pci_mem_offset;
+}
+
+#ifdef CONFIG_POWER4
+extern unsigned long pci_address_offset(int, unsigned int);
+#endif /* CONFIG_POWER4 */
+
+unsigned long
+pci_resource_to_bus(struct pci_dev *pdev, struct resource *res)
+{
+ /* Hack alert again ! See comments in chrp_pci.c
+ */
+#ifdef CONFIG_POWER4
+ unsigned long offset = pci_address_offset(pdev->bus->number, res->flags);
+ return res->start - offset;
+#else /* CONFIG_POWER4 */
+ struct pci_controller* hose =
+ (struct pci_controller *)pdev->sysdata;
+ if (hose && res->flags & IORESOURCE_MEM)
+ return res->start - hose->pci_mem_offset;
+ /* We may want to do something with IOs here... */
+ return res->start;
+#endif
+}
+
+/* Obsolete functions. Should be removed once the symbios driver
+ * is fixed
+ */
+unsigned long
+pci_phys_to_bus(unsigned long pa, int busnr)
+{
+#ifdef CONFIG_POWER4
+ return pa - pci_address_offset(busnr, IORESOURCE_MEM);
+#else /* CONFIG_POWER4 */
+ struct pci_controller* hose = pci_bus_to_hose(busnr);
+ if (!hose)
+ return pa;
+ return pa - hose->pci_mem_offset;
+#endif
+}
+
+unsigned long
+pci_bus_to_phys(unsigned int ba, int busnr)
+{
+#ifdef CONFIG_POWER4
+ return ba + pci_address_offset(dev->bus->number, IORESOURCE_MEM);
+#else /* CONFIG_POWER4 */
+ struct pci_controller* hose = pci_bus_to_hose(busnr);
+ if (!hose)
+ return ba;
+ return ba + hose->pci_mem_offset;
+#endif
}
/* Provide information on locations of various I/O regions in physical
@@ -430,23 +805,93 @@ pci_dev_root_bridge(unsigned char bus, unsigned char devfn)
* Note that the returned IO or memory base is a physical address
*/
-asmlinkage long
+long
sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn)
{
+ struct pci_controller* hose = pci_bus_to_hose(bus);
long result = -EOPNOTSUPP;
+
+ if (!hose)
+ return -ENODEV;
switch (which) {
case IOBASE_BRIDGE_NUMBER:
- return (long)pci_dev_root_bridge(bus, devfn);
+ return (long)hose->first_busno;
case IOBASE_MEMORY:
- return (long)pci_dev_mem_base(bus, devfn);
+ return (long)hose->pci_mem_offset;
case IOBASE_IO:
- result = (long)pci_dev_io_base(bus, devfn, 1);
- if (result == 0)
- result = -EOPNOTSUPP;
- break;
+ return (long)hose->io_base_phys;
+ case IOBASE_ISA_IO:
+ return (long)isa_io_base;
+ case IOBASE_ISA_MEM:
+ return (long)isa_mem_base;
}
return result;
}
+/*
+ * Null PCI config access functions, for the case when we can't
+ * find a hose.
+ */
+#define NULL_PCI_OP(rw, size, type) \
+static int \
+null_##rw##_config_##size(struct pci_dev *dev, int offset, type val) \
+{ \
+ return PCIBIOS_DEVICE_NOT_FOUND; \
+}
+
+NULL_PCI_OP(read, byte, u8 *)
+NULL_PCI_OP(read, word, u16 *)
+NULL_PCI_OP(read, dword, u32 *)
+NULL_PCI_OP(write, byte, u8)
+NULL_PCI_OP(write, word, u16)
+NULL_PCI_OP(write, dword, u32)
+
+static struct pci_ops null_pci_ops =
+{
+ null_read_config_byte,
+ null_read_config_word,
+ null_read_config_dword,
+ null_write_config_byte,
+ null_write_config_word,
+ null_write_config_dword
+};
+
+/*
+ * These functions are used early on before PCI scanning is done
+ * and all of the pci_dev and pci_bus structures have been created.
+ */
+static struct pci_dev *
+fake_pci_dev(struct pci_controller *hose, int busnr, int devfn)
+{
+ static struct pci_dev dev;
+ static struct pci_bus bus;
+
+ if (hose == 0) {
+ hose = pci_bus_to_hose(busnr);
+ if (hose == 0)
+ printk(KERN_ERR "Can't find hose for PCI bus %d!\n", busnr);
+ }
+ dev.bus = &bus;
+ dev.sysdata = hose;
+ dev.devfn = devfn;
+ bus.number = busnr;
+ bus.ops = hose? hose->ops: &null_pci_ops;
+ return &dev;
+}
+
+#define EARLY_PCI_OP(rw, size, type) \
+int early_##rw##_config_##size(struct pci_controller *hose, int bus, \
+ int devfn, int offset, type value) \
+{ \
+ return pci_##rw##_config_##size(fake_pci_dev(hose, bus, devfn), \
+ offset, value); \
+}
+
+EARLY_PCI_OP(read, byte, u8 *)
+EARLY_PCI_OP(read, word, u16 *)
+EARLY_PCI_OP(read, dword, u32 *)
+EARLY_PCI_OP(write, byte, u8)
+EARLY_PCI_OP(write, word, u16)
+EARLY_PCI_OP(write, dword, u32)
diff --git a/arch/ppc/kernel/pci.h b/arch/ppc/kernel/pci.h
index d79eb0f4a..07a64d9f3 100644
--- a/arch/ppc/kernel/pci.h
+++ b/arch/ppc/kernel/pci.h
@@ -2,47 +2,23 @@
#ifndef __PPC_KERNEL_PCI_H__
#define __PPC_KERNEL_PCI_H__
+/* Configure those in your xxx_init() or xxx_setup_arch() function */
extern unsigned long isa_io_base;
extern unsigned long isa_mem_base;
extern unsigned long pci_dram_offset;
-extern unsigned int *pci_config_address;
-extern unsigned char *pci_config_data;
+/* Set this to 1 if you want the kernel to re-assign all PCI
+ * bus numbers
+ */
+extern int pci_assign_all_busses;
-void fix_intr(struct device_node *node, struct pci_dev *dev);
-#if 0
-#define decl_config_access_method(name) \
-struct pci_ops name##_pci_ops = { \
- name##_pcibios_read_config_byte, \
- name##_pcibios_read_config_word, \
- name##_pcibios_read_config_dword, \
- name##_pcibios_write_config_byte, \
- name##_pcibios_write_config_word, \
- name##_pcibios_write_config_dword \
-}
-#endif
+extern struct pci_controller* pcibios_alloc_controller(void);
+extern struct pci_controller* pci_find_hose_for_OF_device(
+ struct device_node* node);
-#define decl_config_access_method(name) \
-extern int name##_pcibios_read_config_byte(unsigned char bus, \
- unsigned char dev_fn, unsigned char offset, unsigned char *val); \
-extern int name##_pcibios_read_config_word(unsigned char bus, \
- unsigned char dev_fn, unsigned char offset, unsigned short *val); \
-extern int name##_pcibios_read_config_dword(unsigned char bus, \
- unsigned char dev_fn, unsigned char offset, unsigned int *val); \
-extern int name##_pcibios_write_config_byte(unsigned char bus, \
- unsigned char dev_fn, unsigned char offset, unsigned char val); \
-extern int name##_pcibios_write_config_word(unsigned char bus, \
- unsigned char dev_fn, unsigned char offset, unsigned short val); \
-extern int name##_pcibios_write_config_dword(unsigned char bus, \
- unsigned char dev_fn, unsigned char offset, unsigned int val)
-
-#define set_config_access_method(name) \
- ppc_md.pcibios_read_config_byte = name##_pcibios_read_config_byte; \
- ppc_md.pcibios_read_config_word = name##_pcibios_read_config_word; \
- ppc_md.pcibios_read_config_dword = name##_pcibios_read_config_dword; \
- ppc_md.pcibios_write_config_byte = name##_pcibios_write_config_byte; \
- ppc_md.pcibios_write_config_word = name##_pcibios_write_config_word; \
- ppc_md.pcibios_write_config_dword = name##_pcibios_write_config_dword
+extern void setup_indirect_pci(struct pci_controller* hose,
+ u32 cfg_addr, u32 cfg_data);
+extern void setup_grackle(struct pci_controller *hose, unsigned io_space_size);
#endif /* __PPC_KERNEL_PCI_H__ */
diff --git a/arch/ppc/kernel/pmac_pci.c b/arch/ppc/kernel/pmac_pci.c
index 8f7b3d7c2..9e1fffb49 100644
--- a/arch/ppc/kernel/pmac_pci.c
+++ b/arch/ppc/kernel/pmac_pci.c
@@ -27,23 +27,14 @@
#include "pci.h"
-struct bridge_data **bridges, *bridge_list;
-static int max_bus;
-
-struct uninorth_data {
- struct device_node* node;
- volatile unsigned int* cfg_addr;
- volatile unsigned int* cfg_data;
- void* iobase;
- unsigned long iobase_phys;
-};
-
-static struct uninorth_data uninorth_bridges[3];
-static int uninorth_count;
-static int uninorth_default = -1;
+#undef DEBUG
static void add_bridges(struct device_node *dev);
+/* XXX Could be per-controller, but I don't think we risk anything by
+ * assuming we won't have both UniNorth and Bandit */
+static int has_uninorth;
+
/*
* Magic constants for enabling cache coherency in the bandit/PSX bridge.
*/
@@ -56,477 +47,201 @@ static void add_bridges(struct device_node *dev);
#define BANDIT_MAGIC 0x50
#define BANDIT_COHERENT 0x40
-/* Obsolete, should be replaced by pmac_pci_dev_io_base() (below) */
-__pmac
-void *pci_io_base(unsigned int bus)
-{
- struct bridge_data *bp;
-
- if (bus > max_bus || (bp = bridges[bus]) == 0)
- return 0;
- return bp->io_base;
-}
-
-__pmac
-int pci_device_loc(struct device_node *dev, unsigned char *bus_ptr,
- unsigned char *devfn_ptr)
+static int __init
+fixup_one_level_bus_range(struct device_node *node, int higher)
{
- unsigned int *reg;
- int len;
+ for (; node != 0;node = node->sibling) {
+ int * bus_range;
+ unsigned int *class_code;
+ int len;
- reg = (unsigned int *) get_property(dev, "reg", &len);
- if (reg == 0 || len < 5 * sizeof(unsigned int)) {
- /* doesn't look like a PCI device */
- *bus_ptr = 0xff;
- *devfn_ptr = 0xff;
- return -1;
+ /* For PCI<->PCI bridges or CardBus bridges, we go down */
+ class_code = (unsigned int *) get_property(node, "class-code", 0);
+ 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);
+ if (bus_range != NULL && len > 2 * sizeof(int)) {
+ if (bus_range[1] > higher)
+ higher = bus_range[1];
+ }
+ higher = fixup_one_level_bus_range(node->child, higher);
}
- *bus_ptr = reg[0] >> 16;
- *devfn_ptr = reg[0] >> 8;
- return 0;
+ return higher;
}
-/* This routines figures out on which root bridge a given PCI device
- * is attached.
+/* This routine fixes the "bus-range" property of all bridges in the
+ * system since they tend to have their "last" member wrong on macs
+ *
+ * Note that the bus numbers manipulated here are OF bus numbers, they
+ * are not Linux bus numbers.
*/
-__pmac
-int
-pmac_pci_dev_root_bridge(unsigned char bus, unsigned char dev_fn)
+static void __init
+fixup_bus_range(struct device_node *bridge)
{
- struct device_node *node, *bridge_node;
- int bridge = uninorth_default;
-
- if (uninorth_count == 0)
- return 0;
- if (bus == 0 && PCI_SLOT(dev_fn) < 11)
- return 0;
+ int * bus_range;
+ int len;
- /* We look for the OF device corresponding to this bus/devfn pair. If we
- * don't find it, we default to the external PCI */
- bridge_node = NULL;
- node = find_pci_device_OFnode(bus, dev_fn & 0xf8);
- if (node) {
- /* note: we don't stop on the first occurence since we need to go
- * up to the root bridge */
- do {
- if (node->type && !strcmp(node->type, "pci")
- && device_is_compatible(node, "uni-north"))
- bridge_node = node;
- node=node->parent;
- } while (node);
- }
- if (bridge_node) {
- int i;
- for (i=0;i<uninorth_count;i++)
- if (uninorth_bridges[i].node == bridge_node) {
- bridge = i;
- break;
- }
- }
-
- if (bridge == -1) {
- printk(KERN_WARNING "pmac_pci: no default bridge !\n");
- return 0;
- }
-
- return bridge;
-}
-
-__pmac
-void *
-pmac_pci_dev_io_base(unsigned char bus, unsigned char devfn, int physical)
-{
- int bridge = -1;
- if (uninorth_count != 0)
- bridge = pmac_pci_dev_root_bridge(bus, devfn);
- if (bridge == -1) {
- struct bridge_data *bp;
-
- if (bus > max_bus || (bp = bridges[bus]) == 0)
- return 0;
- return physical ? (void *) bp->io_base_phys : bp->io_base;
+ /* 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)) {
+ printk(KERN_WARNING "Can't get bus-range for %s\n",
+ bridge->full_name);
+ return;
}
- return physical ? (void *) uninorth_bridges[bridge].iobase_phys
- : uninorth_bridges[bridge].iobase;
-}
-
-__pmac
-void *
-pmac_pci_dev_mem_base(unsigned char bus, unsigned char devfn)
-{
- return 0;
+ bus_range[1] = fixup_one_level_bus_range(bridge->child, bus_range[1]);
}
-/* This function only works for bus 0, uni-N uses a different mecanism for
- * other busses (see below)
+/*
+ * Apple MacRISC (UniNorth, Bandit) PCI controllers.
+ *
+ * The "Bandit" version is present in all early PCI PowerMacs,
+ * and up to the first ones using Grackle. Some machines may
+ * have 2 bandit controllers (2 PCI busses).
+ *
+ * The "UniNorth" version is present in all Core99 machines
+ * (iBook, G4, new IMacs, and all the recent Apple machines).
+ * It contains 3 controllers in one ASIC.
*/
-#define UNI_N_CFA0(devfn, off) \
+
+#define MACRISC_CFA0(devfn, off) \
((1 << (unsigned long)PCI_SLOT(dev_fn)) \
| (((unsigned long)PCI_FUNC(dev_fn)) << 8) \
| (((unsigned long)(off)) & 0xFCUL))
-/* This one is for type 1 config accesses */
-#define UNI_N_CFA1(bus, devfn, off) \
+#define MACRISC_CFA1(bus, devfn, off) \
((((unsigned long)(bus)) << 16) \
|(((unsigned long)(devfn)) << 8) \
|(((unsigned long)(off)) & 0xFCUL) \
|1UL)
-__pmac static
-unsigned int
-uni_north_access_data(unsigned char bus, unsigned char dev_fn,
- unsigned char offset)
+static unsigned int __pmac
+macrisc_cfg_access(struct pci_controller* hose, u8 bus, u8 dev_fn, u8 offset)
{
- int bridge;
unsigned int caddr;
-
- bridge = pmac_pci_dev_root_bridge(bus, dev_fn);
- if (bus == 0)
- caddr = UNI_N_CFA0(dev_fn, offset);
- else
- caddr = UNI_N_CFA1(bus, dev_fn, offset);
-
- if (bridge == -1) {
- printk(KERN_WARNING "pmac_pci: no default bridge !\n");
- return 0;
- }
-
- /* Uninorth will return garbage if we don't read back the value ! */
- out_le32(uninorth_bridges[bridge].cfg_addr, caddr);
- (void)in_le32(uninorth_bridges[bridge].cfg_addr);
- /* Yes, offset is & 7, not & 3 ! */
- return (unsigned int)(uninorth_bridges[bridge].cfg_data) + (offset & 0x07);
-}
-
-__pmac
-int uni_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned char *val)
-{
- unsigned int addr;
-
- *val = 0xff;
- addr = uni_north_access_data(bus, dev_fn, offset);
- if (!addr)
- return PCIBIOS_DEVICE_NOT_FOUND;
- *val = in_8((volatile unsigned char*)addr);
- return PCIBIOS_SUCCESSFUL;
-}
-
-__pmac
-int uni_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned short *val)
-{
- unsigned int addr;
-
- *val = 0xffff;
- addr = uni_north_access_data(bus, dev_fn, offset);
- if (!addr)
- return PCIBIOS_DEVICE_NOT_FOUND;
- *val = in_le16((volatile unsigned short*)addr);
- return PCIBIOS_SUCCESSFUL;
-}
-
-__pmac
-int uni_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned int *val)
-{
- unsigned int addr;
- *val = 0xffff;
- addr = uni_north_access_data(bus, dev_fn, offset);
- if (!addr)
- return PCIBIOS_DEVICE_NOT_FOUND;
- *val = in_le32((volatile unsigned int*)addr);
- return PCIBIOS_SUCCESSFUL;
-}
-
-__pmac
-int uni_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned char val)
-{
- unsigned int addr;
-
- addr = uni_north_access_data(bus, dev_fn, offset);
- if (!addr)
- return PCIBIOS_DEVICE_NOT_FOUND;
- out_8((volatile unsigned char *)addr, val);
- (void)in_8((volatile unsigned char *)addr);
- return PCIBIOS_SUCCESSFUL;
-}
-
-__pmac
-int uni_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned short val)
-{
- unsigned int addr;
-
- addr = uni_north_access_data(bus, dev_fn, offset);
- if (!addr)
- return PCIBIOS_DEVICE_NOT_FOUND;
- out_le16((volatile unsigned short *)addr, val);
- (void)in_le16((volatile unsigned short *)addr);
- return PCIBIOS_SUCCESSFUL;
-}
-
-__pmac
-int uni_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned int val)
-{
- unsigned int addr;
-
- addr = uni_north_access_data(bus, dev_fn, offset);
- if (!addr)
- return PCIBIOS_DEVICE_NOT_FOUND;
- out_le32((volatile unsigned int *)addr, val);
- (void)in_le32((volatile unsigned int *)addr);
- return PCIBIOS_SUCCESSFUL;
-}
-
-__pmac
-int pmac_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned char *val)
-{
- struct bridge_data *bp;
-
- *val = 0xff;
- if (bus > max_bus || (bp = bridges[bus]) == 0)
- return PCIBIOS_DEVICE_NOT_FOUND;
- if (bus == bp->bus_number) {
- if (dev_fn < (11 << 3))
- return PCIBIOS_DEVICE_NOT_FOUND;
- out_le32(bp->cfg_addr,
- (1UL << (dev_fn >> 3)) + ((dev_fn & 7) << 8)
- + (offset & ~3));
- } else {
- /* Bus number once again taken into consideration.
- * Change applied from 2.1.24. This makes devices located
- * behind PCI-PCI bridges visible.
- * -Ranjit Deshpande, 01/20/99
- */
- out_le32(bp->cfg_addr, (bus << 16) + (dev_fn << 8) + (offset & ~3) + 1);
- }
- udelay(2);
- *val = in_8(bp->cfg_data + (offset & 3));
- return PCIBIOS_SUCCESSFUL;
-}
-
-__pmac
-int pmac_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned short *val)
-{
- struct bridge_data *bp;
-
- *val = 0xffff;
- if (bus > max_bus || (bp = bridges[bus]) == 0)
- return PCIBIOS_DEVICE_NOT_FOUND;
- if ((offset & 1) != 0)
- return PCIBIOS_BAD_REGISTER_NUMBER;
- if (bus == bp->bus_number) {
- if (dev_fn < (11 << 3))
- return PCIBIOS_DEVICE_NOT_FOUND;
- out_le32(bp->cfg_addr,
- (1UL << (dev_fn >> 3)) + ((dev_fn & 7) << 8)
- + (offset & ~3));
- } else {
- /* See pci_read_config_byte */
- out_le32(bp->cfg_addr, (bus << 16) + (dev_fn << 8) + (offset & ~3) + 1);
- }
- udelay(2);
- *val = in_le16((volatile unsigned short *)(bp->cfg_data + (offset & 3)));
- return PCIBIOS_SUCCESSFUL;
-}
-
-__pmac
-int pmac_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned int *val)
-{
- struct bridge_data *bp;
-
- *val = 0xffffffff;
- if (bus > max_bus || (bp = bridges[bus]) == 0)
- return PCIBIOS_DEVICE_NOT_FOUND;
- if ((offset & 3) != 0)
- return PCIBIOS_BAD_REGISTER_NUMBER;
- if (bus == bp->bus_number) {
- if (dev_fn < (11 << 3))
- return PCIBIOS_DEVICE_NOT_FOUND;
- out_le32(bp->cfg_addr,
- (1UL << (dev_fn >> 3)) + ((dev_fn & 7) << 8)
- + offset);
- } else {
- /* See pci_read_config_byte */
- out_le32(bp->cfg_addr, (bus << 16) + (dev_fn << 8) + offset + 1);
- }
- udelay(2);
- *val = in_le32((volatile unsigned int *)bp->cfg_data);
- return PCIBIOS_SUCCESSFUL;
-}
-
-__pmac
-int pmac_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned char val)
-{
- struct bridge_data *bp;
-
- if (bus > max_bus || (bp = bridges[bus]) == 0)
- return PCIBIOS_DEVICE_NOT_FOUND;
- if (bus == bp->bus_number) {
+#ifdef DEBUG
+// printk("macrisc_config_access(hose: 0x%08lx, bus: 0x%x, devfb: 0x%x, offset: 0x%x)\n",
+// hose, bus, dev_fn, offset);
+#endif
+ if (bus == hose->first_busno) {
if (dev_fn < (11 << 3))
- return PCIBIOS_DEVICE_NOT_FOUND;
- out_le32(bp->cfg_addr,
- (1UL << (dev_fn >> 3)) + ((dev_fn & 7) << 8)
- + (offset & ~3));
- } else {
- /* See pci_read_config_byte */
- out_le32(bp->cfg_addr, (bus << 16) + (dev_fn << 8) + (offset & ~3) + 1);
- }
- udelay(2);
- out_8(bp->cfg_data + (offset & 3), val);
- return PCIBIOS_SUCCESSFUL;
-}
-
-__pmac
-int pmac_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned short val)
-{
- struct bridge_data *bp;
+ return 0;
+ caddr = MACRISC_CFA0(dev_fn, offset);
+ } else
+ caddr = MACRISC_CFA1(bus, dev_fn, offset);
+
+ /* Uninorth will return garbage if we don't read back the value ! */
+ do {
+ out_le32(hose->cfg_addr, caddr);
+ } while(in_le32(hose->cfg_addr) != caddr);
+
+ offset &= has_uninorth ? 0x07 : 0x03;
+ return (unsigned int)(hose->cfg_data) + (unsigned int)offset;
+}
+
+#define cfg_read(val, addr, type, op, op2) \
+ *val = op((type)(addr))
+#define cfg_write(val, addr, type, op, op2) \
+ op((type *)(addr), (val)); (void) op2((type *)(addr))
+
+#define cfg_read_bad(val, size) *val = bad_##size;
+#define cfg_write_bad(val, size)
+
+#define bad_byte 0xff
+#define bad_word 0xffff
+#define bad_dword 0xffffffffU
+
+#define MACRISC_PCI_OP(rw, size, type, op, op2) \
+static int __pmac \
+macrisc_##rw##_config_##size(struct pci_dev *dev, int off, type val) \
+{ \
+ struct pci_controller *hose = dev->sysdata; \
+ unsigned int addr; \
+ \
+ addr = macrisc_cfg_access(hose, dev->bus->number, dev->devfn, off); \
+ if (!addr) { \
+ cfg_##rw##_bad(val, size) \
+ return PCIBIOS_DEVICE_NOT_FOUND; \
+ } \
+ cfg_##rw(val, addr, type, op, op2); \
+ return PCIBIOS_SUCCESSFUL; \
+}
+
+MACRISC_PCI_OP(read, byte, u8 *, in_8, x)
+MACRISC_PCI_OP(read, word, u16 *, in_le16, x)
+MACRISC_PCI_OP(read, dword, u32 *, in_le32, x)
+MACRISC_PCI_OP(write, byte, u8, out_8, in_8)
+MACRISC_PCI_OP(write, word, u16, out_le16, in_le16)
+MACRISC_PCI_OP(write, dword, u32, out_le32, in_le32)
+
+static struct pci_ops macrisc_pci_ops =
+{
+ macrisc_read_config_byte,
+ macrisc_read_config_word,
+ macrisc_read_config_dword,
+ macrisc_write_config_byte,
+ macrisc_write_config_word,
+ macrisc_write_config_dword
+};
- if (bus > max_bus || (bp = bridges[bus]) == 0)
- return PCIBIOS_DEVICE_NOT_FOUND;
- if ((offset & 1) != 0)
- return PCIBIOS_BAD_REGISTER_NUMBER;
- if (bus == bp->bus_number) {
- if (dev_fn < (11 << 3))
- return PCIBIOS_DEVICE_NOT_FOUND;
- out_le32(bp->cfg_addr,
- (1UL << (dev_fn >> 3)) + ((dev_fn & 7) << 8)
- + (offset & ~3));
- } else {
- /* See pci_read_config_byte */
- out_le32(bp->cfg_addr, (bus << 16) + (dev_fn << 8) + (offset & ~3) + 1);
- }
- udelay(2);
- out_le16((volatile unsigned short *)(bp->cfg_data + (offset & 3)), val);
- return PCIBIOS_SUCCESSFUL;
-}
-__pmac
-int pmac_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned int val)
+/*
+ * Apple "Chaos" PCI controller.
+ *
+ * This controller is present on some first generation "PowerSurge"
+ * machines (8500, 8600, ...). It's a very weird beast and will die
+ * in flames if we try to probe the config space.
+ * The long-term solution is to provide a config space "emulation"
+ * based on what we find in OF device tree
+ */
+
+static int chaos_config_read_byte(struct pci_dev *dev, int offset, u8 *val)
{
- struct bridge_data *bp;
-
- if (bus > max_bus || (bp = bridges[bus]) == 0)
- return PCIBIOS_DEVICE_NOT_FOUND;
- if ((offset & 3) != 0)
- return PCIBIOS_BAD_REGISTER_NUMBER;
- if (bus == bp->bus_number) {
- if (dev_fn < (11 << 3))
- return PCIBIOS_DEVICE_NOT_FOUND;
- out_le32(bp->cfg_addr,
- (1UL << (dev_fn >> 3)) + ((dev_fn & 7) << 8)
- + offset);
- } else {
- /* See pci_read_config_byte */
- out_le32(bp->cfg_addr, (bus << 16) + (dev_fn << 8) + (offset & ~3) + 1);
- }
- udelay(2);
- out_le32((volatile unsigned int *)bp->cfg_data, val);
- return PCIBIOS_SUCCESSFUL;
+ return PCIBIOS_DEVICE_NOT_FOUND;
}
-#define GRACKLE_CFA(b, d, o) (0x80 | ((b) << 8) | ((d) << 16) \
- | (((o) & ~3) << 24))
-
-int grackle_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned char *val)
+static int chaos_config_read_word(struct pci_dev *dev, int offset, u16 *val)
{
- struct bridge_data *bp;
-
- *val = 0xff;
- if (bus > max_bus || (bp = bridges[bus]) == 0)
- return PCIBIOS_DEVICE_NOT_FOUND;
- out_be32(bp->cfg_addr, GRACKLE_CFA(bus, dev_fn, offset));
- *val = in_8(bp->cfg_data + (offset & 3));
- return PCIBIOS_SUCCESSFUL;
+ return PCIBIOS_DEVICE_NOT_FOUND;
}
-int grackle_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned short *val)
+static int chaos_config_read_dword(struct pci_dev *dev, int offset, u32 *val)
{
- struct bridge_data *bp;
-
- *val = 0xffff;
- if (bus > max_bus || (bp = bridges[bus]) == 0)
- return PCIBIOS_DEVICE_NOT_FOUND;
- if ((offset & 1) != 0)
- return PCIBIOS_BAD_REGISTER_NUMBER;
- out_be32(bp->cfg_addr, GRACKLE_CFA(bus, dev_fn, offset));
- *val = in_le16((volatile unsigned short *)(bp->cfg_data + (offset&3)));
- return PCIBIOS_SUCCESSFUL;
+ return PCIBIOS_DEVICE_NOT_FOUND;
}
-int grackle_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned int *val)
+static int chaos_config_write_byte(struct pci_dev *dev, int offset, u8 val)
{
- struct bridge_data *bp;
-
- *val = 0xffffffff;
- if (bus > max_bus || (bp = bridges[bus]) == 0)
- return PCIBIOS_DEVICE_NOT_FOUND;
- if ((offset & 3) != 0)
- return PCIBIOS_BAD_REGISTER_NUMBER;
- out_be32(bp->cfg_addr, GRACKLE_CFA(bus, dev_fn, offset));
- *val = in_le32((volatile unsigned int *)bp->cfg_data);
- return PCIBIOS_SUCCESSFUL;
+ return PCIBIOS_DEVICE_NOT_FOUND;
}
-int grackle_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned char val)
+static int chaos_config_write_word(struct pci_dev *dev, int offset, u16 val)
{
- struct bridge_data *bp;
-
- if (bus > max_bus || (bp = bridges[bus]) == 0)
- return PCIBIOS_DEVICE_NOT_FOUND;
- out_be32(bp->cfg_addr, GRACKLE_CFA(bus, dev_fn, offset));
- out_8(bp->cfg_data + (offset & 3), val);
- return PCIBIOS_SUCCESSFUL;
+ return PCIBIOS_DEVICE_NOT_FOUND;
}
-int grackle_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned short val)
+static int chaos_config_write_dword(struct pci_dev *dev, int offset, u32 val)
{
- struct bridge_data *bp;
-
- if (bus > max_bus || (bp = bridges[bus]) == 0)
- return PCIBIOS_DEVICE_NOT_FOUND;
- if ((offset & 1) != 0)
- return PCIBIOS_BAD_REGISTER_NUMBER;
- out_be32(bp->cfg_addr, GRACKLE_CFA(bus, dev_fn, offset));
- out_le16((volatile unsigned short *)(bp->cfg_data + (offset&3)), val);
- return PCIBIOS_SUCCESSFUL;
+ return PCIBIOS_DEVICE_NOT_FOUND;
}
-int grackle_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned int val)
+static struct pci_ops chaos_pci_ops =
{
- struct bridge_data *bp;
+ chaos_config_read_byte,
+ chaos_config_read_word,
+ chaos_config_read_dword,
+ chaos_config_write_byte,
+ chaos_config_write_word,
+ chaos_config_write_dword
+};
- if (bus > max_bus || (bp = bridges[bus]) == 0)
- return PCIBIOS_DEVICE_NOT_FOUND;
- if ((offset & 1) != 0)
- return PCIBIOS_BAD_REGISTER_NUMBER;
- out_be32(bp->cfg_addr, GRACKLE_CFA(bus, dev_fn, offset));
- out_le32((volatile unsigned int *)bp->cfg_data, val);
- return PCIBIOS_SUCCESSFUL;
-}
/*
* For a bandit bridge, turn on cache coherency if necessary.
- * N.B. we can't use pcibios_*_config_* here because bridges[]
- * is not initialized yet.
+ * N.B. we could clean this up using the hose ops directly.
*/
-static void __init init_bandit(struct bridge_data *bp)
+static void __init init_bandit(struct pci_controller *bp)
{
unsigned int vendev, magic;
int rev;
@@ -543,8 +258,8 @@ static void __init init_bandit(struct bridge_data *bp)
rev = in_8(bp->cfg_data);
if (rev != BANDIT_REVID)
printk(KERN_WARNING
- "Unknown revision %d for bandit at %p\n",
- rev, bp->io_base);
+ "Unknown revision %d for bandit at %08lx\n",
+ rev, bp->io_base_phys);
} else if (vendev != (BANDIT_DEVID_2 << 16) + APPLE_VENDID) {
printk(KERN_WARNING "bandit isn't? (%x)\n", vendev);
return;
@@ -555,8 +270,8 @@ static void __init init_bandit(struct bridge_data *bp)
udelay(2);
rev = in_8(bp->cfg_data);
if (rev != BANDIT_REVID)
- printk(KERN_WARNING "Unknown revision %d for bandit at %p\n",
- rev, bp->io_base);
+ printk(KERN_WARNING "Unknown revision %d for bandit at %08lx\n",
+ rev, bp->io_base_phys);
/* read the word at offset 0x50 */
out_le32(bp->cfg_addr, (1UL << BANDIT_DEVNUM) + BANDIT_MAGIC);
@@ -567,16 +282,71 @@ static void __init init_bandit(struct bridge_data *bp)
magic |= BANDIT_COHERENT;
udelay(2);
out_le32((volatile unsigned int *)bp->cfg_data, magic);
- printk(KERN_INFO "Cache coherency enabled for bandit/PSX at %p\n",
- bp->io_base);
+ printk(KERN_INFO "Cache coherency enabled for bandit/PSX at %08lx\n",
+ bp->io_base_phys);
+}
+
+
+/*
+ * Tweak the PCI-PCI bridge chip on the blue & white G3s.
+ */
+static void __init
+init_p2pbridge(void)
+{
+ struct device_node *p2pbridge;
+ struct pci_controller* hose;
+ u8 bus, devfn;
+ u16 val;
+
+ /* XXX it would be better here to identify the specific
+ PCI-PCI bridge chip we have. */
+ if ((p2pbridge = find_devices("pci-bridge")) == 0
+ || p2pbridge->parent == NULL
+ || strcmp(p2pbridge->parent->name, "pci") != 0)
+ return;
+ if (pci_device_from_OF_node(p2pbridge, &bus, &devfn) < 0) {
+#ifdef DEBUG
+ printk("Can't find PCI infos for PCI<->PCI bridge\n");
+#endif
+ return;
+ }
+ /* Warning: At this point, we have not yet renumbered all busses.
+ * So we must use OF walking to find out hose
+ */
+ hose = pci_find_hose_for_OF_device(p2pbridge);
+ if (!hose) {
+#ifdef DEBUG
+ printk("Can't find hose for PCI<->PCI bridge\n");
+#endif
+ return;
+ }
+ if (early_read_config_word(hose, bus, devfn,
+ PCI_BRIDGE_CONTROL, &val) < 0) {
+ printk(KERN_ERR "init_p2pbridge: couldn't read bridge control\n");
+ return;
+ }
+ val &= ~PCI_BRIDGE_CTL_MASTER_ABORT;
+ early_write_config_word(hose, bus, devfn, PCI_BRIDGE_CONTROL, val);
}
+void __init
+pmac_find_bridges(void)
+{
+ add_bridges(find_devices("bandit"));
+ add_bridges(find_devices("chaos"));
+ add_bridges(find_devices("pci"));
+ init_p2pbridge();
+}
+
+#define GRACKLE_CFA(b, d, o) (0x80 | ((b) << 8) | ((d) << 16) \
+ | (((o) & ~3) << 24))
+
#define GRACKLE_PICR1_STG 0x00000040
#define GRACKLE_PICR1_LOOPSNOOP 0x00000010
/* N.B. this is called before bridges is initialized, so we can't
use grackle_pcibios_{read,write}_config_dword. */
-static inline void grackle_set_stg(struct bridge_data *bp, int enable)
+static inline void grackle_set_stg(struct pci_controller* bp, int enable)
{
unsigned int val;
@@ -586,9 +356,10 @@ static inline void grackle_set_stg(struct bridge_data *bp, int enable)
(val & ~GRACKLE_PICR1_STG);
out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8));
out_le32((volatile unsigned int *)bp->cfg_data, val);
+ (void)in_le32((volatile unsigned int *)bp->cfg_data);
}
-static inline void grackle_set_loop_snoop(struct bridge_data *bp, int enable)
+static inline void grackle_set_loop_snoop(struct pci_controller *bp, int enable)
{
unsigned int val;
@@ -598,25 +369,68 @@ static inline void grackle_set_loop_snoop(struct bridge_data *bp, int enable)
(val & ~GRACKLE_PICR1_LOOPSNOOP);
out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8));
out_le32((volatile unsigned int *)bp->cfg_data, val);
+ (void)in_le32((volatile unsigned int *)bp->cfg_data);
}
+static void __init
+setup_uninorth(struct pci_controller* hose, struct reg_property* addr)
+{
+ pci_assign_all_busses = 1;
+ has_uninorth = 1;
+ hose->ops = &macrisc_pci_ops;
+ hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000);
+ hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000);
+ hose->io_base_phys = addr->address;
+ /* is 0x10000 enough for io space ? */
+ hose->io_base_virt = (void *)ioremap(addr->address, 0x10000);
+
+ /* XXX This is the bridge with the PCI expansion bus. We route
+ * legacy IOs to it.
+ */
+ if (addr->address == 0xf2000000)
+ isa_io_base = (unsigned long)hose->io_base_virt;
+}
-void __init pmac_find_bridges(void)
+static void __init
+setup_bandit(struct pci_controller* hose, struct reg_property* addr)
{
- int bus;
- struct bridge_data *bridge;
+ hose->ops = &macrisc_pci_ops;
+ hose->cfg_addr = (volatile unsigned int *)
+ ioremap(addr->address + 0x800000, 0x1000);
+ hose->cfg_data = (volatile unsigned char *)
+ ioremap(addr->address + 0xc00000, 0x1000);
+ hose->io_base_phys = addr->address;
+ hose->io_base_virt = (void *) ioremap(addr->address, 0x10000);
+ init_bandit(hose);
+}
- bridge_list = 0;
- max_bus = 0;
- add_bridges(find_devices("bandit"));
- add_bridges(find_devices("chaos"));
- add_bridges(find_devices("pci"));
- bridges = (struct bridge_data **)
- alloc_bootmem((max_bus + 1) * sizeof(struct bridge_data *));
- memset(bridges, 0, (max_bus + 1) * sizeof(struct bridge_data *));
- for (bridge = bridge_list; bridge != NULL; bridge = bridge->next)
- for (bus = bridge->bus_number; bus <= bridge->max_bus; ++bus)
- bridges[bus] = bridge;
+static void __init
+setup_chaos(struct pci_controller* hose, struct reg_property* addr)
+{
+ /* assume a `chaos' bridge */
+ hose->ops = &chaos_pci_ops;
+ hose->cfg_addr = (volatile unsigned int *)
+ ioremap(addr->address + 0x800000, 0x1000);
+ hose->cfg_data = (volatile unsigned char *)
+ ioremap(addr->address + 0xc00000, 0x1000);
+ hose->io_base_phys = addr->address;
+ hose->io_base_virt = (void *) ioremap(addr->address, 0x10000);
+}
+
+void __init
+setup_grackle(struct pci_controller *hose, unsigned io_space_size)
+{
+ setup_indirect_pci(hose, 0xfec00000, 0xfee00000);
+ hose->io_base_phys = 0xfe000000;
+ hose->io_base_virt = (void *) ioremap(0xfe000000, io_space_size);
+ pci_dram_offset = 0;
+ isa_mem_base = 0xfd000000;
+ isa_io_base = (unsigned long) hose->io_base_virt;
+ if (machine_is_compatible("AAPL,PowerBook1998"))
+ grackle_set_loop_snoop(hose, 1);
+#if 0 /* Disabled for now, HW problems ??? */
+ grackle_set_stg(hose, 1);
+#endif
}
/*
@@ -626,11 +440,12 @@ void __init pmac_find_bridges(void)
*/
static void __init add_bridges(struct device_node *dev)
{
- int *bus_range;
int len;
- struct bridge_data *bp;
+ struct pci_controller *hose;
struct reg_property *addr;
-
+ char* disp_name;
+ int *bus_range;
+
for (; dev != NULL; dev = dev->next) {
addr = (struct reg_property *) get_property(dev, "reg", &len);
if (addr == NULL || len < sizeof(*addr)) {
@@ -640,108 +455,52 @@ static void __init add_bridges(struct device_node *dev)
}
bus_range = (int *) 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);
- continue;
- }
- if (bus_range[1] == bus_range[0])
- printk(KERN_INFO "PCI bus %d", bus_range[0]);
- else
- printk(KERN_INFO "PCI buses %d..%d", bus_range[0],
- bus_range[1]);
- printk(" controlled by %s at %x\n", dev->name, addr->address);
- if (device_is_compatible(dev, "uni-north")) {
- int i = uninorth_count++;
- uninorth_bridges[i].cfg_addr = ioremap(addr->address + 0x800000, 0x1000);
- uninorth_bridges[i].cfg_data = ioremap(addr->address + 0xc00000, 0x1000);
- uninorth_bridges[i].node = dev;
- uninorth_bridges[i].iobase_phys = addr->address;
- /* is 0x10000 enough for io space ? */
- uninorth_bridges[i].iobase = (void *)ioremap(addr->address, 0x10000);
- /* XXX This is the bridge with the PCI expansion bus. This is also the
- * address of the bus that will receive type 1 config accesses and io
- * accesses. Appears to be correct for iMac DV and G4 Sawtooth too.
- * That means that we cannot do io cycles on the AGP bus nor the internal
- * ethernet/fw bus. Fortunately, they appear not to be needed on iMac DV
- * and G4 neither.
- */
- if (addr->address == 0xf2000000)
- uninorth_default = i;
- else
- continue;
+ printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n",
+ dev->full_name);
}
- bp = (struct bridge_data *) alloc_bootmem(sizeof(*bp));
+ hose = pcibios_alloc_controller();
+ if (!hose)
+ continue;
+ hose->arch_data = dev;
+ hose->first_busno = bus_range ? bus_range[0] : 0;
+ hose->last_busno = bus_range ? bus_range[1] : 0xff;
+
+ disp_name = NULL;
if (device_is_compatible(dev, "uni-north")) {
- bp->cfg_addr = 0;
- bp->cfg_data = 0;
- bp->io_base = uninorth_bridges[uninorth_count-1].iobase;
- bp->io_base_phys = uninorth_bridges[uninorth_count-1].iobase_phys;
+ setup_uninorth(hose, addr);
+ disp_name = "UniNorth";
} else if (strcmp(dev->name, "pci") == 0) {
/* XXX assume this is a mpc106 (grackle) */
- bp->cfg_addr = (volatile unsigned int *)
- ioremap(0xfec00000, 0x1000);
- bp->cfg_data = (volatile unsigned char *)
- ioremap(0xfee00000, 0x1000);
- bp->io_base_phys = 0xfe000000;
- bp->io_base = (void *) ioremap(0xfe000000, 0x20000);
- if (machine_is_compatible("AAPL,PowerBook1998"))
- grackle_set_loop_snoop(bp, 1);
-#if 0 /* Disabled for now, HW problems ??? */
- grackle_set_stg(bp, 1);
-#endif
- } else {
- /* a `bandit' or `chaos' bridge */
- bp->cfg_addr = (volatile unsigned int *)
- ioremap(addr->address + 0x800000, 0x1000);
- bp->cfg_data = (volatile unsigned char *)
- ioremap(addr->address + 0xc00000, 0x1000);
- bp->io_base_phys = addr->address;
- bp->io_base = (void *) ioremap(addr->address, 0x10000);
+ setup_grackle(hose, 0x20000);
+ disp_name = "Grackle (MPC106)";
+ } else if (strcmp(dev->name, "bandit") == 0) {
+ setup_bandit(hose, addr);
+ disp_name = "Bandit";
+ } else if (strcmp(dev->name, "chaos") == 0) {
+ setup_chaos(hose, addr);
+ disp_name = "Chaos";
}
+ printk(KERN_INFO "Found %s PCI host bridge at 0x%08x. Firmware bus number: %d->%d\n",
+ disp_name, addr->address, hose->first_busno, hose->last_busno);
+#ifdef DEBUG
+ printk(" ->Hose at 0x%08lx, cfg_addr=0x%08lx,cfg_data=0x%08lx\n",
+ hose, hose->cfg_addr, hose->cfg_data);
+#endif
+
+ /* Setup a default isa_io_base */
if (isa_io_base == 0)
- isa_io_base = (unsigned long) bp->io_base;
- bp->bus_number = bus_range[0];
- bp->max_bus = bus_range[1];
- bp->next = bridge_list;
- bp->node = dev;
- bridge_list = bp;
- if (bp->max_bus > max_bus)
- max_bus = bp->max_bus;
-
- if (strcmp(dev->name, "bandit") == 0)
- init_bandit(bp);
- }
-}
-
-/* Recursively searches any node that is of type PCI-PCI bridge. Without
- * this, the old code would miss children of P2P bridges and hence not
- * fix IRQ's for cards located behind P2P bridges.
- * - Ranjit Deshpande, 01/20/99
- */
-void __init
-fix_intr(struct device_node *node, struct pci_dev *dev)
-{
- unsigned int *reg, *class_code;
+ isa_io_base = (unsigned long)hose->io_base_virt;
- for (; node != 0;node = node->sibling) {
- class_code = (unsigned int *) get_property(node, "class-code", 0);
- if(class_code && (*class_code >> 8) == PCI_CLASS_BRIDGE_PCI)
- fix_intr(node->child, dev);
- reg = (unsigned int *) get_property(node, "reg", 0);
- if (reg == 0 || ((reg[0] >> 8) & 0xff) != dev->devfn)
- continue;
- /* this is the node, see if it has interrupts */
- if (node->n_intrs > 0)
- dev->irq = node->intrs[0].line;
- break;
+ /* Fixup "bus-range" OF property */
+ fixup_bus_range(dev);
}
}
-void __init
-pmac_pcibios_fixup(void)
-{
- struct pci_dev *dev;
+static void
+pcibios_fixup_OF_interrupts(void)
+{
+ struct pci_dev* dev;
/*
* FIXME: This is broken: We should not assign IRQ's to IRQless
@@ -757,44 +516,43 @@ pmac_pcibios_fixup(void)
* should find the device node and se if it has an
* AAPL,interrupts property.
*/
- struct bridge_data *bp = bridges[dev->bus->number];
unsigned char pin;
+ struct device_node* node;
- if (pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin) ||
- !pin)
+ if (pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin) || !pin)
continue; /* No interrupt generated -> no fixup */
- /* We iterate all instances of uninorth for now */
- if (uninorth_count && dev->bus->number == 0) {
- int i;
- for (i=0;i<uninorth_count;i++)
- fix_intr(uninorth_bridges[i].node->child, dev);
- } else
- fix_intr(bp->node->child, dev);
+ node = pci_device_to_OF_node(dev);
+ if (!node) {
+ printk("No OF node for device %x:%x\n", dev->bus->number, dev->devfn >> 3);
+ continue;
+ }
+ /* this is the node, see if it has interrupts */
+ if (node->n_intrs > 0)
+ dev->irq = node->intrs[0].line;
+ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
}
}
void __init
-pmac_setup_pci_ptrs(void)
+pmac_pcibios_fixup(void)
{
- struct device_node* np;
+ /* Fixup interrupts according to OF tree */
+ pcibios_fixup_OF_interrupts();
+}
- np = find_devices("pci");
- if (np != 0)
- {
- if (device_is_compatible(np, "uni-north"))
- {
- /* looks like an Core99 powermac */
- set_config_access_method(uni);
- } else
- {
- /* looks like a G3 powermac */
- set_config_access_method(grackle);
- }
- } else
- {
- set_config_access_method(pmac);
+/* We don't want to enable USB controllers absent from the OF tree
+ * (iBook second controller)
+ */
+int
+pmac_pci_enable_device_hook(struct pci_dev *dev, int initial)
+{
+ if (dev->vendor == PCI_VENDOR_ID_APPLE
+ && dev->device == PCI_DEVICE_ID_APPLE_KL_USB) {
+ struct device_node* node;
+ node = pci_device_to_OF_node(dev);
+ if (!node)
+ return -EINVAL;
}
-
- ppc_md.pcibios_fixup = pmac_pcibios_fixup;
+ return 0;
}
diff --git a/arch/ppc/kernel/pmac_pic.c b/arch/ppc/kernel/pmac_pic.c
index efd767482..a9a1777ca 100644
--- a/arch/ppc/kernel/pmac_pic.c
+++ b/arch/ppc/kernel/pmac_pic.c
@@ -4,14 +4,15 @@
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/pci.h>
-#include <linux/openpic.h>
#include <asm/init.h>
#include <asm/io.h>
#include <asm/smp.h>
#include <asm/prom.h>
#include <asm/pci-bridge.h>
+
#include "pmac_pic.h"
+#include "open_pic.h"
/* pmac */struct pmac_irq_hw {
unsigned int flag;
@@ -30,16 +31,14 @@ static volatile struct pmac_irq_hw *pmac_irq_hw[4] = {
static int max_irqs;
static int max_real_irqs;
-static int has_openpic = 0;
+static int pmac_has_openpic;
+
+spinlock_t pmac_pic_lock = SPIN_LOCK_UNLOCKED;
+
#define GATWICK_IRQ_POOL_SIZE 10
static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE];
-extern int pmac_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned short *val);
-extern int pmac_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned short val);
-
/*
* Mark an irq as "lost". This is only used on the pmac
* since it can lose interrupts (see pmac_set_irq_mask).
@@ -51,48 +50,11 @@ void __pmac __no_use_set_lost(unsigned long irq_nr)
atomic_inc(&ppc_n_lost_interrupts);
}
-static void pmac_openpic_mask_irq(unsigned int irq_nr)
-{
- openpic_disable_irq(irq_nr);
-}
-
-static void pmac_openpic_unmask_irq(unsigned int irq_nr)
-{
- openpic_enable_irq(irq_nr);
-}
-
-static void pmac_openpic_ack_irq(unsigned int irq_nr)
-{
- if ((irq_desc[irq_nr].status & IRQ_LEVEL) == 0)
- openpic_eoi(smp_processor_id());
- openpic_disable_irq(irq_nr);
-}
-
-static void pmac_openpic_end_irq(unsigned int irq_nr)
-{
- if ((irq_desc[irq_nr].status & IRQ_LEVEL) != 0)
- openpic_eoi(smp_processor_id());
- openpic_enable_irq(irq_nr);
-}
-
-struct hw_interrupt_type pmac_open_pic = {
- " OpenPIC ",
- NULL,
- NULL,
- pmac_openpic_unmask_irq,
- pmac_openpic_mask_irq,
- /* Theorically, the mask&ack should be NULL for OpenPIC. However, doing
- * so shows tons of bogus interrupts coming in.
- */
- pmac_openpic_ack_irq,
- pmac_openpic_end_irq,
- NULL
-};
-
static void __pmac pmac_mask_and_ack_irq(unsigned int irq_nr)
{
unsigned long bit = 1UL << (irq_nr & 0x1f);
int i = irq_nr >> 5;
+ unsigned long flags;
if ((unsigned)irq_nr >= max_irqs)
return;
@@ -100,6 +62,7 @@ static void __pmac pmac_mask_and_ack_irq(unsigned int irq_nr)
clear_bit(irq_nr, ppc_cached_irq_mask);
if (test_and_clear_bit(irq_nr, ppc_lost_interrupts))
atomic_dec(&ppc_n_lost_interrupts);
+ spin_lock_irqsave(&pmac_pic_lock, flags);
out_le32(&pmac_irq_hw[i]->ack, bit);
out_le32(&pmac_irq_hw[i]->enable, ppc_cached_irq_mask[i]);
out_le32(&pmac_irq_hw[i]->ack, bit);
@@ -108,16 +71,19 @@ static void __pmac pmac_mask_and_ack_irq(unsigned int irq_nr)
interrupts */
mb();
} while(in_le32(&pmac_irq_hw[i]->flag) & bit);
+ spin_unlock_irqrestore(&pmac_pic_lock, flags);
}
static void __pmac pmac_set_irq_mask(unsigned int irq_nr)
{
unsigned long bit = 1UL << (irq_nr & 0x1f);
int i = irq_nr >> 5;
+ unsigned long flags;
if ((unsigned)irq_nr >= max_irqs)
return;
+ spin_lock_irqsave(&pmac_pic_lock, flags);
/* enable unmasked interrupts */
out_le32(&pmac_irq_hw[i]->enable, ppc_cached_irq_mask[i]);
@@ -137,6 +103,7 @@ static void __pmac pmac_set_irq_mask(unsigned int irq_nr)
&& (ld_le32(&pmac_irq_hw[i]->level) & bit)
&& !(ld_le32(&pmac_irq_hw[i]->flag) & bit))
__set_lost((ulong)irq_nr);
+ spin_unlock_irqrestore(&pmac_pic_lock, flags);
}
static void __pmac pmac_mask_irq(unsigned int irq_nr)
@@ -152,6 +119,15 @@ static void __pmac pmac_unmask_irq(unsigned int irq_nr)
pmac_set_irq_mask(irq_nr);
}
+static void __pmac pmac_end_irq(unsigned int irq_nr)
+{
+ if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))) {
+ set_bit(irq_nr, ppc_cached_irq_mask);
+ pmac_set_irq_mask(irq_nr);
+ }
+}
+
+
struct hw_interrupt_type pmac_pic = {
" PMAC-PIC ",
NULL,
@@ -159,7 +135,7 @@ struct hw_interrupt_type pmac_pic = {
pmac_unmask_irq,
pmac_mask_irq,
pmac_mask_and_ack_irq,
- pmac_unmask_irq,
+ pmac_end_irq,
NULL
};
@@ -170,7 +146,7 @@ struct hw_interrupt_type gatwick_pic = {
pmac_unmask_irq,
pmac_mask_irq,
pmac_mask_and_ack_irq,
- pmac_unmask_irq,
+ pmac_end_irq,
NULL
};
@@ -204,35 +180,22 @@ pmac_get_irq(struct pt_regs *regs)
unsigned long bits = 0;
#ifdef CONFIG_SMP
- void pmac_smp_message_recv(struct pt_regs *);
+ void psurge_smp_message_recv(struct pt_regs *);
- /* IPI's are a hack on the powersurge -- Cort */
- if ( smp_processor_id() != 0 )
- {
- pmac_smp_message_recv(regs);
+ /* IPI's are a hack on the powersurge -- Cort */
+ if ( smp_processor_id() != 0 ) {
+ psurge_smp_message_recv(regs);
return -2; /* ignore, already handled */
}
#endif /* CONFIG_SMP */
-
- if (has_openpic) {
- irq = openpic_irq(smp_processor_id());
- if (irq == OPENPIC_VEC_SPURIOUS)
- /* We get those when doing polled ADB requests,
- * using -2 is a temp hack to disable the printk
- */
- irq = -2; /*-1; */
- }
- else
- {
- for (irq = max_real_irqs; (irq -= 32) >= 0; ) {
- int i = irq >> 5;
- bits = ld_le32(&pmac_irq_hw[i]->flag)
- | ppc_lost_interrupts[i];
- if (bits == 0)
- continue;
- irq += __ilog2(bits);
- break;
- }
+ for (irq = max_real_irqs; (irq -= 32) >= 0; ) {
+ int i = irq >> 5;
+ bits = ld_le32(&pmac_irq_hw[i]->flag)
+ | ppc_lost_interrupts[i];
+ if (bits == 0)
+ continue;
+ irq += __ilog2(bits);
+ break;
}
return irq;
@@ -336,11 +299,16 @@ static void __init enable_second_ohare(void)
addr = (unsigned long) ioremap(irqctrler->addrs[0].address, 0x40);
pmac_irq_hw[1] = (volatile struct pmac_irq_hw *)(addr + 0x20);
max_irqs = 64;
- if (pci_device_loc(irqctrler, &bus, &devfn) == 0) {
- pmac_pcibios_read_config_word(bus, devfn, PCI_COMMAND, &cmd);
- cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
- cmd &= ~PCI_COMMAND_IO;
- pmac_pcibios_write_config_word(bus, devfn, PCI_COMMAND, cmd);
+ if (pci_device_from_OF_node(irqctrler, &bus, &devfn) == 0) {
+ struct pci_controller* hose = pci_find_hose_for_OF_device(irqctrler);
+ if (!hose)
+ printk(KERN_ERR "Can't find PCI hose for OHare2 !\n");
+ else {
+ early_read_config_word(hose, bus, devfn, PCI_COMMAND, &cmd);
+ cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
+ cmd &= ~PCI_COMMAND_IO;
+ early_write_config_word(hose, bus, devfn, PCI_COMMAND, cmd);
+ }
}
second_irq = irqctrler->intrs[0].line;
@@ -378,20 +346,26 @@ pmac_pic_init(void)
printk("PowerMac using OpenPIC irq controller\n");
if (irqctrler->n_addrs > 0)
{
+ int nmi_irq = -1;
+ unsigned char senses[NR_IRQS];
#ifdef CONFIG_XMON
struct device_node* pswitch;
-#endif /* CONFIG_XMON */
- OpenPIC = (volatile struct OpenPIC *)
- ioremap(irqctrler->addrs[0].address,
- irqctrler->addrs[0].size);
- for ( i = 0 ; i < NR_IRQS ; i++ )
- irq_desc[i].handler = &pmac_open_pic;
- openpic_init(1);
- has_openpic = 1;
-#ifdef CONFIG_XMON
+
pswitch = find_devices("programmer-switch");
if (pswitch && pswitch->n_intrs)
- request_irq(pswitch->intrs[0].line, xmon_irq, 0,
+ nmi_irq = pswitch->intrs[0].line;
+#endif /* CONFIG_XMON */
+ prom_get_irq_senses(senses, 0, NR_IRQS);
+ OpenPIC_InitSenses = senses;
+ OpenPIC_NumInitSenses = NR_IRQS;
+ ppc_md.get_irq = openpic_get_irq;
+ OpenPIC_Addr = ioremap(irqctrler->addrs[0].address,
+ irqctrler->addrs[0].size);
+ openpic_init(1, 0, 0, nmi_irq);
+ pmac_has_openpic = 1;
+#ifdef CONFIG_XMON
+ if (nmi_irq >= 0)
+ request_irq(nmi_irq, xmon_irq, 0,
"NMI - XMON", 0);
#endif /* CONFIG_XMON */
return;
diff --git a/arch/ppc/kernel/pmac_setup.c b/arch/ppc/kernel/pmac_setup.c
index b5bf03abc..e7be1114e 100644
--- a/arch/ppc/kernel/pmac_setup.c
+++ b/arch/ppc/kernel/pmac_setup.c
@@ -47,6 +47,7 @@
#include <linux/cuda.h>
#include <linux/pmu.h>
+#include <asm/processor.h>
#include <asm/init.h>
#include <asm/prom.h>
#include <asm/system.h>
@@ -73,7 +74,8 @@ extern unsigned long pmac_get_rtc_time(void);
extern int pmac_set_rtc_time(unsigned long nowtime);
extern void pmac_read_rtc_time(void);
extern void pmac_calibrate_decr(void);
-extern void pmac_setup_pci_ptrs(void);
+extern void pmac_pcibios_fixup(void);
+extern void pmac_find_bridges(void);
extern int mackbd_setkeycode(unsigned int scancode, unsigned int keycode);
extern int mackbd_getkeycode(unsigned int scancode);
@@ -99,9 +101,7 @@ extern char pckbd_unexpected_up(unsigned char keycode);
extern int keyboard_sends_linux_keycodes;
extern void pmac_nvram_update(void);
-extern void *pmac_pci_dev_io_base(unsigned char bus, unsigned char devfn, int physical);
-extern void *pmac_pci_dev_mem_base(unsigned char bus, unsigned char devfn);
-extern int pmac_pci_dev_root_bridge(unsigned char bus, unsigned char devfn);
+extern int pmac_pci_enable_device_hook(struct pci_dev *dev, int initial);
unsigned char drive_info;
@@ -119,13 +119,34 @@ extern int pmac_newworld;
extern void zs_kgdb_hook(int tty_num);
static void ohare_init(void);
-static void init_p2pbridge(void);
#ifdef CONFIG_BOOTX_TEXT
void pmac_progress(char *s, unsigned short hex);
#endif
sys_ctrler_t sys_ctrler = SYS_CTRLER_UNKNOWN;
+#ifdef CONFIG_SMP
+volatile static long int core99_l2_cache;
+void core99_init_l2(void)
+{
+ int cpu = smp_processor_id();
+
+ if ( (_get_PVR() >> 16) != 8 && (_get_PVR() >> 16) != 12 )
+ return;
+
+ if (cpu == 0){
+ core99_l2_cache = _get_L2CR();
+ printk("CPU0: L2CR is %lx\n", core99_l2_cache);
+ } else {
+ printk("CPU%d: L2CR was %lx\n", cpu, _get_L2CR());
+ _set_L2CR(0);
+ _set_L2CR(core99_l2_cache);
+ printk("CPU%d: L2CR set to %lx\n", cpu, core99_l2_cache);
+ }
+}
+#endif /* CONFIG_SMP */
+
+
__pmac
int
pmac_get_cpuinfo(char *buffer)
@@ -250,7 +271,7 @@ pmac_setup_arch(void)
struct device_node *cpu;
int *fp;
- /* Set loops_per_sec to a half-way reasonable value,
+ /* Set loops_per_jiffy to a half-way reasonable value,
for use until calibrate_delay gets called. */
cpu = find_type_devices("cpu");
if (cpu != 0) {
@@ -263,13 +284,13 @@ pmac_setup_arch(void)
case 10: /* mach V (604ev5) */
case 12: /* G4 */
case 20: /* 620 */
- loops_per_sec = *fp;
+ loops_per_jiffy = *fp / HZ;
break;
default: /* 601, 603, etc. */
- loops_per_sec = *fp / 2;
+ loops_per_jiffy = *fp / (2*HZ);
}
} else
- loops_per_sec = 50000000;
+ loops_per_jiffy = 50000000 / HZ;
}
/* this area has the CPU identification register
@@ -278,8 +299,8 @@ pmac_setup_arch(void)
__ioremap(0xffc00000, 0x400000, pgprot_val(PAGE_READONLY));
ohare_init();
+ /* Lookup PCI hosts */
pmac_find_bridges();
- init_p2pbridge();
/* Checks "l2cr-value" property in the registry */
if ( (_get_PVR() >> 16) == 8 || (_get_PVR() >> 16) == 12 ) {
@@ -303,6 +324,11 @@ pmac_setup_arch(void)
ppc_override_l2cr_value, (ppc_override_l2cr_value & 0x80000000)
? "enabled" : "disabled");
+#ifdef CONFIG_SMP
+ /* somewhat of a hack */
+ core99_init_l2();
+#endif
+
#ifdef CONFIG_KGDB
zs_kgdb_hook(0);
#endif
@@ -330,32 +356,6 @@ pmac_setup_arch(void)
ROOT_DEV = to_kdev_t(DEFAULT_ROOT_DEVICE);
}
-/*
- * Tweak the PCI-PCI bridge chip on the blue & white G3s.
- */
-static void __init init_p2pbridge(void)
-{
- struct device_node *p2pbridge;
- unsigned char bus, devfn;
- unsigned short val;
-
- /* XXX it would be better here to identify the specific
- PCI-PCI bridge chip we have. */
- if ((p2pbridge = find_devices("pci-bridge")) == 0
- || p2pbridge->parent == NULL
- || strcmp(p2pbridge->parent->name, "pci") != 0)
- return;
- if (pci_device_loc(p2pbridge, &bus, &devfn) < 0)
- return;
- if (ppc_md.pcibios_read_config_word(bus, devfn, PCI_BRIDGE_CONTROL, &val) < 0) {
- printk(KERN_ERR "init_p2pbridge: couldn't read bridge control\n");
- return;
- }
- val &= ~PCI_BRIDGE_CTL_MASTER_ABORT;
- ppc_md.pcibios_write_config_word(bus, devfn, PCI_BRIDGE_CONTROL, val);
- ppc_md.pcibios_read_config_word(bus, devfn, PCI_BRIDGE_CONTROL, &val);
-}
-
static void __init ohare_init(void)
{
/*
@@ -448,7 +448,7 @@ kdev_t __init find_ide_boot(void)
void __init find_boot_device(void)
{
-#ifdef CONFIG_SCSI
+#if defined(CONFIG_SCSI) && defined(CONFIG_BLK_DEV_SD)
if (boot_host != NULL) {
boot_dev = sd_find_target(boot_host, boot_target);
if (boot_dev != 0)
@@ -493,7 +493,9 @@ pmac_restart(char *cmd)
struct adb_request req;
#endif /* CONFIG_ADB_CUDA */
+#ifdef CONFIG_NVRAM
pmac_nvram_update();
+#endif
switch (sys_ctrler) {
#ifdef CONFIG_ADB_CUDA
@@ -509,7 +511,7 @@ pmac_restart(char *cmd)
pmu_restart();
break;
#endif /* CONFIG_ADB_PMU */
- default:
+ default: ;
}
}
@@ -520,7 +522,9 @@ pmac_power_off(void)
struct adb_request req;
#endif /* CONFIG_ADB_CUDA */
+#ifdef CONFIG_NVRAM
pmac_nvram_update();
+#endif
switch (sys_ctrler) {
#ifdef CONFIG_ADB_CUDA
@@ -536,7 +540,7 @@ pmac_power_off(void)
pmu_shutdown();
break;
#endif /* CONFIG_ADB_PMU */
- default:
+ default: ;
}
}
@@ -566,17 +570,19 @@ pmac_ide_outsw(ide_ioreg_t port, void *buf, int ns)
int
pmac_ide_default_irq(ide_ioreg_t base)
{
- return 0;
-}
-
#if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC)
-extern ide_ioreg_t pmac_ide_get_base(int index);
+ extern int pmac_ide_get_irq(ide_ioreg_t base);
+ return pmac_ide_get_irq(base);
+#else
+ return 0;
#endif
+}
ide_ioreg_t
pmac_ide_default_io_base(int index)
{
#if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC)
+ extern ide_ioreg_t pmac_ide_get_base(int index);
return pmac_ide_get_base(index);
#else
return 0;
@@ -586,7 +592,14 @@ pmac_ide_default_io_base(int index)
int
pmac_ide_check_region(ide_ioreg_t from, unsigned int extent)
{
- return 0;
+ /*
+ * We only do the check_region if `from' looks like a genuine
+ * I/O port number. If it actually refers to a memory-mapped
+ * register, it should be OK.
+ */
+ if (from < ~_IO_BASE)
+ return 0;
+ return check_region(from, extent);
}
void
@@ -594,24 +607,16 @@ pmac_ide_request_region(ide_ioreg_t from,
unsigned int extent,
const char *name)
{
+ if (from < ~_IO_BASE)
+ request_region(from, extent, name);
}
void
pmac_ide_release_region(ide_ioreg_t from,
unsigned int extent)
{
-}
-
-/* Convert the shorts/longs in hd_driveid from little to big endian;
- * chars are endian independant, of course, but strings need to be flipped.
- * (Despite what it says in drivers/block/ide.h, they come up as little
- * endian...)
- *
- * Changes to linux/hdreg.h may require changes here. */
-void
-pmac_ide_fix_driveid(struct hd_driveid *id)
-{
- ppc_generic_ide_fix_driveid(id);
+ if (from < ~_IO_BASE)
+ release_region(from, extent);
}
#if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC)
@@ -632,8 +637,6 @@ void __init
pmac_init(unsigned long r3, unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7)
{
- pmac_setup_pci_ptrs();
-
/* isa_io_base gets set in pmac_find_bridges */
isa_mem_base = PMAC_ISA_MEM_BASE;
pci_dram_offset = PMAC_PCI_DRAM_OFFSET;
@@ -646,8 +649,11 @@ pmac_init(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_md.get_cpuinfo = pmac_get_cpuinfo;
ppc_md.irq_cannonicalize = NULL;
ppc_md.init_IRQ = pmac_pic_init;
- ppc_md.get_irq = pmac_get_irq;
+ ppc_md.get_irq = pmac_get_irq; /* Changed later on ... */
ppc_md.init = pmac_init2;
+
+ ppc_md.pcibios_fixup = pmac_pcibios_fixup;
+ ppc_md.pcibios_enable_device_hook = pmac_pci_enable_device_hook;
ppc_md.restart = pmac_restart;
ppc_md.power_off = pmac_power_off;
@@ -658,12 +664,8 @@ pmac_init(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_md.get_rtc_time = pmac_get_rtc_time;
ppc_md.calibrate_decr = pmac_calibrate_decr;
- ppc_md.pci_dev_io_base = pmac_pci_dev_io_base;
- ppc_md.pci_dev_mem_base = pmac_pci_dev_mem_base;
- ppc_md.pci_dev_root_bridge = pmac_pci_dev_root_bridge;
-
#ifdef CONFIG_VT
-#ifdef CONFIG_INPUT_ADBHID
+#ifdef CONFIG_INPUT
ppc_md.kbd_init_hw = mac_hid_init_hw;
ppc_md.kbd_translate = mac_hid_kbd_translate;
ppc_md.kbd_unexpected_up = mac_hid_kbd_unexpected_up;
@@ -682,35 +684,33 @@ pmac_init(unsigned long r3, unsigned long r4, unsigned long r5,
}
#endif /* CONFIG_MAGIC_SYSRQ */
#elif defined(CONFIG_ADB_KEYBOARD)
- ppc_md.kbd_setkeycode = mackbd_setkeycode;
- ppc_md.kbd_getkeycode = mackbd_getkeycode;
- ppc_md.kbd_translate = mackbd_translate;
- ppc_md.kbd_unexpected_up = mackbd_unexpected_up;
- ppc_md.kbd_leds = mackbd_leds;
- ppc_md.kbd_init_hw = mackbd_init_hw;
+ ppc_md.kbd_setkeycode = mackbd_setkeycode;
+ ppc_md.kbd_getkeycode = mackbd_getkeycode;
+ ppc_md.kbd_translate = mackbd_translate;
+ ppc_md.kbd_unexpected_up = mackbd_unexpected_up;
+ ppc_md.kbd_leds = mackbd_leds;
+ ppc_md.kbd_init_hw = mackbd_init_hw;
#ifdef CONFIG_MAGIC_SYSRQ
- ppc_md.ppc_kbd_sysrq_xlate = mackbd_sysrq_xlate;
+ ppc_md.ppc_kbd_sysrq_xlate = mackbd_sysrq_xlate;
SYSRQ_KEY = 0x69;
#endif /* CONFIG_MAGIC_SYSRQ */
#endif /* CONFIG_INPUT_ADBHID/CONFIG_ADB_KEYBOARD */
#endif /* CONFIG_VT */
#if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC)
- ppc_ide_md.insw = pmac_ide_insw;
- ppc_ide_md.outsw = pmac_ide_outsw;
- ppc_ide_md.default_irq = pmac_ide_default_irq;
- ppc_ide_md.default_io_base = pmac_ide_default_io_base;
- ppc_ide_md.ide_check_region = pmac_ide_check_region;
- ppc_ide_md.ide_request_region = pmac_ide_request_region;
- ppc_ide_md.ide_release_region = pmac_ide_release_region;
- ppc_ide_md.fix_driveid = pmac_ide_fix_driveid;
- ppc_ide_md.ide_init_hwif = pmac_ide_init_hwif_ports;
-
- ppc_ide_md.io_base = _IO_BASE; /* actually too early for this :-( */
-#endif
+ ppc_ide_md.insw = pmac_ide_insw;
+ ppc_ide_md.outsw = pmac_ide_outsw;
+ ppc_ide_md.default_irq = pmac_ide_default_irq;
+ ppc_ide_md.default_io_base = pmac_ide_default_io_base;
+ ppc_ide_md.ide_check_region = pmac_ide_check_region;
+ ppc_ide_md.ide_request_region = pmac_ide_request_region;
+ ppc_ide_md.ide_release_region = pmac_ide_release_region;
+ ppc_ide_md.fix_driveid = ppc_generic_ide_fix_driveid;
+ ppc_ide_md.ide_init_hwif = pmac_ide_init_hwif_ports;
+#endif /* CONFIG_BLK_DEV_IDE && CONFIG_BLK_DEV_IDE_PMAC */
#ifdef CONFIG_BOOTX_TEXT
ppc_md.progress = pmac_progress;
-#endif
+#endif /* CONFIG_BOOTX_TEXT */
if (ppc_md.progress) ppc_md.progress("pmac_init(): exit", 0);
}
@@ -727,5 +727,5 @@ pmac_progress(char *s, unsigned short hex)
prom_drawstring(s);
prom_drawchar('\n');
}
-#endif CONFIG_BOOTX_TEXT
+#endif /* CONFIG_BOOTX_TEXT */
diff --git a/arch/ppc/kernel/pmac_time.c b/arch/ppc/kernel/pmac_time.c
index 00b6302a7..46d067e81 100644
--- a/arch/ppc/kernel/pmac_time.c
+++ b/arch/ppc/kernel/pmac_time.c
@@ -114,7 +114,7 @@ unsigned long pmac_get_rtc_time(void)
+ (req.reply[3] << 8) + req.reply[4];
return now - RTC_OFFSET;
#endif /* CONFIG_ADB_PMU */
- default:
+ default: ;
}
return 0;
}
@@ -135,7 +135,7 @@ int pmac_set_rtc_time(unsigned long nowtime)
return 0;
while (!req.complete)
cuda_poll();
-// if (req.reply_len != 7)
+ if ((req.reply_len != 3) && (req.reply_len != 7))
printk(KERN_ERR "pmac_set_rtc_time: got %d byte reply\n",
req.reply_len);
return 1;
diff --git a/arch/ppc/kernel/ppc_asm.h b/arch/ppc/kernel/ppc_asm.h
index 42b8c9c39..59c377c4d 100644
--- a/arch/ppc/kernel/ppc_asm.h
+++ b/arch/ppc/kernel/ppc_asm.h
@@ -50,7 +50,7 @@
*/
#define LVX(r,a,b) .long (31<<26)+((r)<<21)+((a)<<16)+((b)<<11)+(103<<1)
#define STVX(r,a,b) .long (31<<26)+((r)<<21)+((a)<<16)+((b)<<11)+(231<<1)
-#define MFVSCR(r) .long (4<<26)+((r)<<21)+(1540<<1)
+#define MFVSCR(r) .long (4<<26)+((r)<<21)+(770<<1)
#define MTVSCR(r) .long (4<<26)+((r)<<11)+(802<<1)
#define SAVE_VR(n,b,base) li b,THREAD_VR0+(16*(n)); STVX(n,b,base)
@@ -66,9 +66,13 @@
#define REST_16VR(n,b,base) REST_8VR(n,b,base); REST_8VR(n+8,b,base)
#define REST_32VR(n,b,base) REST_16VR(n,b,base); REST_16VR(n+16,b,base)
+#ifdef CONFIG_PPC601_SYNC_FIX
#define SYNC \
sync; \
isync
+#else
+#define SYNC
+#endif
/*
* This instruction is not implemented on the PPC 603 or 601; however, on
diff --git a/arch/ppc/kernel/ppc_htab.c b/arch/ppc/kernel/ppc_htab.c
index 32f99ce0e..9768f2890 100644
--- a/arch/ppc/kernel/ppc_htab.c
+++ b/arch/ppc/kernel/ppc_htab.c
@@ -555,10 +555,7 @@ int proc_dol2crvec(ctl_table *table, int write, struct file *filp,
break;
buffer += len;
left -= len;
- _set_L2CR(0);
_set_L2CR(val);
- while ( _get_L2CR() & 0x1 )
- /* wait for invalidate to finish */;
} else {
p = buf;
diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c
index 827e37540..6de2d94fe 100644
--- a/arch/ppc/kernel/ppc_ksyms.c
+++ b/arch/ppc/kernel/ppc_ksyms.c
@@ -12,6 +12,7 @@
#include <linux/console.h>
#include <linux/irq.h>
#include <linux/pci.h>
+#include <linux/delay.h>
#include <asm/page.h>
#include <asm/semaphore.h>
@@ -40,6 +41,7 @@
#include <asm/backlight.h>
#ifdef CONFIG_SMP
#include <asm/smplock.h>
+#include <asm/smp.h>
#endif /* CONFIG_SMP */
#include <asm/time.h>
@@ -53,9 +55,10 @@ extern void MachineCheckException(struct pt_regs *regs);
extern void AlignmentException(struct pt_regs *regs);
extern void ProgramCheckException(struct pt_regs *regs);
extern void SingleStepException(struct pt_regs *regs);
-extern int sys_sigreturn(struct pt_regs *regs);
extern void do_lost_interrupts(unsigned long);
extern int do_signal(sigset_t *, struct pt_regs *);
+extern int pmac_newworld;
+extern int sys_sigreturn(struct pt_regs *regs);
long long __ashrdi3(long long, int);
long long __ashldi3(long long, int);
@@ -98,10 +101,6 @@ EXPORT_SYMBOL(_prep_type);
EXPORT_SYMBOL(ucSystemType);
#endif
#endif
-#ifdef CONFIG_PCI
-EXPORT_SYMBOL(pci_dev_io_base);
-EXPORT_SYMBOL(pci_dev_mem_base);
-#endif
#if !__INLINE_BITOPS
EXPORT_SYMBOL(set_bit);
@@ -125,6 +124,7 @@ EXPORT_SYMBOL(strlen);
EXPORT_SYMBOL(strnlen);
EXPORT_SYMBOL(strcmp);
EXPORT_SYMBOL(strncmp);
+EXPORT_SYMBOL(strcasecmp);
/* EXPORT_SYMBOL(csum_partial); already in net/netsyms.c */
EXPORT_SYMBOL(csum_partial_copy_generic);
@@ -202,6 +202,10 @@ EXPORT_SYMBOL(_read_lock);
EXPORT_SYMBOL(_read_unlock);
EXPORT_SYMBOL(_write_lock);
EXPORT_SYMBOL(_write_unlock);
+EXPORT_SYMBOL(smp_call_function);
+EXPORT_SYMBOL(smp_hw_index);
+EXPORT_SYMBOL(smp_num_cpus);
+EXPORT_SYMBOL(synchronize_irq);
#endif
#ifndef CONFIG_MACH_SPECIFIC
@@ -234,12 +238,14 @@ EXPORT_SYMBOL(pmu_enable_irled);
#ifdef CONFIG_PMAC_BACKLIGHT
EXPORT_SYMBOL(get_backlight_level);
EXPORT_SYMBOL(set_backlight_level);
+EXPORT_SYMBOL(set_backlight_enable);
+EXPORT_SYMBOL(register_backlight_controller);
#endif /* CONFIG_PMAC_BACKLIGHT */
-#if defined(CONFIG_ALL_PPC)
EXPORT_SYMBOL_NOVERS(sys_ctrler);
#ifndef CONFIG_MACH_SPECIFIC
EXPORT_SYMBOL_NOVERS(have_of);
#endif /* CONFIG_MACH_SPECIFIC */
+#if defined(CONFIG_ALL_PPC)
EXPORT_SYMBOL(find_devices);
EXPORT_SYMBOL(find_type_devices);
EXPORT_SYMBOL(find_compatible_devices);
@@ -247,18 +253,29 @@ EXPORT_SYMBOL(find_path_device);
EXPORT_SYMBOL(find_phandle);
EXPORT_SYMBOL(device_is_compatible);
EXPORT_SYMBOL(machine_is_compatible);
-EXPORT_SYMBOL(find_pci_device_OFnode);
EXPORT_SYMBOL(find_all_nodes);
EXPORT_SYMBOL(get_property);
-EXPORT_SYMBOL(pci_io_base);
-EXPORT_SYMBOL(pci_device_loc);
+EXPORT_SYMBOL(pci_bus_io_base);
+EXPORT_SYMBOL(pci_bus_io_base_phys);
+EXPORT_SYMBOL(pci_bus_mem_base_phys);
+EXPORT_SYMBOL(pci_device_to_OF_node);
+EXPORT_SYMBOL(pci_device_from_OF_node);
+EXPORT_SYMBOL(pci_bus_to_hose);
+EXPORT_SYMBOL(pci_resource_to_bus);
+EXPORT_SYMBOL(pci_phys_to_bus);
+EXPORT_SYMBOL(pci_bus_to_phys);
+EXPORT_SYMBOL(pmac_newworld);
EXPORT_SYMBOL(feature_set);
EXPORT_SYMBOL(feature_clear);
EXPORT_SYMBOL(feature_test);
EXPORT_SYMBOL(feature_set_gmac_power);
+EXPORT_SYMBOL(feature_set_gmac_phy_reset);
EXPORT_SYMBOL(feature_set_usb_power);
EXPORT_SYMBOL(feature_set_firewire_power);
#endif /* defined(CONFIG_ALL_PPC) */
+#if defined(CONFIG_BOOTX_TEXT)
+EXPORT_SYMBOL(bootx_update_display);
+#endif
#if defined(CONFIG_SCSI) && defined(CONFIG_ALL_PPC)
EXPORT_SYMBOL(note_scsi_host);
#endif
@@ -286,6 +303,7 @@ EXPORT_SYMBOL(abs);
EXPORT_SYMBOL(screen_info);
#endif
+EXPORT_SYMBOL(__delay);
EXPORT_SYMBOL(int_control);
EXPORT_SYMBOL(timer_interrupt_intercept);
EXPORT_SYMBOL(timer_interrupt);
@@ -300,6 +318,10 @@ EXPORT_SYMBOL(console_lock);
#ifdef CONFIG_XMON
EXPORT_SYMBOL(xmon);
#endif
+EXPORT_SYMBOL(__up);
+EXPORT_SYMBOL(__down);
+EXPORT_SYMBOL(__down_interruptible);
+EXPORT_SYMBOL(__down_trylock);
EXPORT_SYMBOL(down_read_failed);
EXPORT_SYMBOL(down_write_failed);
@@ -324,6 +346,12 @@ EXPORT_SYMBOL(do_softirq);
EXPORT_SYMBOL(next_mmu_context);
EXPORT_SYMBOL(set_context);
EXPORT_SYMBOL(mmu_context_overflow);
+#if !defined(CONFIG_8xx) && !defined(CONFIG_4xx)
+extern long *intercept_table;
+EXPORT_SYMBOL(intercept_table);
+#endif
+extern long *ret_from_intercept;
+EXPORT_SYMBOL(ret_from_intercept);
#ifdef CONFIG_MOL
extern ulong mol_interface[];
diff --git a/arch/ppc/kernel/prep_nvram.c b/arch/ppc/kernel/prep_nvram.c
index c3dcdea07..3d34a853f 100644
--- a/arch/ppc/kernel/prep_nvram.c
+++ b/arch/ppc/kernel/prep_nvram.c
@@ -16,19 +16,9 @@
#include <asm/machdep.h>
#include <asm/prep_nvram.h>
-/*
- * Allow for a maximum of 32K of PReP NvRAM data
- */
-#define MAX_PREP_NVRAM 0x8000
static char nvramData[MAX_PREP_NVRAM];
static NVRAM_MAP *nvram=(NVRAM_MAP *)&nvramData[0];
-#define PREP_NVRAM_AS0 0x74
-#define PREP_NVRAM_AS1 0x75
-#define PREP_NVRAM_DATA 0x77
-
-unsigned char *rs_pcNvRAM;
-
unsigned char __prep prep_nvram_read_val(int addr)
{
outb(addr, PREP_NVRAM_AS0);
@@ -44,20 +34,6 @@ void __prep prep_nvram_write_val(int addr,
outb(val, PREP_NVRAM_DATA);
}
-/*
- * Most Radstone boards have NvRAM memory mapped at offset 8M in ISA space
- */
-unsigned char __prep rs_nvram_read_val(int addr)
-{
- return rs_pcNvRAM[addr];
-}
-
-void __prep rs_nvram_write_val(int addr,
- unsigned char val)
-{
- rs_pcNvRAM[addr]=val;
-}
-
void __init init_prep_nvram(void)
{
unsigned char *nvp;
@@ -65,16 +41,6 @@ void __init init_prep_nvram(void)
int nvramSize;
/*
- * I'm making the assumption that 32k will always cover the
- * nvramsize. If this isn't the case please let me know and we can
- * map the header, then get the size from the header, then map
- * the whole size. -- Cort
- */
- if ( _prep_type == _PREP_Radstone )
- rs_pcNvRAM = (unsigned char *)ioremap(_ISA_MEM_BASE+0x00800000,
- 32<<10);
- request_region(PREP_NVRAM_AS0, 0x8, "PReP NVRAM");
- /*
* The following could fail if the NvRAM were corrupt but
* we expect the boot firmware to have checked its checksum
* before boot
diff --git a/arch/ppc/kernel/prep_pci.c b/arch/ppc/kernel/prep_pci.c
index fd14fc483..2f556d83d 100644
--- a/arch/ppc/kernel/prep_pci.c
+++ b/arch/ppc/kernel/prep_pci.c
@@ -7,11 +7,11 @@
* The motherboard routes/maps will disappear shortly. -- Cort
*/
+#include <linux/config.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/openpic.h>
#include <asm/init.h>
#include <asm/byteorder.h>
@@ -25,6 +25,7 @@
#include <asm/machdep.h>
#include "pci.h"
+#include "open_pic.h"
#define MAX_DEVNR 22
@@ -39,9 +40,6 @@ unsigned char *Motherboard_routes;
/* Used for Motorola to store system config register */
static unsigned long *ProcInfo;
-extern int chrp_get_irq(struct pt_regs *);
-extern void chrp_post_irq(struct pt_regs* regs, int);
-
/* Tables for known hardware */
/* Motorola PowerStackII - Utah */
@@ -534,128 +532,45 @@ static char Nobis_pci_IRQ_routes[] __prepdata = {
#define CFGPTR(dev) (0x80800000 | (1<<(dev>>3)) | ((dev&7)<<8) | offset)
#define DEVNO(dev) (dev>>3)
-__prep
-int
-prep_pcibios_read_config_dword (unsigned char bus,
- unsigned char dev, unsigned char offset, unsigned int *val)
-{
- unsigned long _val;
- unsigned long *ptr;
-
- if ((bus != 0) || (DEVNO(dev) > MAX_DEVNR))
- {
- *val = 0xFFFFFFFF;
- return PCIBIOS_DEVICE_NOT_FOUND;
- } else
- {
- ptr = (unsigned long *)CFGPTR(dev);
- _val = le32_to_cpu(*ptr);
- }
- *val = _val;
- return PCIBIOS_SUCCESSFUL;
-}
-
-__prep
-int
-prep_pcibios_read_config_word (unsigned char bus,
- unsigned char dev, unsigned char offset, unsigned short *val)
-{
- unsigned short _val;
- unsigned short *ptr;
-
- if ((bus != 0) || (DEVNO(dev) > MAX_DEVNR))
- {
- *val = 0xFFFF;
- return PCIBIOS_DEVICE_NOT_FOUND;
- } else
- {
- ptr = (unsigned short *)CFGPTR(dev);
- _val = le16_to_cpu(*ptr);
- }
- *val = _val;
- return PCIBIOS_SUCCESSFUL;
-}
-
-__prep
-int
-prep_pcibios_read_config_byte (unsigned char bus,
- unsigned char dev, unsigned char offset, unsigned char *val)
-{
- unsigned char _val;
- unsigned char *ptr;
-
- if ((bus != 0) || (DEVNO(dev) > MAX_DEVNR))
- {
- *val = 0xFF;
- return PCIBIOS_DEVICE_NOT_FOUND;
- } else
- {
- ptr = (unsigned char *)CFGPTR(dev);
- _val = *ptr;
- }
- *val = _val;
- return PCIBIOS_SUCCESSFUL;
-}
-
-__prep
-int
-prep_pcibios_write_config_dword (unsigned char bus,
- unsigned char dev, unsigned char offset, unsigned int val)
-{
- unsigned long _val;
- unsigned long *ptr;
-
- _val = le32_to_cpu(val);
- if ((bus != 0) || (DEVNO(dev) > MAX_DEVNR))
- {
- return PCIBIOS_DEVICE_NOT_FOUND;
- } else
- {
- ptr = (unsigned long *)CFGPTR(dev);
- *ptr = _val;
- }
- return PCIBIOS_SUCCESSFUL;
+#define cfg_read(val, addr, type, op) *val = op((type)(addr))
+#define cfg_write(val, addr, type, op) op((type *)(addr), (val))
+
+#define cfg_read_bad(val, size) *val = bad_##size;
+#define cfg_write_bad(val, size)
+
+#define bad_byte 0xff
+#define bad_word 0xffff
+#define bad_dword 0xffffffffU
+
+#define PREP_PCI_OP(rw, size, type, op) \
+static int __prep \
+prep_##rw##_config_##size(struct pci_dev *dev, int offset, type val) \
+{ \
+ if ((dev->bus->number != 0) || (DEVNO(dev->devfn) > MAX_DEVNR)) \
+ { \
+ cfg_##rw##_bad(val, size) \
+ return PCIBIOS_DEVICE_NOT_FOUND; \
+ } \
+ cfg_##rw(val, CFGPTR(dev->devfn), type, op); \
+ return PCIBIOS_SUCCESSFUL; \
}
-__prep
-int
-prep_pcibios_write_config_word (unsigned char bus,
- unsigned char dev, unsigned char offset, unsigned short val)
-{
- unsigned short _val;
- unsigned short *ptr;
-
- _val = le16_to_cpu(val);
- if ((bus != 0) || (DEVNO(dev) > MAX_DEVNR))
- {
- return PCIBIOS_DEVICE_NOT_FOUND;
- } else
- {
- ptr = (unsigned short *)CFGPTR(dev);
- *ptr = _val;
- }
- return PCIBIOS_SUCCESSFUL;
-}
+PREP_PCI_OP(read, byte, u8 *, in_8)
+PREP_PCI_OP(read, word, u16 *, in_le16)
+PREP_PCI_OP(read, dword, u32 *, in_le32)
+PREP_PCI_OP(write, byte, u8, out_8)
+PREP_PCI_OP(write, word, u16, out_le16)
+PREP_PCI_OP(write, dword, u32, out_le32)
-__prep
-int
-prep_pcibios_write_config_byte (unsigned char bus,
- unsigned char dev, unsigned char offset, unsigned char val)
+static struct pci_ops prep_pci_ops =
{
- unsigned char _val;
- unsigned char *ptr;
-
- _val = val;
- if ((bus != 0) || (DEVNO(dev) > MAX_DEVNR))
- {
- return PCIBIOS_DEVICE_NOT_FOUND;
- } else
- {
- ptr = (unsigned char *)CFGPTR(dev);
- *ptr = _val;
- }
- return PCIBIOS_SUCCESSFUL;
-}
+ prep_read_config_byte,
+ prep_read_config_word,
+ prep_read_config_dword,
+ prep_write_config_byte,
+ prep_write_config_word,
+ prep_write_config_dword
+};
#define MOTOROLA_CPUTYPE_REG 0x800
#define MOTOROLA_BASETYPE_REG 0x803
@@ -685,7 +600,8 @@ static u_char mvme2600_openpic_initsenses[] __initdata = {
#define MOT_HAWK_PRESENT 0x2
int prep_keybd_present = 1;
-int MotMPIC = 0;
+int MotMPIC;
+int mot_multi;
int __init raven_init(void)
{
@@ -695,18 +611,18 @@ int __init raven_init(void)
/* Check to see if the Raven chip exists. */
if ( _prep_type != _PREP_Motorola) {
- OpenPIC = NULL;
+ OpenPIC_Addr = NULL;
return 0;
}
/* Check to see if this board is a type that might have a Raven. */
if ((inb(MOTOROLA_CPUTYPE_REG) & 0xF0) != 0xE0) {
- OpenPIC = NULL;
+ OpenPIC_Addr = NULL;
return 0;
}
/* Check the first PCI device to see if it is a Raven. */
- pcibios_read_config_dword(0, 0, PCI_VENDOR_ID, &devid);
+ early_read_config_dword(0, 0, 0, PCI_VENDOR_ID, &devid);
switch (devid & 0xffff0000) {
case MPIC_RAVEN_ID:
@@ -716,33 +632,37 @@ int __init raven_init(void)
MotMPIC = MOT_HAWK_PRESENT;
break;
default:
- OpenPIC = NULL;
+ OpenPIC_Addr = NULL;
return 0;
}
/* Read the memory base register. */
- pcibios_read_config_dword(0, 0, PCI_BASE_ADDRESS_1, &pci_membase);
+ early_read_config_dword(0, 0, 0, PCI_BASE_ADDRESS_1, &pci_membase);
if (pci_membase == 0) {
- OpenPIC = NULL;
+ OpenPIC_Addr = NULL;
return 0;
}
/* Map the Raven MPIC registers to virtual memory. */
- OpenPIC = (struct OpenPIC *)ioremap(pci_membase+0xC0000000, 0x22000);
+ OpenPIC_Addr = ioremap(pci_membase+0xC0000000, 0x22000);
OpenPIC_InitSenses = mvme2600_openpic_initsenses;
OpenPIC_NumInitSenses = sizeof(mvme2600_openpic_initsenses);
- ppc_md.get_irq = chrp_get_irq;
- ppc_md.post_irq = chrp_post_irq;
+ ppc_md.get_irq = openpic_get_irq;
/* If raven is present on Motorola store the system config register
* for later use.
*/
ProcInfo = (unsigned long *)ioremap(0xfef80400, 4);
+ /* Indicate to system if this is a multiprocessor board */
+ if (!(*ProcInfo & MOT_PROC2_BIT)) {
+ mot_multi = 1;
+ }
+
/* This is a hack. If this is a 2300 or 2400 mot board then there is
* no keyboard controller and we have to indicate that.
*/
@@ -898,72 +818,8 @@ unsigned long __init prep_route_pci_interrupts(void)
outb(pl_id|CAROLINA_IRQ_EDGE_MASK_HI, 0x04d1);
pl_id=inb(0x04d1);
/*printk("Hi mask now %#0x\n", pl_id);*/
- } else if ( _prep_type == _PREP_Radstone )
- {
- unsigned char ucElcrM, ucElcrS;
-
- /*
- * Set up edge/level
- */
- switch(ucSystemType)
- {
- case RS_SYS_TYPE_PPC1:
- {
- if(ucBoardRevMaj<5)
- {
- ucElcrS=ELCRS_INT15_LVL;
- }
- else
- {
- ucElcrS=ELCRS_INT9_LVL |
- ELCRS_INT11_LVL |
- ELCRS_INT14_LVL |
- ELCRS_INT15_LVL;
- }
- ucElcrM=ELCRM_INT5_LVL | ELCRM_INT7_LVL;
- break;
- }
-
- case RS_SYS_TYPE_PPC1a:
- {
- ucElcrS=ELCRS_INT9_LVL |
- ELCRS_INT11_LVL |
- ELCRS_INT14_LVL |
- ELCRS_INT15_LVL;
- ucElcrM=ELCRM_INT5_LVL;
- break;
- }
-
- case RS_SYS_TYPE_PPC2:
- case RS_SYS_TYPE_PPC2a:
- case RS_SYS_TYPE_PPC2ep:
- case RS_SYS_TYPE_PPC4:
- case RS_SYS_TYPE_PPC4a:
- default:
- {
- ucElcrS=ELCRS_INT9_LVL |
- ELCRS_INT10_LVL |
- ELCRS_INT11_LVL |
- ELCRS_INT14_LVL |
- ELCRS_INT15_LVL;
- ucElcrM=ELCRM_INT5_LVL |
- ELCRM_INT7_LVL;
- break;
- }
- }
-
- /*
- * Write edge/level selection
- */
- outb(ucElcrS, ISA8259_S_ELCR);
- outb(ucElcrM, ISA8259_M_ELCR);
-
- /*
- * Radstone boards have PCI interrupts all set up
- * so leave well alone
- */
- return 0;
- } else
+ }
+ else
{
printk("No known machine pci routing!\n");
return -1;
@@ -987,16 +843,10 @@ prep_pcibios_fixup(void)
extern unsigned char *Motherboard_routes;
unsigned char i;
- if ( _prep_type == _PREP_Radstone )
- {
- printk("Radstone boards require no PCI fixups\n");
- return;
- }
-
prep_route_pci_interrupts();
printk("Setting PCI interrupts for a \"%s\"\n", Motherboard_map_name);
- if (OpenPIC) {
+ if (OpenPIC_Addr) {
/* PCI interrupts are controlled by the OpenPIC */
pci_for_each_dev(dev) {
if (dev->bus->number == 0) {
@@ -1018,7 +868,12 @@ prep_pcibios_fixup(void)
for ( i = 0 ; i <= 5 ; i++ )
{
- if ( dev->resource[i].start > 0x10000000 )
+ /*
+ * Relocate PCI I/O resources if necessary so the
+ * standard 256MB BAT covers them.
+ */
+ if ( (pci_resource_flags(dev, i) & IORESOURCE_IO) &&
+ (dev->resource[i].start > 0x10000000) )
{
printk("Relocating PCI address %lx -> %lx\n",
dev->resource[i].start,
@@ -1029,6 +884,8 @@ prep_pcibios_fixup(void)
pci_write_config_dword(dev,
PCI_BASE_ADDRESS_0+(i*0x4),
dev->resource[i].start );
+ dev->resource[i].end =
+ (dev->resource[i].end & 0x00FFFFFF) | 0x01000000;
}
}
#if 0
@@ -1043,49 +900,50 @@ prep_pcibios_fixup(void)
}
}
-decl_config_access_method(indirect);
-
void __init
-prep_setup_pci_ptrs(void)
+prep_find_bridges(void)
{
- PPC_DEVICE *hostbridge;
-
- printk("PReP architecture\n");
- if ( _prep_type == _PREP_Radstone )
- {
- pci_config_address = (unsigned *)0x80000cf8;
- pci_config_data = (char *)0x80000cfc;
- set_config_access_method(indirect);
- }
- else
- {
- hostbridge = residual_find_device(PROCESSORDEVICE, NULL,
- BridgeController, PCIBridge, -1, 0);
- if (hostbridge &&
- hostbridge->DeviceId.Interface == PCIBridgeIndirect) {
- PnP_TAG_PACKET * pkt;
- set_config_access_method(indirect);
- pkt = PnP_find_large_vendor_packet(
+ struct pci_controller* hose;
+
+ hose = pcibios_alloc_controller();
+ if (!hose)
+ return;
+
+ hose->first_busno = 0;
+ hose->last_busno = 0xff;
+ hose->pci_mem_offset = PREP_ISA_MEM_BASE;
+
+ printk("PReP architecture\n");
+ {
+#ifdef CONFIG_PREP_RESIDUAL
+ PPC_DEVICE *hostbridge;
+
+ hostbridge = residual_find_device(PROCESSORDEVICE, NULL,
+ BridgeController, PCIBridge, -1, 0);
+ if (hostbridge &&
+ hostbridge->DeviceId.Interface == PCIBridgeIndirect) {
+ PnP_TAG_PACKET * pkt;
+ pkt = PnP_find_large_vendor_packet(
res->DevicePnPHeap+hostbridge->AllocatedOffset,
3, 0);
- if(pkt)
+ if(pkt)
{
#define p pkt->L4_Pack.L4_Data.L4_PPCPack
- pci_config_address= (unsigned *)ld_le32((unsigned *) p.PPCData);
- pci_config_data= (unsigned char *)ld_le32((unsigned *) (p.PPCData+8));
- }
+ setup_indirect_pci(hose,
+ ld_le32((unsigned *) (p.PPCData)),
+ ld_le32((unsigned *) (p.PPCData+8)));
+ }
else
{
- pci_config_address= (unsigned *) 0x80000cf8;
- pci_config_data= (unsigned char *) 0x80000cfc;
- }
- }
+ setup_indirect_pci(hose, 0x80000cf8, 0x80000cfc);
+ }
+ }
else
+#endif /* CONFIG_PREP_RESIDUAL */
{
- set_config_access_method(prep);
- }
-
- }
+ hose->ops = &prep_pci_ops;
+ }
+ }
ppc_md.pcibios_fixup = prep_pcibios_fixup;
}
diff --git a/arch/ppc/kernel/prep_setup.c b/arch/ppc/kernel/prep_setup.c
index 6e30462aa..64ad519cb 100644
--- a/arch/ppc/kernel/prep_setup.c
+++ b/arch/ppc/kernel/prep_setup.c
@@ -32,7 +32,6 @@
#include <linux/console.h>
#include <linux/timex.h>
#include <linux/pci.h>
-#include <linux/openpic.h>
#include <linux/ide.h>
#include <asm/init.h>
@@ -48,8 +47,9 @@
#include <asm/prep_nvram.h>
#include <asm/raven.h>
#include <asm/keyboard.h>
-
+#include <asm/vga.h>
#include <asm/time.h>
+
#include "local_irq.h"
#include "i8259.h"
#include "open_pic.h"
@@ -84,7 +84,7 @@ extern void pckbd_leds(unsigned char leds);
extern void pckbd_init_hw(void);
extern unsigned char pckbd_sysrq_xlate[128];
-extern void prep_setup_pci_ptrs(void);
+extern void prep_find_bridges(void);
extern char saved_command_line[256];
int _prep_type;
@@ -101,23 +101,23 @@ unsigned long empty_zero_page[1024];
extern PTE *Hash, *Hash_end;
extern unsigned long Hash_size, Hash_mask;
extern int probingmem;
-extern unsigned long loops_per_sec;
+extern unsigned long loops_per_jiffy;
#ifdef CONFIG_BLK_DEV_RAM
extern int rd_doload; /* 1 = load ramdisk, 0 = don't load */
extern int rd_prompt; /* 1 = prompt for ramdisk, 0 = don't prompt */
extern int rd_image_start; /* starting block # of image */
#endif
-#ifdef CONFIG_VGA_CONSOLE
-unsigned long vgacon_remap_base;
-#endif
int __prep
prep_get_cpuinfo(char *buffer)
{
extern char *Motherboard_map_name;
- int len, i;
-
+ int len;
+#ifdef CONFIG_PREP_RESIDUAL
+ int i;
+#endif
+
#ifdef CONFIG_SMP
#define CD(X) (cpu_data[n].X)
#else
@@ -190,7 +190,10 @@ prep_get_cpuinfo(char *buffer)
}
-no_l2:
+no_l2:
+#ifndef CONFIG_PREP_RESIDUAL
+ return len;
+#else
if ( res->ResidualLength == 0 )
return len;
@@ -205,8 +208,8 @@ no_l2:
res->Memories[i].SIMMSize);
}
len += sprintf(buffer+len,"\n");
-
return len;
+#endif
}
void __init
@@ -214,11 +217,16 @@ prep_setup_arch(void)
{
extern char cmd_line[];
unsigned char reg;
+#if 0 /* unused?? */
unsigned char ucMothMemType;
unsigned char ucEquipPres1;
+#endif
/* init to some ~sane value until calibrate_delay() runs */
- loops_per_sec = 50000000;
+ loops_per_jiffy = 50000000;
+
+ /* Lookup PCI host bridges */
+ prep_find_bridges();
/* Set up floppy in PS/2 mode */
outb(0x09, SIO_CONFIG_RA);
@@ -247,41 +255,6 @@ prep_setup_arch(void)
*(unsigned char *)(0x8000081c) |= 3;
ROOT_DEV = to_kdev_t(0x0802); /* sda2 */
break;
- case _PREP_Radstone:
- ROOT_DEV = to_kdev_t(0x0801); /* sda1 */
-
- /*
- * Determine system type
- */
- ucMothMemType=inb(0x866);
- ucEquipPres1=inb(0x80c);
-
- ucSystemType=((ucMothMemType&0x03)<<1) |
- ((ucEquipPres1&0x80)>>7);
- ucSystemType^=7;
-
- /*
- * Determine board revision for use by
- * rev. specific code
- */
- ucBoardRev=inb(0x854);
- ucBoardRevMaj=ucBoardRev>>5;
- ucBoardRevMin=ucBoardRev&0x1f;
-
- /*
- * Most Radstone boards have memory mapped NvRAM
- */
- if((ucSystemType==RS_SYS_TYPE_PPC1) && (ucBoardRevMaj<5))
- {
- ppc_md.nvram_read_val = prep_nvram_read_val;
- ppc_md.nvram_write_val = prep_nvram_write_val;
- }
- else
- {
- ppc_md.nvram_read_val = rs_nvram_read_val;
- ppc_md.nvram_write_val = rs_nvram_write_val;
- }
- break;
}
/* Read in NVRAM data */
@@ -341,12 +314,6 @@ prep_setup_arch(void)
#endif /* CONFIG_SOUND_CS4232 */
/*print_residual_device_info();*/
- request_region(0x20,0x20,"pic1");
- request_region(0xa0,0x20,"pic2");
- request_region(0x00,0x20,"dma1");
- request_region(0x40,0x20,"timer");
- request_region(0x80,0x10,"dma page reg");
- request_region(0xc0,0x20,"dma2");
raven_init();
@@ -365,6 +332,7 @@ prep_setup_arch(void)
*/
void __init prep_res_calibrate_decr(void)
{
+#ifdef CONFIG_PREP_RESIDUAL
unsigned long freq, divisor=4;
freq = res->VitalProductData.ProcessorBusHz;
@@ -372,6 +340,7 @@ void __init prep_res_calibrate_decr(void)
(freq/divisor)/1000000, (freq/divisor)%1000000);
tb_ticks_per_jiffy = freq / HZ / divisor;
tb_to_us = mulhwu_scale_factor(freq/divisor, 1000000);
+#endif
}
/*
@@ -585,15 +554,16 @@ prep_setup_residual(char *buffer)
{
int len = 0;
-
/* PREP's without residual data will give incorrect values here */
len += sprintf(len+buffer, "clock\t\t: ");
+#ifdef CONFIG_PREP_RESIDUAL
if ( res->ResidualLength )
len += sprintf(len+buffer, "%ldMHz\n",
(res->VitalProductData.ProcessorHz > 1024) ?
res->VitalProductData.ProcessorHz>>20 :
res->VitalProductData.ProcessorHz);
else
+#endif /* CONFIG_PREP_RESIDUAL */
len += sprintf(len+buffer, "???\n");
return len;
@@ -640,19 +610,11 @@ prep_init_IRQ(void)
{
int i;
- if (OpenPIC != NULL) {
- for ( i = 16 ; i < 36 ; i++ )
- irq_desc[i].handler = &open_pic;
- openpic_init(1);
- }
-
- for ( i = 0 ; i < 16 ; i++ )
+ if (OpenPIC_Addr != NULL)
+ openpic_init(1, NUM_8259_INTERRUPTS, 0, -1);
+ for ( i = 0 ; i < NUM_8259_INTERRUPTS ; i++ )
irq_desc[i].handler = &i8259_pic;
- i8259_init();
-#ifdef CONFIG_SMP
- request_irq(openpic_to_irq(OPENPIC_VEC_SPURIOUS), openpic_ipi_action,
- 0, "IPI0", 0);
-#endif /* CONFIG_SMP */
+ i8259_init();
}
#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
@@ -708,19 +670,14 @@ prep_ide_request_region(ide_ioreg_t from,
unsigned int extent,
const char *name)
{
- request_region(from, extent, name);
+ request_region(from, extent, name);
}
void __prep
prep_ide_release_region(ide_ioreg_t from,
unsigned int extent)
{
- release_region(from, extent);
-}
-
-void __prep
-prep_ide_fix_driveid(struct hd_driveid *id)
-{
+ release_region(from, extent);
}
void __init
@@ -743,17 +700,52 @@ prep_ide_init_hwif_ports (hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl
}
#endif
+unsigned long *MotSave_SmpIar;
+unsigned char *MotSave_CpusState[2];
+
+void __init
+prep_init2(void)
+{
+#ifdef CONFIG_NVRAM
+ request_region(PREP_NVRAM_AS0, 0x8, "nvram");
+#endif
+ request_region(0x20,0x20,"pic1");
+ request_region(0xa0,0x20,"pic2");
+ request_region(0x00,0x20,"dma1");
+ request_region(0x40,0x20,"timer");
+ request_region(0x80,0x10,"dma page reg");
+ request_region(0xc0,0x20,"dma2");
+}
+
void __init
prep_init(unsigned long r3, unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7)
{
+#ifdef CONFIG_PREP_RESIDUAL
+ RESIDUAL *old_res = (RESIDUAL *)(r3 + KERNELBASE);
+
/* make a copy of residual data */
if ( r3 )
{
memcpy((void *)res,(void *)(r3+KERNELBASE),
sizeof(RESIDUAL));
+
+ /* These need to be saved for the Motorola Prep
+ * MVME4600 and Dual MTX boards.
+ */
+ MotSave_SmpIar = &old_res->VitalProductData.SmpIar;
+ MotSave_CpusState[0] = &old_res->Cpus[0].CpuState;
+ MotSave_CpusState[1] = &old_res->Cpus[1].CpuState;
}
+#endif
+ /* Copy cmd_line parameters */
+ if ( r6)
+ {
+ *(char *)(r7 + KERNELBASE) = 0;
+ strcpy(cmd_line, (char *)(r6 + KERNELBASE));
+ }
+
isa_io_base = PREP_ISA_IO_BASE;
isa_mem_base = PREP_ISA_MEM_BASE;
pci_dram_offset = PREP_PCI_DRAM_OFFSET;
@@ -762,29 +754,19 @@ prep_init(unsigned long r3, unsigned long r4, unsigned long r5,
DMA_MODE_WRITE = 0x48;
/* figure out what kind of prep workstation we are */
+#ifdef CONFIG_PREP_RESIDUAL
if ( res->ResidualLength != 0 )
{
if ( !strncmp(res->VitalProductData.PrintableModel,"IBM",3) )
_prep_type = _PREP_IBM;
- else if (!strncmp(res->VitalProductData.PrintableModel,
- "Radstone",8))
- {
- extern char *Motherboard_map_name;
-
- _prep_type = _PREP_Radstone;
- Motherboard_map_name=
- res->VitalProductData.PrintableModel;
- }
- else
- _prep_type = _PREP_Motorola;
+ _prep_type = _PREP_Motorola;
}
else /* assume motorola if no residual (netboot?) */
+#endif
{
_prep_type = _PREP_Motorola;
}
- prep_setup_pci_ptrs();
-
ppc_md.setup_arch = prep_setup_arch;
ppc_md.setup_residual = prep_setup_residual;
ppc_md.get_cpuinfo = prep_get_cpuinfo;
@@ -792,40 +774,14 @@ prep_init(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_md.init_IRQ = prep_init_IRQ;
/* this gets changed later on if we have an OpenPIC -- Cort */
ppc_md.get_irq = prep_get_irq;
- ppc_md.init = NULL;
+ ppc_md.init = prep_init2;
ppc_md.restart = prep_restart;
ppc_md.power_off = prep_power_off;
ppc_md.halt = prep_halt;
ppc_md.time_init = NULL;
- if (_prep_type == _PREP_Radstone) {
- /*
- * We require a direct restart as port 92 does not work on
- * all Radstone boards
- */
- ppc_md.restart = prep_direct_restart;
- /*
- * The RTC device used varies according to board type
- */
- if(((ucSystemType==RS_SYS_TYPE_PPC1) && (ucBoardRevMaj>=5)) ||
- (ucSystemType==RS_SYS_TYPE_PPC1a))
- {
- ppc_md.set_rtc_time = mk48t59_set_rtc_time;
- ppc_md.get_rtc_time = mk48t59_get_rtc_time;
- ppc_md.time_init = mk48t59_init;
- }
- else
- {
- ppc_md.set_rtc_time = mc146818_set_rtc_time;
- ppc_md.get_rtc_time = mc146818_get_rtc_time;
- }
- /*
- * Determine the decrementer rate from the residual data
- */
- ppc_md.calibrate_decr = prep_res_calibrate_decr;
- }
- else if (_prep_type == _PREP_IBM) {
+ if (_prep_type == _PREP_IBM) {
ppc_md.set_rtc_time = mc146818_set_rtc_time;
ppc_md.get_rtc_time = mc146818_get_rtc_time;
ppc_md.calibrate_decr = prep_calibrate_decr;
@@ -845,7 +801,7 @@ prep_init(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_ide_md.ide_check_region = prep_ide_check_region;
ppc_ide_md.ide_request_region = prep_ide_request_region;
ppc_ide_md.ide_release_region = prep_ide_release_region;
- ppc_ide_md.fix_driveid = prep_ide_fix_driveid;
+ ppc_ide_md.fix_driveid = NULL;
ppc_ide_md.ide_init_hwif = prep_ide_init_hwif_ports;
#endif
ppc_ide_md.io_base = _IO_BASE;
diff --git a/arch/ppc/kernel/proc_rtas.c b/arch/ppc/kernel/proc_rtas.c
new file mode 100644
index 000000000..2e8144204
--- /dev/null
+++ b/arch/ppc/kernel/proc_rtas.c
@@ -0,0 +1,784 @@
+/*
+ * arch/ppc/kernel/proc_rtas.c
+ * Copyright (C) 2000 Tilmann Bitterberg
+ * (tilmann@bitterberg.de)
+ *
+ * RTAS (Runtime Abstraction Services) stuff
+ * Intention is to provide a clean user interface
+ * to use the RTAS.
+ *
+ * TODO:
+ * Split off a header file and maybe move it to a different
+ * location. Write Documentation on what the /proc/rtas/ entries
+ * actually do.
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/proc_fs.h>
+#include <linux/stat.h>
+#include <linux/ctype.h>
+#include <linux/time.h>
+#include <linux/string.h>
+
+#include <asm/uaccess.h>
+#include <asm/bitops.h>
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/machdep.h> /* for ppc_md */
+#include <asm/time.h>
+
+/* Token for Sensors */
+#define KEY_SWITCH 0x0001
+#define ENCLOSURE_SWITCH 0x0002
+#define THERMAL_SENSOR 0x0003
+#define LID_STATUS 0x0004
+#define POWER_SOURCE 0x0005
+#define BATTERY_VOLTAGE 0x0006
+#define BATTERY_REMAINING 0x0007
+#define BATTERY_PERCENTAGE 0x0008
+#define EPOW_SENSOR 0x0009
+#define BATTERY_CYCLESTATE 0x000a
+#define BATTERY_CHARGING 0x000b
+
+/* IBM specific sensors */
+#define IBM_SURVEILLANCE 0x2328 /* 9000 */
+#define IBM_FANRPM 0x2329 /* 9001 */
+#define IBM_VOLTAGE 0x232a /* 9002 */
+#define IBM_DRCONNECTOR 0x232b /* 9003 */
+#define IBM_POWERSUPPLY 0x232c /* 9004 */
+#define IBM_INTQUEUE 0x232d /* 9005 */
+
+/* Status return values */
+#define SENSOR_CRITICAL_HIGH 13
+#define SENSOR_WARNING_HIGH 12
+#define SENSOR_NORMAL 11
+#define SENSOR_WARNING_LOW 10
+#define SENSOR_CRITICAL_LOW 9
+#define SENSOR_SUCCESS 0
+#define SENSOR_HW_ERROR -1
+#define SENSOR_BUSY -2
+#define SENSOR_NOT_EXIST -3
+#define SENSOR_DR_ENTITY -9000
+
+/* Location Codes */
+#define LOC_SCSI_DEV_ADDR 'A'
+#define LOC_SCSI_DEV_LOC 'B'
+#define LOC_CPU 'C'
+#define LOC_DISKETTE 'D'
+#define LOC_ETHERNET 'E'
+#define LOC_FAN 'F'
+#define LOC_GRAPHICS 'G'
+/* reserved / not used 'H' */
+#define LOC_IO_ADAPTER 'I'
+/* reserved / not used 'J' */
+#define LOC_KEYBOARD 'K'
+#define LOC_LCD 'L'
+#define LOC_MEMORY 'M'
+#define LOC_NV_MEMORY 'N'
+#define LOC_MOUSE 'O'
+#define LOC_PLANAR 'P'
+#define LOC_OTHER_IO 'Q'
+#define LOC_PARALLEL 'R'
+#define LOC_SERIAL 'S'
+#define LOC_DEAD_RING 'T'
+#define LOC_RACKMOUNTED 'U' /* for _u_nit is rack mounted */
+#define LOC_VOLTAGE 'V'
+#define LOC_SWITCH_ADAPTER 'W'
+#define LOC_OTHER 'X'
+#define LOC_FIRMWARE 'Y'
+#define LOC_SCSI 'Z'
+
+/* Tokens for indicators */
+#define TONE_FREQUENCY 0x0001 /* 0 - 1000 (HZ)*/
+#define TONE_VOLUME 0x0002 /* 0 - 100 (%) */
+#define SYSTEM_POWER_STATE 0x0003
+#define WARNING_LIGHT 0x0004
+#define DISK_ACTIVITY_LIGHT 0x0005
+#define HEX_DISPLAY_UNIT 0x0006
+#define BATTERY_WARNING_TIME 0x0007
+#define CONDITION_CYCLE_REQUEST 0x0008
+#define SURVEILLANCE_INDICATOR 0x2328 /* 9000 */
+#define DR_ACTION 0x2329 /* 9001 */
+#define DR_INDICATOR 0x232a /* 9002 */
+/* 9003 - 9004: Vendor specific */
+#define GLOBAL_INTERRUPT_QUEUE 0x232d /* 9005 */
+/* 9006 - 9999: Vendor specific */
+
+/* other */
+#define MAX_SENSORS 17 /* I only know of 17 sensors */
+#define MAX_LINELENGTH 256
+#define SENSOR_PREFIX "ibm,sensor-"
+#define cel_to_fahr(x) ((x*9/5)+32)
+
+
+/* Globals */
+static struct proc_dir_entry *proc_rtas;
+static struct rtas_sensors sensors;
+static struct device_node *rtas;
+static unsigned long power_on_time = 0; /* Save the time the user set */
+static char progress_led[MAX_LINELENGTH];
+
+static unsigned long rtas_tone_frequency = 1000;
+static unsigned long rtas_tone_volume = 0;
+
+/* ****************STRUCTS******************************************* */
+struct individual_sensor {
+ unsigned int token;
+ unsigned int quant;
+};
+
+struct rtas_sensors {
+ struct individual_sensor sensor[MAX_SENSORS];
+ unsigned int quant;
+};
+
+/* ****************************************************************** */
+/* Declarations */
+static int ppc_rtas_sensor_read(char * buf, char ** start, off_t off,
+ int count, int *eof, void *data);
+static ssize_t ppc_rtas_clock_read(struct file * file, char * buf,
+ size_t count, loff_t *ppos);
+static ssize_t ppc_rtas_clock_write(struct file * file, const char * buf,
+ size_t count, loff_t *ppos);
+static ssize_t ppc_rtas_progress_read(struct file * file, char * buf,
+ size_t count, loff_t *ppos);
+static ssize_t ppc_rtas_progress_write(struct file * file, const char * buf,
+ size_t count, loff_t *ppos);
+static ssize_t ppc_rtas_poweron_read(struct file * file, char * buf,
+ size_t count, loff_t *ppos);
+static ssize_t ppc_rtas_poweron_write(struct file * file, const char * buf,
+ size_t count, loff_t *ppos);
+
+static ssize_t ppc_rtas_tone_freq_write(struct file * file, const char * buf,
+ size_t count, loff_t *ppos);
+static ssize_t ppc_rtas_tone_freq_read(struct file * file, char * buf,
+ size_t count, loff_t *ppos);
+static ssize_t ppc_rtas_tone_volume_write(struct file * file, const char * buf,
+ size_t count, loff_t *ppos);
+static ssize_t ppc_rtas_tone_volume_read(struct file * file, char * buf,
+ size_t count, loff_t *ppos);
+
+struct file_operations ppc_rtas_poweron_operations = {
+ read: ppc_rtas_poweron_read,
+ write: ppc_rtas_poweron_write
+};
+struct file_operations ppc_rtas_progress_operations = {
+ read: ppc_rtas_progress_read,
+ write: ppc_rtas_progress_write
+};
+
+struct file_operations ppc_rtas_clock_operations = {
+ read: ppc_rtas_clock_read,
+ write: ppc_rtas_clock_write
+};
+
+struct file_operations ppc_rtas_tone_freq_operations = {
+ read: ppc_rtas_tone_freq_read,
+ write: ppc_rtas_tone_freq_write
+};
+struct file_operations ppc_rtas_tone_volume_operations = {
+ read: ppc_rtas_tone_volume_read,
+ write: ppc_rtas_tone_volume_write
+};
+
+int ppc_rtas_find_all_sensors (void);
+int ppc_rtas_process_sensor(struct individual_sensor s, int state,
+ int error, char * buf);
+char * ppc_rtas_process_error(int error);
+int get_location_code(struct individual_sensor s, char * buf);
+int check_location_string (char *c, char * buf);
+int check_location (char *c, int idx, char * buf);
+
+/* ****************************************************************** */
+/* MAIN */
+/* ****************************************************************** */
+void proc_rtas_init(void)
+{
+ struct proc_dir_entry *entry;
+
+ rtas = find_devices("rtas");
+ if ((rtas == 0) || (_machine != _MACH_chrp)) {
+ return;
+ }
+
+ proc_rtas = proc_mkdir("rtas", 0);
+ if (proc_rtas == 0)
+ return;
+
+ /* /proc/rtas entries */
+
+ entry = create_proc_entry("progress", S_IRUGO|S_IWUSR, proc_rtas);
+ if (entry) entry->proc_fops = &ppc_rtas_progress_operations;
+
+ entry = create_proc_entry("clock", S_IRUGO|S_IWUSR, proc_rtas);
+ if (entry) entry->proc_fops = &ppc_rtas_clock_operations;
+
+ entry = create_proc_entry("poweron", S_IWUSR|S_IRUGO, proc_rtas);
+ if (entry) entry->proc_fops = &ppc_rtas_poweron_operations;
+
+ create_proc_read_entry("sensors", S_IRUGO, proc_rtas,
+ ppc_rtas_sensor_read, NULL);
+
+ entry = create_proc_entry("frequency", S_IWUSR|S_IRUGO, proc_rtas);
+ if (entry) entry->proc_fops = &ppc_rtas_tone_freq_operations;
+
+ entry = create_proc_entry("volume", S_IWUSR|S_IRUGO, proc_rtas);
+ if (entry) entry->proc_fops = &ppc_rtas_tone_volume_operations;
+}
+
+/* ****************************************************************** */
+/* POWER-ON-TIME */
+/* ****************************************************************** */
+static ssize_t ppc_rtas_poweron_write(struct file * file, const char * buf,
+ size_t count, loff_t *ppos)
+{
+ struct rtc_time tm;
+ unsigned long nowtime;
+ char *dest;
+ int error;
+
+ nowtime = simple_strtoul(buf, &dest, 10);
+ if (*dest != '\0' && *dest != '\n') {
+ printk("ppc_rtas_poweron_write: Invalid time\n");
+ return count;
+ }
+ power_on_time = nowtime; /* save the time */
+
+ to_tm(nowtime, &tm);
+
+ error = call_rtas("set-time-for-power-on", 7, 1, NULL,
+ tm.tm_year, tm.tm_mon, tm.tm_mday,
+ tm.tm_hour, tm.tm_min, tm.tm_sec, 0 /* nano */);
+ if (error != 0)
+ printk(KERN_WARNING "error: setting poweron time returned: %s\n",
+ ppc_rtas_process_error(error));
+ return count;
+}
+/* ****************************************************************** */
+static ssize_t ppc_rtas_poweron_read(struct file * file, char * buf,
+ size_t count, loff_t *ppos)
+{
+ int n;
+ if (power_on_time == 0)
+ n = sprintf(buf, "Power on time not set\n");
+ else
+ n = sprintf(buf, "%lu\n", power_on_time);
+
+ if (*ppos >= strlen(buf))
+ return 0;
+ if (n > strlen(buf) - *ppos)
+ n = strlen(buf) - *ppos;
+ if (n > count)
+ n = count;
+ *ppos += n;
+ return n;
+}
+
+/* ****************************************************************** */
+/* PROGRESS */
+/* ****************************************************************** */
+static ssize_t ppc_rtas_progress_write(struct file * file, const char * buf,
+ size_t count, loff_t *ppos)
+{
+ unsigned long hex;
+
+ strcpy(progress_led, buf); /* save the string */
+ /* Lets see if the user passed hexdigits */
+ hex = simple_strtoul(buf, NULL, 10);
+
+ ppc_md.progress ((char *)buf, hex);
+ return count;
+
+ /* clear the line */ /* ppc_md.progress(" ", 0xffff);*/
+}
+/* ****************************************************************** */
+static ssize_t ppc_rtas_progress_read(struct file * file, char * buf,
+ size_t count, loff_t *ppos)
+{
+ int n = 0;
+ if (progress_led != NULL)
+ n = sprintf (buf, "%s\n", progress_led);
+ if (*ppos >= strlen(buf))
+ return 0;
+ if (n > strlen(buf) - *ppos)
+ n = strlen(buf) - *ppos;
+ if (n > count)
+ n = count;
+ *ppos += n;
+ return n;
+}
+
+/* ****************************************************************** */
+/* CLOCK */
+/* ****************************************************************** */
+static ssize_t ppc_rtas_clock_write(struct file * file, const char * buf,
+ size_t count, loff_t *ppos)
+{
+ struct rtc_time tm;
+ unsigned long nowtime;
+ char *dest;
+ int error;
+
+ nowtime = simple_strtoul(buf, &dest, 10);
+ if (*dest != '\0' && *dest != '\n') {
+ printk("ppc_rtas_clock_write: Invalid time\n");
+ return count;
+ }
+
+ to_tm(nowtime, &tm);
+ error = call_rtas("set-time-of-day", 7, 1, NULL,
+ tm.tm_year, tm.tm_mon, tm.tm_mday,
+ tm.tm_hour, tm.tm_min, tm.tm_sec, 0);
+ if (error != 0)
+ printk(KERN_WARNING "error: setting the clock returned: %s\n",
+ ppc_rtas_process_error(error));
+ return count;
+}
+/* ****************************************************************** */
+static ssize_t ppc_rtas_clock_read(struct file * file, char * buf,
+ size_t count, loff_t *ppos)
+{
+ unsigned int year, mon, day, hour, min, sec;
+ unsigned long *ret = kmalloc(4*8, GFP_KERNEL);
+ int n, error;
+
+ error = call_rtas("get-time-of-day", 0, 8, ret);
+
+ year = ret[0]; mon = ret[1]; day = ret[2];
+ hour = ret[3]; min = ret[4]; sec = ret[5];
+
+ if (error != 0){
+ printk(KERN_WARNING "error: reading the clock returned: %s\n",
+ ppc_rtas_process_error(error));
+ n = sprintf (buf, "0");
+ } else {
+ n = sprintf (buf, "%lu\n", mktime(year, mon, day, hour, min, sec));
+ }
+ kfree(ret);
+
+ if (*ppos >= strlen(buf))
+ return 0;
+ if (n > strlen(buf) - *ppos)
+ n = strlen(buf) - *ppos;
+ if (n > count)
+ n = count;
+ *ppos += n;
+ return n;
+}
+
+/* ****************************************************************** */
+/* SENSOR STUFF */
+/* ****************************************************************** */
+static int ppc_rtas_sensor_read(char * buf, char ** start, off_t off,
+ int count, int *eof, void *data)
+{
+ int i,j,n;
+ unsigned long ret;
+ int state, error;
+ char buffer[MAX_LINELENGTH*MAX_SENSORS]; /* May not be enough */
+
+ if (count < 0)
+ return -EINVAL;
+
+ n = sprintf ( buffer , "RTAS (RunTime Abstraction Services) Sensor Information\n");
+ n += sprintf ( buffer+n, "Sensor\t\tValue\t\tCondition\tLocation\n");
+ n += sprintf ( buffer+n, "********************************************************\n");
+
+ if (ppc_rtas_find_all_sensors() != 0) {
+ n += sprintf ( buffer+n, "\nNo sensors are available\n");
+ goto return_string;
+ }
+
+ for (i=0; i<sensors.quant; i++) {
+ j = sensors.sensor[i].quant;
+ /* A sensor may have multiple instances */
+ while (j >= 0) {
+ error = call_rtas("get-sensor-state", 2, 2, &ret,
+ sensors.sensor[i].token, sensors.sensor[i].quant-j);
+ state = (int) ret;
+ n += ppc_rtas_process_sensor(sensors.sensor[i], state, error, buffer+n );
+ n += sprintf (buffer+n, "\n");
+ j--;
+ } /* while */
+ } /* for */
+
+return_string:
+ if (off >= strlen(buffer)) {
+ *eof = 1;
+ return 0;
+ }
+ if (n > strlen(buffer) - off)
+ n = strlen(buffer) - off;
+ if (n > count)
+ n = count;
+ else
+ *eof = 1;
+ memcpy(buf, buffer + off, n);
+ *start = buf;
+ return n;
+}
+
+/* ****************************************************************** */
+
+int ppc_rtas_find_all_sensors (void)
+{
+ unsigned long *utmp;
+ int len, i, j;
+
+ utmp = (unsigned long *) get_property(rtas, "rtas-sensors", &len);
+ if (utmp == NULL) {
+ printk (KERN_ERR "error: could not get rtas-sensors\n");
+ return 1;
+ }
+
+ sensors.quant = len / 8; /* int + int */
+
+ for (i=0, j=0; j<sensors.quant; i+=2, j++) {
+ sensors.sensor[j].token = utmp[i];
+ sensors.sensor[j].quant = utmp[i+1];
+ }
+ return 0;
+}
+
+/* ****************************************************************** */
+/*
+ * Builds a string of what rtas returned
+ */
+char * ppc_rtas_process_error(int error)
+{
+ switch (error) {
+ case SENSOR_CRITICAL_HIGH:
+ return "(critical high)";
+ case SENSOR_WARNING_HIGH:
+ return "(warning high)";
+ case SENSOR_NORMAL:
+ return "(normal)";
+ case SENSOR_WARNING_LOW:
+ return "(warning low)";
+ case SENSOR_CRITICAL_LOW:
+ return "(critical low)";
+ case SENSOR_SUCCESS:
+ return "(read ok)";
+ case SENSOR_HW_ERROR:
+ return "(hardware error)";
+ case SENSOR_BUSY:
+ return "(busy)";
+ case SENSOR_NOT_EXIST:
+ return "(non existant)";
+ case SENSOR_DR_ENTITY:
+ return "(dr entity removed)";
+ default:
+ return "(UNKNOWN)";
+ }
+}
+
+/* ****************************************************************** */
+/*
+ * Builds a string out of what the sensor said
+ */
+
+int ppc_rtas_process_sensor(struct individual_sensor s, int state,
+ int error, char * buf)
+{
+ /* Defined return vales */
+ const char * key_switch[] = { "Off\t", "Normal\t", "Secure\t", "Mainenance" };
+ const char * enclosure_switch[] = { "Closed", "Open" };
+ const char * lid_status[] = { " ", "Open", "Closed" };
+ const char * power_source[] = { "AC\t", "Battery", "AC & Battery" };
+ const char * battery_remaining[] = { "Very Low", "Low", "Mid", "High" };
+ const char * epow_sensor[] = {
+ "EPOW Reset", "Cooling warning", "Power warning",
+ "System shutdown", "System halt", "EPOW main enclosure",
+ "EPOW power off" };
+ const char * battery_cyclestate[] = { "None", "In progress", "Requested" };
+ const char * battery_charging[] = { "Charging", "Discharching", "No current flow" };
+ const char * ibm_drconnector[] = { "Empty", "Present" };
+ const char * ibm_intqueue[] = { "Disabled", "Enabled" };
+
+ int have_strings = 0;
+ int temperature = 0;
+ int unknown = 0;
+ int n = 0;
+
+ /* What kind of sensor do we have here? */
+ switch (s.token) {
+ case KEY_SWITCH:
+ n += sprintf(buf+n, "Key switch:\t");
+ n += sprintf(buf+n, "%s\t", key_switch[state]);
+ have_strings = 1;
+ break;
+ case ENCLOSURE_SWITCH:
+ n += sprintf(buf+n, "Enclosure switch:\t");
+ n += sprintf(buf+n, "%s\t", enclosure_switch[state]);
+ have_strings = 1;
+ break;
+ case THERMAL_SENSOR:
+ n += sprintf(buf+n, "Temp. (°C/°F):\t");
+ temperature = 1;
+ break;
+ case LID_STATUS:
+ n += sprintf(buf+n, "Lid status:\t");
+ n += sprintf(buf+n, "%s\t", lid_status[state]);
+ have_strings = 1;
+ break;
+ case POWER_SOURCE:
+ n += sprintf(buf+n, "Power source:\t");
+ n += sprintf(buf+n, "%s\t", power_source[state]);
+ have_strings = 1;
+ break;
+ case BATTERY_VOLTAGE:
+ n += sprintf(buf+n, "Battery voltage:\t");
+ break;
+ case BATTERY_REMAINING:
+ n += sprintf(buf+n, "Battery remaining:\t");
+ n += sprintf(buf+n, "%s\t", battery_remaining[state]);
+ have_strings = 1;
+ break;
+ case BATTERY_PERCENTAGE:
+ n += sprintf(buf+n, "Battery percentage:\t");
+ break;
+ case EPOW_SENSOR:
+ n += sprintf(buf+n, "EPOW Sensor:\t");
+ n += sprintf(buf+n, "%s\t", epow_sensor[state]);
+ have_strings = 1;
+ break;
+ case BATTERY_CYCLESTATE:
+ n += sprintf(buf+n, "Battery cyclestate:\t");
+ n += sprintf(buf+n, "%s\t", battery_cyclestate[state]);
+ have_strings = 1;
+ break;
+ case BATTERY_CHARGING:
+ n += sprintf(buf+n, "Battery Charging:\t");
+ n += sprintf(buf+n, "%s\t", battery_charging[state]);
+ have_strings = 1;
+ break;
+ case IBM_SURVEILLANCE:
+ n += sprintf(buf+n, "Surveillance:\t");
+ break;
+ case IBM_FANRPM:
+ n += sprintf(buf+n, "Fan (rpm):\t");
+ break;
+ case IBM_VOLTAGE:
+ n += sprintf(buf+n, "Voltage (mv):\t");
+ break;
+ case IBM_DRCONNECTOR:
+ n += sprintf(buf+n, "DR connector:\t");
+ n += sprintf(buf+n, "%s\t", ibm_drconnector[state]);
+ have_strings = 1;
+ break;
+ case IBM_POWERSUPPLY:
+ n += sprintf(buf+n, "Powersupply:\t");
+ break;
+ case IBM_INTQUEUE:
+ n += sprintf(buf+n, "Interrupt queue:\t");
+ n += sprintf(buf+n, "%s\t", ibm_intqueue[state]);
+ have_strings = 1;
+ break;
+ default:
+ n += sprintf(buf+n, "Unkown sensor (type %d), ignoring it\n",
+ s.token);
+ unknown = 1;
+ have_strings = 1;
+ break;
+ }
+ if (have_strings == 0) {
+ if (temperature) {
+ n += sprintf(buf+n, "%4d /%4d\t", state, cel_to_fahr(state));
+ } else
+ n += sprintf(buf+n, "%10d\t", state);
+ }
+ if (unknown == 0) {
+ n += sprintf ( buf+n, "%s\t", ppc_rtas_process_error(error));
+ n += get_location_code(s, buf+n);
+ }
+ return n;
+}
+
+/* ****************************************************************** */
+
+int check_location (char *c, int idx, char * buf)
+{
+ int n = 0;
+
+ switch (*(c+idx)) {
+ case LOC_PLANAR:
+ n += sprintf ( buf, "Planar #%c", *(c+idx+1));
+ break;
+ case LOC_CPU:
+ n += sprintf ( buf, "CPU #%c", *(c+idx+1));
+ break;
+ case LOC_FAN:
+ n += sprintf ( buf, "Fan #%c", *(c+idx+1));
+ break;
+ case LOC_RACKMOUNTED:
+ n += sprintf ( buf, "Rack #%c", *(c+idx+1));
+ break;
+ case LOC_VOLTAGE:
+ n += sprintf ( buf, "Voltage #%c", *(c+idx+1));
+ break;
+ case LOC_LCD:
+ n += sprintf ( buf, "LCD #%c", *(c+idx+1));
+ break;
+ case '.':
+ n += sprintf ( buf, "- %c", *(c+idx+1));
+ default:
+ n += sprintf ( buf, "Unknown location");
+ break;
+ }
+ return n;
+}
+
+
+/* ****************************************************************** */
+/*
+ * Format:
+ * ${LETTER}${NUMBER}[[-/]${LETTER}${NUMBER} [ ... ] ]
+ * the '.' may be an abbrevation
+ */
+int check_location_string (char *c, char *buf)
+{
+ int n=0,i=0;
+
+ while (c[i]) {
+ if (isalpha(c[i]) || c[i] == '.') {
+ n += check_location(c, i, buf+n);
+ }
+ else if (c[i] == '/' || c[i] == '-')
+ n += sprintf(buf+n, " at ");
+ i++;
+ }
+ return n;
+}
+
+
+/* ****************************************************************** */
+
+int get_location_code(struct individual_sensor s, char * buffer)
+{
+ char rstr[512], tmp[10], tmp2[10];
+ int n=0, i=0, llen, len;
+ /* char *buf = kmalloc(MAX_LINELENGTH, GFP_KERNEL); */
+ char *ret;
+
+ static int pos = 0; /* remember position where buffer was */
+
+ /* construct the sensor number like 0003 */
+ /* fill with zeros */
+ n = sprintf(tmp, "%d", s.token);
+ len = strlen(tmp);
+ while (strlen(tmp) < 4)
+ n += sprintf (tmp+n, "0");
+
+ /* invert the string */
+ while (tmp[i]) {
+ if (i<len)
+ tmp2[4-len+i] = tmp[i];
+ else
+ tmp2[3-i] = tmp[i];
+ i++;
+ }
+ tmp2[4] = '\0';
+
+ sprintf (rstr, SENSOR_PREFIX"%s", tmp2);
+
+ ret = (char *) get_property(rtas, rstr, &llen);
+
+ n=0;
+ if (ret[0] == '\0')
+ n += sprintf ( buffer+n, "--- ");/* does not have a location */
+ else {
+ char t[50];
+ ret += pos;
+
+ n += check_location_string(ret, buffer + n);
+ n += sprintf ( buffer+n, " ");
+ /* see how many characters we have printed */
+ sprintf ( t, "%s ", ret);
+
+ pos += strlen(t);
+ if (pos >= llen) pos=0;
+ }
+ return n;
+}
+/* ****************************************************************** */
+/* INDICATORS - Tone Frequency */
+/* ****************************************************************** */
+static ssize_t ppc_rtas_tone_freq_write(struct file * file, const char * buf,
+ size_t count, loff_t *ppos)
+{
+ unsigned long freq;
+ char *dest;
+ int error;
+ freq = simple_strtoul(buf, &dest, 10);
+ if (*dest != '\0' && *dest != '\n') {
+ printk("ppc_rtas_tone_freq_write: Invalid tone freqency\n");
+ return count;
+ }
+ if (freq < 0) freq = 0;
+ rtas_tone_frequency = freq; /* save it for later */
+ error = call_rtas("set-indicator", 3, 1, NULL,
+ TONE_FREQUENCY, 0, freq);
+ if (error != 0)
+ printk(KERN_WARNING "error: setting tone frequency returned: %s\n",
+ ppc_rtas_process_error(error));
+ return count;
+}
+/* ****************************************************************** */
+static ssize_t ppc_rtas_tone_freq_read(struct file * file, char * buf,
+ size_t count, loff_t *ppos)
+{
+ int n;
+ n = sprintf(buf, "%lu\n", rtas_tone_frequency);
+
+ if (*ppos >= strlen(buf))
+ return 0;
+ if (n > strlen(buf) - *ppos)
+ n = strlen(buf) - *ppos;
+ if (n > count)
+ n = count;
+ *ppos += n;
+ return n;
+}
+/* ****************************************************************** */
+/* INDICATORS - Tone Volume */
+/* ****************************************************************** */
+static ssize_t ppc_rtas_tone_volume_write(struct file * file, const char * buf,
+ size_t count, loff_t *ppos)
+{
+ unsigned long volume;
+ char *dest;
+ int error;
+ volume = simple_strtoul(buf, &dest, 10);
+ if (*dest != '\0' && *dest != '\n') {
+ printk("ppc_rtas_tone_volume_write: Invalid tone volume\n");
+ return count;
+ }
+ if (volume < 0) volume = 0;
+ if (volume > 100) volume = 100;
+
+ rtas_tone_volume = volume; /* save it for later */
+ error = call_rtas("set-indicator", 3, 1, NULL,
+ TONE_VOLUME, 0, volume);
+ if (error != 0)
+ printk(KERN_WARNING "error: setting tone volume returned: %s\n",
+ ppc_rtas_process_error(error));
+ return count;
+}
+/* ****************************************************************** */
+static ssize_t ppc_rtas_tone_volume_read(struct file * file, char * buf,
+ size_t count, loff_t *ppos)
+{
+ int n;
+ n = sprintf(buf, "%lu\n", rtas_tone_volume);
+
+ if (*ppos >= strlen(buf))
+ return 0;
+ if (n > strlen(buf) - *ppos)
+ n = strlen(buf) - *ppos;
+ if (n > count)
+ n = count;
+ *ppos += n;
+ return n;
+}
diff --git a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c
index a200b1c78..c4c76adec 100644
--- a/arch/ppc/kernel/process.c
+++ b/arch/ppc/kernel/process.c
@@ -222,16 +222,17 @@ _switch_to(struct task_struct *prev, struct task_struct *new,
giveup_fpu(prev);
#ifdef CONFIG_ALTIVEC
/*
- * If the previous thread 1) has some altivec regs it wants saved
- * (has bits in vrsave set) and 2) used altivec in the last quantum
+ * If the previous thread used altivec in the last quantum
* (thus changing altivec regs) then save them.
+ * We used to check the VRSAVE register but not all apps
+ * set it, so we don't rely on it now (and in fact we need
+ * to save & restore VSCR even if VRSAVE == 0). -- paulus
*
* On SMP we always save/restore altivec regs just to avoid the
* complexity of changing processors.
* -- Cort
*/
- if ( (prev->thread.regs && (prev->thread.regs->msr & MSR_VEC)) &&
- prev->thread.vrsave )
+ if ((prev->thread.regs && (prev->thread.regs->msr & MSR_VEC)))
giveup_altivec(prev);
#endif /* CONFIG_ALTIVEC */
current_set[smp_processor_id()] = new;
@@ -251,13 +252,15 @@ void show_regs(struct pt_regs * regs)
{
int i;
- printk("NIP: %08lX XER: %08lX LR: %08lX REGS: %p TRAP: %04lx\n",
- regs->nip, regs->xer, regs->link, regs,regs->trap);
+ printk("NIP: %08lX XER: %08lX LR: %08lX SP: %08lX REGS: %p TRAP: %04lx\n",
+ regs->nip, regs->xer, regs->link, regs->gpr[1], regs,regs->trap);
printk("MSR: %08lx EE: %01x PR: %01x FP: %01x ME: %01x IR/DR: %01x%01x\n",
regs->msr, regs->msr&MSR_EE ? 1 : 0, regs->msr&MSR_PR ? 1 : 0,
regs->msr & MSR_FP ? 1 : 0,regs->msr&MSR_ME ? 1 : 0,
regs->msr&MSR_IR ? 1 : 0,
regs->msr&MSR_DR ? 1 : 0);
+ if (regs->trap == 0x300 || regs->trap == 0x600)
+ printk("DAR: %08lX, DSISR: %08lX\n", regs->dar, regs->dsisr);
printk("TASK = %p[%d] '%s' ",
current, current->pid, current->comm);
printk("Last syscall: %ld ", current->thread.last_syscall);
@@ -285,7 +288,7 @@ void show_regs(struct pt_regs * regs)
printk("\n");
}
}
-out:
+out: ;
}
void exit_thread(void)
diff --git a/arch/ppc/kernel/prom.c b/arch/ppc/kernel/prom.c
index 5494f2f52..f3b39c222 100644
--- a/arch/ppc/kernel/prom.c
+++ b/arch/ppc/kernel/prom.c
@@ -28,10 +28,11 @@
#include <asm/smp.h>
#include <asm/bootx.h>
#include <asm/system.h>
-#include <asm/gemini.h>
#include <asm/mmu.h>
#include <asm/pgtable.h>
#include <asm/bitops.h>
+/* for openpic_to_irq */
+#include "open_pic.h"
#ifdef CONFIG_FB
#include <asm/linux_logo.h>
@@ -95,26 +96,28 @@ static interpret_func interpret_root_props;
#define FB_MAX 8
#endif
char *prom_display_paths[FB_MAX] __initdata = { 0, };
-unsigned int prom_num_displays = 0;
-char *of_stdout_device = 0;
+unsigned int prom_num_displays __initdata = 0;
+char *of_stdout_device __initdata = 0;
+ihandle prom_disp_node __initdata = 0;
-prom_entry prom = 0;
-ihandle prom_chosen = 0, prom_stdout = 0, prom_disp_node = 0;
+prom_entry prom __initdata = 0;
+ihandle prom_chosen __initdata = 0;
+ihandle prom_stdout __initdata = 0;
extern char *klimit;
-char *bootpath = 0;
-char *bootdevice = 0;
+char *bootpath;
+char *bootdevice;
-unsigned int rtas_data = 0; /* physical pointer */
-unsigned int rtas_entry = 0; /* physical pointer */
-unsigned int rtas_size = 0;
-unsigned int old_rtas = 0;
+unsigned int rtas_data; /* physical pointer */
+unsigned int rtas_entry; /* physical pointer */
+unsigned int rtas_size;
+unsigned int old_rtas;
/* Set for a newworld machine */
-int use_of_interrupt_tree = 0;
-int pmac_newworld = 0;
+int use_of_interrupt_tree;
+int pmac_newworld;
-static struct device_node *allnodes = 0;
+static struct device_node *allnodes;
#ifdef CONFIG_BOOTX_TEXT
@@ -134,13 +137,12 @@ static void draw_byte_32(unsigned char *bits, unsigned long *base, int rb);
static void draw_byte_16(unsigned char *bits, unsigned long *base, int rb);
static void draw_byte_8(unsigned char *bits, unsigned long *base, int rb);
-/* We want those in data, not BSS */
-static long g_loc_X = 0;
-static long g_loc_Y = 0;
-static long g_max_loc_X = 0;
-static long g_max_loc_Y = 0;
+static int g_loc_X;
+static int g_loc_Y;
+static int g_max_loc_X;
+static int g_max_loc_Y;
-unsigned long disp_BAT[2] = {0, 0};
+unsigned long disp_BAT[2] __initdata = {0, 0};
#define cmapsz (16*256)
@@ -173,10 +175,10 @@ extern unsigned long reloc_offset(void);
void phys_call_rtas(int, int, int, ...);
extern char cmd_line[512]; /* XXX */
-boot_infos_t *boot_infos = 0; /* init it so it's in data segment not bss */
+boot_infos_t *boot_infos;
#ifdef CONFIG_BOOTX_TEXT
-boot_infos_t *disp_bi = 0;
-boot_infos_t fake_bi = {0,};
+boot_infos_t *disp_bi;
+boot_infos_t fake_bi;
#endif
unsigned long dev_tree_size;
@@ -195,10 +197,6 @@ unsigned long dev_tree_size;
* OF calls should be done within prom_init(), and prom_init()
* and all routines called within it must be careful to relocate
* references as necessary.
- *
- * Note that the bss is cleared *after* prom_init runs, so we have
- * to make sure that any static or extern variables it accesses
- * are put in the data segment.
*/
#define PTRRELOC(x) ((typeof(x))((unsigned long)(x) + offset))
#define PTRUNRELOC(x) ((typeof(x))((unsigned long)(x) - offset))
@@ -618,6 +616,11 @@ prom_init(int r3, int r4, prom_entry pp)
char *p, *d;
int prom_version = 0;
unsigned long phys;
+ extern char __bss_start, _end;
+
+ /* First zero the BSS -- use memset, some arches don't have
+ * caches on yet */
+ memset_io(PTRRELOC(&__bss_start),0 , &_end - &__bss_start);
/* Default */
phys = offset + KERNELBASE;
@@ -948,34 +951,6 @@ check_display(unsigned long mem)
if ((int) call_prom(RELOC("package-to-path"), 3, 1,
node, path, 255) < 0)
continue;
- prom_print(RELOC("opening display "));
- prom_print(path);
- ih = call_prom(RELOC("open"), 1, 1, path);
- if (ih == 0 || ih == (ihandle) -1) {
- prom_print(RELOC("... failed\n"));
- continue;
- }
- prom_print(RELOC("... ok\n"));
-
- if (RELOC(prom_disp_node) == 0)
- RELOC(prom_disp_node) = node;
-
- /* Setup a useable color table when the appropriate
- * method is available. Should update this to set-colors */
- for (i = 0; i < 32; i++)
- if (prom_set_color(ih, i, RELOC(default_colors)[i*3],
- RELOC(default_colors)[i*3+1],
- RELOC(default_colors)[i*3+2]) != 0)
- break;
-
-#ifdef CONFIG_FB
- for (i = 0; i < LINUX_LOGO_COLORS; i++)
- if (prom_set_color(ih, i + 32,
- RELOC(linux_logo_red)[i],
- RELOC(linux_logo_green)[i],
- RELOC(linux_logo_blue)[i]) != 0)
- break;
-#endif /* CONFIG_FB */
/*
* If this display is the device that OF is using for stdout,
@@ -990,9 +965,44 @@ check_display(unsigned long mem)
= RELOC(prom_display_paths[i-1]);
}
RELOC(prom_display_paths[i]) = PTRUNRELOC(path);
+ if (i == 0)
+ RELOC(prom_disp_node) = node;
if (RELOC(prom_num_displays) >= FB_MAX)
break;
}
+
+ /*
+ * Open the first display and set its colormap.
+ */
+ if (RELOC(prom_num_displays) > 0) {
+ path = PTRRELOC(RELOC(prom_display_paths[0]));
+ prom_print(RELOC("opening display "));
+ prom_print(path);
+ ih = call_prom(RELOC("open"), 1, 1, path);
+ if (ih == 0 || ih == (ihandle) -1) {
+ prom_print(RELOC("... failed\n"));
+ } else {
+ prom_print(RELOC("... ok\n"));
+
+ /* Setup a useable color table when the appropriate
+ * method is available. Should update this to set-colors */
+ for (i = 0; i < 32; i++)
+ if (prom_set_color(ih, i, RELOC(default_colors)[i*3],
+ RELOC(default_colors)[i*3+1],
+ RELOC(default_colors)[i*3+2]) != 0)
+ break;
+
+#ifdef CONFIG_FB
+ for (i = 0; i < LINUX_LOGO_COLORS; i++)
+ if (prom_set_color(ih, i + 32,
+ RELOC(linux_logo_red)[i],
+ RELOC(linux_logo_green)[i],
+ RELOC(linux_logo_blue)[i]) != 0)
+ break;
+#endif /* CONFIG_FB */
+ }
+ }
+
return ALIGN(mem);
}
@@ -1277,7 +1287,7 @@ finish_node(struct device_node *np, unsigned long mem_start,
if (!strcmp(np->name, "display"))
np->name = get_property(np, "compatible", 0);
- if (!strcmp(np->name, "device-tree"))
+ if (np->parent == NULL)
ifunc = interpret_root_props;
else if (np->type == 0)
ifunc = NULL;
@@ -1370,7 +1380,7 @@ finish_node_interrupts(struct device_node *np, unsigned long mem_start)
np->intrs[i].line = *interrupts++;
if (cvt_irq)
np->intrs[i].line = openpic_to_irq(np->intrs[i].line);
- np->intrs[i].sense = 0;
+ np->intrs[i].sense = 1;
if (isize > 1)
np->intrs[i].sense = *interrupts++;
for (j=2; j<isize; j++)
@@ -1540,7 +1550,7 @@ interpret_pci_props(struct device_node *np, unsigned long mem_start,
for (i = 0; (ml -= cell_size) >= 0; ++i) {
if (imp->addr.a_hi == devfn) {
np->intrs[np->n_intrs].line = imp->intr;
- np->intrs[np->n_intrs].sense = 0; /* FIXME */
+ np->intrs[np->n_intrs].sense = 1; /* FIXME */
++np->n_intrs;
}
imp = (struct pci_intr_map *)(((unsigned int)imp)
@@ -1561,7 +1571,7 @@ interpret_pci_props(struct device_node *np, unsigned long mem_start,
mem_start += np->n_intrs * sizeof(struct interrupt_info);
for (i = 0; i < np->n_intrs; ++i) {
np->intrs[i].line = *ip++;
- np->intrs[i].sense = 0;
+ np->intrs[i].sense = 1;
}
}
@@ -1614,7 +1624,7 @@ interpret_dbdma_props(struct device_node *np, unsigned long mem_start,
mem_start += np->n_intrs * sizeof(struct interrupt_info);
for (i = 0; i < np->n_intrs; ++i) {
np->intrs[i].line = *ip++;
- np->intrs[i].sense = 0;
+ np->intrs[i].sense = 1;
}
}
@@ -1675,7 +1685,7 @@ interpret_macio_props(struct device_node *np, unsigned long mem_start,
if (keylargo)
np->intrs[i].sense = *ip++;
else
- np->intrs[i].sense = 0;
+ np->intrs[i].sense = 1;
}
} else {
/* CHRP machines */
@@ -1771,7 +1781,7 @@ interpret_root_props(struct device_node *np, unsigned long mem_start,
mem_start += np->n_intrs * sizeof(struct interrupt_info);
for (i = 0; i < np->n_intrs; ++i) {
np->intrs[i].line = *ip++;
- np->intrs[i].sense = 0;
+ np->intrs[i].sense = 1;
}
}
@@ -1779,6 +1789,30 @@ interpret_root_props(struct device_node *np, unsigned long mem_start,
}
/*
+ * Work out the sense (active-low level / active-high edge)
+ * of each interrupt from the device tree.
+ */
+void __init
+prom_get_irq_senses(unsigned char *senses, int off, int max)
+{
+ struct device_node *np;
+ int i, j;
+
+ /* default to level-triggered */
+ memset(senses, 1, max - off);
+ if (!use_of_interrupt_tree)
+ return;
+
+ for (np = allnodes; np != 0; np = np->allnext) {
+ for (j = 0; j < np->n_intrs; j++) {
+ i = np->intrs[j].line;
+ if (i >= off && i < max)
+ senses[i-off] = np->intrs[j].sense;
+ }
+ }
+}
+
+/*
* Construct and return a list of the device_nodes with a given name.
*/
__openfirmware
@@ -1818,39 +1852,6 @@ find_type_devices(const char *type)
return head;
}
-/* Finds a device node given its PCI bus number, device number
- * and function number
- */
-__openfirmware
-struct device_node *
-find_pci_device_OFnode(unsigned char bus, unsigned char dev_fn)
-{
- struct device_node* np;
- unsigned int *reg;
- int l;
-
- for (np = allnodes; np != 0; np = np->allnext) {
- int in_macio = 0;
- struct device_node* parent = np->parent;
- while(parent) {
- char *pname = (char *)get_property(parent, "name", &l);
- if (pname && strcmp(pname, "mac-io") == 0) {
- in_macio = 1;
- break;
- }
- parent = parent->parent;
- }
- if (in_macio)
- continue;
- reg = (unsigned int *) get_property(np, "reg", &l);
- if (reg == 0 || l < sizeof(struct reg_property))
- continue;
- if (((reg[0] >> 8) & 0xff) == dev_fn && ((reg[0] >> 16) & 0xff) == bus)
- break;
- }
- return np;
-}
-
/*
* Returns all nodes linked together
*/
@@ -1983,6 +1984,21 @@ get_property(struct device_node *np, const char *name, int *lenp)
return 0;
}
+/*
+ * Add a property to a node
+ */
+__openfirmware
+void
+prom_add_property(struct device_node* np, struct property* prop)
+{
+ struct property **next = &np->properties;
+
+ prop->next = NULL;
+ while (*next)
+ next = &(*next)->next;
+ *next = prop;
+}
+
#if 0
__openfirmware
void
diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
index 6bafa57c1..58fb87e9c 100644
--- a/arch/ppc/kernel/setup.c
+++ b/arch/ppc/kernel/setup.c
@@ -12,6 +12,7 @@
#include <linux/delay.h>
#include <linux/blk.h>
#include <linux/ide.h>
+#include <linux/bootmem.h>
#include <asm/init.h>
#include <asm/residual.h>
@@ -71,12 +72,6 @@ extern void apus_init(unsigned long r3,
unsigned long r6,
unsigned long r7);
-extern void gemini_init(unsigned long r3,
- unsigned long r4,
- unsigned long r5,
- unsigned long r6,
- unsigned long r7);
-
#ifdef CONFIG_XMON
extern void xmon_map_scc(void);
#endif
@@ -106,6 +101,10 @@ int have_of = 0;
unsigned long SYSRQ_KEY;
#endif /* CONFIG_MAGIC_SYSRQ */
+#ifdef CONFIG_VGA_CONSOLE
+unsigned long vgacon_remap_base;
+#endif
+
struct machdep_calls ppc_md;
/*
@@ -377,9 +376,9 @@ int get_cpuinfo(char *buffer)
len += sprintf(len+buffer, "revision\t: %hd.%hd\n", maj, min);
len += sprintf(buffer+len, "bogomips\t: %lu.%02lu\n",
- (CD(loops_per_sec)+2500)/500000,
- (CD(loops_per_sec)+2500)/5000 % 100);
- bogosum += CD(loops_per_sec);
+ (CD(loops_per_jiffy)+2500)/(500000/HZ),
+ (CD(loops_per_jiffy)+2500)/(5000/HZ) % 100);
+ bogosum += CD(loops_per_jiffy);
}
#ifdef CONFIG_SMP
@@ -549,11 +548,6 @@ identify_machine(unsigned long r3, unsigned long r4, unsigned long r5,
apus_init(r3, r4, r5, r6, r7);
break;
#endif
-#ifdef CONFIG_GEMINI
- case _MACH_gemini:
- gemini_init(r3, r4, r5, r6, r7);
- break;
-#endif
default:
printk("Unknown machine type in identify_machine!\n");
}
@@ -673,13 +667,14 @@ __setup("l2cr=", ppc_setup_l2cr);
void __init ppc_init(void)
{
/* clear the progress line */
- if ( ppc_md.progress ) ppc_md.progress(" ", 0xffff);
+ if ( ppc_md.progress ) ppc_md.progress(" ", 0xffff);
if (ppc_md.init != NULL) {
ppc_md.init();
}
}
+/* Warning, IO base is not yet inited */
void __init setup_arch(char **cmdline_p)
{
extern int panic_timeout;
@@ -688,7 +683,7 @@ void __init setup_arch(char **cmdline_p)
extern void do_init_bootmem(void);
/* so udelay does something sensible, assume <= 1000 bogomips */
- loops_per_sec = 500000000;
+ loops_per_jiffy = 500000000 / HZ;
#ifdef CONFIG_ALL_PPC
feature_init();
@@ -743,10 +738,34 @@ void __init setup_arch(char **cmdline_p)
ppc_md.setup_arch();
if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab);
+#ifdef CONFIG_PCI
+ /* We create the "pci-OF-bus-map" property now so it appear in the
+ * /proc device tree
+ */
+ if (have_of) {
+ struct property* of_prop;
+
+ of_prop = (struct property*)alloc_bootmem(sizeof(struct property) + 256);
+ if (of_prop && find_path_device("/")) {
+ memset(of_prop, -1, sizeof(struct property) + 256);
+ of_prop->name = "pci-OF-bus-map";
+ of_prop->length = 256;
+ of_prop->value = (unsigned char *)&of_prop[1];
+ prom_add_property(find_path_device("/"), of_prop);
+ }
+ }
+#endif /* CONFIG_PCI */
+
paging_init();
sort_exception_table();
}
+/* Convert the shorts/longs in hd_driveid from little to big endian;
+ * chars are endian independant, of course, but strings need to be flipped.
+ * (Despite what it says in drivers/block/ide.h, they come up as little
+ * endian...)
+ *
+ * Changes to linux/hdreg.h may require changes here. */
void ppc_generic_ide_fix_driveid(struct hd_driveid *id)
{
int i;
diff --git a/arch/ppc/kernel/signal.c b/arch/ppc/kernel/signal.c
index dd3d1ae1b..fe16fae25 100644
--- a/arch/ppc/kernel/signal.c
+++ b/arch/ppc/kernel/signal.c
@@ -53,8 +53,6 @@
#define MSR_USERCHANGE (MSR_FE0 | MSR_FE1)
int do_signal(sigset_t *oldset, struct pt_regs *regs);
-extern int sys_wait4(pid_t pid, unsigned long *stat_addr,
- int options, unsigned long *ru);
int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
{
diff --git a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c
index fb7f38444..7edf7209d 100644
--- a/arch/ppc/kernel/smp.c
+++ b/arch/ppc/kernel/smp.c
@@ -1,6 +1,4 @@
/*
- * $Id: smp.c,v 1.68 1999/09/17 19:38:05 cort Exp $
- *
* Smp support for ppc.
*
* Written by Cort Dougan (cort@cs.nmt.edu) borrowing a great
@@ -8,8 +6,11 @@
*
* Copyright (C) 1999 Cort Dougan <cort@cs.nmt.edu>
*
- * Support for PReP (Motorola MTX/MVME) SMP by Troy Benjegerdes
- * (troy@microux.com, hozer@drgw.net)
+ * Support for PReP (Motorola MTX/MVME) and Macintosh G4 SMP
+ * by Troy Benjegerdes (hozer@drgw.net)
+ *
+ * Support for DayStar quad CPU cards
+ * Copyright (C) XLR8, Inc. 1994-2000
*/
#include <linux/config.h>
@@ -23,7 +24,6 @@
#define __KERNEL_SYSCALLS__
#include <linux/unistd.h>
#include <linux/init.h>
-#include <linux/openpic.h>
#include <linux/spinlock.h>
#include <asm/ptrace.h>
@@ -37,47 +37,97 @@
#include <asm/io.h>
#include <asm/prom.h>
#include <asm/smp.h>
-#include <asm/gemini.h>
-
+#include <asm/residual.h>
+#include <asm/feature.h>
#include <asm/time.h>
+
#include "open_pic.h"
int smp_threads_ready;
volatile int smp_commenced;
int smp_num_cpus = 1;
+int smp_tb_synchronized;
struct cpuinfo_PPC cpu_data[NR_CPUS];
struct klock_info_struct klock_info = { KLOCK_CLEAR, 0 };
-volatile unsigned char active_kernel_processor = NO_PROC_ID; /* Processor holding kernel spinlock */
-volatile unsigned long ipi_count;
+atomic_t ipi_recv;
+atomic_t ipi_sent;
spinlock_t kernel_flag = SPIN_LOCK_UNLOCKED;
unsigned int prof_multiplier[NR_CPUS];
unsigned int prof_counter[NR_CPUS];
cycles_t cacheflush_time;
+static int max_cpus __initdata = NR_CPUS;
-/* this has to go in the data section because it is accessed from prom_init */
int smp_hw_index[NR_CPUS];
/* all cpu mappings are 1-1 -- Cort */
volatile unsigned long cpu_callin_map[NR_CPUS];
+#define TB_SYNC_PASSES 4
+volatile unsigned long __initdata tb_sync_flag = 0;
+volatile unsigned long __initdata tb_offset = 0;
+
int start_secondary(void *);
extern int cpu_idle(void *unused);
-u_int openpic_read(volatile u_int *addr);
void smp_call_function_interrupt(void);
void smp_message_pass(int target, int msg, unsigned long data, int wait);
+extern void __secondary_start_psurge(void);
+extern void __secondary_start_psurge2(void); /* Temporary horrible hack */
+extern void __secondary_start_psurge3(void); /* Temporary horrible hack */
+
+/* Addresses for powersurge registers */
+#define HAMMERHEAD_BASE 0xf8000000
+#define HHEAD_CONFIG 0x90
+#define HHEAD_SEC_INTR 0xc0
+
/* register for interrupting the primary processor on the powersurge */
/* N.B. this is actually the ethernet ROM! */
-#define PSURGE_PRI_INTR 0xf3019000
-/* register for interrupting the secondary processor on the powersurge */
-#define PSURGE_SEC_INTR 0xf80000c0
+#define PSURGE_PRI_INTR 0xf3019000
+
/* register for storing the start address for the secondary processor */
-#define PSURGE_START 0xf2800000
+/* N.B. this is the PCI config space address register for the 1st bridge */
+#define PSURGE_START 0xf2800000
+
+/* Daystar/XLR8 4-CPU card */
+#define PSURGE_QUAD_REG_ADDR 0xf8800000
+
+#define PSURGE_QUAD_IRQ_SET 0
+#define PSURGE_QUAD_IRQ_CLR 1
+#define PSURGE_QUAD_IRQ_PRIMARY 2
+#define PSURGE_QUAD_CKSTOP_CTL 3
+#define PSURGE_QUAD_PRIMARY_ARB 4
+#define PSURGE_QUAD_BOARD_ID 6
+#define PSURGE_QUAD_WHICH_CPU 7
+#define PSURGE_QUAD_CKSTOP_RDBK 8
+#define PSURGE_QUAD_RESET_CTL 11
+
+#define PSURGE_QUAD_OUT(r, v) (out_8((u8 *)(quad_base+((r)<<2)+1), (v)))
+#define PSURGE_QUAD_IN(r) (in_8((u8 *)(quad_base+((r)<<2)+1)) & 0x0f)
+#define PSURGE_QUAD_BIS(r, v) (PSURGE_QUAD_OUT((r), PSURGE_QUAD_IN(r) | (v)))
+#define PSURGE_QUAD_BIC(r, v) (PSURGE_QUAD_OUT((r), PSURGE_QUAD_IN(r) & ~(v)))
+
/* virtual addresses for the above */
-volatile u32 *psurge_pri_intr;
-volatile u32 *psurge_sec_intr;
-volatile u32 *psurge_start;
+static volatile u8 *hhead_base;
+static volatile u32 *quad_base;
+static volatile u32 *psurge_pri_intr;
+static volatile u8 *psurge_sec_intr;
+static volatile u32 *psurge_start;
+
+/* what sort of powersurge board we have */
+static int psurge_type;
+
+/* values for psurge_type */
+#define PSURGE_DUAL 0
+#define PSURGE_QUAD_OKEE 1
+#define PSURGE_QUAD_COTTON 2
+#define PSURGE_QUAD_ICEGRASS 3
-/* Since OpenPIC has only 4 IPIs, we use slightly different message numbers. */
+/* l2 cache stuff for dual G4 macs */
+extern void core99_init_l2(void);
+
+/* Since OpenPIC has only 4 IPIs, we use slightly different message numbers.
+ *
+ * Make sure this matches openpic_request_IPIs in open_pic.c, or what shows up
+ * in /proc/interrupts will be wrong!!! --Troy */
#define PPC_MSG_CALL_FUNCTION 0
#define PPC_MSG_RESCHEDULE 1
#define PPC_MSG_INVALIDATE_TLB 2
@@ -85,10 +135,577 @@ volatile u32 *psurge_start;
static inline void set_tb(unsigned int upper, unsigned int lower)
{
+ mtspr(SPRN_TBWL, 0);
mtspr(SPRN_TBWU, upper);
mtspr(SPRN_TBWL, lower);
}
+/*
+ * Set and clear IPIs for powersurge.
+ */
+static inline void psurge_set_ipi(int cpu)
+{
+ if (cpu == 0)
+ in_be32(psurge_pri_intr);
+ else if (psurge_type == PSURGE_DUAL)
+ out_8(psurge_sec_intr, 0);
+ else
+ PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_SET, 1 << cpu);
+}
+
+static inline void psurge_clr_ipi(int cpu)
+{
+ if (cpu > 0) {
+ if (psurge_type == PSURGE_DUAL)
+ out_8(psurge_sec_intr, ~0);
+ else
+ PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_CLR, 1 << cpu);
+ }
+}
+
+/*
+ * On powersurge (old SMP powermac architecture) we don't have
+ * separate IPIs for separate messages like openpic does. Instead
+ * we have a bitmap for each processor, where a 1 bit means that
+ * the corresponding message is pending for that processor.
+ * Ideally each cpu's entry would be in a different cache line.
+ * -- paulus.
+ */
+static unsigned long psurge_smp_message[NR_CPUS];
+
+void psurge_smp_message_recv(struct pt_regs *regs)
+{
+ int cpu = smp_processor_id();
+ int msg;
+
+ /* clear interrupt */
+ psurge_clr_ipi(cpu);
+
+ if (smp_num_cpus < 2)
+ return;
+
+ /* make sure there is a message there */
+ for (msg = 0; msg < 4; msg++)
+ if (test_and_clear_bit(msg, &psurge_smp_message[cpu]))
+ smp_message_recv(msg, regs);
+}
+
+void
+psurge_primary_intr(int irq, void *d, struct pt_regs *regs)
+{
+ psurge_smp_message_recv(regs);
+}
+
+static void
+smp_psurge_message_pass(int target, int msg, unsigned long data, int wait)
+{
+ int i;
+
+ if (smp_num_cpus < 2)
+ return;
+
+ for (i = 0; i < smp_num_cpus; i++) {
+ if (target == MSG_ALL
+ || (target == MSG_ALL_BUT_SELF && i != smp_processor_id())
+ || target == i) {
+ set_bit(msg, &psurge_smp_message[i]);
+ psurge_set_ipi(i);
+ }
+ }
+}
+
+/*
+ * Determine a quad card presence. We read the board ID register, we
+ * for the data bus to change to something else, and we read it again.
+ * It it's stable, then the register probably exist (ugh !)
+ */
+static int __init psurge_quad_probe(void)
+{
+ int type;
+ unsigned int i;
+
+ type = PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID);
+ if (type < PSURGE_QUAD_OKEE || type > PSURGE_QUAD_ICEGRASS
+ || type != PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID))
+ return PSURGE_DUAL;
+
+ /* looks OK, try a slightly more rigorous test */
+ /* bogus is not necessarily cacheline-aligned,
+ though I don't suppose that really matters. -- paulus */
+ for (i = 0; i < 100; i++) {
+ volatile u32 bogus[8];
+ bogus[(0+i)%8] = 0x00000000;
+ bogus[(1+i)%8] = 0x55555555;
+ bogus[(2+i)%8] = 0xFFFFFFFF;
+ bogus[(3+i)%8] = 0xAAAAAAAA;
+ bogus[(4+i)%8] = 0x33333333;
+ bogus[(5+i)%8] = 0xCCCCCCCC;
+ bogus[(6+i)%8] = 0xCCCCCCCC;
+ bogus[(7+i)%8] = 0x33333333;
+ wmb();
+ asm volatile("dcbf 0,%0" : : "r" (bogus) : "memory");
+ mb();
+ if (type != PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID))
+ return PSURGE_DUAL;
+ }
+ return type;
+}
+
+static void __init psurge_quad_init(void)
+{
+ int procbits;
+
+ if (ppc_md.progress) ppc_md.progress("psurge_quad_init", 0x351);
+ procbits = ~PSURGE_QUAD_IN(PSURGE_QUAD_WHICH_CPU);
+ if (psurge_type == PSURGE_QUAD_ICEGRASS)
+ PSURGE_QUAD_BIS(PSURGE_QUAD_RESET_CTL, procbits);
+ else
+ PSURGE_QUAD_BIC(PSURGE_QUAD_CKSTOP_CTL, procbits);
+ mdelay(33);
+ out_8(psurge_sec_intr, ~0);
+ PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_CLR, procbits);
+ PSURGE_QUAD_BIS(PSURGE_QUAD_RESET_CTL, procbits);
+ if (psurge_type != PSURGE_QUAD_ICEGRASS)
+ PSURGE_QUAD_BIS(PSURGE_QUAD_CKSTOP_CTL, procbits);
+ PSURGE_QUAD_BIC(PSURGE_QUAD_PRIMARY_ARB, procbits);
+ mdelay(33);
+ PSURGE_QUAD_BIC(PSURGE_QUAD_RESET_CTL, procbits);
+ mdelay(33);
+ PSURGE_QUAD_BIS(PSURGE_QUAD_PRIMARY_ARB, procbits);
+ mdelay(33);
+}
+
+static int __init smp_psurge_probe(void)
+{
+ int i, ncpus;
+
+ /* We don't do SMP on the PPC601 -- paulus */
+ if ((_get_PVR() >> 16) == 1)
+ return 1;
+
+ /*
+ * The powersurge cpu board can be used in the generation
+ * of powermacs that have a socket for an upgradeable cpu card,
+ * including the 7500, 8500, 9500, 9600.
+ * The device tree doesn't tell you if you have 2 cpus because
+ * OF doesn't know anything about the 2nd processor.
+ * Instead we look for magic bits in magic registers,
+ * in the hammerhead memory controller in the case of the
+ * dual-cpu powersurge board. -- paulus.
+ */
+ if (find_devices("hammerhead") == NULL)
+ return 1;
+
+ hhead_base = ioremap(HAMMERHEAD_BASE, 0x800);
+ quad_base = ioremap(PSURGE_QUAD_REG_ADDR, 1024);
+ psurge_sec_intr = hhead_base + HHEAD_SEC_INTR;
+
+ psurge_type = psurge_quad_probe();
+ if (psurge_type != PSURGE_DUAL) {
+ psurge_quad_init();
+ /* I believe we could "count" CPUs by counting 1 bits
+ * in procbits on a quad board. For now, we assume 4,
+ * non-present CPUs will just be seen as "stuck".
+ * (hope they are the higher-numbered ones -- paulus)
+ */
+ ncpus = 4;
+ } else {
+ iounmap((void *) quad_base);
+ if ((in_8(hhead_base + HHEAD_CONFIG) & 0x02) == 0) {
+ /* not a dual-cpu card */
+ iounmap((void *) hhead_base);
+ return 1;
+ }
+ ncpus = 2;
+ }
+
+ psurge_start = ioremap(PSURGE_START, 4);
+ psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4);
+
+ /* this is not actually strictly necessary -- paulus. */
+ for (i = 1; i < ncpus; ++i)
+ smp_hw_index[i] = i;
+
+ if (ppc_md.progress) ppc_md.progress("smp_psurge_probe - done", 0x352);
+
+ return ncpus;
+}
+
+static void __init smp_psurge_kick_cpu(int nr)
+{
+ void (*start)(void) = __secondary_start_psurge;
+
+ if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu", 0x353);
+
+ /* setup entry point of secondary processor */
+ switch (nr) {
+ case 2:
+ start = __secondary_start_psurge2;
+ break;
+ case 3:
+ start = __secondary_start_psurge3;
+ break;
+ }
+
+ out_be32(psurge_start, __pa(start));
+ mb();
+
+ psurge_set_ipi(nr);
+ udelay(10);
+ psurge_clr_ipi(nr);
+
+ if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu - done", 0x354);
+}
+
+/*
+ * With the dual-cpu powersurge board, the decrementers and timebases
+ * of both cpus are frozen after the secondary cpu is started up,
+ * until we give the secondary cpu another interrupt. This routine
+ * uses this to get the timebases synchronized.
+ * -- paulus.
+ */
+static void __init psurge_dual_sync_tb(int cpu_nr)
+{
+ static volatile int sec_tb_reset = 0;
+ int t;
+
+ set_dec(tb_ticks_per_jiffy);
+ set_tb(0, 0);
+ last_jiffy_stamp(cpu_nr) = 0;
+
+ if (cpu_nr > 0) {
+ mb();
+ sec_tb_reset = 1;
+ return;
+ }
+
+ /* wait for the secondary to have reset its TB before proceeding */
+ for (t = 10000000; t > 0 && !sec_tb_reset; --t)
+ ;
+
+ /* now interrupt the secondary, starting both TBs */
+ psurge_set_ipi(1);
+
+ smp_tb_synchronized = 1;
+}
+
+static void
+smp_psurge_setup_cpu(int cpu_nr)
+{
+
+ if (cpu_nr == 0) {
+ if (smp_num_cpus < 2)
+ return;
+ /* reset the entry point so if we get another intr we won't
+ * try to startup again */
+ out_be32(psurge_start, 0x100);
+ if (request_irq(30, psurge_primary_intr, 0, "primary IPI", 0))
+ printk(KERN_ERR "Couldn't get primary IPI interrupt");
+ }
+
+ if (psurge_type == PSURGE_DUAL)
+ psurge_dual_sync_tb(cpu_nr);
+}
+
+
+static void
+smp_openpic_message_pass(int target, int msg, unsigned long data, int wait)
+{
+ /* make sure we're sending something that translates to an IPI */
+ if ( msg > 0x3 ){
+ printk("SMP %d: smp_message_pass: unknown msg %d\n",
+ smp_processor_id(), msg);
+ return;
+ }
+ switch ( target )
+ {
+ case MSG_ALL:
+ openpic_cause_IPI(msg, 0xffffffff);
+ break;
+ case MSG_ALL_BUT_SELF:
+ openpic_cause_IPI(msg,
+ 0xffffffff & ~(1 << smp_hw_index[smp_processor_id()]));
+
+ break;
+ default:
+ openpic_cause_IPI(msg, smp_hw_index[1<<target]);
+ break;
+ }
+}
+
+static int
+smp_core99_probe(void)
+{
+ struct device_node *cpus;
+ int *pp;
+ int i, ncpus = 1;
+
+ if (ppc_md.progress) ppc_md.progress("smp_core99_probe", 0x345);
+#if 0 /* Paulus method.. doesn't seem to work on earlier dual G4's??*/
+ cpus = find_devices("cpus");
+ if (cpus != 0) {
+ pp = (int *) get_property(cpus, "#cpus", NULL);
+ if (pp != NULL)
+ ncpus = *pp;
+ }
+#else /* My original method -- Troy <hozer@drgw.net> */
+
+ cpus = find_type_devices("cpu");
+ if (cpus){
+ for ( ncpus = 1; cpus->next; cpus = cpus->next ){
+ ncpus++;
+ }
+ }
+#endif
+ printk("smp_core99_probe: OF reports %d cpus\n", ncpus);
+ if (ncpus > 1) {
+ openpic_request_IPIs();
+ for (i = 1; i < ncpus; ++i)
+ smp_hw_index[i] = i;
+ }
+
+ return ncpus;
+}
+
+static void
+smp_core99_kick_cpu(int nr)
+{
+ unsigned long save_int;
+ unsigned long flags;
+ volatile unsigned long *vector
+ = ((volatile unsigned long *)(KERNELBASE+0x500));
+
+ if (nr != 1)
+ return;
+ if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu", 0x346);
+
+ local_irq_save(flags);
+ local_irq_disable();
+
+ /* Save EE vector */
+ save_int = *vector;
+
+ /* Setup fake EE vector that does
+ * b __secondary_start_psurge - KERNELBASE
+ */
+ *vector = 0x48000002 +
+ ((unsigned long)__secondary_start_psurge - KERNELBASE);
+
+ /* flush data cache and inval instruction cache */
+ flush_icache_range((unsigned long) vector, (unsigned long) vector + 4);
+
+ /* Put some life in our friend */
+ feature_core99_kick_cpu1();
+
+ /* FIXME: We wait a bit for the CPU to take the exception, I should
+ * instead wait for the entry code to set something for me. Well,
+ * ideally, all that crap will be done in prom.c and the CPU left
+ * in a RAM-based wait loop like CHRP.
+ */
+ mdelay(1);
+
+ /* Restore our exception vector */
+ *vector = save_int;
+ flush_icache_range((unsigned long) vector, (unsigned long) vector + 4);
+
+ local_irq_restore(flags);
+ if (ppc_md.progress) ppc_md.progress("smp_core99_probe done", 0x347);
+}
+
+static void
+smp_core99_setup_cpu(int cpu_nr)
+{
+ /* Setup openpic */
+ do_openpic_setup_cpu();
+
+ /* Setup L2 */
+ if (cpu_nr != 0)
+ core99_init_l2();
+ else
+ if (ppc_md.progress) ppc_md.progress("core99_setup_cpu 0 done", 0x349);
+}
+
+static int
+smp_chrp_probe(void)
+{
+ extern unsigned long smp_chrp_cpu_nr;
+
+ if (smp_chrp_cpu_nr > 1)
+ openpic_request_IPIs();
+
+ return smp_chrp_cpu_nr;
+}
+
+static void
+smp_chrp_kick_cpu(int nr)
+{
+ *(unsigned long *)KERNELBASE = nr;
+ asm volatile("dcbf 0,%0"::"r"(KERNELBASE):"memory");
+}
+
+static void
+smp_chrp_setup_cpu(int cpu_nr)
+{
+ static atomic_t ready = ATOMIC_INIT(1);
+ static volatile int frozen = 0;
+
+ if (cpu_nr == 0) {
+ /* wait for all the others */
+ while (atomic_read(&ready) < smp_num_cpus)
+ barrier();
+ atomic_set(&ready, 1);
+ /* freeze the timebase */
+ call_rtas("freeze-time-base", 0, 1, NULL);
+ mb();
+ frozen = 1;
+ /* XXX assumes this is not a 601 */
+ set_tb(0, 0);
+ last_jiffy_stamp(0) = 0;
+ while (atomic_read(&ready) < smp_num_cpus)
+ barrier();
+ /* thaw the timebase again */
+ call_rtas("thaw-time-base", 0, 1, NULL);
+ mb();
+ frozen = 0;
+ smp_tb_synchronized = 1;
+ } else {
+ atomic_inc(&ready);
+ while (!frozen)
+ barrier();
+ set_tb(0, 0);
+ last_jiffy_stamp(0) = 0;
+ mb();
+ atomic_inc(&ready);
+ while (frozen)
+ barrier();
+ }
+
+ if (OpenPIC_Addr)
+ do_openpic_setup_cpu();
+}
+
+#ifdef CONFIG_POWER4
+static void
+smp_xics_message_pass(int target, int msg, unsigned long data, int wait)
+{
+ /* for now, only do reschedule messages
+ since we only have one IPI */
+ if (msg != PPC_MSG_RESCHEDULE)
+ return;
+ for (i = 0; i < smp_num_cpus; ++i) {
+ if (target == MSG_ALL || target == i
+ || (target == MSG_ALL_BUT_SELF
+ && i != smp_processor_id()))
+ xics_cause_IPI(i);
+ }
+}
+
+static int
+smp_xics_probe(void)
+{
+ return smp_chrp_cpu_nr;
+}
+
+static void
+smp_xics_setup_cpu(int cpu_nr)
+{
+ if (cpu_nr > 0)
+ xics_setup_cpu();
+}
+#endif /* CONFIG_POWER4 */
+
+static int
+smp_prep_probe(void)
+{
+ extern int mot_multi;
+
+ if (mot_multi) {
+ openpic_request_IPIs();
+ smp_hw_index[1] = 1;
+ return 2;
+ }
+
+ return 1;
+}
+
+static void
+smp_prep_kick_cpu(int nr)
+{
+ extern unsigned long *MotSave_SmpIar;
+ extern unsigned char *MotSave_CpusState[2];
+
+ *MotSave_SmpIar = (unsigned long)__secondary_start_psurge - KERNELBASE;
+ *MotSave_CpusState[1] = CPU_GOOD;
+ printk("CPU1 reset, waiting\n");
+}
+
+static void
+smp_prep_setup_cpu(int cpu_nr)
+{
+ if (OpenPIC_Addr)
+ do_openpic_setup_cpu();
+}
+
+static struct smp_ops_t {
+ void (*message_pass)(int target, int msg, unsigned long data, int wait);
+ int (*probe)(void);
+ void (*kick_cpu)(int nr);
+ void (*setup_cpu)(int nr);
+
+} *smp_ops;
+
+#define smp_message_pass(t,m,d,w) \
+ do { if (smp_ops) \
+ atomic_inc(&ipi_sent); \
+ smp_ops->message_pass((t),(m),(d),(w)); \
+ } while(0)
+
+
+/* PowerSurge-style Macs */
+static struct smp_ops_t psurge_smp_ops = {
+ smp_psurge_message_pass,
+ smp_psurge_probe,
+ smp_psurge_kick_cpu,
+ smp_psurge_setup_cpu,
+};
+
+/* Core99 Macs (dual G4s) */
+static struct smp_ops_t core99_smp_ops = {
+ smp_openpic_message_pass,
+ smp_core99_probe,
+ smp_core99_kick_cpu,
+ smp_core99_setup_cpu,
+};
+
+/* CHRP with openpic */
+static struct smp_ops_t chrp_smp_ops = {
+ smp_openpic_message_pass,
+ smp_chrp_probe,
+ smp_chrp_kick_cpu,
+ smp_chrp_setup_cpu,
+};
+
+#ifdef CONFIG_POWER4
+/* CHRP with new XICS interrupt controller */
+static struct smp_ops_t xics_smp_ops = {
+ smp_xics_message_pass,
+ smp_xics_probe,
+ smp_chrp_kick_cpu,
+ smp_xics_setup_cpu,
+};
+#endif /* CONFIG_POWER4 */
+
+/* PReP (MTX) */
+static struct smp_ops_t prep_smp_ops = {
+ smp_openpic_message_pass,
+ smp_prep_probe,
+ smp_prep_kick_cpu,
+ smp_prep_setup_cpu,
+};
+
+/*
+ * Common functions
+ */
void smp_local_timer_interrupt(struct pt_regs * regs)
{
int cpu = smp_processor_id();
@@ -101,7 +718,7 @@ void smp_local_timer_interrupt(struct pt_regs * regs)
void smp_message_recv(int msg, struct pt_regs *regs)
{
- ipi_count++;
+ atomic_inc(&ipi_recv);
switch( msg ) {
case PPC_MSG_CALL_FUNCTION:
@@ -126,47 +743,6 @@ void smp_message_recv(int msg, struct pt_regs *regs)
}
/*
- * As it is now, if we're sending two message at the same time
- * we have race conditions on Pmac. The PowerSurge doesn't easily
- * allow us to send IPI messages so we put the messages in
- * smp_message[].
- *
- * This is because don't have several IPI's on the PowerSurge even though
- * we do on the chrp. It would be nice to use actual IPI's such as with
- * openpic rather than this.
- * -- Cort
- */
-int pmac_smp_message[NR_CPUS];
-void pmac_smp_message_recv(struct pt_regs *regs)
-{
- int cpu = smp_processor_id();
- int msg;
-
- /* clear interrupt */
- if (cpu == 1)
- out_be32(psurge_sec_intr, ~0);
-
- if (smp_num_cpus < 2)
- return;
-
- /* make sure there is a message there */
- msg = pmac_smp_message[cpu];
- if (msg == 0)
- return;
-
- /* reset message */
- pmac_smp_message[cpu] = 0;
-
- smp_message_recv(msg - 1, regs);
-}
-
-void
-pmac_primary_intr(int irq, void *d, struct pt_regs *regs)
-{
- pmac_smp_message_recv(regs);
-}
-
-/*
* 750's don't broadcast tlb invalidates so
* we have to emulate that behavior.
* -- Cort
@@ -220,7 +796,7 @@ void smp_send_stop(void)
*/
static spinlock_t call_lock = SPIN_LOCK_UNLOCKED;
-static volatile struct call_data_struct {
+static struct call_data_struct {
void (*func) (void *info);
void *info;
atomic_t started;
@@ -317,87 +893,9 @@ void smp_call_function_interrupt(void)
atomic_inc(&call_data->finished);
}
-void smp_message_pass(int target, int msg, unsigned long data, int wait)
-{
- if ( !(_machine & (_MACH_Pmac|_MACH_chrp|_MACH_prep|_MACH_gemini)) )
- return;
-
- switch (_machine) {
- case _MACH_Pmac:
- /*
- * IPI's on the Pmac are a hack but without reasonable
- * IPI hardware SMP on Pmac is a hack.
- *
- * We assume here that the msg is not -1. If it is,
- * the recipient won't know the message was destined
- * for it. -- Cort
- */
- if (smp_processor_id() == 0) {
- /* primary cpu */
- if (target == 1 || target == MSG_ALL_BUT_SELF
- || target == MSG_ALL) {
- pmac_smp_message[1] = msg + 1;
- /* interrupt secondary processor */
- out_be32(psurge_sec_intr, ~0);
- out_be32(psurge_sec_intr, 0);
- }
- } else {
- /* secondary cpu */
- if (target == 0 || target == MSG_ALL_BUT_SELF
- || target == MSG_ALL) {
- pmac_smp_message[0] = msg + 1;
- /* interrupt primary processor */
- in_be32(psurge_pri_intr);
- }
- }
- if (target == smp_processor_id() || target == MSG_ALL) {
- /* sending a message to ourself */
- /* XXX maybe we shouldn't do this if ints are off */
- smp_message_recv(msg, NULL);
- }
- break;
- case _MACH_chrp:
- case _MACH_prep:
- case _MACH_gemini:
-#ifndef CONFIG_POWER4
- /* make sure we're sending something that translates to an IPI */
- if ( msg > 0x3 )
- break;
- switch ( target )
- {
- case MSG_ALL:
- openpic_cause_IPI(smp_processor_id(), msg, 0xffffffff);
- break;
- case MSG_ALL_BUT_SELF:
- openpic_cause_IPI(smp_processor_id(), msg,
- 0xffffffff & ~(1 << smp_processor_id()));
- break;
- default:
- openpic_cause_IPI(smp_processor_id(), msg, 1<<target);
- break;
- }
-#else /* CONFIG_POWER4 */
- /* for now, only do reschedule messages
- since we only have one IPI */
- if (msg != PPC_MSG_RESCHEDULE)
- break;
- for (i = 0; i < smp_num_cpus; ++i) {
- if (target == MSG_ALL || target == i
- || (target == MSG_ALL_BUT_SELF
- && i != smp_processor_id()))
- xics_cause_IPI(i);
- }
-#endif /* CONFIG_POWER4 */
- break;
- }
-}
-
void __init smp_boot_cpus(void)
{
extern struct task_struct *current_set[NR_CPUS];
- extern unsigned long smp_chrp_cpu_nr;
- extern void __secondary_start_psurge(void);
- extern void __secondary_start_chrp(void);
int i, cpu_nr;
struct task_struct *p;
unsigned long a;
@@ -411,7 +909,6 @@ void __init smp_boot_cpus(void)
* cpu 0, the master -- Cort
*/
cpu_callin_map[0] = 1;
- active_kernel_processor = 0;
current->processor = 0;
init_idle();
@@ -427,41 +924,40 @@ void __init smp_boot_cpus(void)
*/
cacheflush_time = 5 * 1024;
- if ( !(_machine & (_MACH_Pmac|_MACH_chrp|_MACH_gemini)) )
- {
- printk("SMP not supported on this machine.\n");
- return;
- }
-
- switch ( _machine )
- {
+ /* To be later replaced by some arch-specific routine */
+ switch(_machine) {
case _MACH_Pmac:
- /* assume powersurge board - 2 processors -- Cort */
- cpu_nr = 2;
- psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4);
- psurge_sec_intr = ioremap(PSURGE_SEC_INTR, 4);
- psurge_start = ioremap(PSURGE_START, 4);
+ /* Check for Core99 */
+ if (find_devices("uni-n"))
+ smp_ops = &core99_smp_ops;
+ else
+ smp_ops = &psurge_smp_ops;
break;
case _MACH_chrp:
- if (OpenPIC)
- for ( i = 0; i < 4 ; i++ )
- openpic_enable_IPI(i);
- cpu_nr = smp_chrp_cpu_nr;
+#ifndef CONFIG_POWER4
+ smp_ops = &chrp_smp_ops;
+#else
+ smp_ops = &xics_smp_ops;
+#endif /* CONFIG_POWER4 */
break;
- case _MACH_gemini:
- for ( i = 0; i < 4 ; i++ )
- openpic_enable_IPI(i);
- cpu_nr = (readb(GEMINI_CPUSTAT) & GEMINI_CPU_COUNT_MASK)>>2;
- cpu_nr = (cpu_nr == 0) ? 4 : cpu_nr;
+ case _MACH_prep:
+ smp_ops = &prep_smp_ops;
break;
+ default:
+ printk("SMP not supported on this machine.\n");
+ return;
}
+
+ /* Probe arch for CPUs */
+ cpu_nr = smp_ops->probe();
/*
* only check for cpus we know exist. We keep the callin map
* with cpus at the bottom -- Cort
*/
- for ( i = 1 ; i < cpu_nr; i++ )
- {
+ if (cpu_nr > max_cpus)
+ cpu_nr = max_cpus;
+ for (i = 1; i < cpu_nr; i++) {
int c;
struct pt_regs regs;
@@ -487,25 +983,7 @@ void __init smp_boot_cpus(void)
asm volatile("sync");
/* wake up cpus */
- switch ( _machine )
- {
- case _MACH_Pmac:
- /* setup entry point of secondary processor */
- out_be32(psurge_start, __pa(__secondary_start_psurge));
- /* interrupt secondary to begin executing code */
- out_be32(psurge_sec_intr, ~0);
- udelay(1);
- out_be32(psurge_sec_intr, 0);
- break;
- case _MACH_chrp:
- *(unsigned long *)KERNELBASE = i;
- asm volatile("dcbf 0,%0"::"r"(KERNELBASE):"memory");
- break;
- case _MACH_gemini:
- openpic_init_processor( 1<<i );
- openpic_init_processor( 0 );
- break;
- }
+ smp_ops->kick_cpu(i);
/*
* wait to see if the cpu made a callin (is actually up).
@@ -517,40 +995,108 @@ void __init smp_boot_cpus(void)
if ( cpu_callin_map[i] )
{
+ char buf[32];
+ sprintf(buf, "found cpu %d", i);
+ if (ppc_md.progress) ppc_md.progress(buf, 0x350+i);
printk("Processor %d found.\n", i);
smp_num_cpus++;
} else {
+ char buf[32];
+ sprintf(buf, "didn't find cpu %d", i);
+ if (ppc_md.progress) ppc_md.progress(buf, 0x360+i);
printk("Processor %d is stuck.\n", i);
}
}
- if (OpenPIC && (_machine & (_MACH_gemini|_MACH_chrp|_MACH_prep)))
- do_openpic_setup_cpu();
+ /* Setup CPU 0 last (important) */
+ smp_ops->setup_cpu(0);
+}
- if ( _machine == _MACH_Pmac )
- {
- /* reset the entry point so if we get another intr we won't
- * try to startup again */
- out_be32(psurge_start, 0x100);
- if (request_irq(30, pmac_primary_intr, 0, "primary IPI", 0))
- printk(KERN_ERR "Couldn't get primary IPI interrupt");
- /*
- * The decrementers of both cpus are frozen at this point
- * until we give the secondary cpu another interrupt.
- * We set them both to decrementer_count and then send
- * the interrupt. This should get the decrementers
- * synchronized.
- * -- paulus.
- */
- set_dec(tb_ticks_per_jiffy);
- if ((_get_PVR() >> 16) != 1) {
- set_tb(0, 0); /* set timebase if not 601 */
- last_jiffy_stamp(0) = 0;
+void __init smp_software_tb_sync(int cpu)
+{
+#define PASSES 4 /* 4 passes.. */
+ int pass;
+ int i, j;
+
+ /* stop - start will be the number of timebase ticks it takes for cpu0
+ * to send a message to all others and the first reponse to show up.
+ *
+ * ASSUMPTION: this time is similiar for all cpus
+ * ASSUMPTION: the time to send a one-way message is ping/2
+ */
+ register unsigned long start = 0;
+ register unsigned long stop = 0;
+ register unsigned long temp = 0;
+
+ if (smp_num_cpus < 2) {
+ smp_tb_synchronized = 1;
+ return;
+ }
+
+ /* This code need fixing on >2 CPUs --BenH/paulus */
+ if (smp_num_cpus > 2) {
+ smp_tb_synchronized = 0;
+ return;
+ }
+
+ set_tb(0, 0);
+
+ /* multiple passes to get in l1 cache.. */
+ for (pass = 2; pass < 2+PASSES; pass++){
+ if (cpu == 0){
+ mb();
+ for (i = j = 1; i < smp_num_cpus; i++, j++){
+ /* skip stuck cpus */
+ while (!cpu_callin_map[j])
+ ++j;
+ while (cpu_callin_map[j] != pass)
+ barrier();
+ }
+ mb();
+ tb_sync_flag = pass;
+ start = get_tbl(); /* start timing */
+ while (tb_sync_flag)
+ mb();
+ stop = get_tbl(); /* end timing */
+ /* theoretically, the divisor should be 2, but
+ * I get better results on my dual mtx. someone
+ * please report results on other smp machines..
+ */
+ tb_offset = (stop-start)/4;
+ mb();
+ tb_sync_flag = pass;
+ udelay(10);
+ mb();
+ tb_sync_flag = 0;
+ mb();
+ set_tb(0,0);
+ mb();
+ } else {
+ cpu_callin_map[cpu] = pass;
+ mb();
+ while (!tb_sync_flag)
+ mb(); /* wait for cpu0 */
+ mb();
+ tb_sync_flag = 0; /* send response for timing */
+ mb();
+ while (!tb_sync_flag)
+ mb();
+ temp = tb_offset; /* make sure offset is loaded */
+ while (tb_sync_flag)
+ mb();
+ set_tb(0,temp); /* now, set the timebase */
+ mb();
}
- out_be32(psurge_sec_intr, ~0);
- udelay(1);
- out_be32(psurge_sec_intr, 0);
}
+ if (cpu == 0) {
+ smp_tb_synchronized = 1;
+ printk("smp_software_tb_sync: %d passes, final offset: %ld\n",
+ PASSES, tb_offset);
+ }
+ /* so time.c doesn't get confused */
+ set_dec(tb_ticks_per_jiffy);
+ last_jiffy_stamp(cpu) = 0;
+ cpu_callin_map[cpu] = 1;
}
void __init smp_commence(void)
@@ -558,8 +1104,48 @@ void __init smp_commence(void)
/*
* Lets the callin's below out of their loop.
*/
+ if (ppc_md.progress) ppc_md.progress("smp_commence", 0x370);
wmb();
smp_commenced = 1;
+ /* if the smp_ops->setup_cpu function has not already synched the
+ * timebases with a nicer hardware-based method, do so now
+ *
+ * I am open to suggestions for improvements to this method
+ * -- Troy <hozer@drgw.net>
+ *
+ * NOTE: if you are debugging, set smp_tb_synchronized for now
+ * since if this code runs pretty early and needs all cpus that
+ * reported in in smp_callin_map to be working
+ *
+ * NOTE2: this code doesn't seem to work on > 2 cpus. -- paulus
+ */
+ if (!smp_tb_synchronized) {
+ unsigned long flags;
+ __save_and_cli(flags);
+ smp_software_tb_sync(0);
+ __restore_flags(flags);
+ }
+}
+
+void __init smp_callin(void)
+{
+ int cpu = current->processor;
+
+ smp_store_cpu_info(cpu);
+ set_dec(tb_ticks_per_jiffy);
+ cpu_callin_map[cpu] = 1;
+
+ smp_ops->setup_cpu(cpu);
+
+ init_idle();
+
+ while(!smp_commenced)
+ barrier();
+ /* see smp_commence for more info */
+ if (!smp_tb_synchronized){
+ smp_software_tb_sync(cpu);
+ }
+ __sti();
}
/* intel needs this */
@@ -576,37 +1162,6 @@ int __init start_secondary(void *unused)
return cpu_idle(NULL);
}
-void __init smp_callin(void)
-{
- smp_store_cpu_info(current->processor);
- set_dec(tb_ticks_per_jiffy);
- if (_machine == _MACH_Pmac && (_get_PVR() >> 16) != 1) {
- set_tb(0, 0); /* set timebase if not 601 */
- last_jiffy_stamp(current->processor) = 0;
- }
- init_idle();
- cpu_callin_map[current->processor] = 1;
-
-#ifndef CONFIG_POWER4
- /*
- * Each processor has to do this and this is the best
- * place to stick it for now.
- * -- Cort
- */
- if (OpenPIC && _machine & (_MACH_gemini|_MACH_chrp|_MACH_prep))
- do_openpic_setup_cpu();
-#else
- xics_setup_cpu();
-#endif /* CONFIG_POWER4 */
-#ifdef CONFIG_GEMINI
- if ( _machine == _MACH_gemini )
- gemini_init_l2();
-#endif
- while(!smp_commenced)
- barrier();
- __sti();
-}
-
void __init smp_setup(char *str, int *ints)
{
}
@@ -621,6 +1176,14 @@ void __init smp_store_cpu_info(int id)
struct cpuinfo_PPC *c = &cpu_data[id];
/* assume bogomips are same for everything */
- c->loops_per_sec = loops_per_sec;
+ c->loops_per_jiffy = loops_per_jiffy;
c->pvr = _get_PVR();
}
+
+static int __init maxcpus(char *str)
+{
+ get_option(&str, &max_cpus);
+ return 1;
+}
+
+__setup("maxcpus=", maxcpus);
diff --git a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c
index f71c8cbbf..5b36cedcc 100644
--- a/arch/ppc/kernel/time.c
+++ b/arch/ppc/kernel/time.c
@@ -67,7 +67,12 @@
#include <asm/time.h>
-void smp_local_timer_interrupt(struct pt_regs *);
+#ifdef CONFIG_SMP
+extern void smp_local_timer_interrupt(struct pt_regs *);
+extern int smp_tb_synchronized;
+#endif /* CONFIG_SMP */
+
+extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz);
/* keep track of when we need to update the rtc */
time_t last_rtc_update;
@@ -97,6 +102,36 @@ static inline int tb_delta(unsigned *jiffy_stamp) {
return delta;
}
+extern unsigned long prof_cpu_mask;
+extern unsigned int * prof_buffer;
+extern unsigned long prof_len;
+extern unsigned long prof_shift;
+extern char _stext;
+
+static inline void ppc_do_profile (unsigned long nip)
+{
+ if (!prof_buffer)
+ return;
+
+ /*
+ * Only measure the CPUs specified by /proc/irq/prof_cpu_mask.
+ * (default is all CPUs.)
+ */
+ if (!((1<<smp_processor_id()) & prof_cpu_mask))
+ return;
+
+ nip -= (unsigned long) &_stext;
+ nip >>= prof_shift;
+ /*
+ * Don't ignore out-of-bounds EIP values silently,
+ * put them into the last histogram slot, so if
+ * present, they will show up as a sharp peak.
+ */
+ if (nip > prof_len-1)
+ nip = prof_len-1;
+ atomic_inc((atomic_t *)&prof_buffer[nip]);
+}
+
/*
* timer_interrupt - gets called when the decrementer overflows,
* with interrupts disabled.
@@ -110,6 +145,9 @@ int timer_interrupt(struct pt_regs * regs)
hardirq_enter(cpu);
+ if (!user_mode(regs))
+ ppc_do_profile(instruction_pointer(regs));
+
do {
jiffy_stamp += tb_ticks_per_jiffy;
if (smp_processor_id()) continue;
@@ -151,7 +189,7 @@ int timer_interrupt(struct pt_regs * regs)
#ifdef CONFIG_SMP
smp_local_timer_interrupt(regs);
-#endif
+#endif /* CONFIG_SMP */
if (ppc_md.heartbeat && !ppc_md.heartbeat_count--)
ppc_md.heartbeat();
@@ -176,7 +214,7 @@ void do_gettimeofday(struct timeval *tv)
/* As long as timebases are not in sync, gettimeofday can only
* have jiffy resolution on SMP.
*/
- if (_machine != _MACH_Pmac)
+ if (!smp_tb_synchronized)
delta = 0;
#endif /* CONFIG_SMP */
lost_ticks = jiffies - wall_jiffies;
diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c
index 3b7473dda..8bd9ebded 100644
--- a/arch/ppc/kernel/traps.c
+++ b/arch/ppc/kernel/traps.c
@@ -65,21 +65,37 @@ int (*debugger_dabr_match)(struct pt_regs *regs);
void (*debugger_fault_handler)(struct pt_regs *regs);
#endif
#endif
+
/*
* Trap & Exception support
*/
+
+spinlock_t oops_lock = SPIN_LOCK_UNLOCKED;
+
+void die(const char * str, struct pt_regs * fp, long err)
+{
+ console_verbose();
+ spin_lock_irq(&oops_lock);
+ printk("Oops: %s, sig: %ld\n", str, err);
+ show_regs(fp);
+ print_backtrace((unsigned long *)fp->gpr[1]);
+ spin_unlock_irq(&oops_lock);
+ /* do_exit() should take care of panic'ing from an interrupt
+ * context so we don't handle it here
+ */
+ do_exit(err);
+}
+
void
_exception(int signr, struct pt_regs *regs)
{
if (!user_mode(regs))
{
- show_regs(regs);
#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
debugger(regs);
#endif
- print_backtrace((unsigned long *)regs->gpr[1]);
- panic("Exception in kernel pc %lx signal %d",regs->nip,signr);
+ die("Exception in kernel mode", regs, signr);
}
force_sig(signr, current);
}
@@ -98,7 +114,7 @@ MachineCheckException(struct pt_regs *regs)
#if defined(CONFIG_8xx) && defined(CONFIG_PCI)
/* the qspan pci read routines can cause machine checks -- Cort */
- bad_page_fault(regs, regs->dar);
+ bad_page_fault(regs, regs->dar, SIGBUS);
return;
#endif
#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
@@ -151,12 +167,10 @@ MachineCheckException(struct pt_regs *regs)
default:
printk("Unknown values in msr\n");
}
- show_regs(regs);
#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
debugger(regs);
#endif
- print_backtrace((unsigned long *)regs->gpr[1]);
- panic("machine check");
+ die("machine check", regs, SIGBUS);
}
void
@@ -217,13 +231,13 @@ emulate_instruction(struct pt_regs *regs)
uint rd;
uint retval;
- retval = EFAULT;
+ retval = EINVAL;
if (!user_mode(regs))
return retval;
if (get_user(instword, (uint *)(regs->nip)))
- return retval;
+ return EFAULT;
/* Emulate the mfspr rD, PVR.
*/
@@ -337,12 +351,10 @@ SoftwareEmulation(struct pt_regs *regs)
int errcode;
if (!user_mode(regs)) {
- show_regs(regs);
#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
debugger(regs);
#endif
- print_backtrace((unsigned long *)regs->gpr[1]);
- panic("Kernel Mode Software FPU Emulation");
+ die("Kernel Mode Software FPU Emulation", regs, SIGFPE);
}
#ifdef CONFIG_MATH_EMULATION
diff --git a/arch/ppc/lib/Makefile b/arch/ppc/lib/Makefile
index 1e973940c..b6f99174b 100644
--- a/arch/ppc/lib/Makefile
+++ b/arch/ppc/lib/Makefile
@@ -9,6 +9,6 @@ O_TARGET := lib.o
obj-y := checksum.o string.o strcase.o
-obj-$(CONFIG_SMP) := locks.o
+obj-$(CONFIG_SMP) += locks.o
include $(TOPDIR)/Rules.make
diff --git a/arch/ppc/lib/locks.c b/arch/ppc/lib/locks.c
index 60d8576da..a5b0a40a8 100644
--- a/arch/ppc/lib/locks.c
+++ b/arch/ppc/lib/locks.c
@@ -58,8 +58,9 @@ void _spin_unlock(spinlock_t *lp)
{
#ifdef DEBUG_LOCKS
if ( !lp->lock )
- printk("_spin_unlock(%p): no lock cpu %d %s/%d\n", lp,
- smp_processor_id(),current->comm,current->pid);
+ printk("_spin_unlock(%p): no lock cpu %d curr PC %p %s/%d\n",
+ lp, smp_processor_id(), __builtin_return_address(0),
+ current->comm, current->pid);
if ( lp->owner_cpu != smp_processor_id() )
printk("_spin_unlock(%p): cpu %d trying clear of cpu %d pc %lx val %lx\n",
lp, smp_processor_id(), (int)lp->owner_cpu,
diff --git a/arch/ppc/mm/fault.c b/arch/ppc/mm/fault.c
index b6da2cdfc..97bb6dbc1 100644
--- a/arch/ppc/mm/fault.c
+++ b/arch/ppc/mm/fault.c
@@ -48,7 +48,7 @@ unsigned long pte_errors = 0; /* updated by do_page_fault() */
unsigned int probingmem = 0;
extern void die_if_kernel(char *, struct pt_regs *, long);
-void bad_page_fault(struct pt_regs *, unsigned long);
+void bad_page_fault(struct pt_regs *, unsigned long, int sig);
void do_page_fault(struct pt_regs *, unsigned long, unsigned long);
/*
@@ -96,7 +96,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
#endif /* CONFIG_XMON || CONFIG_KGDB */
if (in_interrupt() || mm == NULL) {
- bad_page_fault(regs, address);
+ bad_page_fault(regs, address, SIGSEGV);
return;
}
down(&mm->mmap_sem);
@@ -182,7 +182,7 @@ bad_area:
return;
}
- bad_page_fault(regs, address);
+ bad_page_fault(regs, address, SIGSEGV);
return;
/*
@@ -194,7 +194,7 @@ out_of_memory:
printk("VM: killing process %s\n", current->comm);
if (user_mode(regs))
do_exit(SIGKILL);
- bad_page_fault(regs, address);
+ bad_page_fault(regs, address, SIGKILL);
return;
do_sigbus:
@@ -205,7 +205,7 @@ do_sigbus:
info.si_addr = (void *)address;
force_sig_info (SIGBUS, &info, current);
if (!user_mode(regs))
- bad_page_fault(regs, address);
+ bad_page_fault(regs, address, SIGBUS);
}
/*
@@ -214,8 +214,10 @@ do_sigbus:
* in traps.c.
*/
void
-bad_page_fault(struct pt_regs *regs, unsigned long address)
+bad_page_fault(struct pt_regs *regs, unsigned long address, int sig)
{
+ extern void die(const char *,struct pt_regs *,long);
+
unsigned long fixup;
/* Are we prepared to handle this fault? */
@@ -225,14 +227,11 @@ bad_page_fault(struct pt_regs *regs, unsigned long address)
}
/* kernel has accessed a bad area */
- show_regs(regs);
#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
if (debugger_kernel_faults)
debugger(regs);
#endif
- print_backtrace( (unsigned long *)regs->gpr[1] );
- panic("kernel access of bad area pc %lx lr %lx address %lX tsk %s/%d",
- regs->nip,regs->link,address,current->comm,current->pid);
+ die("kernel access of bad area", regs, sig);
}
#ifdef CONFIG_8xx
diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c
index c3d77a67e..839b618d0 100644
--- a/arch/ppc/mm/init.c
+++ b/arch/ppc/mm/init.c
@@ -34,7 +34,6 @@
#include <linux/vmalloc.h>
#include <linux/init.h>
#include <linux/delay.h>
-#include <linux/openpic.h>
#include <linux/bootmem.h>
#include <linux/highmem.h>
#ifdef CONFIG_BLK_DEV_INITRD
@@ -62,7 +61,6 @@
#include <asm/machdep.h>
#include <asm/setup.h>
#include <asm/amigahw.h>
-#include <asm/gemini.h>
#include "mem_pieces.h"
@@ -70,15 +68,17 @@
#include "4xx_tlb.h"
#endif
-#define MAX_LOW_MEM (640 << 20)
+#define MAX_LOW_MEM (512 << 20)
#define PGTOKB(pages) (((pages) * PAGE_SIZE) >> 10)
int prom_trashed;
atomic_t next_mmu_context;
+rwlock_t context_overflow_lock __cacheline_aligned = RW_LOCK_UNLOCKED;
unsigned long *end_of_DRAM;
unsigned long total_memory;
unsigned long total_lowmem;
+unsigned long ram_phys_base;
int mem_init_done;
int init_bootmem_done;
int boot_mapsize;
@@ -114,7 +114,6 @@ static void *MMU_get_page(void);
unsigned long prep_find_end_of_memory(void);
unsigned long pmac_find_end_of_memory(void);
unsigned long apus_find_end_of_memory(void);
-unsigned long gemini_find_end_of_memory(void);
extern unsigned long find_end_of_memory(void);
#ifdef CONFIG_8xx
unsigned long m8xx_find_end_of_memory(void);
@@ -127,14 +126,13 @@ unsigned long m8260_find_end_of_memory(void);
#endif /* CONFIG_8260 */
static void mapin_ram(void);
void map_page(unsigned long va, unsigned long pa, int flags);
-void set_phys_avail(struct mem_pieces *mp);
+void set_phys_avail(unsigned long total_ram);
extern void die_if_kernel(char *,struct pt_regs *,long);
extern char _start[], _end[];
extern char _stext[], etext[];
extern struct task_struct *current_set[NR_CPUS];
-struct mem_pieces phys_mem;
char *klimit = _end;
struct mem_pieces phys_avail;
@@ -199,6 +197,8 @@ int __map_without_bats;
/* max amount of RAM to use */
unsigned long __max_memory;
+/* max amount of low RAM to map in */
+unsigned long __max_low_memory = MAX_LOW_MEM;
void __bad_pte(pmd_t *pmd)
{
@@ -399,8 +399,8 @@ __ioremap(unsigned long addr, unsigned long size, unsigned long flags)
* If the address lies within the first 16 MB, assume it's in ISA
* memory space
*/
- if (p < 16*1024*1024)
- p += _ISA_MEM_BASE;
+ if ( p < 16*1024*1024 )
+ p += _ISA_MEM_BASE;
/*
* Don't allow anybody to remap normal RAM that we're using.
@@ -437,7 +437,11 @@ __ioremap(unsigned long addr, unsigned long size, unsigned long flags)
return NULL;
v = VMALLOC_VMADDR(area->addr);
} else {
+#ifndef CONFIG_HIGHMEM
if (p >= ioremap_base)
+#else
+ if (p >= ioremap_base && p < PKMAP_BASE)
+#endif /* CONFIG_HIGHMEM */
v = p;
else
v = (ioremap_bot -= size);
@@ -491,16 +495,13 @@ unsigned long iopa(unsigned long addr)
void
map_page(unsigned long va, unsigned long pa, int flags)
{
- pmd_t *pd, oldpd;
+ pmd_t *pd;
pte_t *pg;
/* Use upper 10 bits of VA to index the first level map */
pd = pmd_offset(pgd_offset_k(va), va);
- oldpd = *pd;
/* Use middle 10 bits of VA to index the second-level map */
pg = pte_alloc(pd, va);
- if (pmd_none(oldpd) && mem_init_done)
- set_pgdir(va, *(pgd_t *)pd);
set_pte(pg, mk_pte_phys(pa & PAGE_MASK, __pgprot(flags)));
if (mem_init_done)
flush_hash_page(0, va);
@@ -532,6 +533,8 @@ local_flush_tlb_all(void)
* 0xd0000000 on 64-bit machines. */
flush_hash_segments(0xd, 0xffffff);
#else
+ /* this could cause problems on SMP with nobats -- paulus */
+ /* XXX no hash_table_lock? interesting -- paulus */
__clear_user(Hash, Hash_size);
_tlbia();
#ifdef CONFIG_SMP
@@ -548,6 +551,27 @@ local_flush_tlb_all(void)
void
local_flush_tlb_mm(struct mm_struct *mm)
{
+ if (mm->context == 0) {
+ /* don't try to reassign a new context to the kernel */
+ /*
+ * This could cause problems on SMP if we aren't using
+ * the BATs (e.g. on POWER4 or if the nobats option is used).
+ * The problem scenario is that one cpu is doing
+ * flush_hash_page or similar when another cpu clears
+ * out the HPTEs which map the flush_hash_page text
+ * and the hash table. hash_page will then deadlock.
+ * We need some way to have "protected" HPTEs or else
+ * do all hash-table manipulation with the MMU off.
+ * -- paulus.
+ */
+#ifdef CONFIG_PPC64BRIDGE
+ flush_hash_segments(0xd, 0xf);
+#else
+ flush_hash_segments(0xc, 0xf);
+#endif CONFIG_PPC64BRIDGE
+ _tlbia();
+ return;
+ }
mm->context = NO_CONTEXT;
if (mm == current->mm)
activate_mm(mm, mm);
@@ -581,16 +605,18 @@ local_flush_tlb_range(struct mm_struct *mm, unsigned long start, unsigned long e
{
start &= PAGE_MASK;
- if (end - start > 20 * PAGE_SIZE)
- {
- flush_tlb_mm(mm);
- return;
+ if (mm->context != 0) {
+ if (end > TASK_SIZE)
+ end = TASK_SIZE;
+ if (end - start > 20 * PAGE_SIZE) {
+ flush_tlb_mm(mm);
+ return;
+ }
}
- for (; start < end && start < TASK_SIZE; start += PAGE_SIZE)
- {
+ for (; start < end; start += PAGE_SIZE)
flush_hash_page(mm->context, start);
- }
+
#ifdef CONFIG_SMP
smp_send_tlb_invalidate(0);
#endif
@@ -608,23 +634,36 @@ mmu_context_overflow(void)
struct task_struct *tsk;
printk(KERN_DEBUG "mmu_context_overflow\n");
- read_lock(&tasklist_lock);
- for_each_task(tsk) {
- if (tsk->mm)
- tsk->mm->context = NO_CONTEXT;
- }
- read_unlock(&tasklist_lock);
- flush_hash_segments(0x10, 0xffffff);
+ /* acquire the write lock for context overflow */
+ write_lock (&context_overflow_lock);
+ /* recheck if overflow still exists */
+ if (atomic_read(&next_mmu_context) == LAST_CONTEXT) {
+ read_lock(&tasklist_lock);
+ for_each_task(tsk) {
+ if (tsk->mm)
+ tsk->mm->context = NO_CONTEXT;
+ }
+ read_unlock(&tasklist_lock);
+ flush_hash_segments(0x10, 0xffffff);
#ifdef CONFIG_SMP
- smp_send_tlb_invalidate(0);
+ smp_send_tlb_invalidate(0);
#endif
- atomic_set(&next_mmu_context, 0);
+ atomic_set(&next_mmu_context, 0);
+ }
+ write_unlock (&context_overflow_lock);
/* make sure current always has a context */
- current->mm->context = MUNGE_CONTEXT(atomic_inc_return(&next_mmu_context));
- /* The PGD is only a placeholder. It is only used on
- * 8xx processors.
- */
- set_context(current->mm->context, current->mm->pgd);
+ /* need to check to assure current task has an mm */
+ /* - idle thread does not have an MM */
+ if (current->mm) {
+ current->mm->context = MUNGE_CONTEXT(atomic_inc_return(&next_mmu_context));
+ set_context(current->mm->context, current->mm->pgd);
+ }
+}
+#else /* CONFIG_8xx */
+void
+mmu_context_overflow(void)
+{
+ atomic_set(&next_mmu_context, -1);
}
#endif /* CONFIG_8xx */
@@ -727,22 +766,20 @@ void __init setbat(int index, unsigned long virt, unsigned long phys,
static void __init mapin_ram(void)
{
- int i;
unsigned long v, p, s, f;
#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx) && !defined(CONFIG_POWER4)
if (!__map_without_bats) {
- unsigned long tot, mem_base, bl, done;
+ unsigned long tot, bl, done;
unsigned long max_size = (256<<20);
unsigned long align;
/* Set up BAT2 and if necessary BAT3 to cover RAM. */
- mem_base = __pa(KERNELBASE);
/* Make sure we don't map a block larger than the
smallest alignment of the physical address. */
- /* alignment of mem_base */
- align = ~(mem_base-1) & mem_base;
+ /* alignment of ram_phys_base */
+ align = ~(ram_phys_base-1) & ram_phys_base;
/* set BAT block size to MIN(max_size, align) */
if (align && align < max_size)
max_size = align;
@@ -753,7 +790,7 @@ static void __init mapin_ram(void)
break;
}
- setbat(2, KERNELBASE, mem_base, bl, RAM_PAGE);
+ setbat(2, KERNELBASE, ram_phys_base, bl, RAM_PAGE);
done = (unsigned long)bat_addrs[2].limit - KERNELBASE + 1;
if ((done < tot) && !bat_addrs[3].limit) {
/* use BAT3 to cover a bit more */
@@ -761,41 +798,35 @@ static void __init mapin_ram(void)
for (bl = 128<<10; bl < max_size; bl <<= 1)
if (bl * 2 > tot)
break;
- setbat(3, KERNELBASE+done, mem_base+done, bl,
+ setbat(3, KERNELBASE+done, ram_phys_base+done, bl,
RAM_PAGE);
}
}
#endif /* !CONFIG_4xx && !CONFIG_8xx && !CONFIG_POWER4 */
- for (i = 0; i < phys_mem.n_regions; ++i) {
- v = (ulong)__va(phys_mem.regions[i].address);
- p = phys_mem.regions[i].address;
- if (p >= total_lowmem)
- break;
- for (s = 0; s < phys_mem.regions[i].size; s += PAGE_SIZE) {
- /* On the MPC8xx, we want the page shared so we
- * don't get ASID compares on kernel space.
- */
- f = _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_SHARED;
+ v = KERNELBASE;
+ p = ram_phys_base;
+ for (s = 0; s < total_lowmem; s += PAGE_SIZE) {
+ /* On the MPC8xx, we want the page shared so we
+ * don't get ASID compares on kernel space.
+ */
+ f = _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_SHARED;
#if defined(CONFIG_KGDB) || defined(CONFIG_XMON)
- /* Allows stub to set breakpoints everywhere */
- f |= _PAGE_RW | _PAGE_DIRTY | _PAGE_HWWRITE;
+ /* Allows stub to set breakpoints everywhere */
+ f |= _PAGE_RW | _PAGE_DIRTY | _PAGE_HWWRITE;
#else
- if ((char *) v < _stext || (char *) v >= etext)
- f |= _PAGE_RW | _PAGE_DIRTY | _PAGE_HWWRITE;
+ if ((char *) v < _stext || (char *) v >= etext)
+ f |= _PAGE_RW | _PAGE_DIRTY | _PAGE_HWWRITE;
#ifndef CONFIG_8xx
- else
- /* On the powerpc (not 8xx), no user access
- forces R/W kernel access */
- f |= _PAGE_USER;
+ else
+ /* On the powerpc (not 8xx), no user access
+ forces R/W kernel access */
+ f |= _PAGE_USER;
#endif /* CONFIG_8xx */
#endif /* CONFIG_KGDB */
- map_page(v, p, f);
- v += PAGE_SIZE;
- p += PAGE_SIZE;
- if (p >= total_lowmem)
- break;
- }
+ map_page(v, p, f);
+ v += PAGE_SIZE;
+ p += PAGE_SIZE;
}
}
@@ -922,27 +953,64 @@ MMU_init(void)
mtspr(SPRN_DCCR, 0x80000000); /* 128 MB of data space at 0x0. */
mtspr(SPRN_ICCR, 0x80000000); /* 128 MB of instr. space at 0x0. */
}
-#else
- /* How about ppc_md.md_find_end_of_memory instead of these
- * ifdefs? -- Dan.
- */
-#ifdef CONFIG_BOOTX_TEXT
-extern boot_infos_t *disp_bi;
+
+#elif defined(CONFIG_8xx)
+void __init MMU_init(void)
+{
+ if ( ppc_md.progress ) ppc_md.progress("MMU:enter", 0x111);
+
+ total_memory = total_lowmem = m8xx_find_end_of_memory();
+#ifdef CONFIG_HIGHMEM
+ if (total_lowmem > MAX_LOW_MEM) {
+ total_lowmem = MAX_LOW_MEM;
+ mem_pieces_remove(&phys_avail, total_lowmem,
+ total_memory - total_lowmem, 0);
+ }
+#endif /* CONFIG_HIGHMEM */
+ end_of_DRAM = __va(total_lowmem);
+ set_phys_avail(total_lowmem);
+
+ /* Map in all of RAM starting at KERNELBASE */
+ mapin_ram();
+
+ /* Now map in some of the I/O space that is generically needed
+ * or shared with multiple devices.
+ * All of this fits into the same 4Mbyte region, so it only
+ * requires one page table page.
+ */
+ ioremap(IMAP_ADDR, IMAP_SIZE);
+#ifdef CONFIG_MBX
+ ioremap(NVRAM_ADDR, NVRAM_SIZE);
+ ioremap(MBX_CSR_ADDR, MBX_CSR_SIZE);
+ ioremap(PCI_CSR_ADDR, PCI_CSR_SIZE);
+
+ /* Map some of the PCI/ISA I/O space to get the IDE interface.
+ */
+ ioremap(PCI_ISA_IO_ADDR, 0x4000);
+ ioremap(PCI_IDE_ADDR, 0x4000);
+#endif
+#ifdef CONFIG_RPXLITE
+ ioremap(RPX_CSR_ADDR, RPX_CSR_SIZE);
+ ioremap(HIOX_CSR_ADDR, HIOX_CSR_SIZE);
+#endif
+#ifdef CONFIG_RPXCLASSIC
+ ioremap(PCI_CSR_ADDR, PCI_CSR_SIZE);
+ ioremap(RPX_CSR_ADDR, RPX_CSR_SIZE);
#endif
+ if ( ppc_md.progress ) ppc_md.progress("MMU:exit", 0x211);
+}
+
+#else /* not 4xx or 8xx */
void __init MMU_init(void)
{
if ( ppc_md.progress ) ppc_md.progress("MMU:enter", 0x111);
-#ifndef CONFIG_8xx
+
if (have_of)
total_memory = pmac_find_end_of_memory();
#ifdef CONFIG_APUS
else if (_machine == _MACH_apus )
total_memory = apus_find_end_of_memory();
#endif
-#ifdef CONFIG_GEMINI
- else if ( _machine == _MACH_gemini )
- total_memory = gemini_find_end_of_memory();
-#endif /* CONFIG_GEMINI */
#if defined(CONFIG_8260)
else
total_memory = m8260_find_end_of_memory();
@@ -950,16 +1018,17 @@ void __init MMU_init(void)
else /* prep */
total_memory = prep_find_end_of_memory();
#endif
-
+ if (__max_memory && total_memory > __max_memory)
+ total_memory = __max_memory;
total_lowmem = total_memory;
-#ifdef CONFIG_HIGHMEM
- if (total_lowmem > MAX_LOW_MEM) {
- total_lowmem = MAX_LOW_MEM;
- mem_pieces_remove(&phys_avail, total_lowmem,
- total_memory - total_lowmem, 0);
- }
+ if (total_lowmem > __max_low_memory) {
+ total_lowmem = __max_low_memory;
+#ifndef CONFIG_HIGHMEM
+ total_memory = total_lowmem;
#endif /* CONFIG_HIGHMEM */
+ }
end_of_DRAM = __va(total_lowmem);
+ set_phys_avail(total_lowmem);
if ( ppc_md.progress ) ppc_md.progress("MMU:hash init", 0x300);
hash_init();
@@ -991,12 +1060,15 @@ void __init MMU_init(void)
ioremap_base = 0xf0000000;
break;
case _MACH_chrp:
- setbat(0, 0xf8000000, 0xf8000000, 0x08000000, IO_PAGE);
-#ifdef CONFIG_PPC64BRIDGE
- setbat(1, 0x80000000, 0xc0000000, 0x10000000, IO_PAGE);
-#else
- setbat(1, 0x80000000, 0x80000000, 0x10000000, IO_PAGE);
- setbat(3, 0x90000000, 0x90000000, 0x10000000, IO_PAGE);
+ /*
+ * The code below tends to get removed, please don't take it out.
+ * The F50 needs this mapping and it you take it out I'll track you
+ * down and slap your hands. If it causes problems please email me.
+ * -- Cort <cort@fsmlabs.com>
+ */
+#ifndef CONFIG_POWER3
+ setbat(0, 0x80000000, 0x80000000, 0x10000000, IO_PAGE);
+ setbat(1, 0x90000000, 0x90000000, 0x10000000, IO_PAGE);
#endif
break;
case _MACH_Pmac:
@@ -1008,10 +1080,6 @@ void __init MMU_init(void)
/* Map chip and ZorroII memory */
setbat(1, zTwoBase, 0x00000000, 0x01000000, IO_PAGE);
break;
- case _MACH_gemini:
- setbat(0, 0xf0000000, 0xf0000000, 0x10000000, IO_PAGE);
- setbat(1, 0x80000000, 0x80000000, 0x10000000, IO_PAGE);
- break;
case _MACH_8260:
/* Map the IMMR, plus anything else we can cover
* in that upper space according to the memory controller
@@ -1025,46 +1093,7 @@ void __init MMU_init(void)
}
ioremap_bot = ioremap_base;
#endif /* CONFIG_POWER4 */
-#else /* CONFIG_8xx */
-
- total_memory = total_lowmem = m8xx_find_end_of_memory();
-#ifdef CONFIG_HIGHMEM
- if (total_lowmem > MAX_LOW_MEM) {
- total_lowmem = MAX_LOW_MEM;
- mem_pieces_remove(&phys_avail, total_lowmem,
- total_memory - total_lowmem, 0);
- }
-#endif /* CONFIG_HIGHMEM */
- end_of_DRAM = __va(total_lowmem);
-
- /* Map in all of RAM starting at KERNELBASE */
- mapin_ram();
-
- /* Now map in some of the I/O space that is generically needed
- * or shared with multiple devices.
- * All of this fits into the same 4Mbyte region, so it only
- * requires one page table page.
- */
- ioremap(IMAP_ADDR, IMAP_SIZE);
-#ifdef CONFIG_MBX
- ioremap(NVRAM_ADDR, NVRAM_SIZE);
- ioremap(MBX_CSR_ADDR, MBX_CSR_SIZE);
- ioremap(PCI_CSR_ADDR, PCI_CSR_SIZE);
- /* Map some of the PCI/ISA I/O space to get the IDE interface.
- */
- ioremap(PCI_ISA_IO_ADDR, 0x4000);
- ioremap(PCI_IDE_ADDR, 0x4000);
-#endif
-#ifdef CONFIG_RPXLITE
- ioremap(RPX_CSR_ADDR, RPX_CSR_SIZE);
- ioremap(HIOX_CSR_ADDR, HIOX_CSR_SIZE);
-#endif
-#ifdef CONFIG_RPXCLASSIC
- ioremap(PCI_CSR_ADDR, PCI_CSR_SIZE);
- ioremap(RPX_CSR_ADDR, RPX_CSR_SIZE);
-#endif
-#endif /* CONFIG_8xx */
if ( ppc_md.progress ) ppc_md.progress("MMU:exit", 0x211);
#ifdef CONFIG_BOOTX_TEXT
/* Must be done last, or ppc_md.progress will die */
@@ -1189,7 +1218,8 @@ void __init mem_init(void)
#if defined(CONFIG_ALL_PPC)
/* mark the RTAS pages as reserved */
if ( rtas_data )
- for (addr = rtas_data; addr < PAGE_ALIGN(rtas_data+rtas_size) ;
+ for (addr = (ulong)__va(rtas_data);
+ addr < PAGE_ALIGN((ulong)__va(rtas_data)+rtas_size) ;
addr += PAGE_SIZE)
SetPageReserved(virt_to_page(addr));
#endif /* defined(CONFIG_ALL_PPC) */
@@ -1249,7 +1279,7 @@ void __init mem_init(void)
unsigned long __init pmac_find_end_of_memory(void)
{
unsigned long a, total;
- unsigned long ram_limit = 0xe0000000 - KERNELBASE;
+ struct mem_pieces phys_mem;
memory_node = find_devices("memory");
if (memory_node == NULL) {
@@ -1260,8 +1290,7 @@ unsigned long __init pmac_find_end_of_memory(void)
/*
* Find out where physical memory is, and check that it
* starts at 0 and is contiguous. It seems that RAM is
- * always physically contiguous on Power Macintoshes,
- * because MacOS can't cope if it isn't.
+ * always physically contiguous on Power Macintoshes.
*
* Supporting discontiguous physical memory isn't hard,
* it just makes the virtual <-> physical mapping functions
@@ -1274,23 +1303,14 @@ unsigned long __init pmac_find_end_of_memory(void)
a = phys_mem.regions[0].address;
if (a != 0)
panic("RAM doesn't start at physical address 0");
- if (__max_memory == 0 || __max_memory > ram_limit)
- __max_memory = ram_limit;
- if (phys_mem.regions[0].size >= __max_memory) {
- phys_mem.regions[0].size = __max_memory;
- phys_mem.n_regions = 1;
- }
total = phys_mem.regions[0].size;
-
+
if (phys_mem.n_regions > 1) {
printk("RAM starting at 0x%x is not contiguous\n",
phys_mem.regions[1].address);
printk("Using RAM from 0 to 0x%lx\n", total-1);
- phys_mem.n_regions = 1;
}
- set_phys_avail(&phys_mem);
-
return total;
}
#endif /* CONFIG_ALL_PPC */
@@ -1305,7 +1325,11 @@ unsigned long __init pmac_find_end_of_memory(void)
unsigned long __init prep_find_end_of_memory(void)
{
unsigned long total;
+#ifdef CONFIG_PREP_RESIDUAL
total = res->TotalMemory;
+#else
+ total = 0;
+#endif
if (total == 0 )
{
@@ -1317,33 +1341,11 @@ unsigned long __init prep_find_end_of_memory(void)
total = 0x02000000;
printk("Ramsize default to be %ldM\n", total>>20);
}
- mem_pieces_append(&phys_mem, 0, total);
- set_phys_avail(&phys_mem);
return (total);
}
#endif /* defined(CONFIG_ALL_PPC) */
-
-#if defined(CONFIG_GEMINI)
-unsigned long __init gemini_find_end_of_memory(void)
-{
- unsigned long total;
- unsigned char reg;
-
- reg = readb(GEMINI_MEMCFG);
- total = ((1<<((reg & 0x7) - 1)) *
- (8<<((reg >> 3) & 0x7)));
- total *= (1024*1024);
- phys_mem.regions[0].address = 0;
- phys_mem.regions[0].size = total;
- phys_mem.n_regions = 1;
-
- set_phys_avail(&phys_mem);
- return phys_mem.regions[0].size;
-}
-#endif /* defined(CONFIG_GEMINI) */
-
#ifdef CONFIG_8260
/*
* Same hack as 8xx.
@@ -1355,12 +1357,7 @@ unsigned long __init m8260_find_end_of_memory(void)
binfo = (bd_t *)__res;
- phys_mem.regions[0].address = 0;
- phys_mem.regions[0].size = binfo->bi_memsize;
- phys_mem.n_regions = 1;
-
- set_phys_avail(&phys_mem);
- return phys_mem.regions[0].size;
+ return binfo->bi_memsize;
}
#endif /* CONFIG_8260 */
@@ -1369,6 +1366,7 @@ unsigned long __init m8260_find_end_of_memory(void)
unsigned long __init apus_find_end_of_memory(void)
{
int shadow = 0;
+ unsigned long total;
/* The memory size reported by ADOS excludes the 512KB
reserved for PPC exception registers and possibly 512KB
@@ -1394,43 +1392,28 @@ unsigned long __init apus_find_end_of_memory(void)
memory[0].size = ((size+0x001fffff) & 0xffe00000);
}
- /* Now register the memory block. */
- mem_pieces_append(&phys_mem, memory[0].addr, memory[0].size);
- set_phys_avail(&phys_mem);
+ total = memory[0].size;
/* Remove the memory chunks that are controlled by special
Phase5 hardware. */
- {
- unsigned long top = memory[0].addr + memory[0].size;
- /* Remove the upper 512KB if it contains a shadow of
- the ADOS ROM. FIXME: It might be possible to
- disable this shadow HW. Check the booter
- (ppc_boot.c) */
- if (shadow)
- {
- top -= HARDWARE_MAPPED_SIZE;
- mem_pieces_remove(&phys_avail, top,
- HARDWARE_MAPPED_SIZE, 0);
- }
-
- /* Remove the upper 512KB where the PPC exception
- vectors are mapped. */
- top -= HARDWARE_MAPPED_SIZE;
-#if 0
- /* This would be neat, but it breaks on A3000 machines!? */
- mem_pieces_remove(&phys_avail, top, 16384, 0);
-#else
- mem_pieces_remove(&phys_avail, top, HARDWARE_MAPPED_SIZE, 0);
-#endif
+ /* Remove the upper 512KB if it contains a shadow of
+ the ADOS ROM. FIXME: It might be possible to
+ disable this shadow HW. Check the booter
+ (ppc_boot.c) */
+ if (shadow)
+ total -= HARDWARE_MAPPED_SIZE;
- }
+ /* Remove the upper 512KB where the PPC exception
+ vectors are mapped. */
+ total -= HARDWARE_MAPPED_SIZE;
/* Linux/APUS only handles one block of memory -- the one on
the PowerUP board. Other system memory is horrible slow in
comparison. The user can use other memory for swapping
using the z2ram device. */
- return memory[0].addr + memory[0].size;
+ ram_phys_base = memory[0].addr;
+ return total;
}
#endif /* CONFIG_APUS */
@@ -1440,12 +1423,11 @@ unsigned long __init apus_find_end_of_memory(void)
static void __init hash_init(void)
{
int Hash_bits, mb, mb2;
- unsigned int hmask, ramsize, h;
+ unsigned int hmask, h;
extern unsigned int hash_page_patch_A[], hash_page_patch_B[],
hash_page_patch_C[], hash_page[];
- ramsize = (ulong)end_of_DRAM - KERNELBASE;
#ifdef CONFIG_PPC64BRIDGE
/* The hash table has already been allocated and initialized
in prom.c */
@@ -1464,7 +1446,7 @@ static void __init hash_init(void)
* Allow 64k of hash table for every 16MB of memory,
* up to a maximum of 2MB.
*/
- for (h = 64<<10; h < ramsize / 256 && h < (2<<20); h *= 2)
+ for (h = 64<<10; h < total_memory / 256 && h < (2<<20); h *= 2)
;
Hash_size = h;
Hash_mask = (h >> 6) - 1;
@@ -1498,8 +1480,8 @@ static void __init hash_init(void)
Hash = 0;
#endif /* CONFIG_PPC64BRIDGE */
- printk("Total memory = %dMB; using %ldkB for hash table (at %p)\n",
- ramsize >> 20, Hash_size >> 10, Hash);
+ printk("Total memory = %ldMB; using %ldkB for hash table (at %p)\n",
+ total_memory >> 20, Hash_size >> 10, Hash);
if ( Hash_size )
{
if ( ppc_md.progress ) ppc_md.progress("hash:patch", 0x345);
@@ -1560,12 +1542,7 @@ unsigned long __init m8xx_find_end_of_memory(void)
binfo = (bd_t *)__res;
- phys_mem.regions[0].address = 0;
- phys_mem.regions[0].size = binfo->bi_memsize;
- phys_mem.n_regions = 1;
-
- set_phys_avail(&phys_mem);
- return phys_mem.regions[0].address + phys_mem.regions[0].size;
+ return binfo->bi_memsize;
}
#endif /* !CONFIG_4xx && !CONFIG_8xx */
@@ -1582,20 +1559,16 @@ oak_find_end_of_memory(void)
unsigned long *ret;
bd_t *bip = (bd_t *)__res;
- phys_mem.regions[0].address = 0;
- phys_mem.regions[0].size = bip->bi_memsize;
- phys_mem.n_regions = 1;
-
- set_phys_avail(&phys_mem);
- return (phys_mem.regions[0].address + phys_mem.regions[0].size);
+ return bip->bi_memsize;
}
#endif
/*
- * Set phys_avail to phys_mem less the kernel text/data/bss.
+ * Set phys_avail to the amount of physical memory,
+ * less the kernel text/data/bss.
*/
void __init
-set_phys_avail(struct mem_pieces *mp)
+set_phys_avail(unsigned long total_memory)
{
unsigned long kstart, ksize;
@@ -1604,7 +1577,9 @@ set_phys_avail(struct mem_pieces *mp)
* physical memory.
*/
- phys_avail = *mp;
+ phys_avail.regions[0].address = 0;
+ phys_avail.regions[0].size = total_memory;
+ phys_avail.n_regions = 1;
/*
* Map out the kernel text/data/bss from the available physical
diff --git a/arch/ppc/xmon/start.c b/arch/ppc/xmon/start.c
index 499c5b6c8..611b1e069 100644
--- a/arch/ppc/xmon/start.c
+++ b/arch/ppc/xmon/start.c
@@ -14,6 +14,10 @@
#include <asm/bootx.h>
#include <asm/feature.h>
#include <asm/processor.h>
+#include <asm/delay.h>
+#ifdef CONFIG_SMP
+#include <asm/bitops.h>
+#endif
static volatile unsigned char *sccc, *sccd;
unsigned long TXRDY, RXRDY;
@@ -22,10 +26,10 @@ extern void prom_drawchar(char);
extern void prom_drawstring(const char *str);
static int xmon_expect(const char *str, unsigned int timeout);
-static int console = 0;
-static int use_screen = 1; /* default */
-static int via_modem = 0;
-static int xmon_use_sccb = 0;
+static int console;
+static int use_screen;
+static int via_modem = 1;
+static int xmon_use_sccb;
static struct device_node *macio_node;
#define TB_SPEED 25000000
@@ -53,28 +57,32 @@ xmon_map_scc(void)
use_screen = 0;
- if ( _machine == _MACH_Pmac )
- {
+ if (_machine == _MACH_Pmac) {
struct device_node *np;
unsigned long addr;
#ifdef CONFIG_BOOTX_TEXT
extern boot_infos_t *disp_bi;
+ /* see if there is a keyboard in the device tree
+ with a parent of type "adb" */
+ for (np = find_devices("keyboard"); np; np = np->next)
+ if (np->parent && np->parent->type
+ && strcmp(np->parent->type, "adb") == 0)
+ break;
+
/* needs to be hacked if xmon_printk is to be used
from within find_via_pmu() */
#ifdef CONFIG_ADB_PMU
- if (!via_modem && disp_bi && find_via_pmu()) {
- prom_drawstring("xmon uses screen and keyboard\n");
+ if (np != NULL && disp_bi && find_via_pmu())
use_screen = 1;
- }
#endif
#ifdef CONFIG_ADB_CUDA
- if (!via_modem && disp_bi ) {
- prom_drawstring("xmon uses screen and keyboard\n");
+ if (np != NULL && disp_bi && find_via_cuda())
use_screen = 1;
- }
-#endif
#endif
+ if (use_screen)
+ prom_drawstring("xmon uses screen and keyboard\n");
+#endif /* CONFIG_BOOTX_TEXT */
#ifdef CHRP_ESCC
addr = 0xc1013020;
@@ -93,15 +101,6 @@ xmon_map_scc(void)
sccc = base + (addr & ~PAGE_MASK);
sccd = sccc + 0x10;
}
- else if ( _machine & _MACH_gemini )
- {
- /* should already be mapped by the kernel boot */
- sccc = (volatile unsigned char *) 0xffeffb0d;
- sccd = (volatile unsigned char *) 0xffeffb08;
- TXRDY = 0x20;
- RXRDY = 1;
- console = 1;
- }
else
{
/* should already be mapped by the kernel boot */
@@ -140,12 +139,22 @@ xmon_write(void *handle, void *ptr, int nb)
char *p = ptr;
int i, c, ct;
+#ifdef CONFIG_SMP
+ static unsigned long xmon_write_lock;
+ int lock_wait = 1000000;
+ int locked;
+
+ while ((locked = test_and_set_bit(0, &xmon_write_lock)) != 0)
+ if (--lock_wait == 0)
+ break;
+#endif
+
#ifdef CONFIG_BOOTX_TEXT
if (use_screen) {
/* write it on the screen */
for (i = 0; i < nb; ++i)
prom_drawchar(*p++);
- return nb;
+ goto out;
}
#endif
if (!scc_initialized)
@@ -166,8 +175,15 @@ xmon_write(void *handle, void *ptr, int nb)
}
buf_access();
*sccd = c;
+ eieio();
}
- return i;
+
+ out:
+#ifdef CONFIG_SMP
+ if (!locked)
+ clear_bit(0, &xmon_write_lock);
+#endif
+ return nb;
}
int xmon_wants_key;
diff --git a/arch/ppc/xmon/xmon.c b/arch/ppc/xmon/xmon.c
index 49c3be834..65082d458 100644
--- a/arch/ppc/xmon/xmon.c
+++ b/arch/ppc/xmon/xmon.c
@@ -406,6 +406,7 @@ cmds(struct pt_regs *excp)
break;
case 'M':
print_sysmap();
+ break;
case 'S':
super_regs();
break;
@@ -795,6 +796,8 @@ print_sysmap(void)
extern char *sysmap;
if ( sysmap )
printf("System.map: \n%s", sysmap);
+ else
+ printf("No System.map\n");
}
void