linux-old/drivers/mtd/maps/uclinux.c
<<
>>
Prefs
   1/****************************************************************************/
   2
   3/*
   4 *      uclinux.c -- generic memory mapped MTD driver for uclinux
   5 *
   6 *      (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
   7 *
   8 *      $Id: uclinux.c,v 1.2 2002/08/07 00:43:45 gerg Exp $
   9 */
  10
  11/****************************************************************************/
  12
  13#include <linux/config.h>
  14#include <linux/module.h>
  15#include <linux/types.h>
  16#include <linux/init.h>
  17#include <linux/kernel.h>
  18#include <linux/fs.h>
  19#include <linux/major.h>
  20#include <linux/mtd/mtd.h>
  21#include <linux/mtd/map.h>
  22#include <linux/mtd/partitions.h>
  23#include <asm/io.h>
  24
  25/****************************************************************************/
  26
  27__u8 uclinux_read8(struct map_info *map, unsigned long ofs)
  28{
  29        return(*((__u8 *) (map->map_priv_1 + ofs)));
  30}
  31
  32__u16 uclinux_read16(struct map_info *map, unsigned long ofs)
  33{
  34        return(*((__u16 *) (map->map_priv_1 + ofs)));
  35}
  36
  37__u32 uclinux_read32(struct map_info *map, unsigned long ofs)
  38{
  39        return(*((__u32 *) (map->map_priv_1 + ofs)));
  40}
  41
  42void uclinux_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
  43{
  44        memcpy(to, (void *)(map->map_priv_1 + from), len);
  45}
  46
  47void uclinux_write8(struct map_info *map, __u8 d, unsigned long adr)
  48{
  49        *((__u8 *) (map->map_priv_1 + adr)) = d;
  50}
  51
  52void uclinux_write16(struct map_info *map, __u16 d, unsigned long adr)
  53{
  54        *((__u16 *) (map->map_priv_1 + adr)) = d;
  55}
  56
  57void uclinux_write32(struct map_info *map, __u32 d, unsigned long adr)
  58{
  59        *((__u32 *) (map->map_priv_1 + adr)) = d;
  60}
  61
  62void uclinux_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
  63{
  64        memcpy((void *) (map->map_priv_1 + to), from, len);
  65}
  66
  67/****************************************************************************/
  68
  69struct map_info uclinux_ram_map = {
  70        name:           "RAM",
  71        read8:          uclinux_read8,
  72        read16:         uclinux_read16,
  73        read32:         uclinux_read32,
  74        copy_from:      uclinux_copy_from,
  75        write8:         uclinux_write8,
  76        write16:        uclinux_write16,
  77        write32:        uclinux_write32,
  78        copy_to:        uclinux_copy_to,
  79};
  80
  81struct mtd_info *uclinux_ram_mtdinfo;
  82
  83/****************************************************************************/
  84
  85struct mtd_partition uclinux_romfs[] = {
  86        { name: "ROMfs", offset: 0 }
  87};
  88
  89#define NUM_PARTITIONS  (sizeof(uclinux_romfs) / sizeof(uclinux_romfs[0]))
  90
  91/****************************************************************************/
  92
  93int uclinux_point(struct mtd_info *mtd, loff_t from, size_t len,
  94        size_t *retlen, u_char **mtdbuf)
  95{
  96        struct map_info *map = (struct map_info *) mtd->priv;
  97        *mtdbuf = (u_char *) (map->map_priv_1 + ((int) from));
  98        *retlen = len;
  99        return(0);
 100}
 101
 102/****************************************************************************/
 103
 104int __init uclinux_mtd_init(void)
 105{
 106        struct mtd_info *mtd;
 107        struct map_info *mapp;
 108        extern char _ebss;
 109
 110        mapp = &uclinux_ram_map;
 111        mapp->map_priv_2 = (unsigned long) &_ebss;
 112        mapp->size = PAGE_ALIGN(*((unsigned long *)((&_ebss) + 8)));
 113        mapp->buswidth = 4;
 114
 115        printk("uclinux[mtd]: RAM probe address=0x%x size=0x%x\n",
 116                (int) mapp->map_priv_2, (int) mapp->size);
 117
 118        mapp->map_priv_1 = (unsigned long)
 119                ioremap_nocache(mapp->map_priv_2, mapp->size);
 120
 121        if (mapp->map_priv_1 == 0) {
 122                printk("uclinux[mtd]: ioremap_nocache() failed\n");
 123                return(-EIO);
 124        }
 125
 126        mtd = do_map_probe("map_ram", mapp);
 127        if (!mtd) {
 128                printk("uclinux[mtd]: failed to find a mapping?\n");
 129                iounmap((void *) mapp->map_priv_1);
 130                return(-ENXIO);
 131        }
 132                
 133        mtd->module = THIS_MODULE;
 134        mtd->point = uclinux_point;
 135        mtd->priv = mapp;
 136
 137        uclinux_ram_mtdinfo = mtd;
 138        add_mtd_partitions(mtd, uclinux_romfs, NUM_PARTITIONS);
 139
 140        printk("uclinux[mtd]: set %s to be root filesystem\n",
 141                uclinux_romfs[0].name);
 142        ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, 0);
 143        put_mtd_device(mtd);
 144
 145        return(0);
 146}
 147
 148/****************************************************************************/
 149
 150void __exit uclinux_mtd_cleanup(void)
 151{
 152        if (uclinux_ram_mtdinfo) {
 153                del_mtd_partitions(uclinux_ram_mtdinfo);
 154                map_destroy(uclinux_ram_mtdinfo);
 155                uclinux_ram_mtdinfo = NULL;
 156        }
 157        if (uclinux_ram_map.map_priv_1) {
 158                iounmap((void *) uclinux_ram_map.map_priv_1);
 159                uclinux_ram_map.map_priv_1 = 0;
 160        }
 161}
 162
 163/****************************************************************************/
 164
 165module_init(uclinux_mtd_init);
 166module_exit(uclinux_mtd_cleanup);
 167
 168MODULE_LICENSE("GPL");
 169MODULE_AUTHOR("Greg Ungerer <gerg@snapgear.com>");
 170MODULE_DESCRIPTION("Generic RAM based MTD for uClinux");
 171
 172/****************************************************************************/
 173