Commit 1fe87cd0 authored by David Woodhouse's avatar David Woodhouse

Fix some accidental regressions which slipped in with the MTD merge.

 - Unrevert strncpy->strlcpy change in JEDEC chip driver
 - Fix partition handling in physmap map driver
 - Switch sa1100-flash map driver back to rmk's version.
parent 63957aaa
......@@ -11,7 +11,7 @@
* not going to guess how to send commands to them, plus I expect they will
* all speak CFI..
*
* $Id: jedec.c,v 1.18 2003/05/28 12:51:48 dwmw2 Exp $
* $Id: jedec.c,v 1.19 2003/05/29 09:25:23 dwmw2 Exp $
*/
#include <linux/init.h>
......@@ -174,8 +174,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
/* Generate a part name that includes the number of different chips and
other configuration information */
count = 1;
strncpy(Part,map->name,sizeof(Part)-10);
Part[sizeof(Part)-11] = 0;
strlcpy(Part,map->name,sizeof(Part)-10);
strcat(Part," ");
Uniq = 0;
for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
......@@ -252,8 +251,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
// printk("Part: '%s'\n",Part);
memset(MTD,0,sizeof(*MTD));
// strncpy(MTD->name,Part,sizeof(MTD->name));
// MTD->name[sizeof(MTD->name)-1] = 0;
// strlcpy(MTD->name,Part,sizeof(MTD->name));
MTD->name = map->name;
MTD->type = MTD_NORFLASH;
MTD->flags = MTD_CAP_NORFLASH;
......
/*
* $Id: physmap.c,v 1.27 2003/05/21 12:45:19 dwmw2 Exp $
* $Id: physmap.c,v 1.29 2003/05/29 09:24:10 dwmw2 Exp $
*
* Normal mappings of chips in physical memory
*/
......@@ -8,6 +8,7 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <asm/io.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
......@@ -59,7 +60,7 @@ static struct mtd_partition physmap_partitions[] = {
};
#define NUM_PARTITIONS (sizeof(physmap_partitions)/sizeof(struct mtd_partition))
const char *part_probes = {"cmdlinepart", "RedBoot", NULL};
const char *part_probes[] = {"cmdlinepart", "RedBoot", NULL};
#endif /* CONFIG_MTD_PARTITIONS */
......
......@@ -3,7 +3,7 @@
*
* (C) 2000 Nicolas Pitre <nico@cam.org>
*
* $Id: sa1100-flash.c,v 1.35 2003/05/21 12:45:19 dwmw2 Exp $
* $Id: sa1100-flash.c,v 1.36 2003/05/29 08:59:35 dwmw2 Exp $
*/
#include <linux/config.h>
......@@ -12,46 +12,50 @@
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/concat.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/io.h>
#include <asm/sizes.h>
#include <asm/arch/h3600.h>
#ifndef CONFIG_ARCH_SA1100
#error This is for SA1100 architecture only
#endif
/*
* This isnt complete yet, so...
*/
#define CONFIG_MTD_SA1100_STATICMAP 1
#define WINDOW_ADDR 0xe8000000
static struct map_info sa1100_map = {
.name = "SA1100 flash",
.virt = WINDOW_ADDR,
.phys = NO_XIP;
};
#ifdef CONFIG_MTD_SA1100_STATICMAP
/*
* Here are partition information for all known SA1100-based devices.
* See include/linux/mtd/partitions.h for definition of the mtd_partition
* structure.
*
* The *_max_flash_size is the maximum possible mapped flash size which
* is not necessarily the actual flash size. It must be no more than
* the value specified in the "struct map_desc *_io_desc" mapping
* definition for the corresponding machine.
* Please note:
* 1. We no longer support static flash mappings via the machine io_desc
* structure.
* 2. The flash size given should be the largest flash size that can
* be accommodated.
*
* The MTD layer will detect flash chip aliasing and reduce the size of
* the map accordingly.
*
* Please keep these in alphabetical order, and formatted as per existing
* entries. Thanks.
*/
#ifdef CONFIG_SA1100_ADSBITSY
#define ADSBITSY_FLASH_SIZE 0x02000000
static struct mtd_partition adsbitsy_partitions[] = {
{
.name = "bootROM",
......@@ -78,7 +82,6 @@ static struct mtd_partition adsbitsy_partitions[] = {
#ifdef CONFIG_SA1100_ASSABET
/* Phase 4 Assabet has two 28F160B3 flash parts in bank 0: */
#define ASSABET4_FLASH_SIZE 0x00400000
static struct mtd_partition assabet4_partitions[] = {
{
.name = "bootloader",
......@@ -98,7 +101,6 @@ static struct mtd_partition assabet4_partitions[] = {
};
/* Phase 5 Assabet has two 28F128J3A flash parts in bank 0: */
#define ASSABET5_FLASH_SIZE 0x02000000
static struct mtd_partition assabet5_partitions[] = {
{
.name = "bootloader",
......@@ -117,18 +119,21 @@ static struct mtd_partition assabet5_partitions[] = {
}
};
#define ASSABET_FLASH_SIZE ASSABET5_FLASH_SIZE
#define assabet_partitions assabet5_partitions
#endif
#ifdef CONFIG_SA1100_BADGE4
/*
* 1 x Intel 28F320C3BA100 Advanced+ Boot Block Flash (32 Mi bit)
* 1 x Intel 28F320C3 Advanced+ Boot Block Flash (32 Mi bit)
* Eight 4 KiW Parameter Bottom Blocks (64 KiB)
* Sixty-three 32 KiW Main Blocks (4032 Ki b)
*
* <or>
*
* 1 x Intel 28F640C3 Advanced+ Boot Block Flash (64 Mi bit)
* Eight 4 KiW Parameter Bottom Blocks (64 KiB)
* One-hundred-twenty-seven 32 KiW Main Blocks (8128 Ki b)
*/
#define BADGE4_FLASH_SIZE 0x00400000
static struct mtd_partition badge4_partitions[] = {
{
.name = "BLOB boot loader",
......@@ -138,23 +143,17 @@ static struct mtd_partition badge4_partitions[] = {
.name = "params",
.offset = MTDPART_OFS_APPEND,
.size = 0x00006000
}, {
.name = "kernel",
.offset = MTDPART_OFS_APPEND,
.size = 0x00100000
}, {
.name = "root",
.offset = MTDPART_OFS_APPEND,
.size = MTDPART_SIZ_FULL
}
};
#endif
#ifdef CONFIG_SA1100_CERF
#ifdef CONFIG_SA1100_CERF_FLASH_32MB
#define CERF_FLASH_SIZE 0x02000000
static struct mtd_partition cerf_partitions[] = {
{
.name = "firmware",
......@@ -175,7 +174,6 @@ static struct mtd_partition cerf_partitions[] = {
}
};
#elif defined CONFIG_SA1100_CERF_FLASH_16MB
#define CERF_FLASH_SIZE 0x01000000
static struct mtd_partition cerf_partitions[] = {
{
.name = "firmware",
......@@ -203,7 +201,6 @@ static struct mtd_partition cerf_partitions[] = {
#endif
#ifdef CONFIG_SA1100_CONSUS
#define CONSUS_FLASH_SIZE 0x02000000
static struct mtd_partition consus_partitions[] = {
{
.name = "Consus boot firmware",
......@@ -289,9 +286,8 @@ static struct mtd_partition flexanet_partitions[] = {
#endif
#ifdef CONFIG_SA1100_FREEBIRD
#define FREEBIRD_FLASH_SIZE 0x02000000
static struct mtd_partition freebird_partitions[] = {
#if CONFIG_SA1100_FREEBIRD_NEW
#ifdef CONFIG_SA1100_FREEBIRD_NEW
{
.name = "firmware",
.size = 0x00040000,
......@@ -342,27 +338,30 @@ static struct mtd_partition freebird_partitions[] = {
#ifdef CONFIG_SA1100_FRODO
/* Frodo has 2 x 16M 28F128J3A flash chips in bank 0: */
#define FRODO_FLASH_SIZE 0x02000000
static struct mtd_partition frodo_partitions[] =
{
{
.name = "Boot Loader",
.name = "bootloader",
.size = 0x00040000,
.offset = 0x00000000
.offset = 0x00000000,
.mask_flags = MTD_WRITEABLE
}, {
.name = "Parameter Block",
.name = "bootloader params",
.size = 0x00040000,
.offset = MTDPART_OFS_APPEND
.offset = MTDPART_OFS_APPEND,
.mask_flags = MTD_WRITEABLE
}, {
.name = "Linux Kernel",
.name = "kernel",
.size = 0x00100000,
.offset = MTDPART_OFS_APPEND
.offset = MTDPART_OFS_APPEND,
.mask_flags = MTD_WRITEABLE
}, {
.name = "Ramdisk",
.size = 0x00680000,
.offset = MTDPART_OFS_APPEND
.name = "ramdisk",
.size = 0x00400000,
.offset = MTDPART_OFS_APPEND,
.mask_flags = MTD_WRITEABLE
}, {
.name = "Flash File System",
.name = "file system",
.size = MTDPART_SIZ_FULL,
.offset = MTDPART_OFS_APPEND
}
......@@ -370,7 +369,6 @@ static struct mtd_partition frodo_partitions[] =
#endif
#ifdef CONFIG_SA1100_GRAPHICSCLIENT
#define GRAPHICSCLIENT_FLASH_SIZE 0x02000000
static struct mtd_partition graphicsclient_partitions[] = {
{
.name = "zImage",
......@@ -391,7 +389,6 @@ static struct mtd_partition graphicsclient_partitions[] = {
#endif
#ifdef CONFIG_SA1100_GRAPHICSMASTER
#define GRAPHICSMASTER_FLASH_SIZE 0x01000000
static struct mtd_partition graphicsmaster_partitions[] = {
{
.name = "zImage",
......@@ -413,55 +410,92 @@ static struct mtd_partition graphicsmaster_partitions[] = {
};
#endif
#ifdef CONFIG_SA1100_H3600
#define H3600_FLASH_SIZE 0x02000000
static struct mtd_partition h3600_partitions[] = {
#ifdef CONFIG_SA1100_H3XXX
static struct mtd_partition h3xxx_partitions[] = {
{
.name = "H3600 boot firmware",
.name = "H3XXX boot firmware",
.size = 0x00040000,
.offset = 0,
.mask_flags = MTD_WRITEABLE, /* force read-only */
}, {
.name = "H3600 kernel",
#ifdef CONFIG_MTD_2PARTS_IPAQ
.name = "H3XXX root jffs2",
.size = MTDPART_SIZ_FULL,
.offset = 0x00040000,
#else
.name = "H3XXX kernel",
.size = 0x00080000,
.offset = 0x00040000,
}, {
.name = "H3600 params",
.name = "H3XXX params",
.size = 0x00040000,
.offset = 0x000C0000,
}, {
#ifdef CONFIG_JFFS2_FS
.name = "H3600 root jffs2",
.name = "H3XXX root jffs2",
.size = MTDPART_SIZ_FULL,
.offset = 0x00100000,
#else
.name = "H3600 initrd",
.name = "H3XXX initrd",
.size = 0x00100000,
.offset = 0x00100000,
}, {
.name = "H3600 root cramfs",
.name = "H3XXX root cramfs",
.size = 0x00300000,
.offset = 0x00200000,
}, {
.name = "H3600 usr cramfs",
.name = "H3XXX usr cramfs",
.size = 0x00800000,
.offset = 0x00500000,
}, {
.name = "H3600 usr local",
.name = "H3XXX usr local",
.size = MTDPART_SIZ_FULL,
.offset = 0x00d00000,
#endif
#endif
}
};
static void h3600_set_vpp(struct map_info *map, int vpp)
static void h3xxx_set_vpp(struct map_info *map, int vpp)
{
assign_h3600_egpio(IPAQ_EGPIO_VPP_ON, vpp);
}
#else
#define h3xxx_set_vpp NULL
#endif
#ifdef CONFIG_SA1100_HACKKIT
static struct mtd_partition hackkit_partitions[] = {
{
.name = "BLOB",
.size = 0x00040000,
.offset = 0x00000000,
.mask_flags = MTD_WRITEABLE, /* force read-only */
}, {
.name = "config",
.size = 0x00040000,
.offset = MTDPART_OFS_APPEND,
}, {
.name = "kernel",
.size = 0x00100000,
.offset = MTDPART_OFS_APPEND,
}, {
.name = "initrd",
.size = 0x00180000,
.offset = MTDPART_OFS_APPEND,
}, {
.name = "rootfs",
.size = 0x700000,
.offset = MTDPART_OFS_APPEND,
}, {
.name = "data",
.size = MTDPART_SIZ_FULL,
.offset = MTDPART_OFS_APPEND,
}
};
#endif
#ifdef CONFIG_SA1100_HUW_WEBPANEL
#define HUW_WEBPANEL_FLASH_SIZE 0x01000000
static struct mtd_partition huw_webpanel_partitions[] = {
{
.name = "Loader",
......@@ -479,7 +513,6 @@ static struct mtd_partition huw_webpanel_partitions[] = {
#endif
#ifdef CONFIG_SA1100_JORNADA720
#define JORNADA720_FLASH_SIZE 0x02000000
static struct mtd_partition jornada720_partitions[] = {
{
.name = "JORNADA720 boot firmware",
......@@ -508,12 +541,12 @@ static struct mtd_partition jornada720_partitions[] = {
.offset = 0x00540000,
}, {
.name = "JORNADA720 usr local",
.size = 0 /* will expand to the end of the flash */
.size = 0, /* will expand to the end of the flash */
.offset = 0x00d00000,
}
};
static void jornada720_set_vpp(int vpp)
static void jornada720_set_vpp(struct map_info *map, int vpp)
{
if (vpp)
PPSR |= 0x80;
......@@ -521,11 +554,11 @@ static void jornada720_set_vpp(int vpp)
PPSR &= ~0x80;
PPDR |= 0x80;
}
#else
#define jornada720_set_vpp NULL
#endif
#ifdef CONFIG_SA1100_PANGOLIN
#define PANGOLIN_FLASH_SIZE 0x04000000
static struct mtd_partition pangolin_partitions[] = {
{
.name = "boot firmware",
......@@ -550,7 +583,6 @@ static struct mtd_partition pangolin_partitions[] = {
#ifdef CONFIG_SA1100_PT_SYSTEM3
/* erase size is 0x40000 == 256k partitions have to have this boundary */
#define SYSTEM3_FLASH_SIZE 0x01000000
static struct mtd_partition system3_partitions[] = {
{
.name = "BLOB",
......@@ -574,7 +606,6 @@ static struct mtd_partition system3_partitions[] = {
#endif
#ifdef CONFIG_SA1100_SHANNON
#define SHANNON_FLASH_SIZE 0x00400000
static struct mtd_partition shannon_partitions[] = {
{
.name = "BLOB boot loader",
......@@ -596,7 +627,6 @@ static struct mtd_partition shannon_partitions[] = {
#endif
#ifdef CONFIG_SA1100_SHERMAN
#define SHERMAN_FLASH_SIZE 0x02000000
static struct mtd_partition sherman_partitions[] = {
{
.size = 0x50000,
......@@ -615,7 +645,6 @@ static struct mtd_partition sherman_partitions[] = {
#endif
#ifdef CONFIG_SA1100_SIMPAD
#define SIMPAD_FLASH_SIZE 0x02000000
static struct mtd_partition simpad_partitions[] = {
{
.name = "SIMpad boot firmware",
......@@ -653,7 +682,6 @@ static struct mtd_partition simpad_partitions[] = {
#endif /* CONFIG_SA1100_SIMPAD */
#ifdef CONFIG_SA1100_STORK
#define STORK_FLASH_SIZE 0x02000000
static struct mtd_partition stork_partitions[] = {
{
.name = "STORK boot firmware",
......@@ -694,8 +722,25 @@ static struct mtd_partition stork_partitions[] = {
};
#endif
#ifdef CONFIG_SA1100_TRIZEPS
static struct mtd_partition trizeps_partitions[] = {
{
.name = "Bootloader",
.size = 0x00100000,
.offset = 0,
}, {
.name = "Kernel",
.size = 0x00100000,
.offset = MTDPART_OFS_APPEND,
}, {
.name = "root",
.size = MTDPART_SIZ_FULL,
.offset = MTDPART_OFS_APPEND,
}
};
#endif
#ifdef CONFIG_SA1100_YOPY
#define YOPY_FLASH_SIZE 0x08000000
static struct mtd_partition yopy_partitions[] = {
{
.name = "boot firmware",
......@@ -718,242 +763,607 @@ static struct mtd_partition yopy_partitions[] = {
};
#endif
static struct mtd_partition *parsed_parts;
static struct mtd_info *mymtd;
static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
int __init sa1100_mtd_init(void)
static int __init sa1100_static_partitions(struct mtd_partition **parts)
{
struct mtd_partition *parts;
int nb_parts = 0, ret;
int parsed_nr_parts = 0;
unsigned long base = -1UL;
/* Default flash buswidth */
sa1100_map.buswidth = (MSC0 & MSC_RBW) ? 2 : 4;
/*
* Static partition definition selection
*/
int nb_parts = 0;
#ifdef CONFIG_SA1100_ADSBITSY
if (machine_is_adsbitsy()) {
parts = adsbitsy_partitions;
*parts = adsbitsy_partitions;
nb_parts = ARRAY_SIZE(adsbitsy_partitions);
sa1100_map.size = ADSBITSY_FLASH_SIZE;
sa1100_map.buswidth = (MSC1 & MSC_RBW) ? 2 : 4;
}
#endif
#ifdef CONFIG_SA1100_ASSABET
if (machine_is_assabet()) {
parts = assabet_partitions;
*parts = assabet_partitions;
nb_parts = ARRAY_SIZE(assabet_partitions);
sa1100_map.size = ASSABET_FLASH_SIZE;
sa1100_map.phys = 0;
}
#endif
#ifdef CONFIG_SA1100_BADGE4
if (machine_is_badge4()) {
parts = badge4_partitions;
*parts = badge4_partitions;
nb_parts = ARRAY_SIZE(badge4_partitions);
sa1100_map.size = BADGE4_FLASH_SIZE;
}
#endif
#ifdef CONFIG_SA1100_CERF
if (machine_is_cerf()) {
parts = cerf_partitions;
*parts = cerf_partitions;
nb_parts = ARRAY_SIZE(cerf_partitions);
sa1100_map.size = CERF_FLASH_SIZE;
}
#endif
#ifdef CONFIG_SA1100_CONSUS
if (machine_is_consus()) {
parts = consus_partitions;
*parts = consus_partitions;
nb_parts = ARRAY_SIZE(consus_partitions);
sa1100_map.size = CONSUS_FLASH_SIZE;
}
#endif
#ifdef CONFIG_SA1100_FLEXANET
if (machine_is_flexanet()) {
parts = flexanet_partitions;
*parts = flexanet_partitions;
nb_parts = ARRAY_SIZE(flexanet_partitions);
sa1100_map.size = FLEXANET_FLASH_SIZE;
}
#endif
#ifdef CONFIG_SA1100_FREEBIRD
if (machine_is_freebird()) {
parts = freebird_partitions;
*parts = freebird_partitions;
nb_parts = ARRAY_SIZE(freebird_partitions);
sa1100_map.size = FREEBIRD_FLASH_SIZE;
}
#endif
#ifdef CONFIG_SA1100_FRODO
if (machine_is_frodo()) {
parts = frodo_partitions;
*parts = frodo_partitions;
nb_parts = ARRAY_SIZE(frodo_partitions);
sa1100_map.size = FRODO_FLASH_SIZE;
base = 0x00000000;
}
#endif
#ifdef CONFIG_SA1100_GRAPHICSCLIENT
if (machine_is_graphicsclient()) {
parts = graphicsclient_partitions;
*parts = graphicsclient_partitions;
nb_parts = ARRAY_SIZE(graphicsclient_partitions);
sa1100_map.size = GRAPHICSCLIENT_FLASH_SIZE;
sa1100_map.buswidth = (MSC1 & MSC_RBW) ? 2:4;
}
#endif
#ifdef CONFIG_SA1100_GRAPHICSMASTER
if (machine_is_graphicsmaster()) {
parts = graphicsmaster_partitions;
*parts = graphicsmaster_partitions;
nb_parts = ARRAY_SIZE(graphicsmaster_partitions);
sa1100_map.size = GRAPHICSMASTER_FLASH_SIZE;
sa1100_map.buswidth = (MSC1 & MSC_RBW) ? 2:4;
}
#endif
#ifdef CONFIG_SA1100_H3600
if (machine_is_h3600()) {
parts = h3600_partitions;
nb_parts = ARRAY_SIZE(h3600_partitions);
sa1100_map.size = H3600_FLASH_SIZE;
sa1100_map.set_vpp = h3600_set_vpp;
sa1100_map.phys = 0;
#ifdef CONFIG_SA1100_H3XXX
if (machine_is_h3xxx()) {
*parts = h3xxx_partitions;
nb_parts = ARRAY_SIZE(h3xxx_partitions);
}
#endif
#ifdef CONFIG_SA1100_HACKKIT
if (machine_is_hackkit()) {
*parts = hackkit_partitions;
nb_parts = ARRAY_SIZE(hackkit_partitions);
}
#endif
#ifdef CONFIG_SA1100_HUW_WEBPANEL
if (machine_is_huw_webpanel()) {
parts = huw_webpanel_partitions;
*parts = huw_webpanel_partitions;
nb_parts = ARRAY_SIZE(huw_webpanel_partitions);
sa1100_map.size = HUW_WEBPANEL_FLASH_SIZE;
}
#endif
#ifdef CONFIG_SA1100_JORNADA720
if (machine_is_jornada720()) {
parts = jornada720_partitions;
*parts = jornada720_partitions;
nb_parts = ARRAY_SIZE(jornada720_partitions);
sa1100_map.size = JORNADA720_FLASH_SIZE;
sa1100_map.set_vpp = jornada720_set_vpp;
}
#endif
#ifdef CONFIG_SA1100_PANGOLIN
if (machine_is_pangolin()) {
parts = pangolin_partitions;
*parts = pangolin_partitions;
nb_parts = ARRAY_SIZE(pangolin_partitions);
sa1100_map.size = PANGOLIN_FLASH_SIZE;
}
#endif
#ifdef CONFIG_SA1100_PT_SYSTEM3
if (machine_is_pt_system3()) {
parts = system3_partitions;
*parts = system3_partitions;
nb_parts = ARRAY_SIZE(system3_partitions);
sa1100_map.size = SYSTEM3_FLASH_SIZE;
}
#endif
#ifdef CONFIG_SA1100_SHANNON
if (machine_is_shannon()) {
parts = shannon_partitions;
*parts = shannon_partitions;
nb_parts = ARRAY_SIZE(shannon_partitions);
sa1100_map.size = SHANNON_FLASH_SIZE;
}
#endif
#ifdef CONFIG_SA1100_SHERMAN
if (machine_is_sherman()) {
parts = sherman_partitions;
*parts = sherman_partitions;
nb_parts = ARRAY_SIZE(sherman_partitions);
sa1100_map.size = SHERMAN_FLASH_SIZE;
}
#endif
#ifdef CONFIG_SA1100_SIMPAD
if (machine_is_simpad()) {
parts = simpad_partitions;
*parts = simpad_partitions;
nb_parts = ARRAY_SIZE(simpad_partitions);
sa1100_map.size = SIMPAD_FLASH_SIZE;
}
#endif
#ifdef CONFIG_SA1100_STORK
if (machine_is_stork()) {
parts = stork_partitions;
*parts = stork_partitions;
nb_parts = ARRAY_SIZE(stork_partitions);
sa1100_map.size = STORK_FLASH_SIZE;
}
#endif
#ifdef CONFIG_SA1100_TRIZEPS
if (machine_is_trizeps()) {
*parts = trizeps_partitions;
nb_parts = ARRAY_SIZE(trizeps_partitions);
}
#endif
#ifdef CONFIG_SA1100_YOPY
if (machine_is_yopy()) {
parts = yopy_partitions;
*parts = yopy_partitions;
nb_parts = ARRAY_SIZE(yopy_partitions);
sa1100_map.size = YOPY_FLASH_SIZE;
}
#endif
return nb_parts;
}
#endif
struct sa_info {
unsigned long base;
unsigned long size;
int width;
void *vbase;
void (*set_vpp)(struct map_info *, int);
struct map_info *map;
struct mtd_info *mtd;
struct resource *res;
};
#define NR_SUBMTD 4
static struct sa_info info[NR_SUBMTD];
static int __init sa1100_setup_mtd(struct sa_info *sa, int nr, struct mtd_info **rmtd)
{
struct mtd_info *subdev[nr];
struct map_info *maps;
int i, found = 0, ret = 0;
/*
* Allocate the map_info structs in one go.
*/
maps = kmalloc(sizeof(struct map_info) * nr, GFP_KERNEL);
if (!maps)
return -ENOMEM;
memset(maps, 0, sizeof(struct map_info) * nr);
/*
* For simple flash devices, use ioremap to map the flash.
* Claim and then map the memory regions.
*/
if (base != -1UL) {
if (!request_mem_region(base, sa1100_map.size, "flash"))
return -EBUSY;
sa1100_map.phys = base;
sa1100_map.virt = (unsigned long)
ioremap(base, sa1100_map.size);
for (i = 0; i < nr; i++) {
if (sa[i].base == (unsigned long)-1)
break;
sa[i].res = request_mem_region(sa[i].base, sa[i].size, "sa1100 flash");
if (!sa[i].res) {
ret = -EBUSY;
break;
}
sa[i].map = maps + i;
sa[i].vbase = ioremap(sa[i].base, sa[i].size);
if (!sa[i].vbase) {
ret = -ENOMEM;
if (!sa1100_map.virt)
goto out_err;
break;
}
sa[i].map->virt = (unsigned long)sa[i].vbase;
sa[i].map->phys = sa[i].base;
sa[i].map->set_vpp = sa[i].set_vpp;
sa[i].map->buswidth = sa[i].width;
sa[i].map->size = sa[i].size;
simple_map_init(sa[i].map);
/*
* Now let's probe for the actual flash. Do it here since
* specific machine settings might have been set above.
*/
printk(KERN_NOTICE "SA1100 flash: probing %d-bit flash bus\n", sa1100_map.buswidth*8);
sa[i].mtd = do_map_probe("cfi_probe", sa[i].map);
if (sa[i].mtd == NULL) {
ret = -ENXIO;
break;
}
sa[i].mtd->owner = THIS_MODULE;
subdev[i] = sa[i].mtd;
simple_map_init(&sa1100_map);
printk(KERN_INFO "SA1100 flash: CFI device at 0x%08lx, %dMiB, "
"%d-bit\n", sa[i].base, sa[i].mtd->size >> 20,
sa[i].width * 8);
found += 1;
}
mymtd = do_map_probe("cfi_probe", &sa1100_map);
/*
* ENXIO is special. It means we didn't find a chip when
* we probed. We need to tear down the mapping, free the
* resource and mark it as such.
*/
if (ret == -ENXIO) {
iounmap(sa[i].vbase);
sa[i].vbase = NULL;
release_resource(sa[i].res);
sa[i].res = NULL;
}
/*
* If we found one device, don't bother with concat support.
* If we found multiple devices, use concat if we have it
* available, otherwise fail.
*/
if (ret == 0 || ret == -ENXIO) {
if (found == 1) {
*rmtd = subdev[0];
ret = 0;
} else if (found > 1) {
/*
* We detected multiple devices. Concatenate
* them together.
*/
#ifdef CONFIG_MTD_CONCAT
*rmtd = mtd_concat_create(subdev, found,
"sa1100 flash");
if (*rmtd == NULL)
ret = -ENXIO;
if (!mymtd)
goto out_err;
mymtd->owner = THIS_MODULE;
#else
printk(KERN_ERR "SA1100 flash: multiple devices "
"found but MTD concat support disabled.\n");
ret = -ENXIO;
#endif
}
}
/*
* Dynamic partition selection stuff (might override the static ones)
* If we failed, clean up.
*/
int ret = parse_mtd_partitions(mymtd, probes, &parsed_parts, 0);
if (ret) {
do {
if (sa[i].mtd)
map_destroy(sa[i].mtd);
if (sa[i].vbase)
iounmap(sa[i].vbase);
if (sa[i].res)
release_resource(sa[i].res);
} while (i--);
kfree(maps);
}
return ret;
}
static void __exit sa1100_destroy_mtd(struct sa_info *sa, struct mtd_info *mtd)
{
int i;
if (ret > 0)
parsed_nr_parts = ret;
del_mtd_partitions(mtd);
if (parsed_nr_parts > 0) {
parts = parsed_parts;
nb_parts = parsed_nr_parts;
#ifdef CONFIG_MTD_CONCAT
if (mtd != sa[0].mtd)
mtd_concat_destroy(mtd);
#endif
for (i = NR_SUBMTD; i >= 0; i--) {
if (sa[i].mtd)
map_destroy(sa[i].mtd);
if (sa[i].vbase)
iounmap(sa[i].vbase);
if (sa[i].res)
release_resource(sa[i].res);
}
kfree(sa[0].map);
}
if (nb_parts == 0) {
printk(KERN_NOTICE "SA1100 flash: no partition info available, registering whole flash at once\n");
add_mtd_device(mymtd);
} else {
add_mtd_partitions(mymtd, parts, nb_parts);
/*
* A Thought: can we automatically detect the flash?
* - Check to see if the region is busy (yes -> failure)
* - Is the MSC setup for flash (no -> failure)
* - Probe for flash
*/
static struct map_info sa1100_probe_map __initdata = {
.name = "SA1100-flash",
};
static void __init sa1100_probe_one_cs(unsigned int msc, unsigned long phys)
{
struct mtd_info *mtd;
printk(KERN_INFO "* Probing 0x%08lx: MSC = 0x%04x %d bit ",
phys, msc & 0xffff, msc & MSC_RBW ? 16 : 32);
if (check_mem_region(phys, 0x08000000)) {
printk("busy\n");
return;
}
return 0;
out_err:
if (sa1100_map.virt != WINDOW_ADDR) {
iounmap((void *)sa1100_map.virt);
release_mem_region(sa1100_map.phys, sa1100_map.size);
if ((msc & 3) == 1) {
printk("wrong type\n");
return;
}
return ret;
sa1100_probe_map.buswidth = msc & MSC_RBW ? 2 : 4;
sa1100_probe_map.size = SZ_1M;
sa1100_probe_map.phys = phys;
sa1100_probe_map.virt = (unsigned long)ioremap(phys, SZ_1M);
if (sa1100_probe_map.virt == 0)
goto fail;
simple_map_init(&sa1100_probe_map);
/* Shame cfi_probe blurts out kernel messages... */
mtd = do_map_probe("cfi_probe", &sa1100_probe_map);
if (mtd)
map_destroy(mtd);
iounmap((void *)sa1100_probe_map.virt);
if (!mtd)
goto fail;
printk("pass\n");
return;
fail:
printk("failed\n");
}
static void __exit sa1100_mtd_cleanup(void)
static void __init sa1100_probe_flash(void)
{
if (mymtd) {
del_mtd_partitions(mymtd);
map_destroy(mymtd);
if (parsed_parts)
kfree(parsed_parts);
printk(KERN_INFO "-- SA11xx Flash probe. Please report results.\n");
sa1100_probe_one_cs(MSC0, SA1100_CS0_PHYS);
sa1100_probe_one_cs(MSC0 >> 16, SA1100_CS1_PHYS);
sa1100_probe_one_cs(MSC1, SA1100_CS2_PHYS);
sa1100_probe_one_cs(MSC1 >> 16, SA1100_CS3_PHYS);
sa1100_probe_one_cs(MSC2, SA1100_CS4_PHYS);
sa1100_probe_one_cs(MSC2 >> 16, SA1100_CS5_PHYS);
printk(KERN_INFO "-- SA11xx Flash probe complete.\n");
}
static int __init sa1100_locate_flash(void)
{
int i, nr = -ENODEV;
sa1100_probe_flash();
if (machine_is_adsbitsy()) {
info[0].base = SA1100_CS1_PHYS;
info[0].size = SZ_32M;
nr = 1;
}
if (machine_is_assabet()) {
info[0].base = SA1100_CS0_PHYS;
info[0].size = SZ_32M;
info[1].base = SA1100_CS1_PHYS; /* neponset */
info[1].size = SZ_32M;
nr = 2;
}
if (machine_is_badge4()) {
info[0].base = SA1100_CS0_PHYS;
info[0].size = SZ_64M;
nr = 1;
}
if (machine_is_cerf()) {
info[0].base = SA1100_CS0_PHYS;
info[0].size = SZ_32M;
nr = 1;
}
if (machine_is_consus()) {
info[0].base = SA1100_CS0_PHYS;
info[0].size = SZ_32M;
nr = 1;
}
if (machine_is_flexanet()) {
info[0].base = SA1100_CS0_PHYS;
info[0].size = SZ_32M;
nr = 1;
}
if (sa1100_map.virt != WINDOW_ADDR) {
iounmap((void *)sa1100_map.virt);
release_mem_region(sa1100_map.phys, sa1100_map.size);
if (machine_is_freebird()) {
info[0].base = SA1100_CS0_PHYS;
info[0].size = SZ_32M;
nr = 1;
}
if (machine_is_frodo()) {
info[0].base = SA1100_CS0_PHYS;
info[0].size = SZ_32M;
nr = 1;
}
if (machine_is_graphicsclient()) {
info[0].base = SA1100_CS1_PHYS;
info[0].size = SZ_32M;
nr = 1;
}
if (machine_is_graphicsmaster()) {
info[0].base = SA1100_CS1_PHYS;
info[0].size = SZ_16M;
nr = 1;
}
if (machine_is_h3xxx()) {
info[0].set_vpp = h3xxx_set_vpp;
info[0].base = SA1100_CS0_PHYS;
info[0].size = SZ_32M;
nr = 1;
}
if (machine_is_huw_webpanel()) {
info[0].base = SA1100_CS0_PHYS;
info[0].size = SZ_16M;
nr = 1;
}
if (machine_is_itsy()) {
info[0].base = SA1100_CS0_PHYS;
info[0].size = SZ_32M;
nr = 1;
}
if (machine_is_jornada720()) {
info[0].set_vpp = jornada720_set_vpp;
info[0].base = SA1100_CS0_PHYS;
info[0].size = SZ_32M;
nr = 1;
}
if (machine_is_nanoengine()) {
info[0].base = SA1100_CS0_PHYS;
info[1].size = SZ_32M;
nr = 1;
}
if (machine_is_pangolin()) {
info[0].base = SA1100_CS0_PHYS;
info[0].size = SZ_64M;
nr = 1;
}
if (machine_is_pfs168()) {
info[0].base = SA1100_CS0_PHYS;
info[0].size = SZ_32M;
nr = 1;
}
if (machine_is_pleb()) {
info[0].base = SA1100_CS0_PHYS;
info[0].size = SZ_4M;
info[1].base = SA1100_CS1_PHYS;
info[1].size = SZ_4M;
nr = 2;
}
if (machine_is_pt_system3()) {
info[0].base = SA1100_CS0_PHYS;
info[0].size = SZ_16M;
nr = 1;
}
if (machine_is_shannon()) {
info[0].base = SA1100_CS0_PHYS;
info[0].size = SZ_4M;
nr = 1;
}
if (machine_is_sherman()) {
info[0].base = SA1100_CS0_PHYS;
info[0].size = SZ_32M;
nr = 1;
}
if (machine_is_simpad()) {
info[0].base = SA1100_CS0_PHYS;
info[0].size = SZ_32M;
nr = 1;
}
if (machine_is_stork()) {
info[0].base = SA1100_CS0_PHYS;
info[0].size = SZ_32M;
nr = 1;
}
if (machine_is_trizeps()) {
info[0].base = SA1100_CS0_PHYS;
info[0].size = SZ_16M;
nr = 1;
}
if (machine_is_victor()) {
info[0].base = SA1100_CS0_PHYS;
info[0].size = SZ_2M;
nr = 1;
}
if (machine_is_yopy()) {
info[0].base = SA1100_CS0_PHYS;
info[0].size = SZ_64M;
info[1].base = SA1100_CS1_PHYS;
info[1].size = SZ_64M;
nr = 2;
}
if (nr < 0)
return nr;
/*
* Retrieve the buswidth from the MSC registers.
* We currently only implement CS0 and CS1 here.
*/
for (i = 0; i < nr; i++) {
switch (info[i].base) {
default:
printk(KERN_WARNING "SA1100 flash: unknown base address "
"0x%08lx, assuming CS0\n", info[i].base);
case SA1100_CS0_PHYS:
info[i].width = (MSC0 & MSC_RBW) ? 2 : 4;
break;
case SA1100_CS1_PHYS:
info[i].width = ((MSC0 >> 16) & MSC_RBW) ? 2 : 4;
break;
}
}
return nr;
}
static struct mtd_partition *parsed_parts;
const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL };
static void __init sa1100_locate_partitions(struct mtd_info *mtd)
{
const char *part_type = NULL;
int nr_parts = 0;
do {
/*
* Partition selection stuff.
*/
#ifdef CONFIG_MTD_PARTITIONS
nr_parts = parse_mtd_partitions(mtd, part_probes, &parsed_parts, 0);
if (nr_parts > 0) {
part_type = "dynamic";
break;
}
#endif
#ifdef CONFIG_MTD_SA1100_STATICMAP
nr_parts = sa1100_static_partitions(&parsed_parts);
if (nr_parts > 0) {
part_type = "static";
break;
}
#endif
} while (0);
if (nr_parts == 0) {
printk(KERN_NOTICE "SA1100 flash: no partition info "
"available, registering whole flash\n");
add_mtd_device(mtd);
} else {
printk(KERN_NOTICE "SA1100 flash: using %s partition "
"definition\n", part_type);
add_mtd_partitions(mtd, parsed_parts, nr_parts);
}
/* Always succeeds. */
}
static void __exit sa1100_destroy_partitions(void)
{
if (parsed_parts)
kfree(parsed_parts);
}
static struct mtd_info *mymtd;
static int __init sa1100_mtd_init(void)
{
int ret;
int nr;
nr = sa1100_locate_flash();
if (nr < 0)
return nr;
ret = sa1100_setup_mtd(info, nr, &mymtd);
if (ret == 0)
sa1100_locate_partitions(mymtd);
return ret;
}
static void __exit sa1100_mtd_cleanup(void)
{
sa1100_destroy_mtd(info, mymtd);
sa1100_destroy_partitions();
}
module_init(sa1100_mtd_init);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment