On Fri, Jan 16, 2015 at 03:39:53PM +0100, Paul Osmialowski wrote: > This uses the enhancement of i2c API in order to address following problem > caused by circular lock dependency: Please don't just dump enormous backtraces into commit messages as explanations, explain in words what the problem you are trying to address is. If the backtrace is longer than the commit message things probably aren't working well, and similarly if the first thing the reader sees is several screenfuls of backtrace that's not really aiding understanding. This is all particularly important with something like locking where a clear understanding of the rules and assumptions being made is very important to ensuring correctness, it's easy to just paper over a specific problem and miss a bigger problem or introduce new ones. > Apparently regulator and clock try to acquire lock which is protecting the > same regmap. Communication over i2c requires clock to be started. Both things > require access to the same regmap in order to complete. > To solve this, i2c clock should be started before attempting operation on > regulator (which requires locked regmap). It sounds awfully like something is not doing the right thing with preparing clocks somewhere along the line but since there's no analysis it's hard to tell (I don't propose to spend time trawling backtraces for something I don't know). Please also use blank lines between paragraphs like all the other commit messages, it makes things easier to read. > Exposing preparation and unpreparation stage of i2c transfer serves this > purpose. I don't know what this means, sorry. I'm also very worried about the fact that this is being discussed purely in terms of I2C - why would this not affect other buses? > Note that this change does not require modifications in other places. > > Signed-off-by: Paul Osmialowski <p.osmialowsk@xxxxxxxxxxx> > --- > drivers/base/regmap/internal.h | 2 + > drivers/base/regmap/regmap-i2c.c | 18 +++++++ > drivers/base/regmap/regmap.c | 107 ++++++++++++++++++++++++++++++++++++++- > include/linux/regmap.h | 7 +++ > 4 files changed, 133 insertions(+), 1 deletion(-) Modification may not be required in other places but this is an *enormous* change in the code which I can't really review. > + int (*reg_prepare_sync_io)(void *context); > + void (*reg_unprepare_sync_io)(void *context); The first question here is why this only affects synchronous I/O or alternatively why these operations have _sync in the name if they aren't for synchronous I/O. > + if (bus) { > + map->reg_prepare_sync_io = regmap_bus_prepare_sync_io; > + map->reg_unprepare_sync_io = regmap_bus_unprepare_sync_io; > + } Why are we using these indirections instead of assigning the operation directly? They... > +static int regmap_bus_prepare_sync_io(void *context) > +{ > + struct regmap *map = context; > + > + if (map->bus->prepare_sync_io) > + return map->bus->prepare_sync_io(map->bus_context); > + > + return 0; > +} ...seem to simply check for the operation which appears redundant especially given that the caller... > +static void regmap_unprepare_sync_io(struct regmap *map) > +{ > + void *context = _regmap_map_get_context(map); > + > + if (map->reg_unprepare_sync_io) > + map->reg_unprepare_sync_io(context); > +} ...does essentially the same check again on every call anyway. > @@ -1491,12 +1536,18 @@ int regmap_write(struct regmap *map, unsigned int reg, unsigned int val) > if (reg % map->reg_stride) > return -EINVAL; > > + ret = regmap_prepare_sync_io(map); > + if (ret) > + return ret; > + > map->lock(map->lock_arg); So what are the rules for calling this operation and how are they different to those for locking the map? It looks like they might be the same in which case it seems better to combine them rather than having to update every single caller and remember why they're always being worked with in tandem.
Attachment:
signature.asc
Description: Digital signature