📄 bulverde.c
字号:
/* * $Id: * * Map driver for the Bulverde developer platform. * Author: Echo Engineering (Stolen from Nicolas Pitre's lubbock.c): * Copyright: (C) 2001 MontaVista Software Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */#include <linux/module.h>#include <linux/types.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/slab.h>#include <asm/io.h>#include <asm/system.h>#include <linux/mtd/mtd.h>#include <linux/mtd/map.h>#include <linux/mtd/partitions.h>#define BULVERDE_DEBUGGING 0#if BULVERDE_DEBUGGINGstatic unsigned int bulverde_debug = BULVERDE_DEBUGGING;#else#define bulverde_debug 0#endif#define WINDOW_ADDR 0//#define WINDOW_ADDR 0x04000000/* total flash memory is 32M, split between two chips */#define WINDOW_SIZE 32*1024*1024static void bulverde_inval_cache(struct map_info *map, unsigned long from, ssize_t len){ cpu_dcache_invalidate_range(map->map_priv_2 + from, map->map_priv_2 + from + len);}static struct map_info bulverde_map = { .name = "Bulverde flash", .size = WINDOW_SIZE, .inval_cache = bulverde_inval_cache,};static struct mtd_partition bulverde_partitions[] = { { name: "Bootloader", size: 0x00040000, offset: 0, mask_flags: MTD_WRITEABLE /* force read-only */ },{ name: "Kernel", size: 0x00300000, offset: 0x00040000, },{ name: "Filesystem", size: MTDPART_SIZ_FULL, offset: 0x00340000 }};#define NB_OF(x) (sizeof(x)/sizeof(x[0]))static struct mtd_info *mymtd;static struct mtd_partition *parsed_parts;extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts, unsigned long fis_origin);void bulverde_mtd_unlock_all(void){ int i; /* Unlock the flash device. */ if (bulverde_debug) printk("bulverde_mtd_unlock_all(): unlocking flash device\n"); if(mymtd->unlock){ for (i = 0; i < mymtd->numeraseregions; i++) { int j; if (bulverde_debug) { printk("bulverde_mtd_unlock_all(): unlocking region %d:\n" " numblocks is %lu\n" " offset is %lu\n" " erasesize is %lu\n", i, (unsigned long)mymtd->eraseregions[i].numblocks, (unsigned long)mymtd->eraseregions[i].offset, (unsigned long)mymtd->eraseregions[i].erasesize); } for (j = 0; j < mymtd->eraseregions[i].numblocks; j++){ mymtd->unlock(mymtd, mymtd->eraseregions[i].offset + j * mymtd->eraseregions[i].erasesize, mymtd->eraseregions[i].erasesize); } if (bulverde_debug) printk("bulverde_mtd_unlock_all(): number of blocks was %d\n", j); } if (bulverde_debug) printk("bulverde_mtd_unlock_all(): number of eraseregions was %d\n", i); } return;}static int __init init_bulverde(void){ struct mtd_partition *parts; int nb_parts = 0; int parsed_nr_parts = 0; char *part_type = "static"; bulverde_map.bankwidth = (BOOT_DEF & 1) ? 2 : 4; printk( "Probing Bulverde flash at physical address 0x%08x (%d-bit buswidth)\n", WINDOW_ADDR, bulverde_map.bankwidth * 8 ); //printk("GPDR0= 0x%x\n",GPDR0); //printk("GPLR0= 0x%x\n",GPLR0); //printk("PWER= 0x%x\n",PWER); //printk("PRER= 0x%x\n",PRER); //printk("PFER= 0x%x\n",PFER); bulverde_map.map_priv_1 = (unsigned long)__ioremap(WINDOW_ADDR, WINDOW_SIZE, 0); bulverde_map.map_priv_2 = (unsigned long)__ioremap(WINDOW_ADDR, WINDOW_SIZE, L_PTE_CACHEABLE); if (!bulverde_map.map_priv_1 || !bulverde_map.map_priv_2) { printk("Failed to ioremap\n"); if (bulverde_map.map_priv_1) iounmap((void *)bulverde_map.map_priv_1); if (bulverde_map.map_priv_2) iounmap((void *)bulverde_map.map_priv_2); return -EIO; } bulverde_map.virt = bulverde_map.map_priv_1; bulverde_map.cached = bulverde_map.map_priv_2; mymtd = do_map_probe("cfi_probe", &bulverde_map); if (!mymtd) { iounmap((void *)bulverde_map.map_priv_1); iounmap((void *)bulverde_map.map_priv_2); return -ENXIO; } if (mymtd->size > bulverde_map.size) { printk("Probe revealed more flash memory (0x%08X > 0x%08lX)\n" "Need to ioremap the appropriate size.\n", mymtd->size, bulverde_map.size); iounmap((void *)bulverde_map.map_priv_1); iounmap((void *)bulverde_map.map_priv_2); bulverde_map.size = mymtd->size; /* try to ioremap the correct size */ bulverde_map.map_priv_1 = (unsigned long)__ioremap(WINDOW_ADDR, bulverde_map.size, 0); bulverde_map.map_priv_2 = (unsigned long)__ioremap(WINDOW_ADDR, bulverde_map.size, L_PTE_CACHEABLE); if (!bulverde_map.map_priv_1 || !bulverde_map.map_priv_2) { printk("Failed to ioremap\n"); if (bulverde_map.map_priv_1) iounmap((void *)bulverde_map.map_priv_1); if (bulverde_map.map_priv_2) iounmap((void *)bulverde_map.map_priv_2); return -EIO; } bulverde_map.virt = bulverde_map.map_priv_1; bulverde_map.cached = bulverde_map.map_priv_2; } mymtd->owner = THIS_MODULE; /* Unlock the flash device. */ bulverde_mtd_unlock_all();#ifdef CONFIG_MTD_REDBOOT_PARTS if (parsed_nr_parts == 0) { int ret = parse_redboot_partitions(mymtd, &parsed_parts, 0); if (ret > 0) { part_type = "RedBoot"; parsed_nr_parts = ret; } }#endif if (parsed_nr_parts > 0) { parts = parsed_parts; nb_parts = parsed_nr_parts; } else { parts = bulverde_partitions; nb_parts = NB_OF(bulverde_partitions); } if (nb_parts) { printk(KERN_NOTICE "Using %s partition definition\n", part_type); add_mtd_partitions(mymtd, parts, nb_parts); } else { add_mtd_device(mymtd); } return 0;}static void __exit cleanup_bulverde(void){ if (mymtd) { del_mtd_partitions(mymtd); map_destroy(mymtd); if (parsed_parts) kfree(parsed_parts); } if (bulverde_map.map_priv_1) iounmap((void *)bulverde_map.map_priv_1); if (bulverde_map.map_priv_2) iounmap((void *)bulverde_map.map_priv_2); return;}module_init(init_bulverde);module_exit(cleanup_bulverde);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -