Skip to contentSkip to conversation

adding physical address to point()

PATCH In review Jared Hulbert 1 participant 2 messages Apr 30, 2008 – May 1, 2008

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 adding physical address to point()

[MTD][NOR] adding physical address to point()

Adding the ability to get a physical address from point() in addition to virtual address. This physical address is required for XIP of userspace code from flash.

---

This is 3rd or 4th shot at submitting this patch.
It can be pulled from my git tree at:
git.infradead.org/users/jehulber/mtd.git

drivers/mtd/chips/cfi_cmdset_0001.c |   14 ++++++++------
drivers/mtd/devices/mtdram.c        |   11 +++++++----
drivers/mtd/devices/phram.c         |   13 +++++++------
drivers/mtd/devices/pmc551.c        |   27 +++++++++++++++++----------
drivers/mtd/devices/slram.c         |   15 ++++++++++-----
drivers/mtd/maps/uclinux.c          |    6 ++++--
drivers/mtd/mtdpart.c               |    8 ++++----
fs/jffs2/erase.c                    |    7 ++++---
fs/jffs2/readinode.c                |    9 +++++----
fs/jffs2/scan.c                     |    7 ++++---
include/linux/mtd/mtd.h             |    6 ++++--
include/linux/mtd/pmc551.h          |    5 +++--
12 files changed, 77 insertions(+), 51 deletions(-)
drivers/mtd/chips/cfi_cmdset_0001.c +8 -6
index e812df6..fcd1aec 100644
@@ -82,9 +82,8 @@ static struct mtd_info *cfi_intelext_setup (struct mtd_info *);
 static int cfi_intelext_partition_fixup(struct mtd_info *, struct cfi_private **);
 
 static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len,
-		     size_t *retlen, u_char **mtdbuf);
-static void cfi_intelext_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from,
-			size_t len);
+		     size_t *retlen, void **virt, resource_size_t *phys);
+static void cfi_intelext_unpoint(struct mtd_info *mtd, loff_t from, size_t len);
 
 static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long adr, int mode);
 static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode);
@@ -1240,7 +1239,8 @@ static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t a
 	return ret;
 }
 
-static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf)
+static int cfi_intelext_point(struct mtd_info *mtd, loff_t from, size_t len,
+		size_t *retlen, void **virt, resource_size_t *phys)
 {
 	struct map_info *map = mtd->priv;
 	struct cfi_private *cfi = map->fldrv_priv;
@@ -1257,8 +1257,10 @@ static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, si
 	chipnum = (from >> cfi->chipshift);
 	ofs = from - (chipnum << cfi->chipshift);
 
-	*mtdbuf = (void *)map->virt + cfi->chips[chipnum].start + ofs;
+	*virt = map->virt + cfi->chips[chipnum].start + ofs;
 	*retlen = 0;
+	if (phys)
+		*phys = map->phys + cfi->chips[chipnum].start + ofs;
 
 	while (len) {
 		unsigned long thislen;
@@ -1291,7 +1293,7 @@ static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, si
 	return 0;
 }
 
-static void cfi_intelext_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_t len)
+static void cfi_intelext_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
 {
 	struct map_info *map = mtd->priv;
 	struct cfi_private *cfi = map->fldrv_priv;
drivers/mtd/devices/mtdram.c +7 -4
index bf485ff..0399be1 100644
@@ -48,18 +48,21 @@ static int ram_erase(struct mtd_info *mtd, struct erase_info *instr)
 }
 
 static int ram_point(struct mtd_info *mtd, loff_t from, size_t len,
-		size_t *retlen, u_char **mtdbuf)
+		size_t *retlen, void **virt, resource_size_t *phys)
 {
 	if (from + len > mtd->size)
 		return -EINVAL;
 
-	*mtdbuf = mtd->priv + from;
+	/* can we return a physical address with this driver? */
+	if (phys)
+		return -EINVAL;
+
+	*virt = mtd->priv + from;
 	*retlen = len;
 	return 0;
 }
 
-static void ram_unpoint(struct mtd_info *mtd, u_char * addr, loff_t from,
-		size_t len)
+static void ram_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
 {
 }
 
drivers/mtd/devices/phram.c +7 -6
index 5f96018..c7987b1 100644
@@ -57,20 +57,21 @@ static int phram_erase(struct mtd_info *mtd, struct erase_info *instr)
 }
 
 static int phram_point(struct mtd_info *mtd, loff_t from, size_t len,
-		size_t *retlen, u_char **mtdbuf)
+		size_t *retlen, void **virt, resource_size_t *phys)
 {
-	u_char *start = mtd->priv;
-
 	if (from + len > mtd->size)
 		return -EINVAL;
 
-	*mtdbuf = start + from;
+	/* can we return a physical address with this driver? */
+	if (phys)
+		return -EINVAL;
+
+	*virt = mtd->priv + from;
 	*retlen = len;
 	return 0;
 }
 
