From 5fbabf3f45a15c2b39170980cee01368138f4d79 Mon Sep 17 00:00:00 2001 From: Paul Parsons Date: Wed, 7 Mar 2012 14:12:50 +0000 Subject: mtd: maps: l440gx: Add reference counter to set_vpp() This patch is part of a set which fixes unnecessary flash erase and write errors resulting from the MTD CFI driver turning off vpp while an erase is in progress. This patch allows l440gx_set_vpp() calls to be nested by adding a reference counter. Signed-off-by: Paul Parsons Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/maps/l440gx.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/maps/l440gx.c b/drivers/mtd/maps/l440gx.c index dd0360b..74bd98e 100644 --- a/drivers/mtd/maps/l440gx.c +++ b/drivers/mtd/maps/l440gx.c @@ -27,17 +27,21 @@ static struct mtd_info *mymtd; /* Is this really the vpp port? */ +static DEFINE_SPINLOCK(l440gx_vpp_lock); +static int l440gx_vpp_refcnt; static void l440gx_set_vpp(struct map_info *map, int vpp) { - unsigned long l; + unsigned long flags; - l = inl(VPP_PORT); + spin_lock_irqsave(&l440gx_vpp_lock, flags); if (vpp) { - l |= 1; + if (++l440gx_vpp_refcnt == 1) /* first nested 'on' */ + outl(inl(VPP_PORT) | 1, VPP_PORT); } else { - l &= ~1; + if (--l440gx_vpp_refcnt == 0) /* last nested 'off' */ + outl(inl(VPP_PORT) & ~1, VPP_PORT); } - outl(l, VPP_PORT); + spin_unlock_irqrestore(&l440gx_vpp_lock, flags); } static struct map_info l440gx_map = { -- cgit v1.1