diff -bEruN linux-2.4.20-my/arch/mips/brcm-boards/bcm947xx/compressed/Makefile linux-2.4.20-nc/arch/mips/brcm-boards/bcm947xx/compressed/Makefile
--- linux-2.4.20-my/arch/mips/brcm-boards/bcm947xx/compressed/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/arch/mips/brcm-boards/bcm947xx/compressed/Makefile	2006-06-02 08:21:25.000000000 -0700
@@ -0,0 +1,90 @@
+#
+# Makefile for Broadcom BCM947XX boards
+#
+# Copyright 2005, Broadcom Corporation
+# All Rights Reserved.
+# 
+# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+#
+# $Id: Makefile,v 1.1.1.9 2005/03/07 07:30:37 kanki Exp $
+#
+
+
+# Link at 3 MB offset in RAM
+TEXT_START	?= 0x80300000
+
+
+OBJCOPY		:= $(CROSS_COMPILE)objcopy -O binary -R .reginfo -R .note -R .comment -R .mdebug -S
+OBJCOPYSREC	:= $(CROSS_COMPILE)objcopy -O srec -R .reginfo -R .note -R .comment -R .mdebug -S
+
+vpath %.c $(SRCBASE)/shared
+vpath %.S $(SRCBASE)/shared
+vpath %.lds.in $(SRCBASE)/shared
+
+ASFLAGS		+= -D__ASSEMBLY__ -DLOADADDR=$(LOADADDR)
+CFLAGS		+= -DLOADADDR=$(LOADADDR)
+# The self-decompresor is standalone, get rid of the linux flags
+CFLAGS		:= $(subst -Dlinux,,$(CFLAGS))
+CFLAGS		+= -Ulinux -D_MINOSL_ -ffreestanding
+ifdef CONFIG_MCOUNT
+CFLAGS		:= $(subst -pg,,$(CFLAGS))
+endif
+CFLAGS		+= -ffunction-sections $(call check_gcc, -fvtable-gc, )
+SEDFLAGS	:= s/TEXT_START/$(TEXT_START)/
+
+SYSTEM		?= $(TOPDIR)/vmlinux
+OBJECTS		:= boot.o sbsdram.o load.o sflash.o sbmips.o sbutils.o \
+		   min_osl.o sromstubs.o nvramstubs.o bcmstdlib.o
+
+# Default to bzip2
+COMPRESS	?= bzip2 -c
+
+ifneq ($(findstring gzip,$(COMPRESS)),)
+CFLAGS		+= -DUSE_GZIP
+else
+ifneq ($(findstring bzip2,$(COMPRESS)),)
+CFLAGS		+= -DUSE_BZIP2
+else
+COMPRESS	:= cat
+endif
+endif
+
+all: zImage vmlinuz
+
+# Don't build dependencies, this may die if $(CC) isn't gcc
+dep:
+
+zImage: vmlinux
+	$(OBJCOPY) $< $@
+
+# Link the loader and the kernel binary together
+vmlinux: vmlinux.lds $(OBJECTS) piggy.o
+	$(LD) -static --gc-sections -no-warn-mismatch -T vmlinux.lds -o $@ $(OBJECTS) piggy.o
+
+vmlinux.lds: hndrte.lds.in Makefile
+	@sed "$(SEDFLAGS)" < $< > $@
+
+# Create a linkable version of the (possibly compressed) kernel binary
+piggy.o: piggz piggy.lds
+	$(LD) -no-warn-mismatch -T piggy.lds -r -o $@ -b binary piggz -b elf32-tradlittlemips
+
+piggy.lds:
+	@echo "SECTIONS { .data : { input_len = .; LONG(input_data_end - input_data) input_data = .; *(.data) input_data_end = .; }}" > $@
+
+# Always create a gzipped version named vmlinuz for compatibility
+vmlinuz: piggy
+	gzip -c9 $< > $@
+
+piggz: piggy
+	$(COMPRESS) $< > $@
+
+piggy: $(SYSTEM)
+	$(OBJCOPY) $< $@
+
+mrproper: clean
+
+clean:
+	rm -f vmlinux vmlinuz zImage piggz piggy *.lds *.o
diff -bEruN linux-2.4.20-my/arch/mips/brcm-boards/bcm947xx/compressed/piggy.lds linux-2.4.20-nc/arch/mips/brcm-boards/bcm947xx/compressed/piggy.lds
--- linux-2.4.20-my/arch/mips/brcm-boards/bcm947xx/compressed/piggy.lds	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/arch/mips/brcm-boards/bcm947xx/compressed/piggy.lds	2006-06-02 08:21:25.000000000 -0700
@@ -0,0 +1 @@
+SECTIONS { .data : { input_len = .; LONG(input_data_end - input_data) input_data = .; *(.data) input_data_end = .; }}
diff -bEruN linux-2.4.20-my/arch/mips/brcm-boards/bcm947xx/compressed/vmlinux.lds linux-2.4.20-nc/arch/mips/brcm-boards/bcm947xx/compressed/vmlinux.lds
--- linux-2.4.20-my/arch/mips/brcm-boards/bcm947xx/compressed/vmlinux.lds	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/arch/mips/brcm-boards/bcm947xx/compressed/vmlinux.lds	2006-06-02 08:21:25.000000000 -0700
@@ -0,0 +1,43 @@
+OUTPUT_ARCH(mips)
+ENTRY(startup)
+SECTIONS {
+	. = 0x80300000;
+	.text : {
+		_ftext = . ;
+		text_start = .;
+		*(.init)
+		*(.text)
+		*(.text.*)
+		*(.fini)
+		*(.rodata)
+		*(.rodata.*)
+		_rstart = .;
+		*(.textini.*)
+		_etext = .;
+		text_end = .;
+	}
+
+	.data : {
+		data_start = .;
+		_fdata = .;
+		*(.dataini.*)
+		_rend = .;
+		*(.rdata)
+		*(.data)
+		*(.data.*)
+		*(.sdata)
+		data_end = .;
+		_edata = .;
+	}
+
+	.bss : {
+		_fbss = .;
+		bss_start = .;
+		*(.sbss)
+		*(.scommon)
+		*(.bss)
+		*(COMMON)
+		bss_end = .;
+	}
+	_end = .;
+}
diff -bEruN linux-2.4.20-my/arch/mips/brcm-boards/bcm947xx/gpio.c linux-2.4.20-nc/arch/mips/brcm-boards/bcm947xx/gpio.c
--- linux-2.4.20-my/arch/mips/brcm-boards/bcm947xx/gpio.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/arch/mips/brcm-boards/bcm947xx/gpio.c	2006-06-02 08:21:25.000000000 -0700
@@ -0,0 +1,158 @@
+/*
+ * GPIO char driver
+ *
+ * Copyright 2005, Broadcom Corporation
+ * All Rights Reserved.
+ * 
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ *
+ * $Id: gpio.c,v 1.1.1.8 2005/03/07 07:30:37 kanki Exp $
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <asm/uaccess.h>
+
+#include <typedefs.h>
+#include <bcmutils.h>
+#include <sbutils.h>
+#include <bcmdevs.h>
+
+static void *gpio_sbh;
+static int gpio_major;
+static devfs_handle_t gpio_dir;
+static struct {
+	char *name;
+	devfs_handle_t handle;
+} gpio_file[] = {
+	{ "in", NULL },
+	{ "out", NULL },
+	{ "outen", NULL },
+	{ "control", NULL }
+};
+
+static int
+gpio_open(struct inode *inode, struct file * file)
+{
+	if (MINOR(inode->i_rdev) > ARRAYSIZE(gpio_file))
+		return -ENODEV;
+
+	MOD_INC_USE_COUNT;
+	return 0;
+}
+
+static int
+gpio_release(struct inode *inode, struct file * file)
+{
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+static ssize_t
+gpio_read(struct file *file, char *buf, size_t count, loff_t *ppos)
+{
+	u32 val;
+
+	switch (MINOR(file->f_dentry->d_inode->i_rdev)) {
+	case 0:
+		val = sb_gpioin(gpio_sbh);
+		break;
+	case 1:
+		val = sb_gpioout(gpio_sbh, 0, 0);
+		break;
+	case 2:
+		val = sb_gpioouten(gpio_sbh, 0, 0);
+		break;
+	case 3:
+		val = sb_gpiocontrol(gpio_sbh, 0, 0);
+		break;
+	default:
+		return -ENODEV;
+	}
+
+	if (put_user(val, (u32 *) buf))
+		return -EFAULT;
+
+	return sizeof(val);
+}
+
+static ssize_t
+gpio_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+{
+	u32 val;
+
+	if (get_user(val, (u32 *) buf))
+		return -EFAULT;
+
+	switch (MINOR(file->f_dentry->d_inode->i_rdev)) {
+	case 0:
+		return -EACCES;
+	case 1:
+		sb_gpioout(gpio_sbh, ~0, val);
+		break;
+	case 2:
+		sb_gpioouten(gpio_sbh, ~0, val);
+		break;
+	case 3:
+		sb_gpiocontrol(gpio_sbh, ~0, val);
+		break;
+	default:
+		return -ENODEV;
+	}
+
+	return sizeof(val);
+}
+
+static struct file_operations gpio_fops = {
+	owner:		THIS_MODULE,
+	open:		gpio_open,
+	release:	gpio_release,
+	read:		gpio_read,
+	write:		gpio_write,
+};
+
+static int __init
+gpio_init(void)
+{
+	int i;
+
+	if (!(gpio_sbh = sb_kattach()))
+		return -ENODEV;
+
+	sb_gpiosetcore(gpio_sbh);
+
+	if ((gpio_major = devfs_register_chrdev(0, "gpio", &gpio_fops)) < 0)
+		return gpio_major;
+
+	gpio_dir = devfs_mk_dir(NULL, "gpio", NULL);
+
+	for (i = 0; i < ARRAYSIZE(gpio_file); i++) {
+		gpio_file[i].handle = devfs_register(gpio_dir,
+						     gpio_file[i].name,
+						     DEVFS_FL_DEFAULT, gpio_major, i,
+						     S_IFCHR | S_IRUGO | S_IWUGO,
+						     &gpio_fops, NULL);
+	}
+
+	return 0;
+}
+
+static void __exit
+gpio_exit(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAYSIZE(gpio_file); i++)
+		devfs_unregister(gpio_file[i].handle);
+	devfs_unregister(gpio_dir);
+	devfs_unregister_chrdev(gpio_major, "gpio");
+	sb_detach(gpio_sbh);
+}
+
+module_init(gpio_init);
+module_exit(gpio_exit);
diff -bEruN linux-2.4.20-my/arch/mips/brcm-boards/bcm947xx/Makefile linux-2.4.20-nc/arch/mips/brcm-boards/bcm947xx/Makefile
--- linux-2.4.20-my/arch/mips/brcm-boards/bcm947xx/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/arch/mips/brcm-boards/bcm947xx/Makefile	2006-06-02 08:21:25.000000000 -0700
@@ -0,0 +1,24 @@
+#
+# Makefile for Broadcom BCM947XX boards
+#
+# Copyright 2005, Broadcom Corporation
+# All Rights Reserved.
+# 
+# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+#
+# $Id: Makefile,v 1.1.1.9 2005/03/07 07:30:37 kanki Exp $
+#
+
+O_TARGET	:= bcm947xx.o
+
+export-objs	:= nvram_linux.o setup.o
+obj-y		:= prom.o setup.o time.o sbmips.o perfcntr.o gpio.o
+obj-y		+= sflash.o nvram.o nvram_linux.o
+obj-$(CONFIG_PCI) += sbpci.o pcibios.o
+
+vpath %.c $(SRCBASE)/shared $(SRCBASE)/shared/nvram
+
+include $(TOPDIR)/Rules.make
diff -bEruN linux-2.4.20-my/arch/mips/brcm-boards/bcm947xx/nvram_linux.c linux-2.4.20-nc/arch/mips/brcm-boards/bcm947xx/nvram_linux.c
--- linux-2.4.20-my/arch/mips/brcm-boards/bcm947xx/nvram_linux.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/arch/mips/brcm-boards/bcm947xx/nvram_linux.c	2006-06-02 08:21:25.000000000 -0700
@@ -0,0 +1,638 @@
+/*
+ * NVRAM variable manipulation (Linux kernel half)
+ *
+ * Copyright 2005, Broadcom Corporation
+ * All Rights Reserved.
+ * 
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ *
+ * $Id: nvram_linux.c,v 1.12 2005/03/07 08:35:32 kanki Exp $
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/bootmem.h>
+#include <linux/wrapper.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/mtd/mtd.h>
+#include <asm/addrspace.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+#include <typedefs.h>
+#include <bcmendian.h>
+#include <bcmnvram.h>
+#include <bcmutils.h>
+#include <sbconfig.h>
+#include <sbchipc.h>
+#include <sbutils.h>
+#include <sbmips.h>
+#include <sflash.h>
+
+/* In BSS to minimize text size and page aligned so it can be mmap()-ed */
+static char nvram_buf[NVRAM_SPACE] __attribute__((aligned(PAGE_SIZE)));
+
+#ifdef MODULE
+
+#define early_nvram_get(name) nvram_get(name)
+
+#else /* !MODULE */
+
+/* Global SB handle */
+extern void *bcm947xx_sbh;
+extern spinlock_t bcm947xx_sbh_lock;
+
+/* Convenience */
+#define sbh bcm947xx_sbh
+#define sbh_lock bcm947xx_sbh_lock
+#define KB * 1024
+#define MB * 1024 * 1024
+
+/* Probe for NVRAM header */
+static void __init
+early_nvram_init(void)
+{
+	struct nvram_header *header;
+	chipcregs_t *cc;
+	struct sflash *info = NULL;
+	int i;
+	uint32 base, off, lim;
+
+	if ((cc = sb_setcore(sbh, SB_CC, 0)) != NULL) {
+		base = KSEG1ADDR(SB_FLASH2);
+		switch (readl(&cc->capabilities) & CAP_FLASH_MASK) {
+		case PFLASH:
+			lim = SB_FLASH2_SZ;
+			break;
+
+		case SFLASH_ST:
+		case SFLASH_AT:
+			if ((info = sflash_init(cc)) == NULL)
+				return;
+			lim = info->size;
+			break;
+
+		case FLASH_NONE:
+		default:
+			return;
+		}
+	} else {
+		/* extif assumed, Stop at 4 MB */
+		base = KSEG1ADDR(SB_FLASH1);
+		lim = SB_FLASH1_SZ;
+	}
+
+	off = FLASH_MIN;
+	while (off <= lim) {
+		/* Windowed flash access */
+		header = (struct nvram_header *) KSEG1ADDR(base + off - NVRAM_SPACE);
+		if (header->magic == NVRAM_MAGIC) {
+			u32 *src = (u32 *) header;
+			u32 *dst = (u32 *) nvram_buf;
+			for (i = 0; i < sizeof(struct nvram_header); i += 4)
+				*dst++ = *src++;
+			for (; i < header->len && i < NVRAM_SPACE; i += 4)
+				*dst++ = ltoh32(*src++);
+			return;
+		}
+
+		/* Try embedded NVRAM at 4 KB and 1 KB as last resorts */
+		if (off == 1 KB)
+			break;
+		else if (off == 4 KB)
+			off = 1 KB;
+		else if (off == lim)
+			off = 4 KB;
+		else
+			off <<= 1;
+	}
+}
+
+/* Early (before mm or mtd) read-only access to NVRAM */
+static char * __init
+early_nvram_get(const char *name)
+{
+	char *var, *value, *end, *eq;
+
+	if (!name)
+		return NULL;
+
+	if (!nvram_buf[0])
+		early_nvram_init();
+
+	/* Look for name=value and return value */
+	var = &nvram_buf[sizeof(struct nvram_header)];
+	end = nvram_buf + sizeof(nvram_buf) - 2;
+	end[0] = end[1] = '\0';
+	for (; *var; var = value + strlen(value) + 1) {
+		if (!(eq = strchr(var, '=')))
+			break;
+		value = eq + 1;
+		if ((eq - var) == strlen(name) && strncmp(var, name, (eq - var)) == 0)
+			return value;
+	}
+
+	return NULL;
+}
+
+#endif /* !MODULE */
+
+extern char * _nvram_get(const char *name);
+extern int _nvram_set(const char *name, const char *value);
+extern int _nvram_unset(const char *name);
+extern int _nvram_getall(char *buf, int count);
+extern int _nvram_commit(struct nvram_header *header);
+extern int _nvram_init(void);
+extern void _nvram_exit(void);
+
+/* Globals */
+static spinlock_t nvram_lock = SPIN_LOCK_UNLOCKED;
+static struct semaphore nvram_sem;
+static unsigned long nvram_offset = 0;
+static int nvram_major = -1;
+static devfs_handle_t nvram_handle = NULL;
+static struct mtd_info *nvram_mtd = NULL;
+
+int
+_nvram_read(char *buf)
+{
+	struct nvram_header *header = (struct nvram_header *) buf;
+	size_t len;
+
+	if (!nvram_mtd ||
+	    MTD_READ(nvram_mtd, nvram_mtd->size - NVRAM_SPACE, NVRAM_SPACE, &len, buf) ||
+	    len != NVRAM_SPACE ||
+	    header->magic != NVRAM_MAGIC) {
+		/* Maybe we can recover some data from early initialization */
+		memcpy(buf, nvram_buf, NVRAM_SPACE);
+	}
+
+	return 0;
+}
+
+struct nvram_tuple *
+_nvram_realloc(struct nvram_tuple *t, const char *name, const char *value)
+{
+	if ((nvram_offset + strlen(value) + 1) > NVRAM_SPACE)
+		return NULL;
+
+	if (!t) {
+		if (!(t = kmalloc(sizeof(struct nvram_tuple) + strlen(name) + 1, GFP_ATOMIC)))
+			return NULL;
+
+		/* Copy name */
+		t->name = (char *) &t[1];
+		strcpy(t->name, name);
+
+		t->value = NULL;
+	}
+
+	/* Copy value */
+	if (!t->value || strcmp(t->value, value)) {
+		t->value = &nvram_buf[nvram_offset];
+		strcpy(t->value, value);
+		nvram_offset += strlen(value) + 1;
+	}
+
+	return t;
+}
+
+void
+_nvram_free(struct nvram_tuple *t)
+{
+	if (!t)
+		nvram_offset = 0;
+	else
+		kfree(t);
+}
+
+int
+nvram_set(const char *name, const char *value)
+{
+	unsigned long flags;
+	int ret;
+	struct nvram_header *header;
+
+	spin_lock_irqsave(&nvram_lock, flags);
+	if ((ret = _nvram_set(name, value))) {
+		/* Consolidate space and try again */
+		if ((header = kmalloc(NVRAM_SPACE, GFP_ATOMIC))) {
+			if (_nvram_commit(header) == 0)
+				ret = _nvram_set(name, value);
+			kfree(header);
+		}
+	}
+	spin_unlock_irqrestore(&nvram_lock, flags);
+
+	return ret;
+}
+
+char *
+real_nvram_get(const char *name)
+{
+	unsigned long flags;
+	char *value;
+
+	spin_lock_irqsave(&nvram_lock, flags);
+	value = _nvram_get(name);
+	spin_unlock_irqrestore(&nvram_lock, flags);
+
+	return value;
+}
+
+char *
+nvram_get(const char *name)
+{
+	if (nvram_major >= 0)
+		return real_nvram_get(name);
+	else
+		return early_nvram_get(name);
+}
+
+int
+nvram_unset(const char *name)
+{
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&nvram_lock, flags);
+	ret = _nvram_unset(name);
+	spin_unlock_irqrestore(&nvram_lock, flags);
+
+	return ret;
+}
+
+static void
+erase_callback(struct erase_info *done)
+{
+	wait_queue_head_t *wait_q = (wait_queue_head_t *) done->priv;
+	wake_up(wait_q);
+}
+
+int
+nvram_commit(void)
+{
+	char *buf;
+	size_t erasesize, len;
+	unsigned int i;
+	int ret;
+	struct nvram_header *header;
+	unsigned long flags;
+	u_int32_t offset;
+	DECLARE_WAITQUEUE(wait, current);
+	wait_queue_head_t wait_q;
+	struct erase_info erase;
+
+	printk("nvram_commit(): init\n");
+
+	if (!nvram_mtd) {
+		printk("nvram_commit: NVRAM not found\n");
+		return -ENODEV;
+	}
+
+	if (in_interrupt()) {
+		printk("nvram_commit: not committing in interrupt\n");
+		return -EINVAL;
+	}
+
+	/* Backup sector blocks to be erased */
+	erasesize = ROUNDUP(NVRAM_SPACE, nvram_mtd->erasesize);
+	if (!(buf = kmalloc(erasesize, GFP_KERNEL))) {
+		printk("nvram_commit: out of memory\n");
+		return -ENOMEM;
+	}
+
+	down(&nvram_sem);
+#if 0
+	offset = nvram_mtd->size - erasesize;
+	i = erasesize - NVRAM_SPACE;
+	ret = MTD_READ(nvram_mtd, offset, i, &len, buf);
+	if (ret || len != i) {
+		printk("nvram_commit: read error\n");
+		ret = -EIO;
+		goto done;
+#endif
+	if ((i = erasesize - NVRAM_SPACE) > 0) {
+		offset = nvram_mtd->size - erasesize;
+		len = 0;
+		ret = MTD_READ(nvram_mtd, offset, i, &len, buf);
+		if (ret || len != i) {
+			printk("nvram_commit: read error ret = %d, len = %d/%d\n", ret, len, i);
+			ret = -EIO;
+			goto done;
+		}
+		header = (struct nvram_header *)(buf + i);
+	} else {
+		offset = nvram_mtd->size - NVRAM_SPACE;
+		header = (struct nvram_header *)buf;
+	}
+
+	/* Regenerate NVRAM */
+	spin_lock_irqsave(&nvram_lock, flags);
+	ret = _nvram_commit(header);
+	spin_unlock_irqrestore(&nvram_lock, flags);
+	if (ret)
+		goto done;
+
+	/* Erase sector blocks */
+	init_waitqueue_head(&wait_q);
+	for (; offset < nvram_mtd->size - NVRAM_SPACE + header->len; offset += nvram_mtd->erasesize) {
+		erase.mtd = nvram_mtd;
+		erase.addr = offset;
+		erase.len = nvram_mtd->erasesize;
+		erase.callback = erase_callback;
+		erase.priv = (u_long) &wait_q;
+
+		set_current_state(TASK_INTERRUPTIBLE);
+		add_wait_queue(&wait_q, &wait);
+
+		/* Unlock sector blocks */
+		if (nvram_mtd->unlock)
+			nvram_mtd->unlock(nvram_mtd, offset, nvram_mtd->erasesize);
+
+		if ((ret = MTD_ERASE(nvram_mtd, &erase))) {
+			set_current_state(TASK_RUNNING);
+			remove_wait_queue(&wait_q, &wait);
+			printk("nvram_commit: erase error\n");
+			goto done;
+		}
+
+		/* Wait for erase to finish */
+		schedule();
+		remove_wait_queue(&wait_q, &wait);
+	}
+
+	/* Write partition up to end of data area */
+	offset = nvram_mtd->size - erasesize;
+	i = erasesize - NVRAM_SPACE + header->len;
+	ret = MTD_WRITE(nvram_mtd, offset, i, &len, buf);
+	if (ret || len != i) {
+		printk("nvram_commit: write error\n");
+		ret = -EIO;
+		goto done;
+	}
+	/*
+	 * Reading a few bytes back here will put the device
+	 * back to the correct mode on certain flashes */
+
+	offset = nvram_mtd->size - erasesize;
+	ret = MTD_READ(nvram_mtd, offset, 4, &len, buf);
+
+ done:
+	up(&nvram_sem);
+	kfree(buf);
+	printk("nvram_commit(): end\n");
+	return ret;
+}
+
+int
+nvram_getall(char *buf, int count)
+{
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&nvram_lock, flags);
+	ret = _nvram_getall(buf, count);
+	spin_unlock_irqrestore(&nvram_lock, flags);
+
+	return ret;
+}
+
+EXPORT_SYMBOL(nvram_get);
+EXPORT_SYMBOL(nvram_getall);
+EXPORT_SYMBOL(nvram_set);
+EXPORT_SYMBOL(nvram_unset);
+EXPORT_SYMBOL(nvram_commit);
+
+/* User mode interface below */
+
+static ssize_t
+dev_nvram_read(struct file *file, char *buf, size_t count, loff_t *ppos)
+{
+	char tmp[100], *name = tmp, *value;
+	ssize_t ret;
+	unsigned long off;
+
+	if (count > sizeof(tmp)) {
+		if (!(name = kmalloc(count, GFP_KERNEL)))
+			return -ENOMEM;
+	}
+
+	if (copy_from_user(name, buf, count)) {
+		ret = -EFAULT;
+		goto done;
+	}
+
+	if (*name == '\0') {
+		/* Get all variables */
+		ret = nvram_getall(name, count);
+		if (ret == 0) {
+			if (copy_to_user(buf, name, count)) {
+				ret = -EFAULT;
+				goto done;
+			}
+			ret = count;
+		}
+	} else {
+		if (!(value = nvram_get(name))) {
+			ret = 0;
+			goto done;
+		}
+
+		/* Provide the offset into mmap() space */
+		off = (unsigned long) value - (unsigned long) nvram_buf;
+
+		if (put_user(off, (unsigned long *) buf)) {
+			ret = -EFAULT;
+			goto done;
+		}
+
+		ret = sizeof(unsigned long);
+	}
+
+	flush_cache_all();	
+ 
+done:
+	if (name != tmp)
+		kfree(name);
+
+	return ret;
+}
+
+static ssize_t
+dev_nvram_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+{
+	char tmp[100], *name = tmp, *value;
+	ssize_t ret;
+
+	if (count > sizeof(tmp)) {
+		if (!(name = kmalloc(count, GFP_KERNEL)))
+			return -ENOMEM;
+	}
+
+	if (copy_from_user(name, buf, count)) {
+		ret = -EFAULT;
+		goto done;
+	}
+
+	value = name;
+	name = strsep(&value, "=");
+	if (value)
+		ret = nvram_set(name, value) ? : count;
+	else
+		ret = nvram_unset(name) ? : count;
+
+ done:
+	if (name != tmp)
+		kfree(name);
+
+	return ret;
+}	
+
+static int
+dev_nvram_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+	if (cmd != NVRAM_MAGIC)
+		return -EINVAL;
+	return nvram_commit();
+}
+
+static int
+dev_nvram_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	unsigned long offset = virt_to_phys(nvram_buf);
+
+	if (remap_page_range(vma->vm_start, offset, vma->vm_end-vma->vm_start,
+			     vma->vm_page_prot))
+		return -EAGAIN;
+
+	return 0;
+}
+
+static int
+dev_nvram_open(struct inode *inode, struct file * file)
+{
+	MOD_INC_USE_COUNT;
+	return 0;
+}
+
+static int
+dev_nvram_release(struct inode *inode, struct file * file)
+{
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+static struct file_operations dev_nvram_fops = {
+	owner:		THIS_MODULE,
+	open:		dev_nvram_open,
+	release:	dev_nvram_release,
+	read:		dev_nvram_read,
+	write:		dev_nvram_write,
+	ioctl:		dev_nvram_ioctl,
+	mmap:		dev_nvram_mmap,
+};
+
+static void
+dev_nvram_exit(void)
+{
+	int order = 0;
+	struct page *page, *end;
+
+	if (nvram_handle)
+		devfs_unregister(nvram_handle);
+
+	if (nvram_major >= 0)
+		devfs_unregister_chrdev(nvram_major, "nvram");
+
+	if (nvram_mtd)
+		put_mtd_device(nvram_mtd);
+
+	while ((PAGE_SIZE << order) < NVRAM_SPACE)
+		order++;
+	end = virt_to_page(nvram_buf + (PAGE_SIZE << order) - 1);
+	for (page = virt_to_page(nvram_buf); page <= end; page++)
+		mem_map_unreserve(page);
+
+	_nvram_exit();
+}
+
+static int __init
+dev_nvram_init(void)
+{
+	int order = 0, ret = 0;
+	struct page *page, *end;
+	unsigned int i;
+
+	/* Allocate and reserve memory to mmap() */
+	while ((PAGE_SIZE << order) < NVRAM_SPACE)
+		order++;
+	end = virt_to_page(nvram_buf + (PAGE_SIZE << order) - 1);
+	for (page = virt_to_page(nvram_buf); page <= end; page++)
+		mem_map_reserve(page);
+
+#ifdef CONFIG_MTD
+	/* Find associated MTD device */
+	for (i = 0; i < MAX_MTD_DEVICES; i++) {
+		nvram_mtd = get_mtd_device(NULL, i);
+		if (nvram_mtd) {
+			if (!strcmp(nvram_mtd->name, "nvram") &&
+			    nvram_mtd->size >= NVRAM_SPACE)
+				break;
+			put_mtd_device(nvram_mtd);
+		}
+	}
+	if (i >= MAX_MTD_DEVICES)
+		nvram_mtd = NULL;
+#endif
+
+	/* Initialize hash table lock */
+	spin_lock_init(&nvram_lock);
+
+	/* Initialize commit semaphore */
+	init_MUTEX(&nvram_sem);
+
+	/* Register char device */
+	if ((nvram_major = devfs_register_chrdev(0, "nvram", &dev_nvram_fops)) < 0) {
+		ret = nvram_major;
+		goto err;
+	}
+
+	/* Initialize hash table */
+	_nvram_init();
+
+	/* Create /dev/nvram handle */
+	nvram_handle = devfs_register(NULL, "nvram", DEVFS_FL_NONE, nvram_major, 0,
+				      S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, &dev_nvram_fops, NULL);
+
+	/* Set the SDRAM NCDL value into NVRAM if not already done */
+	if (getintvar(NULL, "sdram_ncdl") == 0) {
+		unsigned int ncdl;
+		char buf[] = "0x00000000";
+
+		if ((ncdl = sb_memc_get_ncdl(sbh))) {
+			sprintf(buf, "0x%08x", ncdl);
+			nvram_set("sdram_ncdl", buf);
+			nvram_commit();
+		}
+	}
+
+	return 0;
+
+ err:
+	dev_nvram_exit();
+	return ret;
+}
+
+module_init(dev_nvram_init);
+module_exit(dev_nvram_exit);
diff -bEruN linux-2.4.20-my/arch/mips/brcm-boards/bcm947xx/pcibios.c linux-2.4.20-nc/arch/mips/brcm-boards/bcm947xx/pcibios.c
--- linux-2.4.20-my/arch/mips/brcm-boards/bcm947xx/pcibios.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/arch/mips/brcm-boards/bcm947xx/pcibios.c	2006-06-02 08:21:25.000000000 -0700
@@ -0,0 +1,355 @@
+/*
+ * Low-Level PCI and SB support for BCM47xx (Linux support code)
+ *
+ * Copyright 2005, Broadcom Corporation
+ * All Rights Reserved.
+ * 
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ *
+ * $Id: pcibios.c,v 1.1.1.7 2005/03/07 07:30:37 kanki Exp $ 
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/paccess.h>
+
+#include <typedefs.h>
+#include <bcmutils.h>
+#include <sbconfig.h>
+#include <sbutils.h>
+#include <sbpci.h>
+#include <pcicfg.h>
+#include <bcmdevs.h>
+#include <bcmnvram.h>
+
+/* Global SB handle */
+extern void *bcm947xx_sbh;
+extern spinlock_t bcm947xx_sbh_lock;
+
+/* Convenience */
+#define sbh bcm947xx_sbh
+#define sbh_lock bcm947xx_sbh_lock
+
+static int
+sbpci_read_config_byte(struct pci_dev *dev, int where, u8 *value)
+{
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&sbh_lock, flags);
+	ret = sbpci_read_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), where, value, sizeof(*value));
+	spin_unlock_irqrestore(&sbh_lock, flags);
+	return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
+}
+
+static int
+sbpci_read_config_word(struct pci_dev *dev, int where, u16 *value)
+{
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&sbh_lock, flags);
+	ret = sbpci_read_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), where, value, sizeof(*value));
+	spin_unlock_irqrestore(&sbh_lock, flags);
+	return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
+}
+
+static int
+sbpci_read_config_dword(struct pci_dev *dev, int where, u32 *value)
+{
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&sbh_lock, flags);
+	ret = sbpci_read_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), where, value, sizeof(*value));
+	spin_unlock_irqrestore(&sbh_lock, flags);
+	return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
+}
+
+static int
+sbpci_write_config_byte(struct pci_dev *dev, int where, u8 value)
+{
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&sbh_lock, flags);
+	ret = sbpci_write_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), where, &value, sizeof(value));
+	spin_unlock_irqrestore(&sbh_lock, flags);
+	return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
+}
+
+static int
+sbpci_write_config_word(struct pci_dev *dev, int where, u16 value)
+{
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&sbh_lock, flags);
+	ret = sbpci_write_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), where, &value, sizeof(value));
+	spin_unlock_irqrestore(&sbh_lock, flags);
+	return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
+}
+
+static int
+sbpci_write_config_dword(struct pci_dev *dev, int where, u32 value)
+{
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&sbh_lock, flags);
+	ret = sbpci_write_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), where, &value, sizeof(value));
+	spin_unlock_irqrestore(&sbh_lock, flags);
+	return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops pcibios_ops = {
+	sbpci_read_config_byte,
+	sbpci_read_config_word,
+	sbpci_read_config_dword,
+	sbpci_write_config_byte,
+	sbpci_write_config_word,
+	sbpci_write_config_dword
+};
+
+
+void __init
+pcibios_init(void)
+{
+	ulong flags;
+
+	if (!(sbh = sb_kattach()))
+		panic("sb_kattach failed");
+	spin_lock_init(&sbh_lock);
+
+	spin_lock_irqsave(&sbh_lock, flags);
+	sbpci_init(sbh);
+	spin_unlock_irqrestore(&sbh_lock, flags);
+
+	set_io_port_base((unsigned long) ioremap_nocache(SB_PCI_MEM, 0x04000000));
+
+	mdelay(300); //By Joey for Atheros Card
+
+	/* Scan the SB bus */
+	pci_scan_bus(0, &pcibios_ops, NULL);
+
+}
+
+char * __init
+pcibios_setup(char *str)
+{
+	if (!strncmp(str, "ban=", 4)) {
+		sbpci_ban(simple_strtoul(str + 4, NULL, 0));
+		return NULL;
+	}
+
+	return (str);
+}
+
+static u32 pci_iobase = 0x100;
+static u32 pci_membase = SB_PCI_DMA;
+
+void __init
+pcibios_fixup_bus(struct pci_bus *b)
+{
+	struct list_head *ln;
+	struct pci_dev *d;
+	struct resource *res;
+	int pos, size;
+	u32 *base;
+	u8 irq;
+
+       	printk("PCI: Fixing up bus %d\n", b->number);
+
+	/* Fix up SB */
+	if (b->number == 0) {
+		for (ln=b->devices.next; ln != &b->devices; ln=ln->next) {
+			d = pci_dev_b(ln);
+			/* Fix up interrupt lines */
+			pci_read_config_byte(d, PCI_INTERRUPT_LINE, &irq);
+			d->irq = irq + 2;
+			pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq);
+		}
+	}
+
+	/* Fix up external PCI */
+	else {
+		for (ln=b->devices.next; ln != &b->devices; ln=ln->next) {
+			d = pci_dev_b(ln);
+			/* Fix up resource bases */
+			for (pos = 0; pos < 6; pos++) {
+				res = &d->resource[pos];
+				base = (res->flags & IORESOURCE_IO) ? &pci_iobase : &pci_membase;
+				if (res->end) {
+					size = res->end - res->start + 1;
+ 					if (*base & (size - 1))
+ 						*base = (*base + size) & ~(size - 1);
+ 					res->start = *base;
+ 					res->end = res->start + size - 1;
+ 					*base += size;
+					pci_write_config_dword(d, PCI_BASE_ADDRESS_0 + (pos << 2), res->start);
+				}
+				/* Fix up PCI bridge BAR0 only */
+				if (b->number == 1 && PCI_SLOT(d->devfn) == 0)
+					break;
+			}
+			/* Fix up interrupt lines */
+			if (pci_find_device(VENDOR_BROADCOM, SB_PCI, NULL))
+				d->irq = (pci_find_device(VENDOR_BROADCOM, SB_PCI, NULL))->irq;
+			pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq);
+		}
+	}
+}
+
+unsigned int
+pcibios_assign_all_busses(void)
+{
+	return 1;
+}
+
+void
+pcibios_align_resource(void *data, struct resource *res,
+		       unsigned long size, unsigned long align)
+{
+}
+
+int
+pcibios_enable_resources(struct pci_dev *dev)
+{
+	u16 cmd, old_cmd;
+	int idx;
+	struct resource *r;
+
+	/* External PCI only */
+	if (dev->bus->number == 0)
+		return 0;
+
+	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+	old_cmd = cmd;
+	for(idx=0; idx<6; idx++) {
+		r = &dev->resource[idx];
+		if (r->flags & IORESOURCE_IO)
+			cmd |= PCI_COMMAND_IO;
+		if (r->flags & IORESOURCE_MEM)
+			cmd |= PCI_COMMAND_MEMORY;
+	}
+	if (dev->resource[PCI_ROM_RESOURCE].start)
+		cmd |= PCI_COMMAND_MEMORY;
+	if (cmd != old_cmd) {
+		printk("PCI: Enabling device %s (%04x -> %04x)\n", dev->slot_name, old_cmd, cmd);
+		pci_write_config_word(dev, PCI_COMMAND, cmd);
+	}
+	return 0;
+}
+
+int
+pcibios_enable_device(struct pci_dev *dev, int mask)
+{
+	ulong flags;
+	uint coreidx;
+
+	/* External PCI device enable */
+	if (dev->bus->number != 0)
+		return pcibios_enable_resources(dev);
+
+	/* These cores come out of reset enabled */
+	if (dev->device == SB_MIPS ||
+	    dev->device == SB_MIPS33 ||
+	    dev->device == SB_EXTIF ||
+	    dev->device == SB_CC)
+		return 0;
+
+	spin_lock_irqsave(&sbh_lock, flags);
+	coreidx = sb_coreidx(sbh);
+	if (!sb_setcoreidx(sbh, PCI_SLOT(dev->devfn)))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	/* 
+	 * The USB core requires a special bit to be set during core
+	 * reset to enable host (OHCI) mode. Resetting the SB core in
+	 * pcibios_enable_device() is a hack for compatibility with
+	 * vanilla usb-ohci so that it does not have to know about
+	 * SB. A driver that wants to use the USB core in device mode
+	 * should know about SB and should reset the bit back to 0
+	 * after calling pcibios_enable_device().
+	 */
+	if (sb_coreid(sbh) == SB_USB) {
+		sb_core_disable(sbh, sb_coreflags(sbh, 0, 0));
+		sb_core_reset(sbh, 1 << 29);
+	} else
+		sb_core_reset(sbh, 0);
+
+	sb_setcoreidx(sbh, coreidx);
+	spin_unlock_irqrestore(&sbh_lock, flags);
+	
+	return 0;
+}
+
+void
+pcibios_update_resource(struct pci_dev *dev, struct resource *root,
+			struct resource *res, int resource)
+{
+	unsigned long where, size;
+	u32 reg;
+
+	/* External PCI only */
+	if (dev->bus->number == 0)
+		return;
+
+	where = PCI_BASE_ADDRESS_0 + (resource * 4);
+	size = res->end - res->start;
+	pci_read_config_dword(dev, where, &reg);
+	reg = (reg & size) | (((u32)(res->start - root->start)) & ~size);
+	pci_write_config_dword(dev, where, reg);
+}
+
+static void __init
+quirk_sbpci_bridge(struct pci_dev *dev)
+{
+	if (dev->bus->number != 1 || PCI_SLOT(dev->devfn) != 0)
+		return;
+
+	printk("PCI: Fixing up bridge\n");
+
+	/* Enable PCI bridge bus mastering and memory space */
+	pci_set_master(dev);
+	pcibios_enable_resources(dev);
+
+	/* Enable PCI bridge BAR1 prefetch and burst */
+	pci_write_config_dword(dev, PCI_BAR1_CONTROL, 3);
+}	
+
+struct pci_fixup pcibios_fixups[] = {
+	{ PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, quirk_sbpci_bridge },
+	{ 0 }
+};
+
+/*
+ *  If we set up a device for bus mastering, we need to check the latency
+ *  timer as certain crappy BIOSes forget to set it properly.
+ */
+unsigned int pcibios_max_latency = 255;
+
+void pcibios_set_master(struct pci_dev *dev)
+{
+	u8 lat;
+	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
+	if (lat < 16)
+		lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
+	else if (lat > pcibios_max_latency)
+		lat = pcibios_max_latency;
+	else
+		return;
+	printk(KERN_DEBUG "PCI: Setting latency timer of device %s to %d\n", dev->slot_name, lat);
+	pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
+}
+
diff -bEruN linux-2.4.20-my/arch/mips/brcm-boards/bcm947xx/perfcntr.c linux-2.4.20-nc/arch/mips/brcm-boards/bcm947xx/perfcntr.c
--- linux-2.4.20-my/arch/mips/brcm-boards/bcm947xx/perfcntr.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/arch/mips/brcm-boards/bcm947xx/perfcntr.c	2006-06-02 08:21:25.000000000 -0700
@@ -0,0 +1,67 @@
+/*
+ * Broadcom BCM47xx Performance Counter /proc/cpuinfo support
+ *
+ * Copyright 2005, Broadcom Corporation
+ * All Rights Reserved.
+ * 
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ *
+ * $Id: perfcntr.c,v 1.1.1.4 2005/03/07 07:30:37 kanki Exp $
+ */
+
+#include <asm/mipsregs.h>
+
+/* 
+ * BCM4710 performance counter register select values
+ * No even-odd control-counter mapping, just counters
+ */
+#define PERF_DCACHE_HIT		0
+#define PERF_DCACHE_MISS	1
+#define PERF_ICACHE_HIT		2
+#define PERF_ICACHE_MISS	3
+#define PERF_ICOUNT		4
+
+/* 
+ * Move from Coprocessor 0 Register 25 Select n
+ * data <- CPR[0,25,n] 
+ * GPR[1] <- data
+ */
+#define read_bcm4710_perf_cntr(n)				\
+({ int __res;							\
+        __asm__ __volatile__(					\
+	".set\tnoreorder\n\t"                                   \
+	".set\tnoat\n\t"                                        \
+	".word\t"STR(0x4001c800|(n))"\n\t"			\
+	"move\t%0,$1\n\t"                                       \
+	".set\tat\n\t"                                          \
+	".set\treorder"                                         \
+	:"=r" (__res));                                         \
+	__res;})
+
+asmlinkage unsigned int read_perf_cntr(unsigned int counter)
+{
+	switch (counter) {
+	case PERF_DCACHE_HIT:	return read_bcm4710_perf_cntr(PERF_DCACHE_HIT);
+	case PERF_DCACHE_MISS:	return read_bcm4710_perf_cntr(PERF_DCACHE_MISS);
+	case PERF_ICACHE_HIT:	return read_bcm4710_perf_cntr(PERF_ICACHE_HIT);
+	case PERF_ICACHE_MISS:	return read_bcm4710_perf_cntr(PERF_ICACHE_MISS);
+	case PERF_ICOUNT:	return read_bcm4710_perf_cntr(PERF_ICOUNT);
+	}
+	return 0;
+}
+
+asmlinkage void write_perf_cntr(unsigned int counter, unsigned int val)
+{
+}
+
+asmlinkage unsigned int read_perf_cntl(unsigned int counter)
+{
+	return 0;
+}
+
+asmlinkage void write_perf_cntl(unsigned int counter, unsigned int val)
+{
+}
diff -bEruN linux-2.4.20-my/arch/mips/brcm-boards/bcm947xx/prom.c linux-2.4.20-nc/arch/mips/brcm-boards/bcm947xx/prom.c
--- linux-2.4.20-my/arch/mips/brcm-boards/bcm947xx/prom.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/arch/mips/brcm-boards/bcm947xx/prom.c	2006-06-02 08:21:25.000000000 -0700
@@ -0,0 +1,41 @@
+/*
+ * Early initialization code for BCM94710 boards
+ *
+ * Copyright 2005, Broadcom Corporation
+ * All Rights Reserved.
+ * 
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ *
+ * $Id: prom.c,v 1.1.1.7 2005/03/07 07:30:37 kanki Exp $
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <asm/bootinfo.h>
+
+void __init
+prom_init(int argc, const char **argv)
+{
+	unsigned long mem;
+
+        mips_machgroup = MACH_GROUP_BRCM;
+        mips_machtype = MACH_BCM947XX;
+
+	/* Figure out memory size by finding aliases */
+	for (mem = (1 << 20); mem < (128 << 20); mem += (1 << 20)) {
+		if (*(unsigned long *)((unsigned long)(prom_init) + mem) == 
+		    *(unsigned long *)(prom_init))
+			break;
+	}
+	add_memory_region(0, mem, BOOT_MEM_RAM);
+}
+
+void __init
+prom_free_prom_memory(void)
+{
+}
diff -bEruN linux-2.4.20-my/arch/mips/brcm-boards/bcm947xx/setup.c linux-2.4.20-nc/arch/mips/brcm-boards/bcm947xx/setup.c
--- linux-2.4.20-my/arch/mips/brcm-boards/bcm947xx/setup.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/arch/mips/brcm-boards/bcm947xx/setup.c	2006-06-02 08:21:25.000000000 -0700
@@ -0,0 +1,379 @@
+/*
+ * Generic setup routines for Broadcom MIPS boards
+ *
+ * Copyright 2005, Broadcom Corporation
+ * All Rights Reserved.
+ * 
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ *
+ * $Id: setup.c,v 1.7 2005/03/07 08:35:32 kanki Exp $
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/serialP.h>
+#include <linux/ide.h>
+#include <asm/bootinfo.h>
+#include <asm/time.h>
+#include <asm/reboot.h>
+
+#ifdef CONFIG_MTD_PARTITIONS
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/minix_fs.h>
+#include <linux/ext2_fs.h>
+#include <linux/romfs_fs.h>
+#include <linux/cramfs_fs.h>
+#include <linux/squashfs_fs.h>
+#endif
+
+#include <typedefs.h>
+#include <bcmutils.h>
+#include <bcmnvram.h>
+#include <sbmips.h>
+#include <sbutils.h>
+#include <trxhdr.h>
+
+#include <cy_conf.h>
+
+extern void bcm947xx_time_init(void);
+extern void bcm947xx_timer_setup(struct irqaction *irq);
+
+#ifdef CONFIG_REMOTE_DEBUG
+extern void set_debug_traps(void);
+extern void rs_kgdb_hook(struct serial_state *);
+extern void breakpoint(void);
+#endif
+
+#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
+extern struct ide_ops std_ide_ops;
+#endif
+
+#ifdef MULTILANG_SUPPORT
+#endif
+
+/* Global SB handle */
+void *bcm947xx_sbh = NULL;
+spinlock_t bcm947xx_sbh_lock = SPIN_LOCK_UNLOCKED;
+EXPORT_SYMBOL(bcm947xx_sbh);
+EXPORT_SYMBOL(bcm947xx_sbh_lock);
+
+/* Convenience */
+#define sbh bcm947xx_sbh
+#define sbh_lock bcm947xx_sbh_lock
+
+/* Kernel command line */
+char arcs_cmdline[CL_SIZE] __initdata = CONFIG_CMDLINE;
+
+void
+bcm947xx_machine_restart(char *command)
+{
+	printk("Please stand by while rebooting the system...\n");
+
+	/* Set the watchdog timer to reset immediately */
+	__cli();
+	sb_watchdog(sbh, 1);
+	while (1);
+}
+
+void
+bcm947xx_machine_halt(void)
+{
+	printk("System halted\n");
+
+	/* Disable interrupts and watchdog and spin forever */
+	__cli();
+	sb_watchdog(sbh, 0);
+	while (1);
+}
+
+#ifdef CONFIG_SERIAL
+
+static struct serial_struct rs = {
+	line: 0,
+	flags: ASYNC_BOOT_AUTOCONF,
+	io_type: SERIAL_IO_MEM,
+};
+
+static void __init
+serial_add(void *regs, uint irq, uint baud_base, uint reg_shift)
+{
+	rs.iomem_base = regs;
+	rs.irq = irq + 2;
+	rs.baud_base = baud_base / 16;
+	rs.iomem_reg_shift = reg_shift;
+
+	early_serial_setup(&rs);
+
+	rs.line++;
+}
+
+static void __init
+serial_setup(void *sbh)
+{
+	sb_serial_init(sbh, serial_add);
+
+#ifdef CONFIG_REMOTE_DEBUG
+	/* Use the last port for kernel debugging */
+	if (rs.iomem_base)
+		rs_kgdb_hook(&rs);
+#endif
+}
+
+#endif /* CONFIG_SERIAL */
+
+extern void check_enable_mips_pfc(int val);
+void __init
+brcm_setup(void)
+{
+	char *value;
+	uint  pfc_val;
+
+	/* Get global SB handle */
+	sbh = sb_kattach();
+
+	/* Initialize clocks and interrupts */
+	sb_mips_init(sbh);
+
+	/* 
+	 * Now that the sbh is inited set the  proper PFC value 
+	 */	
+	pfc_val = sb_mips_get_pfc(sbh);
+	printk("Setting the PFC value as 0x%x\n", pfc_val);
+	check_enable_mips_pfc(pfc_val);
+
+
+#ifdef CONFIG_SERIAL
+	/* Initialize UARTs */
+	serial_setup(sbh);
+#endif
+
+#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
+	ide_ops = &std_ide_ops;
+#endif
+
+	/* Override default command line arguments */
+	value = nvram_get("kernel_args");
+	if (value && strlen(value) && strncmp(value, "empty", 5))
+		strncpy(arcs_cmdline, value, sizeof(arcs_cmdline));
+
+
+	/* Generic setup */
+	_machine_restart = bcm947xx_machine_restart;
+	_machine_halt = bcm947xx_machine_halt;
+	_machine_power_off = bcm947xx_machine_halt;
+
+	board_time_init = bcm947xx_time_init;
+	board_timer_setup = bcm947xx_timer_setup;
+}
+
+const char *
+get_system_type(void)
+{
+	return "Broadcom BCM947XX";
+}
+
+void __init
+bus_error_init(void)
+{
+}
+
+#ifdef CONFIG_MTD_PARTITIONS
+
+static struct mtd_partition bcm947xx_parts[] = {
+	{ name: "pmon",	offset: 0, size: 0, /*mask_flags: MTD_WRITEABLE,*/ },
+	{ name: "linux", offset: 0, size: 0, },
+	{ name: "rootfs", offset: 0, size: 0, /*mask_flags: MTD_WRITEABLE,*/ },
+#ifdef MULTILANG_SUPPORT
+	{ name: "lang", offset: 0, size: 0, /*mask_flags: MTD_WRITEABLE,*/ }, /* for multilang*/
+#endif
+	{ name: "nvram", offset: 0, size: 0, },
+	{ name: NULL, },
+};
+
+struct mtd_partition * __init
+init_mtd_partitions(struct mtd_info *mtd, size_t size)
+{
+	struct minix_super_block *minixsb;
+	struct ext2_super_block *ext2sb;
+	struct romfs_super_block *romfsb;
+	struct cramfs_super *cramfsb;
+	struct squashfs_super_block *squashfsb;
+	struct trx_header *trx;
+	unsigned char buf[512];
+	int off;
+#ifdef MULTILANG_SUPPORT
+	struct lang_header *lang;  /* for multilang */
+	int off1;
+#endif
+	size_t len;
+
+	minixsb = (struct minix_super_block *) buf;
+	ext2sb = (struct ext2_super_block *) buf;
+	romfsb = (struct romfs_super_block *) buf;
+	cramfsb = (struct cramfs_super *) buf;
+	squashfsb = (struct squashfs_super_block *) buf;
+	trx = (struct trx_header *) buf;
+#ifdef MULTILANG_SUPPORT
+	lang = (struct lang_header *) buf;  /* for multilang */
+#endif
+
+	/* Look at every 64 KB boundary */
+	for (off = 0; off < size; off += (64 * 1024)) {
+		memset(buf, 0xe5, sizeof(buf));
+
+		/*
+		 * Read block 0 to test for romfs and cramfs superblock
+		 */
+		if (MTD_READ(mtd, off, sizeof(buf), &len, buf) ||
+		    len != sizeof(buf))
+			continue;
+
+		/* Try looking at TRX header for rootfs offset */
+		if (le32_to_cpu(trx->magic) == TRX_MAGIC) {
+			bcm947xx_parts[1].offset = off;
+			if (le32_to_cpu(trx->offsets[1]) > off)
+				off = le32_to_cpu(trx->offsets[1]);
+			continue;
+		}
+
+		/* romfs is at block zero too */
+		if (romfsb->word0 == ROMSB_WORD0 &&
+		    romfsb->word1 == ROMSB_WORD1) {
+			printk(KERN_NOTICE
+			       "%s: romfs filesystem found at block %d\n",
+			       mtd->name, off / BLOCK_SIZE);
+			goto done;
+		}
+
+		/* so is cramfs */
+		if (cramfsb->magic == CRAMFS_MAGIC) {
+			printk(KERN_NOTICE
+			       "%s: cramfs filesystem found at block %d\n",
+			       mtd->name, off / BLOCK_SIZE);
+			goto done;
+		}
+
+		/* squashfs is at block zero too */
+		if (squashfsb->s_magic == SQUASHFS_MAGIC) {
+			printk(KERN_NOTICE
+			       "%s: squashfs filesystem found at block %d\n",
+			       mtd->name, off / BLOCK_SIZE);
+			goto done;
+		}
+
+		/*
+		 * Read block 1 to test for minix and ext2 superblock
+		 */
+		if (MTD_READ(mtd, off + BLOCK_SIZE, sizeof(buf), &len, buf) ||
+		    len != sizeof(buf))
+			continue;
+
+		/* Try minix */
+		if (minixsb->s_magic == MINIX_SUPER_MAGIC ||
+		    minixsb->s_magic == MINIX_SUPER_MAGIC2) {
+			printk(KERN_NOTICE
+			       "%s: Minix filesystem found at block %d\n",
+			       mtd->name, off / BLOCK_SIZE);
+			goto done;
+		}
+
+		/* Try ext2 */
+		if (ext2sb->s_magic == cpu_to_le16(EXT2_SUPER_MAGIC)) {
+			printk(KERN_NOTICE
+			       "%s: ext2 filesystem found at block %d\n",
+			       mtd->name, off / BLOCK_SIZE);
+			goto done;
+		}
+	}
+
+	printk(KERN_NOTICE
+	       "%s: Couldn't find valid ROM disk image\n",
+	       mtd->name);
+
+ done:
+#if MULTILANG_SUPPORT
+/* below for multilang */
+	/* Look at every 64 KB boundary */
+	for (off1 = 0; off1 < size; off1 += (64 * 1024)) {
+		memset(buf, 0xe5, sizeof(buf));
+
+		/*
+		 * Read block 0 to test for romfs and cramfs superblock
+		 */
+		if (MTD_READ(mtd, off1, sizeof(buf), &len, buf) ||
+		    len != sizeof(buf))
+			continue;
+
+		/* Try looking at TRX header for rootfs offset */
+		if (le32_to_cpu(trx->magic) == TRX_MAGIC) {
+			printk("le32_to_cpu(trx->magic)=0x%lx trx->magic=0x%lx\n", le32_to_cpu(trx->magic), trx->magic);
+			//bcm947xx_parts[1].offset = off1;
+			printk("bcm947xx_parts[1].offset=0x%lx trx->offsets[1]=0x%lx off\n", bcm947xx_parts[2].offset);
+			if (le32_to_cpu(trx->offsets[2]) > off1) {
+				off1 = le32_to_cpu(trx->offsets[2]);
+				printk("ok1 off1=0x%lx\n", off1);
+			}
+			continue;
+		}
+
+		/* so is cramfs */
+		if (cramfsb->magic == CRAMFS_MAGIC) {
+			printk(KERN_NOTICE
+			       "%s: lang cramfs filesystem found at block %d (0x%lx)\n",
+			       mtd->name, off1 / BLOCK_SIZE, off1);
+			goto done1;
+		}
+  
+  		/* squashfs is at block zero too */
+  		if (squashfsb->s_magic == SQUASHFS_MAGIC) {
+  			printk(KERN_NOTICE
+  			       "%s: lang squashfs filesystem found at block %d (0x%lx)\n",
+   			       mtd->name, off1 / BLOCK_SIZE, off1);
+   			goto done1;
+   		}
+
+	}
+done1:
+	printk("off=0x%lx off1=0x%lx size=0x%lx\n", off, off1, size);
+
+	if(off1 == 0 || off1 == size )
+	{
+		off1 = size - 0x60000;  // 0x3d0000 only lang.js
+		printk("(Not Found Lang Block)off=0x%lx off1=0x%lx size=0x%lx\n", off, off1, size);
+	}
+/* for multilang -> */
+	bcm947xx_parts[4].offset = size - ROUNDUP(NVRAM_SPACE, mtd->erasesize);
+	bcm947xx_parts[4].size = size - bcm947xx_parts[4].offset;
+	printk("nvram: offset=0x%lx size=0x%lx\n",  bcm947xx_parts[4].offset, bcm947xx_parts[4].size);
+
+	bcm947xx_parts[3].offset = off1;
+	bcm947xx_parts[3].size = bcm947xx_parts[4].offset - bcm947xx_parts[3].offset;
+/* <- for multilang */
+#else
+	/* Find and size nvram */
+	bcm947xx_parts[3].offset = size - ROUNDUP(NVRAM_SPACE, mtd->erasesize);
+	bcm947xx_parts[3].size = size - bcm947xx_parts[3].offset;
+#endif
+	/* Find and size rootfs */
+	if (off < size) {
+		bcm947xx_parts[2].offset = off;
+		bcm947xx_parts[2].size = bcm947xx_parts[3].offset - bcm947xx_parts[2].offset;
+	}
+
+	/* Size linux (kernel and rootfs) */
+	bcm947xx_parts[1].size = bcm947xx_parts[3].offset - bcm947xx_parts[1].offset;
+
+	/* Size pmon */
+	bcm947xx_parts[0].size = bcm947xx_parts[1].offset - bcm947xx_parts[0].offset;
+
+	return bcm947xx_parts;
+}
+
+EXPORT_SYMBOL(init_mtd_partitions);
+
+#endif
diff -bEruN linux-2.4.20-my/arch/mips/brcm-boards/bcm947xx/time.c linux-2.4.20-nc/arch/mips/brcm-boards/bcm947xx/time.c
--- linux-2.4.20-my/arch/mips/brcm-boards/bcm947xx/time.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/arch/mips/brcm-boards/bcm947xx/time.c	2006-06-02 08:21:25.000000000 -0700
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2005, Broadcom Corporation
+ * All Rights Reserved.
+ * 
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ *
+ * $Id: time.c,v 1.1.1.8 2005/03/07 07:30:37 kanki Exp $
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/serial_reg.h>
+#include <linux/interrupt.h>
+#include <asm/addrspace.h>
+#include <asm/io.h>
+#include <asm/time.h>
+
+#include <typedefs.h>
+#include <bcmnvram.h>
+#include <sbconfig.h>
+#include <sbextif.h>
+#include <sbutils.h>
+#include <sbmips.h>
+
+/* Global SB handle */
+extern void *bcm947xx_sbh;
+extern spinlock_t bcm947xx_sbh_lock;
+
+/* Convenience */
+#define sbh bcm947xx_sbh
+#define sbh_lock bcm947xx_sbh_lock
+
+extern int panic_timeout;
+static int watchdog = 0;
+static u8 *mcr = NULL;
+
+void __init
+bcm947xx_time_init(void)
+{
+	unsigned int hz;
+	extifregs_t *eir;
+
+	/*
+	 * Use deterministic values for initial counter interrupt
+	 * so that calibrate delay avoids encountering a counter wrap.
+	 */
+	write_c0_count(0);
+	write_c0_compare(0xffff);
+
+	if (!(hz = sb_mips_clock(sbh)))
+		hz = 100000000;
+
+	printk("CPU: BCM%04x rev %d at %d MHz\n", sb_chip(sbh), sb_chiprev(sbh),
+	       (hz + 500000) / 1000000);
+
+	/* Set MIPS counter frequency for fixed_rate_gettimeoffset() */
+	mips_hpt_frequency = hz / 2;
+
+	/* Set watchdog interval in ms */
+	watchdog = simple_strtoul(nvram_safe_get("watchdog"), NULL, 0);
+
+	/* Please set the watchdog to 3 sec if it is less than 3 but not equal to 0 */
+	if (watchdog > 0) {
+		if (watchdog < 3000)
+			watchdog = 3000;
+	}
+
+	/* Set panic timeout in seconds */
+	panic_timeout = watchdog / 1000;
+
+	/* Setup blink */
+	if ((eir = sb_setcore(sbh, SB_EXTIF, 0))) {
+		sbconfig_t *sb = (sbconfig_t *)((unsigned int) eir + SBCONFIGOFF);
+		unsigned long base = EXTIF_CFGIF_BASE(sb_base(readl(&sb->sbadmatch1)));
+		mcr = (u8 *) ioremap_nocache(base + UART_MCR, 1);
+	}
+}
+
+static void
+bcm947xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	/* Generic MIPS timer code */
+	timer_interrupt(irq, dev_id, regs);
+
+	/* Set the watchdog timer to reset after the specified number of ms */
+	if (watchdog > 0)
+		sb_watchdog(sbh, WATCHDOG_CLOCK / 1000 * watchdog);
+
+#ifdef	CONFIG_HWSIM
+	(*((int *)0xa0000f1c))++;
+#else
+	/* Blink one of the LEDs in the external UART */
+	if (mcr && !(jiffies % (HZ/2)))
+		writeb(readb(mcr) ^ UART_MCR_OUT2, mcr);
+#endif
+}
+
+static struct irqaction bcm947xx_timer_irqaction = {
+	bcm947xx_timer_interrupt,
+	SA_INTERRUPT,
+	0,
+	"timer",
+	NULL,
+	NULL
+};
+
+void __init
+bcm947xx_timer_setup(struct irqaction *irq)
+{
+	/* Enable the timer interrupt */
+	setup_irq(7, &bcm947xx_timer_irqaction);
+}
diff -bEruN linux-2.4.20-my/arch/mips/brcm-boards/generic/gdb_hook.c linux-2.4.20-nc/arch/mips/brcm-boards/generic/gdb_hook.c
--- linux-2.4.20-my/arch/mips/brcm-boards/generic/gdb_hook.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/arch/mips/brcm-boards/generic/gdb_hook.c	2006-06-02 08:21:25.000000000 -0700
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2005, Broadcom Corporation      
+ * All Rights Reserved.      
+ *       
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY      
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM      
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS      
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.      
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ * This is the interface to the remote debugger stub.
+ *
+ */
+
+#include <linux/serialP.h>
+#include <linux/serial_reg.h>
+
+#include <asm/serial.h>
+#include <asm/io.h>
+
+static struct async_struct kdb_port_info = {0};
+
+static __inline__ unsigned int serial_in(struct async_struct *info, int offset)
+{
+	return readb((unsigned long) info->iomem_base +
+		     (offset<<info->iomem_reg_shift));
+}
+
+static __inline__ void serial_out(struct async_struct *info, int offset,
+				  int value)
+{
+	writeb(value, (unsigned long) info->iomem_base +
+	       (offset<<info->iomem_reg_shift));
+}
+
+void rs_kgdb_hook(struct serial_state *ser) {
+	int t;
+
+	kdb_port_info.state = ser;
+	kdb_port_info.magic = SERIAL_MAGIC;
+	kdb_port_info.port = ser->port;
+	kdb_port_info.flags = ser->flags;
+	kdb_port_info.iomem_base = ser->iomem_base;
+	kdb_port_info.iomem_reg_shift = ser->iomem_reg_shift;
+	kdb_port_info.MCR = UART_MCR_DTR | UART_MCR_RTS;
+
+	/*
+	 * Clear all interrupts
+	 */
+	serial_in(&kdb_port_info, UART_LSR);
+	serial_in(&kdb_port_info, UART_RX);
+	serial_in(&kdb_port_info, UART_IIR);
+	serial_in(&kdb_port_info, UART_MSR);
+
+	/*
+	 * Now, initialize the UART 
+	 */
+	serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8);	/* reset DLAB */
+	serial_out(&kdb_port_info, UART_MCR, kdb_port_info.MCR);
+	
+	/*
+	 * and set the speed of the serial port
+	 * (currently hardwired to 115200 8N1
+	 */
+
+	/* baud rate is fixed to 115200 (is this sufficient?)*/
+	t = kdb_port_info.state->baud_base / 115200;	
+	/* set DLAB */
+	serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8 | UART_LCR_DLAB);
+	serial_out(&kdb_port_info, UART_DLL, t & 0xff);/* LS of divisor */
+	serial_out(&kdb_port_info, UART_DLM, t >> 8);  /* MS of divisor */
+	/* reset DLAB */
+	serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8);
+}
+
+int putDebugChar(char c)
+{
+
+	if (!kdb_port_info.state) { 	/* need to init device first */
+		return 0;
+	}
+
+	while ((serial_in(&kdb_port_info, UART_LSR) & UART_LSR_THRE) == 0)
+		;
+
+	serial_out(&kdb_port_info, UART_TX, c);
+
+	return 1;
+}
+
+char getDebugChar(void) 
+{
+	if (!kdb_port_info.state) { 	/* need to init device first */
+		return 0;
+	}
+
+	while (!(serial_in(&kdb_port_info, UART_LSR) & 1))
+		;
+
+	return(serial_in(&kdb_port_info, UART_RX));
+}
diff -bEruN linux-2.4.20-my/arch/mips/brcm-boards/generic/int-handler.S linux-2.4.20-nc/arch/mips/brcm-boards/generic/int-handler.S
--- linux-2.4.20-my/arch/mips/brcm-boards/generic/int-handler.S	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/arch/mips/brcm-boards/generic/int-handler.S	2006-06-02 08:21:25.000000000 -0700
@@ -0,0 +1,51 @@
+/*
+ * Generic interrupt handler for Broadcom MIPS boards
+ *
+ * Copyright 2005, Broadcom Corporation
+ * All Rights Reserved.
+ * 
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ *
+ * $Id: int-handler.S,v 1.1.1.7 2005/03/07 07:30:37 kanki Exp $
+ */
+
+#include <linux/config.h>
+
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+/*
+ *	MIPS IRQ	Source
+ *      --------        ------
+ *             0	Software (ignored)
+ *             1        Software (ignored)
+ *             2        Combined hardware interrupt (hw0)
+ *             3        Hardware
+ *             4        Hardware
+ *             5        Hardware
+ *             6        Hardware
+ *             7        R4k timer
+ */
+
+	.text
+	.set	noreorder
+	.set	noat
+	.align	5
+	NESTED(brcmIRQ, PT_SIZE, sp)
+	SAVE_ALL
+	CLI
+	.set	at
+    .set    noreorder
+
+	jal	    brcm_irq_dispatch
+	 move	a0, sp
+
+	j	    ret_from_irq
+	 nop
+		
+	END(brcmIRQ)
diff -bEruN linux-2.4.20-my/arch/mips/brcm-boards/generic/irq.c linux-2.4.20-nc/arch/mips/brcm-boards/generic/irq.c
--- linux-2.4.20-my/arch/mips/brcm-boards/generic/irq.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/arch/mips/brcm-boards/generic/irq.c	2006-06-02 08:21:25.000000000 -0700
@@ -0,0 +1,130 @@
+/*
+ * Generic interrupt control functions for Broadcom MIPS boards
+ *
+ * Copyright 2005, Broadcom Corporation
+ * All Rights Reserved.
+ * 
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ *
+ * $Id: irq.c,v 1.1.1.7 2005/03/07 07:30:37 kanki Exp $
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/gdb-stub.h>
+
+#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
+
+extern asmlinkage void brcmIRQ(void);
+extern asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs);
+
+void
+brcm_irq_dispatch(struct pt_regs *regs)
+{
+	u32 cause;
+
+	cause = read_c0_cause() &
+		read_c0_status() &
+		CAUSEF_IP;
+
+#ifdef CONFIG_KERNPROF
+	change_c0_status(cause | 1, 1);
+#else
+	clear_c0_status(cause);
+#endif
+
+	if (cause & CAUSEF_IP7)
+		do_IRQ(7, regs);
+	if (cause & CAUSEF_IP2)
+		do_IRQ(2, regs);
+	if (cause & CAUSEF_IP3)
+		do_IRQ(3, regs);
+	if (cause & CAUSEF_IP4)
+		do_IRQ(4, regs);
+	if (cause & CAUSEF_IP5)
+		do_IRQ(5, regs);
+	if (cause & CAUSEF_IP6)
+		do_IRQ(6, regs);
+}
+
+static void
+enable_brcm_irq(unsigned int irq)
+{
+	if (irq < 8)
+		set_c0_status(1 << (irq + 8));
+	else
+		set_c0_status(IE_IRQ0);
+}
+
+static void
+disable_brcm_irq(unsigned int irq)
+{
+	if (irq < 8)
+		clear_c0_status(1 << (irq + 8));
+	else
+		clear_c0_status(IE_IRQ0);
+}
+
+static void
+ack_brcm_irq(unsigned int irq)
+{
+	/* Already done in brcm_irq_dispatch */
+}
+
+static unsigned int
+startup_brcm_irq(unsigned int irq)
+{ 
+	enable_brcm_irq(irq);
+
+	return 0; /* never anything pending */
+}
+
+static void
+end_brcm_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_brcm_irq(irq);
+}
+
+static struct hw_interrupt_type brcm_irq_type = {
+	typename: "MIPS",
+	startup: startup_brcm_irq,
+	shutdown: disable_brcm_irq,
+	enable: enable_brcm_irq,
+	disable: disable_brcm_irq,
+	ack: ack_brcm_irq,
+	end: end_brcm_irq,
+	NULL
+};
+
+void __init
+init_IRQ(void)
+{
+	int i;
+
+	for (i = 0; i < NR_IRQS; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = 0;
+		irq_desc[i].depth = 1;
+		irq_desc[i].handler = &brcm_irq_type;
+	}
+
+    	set_except_vector(0, brcmIRQ);
+	change_c0_status(ST0_IM, ALLINTS);
+
+#ifdef CONFIG_REMOTE_DEBUG
+	printk("Breaking into debugger...\n");
+	set_debug_traps();
+	breakpoint(); 
+#endif
+}
diff -bEruN linux-2.4.20-my/arch/mips/brcm-boards/generic/Makefile linux-2.4.20-nc/arch/mips/brcm-boards/generic/Makefile
--- linux-2.4.20-my/arch/mips/brcm-boards/generic/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/arch/mips/brcm-boards/generic/Makefile	2006-06-02 08:21:25.000000000 -0700
@@ -0,0 +1,26 @@
+#
+# Makefile for generic Broadcom MIPS boards
+#
+# Copyright 2005, Broadcom Corporation
+# All Rights Reserved.
+# 
+# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+#
+# $Id: Makefile,v 1.1.1.7 2005/03/07 07:30:37 kanki Exp $
+#
+
+.S.s:
+	$(CPP) $(AFLAGS) $< -o $*.s
+.S.o:
+	$(CC) $(AFLAGS) -c $< -o $*.o
+
+O_TARGET	:= brcm.o
+
+obj-y		:= int-handler.o irq.o
+
+obj-$(CONFIG_REMOTE_DEBUG)	+= gdb_hook.o
+
+include $(TOPDIR)/Rules.make
diff -bEruN linux-2.4.20-my/arch/mips/config-shared.in linux-2.4.20-nc/arch/mips/config-shared.in
--- linux-2.4.20-my/arch/mips/config-shared.in	2006-06-02 08:00:41.000000000 -0700
+++ linux-2.4.20-nc/arch/mips/config-shared.in	2006-06-02 08:21:25.000000000 -0700
@@ -187,13 +187,8 @@
       int  '   Memory size (in megabytes)' CONFIG_SIBYTE_STANDALONE_RAM_SIZE 32
    fi
 