-static void phram_unpoint(struct mtd_info *mtd, u_char *addr, loff_t from,
-		size_t len)
+static void phram_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
 {
 }
 
drivers/mtd/devices/pmc551.c +17 -10
index 7060a08..bc99817 100644
@@ -134,7 +134,8 @@ static int pmc551_erase(struct mtd_info *mtd, struct erase_info *instr)
 	eoff_lo = end & (priv->asize - 1);
 	soff_lo = instr->addr & (priv->asize - 1);
 
-	pmc551_point(mtd, instr->addr, instr->len, &retlen, &ptr);
+	pmc551_point(mtd, instr->addr, instr->len, &retlen,
+		     (void **)&ptr, NULL);
 
 	if (soff_hi == eoff_hi || mtd->size == priv->asize) {
 		/* The whole thing fits within one access, so just one shot
@@ -154,7 +155,8 @@ static int pmc551_erase(struct mtd_info *mtd, struct erase_info *instr)
 			}
 			soff_hi += priv->asize;
 			pmc551_point(mtd, (priv->base_map0 | soff_hi),
-				     priv->asize, &retlen, &ptr);
+				     priv->asize, &retlen,
+				     (void **)&ptr, NULL);
 		}
 		memset(ptr, 0xff, eoff_lo);
 	}
@@ -170,7 +172,7 @@ static int pmc551_erase(struct mtd_info *mtd, struct erase_info *instr)
 }
 
 static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len,
-			size_t * retlen, u_char ** mtdbuf)
+			size_t *retlen, void **virt, resource_size_t *phys)
 {
 	struct mypriv *priv = mtd->priv;
 	u32 soff_hi;
@@ -188,6 +190,10 @@ static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len,
 		return -EINVAL;
 	}
 
+	/* can we return a physical address with this driver? */
+	if (phys)
+		return -EINVAL;
+
 	soff_hi = from & ~(priv->asize - 1);
 	soff_lo = from & (priv->asize - 1);
 
@@ -198,13 +204,12 @@ static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len,
 		priv->curr_map0 = soff_hi;
 	}
 
-	*mtdbuf = priv->start + soff_lo;
+	*virt = priv->start + soff_lo;
 	*retlen = len;
 	return 0;
 }
 
