linux/arch/mips/alchemy/devboards/platform.c
Manuel Lauss 206aa6cdad 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>
2010-02-27 12:52:59 +01:00

194 lines
3.9 KiB
C

/*
* devoard misc stuff.
*/
#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>
/* register a pcmcia socket */
int __init db1x_register_pcmcia_socket(unsigned long pseudo_attr_start,
unsigned long pseudo_attr_end,
unsigned long pseudo_mem_start,
unsigned long pseudo_mem_end,
unsigned long pseudo_io_start,
unsigned long pseudo_io_end,
int card_irq,
int cd_irq,
int stschg_irq,
int eject_irq,
int id)
{
int cnt, i, ret;
struct resource *sr;
struct platform_device *pd;
cnt = 5;
if (eject_irq)
cnt++;
if (stschg_irq)
cnt++;
sr = kzalloc(sizeof(struct resource) * cnt, GFP_KERNEL);
if (!sr)
return -ENOMEM;
pd = platform_device_alloc("db1xxx_pcmcia", id);
if (!pd) {
ret = -ENOMEM;
goto out;
}
sr[0].name = "pseudo-attr";
sr[0].flags = IORESOURCE_MEM;
sr[0].start = pseudo_attr_start;
sr[0].end = pseudo_attr_end;
sr[1].name = "pseudo-mem";
sr[1].flags = IORESOURCE_MEM;
sr[1].start = pseudo_mem_start;
sr[1].end = pseudo_mem_end;
sr[2].name = "pseudo-io";
sr[2].flags = IORESOURCE_MEM;
sr[2].start = pseudo_io_start;
sr[2].end = pseudo_io_end;
sr[3].name = "insert";
sr[3].flags = IORESOURCE_IRQ;
sr[3].start = sr[3].end = cd_irq;
sr[4].name = "card";
sr[4].flags = IORESOURCE_IRQ;
sr[4].start = sr[4].end = card_irq;
i = 5;
if (stschg_irq) {
sr[i].name = "insert";
sr[i].flags = IORESOURCE_IRQ;
sr[i].start = sr[i].end = cd_irq;
i++;
}
if (eject_irq) {
sr[i].name = "eject";
sr[i].flags = IORESOURCE_IRQ;
sr[i].start = sr[i].end = eject_irq;
}
pd->resource = sr;
pd->num_resources = cnt;
ret = platform_device_add(pd);
if (!ret)
return 0;
platform_device_put(pd);
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;
}