-   bool '   Support for Bus Watcher statistics' CONFIG_SIBYTE_BUS_WATCHER
-   if [ "$CONFIG_SIBYTE_TBPROF" = "n" ]; then
-      dep_bool '     Capture bus trace before bus error' CONFIG_SIBYTE_BW_TRACE $CONFIG_SIBYTE_BUS_WATCHER
-   fi
-
    bool '   Support for SB1/SOC profiling - SB1/SCD perf counters' CONFIG_SIBYTE_SB1250_PROF
-   bool '   Support for ZBbus profiling' CONFIG_SIBYTE_TBPROF
+   bool '   Support for ZBbus profiling' CONFIG_BCM1250_TBPROF
 
    if [ "$CONFIG_SIBYTE_SWARM" = "y" -o \
         "$CONFIG_SIBYTE_LITTLESUR" = "y" -o \
@@ -208,12 +203,15 @@
    fi
    define_bool CONFIG_MIPS_RTC y
 fi
+dep_bool 'Support for Broadcom MIPS-based boards' CONFIG_MIPS_BRCM $CONFIG_EXPERIMENTAL
+dep_bool 'Support for Broadcom BCM947XX' CONFIG_BCM947XX $CONFIG_MIPS_BRCM
+if [ "$CONFIG_BCM947XX" = "y" ] ; then
+   bool '    Support for Broadcom BCM4710' CONFIG_BCM4710
+   bool '    Support for Broadcom BCM4310' CONFIG_BCM4310
+   bool '    Support for Broadcom BCM4704' CONFIG_BCM4704
+   bool '    Support for Broadcom BCM5365' CONFIG_BCM5365
+fi
 bool 'Support for SNI RM200 PCI' CONFIG_SNI_RM200_PCI
-bool 'Support for TANBAC TB0226 (Mbase)' CONFIG_TANBAC_TB0226
-bool 'Support for TANBAC TB0229 (VR4131DIMM)' CONFIG_TANBAC_TB0229
-if [ "$CONFIG_TANBAC_TB0229" = "y" ]; then
-   bool '  Add TANBAC TB0219 Base board support' CONFIG_TANBAC_TB0219
-fi

 dep_bool 'Support for Toshiba JMR-TX3927 board' CONFIG_TOSHIBA_JMR3927 $CONFIG_MIPS32
 bool 'Support for Toshiba RBTX49[23]7 Reference Board' CONFIG_TOSHIBA_RBTX4927
@@ -554,6 +552,13 @@
    define_bool CONFIG_SWAP_IO_SPACE_L y
    define_bool CONFIG_BOOT_ELF32 y
 fi
+if [ "$CONFIG_BCM947XX" = "y" ] ; then
+   define_bool CONFIG_PCI y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_NEW_TIME_C y
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_HND y
+fi
 if [ "$CONFIG_SNI_RM200_PCI" = "y" ]; then
    define_bool CONFIG_ARC32 y
    define_bool CONFIG_ARC_MEMORY y
@@ -563,18 +568,6 @@
    define_bool CONFIG_NONCOHERENT_IO y
    define_bool CONFIG_PC_KEYB y
 fi
-if [ "$CONFIG_TANBAC_TB0226" = "y" ]; then
-   define_bool CONFIG_IRQ_CPU y
-   define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_DUMMY_KEYB y
-   define_bool CONFIG_SERIAL_MANY_PORTS y
-fi
-if [ "$CONFIG_TANBAC_TB0229" = "y" ]; then
-   define_bool CONFIG_IRQ_CPU y
-   define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_DUMMY_KEYB y
-   define_bool CONFIG_SERIAL_MANY_PORTS y
-fi
 if [ "$CONFIG_TOSHIBA_JMR3927" = "y" ]; then
    define_bool CONFIG_TOSHIBA_BOARDS y
    define_bool CONFIG_NONCOHERENT_IO y
@@ -869,6 +862,7 @@
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
 bool 'Sysctl support' CONFIG_SYSCTL
+bool 'Poor-man strace support' CONFIG_PRINT_SYSCALLS
 define_bool CONFIG_KCORE_ELF y
 define_bool CONFIG_KCORE_AOUT n
 define_bool CONFIG_BINFMT_AOUT n
@@ -1046,10 +1040,19 @@
 else
    bool 'Debugging symbols' CONFIG_DEBUG_INFO
 fi
+if [ "$CONFIG_AU1X00_UART" = "y" -o "$CONFIG_ZS" = "y" -o "$CONFIG_SIBYTE_SB1xxx_SOC" = "y" ]; then
+   dep_bool 'Remote GDB kernel debugging' CONFIG_REMOTE_DEBUG $CONFIG_KGDB
+   dep_bool '  Console output to GDB' CONFIG_GDB_CONSOLE $CONFIG_REMOTE_DEBUG
+fi
 if [ "$CONFIG_SIBYTE_SB1xxx_SOC" = "y" ]; then
    dep_bool 'Compile for Corelis Debugger' CONFIG_SB1XXX_CORELIS $CONFIG_DEBUG_INFO
 fi
 bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
+bool 'Simple kernel trace' CONFIG_KTRACE
+bool 'Running on a hardware simulator' CONFIG_HWSIM
+if [ "$CONFIG_HWSIM" = "y" ]; then
+   bool 'Do clear memory' CONFIG_HWSIM_ZMEM
+fi
 if [ "$CONFIG_SMP" != "y" ]; then
    bool 'Run uncached' CONFIG_MIPS_UNCACHED
 else
diff -bEruN linux-2.4.20-my/arch/mips/defconfig-bcm947xx linux-2.4.20-nc/arch/mips/defconfig-bcm947xx
--- linux-2.4.20-my/arch/mips/defconfig-bcm947xx	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/arch/mips/defconfig-bcm947xx	2006-06-02 08:21:25.000000000 -0700
@@ -0,0 +1,773 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_MIPS=y
+CONFIG_MIPS32=y
+# CONFIG_MIPS64 is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# Machine selection
+#
+# CONFIG_ACER_PICA_61 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_BAGET_MIPS is not set
+# CONFIG_CASIO_E55 is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_HP_LASERJET is not set
+# CONFIG_IBM_WORKPAD is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_NEC_EAGLE is not set
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+CONFIG_MIPS_BRCM=y
+CONFIG_BCM947XX=y
+CONFIG_BCM4710=y
+CONFIG_BCM4310=y
+CONFIG_BCM4704=y
+# CONFIG_BCM5365 is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_VICTOR_MPC30X is not set
+# CONFIG_ZAO_CAPCELLA is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_CMDLINE="root=/dev/mtdblock2 noinitrd console=ttyS0,115200"
+CONFIG_PCI=y
+CONFIG_NONCOHERENT_IO=y
+CONFIG_NEW_TIME_C=y
+CONFIG_NEW_IRQ=y
+CONFIG_HND=y
+# CONFIG_MIPS_AU1000 is not set
+
+#
+# CPU selection
+#
+CONFIG_CPU_MIPS32=y
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_VTAG_ICACHE is not set
+# CONFIG_64BIT_PHYS_ADDR is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+# CONFIG_CPU_HAS_LLDSCD is not set
+# CONFIG_CPU_HAS_WB is not set
+CONFIG_CPU_HAS_SYNC=y
+
+#
+# General setup
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_NET=y
+# CONFIG_PCI_NAMES is not set
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_TC is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+CONFIG_HOTPLUG=y
+
+#
+# PCMCIA/CardBus support
+#
+# CONFIG_PCMCIA is not set
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+# CONFIG_HOTPLUG_PCI_COMPAQ is not set
+# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
+# CONFIG_HOTPLUG_PCI_ACPI is not set
+# CONFIG_SYSVIPC is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_PRINT_SYSCALLS is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_MIPS32_COMPAT is not set
+# CONFIG_MIPS32_O32 is not set
+# CONFIG_MIPS32_N32 is not set
+# CONFIG_BINFMT_ELF32 is not set
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+# CONFIG_MTD_BLOCK is not set
+CONFIG_MTD_BLOCK_RO=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_CFI_B1 is not set
+CONFIG_MTD_CFI_B2=y
+# CONFIG_MTD_CFI_B4 is not set
+CONFIG_MTD_CFI_I1=y
+# CONFIG_MTD_CFI_I2 is not set
+# CONFIG_MTD_CFI_I4 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_SSTSTD=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_BCM947XX=y
+# CONFIG_MTD_PB1000 is not set
+# CONFIG_MTD_PB1500 is not set
+# CONFIG_MTD_PB1100 is not set
+# CONFIG_MTD_CSTM_MIPS_IXX is not set
+# CONFIG_MTD_OCELOT is not set
+# CONFIG_MTD_LASAT is not set
+# CONFIG_MTD_PCI is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_SFLASH=y
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_MSYS is not set
+# CONFIG_NOROOT is not set
+# CONFIG_BLK_DEV_FD is not set
+# 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_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
+
+#
+# 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_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP 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=y
+# CONFIG_IP_PIMSM_V1 is not set
+# CONFIG_IP_PIMSM_V2 is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+
+#
+#   IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=y
+CONFIG_IP_NF_FTP=y
+CONFIG_IP_NF_TFTP=y
+CONFIG_IP_NF_H323=y
+# CONFIG_IP_NF_IRC is not set
+# CONFIG_IP_NF_MMS is not set
+CONFIG_IP_NF_CT_PROTO_GRE=y
+CONFIG_IP_NF_PPTP=y
+# CONFIG_IP_NF_SIP is not set
+# CONFIG_IP_NF_QUEUE is not set
+CONFIG_IP_NF_IPTABLES=y
+# CONFIG_IP_NF_MATCH_LIMIT is not set
+# CONFIG_IP_NF_POOL is not set
+CONFIG_IP_NF_MATCH_MAC=y
+# CONFIG_IP_NF_MATCH_PKTTYPE is not set
+CONFIG_IP_NF_MATCH_MARK=y
+# CONFIG_IP_NF_MATCH_MULTIPORT is not set
+# CONFIG_IP_NF_MATCH_MPORT is not set
+CONFIG_IP_NF_MATCH_TOS=y
+CONFIG_IP_NF_MATCH_TIME=y
+# CONFIG_IP_NF_MATCH_ECN is not set
+# CONFIG_IP_NF_MATCH_DSCP is not set
+# CONFIG_IP_NF_MATCH_AH_ESP is not set
+# CONFIG_IP_NF_MATCH_LENGTH is not set
+# CONFIG_IP_NF_MATCH_TTL is not set
+CONFIG_IP_NF_MATCH_TCPMSS=y
+# CONFIG_IP_NF_MATCH_HELPER is not set
+CONFIG_IP_NF_MATCH_STATE=y
+# CONFIG_IP_NF_MATCH_CONNTRACK is not set
+# CONFIG_IP_NF_MATCH_UNCLEAN is not set
+CONFIG_IP_NF_MATCH_WEBSTR=y
+# CONFIG_IP_NF_MATCH_OWNER is not set
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+# CONFIG_IP_NF_TARGET_MIRROR is not set
+CONFIG_IP_NF_NAT=y
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP_NF_TARGET_REDIRECT=y
+CONFIG_IP_NF_AUTOFW=y
+CONFIG_IP_NF_TARGET_TRIGGER=y
+CONFIG_IP_NF_NAT_H323=y
+CONFIG_IP_NF_NAT_PPTP=y
+# CONFIG_IP_NF_NAT_SIP is not set
+CONFIG_IP_NF_NAT_PROTO_GRE=y
+# CONFIG_IP_NF_NAT_LOCAL is not set
+# CONFIG_IP_NF_NAT_SNMP_BASIC is not set
+CONFIG_IP_NF_NAT_FTP=y
+CONFIG_IP_NF_NAT_TFTP=y
+CONFIG_IP_NF_MANGLE=y
+CONFIG_IP_NF_TARGET_TOS=y
+# CONFIG_IP_NF_TARGET_ECN is not set
+CONFIG_IP_NF_TARGET_DSCP=y
+CONFIG_IP_NF_TARGET_LOG=y
+CONFIG_IP_NF_TARGET_MARK=y
+# CONFIG_IP_NF_TARGET_ULOG is not set
+CONFIG_IP_NF_TARGET_TCPMSS=y
+# CONFIG_IP_NF_ARPTABLES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+CONFIG_VLAN_8021Q=y
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+CONFIG_BRIDGE=y
+# 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=y
+CONFIG_NET_SCH_CBQ=y
+CONFIG_NET_SCH_HTB=y
+# CONFIG_NET_SCH_CSZ is not set
+CONFIG_NET_SCH_PRIO=y
+# CONFIG_NET_SCH_RED is not set
+CONFIG_NET_SCH_SFQ=y
+# CONFIG_NET_SCH_TEQL is not set
+# CONFIG_NET_SCH_TBF is not set
+# CONFIG_NET_SCH_GRED is not set
+# CONFIG_NET_SCH_DSMARK is not set
+# CONFIG_NET_SCH_INGRESS is not set
+CONFIG_NET_QOS=y
+CONFIG_NET_ESTIMATOR=y
+CONFIG_NET_CLS=y
+# CONFIG_NET_CLS_TCINDEX is not set
+# CONFIG_NET_CLS_ROUTE4 is not set
+# CONFIG_NET_CLS_FW is not set
+CONFIG_NET_CLS_U32=y
+# CONFIG_NET_CLS_RSVP is not set
+# CONFIG_NET_CLS_RSVP6 is not set
+# CONFIG_NET_CLS_POLICE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+# CONFIG_PHONE_IXJ is not set
+# CONFIG_PHONE_IXJ_PCMCIA 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 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# Broadcom HND network devices
+#
+CONFIG_HND=y
+# CONFIG_IL is not set
+CONFIG_ET=m
+# CONFIG_ET_4413 is not set
+CONFIG_ET_47XX=y
+CONFIG_WL=m
+CONFIG_WL_AP=wlconfig_lx_router_ap
+CONFIG_WL_STA=wlconfig_lx_router_sta
+CONFIG_WL_APSTA=wlconfig_lx_router_apsta
+CONFIG_WL_DNGL=wlconfig_lx_router_dongle
+
+# specify one of above(postfix) for linking
+CONFIG_WL_LINK=AP
+
+#
+# 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
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM 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_HP100 is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+CONFIG_PPP=y
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_SYNC_TTY=y
+# CONFIG_PPP_DEFLATE is not set
+# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPPOE=y
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR 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
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
+# CONFIG_ROCKETPORT is not set
+# CONFIG_CYCLADES is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_DIGI is not set
+# CONFIG_ESPSERIAL is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+# CONFIG_SYNCLINK is not set
+# CONFIG_SYNCLINKMP is not set
+CONFIG_N_HDLC=y
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+# CONFIG_SERIAL_TX3912 is not set
+# CONFIG_SERIAL_TX3912_CONSOLE is not set
+# CONFIG_TXX927_SERIAL is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=16
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_AMD_PM768 is not set
+# CONFIG_NVRAM is not set
+# 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
+
+#
+# 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_REISERFS_PROC_INFO 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_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+CONFIG_CRAMFS=y
+CONFIG_SQUASHFS=y
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+# CONFIG_ZLIB_FS_INFLATE is not set
+CONFIG_LZMA_FS_INFLATE=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_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=y
+# CONFIG_DEVFS_DEBUG is not set
+# CONFIG_DEVPTS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_EXT2_FS is not set
+# CONFIG_SYSV_FS 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_INTERMEZZO_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_NFSD_TCP 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
+# CONFIG_ZISOFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+# CONFIG_MSDOS_PARTITION is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Support for USB gadgets
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_CROSSCOMPILE=y
+# CONFIG_KERNPROF is not set
+# CONFIG_MCOUNT is not set
+# CONFIG_DEBUG is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_MIPS_UNCACHED is not set
+# CONFIG_KTRACE is not set
+# CONFIG_HWSIM is not set
+
+#
+# Library routines
+#
+CONFIG_ZLIB_INFLATE=y
+# CONFIG_ZLIB_DEFLATE is not set
diff -bEruN linux-2.4.20-my/arch/mips/kernel/cpu-probe.c linux-2.4.20-nc/arch/mips/kernel/cpu-probe.c
--- linux-2.4.20-my/arch/mips/kernel/cpu-probe.c	2006-06-02 07:55:18.000000000 -0700
+++ linux-2.4.20-nc/arch/mips/kernel/cpu-probe.c	2006-06-02 08:21:25.000000000 -0700
@@ -162,7 +162,7 @@

 static inline void cpu_probe_legacy(struct cpuinfo_mips *c)
 {
-	switch (c->processor_id & 0xff00) {
+	switch (c->processor_id & PRID_IMP_MASK) {
 	case PRID_IMP_R2000:
 		c->cputype = CPU_R2000;
 		c->isa_level = MIPS_CPU_ISA_I;
@@ -172,7 +172,7 @@
 		c->tlbsize = 64;
 		break;
 	case PRID_IMP_R3000:
-		if ((c->processor_id & 0xff) == PRID_REV_R3000A)
+		if ((c->processor_id & PRID_REV_MASK) == PRID_REV_R3000A)
 			if (cpu_has_confreg())
 				c->cputype = CPU_R3081E;
 			else
@@ -187,12 +187,12 @@
 		break;
 	case PRID_IMP_R4000:
 		if (read_c0_config() & CONF_SC) {
-			if ((c->processor_id & 0xff) >= PRID_REV_R4400)
+			if ((c->processor_id & PRID_REV_MASK) >= PRID_REV_R4400)
 				c->cputype = CPU_R4400PC;
 			else
 				c->cputype = CPU_R4000PC;
 		} else {
-			if ((c->processor_id & 0xff) >= PRID_REV_R4400)
+			if ((c->processor_id & PRID_REV_MASK) >= PRID_REV_R4400)
 				c->cputype = CPU_R4400SC;
 			else
 				c->cputype = CPU_R4000SC;
@@ -274,7 +274,7 @@
 			c->cputype = CPU_TX3927;
 			c->tlbsize = 64;
 		} else {
-			switch (c->processor_id & 0xff) {
+			switch (c->processor_id & PRID_REV_MASK) {
 			case PRID_REV_TX3912:
 				c->cputype = CPU_TX3912;
 				c->tlbsize = 32;
@@ -412,6 +412,16 @@
 	unsigned long config0 = read_c0_config();
 	unsigned long config1;
 
+	if ((config0 & CONF_BE) !=
+#ifdef	CONFIG_CPU_LITTLE_ENDIAN
+				0
+#else
+				CONF_BE
+#endif
+		) {
+		panic("Kernel compiled little-endian, but running on a big-endian cpu");
+	}
+
 	if ((config0 & (1 << 31)) == 0)
 		return;			/* actually wort a panic() */
 
@@ -438,7 +448,7 @@
 static inline void cpu_probe_mips(struct cpuinfo_mips *c)
 {
 	decode_config1(c);
-	switch (c->processor_id & 0xff00) {
+	switch (c->processor_id & PRID_IMP_MASK) {
 	case PRID_IMP_4KC:
 		c->cputype = CPU_4KC;
 		c->isa_level = MIPS_CPU_ISA_M32;
@@ -479,10 +489,10 @@
 {
 	decode_config1(c);
 	c->options |= MIPS_CPU_PREFETCH;
-	switch (c->processor_id & 0xff00) {
+	switch (c->processor_id & PRID_IMP_MASK) {
 	case PRID_IMP_AU1_REV1:
 	case PRID_IMP_AU1_REV2:
-		switch ((c->processor_id >> 24) & 0xff) {
+		switch ((c->processor_id >> 24) & PRID_REV_MASK) {
 		case 0:
  			c->cputype = CPU_AU1000;
 			break;
@@ -510,10 +520,30 @@
 	}
 }
 
+static inline void cpu_probe_broadcom(struct cpuinfo_mips *c)
+{
+	decode_config1(c);
+	switch (c->processor_id & PRID_IMP_MASK) {
+	case PRID_IMP_BCM4710:          
+		c->cputype = CPU_BCM4710;
+		c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | 
+			     MIPS_CPU_4KTLB | MIPS_CPU_COUNTER;
+		break;
+	case PRID_IMP_4KC:		
+	case PRID_IMP_BCM3302:		
+		c->cputype = CPU_BCM3302;
+		c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | 
+			     MIPS_CPU_4KTLB | MIPS_CPU_COUNTER;
+		break;
+	default:
+		c->cputype = CPU_UNKNOWN;
+		break;
+	}
+}
 static inline void cpu_probe_sibyte(struct cpuinfo_mips *c)
 {
 	decode_config1(c);
-	switch (c->processor_id & 0xff00) {
+	switch (c->processor_id & PRID_IMP_MASK) {
 	case PRID_IMP_SB1:
 		c->cputype = CPU_SB1;
 		c->isa_level = MIPS_CPU_ISA_M64;
@@ -535,7 +565,7 @@
 static inline void cpu_probe_sandcraft(struct cpuinfo_mips *c)
 {
 	decode_config1(c);
-	switch (c->processor_id & 0xff00) {
+	switch (c->processor_id & PRID_IMP_MASK) {
 	case PRID_IMP_SR71000:
 		c->cputype = CPU_SR71000;
 		c->isa_level = MIPS_CPU_ISA_M64;
@@ -560,7 +590,7 @@
 	c->cputype	= CPU_UNKNOWN;
 
 	c->processor_id = read_c0_prid();
-	switch (c->processor_id & 0xff0000) {
+	switch (c->processor_id & PRID_COMP_MASK) {
 
 	case PRID_COMP_LEGACY:
 		cpu_probe_legacy(c);
@@ -571,10 +601,12 @@
 	case PRID_COMP_ALCHEMY:
 		cpu_probe_alchemy(c);
 		break;
+	case PRID_COMP_BROADCOM:
+		cpu_probe_broadcom(c);
+		break;
 	case PRID_COMP_SIBYTE:
 		cpu_probe_sibyte(c);
 		break;
-
 	case PRID_COMP_SANDCRAFT:
 		cpu_probe_sandcraft(c);
 		break;
diff -bEruN linux-2.4.20-my/arch/mips/kernel/head.S linux-2.4.20-nc/arch/mips/kernel/head.S
--- linux-2.4.20-my/arch/mips/kernel/head.S	2006-06-02 07:55:18.000000000 -0700
+++ linux-2.4.20-nc/arch/mips/kernel/head.S	2006-06-02 08:21:25.000000000 -0700
@@ -28,12 +28,20 @@
 #include <asm/mipsregs.h>
 #include <asm/stackframe.h>
 
+#ifdef CONFIG_BCM4710
+#undef eret
+#define eret nop; nop; eret
+#endif
+
 		.text
+		j	kernel_entry
+		nop
+
 		/*
 		 * Reserved space for exception handlers.
 		 * Necessary for machines which link their kernels at KSEG0.
 		 */
-		.fill	0x400
+		.fill	0x3f4
 
 		/* The following two symbols are used for kernel profiling. */
 		EXPORT(stext)
@@ -181,6 +189,8 @@
 		sll	zero,3				# ehb
 		.set	reorder
 
+
+#if	!defined(CONFIG_HWSIM) || defined(CONFIG_HWSIM_ZMEM)
 		/*
 		 * The firmware/bootloader passes argc/argp/envp
 		 * to us as arguments.  But clear bss first because
@@ -194,6 +204,7 @@
 		addiu	t0, 4
 		sw	zero, (t0)
 		bne	t0, t1, 1b
+#endif
 
 		/*
 		 * Stack for kernel and init, current variable
diff -bEruN linux-2.4.20-my/arch/mips/kernel/proc.c linux-2.4.20-nc/arch/mips/kernel/proc.c
--- linux-2.4.20-my/arch/mips/kernel/proc.c	2006-06-02 07:55:18.000000000 -0700
+++ linux-2.4.20-nc/arch/mips/kernel/proc.c	2006-06-02 08:21:25.000000000 -0700
@@ -70,6 +70,8 @@
 	[CPU_VR4131]	"NEC VR4131",
 	[CPU_VR4181]	"NEC VR4181",
 	[CPU_VR4181A]	"NEC VR4181A",
+	[CPU_BCM4710]	"BCM4710",
+	[CPU_BCM3302]	"BCM3302",
 	[CPU_AU1100]	"Au1100",
 	[CPU_SR71000]	"Sandcraft SR71000",
 	[CPU_RM9000]	"RM9000",
@@ -80,6 +82,7 @@
 	[CPU_AU1200]	"Au1200",
 };
 
+extern unsigned long unaligned_instructions;
 
 static int show_cpuinfo(struct seq_file *m, void *v)
 {
@@ -123,6 +126,21 @@
 	seq_printf(m, fmt, 'D', vced_count);
 	seq_printf(m, fmt, 'I', vcei_count);
 
+	seq_printf(m, "unaligned_instructions\t: %u\n", unaligned_instructions);
+
+#if defined(CONFIG_BCM4710) || defined(CONFIG_BCM4310)
+	seq_printf(m, "dcache hits\t\t: %u\n",
+		   read_perf_cntr(0));
+	seq_printf(m, "dcache misses\t\t: %u\n",
+		   read_perf_cntr(1));
+	seq_printf(m, "icache hits\t\t: %u\n",
+		   read_perf_cntr(2));
+	seq_printf(m, "icache misses\t\t: %u\n",
+		   read_perf_cntr(3));
+	seq_printf(m, "instructions\t\t: %u\n",
+		   read_perf_cntr(4));
+#endif
+
 	return 0;
 }
 
diff -bEruN linux-2.4.20-my/arch/mips/kernel/scall_o32.S linux-2.4.20-nc/arch/mips/kernel/scall_o32.S
--- linux-2.4.20-my/arch/mips/kernel/scall_o32.S	2005-11-08 06:24:35.000000000 -0800
+++ linux-2.4.20-nc/arch/mips/kernel/scall_o32.S	2006-06-02 08:21:25.000000000 -0700
@@ -46,6 +46,23 @@
 
 stack_done:
         sw      a3, PT_R26(sp)          # save for syscall restart
+#ifdef CONFIG_PRINT_SYSCALLS
+
+	SAVE_STATIC
+	sw	t2, PT_R1(sp)
+	move	a0,sp			# pass pointer to saved regs
+	
+	jal	strace
+
+	RESTORE_STATIC
+	lw	t2, PT_R1(sp)
+
+	lw	a0, PT_R4(sp)		# Restore argument registers
+	lw	a1, PT_R5(sp)
+	lw	a2, PT_R6(sp)
+	lw	a3, PT_R7(sp)
+#endif
+
 	lw	t0, TASK_PTRACE($28)	# syscall tracing enabled?
 	andi	t0, _PT_TRACESYS
 	bnez	t0, trace_a_syscall
diff -bEruN linux-2.4.20-my/arch/mips/kernel/setup.c linux-2.4.20-nc/arch/mips/kernel/setup.c
--- linux-2.4.20-my/arch/mips/kernel/setup.c	2006-06-02 07:55:18.000000000 -0700
+++ linux-2.4.20-nc/arch/mips/kernel/setup.c	2006-06-02 08:21:25.000000000 -0700
@@ -486,13 +486,13 @@
 	void victor_mpc30x_setup(void);
 	void ibm_workpad_setup(void);
 	void casio_e55_setup(void);
-	void tanbac_tb0226_setup(void);
 	void jmr3927_setup(void);
 	void tx4927_setup(void);
  	void it8172_setup(void);
 	void swarm_setup(void);
 	void hp_setup(void);
 	void au1x00_setup(void);
+	void brcm_setup(void);
 	void frame_info_init(void);
 
 	frame_info_init();
@@ -622,16 +622,6 @@
 			casio_e55_setup();
 			break;
 #endif
-#ifdef CONFIG_TANBAC_TB0226
-		case MACH_TANBAC_TB0226:
-			tanbac_tb0226_setup();
-			break;
-#endif
-#ifdef CONFIG_TANBAC_TB0229
-		case MACH_TANBAC_TB0229:
-			tanbac_tb0229_setup();
-			break;
-#endif
 		}
 		break;
 #endif
@@ -686,6 +676,9 @@
                 hp_setup();
                 break;
 #endif
+	case MACH_GROUP_BRCM:
+		brcm_setup();
+		break;
 #ifdef  CONFIG_PMC_YOSEMITE
         case MACH_GROUP_TITAN:
                 pmc_yosemite_setup();
diff -bEruN linux-2.4.20-my/arch/mips/kernel/syscall.c linux-2.4.20-nc/arch/mips/kernel/syscall.c
--- linux-2.4.20-my/arch/mips/kernel/syscall.c	2005-11-08 06:24:35.000000000 -0800
+++ linux-2.4.20-nc/arch/mips/kernel/syscall.c	2006-06-02 08:21:25.000000000 -0700
@@ -252,11 +252,53 @@
 /*
  * Build the string table for the builtin "poor man's strace".
  */
-#ifdef CONF_PRINT_SYSCALLS
+#ifdef CONFIG_PRINT_SYSCALLS
 #define SYS(fun, narg) #fun,
 static char *sfnames[] = {
 #include "syscalls.h"
 };
+
+#ifdef	CONFIG_HWSIM
+int do_strace = 1;
+#else
+int do_strace = 0;
+#endif
+
+asmlinkage void strace(struct pt_regs *regs)
+{
+	int i;
+	unsigned long scn, narg, *pa0;
+	char *name, space[16];
+
+	if (do_strace == 0)
+		return;
+
+	scn = regs->regs[2];
+	pa0 = &regs->regs[4];
+
+	if ((scn >= __NR_Linux)  && (scn < (__NR_Linux + __NR_Linux_syscalls))) {
+		name = sfnames[scn - __NR_Linux];
+		narg = sys_narg_table[scn];
+	} else {
+		sprintf(space, "sc%lu", scn);
+		name = space;
+		narg = 0;
+	}
+
+	printk("%lu[%s:%d]@0x%08lx: %s(", jiffies, current->comm, current->pid, regs->cp0_epc, name);
+
+	if (narg > 6) narg = 6;
+
+	for (i = 0; i < narg; i++) {
+		if (i) printk(", ");
+		if (i < 4)
+			printk("0x%08lx", pa0[i]);
+		else
+			printk("0x%08lx", regs->pad0[i]);
+	}
+
+	printk(")\n");
+}
 #endif
 
 #if defined(CONFIG_BINFMT_IRIX) && defined(CONF_DEBUG_IRIX)
diff -bEruN linux-2.4.20-my/arch/mips/kernel/traps.c linux-2.4.20-nc/arch/mips/kernel/traps.c
--- linux-2.4.20-my/arch/mips/kernel/traps.c	2006-06-02 07:55:18.000000000 -0700
+++ linux-2.4.20-nc/arch/mips/kernel/traps.c	2006-06-02 08:21:25.000000000 -0700
@@ -293,17 +293,12 @@
 		 unsigned long value)
 {
 	const struct exception_table_entry *mid;
-	long diff;
 
-	while (first < last) {
-		mid = (last - first) / 2 + first;
-		diff = mid->insn - value;
-		if (diff < 0)
-			first = mid + 1;
-		else
-			last = mid;
+	for (mid = first; mid <= last; mid++) {
+		if (mid->insn == value)
+			return mid->nextinsn;
 	}
-	return (first == last && first->insn == value) ? first->nextinsn : 0;
+	return 0;
 }
 
 extern spinlock_t modlist_lock;
@@ -841,7 +836,7 @@
 
 #if 0
 	printk("\n\n----- Enable EJTAG single stepping ----\n\n");
-	write_c0_debug(debug | 0x100);
+	write_32bit_cp0_register(CP0_DEBUG, debug | 0x100);
 #endif
 }
 
@@ -919,7 +914,7 @@
 
 void __init trap_init(void)
 {
-	extern char except_vec1_generic;
+	extern char except_vec1_generic, except_vec2_generic;
 	extern char except_vec3_generic, except_vec3_r4000;
 	extern char except_vec_ejtag_debug;
 	extern char except_vec4;
@@ -927,6 +922,7 @@
 
 	/* Copy the generic exception handler code to it's final destination. */
 	memcpy((void *)(KSEG0 + 0x80), &except_vec1_generic, 0x80);
+	memcpy((void *)(KSEG0 + 0x100), &except_vec2_generic, 0x80);
 
 	/*
 	 * Setup default vectors
@@ -1012,6 +1008,12 @@
 		//set_except_vector(15, handle_ndc);
 	}
 
+	if (current_cpu_data.cputype == CPU_SB1) {
+		/* Enable timer interrupt and scd mapped interrupt */
+		clear_c0_status(0xf000);
+		set_c0_status(0xc00);
+	}
+
 	if (cpu_has_fpu) {
 	        save_fp_context = _save_fp_context;
 		restore_fp_context = _restore_fp_context;
diff -bEruN linux-2.4.20-my/arch/mips/Makefile linux-2.4.20-nc/arch/mips/Makefile
--- linux-2.4.20-my/arch/mips/Makefile	2006-06-02 07:55:18.000000000 -0700
+++ linux-2.4.20-nc/arch/mips/Makefile	2006-06-02 08:21:25.000000000 -0700
@@ -49,8 +49,10 @@
 LINKFLAGS	+= -G 0 -static -n -nostdlib
 MODFLAGS	+= -mlong-calls -fno-common
 
-ifdef CONFIG_REMOTE_DEBUG
-GCCFLAGS	+= -g
+GCCFLAGS	+= -I $(SRCBASE)/
+
+ifdef CONFIG_DEBUG
+GCCFLAGS	+= -gstabs+
 ifdef CONFIG_SB1XXX_CORELIS
 GCCFLAGS	+= -mno-sched-prolog -fno-omit-frame-pointer
 endif
@@ -166,12 +168,13 @@
 		   -Wa,--trap
 endif
 ifdef CONFIG_CPU_SB1
-GCCFLAGS	+= $(call set_gccflags,sb1,mips64,r5000,mips4,mips2) \
+GCCFLAGS	+= $(call set_gccflags,-sb1,mips64,r5000,mips4,mips2) \
 		   -Wa,--trap
 ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
 MODFLAGS	+= -msb1-pass1-workarounds
 endif
 endif
+GCCFLAGS	+= $(call check_gcc, -m4710a0kern, )
 
 AFLAGS		+= $(GCCFLAGS)
 ASFLAGS		+= $(GCCFLAGS)
@@ -613,28 +616,6 @@
 endif
 
 #
-# TANBAC TB0226 Mbase (VR4131)
-#
-ifdef CONFIG_TANBAC_TB0226
-SUBDIRS		+= arch/mips/vr41xx/common \
-		   arch/mips/vr41xx/tanbac-tb0226
-CORE_FILES	+= arch/mips/vr41xx/common/vr41xx.o \
-		   arch/mips/vr41xx/tanbac-tb0226/tb0226.o
-LOADADDR	:= 0x80000000
-endif
-
-#
-# TANBAC TB0229 (VR4131DIMM)
-#
-ifdef CONFIG_TANBAC_TB0229
-SUBDIRS		+= arch/mips/vr41xx/common \
-		   arch/mips/vr41xx/tanbac-tb0229
-CORE_FILES	+= arch/mips/vr41xx/common/vr41xx.o \
-		   arch/mips/vr41xx/tanbac-tb0229/tb0229.o
-LOADADDR	:= 0x80000000
-endif
-
-#
 # Philips Nino
 #
 ifdef CONFIG_NINO
@@ -659,9 +640,34 @@
 endif
 
 #
-# Sibyte SB1250 SOC and Broadcom (SiByte) BCM112x SOCs
+# Sibyte SB1250 SOC
+#
+ifdef CONFIG_SIBYTE_SB1250
+# This is a LIB so that it links at the end, and initcalls are later
+# the sequence; but it is built as an object so that modules don't get
+# removed (as happens, even if they have __initcall/module_init)
+LIBS		+= arch/mips/sibyte/sb1250/sb1250.o
+SUBDIRS		+= arch/mips/sibyte/sb1250
+LOADADDR	:= 0x80100000
+endif
+
+#
+# Sibyte SWARM board
+#
+ifdef CONFIG_SIBYTE_SWARM
+LIBS		+= arch/mips/sibyte/swarm/sbswarm.a
+SUBDIRS		+= arch/mips/sibyte/swarm
+endif
+ifdef CONFIG_SIBYTE_SENTOSA
+LIBS		+= arch/mips/sibyte/swarm/sbswarm.a
+SUBDIRS		+= arch/mips/sibyte/swarm
+endif
+
+#
+# Broadcom (SiByte) BCM112x SOCs
+# (In fact, this just uses the exact same support as the BCM1250.)
 #
-ifneq ($(CONFIG_SIBYTE_SB1250)$(CONFIG_SIBYTE_BCM112X),)
+ifdef CONFIG_SIBYTE_BCM112X
 # This is a LIB so that it links at the end, and initcalls are later
 # the sequence; but it is built as an object so that modules don't get
 # removed (as happens, even if they have __initcall/module_init)
@@ -671,16 +677,37 @@
 endif
 
 #
-# Sibyte boards:
+# Sibyte BCM91120C (CRhine) board
+# (In fact, this just uses the exact same support as the BCM912500A (SWARM).)
+#
+ifdef CONFIG_SIBYTE_CRHINE
+LIBS          += arch/mips/sibyte/swarm/sbswarm.a
+SUBDIRS       += arch/mips/sibyte/swarm
+endif
+
+#
+# Sibyte BCM91120x (Carmel) board
+# (In fact, this just uses the exact same support as the BCM912500A (SWARM).)
+#
+ifdef CONFIG_SIBYTE_CARMEL
+LIBS          += arch/mips/sibyte/swarm/sbswarm.a
+SUBDIRS       += arch/mips/sibyte/swarm
+endif
+
+#
+# Sibyte BCM91125C (CRhone) board
+# (In fact, this just uses the exact same support as the BCM912500A (SWARM).)
 #
-# BCM91250A (SWARM),
-# BCM91250E (Sentosa),
-# BCM91120C (CRhine),
-# BCM91120x (Carmel),
-# BCM91125C (CRhone),
-# BCM91125E (Rhone).
+ifdef CONFIG_SIBYTE_CRHONE
+LIBS          += arch/mips/sibyte/swarm/sbswarm.a
+SUBDIRS       += arch/mips/sibyte/swarm
+endif
+
 #
-ifdef CONFIG_SIBYTE_BOARD
+# Sibyte BCM91125E (Rhone) board
+# (In fact, this just uses the exact same support as the BCM912500A (SWARM).)
+#
+ifdef CONFIG_SIBYTE_RHONE
 LIBS		+= arch/mips/sibyte/swarm/sbswarm.a
 SUBDIRS		+= arch/mips/sibyte/swarm
 endif
@@ -694,6 +721,37 @@
 endif
 
 #
+# Broadcom BCM947XX variants
+#
+ifdef CONFIG_BCM947XX
+LIBS		+= arch/mips/brcm-boards/generic/brcm.o arch/mips/brcm-boards/bcm947xx/bcm947xx.o
+SUBDIRS		+= arch/mips/brcm-boards/generic arch/mips/brcm-boards/bcm947xx
+LOADADDR	:= 0x80001000
+zImage: vmlinux
+	$(MAKE) -C arch/$(ARCH)/brcm-boards/bcm947xx/compressed
+export LOADADDR
+endif
+
+#
+# Broadcom BCM933XX variants
+#
+ifdef CONFIG_BCM933XX
+LIBS          += arch/mips/brcm-boards/bcm933xx/bcm933xx.o
+SUBDIRS       += arch/mips/brcm-boards/bcm933xx
+LOADADDR      := 0x80010000
+
+vmlinux.srec: vmlinux
+	$(OBJCOPY) -O srec $< $@
+linux.srec: vmlinux.srec
+	$(OBJCOPY) --adjust-vma=0x80000000 -O srec $< $@
+vmlinux.out: vmlinux.bin
+	$(TOPDIR)/pstore.sh
+vmlinux.bin: vmlinux
+	$(OBJCOPY) -O binary $< $@
+export LOADADDR
+endif
+
+#
 # SNI RM200 PCI
 #
 ifdef CONFIG_SNI_RM200_PCI
diff -bEruN linux-2.4.20-my/arch/mips/pci/Makefile linux-2.4.20-nc/arch/mips/pci/Makefile
--- linux-2.4.20-my/arch/mips/pci/Makefile	2006-06-12 22:17:21.000000000 -0700
+++ linux-2.4.20-nc/arch/mips/pci/Makefile	2006-05-18 18:18:24.000000000 -0700
@@ -13,7 +13,9 @@
 obj-$(CONFIG_MIPS_MSC)		+= ops-msc.o
 obj-$(CONFIG_MIPS_NILE4)	+= ops-nile4.o
 obj-$(CONFIG_SNI_RM200_PCI)	+= ops-sni.o
+ifndef CONFIG_BCM947XX
 obj-y				+= pci.o
+endif
 obj-$(CONFIG_PCI_AUTO)		+= pci_auto.o
 
 include $(TOPDIR)/Rules.make
diff -bEruN linux-2.4.20-my/arch/mips/ramdisk/Makefile linux-2.4.20-nc/arch/mips/ramdisk/Makefile
--- linux-2.4.20-my/arch/mips/ramdisk/Makefile	2006-06-02 07:55:18.000000000 -0700
+++ linux-2.4.20-nc/arch/mips/ramdisk/Makefile	2006-06-02 08:21:26.000000000 -0700
@@ -5,10 +5,10 @@
 # removes any old dependencies. DON'T put your own dependencies here
 # unless it's something special (ie not a .c file).
 #
-
 O_FORMAT = $(shell $(OBJDUMP) -i | head -2 | grep elf32)
-img = $(CONFIG_EMBEDDED_RAMDISK_IMAGE)
-ramdisk.o: $(subst ",,$(img)) ld.script
+img = $(subst ",,$(CONFIG_EMBEDDED_RAMDISK_IMAGE))
+
+ramdisk.o: $(img) ld.script
 	echo "O_FORMAT:  " $(O_FORMAT)
 	$(LD) $(LDFLAGS) -T ld.script -b binary --oformat $(O_FORMAT) -o $@ $(img)
 
diff -bEruN linux-2.4.20-my/drivers/block/Config.in linux-2.4.20-nc/drivers/block/Config.in
--- linux-2.4.20-my/drivers/block/Config.in	2005-11-08 06:24:37.000000000 -0800
+++ linux-2.4.20-nc/drivers/block/Config.in	2006-06-02 08:21:26.000000000 -0700
@@ -4,6 +4,9 @@
 mainmenu_option next_comment
 comment 'Block devices'
 
+
+tristate 'No-root support' CONFIG_NOROOT
+
 tristate 'Normal floppy disk support' CONFIG_BLK_DEV_FD
 if [ "$CONFIG_AMIGA" = "y" ]; then
    tristate 'Amiga floppy support' CONFIG_AMIGA_FLOPPY
diff -bEruN linux-2.4.20-my/drivers/block/dummy.c linux-2.4.20-nc/drivers/block/dummy.c
--- linux-2.4.20-my/drivers/block/dummy.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/drivers/block/dummy.c	2006-06-02 08:21:26.000000000 -0700
@@ -0,0 +1,70 @@
+/*
+ * dummyfs: a placeholder filesystem that sleeps forever when mounted
+ *
+ * Copyright 2005, Broadcom Corporation      
+ * All Rights Reserved.      
+ *       
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY      
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM      
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS      
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.      
+ *
+ * $Id: dummy.c,v 1.1.1.7 2005/03/07 07:30:43 kanki Exp $
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/stat.h>
+#include <linux/errno.h>
+#include <linux/major.h>
+#include <linux/wait.h>
+#include <linux/blk.h>
+#include <linux/init.h>
+#include <linux/devfs_fs_kernel.h>
+#include <linux/smp_lock.h>
+#include <linux/swap.h>
+#include <linux/slab.h>
+
+#include <asm/uaccess.h>
+
+/* I don't thik anyone would mind if we stole CM206_CDROM_MAJOR */
+#define DUMMY_MAJOR 0x20
+
+static int dummy_open(struct inode *inode, struct file *file)
+{
+	DECLARE_WAIT_QUEUE_HEAD(wait);
+
+	for (;;)
+		sleep_on(&wait);
+
+	return 0;
+}
+
+static struct block_device_operations dummy_fops = {
+	open:		dummy_open,
+};
+
+int __init dummy_init(void) 
+{
+	if (devfs_register_blkdev(DUMMY_MAJOR, "dummy", &dummy_fops)) {
+		printk(KERN_WARNING "Unable to get major number for dummy device\n");
+		return -EIO;
+	}
+
+	register_disk(NULL, MKDEV(DUMMY_MAJOR, 0), 1, &dummy_fops, 0);
+
+	return 0;
+}
+
+void dummy_exit(void) 
+{
+	if (devfs_unregister_blkdev(0, "dummy"))
+		printk(KERN_WARNING "dummy: cannot unregister blkdev\n");
+}
+
+module_init(dummy_init);
+module_exit(dummy_exit);
diff -bEruN linux-2.4.20-my/drivers/char/mem.c linux-2.4.20-nc/drivers/char/mem.c
--- linux-2.4.20-my/drivers/char/mem.c	2005-11-08 06:23:49.000000000 -0800
+++ linux-2.4.20-nc/drivers/char/mem.c	2006-06-02 08:21:26.000000000 -0700
@@ -713,7 +713,8 @@
 	{1, "mem",     S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops},
 	{2, "kmem",    S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops},
 	{3, "null",    S_IRUGO | S_IWUGO,           &null_fops},
-#if defined(CONFIG_ISA) || !defined(__mc68000__)
+#if defined(CONFIG_ISA) || !defined(__mc68000__) || \
+    defined(CONFIG_BCM94702_CPCI)
 	{4, "port",    S_IRUSR | S_IWUSR | S_IRGRP, &port_fops},
 #endif
 	{5, "zero",    S_IRUGO | S_IWUGO,           &zero_fops},
diff -bEruN linux-2.4.20-my/drivers/char/serial.c linux-2.4.20-nc/drivers/char/serial.c
--- linux-2.4.20-my/drivers/char/serial.c	2006-06-02 07:55:18.000000000 -0700
+++ linux-2.4.20-nc/drivers/char/serial.c	2006-06-02 08:21:26.000000000 -0700
@@ -444,6 +444,10 @@
 		return inb(info->port+1);
 #endif
 	case SERIAL_IO_MEM:
+#ifdef CONFIG_BCM4310
+		readb((unsigned long) info->iomem_base +
+		      (UART_SCR<<info->iomem_reg_shift));
+#endif
 		return readb((unsigned long) info->iomem_base +
 			     (offset<<info->iomem_reg_shift));
 	default:
@@ -464,6 +468,9 @@
 	case SERIAL_IO_MEM:
 		writeb(value, (unsigned long) info->iomem_base +
 			      (offset<<info->iomem_reg_shift));
+#ifdef CONFIG_BCM4704
+		*((volatile unsigned int *) KSEG1ADDR(0x18000000));
+#endif
 		break;
 	default:
 		outb(value, info->port+offset);
@@ -1728,7 +1735,7 @@
 			/* Special case since 134 is really 134.5 */
 			quot = (2*baud_base / 269);
 		else if (baud)
-			quot = baud_base / baud;
+			quot = (baud_base + (baud / 2)) / baud;
 	}
 	/* If the quotient is zero refuse the change */
 	if (!quot && old_termios) {
@@ -1745,12 +1752,12 @@
 				/* Special case since 134 is really 134.5 */
 				quot = (2*baud_base / 269);
 			else if (baud)
-				quot = baud_base / baud;
+				quot = (baud_base + (baud / 2)) / baud;
 		}
 	}
 	/* As a last resort, if the quotient is zero, default to 9600 bps */
 	if (!quot)
-		quot = baud_base / 9600;
+		quot = (baud_base + 4800) / 9600;
 	/*
 	 * Work around a bug in the Oxford Semiconductor 952 rev B
 	 * chip which causes it to seriously miscalculate baud rates
@@ -5994,6 +6001,13 @@
 	 *	Divisor, bytesize and parity
 	 */
 	state = rs_table + co->index;
+	/*
+	* Safe guard: state structure must have been initialized
+	*/
+	if (state->iomem_base == NULL) {
+		printk("!unable to setup serial console!\n");
+		return -1;
+	}
 	if (doflow)
 		state->flags |= ASYNC_CONS_FLOW;
 	info = &async_sercons;
@@ -6007,7 +6021,7 @@
 	info->io_type = state->io_type;
 	info->iomem_base = state->iomem_base;
 	info->iomem_reg_shift = state->iomem_reg_shift;
-	quot = state->baud_base / baud;
+	quot = (state->baud_base + (baud / 2)) / baud;
 	cval = cflag & (CSIZE | CSTOPB);
 #if defined(__powerpc__) || defined(__alpha__)
 	cval >>= 8;
diff -bEruN linux-2.4.20-my/drivers/mtd/mtdblock_ro.c linux-2.4.20-nc/drivers/mtd/mtdblock_ro.c
--- linux-2.4.20-my/drivers/mtd/mtdblock_ro.c	2005-11-08 06:23:50.000000000 -0800
+++ linux-2.4.20-nc/drivers/mtd/mtdblock_ro.c	2006-06-02 08:21:26.000000000 -0700
@@ -1,18 +1,16 @@
 /*
  * $Id: mtdblock_ro.c,v 1.12 2001/11/20 11:42:33 dwmw2 Exp $
+ * Direct MTD block device access
  *
- * Read-only version of the mtdblock device, without the 
- * read/erase/modify/writeback stuff
+ *
+ * 02-nov-2000	Nicolas Pitre		Added read-modify-write with cache
  */
 
-#ifdef MTDBLOCK_DEBUG
-#define DEBUGLVL debug
-#endif							       
-
-
-#include <linux/module.h>
+#include <linux/config.h>
 #include <linux/types.h>
-
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/compatmac.h>
 
@@ -24,56 +22,106 @@
 #define DEVICE_OFF(device)
 #define DEVICE_NO_RANDOM
 #include <linux/blk.h>
-
+/* for old kernels... */
+#ifndef QUEUE_EMPTY
+#define QUEUE_EMPTY  (!CURRENT)
+#endif
 #if LINUX_VERSION_CODE < 0x20300
-#define RQFUNC_ARG void
-#define blkdev_dequeue_request(req) do {CURRENT = req->next;} while (0)
+#define QUEUE_PLUGGED (blk_dev[MAJOR_NR].plug_tq.sync)
 #else
-#define RQFUNC_ARG request_queue_t *q
+#define QUEUE_PLUGGED (blk_dev[MAJOR_NR].request_queue.plugged)
 #endif
 
-#ifdef MTDBLOCK_DEBUG
-static int debug = MTDBLOCK_DEBUG;
-MODULE_PARM(debug, "i");
+#ifdef CONFIG_DEVFS_FS
+#include <linux/devfs_fs_kernel.h>
+static void mtd_notify_add(struct mtd_info* mtd);
+static void mtd_notify_remove(struct mtd_info* mtd);
+static struct mtd_notifier notifier = {
+        mtd_notify_add,
+        mtd_notify_remove,
+        NULL
+};
+static devfs_handle_t devfs_dir_handle = NULL;
+static devfs_handle_t devfs_ro_handle[MAX_MTD_DEVICES];
 #endif
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,14)
-#define BLK_INC_USE_COUNT MOD_INC_USE_COUNT
-#define BLK_DEC_USE_COUNT MOD_DEC_USE_COUNT
-#else
-#define BLK_INC_USE_COUNT do {} while(0)
-#define BLK_DEC_USE_COUNT do {} while(0)
-#endif
+static struct mtdblk_dev {
+	struct mtd_info *mtd; /* Locked */
+	int count;
+} *mtdblks[MAX_MTD_DEVICES];
 
-static int mtd_sizes[MAX_MTD_DEVICES];
+static spinlock_t mtdblks_lock;
 
+static int mtd_sizes[MAX_MTD_DEVICES];
 
 static int mtdblock_open(struct inode *inode, struct file *file)
 {
-	struct mtd_info *mtd = NULL;
-
+	struct mtdblk_dev *mtdblk;
+	struct mtd_info *mtd;
 	int dev;
 
-	DEBUG(1,"mtdblock_open\n");
+	DEBUG(MTD_DEBUG_LEVEL1,"mtdblock_open\n");
 	
-	if (inode == 0)
+	if (!inode)
 		return -EINVAL;
 	
 	dev = MINOR(inode->i_rdev);
+	if (dev >= MAX_MTD_DEVICES)
+		return -EINVAL;
 	
 	mtd = get_mtd_device(NULL, dev);
 	if (!mtd)
-		return -EINVAL;
+		return -ENODEV;
 	if (MTD_ABSENT == mtd->type) {
 		put_mtd_device(mtd);
-		return -EINVAL;
+		return -ENODEV;
+	}
+	
+	spin_lock(&mtdblks_lock);
+
+	/* If it's already open, no need to piss about. */
+	if (mtdblks[dev]) {
+		mtdblks[dev]->count++;
+		spin_unlock(&mtdblks_lock);
+		return 0;
+	}
+	
+	/* OK, it's not open. Try to find it */
+
+	/* First we have to drop the lock, because we have to
+	   to things which might sleep.
+	*/
+	spin_unlock(&mtdblks_lock);
+
+	mtdblk = kmalloc(sizeof(struct mtdblk_dev), GFP_KERNEL);
+	if (!mtdblk) {
+		put_mtd_device(mtd);
+		return -ENOMEM;
+	}
+	memset(mtdblk, 0, sizeof(*mtdblk));
+	mtdblk->count = 1;
+	mtdblk->mtd = mtd;
+
+	/* OK, we've created a new one. Add it to the list. */
+
+	spin_lock(&mtdblks_lock);
+
+	if (mtdblks[dev]) {
+		/* Another CPU made one at the same time as us. */
+		mtdblks[dev]->count++;
+		spin_unlock(&mtdblks_lock);
+		put_mtd_device(mtdblk->mtd);
+		kfree(mtdblk);
+		return 0;
 	}
 
-	BLK_INC_USE_COUNT;
+	mtdblks[dev] = mtdblk;
+	mtd_sizes[dev] = mtdblk->mtd->size/1024;
+	set_device_ro (inode->i_rdev, !(mtdblk->mtd->flags & MTD_WRITEABLE));
 
-	mtd_sizes[dev] = mtd->size>>9;
+	spin_unlock(&mtdblks_lock);
 
-	DEBUG(1, "ok\n");
+	DEBUG(MTD_DEBUG_LEVEL1, "ok\n");
 
 	return 0;
 }
@@ -81,163 +129,169 @@
 static release_t mtdblock_release(struct inode *inode, struct file *file)
 {
 	int dev;
-	struct mtd_info *mtd;
-
-   	DEBUG(1, "mtdblock_release\n");
+	struct mtdblk_dev *mtdblk;
+   	DEBUG(MTD_DEBUG_LEVEL1, "mtdblock_release\n");
 
 	if (inode == NULL)
 		release_return(-ENODEV);
    
 	dev = MINOR(inode->i_rdev);
-	mtd = __get_mtd_device(NULL, dev);
+	mtdblk = mtdblks[dev];
 
-	if (!mtd) {
-		printk(KERN_WARNING "MTD device is absent on mtd_release!\n");
-		BLK_DEC_USE_COUNT;
-		release_return(-ENODEV);
+	spin_lock(&mtdblks_lock);
+	if (!--mtdblk->count) {
+		/* It was the last usage. Free the device */
+		mtdblks[dev] = NULL;
+		spin_unlock(&mtdblks_lock);
+		if (mtdblk->mtd->sync)
+			mtdblk->mtd->sync(mtdblk->mtd);
+		put_mtd_device(mtdblk->mtd);
+		kfree(mtdblk);
+	} else {
+		spin_unlock(&mtdblks_lock);
 	}
 	
-	if (mtd->sync)
-		mtd->sync(mtd);
-
-	put_mtd_device(mtd);
-
-	DEBUG(1, "ok\n");
+	DEBUG(MTD_DEBUG_LEVEL1, "ok\n");
 
-	BLK_DEC_USE_COUNT;
 	release_return(0);
 }  
 
 
-static void mtdblock_request(RQFUNC_ARG)
+/* 
+ * This is a special request_fn because it is executed in a process context 
+ * to be able to sleep independently of the caller.  The io_request_lock 
+ * is held upon entry and exit.
+ * The head of our request queue is considered active so there is no need 
+ * to dequeue requests before we are done.
+ */
+static void handle_mtdblock_request(void)
 {
-   struct request *current_request;
-   unsigned int res = 0;
-   struct mtd_info *mtd;
+	struct request *req;
+	struct mtdblk_dev *mtdblk;
+	unsigned int res;
 
-   while (1)
-   {
-      /* Grab the Request and unlink it from the request list, INIT_REQUEST
-       	 will execute a return if we are done. */
+	for (;;) {
       INIT_REQUEST;
-      current_request = CURRENT;
-   
-      if (MINOR(current_request->rq_dev) >= MAX_MTD_DEVICES)
-      {
-	 printk("mtd: Unsupported device!\n");
-	 end_request(0);
-	 continue;
-      }
-      
-      // Grab our MTD structure
+		req = CURRENT;
+		spin_unlock_irq(&io_request_lock);
+		mtdblk = mtdblks[MINOR(req->rq_dev)];
+		res = 0;
 
-      mtd = __get_mtd_device(NULL, MINOR(current_request->rq_dev));
-      if (!mtd) {
-	      printk("MTD device %d doesn't appear to exist any more\n", CURRENT_DEV);
-	      end_request(0);
-      }
+		if (MINOR(req->rq_dev) >= MAX_MTD_DEVICES)
+			panic(__FUNCTION__": minor out of bound");
 
-      if (current_request->sector << 9 > mtd->size ||
-	  (current_request->sector + current_request->current_nr_sectors) << 9 > mtd->size)
-      {
-	 printk("mtd: Attempt to read past end of device!\n");
-	 printk("size: %x, sector: %lx, nr_sectors %lx\n", mtd->size, 
-		current_request->sector, current_request->current_nr_sectors);
-	 end_request(0);
-	 continue;
-      }
-      
-      /* Remove the request we are handling from the request list so nobody messes
-         with it */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
-      /* Now drop the lock that the ll_rw_blk functions grabbed for us
-         and process the request. This is necessary due to the extreme time
-         we spend processing it. */
-      spin_unlock_irq(&io_request_lock);
-#endif
+		if ((req->sector + req->current_nr_sectors) > (mtdblk->mtd->size >> 9))
+			goto end_req;
 
       // Handle the request
-      switch (current_request->cmd)
+		switch (req->cmd)
       {
+			int err;
          size_t retlen;
 
 	 case READ:
-	 if (MTD_READ(mtd,current_request->sector<<9, 
-		      current_request->current_nr_sectors << 9, 
-		      &retlen, current_request->buffer) == 0)
+			err = MTD_READ (mtdblk->mtd, req->sector << 9, 
+					req->current_nr_sectors << 9,
+					&retlen, req->buffer);
+			if (!err)
 	    res = 1;
-	 else
-	    res = 0;
 	 break;
+		}
 	 
-	 case WRITE:
-
-	 /* printk("mtdblock_request WRITE sector=%d(%d)\n",current_request->sector,
-		current_request->current_nr_sectors);
-	 */
-
-	 // Read only device
-	 if ((mtd->flags & MTD_CAP_RAM) == 0)
-	 {
-	    res = 0;
-	    break;
+end_req:
+		spin_lock_irq(&io_request_lock);
+		end_request(res);
 	 }
+}
 
-	 // Do the write
-	 if (MTD_WRITE(mtd,current_request->sector<<9, 
-		       current_request->current_nr_sectors << 9, 
-		       &retlen, current_request->buffer) == 0)
-	    res = 1;
-	 else
-	    res = 0;
-	 break;
+static volatile int leaving = 0;
+static DECLARE_MUTEX_LOCKED(thread_sem);
+static DECLARE_WAIT_QUEUE_HEAD(thr_wq);
 	 
-	 // Shouldn't happen
-	 default:
-	 printk("mtd: unknown request\n");
-	 break;
-      }
+int mtdblock_thread(void *dummy)
+{
+	struct task_struct *tsk = current;
+	DECLARE_WAITQUEUE(wait, tsk);
 
-      // Grab the lock and re-thread the item onto the linked list
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+	tsk->session = 1;
+	tsk->pgrp = 1;
+	/* we might get involved when memory gets low, so use PF_MEMALLOC */
+	tsk->flags |= PF_MEMALLOC;
+	strcpy(tsk->comm, "mtdblockd");
+	tsk->tty = NULL;
+	spin_lock_irq(&tsk->sigmask_lock);
+	sigfillset(&tsk->blocked);
+	recalc_sigpending(tsk);
+	spin_unlock_irq(&tsk->sigmask_lock);
+	exit_mm(tsk);
+	exit_files(tsk);
+	exit_sighand(tsk);
+	exit_fs(tsk);
+
+	while (!leaving) {
+		add_wait_queue(&thr_wq, &wait);
+		set_current_state(TASK_INTERRUPTIBLE);
 	spin_lock_irq(&io_request_lock);
-#endif
-	end_request(res);
+		if (QUEUE_EMPTY || QUEUE_PLUGGED) {
+			spin_unlock_irq(&io_request_lock);
+			schedule();
+			remove_wait_queue(&thr_wq, &wait); 
+		} else {
+			remove_wait_queue(&thr_wq, &wait); 
+			set_current_state(TASK_RUNNING);
+			handle_mtdblock_request();
+			spin_unlock_irq(&io_request_lock);
    }
+	}
+
+	up(&thread_sem);
+	return 0;
 }
 
+#if LINUX_VERSION_CODE < 0x20300
+#define RQFUNC_ARG void
+#else
+#define RQFUNC_ARG request_queue_t *q
+#endif
+
+static void mtdblock_request(RQFUNC_ARG)
+{
+	/* Don't do anything, except wake the thread if necessary */
+	wake_up(&thr_wq);
+}
 
 
 static int mtdblock_ioctl(struct inode * inode, struct file * file,
 		      unsigned int cmd, unsigned long arg)
 {
-	struct mtd_info *mtd;
+	struct mtdblk_dev *mtdblk;
 
-	mtd = __get_mtd_device(NULL, MINOR(inode->i_rdev));
+	mtdblk = mtdblks[MINOR(inode->i_rdev)];
 
-	if (!mtd) return -EINVAL;
+#ifdef PARANOIA
+	if (!mtdblk)
+		BUG();
+#endif
 
 	switch (cmd) {
 	case BLKGETSIZE:   /* Return device size */
-		return put_user((mtd->size >> 9), (unsigned long *) arg);
-
-#ifdef BLKGETSIZE64
+		return put_user((mtdblk->mtd->size >> 9), (unsigned long *) arg);
 	case BLKGETSIZE64:
-		return put_user((u64)mtd->size, (u64 *)arg);
-#endif
+		return put_user((u64)mtdblk->mtd->size, (u64 *)arg);
 
 	case BLKFLSBUF:
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
-		if(!capable(CAP_SYS_ADMIN))  return -EACCES;
+		if(!capable(CAP_SYS_ADMIN))
+			return -EACCES;
 #endif
 		fsync_dev(inode->i_rdev);
 		invalidate_buffers(inode->i_rdev);
-		if (mtd->sync)
-			mtd->sync(mtd);
+		if (mtdblk->mtd->sync)
+			mtdblk->mtd->sync(mtdblk->mtd);
 		return 0;
 
 	default:
-		return -ENOTTY;
+		return -EINVAL;
 	}
 }
 
@@ -253,43 +308,92 @@
 #else
 static struct block_device_operations mtd_fops = 
 {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,14)
 	owner: THIS_MODULE,
-#endif
 	open: mtdblock_open,
 	release: mtdblock_release,
 	ioctl: mtdblock_ioctl
 };
 #endif
 
+#ifdef CONFIG_DEVFS_FS
+/* Notification that a new device has been added. Create the devfs entry for
+ * it. */
+
+static void mtd_notify_add(struct mtd_info* mtd)
+{
+        char name[8];
+
+        if (!mtd || mtd->type == MTD_ABSENT)
+                return;
+
+        sprintf(name, "%d", mtd->index);
+        devfs_ro_handle[mtd->index] = devfs_register(devfs_dir_handle, name,
+                        DEVFS_FL_DEFAULT, MTD_BLOCK_MAJOR, mtd->index,
+                        S_IFBLK | S_IRUGO | S_IWUGO,
+                        &mtd_fops, NULL);
+}
+
+static void mtd_notify_remove(struct mtd_info* mtd)
+{
+        if (!mtd || mtd->type == MTD_ABSENT)
+                return;
+
+        devfs_unregister(devfs_ro_handle[mtd->index]);
+}
+#endif
+
 int __init init_mtdblock(void)
 {
 	int i;
 
+	spin_lock_init(&mtdblks_lock);
+#ifdef CONFIG_DEVFS_FS
+	if (devfs_register_blkdev(MTD_BLOCK_MAJOR, DEVICE_NAME, &mtd_fops))
+	{
+		printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n",
+			MTD_BLOCK_MAJOR);
+		return -EAGAIN;
+	}
+
+	devfs_dir_handle = devfs_mk_dir(NULL, DEVICE_NAME, NULL);
+	register_mtd_user(&notifier);
+#else
 	if (register_blkdev(MAJOR_NR,DEVICE_NAME,&mtd_fops)) {
 		printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n",
 		       MTD_BLOCK_MAJOR);
 		return -EAGAIN;
 	}
+#endif
 	
 	/* We fill it in at open() time. */
 	for (i=0; i< MAX_MTD_DEVICES; i++) {
 		mtd_sizes[i] = 0;
 	}
-	
+	init_waitqueue_head(&thr_wq);
 	/* Allow the block size to default to BLOCK_SIZE. */
 	blksize_size[MAJOR_NR] = NULL;
 	blk_size[MAJOR_NR] = mtd_sizes;
 	
 	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), &mtdblock_request);
+	kernel_thread (mtdblock_thread, NULL, CLONE_FS|CLONE_FILES|CLONE_SIGHAND);
 	return 0;
 }
 
 static void __exit cleanup_mtdblock(void)
 {
+	leaving = 1;
+	wake_up(&thr_wq);
+	down(&thread_sem);
+#ifdef CONFIG_DEVFS_FS
+	unregister_mtd_user(&notifier);
+	devfs_unregister(devfs_dir_handle);
+	devfs_unregister_blkdev(MTD_BLOCK_MAJOR, DEVICE_NAME);
+#else
 	unregister_blkdev(MAJOR_NR,DEVICE_NAME);
-	blk_size[MAJOR_NR] = NULL;
+#endif
 	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
+	blksize_size[MAJOR_NR] = NULL;
+	blk_size[MAJOR_NR] = NULL;
 }
 
 module_init(init_mtdblock);
@@ -297,5 +401,5 @@
 
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Erwin Authried <eauth@softsys.co.at> et al.");
-MODULE_DESCRIPTION("Simple read-only block device emulation access to MTD devices");
+MODULE_AUTHOR("Nicolas Pitre <nico@cam.org> et al.");
+MODULE_DESCRIPTION("Caching read/erase/writeback block device emulation access to MTD devices");
diff -bEruN linux-2.4.20-my/drivers/pcmcia/bcm4710_generic.c linux-2.4.20-nc/drivers/pcmcia/bcm4710_generic.c
--- linux-2.4.20-my/drivers/pcmcia/bcm4710_generic.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/drivers/pcmcia/bcm4710_generic.c	2006-06-02 08:21:26.000000000 -0700
@@ -0,0 +1,912 @@
+/*
+ *
+ * bcm47xx pcmcia driver
+ *
+ * Copyright 2005, Broadcom Corporation
+ * All Rights Reserved.
+ * 
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ *
+ * Based on sa1100_generic.c from www.handhelds.org,
+ *	and au1000_generic.c from oss.sgi.com.
+ *
+ * $Id: bcm4710_generic.c,v 1.1.1.9 2005/03/07 07:30:49 kanki Exp $
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/tqueue.h>
+#include <linux/timer.h>
+#include <linux/mm.h>
+#include <linux/proc_fs.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/vmalloc.h>
+
+#include <pcmcia/version.h>
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/ss.h>
+#include <pcmcia/bulkmem.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/bus_ops.h>
+#include "cs_internal.h"
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+
+#include <typedefs.h>
+#include <sbextif.h>
+#include <sbconfig.h>
+
+#include "bcm4710pcmcia.h"
+
+#ifdef PCMCIA_DEBUG
+static int pc_debug = PCMCIA_DEBUG;
+#endif
+
+MODULE_DESCRIPTION("Linux PCMCIA Card Services: bcm47xx Socket Controller");
+
+/* This structure maintains housekeeping state for each socket, such
+ * as the last known values of the card detect pins, or the Card Services
+ * callback value associated with the socket:
+ */
+static struct bcm47xx_pcmcia_socket *pcmcia_socket;
+static int socket_count;
+
+
+/* Returned by the low-level PCMCIA interface: */
+static struct pcmcia_low_level *pcmcia_low_level;
+
+/* Event poll timer structure */
+static struct timer_list poll_timer;
+
+
+/* Prototypes for routines which are used internally: */
+
+static int  bcm47xx_pcmcia_driver_init(void);
+static void bcm47xx_pcmcia_driver_shutdown(void);
+static void bcm47xx_pcmcia_task_handler(void *data);
+static void bcm47xx_pcmcia_poll_event(unsigned long data);
+static void bcm47xx_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs);
+static struct tq_struct bcm47xx_pcmcia_task;
+
+#ifdef CONFIG_PROC_FS
+static int bcm47xx_pcmcia_proc_status(char *buf, char **start, 
+		off_t pos, int count, int *eof, void *data);
+#endif
+
+
+/* Prototypes for operations which are exported to the
+ * in-kernel PCMCIA core:
+ */
+
+static int bcm47xx_pcmcia_init(unsigned int sock);
+static int bcm47xx_pcmcia_suspend(unsigned int sock);
+static int bcm47xx_pcmcia_register_callback(unsigned int sock, 
+		void (*handler)(void *, unsigned int), void *info);
+static int bcm47xx_pcmcia_inquire_socket(unsigned int sock, socket_cap_t *cap);
+static int bcm47xx_pcmcia_get_status(unsigned int sock, u_int *value);
+static int bcm47xx_pcmcia_get_socket(unsigned int sock, socket_state_t *state);
+static int bcm47xx_pcmcia_set_socket(unsigned int sock, socket_state_t *state);
+static int bcm47xx_pcmcia_get_io_map(unsigned int sock, struct pccard_io_map *io);
+static int bcm47xx_pcmcia_set_io_map(unsigned int sock, struct pccard_io_map *io);
+static int bcm47xx_pcmcia_get_mem_map(unsigned int sock, struct pccard_mem_map *mem);
+static int bcm47xx_pcmcia_set_mem_map(unsigned int sock, struct pccard_mem_map *mem);
+#ifdef CONFIG_PROC_FS
+static void bcm47xx_pcmcia_proc_setup(unsigned int sock, struct proc_dir_entry *base);
+#endif
+
+static struct pccard_operations bcm47xx_pcmcia_operations = {
+	bcm47xx_pcmcia_init,
+	bcm47xx_pcmcia_suspend,
+	bcm47xx_pcmcia_register_callback,
+	bcm47xx_pcmcia_inquire_socket,
+	bcm47xx_pcmcia_get_status,
+	bcm47xx_pcmcia_get_socket,
+	bcm47xx_pcmcia_set_socket,
+	bcm47xx_pcmcia_get_io_map,
+	bcm47xx_pcmcia_set_io_map,
+	bcm47xx_pcmcia_get_mem_map,
+	bcm47xx_pcmcia_set_mem_map,
+#ifdef CONFIG_PROC_FS
+	bcm47xx_pcmcia_proc_setup
+#endif
+};
+
+
+/*
+ * bcm47xx_pcmcia_driver_init()
+ *
+ * This routine performs a basic sanity check to ensure that this
+ * kernel has been built with the appropriate board-specific low-level
+ * PCMCIA support, performs low-level PCMCIA initialization, registers
+ * this socket driver with Card Services, and then spawns the daemon
+ * thread which is the real workhorse of the socket driver.
+ *
+ * Please see linux/Documentation/arm/SA1100/PCMCIA for more information
+ * on the low-level kernel interface.
+ *
+ * Returns: 0 on success, -1 on error
+ */
+static int __init bcm47xx_pcmcia_driver_init(void)
+{
+	servinfo_t info;
+	struct pcmcia_init pcmcia_init;
+	struct pcmcia_state state;
+	unsigned int i;
+	unsigned long tmp;
+
+
+	printk("\nBCM47XX PCMCIA (CS release %s)\n", CS_RELEASE);
+
+	CardServices(GetCardServicesInfo, &info);
+
+	if (info.Revision != CS_RELEASE_CODE) {
+		printk(KERN_ERR "Card Services release codes do not match\n");
+		return -1;
+	}
+
+#ifdef CONFIG_BCM4710
+	pcmcia_low_level=&bcm4710_pcmcia_ops;
+#else
+#error Unsupported Broadcom BCM47XX board.
+#endif
+
+	pcmcia_init.handler=bcm47xx_pcmcia_interrupt;
+
+	if ((socket_count = pcmcia_low_level->init(&pcmcia_init)) < 0) {
+		printk(KERN_ERR "Unable to initialize PCMCIA service.\n");
+		return -EIO;
+	} else {
+		printk("\t%d PCMCIA sockets initialized.\n", socket_count);
+	}
+
+	pcmcia_socket = 
+		kmalloc(sizeof(struct bcm47xx_pcmcia_socket) * socket_count, 
+				GFP_KERNEL);
+	memset(pcmcia_socket, 0, 
+			sizeof(struct bcm47xx_pcmcia_socket) * socket_count);
+	if (!pcmcia_socket) {
+		printk(KERN_ERR "Card Services can't get memory \n");
+		return -1;
+	}
+			
+	for (i = 0; i < socket_count; i++) {
+		if (pcmcia_low_level->socket_state(i, &state) < 0) {
+			printk(KERN_ERR "Unable to get PCMCIA status\n");
+			return -EIO;
+		}
+		pcmcia_socket[i].k_state = state;
+		pcmcia_socket[i].cs_state.csc_mask = SS_DETECT;
+		
+		if (i == 0) {
+			pcmcia_socket[i].virt_io =
+				(unsigned long)ioremap_nocache(EXTIF_PCMCIA_IOBASE(SB_EXTIF_BASE), 0x1000);
+			/* Substract ioport base which gets added by in/out */
+			pcmcia_socket[i].virt_io -= mips_io_port_base;
+			pcmcia_socket[i].phys_attr =
+				(unsigned long)EXTIF_PCMCIA_CFGBASE(SB_EXTIF_BASE);
+			pcmcia_socket[i].phys_mem =
+				(unsigned long)EXTIF_PCMCIA_MEMBASE(SB_EXTIF_BASE);
+		} else  {
+			printk(KERN_ERR "bcm4710: socket 1 not supported\n");
+			return 1;
+		}
+	}
+
+	/* Only advertise as many sockets as we can detect: */
+	if (register_ss_entry(socket_count, &bcm47xx_pcmcia_operations) < 0) {
+		printk(KERN_ERR "Unable to register socket service routine\n");
+		return -ENXIO;
+	}
+
+	/* Start the event poll timer.  
+	 * It will reschedule by itself afterwards. 
+	 */
+	bcm47xx_pcmcia_poll_event(0);
+
+	DEBUG(1, "bcm4710: initialization complete\n");
+	return 0;
+
+}
+
+module_init(bcm47xx_pcmcia_driver_init);
+
+
+/*
+ * bcm47xx_pcmcia_driver_shutdown()
+ *
+ * Invokes the low-level kernel service to free IRQs associated with this
+ * socket controller and reset GPIO edge detection.
+ */
+static void __exit bcm47xx_pcmcia_driver_shutdown(void)
+{
+	int i;
+
+	del_timer_sync(&poll_timer);
+	unregister_ss_entry(&bcm47xx_pcmcia_operations);
+	pcmcia_low_level->shutdown();
+	flush_scheduled_tasks();
+	for (i = 0; i < socket_count; i++) {
+		if (pcmcia_socket[i].virt_io) 
+			iounmap((void *)pcmcia_socket[i].virt_io);
+		if (pcmcia_socket[i].phys_attr) 
+			iounmap((void *)pcmcia_socket[i].phys_attr);
+		if (pcmcia_socket[i].phys_mem) 
+			iounmap((void *)pcmcia_socket[i].phys_mem);
+	}
+	DEBUG(1, "bcm4710: shutdown complete\n");
+}
+
+module_exit(bcm47xx_pcmcia_driver_shutdown);
+
+/*
+ * bcm47xx_pcmcia_init()
+ * We perform all of the interesting initialization tasks in 
+ * bcm47xx_pcmcia_driver_init().
+ *
+ * Returns: 0
+ */
+static int bcm47xx_pcmcia_init(unsigned int sock)
+{
+	DEBUG(1, "%s(): initializing socket %u\n", __FUNCTION__, sock);
+
+	return 0;
+}
+
+/*
+ * bcm47xx_pcmcia_suspend()
+ *
+ * We don't currently perform any actions on a suspend.
+ *
+ * Returns: 0
+ */
+static int bcm47xx_pcmcia_suspend(unsigned int sock)
+{
+	DEBUG(1, "%s(): suspending socket %u\n", __FUNCTION__, sock);
+
+	return 0;
+}
+
+
+/*
+ * bcm47xx_pcmcia_events()
+ *
+ * Helper routine to generate a Card Services event mask based on
+ * state information obtained from the kernel low-level PCMCIA layer
+ * in a recent (and previous) sampling. Updates `prev_state'.
+ *
+ * Returns: an event mask for the given socket state.
+ */
+static inline unsigned 
+bcm47xx_pcmcia_events(struct pcmcia_state *state, 
+		struct pcmcia_state *prev_state, 
+		unsigned int mask, unsigned int flags)
+{
+	unsigned int events=0;
+
+	if (state->bvd1 != prev_state->bvd1) {
+
+		DEBUG(3, "%s(): card BVD1 value %u\n", __FUNCTION__, state->bvd1);
+
+		events |= mask & (flags & SS_IOCARD) ? SS_STSCHG : SS_BATDEAD;
+	}
+
+	if (state->bvd2 != prev_state->bvd2) {
+
+		DEBUG(3, "%s(): card BVD2 value %u\n", __FUNCTION__, state->bvd2);
+
+		events |= mask & (flags & SS_IOCARD) ? 0 : SS_BATWARN;
+	}
+
+	if (state->detect != prev_state->detect) {
+
+		DEBUG(3, "%s(): card detect value %u\n", __FUNCTION__, state->detect);
+
+		events |= mask & SS_DETECT;
+	}
+
+
+	if (state->ready != prev_state->ready) {
+
+		DEBUG(3, "%s(): card ready value %u\n", __FUNCTION__, state->ready);
+
+		events |= mask & ((flags & SS_IOCARD) ? 0 : SS_READY);
+	}
+
+	if (events != 0) {
+		DEBUG(2, "events: %s%s%s%s%s\n",
+		      (events & SS_DETECT) ? "DETECT " : "",
+		      (events & SS_READY) ? "READY " : "",
+		      (events & SS_BATDEAD) ? "BATDEAD " : "",
+		      (events & SS_BATWARN) ? "BATWARN " : "",
+		      (events & SS_STSCHG) ? "STSCHG " : "");
+	}
+
+	*prev_state=*state;
+	return events;
+}
+
+
+/* 
+ * bcm47xx_pcmcia_task_handler()
+ *
+ * Processes serviceable socket events using the "eventd" thread context.
+ *
+ * Event processing (specifically, the invocation of the Card Services event
+ * callback) occurs in this thread rather than in the actual interrupt
+ * handler due to the use of scheduling operations in the PCMCIA core.
+ */
+static void bcm47xx_pcmcia_task_handler(void *data) 
+{
+	struct pcmcia_state state;
+	int i, events, irq_status;
+
+	DEBUG(4, "%s(): entering PCMCIA monitoring thread\n", __FUNCTION__);
+
+	for (i = 0; i < socket_count; i++)  {
+		if ((irq_status = pcmcia_low_level->socket_state(i, &state)) < 0)
+			printk(KERN_ERR "Error in kernel low-level PCMCIA service.\n");
+
+		events = bcm47xx_pcmcia_events(&state, 
+					       &pcmcia_socket[i].k_state, 
+					       pcmcia_socket[i].cs_state.csc_mask, 
+					       pcmcia_socket[i].cs_state.flags);
+
+		if (pcmcia_socket[i].handler != NULL) {
+			pcmcia_socket[i].handler(pcmcia_socket[i].handler_info,
+						 events);
+		}
+	}
+}
+
+static struct tq_struct bcm47xx_pcmcia_task = {
+	routine: bcm47xx_pcmcia_task_handler
+};
+
+
+/*
+ * bcm47xx_pcmcia_poll_event()
+ *
+ * Let's poll for events in addition to IRQs since IRQ only is unreliable...
+ */
+static void bcm47xx_pcmcia_poll_event(unsigned long dummy)
+{
+	DEBUG(4, "%s(): polling for events\n", __FUNCTION__);
+
+	poll_timer.function = bcm47xx_pcmcia_poll_event;
+	poll_timer.expires = jiffies + BCM47XX_PCMCIA_POLL_PERIOD;
+	add_timer(&poll_timer);
+	schedule_task(&bcm47xx_pcmcia_task);
+}
+
+
+/* 
+ * bcm47xx_pcmcia_interrupt()
+ *
+ * Service routine for socket driver interrupts (requested by the
+ * low-level PCMCIA init() operation via bcm47xx_pcmcia_thread()).
+ *
+ * The actual interrupt-servicing work is performed by
+ * bcm47xx_pcmcia_task(), largely because the Card Services event-
+ * handling code performs scheduling operations which cannot be
+ * executed from within an interrupt context.
+ */
+static void 
+bcm47xx_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs)
+{
+	DEBUG(3, "%s(): servicing IRQ %d\n", __FUNCTION__, irq);
+	schedule_task(&bcm47xx_pcmcia_task);
+}
+
+
+/*
+ * bcm47xx_pcmcia_register_callback()
+ *
+ * Implements the register_callback() operation for the in-kernel
+ * PCMCIA service (formerly SS_RegisterCallback in Card Services). If 
+ * the function pointer `handler' is not NULL, remember the callback 
+ * location in the state for `sock', and increment the usage counter 
+ * for the driver module. (The callback is invoked from the interrupt
+ * service routine, bcm47xx_pcmcia_interrupt(), to notify Card Services
+ * of interesting events.) Otherwise, clear the callback pointer in the
+ * socket state and decrement the module usage count.
+ *
+ * Returns: 0
+ */
+static int 
+bcm47xx_pcmcia_register_callback(unsigned int sock, 
+		void (*handler)(void *, unsigned int), void *info)
+{
+	if (handler == NULL) {
+		pcmcia_socket[sock].handler = NULL;
+		MOD_DEC_USE_COUNT;
+	} else {
+		MOD_INC_USE_COUNT;
+		pcmcia_socket[sock].handler = handler;
+		pcmcia_socket[sock].handler_info = info;
+	}
+	return 0;
+}
+
+
+/*
+ * bcm47xx_pcmcia_inquire_socket()
+ *
+ * Implements the inquire_socket() operation for the in-kernel PCMCIA
+ * service (formerly SS_InquireSocket in Card Services). Of note is
+ * the setting of the SS_CAP_PAGE_REGS bit in the `features' field of
+ * `cap' to "trick" Card Services into tolerating large "I/O memory" 
+ * addresses. Also set is SS_CAP_STATIC_MAP, which disables the memory
+ * resource database check. (Mapped memory is set up within the socket
+ * driver itself.)
+ *
+ * In conjunction with the STATIC_MAP capability is a new field,
+ * `io_offset', recommended by David Hinds. Rather than go through
+ * the SetIOMap interface (which is not quite suited for communicating
+ * window locations up from the socket driver), we just pass up
+ * an offset which is applied to client-requested base I/O addresses
+ * in alloc_io_space().
+ *
+ * Returns: 0 on success, -1 if no pin has been configured for `sock'
+ */
+static int
+bcm47xx_pcmcia_inquire_socket(unsigned int sock, socket_cap_t *cap)
+{
+	struct pcmcia_irq_info irq_info;
+
+	if (sock >= socket_count) {
+		printk(KERN_ERR "bcm47xx: socket %u not configured\n", sock);
+		return -1;
+	}
+
+	/* SS_CAP_PAGE_REGS: used by setup_cis_mem() in cistpl.c to set the
+	 *   force_low argument to validate_mem() in rsrc_mgr.c -- since in
+	 *   general, the mapped * addresses of the PCMCIA memory regions
+	 *   will not be within 0xffff, setting force_low would be
+	 *   undesirable.
+	 *
+	 * SS_CAP_STATIC_MAP: don't bother with the (user-configured) memory
+	 *   resource database; we instead pass up physical address ranges
+	 *   and allow other parts of Card Services to deal with remapping.
+	 *
+	 * SS_CAP_PCCARD: we can deal with 16-bit PCMCIA & CF cards, but
+	 *   not 32-bit CardBus devices.
+	 */
+	cap->features = (SS_CAP_PAGE_REGS  | SS_CAP_STATIC_MAP | SS_CAP_PCCARD);
+
+	irq_info.sock = sock;
+	irq_info.irq = -1;
+
+	if (pcmcia_low_level->get_irq_info(&irq_info) < 0) {
+		printk(KERN_ERR "Error obtaining IRQ info socket %u\n", sock);
+		return -1;
+	}
+
+	cap->irq_mask = 0;
+	cap->map_size = PAGE_SIZE;
+	cap->pci_irq = irq_info.irq;
+	cap->io_offset = pcmcia_socket[sock].virt_io;
+
+	return 0;
+}
+
+
+/*
+ * bcm47xx_pcmcia_get_status()
+ *
+ * Implements the get_status() operation for the in-kernel PCMCIA
+ * service (formerly SS_GetStatus in Card Services). Essentially just
+ * fills in bits in `status' according to internal driver state or
+ * the value of the voltage detect chipselect register.
+ *
+ * As a debugging note, during card startup, the PCMCIA core issues
+ * three set_socket() commands in a row the first with RESET deasserted,
+ * the second with RESET asserted, and the last with RESET deasserted
+ * again. Following the third set_socket(), a get_status() command will
+ * be issued. The kernel is looking for the SS_READY flag (see
+ * setup_socket(), reset_socket(), and unreset_socket() in cs.c).
+ *
+ * Returns: 0
+ */
+static int 
+bcm47xx_pcmcia_get_status(unsigned int sock, unsigned int *status)
+{
+	struct pcmcia_state state;
+
+
+	if ((pcmcia_low_level->socket_state(sock, &state)) < 0) {
+		printk(KERN_ERR "Unable to get PCMCIA status from kernel.\n");
+		return -1;
+	}
+
+	pcmcia_socket[sock].k_state = state;
+
+	*status = state.detect ? SS_DETECT : 0;
+
+	*status |= state.ready ? SS_READY : 0;
+
+	/* The power status of individual sockets is not available
+	 * explicitly from the hardware, so we just remember the state
+	 * and regurgitate it upon request:
+	 */
+	*status |= pcmcia_socket[sock].cs_state.Vcc ? SS_POWERON : 0;
+
+	if (pcmcia_socket[sock].cs_state.flags & SS_IOCARD)
+		*status |= state.bvd1 ? SS_STSCHG : 0;
+	else {
+		if (state.bvd1 == 0)
+			*status |= SS_BATDEAD;
+		else if (state.bvd2 == 0)
+			*status |= SS_BATWARN;
+	}
+
+	*status |= state.vs_3v ? SS_3VCARD : 0;
+
+	*status |= state.vs_Xv ? SS_XVCARD : 0;
+
+	DEBUG(2, "\tstatus: %s%s%s%s%s%s%s%s\n",
+	      (*status&SS_DETECT)?"DETECT ":"",
+	      (*status&SS_READY)?"READY ":"", 
+	      (*status&SS_BATDEAD)?"BATDEAD ":"",
+	      (*status&SS_BATWARN)?"BATWARN ":"",
+	      (*status&SS_POWERON)?"POWERON ":"",
+	      (*status&SS_STSCHG)?"STSCHG ":"",
+	      (*status&SS_3VCARD)?"3VCARD ":"",
+	      (*status&SS_XVCARD)?"XVCARD ":"");
+
+	return 0;
+}
+
+
+/*
+ * bcm47xx_pcmcia_get_socket()
+ *
+ * Implements the get_socket() operation for the in-kernel PCMCIA
+ * service (formerly SS_GetSocket in Card Services). Not a very 
+ * exciting routine.
+ *
+ * Returns: 0
+ */
+static int 
+bcm47xx_pcmcia_get_socket(unsigned int sock, socket_state_t *state)
+{
+	DEBUG(2, "%s() for sock %u\n", __FUNCTION__, sock);
+
+	/* This information was given to us in an earlier call to set_socket(),
+	 * so we're just regurgitating it here:
+	 */
+	*state = pcmcia_socket[sock].cs_state;
+	return 0;
+}
+
+
+/*
+ * bcm47xx_pcmcia_set_socket()
+ *
+ * Implements the set_socket() operation for the in-kernel PCMCIA
+ * service (formerly SS_SetSocket in Card Services). We more or
+ * less punt all of this work and let the kernel handle the details
+ * of power configuration, reset, &c. We also record the value of
+ * `state' in order to regurgitate it to the PCMCIA core later.
+ *
+ * Returns: 0
+ */
+static int 
+bcm47xx_pcmcia_set_socket(unsigned int sock, socket_state_t *state)
+{
+	struct pcmcia_configure configure;
+
+	DEBUG(2, "\tmask:  %s%s%s%s%s%s\n\tflags: %s%s%s%s%s%s\n"
+	      "\tVcc %d  Vpp %d  irq %d\n",
+	      (state->csc_mask == 0) ? "<NONE>" : "",
+	      (state->csc_mask & SS_DETECT) ? "DETECT " : "",
+	      (state->csc_mask & SS_READY) ? "READY " : "",
+	      (state->csc_mask & SS_BATDEAD) ? "BATDEAD " : "",
+	      (state->csc_mask & SS_BATWARN) ? "BATWARN " : "",
+	      (state->csc_mask & SS_STSCHG) ? "STSCHG " : "",
+	      (state->flags == 0) ? "<NONE>" : "",
+	      (state->flags & SS_PWR_AUTO) ? "PWR_AUTO " : "",
+	      (state->flags & SS_IOCARD) ? "IOCARD " : "",
+	      (state->flags & SS_RESET) ? "RESET " : "",
+	      (state->flags & SS_SPKR_ENA) ? "SPKR_ENA " : "",
+	      (state->flags & SS_OUTPUT_ENA) ? "OUTPUT_ENA " : "",
+	      state->Vcc, state->Vpp, state->io_irq);
+
+	configure.sock = sock;
+	configure.vcc = state->Vcc;
+	configure.vpp = state->Vpp;
+	configure.output = (state->flags & SS_OUTPUT_ENA) ? 1 : 0;
+	configure.speaker = (state->flags & SS_SPKR_ENA) ? 1 : 0;
+	configure.reset = (state->flags & SS_RESET) ? 1 : 0;
+
+	if (pcmcia_low_level->configure_socket(&configure) < 0) {
+		printk(KERN_ERR "Unable to configure socket %u\n", sock);
+		return -1;
+	}
+
+	pcmcia_socket[sock].cs_state = *state;
+	return 0;
+}
+
+
+/*
+ * bcm47xx_pcmcia_get_io_map()
+ *
+ * Implements the get_io_map() operation for the in-kernel PCMCIA
+ * service (formerly SS_GetIOMap in Card Services). Just returns an
+ * I/O map descriptor which was assigned earlier by a set_io_map().
+ *
+ * Returns: 0 on success, -1 if the map index was out of range
+ */
+static int 
+bcm47xx_pcmcia_get_io_map(unsigned int sock, struct pccard_io_map *map)
+{
+	DEBUG(2, "bcm47xx_pcmcia_get_io_map: sock %d\n", sock);
+
+	if (map->map >= MAX_IO_WIN) {
+		printk(KERN_ERR "%s(): map (%d) out of range\n", 
+		       __FUNCTION__, map->map);
+		return -1;
+	}
+
+	*map = pcmcia_socket[sock].io_map[map->map];
+	return 0;
+}
+
+
+/*
+ * bcm47xx_pcmcia_set_io_map()
+ *
+ * Implements the set_io_map() operation for the in-kernel PCMCIA
+ * service (formerly SS_SetIOMap in Card Services). We configure
+ * the map speed as requested, but override the address ranges
+ * supplied by Card Services.
+ *
+ * Returns: 0 on success, -1 on error
+ */
+int 
+bcm47xx_pcmcia_set_io_map(unsigned int sock, struct pccard_io_map *map)
+{
+	unsigned int speed;
+	unsigned long start;
+
+	DEBUG(2, "\tmap %u  speed %u\n\tstart 0x%08lx  stop 0x%08lx\n"
+	      "\tflags: %s%s%s%s%s%s%s%s\n",
+	      map->map, map->speed, map->start, map->stop,
+	      (map->flags == 0) ? "<NONE>" : "",
+	      (map->flags & MAP_ACTIVE) ? "ACTIVE " : "",
+	      (map->flags & MAP_16BIT) ? "16BIT " : "",
+	      (map->flags & MAP_AUTOSZ) ? "AUTOSZ " : "",
+	      (map->flags & MAP_0WS) ? "0WS " : "",
+	      (map->flags & MAP_WRPROT) ? "WRPROT " : "",
+	      (map->flags & MAP_USE_WAIT) ? "USE_WAIT " : "",
+	      (map->flags & MAP_PREFETCH) ? "PREFETCH " : "");
+
+	if (map->map >= MAX_IO_WIN) {
+		printk(KERN_ERR "%s(): map (%d) out of range\n", 
+				__FUNCTION__, map->map);
+		return -1;
+	}
+
+	if (map->flags & MAP_ACTIVE) {
+		speed = (map->speed > 0) ? map->speed : BCM47XX_PCMCIA_IO_SPEED;
+		pcmcia_socket[sock].speed_io = speed;
+	}
+
+	start = map->start;
+
+	if (map->stop == 1) {
+		map->stop = PAGE_SIZE - 1;
+	}
+
+	map->start = pcmcia_socket[sock].virt_io;
+	map->stop = map->start + (map->stop - start);
+	pcmcia_socket[sock].io_map[map->map] = *map;
+	DEBUG(2, "set_io_map %d start %x stop %x\n", 
+	      map->map, map->start, map->stop);
+	return 0;
+}
+
+
+/*
+ * bcm47xx_pcmcia_get_mem_map()
+ *
+ * Implements the get_mem_map() operation for the in-kernel PCMCIA
+ * service (formerly SS_GetMemMap in Card Services). Just returns a
+ *  memory map descriptor which was assigned earlier by a
+ *  set_mem_map() request.
+ *
+ * Returns: 0 on success, -1 if the map index was out of range
+ */
+static int 
+bcm47xx_pcmcia_get_mem_map(unsigned int sock, struct pccard_mem_map *map)
+{
+	DEBUG(2, "%s() for sock %u\n", __FUNCTION__, sock);
+
+	if (map->map >= MAX_WIN) {
+		printk(KERN_ERR "%s(): map (%d) out of range\n", 
+		       __FUNCTION__, map->map);
+		return -1;
+	}
+
+	*map = pcmcia_socket[sock].mem_map[map->map];
+	return 0;
+}
+
+
+/*
+ * bcm47xx_pcmcia_set_mem_map()
+ *
+ * Implements the set_mem_map() operation for the in-kernel PCMCIA
+ * service (formerly SS_SetMemMap in Card Services). We configure
+ * the map speed as requested, but override the address ranges
+ * supplied by Card Services.
+ *
+ * Returns: 0 on success, -1 on error
+ */
+static int 
+bcm47xx_pcmcia_set_mem_map(unsigned int sock, struct pccard_mem_map *map)
+{
+	unsigned int speed;
+	unsigned long start;
+	u_long flags;
+
+	if (map->map >= MAX_WIN) {
+		printk(KERN_ERR "%s(): map (%d) out of range\n", 
+		       __FUNCTION__, map->map);
+		return -1;
+	}
+
+	DEBUG(2, "\tmap %u  speed %u\n\tsys_start  %#lx\n"
+	      "\tsys_stop   %#lx\n\tcard_start %#x\n"
+	      "\tflags: %s%s%s%s%s%s%s%s\n",
+	      map->map, map->speed, map->sys_start, map->sys_stop,
+	      map->card_start, (map->flags == 0) ? "<NONE>" : "",
+	      (map->flags & MAP_ACTIVE) ? "ACTIVE " : "",
+	      (map->flags & MAP_16BIT) ? "16BIT " : "",
+	      (map->flags & MAP_AUTOSZ) ? "AUTOSZ " : "",
+	      (map->flags & MAP_0WS) ? "0WS " : "",
+	      (map->flags & MAP_WRPROT) ? "WRPROT " : "",
+	      (map->flags & MAP_ATTRIB) ? "ATTRIB " : "",
+	      (map->flags & MAP_USE_WAIT) ? "USE_WAIT " : "");
+
+	if (map->flags & MAP_ACTIVE) {
+		/* When clients issue RequestMap, the access speed is not always
+		 * properly configured:
+		 */
+		speed = (map->speed > 0) ? map->speed : BCM47XX_PCMCIA_MEM_SPEED;
+
+		/* TBD */
+		if (map->flags & MAP_ATTRIB) {
+			pcmcia_socket[sock].speed_attr = speed;
+		} else {
+			pcmcia_socket[sock].speed_mem = speed;
+		}
+	}
+
+	save_flags(flags);
+	cli();
+	start = map->sys_start;
+
+	if (map->sys_stop == 0)
+		map->sys_stop = PAGE_SIZE - 1;
+
+	if (map->flags & MAP_ATTRIB) {
+		map->sys_start = pcmcia_socket[sock].phys_attr + 
+			map->card_start;
+	} else {
+		map->sys_start = pcmcia_socket[sock].phys_mem + 
+			map->card_start;
+	}
+
+	map->sys_stop = map->sys_start + (map->sys_stop - start);
+	pcmcia_socket[sock].mem_map[map->map] = *map;
+	restore_flags(flags);
+	DEBUG(2, "set_mem_map %d start %x stop %x card_start %x\n", 
+			map->map, map->sys_start, map->sys_stop, 
+			map->card_start);
+	return 0;
+}
+
+
+#if defined(CONFIG_PROC_FS)
+
+/*
+ * bcm47xx_pcmcia_proc_setup()
+ *
+ * Implements the proc_setup() operation for the in-kernel PCMCIA
+ * service (formerly SS_ProcSetup in Card Services).
+ *
+ * Returns: 0 on success, -1 on error
+ */
+static void 
+bcm47xx_pcmcia_proc_setup(unsigned int sock, struct proc_dir_entry *base)
+{
+	struct proc_dir_entry *entry;
+
+	if ((entry = create_proc_entry("status", 0, base)) == NULL) {
+		printk(KERN_ERR "Unable to install \"status\" procfs entry\n");
+		return;
+	}
+
+	entry->read_proc = bcm47xx_pcmcia_proc_status;
+	entry->data = (void *)sock;
+}
+
+
+/*
+ * bcm47xx_pcmcia_proc_status()
+ *
+ * Implements the /proc/bus/pccard/??/status file.
+ *
+ * Returns: the number of characters added to the buffer
+ */
+static int 
+bcm47xx_pcmcia_proc_status(char *buf, char **start, off_t pos, 
+			   int count, int *eof, void *data)
+{
+	char *p = buf;
+	unsigned int sock = (unsigned int)data;
+
+	p += sprintf(p, "k_flags  : %s%s%s%s%s%s%s\n", 
+		     pcmcia_socket[sock].k_state.detect ? "detect " : "",
+		     pcmcia_socket[sock].k_state.ready ? "ready " : "",
+		     pcmcia_socket[sock].k_state.bvd1 ? "bvd1 " : "",
+		     pcmcia_socket[sock].k_state.bvd2 ? "bvd2 " : "",
+		     pcmcia_socket[sock].k_state.wrprot ? "wrprot " : "",
+		     pcmcia_socket[sock].k_state.vs_3v ? "vs_3v " : "",
+		     pcmcia_socket[sock].k_state.vs_Xv ? "vs_Xv " : "");
+
+	p += sprintf(p, "status   : %s%s%s%s%s%s%s%s%s\n",
+		     pcmcia_socket[sock].k_state.detect ? "SS_DETECT " : "",
+		     pcmcia_socket[sock].k_state.ready ? "SS_READY " : "",
+		     pcmcia_socket[sock].cs_state.Vcc ? "SS_POWERON " : "",
+		     pcmcia_socket[sock].cs_state.flags & SS_IOCARD ? "SS_IOCARD " : "",
+		     (pcmcia_socket[sock].cs_state.flags & SS_IOCARD &&
+		      pcmcia_socket[sock].k_state.bvd1) ? "SS_STSCHG " : "",
+		     ((pcmcia_socket[sock].cs_state.flags & SS_IOCARD) == 0 &&
+		      (pcmcia_socket[sock].k_state.bvd1 == 0)) ? "SS_BATDEAD " : "",
+		     ((pcmcia_socket[sock].cs_state.flags & SS_IOCARD) == 0 &&
+		      (pcmcia_socket[sock].k_state.bvd2 == 0)) ? "SS_BATWARN " : "",
+		     pcmcia_socket[sock].k_state.vs_3v ? "SS_3VCARD " : "",
+		     pcmcia_socket[sock].k_state.vs_Xv ? "SS_XVCARD " : "");
+
+	p += sprintf(p, "mask     : %s%s%s%s%s\n",
+		     pcmcia_socket[sock].cs_state.csc_mask & SS_DETECT ? "SS_DETECT " : "",
+		     pcmcia_socket[sock].cs_state.csc_mask & SS_READY ? "SS_READY " : "",
+		     pcmcia_socket[sock].cs_state.csc_mask & SS_BATDEAD ? "SS_BATDEAD " : "",
+		     pcmcia_socket[sock].cs_state.csc_mask & SS_BATWARN ? "SS_BATWARN " : "",
+		     pcmcia_socket[sock].cs_state.csc_mask & SS_STSCHG ? "SS_STSCHG " : "");
+
+	p += sprintf(p, "cs_flags : %s%s%s%s%s\n",
+		     pcmcia_socket[sock].cs_state.flags & SS_PWR_AUTO ?
+			"SS_PWR_AUTO " : "",
+		     pcmcia_socket[sock].cs_state.flags & SS_IOCARD ?
+			"SS_IOCARD " : "",
+		     pcmcia_socket[sock].cs_state.flags & SS_RESET ?
+			"SS_RESET " : "",
+		     pcmcia_socket[sock].cs_state.flags & SS_SPKR_ENA ?
+			"SS_SPKR_ENA " : "",
+		     pcmcia_socket[sock].cs_state.flags & SS_OUTPUT_ENA ?
+			"SS_OUTPUT_ENA " : "");
+
+	p += sprintf(p, "Vcc      : %d\n", pcmcia_socket[sock].cs_state.Vcc);
+	p += sprintf(p, "Vpp      : %d\n", pcmcia_socket[sock].cs_state.Vpp);
+	p += sprintf(p, "irq      : %d\n", pcmcia_socket[sock].cs_state.io_irq);
+	p += sprintf(p, "I/O      : %u\n", pcmcia_socket[sock].speed_io);
+	p += sprintf(p, "attribute: %u\n", pcmcia_socket[sock].speed_attr);
+	p += sprintf(p, "common   : %u\n", pcmcia_socket[sock].speed_mem);
+	return p-buf;
+}
+
+
+#endif  /* defined(CONFIG_PROC_FS) */
diff -bEruN linux-2.4.20-my/drivers/pcmcia/bcm4710_pcmcia.c linux-2.4.20-nc/drivers/pcmcia/bcm4710_pcmcia.c
--- linux-2.4.20-my/drivers/pcmcia/bcm4710_pcmcia.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/drivers/pcmcia/bcm4710_pcmcia.c	2006-06-02 08:21:26.000000000 -0700
@@ -0,0 +1,258 @@
+/*
+ * BCM4710 specific pcmcia routines.
+ *
+ * Copyright 2005, Broadcom Corporation
+ * All Rights Reserved.
+ * 
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ *
+ * $Id: bcm4710_pcmcia.c,v 1.1.1.9 2005/03/07 07:30:49 kanki Exp $
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/tqueue.h>
+#include <linux/timer.h>
+#include <linux/mm.h>
+#include <linux/proc_fs.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+
+#include <pcmcia/version.h>
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/ss.h>
+#include <pcmcia/bulkmem.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/bus_ops.h>
+#include "cs_internal.h"
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+
+
+#include <typedefs.h>
+#include <bcmdevs.h>
+#include <sbconfig.h>
+#include <sbextif.h>
+
+#include "bcm4710pcmcia.h"
+
+/* Use a static var for irq dev_id */
+static int bcm47xx_pcmcia_dev_id;
+
+/* Do we think we have a card or not? */
+static int bcm47xx_pcmcia_present = 0;
+
+static extifregs_t *eir = NULL;
+
+
+static void bcm4710_pcmcia_reset(void)
+{
+	unsigned long s;
+	uint32 out0, out1, outen;
+
+	save_and_cli(s);
+
+	/* Use gpio7 to reset the pcmcia slot */
+	outen = readl(&eir->gpio[0].outen);
+	outen |= BCM47XX_PCMCIA_RESET;
+	out0 = readl(&eir->gpio[0].out);
+	out0 &= ~(BCM47XX_PCMCIA_RESET);
+	out1 = out0 | BCM47XX_PCMCIA_RESET;
+
+	writel(out0, &eir->gpio[0].out);
+	writel(outen, &eir->gpio[0].outen);
+	mdelay(1);
+	writel(out1, &eir->gpio[0].out);
+	mdelay(1);
+	writel(out0, &eir->gpio[0].out);
+
+	restore_flags(s);
+}
+
+
+static int bcm4710_pcmcia_init(struct pcmcia_init *init)
+{
+	struct pci_dev *pdev;
+	uint16 *attrsp;
+	uint32 outen, tmp;
+#ifdef DO_BCM47XX_PCMCIA_INTERRUPTS
+	uint32 intp, intm;
+	int rc = 0, i;
+	extern unsigned long bcm4710_cpu_cycle;
+#endif
+
+
+	if (!(pdev = pci_find_device(VENDOR_BROADCOM, SB_EXTIF, NULL))) {
+		printk(KERN_ERR "bcm4710_pcmcia: extif not found\n");
+		return -ENODEV;
+	}
+
+	eir = (extifregs_t *) ioremap_nocache(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
+
+	/* Initialize the pcmcia i/f: 16bit no swap */
+	writel(CF_EM_PCMCIA | CF_DS | CF_EN, &eir->pcmcia_config);
+
+#ifdef	notYet
+
+	/* Set the timing for memory accesses */
+	tmp = (19 / bcm4710_cpu_cycle) << 24;		/* W3 = 10nS */
+	tmp = tmp | ((29 / bcm4710_cpu_cycle) << 16);	/* W2 = 20nS */
+	tmp = tmp | ((109 / bcm4710_cpu_cycle) << 8);	/* W1 = 100nS */
+	tmp = tmp | (129 / bcm4710_cpu_cycle);		/* W0 = 120nS */
+	writel(tmp, &eir->pcmcia_memwait);		/* 0x01020a0c for a 100Mhz clock */
+
+	/* Set the timing for I/O accesses */
+	tmp = (19 / bcm4710_cpu_cycle) << 24;		/* W3 = 10nS */
+	tmp = tmp | ((29 / bcm4710_cpu_cycle) << 16);	/* W2 = 20nS */
+	tmp = tmp | ((109 / bcm4710_cpu_cycle) << 8);	/* W1 = 100nS */
+	tmp = tmp | (129 / bcm4710_cpu_cycle);		/* W0 = 120nS */
+	writel(tmp, &eir->pcmcia_iowait);		/* 0x01020a0c for a 100Mhz clock */
+
+	/* Set the timing for attribute accesses */
+	tmp = (19 / bcm4710_cpu_cycle) << 24;		/* W3 = 10nS */
+	tmp = tmp | ((29 / bcm4710_cpu_cycle) << 16);	/* W2 = 20nS */
+	tmp = tmp | ((109 / bcm4710_cpu_cycle) << 8);	/* W1 = 100nS */
+	tmp = tmp | (129 / bcm4710_cpu_cycle);		/* W0 = 120nS */
+	writel(tmp, &eir->pcmcia_attrwait);		/* 0x01020a0c for a 100Mhz clock */
+
+#endif
+	/* Make sure gpio0 and gpio5 are inputs */
+	outen = readl(&eir->gpio[0].outen);
+	outen &= ~(BCM47XX_PCMCIA_WP | BCM47XX_PCMCIA_STSCHG | BCM47XX_PCMCIA_RESET);
+	writel(outen, &eir->gpio[0].outen);
+
+	/* Issue a reset to the pcmcia socket */
+	bcm4710_pcmcia_reset();
+
+#ifdef	DO_BCM47XX_PCMCIA_INTERRUPTS
+	/* Setup gpio5 to be the STSCHG interrupt */
+	intp = readl(&eir->gpiointpolarity);
+	writel(intp | BCM47XX_PCMCIA_STSCHG, &eir->gpiointpolarity);	/* Active low */
+	intm = readl(&eir->gpiointmask);
+	writel(intm | BCM47XX_PCMCIA_STSCHG, &eir->gpiointmask);	/* Enable it */
+#endif
+
+	DEBUG(2, "bcm4710_pcmcia after reset:\n");
+	DEBUG(2, "\textstatus\t= 0x%08x:\n", readl(&eir->extstatus));
+	DEBUG(2, "\tpcmcia_config\t= 0x%08x:\n", readl(&eir->pcmcia_config));
+	DEBUG(2, "\tpcmcia_memwait\t= 0x%08x:\n", readl(&eir->pcmcia_memwait));
+	DEBUG(2, "\tpcmcia_attrwait\t= 0x%08x:\n", readl(&eir->pcmcia_attrwait));
+	DEBUG(2, "\tpcmcia_iowait\t= 0x%08x:\n", readl(&eir->pcmcia_iowait));
+	DEBUG(2, "\tgpioin\t\t= 0x%08x:\n", readl(&eir->gpioin));
+	DEBUG(2, "\tgpio_outen0\t= 0x%08x:\n", readl(&eir->gpio[0].outen));
+	DEBUG(2, "\tgpio_out0\t= 0x%08x:\n", readl(&eir->gpio[0].out));
+	DEBUG(2, "\tgpiointpolarity\t= 0x%08x:\n", readl(&eir->gpiointpolarity));
+	DEBUG(2, "\tgpiointmask\t= 0x%08x:\n", readl(&eir->gpiointmask));
+
+#ifdef	DO_BCM47XX_PCMCIA_INTERRUPTS
+	/* Request pcmcia interrupt */
+	rc =  request_irq(BCM47XX_PCMCIA_IRQ, init->handler, SA_INTERRUPT,
+			  "PCMCIA Interrupt", &bcm47xx_pcmcia_dev_id);
+#endif
+
+	attrsp = (uint16 *)ioremap_nocache(EXTIF_PCMCIA_CFGBASE(SB_EXTIF_BASE), 0x1000);
+	tmp = readw(&attrsp[0]);
+	DEBUG(2, "\tattr[0] = 0x%04x\n", tmp);
+	if ((tmp == 0x7fff) || (tmp == 0x7f00)) {
+		bcm47xx_pcmcia_present = 0;
+	} else {
+		bcm47xx_pcmcia_present = 1;
+	}
+
+	/* There's only one socket */
+	return 1;
+}
+
+static int bcm4710_pcmcia_shutdown(void)
+{
+	uint32 intm;
+
+	/* Disable the pcmcia i/f */
+	writel(0, &eir->pcmcia_config);
+
+	/* Reset gpio's */
+	intm = readl(&eir->gpiointmask);
+	writel(intm & ~BCM47XX_PCMCIA_STSCHG, &eir->gpiointmask);	/* Disable it */
+
+	free_irq(BCM47XX_PCMCIA_IRQ, &bcm47xx_pcmcia_dev_id);
+
+	return 0;
+}
+
+static int 
+bcm4710_pcmcia_socket_state(unsigned sock, struct pcmcia_state *state)
+{
+	if (sock != 0) {
+		printk(KERN_ERR "bcm4710 socket_state bad sock %d\n", sock);
+		return -1;
+	}
+
+	if (bcm47xx_pcmcia_present) {
+		state->detect = 1;
+		state->ready = 1;
+		state->bvd1 = 1;
+		state->bvd2 = 1;
+		state->wrprot = (readl(&eir->gpioin) & BCM47XX_PCMCIA_WP) == BCM47XX_PCMCIA_WP; 
+		state->vs_3v = 0;
+		state->vs_Xv = 0;
+	} else {
+		state->detect = 0;
+		state->ready = 0;
+	}
+
+	return 1;
+}
+
+
+static int bcm4710_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
+{
+	if (info->sock >= BCM47XX_PCMCIA_MAX_SOCK) return -1;
+
+	info->irq = BCM47XX_PCMCIA_IRQ;		
+
+	return 0;
+}
+
+
+static int 
+bcm4710_pcmcia_configure_socket(const struct pcmcia_configure *configure)
+{
+	if (configure->sock >= BCM47XX_PCMCIA_MAX_SOCK) return -1;
+
+
+	DEBUG(2, "Vcc %dV Vpp %dV output %d speaker %d reset %d\n", configure->vcc,
+	      configure->vpp, configure->output, configure->speaker, configure->reset);
+
+	if ((configure->vcc != 50) || (configure->vpp != 50)) {
+		printk("%s: bad Vcc/Vpp (%d:%d)\n", __FUNCTION__, configure->vcc, 
+		       configure->vpp);
+	}
+
+	if (configure->reset) {
+		/* Issue a reset to the pcmcia socket */
+		DEBUG(1, "%s: Reseting socket\n", __FUNCTION__);
+		bcm4710_pcmcia_reset();
+	}
+
+
+	return 0;
+}
+
+struct pcmcia_low_level bcm4710_pcmcia_ops = { 
+	bcm4710_pcmcia_init,
+	bcm4710_pcmcia_shutdown,
+	bcm4710_pcmcia_socket_state,
+	bcm4710_pcmcia_get_irq_info,
+	bcm4710_pcmcia_configure_socket
+};
+
diff -bEruN linux-2.4.20-my/drivers/pcmcia/bcm4710pcmcia.h linux-2.4.20-nc/drivers/pcmcia/bcm4710pcmcia.h
--- linux-2.4.20-my/drivers/pcmcia/bcm4710pcmcia.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/drivers/pcmcia/bcm4710pcmcia.h	2006-06-02 08:21:26.000000000 -0700
@@ -0,0 +1,118 @@
+/*
+ *
+ * bcm47xx pcmcia driver
+ *
+ * Copyright 2005, Broadcom Corporation
+ * All Rights Reserved.
+ * 
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ *
+ * Based on sa1100.h and include/asm-arm/arch-sa1100/pcmica.h
+ *	from www.handhelds.org,
+ * and au1000_generic.c from oss.sgi.com.
+ *
+ * $Id: bcm4710pcmcia.h,v 1.1.1.8 2005/03/07 07:30:49 kanki Exp $
+ */
+
+#if !defined(_BCM4710PCMCIA_H)
+#define _BCM4710PCMCIA_H
+
+#include <pcmcia/cs_types.h>
+#include <pcmcia/ss.h>
+#include <pcmcia/bulkmem.h>
+#include <pcmcia/cistpl.h>
+#include "cs_internal.h"
+
+
+/* The 47xx can only support one socket */
+#define BCM47XX_PCMCIA_MAX_SOCK		1
+
+/* In the bcm947xx gpio's are used for some pcmcia functions */
+#define	BCM47XX_PCMCIA_WP		0x01		/* Bit 0 is WP input */
+#define	BCM47XX_PCMCIA_STSCHG		0x20		/* Bit 5 is STSCHG input/interrupt */
+#define	BCM47XX_PCMCIA_RESET		0x80		/* Bit 7 is RESET */
+
+#define	BCM47XX_PCMCIA_IRQ		2
+
+/* The socket driver actually works nicely in interrupt-driven form,
+ * so the (relatively infrequent) polling is "just to be sure."
+ */
+#define BCM47XX_PCMCIA_POLL_PERIOD    (2 * HZ)
+
+#define BCM47XX_PCMCIA_IO_SPEED       (255)
+#define BCM47XX_PCMCIA_MEM_SPEED      (300)
+
+
+struct pcmcia_state {
+	unsigned detect: 1,
+		ready: 1,
+		bvd1: 1,
+		bvd2: 1,
+		wrprot: 1,
+		vs_3v: 1,
+		vs_Xv: 1;
+};
+
+
+struct pcmcia_configure {
+	unsigned sock: 8,
+		vcc: 8,
+		vpp: 8,
+		output: 1,
+		speaker: 1,
+		reset: 1;
+};
+
+struct pcmcia_irq_info {
+	unsigned int sock;
+	unsigned int irq;
+};
+
+/* This structure encapsulates per-socket state which we might need to
+ * use when responding to a Card Services query of some kind.
+ */
+struct bcm47xx_pcmcia_socket {
+  socket_state_t        cs_state;
+  struct pcmcia_state   k_state;
+  unsigned int          irq;
+  void                  (*handler)(void *, unsigned int);
+  void                  *handler_info;
+  pccard_io_map         io_map[MAX_IO_WIN];
+  pccard_mem_map        mem_map[MAX_WIN];
+  ioaddr_t              virt_io, phys_attr, phys_mem;
+  unsigned short        speed_io, speed_attr, speed_mem;
+};
+
+struct pcmcia_init {
+	void (*handler)(int irq, void *dev, struct pt_regs *regs);
+};
+
+struct pcmcia_low_level {
+	int (*init)(struct pcmcia_init *);
+	int (*shutdown)(void);
+	int (*socket_state)(unsigned sock, struct pcmcia_state *);
+	int (*get_irq_info)(struct pcmcia_irq_info *);
+	int (*configure_socket)(const struct pcmcia_configure *);
+};
+
+extern struct pcmcia_low_level bcm47xx_pcmcia_ops;
+
+/* I/O pins replacing memory pins
+ * (PCMCIA System Architecture, 2nd ed., by Don Anderson, p.75)
+ *
+ * These signals change meaning when going from memory-only to 
+ * memory-or-I/O interface:
+ */
+#define iostschg bvd1
+#define iospkr   bvd2
+
+
+/*
+ * Declaration for implementation specific low_level operations.
+ */
+extern struct pcmcia_low_level bcm4710_pcmcia_ops;
+
+#endif  /* !defined(_BCM4710PCMCIA_H) */
diff -bEruN linux-2.4.20-my/drivers/pcmcia/Makefile linux-2.4.20-nc/drivers/pcmcia/Makefile
--- linux-2.4.20-my/drivers/pcmcia/Makefile	2006-06-02 07:55:18.000000000 -0700
+++ linux-2.4.20-nc/drivers/pcmcia/Makefile	2006-06-02 08:21:26.000000000 -0700
@@ -74,6 +74,10 @@
 au1000_ss-objs-$(CONFIG_MIPS_HYDROGEN3)		+= au1000_hydrogen3.o
 au1000_ss-objs-$(CONFIG_MIPS_XXS1500) 		+= au1000_xxs1500.o
 
+obj-$(CONFIG_PCMCIA_BCM4710)			+= bcm4710_ss.o
+bcm4710_ss-objs					:= bcm4710_generic.o
+bcm4710_ss-objs					+= bcm4710_pcmcia.o
+
 obj-$(CONFIG_PCMCIA_SA1100)	+= sa1100_cs.o
 obj-$(CONFIG_PCMCIA_M8XX)	+= m8xx_pcmcia.o
 obj-$(CONFIG_PCMCIA_SIBYTE)	+= sibyte_generic.o
@@ -112,5 +116,8 @@
 au1x00_ss.o: $(au1000_ss-objs-y)
 	$(LD) -r -o $@ $(au1000_ss-objs-y)
 
+bcm4710_ss.o: $(bcm4710_ss-objs)
+	$(LD) -r -o $@ $(bcm4710_ss-objs)
+
 yenta_socket.o: $(yenta_socket-objs)
 	$(LD) $(LD_RFLAG) -r -o $@ $(yenta_socket-objs)
diff -bEruN linux-2.4.20-my/drivers/se/Config.in linux-2.4.20-nc/drivers/se/Config.in
--- linux-2.4.20-my/drivers/se/Config.in	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/drivers/se/Config.in	2006-06-02 08:21:26.000000000 -0700
@@ -0,0 +1,8 @@
+#
+# Broadcom Nasoc streaming encryption driver configuration
+#
+
+mainmenu_option next_comment
+comment 'Broadcom NASOC streaming encryption devices'
+   dep_tristate 'Broadcom streaming encryption device support' CONFIG_BCM_SE $CONFIG_BCM4780
+endmenu
diff -bEruN linux-2.4.20-my/drivers/se/Makefile linux-2.4.20-nc/drivers/se/Makefile
--- linux-2.4.20-my/drivers/se/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/drivers/se/Makefile	2006-06-02 08:21:26.000000000 -0700
@@ -0,0 +1,35 @@
+#
+# Makefile for the Broadcom streaming encryption device driver
+#
+# Copyright 2001-2004, Broadcom Corporation
+# All Rights Reserved.
+#
+# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+#
+
+O_TARGET	:= bcm_se.o
+
+SE_OBJS		:= se_thread.o se_change.o se.o
+
+export-objs	:=
+obj-y		:= $(SE_OBJS)
+obj-m		:= $(O_TARGET)
+
+SRCBASE		:= $(TOPDIR)/../..
+EXTRA_CFLAGS	+= -I$(SRCBASE)/linux/linux/include/linux -I$(SRCBASE)/linux/linux/include/asm
+EXTRA_CFLAGS	+= -DLINUX=1 -DMODULE -D__KERNEL__
+
+ifneq ($(wildcard $(SRCBASE)/bcmdrivers/se/*.c),)
+EXTRA_CFLAGS	+= -I$(SRCBASE)/bcmdrivers/se \
+		   -I$(SRCBASE)/include -I$(SRCBASE)/include/security \
+		   -I$(SRCBASE)/include/security/kern 
+	
+vpath %.c $(SRCBASE)/bcmdrivers/se $(SRCBASE)/shared
+else
+obj-y		:= $(foreach obj,$(SE_OBJS),$(SRCBASE)/bcmdrivers/se/linux/$(obj))
+endif
+
+include $(TOPDIR)/Rules.make
diff -bEruN linux-2.4.20-my/fs/partitions/broadcom.c linux-2.4.20-nc/fs/partitions/broadcom.c
--- linux-2.4.20-my/fs/partitions/broadcom.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/fs/partitions/broadcom.c	2006-06-02 08:21:26.000000000 -0700
@@ -0,0 +1,170 @@
+/*
+ * Broadcom NAS Kernel Partition Table Support
+ *
+ * Copyright 2003, Broadcom Corporation
+ * All Rights Reserved.
+ */
+
+
+#include "broadcom.h"
+#include <linux/pagemap.h>
+#include "check.h"
+
+extern int disk_repartition_minor_base;
+extern int disk_repartition_minor_range;
+
+
+#define BROADCOM_PARTITON_TABLE_HEADER "Broadcom NAS Version 1.1 MBR Tag"
+
+
+int broadcom_partition(struct gendisk *hd, struct block_device *bdev,
+		       unsigned long first_sector, int first_part_minor)
+{
+	unsigned char *raw_data;
+	Sector sector_info;
+	size_t byte_num;
+	size_t block_offset;
+	size_t block_num;
+
+	raw_data = read_dev_sector(bdev, 0, &sector_info);
+	if (raw_data == NULL)
+		return -1;
+	for (byte_num = 0; byte_num < sizeof(BROADCOM_PARTITON_TABLE_HEADER);
+	     ++byte_num) {
+		if (raw_data[byte_num] !=
+		    BROADCOM_PARTITON_TABLE_HEADER[byte_num]) {
+			put_dev_sector(sector_info);
+			return 0;
+		}
+	}
+	if (raw_data[100] == 0)
+		block_offset = 1;
+	else
+		block_offset = 3;
+	put_dev_sector(sector_info);
+
+	for (block_num = 0; block_num < 2; ++block_num) {
+		size_t partition_num;
+
+		raw_data = read_dev_sector(bdev, block_num + block_offset,
+					   &sector_info);
+		if (raw_data == NULL)
+			return -1;
+		for (partition_num = 0; partition_num < 32; ++partition_num) {
+			int minor_num;
+			int block_count;
+			int start_block_num;
+
+			minor_num = first_part_minor + (block_num * 32) +
+				    partition_num;
+			if ((raw_data[(partition_num * 16) + 8] != 0) ||
+			    (raw_data[(partition_num * 16) + 9] != 0) ||
+			    (raw_data[(partition_num * 16) + 10] != 0) ||
+			    (raw_data[(partition_num * 16) + 11] != 0) ||
+			    (raw_data[(partition_num * 16) + 12] >= 0x80)) {
+				printk(KERN_ERR
+					"Broadcom partition size of "
+					"0x%02lx%02lx%02lx%02lx%02lx%02lx%02lx"
+					"%02lx blocks overflows signed 32-bit "
+					"type used in the kernel for partition"
+					" sizes.\n",
+					(unsigned long)(raw_data[
+						(partition_num * 16) + 8]),
+					(unsigned long)(raw_data[
+						(partition_num * 16) + 9]),
+					(unsigned long)(raw_data[
+						(partition_num * 16) + 10]),
+					(unsigned long)(raw_data[
+						(partition_num * 16) + 11]),
+					(unsigned long)(raw_data[
+						(partition_num * 16) + 12]),
+					(unsigned long)(raw_data[
+						(partition_num * 16) + 13]),
+					(unsigned long)(raw_data[
+						(partition_num * 16) + 14]),
+					(unsigned long)(raw_data[
+						(partition_num * 16) + 15]));
+				put_dev_sector(sector_info);
+				return -1;
+			}
+			block_count =
+				((((int)(raw_data[
+					(partition_num * 16) + 12])) << 24) |
+				 (((int)(raw_data[
+					(partition_num * 16) + 13])) << 16) |
+				 (((int)(raw_data[
+					(partition_num * 16) + 14])) << 8) |
+				 (((int)(raw_data[
+					(partition_num * 16) + 15])) << 0));
+			if ((((block_num * 32) + partition_num) + 1) >=
+				disk_repartition_minor_range) {
+				if (block_count > 0) {
+					printk(KERN_ERR
+						"Broadcom partition entry %lu is non-empty but the "
+						"device only supports %lu partitions.\n",
+						(unsigned long)((block_num * 32) + partition_num),
+						(unsigned long)(disk_repartition_minor_range - 1));
+					put_dev_sector(sector_info);
+					return -1;
+				}
+				continue;
+			}
+			if (block_count == 0) {
+				if (hd->part[minor_num].nr_sects > 0) {
+					kdev_t devp = MKDEV(hd->major,
+						disk_repartition_minor_base +
+						minor_num);
+					invalidate_device(devp, 1);
+				}
+				hd->part[minor_num].start_sect = 0;
+				hd->part[minor_num].nr_sects   = 0;
+				continue;
+			}
+			if ((raw_data[(partition_num * 16) + 0] != 0) ||
+			    (raw_data[(partition_num * 16) + 1] != 0) ||
+			    (raw_data[(partition_num * 16) + 2] != 0) ||
+			    (raw_data[(partition_num * 16) + 3] != 0) ||
+			    (raw_data[(partition_num * 16) + 4] >= 0x80)) {
+				printk(KERN_ERR
+					"Broadcom partition starting block "
+					"number "
+					"0x%02lx%02lx%02lx%02lx%02lx%02lx%02lx"
+					"%02lx overflows signed 32-bit type "
+					"used in the kernel for partition "
+					"start block numbers.\n",
+					(unsigned long)(raw_data[
+						(partition_num * 16) + 0]),
+					(unsigned long)(raw_data[
+						(partition_num * 16) + 1]),
+					(unsigned long)(raw_data[
+						(partition_num * 16) + 2]),
+					(unsigned long)(raw_data[
+						(partition_num * 16) + 3]),
+					(unsigned long)(raw_data[
+						(partition_num * 16) + 4]),
+					(unsigned long)(raw_data[
+						(partition_num * 16) + 5]),
+					(unsigned long)(raw_data[
+						(partition_num * 16) + 6]),
+					(unsigned long)(raw_data[
+						(partition_num * 16) + 7]));
+				put_dev_sector(sector_info);
+				return -1;
+			}
+			start_block_num =
+				((((int)(raw_data[
+					(partition_num * 16) + 4])) << 24) |
+				 (((int)(raw_data[
+					(partition_num * 16) + 5])) << 16) |
+				 (((int)(raw_data[
+					(partition_num * 16) + 6])) << 8) |
+				 (((int)(raw_data[
+					(partition_num * 16) + 7])) << 0));
+			add_gd_partition(hd, minor_num,
+				first_sector + start_block_num, block_count);
+		}
+		put_dev_sector(sector_info);
+	}
+
+	return 1;
+}
diff -bEruN linux-2.4.20-my/fs/partitions/broadcom.h linux-2.4.20-nc/fs/partitions/broadcom.h
--- linux-2.4.20-my/fs/partitions/broadcom.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/fs/partitions/broadcom.h	2006-06-02 08:21:26.000000000 -0700
@@ -0,0 +1,18 @@
+/*
+ * Broadcom NAS Kernel Partition Table Support
+ *
+ * Copyright 2003, Broadcom Corporation
+ * All Rights Reserved.
+ */
+
+
+#ifndef BROADCOM_PARTITION_H
+#define BROADCOM_PARTITION_H
+
+#include <linux/fs.h>
+#include <linux/genhd.h>
+
+int broadcom_partition(struct gendisk *hd, struct block_device *bdev,
+		       unsigned long first_sector, int first_part_minor);
+
+#endif /* BROADCOM_PARTITION_H */
diff -bEruN linux-2.4.20-my/fs/proc/array.c linux-2.4.20-nc/fs/proc/array.c
--- linux-2.4.20-my/fs/proc/array.c	2006-06-02 07:55:18.000000000 -0700
+++ linux-2.4.20-nc/fs/proc/array.c	2006-06-02 08:21:26.000000000 -0700
@@ -514,8 +514,9 @@
 		up_read(&mm->mmap_sem);
 		mmput(mm);
 	}
-	return sprintf(buffer,"%d %d %d %d %d %d %d\n",
-		       size, resident, share, trs, lrs, drs, dt);
+	return sprintf(buffer,"%d %d %d %d %d %d %d %lu\n",
+		       size, resident, share, trs, lrs, drs, dt,
+		       mm ? mm->brk - mm->start_brk : 0);
 }
 
 static int show_map(struct seq_file *m, void *v)
diff -bEruN linux-2.4.20-my/include/asm-mips/bootinfo.h linux-2.4.20-nc/include/asm-mips/bootinfo.h
--- linux-2.4.20-my/include/asm-mips/bootinfo.h	2006-06-02 07:55:18.000000000 -0700
+++ linux-2.4.20-nc/include/asm-mips/bootinfo.h	2006-06-02 08:21:26.000000000 -0700
@@ -37,6 +37,7 @@
 #define MACH_GROUP_HP_LJ       20 /* Hewlett Packard LaserJet               */
 #define MACH_GROUP_LASAT       21
 #define MACH_GROUP_TITAN       22 /* PMC-Sierra Titan 			    */
+#define MACH_GROUP_BRCM        22 /* Broadcom */
 
 /*
  * Valid machtype values for group unknown (low order halfword of mips_machtype)
@@ -193,8 +194,15 @@
 #define MACH_VICTOR_MPC30X	3	/* Victor MP-C303/304 */
 #define MACH_IBM_WORKPAD	4	/* IBM WorkPad z50 */
 #define MACH_CASIO_E55		5	/* CASIO CASSIOPEIA E-10/15/55/65 */
-#define MACH_TANBAC_TB0226	6	/* TANBAC TB0226 (MBASE) */
-#define MACH_TANBAC_TB0229	7	/* TANBAC TB0229 (VR4131DIMM) */
+
+/*
+ * Valid machtypes for group Broadcom
+ */
+#define MACH_BCM93725		0
+#define MACH_BCM93725_VJ	1
+#define MACH_BCM93730		2
+#define MACH_BCM947XX		3
+#define MACH_BCM933XX		4
 
 /*
  * Valid machtype for group TITAN
diff -bEruN linux-2.4.20-my/include/asm-mips/cpu.h linux-2.4.20-nc/include/asm-mips/cpu.h
--- linux-2.4.20-my/include/asm-mips/cpu.h	2005-11-08 06:24:49.000000000 -0800
+++ linux-2.4.20-nc/include/asm-mips/cpu.h	2006-06-02 08:21:26.000000000 -0700
@@ -22,6 +22,11 @@
    spec.
 */
 
+#define PRID_COPT_MASK         0xff000000
+#define PRID_COMP_MASK         0x00ff0000
+#define PRID_IMP_MASK          0x0000ff00
+#define PRID_REV_MASK          0x000000ff
+
 #define PRID_COMP_LEGACY       0x000000
 #define PRID_COMP_MIPS         0x010000
 #define PRID_COMP_BROADCOM     0x020000
@@ -67,9 +72,16 @@
 #define PRID_IMP_4KSC		0x8600
 #define PRID_IMP_25KF		0x8800
 #define PRID_IMP_24K		0x9300
+#define PRID_IMP_BCM4710	0x4000
+#define PRID_IMP_BCM3302	0x9000
+#define PRID_IMP_BCM3303	0x9100
 
 #define PRID_IMP_UNKNOWN	0xff00
 
+#define       BCM330X(id) \
+	(((id & (PRID_COMP_MASK | PRID_IMP_MASK)) == (PRID_COMP_BROADCOM | PRID_IMP_BCM3302)) \
+	|| ((id & (PRID_COMP_MASK | PRID_IMP_MASK)) == (PRID_COMP_BROADCOM | PRID_IMP_BCM3303)))
+
 /*
  * These are the PRID's for when 23:16 == PRID_COMP_SIBYTE
  */
@@ -174,7 +186,9 @@
 #define CPU_AU1550		57
 #define CPU_24K			58
 #define CPU_AU1200		59
+#define CPU_BCM4710		60
+#define CPU_BCM3302		61
-#define CPU_LAST		59
+#define CPU_LAST		61
 
 /*
  * ISA Level encodings
diff -bEruN linux-2.4.20-my/include/asm-mips/mipsregs.h linux-2.4.20-nc/include/asm-mips/mipsregs.h
--- linux-2.4.20-my/include/asm-mips/mipsregs.h	2006-06-02 07:55:18.000000000 -0700
+++ linux-2.4.20-nc/include/asm-mips/mipsregs.h	2006-06-02 08:21:26.000000000 -0700
@@ -467,6 +467,75 @@
 #define MIPS_CONF_AT		(_ULCAST_(3) << 13)
 #define MIPS_CONF_M		(_ULCAST_(1) << 31)
 
+/* mips32/64 definitions for CP0 config register */
+#define	CONF_MT_MASK			0x00000380		/* MMU Type */
+#define	CONF_MT_NONE			0x00000000		/* No mmu */
+#define	CONF_MT_TLB			0x00000080		/* TLB present */
+#define	CONF_MT_BAT			0x00000100		/* Block address translation */
+#define	CONF_MT_FM			0x00000180		/* Fixed map (Like 4Kp/4Km) */
+#define	CONF_AR_MASK			0x00001c00		/* Architecture revision */
+#define	CONF_AT_MASK			0x00006000		/* Architecture type */
+#define	CONF_AT_M32			0x00000000		/* mips32 */
+#define	CONF_AT_M6432			0x00002000		/* mips64/mips32?? */
+#define	CONF_AT_M64			0x00004000		/* mips64 */
+#define	CONF_BE				0x00008000		/* BigEndian */
+#define	CONF_BM				0x00010000		/* Burst Mode */
+#define	CONF_BM_SEQ			0x00000000		/* Sequential */
+#define	CONF_BM_SB			0x00010000		/* SubBlock */
+#define	CONF_MM_MASK			0x00060000		/* Merge Mode */
+#define	CONF_MM_NONE			0x00000000		/* No merging */
+#define	CONF_MM_SYSAD			0x00020000		/* SysAD merging */
+#define	CONF_MM_FULL			0x00040000		/* Full merging */
+#define	CONF_MDU			0x00100000		/* Slow MDU */
+#define	CONF_KU_MASK			0x0e000000		/* Kuseg and useg cacheability (for MT=FM) */
+#define	CONF_K23_MASK			0x70000000		/* Kseg2 and Kseg3 cacheability (for MT=FM) */
+#define	CONF_M				0x80000000		/* config1 register present */
+
+/* mips32/64 definitions for CP0 config1 register */
+#define CONF1_FP			0x00000001		/* FPU present */
+#define CONF1_EP			0x00000002		/* EJTAG present */
+#define CONF1_CA			0x00000004		/* Code compression (mips16) implemented */
+#define CONF1_WR			0x00000008		/* Watch registers present */
+#define CONF1_PC			0x00000010		/* Performance counters present */
+#define	CONF1_DA_SHIFT			7			/* Data cache associativity */
+#define CONF1_DA_MASK			0x00000380
+#define CONF1_DA_BASE			1
+#define CONF1_DA_DM			0x00000000		/*	Direct mapped */
+#define CONF1_DA_2W			0x00000080		/*	2-way */
+#define CONF1_DA_3W			0x00000100		/*	3-way */
+#define CONF1_DA_4W			0x00000180		/*	4-way */
+#define CONF1_DL_SHIFT			10			/* Data cache line size */
+#define CONF1_DL_MASK			0x00001c00
+#define CONF1_DL_BASE			2
+#define CONF1_DL_NONE			0x00000000		/*	No data cache present */
+#define CONF1_DL_16			0x00000c00		/*	16 bytes */
+#define CONF1_DS_SHIFT			13			/* Data cache sets/way */
+#define CONF1_DS_MASK			0x0000e000
+#define CONF1_DS_BASE			64
+#define CONF1_DS_64			0x00000000		/*	64 sets */
+#define CONF1_DS_128			0x00002000		/*	128 sets */
+#define CONF1_DS_256			0x00004000		/*	256 sets */
+#define CONF1_IA_SHIFT			16			/* Instruction cache associativity */
+#define CONF1_IA_MASK			0x00070000
+#define CONF1_IA_BASE			1
+#define CONF1_IA_DM			0x00000000		/*	Direct mapped */
+#define CONF1_IA_2W			0x00010000		/*	2-way */
+#define CONF1_IA_3W			0x00020000		/*	3-way */
+#define CONF1_IA_4W			0x00030000		/*	4-way */
+#define CONF1_IL_SHIFT			19			/* Instruction cache line size */
+#define CONF1_IL_MASK			0x00380000
+#define CONF1_IL_BASE			2
+#define CONF1_IL_NONE			0x00000000		/*	No data cache present */
+#define CONF1_IL_16			0x00180000		/*	16 bytes */
+#define CONF1_IS_SHIFT			22			/* Instruction cache sets/way */
+#define CONF1_IS_MASK			0x01c00000
+#define CONF1_IS_BASE			64
+#define CONF1_IS_64			0x00000000		/*	64 sets */
+#define CONF1_IS_128			0x00400000		/*	128 sets */
+#define CONF1_IS_256			0x00800000		/*	256 sets */
+#define CONF1_MS_MASK			0x7e000000		/* Number of tlb entries */
+#define CONF1_MS_SHIFT			25
+
 /*
  * R10000 performance counter definitions.
  *
@@ -958,6 +1027,14 @@
 __BUILD_SET_C0(config)
 __BUILD_SET_C0(intcontrol)
 
+/*
+ * Functions to access the performance counter and control registers
+ */
+extern asmlinkage unsigned int read_perf_cntr(unsigned int counter);
+extern asmlinkage void write_perf_cntr(unsigned int counter, unsigned int val);
+extern asmlinkage unsigned int read_perf_cntl(unsigned int counter);
+extern asmlinkage void write_perf_cntl(unsigned int counter, unsigned int val);
+
 #endif /* !__ASSEMBLY__ */
 
 #endif /* _ASM_MIPSREGS_H */
diff -x .depend -x '.*.flags' -ruN linux-2.4.32-tst2/include/asm-mips/ptrace.h linux-2.4.32-tst3/include/asm-mips/ptrace.h
--- linux-2.4.32-tst2/include/asm-mips/ptrace.h	2006-06-22 16:11:14.000000000 -0700
+++ linux-2.4.32-tst3/include/asm-mips/ptrace.h	2006-05-19 14:34:54.000000000 -0700
@@ -4,6 +4,7 @@
  * for more details.
  *
  * Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000 by Ralf Baechle
+ * Copyright (C) 2004  Maciej W. Rozycki
  *
  * Machine dependent structs and defines to help the user use
  * the ptrace system call.
@@ -64,12 +65,10 @@
         "sw\t$22,"__str(PT_R22)"($29)\n\t"                              \
         "sw\t$23,"__str(PT_R23)"($29)\n\t"                              \
         "sw\t$30,"__str(PT_R30)"($29)\n\t"                              \
+       "j\t_" #symbol "\n\t"                                           \
         ".end\t" #symbol "\n\t"                                         \
         ".size\t" #symbol",. - " #symbol)
 
-/* Used in declaration of save_static functions.  */
-#define static_unused static __attribute__((unused))
-
 #endif /* !__ASSEMBLY__ */
 
 /* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
diff -x .depend -x '.*.flags' -ruN linux-2.4.32-tst2/include/asm-mips/signal.h linux-2.4.32-tst3/include/asm-mips/signal.h
--- linux-2.4.32-tst2/include/asm-mips/signal.h	2006-06-22 16:11:14.000000000 -0700
+++ linux-2.4.32-tst3/include/asm-mips/signal.h	2006-05-18 18:19:25.000000000 -0700
@@ -111,6 +111,12 @@
 #define SA_SAMPLE_RANDOM	SA_RESTART
 #define SA_SHIRQ		0x02000000
 
+#ifdef CONFIG_NET_RANDOM
+#define SA_NET_RANDOM	SA_SAMPLE_RANDOM
+#else
+#define SA_NET_RANDOM	0
+#endif
+
 #endif /* __KERNEL__ */
 
 #define SIG_BLOCK	1	/* for blocking signals */
diff -x .depend -x '.*.flags' -ruN linux-2.4.32-tst2/include/asm-mips/timex.h linux-2.4.32-tst3/include/asm-mips/timex.h
--- linux-2.4.32-tst2/include/asm-mips/timex.h	2006-06-22 16:11:14.000000000 -0700
+++ linux-2.4.32-tst3/include/asm-mips/timex.h	2006-05-18 18:19:25.000000000 -0700
@@ -31,6 +31,19 @@
 	return read_c0_count();
 }
 
+extern __u32 get_htscl(void);
+extern __u64 get_tscll(void);
+
+#define rdtsc(low, high) \
+		high = get_htscl(); \
+		low = read_c0_count();
+
+#define rdtscl(low) \
+		low = read_c0_count();
+
+#define rdtscll(val) \
+		val = get_tscll();
+
 #define vxtime_lock()		do {} while (0)
 #define vxtime_unlock()		do {} while (0)
 
diff -x .depend -x '.*.flags' -ruN linux-2.4.32-tst2/include/asm-mips/uaccess.h linux-2.4.32-tst3/include/asm-mips/uaccess.h
--- linux-2.4.32-tst2/include/asm-mips/uaccess.h	2006-06-22 16:11:14.000000000 -0700
+++ linux-2.4.32-tst3/include/asm-mips/uaccess.h	2006-05-19 14:34:54.000000000 -0700
@@ -149,7 +149,7 @@
  * Returns zero on success, or -EFAULT on error.
  */
 #define put_user(x,ptr)	\
-	__put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
+	__put_user_check((x),(ptr),sizeof(*(ptr)))
 
 /*
  * get_user: - Get a simple variable from user space.
@@ -169,7 +169,7 @@
  * On error, the variable @x is set to zero.
  */
 #define get_user(x,ptr) \
-	__get_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
+	__get_user_check((x),(ptr),sizeof(*(ptr)))
 
 /*
  * __put_user: - Write a simple value into user space, with less checking.
@@ -191,7 +191,7 @@
  * Returns zero on success, or -EFAULT on error.
  */
 #define __put_user(x,ptr) \
-	__put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
+	__put_user_nocheck((x),(ptr),sizeof(*(ptr)))
 
 /*
  * __get_user: - Get a simple variable from user space, with less checking.
@@ -214,7 +214,7 @@
  * On error, the variable @x is set to zero.
  */
 #define __get_user(x,ptr) \
-	__get_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
+	__get_user_nocheck((x),(ptr),sizeof(*(ptr)))
 
 struct __large_struct { unsigned long buf[100]; };
 #define __m(x) (*(struct __large_struct *)(x))
@@ -232,7 +232,7 @@
 #define __get_user_nocheck(x,ptr,size)					\
 ({									\
 	long __gu_err = 0;						\
-	__typeof(*(ptr)) __gu_val = 0;					\
+	__typeof(*(ptr)) __gu_val = (__typeof(*(ptr))) 0;					\
 	long __gu_addr;							\
 	__gu_addr = (long) (ptr);					\
 	switch (size) {							\
diff -bEruN linux-2.4.20-my/include/asm-mips/serial.h linux-2.4.20-nc/include/asm-mips/serial.h
--- linux-2.4.20-my/include/asm-mips/serial.h	2006-06-02 07:55:18.000000000 -0700
+++ linux-2.4.20-nc/include/asm-mips/serial.h	2006-06-02 08:21:26.000000000 -0700
@@ -223,6 +223,13 @@
 #define TXX927_SERIAL_PORT_DEFNS
 #endif
 
+#ifdef CONFIG_BCM947XX
+/* reserve 4 ports to be configured at runtime */
+#define BCM947XX_SERIAL_PORT_DEFNS { 0, }, { 0, }, { 0, }, { 0, },
+#else
+#define BCM947XX_SERIAL_PORT_DEFNS
+#endif
+
 #ifdef CONFIG_HAVE_STD_PC_SERIAL_PORT
 #define STD_SERIAL_PORT_DEFNS			\
 	/* UART CLK   PORT IRQ     FLAGS        */			\
@@ -468,6 +475,7 @@
 #endif
 
 #define SERIAL_PORT_DFNS			\
+	BCM947XX_SERIAL_PORT_DEFNS           	\
 	ATLAS_SERIAL_PORT_DEFNS			\
 	AU1000_SERIAL_PORT_DEFNS		\
	COBALT_SERIAL_PORT_DEFNS		\
diff -bEruN linux-2.4.20-my/include/linux/major.h linux-2.4.20-nc/include/linux/major.h
--- linux-2.4.20-my/include/linux/major.h	2006-06-02 08:00:41.000000000 -0700
+++ linux-2.4.20-nc/include/linux/major.h	2006-06-02 08:21:26.000000000 -0700
@@ -138,6 +138,7 @@
 #define JSFD_MAJOR	99
 
 #define PHONE_MAJOR	100
+#define FLASH_MAJOR     101
 
 #define LVM_CHAR_MAJOR	109	/* Logical Volume Manager */
 
diff -bEruN linux-2.4.20-my/include/linux/sockios.h linux-2.4.20-nc/include/linux/sockios.h
--- linux-2.4.20-my/include/linux/sockios.h	2001-11-07 14:39:36.000000000 -0800
+++ linux-2.4.20-nc/include/linux/sockios.h	2006-06-02 08:21:26.000000000 -0700
@@ -134,4 +134,7 @@
  */
  
 #define SIOCPROTOPRIVATE 0x89E0 /* to 89EF */
+
+#define SIOCGIFSTATS	SIOCDEVPRIVATE+3 /* get device statistics */
+
 #endif	/* _LINUX_SOCKIOS_H */
diff -bEruN linux-2.4.20-my/init/do_mounts.c linux-2.4.20-nc/init/do_mounts.c
--- linux-2.4.20-my/init/do_mounts.c	2006-06-02 08:07:24.000000000 -0700
+++ linux-2.4.20-nc/init/do_mounts.c	2006-06-02 08:21:26.000000000 -0700
@@ -254,7 +254,16 @@
 	{ "ftlb", 0x2c08 },
 	{ "ftlc", 0x2c10 },
 	{ "ftld", 0x2c18 },
+#if defined(CONFIG_MTD_BLOCK) || defined(CONFIG_MTD_BLOCK_RO)
 	{ "mtdblock", 0x1f00 },
+        { "mtdblock0",0x1f00 },
+        { "mtdblock1",0x1f01 },
+        { "mtdblock2",0x1f02 },
+        { "mtdblock3",0x1f03 },
+#endif
+#ifdef CONFIG_BLK_DEV_DUMMY
+	{ "dummy",0x2000 },
+#endif
 	{ "nb", 0x2b00 },
 	{ NULL, 0 }
 };
@@ -521,6 +530,13 @@
 		goto done;
 	}
 
+#ifdef CONFIG_BLK_DEV_INITRD
+	/*
+	 * Fallback if size cannot be determined by superblock
+	 */
+	nblocks = (initrd_end-initrd_start+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS;
+#endif
+
 	/* romfs is at block zero too */
 	if (romfsb->word0 == ROMSB_WORD0 &&
 	    romfsb->word1 == ROMSB_WORD1) {
@@ -710,6 +726,17 @@
 		change_floppy("root floppy disk to be loaded into RAM disk");
 	create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, n), NULL);
 #endif
+#if defined(CONFIG_MTD_BLOCK) || defined(CONFIG_MTD_BLOCK_RO)
+	if (MAJOR(ROOT_DEV) == 31) {
+		/* rd_doload is for a ramload setup */
+		if (rd_doload) {
+			if (rd_load_disk(0)) {
+				ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
+				create_dev("/dev/root", ROOT_DEV, NULL);
+			}
+		}
+	}
+#endif
 	return rd_load_image("/dev/root");
 }
 
diff -bEruN linux-2.4.20-my/init/main.c linux-2.4.20-nc/init/main.c
--- linux-2.4.20-my/init/main.c	2006-06-02 08:00:41.000000000 -0700
+++ linux-2.4.20-nc/init/main.c	2006-06-02 08:21:26.000000000 -0700
@@ -158,6 +158,10 @@
 	return 0;
 }
 
+#if defined(CONFIG_BCM947XX) && defined(CONFIG_HWSIM)
+#include <asm/time.h>
+#endif
+
 /* this should be approx 2 Bo*oMips to start (note initial shift), and will
    still work even if initially too large, it will just take slightly longer */
 unsigned long loops_per_jiffy = (1<<12);
@@ -175,6 +179,11 @@
 	loops_per_jiffy = (1<<12);
 
 	printk("Calibrating delay loop... ");
+
+#if defined(CONFIG_BCM947XX) && defined(CONFIG_HWSIM)
+	loops_per_jiffy = 10 * (mips_hpt_frequency / 1000);
+#else
+
 	while (loops_per_jiffy <<= 1) {
 		/* wait for "start of" clock tick */
 		ticks = jiffies;
@@ -201,6 +210,7 @@
 		if (jiffies != ticks)	/* longer than 1 tick */
 			loops_per_jiffy &= ~loopbit;
 	}
+#endif
 
 /* Round the value and print it */	
 	printk("%lu.%02lu BogoMIPS\n",
@@ -565,7 +575,9 @@
 	lock_kernel();
 	do_basic_setup();
 
+#ifndef CONFIG_NOROOT
 	prepare_namespace();
+#endif
 
 	/*
 	 * Ok, we have completed the initial bootup, and
@@ -575,6 +587,13 @@
 	free_initmem();
 	unlock_kernel();
 	
+#ifdef CONFIG_NOROOT
+	for (;;) {
+		DECLARE_WAIT_QUEUE_HEAD(wait);
+		sleep_on(&wait);
+	}
+#endif
+
 	/*
 	 * Right now we are a thread sharing with a ton of kernel
 	 * stuff. We don't want to end up in user space in that state
diff -bEruN linux-2.4.20-my/kernel/printk.c linux-2.4.20-nc/kernel/printk.c
--- linux-2.4.20-my/kernel/printk.c	2006-06-02 07:55:19.000000000 -0700
+++ linux-2.4.20-nc/kernel/printk.c	2006-06-02 08:21:26.000000000 -0700
@@ -46,8 +46,12 @@
 #define LOG_BUF_MASK	(LOG_BUF_LEN-1)
 
 #ifndef arch_consoles_callable
+#if defined(CONFIG_HWSIM) && defined(mips)
+#define arch_consoles_callable() (0)
+#else
 #define arch_consoles_callable() (1)
 #endif
+#endif
 
 /* printk's without a loglevel use this.. */
 #define DEFAULT_MESSAGE_LOGLEVEL 4 /* KERN_WARNING */
@@ -82,7 +86,8 @@
  */
 static spinlock_t logbuf_lock = SPIN_LOCK_UNLOCKED;
 
-static char log_buf[LOG_BUF_LEN];
+static char real_log_buf[LOG_BUF_LEN];
+static char *log_buf = real_log_buf;
 #define LOG_BUF(idx) (log_buf[(idx) & LOG_BUF_MASK])
 
 /*
@@ -418,6 +423,11 @@
 	static char printk_buf[1024];
 	static int log_level_unknown = 1;
 
+#if defined(CONFIG_HWSIM) && defined(mips)
+	if (log_buf == real_log_buf)
+		log_buf = KSEG1ADDR((char *) real_log_buf);
+#endif
+
 	if (oops_in_progress) {
 		/* If a crash is occurring, make sure we can't deadlock */
 		spin_lock_init(&logbuf_lock);
diff -bEruN linux-2.4.20-my/Makefile linux-2.4.20-nc/Makefile
--- linux-2.4.20-my/Makefile	2006-06-02 08:08:54.000000000 -0700
+++ linux-2.4.20-nc/Makefile	2006-06-02 08:21:25.000000000 -0700
@@ -99,6 +99,14 @@
 endif
 AFLAGS := -D__ASSEMBLY__ $(CPPFLAGS)
 
+# Broadcom HWNBU source tree
+export SRCBASE := $(TOPDIR)/../..
+CFLAGS += -I$(SRCBASE)/include
+AFLAGS += -I$(SRCBASE)/include
+ASFLAGS += -I$(SRCBASE)/include
+
+CFLAGS += -DBCMDRIVER
+
 #
 # ROOT_DEV specifies the default root-device when making the image.
 # This can be either FLOPPY, CURRENT, /dev/xxxx or empty, in which case
diff -bEruN linux-2.4.20-my/mm/bootmem.c linux-2.4.20-nc/mm/bootmem.c
--- linux-2.4.20-my/mm/bootmem.c	2005-11-08 06:24:53.000000000 -0800
+++ linux-2.4.20-nc/mm/bootmem.c	2006-06-02 08:21:26.000000000 -0700
@@ -57,11 +57,13 @@
 	bdata->node_boot_start = (start << PAGE_SHIFT);
 	bdata->node_low_pfn = end;
 
+#if	!defined(CONFIG_HWSIM) || defined(CONFIG_HWSIM_ZMEM)
 	/*
 	 * Initially all pages are reserved - setup_arch() has to
 	 * register free RAM areas explicitly.
 	 */
 	memset(bdata->node_bootmem_map, 0xff, mapsize);
+#endif
 
 	return mapsize;
 }
@@ -238,7 +240,9 @@
 	for (i = start; i < start+areasize; i++)
 		if (test_and_set_bit(i, bdata->node_bootmem_map))
 			BUG();
+#ifndef CONFIG_HWSIM
 	memset(ret, 0, size);
+#endif
 	return ret;
 }
 
diff -bEruN linux-2.4.20-my/net/bridge/br_device.c linux-2.4.20-nc/net/bridge/br_device.c
--- linux-2.4.20-my/net/bridge/br_device.c	2002-02-25 11:38:14.000000000 -0800
+++ linux-2.4.20-nc/net/bridge/br_device.c	2006-06-02 08:21:26.000000000 -0700
@@ -121,6 +121,25 @@
 	return -1;
 }
 
+extern void br_stp_change_bridge_id(struct net_bridge *br, unsigned char *addr);
+
+static int
+br_set_mac_address(struct net_device *dev, void *addr)
+{
+	struct net_bridge *br = dev->priv;
+	struct sockaddr *sa = (struct sockaddr *) addr;
+	
+	write_lock_bh(&br->lock);
+
+	memcpy(br->preferred_id.addr, sa->sa_data, ETH_ALEN);
+
+	br_stp_recalculate_bridge_id(br);
+
+	write_unlock_bh(&br->lock);
+
+	return 0;
+}
+
 void br_dev_setup(struct net_device *dev)
 {
 	memset(dev->dev_addr, 0, ETH_ALEN);
@@ -133,5 +152,5 @@
 	dev->stop = br_dev_stop;
 	dev->accept_fastpath = br_dev_accept_fastpath;
 	dev->tx_queue_len = 0;
-	dev->set_mac_address = NULL;
+	dev->set_mac_address = br_set_mac_address;
 }
diff -bEruN linux-2.4.20-my/net/bridge/br_fdb.c linux-2.4.20-nc/net/bridge/br_fdb.c
--- linux-2.4.20-my/net/bridge/br_fdb.c	2002-02-25 11:38:14.000000000 -0800
+++ linux-2.4.20-nc/net/bridge/br_fdb.c	2006-06-02 08:21:26.000000000 -0700
@@ -290,6 +290,7 @@
 	hash = br_mac_hash(addr);
 
 	write_lock_bh(&br->hash_lock);
+	if (!is_local) {
 	fdb = br->hash[hash];
 	while (fdb != NULL) {
 		if (!memcmp(fdb->addr.addr, addr, ETH_ALEN)) {
@@ -312,6 +313,7 @@
 
 		fdb = fdb->next_hash;
 	}
+	}
 
 	fdb = kmalloc(sizeof(*fdb), GFP_ATOMIC);
 	if (fdb == NULL) 
diff -bEruN linux-2.4.20-my/net/bridge/br_private.h linux-2.4.20-nc/net/bridge/br_private.h
--- linux-2.4.20-my/net/bridge/br_private.h	2002-02-25 11:38:14.000000000 -0800
+++ linux-2.4.20-nc/net/bridge/br_private.h	2006-06-02 08:21:26.000000000 -0700
@@ -95,6 +95,7 @@
 	int				hello_time;
 	int				forward_delay;
 	bridge_id			bridge_id;
+	bridge_id			preferred_id;
 	int				bridge_max_age;
 	int				bridge_hello_time;
 	int				bridge_forward_delay;
diff -bEruN linux-2.4.20-my/net/bridge/br_stp_if.c linux-2.4.20-nc/net/bridge/br_stp_if.c
--- linux-2.4.20-my/net/bridge/br_stp_if.c	2001-04-19 08:38:50.000000000 -0700
+++ linux-2.4.20-nc/net/bridge/br_stp_if.c	2006-06-02 08:21:26.000000000 -0700
@@ -162,6 +162,12 @@
 
 	p = br->port_list;
 	while (p != NULL) {
+		/* match against preferred address first */
+		if (memcmp(p->dev->dev_addr, br->preferred_id.addr, ETH_ALEN) == 0) {
+			addr = p->dev->dev_addr;
+			break;
+		}
+
 		if (addr == br_mac_zero ||
 		    memcmp(p->dev->dev_addr, addr, ETH_ALEN) < 0)
 			addr = p->dev->dev_addr;
diff -bEruN linux-2.4.20-my/net/core/dev.c linux-2.4.20-nc/net/core/dev.c
--- linux-2.4.20-my/net/core/dev.c	2005-11-08 06:24:53.000000000 -0800
+++ linux-2.4.20-nc/net/core/dev.c	2006-06-02 08:21:26.000000000 -0700
@@ -108,6 +108,7 @@
 extern int plip_init(void);
 #endif
 
+#include <cy_conf.h>
 
 /* This define, if set, will randomly drop a packet when congestion
  * is more than moderate.  It helps fairness in the multi-interface
@@ -2053,6 +2054,7 @@
 {
 	struct net_device *dev;
 	int err;
+	struct net_device_stats *stats;
 
 	if ((dev = __dev_get_by_name(ifr->ifr_name)) == NULL)
 		return -ENODEV;
@@ -2167,6 +2169,16 @@
 			ifr->ifr_ifindex = dev->ifindex;
 			return 0;
 
+#ifdef PERFORMANCE_SUPPORT			
+		case SIOCGIFSTATS:
+			if (!dev->get_stats || !(stats = dev->get_stats(dev)))
+				return -ENODEV;
+			if (copy_to_user(ifr->ifr_data, stats, 
+			    sizeof(struct net_device_stats)))
+				return -EFAULT;
+			return 0;
+#endif
+			
 		case SIOCGIFTXQLEN:
 			ifr->ifr_qlen = dev->tx_queue_len;
 			return 0;
diff -bEruN linux-2.4.20-my/net/core/Makefile linux-2.4.20-nc/net/core/Makefile
--- linux-2.4.20-my/net/core/Makefile	2005-11-08 06:24:06.000000000 -0800
+++ linux-2.4.20-nc/net/core/Makefile	2006-06-02 08:21:26.000000000 -0700
@@ -7,6 +7,8 @@
 #
 # Note 2! The CFLAGS definition is now in the main makefile...
 
+SRCBASE	:= $(TOPDIR)/../..
+EXTRA_CFLAGS	+= -Wall -I$(SRCBASE)/
 O_TARGET := core.o
 
 export-objs := netfilter.o profile.o ethtool.o neighbour.o
diff -bEruN linux-2.4.20-my/net/ipv4/ipconfig.c linux-2.4.20-nc/net/ipv4/ipconfig.c
--- linux-2.4.20-my/net/ipv4/ipconfig.c	2005-11-08 06:24:53.000000000 -0800
+++ linux-2.4.20-nc/net/ipv4/ipconfig.c	2006-06-02 08:21:26.000000000 -0700
@@ -933,6 +933,7 @@
 	/* We have a winner! */
 	ic_dev = dev;
 	ic_myaddr = b->your_ip;
+	if (ic_servaddr == INADDR_NONE)
 	ic_servaddr = b->server_ip;
 	if (ic_gateway == INADDR_NONE && b->relay_ip)
 		ic_gateway = b->relay_ip;
diff -bEruN linux-2.4.20-my/net/ipv4/ipmr.c linux-2.4.20-nc/net/ipv4/ipmr.c
--- linux-2.4.20-my/net/ipv4/ipmr.c	2005-11-08 06:24:53.000000000 -0800
+++ linux-2.4.20-nc/net/ipv4/ipmr.c	2006-06-02 08:21:26.000000000 -0700
@@ -452,11 +452,13 @@
 
 static struct mfc_cache *ipmr_cache_find(__u32 origin, __u32 mcastgrp)
 {
-	int line=MFC_HASH(mcastgrp,origin);
 	struct mfc_cache *c;
+	int line;
+	
+	line = MFC_HASH(mcastgrp,0);
 
 	for (c=mfc_cache_array[line]; c; c = c->next) {
-		if (c->mfc_origin==origin && c->mfc_mcastgrp==mcastgrp)
+		if (c->mfc_mcastgrp==mcastgrp)
 			break;
 	}
 	return c;
@@ -683,7 +685,7 @@
 	int line;
 	struct mfc_cache *c, **cp;
 
-	line=MFC_HASH(mfc->mfcc_mcastgrp.s_addr, mfc->mfcc_origin.s_addr);
+	line=MFC_HASH(mfc->mfcc_mcastgrp.s_addr, 0);
 
 	for (cp=&mfc_cache_array[line]; (c=*cp) != NULL; cp = &c->next) {
 		if (c->mfc_origin == mfc->mfcc_origin.s_addr &&
@@ -704,7 +706,7 @@
 	int line;
 	struct mfc_cache *uc, *c, **cp;
 
-	line=MFC_HASH(mfc->mfcc_mcastgrp.s_addr, mfc->mfcc_origin.s_addr);
+	line=MFC_HASH(mfc->mfcc_mcastgrp.s_addr, 0);
 
 	for (cp=&mfc_cache_array[line]; (c=*cp) != NULL; cp = &c->next) {
 		if (c->mfc_origin == mfc->mfcc_origin.s_addr &&
diff -bEruN linux-2.4.20-my/net/netsyms.c linux-2.4.20-nc/net/netsyms.c
--- linux-2.4.20-my/net/netsyms.c	2005-11-08 06:24:54.000000000 -0800
+++ linux-2.4.20-nc/net/netsyms.c	2006-06-02 08:21:26.000000000 -0700
@@ -453,20 +453,12 @@
 EXPORT_SYMBOL(neigh_add);
 EXPORT_SYMBOL(neigh_dump_info);
 
-EXPORT_SYMBOL(dev_set_allmulti);
-EXPORT_SYMBOL(dev_set_promiscuity);
-EXPORT_SYMBOL(sklist_remove_socket);
-EXPORT_SYMBOL(rtnl_sem);
-EXPORT_SYMBOL(rtnl_lock);
-EXPORT_SYMBOL(rtnl_unlock);
-
 /* ABI emulation layers need this */
 EXPORT_SYMBOL(move_addr_to_kernel);
 EXPORT_SYMBOL(move_addr_to_user);
                   
 /* Used by at least ipip.c.  */
 EXPORT_SYMBOL(ipv4_config);
-EXPORT_SYMBOL(dev_open);
 
 /* Used by other modules */
 EXPORT_SYMBOL(xrlim_allow);
@@ -481,6 +469,14 @@
 
 #endif  /* CONFIG_INET */
 
+EXPORT_SYMBOL(dev_open);
+EXPORT_SYMBOL(dev_set_allmulti);
+EXPORT_SYMBOL(dev_set_promiscuity);
+EXPORT_SYMBOL(sklist_remove_socket);
+EXPORT_SYMBOL(rtnl_sem);
+EXPORT_SYMBOL(rtnl_lock);
+EXPORT_SYMBOL(rtnl_unlock);
+
 #ifdef CONFIG_TR
 EXPORT_SYMBOL(tr_type_trans);
 #endif
diff -bEruN linux-2.4.20-my/Rules.make linux-2.4.20-nc/Rules.make
--- linux-2.4.20-my/Rules.make	2005-11-08 06:23:46.000000000 -0800
+++ linux-2.4.20-nc/Rules.make	2006-06-02 08:21:25.000000000 -0700
@@ -176,7 +176,14 @@
 _modinst__: dummy
 ifneq "$(strip $(ALL_MOBJS))" ""
 	mkdir -p $(MODLIB)/kernel/$(MOD_DESTDIR)
-	cp $(sort $(ALL_MOBJS)) $(MODLIB)/kernel/$(MOD_DESTDIR)
+#	cp $(sort $(ALL_MOBJS)) $(MODLIB)/kernel/$(MOD_DESTDIR)
+	for f in $(ALL_MOBJS) ; do \
+	    $(OBJCOPY) -R __ksymtab -R .comment -R .note -x \
+	    `$(NM) $$f | cut -f3- -d' ' | sed -n \
+	    -e 's/__module_parm_\(.*\)/-K \1/p' \
+	    -e 's/__ks..tab_\(.*\)/-K \1/p'` \
+	    $$f $(MODLIB)/kernel/$(MOD_DESTDIR)$(MOD_TARGET)$$f ; \
+	done
 endif
 
 .PHONY: modules_install