-static void pmc551_unpoint(struct mtd_info *mtd, u_char * addr, loff_t from,
-			   size_t len)
+static void pmc551_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
 {
 #ifdef CONFIG_MTD_PMC551_DEBUG
 	printk(KERN_DEBUG "pmc551_unpoint()\n");
@@ -242,7 +247,7 @@ static int pmc551_read(struct mtd_info *mtd, loff_t from, size_t len,
 	soff_lo = from & (priv->asize - 1);
 	eoff_lo = end & (priv->asize - 1);
 
-	pmc551_point(mtd, from, len, retlen, &ptr);
+	pmc551_point(mtd, from, len, retlen, (void **)&ptr, NULL);
 
 	if (soff_hi == eoff_hi) {
 		/* The whole thing fits within one access, so just one shot
@@ -263,7 +268,8 @@ static int pmc551_read(struct mtd_info *mtd, loff_t from, size_t len,
 				goto out;
 			}
 			soff_hi += priv->asize;
-			pmc551_point(mtd, soff_hi, priv->asize, retlen, &ptr);
+			pmc551_point(mtd, soff_hi, priv->asize, retlen,
+				     (void **)&ptr, NULL);
 		}
 		memcpy(copyto, ptr, eoff_lo);
 		copyto += eoff_lo;
@@ -308,7 +314,7 @@ static int pmc551_write(struct mtd_info *mtd, loff_t to, size_t len,
 	soff_lo = to & (priv->asize - 1);
 	eoff_lo = end & (priv->asize - 1);
 
-	pmc551_point(mtd, to, len, retlen, &ptr);
+	pmc551_point(mtd, to, len, retlen, (void **)&ptr, NULL);
 
 	if (soff_hi == eoff_hi) {
 		/* The whole thing fits within one access, so just one shot
@@ -329,7 +335,8 @@ static int pmc551_write(struct mtd_info *mtd, loff_t to, size_t len,
 				goto out;
 			}
 			soff_hi += priv->asize;
-			pmc551_point(mtd, soff_hi, priv->asize, retlen, &ptr);
+			pmc551_point(mtd, soff_hi, priv->asize, retlen,
+				     (void **)&ptr, NULL);
 		}
 		memcpy(ptr, copyfrom, eoff_lo);
 		copyfrom += eoff_lo;
drivers/mtd/devices/slram.c +10 -5
index d293add..cb86db7 100644
@@ -76,8 +76,9 @@ static char *map;
 static slram_mtd_list_t *slram_mtdlist = NULL;
 
 static int slram_erase(struct mtd_info *, struct erase_info *);
-static int slram_point(struct mtd_info *, loff_t, size_t, size_t *, u_char **);
-static void slram_unpoint(struct mtd_info *, u_char *, loff_t,	size_t);
+static int slram_point(struct mtd_info *, loff_t, size_t, size_t *, void **,
+		resource_size_t *);
+static void slram_unpoint(struct mtd_info *, loff_t, size_t);
 static int slram_read(struct mtd_info *, loff_t, size_t, size_t *, u_char *);
 static int slram_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
 
@@ -104,19 +105,23 @@ static int slram_erase(struct mtd_info *mtd, struct erase_info *instr)
 }
 
 static int slram_point(struct mtd_info *mtd, loff_t from, size_t len,
-		size_t *retlen, u_char **mtdbuf)
+		size_t *retlen, void **virt, resource_size_t *phys)
 {
 	slram_priv_t *priv = mtd->priv;
 
+	/* can we return a physical address with this driver? */
+	if (phys)
+		return -EINVAL;
+
 	if (from + len > mtd->size)
 		return -EINVAL;
 
-	*mtdbuf = priv->start + from;
+	*virt = priv->start + from;
 	*retlen = len;
 	return(0);
 }
 
-static void slram_unpoint(struct mtd_info *mtd, u_char *addr, loff_t from, size_t len)
+static void slram_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
 {
 }
 
drivers/mtd/maps/uclinux.c +4 -2
index 14ffb1a..c42f4b8 100644
@@ -40,10 +40,12 @@ struct mtd_partition uclinux_romfs[] = {
 /****************************************************************************/
 
 int uclinux_point(struct mtd_info *mtd, loff_t from, size_t len,
-	size_t *retlen, u_char **mtdbuf)
+	size_t *retlen, void **virt, resource_size_t *phys)
 {
 	struct map_info *map = mtd->priv;
-	*mtdbuf = (u_char *) (map->virt + ((int) from));
+	*virt = map->virt + from;
+	if (phys)
+		*phys = map->phys + from;
 	*retlen = len;
 	return(0);
 }
drivers/mtd/mtdpart.c +4 -4
index c66902d..07c7011 100644
@@ -68,7 +68,7 @@ static int part_read (struct mtd_info *mtd, loff_t from, size_t len,
 }
 
 static int part_point (struct mtd_info *mtd, loff_t from, size_t len,
-			size_t *retlen, u_char **buf)
+			size_t *retlen, void **virt, resource_size_t *phys)
 {
 	struct mtd_part *part = PART(mtd);
 	if (from >= mtd->size)
@@ -76,14 +76,14 @@ static int part_point (struct mtd_info *mtd, loff_t from, size_t len,
 	else if (from + len > mtd->size)
 		len = mtd->size - from;
 	return part->master->point (part->master, from + part->offset,
-				    len, retlen, buf);
+				    len, retlen, virt, phys);
 }
 
-static void part_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_t len)
+static void part_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
 {
 	struct mtd_part *part = PART(mtd);
 
-	part->master->unpoint (part->master, addr, from + part->offset, len);
+	part->master->unpoint(part->master, from + part->offset, len);
 }
 
 static int part_read_oob(struct mtd_info *mtd, loff_t from,
fs/jffs2/erase.c +4 -3
index 25a640e..81eb4a6 100644
@@ -332,7 +332,8 @@ static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_erasebl
 	if (c->mtd->point) {
 		unsigned long *wordebuf;
 
-		ret = c->mtd->point(c->mtd, jeb->offset, c->sector_size, &retlen, (unsigned char **)&ebuf);
+		ret = c->mtd->point(c->mtd, jeb->offset, c->sector_size,
+				    &retlen, &ebuf, NULL);
 		if (ret) {
 			D1(printk(KERN_DEBUG "MTD point failed %d\n", ret));
 			goto do_flash_read;
@@ -340,7 +341,7 @@ static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_erasebl
 		if (retlen < c->sector_size) {
 			/* Don't muck about if it won't let us point to the whole erase sector */
 			D1(printk(KERN_DEBUG "MTD point returned len too short: 0x%zx\n", retlen));
-			c->mtd->unpoint(c->mtd, ebuf, jeb->offset, retlen);
+			c->mtd->unpoint(c->mtd, jeb->offset, retlen);
 			goto do_flash_read;
 		}
 		wordebuf = ebuf-sizeof(*wordebuf);
@@ -349,7 +350,7 @@ static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_erasebl
 		   if (*++wordebuf != ~0)
 			   break;
 		} while(--retlen);
-		c->mtd->unpoint(c->mtd, ebuf, jeb->offset, c->sector_size);
+		c->mtd->unpoint(c->mtd, jeb->offset, c->sector_size);
 		if (retlen) {
 			printk(KERN_WARNING "Newly-erased block contained word 0x%lx at offset 0x%08tx\n",
 			       *wordebuf, jeb->offset + c->sector_size-retlen*sizeof(*wordebuf));
fs/jffs2/readinode.c +5 -4
index 4cb4d76..37764f2 100644
@@ -63,10 +63,11 @@ static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info
 	/* TODO: instead, incapsulate point() stuff to jffs2_flash_read(),
 	 * adding and jffs2_flash_read_end() interface. */
 	if (c->mtd->point) {
-		err = c->mtd->point(c->mtd, ofs, len, &retlen, &buffer);
+		err = c->mtd->point(c->mtd, ofs, len, &retlen,
+				    (void **)&buffer, NULL);
 		if (!err && retlen < len) {
 			JFFS2_WARNING("MTD point returned len too short: %zu instead of %u.\n", retlen, tn->csize);
-			c->mtd->unpoint(c->mtd, buffer, ofs, retlen);
+			c->mtd->unpoint(c->mtd, ofs, retlen);
 		} else if (err)
 			JFFS2_WARNING("MTD point failed: error code %d.\n", err);
 		else
@@ -100,7 +101,7 @@ static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info
 		kfree(buffer);
 #ifndef __ECOS
 	else
-		c->mtd->unpoint(c->mtd, buffer, ofs, len);
+		c->mtd->unpoint(c->mtd, ofs, len);
 #endif
 
 	if (crc != tn->data_crc) {
@@ -136,7 +137,7 @@ free_out:
 		kfree(buffer);
 #ifndef __ECOS
 	else
-		c->mtd->unpoint(c->mtd, buffer, ofs, len);
+		c->mtd->unpoint(c->mtd, ofs, len);
 #endif
 	return err;
 }
fs/jffs2/scan.c +4 -3
index 272872d..b1b3884 100644
@@ -97,11 +97,12 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
 	size_t pointlen;
 
 	if (c->mtd->point) {
-		ret = c->mtd->point (c->mtd, 0, c->mtd->size, &pointlen, &flashbuf);
+		ret = c->mtd->point(c->mtd, 0, c->mtd->size, &pointlen,
+				    (void **)&flashbuf, NULL);
 		if (!ret && pointlen < c->mtd->size) {
 			/* Don't muck about if it won't let us point to the whole flash */
 			D1(printk(KERN_DEBUG "MTD point returned len too short: 0x%zx\n", pointlen));
-			c->mtd->unpoint(c->mtd, flashbuf, 0, pointlen);
+			c->mtd->unpoint(c->mtd, 0, pointlen);
 			flashbuf = NULL;
 		}
 		if (ret)
@@ -267,7 +268,7 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
 		kfree(flashbuf);
 #ifndef __ECOS
 	else
-		c->mtd->unpoint(c->mtd, flashbuf, 0, c->mtd->size);
+		c->mtd->unpoint(c->mtd, 0, c->mtd->size);
 #endif
 	if (s)
 		kfree(s);
include/linux/mtd/mtd.h +4 -2
index 0a13bb3..245f909 100644
@@ -143,10 +143,12 @@ struct mtd_info {
 	int (*erase) (struct mtd_info *mtd, struct erase_info *instr);
 
 	/* This stuff for eXecute-In-Place */
-	int (*point) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf);
+	/* phys is optional and may be set to NULL */
+	int (*point) (struct mtd_info *mtd, loff_t from, size_t len,
+			size_t *retlen, void **virt, resource_size_t *phys);
 
 	/* We probably shouldn't allow XIP if the unpoint isn't a NULL */
-	void (*unpoint) (struct mtd_info *mtd, u_char * addr, loff_t from, size_t len);
+	void (*unpoint) (struct mtd_info *mtd, loff_t from, size_t len);
 
 
 	int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
include/linux/mtd/pmc551.h +3 -2
index a7f6d20..5cc070c 100644
@@ -36,8 +36,9 @@ struct mypriv {
  * Function Prototypes
  */
 static int pmc551_erase(struct mtd_info *, struct erase_info *);
-static void pmc551_unpoint(struct mtd_info *, u_char *, loff_t, size_t);
-static int pmc551_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf);
+static void pmc551_unpoint(struct mtd_info *, loff_t, size_t);
+static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len,
+		size_t *retlen, void **virt, resource_size_t *phys);
 static int pmc551_read(struct mtd_info *, loff_t, size_t, size_t *, u_char *);
 static int pmc551_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
#1 lore raw

What are the chances of getting this merged in time for 2.6.26?

Quoted 477 lines · Jared Hulbert

[MTD][NOR] adding physical address to point()

Adding the ability to get a physical address from point() in addition to virtual address. This physical address is required for XIP of userspace code from flash.

---

This is 3rd or 4th shot at submitting this patch. It can be pulled from my git tree at:
git.infradead.org/users/jehulber/mtd.git

 drivers/mtd/chips/cfi_cmdset_0001.c |   14 ++++++++------
 drivers/mtd/devices/mtdram.c        |   11 +++++++----
 drivers/mtd/devices/phram.c         |   13 +++++++------
 drivers/mtd/devices/pmc551.c        |   27 +++++++++++++++++----------
 drivers/mtd/devices/slram.c         |   15 ++++++++++-----
 drivers/mtd/maps/uclinux.c          |    6 ++++--
 drivers/mtd/mtdpart.c               |    8 ++++----
 fs/jffs2/erase.c                    |    7 ++++---
 fs/jffs2/readinode.c                |    9 +++++----
 fs/jffs2/scan.c                     |    7 ++++---
 include/linux/mtd/mtd.h             |    6 ++++--
 include/linux/mtd/pmc551.h          |    5 +++--
12 files changed, 77 insertions(+), 51 deletions(-)

diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index e812df6..fcd1aec 100644

--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -82,9 +82,8 @@ static struct mtd_info *cfi_intelext_setup (struct mtd_info *);
static int cfi_intelext_partition_fixup(struct mtd_info *, struct cfi_private **);

static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len,
- size_t *retlen, u_char **mtdbuf);
-static void cfi_intelext_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from,
- size_t len);
+ size_t *retlen, void **virt, resource_size_t *phys);
+static void cfi_intelext_unpoint(struct mtd_info *mtd, loff_t from, size_t len);

static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long adr, int mode); static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode);
@@ -1240,7 +1239,8 @@ static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t a

        return ret;

}

