X-Git-Url: http://git.rohieb.name/openwrt.git/blobdiff_plain/17c7b6c3fdc48301e50d22cc6138ede16bd1be24..062819b9cb1abcc20133a87434c1b07a3a82ef94:/target/linux/amazon/files/drivers/mtd/maps/amazon.c diff --git a/target/linux/amazon/files/drivers/mtd/maps/amazon.c b/target/linux/amazon/files/drivers/mtd/maps/amazon.c index 3e7dc4f58..55bfe3237 100644 --- a/target/linux/amazon/files/drivers/mtd/maps/amazon.c +++ b/target/linux/amazon/files/drivers/mtd/maps/amazon.c @@ -20,6 +20,7 @@ // copyright 2007 john crispin // copyright 2007 felix fietkau +// copyright 2009 hauke mehrtens #include #include @@ -32,6 +33,7 @@ #include #include #include +#include #include #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"); +