Commit 4ff7118a authored by Russell King's avatar Russell King

[ARM] mtd: update mapping drivers.

This updates dc21285.c, integrator-flash.c and sa1100-flash.c map
drivers.
parent 18c204c8
......@@ -5,7 +5,7 @@
*
* This code is GPL
*
* $Id: dc21285.c,v 1.21 2004/09/16 23:27:13 gleixner Exp $
* $Id: dc21285.c,v 1.22 2004/11/01 13:39:21 rmk Exp $
*/
#include <linux/config.h>
#include <linux/module.h>
......@@ -32,7 +32,8 @@ static struct mtd_info *dc21285_mtd;
* is unpredictible. So we have a 25us penalty per
* write access.
*/
static void nw_en_write(void) {
static void nw_en_write(void)
{
extern spinlock_t gpio_lock;
unsigned long flags;
......@@ -55,53 +56,60 @@ static void nw_en_write(void) {
static map_word dc21285_read8(struct map_info *map, unsigned long ofs)
{
return *(uint8_t*)(map->map_priv_1 + ofs);
map_word val;
val.x[0] = *(uint8_t*)(map->virt + ofs);
return val;
}
static map_word dc21285_read16(struct map_info *map, unsigned long ofs)
{
return *(uint16_t*)(map->map_priv_1 + ofs);
map_word val;
val.x[0] = *(uint16_t*)(map->virt + ofs);
return val;
}
static map_word dc21285_read32(struct map_info *map, unsigned long ofs)
{
return *(uint32_t*)(map->map_priv_1 + ofs);
map_word val;
val.x[0] = *(uint32_t*)(map->virt + ofs);
return val;
}
static void dc21285_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
{
memcpy(to, (void*)(map->map_priv_1 + from), len);
memcpy(to, (void*)(map->virt + from), len);
}
static void dc21285_write(struct map_info *map, map_word d, unsigned long adr)
static void dc21285_write8(struct map_info *map, const map_word d, unsigned long adr)
{
if (machine_is_netwinder())
nw_en_write();
*CSR_ROMWRITEREG = adr & 3;
adr &= ~3;
*(uint8_t*)(map->map_priv_1 + adr) = d.x[0];
*(uint8_t*)(map->virt + adr) = d.x[0];
}
static void dc21285_write16(struct map_info *map, map_word d, unsigned long adr)
static void dc21285_write16(struct map_info *map, const map_word d, unsigned long adr)
{
if (machine_is_netwinder())
nw_en_write();
*CSR_ROMWRITEREG = adr & 3;
adr &= ~3;
*(uint16_t*)(map->map_priv_1 + adr) = d.x[0];
*(uint16_t*)(map->virt + adr) = d.x[0];
}
static void dc21285_write32(struct map_info *map, map_word d, unsigned long adr)
static void dc21285_write32(struct map_info *map, const map_word d, unsigned long adr)
{
if (machine_is_netwinder())
nw_en_write();
*(uint32_t*)(map->map_priv_1 + adr) = d.x[0];
*(uint32_t*)(map->virt + adr) = d.x[0];
}
static void dc21285_copy_to_32(struct map_info *map, unsigned long to, const void *from, ssize_t len)
{
while (len > 0) {
uint32_t d = *((uint32_t*)from)++;
map_word d;
d.x[0] = *((uint32_t*)from)++;
dc21285_write32(map, d, to);
to += 4;
len -= 4;
......@@ -111,7 +119,8 @@ static void dc21285_copy_to_32(struct map_info *map, unsigned long to, const voi
static void dc21285_copy_to_16(struct map_info *map, unsigned long to, const void *from, ssize_t len)
{
while (len > 0) {
uint16_t d = *((uint16_t*)from)++;
map_word d;
d.x[0] = *((uint16_t*)from)++;
dc21285_write16(map, d, to);
to += 2;
len -= 2;
......@@ -120,7 +129,8 @@ static void dc21285_copy_to_16(struct map_info *map, unsigned long to, const voi
static void dc21285_copy_to_8(struct map_info *map, unsigned long to, const void *from, ssize_t len)
{
uint8_t d = *((uint8_t*)from)++;
map_word d;
d.x[0] = *((uint8_t*)from)++;
dc21285_write8(map, d, to);
to++;
len--;
......@@ -135,8 +145,8 @@ static struct map_info dc21285_map = {
/* Partition stuff */
static struct mtd_partition *dc21285_parts;
#ifdef CONFIG_MTD_PARTITIONS
static struct mtd_partition *dc21285_parts;
static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
#endif
......@@ -163,10 +173,10 @@ static int __init init_dc21285(void)
break;
case SA110_CNTL_ROMWIDTH_32:
dc21285_map.bankwidth = 4;
break;
dc21285_map.read = dc21285_read32;
dc21285_map.write = dc21285_write32;
dc21285_map.copy_to = dc21285_copy_to_32;
break;
default:
printk (KERN_ERR "DC21285 flash: undefined bankwidth\n");
return -ENXIO;
......@@ -175,8 +185,8 @@ static int __init init_dc21285(void)
dc21285_map.bankwidth*8);
/* Let's map the flash area */
dc21285_map.map_priv_1 = (void __iomem *)ioremap(DC21285_FLASH, 16*1024*1024);
if (!dc21285_map.map_priv_1) {
dc21285_map.virt = ioremap(DC21285_FLASH, 16*1024*1024);
if (!dc21285_map.virt) {
printk("Failed to ioremap\n");
return -EIO;
}
......@@ -188,14 +198,14 @@ static int __init init_dc21285(void)
}
if (!dc21285_mtd) {
iounmap((void *)dc21285_map.map_priv_1);
iounmap(dc21285_map.virt);
return -ENXIO;
}
dc21285_mtd->owner = THIS_MODULE;
#ifdef CONFIG_MTD_PARTITIONS
nrparts = parse_mtd_partitions(dc21285_mtd, probes, &dc21285_parts, (void *)0);
nrparts = parse_mtd_partitions(dc21285_mtd, probes, &dc21285_parts, 0);
if (nrparts > 0)
add_mtd_partitions(dc21285_mtd, dc21285_parts, nrparts);
else
......@@ -231,7 +241,7 @@ static void __exit cleanup_dc21285(void)
del_mtd_device(dc21285_mtd);
map_destroy(dc21285_mtd);
iounmap((void *)dc21285_map.map_priv_1);
iounmap(dc21285_map.virt);
}
module_init(init_dc21285);
......
......@@ -22,7 +22,7 @@
This is access code for flashes using ARM's flash partitioning
standards.
$Id: integrator-flash.c,v 1.17 2004/09/16 23:27:13 gleixner Exp $
$Id: integrator-flash.c,v 1.18 2004/11/01 13:26:15 rmk Exp $
======================================================================*/
......@@ -75,7 +75,7 @@ static int armflash_probe(struct device *_dev)
unsigned int size = res->end - res->start + 1;
struct armflash_info *info;
int err;
void *base;
void __iomem *base;
info = kmalloc(sizeof(struct armflash_info), GFP_KERNEL);
if (!info) {
......@@ -110,7 +110,7 @@ static int armflash_probe(struct device *_dev)
info->map.size = size;
info->map.bankwidth = plat->width;
info->map.phys = res->start;
info->map.virt = (void __iomem *) base;
info->map.virt = base;
info->map.name = dev->dev.bus_id;
info->map.set_vpp = armflash_set_vpp;
......@@ -179,7 +179,7 @@ static int armflash_remove(struct device *_dev)
if (info->parts)
kfree(info->parts);
iounmap((void *)info->map.virt);
iounmap(info->map.virt);
release_resource(info->res);
kfree(info->res);
......
......@@ -3,7 +3,7 @@
*
* (C) 2000 Nicolas Pitre <nico@cam.org>
*
* $Id: sa1100-flash.c,v 1.39 2004/07/12 21:59:44 dwmw2 Exp $
* $Id: sa1100-flash.c,v 1.47 2004/11/01 13:44:36 rmk Exp $
*/
#include <linux/config.h>
......@@ -496,6 +496,32 @@ static struct mtd_partition huw_webpanel_partitions[] = {
};
#endif
#ifdef CONFIG_SA1100_JORNADA56X
static struct mtd_partition jornada56x_partitions[] = {
{
.name = "bootldr",
.size = 0x00040000,
.offset = 0,
.mask_flags = MTD_WRITEABLE,
}, {
.name = "rootfs",
.size = MTDPART_SIZ_FULL,
.offset = MTDPART_OFS_APPEND,
}
};
static void jornada56x_set_vpp(struct map_info *map, int vpp)
{
if (vpp)
GPSR = GPIO_GPIO26;
else
GPCR = GPIO_GPIO26;
GPDR |= GPIO_GPIO26;
}
#else
#define jornada56x_set_vpp NULL
#endif
#ifdef CONFIG_SA1100_JORNADA720
static struct mtd_partition jornada720_partitions[] = {
{
......@@ -822,6 +848,12 @@ static int __init sa1100_static_partitions(struct mtd_partition **parts)
nb_parts = ARRAY_SIZE(huw_webpanel_partitions);
}
#endif
#ifdef CONFIG_SA1100_JORNADA56X
if (machine_is_jornada56x()) {
*parts = jornada56x_partitions;
nb_parts = ARRAY_SIZE(jornada56x_partitions);
}
#endif
#ifdef CONFIG_SA1100_JORNADA720
if (machine_is_jornada720()) {
*parts = jornada720_partitions;
......@@ -885,11 +917,10 @@ struct sa_info {
unsigned long base;
unsigned long size;
int width;
void __iomem *vbase;
void (*set_vpp)(struct map_info *, int);
char name[16];
struct map_info *map;
struct mtd_info *mtd;
struct resource *res;
};
#define NR_SUBMTD 4
......@@ -918,21 +949,22 @@ static int __init sa1100_setup_mtd(struct sa_info *sa, int nr, struct mtd_info *
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) {
sa[i].map = maps + i;
sa[i].map->name = sa[i].name;
sprintf(sa[i].name, "sa1100-%d", i);
if (!request_mem_region(sa[i].base, sa[i].size, sa[i].name)) {
i -= 1;
ret = -EBUSY;
break;
}
sa[i].map = maps + i;
sa[i].vbase = ioremap(sa[i].base, sa[i].size);
if (!sa[i].vbase) {
sa[i].map->virt = ioremap(sa[i].base, sa[i].size);
if (!sa[i].map->virt) {
ret = -ENOMEM;
break;
}
sa[i].map->virt = sa[i].vbase;
sa[i].map->phys = sa[i].base;
sa[i].map->set_vpp = sa[i].set_vpp;
sa[i].map->bankwidth = sa[i].width;
......@@ -964,10 +996,9 @@ static int __init sa1100_setup_mtd(struct sa_info *sa, int nr, struct mtd_info *
* 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;
iounmap(sa[i].map->virt);
sa[i].map->virt = NULL;
release_mem_region(sa[i].base, sa[i].size);
}
/*
......@@ -986,7 +1017,7 @@ static int __init sa1100_setup_mtd(struct sa_info *sa, int nr, struct mtd_info *
*/
#ifdef CONFIG_MTD_CONCAT
*rmtd = mtd_concat_create(subdev, found,
"sa1100 flash");
"sa1100");
if (*rmtd == NULL)
ret = -ENXIO;
#else
......@@ -1004,11 +1035,10 @@ static int __init sa1100_setup_mtd(struct sa_info *sa, int nr, struct mtd_info *
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--);
if (sa[i].map->virt)
iounmap(sa[i].map->virt);
release_mem_region(sa[i].base, sa[i].size);
} while (i-- > 0);
kfree(maps);
}
......@@ -1030,10 +1060,9 @@ static void __exit sa1100_destroy_mtd(struct sa_info *sa, struct mtd_info *mtd)
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);
if (sa[i].map->virt)
iounmap(sa[i].map->virt);
release_mem_region(sa[i].base, sa[i].size);
}
kfree(sa[0].map);
}
......@@ -1044,13 +1073,9 @@ static void __exit sa1100_destroy_mtd(struct sa_info *sa, struct mtd_info *mtd)
* - 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 map_info map;
struct mtd_info *mtd;
printk(KERN_INFO "* Probing 0x%08lx: MSC = 0x%04x %d bit ",
......@@ -1066,19 +1091,23 @@ static void __init sa1100_probe_one_cs(unsigned int msc, unsigned long phys)
return;
}
sa1100_probe_map.bankwidth = 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)
memset(&map, 0, sizeof(struct map_info));
map.name = "Probe";
map.bankwidth = msc & MSC_RBW ? 2 : 4;
map.size = SZ_1M;
map.phys = phys;
map.virt = ioremap(phys, SZ_1M);
if (map.virt == NULL)
goto fail;
simple_map_init(&sa1100_probe_map);
simple_map_init(&map);
/* Shame cfi_probe blurts out kernel messages... */
mtd = do_map_probe("cfi_probe", &sa1100_probe_map);
mtd = do_map_probe("cfi_probe", &map);
if (mtd)
map_destroy(mtd);
iounmap((void *)sa1100_probe_map.virt);
iounmap(map.virt);
if (!mtd)
goto fail;
......@@ -1176,6 +1205,12 @@ static int __init sa1100_locate_flash(void)
info[0].size = SZ_32M;
nr = 1;
}
if (machine_is_jornada56x()) {
info[0].set_vpp = jornada56x_set_vpp;
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;
......
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