-static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf) +static int cfi_intelext_point(struct mtd_info *mtd, loff_t from, size_t len,
+ size_t *retlen, void **virt, resource_size_t *phys)

  {
        struct map_info *map = mtd->priv;
        struct cfi_private *cfi = map->fldrv_priv;

@@ -1257,8 +1257,10 @@ static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, si

        chipnum = (from >> cfi->chipshift);
        ofs = from - (chipnum << cfi->chipshift);

- *mtdbuf = (void *)map->virt + cfi->chips[chipnum].start + ofs;

 +       *virt = map->virt + cfi->chips[chipnum].start + ofs;
        *retlen = 0;

+ if (phys)
+ *phys = map->phys + cfi->chips[chipnum].start + ofs;

        while (len) {
                unsigned long thislen;

@@ -1291,7 +1293,7 @@ static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, si

        return 0;

}

-static void cfi_intelext_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_t len) +static void cfi_intelext_unpoint(struct mtd_info *mtd, loff_t from, size_t len)

  {
        struct map_info *map = mtd->priv;
        struct cfi_private *cfi = map->fldrv_priv;

diff --git a/drivers/mtd/devices/mtdram.c b/drivers/mtd/devices/mtdram.c index bf485ff..0399be1 100644

--- a/drivers/mtd/devices/mtdram.c
+++ b/drivers/mtd/devices/mtdram.c
@@ -48,18 +48,21 @@ static int ram_erase(struct mtd_info *mtd, struct erase_info *instr)

}

