Broadcom SDK and wireless driver: another attempt to update to ver. 5.10.147.0
[tomato.git] / release / src-rt / linux / linux-2.6 / drivers / mtd / maps / bcm947xx-flash.c
blobe1b2a4135fb576f478d08501ce8843eb56363969
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 #define WINDOW_ADDR 0x1fc00000
46 #define WINDOW_SIZE 0x400000
47 #define BUSWIDTH 2
49 /* e.g., flash=2M or flash=4M */
50 static int flash = 0;
51 module_param(flash, int, 0);
52 static int __init
53 bcm947xx_setup(char *str)
55 flash = memparse(str, &str);
56 return 1;
58 __setup("flash=", bcm947xx_setup);
60 static struct mtd_info *bcm947xx_mtd;
63 #if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
64 #define init_bcm947xx_map init_module
65 #define cleanup_bcm947xx_map cleanup_module
66 #endif
68 struct map_info bcm947xx_map = {
69 .name = "Physically mapped flash",
70 .size = WINDOW_SIZE,
71 .bankwidth = BUSWIDTH
74 static int __init
75 init_bcm947xx_map(void)
77 ulong flags;
78 uint coreidx;
79 chipcregs_t *cc;
80 uint32 fltype;
81 uint window_addr = 0, window_size = 0;
82 size_t size;
83 int ret = 0;
84 #ifdef CONFIG_MTD_PARTITIONS
85 struct mtd_partition *parts;
86 int i;
87 #endif
89 spin_lock_irqsave(&sih_lock, flags);
90 coreidx = si_coreidx(sih);
92 /* Check strapping option if chipcommon exists */
93 if ((cc = si_setcore(sih, CC_CORE_ID, 0))) {
94 fltype = readl(&cc->capabilities) & CC_CAP_FLASH_MASK;
95 if (fltype == PFLASH) {
96 bcm947xx_map.map_priv_2 = 1;
97 window_addr = 0x1c000000;
98 bcm947xx_map.size = window_size = 32 * 1024 * 1024;
99 if ((readl(&cc->flash_config) & CC_CFG_DS) == 0)
100 bcm947xx_map.bankwidth = 1;
102 } else {
103 fltype = PFLASH;
104 bcm947xx_map.map_priv_2 = 0;
105 window_addr = WINDOW_ADDR;
106 bcm947xx_map.size = window_size = WINDOW_SIZE;
109 si_setcoreidx(sih, coreidx);
110 spin_unlock_irqrestore(&sih_lock, flags);
112 if (fltype != PFLASH) {
113 printk(KERN_ERR "pflash: found no supported devices\n");
114 ret = -ENODEV;
115 goto fail;
118 bcm947xx_map.virt = ioremap(window_addr, window_size);
119 if (bcm947xx_map.virt == NULL) {
120 printk(KERN_ERR "pflash: ioremap failed\n");
121 ret = -EIO;
122 goto fail;
125 if ((bcm947xx_mtd = do_map_probe("cfi_probe", &bcm947xx_map)) == NULL) {
126 printk(KERN_ERR "pflash: cfi_probe failed\n");
127 ret = -ENXIO;
128 goto fail;
131 bcm947xx_mtd->owner = THIS_MODULE;
133 /* Allow size override for testing */
134 size = flash ? : bcm947xx_mtd->size;
136 printk(KERN_NOTICE "Flash device: 0x%x at 0x%x\n", size, window_addr);
138 #ifdef CONFIG_MTD_PARTITIONS
139 parts = init_mtd_partitions(bcm947xx_mtd, size);
140 for (i = 0; parts[i].name; i++);
141 ret = add_mtd_partitions(bcm947xx_mtd, parts, i);
142 if (ret) {
143 printk(KERN_ERR "pflash: add_mtd_partitions failed\n");
144 goto fail;
146 #endif
148 return 0;
150 fail:
151 if (bcm947xx_mtd)
152 map_destroy(bcm947xx_mtd);
153 if (bcm947xx_map.map_priv_1)
154 iounmap((void *) bcm947xx_map.map_priv_1);
155 bcm947xx_map.map_priv_1 = 0;
156 return ret;
159 static void __exit
160 cleanup_bcm947xx_map(void)
162 #ifdef CONFIG_MTD_PARTITIONS
163 del_mtd_partitions(bcm947xx_mtd);
164 #endif
165 map_destroy(bcm947xx_mtd);
166 iounmap((void *) bcm947xx_map.map_priv_1);
167 bcm947xx_map.map_priv_1 = 0;
170 module_init(init_bcm947xx_map);
171 module_exit(cleanup_bcm947xx_map);