Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * tsunami_flash.c
0004  *
0005  * flash chip on alpha ds10...
0006  */
0007 #include <asm/io.h>
0008 #include <asm/core_tsunami.h>
0009 #include <linux/init.h>
0010 #include <linux/mtd/map.h>
0011 #include <linux/mtd/mtd.h>
0012 
0013 #define FLASH_ENABLE_PORT 0x00C00001
0014 #define FLASH_ENABLE_BYTE 0x01
0015 #define FLASH_DISABLE_BYTE 0x00
0016 
0017 #define MAX_TIG_FLASH_SIZE (12*1024*1024)
0018 static inline map_word tsunami_flash_read8(struct map_info *map, unsigned long offset)
0019 {
0020     map_word val;
0021     val.x[0] = tsunami_tig_readb(offset);
0022     return val;
0023 }
0024 
0025 static void tsunami_flash_write8(struct map_info *map, map_word value, unsigned long offset)
0026 {
0027     tsunami_tig_writeb(value.x[0], offset);
0028 }
0029 
0030 static void tsunami_flash_copy_from(
0031     struct map_info *map, void *addr, unsigned long offset, ssize_t len)
0032 {
0033     unsigned char *dest;
0034     dest = addr;
0035     while(len && (offset < MAX_TIG_FLASH_SIZE)) {
0036         *dest = tsunami_tig_readb(offset);
0037         offset++;
0038         dest++;
0039         len--;
0040     }
0041 }
0042 
0043 static void tsunami_flash_copy_to(
0044     struct map_info *map, unsigned long offset,
0045     const void *addr, ssize_t len)
0046 {
0047     const unsigned char *src;
0048     src = addr;
0049     while(len && (offset < MAX_TIG_FLASH_SIZE)) {
0050         tsunami_tig_writeb(*src, offset);
0051         offset++;
0052         src++;
0053         len--;
0054     }
0055 }
0056 
0057 /*
0058  * Deliberately don't provide operations wider than 8 bits.  I don't
0059  * have then and it scares me to think how you could mess up if
0060  * you tried to use them.   Buswidth is correctly so I'm safe.
0061  */
0062 static struct map_info tsunami_flash_map = {
0063     .name = "flash chip on the Tsunami TIG bus",
0064     .size = MAX_TIG_FLASH_SIZE,
0065     .phys = NO_XIP,
0066     .bankwidth = 1,
0067     .read = tsunami_flash_read8,
0068     .copy_from = tsunami_flash_copy_from,
0069     .write = tsunami_flash_write8,
0070     .copy_to = tsunami_flash_copy_to,
0071 };
0072 
0073 static struct mtd_info *tsunami_flash_mtd;
0074 
0075 static void __exit  cleanup_tsunami_flash(void)
0076 {
0077     struct mtd_info *mtd;
0078     mtd = tsunami_flash_mtd;
0079     if (mtd) {
0080         mtd_device_unregister(mtd);
0081         map_destroy(mtd);
0082     }
0083     tsunami_flash_mtd = 0;
0084 }
0085 
0086 static const char * const rom_probe_types[] = {
0087     "cfi_probe", "jedec_probe", "map_rom", NULL };
0088 
0089 static int __init init_tsunami_flash(void)
0090 {
0091     const char * const *type;
0092 
0093     tsunami_tig_writeb(FLASH_ENABLE_BYTE, FLASH_ENABLE_PORT);
0094 
0095     tsunami_flash_mtd = 0;
0096     type = rom_probe_types;
0097     for(; !tsunami_flash_mtd && *type; type++) {
0098         tsunami_flash_mtd = do_map_probe(*type, &tsunami_flash_map);
0099     }
0100     if (tsunami_flash_mtd) {
0101         tsunami_flash_mtd->owner = THIS_MODULE;
0102         mtd_device_register(tsunami_flash_mtd, NULL, 0);
0103         return 0;
0104     }
0105     return -ENXIO;
0106 }
0107 
0108 module_init(init_tsunami_flash);
0109 module_exit(cleanup_tsunami_flash);