JFFS for WNR3500Lv2
[tomato.git] / release / src-rt / linux / linux-2.6 / drivers / mtd / maps / bcm947xx-flash.c
blobb88c7f6a9d21775d3e483c9224104beb6fb41dda
1 /*
2 * Flash mapping for BCM947XX boards
4 * Copyright (C) 2009, Broadcom Corporation
5 * All Rights Reserved.
6 *
7 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
8 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
9 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
10 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
12 * $Id: bcm947xx-flash.c,v 1.6 2009/07/27 07:34:33 Exp $
15 #include <linux/module.h>
16 #include <linux/types.h>
17 #include <linux/kernel.h>
18 #include <linux/init.h>
19 #include <asm/io.h>
20 #include <linux/mtd/mtd.h>
21 #include <linux/mtd/map.h>
22 #include <linux/mtd/partitions.h>
23 #include <linux/config.h>
25 #include <typedefs.h>
26 #include <bcmnvram.h>
27 #include <bcmutils.h>
28 #include <hndsoc.h>
29 #include <sbchipc.h>
30 #include <siutils.h>
31 #include <trxhdr.h>
33 /* Global SB handle */
34 extern void *bcm947xx_sih;
35 extern spinlock_t bcm947xx_sih_lock;
37 /* Convenience */
38 #define sih bcm947xx_sih
39 #define sih_lock bcm947xx_sih_lock
41 #ifdef CONFIG_MTD_PARTITIONS
42 extern struct mtd_partition * init_mtd_partitions(struct mtd_info *mtd, size_t size);
43 #endif
45 extern struct mutex *partitions_mutex_init(void);
47 #define WINDOW_ADDR 0x1fc00000
48 #define WINDOW_SIZE 0x400000
49 #define BUSWIDTH 2
51 /* e.g., flash=2M or flash=4M */
52 static int flash = 0;
53 module_param(flash, int, 0);
54 static int __init
55 bcm947xx_setup(char *str)
57 flash = memparse(str, &str);
58 return 1;
60 __setup("flash=", bcm947xx_setup);
62 static struct mtd_info *bcm947xx_mtd;
65 #if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
66 #define init_bcm947xx_map init_module
67 #define cleanup_bcm947xx_map cleanup_module
68 #endif
70 struct map_info bcm947xx_map = {
71 .name = "Physically mapped flash",
72 .size = WINDOW_SIZE,
73 .bankwidth = BUSWIDTH
76 static int __init
77 init_bcm947xx_map(void)
79 ulong flags;
80 uint coreidx;
81 chipcregs_t *cc;
82 uint32 fltype;
83 uint window_addr = 0, window_size = 0;
84 size_t size;
85 int ret = 0;
86 #ifdef CONFIG_MTD_PARTITIONS
87 struct mtd_partition *parts;
88 int i;
89 #endif
91 spin_lock_irqsave(&sih_lock, flags);
92 coreidx = si_coreidx(sih);
94 /* Check strapping option if chipcommon exists */
95 if ((cc = si_setcore(sih, CC_CORE_ID, 0))) {
96 fltype = readl(&cc->capabilities) & CC_CAP_FLASH_MASK;
97 if (fltype == PFLASH) {
98 bcm947xx_map.map_priv_2 = 1;
99 window_addr = 0x1c000000;
100 bcm947xx_map.size = window_size = 32 * 1024 * 1024;
101 if ((readl(&cc->flash_config) & CC_CFG_DS) == 0)
102 bcm947xx_map.bankwidth = 1;
104 } else {
105 fltype = PFLASH;
106 bcm947xx_map.map_priv_2 = 0;
107 window_addr = WINDOW_ADDR;
108 bcm947xx_map.size = window_size = WINDOW_SIZE;
111 si_setcoreidx(sih, coreidx);
112 spin_unlock_irqrestore(&sih_lock, flags);
114 if (fltype != PFLASH) {
115 printk(KERN_ERR "pflash: found no supported devices\n");
116 ret = -ENODEV;
117 goto fail;
120 bcm947xx_map.virt = ioremap(window_addr, window_size);
121 if (bcm947xx_map.virt == NULL) {
122 printk(KERN_ERR "pflash: ioremap failed\n");
123 ret = -EIO;
124 goto fail;
127 if ((bcm947xx_mtd = do_map_probe("cfi_probe", &bcm947xx_map)) == NULL) {
128 printk(KERN_ERR "pflash: cfi_probe failed\n");
129 ret = -ENXIO;
130 goto fail;
133 bcm947xx_mtd->owner = THIS_MODULE;
134 bcm947xx_mtd->mutex = partitions_mutex_init();
136 /* Allow size override for testing */
137 size = flash ? : bcm947xx_mtd->size;
139 printk(KERN_NOTICE "Flash device: 0x%x at 0x%x\n", size, window_addr);
141 #ifdef CONFIG_MTD_PARTITIONS
142 parts = init_mtd_partitions(bcm947xx_mtd, size);
143 for (i = 0; parts[i].name; i++);
144 ret = add_mtd_partitions(bcm947xx_mtd, parts, i);
145 if (ret) {
146 printk(KERN_ERR "pflash: add_mtd_partitions failed\n");
147 goto fail;
149 #endif
151 return 0;
153 fail:
154 if (bcm947xx_mtd)
155 map_destroy(bcm947xx_mtd);
156 if (bcm947xx_map.map_priv_1)
157 iounmap((void *) bcm947xx_map.map_priv_1);
158 bcm947xx_map.map_priv_1 = 0;
159 return ret;
162 static void __exit
163 cleanup_bcm947xx_map(void)
165 #ifdef CONFIG_MTD_PARTITIONS
166 del_mtd_partitions(bcm947xx_mtd);
167 #endif
168 map_destroy(bcm947xx_mtd);
169 iounmap((void *) bcm947xx_map.map_priv_1);
170 bcm947xx_map.map_priv_1 = 0;
173 module_init(init_bcm947xx_map);
174 module_exit(cleanup_bcm947xx_map);