static int ram_point(struct mtd_info *mtd, loff_t from, size_t len,
- size_t *retlen, u_char **mtdbuf)
+ size_t *retlen, void **virt, resource_size_t *phys)

  {
        if (from + len > mtd->size)
                return -EINVAL;
 -       *mtdbuf = mtd->priv + from;
 +       /* can we return a physical address with this driver? */
 +       if (phys)
 +               return -EINVAL;
 +
 +       *virt = mtd->priv + from;
        *retlen = len;
        return 0;

}

-static void ram_unpoint(struct mtd_info *mtd, u_char * addr, loff_t from,
- size_t len)
+static void ram_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
{
}

diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c index 5f96018..c7987b1 100644

--- a/drivers/mtd/devices/phram.c
+++ b/drivers/mtd/devices/phram.c
@@ -57,20 +57,21 @@ static int phram_erase(struct mtd_info *mtd, struct erase_info *instr)
}

static int phram_point(struct mtd_info *mtd, loff_t from, size_t len,
- size_t *retlen, u_char **mtdbuf)
+ size_t *retlen, void **virt, resource_size_t *phys)
{
- u_char *start = mtd->priv;
-

        if (from + len > mtd->size)
                return -EINVAL;
 -       *mtdbuf = start + from;
 +       /* can we return a physical address with this driver? */
 +       if (phys)
 +               return -EINVAL;
 +
 +       *virt = mtd->priv + from;
        *retlen = len;
        return 0;

}

-static void phram_unpoint(struct mtd_info *mtd, u_char *addr, loff_t from,
- size_t len)
+static void phram_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
{
}

