mtdram.c revision 1da177e4c3f41524e886b7f1b8a0c1fc7321cac
11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * mtdram - a test mtd device 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * $Id: mtdram.c,v 1.35 2005/01/05 18:05:12 dwmw2 Exp $ 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Author: Alexander Larsson <alex@cendio.se> 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (c) 1999 Alexander Larsson <alex@cendio.se> 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This code is GPL 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/config.h> 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h> 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/slab.h> 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/ioport.h> 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/vmalloc.h> 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/mtd/compatmac.h> 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/mtd/mtd.h> 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef CONFIG_MTDRAM_ABS_POS 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds #define CONFIG_MTDRAM_ABS_POS 0 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if CONFIG_MTDRAM_ABS_POS > 0 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds #include <asm/io.h> 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef MODULE 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned long total_size = CONFIG_MTDRAM_TOTAL_SIZE; 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned long erase_size = CONFIG_MTDRAM_ERASE_SIZE; 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_param(total_size,ulong,0); 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_PARM_DESC(total_size, "Total device size in KiB"); 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_param(erase_size,ulong,0); 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_PARM_DESC(erase_size, "Device erase block size in KiB"); 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MTDRAM_TOTAL_SIZE (total_size * 1024) 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MTDRAM_ERASE_SIZE (erase_size * 1024) 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MTDRAM_TOTAL_SIZE (CONFIG_MTDRAM_TOTAL_SIZE * 1024) 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MTDRAM_ERASE_SIZE (CONFIG_MTDRAM_ERASE_SIZE * 1024) 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds// We could store these in the mtd structure, but we only support 1 device.. 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct mtd_info *mtd_info; 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsram_erase(struct mtd_info *mtd, struct erase_info *instr) 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DEBUG(MTD_DEBUG_LEVEL2, "ram_erase(pos:%ld, len:%ld)\n", (long)instr->addr, (long)instr->len); 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (instr->addr + instr->len > mtd->size) { 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DEBUG(MTD_DEBUG_LEVEL1, "ram_erase() out of bounds (%ld > %ld)\n", (long)(instr->addr + instr->len), (long)mtd->size); 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset((char *)mtd->priv + instr->addr, 0xff, instr->len); 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds instr->state = MTD_ERASE_DONE; 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mtd_erase_callback(instr); 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int ram_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf) 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (from + len > mtd->size) 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *mtdbuf = mtd->priv + from; 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *retlen = len; 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void ram_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size_t len) 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DEBUG(MTD_DEBUG_LEVEL2, "ram_unpoint\n"); 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int ram_read(struct mtd_info *mtd, loff_t from, size_t len, 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size_t *retlen, u_char *buf) 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DEBUG(MTD_DEBUG_LEVEL2, "ram_read(pos:%ld, len:%ld)\n", (long)from, (long)len); 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (from + len > mtd->size) { 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DEBUG(MTD_DEBUG_LEVEL1, "ram_read() out of bounds (%ld > %ld)\n", (long)(from + len), (long)mtd->size); 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(buf, mtd->priv + from, len); 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *retlen=len; 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int ram_write(struct mtd_info *mtd, loff_t to, size_t len, 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size_t *retlen, const u_char *buf) 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DEBUG(MTD_DEBUG_LEVEL2, "ram_write(pos:%ld, len:%ld)\n", (long)to, (long)len); 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (to + len > mtd->size) { 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DEBUG(MTD_DEBUG_LEVEL1, "ram_write() out of bounds (%ld > %ld)\n", (long)(to + len), (long)mtd->size); 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy ((char *)mtd->priv + to, buf, len); 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *retlen=len; 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __exit cleanup_mtdram(void) 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (mtd_info) { 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds del_mtd_device(mtd_info); 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if CONFIG_MTDRAM_TOTAL_SIZE > 0 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (mtd_info->priv) 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if CONFIG_MTDRAM_ABS_POS > 0 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iounmap(mtd_info->priv); 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vfree(mtd_info->priv); 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(mtd_info); 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint mtdram_init_device(struct mtd_info *mtd, void *mapped_address, 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long size, char *name) 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(mtd, 0, sizeof(*mtd)); 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Setup the MTD structure */ 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mtd->name = name; 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mtd->type = MTD_RAM; 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mtd->flags = MTD_CAP_RAM; 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mtd->size = size; 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mtd->erasesize = MTDRAM_ERASE_SIZE; 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mtd->priv = mapped_address; 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mtd->owner = THIS_MODULE; 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mtd->erase = ram_erase; 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mtd->point = ram_point; 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mtd->unpoint = ram_unpoint; 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mtd->read = ram_read; 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mtd->write = ram_write; 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (add_mtd_device(mtd)) { 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EIO; 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if CONFIG_MTDRAM_TOTAL_SIZE > 0 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if CONFIG_MTDRAM_ABS_POS > 0 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __init init_mtdram(void) 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void *addr; 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Allocate some memory */ 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mtd_info = kmalloc(sizeof(struct mtd_info), GFP_KERNEL); 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!mtd_info) 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOMEM; 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds addr = ioremap(CONFIG_MTDRAM_ABS_POS, MTDRAM_TOTAL_SIZE); 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!addr) { 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DEBUG(MTD_DEBUG_LEVEL1, 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "Failed to ioremap) memory region of size %ld at ABS_POS:%ld\n", 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (long)MTDRAM_TOTAL_SIZE, (long)CONFIG_MTDRAM_ABS_POS); 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(mtd_info); 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mtd_info = NULL; 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOMEM; 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = mtdram_init_device(mtd_info, addr, 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MTDRAM_TOTAL_SIZE, "mtdram test device"); 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (err) 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iounmap(addr); 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(mtd_info); 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mtd_info = NULL; 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return err; 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(mtd_info->priv, 0xff, MTDRAM_TOTAL_SIZE); 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return err; 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else /* CONFIG_MTDRAM_ABS_POS > 0 */ 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __init init_mtdram(void) 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void *addr; 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Allocate some memory */ 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mtd_info = kmalloc(sizeof(struct mtd_info), GFP_KERNEL); 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!mtd_info) 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOMEM; 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds addr = vmalloc(MTDRAM_TOTAL_SIZE); 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!addr) { 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DEBUG(MTD_DEBUG_LEVEL1, 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "Failed to vmalloc memory region of size %ld\n", 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (long)MTDRAM_TOTAL_SIZE); 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(mtd_info); 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mtd_info = NULL; 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOMEM; 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = mtdram_init_device(mtd_info, addr, 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MTDRAM_TOTAL_SIZE, "mtdram test device"); 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (err) 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vfree(addr); 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(mtd_info); 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mtd_info = NULL; 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return err; 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(mtd_info->priv, 0xff, MTDRAM_TOTAL_SIZE); 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return err; 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* !(CONFIG_MTDRAM_ABS_POS > 0) */ 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else /* CONFIG_MTDRAM_TOTAL_SIZE > 0 */ 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __init init_mtdram(void) 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* !(CONFIG_MTDRAM_TOTAL_SIZE > 0) */ 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_init(init_mtdram); 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_exit(cleanup_mtdram); 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL"); 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_AUTHOR("Alexander Larsson <alexl@redhat.com>"); 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_DESCRIPTION("Simulated MTD driver for testing"); 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 236