diff options
author | Manuel Lauss <manuel.lauss@googlemail.com> | 2009-10-19 12:53:37 +0200 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2010-02-27 12:52:59 +0100 |
commit | 206aa6cdadad8bbedee5649f1346fe47e922a039 (patch) | |
tree | 1b66e9d98b65d7afe962bb6c6989f3ad212f2e6d /arch/mips | |
parent | 8facefd0907ae16f96a35bef7ce654206d87c2fc (diff) |
MIPS: Alchemy: physmap-flash for all devboards
Replace the devboard NOR MTD mapping driver with physmap-flash support.
Also honor the "swapboot" switch settings wrt. to the layout of the
NOR partitions.
Signed-off-by: Manuel Lauss <manuel.lauss@gmail.com>
Cc: Linux-MIPS <linux-mips@linux-mips.org>
Acked-By: David Woodhouse <David.Woodhouse@intel.com>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips')
-rw-r--r-- | arch/mips/alchemy/devboards/db1x00/platform.c | 20 | ||||
-rw-r--r-- | arch/mips/alchemy/devboards/pb1000/board_setup.c | 7 | ||||
-rw-r--r-- | arch/mips/alchemy/devboards/pb1100/platform.c | 7 | ||||
-rw-r--r-- | arch/mips/alchemy/devboards/pb1200/platform.c | 9 | ||||
-rw-r--r-- | arch/mips/alchemy/devboards/pb1500/platform.c | 7 | ||||
-rw-r--r-- | arch/mips/alchemy/devboards/pb1550/platform.c | 6 | ||||
-rw-r--r-- | arch/mips/alchemy/devboards/platform.c | 104 | ||||
-rw-r--r-- | arch/mips/alchemy/devboards/platform.h | 3 |
8 files changed, 163 insertions, 0 deletions
diff --git a/arch/mips/alchemy/devboards/db1x00/platform.c b/arch/mips/alchemy/devboards/db1x00/platform.c index 0ac5dd05d3c0..62e2a96fe119 100644 --- a/arch/mips/alchemy/devboards/db1x00/platform.c +++ b/arch/mips/alchemy/devboards/db1x00/platform.c @@ -22,6 +22,7 @@ #include <linux/platform_device.h> #include <asm/mach-au1x00/au1xxx.h> +#include <asm/mach-db1x00/bcsr.h> #include "../platform.h" /* DB1xxx PCMCIA interrupt sources: @@ -32,6 +33,7 @@ */ #define DB1XXX_HAS_PCMCIA +#define F_SWAPPED (bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT) #if defined(CONFIG_MIPS_DB1000) #define DB1XXX_PCMCIA_CD0 AU1000_GPIO0_INT @@ -40,6 +42,8 @@ #define DB1XXX_PCMCIA_CD1 AU1000_GPIO3_INT #define DB1XXX_PCMCIA_STSCHG1 AU1000_GPIO4_INT #define DB1XXX_PCMCIA_CARD1 AU1000_GPIO5_INT +#define BOARD_FLASH_SIZE 0x02000000 /* 32MB */ +#define BOARD_FLASH_WIDTH 4 /* 32-bits */ #elif defined(CONFIG_MIPS_DB1100) #define DB1XXX_PCMCIA_CD0 AU1100_GPIO0_INT #define DB1XXX_PCMCIA_STSCHG0 AU1100_GPIO1_INT @@ -47,6 +51,8 @@ #define DB1XXX_PCMCIA_CD1 AU1100_GPIO3_INT #define DB1XXX_PCMCIA_STSCHG1 AU1100_GPIO4_INT #define DB1XXX_PCMCIA_CARD1 AU1100_GPIO5_INT +#define BOARD_FLASH_SIZE 0x02000000 /* 32MB */ +#define BOARD_FLASH_WIDTH 4 /* 32-bits */ #elif defined(CONFIG_MIPS_DB1500) #define DB1XXX_PCMCIA_CD0 AU1500_GPIO0_INT #define DB1XXX_PCMCIA_STSCHG0 AU1500_GPIO1_INT @@ -54,6 +60,8 @@ #define DB1XXX_PCMCIA_CD1 AU1500_GPIO3_INT #define DB1XXX_PCMCIA_STSCHG1 AU1500_GPIO4_INT #define DB1XXX_PCMCIA_CARD1 AU1500_GPIO5_INT +#define BOARD_FLASH_SIZE 0x02000000 /* 32MB */ +#define BOARD_FLASH_WIDTH 4 /* 32-bits */ #elif defined(CONFIG_MIPS_DB1550) #define DB1XXX_PCMCIA_CD0 AU1550_GPIO0_INT #define DB1XXX_PCMCIA_STSCHG0 AU1550_GPIO21_INT @@ -61,9 +69,20 @@ #define DB1XXX_PCMCIA_CD1 AU1550_GPIO1_INT #define DB1XXX_PCMCIA_STSCHG1 AU1550_GPIO22_INT #define DB1XXX_PCMCIA_CARD1 AU1550_GPIO5_INT +#define BOARD_FLASH_SIZE 0x08000000 /* 128MB */ +#define BOARD_FLASH_WIDTH 4 /* 32-bits */ #else /* other board: no PCMCIA */ #undef DB1XXX_HAS_PCMCIA +#undef F_SWAPPED +#define F_SWAPPED 0 +#if defined(CONFIG_MIPS_BOSPORUS) +#define BOARD_FLASH_SIZE 0x01000000 /* 16MB */ +#define BOARD_FLASH_WIDTH 2 /* 16-bits */ +#elif defined(CONFIG_MIPS_MIRAGE) +#define BOARD_FLASH_SIZE 0x04000000 /* 64MB */ +#define BOARD_FLASH_WIDTH 4 /* 32-bits */ +#endif #endif static int __init db1xxx_dev_init(void) @@ -93,6 +112,7 @@ static int __init db1xxx_dev_init(void) 0, 1); #endif + db1x_register_norflash(BOARD_FLASH_SIZE, BOARD_FLASH_WIDTH, F_SWAPPED); return 0; } device_initcall(db1xxx_dev_init); diff --git a/arch/mips/alchemy/devboards/pb1000/board_setup.c b/arch/mips/alchemy/devboards/pb1000/board_setup.c index 50fff504ae05..28b8bd278a16 100644 --- a/arch/mips/alchemy/devboards/pb1000/board_setup.c +++ b/arch/mips/alchemy/devboards/pb1000/board_setup.c @@ -31,6 +31,7 @@ #include <asm/mach-pb1x00/pb1000.h> #include <prom.h> +#include "../platform.h" const char *get_system_type(void) { @@ -194,3 +195,9 @@ static int __init pb1000_init_irq(void) return 0; } arch_initcall(pb1000_init_irq); + +static int __init pb1000_device_init(void) +{ + return db1x_register_norflash(8 * 1024 * 1024, 4, 0); +} +device_initcall(pb1000_device_init); diff --git a/arch/mips/alchemy/devboards/pb1100/platform.c b/arch/mips/alchemy/devboards/pb1100/platform.c index ec932e773a40..bfc5ab6a121c 100644 --- a/arch/mips/alchemy/devboards/pb1100/platform.c +++ b/arch/mips/alchemy/devboards/pb1100/platform.c @@ -21,11 +21,14 @@ #include <linux/init.h> #include <asm/mach-au1x00/au1000.h> +#include <asm/mach-db1x00/bcsr.h> #include "../platform.h" static int __init pb1100_dev_init(void) { + int swapped; + /* PCMCIA. single socket, identical to Pb1500 */ db1x_register_pcmcia_socket(PCMCIA_ATTR_PSEUDO_PHYS, PCMCIA_ATTR_PSEUDO_PHYS + 0x00040000 - 1, @@ -38,6 +41,10 @@ static int __init pb1100_dev_init(void) /*AU1100_GPIO10_INT*/0, /* stschg */ 0, /* eject */ 0); /* id */ + + swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT; + db1x_register_norflash(64 * 1024 * 1024, 4, swapped); + return 0; } device_initcall(pb1100_dev_init); diff --git a/arch/mips/alchemy/devboards/pb1200/platform.c b/arch/mips/alchemy/devboards/pb1200/platform.c index c8b7ae3f3253..736d647ebe0c 100644 --- a/arch/mips/alchemy/devboards/pb1200/platform.c +++ b/arch/mips/alchemy/devboards/pb1200/platform.c @@ -172,6 +172,8 @@ static struct platform_device *board_platform_devices[] __initdata = { static int __init board_register_devices(void) { + int swapped; + #ifdef CONFIG_MIPS_PB1200 db1x_register_pcmcia_socket(PCMCIA_ATTR_PSEUDO_PHYS, PCMCIA_ATTR_PSEUDO_PHYS + 0x00040000 - 1, @@ -222,6 +224,13 @@ static int __init board_register_devices(void) 1); #endif + swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1200_SWAPBOOT; +#ifdef CONFIG_MIPS_PB1200 + db1x_register_norflash(128 * 1024 * 1024, 2, swapped); +#else + db1x_register_norflash(64 * 1024 * 1024, 2, swapped); +#endif + return platform_add_devices(board_platform_devices, ARRAY_SIZE(board_platform_devices)); } diff --git a/arch/mips/alchemy/devboards/pb1500/platform.c b/arch/mips/alchemy/devboards/pb1500/platform.c index cdce775e2131..529acb789254 100644 --- a/arch/mips/alchemy/devboards/pb1500/platform.c +++ b/arch/mips/alchemy/devboards/pb1500/platform.c @@ -20,11 +20,14 @@ #include <linux/init.h> #include <asm/mach-au1x00/au1000.h> +#include <asm/mach-db1x00/bcsr.h> #include "../platform.h" static int __init pb1500_dev_init(void) { + int swapped; + /* PCMCIA. single socket, identical to Pb1500 */ db1x_register_pcmcia_socket(PCMCIA_ATTR_PSEUDO_PHYS, PCMCIA_ATTR_PSEUDO_PHYS + 0x00040000 - 1, @@ -37,6 +40,10 @@ static int __init pb1500_dev_init(void) /*AU1500_GPIO10_INT*/0, /* stschg */ 0, /* eject */ 0); /* id */ + + swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT; + db1x_register_norflash(64 * 1024 * 1024, 4, swapped); + return 0; } device_initcall(pb1500_dev_init); diff --git a/arch/mips/alchemy/devboards/pb1550/platform.c b/arch/mips/alchemy/devboards/pb1550/platform.c index b496fb6de231..461339166a4e 100644 --- a/arch/mips/alchemy/devboards/pb1550/platform.c +++ b/arch/mips/alchemy/devboards/pb1550/platform.c @@ -22,11 +22,14 @@ #include <asm/mach-au1x00/au1000.h> #include <asm/mach-pb1x00/pb1550.h> +#include <asm/mach-db1x00/bcsr.h> #include "../platform.h" static int __init pb1550_dev_init(void) { + int swapped; + /* Pb1550, like all others, also has statuschange irqs; however they're * wired up on one of the Au1550's shared GPIO201_205 line, which also * services the PCMCIA card interrupts. So we ignore statuschange and @@ -58,6 +61,9 @@ static int __init pb1550_dev_init(void) 0, 1); + swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_PB1550_SWAPBOOT; + db1x_register_norflash(128 * 1024 * 1024, 4, swapped); + return 0; } device_initcall(pb1550_dev_init); diff --git a/arch/mips/alchemy/devboards/platform.c b/arch/mips/alchemy/devboards/platform.c index 48c537cc8efb..7f2bcee7ac34 100644 --- a/arch/mips/alchemy/devboards/platform.c +++ b/arch/mips/alchemy/devboards/platform.c @@ -3,6 +3,9 @@ */ #include <linux/init.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/map.h> +#include <linux/mtd/physmap.h> #include <linux/slab.h> #include <linux/platform_device.h> @@ -87,3 +90,104 @@ out: kfree(sr); return ret; } + +#define YAMON_SIZE 0x00100000 +#define YAMON_ENV_SIZE 0x00040000 + +int __init db1x_register_norflash(unsigned long size, int width, + int swapped) +{ + struct physmap_flash_data *pfd; + struct platform_device *pd; + struct mtd_partition *parts; + struct resource *res; + int ret, i; + + if (size < (8 * 1024 * 1024)) + return -EINVAL; + + ret = -ENOMEM; + parts = kzalloc(sizeof(struct mtd_partition) * 5, GFP_KERNEL); + if (!parts) + goto out; + + res = kzalloc(sizeof(struct resource), GFP_KERNEL); + if (!res) + goto out1; + + pfd = kzalloc(sizeof(struct physmap_flash_data), GFP_KERNEL); + if (!pfd) + goto out2; + + pd = platform_device_alloc("physmap-flash", 0); + if (!pd) + goto out3; + + /* NOR flash ends at 0x20000000, regardless of size */ + res->start = 0x20000000 - size; + res->end = 0x20000000 - 1; + res->flags = IORESOURCE_MEM; + + /* partition setup. Most Develboards have a switch which allows + * to swap the physical locations of the 2 NOR flash banks. + */ + i = 0; + if (!swapped) { + /* first NOR chip */ + parts[i].offset = 0; + parts[i].name = "User FS"; + parts[i].size = size / 2; + i++; + } + + parts[i].offset = MTDPART_OFS_APPEND; + parts[i].name = "User FS 2"; + parts[i].size = (size / 2) - (0x20000000 - 0x1fc00000); + i++; + + parts[i].offset = MTDPART_OFS_APPEND; + parts[i].name = "YAMON"; + parts[i].size = YAMON_SIZE; + parts[i].mask_flags = MTD_WRITEABLE; + i++; + + parts[i].offset = MTDPART_OFS_APPEND; + parts[i].name = "raw kernel"; + parts[i].size = 0x00400000 - YAMON_SIZE - YAMON_ENV_SIZE; + i++; + + parts[i].offset = MTDPART_OFS_APPEND; + parts[i].name = "YAMON Env"; + parts[i].size = YAMON_ENV_SIZE; + parts[i].mask_flags = MTD_WRITEABLE; + i++; + + if (swapped) { + parts[i].offset = MTDPART_OFS_APPEND; + parts[i].name = "User FS"; + parts[i].size = size / 2; + i++; + } + + pfd->width = width; + pfd->parts = parts; + pfd->nr_parts = 5; + + pd->dev.platform_data = pfd; + pd->resource = res; + pd->num_resources = 1; + + ret = platform_device_add(pd); + if (!ret) + return ret; + + platform_device_put(pd); +out3: + kfree(pfd); +out2: + kfree(res); +out1: + kfree(parts); +out: + return ret; +} diff --git a/arch/mips/alchemy/devboards/platform.h b/arch/mips/alchemy/devboards/platform.h index 55ecf7e9258f..828c54e31157 100644 --- a/arch/mips/alchemy/devboards/platform.h +++ b/arch/mips/alchemy/devboards/platform.h @@ -15,4 +15,7 @@ int __init db1x_register_pcmcia_socket(unsigned long pseudo_attr_start, int eject_irq, int id); +int __init db1x_register_norflash(unsigned long size, int width, + int swapped); + #endif |