diff --git a/drivers/mtd/devices/pmc551.c b/drivers/mtd/devices/pmc551.c index 7060a08..bc99817 100644
--- a/drivers/mtd/devices/pmc551.c
+++ b/drivers/mtd/devices/pmc551.c
@@ -134,7 +134,8 @@ static int pmc551_erase(struct mtd_info *mtd, struct erase_info *instr)

        eoff_lo = end & (priv->asize - 1);
        soff_lo = instr->addr & (priv->asize - 1);

- pmc551_point(mtd, instr->addr, instr->len, &retlen, &ptr);
+ pmc551_point(mtd, instr->addr, instr->len, &retlen,
+ (void **)&ptr, NULL);

        if (soff_hi == eoff_hi || mtd->size == priv->asize) {
                /* The whole thing fits within one access, so just one shot
 @@ -154,7 +155,8 @@ static int pmc551_erase(struct mtd_info *mtd, struct erase_info *instr)
                        }
                        soff_hi += priv->asize;
                        pmc551_point(mtd, (priv->base_map0 | soff_hi),
 -                                    priv->asize, &retlen, &ptr);
 +                                    priv->asize, &retlen,
 +                                    (void **)&ptr, NULL);
                }
                memset(ptr, 0xff, eoff_lo);
        }

@@ -170,7 +172,7 @@ static int pmc551_erase(struct mtd_info *mtd, struct erase_info *instr)
}

static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len,
- size_t * retlen, u_char ** mtdbuf)
+ size_t *retlen, void **virt, resource_size_t *phys)

  {
        struct mypriv *priv = mtd->priv;
        u32 soff_hi;
 @@ -188,6 +190,10 @@ static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len,
                return -EINVAL;
        }

+ /* can we return a physical address with this driver? */
+ if (phys)
+ return -EINVAL;
+

        soff_hi = from & ~(priv->asize - 1);
        soff_lo = from & (priv->asize - 1);

@@ -198,13 +204,12 @@ static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len,

                priv->curr_map0 = soff_hi;
        }

- *mtdbuf = priv->start + soff_lo;

 +       *virt = priv->start + soff_lo;
        *retlen = len;
        return 0;

}

