[amazon] export amazon_get_cpu_hz
[openwrt.git] / target / linux / amazon / files / drivers / mtd / maps / amazon.c
index 3e7dc4f..55bfe32 100644 (file)
@@ -20,6 +20,7 @@
 
 // copyright 2007 john crispin <blogic@openwrt.org>
 // copyright 2007 felix fietkau <nbd@openwrt.org>
+// copyright 2009 hauke mehrtens <hauke@hauke-m.de>
 
 #include <linux/module.h>
 #include <linux/types.h>
@@ -32,6 +33,7 @@
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/cfi.h>
 #include <linux/mutex.h>
+#include <linux/platform_device.h>
 #include <asm/amazon/amazon.h>
 
 #define AMAZON_PCI_ARB_CTL_ALT 0xb100205c
@@ -41,7 +43,6 @@
 static struct map_info amazon_map = {
        .name = "AMAZON_FLASH",
        .bankwidth = 2,
-       .size = 0x400000,
 };
 
 static map_word amazon_read16(struct map_info * map, unsigned long ofs)
@@ -62,7 +63,6 @@ void amazon_copy_from(struct map_info *map, void *to, unsigned long from, ssize_
 {
        u8 *p;
        u8 *to_8;
-       ssize_t l = len;
        from = (unsigned long) (from + map->virt);
        p = (u8 *) from;
        to_8 = (u8 *) to;
@@ -102,23 +102,25 @@ static struct mtd_partition       amazon_partitions[3] = {
          },
 };
 
-
-unsigned long flash_start = 0x13000000;
-unsigned long flash_size = 0x800000;
 unsigned long uImage_size = 0x10000d;
 
-int find_uImage_size(unsigned long start_offset){
+int find_uImage_size(unsigned long start_offset)
+{
+       unsigned long magic;
        unsigned long temp;
-
-       printk("trying to find uImage and its size\n");
+       amazon_copy_from(&amazon_map, &magic, start_offset, 4);
+       if (!(ntohl(magic) == 0x27051956)) {
+               printk(KERN_INFO "amazon_mtd: invalid magic (0x%08X) of kernel at 0x%08lx \n", ntohl(magic), start_offset);
+               return 0;
+       }
        amazon_copy_from(&amazon_map, &temp, start_offset + 12, 4);
-       printk("kernel size is %d \n", temp + 0x40);
+       printk(KERN_INFO "amazon_mtd: kernel size is %ld \n", temp + 0x40);
        return temp + 0x40;
 }
 
-int __init init_amazon_mtd(void)
+static int __init amazon_mtd_probe(struct platform_device *dev)
 {
-       int ret = 0;
+       unsigned long uimage_size;
        struct mtd_info *mymtd = NULL;
        struct mtd_partition *parts = NULL;
 
@@ -129,38 +131,74 @@ int __init init_amazon_mtd(void)
        amazon_map.copy_from = amazon_copy_from;
        amazon_map.copy_to = amazon_copy_to;
 
-       amazon_map.phys = flash_start;
-       amazon_map.virt = ioremap_nocache(flash_start, flash_size);
+       amazon_map.phys = dev->resource->start;
+       amazon_map.size = dev->resource->end - amazon_map.phys + 1;
+       amazon_map.virt = ioremap_nocache(amazon_map.phys, amazon_map.size);
        
        if (!amazon_map.virt) {
-               printk(KERN_WARNING "Failed to ioremap!\n");
+               printk(KERN_WARNING "amazon_mtd: Failed to ioremap!\n");
                return -EIO;
        }
        
        mymtd = (struct mtd_info *) do_map_probe("cfi_probe", &amazon_map);
        if (!mymtd) {
                iounmap(amazon_map.virt);
-               printk("probing failed\n");
+               printk(KERN_WARNING "amazon_mtd: probing failed\n");
                return -ENXIO;
        }
 
        mymtd->owner = THIS_MODULE;
        parts = &amazon_partitions[0];
-       amazon_partitions[2].offset = UBOOT_SIZE + find_uImage_size(amazon_partitions[1].offset);
-       amazon_partitions[1].size = mymtd->size - amazon_partitions[1].offset - (2 * mymtd->erasesize);
-       amazon_partitions[2].size = mymtd->size - amazon_partitions[2].offset - (2 * mymtd->erasesize);
+
+       /* Some Samsung devices are containing a 16 MB flash chip with a bigger U-Boot partition. */
+       if(mymtd->size == 0x01000000 && mymtd->erasesize == 0x00020000) {
+               printk(KERN_INFO "amazon_mtd: Found big flash chip!\n");
+               amazon_partitions[0].size = 0x60000;
+               amazon_partitions[1].offset = 0x60000;
+               uimage_size = find_uImage_size(amazon_partitions[1].offset);
+               amazon_partitions[1].size = uimage_size;
+               amazon_partitions[2].offset = 0x60000 + uimage_size;
+               amazon_partitions[2].size = mymtd->size - amazon_partitions[2].offset - mymtd->erasesize;
+       } else {
+               printk(KERN_INFO "amazon_mtd: Found small flash chip!\n");
+               uimage_size = find_uImage_size(amazon_partitions[1].offset);
+               amazon_partitions[1].size = uimage_size;
+               amazon_partitions[2].offset = UBOOT_SIZE + uimage_size;
+               amazon_partitions[2].size = mymtd->size - amazon_partitions[2].offset - (2 * mymtd->erasesize);
+       }
+
        add_mtd_partitions(mymtd, parts, 3);
+
+       printk(KERN_INFO "amazon_mtd: added %s flash with %dMB\n",
+               amazon_map.name, ((int)mymtd->size) >> 20);
        return 0;
 }
 
-static void __exit cleanup_amazon_mtd(void)
+static struct platform_driver amazon_mtd_driver = {
+       .probe = amazon_mtd_probe,
+       .driver = {
+               .name = "amazon_mtd",
+               .owner = THIS_MODULE,
+       },
+};
+
+static int __init amazon_mtd_init(void)
 {
-       /* FIXME! */
+       int ret = platform_driver_register(&amazon_mtd_driver);
+       if (ret)
+               printk(KERN_WARNING "amazon_mtd: error registering platfom driver!\n");
+       return ret;
 }
 
-module_init(init_amazon_mtd);
-module_exit(cleanup_amazon_mtd);
+static void __exit amazon_mtd_cleanup(void)
+{
+       platform_driver_unregister(&amazon_mtd_driver);
+}
+
+module_init(amazon_mtd_init);
+module_exit(amazon_mtd_cleanup);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("john crispin blogic@openwrt.org");
 MODULE_DESCRIPTION("MTD map driver for AMAZON boards");
+
This page took 0.02551 seconds and 4 git commands to generate.