18c2ecf20Sopenharmony_ci/****************************************************************************/ 28c2ecf20Sopenharmony_ci 38c2ecf20Sopenharmony_ci/* 48c2ecf20Sopenharmony_ci * uclinux.c -- generic memory mapped MTD driver for uclinux 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com) 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * License: GPL 98c2ecf20Sopenharmony_ci */ 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci/****************************************************************************/ 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#include <linux/moduleparam.h> 148c2ecf20Sopenharmony_ci#include <linux/types.h> 158c2ecf20Sopenharmony_ci#include <linux/init.h> 168c2ecf20Sopenharmony_ci#include <linux/kernel.h> 178c2ecf20Sopenharmony_ci#include <linux/fs.h> 188c2ecf20Sopenharmony_ci#include <linux/mm.h> 198c2ecf20Sopenharmony_ci#include <linux/major.h> 208c2ecf20Sopenharmony_ci#include <linux/mtd/mtd.h> 218c2ecf20Sopenharmony_ci#include <linux/mtd/map.h> 228c2ecf20Sopenharmony_ci#include <linux/mtd/partitions.h> 238c2ecf20Sopenharmony_ci#include <asm/io.h> 248c2ecf20Sopenharmony_ci#include <asm/sections.h> 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci/****************************************************************************/ 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci#ifdef CONFIG_MTD_ROM 298c2ecf20Sopenharmony_ci#define MAP_NAME "rom" 308c2ecf20Sopenharmony_ci#else 318c2ecf20Sopenharmony_ci#define MAP_NAME "ram" 328c2ecf20Sopenharmony_ci#endif 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_cistatic struct map_info uclinux_ram_map = { 358c2ecf20Sopenharmony_ci .name = MAP_NAME, 368c2ecf20Sopenharmony_ci .size = 0, 378c2ecf20Sopenharmony_ci}; 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_cistatic unsigned long physaddr = -1; 408c2ecf20Sopenharmony_cimodule_param(physaddr, ulong, S_IRUGO); 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_cistatic struct mtd_info *uclinux_ram_mtdinfo; 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci/****************************************************************************/ 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_cistatic const struct mtd_partition uclinux_romfs[] = { 478c2ecf20Sopenharmony_ci { .name = "ROMfs" } 488c2ecf20Sopenharmony_ci}; 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci#define NUM_PARTITIONS ARRAY_SIZE(uclinux_romfs) 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci/****************************************************************************/ 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_cistatic int uclinux_point(struct mtd_info *mtd, loff_t from, size_t len, 558c2ecf20Sopenharmony_ci size_t *retlen, void **virt, resource_size_t *phys) 568c2ecf20Sopenharmony_ci{ 578c2ecf20Sopenharmony_ci struct map_info *map = mtd->priv; 588c2ecf20Sopenharmony_ci *virt = map->virt + from; 598c2ecf20Sopenharmony_ci if (phys) 608c2ecf20Sopenharmony_ci *phys = map->phys + from; 618c2ecf20Sopenharmony_ci *retlen = len; 628c2ecf20Sopenharmony_ci return(0); 638c2ecf20Sopenharmony_ci} 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci/****************************************************************************/ 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_cistatic int __init uclinux_mtd_init(void) 688c2ecf20Sopenharmony_ci{ 698c2ecf20Sopenharmony_ci struct mtd_info *mtd; 708c2ecf20Sopenharmony_ci struct map_info *mapp; 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci mapp = &uclinux_ram_map; 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci if (physaddr == -1) 758c2ecf20Sopenharmony_ci mapp->phys = (resource_size_t)__bss_stop; 768c2ecf20Sopenharmony_ci else 778c2ecf20Sopenharmony_ci mapp->phys = physaddr; 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci if (!mapp->size) 808c2ecf20Sopenharmony_ci mapp->size = PAGE_ALIGN(ntohl(*((unsigned long *)(mapp->phys + 8)))); 818c2ecf20Sopenharmony_ci mapp->bankwidth = 4; 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci printk("uclinux[mtd]: probe address=0x%x size=0x%x\n", 848c2ecf20Sopenharmony_ci (int) mapp->phys, (int) mapp->size); 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci /* 878c2ecf20Sopenharmony_ci * The filesystem is guaranteed to be in direct mapped memory. It is 888c2ecf20Sopenharmony_ci * directly following the kernels own bss region. Following the same 898c2ecf20Sopenharmony_ci * mechanism used by architectures setting up traditional initrds we 908c2ecf20Sopenharmony_ci * use phys_to_virt to get the virtual address of its start. 918c2ecf20Sopenharmony_ci */ 928c2ecf20Sopenharmony_ci mapp->virt = phys_to_virt(mapp->phys); 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci if (mapp->virt == 0) { 958c2ecf20Sopenharmony_ci printk("uclinux[mtd]: no virtual mapping?\n"); 968c2ecf20Sopenharmony_ci return(-EIO); 978c2ecf20Sopenharmony_ci } 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ci simple_map_init(mapp); 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci mtd = do_map_probe("map_" MAP_NAME, mapp); 1028c2ecf20Sopenharmony_ci if (!mtd) { 1038c2ecf20Sopenharmony_ci printk("uclinux[mtd]: failed to find a mapping?\n"); 1048c2ecf20Sopenharmony_ci return(-ENXIO); 1058c2ecf20Sopenharmony_ci } 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ci mtd->owner = THIS_MODULE; 1088c2ecf20Sopenharmony_ci mtd->_point = uclinux_point; 1098c2ecf20Sopenharmony_ci mtd->priv = mapp; 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci uclinux_ram_mtdinfo = mtd; 1128c2ecf20Sopenharmony_ci mtd_device_register(mtd, uclinux_romfs, NUM_PARTITIONS); 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ci return(0); 1158c2ecf20Sopenharmony_ci} 1168c2ecf20Sopenharmony_cidevice_initcall(uclinux_mtd_init); 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci/****************************************************************************/ 119