-static void pmc551_unpoint(struct mtd_info *mtd, u_char * addr, loff_t from,
- size_t len)
+static void pmc551_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
{

  #ifdef CONFIG_MTD_PMC551_DEBUG
        printk(KERN_DEBUG "pmc551_unpoint()\n");
 @@ -242,7 +247,7 @@ static int pmc551_read(struct mtd_info *mtd, loff_t from, size_t len,
        soff_lo = from & (priv->asize - 1);
        eoff_lo = end & (priv->asize - 1);

- pmc551_point(mtd, from, len, retlen, &ptr);
+ pmc551_point(mtd, from, len, retlen, (void **)&ptr, NULL);

        if (soff_hi == eoff_hi) {
                /* The whole thing fits within one access, so just one shot
 @@ -263,7 +268,8 @@ static int pmc551_read(struct mtd_info *mtd, loff_t from, size_t len,
                                goto out;
                        }
                        soff_hi += priv->asize;
 -                       pmc551_point(mtd, soff_hi, priv->asize, retlen, &ptr);
 +                       pmc551_point(mtd, soff_hi, priv->asize, retlen,
 +                                    (void **)&ptr, NULL);
                }
                memcpy(copyto, ptr, eoff_lo);
                copyto += eoff_lo;
 @@ -308,7 +314,7 @@ static int pmc551_write(struct mtd_info *mtd, loff_t to, size_t len,
        soff_lo = to & (priv->asize - 1);
        eoff_lo = end & (priv->asize - 1);

- pmc551_point(mtd, to, len, retlen, &ptr);
+ pmc551_point(mtd, to, len, retlen, (void **)&ptr, NULL);

        if (soff_hi == eoff_hi) {
                /* The whole thing fits within one access, so just one shot
 @@ -329,7 +335,8 @@ static int pmc551_write(struct mtd_info *mtd, loff_t to, size_t len,
                                goto out;
                        }
                        soff_hi += priv->asize;
 -                       pmc551_point(mtd, soff_hi, priv->asize, retlen, &ptr);
 +                       pmc551_point(mtd, soff_hi, priv->asize, retlen,
 +                                    (void **)&ptr, NULL);
                }
                memcpy(ptr, copyfrom, eoff_lo);
                copyfrom += eoff_lo;

diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c index d293add..cb86db7 100644
--- a/drivers/mtd/devices/slram.c
+++ b/drivers/mtd/devices/slram.c
@@ -76,8 +76,9 @@ static char *map;
static slram_mtd_list_t *slram_mtdlist = NULL;

static int slram_erase(struct mtd_info *, struct erase_info *);
-static int slram_point(struct mtd_info *, loff_t, size_t, size_t *, u_char **); -static void slram_unpoint(struct mtd_info *, u_char *, loff_t, size_t); +static int slram_point(struct mtd_info *, loff_t, size_t, size_t *, void **,
+ resource_size_t *);
+static void slram_unpoint(struct mtd_info *, loff_t, size_t);
static int slram_read(struct mtd_info *, loff_t, size_t, size_t *, u_char *); static int slram_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);

@@ -104,19 +105,23 @@ static int slram_erase(struct mtd_info *mtd, struct erase_info *instr)
}

static int slram_point(struct mtd_info *mtd, loff_t from, size_t len,
- size_t *retlen, u_char **mtdbuf)
+ size_t *retlen, void **virt, resource_size_t *phys)

  {
        slram_priv_t *priv = mtd->priv;

+ /* can we return a physical address with this driver? */
+ if (phys)
+ return -EINVAL;
+

        if (from + len > mtd->size)
                return -EINVAL;

- *mtdbuf = priv->start + from;

 +       *virt = priv->start + from;
        *retlen = len;
        return(0);

}

-static void slram_unpoint(struct mtd_info *mtd, u_char *addr, loff_t from, size_t len) +static void slram_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
{
}

diff --git a/drivers/mtd/maps/uclinux.c b/drivers/mtd/maps/uclinux.c index 14ffb1a..c42f4b8 100644
--- a/drivers/mtd/maps/uclinux.c
+++ b/drivers/mtd/maps/uclinux.c
@@ -40,10 +40,12 @@ struct mtd_partition uclinux_romfs[] = {
/****************************************************************************/

int uclinux_point(struct mtd_info *mtd, loff_t from, size_t len,
- size_t *retlen, u_char **mtdbuf)
+ size_t *retlen, void **virt, resource_size_t *phys)

  {
        struct map_info *map = mtd->priv;
 -       *mtdbuf = (u_char *) (map->virt + ((int) from));
 +       *virt = map->virt + from;
 +       if (phys)
 +               *phys = map->phys + from;
        *retlen = len;
        return(0);

}
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index c66902d..07c7011 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -68,7 +68,7 @@ static int part_read (struct mtd_info *mtd, loff_t from, size_t len,
}

static int part_point (struct mtd_info *mtd, loff_t from, size_t len,
- size_t *retlen, u_char **buf)
+ size_t *retlen, void **virt, resource_size_t *phys)

  {
        struct mtd_part *part = PART(mtd);
        if (from >= mtd->size)
 @@ -76,14 +76,14 @@ static int part_point (struct mtd_info *mtd, loff_t from, size_t len,
        else if (from + len > mtd->size)
                len = mtd->size - from;
        return part->master->point (part->master, from + part->offset,

- len, retlen, buf);
+ len, retlen, virt, phys);
}

-static void part_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_t len) +static void part_unpoint(struct mtd_info *mtd, loff_t from, size_t len)

  {
        struct mtd_part *part = PART(mtd);

- part->master->unpoint (part->master, addr, from + part->offset, len);
+ part->master->unpoint(part->master, from + part->offset, len);
}

