/*
* Flash memory access on SA11x0 based devices
- *
+ *
* (C) 2000 Nicolas Pitre <nico@cam.org>
- *
- * $Id: sa1100-flash.c,v 1.36 2003/05/29 08:59:35 dwmw2 Exp $
+ *
+ * $Id: sa1100-flash.c,v 1.51 2005/11/07 11:14:28 gleixner Exp $
*/
-
#include <linux/config.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.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/mach/flash.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
-
-#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.
- *
- * 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
-static struct mtd_partition adsbitsy_partitions[] = {
- {
- .name = "bootROM",
- .size = 0x80000,
- .offset = 0,
- .mask_flags = MTD_WRITEABLE, /* force read-only */
- }, {
- .name = "zImage",
- .size = 0x100000,
- .offset = MTDPART_OFS_APPEND,
- .mask_flags = MTD_WRITEABLE, /* force read-only */
- }, {
- .name = "ramdisk.gz",
- .size = 0x300000,
- .offset = MTDPART_OFS_APPEND,
- .mask_flags = MTD_WRITEABLE, /* force read-only */
- }, {
- .name = "User FS",
- .size = MTDPART_SIZ_FULL,
- .offset = MTDPART_OFS_APPEND,
- }
-};
-#endif
-
-#ifdef CONFIG_SA1100_ASSABET
-/* Phase 4 Assabet has two 28F160B3 flash parts in bank 0: */
-static struct mtd_partition assabet4_partitions[] = {
- {
- .name = "bootloader",
- .size = 0x00020000,
- .offset = 0,
- .mask_flags = MTD_WRITEABLE,
- }, {
- .name = "bootloader params",
- .size = 0x00020000,
- .offset = MTDPART_OFS_APPEND,
- .mask_flags = MTD_WRITEABLE,
- }, {
- .name = "jffs",
- .size = MTDPART_SIZ_FULL,
- .offset = MTDPART_OFS_APPEND,
- }
-};
-
-/* Phase 5 Assabet has two 28F128J3A flash parts in bank 0: */
-static struct mtd_partition assabet5_partitions[] = {
- {
- .name = "bootloader",
- .size = 0x00040000,
- .offset = 0,
- .mask_flags = MTD_WRITEABLE,
- }, {
- .name = "bootloader params",
- .size = 0x00040000,
- .offset = MTDPART_OFS_APPEND,
- .mask_flags = MTD_WRITEABLE,
- }, {
- .name = "jffs",
- .size = MTDPART_SIZ_FULL,
- .offset = MTDPART_OFS_APPEND,
- }
-};
-
-#define assabet_partitions assabet5_partitions
-#endif
-
-#ifdef CONFIG_SA1100_BADGE4
+#if 0
/*
- * 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)
+ * This is here for documentation purposes only - until these people
+ * submit their machine types. It will be gone January 2005.
*/
-static struct mtd_partition badge4_partitions[] = {
- {
- .name = "BLOB boot loader",
- .offset = 0,
- .size = 0x0000A000
- }, {
- .name = "params",
- .offset = MTDPART_OFS_APPEND,
- .size = 0x00006000
- }, {
- .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
-#elif defined CONFIG_SA1100_CERF_FLASH_16MB
-# define CERF_FLASH_SIZE 0x01000000
-#elif defined CONFIG_SA1100_CERF_FLASH_8MB
-# define CERF_FLASH_SIZE 0x00800000
-#else
-# error "Undefined flash size for CERF in sa1100-flash.c"
-#endif
-
-static struct mtd_partition cerf_partitions[] = {
- {
- .name = "Bootloader",
- .size = 0x00020000,
- .offset = 0x00000000,
- }, {
- .name = "Params",
- .size = 0x00040000,
- .offset = 0x00020000,
- }, {
- .name = "Kernel",
- .size = 0x00100000,
- .offset = 0x00060000,
- }, {
- .name = "Filesystem",
- .size = CERF_FLASH_SIZE-0x00160000,
- .offset = 0x00160000,
- }
-};
-#endif
-
-#ifdef CONFIG_SA1100_CONSUS
static struct mtd_partition consus_partitions[] = {
{
.name = "Consus boot firmware",
make it find the size automatically, but right now
i have 32 megs. jffs will use all 32 megs if given
the chance, and this leads to horrible problems
- when you try to re-flash the image because blob
- won't erase the whole partition. */
- .size = 0x01000000 - 0x00140000,
- .mask_flags = 0,
- }, {
- /* this disk is a secondary disk, which can be used as
- needed, for simplicity, make it the size of the other
- consus partition, although realistically it could be
- the remainder of the disk (depending on the file
- system used) */
- .name = "Consus disk2",
- .offset = 0x01000000,
- .size = 0x01000000 - 0x00140000,
- .mask_flags = 0,
- }
-};
-#endif
-
-#ifdef CONFIG_SA1100_FLEXANET
-/* Flexanet has two 28F128J3A flash parts in bank 0: */
-#define FLEXANET_FLASH_SIZE 0x02000000
-static struct mtd_partition flexanet_partitions[] = {
- {
- .name = "bootloader",
- .size = 0x00040000,
- .offset = 0,
- .mask_flags = MTD_WRITEABLE,
- }, {
- .name = "bootloader params",
- .size = 0x00040000,
- .offset = MTDPART_OFS_APPEND,
- .mask_flags = MTD_WRITEABLE,
- }, {
- .name = "kernel",
- .size = 0x000C0000,
- .offset = MTDPART_OFS_APPEND,
- .mask_flags = MTD_WRITEABLE,
- }, {
- .name = "altkernel",
- .size = 0x000C0000,
- .offset = MTDPART_OFS_APPEND,
- .mask_flags = MTD_WRITEABLE,
- }, {
- .name = "root",
- .size = 0x00400000,
- .offset = MTDPART_OFS_APPEND,
- .mask_flags = MTD_WRITEABLE,
- }, {
- .name = "free1",
- .size = 0x00300000,
- .offset = MTDPART_OFS_APPEND,
- .mask_flags = MTD_WRITEABLE,
- }, {
- .name = "free2",
- .size = 0x00300000,
- .offset = MTDPART_OFS_APPEND,
- .mask_flags = MTD_WRITEABLE,
- }, {
- .name = "free3",
- .size = MTDPART_SIZ_FULL,
- .offset = MTDPART_OFS_APPEND,
- .mask_flags = MTD_WRITEABLE,
- }
-};
-#endif
-
-#ifdef CONFIG_SA1100_FREEBIRD
-static struct mtd_partition freebird_partitions[] = {
-#ifdef CONFIG_SA1100_FREEBIRD_NEW
- {
- .name = "firmware",
- .size = 0x00040000,
- .offset = 0,
- .mask_flags = MTD_WRITEABLE, /* force read-only */
- }, {
- .name = "kernel",
- .size = 0x00080000,
- .offset = 0x00040000,
- }, {
- .name = "params",
- .size = 0x00040000,
- .offset = 0x000C0000,
- }, {
- .name = "initrd",
- .size = 0x00100000,
- .offset = 0x00100000,
- }, {
- .name = "root cramfs",
- .size = 0x00300000,
- .offset = 0x00200000,
- }, {
- .name = "usr cramfs",
- .size = 0x00C00000,
- .offset = 0x00500000,
- }, {
- .name = "local",
- .size = MTDPART_SIZ_FULL,
- .offset = 0x01100000,
- }
-#else
- {
- .size = 0x00040000,
- .offset = 0,
- }, {
- .size = 0x000c0000,
- .offset = MTDPART_OFS_APPEND,
- }, {
- .size = 0x00400000,
- .offset = MTDPART_OFS_APPEND,
- }, {
- .size = MTDPART_SIZ_FULL,
- .offset = MTDPART_OFS_APPEND,
- }
-#endif
-};
-#endif
-
-#ifdef CONFIG_SA1100_FRODO
-/* Frodo has 2 x 16M 28F128J3A flash chips in bank 0: */
-static struct mtd_partition frodo_partitions[] =
-{
- {
- .name = "bootloader",
- .size = 0x00040000,
- .offset = 0x00000000,
- .mask_flags = MTD_WRITEABLE
- }, {
- .name = "bootloader params",
- .size = 0x00040000,
- .offset = MTDPART_OFS_APPEND,
- .mask_flags = MTD_WRITEABLE
- }, {
- .name = "kernel",
- .size = 0x00100000,
- .offset = MTDPART_OFS_APPEND,
- .mask_flags = MTD_WRITEABLE
- }, {
- .name = "ramdisk",
- .size = 0x00400000,
- .offset = MTDPART_OFS_APPEND,
- .mask_flags = MTD_WRITEABLE
- }, {
- .name = "file system",
- .size = MTDPART_SIZ_FULL,
- .offset = MTDPART_OFS_APPEND
- }
-};
-#endif
-
-#ifdef CONFIG_SA1100_GRAPHICSCLIENT
-static struct mtd_partition graphicsclient_partitions[] = {
- {
- .name = "zImage",
- .size = 0x100000,
- .offset = 0,
- .mask_flags = MTD_WRITEABLE, /* force read-only */
- }, {
- .name = "ramdisk.gz",
- .size = 0x300000,
- .offset = MTDPART_OFS_APPEND,
- .mask_flags = MTD_WRITEABLE, /* force read-only */
- }, {
- .name = "User FS",
- .size = MTDPART_SIZ_FULL,
- .offset = MTDPART_OFS_APPEND,
- }
-};
-#endif
-
-#ifdef CONFIG_SA1100_GRAPHICSMASTER
-static struct mtd_partition graphicsmaster_partitions[] = {
- {
- .name = "zImage",
- .size = 0x100000,
- .offset = 0,
- .mask_flags = MTD_WRITEABLE, /* force read-only */
- },
- {
- .name = "ramdisk.gz",
- .size = 0x300000,
- .offset = MTDPART_OFS_APPEND,
- .mask_flags = MTD_WRITEABLE, /* force read-only */
- },
- {
- .name = "User FS",
- .size = MTDPART_SIZ_FULL,
- .offset = MTDPART_OFS_APPEND,
- }
-};
-#endif
-
-#ifdef CONFIG_SA1100_H3XXX
-static struct mtd_partition h3xxx_partitions[] = {
- {
- .name = "H3XXX boot firmware",
- .size = 0x00040000,
- .offset = 0,
- .mask_flags = MTD_WRITEABLE, /* force read-only */
- }, {
-#ifdef CONFIG_MTD_2PARTS_IPAQ
- .name = "H3XXX root jffs2",
- .size = MTDPART_SIZ_FULL,
- .offset = 0x00040000,
-#else
- .name = "H3XXX kernel",
- .size = 0x00080000,
- .offset = 0x00040000,
- }, {
- .name = "H3XXX params",
- .size = 0x00040000,
- .offset = 0x000C0000,
- }, {
-#ifdef CONFIG_JFFS2_FS
- .name = "H3XXX root jffs2",
- .size = MTDPART_SIZ_FULL,
- .offset = 0x00100000,
-#else
- .name = "H3XXX initrd",
- .size = 0x00100000,
- .offset = 0x00100000,
- }, {
- .name = "H3XXX root cramfs",
- .size = 0x00300000,
- .offset = 0x00200000,
- }, {
- .name = "H3XXX usr cramfs",
- .size = 0x00800000,
- .offset = 0x00500000,
- }, {
- .name = "H3XXX usr local",
- .size = MTDPART_SIZ_FULL,
- .offset = 0x00d00000,
-#endif
-#endif
- }
-};
-
-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
-static struct mtd_partition huw_webpanel_partitions[] = {
- {
- .name = "Loader",
- .size = 0x00040000,
- .offset = 0,
- }, {
- .name = "Sector 1",
- .size = 0x00040000,
- .offset = MTDPART_OFS_APPEND,
- }, {
- .size = MTDPART_SIZ_FULL,
- .offset = MTDPART_OFS_APPEND,
- }
-};
-#endif
-
-#ifdef CONFIG_SA1100_JORNADA720
-static struct mtd_partition jornada720_partitions[] = {
- {
- .name = "JORNADA720 boot firmware",
- .size = 0x00040000,
- .offset = 0,
- .mask_flags = MTD_WRITEABLE, /* force read-only */
- }, {
- .name = "JORNADA720 kernel",
- .size = 0x000c0000,
- .offset = 0x00040000,
- }, {
- .name = "JORNADA720 params",
- .size = 0x00040000,
- .offset = 0x00100000,
- }, {
- .name = "JORNADA720 initrd",
- .size = 0x00100000,
- .offset = 0x00140000,
- }, {
- .name = "JORNADA720 root cramfs",
- .size = 0x00300000,
- .offset = 0x00240000,
- }, {
- .name = "JORNADA720 usr cramfs",
- .size = 0x00800000,
- .offset = 0x00540000,
- }, {
- .name = "JORNADA720 usr local",
- .size = 0, /* will expand to the end of the flash */
- .offset = 0x00d00000,
- }
-};
-
-static void jornada720_set_vpp(struct map_info *map, int vpp)
-{
- if (vpp)
- PPSR |= 0x80;
- else
- PPSR &= ~0x80;
- PPDR |= 0x80;
-}
-#else
-#define jornada720_set_vpp NULL
-#endif
-
-#ifdef CONFIG_SA1100_PANGOLIN
-static struct mtd_partition pangolin_partitions[] = {
- {
- .name = "boot firmware",
- .size = 0x00080000,
- .offset = 0x00000000,
- .mask_flags = MTD_WRITEABLE, /* force read-only */
- }, {
- .name = "kernel",
- .size = 0x00100000,
- .offset = 0x00080000,
- }, {
- .name = "initrd",
- .size = 0x00280000,
- .offset = 0x00180000,
- }, {
- .name = "initrd-test",
- .size = 0x03C00000,
- .offset = 0x00400000,
- }
-};
-#endif
-
-#ifdef CONFIG_SA1100_PT_SYSTEM3
-/* erase size is 0x40000 == 256k partitions have to have this boundary */
-static struct mtd_partition system3_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 = "root",
- .size = MTDPART_SIZ_FULL,
- .offset = MTDPART_OFS_APPEND,
- }
-};
-#endif
-
-#ifdef CONFIG_SA1100_SHANNON
-static struct mtd_partition shannon_partitions[] = {
- {
- .name = "BLOB boot loader",
- .offset = 0,
- .size = 0x20000
- },
- {
- .name = "kernel",
- .offset = MTDPART_OFS_APPEND,
- .size = 0xe0000
- },
- {
- .name = "initrd",
- .offset = MTDPART_OFS_APPEND,
- .size = MTDPART_SIZ_FULL
- }
-};
-
-#endif
-
-#ifdef CONFIG_SA1100_SHERMAN
-static struct mtd_partition sherman_partitions[] = {
- {
- .size = 0x50000,
- .offset = 0,
- }, {
- .size = 0x70000,
- .offset = MTDPART_OFS_APPEND,
- }, {
- .size = 0x600000,
- .offset = MTDPART_OFS_APPEND,
- }, {
- .size = 0xA0000,
- .offset = MTDPART_OFS_APPEND,
- }
-};
-#endif
-
-#ifdef CONFIG_SA1100_SIMPAD
-static struct mtd_partition simpad_partitions[] = {
- {
- .name = "SIMpad boot firmware",
- .size = 0x00080000,
- .offset = 0,
- .mask_flags = MTD_WRITEABLE, /* force read-only */
- }, {
- .name = "SIMpad kernel",
- .size = 0x00100000,
- .offset = MTDPART_OFS_APPEND,
- }, {
-#ifdef CONFIG_ROOT_CRAMFS
- .name = "SIMpad root cramfs",
- .size =0x00D80000,
- .offset = MTDPART_OFS_APPEND
-
+ when you try to re-flash the image because blob
+ won't erase the whole partition. */
+ .size = 0x01000000 - 0x00140000,
+ .mask_flags = 0,
}, {
- .name = "SIMpad local jffs2",
- .size = MTDPART_SIZ_FULL,
- .offset = MTDPART_OFS_APPEND
-#else
- .name = "SIMpad root jffs2",
- .size = MTDPART_SIZ_FULL,
- .offset = MTDPART_OFS_APPEND
-#endif
+ /* this disk is a secondary disk, which can be used as
+ needed, for simplicity, make it the size of the other
+ consus partition, although realistically it could be
+ the remainder of the disk (depending on the file
+ system used) */
+ .name = "Consus disk2",
+ .offset = 0x01000000,
+ .size = 0x01000000 - 0x00140000,
+ .mask_flags = 0,
}
};
-#endif /* CONFIG_SA1100_SIMPAD */
-#ifdef CONFIG_SA1100_STORK
-static struct mtd_partition stork_partitions[] = {
+/* Frodo has 2 x 16M 28F128J3A flash chips in bank 0: */
+static struct mtd_partition frodo_partitions[] =
+{
{
- .name = "STORK boot firmware",
+ .name = "bootloader",
.size = 0x00040000,
- .offset = 0,
- .mask_flags = MTD_WRITEABLE, /* force read-only */
+ .offset = 0x00000000,
+ .mask_flags = MTD_WRITEABLE
}, {
- .name = "STORK params",
+ .name = "bootloader params",
.size = 0x00040000,
- .offset = 0x00040000,
- }, {
- .name = "STORK kernel",
- .size = 0x00100000,
- .offset = 0x00080000,
+ .offset = MTDPART_OFS_APPEND,
+ .mask_flags = MTD_WRITEABLE
}, {
-#ifdef CONFIG_JFFS2_FS
- .name = "STORK root jffs2",
- .offset = 0x00180000,
- .size = MTDPART_SIZ_FULL,
-#else
- .name = "STORK initrd",
+ .name = "kernel",
.size = 0x00100000,
- .offset = 0x00180000,
- }, {
- .name = "STORK root cramfs",
- .size = 0x00300000,
- .offset = 0x00280000,
+ .offset = MTDPART_OFS_APPEND,
+ .mask_flags = MTD_WRITEABLE
}, {
- .name = "STORK usr cramfs",
- .size = 0x00800000,
- .offset = 0x00580000,
+ .name = "ramdisk",
+ .size = 0x00400000,
+ .offset = MTDPART_OFS_APPEND,
+ .mask_flags = MTD_WRITEABLE
}, {
- .name = "STORK usr local",
- .offset = 0x00d80000,
+ .name = "file system",
.size = MTDPART_SIZ_FULL,
-#endif
+ .offset = MTDPART_OFS_APPEND
}
};
-#endif
-#ifdef CONFIG_SA1100_TRIZEPS
-static struct mtd_partition trizeps_partitions[] = {
+static struct mtd_partition jornada56x_partitions[] = {
{
- .name = "Bootloader",
- .size = 0x00100000,
+ .name = "bootldr",
+ .size = 0x00040000,
.offset = 0,
+ .mask_flags = MTD_WRITEABLE,
}, {
- .name = "Kernel",
- .size = 0x00100000,
- .offset = MTDPART_OFS_APPEND,
- }, {
- .name = "root",
+ .name = "rootfs",
.size = MTDPART_SIZ_FULL,
.offset = MTDPART_OFS_APPEND,
}
};
-#endif
-
-#ifdef CONFIG_SA1100_YOPY
-static struct mtd_partition yopy_partitions[] = {
- {
- .name = "boot firmware",
- .size = 0x00040000,
- .offset = 0x00000000,
- .mask_flags = MTD_WRITEABLE, /* force read-only */
- }, {
- .name = "kernel",
- .size = 0x00080000,
- .offset = 0x00080000,
- }, {
- .name = "initrd",
- .size = 0x00300000,
- .offset = 0x00100000,
- }, {
- .name = "root",
- .size = 0x01000000,
- .offset = 0x00400000,
- }
-};
-#endif
-static int __init sa1100_static_partitions(struct mtd_partition **parts)
+static void jornada56x_set_vpp(int vpp)
{
- int nb_parts = 0;
-
-#ifdef CONFIG_SA1100_ADSBITSY
- if (machine_is_adsbitsy()) {
- *parts = adsbitsy_partitions;
- nb_parts = ARRAY_SIZE(adsbitsy_partitions);
- }
-#endif
-#ifdef CONFIG_SA1100_ASSABET
- if (machine_is_assabet()) {
- *parts = assabet_partitions;
- nb_parts = ARRAY_SIZE(assabet_partitions);
- }
-#endif
-#ifdef CONFIG_SA1100_BADGE4
- if (machine_is_badge4()) {
- *parts = badge4_partitions;
- nb_parts = ARRAY_SIZE(badge4_partitions);
- }
-#endif
-#ifdef CONFIG_SA1100_CERF
- if (machine_is_cerf()) {
- *parts = cerf_partitions;
- nb_parts = ARRAY_SIZE(cerf_partitions);
- }
-#endif
-#ifdef CONFIG_SA1100_CONSUS
- if (machine_is_consus()) {
- *parts = consus_partitions;
- nb_parts = ARRAY_SIZE(consus_partitions);
- }
-#endif
-#ifdef CONFIG_SA1100_FLEXANET
- if (machine_is_flexanet()) {
- *parts = flexanet_partitions;
- nb_parts = ARRAY_SIZE(flexanet_partitions);
- }
-#endif
-#ifdef CONFIG_SA1100_FREEBIRD
- if (machine_is_freebird()) {
- *parts = freebird_partitions;
- nb_parts = ARRAY_SIZE(freebird_partitions);
- }
-#endif
-#ifdef CONFIG_SA1100_FRODO
- if (machine_is_frodo()) {
- *parts = frodo_partitions;
- nb_parts = ARRAY_SIZE(frodo_partitions);
- }
-#endif
-#ifdef CONFIG_SA1100_GRAPHICSCLIENT
- if (machine_is_graphicsclient()) {
- *parts = graphicsclient_partitions;
- nb_parts = ARRAY_SIZE(graphicsclient_partitions);
- }
-#endif
-#ifdef CONFIG_SA1100_GRAPHICSMASTER
- if (machine_is_graphicsmaster()) {
- *parts = graphicsmaster_partitions;
- nb_parts = ARRAY_SIZE(graphicsmaster_partitions);
- }
-#endif
-#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;
- nb_parts = ARRAY_SIZE(huw_webpanel_partitions);
- }
-#endif
-#ifdef CONFIG_SA1100_JORNADA720
- if (machine_is_jornada720()) {
- *parts = jornada720_partitions;
- nb_parts = ARRAY_SIZE(jornada720_partitions);
- }
-#endif
-#ifdef CONFIG_SA1100_PANGOLIN
- if (machine_is_pangolin()) {
- *parts = pangolin_partitions;
- nb_parts = ARRAY_SIZE(pangolin_partitions);
- }
-#endif
-#ifdef CONFIG_SA1100_PT_SYSTEM3
- if (machine_is_pt_system3()) {
- *parts = system3_partitions;
- nb_parts = ARRAY_SIZE(system3_partitions);
- }
-#endif
-#ifdef CONFIG_SA1100_SHANNON
- if (machine_is_shannon()) {
- *parts = shannon_partitions;
- nb_parts = ARRAY_SIZE(shannon_partitions);
- }
-#endif
-#ifdef CONFIG_SA1100_SHERMAN
- if (machine_is_sherman()) {
- *parts = sherman_partitions;
- nb_parts = ARRAY_SIZE(sherman_partitions);
- }
-#endif
-#ifdef CONFIG_SA1100_SIMPAD
- if (machine_is_simpad()) {
- *parts = simpad_partitions;
- nb_parts = ARRAY_SIZE(simpad_partitions);
- }
-#endif
-#ifdef CONFIG_SA1100_STORK
- if (machine_is_stork()) {
- *parts = stork_partitions;
- nb_parts = ARRAY_SIZE(stork_partitions);
- }
-#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;
- nb_parts = ARRAY_SIZE(yopy_partitions);
- }
-#endif
-
- return nb_parts;
+ if (vpp)
+ GPSR = GPIO_GPIO26;
+ else
+ GPCR = GPIO_GPIO26;
+ GPDR |= GPIO_GPIO26;
}
+
+/*
+ * Machine Phys Size set_vpp
+ * Consus : SA1100_CS0_PHYS SZ_32M
+ * Frodo : SA1100_CS0_PHYS SZ_32M
+ * Jornada56x: SA1100_CS0_PHYS SZ_32M jornada56x_set_vpp
+ */
#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 sa_subdev_info {
+ char name[16];
+ struct map_info map;
struct mtd_info *mtd;
- struct resource *res;
+ struct flash_platform_data *plat;
};
-#define NR_SUBMTD 4
+struct sa_info {
+ struct mtd_partition *parts;
+ struct mtd_info *mtd;
+ int num_subdev;
+ unsigned int nr_parts;
+ struct sa_subdev_info subdev[0];
+};
-static struct sa_info info[NR_SUBMTD];
+static void sa1100_set_vpp(struct map_info *map, int on)
+{
+ struct sa_subdev_info *subdev = container_of(map, struct sa_subdev_info, map);
+ subdev->plat->set_vpp(on);
+}
-static int __init sa1100_setup_mtd(struct sa_info *sa, int nr, struct mtd_info **rmtd)
+static void sa1100_destroy_subdev(struct sa_subdev_info *subdev)
{
- struct mtd_info *subdev[nr];
- struct map_info *maps;
- int i, found = 0, ret = 0;
+ if (subdev->mtd)
+ map_destroy(subdev->mtd);
+ if (subdev->map.virt)
+ iounmap(subdev->map.virt);
+ release_mem_region(subdev->map.phys, subdev->map.size);
+}
- /*
- * Allocate the map_info structs in one go.
- */
- maps = kmalloc(sizeof(struct map_info) * nr, GFP_KERNEL);
- if (!maps)
- return -ENOMEM;
+static int sa1100_probe_subdev(struct sa_subdev_info *subdev, struct resource *res)
+{
+ unsigned long phys;
+ unsigned int size;
+ int ret;
- memset(maps, 0, sizeof(struct map_info) * nr);
+ phys = res->start;
+ size = res->end - phys + 1;
/*
- * Claim and then map the memory regions.
+ * Retrieve the bankwidth from the MSC registers.
+ * We currently only implement CS0 and CS1 here.
*/
- 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;
- }
+ switch (phys) {
+ default:
+ printk(KERN_WARNING "SA1100 flash: unknown base address "
+ "0x%08lx, assuming CS0\n", phys);
- sa[i].map = maps + i;
+ case SA1100_CS0_PHYS:
+ subdev->map.bankwidth = (MSC0 & MSC_RBW) ? 2 : 4;
+ break;
- sa[i].vbase = ioremap(sa[i].base, sa[i].size);
- if (!sa[i].vbase) {
- ret = -ENOMEM;
- break;
- }
+ case SA1100_CS1_PHYS:
+ subdev->map.bankwidth = ((MSC0 >> 16) & MSC_RBW) ? 2 : 4;
+ 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;
+ if (!request_mem_region(phys, size, subdev->name)) {
+ ret = -EBUSY;
+ goto out;
+ }
- simple_map_init(sa[i].map);
+ if (subdev->plat->set_vpp)
+ subdev->map.set_vpp = sa1100_set_vpp;
- /*
- * Now let's probe for the actual flash. Do it here since
- * specific machine settings might have been set above.
- */
- 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;
-
- 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;
+ subdev->map.phys = phys;
+ subdev->map.size = size;
+ subdev->map.virt = ioremap(phys, size);
+ if (!subdev->map.virt) {
+ ret = -ENOMEM;
+ goto err;
}
- /*
- * 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;
- }
+ simple_map_init(&subdev->map);
/*
- * 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.
+ * Now let's probe for the actual flash. Do it here since
+ * specific machine settings might have been set above.
*/
- 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;
-#else
- printk(KERN_ERR "SA1100 flash: multiple devices "
- "found but MTD concat support disabled.\n");
- ret = -ENXIO;
-#endif
- }
+ subdev->mtd = do_map_probe(subdev->plat->map_name, &subdev->map);
+ if (subdev->mtd == NULL) {
+ ret = -ENXIO;
+ goto err;
}
+ subdev->mtd->owner = THIS_MODULE;
- /*
- * If we failed, clean up.
- */
- 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);
- }
+ printk(KERN_INFO "SA1100 flash: CFI device at 0x%08lx, %dMiB, "
+ "%d-bit\n", phys, subdev->mtd->size >> 20,
+ subdev->map.bankwidth * 8);
+
+ return 0;
+ err:
+ sa1100_destroy_subdev(subdev);
+ out:
return ret;
}
-static void __exit sa1100_destroy_mtd(struct sa_info *sa, struct mtd_info *mtd)
+static void sa1100_destroy(struct sa_info *info, struct flash_platform_data *plat)
{
int i;
- del_mtd_partitions(mtd);
-
+ if (info->mtd) {
+ if (info->nr_parts == 0)
+ del_mtd_device(info->mtd);
+#ifdef CONFIG_MTD_PARTITIONS
+ else
+ del_mtd_partitions(info->mtd);
+#endif
#ifdef CONFIG_MTD_CONCAT
- if (mtd != sa[0].mtd)
- mtd_concat_destroy(mtd);
+ if (info->mtd != info->subdev[0].mtd)
+ mtd_concat_destroy(info->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);
-}
-/*
- * 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
- */
+ kfree(info->parts);
-static struct map_info sa1100_probe_map __initdata = {
- .name = "SA1100-flash",
-};
+ for (i = info->num_subdev - 1; i >= 0; i--)
+ sa1100_destroy_subdev(&info->subdev[i]);
+ kfree(info);
-static void __init sa1100_probe_one_cs(unsigned int msc, unsigned long phys)
-{
- struct mtd_info *mtd;
+ if (plat->exit)
+ plat->exit();
+}
- printk(KERN_INFO "* Probing 0x%08lx: MSC = 0x%04x %d bit ",
- phys, msc & 0xffff, msc & MSC_RBW ? 16 : 32);
+static struct sa_info *__init
+sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *plat)
+{
+ struct sa_info *info;
+ int nr, size, i, ret = 0;
- if (check_mem_region(phys, 0x08000000)) {
- printk("busy\n");
- return;
- }
+ /*
+ * Count number of devices.
+ */
+ for (nr = 0; ; nr++)
+ if (!platform_get_resource(pdev, IORESOURCE_MEM, nr))
+ break;
- if ((msc & 3) == 1) {
- printk("wrong type\n");
- return;
+ if (nr == 0) {
+ ret = -ENODEV;
+ goto out;
}
- 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);
+ size = sizeof(struct sa_info) + sizeof(struct sa_subdev_info) * nr;
- /* 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;
+ /*
+ * Allocate the map_info structs in one go.
+ */
+ info = kmalloc(size, GFP_KERNEL);
+ if (!info) {
+ ret = -ENOMEM;
+ goto out;
+ }
- printk("pass\n");
- return;
+ memset(info, 0, size);
- fail:
- printk("failed\n");
-}
+ if (plat->init) {
+ ret = plat->init();
+ if (ret)
+ goto err;
+ }
-static void __init sa1100_probe_flash(void)
-{
- 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");
-}
+ /*
+ * Claim and then map the memory regions.
+ */
+ for (i = 0; i < nr; i++) {
+ struct sa_subdev_info *subdev = &info->subdev[i];
+ struct resource *res;
-static int __init sa1100_locate_flash(void)
-{
- int i, nr = -ENODEV;
+ res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+ if (!res)
+ break;
- sa1100_probe_flash();
+ subdev->map.name = subdev->name;
+ sprintf(subdev->name, "%s-%d", plat->name, i);
+ subdev->plat = plat;
- 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 (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_16M;
- info[1].base = SA1100_CS1_PHYS;
- info[1].size = SZ_16M;
- nr = 2;
- }
- 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;
+ ret = sa1100_probe_subdev(subdev, res);
+ if (ret)
+ break;
}
- if (nr < 0)
- return nr;
+ info->num_subdev = i;
/*
- * Retrieve the buswidth from the MSC registers.
- * We currently only implement CS0 and CS1 here.
+ * ENXIO is special. It means we didn't find a chip when we probed.
*/
- 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;
+ if (ret != 0 && !(ret == -ENXIO && info->num_subdev > 0))
+ goto err;
- case SA1100_CS1_PHYS:
- info[i].width = ((MSC0 >> 16) & MSC_RBW) ? 2 : 4;
- break;
- }
+ /*
+ * 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. Either way, it'll be called "sa1100".
+ */
+ if (info->num_subdev == 1) {
+ strcpy(info->subdev[0].name, plat->name);
+ info->mtd = info->subdev[0].mtd;
+ ret = 0;
+ } else if (info->num_subdev > 1) {
+#ifdef CONFIG_MTD_CONCAT
+ struct mtd_info *cdev[nr];
+ /*
+ * We detected multiple devices. Concatenate them together.
+ */
+ for (i = 0; i < info->num_subdev; i++)
+ cdev[i] = info->subdev[i].mtd;
+
+ info->mtd = mtd_concat_create(cdev, info->num_subdev,
+ plat->name);
+ if (info->mtd == NULL)
+ ret = -ENXIO;
+#else
+ printk(KERN_ERR "SA1100 flash: multiple devices "
+ "found but MTD concat support disabled.\n");
+ ret = -ENXIO;
+#endif
}
- return nr;
+ if (ret == 0)
+ return info;
+
+ err:
+ sa1100_destroy(info, plat);
+ out:
+ return ERR_PTR(ret);
}
-static struct mtd_partition *parsed_parts;
-const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL };
+static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL };
-static void __init sa1100_locate_partitions(struct mtd_info *mtd)
+static int __init sa1100_mtd_probe(struct platform_device *pdev)
{
+ struct flash_platform_data *plat = pdev->dev.platform_data;
+ struct mtd_partition *parts;
const char *part_type = NULL;
- int nr_parts = 0;
+ struct sa_info *info;
+ int err, nr_parts = 0;
- do {
- /*
- * Partition selection stuff.
- */
+ if (!plat)
+ return -ENODEV;
+
+ info = sa1100_setup_mtd(pdev, plat);
+ if (IS_ERR(info)) {
+ err = PTR_ERR(info);
+ goto out;
+ }
+
+ /*
+ * 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;
- }
+ nr_parts = parse_mtd_partitions(info->mtd, part_probes, &parts, 0);
+ if (nr_parts > 0) {
+ info->parts = parts;
+ part_type = "dynamic";
+ } else
#endif
- } while (0);
+ {
+ parts = plat->parts;
+ nr_parts = plat->nr_parts;
+ part_type = "static";
+ }
if (nr_parts == 0) {
printk(KERN_NOTICE "SA1100 flash: no partition info "
"available, registering whole flash\n");
- add_mtd_device(mtd);
+ add_mtd_device(info->mtd);
} else {
printk(KERN_NOTICE "SA1100 flash: using %s partition "
"definition\n", part_type);
- add_mtd_partitions(mtd, parsed_parts, nr_parts);
+ add_mtd_partitions(info->mtd, parts, nr_parts);
}
- /* Always succeeds. */
+ info->nr_parts = nr_parts;
+
+ platform_set_drvdata(pdev, info);
+ err = 0;
+
+ out:
+ return err;
}
-static void __exit sa1100_destroy_partitions(void)
+static int __exit sa1100_mtd_remove(struct platform_device *pdev)
{
- if (parsed_parts)
- kfree(parsed_parts);
-}
+ struct sa_info *info = platform_get_drvdata(pdev);
+ struct flash_platform_data *plat = pdev->dev.platform_data;
-static struct mtd_info *mymtd;
+ platform_set_drvdata(pdev, NULL);
+ sa1100_destroy(info, plat);
-static int __init sa1100_mtd_init(void)
-{
- int ret;
- int nr;
+ return 0;
+}
- nr = sa1100_locate_flash();
- if (nr < 0)
- return nr;
+#ifdef CONFIG_PM
+static int sa1100_mtd_suspend(struct platform_device *dev, pm_message_t state)
+{
+ struct sa_info *info = platform_get_drvdata(dev);
+ int ret = 0;
- ret = sa1100_setup_mtd(info, nr, &mymtd);
- if (ret == 0)
- sa1100_locate_partitions(mymtd);
+ if (info)
+ ret = info->mtd->suspend(info->mtd);
return ret;
}
-static void __exit sa1100_mtd_cleanup(void)
+static int sa1100_mtd_resume(struct platform_device *dev)
+{
+ struct sa_info *info = platform_get_drvdata(dev);
+ if (info)
+ info->mtd->resume(info->mtd);
+ return 0;
+}
+
+static void sa1100_mtd_shutdown(struct platform_device *dev)
+{
+ struct sa_info *info = platform_get_drvdata(dev);
+ if (info && info->mtd->suspend(info->mtd) == 0)
+ info->mtd->resume(info->mtd);
+}
+#else
+#define sa1100_mtd_suspend NULL
+#define sa1100_mtd_resume NULL
+#define sa1100_mtd_shutdown NULL
+#endif
+
+static struct platform_driver sa1100_mtd_driver = {
+ .probe = sa1100_mtd_probe,
+ .remove = __exit_p(sa1100_mtd_remove),
+ .suspend = sa1100_mtd_suspend,
+ .resume = sa1100_mtd_resume,
+ .shutdown = sa1100_mtd_shutdown,
+ .driver = {
+ .name = "flash",
+ },
+};
+
+static int __init sa1100_mtd_init(void)
+{
+ return platform_driver_register(&sa1100_mtd_driver);
+}
+
+static void __exit sa1100_mtd_exit(void)
{
- sa1100_destroy_mtd(info, mymtd);
- sa1100_destroy_partitions();
+ platform_driver_unregister(&sa1100_mtd_driver);
}
module_init(sa1100_mtd_init);
-module_exit(sa1100_mtd_cleanup);
+module_exit(sa1100_mtd_exit);
MODULE_AUTHOR("Nicolas Pitre");
MODULE_DESCRIPTION("SA1100 CFI map driver");