Back to home page

OSCL-LXR

 
 

    


0001 /****************************************************************************/
0002 
0003 /*
0004  *  uclinux.c -- generic memory mapped MTD driver for uclinux
0005  *
0006  *  (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
0007  *
0008  *      License: GPL
0009  */
0010 
0011 /****************************************************************************/
0012 
0013 #include <linux/moduleparam.h>
0014 #include <linux/types.h>
0015 #include <linux/init.h>
0016 #include <linux/kernel.h>
0017 #include <linux/fs.h>
0018 #include <linux/mm.h>
0019 #include <linux/major.h>
0020 #include <linux/mtd/mtd.h>
0021 #include <linux/mtd/map.h>
0022 #include <linux/mtd/partitions.h>
0023 #include <asm/io.h>
0024 #include <asm/sections.h>
0025 
0026 /****************************************************************************/
0027 
0028 #ifdef CONFIG_MTD_ROM
0029 #define MAP_NAME "rom"
0030 #else
0031 #define MAP_NAME "ram"
0032 #endif
0033 
0034 static struct map_info uclinux_ram_map = {
0035     .name = MAP_NAME,
0036     .size = 0,
0037 };
0038 
0039 static unsigned long physaddr = -1;
0040 module_param(physaddr, ulong, S_IRUGO);
0041 
0042 static struct mtd_info *uclinux_ram_mtdinfo;
0043 
0044 /****************************************************************************/
0045 
0046 static const struct mtd_partition uclinux_romfs[] = {
0047     { .name = "ROMfs" }
0048 };
0049 
0050 #define NUM_PARTITIONS  ARRAY_SIZE(uclinux_romfs)
0051 
0052 /****************************************************************************/
0053 
0054 static int uclinux_point(struct mtd_info *mtd, loff_t from, size_t len,
0055     size_t *retlen, void **virt, resource_size_t *phys)
0056 {
0057     struct map_info *map = mtd->priv;
0058     *virt = map->virt + from;
0059     if (phys)
0060         *phys = map->phys + from;
0061     *retlen = len;
0062     return(0);
0063 }
0064 
0065 /****************************************************************************/
0066 
0067 static int __init uclinux_mtd_init(void)
0068 {
0069     struct mtd_info *mtd;
0070     struct map_info *mapp;
0071 
0072     mapp = &uclinux_ram_map;
0073 
0074     if (physaddr == -1)
0075         mapp->phys = (resource_size_t)__bss_stop;
0076     else
0077         mapp->phys = physaddr;
0078 
0079     if (!mapp->size)
0080         mapp->size = PAGE_ALIGN(ntohl(*((unsigned long *)(mapp->phys + 8))));
0081     mapp->bankwidth = 4;
0082 
0083     printk("uclinux[mtd]: probe address=0x%x size=0x%x\n",
0084             (int) mapp->phys, (int) mapp->size);
0085 
0086     /*
0087      * The filesystem is guaranteed to be in direct mapped memory. It is
0088      * directly following the kernels own bss region. Following the same
0089      * mechanism used by architectures setting up traditional initrds we
0090      * use phys_to_virt to get the virtual address of its start.
0091      */
0092     mapp->virt = phys_to_virt(mapp->phys);
0093 
0094     if (mapp->virt == 0) {
0095         printk("uclinux[mtd]: no virtual mapping?\n");
0096         return(-EIO);
0097     }
0098 
0099     simple_map_init(mapp);
0100 
0101     mtd = do_map_probe("map_" MAP_NAME, mapp);
0102     if (!mtd) {
0103         printk("uclinux[mtd]: failed to find a mapping?\n");
0104         return(-ENXIO);
0105     }
0106 
0107     mtd->owner = THIS_MODULE;
0108     mtd->_point = uclinux_point;
0109     mtd->priv = mapp;
0110 
0111     uclinux_ram_mtdinfo = mtd;
0112     mtd_device_register(mtd, uclinux_romfs, NUM_PARTITIONS);
0113 
0114     return(0);
0115 }
0116 device_initcall(uclinux_mtd_init);
0117 
0118 /****************************************************************************/