2 * Flash mapping for BCM947XX boards
4 * Copyright (C) 2009, Broadcom Corporation
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>
20 #include <linux/mtd/mtd.h>
21 #include <linux/mtd/map.h>
22 #include <linux/mtd/partitions.h>
23 #include <linux/config.h>
33 /* Global SB handle */
34 extern void *bcm947xx_sih
;
35 extern spinlock_t bcm947xx_sih_lock
;
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
);
45 #define WINDOW_ADDR 0x1fc00000
46 #define WINDOW_SIZE 0x400000
49 /* e.g., flash=2M or flash=4M */
51 module_param(flash
, int, 0);
53 bcm947xx_setup(char *str
)
55 flash
= memparse(str
, &str
);
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
68 struct map_info bcm947xx_map
= {
69 .name
= "Physically mapped flash",
75 init_bcm947xx_map(void)
81 uint window_addr
= 0, window_size
= 0;
84 #ifdef CONFIG_MTD_PARTITIONS
85 struct mtd_partition
*parts
;
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;
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");
118 bcm947xx_map
.virt
= ioremap(window_addr
, window_size
);
119 if (bcm947xx_map
.virt
== NULL
) {
120 printk(KERN_ERR
"pflash: ioremap failed\n");
125 if ((bcm947xx_mtd
= do_map_probe("cfi_probe", &bcm947xx_map
)) == NULL
) {
126 printk(KERN_ERR
"pflash: cfi_probe failed\n");
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
);
143 printk(KERN_ERR
"pflash: add_mtd_partitions failed\n");
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;
160 cleanup_bcm947xx_map(void)
162 #ifdef CONFIG_MTD_PARTITIONS
163 del_mtd_partitions(bcm947xx_mtd
);
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
);