static int part_read_oob(struct mtd_info *mtd, loff_t from,
diff --git a/fs/jffs2/erase.c b/fs/jffs2/erase.c index 25a640e..81eb4a6 100644

--- a/fs/jffs2/erase.c
+++ b/fs/jffs2/erase.c
@@ -332,7 +332,8 @@ static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_erasebl

        if (c->mtd->point) {
                unsigned long *wordebuf;

- ret = c->mtd->point(c->mtd, jeb->offset, c->sector_size, &retlen, (unsigned char **)&ebuf);
+ ret = c->mtd->point(c->mtd, jeb->offset, c->sector_size,

 +                                   &retlen, &ebuf, NULL);
                if (ret) {
                        D1(printk(KERN_DEBUG "MTD point failed %d\n", ret));
                        goto do_flash_read;
 @@ -340,7 +341,7 @@ static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_erasebl
                if (retlen < c->sector_size) {
                        /* Don't muck about if it won't let us point to the whole erase sector */
                        D1(printk(KERN_DEBUG "MTD point returned len too short: 0x%zx\n", retlen));
 -                       c->mtd->unpoint(c->mtd, ebuf, jeb->offset, retlen);
 +                       c->mtd->unpoint(c->mtd, jeb->offset, retlen);
                        goto do_flash_read;
                }
                wordebuf = ebuf-sizeof(*wordebuf);
 @@ -349,7 +350,7 @@ static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_erasebl
                   if (*++wordebuf != ~0)
                           break;
                } while(--retlen);
 -               c->mtd->unpoint(c->mtd, ebuf, jeb->offset, c->sector_size);
 +               c->mtd->unpoint(c->mtd, jeb->offset, c->sector_size);
                if (retlen) {
                        printk(KERN_WARNING "Newly-erased block contained word 0x%lx at offset 0x%08tx\n",
                               *wordebuf, jeb->offset + c->sector_size-retlen*sizeof(*wordebuf));

diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c index 4cb4d76..37764f2 100644

--- a/fs/jffs2/readinode.c
+++ b/fs/jffs2/readinode.c
@@ -63,10 +63,11 @@ static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info

        /* TODO: instead, incapsulate point() stuff to jffs2_flash_read(),
         * adding and jffs2_flash_read_end() interface. */
        if (c->mtd->point) {
 -               err = c->mtd->point(c->mtd, ofs, len, &retlen, &buffer);
 +               err = c->mtd->point(c->mtd, ofs, len, &retlen,
 +                                   (void **)&buffer, NULL);
                if (!err && retlen < len) {
                        JFFS2_WARNING("MTD point returned len too short: %zu instead of %u.\n", retlen, tn->csize);
 -                       c->mtd->unpoint(c->mtd, buffer, ofs, retlen);
 +                       c->mtd->unpoint(c->mtd, ofs, retlen);
                } else if (err)
                        JFFS2_WARNING("MTD point failed: error code %d.\n", err);
                else
 @@ -100,7 +101,7 @@ static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info
                kfree(buffer);

#ifndef __ECOS
else
- c->mtd->unpoint(c->mtd, buffer, ofs, len);
+ c->mtd->unpoint(c->mtd, ofs, len);
#endif

        if (crc != tn->data_crc) {
 @@ -136,7 +137,7 @@ free_out:
                kfree(buffer);
  #ifndef __ECOS
        else
 -               c->mtd->unpoint(c->mtd, buffer, ofs, len);
 +               c->mtd->unpoint(c->mtd, ofs, len);
  #endif
        return err;
  }
 diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c
 index 272872d..b1b3884 100644
 --- a/fs/jffs2/scan.c
 +++ b/fs/jffs2/scan.c
 @@ -97,11 +97,12 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
        size_t pointlen;

        if (c->mtd->point) {
 -               ret = c->mtd->point (c->mtd, 0, c->mtd->size, &pointlen, &flashbuf);
 +               ret = c->mtd->point(c->mtd, 0, c->mtd->size, &pointlen,
 +                                   (void **)&flashbuf, NULL);
                if (!ret && pointlen < c->mtd->size) {
                        /* Don't muck about if it won't let us point to the whole flash */
                        D1(printk(KERN_DEBUG "MTD point returned len too short: 0x%zx\n", pointlen));
 -                       c->mtd->unpoint(c->mtd, flashbuf, 0, pointlen);
 +                       c->mtd->unpoint(c->mtd, 0, pointlen);
                        flashbuf = NULL;
                }
                if (ret)
 @@ -267,7 +268,7 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
                kfree(flashbuf);
  #ifndef __ECOS
        else
 -               c->mtd->unpoint(c->mtd, flashbuf, 0, c->mtd->size);
 +               c->mtd->unpoint(c->mtd, 0, c->mtd->size);
  #endif
        if (s)
                kfree(s);
 diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
 index 0a13bb3..245f909 100644
 --- a/include/linux/mtd/mtd.h
 +++ b/include/linux/mtd/mtd.h
 @@ -143,10 +143,12 @@ struct mtd_info {
        int (*erase) (struct mtd_info *mtd, struct erase_info *instr);

        /* This stuff for eXecute-In-Place */
 -       int (*point) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf);
 +       /* phys is optional and may be set to NULL */
 +       int (*point) (struct mtd_info *mtd, loff_t from, size_t len,

+ size_t *retlen, void **virt, resource_size_t *phys);

        /* We probably shouldn't allow XIP if the unpoint isn't a NULL */

- void (*unpoint) (struct mtd_info *mtd, u_char * addr, loff_t from, size_t len);
+ void (*unpoint) (struct mtd_info *mtd, loff_t from, size_t len);

        int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);

diff --git a/include/linux/mtd/pmc551.h b/include/linux/mtd/pmc551.h
index a7f6d20..5cc070c 100644
--- a/include/linux/mtd/pmc551.h
+++ b/include/linux/mtd/pmc551.h
@@ -36,8 +36,9 @@ struct mypriv {
* Function Prototypes
*/
static int pmc551_erase(struct mtd_info *, struct erase_info *);
-static void pmc551_unpoint(struct mtd_info *, u_char *, loff_t, size_t);
-static int pmc551_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf); +static void pmc551_unpoint(struct mtd_info *, loff_t, size_t);
+static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len,
+ size_t *retlen, void **virt, resource_size_t *phys);
static int pmc551_read(struct mtd_info *, loff_t, size_t, size_t *, u_char *);
static int pmc551_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);