diff options
author | Paul Parsons <lost.distance@yahoo.com> | 2012-03-07 09:12:50 -0500 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2012-03-26 19:52:49 -0400 |
commit | 5fbabf3f45a15c2b39170980cee01368138f4d79 (patch) | |
tree | 486eea6db78490042d4f6d0f6eb7bd8e834e2598 /drivers/mtd | |
parent | 876fe76d793d03077eb61ba3afab4a383f46c554 (diff) |
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 <lost.distance@yahoo.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/maps/l440gx.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/drivers/mtd/maps/l440gx.c b/drivers/mtd/maps/l440gx.c index dd0360ba2412..74bd98ee635f 100644 --- a/drivers/mtd/maps/l440gx.c +++ b/drivers/mtd/maps/l440gx.c | |||
@@ -27,17 +27,21 @@ static struct mtd_info *mymtd; | |||
27 | 27 | ||
28 | 28 | ||
29 | /* Is this really the vpp port? */ | 29 | /* Is this really the vpp port? */ |
30 | static DEFINE_SPINLOCK(l440gx_vpp_lock); | ||
31 | static int l440gx_vpp_refcnt; | ||
30 | static void l440gx_set_vpp(struct map_info *map, int vpp) | 32 | static void l440gx_set_vpp(struct map_info *map, int vpp) |
31 | { | 33 | { |
32 | unsigned long l; | 34 | unsigned long flags; |
33 | 35 | ||
34 | l = inl(VPP_PORT); | 36 | spin_lock_irqsave(&l440gx_vpp_lock, flags); |
35 | if (vpp) { | 37 | if (vpp) { |
36 | l |= 1; | 38 | if (++l440gx_vpp_refcnt == 1) /* first nested 'on' */ |
39 | outl(inl(VPP_PORT) | 1, VPP_PORT); | ||
37 | } else { | 40 | } else { |
38 | l &= ~1; | 41 | if (--l440gx_vpp_refcnt == 0) /* last nested 'off' */ |
42 | outl(inl(VPP_PORT) & ~1, VPP_PORT); | ||
39 | } | 43 | } |
40 | outl(l, VPP_PORT); | 44 | spin_unlock_irqrestore(&l440gx_vpp_lock, flags); |
41 | } | 45 | } |
42 | 46 | ||
43 | static struct map_info l440gx_map = { | 47 | static struct map_info l440gx_map = { |