Commit 5fbabf3f45a15c2b39170980cee01368138f4d79
Committed by
David Woodhouse
1 parent
876fe76d79
Exists in
master
and in
20 other branches
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>
Showing 1 changed file with 9 additions and 5 deletions Side-by-side Diff
drivers/mtd/maps/l440gx.c
... | ... | @@ -27,17 +27,21 @@ |
27 | 27 | |
28 | 28 | |
29 | 29 | /* Is this really the vpp port? */ |
30 | +static DEFINE_SPINLOCK(l440gx_vpp_lock); | |
31 | +static int l440gx_vpp_refcnt; | |
30 | 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 | 37 | if (vpp) { |
36 | - l |= 1; | |
38 | + if (++l440gx_vpp_refcnt == 1) /* first nested 'on' */ | |
39 | + outl(inl(VPP_PORT) | 1, VPP_PORT); | |
37 | 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 | 47 | static struct map_info l440gx_map = { |