rendered paste bodydiff -urN linux.old/drivers/mtd/maps/Kconfig linux.dev/drivers/mtd/maps/Kconfig
--- linux.old/drivers/mtd/maps/Kconfig 2007-01-07 13:15:25.000000000 +0100
+++ linux.dev/drivers/mtd/maps/Kconfig 2007-01-07 14:04:12.000000000 +0100
@@ -622,5 +622,17 @@
This selection automatically selects the map_ram driver.
-endmenu
+config MTD_AR531X
+ tristate "AR531X Flash device in physical memory map"
+ depends on MTD
+ help
+ Map driver for Atheros SoC AR531x
+
+config MTD_AR531X_SIZE
+ hex "Physical size"
+ depends on MTD_AR531X
+ default "0x400000"
+ help
+ Physical size flash
+endmenu
diff -urN linux.old/drivers/mtd/maps/Makefile linux.dev/drivers/mtd/maps/Makefile
--- linux.old/drivers/mtd/maps/Makefile 2007-01-07 13:59:37.000000000 +0100
+++ linux.dev/drivers/mtd/maps/Makefile 2007-01-07 13:59:57.000000000 +0100
@@ -70,3 +70,4 @@
obj-$(CONFIG_MTD_OMAP_NOR) += omap_nor.o
obj-$(CONFIG_MTD_MTX1) += mtx-1_flash.o
obj-$(CONFIG_MTD_TQM834x) += tqm834x.o
+obj-$(CONFIG_MTD_AR531X) += ar531x_flash.o
diff -urN linux.old/drivers/mtd/maps/ar531x_flash.c linux.dev/drivers/mtd/maps/ar531x_flash.c
--- linux.old/drivers/mtd/maps/ar531x_flash.c 1970-01-01 01:00:00.000000000 +0100
+++ linux.dev/drivers/mtd/maps/ar531x_flash.c 2007-01-08 00:34:02.000000000 +0100
@@ -0,0 +1,208 @@
+/*
+ * 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/init.h>
+#include <linux/vmalloc.h>
+
+
+#ifdef CONFIG_MTD_PARTITIONS
+#include <linux/mtd/partitions.h>
+#define MTDID "ar531x"
+#endif
+
+#define WINDOW_ADDR 0xbe000000
+#define WINDOW_SIZE CONFIG_MTD_AR531X_SIZE
+
+
+/* These ought to be somewhere common... */
+
+#define AR531X_FLASHCTL 0x18400000
+
+#define FLASHCTL_MW 0x30000000 /* Memory width */
+#define FLASHCTL_MWx8 0x00000000 /* Memory width x8 */
+#define FLASHCTL_MWx16 0x10000000 /* Memory width x16 */
+#define FLASHCTL_MWx32 0x20000000 /* Memory width x32 (not supported) */
+
+#define sysRegRead(phys) __raw_readl(KSEG1ADDR(phys))
+
+
+static struct mtd_info *mymtd;
+
+#ifdef CONFIG_MTD_PARTITIONS
+static const char *probes []={"cmdlinepart",NULL};
+#endif
+
+struct map_info ar531x_map = {
+ name: "ar531x",
+ size: WINDOW_SIZE
+};
+
+#ifdef CONFIG_MTD_PARTITIONS
+static struct mtd_partition *mtd_parts = 0;
+static int mtd_parts_nb = 0;
+
+struct img_info {
+ uint32_t lenght;
+ uint32_t CRC;
+ };
+
+static struct mtd_partition ar531x_partitions[] = {
+ {
+ name: "bdata",
+ size: 0x10000, /* 64KB */
+ offset: 0,
+ }, {
+ name: "boot",
+ size: 0x40000, /* 256KB */
+ offset: MTDPART_OFS_APPEND,
+ }, {
+ name: "zImage",
+ size: 0x0,
+ offset: MTDPART_OFS_APPEND,
+ }, {
+ name: "root",
+ size: 0x0,
+ offset: MTDPART_OFS_APPEND,
+ }, {
+ name: "EEPROM",
+ size: 0x10000, /* 64KB */
+ offset: MTDPART_OFS_APPEND,
+ }
+
+};
+
+#define NUM_PARTITIONS (sizeof(ar531x_partitions)/sizeof(struct mtd_partition))
+#endif
+
+
+
+int __init init_ar531x(void)
+{
+ static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", "map_rom", 0 };
+ const char **type;
+ unsigned int flashctl;
+ void *buf;
+ size_t retlen;
+ int ret;
+ struct img_info *image_info;
+
+
+ /* This is nasty, but needed as the new AR2312-01 parts only
+ * have an 8 bit bus to the flash; others have 16
+ */
+
+ flashctl = sysRegRead(AR531X_FLASHCTL) & FLASHCTL_MW;
+
+ if (flashctl == FLASHCTL_MWx8)
+ ar531x_map.bankwidth = 1;
+ else if (flashctl == FLASHCTL_MWx16)
+ ar531x_map.bankwidth = 2;
+ else {
+ printk(KERN_ERR "ar531x illegal flash buswidth (%#x)\n",
+ flashctl);
+ return -ENXIO;
+ }
+
+// printk(KERN_NOTICE "ar531x flash buswidth detected as %d\n",
+// ar531x_map.bankwidth);
+
+ /*
+ * Must make sure that WINDOW_ADDR is in kseg1 (uncached)
+ */
+ ar531x_map.map_priv_1 = (WINDOW_ADDR | KSEG1);
+
+ ar531x_map.phys = WINDOW_ADDR;
+ ar531x_map.virt = ioremap(WINDOW_ADDR,WINDOW_SIZE);
+
+ if (!ar531x_map.virt) {
+ printk("Failed to ioremap\n");
+ return -EIO;
+ }
+
+ simple_map_init(&ar531x_map);
+
+ mymtd = 0;
+ type = rom_probe_types;
+ for(; !mymtd && *type; type++) {
+ mymtd = do_map_probe(*type, &ar531x_map);
+ }
+ if (mymtd) {
+ mymtd->owner = THIS_MODULE;
+ add_mtd_device(mymtd);
+ printk(KERN_NOTICE "AR531x Flash device initialized: size 0x%x at 0x%x bankwidth 0x%x\n",
+ mymtd->size, WINDOW_ADDR, ar531x_map.bankwidth);
+
+#ifdef CONFIG_MTD_PARTITIONS
+ mtd_parts_nb = parse_mtd_partitions(mymtd, probes, &mtd_parts,0);
+ if (mtd_parts_nb > 0)
+ {
+ printk(KERN_NOTICE
+ "Using command line partition definition\n");
+ add_mtd_partitions (mymtd, mtd_parts, mtd_parts_nb);
+ }
+
+ else {
+
+/* Pokus o identifikaci openwrt firmware a jeho rozlozeni */
+
+ buf=vmalloc(mymtd->erasesize);
+ if (buf) {
+ ret=mymtd->read(mymtd,0,mymtd->erasesize, &retlen, buf);
+ if (ret)
+ goto out;
+
+ if (retlen != mymtd->erasesize)
+ goto out;
+
+ if (strstr(buf+0x10,"CA804.SOB")) {
+ image_info = buf+0x56;
+ ar531x_partitions[2].size = (image_info->lenght & 0xffff0000) + 0x10000; /* Velikost kernelu */
+ ar531x_partitions[3].size = mymtd->size - ar531x_partitions[0].size
+ - ar531x_partitions[1].size
+ - ar531x_partitions[2].size
+ - ar531x_partitions[4].size; /* Velikost rootFS */
+ if (NUM_PARTITIONS != 0)
+ {
+ printk(KERN_NOTICE "Using ar531x openwrt partition definition\n");
+ add_mtd_partitions (mymtd, ar531x_partitions, NUM_PARTITIONS);
+ }
+
+ }
+out:
+ vfree(buf);
+ }
+ }
+#endif
+
+ return 0;
+ }
+ iounmap ((void *)ar531x_map.virt);
+ return -ENXIO;
+}
+
+static void __exit cleanup_ar531x(void)
+{
+ if (mymtd) {
+ del_mtd_device(mymtd);
+ map_destroy(mymtd);
+ }
+ if (ar531x_map.virt) {
+ iounmap ((void *)ar531x_map.virt);
+ ar531x_map.virt=0;
+ }
+}
+
+module_init(init_ar531x);
+module_exit(cleanup_ar531x);
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Tomas Dlabac");
+MODULE_DESCRIPTION("Atheros AR531x MTD map driver");