openwrt/openwrt/target/linux/linux-2.4/patches/ar7/001-flash_map.patch

319 lines
9.9 KiB
Diff
Raw Normal View History

diff -urN linux-2.4.30/drivers/mtd/maps/Config.in linux-2.4.30.dev/drivers/mtd/maps/Config.in
--- linux-2.4.30/drivers/mtd/maps/Config.in 2005-06-14 19:31:49.000000000 +0200
+++ linux-2.4.30.dev/drivers/mtd/maps/Config.in 2005-06-14 15:36:59.000000000 +0200
@@ -48,6 +48,21 @@
fi
if [ "$CONFIG_MIPS" = "y" ]; then
+ if [ "$CONFIG_AR7" = "y" ]; then
+ dep_tristate ' Flash chip mapping on Texas Instruments AR7' CONFIG_MTD_AVALANCHE $CONFIG_MTD_CFI $CONFIG_MTD_PARTITIONS
+ dep_bool ' Use defaults for Texas Instruments AR7' CONFIG_MTD_AVALANCHE_DEFAULTS $CONFIG_MTD_AVALANCHE
+ if [ "$CONFIG_MTD_AVALANCHE" = "y" -o "$CONFIG_MTD_AVALANCHE" = "m" ]; then
+ if [ "$CONFIG_MTD_AVALANCHE_DEFAULTS" = "y" ]; then
+ define_hex CONFIG_MTD_AVALANCHE_START 0x10000000
+ define_hex CONFIG_MTD_AVALANCHE_LEN 0x400000
+ define_int CONFIG_MTD_AVALANCHE_BUSWIDTH 2
+ else
+ hex ' Physical start address of flash mapping' CONFIG_MTD_AVALANCHE_START 0x10000000
+ hex ' Physical length of flash mapping' CONFIG_MTD_AVALANCHE_LEN 0x400000
+ int ' Bus width in octets' CONFIG_MTD_AVALANCHE_BUSWIDTH 2
+ fi
+ fi
+ fi
dep_tristate ' Pb1000 MTD support' CONFIG_MTD_PB1000 $CONFIG_MIPS_PB1000
dep_tristate ' Pb1500 MTD support' CONFIG_MTD_PB1500 $CONFIG_MIPS_PB1500
dep_tristate ' Pb1100 MTD support' CONFIG_MTD_PB1100 $CONFIG_MIPS_PB1100
diff -urN linux-2.4.30/drivers/mtd/maps/Makefile linux-2.4.30.dev/drivers/mtd/maps/Makefile
--- linux-2.4.30/drivers/mtd/maps/Makefile 2005-06-14 19:31:49.000000000 +0200
+++ linux-2.4.30.dev/drivers/mtd/maps/Makefile 2005-06-14 15:36:59.000000000 +0200
@@ -10,6 +10,7 @@
endif
# Chip mappings
+obj-$(CONFIG_MTD_AVALANCHE) += ar7-flash.o
obj-$(CONFIG_MTD_CDB89712) += cdb89712.o
obj-$(CONFIG_MTD_ARM_INTEGRATOR)+= integrator-flash.o
obj-$(CONFIG_MTD_CFI_FLAGADM) += cfi_flagadm.o
diff -urN linux-2.4.30/drivers/mtd/maps/ar7-flash.c linux-2.4.30.dev/drivers/mtd/maps/ar7-flash.c
--- linux-2.4.30/drivers/mtd/maps/ar7-flash.c 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.30.dev/drivers/mtd/maps/ar7-flash.c 2005-06-14 22:42:23.000000000 +0200
@@ -0,0 +1,245 @@
+/*
+ * $Id$
+ *
+ * Normal mappings of chips in physical memory
+ */
+
+#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/config.h>
+#include <linux/mtd/partitions.h>
+#include "trxhdr.h"
+
+#define WINDOW_ADDR CONFIG_MTD_AVALANCHE_START
+#define WINDOW_SIZE CONFIG_MTD_AVALANCHE_LEN
+#define BUSWIDTH CONFIG_MTD_AVALANCHE_BUSWIDTH
+
+#include <asm/mips-boards/prom.h>
+extern char *prom_getenv(char *name);
+
+static int create_mtd_partitions(void);
+static void __exit avalanche_mtd_cleanup(void);
+
+/* avalanche__partition_info gives details on the logical partitions that splits
+ * the flash device into. If the size if zero we use up to the end of
+ * the device. */
+#define MAX_NUM_PARTITIONS 5
+static struct mtd_partition avalanche_partition_info[MAX_NUM_PARTITIONS];
+static int num_of_partitions = 0;
+
+static struct mtd_info *avalanche_mtd_info;
+
+int avalanche_mtd_ready=0;
+
+__u8 avalanche_read8(struct map_info *map, unsigned long ofs)
+{
+ return __raw_readb(map->map_priv_1 + ofs);
+}
+
+__u16 avalanche_read16(struct map_info *map, unsigned long ofs)
+{
+ return __raw_readw(map->map_priv_1 + ofs);
+}
+
+__u32 avalanche_read32(struct map_info *map, unsigned long ofs)
+{
+ return __raw_readl(map->map_priv_1 + ofs);
+}
+
+void avalanche_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+ memcpy_fromio(to, map->map_priv_1 + from, len);
+}
+
+void avalanche_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+ __raw_writeb(d, map->map_priv_1 + adr);
+ mb();
+}
+
+void avalanche_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+ __raw_writew(d, map->map_priv_1 + adr);
+ mb();
+}
+
+void avalanche_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+ __raw_writel(d, map->map_priv_1 + adr);
+ mb();
+}
+
+void avalanche_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+ memcpy_toio(map->map_priv_1 + to, from, len);
+}
+
+struct map_info avalanche_map = {
+ name: "Physically mapped flash",
+ size: WINDOW_SIZE,
+ buswidth: BUSWIDTH,
+ read8: avalanche_read8,
+ read16: avalanche_read16,
+ read32: avalanche_read32,
+ copy_from: avalanche_copy_from,
+ write8: avalanche_write8,
+ write16: avalanche_write16,
+ write32: avalanche_write32,
+ copy_to: avalanche_copy_to
+};
+
+int __init avalanche_mtd_init(void)
+{
+ printk(KERN_NOTICE "avalanche flash device: 0x%lx at 0x%lx.\n", (unsigned long)WINDOW_SIZE, (unsigned long)WINDOW_ADDR);
+ avalanche_map.map_priv_1 = (unsigned long)ioremap_nocache(WINDOW_ADDR, WINDOW_SIZE);
+
+ if (!avalanche_map.map_priv_1) {
+ printk("Failed to ioremap\n");
+ return -EIO;
+ }
+
+ avalanche_mtd_info = do_map_probe("cfi_probe", &avalanche_map);
+ if (!avalanche_mtd_info)
+ {
+ avalanche_mtd_cleanup();
+ return -ENXIO;
+ }
+
+ avalanche_mtd_info->module = THIS_MODULE;
+
+ if (!create_mtd_partitions())
+ add_mtd_device(avalanche_mtd_info);
+ else
+ add_mtd_partitions(avalanche_mtd_info, avalanche_partition_info, num_of_partitions);
+
+ avalanche_mtd_ready=1;
+
+ return 0;
+}
+
+static char *strdup(char *str)
+{
+ int n = strlen(str)+1;
+ char *s = kmalloc(n, GFP_KERNEL);
+ if (!s) return NULL;
+ return strcpy(s, str);
+}
+
+
+static int create_mtd_partitions(void)
+{
+ unsigned int offset;
+ unsigned int size;
+ unsigned int found;
+ unsigned char *flash_base;
+ unsigned char *flash_end;
+ struct trx_header hdr;
+ char *env_ptr;
+ char *base_ptr;
+ char *end_ptr;
+
+ do {
+ char env_name[20];
+
+ found = 0;
+
+ /* get base and end addresses of flash file system from environment */
+ sprintf(env_name, "mtd%1u", num_of_partitions);
+ printk("Looking for mtd device :%s:\n", env_name);
+
+ env_ptr = prom_getenv(env_name);
+ if(env_ptr == NULL) {
+ /* No more partitions to find */
+ break;
+ }
+
+ /* Extract the start and stop addresses of the partition */
+ base_ptr = strtok(env_ptr, ",");
+ end_ptr = strtok(NULL, ",");
+ if ((base_ptr == NULL) || (end_ptr == NULL)) {
+ printk("JFFS2 ERROR: Invalid %s start,end.\n", env_name);
+ break;
+ }
+
+ flash_base = (unsigned char*) simple_strtol(base_ptr, NULL, 0);
+ flash_end = (unsigned char*) simple_strtol(end_ptr, NULL, 0);
+ if((!flash_base) || (!flash_end)) {
+ printk("JFFS2 ERROR: Invalid %s start,end.\n", env_name);
+ break;
+ }
+
+ offset = virt_to_bus(flash_base) - WINDOW_ADDR;
+ size = flash_end - flash_base;
+ printk("Found a %s image (0x%x), with size (0x%x).\n",env_name, offset, size);
+
+ /* Setup the partition info. We duplicate the env_name for the partiton name */
+ avalanche_partition_info[num_of_partitions].offset = offset;
+ avalanche_partition_info[num_of_partitions].size = size;
+ avalanche_partition_info[num_of_partitions].mask_flags = 0;
+
+ switch (num_of_partitions ) {
+ case 0:
+ avalanche_partition_info[num_of_partitions].name = strdup("rootfs");
+ avalanche_copy_from(&avalanche_map, &hdr, offset, sizeof(hdr));
+ if (hdr.magic == TRX_MAGIC) {
+ printk("TRX partition detected. First offset: %08x\n", hdr.offsets[0]);
+ avalanche_partition_info[num_of_partitions].offset += hdr.offsets[0];
+ avalanche_partition_info[num_of_partitions].size -= hdr.offsets[0];
+ } else {
+ printk("No TRX partition detected\n");
+ }
+ break;
+
+ case 1:
+ avalanche_partition_info[num_of_partitions].name = strdup("linux");
+ break;
+
+ case 2:
+ avalanche_partition_info[num_of_partitions].name = strdup("adam2");
+ break;
+
+ case 3:
+ avalanche_partition_info[num_of_partitions].name = strdup("config");
+ break;
+
+ case 4:
+ avalanche_partition_info[num_of_partitions].name = strdup("firmware");
+ break;
+
+ default:
+ avalanche_partition_info[num_of_partitions].name = strdup(env_name);
+ break;
+ }
+
+ num_of_partitions++;
+ } while (num_of_partitions < MAX_NUM_PARTITIONS);
+
+ return num_of_partitions;
+}
+
+static void __exit avalanche_mtd_cleanup(void)
+{
+ avalanche_mtd_ready=0;
+
+ if (avalanche_mtd_info) {
+ del_mtd_partitions(avalanche_mtd_info);
+ del_mtd_device(avalanche_mtd_info);
+ map_destroy(avalanche_mtd_info);
+ }
+
+ if (avalanche_map.map_priv_1) {
+ iounmap((void *)avalanche_map.map_priv_1);
+ avalanche_map.map_priv_1 = 0;
+ }
+}
+
+module_init(avalanche_mtd_init);
+module_exit(avalanche_mtd_cleanup);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Snehaprabha Narnakaje");
+MODULE_DESCRIPTION("Avalanche CFI map driver");
diff -urN linux-2.4.30/drivers/mtd/maps/trxhdr.h linux-2.4.30.dev/drivers/mtd/maps/trxhdr.h
--- linux-2.4.30/drivers/mtd/maps/trxhdr.h 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.30.dev/drivers/mtd/maps/trxhdr.h 2005-06-14 21:57:04.000000000 +0200
@@ -0,0 +1,29 @@
+/*
+ * TRX image file header format.
+ *
+ * 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$
+ */
+
+
+#define TRX_MAGIC 0x30524448 /* "HDR0" */
+#define TRX_VERSION 1
+#define TRX_MAX_LEN 0x3A0000
+#define TRX_NO_HEADER 1 /* Do not write TRX header */
+#define TRX_GZ_FILES 0x2 /* Contains up to TRX_MAX_OFFSET individual gzip files */
+#define TRX_MAX_OFFSET 3
+
+struct trx_header {
+ __u32 magic; /* "HDR0" */
+ __u32 len; /* Length of file including header */
+ __u32 crc32; /* 32-bit CRC from flag_version to end of file */
+ __u32 flag_version; /* 0:15 flags, 16:31 version */
+ __u32 offsets[TRX_MAX_OFFSET]; /* Offsets of partitions from start of header */
+};