diff options
| author | wbx <wbx@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2005-11-29 01:37:34 +0000 | 
|---|---|---|
| committer | wbx <wbx@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2005-11-29 01:37:34 +0000 | 
| commit | da11d2dbd449cab5448d1c2abf89b36b68f3d477 (patch) | |
| tree | f0b73db6c90cd6a83fee7eb42b263d76cc406287 /target/linux/linux-2.6/patches/brcm/002-flash-map.patch | |
| parent | 032044d7584d018a6762c69289e07e51252f88dc (diff) | |
add new flash map driver, some minor system code cleanup
git-svn-id: svn://svn.openwrt.org/openwrt/trunk/openwrt@2564 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/linux-2.6/patches/brcm/002-flash-map.patch')
| -rw-r--r-- | target/linux/linux-2.6/patches/brcm/002-flash-map.patch | 360 | 
1 files changed, 360 insertions, 0 deletions
diff --git a/target/linux/linux-2.6/patches/brcm/002-flash-map.patch b/target/linux/linux-2.6/patches/brcm/002-flash-map.patch new file mode 100644 index 000000000..406255b64 --- /dev/null +++ b/target/linux/linux-2.6/patches/brcm/002-flash-map.patch @@ -0,0 +1,360 @@ +diff -Nur linux-2.6.12.5/drivers/mtd/maps/bcm47xx-flash.c linux-2.6.12.5-flash/drivers/mtd/maps/bcm47xx-flash.c +--- linux-2.6.12.5/drivers/mtd/maps/bcm47xx-flash.c	1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-flash/drivers/mtd/maps/bcm47xx-flash.c	2005-11-06 20:36:42.553198500 +0100 +@@ -0,0 +1,329 @@ ++/* ++ *  Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org) ++ *  Copyright (C) 2005 Waldemar Brodkorb <wbx@openwrt.org> ++ * ++ *  original functions for finding root filesystem from Mike Baker  ++ * ++ *  This program is free software; you can redistribute  it and/or modify it ++ *  under  the terms of  the GNU General  Public License as published by the ++ *  Free Software Foundation;  either version 2 of the  License, or (at your ++ *  option) any later version. ++ * ++ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED ++ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF ++ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN ++ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT, ++ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF ++ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT ++ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ *  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., ++ *  675 Mass Ave, Cambridge, MA 02139, USA. ++ *  ++ *  Copyright 2001-2003, 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: bcm47xx-flash.c,v 1.1 2004/10/21 07:18:31 jolt Exp $ ++ * ++ *  Flash mapping for BCM947XX boards ++ */ ++ ++#include <linux/init.h> ++#include <linux/module.h> ++#include <linux/types.h> ++#include <linux/kernel.h> ++#include <asm/io.h> ++#include <linux/mtd/mtd.h> ++#include <linux/mtd/map.h> ++#include <linux/mtd/partitions.h> ++#include <linux/config.h> ++#include <typedefs.h> ++#include <bcmutils.h> ++#include <bcmnvram.h> ++#include <trxhdr.h> ++ ++ ++#ifdef CONFIG_MTD_PARTITIONS ++extern struct mtd_partition * init_mtd_partitions(struct mtd_info *mtd, size_t size); ++#endif ++ ++#define WINDOW_ADDR 0x1c000000 ++#define WINDOW_SIZE (0x400000*2) ++#define BUSWIDTH 2 ++ ++static struct mtd_info *bcm947xx_mtd; ++ ++static void bcm947xx_map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) ++{ ++#define MIPS_MEMCPY_ALIGN 4 ++	map_word ret; ++	ssize_t transfer; ++	ssize_t done = 0; ++	if ((len >= MIPS_MEMCPY_ALIGN) && (!(from & (MIPS_MEMCPY_ALIGN - 1))) && (!(((unsigned int)to & (MIPS_MEMCPY_ALIGN - 1))))) { ++		done = len & ~(MIPS_MEMCPY_ALIGN - 1); ++		memcpy_fromio(to, map->virt + from, done); ++	} ++	while (done < len) { ++		ret = map->read(map, from + done); ++		transfer = len - done; ++		if (transfer > map->bankwidth) ++			transfer = map->bankwidth; ++		memcpy((void *)((unsigned long)to + done), &ret.x[0], transfer); ++		done += transfer; ++	} ++} ++ ++static struct map_info bcm947xx_map = { ++	name: "Physically mapped flash", ++	size: WINDOW_SIZE, ++	bankwidth: BUSWIDTH, ++	phys: WINDOW_ADDR, ++}; ++ ++#ifdef CONFIG_MTD_PARTITIONS ++ ++static struct mtd_partition bcm947xx_parts[] = { ++	{ name: "cfe",	offset: 0, size: 0, mask_flags: MTD_WRITEABLE, }, ++	{ name: "linux", offset: 0, size: 0, }, ++	{ name: "rootfs", offset: 0, size: 0, }, ++	{ name: "nvram", offset: 0, size: 0, }, ++	{ name: "OpenWrt", offset: 0, size: 0, }, ++	{ name: NULL, }, ++}; ++ ++static int __init ++find_cfe_size(struct mtd_info *mtd, size_t size) ++{ ++	struct trx_header *trx; ++	unsigned char buf[512]; ++	int off; ++	size_t len; ++	int cfe_size_flag; ++ ++	trx = (struct trx_header *) buf; ++ ++	cfe_size_flag=0; ++ ++	for (off = (256*1024); off < size; off += mtd->erasesize) { ++		memset(buf, 0xe5, sizeof(buf)); ++ ++		/* ++		 * Read into buffer  ++		 */ ++		if (MTD_READ(mtd, off, sizeof(buf), &len, buf) || ++		    len != sizeof(buf)) ++			continue; ++ ++		/* found a TRX header */ ++		if (le32_to_cpu(trx->magic) == TRX_MAGIC) { ++			goto done; ++		} ++		cfe_size_flag += 1; ++	} ++ ++	printk(KERN_NOTICE ++	       "%s: Couldn't find bootloader size\n", ++	       mtd->name); ++	return -1; ++ ++ done: ++	printk(KERN_NOTICE "bootloader size flag: %d\n", cfe_size_flag); ++	return cfe_size_flag; ++ ++} ++ ++static int __init ++find_root(struct mtd_info *mtd, size_t size, struct mtd_partition *part) ++{ ++	struct trx_header *trx; ++	unsigned char buf[512]; ++	int off; ++	size_t len; ++ ++	trx = (struct trx_header *) buf; ++ ++	for (off = (256*1024); off < size; off += mtd->erasesize) { ++		memset(buf, 0xe5, sizeof(buf)); ++ ++		/* ++		 * Read into buffer  ++		 */ ++		if (MTD_READ(mtd, off, sizeof(buf), &len, buf) || ++		    len != sizeof(buf)) ++			continue; ++ ++		/* found a TRX header */ ++		if (le32_to_cpu(trx->magic) == TRX_MAGIC) { ++			part->offset = le32_to_cpu(trx->offsets[2]) ? :  ++				le32_to_cpu(trx->offsets[1]); ++			part->size = le32_to_cpu(trx->len);  ++ ++			part->size -= part->offset; ++			part->offset += off; ++ ++			goto done; ++		} ++	} ++ ++	printk(KERN_NOTICE ++	       "%s: Couldn't find root filesystem\n", ++	       mtd->name); ++	return -1; ++ ++ done: ++	return part->size; ++} ++ ++struct mtd_partition * __init ++init_mtd_partitions(struct mtd_info *mtd, size_t size) ++{ ++ ++	int cfe_size_flag; ++ ++	cfe_size_flag = find_cfe_size(mtd,size);  ++ ++	/* if cfe_size_flag=0, cfe size is 256 kb, else 384 kb */ ++ ++	/* boot loader */ ++	bcm947xx_parts[0].offset = 0; ++	if (cfe_size_flag == 0) { ++		bcm947xx_parts[0].size	 = 1024*256; ++	} else { ++		/* netgear wgt634u has 384 kb bootloader */ ++		bcm947xx_parts[0].size   = 1024*384; ++	} ++ ++	/* nvram */ ++	if (cfe_size_flag == 0) { ++		bcm947xx_parts[3].offset = size - mtd->erasesize; ++		bcm947xx_parts[3].size   = mtd->erasesize; ++	} else { ++		/* nvram (old 128kb config partition on netgear wgt634u) */ ++		bcm947xx_parts[3].offset = bcm947xx_parts[0].size; ++		bcm947xx_parts[3].size   = 1024*128; ++	} ++ ++	/* linux (kernel and rootfs) */ ++	if (cfe_size_flag == 0) { ++		bcm947xx_parts[1].offset = bcm947xx_parts[0].size; ++		bcm947xx_parts[1].size   = bcm947xx_parts[3].offset -  ++			bcm947xx_parts[1].offset; ++	} else { ++		/* do not count the elf loader, which is on one sector */ ++		bcm947xx_parts[1].offset = bcm947xx_parts[0].size +  ++			bcm947xx_parts[3].size + mtd->erasesize; ++		bcm947xx_parts[1].size   = size -  ++			bcm947xx_parts[0].size -  ++			(2*bcm947xx_parts[3].size) -  ++			mtd->erasesize; ++	} ++ ++	/* find and size rootfs */ ++	if (find_root(mtd,size,&bcm947xx_parts[2])==0) { ++		/* entirely jffs2 */ ++		bcm947xx_parts[4].name = NULL; ++		if (cfe_size_flag == 0) { ++			bcm947xx_parts[2].size = bcm947xx_parts[3].offset -  ++				bcm947xx_parts[2].offset; ++		} else { ++			bcm947xx_parts[2].size = size - bcm947xx_parts[2].offset -  ++				bcm947xx_parts[3].size;  ++		} ++	} else { ++		/* legacy setup */ ++		/* calculate leftover flash, and assign it to the jffs2 partition */ ++		if (cfe_size_flag == 0) { ++			bcm947xx_parts[4].offset = bcm947xx_parts[2].offset +  ++				bcm947xx_parts[2].size; ++			bcm947xx_parts[4].size = bcm947xx_parts[3].offset -  ++				bcm947xx_parts[4].offset; ++		} else { ++			bcm947xx_parts[4].offset = bcm947xx_parts[2].offset +  ++				bcm947xx_parts[2].size; ++			if ((bcm947xx_parts[4].offset % mtd->erasesize) > 0) { ++				bcm947xx_parts[4].offset += mtd->erasesize -  ++					(bcm947xx_parts[4].offset % mtd->erasesize); ++			} ++			bcm947xx_parts[4].size = size - bcm947xx_parts[3].size -  ++				bcm947xx_parts[4].offset; ++		} ++	} ++ ++	return bcm947xx_parts; ++} ++ ++EXPORT_SYMBOL(init_mtd_partitions); ++#endif ++ ++int __init init_bcm947xx_map(void) ++{ ++	size_t size; ++	int ret = 0; ++#ifdef CONFIG_MTD_PARTITIONS ++	struct mtd_partition *parts; ++	int i; ++#endif ++ ++	bcm947xx_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE); ++ ++	if (!bcm947xx_map.virt) { ++		printk("Failed to ioremap\n"); ++		return -EIO; ++	} ++	simple_map_init(&bcm947xx_map); ++	 ++	bcm947xx_map.copy_from = bcm947xx_map_copy_from; ++	 ++	if (!(bcm947xx_mtd = do_map_probe("cfi_probe", &bcm947xx_map))) { ++		printk("Failed to do_map_probe\n"); ++		iounmap((void *)bcm947xx_map.virt); ++		return -ENXIO; ++	} ++ ++	bcm947xx_mtd->owner = THIS_MODULE; ++ ++	size = bcm947xx_mtd->size; ++ ++	printk(KERN_NOTICE "Flash device: 0x%x at 0x%x\n", bcm947xx_mtd->size, WINDOW_ADDR); ++ ++#ifdef CONFIG_MTD_PARTITIONS ++	parts = init_mtd_partitions(bcm947xx_mtd, size); ++	for (i = 0; parts[i].name; i++); ++	ret = add_mtd_partitions(bcm947xx_mtd, parts, i); ++	if (ret) { ++		printk(KERN_ERR "Flash: add_mtd_partitions failed\n"); ++		goto fail; ++	} ++#endif ++ ++	return 0; ++ ++ fail: ++	if (bcm947xx_mtd) ++		map_destroy(bcm947xx_mtd); ++	if (bcm947xx_map.map_priv_1) ++		iounmap((void *) bcm947xx_map.map_priv_1); ++	bcm947xx_map.map_priv_1 = 0; ++	return ret; ++} ++ ++void __exit cleanup_bcm947xx_map(void) ++{ ++#ifdef CONFIG_MTD_PARTITIONS ++	del_mtd_partitions(bcm947xx_mtd); ++#endif ++	map_destroy(bcm947xx_mtd); ++	iounmap((void *)bcm947xx_map.virt); ++} ++ ++module_init(init_bcm947xx_map); ++module_exit(cleanup_bcm947xx_map); +diff -Nur linux-2.6.12.5/drivers/mtd/maps/Kconfig linux-2.6.12.5-flash/drivers/mtd/maps/Kconfig +--- linux-2.6.12.5/drivers/mtd/maps/Kconfig	2005-08-15 02:20:18.000000000 +0200 ++++ linux-2.6.12.5-flash/drivers/mtd/maps/Kconfig	2005-09-16 22:27:36.000000000 +0200 +@@ -357,6 +357,12 @@ + 	  Mapping for the Flaga digital module. If you don't have one, ignore + 	  this setting. +  ++config MTD_BCM47XX ++	tristate "BCM47xx flash device" ++	depends on MIPS && MTD_CFI && BCM947XX ++	help ++	  Support for the flash chips on the BCM947xx board. ++	   + config MTD_BEECH + 	tristate "CFI Flash device mapped on IBM 405LP Beech" + 	depends on MTD_CFI && PPC32 && 40x && BEECH +diff -Nur linux-2.6.12.5/drivers/mtd/maps/Makefile linux-2.6.12.5-flash/drivers/mtd/maps/Makefile +--- linux-2.6.12.5/drivers/mtd/maps/Makefile	2005-08-15 02:20:18.000000000 +0200 ++++ linux-2.6.12.5-flash/drivers/mtd/maps/Makefile	2005-09-16 22:27:01.000000000 +0200 +@@ -31,6 +31,7 @@ + obj-$(CONFIG_MTD_PCMCIA)	+= pcmciamtd.o + obj-$(CONFIG_MTD_RPXLITE)	+= rpxlite.o + obj-$(CONFIG_MTD_TQM8XXL)	+= tqm8xxl.o ++obj-$(CONFIG_MTD_BCM47XX)	+= bcm47xx-flash.o + obj-$(CONFIG_MTD_SA1100)	+= sa1100-flash.o + obj-$(CONFIG_MTD_IPAQ)		+= ipaq-flash.o + obj-$(CONFIG_MTD_SBC_GXX)	+= sbc_gxx.o  | 
