diff options
-rw-r--r-- | target/linux/rdc-2.6/files/drivers/mtd/maps/rdc3210.c | 296 | ||||
-rw-r--r-- | target/linux/rdc-2.6/patches/001-rdc3210_flash_map.patch | 2 |
2 files changed, 84 insertions, 214 deletions
diff --git a/target/linux/rdc-2.6/files/drivers/mtd/maps/rdc3210.c b/target/linux/rdc-2.6/files/drivers/mtd/maps/rdc3210.c index f6a634a9c..3ec934825 100644 --- a/target/linux/rdc-2.6/files/drivers/mtd/maps/rdc3210.c +++ b/target/linux/rdc-2.6/files/drivers/mtd/maps/rdc3210.c @@ -1,245 +1,115 @@ -/******************************************************************* - * Simple Flash mapping for RDC3210 * - * * - * 2005.03.23 * - * Dante Su (dante_su@gemtek.com.tw) * - * Copyright (C) 2005 Gemtek Corporation * - *******************************************************************/ - -#include <linux/module.h> -#include <linux/types.h> -#include <linux/kernel.h> +/* + * $Id$ + * Copyright (C) 2005 Gemtek Corporation, Dante Su (dante_su@gemtek.com.tw) + * Copyright (C) 2006 Florian Fainelli <florian@openwrt.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + #include <asm/io.h> -#include <linux/mtd/mtd.h> +#include <linux/init.h> +#include <linux/kernel.h> #include <linux/mtd/map.h> +#include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> -#include <linux/config.h> - -#ifndef RDC3210_STATIC_MAP -#define RDC3210_STATIC_MAP 0 -#endif -#ifndef RDC3210_FACTORY_DFLT -#define RDC3210_FACTORY_DFLT 0 -#endif -#ifndef RDC3210_USING_JFFS2 -#define RDC3210_USING_JFFS2 1 -#endif - -#define WINDOW_ADDR 0xFFC00000 -#define WINDOW_SIZE 0x00400000 - -#define BUSWIDTH 2 - -/* Dante: linked from linux-2.4.x/drivers/mtd/chips/flashdrv.c */ -extern int flashdrv_get_size(void); -extern int flashdrv_get_sector(int addr); -extern int flashdrv_get_sector_addr(int sector); -extern int flashdrv_get_sector_size(int sector); - -static struct mtd_info *rdc3210_mtd; - -__u8 rdc3210_map_read8(struct map_info *map, unsigned long ofs) -{ - return *(__u8 *)(map->map_priv_1 + ofs); -} - -__u16 rdc3210_map_read16(struct map_info *map, unsigned long ofs) -{ - return *(__u16 *)(map->map_priv_1 + ofs); -} - -__u32 rdc3210_map_read32(struct map_info *map, unsigned long ofs) -{ - return *(__u32 *)(map->map_priv_1 + ofs); -} - -void rdc3210_map_write8(struct map_info *map, __u8 d, unsigned long adr) -{ - *(__u8 *)(map->map_priv_1 + adr) = d; -} - -void rdc3210_map_write16(struct map_info *map, __u16 d, unsigned long adr) -{ - *(__u16 *)(map->map_priv_1 + adr) = d; -} - -void rdc3210_map_write32(struct map_info *map, __u32 d, unsigned long adr) -{ - *(__u32 *)(map->map_priv_1 + adr) = d; -} +#include <linux/vmalloc.h> -void rdc3210_map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) -{ - int i; - u16 *dst = (u16 *)(to); - u16 *src = (u16 *)(map->map_priv_1 + from); +#define WINDOW_ADDR 0xFFC00000 +#define WINDOW_SIZE 0x00400000 +#define BUSWIDTH 2 - for(i = 0; i < (len / 2); ++i) - dst[i] = src[i]; +extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts, unsigned long fis_origin); - if(len & 1) - { - printk("# WARNNING!!! rdc3210_map_copy_from has odd length\n"); - //dst[len - 1] = B0(src[i]); - } -} +static struct mtd_partition *parsed_parts; +static struct mtd_info *rdc3210_mtd_info; -void rdc3210_map_copy_to(struct map_info *map, void *to, unsigned long from, ssize_t len) -{ - int i; - u16 *dst = (u16 *)(map->map_priv_1 + to); - u16 *src = (u16 *)(from); - - for(i = 0; i < (len / 2); ++i) - dst[i] = src[i]; - - if(len & 1) - { - printk("# WARNNING!!! rdc3210_map_copy_from has odd length\n"); - //dst[len - 1] = B0(src[i]); - } -} - -struct map_info rdc3210_map = -{ - name: "RDC3210 Flash", - size: WINDOW_SIZE, - buswidth: BUSWIDTH, - read8: rdc3210_map_read8, - read16: rdc3210_map_read16, - read32: rdc3210_map_read32, - copy_from: rdc3210_map_copy_from, - write8: rdc3210_map_write8, - write16: rdc3210_map_write16, - write32: rdc3210_map_write32, - copy_to: rdc3210_map_copy_to, +static struct map_info rdc3210_map = { + .name = "rdc3210", + .size = WINDOW_SIZE, + .bankwidth = BUSWIDTH, + .phys = WINDOW_ADDR, }; -/* Dante: This is the default static mapping, however this is nothing but a hint. (Say dynamic mapping) */ -static struct mtd_partition rdc3210_parts[] = -{ - { name: "linux", offset: 0, size: 0x003C0000 }, /* 3840 KB = (Kernel + ROMFS) = (768 KB + 3072 KB) */ - { name: "romfs", offset: 0x000C0000, size: 0x00300000 }, /* 3072 KB */ - { name: "nvram", offset: 0x003C0000, size: 0x00010000 }, /* 64 KB */ -#if RDC3210_STATIC_MAP || RDC3210_FACTORY_DFLT - { name: "factory", offset: 0x003D0000, size: 0x00010000 }, /* 64 KB */ -#endif - { name: "bootldr", offset: 0x003E0000, size: 0x00020000 }, /* 128 KB */ +static struct mtd_partition rdc3210_parts[] = { + { name: "linux", offset: 0, size: 0x003C0000 }, /* 3840 KB = (Kernel + ROMFS) = (768 KB + 3072 KB) */ + { name: "romfs", offset: 0x000C0000, size: 0x00300000 }, /* 3072 KB */ + { name: "nvram", offset: 0x003C0000, size: 0x00010000 }, /* 64 KB */ + { name: "factory", offset: 0x003D0000, size: 0x00010000 }, /* 64 KB */ + { name: "bootldr", offset: 0x003E0000, size: 0x00020000, mask_flags: MTD_WRITEABLE },/* 128 KB */ }; -#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE) -#define init_rdc3210_map init_module -#define cleanup_rdc3210_map cleanup_module -#endif - -mod_init_t init_rdc3210_map(void) +static int __init rdc3210_mtd_init(void) { - printk(KERN_NOTICE "flash device: %x at %x\n", WINDOW_SIZE, WINDOW_ADDR); - - rdc3210_map.map_priv_1 = ioremap(WINDOW_ADDR, WINDOW_SIZE); + printk(KERN_INFO "rdc3210: 0x%08x at 0x%08x\n", WINDOW_SIZE, WINDOW_ADDR); + rdc3210_map.virt = ioremap_nocache(WINDOW_ADDR, WINDOW_SIZE); - if (!rdc3210_map.map_priv_1) - { - printk("Failed to ioremap\n"); + if (!rdc3210_map.virt) { + printk(KERN_ERR "rdc3210: failed to ioremap\n"); return -EIO; } - rdc3210_mtd = do_map_probe("cfi_probe", &rdc3210_map); -#if RDC3210_STATIC_MAP /* Dante: This is for fixed map */ - if (rdc3210_mtd) - { - rdc3210_mtd->module = THIS_MODULE; - add_mtd_partitions(rdc3210_mtd, rdc3210_parts, sizeof(rdc3210_parts)/sizeof(rdc3210_parts[0])); - return 0; - } -#else /* Dante: This is for dynamic mapping */ -#include <gemtek/sysdep.h> -#include <gemtek/imghdr.h> + simple_map_init(&rdc3210_map); - if (rdc3210_mtd) - { // Dante -#if RDC3210_USING_JFFS2 - unsigned int tmp, tmp2 = rdc3210_mtd->erasesize; -#else - unsigned int tmp, tmp2 = 32; -#endif - gt_imghdr_t *hdr; - - hdr = (gt_imghdr_t *)(rdc3210_map.map_priv_1); - - if(memcmp(hdr->magic, GTIMG_MAGIC, 4)) + rdc3210_mtd_info = do_map_probe("cfi_probe", &rdc3210_map); + + if (rdc3210_mtd_info) + { + rdc3210_mtd_info->owner = THIS_MODULE; + int parsed_nr_parts = 0; + char * part_type; + +#ifdef CONFIG_MTD_REDBOOT_PARTS + if (parsed_nr_parts == 0) { - printk("Invalid MAGIC for Firmware Image!!!\n"); - return -EIO; + int ret = parse_redboot_partitions(rdc3210_mtd_info, &parsed_parts, 0); + if (ret > 0) + { + part_type = "RedBoot"; + parsed_nr_parts = ret; + } else { + printk(KERN_ERR "rdc3210: failed to parse RedBoot partitions, using static mapping\n"); + add_mtd_partitions(rdc3210_mtd_info, rdc3210_parts, sizeof(rdc3210_parts)/sizeof(rdc3210_parts[0])); + return -ENXIO; + } } -#if RDC3210_FACTORY_DFLT - /* 1. Adjust Redboot */ - tmp = flashdrv_get_size() - rdc3210_parts[4].size; - rdc3210_parts[4].offset = flashdrv_get_sector_addr(flashdrv_get_sector(tmp)); - rdc3210_parts[4].size = flashdrv_get_size() - rdc3210_parts[4].offset; - - /* 2. Adjust NVRAM */ - tmp -= rdc3210_parts[3].size; - rdc3210_parts[3].offset = flashdrv_get_sector_addr(flashdrv_get_sector(tmp)); - rdc3210_parts[3].size = rdc3210_parts[4].offset - rdc3210_parts[3].offset; - - /* 3. Adjust Factory Default */ - tmp -= rdc3210_parts[2].size; - rdc3210_parts[2].offset = flashdrv_get_sector_addr(flashdrv_get_sector(tmp)); - rdc3210_parts[2].size = rdc3210_parts[3].offset - rdc3210_parts[2].offset; - - /* 4. Adjust Linux (Kernel + ROMFS) */ - rdc3210_parts[0].size = rdc3210_parts[2].offset - rdc3210_parts[0].offset; - - /* 5. Adjust ROMFS */ - tmp = hdr->kernelsz + sizeof(gt_imghdr_t); - rdc3210_parts[1].offset = rdc3210_parts[0].offset + (((tmp / tmp2) + ((tmp % tmp2) ? 1 : 0)) * tmp2); - rdc3210_parts[1].size = rdc3210_parts[2].offset - rdc3210_parts[1].offset; -#else - /* 1. Adjust Redboot */ - tmp = flashdrv_get_size() - rdc3210_parts[3].size; - rdc3210_parts[3].offset = flashdrv_get_sector_addr(flashdrv_get_sector(tmp)); - rdc3210_parts[3].size = flashdrv_get_size() - rdc3210_parts[3].offset; - - /* 2. Adjust NVRAM */ - tmp -= rdc3210_parts[2].size; - rdc3210_parts[2].offset = flashdrv_get_sector_addr(flashdrv_get_sector(tmp)); - rdc3210_parts[2].size = rdc3210_parts[3].offset - rdc3210_parts[2].offset; - - /* 4. Adjust Linux (Kernel + ROMFS) */ - rdc3210_parts[0].size = rdc3210_parts[2].offset - rdc3210_parts[0].offset; - - /* 5. Adjust ROMFS */ - tmp = hdr->kernelsz + sizeof(gt_imghdr_t); - rdc3210_parts[1].offset = rdc3210_parts[0].offset + (((tmp / tmp2) + ((tmp % tmp2) ? 1 : 0)) * tmp2); - rdc3210_parts[1].size = rdc3210_parts[2].offset - rdc3210_parts[1].offset; -#endif - - rdc3210_mtd->module = THIS_MODULE; - add_mtd_partitions(rdc3210_mtd, rdc3210_parts, sizeof(rdc3210_parts)/sizeof(rdc3210_parts[0])); + add_mtd_partitions(rdc3210_mtd_info, parsed_parts, parsed_nr_parts); return 0; } #endif - - iounmap((void *)rdc3210_map.map_priv_1); + iounmap(rdc3210_map.virt); return -ENXIO; } -mod_exit_t cleanup_rdc3210_map(void) +static void __exit rdc3210_mtd_cleanup(void) { - if (rdc3210_mtd) + if (rdc3210_mtd_info) { - del_mtd_partitions(rdc3210_mtd); - map_destroy(rdc3210_mtd); + del_mtd_partitions(rdc3210_mtd_info); + map_destroy(rdc3210_mtd_info); } - - if (rdc3210_map.map_priv_1) - { - iounmap((void *)rdc3210_map.map_priv_1); - rdc3210_map.map_priv_1 = NULL; + + if (rdc3210_map.virt) { + iounmap(rdc3210_map.virt); + rdc3210_map.virt = 0; } } -module_init(init_rdc3210_map); -module_exit(cleanup_rdc3210_map); +module_init(rdc3210_mtd_init); +module_exit(rdc3210_mtd_cleanup); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("RDC3210 flash map driver"); +MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>"); diff --git a/target/linux/rdc-2.6/patches/001-rdc3210_flash_map.patch b/target/linux/rdc-2.6/patches/001-rdc3210_flash_map.patch index f69fbf8e6..b3a4adb00 100644 --- a/target/linux/rdc-2.6/patches/001-rdc3210_flash_map.patch +++ b/target/linux/rdc-2.6/patches/001-rdc3210_flash_map.patch @@ -6,7 +6,7 @@ diff -urN linux-2.6.17/drivers/mtd/maps/Kconfig linux-2.6.17.new/drivers/mtd/map Ltd. in Japan. It uses CFI-compliant flash. +config MTD_RDC3210 -+ tristate "CFI Flash devcie mapped on RDC3210" ++ tristate "CFI Flash device mapped on RDC3210" + depends on X86 && MTD_CFI && MTD_PARTITIONS + help + RDC-3210 is the flash device we find on Ralink reference board |